@longzai-intelligence-toolchain/core 0.0.0-stage → 0.0.1
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 +8 -2
- package/dist/index.d.ts +318 -0
- package/dist/index.js +5 -0
- package/dist/rolldown-runtime-BqT_7tdF.js +1 -0
- package/package.json +45 -4
package/README.md
CHANGED
|
@@ -1,3 +1,9 @@
|
|
|
1
|
-
#
|
|
1
|
+
# @longzai-intelligence-toolchain/core
|
|
2
2
|
|
|
3
|
-
|
|
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 模块文件尚未在模板中提供,需在使用模板后由开发者按导出契约补齐具体实现。
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,318 @@
|
|
|
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/native/cli-output.utils.d.ts
|
|
103
|
+
/**
|
|
104
|
+
* CLI 输出工具
|
|
105
|
+
*
|
|
106
|
+
* @remarks
|
|
107
|
+
* 按 ADR 0038 禁止 console 系调用。原生域的用户输出统一经
|
|
108
|
+
* `process.stdout.write` 与 `process.stderr.write`,保留多参数拼接语义
|
|
109
|
+
*/
|
|
110
|
+
/**
|
|
111
|
+
* 输出 ANSI 颜色常量
|
|
112
|
+
*/
|
|
113
|
+
declare const COLORS: {
|
|
114
|
+
readonly RED: '[0;31m';
|
|
115
|
+
readonly GREEN: '[0;32m';
|
|
116
|
+
readonly YELLOW: '[1;33m';
|
|
117
|
+
readonly BLUE: '[0;34m';
|
|
118
|
+
readonly RESET: '[0m';
|
|
119
|
+
};
|
|
120
|
+
/**
|
|
121
|
+
* 输出到标准输出,自动追加换行
|
|
122
|
+
*
|
|
123
|
+
* @param args - 任意参数列表
|
|
124
|
+
*/
|
|
125
|
+
declare function stdout(...args: readonly unknown[]): void;
|
|
126
|
+
/**
|
|
127
|
+
* 输出到标准错误流,自动追加换行
|
|
128
|
+
*
|
|
129
|
+
* @param args - 任意参数列表
|
|
130
|
+
*/
|
|
131
|
+
declare function stderr(...args: readonly unknown[]): void;
|
|
132
|
+
//#endregion
|
|
133
|
+
//#region src/native/portfolio-config.utils.d.ts
|
|
134
|
+
/**
|
|
135
|
+
* 产品群聚合配置定位与加载,push-all 消费
|
|
136
|
+
*
|
|
137
|
+
* @remarks
|
|
138
|
+
* 解析链三段,ADR 0081 增量接入 globals 仓 TS 来源,原 yaml 机制原样保留。
|
|
139
|
+
* 其一为 `--config` 显式指定的 yaml 文件。其二为 env `LZI_GLOBALS_ROOT` 定位
|
|
140
|
+
* globals 仓的 `lzi-architecture.config.ts`,聚合根按 globals 仓根的父目录推导,
|
|
141
|
+
* 配置内容零路径。其三为 cwd 逐级上溯查找 `lzi-architecture.yaml`,
|
|
142
|
+
* root 相对 yaml 所在目录,默认上一级。全链未命中返回 null,由调用方保留报错口径
|
|
143
|
+
*/
|
|
144
|
+
/**
|
|
145
|
+
* 产品群配置 yaml 文件名,不入 git,机器本地
|
|
146
|
+
*/
|
|
147
|
+
declare const PORTFOLIO_CONFIG_FILE_NAME = "lzi-architecture.yaml";
|
|
148
|
+
/**
|
|
149
|
+
* 聚合配置命中来源,即解析链层级
|
|
150
|
+
*/
|
|
151
|
+
type PortfolioSource = 'explicit' | 'globals' | 'yaml-upward';
|
|
152
|
+
/**
|
|
153
|
+
* 解析完成的聚合配置,跨仓命令的统一消费面
|
|
154
|
+
*/
|
|
155
|
+
type ResolvedPortfolio = {
|
|
156
|
+
/**
|
|
157
|
+
* 聚合根绝对路径
|
|
158
|
+
*/
|
|
159
|
+
readonly rootDir: string;
|
|
160
|
+
/**
|
|
161
|
+
* 全局排除的项目目录名列表,未声明为空
|
|
162
|
+
*/
|
|
163
|
+
readonly exclude: string[];
|
|
164
|
+
/**
|
|
165
|
+
* 命中的解析链层级
|
|
166
|
+
*/
|
|
167
|
+
readonly source: PortfolioSource;
|
|
168
|
+
};
|
|
169
|
+
/**
|
|
170
|
+
* 解析产品群聚合配置,解析链为显式路径优先、env globals 次之、上溯 yaml 兜底
|
|
171
|
+
*
|
|
172
|
+
* @remarks
|
|
173
|
+
* 显式路径不存在时报错退出。env 指向的目录不存在或配置文件缺失时该层级跳过,
|
|
174
|
+
* 回落下一层。globals 动态加载失败时报错退出。上溯查找仅在既有的 yaml 命名上
|
|
175
|
+
* 逐级探测,不做目录猜测
|
|
176
|
+
* @param explicitPath - `--config` 显式指定的 yaml 路径
|
|
177
|
+
* @returns 统一消费面,全链未命中为 null
|
|
178
|
+
*/
|
|
179
|
+
declare const resolvePortfolioConfig: (explicitPath?: string) => Promise<ResolvedPortfolio | null>;
|
|
180
|
+
//#endregion
|
|
181
|
+
//#region src/native/push-all.run.usecase.d.ts
|
|
182
|
+
/**
|
|
183
|
+
* push-all 原生域用例
|
|
184
|
+
*
|
|
185
|
+
* @remarks
|
|
186
|
+
* 跨产品群多个独立 git 仓并发推送未推送的提交,自 dev-tools 迁入,语义不变。
|
|
187
|
+
* 配置来源见 portfolio-config.utils 的三段解析链。
|
|
188
|
+
* 核心处理点:本地分支名与远程不一致时用 `git push origin HEAD` 沿 upstream 推送,
|
|
189
|
+
* 不约束远程分支名。并发推送默认 10,`--concurrency` 可调。无 remote 或无 upstream
|
|
190
|
+
* 或已是最新的项目跳过。推送失败不重试不强推。`--dry-run` 只列待推项目与
|
|
191
|
+
* ahead 提交数,不实际推
|
|
192
|
+
*/
|
|
193
|
+
/**
|
|
194
|
+
* push-all 命令选项
|
|
195
|
+
*/
|
|
196
|
+
type PushAllOptions = {
|
|
197
|
+
/**
|
|
198
|
+
* 配置文件路径,显式指定覆盖自动查找
|
|
199
|
+
*/
|
|
200
|
+
config?: string;
|
|
201
|
+
/**
|
|
202
|
+
* 并发数
|
|
203
|
+
*
|
|
204
|
+
* @default 10
|
|
205
|
+
*/
|
|
206
|
+
concurrency?: number;
|
|
207
|
+
/**
|
|
208
|
+
* 是否为预览模式,只列待推项目不实际推
|
|
209
|
+
*/
|
|
210
|
+
dryRun: boolean;
|
|
211
|
+
};
|
|
212
|
+
/**
|
|
213
|
+
* 执行 push-all 命令
|
|
214
|
+
*
|
|
215
|
+
* @param options - 命令选项
|
|
216
|
+
*/
|
|
217
|
+
declare const runPushAllCommand: (options: PushAllOptions) => Promise<void>;
|
|
218
|
+
//#endregion
|
|
219
|
+
//#region src/native/workspace-scan.utils.d.ts
|
|
220
|
+
/**
|
|
221
|
+
* 从根 package.json 的 workspaces 字段读取包目录 glob 模式
|
|
222
|
+
*
|
|
223
|
+
* @remarks
|
|
224
|
+
* 支持数组形式与对象形式两种写法。读取失败或未配置时回退默认模式
|
|
225
|
+
* @param rootDir - monorepo 根目录路径
|
|
226
|
+
* @returns workspace glob 模式字符串数组
|
|
227
|
+
*/
|
|
228
|
+
declare const readWorkspacePatterns: (rootDir: string) => Promise<string[]>;
|
|
229
|
+
/**
|
|
230
|
+
* 扫描 monorepo 中所有包,构建包名到路径的映射
|
|
231
|
+
*
|
|
232
|
+
* @param rootDir - monorepo 根目录路径
|
|
233
|
+
* @returns 包名到绝对路径的映射表
|
|
234
|
+
*/
|
|
235
|
+
declare const scanAllPackages: (rootDir: string) => Promise<Map<string, string>>;
|
|
236
|
+
/**
|
|
237
|
+
* 读取 package.json 为 record 形态
|
|
238
|
+
*
|
|
239
|
+
* @param dirPath - 包目录路径
|
|
240
|
+
* @returns 解析后的 package.json 对象
|
|
241
|
+
* @throws {@link Error} package.json 格式不合法
|
|
242
|
+
*/
|
|
243
|
+
declare const readPackageJson: (dirPath: string) => Promise<Record<string, unknown>>;
|
|
244
|
+
//#endregion
|
|
245
|
+
//#region src/native/forbid.run.usecase.d.ts
|
|
246
|
+
/**
|
|
247
|
+
* forbid 原生域用例
|
|
248
|
+
*
|
|
249
|
+
* @remarks
|
|
250
|
+
* 守卫 monorepo 根目录,禁止在根直接运行 dev、build、lint、test、typecheck 等全局任务,
|
|
251
|
+
* 并给出可操作指引:扫描 workspace 内含目标脚本的子包,打印可复制的确切命令。
|
|
252
|
+
* 自 dev-tools 迁入,语义不变,ADR 0058 哨兵机制的承载者。
|
|
253
|
+
* 行为契约:始终退出码 1,与原哨兵等价。错误信息走 stderr,
|
|
254
|
+
* 可复制命令走 stdout。候选子包按相对路径排序,输出稳定可 diff
|
|
255
|
+
*/
|
|
256
|
+
/**
|
|
257
|
+
* forbid 命令选项
|
|
258
|
+
*/
|
|
259
|
+
type ForbidOptions = {
|
|
260
|
+
/**
|
|
261
|
+
* 被禁的任务名,如 dev、build、lint、test、typecheck
|
|
262
|
+
*/
|
|
263
|
+
task: string;
|
|
264
|
+
};
|
|
265
|
+
/**
|
|
266
|
+
* 子包候选,相对路径与该包内对应脚本的执行命令
|
|
267
|
+
*/
|
|
268
|
+
type Candidate = {
|
|
269
|
+
/**
|
|
270
|
+
* 子包相对 monorepo 根的路径,如 apps/cli
|
|
271
|
+
*/
|
|
272
|
+
relPath: string;
|
|
273
|
+
/**
|
|
274
|
+
* 该子包内运行该任务的可复制命令
|
|
275
|
+
*/
|
|
276
|
+
command: string;
|
|
277
|
+
};
|
|
278
|
+
/**
|
|
279
|
+
* 从 package.json 对象提取 scripts 区块为字符串映射
|
|
280
|
+
*
|
|
281
|
+
* @remarks
|
|
282
|
+
* 纯函数无 IO,便于单元测试覆盖各类 scripts 字段形态
|
|
283
|
+
* @param pkg - package.json 对象
|
|
284
|
+
* @returns scripts 映射,无 scripts 或类型不合法时为空映射
|
|
285
|
+
*/
|
|
286
|
+
declare const extractScripts: (pkg: Record<string, unknown>) => Record<string, string>;
|
|
287
|
+
/**
|
|
288
|
+
* 从 package.json 对象判断是否含指定 task 脚本
|
|
289
|
+
*
|
|
290
|
+
* @param pkg - package.json 对象
|
|
291
|
+
* @param task - 目标任务名
|
|
292
|
+
* @returns 含该脚本且脚本值非空时 true
|
|
293
|
+
*/
|
|
294
|
+
declare const hasScript: (pkg: Record<string, unknown>, task: string) => boolean;
|
|
295
|
+
/**
|
|
296
|
+
* 格式化 forbid 消息文本
|
|
297
|
+
*
|
|
298
|
+
* @remarks
|
|
299
|
+
* 纯函数无进程耦合,便于单元测试锁定输出结构,
|
|
300
|
+
* 由 `runForbidCommand` 着色后写流
|
|
301
|
+
* @param task - 被禁的任务名
|
|
302
|
+
* @param candidates - 候选子包列表,已排序
|
|
303
|
+
* @param turboHint - 是否附加 turbo 全量入口提示
|
|
304
|
+
* @returns 完整消息文本,未着色
|
|
305
|
+
*/
|
|
306
|
+
declare const formatForbidMessage: (task: string, candidates: Candidate[], turboHint: boolean) => string;
|
|
307
|
+
/**
|
|
308
|
+
* 执行 forbid 守卫
|
|
309
|
+
*
|
|
310
|
+
* @remarks
|
|
311
|
+
* 以当前工作目录作为 monorepo 根,扫描全部 workspace 包,
|
|
312
|
+
* 逐包读取 package.json 过滤出含目标 task 脚本的子包,
|
|
313
|
+
* 构造可复制命令按相对路径排序,输出禁令与指引后退出码 1
|
|
314
|
+
* @param options - 含目标任务名的选项
|
|
315
|
+
*/
|
|
316
|
+
declare const runForbidCommand: (options: ForbidOptions) => Promise<void>;
|
|
317
|
+
//#endregion
|
|
318
|
+
export { COLORS, DOMAIN_COUNT, DOMAIN_ENTRIES, type DelegateResult, type DomainEntry, PORTFOLIO_CONFIG_FILE_NAME, type PortfolioSource, type PushAllOptions, type ResolvedPortfolio, defineDomainEntry, delegateToDomain, domainEntrySchema, extractScripts, formatForbidMessage, hasScript, loadToolchainConfig, readPackageJson, readWorkspacePatterns, resolveBinCommand, resolvePortfolioConfig, 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}from"@longzai-intelligence-toolchain/config";import{loadConfigFile as m}from"@longzai-intelligence-shared-config/core";const h=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)}),g=e=>{let t=h.safeParse(e);if(!t.success){let e=t.error.issues.map(e=>`${e.path.join(`.`)}: ${e.message}`).join(`, `);throw Error(`域表条目校验失败: ${e}`)}return e},_=Object.freeze([g({domain:`version`,bin:`lzi-version`,packageName:`@longzai-intelligence-version/cli`,description:`版本号同步与检查`}),g({domain:`dependencies`,bin:`lzi-dependencies`,packageName:`@longzai-intelligence-dependencies/cli`,description:`依赖版本升级与跨仓批量升级`}),g({domain:`changelog`,bin:`lzi-changelog`,packageName:`@longzai-intelligence-changelog/cli`,description:`变更日志条目追加与撤回`}),g({domain:`release`,bin:`lzi-release`,packageName:`@longzai-intelligence-release/cli`,description:`版本发布操作`}),g({domain:`config`,bin:`lzi-config`,packageName:`@longzai-intelligence-config/cli`,description:`scripts 与配置文件基线门禁`}),g({domain:`env`,bin:`lzi-env-cli`,packageName:`@longzai-intelligence-env/cli`,description:`环境变量声明门禁`}),g({domain:`tsconfig`,bin:`lzi-tsconfig`,packageName:`@longzai-intelligence-tsconfig/cli`,description:`tsconfig 形态门禁`}),g({domain:`scripts`,bin:`lzi-scripts`,packageName:`@longzai-intelligence-scripts/cli`,description:`标准脚本完备性审计`}),g({domain:`git`,bin:`lzi-git`,packageName:`@longzai-intelligence-git/cli`,description:`gitignore 治理与 git 透传`}),g({domain:`vscode`,bin:`lzi-vscode-cli`,packageName:`@longzai-intelligence-vscode/cli`,description:`工作区编辑器设置同步`}),g({domain:`agent`,bin:`lzi-agent-cli`,packageName:`@longzai-intelligence-agent-tools/cli`,description:`指令面真源合成`}),g({domain:`decision`,bin:`lzi-decision`,packageName:`@longzai-intelligence-decision/cli`,description:`ADR 编号与索引门禁`}),g({domain:`standards`,bin:`lzi-standards`,packageName:`@longzai-intelligence-standards/cli`,description:`标准注册表治理`}),g({domain:`oxlint`,bin:`lzi-oxlint`,packageName:`@longzai-intelligence-oxlint/cli`,description:`lint 依赖声明形态检查`}),g({domain:`bun`,bin:`lzi-bun-cli`,packageName:`@longzai-intelligence-bun/cli`,description:`Bun 工具链配置生成与锁文件审计`}),g({domain:`builder`,bin:`lzi-builder`,packageName:`@longzai-intelligence-builder/cli`,description:`统一构建`}),g({domain:`bootstrap`,bin:`lzi-bootstrap`,packageName:`@longzai-intelligence-bootstrap/cli`,description:`产品启动器`}),g({domain:`port`,bin:`lzi-port`,packageName:`@longzai-intelligence-port/cli`,description:`端口注册与查询`})]),v=_.length,y=e=>{try{return t(e,n.X_OK),!0}catch{return!1}},b=e=>{if(c(e))return y(e)?e:null;let t=process.cwd();for(;;){let n=l(t,`node_modules`,`.bin`,e);if(y(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(y(n))return n}return null},x=f(`@longzai-intelligence-toolchain/core/delegate`),S=async(e,t,n)=>{if(n?.enabled===!1)return x.error(`域 ${e.domain} 已被就地配置禁用`),{exitCode:1};let r=n?.bin??e.bin,i=b(r);return i===null?(x.error(`未找到可执行命令:${r}`),x.error(`请安装引擎依赖:${e.packageName}`),{exitCode:127}):{exitCode:await Bun.spawn([i,...t],{stdin:`inherit`,stdout:`inherit`,stderr:`inherit`}).exited??1}},C={RED:`\x1B[0;31m`,GREEN:`\x1B[0;32m`,YELLOW:`\x1B[1;33m`,BLUE:`\x1B[0;34m`,RESET:`\x1B[0m`};function w(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 T(...e){process.stdout.write(`${w(e)}\n`)}function E(...e){process.stderr.write(`${w(e)}\n`)}const D=`lzi-architecture.yaml`,O=e=>Array.isArray(e)&&e.every(e=>typeof e==`string`),k=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&&O(e.exclude)&&(t.exclude=e.exclude),t},A=async e=>{try{let t=await Bun.file(e).text();return k(Bun.YAML.parse(t))}catch(t){E(`错误:加载配置文件失败:${e}`,t instanceof Error?t.message:String(t)),process.exit(1)}},j=e=>typeof e!=`object`||!e||Array.isArray(e)?{}:`exclude`in e&&O(e.exclude)?{exclude:e.exclude}:{},M=async e=>{if(e){let t=d(process.cwd(),e);r(t)||(E(`错误:配置文件不存在:${t}`),process.exit(1));let n=await A(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 m(e),r=j(n);return{rootDir:s(d(t)),exclude:r.exclude??[],source:`globals`}}catch(t){E(`错误:加载 globals 聚合配置失败:${e}`,t instanceof Error?t.message:String(t)),process.exit(1)}}let n=process.cwd();for(;n!==`/`;){let e=l(n,D);if(r(e)){let t=await A(e);return{rootDir:d(s(e),t.root??`../`),exclude:t.exclude??[],source:`yaml-upward`}}n=s(n)}return null},N=(e,t)=>{let n;try{n=i(e)}catch{E(`错误:无法读取聚合根目录:${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)},P=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},F=e=>Bun.spawnSync([`git`,`rev-parse`,`--abbrev-ref`,`--symbolic-full-name`,`@{upstream}`],{cwd:e,stdout:`pipe`,stderr:`pipe`}).exitCode===0,I=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},L=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},R=e=>{let t=L(e);return t?Bun.spawnSync([`git`,`push`,`origin`,`HEAD:${t}`],{cwd:e,stdout:`pipe`,stderr:`pipe`}).exitCode===0:!1},z=async e=>{let{dryRun:t}=e,n=e.concurrency??10,i=await M(e.config);i||(E(`错误:未找到产品群配置文件 ${D}`),E(`提示:请在 architecture 项目创建该配置文件,参考 lzi-architecture.sample.yaml`),E(`提示:或使用 --config <path> 显式指定`),E(`提示:或在 .env 设置 LZI_GLOBALS_ROOT 定位 globals 仓 TS 配置,见 ADR 0081`),process.exit(1));let a=i.rootDir;r(a)||(E(`错误:聚合根目录不存在:${a}`),process.exit(1));let o=i.exclude;T(`${C.BLUE}═══ push-all ═══${C.RESET}`),T(`聚合配置来源:${i.source}`),T(`聚合根:${a}`),T(`并发数:${n}`),o.length>0&&T(`排除项目:${o.join(`, `)}`),t&&T(`${C.YELLOW}[dry-run] 预览模式,不实际推送${C.RESET}`),T(``);let s=N(a,o);T(`发现 ${s.length} 个子项目,正在扫描推送状态`),T(``);let c=[],l=[],u=[],d=[];for(let e of s){let{name:t,dir:n}=e;if(!P(n)){l.push(t);continue}if(!F(n)){u.push(t);continue}let r=I(n);r===0?d.push(t):c.push({name:t,dir:n,ahead:r})}if(t){T(`${C.GREEN}待推送:${c.length}${C.RESET}`);for(let e of c)T(` ${e.name},ahead ${e.ahead}`);l.length>0&&(T(``),T(`跳过,无 git remote:${l.length}`)),u.length>0&&T(`跳过,无 upstream tracking:${u.length}`),d.length>0&&T(`跳过,已是最新:${d.length}`),T(``),T(`${C.BLUE}汇总:${c.length} 待推送,${d.length} 已最新,${l.length+u.length} 跳过${C.RESET}`);return}if(c.length===0){T(`${C.GREEN}所有项目均已是最新,无需推送${C.RESET}`),T(`跳过,无 git remote:${l.length}`),T(`跳过,无 upstream tracking:${u.length}`),T(`跳过,已是最新:${d.length}`);return}T(`待推送 ${c.length} 个项目,并发数 ${n},开始推送`),T(``);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=R(t.dir);f.push({name:t.name,status:r?`pushed`:`failed`,ahead:t.ahead,reason:r?void 0:`git push 失败`}),p++;let i=r?`${C.GREEN}✓${C.RESET}`:`${C.RED}✗${C.RESET}`;T(` [${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`);T(`${C.BLUE}═══ 处理结果 ═══${C.RESET}`),T(`${C.GREEN}已推送:${h.length}${C.RESET}`);for(let e of h)T(` ${e.name},ahead ${e.ahead}`);if(g.length>0){T(``),T(`${C.RED}失败:${g.length}${C.RESET}`);for(let e of g)T(` ${e.name}:${e.reason}`)}T(``),T(`${C.BLUE}汇总:${h.length} 已推送,${g.length} 失败,${d.length} 已最新,${l.length+u.length} 跳过${C.RESET}`),g.length>0&&(process.exitCode=1)},B=[`packages/*`,`apps/*`],V=e.record(e.string(),e.unknown()),H=e.record(e.string(),e.string()),U=e.array(e.string()),W=e.object({name:e.string()}),G=async e=>Bun.file(e).json(),K=async e=>{try{let t=V.safeParse(await G(`${e}/package.json`));if(t.success){let e=t.data.workspaces,n=U.safeParse(e);if(n.success&&n.data.length>0)return n.data;let r=V.safeParse(e);if(r.success){let e=U.safeParse(r.data.packages);if(e.success&&e.data.length>0)return e.data}}}catch{}return B},q=async e=>{let t=/* @__PURE__ */ new Map,n=await K(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 G(r),n=W.safeParse(e);if(n.success){let e=r.replace(/[/\\]package\.json$/,``);t.set(n.data.name,e)}}catch{}}catch{}return t},J=async e=>{let t=V.safeParse(await Bun.file(`${e}/package.json`).json());if(!t.success)throw Error(`package.json 格式不合法:${e}`);return t.data},Y=e=>{let t=H.safeParse(e.scripts);return t.success?t.data:{}},X=(e,t)=>{let n=Y(e)[t];return typeof n==`string`&&n.trim()!==``},Z=(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
|
+
`)},Q=/* @__PURE__ */ new Set([`dev`,`build`,`lint`,`test`,`typecheck`]),$=async e=>{let{task:t}=e,n=process.cwd(),r=await q(n),i=[];for(let[,e]of r)try{let r=await J(e);if(!X(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=Q.has(t),o=Z(t,i,a),s=C.RED,c=C.RESET;T(o.split(`
|
|
4
|
+
`).map((e,t)=>t===0?`${s}${e}${c}`:e).join(`
|
|
5
|
+
`)),E(``),E(`如需在根目录触发全量任务,请显式使用 turbo,不要直接运行根脚本。`),process.exit(1)};export{C as COLORS,v as DOMAIN_COUNT,_ as DOMAIN_ENTRIES,D as PORTFOLIO_CONFIG_FILE_NAME,g as defineDomainEntry,S as delegateToDomain,h as domainEntrySchema,Y as extractScripts,Z as formatForbidMessage,X as hasScript,p as loadToolchainConfig,J as readPackageJson,K as readWorkspacePatterns,b as resolveBinCommand,M as resolvePortfolioConfig,$ as runForbidCommand,z as runPushAllCommand,q as scanAllPackages,E as stderr,T 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.
|
|
4
|
-
"
|
|
5
|
-
"
|
|
6
|
-
|
|
3
|
+
"version": "0.0.1",
|
|
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.1",
|
|
42
|
+
"zod": "^4.6.5"
|
|
43
|
+
},
|
|
44
|
+
"devDependencies": {
|
|
45
|
+
"@longzai-intelligence-architecture/config": "0.0.2"
|
|
46
|
+
}
|
|
47
|
+
}
|