@glbgpt/cli 0.1.0-test.1

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 (173) hide show
  1. package/README.md +111 -0
  2. package/dist/src/auth/authClient.d.ts +32 -0
  3. package/dist/src/auth/authClient.js +88 -0
  4. package/dist/src/auth/authClient.js.map +1 -0
  5. package/dist/src/auth/credentialStore.d.ts +22 -0
  6. package/dist/src/auth/credentialStore.js +51 -0
  7. package/dist/src/auth/credentialStore.js.map +1 -0
  8. package/dist/src/auth/loginFlow.d.ts +30 -0
  9. package/dist/src/auth/loginFlow.js +43 -0
  10. package/dist/src/auth/loginFlow.js.map +1 -0
  11. package/dist/src/auth/loopbackServer.d.ts +41 -0
  12. package/dist/src/auth/loopbackServer.js +141 -0
  13. package/dist/src/auth/loopbackServer.js.map +1 -0
  14. package/dist/src/auth/token.d.ts +8 -0
  15. package/dist/src/auth/token.js +15 -0
  16. package/dist/src/auth/token.js.map +1 -0
  17. package/dist/src/commands/accountCommand.d.ts +2 -0
  18. package/dist/src/commands/accountCommand.js +56 -0
  19. package/dist/src/commands/accountCommand.js.map +1 -0
  20. package/dist/src/commands/configCommand.d.ts +4 -0
  21. package/dist/src/commands/configCommand.js +53 -0
  22. package/dist/src/commands/configCommand.js.map +1 -0
  23. package/dist/src/commands/execCommand.d.ts +32 -0
  24. package/dist/src/commands/execCommand.js +122 -0
  25. package/dist/src/commands/execCommand.js.map +1 -0
  26. package/dist/src/commands/loginCommand.d.ts +11 -0
  27. package/dist/src/commands/loginCommand.js +96 -0
  28. package/dist/src/commands/loginCommand.js.map +1 -0
  29. package/dist/src/commands/mediaCommand.d.ts +41 -0
  30. package/dist/src/commands/mediaCommand.js +277 -0
  31. package/dist/src/commands/mediaCommand.js.map +1 -0
  32. package/dist/src/config/configFile.d.ts +30 -0
  33. package/dist/src/config/configFile.js +54 -0
  34. package/dist/src/config/configFile.js.map +1 -0
  35. package/dist/src/config/env.d.ts +6 -0
  36. package/dist/src/config/env.js +24 -0
  37. package/dist/src/config/env.js.map +1 -0
  38. package/dist/src/config/paths.d.ts +6 -0
  39. package/dist/src/config/paths.js +16 -0
  40. package/dist/src/config/paths.js.map +1 -0
  41. package/dist/src/core/catalog.d.ts +49 -0
  42. package/dist/src/core/catalog.js +96 -0
  43. package/dist/src/core/catalog.js.map +1 -0
  44. package/dist/src/core/httpChatBackend.d.ts +31 -0
  45. package/dist/src/core/httpChatBackend.js +134 -0
  46. package/dist/src/core/httpChatBackend.js.map +1 -0
  47. package/dist/src/core/id.d.ts +2 -0
  48. package/dist/src/core/id.js +5 -0
  49. package/dist/src/core/id.js.map +1 -0
  50. package/dist/src/core/runChat.d.ts +28 -0
  51. package/dist/src/core/runChat.js +49 -0
  52. package/dist/src/core/runChat.js.map +1 -0
  53. package/dist/src/core/session.d.ts +44 -0
  54. package/dist/src/core/session.js +70 -0
  55. package/dist/src/core/session.js.map +1 -0
  56. package/dist/src/core/sessionStore.d.ts +39 -0
  57. package/dist/src/core/sessionStore.js +106 -0
  58. package/dist/src/core/sessionStore.js.map +1 -0
  59. package/dist/src/core/toolRegistry.d.ts +19 -0
  60. package/dist/src/core/toolRegistry.js +53 -0
  61. package/dist/src/core/toolRegistry.js.map +1 -0
  62. package/dist/src/core/tools/generateImage.d.ts +10 -0
  63. package/dist/src/core/tools/generateImage.js +34 -0
  64. package/dist/src/core/tools/generateImage.js.map +1 -0
  65. package/dist/src/core/turnLoop.d.ts +31 -0
  66. package/dist/src/core/turnLoop.js +155 -0
  67. package/dist/src/core/turnLoop.js.map +1 -0
  68. package/dist/src/core/types.d.ts +137 -0
  69. package/dist/src/core/types.js +9 -0
  70. package/dist/src/core/types.js.map +1 -0
  71. package/dist/src/exec/input.d.ts +35 -0
  72. package/dist/src/exec/input.js +85 -0
  73. package/dist/src/exec/input.js.map +1 -0
  74. package/dist/src/exec/output.d.ts +39 -0
  75. package/dist/src/exec/output.js +84 -0
  76. package/dist/src/exec/output.js.map +1 -0
  77. package/dist/src/index.d.ts +2 -0
  78. package/dist/src/index.js +253 -0
  79. package/dist/src/index.js.map +1 -0
  80. package/dist/src/mcp/server.d.ts +38 -0
  81. package/dist/src/mcp/server.js +99 -0
  82. package/dist/src/mcp/server.js.map +1 -0
  83. package/dist/src/media/aiApiClient.d.ts +53 -0
  84. package/dist/src/media/aiApiClient.js +97 -0
  85. package/dist/src/media/aiApiClient.js.map +1 -0
  86. package/dist/src/media/errors.d.ts +7 -0
  87. package/dist/src/media/errors.js +70 -0
  88. package/dist/src/media/errors.js.map +1 -0
  89. package/dist/src/media/executor.d.ts +50 -0
  90. package/dist/src/media/executor.js +55 -0
  91. package/dist/src/media/executor.js.map +1 -0
  92. package/dist/src/media/generateImageTool.d.ts +19 -0
  93. package/dist/src/media/generateImageTool.js +120 -0
  94. package/dist/src/media/generateImageTool.js.map +1 -0
  95. package/dist/src/media/manifest.d.ts +23 -0
  96. package/dist/src/media/manifest.js +558 -0
  97. package/dist/src/media/manifest.js.map +1 -0
  98. package/dist/src/media/resolution.d.ts +13 -0
  99. package/dist/src/media/resolution.js +42 -0
  100. package/dist/src/media/resolution.js.map +1 -0
  101. package/dist/src/media/taskLedger.d.ts +17 -0
  102. package/dist/src/media/taskLedger.js +44 -0
  103. package/dist/src/media/taskLedger.js.map +1 -0
  104. package/dist/src/media/taskManager.d.ts +52 -0
  105. package/dist/src/media/taskManager.js +130 -0
  106. package/dist/src/media/taskManager.js.map +1 -0
  107. package/dist/src/media/types.d.ts +80 -0
  108. package/dist/src/media/types.js +15 -0
  109. package/dist/src/media/types.js.map +1 -0
  110. package/dist/src/tui/App.d.ts +34 -0
  111. package/dist/src/tui/App.js +540 -0
  112. package/dist/src/tui/App.js.map +1 -0
  113. package/dist/src/tui/MultilineInput.d.ts +36 -0
  114. package/dist/src/tui/MultilineInput.js +221 -0
  115. package/dist/src/tui/MultilineInput.js.map +1 -0
  116. package/dist/src/tui/atPopup.d.ts +21 -0
  117. package/dist/src/tui/atPopup.js +55 -0
  118. package/dist/src/tui/atPopup.js.map +1 -0
  119. package/dist/src/tui/attachments.d.ts +24 -0
  120. package/dist/src/tui/attachments.js +91 -0
  121. package/dist/src/tui/attachments.js.map +1 -0
  122. package/dist/src/tui/branding.d.ts +22 -0
  123. package/dist/src/tui/branding.js +119 -0
  124. package/dist/src/tui/branding.js.map +1 -0
  125. package/dist/src/tui/chatController.d.ts +188 -0
  126. package/dist/src/tui/chatController.js +614 -0
  127. package/dist/src/tui/chatController.js.map +1 -0
  128. package/dist/src/tui/commands.d.ts +13 -0
  129. package/dist/src/tui/commands.js +22 -0
  130. package/dist/src/tui/commands.js.map +1 -0
  131. package/dist/src/tui/confirmationBridge.d.ts +23 -0
  132. package/dist/src/tui/confirmationBridge.js +47 -0
  133. package/dist/src/tui/confirmationBridge.js.map +1 -0
  134. package/dist/src/tui/inputHistory.d.ts +7 -0
  135. package/dist/src/tui/inputHistory.js +64 -0
  136. package/dist/src/tui/inputHistory.js.map +1 -0
  137. package/dist/src/tui/markdown.d.ts +1 -0
  138. package/dist/src/tui/markdown.js +143 -0
  139. package/dist/src/tui/markdown.js.map +1 -0
  140. package/dist/src/tui/models.d.ts +30 -0
  141. package/dist/src/tui/models.js +54 -0
  142. package/dist/src/tui/models.js.map +1 -0
  143. package/dist/src/tui/run.d.ts +29 -0
  144. package/dist/src/tui/run.js +212 -0
  145. package/dist/src/tui/run.js.map +1 -0
  146. package/dist/src/tui/slashMedia.d.ts +36 -0
  147. package/dist/src/tui/slashMedia.js +86 -0
  148. package/dist/src/tui/slashMedia.js.map +1 -0
  149. package/dist/src/tui/visualLines.d.ts +38 -0
  150. package/dist/src/tui/visualLines.js +110 -0
  151. package/dist/src/tui/visualLines.js.map +1 -0
  152. package/dist/src/util/clipboardImage.d.ts +6 -0
  153. package/dist/src/util/clipboardImage.js +69 -0
  154. package/dist/src/util/clipboardImage.js.map +1 -0
  155. package/dist/src/util/hyperlink.d.ts +10 -0
  156. package/dist/src/util/hyperlink.js +33 -0
  157. package/dist/src/util/hyperlink.js.map +1 -0
  158. package/dist/src/util/imageRef.d.ts +15 -0
  159. package/dist/src/util/imageRef.js +46 -0
  160. package/dist/src/util/imageRef.js.map +1 -0
  161. package/dist/src/util/inlineImage.d.ts +13 -0
  162. package/dist/src/util/inlineImage.js +56 -0
  163. package/dist/src/util/inlineImage.js.map +1 -0
  164. package/dist/src/util/openBrowser.d.ts +5 -0
  165. package/dist/src/util/openBrowser.js +23 -0
  166. package/dist/src/util/openBrowser.js.map +1 -0
  167. package/dist/src/util/retry.d.ts +43 -0
  168. package/dist/src/util/retry.js +116 -0
  169. package/dist/src/util/retry.js.map +1 -0
  170. package/dist/src/version.d.ts +6 -0
  171. package/dist/src/version.js +16 -0
  172. package/dist/src/version.js.map +1 -0
  173. package/package.json +45 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hyperlink.js","sourceRoot":"","sources":["../../../src/util/hyperlink.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,wFAAwF;AACxF,oFAAoF;AACpF,6EAA6E;AAC7E,MAAM,mBAAmB,GAAG,CAAC,WAAW,EAAE,QAAQ,EAAE,SAAS,EAAE,QAAQ,EAAE,SAAS,EAAE,OAAO,EAAE,OAAO,EAAE,WAAW,CAAC,CAAC;AAEnH,MAAM,UAAU,kBAAkB,CAAC,MAAyB,OAAO,CAAC,GAAG;IACrE,IAAI,GAAG,CAAC,eAAe,IAAI,GAAG,CAAC,eAAe,KAAK,GAAG;QAAE,OAAO,IAAI,CAAC;IACpE,IAAI,mBAAmB,CAAC,QAAQ,CAAC,GAAG,CAAC,YAAY,IAAI,EAAE,CAAC,IAAI,mBAAmB,CAAC,QAAQ,CAAC,GAAG,CAAC,WAAW,IAAI,EAAE,CAAC;QAAE,OAAO,IAAI,CAAC;IAC7H,IAAI,GAAG,CAAC,eAAe,IAAI,GAAG,CAAC,IAAI,EAAE,QAAQ,CAAC,OAAO,CAAC;QAAE,OAAO,IAAI,CAAC,CAAC,mCAAmC;IACxG,IAAI,GAAG,CAAC,WAAW,IAAI,MAAM,CAAC,GAAG,CAAC,WAAW,CAAC,IAAI,IAAI;QAAE,OAAO,IAAI,CAAC,CAAC,wBAAwB;IAC7F,IAAI,GAAG,CAAC,UAAU;QAAE,OAAO,IAAI,CAAC,CAAC,mBAAmB;IACpD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,8EAA8E;AAC9E,MAAM,UAAU,SAAS,CAAC,IAAY,EAAE,GAAW,EAAE,MAAyB,OAAO,CAAC,GAAG;IACvF,IAAI,CAAC,kBAAkB,CAAC,GAAG,CAAC;QAAE,OAAO,IAAI,CAAC;IAC1C,OAAO,WAAW,GAAG,OAAO,IAAI,cAAc,CAAC;AACjD,CAAC;AAED,iEAAiE;AACjE,MAAM,UAAU,OAAO,CAAC,SAAiB;IACvC,OAAO,UAAU,SAAS,CAAC,SAAS,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC,EAAE,CAAC;AAC/D,CAAC"}
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Resolve an image reference (exec --image, MCP image input, TUI @path) into a URL the
3
+ * chat API accepts as an image_url part:
4
+ * - http(s) and data: URLs pass through untouched (the backend/upstream fetches them);
5
+ * - anything else is treated as a local file and inlined as a data URL
6
+ * (png/jpg/gif/webp only, ≤ 8MB).
7
+ *
8
+ * Throws ImageRefError with a user-facing message on anything unusable.
9
+ */
10
+ export declare class ImageRefError extends Error {
11
+ }
12
+ export declare const MAX_IMAGE_BYTES: number;
13
+ /** File extensions we treat as attachable images (single source — popup/tokenizer/clipboard agree). */
14
+ export declare const IMAGE_EXT: RegExp;
15
+ export declare function resolveImageRef(ref: string, readFile?: (p: string) => Promise<Buffer>): Promise<string>;
@@ -0,0 +1,46 @@
1
+ import { promises as fs } from 'node:fs';
2
+ import path from 'node:path';
3
+ import os from 'node:os';
4
+ /**
5
+ * Resolve an image reference (exec --image, MCP image input, TUI @path) into a URL the
6
+ * chat API accepts as an image_url part:
7
+ * - http(s) and data: URLs pass through untouched (the backend/upstream fetches them);
8
+ * - anything else is treated as a local file and inlined as a data URL
9
+ * (png/jpg/gif/webp only, ≤ 8MB).
10
+ *
11
+ * Throws ImageRefError with a user-facing message on anything unusable.
12
+ */
13
+ export class ImageRefError extends Error {
14
+ }
15
+ export const MAX_IMAGE_BYTES = 8 * 1024 * 1024;
16
+ /** File extensions we treat as attachable images (single source — popup/tokenizer/clipboard agree). */
17
+ export const IMAGE_EXT = /\.(png|jpe?g|gif|webp)$/i;
18
+ const MIME = {
19
+ '.png': 'image/png',
20
+ '.jpg': 'image/jpeg',
21
+ '.jpeg': 'image/jpeg',
22
+ '.gif': 'image/gif',
23
+ '.webp': 'image/webp',
24
+ };
25
+ export async function resolveImageRef(ref, readFile = (p) => fs.readFile(p)) {
26
+ if (/^(https?:|data:)/i.test(ref))
27
+ return ref;
28
+ const ext = path.extname(ref).toLowerCase();
29
+ const mime = MIME[ext];
30
+ if (!mime) {
31
+ throw new ImageRefError(`Cannot attach ${ref}: only png/jpg/gif/webp images are supported.`);
32
+ }
33
+ const filePath = ref.startsWith('~/') ? path.join(os.homedir(), ref.slice(2)) : ref;
34
+ let data;
35
+ try {
36
+ data = await readFile(filePath);
37
+ }
38
+ catch {
39
+ throw new ImageRefError(`Cannot attach ${ref}: file not found or unreadable.`);
40
+ }
41
+ if (data.length === 0 || data.length > MAX_IMAGE_BYTES) {
42
+ throw new ImageRefError(`Cannot attach ${ref}: file is empty or larger than 8MB.`);
43
+ }
44
+ return `data:${mime};base64,${data.toString('base64')}`;
45
+ }
46
+ //# sourceMappingURL=imageRef.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"imageRef.js","sourceRoot":"","sources":["../../../src/util/imageRef.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,IAAI,EAAE,EAAE,MAAM,SAAS,CAAC;AACzC,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,MAAM,SAAS,CAAC;AAEzB;;;;;;;;GAQG;AAEH,MAAM,OAAO,aAAc,SAAQ,KAAK;CAAG;AAE3C,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,GAAG,IAAI,GAAG,IAAI,CAAC;AAE/C,uGAAuG;AACvG,MAAM,CAAC,MAAM,SAAS,GAAG,0BAA0B,CAAC;AAEpD,MAAM,IAAI,GAA2B;IACnC,MAAM,EAAE,WAAW;IACnB,MAAM,EAAE,YAAY;IACpB,OAAO,EAAE,YAAY;IACrB,MAAM,EAAE,WAAW;IACnB,OAAO,EAAE,YAAY;CACtB,CAAC;AAEF,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,GAAW,EACX,WAA2C,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC;IAEhE,IAAI,mBAAmB,CAAC,IAAI,CAAC,GAAG,CAAC;QAAE,OAAO,GAAG,CAAC;IAE9C,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,WAAW,EAAE,CAAC;IAC5C,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC;IACvB,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,MAAM,IAAI,aAAa,CAAC,iBAAiB,GAAG,+CAA+C,CAAC,CAAC;IAC/F,CAAC;IACD,MAAM,QAAQ,GAAG,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC;IACpF,IAAI,IAAY,CAAC;IACjB,IAAI,CAAC;QACH,IAAI,GAAG,MAAM,QAAQ,CAAC,QAAQ,CAAC,CAAC;IAClC,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,IAAI,aAAa,CAAC,iBAAiB,GAAG,iCAAiC,CAAC,CAAC;IACjF,CAAC;IACD,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,IAAI,IAAI,CAAC,MAAM,GAAG,eAAe,EAAE,CAAC;QACvD,MAAM,IAAI,aAAa,CAAC,iBAAiB,GAAG,qCAAqC,CAAC,CAAC;IACrF,CAAC;IACD,OAAO,QAAQ,IAAI,WAAW,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;AAC1D,CAAC"}
@@ -0,0 +1,13 @@
1
+ /** Whether the attached terminal understands OSC 1337 inline images. */
2
+ export declare function supportsInlineImages(env?: NodeJS.ProcessEnv): boolean;
3
+ /** Build the OSC 1337 escape sequence for one image buffer. */
4
+ export declare function inlineImageSequence(data: Buffer, name: string): string;
5
+ /**
6
+ * Print an inline preview of a downloaded file to stderr when everything lines up
7
+ * (supported terminal, TTY, image extension, sane size). Never throws.
8
+ */
9
+ export declare function maybePrintInlinePreview(filePath: string, opts?: {
10
+ env?: NodeJS.ProcessEnv;
11
+ write?: (s: string) => void;
12
+ isTty?: boolean;
13
+ }): Promise<boolean>;
@@ -0,0 +1,56 @@
1
+ import { promises as fs } from 'node:fs';
2
+ import path from 'node:path';
3
+ /**
4
+ * Inline image previews via the iTerm2 OSC 1337 protocol (also spoken by WezTerm).
5
+ *
6
+ * Used by the top-level image/video/task commands after a download: the escape sequence goes
7
+ * to STDERR so stdout keeps its machine-readable contract (the local path only). Anything
8
+ * unsupported — other terminals, non-image files, huge files, non-TTY stderr — degrades to
9
+ * printing nothing extra.
10
+ */
11
+ const IMAGE_EXTS = new Set(['.png', '.jpg', '.jpeg', '.gif', '.webp']);
12
+ /** Skip inlining beyond this size — encoding + rendering a huge raster stalls the terminal. */
13
+ const MAX_INLINE_BYTES = 5 * 1024 * 1024;
14
+ /** Rendered height in text rows. */
15
+ const PREVIEW_ROWS = 12;
16
+ /** Whether the attached terminal understands OSC 1337 inline images. */
17
+ export function supportsInlineImages(env = process.env) {
18
+ const program = env.TERM_PROGRAM ?? '';
19
+ return program === 'iTerm.app' || program === 'WezTerm';
20
+ }
21
+ /** Build the OSC 1337 escape sequence for one image buffer. */
22
+ export function inlineImageSequence(data, name) {
23
+ const args = [
24
+ `name=${Buffer.from(name).toString('base64')}`,
25
+ `size=${data.length}`,
26
+ 'inline=1',
27
+ `height=${PREVIEW_ROWS}`,
28
+ 'preserveAspectRatio=1',
29
+ ].join(';');
30
+ return `\x1b]1337;File=${args}:${data.toString('base64')}\x07`;
31
+ }
32
+ /**
33
+ * Print an inline preview of a downloaded file to stderr when everything lines up
34
+ * (supported terminal, TTY, image extension, sane size). Never throws.
35
+ */
36
+ export async function maybePrintInlinePreview(filePath, opts = {}) {
37
+ const env = opts.env ?? process.env;
38
+ const isTty = opts.isTty ?? process.stderr.isTTY === true;
39
+ const write = opts.write ?? ((s) => process.stderr.write(s));
40
+ if (!isTty || !supportsInlineImages(env))
41
+ return false;
42
+ if (!IMAGE_EXTS.has(path.extname(filePath).toLowerCase()))
43
+ return false;
44
+ try {
45
+ const stat = await fs.stat(filePath);
46
+ if (stat.size === 0 || stat.size > MAX_INLINE_BYTES)
47
+ return false;
48
+ const data = await fs.readFile(filePath);
49
+ write(`${inlineImageSequence(data, path.basename(filePath))}\n`);
50
+ return true;
51
+ }
52
+ catch {
53
+ return false;
54
+ }
55
+ }
56
+ //# sourceMappingURL=inlineImage.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"inlineImage.js","sourceRoot":"","sources":["../../../src/util/inlineImage.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,IAAI,EAAE,EAAE,MAAM,SAAS,CAAC;AACzC,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B;;;;;;;GAOG;AAEH,MAAM,UAAU,GAAG,IAAI,GAAG,CAAC,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;AACvE,+FAA+F;AAC/F,MAAM,gBAAgB,GAAG,CAAC,GAAG,IAAI,GAAG,IAAI,CAAC;AACzC,oCAAoC;AACpC,MAAM,YAAY,GAAG,EAAE,CAAC;AAExB,wEAAwE;AACxE,MAAM,UAAU,oBAAoB,CAAC,MAAyB,OAAO,CAAC,GAAG;IACvE,MAAM,OAAO,GAAG,GAAG,CAAC,YAAY,IAAI,EAAE,CAAC;IACvC,OAAO,OAAO,KAAK,WAAW,IAAI,OAAO,KAAK,SAAS,CAAC;AAC1D,CAAC;AAED,+DAA+D;AAC/D,MAAM,UAAU,mBAAmB,CAAC,IAAY,EAAE,IAAY;IAC5D,MAAM,IAAI,GAAG;QACX,QAAQ,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE;QAC9C,QAAQ,IAAI,CAAC,MAAM,EAAE;QACrB,UAAU;QACV,UAAU,YAAY,EAAE;QACxB,uBAAuB;KACxB,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACZ,OAAO,kBAAkB,IAAI,IAAI,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,MAAM,CAAC;AACjE,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,uBAAuB,CAC3C,QAAgB,EAChB,OAAkF,EAAE;IAEpF,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,IAAI,OAAO,CAAC,GAAG,CAAC;IACpC,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,IAAI,OAAO,CAAC,MAAM,CAAC,KAAK,KAAK,IAAI,CAAC;IAC1D,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,IAAI,CAAC,CAAC,CAAS,EAAE,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;IAErE,IAAI,CAAC,KAAK,IAAI,CAAC,oBAAoB,CAAC,GAAG,CAAC;QAAE,OAAO,KAAK,CAAC;IACvD,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,WAAW,EAAE,CAAC;QAAE,OAAO,KAAK,CAAC;IACxE,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,MAAM,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QACrC,IAAI,IAAI,CAAC,IAAI,KAAK,CAAC,IAAI,IAAI,CAAC,IAAI,GAAG,gBAAgB;YAAE,OAAO,KAAK,CAAC;QAClE,MAAM,IAAI,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;QACzC,KAAK,CAAC,GAAG,mBAAmB,CAAC,IAAI,EAAE,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,CAAC;QACjE,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Open a URL in the user's default browser. Best-effort and non-blocking; if it fails,
3
+ * the caller should still print the URL so the user can open it manually.
4
+ */
5
+ export declare function openBrowser(url: string): void;
@@ -0,0 +1,23 @@
1
+ import { spawn } from 'node:child_process';
2
+ /**
3
+ * Open a URL in the user's default browser. Best-effort and non-blocking; if it fails,
4
+ * the caller should still print the URL so the user can open it manually.
5
+ */
6
+ export function openBrowser(url) {
7
+ const platform = process.platform;
8
+ const [cmd, args] = platform === 'darwin'
9
+ ? ['open', [url]]
10
+ : platform === 'win32'
11
+ ? // `start "" "<url>"`: the quoted title + quoted URL keep `&` from truncating the command.
12
+ ['cmd', ['/c', 'start', '""', `"${url}"`]]
13
+ : ['xdg-open', [url]];
14
+ try {
15
+ const child = spawn(cmd, args, { stdio: 'ignore', detached: true, windowsVerbatimArguments: platform === 'win32' });
16
+ child.on('error', () => { });
17
+ child.unref();
18
+ }
19
+ catch {
20
+ // Ignore; the caller prints the URL as a fallback.
21
+ }
22
+ }
23
+ //# sourceMappingURL=openBrowser.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"openBrowser.js","sourceRoot":"","sources":["../../../src/util/openBrowser.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAE3C;;;GAGG;AACH,MAAM,UAAU,WAAW,CAAC,GAAW;IACrC,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC;IAClC,MAAM,CAAC,GAAG,EAAE,IAAI,CAAC,GACf,QAAQ,KAAK,QAAQ;QACnB,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC;QACjB,CAAC,CAAC,QAAQ,KAAK,OAAO;YACpB,CAAC,CAAC,0FAA0F;gBAC1F,CAAC,KAAK,EAAE,CAAC,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,GAAG,GAAG,CAAC,CAAC;YAC5C,CAAC,CAAC,CAAC,UAAU,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IAC5B,IAAI,CAAC;QACH,MAAM,KAAK,GAAG,KAAK,CAAC,GAAG,EAAE,IAAI,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAE,wBAAwB,EAAE,QAAQ,KAAK,OAAO,EAAE,CAAC,CAAC;QACpH,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;QAC5B,KAAK,CAAC,KAAK,EAAE,CAAC;IAChB,CAAC;IAAC,MAAM,CAAC;QACP,mDAAmD;IACrD,CAAC;AACH,CAAC"}
@@ -0,0 +1,43 @@
1
+ /**
2
+ * Bounded retry with exponential backoff, for transient network failures.
3
+ *
4
+ * Safety: callers must only wrap operations that are safe to repeat. In particular a streaming
5
+ * request may be retried only *before* the first response byte is consumed — once bytes flow,
6
+ * replaying the call would double-bill. Non-idempotent writes (e.g. a media `submit`) must not be
7
+ * wrapped at all.
8
+ */
9
+ export interface RetryOptions {
10
+ /** Max retries after the first attempt (default 3 → up to 4 total attempts). */
11
+ retries?: number;
12
+ /** Base backoff in ms; attempt n waits ~base * 2^n with jitter (default 300). */
13
+ baseMs?: number;
14
+ /** Injected sleep (tests pass a no-op). */
15
+ sleep?: (ms: number) => Promise<void>;
16
+ /** Injected jitter factor in [0,1) (tests pass a constant). Default random. */
17
+ jitter?: () => number;
18
+ /** Retry a returned value (e.g. an HTTP 502 Response). Throws are always retried. */
19
+ isRetryableResult?: (result: unknown) => boolean;
20
+ /** Which thrown errors to retry (default: isTransientNetworkError). Lets callers exclude user aborts. */
21
+ isRetryableError?: (err: unknown) => boolean;
22
+ }
23
+ /**
24
+ * Run `fn`, retrying on a thrown transient error or a retryable result, with exponential backoff.
25
+ * The last attempt's value is returned (or its error thrown) without further retries.
26
+ */
27
+ export declare function withRetry<T>(fn: () => Promise<T>, opts?: RetryOptions): Promise<T>;
28
+ /**
29
+ * Whether a thrown error is a transient, connection-level network failure that is safe to retry
30
+ * (before any response is consumed): DNS/TLS/connection resets, aborts/timeouts, and undici's
31
+ * generic `fetch failed` TypeError whose cause carries a network errno.
32
+ */
33
+ export declare function isTransientNetworkError(err: unknown): boolean;
34
+ /** A friendly, actionable description of a network failure, including the host and retry count. */
35
+ export declare function describeNetworkError(err: unknown, host: string, retries: number): string;
36
+ /** Host portion of a base URL, for user-facing error messages (falls back to the raw string). */
37
+ export declare function hostOf(baseUrl: string): string;
38
+ /**
39
+ * Perform a fetch, translating a transient network throw into a friendly, host-qualified message.
40
+ * Does NOT retry — use {@link withRetry} for that. For one-shot/idempotent calls that only need a
41
+ * readable error instead of a bare `fetch failed`.
42
+ */
43
+ export declare function fetchOrDescribe(fetchImpl: typeof fetch, url: string, init: RequestInit, host: string): Promise<Response>;
@@ -0,0 +1,116 @@
1
+ /**
2
+ * Bounded retry with exponential backoff, for transient network failures.
3
+ *
4
+ * Safety: callers must only wrap operations that are safe to repeat. In particular a streaming
5
+ * request may be retried only *before* the first response byte is consumed — once bytes flow,
6
+ * replaying the call would double-bill. Non-idempotent writes (e.g. a media `submit`) must not be
7
+ * wrapped at all.
8
+ */
9
+ const defaultSleep = (ms) => new Promise((r) => setTimeout(r, ms));
10
+ /**
11
+ * Run `fn`, retrying on a thrown transient error or a retryable result, with exponential backoff.
12
+ * The last attempt's value is returned (or its error thrown) without further retries.
13
+ */
14
+ export async function withRetry(fn, opts = {}) {
15
+ const retries = opts.retries ?? 3;
16
+ const baseMs = opts.baseMs ?? 300;
17
+ const sleep = opts.sleep ?? defaultSleep;
18
+ const jitter = opts.jitter ?? Math.random;
19
+ const isRetryableResult = opts.isRetryableResult ?? (() => false);
20
+ const isRetryableError = opts.isRetryableError ?? isTransientNetworkError;
21
+ let lastError;
22
+ for (let attempt = 0; attempt <= retries; attempt++) {
23
+ try {
24
+ const result = await fn();
25
+ if (attempt < retries && isRetryableResult(result)) {
26
+ await sleep(backoffMs(baseMs, attempt, jitter));
27
+ continue;
28
+ }
29
+ return result;
30
+ }
31
+ catch (err) {
32
+ lastError = err;
33
+ if (attempt < retries && isRetryableError(err)) {
34
+ await sleep(backoffMs(baseMs, attempt, jitter));
35
+ continue;
36
+ }
37
+ throw err;
38
+ }
39
+ }
40
+ // Unreachable (the loop returns or throws), but satisfies the type checker.
41
+ throw lastError;
42
+ }
43
+ function backoffMs(baseMs, attempt, jitter) {
44
+ const exp = baseMs * 2 ** attempt;
45
+ return Math.round(exp * (1 + jitter()));
46
+ }
47
+ /**
48
+ * Whether a thrown error is a transient, connection-level network failure that is safe to retry
49
+ * (before any response is consumed): DNS/TLS/connection resets, aborts/timeouts, and undici's
50
+ * generic `fetch failed` TypeError whose cause carries a network errno.
51
+ */
52
+ export function isTransientNetworkError(err) {
53
+ if (!(err instanceof Error))
54
+ return false;
55
+ if (err.name === 'AbortError' || err.name === 'TimeoutError')
56
+ return true;
57
+ const code = networkErrno(err);
58
+ if (code && TRANSIENT_CODES.has(code))
59
+ return true;
60
+ // undici wraps low-level failures as a TypeError "fetch failed" with a `.cause`.
61
+ return err.message === 'fetch failed';
62
+ }
63
+ const TRANSIENT_CODES = new Set([
64
+ 'ECONNRESET',
65
+ 'ECONNREFUSED',
66
+ 'ENOTFOUND',
67
+ 'EAI_AGAIN',
68
+ 'ETIMEDOUT',
69
+ 'EPIPE',
70
+ 'ECONNABORTED',
71
+ 'UND_ERR_CONNECT_TIMEOUT',
72
+ 'UND_ERR_SOCKET',
73
+ ]);
74
+ function networkErrno(err) {
75
+ const withCode = err;
76
+ if (typeof withCode.code === 'string')
77
+ return withCode.code;
78
+ const cause = withCode.cause;
79
+ if (cause instanceof Error)
80
+ return networkErrno(cause);
81
+ if (cause && typeof cause.code === 'string') {
82
+ return cause.code;
83
+ }
84
+ return undefined;
85
+ }
86
+ /** A friendly, actionable description of a network failure, including the host and retry count. */
87
+ export function describeNetworkError(err, host, retries) {
88
+ const detail = err instanceof Error ? networkErrno(err) ?? err.message : String(err);
89
+ const tries = retries > 0 ? ` (after ${retries} ${retries === 1 ? 'retry' : 'retries'})` : '';
90
+ return `Network error reaching ${host}: ${detail}${tries}. Check your connection and try again.`;
91
+ }
92
+ /** Host portion of a base URL, for user-facing error messages (falls back to the raw string). */
93
+ export function hostOf(baseUrl) {
94
+ try {
95
+ return new URL(baseUrl).host;
96
+ }
97
+ catch {
98
+ return baseUrl;
99
+ }
100
+ }
101
+ /**
102
+ * Perform a fetch, translating a transient network throw into a friendly, host-qualified message.
103
+ * Does NOT retry — use {@link withRetry} for that. For one-shot/idempotent calls that only need a
104
+ * readable error instead of a bare `fetch failed`.
105
+ */
106
+ export async function fetchOrDescribe(fetchImpl, url, init, host) {
107
+ try {
108
+ return await fetchImpl(url, init);
109
+ }
110
+ catch (err) {
111
+ if (isTransientNetworkError(err))
112
+ throw new Error(describeNetworkError(err, host, 0));
113
+ throw err;
114
+ }
115
+ }
116
+ //# sourceMappingURL=retry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"retry.js","sourceRoot":"","sources":["../../../src/util/retry.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAiBH,MAAM,YAAY,GAAG,CAAC,EAAU,EAAiB,EAAE,CAAC,IAAI,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;AAE1F;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,SAAS,CAAI,EAAoB,EAAE,OAAqB,EAAE;IAC9E,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,IAAI,CAAC,CAAC;IAClC,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,IAAI,GAAG,CAAC;IAClC,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,IAAI,YAAY,CAAC;IACzC,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,MAAM,CAAC;IAC1C,MAAM,iBAAiB,GAAG,IAAI,CAAC,iBAAiB,IAAI,CAAC,GAAG,EAAE,CAAC,KAAK,CAAC,CAAC;IAClE,MAAM,gBAAgB,GAAG,IAAI,CAAC,gBAAgB,IAAI,uBAAuB,CAAC;IAE1E,IAAI,SAAkB,CAAC;IACvB,KAAK,IAAI,OAAO,GAAG,CAAC,EAAE,OAAO,IAAI,OAAO,EAAE,OAAO,EAAE,EAAE,CAAC;QACpD,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,EAAE,EAAE,CAAC;YAC1B,IAAI,OAAO,GAAG,OAAO,IAAI,iBAAiB,CAAC,MAAM,CAAC,EAAE,CAAC;gBACnD,MAAM,KAAK,CAAC,SAAS,CAAC,MAAM,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC,CAAC;gBAChD,SAAS;YACX,CAAC;YACD,OAAO,MAAM,CAAC;QAChB,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,SAAS,GAAG,GAAG,CAAC;YAChB,IAAI,OAAO,GAAG,OAAO,IAAI,gBAAgB,CAAC,GAAG,CAAC,EAAE,CAAC;gBAC/C,MAAM,KAAK,CAAC,SAAS,CAAC,MAAM,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC,CAAC;gBAChD,SAAS;YACX,CAAC;YACD,MAAM,GAAG,CAAC;QACZ,CAAC;IACH,CAAC;IACD,4EAA4E;IAC5E,MAAM,SAAS,CAAC;AAClB,CAAC;AAED,SAAS,SAAS,CAAC,MAAc,EAAE,OAAe,EAAE,MAAoB;IACtE,MAAM,GAAG,GAAG,MAAM,GAAG,CAAC,IAAI,OAAO,CAAC;IAClC,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,GAAG,CAAC,CAAC,GAAG,MAAM,EAAE,CAAC,CAAC,CAAC;AAC1C,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,uBAAuB,CAAC,GAAY;IAClD,IAAI,CAAC,CAAC,GAAG,YAAY,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC;IAC1C,IAAI,GAAG,CAAC,IAAI,KAAK,YAAY,IAAI,GAAG,CAAC,IAAI,KAAK,cAAc;QAAE,OAAO,IAAI,CAAC;IAC1E,MAAM,IAAI,GAAG,YAAY,CAAC,GAAG,CAAC,CAAC;IAC/B,IAAI,IAAI,IAAI,eAAe,CAAC,GAAG,CAAC,IAAI,CAAC;QAAE,OAAO,IAAI,CAAC;IACnD,iFAAiF;IACjF,OAAO,GAAG,CAAC,OAAO,KAAK,cAAc,CAAC;AACxC,CAAC;AAED,MAAM,eAAe,GAAG,IAAI,GAAG,CAAC;IAC9B,YAAY;IACZ,cAAc;IACd,WAAW;IACX,WAAW;IACX,WAAW;IACX,OAAO;IACP,cAAc;IACd,yBAAyB;IACzB,gBAAgB;CACjB,CAAC,CAAC;AAEH,SAAS,YAAY,CAAC,GAAU;IAC9B,MAAM,QAAQ,GAAG,GAAyC,CAAC;IAC3D,IAAI,OAAO,QAAQ,CAAC,IAAI,KAAK,QAAQ;QAAE,OAAO,QAAQ,CAAC,IAAI,CAAC;IAC5D,MAAM,KAAK,GAAG,QAAQ,CAAC,KAAK,CAAC;IAC7B,IAAI,KAAK,YAAY,KAAK;QAAE,OAAO,YAAY,CAAC,KAAK,CAAC,CAAC;IACvD,IAAI,KAAK,IAAI,OAAQ,KAA2B,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;QACnE,OAAQ,KAA2B,CAAC,IAAI,CAAC;IAC3C,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,mGAAmG;AACnG,MAAM,UAAU,oBAAoB,CAAC,GAAY,EAAE,IAAY,EAAE,OAAe;IAC9E,MAAM,MAAM,GACV,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,YAAY,CAAC,GAAG,CAAC,IAAI,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;IACxE,MAAM,KAAK,GAAG,OAAO,GAAG,CAAC,CAAC,CAAC,CAAC,WAAW,OAAO,IAAI,OAAO,KAAK,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;IAC9F,OAAO,0BAA0B,IAAI,KAAK,MAAM,GAAG,KAAK,wCAAwC,CAAC;AACnG,CAAC;AAED,iGAAiG;AACjG,MAAM,UAAU,MAAM,CAAC,OAAe;IACpC,IAAI,CAAC;QACH,OAAO,IAAI,GAAG,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC;IAC/B,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,OAAO,CAAC;IACjB,CAAC;AACH,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,SAAuB,EACvB,GAAW,EACX,IAAiB,EACjB,IAAY;IAEZ,IAAI,CAAC;QACH,OAAO,MAAM,SAAS,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;IACpC,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,IAAI,uBAAuB,CAAC,GAAG,CAAC;YAAE,MAAM,IAAI,KAAK,CAAC,oBAAoB,CAAC,GAAG,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;QACtF,MAAM,GAAG,CAAC;IACZ,CAAC;AACH,CAAC"}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * The CLI version, read from package.json at runtime (npm always ships package.json at the
3
+ * tarball root, so `../../package.json` resolves from dist/src/*). Single source — bump the
4
+ * version in package.json only.
5
+ */
6
+ export declare const VERSION: string;
@@ -0,0 +1,16 @@
1
+ import { readFileSync } from 'node:fs';
2
+ /**
3
+ * The CLI version, read from package.json at runtime (npm always ships package.json at the
4
+ * tarball root, so `../../package.json` resolves from dist/src/*). Single source — bump the
5
+ * version in package.json only.
6
+ */
7
+ export const VERSION = (() => {
8
+ try {
9
+ const pkg = JSON.parse(readFileSync(new URL('../../package.json', import.meta.url), 'utf8'));
10
+ return typeof pkg.version === 'string' ? pkg.version : '0.0.0';
11
+ }
12
+ catch {
13
+ return '0.0.0';
14
+ }
15
+ })();
16
+ //# sourceMappingURL=version.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"version.js","sourceRoot":"","sources":["../../src/version.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAEvC;;;;GAIG;AACH,MAAM,CAAC,MAAM,OAAO,GAAW,CAAC,GAAG,EAAE;IACnC,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,GAAG,CAAC,oBAAoB,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC;QAC7F,OAAO,OAAO,GAAG,CAAC,OAAO,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC;IACjE,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,OAAO,CAAC;IACjB,CAAC;AACH,CAAC,CAAC,EAAE,CAAC"}
package/package.json ADDED
@@ -0,0 +1,45 @@
1
+ {
2
+ "name": "@glbgpt/cli",
3
+ "version": "0.1.0-test.1",
4
+ "description": "GlobalGPT 官方终端客户端(对话 TUI / 图片视频生成 / exec)",
5
+ "type": "module",
6
+ "bin": {
7
+ "glbgpt": "dist/src/index.js",
8
+ "globalgpt": "dist/src/index.js"
9
+ },
10
+ "files": [
11
+ "dist/src/",
12
+ "README.md"
13
+ ],
14
+ "engines": {
15
+ "node": ">=18"
16
+ },
17
+ "publishConfig": {
18
+ "access": "public",
19
+ "tag": "test"
20
+ },
21
+ "scripts": {
22
+ "build": "tsc -p tsconfig.json",
23
+ "typecheck": "tsc -p tsconfig.json --noEmit",
24
+ "test": "vitest run",
25
+ "test:watch": "vitest",
26
+ "prepublishOnly": "npm run test && tsc -p tsconfig.build.json",
27
+ "prepack": "tsc -p tsconfig.build.json"
28
+ },
29
+ "dependencies": {
30
+ "@modelcontextprotocol/sdk": "^1.29.0",
31
+ "cli-highlight": "^2.1.11",
32
+ "commander": "^12.1.0",
33
+ "ink": "^7.1.0",
34
+ "marked": "^18.0.6",
35
+ "react": "^19.2.7",
36
+ "wrap-ansi": "^10.0.0"
37
+ },
38
+ "devDependencies": {
39
+ "@types/node": "^22.0.0",
40
+ "@types/react": "^19.2.17",
41
+ "ink-testing-library": "^4.0.0",
42
+ "typescript": "^5.6.0",
43
+ "vitest": "^2.1.0"
44
+ }
45
+ }