@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.
- package/README.md +111 -0
- package/dist/src/auth/authClient.d.ts +32 -0
- package/dist/src/auth/authClient.js +88 -0
- package/dist/src/auth/authClient.js.map +1 -0
- package/dist/src/auth/credentialStore.d.ts +22 -0
- package/dist/src/auth/credentialStore.js +51 -0
- package/dist/src/auth/credentialStore.js.map +1 -0
- package/dist/src/auth/loginFlow.d.ts +30 -0
- package/dist/src/auth/loginFlow.js +43 -0
- package/dist/src/auth/loginFlow.js.map +1 -0
- package/dist/src/auth/loopbackServer.d.ts +41 -0
- package/dist/src/auth/loopbackServer.js +141 -0
- package/dist/src/auth/loopbackServer.js.map +1 -0
- package/dist/src/auth/token.d.ts +8 -0
- package/dist/src/auth/token.js +15 -0
- package/dist/src/auth/token.js.map +1 -0
- package/dist/src/commands/accountCommand.d.ts +2 -0
- package/dist/src/commands/accountCommand.js +56 -0
- package/dist/src/commands/accountCommand.js.map +1 -0
- package/dist/src/commands/configCommand.d.ts +4 -0
- package/dist/src/commands/configCommand.js +53 -0
- package/dist/src/commands/configCommand.js.map +1 -0
- package/dist/src/commands/execCommand.d.ts +32 -0
- package/dist/src/commands/execCommand.js +122 -0
- package/dist/src/commands/execCommand.js.map +1 -0
- package/dist/src/commands/loginCommand.d.ts +11 -0
- package/dist/src/commands/loginCommand.js +96 -0
- package/dist/src/commands/loginCommand.js.map +1 -0
- package/dist/src/commands/mediaCommand.d.ts +41 -0
- package/dist/src/commands/mediaCommand.js +277 -0
- package/dist/src/commands/mediaCommand.js.map +1 -0
- package/dist/src/config/configFile.d.ts +30 -0
- package/dist/src/config/configFile.js +54 -0
- package/dist/src/config/configFile.js.map +1 -0
- package/dist/src/config/env.d.ts +6 -0
- package/dist/src/config/env.js +24 -0
- package/dist/src/config/env.js.map +1 -0
- package/dist/src/config/paths.d.ts +6 -0
- package/dist/src/config/paths.js +16 -0
- package/dist/src/config/paths.js.map +1 -0
- package/dist/src/core/catalog.d.ts +49 -0
- package/dist/src/core/catalog.js +96 -0
- package/dist/src/core/catalog.js.map +1 -0
- package/dist/src/core/httpChatBackend.d.ts +31 -0
- package/dist/src/core/httpChatBackend.js +134 -0
- package/dist/src/core/httpChatBackend.js.map +1 -0
- package/dist/src/core/id.d.ts +2 -0
- package/dist/src/core/id.js +5 -0
- package/dist/src/core/id.js.map +1 -0
- package/dist/src/core/runChat.d.ts +28 -0
- package/dist/src/core/runChat.js +49 -0
- package/dist/src/core/runChat.js.map +1 -0
- package/dist/src/core/session.d.ts +44 -0
- package/dist/src/core/session.js +70 -0
- package/dist/src/core/session.js.map +1 -0
- package/dist/src/core/sessionStore.d.ts +39 -0
- package/dist/src/core/sessionStore.js +106 -0
- package/dist/src/core/sessionStore.js.map +1 -0
- package/dist/src/core/toolRegistry.d.ts +19 -0
- package/dist/src/core/toolRegistry.js +53 -0
- package/dist/src/core/toolRegistry.js.map +1 -0
- package/dist/src/core/tools/generateImage.d.ts +10 -0
- package/dist/src/core/tools/generateImage.js +34 -0
- package/dist/src/core/tools/generateImage.js.map +1 -0
- package/dist/src/core/turnLoop.d.ts +31 -0
- package/dist/src/core/turnLoop.js +155 -0
- package/dist/src/core/turnLoop.js.map +1 -0
- package/dist/src/core/types.d.ts +137 -0
- package/dist/src/core/types.js +9 -0
- package/dist/src/core/types.js.map +1 -0
- package/dist/src/exec/input.d.ts +35 -0
- package/dist/src/exec/input.js +85 -0
- package/dist/src/exec/input.js.map +1 -0
- package/dist/src/exec/output.d.ts +39 -0
- package/dist/src/exec/output.js +84 -0
- package/dist/src/exec/output.js.map +1 -0
- package/dist/src/index.d.ts +2 -0
- package/dist/src/index.js +253 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/mcp/server.d.ts +38 -0
- package/dist/src/mcp/server.js +99 -0
- package/dist/src/mcp/server.js.map +1 -0
- package/dist/src/media/aiApiClient.d.ts +53 -0
- package/dist/src/media/aiApiClient.js +97 -0
- package/dist/src/media/aiApiClient.js.map +1 -0
- package/dist/src/media/errors.d.ts +7 -0
- package/dist/src/media/errors.js +70 -0
- package/dist/src/media/errors.js.map +1 -0
- package/dist/src/media/executor.d.ts +50 -0
- package/dist/src/media/executor.js +55 -0
- package/dist/src/media/executor.js.map +1 -0
- package/dist/src/media/generateImageTool.d.ts +19 -0
- package/dist/src/media/generateImageTool.js +120 -0
- package/dist/src/media/generateImageTool.js.map +1 -0
- package/dist/src/media/manifest.d.ts +23 -0
- package/dist/src/media/manifest.js +558 -0
- package/dist/src/media/manifest.js.map +1 -0
- package/dist/src/media/resolution.d.ts +13 -0
- package/dist/src/media/resolution.js +42 -0
- package/dist/src/media/resolution.js.map +1 -0
- package/dist/src/media/taskLedger.d.ts +17 -0
- package/dist/src/media/taskLedger.js +44 -0
- package/dist/src/media/taskLedger.js.map +1 -0
- package/dist/src/media/taskManager.d.ts +52 -0
- package/dist/src/media/taskManager.js +130 -0
- package/dist/src/media/taskManager.js.map +1 -0
- package/dist/src/media/types.d.ts +80 -0
- package/dist/src/media/types.js +15 -0
- package/dist/src/media/types.js.map +1 -0
- package/dist/src/tui/App.d.ts +34 -0
- package/dist/src/tui/App.js +540 -0
- package/dist/src/tui/App.js.map +1 -0
- package/dist/src/tui/MultilineInput.d.ts +36 -0
- package/dist/src/tui/MultilineInput.js +221 -0
- package/dist/src/tui/MultilineInput.js.map +1 -0
- package/dist/src/tui/atPopup.d.ts +21 -0
- package/dist/src/tui/atPopup.js +55 -0
- package/dist/src/tui/atPopup.js.map +1 -0
- package/dist/src/tui/attachments.d.ts +24 -0
- package/dist/src/tui/attachments.js +91 -0
- package/dist/src/tui/attachments.js.map +1 -0
- package/dist/src/tui/branding.d.ts +22 -0
- package/dist/src/tui/branding.js +119 -0
- package/dist/src/tui/branding.js.map +1 -0
- package/dist/src/tui/chatController.d.ts +188 -0
- package/dist/src/tui/chatController.js +614 -0
- package/dist/src/tui/chatController.js.map +1 -0
- package/dist/src/tui/commands.d.ts +13 -0
- package/dist/src/tui/commands.js +22 -0
- package/dist/src/tui/commands.js.map +1 -0
- package/dist/src/tui/confirmationBridge.d.ts +23 -0
- package/dist/src/tui/confirmationBridge.js +47 -0
- package/dist/src/tui/confirmationBridge.js.map +1 -0
- package/dist/src/tui/inputHistory.d.ts +7 -0
- package/dist/src/tui/inputHistory.js +64 -0
- package/dist/src/tui/inputHistory.js.map +1 -0
- package/dist/src/tui/markdown.d.ts +1 -0
- package/dist/src/tui/markdown.js +143 -0
- package/dist/src/tui/markdown.js.map +1 -0
- package/dist/src/tui/models.d.ts +30 -0
- package/dist/src/tui/models.js +54 -0
- package/dist/src/tui/models.js.map +1 -0
- package/dist/src/tui/run.d.ts +29 -0
- package/dist/src/tui/run.js +212 -0
- package/dist/src/tui/run.js.map +1 -0
- package/dist/src/tui/slashMedia.d.ts +36 -0
- package/dist/src/tui/slashMedia.js +86 -0
- package/dist/src/tui/slashMedia.js.map +1 -0
- package/dist/src/tui/visualLines.d.ts +38 -0
- package/dist/src/tui/visualLines.js +110 -0
- package/dist/src/tui/visualLines.js.map +1 -0
- package/dist/src/util/clipboardImage.d.ts +6 -0
- package/dist/src/util/clipboardImage.js +69 -0
- package/dist/src/util/clipboardImage.js.map +1 -0
- package/dist/src/util/hyperlink.d.ts +10 -0
- package/dist/src/util/hyperlink.js +33 -0
- package/dist/src/util/hyperlink.js.map +1 -0
- package/dist/src/util/imageRef.d.ts +15 -0
- package/dist/src/util/imageRef.js +46 -0
- package/dist/src/util/imageRef.js.map +1 -0
- package/dist/src/util/inlineImage.d.ts +13 -0
- package/dist/src/util/inlineImage.js +56 -0
- package/dist/src/util/inlineImage.js.map +1 -0
- package/dist/src/util/openBrowser.d.ts +5 -0
- package/dist/src/util/openBrowser.js +23 -0
- package/dist/src/util/openBrowser.js.map +1 -0
- package/dist/src/util/retry.d.ts +43 -0
- package/dist/src/util/retry.js +116 -0
- package/dist/src/util/retry.js.map +1 -0
- package/dist/src/version.d.ts +6 -0
- package/dist/src/version.js +16 -0
- package/dist/src/version.js.map +1 -0
- package/package.json +45 -0
|
@@ -0,0 +1,253 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { Command } from 'commander';
|
|
3
|
+
import { basename } from 'node:path';
|
|
4
|
+
import { VERSION } from './version.js';
|
|
5
|
+
/**
|
|
6
|
+
* glbgpt CLI entry (scaffold).
|
|
7
|
+
*
|
|
8
|
+
* Phase 1 focuses on the chat engine (see src/core). The interactive TUI, exec,
|
|
9
|
+
* login, and media commands are wired in subsequent steps. This entry establishes
|
|
10
|
+
* the command surface so `--help` reflects the product contract.
|
|
11
|
+
*
|
|
12
|
+
* All user-facing text is English.
|
|
13
|
+
*/
|
|
14
|
+
const program = new Command();
|
|
15
|
+
// The CLI installs two bins — `glbgpt` and its alias `globalgpt` — so help/usage should
|
|
16
|
+
// name whichever the user actually invoked (fall back to the canonical name).
|
|
17
|
+
const invokedName = process.argv[1] ? basename(process.argv[1]).replace(/\.js$/, '') : 'glbgpt';
|
|
18
|
+
program
|
|
19
|
+
.name(invokedName === 'globalgpt' ? 'globalgpt' : 'glbgpt')
|
|
20
|
+
.description('GlobalGPT in your terminal: chat, image and video generation.')
|
|
21
|
+
.version(VERSION);
|
|
22
|
+
program
|
|
23
|
+
.command('login')
|
|
24
|
+
.description('Authorize with your GlobalGPT account in the browser')
|
|
25
|
+
.option('--no-browser', 'Print the authorization URL instead of opening a browser')
|
|
26
|
+
.option('--code', 'Paste a one-time login code instead (for headless/SSH)')
|
|
27
|
+
.action(async (opts) => {
|
|
28
|
+
const { runLogin } = await import('./commands/loginCommand.js');
|
|
29
|
+
await runLogin({ noBrowser: opts.browser === false, useCode: opts.code === true });
|
|
30
|
+
});
|
|
31
|
+
program
|
|
32
|
+
.command('logout')
|
|
33
|
+
.description('Sign out and remove stored credentials')
|
|
34
|
+
.action(async () => {
|
|
35
|
+
const { runLogout } = await import('./commands/loginCommand.js');
|
|
36
|
+
await runLogout();
|
|
37
|
+
});
|
|
38
|
+
program
|
|
39
|
+
.command('whoami')
|
|
40
|
+
.description('Show the signed-in account')
|
|
41
|
+
.action(async () => {
|
|
42
|
+
const { runWhoami } = await import('./commands/loginCommand.js');
|
|
43
|
+
await runWhoami();
|
|
44
|
+
});
|
|
45
|
+
const account = program
|
|
46
|
+
.command('account')
|
|
47
|
+
.description('Show account summary and recent spend')
|
|
48
|
+
.action(async () => {
|
|
49
|
+
const { runAccount } = await import('./commands/accountCommand.js');
|
|
50
|
+
await runAccount();
|
|
51
|
+
});
|
|
52
|
+
account
|
|
53
|
+
.command('transactions')
|
|
54
|
+
.description('Show recent spend')
|
|
55
|
+
.action(async () => {
|
|
56
|
+
const { runAccountTransactions } = await import('./commands/accountCommand.js');
|
|
57
|
+
await runAccountTransactions();
|
|
58
|
+
});
|
|
59
|
+
program
|
|
60
|
+
.command('exec [prompt]')
|
|
61
|
+
.description('Run a single non-interactive model call (for scripts and external agents)')
|
|
62
|
+
.option('-m, --model <model>', 'Chat model (default gpt-5.6-sol)')
|
|
63
|
+
.option('--system <text>', 'System prompt to steer the model')
|
|
64
|
+
.option('--file <path...>', 'Attach file contents as context (repeatable)')
|
|
65
|
+
.option('-i, --image <path-or-url...>', 'Attach an image for the model to see (repeatable)')
|
|
66
|
+
.option('--output-schema <file>', 'JSON Schema file for the final answer (structured output)')
|
|
67
|
+
.option('--json', 'Emit a single final result object to stdout')
|
|
68
|
+
.option('--jsonl', 'Emit streaming protocol events, one JSON per line')
|
|
69
|
+
.option('-o, --output-last-message <file>', 'Write the final message text to a file')
|
|
70
|
+
.action(async (prompt, opts) => {
|
|
71
|
+
const { runExec } = await import('./commands/execCommand.js');
|
|
72
|
+
const code = await runExec(prompt, {
|
|
73
|
+
model: opts.model,
|
|
74
|
+
system: opts.system,
|
|
75
|
+
file: opts.file,
|
|
76
|
+
image: opts.image,
|
|
77
|
+
outputSchema: opts.outputSchema,
|
|
78
|
+
json: opts.json,
|
|
79
|
+
jsonl: opts.jsonl,
|
|
80
|
+
outputLastMessage: opts.outputLastMessage,
|
|
81
|
+
});
|
|
82
|
+
process.exitCode = code;
|
|
83
|
+
});
|
|
84
|
+
program
|
|
85
|
+
.command('mcp')
|
|
86
|
+
.description('Run an MCP server (stdio) exposing GlobalGPT chat as a tool for external agents')
|
|
87
|
+
.action(async () => {
|
|
88
|
+
const { runMcpServer } = await import('./mcp/server.js');
|
|
89
|
+
await runMcpServer();
|
|
90
|
+
});
|
|
91
|
+
program
|
|
92
|
+
.command('resume [target]')
|
|
93
|
+
.description('Resume a previous conversation (last | <conversation-id>)')
|
|
94
|
+
.action(async (target) => {
|
|
95
|
+
const { runTui, loadResumeSession } = await import('./tui/run.js');
|
|
96
|
+
const resumed = await loadResumeSession(target);
|
|
97
|
+
if (!resumed) {
|
|
98
|
+
const which = target && target !== 'last' ? ` for id: ${target}` : '';
|
|
99
|
+
console.error(`No previous conversation found${which}.`);
|
|
100
|
+
process.exitCode = 1;
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
103
|
+
await runTui({ session: resumed.session, timeline: resumed.timeline });
|
|
104
|
+
});
|
|
105
|
+
program
|
|
106
|
+
.command('image [prompt...]')
|
|
107
|
+
.description('Generate an image')
|
|
108
|
+
.option('-m, --model <model>', 'Model id (see `glbgpt model list`)')
|
|
109
|
+
.option('--aspect-ratio <ratio>', 'Aspect ratio, e.g. 16:9')
|
|
110
|
+
.option('--ar <ratio>', 'Alias for --aspect-ratio')
|
|
111
|
+
.option('--resolution <res>', 'Resolution, e.g. 2K')
|
|
112
|
+
.option('--res <res>', 'Alias for --resolution')
|
|
113
|
+
.option('-i, --image <path...>', 'Reference image path or URL (repeatable)')
|
|
114
|
+
.option('-n, --count <n>', 'Number of images', (v) => parseInt(v, 10))
|
|
115
|
+
.option('--seed <n>', 'Random seed', (v) => parseInt(v, 10))
|
|
116
|
+
.option('--negative-prompt <text>', 'Content to avoid')
|
|
117
|
+
.option('-o, --out <dir>', 'Output directory')
|
|
118
|
+
.option('--estimate', 'Show the price only; do not generate')
|
|
119
|
+
.option('--detach', 'Submit and print the task id without waiting')
|
|
120
|
+
.action(async (prompt, opts) => {
|
|
121
|
+
const { runImage } = await import('./commands/mediaCommand.js');
|
|
122
|
+
await runImage(prompt, {
|
|
123
|
+
model: opts.model,
|
|
124
|
+
aspectRatio: (opts.aspectRatio ?? opts.ar),
|
|
125
|
+
resolution: (opts.resolution ?? opts.res),
|
|
126
|
+
image: opts.image,
|
|
127
|
+
count: opts.count,
|
|
128
|
+
seed: opts.seed,
|
|
129
|
+
negativePrompt: opts.negativePrompt,
|
|
130
|
+
out: opts.out,
|
|
131
|
+
estimate: opts.estimate,
|
|
132
|
+
detach: opts.detach,
|
|
133
|
+
});
|
|
134
|
+
});
|
|
135
|
+
program
|
|
136
|
+
.command('video [prompt...]')
|
|
137
|
+
.description('Generate a video')
|
|
138
|
+
.option('-m, --model <model>', 'Model id (see `glbgpt model list video`)')
|
|
139
|
+
.option('--aspect-ratio <ratio>', 'Aspect ratio, e.g. 16:9')
|
|
140
|
+
.option('--ar <ratio>', 'Alias for --aspect-ratio')
|
|
141
|
+
.option('--resolution <res>', 'Resolution, e.g. 720p')
|
|
142
|
+
.option('--res <res>', 'Alias for --resolution')
|
|
143
|
+
.option('--duration <seconds>', 'Video length in seconds', (v) => parseInt(v, 10))
|
|
144
|
+
.option('--audio', 'Generate a soundtrack')
|
|
145
|
+
.option('--no-audio', 'Do not generate a soundtrack')
|
|
146
|
+
.option('-i, --image <path...>', 'Reference image path or URL (repeatable)')
|
|
147
|
+
.option('--start-image <path>', 'First frame (image-to-video)')
|
|
148
|
+
.option('--end-image <path>', 'Last frame')
|
|
149
|
+
.option('-o, --out <dir>', 'Output directory')
|
|
150
|
+
.option('--estimate', 'Show the price only; do not generate')
|
|
151
|
+
.option('--detach', 'Submit and print the task id without waiting')
|
|
152
|
+
.action(async (prompt, opts) => {
|
|
153
|
+
const { runVideo } = await import('./commands/mediaCommand.js');
|
|
154
|
+
await runVideo(prompt, {
|
|
155
|
+
model: opts.model,
|
|
156
|
+
aspectRatio: (opts.aspectRatio ?? opts.ar),
|
|
157
|
+
resolution: (opts.resolution ?? opts.res),
|
|
158
|
+
duration: opts.duration,
|
|
159
|
+
audio: opts.audio,
|
|
160
|
+
image: opts.image,
|
|
161
|
+
startImage: opts.startImage,
|
|
162
|
+
endImage: opts.endImage,
|
|
163
|
+
out: opts.out,
|
|
164
|
+
estimate: opts.estimate,
|
|
165
|
+
detach: opts.detach,
|
|
166
|
+
});
|
|
167
|
+
});
|
|
168
|
+
const model = program.command('model').description('List and inspect models');
|
|
169
|
+
model
|
|
170
|
+
.command('list [type]')
|
|
171
|
+
.description('List available models (chat|image|video)')
|
|
172
|
+
.action(async (type) => {
|
|
173
|
+
const { runModelList } = await import('./commands/mediaCommand.js');
|
|
174
|
+
await runModelList(type);
|
|
175
|
+
});
|
|
176
|
+
model
|
|
177
|
+
.command('show <model>')
|
|
178
|
+
.description('Show a model\'s parameters and limits')
|
|
179
|
+
.action(async (id) => {
|
|
180
|
+
const { runModelShow } = await import('./commands/mediaCommand.js');
|
|
181
|
+
await runModelShow(id);
|
|
182
|
+
});
|
|
183
|
+
const task = program.command('task').description('Manage generation tasks');
|
|
184
|
+
task
|
|
185
|
+
.command('list')
|
|
186
|
+
.description('List recent tasks')
|
|
187
|
+
.action(async () => {
|
|
188
|
+
const { runTaskList } = await import('./commands/mediaCommand.js');
|
|
189
|
+
await runTaskList();
|
|
190
|
+
});
|
|
191
|
+
task
|
|
192
|
+
.command('show <id>')
|
|
193
|
+
.description('Show a task (id or "last")')
|
|
194
|
+
.action(async (id) => {
|
|
195
|
+
const { runTaskShow } = await import('./commands/mediaCommand.js');
|
|
196
|
+
await runTaskShow(id);
|
|
197
|
+
});
|
|
198
|
+
task
|
|
199
|
+
.command('wait <id>')
|
|
200
|
+
.description('Wait for a task to finish (id or "last")')
|
|
201
|
+
.action(async (id) => {
|
|
202
|
+
const { runTaskWait } = await import('./commands/mediaCommand.js');
|
|
203
|
+
await runTaskWait(id);
|
|
204
|
+
});
|
|
205
|
+
task
|
|
206
|
+
.command('download <id>')
|
|
207
|
+
.description('Download a task result (id or "last")')
|
|
208
|
+
.option('-o, --out <dir>', 'Output directory')
|
|
209
|
+
.action(async (id, opts) => {
|
|
210
|
+
const { runTaskDownload } = await import('./commands/mediaCommand.js');
|
|
211
|
+
await runTaskDownload(id, opts.out);
|
|
212
|
+
});
|
|
213
|
+
const config = program.command('config').description('Manage persistent CLI settings');
|
|
214
|
+
config
|
|
215
|
+
.command('list')
|
|
216
|
+
.description('Show all settings with their effective values')
|
|
217
|
+
.action(async () => {
|
|
218
|
+
const { runConfigList } = await import('./commands/configCommand.js');
|
|
219
|
+
await runConfigList();
|
|
220
|
+
});
|
|
221
|
+
config
|
|
222
|
+
.command('get <key>')
|
|
223
|
+
.description('Print one effective setting')
|
|
224
|
+
.action(async (key) => {
|
|
225
|
+
const { runConfigGet } = await import('./commands/configCommand.js');
|
|
226
|
+
await runConfigGet(key);
|
|
227
|
+
});
|
|
228
|
+
config
|
|
229
|
+
.command('set <key> <value>')
|
|
230
|
+
.description('Persist a setting (env vars still override)')
|
|
231
|
+
.action(async (key, value) => {
|
|
232
|
+
const { runConfigSet } = await import('./commands/configCommand.js');
|
|
233
|
+
await runConfigSet(key, value);
|
|
234
|
+
});
|
|
235
|
+
config
|
|
236
|
+
.command('unset <key>')
|
|
237
|
+
.description('Remove a persisted setting')
|
|
238
|
+
.action(async (key) => {
|
|
239
|
+
const { runConfigUnset } = await import('./commands/configCommand.js');
|
|
240
|
+
await runConfigUnset(key);
|
|
241
|
+
});
|
|
242
|
+
// Default: with no subcommand, `glbgpt` (optionally with a prompt) enters the chat TUI.
|
|
243
|
+
program
|
|
244
|
+
.argument('[prompt...]', 'Start a chat TUI (optionally with an initial prompt)')
|
|
245
|
+
.action(async (prompt) => {
|
|
246
|
+
const { runTui } = await import('./tui/run.js');
|
|
247
|
+
await runTui({ initialPrompt: prompt.join(' ') });
|
|
248
|
+
});
|
|
249
|
+
program.parseAsync().catch((err) => {
|
|
250
|
+
console.error(err instanceof Error ? err.message : String(err));
|
|
251
|
+
process.exitCode = 1;
|
|
252
|
+
});
|
|
253
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
2
|
+
import type { ChatBackend } from '../core/types.js';
|
|
3
|
+
/** Arguments for the `glbgpt_chat` tool. */
|
|
4
|
+
export interface ChatToolArgs {
|
|
5
|
+
prompt: string;
|
|
6
|
+
system?: string;
|
|
7
|
+
model?: string;
|
|
8
|
+
/** Image references the model should see: local paths, http(s) URLs, or data URLs. */
|
|
9
|
+
images?: string[];
|
|
10
|
+
response_schema?: Record<string, unknown>;
|
|
11
|
+
}
|
|
12
|
+
/** MCP CallToolResult shape (text content + optional error flag). */
|
|
13
|
+
export interface ToolResult {
|
|
14
|
+
[key: string]: unknown;
|
|
15
|
+
content: Array<{
|
|
16
|
+
type: 'text';
|
|
17
|
+
text: string;
|
|
18
|
+
}>;
|
|
19
|
+
isError?: boolean;
|
|
20
|
+
}
|
|
21
|
+
/** Injectable deps so the tool handler is unit-testable without a live transport. */
|
|
22
|
+
export interface ChatToolDeps {
|
|
23
|
+
resolveToken?: () => Promise<string | null>;
|
|
24
|
+
backendFor?: (token: string) => ChatBackend;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* The `glbgpt_chat` tool: one chat-only turn through the shared core. Never throws — every failure
|
|
28
|
+
* (not signed in, unknown model, network/turn error) becomes an `isError` tool result so the MCP
|
|
29
|
+
* client can surface it to its model.
|
|
30
|
+
*/
|
|
31
|
+
export declare function runChatTool(args: ChatToolArgs, deps?: ChatToolDeps): Promise<ToolResult>;
|
|
32
|
+
/** Build the MCP server exposing the glbgpt tools. */
|
|
33
|
+
export declare function buildMcpServer(deps?: ChatToolDeps): McpServer;
|
|
34
|
+
/**
|
|
35
|
+
* Run the MCP server over stdio. Protocol travels on stdout, so nothing else may write there;
|
|
36
|
+
* diagnostics go to stderr. Runs until stdin closes.
|
|
37
|
+
*/
|
|
38
|
+
export declare function runMcpServer(): Promise<void>;
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
2
|
+
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
|
|
3
|
+
import { z } from 'zod';
|
|
4
|
+
import { HttpChatBackend } from '../core/httpChatBackend.js';
|
|
5
|
+
import { runChatTurn } from '../core/runChat.js';
|
|
6
|
+
import { resolveToken as defaultResolveToken } from '../auth/token.js';
|
|
7
|
+
import { apiBaseUrl } from '../config/env.js';
|
|
8
|
+
import { ensureCatalog } from '../core/catalog.js';
|
|
9
|
+
import { getDefaultChatModel, resolveChatModel } from '../tui/models.js';
|
|
10
|
+
import { resolveImageRef } from '../util/imageRef.js';
|
|
11
|
+
import { VERSION as SERVER_VERSION } from '../version.js';
|
|
12
|
+
function textResult(text, isError = false) {
|
|
13
|
+
return { content: [{ type: 'text', text }], isError: isError || undefined };
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* The `glbgpt_chat` tool: one chat-only turn through the shared core. Never throws — every failure
|
|
17
|
+
* (not signed in, unknown model, network/turn error) becomes an `isError` tool result so the MCP
|
|
18
|
+
* client can surface it to its model.
|
|
19
|
+
*/
|
|
20
|
+
export async function runChatTool(args, deps = {}) {
|
|
21
|
+
const token = await (deps.resolveToken ?? defaultResolveToken)();
|
|
22
|
+
// Server-driven model catalog (memoized; cache applies now, refresh in background).
|
|
23
|
+
await ensureCatalog({ baseUrl: apiBaseUrl(), token });
|
|
24
|
+
if (!token) {
|
|
25
|
+
return textResult('Not signed in. Run `glbgpt login` first (or set GLBGPT_TOKEN).', true);
|
|
26
|
+
}
|
|
27
|
+
let model;
|
|
28
|
+
try {
|
|
29
|
+
model = args.model?.trim() ? resolveChatModel(args.model.trim()) : getDefaultChatModel();
|
|
30
|
+
}
|
|
31
|
+
catch (err) {
|
|
32
|
+
return textResult(errText(err), true);
|
|
33
|
+
}
|
|
34
|
+
const responseFormat = args.response_schema
|
|
35
|
+
? { type: 'json_schema', json_schema: { name: 'output', strict: true, schema: args.response_schema } }
|
|
36
|
+
: undefined;
|
|
37
|
+
// Vision: turn image references (local paths / URLs) into content parts.
|
|
38
|
+
let prompt = args.prompt;
|
|
39
|
+
if (args.images && args.images.length > 0) {
|
|
40
|
+
const parts = [{ type: 'text', text: args.prompt }];
|
|
41
|
+
for (const ref of args.images) {
|
|
42
|
+
try {
|
|
43
|
+
parts.push({ type: 'image_url', image_url: { url: await resolveImageRef(ref) } });
|
|
44
|
+
}
|
|
45
|
+
catch (err) {
|
|
46
|
+
return textResult(errText(err), true);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
prompt = parts;
|
|
50
|
+
}
|
|
51
|
+
const backend = deps.backendFor?.(token) ?? new HttpChatBackend({ baseUrl: apiBaseUrl(), token });
|
|
52
|
+
try {
|
|
53
|
+
const result = await runChatTurn({ backend, model, prompt, system: args.system, responseFormat });
|
|
54
|
+
const text = result.structured != null ? JSON.stringify(result.structured, null, 2) : result.content;
|
|
55
|
+
return textResult(text);
|
|
56
|
+
}
|
|
57
|
+
catch (err) {
|
|
58
|
+
return textResult(errText(err), true);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
/** Build the MCP server exposing the glbgpt tools. */
|
|
62
|
+
export function buildMcpServer(deps = {}) {
|
|
63
|
+
const server = new McpServer({ name: 'glbgpt', version: SERVER_VERSION });
|
|
64
|
+
server.registerTool('glbgpt_chat', {
|
|
65
|
+
title: 'GlobalGPT chat',
|
|
66
|
+
description: "Ask GlobalGPT's cheap, fast chat models a single question and get the answer. Optionally " +
|
|
67
|
+
'set a system prompt, choose a model, attach images for the model to see (local paths or ' +
|
|
68
|
+
'URLs), or pass a JSON Schema (response_schema) to get structured JSON back. Requires a ' +
|
|
69
|
+
'prior `glbgpt login` (or the GLBGPT_TOKEN env var).',
|
|
70
|
+
inputSchema: {
|
|
71
|
+
prompt: z.string().describe('The question or instruction for the model.'),
|
|
72
|
+
system: z.string().optional().describe('Optional system prompt to steer the model.'),
|
|
73
|
+
model: z.string().optional().describe('Chat model id (default gpt-5.6-sol).'),
|
|
74
|
+
images: z
|
|
75
|
+
.array(z.string())
|
|
76
|
+
.optional()
|
|
77
|
+
.describe('Images for the model to see: local file paths, http(s) URLs, or data URLs.'),
|
|
78
|
+
response_schema: z
|
|
79
|
+
.record(z.string(), z.any())
|
|
80
|
+
.optional()
|
|
81
|
+
.describe('Optional JSON Schema; when set, the model returns matching structured JSON.'),
|
|
82
|
+
},
|
|
83
|
+
}, (args) => runChatTool(args, deps));
|
|
84
|
+
return server;
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Run the MCP server over stdio. Protocol travels on stdout, so nothing else may write there;
|
|
88
|
+
* diagnostics go to stderr. Runs until stdin closes.
|
|
89
|
+
*/
|
|
90
|
+
export async function runMcpServer() {
|
|
91
|
+
const server = buildMcpServer();
|
|
92
|
+
const transport = new StdioServerTransport();
|
|
93
|
+
await server.connect(transport);
|
|
94
|
+
process.stderr.write('glbgpt MCP server ready (stdio). Exposing tool: glbgpt_chat.\n');
|
|
95
|
+
}
|
|
96
|
+
function errText(err) {
|
|
97
|
+
return err instanceof Error ? err.message : String(err);
|
|
98
|
+
}
|
|
99
|
+
//# sourceMappingURL=server.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../../../src/mcp/server.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* HTTP client for the yanfa generation endpoints (/ai-api/ai/*).
|
|
3
|
+
*
|
|
4
|
+
* Response envelopes differ:
|
|
5
|
+
* - estimatePrice → a raw object `{ sellable, credits, reasonCode, ... }` (no code wrapper).
|
|
6
|
+
* - submit / task-get → `{ code, message, ...payload }` with `code === 1` on success; `code === 402`
|
|
7
|
+
* signals a payment/quota block (with `data.subCode`).
|
|
8
|
+
*/
|
|
9
|
+
export interface EstimateResult {
|
|
10
|
+
sellable: boolean;
|
|
11
|
+
credits: number;
|
|
12
|
+
reasonCode: string | null;
|
|
13
|
+
platformModelKey?: string | null;
|
|
14
|
+
platformRobotId?: string | null;
|
|
15
|
+
}
|
|
16
|
+
export interface TaskInfo {
|
|
17
|
+
taskId: string;
|
|
18
|
+
status: 'processing' | 'pending_retry' | 'success' | 'failed' | string;
|
|
19
|
+
outputFileUrl?: string | null;
|
|
20
|
+
failedReason?: string | null;
|
|
21
|
+
errorCode?: string | null;
|
|
22
|
+
mediaType?: number | null;
|
|
23
|
+
mediaW?: number | null;
|
|
24
|
+
mediaH?: number | null;
|
|
25
|
+
}
|
|
26
|
+
/** Payment/quota block (HTTP 200 body code 402). subCode: 4002 balance, 4009 PRO, 4010 UNLIMITED, … */
|
|
27
|
+
export declare class PaymentRequiredError extends Error {
|
|
28
|
+
readonly subCode?: number | undefined;
|
|
29
|
+
constructor(message: string, subCode?: number | undefined);
|
|
30
|
+
}
|
|
31
|
+
export interface AiApiClientOptions {
|
|
32
|
+
baseUrl: string;
|
|
33
|
+
token: string;
|
|
34
|
+
fetchImpl?: typeof fetch;
|
|
35
|
+
}
|
|
36
|
+
export declare class AiApiClient {
|
|
37
|
+
private readonly baseUrl;
|
|
38
|
+
private token;
|
|
39
|
+
private readonly fetchImpl;
|
|
40
|
+
private readonly host;
|
|
41
|
+
constructor(opts: AiApiClientOptions);
|
|
42
|
+
/** Hot-swap the JWT (used by the in-chat /login re-auth). */
|
|
43
|
+
setToken(token: string): void;
|
|
44
|
+
/** Read-only price check (no pre-freeze). */
|
|
45
|
+
estimatePrice(model: string, params: Record<string, unknown>): Promise<EstimateResult>;
|
|
46
|
+
/** Submit a generation task; returns the task id. Throws PaymentRequiredError on a 402 body. */
|
|
47
|
+
submit(submitPath: string, body: Record<string, unknown>): Promise<string>;
|
|
48
|
+
/** Poll a task's status. */
|
|
49
|
+
getTask(taskId: string): Promise<TaskInfo>;
|
|
50
|
+
/** Upload a local image file; returns the hosted URL. */
|
|
51
|
+
uploadImage(agentId: string, filePath: string): Promise<string>;
|
|
52
|
+
private postJson;
|
|
53
|
+
}
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import { promises as fs } from 'node:fs';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import { fetchOrDescribe, hostOf } from '../util/retry.js';
|
|
4
|
+
/** Payment/quota block (HTTP 200 body code 402). subCode: 4002 balance, 4009 PRO, 4010 UNLIMITED, … */
|
|
5
|
+
export class PaymentRequiredError extends Error {
|
|
6
|
+
subCode;
|
|
7
|
+
constructor(message, subCode) {
|
|
8
|
+
super(message);
|
|
9
|
+
this.subCode = subCode;
|
|
10
|
+
this.name = 'PaymentRequiredError';
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
export class AiApiClient {
|
|
14
|
+
baseUrl;
|
|
15
|
+
token;
|
|
16
|
+
fetchImpl;
|
|
17
|
+
host;
|
|
18
|
+
constructor(opts) {
|
|
19
|
+
this.baseUrl = opts.baseUrl.replace(/\/+$/, '');
|
|
20
|
+
this.token = opts.token;
|
|
21
|
+
this.fetchImpl = opts.fetchImpl ?? fetch;
|
|
22
|
+
this.host = hostOf(this.baseUrl);
|
|
23
|
+
}
|
|
24
|
+
/** Hot-swap the JWT (used by the in-chat /login re-auth). */
|
|
25
|
+
setToken(token) {
|
|
26
|
+
this.token = token;
|
|
27
|
+
}
|
|
28
|
+
/** Read-only price check (no pre-freeze). */
|
|
29
|
+
async estimatePrice(model, params) {
|
|
30
|
+
const json = await this.postJson('/ai-api/ai/bill/estimatePrice', { productNo: 'glbgpt', model, params });
|
|
31
|
+
return {
|
|
32
|
+
sellable: Boolean(json.sellable),
|
|
33
|
+
credits: Number(json.credits ?? 0),
|
|
34
|
+
reasonCode: json.reasonCode ?? null,
|
|
35
|
+
platformModelKey: json.platformModelKey,
|
|
36
|
+
platformRobotId: json.platformRobotId,
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
/** Submit a generation task; returns the task id. Throws PaymentRequiredError on a 402 body. */
|
|
40
|
+
async submit(submitPath, body) {
|
|
41
|
+
const json = await this.postJson(submitPath, { ...body, device: { deviceType: 'pc', osplatform: 'cli' } });
|
|
42
|
+
if (json.code === 402) {
|
|
43
|
+
throw new PaymentRequiredError(json.message ?? 'Payment required.', json.data?.subCode);
|
|
44
|
+
}
|
|
45
|
+
if (typeof json.taskId !== 'string' || !json.taskId) {
|
|
46
|
+
throw new Error(json.message ?? 'Submit failed: no task id returned.');
|
|
47
|
+
}
|
|
48
|
+
return json.taskId;
|
|
49
|
+
}
|
|
50
|
+
/** Poll a task's status. */
|
|
51
|
+
async getTask(taskId) {
|
|
52
|
+
const json = await this.postJson('/ai-api/ai/task/get', { taskId });
|
|
53
|
+
const t = json.task;
|
|
54
|
+
if (!t) {
|
|
55
|
+
throw new Error(json.message ?? 'Task not found.');
|
|
56
|
+
}
|
|
57
|
+
return {
|
|
58
|
+
taskId,
|
|
59
|
+
status: t.status,
|
|
60
|
+
outputFileUrl: t.outputFileUrl,
|
|
61
|
+
failedReason: t.failedReasonShort ?? t.failedReasonRaw ?? t.failedReason,
|
|
62
|
+
errorCode: t.errorCode,
|
|
63
|
+
mediaType: t.mediaType,
|
|
64
|
+
mediaW: t.mediaW,
|
|
65
|
+
mediaH: t.mediaH,
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
/** Upload a local image file; returns the hosted URL. */
|
|
69
|
+
async uploadImage(agentId, filePath) {
|
|
70
|
+
const buf = await fs.readFile(filePath);
|
|
71
|
+
const form = new FormData();
|
|
72
|
+
form.append('agentId', agentId);
|
|
73
|
+
form.append('files', new Blob([buf]), path.basename(filePath));
|
|
74
|
+
const res = await fetchOrDescribe(this.fetchImpl, `${this.baseUrl}/ai-api/ai/storage/upload`, { method: 'POST', headers: { Authorization: `Bearer ${this.token}` }, body: form }, this.host);
|
|
75
|
+
const json = await res.json();
|
|
76
|
+
const url = json?.files?.[0]?.url;
|
|
77
|
+
if (typeof url !== 'string' || !url) {
|
|
78
|
+
throw new Error(json?.message ?? `Upload failed for ${filePath}.`);
|
|
79
|
+
}
|
|
80
|
+
return url;
|
|
81
|
+
}
|
|
82
|
+
async postJson(pathname, body) {
|
|
83
|
+
const res = await fetchOrDescribe(this.fetchImpl, `${this.baseUrl}${pathname}`, {
|
|
84
|
+
method: 'POST',
|
|
85
|
+
headers: { 'Content-Type': 'application/json', Authorization: `Bearer ${this.token}` },
|
|
86
|
+
body: JSON.stringify(body),
|
|
87
|
+
}, this.host);
|
|
88
|
+
const text = await res.text();
|
|
89
|
+
try {
|
|
90
|
+
return JSON.parse(text);
|
|
91
|
+
}
|
|
92
|
+
catch {
|
|
93
|
+
throw new Error(`Unexpected response from ${pathname}: ${text.slice(0, 200) || `HTTP ${res.status}`}`);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
//# sourceMappingURL=aiApiClient.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"aiApiClient.js","sourceRoot":"","sources":["../../../src/media/aiApiClient.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { PaymentRequiredError } from './aiApiClient.js';
|
|
2
|
+
/** A 402 payment/quota block raised at submit time. */
|
|
3
|
+
export declare function describePaymentRequired(err: PaymentRequiredError): string;
|
|
4
|
+
/** An estimate that came back not sellable, keyed by reasonCode. */
|
|
5
|
+
export declare function describeNotSellable(reasonCode: string | null | undefined): string;
|
|
6
|
+
/** A failed generation task, classifying the structured errorCode and preserving the raw reason. */
|
|
7
|
+
export declare function describeTaskFailure(errorCode?: string | null, failedReason?: string | null): string;
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Human-readable, actionable messages for media generation failures.
|
|
3
|
+
*
|
|
4
|
+
* Mappings have a basis in the backend contract (verified 2026-07-15):
|
|
5
|
+
* - 402 subCodes are set in GlbgptLifeCycleService.fillInsufficientSubCode.
|
|
6
|
+
* - estimate reasonCodes come from the bill service (insufficient_funds / invalid_user_or_model).
|
|
7
|
+
* - task errorCodes are freeform-prefixed (ANYWHERE_CONTENT_REJECTED, ANYWHERE_INSUFFICIENT_CREDITS,
|
|
8
|
+
* ANYWHERE_INPUT_DOWNLOAD_FAILED, ANYWHERE_PROVIDER_ERROR, ...), so they are classified by keyword
|
|
9
|
+
* rather than exact match, and the raw reason is preserved when it adds detail.
|
|
10
|
+
*/
|
|
11
|
+
const TOP_UP = 'Top up at glbgpt.com to continue.';
|
|
12
|
+
/** A 402 payment/quota block raised at submit time. */
|
|
13
|
+
export function describePaymentRequired(err) {
|
|
14
|
+
switch (err.subCode) {
|
|
15
|
+
case 4002:
|
|
16
|
+
return `Insufficient credit balance. ${TOP_UP}`;
|
|
17
|
+
case 4003:
|
|
18
|
+
return `Your plan's quota is used up for the current period; a new plan starts soon.${detail(err.message)}`;
|
|
19
|
+
case 4004:
|
|
20
|
+
return `Your plan isn't active for this period yet.${detail(err.message)}`;
|
|
21
|
+
case 4009:
|
|
22
|
+
return 'This model requires a PRO plan. Upgrade at glbgpt.com.';
|
|
23
|
+
case 4010:
|
|
24
|
+
return 'This model requires an Unlimited plan. Upgrade at glbgpt.com.';
|
|
25
|
+
default:
|
|
26
|
+
return err.message?.trim() || 'Payment or plan requirement not met.';
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
/** An estimate that came back not sellable, keyed by reasonCode. */
|
|
30
|
+
export function describeNotSellable(reasonCode) {
|
|
31
|
+
switch (reasonCode) {
|
|
32
|
+
case 'insufficient_funds':
|
|
33
|
+
return `Insufficient credit balance. ${TOP_UP}`;
|
|
34
|
+
case 'invalid_user_or_model':
|
|
35
|
+
return "This model isn't available for your account.";
|
|
36
|
+
default:
|
|
37
|
+
return `Not available for this account or these parameters${reasonCode ? ` (${reasonCode})` : ''}.`;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
/** A failed generation task, classifying the structured errorCode and preserving the raw reason. */
|
|
41
|
+
export function describeTaskFailure(errorCode, failedReason) {
|
|
42
|
+
const code = (errorCode ?? '').toUpperCase();
|
|
43
|
+
const raw = failedReason?.trim() || '';
|
|
44
|
+
if (/CONTENT|REJECT|MODERAT|SAFETY|POLICY|NSFW/.test(code)) {
|
|
45
|
+
return `Rejected by content safety — try rephrasing the prompt or using a different reference image.${detail(raw)}`;
|
|
46
|
+
}
|
|
47
|
+
if (/INSUFFICIENT|CREDIT|BALANCE|FUNDS/.test(code)) {
|
|
48
|
+
return `Insufficient credit balance. ${TOP_UP}`;
|
|
49
|
+
}
|
|
50
|
+
if (/DOWNLOAD|INPUT/.test(code)) {
|
|
51
|
+
return `A reference image or URL couldn't be downloaded — make sure it is publicly accessible.${detail(raw)}`;
|
|
52
|
+
}
|
|
53
|
+
if (/PROVIDER|UPSTREAM/.test(code)) {
|
|
54
|
+
return `The model provider returned an error — please try again in a moment.${detail(raw)}`;
|
|
55
|
+
}
|
|
56
|
+
if (/NETWORK|TIMEOUT/.test(code)) {
|
|
57
|
+
return `The generation timed out or hit a network error — please try again.${detail(raw)}`;
|
|
58
|
+
}
|
|
59
|
+
// No recognized code: fall back to the backend's own reason (never fabricate).
|
|
60
|
+
return raw || 'Generation failed.';
|
|
61
|
+
}
|
|
62
|
+
/** Append a truncated raw detail in parentheses when it adds information. */
|
|
63
|
+
function detail(raw) {
|
|
64
|
+
const text = raw?.trim();
|
|
65
|
+
if (!text)
|
|
66
|
+
return '';
|
|
67
|
+
const clipped = text.length > 160 ? `${text.slice(0, 159)}…` : text;
|
|
68
|
+
return ` (${clipped})`;
|
|
69
|
+
}
|
|
70
|
+
//# sourceMappingURL=errors.js.map
|