docs: trim generated prose

This commit is contained in:
Tianyi Cui
2026-07-12 03:36:43 +08:00
parent 3dca90261c
commit 75838e10b5
323 changed files with 2857 additions and 11833 deletions
@@ -139,14 +139,7 @@ describe('dsh-acp-agent composition', () => {
})
it('has the namespace-plugin export shape (no stray default) so the Loader keeps name/Config/apply', () => {
// Postmortem 0001 guard: a stray `export default apply` makes the Loader's
// `unwrapExports` (`exports.default ?? exports`) collapse the module to the
// bare `apply` function, DROPPING the named `name`/`Config`. This package has
// no `inject` export, so that collapse would NOT crash at load (the keyless
// bin smoke would still answer `initialize`) — it would silently lose its
// config schema. So guard the shape directly here: assert no `default`
// export, and that the real `unwrapExports` leaves `name`/`Config`/`apply`
// intact. Adding `export default` to src/index.ts fails this test.
// Loader must retain the namespace so name, Config, and apply survive unwrapping.
expect('default' in acpAgent).toBe(false)
expect(typeof acpAgent.apply).toBe('function')
+6 -26
View File
@@ -18,20 +18,9 @@ import { Readable, Writable } from 'node:stream'
import { afterEach, describe, expect, it } from 'vitest'
/**
* BUILT-ARTIFACT smoke for the published `dsh-acp-agent` bin. `load-path.e2e.ts`
* boots `src/bin.ts` under tsx — but the package's `bin` field points at
* `lib/bin.js`, run under plain `node` by a real consumer. This runs the REAL
* `lib/bin.js` under `node` (NOT tsx) and asserts it answers an `initialize`
* JSON-RPC frame, so a regression in the published entry (a settle race that
* exits before the bridge attaches, a stdout logger leaking onto the protocol)
* fails here.
*
* It build-gates: SKIPS if `lib/bin.js` is absent (suite run without
* `pnpm run build`); CI runs it after the build step. Setup mirrors a real
* install (a temp dir whose `node_modules` symlinks the built packages) and runs
* `node --expose-internals` (the cordis Loader resolves bare plugin specifiers
* via its internal module loader, active only under that flag). KEYLESS:
* `initialize` never reaches the model; a dummy key lets `llm-deepseek` boot.
* Built-ARTIFACT smoke for the published `dsh-acp-agent` bin. `load-path.e2e.ts` boots
* `src/bin.ts` under tsx — but the package's `bin` field points at `lib/bin.js`, run under
* plain `node` by a real consumer.
*/
const repoRoot = fileURLToPath(new URL('../../../../', import.meta.url))
@@ -48,12 +37,7 @@ const vendorPackages = [
'cordis', 'loader', 'include', 'timer', 'hmr', 'logger-console',
'schemastery', 'cosmokit',
]
// Third-party deps the ACP bridge needs at runtime. They are declared by
// `dsh-acp` (NOT by `acp-agent`), so they live under `packages/ui/acp/node_modules`
// and are NOT necessarily hoisted where THIS test file can resolve them — pnpm's
// strict layout only exposes a package's deps under that package. Resolve each
// from the `ui/acp` package directory (the one that declares it) so the lookup
// works regardless of hoisting, then symlink it into the consumer for plain node.
// Third-party deps the ACP bridge needs at runtime.
const npmDeps = ['@agentclientprotocol/sdk', 'zod']
const acpPkgDir = join(repoRoot, 'packages/ui/acp')
@@ -161,18 +145,14 @@ describe.skipIf(!existsSync(acpBin))('dsh-acp-agent BUILT bin (node lib/bin.js,
}, 30_000)
it('fails LOUD (non-zero exit + stderr) on a config whose directory does not exist', async () => {
// A typo'd config path must fail clearly, not exit 0. The include plugin
// itself cannot be imported from a non-existent dir; the Loader logs that and
// leaves the entry with no fiber, which boot()'s entry-load check throws on.
// A typo'd config path must fail clearly, not exit 0.
const { code, stderr } = await runBinExpectingExit('/nonexistent/dir/cordis.yml')
expect(code).not.toBe(0)
expect(stderr).toContain('failed to load')
}, 30_000)
it('fails LOUD (non-zero exit + stderr) on a missing config file in a real directory', async () => {
// The directory exists (the include imports), but the file does not — the
// include's init throws "config file not found", which surfaces as an
// unhandled rejection the fail-loud guard turns into a non-zero exit.
// Existing directory plus missing config exercises the include plugin's fail-loud path.
consumer = await makeConsumer()
const { code, stderr } = await runBinExpectingExit('./does-not-exist.yml', consumer)
expect(code).not.toBe(0)
+5 -23
View File
@@ -17,22 +17,9 @@ import {
} from '@agentclientprotocol/sdk'
/**
* REAL-load-path smoke for @deepseek-ai/dsh-acp-agent: boot the app through its
* own `bin` (the demo:acp entry) as a subprocess, driving the cordis Loader and
* `unwrapExports` over a minimal `cordis.yml` that loads THIS package. This is
* the guard a hand-built `ctx.plugin({...})` mount structurally cannot be — that
* bypasses `unwrapExports`, the exact path that once dropped the bridge's
* `inject` and shipped (docs/postmortem/0001). It exercises the headline ACP
* operations end-to-end: `initialize` → `session/new` → `session/load`.
*
* KEYLESS: `session/new` and `session/load` reach the agent FACTORY but never
* the model (no prompt is sent), so no DEEPSEEK_API_KEY is needed. A dummy key
* lets `llm-deepseek`'s `apply()` (key-PRESENT check only) boot the tree.
*
* The config is written into a temp dir whose cwd IS the session workspace, so
* the bash workdir validation passes. We point tsx at the repo-root tsconfig
* (TSX_TSCONFIG_PATH) because the child's cwd is outside the repo and the
* unbuilt `paths` map is found by searching UP from cwd.
* real-load-path smoke for @deepseek-ai/dsh-acp-agent: boot the app through its own `bin` (the
* demo:acp entry) as a subprocess, driving the cordis Loader and `unwrapExports` over a
* minimal `cordis.yml` that loads THIS package.
*/
const binScript = fileURLToPath(new URL('../src/bin.ts', import.meta.url))
@@ -131,13 +118,8 @@ describe('dsh-acp-agent real-load-path smoke (bin + Loader, keyless)', () => {
const { sessionId } = await client.newSession({ cwd, mcpServers: [] })
expect(sessionId).toBeTruthy()
// session/load reaches the resume FACTORY + persistence without the model:
// load an UNKNOWN id (loading the live `sessionId` would correctly reject as
// "already loaded"). The bridge consults `sessionPersistence.list()` then
// `agents.resume()`, both of which run from the JSON-RPC read loop OUTSIDE
// the bridge's inject scope — the exact path postmortem 0001 crashed. A
// healthy tree rejects with a not-found error; a broken export shape would
// instead throw "cannot get property … without inject" before reaching it.
// session/load reaches the resume FACTORY + persistence without the model: load an UNKNOWN
// id (loading the live `sessionId` would correctly reject as "already loaded").
const unknownId = '00000000-0000-4000-8000-000000000000'
await client.loadSession({ sessionId: unknownId, cwd, mcpServers: [] }).then(
() => { throw new Error('expected session/load of an unknown id to reject') },