Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 27 additions & 0 deletions .agents/docs/notifications.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# Operation notifications

Provider requests use the Host `ctx.notifications.show()` service. Source icon/name,
card interactions, queue, expiry and suppression rules belong to Host.
Declare `notifications` in injection requirements. Field validation and persistent
business state stay beside the relevant control or object. Do not introduce a
custom Toast, page-wide operation error, or raw exception message.

The [Host guide](https://github.com/cordisx/cordisx/blob/3cfe370eb7abf33e16686fbd82659cd441247fbd/.agents/docs/notifications.md)
owns usage and interaction guidance; the
[Protocol contract](https://github.com/cordisx/cordisx-protocol/blob/f46dd21e15a949a26f05f89bf11dea339fc60c02/.agents/docs/notifications-v1.md)
owns the public API. Source merge and package publication are separate stages.

## Development dependencies

`package.json` and `package-lock.json` pin formally merged Host and Protocol
commits. Install through the repository's normal dependency flow:

```sh
npm ci
npm run check
```

Keep the shared Protocol override so public branded types resolve to one copy.
A missing notification service requires a supported Host upgrade; do not recreate
notification UI as an older-Host fallback. The former local candidate SDK archive
is no longer an installation prerequisite.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
dist/
node_modules/

.cache/sdk/
13 changes: 13 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,16 @@
- Read the organization
[CSS ownership and maintenance rule](https://github.com/cordisx/cordisxmono/blob/main/.agents/rules/css.md)
before changing CSS or a style-bearing DOM contract.

## Operation notifications

Use the public `ctx.notifications.show()` service for operation feedback and
require `notifications` in plugin injection. Do not create a custom Toast,
manually positioned alert, or page-wide success/error paragraph. Keep field
validation and durable business state beside the relevant object. Use stable
semantic `kind` values, localized safe text, and notification rules owned by Host;
never expose raw exceptions or notify on every polling attempt.
See the [Host notification guide](https://github.com/cordisx/cordisx/blob/3cfe370eb7abf33e16686fbd82659cd441247fbd/.agents/docs/notifications.md)
for the interaction contract and older-Host capability boundary.

Dependency setup: [notification migration](./.agents/docs/notifications.md).
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,3 +39,7 @@ Desktop. The package remains `private`; use the explicit local source distributi
[HISTORY.md](HISTORY.md) records the filtered owner history from the original
Host-owned implementation. This repository is licensed under
[AGPL-3.0-or-later](LICENSE).

## Notification feedback

See [operation notifications and development dependencies](./.agents/docs/notifications.md).
39 changes: 17 additions & 22 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 6 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,13 +38,13 @@
},
"devDependencies": {
"@cordisx/eslint-config": "github:cordisx/cordisxmono#c63c2e8c2ba7e11502934a52ad2ce3734e804cdc",
"@cordisx/protocol": "github:cordisx/cordisx-protocol#c2f6f8e4bf4a638bf4627c9c567792f2fedbcfd6",
"@cordisx/protocol": "github:cordisx/cordisx-protocol#f46dd21e15a949a26f05f89bf11dea339fc60c02",
"@deepseek-ai/cordis": "4.0.1",
"@deepseek-ai/schemastery": "3.18.1",
"@projectwallace/stylelint-plugin": "0.7.0",
"@typescript-eslint/parser": "8.69.0",
"@vitejs/plugin-react": "6.1.0",
"cordisx": "github:cordisx/cordisx#152d55aa26527b23c5e70a752fb3f6562e944afc",
"cordisx": "github:cordisx/cordisx#3cfe370eb7abf33e16686fbd82659cd441247fbd",
"dprint": "0.57.1",
"eslint": "9.39.4",
"stylelint": "17.15.0",
Expand All @@ -64,5 +64,8 @@
"bugs": {
"url": "https://github.com/cordisx/plugin-cli-proxy-api/issues"
},
"homepage": "https://github.com/cordisx/plugin-cli-proxy-api#readme"
"homepage": "https://github.com/cordisx/plugin-cli-proxy-api#readme",
"overrides": {
"@cordisx/protocol": "$@cordisx/protocol"
}
}
8 changes: 4 additions & 4 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import { createProviderFleetPage } from './provider-fleet-page.js'
import { CLI_PROXY_ICON } from './icon.js'

export const name = 'cli-proxy-api'
export const inject = ['i18n', 'slots', 'pages', 'routes', 'platform']
export const inject = ['i18n', 'slots', 'pages', 'routes', 'platform', 'notifications']
export const icon = CLI_PROXY_ICON

const capabilities = [
Expand Down Expand Up @@ -76,7 +76,7 @@ interface Messages {
'state.empty': undefined
'state.no-models': undefined
'state.select-session': undefined
'state.error': { readonly message: string }
'state.error': undefined
'session.provider': { readonly provider: string }
'session.model': { readonly model: string }
'permission.models.read': undefined
Expand Down Expand Up @@ -185,7 +185,7 @@ export function apply(ctx: Context, config: Config = Config({})): void {
'state.empty': 'No matching sessions.',
'state.no-models': 'No provider models are available.',
'state.select-session': 'Select a provider session to inspect its content.',
'state.error': 'Provider request failed: {message}',
'state.error': 'Provider request failed. Check the connection and try again.',
'session.provider': 'Provider {provider}',
'session.model': 'Model {model}',
'permission.models.read': 'List models from configured external providers',
Expand Down Expand Up @@ -230,7 +230,7 @@ export function apply(ctx: Context, config: Config = Config({})): void {
'state.empty': '没有匹配的会话。',
'state.no-models': '没有可用的 Provider 模型。',
'state.select-session': '选择一个 Provider 会话以查看内容。',
'state.error': 'Provider 请求失败:{message}',
'state.error': 'Provider 请求失败,请检查连接后重试',
'session.provider': 'Provider {provider}',
'session.model': '模型 {model}',
'permission.models.read': '读取已配置外部 Provider 的模型',
Expand Down
8 changes: 5 additions & 3 deletions src/provider-fleet-page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ interface Messages {
'state.empty': undefined
'state.no-models': undefined
'state.select-session': undefined
'state.error': { readonly message: string }
'state.error': undefined
'session.provider': { readonly provider: string }
'session.model': { readonly model: string }
}
Expand Down Expand Up @@ -78,8 +78,10 @@ export function createProviderFleetPage(ctx: Context, config: Config) {
const [steer, setSteer] = useState('')
const [status, setStatus] = useState('')

const showError = (error: { readonly message: string }) =>
setStatus(props.t('state.error', { message: error.message }))
const showError = (_error: { readonly message: string }) => {
setStatus('')
ctx.notifications.show({ kind: 'provider.request-failed', type: 'error', message: props.t('state.error') })
}
const providerIds = provider === ''
? configuredProviders ?? [...new Set(models.map(item => item.ref.providerId))].sort()
: [provider]
Expand Down
2 changes: 1 addition & 1 deletion test/manifest.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ test('exports the CLIProxy renderer manifest through public Host contracts', ()
'turns.control',
],
)
assert.deepEqual(plugin.inject, ['i18n', 'slots', 'pages', 'routes', 'platform'])
assert.deepEqual(plugin.inject, ['i18n', 'slots', 'pages', 'routes', 'platform', 'notifications'])
})

test('registers one public page, route, and navigation contribution', () => {
Expand Down
Loading