@longzai-intelligence-agent-tools/cli 0.0.14 → 0.0.15
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +4 -4
- package/package.json +3 -3
package/dist/index.js
CHANGED
|
@@ -222,7 +222,7 @@ IDE 差异化诉求请写在 agent.claude.md(仅进 CLAUDE.md)。
|
|
|
222
222
|
# frontmatter 各 IDE 不同(claude paths / trae alwaysApply+globs),见 docs/vendors/
|
|
223
223
|
`,"skills/.gitkeep":`# 此目录存放技能真源
|
|
224
224
|
# 命名约定:<base>.md(共同)+ <base>.<type>.md(某 IDE 独有)
|
|
225
|
-
`},q={HEAD_LINES:30,COMMON_MAX_LINES:400,COMMON_MAX_TOKENS:5e3,CODE_BLOCK_MAX_LINES:40,DUPLICATE_MIN_CHARS:60,SIMILARITY_THRESHOLD:.85,CATEGORY_INDEX_MIN_FILES:5,AGENT_SPLIT_MIN_ROLES:3},ju={"volatile-prefix":{id:`volatile-prefix`,severity:`high`,title:`易变占位符位于文件头部,破坏稳定前缀`,reference:`原文优化八:稳定前缀设计(实测收益 >85%,对费用影响最大)`},"oversized-common":{id:`oversized-common`,severity:`medium`,title:`公共源文件过大,应渐进式披露拆分`,reference:`原文优化一:渐进式披露(实测收益 >10%)`},"low-freq-section":{id:`low-freq-section`,severity:`low`,title:`低频段落常驻公共文件,建议下沉为按需加载的独立文件`,reference:`原文优化一:渐进式披露,L2 按需层(实测收益 >10%)`},"type-content-in-common":{id:`type-content-in-common`,severity:`medium`,title:`公共文件包含类型专属内容,应移入 agent.<type>.md`,reference:`原文优化六:Agent 专属配置;原则二:减少不相关的`},"cross-type-duplicate":{id:`cross-type-duplicate`,severity:`medium`,title:`各类型独有文件间存在重复段落,建议上移公共文件`,reference:`原文优化九:避免重复加载 Skill(消除隐性重复膨胀);原则三:减少重复的`},"inline-code-block":{id:`inline-code-block`,severity:`low`,title:`大段内联代码块,建议改为文件引用`,reference:`原文优化一:渐进式披露,工具列表用扁平链接替代说明文档搬运`},"missing-tools-whitelist":{id:`missing-tools-whitelist`,severity:`low`,title:`command 源文件未声明 allowed-tools 白名单`,reference:`原文优化六:Agent 专属配置,tools 白名单`},"missing-index":{id:`missing-index`,severity:`low`,title:`类别目录文件较多且无 INDEX.md 索引`,reference:`原文优化四:长期记忆按需索引加载(实测收益 >10%)`},"sequential-instruction":{id:`sequential-instruction`,severity:`low`,title:`指令要求逐个/串行执行,建议固化为脚本或改为并行`,reference:`原文优化二:确定性操作由脚本执行;原文优化十一:工具调用并行化`},"multi-step-git-ops":{id:`multi-step-git-ops`,severity:`medium`,title:`指令要求 Agent 逐步执行 git 流程,建议改用专用工具一次调用`,reference:`原文优化二:确定性操作由脚本执行,一次脚本调用替代多轮模型交互(实测收益 >10%);原文优化十一:串行工具调用每次携带完整上下文`},"mcp-over-cli":{id:`mcp-over-cli`,severity:`medium`,title:`指令指示通过 MCP 工具执行操作,CLI 优先更省 token`,reference:`原文优化二:CLI 优先于 MCP——MCP 的 JSON 结构化返回往往比纯文本 CLI 输出消耗更多 token(实测收益 >10%)`},"mcp-data-subagent":{id:`mcp-data-subagent`,severity:`medium`,title:`指令让主 Agent 直接经 MCP 获取大数据,应数据获取子 Agent 化`,reference:`原文优化三:MCP 数据获取子 Agent 化——数据获取子 Agent 压缩归纳后只把结论返回主 Agent(实测单次交互 message tokens 从 800KB 降到 5K,降幅 90%+)`},"agent-split":{id:`agent-split`,severity:`medium`,title:`公共指令承载多个职能且体量过大,建议按职能拆分为多 Agent`,reference:`原文优化五:单 Agent 拆分为多 Agent——每个 Agent 的 system prompt 与工具集最小化,拆分后总账更优(降低单次交互成本)`},"blind-search":{id:`blind-search`,severity:`low`,title:`指令要求 Agent 盲搜定位代码,建议图谱查询或精确路径引用`,reference:`原文优化七:代码图谱替代盲搜——grep/glob 暴力遍历搜索范围大、读取文件多(实测任务平均耗时降低 30%+,graphify 已在 10+ 项目落地)`},"verbose-cli-output":{id:`verbose-cli-output`,severity:`low`,title:`指令包含高输出 CLI 命令,建议接入 rtk 输出压缩代理`,reference:`原文优化十:rtk 压缩 CLI 输出——构建日志、测试报告、文件列表经 rtk 压缩后再进入模型上下文(实测压缩率 85% 左右)`}},Mu=[`high`,`medium`,`low`],J=(e,t,n,r)=>({rule:ju[e],file:t,line:n,detail:r}),Y=`.lzi`,Nu=`agents/agent.md`,Pu=`agents/items`,Fu=e=>e===`agents`?`agents/items`:`
|
|
225
|
+
`},q={HEAD_LINES:30,COMMON_MAX_LINES:400,COMMON_MAX_TOKENS:5e3,CODE_BLOCK_MAX_LINES:40,DUPLICATE_MIN_CHARS:60,SIMILARITY_THRESHOLD:.85,CATEGORY_INDEX_MIN_FILES:5,AGENT_SPLIT_MIN_ROLES:3},ju={"volatile-prefix":{id:`volatile-prefix`,severity:`high`,title:`易变占位符位于文件头部,破坏稳定前缀`,reference:`原文优化八:稳定前缀设计(实测收益 >85%,对费用影响最大)`},"oversized-common":{id:`oversized-common`,severity:`medium`,title:`公共源文件过大,应渐进式披露拆分`,reference:`原文优化一:渐进式披露(实测收益 >10%)`},"low-freq-section":{id:`low-freq-section`,severity:`low`,title:`低频段落常驻公共文件,建议下沉为按需加载的独立文件`,reference:`原文优化一:渐进式披露,L2 按需层(实测收益 >10%)`},"type-content-in-common":{id:`type-content-in-common`,severity:`medium`,title:`公共文件包含类型专属内容,应移入 agent.<type>.md`,reference:`原文优化六:Agent 专属配置;原则二:减少不相关的`},"cross-type-duplicate":{id:`cross-type-duplicate`,severity:`medium`,title:`各类型独有文件间存在重复段落,建议上移公共文件`,reference:`原文优化九:避免重复加载 Skill(消除隐性重复膨胀);原则三:减少重复的`},"inline-code-block":{id:`inline-code-block`,severity:`low`,title:`大段内联代码块,建议改为文件引用`,reference:`原文优化一:渐进式披露,工具列表用扁平链接替代说明文档搬运`},"missing-tools-whitelist":{id:`missing-tools-whitelist`,severity:`low`,title:`command 源文件未声明 allowed-tools 白名单`,reference:`原文优化六:Agent 专属配置,tools 白名单`},"missing-index":{id:`missing-index`,severity:`low`,title:`类别目录文件较多且无 INDEX.md 索引`,reference:`原文优化四:长期记忆按需索引加载(实测收益 >10%)`},"sequential-instruction":{id:`sequential-instruction`,severity:`low`,title:`指令要求逐个/串行执行,建议固化为脚本或改为并行`,reference:`原文优化二:确定性操作由脚本执行;原文优化十一:工具调用并行化`},"multi-step-git-ops":{id:`multi-step-git-ops`,severity:`medium`,title:`指令要求 Agent 逐步执行 git 流程,建议改用专用工具一次调用`,reference:`原文优化二:确定性操作由脚本执行,一次脚本调用替代多轮模型交互(实测收益 >10%);原文优化十一:串行工具调用每次携带完整上下文`},"mcp-over-cli":{id:`mcp-over-cli`,severity:`medium`,title:`指令指示通过 MCP 工具执行操作,CLI 优先更省 token`,reference:`原文优化二:CLI 优先于 MCP——MCP 的 JSON 结构化返回往往比纯文本 CLI 输出消耗更多 token(实测收益 >10%)`},"mcp-data-subagent":{id:`mcp-data-subagent`,severity:`medium`,title:`指令让主 Agent 直接经 MCP 获取大数据,应数据获取子 Agent 化`,reference:`原文优化三:MCP 数据获取子 Agent 化——数据获取子 Agent 压缩归纳后只把结论返回主 Agent(实测单次交互 message tokens 从 800KB 降到 5K,降幅 90%+)`},"agent-split":{id:`agent-split`,severity:`medium`,title:`公共指令承载多个职能且体量过大,建议按职能拆分为多 Agent`,reference:`原文优化五:单 Agent 拆分为多 Agent——每个 Agent 的 system prompt 与工具集最小化,拆分后总账更优(降低单次交互成本)`},"blind-search":{id:`blind-search`,severity:`low`,title:`指令要求 Agent 盲搜定位代码,建议图谱查询或精确路径引用`,reference:`原文优化七:代码图谱替代盲搜——grep/glob 暴力遍历搜索范围大、读取文件多(实测任务平均耗时降低 30%+,graphify 已在 10+ 项目落地)`},"verbose-cli-output":{id:`verbose-cli-output`,severity:`low`,title:`指令包含高输出 CLI 命令,建议接入 rtk 输出压缩代理`,reference:`原文优化十:rtk 压缩 CLI 输出——构建日志、测试报告、文件列表经 rtk 压缩后再进入模型上下文(实测压缩率 85% 左右)`}},Mu=[`high`,`medium`,`low`],J=(e,t,n,r)=>({rule:ju[e],file:t,line:n,detail:r}),Y=`.lzi`,Nu=`agents/agent.md`,Pu=`agents/items`,Fu=e=>e===`agents`?`agents/items`:e===`rules`?`rules`:`commands`,Iu=e=>e===`agents`?`${Y}/${Pu}`:`${Y}/${e}`,Lu={claude:`.claude`,trae:`.trae`,zcode:`.zcode`},Ru={claude:[{output:`CLAUDE.md`,commonSource:Nu,agentSource:`agents/agent.claude.md`}],trae:[{output:`CLAUDE.md`,commonSource:Nu,agentSource:`agents/agent.claude.md`},{output:`AGENTS.md`,commonSource:Nu,agentSource:`agents/agent.trae.md`}],zcode:[{output:`AGENTS.md`,commonSource:Nu,agentSource:`agents/agent.zcode.md`}]},zu={commands:{claude:{ideRoot:Lu.claude,mode:`append`},trae:{ideRoot:Lu.trae,mode:`append`},zcode:{ideRoot:Lu.zcode,mode:`append`}},rules:{claude:{ideRoot:Lu.claude,mode:`prepend`},trae:{ideRoot:Lu.trae,mode:`prepend`},zcode:{ideRoot:Lu.zcode,mode:`prepend`}},skills:{claude:{ideRoot:Lu.claude,mode:`append`},trae:{ideRoot:Lu.trae,mode:`append`},zcode:{ideRoot:Lu.zcode,mode:`append`}}},Bu=[`claude`,`trae`,`zcode`],Vu={DATE:()=>(/* @__PURE__ */ new Date()).toISOString().slice(0,10),PROJECT_NAME:()=>process.cwd().split(`/`).pop()??``},Hu=`auto`,Uu=async e=>{try{return await y(e),!0}catch{return!1}},Wu=async e=>{let t=o(e,Y);if(!await Uu(t))return[];let n=[];for(let e of Bu){let r=Ru[e];(await Promise.all(r.map(async e=>Uu(o(t,e.agentSource))))).some(e=>e)&&n.push(e)}return n},X={RED:`\x1B[0;31m`,GREEN:`\x1B[0;32m`,YELLOW:`\x1B[1;33m`,BLUE:`\x1B[0;34m`,RESET:`\x1B[0m`};function Gu(e){return e.map(e=>{if(typeof e==`string`)return e;if(e instanceof Error)return e.message;try{return JSON.stringify(e)}catch{return String(e)}}).join(` `)}function Z(...e){process.stdout.write(`${Gu(e)}\n`)}function Q(...e){process.stderr.write(`${Gu(e)}\n`)}const Ku=e=>Bu.some(t=>t===e),qu=e=>{let t=new Set(Object.keys(Au));if(e===void 0)return t;let n=/* @__PURE__ */ new Set;n.add(`agents/agent.md`);for(let t of Ru[e])n.add(`agents/${t.agentSource.split(`/`).pop()}`);for(let e of t)(!e.startsWith(`agents/`)||e.startsWith(`agents/items/`))&&n.add(e);return n},Ju=async e=>{let t=e.agent===void 0?void 0:Ku(e.agent)?e.agent:null;t===null&&(Z(`${X.RED}错误: --agent 值 '${e.agent}' 无效,合法值: ${Bu.join(`, `)}${X.RESET}`),process.exit(1));let n=process.cwd(),r=o(n,Y),i=qu(t);Z(`${X.BLUE}初始化 Agent Tools 源文件结构...${X.RESET}\n`),e.dryRun&&Z(`${X.YELLOW}[预览模式] 将创建以下文件:${X.RESET}`);let a=[],s=[];for(let[t,n]of Object.entries(Au)){if(!i.has(t))continue;let c=o(r,t);if(await Bun.file(c).exists()){a.push(t),e.dryRun||Z(` ${X.YELLOW}跳过${X.RESET} ${t}(已存在)`);continue}if(s.push(t),e.dryRun){Z(` ${X.GREEN}将创建${X.RESET} ${Y}/${t}`);continue}await Bun.write(c,n,{createPath:!0}),Z(` ${X.GREEN}已创建${X.RESET} ${Y}/${t}`)}Z(``),Z(`${X.BLUE}后续步骤:${X.RESET}`),Z(` 1. 编辑 ${Y}/agents/agent.md,填写共同指令与 {{KEY}} 占位符`),Z(` 2. 按需编辑 ${Y}/agents/agent.<type>.md,填写各 Agent 专属指令`),Z(` 3. 按需在 ${Y}/agents/items/ 下拆分条目(frontmatter order 定序,<type>.md 变体/独有)`),Z(` 4. 在 ${Y}/commands/ rules/ skills/ 下按命名约定添加类别配置`),Z(` 5. 运行 lzi-agent-cli sync 同步生成 CLAUDE.md / AGENTS.md 并分发类别配置`),Z(` 默认 auto:按 ${Y}/agents/agent.<type>.md 真源自动推断为所有存在的类型生成`),Z(` 定向同步:lzi-agent-cli sync --agent <${Bu.join(`|`)}> 或设 LZI_AGENT_TYPE`),Z(` 占位符:可选设置 ${Y}/../.env 的 LZI_PLACEHOLDER_<KEY>=<value>`),Z(` 6. 运行 lzi-agent-cli status 查看真源与产物存在性`),a.length>0&&(Z(``),Z(`${X.YELLOW}提示: ${a.length} 个文件已存在被跳过${X.RESET}`))},Yu=/[\u3400-\u4dbf\u4e00-\u9fff]/g,Xu=e=>{let t=e.match(Yu),n=t?t.length:0,r=e.length-n;return n+Math.ceil(r/3.5)},Zu=e=>{let t=e.split(`
|
|
226
226
|
`),n=[],r=[],i=1;for(let[e,a]of t.entries()){let t=e+1;(a.trim()===``||/^#{1,6}\s/.test(a))&&r.length>0&&(n.push({text:r.join(`
|
|
227
227
|
`),startLine:i}),r=[]),a.trim()!==``&&(r.length===0&&(i=t),r.push(a))}return r.length>0&&n.push({text:r.join(`
|
|
228
228
|
`),startLine:i}),n},Qu=(e,t)=>{let n=/* @__PURE__ */ new Set,r=/* @__PURE__ */ new Set;for(let t=0;t<e.length-1;t+=1)n.add(e.slice(t,t+2));for(let e=0;e<t.length-1;e+=1)r.add(t.slice(e,e+2));if(n.size===0||r.size===0)return 0;let i=0;for(let e of n)r.has(e)&&(i+=1);let a=n.size+r.size-i;return a===0?0:i/a},$u=e=>e.trim().replace(/\s+/g,` `),ed=/\{\{DATE\}\}/,td=/^(#{1,6})\s*(.*(?:FAQ|常见问题|疑难|排障|故障|部署|发布|回滚|迁移).*)$/im,nd=/Claude\s*Code|Trae|ZCode/i,rd=/(逐个|依次|串行|逐一)[^。\n;;]{0,12}(执行|调用|运行|处理|截图)|(批量)[^。\n;;]{0,12}(处理|替换|截图|重命名|修改|执行)/,id=e=>{let t=e.content.split(`
|
|
@@ -256,7 +256,7 @@ const config: AgentToolsConfig = {
|
|
|
256
256
|
${t}${n}${e.distribution?.rules?.trae===void 0?``:` distribution: {\n rules: {\n trae: {\n flatten: ${e.distribution.rules.trae.flatten===!0},\n },\n },\n },\n`}${r}};
|
|
257
257
|
|
|
258
258
|
export default config;
|
|
259
|
-
`},kd=vl().regex(/^[a-z][a-z0-9-]*$/,`名称须为小写字母开头的小写字母/数字/连字符`),Ad=au([`agents`,`rules`]).default(`agents`),jd=Yl(vl().min(1,`glob 不可为空`).refine(e=>!a(e),`禁止绝对路径形态的 glob`).refine(e=>!e.split(`/`).includes(`..`),`glob 禁止 .. 路径段`)).min(1,`glob 列表至少一条`),Md=Yl(Ql({name:kd,category:Ad,include:jd.nullable(),exclude:jd.nullable()})),Nd=e=>{if(e!==`agents`&&e!==`rules`)throw Error(`类别 '${e}' 非法:仅支持 agents / rules(见 docs/issues/0011)`);return e},Pd=e=>e.issues.map(e=>`${e.path.join(`.`)}: ${e.message}`).join(`; `),Fd=(e,t)=>{let n=Md.safeParse(e);if(!n.success)throw Error(`共享提示词订阅配置 ${t} 校验失败(以 zod 为运行时权威): ${Pd(n.error)}`);return n.data};var Id=class extends Error{configPath;constructor(e,t){super(e),this.name=`SharedConfigError`,this.configPath=t}},Ld=class extends Id{searchFrom;constructor(e){super(`未在 ${e} 及其上级目录中找到 lzi.config.ts 配置文件`,e),this.name=`SharedConfigNotFoundError`,this.searchFrom=e}},Rd=class extends Id{cause;constructor(e,t){super(`加载配置文件 ${e} 失败`,e),this.name=`SharedConfigLoadError`,this.cause=t}};function zd(e=process.cwd()){let n=s(e);for(;;){let e=o(n,`lzi.config.ts`);if(t(e))return e;let r=i(n);if(r===n)return null;n=r}}async function Bd(e={}){let t=e.cwd??process.cwd(),n=zd(t);if(n===null)throw new Ld(t);let r=s(n,`..`);try{return{config:(await import(n)).default,configPath:r,configFilePath:n}}catch(e){throw new Rd(n,e)}}function Vd(e,n=process.cwd()){let r=Array.isArray(e)?e:[e],a=s(n);for(;;){for(let e of r){let n=o(a,e);if(t(n))return n}let e=i(a);if(e===a)return null;a=e}}async function Hd(e={}){let t=e.cwd??s(process.cwd());if(e.standaloneFile){let n=Vd(e.standaloneFile,t);if(n)try{let e=await import(n);return{success:!0,config:e.default??e,source:`standalone`,configFilePath:n}}catch(e){throw new Rd(n,e)}}if(e.unifiedField)try{let{config:n,configFilePath:r}=await Bd({cwd:t}),i=n?.[e.unifiedField];if(i!==void 0)return{success:!0,config:i,source:`unified`,configFilePath:r}}catch{}return{success:!1,configFilePath:null}}const Ud=Ql({rules:Ql({trae:Ql({flatten:Ul().optional()})}).optional()}),Wd=e=>{if(e?.distribution===void 0)return!0;let t=Ud.safeParse(e.distribution);if(!t.success)throw Error(`distribution 配置段校验失败(以 zod 为运行时权威): ${t.error.issues.map(e=>`${e.path.join(`.`)}: ${e.message}`).join(`; `)}`);return t.data.rules?.trae?.flatten??!0},Gd=e=>Bu.some(t=>t===e),Kd=async(e,t)=>{let n=e.split(`,`),r=n.includes(Hu),i=n.filter(e=>e!==Hu&&e!==``);if(r&&i.length>0)throw Error(`${$.AGENT_TYPE} 值 '${e}' 非法:auto 与显式类型不可混用,请单独使用 auto 或逗号分隔的类型列表`);if(r)return[...await Wu(t)];if(i.length===0)return[];let a=/* @__PURE__ */ new Set;for(let e of i){if(!Gd(e))throw Error(`${$.AGENT_TYPE} 值 '${e}' 无效,合法值: ${Bu.join(`, `)}, ${Hu}`);if(a.has(e))throw Error(`${$.AGENT_TYPE} 值 '${e}' 重复,多值不可重复`);a.add(e)}return Bu.filter(e=>a.has(e))},qd=()=>{let e=process.env[$.AGENT_TYPE];return e===void 0||e===``?null:e},Jd=async e=>{let t=await Hd({standaloneFile:Td,unifiedField:`agentTools`,...e===void 0?{}:{cwd:e}});return t.success?t.config:void 0},Yd=async(e={})=>{let t=process.cwd(),n=await Jd(),r=e.agent??qd()??n?.agentType??``,i=r===``?[...await Wu(t)]:await Kd(r,t);return i.length===0&&(Q(`错误: 未指定目标 Agent 类型,且 auto 未推断到任何真源`),Q(`请运行 lzi-agent-cli init 创建 .lzi/ 骨架,或用 --agent / ${$.AGENT_TYPE} 指定类型`),Q(`合法值: ${Bu.join(`, `)}, ${Hu}`),process.exit(1)),{agentTypes:i,placeholders:n?.placeholders,rulesTraeFlatten:Wd(n)}},Xd=e=>o(e,Td),Zd=async e=>await Jd(e)??null,Qd=async(e,t)=>{await Bun.write(Xd(e),Od(t))},$d=async e=>{await _(Xd(e),{force:!0})},ef=async e=>{let t=(await Jd(e))?.sharedPrompts?.subscriptions;return t===void 0||t.length===0?[]:Fd(t,Td)},tf=`<!-- BEGIN Lzi Generated(工具维护,请勿手改;修改请编辑 .lzi/ 真源后运行 sync) -->`,nf=`<!-- END Lzi Generated -->`,rf=e=>{let t=e.trimEnd();return`${tf}\n${t}\n${nf}`},af=(e,t)=>{let n=rf(t);if(e===null)return`${n}\n`;let r=e.indexOf(tf),i=e.indexOf(nf);if(r===-1||i===-1||i<r)return`${n}\n\n${e.replace(/\n+$/,``)}\n`;let a=e.slice(i+26);return`${e.slice(0,r)}${n}${a}`},of=e=>{let t=e.indexOf(tf),n=e.indexOf(nf);return t===-1||n===-1||n<t?null:e.slice(t+62,n).replace(/^\n+/,``).trimEnd()},sf=e=>{let t=e.replace(/\r\n/g,`
|
|
259
|
+
`},kd=vl().regex(/^[a-z][a-z0-9-]*$/,`名称须为小写字母开头的小写字母/数字/连字符`),Ad=au([`agents`,`rules`,`commands`]).default(`agents`),jd=Yl(vl().min(1,`glob 不可为空`).refine(e=>!a(e),`禁止绝对路径形态的 glob`).refine(e=>!e.split(`/`).includes(`..`),`glob 禁止 .. 路径段`)).min(1,`glob 列表至少一条`),Md=Yl(Ql({name:kd,category:Ad,include:jd.nullable(),exclude:jd.nullable()})),Nd=e=>{if(e!==`agents`&&e!==`rules`&&e!==`commands`)throw Error(`类别 '${e}' 非法:仅支持 agents / rules / commands(见 docs/issues/0011、008)`);return e},Pd=e=>e.issues.map(e=>`${e.path.join(`.`)}: ${e.message}`).join(`; `),Fd=(e,t)=>{let n=Md.safeParse(e);if(!n.success)throw Error(`共享提示词订阅配置 ${t} 校验失败(以 zod 为运行时权威): ${Pd(n.error)}`);return n.data};var Id=class extends Error{configPath;constructor(e,t){super(e),this.name=`SharedConfigError`,this.configPath=t}},Ld=class extends Id{searchFrom;constructor(e){super(`未在 ${e} 及其上级目录中找到 lzi.config.ts 配置文件`,e),this.name=`SharedConfigNotFoundError`,this.searchFrom=e}},Rd=class extends Id{cause;constructor(e,t){super(`加载配置文件 ${e} 失败`,e),this.name=`SharedConfigLoadError`,this.cause=t}};function zd(e=process.cwd()){let n=s(e);for(;;){let e=o(n,`lzi.config.ts`);if(t(e))return e;let r=i(n);if(r===n)return null;n=r}}async function Bd(e={}){let t=e.cwd??process.cwd(),n=zd(t);if(n===null)throw new Ld(t);let r=s(n,`..`);try{return{config:(await import(n)).default,configPath:r,configFilePath:n}}catch(e){throw new Rd(n,e)}}function Vd(e,n=process.cwd()){let r=Array.isArray(e)?e:[e],a=s(n);for(;;){for(let e of r){let n=o(a,e);if(t(n))return n}let e=i(a);if(e===a)return null;a=e}}async function Hd(e={}){let t=e.cwd??s(process.cwd());if(e.standaloneFile){let n=Vd(e.standaloneFile,t);if(n)try{let e=await import(n);return{success:!0,config:e.default??e,source:`standalone`,configFilePath:n}}catch(e){throw new Rd(n,e)}}if(e.unifiedField)try{let{config:n,configFilePath:r}=await Bd({cwd:t}),i=n?.[e.unifiedField];if(i!==void 0)return{success:!0,config:i,source:`unified`,configFilePath:r}}catch{}return{success:!1,configFilePath:null}}const Ud=Ql({rules:Ql({trae:Ql({flatten:Ul().optional()})}).optional()}),Wd=e=>{if(e?.distribution===void 0)return!0;let t=Ud.safeParse(e.distribution);if(!t.success)throw Error(`distribution 配置段校验失败(以 zod 为运行时权威): ${t.error.issues.map(e=>`${e.path.join(`.`)}: ${e.message}`).join(`; `)}`);return t.data.rules?.trae?.flatten??!0},Gd=e=>Bu.some(t=>t===e),Kd=async(e,t)=>{let n=e.split(`,`),r=n.includes(Hu),i=n.filter(e=>e!==Hu&&e!==``);if(r&&i.length>0)throw Error(`${$.AGENT_TYPE} 值 '${e}' 非法:auto 与显式类型不可混用,请单独使用 auto 或逗号分隔的类型列表`);if(r)return[...await Wu(t)];if(i.length===0)return[];let a=/* @__PURE__ */ new Set;for(let e of i){if(!Gd(e))throw Error(`${$.AGENT_TYPE} 值 '${e}' 无效,合法值: ${Bu.join(`, `)}, ${Hu}`);if(a.has(e))throw Error(`${$.AGENT_TYPE} 值 '${e}' 重复,多值不可重复`);a.add(e)}return Bu.filter(e=>a.has(e))},qd=()=>{let e=process.env[$.AGENT_TYPE];return e===void 0||e===``?null:e},Jd=async e=>{let t=await Hd({standaloneFile:Td,unifiedField:`agentTools`,...e===void 0?{}:{cwd:e}});return t.success?t.config:void 0},Yd=async(e={})=>{let t=process.cwd(),n=await Jd(),r=e.agent??qd()??n?.agentType??``,i=r===``?[...await Wu(t)]:await Kd(r,t);return i.length===0&&(Q(`错误: 未指定目标 Agent 类型,且 auto 未推断到任何真源`),Q(`请运行 lzi-agent-cli init 创建 .lzi/ 骨架,或用 --agent / ${$.AGENT_TYPE} 指定类型`),Q(`合法值: ${Bu.join(`, `)}, ${Hu}`),process.exit(1)),{agentTypes:i,placeholders:n?.placeholders,rulesTraeFlatten:Wd(n)}},Xd=e=>o(e,Td),Zd=async e=>await Jd(e)??null,Qd=async(e,t)=>{await Bun.write(Xd(e),Od(t))},$d=async e=>{await _(Xd(e),{force:!0})},ef=async e=>{let t=(await Jd(e))?.sharedPrompts?.subscriptions;return t===void 0||t.length===0?[]:Fd(t,Td)},tf=`<!-- BEGIN Lzi Generated(工具维护,请勿手改;修改请编辑 .lzi/ 真源后运行 sync) -->`,nf=`<!-- END Lzi Generated -->`,rf=e=>{let t=e.trimEnd();return`${tf}\n${t}\n${nf}`},af=(e,t)=>{let n=rf(t);if(e===null)return`${n}\n`;let r=e.indexOf(tf),i=e.indexOf(nf);if(r===-1||i===-1||i<r)return`${n}\n\n${e.replace(/\n+$/,``)}\n`;let a=e.slice(i+26);return`${e.slice(0,r)}${n}${a}`},of=e=>{let t=e.indexOf(tf),n=e.indexOf(nf);return t===-1||n===-1||n<t?null:e.slice(t+62,n).replace(/^\n+/,``).trimEnd()},sf=e=>{let t=e.replace(/\r\n/g,`
|
|
260
260
|
`),n=t.split(`
|
|
261
261
|
`);if(n[0]!==`---`)return{frontmatter:``,body:t};for(let e=1;e<n.length;e+=1)if(n[e]===`---`)return{frontmatter:n.slice(0,e+1).join(`
|
|
262
262
|
`),body:n.slice(e+1).join(`
|
|
@@ -267,9 +267,9 @@ export default config;
|
|
|
267
267
|
`)},uf=e=>{let{frontmatter:t}=sf(e);return t!==``&&(/* @__PURE__ */ RegExp(`^lzi: true$`,`m`)).test(t)},df=e=>e.includes(tf),ff=async e=>{try{return(await y(e)).isDirectory()}catch{return!1}},pf=async(e,t,n={})=>{let r=process.env[$.PROMPTS_ROOT],i=[...r!==void 0&&r!==``?[{source:`env`,path:s(r)}]:[],...n.explicitPath===void 0?[]:[{source:`explicit`,path:s(t,n.explicitPath)}],{source:`convention`,path:s(t,`..`,e)}],a=[];for(let e of i)if(a.push(`${e.source}: ${e.path}`),await ff(e.path))return{hubRoot:e.path,source:e.source};throw Error(`共享提示词中心仓 '${e}' 定位失败,已尝试:\n ${a.join(`
|
|
268
268
|
`)}\n请在项目 .env 中设置 ${$.PROMPTS_ROOT}=<hub 根绝对路径>(机器本地,不进 git),或确认 hub 已 clone 到约定位置 ../${e}`)},mf=e=>`hub: '${e.replace(/\\/g,`\\\\`).replace(/'/g,`\\'`)}'`,hf=(e,t)=>{let n=mf(t),r=e.split(`
|
|
269
269
|
`);if(r[0]===`---`){let e=r.indexOf(`---`,1);if(e!==-1)return[`---`,n,...r.slice(1,e).filter(e=>!e.trim().startsWith(`hub: '`)),...r.slice(e)].join(`
|
|
270
|
-
`)}return`---\n${n}\n---\n\n${e}`},gf=e=>{let{frontmatter:t}=sf(e);if(t===``)return null;let n=(/* @__PURE__ */ RegExp(`^hub: '([^']+)'$`,`m`)).exec(t);return n===null?null:n[1]??null},_f=async(e,t)=>{let n=Fu(t.category),r=o(e,n),i=[],a=[];try{let e=new Bun.Glob(`*.md`);for await(let t of e.scan({cwd:r,onlyFiles:!0}))i.push(t);let t=new Bun.Glob(`**/*.md`);for await(let e of t.scan({cwd:r,onlyFiles:!0}))a.push(e)}catch{throw Error(`hub ${t.category} 类别条目库目录不存在: ${r}`)}if(i.length>0)throw Error(`hub ${t.category} 类别条目库根存在平铺 .md(${n}/${i[0]} 等 ${i.length} 个):必须按主题目录组织(目录结构端到端保留,见 docs/issues/0011)`);return a.sort().filter(e=>t.include===null||t.include.some(t=>new Bun.Glob(t).match(e))?!(t.exclude!==null&&t.exclude.some(t=>new Bun.Glob(t).match(e))):!1)},vf=async e=>{let t=/* @__PURE__ */ new Map,n=new Bun.Glob(`**/*.md`);try{for await(let r of n.scan({cwd:e,onlyFiles:!0}))t.set(r,await Bun.file(o(e,r)).text())}catch{return t}return t},yf=async(e,t,n)=>{let r=await _f(e,t),i=o(n,Iu(t.category)),a=await vf(i);return r.filter(e=>a.has(e)?gf(a.get(e)??``)!==t.name:!1)},bf=async(e,t)=>_f(e,t),xf=async(e,t)=>{let n=o(e,Iu(t.category)),r=[...(await vf(n)).entries()].filter(([,e])=>gf(e)===t.name).map(([e])=>e);for(let e of r)await _(o(n,e),{force:!0}),await Sf(n,e);try{await v(n)}catch{}return r.length},Sf=async(e,t)=>{let n=i(o(e,t));for(;n.startsWith(e)&&n!==e;){try{await v(n)}catch{return}n=i(n)}},Cf=async(e,t)=>{let n=await ef(e);if(n.length===0)return{skipped:!0,results:[],hasError:!1,hasDrift:!1};let r=[];for(let a of n){let n=await(async()=>{try{let{hubRoot:n}=await pf(a.name,e),r=await _f(n,a),s=o(e,Iu(a.category));if(t===`plan`)return{subscription:a,hubRoot:n,matchedCount:r.length,staleCount:0,status:`planned`,drift:[],message:null};let c=/* @__PURE__ */ new Map;for(let e of r){let t=await Bun.file(o(n,Fu(a.category),e)).text();c.set(e,hf(t,a.name))}let l=await vf(s),u=[...c.keys()].filter(e=>l.has(e)&&gf(l.get(e)??``)!==a.name);if(u.length>0)throw Error(`命中路径被本地文件占用(无 hub 标记,物化会覆盖本地内容): `+u.map(e=>`${Iu(a.category)}/${e}`).join(`, `)+`。请迁移本地文件或调整订阅 include/exclude`);let d=[...l.entries()].filter(([,e])=>gf(e)===a.name).filter(([e])=>!c.has(e)).map(([e])=>e);if(t===`write`){for(let e of d)await _(o(s,e),{force:!0}),await Sf(s,e);for(let[e,t]of c)await g(i(o(s,e)),{recursive:!0}),await Bun.write(o(s,e),t);return{subscription:a,hubRoot:n,matchedCount:r.length,staleCount:d.length,status:`materialized`,drift:[],message:null}}let f=[];for(let[e,t]of c)l.has(e)?l.get(e)!==t&&f.push(`changed: ${e}`):f.push(`missing: ${e}`);for(let e of d)f.push(`stale: ${e}`);return{subscription:a,hubRoot:n,matchedCount:r.length,staleCount:d.length,status:f.length>0?`drifted`:`clean`,drift:f.sort(),message:null}}catch(e){return{subscription:a,hubRoot:null,matchedCount:0,staleCount:0,status:`error`,drift:[],message:e instanceof Error?e.message:String(e)}}})();r.push(n)}return{skipped:!1,results:r,hasError:r.some(e=>e.status===`error`),hasDrift:r.some(e=>e.status===`drifted`)}},wf=e=>{if(e===void 0)return null;let t=e.split(`,`).map(e=>e.trim()).filter(e=>e!==``);return t.length>0?t:null},Tf=async(e,t)=>{let n=Bun.file(o(e,`.env`)),r=await n.exists()?await n.text():null,i=`${$.PROMPTS_ROOT}=${t}`;if(r===null){await Bun.write(o(e,`.env`),`${i}\n`);return}let a=RegExp(`^${$.PROMPTS_ROOT}=.*$`,`m`);if(a.test(r)){let t=r.replace(a,i);t!==r&&await Bun.write(o(e,`.env`),t);return}await Bun.write(o(e,`.env`),`${r.replace(/\n+$/,``)}\n${i}\n`)},Ef=async e=>{let t=Bun.file(o(e,`.env.example`)),n=await t.exists()?await t.text():null,r=`${$.PROMPTS_ROOT}=/absolute/path/to/longzai-intelligence-agent-prompts`;if(!(n!==null&&n.includes(`${$.PROMPTS_ROOT}=`))){if(n===null){await Bun.write(o(e,`.env.example`),`${r}\n`);return}await Bun.write(o(e,`.env.example`),`${n.replace(/\n+$/,``)}\n${r}\n`)}},Df=async e=>{let t=[$.PROMPTS_ROOT,`LZI_AGENT_TOOLS_SHARED_PROMPTS_ROOT`];for(let n of[`.env`,`.env.example`]){let r=Bun.file(o(e,n));if(!await r.exists())continue;let i=await r.text(),a=i;for(let e of t)a=a.replace(RegExp(`^${e}=.*\\n?`,`m`),``);a!==i&&await Bun.write(o(e,n),a)}},Of=async e=>{let t;try{t=await Bun.file(o(e,`package.json`)).json()}catch{return}let n={...t.dependencies,...t.devDependencies};`@longzai-intelligence-agent-tools/config`in n||`@longzai-intelligence-agent-tools/core`in n||`@longzai-intelligence-agent-tools/cli`in n||Z(`${X.YELLOW}提示: 项目未声明 @longzai-intelligence-agent-tools/config 依赖,配置文件的 IDE 静态检查不可用(运行不受影响,type-only import 运行时擦除)${X.RESET}`)},kf=(e,t)=>({...e?.agentType===void 0?{}:{agentType:e.agentType},...e?.placeholders===void 0?{}:{placeholders:e.placeholders},...e?.distribution===void 0?{}:{distribution:e.distribution},...t.length===0?{}:{sharedPrompts:{subscriptions:t}}}),Af=async e=>{let t=process.cwd(),n=e.hub??`longzai-intelligence-agent-prompts`,r=Nd(e.category??`agents`),i=await Zd(t),a=await ef(t),s=a.find(e=>e.name!==n);if(s!==void 0)throw Error(`v1 每项目仅支持订阅单一 hub,当前已订阅 '${s.name}';多 hub 支持规划中`);let c=a.find(e=>e.name===n&&e.category===r)??null,{hubRoot:l,source:u}=await pf(n,t,{explicitPath:e.path});await Tf(t,l),await Ef(t);let d={name:n,category:r,include:wf(e.include),exclude:wf(e.exclude)};if(!await ff(o(l,Fu(r))))Z(`${X.YELLOW}提示: hub ${r} 类别条目库目录 ${Fu(r)}/ 不存在,本次订阅将物化 0 个条目${X.RESET}`);else{await bf(l,d);let e=await yf(l,d,t);if(e.length>0&&c===null)throw Error(`命中路径被本地文件占用(无 hub 元信息标记,物化会覆盖本地内容): `+e.map(e=>`${Iu(r)}/${e}`).join(`, `)+`。请迁移本地文件或调整订阅 include/exclude`)}let f=[...a.filter(e=>e.name!==n||e.category!==r),d];await Qd(t,kf(i,f)),await Of(t);let p=c===null?`已注册`:`已更新`;Z(``),Z(`${X.GREEN}✓ ${p}共享提示词订阅(单端,hub 零写入)${X.RESET}`),Z(` hub: ${n}(定位: ${u})`),Z(` 类别: ${r}`),Z(` 物化根: ${Iu(r)}/(按 hub 主题目录平铺,副本入库)`),Z(` 范围: ${d.include===null?`全部条目`:d.include.join(`, `)}${d.exclude===null?``:`(排除 ${d.exclude.join(`, `)})`}`),Z(` 单端写入: ${Td}`),Z(` 位置固化: .env ${$.PROMPTS_ROOT}(机器本地,不进 git)+ .env.example 占位条目`),Z(`${X.YELLOW}运行 lzi-agent-cli sync 物化共享内容(物化副本入库,请随项目提交)并合成${X.RESET}`)},jf=async e=>{let t=process.cwd(),n=e.category===void 0?void 0:Nd(e.category),r=await ef(t);if(r.length===0){Z(`当前项目未注册共享提示词订阅`);return}let i;if(n!==void 0){if(i=r.filter(e=>e.category===n),i.length===0)throw Error(`类别 '${n}' 未订阅;当前订阅: `+r.map(e=>e.category).join(`, `))}else if(r.length===1)i=r;else throw Error(`存在多个订阅,请用 --category 指定: `+r.map(e=>e.category).join(`, `));let a=r.filter(e=>!i.includes(e));for(let e of i){let n=await xf(t,e);Z(` 已清理 ${e.category} 类别物化文件 ${n} 个`)}let o=await Bun.file(Xd(t)).exists(),s=await Zd(t),c=kf(s,a),l=c.agentType===void 0&&c.placeholders===void 0&&c.sharedPrompts===void 0;l&&!o||(l?await $d(t):await Qd(t,c)),a.length===0&&await Df(t),Z(``),Z(`${X.GREEN}✓ 已注销共享提示词订阅${X.RESET}`),Z(` 移除订阅类别: ${i.map(e=>e.category).join(`, `)}`),Z(` 物化文件删除请随本次变更提交`),a.length>0&&Z(` 保留订阅类别: ${a.map(e=>e.category).join(`, `)}`)},Mf=e=>e===`clean`?`${X.GREEN}物化一致${X.RESET}`:e===`drifted`?`${X.RED}存在漂移${X.RESET}`:e===`planned`?`待物化`:`${X.RED}定位失败${X.RESET}`,Nf=async()=>{let e=process.cwd(),t=await ef(e);if(t.length===0){Z(`当前项目未注册共享提示词订阅(运行 lzi-agent-cli shared register 注册)`);return}Z(`${X.BLUE}=== 共享提示词订阅(${t.length} 个) ===${X.RESET}\n`);let n=await Cf(e,`check`);for(let e of n.results){let t=e.subscription.include===null?`全部条目`:e.subscription.include.join(`, `);Z(`${X.GREEN}${e.subscription.category}${X.RESET} ← ${e.subscription.name}(${t})`),Z(` 状态: ${Mf(e.status)},命中 ${e.matchedCount} 个条目${e.staleCount>0?`,孤儿 ${e.staleCount} 个`:``}${e.hubRoot===null?``:`,hub: ${e.hubRoot}`}`),e.status===`error`&&e.message!==null&&Z(` ${X.RED}${e.message}${X.RESET}`);for(let t of e.drift)Z(` ${X.RED}${t}${X.RESET}`)}n.hasDrift&&(Z(``),Z(`${X.YELLOW}存在物化漂移:运行 lzi-agent-cli sync 对账重建共享内容${X.RESET}`))},Pf=$l({hub:vl().optional(),category:vl().optional(),include:vl().optional(),exclude:vl().optional(),path:vl().optional()}),Ff=$l({category:vl().optional()}),If=e=>{let t=e.command(`shared`).description(`共享提示词中心仓订阅管理`);gt(t,{name:`register`,description:`注册/更新当前项目对共享提示词中心仓的订阅(单端写入,hub 零写入)`,options:[{flags:`--hub <name>`,description:`hub 仓库名(默认 longzai-intelligence-agent-prompts)`},{flags:`--category <category>`,description:`订阅类别:agents = 根指令条目(默认);rules = 项目规则(.trae/rules 真源集中化)`},{flags:`--include <globs>`,description:`订阅范围 glob(逗号分隔,如 lang/**,git/**;缺省全部)`},{flags:`--exclude <globs>`,description:`排除 glob(逗号分隔)`},{flags:`--path <path>`,description:`hub 相对路径(相对项目根;缺省走解析链)`}],schema:Pf,action:async e=>{let t={hub:e.hub,category:e.category,include:e.include,exclude:e.exclude,path:e.path};await Af(t)}}),gt(t,{name:`unregister`,description:`注销订阅(移除订阅 + 按元信息标记清理物化文件)`,options:[{flags:`--category <category>`,description:`待移除的订阅类别(agents/rules;多订阅时必填)`}],schema:Ff,action:async e=>{let t={category:e.category};await jf(t)}}),gt(t,{name:`status`,description:`查看订阅健康度(项目根;hub 定位、命中条数、物化漂移)`,schema:Zl({}),action:async()=>{await Nf()}})},Lf=`${X.GREEN}存在${X.RESET}`,Rf=`${X.RED}缺失${X.RESET}`,zf=e=>Bu.some(t=>t===e),Bf=async e=>Bun.file(e).exists(),Vf=async()=>{let e=process.cwd(),t=o(e,Y),n=process.env[$.AGENT_TYPE];Z(`${X.BLUE}=== Agent Tools 状态 ===${X.RESET}\n`);let r;n===void 0||n===``?(r=await Wu(e),r.length>0?Z(`当前 Agent: ${X.GREEN}auto → ${r.join(`, `)}${X.RESET}(默认,按真源推断)`):Z(`当前 Agent: ${X.YELLOW}auto → 未推断到真源${X.RESET}(请运行 lzi-agent-cli init)`)):zf(n)?(r=[n],Z(`当前 Agent: ${X.GREEN}${n}${X.RESET}(环境变量 ${$.AGENT_TYPE})`)):(r=await Wu(e),Z(`当前 Agent: ${X.RED}${n}(无效,合法值: ${Bu.join(`, `)})${X.RESET}`)),Z(``),Z(`${X.BLUE}源文件(${t}):${X.RESET}`);let i=/* @__PURE__ */ new Set;i.add(Nu);for(let e of r)for(let t of Ru[e])i.add(t.agentSource);for(let e of i){let n=o(t,e);Z(` ${e}: ${await Bf(n)?Lf:Rf}`)}if(Z(``),r.length>0){Z(`${X.BLUE}输出目标(将覆盖):${X.RESET}`);let t=/* @__PURE__ */ new Set;for(let e of r)for(let n of Ru[e])t.add(n.output);for(let n of t){let t=o(e,n);Z(` ${n}: ${await Bf(t)?Lf:Rf}`)}}else Z(`${X.YELLOW}Agent 类型未配置,无法显示输出目标${X.RESET}`);Z(``),Z(`${X.BLUE}类别配置目录(${t} 下):${X.RESET}`);for(let e of Object.keys(zu)){let n=o(t,e);Z(` ${e}/: ${await Bf(n)?Lf:Rf}`)}},Hf=/\{\{([A-Z][A-Z0-9_]*)\}\}/g,Uf=()=>{let e={};for(let[t,n]of Object.entries(process.env))if(t.startsWith($.PLACEHOLDER_PREFIX)&&n!==void 0){let r=t.slice($.PLACEHOLDER_PREFIX.length);e[r]=n}return e},Wf=()=>{let e={};for(let[t,n]of Object.entries(Vu))e[t]=n();return e},Gf=e=>{let t=Wf(),n=Uf();return{...t,...n,...e}},Kf=(e,t)=>e.replace(Hf,(e,n)=>t[n]??e),qf=async e=>{let t=Bun.file(e);return await t.exists()?t.text():null},Jf=async e=>{try{return await y(e),!0}catch{return!1}},Yf=async(e,t,n)=>{let r=new Bun.Glob(t),i=[];for await(let t of r.scan({cwd:e,onlyFiles:n}))i.push(t);return i.sort()},Xf=e=>{let t=e.replace(/\.md$/,``);for(let e of Bu){let n=`.${e}`;if(t.endsWith(n))return{baseRelPath:`${t.slice(0,-n.length)}.md`,isSpecific:!0,specificType:e}}return{baseRelPath:e,isSpecific:!1,specificType:null}},Zf=(e,t,n)=>e===``&&t===``?``:t===``?`${e.trimEnd()}\n`:e===``?`${t.trimEnd()}\n`:n===`prepend`?`${t.trimEnd()}\n\n${e.trimEnd()}\n`:`${e.trimEnd()}\n\n${t.trimEnd()}\n`,Qf=async(e,t,n,i,a)=>{let s=zu[e];if(!s)return[];let c=s[t];if(!c)return[];let l=o(n,Y,e);if(!await Jf(l))return[];let u=await Yf(l,`**/*.md`,!0),d=/* @__PURE__ */ new Map;for(let e of u){let{baseRelPath:t,isSpecific:n,specificType:r}=Xf(e);d.has(t)||d.set(t,{common:null,specifics:/* @__PURE__ */ new Map});let i=d.get(t);i!==void 0&&(n&&r?i.specifics.set(r,e):i.common=e)}let f=[];for(let[n,{common:s,specifics:u}]of d){let d=u.get(t)??null,p=s===null?null:o(l,s),m=d===null?null:o(l,d);if(p===null&&m===null)continue;let h=p===null?``:await qf(p)??``,g=m===null?``:await qf(m)??``,_=Zf(h,g,c.mode),v=Kf(_,i),y=e===`rules`&&t===`trae`&&a.rulesTraeFlatten?r(n):n,b=o(c.ideRoot,e,y);f.push({category:e,agentType:t,output:b,content:v,commonSourcePath:p,agentSourcePath:m})}return f},$f=async(e,t,n,r)=>{let i=o(t,Y);if(!await Jf(i))return[];let a=(await Yf(i,`*/`,!1)).map(e=>e.replace(/\/$/,``)),s=[];for(let i of a){if(!zu[i])continue;let a=await Qf(i,e,t,n,r);s.push(...a)}let c=/* @__PURE__ */ new Map;for(let e of s){let t=`${e.category}:${e.agentType} ← ${e.commonSourcePath??e.agentSourcePath??``}`,n=c.get(e.output);if(n!==void 0)throw Error(`平铺分发产物路径重复(真源命名碰撞): ${e.output}\n ${n}\n ${t}\n请在真源侧重命名(主题目录组织下避免跨主题同名),或经 distribution.rules.trae.flatten: false 保留目录层级`);c.set(e.output,t)}return s},ep=e=>{let t=[],n=new Set(e[0]?.itemsSources??[]);for(let r of e){let e=new Set(r.itemsSources);for(let n of e)t.includes(n)||t.push(n);for(let t of n)e.has(t)||n.delete(t)}return t.filter(e=>!n.has(e))},tp=e=>{let t=/* @__PURE__ */ new Map;for(let n of e){let e=t.get(n.output);e===void 0?t.set(n.output,[n]):e.push(n)}let n=[];for(let[e,r]of t){let t=r[0];t!==void 0&&r.some(e=>e.content.trimEnd()!==t.content.trimEnd())&&n.push({output:e,entries:r,differingItems:ep(r)})}return n},np=/* @__PURE__ */ new Set([`order`,`hub`]),rp=async e=>{try{return await y(e),!0}catch{return!1}},ip=async e=>Bun.file(e).text(),ap=async e=>{let t=new Bun.Glob(`**/*.md`),n=[];for await(let r of t.scan({cwd:e,onlyFiles:!0}))n.push(r);return n.sort()},op=(e,t)=>{if(e===``)return null;let n=e.split(`
|
|
270
|
+
`)}return`---\n${n}\n---\n\n${e}`},gf=e=>{let{frontmatter:t}=sf(e);if(t===``)return null;let n=(/* @__PURE__ */ RegExp(`^hub: '([^']+)'$`,`m`)).exec(t);return n===null?null:n[1]??null},_f=async(e,t)=>{let n=Fu(t.category),r=o(e,n),i=[],a=[];try{let e=new Bun.Glob(`*.md`);for await(let t of e.scan({cwd:r,onlyFiles:!0}))i.push(t);let t=new Bun.Glob(`**/*.md`);for await(let e of t.scan({cwd:r,onlyFiles:!0}))a.push(e)}catch{throw Error(`hub ${t.category} 类别条目库目录不存在: ${r}`)}if(i.length>0)throw Error(`hub ${t.category} 类别条目库根存在平铺 .md(${n}/${i[0]} 等 ${i.length} 个):必须按主题目录组织(目录结构端到端保留,见 docs/issues/0011)`);return a.sort().filter(e=>t.include===null||t.include.some(t=>new Bun.Glob(t).match(e))?!(t.exclude!==null&&t.exclude.some(t=>new Bun.Glob(t).match(e))):!1)},vf=async e=>{let t=/* @__PURE__ */ new Map,n=new Bun.Glob(`**/*.md`);try{for await(let r of n.scan({cwd:e,onlyFiles:!0}))t.set(r,await Bun.file(o(e,r)).text())}catch{return t}return t},yf=async(e,t,n)=>{let r=await _f(e,t),i=o(n,Iu(t.category)),a=await vf(i);return r.filter(e=>a.has(e)?gf(a.get(e)??``)!==t.name:!1)},bf=async(e,t)=>_f(e,t),xf=async(e,t)=>{let n=o(e,Iu(t.category)),r=[...(await vf(n)).entries()].filter(([,e])=>gf(e)===t.name).map(([e])=>e);for(let e of r)await _(o(n,e),{force:!0}),await Sf(n,e);try{await v(n)}catch{}return r.length},Sf=async(e,t)=>{let n=i(o(e,t));for(;n.startsWith(e)&&n!==e;){try{await v(n)}catch{return}n=i(n)}},Cf=async(e,t)=>{let n=await ef(e);if(n.length===0)return{skipped:!0,results:[],hasError:!1,hasDrift:!1};let r=[];for(let a of n){let n=await(async()=>{try{let{hubRoot:n}=await pf(a.name,e),r=await _f(n,a),s=o(e,Iu(a.category));if(t===`plan`)return{subscription:a,hubRoot:n,matchedCount:r.length,staleCount:0,status:`planned`,drift:[],message:null};let c=/* @__PURE__ */ new Map;for(let e of r){let t=await Bun.file(o(n,Fu(a.category),e)).text();c.set(e,hf(t,a.name))}let l=await vf(s),u=[...c.keys()].filter(e=>l.has(e)&&gf(l.get(e)??``)!==a.name);if(u.length>0)throw Error(`命中路径被本地文件占用(无 hub 标记,物化会覆盖本地内容): `+u.map(e=>`${Iu(a.category)}/${e}`).join(`, `)+`。请迁移本地文件或调整订阅 include/exclude`);let d=[...l.entries()].filter(([,e])=>gf(e)===a.name).filter(([e])=>!c.has(e)).map(([e])=>e);if(t===`write`){for(let e of d)await _(o(s,e),{force:!0}),await Sf(s,e);for(let[e,t]of c)await g(i(o(s,e)),{recursive:!0}),await Bun.write(o(s,e),t);return{subscription:a,hubRoot:n,matchedCount:r.length,staleCount:d.length,status:`materialized`,drift:[],message:null}}let f=[];for(let[e,t]of c)l.has(e)?l.get(e)!==t&&f.push(`changed: ${e}`):f.push(`missing: ${e}`);for(let e of d)f.push(`stale: ${e}`);return{subscription:a,hubRoot:n,matchedCount:r.length,staleCount:d.length,status:f.length>0?`drifted`:`clean`,drift:f.sort(),message:null}}catch(e){return{subscription:a,hubRoot:null,matchedCount:0,staleCount:0,status:`error`,drift:[],message:e instanceof Error?e.message:String(e)}}})();r.push(n)}return{skipped:!1,results:r,hasError:r.some(e=>e.status===`error`),hasDrift:r.some(e=>e.status===`drifted`)}},wf=e=>{if(e===void 0)return null;let t=e.split(`,`).map(e=>e.trim()).filter(e=>e!==``);return t.length>0?t:null},Tf=async(e,t)=>{let n=Bun.file(o(e,`.env`)),r=await n.exists()?await n.text():null,i=`${$.PROMPTS_ROOT}=${t}`;if(r===null){await Bun.write(o(e,`.env`),`${i}\n`);return}let a=RegExp(`^${$.PROMPTS_ROOT}=.*$`,`m`);if(a.test(r)){let t=r.replace(a,i);t!==r&&await Bun.write(o(e,`.env`),t);return}await Bun.write(o(e,`.env`),`${r.replace(/\n+$/,``)}\n${i}\n`)},Ef=async e=>{let t=Bun.file(o(e,`.env.example`)),n=await t.exists()?await t.text():null,r=`${$.PROMPTS_ROOT}=/absolute/path/to/longzai-intelligence-agent-prompts`;if(!(n!==null&&n.includes(`${$.PROMPTS_ROOT}=`))){if(n===null){await Bun.write(o(e,`.env.example`),`${r}\n`);return}await Bun.write(o(e,`.env.example`),`${n.replace(/\n+$/,``)}\n${r}\n`)}},Df=async e=>{let t=[$.PROMPTS_ROOT,`LZI_AGENT_TOOLS_SHARED_PROMPTS_ROOT`];for(let n of[`.env`,`.env.example`]){let r=Bun.file(o(e,n));if(!await r.exists())continue;let i=await r.text(),a=i;for(let e of t)a=a.replace(RegExp(`^${e}=.*\\n?`,`m`),``);a!==i&&await Bun.write(o(e,n),a)}},Of=async e=>{let t;try{t=await Bun.file(o(e,`package.json`)).json()}catch{return}let n={...t.dependencies,...t.devDependencies};`@longzai-intelligence-agent-tools/config`in n||`@longzai-intelligence-agent-tools/core`in n||`@longzai-intelligence-agent-tools/cli`in n||Z(`${X.YELLOW}提示: 项目未声明 @longzai-intelligence-agent-tools/config 依赖,配置文件的 IDE 静态检查不可用(运行不受影响,type-only import 运行时擦除)${X.RESET}`)},kf=(e,t)=>({...e?.agentType===void 0?{}:{agentType:e.agentType},...e?.placeholders===void 0?{}:{placeholders:e.placeholders},...e?.distribution===void 0?{}:{distribution:e.distribution},...t.length===0?{}:{sharedPrompts:{subscriptions:t}}}),Af=async e=>{let t=process.cwd(),n=e.hub??`longzai-intelligence-agent-prompts`,r=Nd(e.category??`agents`),i=await Zd(t),a=await ef(t),s=a.find(e=>e.name!==n);if(s!==void 0)throw Error(`v1 每项目仅支持订阅单一 hub,当前已订阅 '${s.name}';多 hub 支持规划中`);let c=a.find(e=>e.name===n&&e.category===r)??null,{hubRoot:l,source:u}=await pf(n,t,{explicitPath:e.path});await Tf(t,l),await Ef(t);let d={name:n,category:r,include:wf(e.include),exclude:wf(e.exclude)};if(!await ff(o(l,Fu(r))))Z(`${X.YELLOW}提示: hub ${r} 类别条目库目录 ${Fu(r)}/ 不存在,本次订阅将物化 0 个条目${X.RESET}`);else{await bf(l,d);let e=await yf(l,d,t);if(e.length>0&&c===null)throw Error(`命中路径被本地文件占用(无 hub 元信息标记,物化会覆盖本地内容): `+e.map(e=>`${Iu(r)}/${e}`).join(`, `)+`。请迁移本地文件或调整订阅 include/exclude`)}let f=[...a.filter(e=>e.name!==n||e.category!==r),d];await Qd(t,kf(i,f)),await Of(t);let p=c===null?`已注册`:`已更新`;Z(``),Z(`${X.GREEN}✓ ${p}共享提示词订阅(单端,hub 零写入)${X.RESET}`),Z(` hub: ${n}(定位: ${u})`),Z(` 类别: ${r}`),Z(` 物化根: ${Iu(r)}/(按 hub 主题目录平铺,副本入库)`),Z(` 范围: ${d.include===null?`全部条目`:d.include.join(`, `)}${d.exclude===null?``:`(排除 ${d.exclude.join(`, `)})`}`),Z(` 单端写入: ${Td}`),Z(` 位置固化: .env ${$.PROMPTS_ROOT}(机器本地,不进 git)+ .env.example 占位条目`),Z(`${X.YELLOW}运行 lzi-agent-cli sync 物化共享内容(物化副本入库,请随项目提交)并合成${X.RESET}`)},jf=async e=>{let t=process.cwd(),n=e.category===void 0?void 0:Nd(e.category),r=await ef(t);if(r.length===0){Z(`当前项目未注册共享提示词订阅`);return}let i;if(n!==void 0){if(i=r.filter(e=>e.category===n),i.length===0)throw Error(`类别 '${n}' 未订阅;当前订阅: `+r.map(e=>e.category).join(`, `))}else if(r.length===1)i=r;else throw Error(`存在多个订阅,请用 --category 指定: `+r.map(e=>e.category).join(`, `));let a=r.filter(e=>!i.includes(e));for(let e of i){let n=await xf(t,e);Z(` 已清理 ${e.category} 类别物化文件 ${n} 个`)}let o=await Bun.file(Xd(t)).exists(),s=await Zd(t),c=kf(s,a),l=c.agentType===void 0&&c.placeholders===void 0&&c.sharedPrompts===void 0;l&&!o||(l?await $d(t):await Qd(t,c)),a.length===0&&await Df(t),Z(``),Z(`${X.GREEN}✓ 已注销共享提示词订阅${X.RESET}`),Z(` 移除订阅类别: ${i.map(e=>e.category).join(`, `)}`),Z(` 物化文件删除请随本次变更提交`),a.length>0&&Z(` 保留订阅类别: ${a.map(e=>e.category).join(`, `)}`)},Mf=e=>e===`clean`?`${X.GREEN}物化一致${X.RESET}`:e===`drifted`?`${X.RED}存在漂移${X.RESET}`:e===`planned`?`待物化`:`${X.RED}定位失败${X.RESET}`,Nf=async()=>{let e=process.cwd(),t=await ef(e);if(t.length===0){Z(`当前项目未注册共享提示词订阅(运行 lzi-agent-cli shared register 注册)`);return}Z(`${X.BLUE}=== 共享提示词订阅(${t.length} 个) ===${X.RESET}\n`);let n=await Cf(e,`check`);for(let e of n.results){let t=e.subscription.include===null?`全部条目`:e.subscription.include.join(`, `);Z(`${X.GREEN}${e.subscription.category}${X.RESET} ← ${e.subscription.name}(${t})`),Z(` 状态: ${Mf(e.status)},命中 ${e.matchedCount} 个条目${e.staleCount>0?`,孤儿 ${e.staleCount} 个`:``}${e.hubRoot===null?``:`,hub: ${e.hubRoot}`}`),e.status===`error`&&e.message!==null&&Z(` ${X.RED}${e.message}${X.RESET}`);for(let t of e.drift)Z(` ${X.RED}${t}${X.RESET}`)}n.hasDrift&&(Z(``),Z(`${X.YELLOW}存在物化漂移:运行 lzi-agent-cli sync 对账重建共享内容${X.RESET}`))},Pf=$l({hub:vl().optional(),category:vl().optional(),include:vl().optional(),exclude:vl().optional(),path:vl().optional()}),Ff=$l({category:vl().optional()}),If=e=>{let t=e.command(`shared`).description(`共享提示词中心仓订阅管理`);gt(t,{name:`register`,description:`注册/更新当前项目对共享提示词中心仓的订阅(单端写入,hub 零写入)`,options:[{flags:`--hub <name>`,description:`hub 仓库名(默认 longzai-intelligence-agent-prompts)`},{flags:`--category <category>`,description:`订阅类别:agents = 根指令条目(默认);rules = 项目规则;commands = 自定义命令(.trae/commands 真源集中化)`},{flags:`--include <globs>`,description:`订阅范围 glob(逗号分隔,如 lang/**,git/**;缺省全部)`},{flags:`--exclude <globs>`,description:`排除 glob(逗号分隔)`},{flags:`--path <path>`,description:`hub 相对路径(相对项目根;缺省走解析链)`}],schema:Pf,action:async e=>{let t={hub:e.hub,category:e.category,include:e.include,exclude:e.exclude,path:e.path};await Af(t)}}),gt(t,{name:`unregister`,description:`注销订阅(移除订阅 + 按元信息标记清理物化文件)`,options:[{flags:`--category <category>`,description:`待移除的订阅类别(agents/rules/commands;多订阅时必填)`}],schema:Ff,action:async e=>{let t={category:e.category};await jf(t)}}),gt(t,{name:`status`,description:`查看订阅健康度(项目根;hub 定位、命中条数、物化漂移)`,schema:Zl({}),action:async()=>{await Nf()}})},Lf=`${X.GREEN}存在${X.RESET}`,Rf=`${X.RED}缺失${X.RESET}`,zf=e=>Bu.some(t=>t===e),Bf=async e=>Bun.file(e).exists(),Vf=async()=>{let e=process.cwd(),t=o(e,Y),n=process.env[$.AGENT_TYPE];Z(`${X.BLUE}=== Agent Tools 状态 ===${X.RESET}\n`);let r;n===void 0||n===``?(r=await Wu(e),r.length>0?Z(`当前 Agent: ${X.GREEN}auto → ${r.join(`, `)}${X.RESET}(默认,按真源推断)`):Z(`当前 Agent: ${X.YELLOW}auto → 未推断到真源${X.RESET}(请运行 lzi-agent-cli init)`)):zf(n)?(r=[n],Z(`当前 Agent: ${X.GREEN}${n}${X.RESET}(环境变量 ${$.AGENT_TYPE})`)):(r=await Wu(e),Z(`当前 Agent: ${X.RED}${n}(无效,合法值: ${Bu.join(`, `)})${X.RESET}`)),Z(``),Z(`${X.BLUE}源文件(${t}):${X.RESET}`);let i=/* @__PURE__ */ new Set;i.add(Nu);for(let e of r)for(let t of Ru[e])i.add(t.agentSource);for(let e of i){let n=o(t,e);Z(` ${e}: ${await Bf(n)?Lf:Rf}`)}if(Z(``),r.length>0){Z(`${X.BLUE}输出目标(将覆盖):${X.RESET}`);let t=/* @__PURE__ */ new Set;for(let e of r)for(let n of Ru[e])t.add(n.output);for(let n of t){let t=o(e,n);Z(` ${n}: ${await Bf(t)?Lf:Rf}`)}}else Z(`${X.YELLOW}Agent 类型未配置,无法显示输出目标${X.RESET}`);Z(``),Z(`${X.BLUE}类别配置目录(${t} 下):${X.RESET}`);for(let e of Object.keys(zu)){let n=o(t,e);Z(` ${e}/: ${await Bf(n)?Lf:Rf}`)}},Hf=/\{\{([A-Z][A-Z0-9_]*)\}\}/g,Uf=()=>{let e={};for(let[t,n]of Object.entries(process.env))if(t.startsWith($.PLACEHOLDER_PREFIX)&&n!==void 0){let r=t.slice($.PLACEHOLDER_PREFIX.length);e[r]=n}return e},Wf=()=>{let e={};for(let[t,n]of Object.entries(Vu))e[t]=n();return e},Gf=e=>{let t=Wf(),n=Uf();return{...t,...n,...e}},Kf=(e,t)=>e.replace(Hf,(e,n)=>t[n]??e),qf=async e=>{let t=Bun.file(e);return await t.exists()?t.text():null},Jf=async e=>{try{return await y(e),!0}catch{return!1}},Yf=async(e,t,n)=>{let r=new Bun.Glob(t),i=[];for await(let t of r.scan({cwd:e,onlyFiles:n}))i.push(t);return i.sort()},Xf=e=>{let t=e.replace(/\.md$/,``);for(let e of Bu){let n=`.${e}`;if(t.endsWith(n))return{baseRelPath:`${t.slice(0,-n.length)}.md`,isSpecific:!0,specificType:e}}return{baseRelPath:e,isSpecific:!1,specificType:null}},Zf=(e,t,n)=>e===``&&t===``?``:t===``?`${e.trimEnd()}\n`:e===``?`${t.trimEnd()}\n`:n===`prepend`?`${t.trimEnd()}\n\n${e.trimEnd()}\n`:`${e.trimEnd()}\n\n${t.trimEnd()}\n`,Qf=async(e,t,n,i,a)=>{let s=zu[e];if(!s)return[];let c=s[t];if(!c)return[];let l=o(n,Y,e);if(!await Jf(l))return[];let u=await Yf(l,`**/*.md`,!0),d=/* @__PURE__ */ new Map;for(let e of u){let{baseRelPath:t,isSpecific:n,specificType:r}=Xf(e);d.has(t)||d.set(t,{common:null,specifics:/* @__PURE__ */ new Map});let i=d.get(t);i!==void 0&&(n&&r?i.specifics.set(r,e):i.common=e)}let f=[];for(let[n,{common:s,specifics:u}]of d){let d=u.get(t)??null,p=s===null?null:o(l,s),m=d===null?null:o(l,d);if(p===null&&m===null)continue;let h=p===null?``:await qf(p)??``,g=m===null?``:await qf(m)??``,_=Zf(h,g,c.mode),v=Kf(_,i),y=e===`rules`&&t===`trae`&&a.rulesTraeFlatten?r(n):n,b=o(c.ideRoot,e,y);f.push({category:e,agentType:t,output:b,content:v,commonSourcePath:p,agentSourcePath:m})}return f},$f=async(e,t,n,r)=>{let i=o(t,Y);if(!await Jf(i))return[];let a=(await Yf(i,`*/`,!1)).map(e=>e.replace(/\/$/,``)),s=[];for(let i of a){if(!zu[i])continue;let a=await Qf(i,e,t,n,r);s.push(...a)}let c=/* @__PURE__ */ new Map;for(let e of s){let t=`${e.category}:${e.agentType} ← ${e.commonSourcePath??e.agentSourcePath??``}`,n=c.get(e.output);if(n!==void 0)throw Error(`平铺分发产物路径重复(真源命名碰撞): ${e.output}\n ${n}\n ${t}\n请在真源侧重命名(主题目录组织下避免跨主题同名),或经 distribution.rules.trae.flatten: false 保留目录层级`);c.set(e.output,t)}return s},ep=e=>{let t=[],n=new Set(e[0]?.itemsSources??[]);for(let r of e){let e=new Set(r.itemsSources);for(let n of e)t.includes(n)||t.push(n);for(let t of n)e.has(t)||n.delete(t)}return t.filter(e=>!n.has(e))},tp=e=>{let t=/* @__PURE__ */ new Map;for(let n of e){let e=t.get(n.output);e===void 0?t.set(n.output,[n]):e.push(n)}let n=[];for(let[e,r]of t){let t=r[0];t!==void 0&&r.some(e=>e.content.trimEnd()!==t.content.trimEnd())&&n.push({output:e,entries:r,differingItems:ep(r)})}return n},np=/* @__PURE__ */ new Set([`order`,`hub`]),rp=async e=>{try{return await y(e),!0}catch{return!1}},ip=async e=>Bun.file(e).text(),ap=async e=>{let t=new Bun.Glob(`**/*.md`),n=[];for await(let r of t.scan({cwd:e,onlyFiles:!0}))n.push(r);return n.sort()},op=(e,t)=>{if(e===``)return null;let n=e.split(`
|
|
271
271
|
`).slice(1,-1),r=null;for(let e of n){let n=e.trim();if(n===``)continue;let i=/^([^\s:]+):\s*(.*)$/.exec(n);if(i===null)throw Error(`条目 ${t} frontmatter 存在无法解析的行: '${n}'`);let a=i[1]??``,o=i[2]??``;if(!np.has(a))throw Error(`条目 ${t} frontmatter 含未知元数据键 '${a}'(v1 仅支持 order;hub 为物化标记保留键,本地条目禁止使用)`);if(a===`hub`)continue;let s=o.trim();if(s===``)throw Error(`条目 ${t} 的 order 值为空`);if(r!==null)throw Error(`条目 ${t} frontmatter 重复声明 order`);let c=Number(s);if(!Number.isFinite(c))throw Error(`条目 ${t} 的 order 值 '${s}' 不是有限数值`);r=c}return r},sp=e=>`${Y}/${Pu}/${e}`,cp=(e,t)=>{let n=e.order??1/0,r=t.order??1/0;return n===r?e.baseRelPath===t.baseRelPath?0:e.baseRelPath<t.baseRelPath?-1:1:n-r},lp=async e=>{let t=o(e,Y,Pu);if(!await rp(t))return/* @__PURE__ */ new Map;let n=await ap(t),r=/* @__PURE__ */ new Map;for(let e of n){let{baseRelPath:t,isSpecific:n,specificType:i}=Xf(e);r.has(t)||r.set(t,{common:null,specifics:/* @__PURE__ */ new Map});let a=r.get(t);a!==void 0&&(n&&i?a.specifics.set(i,e):a.common===null&&(a.common=e))}return r},up=async(e,t)=>{let n=await lp(t),r=o(t,Y,Pu),i=[];for(let[t,a]of n){let n=a.specifics.get(e)??null,s=n??a.common;if(s===null)continue;let c=o(r,s),l=await ip(c),{frontmatter:u,body:d}=sf(l),f=op(u,sp(s)),p=f;if(a.common!==null&&n!==null){if(f!==null)throw Error(`条目 ${sp(t)} 的变体 ${n} 不得声明 order(条目定位由共同版唯一决定)`);let e=await ip(o(r,a.common)),{frontmatter:i}=sf(e);p=op(i,sp(a.common))}d.trim()!==``&&i.push({baseRelPath:t,order:p,content:d.trimEnd()})}return i.sort(cp)},dp=async(e,t)=>{let n=await up(e,t);return{content:n.map(e=>e.content).join(`
|
|
272
272
|
|
|
273
273
|
`),sources:n.map(e=>e.baseRelPath)}},fp=async e=>{let t=Bun.file(e);return await t.exists()?t.text():null},pp=e=>Bu.some(t=>t===e),mp=e=>{let t=(e.split(`/`).pop()??``).replace(/\.md$/,``).split(`.`).pop()??``;if(!pp(t))throw Error(`合成规则源文件 '${e}' 缺少合法 .<type> 后缀`);return t},hp=async(e,t,n)=>{let r=o(t,Y,e.commonSource),i=o(t,Y,e.agentSource),a=await fp(r);if(a===null)throw Error(`共同部分源文件不存在: ${r}`);let s=await fp(i);if(s===null)throw Error(`独有部分源文件不存在: ${i}`);let c=await dp(mp(e.agentSource),t),l=`${[a.trimEnd(),c.content,s.trimEnd()].filter(e=>e!==``).join(`
|
|
274
274
|
|
|
275
|
-
`)}\n`,u=Kf(l,n);return{output:e.output,content:u,commonSourcePath:r,agentSourcePath:i,itemsSources:c.sources}},gp=async(e,t,n)=>{let r=Ru[e],i=[];for(let e of r){let r=await hp(e,t,n);i.push(r)}return i},_p=async(e,t)=>{let n=o(e,t),r=Bun.file(n);return await r.exists()?r.text():null},vp=e=>e.itemsSources.length>0?`${e.commonSourcePath} + items(${e.itemsSources.length}) + ${e.agentSourcePath}`:`${e.commonSourcePath} + ${e.agentSourcePath}`,yp=(e,t)=>{let n=e.map(e=>({output:e.output,content:e.content,sourceLabel:vp(e),kind:`root`,category:null})),r=t.map(e=>{let t=[];return e.commonSourcePath&&t.push(e.commonSourcePath),e.agentSourcePath&&t.push(e.agentSourcePath),{output:e.output,content:e.content,sourceLabel:t.join(` + `),kind:`category`,category:e.category}});return[...n,...r]},bp=e=>{Z(`${X.BLUE}=== 预览模式(不写入文件) ===${X.RESET}\n`);for(let t of e)Z(`${X.GREEN}--- ${t.output} ---${X.RESET}`),Z(`${X.YELLOW}源: ${t.sourceLabel}${X.RESET}`),Z(``),Z(t.content),Z(``)},xp=e=>{let t=[e.commonSourcePath,e.agentSourcePath].filter(e=>e!==null),n=`类别 ${e.category}(${e.agentType})`;return t.length>0?`${n}: ${t.join(` + `)}`:n},Sp=e=>{if(e.length!==0){Q(`${X.RED}✗ 同一产物文件被多条规则合成且内容不一致:${X.RESET}`);for(let t of e){Q(` ${X.RED}${t.output}${X.RESET}`);for(let e of t.entries)Q(` - ${e.label}`);t.differingItems.length>0?Q(` 差异条目(flavor 差异,仅部分规则检出): ${X.YELLOW}${t.differingItems.join(`, `)}${X.RESET}`):Q(` ${X.YELLOW}条目集合一致:差异来自变体正文或独有段(agent.<type>.md)内容${X.RESET}`)}Q(``),Q(`${X.YELLOW}共享同一产物文件的规则合成内容必须一致(见 docs/issues/0008)${X.RESET}`),Q(`${X.YELLOW}IDE 差异化诉求请移至 CLAUDE.md 侧(<path>.claude.md 变体 / agent.claude.md 独有段)${X.RESET}`),process.exit(1)}},Cp=async(e,t)=>{Z(`${X.BLUE}=== 校验模式(比对产物与真源) ===${X.RESET}\n`);let n=[],r=0;for(let i of t){let t=await _p(e,i.output);if(t===null){n.push(`${i.output} (产物缺失)`);continue}if(i.kind===`root`){of(t)===i.content.trimEnd()?r+=1:n.push(`${i.output} (内容不一致)`);continue}t===lf(i.content)?r+=1:n.push(`${i.output} (内容不一致或缺少 lzi 元信息)`)}if(n.length===0){Z(`${X.GREEN}✓ 所有产物与真源一致${X.RESET}(${r} 个文件)`);return}Z(`${X.RED}✗ 检测到 ${n.length} 处漂移:${X.RESET}`);for(let e of n)Z(` ${X.RED}${e}${X.RESET}`);Z(``),Z(`${X.YELLOW}请运行 lzi-agent-cli sync 重新生成产物${X.RESET}`),process.exit(1)},wp=async(e,t)=>{let n=o(e,t.output);if(t.kind===`root`){let r=await _p(e,t.output),i=af(r,t.content);await Bun.write(n,i),Z(`${X.GREEN} ✓${X.RESET} ${t.output}`);return}if(t.category){let r=await _p(e,t.output);if(r!==null&&!uf(r)&&!df(r))throw Error(`类别产物路径被非工具文件占用(无 lzi 元信息、无历史标记): ${t.output}\n产物是纯派生物,请先把该文件内容迁入 .lzi/ 真源并删除文件后重跑 sync`);await Bun.write(n,lf(t.content)),Z(`${X.GREEN} ✓${X.RESET} ${t.output}`)}},Tp=async(e,t,n)=>{let r=/* @__PURE__ */ new Set;for(let e of t)e.category
|
|
275
|
+
`)}\n`,u=Kf(l,n);return{output:e.output,content:u,commonSourcePath:r,agentSourcePath:i,itemsSources:c.sources}},gp=async(e,t,n)=>{let r=Ru[e],i=[];for(let e of r){let r=await hp(e,t,n);i.push(r)}return i},_p=async(e,t)=>{let n=o(e,t),r=Bun.file(n);return await r.exists()?r.text():null},vp=e=>e.itemsSources.length>0?`${e.commonSourcePath} + items(${e.itemsSources.length}) + ${e.agentSourcePath}`:`${e.commonSourcePath} + ${e.agentSourcePath}`,yp=(e,t)=>{let n=e.map(e=>({output:e.output,content:e.content,sourceLabel:vp(e),kind:`root`,category:null})),r=t.map(e=>{let t=[];return e.commonSourcePath&&t.push(e.commonSourcePath),e.agentSourcePath&&t.push(e.agentSourcePath),{output:e.output,content:e.content,sourceLabel:t.join(` + `),kind:`category`,category:e.category}});return[...n,...r]},bp=e=>{Z(`${X.BLUE}=== 预览模式(不写入文件) ===${X.RESET}\n`);for(let t of e)Z(`${X.GREEN}--- ${t.output} ---${X.RESET}`),Z(`${X.YELLOW}源: ${t.sourceLabel}${X.RESET}`),Z(``),Z(t.content),Z(``)},xp=e=>{let t=[e.commonSourcePath,e.agentSourcePath].filter(e=>e!==null),n=`类别 ${e.category}(${e.agentType})`;return t.length>0?`${n}: ${t.join(` + `)}`:n},Sp=e=>{if(e.length!==0){Q(`${X.RED}✗ 同一产物文件被多条规则合成且内容不一致:${X.RESET}`);for(let t of e){Q(` ${X.RED}${t.output}${X.RESET}`);for(let e of t.entries)Q(` - ${e.label}`);t.differingItems.length>0?Q(` 差异条目(flavor 差异,仅部分规则检出): ${X.YELLOW}${t.differingItems.join(`, `)}${X.RESET}`):Q(` ${X.YELLOW}条目集合一致:差异来自变体正文或独有段(agent.<type>.md)内容${X.RESET}`)}Q(``),Q(`${X.YELLOW}共享同一产物文件的规则合成内容必须一致(见 docs/issues/0008)${X.RESET}`),Q(`${X.YELLOW}IDE 差异化诉求请移至 CLAUDE.md 侧(<path>.claude.md 变体 / agent.claude.md 独有段)${X.RESET}`),process.exit(1)}},Cp=async(e,t)=>{Z(`${X.BLUE}=== 校验模式(比对产物与真源) ===${X.RESET}\n`);let n=[],r=0;for(let i of t){let t=await _p(e,i.output);if(t===null){n.push(`${i.output} (产物缺失)`);continue}if(i.kind===`root`){of(t)===i.content.trimEnd()?r+=1:n.push(`${i.output} (内容不一致)`);continue}t===lf(i.content)?r+=1:n.push(`${i.output} (内容不一致或缺少 lzi 元信息)`)}if(n.length===0){Z(`${X.GREEN}✓ 所有产物与真源一致${X.RESET}(${r} 个文件)`);return}Z(`${X.RED}✗ 检测到 ${n.length} 处漂移:${X.RESET}`);for(let e of n)Z(` ${X.RED}${e}${X.RESET}`);Z(``),Z(`${X.YELLOW}请运行 lzi-agent-cli sync 重新生成产物${X.RESET}`),process.exit(1)},wp=async(e,t)=>{let n=o(e,t.output);if(t.kind===`root`){let r=await _p(e,t.output),i=af(r,t.content);await Bun.write(n,i),Z(`${X.GREEN} ✓${X.RESET} ${t.output}`);return}if(t.category){let r=await _p(e,t.output);if(r!==null&&!uf(r)&&!df(r))throw Error(`类别产物路径被非工具文件占用(无 lzi 元信息、无历史标记): ${t.output}\n产物是纯派生物,请先把该文件内容迁入 .lzi/ 真源并删除文件后重跑 sync`);await Bun.write(n,lf(t.content)),Z(`${X.GREEN} ✓${X.RESET} ${t.output}`)}},Tp=async(e,t,n)=>{let r=/* @__PURE__ */ new Set;for(let e of t)if(e.category){let t=e.output.split(`/`);r.add(t.slice(0,2).join(`/`))}let a=new Set(t.filter(e=>e.category).map(e=>e.output)),s=[],c=new Bun.Glob(`**/*.md`);for(let t of r){let r=o(e,t);try{await y(r)}catch{continue}for await(let e of c.scan({cwd:r,onlyFiles:!0})){let c=`${t}/${e}`;if(a.has(c))continue;let l=await Bun.file(o(r,e)).text();if((uf(l)||df(l))&&(s.push(c),!n)){await _(o(r,e),{force:!0});let t=i(o(r,e));for(;t.startsWith(r)&&t!==r;){try{await v(t)}catch{break}t=i(t)}try{await v(r)}catch{}}}}return s.length>0&&!n&&Z(`${X.YELLOW}○ 清理类别产物孤儿 ${s.length} 个${X.RESET}`),s},Ep=e=>{Z(`${X.BLUE}=== 共享提示词物化 ===${X.RESET}`);for(let t of e.results){if(Z(` ${t.subscription.category} ← ${t.subscription.name}`),t.status===`materialized`){Z(` ${X.GREEN}✓ 已物化 ${t.matchedCount} 个条目${t.staleCount>0?`,清理孤儿 ${t.staleCount} 个`:``}${X.RESET}`);continue}if(t.status===`clean`){Z(` ${X.GREEN}✓ 物化一致(${t.matchedCount} 个条目)${X.RESET}`);continue}if(t.status===`planned`){Z(` ${X.YELLOW}○ 将物化 ${t.matchedCount} 个条目(dry-run 不落盘)${X.RESET}`);continue}if(t.status===`drifted`){Z(` ${X.RED}✗ 物化漂移:${X.RESET}`);for(let e of t.drift)Z(` ${X.RED}${e}${X.RESET}`);continue}Z(` ${X.RED}✗ ${t.message??`物化失败`}${X.RESET}`)}Z(``)},Dp=async e=>{let t=await Yd({agent:e.agent}),n=process.cwd(),r=await Cf(n,e.check?`check`:e.dryRun?`plan`:`write`);r.skipped||(Ep(r),r.hasError&&(Q(`${X.RED}✗ 共享提示词物化失败(hub 定位或条目非法),已中止 sync${X.RESET}`),process.exit(1)),e.check&&r.hasDrift&&(Q(`${X.RED}✗ 共享条目物化漂移:hub 内容与本地物化目录不一致${X.RESET}`),Q(`${X.YELLOW}请运行 lzi-agent-cli sync 重建共享条目${X.RESET}`),process.exit(1)));let i=Gf(t.placeholders),a=[],o=[];for(let e of t.agentTypes){let r=await gp(e,n,i);a.push(...r);let s=await $f(e,n,i,{rulesTraeFlatten:t.rulesTraeFlatten});o.push(...s)}let s=[...a.map(e=>({output:e.output,content:e.content,label:vp(e),itemsSources:e.itemsSources})),...o.map(e=>({output:e.output,content:e.content,label:xp(e),itemsSources:[]}))];Sp(tp(s));let c=yp(a,o),l=await Tp(n,c,e.check);if(l.length>0&&e.check){for(let e of l)Z(` ${X.RED}stale: ${e}${X.RESET}`);Q(`${X.RED}✗ 检测到 ${l.length} 个类别产物孤儿(真源已删除)${X.RESET}`),process.exit(1)}if(e.check){await Cp(n,c);return}if(e.dryRun){bp(c);return}Z(``),Z(`${X.BLUE}正在写入...${X.RESET}`);for(let e of c)await wp(n,e);Z(`\n${X.GREEN}同步完成${X.RESET} (Agent: ${t.agentTypes.join(`, `)},共 ${c.length} 个文件)`)},Op=Zl({dryRun:Ul().optional(),agent:vl().optional()}),kp=$l({dryRun:Ul().optional(),force:Ul().optional(),check:Ul().optional(),agent:vl().optional()});function Ap(e){gt(e,{name:`init`,description:`创建 .lzi/ 目录和源文件骨架`,options:[{flags:`--dry-run`,description:`仅预览将创建的文件`},{flags:`--agent <v>`,description:`仅生成指定 Agent 的骨架(claude/trae/zcode),默认全套`}],schema:Op,action:async e=>{await Ju({dryRun:!!e.dryRun,agent:e.agent})}}),gt(e,{name:`sync`,description:`合成根指令文件 + 分发类别配置,同步覆盖目标文件`,options:[{flags:`--dry-run`,description:`仅预览,不写入文件`},{flags:`--force`,description:`跳过覆盖确认`},{flags:`--check`,description:`仅校验:产物与真源不一致则退出码 1(CI 守门)`},{flags:`--agent <v>`,description:`目标 Agent 类型(单值/多值/auto),默认 auto`}],schema:kp,action:async e=>{await Dp({dryRun:!!e.dryRun,force:!!e.force,check:!!e.check,agent:e.agent})}}),gt(e,{name:`status`,description:`显示当前 Agent 类型、源文件存在性、输出目标`,schema:Zl({}),action:async()=>{await Vf()}}),gt(e,{name:`optimize`,description:`只读分析 .lzi/ 源文件,输出 token 成本优化建议(不修改文件)`,schema:Zl({}),action:async()=>{await wd()}}),If(e)}const jp=Zl({version:vl()});function Mp(){let e=jp.safeParse(JSON.parse(n(new URL(`../package.json`,import.meta.url),`utf8`)));if(!e.success)throw Error(`package.json 结构不符合预期: ${e.error.message}`);return e.data.version}const Np=Mp();async function Pp(){let e=mt({name:`lzi-agent-cli`,description:`Longzai Intelligence Agent Tools CLI`,version:Np,interaction:In,color:Fn});Ap(e),await e.parseAsync(process.argv)}await Pp();export{};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@longzai-intelligence-agent-tools/cli",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.15",
|
|
4
4
|
"description": "Longzai Intelligence Agent Tools CLI",
|
|
5
5
|
"license": "UNLICENSED",
|
|
6
6
|
"bin": {
|
|
@@ -34,8 +34,8 @@
|
|
|
34
34
|
"clean": "lzi-dev-cli clean"
|
|
35
35
|
},
|
|
36
36
|
"dependencies": {
|
|
37
|
-
"@longzai-intelligence-agent-tools/config": "0.0.
|
|
38
|
-
"@longzai-intelligence-agent-tools/core": "0.0.
|
|
37
|
+
"@longzai-intelligence-agent-tools/config": "0.0.15",
|
|
38
|
+
"@longzai-intelligence-agent-tools/core": "0.0.15",
|
|
39
39
|
"@longzai-intelligence-cli/core": "^0.0.8",
|
|
40
40
|
"@longzai-intelligence-cli/standard": "^0.0.8",
|
|
41
41
|
"@longzai-intelligence-shared-config/core": "^0.0.5",
|