Files
Agent-System/web/src/engine/planCard.test.ts
T
weichenandCursor 29bb63f766 feat(web): render PLAN_CONFIRM from PlanView without local AST writes
Plan actions post to the decision API and reconcile on 409 instead of mutating documents.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-16 01:09:05 +00:00

68 lines
2.3 KiB
TypeScript

import test from 'node:test';
import assert from 'node:assert/strict';
import {
applyPlanViewToCard,
cardFromPlanView,
isPlanConfirmCard,
markPlanCard,
planCardTouchesLocalAST,
reconcileConflictCard,
} from './planCard';
import { InteractiveCardData } from '../types/workbench';
import type { IntentPlanView } from '../api/intentPlans';
const sample: IntentPlanView = {
plan_id: 'pln_1',
revision: 1,
status: 'awaiting_confirmation',
execution_mode: 'validated_only',
safe_summary: '查法规并生成任务',
steps: [
{ step_id: 'stp_1', action_key: 'regulation.query', status: 'pending', safe_summary: '查询法规' },
{ step_id: 'stp_2', action_key: 'task.run', status: 'pending', safe_summary: '生成任务', depends_on: ['stp_1'] },
],
};
test('PLAN_CONFIRM 卡片来自 PlanView 且不触达 AST', () => {
const card = cardFromPlanView(sample);
assert.equal(card.cardType, 'PLAN_CONFIRM');
assert.equal(card.planId, 'pln_1');
assert.equal(card.stepCount, 2);
assert.equal(card.validatedOnly, true);
assert.equal(planCardTouchesLocalAST('plan_confirm'), false);
assert.equal(isPlanConfirmCard(card), true);
});
test('409 冲突把卡片标为 outdated 并换上最新 revision', () => {
const card = cardFromPlanView(sample);
const latest = { ...sample, revision: 2, status: 'awaiting_confirmation' as const };
const next = reconcileConflictCard(card, latest);
assert.equal(next.status, 'outdated');
assert.equal(next.planRevision, 2);
});
test('GET reconcile 用权威 PlanView 覆盖本地 executing,不假装成功', () => {
const submitting = markPlanCard(cardFromPlanView(sample), 'executing');
const server: IntentPlanView = { ...sample, status: 'awaiting_confirmation' };
const reconciled = applyPlanViewToCard(submitting, server);
assert.equal(reconciled.status, 'active');
assert.notEqual(reconciled.status, 'resolved');
});
test('过期计划映射 expired', () => {
const card = cardFromPlanView({ ...sample, status: 'expired' });
assert.equal(card.status, 'expired');
});
test('非计划卡不被误判', () => {
const card: InteractiveCardData = {
cardId: 'c-doc',
cardType: 'CONFIRMATION',
title: '驳回',
status: 'active',
ttlTurns: 3,
actions: [],
};
assert.equal(isPlanConfirmCard(card), false);
});