// Proof for kb#170 capture pipeline (classify -> Todoist task shape), // run with: // BGE_M3_URL=http://localhost:11436/v1/embeddings node src/capture.test.mjs // // Deliberately stubs createTask/listProjects instead of calling the real // Todoist API — this proves the classify -> label/priority/project mapping // logic without writing test data into the user's live Todoist account // (kb#170 report: no live Todoist writes were made while proving this out). import assert from 'node:assert/strict'; import { todoistCaptureIdea } from './capture.js'; let passed = 0; function check(label, fn) { fn(); passed++; console.log(`ok - ${label}`); } const projects = [ { id: '6CrfPQ8FXxf5ghrx', name: 'Inbox', is_inbox: true }, { id: '6cg4j8CX3vj7H9rJ', name: 'Family' }, ]; function makeStubCreateTask() { const calls = []; const createTask = async (args) => { calls.push(args); return { id: 'stub-1', content: args.content, project_id: args.project_id, priority: args.priority, labels: args.labels }; }; return { createTask, calls }; } const { createTask: createTaskFamily, calls: callsFamily } = makeStubCreateTask(); const familyResult = await todoistCaptureIdea( { text: 'позвонить маме поздравить с днём рождения' }, { listProjects: async () => projects, createTask: createTaskFamily } ); check('семья idea auto-routes to the existing Family project', () => { assert.equal(familyResult.classification.area.label, 'семья'); assert.equal(callsFamily[0].project_id, '6cg4j8CX3vj7H9rJ'); }); check('семья idea is labelled area-семья + urgency-*', () => { assert.ok(callsFamily[0].labels.includes('area-семья')); assert.ok(callsFamily[0].labels.some((l) => l.startsWith('urgency-'))); }); const { createTask: createTaskUrgent, calls: callsUrgent } = makeStubCreateTask(); await todoistCaptureIdea( { text: 'починить квоту Kimi у Adolf, срочно сегодня' }, { listProjects: async () => projects, createTask: createTaskUrgent } ); check('high-urgency idea gets Todoist priority 4 (urgent)', () => { assert.equal(callsUrgent[0].priority, 4); }); check('adolf-area idea is NOT auto-routed to a project (no matching project exists)', () => { assert.equal(callsUrgent[0].project_id, undefined); }); const { createTask: createTaskProject, calls: callsProject } = makeStubCreateTask(); await todoistCaptureIdea( { text: 'купить новый пылесос для дома', project_id: 'explicit-override' }, { listProjects: async () => projects, createTask: createTaskProject } ); check('an explicit project_id always wins over auto-routing', () => { assert.equal(callsProject[0].project_id, 'explicit-override'); }); const { createTask: createTaskDecompose, calls: callsDecompose } = makeStubCreateTask(); await todoistCaptureIdea( { text: 'спроектировать и запустить proactive-секретаря на Agap' }, { listProjects: async () => projects, createTask: createTaskDecompose } ); check('a multi-step idea gets the "decompose" label', () => { assert.ok(callsDecompose[0].labels.includes('decompose')); }); console.log(`\n${passed} passed`);