@fxri/toolkit 1.10.1 → 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,23 @@
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
+
3
21
  ## 1.10.1
4
22
 
5
23
  > 2026-09-16 发布
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.1",
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,14 +3,14 @@ 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.3.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.3.0(随 @fxri/toolkit 同批分发)。被问版本时即报此值——不读磁盘、不跑 CLI:报出的值就是本会话上下文里已加载内容的版本,可与 `toolkit skills status` 打印的磁盘基准值对照,不一致即说明会话上下文已过期,开新会话即可。
13
+ > 本技能版本 1.3.2(随 @fxri/toolkit 同批分发)。被问版本时即报此值——不读磁盘、不跑 CLI:报出的值就是本会话上下文里已加载内容的版本,可与 `toolkit skills status` 打印的磁盘基准值对照,不一致即说明会话上下文已过期,开新会话即可。
14
14
 
15
15
  ## 何时使用
16
16
 
@@ -92,7 +92,9 @@ metadata:
92
92
 
93
93
  ### 6. 收尾边界(硬约束到沉淀)
94
94
 
95
- **归档 + 规范沉淀即本技能流程终点**(先归档、后沉淀)。提交、发版、推送不是必经步骤,是否执行取决于用户的全局 / 个人 / 项目规则;若提交代码,先归档与沉淀、后提交,任务归档文件与规范载体变更、代码变更落在**同一个 git 提交**(顺序不可颠倒),避免任务完成却滞留 `active/` 未归档,或归档单独成一条提交。
95
+ **归档 + 规范沉淀即本技能流程终点**(先归档、后沉淀)。提交、发版、推送不是必经步骤,是否执行取决于用户的全局 / 个人 / 项目规则;若提交代码,按「归档与沉淀 → 跑项目验收命令 → 提交」的顺序执行,任务归档文件与规范载体变更、代码变更落在**同一个 git 提交**(顺序不可颠倒),避免任务完成却滞留 `active/` 未归档,或归档单独成一条提交。
96
+
97
+ ⚠️ **验收须晚于归档**:归档会改写 `.tasks/`(写归档文件、删 active 源文件、清理空月份目录),而归档本身不做阻断式校验——早于归档跑验收就覆盖不到终态,归档产物等于无人校验。同理,归档块「完成情况」只记改动事实与所用验证命令,不逐条抄写验收输出。
96
98
 
97
99
  ## 失败模式
98
100
 
@@ -102,4 +102,6 @@ scope: app # 影响范围;多值以半角加号分隔(toolkit+lxg
102
102
  - **仓库文件改动口径**:需写入版本控制的工作区文件的增 / 改 / 删(源码、配置、文档、技能、任务区自身均计入);纯读取、纯执行、纯汇报不计入;拿不准时列出差异问用户,不猜
103
103
  - **动作不算,改动才算**:收尾动作(提交、发版、推送、部署)本身及其固有产物(版本号、更新日志、标签)不构成任务、不单独建档;这些动作过程中若出现需改仓库文件才能解决的缺陷(如打包配置错误、发布渠道错误),该修复按普通任务建档
104
104
  - **归档块不可变**:已归档块是终结记录(唯一键 + 完成时间已固定),不追加新的工作内容;延续 / 扩展需求走新任务并标注来源链。唯一例外是**事实更正**——后续核实推翻原块结论时,在其正文末尾追加「修订记录」(保留原结论、不动元数据行、附更正时刻与依据),与 conventions 载体「废弃不删行」同属留痕优于抹除
105
- - 强制约束到**沉淀**为止:归档 + 规范沉淀即流程终点;提交、发版、推送不是必经步骤,是否执行取决于用户的全局 / 个人 / 项目规则;若提交代码,先归档与沉淀、后 git commit,任务记录(归档文件 + 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.1.0"
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.1.0(随 @fxri/toolkit 同批分发)。被问版本时即报此值——不读磁盘、不跑 CLI:报出的值就是本会话上下文里已加载内容的版本,可与 `toolkit skills status` 打印的磁盘基准值对照,不一致即说明会话上下文已过期,开新会话即可。
13
+ > 本技能版本 1.1.1(随 @fxri/toolkit 同批分发)。被问版本时即报此值——不读磁盘、不跑 CLI:报出的值就是本会话上下文里已加载内容的版本,可与 `toolkit skills status` 打印的磁盘基准值对照,不一致即说明会话上下文已过期,开新会话即可。
14
14
 
15
15
  ## 何时使用
16
16
 
@@ -36,7 +36,8 @@ metadata:
36
36
  3. 格式化:按 `references/changelog-format.md` 的语义分组规则归类条目、转换分组标题、润色为项目语言风格(中文示例:`### Patch Changes` 下的 `- 修复:xxx` → `### 🐛 问题修复` 下的 `- xxx`——归类后类型前缀被剥离,类型由分组标题承接);分组维度与 bump 维度正交,条目归组只看类型前缀
37
37
  4. 归一:润色后跑一次 `toolkit changelog --history format`——人工润色(含补写历史块明细)容易在条目之间留空行,该命令按「同组顶层条目逐行相邻」重排历史块;项目另有更新日志镜像页(如 `docs/changelog.md`)时再跑一次同步脚本,否则镜像一致性校验会失败
38
38
  5. 清理:删除已消费的 `.changeset/*.md`
39
- 6. 发布:提交版本与 CHANGELOG 改动 → 打 `vX.Y.Z` 标签 → 按项目渠道发布(如 `npm publish`)
39
+ 6. 门禁:发布前跑一次项目的验收命令(如 `pnpm verify`)——**关卡设在发布前而非推送前**:发布到包仓库 / 制品库不可逆,推送失败重推即可,故必须拦在不可逆动作之前;任一步失败即中止发版,不进入提交、打标签、发布
40
+ 7. 发布:提交版本与 CHANGELOG 改动 → 打 `vX.Y.Z` 标签 → 按项目渠道发布(如 `npm publish`)
40
41
 
41
42
  ⚠️ 自动生成的条目必须人工核对润色,与仓库既有 CHANGELOG 风格保持一致。
42
43
 
@@ -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.1"
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.1(随 @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,13 @@ 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 提交
57
58
  - **动作不算、改动才算**:收尾动作(提交、发版、推送、部署)本身及其固有产物(版本号、更新日志、标签)不构成任务、不单独建档;其所依据的改动须有归档记录,缺则补档
58
59
 
59
60
  ### R3 规范落点:`.tasks/conventions/` 载体(两级沉淀同一载体)
@@ -89,7 +90,7 @@ metadata:
89
90
  - 收尾动作(提交、发版、推送、部署)本身及其固有产物(版本号、更新日志、标签)不单独成档;其所依据的改动缺归档记录时须补档
90
91
  4. **归档**:终结态任务按 task-spec「手工归档步骤」执行(合并归档块 → 降序重排 → 写回 → 删源文件 → 清理空月份目录),或 `toolkit tasks archive` 自动化
91
92
  5. **规范沉淀(终点)**:按「规范提炼子流程」执行会话级提炼,写入 conventions 载体
92
- 6. **收尾边界**:沉淀即本技能流程终点。提交、发版、推送不是必经步骤,是否执行取决于用户规则;若提交代码,先归档、后提交,任务归档文件 + conventions 载体与本次代码变更落在**同一个 git 提交**;提交前向用户展示待提交内容供确认
93
+ 6. **收尾边界**:沉淀即本技能流程终点。提交、发版、推送不是必经步骤,是否执行取决于用户规则;⚠️ 验收须晚于归档——若提交代码,先归档、再跑项目验收命令、后提交,任务归档文件 + conventions 载体与本次代码变更落在**同一个 git 提交**;提交前向用户展示待提交内容供确认
93
94
  7. **回报**:向用户列出本次沉淀的任务清单、归档位置与规范变更,确认无遗漏后再结束
94
95
 
95
96
  ## 模式二:恢复上下文