@longzai-intelligence-toolchain/core 0.0.0-stage → 0.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,3 +1,9 @@
1
- # Temporary Holding Version
1
+ # @longzai-intelligence-toolchain/core
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ 开发工具类项目的核心包模板,承载项目核心类型定义与配置校验能力,为 CLI 与 Dashboard 应用提供共享的类型与校验函数。
4
+
5
+ 定位为 dev-tool 项目模板 monorepo 的核心 packages 包,归属于 `packages/*` workspace,是 apps/cli 与 apps/dashboard 共同依赖的底层包。上游被同项目内的 cli 与 dashboard 通过 `workspace:*` 引用,自身依赖 zod 提供 Schema 校验能力,不反向依赖任何应用层包。
6
+
7
+ 职能上,该包通过 src/index.ts 对外导出 CoreConfig 类型与 validateConfig 校验函数:CoreConfig 定义项目核心配置的数据结构,validateConfig 基于 zod 对配置进行运行时校验。构建产物经 tsgo --build 与 resolve-aliases 处理别名解析,再由 tsdown 产出生产构建,导出路径通过 exports 字段限定为 ./dist/index.js 与对应的类型声明。
8
+
9
+ 实现情况为脚手架模板初始状态,package.json 的脚本(build、build:prod、typecheck、lint、test、clean 等)与 exports 声明均已就绪,zod 依赖已声明。src/index.ts 已定义导出契约,但其引用的 ./types 与 ./validate 模块文件尚未在模板中提供,需在使用模板后由开发者按导出契约补齐具体实现。
@@ -0,0 +1,456 @@
1
+ import "./rolldown-runtime-BqT_7tdF.js";
2
+ import * as z from "zod";
3
+ import { DomainOverride, loadToolchainConfig } from "@longzai-intelligence-toolchain/config";
4
+ //#region src/domain-entry.types.d.ts
5
+ /**
6
+ * 委托域表条目
7
+ *
8
+ * @remarks
9
+ * ADR 0147 决策 2:域表按域主自持范式落本包,条目一律经 `defineDomainEntry` 工厂导出并
10
+ * 过 zod 运行时校验,禁裸对象字面量
11
+ */
12
+ type DomainEntry = {
13
+ /**
14
+ * 域名,即伞形 CLI 的一级子命令名
15
+ */
16
+ domain: string;
17
+ /**
18
+ * 该域引擎的 bin 名
19
+ */
20
+ bin: string;
21
+ /**
22
+ * 引擎 bin 所属的 npm 包名,用于 bin 缺失时给出补依赖指引
23
+ */
24
+ packageName: string;
25
+ /**
26
+ * 域职责的一句话说明,显示于 `--help`
27
+ */
28
+ description: string;
29
+ };
30
+ /**
31
+ * 域表条目的 zod schema
32
+ */
33
+ declare const domainEntrySchema: z.ZodObject<{
34
+ domain: z.ZodString;
35
+ bin: z.ZodString;
36
+ packageName: z.ZodString;
37
+ description: z.ZodString;
38
+ }, z.core.$strip>;
39
+ /**
40
+ * 域表条目声明工厂
41
+ *
42
+ * @remarks
43
+ * 传入值经 zod 运行时校验,校验失败即抛错并携带字段路径,禁止静默收录非法条目。
44
+ * 校验通过时返回原对象,保持引用稳定。
45
+ * @param entry - 域表条目
46
+ * @returns 经校验的域表条目
47
+ * @throws {@link Error} 条目校验失败时抛出,消息含字段路径与原因
48
+ */
49
+ declare const defineDomainEntry: (entry: DomainEntry) => DomainEntry;
50
+ //#endregion
51
+ //#region src/domain-table.constants.d.ts
52
+ /**
53
+ * 委托域表
54
+ *
55
+ * @remarks
56
+ * v1 委托域集按 ADR 0147 决策 2 登记,覆盖产品群现行工程操作引擎。
57
+ * 增删域一律编辑本文件,经 `defineDomainEntry` 工厂声明,禁止散落硬编码
58
+ */
59
+ declare const DOMAIN_ENTRIES: readonly DomainEntry[];
60
+ /**
61
+ * 委托域数量
62
+ */
63
+ declare const DOMAIN_COUNT: number;
64
+ //#endregion
65
+ //#region src/bin-resolution.utils.d.ts
66
+ /**
67
+ * 解析 bin 名到可执行文件路径
68
+ *
69
+ * @remarks
70
+ * 解析顺序:绝对路径直接判定。相对名先自 `process.cwd()` 逐级向上的
71
+ * `node_modules/.bin` 目录探测,再按 `PATH` 环境变量逐目录探测。
72
+ * 两段均未命中返回 null,调用方据此给出补依赖指引。
73
+ * @param bin - bin 名或绝对路径
74
+ * @returns 可执行文件路径,未命中为 null
75
+ */
76
+ declare const resolveBinCommand: (bin: string) => string | null;
77
+ //#endregion
78
+ //#region src/delegate.usecase.d.ts
79
+ /**
80
+ * 委托执行结果
81
+ */
82
+ type DelegateResult = {
83
+ /**
84
+ * 引擎进程退出码,或约定失败码
85
+ */
86
+ exitCode: number;
87
+ };
88
+ /**
89
+ * 把域命令委托给引擎 bin 执行
90
+ *
91
+ * @remarks
92
+ * 伞形层只委托不实现:参数数组原样透传,stdin、stdout、stderr 全部继承父进程,
93
+ * 引擎退出码原样返回,由调用方决定进程退出。域被就地配置禁用时记录错误并返回 1。
94
+ * bin 解析失败时输出补依赖指引并返回 127
95
+ * @param entry - 域表条目
96
+ * @param args - 原样透传给引擎的参数数组
97
+ * @param override - 就地配置的域覆盖项,缺省无覆盖
98
+ * @returns 委托执行结果,含退出码
99
+ */
100
+ declare const delegateToDomain: (entry: DomainEntry, args: readonly string[], override?: DomainOverride) => Promise<DelegateResult>;
101
+ //#endregion
102
+ //#region src/check-table.constants.d.ts
103
+ /**
104
+ * check 聚合命令的检查项条目
105
+ *
106
+ * @remarks
107
+ * 检查项映射到域表内既有域的引擎 check 子命令,伞形只登记映射不实现
108
+ * 检查逻辑。增删检查项一律编辑本文件,经 `defineCheckEntry` 工厂声明
109
+ */
110
+ type CheckEntry = {
111
+ /**
112
+ * 检查项 id,聚合报告与 include/exclude 选择的定位键
113
+ */
114
+ id: string;
115
+ /**
116
+ * 所属域名,须为域表内既有域名
117
+ */
118
+ domain: string;
119
+ /**
120
+ * 原样透传给引擎 bin 的参数数组
121
+ */
122
+ args: readonly string[];
123
+ /**
124
+ * 是否属于核心集,核心集缺引擎计失败附补依赖指引,扩展集缺引擎注记不适用
125
+ */
126
+ core: boolean;
127
+ /**
128
+ * 能力探测标记,非空时先以 help 输出判定该子命令在已安装引擎版本中是否存在
129
+ */
130
+ probe?: string;
131
+ /**
132
+ * 检查项职责的一句话说明,显示于聚合报告
133
+ */
134
+ description: string;
135
+ };
136
+ /**
137
+ * 检查项条目的 zod schema
138
+ */
139
+ declare const checkEntrySchema: z.ZodObject<{
140
+ id: z.ZodString;
141
+ domain: z.ZodString;
142
+ args: z.ZodArray<z.ZodString>;
143
+ core: z.ZodBoolean;
144
+ probe: z.ZodOptional<z.ZodString>;
145
+ description: z.ZodString;
146
+ }, z.core.$strip>;
147
+ /**
148
+ * 检查项条目声明工厂
149
+ *
150
+ * @remarks
151
+ * 传入值经 zod 运行时校验,校验失败即抛错并携带字段路径,禁止静默收录非法条目
152
+ * @param entry - 检查项条目
153
+ * @returns 经校验的检查项条目
154
+ * @throws {@link Error} 条目校验失败时抛出,消息含字段路径与原因
155
+ */
156
+ declare const defineCheckEntry: (entry: CheckEntry) => CheckEntry;
157
+ /**
158
+ * check 聚合命令的检查项表
159
+ *
160
+ * @remarks
161
+ * 核心集为每仓应具备的基线检查,扩展集为域表内既有域的独占检查,
162
+ * 扩展集以引擎 bin 可解析为纳入条件。域表外引擎的检查不入本表
163
+ */
164
+ declare const CHECK_ENTRIES: readonly CheckEntry[];
165
+ //#endregion
166
+ //#region src/check.usecase.d.ts
167
+ /**
168
+ * 单个检查项的执行状态
169
+ *
170
+ * @remarks
171
+ * pass 与 fail 为引擎退出码判定。missing 为核心集缺引擎,计入失败。
172
+ * not-applicable 为扩展集缺引擎,capability-missing 为引擎版本不含
173
+ * 子命令,disabled 为就地配置禁用,三者均不计入失败
174
+ */
175
+ type CheckRunStatus = 'pass' | 'fail' | 'missing' | 'not-applicable' | 'capability-missing' | 'disabled';
176
+ /**
177
+ * 单个检查项的执行结果
178
+ */
179
+ type CheckItemResult = {
180
+ /**
181
+ * 检查项 id
182
+ */
183
+ id: string;
184
+ /**
185
+ * 所属域名
186
+ */
187
+ domain: string;
188
+ /**
189
+ * 实际执行的引擎命令展示文本
190
+ */
191
+ command: string;
192
+ /**
193
+ * 执行状态
194
+ */
195
+ status: CheckRunStatus;
196
+ /**
197
+ * 引擎退出码,未实际执行时为 null
198
+ */
199
+ exitCode: number | null;
200
+ };
201
+ /**
202
+ * 聚合执行结果
203
+ */
204
+ type CheckRunResult = {
205
+ /**
206
+ * 各检查项结果,按执行顺序排列
207
+ */
208
+ results: CheckItemResult[];
209
+ /**
210
+ * 聚合退出码,失败项数上限 255
211
+ */
212
+ exitCode: number;
213
+ };
214
+ /**
215
+ * check 聚合命令的入参选项
216
+ */
217
+ type CheckRunOptions = {
218
+ /**
219
+ * 限定执行的检查项,值为检查项 id 或域名
220
+ */
221
+ only?: readonly string[];
222
+ /**
223
+ * 剔除的检查项,值为检查项 id 或域名
224
+ */
225
+ skip?: readonly string[];
226
+ };
227
+ /**
228
+ * 执行 check 聚合命令
229
+ *
230
+ * @remarks
231
+ * 检查项选择优先级为命令行 `only`、就地配置 `checks.include`、默认全集,
232
+ * 命令行 `skip` 与就地配置 `checks.exclude` 叠加剔除。串行执行不
233
+ * fail-fast,末尾输出汇总与修复指引。聚合退出码为失败项数,其中
234
+ * 核心集缺引擎计入失败,上限 255
235
+ * @param options - 聚合命令入参选项
236
+ * @returns 聚合执行结果,含逐项结果与退出码
237
+ */
238
+ declare const runCheckCommand: (options?: CheckRunOptions) => Promise<CheckRunResult>;
239
+ //#endregion
240
+ //#region src/native/cli-output.utils.d.ts
241
+ /**
242
+ * CLI 输出工具
243
+ *
244
+ * @remarks
245
+ * 按 ADR 0038 禁止 console 系调用。原生域的用户输出统一经
246
+ * `process.stdout.write` 与 `process.stderr.write`,保留多参数拼接语义
247
+ */
248
+ /**
249
+ * 输出 ANSI 颜色常量
250
+ */
251
+ declare const COLORS: {
252
+ readonly RED: '';
253
+ readonly GREEN: '';
254
+ readonly YELLOW: '';
255
+ readonly BLUE: '';
256
+ readonly RESET: '';
257
+ };
258
+ /**
259
+ * 输出到标准输出,自动追加换行
260
+ *
261
+ * @param args - 任意参数列表
262
+ */
263
+ declare function stdout(...args: readonly unknown[]): void;
264
+ /**
265
+ * 输出到标准错误流,自动追加换行
266
+ *
267
+ * @param args - 任意参数列表
268
+ */
269
+ declare function stderr(...args: readonly unknown[]): void;
270
+ //#endregion
271
+ //#region src/native/portfolio-config.utils.d.ts
272
+ /**
273
+ * 产品群聚合配置定位与加载,push-all 消费
274
+ *
275
+ * @remarks
276
+ * 解析链三段,ADR 0081 增量接入 globals 仓 TS 来源,原 yaml 机制原样保留。
277
+ * 其一为 `--config` 显式指定的 yaml 文件。其二为 env `LZI_GLOBALS_ROOT` 定位
278
+ * globals 仓的 `lzi-architecture.config.ts`,聚合根按 globals 仓根的父目录推导,
279
+ * 配置内容零路径。其三为 cwd 逐级上溯查找 `lzi-architecture.yaml`,
280
+ * root 相对 yaml 所在目录,默认上一级。全链未命中返回 null,由调用方保留报错口径
281
+ */
282
+ /**
283
+ * 产品群配置 yaml 文件名,不入 git,机器本地
284
+ */
285
+ declare const PORTFOLIO_CONFIG_FILE_NAME = "lzi-architecture.yaml";
286
+ /**
287
+ * 聚合配置命中来源,即解析链层级
288
+ */
289
+ type PortfolioSource = 'explicit' | 'globals' | 'yaml-upward';
290
+ /**
291
+ * 解析完成的聚合配置,跨仓命令的统一消费面
292
+ */
293
+ type ResolvedPortfolio = {
294
+ /**
295
+ * 聚合根绝对路径
296
+ */
297
+ readonly rootDir: string;
298
+ /**
299
+ * 全局排除的项目目录名列表,未声明为空
300
+ */
301
+ readonly exclude: string[];
302
+ /**
303
+ * 命中的解析链层级
304
+ */
305
+ readonly source: PortfolioSource;
306
+ };
307
+ /**
308
+ * 解析产品群聚合配置,解析链为显式路径优先、env globals 次之、上溯 yaml 兜底
309
+ *
310
+ * @remarks
311
+ * 显式路径不存在时报错退出。env 指向的目录不存在或配置文件缺失时该层级跳过,
312
+ * 回落下一层。globals 动态加载失败时报错退出。上溯查找仅在既有的 yaml 命名上
313
+ * 逐级探测,不做目录猜测
314
+ * @param explicitPath - `--config` 显式指定的 yaml 路径
315
+ * @returns 统一消费面,全链未命中为 null
316
+ */
317
+ declare const resolvePortfolioConfig: (explicitPath?: string) => Promise<ResolvedPortfolio | null>;
318
+ //#endregion
319
+ //#region src/native/push-all.run.usecase.d.ts
320
+ /**
321
+ * push-all 原生域用例
322
+ *
323
+ * @remarks
324
+ * 跨产品群多个独立 git 仓并发推送未推送的提交,自 dev-tools 迁入,语义不变。
325
+ * 配置来源见 portfolio-config.utils 的三段解析链。
326
+ * 核心处理点:本地分支名与远程不一致时用 `git push origin HEAD` 沿 upstream 推送,
327
+ * 不约束远程分支名。并发推送默认 10,`--concurrency` 可调。无 remote 或无 upstream
328
+ * 或已是最新的项目跳过。推送失败不重试不强推。`--dry-run` 只列待推项目与
329
+ * ahead 提交数,不实际推
330
+ */
331
+ /**
332
+ * push-all 命令选项
333
+ */
334
+ type PushAllOptions = {
335
+ /**
336
+ * 配置文件路径,显式指定覆盖自动查找
337
+ */
338
+ config?: string;
339
+ /**
340
+ * 并发数
341
+ *
342
+ * @default 10
343
+ */
344
+ concurrency?: number;
345
+ /**
346
+ * 是否为预览模式,只列待推项目不实际推
347
+ */
348
+ dryRun: boolean;
349
+ };
350
+ /**
351
+ * 执行 push-all 命令
352
+ *
353
+ * @param options - 命令选项
354
+ */
355
+ declare const runPushAllCommand: (options: PushAllOptions) => Promise<void>;
356
+ //#endregion
357
+ //#region src/native/workspace-scan.utils.d.ts
358
+ /**
359
+ * 从根 package.json 的 workspaces 字段读取包目录 glob 模式
360
+ *
361
+ * @remarks
362
+ * 支持数组形式与对象形式两种写法。读取失败或未配置时回退默认模式
363
+ * @param rootDir - monorepo 根目录路径
364
+ * @returns workspace glob 模式字符串数组
365
+ */
366
+ declare const readWorkspacePatterns: (rootDir: string) => Promise<string[]>;
367
+ /**
368
+ * 扫描 monorepo 中所有包,构建包名到路径的映射
369
+ *
370
+ * @param rootDir - monorepo 根目录路径
371
+ * @returns 包名到绝对路径的映射表
372
+ */
373
+ declare const scanAllPackages: (rootDir: string) => Promise<Map<string, string>>;
374
+ /**
375
+ * 读取 package.json 为 record 形态
376
+ *
377
+ * @param dirPath - 包目录路径
378
+ * @returns 解析后的 package.json 对象
379
+ * @throws {@link Error} package.json 格式不合法
380
+ */
381
+ declare const readPackageJson: (dirPath: string) => Promise<Record<string, unknown>>;
382
+ //#endregion
383
+ //#region src/native/forbid.run.usecase.d.ts
384
+ /**
385
+ * forbid 原生域用例
386
+ *
387
+ * @remarks
388
+ * 守卫 monorepo 根目录,禁止在根直接运行 dev、build、lint、test、typecheck 等全局任务,
389
+ * 并给出可操作指引:扫描 workspace 内含目标脚本的子包,打印可复制的确切命令。
390
+ * 自 dev-tools 迁入,语义不变,ADR 0058 哨兵机制的承载者。
391
+ * 行为契约:始终退出码 1,与原哨兵等价。错误信息走 stderr,
392
+ * 可复制命令走 stdout。候选子包按相对路径排序,输出稳定可 diff
393
+ */
394
+ /**
395
+ * forbid 命令选项
396
+ */
397
+ type ForbidOptions = {
398
+ /**
399
+ * 被禁的任务名,如 dev、build、lint、test、typecheck
400
+ */
401
+ task: string;
402
+ };
403
+ /**
404
+ * 子包候选,相对路径与该包内对应脚本的执行命令
405
+ */
406
+ type Candidate = {
407
+ /**
408
+ * 子包相对 monorepo 根的路径,如 apps/cli
409
+ */
410
+ relPath: string;
411
+ /**
412
+ * 该子包内运行该任务的可复制命令
413
+ */
414
+ command: string;
415
+ };
416
+ /**
417
+ * 从 package.json 对象提取 scripts 区块为字符串映射
418
+ *
419
+ * @remarks
420
+ * 纯函数无 IO,便于单元测试覆盖各类 scripts 字段形态
421
+ * @param pkg - package.json 对象
422
+ * @returns scripts 映射,无 scripts 或类型不合法时为空映射
423
+ */
424
+ declare const extractScripts: (pkg: Record<string, unknown>) => Record<string, string>;
425
+ /**
426
+ * 从 package.json 对象判断是否含指定 task 脚本
427
+ *
428
+ * @param pkg - package.json 对象
429
+ * @param task - 目标任务名
430
+ * @returns 含该脚本且脚本值非空时 true
431
+ */
432
+ declare const hasScript: (pkg: Record<string, unknown>, task: string) => boolean;
433
+ /**
434
+ * 格式化 forbid 消息文本
435
+ *
436
+ * @remarks
437
+ * 纯函数无进程耦合,便于单元测试锁定输出结构,
438
+ * 由 `runForbidCommand` 着色后写流
439
+ * @param task - 被禁的任务名
440
+ * @param candidates - 候选子包列表,已排序
441
+ * @param turboHint - 是否附加 turbo 全量入口提示
442
+ * @returns 完整消息文本,未着色
443
+ */
444
+ declare const formatForbidMessage: (task: string, candidates: Candidate[], turboHint: boolean) => string;
445
+ /**
446
+ * 执行 forbid 守卫
447
+ *
448
+ * @remarks
449
+ * 以当前工作目录作为 monorepo 根,扫描全部 workspace 包,
450
+ * 逐包读取 package.json 过滤出含目标 task 脚本的子包,
451
+ * 构造可复制命令按相对路径排序,输出禁令与指引后退出码 1
452
+ * @param options - 含目标任务名的选项
453
+ */
454
+ declare const runForbidCommand: (options: ForbidOptions) => Promise<void>;
455
+ //#endregion
456
+ export { CHECK_ENTRIES, COLORS, type CheckEntry, type CheckItemResult, type CheckRunOptions, type CheckRunResult, type CheckRunStatus, DOMAIN_COUNT, DOMAIN_ENTRIES, type DelegateResult, type DomainEntry, PORTFOLIO_CONFIG_FILE_NAME, type PortfolioSource, type PushAllOptions, type ResolvedPortfolio, checkEntrySchema, defineCheckEntry, defineDomainEntry, delegateToDomain, domainEntrySchema, extractScripts, formatForbidMessage, hasScript, loadToolchainConfig, readPackageJson, readWorkspacePatterns, resolveBinCommand, resolvePortfolioConfig, runCheckCommand, runForbidCommand, runPushAllCommand, scanAllPackages, stderr, stdout };
package/dist/index.js ADDED
@@ -0,0 +1,5 @@
1
+ import"./rolldown-runtime-BqT_7tdF.js";import*as e from"zod";import{accessSync as t,constants as n,existsSync as r,readdirSync as i,statSync as a}from"node:fs";import{delimiter as o,dirname as s,isAbsolute as c,join as l,relative as u,resolve as d}from"node:path";import{createNodeLogger as f}from"@longzai-intelligence-logger/node";import{loadToolchainConfig as p,loadToolchainConfig as m}from"@longzai-intelligence-toolchain/config";import{loadConfigFile as h}from"@longzai-intelligence-shared-config/core";const g=e.object({domain:e.string().regex(/^[a-z][a-z0-9-]*$/,`域名为小写字母开头的 kebab-case`),bin:e.string().min(1),packageName:e.string().regex(/^@[a-z0-9-]+\/[a-z0-9-]+$/,`包名为带 scope 的 npm 包名`),description:e.string().min(1)}),_=e=>{let t=g.safeParse(e);if(!t.success){let e=t.error.issues.map(e=>`${e.path.join(`.`)}: ${e.message}`).join(`, `);throw Error(`域表条目校验失败: ${e}`)}return e},v=Object.freeze([_({domain:`version`,bin:`lzi-version`,packageName:`@longzai-intelligence-version/cli`,description:`版本号同步与检查`}),_({domain:`dependencies`,bin:`lzi-dependencies`,packageName:`@longzai-intelligence-dependencies/cli`,description:`依赖版本升级与跨仓批量升级`}),_({domain:`changelog`,bin:`lzi-changelog`,packageName:`@longzai-intelligence-changelog/cli`,description:`变更日志条目追加与撤回`}),_({domain:`release`,bin:`lzi-release`,packageName:`@longzai-intelligence-release/cli`,description:`版本发布操作`}),_({domain:`config`,bin:`lzi-config`,packageName:`@longzai-intelligence-config/cli`,description:`scripts 与配置文件基线门禁`}),_({domain:`env`,bin:`lzi-env-cli`,packageName:`@longzai-intelligence-env/cli`,description:`环境变量声明门禁`}),_({domain:`tsconfig`,bin:`lzi-tsconfig`,packageName:`@longzai-intelligence-tsconfig/cli`,description:`tsconfig 形态门禁`}),_({domain:`scripts`,bin:`lzi-scripts`,packageName:`@longzai-intelligence-scripts/cli`,description:`标准脚本完备性审计`}),_({domain:`git`,bin:`lzi-git`,packageName:`@longzai-intelligence-git/cli`,description:`gitignore 治理与 git 透传`}),_({domain:`vscode`,bin:`lzi-vscode-cli`,packageName:`@longzai-intelligence-vscode/cli`,description:`工作区编辑器设置同步`}),_({domain:`agent`,bin:`lzi-agent-cli`,packageName:`@longzai-intelligence-agent-tools/cli`,description:`指令面真源合成`}),_({domain:`decision`,bin:`lzi-decision`,packageName:`@longzai-intelligence-decision/cli`,description:`ADR 编号与索引门禁`}),_({domain:`standards`,bin:`lzi-standards`,packageName:`@longzai-intelligence-standards/cli`,description:`标准注册表治理`}),_({domain:`oxlint`,bin:`lzi-oxlint`,packageName:`@longzai-intelligence-oxlint/cli`,description:`lint 依赖声明形态检查`}),_({domain:`bun`,bin:`lzi-bun-cli`,packageName:`@longzai-intelligence-bun/cli`,description:`Bun 工具链配置生成与锁文件审计`}),_({domain:`builder`,bin:`lzi-builder`,packageName:`@longzai-intelligence-builder/cli`,description:`统一构建`}),_({domain:`bootstrap`,bin:`lzi-bootstrap`,packageName:`@longzai-intelligence-bootstrap/cli`,description:`产品启动器`}),_({domain:`port`,bin:`lzi-port`,packageName:`@longzai-intelligence-port/cli`,description:`端口注册与查询`})]),y=v.length,b=e=>{try{return t(e,n.X_OK),!0}catch{return!1}},x=e=>{if(c(e))return b(e)?e:null;let t=process.cwd();for(;;){let n=l(t,`node_modules`,`.bin`,e);if(b(n))return n;let r=l(t,`..`);if(r===t)break;t=r}let n=(process.env.PATH??``).split(o);for(let t of n){if(t.length===0)continue;let n=l(t,e);if(b(n))return n}return null},S=f(`@longzai-intelligence-toolchain/core/delegate`),C=async(e,t,n)=>{if(n?.enabled===!1)return S.error(`域 ${e.domain} 已被就地配置禁用`),{exitCode:1};let r=n?.bin??e.bin,i=x(r);return i===null?(S.error(`未找到可执行命令:${r}`),S.error(`请安装引擎依赖:${e.packageName}`),{exitCode:127}):{exitCode:await Bun.spawn([i,...t],{stdin:`inherit`,stdout:`inherit`,stderr:`inherit`}).exited??1}},w=e.object({id:e.string().regex(/^[a-z][a-z0-9-]*$/,`检查项 id 为小写字母开头的 kebab-case`),domain:e.string().regex(/^[a-z][a-z0-9-]*$/,`域名为小写字母开头的 kebab-case`),args:e.array(e.string().min(1)).min(1),core:e.boolean(),probe:e.string().min(1).optional(),description:e.string().min(1)}),T=e=>{let t=w.safeParse(e);if(!t.success){let e=t.error.issues.map(e=>`${e.path.join(`.`)}: ${e.message}`).join(`, `);throw Error(`检查项条目校验失败: ${e}`)}return e},E=Object.freeze([T({id:`lockfile`,domain:`bun`,args:[`lockfile`,`check`],core:!0,description:`bun 单一锁文件不变量审计`}),T({id:`node-links`,domain:`bun`,args:[`node-links`,`check`],core:!0,probe:`node-links`,description:`node_modules 悬挂符号链接检测`}),T({id:`bunfig-drift`,domain:`bun`,args:[`config`,`generate`,`--check`,`--recursive`],core:!0,description:`bunfig.toml 与生成器预期漂移校验`}),T({id:`tsconfig`,domain:`tsconfig`,args:[`check`],core:!0,description:`tsconfig 形态门禁`}),T({id:`oxlint`,domain:`oxlint`,args:[`check`],core:!0,description:`lint 依赖声明形态检查`}),T({id:`env`,domain:`env`,args:[`check`],core:!0,description:`环境变量声明门禁`}),T({id:`gitignore`,domain:`git`,args:[`gitignore`,`check`],core:!0,description:`gitignore 归一化守门`}),T({id:`vscode`,domain:`vscode`,args:[`sync`,`--check`],core:!0,description:`编辑器设置同步校验`}),T({id:`version`,domain:`version`,args:[`check`],core:!0,description:`版本号一致性检查`}),T({id:`agent-sync`,domain:`agent`,args:[`sync`,`--check`],core:!1,description:`指令面真源同步校验`}),T({id:`decision-lint`,domain:`decision`,args:[`lint`],core:!1,description:`ADR 正文形态检查`}),T({id:`decision-numbering`,domain:`decision`,args:[`numbering`,`check`],core:!1,description:`ADR 编号连续性检查`}),T({id:`decision-index`,domain:`decision`,args:[`index`,`check`],core:!1,description:`ADR 索引一致性检查`}),T({id:`standards-lint`,domain:`standards`,args:[`lint`],core:!1,description:`标准注册表正文形态检查`}),T({id:`standards-index`,domain:`standards`,args:[`index`,`check`],core:!1,description:`标准注册表索引一致性检查`})]),D={RED:`\x1B[0;31m`,GREEN:`\x1B[0;32m`,YELLOW:`\x1B[1;33m`,BLUE:`\x1B[0;34m`,RESET:`\x1B[0m`};function O(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 k(...e){process.stdout.write(`${O(e)}\n`)}function A(...e){process.stderr.write(`${O(e)}\n`)}const j=new Map(v.map(e=>[e.domain,e])),M=(e,t)=>t.includes(e.id)||t.includes(e.domain),ee=async(e,t)=>{let n=Bun.spawn([e,`--help`],{stdout:`pipe`,stderr:`pipe`}),[r,i]=await Promise.all([n.exited,new Response(n.stdout).text()]);return r===0&&i.includes(t)},te=async(e,t)=>{let n=j.get(e.domain);if(n===void 0)throw Error(`检查项 ${e.id} 引用的域 ${e.domain} 不在域表内`);let r=`${n.bin} ${e.args.join(` `)}`,i=t?.[e.domain];if(i?.enabled===!1)return k(`${D.YELLOW}- ${e.id} ${r} 已禁用${D.RESET}`),{id:e.id,domain:e.domain,command:r,status:`disabled`,exitCode:null};let a=i?.bin??n.bin,o=x(a);if(o===null)return e.core?(A(`${D.RED}✗ ${e.id} 缺引擎,请安装 ${n.packageName}${D.RESET}`),{id:e.id,domain:e.domain,command:r,status:`missing`,exitCode:null}):(k(`${D.YELLOW}- ${e.id} ${r} 不适用,未安装 ${n.packageName}${D.RESET}`),{id:e.id,domain:e.domain,command:r,status:`not-applicable`,exitCode:null});if(e.probe!==void 0&&!await ee(o,e.probe))return A(`${D.YELLOW}⚠ ${e.id} 已安装引擎不含该子命令,跳过检查,升级 ${n.packageName} 后自动生效${D.RESET}`),{id:e.id,domain:e.domain,command:r,status:`capability-missing`,exitCode:null};k(`${D.BLUE}▶ ${e.id} ${e.description}${D.RESET}`);let s=await Bun.spawn([o,...e.args],{stdin:`inherit`,stdout:`inherit`,stderr:`inherit`}).exited??1;return{id:e.id,domain:e.domain,command:r,status:s===0?`pass`:`fail`,exitCode:s}},ne=async(e={})=>{let t=(await m())?.config,n=t?.checks,r;r=e.only!==void 0&&e.only.length>0?E.filter(t=>M(t,e.only??[])):n?.include!==void 0&&n.include.length>0?E.filter(e=>M(e,n.include??[])):E;let i=[...e.skip??[],...n?.exclude??[]];if(i.length>0&&(r=r.filter(e=>!M(e,i))),r.length===0)return A(`未命中任何检查项,请核对 only、skip 与就地配置的 checks 选择`),{results:[],exitCode:1};k(`开始聚合检查,共 ${r.length} 项,串行执行`);let a=[];for(let e of r)a.push(await te(e,t?.domains));let o=e=>a.filter(t=>t.status===e).length;k(``),k(`检查汇总: 通过 ${o(`pass`)},失败 ${o(`fail`)},缺引擎 ${o(`missing`)},能力缺失 ${o(`capability-missing`)},不适用 ${o(`not-applicable`)},已禁用 ${o(`disabled`)}`);for(let e of a){if(e.status===`pass`)continue;let t=e.status===`fail`&&e.exitCode!==null?`${e.id} ${e.command} 退出码 ${e.exitCode}`:`${e.id} ${e.command} ${e.status}`;k(e.status===`fail`||e.status===`missing`?`${D.RED} ✗ ${t}${D.RESET}`:`${D.YELLOW} - ${t}${D.RESET}`)}let s=o(`fail`)+o(`missing`);return s>0&&A(`修复指引: 对失败项以 lzi-toolchain <域名> <参数> 单独重跑查看引擎明细`),{results:a,exitCode:Math.min(s,255)}},N=`lzi-architecture.yaml`,P=e=>Array.isArray(e)&&e.every(e=>typeof e==`string`),re=e=>{if(typeof e!=`object`||!e||Array.isArray(e))return{};let t={};return`root`in e&&typeof e.root==`string`&&(t.root=e.root),`exclude`in e&&P(e.exclude)&&(t.exclude=e.exclude),t},F=async e=>{try{let t=await Bun.file(e).text();return re(Bun.YAML.parse(t))}catch(t){A(`错误:加载配置文件失败:${e}`,t instanceof Error?t.message:String(t)),process.exit(1)}},ie=e=>typeof e!=`object`||!e||Array.isArray(e)?{}:`exclude`in e&&P(e.exclude)?{exclude:e.exclude}:{},I=async e=>{if(e){let t=d(process.cwd(),e);r(t)||(A(`错误:配置文件不存在:${t}`),process.exit(1));let n=await F(t);return{rootDir:d(s(t),n.root??`../`),exclude:n.exclude??[],source:`explicit`}}let t=process.env.LZI_GLOBALS_ROOT;if(t!==void 0&&t!==``){let e=l(d(t),`lzi-architecture.config.ts`);if(r(e))try{let{config:n}=await h(e),r=ie(n);return{rootDir:s(d(t)),exclude:r.exclude??[],source:`globals`}}catch(t){A(`错误:加载 globals 聚合配置失败:${e}`,t instanceof Error?t.message:String(t)),process.exit(1)}}let n=process.cwd();for(;n!==`/`;){let e=l(n,N);if(r(e)){let t=await F(e);return{rootDir:d(s(e),t.root??`../`),exclude:t.exclude??[],source:`yaml-upward`}}n=s(n)}return null},ae=(e,t)=>{let n;try{n=i(e)}catch{A(`错误:无法读取聚合根目录:${e}`),process.exit(1)}let o=new Set(t);return n.filter(e=>!(e.startsWith(`.`)||e===`node_modules`||o.has(e))).map(t=>{let n=l(e,t);try{if(a(n).isDirectory()&&r(l(n,`.git`)))return{name:t,dir:n}}catch{}return null}).filter(e=>e!==null)},oe=e=>{let t=Bun.spawnSync([`git`,`remote`],{cwd:e,stdout:`pipe`,stderr:`pipe`}),n=t.stdout.toString().trim();return t.exitCode===0&&n.length>0},L=e=>Bun.spawnSync([`git`,`rev-parse`,`--abbrev-ref`,`--symbolic-full-name`,`@{upstream}`],{cwd:e,stdout:`pipe`,stderr:`pipe`}).exitCode===0,R=e=>{let t=Bun.spawnSync([`git`,`rev-list`,`--count`,`@{upstream}..HEAD`],{cwd:e,stdout:`pipe`,stderr:`pipe`});if(t.exitCode!==0)return 0;let n=Number.parseInt(t.stdout.toString().trim(),10);return Number.isNaN(n)?0:n},z=e=>{let t=Bun.spawnSync([`git`,`rev-parse`,`--abbrev-ref`,`--symbolic-full-name`,`@{upstream}`],{cwd:e,stdout:`pipe`,stderr:`pipe`});if(t.exitCode!==0)return null;let n=t.stdout.toString().trim(),r=n.indexOf(`/`);return r>=0?n.slice(r+1):n},B=e=>{let t=z(e);return t?Bun.spawnSync([`git`,`push`,`origin`,`HEAD:${t}`],{cwd:e,stdout:`pipe`,stderr:`pipe`}).exitCode===0:!1},V=async e=>{let{dryRun:t}=e,n=e.concurrency??10,i=await I(e.config);i||(A(`错误:未找到产品群配置文件 ${N}`),A(`提示:请在 architecture 项目创建该配置文件,参考 lzi-architecture.sample.yaml`),A(`提示:或使用 --config <path> 显式指定`),A(`提示:或在 .env 设置 LZI_GLOBALS_ROOT 定位 globals 仓 TS 配置,见 ADR 0081`),process.exit(1));let a=i.rootDir;r(a)||(A(`错误:聚合根目录不存在:${a}`),process.exit(1));let o=i.exclude;k(`${D.BLUE}═══ push-all ═══${D.RESET}`),k(`聚合配置来源:${i.source}`),k(`聚合根:${a}`),k(`并发数:${n}`),o.length>0&&k(`排除项目:${o.join(`, `)}`),t&&k(`${D.YELLOW}[dry-run] 预览模式,不实际推送${D.RESET}`),k(``);let s=ae(a,o);k(`发现 ${s.length} 个子项目,正在扫描推送状态`),k(``);let c=[],l=[],u=[],d=[];for(let e of s){let{name:t,dir:n}=e;if(!oe(n)){l.push(t);continue}if(!L(n)){u.push(t);continue}let r=R(n);r===0?d.push(t):c.push({name:t,dir:n,ahead:r})}if(t){k(`${D.GREEN}待推送:${c.length}${D.RESET}`);for(let e of c)k(` ${e.name},ahead ${e.ahead}`);l.length>0&&(k(``),k(`跳过,无 git remote:${l.length}`)),u.length>0&&k(`跳过,无 upstream tracking:${u.length}`),d.length>0&&k(`跳过,已是最新:${d.length}`),k(``),k(`${D.BLUE}汇总:${c.length} 待推送,${d.length} 已最新,${l.length+u.length} 跳过${D.RESET}`);return}if(c.length===0){k(`${D.GREEN}所有项目均已是最新,无需推送${D.RESET}`),k(`跳过,无 git remote:${l.length}`),k(`跳过,无 upstream tracking:${u.length}`),k(`跳过,已是最新:${d.length}`);return}k(`待推送 ${c.length} 个项目,并发数 ${n},开始推送`),k(``);let f=[],p=0,m=c.length;await(async(e,t)=>{let n=0,r=async()=>{for(;n<e.length;){let t=e[n];if(!t)break;n++;let r=B(t.dir);f.push({name:t.name,status:r?`pushed`:`failed`,ahead:t.ahead,reason:r?void 0:`git push 失败`}),p++;let i=r?`${D.GREEN}✓${D.RESET}`:`${D.RED}✗${D.RESET}`;k(` [${p}/${m}] ${i} ${t.name}`)}},i=Array.from({length:Math.min(t,e.length)},()=>r());await Promise.all(i)})(c,n);let h=f.filter(e=>e.status===`pushed`),g=f.filter(e=>e.status===`failed`);k(`${D.BLUE}═══ 处理结果 ═══${D.RESET}`),k(`${D.GREEN}已推送:${h.length}${D.RESET}`);for(let e of h)k(` ${e.name},ahead ${e.ahead}`);if(g.length>0){k(``),k(`${D.RED}失败:${g.length}${D.RESET}`);for(let e of g)k(` ${e.name}:${e.reason}`)}k(``),k(`${D.BLUE}汇总:${h.length} 已推送,${g.length} 失败,${d.length} 已最新,${l.length+u.length} 跳过${D.RESET}`),g.length>0&&(process.exitCode=1)},H=[`packages/*`,`apps/*`],U=e.record(e.string(),e.unknown()),W=e.record(e.string(),e.string()),G=e.array(e.string()),K=e.object({name:e.string()}),q=async e=>Bun.file(e).json(),J=async e=>{try{let t=U.safeParse(await q(`${e}/package.json`));if(t.success){let e=t.data.workspaces,n=G.safeParse(e);if(n.success&&n.data.length>0)return n.data;let r=U.safeParse(e);if(r.success){let e=G.safeParse(r.data.packages);if(e.success&&e.data.length>0)return e.data}}}catch{}return H},Y=async e=>{let t=/* @__PURE__ */ new Map,n=await J(e);for(let r of n)try{let n=new Bun.Glob(`${r}/package.json`);for await(let r of n.scan({cwd:e,absolute:!0}))try{let e=await q(r),n=K.safeParse(e);if(n.success){let e=r.replace(/[/\\]package\.json$/,``);t.set(n.data.name,e)}}catch{}}catch{}return t},X=async e=>{let t=U.safeParse(await Bun.file(`${e}/package.json`).json());if(!t.success)throw Error(`package.json 格式不合法:${e}`);return t.data},Z=e=>{let t=W.safeParse(e.scripts);return t.success?t.data:{}},Q=(e,t)=>{let n=Z(e)[t];return typeof n==`string`&&n.trim()!==``},$=(e,t,n)=>{if(t.length===0)return[`禁止在 monorepo 根目录运行 ${e}。`,``,`当前 workspace 内无子包声明 "${e}" 脚本。`,`请进入具体子包目录后执行,或确认任务名是否正确。`].join(`
2
+ `);let r=t.map(e=>` ${e.relPath.padEnd(18)} → ${e.command}`),i=n?`\n或显式全量:turbo run ${e}`:``;return[`禁止在 monorepo 根目录运行 ${e}。`,``,`${e} 需在具体子包内执行。当前 workspace 内含该脚本的子包:`,``,...r,i].filter(e=>e!==``).join(`
3
+ `)},se=/* @__PURE__ */ new Set([`dev`,`build`,`lint`,`test`,`typecheck`]),ce=async e=>{let{task:t}=e,n=process.cwd(),r=await Y(n),i=[];for(let[,e]of r)try{let r=await X(e);if(!Q(r,t))continue;let a=u(n,e);i.push({relPath:a,command:`bun run --cwd ${a} ${t}`})}catch{}i.sort((e,t)=>e.relPath.localeCompare(t.relPath));let a=se.has(t),o=$(t,i,a),s=D.RED,c=D.RESET;k(o.split(`
4
+ `).map((e,t)=>t===0?`${s}${e}${c}`:e).join(`
5
+ `)),A(``),A(`如需在根目录触发全量任务,请显式使用 turbo,不要直接运行根脚本。`),process.exit(1)};export{E as CHECK_ENTRIES,D as COLORS,y as DOMAIN_COUNT,v as DOMAIN_ENTRIES,N as PORTFOLIO_CONFIG_FILE_NAME,w as checkEntrySchema,T as defineCheckEntry,_ as defineDomainEntry,C as delegateToDomain,g as domainEntrySchema,Z as extractScripts,$ as formatForbidMessage,Q as hasScript,p as loadToolchainConfig,X as readPackageJson,J as readWorkspacePatterns,x as resolveBinCommand,I as resolvePortfolioConfig,ne as runCheckCommand,ce as runForbidCommand,V as runPushAllCommand,Y as scanAllPackages,A as stderr,k as stdout};
@@ -0,0 +1 @@
1
+ import"node:module";export{};
package/package.json CHANGED
@@ -1,6 +1,47 @@
1
1
  {
2
2
  "name": "@longzai-intelligence-toolchain/core",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
6
- }
3
+ "version": "0.0.2",
4
+ "description": "Longzai Intelligence 工具链伞形核心:域表、委托内核与原生跨仓域用例",
5
+ "keywords": [
6
+ "core",
7
+ "domain-model",
8
+ "longzai-intelligence"
9
+ ],
10
+ "license": "UNLICENSED",
11
+ "files": [
12
+ "dist"
13
+ ],
14
+ "type": "module",
15
+ "main": "./dist/index.js",
16
+ "types": "./dist/index.d.ts",
17
+ "exports": {
18
+ ".": {
19
+ "types": "./dist/index.d.ts",
20
+ "import": "./dist/index.js"
21
+ }
22
+ },
23
+ "scripts": {
24
+ "build": "lzi-builder",
25
+ "build:prod": "NODE_ENV=production lzi-builder",
26
+ "prepublishOnly": "bun run build:prod",
27
+ "typecheck": "bun run typecheck:app && bun run typecheck:node && bun run typecheck:test",
28
+ "typecheck:app": "lzi-tsgo typecheck tsconfig/app.json",
29
+ "typecheck:node": "lzi-tsgo typecheck tsconfig/node.json",
30
+ "typecheck:test": "lzi-tsgo typecheck tsconfig/test.json",
31
+ "lint": "oxlint && oxfmt --check",
32
+ "lint:fix": "oxlint --fix && oxfmt",
33
+ "test": "bun test",
34
+ "test:watch": "bun test --watch",
35
+ "test:coverage": "bun test --coverage",
36
+ "clean": "lzi-dev-cli clean"
37
+ },
38
+ "dependencies": {
39
+ "@longzai-intelligence-logger/node": "^0.1.4",
40
+ "@longzai-intelligence-shared-config/core": "^0.0.9",
41
+ "@longzai-intelligence-toolchain/config": "0.0.2",
42
+ "zod": "^4.6.5"
43
+ },
44
+ "devDependencies": {
45
+ "@longzai-intelligence-architecture/config": "0.0.2"
46
+ }
47
+ }