maoda-commander-tt 0.0.4 → 0.0.6

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/main.js CHANGED
@@ -813,7 +813,9 @@ async function searchLogCn(options) {
813
813
  if (!detailResult.ok) {
814
814
  return detailResult;
815
815
  }
816
- const payload = parseDetailPayload(detailResult.value.spans?.[0]?.input);
816
+ const payload = parseDetailPayload(
817
+ detailResult.value.spans?.[0]?.input
818
+ );
817
819
  if (!payload.ok) {
818
820
  return payload;
819
821
  }
@@ -907,8 +909,21 @@ async function searchLogI18n(options) {
907
909
  }
908
910
 
909
911
  // src/commands/pippit/modules/search-log/search-log.ts
912
+ function trimFornaxMessages(data) {
913
+ if (!Array.isArray(data.messages)) {
914
+ return;
915
+ }
916
+ for (const message of data.messages) {
917
+ if (message === null || typeof message !== "object") {
918
+ continue;
919
+ }
920
+ if (Object.prototype.hasOwnProperty.call(message, "metadata")) {
921
+ void Reflect.deleteProperty(message, "metadata");
922
+ }
923
+ }
924
+ }
910
925
  async function searchLog(options) {
911
- const { logId, region } = options;
926
+ const { logId, region, trim = true } = options;
912
927
  if (!logId) {
913
928
  return missingLogIdError();
914
929
  }
@@ -916,9 +931,17 @@ async function searchLog(options) {
916
931
  return missingRegionError();
917
932
  }
918
933
  if (region === "cn" /* CN */) {
919
- return searchLogCn({ logId, region });
934
+ const result2 = await searchLogCn({ logId, region });
935
+ if (result2.ok && trim) {
936
+ trimFornaxMessages(result2.value.data);
937
+ }
938
+ return result2;
939
+ }
940
+ const result = await searchLogI18n({ logId, region });
941
+ if (result.ok && trim) {
942
+ trimFornaxMessages(result.value.data);
920
943
  }
921
- return searchLogI18n({ logId, region });
944
+ return result;
922
945
  }
923
946
 
924
947
  // src/commands/pippit/pippit-search-fornax-log-command.ts
@@ -950,6 +973,112 @@ var PippitSearchFornaxLogCommand = class extends BaseCommand {
950
973
  }
951
974
  };
952
975
 
976
+ // src/commands/pippit/pippit-save-thread-fornax-command.ts
977
+ import * as fs3 from "fs/promises";
978
+ import * as path3 from "path";
979
+ import { Option as Option4 } from "commander";
980
+ var PippitSaveThreadFornaxCommand = class extends BaseCommand {
981
+ _meta() {
982
+ return {
983
+ name: "save",
984
+ description: "\u83B7\u53D6 thread \u548C fornax \u5E76\u4FDD\u5B58\u5230\u672C\u5730"
985
+ };
986
+ }
987
+ _configureArguments(cmd) {
988
+ cmd.argument("<thread_id>", "\u8981\u83B7\u53D6\u5E76\u4FDD\u5B58\u7684 thread id");
989
+ }
990
+ _configureOptions(cmd) {
991
+ cmd.addOption(
992
+ new Option4("-o, --output-dir <dir>", "\u4FDD\u5B58\u76EE\u5F55\uFF0C\u7F3A\u7701\u65F6\u4F7F\u7528\u5F53\u524D\u5DE5\u4F5C\u76EE\u5F55")
993
+ );
994
+ }
995
+ async _execute(ctx) {
996
+ const threadId = ctx.args[0];
997
+ const outputDir = ctx.options.outputDir;
998
+ const threadResult = await getThread({ threadId, trim: true });
999
+ if (!threadResult.ok) {
1000
+ return this._emitJsonError(threadResult.code, threadResult.msg);
1001
+ }
1002
+ const threadData = threadResult.value.thread;
1003
+ const region = threadResult.value.region;
1004
+ const logId = this._extractExecuteLogId(threadData);
1005
+ if (!logId) {
1006
+ return this._emitJsonError(
1007
+ 1,
1008
+ "\u672A\u627E\u5230 thread \u4E2D\u53EF\u7528\u4E8E\u67E5\u8BE2 fornax \u7684 execute_log_id\u3002"
1009
+ );
1010
+ }
1011
+ const fornaxResult = await searchLog({ logId, region });
1012
+ if (!fornaxResult.ok) {
1013
+ return this._emitJsonError(fornaxResult.code, fornaxResult.msg);
1014
+ }
1015
+ const targetDir = this._resolveTargetDir(threadId, outputDir);
1016
+ const threadPath = path3.join(targetDir, "thread.json");
1017
+ const fornaxPath = path3.join(targetDir, "fornax.json");
1018
+ try {
1019
+ await fs3.mkdir(targetDir, { recursive: true });
1020
+ await fs3.writeFile(
1021
+ threadPath,
1022
+ `${JSON.stringify(threadData, null, 2)}
1023
+ `,
1024
+ "utf8"
1025
+ );
1026
+ await fs3.writeFile(
1027
+ fornaxPath,
1028
+ `${JSON.stringify(fornaxResult.value.data, null, 2)}
1029
+ `,
1030
+ "utf8"
1031
+ );
1032
+ } catch (error) {
1033
+ const message = error instanceof Error ? error.message : String(error);
1034
+ return this._emitJsonError(1, `\u5199\u5165\u6587\u4EF6\u5931\u8D25: ${message}`);
1035
+ }
1036
+ this._outputJsonOk({
1037
+ thread_id: threadId,
1038
+ output_dir: targetDir,
1039
+ files: {
1040
+ thread: threadPath,
1041
+ fornax: fornaxPath
1042
+ }
1043
+ });
1044
+ return this._makeOk();
1045
+ }
1046
+ _emitJsonError(code, msg) {
1047
+ this._outputJsonError(code, msg);
1048
+ process.exitCode = 1;
1049
+ return this._makeOk();
1050
+ }
1051
+ _resolveTargetDir(threadId, outputDir) {
1052
+ const baseDir = outputDir ? path3.resolve(process.cwd(), outputDir) : process.cwd();
1053
+ return path3.join(baseDir, threadId);
1054
+ }
1055
+ _extractExecuteLogId(thread) {
1056
+ const lastRun = thread.run_list.at(-1);
1057
+ if (!lastRun) {
1058
+ return void 0;
1059
+ }
1060
+ if (typeof lastRun.execute_log_id === "string") {
1061
+ const executeLogId = lastRun.execute_log_id.trim();
1062
+ if (executeLogId.length > 0) {
1063
+ return executeLogId;
1064
+ }
1065
+ }
1066
+ if (typeof lastRun.extra !== "string" || lastRun.extra.length === 0) {
1067
+ return void 0;
1068
+ }
1069
+ try {
1070
+ const extra = JSON.parse(lastRun.extra);
1071
+ if (typeof extra.execute_log_id !== "string") {
1072
+ return void 0;
1073
+ }
1074
+ const executeLogId = extra.execute_log_id.trim();
1075
+ return executeLogId.length > 0 ? executeLogId : void 0;
1076
+ } catch {
1077
+ return void 0;
1078
+ }
1079
+ }
1080
+ };
1081
+
953
1082
  // src/commands/pippit/pippit-command.ts
954
1083
  var PippitCommand = class extends BaseSubcommandHost {
955
1084
  _meta() {
@@ -963,6 +1092,7 @@ var PippitCommand = class extends BaseSubcommandHost {
963
1092
  this._addSubcommand(new PippitGetThreadCommand());
964
1093
  this._addSubcommand(new PippitFornaxTokenCommand());
965
1094
  this._addSubcommand(new PippitSearchFornaxLogCommand());
1095
+ this._addSubcommand(new PippitSaveThreadFornaxCommand());
966
1096
  }
967
1097
  };
968
1098
 
package/dist/main.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/main.ts","../src/commands/hello/hello-greet-command.ts","../src/commands/hello/hello-info-command.ts","../src/commands/hello/hello-command.ts","../src/commands/pippit/pippit-get-thread-command.ts","../src/commands/pippit/modules/get-thread/errors.ts","../src/commands/pippit/modules/get-thread/fetch-thread.ts","../src/commands/pippit/modules/get-thread/trim-thread.ts","../src/commands/pippit/modules/get-thread/get-thread.ts","../src/commands/pippit/pippit-fornax-token-command.ts","../src/bedrock/config/local-config.ts","../src/bedrock/pkg/find-closest-package-json.ts","../src/commands/pippit/modules/fornax-token/fornax-token.ts","../src/commands/pippit/pippit-search-fornax-log-command.ts","../src/commands/pippit/modules/search-log/errors.ts","../src/commands/pippit/modules/search-log/common.ts","../src/commands/pippit/modules/search-log/cn-search-log.ts","../src/commands/pippit/modules/search-log/i18n-search-log.ts","../src/commands/pippit/modules/search-log/search-log.ts","../src/commands/pippit/pippit-command.ts"],"sourcesContent":["#!/usr/bin/env node\n\nimport { createRequire } from \"node:module\";\nimport { CliApp } from \"./core\";\nimport { HelloCommand, PippitCommand } from \"./commands\";\n\nconst require = createRequire(import.meta.url);\nconst pkg = require(\"../package.json\");\n\n/**\n * 注:\n * option 里,boolean 的同时支持长、短选项,短的还可以合并,比如 -fr\n * option 里,字符串的,也同时支持长短,唯独短选项不支持=,只支持空格\n * 子命令,通常最多 3 层,比如 npm config set\n */\n\nasync function bootstrap(): Promise<void> {\n const binName = Object.keys(pkg.bin)[0];\n\n const app = new CliApp({\n name: binName,\n version: pkg.version,\n description: pkg.description,\n });\n\n app.registerCommand(new HelloCommand(), { hidden: true });\n app.registerCommand(new PippitCommand());\n\n const result = await app.run();\n\n if (!result.ok) {\n process.stderr.write(`Fatal: ${result.msg}\\n`);\n process.exitCode = 1;\n }\n\n app.dispose();\n}\n\nbootstrap();\n","import type { Command } from 'commander';\nimport { BaseCommand } from '../../core/base-command';\nimport type { ICommandActionContext } from '../../core/base-command';\nimport type { ICommandMeta } from '../../core/command-types';\nimport type { ILvErrorOr } from '../../bedrock/error';\n\ninterface IHelloGreetOptions {\n uppercase: boolean;\n}\n\nexport class HelloGreetCommand extends BaseCommand<IHelloGreetOptions> {\n protected _meta(): ICommandMeta {\n return {\n name: 'greet',\n description: '向指定用户打招呼',\n };\n }\n\n protected _configureArguments(cmd: Command): void {\n cmd.argument('[name]', '要打招呼的用户名', 'World');\n }\n\n protected _configureOptions(cmd: Command): void {\n cmd.option('-u, --uppercase', '将输出转为大写', false);\n }\n\n protected async _execute(\n ctx: ICommandActionContext<IHelloGreetOptions>,\n ): Promise<ILvErrorOr<void>> {\n const name = ctx.args[0] as string;\n const { uppercase } = ctx.options;\n\n let message = `Hello, ${name}!`;\n if (uppercase) {\n message = message.toUpperCase();\n }\n\n this._outputJsonOk({ message });\n return this._makeOk();\n }\n}\n","import { BaseCommand } from '../../core/base-command';\nimport type { ICommandActionContext } from '../../core/base-command';\nimport type { ICommandMeta } from '../../core/command-types';\nimport type { ILvErrorOr } from '../../bedrock/error';\n\nexport class HelloInfoCommand extends BaseCommand {\n protected _meta(): ICommandMeta {\n return {\n name: 'info',\n description: '显示 hello 命令的相关信息',\n };\n }\n\n protected async _execute(\n _ctx: ICommandActionContext,\n ): Promise<ILvErrorOr<void>> {\n this._outputJsonOk({\n version: '1.0.0',\n description: 'Hello 命令组 - 用于打招呼的示例命令',\n });\n return this._makeOk();\n }\n}\n","import type { ICommandMeta } from '../../core/command-types';\nimport { BaseSubcommandHost } from '../../core/base-subcommand-host';\nimport { HelloGreetCommand } from './hello-greet-command';\nimport { HelloInfoCommand } from './hello-info-command';\n\nexport class HelloCommand extends BaseSubcommandHost {\n protected _meta(): ICommandMeta {\n return {\n name: 'hello',\n description: '向指定用户打招呼 (示例命令组)',\n aliases: ['hi'],\n };\n }\n\n protected _registerSubcommands(): void {\n this._addSubcommand(new HelloGreetCommand());\n this._addSubcommand(new HelloInfoCommand());\n }\n}\n","import { BaseCommand } from \"../../core/base-command\";\nimport type { ICommandActionContext } from \"../../core/base-command\";\nimport type { ICommandMeta } from \"../../core/command-types\";\nimport type { ILvErrorOr } from \"../../bedrock/error\";\nimport { Option, type Command } from \"commander\";\nimport type { Region } from \"./types\";\nimport { getThread } from \"./modules/get-thread\";\n\nexport class PippitGetThreadCommand extends BaseCommand {\n protected _meta(): ICommandMeta {\n return {\n name: \"thread\",\n description: \"获取指定 thread 的详细信息\",\n };\n }\n\n protected _configureArguments(cmd: Command): void {\n cmd.argument(\"<thread_id>\", \"要获取的 thread id\");\n }\n\n protected _configureOptions(cmd: Command): void {\n cmd.addOption(\n new Option(\n \"-r, --region <region>\",\n \"指定区域,缺省时,会多 region 自动尝试,略微会有额外的耗时\",\n ).choices([\"cn\", \"i18n\"]),\n );\n }\n\n protected async _execute(\n _ctx: ICommandActionContext,\n ): Promise<ILvErrorOr<void>> {\n const threadId = _ctx.args[0] as string;\n const region = _ctx.options.region as Region | undefined;\n\n const result = await getThread({ threadId, region });\n\n if (!result.ok) {\n this._outputJsonError(result.code, result.msg);\n return this._makeOk();\n }\n\n this._outputJsonOk(result.value);\n return this._makeOk();\n }\n}\n","import { lvErrorConst } from \"../../../../bedrock/error\";\n\nconst BASE = 10000;\n\nexport enum GetThreadError {\n MissingThreadId = BASE + 1,\n NetworkRequestFailed = BASE + 2,\n ResponseParseFailed = BASE + 3,\n ThreadNotFound = BASE + 4,\n}\n\nexport const missingThreadIdError = lvErrorConst(\n GetThreadError.MissingThreadId,\n \"缺少 thread_id 参数。\",\n);\n\nexport const networkRequestFailedError = lvErrorConst(\n GetThreadError.NetworkRequestFailed,\n \"请求 Pippit API 失败,请确保在内网环境下请求\",\n);\n\nexport const responseParseFailed = lvErrorConst(\n GetThreadError.ResponseParseFailed,\n \"解析 API 响应失败,返回消息的数据格式异常。\",\n);\n\nexport const threadNotFoundError = lvErrorConst(\n GetThreadError.ThreadNotFound,\n \"未找到对应的 thread 数据。\",\n);\n","import type { ILvErrorOr } from \"../../../../bedrock/error\";\nimport { makeOkWith } from \"../../../../bedrock/error\";\nimport { Region } from \"../../types\";\nimport type { IThreadData } from \"./types\";\nimport {\n networkRequestFailedError,\n responseParseFailed,\n threadNotFoundError,\n} from \"./errors\";\n\nconst REGION_URL_MAP: Record<Region, string> = {\n [Region.CN]:\n \"https://pippit-cms.bytedance.net/api/internal/v1/agent/get_thread\",\n [Region.I18N]:\n \"https://pippit-cms.tiktok-row.org/api/internal/v1/agent/get_thread\",\n};\n\nconst REGION_REFERER_MAP: Record<Region, string> = {\n [Region.CN]: \"https://pippit-cms.bytedance.net/\",\n [Region.I18N]: \"https://pippit-cms.tiktok-row.org/\",\n};\n\nexport async function fetchThread(\n threadId: string,\n region: Region,\n): Promise<ILvErrorOr<IThreadData>> {\n const url = REGION_URL_MAP[region];\n const referer = REGION_REFERER_MAP[region];\n\n let res: Response;\n try {\n res = await fetch(url, {\n method: \"POST\",\n headers: {\n accept: \"*/*\",\n \"accept-language\": \"zh-CN,zh;q=0.9,en;q=0.8\",\n appvr: \"1.1.4\",\n \"content-type\": \"application/json\",\n Referer: referer,\n },\n body: JSON.stringify({\n scopes: [\"run_list.entry_list\"],\n thread_id: threadId,\n }),\n });\n } catch (err) {\n return networkRequestFailedError(err instanceof Error ? err : undefined);\n }\n\n let data: any;\n try {\n data = await res.json();\n } catch (err) {\n return responseParseFailed(err instanceof Error ? err : undefined);\n }\n\n const thread = data?.data?.thread as IThreadData | undefined;\n if (!thread?.run_list) {\n return threadNotFoundError();\n }\n\n return makeOkWith(thread);\n}\n","import type { IThreadData, IThreadRun, IThreadMessage, IThreadPart } from \"./types\";\n\nconst RUN_WHITE_KEYS: readonly string[] = [\n \"run_id\",\n \"state\",\n \"agent_name\",\n \"entry_list\",\n \"updated_at\",\n];\n\nconst MESSAGE_WHITE_KEYS: readonly string[] = [\n \"content\",\n \"message_id\",\n \"role\",\n \"run_id\",\n];\n\nconst PART_WHITE_KEYS: readonly string[] = [\"data\", \"sub_type\"];\n\nfunction pickKeys<T extends Record<string, unknown>>(\n obj: T,\n keys: readonly string[],\n): void {\n for (const key of Object.keys(obj)) {\n if (!keys.includes(key)) {\n delete obj[key];\n }\n }\n}\n\nfunction extractLogId(extraStr: string | undefined): string | undefined {\n if (!extraStr) return undefined;\n try {\n const extra = JSON.parse(extraStr);\n return extra?.execute_log_id as string | undefined;\n } catch {\n return undefined;\n }\n}\n\nfunction trimMessage(message: IThreadMessage): void {\n pickKeys(message, MESSAGE_WHITE_KEYS);\n if (Array.isArray(message.content)) {\n for (const part of message.content as IThreadPart[]) {\n pickKeys(part, PART_WHITE_KEYS);\n }\n }\n}\n\nfunction trimRun(run: IThreadRun, isLast: boolean): void {\n const logId = isLast ? extractLogId(run.extra) : undefined;\n\n pickKeys(run, RUN_WHITE_KEYS);\n\n if (logId) {\n run.execute_log_id = logId;\n }\n\n if (!run.entry_list) return;\n\n const messages: IThreadMessage[] = [];\n for (const entry of run.entry_list) {\n const msg = entry.artifact ?? entry.message;\n if (msg) {\n trimMessage(msg);\n messages.push(msg);\n }\n }\n\n run.entry_list.length = 0;\n run.entry_list.push(...(messages as any[]));\n}\n\n/**\n * 对 thread 数据做字段裁剪,只保留关键信息。\n * 会直接修改传入的对象。\n */\nexport function trimThread(thread: IThreadData): void {\n const { run_list } = thread;\n for (let i = 0; i < run_list.length; i++) {\n trimRun(run_list[i], i === run_list.length - 1);\n }\n}\n","import type { ILvErrorOr } from \"../../../../bedrock/error\";\nimport { makeOkWith } from \"../../../../bedrock/error\";\nimport { Region } from \"../../types\";\nimport type { IGetThreadOptions, IGetThreadResult } from \"./types\";\nimport { fetchThread } from \"./fetch-thread\";\nimport { trimThread } from \"./trim-thread\";\nimport {\n GetThreadError,\n missingThreadIdError,\n threadNotFoundError,\n} from \"./errors\";\n\nconst AUTO_DETECT_REGIONS: readonly Region[] = [Region.CN, Region.I18N];\n\n/**\n * 获取 thread 信息。\n *\n * - 指定 region 时直接请求对应区域\n * - 未指定 region 时依次尝试 cn -> i18n\n * - trim 选项控制是否裁剪冗余字段(默认 true)\n */\nexport async function getThread(\n options: IGetThreadOptions,\n): Promise<ILvErrorOr<IGetThreadResult>> {\n const { threadId, region, trim = true } = options;\n\n if (!threadId) {\n return missingThreadIdError();\n }\n\n if (region) {\n return _fetchAndProcess(threadId, region, trim);\n }\n\n let lastNonNotFoundError: ILvErrorOr<IGetThreadResult> | undefined;\n\n for (const r of AUTO_DETECT_REGIONS) {\n const result = await _fetchAndProcess(threadId, r, trim);\n if (result.ok) {\n return result;\n }\n if (result.code !== GetThreadError.ThreadNotFound) {\n lastNonNotFoundError = result;\n }\n }\n\n return lastNonNotFoundError ?? threadNotFoundError();\n}\n\nasync function _fetchAndProcess(\n threadId: string,\n region: Region,\n trim: boolean,\n): Promise<ILvErrorOr<IGetThreadResult>> {\n const result = await fetchThread(threadId, region);\n if (!result.ok) {\n return result;\n }\n\n const thread = result.value;\n if (trim) {\n trimThread(thread);\n }\n\n return makeOkWith({ thread, region });\n}\n","import type { Command } from \"commander\";\nimport { Option } from \"commander\";\nimport { BaseCommand } from \"../../core/base-command\";\nimport type { ICommandActionContext } from \"../../core/base-command\";\nimport type { ICommandMeta } from \"../../core/command-types\";\nimport type { ILvErrorOr } from \"../../bedrock/error\";\nimport { writeFornaxToken } from \"./modules/fornax-token\";\nimport type { Region } from \"./types\";\n\ninterface IPippitFornaxTokenOptions {\n region: Region;\n}\n\nexport class PippitFornaxTokenCommand extends BaseCommand<IPippitFornaxTokenOptions> {\n protected _meta(): ICommandMeta {\n return {\n name: \"fornax-token\",\n description: \"设置 fornax 的 token\",\n };\n }\n\n protected _configureArguments(cmd: Command): void {\n cmd.argument(\"<token>\", \"要写入的 fornax token\");\n }\n\n protected _configureOptions(cmd: Command): void {\n cmd.addOption(\n new Option(\"-r, --region <region>\", \"token 所属区域\")\n .choices([\"cn\", \"i18n\"])\n .makeOptionMandatory(),\n );\n }\n\n protected async _execute(\n ctx: ICommandActionContext<IPippitFornaxTokenOptions>,\n ): Promise<ILvErrorOr<void>> {\n const token = ctx.args[0] as string;\n const { region } = ctx.options;\n\n const result = await writeFornaxToken(region, token);\n if (!result.ok) {\n return this._makeError(result.code, result.msg);\n }\n\n this._outputJsonOk({\n region,\n stored: true,\n });\n return this._makeOk();\n }\n}\n","import * as fs from \"node:fs/promises\";\nimport * as os from \"node:os\";\nimport * as path from \"node:path\";\nimport { findClosestPackageJson } from \"../pkg\";\nimport { makeError, makeOkWith, type ILvErrorOr } from \"../error\";\n\nexport type ConfigPath = string | Array<string | number>;\n\nexport interface IConfigLocation {\n readonly packageName: string;\n readonly configDir: string;\n readonly configFilePath: string;\n}\n\nfunction normalizeAppName(rawName: string): string {\n const lastSegment = rawName.split(\"/\").pop() ?? rawName;\n const sanitized = lastSegment\n .trim()\n .replace(/[<>:\"/\\\\|?*\\u0000-\\u001F]/g, \"-\")\n .replace(/-+/g, \"-\")\n .replace(/^[-.]+|[-.]+$/g, \"\");\n return sanitized.length > 0 ? sanitized : \"app\";\n}\n\nasync function readClosestPackageName(): Promise<ILvErrorOr<string>> {\n const packageJsonResult = findClosestPackageJson();\n if (!packageJsonResult.ok) {\n return packageJsonResult;\n }\n\n try {\n const content = await fs.readFile(packageJsonResult.value, \"utf8\");\n const parsed = JSON.parse(content) as { name?: unknown };\n if (typeof parsed.name !== \"string\" || parsed.name.trim().length === 0) {\n return makeError(\n 1,\n `package.json at ${packageJsonResult.value} does not contain a valid name field`,\n );\n }\n return makeOkWith(normalizeAppName(parsed.name));\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n return makeError(\n 1,\n `failed to read package name from ${packageJsonResult.value}: ${message}`,\n );\n }\n}\n\nasync function getBaseConfigDir(): Promise<string> {\n if (process.platform === \"win32\") {\n return process.env.APPDATA ?? path.join(os.homedir(), \"AppData\", \"Roaming\");\n }\n\n return process.env.XDG_CONFIG_HOME ?? path.join(os.homedir(), \".config\");\n}\n\nexport async function resolveConfigLocation(): Promise<\n ILvErrorOr<IConfigLocation>\n> {\n const appNameResult = await readClosestPackageName();\n if (!appNameResult.ok) {\n return appNameResult;\n }\n\n const baseDir = await getBaseConfigDir();\n const configDir = path.join(baseDir, appNameResult.value);\n return makeOkWith({\n packageName: appNameResult.value,\n configDir,\n configFilePath: path.join(configDir, `${appNameResult.value}.json`),\n });\n}\n\nexport function parseConfigPath(\n configPath: ConfigPath,\n): Array<string | number> {\n if (Array.isArray(configPath)) {\n return configPath.slice();\n }\n\n const segments: Array<string | number> = [];\n const matcher = /[^.[\\]]+|\\[(\\d+)\\]/g;\n configPath.replace(matcher, (match, index) => {\n if (index !== undefined) {\n segments.push(Number(index));\n } else {\n segments.push(match);\n }\n return \"\";\n });\n return segments;\n}\n\nfunction isContainer(\n value: unknown,\n): value is Record<string, unknown> | Array<unknown> {\n return typeof value === \"object\" && value !== null;\n}\n\nfunction getIndexableContainer(\n value: Record<string, unknown> | Array<unknown>,\n): Record<string | number, unknown> {\n return value as Record<string | number, unknown>;\n}\n\nfunction getConfigValue<T>(\n source: unknown,\n configPath: ConfigPath,\n defaultValue?: T,\n): T {\n const segments = parseConfigPath(configPath);\n if (segments.length === 0) {\n return (source === undefined ? defaultValue : source) as T;\n }\n\n let current: unknown = source;\n for (const segment of segments) {\n if (!isContainer(current)) {\n return defaultValue as T;\n }\n current = getIndexableContainer(current)[segment];\n if (current === undefined) {\n return defaultValue as T;\n }\n }\n\n return (current === undefined ? defaultValue : current) as T;\n}\n\nfunction createNextContainer(\n nextSegment: string | number | undefined,\n): Record<string, unknown> | Array<unknown> {\n return typeof nextSegment === \"number\" ? [] : {};\n}\n\nfunction setConfigValue(\n target: Record<string, unknown>,\n configPath: ConfigPath,\n value: unknown,\n): void {\n const segments = parseConfigPath(configPath);\n if (segments.length === 0) {\n return;\n }\n\n let current: Record<string, unknown> | Array<unknown> = target;\n for (let index = 0; index < segments.length; index++) {\n const segment = segments[index];\n const isLast = index === segments.length - 1;\n const currentIndexable = getIndexableContainer(current);\n\n if (isLast) {\n currentIndexable[segment] = value;\n return;\n }\n\n const nextSegment = segments[index + 1];\n const existing = currentIndexable[segment];\n if (!isContainer(existing)) {\n currentIndexable[segment] = createNextContainer(nextSegment);\n }\n current = currentIndexable[segment] as\n | Record<string, unknown>\n | Array<unknown>;\n }\n}\n\nasync function ensureConfigFile(\n configFilePath: string,\n): Promise<ILvErrorOr<void>> {\n try {\n await fs.mkdir(path.dirname(configFilePath), { recursive: true });\n await fs.access(configFilePath).catch(async () => {\n await fs.writeFile(configFilePath, \"{}\\n\", \"utf8\");\n });\n return makeOkWith(undefined);\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n return makeError(\n 1,\n `failed to ensure config file ${configFilePath}: ${message}`,\n );\n }\n}\n\nexport async function readConfig<\n T extends Record<string, unknown> = Record<string, unknown>,\n>(): Promise<ILvErrorOr<T>> {\n const locationResult = await resolveConfigLocation();\n if (!locationResult.ok) {\n return locationResult;\n }\n\n const ensureResult = await ensureConfigFile(\n locationResult.value.configFilePath,\n );\n if (!ensureResult.ok) {\n return ensureResult;\n }\n\n try {\n const content = await fs.readFile(\n locationResult.value.configFilePath,\n \"utf8\",\n );\n if (content.trim().length === 0) {\n return makeOkWith({} as T);\n }\n return makeOkWith(JSON.parse(content) as T);\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n return makeError(\n 1,\n `failed to read config from ${locationResult.value.configFilePath}: ${message}`,\n );\n }\n}\n\nexport async function writeConfig<T extends Record<string, unknown>>(\n config: T,\n): Promise<ILvErrorOr<void>> {\n const locationResult = await resolveConfigLocation();\n if (!locationResult.ok) {\n return locationResult;\n }\n\n const ensureResult = await ensureConfigFile(\n locationResult.value.configFilePath,\n );\n if (!ensureResult.ok) {\n return ensureResult;\n }\n\n try {\n const content = `${JSON.stringify(config, null, 2)}\\n`;\n await fs.writeFile(locationResult.value.configFilePath, content, \"utf8\");\n return makeOkWith(undefined);\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n return makeError(\n 1,\n `failed to write config to ${locationResult.value.configFilePath}: ${message}`,\n );\n }\n}\n\nexport async function readConfigValue<T = unknown>(\n configPath: ConfigPath,\n defaultValue?: T,\n): Promise<ILvErrorOr<T>> {\n const configResult = await readConfig<Record<string, unknown>>();\n if (!configResult.ok) {\n return configResult;\n }\n\n return makeOkWith(\n getConfigValue(configResult.value, configPath, defaultValue),\n );\n}\n\nexport async function writeConfigValue<T = unknown>(\n configPath: ConfigPath,\n value: T,\n): Promise<ILvErrorOr<void>> {\n const configResult = await readConfig<Record<string, unknown>>();\n if (!configResult.ok) {\n return configResult;\n }\n\n setConfigValue(configResult.value, configPath, value);\n return writeConfig(configResult.value);\n}\n","import * as path from 'node:path';\nimport * as fs from 'node:fs';\nimport { fileURLToPath } from 'node:url';\nimport { makeOkWith, makeError } from '../error/error-t';\nimport type { ILvErrorOr } from '../error/error-base';\n\nconst _thisDir = path.dirname(fileURLToPath(import.meta.url));\nconst DEFAULT_MAX_DEPTH = 10;\n\n/**\n * 从当前文件所在目录向上查找最近的 package.json 文件\n * @param maxDepth 最多向上遍历的层级数,缺省为 10\n */\nexport function findClosestPackageJson(\n maxDepth: number = DEFAULT_MAX_DEPTH,\n): ILvErrorOr<string> {\n let currentDir = _thisDir;\n\n for (let i = 0; i < maxDepth; i++) {\n const candidate = path.join(currentDir, 'package.json');\n if (fs.existsSync(candidate)) {\n return makeOkWith(candidate);\n }\n\n const parentDir = path.dirname(currentDir);\n if (parentDir === currentDir) {\n break;\n }\n currentDir = parentDir;\n }\n\n return makeError(1, `package.json not found within ${maxDepth} levels from ${_thisDir}`);\n}\n","import { readConfigValue, writeConfigValue } from \"../../../../bedrock/config\";\nimport type { ILvErrorOr } from \"../../../../bedrock/error\";\nimport type { Region } from \"../../types\";\n\nconst FORNAX_TOKEN_CONFIG_PATH = [\"fornax\", \"token\"] as const;\n\nexport async function writeFornaxToken(\n region: Region,\n token: string,\n): Promise<ILvErrorOr<void>> {\n return writeConfigValue([...FORNAX_TOKEN_CONFIG_PATH, region], token);\n}\n\nexport async function readFornaxToken(\n region: Region,\n): Promise<ILvErrorOr<string | undefined>> {\n return readConfigValue([...FORNAX_TOKEN_CONFIG_PATH, region]);\n}\n","import type { Command } from \"commander\";\nimport { Option } from \"commander\";\nimport { BaseCommand } from \"../../core/base-command\";\nimport type { ICommandActionContext } from \"../../core/base-command\";\nimport type { ICommandMeta } from \"../../core/command-types\";\nimport type { ILvErrorOr } from \"../../bedrock/error\";\nimport { searchLog } from \"./modules/search-log\";\nimport type { Region } from \"./types\";\n\ninterface IPippitSearchFornaxLogOptions {\n region: Region;\n}\n\nexport class PippitSearchFornaxLogCommand extends BaseCommand<IPippitSearchFornaxLogOptions> {\n protected _meta(): ICommandMeta {\n return {\n name: \"fornax\",\n description: \"从 fornax 中获取并解析 log 数据\",\n };\n }\n\n protected _configureArguments(cmd: Command): void {\n cmd.argument(\"<log_id>\", \"要获取的 log id\");\n }\n\n protected _configureOptions(cmd: Command): void {\n cmd.addOption(\n new Option(\"-r, --region <region>\", \"指定区域\")\n .choices([\"cn\", \"i18n\"])\n .makeOptionMandatory(),\n );\n }\n\n protected async _execute(\n ctx: ICommandActionContext<IPippitSearchFornaxLogOptions>,\n ): Promise<ILvErrorOr<void>> {\n const logId = ctx.args[0] as string;\n const region = ctx.options.region;\n\n const result = await searchLog({ logId, region });\n if (!result.ok) {\n this._outputJsonError(result.code, result.msg);\n return this._makeOk();\n }\n\n this._outputJsonOk(result.value);\n return this._makeOk();\n }\n}\n","import { lvErrorConst } from \"../../../../bedrock/error\";\n\nconst BASE = 11000;\n\nexport enum FornaxSearchError {\n MissingLogId = BASE + 1,\n MissingFornaxToken = BASE + 2,\n NetworkRequestFailed = BASE + 3,\n ResponseParseFailed = BASE + 4,\n SearchResultNotFound = BASE + 5,\n DetailSpanNotFound = BASE + 6,\n PayloadNotFound = BASE + 7,\n PayloadParseFailed = BASE + 8,\n MissingRegion = BASE + 9,\n ExpiredFornaxToken = BASE + 10,\n}\n\nexport const missingLogIdError = lvErrorConst(\n FornaxSearchError.MissingLogId,\n \"缺少 log_id 参数。\",\n);\n\nexport const missingRegionError = lvErrorConst(\n FornaxSearchError.MissingRegion,\n \"缺少 region 参数,请显式指定 cn 或 i18n。\",\n);\n\nexport const howToConfigureFornaxToken =\n \"关于如何获取 token: 国内访问 https://fornax.bytedance.net/ 海外访问 https://fornax-i18n.byteintl.net/,然后拷贝 cookie 里的 prompt-platform-session\";\n\nexport const missingFornaxTokenError = lvErrorConst(\n FornaxSearchError.MissingFornaxToken,\n \"缺少可用的 fornax-token,请先使用 `tt pippit fornax-token -r <region> <token>` 配置。\" +\n howToConfigureFornaxToken,\n);\n\nexport const expiredFornaxTokenError = lvErrorConst(\n FornaxSearchError.ExpiredFornaxToken,\n \"fornax-token 可能已失效,请先使用 `tt pippit fornax-token -r <region> <token>` 重新配置。\" +\n howToConfigureFornaxToken,\n);\n\nexport const networkRequestFailedError = lvErrorConst(\n FornaxSearchError.NetworkRequestFailed,\n \"请求 fornax API 失败,请确保在内网环境下请求。\",\n);\n\nexport const responseParseFailedError = lvErrorConst(\n FornaxSearchError.ResponseParseFailed,\n \"解析 fornax API 响应失败,返回消息的数据格式异常。\",\n);\n\nexport const searchResultNotFoundError = lvErrorConst(\n FornaxSearchError.SearchResultNotFound,\n \"未找到符合条件的 fornax 记录。\",\n);\n\nexport const detailSpanNotFoundError = lvErrorConst(\n FornaxSearchError.DetailSpanNotFound,\n \"未找到可用于读取数据的 span。\",\n);\n\nexport const payloadNotFoundError = lvErrorConst(\n FornaxSearchError.PayloadNotFound,\n \"未找到 span 的 input 数据。\",\n);\n\nexport const payloadParseFailedError = lvErrorConst(\n FornaxSearchError.PayloadParseFailed,\n \"解析 span payload 失败。\",\n);\n","import { makeOkWith, type ILvErrorOr } from \"../../../../bedrock/error\";\nimport {\n expiredFornaxTokenError,\n networkRequestFailedError,\n payloadNotFoundError,\n payloadParseFailedError,\n responseParseFailedError,\n} from \"./errors\";\nimport type { IFornaxSpan } from \"./types\";\n\nexport interface IJsonRequestOptions extends RequestInit {\n unauthorizedError?: () => ILvErrorOr<never>;\n}\n\nexport function normalizeToken(token: string): string {\n const trimmed = token.trim();\n const prefix = \"prompt-platform-session=\";\n if (trimmed.startsWith(prefix)) {\n return trimmed.slice(prefix.length).trim();\n }\n return trimmed;\n}\n\nexport function createHeaders(token: string, referer: string): any {\n return {\n accept: \"application/json, text/plain, */*\",\n \"accept-language\": \"zh-CN,zh;q=0.9,en;q=0.8\",\n \"agw-js-conv\": \"str\",\n \"content-type\": \"application/json\",\n \"sec-ch-ua\":\n '\"Chromium\";v=\"146\", \"Not-A.Brand\";v=\"24\", \"Google Chrome\";v=\"146\"',\n \"sec-ch-ua-mobile\": \"?0\",\n \"sec-ch-ua-platform\": '\"macOS\"',\n \"sec-fetch-dest\": \"empty\",\n \"sec-fetch-mode\": \"cors\",\n \"sec-fetch-site\": \"same-origin\",\n \"x-requested-with\": \"XMLHttpRequest\",\n cookie: `prompt-platform-session=${normalizeToken(token)}`,\n Referer: referer,\n };\n}\n\nexport async function requestJson<T>(\n url: string,\n options: IJsonRequestOptions,\n): Promise<ILvErrorOr<T>> {\n let res: Response;\n try {\n res = await fetch(url, options);\n } catch (error) {\n return networkRequestFailedError(\n error instanceof Error ? error : undefined,\n );\n }\n\n if (res.status === 401 || res.status === 403) {\n return (options.unauthorizedError ?? expiredFornaxTokenError)();\n }\n\n if (!res.ok) {\n return networkRequestFailedError(\n new Error(`HTTP ${res.status} ${res.statusText}`),\n );\n }\n\n try {\n return makeOkWith((await res.json()) as T);\n } catch (error) {\n return responseParseFailedError(error instanceof Error ? error : undefined);\n }\n}\n\nexport function resolveTimeWindow(\n baseOffsetInDays: number,\n daysLater: number,\n): { startTime: string; endTime: string } {\n const currentTime = Date.now();\n return {\n startTime: String(currentTime - 1000 * 60 * 60 * 24 * baseOffsetInDays),\n endTime: String(currentTime + 1000 * 60 * 60 * 24 * daysLater),\n };\n}\n\nexport function parseDetailPayload(input: unknown): ILvErrorOr<unknown> {\n if (typeof input === \"string\") {\n try {\n return makeOkWith(JSON.parse(input) as unknown);\n } catch (error) {\n return payloadParseFailedError(\n error instanceof Error ? error : undefined,\n );\n }\n }\n\n if (input !== null && typeof input === \"object\") {\n return makeOkWith(input);\n }\n\n return payloadNotFoundError();\n}\n\nexport function selectDetailSpan(\n spans: IFornaxSpan[],\n): IFornaxSpan | undefined {\n return spans.findLast((span) => {\n return (\n span?.type === \"model\" && span?.service_name === \"pippit.business.agent\"\n );\n });\n}\n","import { makeOkWith, type ILvErrorOr } from \"../../../../bedrock/error\";\nimport { Region } from \"../../types\";\nimport { readFornaxToken } from \"../fornax-token\";\nimport {\n expiredFornaxTokenError,\n detailSpanNotFoundError,\n missingFornaxTokenError,\n missingLogIdError,\n searchResultNotFoundError,\n} from \"./errors\";\nimport {\n createHeaders,\n parseDetailPayload,\n requestJson,\n resolveTimeWindow,\n selectDetailSpan,\n} from \"./common\";\nimport type {\n IFornaxDataResult,\n IFornaxSearchOptions,\n IFornaxSpan,\n} from \"./types\";\n\nconst CONFIG = {\n BASE_URL: \"https://fornax.bytedance.net/\",\n WORKSPACE_ID: \"7507836945448304652\",\n SCAN_SPAN_IN_HOUR: \"4\",\n DAYS_AGO: 30,\n DAYS_LATER: 1,\n PLATFORM_TYPE: \"inner_cozeloop\",\n PAGE_SIZE: 30,\n} as const;\n\ninterface ITraceSearchResult {\n spans?: IFornaxSpan[];\n [key: string]: unknown;\n}\n\nfunction createFilterField(\n fieldName: string,\n fieldType: string,\n values: string[],\n queryType: string,\n isCustom = false,\n) {\n return {\n field_name: fieldName,\n field_type: fieldType,\n values,\n query_type: queryType,\n query_and_or: \"and\",\n is_custom: isCustom,\n sub_filter: {\n query_and_or: \"and\",\n filter_fields: [],\n },\n };\n}\n\nfunction selectRootSpan(spans: IFornaxSpan[]): IFornaxSpan | undefined {\n let selected: IFornaxSpan | undefined;\n for (const span of spans) {\n if (typeof span.span_id !== \"string\" || typeof span.trace_id !== \"string\") {\n continue;\n }\n if (\n !selected ||\n (span.duration ?? -Infinity) > (selected.duration ?? -Infinity)\n ) {\n selected = span;\n }\n }\n return selected;\n}\n\nfunction getSearchUrl(): string {\n return `${CONFIG.BASE_URL}api/observability/v1/spans/list`;\n}\n\nfunction getSearchReferer(): string {\n return getSearchUrl();\n}\n\nfunction getTimeWindow(): { startTime: string; endTime: string } {\n return resolveTimeWindow(CONFIG.DAYS_AGO, CONFIG.DAYS_LATER);\n}\n\nfunction getSearchBody(logId: string): string {\n const { startTime, endTime } = getTimeWindow();\n return JSON.stringify({\n workspace_id: CONFIG.WORKSPACE_ID,\n start_time: startTime,\n end_time: endTime,\n filters: {\n query_and_or: \"and\",\n filter_fields: [\n createFilterField(\"deployment_env\", \"string\", [\"boe\"], \"not_in\"),\n createFilterField(\"psm\", \"string\", [\"pippit.business.agent\"], \"in\"),\n createFilterField(\"logid\", \"string\", [logId], \"in\"),\n ],\n },\n page_size: CONFIG.PAGE_SIZE,\n order_bys: [\n {\n field: \"start_time\",\n is_asc: false,\n },\n ],\n platform_type: CONFIG.PLATFORM_TYPE,\n span_list_type: \"root_span\",\n });\n}\n\nfunction getTreeUrl(): string {\n return `${CONFIG.BASE_URL}api/observability/v1/traces/search_tree`;\n}\n\nfunction getDetailUrl(traceId: string, spanId: string): string {\n const { startTime, endTime } = getTimeWindow();\n return `${CONFIG.BASE_URL}api/observability/v1/traces/${traceId}?workspace_id=${CONFIG.WORKSPACE_ID}&start_time=${startTime}&end_time=${endTime}&platform_type=${CONFIG.PLATFORM_TYPE}&span_ids=${spanId}`;\n}\n\nexport async function searchLogCn(\n options: IFornaxSearchOptions,\n): Promise<ILvErrorOr<IFornaxDataResult>> {\n const { logId } = options;\n if (!logId) {\n return missingLogIdError();\n }\n\n const tokenResult = await readFornaxToken(Region.CN);\n if (!tokenResult.ok) {\n return tokenResult;\n }\n\n const token = tokenResult.value?.trim();\n if (!token) {\n return missingFornaxTokenError();\n }\n\n const searchResult = await requestJson<ITraceSearchResult>(getSearchUrl(), {\n method: \"POST\",\n headers: createHeaders(token, getSearchReferer()),\n body: getSearchBody(logId),\n unauthorizedError: expiredFornaxTokenError,\n });\n if (!searchResult.ok) {\n return searchResult;\n }\n\n const searchSpans = searchResult.value.spans ?? [];\n if (searchSpans.length === 0) {\n return searchResultNotFoundError();\n }\n\n const rootSpan = selectRootSpan(searchSpans);\n if (!rootSpan?.trace_id) {\n return detailSpanNotFoundError();\n }\n\n const treeResult = await requestJson<ITraceSearchResult>(getTreeUrl(), {\n method: \"POST\",\n headers: createHeaders(token, getSearchReferer()),\n body: JSON.stringify({\n workspace_id: CONFIG.WORKSPACE_ID,\n trace_id: rootSpan.trace_id,\n start_time: getTimeWindow().startTime,\n end_time: getTimeWindow().endTime,\n platform_type: CONFIG.PLATFORM_TYPE,\n }),\n unauthorizedError: expiredFornaxTokenError,\n });\n if (!treeResult.ok) {\n return treeResult;\n }\n\n const detailSpan = selectDetailSpan(treeResult.value.spans ?? []);\n if (!detailSpan?.trace_id || !detailSpan.span_id) {\n return detailSpanNotFoundError();\n }\n\n const detailResult = await requestJson<ITraceSearchResult>(\n getDetailUrl(detailSpan.trace_id, detailSpan.span_id),\n {\n method: \"GET\",\n headers: createHeaders(token, getSearchReferer()),\n unauthorizedError: expiredFornaxTokenError,\n },\n );\n if (!detailResult.ok) {\n return detailResult;\n }\n\n const payload = parseDetailPayload(detailResult.value.spans?.[0]?.input);\n if (!payload.ok) {\n return payload;\n }\n\n return makeOkWith({\n meta: {\n region: Region.CN,\n spanName: detailSpan.span_name || \"\",\n },\n data: payload.value,\n });\n}\n","import { makeOkWith, type ILvErrorOr } from \"../../../../bedrock/error\";\nimport { Region } from \"../../types\";\nimport { readFornaxToken } from \"../fornax-token\";\nimport {\n expiredFornaxTokenError,\n detailSpanNotFoundError,\n missingFornaxTokenError,\n missingLogIdError,\n searchResultNotFoundError,\n} from \"./errors\";\nimport {\n createHeaders,\n parseDetailPayload,\n requestJson,\n resolveTimeWindow,\n selectDetailSpan,\n} from \"./common\";\nimport type {\n IFornaxDataResult,\n IFornaxSearchOptions,\n IFornaxSpan,\n} from \"./types\";\n\nconst CONFIG = {\n BASE_URL: \"https://fornax-i18n.byteintl.net\",\n WORKSPACE_ID: \"7517207223651532851\",\n SCAN_SPAN_IN_HOUR: \"4\",\n DAYS_AGO: 30,\n DAYS_LATER: 1,\n} as const;\n\ninterface ITraceSearchResult {\n spans?: IFornaxSpan[];\n [key: string]: unknown;\n}\n\nfunction getSearchUrl(): string {\n return `${CONFIG.BASE_URL}/api/observability/v1/traces/search`;\n}\n\nfunction getSearchReferer(logId: string): string {\n return `${CONFIG.BASE_URL}/space/${CONFIG.WORKSPACE_ID}/analytics/log-query?env=online&logIdTime=${CONFIG.SCAN_SPAN_IN_HOUR}&queryID=${logId}&queryType=log_id`;\n}\n\nfunction getTimeWindow(): { startTime: string; endTime: string } {\n return resolveTimeWindow(CONFIG.DAYS_AGO, CONFIG.DAYS_LATER);\n}\n\nfunction getDetailUrl(traceId: string, spanId: string): string {\n const { startTime, endTime } = getTimeWindow();\n return `${CONFIG.BASE_URL}/api/observability/v1/traces/${traceId}?workspace_id=${CONFIG.WORKSPACE_ID}&start_time=${startTime}&end_time=${endTime}&platform_type=trace_detail&span_ids=${spanId}`;\n}\n\nexport async function searchLogI18n(\n options: IFornaxSearchOptions,\n): Promise<ILvErrorOr<IFornaxDataResult>> {\n const { logId } = options;\n if (!logId) {\n return missingLogIdError();\n }\n\n const tokenResult = await readFornaxToken(Region.I18N);\n if (!tokenResult.ok) {\n return tokenResult;\n }\n\n const token = tokenResult.value?.trim();\n if (!token) {\n return missingFornaxTokenError();\n }\n\n const searchResult = await requestJson<ITraceSearchResult>(getSearchUrl(), {\n method: \"POST\",\n headers: createHeaders(token, getSearchReferer(logId)),\n body: JSON.stringify({\n workspace_id: CONFIG.WORKSPACE_ID,\n search_type: \"log_id\",\n id: logId,\n scan_span_in_hour: CONFIG.SCAN_SPAN_IN_HOUR,\n }),\n unauthorizedError: expiredFornaxTokenError,\n });\n if (!searchResult.ok) {\n return searchResult;\n }\n\n const searchSpan = selectDetailSpan(searchResult.value.spans ?? []);\n if (!searchSpan?.trace_id || !searchSpan.span_id) {\n return searchResultNotFoundError();\n }\n\n const detailResult = await requestJson<ITraceSearchResult>(\n getDetailUrl(searchSpan.trace_id, searchSpan.span_id),\n {\n method: \"GET\",\n headers: createHeaders(token, getSearchReferer(logId)),\n unauthorizedError: expiredFornaxTokenError,\n },\n );\n if (!detailResult.ok) {\n return detailResult;\n }\n\n const detailSpan = selectDetailSpan(detailResult.value.spans ?? []);\n if (!detailSpan?.trace_id || !detailSpan.span_id) {\n return detailSpanNotFoundError();\n }\n\n const payload = parseDetailPayload(detailSpan.input);\n if (!payload.ok) {\n return payload;\n }\n\n return makeOkWith({\n meta: {\n region: Region.I18N,\n spanName: detailSpan.span_name || \"\",\n },\n data: payload.value,\n });\n}\n","import { Region } from \"../../types\";\nimport type { IFornaxDataResult, IFornaxSearchOptions } from \"./types\";\nimport { searchLogCn } from \"./cn-search-log\";\nimport { searchLogI18n } from \"./i18n-search-log\";\nimport { missingLogIdError, missingRegionError } from \"./errors\";\nimport type { ILvErrorOr } from \"../../../../bedrock/error\";\n\nexport async function searchLog(\n options: IFornaxSearchOptions,\n): Promise<ILvErrorOr<IFornaxDataResult>> {\n const { logId, region } = options;\n if (!logId) {\n return missingLogIdError();\n }\n\n if (!region) {\n return missingRegionError();\n }\n\n if (region === Region.CN) {\n return searchLogCn({ logId, region });\n }\n\n return searchLogI18n({ logId, region });\n}\n","import type { ICommandMeta } from \"../../core/command-types\";\nimport { BaseSubcommandHost } from \"../../core/base-subcommand-host\";\nimport { PippitGetThreadCommand } from \"./pippit-get-thread-command\";\nimport { PippitFornaxTokenCommand } from \"./pippit-fornax-token-command\";\nimport { PippitSearchFornaxLogCommand } from \"./pippit-search-fornax-log-command\";\n\nexport class PippitCommand extends BaseSubcommandHost {\n protected _meta(): ICommandMeta {\n return {\n name: \"pippit\",\n description: \"访问 pippit 服务\",\n aliases: [\"pp\", \"xyq\"],\n };\n }\n\n protected _registerSubcommands(): void {\n this._addSubcommand(new PippitGetThreadCommand());\n this._addSubcommand(new PippitFornaxTokenCommand());\n this._addSubcommand(new PippitSearchFornaxLogCommand());\n }\n}\n"],"mappings":";;;;;;;;;;;AAEA,SAAS,qBAAqB;;;ACQvB,IAAM,oBAAN,cAAgC,YAAgC;AAAA,EAC3D,QAAsB;AAC9B,WAAO;AAAA,MACL,MAAM;AAAA,MACN,aAAa;AAAA,IACf;AAAA,EACF;AAAA,EAEU,oBAAoB,KAAoB;AAChD,QAAI,SAAS,UAAU,oDAAY,OAAO;AAAA,EAC5C;AAAA,EAEU,kBAAkB,KAAoB;AAC9C,QAAI,OAAO,mBAAmB,8CAAW,KAAK;AAAA,EAChD;AAAA,EAEA,MAAgB,SACd,KAC2B;AAC3B,UAAM,OAAO,IAAI,KAAK,CAAC;AACvB,UAAM,EAAE,UAAU,IAAI,IAAI;AAE1B,QAAI,UAAU,UAAU,IAAI;AAC5B,QAAI,WAAW;AACb,gBAAU,QAAQ,YAAY;AAAA,IAChC;AAEA,SAAK,cAAc,EAAE,QAAQ,CAAC;AAC9B,WAAO,KAAK,QAAQ;AAAA,EACtB;AACF;;;ACnCO,IAAM,mBAAN,cAA+B,YAAY;AAAA,EACtC,QAAsB;AAC9B,WAAO;AAAA,MACL,MAAM;AAAA,MACN,aAAa;AAAA,IACf;AAAA,EACF;AAAA,EAEA,MAAgB,SACd,MAC2B;AAC3B,SAAK,cAAc;AAAA,MACjB,SAAS;AAAA,MACT,aAAa;AAAA,IACf,CAAC;AACD,WAAO,KAAK,QAAQ;AAAA,EACtB;AACF;;;ACjBO,IAAM,eAAN,cAA2B,mBAAmB;AAAA,EACzC,QAAsB;AAC9B,WAAO;AAAA,MACL,MAAM;AAAA,MACN,aAAa;AAAA,MACb,SAAS,CAAC,IAAI;AAAA,IAChB;AAAA,EACF;AAAA,EAEU,uBAA6B;AACrC,SAAK,eAAe,IAAI,kBAAkB,CAAC;AAC3C,SAAK,eAAe,IAAI,iBAAiB,CAAC;AAAA,EAC5C;AACF;;;ACdA,SAAS,cAA4B;;;ACFrC,IAAM,OAAO;AAEN,IAAK,kBAAL,CAAKA,oBAAL;AACL,EAAAA,gCAAA,qBAAkB,OAAO,KAAzB;AACA,EAAAA,gCAAA,0BAAuB,OAAO,KAA9B;AACA,EAAAA,gCAAA,yBAAsB,OAAO,KAA7B;AACA,EAAAA,gCAAA,oBAAiB,OAAO,KAAxB;AAJU,SAAAA;AAAA,GAAA;AAOL,IAAM,uBAAuB;AAAA,EAClC,eAAe;AAAA,EACf;AACF;AAEO,IAAM,4BAA4B;AAAA,EACvC,eAAe;AAAA,EACf;AACF;AAEO,IAAM,sBAAsB;AAAA,EACjC,eAAe;AAAA,EACf;AACF;AAEO,IAAM,sBAAsB;AAAA,EACjC,eAAe;AAAA,EACf;AACF;;;ACnBA,IAAM,iBAAyC;AAAA,EAC7C,cAAU,GACR;AAAA,EACF,kBAAY,GACV;AACJ;AAEA,IAAM,qBAA6C;AAAA,EACjD,cAAU,GAAG;AAAA,EACb,kBAAY,GAAG;AACjB;AAEA,eAAsB,YACpB,UACA,QACkC;AAClC,QAAM,MAAM,eAAe,MAAM;AACjC,QAAM,UAAU,mBAAmB,MAAM;AAEzC,MAAI;AACJ,MAAI;AACF,UAAM,MAAM,MAAM,KAAK;AAAA,MACrB,QAAQ;AAAA,MACR,SAAS;AAAA,QACP,QAAQ;AAAA,QACR,mBAAmB;AAAA,QACnB,OAAO;AAAA,QACP,gBAAgB;AAAA,QAChB,SAAS;AAAA,MACX;AAAA,MACA,MAAM,KAAK,UAAU;AAAA,QACnB,QAAQ,CAAC,qBAAqB;AAAA,QAC9B,WAAW;AAAA,MACb,CAAC;AAAA,IACH,CAAC;AAAA,EACH,SAAS,KAAK;AACZ,WAAO,0BAA0B,eAAe,QAAQ,MAAM,MAAS;AAAA,EACzE;AAEA,MAAI;AACJ,MAAI;AACF,WAAO,MAAM,IAAI,KAAK;AAAA,EACxB,SAAS,KAAK;AACZ,WAAO,oBAAoB,eAAe,QAAQ,MAAM,MAAS;AAAA,EACnE;AAEA,QAAM,SAAS,MAAM,MAAM;AAC3B,MAAI,CAAC,QAAQ,UAAU;AACrB,WAAO,oBAAoB;AAAA,EAC7B;AAEA,SAAO,WAAW,MAAM;AAC1B;;;AC5DA,IAAM,iBAAoC;AAAA,EACxC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAEA,IAAM,qBAAwC;AAAA,EAC5C;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAEA,IAAM,kBAAqC,CAAC,QAAQ,UAAU;AAE9D,SAAS,SACP,KACA,MACM;AACN,aAAW,OAAO,OAAO,KAAK,GAAG,GAAG;AAClC,QAAI,CAAC,KAAK,SAAS,GAAG,GAAG;AACvB,aAAO,IAAI,GAAG;AAAA,IAChB;AAAA,EACF;AACF;AAEA,SAAS,aAAa,UAAkD;AACtE,MAAI,CAAC,SAAU,QAAO;AACtB,MAAI;AACF,UAAM,QAAQ,KAAK,MAAM,QAAQ;AACjC,WAAO,OAAO;AAAA,EAChB,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEA,SAAS,YAAY,SAA+B;AAClD,WAAS,SAAS,kBAAkB;AACpC,MAAI,MAAM,QAAQ,QAAQ,OAAO,GAAG;AAClC,eAAW,QAAQ,QAAQ,SAA0B;AACnD,eAAS,MAAM,eAAe;AAAA,IAChC;AAAA,EACF;AACF;AAEA,SAAS,QAAQ,KAAiB,QAAuB;AACvD,QAAM,QAAQ,SAAS,aAAa,IAAI,KAAK,IAAI;AAEjD,WAAS,KAAK,cAAc;AAE5B,MAAI,OAAO;AACT,QAAI,iBAAiB;AAAA,EACvB;AAEA,MAAI,CAAC,IAAI,WAAY;AAErB,QAAM,WAA6B,CAAC;AACpC,aAAW,SAAS,IAAI,YAAY;AAClC,UAAM,MAAM,MAAM,YAAY,MAAM;AACpC,QAAI,KAAK;AACP,kBAAY,GAAG;AACf,eAAS,KAAK,GAAG;AAAA,IACnB;AAAA,EACF;AAEA,MAAI,WAAW,SAAS;AACxB,MAAI,WAAW,KAAK,GAAI,QAAkB;AAC5C;AAMO,SAAS,WAAW,QAA2B;AACpD,QAAM,EAAE,SAAS,IAAI;AACrB,WAAS,IAAI,GAAG,IAAI,SAAS,QAAQ,KAAK;AACxC,YAAQ,SAAS,CAAC,GAAG,MAAM,SAAS,SAAS,CAAC;AAAA,EAChD;AACF;;;ACtEA,IAAM,sBAAyC,iCAAuB;AAStE,eAAsB,UACpB,SACuC;AACvC,QAAM,EAAE,UAAU,QAAQ,OAAO,KAAK,IAAI;AAE1C,MAAI,CAAC,UAAU;AACb,WAAO,qBAAqB;AAAA,EAC9B;AAEA,MAAI,QAAQ;AACV,WAAO,iBAAiB,UAAU,QAAQ,IAAI;AAAA,EAChD;AAEA,MAAI;AAEJ,aAAW,KAAK,qBAAqB;AACnC,UAAM,SAAS,MAAM,iBAAiB,UAAU,GAAG,IAAI;AACvD,QAAI,OAAO,IAAI;AACb,aAAO;AAAA,IACT;AACA,QAAI,OAAO,SAAS,eAAe,gBAAgB;AACjD,6BAAuB;AAAA,IACzB;AAAA,EACF;AAEA,SAAO,wBAAwB,oBAAoB;AACrD;AAEA,eAAe,iBACb,UACA,QACA,MACuC;AACvC,QAAM,SAAS,MAAM,YAAY,UAAU,MAAM;AACjD,MAAI,CAAC,OAAO,IAAI;AACd,WAAO;AAAA,EACT;AAEA,QAAM,SAAS,OAAO;AACtB,MAAI,MAAM;AACR,eAAW,MAAM;AAAA,EACnB;AAEA,SAAO,WAAW,EAAE,QAAQ,OAAO,CAAC;AACtC;;;AJzDO,IAAM,yBAAN,cAAqC,YAAY;AAAA,EAC5C,QAAsB;AAC9B,WAAO;AAAA,MACL,MAAM;AAAA,MACN,aAAa;AAAA,IACf;AAAA,EACF;AAAA,EAEU,oBAAoB,KAAoB;AAChD,QAAI,SAAS,eAAe,oCAAgB;AAAA,EAC9C;AAAA,EAEU,kBAAkB,KAAoB;AAC9C,QAAI;AAAA,MACF,IAAI;AAAA,QACF;AAAA,QACA;AAAA,MACF,EAAE,QAAQ,CAAC,MAAM,MAAM,CAAC;AAAA,IAC1B;AAAA,EACF;AAAA,EAEA,MAAgB,SACd,MAC2B;AAC3B,UAAM,WAAW,KAAK,KAAK,CAAC;AAC5B,UAAM,SAAS,KAAK,QAAQ;AAE5B,UAAM,SAAS,MAAM,UAAU,EAAE,UAAU,OAAO,CAAC;AAEnD,QAAI,CAAC,OAAO,IAAI;AACd,WAAK,iBAAiB,OAAO,MAAM,OAAO,GAAG;AAC7C,aAAO,KAAK,QAAQ;AAAA,IACtB;AAEA,SAAK,cAAc,OAAO,KAAK;AAC/B,WAAO,KAAK,QAAQ;AAAA,EACtB;AACF;;;AK5CA,SAAS,UAAAC,eAAc;;;ACDvB,YAAYC,SAAQ;AACpB,YAAY,QAAQ;AACpB,YAAYC,WAAU;;;ACFtB,YAAY,UAAU;AACtB,YAAY,QAAQ;AACpB,SAAS,qBAAqB;AAI9B,IAAM,WAAgB,aAAQ,cAAc,YAAY,GAAG,CAAC;AAC5D,IAAM,oBAAoB;AAMnB,SAAS,uBACd,WAAmB,mBACC;AACpB,MAAI,aAAa;AAEjB,WAAS,IAAI,GAAG,IAAI,UAAU,KAAK;AACjC,UAAM,YAAiB,UAAK,YAAY,cAAc;AACtD,QAAO,cAAW,SAAS,GAAG;AAC5B,aAAO,WAAW,SAAS;AAAA,IAC7B;AAEA,UAAM,YAAiB,aAAQ,UAAU;AACzC,QAAI,cAAc,YAAY;AAC5B;AAAA,IACF;AACA,iBAAa;AAAA,EACf;AAEA,SAAO,UAAU,GAAG,iCAAiC,QAAQ,gBAAgB,QAAQ,EAAE;AACzF;;;ADlBA,SAAS,iBAAiB,SAAyB;AACjD,QAAM,cAAc,QAAQ,MAAM,GAAG,EAAE,IAAI,KAAK;AAChD,QAAM,YAAY,YACf,KAAK,EACL,QAAQ,8BAA8B,GAAG,EACzC,QAAQ,OAAO,GAAG,EAClB,QAAQ,kBAAkB,EAAE;AAC/B,SAAO,UAAU,SAAS,IAAI,YAAY;AAC5C;AAEA,eAAe,yBAAsD;AACnE,QAAM,oBAAoB,uBAAuB;AACjD,MAAI,CAAC,kBAAkB,IAAI;AACzB,WAAO;AAAA,EACT;AAEA,MAAI;AACF,UAAM,UAAU,MAAS,aAAS,kBAAkB,OAAO,MAAM;AACjE,UAAM,SAAS,KAAK,MAAM,OAAO;AACjC,QAAI,OAAO,OAAO,SAAS,YAAY,OAAO,KAAK,KAAK,EAAE,WAAW,GAAG;AACtE,aAAO;AAAA,QACL;AAAA,QACA,mBAAmB,kBAAkB,KAAK;AAAA,MAC5C;AAAA,IACF;AACA,WAAO,WAAW,iBAAiB,OAAO,IAAI,CAAC;AAAA,EACjD,SAAS,OAAO;AACd,UAAM,UAAU,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AACrE,WAAO;AAAA,MACL;AAAA,MACA,oCAAoC,kBAAkB,KAAK,KAAK,OAAO;AAAA,IACzE;AAAA,EACF;AACF;AAEA,eAAe,mBAAoC;AACjD,MAAI,QAAQ,aAAa,SAAS;AAChC,WAAO,QAAQ,IAAI,WAAgB,WAAQ,WAAQ,GAAG,WAAW,SAAS;AAAA,EAC5E;AAEA,SAAO,QAAQ,IAAI,mBAAwB,WAAQ,WAAQ,GAAG,SAAS;AACzE;AAEA,eAAsB,wBAEpB;AACA,QAAM,gBAAgB,MAAM,uBAAuB;AACnD,MAAI,CAAC,cAAc,IAAI;AACrB,WAAO;AAAA,EACT;AAEA,QAAM,UAAU,MAAM,iBAAiB;AACvC,QAAM,YAAiB,WAAK,SAAS,cAAc,KAAK;AACxD,SAAO,WAAW;AAAA,IAChB,aAAa,cAAc;AAAA,IAC3B;AAAA,IACA,gBAAqB,WAAK,WAAW,GAAG,cAAc,KAAK,OAAO;AAAA,EACpE,CAAC;AACH;AAEO,SAAS,gBACd,YACwB;AACxB,MAAI,MAAM,QAAQ,UAAU,GAAG;AAC7B,WAAO,WAAW,MAAM;AAAA,EAC1B;AAEA,QAAM,WAAmC,CAAC;AAC1C,QAAM,UAAU;AAChB,aAAW,QAAQ,SAAS,CAAC,OAAO,UAAU;AAC5C,QAAI,UAAU,QAAW;AACvB,eAAS,KAAK,OAAO,KAAK,CAAC;AAAA,IAC7B,OAAO;AACL,eAAS,KAAK,KAAK;AAAA,IACrB;AACA,WAAO;AAAA,EACT,CAAC;AACD,SAAO;AACT;AAEA,SAAS,YACP,OACmD;AACnD,SAAO,OAAO,UAAU,YAAY,UAAU;AAChD;AAEA,SAAS,sBACP,OACkC;AAClC,SAAO;AACT;AAEA,SAAS,eACP,QACA,YACA,cACG;AACH,QAAM,WAAW,gBAAgB,UAAU;AAC3C,MAAI,SAAS,WAAW,GAAG;AACzB,WAAQ,WAAW,SAAY,eAAe;AAAA,EAChD;AAEA,MAAI,UAAmB;AACvB,aAAW,WAAW,UAAU;AAC9B,QAAI,CAAC,YAAY,OAAO,GAAG;AACzB,aAAO;AAAA,IACT;AACA,cAAU,sBAAsB,OAAO,EAAE,OAAO;AAChD,QAAI,YAAY,QAAW;AACzB,aAAO;AAAA,IACT;AAAA,EACF;AAEA,SAAQ,YAAY,SAAY,eAAe;AACjD;AAEA,SAAS,oBACP,aAC0C;AAC1C,SAAO,OAAO,gBAAgB,WAAW,CAAC,IAAI,CAAC;AACjD;AAEA,SAAS,eACP,QACA,YACA,OACM;AACN,QAAM,WAAW,gBAAgB,UAAU;AAC3C,MAAI,SAAS,WAAW,GAAG;AACzB;AAAA,EACF;AAEA,MAAI,UAAoD;AACxD,WAAS,QAAQ,GAAG,QAAQ,SAAS,QAAQ,SAAS;AACpD,UAAM,UAAU,SAAS,KAAK;AAC9B,UAAM,SAAS,UAAU,SAAS,SAAS;AAC3C,UAAM,mBAAmB,sBAAsB,OAAO;AAEtD,QAAI,QAAQ;AACV,uBAAiB,OAAO,IAAI;AAC5B;AAAA,IACF;AAEA,UAAM,cAAc,SAAS,QAAQ,CAAC;AACtC,UAAM,WAAW,iBAAiB,OAAO;AACzC,QAAI,CAAC,YAAY,QAAQ,GAAG;AAC1B,uBAAiB,OAAO,IAAI,oBAAoB,WAAW;AAAA,IAC7D;AACA,cAAU,iBAAiB,OAAO;AAAA,EAGpC;AACF;AAEA,eAAe,iBACb,gBAC2B;AAC3B,MAAI;AACF,UAAS,UAAW,cAAQ,cAAc,GAAG,EAAE,WAAW,KAAK,CAAC;AAChE,UAAS,WAAO,cAAc,EAAE,MAAM,YAAY;AAChD,YAAS,cAAU,gBAAgB,QAAQ,MAAM;AAAA,IACnD,CAAC;AACD,WAAO,WAAW,MAAS;AAAA,EAC7B,SAAS,OAAO;AACd,UAAM,UAAU,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AACrE,WAAO;AAAA,MACL;AAAA,MACA,gCAAgC,cAAc,KAAK,OAAO;AAAA,IAC5D;AAAA,EACF;AACF;AAEA,eAAsB,aAEM;AAC1B,QAAM,iBAAiB,MAAM,sBAAsB;AACnD,MAAI,CAAC,eAAe,IAAI;AACtB,WAAO;AAAA,EACT;AAEA,QAAM,eAAe,MAAM;AAAA,IACzB,eAAe,MAAM;AAAA,EACvB;AACA,MAAI,CAAC,aAAa,IAAI;AACpB,WAAO;AAAA,EACT;AAEA,MAAI;AACF,UAAM,UAAU,MAAS;AAAA,MACvB,eAAe,MAAM;AAAA,MACrB;AAAA,IACF;AACA,QAAI,QAAQ,KAAK,EAAE,WAAW,GAAG;AAC/B,aAAO,WAAW,CAAC,CAAM;AAAA,IAC3B;AACA,WAAO,WAAW,KAAK,MAAM,OAAO,CAAM;AAAA,EAC5C,SAAS,OAAO;AACd,UAAM,UAAU,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AACrE,WAAO;AAAA,MACL;AAAA,MACA,8BAA8B,eAAe,MAAM,cAAc,KAAK,OAAO;AAAA,IAC/E;AAAA,EACF;AACF;AAEA,eAAsB,YACpB,QAC2B;AAC3B,QAAM,iBAAiB,MAAM,sBAAsB;AACnD,MAAI,CAAC,eAAe,IAAI;AACtB,WAAO;AAAA,EACT;AAEA,QAAM,eAAe,MAAM;AAAA,IACzB,eAAe,MAAM;AAAA,EACvB;AACA,MAAI,CAAC,aAAa,IAAI;AACpB,WAAO;AAAA,EACT;AAEA,MAAI;AACF,UAAM,UAAU,GAAG,KAAK,UAAU,QAAQ,MAAM,CAAC,CAAC;AAAA;AAClD,UAAS,cAAU,eAAe,MAAM,gBAAgB,SAAS,MAAM;AACvE,WAAO,WAAW,MAAS;AAAA,EAC7B,SAAS,OAAO;AACd,UAAM,UAAU,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AACrE,WAAO;AAAA,MACL;AAAA,MACA,6BAA6B,eAAe,MAAM,cAAc,KAAK,OAAO;AAAA,IAC9E;AAAA,EACF;AACF;AAEA,eAAsB,gBACpB,YACA,cACwB;AACxB,QAAM,eAAe,MAAM,WAAoC;AAC/D,MAAI,CAAC,aAAa,IAAI;AACpB,WAAO;AAAA,EACT;AAEA,SAAO;AAAA,IACL,eAAe,aAAa,OAAO,YAAY,YAAY;AAAA,EAC7D;AACF;AAEA,eAAsB,iBACpB,YACA,OAC2B;AAC3B,QAAM,eAAe,MAAM,WAAoC;AAC/D,MAAI,CAAC,aAAa,IAAI;AACpB,WAAO;AAAA,EACT;AAEA,iBAAe,aAAa,OAAO,YAAY,KAAK;AACpD,SAAO,YAAY,aAAa,KAAK;AACvC;;;AE5QA,IAAM,2BAA2B,CAAC,UAAU,OAAO;AAEnD,eAAsB,iBACpB,QACA,OAC2B;AAC3B,SAAO,iBAAiB,CAAC,GAAG,0BAA0B,MAAM,GAAG,KAAK;AACtE;AAEA,eAAsB,gBACpB,QACyC;AACzC,SAAO,gBAAgB,CAAC,GAAG,0BAA0B,MAAM,CAAC;AAC9D;;;AHJO,IAAM,2BAAN,cAAuC,YAAuC;AAAA,EACzE,QAAsB;AAC9B,WAAO;AAAA,MACL,MAAM;AAAA,MACN,aAAa;AAAA,IACf;AAAA,EACF;AAAA,EAEU,oBAAoB,KAAoB;AAChD,QAAI,SAAS,WAAW,uCAAmB;AAAA,EAC7C;AAAA,EAEU,kBAAkB,KAAoB;AAC9C,QAAI;AAAA,MACF,IAAIC,QAAO,yBAAyB,gCAAY,EAC7C,QAAQ,CAAC,MAAM,MAAM,CAAC,EACtB,oBAAoB;AAAA,IACzB;AAAA,EACF;AAAA,EAEA,MAAgB,SACd,KAC2B;AAC3B,UAAM,QAAQ,IAAI,KAAK,CAAC;AACxB,UAAM,EAAE,OAAO,IAAI,IAAI;AAEvB,UAAM,SAAS,MAAM,iBAAiB,QAAQ,KAAK;AACnD,QAAI,CAAC,OAAO,IAAI;AACd,aAAO,KAAK,WAAW,OAAO,MAAM,OAAO,GAAG;AAAA,IAChD;AAEA,SAAK,cAAc;AAAA,MACjB;AAAA,MACA,QAAQ;AAAA,IACV,CAAC;AACD,WAAO,KAAK,QAAQ;AAAA,EACtB;AACF;;;AIjDA,SAAS,UAAAC,eAAc;;;ACCvB,IAAMC,QAAO;AAEN,IAAK,qBAAL,CAAKC,uBAAL;AACL,EAAAA,sCAAA,kBAAeD,QAAO,KAAtB;AACA,EAAAC,sCAAA,wBAAqBD,QAAO,KAA5B;AACA,EAAAC,sCAAA,0BAAuBD,QAAO,KAA9B;AACA,EAAAC,sCAAA,yBAAsBD,QAAO,KAA7B;AACA,EAAAC,sCAAA,0BAAuBD,QAAO,KAA9B;AACA,EAAAC,sCAAA,wBAAqBD,QAAO,KAA5B;AACA,EAAAC,sCAAA,qBAAkBD,QAAO,KAAzB;AACA,EAAAC,sCAAA,wBAAqBD,QAAO,KAA5B;AACA,EAAAC,sCAAA,mBAAgBD,QAAO,KAAvB;AACA,EAAAC,sCAAA,wBAAqBD,QAAO,MAA5B;AAVU,SAAAC;AAAA,GAAA;AAaL,IAAM,oBAAoB;AAAA,EAC/B,kBAAkB;AAAA,EAClB;AACF;AAEO,IAAM,qBAAqB;AAAA,EAChC,kBAAkB;AAAA,EAClB;AACF;AAEO,IAAM,4BACX;AAEK,IAAM,0BAA0B;AAAA,EACrC,kBAAkB;AAAA,EAClB,8IACE;AACJ;AAEO,IAAM,0BAA0B;AAAA,EACrC,kBAAkB;AAAA,EAClB,0JACE;AACJ;AAEO,IAAMC,6BAA4B;AAAA,EACvC,kBAAkB;AAAA,EAClB;AACF;AAEO,IAAM,2BAA2B;AAAA,EACtC,kBAAkB;AAAA,EAClB;AACF;AAEO,IAAM,4BAA4B;AAAA,EACvC,kBAAkB;AAAA,EAClB;AACF;AAEO,IAAM,0BAA0B;AAAA,EACrC,kBAAkB;AAAA,EAClB;AACF;AAEO,IAAM,uBAAuB;AAAA,EAClC,kBAAkB;AAAA,EAClB;AACF;AAEO,IAAM,0BAA0B;AAAA,EACrC,kBAAkB;AAAA,EAClB;AACF;;;ACxDO,SAAS,eAAe,OAAuB;AACpD,QAAM,UAAU,MAAM,KAAK;AAC3B,QAAM,SAAS;AACf,MAAI,QAAQ,WAAW,MAAM,GAAG;AAC9B,WAAO,QAAQ,MAAM,OAAO,MAAM,EAAE,KAAK;AAAA,EAC3C;AACA,SAAO;AACT;AAEO,SAAS,cAAc,OAAe,SAAsB;AACjE,SAAO;AAAA,IACL,QAAQ;AAAA,IACR,mBAAmB;AAAA,IACnB,eAAe;AAAA,IACf,gBAAgB;AAAA,IAChB,aACE;AAAA,IACF,oBAAoB;AAAA,IACpB,sBAAsB;AAAA,IACtB,kBAAkB;AAAA,IAClB,kBAAkB;AAAA,IAClB,kBAAkB;AAAA,IAClB,oBAAoB;AAAA,IACpB,QAAQ,2BAA2B,eAAe,KAAK,CAAC;AAAA,IACxD,SAAS;AAAA,EACX;AACF;AAEA,eAAsB,YACpB,KACA,SACwB;AACxB,MAAI;AACJ,MAAI;AACF,UAAM,MAAM,MAAM,KAAK,OAAO;AAAA,EAChC,SAAS,OAAO;AACd,WAAOC;AAAA,MACL,iBAAiB,QAAQ,QAAQ;AAAA,IACnC;AAAA,EACF;AAEA,MAAI,IAAI,WAAW,OAAO,IAAI,WAAW,KAAK;AAC5C,YAAQ,QAAQ,qBAAqB,yBAAyB;AAAA,EAChE;AAEA,MAAI,CAAC,IAAI,IAAI;AACX,WAAOA;AAAA,MACL,IAAI,MAAM,QAAQ,IAAI,MAAM,IAAI,IAAI,UAAU,EAAE;AAAA,IAClD;AAAA,EACF;AAEA,MAAI;AACF,WAAO,WAAY,MAAM,IAAI,KAAK,CAAO;AAAA,EAC3C,SAAS,OAAO;AACd,WAAO,yBAAyB,iBAAiB,QAAQ,QAAQ,MAAS;AAAA,EAC5E;AACF;AAEO,SAAS,kBACd,kBACA,WACwC;AACxC,QAAM,cAAc,KAAK,IAAI;AAC7B,SAAO;AAAA,IACL,WAAW,OAAO,cAAc,MAAO,KAAK,KAAK,KAAK,gBAAgB;AAAA,IACtE,SAAS,OAAO,cAAc,MAAO,KAAK,KAAK,KAAK,SAAS;AAAA,EAC/D;AACF;AAEO,SAAS,mBAAmB,OAAqC;AACtE,MAAI,OAAO,UAAU,UAAU;AAC7B,QAAI;AACF,aAAO,WAAW,KAAK,MAAM,KAAK,CAAY;AAAA,IAChD,SAAS,OAAO;AACd,aAAO;AAAA,QACL,iBAAiB,QAAQ,QAAQ;AAAA,MACnC;AAAA,IACF;AAAA,EACF;AAEA,MAAI,UAAU,QAAQ,OAAO,UAAU,UAAU;AAC/C,WAAO,WAAW,KAAK;AAAA,EACzB;AAEA,SAAO,qBAAqB;AAC9B;AAEO,SAAS,iBACd,OACyB;AACzB,SAAO,MAAM,SAAS,CAAC,SAAS;AAC9B,WACE,MAAM,SAAS,WAAW,MAAM,iBAAiB;AAAA,EAErD,CAAC;AACH;;;ACtFA,IAAM,SAAS;AAAA,EACb,UAAU;AAAA,EACV,cAAc;AAAA,EACd,mBAAmB;AAAA,EACnB,UAAU;AAAA,EACV,YAAY;AAAA,EACZ,eAAe;AAAA,EACf,WAAW;AACb;AAOA,SAAS,kBACP,WACA,WACA,QACA,WACA,WAAW,OACX;AACA,SAAO;AAAA,IACL,YAAY;AAAA,IACZ,YAAY;AAAA,IACZ;AAAA,IACA,YAAY;AAAA,IACZ,cAAc;AAAA,IACd,WAAW;AAAA,IACX,YAAY;AAAA,MACV,cAAc;AAAA,MACd,eAAe,CAAC;AAAA,IAClB;AAAA,EACF;AACF;AAEA,SAAS,eAAe,OAA+C;AACrE,MAAI;AACJ,aAAW,QAAQ,OAAO;AACxB,QAAI,OAAO,KAAK,YAAY,YAAY,OAAO,KAAK,aAAa,UAAU;AACzE;AAAA,IACF;AACA,QACE,CAAC,aACA,KAAK,YAAY,cAAc,SAAS,YAAY,YACrD;AACA,iBAAW;AAAA,IACb;AAAA,EACF;AACA,SAAO;AACT;AAEA,SAAS,eAAuB;AAC9B,SAAO,GAAG,OAAO,QAAQ;AAC3B;AAEA,SAAS,mBAA2B;AAClC,SAAO,aAAa;AACtB;AAEA,SAAS,gBAAwD;AAC/D,SAAO,kBAAkB,OAAO,UAAU,OAAO,UAAU;AAC7D;AAEA,SAAS,cAAc,OAAuB;AAC5C,QAAM,EAAE,WAAW,QAAQ,IAAI,cAAc;AAC7C,SAAO,KAAK,UAAU;AAAA,IACpB,cAAc,OAAO;AAAA,IACrB,YAAY;AAAA,IACZ,UAAU;AAAA,IACV,SAAS;AAAA,MACP,cAAc;AAAA,MACd,eAAe;AAAA,QACb,kBAAkB,kBAAkB,UAAU,CAAC,KAAK,GAAG,QAAQ;AAAA,QAC/D,kBAAkB,OAAO,UAAU,CAAC,uBAAuB,GAAG,IAAI;AAAA,QAClE,kBAAkB,SAAS,UAAU,CAAC,KAAK,GAAG,IAAI;AAAA,MACpD;AAAA,IACF;AAAA,IACA,WAAW,OAAO;AAAA,IAClB,WAAW;AAAA,MACT;AAAA,QACE,OAAO;AAAA,QACP,QAAQ;AAAA,MACV;AAAA,IACF;AAAA,IACA,eAAe,OAAO;AAAA,IACtB,gBAAgB;AAAA,EAClB,CAAC;AACH;AAEA,SAAS,aAAqB;AAC5B,SAAO,GAAG,OAAO,QAAQ;AAC3B;AAEA,SAAS,aAAa,SAAiB,QAAwB;AAC7D,QAAM,EAAE,WAAW,QAAQ,IAAI,cAAc;AAC7C,SAAO,GAAG,OAAO,QAAQ,+BAA+B,OAAO,iBAAiB,OAAO,YAAY,eAAe,SAAS,aAAa,OAAO,kBAAkB,OAAO,aAAa,aAAa,MAAM;AAC1M;AAEA,eAAsB,YACpB,SACwC;AACxC,QAAM,EAAE,MAAM,IAAI;AAClB,MAAI,CAAC,OAAO;AACV,WAAO,kBAAkB;AAAA,EAC3B;AAEA,QAAM,cAAc,MAAM,6BAAyB;AACnD,MAAI,CAAC,YAAY,IAAI;AACnB,WAAO;AAAA,EACT;AAEA,QAAM,QAAQ,YAAY,OAAO,KAAK;AACtC,MAAI,CAAC,OAAO;AACV,WAAO,wBAAwB;AAAA,EACjC;AAEA,QAAM,eAAe,MAAM,YAAgC,aAAa,GAAG;AAAA,IACzE,QAAQ;AAAA,IACR,SAAS,cAAc,OAAO,iBAAiB,CAAC;AAAA,IAChD,MAAM,cAAc,KAAK;AAAA,IACzB,mBAAmB;AAAA,EACrB,CAAC;AACD,MAAI,CAAC,aAAa,IAAI;AACpB,WAAO;AAAA,EACT;AAEA,QAAM,cAAc,aAAa,MAAM,SAAS,CAAC;AACjD,MAAI,YAAY,WAAW,GAAG;AAC5B,WAAO,0BAA0B;AAAA,EACnC;AAEA,QAAM,WAAW,eAAe,WAAW;AAC3C,MAAI,CAAC,UAAU,UAAU;AACvB,WAAO,wBAAwB;AAAA,EACjC;AAEA,QAAM,aAAa,MAAM,YAAgC,WAAW,GAAG;AAAA,IACrE,QAAQ;AAAA,IACR,SAAS,cAAc,OAAO,iBAAiB,CAAC;AAAA,IAChD,MAAM,KAAK,UAAU;AAAA,MACnB,cAAc,OAAO;AAAA,MACrB,UAAU,SAAS;AAAA,MACnB,YAAY,cAAc,EAAE;AAAA,MAC5B,UAAU,cAAc,EAAE;AAAA,MAC1B,eAAe,OAAO;AAAA,IACxB,CAAC;AAAA,IACD,mBAAmB;AAAA,EACrB,CAAC;AACD,MAAI,CAAC,WAAW,IAAI;AAClB,WAAO;AAAA,EACT;AAEA,QAAM,aAAa,iBAAiB,WAAW,MAAM,SAAS,CAAC,CAAC;AAChE,MAAI,CAAC,YAAY,YAAY,CAAC,WAAW,SAAS;AAChD,WAAO,wBAAwB;AAAA,EACjC;AAEA,QAAM,eAAe,MAAM;AAAA,IACzB,aAAa,WAAW,UAAU,WAAW,OAAO;AAAA,IACpD;AAAA,MACE,QAAQ;AAAA,MACR,SAAS,cAAc,OAAO,iBAAiB,CAAC;AAAA,MAChD,mBAAmB;AAAA,IACrB;AAAA,EACF;AACA,MAAI,CAAC,aAAa,IAAI;AACpB,WAAO;AAAA,EACT;AAEA,QAAM,UAAU,mBAAmB,aAAa,MAAM,QAAQ,CAAC,GAAG,KAAK;AACvE,MAAI,CAAC,QAAQ,IAAI;AACf,WAAO;AAAA,EACT;AAEA,SAAO,WAAW;AAAA,IAChB,MAAM;AAAA,MACJ;AAAA,MACA,UAAU,WAAW,aAAa;AAAA,IACpC;AAAA,IACA,MAAM,QAAQ;AAAA,EAChB,CAAC;AACH;;;ACtLA,IAAMC,UAAS;AAAA,EACb,UAAU;AAAA,EACV,cAAc;AAAA,EACd,mBAAmB;AAAA,EACnB,UAAU;AAAA,EACV,YAAY;AACd;AAOA,SAASC,gBAAuB;AAC9B,SAAO,GAAGD,QAAO,QAAQ;AAC3B;AAEA,SAASE,kBAAiB,OAAuB;AAC/C,SAAO,GAAGF,QAAO,QAAQ,UAAUA,QAAO,YAAY,6CAA6CA,QAAO,iBAAiB,YAAY,KAAK;AAC9I;AAEA,SAASG,iBAAwD;AAC/D,SAAO,kBAAkBH,QAAO,UAAUA,QAAO,UAAU;AAC7D;AAEA,SAASI,cAAa,SAAiB,QAAwB;AAC7D,QAAM,EAAE,WAAW,QAAQ,IAAID,eAAc;AAC7C,SAAO,GAAGH,QAAO,QAAQ,gCAAgC,OAAO,iBAAiBA,QAAO,YAAY,eAAe,SAAS,aAAa,OAAO,wCAAwC,MAAM;AAChM;AAEA,eAAsB,cACpB,SACwC;AACxC,QAAM,EAAE,MAAM,IAAI;AAClB,MAAI,CAAC,OAAO;AACV,WAAO,kBAAkB;AAAA,EAC3B;AAEA,QAAM,cAAc,MAAM,iCAA2B;AACrD,MAAI,CAAC,YAAY,IAAI;AACnB,WAAO;AAAA,EACT;AAEA,QAAM,QAAQ,YAAY,OAAO,KAAK;AACtC,MAAI,CAAC,OAAO;AACV,WAAO,wBAAwB;AAAA,EACjC;AAEA,QAAM,eAAe,MAAM,YAAgCC,cAAa,GAAG;AAAA,IACzE,QAAQ;AAAA,IACR,SAAS,cAAc,OAAOC,kBAAiB,KAAK,CAAC;AAAA,IACrD,MAAM,KAAK,UAAU;AAAA,MACnB,cAAcF,QAAO;AAAA,MACrB,aAAa;AAAA,MACb,IAAI;AAAA,MACJ,mBAAmBA,QAAO;AAAA,IAC5B,CAAC;AAAA,IACD,mBAAmB;AAAA,EACrB,CAAC;AACD,MAAI,CAAC,aAAa,IAAI;AACpB,WAAO;AAAA,EACT;AAEA,QAAM,aAAa,iBAAiB,aAAa,MAAM,SAAS,CAAC,CAAC;AAClE,MAAI,CAAC,YAAY,YAAY,CAAC,WAAW,SAAS;AAChD,WAAO,0BAA0B;AAAA,EACnC;AAEA,QAAM,eAAe,MAAM;AAAA,IACzBI,cAAa,WAAW,UAAU,WAAW,OAAO;AAAA,IACpD;AAAA,MACE,QAAQ;AAAA,MACR,SAAS,cAAc,OAAOF,kBAAiB,KAAK,CAAC;AAAA,MACrD,mBAAmB;AAAA,IACrB;AAAA,EACF;AACA,MAAI,CAAC,aAAa,IAAI;AACpB,WAAO;AAAA,EACT;AAEA,QAAM,aAAa,iBAAiB,aAAa,MAAM,SAAS,CAAC,CAAC;AAClE,MAAI,CAAC,YAAY,YAAY,CAAC,WAAW,SAAS;AAChD,WAAO,wBAAwB;AAAA,EACjC;AAEA,QAAM,UAAU,mBAAmB,WAAW,KAAK;AACnD,MAAI,CAAC,QAAQ,IAAI;AACf,WAAO;AAAA,EACT;AAEA,SAAO,WAAW;AAAA,IAChB,MAAM;AAAA,MACJ;AAAA,MACA,UAAU,WAAW,aAAa;AAAA,IACpC;AAAA,IACA,MAAM,QAAQ;AAAA,EAChB,CAAC;AACH;;;ACjHA,eAAsB,UACpB,SACwC;AACxC,QAAM,EAAE,OAAO,OAAO,IAAI;AAC1B,MAAI,CAAC,OAAO;AACV,WAAO,kBAAkB;AAAA,EAC3B;AAEA,MAAI,CAAC,QAAQ;AACX,WAAO,mBAAmB;AAAA,EAC5B;AAEA,MAAI,0BAAsB;AACxB,WAAO,YAAY,EAAE,OAAO,OAAO,CAAC;AAAA,EACtC;AAEA,SAAO,cAAc,EAAE,OAAO,OAAO,CAAC;AACxC;;;ALXO,IAAM,+BAAN,cAA2C,YAA2C;AAAA,EACjF,QAAsB;AAC9B,WAAO;AAAA,MACL,MAAM;AAAA,MACN,aAAa;AAAA,IACf;AAAA,EACF;AAAA,EAEU,oBAAoB,KAAoB;AAChD,QAAI,SAAS,YAAY,iCAAa;AAAA,EACxC;AAAA,EAEU,kBAAkB,KAAoB;AAC9C,QAAI;AAAA,MACF,IAAIG,QAAO,yBAAyB,0BAAM,EACvC,QAAQ,CAAC,MAAM,MAAM,CAAC,EACtB,oBAAoB;AAAA,IACzB;AAAA,EACF;AAAA,EAEA,MAAgB,SACd,KAC2B;AAC3B,UAAM,QAAQ,IAAI,KAAK,CAAC;AACxB,UAAM,SAAS,IAAI,QAAQ;AAE3B,UAAM,SAAS,MAAM,UAAU,EAAE,OAAO,OAAO,CAAC;AAChD,QAAI,CAAC,OAAO,IAAI;AACd,WAAK,iBAAiB,OAAO,MAAM,OAAO,GAAG;AAC7C,aAAO,KAAK,QAAQ;AAAA,IACtB;AAEA,SAAK,cAAc,OAAO,KAAK;AAC/B,WAAO,KAAK,QAAQ;AAAA,EACtB;AACF;;;AM1CO,IAAM,gBAAN,cAA4B,mBAAmB;AAAA,EAC1C,QAAsB;AAC9B,WAAO;AAAA,MACL,MAAM;AAAA,MACN,aAAa;AAAA,MACb,SAAS,CAAC,MAAM,KAAK;AAAA,IACvB;AAAA,EACF;AAAA,EAEU,uBAA6B;AACrC,SAAK,eAAe,IAAI,uBAAuB,CAAC;AAChD,SAAK,eAAe,IAAI,yBAAyB,CAAC;AAClD,SAAK,eAAe,IAAI,6BAA6B,CAAC;AAAA,EACxD;AACF;;;AnBdA,IAAMC,WAAU,cAAc,YAAY,GAAG;AAC7C,IAAM,MAAMA,SAAQ,iBAAiB;AASrC,eAAe,YAA2B;AACxC,QAAM,UAAU,OAAO,KAAK,IAAI,GAAG,EAAE,CAAC;AAEtC,QAAM,MAAM,IAAI,OAAO;AAAA,IACrB,MAAM;AAAA,IACN,SAAS,IAAI;AAAA,IACb,aAAa,IAAI;AAAA,EACnB,CAAC;AAED,MAAI,gBAAgB,IAAI,aAAa,GAAG,EAAE,QAAQ,KAAK,CAAC;AACxD,MAAI,gBAAgB,IAAI,cAAc,CAAC;AAEvC,QAAM,SAAS,MAAM,IAAI,IAAI;AAE7B,MAAI,CAAC,OAAO,IAAI;AACd,YAAQ,OAAO,MAAM,UAAU,OAAO,GAAG;AAAA,CAAI;AAC7C,YAAQ,WAAW;AAAA,EACrB;AAEA,MAAI,QAAQ;AACd;AAEA,UAAU;","names":["GetThreadError","Option","fs","path","Option","Option","BASE","FornaxSearchError","networkRequestFailedError","networkRequestFailedError","CONFIG","getSearchUrl","getSearchReferer","getTimeWindow","getDetailUrl","Option","require"]}
1
+ {"version":3,"sources":["../src/main.ts","../src/commands/hello/hello-greet-command.ts","../src/commands/hello/hello-info-command.ts","../src/commands/hello/hello-command.ts","../src/commands/pippit/pippit-get-thread-command.ts","../src/commands/pippit/modules/get-thread/errors.ts","../src/commands/pippit/modules/get-thread/fetch-thread.ts","../src/commands/pippit/modules/get-thread/trim-thread.ts","../src/commands/pippit/modules/get-thread/get-thread.ts","../src/commands/pippit/pippit-fornax-token-command.ts","../src/bedrock/config/local-config.ts","../src/bedrock/pkg/find-closest-package-json.ts","../src/commands/pippit/modules/fornax-token/fornax-token.ts","../src/commands/pippit/pippit-search-fornax-log-command.ts","../src/commands/pippit/modules/search-log/errors.ts","../src/commands/pippit/modules/search-log/common.ts","../src/commands/pippit/modules/search-log/cn-search-log.ts","../src/commands/pippit/modules/search-log/i18n-search-log.ts","../src/commands/pippit/modules/search-log/search-log.ts","../src/commands/pippit/pippit-save-thread-fornax-command.ts","../src/commands/pippit/pippit-command.ts"],"sourcesContent":["#!/usr/bin/env node\n\nimport { createRequire } from \"node:module\";\nimport { CliApp } from \"./core\";\nimport { HelloCommand, PippitCommand } from \"./commands\";\n\nconst require = createRequire(import.meta.url);\nconst pkg = require(\"../package.json\");\n\n/**\n * 注:\n * option 里,boolean 的同时支持长、短选项,短的还可以合并,比如 -fr\n * option 里,字符串的,也同时支持长短,唯独短选项不支持=,只支持空格\n * 子命令,通常最多 3 层,比如 npm config set\n */\n\nasync function bootstrap(): Promise<void> {\n const binName = Object.keys(pkg.bin)[0];\n\n const app = new CliApp({\n name: binName,\n version: pkg.version,\n description: pkg.description,\n });\n\n app.registerCommand(new HelloCommand(), { hidden: true });\n app.registerCommand(new PippitCommand());\n\n const result = await app.run();\n\n if (!result.ok) {\n process.stderr.write(`Fatal: ${result.msg}\\n`);\n process.exitCode = 1;\n }\n\n app.dispose();\n}\n\nbootstrap();\n","import type { Command } from 'commander';\nimport { BaseCommand } from '../../core/base-command';\nimport type { ICommandActionContext } from '../../core/base-command';\nimport type { ICommandMeta } from '../../core/command-types';\nimport type { ILvErrorOr } from '../../bedrock/error';\n\ninterface IHelloGreetOptions {\n uppercase: boolean;\n}\n\nexport class HelloGreetCommand extends BaseCommand<IHelloGreetOptions> {\n protected _meta(): ICommandMeta {\n return {\n name: 'greet',\n description: '向指定用户打招呼',\n };\n }\n\n protected _configureArguments(cmd: Command): void {\n cmd.argument('[name]', '要打招呼的用户名', 'World');\n }\n\n protected _configureOptions(cmd: Command): void {\n cmd.option('-u, --uppercase', '将输出转为大写', false);\n }\n\n protected async _execute(\n ctx: ICommandActionContext<IHelloGreetOptions>,\n ): Promise<ILvErrorOr<void>> {\n const name = ctx.args[0] as string;\n const { uppercase } = ctx.options;\n\n let message = `Hello, ${name}!`;\n if (uppercase) {\n message = message.toUpperCase();\n }\n\n this._outputJsonOk({ message });\n return this._makeOk();\n }\n}\n","import { BaseCommand } from '../../core/base-command';\nimport type { ICommandActionContext } from '../../core/base-command';\nimport type { ICommandMeta } from '../../core/command-types';\nimport type { ILvErrorOr } from '../../bedrock/error';\n\nexport class HelloInfoCommand extends BaseCommand {\n protected _meta(): ICommandMeta {\n return {\n name: 'info',\n description: '显示 hello 命令的相关信息',\n };\n }\n\n protected async _execute(\n _ctx: ICommandActionContext,\n ): Promise<ILvErrorOr<void>> {\n this._outputJsonOk({\n version: '1.0.0',\n description: 'Hello 命令组 - 用于打招呼的示例命令',\n });\n return this._makeOk();\n }\n}\n","import type { ICommandMeta } from '../../core/command-types';\nimport { BaseSubcommandHost } from '../../core/base-subcommand-host';\nimport { HelloGreetCommand } from './hello-greet-command';\nimport { HelloInfoCommand } from './hello-info-command';\n\nexport class HelloCommand extends BaseSubcommandHost {\n protected _meta(): ICommandMeta {\n return {\n name: 'hello',\n description: '向指定用户打招呼 (示例命令组)',\n aliases: ['hi'],\n };\n }\n\n protected _registerSubcommands(): void {\n this._addSubcommand(new HelloGreetCommand());\n this._addSubcommand(new HelloInfoCommand());\n }\n}\n","import { BaseCommand } from \"../../core/base-command\";\nimport type { ICommandActionContext } from \"../../core/base-command\";\nimport type { ICommandMeta } from \"../../core/command-types\";\nimport type { ILvErrorOr } from \"../../bedrock/error\";\nimport { Option, type Command } from \"commander\";\nimport type { Region } from \"./types\";\nimport { getThread } from \"./modules/get-thread\";\n\nexport class PippitGetThreadCommand extends BaseCommand {\n protected _meta(): ICommandMeta {\n return {\n name: \"thread\",\n description: \"获取指定 thread 的详细信息\",\n };\n }\n\n protected _configureArguments(cmd: Command): void {\n cmd.argument(\"<thread_id>\", \"要获取的 thread id\");\n }\n\n protected _configureOptions(cmd: Command): void {\n cmd.addOption(\n new Option(\n \"-r, --region <region>\",\n \"指定区域,缺省时,会多 region 自动尝试,略微会有额外的耗时\",\n ).choices([\"cn\", \"i18n\"]),\n );\n }\n\n protected async _execute(\n _ctx: ICommandActionContext,\n ): Promise<ILvErrorOr<void>> {\n const threadId = _ctx.args[0] as string;\n const region = _ctx.options.region as Region | undefined;\n\n const result = await getThread({ threadId, region });\n\n if (!result.ok) {\n this._outputJsonError(result.code, result.msg);\n return this._makeOk();\n }\n\n this._outputJsonOk(result.value);\n return this._makeOk();\n }\n}\n","import { lvErrorConst } from \"../../../../bedrock/error\";\n\nconst BASE = 10000;\n\nexport enum GetThreadError {\n MissingThreadId = BASE + 1,\n NetworkRequestFailed = BASE + 2,\n ResponseParseFailed = BASE + 3,\n ThreadNotFound = BASE + 4,\n}\n\nexport const missingThreadIdError = lvErrorConst(\n GetThreadError.MissingThreadId,\n \"缺少 thread_id 参数。\",\n);\n\nexport const networkRequestFailedError = lvErrorConst(\n GetThreadError.NetworkRequestFailed,\n \"请求 Pippit API 失败,请确保在内网环境下请求\",\n);\n\nexport const responseParseFailed = lvErrorConst(\n GetThreadError.ResponseParseFailed,\n \"解析 API 响应失败,返回消息的数据格式异常。\",\n);\n\nexport const threadNotFoundError = lvErrorConst(\n GetThreadError.ThreadNotFound,\n \"未找到对应的 thread 数据。\",\n);\n","import type { ILvErrorOr } from \"../../../../bedrock/error\";\nimport { makeOkWith } from \"../../../../bedrock/error\";\nimport { Region } from \"../../types\";\nimport type { IThreadData } from \"./types\";\nimport {\n networkRequestFailedError,\n responseParseFailed,\n threadNotFoundError,\n} from \"./errors\";\n\nconst REGION_URL_MAP: Record<Region, string> = {\n [Region.CN]:\n \"https://pippit-cms.bytedance.net/api/internal/v1/agent/get_thread\",\n [Region.I18N]:\n \"https://pippit-cms.tiktok-row.org/api/internal/v1/agent/get_thread\",\n};\n\nconst REGION_REFERER_MAP: Record<Region, string> = {\n [Region.CN]: \"https://pippit-cms.bytedance.net/\",\n [Region.I18N]: \"https://pippit-cms.tiktok-row.org/\",\n};\n\nexport async function fetchThread(\n threadId: string,\n region: Region,\n): Promise<ILvErrorOr<IThreadData>> {\n const url = REGION_URL_MAP[region];\n const referer = REGION_REFERER_MAP[region];\n\n let res: Response;\n try {\n res = await fetch(url, {\n method: \"POST\",\n headers: {\n accept: \"*/*\",\n \"accept-language\": \"zh-CN,zh;q=0.9,en;q=0.8\",\n appvr: \"1.1.4\",\n \"content-type\": \"application/json\",\n Referer: referer,\n },\n body: JSON.stringify({\n scopes: [\"run_list.entry_list\"],\n thread_id: threadId,\n }),\n });\n } catch (err) {\n return networkRequestFailedError(err instanceof Error ? err : undefined);\n }\n\n let data: any;\n try {\n data = await res.json();\n } catch (err) {\n return responseParseFailed(err instanceof Error ? err : undefined);\n }\n\n const thread = data?.data?.thread as IThreadData | undefined;\n if (!thread?.run_list) {\n return threadNotFoundError();\n }\n\n return makeOkWith(thread);\n}\n","import type { IThreadData, IThreadRun, IThreadMessage, IThreadPart } from \"./types\";\n\nconst RUN_WHITE_KEYS: readonly string[] = [\n \"run_id\",\n \"state\",\n \"agent_name\",\n \"entry_list\",\n \"updated_at\",\n];\n\nconst MESSAGE_WHITE_KEYS: readonly string[] = [\n \"content\",\n \"message_id\",\n \"role\",\n \"run_id\",\n];\n\nconst PART_WHITE_KEYS: readonly string[] = [\"data\", \"sub_type\"];\n\nfunction pickKeys<T extends Record<string, unknown>>(\n obj: T,\n keys: readonly string[],\n): void {\n for (const key of Object.keys(obj)) {\n if (!keys.includes(key)) {\n delete obj[key];\n }\n }\n}\n\nfunction extractLogId(extraStr: string | undefined): string | undefined {\n if (!extraStr) return undefined;\n try {\n const extra = JSON.parse(extraStr);\n return extra?.execute_log_id as string | undefined;\n } catch {\n return undefined;\n }\n}\n\nfunction trimMessage(message: IThreadMessage): void {\n pickKeys(message, MESSAGE_WHITE_KEYS);\n if (Array.isArray(message.content)) {\n for (const part of message.content as IThreadPart[]) {\n pickKeys(part, PART_WHITE_KEYS);\n }\n }\n}\n\nfunction trimRun(run: IThreadRun, isLast: boolean): void {\n const logId = isLast ? extractLogId(run.extra) : undefined;\n\n pickKeys(run, RUN_WHITE_KEYS);\n\n if (logId) {\n run.execute_log_id = logId;\n }\n\n if (!run.entry_list) return;\n\n const messages: IThreadMessage[] = [];\n for (const entry of run.entry_list) {\n const msg = entry.artifact ?? entry.message;\n if (msg) {\n trimMessage(msg);\n messages.push(msg);\n }\n }\n\n run.entry_list.length = 0;\n run.entry_list.push(...(messages as any[]));\n}\n\n/**\n * 对 thread 数据做字段裁剪,只保留关键信息。\n * 会直接修改传入的对象。\n */\nexport function trimThread(thread: IThreadData): void {\n const { run_list } = thread;\n for (let i = 0; i < run_list.length; i++) {\n trimRun(run_list[i], i === run_list.length - 1);\n }\n}\n","import type { ILvErrorOr } from \"../../../../bedrock/error\";\nimport { makeOkWith } from \"../../../../bedrock/error\";\nimport { Region } from \"../../types\";\nimport type { IGetThreadOptions, IGetThreadResult } from \"./types\";\nimport { fetchThread } from \"./fetch-thread\";\nimport { trimThread } from \"./trim-thread\";\nimport {\n GetThreadError,\n missingThreadIdError,\n threadNotFoundError,\n} from \"./errors\";\n\nconst AUTO_DETECT_REGIONS: readonly Region[] = [Region.CN, Region.I18N];\n\n/**\n * 获取 thread 信息。\n *\n * - 指定 region 时直接请求对应区域\n * - 未指定 region 时依次尝试 cn -> i18n\n * - trim 选项控制是否裁剪冗余字段(默认 true)\n */\nexport async function getThread(\n options: IGetThreadOptions,\n): Promise<ILvErrorOr<IGetThreadResult>> {\n const { threadId, region, trim = true } = options;\n\n if (!threadId) {\n return missingThreadIdError();\n }\n\n if (region) {\n return _fetchAndProcess(threadId, region, trim);\n }\n\n let lastNonNotFoundError: ILvErrorOr<IGetThreadResult> | undefined;\n\n for (const r of AUTO_DETECT_REGIONS) {\n const result = await _fetchAndProcess(threadId, r, trim);\n if (result.ok) {\n return result;\n }\n if (result.code !== GetThreadError.ThreadNotFound) {\n lastNonNotFoundError = result;\n }\n }\n\n return lastNonNotFoundError ?? threadNotFoundError();\n}\n\nasync function _fetchAndProcess(\n threadId: string,\n region: Region,\n trim: boolean,\n): Promise<ILvErrorOr<IGetThreadResult>> {\n const result = await fetchThread(threadId, region);\n if (!result.ok) {\n return result;\n }\n\n const thread = result.value;\n if (trim) {\n trimThread(thread);\n }\n\n return makeOkWith({ thread, region });\n}\n","import type { Command } from \"commander\";\nimport { Option } from \"commander\";\nimport { BaseCommand } from \"../../core/base-command\";\nimport type { ICommandActionContext } from \"../../core/base-command\";\nimport type { ICommandMeta } from \"../../core/command-types\";\nimport type { ILvErrorOr } from \"../../bedrock/error\";\nimport { writeFornaxToken } from \"./modules/fornax-token\";\nimport type { Region } from \"./types\";\n\ninterface IPippitFornaxTokenOptions {\n region: Region;\n}\n\nexport class PippitFornaxTokenCommand extends BaseCommand<IPippitFornaxTokenOptions> {\n protected _meta(): ICommandMeta {\n return {\n name: \"fornax-token\",\n description: \"设置 fornax 的 token\",\n };\n }\n\n protected _configureArguments(cmd: Command): void {\n cmd.argument(\"<token>\", \"要写入的 fornax token\");\n }\n\n protected _configureOptions(cmd: Command): void {\n cmd.addOption(\n new Option(\"-r, --region <region>\", \"token 所属区域\")\n .choices([\"cn\", \"i18n\"])\n .makeOptionMandatory(),\n );\n }\n\n protected async _execute(\n ctx: ICommandActionContext<IPippitFornaxTokenOptions>,\n ): Promise<ILvErrorOr<void>> {\n const token = ctx.args[0] as string;\n const { region } = ctx.options;\n\n const result = await writeFornaxToken(region, token);\n if (!result.ok) {\n return this._makeError(result.code, result.msg);\n }\n\n this._outputJsonOk({\n region,\n stored: true,\n });\n return this._makeOk();\n }\n}\n","import * as fs from \"node:fs/promises\";\nimport * as os from \"node:os\";\nimport * as path from \"node:path\";\nimport { findClosestPackageJson } from \"../pkg\";\nimport { makeError, makeOkWith, type ILvErrorOr } from \"../error\";\n\nexport type ConfigPath = string | Array<string | number>;\n\nexport interface IConfigLocation {\n readonly packageName: string;\n readonly configDir: string;\n readonly configFilePath: string;\n}\n\nfunction normalizeAppName(rawName: string): string {\n const lastSegment = rawName.split(\"/\").pop() ?? rawName;\n const sanitized = lastSegment\n .trim()\n .replace(/[<>:\"/\\\\|?*\\u0000-\\u001F]/g, \"-\")\n .replace(/-+/g, \"-\")\n .replace(/^[-.]+|[-.]+$/g, \"\");\n return sanitized.length > 0 ? sanitized : \"app\";\n}\n\nasync function readClosestPackageName(): Promise<ILvErrorOr<string>> {\n const packageJsonResult = findClosestPackageJson();\n if (!packageJsonResult.ok) {\n return packageJsonResult;\n }\n\n try {\n const content = await fs.readFile(packageJsonResult.value, \"utf8\");\n const parsed = JSON.parse(content) as { name?: unknown };\n if (typeof parsed.name !== \"string\" || parsed.name.trim().length === 0) {\n return makeError(\n 1,\n `package.json at ${packageJsonResult.value} does not contain a valid name field`,\n );\n }\n return makeOkWith(normalizeAppName(parsed.name));\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n return makeError(\n 1,\n `failed to read package name from ${packageJsonResult.value}: ${message}`,\n );\n }\n}\n\nasync function getBaseConfigDir(): Promise<string> {\n if (process.platform === \"win32\") {\n return process.env.APPDATA ?? path.join(os.homedir(), \"AppData\", \"Roaming\");\n }\n\n return process.env.XDG_CONFIG_HOME ?? path.join(os.homedir(), \".config\");\n}\n\nexport async function resolveConfigLocation(): Promise<\n ILvErrorOr<IConfigLocation>\n> {\n const appNameResult = await readClosestPackageName();\n if (!appNameResult.ok) {\n return appNameResult;\n }\n\n const baseDir = await getBaseConfigDir();\n const configDir = path.join(baseDir, appNameResult.value);\n return makeOkWith({\n packageName: appNameResult.value,\n configDir,\n configFilePath: path.join(configDir, `${appNameResult.value}.json`),\n });\n}\n\nexport function parseConfigPath(\n configPath: ConfigPath,\n): Array<string | number> {\n if (Array.isArray(configPath)) {\n return configPath.slice();\n }\n\n const segments: Array<string | number> = [];\n const matcher = /[^.[\\]]+|\\[(\\d+)\\]/g;\n configPath.replace(matcher, (match, index) => {\n if (index !== undefined) {\n segments.push(Number(index));\n } else {\n segments.push(match);\n }\n return \"\";\n });\n return segments;\n}\n\nfunction isContainer(\n value: unknown,\n): value is Record<string, unknown> | Array<unknown> {\n return typeof value === \"object\" && value !== null;\n}\n\nfunction getIndexableContainer(\n value: Record<string, unknown> | Array<unknown>,\n): Record<string | number, unknown> {\n return value as Record<string | number, unknown>;\n}\n\nfunction getConfigValue<T>(\n source: unknown,\n configPath: ConfigPath,\n defaultValue?: T,\n): T {\n const segments = parseConfigPath(configPath);\n if (segments.length === 0) {\n return (source === undefined ? defaultValue : source) as T;\n }\n\n let current: unknown = source;\n for (const segment of segments) {\n if (!isContainer(current)) {\n return defaultValue as T;\n }\n current = getIndexableContainer(current)[segment];\n if (current === undefined) {\n return defaultValue as T;\n }\n }\n\n return (current === undefined ? defaultValue : current) as T;\n}\n\nfunction createNextContainer(\n nextSegment: string | number | undefined,\n): Record<string, unknown> | Array<unknown> {\n return typeof nextSegment === \"number\" ? [] : {};\n}\n\nfunction setConfigValue(\n target: Record<string, unknown>,\n configPath: ConfigPath,\n value: unknown,\n): void {\n const segments = parseConfigPath(configPath);\n if (segments.length === 0) {\n return;\n }\n\n let current: Record<string, unknown> | Array<unknown> = target;\n for (let index = 0; index < segments.length; index++) {\n const segment = segments[index];\n const isLast = index === segments.length - 1;\n const currentIndexable = getIndexableContainer(current);\n\n if (isLast) {\n currentIndexable[segment] = value;\n return;\n }\n\n const nextSegment = segments[index + 1];\n const existing = currentIndexable[segment];\n if (!isContainer(existing)) {\n currentIndexable[segment] = createNextContainer(nextSegment);\n }\n current = currentIndexable[segment] as\n | Record<string, unknown>\n | Array<unknown>;\n }\n}\n\nasync function ensureConfigFile(\n configFilePath: string,\n): Promise<ILvErrorOr<void>> {\n try {\n await fs.mkdir(path.dirname(configFilePath), { recursive: true });\n await fs.access(configFilePath).catch(async () => {\n await fs.writeFile(configFilePath, \"{}\\n\", \"utf8\");\n });\n return makeOkWith(undefined);\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n return makeError(\n 1,\n `failed to ensure config file ${configFilePath}: ${message}`,\n );\n }\n}\n\nexport async function readConfig<\n T extends Record<string, unknown> = Record<string, unknown>,\n>(): Promise<ILvErrorOr<T>> {\n const locationResult = await resolveConfigLocation();\n if (!locationResult.ok) {\n return locationResult;\n }\n\n const ensureResult = await ensureConfigFile(\n locationResult.value.configFilePath,\n );\n if (!ensureResult.ok) {\n return ensureResult;\n }\n\n try {\n const content = await fs.readFile(\n locationResult.value.configFilePath,\n \"utf8\",\n );\n if (content.trim().length === 0) {\n return makeOkWith({} as T);\n }\n return makeOkWith(JSON.parse(content) as T);\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n return makeError(\n 1,\n `failed to read config from ${locationResult.value.configFilePath}: ${message}`,\n );\n }\n}\n\nexport async function writeConfig<T extends Record<string, unknown>>(\n config: T,\n): Promise<ILvErrorOr<void>> {\n const locationResult = await resolveConfigLocation();\n if (!locationResult.ok) {\n return locationResult;\n }\n\n const ensureResult = await ensureConfigFile(\n locationResult.value.configFilePath,\n );\n if (!ensureResult.ok) {\n return ensureResult;\n }\n\n try {\n const content = `${JSON.stringify(config, null, 2)}\\n`;\n await fs.writeFile(locationResult.value.configFilePath, content, \"utf8\");\n return makeOkWith(undefined);\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n return makeError(\n 1,\n `failed to write config to ${locationResult.value.configFilePath}: ${message}`,\n );\n }\n}\n\nexport async function readConfigValue<T = unknown>(\n configPath: ConfigPath,\n defaultValue?: T,\n): Promise<ILvErrorOr<T>> {\n const configResult = await readConfig<Record<string, unknown>>();\n if (!configResult.ok) {\n return configResult;\n }\n\n return makeOkWith(\n getConfigValue(configResult.value, configPath, defaultValue),\n );\n}\n\nexport async function writeConfigValue<T = unknown>(\n configPath: ConfigPath,\n value: T,\n): Promise<ILvErrorOr<void>> {\n const configResult = await readConfig<Record<string, unknown>>();\n if (!configResult.ok) {\n return configResult;\n }\n\n setConfigValue(configResult.value, configPath, value);\n return writeConfig(configResult.value);\n}\n","import * as path from 'node:path';\nimport * as fs from 'node:fs';\nimport { fileURLToPath } from 'node:url';\nimport { makeOkWith, makeError } from '../error/error-t';\nimport type { ILvErrorOr } from '../error/error-base';\n\nconst _thisDir = path.dirname(fileURLToPath(import.meta.url));\nconst DEFAULT_MAX_DEPTH = 10;\n\n/**\n * 从当前文件所在目录向上查找最近的 package.json 文件\n * @param maxDepth 最多向上遍历的层级数,缺省为 10\n */\nexport function findClosestPackageJson(\n maxDepth: number = DEFAULT_MAX_DEPTH,\n): ILvErrorOr<string> {\n let currentDir = _thisDir;\n\n for (let i = 0; i < maxDepth; i++) {\n const candidate = path.join(currentDir, 'package.json');\n if (fs.existsSync(candidate)) {\n return makeOkWith(candidate);\n }\n\n const parentDir = path.dirname(currentDir);\n if (parentDir === currentDir) {\n break;\n }\n currentDir = parentDir;\n }\n\n return makeError(1, `package.json not found within ${maxDepth} levels from ${_thisDir}`);\n}\n","import { readConfigValue, writeConfigValue } from \"../../../../bedrock/config\";\nimport type { ILvErrorOr } from \"../../../../bedrock/error\";\nimport type { Region } from \"../../types\";\n\nconst FORNAX_TOKEN_CONFIG_PATH = [\"fornax\", \"token\"] as const;\n\nexport async function writeFornaxToken(\n region: Region,\n token: string,\n): Promise<ILvErrorOr<void>> {\n return writeConfigValue([...FORNAX_TOKEN_CONFIG_PATH, region], token);\n}\n\nexport async function readFornaxToken(\n region: Region,\n): Promise<ILvErrorOr<string | undefined>> {\n return readConfigValue([...FORNAX_TOKEN_CONFIG_PATH, region]);\n}\n","import type { Command } from \"commander\";\nimport { Option } from \"commander\";\nimport { BaseCommand } from \"../../core/base-command\";\nimport type { ICommandActionContext } from \"../../core/base-command\";\nimport type { ICommandMeta } from \"../../core/command-types\";\nimport type { ILvErrorOr } from \"../../bedrock/error\";\nimport { searchLog } from \"./modules/search-log\";\nimport type { Region } from \"./types\";\n\ninterface IPippitSearchFornaxLogOptions {\n region: Region;\n}\n\nexport class PippitSearchFornaxLogCommand extends BaseCommand<IPippitSearchFornaxLogOptions> {\n protected _meta(): ICommandMeta {\n return {\n name: \"fornax\",\n description: \"从 fornax 中获取并解析 log 数据\",\n };\n }\n\n protected _configureArguments(cmd: Command): void {\n cmd.argument(\"<log_id>\", \"要获取的 log id\");\n }\n\n protected _configureOptions(cmd: Command): void {\n cmd.addOption(\n new Option(\"-r, --region <region>\", \"指定区域\")\n .choices([\"cn\", \"i18n\"])\n .makeOptionMandatory(),\n );\n }\n\n protected async _execute(\n ctx: ICommandActionContext<IPippitSearchFornaxLogOptions>,\n ): Promise<ILvErrorOr<void>> {\n const logId = ctx.args[0] as string;\n const region = ctx.options.region;\n\n const result = await searchLog({ logId, region });\n if (!result.ok) {\n this._outputJsonError(result.code, result.msg);\n return this._makeOk();\n }\n\n this._outputJsonOk(result.value);\n return this._makeOk();\n }\n}\n","import { lvErrorConst } from \"../../../../bedrock/error\";\n\nconst BASE = 11000;\n\nexport enum FornaxSearchError {\n MissingLogId = BASE + 1,\n MissingFornaxToken = BASE + 2,\n NetworkRequestFailed = BASE + 3,\n ResponseParseFailed = BASE + 4,\n SearchResultNotFound = BASE + 5,\n DetailSpanNotFound = BASE + 6,\n PayloadNotFound = BASE + 7,\n PayloadParseFailed = BASE + 8,\n MissingRegion = BASE + 9,\n ExpiredFornaxToken = BASE + 10,\n}\n\nexport const missingLogIdError = lvErrorConst(\n FornaxSearchError.MissingLogId,\n \"缺少 log_id 参数。\",\n);\n\nexport const missingRegionError = lvErrorConst(\n FornaxSearchError.MissingRegion,\n \"缺少 region 参数,请显式指定 cn 或 i18n。\",\n);\n\nexport const howToConfigureFornaxToken =\n \"关于如何获取 token: 国内访问 https://fornax.bytedance.net/ 海外访问 https://fornax-i18n.byteintl.net/,然后拷贝 cookie 里的 prompt-platform-session\";\n\nexport const missingFornaxTokenError = lvErrorConst(\n FornaxSearchError.MissingFornaxToken,\n \"缺少可用的 fornax-token,请先使用 `tt pippit fornax-token -r <region> <token>` 配置。\" +\n howToConfigureFornaxToken,\n);\n\nexport const expiredFornaxTokenError = lvErrorConst(\n FornaxSearchError.ExpiredFornaxToken,\n \"fornax-token 可能已失效,请先使用 `tt pippit fornax-token -r <region> <token>` 重新配置。\" +\n howToConfigureFornaxToken,\n);\n\nexport const networkRequestFailedError = lvErrorConst(\n FornaxSearchError.NetworkRequestFailed,\n \"请求 fornax API 失败,请确保在内网环境下请求。\",\n);\n\nexport const responseParseFailedError = lvErrorConst(\n FornaxSearchError.ResponseParseFailed,\n \"解析 fornax API 响应失败,返回消息的数据格式异常。\",\n);\n\nexport const searchResultNotFoundError = lvErrorConst(\n FornaxSearchError.SearchResultNotFound,\n \"未找到符合条件的 fornax 记录。\",\n);\n\nexport const detailSpanNotFoundError = lvErrorConst(\n FornaxSearchError.DetailSpanNotFound,\n \"未找到可用于读取数据的 span。\",\n);\n\nexport const payloadNotFoundError = lvErrorConst(\n FornaxSearchError.PayloadNotFound,\n \"未找到 span 的 input 数据。\",\n);\n\nexport const payloadParseFailedError = lvErrorConst(\n FornaxSearchError.PayloadParseFailed,\n \"解析 span payload 失败。\",\n);\n","import { makeOkWith, type ILvErrorOr } from \"../../../../bedrock/error\";\nimport {\n expiredFornaxTokenError,\n networkRequestFailedError,\n payloadNotFoundError,\n payloadParseFailedError,\n responseParseFailedError,\n} from \"./errors\";\nimport type { IFornaxSpan } from \"./types\";\n\nexport interface IJsonRequestOptions extends RequestInit {\n unauthorizedError?: () => ILvErrorOr<never>;\n}\n\nexport function normalizeToken(token: string): string {\n const trimmed = token.trim();\n const prefix = \"prompt-platform-session=\";\n if (trimmed.startsWith(prefix)) {\n return trimmed.slice(prefix.length).trim();\n }\n return trimmed;\n}\n\nexport function createHeaders(token: string, referer: string): any {\n return {\n accept: \"application/json, text/plain, */*\",\n \"accept-language\": \"zh-CN,zh;q=0.9,en;q=0.8\",\n \"agw-js-conv\": \"str\",\n \"content-type\": \"application/json\",\n \"sec-ch-ua\":\n '\"Chromium\";v=\"146\", \"Not-A.Brand\";v=\"24\", \"Google Chrome\";v=\"146\"',\n \"sec-ch-ua-mobile\": \"?0\",\n \"sec-ch-ua-platform\": '\"macOS\"',\n \"sec-fetch-dest\": \"empty\",\n \"sec-fetch-mode\": \"cors\",\n \"sec-fetch-site\": \"same-origin\",\n \"x-requested-with\": \"XMLHttpRequest\",\n cookie: `prompt-platform-session=${normalizeToken(token)}`,\n Referer: referer,\n };\n}\n\nexport async function requestJson<T>(\n url: string,\n options: IJsonRequestOptions,\n): Promise<ILvErrorOr<T>> {\n let res: Response;\n try {\n res = await fetch(url, options);\n } catch (error) {\n return networkRequestFailedError(\n error instanceof Error ? error : undefined,\n );\n }\n\n if (res.status === 401 || res.status === 403) {\n return (options.unauthorizedError ?? expiredFornaxTokenError)();\n }\n\n if (!res.ok) {\n return networkRequestFailedError(\n new Error(`HTTP ${res.status} ${res.statusText}`),\n );\n }\n\n try {\n return makeOkWith((await res.json()) as T);\n } catch (error) {\n return responseParseFailedError(error instanceof Error ? error : undefined);\n }\n}\n\nexport function resolveTimeWindow(\n baseOffsetInDays: number,\n daysLater: number,\n): { startTime: string; endTime: string } {\n const currentTime = Date.now();\n return {\n startTime: String(currentTime - 1000 * 60 * 60 * 24 * baseOffsetInDays),\n endTime: String(currentTime + 1000 * 60 * 60 * 24 * daysLater),\n };\n}\n\nexport function parseDetailPayload<T>(input: unknown): ILvErrorOr<T> {\n if (typeof input === \"string\") {\n try {\n return makeOkWith(JSON.parse(input) as unknown) as ILvErrorOr<T>;\n } catch (error) {\n return payloadParseFailedError(\n error instanceof Error ? error : undefined,\n );\n }\n }\n\n if (input !== null && typeof input === \"object\") {\n return makeOkWith(input as T);\n }\n\n return payloadNotFoundError();\n}\n\nexport function selectDetailSpan(\n spans: IFornaxSpan[],\n): IFornaxSpan | undefined {\n return spans.findLast((span) => {\n return (\n span?.type === \"model\" && span?.service_name === \"pippit.business.agent\"\n );\n });\n}\n","import { makeOkWith, type ILvErrorOr } from \"../../../../bedrock/error\";\nimport { Region } from \"../../types\";\nimport { readFornaxToken } from \"../fornax-token\";\nimport {\n expiredFornaxTokenError,\n detailSpanNotFoundError,\n missingFornaxTokenError,\n missingLogIdError,\n searchResultNotFoundError,\n} from \"./errors\";\nimport {\n createHeaders,\n parseDetailPayload,\n requestJson,\n resolveTimeWindow,\n selectDetailSpan,\n} from \"./common\";\nimport type {\n IFornaxDataResult,\n IFornaxSearchOptions,\n IFornaxSpan,\n IFornaxLogData,\n} from \"./types\";\n\nconst CONFIG = {\n BASE_URL: \"https://fornax.bytedance.net/\",\n WORKSPACE_ID: \"7507836945448304652\",\n SCAN_SPAN_IN_HOUR: \"4\",\n DAYS_AGO: 30,\n DAYS_LATER: 1,\n PLATFORM_TYPE: \"inner_cozeloop\",\n PAGE_SIZE: 30,\n} as const;\n\ninterface ITraceSearchResult {\n spans?: IFornaxSpan[];\n [key: string]: unknown;\n}\n\nfunction createFilterField(\n fieldName: string,\n fieldType: string,\n values: string[],\n queryType: string,\n isCustom = false,\n) {\n return {\n field_name: fieldName,\n field_type: fieldType,\n values,\n query_type: queryType,\n query_and_or: \"and\",\n is_custom: isCustom,\n sub_filter: {\n query_and_or: \"and\",\n filter_fields: [],\n },\n };\n}\n\nfunction selectRootSpan(spans: IFornaxSpan[]): IFornaxSpan | undefined {\n let selected: IFornaxSpan | undefined;\n for (const span of spans) {\n if (typeof span.span_id !== \"string\" || typeof span.trace_id !== \"string\") {\n continue;\n }\n if (\n !selected ||\n (span.duration ?? -Infinity) > (selected.duration ?? -Infinity)\n ) {\n selected = span;\n }\n }\n return selected;\n}\n\nfunction getSearchUrl(): string {\n return `${CONFIG.BASE_URL}api/observability/v1/spans/list`;\n}\n\nfunction getSearchReferer(): string {\n return getSearchUrl();\n}\n\nfunction getTimeWindow(): { startTime: string; endTime: string } {\n return resolveTimeWindow(CONFIG.DAYS_AGO, CONFIG.DAYS_LATER);\n}\n\nfunction getSearchBody(logId: string): string {\n const { startTime, endTime } = getTimeWindow();\n return JSON.stringify({\n workspace_id: CONFIG.WORKSPACE_ID,\n start_time: startTime,\n end_time: endTime,\n filters: {\n query_and_or: \"and\",\n filter_fields: [\n createFilterField(\"deployment_env\", \"string\", [\"boe\"], \"not_in\"),\n createFilterField(\"psm\", \"string\", [\"pippit.business.agent\"], \"in\"),\n createFilterField(\"logid\", \"string\", [logId], \"in\"),\n ],\n },\n page_size: CONFIG.PAGE_SIZE,\n order_bys: [\n {\n field: \"start_time\",\n is_asc: false,\n },\n ],\n platform_type: CONFIG.PLATFORM_TYPE,\n span_list_type: \"root_span\",\n });\n}\n\nfunction getTreeUrl(): string {\n return `${CONFIG.BASE_URL}api/observability/v1/traces/search_tree`;\n}\n\nfunction getDetailUrl(traceId: string, spanId: string): string {\n const { startTime, endTime } = getTimeWindow();\n return `${CONFIG.BASE_URL}api/observability/v1/traces/${traceId}?workspace_id=${CONFIG.WORKSPACE_ID}&start_time=${startTime}&end_time=${endTime}&platform_type=${CONFIG.PLATFORM_TYPE}&span_ids=${spanId}`;\n}\n\nexport async function searchLogCn(\n options: IFornaxSearchOptions,\n): Promise<ILvErrorOr<IFornaxDataResult>> {\n const { logId } = options;\n if (!logId) {\n return missingLogIdError();\n }\n\n const tokenResult = await readFornaxToken(Region.CN);\n if (!tokenResult.ok) {\n return tokenResult;\n }\n\n const token = tokenResult.value?.trim();\n if (!token) {\n return missingFornaxTokenError();\n }\n\n const searchResult = await requestJson<ITraceSearchResult>(getSearchUrl(), {\n method: \"POST\",\n headers: createHeaders(token, getSearchReferer()),\n body: getSearchBody(logId),\n unauthorizedError: expiredFornaxTokenError,\n });\n if (!searchResult.ok) {\n return searchResult;\n }\n\n const searchSpans = searchResult.value.spans ?? [];\n if (searchSpans.length === 0) {\n return searchResultNotFoundError();\n }\n\n const rootSpan = selectRootSpan(searchSpans);\n if (!rootSpan?.trace_id) {\n return detailSpanNotFoundError();\n }\n\n const treeResult = await requestJson<ITraceSearchResult>(getTreeUrl(), {\n method: \"POST\",\n headers: createHeaders(token, getSearchReferer()),\n body: JSON.stringify({\n workspace_id: CONFIG.WORKSPACE_ID,\n trace_id: rootSpan.trace_id,\n start_time: getTimeWindow().startTime,\n end_time: getTimeWindow().endTime,\n platform_type: CONFIG.PLATFORM_TYPE,\n }),\n unauthorizedError: expiredFornaxTokenError,\n });\n if (!treeResult.ok) {\n return treeResult;\n }\n\n const detailSpan = selectDetailSpan(treeResult.value.spans ?? []);\n if (!detailSpan?.trace_id || !detailSpan.span_id) {\n return detailSpanNotFoundError();\n }\n\n const detailResult = await requestJson<ITraceSearchResult>(\n getDetailUrl(detailSpan.trace_id, detailSpan.span_id),\n {\n method: \"GET\",\n headers: createHeaders(token, getSearchReferer()),\n unauthorizedError: expiredFornaxTokenError,\n },\n );\n if (!detailResult.ok) {\n return detailResult;\n }\n\n const payload = parseDetailPayload<IFornaxLogData>(\n detailResult.value.spans?.[0]?.input,\n );\n if (!payload.ok) {\n return payload;\n }\n\n return makeOkWith({\n meta: {\n region: Region.CN,\n spanName: detailSpan.span_name || \"\",\n },\n data: payload.value,\n });\n}\n","import { makeOkWith, type ILvErrorOr } from \"../../../../bedrock/error\";\nimport { Region } from \"../../types\";\nimport { readFornaxToken } from \"../fornax-token\";\nimport {\n expiredFornaxTokenError,\n detailSpanNotFoundError,\n missingFornaxTokenError,\n missingLogIdError,\n searchResultNotFoundError,\n} from \"./errors\";\nimport {\n createHeaders,\n parseDetailPayload,\n requestJson,\n resolveTimeWindow,\n selectDetailSpan,\n} from \"./common\";\nimport type {\n IFornaxDataResult,\n IFornaxSearchOptions,\n IFornaxLogData,\n IFornaxSpan,\n} from \"./types\";\n\nconst CONFIG = {\n BASE_URL: \"https://fornax-i18n.byteintl.net\",\n WORKSPACE_ID: \"7517207223651532851\",\n SCAN_SPAN_IN_HOUR: \"4\",\n DAYS_AGO: 30,\n DAYS_LATER: 1,\n} as const;\n\ninterface ITraceSearchResult {\n spans?: IFornaxSpan[];\n [key: string]: unknown;\n}\n\nfunction getSearchUrl(): string {\n return `${CONFIG.BASE_URL}/api/observability/v1/traces/search`;\n}\n\nfunction getSearchReferer(logId: string): string {\n return `${CONFIG.BASE_URL}/space/${CONFIG.WORKSPACE_ID}/analytics/log-query?env=online&logIdTime=${CONFIG.SCAN_SPAN_IN_HOUR}&queryID=${logId}&queryType=log_id`;\n}\n\nfunction getTimeWindow(): { startTime: string; endTime: string } {\n return resolveTimeWindow(CONFIG.DAYS_AGO, CONFIG.DAYS_LATER);\n}\n\nfunction getDetailUrl(traceId: string, spanId: string): string {\n const { startTime, endTime } = getTimeWindow();\n return `${CONFIG.BASE_URL}/api/observability/v1/traces/${traceId}?workspace_id=${CONFIG.WORKSPACE_ID}&start_time=${startTime}&end_time=${endTime}&platform_type=trace_detail&span_ids=${spanId}`;\n}\n\nexport async function searchLogI18n(\n options: IFornaxSearchOptions,\n): Promise<ILvErrorOr<IFornaxDataResult>> {\n const { logId } = options;\n if (!logId) {\n return missingLogIdError();\n }\n\n const tokenResult = await readFornaxToken(Region.I18N);\n if (!tokenResult.ok) {\n return tokenResult;\n }\n\n const token = tokenResult.value?.trim();\n if (!token) {\n return missingFornaxTokenError();\n }\n\n const searchResult = await requestJson<ITraceSearchResult>(getSearchUrl(), {\n method: \"POST\",\n headers: createHeaders(token, getSearchReferer(logId)),\n body: JSON.stringify({\n workspace_id: CONFIG.WORKSPACE_ID,\n search_type: \"log_id\",\n id: logId,\n scan_span_in_hour: CONFIG.SCAN_SPAN_IN_HOUR,\n }),\n unauthorizedError: expiredFornaxTokenError,\n });\n if (!searchResult.ok) {\n return searchResult;\n }\n\n const searchSpan = selectDetailSpan(searchResult.value.spans ?? []);\n if (!searchSpan?.trace_id || !searchSpan.span_id) {\n return searchResultNotFoundError();\n }\n\n const detailResult = await requestJson<ITraceSearchResult>(\n getDetailUrl(searchSpan.trace_id, searchSpan.span_id),\n {\n method: \"GET\",\n headers: createHeaders(token, getSearchReferer(logId)),\n unauthorizedError: expiredFornaxTokenError,\n },\n );\n if (!detailResult.ok) {\n return detailResult;\n }\n\n const detailSpan = selectDetailSpan(detailResult.value.spans ?? []);\n if (!detailSpan?.trace_id || !detailSpan.span_id) {\n return detailSpanNotFoundError();\n }\n\n const payload = parseDetailPayload<IFornaxLogData>(detailSpan.input);\n if (!payload.ok) {\n return payload;\n }\n\n return makeOkWith({\n meta: {\n region: Region.I18N,\n spanName: detailSpan.span_name || \"\",\n },\n data: payload.value,\n });\n}\n","import { Region } from \"../../types\";\nimport type { IFornaxDataResult, IFornaxSearchOptions } from \"./types\";\nimport { searchLogCn } from \"./cn-search-log\";\nimport { searchLogI18n } from \"./i18n-search-log\";\nimport { missingLogIdError, missingRegionError } from \"./errors\";\nimport type { ILvErrorOr } from \"../../../../bedrock/error\";\nimport type { IFornaxLogData } from \"./types\";\n\nfunction trimFornaxMessages(data: IFornaxLogData): void {\n if (!Array.isArray(data.messages)) {\n return;\n }\n\n for (const message of data.messages) {\n if (message === null || typeof message !== \"object\") {\n continue;\n }\n\n if (Object.prototype.hasOwnProperty.call(message, \"metadata\")) {\n void Reflect.deleteProperty(message as Record<string, unknown>, \"metadata\");\n }\n }\n}\n\nexport async function searchLog(\n options: IFornaxSearchOptions,\n): Promise<ILvErrorOr<IFornaxDataResult>> {\n const { logId, region, trim = true } = options;\n if (!logId) {\n return missingLogIdError();\n }\n\n if (!region) {\n return missingRegionError();\n }\n\n if (region === Region.CN) {\n const result = await searchLogCn({ logId, region });\n if (result.ok && trim) {\n trimFornaxMessages(result.value.data);\n }\n return result;\n }\n\n const result = await searchLogI18n({ logId, region });\n if (result.ok && trim) {\n trimFornaxMessages(result.value.data);\n }\n return result;\n}\n","import * as fs from \"node:fs/promises\";\nimport * as path from \"node:path\";\nimport type { Command } from \"commander\";\nimport { Option } from \"commander\";\nimport { BaseCommand } from \"../../core/base-command\";\nimport type { ICommandActionContext } from \"../../core/base-command\";\nimport type { ICommandMeta } from \"../../core/command-types\";\nimport type { ILvErrorOr } from \"../../bedrock/error\";\nimport { getThread } from \"./modules/get-thread\";\nimport type { IThreadData } from \"./modules/get-thread/types\";\nimport { searchLog } from \"./modules/search-log\";\nimport type { Region } from \"./types\";\n\ninterface IPippitSaveThreadFornaxOptions {\n outputDir?: string;\n}\n\nexport class PippitSaveThreadFornaxCommand extends BaseCommand<IPippitSaveThreadFornaxOptions> {\n protected _meta(): ICommandMeta {\n return {\n name: \"save\",\n description: \"获取 thread 和 fornax 并保存到本地\",\n };\n }\n\n protected _configureArguments(cmd: Command): void {\n cmd.argument(\"<thread_id>\", \"要获取并保存的 thread id\");\n }\n\n protected _configureOptions(cmd: Command): void {\n cmd.addOption(\n new Option(\"-o, --output-dir <dir>\", \"保存目录,缺省时使用当前工作目录\"),\n );\n }\n\n protected async _execute(\n ctx: ICommandActionContext<IPippitSaveThreadFornaxOptions>,\n ): Promise<ILvErrorOr<void>> {\n const threadId = ctx.args[0] as string;\n const outputDir = ctx.options.outputDir;\n\n const threadResult = await getThread({ threadId, trim: true });\n if (!threadResult.ok) {\n return this._emitJsonError(threadResult.code, threadResult.msg);\n }\n\n const threadData = threadResult.value.thread;\n const region = threadResult.value.region;\n const logId = this._extractExecuteLogId(threadData);\n if (!logId) {\n return this._emitJsonError(\n 1,\n \"未找到 thread 中可用于查询 fornax 的 execute_log_id。\",\n );\n }\n\n const fornaxResult = await searchLog({ logId, region });\n if (!fornaxResult.ok) {\n return this._emitJsonError(fornaxResult.code, fornaxResult.msg);\n }\n\n const targetDir = this._resolveTargetDir(threadId, outputDir);\n const threadPath = path.join(targetDir, \"thread.json\");\n const fornaxPath = path.join(targetDir, \"fornax.json\");\n\n try {\n await fs.mkdir(targetDir, { recursive: true });\n await fs.writeFile(\n threadPath,\n `${JSON.stringify(threadData, null, 2)}\\n`,\n \"utf8\",\n );\n await fs.writeFile(\n fornaxPath,\n `${JSON.stringify(fornaxResult.value.data, null, 2)}\\n`,\n \"utf8\",\n );\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n return this._emitJsonError(1, `写入文件失败: ${message}`);\n }\n\n this._outputJsonOk({\n thread_id: threadId,\n output_dir: targetDir,\n files: {\n thread: threadPath,\n fornax: fornaxPath,\n },\n });\n return this._makeOk();\n }\n\n private _emitJsonError(code: number, msg: string): ILvErrorOr<void> {\n this._outputJsonError(code, msg);\n process.exitCode = 1;\n return this._makeOk();\n }\n\n private _resolveTargetDir(threadId: string, outputDir?: string): string {\n const baseDir = outputDir\n ? path.resolve(process.cwd(), outputDir)\n : process.cwd();\n return path.join(baseDir, threadId);\n }\n\n private _extractExecuteLogId(thread: IThreadData): string | undefined {\n const lastRun = thread.run_list.at(-1);\n if (!lastRun) {\n return undefined;\n }\n\n if (typeof lastRun.execute_log_id === \"string\") {\n const executeLogId = lastRun.execute_log_id.trim();\n if (executeLogId.length > 0) {\n return executeLogId;\n }\n }\n\n if (typeof lastRun.extra !== \"string\" || lastRun.extra.length === 0) {\n return undefined;\n }\n\n try {\n const extra = JSON.parse(lastRun.extra) as {\n execute_log_id?: unknown;\n };\n if (typeof extra.execute_log_id !== \"string\") {\n return undefined;\n }\n\n const executeLogId = extra.execute_log_id.trim();\n return executeLogId.length > 0 ? executeLogId : undefined;\n } catch {\n return undefined;\n }\n }\n}\n","import type { ICommandMeta } from \"../../core/command-types\";\nimport { BaseSubcommandHost } from \"../../core/base-subcommand-host\";\nimport { PippitGetThreadCommand } from \"./pippit-get-thread-command\";\nimport { PippitFornaxTokenCommand } from \"./pippit-fornax-token-command\";\nimport { PippitSearchFornaxLogCommand } from \"./pippit-search-fornax-log-command\";\nimport { PippitSaveThreadFornaxCommand } from \"./pippit-save-thread-fornax-command\";\n\nexport class PippitCommand extends BaseSubcommandHost {\n protected _meta(): ICommandMeta {\n return {\n name: \"pippit\",\n description: \"访问 pippit 服务\",\n aliases: [\"pp\", \"xyq\"],\n };\n }\n\n protected _registerSubcommands(): void {\n this._addSubcommand(new PippitGetThreadCommand());\n this._addSubcommand(new PippitFornaxTokenCommand());\n this._addSubcommand(new PippitSearchFornaxLogCommand());\n this._addSubcommand(new PippitSaveThreadFornaxCommand());\n }\n}\n"],"mappings":"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","names":["GetThreadError","Option","fs","path","Option","Option","BASE","FornaxSearchError","networkRequestFailedError","networkRequestFailedError","CONFIG","getSearchUrl","getSearchReferer","getTimeWindow","getDetailUrl","result","Option","fs","path","Option","Option","require"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "maoda-commander-tt",
3
- "version": "0.0.4",
3
+ "version": "0.0.6",
4
4
  "description": "一个通用命令行工具",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -26,7 +26,8 @@
26
26
  "lint": "eslint src --ext .ts",
27
27
  "clean": "rm -rf dist",
28
28
  "prerelease": "pnpm run clean && pnpm run build",
29
- "release": "pnpm version patch && npm publish --registry=https://registry.npmjs.org"
29
+ "release": "pnpm version patch && npm publish --registry=https://registry.npmjs.org",
30
+ "pub": "pnpm prerelease && pnpm release"
30
31
  },
31
32
  "keywords": [
32
33
  "cli",