@fxri/toolkit 1.10.0 → 1.10.2

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/CHANGELOG.md CHANGED
@@ -1,5 +1,37 @@
1
1
  # 方弦工具集
2
2
 
3
+ ## 1.10.2
4
+
5
+ > 2026-09-16 发布
6
+
7
+ ### ⚡ 优化改进
8
+
9
+ - 发版链路在发布动作前补门禁关卡——`fxri-release-changelog` 技能要求发布前跑一次项目验收命令(如 `pnpm verify`),本仓库「发版链路」第 2 步由纯构建升级为该门禁(版本 1.1.1)
10
+ - 关卡设在发布前而非推送前:发布到包仓库 / 制品库不可逆,推送失败重推即可
11
+ - 原第 2 步为纯 `pnpm build`,构建工具不做类型检查,发布前无任何验收关卡
12
+ - 任务收尾链路明确「归档与沉淀 → 验收 → 提交」顺序,验收须晚于归档——归档会改写 `.tasks/`(写归档文件、删 active 源文件、清理空月份目录)且自身不做阻断式校验,早于归档跑验收就覆盖不到终态、归档产物等于无人校验;配套约定归档块「完成情况」只记改动事实与所用验证命令,不逐条抄门禁结果(避免先写结论后验证)(`fxri-plan-to-task` 1.3.2、`fxri-session-recap` 1.2.2;`docs/faq.md` 同步该顺序约束的表述)
13
+ - 本仓库验收步骤清单单源化——新增 `pnpm verify` 聚合门禁(步骤定义在 `scripts/verify.mjs`),本地与全部 CI 流水线共用同一份清单,消除此前四份手写清单彼此漂移导致的「本地自检通过、CI 才报错」
14
+ - `fxri-plan-to-task` 技能补「验收与 CI 同源、不手写清单」纪律(版本 1.3.1)
15
+ - 本仓库验收门禁补 `pnpm typecheck`——`pnpm lint`(eslint)与 `pnpm build` 均不做类型检查,此前仅靠 CI 暴露类型错误
16
+
17
+ ### 🐛 问题修复
18
+
19
+ - 修复 `toolkit changelog` 帮助拦截与解析错误提示两处 TypeScript 类型错误(`noUncheckedIndexedAccess` 下索引与正则捕获组取值未兜底),改用解构判空与空串兜底;运行时行为与输出不变,本仓库 `pnpm typecheck` 恢复通过
20
+
21
+ ## 1.10.1
22
+
23
+ > 2026-09-16 发布
24
+
25
+ ### 🔧 功能调整
26
+
27
+ - 建档同主题判别改用客观口径——判据由主观的「有无增量」改为「本次是否产生仓库文件改动」(需写入版本控制的工作区文件增 / 改 / 删计入,纯读取、纯执行、纯汇报不计入),任何项目、任何人或 AI 均可按同一标准得到同一结论
28
+ - 收尾动作边界明确——提交、发版、推送、部署等收尾动作本身及其固有产物(版本号、更新日志、标签)不构成任务、不单独建档;这些动作过程中暴露的需改仓库文件才能修复的缺陷按普通任务建档
29
+ - 归档块补「事实更正」唯一例外——归档块仍不可追加新的工作内容,但后续核实推翻原块结论时可在正文末尾追加「修订记录」(保留原结论、不动元数据行、附更正时刻与依据)
30
+
31
+ ### 📝 文档更新
32
+
33
+ - 同步 `SPEC.md`、`docs/guide.md`、`docs/ai-rules.md`、`AGENTS.md` 与 fxri-plan-to-task / fxri-session-recap / fxri-release-changelog 三技能措辞;规则层锚点随内容变更同批更新
34
+
3
35
  ## 1.10.0
4
36
 
5
37
  > 2026-09-16 发布
package/SPEC.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # 任务文件规范(SPEC)
2
2
 
3
- > 规范更新时间 2026-09-16 09:52。本规范内容变更时以变更时刻更新此值,实现方与规范快照据此对照是否失同步。
3
+ > 规范更新时间 2026-09-16 13:11。本规范内容变更时以变更时刻更新此值,实现方与规范快照据此对照是否失同步。
4
4
 
5
5
  > 本规范**全语言支持**,面向**多人 + AI 跨项目协作**,定义任务文件的目录结构、文件格式与归档规则。任何编程语言均可按本规范实现读写;@fxri/toolkit 的 `tasks` 域仅为参考实现。
6
6
  >
@@ -10,9 +10,9 @@
10
10
 
11
11
  任务区是**多写者共享**的:同一 `.tasks/` 可能被多人或多个 AI 参与。为避免互相覆盖,归档、归一化修复等工具内部写操作以排他锁(`.archive.lock`)防并发覆盖;人 / AI 的直接编辑遵循「先查后写」约定。约定:
12
12
 
13
- 1. **先查后写**:新建、更新或归档任务前,先 `toolkit tasks` 查看 active 总览,并核对 archive 是否已有同主题任务;active 已有同主题任务则更新原文件,禁止重复建档。archive 已有同主题任务(已归档完成)时按增量判别:无增量(重复提议)不建档、有增量(延续/扩展)则重新建档并在正文首行标注来源链 `延续 {原归档任务名}(见 archive/{YYYYMM}/{YYYYMMDD}.md)`、仅修正旧记录错误走历史修正(fxri-session-recap 模式三)不建档。**归档任务不可变**:已归档块是终结记录,不追加新内容,延续需求一律走新任务。
13
+ 1. **先查后写**:新建、更新或归档任务前,先 `toolkit tasks` 查看 active 总览,并核对 archive 是否已有同主题任务;active 已有同主题任务则更新原文件,禁止重复建档;已分叉成不同范围时问用户(拆新任务 or 合并更新)。archive 已有同主题任务(已归档完成)时按**改动判别**:本次不产生仓库文件改动(重复提议 / 重复执行)则不重复建档,仅提示「同主题任务已归档于 {日期}」;本次产生仓库文件改动(延续 / 扩展 / 重新实现)则重新建档,并在正文首行标注来源链 `延续 {原归档任务名}(见 archive/{YYYYMM}/{YYYYMMDD}.md)`;仅修正旧记录的时间或内容走历史修正(fxri-session-recap 模式三),不建档。**仓库文件改动口径**:需写入版本控制的工作区文件的增 / 改 / 删(源码、配置、文档、技能、任务区自身均计入),纯读取、纯执行、纯汇报不计入;拿不准时列出差异问用户,不猜。**归档块不可变**:已归档块不追加新的工作内容,延续需求一律走新任务;唯一例外是**事实更正**——后续核实推翻原块结论时,在其正文末尾追加「修订记录」(保留原结论、不动元数据行、附更正时刻与依据)。
14
14
  2. **任务唯一键**:`{年月日}-{用户名}-{任务简述}` 唯一标识一个任务;多人对同一需求不得各自建档,应共用同一文件。
15
- 3. **收尾边界到沉淀**:强制约束到「归档 + 规范沉淀」为止——终结态任务归档后做任务级规范沉淀(写入 conventions 载体),归档 + 沉淀即流程终点;提交、发版、推送不是必经步骤,是否执行取决于用户的全局 / 个人 / 项目规则。若提交代码,先归档与沉淀、后提交,任务记录与代码变更落在同一 git 提交。
15
+ 3. **收尾边界到沉淀**:强制约束到「归档 + 规范沉淀」为止——终结态任务归档后做任务级规范沉淀(写入 conventions 载体),归档 + 沉淀即流程终点;提交、发版、推送不是必经步骤,是否执行取决于用户的全局 / 个人 / 项目规则。**动作不算,改动才算**:任务 = 已确认的方案 + 它落地的仓库文件改动;收尾动作(提交、发版、推送、部署)本身及其固有产物(版本号、更新日志、标签)不构成任务、不单独建档,但当这些动作过程中出现需改仓库文件才能解决的缺陷(如打包配置错误、发布渠道错误)时,该修复按普通任务建档。若提交代码,先归档与沉淀、后提交,任务记录与代码变更落在同一 git 提交。
16
16
  4. **可执行项必须落地为任务**:方案正文里的「待办 / 待实施 / 待核对」等子项,应拆分为独立 active 任务,不留游离待办;`toolkit tasks check` 会扫描此类未闭合标记。
17
17
 
18
18
  ## 1. 目录结构
package/dist/cli.cjs CHANGED
@@ -95,7 +95,7 @@ ${n.deps}`,n.deps);for(;;){let h=l.replace(/^- (.+)\n- \1$/gm,"- $1");if(h===l)b
95
95
  `:`
96
96
  `,o=n.endsWith(`
97
97
  `)||n===""?n:n+r;$(t,o+vn.replace(/\n/g,r).replace(/^\r?\n/,""))}function wn(e){return JSON.stringify({schemaVersion:1,...e},null,2)}function ie(e){return e&&e!=="json"?(console.error(`\u26A0\uFE0F \u4E0D\u652F\u6301\u7684\u8F93\u51FA\u683C\u5F0F\u300C${e}\u300D\uFF0C\u4EC5\u652F\u6301 json`),process.exitCode=1,!1):!0}var y=require("fs"),k=require("path"),Tn=require("url");var xn="@fxri/toolkit",ut="SKILL.md",W=".agents/skills",Rn="canonical\uFF08\u591A\u5BB6 agent \u5171\u8BFB\uFF09",wo=".toolkit-skills.json",An=[{name:"aider-desk",label:"AiderDesk",dir:".aider-desk/skills"},{name:"amp",label:"Amp",dir:".config/agents/skills",detect:[".config/amp"]},{name:"antigravity",label:"Antigravity",dir:".gemini/antigravity/skills"},{name:"antigravity-cli",label:"Antigravity CLI",dir:".gemini/antigravity-cli/skills"},{name:"astrbot",label:"AstrBot",dir:".astrbot/data/skills",detect:[".astrbot"]},{name:"autohand-code",label:"Autohand Code CLI",dir:".autohand/skills"},{name:"augment",label:"Augment",dir:".augment/skills"},{name:"bob",label:"IBM Bob",dir:".bob/skills"},{name:"claude-code",label:"Claude Code",dir:".claude/skills"},{name:"openclaw",label:"OpenClaw",dir:".openclaw/skills",detect:[".openclaw",".clawdbot",".moltbot"]},{name:"cline",label:"Cline",dir:W,detect:[".cline"]},{name:"codearts-agent",label:"CodeArts Agent",dir:".codeartsdoer/skills"},{name:"codebuddy",label:"CodeBuddy",dir:".codebuddy/skills"},{name:"codemaker",label:"Codemaker",dir:".codemaker/skills"},{name:"codestudio",label:"Code Studio",dir:".codestudio/skills"},{name:"codex",label:"Codex",dir:".codex/skills",detect:[".codex","/etc/codex"]},{name:"command-code",label:"Command Code",dir:".commandcode/skills"},{name:"continue",label:"Continue",dir:".continue/skills"},{name:"cortex",label:"Cortex Code",dir:".snowflake/cortex/skills"},{name:"crush",label:"Crush",dir:".config/crush/skills"},{name:"cursor",label:"Cursor",dir:".cursor/skills"},{name:"deepagents",label:"Deep Agents",dir:".deepagents/agent/skills",detect:[".deepagents"]},{name:"devin",label:"Devin for Terminal",dir:".config/devin/skills"},{name:"dexto",label:"Dexto",dir:W,detect:[".dexto"]},{name:"droid",label:"Droid",dir:".factory/skills"},{name:"firebender",label:"Firebender",dir:".firebender/skills"},{name:"forgecode",label:"ForgeCode",dir:".forge/skills"},{name:"fx",label:"fx",dir:".fx/skills"},{name:"gemini-cli",label:"Gemini CLI",dir:".gemini/skills"},{name:"github-copilot",label:"GitHub Copilot",dir:".copilot/skills"},{name:"goose",label:"Goose",dir:".config/goose/skills"},{name:"grok",label:"Grok Build",dir:".grok/skills"},{name:"hermes-agent",label:"Hermes Agent",dir:".hermes/skills"},{name:"inference-sh",label:"inference.sh",dir:".inferencesh/skills"},{name:"jazz",label:"Jazz",dir:".jazz/skills"},{name:"junie",label:"Junie",dir:".junie/skills"},{name:"iflow-cli",label:"iFlow CLI",dir:".iflow/skills"},{name:"kilo",label:"Kilo Code",dir:".kilo/skills",detect:[".kilo",".kilocode"]},{name:"kimchi",label:"Kimchi",dir:".config/kimchi/harness/skills",detect:[".config/kimchi"]},{name:"kimi-code-cli",label:"Kimi Code CLI",dir:W,detect:[".kimi-code",".kimi"]},{name:"kiro-cli",label:"Kiro CLI",dir:".kiro/skills"},{name:"kode",label:"Kode",dir:".kode/skills"},{name:"lingma",label:"Lingma",dir:".lingma/skills"},{name:"loaf",label:"Loaf",dir:W,detect:[".loaf"]},{name:"mcpjam",label:"MCPJam",dir:".mcpjam/skills"},{name:"minimax-code",label:"MiniMax Code",dir:".minimax/skills",detect:[".minimax","/Applications/MiniMax Code.app"]},{name:"mistral-vibe",label:"Mistral Vibe",dir:".vibe/skills"},{name:"moxby",label:"Moxby",dir:".moxby/skills"},{name:"mux",label:"Mux",dir:".mux/skills"},{name:"opencode",label:"OpenCode",dir:".config/opencode/skills"},{name:"openhands",label:"OpenHands",dir:".openhands/skills"},{name:"ona",label:"Ona",dir:".ona/skills"},{name:"pi",label:"Pi",dir:".pi/agent/skills"},{name:"posit-assistant",label:"Posit Assistant",dir:".posit/assistant/skills",detect:[".posit/assistant",".positai"]},{name:"qoder",label:"Qoder",dir:".qoder/skills"},{name:"qoder-cn",label:"Qoder CN",dir:".qoder-cn/skills"},{name:"qwen-code",label:"Qwen Code",dir:".qwen/skills"},{name:"replit",label:"Replit",dir:".config/agents/skills"},{name:"reasonix",label:"Reasonix",dir:".reasonix/skills"},{name:"rovodev",label:"Rovo Dev",dir:".rovodev/skills"},{name:"roo",label:"Roo Code",dir:".roo/skills"},{name:"sarvam-code",label:"Sarvam Code",dir:W,detect:[".sarvam"]},{name:"tabnine-cli",label:"Tabnine CLI",dir:".tabnine/agent/skills",detect:[".tabnine"]},{name:"terramind",label:"Terramind",dir:".terramind/skills"},{name:"tinycloud",label:"Tinycloud",dir:".tinycloud/skills"},{name:"trae",label:"Trae",dir:".trae/skills"},{name:"trae-cn",label:"Trae CN",dir:".trae-cn/skills"},{name:"warp",label:"Warp",dir:W,detect:[".warp"]},{name:"windsurf",label:"Windsurf",dir:".codeium/windsurf/skills"},{name:"zed",label:"Zed",dir:W,detect:[".config/zed"]},{name:"zcode",label:"ZCode",dir:".zcode/skills",detect:[".zcode","/Applications/ZCode.app"]},{name:"zencoder",label:"Zencoder",dir:".zencoder/skills"},{name:"zenflow",label:"Zenflow",dir:".zencoder/skills"},{name:"neovate",label:"Neovate",dir:".neovate/skills"},{name:"pochi",label:"Pochi",dir:".pochi/skills"},{name:"adal",label:"AdaL",dir:".adal/skills"},{name:"universal",label:"Universal",dir:".config/agents/skills"}],dt;function Cn(){if(dt)return dt;let e=(0,k.dirname)((0,Tn.fileURLToPath)(v));for(;;){let t=(0,k.join)(e,"package.json");if((0,y.existsSync)(t))try{if(JSON.parse(R(t)).name===xn)return dt=e,e}catch{}let n=(0,k.dirname)(e);if(n===e)break;e=n}throw new Error(`\u672A\u80FD\u4ECE\u6A21\u5757\u4F4D\u7F6E\u5411\u4E0A\u5B9A\u4F4D ${xn} \u7684\u5305\u6839\u76EE\u5F55`)}function Z(){return(0,k.join)(Cn(),"skills")}function ft(){return Cn()}function xo(e){try{let n=R((0,k.join)(e,ut)).match(/^---\r?\n([\s\S]*?)\r?\n---/);if(!n)return"";let r=(n[1]??"").match(/^[ \t]+version:[ \t]*"?([^"\r\n]+?)"?[ \t]*$/m);return r?(r[1]??"").trim():""}catch{return""}}function $o(e){try{let n=R((0,k.join)(e,ut)).match(/^>[ \t]*本技能版本[ \t]*([^ \t((]+)/m);return n?(n[1]??"").trim():""}catch{return""}}function To(e){let t=[];for(let n of e){if(!n.version)continue;let r=$o(n.dir);r!==n.version&&t.push({name:n.name,frontmatter:n.version,body:r})}return t}function $e(){let e=Z();if(!(0,y.existsSync)(e))return[];let t=[];for(let n of(0,y.readdirSync)(e).sort()){let r=(0,k.join)(e,n);try{if(!(0,y.lstatSync)(r).isDirectory())continue}catch{continue}(0,y.existsSync)((0,k.join)(r,ut))&&t.push({name:n,dir:r,version:xo(r)})}return t}function N(e){let t=(0,k.normalize)((0,k.resolve)(e));return process.platform==="win32"?t.toLowerCase():t}function Ro(e){let t=(0,k.normalize)(e);return/^[a-zA-Z]:[\\/]$/.test(t)?t:t.replace(/[\\/]+$/,"")||t}function Ye(e,t,n,r=!1){let o;if(n)o=n;else try{o=(0,y.lstatSync)(e)}catch{return"absent"}if(o.isSymbolicLink()){let s="";try{s=(0,y.readlinkSync)(e)}catch{return"dangling"}let i=Ro((0,k.isAbsolute)(s)?s:(0,k.resolve)((0,k.dirname)(e),s));return N(i)!==N(t)?"wrong":r||(0,y.existsSync)(e)?"link-ok":"dangling"}return o.isDirectory()?"dir":"file"}function We(e,t){let n,r;try{n=(0,y.readdirSync)(e).sort(),r=(0,y.readdirSync)(t).sort()}catch{return!1}if(n.length!==r.length||n.some((o,s)=>o!==r[s]))return!1;for(let o of n){let s=(0,k.join)(e,o),i=(0,k.join)(t,o),a,l;try{a=(0,y.statSync)(s),l=(0,y.statSync)(i)}catch{return!1}if(a.isDirectory()!==l.isDirectory())return!1;if(a.isDirectory()){if(!We(s,i))return!1}else try{if(!(0,y.readFileSync)(s).equals((0,y.readFileSync)(i)))return!1}catch{return!1}}return!0}function Te(){return(0,k.join)(ae(),".agents",wo)}function Ke(){let e=Te();if(!(0,y.existsSync)(e))return null;try{let t=JSON.parse(R(e));return!t||!Array.isArray(t.targets)?null:t}catch{return null}}function En(e){let t=Te();(0,y.mkdirSync)((0,k.dirname)(t),{recursive:!0});let n={version:1,updatedAt:new Date().toISOString(),targets:e};$(t,`${JSON.stringify(n,null,2)}
98
- `)}function Ln(e=[]){let t=ae(),n=[],r=new Set,o=(s,i,a,l)=>{let d=(0,k.resolve)(s),u=N(d);r.has(u)||(r.add(u),n.push({dir:d,label:i,kind:a,available:l,dirExists:(0,y.existsSync)(d)}))};o((0,k.join)(t,W),Rn,"primary",!0);for(let s of An){let i=(0,k.join)(t,(0,k.dirname)(s.dir)),a=(0,y.existsSync)(i)||(s.detect??[]).some(l=>(0,y.existsSync)((0,k.isAbsolute)(l)?l:(0,k.join)(t,l)));o((0,k.join)(t,s.dir),s.label,"agent",a)}for(let s of e)o(s,"\u81EA\u5B9A\u4E49 --dir","custom",!0);return n}function Ao(e){let t=N((0,k.resolve)(e));return t===N((0,k.join)(ae(),W))?Rn:An.find(r=>N((0,k.join)(ae(),r.dir))===t)?.label??null}function mt(e){(0,y.rmSync)(e,{recursive:!0,force:!0})}function $n(e,t){(0,y.mkdirSync)((0,k.dirname)(t),{recursive:!0}),(0,y.cpSync)(e,t,{recursive:!0})}function Co(e,t,n){if(n)return $n(e,t),{mode:"copy"};try{return(0,y.mkdirSync)((0,k.dirname)(t),{recursive:!0}),(0,y.symlinkSync)(e,t,process.platform==="win32"?"junction":"dir"),{mode:"link"}}catch(r){return $n(e,t),{mode:"copy",reason:r.message}}}function In(e={}){let t=$e(),n=Ln(e.dirs??[]),r=Ke(),o=new Map;for(let l of r?.targets??[])o.set(N(l.dir),l);let s=[],i=[],a=[];for(let l of n){if(!l.available){i.push({dir:l.dir,label:l.label});continue}let d={dir:l.dir,label:l.label,kind:l.kind,created:[],updated:[],skipped:[],conflicts:[],failed:[],degraded:[],links:[],copies:[]};for(let u of t){let m=(0,k.join)(l.dir,u.name),p=Ye(m,u.dir);if(p==="link-ok"){d.skipped.push(u.name),d.links.push(u.name);continue}if(p==="dir"&&!e.force){if(!(o.get(N(l.dir))?.copies.includes(u.name)??!1)){d.conflicts.push(u.name);continue}if(We(u.dir,m)){d.skipped.push(u.name),d.copies.push(u.name);continue}}if(p==="file"&&!e.force){d.conflicts.push(u.name);continue}if(e.dryRun){p==="absent"?d.created.push(u.name):d.updated.push(u.name),e.copy?d.copies.push(u.name):d.links.push(u.name);continue}try{p!=="absent"&&mt(m);let c=Co(u.dir,m,!!e.copy);p==="absent"?d.created.push(u.name):d.updated.push(u.name),c.mode==="link"?d.links.push(u.name):(d.copies.push(u.name),c.reason&&d.degraded.push({name:u.name,reason:c.reason}))}catch(c){d.failed.push({name:u.name,reason:c.message})}}s.push(d),e.dryRun||a.push({dir:l.dir,updatedAt:new Date().toISOString(),links:d.links,copies:d.copies})}if(!e.dryRun){let l=new Set(s.map(m=>N(m.dir))),d=(r?.targets??[]).filter(m=>!l.has(N(m.dir))),u=[...a,...d].filter(m=>m.links.length>0||m.copies.length>0);u.length>0&&En(u)}return{source:Z(),skills:t.map(l=>l.name),targets:s,skippedTargets:i,stateFile:Te()}}function Fn(e={}){let t=Ke(),n=Te();if(!t)return{stateFile:n,stateExists:!1,targets:[],stateRemoved:!1};let r=[],o=!1;for(let a of t.targets){let l={dir:a.dir,label:Ao(a.dir),removed:[],missing:[],skippedForeign:[]},d=[...new Set([...a.links,...a.copies])];for(let u of d){let m=(0,k.join)(a.dir,u),p=(0,k.join)(Z(),u),c=Ye(m,p);if(c==="absent"){l.missing.push(u);continue}if(c==="wrong"){l.skippedForeign.push(u);continue}if(c==="file"){l.skippedForeign.push(u);continue}if(c==="dir"&&!We(p,m)){l.skippedForeign.push(u);continue}if(e.dryRun){l.removed.push(u);continue}try{mt(m),l.removed.push(u)}catch{o=!0,l.skippedForeign.push(u)}}r.push(l)}let s=r.every(a=>a.skippedForeign.length===0),i=!e.dryRun&&!o&&s;return i&&(0,y.rmSync)(n,{force:!0}),{stateFile:n,stateExists:!0,targets:r,stateRemoved:i}}function On(){let e=$e(),t=Ln([]),n=Ke(),r=new Map;for(let i of n?.targets??[])r.set(N(i.dir),i);let o=[],s=[];for(let i of t){let a=r.get(N(i.dir));if(!i.available&&i.kind==="agent"){s.push({dir:i.dir,label:i.label});continue}if(i.kind!=="primary"&&!i.dirExists&&!a)continue;let l=[...new Set([...e.map(m=>m.name),...a?[...a.links,...a.copies]:[]])].sort(),d=new Map(e.map(m=>[m.name,m.version])),u=[];for(let m of l){let p=(0,k.join)(Z(),m),c=(0,k.join)(i.dir,m),f=Ye(c,p),g;f==="link-ok"?g="link":f==="dangling"?g="dangling":f==="wrong"?g="wrong":f==="file"?g="conflict":f==="dir"?(0,y.existsSync)(p)&&We(p,c)?g="copy":g=a?.copies.includes(m)?"copy-drift":"conflict":g="missing",u.push({name:m,state:g,version:d.get(m)??""})}o.push({dir:i.dir,label:i.label,kind:i.kind,available:i.available,dirExists:i.dirExists,recorded:!!a,items:u})}return{source:Z(),skills:e.map(i=>i.name),skillVersions:Object.fromEntries(e.map(i=>[i.name,i.version])),versionMismatches:To(e),stateFile:Te(),stateExists:!!n,targets:o,pendingAgents:s}}function jn(){let e=_("skills");if(e?.autoLink===!1||process.env.CI)return 0;let t=Ke();if(!t)return 0;let n=Z(),r;try{r=new Set((0,y.readdirSync)(n).filter(l=>(0,y.existsSync)((0,k.join)(n,l))))}catch{return 0}let o=e?.autoLinkReplaceForeign!==!1,s=process.platform==="win32"?"junction":"dir",i=0,a=[];for(let l of t.targets){let d;try{d=(0,y.readdirSync)(l.dir,{withFileTypes:!0})}catch{a.push(l);continue}let u=new Map(d.map(p=>[p.name,p])),m=l.links.filter(p=>{if(!r.has(p))return!1;let c=(0,k.join)(n,p),f=(0,k.join)(l.dir,p),g=u.get(p),h=g?Ye(f,c,g,!0):"absent";if(h==="link-ok"||!o&&(h==="dir"||h==="file"))return!0;try{return h!=="absent"&&mt(f),(0,y.symlinkSync)(c,f,s),i+=1,!0}catch{return!0}});a.push({...l,links:m,updatedAt:new Date().toISOString()})}return i>0&&En(a),i}var me=require("fs"),Dn=require("path"),pt=require("os"),Nn=require("child_process");var Eo="https://registry.npmjs.org/@fxri%2Ftoolkit/latest";async function Mn(){try{let e=await fetch(Eo,{signal:AbortSignal.timeout(1e3),headers:{accept:"application/vnd.npm.install-v1+json"}});if(!e.ok)return null;let t=await e.json();return typeof t.version=="string"?t.version:null}catch{return null}}function _n(e,t){let n=i=>i.trim().replace(/^-/,"").split(/[.+-]/).map(a=>Number.parseInt(a,10)).map(a=>Number.isFinite(a)?a:0),r=n(e),o=n(t),s=Math.max(r.length,o.length);for(let i=0;i<s;i++){let a=r[i]??0,l=o[i]??0;if(a!==l)return a>l}return!1}var Lo=1440*60*1e3,Io=3600*1e3,Fo="FX_NO_UPDATE_CHECK",gt="--fxri-update-check-worker";function Bn(){return(0,Dn.join)((0,pt.tmpdir)(),".toolkit-update-check.json")}function Oo(){let e=Bn();try{if(!(0,me.existsSync)(e))return null;let t=JSON.parse(R(e)),n=typeof t.ts=="number"?t.ts:0,r=typeof t.latest=="string"?t.latest:"",o=t.ok===!0,s=o?Lo:Io;return Date.now()-n>=s?((0,me.rmSync)(e,{force:!0}),null):o&&!r?null:{ts:n,ok:o,latest:r}}catch{return null}}function jo(e,t){try{let n=Bn();(0,me.mkdirSync)((0,pt.tmpdir)(),{recursive:!0}),$(n,JSON.stringify({ts:Date.now(),ok:e,latest:t}))}catch{}}function Mo(){let e=process.env[Fo];if(e!==void 0&&e!=="")return!["0","false","off","no"].includes(e.trim().toLowerCase());let t=qe()?.updateCheck;return t&&typeof t=="object"?t.enabled===!1:!1}function Pn(e){if(Mo())return;let t=Oo();if(t){t.ok&&_n(t.latest,e)&&Do(t.latest,e);return}_o()}function _o(){let e=process.argv[1];if(e)try{(0,Nn.spawn)(process.execPath,[e,gt],{detached:!0,stdio:"ignore",windowsHide:!0}).unref()}catch{}}async function Un(){let e=await Mn().catch(()=>null);jo(e!==null,e??"")}function Do(e,t){console.error(`\u2B06\uFE0F \u53D1\u73B0\u65B0\u7248\u672C ${e}\uFF08\u5F53\u524D ${t}\uFF09\uFF1Apnpm add -g @fxri/toolkit \u5347\u7EA7\u540E\u8BF7\u5F00\u65B0\u4F1A\u8BDD\u52A0\u8F7D\u6700\u65B0 skills \u89C4\u5219\uFF1B\u672C\u5730\u6280\u80FD\u53EF\u7528 toolkit skills status \u68C0\u67E5\uFF08\u8F6F\u94FE\u81EA\u52A8\u8DDF\u968F\uFF0C\u526F\u672C\u5F62\u5F0F\u9700\u91CD\u8DD1 toolkit skills install\uFF09`)}var No="\u663E\u793A\u5E2E\u52A9",Bo=["version","format"];function ht(e){e.helpOption("-h, --help",No),e.configureHelp({subcommandTerm:t=>`${t.name()} ${t.usage()}`.replace(/\s+/g," ").trim()});for(let t of e.commands)ht(t)}function zn(e){return Bo.includes(e[0])?e.slice(1).some(t=>t==="-h"||t==="--help"):!1}var kt="\u8FD0\u884C toolkit --help \u67E5\u770B\u53EF\u7528\u547D\u4EE4";function Yn(e){let t=/\n\(Did you mean (one of )?([^)]*?)\?\)$/.exec(e);if(!t)return"";let n=t[2].split(", ").join("\u3001");return t[1]?`\uFF08\u662F\u5426\u60F3\u8F93\u5165 ${n} \u4E4B\u4E00\uFF1F\uFF09`:`\uFF08\u662F\u5426\u60F3\u8F93\u5165 ${n}\uFF1F\uFF09`}function Wn(e){switch(e.code){case"commander.unknownCommand":{let t=/unknown command '([^']*)'/.exec(e.message)?.[1];return t?`\u26A0\uFE0F \u672A\u77E5\u547D\u4EE4\u300C${t}\u300D\u3002${Yn(e.message)}
98
+ `)}function Ln(e=[]){let t=ae(),n=[],r=new Set,o=(s,i,a,l)=>{let d=(0,k.resolve)(s),u=N(d);r.has(u)||(r.add(u),n.push({dir:d,label:i,kind:a,available:l,dirExists:(0,y.existsSync)(d)}))};o((0,k.join)(t,W),Rn,"primary",!0);for(let s of An){let i=(0,k.join)(t,(0,k.dirname)(s.dir)),a=(0,y.existsSync)(i)||(s.detect??[]).some(l=>(0,y.existsSync)((0,k.isAbsolute)(l)?l:(0,k.join)(t,l)));o((0,k.join)(t,s.dir),s.label,"agent",a)}for(let s of e)o(s,"\u81EA\u5B9A\u4E49 --dir","custom",!0);return n}function Ao(e){let t=N((0,k.resolve)(e));return t===N((0,k.join)(ae(),W))?Rn:An.find(r=>N((0,k.join)(ae(),r.dir))===t)?.label??null}function mt(e){(0,y.rmSync)(e,{recursive:!0,force:!0})}function $n(e,t){(0,y.mkdirSync)((0,k.dirname)(t),{recursive:!0}),(0,y.cpSync)(e,t,{recursive:!0})}function Co(e,t,n){if(n)return $n(e,t),{mode:"copy"};try{return(0,y.mkdirSync)((0,k.dirname)(t),{recursive:!0}),(0,y.symlinkSync)(e,t,process.platform==="win32"?"junction":"dir"),{mode:"link"}}catch(r){return $n(e,t),{mode:"copy",reason:r.message}}}function In(e={}){let t=$e(),n=Ln(e.dirs??[]),r=Ke(),o=new Map;for(let l of r?.targets??[])o.set(N(l.dir),l);let s=[],i=[],a=[];for(let l of n){if(!l.available){i.push({dir:l.dir,label:l.label});continue}let d={dir:l.dir,label:l.label,kind:l.kind,created:[],updated:[],skipped:[],conflicts:[],failed:[],degraded:[],links:[],copies:[]};for(let u of t){let m=(0,k.join)(l.dir,u.name),p=Ye(m,u.dir);if(p==="link-ok"){d.skipped.push(u.name),d.links.push(u.name);continue}if(p==="dir"&&!e.force){if(!(o.get(N(l.dir))?.copies.includes(u.name)??!1)){d.conflicts.push(u.name);continue}if(We(u.dir,m)){d.skipped.push(u.name),d.copies.push(u.name);continue}}if(p==="file"&&!e.force){d.conflicts.push(u.name);continue}if(e.dryRun){p==="absent"?d.created.push(u.name):d.updated.push(u.name),e.copy?d.copies.push(u.name):d.links.push(u.name);continue}try{p!=="absent"&&mt(m);let c=Co(u.dir,m,!!e.copy);p==="absent"?d.created.push(u.name):d.updated.push(u.name),c.mode==="link"?d.links.push(u.name):(d.copies.push(u.name),c.reason&&d.degraded.push({name:u.name,reason:c.reason}))}catch(c){d.failed.push({name:u.name,reason:c.message})}}s.push(d),e.dryRun||a.push({dir:l.dir,updatedAt:new Date().toISOString(),links:d.links,copies:d.copies})}if(!e.dryRun){let l=new Set(s.map(m=>N(m.dir))),d=(r?.targets??[]).filter(m=>!l.has(N(m.dir))),u=[...a,...d].filter(m=>m.links.length>0||m.copies.length>0);u.length>0&&En(u)}return{source:Z(),skills:t.map(l=>l.name),targets:s,skippedTargets:i,stateFile:Te()}}function Fn(e={}){let t=Ke(),n=Te();if(!t)return{stateFile:n,stateExists:!1,targets:[],stateRemoved:!1};let r=[],o=!1;for(let a of t.targets){let l={dir:a.dir,label:Ao(a.dir),removed:[],missing:[],skippedForeign:[]},d=[...new Set([...a.links,...a.copies])];for(let u of d){let m=(0,k.join)(a.dir,u),p=(0,k.join)(Z(),u),c=Ye(m,p);if(c==="absent"){l.missing.push(u);continue}if(c==="wrong"){l.skippedForeign.push(u);continue}if(c==="file"){l.skippedForeign.push(u);continue}if(c==="dir"&&!We(p,m)){l.skippedForeign.push(u);continue}if(e.dryRun){l.removed.push(u);continue}try{mt(m),l.removed.push(u)}catch{o=!0,l.skippedForeign.push(u)}}r.push(l)}let s=r.every(a=>a.skippedForeign.length===0),i=!e.dryRun&&!o&&s;return i&&(0,y.rmSync)(n,{force:!0}),{stateFile:n,stateExists:!0,targets:r,stateRemoved:i}}function On(){let e=$e(),t=Ln([]),n=Ke(),r=new Map;for(let i of n?.targets??[])r.set(N(i.dir),i);let o=[],s=[];for(let i of t){let a=r.get(N(i.dir));if(!i.available&&i.kind==="agent"){s.push({dir:i.dir,label:i.label});continue}if(i.kind!=="primary"&&!i.dirExists&&!a)continue;let l=[...new Set([...e.map(m=>m.name),...a?[...a.links,...a.copies]:[]])].sort(),d=new Map(e.map(m=>[m.name,m.version])),u=[];for(let m of l){let p=(0,k.join)(Z(),m),c=(0,k.join)(i.dir,m),f=Ye(c,p),g;f==="link-ok"?g="link":f==="dangling"?g="dangling":f==="wrong"?g="wrong":f==="file"?g="conflict":f==="dir"?(0,y.existsSync)(p)&&We(p,c)?g="copy":g=a?.copies.includes(m)?"copy-drift":"conflict":g="missing",u.push({name:m,state:g,version:d.get(m)??""})}o.push({dir:i.dir,label:i.label,kind:i.kind,available:i.available,dirExists:i.dirExists,recorded:!!a,items:u})}return{source:Z(),skills:e.map(i=>i.name),skillVersions:Object.fromEntries(e.map(i=>[i.name,i.version])),versionMismatches:To(e),stateFile:Te(),stateExists:!!n,targets:o,pendingAgents:s}}function jn(){let e=_("skills");if(e?.autoLink===!1||process.env.CI)return 0;let t=Ke();if(!t)return 0;let n=Z(),r;try{r=new Set((0,y.readdirSync)(n).filter(l=>(0,y.existsSync)((0,k.join)(n,l))))}catch{return 0}let o=e?.autoLinkReplaceForeign!==!1,s=process.platform==="win32"?"junction":"dir",i=0,a=[];for(let l of t.targets){let d;try{d=(0,y.readdirSync)(l.dir,{withFileTypes:!0})}catch{a.push(l);continue}let u=new Map(d.map(p=>[p.name,p])),m=l.links.filter(p=>{if(!r.has(p))return!1;let c=(0,k.join)(n,p),f=(0,k.join)(l.dir,p),g=u.get(p),h=g?Ye(f,c,g,!0):"absent";if(h==="link-ok"||!o&&(h==="dir"||h==="file"))return!0;try{return h!=="absent"&&mt(f),(0,y.symlinkSync)(c,f,s),i+=1,!0}catch{return!0}});a.push({...l,links:m,updatedAt:new Date().toISOString()})}return i>0&&En(a),i}var me=require("fs"),Dn=require("path"),pt=require("os"),Nn=require("child_process");var Eo="https://registry.npmjs.org/@fxri%2Ftoolkit/latest";async function Mn(){try{let e=await fetch(Eo,{signal:AbortSignal.timeout(1e3),headers:{accept:"application/vnd.npm.install-v1+json"}});if(!e.ok)return null;let t=await e.json();return typeof t.version=="string"?t.version:null}catch{return null}}function _n(e,t){let n=i=>i.trim().replace(/^-/,"").split(/[.+-]/).map(a=>Number.parseInt(a,10)).map(a=>Number.isFinite(a)?a:0),r=n(e),o=n(t),s=Math.max(r.length,o.length);for(let i=0;i<s;i++){let a=r[i]??0,l=o[i]??0;if(a!==l)return a>l}return!1}var Lo=1440*60*1e3,Io=3600*1e3,Fo="FX_NO_UPDATE_CHECK",gt="--fxri-update-check-worker";function Bn(){return(0,Dn.join)((0,pt.tmpdir)(),".toolkit-update-check.json")}function Oo(){let e=Bn();try{if(!(0,me.existsSync)(e))return null;let t=JSON.parse(R(e)),n=typeof t.ts=="number"?t.ts:0,r=typeof t.latest=="string"?t.latest:"",o=t.ok===!0,s=o?Lo:Io;return Date.now()-n>=s?((0,me.rmSync)(e,{force:!0}),null):o&&!r?null:{ts:n,ok:o,latest:r}}catch{return null}}function jo(e,t){try{let n=Bn();(0,me.mkdirSync)((0,pt.tmpdir)(),{recursive:!0}),$(n,JSON.stringify({ts:Date.now(),ok:e,latest:t}))}catch{}}function Mo(){let e=process.env[Fo];if(e!==void 0&&e!=="")return!["0","false","off","no"].includes(e.trim().toLowerCase());let t=qe()?.updateCheck;return t&&typeof t=="object"?t.enabled===!1:!1}function Pn(e){if(Mo())return;let t=Oo();if(t){t.ok&&_n(t.latest,e)&&Do(t.latest,e);return}_o()}function _o(){let e=process.argv[1];if(e)try{(0,Nn.spawn)(process.execPath,[e,gt],{detached:!0,stdio:"ignore",windowsHide:!0}).unref()}catch{}}async function Un(){let e=await Mn().catch(()=>null);jo(e!==null,e??"")}function Do(e,t){console.error(`\u2B06\uFE0F \u53D1\u73B0\u65B0\u7248\u672C ${e}\uFF08\u5F53\u524D ${t}\uFF09\uFF1Apnpm add -g @fxri/toolkit \u5347\u7EA7\u540E\u8BF7\u5F00\u65B0\u4F1A\u8BDD\u52A0\u8F7D\u6700\u65B0 skills \u89C4\u5219\uFF1B\u672C\u5730\u6280\u80FD\u53EF\u7528 toolkit skills status \u68C0\u67E5\uFF08\u8F6F\u94FE\u81EA\u52A8\u8DDF\u968F\uFF0C\u526F\u672C\u5F62\u5F0F\u9700\u91CD\u8DD1 toolkit skills install\uFF09`)}var No="\u663E\u793A\u5E2E\u52A9",Bo=["version","format"];function ht(e){e.helpOption("-h, --help",No),e.configureHelp({subcommandTerm:t=>`${t.name()} ${t.usage()}`.replace(/\s+/g," ").trim()});for(let t of e.commands)ht(t)}function zn(e){let[t]=e;return!t||!Bo.includes(t)?!1:e.slice(1).some(n=>n==="-h"||n==="--help")}var kt="\u8FD0\u884C toolkit --help \u67E5\u770B\u53EF\u7528\u547D\u4EE4";function Yn(e){let t=/\n\(Did you mean (one of )?([^)]*?)\?\)$/.exec(e);if(!t)return"";let n=(t[2]??"").split(", ").join("\u3001");return t[1]?`\uFF08\u662F\u5426\u60F3\u8F93\u5165 ${n} \u4E4B\u4E00\uFF1F\uFF09`:`\uFF08\u662F\u5426\u60F3\u8F93\u5165 ${n}\uFF1F\uFF09`}function Wn(e){switch(e.code){case"commander.unknownCommand":{let t=/unknown command '([^']*)'/.exec(e.message)?.[1];return t?`\u26A0\uFE0F \u672A\u77E5\u547D\u4EE4\u300C${t}\u300D\u3002${Yn(e.message)}
99
99
  ${kt}`:null}case"commander.unknownOption":{let t=/unknown option '([^']*)'/.exec(e.message)?.[1];return t?`\u26A0\uFE0F \u672A\u77E5\u9009\u9879\u300C${t}\u300D\u3002${Yn(e.message)}
100
100
  ${kt}`:null}case"commander.excessArguments":{let t=/too many arguments(?: for '([^']*)')?\. Expected (\d+) arguments? but got (\d+)\./.exec(e.message);return t?`\u26A0\uFE0F ${t[1]?`\u547D\u4EE4\u300C${t[1]}\u300D`:"\u547D\u4EE4"}\u671F\u671B ${t[2]} \u4E2A\u53C2\u6570\uFF0C\u5B9E\u9645\u6536\u5230 ${t[3]} \u4E2A\u3002
101
101
  ${kt}`:null}default:return null}}var Kn="\u4E13\u4E3A\u591A\u4EBA + AI \u8DE8\u9879\u76EE\u534F\u4F5C\u6253\u9020\uFF1A\u4EFB\u52A1\u7BA1\u7406 + \u591A\u8BED\u8A00 CHANGELOG\u3002";var qn=(0,Gn.createRequire)(v),Po=qn.resolve("@changesets/cli/bin.js"),{version:Zn}=qn("../package.json"),bt=e=>{let t=(0,Vn.spawnSync)(process.execPath,[Po,...e],{stdio:"inherit"});t.status!==0&&process.exit(t.status??1)};function Uo(){if(process.platform==="win32")try{process.stdout.setDefaultEncoding("utf8"),process.stderr.setDefaultEncoding("utf8")}catch{}}function Xn(){let e=_("check");return typeof e?.warnings=="boolean"?e.warnings:void 0}function zo(){let t=_("changelog")?.languages;if(!t||typeof t!="object")return ue;let n={...ue};for(let[r,o]of Object.entries(t))o&&typeof o=="object"&&(n[r]=o);return n}function Yo(e=".changeset"){if(!(0,Re.existsSync)(e))return!1;try{return(0,Re.readdirSync)(e).some(t=>t.endsWith(".md")&&t!=="README.md")}catch{return!1}}function Wo(e=".tasks"){return F((0,Jn.join)(e,"active")).length>0}function Hn(e){let t=fn(".",e);t>0&&console.warn(`\u26A0\uFE0F ${t} \u6761\u53D8\u66F4\u96C6\u6761\u76EE\u7F3A\u7C7B\u578B\u524D\u7F00\uFF0C\u5EFA\u8BAE\u6309\u300C\u7C7B\u578B\uFF1A\u63CF\u8FF0\u300D\u64B0\u5199`)}function He(e){if(e.length===0){console.log("\u672A\u53D1\u73B0\u95EE\u9898");return}for(let t of e)console.log(` ${t.file}${t.line?`:${t.line}`:""}: ${t.message}`)}function Ko(e,t){return[...t,e]}var Ho={link:"\u8F6F\u94FE\u6B63\u5E38",dangling:"\u8F6F\u94FE\u60AC\u7A7A\uFF08\u771F\u6E90\u7F3A\u5931\u6216\u5347\u7EA7\u540E\u65E7\u8DEF\u5F84\u5931\u6548\uFF09",wrong:"\u8F6F\u94FE\u6307\u5411\u522B\u5904",copy:"\u526F\u672C\u5DF2\u540C\u6B65","copy-drift":"\u526F\u672C\u5DF2\u6F02\u79FB\uFF08\u4E0E\u771F\u6E90\u4E0D\u4E00\u81F4\uFF09",missing:"\u7F3A\u5931",conflict:"\u540C\u540D\u51B2\u7A81\uFF08\u975E\u672C\u5305\u4EA7\u7269\uFF09"},Go=["dangling","wrong","copy-drift","missing","conflict"];function Ae(e){console.log(wn(e))}function Qn(e,t){return t?`${e}@${t}`:e}function Vo(e,t){let n=t?"[\u9884\u6F14] ":"",r=new Map($e().map(o=>[o.name,o.version]));console.log(`${n}\u6280\u80FD\u6E90\uFF1A${e.source}`),console.log(`${n}\u5305\u5185\u6280\u80FD\uFF08${e.skills.length}\uFF09\uFF1A${e.skills.map(o=>Qn(o,r.get(o)??"")).join("\u3001")||"\u65E0"}`);for(let o of e.targets){console.log(""),console.log(`${o.label}\uFF1A${o.dir}`),o.created.length>0&&console.log(` \u65B0\u5EFA\uFF1A${o.created.join("\u3001")}`),o.updated.length>0&&console.log(` \u91CD\u5EFA/\u66F4\u65B0\uFF1A${o.updated.join("\u3001")}`),o.skipped.length>0&&console.log(` \u8DF3\u8FC7\uFF08\u5DF2\u5C31\u7EEA\uFF09\uFF1A${o.skipped.join("\u3001")}`),o.conflicts.length>0&&console.log(` \u8DF3\u8FC7\uFF08\u540C\u540D\u975E\u672C\u5305\u4EA7\u7269\uFF0C\u5982\u9700\u8986\u76D6\u52A0 --force\uFF09\uFF1A${o.conflicts.join("\u3001")}`);for(let i of o.degraded)console.log(` \u26A0\uFE0F \u964D\u7EA7\u4E3A\u526F\u672C\uFF1A${i.name}\uFF08\u94FE\u63A5\u521B\u5EFA\u5931\u8D25\uFF1A${i.reason}\uFF09`);for(let i of o.failed)console.log(` \u26A0\uFE0F \u5931\u8D25\uFF1A${i.name}\uFF08${i.reason}\uFF09`);let s=[];o.links.length>0&&s.push(`\u8F6F\u94FE ${o.links.length} \u4E2A`),o.copies.length>0&&s.push(`\u526F\u672C ${o.copies.length} \u4E2A`),s.length>0&&console.log(` \u4EA7\u7269\u5F62\u6001\uFF1A${s.join(" / ")}`)}console.log(""),e.skippedTargets.length>0&&console.log(`\u672A\u5B89\u88C5\u7684 agent ${e.skippedTargets.length} \u4E2A\u5DF2\u8DF3\u8FC7\uFF08\u4E0D\u5728\u7528\u6237\u673A\u5668\u4E0A\u51ED\u7A7A\u9020\u76EE\u5F55\uFF09\uFF1B\u5982\u9700\u88C5\u5230\u672A\u8BC6\u522B\u7684 agent\uFF1Atoolkit skills install --dir <\u5176\u5168\u5C40\u6280\u80FD\u76EE\u5F55>`),console.log(`${n}\u72B6\u6001\u6587\u4EF6\uFF1A${e.stateFile}`),t&&console.log("[\u9884\u6F14] \u672A\u5199\u5165\u4EFB\u4F55\u6587\u4EF6\uFF1B\u786E\u8BA4\u65E0\u8BEF\u540E\u53BB\u6389 --dry-run \u6267\u884C")}function Jo(e){console.log(`\u6280\u80FD\u6E90\uFF1A${e.source}`),console.log(`\u6280\u80FD\u7248\u672C\uFF1A${e.skills.map(n=>Qn(n,e.skillVersions[n]??"")).join("\u3001")||"\u65E0"}`);for(let n of e.versionMismatches)console.warn(`\u26A0\uFE0F \u6280\u80FD\u7248\u672C\u53CC\u5199\u4F4D\u4E0D\u4E00\u81F4\uFF1A${n.name}\uFF08frontmatter ${n.frontmatter} / \u6B63\u6587 ${n.body||"\u672A\u58F0\u660E"}\uFF09`);console.log(`\u72B6\u6001\u6587\u4EF6\uFF1A${e.stateFile}${e.stateExists?"":"\uFF08\u672A\u8BB0\u5F55\uFF0C\u5C1A\u672A\u6267\u884C\u8FC7 toolkit skills install\uFF09"}`);let t=0;for(let n of e.targets){console.log(""),console.log(`${n.label}\uFF1A${n.dir}${n.dirExists?"":"\uFF08\u76EE\u5F55\u672A\u521B\u5EFA\uFF09"}`);for(let r of n.items)Go.includes(r.state)&&(t+=1),console.log(` ${r.name}\uFF1A${Ho[r.state]}`)}e.pendingAgents.length>0&&(console.log(""),console.log(`\u672A\u5B89\u88C5\u7684 agent ${e.pendingAgents.length} \u4E2A\u672A\u7EB3\u5165\u5206\u53D1\uFF08\u9700\u8981\u65F6\u7528 toolkit skills install --dir <\u8DEF\u5F84> \u6307\u5B9A\uFF09`)),console.log(""),console.log(t>0?`\u5171 ${t} \u5904\u9700\u5904\u7406\uFF1A\u7F3A\u5931 / \u60AC\u7A7A / \u6307\u5411\u9519\u8BEF / \u526F\u672C\u6F02\u79FB\u7528 toolkit skills install \u8865\u9F50\uFF0C\u540C\u540D\u51B2\u7A81\u7528 toolkit skills install --force \u8986\u76D6`:"\u6240\u6709\u5DF2\u7EB3\u5165\u7684\u76EE\u6807\u5747\u6B63\u5E38")}function qo(e,t){let n=t?"[\u9884\u6F14] ":"";if(!e.stateExists){console.log("\u672A\u627E\u5230\u672C\u5305\u7684\u72B6\u6001\u6587\u4EF6\uFF0C\u6CA1\u6709\u7531\u672C\u5305\u5B89\u88C5\u7684\u4EA7\u7269\u9700\u8981\u6E05\u7406\uFF08\u5176\u4ED6\u65B9\u5F0F\u5B89\u88C5\u7684\u6280\u80FD\u4E0D\u53D7\u5F71\u54CD\uFF09");return}console.log(`${n}\u72B6\u6001\u6587\u4EF6\uFF1A${e.stateFile}`);for(let r of e.targets)console.log(""),console.log(r.label?`${r.label}\uFF1A${r.dir}`:r.dir),r.removed.length>0&&console.log(` ${t?"\u5C06\u79FB\u9664":"\u5DF2\u79FB\u9664"}\uFF1A${r.removed.join("\u3001")}`),r.missing.length>0&&console.log(` \u5DF2\u4E0D\u5B58\u5728\uFF1A${r.missing.join("\u3001")}`),r.skippedForeign.length>0&&console.log(` \u26A0\uFE0F \u8DF3\u8FC7\uFF08\u975E\u672C\u5305\u4EA7\u7269\u6216\u5185\u5BB9\u5DF2\u88AB\u6539\u52A8\uFF0C\u8BF7\u4EBA\u5DE5\u786E\u8BA4\uFF09\uFF1A${r.skippedForeign.join("\u3001")}`);console.log(""),t?console.log("[\u9884\u6F14] \u672A\u6267\u884C\u5220\u9664\uFF1B\u65E0\u9057\u7559\u6761\u76EE\u65F6\u5C06\u540C\u65F6\u5220\u9664\u72B6\u6001\u6587\u4EF6"):e.stateRemoved?console.log("\u72B6\u6001\u6587\u4EF6\u5DF2\u5220\u9664\uFF0C\u672C\u5305\u4EA7\u7269\u6E05\u7406\u5B8C\u6BD5"):console.log("\u72B6\u6001\u6587\u4EF6\u5DF2\u4FDD\u7559\uFF08\u5B58\u5728\u9700\u4EBA\u5DE5\u786E\u8BA4\u6216\u672A\u79FB\u9664\u7684\u6761\u76EE\uFF09")}var yt=["archive","check","normalize","stats"],K=new Ge.Command,er="";K.name("toolkit").description(Kn).version(Zn,"-v, --version","\u663E\u793A\u7248\u672C\u53F7").enablePositionalOptions(!0).exitOverride().configureOutput({writeErr:e=>{er+=e}});K.addHelpText("after",["","\u6587\u6863\u7AD9\uFF1A",` \u65B0\u624B\u6307\u5357 ${fe.gettingStarted}`,` \u5B8C\u6574\u653B\u7565 ${fe.guide}`,` \u5168\u90E8\u6587\u6863 ${fe.site}`].join(`
package/dist/cli.js CHANGED
@@ -95,7 +95,7 @@ ${n.deps}`,n.deps);for(;;){let h=l.replace(/^- (.+)\n- \1$/gm,"- $1");if(h===l)b
95
95
  `:`
96
96
  `,o=n.endsWith(`
97
97
  `)||n===""?n:n+r;$(t,o+vn.replace(/\n/g,r).replace(/^\r?\n/,""))}function Sn(e){return JSON.stringify({schemaVersion:1,...e},null,2)}function V(e){return e&&e!=="json"?(console.error(`\u26A0\uFE0F \u4E0D\u652F\u6301\u7684\u8F93\u51FA\u683C\u5F0F\u300C${e}\u300D\uFF0C\u4EC5\u652F\u6301 json`),process.exitCode=1,!1):!0}import{cpSync as as,existsSync as M,lstatSync as An,mkdirSync as st,readdirSync as he,readFileSync as xn,readlinkSync as ls,rmSync as Cn,statSync as $n,symlinkSync as En}from"fs";import{dirname as J,isAbsolute as Ln,join as S,normalize as Fn,resolve as _e}from"path";import{fileURLToPath as cs}from"url";var Tn="@fxri/toolkit",it="SKILL.md",_=".agents/skills",In="canonical\uFF08\u591A\u5BB6 agent \u5171\u8BFB\uFF09",ds=".toolkit-skills.json",On=[{name:"aider-desk",label:"AiderDesk",dir:".aider-desk/skills"},{name:"amp",label:"Amp",dir:".config/agents/skills",detect:[".config/amp"]},{name:"antigravity",label:"Antigravity",dir:".gemini/antigravity/skills"},{name:"antigravity-cli",label:"Antigravity CLI",dir:".gemini/antigravity-cli/skills"},{name:"astrbot",label:"AstrBot",dir:".astrbot/data/skills",detect:[".astrbot"]},{name:"autohand-code",label:"Autohand Code CLI",dir:".autohand/skills"},{name:"augment",label:"Augment",dir:".augment/skills"},{name:"bob",label:"IBM Bob",dir:".bob/skills"},{name:"claude-code",label:"Claude Code",dir:".claude/skills"},{name:"openclaw",label:"OpenClaw",dir:".openclaw/skills",detect:[".openclaw",".clawdbot",".moltbot"]},{name:"cline",label:"Cline",dir:_,detect:[".cline"]},{name:"codearts-agent",label:"CodeArts Agent",dir:".codeartsdoer/skills"},{name:"codebuddy",label:"CodeBuddy",dir:".codebuddy/skills"},{name:"codemaker",label:"Codemaker",dir:".codemaker/skills"},{name:"codestudio",label:"Code Studio",dir:".codestudio/skills"},{name:"codex",label:"Codex",dir:".codex/skills",detect:[".codex","/etc/codex"]},{name:"command-code",label:"Command Code",dir:".commandcode/skills"},{name:"continue",label:"Continue",dir:".continue/skills"},{name:"cortex",label:"Cortex Code",dir:".snowflake/cortex/skills"},{name:"crush",label:"Crush",dir:".config/crush/skills"},{name:"cursor",label:"Cursor",dir:".cursor/skills"},{name:"deepagents",label:"Deep Agents",dir:".deepagents/agent/skills",detect:[".deepagents"]},{name:"devin",label:"Devin for Terminal",dir:".config/devin/skills"},{name:"dexto",label:"Dexto",dir:_,detect:[".dexto"]},{name:"droid",label:"Droid",dir:".factory/skills"},{name:"firebender",label:"Firebender",dir:".firebender/skills"},{name:"forgecode",label:"ForgeCode",dir:".forge/skills"},{name:"fx",label:"fx",dir:".fx/skills"},{name:"gemini-cli",label:"Gemini CLI",dir:".gemini/skills"},{name:"github-copilot",label:"GitHub Copilot",dir:".copilot/skills"},{name:"goose",label:"Goose",dir:".config/goose/skills"},{name:"grok",label:"Grok Build",dir:".grok/skills"},{name:"hermes-agent",label:"Hermes Agent",dir:".hermes/skills"},{name:"inference-sh",label:"inference.sh",dir:".inferencesh/skills"},{name:"jazz",label:"Jazz",dir:".jazz/skills"},{name:"junie",label:"Junie",dir:".junie/skills"},{name:"iflow-cli",label:"iFlow CLI",dir:".iflow/skills"},{name:"kilo",label:"Kilo Code",dir:".kilo/skills",detect:[".kilo",".kilocode"]},{name:"kimchi",label:"Kimchi",dir:".config/kimchi/harness/skills",detect:[".config/kimchi"]},{name:"kimi-code-cli",label:"Kimi Code CLI",dir:_,detect:[".kimi-code",".kimi"]},{name:"kiro-cli",label:"Kiro CLI",dir:".kiro/skills"},{name:"kode",label:"Kode",dir:".kode/skills"},{name:"lingma",label:"Lingma",dir:".lingma/skills"},{name:"loaf",label:"Loaf",dir:_,detect:[".loaf"]},{name:"mcpjam",label:"MCPJam",dir:".mcpjam/skills"},{name:"minimax-code",label:"MiniMax Code",dir:".minimax/skills",detect:[".minimax","/Applications/MiniMax Code.app"]},{name:"mistral-vibe",label:"Mistral Vibe",dir:".vibe/skills"},{name:"moxby",label:"Moxby",dir:".moxby/skills"},{name:"mux",label:"Mux",dir:".mux/skills"},{name:"opencode",label:"OpenCode",dir:".config/opencode/skills"},{name:"openhands",label:"OpenHands",dir:".openhands/skills"},{name:"ona",label:"Ona",dir:".ona/skills"},{name:"pi",label:"Pi",dir:".pi/agent/skills"},{name:"posit-assistant",label:"Posit Assistant",dir:".posit/assistant/skills",detect:[".posit/assistant",".positai"]},{name:"qoder",label:"Qoder",dir:".qoder/skills"},{name:"qoder-cn",label:"Qoder CN",dir:".qoder-cn/skills"},{name:"qwen-code",label:"Qwen Code",dir:".qwen/skills"},{name:"replit",label:"Replit",dir:".config/agents/skills"},{name:"reasonix",label:"Reasonix",dir:".reasonix/skills"},{name:"rovodev",label:"Rovo Dev",dir:".rovodev/skills"},{name:"roo",label:"Roo Code",dir:".roo/skills"},{name:"sarvam-code",label:"Sarvam Code",dir:_,detect:[".sarvam"]},{name:"tabnine-cli",label:"Tabnine CLI",dir:".tabnine/agent/skills",detect:[".tabnine"]},{name:"terramind",label:"Terramind",dir:".terramind/skills"},{name:"tinycloud",label:"Tinycloud",dir:".tinycloud/skills"},{name:"trae",label:"Trae",dir:".trae/skills"},{name:"trae-cn",label:"Trae CN",dir:".trae-cn/skills"},{name:"warp",label:"Warp",dir:_,detect:[".warp"]},{name:"windsurf",label:"Windsurf",dir:".codeium/windsurf/skills"},{name:"zed",label:"Zed",dir:_,detect:[".config/zed"]},{name:"zcode",label:"ZCode",dir:".zcode/skills",detect:[".zcode","/Applications/ZCode.app"]},{name:"zencoder",label:"Zencoder",dir:".zencoder/skills"},{name:"zenflow",label:"Zenflow",dir:".zencoder/skills"},{name:"neovate",label:"Neovate",dir:".neovate/skills"},{name:"pochi",label:"Pochi",dir:".pochi/skills"},{name:"adal",label:"AdaL",dir:".adal/skills"},{name:"universal",label:"Universal",dir:".config/agents/skills"}],ot;function jn(){if(ot)return ot;let e=J(cs(import.meta.url));for(;;){let t=S(e,"package.json");if(M(t))try{if(JSON.parse(T(t)).name===Tn)return ot=e,e}catch{}let n=J(e);if(n===e)break;e=n}throw new Error(`\u672A\u80FD\u4ECE\u6A21\u5757\u4F4D\u7F6E\u5411\u4E0A\u5B9A\u4F4D ${Tn} \u7684\u5305\u6839\u76EE\u5F55`)}function Y(){return S(jn(),"skills")}function at(){return jn()}function us(e){try{let n=T(S(e,it)).match(/^---\r?\n([\s\S]*?)\r?\n---/);if(!n)return"";let r=(n[1]??"").match(/^[ \t]+version:[ \t]*"?([^"\r\n]+?)"?[ \t]*$/m);return r?(r[1]??"").trim():""}catch{return""}}function fs(e){try{let n=T(S(e,it)).match(/^>[ \t]*本技能版本[ \t]*([^ \t((]+)/m);return n?(n[1]??"").trim():""}catch{return""}}function ms(e){let t=[];for(let n of e){if(!n.version)continue;let r=fs(n.dir);r!==n.version&&t.push({name:n.name,frontmatter:n.version,body:r})}return t}function ke(){let e=Y();if(!M(e))return[];let t=[];for(let n of he(e).sort()){let r=S(e,n);try{if(!An(r).isDirectory())continue}catch{continue}M(S(r,it))&&t.push({name:n,dir:r,version:us(r)})}return t}function I(e){let t=Fn(_e(e));return process.platform==="win32"?t.toLowerCase():t}function ps(e){let t=Fn(e);return/^[a-zA-Z]:[\\/]$/.test(t)?t:t.replace(/[\\/]+$/,"")||t}function De(e,t,n,r=!1){let o;if(n)o=n;else try{o=An(e)}catch{return"absent"}if(o.isSymbolicLink()){let s="";try{s=ls(e)}catch{return"dangling"}let i=ps(Ln(s)?s:_e(J(e),s));return I(i)!==I(t)?"wrong":r||M(e)?"link-ok":"dangling"}return o.isDirectory()?"dir":"file"}function Ne(e,t){let n,r;try{n=he(e).sort(),r=he(t).sort()}catch{return!1}if(n.length!==r.length||n.some((o,s)=>o!==r[s]))return!1;for(let o of n){let s=S(e,o),i=S(t,o),a,l;try{a=$n(s),l=$n(i)}catch{return!1}if(a.isDirectory()!==l.isDirectory())return!1;if(a.isDirectory()){if(!Ne(s,i))return!1}else try{if(!xn(s).equals(xn(i)))return!1}catch{return!1}}return!0}function be(){return S(q(),".agents",ds)}function Be(){let e=be();if(!M(e))return null;try{let t=JSON.parse(T(e));return!t||!Array.isArray(t.targets)?null:t}catch{return null}}function Mn(e){let t=be();st(J(t),{recursive:!0});let n={version:1,updatedAt:new Date().toISOString(),targets:e};$(t,`${JSON.stringify(n,null,2)}
98
- `)}function _n(e=[]){let t=q(),n=[],r=new Set,o=(s,i,a,l)=>{let d=_e(s),u=I(d);r.has(u)||(r.add(u),n.push({dir:d,label:i,kind:a,available:l,dirExists:M(d)}))};o(S(t,_),In,"primary",!0);for(let s of On){let i=S(t,J(s.dir)),a=M(i)||(s.detect??[]).some(l=>M(Ln(l)?l:S(t,l)));o(S(t,s.dir),s.label,"agent",a)}for(let s of e)o(s,"\u81EA\u5B9A\u4E49 --dir","custom",!0);return n}function gs(e){let t=I(_e(e));return t===I(S(q(),_))?In:On.find(r=>I(S(q(),r.dir))===t)?.label??null}function lt(e){Cn(e,{recursive:!0,force:!0})}function Rn(e,t){st(J(t),{recursive:!0}),as(e,t,{recursive:!0})}function hs(e,t,n){if(n)return Rn(e,t),{mode:"copy"};try{return st(J(t),{recursive:!0}),En(e,t,process.platform==="win32"?"junction":"dir"),{mode:"link"}}catch(r){return Rn(e,t),{mode:"copy",reason:r.message}}}function Dn(e={}){let t=ke(),n=_n(e.dirs??[]),r=Be(),o=new Map;for(let l of r?.targets??[])o.set(I(l.dir),l);let s=[],i=[],a=[];for(let l of n){if(!l.available){i.push({dir:l.dir,label:l.label});continue}let d={dir:l.dir,label:l.label,kind:l.kind,created:[],updated:[],skipped:[],conflicts:[],failed:[],degraded:[],links:[],copies:[]};for(let u of t){let m=S(l.dir,u.name),p=De(m,u.dir);if(p==="link-ok"){d.skipped.push(u.name),d.links.push(u.name);continue}if(p==="dir"&&!e.force){if(!(o.get(I(l.dir))?.copies.includes(u.name)??!1)){d.conflicts.push(u.name);continue}if(Ne(u.dir,m)){d.skipped.push(u.name),d.copies.push(u.name);continue}}if(p==="file"&&!e.force){d.conflicts.push(u.name);continue}if(e.dryRun){p==="absent"?d.created.push(u.name):d.updated.push(u.name),e.copy?d.copies.push(u.name):d.links.push(u.name);continue}try{p!=="absent"&&lt(m);let c=hs(u.dir,m,!!e.copy);p==="absent"?d.created.push(u.name):d.updated.push(u.name),c.mode==="link"?d.links.push(u.name):(d.copies.push(u.name),c.reason&&d.degraded.push({name:u.name,reason:c.reason}))}catch(c){d.failed.push({name:u.name,reason:c.message})}}s.push(d),e.dryRun||a.push({dir:l.dir,updatedAt:new Date().toISOString(),links:d.links,copies:d.copies})}if(!e.dryRun){let l=new Set(s.map(m=>I(m.dir))),d=(r?.targets??[]).filter(m=>!l.has(I(m.dir))),u=[...a,...d].filter(m=>m.links.length>0||m.copies.length>0);u.length>0&&Mn(u)}return{source:Y(),skills:t.map(l=>l.name),targets:s,skippedTargets:i,stateFile:be()}}function Nn(e={}){let t=Be(),n=be();if(!t)return{stateFile:n,stateExists:!1,targets:[],stateRemoved:!1};let r=[],o=!1;for(let a of t.targets){let l={dir:a.dir,label:gs(a.dir),removed:[],missing:[],skippedForeign:[]},d=[...new Set([...a.links,...a.copies])];for(let u of d){let m=S(a.dir,u),p=S(Y(),u),c=De(m,p);if(c==="absent"){l.missing.push(u);continue}if(c==="wrong"){l.skippedForeign.push(u);continue}if(c==="file"){l.skippedForeign.push(u);continue}if(c==="dir"&&!Ne(p,m)){l.skippedForeign.push(u);continue}if(e.dryRun){l.removed.push(u);continue}try{lt(m),l.removed.push(u)}catch{o=!0,l.skippedForeign.push(u)}}r.push(l)}let s=r.every(a=>a.skippedForeign.length===0),i=!e.dryRun&&!o&&s;return i&&Cn(n,{force:!0}),{stateFile:n,stateExists:!0,targets:r,stateRemoved:i}}function Bn(){let e=ke(),t=_n([]),n=Be(),r=new Map;for(let i of n?.targets??[])r.set(I(i.dir),i);let o=[],s=[];for(let i of t){let a=r.get(I(i.dir));if(!i.available&&i.kind==="agent"){s.push({dir:i.dir,label:i.label});continue}if(i.kind!=="primary"&&!i.dirExists&&!a)continue;let l=[...new Set([...e.map(m=>m.name),...a?[...a.links,...a.copies]:[]])].sort(),d=new Map(e.map(m=>[m.name,m.version])),u=[];for(let m of l){let p=S(Y(),m),c=S(i.dir,m),f=De(c,p),g;f==="link-ok"?g="link":f==="dangling"?g="dangling":f==="wrong"?g="wrong":f==="file"?g="conflict":f==="dir"?M(p)&&Ne(p,c)?g="copy":g=a?.copies.includes(m)?"copy-drift":"conflict":g="missing",u.push({name:m,state:g,version:d.get(m)??""})}o.push({dir:i.dir,label:i.label,kind:i.kind,available:i.available,dirExists:i.dirExists,recorded:!!a,items:u})}return{source:Y(),skills:e.map(i=>i.name),skillVersions:Object.fromEntries(e.map(i=>[i.name,i.version])),versionMismatches:ms(e),stateFile:be(),stateExists:!!n,targets:o,pendingAgents:s}}function Pn(){let e=L("skills");if(e?.autoLink===!1||process.env.CI)return 0;let t=Be();if(!t)return 0;let n=Y(),r;try{r=new Set(he(n).filter(l=>M(S(n,l))))}catch{return 0}let o=e?.autoLinkReplaceForeign!==!1,s=process.platform==="win32"?"junction":"dir",i=0,a=[];for(let l of t.targets){let d;try{d=he(l.dir,{withFileTypes:!0})}catch{a.push(l);continue}let u=new Map(d.map(p=>[p.name,p])),m=l.links.filter(p=>{if(!r.has(p))return!1;let c=S(n,p),f=S(l.dir,p),g=u.get(p),h=g?De(f,c,g,!0):"absent";if(h==="link-ok"||!o&&(h==="dir"||h==="file"))return!0;try{return h!=="absent"&&lt(f),En(c,f,s),i+=1,!0}catch{return!0}});a.push({...l,links:m,updatedAt:new Date().toISOString()})}return i>0&&Mn(a),i}import{existsSync as bs,mkdirSync as ys,rmSync as vs}from"fs";import{join as ws}from"path";import{tmpdir as Yn}from"os";import{spawn as Ss}from"child_process";var ks="https://registry.npmjs.org/@fxri%2Ftoolkit/latest";async function Un(){try{let e=await fetch(ks,{signal:AbortSignal.timeout(1e3),headers:{accept:"application/vnd.npm.install-v1+json"}});if(!e.ok)return null;let t=await e.json();return typeof t.version=="string"?t.version:null}catch{return null}}function zn(e,t){let n=i=>i.trim().replace(/^-/,"").split(/[.+-]/).map(a=>Number.parseInt(a,10)).map(a=>Number.isFinite(a)?a:0),r=n(e),o=n(t),s=Math.max(r.length,o.length);for(let i=0;i<s;i++){let a=r[i]??0,l=o[i]??0;if(a!==l)return a>l}return!1}var xs=1440*60*1e3,$s=3600*1e3,Ts="FX_NO_UPDATE_CHECK",ct="--fxri-update-check-worker";function Wn(){return ws(Yn(),".toolkit-update-check.json")}function Rs(){let e=Wn();try{if(!bs(e))return null;let t=JSON.parse(T(e)),n=typeof t.ts=="number"?t.ts:0,r=typeof t.latest=="string"?t.latest:"",o=t.ok===!0,s=o?xs:$s;return Date.now()-n>=s?(vs(e,{force:!0}),null):o&&!r?null:{ts:n,ok:o,latest:r}}catch{return null}}function As(e,t){try{let n=Wn();ys(Yn(),{recursive:!0}),$(n,JSON.stringify({ts:Date.now(),ok:e,latest:t}))}catch{}}function Cs(){let e=process.env[Ts];if(e!==void 0&&e!=="")return!["0","false","off","no"].includes(e.trim().toLowerCase());let t=Ye()?.updateCheck;return t&&typeof t=="object"?t.enabled===!1:!1}function Kn(e){if(Cs())return;let t=Rs();if(t){t.ok&&zn(t.latest,e)&&Ls(t.latest,e);return}Es()}function Es(){let e=process.argv[1];if(e)try{Ss(process.execPath,[e,ct],{detached:!0,stdio:"ignore",windowsHide:!0}).unref()}catch{}}async function Hn(){let e=await Un().catch(()=>null);As(e!==null,e??"")}function Ls(e,t){console.error(`\u2B06\uFE0F \u53D1\u73B0\u65B0\u7248\u672C ${e}\uFF08\u5F53\u524D ${t}\uFF09\uFF1Apnpm add -g @fxri/toolkit \u5347\u7EA7\u540E\u8BF7\u5F00\u65B0\u4F1A\u8BDD\u52A0\u8F7D\u6700\u65B0 skills \u89C4\u5219\uFF1B\u672C\u5730\u6280\u80FD\u53EF\u7528 toolkit skills status \u68C0\u67E5\uFF08\u8F6F\u94FE\u81EA\u52A8\u8DDF\u968F\uFF0C\u526F\u672C\u5F62\u5F0F\u9700\u91CD\u8DD1 toolkit skills install\uFF09`)}var Fs="\u663E\u793A\u5E2E\u52A9",Is=["version","format"];function dt(e){e.helpOption("-h, --help",Fs),e.configureHelp({subcommandTerm:t=>`${t.name()} ${t.usage()}`.replace(/\s+/g," ").trim()});for(let t of e.commands)dt(t)}function Gn(e){return Is.includes(e[0])?e.slice(1).some(t=>t==="-h"||t==="--help"):!1}var ut="\u8FD0\u884C toolkit --help \u67E5\u770B\u53EF\u7528\u547D\u4EE4";function Vn(e){let t=/\n\(Did you mean (one of )?([^)]*?)\?\)$/.exec(e);if(!t)return"";let n=t[2].split(", ").join("\u3001");return t[1]?`\uFF08\u662F\u5426\u60F3\u8F93\u5165 ${n} \u4E4B\u4E00\uFF1F\uFF09`:`\uFF08\u662F\u5426\u60F3\u8F93\u5165 ${n}\uFF1F\uFF09`}function Jn(e){switch(e.code){case"commander.unknownCommand":{let t=/unknown command '([^']*)'/.exec(e.message)?.[1];return t?`\u26A0\uFE0F \u672A\u77E5\u547D\u4EE4\u300C${t}\u300D\u3002${Vn(e.message)}
98
+ `)}function _n(e=[]){let t=q(),n=[],r=new Set,o=(s,i,a,l)=>{let d=_e(s),u=I(d);r.has(u)||(r.add(u),n.push({dir:d,label:i,kind:a,available:l,dirExists:M(d)}))};o(S(t,_),In,"primary",!0);for(let s of On){let i=S(t,J(s.dir)),a=M(i)||(s.detect??[]).some(l=>M(Ln(l)?l:S(t,l)));o(S(t,s.dir),s.label,"agent",a)}for(let s of e)o(s,"\u81EA\u5B9A\u4E49 --dir","custom",!0);return n}function gs(e){let t=I(_e(e));return t===I(S(q(),_))?In:On.find(r=>I(S(q(),r.dir))===t)?.label??null}function lt(e){Cn(e,{recursive:!0,force:!0})}function Rn(e,t){st(J(t),{recursive:!0}),as(e,t,{recursive:!0})}function hs(e,t,n){if(n)return Rn(e,t),{mode:"copy"};try{return st(J(t),{recursive:!0}),En(e,t,process.platform==="win32"?"junction":"dir"),{mode:"link"}}catch(r){return Rn(e,t),{mode:"copy",reason:r.message}}}function Dn(e={}){let t=ke(),n=_n(e.dirs??[]),r=Be(),o=new Map;for(let l of r?.targets??[])o.set(I(l.dir),l);let s=[],i=[],a=[];for(let l of n){if(!l.available){i.push({dir:l.dir,label:l.label});continue}let d={dir:l.dir,label:l.label,kind:l.kind,created:[],updated:[],skipped:[],conflicts:[],failed:[],degraded:[],links:[],copies:[]};for(let u of t){let m=S(l.dir,u.name),p=De(m,u.dir);if(p==="link-ok"){d.skipped.push(u.name),d.links.push(u.name);continue}if(p==="dir"&&!e.force){if(!(o.get(I(l.dir))?.copies.includes(u.name)??!1)){d.conflicts.push(u.name);continue}if(Ne(u.dir,m)){d.skipped.push(u.name),d.copies.push(u.name);continue}}if(p==="file"&&!e.force){d.conflicts.push(u.name);continue}if(e.dryRun){p==="absent"?d.created.push(u.name):d.updated.push(u.name),e.copy?d.copies.push(u.name):d.links.push(u.name);continue}try{p!=="absent"&&lt(m);let c=hs(u.dir,m,!!e.copy);p==="absent"?d.created.push(u.name):d.updated.push(u.name),c.mode==="link"?d.links.push(u.name):(d.copies.push(u.name),c.reason&&d.degraded.push({name:u.name,reason:c.reason}))}catch(c){d.failed.push({name:u.name,reason:c.message})}}s.push(d),e.dryRun||a.push({dir:l.dir,updatedAt:new Date().toISOString(),links:d.links,copies:d.copies})}if(!e.dryRun){let l=new Set(s.map(m=>I(m.dir))),d=(r?.targets??[]).filter(m=>!l.has(I(m.dir))),u=[...a,...d].filter(m=>m.links.length>0||m.copies.length>0);u.length>0&&Mn(u)}return{source:Y(),skills:t.map(l=>l.name),targets:s,skippedTargets:i,stateFile:be()}}function Nn(e={}){let t=Be(),n=be();if(!t)return{stateFile:n,stateExists:!1,targets:[],stateRemoved:!1};let r=[],o=!1;for(let a of t.targets){let l={dir:a.dir,label:gs(a.dir),removed:[],missing:[],skippedForeign:[]},d=[...new Set([...a.links,...a.copies])];for(let u of d){let m=S(a.dir,u),p=S(Y(),u),c=De(m,p);if(c==="absent"){l.missing.push(u);continue}if(c==="wrong"){l.skippedForeign.push(u);continue}if(c==="file"){l.skippedForeign.push(u);continue}if(c==="dir"&&!Ne(p,m)){l.skippedForeign.push(u);continue}if(e.dryRun){l.removed.push(u);continue}try{lt(m),l.removed.push(u)}catch{o=!0,l.skippedForeign.push(u)}}r.push(l)}let s=r.every(a=>a.skippedForeign.length===0),i=!e.dryRun&&!o&&s;return i&&Cn(n,{force:!0}),{stateFile:n,stateExists:!0,targets:r,stateRemoved:i}}function Bn(){let e=ke(),t=_n([]),n=Be(),r=new Map;for(let i of n?.targets??[])r.set(I(i.dir),i);let o=[],s=[];for(let i of t){let a=r.get(I(i.dir));if(!i.available&&i.kind==="agent"){s.push({dir:i.dir,label:i.label});continue}if(i.kind!=="primary"&&!i.dirExists&&!a)continue;let l=[...new Set([...e.map(m=>m.name),...a?[...a.links,...a.copies]:[]])].sort(),d=new Map(e.map(m=>[m.name,m.version])),u=[];for(let m of l){let p=S(Y(),m),c=S(i.dir,m),f=De(c,p),g;f==="link-ok"?g="link":f==="dangling"?g="dangling":f==="wrong"?g="wrong":f==="file"?g="conflict":f==="dir"?M(p)&&Ne(p,c)?g="copy":g=a?.copies.includes(m)?"copy-drift":"conflict":g="missing",u.push({name:m,state:g,version:d.get(m)??""})}o.push({dir:i.dir,label:i.label,kind:i.kind,available:i.available,dirExists:i.dirExists,recorded:!!a,items:u})}return{source:Y(),skills:e.map(i=>i.name),skillVersions:Object.fromEntries(e.map(i=>[i.name,i.version])),versionMismatches:ms(e),stateFile:be(),stateExists:!!n,targets:o,pendingAgents:s}}function Pn(){let e=L("skills");if(e?.autoLink===!1||process.env.CI)return 0;let t=Be();if(!t)return 0;let n=Y(),r;try{r=new Set(he(n).filter(l=>M(S(n,l))))}catch{return 0}let o=e?.autoLinkReplaceForeign!==!1,s=process.platform==="win32"?"junction":"dir",i=0,a=[];for(let l of t.targets){let d;try{d=he(l.dir,{withFileTypes:!0})}catch{a.push(l);continue}let u=new Map(d.map(p=>[p.name,p])),m=l.links.filter(p=>{if(!r.has(p))return!1;let c=S(n,p),f=S(l.dir,p),g=u.get(p),h=g?De(f,c,g,!0):"absent";if(h==="link-ok"||!o&&(h==="dir"||h==="file"))return!0;try{return h!=="absent"&&lt(f),En(c,f,s),i+=1,!0}catch{return!0}});a.push({...l,links:m,updatedAt:new Date().toISOString()})}return i>0&&Mn(a),i}import{existsSync as bs,mkdirSync as ys,rmSync as vs}from"fs";import{join as ws}from"path";import{tmpdir as Yn}from"os";import{spawn as Ss}from"child_process";var ks="https://registry.npmjs.org/@fxri%2Ftoolkit/latest";async function Un(){try{let e=await fetch(ks,{signal:AbortSignal.timeout(1e3),headers:{accept:"application/vnd.npm.install-v1+json"}});if(!e.ok)return null;let t=await e.json();return typeof t.version=="string"?t.version:null}catch{return null}}function zn(e,t){let n=i=>i.trim().replace(/^-/,"").split(/[.+-]/).map(a=>Number.parseInt(a,10)).map(a=>Number.isFinite(a)?a:0),r=n(e),o=n(t),s=Math.max(r.length,o.length);for(let i=0;i<s;i++){let a=r[i]??0,l=o[i]??0;if(a!==l)return a>l}return!1}var xs=1440*60*1e3,$s=3600*1e3,Ts="FX_NO_UPDATE_CHECK",ct="--fxri-update-check-worker";function Wn(){return ws(Yn(),".toolkit-update-check.json")}function Rs(){let e=Wn();try{if(!bs(e))return null;let t=JSON.parse(T(e)),n=typeof t.ts=="number"?t.ts:0,r=typeof t.latest=="string"?t.latest:"",o=t.ok===!0,s=o?xs:$s;return Date.now()-n>=s?(vs(e,{force:!0}),null):o&&!r?null:{ts:n,ok:o,latest:r}}catch{return null}}function As(e,t){try{let n=Wn();ys(Yn(),{recursive:!0}),$(n,JSON.stringify({ts:Date.now(),ok:e,latest:t}))}catch{}}function Cs(){let e=process.env[Ts];if(e!==void 0&&e!=="")return!["0","false","off","no"].includes(e.trim().toLowerCase());let t=Ye()?.updateCheck;return t&&typeof t=="object"?t.enabled===!1:!1}function Kn(e){if(Cs())return;let t=Rs();if(t){t.ok&&zn(t.latest,e)&&Ls(t.latest,e);return}Es()}function Es(){let e=process.argv[1];if(e)try{Ss(process.execPath,[e,ct],{detached:!0,stdio:"ignore",windowsHide:!0}).unref()}catch{}}async function Hn(){let e=await Un().catch(()=>null);As(e!==null,e??"")}function Ls(e,t){console.error(`\u2B06\uFE0F \u53D1\u73B0\u65B0\u7248\u672C ${e}\uFF08\u5F53\u524D ${t}\uFF09\uFF1Apnpm add -g @fxri/toolkit \u5347\u7EA7\u540E\u8BF7\u5F00\u65B0\u4F1A\u8BDD\u52A0\u8F7D\u6700\u65B0 skills \u89C4\u5219\uFF1B\u672C\u5730\u6280\u80FD\u53EF\u7528 toolkit skills status \u68C0\u67E5\uFF08\u8F6F\u94FE\u81EA\u52A8\u8DDF\u968F\uFF0C\u526F\u672C\u5F62\u5F0F\u9700\u91CD\u8DD1 toolkit skills install\uFF09`)}var Fs="\u663E\u793A\u5E2E\u52A9",Is=["version","format"];function dt(e){e.helpOption("-h, --help",Fs),e.configureHelp({subcommandTerm:t=>`${t.name()} ${t.usage()}`.replace(/\s+/g," ").trim()});for(let t of e.commands)dt(t)}function Gn(e){let[t]=e;return!t||!Is.includes(t)?!1:e.slice(1).some(n=>n==="-h"||n==="--help")}var ut="\u8FD0\u884C toolkit --help \u67E5\u770B\u53EF\u7528\u547D\u4EE4";function Vn(e){let t=/\n\(Did you mean (one of )?([^)]*?)\?\)$/.exec(e);if(!t)return"";let n=(t[2]??"").split(", ").join("\u3001");return t[1]?`\uFF08\u662F\u5426\u60F3\u8F93\u5165 ${n} \u4E4B\u4E00\uFF1F\uFF09`:`\uFF08\u662F\u5426\u60F3\u8F93\u5165 ${n}\uFF1F\uFF09`}function Jn(e){switch(e.code){case"commander.unknownCommand":{let t=/unknown command '([^']*)'/.exec(e.message)?.[1];return t?`\u26A0\uFE0F \u672A\u77E5\u547D\u4EE4\u300C${t}\u300D\u3002${Vn(e.message)}
99
99
  ${ut}`:null}case"commander.unknownOption":{let t=/unknown option '([^']*)'/.exec(e.message)?.[1];return t?`\u26A0\uFE0F \u672A\u77E5\u9009\u9879\u300C${t}\u300D\u3002${Vn(e.message)}
100
100
  ${ut}`:null}case"commander.excessArguments":{let t=/too many arguments(?: for '([^']*)')?\. Expected (\d+) arguments? but got (\d+)\./.exec(e.message);return t?`\u26A0\uFE0F ${t[1]?`\u547D\u4EE4\u300C${t[1]}\u300D`:"\u547D\u4EE4"}\u671F\u671B ${t[2]} \u4E2A\u53C2\u6570\uFF0C\u5B9E\u9645\u6536\u5230 ${t[3]} \u4E2A\u3002
101
101
  ${ut}`:null}default:return null}}var qn="\u4E13\u4E3A\u591A\u4EBA + AI \u8DE8\u9879\u76EE\u534F\u4F5C\u6253\u9020\uFF1A\u4EFB\u52A1\u7BA1\u7406 + \u591A\u8BED\u8A00 CHANGELOG\u3002";var Qn=Ms(import.meta.url),Bs=Qn.resolve("@changesets/cli/bin.js"),{version:er}=Qn("../package.json"),ft=e=>{let t=_s(process.execPath,[Bs,...e],{stdio:"inherit"});t.status!==0&&process.exit(t.status??1)};function Ps(){if(process.platform==="win32")try{process.stdout.setDefaultEncoding("utf8"),process.stderr.setDefaultEncoding("utf8")}catch{}}function tr(){let e=L("check");return typeof e?.warnings=="boolean"?e.warnings:void 0}function Us(){let t=L("changelog")?.languages;if(!t||typeof t!="object")return oe;let n={...oe};for(let[r,o]of Object.entries(t))o&&typeof o=="object"&&(n[r]=o);return n}function zs(e=".changeset"){if(!Xn(e))return!1;try{return Ds(e).some(t=>t.endsWith(".md")&&t!=="README.md")}catch{return!1}}function Ys(e=".tasks"){return C(Ns(e,"active")).length>0}function Zn(e){let t=fn(".",e);t>0&&console.warn(`\u26A0\uFE0F ${t} \u6761\u53D8\u66F4\u96C6\u6761\u76EE\u7F3A\u7C7B\u578B\u524D\u7F00\uFF0C\u5EFA\u8BAE\u6309\u300C\u7C7B\u578B\uFF1A\u63CF\u8FF0\u300D\u64B0\u5199`)}function Pe(e){if(e.length===0){console.log("\u672A\u53D1\u73B0\u95EE\u9898");return}for(let t of e)console.log(` ${t.file}${t.line?`:${t.line}`:""}: ${t.message}`)}function Ws(e,t){return[...t,e]}var Ks={link:"\u8F6F\u94FE\u6B63\u5E38",dangling:"\u8F6F\u94FE\u60AC\u7A7A\uFF08\u771F\u6E90\u7F3A\u5931\u6216\u5347\u7EA7\u540E\u65E7\u8DEF\u5F84\u5931\u6548\uFF09",wrong:"\u8F6F\u94FE\u6307\u5411\u522B\u5904",copy:"\u526F\u672C\u5DF2\u540C\u6B65","copy-drift":"\u526F\u672C\u5DF2\u6F02\u79FB\uFF08\u4E0E\u771F\u6E90\u4E0D\u4E00\u81F4\uFF09",missing:"\u7F3A\u5931",conflict:"\u540C\u540D\u51B2\u7A81\uFF08\u975E\u672C\u5305\u4EA7\u7269\uFF09"},Hs=["dangling","wrong","copy-drift","missing","conflict"];function ye(e){console.log(Sn(e))}function nr(e,t){return t?`${e}@${t}`:e}function Gs(e,t){let n=t?"[\u9884\u6F14] ":"",r=new Map(ke().map(o=>[o.name,o.version]));console.log(`${n}\u6280\u80FD\u6E90\uFF1A${e.source}`),console.log(`${n}\u5305\u5185\u6280\u80FD\uFF08${e.skills.length}\uFF09\uFF1A${e.skills.map(o=>nr(o,r.get(o)??"")).join("\u3001")||"\u65E0"}`);for(let o of e.targets){console.log(""),console.log(`${o.label}\uFF1A${o.dir}`),o.created.length>0&&console.log(` \u65B0\u5EFA\uFF1A${o.created.join("\u3001")}`),o.updated.length>0&&console.log(` \u91CD\u5EFA/\u66F4\u65B0\uFF1A${o.updated.join("\u3001")}`),o.skipped.length>0&&console.log(` \u8DF3\u8FC7\uFF08\u5DF2\u5C31\u7EEA\uFF09\uFF1A${o.skipped.join("\u3001")}`),o.conflicts.length>0&&console.log(` \u8DF3\u8FC7\uFF08\u540C\u540D\u975E\u672C\u5305\u4EA7\u7269\uFF0C\u5982\u9700\u8986\u76D6\u52A0 --force\uFF09\uFF1A${o.conflicts.join("\u3001")}`);for(let i of o.degraded)console.log(` \u26A0\uFE0F \u964D\u7EA7\u4E3A\u526F\u672C\uFF1A${i.name}\uFF08\u94FE\u63A5\u521B\u5EFA\u5931\u8D25\uFF1A${i.reason}\uFF09`);for(let i of o.failed)console.log(` \u26A0\uFE0F \u5931\u8D25\uFF1A${i.name}\uFF08${i.reason}\uFF09`);let s=[];o.links.length>0&&s.push(`\u8F6F\u94FE ${o.links.length} \u4E2A`),o.copies.length>0&&s.push(`\u526F\u672C ${o.copies.length} \u4E2A`),s.length>0&&console.log(` \u4EA7\u7269\u5F62\u6001\uFF1A${s.join(" / ")}`)}console.log(""),e.skippedTargets.length>0&&console.log(`\u672A\u5B89\u88C5\u7684 agent ${e.skippedTargets.length} \u4E2A\u5DF2\u8DF3\u8FC7\uFF08\u4E0D\u5728\u7528\u6237\u673A\u5668\u4E0A\u51ED\u7A7A\u9020\u76EE\u5F55\uFF09\uFF1B\u5982\u9700\u88C5\u5230\u672A\u8BC6\u522B\u7684 agent\uFF1Atoolkit skills install --dir <\u5176\u5168\u5C40\u6280\u80FD\u76EE\u5F55>`),console.log(`${n}\u72B6\u6001\u6587\u4EF6\uFF1A${e.stateFile}`),t&&console.log("[\u9884\u6F14] \u672A\u5199\u5165\u4EFB\u4F55\u6587\u4EF6\uFF1B\u786E\u8BA4\u65E0\u8BEF\u540E\u53BB\u6389 --dry-run \u6267\u884C")}function Vs(e){console.log(`\u6280\u80FD\u6E90\uFF1A${e.source}`),console.log(`\u6280\u80FD\u7248\u672C\uFF1A${e.skills.map(n=>nr(n,e.skillVersions[n]??"")).join("\u3001")||"\u65E0"}`);for(let n of e.versionMismatches)console.warn(`\u26A0\uFE0F \u6280\u80FD\u7248\u672C\u53CC\u5199\u4F4D\u4E0D\u4E00\u81F4\uFF1A${n.name}\uFF08frontmatter ${n.frontmatter} / \u6B63\u6587 ${n.body||"\u672A\u58F0\u660E"}\uFF09`);console.log(`\u72B6\u6001\u6587\u4EF6\uFF1A${e.stateFile}${e.stateExists?"":"\uFF08\u672A\u8BB0\u5F55\uFF0C\u5C1A\u672A\u6267\u884C\u8FC7 toolkit skills install\uFF09"}`);let t=0;for(let n of e.targets){console.log(""),console.log(`${n.label}\uFF1A${n.dir}${n.dirExists?"":"\uFF08\u76EE\u5F55\u672A\u521B\u5EFA\uFF09"}`);for(let r of n.items)Hs.includes(r.state)&&(t+=1),console.log(` ${r.name}\uFF1A${Ks[r.state]}`)}e.pendingAgents.length>0&&(console.log(""),console.log(`\u672A\u5B89\u88C5\u7684 agent ${e.pendingAgents.length} \u4E2A\u672A\u7EB3\u5165\u5206\u53D1\uFF08\u9700\u8981\u65F6\u7528 toolkit skills install --dir <\u8DEF\u5F84> \u6307\u5B9A\uFF09`)),console.log(""),console.log(t>0?`\u5171 ${t} \u5904\u9700\u5904\u7406\uFF1A\u7F3A\u5931 / \u60AC\u7A7A / \u6307\u5411\u9519\u8BEF / \u526F\u672C\u6F02\u79FB\u7528 toolkit skills install \u8865\u9F50\uFF0C\u540C\u540D\u51B2\u7A81\u7528 toolkit skills install --force \u8986\u76D6`:"\u6240\u6709\u5DF2\u7EB3\u5165\u7684\u76EE\u6807\u5747\u6B63\u5E38")}function Js(e,t){let n=t?"[\u9884\u6F14] ":"";if(!e.stateExists){console.log("\u672A\u627E\u5230\u672C\u5305\u7684\u72B6\u6001\u6587\u4EF6\uFF0C\u6CA1\u6709\u7531\u672C\u5305\u5B89\u88C5\u7684\u4EA7\u7269\u9700\u8981\u6E05\u7406\uFF08\u5176\u4ED6\u65B9\u5F0F\u5B89\u88C5\u7684\u6280\u80FD\u4E0D\u53D7\u5F71\u54CD\uFF09");return}console.log(`${n}\u72B6\u6001\u6587\u4EF6\uFF1A${e.stateFile}`);for(let r of e.targets)console.log(""),console.log(r.label?`${r.label}\uFF1A${r.dir}`:r.dir),r.removed.length>0&&console.log(` ${t?"\u5C06\u79FB\u9664":"\u5DF2\u79FB\u9664"}\uFF1A${r.removed.join("\u3001")}`),r.missing.length>0&&console.log(` \u5DF2\u4E0D\u5B58\u5728\uFF1A${r.missing.join("\u3001")}`),r.skippedForeign.length>0&&console.log(` \u26A0\uFE0F \u8DF3\u8FC7\uFF08\u975E\u672C\u5305\u4EA7\u7269\u6216\u5185\u5BB9\u5DF2\u88AB\u6539\u52A8\uFF0C\u8BF7\u4EBA\u5DE5\u786E\u8BA4\uFF09\uFF1A${r.skippedForeign.join("\u3001")}`);console.log(""),t?console.log("[\u9884\u6F14] \u672A\u6267\u884C\u5220\u9664\uFF1B\u65E0\u9057\u7559\u6761\u76EE\u65F6\u5C06\u540C\u65F6\u5220\u9664\u72B6\u6001\u6587\u4EF6"):e.stateRemoved?console.log("\u72B6\u6001\u6587\u4EF6\u5DF2\u5220\u9664\uFF0C\u672C\u5305\u4EA7\u7269\u6E05\u7406\u5B8C\u6BD5"):console.log("\u72B6\u6001\u6587\u4EF6\u5DF2\u4FDD\u7559\uFF08\u5B58\u5728\u9700\u4EBA\u5DE5\u786E\u8BA4\u6216\u672A\u79FB\u9664\u7684\u6761\u76EE\uFF09")}var mt=["archive","check","normalize","stats"],D=new Os,rr="";D.name("toolkit").description(qn).version(er,"-v, --version","\u663E\u793A\u7248\u672C\u53F7").enablePositionalOptions(!0).exitOverride().configureOutput({writeErr:e=>{rr+=e}});D.addHelpText("after",["","\u6587\u6863\u7AD9\uFF1A",` \u65B0\u624B\u6307\u5357 ${ie.gettingStarted}`,` \u5B8C\u6574\u653B\u7565 ${ie.guide}`,` \u5168\u90E8\u6587\u6863 ${ie.site}`].join(`
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fxri/toolkit",
3
- "version": "1.10.0",
3
+ "version": "1.10.2",
4
4
  "description": "专为多人 + AI 跨项目协作打造:任务管理 + 多语言 CHANGELOG。",
5
5
  "license": "MIT",
6
6
  "author": {
@@ -82,6 +82,7 @@
82
82
  "test": "vitest run",
83
83
  "test:watch": "vitest",
84
84
  "test:coverage": "vitest run --coverage",
85
+ "verify": "node scripts/verify.mjs",
85
86
  "changeset": "changeset",
86
87
  "sync:changelog-doc": "node scripts/sync-changelog-doc.mjs",
87
88
  "docs:dev": "vitepress dev docs",
package/skills/README.md CHANGED
@@ -8,9 +8,9 @@
8
8
 
9
9
  | 技能 | 版本 | 用途 |
10
10
  | --- | --- | --- |
11
- | [fxri-plan-to-task](./fxri-plan-to-task/SKILL.md) | 1.2.0 | 方案落盘:建档评估(先查后写)→ 建档 → 校验 → 归档 → 任务级规范沉淀(能力终点);规范载体迁移 |
12
- | [fxri-release-changelog](./fxri-release-changelog/SKILL.md) | 1.0.12 | changesets 发版与多语言 CHANGELOG 维护 |
13
- | [fxri-session-recap](./fxri-session-recap/SKILL.md) | 1.2.0 | 会话收尾全量沉淀 + 规范沉淀 / 新会话三层恢复 / 历史任务时间批量修正 |
11
+ | [fxri-plan-to-task](./fxri-plan-to-task/SKILL.md) | 1.3.2 | 方案落盘:建档评估(先查后写)→ 建档 → 校验 → 归档 → 任务级规范沉淀(能力终点);规范载体迁移 |
12
+ | [fxri-release-changelog](./fxri-release-changelog/SKILL.md) | 1.1.1 | changesets 发版与多语言 CHANGELOG 维护 |
13
+ | [fxri-session-recap](./fxri-session-recap/SKILL.md) | 1.2.2 | 会话收尾全量沉淀 + 规范沉淀 / 新会话三层恢复 / 历史任务时间批量修正 |
14
14
 
15
15
  版本号取自各 SKILL.md 的 frontmatter `metadata.version`(`toolkit skills status` / `skills install` 打印的真源版本),与正文首部版本声明双写一致。
16
16
 
@@ -3,21 +3,21 @@ name: fxri-plan-to-task
3
3
  description: 将已确认的实施方案落盘为标准任务文件并跟踪至归档:动手前建档评估(查 active/archive 判同主题)、按模板建档、状态机更新、四级时间源取证、自查校验、任务级规范沉淀与手工归档。当用户确认方案后表达「开始落地/登记记录」的意图,或即将动手改仓库文件时使用——含建档、任务登记、落盘、归档、任务校验、规范载体迁移(conventions 单文件升目录形态)等说法及其口语近义表达(如按这个做吧、记一下、建个任务跟踪)均触发。不用于方案未确认的对话、会话收尾整场沉淀(fxri-session-recap 模式一)、与任务记录无关的普通 TODO、issue 管理或日常提交信息撰写。
4
4
  license: MIT
5
5
  metadata:
6
- version: "1.2.0"
6
+ version: "1.3.2"
7
7
  author: fxri
8
8
  source: https://github.com/fxri-net/toolkit
9
9
  ---
10
10
 
11
11
  # 方案落盘:任务建档与归档
12
12
 
13
- > 本技能版本 1.2.0(随 @fxri/toolkit 同批分发)。被问版本时即报此值——不读磁盘、不跑 CLI:报出的值就是本会话上下文里已加载内容的版本,可与 `toolkit skills status` 打印的磁盘基准值对照,不一致即说明会话上下文已过期,开新会话即可。
13
+ > 本技能版本 1.3.2(随 @fxri/toolkit 同批分发)。被问版本时即报此值——不读磁盘、不跑 CLI:报出的值就是本会话上下文里已加载内容的版本,可与 `toolkit skills status` 打印的磁盘基准值对照,不一致即说明会话上下文已过期,开新会话即可。
14
14
 
15
15
  ## 何时使用
16
16
 
17
17
  - 用户确认实施方案后,表达开始落地/登记记录的意图(语义触发,不要求字面一致):建档 / 任务登记 / 落盘 / 归档 / 任务校验 / 规范载体迁移 / 按这个做吧 / 记一下 / 建个任务跟踪
18
18
  - **即将动手改仓库文件前**(方案已确认、准备执行改动)也是本技能适用场景——动手前先做建档评估(见工作流第 1 步),避免跳过建档直接执行
19
19
  - 触发前置条件:**方案已确认**。用户说「开始/开工」但方案尚未确认时,先出方案等确认,不建档
20
- - **何时不使用**:方案未确认的对话;会话收尾的整场沉淀与归档(那是 fxri-session-recap 模式一);与方案落盘无关的普通 TODO、issue 管理、日历待办、日常提交信息撰写
20
+ - **何时不使用**:方案未确认的对话;会话收尾的整场沉淀与归档(那是 fxri-session-recap 模式一);收尾动作(提交、发版、推送、部署)本身——动作不算、改动才算(见工作流第 1 步);与方案落盘无关的普通 TODO、issue 管理、日历待办、日常提交信息撰写
21
21
 
22
22
  ## 核心约定
23
23
 
@@ -46,16 +46,17 @@ metadata:
46
46
  - 列出任务目录 `active/` 下全部 `.md`(含一层 `{YYYYMM}/` 月份子目录),并核对 `archive/` 是否已有同主题任务
47
47
  - 读 conventions 载体(存在时):先找 `.tasks/conventions/index.md`,不存在再看旧单文件 `.tasks/conventions.md`(兼容期读取,并在对话中提示可迁移);常驻只读 `index.md`,再按本任务 `scope` 命中加载 `common` 与端分册(判定见 `references/conventions-spec.md`);项目协作规范在建档与执行时须遵守;规范载体本身不属于任务,不为其建档
48
48
  - **同主题判别表**(建档前必须按此决策):
49
- | 现状 | 增量情况 | 处理 |
49
+ | 现状 | 本次是否产生仓库文件改动 | 处理 |
50
50
  | --- | --- | --- |
51
51
  | active 有同主题 | 补充/细化(同需求未完) | **更新原文件**正文,updated 同步,不新建 |
52
52
  | active 有同主题 | 已分叉成不同范围 | 问用户:拆新任务 or 合并更新 |
53
- | active 无、archive 有(已归档完成) | 无增量(重复提议同一件事) | 提示「同主题任务已归档于 {日期}」,不重复建档,直接执行 |
54
- | active 无、archive 有 | 有增量(延续/扩展) | **重新建档**,正文首行标注来源链 `延续 {原归档任务名}(见 archive/{YYYYMM}/{YYYYMMDD}.md)` |
55
- | active 无、archive 有 | 仅修正旧记录的时间/内容 | 走 fxri-session-recap 模式三(历史修正),**不是建档** |
53
+ | active 无、archive 有(已归档完成) | 否(重复提议 / 重复执行同一件事) | 提示「同主题任务已归档于 {日期}」,不重复建档,直接执行 |
54
+ | active 无、archive 有 | 是(延续 / 扩展 / 重新实现) | **重新建档**,正文首行标注来源链 `延续 {原归档任务名}(见 archive/{YYYYMM}/{YYYYMMDD}.md)` |
55
+ | active 无、archive 有 | 否,仅修正旧记录的时间/内容 | 走 fxri-session-recap 模式三(历史修正),**不是建档** |
56
56
  | active 与 archive 均无 | — | **建档后再动手**(硬前置,不建档不许改文件) |
57
- - **增量判别口径**(不靠感觉):新方案含原任务中不存在的新需求点/变更点/范围 = 有增量;完全同描述同范围 = 无增量;拿不准 → 列出差异问用户,不猜
58
- - **归档任务不可变**:已归档块是终结记录,不向其追加新内容(追加会破坏完成时间/范围的可信度);延续需求一律走新任务
57
+ - **仓库文件改动口径**(客观判据,不靠感觉):需写入版本控制的工作区文件的增 / 改 / 删(源码、配置、文档、技能、任务区自身均计入);纯读取、纯执行、纯汇报不计入;拿不准 → 列出差异问用户,不猜
58
+ - **动作不算,改动才算**:收尾动作(提交、发版、推送、部署)本身及其固有产物(版本号、更新日志、标签)不构成任务、不作为建档对象;这些动作过程中若出现需改仓库文件才能解决的缺陷(如打包配置错误、发布渠道错误),该修复按普通任务建档
59
+ - **归档块不可变**:已归档块不追加新的工作内容(追加新工作内容会破坏完成时间/范围的可信度);延续需求一律走新任务。唯一例外是**事实更正**:后续核实推翻原块结论时,在其正文末尾追加「修订记录」(保留原结论、不动元数据行、附更正时刻与依据)
59
60
  - 任务唯一键:`{年月日}-{用户名}-{任务简述}`;多人对同一需求共用一个文件
60
61
 
61
62
  ### 2. 建档
@@ -91,7 +92,9 @@ metadata:
91
92
 
92
93
  ### 6. 收尾边界(硬约束到沉淀)
93
94
 
94
- **归档 + 规范沉淀即本技能流程终点**(先归档、后沉淀)。提交、发版、推送不是必经步骤,是否执行取决于用户的全局 / 个人 / 项目规则;若提交代码,先归档与沉淀、后提交,任务归档文件与规范载体变更、代码变更落在**同一个 git 提交**(顺序不可颠倒),避免任务完成却滞留 `active/` 未归档,或归档单独成一条提交。
95
+ **归档 + 规范沉淀即本技能流程终点**(先归档、后沉淀)。提交、发版、推送不是必经步骤,是否执行取决于用户的全局 / 个人 / 项目规则;若提交代码,按「归档与沉淀 → 跑项目验收命令 → 提交」的顺序执行,任务归档文件与规范载体变更、代码变更落在**同一个 git 提交**(顺序不可颠倒),避免任务完成却滞留 `active/` 未归档,或归档单独成一条提交。
96
+
97
+ ⚠️ **验收须晚于归档**:归档会改写 `.tasks/`(写归档文件、删 active 源文件、清理空月份目录),而归档本身不做阻断式校验——早于归档跑验收就覆盖不到终态,归档产物等于无人校验。同理,归档块「完成情况」只记改动事实与所用验证命令,不逐条抄写验收输出。
95
98
 
96
99
  ## 失败模式
97
100
 
@@ -98,6 +98,10 @@ scope: app # 影响范围;多值以半角加号分隔(toolkit+lxg
98
98
  ## 6. 协作约定
99
99
 
100
100
  - 任务区是多写者共享区:先查后写,同一需求共用一个任务文件;建档与执行时遵守 conventions 载体(`.tasks/conventions/index.md`,存在时)中的项目规范,旧单文件 `conventions.md` 亦兼容读取
101
- - **动手前置建档评估**:涉及仓库文件改动的任务,动手前先查 active/archive 判同主题(完整判别表见 SKILL.md 工作流第 1 步);active 有同主题则更新原文件,archive 有同主题且无增量则不重复建档
102
- - **归档任务不可变**:已归档块是终结记录(唯一键 + 完成时间已固定),不向其追加新内容;延续/扩展需求走新任务并标注来源链
103
- - 强制约束到**沉淀**为止:归档 + 规范沉淀即流程终点;提交、发版、推送不是必经步骤,是否执行取决于用户的全局 / 个人 / 项目规则;若提交代码,先归档与沉淀、后 git commit,任务记录(归档文件 + conventions 载体)与代码变更落在同一提交
101
+ - **动手前置建档评估**:涉及仓库文件改动的任务,动手前先查 active/archive 判同主题(完整判别表见 SKILL.md 工作流第 1 步);active 有同主题则更新原文件;archive 有同主题且本次不产生仓库文件改动(重复提议 / 重复执行)则不重复建档,本次产生仓库文件改动(延续 / 扩展 / 重新实现)则重新建档并标注来源链
102
+ - **仓库文件改动口径**:需写入版本控制的工作区文件的增 / 改 / 删(源码、配置、文档、技能、任务区自身均计入);纯读取、纯执行、纯汇报不计入;拿不准时列出差异问用户,不猜
103
+ - **动作不算,改动才算**:收尾动作(提交、发版、推送、部署)本身及其固有产物(版本号、更新日志、标签)不构成任务、不单独建档;这些动作过程中若出现需改仓库文件才能解决的缺陷(如打包配置错误、发布渠道错误),该修复按普通任务建档
104
+ - **归档块不可变**:已归档块是终结记录(唯一键 + 完成时间已固定),不追加新的工作内容;延续 / 扩展需求走新任务并标注来源链。唯一例外是**事实更正**——后续核实推翻原块结论时,在其正文末尾追加「修订记录」(保留原结论、不动元数据行、附更正时刻与依据),与 conventions 载体「废弃不删行」同属留痕优于抹除
105
+ - **验收与 CI 同源,不手写清单**:项目的验收步骤清单只允许一份真源——一条聚合命令(如 `pnpm verify`)背后由脚本定义步骤,本地与全部 CI 流水线共用它;禁止在规则文件、CI 配置里另抄一份步骤枚举。多份手写清单必然漂移,征兆就是「本地自检通过、CI 才报错」,出现该征兆先查清单是否已经漂移
106
+ - 强制约束到**沉淀**为止:归档 + 规范沉淀即流程终点;提交、发版、推送不是必经步骤,是否执行取决于用户的全局 / 个人 / 项目规则;若提交代码,按「归档与沉淀 → 跑项目验收命令 → git commit」的顺序执行,任务记录(归档文件 + conventions 载体)与代码变更落在同一提交
107
+ - **验收须晚于归档**:归档会改写任务区(写归档文件、删 active 源文件、清理空月份目录),而归档本身不做阻断式校验——早于归档跑验收就覆盖不到终态,归档产物等于无人校验。同理,归档块「完成情况」只记改动事实与所用验证命令,不逐条抄写验收输出(归档在前、验收在后,抄结果就成了先写结论后验证)
@@ -3,14 +3,14 @@ name: fxri-release-changelog
3
3
  description: 基于 changesets 的发版与多语言 CHANGELOG 维护流程:创建变更集、消费发版、把分组标题与条目转为项目语言风格、清理变更集、打标签发布;无 changesets 的项目提供同格式手工模式。当用户表达发版或记录变更意图——含创建变更集、changeset、发版、version、CHANGELOG 格式化等说法及其口语近义表达(如发一版、出个版本、记一下这次改动、生成更新日志)时使用。⚠️ 注意区分:用户说「提交个版本 / 先提交一版 / commit」通常指 git 提交当前改动(走任务收尾后提交),**不是发版**。不用于日常 commit message 撰写、git 提交操作或与发版无关的文档修改。
4
4
  license: MIT
5
5
  metadata:
6
- version: "1.0.12"
6
+ version: "1.1.1"
7
7
  author: fxri
8
8
  source: https://github.com/fxri-net/toolkit
9
9
  ---
10
10
 
11
11
  # 发版与 CHANGELOG
12
12
 
13
- > 本技能版本 1.0.12(随 @fxri/toolkit 同批分发)。被问版本时即报此值——不读磁盘、不跑 CLI:报出的值就是本会话上下文里已加载内容的版本,可与 `toolkit skills status` 打印的磁盘基准值对照,不一致即说明会话上下文已过期,开新会话即可。
13
+ > 本技能版本 1.1.1(随 @fxri/toolkit 同批分发)。被问版本时即报此值——不读磁盘、不跑 CLI:报出的值就是本会话上下文里已加载内容的版本,可与 `toolkit skills status` 打印的磁盘基准值对照,不一致即说明会话上下文已过期,开新会话即可。
14
14
 
15
15
  ## 何时使用
16
16
 
@@ -23,7 +23,9 @@ metadata:
23
23
  ## 前置检查
24
24
 
25
25
  - ⚠️ 发版不是必经步骤:仅在用户明确要求,或用户全局 / 个人 / 项目规则约定时才进入本技能,不主动发版
26
+ - ⚠️ **发版是收尾动作,不是任务**:本技能不为发版本身建档——发版的输入是「已归档的任务改动」,发版过程及其固有产物(版本号、更新日志、标签)不构成任务、不作为建档对象。例外:过程中暴露的、需改仓库文件才能修复的缺陷(打包配置错误、发布渠道错误、版本号冲突)→ 走 fxri-plan-to-task 先建档再改
26
27
  - `.tasks/active/` 存在未归档任务 → 先完成归档再发版(任务归档是发版的前置顺序)
28
+ - **覆盖核对**:本次待发布的改动逐项确认已有归档记录;出现「有改动却无归档记录」→ 先补归档(fxri-session-recap 模式一)再发版
27
29
  - 项目根存在 `.changeset/` 目录 → 走「changesets 流程」
28
30
  - 不存在 → 走「手工模式」(规范见 `references/changelog-format.md`)
29
31
 
@@ -34,7 +36,8 @@ metadata:
34
36
  3. 格式化:按 `references/changelog-format.md` 的语义分组规则归类条目、转换分组标题、润色为项目语言风格(中文示例:`### Patch Changes` 下的 `- 修复:xxx` → `### 🐛 问题修复` 下的 `- xxx`——归类后类型前缀被剥离,类型由分组标题承接);分组维度与 bump 维度正交,条目归组只看类型前缀
35
37
  4. 归一:润色后跑一次 `toolkit changelog --history format`——人工润色(含补写历史块明细)容易在条目之间留空行,该命令按「同组顶层条目逐行相邻」重排历史块;项目另有更新日志镜像页(如 `docs/changelog.md`)时再跑一次同步脚本,否则镜像一致性校验会失败
36
38
  5. 清理:删除已消费的 `.changeset/*.md`
37
- 6. 发布:提交版本与 CHANGELOG 改动 → 打 `vX.Y.Z` 标签 → 按项目渠道发布(如 `npm publish`)
39
+ 6. 门禁:发布前跑一次项目的验收命令(如 `pnpm verify`)——**关卡设在发布前而非推送前**:发布到包仓库 / 制品库不可逆,推送失败重推即可,故必须拦在不可逆动作之前;任一步失败即中止发版,不进入提交、打标签、发布
40
+ 7. 发布:提交版本与 CHANGELOG 改动 → 打 `vX.Y.Z` 标签 → 按项目渠道发布(如 `npm publish`)
38
41
 
39
42
  ⚠️ 自动生成的条目必须人工核对润色,与仓库既有 CHANGELOG 风格保持一致。
40
43
 
@@ -50,6 +53,7 @@ metadata:
50
53
  | CHANGELOG 出现「- - 条目」双前缀伪影(变更集条目以 `- ` 开头) | `toolkit changelog version/format` 已自动还原为顶层条目;手工模式按 references 规则手动清理 |
51
54
  | 条目与仓库既有风格不一致 | 人工润色为项目语言与句式,勿保留机器直译 |
52
55
  | 变更集遗漏(发版后才发现功能未记录) | 补建变更集随下次发版;本次在发布说明中人工补充 |
56
+ | 改动已发布却无归档记录(有提交、无任务档) | 先补归档(fxri-session-recap 模式一)再继续发布后续步骤;发版本身不补建档 |
53
57
  | 发版后历史块内出现多余空行(`自举一致性` 类零改动用例失败) | 跑 `toolkit changelog --history format` 归一(**必须带 `--history`**,默认模式不动历史块),再补跑一次镜像页同步脚本 |
54
58
 
55
59
  ## 可选加速(不构成依赖)
@@ -3,14 +3,14 @@ name: fxri-session-recap
3
3
  description: 会话收尾的工作记忆沉淀 + 新会话开场恢复 + 历史任务时间修正:收尾时把整场会话的全部任务完整建档归档,按四级时间源还原真实完成时间,沉淀规范进 conventions 载体;新会话开场按三层恢复(全量索引 + active 精读 + 近窗归档)重建现场并核对规范;也可批量修正历史归档时间。当用户表达会话收尾意图(如今天先到这、收个尾、归档本次会话、把结论记下来)、接续意图(如恢复上下文、继续上次、上次做到哪)、或修正历史任务时间时使用。不用于会话中途的常规方案建档(那是 fxri-plan-to-task 的职责)、与工作交接无关的代码技术总结。
4
4
  license: MIT
5
5
  metadata:
6
- version: "1.2.0"
6
+ version: "1.2.2"
7
7
  author: fxri
8
8
  source: https://github.com/fxri-net/toolkit
9
9
  ---
10
10
 
11
11
  # 会话归档、上下文恢复与历史修正
12
12
 
13
- > 本技能版本 1.2.0(随 @fxri/toolkit 同批分发)。被问版本时即报此值——不读磁盘、不跑 CLI:报出的值就是本会话上下文里已加载内容的版本,可与 `toolkit skills status` 打印的磁盘基准值对照,不一致即说明会话上下文已过期,开新会话即可。
13
+ > 本技能版本 1.2.2(随 @fxri/toolkit 同批分发)。被问版本时即报此值——不读磁盘、不跑 CLI:报出的值就是本会话上下文里已加载内容的版本,可与 `toolkit skills status` 打印的磁盘基准值对照,不一致即说明会话上下文已过期,开新会话即可。
14
14
 
15
15
  ## 何时使用
16
16
 
@@ -48,12 +48,14 @@ metadata:
48
48
  ### R2 统一收尾链路(能力终点 = 沉淀)
49
49
 
50
50
  ```
51
- 任务终结 → 归档 → 规范沉淀(硬终点) → 提交/发版/推送(可选,需用户确认)
51
+ 任务终结 → 归档 → 规范沉淀(硬终点) → 验收 → 提交/发版/推送(可选,需用户确认)
52
52
  ```
53
53
 
54
54
  - 归档是中间步骤,**规范沉淀才是流程终点**
55
- - 沉淀时机固定:归档完成后、任何 git 操作前,规范与归档文件同批落盘
56
- - 提交、发版、推送**不是必经步骤**,是否执行取决于用户全局/个人/项目规则;若提交代码:先归档、后提交,归档文件与代码变更落在同一 git 提交
55
+ - 沉淀时机固定:归档完成后、任何收尾动作(验收 / 提交 / 发版 / 推送)前,规范与归档文件同批落盘
56
+ - ⚠️ **验收须晚于归档**:归档会改写 `.tasks/`,且归档本身不做阻断式校验——早于归档跑验收就覆盖不到终态,归档产物等于无人校验;归档块「完成情况」只记改动事实与所用验证命令,不逐条抄写验收输出
57
+ - 提交、发版、推送**不是必经步骤**,是否执行取决于用户全局/个人/项目规则;若提交代码:先归档、后跑项目验收命令、再提交,归档文件与代码变更落在同一 git 提交
58
+ - **动作不算、改动才算**:收尾动作(提交、发版、推送、部署)本身及其固有产物(版本号、更新日志、标签)不构成任务、不单独建档;其所依据的改动须有归档记录,缺则补档
57
59
 
58
60
  ### R3 规范落点:`.tasks/conventions/` 载体(两级沉淀同一载体)
59
61
 
@@ -84,10 +86,11 @@ metadata:
84
86
  3. **逐条落盘**(先查后写;格式与目录规范见 `../fxri-plan-to-task/references/task-spec.md`;fxri-plan-to-task 未一并安装、该兄弟路径不存在时,改读包内真源——`toolkit skills status` 打印的「技能源」目录下 `fxri-plan-to-task/references/task-spec.md`):
85
87
  - 会话工作有对应任务 → 更新原文件:正文追加结论与决策,时间字段按 R1 校准
86
88
  - 无对应任务但有独立成果 → 按 fxri-plan-to-task 规范建档,created 取任务真实创建日
87
- - 未尽事项 → 拆独立任务文件(status: 待办),不在正文留游离待办
89
+ - 未尽事项 → 拆独立任务文件(status: 待办),不在正文留游离待办
90
+ - 收尾动作(提交、发版、推送、部署)本身及其固有产物(版本号、更新日志、标签)不单独成档;其所依据的改动缺归档记录时须补档
88
91
  4. **归档**:终结态任务按 task-spec「手工归档步骤」执行(合并归档块 → 降序重排 → 写回 → 删源文件 → 清理空月份目录),或 `toolkit tasks archive` 自动化
89
92
  5. **规范沉淀(终点)**:按「规范提炼子流程」执行会话级提炼,写入 conventions 载体
90
- 6. **收尾边界**:沉淀即本技能流程终点。提交、发版、推送不是必经步骤,是否执行取决于用户规则;若提交代码,先归档、后提交,任务归档文件 + conventions 载体与本次代码变更落在**同一个 git 提交**;提交前向用户展示待提交内容供确认
93
+ 6. **收尾边界**:沉淀即本技能流程终点。提交、发版、推送不是必经步骤,是否执行取决于用户规则;⚠️ 验收须晚于归档——若提交代码,先归档、再跑项目验收命令、后提交,任务归档文件 + conventions 载体与本次代码变更落在**同一个 git 提交**;提交前向用户展示待提交内容供确认
91
94
  7. **回报**:向用户列出本次沉淀的任务清单、归档位置与规范变更,确认无遗漏后再结束
92
95
 
93
96
  ## 模式二:恢复上下文