@longzai-intelligence-cli/core 0.0.5 → 0.0.7

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
@@ -169,13 +169,25 @@ type ColorProvider = {
169
169
  */
170
170
  blue: (text: string) => string;
171
171
  /**
172
- * 加粗文本
172
+ * 青色文本
173
173
  */
174
- bold: (text: string) => string;
174
+ cyan: (text: string) => string;
175
+ /**
176
+ * 品红文本
177
+ */
178
+ magenta: (text: string) => string;
175
179
  /**
176
180
  * 灰色文本
177
181
  */
178
182
  gray: (text: string) => string;
183
+ /**
184
+ * 加粗文本
185
+ */
186
+ bold: (text: string) => string;
187
+ /**
188
+ * 暗淡文本(降低亮度)
189
+ */
190
+ dim: (text: string) => string;
179
191
  };
180
192
  /**
181
193
  * 进度条控制器(交互无关、平台无关能力,core 直接提供实现)
@@ -465,6 +477,90 @@ declare const log: {
465
477
  */
466
478
  declare function progressBar(total?: number): ProgressController;
467
479
  //#endregion
480
+ //#region src/log-format.d.ts
481
+ /**
482
+ * 日志格式化能力
483
+ *
484
+ * 提供日志条目的通用格式化能力:时间戳格式化、日志级别着色、
485
+ * JSON Lines 条目 pretty-print、嵌套对象扁平化。
486
+ *
487
+ * 这些能力由迁移 observability 时回补(ADR-0049 §4.6 能力回补原则),
488
+ * 属于日志/监控类 CLI 的通用需求。
489
+ */
490
+ /**
491
+ * 支持的日志级别
492
+ */
493
+ type LogLevel = 'trace' | 'debug' | 'info' | 'warn' | 'error' | 'fatal';
494
+ /**
495
+ * 日志条目字段(formatLogEntry 的输入)
496
+ */
497
+ type LogEntry = {
498
+ /**
499
+ * ISO 时间戳
500
+ */
501
+ timestamp?: string;
502
+ /**
503
+ * 日志级别
504
+ */
505
+ level?: string;
506
+ /**
507
+ * 日志消息
508
+ */
509
+ message?: string;
510
+ /**
511
+ * 服务名称
512
+ */
513
+ serviceName?: string;
514
+ /**
515
+ * 元数据(任意键值对)
516
+ */
517
+ metadata?: Record<string, unknown>;
518
+ /**
519
+ * 其他字段
520
+ */
521
+ [key: string]: unknown;
522
+ };
523
+ /**
524
+ * 格式化时间戳为可读字符串
525
+ *
526
+ * 将 ISO 时间戳转换为本地化(zh-CN)的可读格式。
527
+ * 解析失败时返回原始字符串。
528
+ *
529
+ * @param timestamp - ISO 时间戳字符串
530
+ * @returns 格式化后的时间字符串
531
+ */
532
+ declare function formatTimestamp(timestamp: string): string;
533
+ /**
534
+ * 格式化日志级别标签
535
+ *
536
+ * 将级别名称大写并右填充到固定宽度,按级别着色(读取当前 ColorProvider)。
537
+ *
538
+ * @param level - 日志级别(原始大小写均可)
539
+ * @returns 带颜色的级别标签
540
+ */
541
+ declare function formatLevel(level: string): string;
542
+ /**
543
+ * 将日志条目格式化为 Pretty Print 单行
544
+ *
545
+ * 组装"时间戳 级别 [服务名] 消息 {元数据}"格式,
546
+ * 各部分按级别/语义着色(读取当前 ColorProvider)。
547
+ *
548
+ * @param entry - 日志条目
549
+ * @returns 格式化后的字符串
550
+ */
551
+ declare function formatLogEntry(entry: LogEntry): string;
552
+ /**
553
+ * 扁平化嵌套对象为点号分隔键值对
554
+ *
555
+ * 用于 CSV 导出等场景,将 `{ user: { name: "x" } }` 转为 `{ "user.name": "x" }`。
556
+ * null/undefined 转为空字符串,数组转为逗号分隔字符串。
557
+ *
558
+ * @param obj - 待扁平化对象
559
+ * @param prefix - 键前缀(递归用)
560
+ * @returns 扁平化后的键值对(所有值为 string)
561
+ */
562
+ declare function flattenObject(obj: Record<string, unknown>, prefix?: string): Record<string, string>;
563
+ //#endregion
468
564
  //#region src/define-command.d.ts
469
565
  /**
470
566
  * 选项声明(commander 选项签名 + 是否带默认值)
@@ -569,4 +665,4 @@ type CommandSpec<T extends z.ZodType> = {
569
665
  */
570
666
  declare function defineCommand<T extends z.ZodType>(program: Command$1, spec: CommandSpec<T>): void;
571
667
  //#endregion
572
- export { type ColorProvider, type Command, type CommandSpec, type ConfirmOptions, type CreateCliOptions, type InteractionProvider, type LogToolset, type OptionDecl, type OutputFormat, OutputFormatter, type ProgressController, type SelectOption, type SpinnerController, type TextInputOptions, confirm, createCli, defineCommand, getCliVersion, getColorProvider, getInteractionProvider, log, note, parseOutputFormat, progressBar, select, setColorProvider, setInteractionProvider, spinner, textInput };
668
+ export { type ColorProvider, type Command, type CommandSpec, type ConfirmOptions, type CreateCliOptions, type InteractionProvider, 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, getCliVersion, getColorProvider, getInteractionProvider, log, note, parseOutputFormat, progressBar, 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"node:fs";import"node:path";import"node:url";const n=e(`@longzai-intelligence-cli/core/provider`),r={red:e=>e,green:e=>e,yellow:e=>e,blue:e=>e,bold:e=>e,gray:e=>e};let i={select:async(e,t)=>t[0]?.value??``,textInput:async(e,t)=>t?.defaultValue??``,confirm:async(e,t)=>t?.defaultValue??!1,spinner:()=>({start:e=>n.info(e),stop:e=>n.info(e)}),note:(e,t)=>{t?n.info(`${t}: ${e}`):n.info(e)},log:{info:e=>n.info(e),success:e=>n.info(e),warn:e=>n.warn(e),error:e=>n.error(e),step:e=>n.info(e)}},a=r;function o(e){i=e}function s(e){a=e}function c(){return i}function l(){return a}const u=()=>`0.0.5`;function d(e){let n=e.version??u();e.interaction&&o(e.interaction),e.color&&s(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 f=e(`@longzai-intelligence-cli/core/output`);var p=class{format;constructor(e=`text`){this.format=e}get colors(){return l()}success(e,t){this.format===`json`?f.info(JSON.stringify({success:!0,data:e},null,2)):f.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)};f.info(JSON.stringify({success:!1,error:t},null,2))}else{let t=e instanceof Error?e.message:String(e);f.error(this.colors.red(`错误: ${t}`))}}info(e){this.format===`json`?f.info(JSON.stringify({success:!0,message:e},null,2)):f.info(this.colors.blue(e))}warn(e){this.format===`json`?f.info(JSON.stringify({success:!0,warning:e},null,2)):f.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});f.info(JSON.stringify({success:!0,data:n},null,2))}else{let n=e.map((e,n)=>Math.max(e.length,...t.map(e=>(e[n]??``).length)));f.info(e.map((e,t)=>this.colors.bold(e.padEnd(n[t]??0))).join(` `)),f.info(n.map(e=>`-`.repeat(e??0)).join(` `));for(let e of t)f.info(e.map((e,t)=>(e??``).padEnd(n[t]??0)).join(` `))}}formatData(e){return typeof e==`string`?e:typeof e==`number`||typeof e==`boolean`?String(e):JSON.stringify(e,null,2)}};function m(e){return e===`json`?`json`:`text`}async function h(e,t){return c().select(e,t)}async function g(e,t){return c().textInput(e,t)}async function _(e,t){return c().confirm(e,t)}function v(){return c().spinner()}function y(e,t){c().note(e,t)}const b={info(e){c().log.info(e)},success(e){c().log.success(e)},warn(e){c().log.warn(e)},error(e){c().log.error(e)},step(e){c().log.step(e)}},x=e(`@longzai-intelligence-cli/core/progress`);function S(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${l().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"node:fs";import"node:path";import"node:url";const n=e(`@longzai-intelligence-cli/core/provider`),r={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 i={select:async(e,t)=>t[0]?.value??``,textInput:async(e,t)=>t?.defaultValue??``,confirm:async(e,t)=>t?.defaultValue??!1,spinner:()=>({start:e=>n.info(e),stop:e=>n.info(e)}),note:(e,t)=>{t?n.info(`${t}: ${e}`):n.info(e)},log:{info:e=>n.info(e),success:e=>n.info(e),warn:e=>n.warn(e),error:e=>n.error(e),step:e=>n.info(e)}},a=r;function o(e){i=e}function s(e){a=e}function c(){return i}function l(){return a}const u=()=>`0.0.7`;function d(e){let n=e.version??u();e.interaction&&o(e.interaction),e.color&&s(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 f=e(`@longzai-intelligence-cli/core/output`);var p=class{format;constructor(e=`text`){this.format=e}get colors(){return l()}success(e,t){this.format===`json`?f.info(JSON.stringify({success:!0,data:e},null,2)):f.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)};f.info(JSON.stringify({success:!1,error:t},null,2))}else{let t=e instanceof Error?e.message:String(e);f.error(this.colors.red(`错误: ${t}`))}}info(e){this.format===`json`?f.info(JSON.stringify({success:!0,message:e},null,2)):f.info(this.colors.blue(e))}warn(e){this.format===`json`?f.info(JSON.stringify({success:!0,warning:e},null,2)):f.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});f.info(JSON.stringify({success:!0,data:n},null,2))}else{let n=e.map((e,n)=>Math.max(e.length,...t.map(e=>(e[n]??``).length)));f.info(e.map((e,t)=>this.colors.bold(e.padEnd(n[t]??0))).join(` `)),f.info(n.map(e=>`-`.repeat(e??0)).join(` `));for(let e of t)f.info(e.map((e,t)=>(e??``).padEnd(n[t]??0)).join(` `))}}formatData(e){return typeof e==`string`?e:typeof e==`number`||typeof e==`boolean`?String(e):JSON.stringify(e,null,2)}};function m(e){return e===`json`?`json`:`text`}async function h(e,t){return c().select(e,t)}async function g(e,t){return c().textInput(e,t)}async function _(e,t){return c().confirm(e,t)}function v(){return c().spinner()}function y(e,t){c().note(e,t)}const b={info(e){c().log.info(e)},success(e){c().log.success(e)},warn(e){c().log.warn(e)},error(e){c().log.error(e)},step(e){c().log.step(e)}},x=e(`@longzai-intelligence-cli/core/progress`);function S(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${l().blue(a)} ${r.toFixed(0)}%${i}`),r>=100&&process.stdout.write(`
2
2
  `)}},done(e){process.stdout.write(`
3
- `),e&&x.info(l().green(`✓ ${e}`))}}}const C=e(`@longzai-intelligence-cli/core/define-command`);function w(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(`, `);C.error(l().red(`参数校验失败: ${e}`)),c().log.error(`参数校验失败: ${e}`),process.exit(1)}await n.action(o.data,a)})}export{p as OutputFormatter,_ as confirm,d as createCli,w as defineCommand,u as getCliVersion,l as getColorProvider,c as getInteractionProvider,b as log,y as note,m as parseOutputFormat,S as progressBar,h as select,s as setColorProvider,o as setInteractionProvider,v as spinner,g as textInput};
3
+ `),e&&x.info(l().green(`✓ ${e}`))}}}const C={debug:`gray`,error:`red`,fatal:`red`,info:`green`,trace:`gray`,warn:`yellow`};function w(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 T(e){let t=e.toLowerCase(),n=e.toUpperCase().padEnd(5),r=C[t]??`green`;return l()[r](n)}function E(e){let t=l(),n=[];return e.timestamp!==void 0&&n.push(t.gray(w(e.timestamp))),n.push(T(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 D(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function O(e,t=``){let n={};for(let[r,i]of Object.entries(e)){let e=t===``?r:`${t}.${r}`;D(i)?Object.assign(n,O(i,e)):n[e]=String(i??``)}return n}const k=e(`@longzai-intelligence-cli/core/define-command`);function A(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(`, `);k.error(l().red(`参数校验失败: ${e}`)),c().log.error(`参数校验失败: ${e}`),process.exit(1)}await n.action(o.data,a)})}export{p as OutputFormatter,_ as confirm,d as createCli,A as defineCommand,O as flattenObject,T as formatLevel,E as formatLogEntry,w as formatTimestamp,u as getCliVersion,l as getColorProvider,c as getInteractionProvider,b as log,y as note,m as parseOutputFormat,S as progressBar,h as select,s as setColorProvider,o as setInteractionProvider,v as spinner,g as textInput};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@longzai-intelligence-cli/core",
3
- "version": "0.0.5",
3
+ "version": "0.0.7",
4
4
  "private": false,
5
5
  "keywords": [
6
6
  "cli",