@norman-else/dsh-claude 0.1.36 → 0.1.37
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/cordis.patch.yml +12 -12
- package/legacy-preset/agent.cordis.yml +11 -11
- package/legacy-preset/preset.yml +4 -4
- package/lib/bin.mjs +0 -0
- package/lib/bin.mjs.map +1 -1
- package/lib/client.d.ts +4 -0
- package/lib/client.js +123 -28
- package/lib/client.js.map +1 -1
- package/lib/index.mjs +176 -41
- package/lib/index.mjs.map +1 -1
- package/lib/presenters-BBoM1Ju1.mjs.map +1 -1
- package/lib/preset-installer-loenwnLS.mjs.map +1 -1
- package/lib/preset-route.mjs.map +1 -1
- package/package.json +195 -189
- package/preset/claude/agent.cordis.yml +11 -11
- package/preset/claude/preset.yml +4 -4
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 keeps a protected compatibility preset at `$DSH_HOME/.agent-presets/claude`, because DSH Desktop 2.0.4 does not retain third-party preset roots from bundle patches. Its route uses the active profile package source to avoid duplicate client-module Loaders. User-modified preset files are preserved.
|
|
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 keeps a protected compatibility preset at `$DSH_HOME/.agent-presets/claude`, because DSH Desktop 2.0.4 does not retain third-party preset roots from bundle patches. Its route uses the active profile package source to avoid duplicate client-module Loaders. User-modified preset files are preserved.
|
|
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/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
|
package/legacy-preset/preset.yml
CHANGED
|
@@ -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
|
File without changes
|
package/lib/bin.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bin.mjs","names":[],"sources":["../src/bin.ts"],"sourcesContent":["#!/usr/bin/env node\
|
|
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
|
@@ -148,6 +148,7 @@ declare const en: {
|
|
|
148
148
|
readonly repositoryProgressDismiss: "Dismiss Worktree progress";
|
|
149
149
|
readonly repositoryProgress_inspecting: "Checking repository and branch";
|
|
150
150
|
readonly repositoryProgress_fetching: "Refreshing remote references";
|
|
151
|
+
readonly repositoryProgress_summarizing: "Naming the branch after the request";
|
|
151
152
|
readonly 'repositoryProgress_creating-worktree': "Creating branch and Worktree";
|
|
152
153
|
readonly 'repositoryProgress_saving-worktree': "Saving Worktree state";
|
|
153
154
|
readonly 'repositoryProgress_switching-branch': "Switching local branch";
|
|
@@ -205,6 +206,9 @@ declare const en: {
|
|
|
205
206
|
readonly diffCommentNext: "Next comment";
|
|
206
207
|
readonly diffCommentPosition: "Comment {index} of {total}";
|
|
207
208
|
readonly diffCommentCounter: "{index}/{total}";
|
|
209
|
+
readonly diffCardExpand: "Show {count} more lines";
|
|
210
|
+
readonly diffCardCollapse: "Show less";
|
|
211
|
+
readonly diffCardFiles: "{count} files";
|
|
208
212
|
readonly diffExpandAll: "Expand all files";
|
|
209
213
|
readonly diffCollapseAll: "Collapse all files";
|
|
210
214
|
readonly diffRestore: "Restore diff panel";
|
package/lib/client.js
CHANGED
|
@@ -3630,7 +3630,7 @@ window.__ModuleLoader__.load({
|
|
|
3630
3630
|
`body[data-ds-dark-theme] .${CLAUDE_MARKDOWN_SCOPE}{`,
|
|
3631
3631
|
palette(PIERRE_DARK, "#1a1a19", "#1a1a19", INLINE_FILL_DARK),
|
|
3632
3632
|
"}",
|
|
3633
|
-
`.${CLAUDE_MARKDOWN_SCOPE} :not(pre)>code{color:${CLAY_EMPHASIZED};border-radius:4px;padding:1px 2px}`,
|
|
3633
|
+
`.${CLAUDE_MARKDOWN_SCOPE} :not(pre)>code{color:${CLAY_EMPHASIZED};border-radius:4px;padding:1px 2px;font-size:1.05em!important}`,
|
|
3634
3634
|
`body[data-ds-dark-theme] .${CLAUDE_MARKDOWN_SCOPE} :not(pre)>code{color:${CLAY}}`,
|
|
3635
3635
|
`.${CLAUDE_MARKDOWN_SCOPE} [class*="bannerWrap"]{position:absolute;top:0;right:0;z-index:7;background:transparent;border-radius:0}`,
|
|
3636
3636
|
`.${CLAUDE_MARKDOWN_SCOPE} [class*="banner"]:not([class*="bannerWrap"]){background:transparent;padding:6px 8px}`,
|
|
@@ -4578,6 +4578,7 @@ window.__ModuleLoader__.load({
|
|
|
4578
4578
|
".dsh-claude-transcript-text{color:var(--dsw-alias-label-primary);font-size:15px;line-height:24px;overflow-wrap:anywhere}",
|
|
4579
4579
|
".dsh-claude-tool-group-native{overflow:visible}",
|
|
4580
4580
|
".dsh-claude-tool-group-native>.dsh-claude-flow-row{padding:0}",
|
|
4581
|
+
".dsh-claude-flow-row .dsh-claude-tool-stats{margin-left:8px}",
|
|
4581
4582
|
".dsh-claude-tool-list{max-height:min(420px,calc(100vh - 320px));overflow-x:hidden;overflow-y:auto;overscroll-behavior:contain;margin-top:4px;border:1px solid var(--dsw-alias-border-l1, color-mix(in srgb, currentColor 12%, transparent));border-radius:10px;scrollbar-gutter:stable}",
|
|
4582
4583
|
".dsh-claude-tool-item{border-top:1px solid var(--dsw-alias-border-l1, color-mix(in srgb, currentColor 12%, transparent))}",
|
|
4583
4584
|
".dsh-claude-tool-item:first-child{border-top:0}",
|
|
@@ -4816,13 +4817,36 @@ window.__ModuleLoader__.load({
|
|
|
4816
4817
|
if (!Array.isArray(value)) return [];
|
|
4817
4818
|
return value.filter((item) => typeof item === "string");
|
|
4818
4819
|
}
|
|
4820
|
+
/** The diff card's chrome, which primitives 0.1.2 moved onto the caller.
|
|
4821
|
+
*
|
|
4822
|
+
* The card reads `labels.copy` while it builds, so omitting them throws
|
|
4823
|
+
* mid-render -- and React answers by tearing down the whole conversation, not
|
|
4824
|
+
* the one tool row.
|
|
4825
|
+
*
|
|
4826
|
+
* The aria strings deliberately repeat the visible ones: both already say
|
|
4827
|
+
* exactly what the control does. */
|
|
4828
|
+
function diffBlockLabels(t) {
|
|
4829
|
+
const expand = (hidden) => t("diffCardExpand", { count: hidden });
|
|
4830
|
+
return {
|
|
4831
|
+
copy: t("markdownCopy"),
|
|
4832
|
+
copied: t("markdownCopied"),
|
|
4833
|
+
collapse: t("diffCardCollapse"),
|
|
4834
|
+
collapseAria: t("diffCardCollapse"),
|
|
4835
|
+
expand,
|
|
4836
|
+
expandAria: expand,
|
|
4837
|
+
files: (count) => t("diffCardFiles", { count })
|
|
4838
|
+
};
|
|
4839
|
+
}
|
|
4819
4840
|
function ToolPresentation({ tool, t }) {
|
|
4820
4841
|
const inputValue = parsedValue(tool.input);
|
|
4821
4842
|
const outputValue = parsedValue(tool.output);
|
|
4822
4843
|
const input = record$6(inputValue);
|
|
4823
4844
|
const output = record$6(outputValue);
|
|
4824
4845
|
const outputTitle = tool.isError === true ? t("toolError") : t("toolOutput");
|
|
4825
|
-
if (tool.diffs !== void 0) return /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx(DiffBlock, {
|
|
4846
|
+
if (tool.diffs !== void 0) return /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx(DiffBlock, {
|
|
4847
|
+
diffs: [...tool.diffs],
|
|
4848
|
+
labels: diffBlockLabels(t)
|
|
4849
|
+
}), /* @__PURE__ */ jsx(TextDetail, {
|
|
4826
4850
|
title: outputTitle,
|
|
4827
4851
|
value: typeof outputValue === "string" ? outputValue : void 0
|
|
4828
4852
|
})] });
|
|
@@ -6555,10 +6579,14 @@ window.__ModuleLoader__.load({
|
|
|
6555
6579
|
const HOST_STAGES = /* @__PURE__ */ new Set([
|
|
6556
6580
|
"inspecting",
|
|
6557
6581
|
"fetching",
|
|
6582
|
+
"summarizing",
|
|
6558
6583
|
"creating-worktree",
|
|
6559
6584
|
"saving-worktree",
|
|
6560
6585
|
"switching-branch"
|
|
6561
6586
|
]);
|
|
6587
|
+
/** The draft only has to describe the work; the host truncates it again before
|
|
6588
|
+
* summarizing, and the setup route caps the whole body at 16 KiB. */
|
|
6589
|
+
const MAX_INTENT_CHARS = 2e3;
|
|
6562
6590
|
function record$3(value) {
|
|
6563
6591
|
return typeof value === "object" && value !== null && !Array.isArray(value) ? value : void 0;
|
|
6564
6592
|
}
|
|
@@ -6594,7 +6622,7 @@ window.__ModuleLoader__.load({
|
|
|
6594
6622
|
throw error;
|
|
6595
6623
|
}
|
|
6596
6624
|
}
|
|
6597
|
-
async function prepareRepository(cwd, branch, worktree, branchName, onProgress = () => {}) {
|
|
6625
|
+
async function prepareRepository(cwd, branch, worktree, branchName, onProgress = () => {}, intent) {
|
|
6598
6626
|
const carrier = new AbortController();
|
|
6599
6627
|
try {
|
|
6600
6628
|
const reader = await pluginNdjson(CLAUDE_REPOSITORY_SETUP_PATH, carrier.signal, {
|
|
@@ -6603,7 +6631,8 @@ window.__ModuleLoader__.load({
|
|
|
6603
6631
|
cwd,
|
|
6604
6632
|
branch,
|
|
6605
6633
|
worktree,
|
|
6606
|
-
...branchName === void 0 ? {} : { branchName }
|
|
6634
|
+
...branchName === void 0 ? {} : { branchName },
|
|
6635
|
+
...intent === void 0 || intent.trim().length === 0 ? {} : { intent: intent.slice(0, MAX_INTENT_CHARS) }
|
|
6607
6636
|
}
|
|
6608
6637
|
});
|
|
6609
6638
|
const decoder = new TextDecoder();
|
|
@@ -6892,10 +6921,40 @@ window.__ModuleLoader__.load({
|
|
|
6892
6921
|
const CLAUDE_SCOPED_CSS_VARIABLES = ["--dsh-composer-card-max-width"];
|
|
6893
6922
|
/** Marks the bar the scoped-property probe measures. */
|
|
6894
6923
|
const CLAUDE_COMPOSER_BAR_ATTRIBUTE = "data-dsh-claude-composer-bar";
|
|
6895
|
-
/**
|
|
6896
|
-
|
|
6924
|
+
/** Methods this plugin calls on the Host services it injects.
|
|
6925
|
+
*
|
|
6926
|
+
* A service that still resolves but has lost a method is the drift the
|
|
6927
|
+
* service list above cannot see: Desktop 0.1.2 moved `connectWorkspace` off
|
|
6928
|
+
* `workspaces` onto a new service, and the worktree flow went on registering
|
|
6929
|
+
* itself and only broke once a user ran it. Naming the methods here turns
|
|
6930
|
+
* that into a boot-time line. Methods with a runtime fallback stay out. */
|
|
6931
|
+
const CLAUDE_REQUIRED_SERVICE_METHODS = {
|
|
6932
|
+
sessions: [
|
|
6933
|
+
"scope",
|
|
6934
|
+
"open",
|
|
6935
|
+
"binding"
|
|
6936
|
+
],
|
|
6937
|
+
workspaces: [
|
|
6938
|
+
"create",
|
|
6939
|
+
"delete",
|
|
6940
|
+
"archiveSession"
|
|
6941
|
+
],
|
|
6942
|
+
uiConversation: ["binding"],
|
|
6943
|
+
uiSession: ["provide"],
|
|
6944
|
+
inputTriggers: ["registerSource"]
|
|
6945
|
+
};
|
|
6946
|
+
/** One line per service the Host no longer provides, or provides without a
|
|
6947
|
+
* method this plugin calls on it; empty when everything resolves. */
|
|
6948
|
+
function claudeBootCheckFindings(input, methods = CLAUDE_REQUIRED_SERVICE_METHODS) {
|
|
6897
6949
|
const findings = [];
|
|
6898
|
-
for (const name of input.services)
|
|
6950
|
+
for (const name of input.services) {
|
|
6951
|
+
const service = input.resolve(name);
|
|
6952
|
+
if (service === void 0) {
|
|
6953
|
+
findings.push(`service "${name}" is declared in inject but the Host does not provide it`);
|
|
6954
|
+
continue;
|
|
6955
|
+
}
|
|
6956
|
+
for (const method of methods[name] ?? []) if (typeof service[method] !== "function") findings.push(`service "${name}" no longer provides ${method}(); the features calling it are broken`);
|
|
6957
|
+
}
|
|
6899
6958
|
return findings;
|
|
6900
6959
|
}
|
|
6901
6960
|
/** One line per scoped custom property the measured element cannot see.
|
|
@@ -7828,9 +7887,15 @@ window.__ModuleLoader__.load({
|
|
|
7828
7887
|
style: repositoryRemote,
|
|
7829
7888
|
children: repositoryName$1(repository.remote)
|
|
7830
7889
|
}),
|
|
7831
|
-
/* @__PURE__ */ jsx(
|
|
7832
|
-
|
|
7833
|
-
|
|
7890
|
+
/* @__PURE__ */ jsx(Tooltip, {
|
|
7891
|
+
label: branch,
|
|
7892
|
+
side: "top",
|
|
7893
|
+
delayMs: 250,
|
|
7894
|
+
maxWidth: 420,
|
|
7895
|
+
children: /* @__PURE__ */ jsx("span", {
|
|
7896
|
+
style: repositoryBranch,
|
|
7897
|
+
children: branch
|
|
7898
|
+
})
|
|
7834
7899
|
}),
|
|
7835
7900
|
repository.worktree === true ? /* @__PURE__ */ jsx("span", {
|
|
7836
7901
|
style: repositoryWorktree,
|
|
@@ -8022,7 +8087,9 @@ window.__ModuleLoader__.load({
|
|
|
8022
8087
|
children: comment.text
|
|
8023
8088
|
})]
|
|
8024
8089
|
}),
|
|
8025
|
-
openDelayMs: 250
|
|
8090
|
+
openDelayMs: 250,
|
|
8091
|
+
copyLabel: t("markdownCopy"),
|
|
8092
|
+
copiedLabel: t("markdownCopied")
|
|
8026
8093
|
});
|
|
8027
8094
|
}
|
|
8028
8095
|
/** Pending review comments docked above the composer; drained by the next user turn. */
|
|
@@ -14091,7 +14158,7 @@ window.__ModuleLoader__.load({
|
|
|
14091
14158
|
* @returns the preset id, or undefined when neither source carries one.
|
|
14092
14159
|
*/
|
|
14093
14160
|
function sessionRowPreset(row) {
|
|
14094
|
-
return row?.agentPreset ?? row?.projectionValues?.agentPreset;
|
|
14161
|
+
return row?.agentPreset ?? row?.projectionValues?.agentPreset ?? void 0;
|
|
14095
14162
|
}
|
|
14096
14163
|
//#endregion
|
|
14097
14164
|
//#region src/client/ClaudePullRequestsPanel.tsx
|
|
@@ -15322,10 +15389,15 @@ window.__ModuleLoader__.load({
|
|
|
15322
15389
|
}
|
|
15323
15390
|
//#endregion
|
|
15324
15391
|
//#region src/client/ClaudeHeroRepositoryControls.tsx
|
|
15392
|
+
/** The host composer was a textarea through rc.8 and is a Lexical
|
|
15393
|
+
* contenteditable from 0.1.2 on, so match the composer seat rather than the
|
|
15394
|
+
* element type: an element-type check silently stops intercepting Enter, and
|
|
15395
|
+
* the capsule's branch and Worktree choices go nowhere. */
|
|
15325
15396
|
function shouldInterceptKey(event) {
|
|
15326
15397
|
if (event.key !== "Enter" || event.shiftKey || event.repeat || event.isComposing) return false;
|
|
15327
15398
|
const target = event.target;
|
|
15328
|
-
|
|
15399
|
+
if (!(target instanceof Element)) return false;
|
|
15400
|
+
return target.closest("textarea, [data-composer-input]") !== null && target.closest("[data-phase=\"hero\"]") !== null;
|
|
15329
15401
|
}
|
|
15330
15402
|
function shouldInterceptClick(event) {
|
|
15331
15403
|
const target = event.target;
|
|
@@ -15361,6 +15433,7 @@ window.__ModuleLoader__.load({
|
|
|
15361
15433
|
const WORKTREE_PROGRESS_STAGES = [
|
|
15362
15434
|
"inspecting",
|
|
15363
15435
|
"fetching",
|
|
15436
|
+
"summarizing",
|
|
15364
15437
|
"creating-worktree",
|
|
15365
15438
|
"saving-worktree",
|
|
15366
15439
|
"creating-workspace",
|
|
@@ -15371,6 +15444,7 @@ window.__ModuleLoader__.load({
|
|
|
15371
15444
|
const PROGRESS_LABEL_KEYS = {
|
|
15372
15445
|
inspecting: "repositoryProgress_inspecting",
|
|
15373
15446
|
fetching: "repositoryProgress_fetching",
|
|
15447
|
+
summarizing: "repositoryProgress_summarizing",
|
|
15374
15448
|
"creating-worktree": "repositoryProgress_creating-worktree",
|
|
15375
15449
|
"saving-worktree": "repositoryProgress_saving-worktree",
|
|
15376
15450
|
"switching-branch": "repositoryProgress_switching-branch",
|
|
@@ -17050,6 +17124,7 @@ window.__ModuleLoader__.load({
|
|
|
17050
17124
|
repositoryProgressDismiss: "关闭 Worktree 进度",
|
|
17051
17125
|
repositoryProgress_inspecting: "检查仓库和分支",
|
|
17052
17126
|
repositoryProgress_fetching: "刷新远程引用",
|
|
17127
|
+
repositoryProgress_summarizing: "总结需求生成分支名",
|
|
17053
17128
|
"repositoryProgress_creating-worktree": "创建分支和 Worktree",
|
|
17054
17129
|
"repositoryProgress_saving-worktree": "保存 Worktree 状态",
|
|
17055
17130
|
"repositoryProgress_switching-branch": "切换本地分支",
|
|
@@ -17107,6 +17182,9 @@ window.__ModuleLoader__.load({
|
|
|
17107
17182
|
diffCommentNext: "下一条评论",
|
|
17108
17183
|
diffCommentPosition: "第 {index} 条,共 {total} 条",
|
|
17109
17184
|
diffCommentCounter: "{index}/{total}",
|
|
17185
|
+
diffCardExpand: "展开其余 {count} 行",
|
|
17186
|
+
diffCardCollapse: "收起",
|
|
17187
|
+
diffCardFiles: "{count} 个文件",
|
|
17110
17188
|
diffExpandAll: "展开全部文件",
|
|
17111
17189
|
diffCollapseAll: "收起全部文件",
|
|
17112
17190
|
diffRestore: "还原 Diff 面板",
|
|
@@ -17423,6 +17501,7 @@ window.__ModuleLoader__.load({
|
|
|
17423
17501
|
repositoryProgressDismiss: "Dismiss Worktree progress",
|
|
17424
17502
|
repositoryProgress_inspecting: "Checking repository and branch",
|
|
17425
17503
|
repositoryProgress_fetching: "Refreshing remote references",
|
|
17504
|
+
repositoryProgress_summarizing: "Naming the branch after the request",
|
|
17426
17505
|
"repositoryProgress_creating-worktree": "Creating branch and Worktree",
|
|
17427
17506
|
"repositoryProgress_saving-worktree": "Saving Worktree state",
|
|
17428
17507
|
"repositoryProgress_switching-branch": "Switching local branch",
|
|
@@ -17480,6 +17559,9 @@ window.__ModuleLoader__.load({
|
|
|
17480
17559
|
diffCommentNext: "Next comment",
|
|
17481
17560
|
diffCommentPosition: "Comment {index} of {total}",
|
|
17482
17561
|
diffCommentCounter: "{index}/{total}",
|
|
17562
|
+
diffCardExpand: "Show {count} more lines",
|
|
17563
|
+
diffCardCollapse: "Show less",
|
|
17564
|
+
diffCardFiles: "{count} files",
|
|
17483
17565
|
diffExpandAll: "Expand all files",
|
|
17484
17566
|
diffCollapseAll: "Collapse all files",
|
|
17485
17567
|
diffRestore: "Restore diff panel",
|
|
@@ -17680,6 +17762,17 @@ window.__ModuleLoader__.load({
|
|
|
17680
17762
|
"conversation",
|
|
17681
17763
|
"connection"
|
|
17682
17764
|
];
|
|
17765
|
+
/** Resolve one session's composer facade.
|
|
17766
|
+
*
|
|
17767
|
+
* `sessions.scope()` returns the client runtime's AgentContext, and the
|
|
17768
|
+
* conversation package -- a release ahead of the runtime in the graph the Host
|
|
17769
|
+
* itself ships -- types `input.for` against a Context whose `remote` has since
|
|
17770
|
+
* gained `$stream` and `$host`. It is the same object at runtime; only the two
|
|
17771
|
+
* declarations disagree, and they disagree inside the Host too, so the cast
|
|
17772
|
+
* lives here once instead of at all nine call sites. */
|
|
17773
|
+
function sessionInput(conversation, scope) {
|
|
17774
|
+
return conversation.input.for(scope);
|
|
17775
|
+
}
|
|
17683
17776
|
function apply(ctx) {
|
|
17684
17777
|
const namespace = "settings.claude-code";
|
|
17685
17778
|
const diagnostics = createClaudeDiagnosticsReporter();
|
|
@@ -17705,6 +17798,8 @@ window.__ModuleLoader__.load({
|
|
|
17705
17798
|
ctx.effect(() => ctx.inputTriggers.registerSource(createClaudeCommandSource(ctx, projections)), "dsh-claude: Claude slash source");
|
|
17706
17799
|
const sessions = ctx.get("sessions");
|
|
17707
17800
|
const workspaces = ctx.get("workspaces");
|
|
17801
|
+
const uiWorkspace = ctx.get("uiWorkspace");
|
|
17802
|
+
const connectWorkspace = uiWorkspace?.connectWorkspace?.bind(uiWorkspace) ?? (typeof workspaces?.connectWorkspace === "function" ? workspaces.connectWorkspace.bind(workspaces) : void 0);
|
|
17708
17803
|
const conversation = ctx.get("conversation");
|
|
17709
17804
|
const connection = ctx.get("connection");
|
|
17710
17805
|
const remote = ctx.get("remote");
|
|
@@ -17716,7 +17811,7 @@ window.__ModuleLoader__.load({
|
|
|
17716
17811
|
return (draft, mode = "append") => {
|
|
17717
17812
|
const scope = sessions.scope(sessionId);
|
|
17718
17813
|
if (scope === void 0) return false;
|
|
17719
|
-
const input = conversation
|
|
17814
|
+
const input = sessionInput(conversation, scope);
|
|
17720
17815
|
const current = input.state.getSnapshot().draft;
|
|
17721
17816
|
if (current.trim() === "") input.setDraft(draft);
|
|
17722
17817
|
else if (mode === "append") input.setDraft(`${current}\n\n${draft}`);
|
|
@@ -17962,7 +18057,7 @@ window.__ModuleLoader__.load({
|
|
|
17962
18057
|
...sessions === void 0 || conversation === void 0 ? {} : { submitWith: (fallbackDraft) => {
|
|
17963
18058
|
const scope = sessions.scope(sessionId);
|
|
17964
18059
|
if (scope === void 0) return;
|
|
17965
|
-
const input = conversation
|
|
18060
|
+
const input = sessionInput(conversation, scope);
|
|
17966
18061
|
if (input.state.getSnapshot().draft.trim() === "") input.setDraft(fallbackDraft);
|
|
17967
18062
|
input.submit();
|
|
17968
18063
|
} }
|
|
@@ -18000,7 +18095,7 @@ window.__ModuleLoader__.load({
|
|
|
18000
18095
|
...sessions === void 0 || conversation === void 0 ? {} : { insertIntoChat: (sessionId, text) => {
|
|
18001
18096
|
const scope = sessions.scope(sessionId);
|
|
18002
18097
|
if (scope === void 0) return;
|
|
18003
|
-
const input = conversation
|
|
18098
|
+
const input = sessionInput(conversation, scope);
|
|
18004
18099
|
const current = input.state.getSnapshot().draft;
|
|
18005
18100
|
input.setDraft(current.trim() === "" ? text : `${current}\n\n${text}`);
|
|
18006
18101
|
} }
|
|
@@ -18062,7 +18157,7 @@ window.__ModuleLoader__.load({
|
|
|
18062
18157
|
...conversation === void 0 ? {} : { setDraft: (sessionId, text) => {
|
|
18063
18158
|
const scope = sessions.scope(sessionId);
|
|
18064
18159
|
if (scope === void 0) return;
|
|
18065
|
-
conversation
|
|
18160
|
+
sessionInput(conversation, scope).setDraft(text);
|
|
18066
18161
|
} }
|
|
18067
18162
|
};
|
|
18068
18163
|
ctx.slots.inject("shell.overlay", () => ctx.slots.register({
|
|
@@ -18084,12 +18179,12 @@ window.__ModuleLoader__.load({
|
|
|
18084
18179
|
t,
|
|
18085
18180
|
updateQueue: (itemId, action) => target.updateQueue(itemId, action),
|
|
18086
18181
|
notify: (level, text) => {
|
|
18087
|
-
if (scope !== void 0) conversation
|
|
18182
|
+
if (scope !== void 0) sessionInput(conversation, scope).notify(level, text);
|
|
18088
18183
|
}
|
|
18089
18184
|
};
|
|
18090
18185
|
}
|
|
18091
18186
|
}, ClaudeQueueDock));
|
|
18092
|
-
if (sessions !== void 0 && workspaces !== void 0 && conversation !== void 0 && connection !== void 0 && remote !== void 0) {
|
|
18187
|
+
if (sessions !== void 0 && workspaces !== void 0 && connectWorkspace !== void 0 && conversation !== void 0 && connection !== void 0 && remote !== void 0) {
|
|
18093
18188
|
/** Attach a prepared worktree to its session without blocking the flow. */
|
|
18094
18189
|
const bindLease = (leaseId, targetSessionId) => {
|
|
18095
18190
|
if (leaseId === void 0) return;
|
|
@@ -18107,11 +18202,11 @@ window.__ModuleLoader__.load({
|
|
|
18107
18202
|
prepare: async (cwd, branch, useWorktree, onProgress, ticket) => {
|
|
18108
18203
|
const sourceScope = sessions.scope(sourceSessionId);
|
|
18109
18204
|
if (sourceScope === void 0) throw new Error(t("repositorySessionUnavailable"));
|
|
18110
|
-
const sourceInput = conversation
|
|
18205
|
+
const sourceInput = sessionInput(conversation, sourceScope);
|
|
18111
18206
|
const rawDraft = sourceInput.state.getSnapshot().draft;
|
|
18112
18207
|
const draft = ticket === void 0 ? rawDraft : rawDraft.trim() === "" ? ticketPrompt(ticket) : `${rawDraft.trimEnd()}\n\n${ticketContext(ticket)}`;
|
|
18113
18208
|
const imageIds = sourceInput.state.getSnapshot().imageIds;
|
|
18114
|
-
const prepared = await prepareRepository(cwd, branch, useWorktree, ticket?.key, onProgress);
|
|
18209
|
+
const prepared = await prepareRepository(cwd, branch, useWorktree, ticket?.key, onProgress, ticket === void 0 ? draft : void 0);
|
|
18115
18210
|
if (ticket !== void 0) assignJiraTicket(ticket.key).catch((reason) => {
|
|
18116
18211
|
console.warn(`dsh-claude: could not assign ${ticket.key}: ${reason instanceof Error ? reason.message : String(reason)}`);
|
|
18117
18212
|
});
|
|
@@ -18123,13 +18218,13 @@ window.__ModuleLoader__.load({
|
|
|
18123
18218
|
onProgress("creating-workspace");
|
|
18124
18219
|
const workspace = await workspaces.create({ path: prepared.path });
|
|
18125
18220
|
onProgress("starting-session");
|
|
18126
|
-
const targetSessionId = await
|
|
18221
|
+
const targetSessionId = await connectWorkspace(workspace.workspaceId);
|
|
18127
18222
|
const targetScope = sessions.scope(targetSessionId);
|
|
18128
18223
|
if (targetScope === void 0) throw new Error(t("repositorySessionUnavailable"));
|
|
18129
18224
|
const presetResponse = await remote.agentPresets.select(targetSessionId, "claude");
|
|
18130
18225
|
if (!presetResponse.ok) throw new Error(presetResponse.error.message);
|
|
18131
|
-
sessions.noteAgentPreset(targetSessionId, presetResponse.value);
|
|
18132
|
-
const targetInput = conversation
|
|
18226
|
+
sessions.noteAgentPreset?.(targetSessionId, presetResponse.value);
|
|
18227
|
+
const targetInput = sessionInput(conversation, targetScope);
|
|
18133
18228
|
onProgress("transferring-draft");
|
|
18134
18229
|
if (imageIds.length > 0 && !targetInput.addImages(imageIds)) throw new Error(t("repositoryDraftTransferFailed"));
|
|
18135
18230
|
if (draft !== "") targetInput.setDraft(draft);
|
|
@@ -18143,7 +18238,7 @@ window.__ModuleLoader__.load({
|
|
|
18143
18238
|
prepareMany: async (cwd, branch, tickets, onProgress) => {
|
|
18144
18239
|
const sourceScope = sessions.scope(sourceSessionId);
|
|
18145
18240
|
if (sourceScope === void 0) throw new Error(t("repositorySessionUnavailable"));
|
|
18146
|
-
const sourceInput = conversation
|
|
18241
|
+
const sourceInput = sessionInput(conversation, sourceScope);
|
|
18147
18242
|
const rawDraft = sourceInput.state.getSnapshot().draft;
|
|
18148
18243
|
const failures = [];
|
|
18149
18244
|
for (const [index, ticket] of tickets.entries()) {
|
|
@@ -18164,13 +18259,13 @@ window.__ModuleLoader__.load({
|
|
|
18164
18259
|
report("creating-workspace");
|
|
18165
18260
|
const workspace = await workspaces.create({ path: prepared.path });
|
|
18166
18261
|
report("starting-session");
|
|
18167
|
-
const targetSessionId = await
|
|
18262
|
+
const targetSessionId = await connectWorkspace(workspace.workspaceId);
|
|
18168
18263
|
const targetScope = sessions.scope(targetSessionId);
|
|
18169
18264
|
if (targetScope === void 0) throw new Error(t("repositorySessionUnavailable"));
|
|
18170
18265
|
const presetResponse = await remote.agentPresets.select(targetSessionId, "claude");
|
|
18171
18266
|
if (!presetResponse.ok) throw new Error(presetResponse.error.message);
|
|
18172
|
-
sessions.noteAgentPreset(targetSessionId, presetResponse.value);
|
|
18173
|
-
const targetInput = conversation
|
|
18267
|
+
sessions.noteAgentPreset?.(targetSessionId, presetResponse.value);
|
|
18268
|
+
const targetInput = sessionInput(conversation, targetScope);
|
|
18174
18269
|
report("transferring-draft");
|
|
18175
18270
|
targetInput.setDraft(rawDraft.trim() === "" ? ticketPrompt(ticket) : `${rawDraft.trimEnd()}\n\n${ticketContext(ticket)}`);
|
|
18176
18271
|
bindLease(prepared.leaseId, targetSessionId);
|