@longzai-intelligence-agent-tools/cli 0.0.2 → 0.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1 @@
1
+ import "./rolldown-runtime-BqT_7tdF.js";
package/dist/index.js CHANGED
@@ -1,41 +1,31 @@
1
1
  #!/usr/bin/env bun
2
- /**
3
- * Longzai Intelligence Agent Tools CLI
4
- * .lzi/ 下的源 markdown 按当前 IDE 合成,同步覆盖为 CLAUDE.md / AGENTS.md。
5
- */
6
- import { initCommand } from './commands/init';
7
- import { statusCommand } from './commands/status';
8
- import { syncCommand } from './commands/sync';
9
- import { stderr, stdout } from './utils/cli-output';
10
- /**
11
- * CLI 工具名称
12
- */
13
- const CLI_NAME = 'lzi-agent-cli';
14
- /**
15
- * 全局帮助信息
16
- */
17
- const HELP_TEXT = `
18
- ${CLI_NAME} - Longzai Intelligence Agent Tools
2
+ import"./rolldown-runtime-BqT_7tdF.js";import{BUILTIN_PLACEHOLDERS as e,CATEGORY_RULES as t,COMMON_SOURCE as n,DEFAULT_SOURCES as r,ENV_KEYS as i,GENERATED_FILE_HEADER as a,GENERATED_FILE_SUFFIX as o,LZI_DIR as s,SYNTHESIS_RULES as c,VALID_AGENTS as l}from"@longzai-intelligence-agent-tools/core";import{join as u}from"node:path";import{stat as d}from"node:fs/promises";import{loadUnifiedConfig as f}from"@longzai-intelligence-shared-config/core";const p={RED:`\x1B[0;31m`,GREEN:`\x1B[0;32m`,YELLOW:`\x1B[1;33m`,BLUE:`\x1B[0;34m`,RESET:`\x1B[0m`};function m(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 h(...e){process.stdout.write(`${m(e)}\n`)}function g(...e){process.stderr.write(`${m(e)}\n`)}async function _(e){return process.stdout.write(e),new Promise(e=>{let t=process.stdin;t.setEncoding(`utf8`),t.resume();let n=r=>{t.removeListener(`data`,n),t.pause(),e(r.toString().trim())};t.once(`data`,n)})}const v=async e=>{let t=u(process.cwd(),s);h(`${p.BLUE}初始化 Agent Tools 源文件结构...${p.RESET}\n`),e.dryRun&&h(`${p.YELLOW}[预览模式] 将创建以下文件:${p.RESET}`);let n=[],a=[];for(let[i,o]of Object.entries(r)){let r=u(t,i);if(await Bun.file(r).exists()){n.push(i),e.dryRun||h(` ${p.YELLOW}跳过${p.RESET} ${i}(已存在)`);continue}if(a.push(i),e.dryRun){h(` ${p.GREEN}将创建${p.RESET} ${s}/${i}`);continue}await Bun.write(r,o,{createPath:!0}),h(` ${p.GREEN}已创建${p.RESET} ${s}/${i}`)}h(``),h(`${p.BLUE}后续步骤:${p.RESET}`),h(` 1. 编辑 ${s}/agents/agent.md,填写共同指令与 {{KEY}} 占位符`),h(` 2. 按需编辑 ${s}/agents/agent.<type>.md,填写各 Agent 专属指令`),h(` 3. 在 ${s}/commands/ rules/ skills/ 下按命名约定添加类别配置`),h(` 4. 创建 .env 文件,配置当前 Agent 类型:`),h(` ${i.AGENT_TYPE}=<${l.join(`|`)}>`),h(` ${i.PLACEHOLDER_PREFIX}<KEY>=<value> (如 LZI_PLACEHOLDER_LZI_ROOT=/path/to/project)`),h(` 5. 运行 lzi-agent-cli sync 同步生成 CLAUDE.md / AGENTS.md 并分发类别配置`),n.length>0&&(h(``),h(`${p.YELLOW}提示: ${n.length} 个文件已存在被跳过${p.RESET}`))},y=`${p.GREEN}存在${p.RESET}`,b=`${p.RED}缺失${p.RESET}`,x=e=>l.some(t=>t===e),S=async e=>Bun.file(e).exists(),ee=async()=>{let e=process.cwd(),r=u(e,s),a=process.env[i.AGENT_TYPE],o=a&&x(a)?a:null;h(`${p.BLUE}=== Agent Tools 状态 ===${p.RESET}\n`),h(o?`当前 Agent: ${p.GREEN}${o}${p.RESET}`:a?`当前 Agent: ${p.RED}${a}(无效,合法值: ${l.join(`, `)})${p.RESET}`:`当前 Agent: ${p.YELLOW}未设置(请在 .env 配置 ${i.AGENT_TYPE})${p.RESET}`),h(``),h(`${p.BLUE}源文件(${r}):${p.RESET}`);let d=new Set;if(d.add(n),o)for(let e of c[o])d.add(e.agentSource);for(let e of d){let t=u(r,e);h(` ${e}: ${await S(t)?y:b}`)}if(h(``),o){h(`${p.BLUE}输出目标(将覆盖):${p.RESET}`);for(let t of c[o]){let n=u(e,t.output),r=await S(n);h(` ${t.output}: ${r?y:b}`)}}else h(`${p.YELLOW}Agent 类型未配置,无法显示输出目标${p.RESET}`);h(``),h(`${p.BLUE}类别配置目录(${r} 下):${p.RESET}`);for(let e of Object.keys(t)){let t=u(r,e);h(` ${e}/: ${await S(t)?y:b}`)}},C=/\{\{([A-Z][A-Z0-9_]*)\}\}/g,w=()=>{let e={};for(let[t,n]of Object.entries(process.env))if(t.startsWith(i.PLACEHOLDER_PREFIX)&&n!==void 0){let r=t.slice(i.PLACEHOLDER_PREFIX.length);e[r]=n}return e},T=()=>{let t={};for(let[n,r]of Object.entries(e))t[n]=r();return t},E=e=>{let t=T(),n=w();return{...t,...n,...e}},D=(e,t)=>e.replace(C,(e,n)=>t[n]??e),O=async e=>{let t=Bun.file(e);return await t.exists()?t.text():null},k=async e=>{try{return await d(e),!0}catch{return!1}},A=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()},j=e=>{let t=e.replace(/\.md$/,``);for(let e of l){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}},M=(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`,N=async(e,n,r,i)=>{let a=t[e];if(!a)return[];let c=a[n];if(!c)return[];let l=u(r,s,e);if(!await k(l))return[];let d=await A(l,`**/*.md`,!0),f=new Map;for(let e of d){let{baseRelPath:t,isSpecific:n,specificType:r}=j(e);f.has(t)||f.set(t,{common:null,specifics:new Map});let i=f.get(t);i!==void 0&&(n&&r?i.specifics.set(r,e):i.common=e)}let p=[];for(let[t,{common:r,specifics:a}]of f){let s=a.get(n)??null,d=r===null?null:u(l,r),f=s===null?null:u(l,s);if(d===null&&f===null)continue;let m=d===null?``:await O(d)??``,h=f===null?``:await O(f)??``,g=D(M(m,h,c.mode),i),_=t.replace(/\.md$/,`${o}.md`),v=u(c.ideRoot,e,_);p.push({category:e,agentType:n,output:v,content:g,commonSourcePath:d,agentSourcePath:f})}return p},P=async(e,n,r)=>{let i=u(n,s);if(!await k(i))return[];let a=(await A(i,`*/`,!1)).map(e=>e.replace(/\/$/,``)),o=[];for(let i of a){if(!t[i])continue;let a=await N(i,e,n,r);o.push(...a)}return o},F=async e=>{let t=Bun.file(e);return await t.exists()?t.text():null},I=async(e,t,n)=>{let r=u(t,s,e.commonSource),i=u(t,s,e.agentSource),o=await F(r);if(o===null)throw Error(`共同部分源文件不存在: ${r}`);let c=await F(i);if(c===null)throw Error(`独有部分源文件不存在: ${i}`);let l=D(`${a}\n\n${o.trimEnd()}\n\n${c.trimEnd()}\n`,n);return{output:e.output,content:l,commonSourcePath:r,agentSourcePath:i}},L=async(e,t,n)=>{let r=c[e],i=[];for(let e of r){let r=await I(e,t,n);i.push(r)}return i},R=e=>l.some(t=>t===e),z=()=>{let e=process.env[i.AGENT_TYPE];return e?R(e)?e:(g(`错误: ${i.AGENT_TYPE} 值 '${e}' 无效,合法值为: ${l.join(`, `)}`),null):null},B=async()=>{let e=await f({unifiedField:`agentTools`});return e.success?e.config:void 0},V=async()=>{let e=z();return e||(g(`错误: 环境变量 ${i.AGENT_TYPE} 未设置`),g(`请在 .env 中配置,合法值为: ${l.join(`, `)}`),process.exit(1)),{agentType:e,placeholders:(await B())?.placeholders}},H=async(e,t)=>{let n=u(e,t);return Bun.file(n).exists()},U=async(e,t)=>{let n=u(e,t),r=Bun.file(n);return await r.exists()?r.text():null},W=(e,t)=>{let n=e.map(e=>({output:e.output,content:e.content,sourceLabel:`${e.commonSourcePath} + ${e.agentSourcePath}`})),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(` + `)}});return[...n,...r]},G=e=>{h(`${p.BLUE}=== 预览模式(不写入文件) ===${p.RESET}\n`);for(let t of e)h(`${p.GREEN}--- ${t.output} ---${p.RESET}`),h(`${p.YELLOW}源: ${t.sourceLabel}${p.RESET}`),h(``),h(t.content),h(``)},K=async(e,t)=>{h(`${p.BLUE}=== 校验模式(比对产物与真源) ===${p.RESET}\n`);let n=[],r=0;for(let i of t){let t=await U(e,i.output);t===null?n.push(`${i.output} (产物缺失)`):t===i.content?r+=1:n.push(`${i.output} (内容不一致)`)}if(n.length===0){h(`${p.GREEN}✓ 所有产物与真源一致${p.RESET}(${r} 个文件)`);return}h(`${p.RED}✗ 检测到 ${n.length} 处漂移:${p.RESET}`);for(let e of n)h(` ${p.RED}${e}${p.RESET}`);h(``),h(`${p.YELLOW}请运行 lzi-agent-cli sync 重新生成产物${p.RESET}`),process.exit(1)},q=async(e,t)=>{let n=u(e,t.output);await Bun.write(n,t.content),h(`${p.GREEN} ✓${p.RESET} ${t.output}`)},J=async e=>{let t=await V(),n=process.cwd(),r=E(t.placeholders),i=await L(t.agentType,n,r),a=await P(t.agentType,n,r),o=W(i,a);if(e.check){await K(n,o);return}if(e.dryRun){G(o);return}let s=[];for(let e of o)await H(n,e.output)&&s.push(e.output);if(s.length>0&&!e.force){h(`${p.YELLOW}将覆盖以下文件:${p.RESET}`);for(let e of s)h(` ${e}`);if((await _(`
3
+ 确认覆盖?(y/N): `)).toLowerCase()!==`y`){h(`已取消`);return}}h(``),h(`${p.BLUE}正在写入...${p.RESET}`);for(let e of o)await q(n,e);h(`\n${p.GREEN}同步完成${p.RESET} (Agent: ${t.agentType},共 ${o.length} 个文件)`)},Y=`lzi-agent-cli`,X=`
4
+ ${Y} - Longzai Intelligence Agent Tools
19
5
 
20
6
  把 .lzi/ 下的源 markdown(共同部分 + 各 IDE 独有部分)按当前 IDE 自动合成,
21
- 同步覆盖为 CLAUDE.md / AGENTS.md
7
+ 同步覆盖为 CLAUDE.md / AGENTS.md,并分发 commands / rules / skills 类别配置。
22
8
 
23
9
  源文件(.lzi/ 下):
24
- agent.md 共同部分
25
- agent.claude.md claude 独有
26
- agent.trae.md trae 独有
27
- agent.zcode.md zcode 独有
10
+ agents/agent.md 共同部分
11
+ agents/agent.claude.md claude 独有
12
+ agents/agent.trae.md trae 独有
13
+ agents/agent.zcode.md zcode 独有
14
+ commands/ 自定义命令真源(<base>.md / <base>.<type>.md)
15
+ rules/ 项目规则真源
16
+ skills/ 技能真源
28
17
 
29
18
  用法:
30
- ${CLI_NAME} <command> [options]
19
+ ${Y} <command> [options]
31
20
 
32
21
  命令:
33
22
  init 创建 .lzi/ 目录和源文件骨架
34
23
  [--dry-run] 仅预览将创建的文件
35
24
 
36
- sync 合成并同步覆盖目标文件
25
+ sync 合成根指令文件 + 分发类别配置,同步覆盖目标文件
37
26
  [--dry-run] 仅预览,不写入文件
38
27
  [--force] 跳过覆盖确认
28
+ [--check] 仅校验:产物与真源不一致则退出码 1(CI 守门)
39
29
 
40
30
  status 显示当前 Agent 类型、源文件存在性、输出目标
41
31
 
@@ -46,76 +36,4 @@ ${CLI_NAME} - Longzai Intelligence Agent Tools
46
36
  选项:
47
37
  --help 显示帮助信息
48
38
  --version 显示版本号
49
- `;
50
- /**
51
- * 显示全局帮助信息并退出
52
- */
53
- const showHelp = () => {
54
- stdout(HELP_TEXT.trim());
55
- process.exit(0);
56
- };
57
- /**
58
- * 显示版本号并退出
59
- */
60
- const showVersion = () => {
61
- /** 从 package.json 读取版本号 */
62
- const version = '0.0.1';
63
- stdout(`${CLI_NAME} v${version}`);
64
- process.exit(0);
65
- };
66
- const parseSyncFlags = (args) => {
67
- /** dry-run 标志 */
68
- const dryRun = args.includes('--dry-run');
69
- /** force 标志 */
70
- const force = args.includes('--force');
71
- return { dryRun, force };
72
- };
73
- /**
74
- * CLI 主入口函数
75
- *
76
- * 解析命令行参数并路由到对应命令。
77
- */
78
- const main = async () => {
79
- /** 命令行参数(去除 node 和脚本路径) */
80
- const args = process.argv.slice(2);
81
- if (args.length === 0 || args[0] === '--help') {
82
- showHelp();
83
- return;
84
- }
85
- if (args[0] === '--version') {
86
- showVersion();
87
- return;
88
- }
89
- /** 命令名称 */
90
- const command = args[0];
91
- /** 命令参数 */
92
- const cmdArgs = args.slice(1);
93
- switch (command) {
94
- case 'init': {
95
- /** 解析标志 */
96
- const { dryRun } = parseSyncFlags(cmdArgs);
97
- await initCommand({ dryRun });
98
- break;
99
- }
100
- case 'sync': {
101
- /** 解析标志 */
102
- const { dryRun, force } = parseSyncFlags(cmdArgs);
103
- await syncCommand({ dryRun, force });
104
- break;
105
- }
106
- case 'status': {
107
- await statusCommand();
108
- break;
109
- }
110
- default: {
111
- stderr(`错误: 未知命令 '${command}'`);
112
- stderr(`使用 '${CLI_NAME} --help' 查看可用命令`);
113
- process.exit(1);
114
- }
115
- }
116
- };
117
- main().catch((err) => {
118
- stderr('错误:', err instanceof Error ? err.message : String(err));
119
- process.exit(1);
120
- });
121
- //# sourceMappingURL=index.js.map
39
+ `,Z=()=>{h(X.trim()),process.exit(0)},Q=()=>{h(`${Y} v0.0.1`),process.exit(0)},$=e=>({dryRun:e.includes(`--dry-run`),force:e.includes(`--force`),check:e.includes(`--check`)});(async()=>{let e=process.argv.slice(2);if(e.length===0||e[0]===`--help`){Z();return}if(e[0]===`--version`){Q();return}let t=e[0],n=e.slice(1);switch(t){case`init`:{let{dryRun:e}=$(n);await v({dryRun:e});break}case`sync`:{let{dryRun:e,force:t,check:r}=$(n);await J({dryRun:e,force:t,check:r});break}case`status`:await ee();break;default:g(`错误: 未知命令 '${t}'`),g(`使用 '${Y} --help' 查看可用命令`),process.exit(1)}})().catch(e=>{g(`错误:`,e instanceof Error?e.message:String(e)),process.exit(1)});export{};
@@ -0,0 +1 @@
1
+ import"node:module";export{};
package/package.json CHANGED
@@ -1,15 +1,15 @@
1
1
  {
2
2
  "name": "@longzai-intelligence-agent-tools/cli",
3
- "version": "0.0.2",
3
+ "version": "0.0.4",
4
4
  "description": "Longzai Intelligence Agent Tools CLI",
5
5
  "license": "UNLICENSED",
6
- "type": "module",
7
6
  "bin": {
8
7
  "lzi-agent-cli": "./dist/index.js"
9
8
  },
10
9
  "files": [
11
10
  "dist"
12
11
  ],
12
+ "type": "module",
13
13
  "main": "./dist/index.js",
14
14
  "types": "./dist/index.d.ts",
15
15
  "exports": {
@@ -19,8 +19,8 @@
19
19
  }
20
20
  },
21
21
  "scripts": {
22
- "build": "tsgo --build tsconfig/build.json && resolve-aliases -p tsconfig/build.json",
23
- "build:prod": "NODE_ENV=production bun run build",
22
+ "build": "lzi-builder",
23
+ "build:prod": "NODE_ENV=production lzi-builder",
24
24
  "prepublishOnly": "bun run build:prod",
25
25
  "typecheck": "bun run typecheck:app && bun run typecheck:node && bun run typecheck:test",
26
26
  "typecheck:app": "tsgo --noEmit -p tsconfig/app.json",
@@ -31,10 +31,10 @@
31
31
  "test": "bun test",
32
32
  "test:watch": "bun test --watch",
33
33
  "test:coverage": "bun test --coverage",
34
- "clean": "rimraf dist out .cache"
34
+ "clean": "lzi-dev-cli clean"
35
35
  },
36
36
  "dependencies": {
37
- "@longzai-intelligence-agent-tools/core": "0.0.2",
38
- "@longzai-intelligence-shared-config/core": "^0.0.4"
37
+ "@longzai-intelligence-agent-tools/core": "0.0.4",
38
+ "@longzai-intelligence-shared-config/core": "^0.0.5"
39
39
  }
40
40
  }
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/commands/init/index.ts"],"names":[],"mappings":"AAMA;;GAEG;AACH,UAAU,kBAAkB;IAC1B,sBAAsB;IACtB,MAAM,EAAE,OAAO,CAAC;CACjB;AAED;;;;;;;GAOG;AACH,eAAO,MAAM,WAAW,YAAmB,kBAAkB,KAAG,OAAO,CAAC,IAAI,CA4D3E,CAAC"}
@@ -1,60 +0,0 @@
1
- import { join } from 'node:path';
2
- import { DEFAULT_SOURCES, ENV_KEYS, LZI_DIR, VALID_AGENTS } from '@longzai-intelligence-agent-tools/core';
3
- import { COLORS, stdout } from '../../utils/cli-output';
4
- /**
5
- * 执行 init 命令
6
- *
7
- * 在当前项目创建 .lzi/ 目录和四个源文件骨架。
8
- * 已存在的文件跳过,不覆盖。
9
- *
10
- * @param options - 命令选项
11
- */
12
- export const initCommand = async (options) => {
13
- /** 项目根目录 */
14
- const projectRoot = process.cwd();
15
- /** .lzi 目录绝对路径 */
16
- const lziDir = join(projectRoot, LZI_DIR);
17
- stdout(`${COLORS.BLUE}初始化 Agent Tools 源文件结构...${COLORS.RESET}\n`);
18
- if (options.dryRun) {
19
- stdout(`${COLORS.YELLOW}[预览模式] 将创建以下文件:${COLORS.RESET}`);
20
- }
21
- /** 已跳过的文件列表 */
22
- const skipped = [];
23
- /** 已创建的文件列表 */
24
- const created = [];
25
- for (const [fileName, content] of Object.entries(DEFAULT_SOURCES)) {
26
- /** 文件绝对路径 */
27
- const filePath = join(lziDir, fileName);
28
- /** 检查文件是否已存在 */
29
- const exists = await Bun.file(filePath).exists();
30
- if (exists) {
31
- skipped.push(fileName);
32
- if (!options.dryRun) {
33
- stdout(` ${COLORS.YELLOW}跳过${COLORS.RESET} ${fileName}(已存在)`);
34
- }
35
- continue;
36
- }
37
- created.push(fileName);
38
- if (options.dryRun) {
39
- stdout(` ${COLORS.GREEN}将创建${COLORS.RESET} ${LZI_DIR}/${fileName}`);
40
- continue;
41
- }
42
- /** 写入文件 */
43
- await Bun.write(filePath, content);
44
- stdout(` ${COLORS.GREEN}已创建${COLORS.RESET} ${LZI_DIR}/${fileName}`);
45
- }
46
- /** 后续提示 */
47
- stdout('');
48
- stdout(`${COLORS.BLUE}后续步骤:${COLORS.RESET}`);
49
- stdout(` 1. 编辑 ${LZI_DIR}/agent.md,填写共同指令与 {{KEY}} 占位符`);
50
- stdout(` 2. 按需编辑 ${LZI_DIR}/agent.<type>.md,填写各 Agent 专属指令`);
51
- stdout(` 3. 创建 .env 文件,配置当前 Agent 类型:`);
52
- stdout(` ${ENV_KEYS.AGENT_TYPE}=<${VALID_AGENTS.join('|')}>`);
53
- stdout(` ${ENV_KEYS.PLACEHOLDER_PREFIX}<KEY>=<value> (如 LZI_PLACEHOLDER_LZI_ROOT=/path/to/project)`);
54
- stdout(` 4. 运行 lzi-agent-cli sync 同步生成 CLAUDE.md / AGENTS.md`);
55
- if (skipped.length > 0) {
56
- stdout('');
57
- stdout(`${COLORS.YELLOW}提示: ${skipped.length} 个文件已存在被跳过${COLORS.RESET}`);
58
- }
59
- };
60
- //# sourceMappingURL=index.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/commands/init/index.ts"],"names":[],"mappings":"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","sourcesContent":["import { join } from 'node:path';\n\nimport { DEFAULT_SOURCES, ENV_KEYS, LZI_DIR, VALID_AGENTS } from '@longzai-intelligence-agent-tools/core';\n\nimport { COLORS, stdout } from '@/utils/cli-output';\n\n/**\n * init 命令选项\n */\ninterface InitCommandOptions {\n /** 仅预览将创建的文件,不实际写入 */\n dryRun: boolean;\n}\n\n/**\n * 执行 init 命令\n *\n * 在当前项目创建 .lzi/ 目录和四个源文件骨架。\n * 已存在的文件跳过,不覆盖。\n *\n * @param options - 命令选项\n */\nexport const initCommand = async (options: InitCommandOptions): Promise<void> => {\n /** 项目根目录 */\n const projectRoot = process.cwd();\n\n /** .lzi 目录绝对路径 */\n const lziDir = join(projectRoot, LZI_DIR);\n\n stdout(`${COLORS.BLUE}初始化 Agent Tools 源文件结构...${COLORS.RESET}\\n`);\n\n if (options.dryRun) {\n stdout(`${COLORS.YELLOW}[预览模式] 将创建以下文件:${COLORS.RESET}`);\n }\n\n /** 已跳过的文件列表 */\n const skipped: string[] = [];\n\n /** 已创建的文件列表 */\n const created: string[] = [];\n\n for (const [fileName, content] of Object.entries(DEFAULT_SOURCES)) {\n /** 文件绝对路径 */\n const filePath = join(lziDir, fileName);\n\n /** 检查文件是否已存在 */\n const exists = await Bun.file(filePath).exists();\n\n if (exists) {\n skipped.push(fileName);\n if (!options.dryRun) {\n stdout(` ${COLORS.YELLOW}跳过${COLORS.RESET} ${fileName}(已存在)`);\n }\n continue;\n }\n\n created.push(fileName);\n\n if (options.dryRun) {\n stdout(` ${COLORS.GREEN}将创建${COLORS.RESET} ${LZI_DIR}/${fileName}`);\n continue;\n }\n\n /** 写入文件 */\n await Bun.write(filePath, content);\n stdout(` ${COLORS.GREEN}已创建${COLORS.RESET} ${LZI_DIR}/${fileName}`);\n }\n\n /** 后续提示 */\n stdout('');\n stdout(`${COLORS.BLUE}后续步骤:${COLORS.RESET}`);\n stdout(` 1. 编辑 ${LZI_DIR}/agent.md,填写共同指令与 {{KEY}} 占位符`);\n stdout(` 2. 按需编辑 ${LZI_DIR}/agent.<type>.md,填写各 Agent 专属指令`);\n stdout(` 3. 创建 .env 文件,配置当前 Agent 类型:`);\n stdout(` ${ENV_KEYS.AGENT_TYPE}=<${VALID_AGENTS.join('|')}>`);\n stdout(` ${ENV_KEYS.PLACEHOLDER_PREFIX}<KEY>=<value> (如 LZI_PLACEHOLDER_LZI_ROOT=/path/to/project)`);\n stdout(` 4. 运行 lzi-agent-cli sync 同步生成 CLAUDE.md / AGENTS.md`);\n\n if (skipped.length > 0) {\n stdout('');\n stdout(`${COLORS.YELLOW}提示: ${skipped.length} 个文件已存在被跳过${COLORS.RESET}`);\n }\n};\n"]}
@@ -1,7 +0,0 @@
1
- /**
2
- * 执行 status 命令
3
- *
4
- * 显示当前 Agent 类型、源文件存在性、目标文件存在性。
5
- */
6
- export declare const statusCommand: () => Promise<void>;
7
- //# sourceMappingURL=index.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/commands/status/index.ts"],"names":[],"mappings":"AA4BA;;;;GAIG;AACH,eAAO,MAAM,aAAa,QAAa,OAAO,CAAC,IAAI,CA8DlD,CAAC"}
@@ -1,76 +0,0 @@
1
- import { join } from 'node:path';
2
- import { ENV_KEYS, LZI_DIR, SYNTHESIS_RULES, VALID_AGENTS, } from '@longzai-intelligence-agent-tools/core';
3
- import { COLORS, stdout } from '../../utils/cli-output';
4
- /**
5
- * 状态标记符号
6
- */
7
- const STATUS_OK = `${COLORS.GREEN}存在${COLORS.RESET}`;
8
- const STATUS_MISSING = `${COLORS.RED}缺失${COLORS.RESET}`;
9
- /**
10
- * 检测文件是否存在
11
- *
12
- * @param filePath - 文件绝对路径
13
- * @returns 是否存在
14
- */
15
- const fileExists = async (filePath) => {
16
- return Bun.file(filePath).exists();
17
- };
18
- /**
19
- * 执行 status 命令
20
- *
21
- * 显示当前 Agent 类型、源文件存在性、目标文件存在性。
22
- */
23
- export const statusCommand = async () => {
24
- /** 项目根目录 */
25
- const projectRoot = process.cwd();
26
- /** 源目录绝对路径 */
27
- const lziDir = join(projectRoot, LZI_DIR);
28
- /** 从环境变量读 Agent 类型 */
29
- const agentTypeRaw = process.env[ENV_KEYS.AGENT_TYPE];
30
- const agentTypeValid = agentTypeRaw && VALID_AGENTS.includes(agentTypeRaw) ? agentTypeRaw : null;
31
- stdout(`${COLORS.BLUE}=== Agent Tools 状态 ===${COLORS.RESET}\n`);
32
- /** 当前 Agent 类型 */
33
- if (agentTypeValid) {
34
- stdout(`当前 Agent: ${COLORS.GREEN}${agentTypeValid}${COLORS.RESET}`);
35
- }
36
- else if (agentTypeRaw) {
37
- stdout(`当前 Agent: ${COLORS.RED}${agentTypeRaw}(无效,合法值: ${VALID_AGENTS.join(', ')})${COLORS.RESET}`);
38
- }
39
- else {
40
- stdout(`当前 Agent: ${COLORS.YELLOW}未设置(请在 .env 配置 ${ENV_KEYS.AGENT_TYPE})${COLORS.RESET}`);
41
- }
42
- stdout('');
43
- /** 源文件存在性 */
44
- stdout(`${COLORS.BLUE}源文件(${lziDir}):${COLORS.RESET}`);
45
- /** 需要检查的源文件名集合 */
46
- const sourceFiles = new Set();
47
- /** 共同部分 */
48
- sourceFiles.add('agent.md');
49
- /** 该 Agent 的独有部分 */
50
- if (agentTypeValid) {
51
- for (const rule of SYNTHESIS_RULES[agentTypeValid]) {
52
- sourceFiles.add(rule.agentSource);
53
- }
54
- }
55
- for (const fileName of sourceFiles) {
56
- /** 文件绝对路径 */
57
- const filePath = join(lziDir, fileName);
58
- const exists = await fileExists(filePath);
59
- stdout(` ${fileName}: ${exists ? STATUS_OK : STATUS_MISSING}`);
60
- }
61
- stdout('');
62
- /** 目标文件存在性 */
63
- if (agentTypeValid) {
64
- stdout(`${COLORS.BLUE}输出目标(将覆盖):${COLORS.RESET}`);
65
- for (const rule of SYNTHESIS_RULES[agentTypeValid]) {
66
- /** 目标文件绝对路径 */
67
- const targetPath = join(projectRoot, rule.output);
68
- const exists = await fileExists(targetPath);
69
- stdout(` ${rule.output}: ${exists ? STATUS_OK : STATUS_MISSING}`);
70
- }
71
- }
72
- else {
73
- stdout(`${COLORS.YELLOW}Agent 类型未配置,无法显示输出目标${COLORS.RESET}`);
74
- }
75
- };
76
- //# sourceMappingURL=index.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/commands/status/index.ts"],"names":[],"mappings":"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","sourcesContent":["import { join } from 'node:path';\n\nimport {\n type AgentType,\n ENV_KEYS,\n LZI_DIR,\n SYNTHESIS_RULES,\n VALID_AGENTS,\n} from '@longzai-intelligence-agent-tools/core';\n\nimport { COLORS, stdout } from '@/utils/cli-output';\n\n/**\n * 状态标记符号\n */\nconst STATUS_OK = `${COLORS.GREEN}存在${COLORS.RESET}`;\nconst STATUS_MISSING = `${COLORS.RED}缺失${COLORS.RESET}`;\n\n/**\n * 检测文件是否存在\n *\n * @param filePath - 文件绝对路径\n * @returns 是否存在\n */\nconst fileExists = async (filePath: string): Promise<boolean> => {\n return Bun.file(filePath).exists();\n};\n\n/**\n * 执行 status 命令\n *\n * 显示当前 Agent 类型、源文件存在性、目标文件存在性。\n */\nexport const statusCommand = async (): Promise<void> => {\n /** 项目根目录 */\n const projectRoot = process.cwd();\n\n /** 源目录绝对路径 */\n const lziDir = join(projectRoot, LZI_DIR);\n\n /** 从环境变量读 Agent 类型 */\n const agentTypeRaw = process.env[ENV_KEYS.AGENT_TYPE];\n const agentTypeValid = agentTypeRaw && VALID_AGENTS.includes(agentTypeRaw as AgentType) ? (agentTypeRaw as AgentType) : null;\n\n stdout(`${COLORS.BLUE}=== Agent Tools 状态 ===${COLORS.RESET}\\n`);\n\n /** 当前 Agent 类型 */\n if (agentTypeValid) {\n stdout(`当前 Agent: ${COLORS.GREEN}${agentTypeValid}${COLORS.RESET}`);\n } else if (agentTypeRaw) {\n stdout(`当前 Agent: ${COLORS.RED}${agentTypeRaw}(无效,合法值: ${VALID_AGENTS.join(', ')})${COLORS.RESET}`);\n } else {\n stdout(`当前 Agent: ${COLORS.YELLOW}未设置(请在 .env 配置 ${ENV_KEYS.AGENT_TYPE})${COLORS.RESET}`);\n }\n\n stdout('');\n\n /** 源文件存在性 */\n stdout(`${COLORS.BLUE}源文件(${lziDir}):${COLORS.RESET}`);\n\n /** 需要检查的源文件名集合 */\n const sourceFiles = new Set<string>();\n\n /** 共同部分 */\n sourceFiles.add('agent.md');\n\n /** 该 Agent 的独有部分 */\n if (agentTypeValid) {\n for (const rule of SYNTHESIS_RULES[agentTypeValid]) {\n sourceFiles.add(rule.agentSource);\n }\n }\n\n for (const fileName of sourceFiles) {\n /** 文件绝对路径 */\n const filePath = join(lziDir, fileName);\n const exists = await fileExists(filePath);\n stdout(` ${fileName}: ${exists ? STATUS_OK : STATUS_MISSING}`);\n }\n\n stdout('');\n\n /** 目标文件存在性 */\n if (agentTypeValid) {\n stdout(`${COLORS.BLUE}输出目标(将覆盖):${COLORS.RESET}`);\n\n for (const rule of SYNTHESIS_RULES[agentTypeValid]) {\n /** 目标文件绝对路径 */\n const targetPath = join(projectRoot, rule.output);\n const exists = await fileExists(targetPath);\n stdout(` ${rule.output}: ${exists ? STATUS_OK : STATUS_MISSING}`);\n }\n } else {\n stdout(`${COLORS.YELLOW}Agent 类型未配置,无法显示输出目标${COLORS.RESET}`);\n }\n};\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/commands/sync/index.ts"],"names":[],"mappings":"AAOA;;GAEG;AACH,UAAU,kBAAkB;IAC1B,gBAAgB;IAChB,MAAM,EAAE,OAAO,CAAC;IAChB,aAAa;IACb,KAAK,EAAE,OAAO,CAAC;CAChB;AAiDD;;;;;;;GAOG;AACH,eAAO,MAAM,WAAW,YAAmB,kBAAkB,KAAG,OAAO,CAAC,IAAI,CAqD3E,CAAC"}
@@ -1,97 +0,0 @@
1
- import { join } from 'node:path';
2
- import { loadCliConfig } from '../../config';
3
- import { COLORS, promptInput, stdout } from '../../utils/cli-output';
4
- import { synthesizeAll } from './synthesizer';
5
- import { resolvePlaceholders } from '../../utils/placeholder-resolver';
6
- /**
7
- * 检测目标文件是否已存在
8
- *
9
- * @param projectRoot - 项目根目录绝对路径
10
- * @param output - 输出文件相对路径
11
- * @returns 是否已存在
12
- */
13
- const targetExists = async (projectRoot, output) => {
14
- /** 目标文件绝对路径 */
15
- const targetPath = join(projectRoot, output);
16
- return Bun.file(targetPath).exists();
17
- };
18
- /**
19
- * 执行 dry-run 预览
20
- *
21
- * 打印每个输出文件的合成内容。
22
- *
23
- * @param results - 合成结果列表
24
- */
25
- const previewResults = (results) => {
26
- stdout(`${COLORS.BLUE}=== 预览模式(不写入文件) ===${COLORS.RESET}\n`);
27
- for (const result of results) {
28
- stdout(`${COLORS.GREEN}--- ${result.output} ---${COLORS.RESET}`);
29
- stdout(`${COLORS.YELLOW}源: ${result.commonSourcePath} + ${result.agentSourcePath}${COLORS.RESET}`);
30
- stdout('');
31
- stdout(result.content);
32
- stdout('');
33
- }
34
- };
35
- /**
36
- * 写入合成结果到目标文件
37
- *
38
- * @param projectRoot - 项目根目录绝对路径
39
- * @param result - 单个合成结果
40
- */
41
- const writeResult = async (projectRoot, result) => {
42
- /** 目标文件绝对路径 */
43
- const targetPath = join(projectRoot, result.output);
44
- await Bun.write(targetPath, result.content);
45
- stdout(`${COLORS.GREEN} ✓${COLORS.RESET} ${result.output}`);
46
- };
47
- /**
48
- * 执行 sync 命令
49
- *
50
- * 按 .env 配置的 IDE 合成源 markdown,同步覆盖目标文件。
51
- * 目标已存在时提示用户确认,--force 跳过确认,--dry-run 仅预览。
52
- *
53
- * @param options - 命令选项
54
- */
55
- export const syncCommand = async (options) => {
56
- /** 加载 CLI 配置(IDE + placeholders) */
57
- const config = await loadCliConfig();
58
- /** 项目根目录 */
59
- const projectRoot = process.cwd();
60
- /** 合并所有来源的占位符 */
61
- const placeholders = resolvePlaceholders(config.placeholders);
62
- /** 合成所有输出文件 */
63
- const results = await synthesizeAll(config.agentType, projectRoot, placeholders);
64
- /** dry-run:仅预览 */
65
- if (options.dryRun) {
66
- previewResults(results);
67
- return;
68
- }
69
- /** 检测已存在的目标文件 */
70
- const existingTargets = [];
71
- for (const result of results) {
72
- if (await targetExists(projectRoot, result.output)) {
73
- existingTargets.push(result.output);
74
- }
75
- }
76
- /** 覆盖确认 */
77
- if (existingTargets.length > 0 && !options.force) {
78
- stdout(`${COLORS.YELLOW}将覆盖以下文件:${COLORS.RESET}`);
79
- for (const target of existingTargets) {
80
- stdout(` ${target}`);
81
- }
82
- /** 用户确认 */
83
- const confirmed = await promptInput(`\n确认覆盖?(y/N): `);
84
- if (confirmed.toLowerCase() !== 'y') {
85
- stdout('已取消');
86
- return;
87
- }
88
- }
89
- /** 写入目标文件 */
90
- stdout('');
91
- stdout(`${COLORS.BLUE}正在写入...${COLORS.RESET}`);
92
- for (const result of results) {
93
- await writeResult(projectRoot, result);
94
- }
95
- stdout(`\n${COLORS.GREEN}同步完成${COLORS.RESET} (Agent: ${config.agentType},共 ${results.length} 个文件)`);
96
- };
97
- //# sourceMappingURL=index.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/commands/sync/index.ts"],"names":[],"mappings":"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","sourcesContent":["import { join } from 'node:path';\n\nimport { loadCliConfig } from '@/config';\nimport { COLORS, promptInput, stdout } from '@/utils/cli-output';\nimport { type SynthesisResult, synthesizeAll } from '@/commands/sync/synthesizer';\nimport { resolvePlaceholders } from '@/utils/placeholder-resolver';\n\n/**\n * sync 命令选项\n */\ninterface SyncCommandOptions {\n /** 仅预览,不写入文件 */\n dryRun: boolean;\n /** 跳过覆盖确认 */\n force: boolean;\n}\n\n/**\n * 检测目标文件是否已存在\n *\n * @param projectRoot - 项目根目录绝对路径\n * @param output - 输出文件相对路径\n * @returns 是否已存在\n */\nconst targetExists = async (projectRoot: string, output: string): Promise<boolean> => {\n /** 目标文件绝对路径 */\n const targetPath = join(projectRoot, output);\n return Bun.file(targetPath).exists();\n};\n\n/**\n * 执行 dry-run 预览\n *\n * 打印每个输出文件的合成内容。\n *\n * @param results - 合成结果列表\n */\nconst previewResults = (results: readonly SynthesisResult[]): void => {\n stdout(`${COLORS.BLUE}=== 预览模式(不写入文件) ===${COLORS.RESET}\\n`);\n\n for (const result of results) {\n stdout(`${COLORS.GREEN}--- ${result.output} ---${COLORS.RESET}`);\n stdout(`${COLORS.YELLOW}源: ${result.commonSourcePath} + ${result.agentSourcePath}${COLORS.RESET}`);\n stdout('');\n stdout(result.content);\n stdout('');\n }\n};\n\n/**\n * 写入合成结果到目标文件\n *\n * @param projectRoot - 项目根目录绝对路径\n * @param result - 单个合成结果\n */\nconst writeResult = async (projectRoot: string, result: SynthesisResult): Promise<void> => {\n /** 目标文件绝对路径 */\n const targetPath = join(projectRoot, result.output);\n\n await Bun.write(targetPath, result.content);\n\n stdout(`${COLORS.GREEN} ✓${COLORS.RESET} ${result.output}`);\n};\n\n/**\n * 执行 sync 命令\n *\n * 按 .env 配置的 IDE 合成源 markdown,同步覆盖目标文件。\n * 目标已存在时提示用户确认,--force 跳过确认,--dry-run 仅预览。\n *\n * @param options - 命令选项\n */\nexport const syncCommand = async (options: SyncCommandOptions): Promise<void> => {\n /** 加载 CLI 配置(IDE + placeholders) */\n const config = await loadCliConfig();\n\n /** 项目根目录 */\n const projectRoot = process.cwd();\n\n /** 合并所有来源的占位符 */\n const placeholders = resolvePlaceholders(config.placeholders);\n\n /** 合成所有输出文件 */\n const results = await synthesizeAll(config.agentType, projectRoot, placeholders);\n\n /** dry-run:仅预览 */\n if (options.dryRun) {\n previewResults(results);\n return;\n }\n\n /** 检测已存在的目标文件 */\n const existingTargets: string[] = [];\n\n for (const result of results) {\n if (await targetExists(projectRoot, result.output)) {\n existingTargets.push(result.output);\n }\n }\n\n /** 覆盖确认 */\n if (existingTargets.length > 0 && !options.force) {\n stdout(`${COLORS.YELLOW}将覆盖以下文件:${COLORS.RESET}`);\n for (const target of existingTargets) {\n stdout(` ${target}`);\n }\n\n /** 用户确认 */\n const confirmed = await promptInput(`\\n确认覆盖?(y/N): `);\n\n if (confirmed.toLowerCase() !== 'y') {\n stdout('已取消');\n return;\n }\n }\n\n /** 写入目标文件 */\n stdout('');\n stdout(`${COLORS.BLUE}正在写入...${COLORS.RESET}`);\n\n for (const result of results) {\n await writeResult(projectRoot, result);\n }\n\n stdout(`\\n${COLORS.GREEN}同步完成${COLORS.RESET} (Agent: ${config.agentType},共 ${results.length} 个文件)`);\n};\n"]}
@@ -1,39 +0,0 @@
1
- import { type AgentType, type SynthesisRule } from '@longzai-intelligence-agent-tools/core';
2
- import { type ResolvedPlaceholders } from '../../utils/placeholder-resolver';
3
- /**
4
- * 单个输出文件的合成结果
5
- */
6
- export type SynthesisResult = {
7
- /** 输出文件相对路径 */
8
- readonly output: string;
9
- /** 合成后的完整内容 */
10
- readonly content: string;
11
- /** 共同部分源文件路径(绝对) */
12
- readonly commonSourcePath: string;
13
- /** 独有部分源文件路径(绝对) */
14
- readonly agentSourcePath: string;
15
- };
16
- /**
17
- * 按合成规则合成单个输出文件
18
- *
19
- * 读取 agent.md(共同)+ agent.<type>.md(独有),拼接后做占位符替换。
20
- *
21
- * @param rule - 合成规则
22
- * @param projectRoot - 项目根目录绝对路径
23
- * @param placeholders - 已解析的占位符表
24
- * @returns 合成结果,源文件缺失时抛出错误
25
- * @throws Error 当共同部分或独有部分源文件不存在时
26
- */
27
- export declare const synthesizeOne: (rule: SynthesisRule, projectRoot: string, placeholders: ResolvedPlaceholders) => Promise<SynthesisResult>;
28
- /**
29
- * 合成某 Agent 类型的所有输出文件
30
- *
31
- * 按 SYNTHESIS_RULES 查表,逐条合成。
32
- *
33
- * @param agentType - 目标 Agent 类型
34
- * @param projectRoot - 项目根目录绝对路径
35
- * @param placeholders - 已解析的占位符表
36
- * @returns 所有输出文件的合成结果列表
37
- */
38
- export declare const synthesizeAll: (agentType: AgentType, projectRoot: string, placeholders: ResolvedPlaceholders) => Promise<SynthesisResult[]>;
39
- //# sourceMappingURL=synthesizer.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"synthesizer.d.ts","sourceRoot":"","sources":["../../../src/commands/sync/synthesizer.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,SAAS,EACd,KAAK,aAAa,EAGnB,MAAM,wCAAwC,CAAC;AAIhD,OAAO,EAAE,KAAK,oBAAoB,EAAuB,MAAM,8BAA8B,CAAC;AAE9F;;GAEG;AACH,MAAM,MAAM,eAAe,GAAG;IAC5B,eAAe;IACf,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,eAAe;IACf,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,oBAAoB;IACpB,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAC;IAClC,oBAAoB;IACpB,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAC;CAClC,CAAC;AAmBF;;;;;;;;;;GAUG;AACH,eAAO,MAAM,aAAa,SAClB,aAAa,eACN,MAAM,gBACL,oBAAoB,KACjC,OAAO,CAAC,eAAe,CA+BzB,CAAC;AAEF;;;;;;;;;GASG;AACH,eAAO,MAAM,aAAa,cACb,SAAS,eACP,MAAM,gBACL,oBAAoB,KACjC,OAAO,CAAC,eAAe,EAAE,CAc3B,CAAC"}
@@ -1,77 +0,0 @@
1
- import { LZI_DIR, SYNTHESIS_RULES, } from '@longzai-intelligence-agent-tools/core';
2
- import { join } from 'node:path';
3
- import { replacePlaceholders } from '../../utils/placeholder-resolver';
4
- /**
5
- * 读取源文件内容
6
- *
7
- * @param filePath - 文件绝对路径
8
- * @returns 文件内容字符串,文件不存在时返回 null
9
- */
10
- const readSourceFile = async (filePath) => {
11
- /** Bun 文件句柄 */
12
- const file = Bun.file(filePath);
13
- if (!(await file.exists())) {
14
- return null;
15
- }
16
- return file.text();
17
- };
18
- /**
19
- * 按合成规则合成单个输出文件
20
- *
21
- * 读取 agent.md(共同)+ agent.<type>.md(独有),拼接后做占位符替换。
22
- *
23
- * @param rule - 合成规则
24
- * @param projectRoot - 项目根目录绝对路径
25
- * @param placeholders - 已解析的占位符表
26
- * @returns 合成结果,源文件缺失时抛出错误
27
- * @throws Error 当共同部分或独有部分源文件不存在时
28
- */
29
- export const synthesizeOne = async (rule, projectRoot, placeholders) => {
30
- /** 共同部分源文件绝对路径 */
31
- const commonSourcePath = join(projectRoot, LZI_DIR, rule.commonSource);
32
- /** 独有部分源文件绝对路径 */
33
- const agentSourcePath = join(projectRoot, LZI_DIR, rule.agentSource);
34
- /** 读取共同部分 */
35
- const commonContent = await readSourceFile(commonSourcePath);
36
- if (commonContent === null) {
37
- throw new Error(`共同部分源文件不存在: ${commonSourcePath}`);
38
- }
39
- /** 读取独有部分 */
40
- const agentContent = await readSourceFile(agentSourcePath);
41
- if (agentContent === null) {
42
- throw new Error(`独有部分源文件不存在: ${agentSourcePath}`);
43
- }
44
- /** 拼接共同部分 + 独有部分(空行分隔) */
45
- const combined = `${commonContent.trimEnd()}\n\n${agentContent.trimEnd()}\n`;
46
- /** 占位符替换 */
47
- const content = replacePlaceholders(combined, placeholders);
48
- return {
49
- output: rule.output,
50
- content,
51
- commonSourcePath,
52
- agentSourcePath,
53
- };
54
- };
55
- /**
56
- * 合成某 Agent 类型的所有输出文件
57
- *
58
- * 按 SYNTHESIS_RULES 查表,逐条合成。
59
- *
60
- * @param agentType - 目标 Agent 类型
61
- * @param projectRoot - 项目根目录绝对路径
62
- * @param placeholders - 已解析的占位符表
63
- * @returns 所有输出文件的合成结果列表
64
- */
65
- export const synthesizeAll = async (agentType, projectRoot, placeholders) => {
66
- /** 该 Agent 类型的合成规则列表 */
67
- const rules = SYNTHESIS_RULES[agentType];
68
- /** 逐条合成 */
69
- const results = [];
70
- for (const rule of rules) {
71
- /** 单条合成结果 */
72
- const result = await synthesizeOne(rule, projectRoot, placeholders);
73
- results.push(result);
74
- }
75
- return results;
76
- };
77
- //# sourceMappingURL=synthesizer.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"synthesizer.js","sourceRoot":"","sources":["../../../src/commands/sync/synthesizer.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,OAAO,EACP,eAAe,GAChB,MAAM,wCAAwC,CAAC;AAEhD,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC,OAAO,EAA6B,mBAAmB,EAAE,MAAM,8BAA8B,CAAC;AAgB9F;;;;;GAKG;AACH,MAAM,cAAc,GAAG,KAAK,EAAE,QAAgB,EAA0B,EAAE;IACxE,eAAe;IACf,MAAM,IAAI,GAAG,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IAEhC,IAAI,CAAC,CAAC,MAAM,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,CAAC;QAC3B,OAAO,IAAI,CAAC;IACd,CAAC;IAED,OAAO,IAAI,CAAC,IAAI,EAAE,CAAC;AACrB,CAAC,CAAC;AAEF;;;;;;;;;;GAUG;AACH,MAAM,CAAC,MAAM,aAAa,GAAG,KAAK,EAChC,IAAmB,EACnB,WAAmB,EACnB,YAAkC,EACR,EAAE;IAC5B,kBAAkB;IAClB,MAAM,gBAAgB,GAAG,IAAI,CAAC,WAAW,EAAE,OAAO,EAAE,IAAI,CAAC,YAAY,CAAC,CAAC;IAEvE,kBAAkB;IAClB,MAAM,eAAe,GAAG,IAAI,CAAC,WAAW,EAAE,OAAO,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;IAErE,aAAa;IACb,MAAM,aAAa,GAAG,MAAM,cAAc,CAAC,gBAAgB,CAAC,CAAC;IAC7D,IAAI,aAAa,KAAK,IAAI,EAAE,CAAC;QAC3B,MAAM,IAAI,KAAK,CAAC,eAAe,gBAAgB,EAAE,CAAC,CAAC;IACrD,CAAC;IAED,aAAa;IACb,MAAM,YAAY,GAAG,MAAM,cAAc,CAAC,eAAe,CAAC,CAAC;IAC3D,IAAI,YAAY,KAAK,IAAI,EAAE,CAAC;QAC1B,MAAM,IAAI,KAAK,CAAC,eAAe,eAAe,EAAE,CAAC,CAAC;IACpD,CAAC;IAED,0BAA0B;IAC1B,MAAM,QAAQ,GAAG,GAAG,aAAa,CAAC,OAAO,EAAE,OAAO,YAAY,CAAC,OAAO,EAAE,IAAI,CAAC;IAE7E,YAAY;IACZ,MAAM,OAAO,GAAG,mBAAmB,CAAC,QAAQ,EAAE,YAAY,CAAC,CAAC;IAE5D,OAAO;QACL,MAAM,EAAE,IAAI,CAAC,MAAM;QACnB,OAAO;QACP,gBAAgB;QAChB,eAAe;KAChB,CAAC;AACJ,CAAC,CAAC;AAEF;;;;;;;;;GASG;AACH,MAAM,CAAC,MAAM,aAAa,GAAG,KAAK,EAChC,SAAoB,EACpB,WAAmB,EACnB,YAAkC,EACN,EAAE;IAC9B,wBAAwB;IACxB,MAAM,KAAK,GAAG,eAAe,CAAC,SAAS,CAAC,CAAC;IAEzC,WAAW;IACX,MAAM,OAAO,GAAsB,EAAE,CAAC;IAEtC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,aAAa;QACb,MAAM,MAAM,GAAG,MAAM,aAAa,CAAC,IAAI,EAAE,WAAW,EAAE,YAAY,CAAC,CAAC;QACpE,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IACvB,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC,CAAC","sourcesContent":["import {\n type AgentType,\n type SynthesisRule,\n LZI_DIR,\n SYNTHESIS_RULES,\n} from '@longzai-intelligence-agent-tools/core';\n\nimport { join } from 'node:path';\n\nimport { type ResolvedPlaceholders, replacePlaceholders } from '@/utils/placeholder-resolver';\n\n/**\n * 单个输出文件的合成结果\n */\nexport type SynthesisResult = {\n /** 输出文件相对路径 */\n readonly output: string;\n /** 合成后的完整内容 */\n readonly content: string;\n /** 共同部分源文件路径(绝对) */\n readonly commonSourcePath: string;\n /** 独有部分源文件路径(绝对) */\n readonly agentSourcePath: string;\n};\n\n/**\n * 读取源文件内容\n *\n * @param filePath - 文件绝对路径\n * @returns 文件内容字符串,文件不存在时返回 null\n */\nconst readSourceFile = async (filePath: string): Promise<string | null> => {\n /** Bun 文件句柄 */\n const file = Bun.file(filePath);\n\n if (!(await file.exists())) {\n return null;\n }\n\n return file.text();\n};\n\n/**\n * 按合成规则合成单个输出文件\n *\n * 读取 agent.md(共同)+ agent.<type>.md(独有),拼接后做占位符替换。\n *\n * @param rule - 合成规则\n * @param projectRoot - 项目根目录绝对路径\n * @param placeholders - 已解析的占位符表\n * @returns 合成结果,源文件缺失时抛出错误\n * @throws Error 当共同部分或独有部分源文件不存在时\n */\nexport const synthesizeOne = async (\n rule: SynthesisRule,\n projectRoot: string,\n placeholders: ResolvedPlaceholders,\n): Promise<SynthesisResult> => {\n /** 共同部分源文件绝对路径 */\n const commonSourcePath = join(projectRoot, LZI_DIR, rule.commonSource);\n\n /** 独有部分源文件绝对路径 */\n const agentSourcePath = join(projectRoot, LZI_DIR, rule.agentSource);\n\n /** 读取共同部分 */\n const commonContent = await readSourceFile(commonSourcePath);\n if (commonContent === null) {\n throw new Error(`共同部分源文件不存在: ${commonSourcePath}`);\n }\n\n /** 读取独有部分 */\n const agentContent = await readSourceFile(agentSourcePath);\n if (agentContent === null) {\n throw new Error(`独有部分源文件不存在: ${agentSourcePath}`);\n }\n\n /** 拼接共同部分 + 独有部分(空行分隔) */\n const combined = `${commonContent.trimEnd()}\\n\\n${agentContent.trimEnd()}\\n`;\n\n /** 占位符替换 */\n const content = replacePlaceholders(combined, placeholders);\n\n return {\n output: rule.output,\n content,\n commonSourcePath,\n agentSourcePath,\n };\n};\n\n/**\n * 合成某 Agent 类型的所有输出文件\n *\n * 按 SYNTHESIS_RULES 查表,逐条合成。\n *\n * @param agentType - 目标 Agent 类型\n * @param projectRoot - 项目根目录绝对路径\n * @param placeholders - 已解析的占位符表\n * @returns 所有输出文件的合成结果列表\n */\nexport const synthesizeAll = async (\n agentType: AgentType,\n projectRoot: string,\n placeholders: ResolvedPlaceholders,\n): Promise<SynthesisResult[]> => {\n /** 该 Agent 类型的合成规则列表 */\n const rules = SYNTHESIS_RULES[agentType];\n\n /** 逐条合成 */\n const results: SynthesisResult[] = [];\n\n for (const rule of rules) {\n /** 单条合成结果 */\n const result = await synthesizeOne(rule, projectRoot, placeholders);\n results.push(result);\n }\n\n return results;\n};\n"]}
package/dist/config.d.ts DELETED
@@ -1,21 +0,0 @@
1
- import { type AgentType } from '@longzai-intelligence-agent-tools/core';
2
- /**
3
- * CLI 运行时配置
4
- *
5
- * 合并来源:环境变量(Agent 类型)+ lzi.config.ts(placeholders)。
6
- */
7
- export type CliConfig = {
8
- /** 当前 Agent 类型 */
9
- readonly agentType: AgentType;
10
- /** 占位符表(已合并所有来源) */
11
- readonly placeholders?: Record<string, string>;
12
- };
13
- /**
14
- * 加载完整 CLI 配置
15
- *
16
- * Agent 类型来自环境变量,placeholders 来自 lzi.config.ts。
17
- *
18
- * @returns CLI 配置,Agent 类型未配置时退出进程
19
- */
20
- export declare const loadCliConfig: () => Promise<CliConfig>;
21
- //# sourceMappingURL=config.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,SAAS,EAGf,MAAM,wCAAwC,CAAC;AAKhD;;;;GAIG;AACH,MAAM,MAAM,SAAS,GAAG;IACtB,kBAAkB;IAClB,QAAQ,CAAC,SAAS,EAAE,SAAS,CAAC;IAC9B,oBAAoB;IACpB,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAChD,CAAC;AAsCF;;;;;;GAMG;AACH,eAAO,MAAM,aAAa,QAAa,OAAO,CAAC,SAAS,CAiBvD,CAAC"}
package/dist/config.js DELETED
@@ -1,56 +0,0 @@
1
- import { ENV_KEYS, VALID_AGENTS, } from '@longzai-intelligence-agent-tools/core';
2
- import { loadUnifiedConfig } from '@longzai-intelligence-shared-config/core';
3
- import { stderr } from './utils/cli-output';
4
- /**
5
- * 从环境变量读取当前 Agent 类型
6
- *
7
- * @returns Agent 类型标识,若未配置或非法则返回 null
8
- */
9
- const readAgentTypeFromEnv = () => {
10
- /** 环境变量值 */
11
- const raw = process.env[ENV_KEYS.AGENT_TYPE];
12
- if (!raw) {
13
- return null;
14
- }
15
- if (!VALID_AGENTS.includes(raw)) {
16
- stderr(`错误: ${ENV_KEYS.AGENT_TYPE} 值 '${raw}' 无效,合法值为: ${VALID_AGENTS.join(', ')}`);
17
- return null;
18
- }
19
- return raw;
20
- };
21
- /**
22
- * 从统一配置 lzi.config.ts 读取 agentTools 配置
23
- *
24
- * 使用 shared-config 的 loadUnifiedConfig 统一加载。
25
- *
26
- * @returns agentTools 配置,未找到时返回 undefined
27
- */
28
- const loadAgentToolsConfig = async () => {
29
- const result = await loadUnifiedConfig({
30
- unifiedField: 'agentTools',
31
- });
32
- return result.success ? result.config : undefined;
33
- };
34
- /**
35
- * 加载完整 CLI 配置
36
- *
37
- * Agent 类型来自环境变量,placeholders 来自 lzi.config.ts。
38
- *
39
- * @returns CLI 配置,Agent 类型未配置时退出进程
40
- */
41
- export const loadCliConfig = async () => {
42
- /** 从环境变量读 Agent 类型 */
43
- const agentType = readAgentTypeFromEnv();
44
- if (!agentType) {
45
- stderr(`错误: 环境变量 ${ENV_KEYS.AGENT_TYPE} 未设置`);
46
- stderr(`请在 .env 中配置,合法值为: ${VALID_AGENTS.join(', ')}`);
47
- process.exit(1);
48
- }
49
- /** 加载 agentTools 配置 */
50
- const agentTools = await loadAgentToolsConfig();
51
- return {
52
- agentType,
53
- placeholders: agentTools?.placeholders,
54
- };
55
- };
56
- //# sourceMappingURL=config.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,QAAQ,EACR,YAAY,GACb,MAAM,wCAAwC,CAAC;AAChD,OAAO,EAAE,iBAAiB,EAAE,MAAM,0CAA0C,CAAC;AAE7E,OAAO,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAc5C;;;;GAIG;AACH,MAAM,oBAAoB,GAAG,GAAqB,EAAE;IAClD,YAAY;IACZ,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC;IAE7C,IAAI,CAAC,GAAG,EAAE,CAAC;QACT,OAAO,IAAI,CAAC;IACd,CAAC;IAED,IAAI,CAAC,YAAY,CAAC,QAAQ,CAAC,GAAgB,CAAC,EAAE,CAAC;QAC7C,MAAM,CAAC,OAAO,QAAQ,CAAC,UAAU,OAAO,GAAG,cAAc,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACpF,OAAO,IAAI,CAAC;IACd,CAAC;IAED,OAAO,GAAgB,CAAC;AAC1B,CAAC,CAAC;AAEF;;;;;;GAMG;AACH,MAAM,oBAAoB,GAAG,KAAK,IAA2C,EAAE;IAC7E,MAAM,MAAM,GAAG,MAAM,iBAAiB,CAAmB;QACvD,YAAY,EAAE,YAAY;KAC3B,CAAC,CAAC;IAEH,OAAO,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC;AACpD,CAAC,CAAC;AAEF;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,aAAa,GAAG,KAAK,IAAwB,EAAE;IAC1D,sBAAsB;IACtB,MAAM,SAAS,GAAG,oBAAoB,EAAE,CAAC;IAEzC,IAAI,CAAC,SAAS,EAAE,CAAC;QACf,MAAM,CAAC,YAAY,QAAQ,CAAC,UAAU,MAAM,CAAC,CAAC;QAC9C,MAAM,CAAC,qBAAqB,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACvD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,uBAAuB;IACvB,MAAM,UAAU,GAAG,MAAM,oBAAoB,EAAE,CAAC;IAEhD,OAAO;QACL,SAAS;QACT,YAAY,EAAE,UAAU,EAAE,YAAY;KACvC,CAAC;AACJ,CAAC,CAAC","sourcesContent":["import {\n type AgentToolsConfig,\n type AgentType,\n ENV_KEYS,\n VALID_AGENTS,\n} from '@longzai-intelligence-agent-tools/core';\nimport { loadUnifiedConfig } from '@longzai-intelligence-shared-config/core';\n\nimport { stderr } from '@/utils/cli-output';\n\n/**\n * CLI 运行时配置\n *\n * 合并来源:环境变量(Agent 类型)+ lzi.config.ts(placeholders)。\n */\nexport type CliConfig = {\n /** 当前 Agent 类型 */\n readonly agentType: AgentType;\n /** 占位符表(已合并所有来源) */\n readonly placeholders?: Record<string, string>;\n};\n\n/**\n * 从环境变量读取当前 Agent 类型\n *\n * @returns Agent 类型标识,若未配置或非法则返回 null\n */\nconst readAgentTypeFromEnv = (): AgentType | null => {\n /** 环境变量值 */\n const raw = process.env[ENV_KEYS.AGENT_TYPE];\n\n if (!raw) {\n return null;\n }\n\n if (!VALID_AGENTS.includes(raw as AgentType)) {\n stderr(`错误: ${ENV_KEYS.AGENT_TYPE} 值 '${raw}' 无效,合法值为: ${VALID_AGENTS.join(', ')}`);\n return null;\n }\n\n return raw as AgentType;\n};\n\n/**\n * 从统一配置 lzi.config.ts 读取 agentTools 配置\n *\n * 使用 shared-config 的 loadUnifiedConfig 统一加载。\n *\n * @returns agentTools 配置,未找到时返回 undefined\n */\nconst loadAgentToolsConfig = async (): Promise<AgentToolsConfig | undefined> => {\n const result = await loadUnifiedConfig<AgentToolsConfig>({\n unifiedField: 'agentTools',\n });\n\n return result.success ? result.config : undefined;\n};\n\n/**\n * 加载完整 CLI 配置\n *\n * Agent 类型来自环境变量,placeholders 来自 lzi.config.ts。\n *\n * @returns CLI 配置,Agent 类型未配置时退出进程\n */\nexport const loadCliConfig = async (): Promise<CliConfig> => {\n /** 从环境变量读 Agent 类型 */\n const agentType = readAgentTypeFromEnv();\n\n if (!agentType) {\n stderr(`错误: 环境变量 ${ENV_KEYS.AGENT_TYPE} 未设置`);\n stderr(`请在 .env 中配置,合法值为: ${VALID_AGENTS.join(', ')}`);\n process.exit(1);\n }\n\n /** 加载 agentTools 配置 */\n const agentTools = await loadAgentToolsConfig();\n\n return {\n agentType,\n placeholders: agentTools?.placeholders,\n };\n};\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA;;;GAGG"}
package/dist/index.js.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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","sourcesContent":["#!/usr/bin/env bun\n/**\n * Longzai Intelligence Agent Tools CLI\n * 把 .lzi/ 下的源 markdown 按当前 IDE 合成,同步覆盖为 CLAUDE.md / AGENTS.md。\n */\n\nimport { initCommand } from '@/commands/init';\nimport { statusCommand } from '@/commands/status';\nimport { syncCommand } from '@/commands/sync';\n\nimport { stderr, stdout } from '@/utils/cli-output';\n\n/**\n * CLI 工具名称\n */\nconst CLI_NAME = 'lzi-agent-cli';\n\n/**\n * 全局帮助信息\n */\nconst HELP_TEXT = `\n${CLI_NAME} - Longzai Intelligence Agent Tools\n\n把 .lzi/ 下的源 markdown(共同部分 + 各 IDE 独有部分)按当前 IDE 自动合成,\n同步覆盖为 CLAUDE.md / AGENTS.md。\n\n源文件(.lzi/ 下):\n agent.md 共同部分\n agent.claude.md claude 独有\n agent.trae.md trae 独有\n agent.zcode.md zcode 独有\n\n用法:\n ${CLI_NAME} <command> [options]\n\n命令:\n init 创建 .lzi/ 目录和源文件骨架\n [--dry-run] 仅预览将创建的文件\n\n sync 合成并同步覆盖目标文件\n [--dry-run] 仅预览,不写入文件\n [--force] 跳过覆盖确认\n\n status 显示当前 Agent 类型、源文件存在性、输出目标\n\n环境变量:\n LZI_AGENT_TYPE 当前 Agent 类型(claude | trae | zcode)\n LZI_PLACEHOLDER_<KEY> 占位符值(可选,优先级低于 lzi.config.ts)\n\n选项:\n --help 显示帮助信息\n --version 显示版本号\n`;\n\n/**\n * 显示全局帮助信息并退出\n */\nconst showHelp = (): void => {\n stdout(HELP_TEXT.trim());\n process.exit(0);\n};\n\n/**\n * 显示版本号并退出\n */\nconst showVersion = (): void => {\n /** 从 package.json 读取版本号 */\n const version = '0.0.1';\n stdout(`${CLI_NAME} v${version}`);\n process.exit(0);\n};\n\n/**\n * 解析 sync 命令标志\n *\n * @param args - 参数列表\n * @returns 解析后的标志\n */\ntype ParseSyncFlagsResult = { dryRun: boolean; force: boolean };\n\nconst parseSyncFlags = (args: readonly string[]): ParseSyncFlagsResult => {\n /** dry-run 标志 */\n const dryRun = args.includes('--dry-run');\n /** force 标志 */\n const force = args.includes('--force');\n\n return { dryRun, force };\n};\n\n/**\n * CLI 主入口函数\n *\n * 解析命令行参数并路由到对应命令。\n */\nconst main = async (): Promise<void> => {\n /** 命令行参数(去除 node 和脚本路径) */\n const args = process.argv.slice(2);\n\n if (args.length === 0 || args[0] === '--help') {\n showHelp();\n return;\n }\n\n if (args[0] === '--version') {\n showVersion();\n return;\n }\n\n /** 命令名称 */\n const command = args[0];\n\n /** 命令参数 */\n const cmdArgs = args.slice(1);\n\n switch (command) {\n case 'init': {\n /** 解析标志 */\n const { dryRun } = parseSyncFlags(cmdArgs);\n await initCommand({ dryRun });\n break;\n }\n case 'sync': {\n /** 解析标志 */\n const { dryRun, force } = parseSyncFlags(cmdArgs);\n await syncCommand({ dryRun, force });\n break;\n }\n case 'status': {\n await statusCommand();\n break;\n }\n default: {\n stderr(`错误: 未知命令 '${command}'`);\n stderr(`使用 '${CLI_NAME} --help' 查看可用命令`);\n process.exit(1);\n }\n }\n};\n\nmain().catch((err) => {\n stderr('错误:', err instanceof Error ? err.message : String(err));\n process.exit(1);\n});\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"file":"placeholder-resolver.d.ts","sourceRoot":"","sources":["../../src/utils/placeholder-resolver.ts"],"names":[],"mappings":"AAEA;;GAEG;AACH,MAAM,MAAM,oBAAoB,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AA+C1D;;;;;;;;;;GAUG;AACH,eAAO,MAAM,mBAAmB,wBACT,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,KAC1C,oBAaF,CAAC;AAEF;;;;;;;;GAQG;AACH,eAAO,MAAM,mBAAmB,YACrB,MAAM,gBACD,oBAAoB,KACjC,MAIF,CAAC"}
@@ -1,77 +0,0 @@
1
- import { BUILTIN_PLACEHOLDERS, ENV_KEYS } from '@longzai-intelligence-agent-tools/core';
2
- /**
3
- * 占位符正则
4
- *
5
- * 匹配 {{KEY}} 形式的占位符,KEY 为大写字母、数字、下划线。
6
- */
7
- const PLACEHOLDER_PATTERN = /\{\{([A-Z][A-Z0-9_]*)\}\}/g;
8
- /**
9
- * 从环境变量收集 LZI_PLACEHOLDER_* 前缀的占位符
10
- *
11
- * @returns 环境变量占位符键值对
12
- */
13
- const collectEnvPlaceholders = () => {
14
- /** 收集结果 */
15
- const result = {};
16
- for (const [key, value] of Object.entries(process.env)) {
17
- if (key.startsWith(ENV_KEYS.PLACEHOLDER_PREFIX) && value !== undefined) {
18
- /** 去掉前缀得到占位符 KEY */
19
- const placeholderKey = key.slice(ENV_KEYS.PLACEHOLDER_PREFIX.length);
20
- result[placeholderKey] = value;
21
- }
22
- }
23
- return result;
24
- };
25
- /**
26
- * 解析内置占位符
27
- *
28
- * 内置占位符是动态计算的(如 DATE、PROJECT_NAME)。
29
- *
30
- * @returns 内置占位符键值对
31
- */
32
- const resolveBuiltinPlaceholders = () => {
33
- /** 解析结果 */
34
- const result = {};
35
- for (const [key, factory] of Object.entries(BUILTIN_PLACEHOLDERS)) {
36
- result[key] = factory();
37
- }
38
- return result;
39
- };
40
- /**
41
- * 合并所有来源的占位符
42
- *
43
- * 优先级(后者覆盖前者):
44
- * 1. 内置占位符(DATE、PROJECT_NAME)
45
- * 2. 环境变量 LZI_PLACEHOLDER_*
46
- * 3. lzi.config.ts 的 agentTools.placeholders
47
- *
48
- * @param configPlaceholders - 来自 lzi.config.ts 的占位符
49
- * @returns 合并后的完整占位符表
50
- */
51
- export const resolvePlaceholders = (configPlaceholders) => {
52
- /** 内置占位符(最低优先级) */
53
- const builtin = resolveBuiltinPlaceholders();
54
- /** 环境变量占位符 */
55
- const env = collectEnvPlaceholders();
56
- /** 合并:内置 → env → config(后者覆盖前者) */
57
- return {
58
- ...builtin,
59
- ...env,
60
- ...(configPlaceholders ?? {}),
61
- };
62
- };
63
- /**
64
- * 替换内容中的占位符
65
- *
66
- * 将所有 {{KEY}} 替换为对应值。未匹配的占位符原样保留。
67
- *
68
- * @param content - 待替换的内容字符串
69
- * @param placeholders - 占位符键值对
70
- * @returns 替换后的内容字符串
71
- */
72
- export const replacePlaceholders = (content, placeholders) => {
73
- return content.replace(PLACEHOLDER_PATTERN, (match, key) => {
74
- return placeholders[key] ?? match;
75
- });
76
- };
77
- //# sourceMappingURL=placeholder-resolver.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"placeholder-resolver.js","sourceRoot":"","sources":["../../src/utils/placeholder-resolver.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,QAAQ,EAAE,MAAM,wCAAwC,CAAC;AAOxF;;;;GAIG;AACH,MAAM,mBAAmB,GAAG,4BAA4B,CAAC;AAEzD;;;;GAIG;AACH,MAAM,sBAAsB,GAAG,GAA2B,EAAE;IAC1D,WAAW;IACX,MAAM,MAAM,GAA2B,EAAE,CAAC;IAE1C,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;QACvD,IAAI,GAAG,CAAC,UAAU,CAAC,QAAQ,CAAC,kBAAkB,CAAC,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;YACvE,oBAAoB;YACpB,MAAM,cAAc,GAAG,GAAG,CAAC,KAAK,CAAC,QAAQ,CAAC,kBAAkB,CAAC,MAAM,CAAC,CAAC;YACrE,MAAM,CAAC,cAAc,CAAC,GAAG,KAAK,CAAC;QACjC,CAAC;IACH,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC,CAAC;AAEF;;;;;;GAMG;AACH,MAAM,0BAA0B,GAAG,GAA2B,EAAE;IAC9D,WAAW;IACX,MAAM,MAAM,GAA2B,EAAE,CAAC;IAE1C,KAAK,MAAM,CAAC,GAAG,EAAE,OAAO,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,oBAAoB,CAAC,EAAE,CAAC;QAClE,MAAM,CAAC,GAAG,CAAC,GAAG,OAAO,EAAE,CAAC;IAC1B,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC,CAAC;AAEF;;;;;;;;;;GAUG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG,CACjC,kBAA2C,EACrB,EAAE;IACxB,mBAAmB;IACnB,MAAM,OAAO,GAAG,0BAA0B,EAAE,CAAC;IAE7C,cAAc;IACd,MAAM,GAAG,GAAG,sBAAsB,EAAE,CAAC;IAErC,mCAAmC;IACnC,OAAO;QACL,GAAG,OAAO;QACV,GAAG,GAAG;QACN,GAAG,CAAC,kBAAkB,IAAI,EAAE,CAAC;KAC9B,CAAC;AACJ,CAAC,CAAC;AAEF;;;;;;;;GAQG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG,CACjC,OAAe,EACf,YAAkC,EAC1B,EAAE;IACV,OAAO,OAAO,CAAC,OAAO,CAAC,mBAAmB,EAAE,CAAC,KAAK,EAAE,GAAW,EAAE,EAAE;QACjE,OAAO,YAAY,CAAC,GAAG,CAAC,IAAI,KAAK,CAAC;IACpC,CAAC,CAAC,CAAC;AACL,CAAC,CAAC","sourcesContent":["import { BUILTIN_PLACEHOLDERS, ENV_KEYS } from '@longzai-intelligence-agent-tools/core';\n\n/**\n * 占位符解析结果\n */\nexport type ResolvedPlaceholders = Record<string, string>;\n\n/**\n * 占位符正则\n *\n * 匹配 {{KEY}} 形式的占位符,KEY 为大写字母、数字、下划线。\n */\nconst PLACEHOLDER_PATTERN = /\\{\\{([A-Z][A-Z0-9_]*)\\}\\}/g;\n\n/**\n * 从环境变量收集 LZI_PLACEHOLDER_* 前缀的占位符\n *\n * @returns 环境变量占位符键值对\n */\nconst collectEnvPlaceholders = (): Record<string, string> => {\n /** 收集结果 */\n const result: Record<string, string> = {};\n\n for (const [key, value] of Object.entries(process.env)) {\n if (key.startsWith(ENV_KEYS.PLACEHOLDER_PREFIX) && value !== undefined) {\n /** 去掉前缀得到占位符 KEY */\n const placeholderKey = key.slice(ENV_KEYS.PLACEHOLDER_PREFIX.length);\n result[placeholderKey] = value;\n }\n }\n\n return result;\n};\n\n/**\n * 解析内置占位符\n *\n * 内置占位符是动态计算的(如 DATE、PROJECT_NAME)。\n *\n * @returns 内置占位符键值对\n */\nconst resolveBuiltinPlaceholders = (): Record<string, string> => {\n /** 解析结果 */\n const result: Record<string, string> = {};\n\n for (const [key, factory] of Object.entries(BUILTIN_PLACEHOLDERS)) {\n result[key] = factory();\n }\n\n return result;\n};\n\n/**\n * 合并所有来源的占位符\n *\n * 优先级(后者覆盖前者):\n * 1. 内置占位符(DATE、PROJECT_NAME)\n * 2. 环境变量 LZI_PLACEHOLDER_*\n * 3. lzi.config.ts 的 agentTools.placeholders\n *\n * @param configPlaceholders - 来自 lzi.config.ts 的占位符\n * @returns 合并后的完整占位符表\n */\nexport const resolvePlaceholders = (\n configPlaceholders?: Record<string, string>,\n): ResolvedPlaceholders => {\n /** 内置占位符(最低优先级) */\n const builtin = resolveBuiltinPlaceholders();\n\n /** 环境变量占位符 */\n const env = collectEnvPlaceholders();\n\n /** 合并:内置 → env → config(后者覆盖前者) */\n return {\n ...builtin,\n ...env,\n ...(configPlaceholders ?? {}),\n };\n};\n\n/**\n * 替换内容中的占位符\n *\n * 将所有 {{KEY}} 替换为对应值。未匹配的占位符原样保留。\n *\n * @param content - 待替换的内容字符串\n * @param placeholders - 占位符键值对\n * @returns 替换后的内容字符串\n */\nexport const replacePlaceholders = (\n content: string,\n placeholders: ResolvedPlaceholders,\n): string => {\n return content.replace(PLACEHOLDER_PATTERN, (match, key: string) => {\n return placeholders[key] ?? match;\n });\n};\n"]}