Merge remote-tracking branch 'origin/master' into simpl-e-acp-trim

This commit is contained in:
Tianyi Cui
2026-07-04 21:11:25 +08:00
112 changed files with 1825 additions and 835 deletions

View File

@@ -20,7 +20,7 @@ describe('acp bridge', () => {
})
afterEach(async () => {
// e2e/integration tests own their resources (AGENTS.md): dispose even on
// e2e/integration tests own their resources (docs/testing.md): dispose even on
// failure so a flaky run never leaks a context or persistence dir.
if (harness) await harness.dispose()
harness = undefined

View File

@@ -158,7 +158,7 @@ export async function makeBridgeHarness(options: {
* Plug the REAL `dsh-bash-local` executor + `dsh-tool-bash` tools (instead of
* a test's own inline tool). Lets a test drive the actual `bash` tool — its
* real `presentCall`/`presentResult` — through the bridge, so tool-call UI
* tests verify the SHIPPING tool, not a stand-in (AGENTS.md "prefer the real
* tests verify the SHIPPING tool, not a stand-in (docs/testing.md "prefer the real
* implementation over a mock in tests").
*/
withBash?: boolean

View File

@@ -62,7 +62,7 @@ describe('acp bridge — session/load replay', () => {
// bridge. The replayed tool_call/tool_call_update must carry the tool's OWN
// presentation — identical to how it streamed live — via a throwaway
// presenter that pairs call→result as the log replays in order. Uses the
// shipping tool (withBash), not a stand-in (AGENTS.md "prefer the real
// shipping tool (withBash), not a stand-in (docs/testing.md "prefer the real
// implementation over a mock in tests").
live = await makeBridgeHarness({
storageDir,

View File

@@ -289,7 +289,7 @@ describe('ToolPresenter (tool-owned presentation via the tool registry)', () =>
it('a THROWING presentCall/presentResult is contained: generic fallback + onError, never propagates', () => {
// A buggy tool whose display callbacks throw must NOT fail a live turn or a
// session/load replay (AGENTS.md "contain callback exceptions at the
// session/load replay (docs/defensive-patterns.md "contain callback exceptions at the
// boundary"). The presenter swallows the throw, reports via onError, and
// falls back to the generic presentation.
const boom: ToolDefinition = {
@@ -381,7 +381,7 @@ describe('ToolPresenter (tool-owned presentation via the tool registry)', () =>
it('forwards fs-tool render intents onto the wire (REAL read → generic locations, edit → diff content)', async () => {
// Use the SHIPPING fs tools (not a stand-in), booted through their real
// plugins, so the wire tool_call carries the actual presentCall output —
// read's follow-along `locations` and edit's `diff` content block. (AGENTS.md
// read's follow-along `locations` and edit's `diff` content block. (docs/testing.md
// "prefer the real implementation over a mock".)
const ctx = new Context()
await ctx.plugin(SystemPrompt)

View File

@@ -82,7 +82,7 @@ describe('acp bridge — turn outcomes', () => {
it('the REAL bash tool drives the tool-call UI end-to-end: command title + description block + console output', async () => {
// Use the SHIPPING tool (dsh-tool-bash + dsh-bash-local), not an inline
// stand-in, so this verifies the actual presentCall/presentResult the editor
// sees (AGENTS.md "prefer the real implementation over a mock in tests").
// sees (docs/testing.md "prefer the real implementation over a mock").
// The mock MODEL still scripts the tool call (no real LLM needed), but the
// tool and executor are real: a real `echo` runs and its real output flows
// back through the bridge.