Merge remote-tracking branch 'origin/master' into cross-family-fs-sandbox

# Conflicts:
#	docs/config-catalog.md
#	docs/cordis-catalog/events.md
#	docs/cordis-catalog/services.md
#	docs/event-producer-consumer.md
#	docs/persistence-catalog.md
#	examples/acp-agent/cordis.yml
#	examples/acp-agent/tests/snapshots/advanced-toolchain/session.1.jsonl
#	examples/acp-agent/tests/snapshots/advanced-toolchain/session.2.jsonl
#	examples/acp-agent/tests/snapshots/advanced-toolchain/session.jsonl
#	examples/acp-agent/tests/snapshots/both-mode-turn/session.jsonl
#	examples/acp-agent/tests/snapshots/permission-switching/session.jsonl
#	examples/acp-agent/tests/snapshots/skill-load/session.jsonl
#	examples/acp-agent/tests/snapshots/text-turn/session.jsonl
#	packages/bash/bash-sandbox/src/index.ts
#	packages/bash/bash/src/types.ts
#	packages/bash/tool-bash/src/index.ts
#	packages/fs/fs/src/index.ts
#	packages/sandbox/sandbox-policy/src/session-mode.ts
#	packages/ui/permission/src/index.ts
#	packages/ui/permission/tests/permission.spec.ts
#	scripts/doc-budgets.manifest.json
This commit is contained in:
kingwl
2026-07-14 21:25:36 +08:00
608 changed files with 7195 additions and 12508 deletions

View File

@@ -1,27 +1,22 @@
# AGENTS.md — Examples
Runnable demos showing how the harness is wired. **Examples are NOT workspaces** — each `examples/*/package.json` is a private, dependency-free stub, never built. They are booted as unbuilt `tsx` subprocesses via the cordis Loader reading a `cordis.yml`; the `@deepseek-ai/dsh-*` plugin names in those YAML files resolve through the root `tsconfig.json` `paths` map, not through `node_modules`.
Runnable harness compositions. **Examples are not workspaces:** private package stubs are not built. App bins load each `cordis.yml` through `tsx`; package names resolve through root `tsconfig.json` paths, not `node_modules`.
Because examples are not under the `packages/*/src` coverage gate, an example that grows real, reusable *logic* should extract it into a `packages/` package (where it gets the per-file 100% gate and a README). Keep only example-specific glue here: the `cordis.yml` wiring, demo-only mocks/teaching artifacts, and the e2e/snapshot scenarios. There is no `start.ts` — the boot glue lives in each app package's `bin` (`@deepseek-ai/dsh-stdio-agent`, `@deepseek-ai/dsh-acp-agent`), which the `demo:*` scripts invoke against the leaf `cordis.yml`.
Keep wiring, demo fixtures, and e2e/snapshot scenarios here. Move reusable logic into `packages/`, with coverage and a README. App bins own bootstrapping; examples have no `start.ts`.
## Every example ships e2e smokes (keyless + with-key)
## E2E smokes
Each example must have **both** kinds of end-to-end smoke, because they catch different failures:
Each example has both:
- **Keyless smoke** boot the example through its real `cordis.yml` via the Loader (no API key), drive it, and assert the rendered output and a clean exit. This is the guard a hand-mounted unit test structurally cannot be: it exercises the REAL load path (`unwrapExports`, `inject`, the whole plugin tree), so a broken plugin export shape — e.g. a stray `export default` that collapses a namespace plugin and drops `inject` — fails here even when unit tests stay green (see [docs/postmortem/0001](../docs/postmortem/0001-acp-default-export-drops-inject.md)). It runs in the default e2e gate (CI has no secrets).
- **With-key smoke** — send a real prompt against the live model and verify the WORLD (a file on disk, a non-empty assistant turn), not the agent's self-report. This proves the actual product works, which a mock/keyless run structurally cannot. Key-gated: it self-skips without `DEEPSEEK_API_KEY` (see [the testing policy](../docs/testing.md) — inference is cheap here, so write many).
- **Keyless:** boot the real `cordis.yml` through the Loader, drive it, and assert output and clean exit. Catches Loader/export-shape failures hand-mounted tests miss ([postmortem](../docs/postmortem/0001-acp-default-export-drops-inject.md)).
- **With-key:** send a live-model prompt and verify external state, not the model's claim. Self-skip without `DEEPSEEK_API_KEY`; see [testing.md](../docs/testing.md).
**Exception — keyless-by-nature examples.** An example whose model is itself a mock/deterministic stand-in (no real provider) has no meaningful with-key smoke; the keyless smoke is the complete requirement. State the exception inline in the test.
Mock-only examples require only the keyless tier; state that exception in the test.
A keyless smoke that spawns the example from a temp cwd must set `TSX_TSCONFIG_PATH` to the repo-root tsconfig (the unbuilt `paths` map is found by searching UP from cwd), and pass `--expose-internals` when the `cordis.yml` loads the HMR plugin (mirror the `demo:*` script).
Temp-cwd keyless smokes set `TSX_TSCONFIG_PATH` to the root tsconfig and pass `--expose-internals` when loading HMR.
## Current state
Do not inventory example tests here; the `tests/` trees and root scripts are authoritative.
| Example | Keyless smoke | With-key smoke |
|---|---|---|
| `echo-agent` | `tests/echo.e2e.ts` — boots the real `cordis.yml`, drives the echo tool round-trip and the direct canned reply | **N/A — keyless by nature** (the `mock-echo` model has no real provider) |
| `coding-agent` | `tests/keyless-smoke.e2e.ts` — boots the full real tree (dummy key, no prompt → no model call), asserts banner + clean exit; `tests/code-mode-keyless-smoke.e2e.ts` — the same boot guard for the Code Mode overlay | `tests/{full-loop,coding-task,resume,compaction,todo-write}.e2e.ts` — real model + real bash + real todo_write, world-verified; `tests/code-mode.e2e.ts` — a real model composes two bash calls in one `run_code` program; collapsed header, dispatch events, written file all verified |
| `cordis-agent` | `tests/keyless-smoke.e2e.ts` — boots the real tree incl. `@deepseek-ai/dsh-tool-cordis` by package name; the tool logic is unit-tested in `packages/cordis/tool-cordis` | `tests/cordis-tools.e2e.ts` — real model mounts a listener (tagged line fires), builds+calls its own tool, composes two mounts via provide/inject |
| `acp-agent` | `pnpm run test:snapshot` — boots the real ACP subprocess and replays a recorded session keyless (incl. the hook matrix: a scenario per hook point × outcome for BOTH the Claude and Codex bridges — block, deny, ask, context-fold, force-continue); `tests/acp.e2e.ts` also asserts stdout purity without a key; `tests/escalation.e2e.ts` boots the default tree (sandbox + approval + permission + bridge) keyless: initialize + `session/new` | `tests/acp.e2e.ts` — real ACP prompt, verifies a file the agent wrote; `tests/hooks.e2e.ts` — a real `PreToolUse` hook blocks bash, verifies the file is NOT written; `tests/escalation.e2e.ts` — denied → escalates → a scripted client grants (the write must land) or rejects (it must not); skips without key/runner |
In `cordis.yml`, comment only non-obvious wiring, load-order consequences, replay, security boundaries, and configuration scope. Do not narrate visible entries; use [dsh-prose-standard](../.agents/skills/dsh-prose-standard/SKILL.md) for required coverage and editorial judgment.
See [the root AGENTS.md](../AGENTS.md) for repo-wide conventions and [docs/architecture.md](../docs/architecture.md) for the design.

View File

@@ -1,6 +1,6 @@
# Examples
Runnable demos (not workspaces) that showcase how the harness is wired. Each example is now a **thin leaf**: a `cordis.yml` that picks the swappable backends (an LLM adapter, a bash executor), loads ONE app package, and may add optional product tools or demo-only mocks. The composition — the spine, the front-door cluster, and the boot glue — lives in the app packages ([`@deepseek-ai/dsh-stdio-agent`](../packages/ui/stdio-agent), [`@deepseek-ai/dsh-acp-agent`](../packages/ui/acp-agent)) and the [`@deepseek-ai/dsh-agent-core`](../packages/core/agent-core) bundle they share. There is no `start.ts`; the `demo:*` scripts invoke each app package's `bin`.
Runnable demos (not workspaces) that showcase how the harness is wired. Each example is a **thin leaf**: a `cordis.yml` that picks the swappable backends (an LLM adapter, a bash executor), loads one app package, and may add optional product tools or demo-only mocks. The composition — the spine, the front-door cluster, and the boot glue — lives in the app packages ([`@deepseek-ai/dsh-stdio-agent`](../packages/ui/stdio-agent), [`@deepseek-ai/dsh-acp-agent`](../packages/ui/acp-agent)) and the [`@deepseek-ai/dsh-agent-core`](../packages/core/agent-core) bundle they share. There is no `start.ts`; the `demo:*` scripts invoke each app package's `bin`.
## echo-agent
@@ -19,7 +19,7 @@ A REPL agent demo: DeepSeek V4 + the `read`/`write`/`edit` filesystem tools + th
Run with: `pnpm run demo:repl` (needs `DEEPSEEK_API_KEY` in the environment or a gitignored repo-root `.env`). See [coding-agent/README.md](coding-agent/README.md) for details.
Its `code-mode.cordis.yml` overlay flips the same tree to **Code Mode**: the worker-thread code runtime is loaded and the tool registry runs `mode: code`, so its registry contribution is the reserved `run_code` transport plus a generated TypeScript SDK section, and the model composes the other tools by writing a program whose output it curates. Run with: `pnpm run demo:code-mode` (the REPL is the default UI; `acp` as the argument serves the acp-agent example's same-shaped overlay instead) — see the [Code Mode section](coding-agent/README.md#code-mode) for what to try.
Run the Code Mode overlay with `pnpm run demo:code-mode`, or pass `acp` for the ACP example. See the [Code Mode example](coding-agent/README.md#code-mode) for its composition and a sample task.
## cordis-agent

View File

@@ -7,7 +7,7 @@ pnpm run demo:acp # needs DEEPSEEK_API_KEY (repo-root .env or env)
pnpm run demo:code-mode acp # the same server in Code Mode: one wire tool, run_code
```
This example is one leaf `cordis.yml`: it loads the [`@deepseek-ai/dsh-acp-agent`](../../packages/ui/acp-agent) app (the [`@deepseek-ai/dsh-agent-core`](../../packages/core/agent-core) spine, JSONL session persistence, and the `@deepseek-ai/dsh-acp` bridge), the DeepSeek adapter, sandboxed bash, approval and permission services, subagent/workflow/todo tools, and the advisory `repeat-tool-guard`. ACP `session/new` creates agents on demand. The app package bakes in the no-stdout-logger cluster, so the leaf has no logger entry to get wrong by default. `demo:code-mode acp` boots the same tree through [`code-mode.cordis.yml`](code-mode.cordis.yml), collapsing the tool surface to `run_code` plus the generated TypeScript SDK (see the [dsh-tools Code Mode section](../../packages/core/tools/README.md#code-mode)).
The leaf config loads the ACP app, DeepSeek adapter, sandboxed bash, approval and permission services, model-facing tools, and repeat guard. The app bundles the agent spine, JSONL persistence, and bridge, creates agents on `session/new`, and keeps stdout logger-free. [`code-mode.cordis.yml`](code-mode.cordis.yml) overlays the same tree with `run_code` and its generated TypeScript SDK; see [Code Mode](../../packages/core/tools/README.md#code-mode).
## stdout is the protocol
@@ -33,7 +33,7 @@ The editor sets each session's `cwd` to the project it opens, and bash uses that
## Snapshot tests (record-once / replay-deterministic)
This example is the home of the harness's **snapshot tests** — they boot this server as a real subprocess, drive it with a deterministic input script, and diff its normalized output against committed golden files. The model is made deterministic by `@deepseek-ai/dsh-llm-replay`, a function/namespace plugin that installs an `llm/stream` waterfall listener and short-circuits it, serving model streams reconstructed from a recorded **session JSONL** fixture (`<scenario>/session.jsonl`) — so replay needs no API key. The fixture IS the persisted session log: its `assistant/chunk` events carry every `StreamChunk`, so grouping them by `(turn, step)` reconstructs each `stream()` call (one model call per loop step). Recording is therefore "run the real agent once and harvest the `.jsonl`"; use `pnpm run test:snapshot:record` when the model transcript itself should change, and `pnpm run test:snapshot:refresh` when the committed model transcript is still the right mock input and only the current replay output/goldens need to be rewritten. The two failure modes not expressible as logged chunks — a pure throw before any chunk, and cancel/hang — use an optional `<scenario>/replay.override.json` sidecar (a `ReplayEntry[]` that replaces the derived script). A scenario that needs the agent to operate on existing files ships an optional `<scenario>/workspace/` directory — the harness copies its contents into the temp cwd before the run (see `workspace-edit`). See [the ACP snapshot tests RFC](../../docs/rfc/implemented/testing/2026-06-19-acp-snapshot-tests.md) for the full design.
This example hosts the ACP snapshot suite. `dsh-llm-replay` reconstructs model streams from `assistant/chunk` events in each scenario's session JSONL, so replay is keyless. Recording runs the real agent and harvests that log; refresh keeps the committed transcript as mock input and rewrites current replay outputs. `replay.override.json` covers throw and hang cases that chunks cannot express, and an optional `workspace/` seeds files. The [snapshot RFC](../../docs/rfc/implemented/testing/2026-06-19-acp-snapshot-tests.md) owns the full design.
## Permissions and sandboxing

View File

@@ -1,6 +1,4 @@
# Keyless replay counterpart to advanced.cordis.yml. It composes the same
# Code Mode + Cordis + subagent + workflow tree while replacing only the live
# model adapter with the committed multi-session replay script.
# Replay counterpart to advanced.cordis.yml; only the live model is replaced.
- id: base
name: '@cordisjs/plugin-include'
config:

View File

@@ -1,7 +1,5 @@
# Advanced ACP snapshot overlay: keep every native tool on the wire, add the
# Code Mode worker, and opt into the self-referential Cordis toolset. The base
# tree already supplies direct spawn subagents and the workflow worker, so this
# composition exercises all four boundaries in one editor-facing ACP turn.
# Add Code Mode and Cordis tools to the base spawn/workflow stack, exercising
# all four boundaries in one ACP snapshot.
- id: base
name: '@cordisjs/plugin-include'
config:

View File

@@ -1,9 +1,6 @@
# Both-mode REPLAY overlay: the same patched tree as both-mode.cordis.yml
# (registry in `mode: both` + the worker code runtime) with the keyless model
# swap from cordis.snapshot.yml (llm-deepseek disabled, llm-replay serving
# the recorded fixture). Patches do not compose across nested includes —
# an outer include's patch can only target entries in the file IT loads — so
# this file patches ./cordis.yml directly with the union of both overlays.
# Keyless both mode combines the runtime/registry patch with the DeepSeek-to-replay
# swap. Include patches cannot target entries behind a nested include, so this file
# applies both overlays directly to `cordis.yml`.
- id: base
name: '@cordisjs/plugin-include'
config:

View File

@@ -1,11 +1,7 @@
# Both-mode RECORD overlay: the live acp-agent tree (./cordis.yml) with two
# load-time patches — the app entry's config gains `tools: { mode: both }`
# (every native tool definition stays on the wire AND run_code + the generated
# TypeScript SDK prompt section ride along) and the worker-thread code runtime joins the
# tree as `ctx.codeRuntime`. The dsh-acp-agent bin boots this file when the
# snapshot harness records the both-mode scenario; DSH_SNAPSHOT=replay swaps
# it for the sibling both-mode.cordis.snapshot.yml. A config patch REPLACES
# the entry's whole config, so the base entry's fields are restated verbatim.
# Both mode adds `ctx.codeRuntime` while keeping native tools on the wire and
# adding `run_code` plus its generated TypeScript SDK prompt. The app bin selects
# this overlay for snapshot recording and the sibling overlay for replay. A config
# patch replaces the whole app config, so unchanged base fields are restated below.
- id: base
name: '@cordisjs/plugin-include'
config:

View File

@@ -1,9 +1,6 @@
# Code Mode REPLAY overlay: the same patched tree as code-mode.cordis.yml
# (registry in `mode: code` + the worker code runtime) with the keyless model
# swap from cordis.snapshot.yml (llm-deepseek disabled, llm-replay serving
# the recorded fixture). Patches do not compose across nested includes —
# an outer include's patch can only target entries in the file IT loads — so
# this file patches ./cordis.yml directly with the union of both overlays.
# Keyless Code Mode combines the runtime/registry patch with the DeepSeek-to-replay
# swap. Include patches cannot target entries behind a nested include, so this file
# applies both overlays directly to `cordis.yml`.
- id: base
name: '@cordisjs/plugin-include'
config:

View File

@@ -1,12 +1,8 @@
# Code Mode overlay: the live acp-agent tree (./cordis.yml) with two
# load-time patches — the app entry's config gains `tools: { mode: code }`
# (the registry offers exactly one wire tool, run_code, plus the generated
# TypeScript SDK prompt section) and the worker-thread code runtime joins the
# tree as `ctx.codeRuntime`. The dsh-acp-agent bin boots this file for
# `pnpm run demo:code-mode acp` and when the snapshot harness records the
# code-mode scenarios; DSH_SNAPSHOT=replay swaps it for the sibling
# code-mode.cordis.snapshot.yml. A config patch REPLACES the entry's whole
# config, so the base entry's fields are restated verbatim.
# Code Mode adds `ctx.codeRuntime` and changes the registry to one wire tool,
# `run_code`, plus its generated TypeScript SDK prompt. The app bin selects this
# overlay for `demo:code-mode acp` and snapshot recording, and selects the sibling
# replay overlay for `DSH_SNAPSHOT=replay`. A config patch replaces the whole app
# config, so unchanged base fields are restated below.
- id: base
name: '@cordisjs/plugin-include'
config:

View File

@@ -1,30 +1,17 @@
# Snapshot-test REPLAY overlay: the SAME app tree as cordis.yml, derived from
# it by an include — the one difference is the model backend. A keyless replay
# run cannot boot the real adapter (llm-deepseek's apply() throws without
# DEEPSEEK_API_KEY), so the include patches the live tree at load time: the
# llm-deepseek entry is disabled by id, and the llm-replay entry (which serves
# a recorded session JSONL — no API key, no network) is inserted. Every other
# entry — the app, the bash executor, the fs/subagent/todo tools, both hook
# bridges, the system prompt — IS the live tree, so replay exercises exactly
# what ships and an app-shape change lands once, in cordis.yml.
#
# The dsh-acp-agent bin selects this file for DSH_SNAPSHOT=replay. The replay
# fixture path comes from $DSH_SNAPSHOT_FILE (and an optional
# $DSH_SNAPSHOT_OVERRIDE sidecar), set by the snapshot harness. stdout stays
# reserved for the ACP JSON-RPC protocol (the app package loads no stdout
# logger). Patches apply when the include loads the file — a one-shot replay
# boot, so the load-time-only patch semantics are exactly enough.
# Keyless replay includes the live `cordis.yml`, disables the key-requiring
# DeepSeek adapter, and inserts `llm-replay` to serve recorded JSONL without a key
# or network; every other app entry remains shared.
# With `DSH_SNAPSHOT=replay`, the app bin reads `DSH_SNAPSHOT_FILE` and optional
# `DSH_SNAPSHOT_OVERRIDE` from the harness. The one-shot patch applies at include
# load time, and stdout remains reserved for ACP JSON-RPC.
- id: base
name: '@cordisjs/plugin-include'
config:
path: ./cordis.yml
patches:
# The name is an assertion, not an override: the include skips the patch
# (warning if a logger exists) when the id points at a different plugin,
# so this can never disable the wrong entry. If cordis.yml ever RENAMES
# the id, the patch degrades to a skip — replay output stays correct
# (llm-replay still short-circuits the stream) but the stale patch and a
# futile keyless adapter entry linger until review catches them.
# `name` asserts the target: a mismatch skips the patch and warns only when
# a logger exists. A renamed id leaves a stale adapter entry, but replay still
# short-circuits through `llm-replay`.
- id: llm-deepseek
name: '@deepseek-ai/dsh-llm-deepseek'
disabled: true

View File

@@ -1,17 +1,7 @@
# The acp-agent plugin tree: the ACP server. Also the snapshot RECORD config
# (the dsh-acp-agent bin selects it for DSH_SNAPSHOT=record): a real llm-deepseek
# run whose persisted log the snapshot harness harvests. The swappable DeepSeek
# adapter, sandboxed bash executor, the ACP server app
# (@deepseek-ai/dsh-acp-agent), and the optional model-facing
# fs/subagent/todo tools loaded below.
#
# CRITICAL: this tree loads NO stdout logger and NO hmr — stdout is reserved for
# the ACP JSON-RPC protocol (see packages/ui/acp). That guarantee is now a
# property of @deepseek-ai/dsh-acp-agent (it contains no logger entry), not a
# leaf convention: there is no logger here to get wrong.
#
# Requires DEEPSEEK_API_KEY (and optionally DEEPSEEK_BASE_URL) — the
# dsh-acp-agent bin loads the gitignored repo-root .env first (on STDERR only).
# ACP server and snapshot-record composition. With `DSH_SNAPSHOT=record`, the
# app bin runs the real DeepSeek adapter and the harness harvests its persisted
# log. The bin loads the gitignored root `.env` before this config. This tree has
# no stdout logger or HMR because stdout carries ACP JSON-RPC.
# The DeepSeek adapter.
- id: llm-deepseek
@@ -59,22 +49,16 @@
config:
model: deepseek-v4-flash
persistenceRoot: !!js process.env.DSH_SNAPSHOT_SESSIONS_ROOT ?? './.sessions'
# The persona: identity + behavior only, nothing about transports or
# tooling — tool guidance lives with each tool plugin (descriptions +
# prompt sections). {{model}} and {{cwd}} are prompt variables the agent
# loop resolves per session (every ACP session carries the client's cwd,
# so the persona can state the workspace).
# Keep the persona to identity and behavior; tool plugins own tool guidance.
# The loop resolves {{model}} and each ACP session's client-supplied {{cwd}}.
persona: |
You are a coding assistant powered by the {{model}} model. Your working directory is {{cwd}}. Your bash tool runs under a file sandbox — a `[sandbox: file access denied …]` result is policy, not a command bug.
Verify your work by running the code or tests. Keep answers brief and factual.
# The subagent seam + both in-process backends + two model-facing tools, as leaf
# entries after the app (which provides ctx.agents/ctx.tools). spawn (a fresh
# child) and fork (a child seeded with the parent's completed-turn prefix) are
# both reachable by the model: dsh-tool-subagent is loaded once per backend with
# a distinct toolName (subagent → spawn, subagent_fork → fork), so a multi-child
# scenario can exercise both transports.
# Expose fresh-child `spawn` and completed-prefix `fork` through separate tool
# names so multi-child scenarios exercise both transports. These leaves follow
# the app because it provides `ctx.agents` and `ctx.tools`.
- id: subagent
name: '@deepseek-ai/dsh-subagent'
@@ -101,10 +85,8 @@
toolName: subagent_fork
# Dynamic workflows: the worker-thread engine (ctx.workflows) over the spawn
# subagent backend above, plus the model-facing `workflow` tool. The model
# writes a JavaScript orchestration script (meta + body); the engine runs it
# in its own worker thread and fans agent() calls out as spawn children.
# The worker-thread workflow engine fans a model-written JavaScript script's
# `agent()` calls out through the spawn backend; the adjacent tool exposes it to the model.
- id: workflow-workerthread
name: '@deepseek-ai/dsh-workflow-workerthread'
config:
@@ -112,16 +94,12 @@
- id: tool-workflow
name: '@deepseek-ai/dsh-tool-workflow'
# The model-facing todo_write tool: whole-list task tracking written to the
# session log (todo/write), surfaced to the ACP client as a `plan` update.
# `todo_write` replaces the logged whole list and surfaces an ACP `plan` update.
- id: tool-todo
name: '@deepseek-ai/dsh-tool-todo'
# The repeat-tool-call guard: advisory reminders (injected context, never a
# block) when the model re-issues the same tool call with identical arguments;
# defaults [3, 5, 8]. Loaded here so the snapshot tier exercises the reminder
# transcript (the repeat-tool-guard scenario) — no other scenario repeats a
# call three times, so it is inert everywhere else.
# Identical repeat calls trigger advisory context, never a block, at the default
# thresholds [3, 5, 8]. Only the repeat-tool-guard snapshot scenario reaches them.
- id: repeat-tool-guard
name: '@deepseek-ai/dsh-repeat-tool-guard'
@@ -141,28 +119,19 @@
- id: tool-fs
name: '@deepseek-ai/dsh-tool-fs'
# The Claude Code hook bridge. `configPath` is PROCESS-LEVEL: it is read ONCE at
# load and the relative `./hooks.json` resolves against the ACP server's launch
# cwd, NOT each `session/new.cwd`. So a single `hooks.json` next to where the
# server starts applies to every session; a project-local, per-session hooks.json
# is NOT discovered (per-session config resolution is a TODO — see the bridge
# README). With no file present the parse fails-soft and the bridge registers
# nothing (a silent no-op). Hooks THEMSELVES run in the session cwd (the bridge
# passes it as the workdir); only WHERE the config is read from is process-level.
# stdout is the ACP JSON-RPC channel — the bridge's warnings go through ctx.logger
# (no exporter here), never to stdout.
# `configPath` is read once at load and resolves from the server launch cwd, not
# `session/new.cwd`; one `hooks.json` therefore applies to every session and a
# project-local file is not discovered. Missing config registers nothing. Hook
# commands still run in the session cwd. Warnings use `ctx.logger`, never stdout;
# see packages/hooks/hooks-claude/README.md for the deferred per-session design.
- id: hooks-claude
name: '@deepseek-ai/dsh-hooks-claude'
config:
configPath: ./hooks.json
# The Codex hook bridge, loaded alongside the Claude one. It reads its OWN config
# file (`./codex-hooks.json`, Codex's snake_case five-event dialect) — the two
# bridges cannot share one file, so each owns a distinct path. Same process-level
# read-once semantics and same fails-soft-when-absent contract: a launch cwd with
# no `codex-hooks.json` registers nothing (a silent no-op through ctx.logger, never
# stdout). The example ships both bridges so a scenario can exercise EITHER dialect
# end-to-end by seeding the matching file in its workspace/.
# Codex uses its own `codex-hooks.json` and snake_case five-event dialect; it
# cannot share Claude's file. It has the same process-level, read-once, missing-is-no-op,
# logger-only contract. Shipping both bridges lets a scenario seed and exercise either dialect.
- id: hooks-codex
name: '@deepseek-ai/dsh-hooks-codex'
config:

View File

@@ -17,36 +17,18 @@ import {
} from '@agentclientprotocol/sdk'
/**
* End-to-end: boot examples/acp-agent as a real subprocess speaking ACP over
* its stdio, drive it with a real ClientSideConnection, send a real prompt, and
* verify the WORLD (a file the agent wrote), not the agent's self-report. Owns
* and disposes the subprocess in afterEach. Key-gated.
*
* Also asserts stdout purity (only framed JSON-RPC on stdout) — that one runs
* WITHOUT a key, since it only needs the server to boot and answer initialize.
* Boots examples/acp-agent as an ACP subprocess. The key-gated prompt leg
* verifies its filesystem effect; a keyless initialize leg verifies that stdout
* contains only framed JSON-RPC. Each subprocess is disposed in `afterEach`.
*/
// The dsh-acp-agent bin (the demo:acp entry) and this example's cordis.yml. The
// bin resolves its config-path arg from CWD; the subprocess runs from a temp
// workdir, so pass the example config's ABSOLUTE path.
// The child runs from a temp cwd, so its bin and config path are absolute.
const binScript = fileURLToPath(new URL('../../../packages/ui/acp-agent/src/bin.ts', import.meta.url))
const configPath = fileURLToPath(new URL('../cordis.yml', import.meta.url))
// Resolve tsx's loader to an ABSOLUTE path: the subprocess runs with cwd set to
// a temp workdir (this test launches there and uses it as the session cwd; the
// bridge no longer requires cwd === the launch dir, but a temp dir keeps the
// test hermetic), where a bare `--import tsx` would not resolve from
// node_modules. import.meta.resolve gives the worktree's tsx regardless of cwd.
// Resolve tsx absolutely because the subprocess runs outside the repo.
const tsxLoader = fileURLToPath(import.meta.resolve('tsx'))
// Absolute path to the repo-root tsconfig. Dev/test/demo run UNBUILT: the
// `@deepseek-ai/dsh-*` workspace imports resolve through the `paths` map in the
// root tsconfig (tsx reads it), NOT through built `lib/` output. But tsx finds
// that tsconfig by searching UP from the child's cwd — and the child's cwd is a
// temp workdir OUTSIDE the repo, so the search misses and the dsh-* imports fail
// (the child dies before writing a byte). Point tsx at the repo tsconfig
// explicitly via TSX_TSCONFIG_PATH so resolution is cwd-independent. (Without
// this the suite only passed by accident when a stale built `lib/` happened to
// exist — exactly the contamination that masked the inject bug this suite now
// guards.) The repo root is four levels up from this file (examples/acp-agent/tests).
// The root tsconfig supplies unbuilt workspace `paths`; making it explicit
// avoids accidental resolution through stale built output.
const repoTsconfig = fileURLToPath(new URL('../../../tsconfig.json', import.meta.url))
interface Spawned {
@@ -155,9 +137,7 @@ describe('acp-agent over real stdio (no key required)', () => {
it('emits only framed JSON-RPC on stdout', async () => {
workdir = await mkdtemp(join(tmpdir(), 'acp-e2e-'))
// Collect raw stdout bytes directly (bypass the SDK framing) to inspect.
// A dummy key lets the deepseek adapter APPLY (it only checks the key is
// present at boot, not valid — the key is used only on a real model call,
// which this purity test never triggers). So this runs WITHOUT real creds.
// A dummy key boots the adapter; this purity test sends no prompt and makes no model call.
const child = spawn(process.execPath, ['--import', tsxLoader, binScript, '--config', configPath], {
cwd: workdir,
env: {
@@ -197,17 +177,10 @@ describe('acp-agent over real stdio (no key required)', () => {
}, 30_000)
it('session/new succeeds over real stdio (no model call)', async () => {
// REGRESSION GUARD (this exact RPC crashed a real Zed session with
// "cannot get property \"agents\" without inject"): `session/new` drives the
// full bridge → `ctx.agents.create({sessionId, meta:{cwd}})` → AgentLoop →
// registry/persistence path, ALL of which run from the JSON-RPC read loop
// OUTSIDE the bridge plugin's injection scope. A lazy `ctx.<service>` read
// on that path throws and the RPC fails with an Internal error — yet the
// call never touches the model, so this reproduces WITHOUT a key. The
// key-gated prompt test below never caught it (it needs real creds); the
// initialize-only purity test never caught it (initialize does not reach
// the factory). This closes that gap: boot the real subprocess and create a
// session, asserting the RPC RESOLVES (not rejects with an inject error).
// Regression guard (this exact RPC crashed a real Zed session with "cannot get property
// \"agents\" without inject"): `session/new` drives the full bridge →
// `ctx.agents.create({sessionId, meta:{cwd}})` → AgentLoop → registry/persistence path, ALL
// of which run from the JSON-RPC read loop outside the bridge plugin's injection scope.
workdir = await mkdtemp(join(tmpdir(), 'acp-e2e-'))
// A dummy key lets the deepseek adapter boot (it only checks presence, not
// validity, at apply time); no model call is made, so the key is never used.
@@ -238,28 +211,23 @@ describe.skipIf(!process.env.DEEPSEEK_API_KEY)('acp-agent e2e: real prompt over
})
expect(['end_turn', 'max_tokens']).toContain(res.stopReason)
// Verify the WORLD, not the agent's self-report: read the file from disk.
// Verify the filesystem effect rather than the agent's report.
const proof = await readFile(join(workdir, 'proof.txt'), 'utf8')
expect(proof).toContain('ACP_OK')
// And the client saw tool-call activity stream through.
const toolCalls = updates.filter(u => u.sessionUpdate === 'tool_call')
expect(toolCalls.length).toBeGreaterThan(0)
// Tool-call UI quality (the tool owns its presentation): the bash tool's
// `presentCall` sets the title to the exact command (an execute card hides
// rawInput, so the command IS the title) — NOT the bare tool name "bash".
// A `bash` call must therefore carry an execute kind, a non-"bash" title,
// and a string rawInput (the command). `toolCalls` is already narrowed to
// the `tool_call` shape by the filter above, so these fields are reachable.
// Bash execute cards hide rawInput, so `presentCall` uses the exact command
// as the title rather than the bare tool name "bash".
const bashCall = toolCalls.find(u => u.kind === 'execute')
expect(bashCall).toBeDefined()
if (bashCall === undefined) throw new Error('expected an execute tool_call')
expect(typeof bashCall.title).toBe('string')
expect(bashCall.title.length).toBeGreaterThan(0)
expect(bashCall.title).not.toBe('bash') // the old, unhelpful title
expect(typeof bashCall.rawInput).toBe('string') // the exact command
// Capability OFF: no terminal _meta — the ```console text path renders.
expect(bashCall.title).not.toBe('bash')
expect(typeof bashCall.rawInput).toBe('string')
// Without the terminal capability, output uses the console-text path.
expect((bashCall as { _meta?: unknown })._meta).toBeUndefined()
}, 180_000)

View File

@@ -76,12 +76,9 @@ const SCENARIOS: Scenario[] = [
// child runs as a spawn subagent under the worker-thread engine (its session is the
// child fixture), and the tool result carries the script's return value.
{ name: 'workflow-run', hasModelTurn: true, recorded: true, childSessions: 1 },
// ACP-facing counterpart to the packaged Python SDK snapshot: Cordis mounts
// a live marker, Code Mode inspects it through the worker bridge, then a
// direct child and a workflow child run before the mount is disposed. This
// class adds both Code Mode and the opt-in Cordis tools to the base tree, so
// it owns a distinct request-header pin. The scripted fixture is authored:
// the value is deterministic cross-boundary composition, not live-model prose.
// Authored counterpart to the packaged Python SDK snapshot: mount a live marker, inspect it
// through Code Mode, run direct and workflow children, then unmount it. The extra Code Mode and
// Cordis plugins require their own request-header pin; the fixture tests deterministic composition.
{
name: 'advanced-toolchain',
hasModelTurn: true,
@@ -91,31 +88,15 @@ const SCENARIOS: Scenario[] = [
headerClass: 'advanced',
configPath: ADVANCED_CONFIG,
},
// Hook matrix — one scenario per hook point × its headline Decision outcome,
// across BOTH bridges (Claude `hooks.json`, Codex `codex-hooks.json`, seeded in
// workspace/). The block scenarios need no model call: a UserPromptSubmit hook
// blocks the prompt before any step runs (keyless, authored — the derived
// script is empty so no sidecar), yet persists a `rejected` turn carrying
// `hook/*` events, so their logs ARE compared. Every other point fires a real
// seam mid-turn, so its transcript is recorded WITH the hook active.
// Prompt-submit blocks are authored keylessly: they persist a rejected turn
// and hook events without starting a model step, so their logs still compare.
{ name: 'hook-cc-promptsubmit-block', hasModelTurn: false, comparesLog: true, recorded: false },
{ name: 'hook-codex-promptsubmit-block', hasModelTurn: false, comparesLog: true, recorded: false },
// The mid-turn seams fire during a real model turn, so each is recorded WITH
// its hook active (the model's reaction to a deny/block/force-continue is part
// of the captured transcript). The Codex bridge exercises the same seams in its
// own snake_case dialect.
//
// Two hook points are deliberately NOT snapshotted, and stay on the bridges'
// unit coverage (`bridge.spec.ts` / `coverage.spec.ts`) instead:
// - SessionStart and SubagentStart inject context through a detached,
// best-effort `void runPoint(...).then(agent.inject())` with no turn
// binding, so the resulting `context/message` races the work it precedes
// and lands at a nondeterministic log position — a recorded golden does not
// even reproduce on its own replay.
// - SubagentStop is observe-only with no turn and no injection, so it writes
// NOTHING to the transcript — a golden would be byte-identical to the
// no-hook run and could never be proven to fail.
// See the hook-snapshot-matrix RFC for the full rationale.
// The mid-turn seams fire during a real model turn, so each is recorded with its hook active
// (the model's reaction to a deny/block/force-continue is part of the captured transcript).
// SessionStart/SubagentStart are excluded because detached injection races log
// order; SubagentStop writes no transcript, so a golden could not prove it ran.
// Unit tests cover those points; the hook-snapshot-matrix RFC owns the rationale.
{ name: 'hook-cc-promptsubmit-context', hasModelTurn: true, recorded: true },
{ name: 'hook-cc-pretool-deny', hasModelTurn: true, recorded: true },
{ name: 'hook-cc-pretool-ask', hasModelTurn: true, recorded: true },
@@ -130,11 +111,9 @@ const SCENARIOS: Scenario[] = [
{ name: 'hook-codex-posttool-block', hasModelTurn: true, recorded: true },
{ name: 'hook-codex-posttool-context', hasModelTurn: true, recorded: true },
{ name: 'hook-codex-stop-continue', hasModelTurn: true, recorded: true },
// Code Mode: the registry in `mode: code` — the wire tool list collapses to
// [run_code], the tools:sdk section rides in the prompt, and the program's
// tool calls land as tool/code-dispatch events. Each mode boots its own
// overlay config, composes a different header by construction, and
// therefore pins its own class.
// Code Mode: the registry in `mode: code` — the wire tool list collapses to [run_code], the
// tools:sdk section rides in the prompt, and the program's tool calls land as
// tool/code-dispatch events. Each overlay composes and pins its own header class.
{ name: 'code-mode-turn', hasModelTurn: true, recorded: true, pinsHeader: true, headerClass: 'code', configPath: CODE_MODE_CONFIG },
{ name: 'both-mode-turn', hasModelTurn: true, recorded: true, pinsHeader: true, headerClass: 'both', configPath: BOTH_MODE_CONFIG },
// The default tree owns the single Permissions select. Snapshot mode starts

View File

@@ -17,35 +17,24 @@ import {
} from '@agentclientprotocol/sdk'
/**
* The default ACP composition (`cordis.yml`) end to end.
*
* Keyless smoke: boot the REAL `cordis.yml` through the `dsh-acp-agent` bin as
* an ACP subprocess and drive initialize + session/new — the real-Loader-path
* guard (postmortem 0001) for THIS tree's export shapes, which now include the
* sandbox executor AND the approval service. No prompt is sent, so neither the
* model nor a sandbox runner is ever exercised.
*
* With-key escalation flow (self-skips without DEEPSEEK_API_KEY or a usable
* platform runner): a scripted ACP client plays the human. The prompt asserts
* a prior denial (the organic denial→marker path lives on the sandbox e2e
* legs and unit tiers), the real model escalates with `sandbox_permissions` +
* `justification`, the bridge prompts THIS client over
* `session/request_permission`, the client answers `allow-once`, and the
* retried write must land ON DISK (world-verified) — under the granted mode,
* a temp-dir session cwd is writable either way.
* Exercises the default ACP composition through the real bin and Loader. The
* keyless leg boots sandbox, approval, permission, and bridge services, then
* initializes and opens a session without a model call or runner probe. With a
* key and usable runner, the prompt asserts a prior denial; the model requests
* a wider retry with justification, and a scripted client grants or rejects it.
* The filesystem must show that only the granted retry ran. Missing credentials
* or runner support self-skip; real denial markers remain on sandbox e2e tiers.
*/
const binScript = fileURLToPath(new URL('../../../packages/ui/acp-agent/src/bin.ts', import.meta.url))
const configPath = fileURLToPath(new URL('../cordis.yml', import.meta.url))
const tsxLoader = fileURLToPath(import.meta.resolve('tsx'))
// The subprocess runs from a temp cwd OUTSIDE the repo; point tsx at the repo
// The subprocess runs from a temp cwd outside the repo; point tsx at the repo
// tsconfig so the unbuilt `paths` map resolves (see examples/AGENTS.md).
const repoTsconfig = fileURLToPath(new URL('../../../tsconfig.json', import.meta.url))
// A usable confining runner, probed the same way the executor suites do:
// bwrap on Linux, Seatbelt's sandbox-exec on macOS. Without one the strict
// attempt would fail closed (SANDBOX_UNAVAILABLE) instead of producing the
// denial this flow starts from.
// Without a usable bwrap/Seatbelt runner, the strict attempt fails closed with
// SANDBOX_UNAVAILABLE instead of producing the denial this flow requires.
const hasBwrap = spawnSync('bwrap', ['--ro-bind', '/', '/', '--dev', '/dev', '--proc', '/proc', '--die-with-parent', '--', 'true'], {
timeout: 5_000,
stdio: 'ignore',
@@ -96,8 +85,7 @@ function spawnAcpAgent(cwd: string, answer: 'allow-once' | 'reject-once'): Spawn
requestPermission(params: RequestPermissionRequest): Promise<RequestPermissionResponse> {
permissionRequests.push(params)
const option = params.options.find(o => o.optionId === answer)
// The scripted human: pick the requested option when the prompt offers
// it; an unexpected prompt shape cancels (fail closed, never grants).
// An unexpected prompt shape cancels without granting.
if (option === undefined) return Promise.resolve({ outcome: { outcome: 'cancelled' } })
return Promise.resolve({ outcome: { outcome: 'selected', optionId: option.optionId } })
},
@@ -121,9 +109,6 @@ describe('default sandbox composition keyless smoke (real cordis.yml via the Loa
workdir = await mkdtemp(join(tmpdir(), 'sandbox-acp-smoke-'))
spawned = spawnAcpAgent(workdir, 'reject-once')
const { client } = spawned
// A dummy key boots the adapter; no prompt is ever sent, so no model call
// and no sandbox runner probe happen. This drives the fiber tree the same
// way an editor would, which is what catches a broken export/inject shape.
const init = await client.initialize({ protocolVersion: PROTOCOL_VERSION, clientCapabilities: {} })
expect(init.protocolVersion).toBe(PROTOCOL_VERSION)
const { sessionId } = await client.newSession({ cwd: workdir, mcpServers: [] })
@@ -135,14 +120,10 @@ describe('default sandbox composition keyless smoke (real cordis.yml via the Loa
spawned = spawnAcpAgent(workdir, 'reject-once')
const { client } = spawned
await client.initialize({ protocolVersion: PROTOCOL_VERSION, clientCapabilities: {} })
// This tree composes the permission presets over bash-sandbox + approval →
// ONE select advertises, current from the configured default preset.
const created = await client.newSession({ cwd: workdir, mcpServers: [] })
const advertised = created.configOptions ?? []
expect(advertised.map(option => [option.id, 'currentValue' in option ? option.currentValue : undefined]))
.toEqual([['permission', 'workspace-write']])
// A switch responds with the COMPLETE refreshed state (the spec contract),
// and the new current survives in the response of a second switch.
const afterFullAccess = await client.setSessionConfigOption({
sessionId: created.sessionId, configId: 'permission', value: 'danger-full-access',
})
@@ -153,7 +134,6 @@ describe('default sandbox composition keyless smoke (real cordis.yml via the Loa
})
expect((again.configOptions ?? []).map(option => [option.id, 'currentValue' in option ? option.currentValue : undefined]))
.toEqual([['permission', 'danger-full-access']])
// An out-of-vocabulary value is a protocol error, never a silent default.
await expect(client.setSessionConfigOption({
sessionId: created.sessionId, configId: 'permission', value: 'plan',
})).rejects.toThrow(/unknown permission value/)
@@ -175,13 +155,11 @@ describe.skipIf(!process.env.DEEPSEEK_API_KEY || !hasRunner)('default sandbox co
})
expect(['end_turn', 'max_tokens']).toContain(res.stopReason)
// The WORLD: the approved escalated retry landed the write.
// Verify the filesystem, not the model's report.
const proof = await readFile(join(workdir, 'escalated.txt'), 'utf8')
expect(proof).toContain('ACP_ESCALATION_OK')
// The CHANNEL: the grant came through a real session/request_permission
// prompt attached to the escalating tool call, offering exactly the
// one-shot options.
// Verify that ACP carried the grant with only one-shot choices.
expect(permissionRequests.length).toBeGreaterThan(0)
const prompt = permissionRequests[0]
if (prompt === undefined) throw new Error('expected a permission request')
@@ -204,9 +182,8 @@ describe.skipIf(!process.env.DEEPSEEK_API_KEY || !hasRunner)('default sandbox co
})
expect(['end_turn', 'max_tokens']).toContain(res.stopReason)
// The WORLD: rejected means the file never appeared.
await expect(readFile(join(workdir, 'refused.txt'), 'utf8')).rejects.toThrow()
// And the rejection really flowed through a prompt (not a missing channel).
// Distinguish a user rejection from a missing approval channel.
expect(permissionRequests.length).toBeGreaterThan(0)
}, 240_000)
})

View File

@@ -17,21 +17,10 @@ import {
} from '@agentclientprotocol/sdk'
/**
* With-key e2e: the Claude Code hook bridge running against the REAL acp-agent
* subprocess and the REAL model. The example `cordis.yml` loads `dsh-hooks-claude`
* with a PROCESS-LEVEL `configPath` of `./hooks.json`, resolved once at load
* against the ACP server's launch cwd (NOT per-session); this test sets that
* launch cwd to the temp workspace and writes a `hooks.json` there with a
* PreToolUse hook that BLOCKS every bash command, then asks the live model to
* write a file — and verifies the WORLD (the file never appears on disk),
* proving the hook actually intercepted execution rather than the agent merely
* claiming it couldn't. (The hook itself then runs in the session cwd.)
* Key-gated; owns and disposes its subprocess.
*
* A keyless companion lives in acp.e2e.ts (stdout purity + session/new); the
* full hook-fires-end-to-end transcript is the keyless `hook-cc-promptsubmit-block`
* snapshot scenario. This one closes the "green plumbing, broken product" gap:
* only a real model deciding to call bash exercises the PreToolUse seam live.
* With-key e2e for the Claude hook bridge. The process-level `./hooks.json` is
* resolved from a temporary launch cwd and blocks all PreToolUse calls; a real
* model is asked to write there, and absence of the file proves interception.
* The test owns and disposes the ACP subprocess.
*/
const binScript = fileURLToPath(new URL('../../../packages/ui/acp-agent/src/bin.ts', import.meta.url))
@@ -89,9 +78,8 @@ afterEach(async () => {
describe.skipIf(!process.env.DEEPSEEK_API_KEY)('acp-agent e2e: a PreToolUse hook blocks bash (real model)', () => {
it('denies every bash command, so the requested file is never written (verified on disk)', async () => {
workdir = await mkdtemp(join(tmpdir(), 'acp-hooks-e2e-'))
// A PreToolUse hook that blocks EVERY tool (exit 2, no matcher = match-all).
// The session cwd is `workdir`, and the bridge resolves `./hooks.json` from
// the process cwd (the launch dir = workdir), so this is the config it loads.
// `configPath` is process-relative, so placing the match-all hook in the
// launch cwd selects it; hook commands themselves run in the session cwd.
await writeFile(join(workdir, 'hooks.json'), JSON.stringify({
hooks: { PreToolUse: [{ hooks: [{ type: 'command', command: 'echo "bash blocked by policy" >&2; exit 2' }] }] },
}))
@@ -110,12 +98,10 @@ describe.skipIf(!process.env.DEEPSEEK_API_KEY)('acp-agent e2e: a PreToolUse hook
// the model, not a turn failure).
expect(['end_turn', 'max_tokens']).toContain(res.stopReason)
// Verify the WORLD: the hook denied execution, so the file must NOT exist —
// a keyword probe a "cheating" agent could fake in prose cannot pass this.
// Verify that the denied hook left no filesystem effect.
await expect(access(join(workdir, 'proof.txt'))).rejects.toThrow()
// The client still saw a tool_call stream (the model TRIED), and its result
// carried the hook's block reason back as an error.
// A blocked call is still streamed with the hook's reason as an error.
const toolCalls = updates.filter(u => u.sessionUpdate === 'tool_call' || u.sessionUpdate === 'tool_call_update')
expect(toolCalls.length).toBeGreaterThan(0)
}, 180_000)

View File

@@ -1,5 +1,5 @@
{"jsonrpc":"2.0","id":1,"result":{"protocolVersion":1,"agentInfo":{"name":"deepseek-harness-acp","version":"0.0.1"},"agentCapabilities":{"loadSession":true,"promptCapabilities":{"image":false,"audio":false,"embeddedContext":false}},"authMethods":[]}}
{"jsonrpc":"2.0","id":2,"result":{"sessionId":"{{sessionId}}","configOptions":[{"id":"permission","name":"Permissions","description":"The session permission preset: each choice bundles a sandbox mode and an approval policy.","category":"mode","type":"select","currentValue":"danger-full-access","options":[{"value":"workspace-write","name":"workspace-write","description":"Write inside the workspace; anything wider asks for your approval."},{"value":"danger-full-access","name":"danger-full-access","description":"Full file access, no approval prompts."}]}]}}
{"jsonrpc":"2.0","id":2,"result":{"sessionId":"{{sessionId}}","configOptions":[{"id":"permission","name":"Permissions","description":"Sets this session's sandbox and approval behavior.","category":"mode","type":"select","currentValue":"danger-full-access","options":[{"value":"workspace-write","name":"workspace-write","description":"Write inside the workspace and permitted temporary directories; wider retries require approval."},{"value":"danger-full-access","name":"danger-full-access","description":"Full file access without approval prompts."}]}]}}
{"jsonrpc":"2.0","method":"session/update","params":{"sessionId":"{{sessionId}}","update":{"sessionUpdate":"tool_call","toolCallId":"advanced-mount","title":"Mount plugin into live cordis runtime","kind":"execute","status":"in_progress","rawInput":{"code":"return { name: 'snapshot-marker', apply() {} }"}}}}
{"jsonrpc":"2.0","method":"session/update","params":{"sessionId":"{{sessionId}}","update":{"sessionUpdate":"tool_call_update","toolCallId":"advanced-mount","status":"completed","content":[{"type":"content","content":{"type":"text","text":"mounted dyn-1 (plugin \"snapshot-marker\", state: active)"}}]}}}
{"jsonrpc":"2.0","method":"session/update","params":{"sessionId":"{{sessionId}}","update":{"sessionUpdate":"tool_call","toolCallId":"advanced-code","title":"return await tools.cordis_inspect({ what: 'dynamic' })","kind":"execute","status":"in_progress","rawInput":"return await tools.cordis_inspect({ what: 'dynamic' })"}}}

View File

@@ -1,5 +1,5 @@
{"jsonrpc":"2.0","id":1,"result":{"protocolVersion":1,"agentInfo":{"name":"deepseek-harness-acp","version":"0.0.1"},"agentCapabilities":{"loadSession":true,"promptCapabilities":{"image":false,"audio":false,"embeddedContext":false}},"authMethods":[]}}
{"jsonrpc":"2.0","id":2,"result":{"sessionId":"{{sessionId}}","configOptions":[{"id":"permission","name":"Permissions","description":"The session permission preset: each choice bundles a sandbox mode and an approval policy.","category":"mode","type":"select","currentValue":"danger-full-access","options":[{"value":"workspace-write","name":"workspace-write","description":"Write inside the workspace; anything wider asks for your approval."},{"value":"danger-full-access","name":"danger-full-access","description":"Full file access, no approval prompts."}]}]}}
{"jsonrpc":"2.0","id":2,"result":{"sessionId":"{{sessionId}}","configOptions":[{"id":"permission","name":"Permissions","description":"Sets this session's sandbox and approval behavior.","category":"mode","type":"select","currentValue":"danger-full-access","options":[{"value":"workspace-write","name":"workspace-write","description":"Write inside the workspace and permitted temporary directories; wider retries require approval."},{"value":"danger-full-access","name":"danger-full-access","description":"Full file access without approval prompts."}]}]}}
{"jsonrpc":"2.0","method":"session/update","params":{"sessionId":"{{sessionId}}","update":{"sessionUpdate":"agent_thought_chunk","content":{"type":"text","text":"The"}}}}
{"jsonrpc":"2.0","method":"session/update","params":{"sessionId":"{{sessionId}}","update":{"sessionUpdate":"agent_thought_chunk","content":{"type":"text","text":" user"}}}}
{"jsonrpc":"2.0","method":"session/update","params":{"sessionId":"{{sessionId}}","update":{"sessionUpdate":"agent_thought_chunk","content":{"type":"text","text":" wants"}}}}

View File

@@ -1,4 +1,4 @@
{"jsonrpc":"2.0","id":1,"result":{"protocolVersion":1,"agentInfo":{"name":"deepseek-harness-acp","version":"0.0.1"},"agentCapabilities":{"loadSession":true,"promptCapabilities":{"image":false,"audio":false,"embeddedContext":false}},"authMethods":[]}}
{"jsonrpc":"2.0","id":2,"result":{"sessionId":"{{sessionId}}","configOptions":[{"id":"permission","name":"Permissions","description":"The session permission preset: each choice bundles a sandbox mode and an approval policy.","category":"mode","type":"select","currentValue":"danger-full-access","options":[{"value":"workspace-write","name":"workspace-write","description":"Write inside the workspace; anything wider asks for your approval."},{"value":"danger-full-access","name":"danger-full-access","description":"Full file access, no approval prompts."}]}]}}
{"jsonrpc":"2.0","id":2,"result":{"sessionId":"{{sessionId}}","configOptions":[{"id":"permission","name":"Permissions","description":"Sets this session's sandbox and approval behavior.","category":"mode","type":"select","currentValue":"danger-full-access","options":[{"value":"workspace-write","name":"workspace-write","description":"Write inside the workspace and permitted temporary directories; wider retries require approval."},{"value":"danger-full-access","name":"danger-full-access","description":"Full file access without approval prompts."}]}]}}
{"jsonrpc":"2.0","method":"session/update","params":{"sessionId":"{{sessionId}}","update":{"sessionUpdate":"agent_message_chunk","content":{"type":"text","text":"partial"}}}}
{"jsonrpc":"2.0","id":3,"result":{"stopReason":"cancelled"}}

View File

@@ -1,5 +1,5 @@
{"jsonrpc":"2.0","id":1,"result":{"protocolVersion":1,"agentInfo":{"name":"deepseek-harness-acp","version":"0.0.1"},"agentCapabilities":{"loadSession":true,"promptCapabilities":{"image":false,"audio":false,"embeddedContext":false}},"authMethods":[]}}
{"jsonrpc":"2.0","id":2,"result":{"sessionId":"{{sessionId}}","configOptions":[{"id":"permission","name":"Permissions","description":"The session permission preset: each choice bundles a sandbox mode and an approval policy.","category":"mode","type":"select","currentValue":"danger-full-access","options":[{"value":"workspace-write","name":"workspace-write","description":"Write inside the workspace; anything wider asks for your approval."},{"value":"danger-full-access","name":"danger-full-access","description":"Full file access, no approval prompts."}]}]}}
{"jsonrpc":"2.0","id":2,"result":{"sessionId":"{{sessionId}}","configOptions":[{"id":"permission","name":"Permissions","description":"Sets this session's sandbox and approval behavior.","category":"mode","type":"select","currentValue":"danger-full-access","options":[{"value":"workspace-write","name":"workspace-write","description":"Write inside the workspace and permitted temporary directories; wider retries require approval."},{"value":"danger-full-access","name":"danger-full-access","description":"Full file access without approval prompts."}]}]}}
{"jsonrpc":"2.0","method":"session/update","params":{"sessionId":"{{sessionId}}","update":{"sessionUpdate":"agent_thought_chunk","content":{"type":"text","text":"The"}}}}
{"jsonrpc":"2.0","method":"session/update","params":{"sessionId":"{{sessionId}}","update":{"sessionUpdate":"agent_thought_chunk","content":{"type":"text","text":" user"}}}}
{"jsonrpc":"2.0","method":"session/update","params":{"sessionId":"{{sessionId}}","update":{"sessionUpdate":"agent_thought_chunk","content":{"type":"text","text":" wants"}}}}

View File

@@ -1,6 +1,6 @@
{"jsonrpc":"2.0","id":1,"result":{"protocolVersion":1,"agentInfo":{"name":"deepseek-harness-acp","version":"0.0.1"},"agentCapabilities":{"loadSession":true,"promptCapabilities":{"image":false,"audio":false,"embeddedContext":false}},"authMethods":[]}}
{"jsonrpc":"2.0","id":2,"result":{"sessionId":"{{sessionId}}","configOptions":[{"id":"permission","name":"Permissions","description":"The session permission preset: each choice bundles a sandbox mode and an approval policy.","category":"mode","type":"select","currentValue":"danger-full-access","options":[{"value":"workspace-write","name":"workspace-write","description":"Write inside the workspace; anything wider asks for your approval."},{"value":"danger-full-access","name":"danger-full-access","description":"Full file access, no approval prompts."}]}]}}
{"jsonrpc":"2.0","id":3,"result":{"configOptions":[{"id":"permission","name":"Permissions","description":"The session permission preset: each choice bundles a sandbox mode and an approval policy.","category":"mode","type":"select","currentValue":"workspace-write","options":[{"value":"workspace-write","name":"workspace-write","description":"Write inside the workspace; anything wider asks for your approval."},{"value":"danger-full-access","name":"danger-full-access","description":"Full file access, no approval prompts."}]}]}}
{"jsonrpc":"2.0","id":4,"result":{"configOptions":[{"id":"permission","name":"Permissions","description":"The session permission preset: each choice bundles a sandbox mode and an approval policy.","category":"mode","type":"select","currentValue":"danger-full-access","options":[{"value":"workspace-write","name":"workspace-write","description":"Write inside the workspace; anything wider asks for your approval."},{"value":"danger-full-access","name":"danger-full-access","description":"Full file access, no approval prompts."}]}]}}
{"jsonrpc":"2.0","id":2,"result":{"sessionId":"{{sessionId}}","configOptions":[{"id":"permission","name":"Permissions","description":"Sets this session's sandbox and approval behavior.","category":"mode","type":"select","currentValue":"danger-full-access","options":[{"value":"workspace-write","name":"workspace-write","description":"Write inside the workspace and permitted temporary directories; wider retries require approval."},{"value":"danger-full-access","name":"danger-full-access","description":"Full file access without approval prompts."}]}]}}
{"jsonrpc":"2.0","id":3,"result":{"configOptions":[{"id":"permission","name":"Permissions","description":"Sets this session's sandbox and approval behavior.","category":"mode","type":"select","currentValue":"workspace-write","options":[{"value":"workspace-write","name":"workspace-write","description":"Write inside the workspace and permitted temporary directories; wider retries require approval."},{"value":"danger-full-access","name":"danger-full-access","description":"Full file access without approval prompts."}]}]}}
{"jsonrpc":"2.0","id":4,"result":{"configOptions":[{"id":"permission","name":"Permissions","description":"Sets this session's sandbox and approval behavior.","category":"mode","type":"select","currentValue":"danger-full-access","options":[{"value":"workspace-write","name":"workspace-write","description":"Write inside the workspace and permitted temporary directories; wider retries require approval."},{"value":"danger-full-access","name":"danger-full-access","description":"Full file access without approval prompts."}]}]}}
{"jsonrpc":"2.0","id":5,"error":{"code":-32602,"message":"Invalid params: unknown permission value \"plan\""}}
{"jsonrpc":"2.0","id":6,"error":{"code":-32602,"message":"Invalid params: unknown config option \"reasoning-effort\""}}

View File

@@ -1,3 +1,3 @@
{"jsonrpc":"2.0","id":1,"result":{"protocolVersion":1,"agentInfo":{"name":"deepseek-harness-acp","version":"0.0.1"},"agentCapabilities":{"loadSession":true,"promptCapabilities":{"image":false,"audio":false,"embeddedContext":false}},"authMethods":[]}}
{"jsonrpc":"2.0","id":2,"result":{"sessionId":"{{sessionId}}","configOptions":[{"id":"permission","name":"Permissions","description":"The session permission preset: each choice bundles a sandbox mode and an approval policy.","category":"mode","type":"select","currentValue":"danger-full-access","options":[{"value":"workspace-write","name":"workspace-write","description":"Write inside the workspace; anything wider asks for your approval."},{"value":"danger-full-access","name":"danger-full-access","description":"Full file access, no approval prompts."}]}]}}
{"jsonrpc":"2.0","id":2,"result":{"sessionId":"{{sessionId}}","configOptions":[{"id":"permission","name":"Permissions","description":"Sets this session's sandbox and approval behavior.","category":"mode","type":"select","currentValue":"danger-full-access","options":[{"value":"workspace-write","name":"workspace-write","description":"Write inside the workspace and permitted temporary directories; wider retries require approval."},{"value":"danger-full-access","name":"danger-full-access","description":"Full file access without approval prompts."}]}]}}
{"jsonrpc":"2.0","id":3,"error":{"code":-32603,"message":"Internal error: turn failed: simulated provider error (HTTP 401)"}}

View File

@@ -131,8 +131,8 @@
{"type":"assistant/chunk","seq":129,"time":1783962245385,"data":{"turn":1,"step":1,"chunk":{"type":"finish","reason":{"kind":"tool-calls"}}}}
{"type":"assistant/message","seq":130,"time":1783962245385,"data":{"turn":1,"step":1,"content":[{"type":"reasoning","text":"The user wants me to run a command with sandbox_permissions set to danger-full-access, no prior run needed, justified as instructed."},{"type":"tool-call","id":"call_00_d0sAHpJ9mYOJi0z7KNy30441","name":"bash","arguments":"{\"command\": \"printf 'escalated\\\\n' > /tmp/dsh-escalated.txt && cat /tmp/dsh-escalated.txt && rm /tmp/dsh-escalated.txt\", \"description\": \"Write file outside workspace and verify\", \"sandbox_permissions\": \"danger-full-access\", \"justification\": \"the user asked to write a file outside the workspace\"}"}],"usage":{"inputTokens":1501,"outputTokens":174,"cacheReadTokens":0,"reasoningTokens":28}},"sourceEventSeqs":[7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129],"surfaceOp":"append"}
{"type":"tool/call","seq":131,"time":1783962245385,"data":{"turn":1,"step":1,"callId":"call_00_d0sAHpJ9mYOJi0z7KNy30441","name":"bash","arguments":"{\"command\": \"printf 'escalated\\\\n' > /tmp/dsh-escalated.txt && cat /tmp/dsh-escalated.txt && rm /tmp/dsh-escalated.txt\", \"description\": \"Write file outside workspace and verify\", \"sandbox_permissions\": \"danger-full-access\", \"justification\": \"the user asked to write a file outside the workspace\"}"}}
{"type":"approval/asked","seq":132,"time":1783962245386,"data":{"id":"0dfc6fba-ccdf-4233-8b48-87003f0b75b7","toolName":"bash","callId":"call_00_d0sAHpJ9mYOJi0z7KNy30441","reason":"escalate sandbox to danger-full-access: the user asked to write a file outside the workspace"}}
{"type":"approval/decided","seq":133,"time":1783962245387,"data":{"id":"0dfc6fba-ccdf-4233-8b48-87003f0b75b7","outcome":"allowed-once"}}
{"type":"approval/asked","seq":132,"time":1783962245386,"data":{"id":"c1064cdf-2f1e-4ce7-a414-90be20d8727b","toolName":"bash","callId":"call_00_d0sAHpJ9mYOJi0z7KNy30441","reason":"escalate sandbox to danger-full-access: the user asked to write a file outside the workspace"}}
{"type":"approval/decided","seq":133,"time":1783962245387,"data":{"id":"c1064cdf-2f1e-4ce7-a414-90be20d8727b","outcome":"allowed-once"}}
{"type":"tool/result","seq":134,"time":1783962245399,"data":{"turn":1,"step":1,"callId":"call_00_d0sAHpJ9mYOJi0z7KNy30441","content":[{"type":"text","text":"escalated\n"}],"isError":false},"sourceEventSeqs":[131],"surfaceOp":"append"}
{"type":"step/end","seq":135,"time":1783962245400,"data":{"turn":1,"step":1}}
{"type":"step/start","seq":136,"time":1783962245400,"data":{"turn":1,"step":2}}

View File

@@ -1,6 +1,6 @@
{"jsonrpc":"2.0","id":1,"result":{"protocolVersion":1,"agentInfo":{"name":"deepseek-harness-acp","version":"0.0.1"},"agentCapabilities":{"loadSession":true,"promptCapabilities":{"image":false,"audio":false,"embeddedContext":false}},"authMethods":[]}}
{"jsonrpc":"2.0","id":2,"result":{"sessionId":"{{sessionId}}","configOptions":[{"id":"permission","name":"Permissions","description":"The session permission preset: each choice bundles a sandbox mode and an approval policy.","category":"mode","type":"select","currentValue":"danger-full-access","options":[{"value":"workspace-write","name":"workspace-write","description":"Write inside the workspace; anything wider asks for your approval."},{"value":"danger-full-access","name":"danger-full-access","description":"Full file access, no approval prompts."}]}]}}
{"jsonrpc":"2.0","id":3,"result":{"configOptions":[{"id":"permission","name":"Permissions","description":"The session permission preset: each choice bundles a sandbox mode and an approval policy.","category":"mode","type":"select","currentValue":"workspace-write","options":[{"value":"workspace-write","name":"workspace-write","description":"Write inside the workspace; anything wider asks for your approval."},{"value":"danger-full-access","name":"danger-full-access","description":"Full file access, no approval prompts."}]}]}}
{"jsonrpc":"2.0","id":2,"result":{"sessionId":"{{sessionId}}","configOptions":[{"id":"permission","name":"Permissions","description":"Sets this session's sandbox and approval behavior.","category":"mode","type":"select","currentValue":"danger-full-access","options":[{"value":"workspace-write","name":"workspace-write","description":"Write inside the workspace and permitted temporary directories; wider retries require approval."},{"value":"danger-full-access","name":"danger-full-access","description":"Full file access without approval prompts."}]}]}}
{"jsonrpc":"2.0","id":3,"result":{"configOptions":[{"id":"permission","name":"Permissions","description":"Sets this session's sandbox and approval behavior.","category":"mode","type":"select","currentValue":"workspace-write","options":[{"value":"workspace-write","name":"workspace-write","description":"Write inside the workspace and permitted temporary directories; wider retries require approval."},{"value":"danger-full-access","name":"danger-full-access","description":"Full file access without approval prompts."}]}]}}
{"jsonrpc":"2.0","method":"session/update","params":{"sessionId":"{{sessionId}}","update":{"sessionUpdate":"agent_thought_chunk","content":{"type":"text","text":"The"}}}}
{"jsonrpc":"2.0","method":"session/update","params":{"sessionId":"{{sessionId}}","update":{"sessionUpdate":"agent_thought_chunk","content":{"type":"text","text":" user"}}}}
{"jsonrpc":"2.0","method":"session/update","params":{"sessionId":"{{sessionId}}","update":{"sessionUpdate":"agent_thought_chunk","content":{"type":"text","text":" wants"}}}}

View File

@@ -155,8 +155,8 @@
{"type":"assistant/chunk","seq":153,"time":1783962246274,"data":{"turn":1,"step":1,"chunk":{"type":"finish","reason":{"kind":"tool-calls"}}}}
{"type":"assistant/message","seq":154,"time":1783962246274,"data":{"turn":1,"step":1,"content":[{"type":"reasoning","text":"The user wants me to run a specific command with `sandbox_permissions` set to `danger-full-access` and a specific justification. They explicitly said NOT to run it without sandbox_permissions first. Let me do exactly that."},{"type":"tool-call","id":"call_00_WB1vnPomi8yr6MlcFKTj7912","name":"bash","arguments":"{\"command\": \"printf 'escalated\\\\n' > /tmp/dsh-escalated.txt && cat /tmp/dsh-escalated.txt && rm /tmp/dsh-escalated.txt\", \"description\": \"Write to /tmp and verify, then clean up\", \"sandbox_permissions\": \"danger-full-access\", \"justification\": \"the user asked to write a file outside the workspace\"}"}],"usage":{"inputTokens":1509,"outputTokens":198,"cacheReadTokens":0,"reasoningTokens":48}},"sourceEventSeqs":[7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153],"surfaceOp":"append"}
{"type":"tool/call","seq":155,"time":1783962246274,"data":{"turn":1,"step":1,"callId":"call_00_WB1vnPomi8yr6MlcFKTj7912","name":"bash","arguments":"{\"command\": \"printf 'escalated\\\\n' > /tmp/dsh-escalated.txt && cat /tmp/dsh-escalated.txt && rm /tmp/dsh-escalated.txt\", \"description\": \"Write to /tmp and verify, then clean up\", \"sandbox_permissions\": \"danger-full-access\", \"justification\": \"the user asked to write a file outside the workspace\"}"}}
{"type":"approval/asked","seq":156,"time":1783962246275,"data":{"id":"5b59a78f-4b4c-400b-b7f7-d8f689f75854","toolName":"bash","callId":"call_00_WB1vnPomi8yr6MlcFKTj7912","reason":"escalate sandbox to danger-full-access: the user asked to write a file outside the workspace"}}
{"type":"approval/decided","seq":157,"time":1783962246275,"data":{"id":"5b59a78f-4b4c-400b-b7f7-d8f689f75854","outcome":"rejected"}}
{"type":"approval/asked","seq":156,"time":1783962246275,"data":{"id":"7545baed-a236-4325-852a-b892fe176a8c","toolName":"bash","callId":"call_00_WB1vnPomi8yr6MlcFKTj7912","reason":"escalate sandbox to danger-full-access: the user asked to write a file outside the workspace"}}
{"type":"approval/decided","seq":157,"time":1783962246275,"data":{"id":"7545baed-a236-4325-852a-b892fe176a8c","outcome":"rejected"}}
{"type":"tool/result","seq":158,"time":1783962246275,"data":{"turn":1,"step":1,"callId":"call_00_WB1vnPomi8yr6MlcFKTj7912","content":[{"type":"text","text":"Error: the user rejected escalating this command to \"danger-full-access\""}],"isError":true},"sourceEventSeqs":[155],"surfaceOp":"append"}
{"type":"step/end","seq":159,"time":1783962246276,"data":{"turn":1,"step":1}}
{"type":"step/start","seq":160,"time":1783962246276,"data":{"turn":1,"step":2}}

View File

@@ -1,6 +1,6 @@
{"jsonrpc":"2.0","id":1,"result":{"protocolVersion":1,"agentInfo":{"name":"deepseek-harness-acp","version":"0.0.1"},"agentCapabilities":{"loadSession":true,"promptCapabilities":{"image":false,"audio":false,"embeddedContext":false}},"authMethods":[]}}
{"jsonrpc":"2.0","id":2,"result":{"sessionId":"{{sessionId}}","configOptions":[{"id":"permission","name":"Permissions","description":"The session permission preset: each choice bundles a sandbox mode and an approval policy.","category":"mode","type":"select","currentValue":"danger-full-access","options":[{"value":"workspace-write","name":"workspace-write","description":"Write inside the workspace; anything wider asks for your approval."},{"value":"danger-full-access","name":"danger-full-access","description":"Full file access, no approval prompts."}]}]}}
{"jsonrpc":"2.0","id":3,"result":{"configOptions":[{"id":"permission","name":"Permissions","description":"The session permission preset: each choice bundles a sandbox mode and an approval policy.","category":"mode","type":"select","currentValue":"workspace-write","options":[{"value":"workspace-write","name":"workspace-write","description":"Write inside the workspace; anything wider asks for your approval."},{"value":"danger-full-access","name":"danger-full-access","description":"Full file access, no approval prompts."}]}]}}
{"jsonrpc":"2.0","id":2,"result":{"sessionId":"{{sessionId}}","configOptions":[{"id":"permission","name":"Permissions","description":"Sets this session's sandbox and approval behavior.","category":"mode","type":"select","currentValue":"danger-full-access","options":[{"value":"workspace-write","name":"workspace-write","description":"Write inside the workspace and permitted temporary directories; wider retries require approval."},{"value":"danger-full-access","name":"danger-full-access","description":"Full file access without approval prompts."}]}]}}
{"jsonrpc":"2.0","id":3,"result":{"configOptions":[{"id":"permission","name":"Permissions","description":"Sets this session's sandbox and approval behavior.","category":"mode","type":"select","currentValue":"workspace-write","options":[{"value":"workspace-write","name":"workspace-write","description":"Write inside the workspace and permitted temporary directories; wider retries require approval."},{"value":"danger-full-access","name":"danger-full-access","description":"Full file access without approval prompts."}]}]}}
{"jsonrpc":"2.0","method":"session/update","params":{"sessionId":"{{sessionId}}","update":{"sessionUpdate":"agent_thought_chunk","content":{"type":"text","text":"The"}}}}
{"jsonrpc":"2.0","method":"session/update","params":{"sessionId":"{{sessionId}}","update":{"sessionUpdate":"agent_thought_chunk","content":{"type":"text","text":" user"}}}}
{"jsonrpc":"2.0","method":"session/update","params":{"sessionId":"{{sessionId}}","update":{"sessionUpdate":"agent_thought_chunk","content":{"type":"text","text":" wants"}}}}

View File

@@ -1,5 +1,5 @@
{"jsonrpc":"2.0","id":1,"result":{"protocolVersion":1,"agentInfo":{"name":"deepseek-harness-acp","version":"0.0.1"},"agentCapabilities":{"loadSession":true,"promptCapabilities":{"image":false,"audio":false,"embeddedContext":false}},"authMethods":[]}}
{"jsonrpc":"2.0","id":2,"result":{"sessionId":"{{sessionId}}","configOptions":[{"id":"permission","name":"Permissions","description":"The session permission preset: each choice bundles a sandbox mode and an approval policy.","category":"mode","type":"select","currentValue":"danger-full-access","options":[{"value":"workspace-write","name":"workspace-write","description":"Write inside the workspace; anything wider asks for your approval."},{"value":"danger-full-access","name":"danger-full-access","description":"Full file access, no approval prompts."}]}]}}
{"jsonrpc":"2.0","id":2,"result":{"sessionId":"{{sessionId}}","configOptions":[{"id":"permission","name":"Permissions","description":"Sets this session's sandbox and approval behavior.","category":"mode","type":"select","currentValue":"danger-full-access","options":[{"value":"workspace-write","name":"workspace-write","description":"Write inside the workspace and permitted temporary directories; wider retries require approval."},{"value":"danger-full-access","name":"danger-full-access","description":"Full file access without approval prompts."}]}]}}
{"jsonrpc":"2.0","method":"session/update","params":{"sessionId":"{{sessionId}}","update":{"sessionUpdate":"agent_thought_chunk","content":{"type":"text","text":"The"}}}}
{"jsonrpc":"2.0","method":"session/update","params":{"sessionId":"{{sessionId}}","update":{"sessionUpdate":"agent_thought_chunk","content":{"type":"text","text":" user"}}}}
{"jsonrpc":"2.0","method":"session/update","params":{"sessionId":"{{sessionId}}","update":{"sessionUpdate":"agent_thought_chunk","content":{"type":"text","text":" wants"}}}}

View File

@@ -1,5 +1,5 @@
{"jsonrpc":"2.0","id":1,"result":{"protocolVersion":1,"agentInfo":{"name":"deepseek-harness-acp","version":"0.0.1"},"agentCapabilities":{"loadSession":true,"promptCapabilities":{"image":false,"audio":false,"embeddedContext":false}},"authMethods":[]}}
{"jsonrpc":"2.0","id":2,"result":{"sessionId":"{{sessionId}}","configOptions":[{"id":"permission","name":"Permissions","description":"The session permission preset: each choice bundles a sandbox mode and an approval policy.","category":"mode","type":"select","currentValue":"danger-full-access","options":[{"value":"workspace-write","name":"workspace-write","description":"Write inside the workspace; anything wider asks for your approval."},{"value":"danger-full-access","name":"danger-full-access","description":"Full file access, no approval prompts."}]}]}}
{"jsonrpc":"2.0","id":2,"result":{"sessionId":"{{sessionId}}","configOptions":[{"id":"permission","name":"Permissions","description":"Sets this session's sandbox and approval behavior.","category":"mode","type":"select","currentValue":"danger-full-access","options":[{"value":"workspace-write","name":"workspace-write","description":"Write inside the workspace and permitted temporary directories; wider retries require approval."},{"value":"danger-full-access","name":"danger-full-access","description":"Full file access without approval prompts."}]}]}}
{"jsonrpc":"2.0","method":"session/update","params":{"sessionId":"{{sessionId}}","update":{"sessionUpdate":"agent_thought_chunk","content":{"type":"text","text":"The"}}}}
{"jsonrpc":"2.0","method":"session/update","params":{"sessionId":"{{sessionId}}","update":{"sessionUpdate":"agent_thought_chunk","content":{"type":"text","text":" user"}}}}
{"jsonrpc":"2.0","method":"session/update","params":{"sessionId":"{{sessionId}}","update":{"sessionUpdate":"agent_thought_chunk","content":{"type":"text","text":" wants"}}}}

View File

@@ -1,5 +1,5 @@
{"jsonrpc":"2.0","id":1,"result":{"protocolVersion":1,"agentInfo":{"name":"deepseek-harness-acp","version":"0.0.1"},"agentCapabilities":{"loadSession":true,"promptCapabilities":{"image":false,"audio":false,"embeddedContext":false}},"authMethods":[]}}
{"jsonrpc":"2.0","id":2,"result":{"sessionId":"{{sessionId}}","configOptions":[{"id":"permission","name":"Permissions","description":"The session permission preset: each choice bundles a sandbox mode and an approval policy.","category":"mode","type":"select","currentValue":"danger-full-access","options":[{"value":"workspace-write","name":"workspace-write","description":"Write inside the workspace; anything wider asks for your approval."},{"value":"danger-full-access","name":"danger-full-access","description":"Full file access, no approval prompts."}]}]}}
{"jsonrpc":"2.0","id":2,"result":{"sessionId":"{{sessionId}}","configOptions":[{"id":"permission","name":"Permissions","description":"Sets this session's sandbox and approval behavior.","category":"mode","type":"select","currentValue":"danger-full-access","options":[{"value":"workspace-write","name":"workspace-write","description":"Write inside the workspace and permitted temporary directories; wider retries require approval."},{"value":"danger-full-access","name":"danger-full-access","description":"Full file access without approval prompts."}]}]}}
{"jsonrpc":"2.0","method":"session/update","params":{"sessionId":"{{sessionId}}","update":{"sessionUpdate":"agent_thought_chunk","content":{"type":"text","text":"The"}}}}
{"jsonrpc":"2.0","method":"session/update","params":{"sessionId":"{{sessionId}}","update":{"sessionUpdate":"agent_thought_chunk","content":{"type":"text","text":" user"}}}}
{"jsonrpc":"2.0","method":"session/update","params":{"sessionId":"{{sessionId}}","update":{"sessionUpdate":"agent_thought_chunk","content":{"type":"text","text":" wants"}}}}

View File

@@ -1,5 +1,5 @@
{"jsonrpc":"2.0","id":1,"result":{"protocolVersion":1,"agentInfo":{"name":"deepseek-harness-acp","version":"0.0.1"},"agentCapabilities":{"loadSession":true,"promptCapabilities":{"image":false,"audio":false,"embeddedContext":false}},"authMethods":[]}}
{"jsonrpc":"2.0","id":2,"result":{"sessionId":"{{sessionId}}","configOptions":[{"id":"permission","name":"Permissions","description":"The session permission preset: each choice bundles a sandbox mode and an approval policy.","category":"mode","type":"select","currentValue":"danger-full-access","options":[{"value":"workspace-write","name":"workspace-write","description":"Write inside the workspace; anything wider asks for your approval."},{"value":"danger-full-access","name":"danger-full-access","description":"Full file access, no approval prompts."}]}]}}
{"jsonrpc":"2.0","id":2,"result":{"sessionId":"{{sessionId}}","configOptions":[{"id":"permission","name":"Permissions","description":"Sets this session's sandbox and approval behavior.","category":"mode","type":"select","currentValue":"danger-full-access","options":[{"value":"workspace-write","name":"workspace-write","description":"Write inside the workspace and permitted temporary directories; wider retries require approval."},{"value":"danger-full-access","name":"danger-full-access","description":"Full file access without approval prompts."}]}]}}
{"jsonrpc":"2.0","method":"session/update","params":{"sessionId":"{{sessionId}}","update":{"sessionUpdate":"agent_thought_chunk","content":{"type":"text","text":"The"}}}}
{"jsonrpc":"2.0","method":"session/update","params":{"sessionId":"{{sessionId}}","update":{"sessionUpdate":"agent_thought_chunk","content":{"type":"text","text":" user"}}}}
{"jsonrpc":"2.0","method":"session/update","params":{"sessionId":"{{sessionId}}","update":{"sessionUpdate":"agent_thought_chunk","content":{"type":"text","text":" wants"}}}}

View File

@@ -1,5 +1,5 @@
{"jsonrpc":"2.0","id":1,"result":{"protocolVersion":1,"agentInfo":{"name":"deepseek-harness-acp","version":"0.0.1"},"agentCapabilities":{"loadSession":true,"promptCapabilities":{"image":false,"audio":false,"embeddedContext":false}},"authMethods":[]}}
{"jsonrpc":"2.0","id":2,"result":{"sessionId":"{{sessionId}}","configOptions":[{"id":"permission","name":"Permissions","description":"The session permission preset: each choice bundles a sandbox mode and an approval policy.","category":"mode","type":"select","currentValue":"danger-full-access","options":[{"value":"workspace-write","name":"workspace-write","description":"Write inside the workspace; anything wider asks for your approval."},{"value":"danger-full-access","name":"danger-full-access","description":"Full file access, no approval prompts."}]}]}}
{"jsonrpc":"2.0","id":2,"result":{"sessionId":"{{sessionId}}","configOptions":[{"id":"permission","name":"Permissions","description":"Sets this session's sandbox and approval behavior.","category":"mode","type":"select","currentValue":"danger-full-access","options":[{"value":"workspace-write","name":"workspace-write","description":"Write inside the workspace and permitted temporary directories; wider retries require approval."},{"value":"danger-full-access","name":"danger-full-access","description":"Full file access without approval prompts."}]}]}}
{"jsonrpc":"2.0","method":"session/update","params":{"sessionId":"{{sessionId}}","update":{"sessionUpdate":"agent_thought_chunk","content":{"type":"text","text":"The"}}}}
{"jsonrpc":"2.0","method":"session/update","params":{"sessionId":"{{sessionId}}","update":{"sessionUpdate":"agent_thought_chunk","content":{"type":"text","text":" user"}}}}
{"jsonrpc":"2.0","method":"session/update","params":{"sessionId":"{{sessionId}}","update":{"sessionUpdate":"agent_thought_chunk","content":{"type":"text","text":" wants"}}}}

View File

@@ -1,5 +1,5 @@
{"jsonrpc":"2.0","id":1,"result":{"protocolVersion":1,"agentInfo":{"name":"deepseek-harness-acp","version":"0.0.1"},"agentCapabilities":{"loadSession":true,"promptCapabilities":{"image":false,"audio":false,"embeddedContext":false}},"authMethods":[]}}
{"jsonrpc":"2.0","id":2,"result":{"sessionId":"{{sessionId}}","configOptions":[{"id":"permission","name":"Permissions","description":"The session permission preset: each choice bundles a sandbox mode and an approval policy.","category":"mode","type":"select","currentValue":"danger-full-access","options":[{"value":"workspace-write","name":"workspace-write","description":"Write inside the workspace; anything wider asks for your approval."},{"value":"danger-full-access","name":"danger-full-access","description":"Full file access, no approval prompts."}]}]}}
{"jsonrpc":"2.0","id":2,"result":{"sessionId":"{{sessionId}}","configOptions":[{"id":"permission","name":"Permissions","description":"Sets this session's sandbox and approval behavior.","category":"mode","type":"select","currentValue":"danger-full-access","options":[{"value":"workspace-write","name":"workspace-write","description":"Write inside the workspace and permitted temporary directories; wider retries require approval."},{"value":"danger-full-access","name":"danger-full-access","description":"Full file access without approval prompts."}]}]}}
{"jsonrpc":"2.0","method":"session/update","params":{"sessionId":"{{sessionId}}","update":{"sessionUpdate":"agent_thought_chunk","content":{"type":"text","text":"The"}}}}
{"jsonrpc":"2.0","method":"session/update","params":{"sessionId":"{{sessionId}}","update":{"sessionUpdate":"agent_thought_chunk","content":{"type":"text","text":" user"}}}}
{"jsonrpc":"2.0","method":"session/update","params":{"sessionId":"{{sessionId}}","update":{"sessionUpdate":"agent_thought_chunk","content":{"type":"text","text":" wants"}}}}

View File

@@ -1,5 +1,5 @@
{"jsonrpc":"2.0","id":1,"result":{"protocolVersion":1,"agentInfo":{"name":"deepseek-harness-acp","version":"0.0.1"},"agentCapabilities":{"loadSession":true,"promptCapabilities":{"image":false,"audio":false,"embeddedContext":false}},"authMethods":[]}}
{"jsonrpc":"2.0","id":2,"result":{"sessionId":"{{sessionId}}","configOptions":[{"id":"permission","name":"Permissions","description":"The session permission preset: each choice bundles a sandbox mode and an approval policy.","category":"mode","type":"select","currentValue":"danger-full-access","options":[{"value":"workspace-write","name":"workspace-write","description":"Write inside the workspace; anything wider asks for your approval."},{"value":"danger-full-access","name":"danger-full-access","description":"Full file access, no approval prompts."}]}]}}
{"jsonrpc":"2.0","id":2,"result":{"sessionId":"{{sessionId}}","configOptions":[{"id":"permission","name":"Permissions","description":"Sets this session's sandbox and approval behavior.","category":"mode","type":"select","currentValue":"danger-full-access","options":[{"value":"workspace-write","name":"workspace-write","description":"Write inside the workspace and permitted temporary directories; wider retries require approval."},{"value":"danger-full-access","name":"danger-full-access","description":"Full file access without approval prompts."}]}]}}
{"jsonrpc":"2.0","method":"session/update","params":{"sessionId":"{{sessionId}}","update":{"sessionUpdate":"agent_thought_chunk","content":{"type":"text","text":"The"}}}}
{"jsonrpc":"2.0","method":"session/update","params":{"sessionId":"{{sessionId}}","update":{"sessionUpdate":"agent_thought_chunk","content":{"type":"text","text":" user"}}}}
{"jsonrpc":"2.0","method":"session/update","params":{"sessionId":"{{sessionId}}","update":{"sessionUpdate":"agent_thought_chunk","content":{"type":"text","text":" wants"}}}}

View File

@@ -1,2 +1,2 @@
{"jsonrpc":"2.0","id":1,"result":{"protocolVersion":1,"agentInfo":{"name":"deepseek-harness-acp","version":"0.0.1"},"agentCapabilities":{"loadSession":true,"promptCapabilities":{"image":false,"audio":false,"embeddedContext":false}},"authMethods":[]}}
{"jsonrpc":"2.0","id":2,"result":{"sessionId":"{{sessionId}}","configOptions":[{"id":"permission","name":"Permissions","description":"The session permission preset: each choice bundles a sandbox mode and an approval policy.","category":"mode","type":"select","currentValue":"danger-full-access","options":[{"value":"workspace-write","name":"workspace-write","description":"Write inside the workspace; anything wider asks for your approval."},{"value":"danger-full-access","name":"danger-full-access","description":"Full file access, no approval prompts."}]}]}}
{"jsonrpc":"2.0","id":2,"result":{"sessionId":"{{sessionId}}","configOptions":[{"id":"permission","name":"Permissions","description":"Sets this session's sandbox and approval behavior.","category":"mode","type":"select","currentValue":"danger-full-access","options":[{"value":"workspace-write","name":"workspace-write","description":"Write inside the workspace and permitted temporary directories; wider retries require approval."},{"value":"danger-full-access","name":"danger-full-access","description":"Full file access without approval prompts."}]}]}}

View File

@@ -1,5 +1,5 @@
{"jsonrpc":"2.0","id":1,"result":{"protocolVersion":1,"agentInfo":{"name":"deepseek-harness-acp","version":"0.0.1"},"agentCapabilities":{"loadSession":true,"promptCapabilities":{"image":false,"audio":false,"embeddedContext":false}},"authMethods":[]}}
{"jsonrpc":"2.0","id":2,"result":{"sessionId":"{{sessionId}}","configOptions":[{"id":"permission","name":"Permissions","description":"The session permission preset: each choice bundles a sandbox mode and an approval policy.","category":"mode","type":"select","currentValue":"danger-full-access","options":[{"value":"workspace-write","name":"workspace-write","description":"Write inside the workspace; anything wider asks for your approval."},{"value":"danger-full-access","name":"danger-full-access","description":"Full file access, no approval prompts."}]}]}}
{"jsonrpc":"2.0","id":2,"result":{"sessionId":"{{sessionId}}","configOptions":[{"id":"permission","name":"Permissions","description":"Sets this session's sandbox and approval behavior.","category":"mode","type":"select","currentValue":"danger-full-access","options":[{"value":"workspace-write","name":"workspace-write","description":"Write inside the workspace and permitted temporary directories; wider retries require approval."},{"value":"danger-full-access","name":"danger-full-access","description":"Full file access without approval prompts."}]}]}}
{"jsonrpc":"2.0","method":"session/update","params":{"sessionId":"{{sessionId}}","update":{"sessionUpdate":"agent_thought_chunk","content":{"type":"text","text":"The"}}}}
{"jsonrpc":"2.0","method":"session/update","params":{"sessionId":"{{sessionId}}","update":{"sessionUpdate":"agent_thought_chunk","content":{"type":"text","text":" user"}}}}
{"jsonrpc":"2.0","method":"session/update","params":{"sessionId":"{{sessionId}}","update":{"sessionUpdate":"agent_thought_chunk","content":{"type":"text","text":" wants"}}}}

View File

@@ -1,5 +1,5 @@
{"jsonrpc":"2.0","id":1,"result":{"protocolVersion":1,"agentInfo":{"name":"deepseek-harness-acp","version":"0.0.1"},"agentCapabilities":{"loadSession":true,"promptCapabilities":{"image":false,"audio":false,"embeddedContext":false}},"authMethods":[]}}
{"jsonrpc":"2.0","id":2,"result":{"sessionId":"{{sessionId}}","configOptions":[{"id":"permission","name":"Permissions","description":"The session permission preset: each choice bundles a sandbox mode and an approval policy.","category":"mode","type":"select","currentValue":"danger-full-access","options":[{"value":"workspace-write","name":"workspace-write","description":"Write inside the workspace; anything wider asks for your approval."},{"value":"danger-full-access","name":"danger-full-access","description":"Full file access, no approval prompts."}]}]}}
{"jsonrpc":"2.0","id":2,"result":{"sessionId":"{{sessionId}}","configOptions":[{"id":"permission","name":"Permissions","description":"Sets this session's sandbox and approval behavior.","category":"mode","type":"select","currentValue":"danger-full-access","options":[{"value":"workspace-write","name":"workspace-write","description":"Write inside the workspace and permitted temporary directories; wider retries require approval."},{"value":"danger-full-access","name":"danger-full-access","description":"Full file access without approval prompts."}]}]}}
{"jsonrpc":"2.0","method":"session/update","params":{"sessionId":"{{sessionId}}","update":{"sessionUpdate":"agent_thought_chunk","content":{"type":"text","text":"The"}}}}
{"jsonrpc":"2.0","method":"session/update","params":{"sessionId":"{{sessionId}}","update":{"sessionUpdate":"agent_thought_chunk","content":{"type":"text","text":" user"}}}}
{"jsonrpc":"2.0","method":"session/update","params":{"sessionId":"{{sessionId}}","update":{"sessionUpdate":"agent_thought_chunk","content":{"type":"text","text":" wants"}}}}

View File

@@ -55,8 +55,8 @@
{"type":"tool/call","seq":53,"time":1783352172557,"data":{"turn":1,"step":1,"callId":"call_00_6k0oGSliVHxGSgqBmMEO4311","name":"bash","arguments":"{\"command\": \"echo HELLO\", \"description\": \"Echo HELLO\"}"}}
{"type":"hook/invoked","seq":54,"time":1783352172558,"data":{"turn":1,"point":"PreToolUse","dialect":"claude","handlerId":"claude:PreToolUse:1","matcher":"bash"}}
{"type":"hook/result","seq":55,"time":1783352172573,"data":{"turn":1,"point":"PreToolUse","handlerId":"claude:PreToolUse:1","decision":"ask","exitCode":0,"durationMs":14.113374999999905}}
{"type":"approval/asked","seq":56,"time":1783962235813,"data":{"id":"f8f9d54e-a313-4719-9950-713e317b29b7","toolName":"bash","callId":"call_00_6k0oGSliVHxGSgqBmMEO4311","reason":"bash requires manual approval in this session"}}
{"type":"approval/decided","seq":57,"time":1783962235813,"data":{"id":"f8f9d54e-a313-4719-9950-713e317b29b7","outcome":"rejected"}}
{"type":"approval/asked","seq":56,"time":1783962235813,"data":{"id":"8ba05227-bb65-4576-8f2e-66a74d607a35","toolName":"bash","callId":"call_00_6k0oGSliVHxGSgqBmMEO4311","reason":"bash requires manual approval in this session"}}
{"type":"approval/decided","seq":57,"time":1783962235813,"data":{"id":"8ba05227-bb65-4576-8f2e-66a74d607a35","outcome":"rejected"}}
{"type":"tool/result","seq":58,"time":1783962235814,"data":{"turn":1,"step":1,"callId":"call_00_6k0oGSliVHxGSgqBmMEO4311","content":[{"type":"text","text":"Error: the user rejected tool \"bash\""}],"isError":true},"sourceEventSeqs":[53],"surfaceOp":"append"}
{"type":"step/end","seq":59,"time":1783962235814,"data":{"turn":1,"step":1}}
{"type":"step/start","seq":60,"time":1783962235814,"data":{"turn":1,"step":2}}

View File

@@ -1,5 +1,5 @@
{"jsonrpc":"2.0","id":1,"result":{"protocolVersion":1,"agentInfo":{"name":"deepseek-harness-acp","version":"0.0.1"},"agentCapabilities":{"loadSession":true,"promptCapabilities":{"image":false,"audio":false,"embeddedContext":false}},"authMethods":[]}}
{"jsonrpc":"2.0","id":2,"result":{"sessionId":"{{sessionId}}","configOptions":[{"id":"permission","name":"Permissions","description":"The session permission preset: each choice bundles a sandbox mode and an approval policy.","category":"mode","type":"select","currentValue":"danger-full-access","options":[{"value":"workspace-write","name":"workspace-write","description":"Write inside the workspace; anything wider asks for your approval."},{"value":"danger-full-access","name":"danger-full-access","description":"Full file access, no approval prompts."}]}]}}
{"jsonrpc":"2.0","id":2,"result":{"sessionId":"{{sessionId}}","configOptions":[{"id":"permission","name":"Permissions","description":"Sets this session's sandbox and approval behavior.","category":"mode","type":"select","currentValue":"danger-full-access","options":[{"value":"workspace-write","name":"workspace-write","description":"Write inside the workspace and permitted temporary directories; wider retries require approval."},{"value":"danger-full-access","name":"danger-full-access","description":"Full file access without approval prompts."}]}]}}
{"jsonrpc":"2.0","method":"session/update","params":{"sessionId":"{{sessionId}}","update":{"sessionUpdate":"agent_thought_chunk","content":{"type":"text","text":"The"}}}}
{"jsonrpc":"2.0","method":"session/update","params":{"sessionId":"{{sessionId}}","update":{"sessionUpdate":"agent_thought_chunk","content":{"type":"text","text":" user"}}}}
{"jsonrpc":"2.0","method":"session/update","params":{"sessionId":"{{sessionId}}","update":{"sessionUpdate":"agent_thought_chunk","content":{"type":"text","text":" wants"}}}}

View File

@@ -1,5 +1,5 @@
{"jsonrpc":"2.0","id":1,"result":{"protocolVersion":1,"agentInfo":{"name":"deepseek-harness-acp","version":"0.0.1"},"agentCapabilities":{"loadSession":true,"promptCapabilities":{"image":false,"audio":false,"embeddedContext":false}},"authMethods":[]}}
{"jsonrpc":"2.0","id":2,"result":{"sessionId":"{{sessionId}}","configOptions":[{"id":"permission","name":"Permissions","description":"The session permission preset: each choice bundles a sandbox mode and an approval policy.","category":"mode","type":"select","currentValue":"danger-full-access","options":[{"value":"workspace-write","name":"workspace-write","description":"Write inside the workspace; anything wider asks for your approval."},{"value":"danger-full-access","name":"danger-full-access","description":"Full file access, no approval prompts."}]}]}}
{"jsonrpc":"2.0","id":2,"result":{"sessionId":"{{sessionId}}","configOptions":[{"id":"permission","name":"Permissions","description":"Sets this session's sandbox and approval behavior.","category":"mode","type":"select","currentValue":"danger-full-access","options":[{"value":"workspace-write","name":"workspace-write","description":"Write inside the workspace and permitted temporary directories; wider retries require approval."},{"value":"danger-full-access","name":"danger-full-access","description":"Full file access without approval prompts."}]}]}}
{"jsonrpc":"2.0","method":"session/update","params":{"sessionId":"{{sessionId}}","update":{"sessionUpdate":"agent_thought_chunk","content":{"type":"text","text":"The"}}}}
{"jsonrpc":"2.0","method":"session/update","params":{"sessionId":"{{sessionId}}","update":{"sessionUpdate":"agent_thought_chunk","content":{"type":"text","text":" user"}}}}
{"jsonrpc":"2.0","method":"session/update","params":{"sessionId":"{{sessionId}}","update":{"sessionUpdate":"agent_thought_chunk","content":{"type":"text","text":" wants"}}}}

View File

@@ -1,3 +1,3 @@
{"jsonrpc":"2.0","id":1,"result":{"protocolVersion":1,"agentInfo":{"name":"deepseek-harness-acp","version":"0.0.1"},"agentCapabilities":{"loadSession":true,"promptCapabilities":{"image":false,"audio":false,"embeddedContext":false}},"authMethods":[]}}
{"jsonrpc":"2.0","id":2,"result":{"sessionId":"{{sessionId}}","configOptions":[{"id":"permission","name":"Permissions","description":"The session permission preset: each choice bundles a sandbox mode and an approval policy.","category":"mode","type":"select","currentValue":"danger-full-access","options":[{"value":"workspace-write","name":"workspace-write","description":"Write inside the workspace; anything wider asks for your approval."},{"value":"danger-full-access","name":"danger-full-access","description":"Full file access, no approval prompts."}]}]}}
{"jsonrpc":"2.0","id":2,"result":{"sessionId":"{{sessionId}}","configOptions":[{"id":"permission","name":"Permissions","description":"Sets this session's sandbox and approval behavior.","category":"mode","type":"select","currentValue":"danger-full-access","options":[{"value":"workspace-write","name":"workspace-write","description":"Write inside the workspace and permitted temporary directories; wider retries require approval."},{"value":"danger-full-access","name":"danger-full-access","description":"Full file access without approval prompts."}]}]}}
{"jsonrpc":"2.0","id":3,"result":{"stopReason":"cancelled"}}

View File

@@ -1,5 +1,5 @@
{"jsonrpc":"2.0","id":1,"result":{"protocolVersion":1,"agentInfo":{"name":"deepseek-harness-acp","version":"0.0.1"},"agentCapabilities":{"loadSession":true,"promptCapabilities":{"image":false,"audio":false,"embeddedContext":false}},"authMethods":[]}}
{"jsonrpc":"2.0","id":2,"result":{"sessionId":"{{sessionId}}","configOptions":[{"id":"permission","name":"Permissions","description":"The session permission preset: each choice bundles a sandbox mode and an approval policy.","category":"mode","type":"select","currentValue":"danger-full-access","options":[{"value":"workspace-write","name":"workspace-write","description":"Write inside the workspace; anything wider asks for your approval."},{"value":"danger-full-access","name":"danger-full-access","description":"Full file access, no approval prompts."}]}]}}
{"jsonrpc":"2.0","id":2,"result":{"sessionId":"{{sessionId}}","configOptions":[{"id":"permission","name":"Permissions","description":"Sets this session's sandbox and approval behavior.","category":"mode","type":"select","currentValue":"danger-full-access","options":[{"value":"workspace-write","name":"workspace-write","description":"Write inside the workspace and permitted temporary directories; wider retries require approval."},{"value":"danger-full-access","name":"danger-full-access","description":"Full file access without approval prompts."}]}]}}
{"jsonrpc":"2.0","method":"session/update","params":{"sessionId":"{{sessionId}}","update":{"sessionUpdate":"agent_thought_chunk","content":{"type":"text","text":"The"}}}}
{"jsonrpc":"2.0","method":"session/update","params":{"sessionId":"{{sessionId}}","update":{"sessionUpdate":"agent_thought_chunk","content":{"type":"text","text":" user"}}}}
{"jsonrpc":"2.0","method":"session/update","params":{"sessionId":"{{sessionId}}","update":{"sessionUpdate":"agent_thought_chunk","content":{"type":"text","text":"'s"}}}}

View File

@@ -1,5 +1,5 @@
{"jsonrpc":"2.0","id":1,"result":{"protocolVersion":1,"agentInfo":{"name":"deepseek-harness-acp","version":"0.0.1"},"agentCapabilities":{"loadSession":true,"promptCapabilities":{"image":false,"audio":false,"embeddedContext":false}},"authMethods":[]}}
{"jsonrpc":"2.0","id":2,"result":{"sessionId":"{{sessionId}}","configOptions":[{"id":"permission","name":"Permissions","description":"The session permission preset: each choice bundles a sandbox mode and an approval policy.","category":"mode","type":"select","currentValue":"danger-full-access","options":[{"value":"workspace-write","name":"workspace-write","description":"Write inside the workspace; anything wider asks for your approval."},{"value":"danger-full-access","name":"danger-full-access","description":"Full file access, no approval prompts."}]}]}}
{"jsonrpc":"2.0","id":2,"result":{"sessionId":"{{sessionId}}","configOptions":[{"id":"permission","name":"Permissions","description":"Sets this session's sandbox and approval behavior.","category":"mode","type":"select","currentValue":"danger-full-access","options":[{"value":"workspace-write","name":"workspace-write","description":"Write inside the workspace and permitted temporary directories; wider retries require approval."},{"value":"danger-full-access","name":"danger-full-access","description":"Full file access without approval prompts."}]}]}}
{"jsonrpc":"2.0","method":"session/update","params":{"sessionId":"{{sessionId}}","update":{"sessionUpdate":"agent_thought_chunk","content":{"type":"text","text":"The"}}}}
{"jsonrpc":"2.0","method":"session/update","params":{"sessionId":"{{sessionId}}","update":{"sessionUpdate":"agent_thought_chunk","content":{"type":"text","text":" user"}}}}
{"jsonrpc":"2.0","method":"session/update","params":{"sessionId":"{{sessionId}}","update":{"sessionUpdate":"agent_thought_chunk","content":{"type":"text","text":" wants"}}}}

View File

@@ -1,5 +1,5 @@
{"jsonrpc":"2.0","id":1,"result":{"protocolVersion":1,"agentInfo":{"name":"deepseek-harness-acp","version":"0.0.1"},"agentCapabilities":{"loadSession":true,"promptCapabilities":{"image":false,"audio":false,"embeddedContext":false}},"authMethods":[]}}
{"jsonrpc":"2.0","id":2,"result":{"sessionId":"{{sessionId}}","configOptions":[{"id":"permission","name":"Permissions","description":"The session permission preset: each choice bundles a sandbox mode and an approval policy.","category":"mode","type":"select","currentValue":"danger-full-access","options":[{"value":"workspace-write","name":"workspace-write","description":"Write inside the workspace; anything wider asks for your approval."},{"value":"danger-full-access","name":"danger-full-access","description":"Full file access, no approval prompts."}]}]}}
{"jsonrpc":"2.0","id":2,"result":{"sessionId":"{{sessionId}}","configOptions":[{"id":"permission","name":"Permissions","description":"Sets this session's sandbox and approval behavior.","category":"mode","type":"select","currentValue":"danger-full-access","options":[{"value":"workspace-write","name":"workspace-write","description":"Write inside the workspace and permitted temporary directories; wider retries require approval."},{"value":"danger-full-access","name":"danger-full-access","description":"Full file access without approval prompts."}]}]}}
{"jsonrpc":"2.0","method":"session/update","params":{"sessionId":"{{sessionId}}","update":{"sessionUpdate":"agent_thought_chunk","content":{"type":"text","text":"The"}}}}
{"jsonrpc":"2.0","method":"session/update","params":{"sessionId":"{{sessionId}}","update":{"sessionUpdate":"agent_thought_chunk","content":{"type":"text","text":" user"}}}}
{"jsonrpc":"2.0","method":"session/update","params":{"sessionId":"{{sessionId}}","update":{"sessionUpdate":"agent_thought_chunk","content":{"type":"text","text":" wants"}}}}

View File

@@ -1,5 +1,5 @@
{"jsonrpc":"2.0","id":1,"result":{"protocolVersion":1,"agentInfo":{"name":"deepseek-harness-acp","version":"0.0.1"},"agentCapabilities":{"loadSession":true,"promptCapabilities":{"image":false,"audio":false,"embeddedContext":false}},"authMethods":[]}}
{"jsonrpc":"2.0","id":2,"result":{"sessionId":"{{sessionId}}","configOptions":[{"id":"permission","name":"Permissions","description":"The session permission preset: each choice bundles a sandbox mode and an approval policy.","category":"mode","type":"select","currentValue":"danger-full-access","options":[{"value":"workspace-write","name":"workspace-write","description":"Write inside the workspace; anything wider asks for your approval."},{"value":"danger-full-access","name":"danger-full-access","description":"Full file access, no approval prompts."}]}]}}
{"jsonrpc":"2.0","id":2,"result":{"sessionId":"{{sessionId}}","configOptions":[{"id":"permission","name":"Permissions","description":"Sets this session's sandbox and approval behavior.","category":"mode","type":"select","currentValue":"danger-full-access","options":[{"value":"workspace-write","name":"workspace-write","description":"Write inside the workspace and permitted temporary directories; wider retries require approval."},{"value":"danger-full-access","name":"danger-full-access","description":"Full file access without approval prompts."}]}]}}
{"jsonrpc":"2.0","method":"session/update","params":{"sessionId":"{{sessionId}}","update":{"sessionUpdate":"agent_thought_chunk","content":{"type":"text","text":"The"}}}}
{"jsonrpc":"2.0","method":"session/update","params":{"sessionId":"{{sessionId}}","update":{"sessionUpdate":"agent_thought_chunk","content":{"type":"text","text":" user"}}}}
{"jsonrpc":"2.0","method":"session/update","params":{"sessionId":"{{sessionId}}","update":{"sessionUpdate":"agent_thought_chunk","content":{"type":"text","text":" wants"}}}}

View File

@@ -1,5 +1,5 @@
{"jsonrpc":"2.0","id":1,"result":{"protocolVersion":1,"agentInfo":{"name":"deepseek-harness-acp","version":"0.0.1"},"agentCapabilities":{"loadSession":true,"promptCapabilities":{"image":false,"audio":false,"embeddedContext":false}},"authMethods":[]}}
{"jsonrpc":"2.0","id":2,"result":{"sessionId":"{{sessionId}}","configOptions":[{"id":"permission","name":"Permissions","description":"The session permission preset: each choice bundles a sandbox mode and an approval policy.","category":"mode","type":"select","currentValue":"danger-full-access","options":[{"value":"workspace-write","name":"workspace-write","description":"Write inside the workspace; anything wider asks for your approval."},{"value":"danger-full-access","name":"danger-full-access","description":"Full file access, no approval prompts."}]}]}}
{"jsonrpc":"2.0","id":2,"result":{"sessionId":"{{sessionId}}","configOptions":[{"id":"permission","name":"Permissions","description":"Sets this session's sandbox and approval behavior.","category":"mode","type":"select","currentValue":"danger-full-access","options":[{"value":"workspace-write","name":"workspace-write","description":"Write inside the workspace and permitted temporary directories; wider retries require approval."},{"value":"danger-full-access","name":"danger-full-access","description":"Full file access without approval prompts."}]}]}}
{"jsonrpc":"2.0","method":"session/update","params":{"sessionId":"{{sessionId}}","update":{"sessionUpdate":"agent_thought_chunk","content":{"type":"text","text":"The"}}}}
{"jsonrpc":"2.0","method":"session/update","params":{"sessionId":"{{sessionId}}","update":{"sessionUpdate":"agent_thought_chunk","content":{"type":"text","text":" user"}}}}
{"jsonrpc":"2.0","method":"session/update","params":{"sessionId":"{{sessionId}}","update":{"sessionUpdate":"agent_thought_chunk","content":{"type":"text","text":" wants"}}}}

View File

@@ -1,3 +1,3 @@
{"jsonrpc":"2.0","id":1,"result":{"protocolVersion":1,"agentInfo":{"name":"deepseek-harness-acp","version":"0.0.1"},"agentCapabilities":{"loadSession":true,"promptCapabilities":{"image":false,"audio":false,"embeddedContext":false}},"authMethods":[]}}
{"jsonrpc":"2.0","id":2,"result":{"sessionId":"{{sessionId}}","configOptions":[{"id":"permission","name":"Permissions","description":"The session permission preset: each choice bundles a sandbox mode and an approval policy.","category":"mode","type":"select","currentValue":"danger-full-access","options":[{"value":"workspace-write","name":"workspace-write","description":"Write inside the workspace; anything wider asks for your approval."},{"value":"danger-full-access","name":"danger-full-access","description":"Full file access, no approval prompts."}]}]}}
{"jsonrpc":"2.0","id":2,"result":{"sessionId":"{{sessionId}}","configOptions":[{"id":"permission","name":"Permissions","description":"Sets this session's sandbox and approval behavior.","category":"mode","type":"select","currentValue":"danger-full-access","options":[{"value":"workspace-write","name":"workspace-write","description":"Write inside the workspace and permitted temporary directories; wider retries require approval."},{"value":"danger-full-access","name":"danger-full-access","description":"Full file access without approval prompts."}]}]}}
{"jsonrpc":"2.0","id":3,"result":{"stopReason":"cancelled"}}

View File

@@ -1,5 +1,5 @@
{"jsonrpc":"2.0","id":1,"result":{"protocolVersion":1,"agentInfo":{"name":"deepseek-harness-acp","version":"0.0.1"},"agentCapabilities":{"loadSession":true,"promptCapabilities":{"image":false,"audio":false,"embeddedContext":false}},"authMethods":[]}}
{"jsonrpc":"2.0","id":2,"result":{"sessionId":"{{sessionId}}","configOptions":[{"id":"permission","name":"Permissions","description":"The session permission preset: each choice bundles a sandbox mode and an approval policy.","category":"mode","type":"select","currentValue":"danger-full-access","options":[{"value":"workspace-write","name":"workspace-write","description":"Write inside the workspace; anything wider asks for your approval."},{"value":"danger-full-access","name":"danger-full-access","description":"Full file access, no approval prompts."}]}]}}
{"jsonrpc":"2.0","id":2,"result":{"sessionId":"{{sessionId}}","configOptions":[{"id":"permission","name":"Permissions","description":"Sets this session's sandbox and approval behavior.","category":"mode","type":"select","currentValue":"danger-full-access","options":[{"value":"workspace-write","name":"workspace-write","description":"Write inside the workspace and permitted temporary directories; wider retries require approval."},{"value":"danger-full-access","name":"danger-full-access","description":"Full file access without approval prompts."}]}]}}
{"jsonrpc":"2.0","method":"session/update","params":{"sessionId":"{{sessionId}}","update":{"sessionUpdate":"agent_thought_chunk","content":{"type":"text","text":"The"}}}}
{"jsonrpc":"2.0","method":"session/update","params":{"sessionId":"{{sessionId}}","update":{"sessionUpdate":"agent_thought_chunk","content":{"type":"text","text":" user"}}}}
{"jsonrpc":"2.0","method":"session/update","params":{"sessionId":"{{sessionId}}","update":{"sessionUpdate":"agent_thought_chunk","content":{"type":"text","text":" asked"}}}}

View File

@@ -1,5 +1,5 @@
{"jsonrpc":"2.0","id":1,"result":{"protocolVersion":1,"agentInfo":{"name":"deepseek-harness-acp","version":"0.0.1"},"agentCapabilities":{"loadSession":true,"promptCapabilities":{"image":false,"audio":false,"embeddedContext":false}},"authMethods":[]}}
{"jsonrpc":"2.0","id":2,"result":{"sessionId":"{{sessionId}}","configOptions":[{"id":"permission","name":"Permissions","description":"The session permission preset: each choice bundles a sandbox mode and an approval policy.","category":"mode","type":"select","currentValue":"danger-full-access","options":[{"value":"workspace-write","name":"workspace-write","description":"Write inside the workspace; anything wider asks for your approval."},{"value":"danger-full-access","name":"danger-full-access","description":"Full file access, no approval prompts."}]}]}}
{"jsonrpc":"2.0","id":2,"result":{"sessionId":"{{sessionId}}","configOptions":[{"id":"permission","name":"Permissions","description":"Sets this session's sandbox and approval behavior.","category":"mode","type":"select","currentValue":"danger-full-access","options":[{"value":"workspace-write","name":"workspace-write","description":"Write inside the workspace and permitted temporary directories; wider retries require approval."},{"value":"danger-full-access","name":"danger-full-access","description":"Full file access without approval prompts."}]}]}}
{"jsonrpc":"2.0","method":"session/update","params":{"sessionId":"{{sessionId}}","update":{"sessionUpdate":"agent_thought_chunk","content":{"type":"text","text":"The"}}}}
{"jsonrpc":"2.0","method":"session/update","params":{"sessionId":"{{sessionId}}","update":{"sessionUpdate":"agent_thought_chunk","content":{"type":"text","text":" user"}}}}
{"jsonrpc":"2.0","method":"session/update","params":{"sessionId":"{{sessionId}}","update":{"sessionUpdate":"agent_thought_chunk","content":{"type":"text","text":" wants"}}}}

View File

@@ -1,5 +1,5 @@
{"jsonrpc":"2.0","id":1,"result":{"protocolVersion":1,"agentInfo":{"name":"deepseek-harness-acp","version":"0.0.1"},"agentCapabilities":{"loadSession":true,"promptCapabilities":{"image":false,"audio":false,"embeddedContext":false}},"authMethods":[]}}
{"jsonrpc":"2.0","id":2,"result":{"sessionId":"{{sessionId}}","configOptions":[{"id":"permission","name":"Permissions","description":"The session permission preset: each choice bundles a sandbox mode and an approval policy.","category":"mode","type":"select","currentValue":"danger-full-access","options":[{"value":"workspace-write","name":"workspace-write","description":"Write inside the workspace; anything wider asks for your approval."},{"value":"danger-full-access","name":"danger-full-access","description":"Full file access, no approval prompts."}]}]}}
{"jsonrpc":"2.0","id":2,"result":{"sessionId":"{{sessionId}}","configOptions":[{"id":"permission","name":"Permissions","description":"Sets this session's sandbox and approval behavior.","category":"mode","type":"select","currentValue":"danger-full-access","options":[{"value":"workspace-write","name":"workspace-write","description":"Write inside the workspace and permitted temporary directories; wider retries require approval."},{"value":"danger-full-access","name":"danger-full-access","description":"Full file access without approval prompts."}]}]}}
{"jsonrpc":"2.0","method":"session/update","params":{"sessionId":"{{sessionId}}","update":{"sessionUpdate":"agent_thought_chunk","content":{"type":"text","text":"The"}}}}
{"jsonrpc":"2.0","method":"session/update","params":{"sessionId":"{{sessionId}}","update":{"sessionUpdate":"agent_thought_chunk","content":{"type":"text","text":" user"}}}}
{"jsonrpc":"2.0","method":"session/update","params":{"sessionId":"{{sessionId}}","update":{"sessionUpdate":"agent_thought_chunk","content":{"type":"text","text":" wants"}}}}

View File

@@ -1,7 +1,7 @@
{"type":"session","version":0,"id":"df041acb-2f14-4d5f-b6e2-2fb6b9eb6427","createdAt":1783860666204,"cwd":"/var/folders/2g/b32ct0qn1d728l_v6tdkjytr0000gn/T/acp-snap-cwd-4oJKT4"}
{"type":"turn/start","seq":0,"time":1783860666206,"data":{"turn":1,"trigger":{"kind":"message","source":{"kind":"user"}}}}
{"type":"permission/preset","seq":1,"time":1783962244578,"data":{"preset":"workspace-write"}}
{"type":"sandbox/mode","seq":2,"time":1784023678825,"data":{"mode":"workspace-write"}}
{"type":"sandbox/mode","seq":2,"time":1784034570500,"data":{"mode":"workspace-write"}}
{"type":"approval/policy","seq":3,"time":1783962244578,"data":{"policy":"ask"}}
{"type":"user/message","seq":4,"time":1783962244578,"data":{"content":[{"type":"text","text":"Use the bash tool to run exactly this one command in a single call: printf 'before\\n' > out.txt && cat out.txt. Then reply with the single word DONE and stop."}],"source":{"kind":"user"}},"surfaceOp":"append"}
{"type":"step/start","seq":5,"time":1783962244579,"data":{"turn":1,"step":1}}
@@ -102,7 +102,7 @@
{"type":"turn/end","seq":100,"time":1783962244601,"data":{"turn":1,"reason":{"kind":"completed"}}}
{"type":"turn/start","seq":101,"time":1783962244623,"data":{"turn":2,"trigger":{"kind":"message","source":{"kind":"user"}}}}
{"type":"permission/preset","seq":102,"time":1783962244624,"data":{"preset":"danger-full-access"}}
{"type":"sandbox/mode","seq":103,"time":1784023678940,"data":{"mode":"danger-full-access"}}
{"type":"sandbox/mode","seq":103,"time":1784034570612,"data":{"mode":"danger-full-access"}}
{"type":"approval/policy","seq":104,"time":1783962244624,"data":{"policy":"never"}}
{"type":"user/message","seq":105,"time":1783962244624,"data":{"content":[{"type":"text","text":"Use the bash tool to run exactly: cat out.txt. Then reply with the single word DONE and stop."}],"source":{"kind":"user"}},"surfaceOp":"append"}
{"type":"context/message","seq":106,"time":1783962244624,"data":{"content":[{"type":"text","text":"The approval policy changed from \"ask\" to \"never\" (changed by the user)."}],"source":{"kind":"plugin","plugin":"user-approval"}},"surfaceOp":"append"}

View File

@@ -1,6 +1,6 @@
{"jsonrpc":"2.0","id":1,"result":{"protocolVersion":1,"agentInfo":{"name":"deepseek-harness-acp","version":"0.0.1"},"agentCapabilities":{"loadSession":true,"promptCapabilities":{"image":false,"audio":false,"embeddedContext":false}},"authMethods":[]}}
{"jsonrpc":"2.0","id":2,"result":{"sessionId":"{{sessionId}}","configOptions":[{"id":"permission","name":"Permissions","description":"The session permission preset: each choice bundles a sandbox mode and an approval policy.","category":"mode","type":"select","currentValue":"danger-full-access","options":[{"value":"workspace-write","name":"workspace-write","description":"Write inside the workspace; anything wider asks for your approval."},{"value":"danger-full-access","name":"danger-full-access","description":"Full file access, no approval prompts."}]}]}}
{"jsonrpc":"2.0","id":3,"result":{"configOptions":[{"id":"permission","name":"Permissions","description":"The session permission preset: each choice bundles a sandbox mode and an approval policy.","category":"mode","type":"select","currentValue":"workspace-write","options":[{"value":"workspace-write","name":"workspace-write","description":"Write inside the workspace; anything wider asks for your approval."},{"value":"danger-full-access","name":"danger-full-access","description":"Full file access, no approval prompts."}]}]}}
{"jsonrpc":"2.0","id":2,"result":{"sessionId":"{{sessionId}}","configOptions":[{"id":"permission","name":"Permissions","description":"Sets this session's sandbox and approval behavior.","category":"mode","type":"select","currentValue":"danger-full-access","options":[{"value":"workspace-write","name":"workspace-write","description":"Write inside the workspace and permitted temporary directories; wider retries require approval."},{"value":"danger-full-access","name":"danger-full-access","description":"Full file access without approval prompts."}]}]}}
{"jsonrpc":"2.0","id":3,"result":{"configOptions":[{"id":"permission","name":"Permissions","description":"Sets this session's sandbox and approval behavior.","category":"mode","type":"select","currentValue":"workspace-write","options":[{"value":"workspace-write","name":"workspace-write","description":"Write inside the workspace and permitted temporary directories; wider retries require approval."},{"value":"danger-full-access","name":"danger-full-access","description":"Full file access without approval prompts."}]}]}}
{"jsonrpc":"2.0","method":"session/update","params":{"sessionId":"{{sessionId}}","update":{"sessionUpdate":"agent_thought_chunk","content":{"type":"text","text":"The"}}}}
{"jsonrpc":"2.0","method":"session/update","params":{"sessionId":"{{sessionId}}","update":{"sessionUpdate":"agent_thought_chunk","content":{"type":"text","text":" user"}}}}
{"jsonrpc":"2.0","method":"session/update","params":{"sessionId":"{{sessionId}}","update":{"sessionUpdate":"agent_thought_chunk","content":{"type":"text","text":" wants"}}}}
@@ -44,7 +44,7 @@
{"jsonrpc":"2.0","method":"session/update","params":{"sessionId":"{{sessionId}}","update":{"sessionUpdate":"agent_message_chunk","content":{"type":"text","text":"D"}}}}
{"jsonrpc":"2.0","method":"session/update","params":{"sessionId":"{{sessionId}}","update":{"sessionUpdate":"agent_message_chunk","content":{"type":"text","text":"ONE"}}}}
{"jsonrpc":"2.0","id":4,"result":{"stopReason":"end_turn"}}
{"jsonrpc":"2.0","id":5,"result":{"configOptions":[{"id":"permission","name":"Permissions","description":"The session permission preset: each choice bundles a sandbox mode and an approval policy.","category":"mode","type":"select","currentValue":"danger-full-access","options":[{"value":"workspace-write","name":"workspace-write","description":"Write inside the workspace; anything wider asks for your approval."},{"value":"danger-full-access","name":"danger-full-access","description":"Full file access, no approval prompts."}]}]}}
{"jsonrpc":"2.0","id":5,"result":{"configOptions":[{"id":"permission","name":"Permissions","description":"Sets this session's sandbox and approval behavior.","category":"mode","type":"select","currentValue":"danger-full-access","options":[{"value":"workspace-write","name":"workspace-write","description":"Write inside the workspace and permitted temporary directories; wider retries require approval."},{"value":"danger-full-access","name":"danger-full-access","description":"Full file access without approval prompts."}]}]}}
{"jsonrpc":"2.0","method":"session/update","params":{"sessionId":"{{sessionId}}","update":{"sessionUpdate":"agent_thought_chunk","content":{"type":"text","text":"The"}}}}
{"jsonrpc":"2.0","method":"session/update","params":{"sessionId":"{{sessionId}}","update":{"sessionUpdate":"agent_thought_chunk","content":{"type":"text","text":" user"}}}}
{"jsonrpc":"2.0","method":"session/update","params":{"sessionId":"{{sessionId}}","update":{"sessionUpdate":"agent_thought_chunk","content":{"type":"text","text":" wants"}}}}

View File

@@ -1,5 +1,5 @@
{"jsonrpc":"2.0","id":1,"result":{"protocolVersion":1,"agentInfo":{"name":"deepseek-harness-acp","version":"0.0.1"},"agentCapabilities":{"loadSession":true,"promptCapabilities":{"image":false,"audio":false,"embeddedContext":false}},"authMethods":[]}}
{"jsonrpc":"2.0","id":2,"result":{"sessionId":"{{sessionId}}","configOptions":[{"id":"permission","name":"Permissions","description":"The session permission preset: each choice bundles a sandbox mode and an approval policy.","category":"mode","type":"select","currentValue":"danger-full-access","options":[{"value":"workspace-write","name":"workspace-write","description":"Write inside the workspace; anything wider asks for your approval."},{"value":"danger-full-access","name":"danger-full-access","description":"Full file access, no approval prompts."}]}]}}
{"jsonrpc":"2.0","id":2,"result":{"sessionId":"{{sessionId}}","configOptions":[{"id":"permission","name":"Permissions","description":"Sets this session's sandbox and approval behavior.","category":"mode","type":"select","currentValue":"danger-full-access","options":[{"value":"workspace-write","name":"workspace-write","description":"Write inside the workspace and permitted temporary directories; wider retries require approval."},{"value":"danger-full-access","name":"danger-full-access","description":"Full file access without approval prompts."}]}]}}
{"jsonrpc":"2.0","method":"session/update","params":{"sessionId":"{{sessionId}}","update":{"sessionUpdate":"tool_call","toolCallId":"call_1","title":"Update todo list","kind":"other","status":"in_progress","rawInput":[{"content":"watch the kettle boil","status":"in_progress"}]}}}
{"jsonrpc":"2.0","method":"session/update","params":{"sessionId":"{{sessionId}}","update":{"sessionUpdate":"plan","entries":[{"content":"watch the kettle boil","priority":"medium","status":"in_progress"}]}}}
{"jsonrpc":"2.0","method":"session/update","params":{"sessionId":"{{sessionId}}","update":{"sessionUpdate":"tool_call_update","toolCallId":"call_1","status":"completed","content":[{"type":"content","content":{"type":"text","text":"Updated todo list: 0 pending, 1 in progress, 0 completed."}}]}}}

View File

@@ -1,5 +1,5 @@
{"jsonrpc":"2.0","id":1,"result":{"protocolVersion":1,"agentInfo":{"name":"deepseek-harness-acp","version":"0.0.1"},"agentCapabilities":{"loadSession":true,"promptCapabilities":{"image":false,"audio":false,"embeddedContext":false}},"authMethods":[]}}
{"jsonrpc":"2.0","id":2,"result":{"sessionId":"{{sessionId}}","configOptions":[{"id":"permission","name":"Permissions","description":"The session permission preset: each choice bundles a sandbox mode and an approval policy.","category":"mode","type":"select","currentValue":"danger-full-access","options":[{"value":"workspace-write","name":"workspace-write","description":"Write inside the workspace; anything wider asks for your approval."},{"value":"danger-full-access","name":"danger-full-access","description":"Full file access, no approval prompts."}]}]}}
{"jsonrpc":"2.0","id":2,"result":{"sessionId":"{{sessionId}}","configOptions":[{"id":"permission","name":"Permissions","description":"Sets this session's sandbox and approval behavior.","category":"mode","type":"select","currentValue":"danger-full-access","options":[{"value":"workspace-write","name":"workspace-write","description":"Write inside the workspace and permitted temporary directories; wider retries require approval."},{"value":"danger-full-access","name":"danger-full-access","description":"Full file access without approval prompts."}]}]}}
{"jsonrpc":"2.0","method":"session/update","params":{"sessionId":"{{sessionId}}","update":{"sessionUpdate":"agent_thought_chunk","content":{"type":"text","text":"Load the requested skill."}}}}
{"jsonrpc":"2.0","method":"session/update","params":{"sessionId":"{{sessionId}}","update":{"sessionUpdate":"tool_call","toolCallId":"call_skill_load","title":"Load skill snapshot-skill","kind":"read","status":"in_progress","rawInput":"snapshot-skill"}}}
{"jsonrpc":"2.0","method":"session/update","params":{"sessionId":"{{sessionId}}","update":{"sessionUpdate":"tool_call_update","toolCallId":"call_skill_load","status":"completed","content":[{"type":"content","content":{"type":"text","text":"<skill_content name=\"snapshot-skill\">\n<skill_resources>\nBase directory for this skill: {{cwd}}/.dsh/skills/snapshot-skill\nResolve relative paths mentioned by this skill against the base directory before using them. Load referenced resources only as needed.\n</skill_resources>\n\n<skill_instructions>\nFollow these snapshot-only instructions.\nResolve referenced resources relative to this skill directory.\n</skill_instructions>\n</skill_content>"}}]}}}

View File

@@ -1,5 +1,5 @@
{"jsonrpc":"2.0","id":1,"result":{"protocolVersion":1,"agentInfo":{"name":"deepseek-harness-acp","version":"0.0.1"},"agentCapabilities":{"loadSession":true,"promptCapabilities":{"image":false,"audio":false,"embeddedContext":false}},"authMethods":[]}}
{"jsonrpc":"2.0","id":2,"result":{"sessionId":"{{sessionId}}","configOptions":[{"id":"permission","name":"Permissions","description":"The session permission preset: each choice bundles a sandbox mode and an approval policy.","category":"mode","type":"select","currentValue":"danger-full-access","options":[{"value":"workspace-write","name":"workspace-write","description":"Write inside the workspace; anything wider asks for your approval."},{"value":"danger-full-access","name":"danger-full-access","description":"Full file access, no approval prompts."}]}]}}
{"jsonrpc":"2.0","id":2,"result":{"sessionId":"{{sessionId}}","configOptions":[{"id":"permission","name":"Permissions","description":"Sets this session's sandbox and approval behavior.","category":"mode","type":"select","currentValue":"danger-full-access","options":[{"value":"workspace-write","name":"workspace-write","description":"Write inside the workspace and permitted temporary directories; wider retries require approval."},{"value":"danger-full-access","name":"danger-full-access","description":"Full file access without approval prompts."}]}]}}
{"jsonrpc":"2.0","method":"session/update","params":{"sessionId":"{{sessionId}}","update":{"sessionUpdate":"agent_thought_chunk","content":{"type":"text","text":"The"}}}}
{"jsonrpc":"2.0","method":"session/update","params":{"sessionId":"{{sessionId}}","update":{"sessionUpdate":"agent_thought_chunk","content":{"type":"text","text":" user"}}}}
{"jsonrpc":"2.0","method":"session/update","params":{"sessionId":"{{sessionId}}","update":{"sessionUpdate":"agent_thought_chunk","content":{"type":"text","text":" wants"}}}}

View File

@@ -1,5 +1,5 @@
{"jsonrpc":"2.0","id":1,"result":{"protocolVersion":1,"agentInfo":{"name":"deepseek-harness-acp","version":"0.0.1"},"agentCapabilities":{"loadSession":true,"promptCapabilities":{"image":false,"audio":false,"embeddedContext":false}},"authMethods":[]}}
{"jsonrpc":"2.0","id":2,"result":{"sessionId":"{{sessionId}}","configOptions":[{"id":"permission","name":"Permissions","description":"The session permission preset: each choice bundles a sandbox mode and an approval policy.","category":"mode","type":"select","currentValue":"danger-full-access","options":[{"value":"workspace-write","name":"workspace-write","description":"Write inside the workspace; anything wider asks for your approval."},{"value":"danger-full-access","name":"danger-full-access","description":"Full file access, no approval prompts."}]}]}}
{"jsonrpc":"2.0","id":2,"result":{"sessionId":"{{sessionId}}","configOptions":[{"id":"permission","name":"Permissions","description":"Sets this session's sandbox and approval behavior.","category":"mode","type":"select","currentValue":"danger-full-access","options":[{"value":"workspace-write","name":"workspace-write","description":"Write inside the workspace and permitted temporary directories; wider retries require approval."},{"value":"danger-full-access","name":"danger-full-access","description":"Full file access without approval prompts."}]}]}}
{"jsonrpc":"2.0","method":"session/update","params":{"sessionId":"{{sessionId}}","update":{"sessionUpdate":"agent_thought_chunk","content":{"type":"text","text":"The"}}}}
{"jsonrpc":"2.0","method":"session/update","params":{"sessionId":"{{sessionId}}","update":{"sessionUpdate":"agent_thought_chunk","content":{"type":"text","text":" user"}}}}
{"jsonrpc":"2.0","method":"session/update","params":{"sessionId":"{{sessionId}}","update":{"sessionUpdate":"agent_thought_chunk","content":{"type":"text","text":" wants"}}}}

View File

@@ -1,5 +1,5 @@
{"jsonrpc":"2.0","id":1,"result":{"protocolVersion":1,"agentInfo":{"name":"deepseek-harness-acp","version":"0.0.1"},"agentCapabilities":{"loadSession":true,"promptCapabilities":{"image":false,"audio":false,"embeddedContext":false}},"authMethods":[]}}
{"jsonrpc":"2.0","id":2,"result":{"sessionId":"{{sessionId}}","configOptions":[{"id":"permission","name":"Permissions","description":"The session permission preset: each choice bundles a sandbox mode and an approval policy.","category":"mode","type":"select","currentValue":"danger-full-access","options":[{"value":"workspace-write","name":"workspace-write","description":"Write inside the workspace; anything wider asks for your approval."},{"value":"danger-full-access","name":"danger-full-access","description":"Full file access, no approval prompts."}]}]}}
{"jsonrpc":"2.0","id":2,"result":{"sessionId":"{{sessionId}}","configOptions":[{"id":"permission","name":"Permissions","description":"Sets this session's sandbox and approval behavior.","category":"mode","type":"select","currentValue":"danger-full-access","options":[{"value":"workspace-write","name":"workspace-write","description":"Write inside the workspace and permitted temporary directories; wider retries require approval."},{"value":"danger-full-access","name":"danger-full-access","description":"Full file access without approval prompts."}]}]}}
{"jsonrpc":"2.0","method":"session/update","params":{"sessionId":"{{sessionId}}","update":{"sessionUpdate":"agent_thought_chunk","content":{"type":"text","text":"The"}}}}
{"jsonrpc":"2.0","method":"session/update","params":{"sessionId":"{{sessionId}}","update":{"sessionUpdate":"agent_thought_chunk","content":{"type":"text","text":" user"}}}}
{"jsonrpc":"2.0","method":"session/update","params":{"sessionId":"{{sessionId}}","update":{"sessionUpdate":"agent_thought_chunk","content":{"type":"text","text":" wants"}}}}

View File

@@ -1,5 +1,5 @@
{"jsonrpc":"2.0","id":1,"result":{"protocolVersion":1,"agentInfo":{"name":"deepseek-harness-acp","version":"0.0.1"},"agentCapabilities":{"loadSession":true,"promptCapabilities":{"image":false,"audio":false,"embeddedContext":false}},"authMethods":[]}}
{"jsonrpc":"2.0","id":2,"result":{"sessionId":"{{sessionId}}","configOptions":[{"id":"permission","name":"Permissions","description":"The session permission preset: each choice bundles a sandbox mode and an approval policy.","category":"mode","type":"select","currentValue":"danger-full-access","options":[{"value":"workspace-write","name":"workspace-write","description":"Write inside the workspace; anything wider asks for your approval."},{"value":"danger-full-access","name":"danger-full-access","description":"Full file access, no approval prompts."}]}]}}
{"jsonrpc":"2.0","id":2,"result":{"sessionId":"{{sessionId}}","configOptions":[{"id":"permission","name":"Permissions","description":"Sets this session's sandbox and approval behavior.","category":"mode","type":"select","currentValue":"danger-full-access","options":[{"value":"workspace-write","name":"workspace-write","description":"Write inside the workspace and permitted temporary directories; wider retries require approval."},{"value":"danger-full-access","name":"danger-full-access","description":"Full file access without approval prompts."}]}]}}
{"jsonrpc":"2.0","method":"session/update","params":{"sessionId":"{{sessionId}}","update":{"sessionUpdate":"agent_thought_chunk","content":{"type":"text","text":"The"}}}}
{"jsonrpc":"2.0","method":"session/update","params":{"sessionId":"{{sessionId}}","update":{"sessionUpdate":"agent_thought_chunk","content":{"type":"text","text":" user"}}}}
{"jsonrpc":"2.0","method":"session/update","params":{"sessionId":"{{sessionId}}","update":{"sessionUpdate":"agent_thought_chunk","content":{"type":"text","text":" wants"}}}}

View File

@@ -1,5 +1,5 @@
{"jsonrpc":"2.0","id":1,"result":{"protocolVersion":1,"agentInfo":{"name":"deepseek-harness-acp","version":"0.0.1"},"agentCapabilities":{"loadSession":true,"promptCapabilities":{"image":false,"audio":false,"embeddedContext":false}},"authMethods":[]}}
{"jsonrpc":"2.0","id":2,"result":{"sessionId":"{{sessionId}}","configOptions":[{"id":"permission","name":"Permissions","description":"The session permission preset: each choice bundles a sandbox mode and an approval policy.","category":"mode","type":"select","currentValue":"danger-full-access","options":[{"value":"workspace-write","name":"workspace-write","description":"Write inside the workspace; anything wider asks for your approval."},{"value":"danger-full-access","name":"danger-full-access","description":"Full file access, no approval prompts."}]}]}}
{"jsonrpc":"2.0","id":2,"result":{"sessionId":"{{sessionId}}","configOptions":[{"id":"permission","name":"Permissions","description":"Sets this session's sandbox and approval behavior.","category":"mode","type":"select","currentValue":"danger-full-access","options":[{"value":"workspace-write","name":"workspace-write","description":"Write inside the workspace and permitted temporary directories; wider retries require approval."},{"value":"danger-full-access","name":"danger-full-access","description":"Full file access without approval prompts."}]}]}}
{"jsonrpc":"2.0","method":"session/update","params":{"sessionId":"{{sessionId}}","update":{"sessionUpdate":"agent_thought_chunk","content":{"type":"text","text":"The"}}}}
{"jsonrpc":"2.0","method":"session/update","params":{"sessionId":"{{sessionId}}","update":{"sessionUpdate":"agent_thought_chunk","content":{"type":"text","text":" user"}}}}
{"jsonrpc":"2.0","method":"session/update","params":{"sessionId":"{{sessionId}}","update":{"sessionUpdate":"agent_thought_chunk","content":{"type":"text","text":" wants"}}}}

View File

@@ -1,5 +1,5 @@
{"jsonrpc":"2.0","id":1,"result":{"protocolVersion":1,"agentInfo":{"name":"deepseek-harness-acp","version":"0.0.1"},"agentCapabilities":{"loadSession":true,"promptCapabilities":{"image":false,"audio":false,"embeddedContext":false}},"authMethods":[]}}
{"jsonrpc":"2.0","id":2,"result":{"sessionId":"{{sessionId}}","configOptions":[{"id":"permission","name":"Permissions","description":"The session permission preset: each choice bundles a sandbox mode and an approval policy.","category":"mode","type":"select","currentValue":"danger-full-access","options":[{"value":"workspace-write","name":"workspace-write","description":"Write inside the workspace; anything wider asks for your approval."},{"value":"danger-full-access","name":"danger-full-access","description":"Full file access, no approval prompts."}]}]}}
{"jsonrpc":"2.0","id":2,"result":{"sessionId":"{{sessionId}}","configOptions":[{"id":"permission","name":"Permissions","description":"Sets this session's sandbox and approval behavior.","category":"mode","type":"select","currentValue":"danger-full-access","options":[{"value":"workspace-write","name":"workspace-write","description":"Write inside the workspace and permitted temporary directories; wider retries require approval."},{"value":"danger-full-access","name":"danger-full-access","description":"Full file access without approval prompts."}]}]}}
{"jsonrpc":"2.0","method":"session/update","params":{"sessionId":"{{sessionId}}","update":{"sessionUpdate":"agent_thought_chunk","content":{"type":"text","text":"The"}}}}
{"jsonrpc":"2.0","method":"session/update","params":{"sessionId":"{{sessionId}}","update":{"sessionUpdate":"agent_thought_chunk","content":{"type":"text","text":" user"}}}}
{"jsonrpc":"2.0","method":"session/update","params":{"sessionId":"{{sessionId}}","update":{"sessionUpdate":"agent_thought_chunk","content":{"type":"text","text":" wants"}}}}

View File

@@ -1,5 +1,5 @@
{"jsonrpc":"2.0","id":1,"result":{"protocolVersion":1,"agentInfo":{"name":"deepseek-harness-acp","version":"0.0.1"},"agentCapabilities":{"loadSession":true,"promptCapabilities":{"image":false,"audio":false,"embeddedContext":false}},"authMethods":[]}}
{"jsonrpc":"2.0","id":2,"result":{"sessionId":"{{sessionId}}","configOptions":[{"id":"permission","name":"Permissions","description":"The session permission preset: each choice bundles a sandbox mode and an approval policy.","category":"mode","type":"select","currentValue":"danger-full-access","options":[{"value":"workspace-write","name":"workspace-write","description":"Write inside the workspace; anything wider asks for your approval."},{"value":"danger-full-access","name":"danger-full-access","description":"Full file access, no approval prompts."}]}]}}
{"jsonrpc":"2.0","id":2,"result":{"sessionId":"{{sessionId}}","configOptions":[{"id":"permission","name":"Permissions","description":"Sets this session's sandbox and approval behavior.","category":"mode","type":"select","currentValue":"danger-full-access","options":[{"value":"workspace-write","name":"workspace-write","description":"Write inside the workspace and permitted temporary directories; wider retries require approval."},{"value":"danger-full-access","name":"danger-full-access","description":"Full file access without approval prompts."}]}]}}
{"jsonrpc":"2.0","method":"session/update","params":{"sessionId":"{{sessionId}}","update":{"sessionUpdate":"agent_thought_chunk","content":{"type":"text","text":"The"}}}}
{"jsonrpc":"2.0","method":"session/update","params":{"sessionId":"{{sessionId}}","update":{"sessionUpdate":"agent_thought_chunk","content":{"type":"text","text":" user"}}}}
{"jsonrpc":"2.0","method":"session/update","params":{"sessionId":"{{sessionId}}","update":{"sessionUpdate":"agent_thought_chunk","content":{"type":"text","text":" wants"}}}}

View File

@@ -1,5 +1,5 @@
{"jsonrpc":"2.0","id":1,"result":{"protocolVersion":1,"agentInfo":{"name":"deepseek-harness-acp","version":"0.0.1"},"agentCapabilities":{"loadSession":true,"promptCapabilities":{"image":false,"audio":false,"embeddedContext":false}},"authMethods":[]}}
{"jsonrpc":"2.0","id":2,"result":{"sessionId":"{{sessionId}}","configOptions":[{"id":"permission","name":"Permissions","description":"The session permission preset: each choice bundles a sandbox mode and an approval policy.","category":"mode","type":"select","currentValue":"danger-full-access","options":[{"value":"workspace-write","name":"workspace-write","description":"Write inside the workspace; anything wider asks for your approval."},{"value":"danger-full-access","name":"danger-full-access","description":"Full file access, no approval prompts."}]}]}}
{"jsonrpc":"2.0","id":2,"result":{"sessionId":"{{sessionId}}","configOptions":[{"id":"permission","name":"Permissions","description":"Sets this session's sandbox and approval behavior.","category":"mode","type":"select","currentValue":"danger-full-access","options":[{"value":"workspace-write","name":"workspace-write","description":"Write inside the workspace and permitted temporary directories; wider retries require approval."},{"value":"danger-full-access","name":"danger-full-access","description":"Full file access without approval prompts."}]}]}}
{"jsonrpc":"2.0","method":"session/update","params":{"sessionId":"{{sessionId}}","update":{"sessionUpdate":"agent_thought_chunk","content":{"type":"text","text":"The"}}}}
{"jsonrpc":"2.0","method":"session/update","params":{"sessionId":"{{sessionId}}","update":{"sessionUpdate":"agent_thought_chunk","content":{"type":"text","text":" user"}}}}
{"jsonrpc":"2.0","method":"session/update","params":{"sessionId":"{{sessionId}}","update":{"sessionUpdate":"agent_thought_chunk","content":{"type":"text","text":" wants"}}}}

View File

@@ -1,5 +1,5 @@
{"jsonrpc":"2.0","id":1,"result":{"protocolVersion":1,"agentInfo":{"name":"deepseek-harness-acp","version":"0.0.1"},"agentCapabilities":{"loadSession":true,"promptCapabilities":{"image":false,"audio":false,"embeddedContext":false}},"authMethods":[]}}
{"jsonrpc":"2.0","id":2,"result":{"sessionId":"{{sessionId}}","configOptions":[{"id":"permission","name":"Permissions","description":"The session permission preset: each choice bundles a sandbox mode and an approval policy.","category":"mode","type":"select","currentValue":"danger-full-access","options":[{"value":"workspace-write","name":"workspace-write","description":"Write inside the workspace; anything wider asks for your approval."},{"value":"danger-full-access","name":"danger-full-access","description":"Full file access, no approval prompts."}]}]}}
{"jsonrpc":"2.0","id":2,"result":{"sessionId":"{{sessionId}}","configOptions":[{"id":"permission","name":"Permissions","description":"Sets this session's sandbox and approval behavior.","category":"mode","type":"select","currentValue":"danger-full-access","options":[{"value":"workspace-write","name":"workspace-write","description":"Write inside the workspace and permitted temporary directories; wider retries require approval."},{"value":"danger-full-access","name":"danger-full-access","description":"Full file access without approval prompts."}]}]}}
{"jsonrpc":"2.0","method":"session/update","params":{"sessionId":"{{sessionId}}","update":{"sessionUpdate":"agent_thought_chunk","content":{"type":"text","text":"The"}}}}
{"jsonrpc":"2.0","method":"session/update","params":{"sessionId":"{{sessionId}}","update":{"sessionUpdate":"agent_thought_chunk","content":{"type":"text","text":" user"}}}}
{"jsonrpc":"2.0","method":"session/update","params":{"sessionId":"{{sessionId}}","update":{"sessionUpdate":"agent_thought_chunk","content":{"type":"text","text":" wants"}}}}

View File

@@ -33,7 +33,7 @@ The id is wired through `cordis.yml` (`resumeSessionId: !!js process.env.RESUME_
## Code Mode
[`code-mode.cordis.yml`](code-mode.cordis.yml) is this same tree flipped to [Code Mode](../../docs/rfc/implemented/feature/2026-06-15-code-mode.md): an include overlay over `./cordis.yml` whose two patches insert the worker-thread code runtime (`@deepseek-ai/dsh-code-runtime-worker`, registering `ctx.codeRuntime`) and set `tools: { mode: code }` on the app. The registry contributes exactly one reserved wire transport — `run_code` plus a generated TypeScript SDK section declaring the visible end-capability tools. The model composes those capabilities by writing a program; each program call carries an immutable link to its enclosing transport, bridges back through pre-policy, monotonic guards, around dispatch, post-policy, and final-result observation one at a time, and is logged as a `tool/code-dispatch` session event. Only what the program prints or returns re-enters model context. (Flip the mode to `both` to offer native calls and `run_code` side by side.)
[`code-mode.cordis.yml`](code-mode.cordis.yml) overlays the same tree with the worker-thread runtime and `tools: { mode: code }`. The model receives one `run_code` transport plus a generated TypeScript SDK for the visible tools; only program output returns to model context. Use `mode: both` to expose native calls alongside `run_code`. See the [Code Mode RFC](../../docs/rfc/implemented/feature/2026-06-15-code-mode.md) for the execution contract.
```sh
pnpm run demo:code-mode # this overlay under the REPL (default UI)

View File

@@ -1,13 +1,8 @@
# Code Mode overlay: the live coding-agent tree (./cordis.yml) with two
# load-time patches — the app entry's config gains `tools: { mode: code }`
# (the registry offers exactly one wire tool, run_code, plus the generated
# TypeScript SDK prompt section declaring bash/read/write/edit/subagent/
# todo_write) and the worker-thread code runtime joins the tree as
# `ctx.codeRuntime`. The dsh-stdio-agent bin boots this file for
# `pnpm run demo:code-mode` (the acp-agent example carries the same-shaped
# overlay for the `acp` UI). A config patch REPLACES the entry's whole
# config, so the base entry's fields are restated verbatim; only `tools`,
# the welcome, and the persona's second paragraph are Code Mode deltas.
# Code Mode adds `ctx.codeRuntime` and changes the registry to one wire tool,
# `run_code`, plus a generated SDK for bash/read/write/edit/subagent/todo_write.
# `demo:code-mode` selects this overlay; the ACP example has the same UI-specific
# shape. A config patch replaces the whole app config, so unchanged base fields
# are restated; only `tools`, `welcome`, and the persona's second paragraph differ.
- id: base
name: '@cordisjs/plugin-include'
config:

View File

@@ -1,15 +1,8 @@
# The coding-agent plugin tree: the REPL agent demo. The two swappable
# backends — the DeepSeek adapter and the local bash executor — plus `hmr` for
# the dev/demo reload loop, then the stdio chat app (@deepseek-ai/dsh-stdio-
# agent), which bundles the whole agent-core spine (timer, llm, sessions,
# system-prompt, tools, agents, invariants, tool-bash, agent-loop), the console
# logger, JSONL persistence, the readline UI, and a pre-created `main` agent.
#
# `hmr` is a leaf entry (not baked into dsh-stdio-agent): it is a Loader-only
# dev plugin that needs `--expose-internals` — the `demo:repl` script passes
# it. Requires DEEPSEEK_API_KEY (and optionally DEEPSEEK_BASE_URL) in the
# environment — the dsh-stdio-agent bin loads the gitignored repo-root .env
# first. cordis.yml reads them via the `!!js` tag.
# REPL agent with swappable DeepSeek and local-bash backends. `dsh-stdio-agent`
# supplies the agent-core spine, logging, JSONL persistence, readline UI, and `main` agent.
# HMR remains a leaf because it requires Loader internals; `demo:repl` passes
# `--expose-internals`. The app bin loads the gitignored root `.env`; this file
# reads `DEEPSEEK_API_KEY` and optional `DEEPSEEK_BASE_URL` through `!!js`.
# Hot-module reload for the dev/demo loop (needs `node --expose-internals`).
- id: hmr
@@ -28,15 +21,13 @@
- deepseek-v4-pro
- deepseek-v4-flash
# Local bash executor for agent-core's tool-bash schema (one of several tool
# stacks in this tree: filesystem, subagent, and todo_write load below).
# Local executor for the app bundle's bash tool.
- id: bash
name: '@deepseek-ai/dsh-bash-local'
config:
timeoutMs: 60000
# The stdio chat app: the whole spine + front-door cluster, configured for a
# REPL agent demo driving a pre-created `main` agent.
# The app bundle pre-creates the REPL's `main` agent.
- id: stdio-agent
name: '@deepseek-ai/dsh-stdio-agent'
config:
@@ -46,20 +37,16 @@
resumeSessionId: !!js process.env.RESUME_SESSION_ID
persistenceRoot: './.sessions'
welcome: 'agent REPL ready. Give it a coding task.'
# The persona: identity + behavior only, nothing about transports or
# tooling — tool guidance lives with each tool plugin (descriptions +
# prompt sections). {{model}} is the prompt variable the agent loop
# resolves from this agent's configured model.
# Keep the persona to identity and behavior; tool plugins own tool guidance.
# The loop resolves {{model}} from this agent's configuration.
persona: |
You are coding-agent, a coding assistant powered by the {{model}} model.
Verify your work by running the code or tests. Keep answers brief and
factual.
# Automatic context compaction: when the derived history approaches the model's
# context window, summarize an older range into a checkpoint so a long-running
# or tool-heavy session keeps fitting. A leaf entry (needs ctx.llm + the
# agent-loop's `agent/pre-step` seam from the app above).
# Summarize an older range when derived history approaches the context window.
# This leaf consumes `ctx.llm` and the app's `agent/pre-step` seam.
- id: compact-basic
name: '@deepseek-ai/dsh-compact-basic'
config:
@@ -70,13 +57,9 @@
maxTokens: 8192
compactionRetries: 1
# The subagent seam + BOTH in-process backends + two model-facing tools, as leaf
# entries after the app (which provides ctx.agents/ctx.tools). spawn (a fresh
# child) and fork (a child seeded with the parent's completed-turn prefix) are
# independent backends over the shared dsh-subagent-inprocess driver. Exposing
# both transports is pure config: load each backend, then load dsh-tool-subagent
# once per backend with a distinct toolName (the tool registry rejects a
# duplicate name) — no code change.
# Expose fresh-child `spawn` and completed-prefix `fork` through independent
# in-process backends. Each tool instance needs a distinct `toolName`; the registry
# rejects duplicates. These leaves follow the app because it provides `ctx.agents` and `ctx.tools`.
- id: subagent
name: '@deepseek-ai/dsh-subagent'
@@ -103,10 +86,8 @@
toolName: subagent_fork
# Dynamic workflows: the worker-thread engine (ctx.workflows) over the spawn
# subagent backend above, plus the model-facing `workflow` tool. The model
# writes a JavaScript orchestration script (meta + body); the engine runs it
# in its own worker thread and fans agent() calls out as spawn children.
# The worker-thread workflow engine fans a model-written JavaScript script's
# `agent()` calls out through the spawn backend; the adjacent tool exposes it to the model.
- id: workflow-workerthread
name: '@deepseek-ai/dsh-workflow-workerthread'
config:
@@ -114,14 +95,12 @@
- id: tool-workflow
name: '@deepseek-ai/dsh-tool-workflow'
# The model-facing todo_write tool: whole-list task tracking written to the
# session log (todo/write), rendered as a stdio checklist / ACP plan.
# `todo_write` replaces the logged whole list and renders as a stdio checklist or ACP plan.
- id: tool-todo
name: '@deepseek-ai/dsh-tool-todo'
# Filesystem capability stack: local provider, read-before-write/edit policy
# gate, then the model-facing read/write/edit tools. stdio-agent is a single
# session, so relative paths resolve from the process cwd (the workspace).
# Policy loads before the model-facing filesystem tools so writes and edits require
# an observed file. This single-session app resolves relative paths from the process cwd.
- id: fs-local
name: '@deepseek-ai/dsh-fs-local'
config:

View File

@@ -6,17 +6,12 @@ import { fileURLToPath } from 'node:url'
import { afterEach, describe, expect, it } from 'vitest'
/**
* Keyless Loader-path smoke for the Code Mode overlay: boot the REAL
* example through the `@deepseek-ai/dsh-stdio-agent` bin against
* `code-mode.cordis.yml` (the cordis Loader, `unwrapExports`, the include
* patches over ./cordis.yml, the worker-thread code runtime, and the
* registry in `mode: code`), then close stdin with no prompt and assert
* the Code Mode banner + a clean exit.
*
* No prompt is ever sent, so the model is NEVER called and no `run_code`
* turn happens — a dummy key lets `llm-deepseek`'s key-PRESENT check boot
* the tree. This is the export-shape guard (postmortem 0001) for the Code
* Mode composition; the with-key proof lives in `code-mode.e2e.ts`.
* Keyless Loader-path smoke for the Code Mode overlay: boot the real example through the
* `@deepseek-ai/dsh-stdio-agent` bin against `code-mode.cordis.yml` (the cordis Loader,
* `unwrapExports`, the include patches over ./cordis.yml, the worker-thread code runtime, and
* the registry in `mode: code`), then close stdin with no prompt and assert the Code Mode
* banner + a clean exit. A dummy key satisfies adapter boot, but no prompt means
* no model call; the with-key proof lives in `code-mode.e2e.ts`.
*/
const binScript = fileURLToPath(new URL('../../../packages/ui/stdio-agent/src/bin.ts', import.meta.url))
@@ -26,10 +21,8 @@ const tsxLoader = fileURLToPath(import.meta.resolve('tsx'))
// `paths` map; tsx searches UP from cwd, and we spawn from a temp dir outside
// the repo, so point it at the repo tsconfig.
const repoTsconfig = fileURLToPath(new URL('../../../tsconfig.json', import.meta.url))
// The real-API workflow runs up to 14 e2e files at once. Cold tsx/Loader
// startup can therefore outlive a tight smoke-test deadline before the child
// emits any output; 30s still detects a wedged process without confusing
// bounded CI contention with a lifecycle failure.
// Under parallel e2e load, cold tsx/Loader startup can exceed a tight deadline;
// 30s still detects a wedged child.
const PROCESS_TIMEOUT_MS = 30_000
// Leave enough room for the process-owned timeout to report captured output
// before Vitest aborts the test itself.

View File

@@ -16,14 +16,9 @@ import * as LlmDeepSeek from '@deepseek-ai/dsh-llm-deepseek'
import { WorkerCodeRuntime } from '@deepseek-ai/dsh-code-runtime-worker'
/**
* The Code Mode with-key proof (the RFC's e2e tier): a REAL model under
* `mode: 'code'`, a task that requires composing two tool calls, verified
* against the WORLD — the persisted request header carried exactly
* `[run_code]` as the wire tool list, each sub-call landed as a
* `tool/code-dispatch` event, the file the program wrote exists on disk, and
* the final answer is the program's curated output. Key-gated (see
* vitest.e2e.config.ts); the keyless Loader-path smoke of the overlay lives
* in `code-mode-keyless-smoke.e2e.ts`.
* With-key Code Mode proof: a real model receives only `run_code`, composes two
* sub-calls, writes a file, and returns curated output while the log records
* each `tool/code-dispatch`. The keyless Loader smoke is in the sibling test.
*/
const PERSONA = 'You are coding-agent. You work by writing TypeScript programs for run_code: '

View File

@@ -7,25 +7,11 @@ import { AgentId } from '@deepseek-ai/dsh-agent'
import { codingHarness, finalText, SYSTEM_PROMPT, waitForIdle } from './harness.ts'
/**
* The compaction smoke test: a real model runs a multi-step bash task with a
* deliberately tiny context window, so the auto-compaction listener fires
* MID-SESSION and summarizes the older history into a checkpoint. This is the
* first end-to-end exercise of the compaction seam (it is wired nowhere else),
* and the runaway-survival regression net — it proves a session that grows past
* the window keeps running rather than overflowing. Key-gated.
*
* Verifies the WORLD, not the agent's self-report: a compact/start…end pair
* landed in the real session log, the surface actually shrank (a replace node
* exists and shadowed older nodes), and the agent still produced a final answer
* after compaction (so the summarized history did not break the conversation).
*
* FIXME(compaction-snapshot): this key-gated e2e is the ONLY coverage of runaway
* compaction — there is no keyless full-transcript snapshot of it. dsh-llm-replay
* reconstructs one model call per (turn, step) from `assistant/chunk` events, but
* `summarize()` assembles its stream into a local BlockAssembler and appends no
* `assistant/chunk`, so the interleaved summarization call is unreplayable. A
* snapshot needs replay-harness work to serve that call; deferred as a follow-up.
* Key-gated smoke for mid-session compaction. It verifies the compact event
* pair, replacement of older surface nodes, and a final answer after compaction.
*/
// FIXME(compaction-snapshot): this is the only full compaction coverage because
// replay cannot serve the summarizer's unlogged model call.
let workdir: string | undefined
let ctx: Context | undefined
@@ -40,18 +26,11 @@ afterEach(async () => {
describe.skipIf(!process.env.DEEPSEEK_API_KEY)('compaction: a long session compacts mid-flight and keeps running', () => {
it('summarizes older history into a checkpoint without breaking the task', async () => {
workdir = await mkdtemp(join(tmpdir(), 'dsh-compaction-'))
// A handful of files for the model to read, so multiple bash steps
// accumulate surface nodes (tool calls + results) and grow the history past
// the (deliberately tiny) window.
for (let i = 1; i <= 4; i++) {
await writeFile(join(workdir, `file${i}.txt`), `This is file number ${i}. `.repeat(50))
}
// Tiny window so a couple of steps crosses the threshold. The generation
// cap is deliberately larger than the final checkpoint because
// reasoning-capable APIs count reasoning tokens against the provider output
// budget even though those blocks are stripped before the checkpoint is
// stored.
// Reasoning tokens require a larger generation cap than the retained checkpoint.
ctx = await codingHarness(workdir, {
persona: SYSTEM_PROMPT,
compact: {

View File

@@ -6,44 +6,22 @@ import { fileURLToPath } from 'node:url'
import { afterEach, describe, expect, it } from 'vitest'
/**
* Keyless Loader-path smoke for examples/coding-agent: boot the REAL example
* through the `@deepseek-ai/dsh-stdio-agent` bin against its `cordis.yml` (the
* cordis Loader, `unwrapExports`, the full plugin tree incl. the
* `@deepseek-ai/dsh-agent-core` bundle and the app's in-package readline UI
* module), then close stdin with no prompt and assert the
* ready banner + a clean exit.
*
* No prompt is ever sent, so the model is NEVER called — this is why it runs
* without a real key. coding-agent's `cordis.yml` loads `llm-deepseek`, whose
* `apply()` only requires a key to be PRESENT (it does not validate it and only
* uses it when a stream actually starts), so a dummy key lets the tree boot
* while the absence of any prompt guarantees no network call. The value is the
* real-Loader-path guard that the composed tree boots (see postmortem 0001;
* the app carries no `inject`, so its export SHAPE is pinned by the stdio-agent
* unit suite's unwrap assertion, not by a crash here),
* complementing coding-agent's with-key e2e suites which prove the real
* product.
* Boots the real example through the stdio bin and `cordis.yml`, covering Loader,
* `unwrapExports`, the full plugin tree, the agent-core bundle, and the readline module.
* A dummy key permits startup; closing stdin before a prompt prevents network calls,
* while with-key suites cover product behavior.
*/
// TODO(loader-smoke-harness): extract the shared spawn/tempdir/timeout/EOF
// harness used here, code-mode-keyless-smoke, and cordis-agent's keyless smoke.
// The dsh-stdio-agent bin (the demo:repl entry) and this example's cordis.yml.
// The bin resolves its config-path arg from CWD; the test spawns from a temp
// cwd, so we pass the example config's ABSOLUTE path.
// TODO(loader-smoke-harness): share spawn/tempdir/timeout/EOF setup with the other keyless smoke tests.
// The temp-cwd child needs absolute bin and config paths.
const binScript = fileURLToPath(new URL('../../../packages/ui/stdio-agent/src/bin.ts', import.meta.url))
const configPath = fileURLToPath(new URL('../cordis.yml', import.meta.url))
const tsxLoader = fileURLToPath(import.meta.resolve('tsx'))
// Dev/test run UNBUILT: resolve `@deepseek-ai/dsh-*` through the root tsconfig
// `paths` map; tsx searches UP from cwd, and we spawn from a temp dir outside
// the repo, so point it at the repo tsconfig (root is four levels up).
// The temp cwd cannot discover the root tsconfig used for unbuilt package aliases.
const repoTsconfig = fileURLToPath(new URL('../../../tsconfig.json', import.meta.url))
// The real-API workflow runs up to 14 e2e files at once. Cold tsx/Loader
// startup can therefore outlive a tight smoke-test deadline before the child
// emits any output; 30s still detects a wedged process without confusing
// bounded CI contention with a lifecycle failure.
// Allow cold Loader startup under parallel load while still detecting hangs.
const PROCESS_TIMEOUT_MS = 30_000
// Leave enough room for the process-owned timeout to report captured output
// before Vitest aborts the test itself.
// Let the child timeout report captured output before Vitest aborts.
const TEST_TIMEOUT_MS = PROCESS_TIMEOUT_MS + 15_000
let child: ChildProcessWithoutNullStreams | undefined

View File

@@ -30,4 +30,4 @@ Ask for `cordis_inspect` with `what: "api"` or `what: "events"` to see the gener
## End-to-end tests
`tests/keyless-smoke.e2e.ts` boots the real `cordis.yml` through the Loader with a dummy key and asserts the banner + clean EOF exit (the export-shape / real-load-path guard, now across the package-name resolution). `tests/cordis-tools.e2e.ts` is the with-key smoke: a real model mounts a status listener (asserting the tagged console line actually fires — the world, not the agent's claim), builds itself a `reverse_text` tool and uses it, and composes two mounts via provide/inject. The tool logic itself is unit-tested in [`packages/cordis/tool-cordis`](../../packages/cordis/tool-cordis) under the per-file 100% coverage gate.
`tests/keyless-smoke.e2e.ts` boots the real `cordis.yml` through the Loader with a dummy key and asserts the banner, package-name resolution, and clean EOF exit. `tests/cordis-tools.e2e.ts` is the with-key smoke: a real model mounts a status listener and the test verifies its tagged console line, creates and uses a `reverse_text` tool, and composes two mounts through provide/inject. [`packages/cordis/tool-cordis`](../../packages/cordis/tool-cordis) carries the unit coverage under the per-file 100% gate.

View File

@@ -1,17 +1,11 @@
# The cordis-agent plugin tree: the SELF-REFERENTIAL harness demo. Same spine
# as coding-agent (DeepSeek V4 + local bash on @deepseek-ai/dsh-stdio-agent),
# plus @deepseek-ai/dsh-tool-cordis, which gives the model three tools over the
# live cordis runtime it is running inside: cordis_inspect (services / plugin
# tree / tools / dynamic mounts / api / events), cordis_mount (evaluate
# model-written code in a vm sandbox and mount the returned plugin under the
# `cordis-dynamic` group), and cordis_unmount (dispose one mount by id).
# Requires DEEPSEEK_API_KEY (and optionally DEEPSEEK_BASE_URL) — the
# dsh-stdio-agent bin loads the gitignored repo-root .env first.
#
# Trust stance (docs/rfc/implemented/feature/2026-07-08-self-referential-cordis-toolset.md):
# the mounted code gets the REAL ctx — the
# vm sandbox only prevents accidental global pollution. Load the toolset as
# deliberately as you would grant a bash tool.
# Self-referential stdio demo: the coding spine plus tools to inspect the live
# service/plugin/tool/mount/API/event state, mount a model-written plugin under
# `cordis-dynamic`, and quiescently unmount it. The app bin loads the gitignored
# root `.env` before reading the required DeepSeek key and optional base URL.
# Trust stance: the vm and context façade limit accidental global/framework
# access but are not a security boundary; mounted code can reach live capabilities
# such as `ctx.bash`. Grant this toolset like bash access. See
# ../../docs/rfc/implemented/feature/2026-07-08-self-referential-cordis-toolset.md.
# Hot-module reload for the dev/demo loop (needs `node --expose-internals`).
- id: hmr
@@ -53,8 +47,7 @@
- id: web-fetch-local
name: '@deepseek-ai/dsh-web-fetch-local'
# The stdio chat app: the whole spine + front-door cluster, configured for the
# self-referential demo driving a pre-created `main` agent.
# The app bundle pre-creates the self-referential demo's `main` agent.
- id: stdio-agent
name: '@deepseek-ai/dsh-stdio-agent'
config:

View File

@@ -78,10 +78,9 @@ describe.skipIf(!process.env.DEEPSEEK_API_KEY)('cordis tools: a real model modif
}])
await waitForIdle(ctx, agent)
// World checks: the tool exists in the registry, was invoked as a real
// tool call, and its RESULT (the self-made execute actually running) is the
// reversed string. The model's prose is not asserted — the tool result is
// the world; the summary sentence is just the self-report.
// World checks: the tool exists in the registry, was invoked as a real tool call, and its
// RESULT (the self-made execute actually running) is the reversed string. Model prose is only
// self-report and is deliberately not asserted.
expect(ctx.tools.get('reverse_text')).toBeDefined()
const events = [...agent.session.events]
const calls = events.filter(event => event.type === 'tool/call')

View File

@@ -6,22 +6,16 @@ import { fileURLToPath } from 'node:url'
import { afterEach, describe, expect, it } from 'vitest'
/**
* Keyless Loader-path smoke for examples/cordis-agent: boot the REAL example
* through the `@deepseek-ai/dsh-stdio-agent` bin against its `cordis.yml` —
* the cordis Loader, `unwrapExports`, the full plugin tree INCLUDING the
* `@deepseek-ai/dsh-tool-cordis` package resolved by name (whose `inject`
* would crash a collapsed export shape at load, see docs/postmortem/0001) —
* then close stdin with no prompt and assert the ready banner + a clean exit.
*
* No prompt is ever sent, so the model is NEVER called — that is why it runs
* without a real key: `llm-deepseek`'s apply() only requires a key to be
* PRESENT, and the absence of any prompt guarantees no network call. The
* with-key product proof lives in cordis-tools.e2e.ts.
* Keyless Loader-path smoke for examples/cordis-agent: boot the real example through the
* `@deepseek-ai/dsh-stdio-agent` bin against its `cordis.yml` — the cordis Loader,
* `unwrapExports`, the full plugin tree INCLUDING the `@deepseek-ai/dsh-tool-cordis` package
* resolved by name (whose `inject` would crash a collapsed export shape at load, see
* docs/postmortem/0001) — then close stdin with no prompt and assert the ready banner + a
* clean exit. A dummy key satisfies adapter boot, but no prompt means no network
* call; `cordis-tools.e2e.ts` owns the with-key product proof.
*/
// The dsh-stdio-agent bin (the demo:cordis entry) and this example's cordis.yml.
// The bin resolves its config-path arg from CWD; the test spawns from a temp
// cwd, so we pass the example config's ABSOLUTE path.
// The temp-cwd child needs absolute bin and config paths.
const binScript = fileURLToPath(new URL('../../../packages/ui/stdio-agent/src/bin.ts', import.meta.url))
const configPath = fileURLToPath(new URL('../cordis.yml', import.meta.url))
const tsxLoader = fileURLToPath(import.meta.resolve('tsx'))
@@ -29,10 +23,8 @@ const tsxLoader = fileURLToPath(import.meta.resolve('tsx'))
// `paths` map; tsx searches UP from cwd, and we spawn from a temp dir outside
// the repo, so point it at the repo tsconfig (root is three levels up).
const repoTsconfig = fileURLToPath(new URL('../../../tsconfig.json', import.meta.url))
// The real-API workflow runs up to 14 e2e files at once. Cold tsx/Loader
// startup can therefore outlive a tight smoke-test deadline before the child
// emits any output; 30s still detects a wedged process without confusing
// bounded CI contention with a lifecycle failure.
// Under parallel e2e load, cold tsx/Loader startup can exceed a tight deadline;
// 30s still detects a wedged child.
const PROCESS_TIMEOUT_MS = 30_000
// Leave enough room for the process-owned timeout to report captured output
// before Vitest aborts the test itself.

View File

@@ -1,9 +1,5 @@
# The echo-agent plugin tree: the stdio chat app with its LLM backend swapped to
# the local `mock-echo` mock and the local `echo` tool added. The clean
# demonstration of "swap the backend, keep the app" — every service the agent
# needs lives in @deepseek-ai/dsh-stdio-agent (which bundles @deepseek-ai/dsh-
# agent-core); this leaf only picks the backends, `hmr`, and the app config.
#
# Stdio agent with the network-free `mock-echo` adapter and example-local `echo`
# tool. The app bundle supplies the spine; this leaf selects backends, HMR, and app config.
# No API key: the `mock-echo` adapter never touches the network.
# Hot-module reload for the dev/demo loop (a leaf entry, not baked into
@@ -13,8 +9,7 @@
config:
root: ['.']
# The mock model (registers the `mock-echo` adapter) and the demo `echo` tool —
# example-local teaching plugins, resolved relative to THIS file's directory.
# Example-local model and tool plugins resolve relative to this file.
- id: mock-llm
name: './src/mock-llm.ts'
@@ -27,8 +22,7 @@
- id: bash
name: '@deepseek-ai/dsh-bash-local'
# The stdio chat app: console logger + the agent-core spine (pre-creating the
# `main` agent on the mock model) + JSONL persistence + the readline UI.
# The app pre-creates `main` on the mock model and supplies logging, persistence, and readline UI.
- id: stdio-agent
name: '@deepseek-ai/dsh-stdio-agent'
config:

View File

@@ -6,41 +6,22 @@ import { fileURLToPath } from 'node:url'
import { afterEach, describe, expect, it } from 'vitest'
/**
* Keyless Loader-path smoke for examples/echo-agent: boot the REAL example
* through the `@deepseek-ai/dsh-stdio-agent` bin against this example's
* `cordis.yml` (the cordis Loader, `unwrapExports`, the whole plugin tree),
* pipe a script of stdin lines, and assert the rendered stdout.
*
* This is the guard the per-file unit suite structurally cannot be: it drives
* the `@deepseek-ai/dsh-stdio-agent` app plugin, the `@deepseek-ai/dsh-agent-core`
* bundle it loads, the app's in-package readline UI module, AND the
* example-local `mock-llm.ts` / `echo-tool.ts` through their REAL load path
* (see docs/postmortem/0001). The app itself carries no `inject`, so a stray
* `export default` would boot rather than crash here — the export SHAPE is
* pinned by the explicit unwrap assertion in the stdio-agent unit suite; this
* smoke proves the composed tree actually runs. It needs no API key — the
* `mock-echo` adapter never touches the network — so it runs in the default e2e
* gate.
*
* Both branches of mock-llm.ts are exercised: an `echo …` line (the tool
* round-trip → `ECHO: …`) and a plain line (the direct canned reply).
* Keyless Loader-path smoke for examples/echo-agent: boot the real example through the
* `@deepseek-ai/dsh-stdio-agent` bin against this example's `cordis.yml` (the cordis Loader,
* `unwrapExports`, the whole plugin tree), pipe a script of stdin lines, and assert the
* rendered stdout. The mock adapter is network-free, making this the complete
* smoke; inputs cover both the echo-tool round trip and direct-reply branch.
*/
// The dsh-stdio-agent bin (the demo:echo entry) and this example's cordis.yml.
// The bin resolves its config-path arg from CWD; the test spawns from a temp
// cwd, so we pass the example config's ABSOLUTE path.
// The temp-cwd child needs absolute bin and config paths.
const binScript = fileURLToPath(new URL('../../../packages/ui/stdio-agent/src/bin.ts', import.meta.url))
const configPath = fileURLToPath(new URL('../cordis.yml', import.meta.url))
const tsxLoader = fileURLToPath(import.meta.resolve('tsx'))
// Dev/test run UNBUILT: `@deepseek-ai/dsh-*` imports resolve through the root
// tsconfig `paths` map, which tsx finds by searching UP from cwd. We spawn from
// a temp cwd OUTSIDE the repo, so point tsx at the repo tsconfig explicitly
// (repo root is four levels up from examples/echo-agent/tests).
// The temp cwd is outside the repo, so point tsx at the root config that resolves
// unbuilt workspace packages through `paths`.
const repoTsconfig = fileURLToPath(new URL('../../../tsconfig.json', import.meta.url))
// The real-API workflow runs up to 14 e2e files at once. Cold tsx/Loader
// startup can therefore outlive a tight smoke-test deadline before the child
// emits any output; 30s still detects a wedged process without confusing
// bounded CI contention with a lifecycle failure.
// Under parallel e2e load, cold tsx/Loader startup can exceed a tight deadline;
// 30s still detects a wedged child.
const PROCESS_TIMEOUT_MS = 30_000
// Leave enough room for the process-owned timeout to report captured output
// before Vitest aborts the test itself.
@@ -67,9 +48,8 @@ async function runEcho(lines: string[]): Promise<{ stdout: string; code: number
return new Promise((resolve, reject) => {
const proc = spawn(
process.execPath,
// --expose-internals: the example's cordis.yml loads the HMR plugin, which
// requires it (mirrors the `demo:echo` script). The whole point is to boot
// the example EXACTLY as it really runs, through the bin + Loader.
// --expose-internals: the example's cordis.yml loads the HMR plugin, which requires it
// (mirrors the `demo:echo` script).
['--expose-internals', '--import', tsxLoader, binScript, configPath],
{
cwd,