diff --git a/packages/examples/cli-demo/src/cli.ts b/packages/examples/cli-demo/src/cli.ts index 63c08ae39f..3a8fecc7a8 100644 --- a/packages/examples/cli-demo/src/cli.ts +++ b/packages/examples/cli-demo/src/cli.ts @@ -361,7 +361,8 @@ export function formatTurnFailure(reason: TurnEndReason): string { /** * Execute one CLI invocation. Argument and boot failures never write stdout; - * every booted context is disposed before this promise resolves. + * context disposal is awaited before return, and its failure does not replace + * an earlier diagnostic. * @param args - arguments after the executable name. * @param runtime - optional injected process boundaries for tests and embedding. * @returns the ordinary process exit code; the thin bin overrides it for Unix signals. @@ -421,7 +422,7 @@ export async function executeCli(args: readonly string[], runtime: CliRuntime = try { await disposeContext(ctx) } catch (error: unknown) { - diagnostic ??= `${CLI_NAME}: dispose failed: ${toError(error).message}\n` + diagnostic = `${diagnostic ?? ''}${CLI_NAME}: dispose failed: ${toError(error).message}\n` exitCode = 1 } } diff --git a/packages/examples/cli-demo/tests/cli.spec.ts b/packages/examples/cli-demo/tests/cli.spec.ts index fcdf8a3004..8c41236829 100644 --- a/packages/examples/cli-demo/tests/cli.spec.ts +++ b/packages/examples/cli-demo/tests/cli.spec.ts @@ -398,6 +398,18 @@ describe('runOneShot and executeCli', () => { expect(disposalOutput.stderr).toContain('dispose exploded') }) + it('reports disposal failure alongside an earlier run failure', async () => { + const ctx = new Context() + liveContexts.push(ctx) + const output = await invoke(ctx, ['task'], { failDispose: true }) + expect(output).toEqual({ + code: 1, + stdout: '', + stderr: 'dsh-cli-demo: config must create exactly one top-level agent, found 0\n' + + 'dsh-cli-demo: dispose failed: dispose exploded\n', + }) + }) + it('cancels startup work and queued work before the correlated turn begins', async () => { const startup = await harness(['hang']) let started!: () => void