@xiaoso/dsh-tool-plus 0.1.9 → 0.1.10-beta.1

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.
Files changed (40) hide show
  1. package/README.en.md +12 -5
  2. package/README.md +11 -4
  3. package/THIRD_PARTY_NOTICES.md +36 -0
  4. package/lib/client.js +272 -181
  5. package/lib/index.mjs +875 -1081
  6. package/lib/{scrapers-mhvFrvjH.mjs → scrapers-DODCPcZW.mjs} +1 -1
  7. package/lib/types/client/BashPlusCard.d.ts +6 -6
  8. package/lib/types/client/ToolPlusSection.d.ts +3 -3
  9. package/lib/types/client/forms.d.ts +6 -6
  10. package/lib/types/client/index.d.ts +25 -12
  11. package/lib/types/client/locales.d.ts +1 -1
  12. package/lib/types/client/preset-panel.d.ts +54 -42
  13. package/lib/types/config/settings.d.ts +202 -21
  14. package/lib/types/host/browser-probe-rpc.d.ts +2 -1
  15. package/lib/types/host/preset-host.d.ts +103 -0
  16. package/lib/types/host/preset-rpc.d.ts +37 -72
  17. package/lib/types/presets/compare.d.ts +14 -37
  18. package/lib/types/presets/conflicts.d.ts +59 -0
  19. package/lib/types/presets/delta.d.ts +23 -18
  20. package/lib/types/presets/plan.d.ts +55 -0
  21. package/lib/types/presets/rows.d.ts +84 -0
  22. package/lib/types/presets/status.d.ts +56 -47
  23. package/lib/types/tools/bash/background.d.ts +20 -5
  24. package/lib/types/tools/bash/streaming-output.d.ts +4 -2
  25. package/lib/types/tools/shared/browser-rpc-channel.d.ts +84 -42
  26. package/lib/types/web/client/labels.d.ts +1 -1
  27. package/lib/types/web/client/row-utils.d.ts +26 -1
  28. package/lib/{utils-eiUz9n8I.mjs → utils-D80w8vry.mjs} +1 -1
  29. package/package.json +61 -46
  30. package/presets/tool-plus-ptc.patch.yml +164 -0
  31. package/presets/tool-plus-standard.patch.yml +158 -0
  32. package/lib/types/presets/install.d.ts +0 -44
  33. package/lib/types/presets/paths.d.ts +0 -41
  34. package/lib/types/presets/rewrite.d.ts +0 -86
  35. package/presets/install-presets.mjs +0 -143
  36. package/presets/package.json +0 -42
  37. package/presets/tool-plus-ptc/agent.cordis.yml +0 -284
  38. package/presets/tool-plus-ptc/preset.yml +0 -3
  39. package/presets/tool-plus-standard/agent.cordis.yml +0 -269
  40. package/presets/tool-plus-standard/preset.yml +0 -3
@@ -41,80 +41,104 @@ export type RmSafeStatusValue = {
41
41
  /** Endpoint that lists agent presets with their status (roster + conflicts + template diff). */
42
42
  export declare const PRESET_STATUS_ENDPOINT = "presets/status";
43
43
  /**
44
- * The preset ids this plugin ships a template for. Single source of truth for
45
- * both halves: the host uses it for the startup bootstrap and the template
46
- * lookup, the panel uses it to synthesize the "not installed" rows for a
47
- * deployment whose roster does not carry them yet.
44
+ * The preset ids this plugin **declares**. Single source of truth for both
45
+ * halves: the host picks its own declarations out of the profile's composed
46
+ * configuration, and the panel uses the list to tell "ours" from everything else.
47
+ *
48
+ * They ship as `@deepseek-ai/dsh-agent-preset` declaration rows in this
49
+ * package's own bundle patches (`presets/<id>.patch.yml`), so installing the
50
+ * plugin as a profile bundle declares them: no install step, no file copy, and
51
+ * nothing written at startup.
48
52
  */
49
53
  export declare const BUNDLED_PRESET_IDS: readonly string[];
50
- /** Endpoint that applies one preset action to a user-root preset. */
54
+ /** Endpoint that applies one preset action to the active profile. */
51
55
  export declare const PRESET_ACTION_ENDPOINT = "presets/apply";
52
- /** Endpoint that compares one preset against one of our templates (read-only). */
56
+ /** Endpoint that compares one preset against one of our declarations (read-only). */
53
57
  export declare const PRESET_COMPARE_ENDPOINT = "presets/compare";
58
+ /**
59
+ * Loader row id a preset declaration is addressed by. A profile patch overrides
60
+ * a declaration **by this id** — the harness's config editor locates the row by
61
+ * id, and the override replaces the row's whole `config`.
62
+ * @param presetId - The preset identity (the declaration's `config.id`).
63
+ * @returns The row id as it appears in profile patches.
64
+ */
65
+ export declare function profileRowId(presetId: string): string;
54
66
  /** One preset action the settings panel may ask for. */
55
- export type PresetActionValue = 'upgrade' | 'reset';
67
+ export type PresetActionValue = 'upgrade' | 'align' | 'revert';
56
68
  /** Payload of a presets/apply call. */
57
69
  export interface PresetActionPayload {
58
- /** Preset id (a directory name under the user preset root, or a roster id). */
70
+ /** The preset to act on. */
59
71
  id: string;
60
- /** `upgrade` disables conflicting rows only; `reset` overwrites from our template. */
61
- action: PresetActionValue;
62
72
  /**
63
- * Which of our templates `reset` should align this preset to. Absent means
64
- * "the template with the same id" (historical behaviour); the panel always
65
- * sends the template the user picked in the compare picker, so a preset can
66
- * be aligned to a different template than its own.
73
+ * `upgrade` disables the still-mounted official tool rows and nothing else;
74
+ * `align` replaces the whole plugin list with one of our declarations;
75
+ * `revert` removes the profile override so the row falls back to its bundled
76
+ * declaration.
67
77
  */
78
+ action: PresetActionValue;
79
+ /** Required for `align`: which of our declarations to align this preset to. */
68
80
  templateId?: string;
69
81
  }
70
- /** Which layer a preset comes from: our shipped templates, the user root, or the shipped set. */
71
- export type PresetSourceValue = 'ours' | 'user' | 'shipped';
72
- /** One preset change produced by a rewrite. */
82
+ /**
83
+ * Where a preset comes from. dsh 0.1.7 dropped the registry's `trust` and `path`
84
+ * fields, so the only distinction left is "this plugin declared it" versus
85
+ * "something else did" (the shipped set, or another user-installed bundle).
86
+ */
87
+ export type PresetSourceValue = 'ours' | 'other';
88
+ /** One preset change produced by an upgrade. */
73
89
  export interface PresetChangeValue {
74
90
  /** The official tool row id that was handled. */
75
91
  id: string;
76
- /** `disabled` = row had no switch and got one; `flipped` = `disabled: false` -> true; `absent` = nothing to do. */
77
- action: 'disabled' | 'flipped' | 'absent';
92
+ /** `disabled` = the row had no switch and got one; `flipped` = an existing value became `true`. */
93
+ action: 'disabled' | 'flipped';
78
94
  }
79
95
  /** One agent preset as surfaced to the settings panel. */
80
96
  export interface PresetStatusValue {
81
97
  id: string;
98
+ /** Loader row id in the profile patch (`preset-<id>`); absent when this profile has no such row. */
99
+ entryId?: string;
82
100
  name?: string;
83
101
  description?: string;
84
102
  source: PresetSourceValue;
85
- path: string;
86
- /** Official tool rows this preset still mounts (empty = nothing to disable). */
103
+ /** Whether a session naming no preset composes this one. */
104
+ isDefault: boolean;
105
+ /** Official tool rows this preset still mounts enabled (empty = nothing to disable). */
87
106
  conflicts: string[];
88
107
  clean: boolean;
89
- /** Composition could not be parsed as a top-level row list — never rewritten. */
108
+ /** The plugin list is not a readable row list — never rewritten. */
90
109
  unrecognized: boolean;
110
+ /** Why the registry cannot mount this preset, when it reported one. */
91
111
  broken?: string;
92
- /** Whether the preset directory exists in the writable user root. */
93
- installed: boolean;
94
- /** Whether our package ships a template for this id. */
95
- templatePresent: boolean;
96
- /** For template-backed presets: whether the local copy differs from the template. */
112
+ /** The user wrote an override for this row in the profile patch. */
113
+ customized: boolean;
114
+ /** For our own presets: whether the effective content differs from the bundled declaration. */
97
115
  templateDiffers: boolean;
98
116
  /**
99
- * For template-backed presets: *what* differs (so the panel can say it instead
100
- * of the bare "differs", which reads as contradictory next to "nothing to
101
- * adjust"). Absent when there is nothing to compare.
117
+ * For our own presets: *what* differs (so the panel can say it instead of the
118
+ * bare "differs", which reads as contradictory next to "nothing to adjust").
119
+ * Absent when there is nothing to compare.
102
120
  */
103
121
  templateDelta?: PresetDeltaValue;
122
+ /** Rows in the effective plugin list, group children included (scale hint). */
123
+ rowCount: number;
104
124
  }
105
- /** One concrete difference between the local copy and the bundled template. */
125
+ /** One concrete difference between a preset's effective content and a template. */
106
126
  export interface PresetDeltaItemValue {
107
127
  kind: 'changed' | 'only-yours' | 'only-template' | 'row-only-yours' | 'row-only-template';
108
- /** Top-level row id. */
128
+ /**
129
+ * Row path: a top-level row id (`tool-web`), or a group child
130
+ * (`delegation/tool-ralph`). A bare id would point at the wrong row when a
131
+ * nested row shares its id.
132
+ */
109
133
  row: string;
110
134
  /** Dotted path inside that row (e.g. `config.thresholdRatio`); empty for a row-level difference. */
111
135
  path: string;
112
- /** Value in the local copy (`only-template` / `row-only-template` omit it). */
136
+ /** Value in the preset's effective content (`only-template` / `row-only-template` omit it). */
113
137
  yours?: string;
114
138
  /** Value in the template (`only-yours` / `row-only-yours` omit it). */
115
139
  template?: string;
116
140
  }
117
- /** Concrete local-vs-template differences; `items` is capped, `total` is not. */
141
+ /** Concrete preset-vs-template differences; `items` is capped, `total` is not. */
118
142
  export interface PresetDeltaValue {
119
143
  items: PresetDeltaItemValue[];
120
144
  total: number;
@@ -130,31 +154,31 @@ export interface PresetDeltaValue {
130
154
  * @returns True for the "yours" group.
131
155
  */
132
156
  export declare function isYoursDelta(kind: PresetDeltaItemValue['kind']): boolean;
133
- /** One template we ship, as the panel's "compare with" picker needs it. */
157
+ /** One declaration we ship, as the panel's "compare with" picker needs it. */
134
158
  export interface PresetTemplateValue {
135
159
  id: string;
136
160
  name?: string;
137
161
  }
138
162
  /** presets/compare request. */
139
163
  export interface PresetComparePayloadValue {
140
- /** The preset being inspected (any roster id). */
164
+ /** The preset being inspected (any preset in the roster). */
141
165
  presetId: string;
142
- /** The template we ship to compare it against. */
166
+ /** The declaration we ship to compare it against. */
143
167
  templateId: string;
144
168
  }
145
169
  /**
146
170
  * presets/compare result: the full, uncapped comparison between one preset and
147
- * one of our templates. `conflicts` answers "are our tools wired in", `items`
171
+ * one of our declarations. `conflicts` answers "are our tools wired in", `items`
148
172
  * answers "how else does the content differ" (and is what the diff dialog shows).
149
173
  */
150
174
  export interface PresetCompareValue {
151
175
  presetId: string;
152
176
  templateId: string;
153
- /** `unreadable` when either side cannot be read/parsed — nothing to compare. */
177
+ /** `unreadable` when either side cannot be resolved — nothing to compare. */
154
178
  status: 'ok' | 'unreadable';
155
179
  /** Official tool rows still mounted (empty = the plugin's tools are wired in). */
156
180
  conflicts: string[];
157
- /** Content is structurally identical (comments/formatting ignored). */
181
+ /** Content is structurally identical (row order and formatting ignored). */
158
182
  identical: boolean;
159
183
  /** Full-population counts: your own edits vs the template being ahead. */
160
184
  yoursCount: number;
@@ -165,14 +189,32 @@ export interface PresetCompareValue {
165
189
  /** presets/status result. */
166
190
  export interface PresetStatusListValue {
167
191
  presets: PresetStatusValue[];
168
- /** Templates this package ships (the "compare with" picker's options). */
192
+ /** Declarations this package ships (the "compare with" picker's options). */
169
193
  templates: PresetTemplateValue[];
194
+ /**
195
+ * Whether this deployment has an editable profile at all (`ctx.configEditor`
196
+ * is present). Without it the panel can still show state but cannot write.
197
+ */
198
+ writable: boolean;
199
+ /**
200
+ * Absolute path of a legacy `$DSH_HOME/.agent-presets` directory, present only
201
+ * when one still exists and is non-empty. dsh 0.1.7 reads no such directory —
202
+ * it is a cleanup hint for users upgrading from the directory mechanism, not a
203
+ * feature of this deployment.
204
+ */
205
+ legacyPresetRoot?: string;
170
206
  }
171
- /** presets/apply result (mirrors PresetInstallResult from presets/install). */
207
+ /** presets/apply result. */
172
208
  export interface PresetActionResultValue {
173
209
  ok: boolean;
174
210
  changed: boolean;
211
+ /** Why nothing was written, or why the write failed (one line for the panel). */
175
212
  reason?: string;
213
+ /**
214
+ * The `<profile patch>.bak-<version>` copy taken before this write, when the
215
+ * patch already existed. One backup per profile, written once and never
216
+ * overwritten, so it always holds the earliest pre-change state.
217
+ */
176
218
  backupPath?: string;
177
219
  changes: PresetChangeValue[];
178
220
  }
@@ -17,7 +17,7 @@
17
17
  /** Locale namespace of the tool-card bundle (registered by `registerToolCards`). */
18
18
  export declare const CARD_LOCALE_NS = "tool-plus-cards";
19
19
  /** Every copy key of the tool-card namespace. */
20
- export type ToolCardLocaleKey = 'copy' | 'copied' | 'collapse' | 'expand' | 'collapseAria' | 'expandAria' | 'expandRest' | 'files.one' | 'files.other' | 'running' | 'done' | 'failed' | 'stopped' | 'cancelled' | 'timedOut' | 'noOutput' | 'title.bash' | 'title.read' | 'title.write' | 'title.edit' | 'title.grep' | 'title.glob' | 'title.astGrep' | 'title.astEdit' | 'write.lines' | 'write.madeExecutable' | 'astEdit.replacements' | 'astEdit.files' | 'astEdit.parseErrors' | 'astEdit.rules' | 'astEdit.rulesRest' | 'read.window' | 'read.collapseAria' | 'read.expandAria' | 'read.expandRest' | 'search.paths' | 'search.paths.truncated' | 'search.matches' | 'search.matches.truncated' | 'search.noResults' | 'search.scope' | 'search.collapseAria' | 'search.expandAria' | 'search.expandRest' | 'terminal.signal' | 'terminal.exitCode' | 'terminal.running' | 'terminal.failed' | 'terminal.done' | 'terminal.noOutput' | 'bash.background' | 'image.loading' | 'image.loadFailed' | 'image.open' | 'image.openNamed' | 'image.dialog' | 'image.close' | 'image.unnamed' | 'image.caption' | 'generic.params' | 'generic.noDetail' | 'inspect';
20
+ export type ToolCardLocaleKey = 'copy' | 'copied' | 'collapse' | 'expand' | 'collapseAria' | 'expandAria' | 'expandRest' | 'files.one' | 'files.other' | 'codeBlock.title' | 'codeBlock.wrap' | 'codeBlock.unwrap' | 'running' | 'done' | 'failed' | 'stopped' | 'cancelled' | 'timedOut' | 'noOutput' | 'title.bash' | 'title.read' | 'title.write' | 'title.edit' | 'title.grep' | 'title.glob' | 'title.astGrep' | 'title.astEdit' | 'write.lines' | 'write.madeExecutable' | 'astEdit.replacements' | 'astEdit.files' | 'astEdit.parseErrors' | 'astEdit.rules' | 'astEdit.rulesRest' | 'read.window' | 'read.collapseAria' | 'read.expandAria' | 'read.expandRest' | 'search.paths' | 'search.paths.truncated' | 'search.matches' | 'search.matches.truncated' | 'search.noResults' | 'search.scope' | 'search.collapseAria' | 'search.expandAria' | 'search.expandRest' | 'terminal.signal' | 'terminal.exitCode' | 'terminal.running' | 'terminal.failed' | 'terminal.done' | 'terminal.noOutput' | 'terminal.noExitCode' | 'bash.background' | 'image.loading' | 'image.loadFailed' | 'image.open' | 'image.openNamed' | 'image.dialog' | 'image.close' | 'image.unnamed' | 'image.caption' | 'generic.params' | 'generic.noDetail' | 'inspect';
21
21
  /** Simplified Chinese copy (the source dictionary). */
22
22
  export declare const zh: Record<ToolCardLocaleKey, string>;
23
23
  /** English dictionary, checked complete against the zh key set. */
@@ -14,7 +14,7 @@
14
14
  * nothing here touches a raw `meta` field directly.
15
15
  * @module @xiaoso/dsh-tool-plus/web/client/row-utils
16
16
  */
17
- import type { DiffBlockLabels, ReadBlockLabels, SearchBlockLabels, TerminalBlockLabels } from '@deepseek-ai/dsh-client-ui-primitives';
17
+ import type { CodeToolbarLabels, DiffBlockLabels, ReadBlockLabels, SearchBlockLabels, TerminalBlockLabels } from '@deepseek-ai/dsh-client-ui-primitives';
18
18
  import type { TranslateNS } from '@deepseek-ai/dsh-client-ui-slots';
19
19
  import type { CARD_LOCALE_NS, ToolCardLocaleKey } from './labels.ts';
20
20
  /** Translate seat of this plugin's card namespace. */
@@ -48,6 +48,20 @@ export interface CardBlockView {
48
48
  export type CardState = 'running' | 'ok' | 'error' | 'warning';
49
49
  /** Whether a block is the settled half of a call pair. */
50
50
  export declare function isSettled(block: CardBlockView): boolean;
51
+ /**
52
+ * Whether a call already landed as a failed result.
53
+ *
54
+ * Only a settled result can be wrong about its work: the union's error state is
55
+ * `ToolResultNode.isError` alone, and the shipped row model reads it the same
56
+ * way — settle on the `kind` discriminant (`'kind' in block`) and only then look
57
+ * at `error`, `isError`. A preparing or dispatched call has no result yet, so it
58
+ * is never an error; the rows that fall back to the generic shell keep exactly
59
+ * the criterion they have always had (`isError === true`), stated where the
60
+ * union still allows it.
61
+ * @param block - the frozen running-or-settled call node.
62
+ * @returns whether the call settled as a failure.
63
+ */
64
+ export declare function isErrorResult(block: CardBlockView): boolean;
51
65
  /**
52
66
  * The call's original argument text.
53
67
  *
@@ -187,6 +201,17 @@ export interface ShellStatus {
187
201
  * @returns the marker-free output and the facts the markers named.
188
202
  */
189
203
  export declare function parseShellStatus(text: string): ShellStatus;
204
+ /**
205
+ * Bind the card dictionary to the shared code-card toolbar labels.
206
+ *
207
+ * The toolbar rides every code surface the primitives draw (the diff block, the
208
+ * read block), and the host's own adapter for it reads the base locale's
209
+ * `codeBlock.*` wording; this dictionary carries the same three strings, so a
210
+ * takeover's code cards read exactly as the shipped ones do.
211
+ * @param t - the card translate seat.
212
+ * @returns the language fallback and wrapping actions.
213
+ */
214
+ export declare function codeToolbarLabels(t: CardTranslate): CodeToolbarLabels;
190
215
  /** Bind the card dictionary to the diff primitive's chrome labels. */
191
216
  export declare function diffBlockLabels(t: CardTranslate): DiffBlockLabels;
192
217
  /** Bind the card dictionary to the read primitive's chrome labels. */
@@ -6267,7 +6267,7 @@ const settings = {
6267
6267
  };
6268
6268
  //#endregion
6269
6269
  //#region package.json
6270
- var version = "0.1.9";
6270
+ var version = "0.1.10";
6271
6271
  /** `.tmp` files older than this are treated as orphaned writes and swept. */
6272
6272
  const TMP_ORPHAN_MAX_AGE_MS = 3e5;
6273
6273
  function markitConversionCacheKey(bytes, extension) {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@xiaoso/dsh-tool-plus",
3
3
  "description": "Oh My Pi bash runtime ported as a deepseek-harness tool plugin: persistent shell session, output minimizer, managed background jobs, command interception",
4
- "version": "0.1.9",
4
+ "version": "0.1.10-beta.1",
5
5
  "license": "MIT",
6
6
  "keywords": [
7
7
  "deepseek-harness",
@@ -46,21 +46,29 @@
46
46
  "types": "./lib/types/client/index.d.ts",
47
47
  "default": "./lib/client.js"
48
48
  },
49
+ "./cordis.patch.yml": "./cordis.patch.yml",
50
+ "./presets/*.patch.yml": "./presets/*.patch.yml",
49
51
  "./package.json": "./package.json"
50
52
  },
51
53
  "files": [
52
54
  "lib",
53
- "presets",
55
+ "cordis.patch.yml",
56
+ "presets/tool-plus-standard.patch.yml",
57
+ "presets/tool-plus-ptc.patch.yml",
54
58
  "scripts/patch-pi-natives.mjs",
55
59
  "src/bash-runtime/shell-snapshot-fn-env.sh",
56
- "cordis.patch.yml",
57
60
  "README.md",
58
61
  "LICENSE",
59
62
  "THIRD_PARTY_NOTICES.md"
60
63
  ],
61
64
  "dsh": {
65
+ "manifestVersion": 1,
62
66
  "bundle": {
63
- "patch": "./cordis.patch.yml"
67
+ "patch": [
68
+ "./cordis.patch.yml",
69
+ "./presets/tool-plus-standard.patch.yml",
70
+ "./presets/tool-plus-ptc.patch.yml"
71
+ ]
64
72
  },
65
73
  "client": {
66
74
  "inject": [
@@ -74,33 +82,35 @@
74
82
  "build": "tsdown -c tsdown.config.ts && tsc -p tsconfig.json && node scripts/copy-assets.mjs",
75
83
  "typecheck": "tsc -p tsconfig.json --noEmit",
76
84
  "test": "vitest run --config vitest.config.ts",
77
- "presets:install": "node presets/install-presets.mjs",
78
- "presets:install:force": "node presets/install-presets.mjs --force",
85
+ "presets:build": "node scripts/build-preset-patches.mjs",
86
+ "presets:check": "node scripts/build-preset-patches.mjs --check",
79
87
  "postinstall": "node scripts/patch-pi-natives.mjs"
80
88
  },
81
89
  "peerDependencies": {
82
- "@deepseek-ai/cordis": "4.0.2",
83
- "@deepseek-ai/dsh-agent": "0.1.5-rc.1",
84
- "@deepseek-ai/dsh-attachment": "0.1.5-rc.1",
85
- "@deepseek-ai/dsh-client-connection": "0.1.5-rc.1",
86
- "@deepseek-ai/dsh-fs": "0.1.5-rc.1",
87
- "@deepseek-ai/dsh-jobs": "0.1.5-rc.1",
88
- "@deepseek-ai/dsh-llm": "0.1.5-rc.1",
89
- "@deepseek-ai/dsh-sandbox": "0.1.5-rc.1",
90
- "@deepseek-ai/dsh-session": "0.1.5-rc.1",
91
- "@deepseek-ai/dsh-settings": "0.1.5-rc.1",
92
- "@deepseek-ai/dsh-shell": "0.1.5-rc.1",
93
- "@deepseek-ai/dsh-shell-env": "0.1.5-rc.1",
94
- "@deepseek-ai/dsh-system-prompt": "0.1.5-rc.1",
95
- "@deepseek-ai/dsh-tools": "0.1.5-rc.1"
90
+ "@deepseek-ai/cordis": "~4.0.4",
91
+ "@deepseek-ai/dsh-agent": "0.1.7-rc.2",
92
+ "@deepseek-ai/dsh-agent-preset": "0.1.7-rc.2",
93
+ "@deepseek-ai/dsh-agent-preset-registry": "0.1.7-rc.2",
94
+ "@deepseek-ai/dsh-attachment": "0.1.7-rc.2",
95
+ "@deepseek-ai/dsh-client-connection": "0.1.7-rc.2",
96
+ "@deepseek-ai/dsh-fs": "0.1.7-rc.2",
97
+ "@deepseek-ai/dsh-jobs": "0.1.7-rc.2",
98
+ "@deepseek-ai/dsh-llm": "0.1.7-rc.2",
99
+ "@deepseek-ai/dsh-sandbox": "0.1.7-rc.2",
100
+ "@deepseek-ai/dsh-session": "0.1.7-rc.2",
101
+ "@deepseek-ai/dsh-settings": "0.1.7-rc.2",
102
+ "@deepseek-ai/dsh-shell": "0.1.7-rc.2",
103
+ "@deepseek-ai/dsh-shell-env": "0.1.7-rc.2",
104
+ "@deepseek-ai/dsh-system-prompt": "0.1.7-rc.2",
105
+ "@deepseek-ai/dsh-tools": "0.1.7-rc.2"
96
106
  },
97
107
  "optionalPeerDependencies": {
98
108
  "sharp": ">=0.33"
99
109
  },
100
110
  "dependencies": {
101
- "@deepseek-ai/dsh-brand": "0.1.5-rc.1",
102
- "@deepseek-ai/dsh-invariants": "0.1.5-rc.1",
103
- "@deepseek-ai/schemastery": "3.18.2",
111
+ "@deepseek-ai/dsh-brand": "0.1.7-rc.2",
112
+ "@deepseek-ai/dsh-invariants": "0.1.7-rc.2",
113
+ "@deepseek-ai/schemastery": "~3.18.4",
104
114
  "@oh-my-pi/omptype": "18.1.17",
105
115
  "@oh-my-pi/pi-agent-core": "18.1.17",
106
116
  "@oh-my-pi/pi-ai": "18.1.17",
@@ -114,29 +124,34 @@
114
124
  "yaml": "^2.9.0"
115
125
  },
116
126
  "devDependencies": {
117
- "@deepseek-ai/cordis": "4.0.2",
118
- "@deepseek-ai/dsh-agent": "0.1.5-rc.1",
119
- "@deepseek-ai/dsh-client-connection": "0.1.5-rc.1",
120
- "@deepseek-ai/dsh-client-locale": "0.1.5-rc.1",
121
- "@deepseek-ai/dsh-client-ui-chat": "0.1.5-rc.1",
122
- "@deepseek-ai/dsh-client-ui-primitives": "0.1.5-rc.1",
123
- "@deepseek-ai/dsh-client-ui-renderer": "0.1.5-rc.1",
124
- "@deepseek-ai/dsh-client-ui-settings": "0.1.5-rc.1",
125
- "@deepseek-ai/dsh-client-ui-settings-plugins": "0.1.5-rc.1",
126
- "@deepseek-ai/dsh-client-ui-slots": "0.1.5-rc.1",
127
- "@deepseek-ai/dsh-client-ui-tool": "0.1.5-rc.1",
128
- "@deepseek-ai/dsh-fs-local": "0.1.5-rc.1",
129
- "@deepseek-ai/dsh-jobs": "0.1.5-rc.1",
130
- "@deepseek-ai/dsh-jobs-local": "0.1.5-rc.1",
131
- "@deepseek-ai/dsh-llm": "0.1.5-rc.1",
132
- "@deepseek-ai/dsh-session": "0.1.5-rc.1",
133
- "@deepseek-ai/dsh-settings": "0.1.5-rc.1",
134
- "@deepseek-ai/dsh-shell": "0.1.5-rc.1",
135
- "@deepseek-ai/dsh-shell-env": "0.1.5-rc.1",
136
- "@deepseek-ai/dsh-system-prompt": "0.1.5-rc.1",
137
- "@deepseek-ai/dsh-tool-jobs": "0.1.5-rc.1",
138
- "@deepseek-ai/dsh-tool-str-replace-editor": "0.1.5-rc.1",
139
- "@deepseek-ai/dsh-tools": "0.1.5-rc.1",
127
+ "@deepseek-ai/cordis": "~4.0.4",
128
+ "@deepseek-ai/dsh-agent": "0.1.7-rc.2",
129
+ "@deepseek-ai/dsh-api-remotes": "0.1.7-rc.2",
130
+ "@deepseek-ai/dsh-api-session-controller": "0.1.7-rc.2",
131
+ "@deepseek-ai/dsh-client-connection": "0.1.7-rc.2",
132
+ "@deepseek-ai/dsh-client-store": "0.1.7-rc.2",
133
+ "@deepseek-ai/dsh-client-ui-conversation": "0.1.7-rc.2",
134
+ "@deepseek-ai/dsh-token-meter": "0.1.7-rc.2",
135
+ "@deepseek-ai/dsh-client-locale": "0.1.7-rc.2",
136
+ "@deepseek-ai/dsh-client-ui-chat": "0.1.7-rc.2",
137
+ "@deepseek-ai/dsh-client-ui-primitives": "0.1.7-rc.2",
138
+ "@deepseek-ai/dsh-client-ui-renderer": "0.1.7-rc.2",
139
+ "@deepseek-ai/dsh-client-ui-settings": "0.1.7-rc.2",
140
+ "@deepseek-ai/dsh-client-ui-settings-plugins": "0.1.7-rc.2",
141
+ "@deepseek-ai/dsh-client-ui-slots": "0.1.7-rc.2",
142
+ "@deepseek-ai/dsh-client-ui-tool": "0.1.7-rc.2",
143
+ "@deepseek-ai/dsh-fs-local": "0.1.7-rc.2",
144
+ "@deepseek-ai/dsh-jobs": "0.1.7-rc.2",
145
+ "@deepseek-ai/dsh-jobs-local": "0.1.7-rc.2",
146
+ "@deepseek-ai/dsh-llm": "0.1.7-rc.2",
147
+ "@deepseek-ai/dsh-session": "0.1.7-rc.2",
148
+ "@deepseek-ai/dsh-settings": "0.1.7-rc.2",
149
+ "@deepseek-ai/dsh-shell": "0.1.7-rc.2",
150
+ "@deepseek-ai/dsh-shell-env": "0.1.7-rc.2",
151
+ "@deepseek-ai/dsh-system-prompt": "0.1.7-rc.2",
152
+ "@deepseek-ai/dsh-tool-jobs": "0.1.7-rc.2",
153
+ "@deepseek-ai/dsh-tool-str-replace-editor": "0.1.7-rc.2",
154
+ "@deepseek-ai/dsh-tools": "0.1.7-rc.2",
140
155
  "@types/node": "^22.19.0",
141
156
  "@types/react": "^19.0.0",
142
157
  "@types/react-dom": "^19.0.0",
@@ -0,0 +1,164 @@
1
+ # Agent preset `tool-plus-ptc` — declared as one `@deepseek-ai/dsh-agent-preset` row.
2
+ #
3
+ # GENERATED by scripts/build-preset-patches.mjs from
4
+ # presets/baseline/ptc.patch.yml (the shipped `ptc` composition of the dsh
5
+ # release this plugin pins). Do not edit by hand: the generator is what keeps
6
+ # our delta honest across dsh upgrades, and tests/unit/preset-patches.spec.ts
7
+ # fails when this file and the generator disagree.
8
+ #
9
+ # Delta over the baseline:
10
+ # - tool-bash, tool-fs, tool-fs-search are removed — the host plane already serves them
11
+ # through this plugin's `cordis.patch.yml`, and mounting them again in the
12
+ # agent plane would create a per-session shadow instance
13
+ # - tool-pwsh is forced `disabled: true` (neither Tool Plus preset enables pwsh)
14
+ # - an inert `tool-plus` row documents where an agent-plane plugin row would go
15
+ # - everything else is the baseline, byte-equivalent
16
+ #
17
+ # A profile patch overriding this row BY THE ROW ID BELOW replaces the whole
18
+ # `config`, so an override must restate `id`, `name`, `description`, `order` and
19
+ # `plugins`. That is what `@xiaoso/dsh-tool-plus`'s settings panel writes.
20
+ - insert:
21
+ - id: preset-tool-plus-ptc
22
+ name: '@deepseek-ai/dsh-agent-preset'
23
+ config:
24
+ id: tool-plus-ptc
25
+ name: Tool Plus PTC 增强版
26
+ description: PTC 模式全部能力 + tool-plus 增强:文件/Shell 工具集替换为 @xiaoso/dsh-tool-plus(移植 oh-my-pi:read 单参数 file_path 内联行选择器、edit 三模式、bash/grep/glob),经 Code Mode SDK 以 run_code 组合多步操作;pwsh 默认禁用。
27
+ order: 21
28
+ plugins:
29
+ - id: persona
30
+ name: '@deepseek-ai/dsh-persona'
31
+ config:
32
+ suffix: Your working directory is {{cwd}}.
33
+ prefix: You are a coding agent powered by the {{model}} model.
34
+ - id: agent-instructions
35
+ name: '@deepseek-ai/dsh-agent-instructions'
36
+ config:
37
+ maxBytes: 65536
38
+ - id: tool-plus
39
+ name: '@xiaoso/dsh-tool-plus'
40
+ disabled: true
41
+ - id: tool-pwsh
42
+ name: '@deepseek-ai/dsh-tool-pwsh'
43
+ disabled: true
44
+ - id: tool-jobs
45
+ name: '@deepseek-ai/dsh-tool-jobs'
46
+ - id: skill-filesystem
47
+ name: '@deepseek-ai/dsh-skill-filesystem'
48
+ - id: tool-skill
49
+ name: '@deepseek-ai/dsh-tool-skill'
50
+ - id: command-goal
51
+ name: '@deepseek-ai/dsh-command-goal'
52
+ - id: tool-goal
53
+ name: '@deepseek-ai/dsh-tool-goal'
54
+ - id: planning
55
+ name: cordis:group
56
+ group: true
57
+ isolate:
58
+ planMode: true
59
+ config:
60
+ - id: plan-mode
61
+ name: '@deepseek-ai/dsh-plan-mode'
62
+ config:
63
+ section: |
64
+ You are in plan mode. Stay in plan mode until exit_plan_mode succeeds or the user switches the session mode. Imperative language to implement changes means plan the implementation, not execute it. A user's conversational agreement — including an answer confirming something you asked — approves nothing and does not end plan mode; fold the confirmed decision into the plan and submit it through exit_plan_mode.
65
+
66
+ Explore first. Use non-mutating reads, searches, static analysis, and checks to ground the plan in the actual repository. Do not edit or write files, change configuration, run formatters or code generation that rewrites tracked files, commit, or otherwise carry out the plan. Prefer existing functions and patterns over new machinery.
67
+
68
+ The tool catalog stays the same across modes for request-cache stability. These plan-mode rules override any later tool description or guidance that suggests using mutation tools; those tools remain listed to keep the tool catalog unchanged. Do not use todo_write to track this planning phase: it tracks implementation after an approved plan, while the plan itself belongs in exit_plan_mode.
69
+
70
+ Resolve discoverable facts by inspection. Use ask_user_question only for user-owned choices or material ambiguity that inspection cannot answer. Do not ask the user where code lives or how current behavior works when you can find out.
71
+
72
+ Make the plan decision-complete: state the goal and success criteria; group implementation changes by subsystem; identify public API, schema, and data-flow changes; cover edge cases, failure modes, tests, acceptance criteria, and explicit assumptions. Keep it concise enough to review but detailed enough that another engineer can implement it without making design decisions.
73
+
74
+ When ready, call exit_plan_mode with the complete plan markdown, starting with a # title. Make exit_plan_mode the only and final tool call in that assistant response: it presents the plan for approval, and implementation begins only in a later step after approval. Do not paste the final plan as a plain reply or ask "should I proceed?" through prose or ask_user_question. If review rejects it, incorporate the feedback and present again. If the review channel is unavailable or aborted, stay in plan mode and ask the user to switch modes manually; do not proceed with implementation.
75
+ - id: compaction
76
+ name: cordis:group
77
+ group: true
78
+ isolate:
79
+ compaction: true
80
+ toolResultPruner: true
81
+ config:
82
+ - id: compaction-basic
83
+ name: '@deepseek-ai/dsh-compaction-basic'
84
+ - id: command-compact
85
+ name: '@deepseek-ai/dsh-command-compact'
86
+ - id: tool-result-pruner
87
+ name: '@deepseek-ai/dsh-compaction-tool-result-pruner'
88
+ config:
89
+ thresholdChars: 8192
90
+ headChars: 4096
91
+ tailChars: 1024
92
+ - id: delegation
93
+ name: cordis:group
94
+ group: true
95
+ isolate:
96
+ workflowEngine: true
97
+ config:
98
+ - id: tool-subagent-control
99
+ name: '@deepseek-ai/dsh-tool-subagent-control'
100
+ - id: tool-subagent-list-agents
101
+ name: '@deepseek-ai/dsh-tool-subagent-control/list-agents'
102
+ - id: tool-subagent
103
+ name: '@deepseek-ai/dsh-tool-subagent'
104
+ config:
105
+ provider: spawn
106
+ toolName: subagent
107
+ modelSelectionSettings: true
108
+ backgroundMode: continuable
109
+ - id: tool-subagent-fork
110
+ name: '@deepseek-ai/dsh-tool-subagent'
111
+ config:
112
+ provider: fork
113
+ toolName: subagent_fork
114
+ backgroundMode: continuable
115
+ - id: tool-subagent-codex
116
+ name: '@deepseek-ai/dsh-tool-subagent'
117
+ disabled: true
118
+ config:
119
+ provider: codex
120
+ toolName: subagent_codex
121
+ backgroundMode: one-shot
122
+ maxDepth: provider-managed
123
+ - id: tool-subagent-claude-code
124
+ name: '@deepseek-ai/dsh-tool-subagent'
125
+ disabled: true
126
+ config:
127
+ provider: claude-code
128
+ toolName: subagent_claude_code
129
+ backgroundMode: one-shot
130
+ maxDepth: provider-managed
131
+ - id: workflow-ptc
132
+ name: '@deepseek-ai/dsh-workflow-ptc'
133
+ disabled: true
134
+ config:
135
+ provider: spawn
136
+ - id: tool-workflow
137
+ name: '@deepseek-ai/dsh-tool-workflow'
138
+ disabled: true
139
+ - id: tool-ralph
140
+ name: '@deepseek-ai/dsh-tool-ralph'
141
+ disabled: true
142
+ config:
143
+ subagentProvider: spawn
144
+ maxRounds: 64
145
+ - id: tool-ask-user
146
+ name: '@deepseek-ai/dsh-tool-ask-user'
147
+ - id: tool-todo
148
+ name: '@deepseek-ai/dsh-tool-todo'
149
+ config:
150
+ allowParallelInProgress: true
151
+ - id: tool-web
152
+ name: '@deepseek-ai/dsh-tool-web'
153
+ config:
154
+ fetch: true
155
+ searchTimeoutMs: 60000
156
+ - id: tool-presentation
157
+ name: '@deepseek-ai/dsh-agent-tool-presentation'
158
+ config:
159
+ mode: ptc
160
+ - id: present
161
+ name: '@deepseek-ai/dsh-tool-present'
162
+ - id: tool-plugin-manager
163
+ name: '@deepseek-ai/dsh-plugin-manager/tools'
164
+ disabled: true