@norman-else/dsh-claude 0.1.25 → 0.1.27

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 CHANGED
@@ -1,55 +1,55 @@
1
- # Agent Installation Runbook
2
-
3
- This runbook is idempotent for a local `dsh-claude` checkout and an existing DSH `web` profile.
4
-
5
- ## 1. Verify the checkout
6
-
7
- ```sh
8
- cd /path/to/dsh-claude
9
- export PATH="/opt/homebrew/bin:$PATH"
10
- pnpm install
11
- pnpm check
12
- node lib/bin.mjs doctor
13
- ```
14
-
15
- Stop if Doctor cannot find an authenticated local Claude Code installation. Do not request, copy, or write credentials.
16
-
17
- ## 2. Link the bundle into the current Web profile
18
-
19
- The bundle retains its package-contained system preset and installs a protected compatibility copy at `$DSH_HOME/.agent-presets/claude` during Host activation. This works around supported DSH release-candidate builds replacing third-party preset roots. Existing user-modified files are preserved rather than overwritten.
20
-
21
- ```sh
22
- dsh plugin --profile web add "link:$(pwd)"
23
- ```
24
-
25
- Do not start another DSH Web server. This bundle must load in the existing app at `http://127.0.0.1:56454`.
26
-
27
- ## 3. Refresh and smoke test
28
-
29
- 1. Refresh the existing DSH Web page.
30
- 2. Confirm **Claude** appears in the new-session Agent Preset picker.
31
- 3. Run one existing native preset prompt and verify it remains native.
32
- 4. Create a Claude session and send a read-only prompt.
33
- 5. Send one edit prompt; verify DSH displays a permission request. Exercise reject first, then allow once with a harmless temporary file.
34
- 6. Cancel a running prompt and confirm the cancelled session owns no child `claude` process that is still executing cancelled work or left orphaned/unowned.
35
- 7. Refresh the browser and continue the session.
36
- 8. Restart DSH and confirm the next prompt resumes the persisted Claude session.
37
-
38
- A live prompt can consume the user's Claude subscription. Keep it minimal.
39
-
40
- ## 4. Uninstall
41
-
42
- Clean up the managed preset while the profile can still execute the package CLI, then remove the plugin:
43
-
44
- ```sh
45
- dsh plugin --profile web exec dsh-claude remove-preset
46
- dsh plugin --profile web remove @norman-else/dsh-claude
47
- ```
48
-
49
- DSH has no plugin uninstall lifecycle hook, so direct package removal can leave the compatibility preset behind. After direct removal, no source checkout is required; run the matching package version:
50
-
51
- ```sh
52
- pnpm dlx @norman-else/dsh-claude@<version> remove-preset
53
- ```
54
-
55
- Cleanup refuses to delete user-modified preset content.
1
+ # Agent Installation Runbook
2
+
3
+ This runbook is idempotent for a local `dsh-claude` checkout and an existing DSH `web` profile.
4
+
5
+ ## 1. Verify the checkout
6
+
7
+ ```sh
8
+ cd /path/to/dsh-claude
9
+ export PATH="/opt/homebrew/bin:$PATH"
10
+ pnpm install
11
+ pnpm check
12
+ node lib/bin.mjs doctor
13
+ ```
14
+
15
+ Stop if Doctor cannot find an authenticated local Claude Code installation. Do not request, copy, or write credentials.
16
+
17
+ ## 2. Link the bundle into the current Web profile
18
+
19
+ The bundle retains its package-contained system preset and installs a protected compatibility copy at `$DSH_HOME/.agent-presets/claude` during Host activation. This works around supported DSH release-candidate builds replacing third-party preset roots. Existing user-modified files are preserved rather than overwritten.
20
+
21
+ ```sh
22
+ dsh plugin --profile web add "link:$(pwd)"
23
+ ```
24
+
25
+ Do not start another DSH Web server. This bundle must load in the existing app at `http://127.0.0.1:56454`.
26
+
27
+ ## 3. Refresh and smoke test
28
+
29
+ 1. Refresh the existing DSH Web page.
30
+ 2. Confirm **Claude** appears in the new-session Agent Preset picker.
31
+ 3. Run one existing native preset prompt and verify it remains native.
32
+ 4. Create a Claude session and send a read-only prompt.
33
+ 5. Send one edit prompt; verify DSH displays a permission request. Exercise reject first, then allow once with a harmless temporary file.
34
+ 6. Cancel a running prompt and confirm the cancelled session owns no child `claude` process that is still executing cancelled work or left orphaned/unowned.
35
+ 7. Refresh the browser and continue the session.
36
+ 8. Restart DSH and confirm the next prompt resumes the persisted Claude session.
37
+
38
+ A live prompt can consume the user's Claude subscription. Keep it minimal.
39
+
40
+ ## 4. Uninstall
41
+
42
+ Clean up the managed preset while the profile can still execute the package CLI, then remove the plugin:
43
+
44
+ ```sh
45
+ dsh plugin --profile web exec dsh-claude remove-preset
46
+ dsh plugin --profile web remove @norman-else/dsh-claude
47
+ ```
48
+
49
+ DSH has no plugin uninstall lifecycle hook, so direct package removal can leave the compatibility preset behind. After direct removal, no source checkout is required; run the matching package version:
50
+
51
+ ```sh
52
+ pnpm dlx @norman-else/dsh-claude@<version> remove-preset
53
+ ```
54
+
55
+ Cleanup refuses to delete user-modified preset content.
package/LICENSE CHANGED
@@ -1,21 +1,21 @@
1
- MIT License
2
-
3
- Copyright (c) 2026 dsh-claude contributors
4
-
5
- Permission is hereby granted, free of charge, to any person obtaining a copy
6
- of this software and associated documentation files (the "Software"), to deal
7
- in the Software without restriction, including without limitation the rights
8
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- copies of the Software, and to permit persons to whom the Software is
10
- furnished to do so, subject to the following conditions:
11
-
12
- The above copyright notice and this permission notice shall be included in all
13
- copies or substantial portions of the Software.
14
-
15
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
- SOFTWARE.
1
+ MIT License
2
+
3
+ Copyright (c) 2026 dsh-claude contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,82 +1,82 @@
1
- # dsh-claude
2
-
3
- ## 1. Overview
4
-
5
- `dsh-claude` runs the locally installed Claude Code CLI as a first-class conversation provider inside DeepSeek Harness (DSH). It uses Claude Code's official Agent SDK protocol instead of recreating the agent with a separate API client.
6
-
7
- Claude Code remains responsible for its agent loop, tools, `CLAUDE.md`, Skills, Hooks, Plugins, MCP servers, settings, and authentication. DSH provides the conversation UI, approval and question surfaces, repository workflow, activity presentation, and managed process lifetime.
8
-
9
- ## 2. Installation and removal
10
-
11
- ### Requirements
12
-
13
- - DeepSeek Harness Desktop with compatible public plugin APIs. This package is currently developed against the DSH `0.1.1-rc.2` package line.
14
- - A local Claude Code installation that is already authenticated.
15
- - Node.js 20 or later when installing from a source checkout.
16
-
17
- The plugin never asks for or stores Claude credentials. Authenticate through the local Claude Code CLI before using the plugin.
18
-
19
- ### Install from npm
20
-
21
- Add the published package to the DSH Web profile:
22
-
23
- ```sh
24
- dsh plugin --profile web add @norman-else/dsh-claude
25
- ```
26
-
27
- Wait for the profile rebuild to finish, then restart DSH Desktop if requested. Create a new conversation and select **Claude** from the Agent Preset picker.
28
-
29
- ### Install from source
30
-
31
- ```sh
32
- git clone https://github.com/Norman-else/dsh-claude.git
33
- cd dsh-claude
34
- pnpm install
35
- pnpm check
36
- ```
37
-
38
- Link the checkout to DSH from PowerShell:
39
-
40
- ```powershell
41
- dsh plugin --profile web add "link:$PWD"
42
- ```
43
-
44
- Or from macOS/Linux:
45
-
46
- ```sh
47
- dsh plugin --profile web add "link:$(pwd)"
48
- ```
49
-
50
- ### Remove the plugin
51
-
52
- Remove the managed compatibility preset before removing the package:
53
-
54
- ```sh
55
- dsh plugin --profile web exec dsh-claude remove-preset
56
- dsh plugin --profile web remove @norman-else/dsh-claude
57
- ```
58
-
59
- DSH does not currently expose a plugin uninstall lifecycle hook. If the package was removed before its managed preset was cleaned up, run the matching installed version directly:
60
-
61
- ```sh
62
- pnpm dlx @norman-else/dsh-claude@<version> remove-preset
63
- ```
64
-
65
- Preset cleanup removes only installer-managed content and refuses to delete user-modified preset files.
66
-
67
- ## 3. Features
68
-
69
- - **Native Claude Code conversations** — Runs Claude Code as the main agent in a normal DSH conversation instead of wrapping it as a tool or secondary chat.
70
- - **Claude preset and model selection** — Adds a `Claude` Agent Preset and exposes Claude Code's `default`, `opus[1m]`, `fable`, `sonnet`, and `haiku` model choices.
71
- - **Local Claude environment compatibility** — Preserves the user's existing Claude Code authentication, settings, `CLAUDE.md`, Skills, Hooks, Plugins, tools, and MCP configuration.
72
- - **Real-time streaming and conversation continuity** — Streams Claude responses and tool activity into DSH while retaining multi-turn context and persisted Claude session resume.
73
- - **DSH permissions and questions** — Routes Claude tool permission requests through DSH approvals and Claude clarification prompts through DSH's native question forms.
74
- - **Managed process lifecycle** — Keeps one live Claude process per active session, serializes turns, evicts idle processes, and handles Stop, cancellation, restart, and process-tree cleanup.
75
- - **Redacted activity timeline** — Displays thinking summaries, tool calls and results, permission events, questions, status changes, usage, errors, and subagent activity without persisting credentials.
76
- - **Background task tracking** — Shows running and completed Claude subagents or background tasks with task status, recent tools, and expandable activity.
77
- - **Repository and worktree preparation** — Lets a user choose a branch before submitting, switch an eligible local branch, or create a dedicated Git worktree and DSH workspace while transferring the current draft and attachments, and removes a worktree's directory automatically once its workspace is deleted and the tree is clean.
78
- - **Repository and pull request status** — Shows the current repository, branch, worktree state, changed-line counts, unpushed commits, GitHub pull request, checks, review state, merge state, and blocking Claude rate limits near the composer.
79
- - **Diff viewer and review comments** — Provides an expandable or maximized branch diff, including file statistics and line-level review comments that are attached to the next Claude message.
80
- - **Commit, push, and pull request actions** — Supports Commit, Commit & Push, Push, and draft pull request creation, with repository snapshot validation and optional Claude-generated commit messages.
81
- - **Claude Code settings and Doctor** — Adds a Settings panel for runtime diagnostics, supported Claude settings, worktree branch prefix, process limits, authentication and handshake status, and safe npm update checks.
82
- - **Managed preset compatibility** — Installs an idempotent compatibility copy of the Claude preset for supported DSH builds without overwriting user-modified preset content.
1
+ # dsh-claude
2
+
3
+ ## 1. Overview
4
+
5
+ `dsh-claude` runs the locally installed Claude Code CLI as a first-class conversation provider inside DeepSeek Harness (DSH). It uses Claude Code's official Agent SDK protocol instead of recreating the agent with a separate API client.
6
+
7
+ Claude Code remains responsible for its agent loop, tools, `CLAUDE.md`, Skills, Hooks, Plugins, MCP servers, settings, and authentication. DSH provides the conversation UI, approval and question surfaces, repository workflow, activity presentation, and managed process lifetime.
8
+
9
+ ## 2. Installation and removal
10
+
11
+ ### Requirements
12
+
13
+ - DeepSeek Harness Desktop with compatible public plugin APIs. This package is currently developed against the DSH `0.1.1-rc.2` package line.
14
+ - A local Claude Code installation that is already authenticated.
15
+ - Node.js 20 or later when installing from a source checkout.
16
+
17
+ The plugin never asks for or stores Claude credentials. Authenticate through the local Claude Code CLI before using the plugin.
18
+
19
+ ### Install from npm
20
+
21
+ Add the published package to the DSH Web profile:
22
+
23
+ ```sh
24
+ dsh plugin --profile web add @norman-else/dsh-claude
25
+ ```
26
+
27
+ Wait for the profile rebuild to finish, then restart DSH Desktop if requested. Create a new conversation and select **Claude** from the Agent Preset picker.
28
+
29
+ ### Install from source
30
+
31
+ ```sh
32
+ git clone https://github.com/Norman-else/dsh-claude.git
33
+ cd dsh-claude
34
+ pnpm install
35
+ pnpm check
36
+ ```
37
+
38
+ Link the checkout to DSH from PowerShell:
39
+
40
+ ```powershell
41
+ dsh plugin --profile web add "link:$PWD"
42
+ ```
43
+
44
+ Or from macOS/Linux:
45
+
46
+ ```sh
47
+ dsh plugin --profile web add "link:$(pwd)"
48
+ ```
49
+
50
+ ### Remove the plugin
51
+
52
+ Remove the managed compatibility preset before removing the package:
53
+
54
+ ```sh
55
+ dsh plugin --profile web exec dsh-claude remove-preset
56
+ dsh plugin --profile web remove @norman-else/dsh-claude
57
+ ```
58
+
59
+ DSH does not currently expose a plugin uninstall lifecycle hook. If the package was removed before its managed preset was cleaned up, run the matching installed version directly:
60
+
61
+ ```sh
62
+ pnpm dlx @norman-else/dsh-claude@<version> remove-preset
63
+ ```
64
+
65
+ Preset cleanup removes only installer-managed content and refuses to delete user-modified preset files.
66
+
67
+ ## 3. Features
68
+
69
+ - **Native Claude Code conversations** — Runs Claude Code as the main agent in a normal DSH conversation instead of wrapping it as a tool or secondary chat.
70
+ - **Claude preset and model selection** — Adds a `Claude` Agent Preset and exposes Claude Code's `default`, `opus[1m]`, `fable`, `sonnet`, and `haiku` model choices.
71
+ - **Local Claude environment compatibility** — Preserves the user's existing Claude Code authentication, settings, `CLAUDE.md`, Skills, Hooks, Plugins, tools, and MCP configuration.
72
+ - **Real-time streaming and conversation continuity** — Streams Claude responses and tool activity into DSH while retaining multi-turn context and persisted Claude session resume.
73
+ - **DSH permissions and questions** — Routes Claude tool permission requests through DSH approvals and Claude clarification prompts through DSH's native question forms.
74
+ - **Managed process lifecycle** — Keeps one live Claude process per active session, serializes turns, evicts idle processes, and handles Stop, cancellation, restart, and process-tree cleanup.
75
+ - **Redacted activity timeline** — Displays thinking summaries, tool calls and results, permission events, questions, status changes, usage, errors, and subagent activity without persisting credentials.
76
+ - **Background task tracking** — Shows running and completed Claude subagents or background tasks with task status, recent tools, and expandable activity.
77
+ - **Repository and worktree preparation** — Lets a user choose a branch before submitting, switch an eligible local branch, or create a dedicated Git worktree and DSH workspace while transferring the current draft and attachments, and removes a worktree's directory automatically once its workspace is deleted and the tree is clean.
78
+ - **Repository and pull request status** — Shows the current repository, branch, worktree state, changed-line counts, unpushed commits, GitHub pull request, checks, review state, merge state, and blocking Claude rate limits near the composer.
79
+ - **Diff viewer and review comments** — Provides an expandable or maximized branch diff, including file statistics and line-level review comments that are attached to the next Claude message.
80
+ - **Commit, push, and pull request actions** — Supports Commit, Commit & Push, Push, and draft pull request creation, with repository snapshot validation and optional Claude-generated commit messages.
81
+ - **Claude Code settings and Doctor** — Adds a Settings panel for runtime diagnostics, supported Claude settings, worktree branch prefix, process limits, authentication and handshake status, and safe npm update checks.
82
+ - **Managed preset compatibility** — Installs an idempotent compatibility copy of the Claude preset for supported DSH builds without overwriting user-modified preset content.
package/cordis.patch.yml CHANGED
@@ -1,12 +1,12 @@
1
- # dsh-claude host bundle. The preset stays inside this package as a system
2
- # preset, so removing the profile dependency removes the complete integration.
3
- - id: agent-presets
4
- config:
5
- default: standard
6
- roots:
7
- - path: !!js "process.getBuiltinModule('node:path').join(process.getBuiltinModule('node:path').dirname(process.getBuiltinModule('node:module').createRequire(ctx.baseUrl).resolve('@norman-else/dsh-claude/package.json')), 'preset')"
8
- trust: system
9
-
10
- - insert:
11
- - id: llm-claude
12
- name: '@norman-else/dsh-claude'
1
+ # dsh-claude host bundle. The preset stays inside this package as a system
2
+ # preset, so removing the profile dependency removes the complete integration.
3
+ - id: agent-presets
4
+ config:
5
+ default: standard
6
+ roots:
7
+ - path: !!js "process.getBuiltinModule('node:path').join(process.getBuiltinModule('node:path').dirname(process.getBuiltinModule('node:module').createRequire(ctx.baseUrl).resolve('@norman-else/dsh-claude/package.json')), 'preset')"
8
+ trust: system
9
+
10
+ - insert:
11
+ - id: llm-claude
12
+ name: '@norman-else/dsh-claude'
@@ -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
@@ -1,4 +1,4 @@
1
- # Shipped by dsh-claude. Copy this system preset under a new id to customize it.
2
- name: Claude
3
- description: Use the local Claude Code as the complete agent runtime inside DSH.
4
- order: 10
1
+ # Shipped by dsh-claude. Copy this system preset under a new id to customize it.
2
+ name: Claude
3
+ description: Use the local Claude Code as the complete agent runtime inside DSH.
4
+ order: 10
package/lib/bin.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { i as parseClaudeVersion, n as ensureManagedPreset, r as removeManagedPreset } from "./preset-installer-Bzw8tuGI.mjs";
2
+ import { i as parseClaudeVersion, n as ensureManagedPreset, r as removeManagedPreset } from "./preset-installer-CPOH9lAr.mjs";
3
3
  import { access } from "node:fs/promises";
4
4
  import { delimiter, isAbsolute, join } from "node:path";
5
5
  import { homedir } from "node:os";
package/lib/bin.mjs.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"bin.mjs","names":[],"sources":["../src/bin.ts"],"sourcesContent":["#!/usr/bin/env node\r\n\r\nimport { access } from 'node:fs/promises'\r\nimport { constants } from 'node:fs'\r\nimport { homedir } from 'node:os'\r\nimport { delimiter, isAbsolute, join } from 'node:path'\r\nimport { spawnSync } from 'node:child_process'\r\nimport { scrubbedParentEnv } from '@deepseek-ai/dsh-subprocess'\r\nimport { parseClaudeVersion } from './executable.ts'\r\nimport { ensureManagedPreset, removeManagedPreset } from './preset-installer.ts'\r\n\r\nfunction option(name: string): string | undefined {\r\n const index = process.argv.indexOf(name)\r\n return index < 0 ? undefined : process.argv[index + 1]\r\n}\r\n\r\nasync function executable(configured?: string): Promise<string | undefined> {\r\n const candidates: string[] = []\r\n if (configured !== undefined) candidates.push(configured)\r\n else {\r\n for (const directory of (process.env.PATH ?? '').split(delimiter)) {\r\n if (directory.length > 0) candidates.push(join(directory, 'claude'))\r\n }\r\n candidates.push(join(homedir(), '.local', 'bin', 'claude'), '/opt/homebrew/bin/claude', '/usr/local/bin/claude')\r\n }\r\n for (const candidate of [...new Set(candidates)]) {\r\n if (!isAbsolute(candidate)) continue\r\n try {\r\n await access(candidate, constants.X_OK)\r\n return candidate\r\n } catch {\r\n // Continue to the next documented candidate.\r\n }\r\n }\r\n return undefined\r\n}\r\n\r\nfunction run(executablePath: string, args: string[]) {\r\n return spawnSync(executablePath, args, {\r\n encoding: 'utf8',\r\n env: scrubbedParentEnv(),\r\n timeout: 15_000,\r\n windowsHide: true,\r\n })\r\n}\r\n\r\nasync function doctor(): Promise<number> {\r\n const configured = option('--executable') ?? process.env.DSH_CLAUDE_CODE_EXECUTABLE\r\n const path = await executable(configured)\r\n if (path === undefined) {\r\n process.stdout.write(`${JSON.stringify({\r\n executable: { status: 'missing', searched: configured === undefined ? ['claude', '~/.local/bin/claude', '/opt/homebrew/bin/claude', '/usr/local/bin/claude'] : [configured] },\r\n version: { status: 'not-run' },\r\n authentication: { status: 'not-run' },\r\n message: 'Set executablePath to an absolute Claude Code CLI path',\r\n }, null, 2)}\\n`)\r\n return 1\r\n }\r\n const versionProbe = run(path, ['--version'])\r\n const version = parseClaudeVersion(`${versionProbe.stdout ?? ''}\\n${versionProbe.stderr ?? ''}`)\r\n const authProbe = run(path, ['auth', 'status', '--json'])\r\n let authentication: Record<string, unknown> = { status: 'unknown' }\r\n if (authProbe.status === 0) {\r\n try {\r\n const value = JSON.parse(authProbe.stdout) as Record<string, unknown>\r\n authentication = {\r\n status: value.loggedIn === true ? 'signed-in' : 'signed-out',\r\n ...(typeof value.authMethod === 'string' ? { method: value.authMethod } : {}),\r\n ...(typeof value.apiProvider === 'string' ? { provider: value.apiProvider } : {}),\r\n ...(typeof value.subscriptionType === 'string' ? { subscription: value.subscriptionType } : {}),\r\n }\r\n } catch {\r\n authentication = { status: 'unknown', message: 'Authentication status was not valid JSON' }\r\n }\r\n }\r\n process.stdout.write(`${JSON.stringify({\r\n executable: { status: 'found', path },\r\n version: version === undefined ? { status: 'error' } : { status: 'ok', value: version },\r\n authentication,\r\n handshake: 'not-run',\r\n }, null, 2)}\\n`)\r\n return version === undefined ? 1 : 0\r\n}\r\n\r\nasync function main(): Promise<number> {\r\n const command = process.argv[2] ?? 'doctor'\r\n if (command === 'doctor') return doctor()\r\n if (command === 'install-preset') {\r\n process.stdout.write(`${await ensureManagedPreset()}\\n`)\r\n return 0\r\n }\r\n if (command === 'remove-preset') {\r\n process.stdout.write(`${await removeManagedPreset()}\\n`)\r\n return 0\r\n }\r\n process.stderr.write(`Usage: dsh-claude [doctor [--executable PATH] | install-preset | remove-preset]\\n`)\r\n return 2\r\n}\r\n\r\ntry {\r\n process.exitCode = await main()\r\n} catch (error) {\r\n process.stderr.write(`${error instanceof Error ? error.message : String(error)}\\n`)\r\n process.exitCode = 1\r\n}\r\n"],"mappings":"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"}
1
+ {"version":3,"file":"bin.mjs","names":[],"sources":["../src/bin.ts"],"sourcesContent":["#!/usr/bin/env node\n\nimport { access } from 'node:fs/promises'\nimport { constants } from 'node:fs'\nimport { homedir } from 'node:os'\nimport { delimiter, isAbsolute, join } from 'node:path'\nimport { spawnSync } from 'node:child_process'\nimport { scrubbedParentEnv } from '@deepseek-ai/dsh-subprocess'\nimport { parseClaudeVersion } from './executable.ts'\nimport { ensureManagedPreset, removeManagedPreset } from './preset-installer.ts'\n\nfunction option(name: string): string | undefined {\n const index = process.argv.indexOf(name)\n return index < 0 ? undefined : process.argv[index + 1]\n}\n\nasync function executable(configured?: string): Promise<string | undefined> {\n const candidates: string[] = []\n if (configured !== undefined) candidates.push(configured)\n else {\n for (const directory of (process.env.PATH ?? '').split(delimiter)) {\n if (directory.length > 0) candidates.push(join(directory, 'claude'))\n }\n candidates.push(join(homedir(), '.local', 'bin', 'claude'), '/opt/homebrew/bin/claude', '/usr/local/bin/claude')\n }\n for (const candidate of [...new Set(candidates)]) {\n if (!isAbsolute(candidate)) continue\n try {\n await access(candidate, constants.X_OK)\n return candidate\n } catch {\n // Continue to the next documented candidate.\n }\n }\n return undefined\n}\n\nfunction run(executablePath: string, args: string[]) {\n return spawnSync(executablePath, args, {\n encoding: 'utf8',\n env: scrubbedParentEnv(),\n timeout: 15_000,\n windowsHide: true,\n })\n}\n\nasync function doctor(): Promise<number> {\n const configured = option('--executable') ?? process.env.DSH_CLAUDE_CODE_EXECUTABLE\n const path = await executable(configured)\n if (path === undefined) {\n process.stdout.write(`${JSON.stringify({\n executable: { status: 'missing', searched: configured === undefined ? ['claude', '~/.local/bin/claude', '/opt/homebrew/bin/claude', '/usr/local/bin/claude'] : [configured] },\n version: { status: 'not-run' },\n authentication: { status: 'not-run' },\n message: 'Set executablePath to an absolute Claude Code CLI path',\n }, null, 2)}\\n`)\n return 1\n }\n const versionProbe = run(path, ['--version'])\n const version = parseClaudeVersion(`${versionProbe.stdout ?? ''}\\n${versionProbe.stderr ?? ''}`)\n const authProbe = run(path, ['auth', 'status', '--json'])\n let authentication: Record<string, unknown> = { status: 'unknown' }\n if (authProbe.status === 0) {\n try {\n const value = JSON.parse(authProbe.stdout) as Record<string, unknown>\n authentication = {\n status: value.loggedIn === true ? 'signed-in' : 'signed-out',\n ...(typeof value.authMethod === 'string' ? { method: value.authMethod } : {}),\n ...(typeof value.apiProvider === 'string' ? { provider: value.apiProvider } : {}),\n ...(typeof value.subscriptionType === 'string' ? { subscription: value.subscriptionType } : {}),\n }\n } catch {\n authentication = { status: 'unknown', message: 'Authentication status was not valid JSON' }\n }\n }\n process.stdout.write(`${JSON.stringify({\n executable: { status: 'found', path },\n version: version === undefined ? { status: 'error' } : { status: 'ok', value: version },\n authentication,\n handshake: 'not-run',\n }, null, 2)}\\n`)\n return version === undefined ? 1 : 0\n}\n\nasync function main(): Promise<number> {\n const command = process.argv[2] ?? 'doctor'\n if (command === 'doctor') return doctor()\n if (command === 'install-preset') {\n process.stdout.write(`${await ensureManagedPreset()}\\n`)\n return 0\n }\n if (command === 'remove-preset') {\n process.stdout.write(`${await removeManagedPreset()}\\n`)\n return 0\n }\n process.stderr.write(`Usage: dsh-claude [doctor [--executable PATH] | install-preset | remove-preset]\\n`)\n return 2\n}\n\ntry {\n process.exitCode = await main()\n} catch (error) {\n process.stderr.write(`${error instanceof Error ? error.message : String(error)}\\n`)\n process.exitCode = 1\n}\n"],"mappings":"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"}
package/lib/client.d.ts CHANGED
@@ -38,14 +38,16 @@ declare const en: {
38
38
  readonly globalSettings: "Claude Code settings";
39
39
  readonly globalSettingsBody: "Modify supported Claude Code and plugin settings while preserving every other field.";
40
40
  readonly globalSettingsLoading: "Loading global settings…";
41
- readonly globalSettingsNewSession: "Output Style changes apply only to new Claude sessions.";
41
+ readonly globalSettingsNewSession: "Changes apply only to new Claude sessions.";
42
42
  readonly globalSettingsError: "Global settings save failed";
43
43
  readonly outputStyle: "Output Style";
44
44
  readonly worktreeBranchPrefix: "Worktree branch prefix";
45
45
  readonly worktreeBranchPrefixEffect: "Prefix changes apply to subsequently generated Worktree branches. Explicit full branch names remain unchanged.";
46
46
  readonly maxProcessesSetting: "Claude process limit";
47
47
  readonly idleTimeoutSetting: "Idle timeout (minutes)";
48
- readonly limitsSettingEffect: "The process limit applies when the next Claude process is admitted; the idle timeout applies after the next completed turn.";
48
+ readonly maxProcessesEffect: "The process limit applies when the next Claude process is admitted. Blank or invalid values are rejected.";
49
+ readonly idleTimeoutEffect: "The idle timeout applies after the next completed turn. Blank or invalid values are rejected.";
50
+ readonly settingHint: "Show details";
49
51
  readonly pluginUpdate: "Plugin updates";
50
52
  readonly pluginUpdateBody: "Check npm for new releases. Only a uniquely identified npm installation can update in place; local development links are never replaced.";
51
53
  readonly updateNotChecked: "Updates have not been checked yet.";
@@ -83,7 +85,22 @@ declare const en: {
83
85
  readonly tasksViewActivity: "View activity";
84
86
  readonly tasksHideActivity: "Hide activity";
85
87
  readonly tasksRunningCount: "{count} running task(s)";
86
- readonly repositoryRateLimited: "Rate limited";
88
+ readonly planUsage: "Plan usage";
89
+ readonly planUsageBody: "Utilization windows for the signed-in Claude subscription, from Claude Code's /usage data. Refreshes whenever a session goes idle, and on demand.";
90
+ readonly planUsageLoading: "Loading…";
91
+ readonly planUsageRefresh: "Refresh usage";
92
+ readonly planUsageRefreshing: "Refreshing…";
93
+ readonly planUsageUnavailable: "This account has no plan limits (API key, Bedrock, and Vertex sessions are not rate limited by a subscription).";
94
+ readonly planUsageNever: "No usage data yet — run a turn or refresh.";
95
+ readonly planUsageError: "Usage lookup failed";
96
+ readonly planUsageSubscription: "Subscription";
97
+ readonly planUsageUpdated: "Updated {age} ago";
98
+ readonly planUsageResets: "Resets in {age}";
99
+ readonly planUsageUsed: "{percent}% used";
100
+ readonly planWindow_five_hour: "5-hour";
101
+ readonly planWindow_seven_day: "All models · weekly";
102
+ readonly planWindow_seven_day_opus: "Opus · weekly";
103
+ readonly planWindow_seven_day_sonnet: "Sonnet · weekly";
87
104
  readonly tasksTurnRunning: "{count} task(s) running";
88
105
  readonly tasksTurnCompleted: "{count} task(s) completed";
89
106
  readonly tasksTurnFailed: "{failed} failed, {completed} completed";
@@ -231,7 +248,10 @@ declare const en: {
231
248
  readonly heroTicketSearch: "Search tickets or enter a key…";
232
249
  readonly heroTicketLoading: "Searching…";
233
250
  readonly heroTicketEmpty: "No matching tickets";
234
- readonly heroTicketNone: "No ticket";
251
+ readonly heroTicketNone: "Clear selected tickets";
252
+ readonly heroTicketRemove: "Remove {key}";
253
+ readonly heroTicketCount: "{count} tickets";
254
+ readonly heroBatchStarted: "Kicked off {count} tickets, each in its own worktree session";
235
255
  readonly heroTicketNotConnected: "Connect Jira in Settings first";
236
256
  readonly heroTicketFailed: "Ticket search failed";
237
257
  readonly jiraTitle: "Jira";
@@ -251,14 +271,31 @@ declare const en: {
251
271
  readonly cleanupTitle: "Clean up merged branch";
252
272
  readonly cleanupDescription: "Remove the worktree and local branch and delete the workspace; a plain checkout switches back to the base branch and deletes the merged branch.";
253
273
  readonly cleanupCompleted: "Cleaned up {branch}";
254
- readonly overviewOpen: "Show pull requests across Claude sessions";
255
- readonly overviewTitle: "Pull requests";
256
- readonly overviewBody: "Branch and pull request state across Claude sessions";
274
+ readonly overviewOpen: "Open the Claude session board";
275
+ readonly overviewTitle: "Session board";
276
+ readonly overviewBody: "Run state, branch, and pull request across Claude sessions";
257
277
  readonly overviewEmpty: "No active Claude sessions";
258
278
  readonly overviewNoPr: "No PR";
259
279
  readonly overviewRunning: "Running";
280
+ readonly overviewNeedsPermission: "Awaiting approval";
281
+ readonly overviewNeedsAnswer: "Awaiting answer";
282
+ readonly overviewContextUsage: "Context {percentage}%";
260
283
  readonly overviewAutoFix: "Auto fix on";
261
284
  readonly overviewLoading: "Loading…";
285
+ readonly askToolbar: "Selection actions";
286
+ readonly askTooltip: "Ask about this";
287
+ readonly copyTooltip: "Copy";
288
+ readonly askCopied: "Copied";
289
+ readonly askPlaceholder: "Ask about the selected text…";
290
+ readonly askSubmit: "Ask";
291
+ readonly askStarting: "Starting Claude…";
292
+ readonly askThinking: "Thinking…";
293
+ readonly askThinkingLive: "Thinking ·";
294
+ readonly askThinkingLabel: "Think ·";
295
+ readonly askCopyAnswer: "Copy answer";
296
+ readonly askSendToChat: "Send to chat";
297
+ readonly askClose: "Close";
298
+ readonly askFailed: "The question could not be answered";
262
299
  readonly reviewCommentAdd: "Add line comment";
263
300
  readonly reviewCommentPlaceholder: "Request changes";
264
301
  readonly reviewCommentSubmit: "Comment";
@@ -270,6 +307,12 @@ declare const en: {
270
307
  readonly reviewCommentsSendDraft: "Please address the attached review comments.";
271
308
  readonly reviewCommentOldSide: "Old line {line}";
272
309
  readonly reviewCommentNewSide: "Line {line}";
310
+ readonly reviewCommentOldRange: "Old lines {start}–{end}";
311
+ readonly reviewCommentNewRange: "Lines {start}–{end}";
312
+ readonly diffUnmodifiedLines: "{count} unmodified lines";
313
+ readonly diffUnmodifiedTail: "More unmodified lines below";
314
+ readonly diffExpandUp: "Expand up";
315
+ readonly diffExpandDown: "Expand down";
273
316
  };
274
317
  type ClaudeCodeSettingsKey = keyof typeof en;
275
318
  //#endregion