@norman-else/dsh-claude 0.1.11 → 0.1.12

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.
@@ -32,9 +32,11 @@ const CLAUDE_COMMANDS_SERVICE = "claudeCommands";
32
32
  function bounded(value, maxChars) {
33
33
  return redactText(value, maxChars);
34
34
  }
35
- function desiredCommands(catalog, reservedNames, forward) {
36
- const desired = /* @__PURE__ */ new Map();
35
+ function projectClaudeCommands(catalog, target) {
36
+ const reservedNames = new Set(target.list().map((command) => command.name));
37
+ for (const name of CLIENT_CONTRIBUTION_NAMES) reservedNames.add(name);
37
38
  const assigned = /* @__PURE__ */ new Set();
39
+ const views = [];
38
40
  for (const command of catalog) {
39
41
  const names = [command.name, ...command.aliases ?? []];
40
42
  for (const claudeName of names) {
@@ -49,67 +51,18 @@ function desiredCommands(catalog, reservedNames, forward) {
49
51
  if (!COMMAND_NAME.test(publicName) || reservedNames.has(publicName) || assigned.has(publicName)) continue;
50
52
  const description = bounded(command.description || `Claude Code /${command.name}`, MAX_DESCRIPTION_CHARS);
51
53
  const hint = bounded(command.argumentHint ?? "", MAX_HINT_CHARS);
52
- const signature = JSON.stringify({
54
+ views.push({
53
55
  publicName,
54
56
  claudeName,
55
57
  description,
56
- hint
57
- });
58
- desired.set(publicName, {
59
- publicName,
60
- claudeName,
61
- prefixed,
62
- signature,
63
- definition: {
64
- name: publicName,
65
- description,
66
- ...hint.length === 0 ? {} : { input: { hint } },
67
- recordInput: false,
68
- handler: ({ agent, rawInput }) => {
69
- forward(agent, `/${claudeName}${rawInput}`);
70
- return { kind: "success" };
71
- }
72
- }
58
+ ...hint.length === 0 ? {} : { hint },
59
+ prefixed
73
60
  });
74
61
  assigned.add(publicName);
75
62
  }
76
63
  }
77
- return desired;
64
+ return views;
78
65
  }
79
- var ClaudeCommandBridge = class {
80
- #target;
81
- #live = /* @__PURE__ */ new Map();
82
- constructor(target) {
83
- this.#target = target;
84
- }
85
- refresh(catalog) {
86
- const owned = new Set(this.#live.keys());
87
- const reserved = new Set(this.#target.list().map((command) => command.name).filter((name) => !owned.has(name)));
88
- for (const name of CLIENT_CONTRIBUTION_NAMES) reserved.add(name);
89
- const desired = desiredCommands(catalog, reserved, (agent, line) => this.#target.forward(agent, line));
90
- for (const [name, live] of [...this.#live]) {
91
- if (desired.get(name)?.signature === live.signature) continue;
92
- live.dispose();
93
- this.#live.delete(name);
94
- }
95
- for (const [name, next] of desired) {
96
- if (this.#live.has(name)) continue;
97
- this.#live.set(name, {
98
- signature: next.signature,
99
- dispose: this.#target.register(next.definition)
100
- });
101
- }
102
- return [...desired.values()].map(({ publicName, claudeName, prefixed }) => ({
103
- publicName,
104
- claudeName,
105
- prefixed
106
- }));
107
- }
108
- dispose() {
109
- for (const command of this.#live.values()) command.dispose();
110
- this.#live.clear();
111
- }
112
- };
113
66
  //#endregion
114
67
  //#region src/presenters.ts
115
68
  function record(value) {
@@ -297,6 +250,6 @@ function claudePresenterDefinitions() {
297
250
  /** Names covered by the static preset-scope registry; dynamic mirrors skip them. */
298
251
  const CLAUDE_PRESENTER_NAMES = new Set(claudePresenterDefinitions().map((definition) => definition.name));
299
252
  //#endregion
300
- export { ClaudeCommandBridge as a, CLAUDE_COMMANDS_SERVICE as i, claudePresenterDefinitions as n, dynamicPresenterDefinition as r, CLAUDE_PRESENTER_NAMES as t };
253
+ export { projectClaudeCommands as a, CLAUDE_COMMANDS_SERVICE as i, claudePresenterDefinitions as n, dynamicPresenterDefinition as r, CLAUDE_PRESENTER_NAMES as t };
301
254
 
302
- //# sourceMappingURL=presenters-BE6LPw2m.mjs.map
255
+ //# sourceMappingURL=presenters-CtgkpzZo.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"presenters-CtgkpzZo.mjs","names":[],"sources":["../src/command-bridge.ts","../src/presenters.ts"],"sourcesContent":["import type { SlashCommand } from '@anthropic-ai/claude-agent-sdk'\nimport type { CommandDescriptor } from '@deepseek-ai/dsh-commands'\nimport { redactText } from './events.ts'\n\nconst COMMAND_NAME = /^[a-z][a-z0-9_-]*$/u\nconst MAX_DESCRIPTION_CHARS = 300\nconst MAX_HINT_CHARS = 120\n\n/** DSH registry names reject `:`, but plugin-qualified Claude skills carry it\n * (e.g. `awesome-skills:ci-deploy`). Derive a registry-safe public name while\n * forwarding keeps the exact Claude-side name. */\nfunction registryName(claudeName: string): string | undefined {\n if (COMMAND_NAME.test(claudeName)) return claudeName\n const short = claudeName.includes(':') ? claudeName.slice(claudeName.lastIndexOf(':') + 1) : undefined\n if (short !== undefined && COMMAND_NAME.test(short)) return short\n const sanitized = claudeName.replaceAll(':', '-').toLowerCase()\n return COMMAND_NAME.test(sanitized) ? sanitized : undefined\n}\n\n/**\n * Names registered as CLIENT-side commandUi contributions (not host\n * commands). The DSH web command palette fails its whole command group when\n * a host command name equals a contribution name\n * (\"contribution /model collides with a host command\"), so these can never\n * be registered by this bridge. Keep in sync with the client bundles:\n * dsh-client-ui-model-selection registers \"model\".\n */\nconst CLIENT_CONTRIBUTION_NAMES: ReadonlySet<string> = new Set(['model'])\n\nexport interface ClaudeCommandTarget {\n list(): readonly Pick<CommandDescriptor, 'name'>[]\n}\n\n/**\n * Agent-scope command-directory contract. The commands service is unreachable\n * from the host plugin's view of `agent.ctx` (\"without inject\"), but the\n * preset route plugin runs inside the agent's preset composition with\n * `commands` injected. The Host reads only the exact agent's effective names\n * for collision checks; Claude catalog entries are never registered there.\n */\nexport interface ClaudeAgentCommandService {\n list(agent: unknown): readonly Pick<CommandDescriptor, 'name'>[]\n}\n\n/**\n * Cordis service name the preset route provides (behind an entry-local\n * isolate realm, so each session gets its own instance) and the host reads\n * back with dsh-agent-presets' official `serviceForAgent(ctx, agent, name)`\n * — the supported cross-scope read for callers that already hold the agent.\n */\nexport const CLAUDE_COMMANDS_SERVICE = 'claudeCommands'\n\ndeclare module '@deepseek-ai/cordis' {\n interface Context {\n claudeCommands?: ClaudeAgentCommandService\n }\n}\n\nexport interface ClaudeCommandView {\n publicName: string\n claudeName: string\n description: string\n hint?: string\n prefixed: boolean\n}\n\nfunction bounded(value: string, maxChars: number): string {\n return redactText(value, maxChars)\n}\n\nexport function projectClaudeCommands(\n catalog: readonly SlashCommand[],\n target: ClaudeCommandTarget,\n): readonly ClaudeCommandView[] {\n const reservedNames = new Set(target.list().map(command => command.name))\n // Client contributions are absent from the Host directory but share the\n // same slash menu, so reserve their public names explicitly.\n for (const name of CLIENT_CONTRIBUTION_NAMES) reservedNames.add(name)\n const assigned = new Set<string>()\n const views: ClaudeCommandView[] = []\n for (const command of catalog) {\n const names = [command.name, ...(command.aliases ?? [])]\n for (const claudeName of names) {\n const base = registryName(claudeName)\n if (base === undefined) continue\n let publicName = base\n let prefixed = false\n if (reservedNames.has(publicName) || assigned.has(publicName)) {\n publicName = `claude-${base}`\n prefixed = true\n }\n if (!COMMAND_NAME.test(publicName) || reservedNames.has(publicName) || assigned.has(publicName)) continue\n const description = bounded(command.description || `Claude Code /${command.name}`, MAX_DESCRIPTION_CHARS)\n const hint = bounded(command.argumentHint ?? '', MAX_HINT_CHARS)\n views.push({\n publicName,\n claudeName,\n description,\n ...(hint.length === 0 ? {} : { hint }),\n prefixed,\n })\n assigned.add(publicName)\n }\n }\n return views\n}\n","/**\n * Presentation-only tool definitions for the Claude Code preset. Claude Code\n * owns tool execution; these definitions exist solely so the host's tool\n * presentation pipeline (`viewFor` → `presentCall`/`presentResult`) can\n * compute native render intents for the mirrored `tool/call`/`tool/result`\n * events, giving Claude tool rows the same cards DSH-executed tools get.\n */\nimport type { ToolDefinition, ToolResult } from '@deepseek-ai/dsh-tools'\nimport type { ToolCallView, ToolResultView } from '@deepseek-ai/dsh-tools/presentation'\n\nfunction record(value: unknown): Record<string, unknown> | undefined {\n return value !== null && typeof value === 'object' && !Array.isArray(value) ? value as Record<string, unknown> : undefined\n}\n\nfunction str(value: unknown): string | undefined {\n return typeof value === 'string' && value.length > 0 ? value : undefined\n}\n\nfunction resultText(result: ToolResult): string {\n return result.content\n .filter((block): block is Extract<typeof block, { type: 'text' }> => block.type === 'text')\n .map(block => block.text)\n .join('\\n')\n}\n\n/** Bash: a terminal card headed by the command, described above by Claude's own summary. */\nexport function bashCallView(args: unknown): ToolCallView | undefined {\n const command = str(record(args)?.command)\n if (command === undefined) return undefined\n const description = str(record(args)?.description)\n return { card: 'terminal', title: command, ...(description === undefined ? {} : { description }) }\n}\n\nexport function terminalResultView(_args: unknown, result: ToolResult): ToolResultView | undefined {\n const output = resultText(result)\n return output.length === 0 ? undefined : { card: 'terminal', output }\n}\n\n/** Read: a generic read card that follow-alongs the file window. */\nexport function readCallView(args: unknown): ToolCallView | undefined {\n const arguments_ = record(args)\n const path = str(arguments_?.file_path)\n if (path === undefined) return undefined\n const offset = typeof arguments_?.offset === 'number' ? arguments_.offset : undefined\n return {\n card: 'generic',\n kind: 'read',\n title: `Read ${path}`,\n locations: [{ path, ...(offset === undefined ? {} : { line: offset }) }],\n }\n}\n\nfunction fileDiffs(args: unknown): { path: string; oldText: string | null; newText: string }[] | undefined {\n const arguments_ = record(args)\n const path = str(arguments_?.file_path)\n if (path === undefined) return undefined\n if (Array.isArray(arguments_?.edits)) {\n const diffs: { path: string; oldText: string | null; newText: string }[] = []\n for (const edit of arguments_.edits) {\n const item = record(edit)\n const oldText = str(item?.old_string)\n const newText = str(item?.new_string)\n if (newText === undefined) continue\n diffs.push({ path, oldText: oldText ?? null, newText })\n }\n return diffs.length > 0 ? diffs : undefined\n }\n const newText = str(arguments_?.new_string) ?? arguments_?.content\n if (typeof newText !== 'string' || newText.length === 0) return undefined\n const oldText = str(arguments_?.old_string)\n return [{ path, oldText: oldText ?? null, newText }]\n}\n\n/** Edit / MultiEdit / Write: inline diff cards derived from the call arguments. */\nexport function diffCallView(args: unknown): ToolCallView | undefined {\n const arguments_ = record(args)\n const path = str(arguments_?.file_path)\n const diffs = fileDiffs(args)\n if (path === undefined || diffs === undefined) return undefined\n const verb = typeof arguments_?.new_string === 'string' || Array.isArray(arguments_?.edits) ? 'Edit' : 'Write'\n return { card: 'diff', title: `${verb} ${path}`, diffs, locations: [{ path }] }\n}\n\n/** Grep / Glob / WebSearch: search-category cards titled by the query. */\nexport function searchCallView(args: unknown): ToolCallView | undefined {\n const arguments_ = record(args)\n const query = str(arguments_?.pattern) ?? str(arguments_?.query)\n if (query === undefined) return undefined\n const scope = str(arguments_?.path)\n return {\n card: 'generic',\n kind: 'search',\n title: scope === undefined ? query : `${query} · ${scope}`,\n rawInput: args,\n }\n}\n\n/** WebFetch: a fetch-category card titled by the URL. */\nexport function fetchCallView(args: unknown): ToolCallView | undefined {\n const url = str(record(args)?.url)\n if (url === undefined) return undefined\n return { card: 'generic', kind: 'fetch', title: url, rawInput: args }\n}\n\n/** Task: a subagent card titled by Claude's task description. */\nexport function taskCallView(args: unknown): ToolCallView | undefined {\n const arguments_ = record(args)\n const title = str(arguments_?.description) ?? str(arguments_?.subagent_type) ?? 'Subagent'\n return { card: 'generic', kind: 'other', title, rawInput: args }\n}\n\nfunction genericTitle(title: string): ToolCallView {\n return { card: 'generic', kind: 'other', title }\n}\n\nfunction presenterDefinition(\n name: string,\n description: string,\n presentCall?: (args: unknown) => ToolCallView | undefined,\n presentResult?: (args: unknown, result: ToolResult) => ToolResultView | undefined,\n): ToolDefinition {\n return {\n name,\n description,\n parameters: { type: 'object', properties: {} },\n output: {\n schema: { type: 'object', properties: {} } as ToolDefinition['output']['schema'],\n render: () => [],\n },\n execute: async () => {\n throw new Error(`dsh-claude: Claude Code owns execution of ${name}`)\n },\n ...(presentCall === undefined ? {} : { presentCall }),\n ...(presentResult === undefined ? {} : { presentResult }),\n }\n}\n\nconst PRESENTATION_NOTE = 'Presentation mirror of the Claude Code tool; execution is owned by Claude Code.'\n\n/** Generic call view for dynamically observed tools (MCP tools, new built-ins). */\nexport function genericCallView(toolName: string): (args: unknown) => ToolCallView | undefined {\n return (args: unknown) => {\n const description = str(record(args)?.description)\n return { card: 'generic', kind: 'other', title: description ?? toolName, rawInput: args }\n }\n}\n\n/** One presenter-only mirror for a tool name discovered at runtime. */\nexport function dynamicPresenterDefinition(name: string): ToolDefinition {\n return presenterDefinition(name, PRESENTATION_NOTE, genericCallView(name))\n}\n\n/** The presentation-only registry contributed to the Claude Code preset scope. */\nexport function claudePresenterDefinitions(): ToolDefinition[] {\n return [\n presenterDefinition('Bash', PRESENTATION_NOTE, bashCallView, terminalResultView),\n presenterDefinition('Read', PRESENTATION_NOTE, readCallView),\n presenterDefinition('Edit', PRESENTATION_NOTE, diffCallView),\n presenterDefinition('MultiEdit', PRESENTATION_NOTE, diffCallView),\n presenterDefinition('Write', PRESENTATION_NOTE, diffCallView),\n presenterDefinition('NotebookEdit', PRESENTATION_NOTE, args => {\n const path = str(record(args)?.notebook_path)\n return path === undefined ? undefined : genericTitle(`NotebookEdit ${path}`)\n }),\n presenterDefinition('Grep', PRESENTATION_NOTE, searchCallView),\n presenterDefinition('Glob', PRESENTATION_NOTE, searchCallView),\n presenterDefinition('WebSearch', PRESENTATION_NOTE, searchCallView),\n presenterDefinition('WebFetch', PRESENTATION_NOTE, fetchCallView),\n presenterDefinition('Task', PRESENTATION_NOTE, taskCallView),\n presenterDefinition('TodoWrite', PRESENTATION_NOTE, () => genericTitle('Update todos')),\n ]\n}\n\n/** Names covered by the static preset-scope registry; dynamic mirrors skip them. */\nexport const CLAUDE_PRESENTER_NAMES: ReadonlySet<string> = new Set(claudePresenterDefinitions().map(definition => definition.name))\n"],"mappings":"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"}
@@ -1,5 +1,5 @@
1
1
  import { p as CLAUDE_CODE_PROVIDER } from "./events-6xTApIQw.mjs";
2
- import { i as CLAUDE_COMMANDS_SERVICE, n as claudePresenterDefinitions } from "./presenters-BE6LPw2m.mjs";
2
+ import { i as CLAUDE_COMMANDS_SERVICE, n as claudePresenterDefinitions } from "./presenters-CtgkpzZo.mjs";
3
3
  //#region src/preset-route.ts
4
4
  const name = "claude-code-preset-route";
5
5
  const inject = ["tools", "commands"];
@@ -12,10 +12,7 @@ function apply(ctx, config = {}) {
12
12
  model: config.model ?? upstream.model ?? "default"
13
13
  };
14
14
  });
15
- ctx.provide(CLAUDE_COMMANDS_SERVICE, {
16
- list: (agent) => ctx.commands.list(agent),
17
- register: (definition) => ctx.commands.register(definition)
18
- });
15
+ ctx.provide(CLAUDE_COMMANDS_SERVICE, { list: (agent) => ctx.commands.list(agent) });
19
16
  for (const definition of claudePresenterDefinitions()) ctx.effect(() => ctx.tools.register(definition), `dsh-claude: ${definition.name} presentation`);
20
17
  }
21
18
  //#endregion
@@ -1 +1 @@
1
- {"version":3,"file":"preset-route.mjs","names":[],"sources":["../src/preset-route.ts"],"sourcesContent":["import type { Context } from '@deepseek-ai/cordis'\nimport type {} from '@deepseek-ai/dsh-agent'\nimport type {} from '@deepseek-ai/dsh-commands'\nimport type {} from '@deepseek-ai/dsh-tools'\nimport { CLAUDE_CODE_PROVIDER } from './constants.ts'\nimport { CLAUDE_COMMANDS_SERVICE } from './command-bridge.ts'\nimport { claudePresenterDefinitions } from './presenters.ts'\n\nexport const name = 'claude-code-preset-route'\nexport const inject = ['tools', 'commands']\n\nexport interface Config {\n model?: string\n}\n\nexport function apply(ctx: Context, config: Config = {}): void {\n ctx.on('agent/request', async (_payload, next) => {\n const upstream = await next()\n return {\n ...upstream,\n provider: CLAUDE_CODE_PROVIDER,\n model: config.model ?? upstream.model ?? 'default',\n }\n })\n // Provide this agent-scope commands service so the host-side command\n // bridge can register Claude's catalog into exactly this agent's scope\n // layer. The preset row isolates the service per entry (per session); the\n // host reads it via serviceForAgent(ctx, agent, CLAUDE_COMMANDS_SERVICE).\n ctx.provide(CLAUDE_COMMANDS_SERVICE, {\n list: agent => ctx.commands.list(agent as never),\n register: definition => ctx.commands.register(definition),\n })\n // Presentation-only tool mirrors, scoped to this preset's agents: they let\n // the host compute native render intents for the mirrored Claude tool\n // events. Claude Code owns execution; the stub `execute` never runs.\n for (const definition of claudePresenterDefinitions()) {\n ctx.effect(() => ctx.tools.register(definition), `dsh-claude: ${definition.name} presentation`)\n }\n}\n"],"mappings":";;;AAQA,MAAa,OAAO;AACpB,MAAa,SAAS,CAAC,SAAS,UAAU;AAM1C,SAAgB,MAAM,KAAc,SAAiB,CAAC,GAAS;CAC7D,IAAI,GAAG,iBAAiB,OAAO,UAAU,SAAS;EAChD,MAAM,WAAW,MAAM,KAAK;EAC5B,OAAO;GACL,GAAG;GACH,UAAU;GACV,OAAO,OAAO,SAAS,SAAS,SAAS;EAC3C;CACF,CAAC;CAKD,IAAI,QAAQ,yBAAyB;EACnC,OAAM,UAAS,IAAI,SAAS,KAAK,KAAc;EAC/C,WAAU,eAAc,IAAI,SAAS,SAAS,UAAU;CAC1D,CAAC;CAID,KAAK,MAAM,cAAc,2BAA2B,GAClD,IAAI,aAAa,IAAI,MAAM,SAAS,UAAU,GAAG,eAAe,WAAW,KAAK,cAAc;AAElG"}
1
+ {"version":3,"file":"preset-route.mjs","names":[],"sources":["../src/preset-route.ts"],"sourcesContent":["import type { Context } from '@deepseek-ai/cordis'\nimport type {} from '@deepseek-ai/dsh-agent'\nimport type {} from '@deepseek-ai/dsh-commands'\nimport type {} from '@deepseek-ai/dsh-tools'\nimport { CLAUDE_CODE_PROVIDER } from './constants.ts'\nimport { CLAUDE_COMMANDS_SERVICE } from './command-bridge.ts'\nimport { claudePresenterDefinitions } from './presenters.ts'\n\nexport const name = 'claude-code-preset-route'\nexport const inject = ['tools', 'commands']\n\nexport interface Config {\n model?: string\n}\n\nexport function apply(ctx: Context, config: Config = {}): void {\n ctx.on('agent/request', async (_payload, next) => {\n const upstream = await next()\n return {\n ...upstream,\n provider: CLAUDE_CODE_PROVIDER,\n model: config.model ?? upstream.model ?? 'default',\n }\n })\n // Expose the effective Host command names for collision-safe projection.\n // Claude Skills are not registered as Host commands: the Client slash source\n // submits them as ordinary messages, so no command lifecycle row is created.\n ctx.provide(CLAUDE_COMMANDS_SERVICE, {\n list: agent => ctx.commands.list(agent as never),\n })\n // Presentation-only tool mirrors, scoped to this preset's agents: they let\n // the host compute native render intents for the mirrored Claude tool\n // events. Claude Code owns execution; the stub `execute` never runs.\n for (const definition of claudePresenterDefinitions()) {\n ctx.effect(() => ctx.tools.register(definition), `dsh-claude: ${definition.name} presentation`)\n }\n}\n"],"mappings":";;;AAQA,MAAa,OAAO;AACpB,MAAa,SAAS,CAAC,SAAS,UAAU;AAM1C,SAAgB,MAAM,KAAc,SAAiB,CAAC,GAAS;CAC7D,IAAI,GAAG,iBAAiB,OAAO,UAAU,SAAS;EAChD,MAAM,WAAW,MAAM,KAAK;EAC5B,OAAO;GACL,GAAG;GACH,UAAU;GACV,OAAO,OAAO,SAAS,SAAS,SAAS;EAC3C;CACF,CAAC;CAID,IAAI,QAAQ,yBAAyB,EACnC,OAAM,UAAS,IAAI,SAAS,KAAK,KAAc,EACjD,CAAC;CAID,KAAK,MAAM,cAAc,2BAA2B,GAClD,IAAI,aAAa,IAAI,MAAM,SAAS,UAAU,GAAG,eAAe,WAAW,KAAK,cAAc;AAElG"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@norman-else/dsh-claude",
3
3
  "description": "Run the local Claude Code CLI as a first-class main conversation inside DeepSeek Harness",
4
- "version": "0.1.11",
4
+ "version": "0.1.12",
5
5
  "type": "module",
6
6
  "main": "lib/index.mjs",
7
7
  "types": "lib/index.d.mts",
@@ -61,6 +61,7 @@
61
61
  "inject": [
62
62
  "@deepseek-ai/dsh-client-runtime",
63
63
  "@deepseek-ai/dsh-client-ui-conversation",
64
+ "@deepseek-ai/dsh-client-ui-input-trigger",
64
65
  "@deepseek-ai/dsh-client-ui-primitives",
65
66
  "@deepseek-ai/dsh-client-ui-settings",
66
67
  "@deepseek-ai/dsh-client-ui-slots",
@@ -81,6 +82,7 @@
81
82
  "@deepseek-ai/dsh-client-locale": "*",
82
83
  "@deepseek-ai/dsh-client-runtime": "*",
83
84
  "@deepseek-ai/dsh-client-ui-conversation": "*",
85
+ "@deepseek-ai/dsh-client-ui-input-trigger": "*",
84
86
  "@deepseek-ai/dsh-client-ui-primitives": "*",
85
87
  "@deepseek-ai/dsh-client-ui-settings": "*",
86
88
  "@deepseek-ai/dsh-client-ui-slots": "*",
@@ -106,6 +108,7 @@
106
108
  "@deepseek-ai/dsh-client-locale": "0.1.0-rc.6",
107
109
  "@deepseek-ai/dsh-client-runtime": "0.1.0-rc.6",
108
110
  "@deepseek-ai/dsh-client-ui-conversation": "0.1.0-rc.6",
111
+ "@deepseek-ai/dsh-client-ui-input-trigger": "0.1.0-rc.6",
109
112
  "@deepseek-ai/dsh-client-ui-primitives": "0.1.0-rc.6",
110
113
  "@deepseek-ai/dsh-client-ui-settings": "0.1.0-rc.6",
111
114
  "@deepseek-ai/dsh-client-ui-slots": "0.1.0-rc.6",
@@ -1 +0,0 @@
1
- {"version":3,"file":"presenters-BE6LPw2m.mjs","names":["#target","#live"],"sources":["../src/command-bridge.ts","../src/presenters.ts"],"sourcesContent":["import type { SlashCommand } from '@anthropic-ai/claude-agent-sdk'\nimport type { Agent } from '@deepseek-ai/dsh-agent'\nimport type { CommandDefinition, CommandDescriptor } from '@deepseek-ai/dsh-commands'\nimport { redactText } from './events.ts'\n\nconst COMMAND_NAME = /^[a-z][a-z0-9_-]*$/u\nconst MAX_DESCRIPTION_CHARS = 300\nconst MAX_HINT_CHARS = 120\n\n/** DSH registry names reject `:`, but plugin-qualified Claude skills carry it\n * (e.g. `awesome-skills:ci-deploy`). Derive a registry-safe public name while\n * forwarding keeps the exact Claude-side name. */\nfunction registryName(claudeName: string): string | undefined {\n if (COMMAND_NAME.test(claudeName)) return claudeName\n const short = claudeName.includes(':') ? claudeName.slice(claudeName.lastIndexOf(':') + 1) : undefined\n if (short !== undefined && COMMAND_NAME.test(short)) return short\n const sanitized = claudeName.replaceAll(':', '-').toLowerCase()\n return COMMAND_NAME.test(sanitized) ? sanitized : undefined\n}\n\n/**\n * Names registered as CLIENT-side commandUi contributions (not host\n * commands). The DSH web command palette fails its whole command group when\n * a host command name equals a contribution name\n * (\"contribution /model collides with a host command\"), so these can never\n * be registered by this bridge. Keep in sync with the client bundles:\n * dsh-client-ui-model-selection registers \"model\".\n */\nconst CLIENT_CONTRIBUTION_NAMES: ReadonlySet<string> = new Set(['model'])\n\nexport interface ClaudeCommandTarget {\n list(): readonly Pick<CommandDescriptor, 'name'>[]\n register(definition: CommandDefinition): () => void\n forward(agent: Agent, line: string): void\n}\n\n/**\n * Agent-scope command service contract. The commands service is unreachable\n * from the host plugin's view of `agent.ctx` (\"without inject\"), but the\n * preset route plugin runs INSIDE the agent's preset composition with\n * `commands` injected. Registrations made through the provided service land\n * in the agent's scope layer, which the command registry inherits into\n * `list(agent)` for exactly that agent — invisible to every other session.\n */\nexport interface ClaudeAgentCommandService {\n list(agent: unknown): readonly Pick<CommandDescriptor, 'name'>[]\n register(definition: CommandDefinition): () => void\n}\n\n/**\n * Cordis service name the preset route provides (behind an entry-local\n * isolate realm, so each session gets its own instance) and the host reads\n * back with dsh-agent-presets' official `serviceForAgent(ctx, agent, name)`\n * — the supported cross-scope read for callers that already hold the agent.\n */\nexport const CLAUDE_COMMANDS_SERVICE = 'claudeCommands'\n\ndeclare module '@deepseek-ai/cordis' {\n interface Context {\n claudeCommands?: ClaudeAgentCommandService\n }\n}\n\nexport interface ClaudeCommandView {\n publicName: string\n claudeName: string\n prefixed: boolean\n}\n\ninterface DesiredCommand extends ClaudeCommandView {\n signature: string\n definition: CommandDefinition\n}\n\ninterface LiveCommand {\n signature: string\n dispose: () => void\n}\n\nfunction bounded(value: string, maxChars: number): string {\n return redactText(value, maxChars)\n}\n\nfunction desiredCommands(\n catalog: readonly SlashCommand[],\n reservedNames: ReadonlySet<string>,\n forward: (agent: Agent, line: string) => void,\n): Map<string, DesiredCommand> {\n const desired = new Map<string, DesiredCommand>()\n const assigned = new Set<string>()\n for (const command of catalog) {\n const names = [command.name, ...(command.aliases ?? [])]\n for (const claudeName of names) {\n const base = registryName(claudeName)\n if (base === undefined) continue\n let publicName = base\n let prefixed = false\n if (reservedNames.has(publicName) || assigned.has(publicName)) {\n publicName = `claude-${base}`\n prefixed = true\n }\n if (!COMMAND_NAME.test(publicName) || reservedNames.has(publicName) || assigned.has(publicName)) continue\n const description = bounded(command.description || `Claude Code /${command.name}`, MAX_DESCRIPTION_CHARS)\n const hint = bounded(command.argumentHint ?? '', MAX_HINT_CHARS)\n const signature = JSON.stringify({ publicName, claudeName, description, hint })\n desired.set(publicName, {\n publicName,\n claudeName,\n prefixed,\n signature,\n definition: {\n name: publicName,\n description,\n ...(hint.length === 0 ? {} : { input: { hint } }),\n recordInput: false,\n handler: ({ agent, rawInput }) => {\n // The invocation owns the exact session that received the command.\n // Never route through an agent captured during catalog refresh.\n forward(agent, `/${claudeName}${rawInput}`)\n return { kind: 'success' }\n },\n },\n })\n assigned.add(publicName)\n }\n }\n return desired\n}\n\nexport class ClaudeCommandBridge {\n readonly #target: ClaudeCommandTarget\n readonly #live = new Map<string, LiveCommand>()\n\n constructor(target: ClaudeCommandTarget) {\n this.#target = target\n }\n\n refresh(catalog: readonly SlashCommand[]): readonly ClaudeCommandView[] {\n const owned = new Set(this.#live.keys())\n const reserved = new Set(\n this.#target.list()\n .map(command => command.name)\n .filter(name => !owned.has(name)),\n )\n // Client-side commandUi contributions (e.g. /model from\n // dsh-client-ui-model-selection) are invisible to the host registry, but\n // the web palette throws away its ENTIRE command group when a host\n // command collides with a contribution. Reserve those names so Claude's\n // same-named commands take the claude- prefix instead.\n for (const name of CLIENT_CONTRIBUTION_NAMES) reserved.add(name)\n const desired = desiredCommands(catalog, reserved, (agent, line) => this.#target.forward(agent, line))\n\n for (const [name, live] of [...this.#live]) {\n const next = desired.get(name)\n if (next?.signature === live.signature) continue\n live.dispose()\n this.#live.delete(name)\n }\n for (const [name, next] of desired) {\n if (this.#live.has(name)) continue\n this.#live.set(name, {\n signature: next.signature,\n dispose: this.#target.register(next.definition),\n })\n }\n return [...desired.values()].map(({ publicName, claudeName, prefixed }) => ({\n publicName,\n claudeName,\n prefixed,\n }))\n }\n\n dispose(): void {\n for (const command of this.#live.values()) command.dispose()\n this.#live.clear()\n }\n}\n","/**\n * Presentation-only tool definitions for the Claude Code preset. Claude Code\n * owns tool execution; these definitions exist solely so the host's tool\n * presentation pipeline (`viewFor` → `presentCall`/`presentResult`) can\n * compute native render intents for the mirrored `tool/call`/`tool/result`\n * events, giving Claude tool rows the same cards DSH-executed tools get.\n */\nimport type { ToolDefinition, ToolResult } from '@deepseek-ai/dsh-tools'\nimport type { ToolCallView, ToolResultView } from '@deepseek-ai/dsh-tools/presentation'\n\nfunction record(value: unknown): Record<string, unknown> | undefined {\n return value !== null && typeof value === 'object' && !Array.isArray(value) ? value as Record<string, unknown> : undefined\n}\n\nfunction str(value: unknown): string | undefined {\n return typeof value === 'string' && value.length > 0 ? value : undefined\n}\n\nfunction resultText(result: ToolResult): string {\n return result.content\n .filter((block): block is Extract<typeof block, { type: 'text' }> => block.type === 'text')\n .map(block => block.text)\n .join('\\n')\n}\n\n/** Bash: a terminal card headed by the command, described above by Claude's own summary. */\nexport function bashCallView(args: unknown): ToolCallView | undefined {\n const command = str(record(args)?.command)\n if (command === undefined) return undefined\n const description = str(record(args)?.description)\n return { card: 'terminal', title: command, ...(description === undefined ? {} : { description }) }\n}\n\nexport function terminalResultView(_args: unknown, result: ToolResult): ToolResultView | undefined {\n const output = resultText(result)\n return output.length === 0 ? undefined : { card: 'terminal', output }\n}\n\n/** Read: a generic read card that follow-alongs the file window. */\nexport function readCallView(args: unknown): ToolCallView | undefined {\n const arguments_ = record(args)\n const path = str(arguments_?.file_path)\n if (path === undefined) return undefined\n const offset = typeof arguments_?.offset === 'number' ? arguments_.offset : undefined\n return {\n card: 'generic',\n kind: 'read',\n title: `Read ${path}`,\n locations: [{ path, ...(offset === undefined ? {} : { line: offset }) }],\n }\n}\n\nfunction fileDiffs(args: unknown): { path: string; oldText: string | null; newText: string }[] | undefined {\n const arguments_ = record(args)\n const path = str(arguments_?.file_path)\n if (path === undefined) return undefined\n if (Array.isArray(arguments_?.edits)) {\n const diffs: { path: string; oldText: string | null; newText: string }[] = []\n for (const edit of arguments_.edits) {\n const item = record(edit)\n const oldText = str(item?.old_string)\n const newText = str(item?.new_string)\n if (newText === undefined) continue\n diffs.push({ path, oldText: oldText ?? null, newText })\n }\n return diffs.length > 0 ? diffs : undefined\n }\n const newText = str(arguments_?.new_string) ?? arguments_?.content\n if (typeof newText !== 'string' || newText.length === 0) return undefined\n const oldText = str(arguments_?.old_string)\n return [{ path, oldText: oldText ?? null, newText }]\n}\n\n/** Edit / MultiEdit / Write: inline diff cards derived from the call arguments. */\nexport function diffCallView(args: unknown): ToolCallView | undefined {\n const arguments_ = record(args)\n const path = str(arguments_?.file_path)\n const diffs = fileDiffs(args)\n if (path === undefined || diffs === undefined) return undefined\n const verb = typeof arguments_?.new_string === 'string' || Array.isArray(arguments_?.edits) ? 'Edit' : 'Write'\n return { card: 'diff', title: `${verb} ${path}`, diffs, locations: [{ path }] }\n}\n\n/** Grep / Glob / WebSearch: search-category cards titled by the query. */\nexport function searchCallView(args: unknown): ToolCallView | undefined {\n const arguments_ = record(args)\n const query = str(arguments_?.pattern) ?? str(arguments_?.query)\n if (query === undefined) return undefined\n const scope = str(arguments_?.path)\n return {\n card: 'generic',\n kind: 'search',\n title: scope === undefined ? query : `${query} · ${scope}`,\n rawInput: args,\n }\n}\n\n/** WebFetch: a fetch-category card titled by the URL. */\nexport function fetchCallView(args: unknown): ToolCallView | undefined {\n const url = str(record(args)?.url)\n if (url === undefined) return undefined\n return { card: 'generic', kind: 'fetch', title: url, rawInput: args }\n}\n\n/** Task: a subagent card titled by Claude's task description. */\nexport function taskCallView(args: unknown): ToolCallView | undefined {\n const arguments_ = record(args)\n const title = str(arguments_?.description) ?? str(arguments_?.subagent_type) ?? 'Subagent'\n return { card: 'generic', kind: 'other', title, rawInput: args }\n}\n\nfunction genericTitle(title: string): ToolCallView {\n return { card: 'generic', kind: 'other', title }\n}\n\nfunction presenterDefinition(\n name: string,\n description: string,\n presentCall?: (args: unknown) => ToolCallView | undefined,\n presentResult?: (args: unknown, result: ToolResult) => ToolResultView | undefined,\n): ToolDefinition {\n return {\n name,\n description,\n parameters: { type: 'object', properties: {} },\n output: {\n schema: { type: 'object', properties: {} } as ToolDefinition['output']['schema'],\n render: () => [],\n },\n execute: async () => {\n throw new Error(`dsh-claude: Claude Code owns execution of ${name}`)\n },\n ...(presentCall === undefined ? {} : { presentCall }),\n ...(presentResult === undefined ? {} : { presentResult }),\n }\n}\n\nconst PRESENTATION_NOTE = 'Presentation mirror of the Claude Code tool; execution is owned by Claude Code.'\n\n/** Generic call view for dynamically observed tools (MCP tools, new built-ins). */\nexport function genericCallView(toolName: string): (args: unknown) => ToolCallView | undefined {\n return (args: unknown) => {\n const description = str(record(args)?.description)\n return { card: 'generic', kind: 'other', title: description ?? toolName, rawInput: args }\n }\n}\n\n/** One presenter-only mirror for a tool name discovered at runtime. */\nexport function dynamicPresenterDefinition(name: string): ToolDefinition {\n return presenterDefinition(name, PRESENTATION_NOTE, genericCallView(name))\n}\n\n/** The presentation-only registry contributed to the Claude Code preset scope. */\nexport function claudePresenterDefinitions(): ToolDefinition[] {\n return [\n presenterDefinition('Bash', PRESENTATION_NOTE, bashCallView, terminalResultView),\n presenterDefinition('Read', PRESENTATION_NOTE, readCallView),\n presenterDefinition('Edit', PRESENTATION_NOTE, diffCallView),\n presenterDefinition('MultiEdit', PRESENTATION_NOTE, diffCallView),\n presenterDefinition('Write', PRESENTATION_NOTE, diffCallView),\n presenterDefinition('NotebookEdit', PRESENTATION_NOTE, args => {\n const path = str(record(args)?.notebook_path)\n return path === undefined ? undefined : genericTitle(`NotebookEdit ${path}`)\n }),\n presenterDefinition('Grep', PRESENTATION_NOTE, searchCallView),\n presenterDefinition('Glob', PRESENTATION_NOTE, searchCallView),\n presenterDefinition('WebSearch', PRESENTATION_NOTE, searchCallView),\n presenterDefinition('WebFetch', PRESENTATION_NOTE, fetchCallView),\n presenterDefinition('Task', PRESENTATION_NOTE, taskCallView),\n presenterDefinition('TodoWrite', PRESENTATION_NOTE, () => genericTitle('Update todos')),\n ]\n}\n\n/** Names covered by the static preset-scope registry; dynamic mirrors skip them. */\nexport const CLAUDE_PRESENTER_NAMES: ReadonlySet<string> = new Set(claudePresenterDefinitions().map(definition => definition.name))\n"],"mappings":"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"}