@norman-else/dsh-claude 0.1.45 → 0.1.47
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.
- package/INSTALL.md +55 -55
- package/LICENSE +21 -21
- package/README.md +199 -200
- package/cordis.patch.yml +12 -12
- package/legacy-preset/agent.cordis.yml +11 -11
- package/legacy-preset/preset.yml +4 -4
- package/lib/bin.mjs +1 -1
- package/lib/bin.mjs.map +1 -1
- package/lib/client.d.ts +5 -11
- package/lib/client.js +1044 -1147
- package/lib/client.js.map +1 -1
- package/lib/{events-oovRTmX7.mjs → events-B498uofA.mjs} +2 -3
- package/lib/events-B498uofA.mjs.map +1 -0
- package/lib/index.d.mts +0 -1
- package/lib/index.mjs +254 -237
- package/lib/index.mjs.map +1 -1
- package/lib/{presenters-BVWj7u0a.mjs → presenters-CRFcjLSC.mjs} +2 -2
- package/lib/presenters-CRFcjLSC.mjs.map +1 -0
- package/lib/{preset-installer-CuosP3sA.mjs → preset-installer-C4TTNV9L.mjs} +2 -2
- package/lib/preset-installer-C4TTNV9L.mjs.map +1 -0
- package/lib/preset-route.mjs +2 -2
- package/lib/preset-route.mjs.map +1 -1
- package/package.json +222 -197
- package/preset/claude/agent.cordis.yml +11 -11
- package/preset/claude/preset.yml +4 -4
- package/lib/events-oovRTmX7.mjs.map +0 -1
- package/lib/presenters-BVWj7u0a.mjs.map +0 -1
- package/lib/preset-installer-CuosP3sA.mjs.map +0 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { l as redactText } from "./events-
|
|
1
|
+
import { l as redactText } from "./events-B498uofA.mjs";
|
|
2
2
|
//#region src/command-bridge.ts
|
|
3
3
|
const COMMAND_NAME = /^[a-z][a-z0-9_-]*$/u;
|
|
4
4
|
const MAX_DESCRIPTION_CHARS = 300;
|
|
@@ -316,4 +316,4 @@ const CLAUDE_PRESENTER_NAMES = new Set(claudePresenterDefinitions().map((definit
|
|
|
316
316
|
//#endregion
|
|
317
317
|
export { projectClaudeCommands as a, CLAUDE_COMMANDS_SERVICE as i, claudePresenterDefinitions as n, dynamicPresenterDefinition as r, CLAUDE_PRESENTER_NAMES as t };
|
|
318
318
|
|
|
319
|
-
//# sourceMappingURL=presenters-
|
|
319
|
+
//# sourceMappingURL=presenters-CRFcjLSC.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"presenters-CRFcjLSC.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 const commandBases = new Set<string>()\n for (const claudeName of names) {\n const base = registryName(claudeName)\n if (base === undefined || commandBases.has(base)) continue\n commandBases.add(base)\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/** Edit / MultiEdit / Write results: the same diff, again.\n *\n * A completed card replaces the pending one, so a mutation that returns no\n * result view loses its diff to the raw result text. The plugin transcript\n * drops the diff on failure and shows the error instead; mirror that. */\nexport function diffResultView(args: unknown, result: ToolResult): ToolResultView | undefined {\n if (result.isError) return undefined\n const diffs = fileDiffs(args)\n return diffs === undefined ? undefined : { card: 'diff', diffs }\n}\n\nfunction parsedResult(result: ToolResult): unknown {\n const text = resultText(result)\n if (text.length === 0) return undefined\n try {\n return JSON.parse(text) as unknown\n } catch {\n return text\n }\n}\n\n/** Grep / Glob results: the discovered paths as a search card.\n *\n * Only the structured `filenames` shape is projected. A text result (Grep's\n * content mode) carries its own formatting, so it falls through to the raw\n * result content rather than being re-parsed into fake match groups. */\nexport function searchResultView(_args: unknown, result: ToolResult): ToolResultView | undefined {\n if (result.isError) return undefined\n const output = record(parsedResult(result))\n if (!Array.isArray(output?.filenames)) return undefined\n const paths = output.filenames.filter((item): item is string => typeof item === 'string')\n const reported = output.numFiles\n const total = typeof reported === 'number' && Number.isInteger(reported) && reported >= paths.length ? reported : paths.length\n return { card: 'search', shape: 'paths', paths, truncated: total > paths.length, total }\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/** ExitPlanMode: the plan itself, as prose rather than as tool arguments.\n *\n * This is the one built-in tool whose whole payload is written for the user\n * to read: Claude asks to leave plan mode and the approval that follows is\n * the user agreeing to the plan. Rendering it as `Input: {\"plan\":\"...\"}`\n * buries the only thing worth reading, so the plan becomes the card body. */\nexport function planCallView(args: unknown): ToolCallView | undefined {\n const plan = str(record(args)?.plan)\n return plan === undefined ? undefined : {\n card: 'generic',\n kind: 'other',\n title: 'Plan ready for review',\n content: [{ type: 'text', text: plan }],\n }\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 // The plugin transcript gives PowerShell the same terminal treatment as\n // Bash; without its own mirror the native card would fall back to generic.\n presenterDefinition('PowerShell', PRESENTATION_NOTE, bashCallView, terminalResultView),\n presenterDefinition('Read', PRESENTATION_NOTE, readCallView),\n presenterDefinition('Edit', PRESENTATION_NOTE, diffCallView, diffResultView),\n presenterDefinition('MultiEdit', PRESENTATION_NOTE, diffCallView, diffResultView),\n presenterDefinition('Write', PRESENTATION_NOTE, diffCallView, diffResultView),\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, searchResultView),\n presenterDefinition('Glob', PRESENTATION_NOTE, searchCallView, searchResultView),\n presenterDefinition('WebSearch', PRESENTATION_NOTE, searchCallView),\n presenterDefinition('WebFetch', PRESENTATION_NOTE, fetchCallView),\n presenterDefinition('Task', PRESENTATION_NOTE, taskCallView),\n presenterDefinition('ExitPlanMode', PRESENTATION_NOTE, planCallView),\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,4 +1,4 @@
|
|
|
1
|
-
import { h as CLAUDE_CODE_PRESET_ID, l as redactText } from "./events-
|
|
1
|
+
import { h as CLAUDE_CODE_PRESET_ID, l as redactText } from "./events-B498uofA.mjs";
|
|
2
2
|
import { randomUUID } from "node:crypto";
|
|
3
3
|
import { access, link, lstat, mkdir, readFile, readdir, rm, rmdir, writeFile } from "node:fs/promises";
|
|
4
4
|
import { dirname, isAbsolute, join, win32 } from "node:path";
|
|
@@ -304,4 +304,4 @@ async function removeManagedPreset(paths = defaultManagedPresetPaths()) {
|
|
|
304
304
|
//#endregion
|
|
305
305
|
export { resolveClaudeExecutable as a, parseClaudeVersion as i, ensureManagedPreset as n, runClaudeDoctor as o, removeManagedPreset as r, ManagedPresetConflictError as t };
|
|
306
306
|
|
|
307
|
-
//# sourceMappingURL=preset-installer-
|
|
307
|
+
//# sourceMappingURL=preset-installer-C4TTNV9L.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"preset-installer-C4TTNV9L.mjs","names":[],"sources":["../src/executable.ts","../src/preset-installer.ts"],"sourcesContent":["import { constants } from 'node:fs'\nimport { access } from 'node:fs/promises'\nimport { homedir } from 'node:os'\nimport { isAbsolute, join, win32 } from 'node:path'\nimport type { SubprocessHandle, SubprocessRuntime } from '@deepseek-ai/dsh-subprocess'\nimport { redactText } from './events.ts'\n\nconst VERSION_PATTERN = /(?:Claude Code\\s+)?v?(\\d+\\.\\d+\\.\\d+(?:[-+][\\w.-]+)?)/i\nconst MAX_PROBE_STDOUT = 64 * 1024\nconst MAX_PROBE_STDERR = 8 * 1024\n\nexport type ExecutableRuntime = Pick<SubprocessRuntime, 'resolveExecutable' | 'spawn'>\n\nexport class ClaudeExecutableNotFoundError extends Error {\n readonly searched: readonly string[]\n\n constructor(searched: readonly string[], options?: ErrorOptions) {\n super(`Claude Code executable not found. Searched: ${searched.join(', ')}`, options)\n this.name = 'ClaudeExecutableNotFoundError'\n this.searched = [...searched]\n }\n}\n\nexport interface ClaudeExecutableResolution {\n path: string\n searched: readonly string[]\n}\n\nexport interface ClaudeDoctorReport {\n executable: {\n status: 'found' | 'missing'\n path?: string\n searched: readonly string[]\n }\n version: {\n status: 'ok' | 'error' | 'not-run'\n value?: string\n message?: string\n }\n authentication: {\n status: 'signed-in' | 'signed-out' | 'unknown' | 'not-run'\n method?: string\n provider?: string\n subscription?: string\n message?: string\n }\n handshake: 'not-run' | 'ok' | 'error'\n}\n\nfunction fallbackCandidates(): string[] {\n if (process.platform !== 'darwin') return []\n return [\n join(homedir(), '.local', 'bin', 'claude'),\n '/opt/homebrew/bin/claude',\n '/usr/local/bin/claude',\n ]\n}\n\nfunction abortError(error: unknown): boolean {\n return error instanceof Error && (error.name === 'AbortError' || error.name === 'TimeoutError')\n}\n\n/**\n * Prefer the package's own native binary over a Windows npm shim.\n *\n * A PATH lookup on Windows answers `claude.CMD`, and since the fix for\n * CVE-2024-27980 Node refuses to spawn `.cmd` and `.bat` without\n * `shell: true` — every probe and every session then fails with\n * `spawn EINVAL`, reported to the user as an executable and authentication\n * error with nothing pointing at the file extension. Auto-resolution\n * therefore cannot work on Windows at all, and the user has to discover\n * `executablePath` to get anywhere.\n *\n * npm installs the package beside the shim it writes, and\n * `@anthropic-ai/claude-code` ships a native executable (its own manifest\n * declares `\"bin\": { \"claude\": \"bin/claude.exe\" }`), which carries no such\n * restriction. Falling back to the shim keeps a layout that does not match\n * this assumption working exactly as before.\n *\n * @param path - the resolved candidate, possibly a Windows shim.\n * @returns the native executable when one sits beside the shim, else `path`.\n */\nasync function preferNativeWindowsBinary(path: string): Promise<string> {\n if (process.platform !== 'win32') return path\n if (!/\\.(?:cmd|bat)$/iu.test(path)) return path\n const native = win32.join(\n win32.dirname(path),\n 'node_modules',\n '@anthropic-ai',\n 'claude-code',\n 'bin',\n 'claude.exe',\n )\n try {\n await access(native, constants.X_OK)\n return native\n } catch {\n return path\n }\n}\n\nexport async function resolveClaudeExecutable(\n runtime: ExecutableRuntime,\n configuredPath?: string,\n signal?: AbortSignal,\n): Promise<ClaudeExecutableResolution> {\n const searched: string[] = []\n const candidates = configuredPath === undefined\n ? ['claude', ...fallbackCandidates()]\n : [configuredPath]\n if (configuredPath !== undefined && !isAbsolute(configuredPath) && !win32.isAbsolute(configuredPath)) {\n throw new Error(`Claude Code executable path must be absolute: ${configuredPath}`)\n }\n\n let lastError: unknown\n for (const candidate of candidates) {\n if (searched.includes(candidate)) continue\n searched.push(candidate)\n try {\n const resolved = await runtime.resolveExecutable(candidate, undefined, signal)\n return { path: await preferNativeWindowsBinary(resolved), searched }\n } catch (error) {\n if (abortError(error) || signal?.aborted === true) throw error\n lastError = error\n }\n }\n throw new ClaudeExecutableNotFoundError(searched, lastError === undefined ? undefined : { cause: lastError })\n}\n\ninterface CollectedCommand {\n exitCode: number | null\n signal: NodeJS.Signals | null\n stdout: string\n stderr: string\n}\n\nasync function collect(handle: SubprocessHandle): Promise<CollectedCommand> {\n const outcome = await handle.done\n const stdout = handle.collected.stdout?.readFrom(0).text ?? ''\n const stderr = handle.collected.stderr?.readFrom(0).text ?? ''\n return { ...outcome, stdout, stderr }\n}\n\nasync function runProbe(\n runtime: ExecutableRuntime,\n executable: string,\n args: readonly string[],\n cwd: string,\n signal?: AbortSignal,\n): Promise<CollectedCommand> {\n return collect(runtime.spawn({\n argv: [executable, ...args],\n cwd,\n stdio: {\n stdin: 'ignore',\n stdout: { maxBytes: MAX_PROBE_STDOUT },\n stderr: { maxBytes: MAX_PROBE_STDERR },\n },\n graceMs: 2_000,\n ...(signal === undefined ? {} : { signal }),\n env: {},\n }))\n}\n\nexport function parseClaudeVersion(output: string): string | undefined {\n return VERSION_PATTERN.exec(output)?.[1]\n}\n\nexport async function probeClaudeVersion(\n runtime: ExecutableRuntime,\n executable: string,\n cwd: string,\n signal?: AbortSignal,\n): Promise<string> {\n const result = await runProbe(runtime, executable, ['--version'], cwd, signal)\n const version = parseClaudeVersion(`${result.stdout}\\n${result.stderr}`)\n if (result.exitCode !== 0 || version === undefined) {\n throw new Error(`Claude Code version probe failed (${result.exitCode ?? result.signal ?? 'unknown exit'})`)\n }\n return version\n}\n\nexport async function probeClaudeAuthentication(\n runtime: ExecutableRuntime,\n executable: string,\n cwd: string,\n signal?: AbortSignal,\n): Promise<ClaudeDoctorReport['authentication']> {\n const result = await runProbe(runtime, executable, ['auth', 'status', '--json'], cwd, signal)\n if (result.exitCode !== 0) {\n return { status: 'unknown', message: 'Claude authentication status command failed' }\n }\n try {\n const value = JSON.parse(result.stdout) as Record<string, unknown>\n const report: ClaudeDoctorReport['authentication'] = {\n status: value.loggedIn === true ? 'signed-in' : value.loggedIn === false ? 'signed-out' : 'unknown',\n }\n if (typeof value.authMethod === 'string') report.method = redactText(value.authMethod, 100)\n if (typeof value.apiProvider === 'string') report.provider = redactText(value.apiProvider, 100)\n if (typeof value.subscriptionType === 'string') report.subscription = redactText(value.subscriptionType, 100)\n return report\n } catch {\n return { status: 'unknown', message: 'Claude authentication status was not valid JSON' }\n }\n}\n\nexport async function runClaudeDoctor(\n runtime: ExecutableRuntime,\n options: { configuredPath?: string; cwd: string; signal?: AbortSignal },\n): Promise<ClaudeDoctorReport> {\n let resolution: ClaudeExecutableResolution\n try {\n resolution = await resolveClaudeExecutable(runtime, options.configuredPath, options.signal)\n } catch (error) {\n if (error instanceof ClaudeExecutableNotFoundError) {\n return {\n executable: { status: 'missing', searched: error.searched },\n version: { status: 'not-run' },\n authentication: { status: 'not-run' },\n handshake: 'not-run',\n }\n }\n throw error\n }\n\n const report: ClaudeDoctorReport = {\n executable: { status: 'found', path: resolution.path, searched: resolution.searched },\n version: { status: 'not-run' },\n authentication: { status: 'not-run' },\n handshake: 'not-run',\n }\n try {\n report.version = {\n status: 'ok',\n value: await probeClaudeVersion(runtime, resolution.path, options.cwd, options.signal),\n }\n } catch (error) {\n report.version = {\n status: 'error',\n message: error instanceof Error ? error.message : 'Version probe failed',\n }\n }\n try {\n report.authentication = await probeClaudeAuthentication(runtime, resolution.path, options.cwd, options.signal)\n } catch (error) {\n report.authentication = {\n status: 'unknown',\n message: error instanceof Error ? error.message : 'Authentication probe failed',\n }\n }\n return report\n}\n","import { randomUUID } from 'node:crypto'\nimport { link, lstat, mkdir, readFile, readdir, rm, rmdir, writeFile } from 'node:fs/promises'\nimport { dirname, join } from 'node:path'\nimport { fileURLToPath } from 'node:url'\nimport { dshHomePath } from '@deepseek-ai/dsh-home-paths'\nimport { CLAUDE_CODE_PRESET_ID } from './constants.ts'\n\nexport const MANAGED_PRESET_FILES = ['agent.cordis.yml', 'preset.yml'] as const\n\n/** Package specifier kept in the installed template. DSH Desktop 2.0.4 resolves\n * it through the active profile package factory, so the preset route and client\n * module share one Loader source. An absolute built entry would register a\n * second source and make the Desktop renderer reject the plugin graph. */\nconst PRESET_ROUTE_PACKAGE_SPECIFIER = '@norman-else/dsh-claude/preset-route'\n\nexport class ManagedPresetConflictError extends Error {\n readonly path: string\n\n constructor(path: string) {\n super(`dsh-claude: refusing to overwrite user-modified preset file ${path}`)\n this.name = 'ManagedPresetConflictError'\n this.path = path\n }\n}\n\nexport interface ManagedPresetPaths {\n sourceDir: string\n targetDir: string\n}\n\nexport function defaultManagedPresetPaths(dshHome?: string): ManagedPresetPaths {\n const packageRoot = fileURLToPath(new URL('../', import.meta.url))\n return {\n sourceDir: join(packageRoot, 'legacy-preset'),\n targetDir: dshHome === undefined\n ? dshHomePath('.agent-presets', CLAUDE_CODE_PRESET_ID)\n : join(dshHome, '.agent-presets', CLAUDE_CODE_PRESET_ID),\n }\n}\n\ninterface ManagedContent {\n file: string\n /** Content this installer version writes. */\n content: string\n /** Older installer-written contents that may be silently upgraded/removed. */\n legacy: readonly string[]\n /** Legacy detection for contents that predate the current template. */\n isLegacy(current: string): boolean\n}\n\nasync function managedContents(paths: ManagedPresetPaths): Promise<ManagedContent[]> {\n return await Promise.all(MANAGED_PRESET_FILES.map(async (file): Promise<ManagedContent> => {\n const source = await readFile(join(paths.sourceDir, file), 'utf8')\n const nameRow = `name: '${PRESET_ROUTE_PACKAGE_SPECIFIER}'`\n const legacyNameRow = `name: ${PRESET_ROUTE_PACKAGE_SPECIFIER}`\n if (file !== 'agent.cordis.yml' || !source.includes(nameRow)) {\n return { file, content: source, legacy: [], isLegacy: () => false }\n }\n return {\n file,\n content: source,\n legacy: [],\n // Earlier installers wrote either an unquoted specifier or an absolute\n // built-module path. Both are installer-owned and safe to converge to the\n // single profile package source used by Desktop 2.0.4.\n // Older installers wrote the route as an absolute path; on Windows that\n // path carries backslashes, so compare with separators normalized.\n isLegacy: current =>\n current.includes('id: claude-code-route')\n && (current.includes(legacyNameRow)\n || current.replaceAll('\\\\', '/').includes('lib/preset-route.mjs')),\n }\n }))\n}\n\nasync function readIfPresent(path: string): Promise<string | undefined> {\n try {\n return await readFile(path, 'utf8')\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === 'ENOENT') return undefined\n throw error\n }\n}\n\nasync function atomicWrite(path: string, content: string): Promise<boolean> {\n await mkdir(dirname(path), { recursive: true })\n const temporary = `${path}.${randomUUID()}.tmp`\n try {\n await writeFile(temporary, content, { encoding: 'utf8', mode: 0o600, flag: 'wx' })\n try {\n await link(temporary, path)\n return true\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code !== 'EEXIST') throw error\n if (await readIfPresent(path) === content) return false\n throw new ManagedPresetConflictError(path)\n }\n } finally {\n await rm(temporary, { force: true })\n }\n}\n\nexport async function ensureManagedPreset(paths = defaultManagedPresetPaths()): Promise<'installed' | 'unchanged'> {\n await assertSafeTargetDirectory(paths.targetDir)\n const expected = await managedContents(paths)\n let changed = false\n for (const { file, content, legacy, isLegacy } of expected) {\n const target = join(paths.targetDir, file)\n const current = await readIfPresent(target)\n if (current === content) continue\n if (current !== undefined) {\n // Upgrade installer-written legacy content in place; never touch user edits.\n if (!legacy.includes(current) && !isLegacy(current)) throw new ManagedPresetConflictError(target)\n await rm(target)\n }\n changed = await atomicWrite(target, content) || changed\n }\n return changed ? 'installed' : 'unchanged'\n}\n\n/** Reject a target directory that is a symlink (or occupies the path as a file)\n * so the managed preset never writes through an attacker-controlled link. */\nasync function assertSafeTargetDirectory(targetDir: string): Promise<void> {\n try {\n const stat = await lstat(targetDir)\n if (!stat.isDirectory() || stat.isSymbolicLink()) {\n throw new ManagedPresetConflictError(targetDir)\n }\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === 'ENOENT') return\n throw error\n }\n}\n\nexport async function removeManagedPreset(paths = defaultManagedPresetPaths()): Promise<'removed' | 'absent'> {\n await assertSafeTargetDirectory(paths.targetDir)\n const expected = await managedContents(paths)\n const managedTargets: string[] = []\n for (const { file, content, legacy, isLegacy } of expected) {\n const target = join(paths.targetDir, file)\n const current = await readIfPresent(target)\n if (current === undefined) continue\n if (current !== content && !legacy.includes(current) && !isLegacy(current)) throw new ManagedPresetConflictError(target)\n managedTargets.push(target)\n }\n for (const target of managedTargets) await rm(target)\n try {\n if ((await readdir(paths.targetDir)).length === 0) await rmdir(paths.targetDir)\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code !== 'ENOENT') throw error\n }\n return managedTargets.length > 0 ? 'removed' : 'absent'\n}\n"],"mappings":"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"}
|
package/lib/preset-route.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { g as CLAUDE_CODE_PROVIDER } from "./events-
|
|
2
|
-
import { i as CLAUDE_COMMANDS_SERVICE, n as claudePresenterDefinitions } from "./presenters-
|
|
1
|
+
import { g as CLAUDE_CODE_PROVIDER } from "./events-B498uofA.mjs";
|
|
2
|
+
import { i as CLAUDE_COMMANDS_SERVICE, n as claudePresenterDefinitions } from "./presenters-CRFcjLSC.mjs";
|
|
3
3
|
//#region src/preset-route.ts
|
|
4
4
|
const name = "claude-code-preset-route";
|
|
5
5
|
const inject = ["tools", "commands"];
|
package/lib/preset-route.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"preset-route.mjs","names":[],"sources":["../src/preset-route.ts"],"sourcesContent":["import type { Context } from '@deepseek-ai/cordis'\
|
|
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,197 +1,222 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "@norman-else/dsh-claude",
|
|
3
|
-
"description": "Run the local Claude Code CLI as a first-class main conversation inside DeepSeek Harness",
|
|
4
|
-
"version": "0.1.
|
|
5
|
-
"type": "module",
|
|
6
|
-
"main": "lib/index.mjs",
|
|
7
|
-
"types": "lib/index.d.mts",
|
|
8
|
-
"bin": {
|
|
9
|
-
"dsh-claude": "lib/bin.mjs"
|
|
10
|
-
},
|
|
11
|
-
"scripts": {
|
|
12
|
-
"build": "tsdown",
|
|
13
|
-
"typecheck": "tsc -p tsconfig.json && tsc -p tsconfig.client.json",
|
|
14
|
-
"test": "vitest run",
|
|
15
|
-
"check": "pnpm run typecheck && pnpm run test && pnpm run build",
|
|
16
|
-
"prepack": "pnpm run build",
|
|
17
|
-
"release": "node scripts/publish.mjs",
|
|
18
|
-
"release:check": "node scripts/publish.mjs --dry-run"
|
|
19
|
-
},
|
|
20
|
-
"exports": {
|
|
21
|
-
".": {
|
|
22
|
-
"types": "./lib/index.d.mts",
|
|
23
|
-
"default": "./lib/index.mjs"
|
|
24
|
-
},
|
|
25
|
-
"./preset-route": {
|
|
26
|
-
"types": "./lib/preset-route.d.mts",
|
|
27
|
-
"default": "./lib/preset-route.mjs"
|
|
28
|
-
},
|
|
29
|
-
"./client": "./lib/client.js",
|
|
30
|
-
"./package.json": "./package.json"
|
|
31
|
-
},
|
|
32
|
-
"files": [
|
|
33
|
-
"lib",
|
|
34
|
-
"preset",
|
|
35
|
-
"legacy-preset",
|
|
36
|
-
"cordis.patch.yml",
|
|
37
|
-
"README.md",
|
|
38
|
-
"INSTALL.md",
|
|
39
|
-
"LICENSE"
|
|
40
|
-
],
|
|
41
|
-
"license": "MIT",
|
|
42
|
-
"repository": {
|
|
43
|
-
"type": "git",
|
|
44
|
-
"url": "git+https://github.com/Norman-else/dsh-claude.git"
|
|
45
|
-
},
|
|
46
|
-
"homepage": "https://github.com/Norman-else/dsh-claude#readme",
|
|
47
|
-
"bugs": {
|
|
48
|
-
"url": "https://github.com/Norman-else/dsh-claude/issues"
|
|
49
|
-
},
|
|
50
|
-
"publishConfig": {
|
|
51
|
-
"access": "public"
|
|
52
|
-
},
|
|
53
|
-
"engines": {
|
|
54
|
-
"node": ">=20"
|
|
55
|
-
},
|
|
56
|
-
"dsh": {
|
|
57
|
-
"bundle": {
|
|
58
|
-
"patch": "./cordis.patch.yml"
|
|
59
|
-
},
|
|
60
|
-
"client": {
|
|
61
|
-
"inject": [
|
|
62
|
-
"@deepseek-ai/dsh-client-connection",
|
|
63
|
-
"@deepseek-ai/dsh-api-session-controller",
|
|
64
|
-
"@deepseek-ai/dsh-api-workspace-controller",
|
|
65
|
-
"@deepseek-ai/dsh-api-remotes",
|
|
66
|
-
"@deepseek-ai/dsh-client-ui-chat",
|
|
67
|
-
"@deepseek-ai/dsh-client-ui-conversation",
|
|
68
|
-
"@deepseek-ai/dsh-client-ui-input-trigger",
|
|
69
|
-
"@deepseek-ai/dsh-client-ui-renderer",
|
|
70
|
-
"@deepseek-ai/dsh-client-ui-session",
|
|
71
|
-
"@deepseek-ai/dsh-client-ui-settings",
|
|
72
|
-
"@deepseek-ai/dsh-client-locale"
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
"
|
|
80
|
-
"
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
"@deepseek-ai/
|
|
85
|
-
"@deepseek-ai/dsh-agent
|
|
86
|
-
"@deepseek-ai/dsh-
|
|
87
|
-
"@deepseek-ai/dsh-
|
|
88
|
-
"@deepseek-ai/dsh-
|
|
89
|
-
"@deepseek-ai/dsh-client-
|
|
90
|
-
"@deepseek-ai/dsh-client-
|
|
91
|
-
"@deepseek-ai/dsh-client-ui-
|
|
92
|
-
"@deepseek-ai/dsh-client-ui-
|
|
93
|
-
"@deepseek-ai/dsh-client-ui-
|
|
94
|
-
"@deepseek-ai/dsh-client-ui-
|
|
95
|
-
"@deepseek-ai/dsh-
|
|
96
|
-
"@deepseek-ai/dsh-
|
|
97
|
-
"@deepseek-ai/dsh-
|
|
98
|
-
"@deepseek-ai/dsh-
|
|
99
|
-
"@deepseek-ai/dsh-
|
|
100
|
-
"@deepseek-ai/dsh-
|
|
101
|
-
"@deepseek-ai/dsh-
|
|
102
|
-
"@deepseek-ai/dsh-
|
|
103
|
-
"@deepseek-ai/dsh-
|
|
104
|
-
"@deepseek-ai/dsh-
|
|
105
|
-
"@deepseek-ai/
|
|
106
|
-
"
|
|
107
|
-
"
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
"@deepseek-ai/
|
|
113
|
-
"@deepseek-ai/dsh-agent
|
|
114
|
-
"@deepseek-ai/dsh-
|
|
115
|
-
"@deepseek-ai/dsh-
|
|
116
|
-
"@deepseek-ai/dsh-api-
|
|
117
|
-
"@deepseek-ai/dsh-api-
|
|
118
|
-
"@deepseek-ai/dsh-
|
|
119
|
-
"@deepseek-ai/dsh-
|
|
120
|
-
"@deepseek-ai/dsh-
|
|
121
|
-
"@deepseek-ai/dsh-
|
|
122
|
-
"@deepseek-ai/dsh-
|
|
123
|
-
"@deepseek-ai/dsh-client-
|
|
124
|
-
"@deepseek-ai/dsh-client-
|
|
125
|
-
"@deepseek-ai/dsh-client-
|
|
126
|
-
"@deepseek-ai/dsh-client-
|
|
127
|
-
"@deepseek-ai/dsh-client-
|
|
128
|
-
"@deepseek-ai/dsh-client-ui-
|
|
129
|
-
"@deepseek-ai/dsh-client-ui-
|
|
130
|
-
"@deepseek-ai/dsh-client-ui-
|
|
131
|
-
"@deepseek-ai/dsh-client-ui-
|
|
132
|
-
"@deepseek-ai/dsh-client-ui-
|
|
133
|
-
"@deepseek-ai/dsh-client-ui-
|
|
134
|
-
"@deepseek-ai/dsh-client-ui-
|
|
135
|
-
"@deepseek-ai/dsh-
|
|
136
|
-
"@deepseek-ai/dsh-
|
|
137
|
-
"@deepseek-ai/dsh-
|
|
138
|
-
"@deepseek-ai/dsh-
|
|
139
|
-
"@deepseek-ai/dsh-
|
|
140
|
-
"@deepseek-ai/dsh-
|
|
141
|
-
"@deepseek-ai/dsh-
|
|
142
|
-
"@deepseek-ai/dsh-
|
|
143
|
-
"@deepseek-ai/dsh-
|
|
144
|
-
"@deepseek-ai/dsh-
|
|
145
|
-
"@deepseek-ai/dsh-
|
|
146
|
-
"@deepseek-ai/dsh-
|
|
147
|
-
"@deepseek-ai/dsh-
|
|
148
|
-
"@deepseek-ai/dsh-
|
|
149
|
-
"@deepseek-ai/dsh-
|
|
150
|
-
"@deepseek-ai/dsh-
|
|
151
|
-
"@deepseek-ai/dsh-
|
|
152
|
-
"@deepseek-ai/dsh-
|
|
153
|
-
"@deepseek-ai/dsh-
|
|
154
|
-
"@deepseek-ai/dsh-
|
|
155
|
-
"@deepseek-ai/dsh-
|
|
156
|
-
"@deepseek-ai/dsh-
|
|
157
|
-
"@deepseek-ai/dsh-
|
|
158
|
-
"@deepseek-ai/dsh-
|
|
159
|
-
"@deepseek-ai/dsh-
|
|
160
|
-
"@deepseek-ai/dsh-
|
|
161
|
-
"@deepseek-ai/dsh-
|
|
162
|
-
"@deepseek-ai/dsh-
|
|
163
|
-
"@deepseek-ai/dsh-
|
|
164
|
-
"@deepseek-ai/dsh-
|
|
165
|
-
"@deepseek-ai/dsh-session
|
|
166
|
-
"@deepseek-ai/dsh-session-
|
|
167
|
-
"@deepseek-ai/dsh-
|
|
168
|
-
"@deepseek-ai/dsh-
|
|
169
|
-
"@deepseek-ai/dsh-
|
|
170
|
-
"@deepseek-ai/dsh-
|
|
171
|
-
"@deepseek-ai/dsh-
|
|
172
|
-
"@deepseek-ai/dsh-
|
|
173
|
-
"@deepseek-ai/dsh-
|
|
174
|
-
"@deepseek-ai/dsh-
|
|
175
|
-
"@deepseek-ai/dsh-
|
|
176
|
-
"@deepseek-ai/dsh-
|
|
177
|
-
"@deepseek-ai/dsh-
|
|
178
|
-
"@deepseek-ai/dsh-
|
|
179
|
-
"@deepseek-ai/dsh-
|
|
180
|
-
"@deepseek-ai/dsh-
|
|
181
|
-
"@deepseek-ai/dsh-
|
|
182
|
-
"@deepseek-ai/dsh-
|
|
183
|
-
"@deepseek-ai/dsh-
|
|
184
|
-
"@deepseek-ai/dsh-
|
|
185
|
-
"@deepseek-ai/dsh-
|
|
186
|
-
"@deepseek-ai/
|
|
187
|
-
"@
|
|
188
|
-
"@
|
|
189
|
-
"@
|
|
190
|
-
"
|
|
191
|
-
"
|
|
192
|
-
"
|
|
193
|
-
"
|
|
194
|
-
"
|
|
195
|
-
"
|
|
196
|
-
|
|
197
|
-
|
|
1
|
+
{
|
|
2
|
+
"name": "@norman-else/dsh-claude",
|
|
3
|
+
"description": "Run the local Claude Code CLI as a first-class main conversation inside DeepSeek Harness",
|
|
4
|
+
"version": "0.1.47",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "lib/index.mjs",
|
|
7
|
+
"types": "lib/index.d.mts",
|
|
8
|
+
"bin": {
|
|
9
|
+
"dsh-claude": "lib/bin.mjs"
|
|
10
|
+
},
|
|
11
|
+
"scripts": {
|
|
12
|
+
"build": "tsdown",
|
|
13
|
+
"typecheck": "tsc -p tsconfig.json && tsc -p tsconfig.client.json",
|
|
14
|
+
"test": "vitest run",
|
|
15
|
+
"check": "pnpm run typecheck && pnpm run test && pnpm run build",
|
|
16
|
+
"prepack": "pnpm run build",
|
|
17
|
+
"release": "node scripts/publish.mjs",
|
|
18
|
+
"release:check": "node scripts/publish.mjs --dry-run"
|
|
19
|
+
},
|
|
20
|
+
"exports": {
|
|
21
|
+
".": {
|
|
22
|
+
"types": "./lib/index.d.mts",
|
|
23
|
+
"default": "./lib/index.mjs"
|
|
24
|
+
},
|
|
25
|
+
"./preset-route": {
|
|
26
|
+
"types": "./lib/preset-route.d.mts",
|
|
27
|
+
"default": "./lib/preset-route.mjs"
|
|
28
|
+
},
|
|
29
|
+
"./client": "./lib/client.js",
|
|
30
|
+
"./package.json": "./package.json"
|
|
31
|
+
},
|
|
32
|
+
"files": [
|
|
33
|
+
"lib",
|
|
34
|
+
"preset",
|
|
35
|
+
"legacy-preset",
|
|
36
|
+
"cordis.patch.yml",
|
|
37
|
+
"README.md",
|
|
38
|
+
"INSTALL.md",
|
|
39
|
+
"LICENSE"
|
|
40
|
+
],
|
|
41
|
+
"license": "MIT",
|
|
42
|
+
"repository": {
|
|
43
|
+
"type": "git",
|
|
44
|
+
"url": "git+https://github.com/Norman-else/dsh-claude.git"
|
|
45
|
+
},
|
|
46
|
+
"homepage": "https://github.com/Norman-else/dsh-claude#readme",
|
|
47
|
+
"bugs": {
|
|
48
|
+
"url": "https://github.com/Norman-else/dsh-claude/issues"
|
|
49
|
+
},
|
|
50
|
+
"publishConfig": {
|
|
51
|
+
"access": "public"
|
|
52
|
+
},
|
|
53
|
+
"engines": {
|
|
54
|
+
"node": ">=20"
|
|
55
|
+
},
|
|
56
|
+
"dsh": {
|
|
57
|
+
"bundle": {
|
|
58
|
+
"patch": "./cordis.patch.yml"
|
|
59
|
+
},
|
|
60
|
+
"client": {
|
|
61
|
+
"inject": [
|
|
62
|
+
"@deepseek-ai/dsh-client-connection",
|
|
63
|
+
"@deepseek-ai/dsh-api-session-controller",
|
|
64
|
+
"@deepseek-ai/dsh-api-workspace-controller",
|
|
65
|
+
"@deepseek-ai/dsh-api-remotes",
|
|
66
|
+
"@deepseek-ai/dsh-client-ui-chat",
|
|
67
|
+
"@deepseek-ai/dsh-client-ui-conversation",
|
|
68
|
+
"@deepseek-ai/dsh-client-ui-input-trigger",
|
|
69
|
+
"@deepseek-ai/dsh-client-ui-renderer",
|
|
70
|
+
"@deepseek-ai/dsh-client-ui-session",
|
|
71
|
+
"@deepseek-ai/dsh-client-ui-settings",
|
|
72
|
+
"@deepseek-ai/dsh-client-locale",
|
|
73
|
+
"@deepseek-ai/dsh-client-ui-sidebar-right"
|
|
74
|
+
],
|
|
75
|
+
"platform": "web"
|
|
76
|
+
}
|
|
77
|
+
},
|
|
78
|
+
"dependencies": {
|
|
79
|
+
"@anthropic-ai/claude-agent-sdk": "0.3.247",
|
|
80
|
+
"dompurify": "^3.4.14",
|
|
81
|
+
"marked": "^18.0.11"
|
|
82
|
+
},
|
|
83
|
+
"peerDependencies": {
|
|
84
|
+
"@deepseek-ai/cordis": "^4.0.1",
|
|
85
|
+
"@deepseek-ai/dsh-agent": ">=0.1.5-rc.1",
|
|
86
|
+
"@deepseek-ai/dsh-agent-presets": ">=0.1.5-rc.1",
|
|
87
|
+
"@deepseek-ai/dsh-attachment": ">=0.1.5-rc.1",
|
|
88
|
+
"@deepseek-ai/dsh-brand": ">=0.1.5-rc.1",
|
|
89
|
+
"@deepseek-ai/dsh-client-locale": ">=0.1.5-rc.1",
|
|
90
|
+
"@deepseek-ai/dsh-client-runtime": ">=0.1.1-rc.2",
|
|
91
|
+
"@deepseek-ai/dsh-client-ui-conversation": ">=0.1.5-rc.1",
|
|
92
|
+
"@deepseek-ai/dsh-client-ui-input-trigger": ">=0.1.5-rc.1",
|
|
93
|
+
"@deepseek-ai/dsh-client-ui-primitives": ">=0.1.5-rc.1",
|
|
94
|
+
"@deepseek-ai/dsh-client-ui-settings": ">=0.1.5-rc.1",
|
|
95
|
+
"@deepseek-ai/dsh-client-ui-sidebar-right": ">=0.1.5-rc.1",
|
|
96
|
+
"@deepseek-ai/dsh-client-ui-slots": ">=0.1.5-rc.1",
|
|
97
|
+
"@deepseek-ai/dsh-commands": ">=0.1.5-rc.1",
|
|
98
|
+
"@deepseek-ai/dsh-home-paths": ">=0.1.5-rc.1",
|
|
99
|
+
"@deepseek-ai/dsh-host-webserver": ">=0.1.5-rc.1",
|
|
100
|
+
"@deepseek-ai/dsh-llm": ">=0.1.5-rc.1",
|
|
101
|
+
"@deepseek-ai/dsh-session": ">=0.1.5-rc.1",
|
|
102
|
+
"@deepseek-ai/dsh-subprocess": ">=0.1.5-rc.1",
|
|
103
|
+
"@deepseek-ai/dsh-timeout": ">=0.1.5-rc.1",
|
|
104
|
+
"@deepseek-ai/dsh-tools": ">=0.1.5-rc.1",
|
|
105
|
+
"@deepseek-ai/dsh-user-approval": ">=0.1.5-rc.1",
|
|
106
|
+
"@deepseek-ai/dsh-user-questions": ">=0.1.5-rc.1",
|
|
107
|
+
"@deepseek-ai/schemastery": "^3.18.1",
|
|
108
|
+
"react": "^18.2.0",
|
|
109
|
+
"react-dom": "^18.2.0"
|
|
110
|
+
},
|
|
111
|
+
"devDependencies": {
|
|
112
|
+
"@deepseek-ai/cordis": "4.0.2",
|
|
113
|
+
"@deepseek-ai/dsh-agent": "0.1.5-rc.1",
|
|
114
|
+
"@deepseek-ai/dsh-agent-default-model": "0.1.5-rc.1",
|
|
115
|
+
"@deepseek-ai/dsh-agent-presets": "0.1.5-rc.1",
|
|
116
|
+
"@deepseek-ai/dsh-api-gateway": "0.1.5-rc.1",
|
|
117
|
+
"@deepseek-ai/dsh-api-remotes": "0.1.5-rc.1",
|
|
118
|
+
"@deepseek-ai/dsh-api-session-controller": "0.1.5-rc.1",
|
|
119
|
+
"@deepseek-ai/dsh-api-workspace-controller": "0.1.5-rc.1",
|
|
120
|
+
"@deepseek-ai/dsh-atomic-write": "0.1.5-rc.1",
|
|
121
|
+
"@deepseek-ai/dsh-attachment": "0.1.5-rc.1",
|
|
122
|
+
"@deepseek-ai/dsh-brand": "0.1.5-rc.1",
|
|
123
|
+
"@deepseek-ai/dsh-client-connection": "0.1.5-rc.1",
|
|
124
|
+
"@deepseek-ai/dsh-client-locale": "0.1.5-rc.1",
|
|
125
|
+
"@deepseek-ai/dsh-client-resources": "0.1.5-rc.1",
|
|
126
|
+
"@deepseek-ai/dsh-client-runtime": "0.1.1-rc.2",
|
|
127
|
+
"@deepseek-ai/dsh-client-store": "0.1.5-rc.1",
|
|
128
|
+
"@deepseek-ai/dsh-client-ui-chat": "0.1.5-rc.1",
|
|
129
|
+
"@deepseek-ai/dsh-client-ui-conversation": "0.1.5-rc.1",
|
|
130
|
+
"@deepseek-ai/dsh-client-ui-input-trigger": "0.1.5-rc.1",
|
|
131
|
+
"@deepseek-ai/dsh-client-ui-layout": "0.1.5-rc.1",
|
|
132
|
+
"@deepseek-ai/dsh-client-ui-primitives": "0.1.5-rc.1",
|
|
133
|
+
"@deepseek-ai/dsh-client-ui-renderer": "0.1.5-rc.1",
|
|
134
|
+
"@deepseek-ai/dsh-client-ui-session": "0.1.5-rc.1",
|
|
135
|
+
"@deepseek-ai/dsh-client-ui-settings": "0.1.5-rc.1",
|
|
136
|
+
"@deepseek-ai/dsh-client-ui-sidebar-right": "0.1.5-rc.1",
|
|
137
|
+
"@deepseek-ai/dsh-client-ui-slots": "0.1.5-rc.1",
|
|
138
|
+
"@deepseek-ai/dsh-client-ui-theme": "0.1.5-rc.1",
|
|
139
|
+
"@deepseek-ai/dsh-code-runtime": "0.1.5-rc.1",
|
|
140
|
+
"@deepseek-ai/dsh-commands": "0.1.5-rc.1",
|
|
141
|
+
"@deepseek-ai/dsh-compaction": "0.1.5-rc.1",
|
|
142
|
+
"@deepseek-ai/dsh-cordis-host-runner": "0.1.5-rc.1",
|
|
143
|
+
"@deepseek-ai/dsh-credentials": "0.1.5-rc.1",
|
|
144
|
+
"@deepseek-ai/dsh-deque": "0.1.5-rc.1",
|
|
145
|
+
"@deepseek-ai/dsh-file-reference": "0.1.5-rc.1",
|
|
146
|
+
"@deepseek-ai/dsh-fs": "0.1.5-rc.1",
|
|
147
|
+
"@deepseek-ai/dsh-goal": "0.1.5-rc.1",
|
|
148
|
+
"@deepseek-ai/dsh-home-paths": "0.1.5-rc.1",
|
|
149
|
+
"@deepseek-ai/dsh-host-apiproxy": "0.1.1-rc.2",
|
|
150
|
+
"@deepseek-ai/dsh-host-directory-picker": "0.1.5-rc.1",
|
|
151
|
+
"@deepseek-ai/dsh-host-plugin-inventory": "0.1.5-rc.1",
|
|
152
|
+
"@deepseek-ai/dsh-host-webserver": "0.1.5-rc.1",
|
|
153
|
+
"@deepseek-ai/dsh-invariants": "0.1.5-rc.1",
|
|
154
|
+
"@deepseek-ai/dsh-jobs": "0.1.5-rc.1",
|
|
155
|
+
"@deepseek-ai/dsh-llm": "0.1.5-rc.1",
|
|
156
|
+
"@deepseek-ai/dsh-llm-retry": "0.1.5-rc.1",
|
|
157
|
+
"@deepseek-ai/dsh-message-feedback": "0.1.5-rc.1",
|
|
158
|
+
"@deepseek-ai/dsh-native-command": "0.1.5-rc.1",
|
|
159
|
+
"@deepseek-ai/dsh-output-retention": "0.1.5-rc.1",
|
|
160
|
+
"@deepseek-ai/dsh-permission-presets": "0.1.5-rc.1",
|
|
161
|
+
"@deepseek-ai/dsh-plan-mode": "0.1.5-rc.1",
|
|
162
|
+
"@deepseek-ai/dsh-sandbox": "0.1.5-rc.1",
|
|
163
|
+
"@deepseek-ai/dsh-sandbox-policy": "0.1.5-rc.1",
|
|
164
|
+
"@deepseek-ai/dsh-scope": "0.1.5-rc.1",
|
|
165
|
+
"@deepseek-ai/dsh-session": "0.1.5-rc.1",
|
|
166
|
+
"@deepseek-ai/dsh-session-persistence": "0.1.5-rc.1",
|
|
167
|
+
"@deepseek-ai/dsh-session-projection": "0.1.5-rc.1",
|
|
168
|
+
"@deepseek-ai/dsh-session-projection-cache": "0.1.5-rc.1",
|
|
169
|
+
"@deepseek-ai/dsh-session-query": "0.1.5-rc.1",
|
|
170
|
+
"@deepseek-ai/dsh-session-reference": "0.1.5-rc.1",
|
|
171
|
+
"@deepseek-ai/dsh-session-stats": "0.1.5-rc.1",
|
|
172
|
+
"@deepseek-ai/dsh-session-title": "0.1.5-rc.1",
|
|
173
|
+
"@deepseek-ai/dsh-settings": "0.1.5-rc.1",
|
|
174
|
+
"@deepseek-ai/dsh-shell": "0.1.5-rc.1",
|
|
175
|
+
"@deepseek-ai/dsh-skill": "0.1.5-rc.1",
|
|
176
|
+
"@deepseek-ai/dsh-storage": "0.1.5-rc.1",
|
|
177
|
+
"@deepseek-ai/dsh-storage-domain": "0.1.5-rc.1",
|
|
178
|
+
"@deepseek-ai/dsh-subagent": "0.1.5-rc.1",
|
|
179
|
+
"@deepseek-ai/dsh-subprocess": "0.1.5-rc.1",
|
|
180
|
+
"@deepseek-ai/dsh-system-prompt": "0.1.5-rc.1",
|
|
181
|
+
"@deepseek-ai/dsh-timeout": "0.1.5-rc.1",
|
|
182
|
+
"@deepseek-ai/dsh-token-meter": "0.1.5-rc.1",
|
|
183
|
+
"@deepseek-ai/dsh-tool-todo": "0.1.5-rc.1",
|
|
184
|
+
"@deepseek-ai/dsh-tools": "0.1.5-rc.1",
|
|
185
|
+
"@deepseek-ai/dsh-typert-protocol": "0.1.5-rc.1",
|
|
186
|
+
"@deepseek-ai/dsh-typert-registry": "0.1.5-rc.1",
|
|
187
|
+
"@deepseek-ai/dsh-user-approval": "0.1.5-rc.1",
|
|
188
|
+
"@deepseek-ai/dsh-user-questions": "0.1.5-rc.1",
|
|
189
|
+
"@deepseek-ai/dsh-util-time": "0.1.5-rc.1",
|
|
190
|
+
"@deepseek-ai/dsh-util-values": "0.1.5-rc.1",
|
|
191
|
+
"@deepseek-ai/dsh-util-workspace-path": "0.1.5-rc.1",
|
|
192
|
+
"@deepseek-ai/dsh-workspace": "0.1.5-rc.1",
|
|
193
|
+
"@deepseek-ai/schemastery": "^3.18.2",
|
|
194
|
+
"@shikijs/langs": "^4.4.3",
|
|
195
|
+
"@types/node": "^22.20.1",
|
|
196
|
+
"@types/react": "~18.3.31",
|
|
197
|
+
"@types/react-dom": "~18.3.7",
|
|
198
|
+
"anser": "^2.3.5",
|
|
199
|
+
"clsx": "2.1.1",
|
|
200
|
+
"jsdom": "^30.0.1",
|
|
201
|
+
"katex": "^0.18.7",
|
|
202
|
+
"mdast-util-from-markdown": "^2.0.3",
|
|
203
|
+
"mdast-util-gfm": "^3.1.0",
|
|
204
|
+
"mdast-util-math": "^3.0.0",
|
|
205
|
+
"micromark-core-commonmark": "^2.0.3",
|
|
206
|
+
"micromark-extension-gfm": "^3.0.0",
|
|
207
|
+
"micromark-extension-math": "^3.1.0",
|
|
208
|
+
"micromark-factory-space": "^2.0.1",
|
|
209
|
+
"micromark-util-character": "^2.1.1",
|
|
210
|
+
"micromark-util-classify-character": "^2.0.1",
|
|
211
|
+
"micromark-util-sanitize-uri": "^2.0.1",
|
|
212
|
+
"micromark-util-symbol": "^2.0.1",
|
|
213
|
+
"mime-types": "3.0.2",
|
|
214
|
+
"react": "18.2.0",
|
|
215
|
+
"react-dom": "18.2.0",
|
|
216
|
+
"shiki": "^4.4.3",
|
|
217
|
+
"tsdown": "^0.22.14",
|
|
218
|
+
"typescript": "^5.9.3",
|
|
219
|
+
"vitest": "^4.1.11",
|
|
220
|
+
"zod": "4.4.3"
|
|
221
|
+
}
|
|
222
|
+
}
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
# Shipped by dsh-claude. Claude Code owns the inner agent loop and tools;
|
|
2
|
-
# this system preset contributes only the request-route override. DSH resolves
|
|
3
|
-
# the bare package specifier from the host profile when mounting system roots.
|
|
4
|
-
- id: claude-code-route
|
|
5
|
-
name: '@norman-else/dsh-claude/preset-route'
|
|
6
|
-
# Entry-local isolate realm: each session's preset mount gets its own
|
|
7
|
-
# claudeCommands service instance (keeps mountPreset's leaked-service check
|
|
8
|
-
# happy and prevents cross-session collisions). The host reads it through
|
|
9
|
-
# dsh-agent-presets' serviceForAgent().
|
|
10
|
-
isolate:
|
|
11
|
-
claudeCommands: true
|
|
1
|
+
# Shipped by dsh-claude. Claude Code owns the inner agent loop and tools;
|
|
2
|
+
# this system preset contributes only the request-route override. DSH resolves
|
|
3
|
+
# the bare package specifier from the host profile when mounting system roots.
|
|
4
|
+
- id: claude-code-route
|
|
5
|
+
name: '@norman-else/dsh-claude/preset-route'
|
|
6
|
+
# Entry-local isolate realm: each session's preset mount gets its own
|
|
7
|
+
# claudeCommands service instance (keeps mountPreset's leaked-service check
|
|
8
|
+
# happy and prevents cross-session collisions). The host reads it through
|
|
9
|
+
# dsh-agent-presets' serviceForAgent().
|
|
10
|
+
isolate:
|
|
11
|
+
claudeCommands: true
|