@longzai-intelligence-cli/core 0.0.10 → 0.0.12
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 +14 -25
- package/dist/index.d.ts +4 -3
- package/dist/index.js +2 -2
- package/package.json +10 -7
package/README.md
CHANGED
|
@@ -1,31 +1,20 @@
|
|
|
1
1
|
# @longzai-intelligence-cli/core
|
|
2
2
|
|
|
3
|
-
Longzai Intelligence
|
|
3
|
+
Longzai Intelligence Cli 的核心包,承载命令行应用的命令装配、输出版式、交互契约与版本注入等平台无关能力,是全部预设与各命令行应用的共同基础。
|
|
4
4
|
|
|
5
|
-
##
|
|
5
|
+
## 简介
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
治理命令行基础设施的单一来源:交互与着色只定契约、实现经 Provider 注入,命令装配、输出版式、进度与持久化等能力由本包统一提供,各命令行应用不再散落自研 CLI 副本,避免装配与输出口径漂移。
|
|
8
8
|
|
|
9
|
-
##
|
|
9
|
+
## 能力
|
|
10
10
|
|
|
11
|
-
-
|
|
12
|
-
-
|
|
13
|
-
-
|
|
14
|
-
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
const program = createCli({
|
|
22
|
-
name: 'lzi-my-app',
|
|
23
|
-
description: '我的 CLI 应用',
|
|
24
|
-
});
|
|
25
|
-
|
|
26
|
-
program.command('hello').action(() => {
|
|
27
|
-
console.log('Hello, Longzai Intelligence!');
|
|
28
|
-
});
|
|
29
|
-
|
|
30
|
-
await program.parseAsync(process.argv);
|
|
31
|
-
```
|
|
11
|
+
- 命令装配工厂(`createCli()`,内置版本与帮助入口)
|
|
12
|
+
- 交互与着色契约(InteractionProvider / ColorProvider)及全局 Provider 槽位注入
|
|
13
|
+
- 交互函数(单选、确认、文本输入、spinner、提示与日志输出)
|
|
14
|
+
- 输出版式(text / json 双格式与表格渲染)
|
|
15
|
+
- 进度条与进度控制器
|
|
16
|
+
- CLI 版本号读取(构建期注入优先、开发期兜底)
|
|
17
|
+
- 命令定义工厂(选项声明与参数校验统一封装、父子命令挂接)
|
|
18
|
+
- 通用 JSON 文件持久化
|
|
19
|
+
- 日志条目格式化(时间戳、级别着色、条目美化、嵌套对象扁平化)
|
|
20
|
+
- 带前缀唯一 ID 生成
|
package/dist/index.d.ts
CHANGED
|
@@ -272,7 +272,8 @@ type CreateCliOptions = {
|
|
|
272
272
|
/**
|
|
273
273
|
* 创建 CLI 程序实例
|
|
274
274
|
*
|
|
275
|
-
* 基于 commander 封装,内置 `--version
|
|
275
|
+
* 基于 commander 封装,内置 `--version`(版本号显式传入优先,否则经 `getCliVersion`
|
|
276
|
+
* 解析——内联消费方构建期 define 注入 + 运行时 package.json 兜底)
|
|
276
277
|
* 与 `--help`。调用方注入交互/着色 provider 后,模块级交互函数(select/confirm 等)
|
|
277
278
|
* 与 OutputFormatter 即按注入的 provider 工作。
|
|
278
279
|
*
|
|
@@ -301,8 +302,8 @@ declare function createCli(options: CreateCliOptions): Command$1;
|
|
|
301
302
|
*
|
|
302
303
|
* 解析顺序:
|
|
303
304
|
*
|
|
304
|
-
* 1.
|
|
305
|
-
* 2.
|
|
305
|
+
* 1. `process.env.CLI_VERSION`——内联消费方构建期经 define 静态替换,或运行时环境变量注入
|
|
306
|
+
* 2. 兜底:从模块旁的 package.json 读取(源码形态 `src/../package.json`,产物形态 `dist/../package.json`)
|
|
306
307
|
* 3. 找不到时回退 '0.0.0'(极端沙箱场景),避免阻塞 --version 输出
|
|
307
308
|
*
|
|
308
309
|
* @returns CLI 版本号字符串
|
package/dist/index.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import"./rolldown-runtime-BqT_7tdF.js";import{createNodeLogger as e}from"@longzai-intelligence-logger/node";import{Command as t}from"commander";import{existsSync as n,mkdirSync as r,readFileSync as i,writeFileSync as a}from"node:fs";import{dirname as o}from"node:path";import"node:url";import*as
|
|
1
|
+
import"./rolldown-runtime-BqT_7tdF.js";import{createNodeLogger as e}from"@longzai-intelligence-logger/node";import{Command as t}from"commander";import{existsSync as n,mkdirSync as r,readFileSync as i,writeFileSync as a}from"node:fs";import{dirname as o,join as s}from"node:path";import{fileURLToPath as c}from"node:url";import*as l from"zod";let u;function d(){return u??=e(`@longzai-intelligence-cli/core/provider`),u}const f={red:e=>e,green:e=>e,yellow:e=>e,blue:e=>e,cyan:e=>e,magenta:e=>e,gray:e=>e,bold:e=>e,dim:e=>e};let p={select:async(e,t)=>t[0]?.value??``,textInput:async(e,t)=>t?.defaultValue??``,confirm:async(e,t)=>t?.defaultValue??!1,spinner:()=>({start:e=>d().info(e),stop:e=>d().info(e)}),note:(e,t)=>{t?d().info(`${t}: ${e}`):d().info(e)},log:{info:e=>d().info(e),success:e=>d().info(e),warn:e=>d().warn(e),error:e=>d().error(e),step:e=>d().info(e)}},m=f;function h(e){p=e}function g(e){m=e}function _(){return p}function v(){return m}function y(e){return typeof e==`object`&&!!e&&(!(`name`in e)||typeof e.name==`string`)&&`version`in e&&typeof e.version==`string`}const b=()=>{let e=process.env.CLI_VERSION;if(typeof e==`string`&&e.length>0)return e;try{let e=s(o(c(import.meta.url)),`..`,`package.json`),t=JSON.parse(i(e,`utf-8`));if(y(t)&&t.name===`@longzai-intelligence-cli/core`)return t.version}catch{}return`0.0.0`};function x(e){let n=e.version??b();e.interaction&&h(e.interaction),e.color&&g(e.color);let r=new t;return r.name(e.name).version(n,`-v, --version`,`输出 ${e.name} 的版本号`),e.description&&r.description(e.description),r}let S;function C(){return S??=e(`@longzai-intelligence-cli/core/output`),S}var w=class{format;constructor(e=`text`){this.format=e}get colors(){return v()}success(e,t){this.format===`json`?C().info(JSON.stringify({success:!0,data:e},null,2)):C().info(t?this.colors.green(t):this.colors.green(this.formatData(e)))}error(e){if(this.format===`json`){let t=e instanceof Error?{message:e.message,name:e.name}:{message:String(e)};C().info(JSON.stringify({success:!1,error:t},null,2))}else{let t=e instanceof Error?e.message:String(e);C().error(this.colors.red(`错误: ${t}`))}}info(e){this.format===`json`?C().info(JSON.stringify({success:!0,message:e},null,2)):C().info(this.colors.blue(e))}warn(e){this.format===`json`?C().info(JSON.stringify({success:!0,warning:e},null,2)):C().info(this.colors.yellow(e))}table(e,t){if(this.format===`json`){let n=t.map(t=>{let n={};return e.forEach((e,r)=>{n[e]=t[r]??``}),n});C().info(JSON.stringify({success:!0,data:n},null,2))}else{let n=e.map((e,n)=>Math.min(60,Math.max(e.length,...t.map(e=>(e[n]??``).length))));C().info(e.map((e,t)=>this.colors.bold(e.padEnd(n[t]??0))).join(` `)),C().info(n.map(e=>`─`.repeat(e??0)).join(` `));for(let e of t)C().info(e.map((e,t)=>{let r=n[t]??0,i=e??``;return i.length>r?i.slice(0,Math.max(0,r-1))+`…`:i.padEnd(r)}).join(` `))}}formatData(e){return typeof e==`string`?e:typeof e==`number`||typeof e==`boolean`?String(e):JSON.stringify(e,null,2)}};function T(e){return e===`json`?`json`:`text`}async function E(e,t){return _().select(e,t)}async function D(e,t){return _().textInput(e,t)}async function O(e,t){return _().confirm(e,t)}function k(){return _().spinner()}function A(e,t){_().note(e,t)}const j={info(e){_().log.info(e)},success(e){_().log.success(e)},warn(e){_().log.warn(e)},error(e){_().log.error(e)},step(e){_().log.step(e)}};let M;function N(){return M??=e(`@longzai-intelligence-cli/core/progress`),M}function P(e=100){let t=-1;return{update(e,n){let r=Math.max(0,Math.min(100,e)),i=Math.round(r/100*30),a=`█`.repeat(i)+`░`.repeat(30-i);if(e!==t){t=e;let i=n?` ${n}`:``;process.stdout.write(`\r${v().blue(a)} ${r.toFixed(0)}%${i}`),r>=100&&process.stdout.write(`
|
|
2
2
|
`)}},done(e){process.stdout.write(`
|
|
3
|
-
`),e&&
|
|
3
|
+
`),e&&N().info(v().green(`✓ ${e}`))}}}const F={debug:`gray`,error:`red`,fatal:`red`,info:`green`,trace:`gray`,warn:`yellow`};function I(e){try{return new Date(e).toLocaleString(`zh-CN`,{day:`2-digit`,hour:`2-digit`,hour12:!1,minute:`2-digit`,month:`2-digit`,second:`2-digit`,year:`numeric`})}catch{return e}}function L(e){let t=e.toLowerCase(),n=e.toUpperCase().padEnd(5),r=F[t]??`green`;return v()[r](n)}function R(e){let t=v(),n=[];return e.timestamp!==void 0&&n.push(t.gray(I(e.timestamp))),n.push(L(e.level??`info`)),e.serviceName!==void 0&&e.serviceName!==``&&n.push(t.blue(`[${e.serviceName}]`)),n.push(e.message??String(e.message??``)),e.metadata!==void 0&&typeof e.metadata==`object`&&Object.keys(e.metadata).length>0&&n.push(t.gray(JSON.stringify(e.metadata))),n.join(` `)}function z(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function B(e,t=``){let n={};for(let[r,i]of Object.entries(e)){let e=t===``?r:`${t}.${r}`;z(i)?Object.assign(n,B(i,e)):n[e]=String(i??``)}return n}const V=l.array(l.unknown());function H(e){return V.safeParse(e).success}var U=class{filePath;constructor(e){this.filePath=e;let t=o(e);n(t)||r(t,{recursive:!0}),n(e)||a(e,`[]`,`utf-8`)}read(){try{let e=i(this.filePath,`utf-8`),t=JSON.parse(e);return H(t)?t:[]}catch{return[]}}write(e){let t=o(this.filePath);n(t)||r(t,{recursive:!0}),a(this.filePath,JSON.stringify(e,null,2),`utf-8`)}add(e){let t=this.read();t.push(e),this.write(t)}find(e){return this.read().find(e)}remove(e){let t=this.read(),n=t.filter(t=>!e(t));return n.length!==t.length&&(this.write(n),!0)}update(e,t){let n=this.read(),r=!1,i=n.map(n=>e(n)?(r=!0,t(n)):n);return r&&this.write(i),r}};function W(e){return`${e}_${Date.now().toString(36)}_${Math.random().toString(36).slice(2,8)}`}let G;function K(){return G??=e(`@longzai-intelligence-cli/core/define-command`),G}function q(e,t){let n=e.commands.find(e=>e.name()===t);return n===void 0?e.command(t):n}function J(e,t){if(t.length===1){let n=t[0];if(n===void 0)throw Error(`defineCommand: segments 为空,无法解析命令名`);return e.command(n)}let[n,...r]=t;if(n===void 0)throw Error(`defineCommand: segments 首段为空,无法解析父命令名`);let i=r.pop();if(i===void 0)throw Error(`defineCommand: segments 末段为空,无法解析子命令名`);let a=q(e,n);for(let e of r)a=q(a,e);return a.command(i)}function Y(e,n){let r=J(e,n.name.split(` `).filter(e=>e.length>0));n.description&&r.description(n.description);for(let e of n.arguments??[])e.description?r.argument(e.signature,e.description):r.argument(e.signature);for(let e of n.options??[])e.defaultValue===void 0?r.option(e.flags,e.description??``):r.option(e.flags,e.description??``,e.defaultValue);r.action(async(...e)=>{let r=e[e.length-1];if(!(r instanceof t))return;let i=r.opts(),a=r.args,o=n.schema.safeParse(i);if(!o.success){let e=o.error.issues.map(e=>e.message).join(`, `);K().error(v().red(`参数校验失败: ${e}`)),_().log.error(`参数校验失败: ${e}`),process.exit(1)}await n.action(o.data,a)})}export{U as JsonStorage,w as OutputFormatter,O as confirm,x as createCli,Y as defineCommand,B as flattenObject,L as formatLevel,R as formatLogEntry,I as formatTimestamp,W as generateId,b as getCliVersion,v as getColorProvider,_ as getInteractionProvider,j as log,A as note,T as parseOutputFormat,P as progressBar,q as resolveCommandParent,E as select,g as setColorProvider,h as setInteractionProvider,k as spinner,D as textInput};
|
package/package.json
CHANGED
|
@@ -1,11 +1,14 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@longzai-intelligence-cli/core",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.12",
|
|
4
4
|
"private": false,
|
|
5
|
+
"description": "Longzai Intelligence CLI 核心契约与平台无关能力",
|
|
5
6
|
"keywords": [
|
|
6
7
|
"cli",
|
|
7
8
|
"commander",
|
|
8
|
-
"
|
|
9
|
+
"core",
|
|
10
|
+
"infrastructure",
|
|
11
|
+
"longzai-intelligence"
|
|
9
12
|
],
|
|
10
13
|
"license": "UNLICENSED",
|
|
11
14
|
"files": [
|
|
@@ -22,12 +25,12 @@
|
|
|
22
25
|
},
|
|
23
26
|
"scripts": {
|
|
24
27
|
"build": "lzi-builder",
|
|
25
|
-
"build:prod": "NODE_ENV=production
|
|
28
|
+
"build:prod": "NODE_ENV=production bun run build",
|
|
26
29
|
"prepublishOnly": "bun run build:prod",
|
|
27
30
|
"typecheck": "bun run typecheck:app && bun run typecheck:node && bun run typecheck:test",
|
|
28
|
-
"typecheck:app": "tsgo
|
|
29
|
-
"typecheck:node": "tsgo
|
|
30
|
-
"typecheck:test": "tsgo
|
|
31
|
+
"typecheck:app": "lzi-tsgo typecheck tsconfig/app.json",
|
|
32
|
+
"typecheck:node": "lzi-tsgo typecheck tsconfig/node.json",
|
|
33
|
+
"typecheck:test": "lzi-tsgo typecheck tsconfig/test.json",
|
|
31
34
|
"lint": "oxlint && oxfmt --check",
|
|
32
35
|
"lint:fix": "oxlint --fix && oxfmt",
|
|
33
36
|
"test": "bun test",
|
|
@@ -37,7 +40,7 @@
|
|
|
37
40
|
},
|
|
38
41
|
"dependencies": {
|
|
39
42
|
"@longzai-intelligence-builder/utils": "^0.2.13",
|
|
40
|
-
"@longzai-intelligence-logger/node": "^0.1.
|
|
43
|
+
"@longzai-intelligence-logger/node": "^0.1.5",
|
|
41
44
|
"commander": "^14.0.0",
|
|
42
45
|
"zod": "^4.4.3"
|
|
43
46
|
},
|