@x1a0f3n9/dsh-client-ui-commands 0.1.5-rc.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,152 @@
1
+ /**
2
+ * CommandUiRuntime (`ctx.commandUi`): the '/' command source over the
3
+ * session-keyed directory, the client-contribution registry, and the
4
+ * per-session popupSelect controllers. Candidate synthesis merges the host
5
+ * catalog with contributions by availability, gives built-in Host rows their
6
+ * localized face (presentation.ts), then position-filters; an empty query
7
+ * lists the Add and Commands sections in usage order, a typed query ranks
8
+ * every row by the `/` menu's shared name-and-label ranking (ui-primitives
9
+ * `rankByName`). A host/contribution name collision fails loud. Every
10
+ * execute addresses the session's agent by sessionId — sessions are always
11
+ * agent-backed.
12
+ */
13
+ import { Service } from '@deepseek-ai/cordis';
14
+ import type { Context } from '@deepseek-ai/cordis';
15
+ import type { CommandResult } from '@x1a0f3n9/dsh-commands/types';
16
+ import type { Context as ClientContext } from '@deepseek-ai/cordis';
17
+ import type { SessionId } from '@x1a0f3n9/dsh-session/types';
18
+ import type { ClientSessionContext } from '@x1a0f3n9/dsh-client-ui-input-trigger/client';
19
+ import type { CommandContribution, CommandDecoration, CommandUiContract } from './contract.ts';
20
+ import { PopupSelectController } from './popup.ts';
21
+ declare module '@deepseek-ai/cordis' {
22
+ interface Events {
23
+ /**
24
+ * This browser client completed one admitted Host command execution.
25
+ * Other clients receive the durable command nodes but never this local
26
+ * submission acknowledgment.
27
+ * @param sessionId - Session addressed by the local submission.
28
+ * @param name - Executed command name without the leading slash.
29
+ * @param result - Host command result returned to this browser.
30
+ * @mode emit
31
+ */
32
+ 'command/executed'(sessionId: SessionId, name: string, result: CommandResult): void;
33
+ }
34
+ }
35
+ /** Command surface: session-keyed directory + '/' source + contribution registry + per-session popups. */
36
+ export declare class CommandUiRuntime extends Service implements CommandUiContract {
37
+ static inject: string[];
38
+ private readonly directory;
39
+ private readonly live;
40
+ /** `command`-namespace translator (composer refusal notices). */
41
+ private readonly t;
42
+ /**
43
+ * @param ctx - owning root context (plugin fiber; the service registers
44
+ * itself as `command` and follows that fiber's lifetime).
45
+ */
46
+ constructor(ctx: Context);
47
+ /**
48
+ * Register one client command contribution; effect disposer (rides the
49
+ * caller's fiber). Duplicate names throw.
50
+ * @param contribution - the contribution (descriptor + availability + popup spec).
51
+ * @returns the disposer removing the registration.
52
+ */
53
+ register(contribution: CommandContribution): () => void;
54
+ /**
55
+ * Hang a bare-invocation decoration on one host command; effect disposer
56
+ * (rides the caller's fiber). Duplicate names throw.
57
+ * @param decoration - host command name + availability + popup spec.
58
+ * @returns the disposer removing the registration.
59
+ */
60
+ decorate(decoration: CommandDecoration): () => void;
61
+ /**
62
+ * Resolve the per-session popup controller (lazy; dies with the session
63
+ * scope). The controller's consume callback dispatches the scoped
64
+ * consume-token event back to this session; focusComposer reaches the
65
+ * composer through the overlay slot currency.
66
+ * @param actx - session-scope ctx.
67
+ * @returns the resident controller.
68
+ */
69
+ popupFor(actx: ClientContext): PopupSelectController<ClientSessionContext>;
70
+ /** Composer focus hooks by session (the overlay wiring binds the textarea focus here). */
71
+ private readonly focusHooks;
72
+ /**
73
+ * Bind one session's composer-focus hook (overlay slot wiring; unbind on unmount).
74
+ * @param id - session id.
75
+ * @param focus - textarea focus callback.
76
+ * @returns the unbind disposer.
77
+ */
78
+ bindComposerFocus(id: SessionId, focus: () => void): () => void;
79
+ /**
80
+ * Menu candidates: host catalog + contribution availability, built-in rows
81
+ * localized, then position filtering; sections for an empty query, the
82
+ * shared name-and-label ranking for a typed one.
83
+ */
84
+ private candidates;
85
+ /** Decision table, menu column: contribution/decorated-host → popup or action; host input → claim; host bare → detached execute. */
86
+ private dispatch;
87
+ /** Decision table, space column: hot-key sync check; only host leadingInput claims. */
88
+ private matchSpace;
89
+ /**
90
+ * Decision table, enter column. Strong-waits the session's catalog (a
91
+ * warmup failure rejects — never a silent downgrade). Contributions and
92
+ * bare host commands act on the bare token only; leadingInput claims
93
+ * args-tolerant.
94
+ *
95
+ * Envelope policy: an enter submission carrying attachments resolves only
96
+ * through a command declaring attachment acceptance. Every other submitting
97
+ * route — popup, non-accepting claim, bare detached execute — throws the
98
+ * refusal so the machine surfaces one composer notice and the draft and
99
+ * attachments stay in place; nothing executes and nothing is dropped. An
100
+ * action submits nothing and runs regardless.
101
+ *
102
+ * A typed token is resolved through the localized claim tokens, so a line
103
+ * written as `/计划` reaches the `plan` descriptor and executes as `/plan`.
104
+ */
105
+ private matchEnter;
106
+ /**
107
+ * Invoke one contribution or decoration (menu pick / bare enter): open the
108
+ * session's popup, or consume the token and run the action.
109
+ */
110
+ private invoke;
111
+ /**
112
+ * Build the leadingInput claim. The composer keeps the claimed token in
113
+ * the draft and reads the arguments after it, so the token is the spelling
114
+ * the draft will carry: the locale's token for a menu pick, the typed
115
+ * spelling for Space and Enter. The command.execute submit transaction
116
+ * always sends the catalog name.
117
+ */
118
+ private leadingClaim;
119
+ /**
120
+ * The command.execute transaction, addressed to the session's agent — pure
121
+ * admission semantics. An unmatched line reports an error outcome (the
122
+ * composer's immediate admission feedback); an admitted command reports
123
+ * plain success regardless of its handler outcome, because the host
124
+ * executor durably logged the lifecycle (`command/run`/`command/done`) and
125
+ * the outcome renders as a persistent flow node — the composer never
126
+ * echoes it. A handler error result reports an error outcome so the
127
+ * composer keeps the draft and attachments for correction.
128
+ * A refused call throws.
129
+ */
130
+ private execute;
131
+ /** Publish the local acknowledgment without letting an observer change command admission. */
132
+ private notifyExecuted;
133
+ /** Log one contained `command/executed` observer failure. */
134
+ private warnExecutedListenerFailure;
135
+ /**
136
+ * Fire-and-forget execute for the internal ('handled') paths. Outcomes are
137
+ * NOT surfaced here: the host executor durably logs the command lifecycle
138
+ * (`command/run`/`command/done`), and the mux-broadcast events render as a
139
+ * persistent flow node on every tab. Only an admission failure — which never
140
+ * entered a handler and therefore never logged — falls back to the composer
141
+ * notice as immediate feedback.
142
+ */
143
+ private runDetached;
144
+ /** Dispatch a consume-token event to one session (menu-pick / bare-enter execute paths). */
145
+ private consumeVia;
146
+ /** Route an admission failure to the session's composer notice channel (scope gone = attempt died with it). */
147
+ private noticeFor;
148
+ /** id → actx interchange (registered exchange point: this service coordinates for projection-only sources). */
149
+ private scopeFor;
150
+ private sessions;
151
+ }
152
+ //# sourceMappingURL=service.d.ts.map
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Command UI plugin, node half. Pure UI plugin: the empty apply exists so
3
+ * the plugin appears in the host cordis.yml / Loader; the browser half ships
4
+ * via exports["./client"], discovered through the package.json dsh.client
5
+ * declaration. The host command registry itself mounts separately
6
+ * (bootHost + CommandUiRuntime).
7
+ */
8
+ /** Host plugin body — no host-side behavior for the command UI plugin. */
9
+ export declare function apply(): void;
10
+ //# sourceMappingURL=index.d.ts.map
package/package.json ADDED
@@ -0,0 +1,72 @@
1
+ {
2
+ "name": "@x1a0f3n9/dsh-client-ui-commands",
3
+ "description": "Client command surface: global directory cache, '/' source, three command UI kinds, popupSelect registry",
4
+ "version": "0.1.5-rc.3",
5
+ "publishConfig": {
6
+ "access": "public"
7
+ },
8
+ "repository": {
9
+ "type": "git",
10
+ "url": "git+https://github.com/deepseek-ai/deepseek-harness.git",
11
+ "directory": "packages/client/ui-commands"
12
+ },
13
+ "type": "module",
14
+ "main": "lib/index.js",
15
+ "types": "lib/types/index.d.ts",
16
+ "exports": {
17
+ ".": {
18
+ "types": "./lib/types/index.d.ts",
19
+ "default": "./lib/index.js"
20
+ },
21
+ "./client": {
22
+ "types": "./lib/types/client/index.d.ts",
23
+ "default": "./lib/client.js"
24
+ },
25
+ "./src/*": "./src/*",
26
+ "./package.json": "./package.json"
27
+ },
28
+ "dsh": {
29
+ "client": {
30
+ "inject": [
31
+ "@x1a0f3n9/dsh-api-remotes",
32
+ "@x1a0f3n9/dsh-client-locale",
33
+ "@x1a0f3n9/dsh-client-ui-input-trigger",
34
+ "@x1a0f3n9/dsh-client-ui-conversation"
35
+ ],
36
+ "platform": "web"
37
+ }
38
+ },
39
+ "license": "MIT",
40
+ "peerDependencies": {
41
+ "@deepseek-ai/cordis": "^4.0.2"
42
+ },
43
+ "devDependencies": {
44
+ "@types/react": "~18.3.1",
45
+ "react": "^18.2.0",
46
+ "clsx": "^2.0.0",
47
+ "@x1a0f3n9/dsh-api-remotes": "^0.1.5-rc.3",
48
+ "@x1a0f3n9/dsh-client-connection": "^0.1.5-rc.3",
49
+ "@x1a0f3n9/dsh-client-locale": "^0.1.5-rc.3",
50
+ "@x1a0f3n9/dsh-client-test-runtime": "^0.1.5-rc.3",
51
+ "@x1a0f3n9/dsh-client-ui-primitives": "^0.1.5-rc.3",
52
+ "@x1a0f3n9/dsh-client-ui-conversation": "^0.1.5-rc.3",
53
+ "@x1a0f3n9/dsh-client-ui-input-trigger": "^0.1.5-rc.3",
54
+ "@x1a0f3n9/dsh-client-ui-slots": "^0.1.5-rc.3",
55
+ "@x1a0f3n9/dsh-commands": "^0.1.5-rc.3",
56
+ "@deepseek-ai/cordis": "^4.0.2",
57
+ "@x1a0f3n9/dsh-api-session-controller": "^0.1.5-rc.3",
58
+ "@x1a0f3n9/dsh-client-store": "^0.1.5-rc.3",
59
+ "@x1a0f3n9/dsh-session": "^0.1.5-rc.3",
60
+ "@x1a0f3n9/dsh-client-ui-renderer": "^0.1.5-rc.3",
61
+ "@x1a0f3n9/dsh-client-ui-session": "^0.1.5-rc.3"
62
+ },
63
+ "files": [
64
+ "lib/index.js",
65
+ "lib/client.js",
66
+ "lib/types/**/*.d.ts"
67
+ ],
68
+ "scripts": {
69
+ "bundle": "tsdown",
70
+ "watch": "tsdown --watch"
71
+ }
72
+ }