@cat-kit/agent-context 1.1.3 → 1.1.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,2 +1,2 @@
1
- import{readRawContext as e}from"../context/reader.js";import{validate as t}from"../context/validator.js";async function n(){let{snapshot:n,currentPlanCount:r}=await e(process.cwd()),i=t(n,r);if(!i.valid){for(let e of i.errors)console.log(`❌ ${e}`);process.exitCode=1;return}if(i.context===null){console.log(`ℹ 无活跃上下文`);return}let a=i.context,o=a.currentPlan?`plan-${a.currentPlan.number} (${a.currentPlan.status})`:`无`,s=a.preparing.length>0?a.preparing.map(e=>`plan-${e.number}`).join(`, `):`无`;console.log(``),console.log(`Agent Context Status`),console.log(`────────────────────`),console.log(`当前计划: ${o}`),console.log(`待执行队列: ${s}`),console.log(`已归档: ${a.doneCount} 个`)}export{n as statusCommand};
1
+ import{readRawContext as e}from"../context/reader.js";import{validate as t}from"../context/validator.js";async function n(){let{snapshot:n,currentPlanCount:r}=await e(process.cwd()),i=t(n,r);if(!i.valid){for(let e of i.errors)console.log(`❌ ${e}`);process.exitCode=1;return}if(i.context===null){console.log(`ℹ 无活跃上下文`);return}let a=i.context,o=a.currentPlan?`plan-${a.currentPlan.number} (${a.currentPlan.status})`:`无`,s=a.preparing.length>0?a.preparing.map(e=>`plan-${e.number}`).join(`, `):`无`;console.log(``),console.log(`Agent Context Status`),console.log(`────────────────────`),console.log(`当前计划: ${o}`),console.log(`待执行队列: ${s}`),console.log(`已归档: ${a.done.length} 个`)}export{n as statusCommand};
2
2
  //# sourceMappingURL=status.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"status.js","names":[],"sources":["../../src/commands/status.ts"],"sourcesContent":["import { readRawContext, validate } from '../context/index.js'\n\nexport async function statusCommand(): Promise<void> {\n const { snapshot, currentPlanCount } = await readRawContext(process.cwd())\n const result = validate(snapshot, currentPlanCount)\n\n if (!result.valid) {\n for (const error of result.errors) {\n console.log(`❌ ${error}`) // eslint-disable-line no-console\n }\n process.exitCode = 1\n return\n }\n\n if (result.context === null) {\n console.log('ℹ 无活跃上下文') // eslint-disable-line no-console\n return\n }\n\n const ctx = result.context\n const current = ctx.currentPlan\n ? `plan-${ctx.currentPlan.number} (${ctx.currentPlan.status})`\n : '无'\n const preparing =\n ctx.preparing.length > 0\n ? ctx.preparing.map((p) => `plan-${p.number}`).join(', ')\n : '无'\n\n console.log('') // eslint-disable-line no-console\n console.log('Agent Context Status') // eslint-disable-line no-console\n console.log('────────────────────') // eslint-disable-line no-console\n console.log(`当前计划: ${current}`) // eslint-disable-line no-console\n console.log(`待执行队列: ${preparing}`) // eslint-disable-line no-console\n console.log(`已归档: ${ctx.doneCount} 个`) // eslint-disable-line no-console\n}\n"],"mappings":"yGAEA,eAAsB,GAA+B,CACnD,GAAM,CAAE,WAAU,oBAAqB,MAAM,EAAe,QAAQ,KAAK,CAAC,CACpE,EAAS,EAAS,EAAU,EAAiB,CAEnD,GAAI,CAAC,EAAO,MAAO,CACjB,IAAK,IAAM,KAAS,EAAO,OACzB,QAAQ,IAAI,KAAK,IAAQ,CAE3B,QAAQ,SAAW,EACnB,OAGF,GAAI,EAAO,UAAY,KAAM,CAC3B,QAAQ,IAAI,WAAW,CACvB,OAGF,IAAM,EAAM,EAAO,QACb,EAAU,EAAI,YAChB,QAAQ,EAAI,YAAY,OAAO,IAAI,EAAI,YAAY,OAAO,GAC1D,IACE,EACJ,EAAI,UAAU,OAAS,EACnB,EAAI,UAAU,IAAK,GAAM,QAAQ,EAAE,SAAS,CAAC,KAAK,KAAK,CACvD,IAEN,QAAQ,IAAI,GAAG,CACf,QAAQ,IAAI,uBAAuB,CACnC,QAAQ,IAAI,uBAAuB,CACnC,QAAQ,IAAI,UAAU,IAAU,CAChC,QAAQ,IAAI,UAAU,IAAY,CAClC,QAAQ,IAAI,WAAW,EAAI,UAAU,IAAI"}
1
+ {"version":3,"file":"status.js","names":[],"sources":["../../src/commands/status.ts"],"sourcesContent":["import { readRawContext, validate } from '../context/index.js'\n\nexport async function statusCommand(): Promise<void> {\n const { snapshot, currentPlanCount } = await readRawContext(process.cwd())\n const result = validate(snapshot, currentPlanCount)\n\n if (!result.valid) {\n for (const error of result.errors) {\n console.log(`❌ ${error}`) // eslint-disable-line no-console\n }\n process.exitCode = 1\n return\n }\n\n if (result.context === null) {\n console.log('ℹ 无活跃上下文') // eslint-disable-line no-console\n return\n }\n\n const ctx = result.context\n const current = ctx.currentPlan\n ? `plan-${ctx.currentPlan.number} (${ctx.currentPlan.status})`\n : '无'\n const preparing =\n ctx.preparing.length > 0 ? ctx.preparing.map((p) => `plan-${p.number}`).join(', ') : '无'\n\n console.log('')\n console.log('Agent Context Status')\n console.log('────────────────────')\n console.log(`当前计划: ${current}`)\n console.log(`待执行队列: ${preparing}`)\n console.log(`已归档: ${ctx.done.length} 个`)\n}\n"],"mappings":"yGAEA,eAAsB,GAA+B,CACnD,GAAM,CAAE,WAAU,oBAAqB,MAAM,EAAe,QAAQ,KAAK,CAAC,CACpE,EAAS,EAAS,EAAU,EAAiB,CAEnD,GAAI,CAAC,EAAO,MAAO,CACjB,IAAK,IAAM,KAAS,EAAO,OACzB,QAAQ,IAAI,KAAK,IAAQ,CAE3B,QAAQ,SAAW,EACnB,OAGF,GAAI,EAAO,UAAY,KAAM,CAC3B,QAAQ,IAAI,WAAW,CACvB,OAGF,IAAM,EAAM,EAAO,QACb,EAAU,EAAI,YAChB,QAAQ,EAAI,YAAY,OAAO,IAAI,EAAI,YAAY,OAAO,GAC1D,IACE,EACJ,EAAI,UAAU,OAAS,EAAI,EAAI,UAAU,IAAK,GAAM,QAAQ,EAAE,SAAS,CAAC,KAAK,KAAK,CAAG,IAEvF,QAAQ,IAAI,GAAG,CACf,QAAQ,IAAI,uBAAuB,CACnC,QAAQ,IAAI,uBAAuB,CACnC,QAAQ,IAAI,UAAU,IAAU,CAChC,QAAQ,IAAI,UAAU,IAAY,CAClC,QAAQ,IAAI,WAAW,EAAI,KAAK,OAAO,IAAI"}
@@ -1,2 +1,2 @@
1
- import{readRawContext as e}from"../context/reader.js";import{validate as t}from"../context/validator.js";async function n(){let{snapshot:n,currentPlanCount:r}=await e(process.cwd()),i=t(n,r);if(i.context===null){console.log(`ℹ 无 .agent-context 目录`);return}if(i.valid){console.log(`✅ 校验通过`);let e=i.context,t=e.currentPlan?`plan-${e.currentPlan.number} (${e.currentPlan.status})`:`无`;console.log(` 当前计划: ${t}`),console.log(` 待执行: ${e.preparing.length} 个`),console.log(` 已归档: ${e.doneCount} 个`);return}for(let e of i.errors)console.log(`❌ ${e}`);process.exitCode=1}export{n as validateCommand};
1
+ import{readRawContext as e}from"../context/reader.js";import{validate as t}from"../context/validator.js";async function n(){let{snapshot:n,currentPlanCount:r}=await e(process.cwd()),i=t(n,r);if(i.context===null){console.log(`⚠️ 无 .agent-context 目录`);return}if(i.valid){console.log(`✅ 校验通过`);let e=i.context,t=e.currentPlan?`plan-${e.currentPlan.number} (${e.currentPlan.status})`:`无`;console.log(` 当前计划: ${t}`),console.log(` 待执行: ${e.preparing.length} 个`),console.log(` 已归档: ${e.done.length} 个`);return}for(let e of i.errors)console.log(`❌ ${e}`);process.exitCode=1}export{n as validateCommand};
2
2
  //# sourceMappingURL=validate.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"validate.js","names":[],"sources":["../../src/commands/validate.ts"],"sourcesContent":["import { readRawContext, validate } from '../context/index.js'\n\nexport async function validateCommand(): Promise<void> {\n const { snapshot, currentPlanCount } = await readRawContext(process.cwd())\n const result = validate(snapshot, currentPlanCount)\n\n if (result.context === null) {\n console.log(' 无 .agent-context 目录') // eslint-disable-line no-console\n return\n }\n\n if (result.valid) {\n console.log('✅ 校验通过') // eslint-disable-line no-console\n const ctx = result.context\n const current = ctx.currentPlan\n ? `plan-${ctx.currentPlan.number} (${ctx.currentPlan.status})`\n : '无'\n console.log(` 当前计划: ${current}`) // eslint-disable-line no-console\n console.log(` 待执行: ${ctx.preparing.length} 个`) // eslint-disable-line no-console\n console.log(` 已归档: ${ctx.doneCount} 个`) // eslint-disable-line no-console\n return\n }\n\n for (const error of result.errors) {\n console.log(`❌ ${error}`) // eslint-disable-line no-console\n }\n process.exitCode = 1\n}\n"],"mappings":"yGAEA,eAAsB,GAAiC,CACrD,GAAM,CAAE,WAAU,oBAAqB,MAAM,EAAe,QAAQ,KAAK,CAAC,CACpE,EAAS,EAAS,EAAU,EAAiB,CAEnD,GAAI,EAAO,UAAY,KAAM,CAC3B,QAAQ,IAAI,wBAAwB,CACpC,OAGF,GAAI,EAAO,MAAO,CAChB,QAAQ,IAAI,SAAS,CACrB,IAAM,EAAM,EAAO,QACb,EAAU,EAAI,YAChB,QAAQ,EAAI,YAAY,OAAO,IAAI,EAAI,YAAY,OAAO,GAC1D,IACJ,QAAQ,IAAI,WAAW,IAAU,CACjC,QAAQ,IAAI,UAAU,EAAI,UAAU,OAAO,IAAI,CAC/C,QAAQ,IAAI,UAAU,EAAI,UAAU,IAAI,CACxC,OAGF,IAAK,IAAM,KAAS,EAAO,OACzB,QAAQ,IAAI,KAAK,IAAQ,CAE3B,QAAQ,SAAW"}
1
+ {"version":3,"file":"validate.js","names":[],"sources":["../../src/commands/validate.ts"],"sourcesContent":["import { readRawContext, validate } from '../context/index.js'\n\nexport async function validateCommand(): Promise<void> {\n const { snapshot, currentPlanCount } = await readRawContext(process.cwd())\n const result = validate(snapshot, currentPlanCount)\n\n if (result.context === null) {\n console.log('⚠️ 无 .agent-context 目录')\n return\n }\n\n if (result.valid) {\n console.log('✅ 校验通过')\n const ctx = result.context\n const current = ctx.currentPlan\n ? `plan-${ctx.currentPlan.number} (${ctx.currentPlan.status})`\n : '无'\n console.log(` 当前计划: ${current}`)\n console.log(` 待执行: ${ctx.preparing.length} 个`)\n console.log(` 已归档: ${ctx.done.length} 个`)\n return\n }\n\n for (const error of result.errors) {\n console.log(`❌ ${error}`)\n }\n process.exitCode = 1\n}\n"],"mappings":"yGAEA,eAAsB,GAAiC,CACrD,GAAM,CAAE,WAAU,oBAAqB,MAAM,EAAe,QAAQ,KAAK,CAAC,CACpE,EAAS,EAAS,EAAU,EAAiB,CAEnD,GAAI,EAAO,UAAY,KAAM,CAC3B,QAAQ,IAAI,yBAAyB,CACrC,OAGF,GAAI,EAAO,MAAO,CAChB,QAAQ,IAAI,SAAS,CACrB,IAAM,EAAM,EAAO,QACb,EAAU,EAAI,YAChB,QAAQ,EAAI,YAAY,OAAO,IAAI,EAAI,YAAY,OAAO,GAC1D,IACJ,QAAQ,IAAI,WAAW,IAAU,CACjC,QAAQ,IAAI,UAAU,EAAI,UAAU,OAAO,IAAI,CAC/C,QAAQ,IAAI,UAAU,EAAI,KAAK,OAAO,IAAI,CAC1C,OAGF,IAAK,IAAM,KAAS,EAAO,OACzB,QAAQ,IAAI,KAAK,IAAQ,CAE3B,QAAQ,SAAW"}
@@ -1,2 +1,2 @@
1
- import{existsSync as e}from"node:fs";import{join as t}from"node:path";import{readFile as n,readdir as r}from"node:fs/promises";const i=/^plan-(\d+)$/,a=/^>\s*状态:\s*(未执行|已执行)\s*$/m;async function o(n){let r=t(n,`.agent-context`);if(!e(r))return{snapshot:null,currentPlanCount:0};let i=await c(r),a=await c(t(r,`preparing`)),o=await l(t(r,`done`));return{snapshot:{root:r,currentPlan:i[0]??null,preparing:a,doneCount:o},currentPlanCount:i.length}}async function s(r){let i=t(r,`plan.md`);if(!e(i))return`未执行`;let o=(await n(i,`utf-8`)).match(a);return o?o[1]:`未执行`}async function c(n){if(!e(n))return[];let a=await r(n,{withFileTypes:!0}),o=[];for(let e of a){if(!e.isDirectory())continue;let r=e.name.match(i);if(!r?.[1])continue;let a=parseInt(r[1],10),c=t(n,e.name),l=await s(c);o.push({number:a,status:l,dir:c})}return o.sort((e,t)=>e.number-t.number)}async function l(t){return e(t)?(await r(t,{withFileTypes:!0})).filter(e=>e.isDirectory()).length:0}export{o as readRawContext};
1
+ import{existsSync as e}from"node:fs";import{join as t}from"node:path";import{readFile as n,readdir as r}from"node:fs/promises";const i=/^plan-(\d+)$/,a=/^plan-(\d+)(?:-\d{8})?$/,o=/^>\s*状态:\s*(未执行|已执行)$/m,s=/^>?[ \t]*状态[::].*$/m;async function c(n){let r=t(n,`.agent-context`);if(!e(r))return{snapshot:null,currentPlanCount:0};let i=await u(r),a=await u(t(r,`preparing`)),o=await d(t(r,`done`));return{snapshot:{root:r,currentPlan:i[0]??null,preparing:a,done:o},currentPlanCount:i.length}}async function l(r){let i=t(r,`plan.md`);if(!e(i))return`未执行`;let a=await n(i,`utf-8`),c=a.match(o);return c?c[1]:s.test(a)?`未知`:`未执行`}async function u(n){if(!e(n))return[];let a=await r(n,{withFileTypes:!0}),o=[];for(let e of a){if(!e.isDirectory())continue;let r=e.name.match(i);if(!r?.[1])continue;let a=parseInt(r[1],10),s=t(n,e.name),c=await l(s);o.push({number:a,status:c,dir:s})}return o.sort((e,t)=>e.number-t.number)}async function d(n){if(!e(n))return[];let i=await r(n,{withFileTypes:!0}),o=[];for(let e of i){if(!e.isDirectory())continue;let r=e.name.match(a);r?.[1]&&o.push({number:parseInt(r[1],10),dir:t(n,e.name)})}return o.sort((e,t)=>e.number-t.number)}export{c as readRawContext};
2
2
  //# sourceMappingURL=reader.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"reader.js","names":[],"sources":["../../src/context/reader.ts"],"sourcesContent":["import { readdir, readFile } from 'node:fs/promises'\nimport { existsSync } from 'node:fs'\nimport { join } from 'node:path'\n\nimport type { ContextSnapshot, PlanInfo, PlanStatus } from '../types.js'\n\nconst PLAN_DIR_RE = /^plan-(\\d+)$/\nconst STATUS_RE = /^>\\s*状态:\\s*(未执行|已执行)\\s*$/m\n\n// ── Public API ───────────────────────────────────────\n\nexport async function readContext(cwd: string): Promise<ContextSnapshot | null> {\n const { snapshot } = await readRawContext(cwd)\n return snapshot\n}\n\nexport async function readRawContext(\n cwd: string\n): Promise<{ snapshot: ContextSnapshot | null; currentPlanCount: number }> {\n const root = join(cwd, '.agent-context')\n\n if (!existsSync(root)) {\n return { snapshot: null, currentPlanCount: 0 }\n }\n\n const currentPlans = await readPlanDirs(root)\n const preparing = await readPlanDirs(join(root, 'preparing'))\n const doneCount = await countDirs(join(root, 'done'))\n\n const snapshot: ContextSnapshot = {\n root,\n currentPlan: currentPlans[0] ?? null,\n preparing,\n doneCount\n }\n\n return { snapshot, currentPlanCount: currentPlans.length }\n}\n\nexport async function readPlanStatus(planDir: string): Promise<PlanStatus> {\n const planFile = join(planDir, 'plan.md')\n\n if (!existsSync(planFile)) {\n return '未执行'\n }\n\n const content = await readFile(planFile, 'utf-8')\n const match = content.match(STATUS_RE)\n return match ? (match[1] as PlanStatus) : '未执行'\n}\n\n// ── Helpers ──────────────────────────────────────────\n\nasync function readPlanDirs(parentDir: string): Promise<PlanInfo[]> {\n if (!existsSync(parentDir)) return []\n\n const entries = await readdir(parentDir, { withFileTypes: true })\n const plans: PlanInfo[] = []\n\n for (const entry of entries) {\n if (!entry.isDirectory()) continue\n const match = entry.name.match(PLAN_DIR_RE)\n if (!match?.[1]) continue\n const number = parseInt(match[1], 10)\n const dir = join(parentDir, entry.name)\n const status = await readPlanStatus(dir)\n plans.push({ number, status, dir })\n }\n\n return plans.sort((a, b) => a.number - b.number)\n}\n\nasync function countDirs(dir: string): Promise<number> {\n if (!existsSync(dir)) return 0\n const entries = await readdir(dir, { withFileTypes: true })\n return entries.filter(e => e.isDirectory()).length\n}\n"],"mappings":"+HAMA,MAAM,EAAc,eACd,EAAY,4BASlB,eAAsB,EACpB,EACyE,CACzE,IAAM,EAAO,EAAK,EAAK,iBAAiB,CAExC,GAAI,CAAC,EAAW,EAAK,CACnB,MAAO,CAAE,SAAU,KAAM,iBAAkB,EAAG,CAGhD,IAAM,EAAe,MAAM,EAAa,EAAK,CACvC,EAAY,MAAM,EAAa,EAAK,EAAM,YAAY,CAAC,CACvD,EAAY,MAAM,EAAU,EAAK,EAAM,OAAO,CAAC,CASrD,MAAO,CAAE,SAPyB,CAChC,OACA,YAAa,EAAa,IAAM,KAChC,YACA,YACD,CAEkB,iBAAkB,EAAa,OAAQ,CAG5D,eAAsB,EAAe,EAAsC,CACzE,IAAM,EAAW,EAAK,EAAS,UAAU,CAEzC,GAAI,CAAC,EAAW,EAAS,CACvB,MAAO,MAIT,IAAM,GADU,MAAM,EAAS,EAAU,QAAQ,EAC3B,MAAM,EAAU,CACtC,OAAO,EAAS,EAAM,GAAoB,MAK5C,eAAe,EAAa,EAAwC,CAClE,GAAI,CAAC,EAAW,EAAU,CAAE,MAAO,EAAE,CAErC,IAAM,EAAU,MAAM,EAAQ,EAAW,CAAE,cAAe,GAAM,CAAC,CAC3D,EAAoB,EAAE,CAE5B,IAAK,IAAM,KAAS,EAAS,CAC3B,GAAI,CAAC,EAAM,aAAa,CAAE,SAC1B,IAAM,EAAQ,EAAM,KAAK,MAAM,EAAY,CAC3C,GAAI,CAAC,IAAQ,GAAI,SACjB,IAAM,EAAS,SAAS,EAAM,GAAI,GAAG,CAC/B,EAAM,EAAK,EAAW,EAAM,KAAK,CACjC,EAAS,MAAM,EAAe,EAAI,CACxC,EAAM,KAAK,CAAE,SAAQ,SAAQ,MAAK,CAAC,CAGrC,OAAO,EAAM,MAAM,EAAG,IAAM,EAAE,OAAS,EAAE,OAAO,CAGlD,eAAe,EAAU,EAA8B,CAGrD,OAFK,EAAW,EAAI,EACJ,MAAM,EAAQ,EAAK,CAAE,cAAe,GAAM,CAAC,EAC5C,OAAO,GAAK,EAAE,aAAa,CAAC,CAAC,OAFf"}
1
+ {"version":3,"file":"reader.js","names":[],"sources":["../../src/context/reader.ts"],"sourcesContent":["import { readdir, readFile } from 'node:fs/promises'\nimport { existsSync } from 'node:fs'\nimport { join } from 'node:path'\n\nimport type { ContextSnapshot, PlanInfo, PlanStatus } from '../types.js'\n\nconst PLAN_DIR_RE = /^plan-(\\d+)$/\nconst DONE_DIR_RE = /^plan-(\\d+)(?:-\\d{8})?$/\nconst EXACT_STATUS_RE = /^>\\s*状态:\\s*(未执行|已执行)$/m\nconst LOOSE_STATUS_RE = /^>?[ \\t]*状态[::].*$/m\n\n// ── Public API ───────────────────────────────────────\n\nexport async function readContext(cwd: string): Promise<ContextSnapshot | null> {\n const { snapshot } = await readRawContext(cwd)\n return snapshot\n}\n\nexport async function readRawContext(\n cwd: string\n): Promise<{ snapshot: ContextSnapshot | null; currentPlanCount: number }> {\n const root = join(cwd, '.agent-context')\n\n if (!existsSync(root)) {\n return { snapshot: null, currentPlanCount: 0 }\n }\n\n const currentPlans = await readPlanDirs(root)\n const preparing = await readPlanDirs(join(root, 'preparing'))\n const done = await readDonePlans(join(root, 'done'))\n\n const snapshot: ContextSnapshot = {\n root,\n currentPlan: currentPlans[0] ?? null,\n preparing,\n done\n }\n\n return { snapshot, currentPlanCount: currentPlans.length }\n}\n\nexport async function readPlanStatus(planDir: string): Promise<PlanStatus> {\n const planFile = join(planDir, 'plan.md')\n\n if (!existsSync(planFile)) {\n return '未执行'\n }\n\n const content = await readFile(planFile, 'utf-8')\n \n const exactMatch = content.match(EXACT_STATUS_RE)\n if (exactMatch) {\n return exactMatch[1] as PlanStatus\n }\n\n if (LOOSE_STATUS_RE.test(content)) {\n return '未知'\n }\n\n return '未执行'\n}\n\n// ── Helpers ──────────────────────────────────────────\n\nasync function readPlanDirs(parentDir: string): Promise<PlanInfo[]> {\n if (!existsSync(parentDir)) return []\n\n const entries = await readdir(parentDir, { withFileTypes: true })\n const plans: PlanInfo[] = []\n\n for (const entry of entries) {\n if (!entry.isDirectory()) continue\n const match = entry.name.match(PLAN_DIR_RE)\n if (!match?.[1]) continue\n const number = parseInt(match[1], 10)\n const dir = join(parentDir, entry.name)\n const status = await readPlanStatus(dir)\n plans.push({ number, status, dir })\n }\n\n return plans.sort((a, b) => a.number - b.number)\n}\n\nasync function readDonePlans(parentDir: string): Promise<Pick<PlanInfo, 'number' | 'dir'>[]> {\n if (!existsSync(parentDir)) return []\n const entries = await readdir(parentDir, { withFileTypes: true })\n const plans: Pick<PlanInfo, 'number' | 'dir'>[] = []\n \n for (const entry of entries) {\n if (!entry.isDirectory()) continue\n const match = entry.name.match(DONE_DIR_RE)\n if (!match?.[1]) continue\n plans.push({\n number: parseInt(match[1], 10),\n dir: join(parentDir, entry.name)\n })\n }\n\n return plans.sort((a, b) => a.number - b.number)\n}\n"],"mappings":"+HAMA,MAAM,EAAc,eACd,EAAc,0BACd,EAAkB,yBAClB,EAAkB,sBASxB,eAAsB,EACpB,EACyE,CACzE,IAAM,EAAO,EAAK,EAAK,iBAAiB,CAExC,GAAI,CAAC,EAAW,EAAK,CACnB,MAAO,CAAE,SAAU,KAAM,iBAAkB,EAAG,CAGhD,IAAM,EAAe,MAAM,EAAa,EAAK,CACvC,EAAY,MAAM,EAAa,EAAK,EAAM,YAAY,CAAC,CACvD,EAAO,MAAM,EAAc,EAAK,EAAM,OAAO,CAAC,CASpD,MAAO,CAAE,SAPyB,CAChC,OACA,YAAa,EAAa,IAAM,KAChC,YACA,OACD,CAEkB,iBAAkB,EAAa,OAAQ,CAG5D,eAAsB,EAAe,EAAsC,CACzE,IAAM,EAAW,EAAK,EAAS,UAAU,CAEzC,GAAI,CAAC,EAAW,EAAS,CACvB,MAAO,MAGT,IAAM,EAAU,MAAM,EAAS,EAAU,QAAQ,CAE3C,EAAa,EAAQ,MAAM,EAAgB,CASjD,OARI,EACK,EAAW,GAGhB,EAAgB,KAAK,EAAQ,CACxB,KAGF,MAKT,eAAe,EAAa,EAAwC,CAClE,GAAI,CAAC,EAAW,EAAU,CAAE,MAAO,EAAE,CAErC,IAAM,EAAU,MAAM,EAAQ,EAAW,CAAE,cAAe,GAAM,CAAC,CAC3D,EAAoB,EAAE,CAE5B,IAAK,IAAM,KAAS,EAAS,CAC3B,GAAI,CAAC,EAAM,aAAa,CAAE,SAC1B,IAAM,EAAQ,EAAM,KAAK,MAAM,EAAY,CAC3C,GAAI,CAAC,IAAQ,GAAI,SACjB,IAAM,EAAS,SAAS,EAAM,GAAI,GAAG,CAC/B,EAAM,EAAK,EAAW,EAAM,KAAK,CACjC,EAAS,MAAM,EAAe,EAAI,CACxC,EAAM,KAAK,CAAE,SAAQ,SAAQ,MAAK,CAAC,CAGrC,OAAO,EAAM,MAAM,EAAG,IAAM,EAAE,OAAS,EAAE,OAAO,CAGlD,eAAe,EAAc,EAAgE,CAC3F,GAAI,CAAC,EAAW,EAAU,CAAE,MAAO,EAAE,CACrC,IAAM,EAAU,MAAM,EAAQ,EAAW,CAAE,cAAe,GAAM,CAAC,CAC3D,EAA4C,EAAE,CAEpD,IAAK,IAAM,KAAS,EAAS,CAC3B,GAAI,CAAC,EAAM,aAAa,CAAE,SAC1B,IAAM,EAAQ,EAAM,KAAK,MAAM,EAAY,CACtC,IAAQ,IACb,EAAM,KAAK,CACT,OAAQ,SAAS,EAAM,GAAI,GAAG,CAC9B,IAAK,EAAK,EAAW,EAAM,KAAK,CACjC,CAAC,CAGJ,OAAO,EAAM,MAAM,EAAG,IAAM,EAAE,OAAS,EAAE,OAAO"}
@@ -1,2 +1,2 @@
1
- import{existsSync as e}from"node:fs";import{join as t}from"node:path";function n(n,r){if(n===null)return{valid:!0,errors:[],context:null};let i=[];r>1&&i.push(`存在 ${r} 个当前计划,应最多 1 个。`),n.currentPlan&&(e(t(n.currentPlan.dir,`plan.md`))||i.push(`当前计划 plan-${n.currentPlan.number} 缺少 plan.md。`));let a=[];n.currentPlan&&a.push(n.currentPlan.number);for(let e of n.preparing)a.push(e.number);let o=new Set,s=new Set;for(let e of a)o.has(e)&&s.add(e),o.add(e);if(s.size>0){let e=[...s].sort((e,t)=>e-t).join(`, `);i.push(`计划编号冲突: ${e}。`)}return{valid:i.length===0,errors:i,context:n}}export{n as validate};
1
+ import{existsSync as e}from"node:fs";import{join as t}from"node:path";function n(n,r){if(n===null)return{valid:!0,errors:[],context:null};let i=[];r>1&&i.push(`存在 ${r} 个当前计划,应最多 1 个。`),n.currentPlan&&(e(t(n.currentPlan.dir,`plan.md`))||i.push(`当前计划 plan-${n.currentPlan.number} 缺少 plan.md。`),n.currentPlan.status===`未知`&&i.push(`当前计划 plan-${n.currentPlan.number} 的状态格式严重不符合要求,请严格按照 "> 状态: 已执行" 或 "> 状态: 未执行" 的格式书写,禁止添加 emoji 或其他额外字符。`));for(let e of n.preparing)e.status===`未知`&&i.push(`待执行计划 plan-${e.number} 的状态格式严重不符合要求,请严格按照 "> 状态: 已执行" 或 "> 状态: 未执行" 的格式书写。`);let a=[];for(let e of n.done)a.push(e.number);n.currentPlan&&a.push(n.currentPlan.number);for(let e of n.preparing)a.push(e.number);let o=new Set,s=new Set;for(let e of a)o.has(e)&&s.add(e),o.add(e);if(s.size>0){let e=[...s].sort((e,t)=>e-t).join(`, `);i.push(`计划编号冲突: ${e}。`)}a.sort((e,t)=>e-t);for(let e=0;e<a.length;e++)if(a[e]!==e+1){i.push(`计划序列不连续或未从 1 开始。预期出现编号 ${e+1},实际遇到编号 ${a[e]} (要求必须是从 1 开始顺序查询)。`);break}return{valid:i.length===0,errors:i,context:n}}export{n as validate};
2
2
  //# sourceMappingURL=validator.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"validator.js","names":[],"sources":["../../src/context/validator.ts"],"sourcesContent":["import { existsSync } from 'node:fs'\nimport { join } from 'node:path'\n\nimport type { ContextSnapshot, ValidateResult } from '../types.js'\n\nexport function validate(\n snapshot: ContextSnapshot | null,\n currentPlanCount: number\n): ValidateResult {\n if (snapshot === null) {\n return { valid: true, errors: [], context: null }\n }\n\n const errors: string[] = []\n\n if (currentPlanCount > 1) {\n errors.push(`存在 ${currentPlanCount} 个当前计划,应最多 1 个。`)\n }\n\n if (snapshot.currentPlan) {\n const planMd = join(snapshot.currentPlan.dir, 'plan.md')\n if (!existsSync(planMd)) {\n errors.push(`当前计划 plan-${snapshot.currentPlan.number} 缺少 plan.md。`)\n }\n }\n\n const allNumbers: number[] = []\n if (snapshot.currentPlan) allNumbers.push(snapshot.currentPlan.number)\n for (const p of snapshot.preparing) allNumbers.push(p.number)\n\n const seen = new Set<number>()\n const duplicates = new Set<number>()\n for (const n of allNumbers) {\n if (seen.has(n)) duplicates.add(n)\n seen.add(n)\n }\n\n if (duplicates.size > 0) {\n const nums = [...duplicates].sort((a, b) => a - b).join(', ')\n errors.push(`计划编号冲突: ${nums}。`)\n }\n\n return { valid: errors.length === 0, errors, context: snapshot }\n}\n"],"mappings":"sEAKA,SAAgB,EACd,EACA,EACgB,CAChB,GAAI,IAAa,KACf,MAAO,CAAE,MAAO,GAAM,OAAQ,EAAE,CAAE,QAAS,KAAM,CAGnD,IAAM,EAAmB,EAAE,CAEvB,EAAmB,GACrB,EAAO,KAAK,MAAM,EAAiB,iBAAiB,CAGlD,EAAS,cAEN,EADU,EAAK,EAAS,YAAY,IAAK,UAAU,CACjC,EACrB,EAAO,KAAK,aAAa,EAAS,YAAY,OAAO,cAAc,EAIvE,IAAM,EAAuB,EAAE,CAC3B,EAAS,aAAa,EAAW,KAAK,EAAS,YAAY,OAAO,CACtE,IAAK,IAAM,KAAK,EAAS,UAAW,EAAW,KAAK,EAAE,OAAO,CAE7D,IAAM,EAAO,IAAI,IACX,EAAa,IAAI,IACvB,IAAK,IAAM,KAAK,EACV,EAAK,IAAI,EAAE,EAAE,EAAW,IAAI,EAAE,CAClC,EAAK,IAAI,EAAE,CAGb,GAAI,EAAW,KAAO,EAAG,CACvB,IAAM,EAAO,CAAC,GAAG,EAAW,CAAC,MAAM,EAAG,IAAM,EAAI,EAAE,CAAC,KAAK,KAAK,CAC7D,EAAO,KAAK,WAAW,EAAK,GAAG,CAGjC,MAAO,CAAE,MAAO,EAAO,SAAW,EAAG,SAAQ,QAAS,EAAU"}
1
+ {"version":3,"file":"validator.js","names":[],"sources":["../../src/context/validator.ts"],"sourcesContent":["import { existsSync } from 'node:fs'\nimport { join } from 'node:path'\n\nimport type { ContextSnapshot, ValidateResult } from '../types.js'\n\nexport function validate(\n snapshot: ContextSnapshot | null,\n currentPlanCount: number\n): ValidateResult {\n if (snapshot === null) {\n return { valid: true, errors: [], context: null }\n }\n\n const errors: string[] = []\n\n if (currentPlanCount > 1) {\n errors.push(`存在 ${currentPlanCount} 个当前计划,应最多 1 个。`)\n }\n\n if (snapshot.currentPlan) {\n const planMd = join(snapshot.currentPlan.dir, 'plan.md')\n if (!existsSync(planMd)) {\n errors.push(`当前计划 plan-${snapshot.currentPlan.number} 缺少 plan.md。`)\n }\n\n if (snapshot.currentPlan.status === '未知') {\n errors.push(`当前计划 plan-${snapshot.currentPlan.number} 的状态格式严重不符合要求,请严格按照 \"> 状态: 已执行\" 或 \"> 状态: 未执行\" 的格式书写,禁止添加 emoji 或其他额外字符。`)\n }\n }\n\n for (const p of snapshot.preparing) {\n if (p.status === '未知') {\n errors.push(`待执行计划 plan-${p.number} 的状态格式严重不符合要求,请严格按照 \"> 状态: 已执行\" 或 \"> 状态: 未执行\" 的格式书写。`)\n }\n }\n\n const allNumbers: number[] = []\n for (const d of snapshot.done) allNumbers.push(d.number)\n if (snapshot.currentPlan) allNumbers.push(snapshot.currentPlan.number)\n for (const p of snapshot.preparing) allNumbers.push(p.number)\n\n const seen = new Set<number>()\n const duplicates = new Set<number>()\n for (const n of allNumbers) {\n if (seen.has(n)) duplicates.add(n)\n seen.add(n)\n }\n\n if (duplicates.size > 0) {\n const nums = [...duplicates].sort((a, b) => a - b).join(', ')\n errors.push(`计划编号冲突: ${nums}。`)\n }\n\n allNumbers.sort((a, b) => a - b)\n for (let i = 0; i < allNumbers.length; i++) {\n if (allNumbers[i] !== i + 1) {\n errors.push(`计划序列不连续或未从 1 开始。预期出现编号 ${i + 1},实际遇到编号 ${allNumbers[i]} (要求必须是从 1 开始顺序查询)。`)\n break\n }\n }\n\n return { valid: errors.length === 0, errors, context: snapshot }\n}\n"],"mappings":"sEAKA,SAAgB,EACd,EACA,EACgB,CAChB,GAAI,IAAa,KACf,MAAO,CAAE,MAAO,GAAM,OAAQ,EAAE,CAAE,QAAS,KAAM,CAGnD,IAAM,EAAmB,EAAE,CAEvB,EAAmB,GACrB,EAAO,KAAK,MAAM,EAAiB,iBAAiB,CAGlD,EAAS,cAEN,EADU,EAAK,EAAS,YAAY,IAAK,UAAU,CACjC,EACrB,EAAO,KAAK,aAAa,EAAS,YAAY,OAAO,cAAc,CAGjE,EAAS,YAAY,SAAW,MAClC,EAAO,KAAK,aAAa,EAAS,YAAY,OAAO,yEAAyE,EAIlI,IAAK,IAAM,KAAK,EAAS,UACnB,EAAE,SAAW,MACf,EAAO,KAAK,cAAc,EAAE,OAAO,sDAAsD,CAI7F,IAAM,EAAuB,EAAE,CAC/B,IAAK,IAAM,KAAK,EAAS,KAAM,EAAW,KAAK,EAAE,OAAO,CACpD,EAAS,aAAa,EAAW,KAAK,EAAS,YAAY,OAAO,CACtE,IAAK,IAAM,KAAK,EAAS,UAAW,EAAW,KAAK,EAAE,OAAO,CAE7D,IAAM,EAAO,IAAI,IACX,EAAa,IAAI,IACvB,IAAK,IAAM,KAAK,EACV,EAAK,IAAI,EAAE,EAAE,EAAW,IAAI,EAAE,CAClC,EAAK,IAAI,EAAE,CAGb,GAAI,EAAW,KAAO,EAAG,CACvB,IAAM,EAAO,CAAC,GAAG,EAAW,CAAC,MAAM,EAAG,IAAM,EAAI,EAAE,CAAC,KAAK,KAAK,CAC7D,EAAO,KAAK,WAAW,EAAK,GAAG,CAGjC,EAAW,MAAM,EAAG,IAAM,EAAI,EAAE,CAChC,IAAK,IAAI,EAAI,EAAG,EAAI,EAAW,OAAQ,IACrC,GAAI,EAAW,KAAO,EAAI,EAAG,CAC3B,EAAO,KAAK,0BAA0B,EAAI,EAAE,UAAU,EAAW,GAAG,qBAAqB,CACzF,MAIJ,MAAO,CAAE,MAAO,EAAO,SAAW,EAAG,SAAQ,QAAS,EAAU"}
package/dist/stats.html CHANGED
@@ -4930,7 +4930,7 @@ var drawChart = (function (exports) {
4930
4930
  </script>
4931
4931
  <script>
4932
4932
  /*<!--*/
4933
- const data = {"version":2,"tree":{"name":"root","children":[{"name":"cli.d.ts","children":[{"name":"home/whj/codes/cat-kit/packages/agent-context/src/cli.d.ts","uid":"a194fe0a-1"}]},{"name":"cli.js","children":[{"name":"home/whj/codes/cat-kit/packages/agent-context/src/cli.ts","uid":"a194fe0a-3"}]},{"name":"commands/done.js","children":[{"name":"home/whj/codes/cat-kit/packages/agent-context/src/commands/done.ts","uid":"a194fe0a-5"}]},{"name":"commands/install.js","children":[{"name":"home/whj/codes/cat-kit/packages/agent-context/src/commands/install.ts","uid":"a194fe0a-7"}]},{"name":"commands/printer.js","children":[{"name":"home/whj/codes/cat-kit/packages/agent-context/src/commands/printer.ts","uid":"a194fe0a-9"}]},{"name":"commands/status.js","children":[{"name":"home/whj/codes/cat-kit/packages/agent-context/src/commands/status.ts","uid":"a194fe0a-11"}]},{"name":"commands/sync.js","children":[{"name":"home/whj/codes/cat-kit/packages/agent-context/src/commands/sync.ts","uid":"a194fe0a-13"}]},{"name":"commands/validate.js","children":[{"name":"home/whj/codes/cat-kit/packages/agent-context/src/commands/validate.ts","uid":"a194fe0a-15"}]},{"name":"content/actions.js","children":[{"name":"home/whj/codes/cat-kit/packages/agent-context/src/content/actions.ts","uid":"a194fe0a-17"}]},{"name":"content/index.js","children":[{"name":"home/whj/codes/cat-kit/packages/agent-context/src/content/index.ts","uid":"a194fe0a-19"}]},{"name":"context/archiver.js","children":[{"name":"home/whj/codes/cat-kit/packages/agent-context/src/context/archiver.ts","uid":"a194fe0a-21"}]},{"name":"context/reader.js","children":[{"name":"home/whj/codes/cat-kit/packages/agent-context/src/context/reader.ts","uid":"a194fe0a-23"}]},{"name":"context/validator.js","children":[{"name":"home/whj/codes/cat-kit/packages/agent-context/src/context/validator.ts","uid":"a194fe0a-25"}]},{"name":"runner.js","children":[{"name":"home/whj/codes/cat-kit/packages/agent-context/src/runner.ts","uid":"a194fe0a-27"}]},{"name":"tools.js","children":[{"name":"home/whj/codes/cat-kit/packages/agent-context/src/tools.ts","uid":"a194fe0a-29"}]}],"isRoot":true},"nodeParts":{"a194fe0a-1":{"renderedLength":0,"gzipLength":0,"brotliLength":0,"metaUid":"a194fe0a-0"},"a194fe0a-3":{"renderedLength":1518,"gzipLength":0,"brotliLength":0,"metaUid":"a194fe0a-2"},"a194fe0a-5":{"renderedLength":1349,"gzipLength":0,"brotliLength":0,"metaUid":"a194fe0a-4"},"a194fe0a-7":{"renderedLength":985,"gzipLength":0,"brotliLength":0,"metaUid":"a194fe0a-6"},"a194fe0a-9":{"renderedLength":909,"gzipLength":0,"brotliLength":0,"metaUid":"a194fe0a-8"},"a194fe0a-11":{"renderedLength":944,"gzipLength":0,"brotliLength":0,"metaUid":"a194fe0a-10"},"a194fe0a-13":{"renderedLength":745,"gzipLength":0,"brotliLength":0,"metaUid":"a194fe0a-12"},"a194fe0a-15":{"renderedLength":758,"gzipLength":0,"brotliLength":0,"metaUid":"a194fe0a-14"},"a194fe0a-17":{"renderedLength":8872,"gzipLength":0,"brotliLength":0,"metaUid":"a194fe0a-16"},"a194fe0a-19":{"renderedLength":3024,"gzipLength":0,"brotliLength":0,"metaUid":"a194fe0a-18"},"a194fe0a-21":{"renderedLength":1012,"gzipLength":0,"brotliLength":0,"metaUid":"a194fe0a-20"},"a194fe0a-23":{"renderedLength":1573,"gzipLength":0,"brotliLength":0,"metaUid":"a194fe0a-22"},"a194fe0a-25":{"renderedLength":1039,"gzipLength":0,"brotliLength":0,"metaUid":"a194fe0a-24"},"a194fe0a-27":{"renderedLength":2037,"gzipLength":0,"brotliLength":0,"metaUid":"a194fe0a-26"},"a194fe0a-29":{"renderedLength":2174,"gzipLength":0,"brotliLength":0,"metaUid":"a194fe0a-28"}},"nodeMetas":{"a194fe0a-0":{"id":"/home/whj/codes/cat-kit/packages/agent-context/src/cli.d.ts","moduleParts":{"cli.d.ts":"a194fe0a-1"},"imported":[],"importedBy":[],"isEntry":true},"a194fe0a-2":{"id":"/home/whj/codes/cat-kit/packages/agent-context/src/cli.ts","moduleParts":{"cli.js":"a194fe0a-3"},"imported":[{"uid":"a194fe0a-30"},{"uid":"a194fe0a-31"},{"uid":"a194fe0a-4"},{"uid":"a194fe0a-6"},{"uid":"a194fe0a-10"},{"uid":"a194fe0a-12"},{"uid":"a194fe0a-14"}],"importedBy":[],"isEntry":true},"a194fe0a-4":{"id":"/home/whj/codes/cat-kit/packages/agent-context/src/commands/done.ts","moduleParts":{"commands/done.js":"a194fe0a-5"},"imported":[{"uid":"a194fe0a-32"},{"uid":"a194fe0a-33"},{"uid":"a194fe0a-34"}],"importedBy":[{"uid":"a194fe0a-2"}]},"a194fe0a-6":{"id":"/home/whj/codes/cat-kit/packages/agent-context/src/commands/install.ts","moduleParts":{"commands/install.js":"a194fe0a-7"},"imported":[{"uid":"a194fe0a-33"},{"uid":"a194fe0a-26"},{"uid":"a194fe0a-28"},{"uid":"a194fe0a-8"}],"importedBy":[{"uid":"a194fe0a-2"}]},"a194fe0a-8":{"id":"/home/whj/codes/cat-kit/packages/agent-context/src/commands/printer.ts","moduleParts":{"commands/printer.js":"a194fe0a-9"},"imported":[{"uid":"a194fe0a-32"}],"importedBy":[{"uid":"a194fe0a-6"},{"uid":"a194fe0a-12"}]},"a194fe0a-10":{"id":"/home/whj/codes/cat-kit/packages/agent-context/src/commands/status.ts","moduleParts":{"commands/status.js":"a194fe0a-11"},"imported":[{"uid":"a194fe0a-34"}],"importedBy":[{"uid":"a194fe0a-2"}]},"a194fe0a-12":{"id":"/home/whj/codes/cat-kit/packages/agent-context/src/commands/sync.ts","moduleParts":{"commands/sync.js":"a194fe0a-13"},"imported":[{"uid":"a194fe0a-28"},{"uid":"a194fe0a-26"},{"uid":"a194fe0a-8"}],"importedBy":[{"uid":"a194fe0a-2"}]},"a194fe0a-14":{"id":"/home/whj/codes/cat-kit/packages/agent-context/src/commands/validate.ts","moduleParts":{"commands/validate.js":"a194fe0a-15"},"imported":[{"uid":"a194fe0a-34"}],"importedBy":[{"uid":"a194fe0a-2"}]},"a194fe0a-16":{"id":"/home/whj/codes/cat-kit/packages/agent-context/src/content/actions.ts","moduleParts":{"content/actions.js":"a194fe0a-17"},"imported":[],"importedBy":[{"uid":"a194fe0a-18"}]},"a194fe0a-18":{"id":"/home/whj/codes/cat-kit/packages/agent-context/src/content/index.ts","moduleParts":{"content/index.js":"a194fe0a-19"},"imported":[{"uid":"a194fe0a-16"}],"importedBy":[{"uid":"a194fe0a-26"}]},"a194fe0a-20":{"id":"/home/whj/codes/cat-kit/packages/agent-context/src/context/archiver.ts","moduleParts":{"context/archiver.js":"a194fe0a-21"},"imported":[{"uid":"a194fe0a-35"},{"uid":"a194fe0a-32"}],"importedBy":[{"uid":"a194fe0a-34"}]},"a194fe0a-22":{"id":"/home/whj/codes/cat-kit/packages/agent-context/src/context/reader.ts","moduleParts":{"context/reader.js":"a194fe0a-23"},"imported":[{"uid":"a194fe0a-35"},{"uid":"a194fe0a-30"},{"uid":"a194fe0a-32"}],"importedBy":[{"uid":"a194fe0a-34"}]},"a194fe0a-24":{"id":"/home/whj/codes/cat-kit/packages/agent-context/src/context/validator.ts","moduleParts":{"context/validator.js":"a194fe0a-25"},"imported":[{"uid":"a194fe0a-30"},{"uid":"a194fe0a-32"}],"importedBy":[{"uid":"a194fe0a-34"}]},"a194fe0a-26":{"id":"/home/whj/codes/cat-kit/packages/agent-context/src/runner.ts","moduleParts":{"runner.js":"a194fe0a-27"},"imported":[{"uid":"a194fe0a-32"},{"uid":"a194fe0a-30"},{"uid":"a194fe0a-35"},{"uid":"a194fe0a-28"},{"uid":"a194fe0a-18"}],"importedBy":[{"uid":"a194fe0a-6"},{"uid":"a194fe0a-12"}]},"a194fe0a-28":{"id":"/home/whj/codes/cat-kit/packages/agent-context/src/tools.ts","moduleParts":{"tools.js":"a194fe0a-29"},"imported":[{"uid":"a194fe0a-30"},{"uid":"a194fe0a-32"}],"importedBy":[{"uid":"a194fe0a-6"},{"uid":"a194fe0a-12"},{"uid":"a194fe0a-26"}]},"a194fe0a-30":{"id":"node:fs","moduleParts":{},"imported":[],"importedBy":[{"uid":"a194fe0a-2"},{"uid":"a194fe0a-26"},{"uid":"a194fe0a-28"},{"uid":"a194fe0a-22"},{"uid":"a194fe0a-24"}]},"a194fe0a-31":{"id":"commander","moduleParts":{},"imported":[],"importedBy":[{"uid":"a194fe0a-2"}]},"a194fe0a-32":{"id":"node:path","moduleParts":{},"imported":[],"importedBy":[{"uid":"a194fe0a-4"},{"uid":"a194fe0a-26"},{"uid":"a194fe0a-28"},{"uid":"a194fe0a-8"},{"uid":"a194fe0a-22"},{"uid":"a194fe0a-24"},{"uid":"a194fe0a-20"}]},"a194fe0a-33":{"id":"@inquirer/prompts","moduleParts":{},"imported":[],"importedBy":[{"uid":"a194fe0a-4"},{"uid":"a194fe0a-6"}]},"a194fe0a-34":{"id":"/home/whj/codes/cat-kit/packages/agent-context/src/context/index.ts","moduleParts":{},"imported":[{"uid":"a194fe0a-22"},{"uid":"a194fe0a-24"},{"uid":"a194fe0a-20"}],"importedBy":[{"uid":"a194fe0a-4"},{"uid":"a194fe0a-10"},{"uid":"a194fe0a-14"}]},"a194fe0a-35":{"id":"node:fs/promises","moduleParts":{},"imported":[],"importedBy":[{"uid":"a194fe0a-26"},{"uid":"a194fe0a-22"},{"uid":"a194fe0a-20"}]}},"env":{"rollup":"4.23.0"},"options":{"gzip":false,"brotli":false,"sourcemap":false}};
4933
+ const data = {"version":2,"tree":{"name":"root","children":[{"name":"cli.d.ts","children":[{"name":"home/whj/codes/cat-kit/packages/agent-context/src/cli.d.ts","uid":"04e2242d-1"}]},{"name":"cli.js","children":[{"name":"home/whj/codes/cat-kit/packages/agent-context/src/cli.ts","uid":"04e2242d-3"}]},{"name":"commands/done.js","children":[{"name":"home/whj/codes/cat-kit/packages/agent-context/src/commands/done.ts","uid":"04e2242d-5"}]},{"name":"commands/install.js","children":[{"name":"home/whj/codes/cat-kit/packages/agent-context/src/commands/install.ts","uid":"04e2242d-7"}]},{"name":"commands/printer.js","children":[{"name":"home/whj/codes/cat-kit/packages/agent-context/src/commands/printer.ts","uid":"04e2242d-9"}]},{"name":"commands/status.js","children":[{"name":"home/whj/codes/cat-kit/packages/agent-context/src/commands/status.ts","uid":"04e2242d-11"}]},{"name":"commands/sync.js","children":[{"name":"home/whj/codes/cat-kit/packages/agent-context/src/commands/sync.ts","uid":"04e2242d-13"}]},{"name":"commands/validate.js","children":[{"name":"home/whj/codes/cat-kit/packages/agent-context/src/commands/validate.ts","uid":"04e2242d-15"}]},{"name":"content/actions.js","children":[{"name":"home/whj/codes/cat-kit/packages/agent-context/src/content/actions.ts","uid":"04e2242d-17"}]},{"name":"content/index.js","children":[{"name":"home/whj/codes/cat-kit/packages/agent-context/src/content/index.ts","uid":"04e2242d-19"}]},{"name":"context/archiver.js","children":[{"name":"home/whj/codes/cat-kit/packages/agent-context/src/context/archiver.ts","uid":"04e2242d-21"}]},{"name":"context/reader.js","children":[{"name":"home/whj/codes/cat-kit/packages/agent-context/src/context/reader.ts","uid":"04e2242d-23"}]},{"name":"context/validator.js","children":[{"name":"home/whj/codes/cat-kit/packages/agent-context/src/context/validator.ts","uid":"04e2242d-25"}]},{"name":"runner.js","children":[{"name":"home/whj/codes/cat-kit/packages/agent-context/src/runner.ts","uid":"04e2242d-27"}]},{"name":"tools.js","children":[{"name":"home/whj/codes/cat-kit/packages/agent-context/src/tools.ts","uid":"04e2242d-29"}]}],"isRoot":true},"nodeParts":{"04e2242d-1":{"renderedLength":0,"gzipLength":0,"brotliLength":0,"metaUid":"04e2242d-0"},"04e2242d-3":{"renderedLength":1518,"gzipLength":0,"brotliLength":0,"metaUid":"04e2242d-2"},"04e2242d-5":{"renderedLength":1349,"gzipLength":0,"brotliLength":0,"metaUid":"04e2242d-4"},"04e2242d-7":{"renderedLength":985,"gzipLength":0,"brotliLength":0,"metaUid":"04e2242d-6"},"04e2242d-9":{"renderedLength":909,"gzipLength":0,"brotliLength":0,"metaUid":"04e2242d-8"},"04e2242d-11":{"renderedLength":946,"gzipLength":0,"brotliLength":0,"metaUid":"04e2242d-10"},"04e2242d-13":{"renderedLength":745,"gzipLength":0,"brotliLength":0,"metaUid":"04e2242d-12"},"04e2242d-15":{"renderedLength":763,"gzipLength":0,"brotliLength":0,"metaUid":"04e2242d-14"},"04e2242d-17":{"renderedLength":8872,"gzipLength":0,"brotliLength":0,"metaUid":"04e2242d-16"},"04e2242d-19":{"renderedLength":3024,"gzipLength":0,"brotliLength":0,"metaUid":"04e2242d-18"},"04e2242d-21":{"renderedLength":1012,"gzipLength":0,"brotliLength":0,"metaUid":"04e2242d-20"},"04e2242d-23":{"renderedLength":2081,"gzipLength":0,"brotliLength":0,"metaUid":"04e2242d-22"},"04e2242d-25":{"renderedLength":1905,"gzipLength":0,"brotliLength":0,"metaUid":"04e2242d-24"},"04e2242d-27":{"renderedLength":2037,"gzipLength":0,"brotliLength":0,"metaUid":"04e2242d-26"},"04e2242d-29":{"renderedLength":2174,"gzipLength":0,"brotliLength":0,"metaUid":"04e2242d-28"}},"nodeMetas":{"04e2242d-0":{"id":"/home/whj/codes/cat-kit/packages/agent-context/src/cli.d.ts","moduleParts":{"cli.d.ts":"04e2242d-1"},"imported":[],"importedBy":[],"isEntry":true},"04e2242d-2":{"id":"/home/whj/codes/cat-kit/packages/agent-context/src/cli.ts","moduleParts":{"cli.js":"04e2242d-3"},"imported":[{"uid":"04e2242d-30"},{"uid":"04e2242d-31"},{"uid":"04e2242d-4"},{"uid":"04e2242d-6"},{"uid":"04e2242d-10"},{"uid":"04e2242d-12"},{"uid":"04e2242d-14"}],"importedBy":[],"isEntry":true},"04e2242d-4":{"id":"/home/whj/codes/cat-kit/packages/agent-context/src/commands/done.ts","moduleParts":{"commands/done.js":"04e2242d-5"},"imported":[{"uid":"04e2242d-32"},{"uid":"04e2242d-33"},{"uid":"04e2242d-34"}],"importedBy":[{"uid":"04e2242d-2"}]},"04e2242d-6":{"id":"/home/whj/codes/cat-kit/packages/agent-context/src/commands/install.ts","moduleParts":{"commands/install.js":"04e2242d-7"},"imported":[{"uid":"04e2242d-33"},{"uid":"04e2242d-26"},{"uid":"04e2242d-28"},{"uid":"04e2242d-8"}],"importedBy":[{"uid":"04e2242d-2"}]},"04e2242d-8":{"id":"/home/whj/codes/cat-kit/packages/agent-context/src/commands/printer.ts","moduleParts":{"commands/printer.js":"04e2242d-9"},"imported":[{"uid":"04e2242d-32"}],"importedBy":[{"uid":"04e2242d-6"},{"uid":"04e2242d-12"}]},"04e2242d-10":{"id":"/home/whj/codes/cat-kit/packages/agent-context/src/commands/status.ts","moduleParts":{"commands/status.js":"04e2242d-11"},"imported":[{"uid":"04e2242d-34"}],"importedBy":[{"uid":"04e2242d-2"}]},"04e2242d-12":{"id":"/home/whj/codes/cat-kit/packages/agent-context/src/commands/sync.ts","moduleParts":{"commands/sync.js":"04e2242d-13"},"imported":[{"uid":"04e2242d-28"},{"uid":"04e2242d-26"},{"uid":"04e2242d-8"}],"importedBy":[{"uid":"04e2242d-2"}]},"04e2242d-14":{"id":"/home/whj/codes/cat-kit/packages/agent-context/src/commands/validate.ts","moduleParts":{"commands/validate.js":"04e2242d-15"},"imported":[{"uid":"04e2242d-34"}],"importedBy":[{"uid":"04e2242d-2"}]},"04e2242d-16":{"id":"/home/whj/codes/cat-kit/packages/agent-context/src/content/actions.ts","moduleParts":{"content/actions.js":"04e2242d-17"},"imported":[],"importedBy":[{"uid":"04e2242d-18"}]},"04e2242d-18":{"id":"/home/whj/codes/cat-kit/packages/agent-context/src/content/index.ts","moduleParts":{"content/index.js":"04e2242d-19"},"imported":[{"uid":"04e2242d-16"}],"importedBy":[{"uid":"04e2242d-26"}]},"04e2242d-20":{"id":"/home/whj/codes/cat-kit/packages/agent-context/src/context/archiver.ts","moduleParts":{"context/archiver.js":"04e2242d-21"},"imported":[{"uid":"04e2242d-35"},{"uid":"04e2242d-32"}],"importedBy":[{"uid":"04e2242d-34"}]},"04e2242d-22":{"id":"/home/whj/codes/cat-kit/packages/agent-context/src/context/reader.ts","moduleParts":{"context/reader.js":"04e2242d-23"},"imported":[{"uid":"04e2242d-35"},{"uid":"04e2242d-30"},{"uid":"04e2242d-32"}],"importedBy":[{"uid":"04e2242d-34"}]},"04e2242d-24":{"id":"/home/whj/codes/cat-kit/packages/agent-context/src/context/validator.ts","moduleParts":{"context/validator.js":"04e2242d-25"},"imported":[{"uid":"04e2242d-30"},{"uid":"04e2242d-32"}],"importedBy":[{"uid":"04e2242d-34"}]},"04e2242d-26":{"id":"/home/whj/codes/cat-kit/packages/agent-context/src/runner.ts","moduleParts":{"runner.js":"04e2242d-27"},"imported":[{"uid":"04e2242d-32"},{"uid":"04e2242d-30"},{"uid":"04e2242d-35"},{"uid":"04e2242d-28"},{"uid":"04e2242d-18"}],"importedBy":[{"uid":"04e2242d-6"},{"uid":"04e2242d-12"}]},"04e2242d-28":{"id":"/home/whj/codes/cat-kit/packages/agent-context/src/tools.ts","moduleParts":{"tools.js":"04e2242d-29"},"imported":[{"uid":"04e2242d-30"},{"uid":"04e2242d-32"}],"importedBy":[{"uid":"04e2242d-6"},{"uid":"04e2242d-12"},{"uid":"04e2242d-26"}]},"04e2242d-30":{"id":"node:fs","moduleParts":{},"imported":[],"importedBy":[{"uid":"04e2242d-2"},{"uid":"04e2242d-26"},{"uid":"04e2242d-28"},{"uid":"04e2242d-22"},{"uid":"04e2242d-24"}]},"04e2242d-31":{"id":"commander","moduleParts":{},"imported":[],"importedBy":[{"uid":"04e2242d-2"}]},"04e2242d-32":{"id":"node:path","moduleParts":{},"imported":[],"importedBy":[{"uid":"04e2242d-4"},{"uid":"04e2242d-26"},{"uid":"04e2242d-28"},{"uid":"04e2242d-8"},{"uid":"04e2242d-22"},{"uid":"04e2242d-24"},{"uid":"04e2242d-20"}]},"04e2242d-33":{"id":"@inquirer/prompts","moduleParts":{},"imported":[],"importedBy":[{"uid":"04e2242d-4"},{"uid":"04e2242d-6"}]},"04e2242d-34":{"id":"/home/whj/codes/cat-kit/packages/agent-context/src/context/index.ts","moduleParts":{},"imported":[{"uid":"04e2242d-22"},{"uid":"04e2242d-24"},{"uid":"04e2242d-20"}],"importedBy":[{"uid":"04e2242d-4"},{"uid":"04e2242d-10"},{"uid":"04e2242d-14"}]},"04e2242d-35":{"id":"node:fs/promises","moduleParts":{},"imported":[],"importedBy":[{"uid":"04e2242d-26"},{"uid":"04e2242d-22"},{"uid":"04e2242d-20"}]}},"env":{"rollup":"4.23.0"},"options":{"gzip":false,"brotli":false,"sourcemap":false}};
4934
4934
 
4935
4935
  const run = () => {
4936
4936
  const width = window.innerWidth;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cat-kit/agent-context",
3
- "version": "1.1.3",
3
+ "version": "1.1.4",
4
4
  "description": "代理上下文管理工具",
5
5
  "bin": {
6
6
  "agent-context": "./dist/cli.js"
@@ -21,6 +21,6 @@
21
21
  },
22
22
  "devDependencies": {
23
23
  "@cat-kit/tsconfig": "1.0.0",
24
- "@types/node": "^24.10.15"
24
+ "@types/node": "^24.12.0"
25
25
  }
26
26
  }
@@ -22,14 +22,12 @@ export async function statusCommand(): Promise<void> {
22
22
  ? `plan-${ctx.currentPlan.number} (${ctx.currentPlan.status})`
23
23
  : '无'
24
24
  const preparing =
25
- ctx.preparing.length > 0
26
- ? ctx.preparing.map((p) => `plan-${p.number}`).join(', ')
27
- : '无'
25
+ ctx.preparing.length > 0 ? ctx.preparing.map((p) => `plan-${p.number}`).join(', ') : '无'
28
26
 
29
- console.log('') // eslint-disable-line no-console
30
- console.log('Agent Context Status') // eslint-disable-line no-console
31
- console.log('────────────────────') // eslint-disable-line no-console
32
- console.log(`当前计划: ${current}`) // eslint-disable-line no-console
33
- console.log(`待执行队列: ${preparing}`) // eslint-disable-line no-console
34
- console.log(`已归档: ${ctx.doneCount} 个`) // eslint-disable-line no-console
27
+ console.log('')
28
+ console.log('Agent Context Status')
29
+ console.log('────────────────────')
30
+ console.log(`当前计划: ${current}`)
31
+ console.log(`待执行队列: ${preparing}`)
32
+ console.log(`已归档: ${ctx.done.length} 个`)
35
33
  }
@@ -5,24 +5,24 @@ export async function validateCommand(): Promise<void> {
5
5
  const result = validate(snapshot, currentPlanCount)
6
6
 
7
7
  if (result.context === null) {
8
- console.log(' 无 .agent-context 目录') // eslint-disable-line no-console
8
+ console.log('⚠️ 无 .agent-context 目录')
9
9
  return
10
10
  }
11
11
 
12
12
  if (result.valid) {
13
- console.log('✅ 校验通过') // eslint-disable-line no-console
13
+ console.log('✅ 校验通过')
14
14
  const ctx = result.context
15
15
  const current = ctx.currentPlan
16
16
  ? `plan-${ctx.currentPlan.number} (${ctx.currentPlan.status})`
17
17
  : '无'
18
- console.log(` 当前计划: ${current}`) // eslint-disable-line no-console
19
- console.log(` 待执行: ${ctx.preparing.length} 个`) // eslint-disable-line no-console
20
- console.log(` 已归档: ${ctx.doneCount} 个`) // eslint-disable-line no-console
18
+ console.log(` 当前计划: ${current}`)
19
+ console.log(` 待执行: ${ctx.preparing.length} 个`)
20
+ console.log(` 已归档: ${ctx.done.length} 个`)
21
21
  return
22
22
  }
23
23
 
24
24
  for (const error of result.errors) {
25
- console.log(`❌ ${error}`) // eslint-disable-line no-console
25
+ console.log(`❌ ${error}`)
26
26
  }
27
27
  process.exitCode = 1
28
28
  }
@@ -5,7 +5,9 @@ import { join } from 'node:path'
5
5
  import type { ContextSnapshot, PlanInfo, PlanStatus } from '../types.js'
6
6
 
7
7
  const PLAN_DIR_RE = /^plan-(\d+)$/
8
- const STATUS_RE = /^>\s*状态:\s*(未执行|已执行)\s*$/m
8
+ const DONE_DIR_RE = /^plan-(\d+)(?:-\d{8})?$/
9
+ const EXACT_STATUS_RE = /^>\s*状态:\s*(未执行|已执行)$/m
10
+ const LOOSE_STATUS_RE = /^>?[ \t]*状态[::].*$/m
9
11
 
10
12
  // ── Public API ───────────────────────────────────────
11
13
 
@@ -25,13 +27,13 @@ export async function readRawContext(
25
27
 
26
28
  const currentPlans = await readPlanDirs(root)
27
29
  const preparing = await readPlanDirs(join(root, 'preparing'))
28
- const doneCount = await countDirs(join(root, 'done'))
30
+ const done = await readDonePlans(join(root, 'done'))
29
31
 
30
32
  const snapshot: ContextSnapshot = {
31
33
  root,
32
34
  currentPlan: currentPlans[0] ?? null,
33
35
  preparing,
34
- doneCount
36
+ done
35
37
  }
36
38
 
37
39
  return { snapshot, currentPlanCount: currentPlans.length }
@@ -45,8 +47,17 @@ export async function readPlanStatus(planDir: string): Promise<PlanStatus> {
45
47
  }
46
48
 
47
49
  const content = await readFile(planFile, 'utf-8')
48
- const match = content.match(STATUS_RE)
49
- return match ? (match[1] as PlanStatus) : '未执行'
50
+
51
+ const exactMatch = content.match(EXACT_STATUS_RE)
52
+ if (exactMatch) {
53
+ return exactMatch[1] as PlanStatus
54
+ }
55
+
56
+ if (LOOSE_STATUS_RE.test(content)) {
57
+ return '未知'
58
+ }
59
+
60
+ return '未执行'
50
61
  }
51
62
 
52
63
  // ── Helpers ──────────────────────────────────────────
@@ -70,8 +81,20 @@ async function readPlanDirs(parentDir: string): Promise<PlanInfo[]> {
70
81
  return plans.sort((a, b) => a.number - b.number)
71
82
  }
72
83
 
73
- async function countDirs(dir: string): Promise<number> {
74
- if (!existsSync(dir)) return 0
75
- const entries = await readdir(dir, { withFileTypes: true })
76
- return entries.filter(e => e.isDirectory()).length
84
+ async function readDonePlans(parentDir: string): Promise<Pick<PlanInfo, 'number' | 'dir'>[]> {
85
+ if (!existsSync(parentDir)) return []
86
+ const entries = await readdir(parentDir, { withFileTypes: true })
87
+ const plans: Pick<PlanInfo, 'number' | 'dir'>[] = []
88
+
89
+ for (const entry of entries) {
90
+ if (!entry.isDirectory()) continue
91
+ const match = entry.name.match(DONE_DIR_RE)
92
+ if (!match?.[1]) continue
93
+ plans.push({
94
+ number: parseInt(match[1], 10),
95
+ dir: join(parentDir, entry.name)
96
+ })
97
+ }
98
+
99
+ return plans.sort((a, b) => a.number - b.number)
77
100
  }
@@ -22,9 +22,20 @@ export function validate(
22
22
  if (!existsSync(planMd)) {
23
23
  errors.push(`当前计划 plan-${snapshot.currentPlan.number} 缺少 plan.md。`)
24
24
  }
25
+
26
+ if (snapshot.currentPlan.status === '未知') {
27
+ errors.push(`当前计划 plan-${snapshot.currentPlan.number} 的状态格式严重不符合要求,请严格按照 "> 状态: 已执行" 或 "> 状态: 未执行" 的格式书写,禁止添加 emoji 或其他额外字符。`)
28
+ }
29
+ }
30
+
31
+ for (const p of snapshot.preparing) {
32
+ if (p.status === '未知') {
33
+ errors.push(`待执行计划 plan-${p.number} 的状态格式严重不符合要求,请严格按照 "> 状态: 已执行" 或 "> 状态: 未执行" 的格式书写。`)
34
+ }
25
35
  }
26
36
 
27
37
  const allNumbers: number[] = []
38
+ for (const d of snapshot.done) allNumbers.push(d.number)
28
39
  if (snapshot.currentPlan) allNumbers.push(snapshot.currentPlan.number)
29
40
  for (const p of snapshot.preparing) allNumbers.push(p.number)
30
41
 
@@ -40,5 +51,13 @@ export function validate(
40
51
  errors.push(`计划编号冲突: ${nums}。`)
41
52
  }
42
53
 
54
+ allNumbers.sort((a, b) => a - b)
55
+ for (let i = 0; i < allNumbers.length; i++) {
56
+ if (allNumbers[i] !== i + 1) {
57
+ errors.push(`计划序列不连续或未从 1 开始。预期出现编号 ${i + 1},实际遇到编号 ${allNumbers[i]} (要求必须是从 1 开始顺序查询)。`)
58
+ break
59
+ }
60
+ }
61
+
43
62
  return { valid: errors.length === 0, errors, context: snapshot }
44
63
  }
package/src/types.ts CHANGED
@@ -43,7 +43,7 @@ export interface RunResult extends ApplyMutationResult {
43
43
 
44
44
  // ── Context types ────────────────────────────────────
45
45
 
46
- export type PlanStatus = '未执行' | '已执行'
46
+ export type PlanStatus = '未执行' | '已执行' | '未知'
47
47
 
48
48
  export interface PlanInfo {
49
49
  number: number
@@ -55,7 +55,7 @@ export interface ContextSnapshot {
55
55
  root: string
56
56
  currentPlan: PlanInfo | null
57
57
  preparing: PlanInfo[]
58
- doneCount: number
58
+ done: Pick<PlanInfo, 'number' | 'dir'>[]
59
59
  }
60
60
 
61
61
  export interface ValidateResult {