Adds the snapshot-test harness and the keyless replay pipeline end-to-end. - snapshot-harness.ts: boots the real acp-agent subprocess via the cordis Loader (preserving TSX_TSCONFIG_PATH so unbuilt dsh-* imports resolve from a temp cwd), tees raw stdout into an SDK ClientSideConnection, interprets a per-scenario input.json DSL (initialize / newSession capturing the random sessionId / prompt / cancel), closes stdin to trigger graceful shutdown, and harvests the persisted session.jsonl. Failure-safe: a finally block SIGKILLs a live child, awaits its exit, and removes both temp dirs even on a thrown step or harvest. Raw bytes are buffered and decoded once (no multibyte split). - snapshot-normalize.ts (+ spec): two pure normalizers (stdout frames + session JSONL) scrub cwd, session ids / UUIDs, and JSON-RPC ids, and zero time / createdAt — but keep `seq` (deterministic by contract). normalizeStdout throws on a non-JSON line (the stdout-purity check). - start.ts: selects cordis.snapshot.yml (replay, providerless) or cordis.snapshot-record.yml (record, real adapter) from DSH_SNAPSHOT, skips .env in replay, and disposes the ctx on stdin end so persistence flushes before exit (harvest-after-flush, not on the prompt response). - acp.snapshot.ts: asserts the normalized stdout golden (and, for model scenarios, the re-persisted JSONL golden) via toMatchFileSnapshot; record mode writes the harvested log back to the scenario fixture; an orphan-fixture guard fails on an unregistered scenario dir. - handshake scenario: initialize + session/new (no model call; a header-only session.jsonl, since session/new persists no events). - vitest.snapshot.config.ts, test:snapshot / test:snapshot:record scripts, a pre-push snapshot job, and the knip entry. Incorporates Codex review: record-fixture writeback, failure-safe teardown, seq-not-scrubbed, harvest-after-flush. Per docs/rfc/implemented/2026-06-19.
44 lines
1.6 KiB
YAML
44 lines
1.6 KiB
YAML
# Snapshot-test RECORD config: a real run whose persisted session JSONL is
|
|
# harvested into a scenario fixture. Identical to cordis.yml (real llm-deepseek
|
|
# adapter + JSONL persistence) — recording must exercise the REAL model so the
|
|
# recorded log is a genuine product of the system. Needs DEEPSEEK_API_KEY.
|
|
#
|
|
# It is a separate file (rather than reusing cordis.yml) only so the snapshot
|
|
# harness selects it explicitly via $DSH_SNAPSHOT=record and so its persistence
|
|
# root can be pointed at the harness's harvest directory by the same env the
|
|
# replay path uses. The graceful-shutdown path in start.ts flushes persistence
|
|
# before exit so the harvested log is complete.
|
|
|
|
- id: timer
|
|
name: '@cordisjs/plugin-timer'
|
|
|
|
# Shared provider/tool core, INCLUDING the real llm-deepseek adapter.
|
|
- id: base
|
|
name: '@cordisjs/plugin-include'
|
|
config:
|
|
path: '../base.yml'
|
|
|
|
- id: agent-loop
|
|
name: '@deepseek-ai/dsh-agent-loop'
|
|
config:
|
|
agents: []
|
|
|
|
- id: session-persistence
|
|
name: '@deepseek-ai/dsh-session-persistence-jsonl'
|
|
config:
|
|
root: !!js process.env.DSH_SNAPSHOT_SESSIONS_ROOT
|
|
|
|
- id: acp
|
|
name: '@deepseek-ai/dsh-acp'
|
|
config:
|
|
model: deepseek-v4-flash
|
|
systemPrompt: |
|
|
You are a coding assistant driven over the Agent Client Protocol.
|
|
|
|
Your only tools are bash (plus bash_output/bash_kill for background
|
|
tasks). Do ALL file operations through bash: read with cat/sed/head,
|
|
search with grep, write with heredocs (cat <<'EOF' > file), edit with
|
|
sed or a rewrite. Each bash call runs in a fresh shell — pass workdir
|
|
instead of cd. Check the [exit code: N] marker; verify your work. Keep
|
|
answers brief and factual.
|