@done-coding/cli-utils 0.8.2-alpha.1 → 0.8.3-alpha.0

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.
Files changed (3) hide show
  1. package/es/index.mjs +500 -563
  2. package/package.json +11 -10
  3. package/types/index.d.ts +101 -135
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@done-coding/cli-utils",
3
- "version": "0.8.2-alpha.1",
3
+ "version": "0.8.3-alpha.0",
4
4
  "description": "cli utils",
5
5
  "private": false,
6
6
  "module": "es/index.mjs",
@@ -18,10 +18,7 @@
18
18
  "types"
19
19
  ],
20
20
  "scripts": {
21
- "clean": "rimraf es lib types",
22
- "predev": "pnpm run clean",
23
- "dev": "vite build --watch",
24
- "prebuild": "pnpm run clean",
21
+ "dev": "vite build -w -m hotBuild",
25
22
  "build": "vite build",
26
23
  "prepack": "pnpm build"
27
24
  },
@@ -47,26 +44,30 @@
47
44
  "@types/pinyin": "^2.10.0",
48
45
  "@types/prompts": "^2.4.6",
49
46
  "@types/semver": "^7.5.3",
47
+ "@types/signal-exit": "^4.0.0",
50
48
  "@types/yargs": "^17.0.28",
51
- "rimraf": "^6.0.1",
52
49
  "typescript": "^5.8.3",
53
50
  "vite": "^4.4.11",
54
51
  "vite-plugin-dts": "^3.6.0"
55
52
  },
56
- "engines": {
57
- "node": ">=18.0.0"
58
- },
59
53
  "dependencies": {
54
+ "@done-coding/output-node": "0.1.1",
60
55
  "chalk": "^5.3.0",
56
+ "dayjs": "^1.11.19",
61
57
  "json5": "^2.2.3",
62
58
  "lodash.curry": "^4.1.1",
63
59
  "lodash.get": "^4.4.2",
64
60
  "lodash.merge": "^4.6.2",
65
61
  "lodash.set": "^4.3.2",
62
+ "pino": "8.17.2",
66
63
  "pinyin": "^2.11.2",
67
64
  "prompts": "^2.4.2",
68
65
  "semver": "^7.5.4",
66
+ "signal-exit": "4.1.0",
69
67
  "yargs": "^17.7.2"
70
68
  },
71
- "gitHead": "660e39fc523e4eba1ea621e3c59122f98015a2de"
69
+ "engines": {
70
+ "node": ">=18.0.0"
71
+ },
72
+ "gitHead": "906b7683d9e4dc75fb07806b12e5507827122a16"
72
73
  }
package/types/index.d.ts CHANGED
@@ -1,10 +1,13 @@
1
1
  import type { ArgumentsCamelCase } from 'yargs';
2
+ import chalk from 'chalk';
2
3
  import type { CommandModule } from 'yargs';
3
4
  import _curry from 'lodash.curry';
4
- import { ExecSyncOptions } from 'node:child_process';
5
- import fs from 'node:fs';
5
+ import dayjs from 'dayjs';
6
6
  import _get from 'lodash.get';
7
7
  import json5 from 'json5';
8
+ import { OutputConsole } from '@done-coding/output-node';
9
+ import { OutputConsoleTypeEnum } from '@done-coding/output-node';
10
+ import { OutputLogFile } from '@done-coding/output-node';
8
11
  import { Answers as PromptAnswers } from 'prompts';
9
12
  import { Choice as PromptChoice } from 'prompts';
10
13
  import { Falsy as PromptFalsy } from 'prompts';
@@ -16,7 +19,6 @@ import prompts from 'prompts';
16
19
  import { PromptType } from 'prompts';
17
20
  import { ValueOrFunc as PromptValueOrFunc } from 'prompts';
18
21
  import _set from 'lodash.set';
19
- import type { WriteStream } from 'node:fs';
20
22
  import yargs from 'yargs';
21
23
  import type { Argv as YargsArgv } from 'yargs';
22
24
  import type { Options as YargsOptions } from 'yargs';
@@ -36,9 +38,6 @@ export declare const addPackageConfig: ({ patchConfig, rootDir, }: {
36
38
  rootDir: string;
37
39
  }) => void;
38
40
 
39
- /** 允许输出日志到控制台 */
40
- export declare const allowConsoleLog: () => boolean;
41
-
42
41
  /**
43
42
  * 申请使用临时目录
44
43
  * ---
@@ -66,6 +65,8 @@ assetPath: string) => boolean;
66
65
  */
67
66
  export declare const assetIsExitsAsync: (path: string) => Promise<boolean>;
68
67
 
68
+ export { chalk }
69
+
69
70
  /** 检测当前正在变基 */
70
71
  export declare const checkCurrentIsRebasing: (rootDir: string) => boolean;
71
72
 
@@ -122,12 +123,17 @@ export declare const createSubcommand: (cliInfo: SubCliInfo) => CommandModule;
122
123
 
123
124
  export { _curry }
124
125
 
126
+ export { dayjs }
127
+
125
128
  /** AES 解密 */
126
129
  export declare function decryptAES({ encryptedText, secretKey, }: {
127
130
  encryptedText: string;
128
131
  secretKey: string;
129
132
  }): string;
130
133
 
134
+ /** done-coding 当前进程日志文件名symbol */
135
+ declare const DONE_CODING_CURRENT_LOG_FILE_NAME_SYMBOL: unique symbol;
136
+
131
137
  /** done-coding 全局环境配置symbol */
132
138
  declare const DONE_CONFIG_ENV_CONFIG_GLOBAL_SYMBOL: unique symbol;
133
139
 
@@ -171,16 +177,19 @@ export declare function encryptAES({ text, secretKey, }: {
171
177
  * !!! 不作为主要的通信方式
172
178
  */
173
179
  export declare interface EnvConfig {
174
- /** 调用模式 */
175
- callMode: EnvConfigCallModeEnum;
176
180
  /** 系列
177
181
  * ----
178
182
  * 规划的系列 会有 cli 、server等
179
183
  * 默认会是 `${DONE_CODING_SERIES_DEFAULT}`
180
184
  */
181
185
  series: string;
182
- /** 是否允许日志输出到控制台 */
183
- consoleLog: boolean;
186
+ /**
187
+ * 是否允许日志输出到控制台
188
+ * ---
189
+ * boolean 类型 表示是否允许所有类型日志输出到控制台
190
+ * array 类型 表示允许的日志类型
191
+ */
192
+ consoleLog: boolean | OutputConsoleTypeEnum[];
184
193
  /** 日志输出路径 */
185
194
  logOutputDir: string;
186
195
  /**
@@ -189,12 +198,16 @@ export declare interface EnvConfig {
189
198
  * 新进程的日志从左侧进栈
190
199
  */
191
200
  processLogFileNameList: string[];
201
+ /** 自身或祖先进程是否被劫持进程创建 */
202
+ processCreateByHijack: boolean;
203
+ /** 自身或祖先进程被劫持进程创建 行为预设信息 */
204
+ processCreateByHijackPresetInfo?: EnvConfigProcessCreateByHijackPresetInfo;
192
205
  }
193
206
 
194
- /** 环境配置 - 调用模式枚举 */
195
- export declare enum EnvConfigCallModeEnum {
196
- DEFAULT = "DEFAULT",
197
- MCP = "MCP"
207
+ /** 自身或祖先进程被劫持进程创建 行为预设信息 */
208
+ export declare interface EnvConfigProcessCreateByHijackPresetInfo {
209
+ /** 开始等待用户输入前退出 */
210
+ beforeInputExit?: boolean;
198
211
  }
199
212
 
200
213
  /**
@@ -207,52 +220,42 @@ export declare enum EnvConfigProcessKeyEnum {
207
220
  GLOBAL_CONFIG_IMAGE = "GLOBAL_CONFIG_IMAGE"
208
221
  }
209
222
 
210
- /**
211
- * 工业级同步执行分发日志 (2026 稳定版)
212
- */
213
- export declare const execSyncWithLogDispatch: (command: string, options?: ExecSyncOptions) => string | Buffer;
214
-
215
223
  /** 文件添加执行权限 */
216
224
  export declare const fileAddX: (filePath: string) => void;
217
225
 
218
- /** 格式化日志流写入格式 */
219
- export declare const formatLogSteamWrite: ({ stream, type, content, }: {
220
- /** 流类型 */
221
- stream: WriteStream;
222
- /** 日志类型 */
223
- type: LogTypeEnum;
224
- /** 日志内容 */
225
- content: string;
226
- }) => boolean;
226
+ /** 生成 获取答案的快捷函数 */
227
+ export declare const generateGetAnswerSwiftFn: ({ presetAnswer, }: Pick<GetAnswerOptions<unknown, string>, "presetAnswer">) => <V = unknown, T extends string = string>(key: T,
228
+ /** 表单问询配置 */
229
+ questionConfig?: Parameters<typeof prompts<T>>[0],
230
+ /** 默认值 */
231
+ defaultValue?: V) => Promise<V | undefined>;
227
232
 
228
233
  export { _get }
229
234
 
230
- /** 快捷获取答案 */
231
- export declare const getAnswerSwift: <V = unknown, T extends string = string>(key: T,
232
- /** 表单问询配置 */
233
- questionConfig: Parameters<typeof prompts<T>>[0]) => Promise<V>;
234
-
235
235
  /**
236
236
  * 获取答案 考虑mcp情况
237
237
  * ----
238
238
  * mcp 只拿预设值,非mcp优先拿默认值
239
239
  * 有预设值的场景: MCP
240
240
  */
241
- export declare const getAnswerWithMCP: <V = unknown, T extends string = string>({ isMCP, key, presetAnswer, defaultValue, questionConfig, }: {
242
- /** 是否mcp场景 */
243
- isMCP: boolean;
241
+ export declare const getAnswer: <V = unknown, T extends string = string>({ key, presetAnswer, defaultValue, questionConfig, }: GetAnswerOptions<V, T>) => GetAnswerResult<V, T, typeof questionConfig>;
242
+
243
+ /** 获取答案 考虑mcp情况 的选项 */
244
+ export declare interface GetAnswerOptions<V, T extends string> {
244
245
  /** 表单key */
245
246
  key: T;
246
247
  /** 预设答案所在的对象 */
247
- presetAnswer?: object & { [K in T]: any; };
248
+ presetAnswer?: object & {
249
+ [K in T]?: any;
250
+ };
248
251
  /** 默认值 */
249
252
  defaultValue?: V;
250
253
  /** 表单问询配置 */
251
- questionConfig: Parameters<typeof prompts<T>>[0];
252
- }) => Promise<V>;
254
+ questionConfig?: Parameters<typeof prompts<T>>[0];
255
+ }
253
256
 
254
- /** 获取调用模式 */
255
- export declare const getCallMode: () => EnvConfigCallModeEnum;
257
+ /** 获取答案结果类型 */
258
+ export declare type GetAnswerResult<V, T extends string, Q extends GetAnswerOptions<V, T>["questionConfig"]> = Promise<Q extends undefined ? V | undefined : V>;
256
259
 
257
260
  /** 获取cli模块【临时】目录[绝对路径] */
258
261
  export declare const getCliModuleTempDir: (moduleName: string) => string;
@@ -279,7 +282,7 @@ export declare const getCurrentBranchLastCommitList: ({ count, }?: {
279
282
  /** 获取当前分支名 */
280
283
  export declare const getCurrentBranchName: () => string | undefined;
281
284
 
282
- /** 获取自身进程日志文件名 */
285
+ /** 获取当前进程日志文件名 */
283
286
  export declare const getCurrentProcessLogFileName: () => string;
284
287
 
285
288
  /** 获取编辑器类型 */
@@ -325,32 +328,6 @@ export declare const getLastReflogList: ({ count, filterItem, }?: {
325
328
  */
326
329
  export declare const getLogOutputDir: (persistent?: boolean) => string;
327
330
 
328
- /** 获取输出文字 */
329
- export declare const getLogText: ((type: LogTypeEnum, ...messages: unknown[]) => string) & {
330
- /** 系统 */
331
- system: (...messages: unknown[]) => string;
332
- /** 成功 */
333
- success: (...messages: unknown[]) => string;
334
- /** /步骤 */
335
- stage: (...messages: unknown[]) => string;
336
- /** 提示信息 */
337
- info: (...messages: unknown[]) => string;
338
- /** 警告 */
339
- warn: (...messages: unknown[]) => string;
340
- /** 错误 */
341
- error: (...messages: unknown[]) => string;
342
- /** 跳过 */
343
- skip: (...messages: unknown[]) => string;
344
- /** 表格 */
345
- table: (...messages: unknown[]) => string;
346
- };
347
-
348
- /** 格式: 2026-01-18 11:38:05 */
349
- export declare const getLogTime: () => string;
350
-
351
- /** 通过 LogTypeEnum 枚举值或者key */
352
- export declare const getLogTypeByValue: (value: LogTypeEnum) => string;
353
-
354
331
  /** 获取package.json文件内容 */
355
332
  export declare const getPackageJson: <R extends PackageJson>({ rootDir, }: {
356
333
  rootDir: string;
@@ -359,12 +336,12 @@ export declare const getPackageJson: <R extends PackageJson>({ rootDir, }: {
359
336
  /** 获取父级进程日志文件名 */
360
337
  export declare const getParentProcessLogFileName: () => string | undefined;
361
338
 
339
+ /** 获取自身或祖先进程被劫持进程创建 行为预设信息 */
340
+ export declare const getProcessCreateByHijackPresetInfo: () => EnvConfigProcessCreateByHijackPresetInfo | undefined;
341
+
362
342
  /** 获取环境变量 */
363
343
  export declare const getProcessEnv: <T>(keyInit: EnvConfigProcessKeyEnum, defaultValue?: T) => T | undefined;
364
344
 
365
- /** 获取当前进程对应的日志流 */
366
- export declare const getProcessLogStream: () => XFsWriteStream;
367
-
368
345
  /** 获取依赖包版本 */
369
346
  export declare const getRelyPkgVersion: <R extends PackageJson>({ rootDir, pkgJson, pkgName, isDevPkg, }: {
370
347
  rootDir: string;
@@ -539,6 +516,33 @@ export declare interface GitRemoteInfo {
539
516
  url?: string;
540
517
  }
541
518
 
519
+ /**
520
+ * 劫持子进程
521
+ * -----
522
+ * 用途:
523
+ * 如 mcp模式禁止控制台输出、process.exit等操作,需要shim进程拦截控制台输出及退出
524
+ * 如果mcp禁止输入 那么监听到开始等待用户输入事件后 那么直接中断子进程
525
+ */
526
+ export declare const hijackChildProcess: ({ command, args, env, cwd, beforeInputExit, }: HijackChildProcessOptions) => Promise<{
527
+ success: boolean;
528
+ code: number | null;
529
+ signal: NodeJS.Signals | null;
530
+ stdout: string;
531
+ stderr: string;
532
+ }>;
533
+
534
+ /** 劫持子进程选项 */
535
+ export declare interface HijackChildProcessOptions extends EnvConfigProcessCreateByHijackPresetInfo {
536
+ /** 命令 */
537
+ command: string;
538
+ /** 参数 */
539
+ args: string[];
540
+ /** 工作目录 */
541
+ cwd: string;
542
+ /** 环境变量 */
543
+ env: NodeJS.ProcessEnv;
544
+ }
545
+
542
546
  export declare enum HooksNameEnum {
543
547
  /** 预提交 */
544
548
  PRE_COMMIT = "pre-commit",
@@ -567,19 +571,6 @@ export declare const initConfigFile: <T>(content: T, argv: CliHandlerArgv<InitCo
567
571
  /** 初始化文件选项 */
568
572
  export declare type InitConfigFileOptions = ConfigFileCommonOptions;
569
573
 
570
- /**
571
- * 初始化环境配置
572
- * ---
573
- * !!! 顶级进程才调用且只能调用一次
574
- * 非顶级进程调用会忽略入参 即优先使用父级设置的进程配置
575
- * ---
576
- * 即顶级进程调用
577
- * 非顶级进程通过进程环境继承
578
- */
579
- export declare const initEnvConfig: ({ series, ...otherConfig }: Partial<Pick<EnvConfig, "callMode" | "consoleLog"> & {
580
- series: string;
581
- }>) => EnvConfig;
582
-
583
574
  /** 初始化配置文件通用处理器 */
584
575
  export declare const initHandlerCommon: <T>(content: T, argv: CliHandlerArgv<InitConfigFileOptions>, { onFileGenerated, edit, }?: {
585
576
  /** 文件已生成 */
@@ -590,55 +581,13 @@ export declare const initHandlerCommon: <T>(content: T, argv: CliHandlerArgv<Ini
590
581
  /** 是http git地址 */
591
582
  export declare const isHttpGitUrl: (url: string) => boolean;
592
583
 
593
- /** 是mcp模式 */
594
- export declare const isMcpMode: () => boolean;
595
-
596
584
  /** 是 ssh git地址 */
597
585
  export declare const isSshGitUrl: (url: string) => boolean;
598
586
 
599
587
  export { json5 }
600
588
 
601
- /** 日志 */
602
- export declare const log: ((type: LogTypeEnum, ...messages: unknown[]) => void) & {
603
- /** 系统 */
604
- system: (...messages: unknown[]) => void;
605
- /** 成功 */
606
- success: (...messages: unknown[]) => void;
607
- /** /步骤 */
608
- stage: (...messages: unknown[]) => void;
609
- /** 提示信息 */
610
- info: (...messages: unknown[]) => void;
611
- /** 警告 */
612
- warn: (...messages: unknown[]) => void;
613
- /** 错误 */
614
- error: (...messages: unknown[]) => void;
615
- /** 跳过 */
616
- skip: (...messages: unknown[]) => void;
617
- /** 表格 */
618
- table: (...messages: unknown[]) => void;
619
- };
620
-
621
- export declare type LogParams = [type: LogTypeEnum, ...messages: unknown[]];
622
-
623
- /** 日志类型 */
624
- export declare enum LogTypeEnum {
625
- /** 系统 */
626
- SYSTEM = "magenta",
627
- /** 成功 */
628
- SUCCESS = "greenBright",
629
- /** 步骤 */
630
- STAGE = "blue",
631
- /** 提示信息 */
632
- INFO = "white",
633
- /** 警告 */
634
- WARN = "yellow",
635
- /** 错误 */
636
- ERROR = "redBright",
637
- /** 跳过 */
638
- SKIP = "dim",
639
- /** ---- 表格 ---- */
640
- TABLE = "table"
641
- }
589
+ /** 日志文件输出实例 */
590
+ export declare const logger: OutputLogFile;
642
591
 
643
592
  /**
644
593
  * 查找目标文件或目录
@@ -653,6 +602,9 @@ target: string, { currentDir, isFindFarthest, }?: {
653
602
  /** 用编辑器打开文件 */
654
603
  export declare const openFileInEditor: (path: string, editorType: EditorTypeEnum) => void;
655
604
 
605
+ /** 控制台输出实例 */
606
+ export declare const outputConsole: OutputConsole;
607
+
656
608
  /** package.json文件内容 */
657
609
  export declare interface PackageJson {
658
610
  name: string;
@@ -665,9 +617,20 @@ export declare interface PackageJson {
665
617
  peerDependencies?: Record<string, string>;
666
618
  }
667
619
 
620
+ /**
621
+ * 参数转cli参数
622
+ * -----
623
+ * yargs 参数格式:
624
+ * --key=value
625
+ */
626
+ export declare const params2cliParams: (params: Record<string, any>) => string[];
627
+
668
628
  /** 路径是否安全 */
669
629
  export declare const pathIsSafe: (path?: string) => boolean;
670
630
 
631
+ /** 是否被劫持进程创建 */
632
+ export declare const processIsHijacked: () => boolean;
633
+
671
634
  /** 进程值变量初始值 */
672
635
  export declare interface ProcessValueInit<T> {
673
636
  value: T;
@@ -794,17 +757,20 @@ export declare const SUPPORT_GET_COMMIT_BY_HOOKS_NAMES: readonly [HooksNameEnum.
794
757
 
795
758
  export declare type SupportGetCommitByHookName = (typeof SUPPORT_GET_COMMIT_BY_HOOKS_NAMES)[number];
796
759
 
797
- export declare const uuidv4: () => `${string}-${string}-${string}-${string}-${string}`;
798
-
799
760
  /**
800
- * fs.WriteStream 确实没有直接声明 fd 属性(虽然运行时它确实存在)。这是因为 fd 是由底层的物理文件句柄分配的,其类型定义在内部较为隐蔽。
761
+ * 更新环境配置
762
+ * ---
763
+ * 可以多次调用 不限制进程层级
801
764
  */
802
- declare interface XFsWriteStream extends fs.WriteStream {
803
- fd?: number;
804
- }
765
+ export declare const updateEnvConfig: ({ series, consoleLog, }: Partial<Pick<EnvConfig, "consoleLog" | "series">>) => EnvConfig;
766
+
767
+ export declare const uuidv4: () => `${string}-${string}-${string}-${string}-${string}`;
805
768
 
806
769
  export declare interface XGlobalThis {
807
- [DONE_CONFIG_ENV_CONFIG_GLOBAL_SYMBOL]: EnvConfig;
770
+ /** 全局配置 */
771
+ [DONE_CONFIG_ENV_CONFIG_GLOBAL_SYMBOL]?: EnvConfig;
772
+ /** 当前进程日志文件名 */
773
+ [DONE_CODING_CURRENT_LOG_FILE_NAME_SYMBOL]?: string;
808
774
  }
809
775
 
810
776
  /** prompts 拓展 */