@cat-kit/agent-context 1.1.2 → 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.
- package/dist/commands/status.js +1 -1
- package/dist/commands/status.js.map +1 -1
- package/dist/commands/validate.js +1 -1
- package/dist/commands/validate.js.map +1 -1
- package/dist/content/index.js +4 -2
- package/dist/content/index.js.map +1 -1
- package/dist/context/reader.js +1 -1
- package/dist/context/reader.js.map +1 -1
- package/dist/context/validator.js +1 -1
- package/dist/context/validator.js.map +1 -1
- package/dist/stats.html +1 -1
- package/package.json +2 -2
- package/src/commands/status.ts +7 -9
- package/src/commands/validate.ts +6 -6
- package/src/content/index.ts +4 -2
- package/src/context/reader.ts +32 -9
- package/src/context/validator.ts +19 -0
- package/src/types.ts +2 -2
package/dist/commands/status.js
CHANGED
|
@@ -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.
|
|
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
|
|
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(
|
|
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('
|
|
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"}
|
package/dist/content/index.js
CHANGED
|
@@ -11,10 +11,12 @@ import{ACTION_NAMES as e,ACTION_RENDERERS as t}from"./actions.js";function n(n){
|
|
|
11
11
|
| 给需求出计划、拆分任务 | plan | \`actions/plan.md\` |
|
|
12
12
|
| 重做计划、调整方案 | replan | \`actions/replan.md\` |
|
|
13
13
|
| 按计划开始做、实现当前计划 | implement | \`actions/implement.md\` |
|
|
14
|
-
|
|
|
15
|
-
|
|
|
14
|
+
| 实施后不满意、追加需求、修补问题 | patch | \`actions/patch.md\` |
|
|
15
|
+
| 无活跃计划时快速出计划并实施 | rush | \`actions/rush.md\` |
|
|
16
16
|
| 任务彻底完成、归档当前计划 | done | 运行 \`agent-context done\` |
|
|
17
17
|
|
|
18
|
+
> **消歧**:存在已执行的当前计划时,用户提出任何变更需求 → 一律走 **patch**,禁止走 plan / rush。
|
|
19
|
+
|
|
18
20
|
## 全局约束
|
|
19
21
|
|
|
20
22
|
- 状态机两态:\`未执行\`、\`已执行\`。
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[],"sources":["../../src/content/index.ts"],"sourcesContent":["import type { SkillArtifacts, ToolTarget } from '../types.js'\nimport { ACTION_NAMES, ACTION_RENDERERS } from './actions.js'\n\nconst SKILL_NAME = 'ac-workflow'\nconst SKILL_DESCRIPTION =\n '管理 .agent-context 计划生命周期,按 init、plan、replan、implement、patch、rush、done 协议推进任务。'\n\nexport function renderSkillArtifacts(target: ToolTarget): SkillArtifacts {\n const files: SkillArtifacts['files'] = [\n { relativePath: 'SKILL.md', body: renderNavigator(target) },\n ...ACTION_NAMES.map((name) => ({\n relativePath: `actions/${name}.md`,\n body: ACTION_RENDERERS[name]()\n }))\n ]\n\n if (target.metadataFiles.includes('openai')) {\n files.push({ relativePath: 'agents/openai.yaml', body: renderOpenAIMetadata() })\n }\n\n return { files }\n}\n\n// ── Navigator ────────────────────────────────────────\n\nfunction renderNavigator(target: ToolTarget): string {\n return `${renderFrontmatter(target)}\n# Agent Context\n\n管理项目中的 \\`.agent-context/\\` 计划生命周期。匹配用户意图后,读取对应协议文件(相对于本文件所在目录)严格执行。\n\n## 意图匹配\n\n| 用户意图 | 动作 | 协议文件 |\n|----------|------|----------|\n| 初始化项目上下文、补全 AGENTS | init | \\`actions/init.md\\` |\n| 给需求出计划、拆分任务 | plan | \\`actions/plan.md\\` |\n| 重做计划、调整方案 | replan | \\`actions/replan.md\\` |\n| 按计划开始做、实现当前计划 | implement | \\`actions/implement.md\\` |\n|
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../../src/content/index.ts"],"sourcesContent":["import type { SkillArtifacts, ToolTarget } from '../types.js'\nimport { ACTION_NAMES, ACTION_RENDERERS } from './actions.js'\n\nconst SKILL_NAME = 'ac-workflow'\nconst SKILL_DESCRIPTION =\n '管理 .agent-context 计划生命周期,按 init、plan、replan、implement、patch、rush、done 协议推进任务。'\n\nexport function renderSkillArtifacts(target: ToolTarget): SkillArtifacts {\n const files: SkillArtifacts['files'] = [\n { relativePath: 'SKILL.md', body: renderNavigator(target) },\n ...ACTION_NAMES.map((name) => ({\n relativePath: `actions/${name}.md`,\n body: ACTION_RENDERERS[name]()\n }))\n ]\n\n if (target.metadataFiles.includes('openai')) {\n files.push({ relativePath: 'agents/openai.yaml', body: renderOpenAIMetadata() })\n }\n\n return { files }\n}\n\n// ── Navigator ────────────────────────────────────────\n\nfunction renderNavigator(target: ToolTarget): string {\n return `${renderFrontmatter(target)}\n# Agent Context\n\n管理项目中的 \\`.agent-context/\\` 计划生命周期。匹配用户意图后,读取对应协议文件(相对于本文件所在目录)严格执行。\n\n## 意图匹配\n\n| 用户意图 | 动作 | 协议文件 |\n|----------|------|----------|\n| 初始化项目上下文、补全 AGENTS | init | \\`actions/init.md\\` |\n| 给需求出计划、拆分任务 | plan | \\`actions/plan.md\\` |\n| 重做计划、调整方案 | replan | \\`actions/replan.md\\` |\n| 按计划开始做、实现当前计划 | implement | \\`actions/implement.md\\` |\n| 实施后不满意、追加需求、修补问题 | patch | \\`actions/patch.md\\` |\n| 无活跃计划时快速出计划并实施 | rush | \\`actions/rush.md\\` |\n| 任务彻底完成、归档当前计划 | done | 运行 \\`agent-context done\\` |\n\n> **消歧**:存在已执行的当前计划时,用户提出任何变更需求 → 一律走 **patch**,禁止走 plan / rush。\n\n## 全局约束\n\n- 状态机两态:\\`未执行\\`、\\`已执行\\`。\n- 任意时刻最多一个当前计划:\\`.agent-context/plan-{number}\\`。\n- 多个当前计划 → 拒绝执行,提示恢复单活跃状态。\n- 计划编号全局递增,不复用。补丁编号在单计划目录内递增,不复用。\n\n## 目录结构\n\n\\`\\`\\`text\n.agent-context/\n├── plan-{N}/ # 当前计划(最多一个)\n│ ├── plan.md\n│ └── patch-{N}.md\n├── preparing/ # 待执行计划队列\n│ └── plan-{N}/\n└── done/ # 已归档计划\n └── plan-{N}-{YYYYMMDD}/\n\\`\\`\\`\n\n编号规则:扫描全部 \\`plan-N\\` 目录取 \\`max(N)+1\\`。\n`\n}\n\n// ── Frontmatter & Metadata ──────────────────────────\n\nfunction renderFrontmatter(target: ToolTarget): string {\n const lines = ['---', `name: ${SKILL_NAME}`, `description: ${SKILL_DESCRIPTION}`]\n\n if (target.frontmatterProfile === 'claude') {\n lines.push('argument-hint: [request]')\n }\n\n if (target.frontmatterProfile === 'copilot') {\n lines.push('license: MIT')\n }\n\n lines.push('---', '')\n return `${lines.join('\\n')}\\n`\n}\n\nfunction renderOpenAIMetadata(): string {\n return `interface:\n display_name: \"Agent Context Workflow\"\n short_description: \"统一管理 .agent-context 计划生命周期\"\n default_prompt: \"Use $ac-workflow to manage the current task through init, plan, replan, implement, patch, rush, or done.\"\n\npolicy:\n allow_implicit_invocation: true\n`\n}\n"],"mappings":"kEAOA,SAAgB,EAAqB,EAAoC,CACvE,IAAM,EAAiC,CACrC,CAAE,aAAc,WAAY,KAAM,EAAgB,EAAO,CAAE,CAC3D,GAAG,EAAa,IAAK,IAAU,CAC7B,aAAc,WAAW,EAAK,KAC9B,KAAM,EAAiB,IAAO,CAC/B,EAAE,CACJ,CAMD,OAJI,EAAO,cAAc,SAAS,SAAS,EACzC,EAAM,KAAK,CAAE,aAAc,qBAAsB,KAAM,GAAsB,CAAE,CAAC,CAG3E,CAAE,QAAO,CAKlB,SAAS,EAAgB,EAA4B,CACnD,MAAO,GAAG,EAAkB,EAAO,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA6CtC,SAAS,EAAkB,EAA4B,CACrD,IAAM,EAAQ,CAAC,MAAO,oBAAuB,6FAAoC,CAWjF,OATI,EAAO,qBAAuB,UAChC,EAAM,KAAK,2BAA2B,CAGpC,EAAO,qBAAuB,WAChC,EAAM,KAAK,eAAe,CAG5B,EAAM,KAAK,MAAO,GAAG,CACd,GAAG,EAAM,KAAK;EAAK,CAAC,IAG7B,SAAS,GAA+B,CACtC,MAAO"}
|
package/dist/context/reader.js
CHANGED
|
@@ -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*(未执行|已执行)\
|
|
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
|
|
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,
|
|
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":"
|
|
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
|
+
"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.
|
|
24
|
+
"@types/node": "^24.12.0"
|
|
25
25
|
}
|
|
26
26
|
}
|
package/src/commands/status.ts
CHANGED
|
@@ -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('')
|
|
30
|
-
console.log('Agent Context Status')
|
|
31
|
-
console.log('────────────────────')
|
|
32
|
-
console.log(`当前计划: ${current}`)
|
|
33
|
-
console.log(`待执行队列: ${preparing}`)
|
|
34
|
-
console.log(`已归档: ${ctx.
|
|
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
|
}
|
package/src/commands/validate.ts
CHANGED
|
@@ -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('
|
|
8
|
+
console.log('⚠️ 无 .agent-context 目录')
|
|
9
9
|
return
|
|
10
10
|
}
|
|
11
11
|
|
|
12
12
|
if (result.valid) {
|
|
13
|
-
console.log('✅ 校验通过')
|
|
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}`)
|
|
19
|
-
console.log(` 待执行: ${ctx.preparing.length} 个`)
|
|
20
|
-
console.log(` 已归档: ${ctx.
|
|
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}`)
|
|
25
|
+
console.log(`❌ ${error}`)
|
|
26
26
|
}
|
|
27
27
|
process.exitCode = 1
|
|
28
28
|
}
|
package/src/content/index.ts
CHANGED
|
@@ -37,10 +37,12 @@ function renderNavigator(target: ToolTarget): string {
|
|
|
37
37
|
| 给需求出计划、拆分任务 | plan | \`actions/plan.md\` |
|
|
38
38
|
| 重做计划、调整方案 | replan | \`actions/replan.md\` |
|
|
39
39
|
| 按计划开始做、实现当前计划 | implement | \`actions/implement.md\` |
|
|
40
|
-
|
|
|
41
|
-
|
|
|
40
|
+
| 实施后不满意、追加需求、修补问题 | patch | \`actions/patch.md\` |
|
|
41
|
+
| 无活跃计划时快速出计划并实施 | rush | \`actions/rush.md\` |
|
|
42
42
|
| 任务彻底完成、归档当前计划 | done | 运行 \`agent-context done\` |
|
|
43
43
|
|
|
44
|
+
> **消歧**:存在已执行的当前计划时,用户提出任何变更需求 → 一律走 **patch**,禁止走 plan / rush。
|
|
45
|
+
|
|
44
46
|
## 全局约束
|
|
45
47
|
|
|
46
48
|
- 状态机两态:\`未执行\`、\`已执行\`。
|
package/src/context/reader.ts
CHANGED
|
@@ -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
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
49
|
-
|
|
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
|
|
74
|
-
if (!existsSync(
|
|
75
|
-
const entries = await readdir(
|
|
76
|
-
|
|
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
|
}
|
package/src/context/validator.ts
CHANGED
|
@@ -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
|
-
|
|
58
|
+
done: Pick<PlanInfo, 'number' | 'dir'>[]
|
|
59
59
|
}
|
|
60
60
|
|
|
61
61
|
export interface ValidateResult {
|