diff --git a/apps/cli/package.json b/apps/cli/package.json
index b5c6da4aed..739e00a2d4 100644
--- a/apps/cli/package.json
+++ b/apps/cli/package.json
@@ -103,9 +103,7 @@
"@deepseek-ai/dsh-experimental-ralph-bundle": "workspace:*",
"@deepseek-ai/dsh-experimental-session-titles-bundle": "workspace:*",
"@deepseek-ai/dsh-experimental-terminal-bundle": "workspace:*",
- "@deepseek-ai/dsh-session-search": "workspace:*",
- "@deepseek-ai/dsh-string-editor": "workspace:*",
- "@deepseek-ai/dsh-tmux-location": "workspace:*",
+ "@deepseek-ai/dsh-experimental-session-search": "workspace:*",
"@deepseek-ai/dsh-experimental-tool-worktree": "workspace:*"
},
"devDependencies": {
diff --git a/apps/cli/tests/optional-bundle-transitions.e2e.ts b/apps/cli/tests/optional-bundle-transitions.e2e.ts
index 5e8e9dcab0..78d0e45813 100644
--- a/apps/cli/tests/optional-bundle-transitions.e2e.ts
+++ b/apps/cli/tests/optional-bundle-transitions.e2e.ts
@@ -25,9 +25,7 @@ import { textResponse, toolCallResponse } from '../../../packages/core/agent-loo
const root = fileURLToPath(new URL('../../..', import.meta.url))
const installAnchor = join(root, 'apps/cli/package.json')
const bundles = {
- search: '@deepseek-ai/dsh-session-search',
- editor: '@deepseek-ai/dsh-string-editor',
- tmux: '@deepseek-ai/dsh-tmux-location',
+ search: '@deepseek-ai/dsh-experimental-session-search',
ralph: '@deepseek-ai/dsh-experimental-ralph-bundle',
terminal: '@deepseek-ai/dsh-experimental-terminal-bundle',
badge: '@deepseek-ai/dsh-experimental-badge-skill-bundle',
@@ -165,7 +163,6 @@ describe.skipIf(!existsSync(join(root, 'apps/cli/lib/bin.js')))('Official option
}
const names = (owner?: Agent) => ctx.tools.schemas(owner).map(tool => tool.name).sort()
- const transcript = (owner: Agent) => JSON.stringify(owner.session.deriveMessages())
const toolResult = (owner: Agent, callId: string) => owner.session.deriveMessages()
.flatMap(message => message.role === 'tool' && message.toolCallId === callId ? message.content : [])
.flatMap(block => block.type === 'text' ? [block.text] : []).join('\n')
@@ -179,53 +176,25 @@ describe.skipIf(!existsSync(join(root, 'apps/cli/lib/bin.js')))('Official option
expect((await ctx.skills.list({ cwd: workspace, scope: standard.agent })).some(skill => skill.name === 'dsh-badge')).toBe(false)
})
- it('preserves existing Agent generations across editor off/on/off and resumes with the current preset', async () => {
- const old = await agent()
- await select(bundles.editor, true)
- const enabled = await agent()
- expect(names(old.agent)).not.toContain('str_replace_editor')
- const first = join(workspace, 'editor-enabled.txt')
- await turn(enabled.agent, 'Create the requested file with the string editor.', [
- toolCallResponse('editor-on', 'str_replace_editor', { command: 'create', path: first, file_text: 'EDITOR_ENABLED' }), textResponse('EDITOR_DONE'),
- ])
- expect(await readFile(first, 'utf8')).toBe('EDITOR_ENABLED')
- expect(transcript(enabled.agent)).toContain('EDITOR_DONE')
- await select(bundles.editor, false)
- const after = await agent()
- expect(names(after.agent)).not.toContain('str_replace_editor')
- const retained = join(workspace, 'editor-retained.txt')
- await turn(enabled.agent, 'Use the retained editor to create the second file.', [
- toolCallResponse('editor-retained', 'str_replace_editor', { command: 'create', path: retained, file_text: 'RETAINED_EDITOR' }), textResponse('RETAINED_DONE'),
- ])
- expect(await readFile(retained, 'utf8')).toBe('RETAINED_EDITOR')
- const sessionId = enabled.agent.session.id
- await enabled.dispose()
- handles.delete(enabled)
- const resumed = await ctx.agents.resume({ resumeSessionId: sessionId, setup: scoped => ctx.agentPresets.mount(scoped, 'standard').then(() => undefined) })
- handles.add(resumed)
- expect(names(resumed.agent)).not.toContain('str_replace_editor')
- })
-
- it('generates and executes the PTC SDK for a selected editor bundle', async () => {
- await select(bundles.editor, true)
+ it('generates and executes the PTC SDK for the selected search bundle', async () => {
+ await select(bundles.search, true)
const coded = await agent('ptc')
const native = await agent('cordis')
const minimal = await agent('minimal')
- const target = join(workspace, 'ptc-editor.txt')
const assembly = await ctx.systemPrompt.assemble({ scope: coded.agent })
expect(assembly.tools.map(tool => tool.name)).toEqual(['run_code'])
- expect(assembly.sections.find(section => section.name === 'tools:sdk')?.text).toContain('str_replace_editor')
- expect(names(native.agent)).toContain('str_replace_editor')
+ expect(assembly.sections.find(section => section.name === 'tools:sdk')?.text).toContain('session_trace')
+ expect(names(native.agent)).toContain('session_search')
expect(names(minimal.agent)).toEqual([process.platform === 'win32' ? 'pwsh' : 'bash', 'working_directory'])
- await turn(coded.agent, 'Create the file with the editor through run_code.', [
- toolCallResponse('ptc-editor', 'run_code', {
- code: `console.log(await tools.str_replace_editor(${JSON.stringify({ command: 'create', path: target, file_text: 'PTC_EDITOR_OK' })}));`,
- description: 'Create the optional editor file',
- }), textResponse('PTC_EDITOR_DONE'),
+ await turn(coded.agent, 'Read this session lineage through run_code.', [
+ toolCallResponse('ptc-search', 'run_code', {
+ code: 'console.log(await tools.session_trace({}));',
+ description: 'Read the current session lineage',
+ }), textResponse('PTC_SEARCH_DONE'),
])
- expect(await readFile(target, 'utf8')).toBe('PTC_EDITOR_OK')
- expect(coded.agent.session.snapshotEvents().some(event => event.type === 'tool/ptc-dispatch' && event.data.name === 'str_replace_editor')).toBe(true)
- await select(bundles.editor, false)
+ expect(toolResult(coded.agent, 'ptc-search')).toContain(coded.agent.session.id)
+ expect(coded.agent.session.snapshotEvents().some(event => event.type === 'tool/ptc-dispatch' && event.data.name === 'session_trace')).toBe(true)
+ await select(bundles.search, false)
})
it('searches persisted conversation content only through the selected search bundle', async () => {
@@ -241,6 +210,7 @@ describe.skipIf(!existsSync(join(root, 'apps/cli/lib/bin.js')))('Official option
const foreign = await agent('standard', otherWorkspace)
await turn(foreign.agent, 'Keep OPTIONAL_SEARCH_MARKER in the other workspace.', [textResponse('Other marker recorded.')])
await select(bundles.search, true)
+ expect(names(live.agent)).not.toContain('session_search')
const searcher = await agent()
await turn(searcher.agent, 'Find the previous marker in session history.', [
toolCallResponse('search-history', 'session_search', { query: 'OPTIONAL_SEARCH_MARKER' }), textResponse('SEARCH_DONE'),
@@ -255,6 +225,12 @@ describe.skipIf(!existsSync(join(root, 'apps/cli/lib/bin.js')))('Official option
toolCallResponse('search-retained', 'session_search', { query: 'OPTIONAL_SEARCH_MARKER' }), textResponse('RETAINED_SEARCH_DONE'),
])
expect(toolResult(searcher.agent, 'search-retained')).toContain(seedId)
+ const sessionId = searcher.agent.session.id
+ await searcher.dispose()
+ handles.delete(searcher)
+ const reopened = await ctx.agents.resume({ resumeSessionId: sessionId, setup: scoped => ctx.agentPresets.mount(scoped, 'standard').then(() => undefined) })
+ handles.add(reopened)
+ expect(names(reopened.agent)).not.toContain('session_search')
})
it('loads the actual badge asset only while its bundle is selected', async () => {
@@ -322,18 +298,6 @@ describe.skipIf(!existsSync(join(root, 'apps/cli/lib/bin.js')))('Official option
expect(names((await agent()).agent)).not.toContain('ralph')
})
- it('runs the selected tmux context plugin without inventing a location outside tmux', async () => {
- await select(bundles.tmux, true)
- expect((await ctx.agentPresets.readDocument('standard')).content).toContain('@deepseek-ai/dsh-tmux-context')
- expect((await ctx.agentPresets.readDocument('minimal')).content).not.toContain('@deepseek-ai/dsh-tmux-context')
- const owner = await agent()
- await turn(owner.agent, 'Reply from this ordinary GUI process.', [textResponse('TMUX_UNAVAILABLE')])
- expect(owner.agent.session.snapshotEvents().some(event => event.type === 'user/message' && event.data.source.kind === 'tmux-context')).toBe(false)
- expect(transcript(owner.agent)).toContain('TMUX_UNAVAILABLE')
- await select(bundles.tmux, false)
- expect((await ctx.agentPresets.readDocument('standard')).content).not.toContain('@deepseek-ai/dsh-tmux-context')
- })
-
it('switches title cadence off/on/off through the live manager', async () => {
const titleRequests = (owner: Agent) => owner.session.snapshotEvents().filter(event => event.type === 'session/title-llm-request')
const first = await agent()
@@ -359,28 +323,27 @@ describe.skipIf(!existsSync(join(root, 'apps/cli/lib/bin.js')))('Official option
expect(titleRequests(restored.agent)[0]?.data.titleProvider).toBe('session-title-first-prompt-llm')
})
- it('composes all seven bundles while leaving minimal and host tools unchanged', async () => {
+ it('composes all five bundles while leaving minimal and host tools unchanged', async () => {
for (const name of Object.values(bundles)) await select(name, true)
let coded: Agent | undefined
for (const preset of ['standard', 'cordis', 'ptc']) {
const owner = await agent(preset)
- expect(names(owner.agent)).toEqual(expect.arrayContaining(['str_replace_editor', 'session_search', 'terminal_open', 'ralph']))
+ expect(names(owner.agent)).toEqual(expect.arrayContaining(['session_search', 'terminal_open', 'ralph']))
if (preset === 'ptc') coded = owner.agent
}
if (coded === undefined) throw new Error('the PTC Agent was not created')
- const target = join(workspace, 'combined-bundles.txt')
- await turn(coded, 'Create the file and load the badge through one program.', [
+ await turn(coded, 'Read this session lineage and load the badge through one program.', [
toolCallResponse('combined-program', 'run_code', {
- code: `await tools.str_replace_editor(${JSON.stringify({ command: 'create', path: target, file_text: 'COMBINED_BUNDLES_OK' })}); console.log(await tools.skill({ name: 'dsh-badge' }));`,
- description: 'Use the optional editor and badge together',
+ code: 'console.log(await tools.session_trace({})); console.log(await tools.skill({ name: "dsh-badge" }));',
+ description: 'Use optional session search and badge together',
}), textResponse('COMBINED_DONE'),
])
- expect(await readFile(target, 'utf8')).toBe('COMBINED_BUNDLES_OK')
+ expect(toolResult(coded, 'combined-program')).toContain(coded.session.id)
expect(toolResult(coded, 'combined-program')).toContain('dsh-badge')
const minimal = await agent('minimal')
expect(names(minimal.agent)).toEqual([process.platform === 'win32' ? 'pwsh' : 'bash', 'working_directory'])
expect(names()).toEqual(['working_directory'])
for (const name of [...Object.values(bundles)].reverse()) await select(name, false)
- expect(names((await agent()).agent)).not.toContain('str_replace_editor')
+ expect(names((await agent()).agent)).not.toContain('session_search')
})
})
diff --git a/apps/web/tests/optional-string-editor.e2e.ts b/apps/web/tests/standalone-string-editor.e2e.ts
similarity index 76%
rename from apps/web/tests/optional-string-editor.e2e.ts
rename to apps/web/tests/standalone-string-editor.e2e.ts
index 2d81a2002e..79e1efed80 100644
--- a/apps/web/tests/optional-string-editor.e2e.ts
+++ b/apps/web/tests/standalone-string-editor.e2e.ts
@@ -1,11 +1,10 @@
-/** An optional bundle reaches the generated PTC SDK through real profile selection and a persisted Session. */
+/** A standalone tool in a custom scoped patch reaches the PTC SDK and a persisted Session. */
import { readFile } from 'node:fs/promises'
import { join } from 'node:path'
import { fileURLToPath } from 'node:url'
import { chromium, type Browser, type Page } from 'playwright'
import { afterAll, beforeAll, describe, expect, it, onTestFailed } from 'vitest'
import type {} from '@deepseek-ai/dsh-tools'
-import type {} from '@deepseek-ai/dsh-plugin-manager'
import {
assertFinalWorkspaceSnapshot, assertFixtureInventory, captureExpandedTurnProcessAria, compareOrRefreshGolden,
fixtureUserPrompts, launchWebScaffold, recordFixture, selectedSessionFixture, watchConsole, webSnapshotMode, type WebScaffold,
@@ -14,10 +13,9 @@ import { connectFreshWorkspace, newEnglishPage, saveFailureShot } from './suppor
const DIR = fileURLToPath(new URL('../../../snapshots/web/optional-string-editor', import.meta.url))
const FIXTURE = join(DIR, 'session.v4.jsonl')
-const BUNDLE = '@deepseek-ai/dsh-string-editor'
const MODE = webSnapshotMode()
-describe('web snapshot: optional string editor through PTC', () => {
+describe('web snapshot: standalone string editor through PTC', () => {
let scaffold: WebScaffold
let browser: Browser
let page: Page
@@ -26,20 +24,16 @@ describe('web snapshot: optional string editor through PTC', () => {
beforeAll(async () => {
scaffold = await launchWebScaffold({
developerTools: true,
- extraOverlayPath: fileURLToPath(new URL('./pin-browse-picker.overlay.yml', import.meta.url)),
+ extraOverlayPath: [
+ fileURLToPath(new URL('./pin-browse-picker.overlay.yml', import.meta.url)),
+ fileURLToPath(new URL('./standalone-string-editor.overlay.yml', import.meta.url)),
+ ],
profile: { packages: [] },
compareReplaySession: true,
...(MODE === 'record' ? {} : { replayFixture: FIXTURE }),
})
- expect((await scaffold.ctx.pluginManager.listBundles()).find(bundle => bundle.name === BUNDLE))
- .toMatchObject({ enabled: false, optional: true })
expect((await scaffold.ctx.agentPresets.compositionInventory()).find(preset => preset.id === 'ptc')?.rows
- .some(row => row.moduleName === '@deepseek-ai/dsh-tool-str-replace-editor')).toBe(false)
- expect(await scaffold.ctx.pluginManager.setBundleEnabled(BUNDLE, true))
- .toMatchObject({ application: 'applied', changed: true })
- const active = (await scaffold.ctx.pluginManager.listBundles()).find(bundle => bundle.name === BUNDLE)
- expect(active?.rows.find(row => row.preset === 'preset-ptc'))
- .toMatchObject({ composition: { enabled: true, fiberPhase: 'active' } })
+ .some(row => row.moduleName === '@deepseek-ai/dsh-tool-str-replace-editor')).toBe(true)
browser = await chromium.launch()
page = await newEnglishPage(browser)
tripwire = watchConsole(page)
@@ -55,7 +49,7 @@ describe('web snapshot: optional string editor through PTC', () => {
try { await browser?.close() } finally { await scaffold?.close() }
})
- it('executes the newly selected SDK tool, persists its subcall, and verifies the created file', async () => {
+ it('executes the explicitly composed SDK tool, persists its subcall, and verifies the created file', async () => {
onTestFailed(() => saveFailureShot(page, 'optional-string-editor'))
const prompts = fixtureUserPrompts(await readFile(await selectedSessionFixture(FIXTURE), 'utf8'))
expect(prompts).toHaveLength(1)
@@ -65,7 +59,7 @@ describe('web snapshot: optional string editor through PTC', () => {
await input.press('Enter')
const sessionId = await settled
const agent = scaffold.ctx.agents.get(sessionId)
- if (agent === undefined) throw new Error('Optional editor Session has no live Agent')
+ if (agent === undefined) throw new Error('Standalone editor Session has no live Agent')
expect(scaffold.ctx.agentPresets.composedPreset(agent.ctx)).toBe('ptc')
expect(agent.session.requestHeader()?.tools?.map(tool => tool.name)).toEqual(['run_code'])
const system = agent.session.deriveMessages().filter(message => message.role === 'system')
@@ -76,7 +70,7 @@ describe('web snapshot: optional string editor through PTC', () => {
expect(events.filter(event => event.type === 'tool/ptc-dispatch').map(event => event.data))
.toMatchObject([{ name: 'str_replace_editor', arguments: { command: 'create' }, isError: false }])
const cwd = agent.session.header.cwd
- if (cwd === undefined) throw new Error('Optional editor Session has no working directory')
+ if (cwd === undefined) throw new Error('Standalone editor Session has no working directory')
expect(await readFile(join(cwd, 'edited.txt'), 'utf8')).toBe('PTC_EDITOR_OK\n')
await assertFinalWorkspaceSnapshot(DIR, cwd)
await expect.poll(() => page.getByText('DONE', { exact: true }).count()).toBeGreaterThanOrEqual(1)
diff --git a/apps/web/tests/standalone-string-editor.overlay.yml b/apps/web/tests/standalone-string-editor.overlay.yml
new file mode 100644
index 0000000000..7522f1800c
--- /dev/null
+++ b/apps/web/tests/standalone-string-editor.overlay.yml
@@ -0,0 +1,4 @@
+- preset: preset-ptc
+ insert:
+ - id: optional-tool-str-replace-editor
+ name: '@deepseek-ai/dsh-tool-str-replace-editor'
diff --git a/apps/web/tsconfig.json b/apps/web/tsconfig.json
index 45f330815f..baf71d22a4 100644
--- a/apps/web/tsconfig.json
+++ b/apps/web/tsconfig.json
@@ -53,7 +53,7 @@
"tests/question-composer.e2e.ts",
"tests/approval-composer.e2e.ts",
"tests/ptc-escalation.e2e.ts",
- "tests/optional-string-editor.e2e.ts",
+ "tests/standalone-string-editor.e2e.ts",
"tests/plan-control-row.e2e.ts",
"tests/plan-review.e2e.ts",
"tests/steering.e2e.ts",
diff --git a/docs/upgrade-guide/v0.2.1-alpha.1/new-session-generations/guide.i18n.yaml b/docs/upgrade-guide/v0.2.1-alpha.1/new-session-generations/guide.i18n.yaml
new file mode 100644
index 0000000000..01ecc3a8b0
--- /dev/null
+++ b/docs/upgrade-guide/v0.2.1-alpha.1/new-session-generations/guide.i18n.yaml
@@ -0,0 +1,16 @@
+# Bilingual-pair consistency record for guide.md (docs/i18n/README.md): per heading
+# section, a hash of its English and Chinese blocks outside code blocks and generated regions.
+# After editing either side, bring the other along and re-record with:
+# pnpm run verify-translation-pairing --write docs/upgrade-guide/v0.2.1-alpha.1/new-session-generations/guide.md
+/:
+ en: ad37e45180bc096f
+ zh: e44c85b10b1d9d4b
+/start-a-fresh-agent-with-new-session:
+ en: 5e4b26181326018f
+ zh: 99bc75dcd12bf647
+/start-a-fresh-agent-with-new-session/change:
+ en: ab12aadb31d0d3e8
+ zh: 637b446aef86456e
+/start-a-fresh-agent-with-new-session/migration:
+ en: 9565e66b6bcdf269
+ zh: 226e470de85aa8b6
diff --git a/docs/upgrade-guide/v0.2.1-alpha.1/new-session-generations/guide.md b/docs/upgrade-guide/v0.2.1-alpha.1/new-session-generations/guide.md
new file mode 100644
index 0000000000..bc735fe299
--- /dev/null
+++ b/docs/upgrade-guide/v0.2.1-alpha.1/new-session-generations/guide.md
@@ -0,0 +1,20 @@
+---
+kind: upgrade-guide
+description: "New Session creates a fresh Agent instead of reusing an existing empty Session."
+---
+
+# Start a fresh Agent with New Session
+
+English | [中文](guide.zh.md)
+
+## Change
+
+In Web and Desktop, New Session creates a fresh Session and Agent using the current preset definition. It previously reused an existing empty Session in the workspace, which could retain tools from before an optional bundle changed.
+
+Client calls to `uiWorkspace.startSession(workspaceId)` follow the same behavior. Workspace reconnection through `openWorkspace` or `connectWorkspace` still reuses an eligible blank. Calls with draft-preparation options preserve their existing reuse and content rules. Existing Agents retain their composition.
+
+## Migration
+
+1. After changing optional bundles, use New Session to obtain the current tool composition. Continue in an existing Session when its retained composition is intentional.
+2. Client integrations that reconnect a workspace should use `openWorkspace` or `connectWorkspace`. Keep explicit draft-preparation options when preparing an existing draft.
+3. Confirm that the new Agent has the selected tools; no persisted Session files or profile patches need rewriting.
diff --git a/docs/upgrade-guide/v0.2.1-alpha.1/new-session-generations/guide.zh.md b/docs/upgrade-guide/v0.2.1-alpha.1/new-session-generations/guide.zh.md
new file mode 100644
index 0000000000..b3371908a1
--- /dev/null
+++ b/docs/upgrade-guide/v0.2.1-alpha.1/new-session-generations/guide.zh.md
@@ -0,0 +1,20 @@
+---
+kind: upgrade-guide
+description: "新会话会创建新的 Agent,不再复用已有空 Session。"
+---
+
+# 通过新会话创建新的 Agent
+
+[English](guide.md) | 中文
+
+## 变更
+
+在 Web 和 Desktop 中,新会话按当前预设定义创建新的 Session 和 Agent。此前该操作会复用工作区内已有的空 Session,因而可能保留可选组合包变更前的工具。
+
+客户端调用 `uiWorkspace.startSession(workspaceId)` 采用相同行为。通过 `openWorkspace` 或 `connectWorkspace` 重连工作区时仍复用符合条件的空 Session。带草稿准备选项的调用保留已有复用与内容规则。已有 Agent 保留其组合。
+
+## 迁移
+
+1. 更改可选组合包后,通过新会话取得当前工具组合。需要保留原组合时,继续使用已有 Session。
+2. 重连工作区的客户端集成应使用 `openWorkspace` 或 `connectWorkspace`。准备已有草稿时保留显式草稿准备选项。
+3. 确认新 Agent 拥有已选择的工具;无需重写持久化 Session 文件或 profile patch。
diff --git a/packages/api/session-controller/src/client/sessions/service.ts b/packages/api/session-controller/src/client/sessions/service.ts
index e9fc6cd26b..964105a486 100644
--- a/packages/api/session-controller/src/client/sessions/service.ts
+++ b/packages/api/session-controller/src/client/sessions/service.ts
@@ -40,7 +40,7 @@ export interface SessionSummary {
/**
* New Session presentation and reuse eligibility, derived from the Host
* summary, `sessionListMetadata`, and client acceptance/running observations.
- * New Session reuses a blank one targeting the same workspace. Filtering
+ * Workspace reconnection may reuse a blank in the same workspace. Filtering
* stays with the consumer: the store carries every row, while the Workspace
* browser shows only the selected blank entry.
*/
diff --git a/packages/boot/app-boot/src/profile.ts b/packages/boot/app-boot/src/profile.ts
index ec8ca5cac5..e8aee3ce21 100644
--- a/packages/boot/app-boot/src/profile.ts
+++ b/packages/boot/app-boot/src/profile.ts
@@ -221,9 +221,7 @@ export const DEFAULT_PROFILE_BUNDLES: readonly string[] = ['@deepseek-ai/dsh-bas
* [admission](../../../../.agents/notes/implemented/architecture/2026-09-21-experimental-capabilities-as-optional-bundles.md)).
*/
export const OPTIONAL_BUNDLES: readonly string[] = [
- '@deepseek-ai/dsh-session-search',
- '@deepseek-ai/dsh-string-editor',
- '@deepseek-ai/dsh-tmux-location',
+ '@deepseek-ai/dsh-experimental-session-search',
'@deepseek-ai/dsh-experimental-ralph-bundle',
'@deepseek-ai/dsh-experimental-terminal-bundle',
'@deepseek-ai/dsh-experimental-badge-skill-bundle',
diff --git a/packages/bundle/README.i18n.yaml b/packages/bundle/README.i18n.yaml
index a6e2843099..2db95bd425 100644
--- a/packages/bundle/README.i18n.yaml
+++ b/packages/bundle/README.i18n.yaml
@@ -15,8 +15,8 @@
en: 09848f4d056e4fc1
zh: 8df6139cff0288f6
/bundle-profile-plugin-bundles/packages:
- en: 8313a008ecf37fe7
- zh: 79c631b3ed7963ec
+ en: 3c0457febc9525d6
+ zh: a236402f8e9fb212
/bundle-profile-plugin-bundles/related-documentation:
en: 29a969a46018d862
zh: bb0be22dd0273886
diff --git a/packages/bundle/README.md b/packages/bundle/README.md
index 0ef81245e8..6311b61d5e 100644
--- a/packages/bundle/README.md
+++ b/packages/bundle/README.md
@@ -22,9 +22,6 @@ This group maps the installable patch layers used by `dsh --profile`. Each packa
| Package | Role | ctx key |
|---|---|---|
-| [`session-search`](session-search/README.md) | Optional session search in full Web presets | — |
-| [`string-editor`](string-editor/README.md) | Optional string-replacement editing in full Web presets | — |
-| [`tmux-location`](tmux-location/README.md) | Optional tmux location context in full Web presets | — |
| [`base`](base/README.md) | Shared core for base-backed profiles | — (patch only) |
| [`acp-app`](acp-app/README.md) | Automation-only ACP stdio application over base | mounts the ACP bridge |
| [`web-app`](web-app/README.md) | Browser application layer over base | mounts Web rows |
diff --git a/packages/bundle/README.zh.md b/packages/bundle/README.zh.md
index 998d50cfa4..829408f1e1 100644
--- a/packages/bundle/README.zh.md
+++ b/packages/bundle/README.zh.md
@@ -22,9 +22,6 @@ kind: "package-group"
| 包 | 职责 | ctx key |
|---|---|---|
-| [`session-search`](session-search/README.zh.md) | 完整 Web 预设的可选会话搜索 | — |
-| [`string-editor`](string-editor/README.zh.md) | 完整 Web 预设的可选字符串替换编辑 | — |
-| [`tmux-location`](tmux-location/README.zh.md) | 完整 Web 预设的可选 tmux 位置上下文 | — |
| [`base`](base/README.zh.md) | 基于 base 的 profile 共享核心 | —(仅 patch) |
| [`acp-app`](acp-app/README.zh.md) | 基于 base、仅用于自动化的 ACP stdio 应用 | 挂载 ACP bridge |
| [`web-app`](web-app/README.zh.md) | 基于 base 的浏览器应用层 | 挂载多条 Web 配置行 |
diff --git a/packages/bundle/session-search/README.i18n.yaml b/packages/bundle/session-search/README.i18n.yaml
deleted file mode 100644
index 2db8d3be97..0000000000
--- a/packages/bundle/session-search/README.i18n.yaml
+++ /dev/null
@@ -1,37 +0,0 @@
-# Bilingual-pair consistency record for README.md (docs/i18n/README.md): per heading
-# section, a hash of its English and Chinese blocks outside code blocks and generated regions.
-# After editing either side, bring the other along and re-record with:
-# pnpm run verify-translation-pairing --write packages/bundle/session-search/README.md
-/:
- en: ac0fb71830f58337
- zh: 0ece950cf48261a1
-/deepseek-ai-dsh-session-search:
- en: 04bcc04b53b7a3b4
- zh: aceb77b602fcb0e8
-/deepseek-ai-dsh-session-search/summary:
- en: 7626a2d873e7c0fa
- zh: 4537d44c81126542
-/deepseek-ai-dsh-session-search/table-of-contents:
- en: d152484eb41ac6b4
- zh: 988e839059414d27
-/deepseek-ai-dsh-session-search/use-this-package:
- en: 958c815e002afb63
- zh: 2f429ace45fb2738
-/deepseek-ai-dsh-session-search/understand-the-implementation:
- en: e7eb9f3b6081a532
- zh: 49a942e930a1b7f7
-/deepseek-ai-dsh-session-search/further-exploration:
- en: fcd73e6db7e973cd
- zh: b158af8273d11df0
-/deepseek-ai-dsh-session-search/model-experience:
- en: e01cb02606d75f9c
- zh: 38709ef0209996ac
-/deepseek-ai-dsh-session-search/model-experience/kv-cache-effect:
- en: 1b2209bbbf869b1a
- zh: 5b9de62271343e4e
-/deepseek-ai-dsh-session-search/known-limitations-and-deferred-work:
- en: d5211fd04a6cdddd
- zh: d8ee29b1a060b77d
-/deepseek-ai-dsh-session-search/known-limitations-and-deferred-work/dev-note:
- en: 279d01435256cd2a
- zh: 83780964e5de2f54
diff --git a/packages/bundle/string-editor/README.i18n.yaml b/packages/bundle/string-editor/README.i18n.yaml
deleted file mode 100644
index db22d29929..0000000000
--- a/packages/bundle/string-editor/README.i18n.yaml
+++ /dev/null
@@ -1,37 +0,0 @@
-# Bilingual-pair consistency record for README.md (docs/i18n/README.md): per heading
-# section, a hash of its English and Chinese blocks outside code blocks and generated regions.
-# After editing either side, bring the other along and re-record with:
-# pnpm run verify-translation-pairing --write packages/bundle/string-editor/README.md
-/:
- en: 0b3c78e2974ee23e
- zh: a88be7b7a3597905
-/deepseek-ai-dsh-string-editor:
- en: 39dda6b9f981619c
- zh: 84ff97fcc5366a6c
-/deepseek-ai-dsh-string-editor/summary:
- en: 7faabd373dc07650
- zh: a103e851accd0f8a
-/deepseek-ai-dsh-string-editor/table-of-contents:
- en: d152484eb41ac6b4
- zh: 988e839059414d27
-/deepseek-ai-dsh-string-editor/use-this-package:
- en: 983e3a8a6357ae12
- zh: 1bad4087471b4c60
-/deepseek-ai-dsh-string-editor/understand-the-implementation:
- en: 878820ec8f3bab5c
- zh: 51eddc38d2a7685d
-/deepseek-ai-dsh-string-editor/further-exploration:
- en: eb617353b0c4d3bb
- zh: 7c8aa163a51d5646
-/deepseek-ai-dsh-string-editor/model-experience:
- en: 11bb237fccd3cad8
- zh: c74b0c591a5dd72b
-/deepseek-ai-dsh-string-editor/model-experience/kv-cache-effect:
- en: 1b2209bbbf869b1a
- zh: 5b9de62271343e4e
-/deepseek-ai-dsh-string-editor/known-limitations-and-deferred-work:
- en: 73646ce5ca58c7ad
- zh: da9660b48eff816d
-/deepseek-ai-dsh-string-editor/known-limitations-and-deferred-work/dev-note:
- en: 279d01435256cd2a
- zh: 83780964e5de2f54
diff --git a/packages/bundle/string-editor/README.md b/packages/bundle/string-editor/README.md
deleted file mode 100644
index e41fff72bb..0000000000
--- a/packages/bundle/string-editor/README.md
+++ /dev/null
@@ -1,78 +0,0 @@
----
-description: "Edit files with the str_replace_editor tool."
-kind: "package-bundle"
----
-
-# @deepseek-ai/dsh-string-editor
-
-English | [中文](README.zh.md)
-
-## Summary
-
-Add str_replace_editor to standard, cordis, and ptc alongside their existing filesystem tools. It ships switched off in Web and Desktop. Select it in Plugins to enable it.
-
-## Table of Contents
-
-- [Use this package](#use-this-package)
-- [Understand the implementation](#understand-the-implementation)
-- [Further Exploration](#further-exploration)
-- [Model Experience](#model-experience)
-- [Known Limitations and Deferred Work](#known-limitations-and-deferred-work)
-- [Dev Note](#dev-note)
-
------
-
-
-## Use this package
-
-In Web or Desktop, open Plugins and enable **String editor** in Official. Switch it off to remove its profile layer.
-
-New Agents and subsequently reopened Sessions use the selected composition; live Agents retain their existing plugins. The minimal preset and host-level tool catalog remain unchanged.
-
------
-
-
-## Understand the implementation
-
-
-Implementation details — click to expand
-
-[`cordis.patch.yml`](cordis.patch.yml) contributes rows through `preset: preset-standard`, `preset: preset-cordis`, and `preset: preset-ptc`. Later profile patches can override their settings. The [profile composer](../../boot/app-boot/README.md) owns patch ordering and errors.
-
-
-
------
-
-
-## Further Exploration
-
-[Capability implementation](../../fs/tool-str-replace-editor/README.md)
-
------
-
-
-## Model Experience
-
-Indirectly, through the [capability implementation](../../fs/tool-str-replace-editor/README.md), which owns model context and results.
-
-#### KV Cache effect
-
-The layer adds no request content directly; the capability implementation owns cache effects from tools, prompts, and results.
-
-## Known Limitations and Deferred Work
-
-
-
-- This editor overlaps with existing filesystem tools and follows their workspace authorization and observation requirements.
-
------
-
-
-### Dev Note
-
-
-Maintainer context — click to expand
-
-None.
-
-
diff --git a/packages/bundle/string-editor/README.zh.md b/packages/bundle/string-editor/README.zh.md
deleted file mode 100644
index 704d3062e2..0000000000
--- a/packages/bundle/string-editor/README.zh.md
+++ /dev/null
@@ -1,78 +0,0 @@
----
-description: "使用 str_replace_editor 工具编辑文件。"
-kind: "package-bundle"
----
-
-# @deepseek-ai/dsh-string-editor
-
-[English](README.md) | 中文
-
-## 概述
-
-为 standard、cordis 和 ptc 添加 str_replace_editor,保留原有文件系统工具。 Web 和 Desktop 随附此功能,默认关闭。在插件页选择它即可启用。
-
-## 目录
-
-- [使用此包](#use-this-package)
-- [理解实现](#understand-the-implementation)
-- [进一步探索](#further-exploration)
-- [模型体验](#model-experience)
-- [已知限制与暂缓工作](#known-limitations-and-deferred-work)
-- [开发备注](#dev-note)
-
------
-
-
-## 使用此包
-
-在 Web 或 Desktop 中打开插件页,在官方分组启用 **字符串编辑器**。关闭后移除其配置层。
-
-新智能体和随后重新打开的会话使用所选组合;正在运行的智能体保留已有插件。minimal 预设和 Host 层工具目录保持不变。
-
------
-
-
-## 理解实现
-
-
-实现细节 — 点击展开
-
-[`cordis.patch.yml`](cordis.patch.yml) 通过 `preset: preset-standard`、`preset: preset-cordis` 和 `preset: preset-ptc` 贡献插件行。后续配置补丁可以覆盖这些设置。[配置组合器](../../boot/app-boot/README.zh.md) 负责补丁顺序和错误处理。
-
-
-
------
-
-
-## 进一步探索
-
-[能力实现](../../fs/tool-str-replace-editor/README.zh.md)
-
------
-
-
-## 模型体验
-
-间接影响,通过[能力实现](../../fs/tool-str-replace-editor/README.zh.md) 贡献模型上下文和结果。
-
-#### KV Cache 影响
-
-此配置层不直接添加请求内容;能力实现负责工具目录、提示和结果的缓存影响。
-
-## 已知限制与暂缓工作
-
-
-
-- 此编辑器与现有文件系统工具的功能重叠,并遵守工作区授权和文件观察要求。
-
------
-
-
-### 开发备注
-
-
-维护者上下文 — 点击展开
-
-无。
-
-
diff --git a/packages/bundle/string-editor/cordis.patch.yml b/packages/bundle/string-editor/cordis.patch.yml
deleted file mode 100644
index e78f0fd35d..0000000000
--- a/packages/bundle/string-editor/cordis.patch.yml
+++ /dev/null
@@ -1,14 +0,0 @@
-- preset: preset-standard
- insert:
- - id: optional-tool-str-replace-editor
- name: '@deepseek-ai/dsh-tool-str-replace-editor'
-
-- preset: preset-cordis
- insert:
- - id: optional-tool-str-replace-editor
- name: '@deepseek-ai/dsh-tool-str-replace-editor'
-
-- preset: preset-ptc
- insert:
- - id: optional-tool-str-replace-editor
- name: '@deepseek-ai/dsh-tool-str-replace-editor'
diff --git a/packages/bundle/string-editor/icon.svg b/packages/bundle/string-editor/icon.svg
deleted file mode 100644
index b140ff7c64..0000000000
--- a/packages/bundle/string-editor/icon.svg
+++ /dev/null
@@ -1 +0,0 @@
-
diff --git a/packages/bundle/string-editor/locale/en.json b/packages/bundle/string-editor/locale/en.json
deleted file mode 100644
index 813030ce65..0000000000
--- a/packages/bundle/string-editor/locale/en.json
+++ /dev/null
@@ -1,6 +0,0 @@
-{
- "meta": {
- "title": "String editor",
- "description": "Edit files with the str_replace_editor tool."
- }
-}
diff --git a/packages/bundle/string-editor/locale/zh.json b/packages/bundle/string-editor/locale/zh.json
deleted file mode 100644
index 0cd1f9b40b..0000000000
--- a/packages/bundle/string-editor/locale/zh.json
+++ /dev/null
@@ -1,6 +0,0 @@
-{
- "meta": {
- "title": "字符串编辑器",
- "description": "使用 str_replace_editor 工具编辑文件。"
- }
-}
diff --git a/packages/bundle/string-editor/package.json b/packages/bundle/string-editor/package.json
deleted file mode 100644
index 5668403a8e..0000000000
--- a/packages/bundle/string-editor/package.json
+++ /dev/null
@@ -1,49 +0,0 @@
-{
- "name": "@deepseek-ai/dsh-string-editor",
- "description": "Edit files with the str_replace_editor tool.",
- "version": "0.2.1-alpha.1",
- "icon": "./icon.svg",
- "publishConfig": {
- "access": "public"
- },
- "repository": {
- "type": "git",
- "url": "git+https://github.com/deepseek-ai/deepseek-harness.git",
- "directory": "packages/bundle/string-editor"
- },
- "type": "module",
- "main": "lib/index.js",
- "types": "lib/types/index.d.ts",
- "exports": {
- ".": {
- "types": "./lib/types/index.d.ts",
- "default": "./lib/index.js"
- },
- "./cordis.patch.yml": "./cordis.patch.yml",
- "./locale/*.json": "./locale/*.json",
- "./src/*": "./src/*",
- "./package.json": "./package.json"
- },
- "files": [
- "icon.svg",
- "locale/*.json",
- "lib/index.js",
- "cordis.patch.yml",
- "lib/types/**/*.d.ts"
- ],
- "license": "MIT",
- "dsh": {
- "bundle": {
- "patch": "./cordis.patch.yml"
- }
- },
- "dependencies": {
- "@deepseek-ai/dsh-tool-str-replace-editor": "workspace:*"
- },
- "peerDependencies": {
- "@deepseek-ai/cordis": "workspace:~"
- },
- "devDependencies": {
- "@deepseek-ai/cordis": "workspace:~"
- }
-}
diff --git a/packages/bundle/string-editor/src/index.ts b/packages/bundle/string-editor/src/index.ts
deleted file mode 100644
index d53829cf34..0000000000
--- a/packages/bundle/string-editor/src/index.ts
+++ /dev/null
@@ -1,2 +0,0 @@
-/** String editor profile layer; runtime entries are declared in cordis.patch.yml. */
-export {}
diff --git a/packages/bundle/string-editor/tsconfig.json b/packages/bundle/string-editor/tsconfig.json
deleted file mode 100644
index f1a449634c..0000000000
--- a/packages/bundle/string-editor/tsconfig.json
+++ /dev/null
@@ -1,15 +0,0 @@
-{
- "extends": "../../../tsconfig.base.json",
- "compilerOptions": {
- "rootDir": "src",
- "outDir": "lib/types"
- },
- "include": [
- "src"
- ],
- "references": [
- {
- "path": "../../../vendor/cordis"
- }
- ]
-}
diff --git a/packages/bundle/tmux-location/README.i18n.yaml b/packages/bundle/tmux-location/README.i18n.yaml
deleted file mode 100644
index f5b790acec..0000000000
--- a/packages/bundle/tmux-location/README.i18n.yaml
+++ /dev/null
@@ -1,37 +0,0 @@
-# Bilingual-pair consistency record for README.md (docs/i18n/README.md): per heading
-# section, a hash of its English and Chinese blocks outside code blocks and generated regions.
-# After editing either side, bring the other along and re-record with:
-# pnpm run verify-translation-pairing --write packages/bundle/tmux-location/README.md
-/:
- en: abb9ad88845a269c
- zh: c9a96576c1c63e5f
-/deepseek-ai-dsh-tmux-location:
- en: 7a09a973be4f5928
- zh: 4421d7042de293cd
-/deepseek-ai-dsh-tmux-location/summary:
- en: 0c24b9949fb2abca
- zh: 454e3c18b985a62a
-/deepseek-ai-dsh-tmux-location/table-of-contents:
- en: d152484eb41ac6b4
- zh: 988e839059414d27
-/deepseek-ai-dsh-tmux-location/use-this-package:
- en: 3060df5b52b95d4a
- zh: c04fbce2fe75a633
-/deepseek-ai-dsh-tmux-location/understand-the-implementation:
- en: 878820ec8f3bab5c
- zh: 51eddc38d2a7685d
-/deepseek-ai-dsh-tmux-location/further-exploration:
- en: 10b3d66543bb26a4
- zh: a8474dcf3fc93d85
-/deepseek-ai-dsh-tmux-location/model-experience:
- en: e9a9a7b0723e98b9
- zh: 3cf108307e3093ce
-/deepseek-ai-dsh-tmux-location/model-experience/kv-cache-effect:
- en: 1b2209bbbf869b1a
- zh: 5b9de62271343e4e
-/deepseek-ai-dsh-tmux-location/known-limitations-and-deferred-work:
- en: 487ebdb62ba78ea2
- zh: acd142a5cdaa5301
-/deepseek-ai-dsh-tmux-location/known-limitations-and-deferred-work/dev-note:
- en: 279d01435256cd2a
- zh: 83780964e5de2f54
diff --git a/packages/bundle/tmux-location/README.md b/packages/bundle/tmux-location/README.md
deleted file mode 100644
index b471576271..0000000000
--- a/packages/bundle/tmux-location/README.md
+++ /dev/null
@@ -1,78 +0,0 @@
----
-description: "Let agents read the current tmux pane and layout when available."
-kind: "package-bundle"
----
-
-# @deepseek-ai/dsh-tmux-location
-
-English | [中文](README.zh.md)
-
-## Summary
-
-Give standard, cordis, and ptc the current tmux session, window, pane, and layout when the process runs inside tmux. It ships switched off in Web and Desktop. Select it in Plugins to enable it.
-
-## Table of Contents
-
-- [Use this package](#use-this-package)
-- [Understand the implementation](#understand-the-implementation)
-- [Further Exploration](#further-exploration)
-- [Model Experience](#model-experience)
-- [Known Limitations and Deferred Work](#known-limitations-and-deferred-work)
-- [Dev Note](#dev-note)
-
------
-
-
-## Use this package
-
-In Web or Desktop, open Plugins and enable **tmux location** in Official. Switch it off to remove its profile layer.
-
-New Agents and subsequently reopened Sessions use the selected composition; live Agents retain their existing plugins. The minimal preset and host-level tool catalog remain unchanged.
-
------
-
-
-## Understand the implementation
-
-
-Implementation details — click to expand
-
-[`cordis.patch.yml`](cordis.patch.yml) contributes rows through `preset: preset-standard`, `preset: preset-cordis`, and `preset: preset-ptc`. Later profile patches can override their settings. The [profile composer](../../boot/app-boot/README.md) owns patch ordering and errors.
-
-
-
------
-
-
-## Further Exploration
-
-[Capability implementation](../../context/tmux-context/README.md)
-
------
-
-
-## Model Experience
-
-Indirectly, through the [capability implementation](../../context/tmux-context/README.md), which owns model context and results.
-
-#### KV Cache effect
-
-The layer adds no request content directly; the capability implementation owns cache effects from tools, prompts, and results.
-
-## Known Limitations and Deferred Work
-
-
-
-- No context is added outside a verified tmux pane. Inherited tmux variables alone do not establish that the process belongs to the pane.
-
------
-
-
-### Dev Note
-
-
-Maintainer context — click to expand
-
-None.
-
-
diff --git a/packages/bundle/tmux-location/README.zh.md b/packages/bundle/tmux-location/README.zh.md
deleted file mode 100644
index 7c7e987f39..0000000000
--- a/packages/bundle/tmux-location/README.zh.md
+++ /dev/null
@@ -1,78 +0,0 @@
----
-description: "在可用时让智能体读取当前 tmux 窗格和布局。"
-kind: "package-bundle"
----
-
-# @deepseek-ai/dsh-tmux-location
-
-[English](README.md) | 中文
-
-## 概述
-
-当进程在 tmux 中运行时,为 standard、cordis 和 ptc 提供当前 tmux 会话、窗口、窗格和布局。 Web 和 Desktop 随附此功能,默认关闭。在插件页选择它即可启用。
-
-## 目录
-
-- [使用此包](#use-this-package)
-- [理解实现](#understand-the-implementation)
-- [进一步探索](#further-exploration)
-- [模型体验](#model-experience)
-- [已知限制与暂缓工作](#known-limitations-and-deferred-work)
-- [开发备注](#dev-note)
-
------
-
-
-## 使用此包
-
-在 Web 或 Desktop 中打开插件页,在官方分组启用 **tmux 位置**。关闭后移除其配置层。
-
-新智能体和随后重新打开的会话使用所选组合;正在运行的智能体保留已有插件。minimal 预设和 Host 层工具目录保持不变。
-
------
-
-
-## 理解实现
-
-
-实现细节 — 点击展开
-
-[`cordis.patch.yml`](cordis.patch.yml) 通过 `preset: preset-standard`、`preset: preset-cordis` 和 `preset: preset-ptc` 贡献插件行。后续配置补丁可以覆盖这些设置。[配置组合器](../../boot/app-boot/README.zh.md) 负责补丁顺序和错误处理。
-
-
-
------
-
-
-## 进一步探索
-
-[能力实现](../../context/tmux-context/README.zh.md)
-
------
-
-
-## 模型体验
-
-间接影响,通过[能力实现](../../context/tmux-context/README.zh.md) 贡献模型上下文和结果。
-
-#### KV Cache 影响
-
-此配置层不直接添加请求内容;能力实现负责工具目录、提示和结果的缓存影响。
-
-## 已知限制与暂缓工作
-
-
-
-- 在未验证的 tmux 窗格之外不添加上下文。仅继承 tmux 变量不能证明进程属于该窗格。
-
------
-
-
-### 开发备注
-
-
-维护者上下文 — 点击展开
-
-无。
-
-
diff --git a/packages/bundle/tmux-location/cordis.patch.yml b/packages/bundle/tmux-location/cordis.patch.yml
deleted file mode 100644
index fca150eec7..0000000000
--- a/packages/bundle/tmux-location/cordis.patch.yml
+++ /dev/null
@@ -1,14 +0,0 @@
-- preset: preset-standard
- insert:
- - id: optional-tmux-context
- name: '@deepseek-ai/dsh-tmux-context'
-
-- preset: preset-cordis
- insert:
- - id: optional-tmux-context
- name: '@deepseek-ai/dsh-tmux-context'
-
-- preset: preset-ptc
- insert:
- - id: optional-tmux-context
- name: '@deepseek-ai/dsh-tmux-context'
diff --git a/packages/bundle/tmux-location/icon.svg b/packages/bundle/tmux-location/icon.svg
deleted file mode 100644
index 23c04e86a7..0000000000
--- a/packages/bundle/tmux-location/icon.svg
+++ /dev/null
@@ -1 +0,0 @@
-
diff --git a/packages/bundle/tmux-location/locale/en.json b/packages/bundle/tmux-location/locale/en.json
deleted file mode 100644
index ef25ff6492..0000000000
--- a/packages/bundle/tmux-location/locale/en.json
+++ /dev/null
@@ -1,6 +0,0 @@
-{
- "meta": {
- "title": "tmux location",
- "description": "Let agents read the current tmux pane and layout when available."
- }
-}
diff --git a/packages/bundle/tmux-location/locale/zh.json b/packages/bundle/tmux-location/locale/zh.json
deleted file mode 100644
index 3c5441ce06..0000000000
--- a/packages/bundle/tmux-location/locale/zh.json
+++ /dev/null
@@ -1,6 +0,0 @@
-{
- "meta": {
- "title": "tmux 位置",
- "description": "在可用时让智能体读取当前 tmux 窗格和布局。"
- }
-}
diff --git a/packages/bundle/tmux-location/package.json b/packages/bundle/tmux-location/package.json
deleted file mode 100644
index 15110465c6..0000000000
--- a/packages/bundle/tmux-location/package.json
+++ /dev/null
@@ -1,49 +0,0 @@
-{
- "name": "@deepseek-ai/dsh-tmux-location",
- "description": "Let agents read the current tmux pane and layout when available.",
- "version": "0.2.1-alpha.1",
- "icon": "./icon.svg",
- "publishConfig": {
- "access": "public"
- },
- "repository": {
- "type": "git",
- "url": "git+https://github.com/deepseek-ai/deepseek-harness.git",
- "directory": "packages/bundle/tmux-location"
- },
- "type": "module",
- "main": "lib/index.js",
- "types": "lib/types/index.d.ts",
- "exports": {
- ".": {
- "types": "./lib/types/index.d.ts",
- "default": "./lib/index.js"
- },
- "./cordis.patch.yml": "./cordis.patch.yml",
- "./locale/*.json": "./locale/*.json",
- "./src/*": "./src/*",
- "./package.json": "./package.json"
- },
- "files": [
- "icon.svg",
- "locale/*.json",
- "lib/index.js",
- "cordis.patch.yml",
- "lib/types/**/*.d.ts"
- ],
- "license": "MIT",
- "dsh": {
- "bundle": {
- "patch": "./cordis.patch.yml"
- }
- },
- "dependencies": {
- "@deepseek-ai/dsh-tmux-context": "workspace:*"
- },
- "peerDependencies": {
- "@deepseek-ai/cordis": "workspace:~"
- },
- "devDependencies": {
- "@deepseek-ai/cordis": "workspace:~"
- }
-}
diff --git a/packages/bundle/tmux-location/src/index.ts b/packages/bundle/tmux-location/src/index.ts
deleted file mode 100644
index 12a0b5988d..0000000000
--- a/packages/bundle/tmux-location/src/index.ts
+++ /dev/null
@@ -1,2 +0,0 @@
-/** tmux location profile layer; runtime entries are declared in cordis.patch.yml. */
-export {}
diff --git a/packages/bundle/tmux-location/tsconfig.json b/packages/bundle/tmux-location/tsconfig.json
deleted file mode 100644
index f1a449634c..0000000000
--- a/packages/bundle/tmux-location/tsconfig.json
+++ /dev/null
@@ -1,15 +0,0 @@
-{
- "extends": "../../../tsconfig.base.json",
- "compilerOptions": {
- "rootDir": "src",
- "outDir": "lib/types"
- },
- "include": [
- "src"
- ],
- "references": [
- {
- "path": "../../../vendor/cordis"
- }
- ]
-}
diff --git a/packages/client/ui-workspace/README.i18n.yaml b/packages/client/ui-workspace/README.i18n.yaml
index 4e07b343fb..72e150aa9b 100644
--- a/packages/client/ui-workspace/README.i18n.yaml
+++ b/packages/client/ui-workspace/README.i18n.yaml
@@ -36,8 +36,8 @@
en: dd0a7799c76c0f94
zh: 48d1cdacc9168aa2
/deepseek-ai-dsh-client-ui-workspace/understand-the-implementation:
- en: 0cc718002a249cc9
- zh: 969b2a034331ab56
+ en: 721d5a49fe231191
+ zh: 3ef1dd720219e00e
/deepseek-ai-dsh-client-ui-workspace/understand-the-implementation/the-directory-flow-hole:
en: 978415ec6b2e0cc0
zh: 0d5c705ff34fb1da
diff --git a/packages/client/ui-workspace/README.md b/packages/client/ui-workspace/README.md
index b4f3ba4052..d8ad74def5 100644
--- a/packages/client/ui-workspace/README.md
+++ b/packages/client/ui-workspace/README.md
@@ -89,7 +89,7 @@ The package is one composition: both target slots are declared by other plugins,
The browser entry also declares two root-scoped `list` child seats on each Session row: `sidebar.session.row.leading`, rendered only while that row's primary status is idle and left blank on an archived row, and `sidebar.session.row.hover`, mounted only while that row's hover card is open. Both take the row's Session identity and nothing else, so an occupant reads its own data by that id; a Session-scoped seat would force a Session binding, which would activate and retain every listed Session.
-Client callers can pass `prompt` and `clearPreviousDraft` in the second argument to `uiWorkspace.startSession`. A prompt is plain text; structured drafts are handled internally during restoration and Workspace transfer. Without clearing, existing text or attachments are preserved; explicit clearing replaces only the target Session's text and inline references, leaving attachments intact. Option values are captured before asynchronous creation and applied to the exact retained binding before navigation commits. Superseded navigation does not write content; a submission-blocked input refuses preparation and keeps the previous selection. Calls without options retain the normal New Session flow. The [draft initialization decision](../../../.agents/notes/implemented/architecture/2026-09-30-structured-draft-initialization.md) describes the input owner's data flow.
+Client callers can pass `prompt` and `clearPreviousDraft` in the second argument to `uiWorkspace.startSession`. A prompt is plain text; structured drafts are handled internally during restoration and Workspace transfer. Without clearing, existing text or attachments are preserved; explicit clearing replaces only the target Session's text and inline references, leaving attachments intact. Option values are captured before asynchronous creation and applied to the exact retained binding before navigation commits. Superseded navigation does not write content; a submission-blocked input refuses preparation and keeps the previous selection. Calls without options create a fresh Session using the current Agent preset definition. Workspace reconnection and explicit draft preparation may reuse an existing blank Session. The [draft initialization decision](../../../.agents/notes/implemented/architecture/2026-09-30-structured-draft-initialization.md) describes the input owner's data flow.
### The directory-flow hole
diff --git a/packages/client/ui-workspace/README.zh.md b/packages/client/ui-workspace/README.zh.md
index def7a0129a..97d1eb49ca 100644
--- a/packages/client/ui-workspace/README.zh.md
+++ b/packages/client/ui-workspace/README.zh.md
@@ -89,7 +89,7 @@ Workspace 和 Session 的启动基线均就绪后,空安装环境调用 `works
浏览器入口还为每个 Session 行声明两个 root 作用域的 `list` 子 slot:`sidebar.session.row.leading` 仅在该行主状态为 idle 时渲染、归档行留空,`sidebar.session.row.hover` 仅在该行的悬浮卡片打开时挂载。两者只接收行的 Session 身份,占用方据此读取自己的数据;Session 作用域的 slot 会强制建立 Session 绑定,从而激活并保留列表中每个 Session。
-客户端调用方可以在 `uiWorkspace.startSession` 的第二参数中传入 `prompt` 与 `clearPreviousDraft`。提示词仅接受普通文字;结构化草稿由内部恢复和工作区携带流程处理。不清空时保留已有文字或附件;显式清空只替换目标 Session 的文字和内联引用,不删除附件。在异步创建前捕获选项值,在导航提交前应用到准确保留的 binding。已被后续操作取代的导航不写内容;输入处于提交阻塞状态时拒绝准备并保留原选择。不传选项时保持正常新会话流程。[草稿初始化决策](../../../.agents/notes/implemented/architecture/2026-09-30-structured-draft-initialization.zh.md)说明输入 owner 的数据流。
+客户端调用方可以在 `uiWorkspace.startSession` 的第二参数中传入 `prompt` 与 `clearPreviousDraft`。提示词仅接受普通文字;结构化草稿由内部恢复和工作区携带流程处理。不清空时保留已有文字或附件;显式清空只替换目标 Session 的文字和内联引用,不删除附件。在异步创建前捕获选项值,在导航提交前应用到准确保留的 binding。已被后续操作取代的导航不写内容;输入处于提交阻塞状态时拒绝准备并保留原选择。不传选项时按当前 Agent 预设定义创建新的 Session。工作区重连和显式草稿准备仍可复用已有空 Session。[草稿初始化决策](../../../.agents/notes/implemented/architecture/2026-09-30-structured-draft-initialization.zh.md)说明输入 owner 的数据流。
### 目录流子 slot
diff --git a/packages/client/ui-workspace/src/client/navigation.ts b/packages/client/ui-workspace/src/client/navigation.ts
index 61084b7f79..e58732586d 100644
--- a/packages/client/ui-workspace/src/client/navigation.ts
+++ b/packages/client/ui-workspace/src/client/navigation.ts
@@ -61,7 +61,7 @@ export interface UiWorkspace {
*/
connectWorkspace(workspaceId: WorkspaceId): Promise
/**
- * Start a New Session flow and navigate to its Session; a creation the Host
+ * Create a fresh Session, or reuse a blank when preparing an explicit draft. A creation the Host
* refuses is shown through the Workspace notice and leaves the selection as it was.
* @param workspaceId - explicit target; absent inherits the current or most recent Workspace.
* @param options - initial content; existing text or attachments are preserved unless clearPreviousDraft is true.
@@ -167,12 +167,17 @@ class UiWorkspaceService extends Service implements UiWorkspace {
}, 'ui-workspace: Workspace navigation policy')
}
- async connectWorkspace(workspaceId: WorkspaceId): Promise {
+ connectWorkspace(workspaceId: WorkspaceId): Promise {
+ return this.connectBlank(workspaceId, true)
+ }
+
+ private async connectBlank(workspaceId: WorkspaceId, reuse: boolean): Promise {
const workspace = this.workspaces.list.getSnapshot().items
.find(item => item.workspaceId === workspaceId)
if (workspace === undefined) {
throw new Error(`uiWorkspace.connectWorkspace: unknown workspace ${workspaceId}`)
}
+ if (!reuse) return this.sessions.create({ workspaceId })
const inflight = this.connecting.get(workspaceId)
if (inflight !== undefined) return inflight
@@ -207,11 +212,17 @@ class UiWorkspaceService extends Service implements UiWorkspace {
this.replaceMain(target, this.lifetime.signal, 'reveal')
}
- async openWorkspace(workspaceId: WorkspaceId, beforeOpen?: (sessionId: SessionId) => void): Promise {
+ openWorkspace(workspaceId: WorkspaceId, beforeOpen?: (sessionId: SessionId) => void): Promise {
+ return this.openWorkspaceSession(workspaceId, beforeOpen, true)
+ }
+
+ private async openWorkspaceSession(
+ workspaceId: WorkspaceId, beforeOpen: ((sessionId: SessionId) => void) | undefined, reuse: boolean,
+ ): Promise {
const navigation = AbortSignal.any([this.ctx.layout.beginNavigation(), this.lifetime.signal])
let sessionId: SessionId
try {
- sessionId = await this.connectWorkspace(workspaceId)
+ sessionId = await this.connectBlank(workspaceId, reuse)
} catch (error: unknown) {
// Reported here, not in connectWorkspace: startup restoration calls that
// directly and stays console-only.
@@ -248,11 +259,14 @@ class UiWorkspaceService extends Service implements UiWorkspace {
this.clearMain()
return
}
- void this.openWorkspace(target, initializeDraft ? (id) => {
- const binding = this.sessions.binding(id)
- if (binding === undefined) this.draftPreparationFailed()
- this.prepareDraft(binding, draftOptions)
- } : undefined).catch(
+ const opening = draftOptions === undefined
+ ? this.openWorkspaceSession(target, undefined, false)
+ : this.openWorkspace(target, initializeDraft ? (id) => {
+ const binding = this.sessions.binding(id)
+ if (binding === undefined) this.draftPreparationFailed()
+ this.prepareDraft(binding, draftOptions)
+ } : undefined)
+ void opening.catch(
(reason: unknown) => { console.warn('new session failed:', reason) },
)
}
diff --git a/packages/client/ui-workspace/tests/workspaces-service.client.spec.ts b/packages/client/ui-workspace/tests/workspaces-service.client.spec.ts
index ef041c51b2..579db72f66 100644
--- a/packages/client/ui-workspace/tests/workspaces-service.client.spec.ts
+++ b/packages/client/ui-workspace/tests/workspaces-service.client.spec.ts
@@ -662,6 +662,18 @@ describe('UiWorkspaceService', () => {
expect(b.sessions.retain).not.toHaveBeenCalled()
})
+ it('creates a fresh Agent on explicit New Session instead of reusing a mounted blank', async () => {
+ const b = bench({
+ sessions: sessionState([summary('blank', { blank: true, cwd: '/w/a' })], 'pending'),
+ workspaces: workspaceState([workspace('a', [sid('blank')])]),
+ })
+ b.uiWorkspace.startSession(wid('a'))
+ await vi.waitFor(() => {
+ expect(b.sessions.create).toHaveBeenCalledExactlyOnceWith({ workspaceId: wid('a') })
+ })
+ await vi.waitFor(() => { expect(b.sessions.retain).toHaveBeenCalledWith(sid('created-a'), expect.anything()) })
+ })
+
it('reports a refused explicit Session creation through the Workspace notice', async () => {
const b = bench({ workspaces: workspaceState([workspace('a')]), sessions: sessionState() })
// Startup restoration creates its own Session first and stays quiet on failure (pinned above).
@@ -797,7 +809,8 @@ describe('UiWorkspaceService', () => {
const opening = vi.spyOn(b.uiWorkspace, 'openWorkspace')
b.uiWorkspace.startSession(wid('a'), options)
- await lastOpening(opening)
+ if (options === undefined) await vi.waitFor(() => { expect(b.sessions.retain).toHaveBeenCalledOnce() })
+ else await lastOpening(opening)
expect(b.sessions.retain).toHaveBeenCalledExactlyOnceWith(sid('created-a'), { source: 'mainView' })
expect(b.sessions.binding).not.toHaveBeenCalled()
diff --git a/packages/experimental/README.i18n.yaml b/packages/experimental/README.i18n.yaml
index 453a9a8aa0..37a3b83ad0 100644
--- a/packages/experimental/README.i18n.yaml
+++ b/packages/experimental/README.i18n.yaml
@@ -18,8 +18,8 @@
en: b55aeb927737b90d
zh: 0b215fcb5c2c7908
/packages-experimental/packages:
- en: a7fb1f6cc249d885
- zh: 523ecd7600ecd436
+ en: 8d4c5d32901b2ce6
+ zh: 0240d4c81489edaa
/packages-experimental/related-documentation:
en: 1cb9d3448d44e48d
zh: cd326d70a746b896
diff --git a/packages/experimental/README.md b/packages/experimental/README.md
index 5bde76d20b..57d0f5aae5 100644
--- a/packages/experimental/README.md
+++ b/packages/experimental/README.md
@@ -37,6 +37,7 @@ Promotion requires a named product role, documented public behavior and limitati
| Package | Role | ctx key |
|---|---|---|
| [`tool-session-query`](tool-session-query/README.md) | Workspace-authorized model session search, trace, and event reads | — |
+| [`session-search`](session-search/README.md) | Optional experimental session search in full Web presets | — |
| [`ralph-bundle`](ralph-bundle/README.md) | Optional repeated delegation with an isolated workflow engine | — |
| [`terminal-bundle`](terminal-bundle/README.md) | Optional persistent terminal tools for full Web presets | — |
| [`badge-skill-bundle`](badge-skill-bundle/README.md) | Optional powered-by-dsh badge skill | — |
diff --git a/packages/experimental/README.zh.md b/packages/experimental/README.zh.md
index 36967ae96c..4c6176f99b 100644
--- a/packages/experimental/README.zh.md
+++ b/packages/experimental/README.zh.md
@@ -37,6 +37,7 @@ kind: "package-group"
| 包 | 职责 | ctx 键 |
|---|---|---|
| [`tool-session-query`](tool-session-query/README.zh.md) | 按工作区授权的模型会话搜索、追踪与事件读取 | — |
+| [`session-search`](session-search/README.zh.md) | 完整 Web 预设的可选实验性会话搜索 | — |
| [`ralph-bundle`](ralph-bundle/README.zh.md) | 带隔离 workflow 引擎的可选重复委派 | — |
| [`terminal-bundle`](terminal-bundle/README.zh.md) | 完整 Web 预设的可选持久终端工具 | — |
| [`badge-skill-bundle`](badge-skill-bundle/README.zh.md) | 可选 powered-by-dsh 徽章技能 | — |
diff --git a/packages/experimental/session-search/README.i18n.yaml b/packages/experimental/session-search/README.i18n.yaml
new file mode 100644
index 0000000000..931c2588eb
--- /dev/null
+++ b/packages/experimental/session-search/README.i18n.yaml
@@ -0,0 +1,37 @@
+# Bilingual-pair consistency record for README.md (docs/i18n/README.md): per heading
+# section, a hash of its English and Chinese blocks outside code blocks and generated regions.
+# After editing either side, bring the other along and re-record with:
+# pnpm run verify-translation-pairing --write packages/experimental/session-search/README.md
+/:
+ en: ac0fb71830f58337
+ zh: 0ece950cf48261a1
+/deepseek-ai-dsh-experimental-session-search:
+ en: f4f9c83d1dd36580
+ zh: f34e5a1c0df5e469
+/deepseek-ai-dsh-experimental-session-search/summary:
+ en: 565d4c9c763ed823
+ zh: 36b12b0511b46f5e
+/deepseek-ai-dsh-experimental-session-search/table-of-contents:
+ en: d152484eb41ac6b4
+ zh: 988e839059414d27
+/deepseek-ai-dsh-experimental-session-search/use-this-package:
+ en: 958c815e002afb63
+ zh: 2f429ace45fb2738
+/deepseek-ai-dsh-experimental-session-search/understand-the-implementation:
+ en: e7eb9f3b6081a532
+ zh: 49a942e930a1b7f7
+/deepseek-ai-dsh-experimental-session-search/further-exploration:
+ en: 3016959b8c0546d0
+ zh: a356ef50b3ce9f77
+/deepseek-ai-dsh-experimental-session-search/model-experience:
+ en: 00d8bdccc42b1f10
+ zh: 3264a962cff8127e
+/deepseek-ai-dsh-experimental-session-search/model-experience/kv-cache-effect:
+ en: 1b2209bbbf869b1a
+ zh: 5b9de62271343e4e
+/deepseek-ai-dsh-experimental-session-search/known-limitations-and-deferred-work:
+ en: d5211fd04a6cdddd
+ zh: d8ee29b1a060b77d
+/deepseek-ai-dsh-experimental-session-search/known-limitations-and-deferred-work/dev-note:
+ en: 279d01435256cd2a
+ zh: 83780964e5de2f54
diff --git a/packages/bundle/session-search/README.md b/packages/experimental/session-search/README.md
similarity index 81%
rename from packages/bundle/session-search/README.md
rename to packages/experimental/session-search/README.md
index 12e29b0064..22b94aed22 100644
--- a/packages/bundle/session-search/README.md
+++ b/packages/experimental/session-search/README.md
@@ -3,13 +3,13 @@ description: "Give Agents tools to search and read earlier sessions from the cur
kind: "package-bundle"
---
-# @deepseek-ai/dsh-session-search
+# @deepseek-ai/dsh-experimental-session-search
English | [中文](README.zh.md)
## Summary
-Give Agents five read-only tools to search earlier sessions in standard, cordis, and ptc. The content index opens on the first search and is shared by Agents using the same preset revision. The bundle ships switched off in Web and Desktop. Select it in Plugins to enable it.
+Give Agents five experimental read-only tools to search earlier sessions in standard, cordis, and ptc. The content index opens on the first search and is shared by Agents using the same preset revision. The bundle ships switched off in Web and Desktop. Select it in Plugins to enable it.
## Table of Contents
@@ -50,14 +50,14 @@ Each preset revision owns an isolated `sessionQuery` provider with a lazy `:memo
## Further Exploration
-[Capability implementation](../../session-query/tool-session-query/README.md)
+[Capability implementation](../tool-session-query/README.md)
-----
## Model Experience
-Indirectly, through the [capability implementation](../../session-query/tool-session-query/README.md), which owns model context and results.
+Indirectly, through the [capability implementation](../tool-session-query/README.md), which owns model context and results.
#### KV Cache effect
diff --git a/packages/bundle/session-search/README.zh.md b/packages/experimental/session-search/README.zh.md
similarity index 80%
rename from packages/bundle/session-search/README.zh.md
rename to packages/experimental/session-search/README.zh.md
index bcdb8f09ca..f099d29b5b 100644
--- a/packages/bundle/session-search/README.zh.md
+++ b/packages/experimental/session-search/README.zh.md
@@ -3,13 +3,13 @@ description: "为智能体提供搜索和读取当前工作区历史会话的工
kind: "package-bundle"
---
-# @deepseek-ai/dsh-session-search
+# @deepseek-ai/dsh-experimental-session-search
[English](README.md) | 中文
## 概述
-为 standard、cordis 和 ptc 中的智能体提供五个只读工具,用于搜索历史会话。内容索引在首次搜索时打开,由使用同一预设版本的智能体共享。Web 和 Desktop 随附此配置包,默认关闭。在插件页选择它即可启用。
+为 standard、cordis 和 ptc 中的智能体提供五个实验性只读工具,用于搜索历史会话。内容索引在首次搜索时打开,由使用同一预设版本的智能体共享。Web 和 Desktop 随附此配置包,默认关闭。在插件页选择它即可启用。
## 目录
@@ -50,14 +50,14 @@ kind: "package-bundle"
## 进一步探索
-[能力实现](../../session-query/tool-session-query/README.zh.md)
+[能力实现](../tool-session-query/README.zh.md)
-----
## 模型体验
-间接影响,通过[能力实现](../../session-query/tool-session-query/README.zh.md) 贡献模型上下文和结果。
+间接影响,通过[能力实现](../tool-session-query/README.zh.md) 贡献模型上下文和结果。
#### KV Cache 影响
diff --git a/packages/bundle/session-search/cordis.patch.yml b/packages/experimental/session-search/cordis.patch.yml
similarity index 100%
rename from packages/bundle/session-search/cordis.patch.yml
rename to packages/experimental/session-search/cordis.patch.yml
diff --git a/packages/bundle/session-search/icon.svg b/packages/experimental/session-search/icon.svg
similarity index 100%
rename from packages/bundle/session-search/icon.svg
rename to packages/experimental/session-search/icon.svg
diff --git a/packages/bundle/session-search/locale/en.json b/packages/experimental/session-search/locale/en.json
similarity index 100%
rename from packages/bundle/session-search/locale/en.json
rename to packages/experimental/session-search/locale/en.json
diff --git a/packages/bundle/session-search/locale/zh.json b/packages/experimental/session-search/locale/zh.json
similarity index 100%
rename from packages/bundle/session-search/locale/zh.json
rename to packages/experimental/session-search/locale/zh.json
diff --git a/packages/bundle/session-search/package.json b/packages/experimental/session-search/package.json
similarity index 91%
rename from packages/bundle/session-search/package.json
rename to packages/experimental/session-search/package.json
index af1b45db90..e563a02406 100644
--- a/packages/bundle/session-search/package.json
+++ b/packages/experimental/session-search/package.json
@@ -1,5 +1,5 @@
{
- "name": "@deepseek-ai/dsh-session-search",
+ "name": "@deepseek-ai/dsh-experimental-session-search",
"description": "Give Agents tools to search and read earlier sessions from the current workspace.",
"version": "0.2.1-alpha.1",
"icon": "./icon.svg",
@@ -9,7 +9,7 @@
"repository": {
"type": "git",
"url": "git+https://github.com/deepseek-ai/deepseek-harness.git",
- "directory": "packages/bundle/session-search"
+ "directory": "packages/experimental/session-search"
},
"type": "module",
"main": "lib/index.js",
diff --git a/packages/bundle/session-search/src/index.ts b/packages/experimental/session-search/src/index.ts
similarity index 100%
rename from packages/bundle/session-search/src/index.ts
rename to packages/experimental/session-search/src/index.ts
diff --git a/packages/bundle/session-search/tsconfig.json b/packages/experimental/session-search/tsconfig.json
similarity index 100%
rename from packages/bundle/session-search/tsconfig.json
rename to packages/experimental/session-search/tsconfig.json
diff --git a/packages/fs/tool-str-replace-editor/README.i18n.yaml b/packages/fs/tool-str-replace-editor/README.i18n.yaml
index 4e1527febe..7bd12ad505 100644
--- a/packages/fs/tool-str-replace-editor/README.i18n.yaml
+++ b/packages/fs/tool-str-replace-editor/README.i18n.yaml
@@ -15,8 +15,8 @@
en: d152484eb41ac6b4
zh: 09388d293f9be9cb
/deepseek-ai-dsh-tool-str-replace-editor/use-this-package:
- en: 00b16ec00064922b
- zh: 5e0f3e78f1bb4a29
+ en: 549d3ed126a46a99
+ zh: 476e0f61fa5e9ecb
/deepseek-ai-dsh-tool-str-replace-editor/use-this-package/minimal-composition:
en: db6e7d91ff7e0439
zh: 2ed4096f6c856e17
diff --git a/packages/fs/tool-str-replace-editor/README.md b/packages/fs/tool-str-replace-editor/README.md
index 950ad54b57..f1880a5217 100644
--- a/packages/fs/tool-str-replace-editor/README.md
+++ b/packages/fs/tool-str-replace-editor/README.md
@@ -25,6 +25,8 @@ English | [中文](README.zh.md)
## Use this package
+This nonexperimental standalone plugin is intended for custom compositions. It is not offered as an optional bundle in the Plugins page.
+
Mount the tool alongside a `ctx.fs` backend (and, for guarded mutations, the policy plugin) when the model should edit files through the familiar `view`/`create`/`str_replace`/`insert` command vocabulary on absolute paths.
### Minimal composition
diff --git a/packages/fs/tool-str-replace-editor/README.zh.md b/packages/fs/tool-str-replace-editor/README.zh.md
index b1b4bc448e..9c69505356 100644
--- a/packages/fs/tool-str-replace-editor/README.zh.md
+++ b/packages/fs/tool-str-replace-editor/README.zh.md
@@ -25,6 +25,8 @@ kind: "package-reference"
## 使用本包
+此非实验性的独立插件面向自定义组合。Plugins 页面不将它作为可选 bundle 提供。
+
当模型应通过熟悉的 `view`/`create`/`str_replace`/`insert` 命令词汇在绝对路径上编辑文件时,把工具与 `ctx.fs` 后端(以及需要防护变更时的策略插件)一起挂载。
### 最小组合
diff --git a/scripts/optional-bundles.spec.ts b/scripts/optional-bundles.spec.ts
index 9a3888af63..5ad22777de 100644
--- a/scripts/optional-bundles.spec.ts
+++ b/scripts/optional-bundles.spec.ts
@@ -31,9 +31,7 @@ function bundle(name: string): { dir: string; patches: ReturnType {
}
})
- it('ships all seven lightweight bundles without selecting them in a default template', () => {
+ it('ships all five lightweight bundles without selecting them in a default template', () => {
const defaults = Object.values(PROFILE_TEMPLATES).flatMap(template => template.bundles)
for (const name of lightweight) {
expect(OPTIONAL_BUNDLES).toContain(name)
@@ -199,7 +197,7 @@ describe('optional bundles', () => {
const roots = presetRows(composed, id)
const names = flattenRows(roots).map(row => row.name)
for (const name of [
- '@deepseek-ai/dsh-tool-session-query', '@deepseek-ai/dsh-tool-str-replace-editor', '@deepseek-ai/dsh-tmux-context',
+ '@deepseek-ai/dsh-tool-session-query',
'@deepseek-ai/dsh-tool-ralph', '@deepseek-ai/dsh-tool-terminal',
]) expect(names).toContain(name)
expect(roots.find(row => row.id === 'optional-ralph')?.isolate).toEqual({ workflowEngine: true })
diff --git a/scripts/verify-package-readme-model-experience.ts b/scripts/verify-package-readme-model-experience.ts
index f38a18bfba..dd3a6c102b 100644
--- a/scripts/verify-package-readme-model-experience.ts
+++ b/scripts/verify-package-readme-model-experience.ts
@@ -175,9 +175,7 @@ const SENTENCE_MODEL_EXPERIENCE: Readonly> = {
'packages/host/plugin-inventory': { kind: 'none', reason: 'Host-side read-only Loader projection; registers nothing model-facing.' },
'packages/host/open-in-app': { kind: 'none', reason: 'Host routes opening desktop applications for a human; registers nothing model-facing.' },
'packages/client/ui-open-in-app': { kind: 'none', reason: 'Browser-side split button opening the workspace directory for a human; registers nothing model-facing.' },
- 'packages/bundle/session-search': { kind: 'indirect', reason: 'The profile layer delegates model-visible behavior to its selected capability.' },
- 'packages/bundle/string-editor': { kind: 'indirect', reason: 'The profile layer delegates model-visible behavior to its selected capability.' },
- 'packages/bundle/tmux-location': { kind: 'indirect', reason: 'The profile layer delegates model-visible behavior to its selected capability.' },
+ 'packages/experimental/session-search': { kind: 'indirect', reason: 'The profile layer delegates model-visible behavior to its selected capability.' },
'packages/experimental/ralph-bundle': { kind: 'indirect', reason: 'The profile layer delegates model-visible behavior to its selected capability.' },
'packages/experimental/terminal-bundle': { kind: 'indirect', reason: 'The profile layer delegates model-visible behavior to its selected capability.' },
'packages/experimental/badge-skill-bundle': { kind: 'indirect', reason: 'The profile layer delegates model-visible behavior to its selected capability.' },
diff --git a/tsconfig.base.json b/tsconfig.base.json
index a727cb716f..86f3ef50fd 100644
--- a/tsconfig.base.json
+++ b/tsconfig.base.json
@@ -28,9 +28,7 @@
// not declaration path aliases, keep each package/vendor source compiled
// under its own tsconfig boundary.
"paths": {
- "@deepseek-ai/dsh-session-search": ["./packages/bundle/session-search/src/index.ts"],
- "@deepseek-ai/dsh-string-editor": ["./packages/bundle/string-editor/src/index.ts"],
- "@deepseek-ai/dsh-tmux-location": ["./packages/bundle/tmux-location/src/index.ts"],
+ "@deepseek-ai/dsh-experimental-session-search": ["./packages/experimental/session-search/src/index.ts"],
"@deepseek-ai/dsh-experimental-ralph-bundle": ["./packages/experimental/ralph-bundle/src/index.ts"],
"@deepseek-ai/dsh-experimental-terminal-bundle": ["./packages/experimental/terminal-bundle/src/index.ts"],
"@deepseek-ai/dsh-experimental-badge-skill-bundle": ["./packages/experimental/badge-skill-bundle/src/index.ts"],
diff --git a/tsconfig.host.json b/tsconfig.host.json
index eec3f1741a..93241fbe97 100644
--- a/tsconfig.host.json
+++ b/tsconfig.host.json
@@ -118,7 +118,7 @@
"apps/web/tests/conversation-column-overflow.e2e.ts",
"apps/web/tests/ptc-round.e2e.ts",
"apps/web/tests/ptc-escalation.e2e.ts",
- "apps/web/tests/optional-string-editor.e2e.ts",
+ "apps/web/tests/standalone-string-editor.e2e.ts",
"apps/web/tests/present.e2e.ts",
"apps/web/tests/present-svg.e2e.ts",
"apps/web/tests/composer-draft-scroll.e2e.ts",
@@ -217,9 +217,7 @@
"references": [
{ "path": "./packages/experimental/client-ui-cot-translation/tsconfig.host.json" },
{ "path": "./packages/experimental/cot-translation-bundle" },
- { "path": "./packages/bundle/session-search" },
- { "path": "./packages/bundle/string-editor" },
- { "path": "./packages/bundle/tmux-location" },
+ { "path": "./packages/experimental/session-search" },
{ "path": "./packages/experimental/ralph-bundle" },
{ "path": "./packages/experimental/terminal-bundle" },
{ "path": "./packages/experimental/badge-skill-bundle" },