@longzai-intelligence-cli/core 0.0.8 → 0.0.10

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/dist/index.d.ts CHANGED
@@ -571,6 +571,18 @@ declare function flattenObject(obj: Record<string, unknown>, prefix?: string): R
571
571
  * 提供 JSON 文件读写、增删改查的通用存储能力,消除各 CLI 项目重复实现的 JsonStorage。
572
572
  * 基于 node:fs,无交互/着色依赖,属于 core 的平台无关能力。
573
573
  */
574
+ /**
575
+ * 记录匹配谓词(用于 find / remove / update 定位目标记录)
576
+ *
577
+ * @typeParam T - 记录类型
578
+ */
579
+ type Predicate<T> = (item: T) => boolean;
580
+ /**
581
+ * 记录更新函数(接收匹配记录,返回更新后的新记录)
582
+ *
583
+ * @typeParam T - 记录类型
584
+ */
585
+ type Updater<T> = (item: T) => T;
574
586
  /**
575
587
  * 通用 JSON 文件存储
576
588
  *
@@ -619,14 +631,14 @@ declare class JsonStorage<T> {
619
631
  * @param predicate - 匹配条件
620
632
  * @returns 匹配的记录或 undefined
621
633
  */
622
- find(predicate: (item: T) => boolean): T | undefined;
634
+ find(predicate: Predicate<T>): T | undefined;
623
635
  /**
624
636
  * 删除所有匹配的记录
625
637
  *
626
638
  * @param predicate - 匹配条件
627
639
  * @returns 是否实际删除了记录
628
640
  */
629
- remove(predicate: (item: T) => boolean): boolean;
641
+ remove(predicate: Predicate<T>): boolean;
630
642
  /**
631
643
  * 更新第一条匹配的记录
632
644
  *
@@ -634,7 +646,7 @@ declare class JsonStorage<T> {
634
646
  * @param updater - 更新函数(返回新记录)
635
647
  * @returns 是否实际更新了记录
636
648
  */
637
- update(predicate: (item: T) => boolean, updater: (item: T) => T): boolean;
649
+ update(predicate: Predicate<T>, updater: Updater<T>): boolean;
638
650
  }
639
651
  //#endregion
640
652
  //#region src/id.d.ts
@@ -722,6 +734,22 @@ type CommandSpec<T extends z.ZodType> = {
722
734
  */
723
735
  action: (validated: z.infer<T>, positionals: string[]) => Promise<void>;
724
736
  };
737
+ /**
738
+ * 解析或创建 commander 父命令(公共工具)
739
+ *
740
+ * 在 program 的直接子命令中查找指定名称的父命令,找不到则创建。
741
+ * 用于消费方注册「父命令 + 子命令」形式(如 `template create`)时复用已有父命令,
742
+ * 规避 commander 14.x 对 program.command('template create') 多次调用重复创建 'template' 父命令
743
+ * 导致的 'cannot add command' 错误。
744
+ *
745
+ * 消费方用原生 commander 注册带空格子命令时(defineCommand 已内置此逻辑,无需手动调用),
746
+ * 应通过本函数获取父命令再 .command('子命令名'),而非 program.command('父 子')。
747
+ *
748
+ * @param program - commander 顶层 Command 实例
749
+ * @param parentName - 父命令名称(不含空格的单段名)
750
+ * @returns 已存在或新创建的父命令 Command 实例
751
+ */
752
+ declare function resolveCommandParent(program: Command$1, parentName: string): Command$1;
725
753
  /**
726
754
  * 定义并注册命令(commander 选项 + zod 校验统一封装)
727
755
  *
@@ -756,4 +784,4 @@ type CommandSpec<T extends z.ZodType> = {
756
784
  */
757
785
  declare function defineCommand<T extends z.ZodType>(program: Command$1, spec: CommandSpec<T>): void;
758
786
  //#endregion
759
- export { type ColorProvider, type Command, type CommandSpec, type ConfirmOptions, type CreateCliOptions, type InteractionProvider, JsonStorage, type LogEntry, type LogLevel, type LogToolset, type OptionDecl, type OutputFormat, OutputFormatter, type ProgressController, type SelectOption, type SpinnerController, type TextInputOptions, confirm, createCli, defineCommand, flattenObject, formatLevel, formatLogEntry, formatTimestamp, generateId, getCliVersion, getColorProvider, getInteractionProvider, log, note, parseOutputFormat, progressBar, select, setColorProvider, setInteractionProvider, spinner, textInput };
787
+ export { type ColorProvider, type Command, type CommandSpec, type ConfirmOptions, type CreateCliOptions, type InteractionProvider, JsonStorage, type LogEntry, type LogLevel, type LogToolset, type OptionDecl, type OutputFormat, OutputFormatter, type ProgressController, type SelectOption, type SpinnerController, type TextInputOptions, confirm, createCli, defineCommand, flattenObject, formatLevel, formatLogEntry, formatTimestamp, generateId, getCliVersion, getColorProvider, getInteractionProvider, log, note, parseOutputFormat, progressBar, resolveCommandParent, select, setColorProvider, setInteractionProvider, spinner, textInput };
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";const s=e(`@longzai-intelligence-cli/core/provider`),c={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 l={select:async(e,t)=>t[0]?.value??``,textInput:async(e,t)=>t?.defaultValue??``,confirm:async(e,t)=>t?.defaultValue??!1,spinner:()=>({start:e=>s.info(e),stop:e=>s.info(e)}),note:(e,t)=>{t?s.info(`${t}: ${e}`):s.info(e)},log:{info:e=>s.info(e),success:e=>s.info(e),warn:e=>s.warn(e),error:e=>s.error(e),step:e=>s.info(e)}},u=c;function d(e){l=e}function f(e){u=e}function p(){return l}function m(){return u}const h=()=>`0.0.8`;function g(e){let n=e.version??h();e.interaction&&d(e.interaction),e.color&&f(e.color);let r=new t;return r.name(e.name).version(n,`-v, --version`,`输出 ${e.name} 的版本号`),e.description&&r.description(e.description),r}const _=e(`@longzai-intelligence-cli/core/output`);var v=class{format;constructor(e=`text`){this.format=e}get colors(){return m()}success(e,t){this.format===`json`?_.info(JSON.stringify({success:!0,data:e},null,2)):_.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)};_.info(JSON.stringify({success:!1,error:t},null,2))}else{let t=e instanceof Error?e.message:String(e);_.error(this.colors.red(`错误: ${t}`))}}info(e){this.format===`json`?_.info(JSON.stringify({success:!0,message:e},null,2)):_.info(this.colors.blue(e))}warn(e){this.format===`json`?_.info(JSON.stringify({success:!0,warning:e},null,2)):_.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});_.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))));_.info(e.map((e,t)=>this.colors.bold(e.padEnd(n[t]??0))).join(` `)),_.info(n.map(e=>`─`.repeat(e??0)).join(` `));for(let e of t)_.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 y(e){return e===`json`?`json`:`text`}async function b(e,t){return p().select(e,t)}async function x(e,t){return p().textInput(e,t)}async function S(e,t){return p().confirm(e,t)}function C(){return p().spinner()}function w(e,t){p().note(e,t)}const T={info(e){p().log.info(e)},success(e){p().log.success(e)},warn(e){p().log.warn(e)},error(e){p().log.error(e)},step(e){p().log.step(e)}},E=e(`@longzai-intelligence-cli/core/progress`);function D(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${m().blue(a)} ${r.toFixed(0)}%${i}`),r>=100&&process.stdout.write(`
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 s from"zod";const c=e(`@longzai-intelligence-cli/core/provider`),l={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 u={select:async(e,t)=>t[0]?.value??``,textInput:async(e,t)=>t?.defaultValue??``,confirm:async(e,t)=>t?.defaultValue??!1,spinner:()=>({start:e=>c.info(e),stop:e=>c.info(e)}),note:(e,t)=>{t?c.info(`${t}: ${e}`):c.info(e)},log:{info:e=>c.info(e),success:e=>c.info(e),warn:e=>c.warn(e),error:e=>c.error(e),step:e=>c.info(e)}},d=l;function f(e){u=e}function p(e){d=e}function m(){return u}function h(){return d}const g=()=>`0.0.10`;function _(e){let n=e.version??g();e.interaction&&f(e.interaction),e.color&&p(e.color);let r=new t;return r.name(e.name).version(n,`-v, --version`,`输出 ${e.name} 的版本号`),e.description&&r.description(e.description),r}const v=e(`@longzai-intelligence-cli/core/output`);var y=class{format;constructor(e=`text`){this.format=e}get colors(){return h()}success(e,t){this.format===`json`?v.info(JSON.stringify({success:!0,data:e},null,2)):v.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)};v.info(JSON.stringify({success:!1,error:t},null,2))}else{let t=e instanceof Error?e.message:String(e);v.error(this.colors.red(`错误: ${t}`))}}info(e){this.format===`json`?v.info(JSON.stringify({success:!0,message:e},null,2)):v.info(this.colors.blue(e))}warn(e){this.format===`json`?v.info(JSON.stringify({success:!0,warning:e},null,2)):v.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});v.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))));v.info(e.map((e,t)=>this.colors.bold(e.padEnd(n[t]??0))).join(` `)),v.info(n.map(e=>`─`.repeat(e??0)).join(` `));for(let e of t)v.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 b(e){return e===`json`?`json`:`text`}async function x(e,t){return m().select(e,t)}async function S(e,t){return m().textInput(e,t)}async function C(e,t){return m().confirm(e,t)}function w(){return m().spinner()}function T(e,t){m().note(e,t)}const E={info(e){m().log.info(e)},success(e){m().log.success(e)},warn(e){m().log.warn(e)},error(e){m().log.error(e)},step(e){m().log.step(e)}},D=e(`@longzai-intelligence-cli/core/progress`);function O(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${h().blue(a)} ${r.toFixed(0)}%${i}`),r>=100&&process.stdout.write(`
2
2
  `)}},done(e){process.stdout.write(`
3
- `),e&&E.info(m().green(`✓ ${e}`))}}}const O={debug:`gray`,error:`red`,fatal:`red`,info:`green`,trace:`gray`,warn:`yellow`};function k(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 A(e){let t=e.toLowerCase(),n=e.toUpperCase().padEnd(5),r=O[t]??`green`;return m()[r](n)}function j(e){let t=m(),n=[];return e.timestamp!==void 0&&n.push(t.gray(k(e.timestamp))),n.push(A(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 M(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function N(e,t=``){let n={};for(let[r,i]of Object.entries(e)){let e=t===``?r:`${t}.${r}`;M(i)?Object.assign(n,N(i,e)):n[e]=String(i??``)}return n}var P=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`);return JSON.parse(e)}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?!1:(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 F(e){return`${e}_${Date.now().toString(36)}_${Math.random().toString(36).slice(2,8)}`}const I=e(`@longzai-intelligence-cli/core/define-command`);function L(e,n){let r=e.command(n.name);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(`, `);I.error(m().red(`参数校验失败: ${e}`)),p().log.error(`参数校验失败: ${e}`),process.exit(1)}await n.action(o.data,a)})}export{P as JsonStorage,v as OutputFormatter,S as confirm,g as createCli,L as defineCommand,N as flattenObject,A as formatLevel,j as formatLogEntry,k as formatTimestamp,F as generateId,h as getCliVersion,m as getColorProvider,p as getInteractionProvider,T as log,w as note,y as parseOutputFormat,D as progressBar,b as select,f as setColorProvider,d as setInteractionProvider,C as spinner,x as textInput};
3
+ `),e&&D.info(h().green(`✓ ${e}`))}}}const k={debug:`gray`,error:`red`,fatal:`red`,info:`green`,trace:`gray`,warn:`yellow`};function A(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 j(e){let t=e.toLowerCase(),n=e.toUpperCase().padEnd(5),r=k[t]??`green`;return h()[r](n)}function M(e){let t=h(),n=[];return e.timestamp!==void 0&&n.push(t.gray(A(e.timestamp))),n.push(j(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 N(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function P(e,t=``){let n={};for(let[r,i]of Object.entries(e)){let e=t===``?r:`${t}.${r}`;N(i)?Object.assign(n,P(i,e)):n[e]=String(i??``)}return n}const F=s.array(s.unknown());function I(e){return F.safeParse(e).success}var L=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 I(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?!1:(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 R(e){return`${e}_${Date.now().toString(36)}_${Math.random().toString(36).slice(2,8)}`}const z=e(`@longzai-intelligence-cli/core/define-command`);function B(e,t){let n=e.commands.find(e=>e.name()===t);return n===void 0?e.command(t):n}function V(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=B(e,n);for(let e of r)a=B(a,e);return a.command(i)}function H(e,n){let r=V(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(`, `);z.error(h().red(`参数校验失败: ${e}`)),m().log.error(`参数校验失败: ${e}`),process.exit(1)}await n.action(o.data,a)})}export{L as JsonStorage,y as OutputFormatter,C as confirm,_ as createCli,H as defineCommand,P as flattenObject,j as formatLevel,M as formatLogEntry,A as formatTimestamp,R as generateId,g as getCliVersion,h as getColorProvider,m as getInteractionProvider,E as log,T as note,b as parseOutputFormat,O as progressBar,B as resolveCommandParent,x as select,p as setColorProvider,f as setInteractionProvider,w as spinner,S as textInput};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@longzai-intelligence-cli/core",
3
- "version": "0.0.8",
3
+ "version": "0.0.10",
4
4
  "private": false,
5
5
  "keywords": [
6
6
  "cli",