Files
zero/tests/plan.test.ts
8d49c3c0a5 fix plan mode and add test (#2)
* fix plan mode and add test

* Address review: wire plan mode, harden test script, restore friendly errors

- Wire /plan into agent behavior: add PLAN_MODE_SYSTEM_PROMPT and a planMode
  option on runAgent; App passes isPlanMode through so the agent actually
  plans without editing instead of only changing UI color.
- Harden test script to "bun test ./tests --timeout 15000" for deterministic
  discovery and a bounded runtime so it always exits.
- Restore friendly provider-setup/auth/network error mapping via
  toFriendlyError(); debug mode still records the full error object.
- Add tests/agent-loop.test.ts covering prompt selection and the
  tool-call -> result -> final-answer loop with a mock provider.

Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>

---------

Co-authored-by: Kevin Codex <[email protected]>
Co-authored-by: Claude Opus 4.8 (1M context) <[email protected]>
2026-05-31 10:08:01 +08:00

45 lines
1.6 KiB
TypeScript

import { describe, it, expect, beforeEach } from 'bun:test';
import { planTool, getCurrentPlan, clearPlan } from '../src/tools/plan';
const samplePlan = [
{ id: '1', content: 'First step', status: 'completed' as const },
{ id: '2', content: 'Second step', status: 'in_progress' as const, notes: 'halfway' },
{ id: '3', content: 'Third step', status: 'pending' as const },
];
describe('planTool', () => {
beforeEach(() => clearPlan());
it('stores the plan and reflects it via getCurrentPlan', async () => {
await planTool.execute({ plan: samplePlan });
expect(getCurrentPlan()).toEqual(samplePlan);
});
it('formats the plan with status markers and notes', async () => {
const output = await planTool.execute({ plan: samplePlan });
expect(output).toContain('1. ✓ [completed] First step');
expect(output).toContain('2. ◉ [in_progress] Second step');
expect(output).toContain('Notes: halfway');
expect(output).toContain('3. ○ [pending] Third step');
});
it('clearPlan empties the stored plan', async () => {
await planTool.execute({ plan: samplePlan });
clearPlan();
expect(getCurrentPlan()).toEqual([]);
});
it('getCurrentPlan returns a copy, not the internal reference', async () => {
await planTool.execute({ plan: samplePlan });
const snapshot = getCurrentPlan();
snapshot.push({ id: 'x', content: 'mutation', status: 'pending' });
expect(getCurrentPlan()).toHaveLength(samplePlan.length);
});
it('rejects invalid status values', async () => {
await expect(
planTool.execute({ plan: [{ id: '1', content: 'bad', status: 'nope' }] })
).rejects.toThrow();
});
});