codsh-bundle 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 codsh contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,10 @@
1
+ # codsh-bundle
2
+
3
+ The [codsh](https://github.com/Blackman99/codsh) runtime: the interactive TTY surface and the `code-cli` agent preset, packaged as a dsh bundle. It is installed **into dsh profiles**, not globally — either by the [`codsh-cli`](https://www.npmjs.com/package/codsh-cli) launcher on first run, or directly:
4
+
5
+ ```sh
6
+ dsh plugin --profile code add codsh-bundle
7
+ dsh --profile code
8
+ ```
9
+
10
+ Full documentation: [github.com/Blackman99/codsh](https://github.com/Blackman99/codsh)
@@ -0,0 +1,322 @@
1
+ # The `code-cli` agent preset: the `standard` coding agent plus the capabilities a
2
+ # terminal surface needs — persistent terminal sessions, optional LSP code
3
+ # navigation, and web fetch.
4
+ #
5
+ # This file is an AGENT-PLANE composition. The roster mounts it ONCE under a
6
+ # standing scope; every session naming it joins by scope parentage, so the
7
+ # tools and prompt sections registered here cover each joined agent while a
8
+ # session's own state stays keyed per Session/Agent inside the plugins. The
9
+ # host composition (`base.cordis.yml` + the `dsh-coding-cli` bundle patch) keeps
10
+ # everything a preset must not own: the registries themselves, the sandbox and
11
+ # approval stack, persistence, and the model route.
12
+ #
13
+ # A service row here MUST sit inside a group carrying an `isolate` realm.
14
+ # Without one it publishes into the root realm, where it is process-global —
15
+ # another preset publishing the same name collides, and a host reader would
16
+ # resolve one preset's instance for every session; `dsh-agent-presets` rejects
17
+ # that at mount. `true` means an entry-local realm: this standing mount's own
18
+ # private instance, apart from every other preset's. (A shared label does NOT
19
+ # pool instances — `provide()` throws on the second registration under the
20
+ # same realm symbol; labels join REALMS, and are not what this file needs.)
21
+ #
22
+ # The `app:cli-surface` prompt section that orients the model to the terminal
23
+ # belongs to the `dsh-coding-cli` bundle, not here: it describes the surface
24
+ # that booted the process, and every preset a terminal session mounts needs it.
25
+
26
+ # ── identity ────────────────────────────────────────────────────────────────
27
+
28
+ # The preset's own persona, shadowing the deployment default for this agent.
29
+ # `{{model}}` and `{{cwd}}` resolve from the agent's own route and workspace.
30
+ - id: persona
31
+ name: '@deepseek-ai/dsh-persona'
32
+ config:
33
+ text: >-
34
+ You are a coding agent powered by the {{model}} model. Your working directory is {{cwd}}.
35
+
36
+ - id: agent-instructions
37
+ name: '@deepseek-ai/dsh-agent-instructions'
38
+ config:
39
+ maxBytes: 65536
40
+
41
+ # ── shell ───────────────────────────────────────────────────────────────────
42
+
43
+ # `shell-env` stays in the HOST composition: a host row that injects a service is
44
+ # the criterion for host-plane ownership — injection resolves before any session
45
+ # exists, so there is no agent to key by. Both shell tools consume the host
46
+ # registry from here; their executors (`bash-sandbox`/`pwsh-sandbox`) are
47
+ # host-plane too.
48
+ - id: tool-bash
49
+ name: '@deepseek-ai/dsh-tool-bash'
50
+ disabled: !!js process.platform === 'win32'
51
+
52
+ - id: tool-pwsh
53
+ name: '@deepseek-ai/dsh-tool-pwsh'
54
+ disabled: !!js process.platform !== 'win32'
55
+
56
+ # ── persistent terminals ────────────────────────────────────────────────────
57
+
58
+ # `terminals` is an agent-owned registry, so it lives in an entry-local realm;
59
+ # the backend still consumes the host sandbox policy and subprocess
60
+ # implementation. A terminal outlives one tool call, which is what separates it
61
+ # from `tool-bash`: the agent starts a dev server, a watcher, or a REPL and
62
+ # reads from it across turns instead of blocking a call until the process exits.
63
+ #
64
+ # `dsh-terminal-bash` is the only shipped backend, so the whole group is off on
65
+ # Windows — `tool-terminal` without a backend would answer every `terminal_open`
66
+ # with an unavailable registry rather than a missing tool.
67
+ - id: terminals
68
+ name: cordis:group
69
+ group: true
70
+ disabled: !!js process.platform === 'win32'
71
+ isolate:
72
+ terminals: true
73
+ config:
74
+ - id: pty
75
+ name: '@deepseek-ai/dsh-terminal'
76
+
77
+ - id: terminal-bash
78
+ name: '@deepseek-ai/dsh-terminal-bash'
79
+ config:
80
+ timeoutMs: 300000
81
+
82
+ - id: tool-terminal
83
+ name: '@deepseek-ai/dsh-tool-terminal'
84
+
85
+ # ── code navigation ─────────────────────────────────────────────────────────
86
+
87
+ # `lsp` is an agent-owned provider registry, so it and its stdio provider share
88
+ # one entry-local realm with the tool that reads them.
89
+ #
90
+ # The group is off by default because `lsp-stdio` spawns `command` from the host
91
+ # PATH: enabling it on a machine without that binary turns every `lsp` call into
92
+ # a spawn failure. Install the server, then delete the `disabled` line below.
93
+ # The `servers` table maps stable provider ids to independent local servers, and
94
+ # each provider reserves its `extensionToLanguage` extensions exclusively.
95
+ - id: code-navigation
96
+ name: cordis:group
97
+ group: true
98
+ disabled: true
99
+ isolate:
100
+ lsp: true
101
+ config:
102
+ - id: lsp
103
+ name: '@deepseek-ai/dsh-lsp'
104
+
105
+ - id: lsp-stdio
106
+ name: '@deepseek-ai/dsh-lsp-stdio'
107
+ config:
108
+ servers:
109
+ typescript:
110
+ command: typescript-language-server
111
+ args: ['--stdio']
112
+ extensionToLanguage:
113
+ .ts: typescript
114
+ .tsx: typescriptreact
115
+ .mts: typescript
116
+ .cts: typescript
117
+ .js: javascript
118
+ .jsx: javascriptreact
119
+ .mjs: javascript
120
+ .cjs: javascript
121
+
122
+ - id: tool-lsp
123
+ name: '@deepseek-ai/dsh-tool-lsp'
124
+
125
+ # ── filesystem ──────────────────────────────────────────────────────────────
126
+
127
+ # Both register into the host `tools` registry and provide nothing, so
128
+ # they need no realm. The `fs` service and its policy stay in the host.
129
+ - id: tool-fs
130
+ name: '@deepseek-ai/dsh-tool-fs'
131
+
132
+ - id: tool-fs-search
133
+ name: '@deepseek-ai/dsh-tool-fs-search'
134
+ config:
135
+ sampleOverCapGlobResults: false
136
+
137
+ # ── background jobs ────────────────────────────────────────────────────────
138
+
139
+ # Only the model-facing controls. The task REGISTRY stays on the host plane:
140
+ # its producers sit outside any realm this file could put it in — `tool-bash`
141
+ # above resolves it with `ctx.get`, and an entry-local realm here is invisible
142
+ # to every sibling row, so `run_in_background` would answer "background jobs
143
+ # unavailable" while these controls sat in the catalog. The registry is keyed by
144
+ # owning agent anyway, so one host instance serves every session. What a preset
145
+ # chooses is whether its agent can collect and stop background work at all.
146
+ - id: tool-jobs
147
+ name: '@deepseek-ai/dsh-tool-jobs'
148
+
149
+ # ── skills ──────────────────────────────────────────────────────────────────
150
+
151
+ # The skill REGISTRY lives in the host composition and is layered per scope:
152
+ # these rows register into THIS preset's layer of it, so they need no realm.
153
+ # `skill-filesystem` contributes local-root discovery for agents on this preset, and
154
+ # `tool-skill` gives them the catalog and loader; the merged catalog also
155
+ # carries whatever the deployment registered globally (repository plugins).
156
+ - id: skill-filesystem
157
+ name: '@deepseek-ai/dsh-skill-filesystem'
158
+
159
+ - id: tool-skill
160
+ name: '@deepseek-ai/dsh-tool-skill'
161
+
162
+ # ── goals ───────────────────────────────────────────────────────────────────
163
+
164
+ # Only the model-facing tool. The goal SERVICE and its session driver stay on
165
+ # the host plane; the registry is keyed by session anyway, so one host instance
166
+ # serves every session. What a preset chooses is whether its agent can call the
167
+ # goal tool.
168
+ - id: tool-goal
169
+ name: '@deepseek-ai/dsh-tool-goal'
170
+
171
+ # ── plan mode ───────────────────────────────────────────────────────────────
172
+
173
+ # Plan state is per-agent by nature, so an entry-local realm is not a
174
+ # workaround here — it is the correct lifetime.
175
+ - id: planning
176
+ name: cordis:group
177
+ group: true
178
+ isolate:
179
+ planMode: true
180
+ config:
181
+ - id: plan-mode
182
+ name: '@deepseek-ai/dsh-plan-mode'
183
+ config:
184
+ section: |
185
+ 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.
186
+
187
+ 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.
188
+
189
+ 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.
190
+
191
+ 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.
192
+
193
+ 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.
194
+
195
+ 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.
196
+
197
+ # ── compaction ──────────────────────────────────────────────────────────────
198
+
199
+ # `compaction-basic` reads `toolResultPrune` through `ctx.get`, so the pruner must
200
+ # share this realm rather than sit outside it.
201
+ #
202
+ # `tokenMeter` is deliberately NOT in this realm: the meter stays on the HOST
203
+ # plane, and the rows here resolve that one instance. It takes no configuration,
204
+ # keys every fold by Session, and owns the context-meter projection units the
205
+ # terminal status line reads for every session — behind a realm those units
206
+ # would come and go with whichever presets happen to be mounted. What a preset
207
+ # chooses is whether its agent compacts at all, which is `compaction-basic`.
208
+ - id: compaction
209
+ name: cordis:group
210
+ group: true
211
+ isolate:
212
+ compaction: true
213
+ toolResultPruner: true
214
+ config:
215
+ - id: compaction-basic
216
+ name: '@deepseek-ai/dsh-compaction-basic'
217
+
218
+ - id: command-compact
219
+ name: '@deepseek-ai/dsh-command-compact'
220
+
221
+ - id: tool-result-pruner
222
+ name: '@deepseek-ai/dsh-compaction-tool-result-pruner'
223
+ config:
224
+ thresholdChars: 8192
225
+ headChars: 4096
226
+ tailChars: 1024
227
+
228
+ # ── delegation and workflows ────────────────────────────────────────────────
229
+
230
+ # The `subagents` registry and its spawn/fork backends live in the HOST
231
+ # composition: the registry is a process singleton, and a provider name may only
232
+ # be registered once. This preset contributes the delegation TOOLS, which
233
+ # resolve that host registry.
234
+ #
235
+ # `workflows` is different — nothing outside an agent reads it — so every row
236
+ # that reaches it shares one entry-local realm here, and a consumer left
237
+ # outside would resolve a host registry this preset does not populate.
238
+ #
239
+ # `tool-subagent-report` is host-plane for the same reason as the registry,
240
+ # not because a preset may not want it: it registers a CONTINUABLE SETUP on
241
+ # that singleton rather than a tool this agent calls, and the setup list is
242
+ # not scope-aware — one copy per mounted preset means every child gets
243
+ # `report` registered once per live session, which throws on the second.
244
+ - id: delegation
245
+ name: cordis:group
246
+ group: true
247
+ isolate:
248
+ workflowEngine: true
249
+ config:
250
+ - id: tool-subagent-control
251
+ name: '@deepseek-ai/dsh-tool-subagent-control'
252
+
253
+ - id: tool-subagent-list-agents
254
+ name: '@deepseek-ai/dsh-tool-subagent-control/list-agents'
255
+
256
+ - id: tool-subagent
257
+ name: '@deepseek-ai/dsh-tool-subagent'
258
+ config:
259
+ provider: spawn
260
+ toolName: subagent
261
+ backgroundMode: continuable
262
+
263
+ - id: tool-subagent-fork
264
+ name: '@deepseek-ai/dsh-tool-subagent'
265
+ config:
266
+ provider: fork
267
+ toolName: subagent_fork
268
+ backgroundMode: continuable
269
+
270
+ # Product providers are host-plane singletons. Copy this preset, then
271
+ # remove `disabled` from either ordinary tool row to expose that product
272
+ # only to agents composed from the copy.
273
+ - id: tool-subagent-codex
274
+ name: '@deepseek-ai/dsh-tool-subagent'
275
+ disabled: true
276
+ config:
277
+ provider: codex
278
+ toolName: subagent_codex
279
+ enableRunInBackground: false
280
+ maxDepth: provider-managed
281
+
282
+ - id: tool-subagent-claude-code
283
+ name: '@deepseek-ai/dsh-tool-subagent'
284
+ disabled: true
285
+ config:
286
+ provider: claude-code
287
+ toolName: subagent_claude_code
288
+ enableRunInBackground: false
289
+ maxDepth: provider-managed
290
+
291
+ - id: workflow-worker-thread
292
+ name: '@deepseek-ai/dsh-workflow-worker-thread'
293
+ config:
294
+ provider: spawn
295
+
296
+ - id: tool-workflow
297
+ name: '@deepseek-ai/dsh-tool-workflow'
298
+
299
+ - id: tool-ralph
300
+ name: '@deepseek-ai/dsh-tool-ralph'
301
+ config:
302
+ subagentProvider: spawn
303
+ maxRounds: 64
304
+
305
+ # ── remaining model-facing rows ─────────────────────────────────────────────
306
+
307
+ - id: tool-ask-user
308
+ name: '@deepseek-ai/dsh-tool-ask-user'
309
+
310
+ - id: tool-todo
311
+ name: '@deepseek-ai/dsh-tool-todo'
312
+ config:
313
+ allowParallelInProgress: true
314
+
315
+ # The `web` service and its providers stay in the host composition; only the
316
+ # model-facing tool is per-session. `fetch` is on here because a terminal
317
+ # session has no browser beside it to open a result in.
318
+ - id: tool-web
319
+ name: '@deepseek-ai/dsh-tool-web'
320
+ config:
321
+ fetch: true
322
+ searchTimeoutMs: 60000
@@ -0,0 +1,3 @@
1
+ name: 终端模式
2
+ description: 具备标准模式的全部能力,并增加常驻终端会话与可选的 LSP 代码导航,面向 `dsh code` 的终端界面。
3
+ order: 5
@@ -0,0 +1,165 @@
1
+ # The codsh bundle patch: the interactive terminal surface over
2
+ # dsh-base. It mounts no Host, HTTP server, Web runtime, or browser plugin —
3
+ # the surface shares the process with the Agent, so it reads `ctx.agents`
4
+ # directly instead of through the API gateway, which exists to carry
5
+ # out-of-process clients.
6
+ #
7
+ # An ordinary provider plugin injects `cmdlineArgs`, parses this app's flags,
8
+ # then the runner creates an Agent through the core registry, mounts the
9
+ # preset the roster resolves, renders the session log to the TTY, and answers
10
+ # approvals and questions from the keyboard.
11
+
12
+ - id: system-prompt
13
+ config:
14
+ persona: >-
15
+ You are a coding agent powered by the {{model}} model. Your working directory is {{cwd}}.
16
+
17
+ # The shared module-reload HMR row stays off; the launcher's watch-only
18
+ # fallback still keeps the user patch layers live until the run exits.
19
+ - id: hmr
20
+ disabled: true
21
+
22
+ - id: tools
23
+ config:
24
+ # Keep the same temporary process-wide Code Mode opt-in as the Web surface.
25
+ mode: !!js process.env.DSH_TOOLS_MODE
26
+
27
+ # ── per-agent rows move behind the preset ───────────────────────────────────
28
+ #
29
+ # Every model-facing row below is composed by the mounted preset instead, so
30
+ # the tool registry's global layer stays empty and an agent sees exactly what
31
+ # its preset grants. Disabling rather than deleting is deliberate: the base is
32
+ # shared, and a row absent from a surface overlay would silently reappear the
33
+ # day someone reorders the composition.
34
+ #
35
+ # `shell-env` STAYS in the host plane: a host row that injects a service is the
36
+ # criterion for host-plane ownership — injection resolves before any session
37
+ # exists, so there is no agent to key by.
38
+
39
+ - id: tool-bash
40
+ disabled: true
41
+
42
+ - id: tool-pwsh
43
+ disabled: true
44
+
45
+ # The background-job REGISTRY stays on the host plane; only the model-facing
46
+ # `job_*` controls move. Its producers are preset rows that resolve it with
47
+ # `ctx.get`, and an entry-local realm around the registry is invisible to every
48
+ # sibling row outside that realm. The registry is keyed by owning agent, so one
49
+ # host instance serves every session.
50
+
51
+ - id: tool-jobs
52
+ disabled: true
53
+
54
+ - id: tool-fs
55
+ disabled: true
56
+
57
+ - id: tool-fs-search
58
+ disabled: true
59
+
60
+ - id: tool-str-replace-editor
61
+ disabled: true
62
+
63
+ # The `skill` REGISTRY stays in the host plane, host+per-scope layered:
64
+ # deployment-level providers register into its global layer while a preset's
65
+ # `skill-filesystem` registers into that preset's layer, and each agent reads
66
+ # the merged catalog its scope chain selects.
67
+
68
+ - id: skill-filesystem
69
+ disabled: true
70
+
71
+ - id: tool-skill
72
+ disabled: true
73
+
74
+ # The goal SERVICE and its session driver STAY on the host plane; only the
75
+ # model-facing tool moves. The registry is keyed by session, so one host
76
+ # instance serves every session.
77
+
78
+ - id: tool-goal
79
+ disabled: true
80
+
81
+ - id: plan-mode
82
+ disabled: true
83
+
84
+ # The token METER stays on the host plane; only the compaction backend that
85
+ # reads it moves. It owns the context-meter projection units the terminal
86
+ # status line reads, and that table is process-wide, so preset ownership would
87
+ # make the meter a function of which presets happen to be mounted.
88
+
89
+ - id: compaction-basic
90
+ disabled: true
91
+
92
+ - id: command-compact
93
+ disabled: true
94
+
95
+ - id: tool-result-pruner
96
+ disabled: true
97
+
98
+ # The subagent registry and its backends STAY in the host plane. `subagents` is
99
+ # a process singleton, and a provider registers under a globally unique name,
100
+ # so a per-session copy would both starve that host row and collide on the
101
+ # second session. What a preset chooses is which delegation TOOLS its agent
102
+ # sees.
103
+
104
+ - id: tool-subagent-control
105
+ disabled: true
106
+
107
+ - id: tool-subagent-list-agents
108
+ disabled: true
109
+
110
+ - id: tool-subagent
111
+ disabled: true
112
+
113
+ - id: tool-subagent-fork
114
+ disabled: true
115
+
116
+ - id: workflow-worker-thread
117
+ disabled: true
118
+
119
+ - id: tool-workflow
120
+ disabled: true
121
+
122
+ - id: tool-ralph
123
+ disabled: true
124
+
125
+ - id: agent-instructions
126
+ disabled: true
127
+
128
+ - id: tool-todo
129
+ disabled: true
130
+
131
+ - id: tool-web
132
+ disabled: true
133
+
134
+ - insert:
135
+ # Code Mode is a core execution capability, not a Web component.
136
+ - id: code-runtime
137
+ name: '@deepseek-ai/dsh-code-runtime-worker-thread'
138
+
139
+ # The preset roster. `config/agent-presets/` ships with the deployment and
140
+ # is read-only (its entries carry `system` trust); `$DSH_HOME/.agent-presets`
141
+ # is where a person — or an agent — authors their own, and carries the same
142
+ # trust as shell access because a preset IS a composition.
143
+ #
144
+ # Only the SHIPPED root is an assembly fact: it sits beside the installed
145
+ # app's own config, so `apps/cli`'s `composeProfile` resolves and patches it
146
+ # in. The writable root is `dsh-agent-presets`' own default
147
+ # (`includeUserRoot`), so a composition that never reaches that patch still
148
+ # finds a person's presets.
149
+ - id: agent-presets
150
+ name: '@deepseek-ai/dsh-agent-presets'
151
+ config:
152
+ default: code-cli
153
+
154
+ - id: coding-cli-startup
155
+ name: 'codsh-bundle/startup'
156
+
157
+ # Reads its invocation from the ordinary codingCliStartup provider.
158
+ - id: coding-cli-runner
159
+ name: 'codsh-bundle'
160
+ inject: [codingCliStartup]
161
+ config:
162
+ task: !!js ctx.codingCliStartup.task
163
+ resume: !!js ctx.codingCliStartup.resume
164
+ preset: !!js ctx.codingCliStartup.preset
165
+ print: !!js ctx.codingCliStartup.print