chatlab-cli 0.21.1 → 0.22.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (60) hide show
  1. package/README.md +5 -5
  2. package/dist/{chunk-OQVKZTVD.mjs → chunk-3UBWLWXB.mjs} +2 -2
  3. package/dist/{chunk-AIR7EAF4.mjs → chunk-4U45E7TO.mjs} +2 -2
  4. package/dist/{chunk-OZWXLRJL.mjs → chunk-6GLMVWGA.mjs} +24 -15
  5. package/dist/chunk-6GLMVWGA.mjs.map +1 -0
  6. package/dist/{chunk-2AIOU3PW.mjs → chunk-6NB475AA.mjs} +12 -3
  7. package/dist/chunk-6NB475AA.mjs.map +1 -0
  8. package/dist/{chunk-LI4X52E7.mjs → chunk-AMMSVJG4.mjs} +325 -94
  9. package/dist/chunk-AMMSVJG4.mjs.map +1 -0
  10. package/dist/{chunk-4GI2UPCS.mjs → chunk-D2XJ4Z7G.mjs} +2 -2
  11. package/dist/{chunk-7HQWGLX6.mjs → chunk-QJQJIUUS.mjs} +102 -96
  12. package/dist/chunk-QJQJIUUS.mjs.map +1 -0
  13. package/dist/chunk-VSOWNKPA.mjs +49 -0
  14. package/dist/cli.mjs +4 -3
  15. package/dist/{http-DHQI4G5J.mjs → http-R5UECMPJ.mjs} +8 -7
  16. package/dist/{import-CQWGIMZQ.mjs → import-3LOWRXWA.mjs} +5 -4
  17. package/dist/index.mjs +8 -7
  18. package/dist/{mcp-7Q3FEI3Z.mjs → mcp-WBHNLED2.mjs} +8 -7
  19. package/dist/mcp-WBHNLED2.mjs.map +1 -0
  20. package/dist/{src-QBT5SYW5.mjs → src-UHM2UDRD.mjs} +3 -2
  21. package/dist/{stream-import-VG7RP6KJ.mjs → stream-import-V6Z7DXSW.mjs} +4 -3
  22. package/dist/stream-import-V6Z7DXSW.mjs.map +1 -0
  23. package/dist/update-checker-MQMQ6A4B.mjs +191 -0
  24. package/dist/update-checker-MQMQ6A4B.mjs.map +1 -0
  25. package/dist-web/assets/{DebugToolsPanel-CoBtqb--.css → DebugToolsPanel-DkbsB6lr.css} +1 -1
  26. package/dist-web/assets/{DebugToolsPanel.vue_vue_type_script_setup_true_lang-CpFGhsl5.js → DebugToolsPanel.vue_vue_type_script_setup_true_lang-CxYyne-Q.js} +5 -5
  27. package/dist-web/assets/{EChartWordcloud-BYLFxPAX.js → EChartWordcloud-Ubal_aYg.js} +1 -1
  28. package/dist-web/assets/{MessageExportModal-DTgxz1eQ.js → MessageExportModal-De5_tX6a.js} +1 -1
  29. package/dist-web/assets/{electron-CTK4NJag.js → electron-CRSL7qPM.js} +1 -1
  30. package/dist-web/assets/{fetch-C2vUkdnA.js → fetch-Q-PqsiMb.js} +1 -1
  31. package/dist-web/assets/{fetch-CTZXLLcn.js → fetch-cFjLAPG2.js} +1 -1
  32. package/dist-web/assets/{index-DeG0EHOT.js → index-BJUGnYn5.js} +1 -1
  33. package/dist-web/assets/{index-DuhN8jAf.js → index-B_31fXeB.js} +2 -2
  34. package/dist-web/assets/index-CbOwHYzO.css +1 -0
  35. package/dist-web/assets/index-DKMUn8F5.js +173 -0
  36. package/dist-web/assets/{index-C4B0hv6C.js → index-D_ksezTw.js} +4 -4
  37. package/dist-web/assets/index-Dhg3SDb6.js +7 -0
  38. package/dist-web/assets/logo-DXIuG_WE.svg +17 -0
  39. package/dist-web/assets/{vendor-echarts-C13vDgZW.js → vendor-echarts-C5u62NnM.js} +1 -1
  40. package/dist-web/assets/{vendor-echarts-wordcloud-uVdwYsYa.js → vendor-echarts-wordcloud-CZ9gsX8l.js} +1 -1
  41. package/dist-web/assets/{vendor-nuxt-ui-CYMNNdeD.js → vendor-nuxt-ui-7OAuiz_i.js} +1 -1
  42. package/dist-web/assets/{vendor-zrender-5DcYjSZk.js → vendor-zrender-DFl4U2Oe.js} +1 -1
  43. package/dist-web/assets/{web-DImo6Kjz.js → web-CZe0Ismu.js} +1 -1
  44. package/dist-web/index.html +3 -3
  45. package/package.json +4 -3
  46. package/dist/chunk-2AIOU3PW.mjs.map +0 -1
  47. package/dist/chunk-7HQWGLX6.mjs.map +0 -1
  48. package/dist/chunk-LI4X52E7.mjs.map +0 -1
  49. package/dist/chunk-OZWXLRJL.mjs.map +0 -1
  50. package/dist/mcp-7Q3FEI3Z.mjs.map +0 -1
  51. package/dist-web/assets/index-B8867dX7.css +0 -1
  52. package/dist-web/assets/index-DUXf21MT.js +0 -173
  53. package/dist-web/assets/index-DZiH2cC1.js +0 -7
  54. /package/dist/{chunk-OQVKZTVD.mjs.map → chunk-3UBWLWXB.mjs.map} +0 -0
  55. /package/dist/{chunk-AIR7EAF4.mjs.map → chunk-4U45E7TO.mjs.map} +0 -0
  56. /package/dist/{chunk-4GI2UPCS.mjs.map → chunk-D2XJ4Z7G.mjs.map} +0 -0
  57. /package/dist/{http-DHQI4G5J.mjs.map → chunk-VSOWNKPA.mjs.map} +0 -0
  58. /package/dist/{import-CQWGIMZQ.mjs.map → http-R5UECMPJ.mjs.map} +0 -0
  59. /package/dist/{src-QBT5SYW5.mjs.map → import-3LOWRXWA.mjs.map} +0 -0
  60. /package/dist/{stream-import-VG7RP6KJ.mjs.map → src-UHM2UDRD.mjs.map} +0 -0
@@ -0,0 +1,49 @@
1
+ import { createRequire as __createRequire } from 'module';
2
+ import { dirname as __pathDirname } from 'path';
3
+ import { fileURLToPath as __fileURLToPath } from 'url';
4
+ const require = __createRequire(import.meta.url);
5
+ const __filename = __fileURLToPath(import.meta.url);
6
+ const __dirname = __pathDirname(__filename);
7
+ var __create = Object.create;
8
+ var __defProp = Object.defineProperty;
9
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
10
+ var __getOwnPropNames = Object.getOwnPropertyNames;
11
+ var __getProtoOf = Object.getPrototypeOf;
12
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
13
+ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
14
+ get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
15
+ }) : x)(function(x) {
16
+ if (typeof require !== "undefined") return require.apply(this, arguments);
17
+ throw Error('Dynamic require of "' + x + '" is not supported');
18
+ });
19
+ var __commonJS = (cb, mod) => function __require2() {
20
+ return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
21
+ };
22
+ var __export = (target, all) => {
23
+ for (var name in all)
24
+ __defProp(target, name, { get: all[name], enumerable: true });
25
+ };
26
+ var __copyProps = (to, from, except, desc) => {
27
+ if (from && typeof from === "object" || typeof from === "function") {
28
+ for (let key of __getOwnPropNames(from))
29
+ if (!__hasOwnProp.call(to, key) && key !== except)
30
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
31
+ }
32
+ return to;
33
+ };
34
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
35
+ // If the importer is in node compatibility mode or this is not an ESM
36
+ // file that has been converted to a CommonJS file using a Babel-
37
+ // compatible transform (i.e. "__esModule" has not been set), then set
38
+ // "default" to the CommonJS "module.exports" for node compatibility.
39
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
40
+ mod
41
+ ));
42
+
43
+ export {
44
+ __require,
45
+ __commonJS,
46
+ __export,
47
+ __toESM
48
+ };
49
+ //# sourceMappingURL=chunk-VSOWNKPA.mjs.map
package/dist/cli.mjs CHANGED
@@ -6,9 +6,10 @@ const __filename = __fileURLToPath(import.meta.url);
6
6
  const __dirname = __pathDirname(__filename);
7
7
  import {
8
8
  run
9
- } from "./chunk-OZWXLRJL.mjs";
10
- import "./chunk-2AIOU3PW.mjs";
11
- import "./chunk-7HQWGLX6.mjs";
9
+ } from "./chunk-6GLMVWGA.mjs";
10
+ import "./chunk-6NB475AA.mjs";
11
+ import "./chunk-QJQJIUUS.mjs";
12
+ import "./chunk-VSOWNKPA.mjs";
12
13
  export {
13
14
  run
14
15
  };
@@ -13,12 +13,13 @@ import {
13
13
  registerWebRoutes,
14
14
  startHttpServer,
15
15
  stopHttpServer
16
- } from "./chunk-LI4X52E7.mjs";
17
- import "./chunk-OQVKZTVD.mjs";
18
- import "./chunk-AIR7EAF4.mjs";
19
- import "./chunk-4GI2UPCS.mjs";
20
- import "./chunk-2AIOU3PW.mjs";
21
- import "./chunk-7HQWGLX6.mjs";
16
+ } from "./chunk-AMMSVJG4.mjs";
17
+ import "./chunk-3UBWLWXB.mjs";
18
+ import "./chunk-4U45E7TO.mjs";
19
+ import "./chunk-D2XJ4Z7G.mjs";
20
+ import "./chunk-6NB475AA.mjs";
21
+ import "./chunk-QJQJIUUS.mjs";
22
+ import "./chunk-VSOWNKPA.mjs";
22
23
  export {
23
24
  createServer,
24
25
  registerAiRoutes,
@@ -29,4 +30,4 @@ export {
29
30
  startHttpServer,
30
31
  stopHttpServer
31
32
  };
32
- //# sourceMappingURL=http-DHQI4G5J.mjs.map
33
+ //# sourceMappingURL=http-R5UECMPJ.mjs.map
@@ -8,13 +8,13 @@ import {
8
8
  detectFormat as detectFormat2,
9
9
  importData,
10
10
  parseFile
11
- } from "./chunk-OQVKZTVD.mjs";
11
+ } from "./chunk-3UBWLWXB.mjs";
12
12
  import {
13
13
  analyzeIncrementalImport,
14
14
  analyzeNewImport,
15
15
  incrementalImport,
16
16
  streamImport
17
- } from "./chunk-AIR7EAF4.mjs";
17
+ } from "./chunk-4U45E7TO.mjs";
18
18
  import {
19
19
  detectAllFormats,
20
20
  detectFormat,
@@ -22,7 +22,8 @@ import {
22
22
  getFormatFeatureById,
23
23
  getSupportedFormats,
24
24
  scanMultiChatFile
25
- } from "./chunk-7HQWGLX6.mjs";
25
+ } from "./chunk-QJQJIUUS.mjs";
26
+ import "./chunk-VSOWNKPA.mjs";
26
27
  export {
27
28
  analyzeIncrementalImport,
28
29
  analyzeNewImport,
@@ -38,4 +39,4 @@ export {
38
39
  scanMultiChatFile,
39
40
  streamImport
40
41
  };
41
- //# sourceMappingURL=import-CQWGIMZQ.mjs.map
42
+ //# sourceMappingURL=import-3LOWRXWA.mjs.map
package/dist/index.mjs CHANGED
@@ -6,16 +6,17 @@ const __filename = __fileURLToPath(import.meta.url);
6
6
  const __dirname = __pathDirname(__filename);
7
7
  import {
8
8
  run
9
- } from "./chunk-OZWXLRJL.mjs";
9
+ } from "./chunk-6GLMVWGA.mjs";
10
10
  import {
11
11
  startHttpServer,
12
12
  stopHttpServer
13
- } from "./chunk-LI4X52E7.mjs";
14
- import "./chunk-OQVKZTVD.mjs";
15
- import "./chunk-AIR7EAF4.mjs";
16
- import "./chunk-4GI2UPCS.mjs";
17
- import "./chunk-2AIOU3PW.mjs";
18
- import "./chunk-7HQWGLX6.mjs";
13
+ } from "./chunk-AMMSVJG4.mjs";
14
+ import "./chunk-3UBWLWXB.mjs";
15
+ import "./chunk-4U45E7TO.mjs";
16
+ import "./chunk-D2XJ4Z7G.mjs";
17
+ import "./chunk-6NB475AA.mjs";
18
+ import "./chunk-QJQJIUUS.mjs";
19
+ import "./chunk-VSOWNKPA.mjs";
19
20
  export {
20
21
  run,
21
22
  startHttpServer,
@@ -7,10 +7,11 @@ const __dirname = __pathDirname(__filename);
7
7
  import {
8
8
  CoreDataProvider,
9
9
  MCP_TOOL_REGISTRY
10
- } from "./chunk-4GI2UPCS.mjs";
10
+ } from "./chunk-D2XJ4Z7G.mjs";
11
11
  import {
12
- getVersion
13
- } from "./chunk-2AIOU3PW.mjs";
12
+ getVersion,
13
+ resolveCliPath
14
+ } from "./chunk-6NB475AA.mjs";
14
15
  import {
15
16
  DatabaseManager,
16
17
  NodePathProvider,
@@ -20,11 +21,11 @@ import {
20
21
  hasPendingElectronDataWarning,
21
22
  loadConfig,
22
23
  verifyCliDataPath
23
- } from "./chunk-7HQWGLX6.mjs";
24
+ } from "./chunk-QJQJIUUS.mjs";
25
+ import "./chunk-VSOWNKPA.mjs";
24
26
 
25
27
  // src/mcp.ts
26
28
  import fs from "fs";
27
- import path from "path";
28
29
 
29
30
  // ../../packages/mcp-server/src/server.ts
30
31
  import { McpServer, ResourceTemplate } from "@modelcontextprotocol/sdk/server/mcp.js";
@@ -378,7 +379,7 @@ async function startMcpServer(options) {
378
379
  // src/mcp.ts
379
380
  function resolveNativeBinding() {
380
381
  if (process.versions.electron) return void 0;
381
- const nativePath = path.resolve(__dirname, "../native/better_sqlite3.node");
382
+ const nativePath = resolveCliPath("native/better_sqlite3.node");
382
383
  if (fs.existsSync(nativePath)) return nativePath;
383
384
  return void 0;
384
385
  }
@@ -402,4 +403,4 @@ async function startCliMcpServer() {
402
403
  export {
403
404
  startCliMcpServer
404
405
  };
405
- //# sourceMappingURL=mcp-7Q3FEI3Z.mjs.map
406
+ //# sourceMappingURL=mcp-WBHNLED2.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/mcp.ts","../../../packages/mcp-server/src/server.ts","../../../packages/mcp-server/src/schema.ts","../../../packages/mcp-server/src/format.ts"],"sourcesContent":["/**\n * CLI MCP Server entry point\n *\n * Thin wrapper: initializes Node.js runtime, then delegates to chatlab-mcp.\n */\n\nimport fs from 'fs'\nimport { loadConfig } from '@openchatlab/config'\nimport {\n NodePathProvider,\n DatabaseManager,\n hasPendingElectronDataWarning,\n verifyCliDataPath,\n} from '@openchatlab/node-runtime'\nimport { startMcpServer } from 'chatlab-mcp'\nimport { getVersion } from './version'\nimport { resolveCliPath } from './paths'\n\nfunction resolveNativeBinding(): string | undefined {\n if (process.versions.electron) return undefined\n const nativePath = resolveCliPath('native/better_sqlite3.node')\n if (fs.existsSync(nativePath)) return nativePath\n return undefined\n}\n\nfunction initMcpRuntime(): DatabaseManager {\n const config = loadConfig()\n const userDataDir = config.data.user_data_dir || undefined\n const pathProvider = new NodePathProvider(userDataDir)\n pathProvider.ensureAllDirs()\n\n if (hasPendingElectronDataWarning() || !verifyCliDataPath(pathProvider.getDatabaseDir())) {\n console.error('[MCP] Electron desktop data detected but databases not found.')\n console.error('[MCP] Set CHATLAB_DATA_DIR or edit ~/.chatlab/config.toml to point to your data directory.')\n process.exit(1)\n }\n\n const nativeBinding = resolveNativeBinding()\n return new DatabaseManager(pathProvider, { nativeBinding })\n}\n\nexport async function startCliMcpServer(): Promise<void> {\n const dbManager = initMcpRuntime()\n await startMcpServer({ version: getVersion(), dbManager })\n}\n","/**\n * ChatLab MCP Server core\n *\n * Registers @openchatlab/tools as MCP tools and exposes session data as MCP resources.\n * Communicates with AI agents (ClaudeCode, Cursor, etc.) via stdio transport.\n */\n\nimport { McpServer, ResourceTemplate } from '@modelcontextprotocol/sdk/server/mcp.js'\nimport { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'\nimport { z } from 'zod'\nimport { getSessionMeta, getSessionOverview, getDatabaseSchema } from '@openchatlab/core'\nimport { MCP_TOOL_REGISTRY, CoreDataProvider } from '@openchatlab/tools'\nimport type { SessionListContext } from '@openchatlab/tools/src/definitions/sessions'\nimport type { McpDatabaseManager, McpServerOptions } from './types'\nimport { jsonSchemaToZod } from './schema'\nimport { formatToolResultAsText } from './format'\n\nconst MCP_TOOL_PREFIX = 'chatlab_'\n\nconst FORMAT_PARAM = z.enum(['text', 'json']).optional().describe('text (default) or json')\n\n/** Tools where JSON is a better default (raw SQL results, schema) */\nconst JSON_DEFAULT_TOOLS = new Set(['execute_sql', 'get_schema'])\n\nfunction applyFormat(content: string, format: string | undefined, toolName: string): string {\n const effectiveFormat = format ?? (JSON_DEFAULT_TOOLS.has(toolName) ? 'json' : 'text')\n if (effectiveFormat === 'json') return content\n\n const textResult = formatToolResultAsText(content)\n return textResult ?? content\n}\n\nfunction registerTools(server: McpServer, dbManager: McpDatabaseManager): void {\n for (const tool of MCP_TOOL_REGISTRY) {\n const mcpName = `${MCP_TOOL_PREFIX}${tool.name}`\n\n if (tool.name === 'list_sessions') {\n const zodShape = {\n ...jsonSchemaToZod(tool.inputSchema.properties, tool.inputSchema.required),\n format: FORMAT_PARAM,\n }\n\n server.tool(mcpName, tool.description, zodShape, async (params) => {\n const format = params.format as string | undefined\n const context: SessionListContext = {\n db: null as any,\n sessionId: '',\n listSessionIds: () => dbManager.listSessionIds(),\n openDb: (id) => dbManager.open(id),\n }\n const toolParams = { ...params } as Record<string, unknown>\n delete toolParams.format\n const result = await tool.handler(toolParams, context)\n const text = applyFormat(result.content, format, tool.name)\n return { content: [{ type: 'text' as const, text }] }\n })\n continue\n }\n\n const zodShape = {\n session_id: z.string().describe('Session ID'),\n ...jsonSchemaToZod(tool.inputSchema.properties, tool.inputSchema.required),\n format: FORMAT_PARAM,\n }\n\n server.tool(mcpName, tool.description, zodShape, async (params) => {\n const sessionId = params.session_id as string\n const format = params.format as string | undefined\n const db = dbManager.open(sessionId)\n if (!db) {\n return {\n content: [{ type: 'text' as const, text: `Session not found: ${sessionId}` }],\n isError: true,\n }\n }\n\n const toolParams = { ...params } as Record<string, unknown>\n delete toolParams.session_id\n delete toolParams.format\n\n const result = await tool.handler(toolParams, { db, sessionId, dataProvider: new CoreDataProvider(db) })\n const text = applyFormat(result.content, format, tool.name)\n return { content: [{ type: 'text' as const, text }] }\n })\n }\n}\n\nfunction registerResources(server: McpServer, dbManager: McpDatabaseManager): void {\n server.resource('sessions-list', 'chatlab://sessions', { description: '所有已导入的聊天会话列表' }, async () => {\n const sessionIds = dbManager.listSessionIds()\n const sessions = sessionIds\n .map((id) => {\n const db = dbManager.open(id)\n if (!db) return null\n const meta = getSessionMeta(db)\n if (!meta) return null\n return { id, name: meta.name, platform: meta.platform, type: meta.type }\n })\n .filter(Boolean)\n\n return {\n contents: [\n {\n uri: 'chatlab://sessions',\n text: JSON.stringify(sessions, null, 2),\n mimeType: 'application/json',\n },\n ],\n }\n })\n\n server.resource(\n 'session-meta',\n new ResourceTemplate('chatlab://sessions/{sessionId}/meta', { list: undefined }),\n { description: '会话元信息(名称、平台、消息数等)' },\n async (uri, params) => {\n const sessionId = params.sessionId as string\n const db = dbManager.open(sessionId)\n if (!db) {\n return { contents: [{ uri: uri.href, text: '{\"error\": \"Session not found\"}', mimeType: 'application/json' }] }\n }\n\n const meta = getSessionMeta(db)\n const overview = getSessionOverview(db)\n\n return {\n contents: [\n {\n uri: uri.href,\n text: JSON.stringify({ ...meta, ...overview }, null, 2),\n mimeType: 'application/json',\n },\n ],\n }\n }\n )\n\n server.resource(\n 'session-schema',\n new ResourceTemplate('chatlab://sessions/{sessionId}/schema', { list: undefined }),\n { description: '会话数据库的表结构' },\n async (uri, params) => {\n const sessionId = params.sessionId as string\n const db = dbManager.open(sessionId)\n if (!db) {\n return { contents: [{ uri: uri.href, text: '{\"error\": \"Session not found\"}', mimeType: 'application/json' }] }\n }\n\n const schema = getDatabaseSchema(db)\n\n return {\n contents: [\n {\n uri: uri.href,\n text: JSON.stringify(schema, null, 2),\n mimeType: 'application/json',\n },\n ],\n }\n }\n )\n}\n\nexport async function startMcpServer(options: McpServerOptions): Promise<void> {\n const { version, name = 'chatlab', dbManager } = options\n\n const server = new McpServer({ name, version })\n\n registerTools(server, dbManager)\n registerResources(server, dbManager)\n\n const transport = new StdioServerTransport()\n await server.connect(transport)\n}\n","/**\n * JSON Schema → Zod conversion for MCP tool registration\n */\n\nimport { z } from 'zod'\n\n/**\n * Convert simple JSON Schema properties to a Zod shape object.\n * Supports string / number / boolean / enum types.\n */\nexport function jsonSchemaToZod(\n properties: Record<string, { type: string; description?: string; default?: unknown; enum?: unknown[] }>,\n required?: string[]\n): Record<string, z.ZodTypeAny> {\n const shape: Record<string, z.ZodTypeAny> = {}\n const requiredSet = new Set(required ?? [])\n\n for (const [key, prop] of Object.entries(properties)) {\n let zodType: z.ZodTypeAny\n\n switch (prop.type) {\n case 'number':\n zodType = z.number().describe(prop.description ?? '')\n break\n case 'boolean':\n zodType = z.boolean().describe(prop.description ?? '')\n break\n case 'string':\n default:\n if (prop.enum) {\n zodType = z.enum(prop.enum as [string, ...string[]]).describe(prop.description ?? '')\n } else {\n zodType = z.string().describe(prop.description ?? '')\n }\n break\n }\n\n if (!requiredSet.has(key)) {\n zodType = zodType.optional()\n }\n\n shape[key] = zodType\n }\n\n return shape\n}\n","/**\n * MCP output formatting for token-efficient LLM consumption\n *\n * Provides message filtering, merging, truncation, and compact text output.\n * Inspired by community chatlab-mcp-server's format.ts.\n */\n\nconst MAX_CONTENT_LENGTH = 200\nconst MAX_MERGED_CONTENT_LENGTH = 400\n\nconst PLACEHOLDER_CONTENTS = new Set([\n '[图片]',\n '[语音]',\n '[视频]',\n '[文件]',\n '[表情]',\n '[动画表情]',\n '[位置]',\n '[名片]',\n '[红包]',\n '[转账]',\n '[撤回消息]',\n '[分享]',\n '[image]',\n '[voice]',\n '[video]',\n '[file]',\n '[sticker]',\n '[animated sticker]',\n '[location]',\n '[contact]',\n '[red packet]',\n '[transfer]',\n '[recalled message]',\n '[photo]',\n '[audio]',\n '[gif]',\n '[share]',\n])\n\nconst MEANINGLESS_SHORT_EN = new Set([\n 'ok',\n 'k',\n 'yes',\n 'no',\n 'ya',\n 'yep',\n 'nope',\n 'lol',\n 'haha',\n 'hehe',\n 'hmm',\n 'ah',\n 'oh',\n 'wow',\n 'thx',\n 'ty',\n 'np',\n 'gg',\n 'brb',\n 'idk',\n])\n\nconst MEANINGFUL_SHORT_ZH = new Set(['好的', '不是', '是的', '可以', '不行', '好吧', '明白', '知道', '同意'])\n\nconst SYSTEM_PATTERNS_ZH = [/^.*邀请.*加入了群聊$/, /^.*退出了群聊$/, /^.*撤回了一条消息$/, /^你撤回了一条消息$/]\n\nconst SYSTEM_PATTERNS_EN = [\n /^.*invited.*to the group$/i,\n /^.*left the group$/i,\n /^.*recalled a message$/i,\n /^.*joined the group$/i,\n /^.*has been removed$/i,\n]\n\nconst EMOJI_ONLY = /^[\\p{Emoji}\\s[\\]()()]+$/u\n\ninterface FormattableMessage {\n senderName: string\n content: string | null\n timestamp: number\n}\n\n/**\n * Check if message content is meaningful (not noise).\n */\nexport function isValidMessage(content: string): boolean {\n const trimmed = content.trim()\n if (!trimmed) return false\n\n if (trimmed.length <= 2 && !MEANINGFUL_SHORT_ZH.has(trimmed)) return false\n if (MEANINGLESS_SHORT_EN.has(trimmed.toLowerCase())) return false\n if (EMOJI_ONLY.test(trimmed)) return false\n if (PLACEHOLDER_CONTENTS.has(trimmed.toLowerCase())) return false\n if (SYSTEM_PATTERNS_ZH.some((p) => p.test(trimmed))) return false\n if (SYSTEM_PATTERNS_EN.some((p) => p.test(trimmed))) return false\n\n return true\n}\n\nfunction truncate(text: string, maxLen: number): string {\n return text.length <= maxLen ? text : text.slice(0, maxLen) + '...'\n}\n\nfunction formatTimestamp(ts: number): string {\n const d = new Date(ts * 1000)\n const M = d.getMonth() + 1\n const D = d.getDate()\n const h = String(d.getHours()).padStart(2, '0')\n const m = String(d.getMinutes()).padStart(2, '0')\n return `${M}/${D} ${h}:${m}`\n}\n\n/**\n * Format messages as compact plain text with consecutive-sender merging.\n * Filters out noise messages, merges same-sender runs, truncates long content.\n */\nexport function formatMessagesCompact(messages: FormattableMessage[]): string {\n if (messages.length === 0) return ''\n\n const valid = messages.filter((m) => m.content && isValidMessage(m.content))\n if (valid.length === 0) return ''\n\n const lines: string[] = []\n let prevSender = ''\n let pendingContents: string[] = []\n let pendingTs = 0\n\n const flush = () => {\n if (pendingContents.length === 0) return\n const combined = pendingContents.join('; ')\n const maxLen = pendingContents.length > 1 ? MAX_MERGED_CONTENT_LENGTH : MAX_CONTENT_LENGTH\n lines.push(`${formatTimestamp(pendingTs)} ${prevSender}: ${truncate(combined, maxLen)}`)\n }\n\n for (const msg of valid) {\n const content = msg.content!.trim()\n if (msg.senderName === prevSender) {\n pendingContents.push(content)\n } else {\n flush()\n prevSender = msg.senderName\n pendingContents = [content]\n pendingTs = msg.timestamp\n }\n }\n flush()\n\n return lines.join('\\n')\n}\n\n/**\n * Try to parse a tool result's JSON content and convert to compact text.\n * Returns null if the content is not suitable for text formatting.\n */\nexport function formatToolResultAsText(content: string): string | null {\n let parsed: unknown\n try {\n parsed = JSON.parse(content)\n } catch {\n return null\n }\n\n if (!parsed || typeof parsed !== 'object') return null\n const obj = parsed as Record<string, unknown>\n\n // If there's a messages array with senderName/content/timestamp, format it\n if (Array.isArray(obj.messages) && obj.messages.length > 0) {\n const msgs = obj.messages as FormattableMessage[]\n if (msgs[0] && 'senderName' in msgs[0] && 'timestamp' in msgs[0]) {\n return formatObjectWithMessages(obj, msgs)\n }\n }\n\n // If there are ranking/keywords arrays, format as numbered list\n if (Array.isArray(obj.ranking) || Array.isArray(obj.keywords)) {\n return formatArrayResult(obj)\n }\n\n // If there are sessions, format them compactly\n if (Array.isArray(obj.sessions)) {\n return formatSessionsList(obj)\n }\n\n return null\n}\n\nfunction formatObjectWithMessages(obj: Record<string, unknown>, msgs: FormattableMessage[]): string {\n const lines: string[] = []\n\n for (const [key, value] of Object.entries(obj)) {\n if (key === 'messages') continue\n if (value === undefined || value === null) continue\n if (typeof value === 'object' && !Array.isArray(value)) continue\n if (Array.isArray(value)) continue\n lines.push(`${key}: ${value}`)\n }\n\n const formatted = formatMessagesCompact(msgs)\n if (formatted) {\n if (lines.length > 0) lines.push('')\n lines.push(formatted)\n }\n\n return lines.join('\\n')\n}\n\nfunction formatArrayResult(obj: Record<string, unknown>): string {\n const lines: string[] = []\n\n for (const [key, value] of Object.entries(obj)) {\n if (Array.isArray(value) && value.length > 0 && typeof value[0] === 'string') {\n if (lines.length > 0) lines.push('')\n lines.push(...value)\n } else if (!Array.isArray(value) && value !== undefined && value !== null) {\n lines.push(`${key}: ${value}`)\n }\n }\n\n return lines.join('\\n')\n}\n\nfunction formatSessionsList(obj: Record<string, unknown>): string {\n const sessions = obj.sessions as Array<Record<string, unknown>>\n const total = obj.total ?? sessions.length\n const lines: string[] = [`${total} sessions:`]\n\n for (const s of sessions) {\n const name = s.name ?? s.id\n const platform = s.platform ? ` (${s.platform})` : ''\n const msgCount = s.totalMessages ?? s.messageCount ?? ''\n const members = s.totalMembers ?? s.memberCount ?? ''\n const stats = msgCount ? ` — ${msgCount} msgs, ${members} members` : ''\n lines.push(`- ${name}${platform}${stats} [${s.id}]`)\n }\n\n return lines.join('\\n')\n}\n"],"mappings":"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","names":["z","z","zodShape"]}
@@ -169,7 +169,8 @@ import {
169
169
  verifyCliDataPath,
170
170
  wasElectronUsed,
171
171
  writeParseResultToDb
172
- } from "./chunk-7HQWGLX6.mjs";
172
+ } from "./chunk-QJQJIUUS.mjs";
173
+ import "./chunk-VSOWNKPA.mjs";
173
174
  export {
174
175
  AIConversationManager,
175
176
  AgentEventHandler,
@@ -336,4 +337,4 @@ export {
336
337
  wasElectronUsed,
337
338
  writeParseResultToDb
338
339
  };
339
- //# sourceMappingURL=src-QBT5SYW5.mjs.map
340
+ //# sourceMappingURL=src-UHM2UDRD.mjs.map
@@ -9,7 +9,7 @@ import {
9
9
  analyzeNewImport,
10
10
  incrementalImport,
11
11
  streamImport
12
- } from "./chunk-AIR7EAF4.mjs";
12
+ } from "./chunk-4U45E7TO.mjs";
13
13
  import {
14
14
  detectAllFormats,
15
15
  detectFormat,
@@ -17,7 +17,8 @@ import {
17
17
  getFormatFeatureById,
18
18
  getSupportedFormats,
19
19
  scanMultiChatFile
20
- } from "./chunk-7HQWGLX6.mjs";
20
+ } from "./chunk-QJQJIUUS.mjs";
21
+ import "./chunk-VSOWNKPA.mjs";
21
22
  export {
22
23
  analyzeIncrementalImport,
23
24
  analyzeNewImport,
@@ -30,4 +31,4 @@ export {
30
31
  scanMultiChatFile,
31
32
  streamImport
32
33
  };
33
- //# sourceMappingURL=stream-import-VG7RP6KJ.mjs.map
34
+ //# sourceMappingURL=stream-import-V6Z7DXSW.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
@@ -0,0 +1,191 @@
1
+ import { createRequire as __createRequire } from 'module';
2
+ import { dirname as __pathDirname } from 'path';
3
+ import { fileURLToPath as __fileURLToPath } from 'url';
4
+ const require = __createRequire(import.meta.url);
5
+ const __filename = __fileURLToPath(import.meta.url);
6
+ const __dirname = __pathDirname(__filename);
7
+ import {
8
+ getVersion
9
+ } from "./chunk-6NB475AA.mjs";
10
+ import "./chunk-VSOWNKPA.mjs";
11
+
12
+ // src/update-checker.ts
13
+ import * as fs from "fs";
14
+ import * as path from "path";
15
+ import * as os from "os";
16
+ import { execFile } from "child_process";
17
+ var PACKAGE_NAME = "chatlab-cli";
18
+ var CACHE_STALE_MS = 6 * 60 * 60 * 1e3;
19
+ var PERIODIC_CHECK_MS = 24 * 60 * 60 * 1e3;
20
+ var CACHE_FILE = path.join(os.homedir(), ".chatlab", "update-check.json");
21
+ function readCache() {
22
+ try {
23
+ if (fs.existsSync(CACHE_FILE)) {
24
+ return JSON.parse(fs.readFileSync(CACHE_FILE, "utf-8"));
25
+ }
26
+ } catch {
27
+ }
28
+ return null;
29
+ }
30
+ function writeCache(cache) {
31
+ try {
32
+ const dir = path.dirname(CACHE_FILE);
33
+ if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true });
34
+ fs.writeFileSync(CACHE_FILE, JSON.stringify(cache), "utf-8");
35
+ } catch {
36
+ }
37
+ }
38
+ function isNewerVersion(latest, current) {
39
+ const parse = (v) => {
40
+ const [core, pre] = v.split("-", 2);
41
+ const parts = core.split(".").map(Number);
42
+ return { major: parts[0] || 0, minor: parts[1] || 0, patch: parts[2] || 0, pre };
43
+ };
44
+ const l = parse(latest);
45
+ const c = parse(current);
46
+ if (l.major !== c.major) return l.major > c.major;
47
+ if (l.minor !== c.minor) return l.minor > c.minor;
48
+ if (l.patch !== c.patch) return l.patch > c.patch;
49
+ if (c.pre && !l.pre) return true;
50
+ return false;
51
+ }
52
+ async function fetchLatestVersion() {
53
+ try {
54
+ const resp = await fetch(`https://registry.npmjs.org/${PACKAGE_NAME}/latest`, {
55
+ headers: { Accept: "application/json" },
56
+ signal: AbortSignal.timeout(8e3)
57
+ });
58
+ if (!resp.ok) return null;
59
+ const data = await resp.json();
60
+ return data.version || null;
61
+ } catch {
62
+ return null;
63
+ }
64
+ }
65
+ function promptUser(question, choices) {
66
+ return new Promise((resolve) => {
67
+ process.stderr.write(`${question}
68
+
69
+ `);
70
+ choices.forEach((c, i) => {
71
+ process.stderr.write(i === 0 ? `\u203A ${i + 1}. ${c}
72
+ ` : ` ${i + 1}. ${c}
73
+ `);
74
+ });
75
+ process.stderr.write("\n");
76
+ if (!process.stdin.isTTY || !process.stdin.setRawMode) {
77
+ resolve(2);
78
+ return;
79
+ }
80
+ process.stdin.setRawMode(true);
81
+ process.stdin.resume();
82
+ const onData = (data) => {
83
+ const key = data.toString();
84
+ if (key === "") {
85
+ process.stdin.setRawMode(false);
86
+ process.stdin.pause();
87
+ process.exit(0);
88
+ }
89
+ if (key.length === 1) {
90
+ const num = parseInt(key);
91
+ if (num >= 1 && num <= choices.length) {
92
+ process.stdin.removeListener("data", onData);
93
+ process.stdin.setRawMode(false);
94
+ process.stdin.pause();
95
+ process.stderr.write("\n");
96
+ resolve(num);
97
+ }
98
+ }
99
+ };
100
+ process.stdin.on("data", onData);
101
+ });
102
+ }
103
+ function runNpmUpdate() {
104
+ return new Promise((resolve) => {
105
+ const npmCmd = process.platform === "win32" ? "npm.cmd" : "npm";
106
+ process.stderr.write(`
107
+ Running: npm install -g ${PACKAGE_NAME}@latest
108
+
109
+ `);
110
+ const child = execFile(
111
+ npmCmd,
112
+ ["install", "-g", `${PACKAGE_NAME}@latest`],
113
+ { timeout: 12e4 },
114
+ (err, _stdout, stderr) => {
115
+ if (err) {
116
+ resolve({ success: false, error: stderr || err.message });
117
+ } else {
118
+ resolve({ success: true });
119
+ }
120
+ }
121
+ );
122
+ child.stdout?.pipe(process.stderr);
123
+ child.stderr?.pipe(process.stderr);
124
+ });
125
+ }
126
+ function isDevEnvironment() {
127
+ if (process.env.CHATLAB_SKIP_UPDATE_CHECK) return true;
128
+ if (process.env.NODE_ENV === "development") return true;
129
+ const entryFile = process.argv[1] || "";
130
+ return entryFile.endsWith(".ts") || entryFile.endsWith(".mts");
131
+ }
132
+ function refreshCacheInBackground(existingCache) {
133
+ fetchLatestVersion().then((latestVersion) => {
134
+ writeCache({
135
+ lastCheckTime: Date.now(),
136
+ latestVersion,
137
+ skippedVersion: existingCache?.skippedVersion
138
+ });
139
+ }).catch(() => {
140
+ });
141
+ }
142
+ function startPeriodicUpdateCheck() {
143
+ if (isDevEnvironment()) return;
144
+ refreshCacheInBackground(readCache());
145
+ const timer = setInterval(() => {
146
+ refreshCacheInBackground(readCache());
147
+ }, PERIODIC_CHECK_MS);
148
+ timer.unref();
149
+ }
150
+ async function checkForUpdatesInteractive() {
151
+ if (!process.stdin.isTTY || process.env.CI || isDevEnvironment()) return;
152
+ const currentVersion = getVersion();
153
+ const cache = readCache();
154
+ if (!cache || Date.now() - cache.lastCheckTime >= CACHE_STALE_MS) {
155
+ refreshCacheInBackground(cache);
156
+ }
157
+ const latestVersion = cache?.latestVersion;
158
+ if (!latestVersion || !isNewerVersion(latestVersion, currentVersion)) return;
159
+ if (cache?.skippedVersion === latestVersion) return;
160
+ const choice = await promptUser(` \u2728 Update available! ${currentVersion} \u2192 ${latestVersion}`, [
161
+ `Update now (runs \`npm install -g ${PACKAGE_NAME}\`)`,
162
+ "Skip",
163
+ "Skip until next version"
164
+ ]);
165
+ if (choice === 1) {
166
+ const result = await runNpmUpdate();
167
+ if (result.success) {
168
+ process.stderr.write(
169
+ ` \x1B[32m\u{1F389} Updated successfully! Please restart chatlab to use the new version.\x1B[0m
170
+
171
+ `
172
+ );
173
+ process.exit(0);
174
+ } else {
175
+ process.stderr.write(` \u274C Update failed: ${result.error}
176
+
177
+ `);
178
+ }
179
+ } else if (choice === 3) {
180
+ writeCache({
181
+ lastCheckTime: Date.now(),
182
+ latestVersion,
183
+ skippedVersion: latestVersion
184
+ });
185
+ }
186
+ }
187
+ export {
188
+ checkForUpdatesInteractive,
189
+ startPeriodicUpdateCheck
190
+ };
191
+ //# sourceMappingURL=update-checker-MQMQ6A4B.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/update-checker.ts"],"sourcesContent":["/**\n * CLI startup update checker — npm registry version comparison\n * with interactive prompt (Codex-style).\n *\n * Caches check results to avoid hitting npm on every invocation.\n * Respects user \"skip until next version\" preference.\n */\n\nimport * as fs from 'fs'\nimport * as path from 'path'\nimport * as os from 'os'\nimport { execFile } from 'child_process'\nimport { getVersion } from './version'\n\nconst PACKAGE_NAME = 'chatlab-cli'\nconst CACHE_STALE_MS = 6 * 60 * 60 * 1000 // 6h — startup cache TTL\nconst PERIODIC_CHECK_MS = 24 * 60 * 60 * 1000 // 24h — long-running service interval\nconst CACHE_FILE = path.join(os.homedir(), '.chatlab', 'update-check.json')\n\ninterface UpdateCache {\n lastCheckTime: number\n latestVersion: string | null\n skippedVersion?: string\n}\n\nfunction readCache(): UpdateCache | null {\n try {\n if (fs.existsSync(CACHE_FILE)) {\n return JSON.parse(fs.readFileSync(CACHE_FILE, 'utf-8'))\n }\n } catch {\n // corrupted cache\n }\n return null\n}\n\nfunction writeCache(cache: UpdateCache): void {\n try {\n const dir = path.dirname(CACHE_FILE)\n if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true })\n fs.writeFileSync(CACHE_FILE, JSON.stringify(cache), 'utf-8')\n } catch {\n // non-critical\n }\n}\n\nfunction isNewerVersion(latest: string, current: string): boolean {\n const parse = (v: string) => {\n const [core, pre] = v.split('-', 2)\n const parts = core.split('.').map(Number)\n return { major: parts[0] || 0, minor: parts[1] || 0, patch: parts[2] || 0, pre }\n }\n const l = parse(latest)\n const c = parse(current)\n if (l.major !== c.major) return l.major > c.major\n if (l.minor !== c.minor) return l.minor > c.minor\n if (l.patch !== c.patch) return l.patch > c.patch\n // Design note: prerelease users are not prompted for prerelease-to-prerelease updates.\n // Only a stable release with the same core version should supersede a prerelease build.\n if (c.pre && !l.pre) return true\n return false\n}\n\nasync function fetchLatestVersion(): Promise<string | null> {\n try {\n const resp = await fetch(`https://registry.npmjs.org/${PACKAGE_NAME}/latest`, {\n headers: { Accept: 'application/json' },\n signal: AbortSignal.timeout(8_000),\n })\n if (!resp.ok) return null\n const data = (await resp.json()) as { version?: string }\n return data.version || null\n } catch {\n return null\n }\n}\n\nfunction promptUser(question: string, choices: string[]): Promise<number> {\n return new Promise((resolve) => {\n process.stderr.write(`${question}\\n\\n`)\n choices.forEach((c, i) => {\n process.stderr.write(i === 0 ? `› ${i + 1}. ${c}\\n` : ` ${i + 1}. ${c}\\n`)\n })\n process.stderr.write('\\n')\n\n if (!process.stdin.isTTY || !process.stdin.setRawMode) {\n resolve(2)\n return\n }\n\n process.stdin.setRawMode(true)\n process.stdin.resume()\n\n const onData = (data: Buffer) => {\n const key = data.toString()\n if (key === '\\x03') {\n process.stdin.setRawMode!(false)\n process.stdin.pause()\n process.exit(0)\n }\n // Only accept single-digit keys matching a valid choice;\n // ignore arrow keys (\\x1b[A/B/C/D), Enter, and other non-digit input.\n if (key.length === 1) {\n const num = parseInt(key)\n if (num >= 1 && num <= choices.length) {\n process.stdin.removeListener('data', onData)\n process.stdin.setRawMode!(false)\n process.stdin.pause()\n process.stderr.write('\\n')\n resolve(num)\n }\n }\n }\n process.stdin.on('data', onData)\n })\n}\n\nfunction runNpmUpdate(): Promise<{ success: boolean; error?: string }> {\n return new Promise((resolve) => {\n const npmCmd = process.platform === 'win32' ? 'npm.cmd' : 'npm'\n process.stderr.write(`\\n Running: npm install -g ${PACKAGE_NAME}@latest\\n\\n`)\n\n const child = execFile(\n npmCmd,\n ['install', '-g', `${PACKAGE_NAME}@latest`],\n { timeout: 120_000 },\n (err, _stdout, stderr) => {\n if (err) {\n resolve({ success: false, error: stderr || err.message })\n } else {\n resolve({ success: true })\n }\n }\n )\n child.stdout?.pipe(process.stderr)\n child.stderr?.pipe(process.stderr)\n })\n}\n\nfunction isDevEnvironment(): boolean {\n if (process.env.CHATLAB_SKIP_UPDATE_CHECK) return true\n if (process.env.NODE_ENV === 'development') return true\n const entryFile = process.argv[1] || ''\n return entryFile.endsWith('.ts') || entryFile.endsWith('.mts')\n}\n\n/**\n * Fire-and-forget: fetch latest version from npm and update local cache.\n * Runs in background so CLI startup is never blocked by network IO.\n */\nfunction refreshCacheInBackground(existingCache: UpdateCache | null): void {\n fetchLatestVersion()\n .then((latestVersion) => {\n writeCache({\n lastCheckTime: Date.now(),\n latestVersion,\n skippedVersion: existingCache?.skippedVersion,\n })\n })\n .catch(() => {})\n}\n\n/**\n * Start a periodic background cache refresh for long-running services.\n * Immediately refreshes once on startup, then every 24h thereafter.\n * The update prompt will appear on the *next* CLI startup.\n * The timer is unref'd so it won't prevent process exit.\n */\nexport function startPeriodicUpdateCheck(): void {\n if (isDevEnvironment()) return\n refreshCacheInBackground(readCache())\n const timer = setInterval(() => {\n refreshCacheInBackground(readCache())\n }, PERIODIC_CHECK_MS)\n timer.unref()\n}\n\n/**\n * Check for updates and prompt user interactively.\n *\n * Strategy (Codex-style):\n * - Read local cache synchronously (instant, no network).\n * - If cache is stale, kick off a background fetch for *next* run.\n * - Prompt is only shown when cache already contains a newer version.\n * - This means the first run after a new release sees no prompt;\n * the second run (with fresh cache) shows it — zero startup delay.\n */\nexport async function checkForUpdatesInteractive(): Promise<void> {\n if (!process.stdin.isTTY || process.env.CI || isDevEnvironment()) return\n\n const currentVersion = getVersion()\n const cache = readCache()\n\n // Kick off background refresh if cache is missing or stale\n if (!cache || Date.now() - cache.lastCheckTime >= CACHE_STALE_MS) {\n refreshCacheInBackground(cache)\n }\n\n // Prompt is based on cached data only — no network wait\n const latestVersion = cache?.latestVersion\n if (!latestVersion || !isNewerVersion(latestVersion, currentVersion)) return\n if (cache?.skippedVersion === latestVersion) return\n\n const choice = await promptUser(` ✨ Update available! ${currentVersion} → ${latestVersion}`, [\n `Update now (runs \\`npm install -g ${PACKAGE_NAME}\\`)`,\n 'Skip',\n 'Skip until next version',\n ])\n\n if (choice === 1) {\n const result = await runNpmUpdate()\n if (result.success) {\n process.stderr.write(\n ` \\x1b[32m🎉 Updated successfully! Please restart chatlab to use the new version.\\x1b[0m\\n\\n`\n )\n process.exit(0)\n } else {\n process.stderr.write(` ❌ Update failed: ${result.error}\\n\\n`)\n }\n } else if (choice === 3) {\n writeCache({\n lastCheckTime: Date.now(),\n latestVersion,\n skippedVersion: latestVersion,\n })\n }\n}\n"],"mappings":"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","names":[]}
@@ -1 +1 @@
1
- .writing-vertical[data-v-19a25590]{writing-mode:vertical-rl;text-orientation:mixed}.data-flow-bg[data-v-19a25590]{background:repeating-linear-gradient(0deg,transparent,transparent 20px,currentColor 20px,currentColor 21px);animation:dataFlow-19a25590 20s linear infinite}@keyframes dataFlow-19a25590{0%{transform:translateY(0)}to{transform:translateY(-100px)}}.mention-menu-enter-active[data-v-0262c6da],.mention-menu-leave-active[data-v-0262c6da]{transition:opacity .16s ease,transform .16s ease}.mention-menu-enter-from[data-v-0262c6da],.mention-menu-leave-to[data-v-0262c6da]{transform:translateY(8px);opacity:0}.slash-menu-enter-active[data-v-0853b251],.slash-menu-leave-active[data-v-0853b251]{transition:opacity .16s ease,transform .16s ease}.slash-menu-enter-from[data-v-0853b251],.slash-menu-leave-to[data-v-0853b251]{transform:translateY(8px);opacity:0}.custom-scrollbar[data-v-4776dd3d]::-webkit-scrollbar{width:4px}.custom-scrollbar[data-v-4776dd3d]::-webkit-scrollbar-track{background:transparent}.custom-scrollbar[data-v-4776dd3d]::-webkit-scrollbar-thumb{border-radius:4px;background-color:#9ca3af4d}.dark .custom-scrollbar[data-v-4776dd3d]::-webkit-scrollbar-thumb{background-color:#9ca3af26}.slide-fade-enter-active[data-v-04240f9d],.slide-fade-leave-active[data-v-04240f9d]{transition:all .3s ease-out}.slide-fade-enter-from[data-v-04240f9d],.slide-fade-leave-to[data-v-04240f9d]{transform:translate(20px);opacity:0}.slide-up-enter-active[data-v-04240f9d],.slide-up-leave-active[data-v-04240f9d]{transition:all .3s ease-out}.slide-up-enter-from[data-v-04240f9d],.slide-up-leave-to[data-v-04240f9d]{transform:translateY(10px);opacity:0}.fade-up-enter-active[data-v-04240f9d],.fade-up-leave-active[data-v-04240f9d]{transition:opacity .2s ease-out}.fade-up-enter-from[data-v-04240f9d],.fade-up-leave-to[data-v-04240f9d]{opacity:0}.fade-enter-active[data-v-0df46b7b],.fade-leave-active[data-v-0df46b7b]{transition:opacity .15s ease}.fade-enter-from[data-v-0df46b7b],.fade-leave-to[data-v-0df46b7b]{opacity:0}.fade-enter-active[data-v-d712cb76],.fade-leave-active[data-v-d712cb76]{transition:opacity .15s ease}.fade-enter-from[data-v-d712cb76],.fade-leave-to[data-v-d712cb76]{opacity:0}.titlebar-drag-cover[data-v-b3d2cc85]{position:absolute;left:0;right:0;z-index:50;top:calc(-1 * var(--titlebar-area-height));height:calc(var(--titlebar-area-height) + 1rem);-webkit-app-region:drag}
1
+ .writing-vertical[data-v-19a25590]{writing-mode:vertical-rl;text-orientation:mixed}.data-flow-bg[data-v-19a25590]{background:repeating-linear-gradient(0deg,transparent,transparent 20px,currentColor 20px,currentColor 21px);animation:dataFlow-19a25590 20s linear infinite}@keyframes dataFlow-19a25590{0%{transform:translateY(0)}to{transform:translateY(-100px)}}.mention-menu-enter-active[data-v-0262c6da],.mention-menu-leave-active[data-v-0262c6da]{transition:opacity .16s ease,transform .16s ease}.mention-menu-enter-from[data-v-0262c6da],.mention-menu-leave-to[data-v-0262c6da]{transform:translateY(8px);opacity:0}.slash-menu-enter-active[data-v-0853b251],.slash-menu-leave-active[data-v-0853b251]{transition:opacity .16s ease,transform .16s ease}.slash-menu-enter-from[data-v-0853b251],.slash-menu-leave-to[data-v-0853b251]{transform:translateY(8px);opacity:0}.custom-scrollbar[data-v-94ffe515]::-webkit-scrollbar{width:4px}.custom-scrollbar[data-v-94ffe515]::-webkit-scrollbar-track{background:transparent}.custom-scrollbar[data-v-94ffe515]::-webkit-scrollbar-thumb{border-radius:4px;background-color:#9ca3af4d}.dark .custom-scrollbar[data-v-94ffe515]::-webkit-scrollbar-thumb{background-color:#9ca3af26}.slide-fade-enter-active[data-v-cf4f2fa6],.slide-fade-leave-active[data-v-cf4f2fa6]{transition:all .3s ease-out}.slide-fade-enter-from[data-v-cf4f2fa6],.slide-fade-leave-to[data-v-cf4f2fa6]{transform:translate(20px);opacity:0}.slide-up-enter-active[data-v-cf4f2fa6],.slide-up-leave-active[data-v-cf4f2fa6]{transition:all .3s ease-out}.slide-up-enter-from[data-v-cf4f2fa6],.slide-up-leave-to[data-v-cf4f2fa6]{transform:translateY(10px);opacity:0}.fade-up-enter-active[data-v-cf4f2fa6],.fade-up-leave-active[data-v-cf4f2fa6]{transition:opacity .2s ease-out}.fade-up-enter-from[data-v-cf4f2fa6],.fade-up-leave-to[data-v-cf4f2fa6]{opacity:0}.fade-enter-active[data-v-0df46b7b],.fade-leave-active[data-v-0df46b7b]{transition:opacity .15s ease}.fade-enter-from[data-v-0df46b7b],.fade-leave-to[data-v-0df46b7b]{opacity:0}.fade-enter-active[data-v-d712cb76],.fade-leave-active[data-v-d712cb76]{transition:opacity .15s ease}.fade-enter-from[data-v-d712cb76],.fade-leave-to[data-v-d712cb76]{opacity:0}.titlebar-drag-cover[data-v-b3d2cc85]{position:absolute;left:0;right:0;z-index:50;top:calc(-1 * var(--titlebar-area-height));height:calc(var(--titlebar-area-height) + 1rem);-webkit-app-region:drag}