@longzai-intelligence-plugin/kit 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 ADDED
@@ -0,0 +1,15 @@
1
+ # @longzai-intelligence-plugin/kit
2
+
3
+ Longzai Intelligence Plugin 的零框架工具包,为宿主载体件与插件命令提供子进程执行、脚本探测与结果呈现的通用工具,不含业务知识。
4
+
5
+ ## 简介
6
+
7
+ 治理插件命令执行链的通用工具面:在目标仓根执行子进程命令的统一服务、root 脚本形态的探测与改道决策、检查报告的终端与 JSON 双模式呈现、用户自定义命令的文件契约。全部工具零框架依赖,宿主自持装配时按需取用。
8
+
9
+ ## 能力
10
+
11
+ - 子进程执行服务,含目标仓根注入、超时控制、退出码透传、输出尾部摘录与可选流式转发
12
+ - root 脚本形态探测,识别缺失、守卫哨兵、禁令守卫与直跑四形态并做改道决策
13
+ - 检查报告终端渲染,含四态状态行、失败输出面板与汇总行
14
+ - 命令结果 JSON 双模式输出,供机读透出
15
+ - 用户自定义命令文件契约,含读取、校验与重名拒绝
@@ -0,0 +1,277 @@
1
+ import * as z from "zod";
2
+ import { CheckReport, PluginCommandResult } from "@longzai-intelligence-plugin/core";
3
+ //#region src/exec.service.d.ts
4
+ /**
5
+ * 子进程执行服务,机制七的执行面
6
+ *
7
+ * 统一 cwd 注入、超时、退出码、输出尾部摘录与可选流式转发。宿主无关,
8
+ * 使用 node 标准 child_process,bun 与 node 宿主均可运行
9
+ */
10
+ /**
11
+ * 执行入参
12
+ */
13
+ type ExecSpec = {
14
+ /**
15
+ * 命令名(如 `bun`)
16
+ */
17
+ command: string;
18
+ /**
19
+ * 参数数组
20
+ */
21
+ args: readonly string[];
22
+ /**
23
+ * 工作目录,通常为目标仓根
24
+ */
25
+ cwd: string;
26
+ /**
27
+ * 超时毫秒数,缺省取服务缺省
28
+ */
29
+ timeoutMs?: number;
30
+ /**
31
+ * 附加环境变量,与 process.env 合并
32
+ */
33
+ env?: Record<string, string>;
34
+ /**
35
+ * 是否流式转发,实时透传 stdio,此时摘录为空
36
+ */
37
+ stream?: boolean;
38
+ };
39
+ /**
40
+ * 执行产物
41
+ */
42
+ type ExecOutcome = {
43
+ /**
44
+ * 退出码,超时被杀为非零
45
+ */
46
+ code: number;
47
+ /**
48
+ * 耗时毫秒数
49
+ */
50
+ durationMs: number;
51
+ /**
52
+ * 标准输出尾部摘录
53
+ */
54
+ stdoutExcerpt: string;
55
+ /**
56
+ * 标准错误尾部摘录
57
+ */
58
+ stderrExcerpt: string;
59
+ /**
60
+ * 是否因超时被终止
61
+ */
62
+ timedOut: boolean;
63
+ };
64
+ /**
65
+ * 执行服务缺省项
66
+ */
67
+ type ExecServiceOptions = {
68
+ /**
69
+ * 缺省超时毫秒数
70
+ *
71
+ * @default 300000
72
+ */
73
+ defaultTimeoutMs?: number;
74
+ /**
75
+ * 摘录保留尾部行数
76
+ *
77
+ * @default 40
78
+ */
79
+ excerptLines?: number;
80
+ };
81
+ /**
82
+ * 执行服务
83
+ */
84
+ type ExecService = {
85
+ /**
86
+ * 同步执行一条命令
87
+ *
88
+ * @param spec - 执行入参
89
+ * @returns 执行产物
90
+ */
91
+ run(spec: ExecSpec): ExecOutcome;
92
+ };
93
+ /**
94
+ * 创建子进程执行服务
95
+ *
96
+ * @param options - 缺省项
97
+ * @returns 执行服务实例
98
+ */
99
+ declare function createExecService(options?: ExecServiceOptions): ExecService;
100
+ //#endregion
101
+ //#region src/script-probe.utils.d.ts
102
+ /**
103
+ * 目标仓 root 脚本形态探测
104
+ *
105
+ * 普查事实见架构报告 records/002 质量守卫族,产品仓 root 的 lint 与 typecheck
106
+ * 与 test 等质量脚本多为 `lzi-dev-cli forbid` 哨兵或 echo 禁令,库仓 root 为真实
107
+ * turbo 任务,执行前必须识别形态并决定直跑还是改道 `bun turbo run`
108
+ */
109
+ /**
110
+ * root 脚本四形态
111
+ */
112
+ type RootScriptForm = 'missing' | 'forbid-sentinel' | 'echo-guard' | 'direct';
113
+ /**
114
+ * 探测结果
115
+ */
116
+ type RootScriptProbe = {
117
+ /**
118
+ * 脚本形态
119
+ */
120
+ form: RootScriptForm;
121
+ /**
122
+ * 脚本原文,missing 时缺省
123
+ */
124
+ command?: string;
125
+ };
126
+ /**
127
+ * 探测目标仓 root 脚本形态
128
+ *
129
+ * @param repoRoot - 目标仓根绝对路径
130
+ * @param scriptName - scripts 键名(如 `lint`、`test`)
131
+ * @returns 形态与原文
132
+ */
133
+ declare function probeRootScript(repoRoot: string, scriptName: string): RootScriptProbe;
134
+ /**
135
+ * 质量任务的执行改道决策产物,含命令与参数,脚本缺失时为 null
136
+ */
137
+ type QualityTaskInvocation = {
138
+ command: string;
139
+ args: readonly string[];
140
+ } | null;
141
+ /**
142
+ * 质量任务的执行改道决策
143
+ *
144
+ * 直跑形态执行 `bun run <scriptName>`;forbid 哨兵与 echo 禁令形态改道
145
+ * `bun turbo run <scriptName>`;脚本缺失返回 null 由调用方记 skip。
146
+ *
147
+ * @param probe - 探测结果
148
+ * @param scriptName - scripts 键名
149
+ * @returns 执行命令与参数,缺失时为 null
150
+ */
151
+ declare function resolveQualityTaskInvocation(probe: RootScriptProbe, scriptName: string): QualityTaskInvocation;
152
+ //#endregion
153
+ //#region src/render.service.d.ts
154
+ /**
155
+ * 输出格式,text 人读或 json 机读,结构化类型与宿主 CLI 框架的格式枚举同构
156
+ */
157
+ type OutputFormat = 'text' | 'json';
158
+ /**
159
+ * 渲染着色器,结构化类型与宿主 CLI 框架的颜色 Provider 结构同构
160
+ */
161
+ type RenderColor = {
162
+ /**
163
+ * 绿色(通过态)
164
+ */
165
+ green: (text: string) => string;
166
+ /**
167
+ * 红色(失败态)
168
+ */
169
+ red: (text: string) => string;
170
+ /**
171
+ * 黄色(警告态)
172
+ */
173
+ yellow: (text: string) => string;
174
+ /**
175
+ * 灰色(次要信息)
176
+ */
177
+ gray: (text: string) => string;
178
+ /**
179
+ * 加粗(汇总标题)
180
+ */
181
+ bold: (text: string) => string;
182
+ };
183
+ /**
184
+ * 渲染检查报告为多行文本
185
+ *
186
+ * @param report - 检查报告
187
+ * @param color - 着色器
188
+ * @returns 行数组(逐项行 + 失败摘录面板 + 汇总行)
189
+ */
190
+ declare function renderCheckReportLines(report: CheckReport, color: RenderColor): string[];
191
+ /**
192
+ * 结果输出选项
193
+ */
194
+ type PrintPluginCommandResultOptions = {
195
+ /**
196
+ * 输出格式(text 人读或 json 机读)
197
+ */
198
+ format: OutputFormat;
199
+ /**
200
+ * 着色器
201
+ */
202
+ color: RenderColor;
203
+ /**
204
+ * 输出行回调
205
+ */
206
+ write: (line: string) => void;
207
+ };
208
+ /**
209
+ * 输出命令结果(text 或 json 双模式)
210
+ *
211
+ * @param result - 命令结果
212
+ * @param options - 输出选项
213
+ */
214
+ declare function printPluginCommandResult(result: PluginCommandResult, options: PrintPluginCommandResultOptions): void;
215
+ //#endregion
216
+ //#region src/user-commands.schema.d.ts
217
+ /**
218
+ * 用户命令定义文件路径段,相对仓根
219
+ */
220
+ declare const USER_COMMANDS_PATH: string;
221
+ /**
222
+ * 单条用户命令定义
223
+ */
224
+ declare const UserCommandSpecSchema: z.ZodObject<{
225
+ name: z.ZodString;
226
+ description: z.ZodString;
227
+ command: z.ZodString;
228
+ args: z.ZodDefault<z.ZodArray<z.ZodString>>;
229
+ timeoutMs: z.ZodDefault<z.ZodNumber>;
230
+ }, z.core.$strip>;
231
+ /**
232
+ * 单条用户命令定义类型
233
+ */
234
+ type UserCommandSpec = z.infer<typeof UserCommandSpecSchema>;
235
+ /**
236
+ * 用户命令文件整体 schema
237
+ */
238
+ declare const UserCommandsFileSchema: z.ZodObject<{
239
+ commands: z.ZodArray<z.ZodObject<{
240
+ name: z.ZodString;
241
+ description: z.ZodString;
242
+ command: z.ZodString;
243
+ args: z.ZodDefault<z.ZodArray<z.ZodString>>;
244
+ timeoutMs: z.ZodDefault<z.ZodNumber>;
245
+ }, z.core.$strip>>;
246
+ }, z.core.$strip>;
247
+ /**
248
+ * 用户命令文件解析结果
249
+ */
250
+ type UserCommandsParseResult = {
251
+ /**
252
+ * 解析成功标记
253
+ */
254
+ ok: true;
255
+ /**
256
+ * 命令清单
257
+ */
258
+ commands: readonly UserCommandSpec[];
259
+ } | {
260
+ /**
261
+ * 解析失败标记
262
+ */
263
+ ok: false;
264
+ /**
265
+ * 全部问题,逐条人类可读
266
+ */
267
+ issues: string[];
268
+ };
269
+ /**
270
+ * 读目标仓的用户命令文件,缺失视为空清单成功,未配置属常态
271
+ *
272
+ * @param repoRoot - 目标仓根绝对路径
273
+ * @returns 解析结果
274
+ */
275
+ declare function readUserCommands(repoRoot: string): UserCommandsParseResult;
276
+ //#endregion
277
+ export { type ExecOutcome, type ExecService, type ExecServiceOptions, type ExecSpec, type PrintPluginCommandResultOptions, type QualityTaskInvocation, type RenderColor, type RootScriptForm, type RootScriptProbe, USER_COMMANDS_PATH, type UserCommandSpec, UserCommandSpecSchema, UserCommandsFileSchema, type UserCommandsParseResult, createExecService, printPluginCommandResult, probeRootScript, readUserCommands, renderCheckReportLines, resolveQualityTaskInvocation };
package/dist/index.js ADDED
@@ -0,0 +1,4 @@
1
+ import{spawnSync as e}from"node:child_process";import{existsSync as t,readFileSync as n}from"node:fs";import{join as r}from"node:path";import*as i from"zod";function a(e,t){let n=e.length===0?[]:e.split(`
2
+ `);return n.length<=t?e:n.slice(n.length-t).join(`
3
+ `)}function o(t={}){let n=t.defaultTimeoutMs??3e5,r=t.excerptLines??40;return{run(t){let i=Date.now(),o=e(t.command,[...t.args],{cwd:t.cwd,timeout:t.timeoutMs??n,encoding:`utf-8`,env:{...process.env,...t.env},stdio:t.stream===!0?`inherit`:`pipe`}),s=Date.now()-i,c=o.signal===`SIGTERM`,l=typeof o.stdout==`string`?o.stdout:``,u=typeof o.stderr==`string`?o.stderr:``,d=typeof o.status==`number`?o.status:1;return o.error!==void 0&&d===1&&l.length===0&&u.length===0?{code:d,durationMs:s,stdoutExcerpt:``,stderrExcerpt:o.error.message,timedOut:c}:{code:d,durationMs:s,stdoutExcerpt:a(l,r),stderrExcerpt:a(u,r),timedOut:c}}}}function s(e){return typeof e==`object`&&!!e}function c(e,i){let a=r(e,`package.json`);if(!t(a))return{form:`missing`};try{let e=JSON.parse(n(a,`utf-8`));if(!s(e)||!s(e.scripts))return{form:`missing`};let t=e.scripts;if(!(i in t))return{form:`missing`};let r=t[i];return typeof r==`string`?r.includes(`lzi-dev-cli forbid`)?{form:`forbid-sentinel`,command:r}:r.trimStart().startsWith(`echo`)?{form:`echo-guard`,command:r}:{form:`direct`,command:r}:{form:`missing`}}catch{return{form:`missing`}}}function l(e,t){return e.form===`missing`?null:e.form===`direct`?{command:`bun`,args:[`run`,t]}:{command:`bun`,args:[`turbo`,`run`,t]}}function u(e){switch(e){case`pass`:return`✓`;case`fail`:return`✗`;case`warn`:return`⚠`;default:return`–`}}function d(e,t){let n=(e.status===`pass`?t.green:e.status===`fail`?t.red:e.status===`warn`?t.yellow:t.gray)(u(e.status)),r=e.durationMs===void 0?``:` ${t.gray(`${e.durationMs}ms`)}`,i=e.detail===void 0?``:` — ${e.detail}`;return`${n} ${e.label}${r}${i}`}function f(e,t){let n=[];for(let r of e.items)if(n.push(d(r,t)),r.status===`fail`&&r.outputExcerpt!==void 0&&r.outputExcerpt!==``)for(let e of r.outputExcerpt.split(`
4
+ `))n.push(t.gray(` ${e}`));let{pass:r,fail:i,warn:a,skip:o}=e.totals;return n.push(`${t.bold(`汇总`)} ${t.green(`通过 ${r}`)} ${t.red(`失败 ${i}`)} ${t.yellow(`警告 ${a}`)} ${t.gray(`跳过 ${o}`)}`),n}function p(e,t){if(t.format===`json`){t.write(JSON.stringify(e,null,2));return}let n=e.status===`ok`?t.color.green(e.status):e.status===`warn`?t.color.yellow(e.status):t.color.red(e.status);if(t.write(`${n} ${e.summary}`),e.report!==void 0)for(let n of f(e.report,t.color))t.write(n)}const m=r(`.lzi`,`plugin`,`user-commands.json`),h=i.object({name:i.string().regex(/^[a-z][a-z0-9-]*$/,`命令名必须 kebab-case`),description:i.string().min(1),command:i.string().min(1),args:i.array(i.string()).default([]),timeoutMs:i.number().int().positive().default(3e5)}),g=i.object({commands:i.array(h).min(1,`命令清单至少一条`)});function _(e){let i=r(e,m);if(!t(i))return{ok:!0,commands:[]};let a;try{a=n(i,`utf-8`)}catch(e){return{ok:!1,issues:[`文件不可读:${e instanceof Error?e.message:String(e)}`]}}let o;try{o=JSON.parse(a)}catch(e){return{ok:!1,issues:[`不是合法 JSON:${e instanceof Error?e.message:String(e)}`]}}let s=g.safeParse(o);if(!s.success)return{ok:!1,issues:s.error.issues.map(e=>`${e.path.map(String).join(`.`)||`<root>`}: ${e.message}`)};let c=/* @__PURE__ */ new Set;for(let e of s.data.commands){if(c.has(e.name))return{ok:!1,issues:[`commands.name 重复:${e.name}`]};c.add(e.name)}return{ok:!0,commands:s.data.commands}}export{m as USER_COMMANDS_PATH,h as UserCommandSpecSchema,g as UserCommandsFileSchema,o as createExecService,p as printPluginCommandResult,c as probeRootScript,_ as readUserCommands,f as renderCheckReportLines,l as resolveQualityTaskInvocation};
package/package.json ADDED
@@ -0,0 +1,42 @@
1
+ {
2
+ "name": "@longzai-intelligence-plugin/kit",
3
+ "version": "0.0.1",
4
+ "private": false,
5
+ "description": "Longzai Intelligence Plugin 零框架工具包",
6
+ "keywords": [
7
+ "kit",
8
+ "longzai-intelligence",
9
+ "plugin"
10
+ ],
11
+ "license": "UNLICENSED",
12
+ "files": [
13
+ "dist"
14
+ ],
15
+ "type": "module",
16
+ "main": "./dist/index.js",
17
+ "types": "./dist/index.d.ts",
18
+ "exports": {
19
+ ".": {
20
+ "types": "./dist/index.d.ts",
21
+ "import": "./dist/index.js"
22
+ }
23
+ },
24
+ "scripts": {
25
+ "build": "lzi-builder",
26
+ "build:prod": "NODE_ENV=production bun run build",
27
+ "prepublishOnly": "bun run build:prod",
28
+ "typecheck": "bun run typecheck:app && bun run typecheck:node && bun run typecheck:test",
29
+ "typecheck:app": "lzi-tsgo typecheck tsconfig/app.json",
30
+ "typecheck:node": "lzi-tsgo typecheck tsconfig/node.json",
31
+ "typecheck:test": "lzi-tsgo typecheck tsconfig/test.json",
32
+ "lint": "oxlint && oxfmt --check",
33
+ "lint:fix": "oxlint --fix && oxfmt",
34
+ "test": "bun test",
35
+ "clean": "lzi-dev-cli clean"
36
+ },
37
+ "dependencies": {
38
+ "@longzai-intelligence-plugin/core": "0.0.1",
39
+ "zod": "^4.4.3"
40
+ },
41
+ "devDependencies": {}
42
+ }