@glbgpt/cli 0.1.0-test.5 → 0.1.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.
- package/README.md +79 -6
- package/dist/src/auth/authClient.d.ts +21 -2
- package/dist/src/auth/authClient.js +62 -2
- package/dist/src/auth/authClient.js.map +1 -1
- package/dist/src/auth/loginFlow.js +5 -2
- package/dist/src/auth/loginFlow.js.map +1 -1
- package/dist/src/auth/loopbackServer.d.ts +2 -1
- package/dist/src/auth/loopbackServer.js +6 -3
- package/dist/src/auth/loopbackServer.js.map +1 -1
- package/dist/src/commands/accountCommand.js +10 -4
- package/dist/src/commands/accountCommand.js.map +1 -1
- package/dist/src/commands/configCommand.d.ts +5 -0
- package/dist/src/commands/configCommand.js +15 -2
- package/dist/src/commands/configCommand.js.map +1 -1
- package/dist/src/commands/execCommand.d.ts +6 -0
- package/dist/src/commands/execCommand.js +61 -9
- package/dist/src/commands/execCommand.js.map +1 -1
- package/dist/src/commands/loginCommand.js +9 -6
- package/dist/src/commands/loginCommand.js.map +1 -1
- package/dist/src/commands/mediaCommand.js +3 -2
- package/dist/src/commands/mediaCommand.js.map +1 -1
- package/dist/src/commands/skillCommand.d.ts +30 -0
- package/dist/src/commands/skillCommand.js +160 -0
- package/dist/src/commands/skillCommand.js.map +1 -0
- package/dist/src/config/configFile.d.ts +12 -0
- package/dist/src/config/configFile.js +12 -0
- package/dist/src/config/configFile.js.map +1 -1
- package/dist/src/config/env.d.ts +18 -0
- package/dist/src/config/env.js +57 -7
- package/dist/src/config/env.js.map +1 -1
- package/dist/src/core/catalog.d.ts +8 -1
- package/dist/src/core/catalog.js +13 -2
- package/dist/src/core/catalog.js.map +1 -1
- package/dist/src/core/contextPrune.d.ts +13 -0
- package/dist/src/core/contextPrune.js +61 -0
- package/dist/src/core/contextPrune.js.map +1 -0
- package/dist/src/core/httpChatBackend.js +22 -5
- package/dist/src/core/httpChatBackend.js.map +1 -1
- package/dist/src/core/runChat.d.ts +9 -5
- package/dist/src/core/runChat.js +10 -7
- package/dist/src/core/runChat.js.map +1 -1
- package/dist/src/core/session.d.ts +11 -0
- package/dist/src/core/session.js +20 -1
- package/dist/src/core/session.js.map +1 -1
- package/dist/src/core/toolRegistry.d.ts +14 -3
- package/dist/src/core/toolRegistry.js +24 -15
- package/dist/src/core/toolRegistry.js.map +1 -1
- package/dist/src/core/turnLoop.d.ts +4 -0
- package/dist/src/core/turnLoop.js +54 -13
- package/dist/src/core/turnLoop.js.map +1 -1
- package/dist/src/core/types.d.ts +6 -0
- package/dist/src/core/updateCheck.d.ts +46 -0
- package/dist/src/core/updateCheck.js +139 -0
- package/dist/src/core/updateCheck.js.map +1 -0
- package/dist/src/exec/media.d.ts +32 -0
- package/dist/src/exec/media.js +70 -0
- package/dist/src/exec/media.js.map +1 -0
- package/dist/src/exec/output.d.ts +16 -0
- package/dist/src/exec/output.js +41 -0
- package/dist/src/exec/output.js.map +1 -1
- package/dist/src/fs/globTool.d.ts +8 -0
- package/dist/src/fs/globTool.js +117 -0
- package/dist/src/fs/globTool.js.map +1 -0
- package/dist/src/fs/grepTool.d.ts +4 -0
- package/dist/src/fs/grepTool.js +146 -0
- package/dist/src/fs/grepTool.js.map +1 -0
- package/dist/src/fs/index.d.ts +8 -0
- package/dist/src/fs/index.js +13 -0
- package/dist/src/fs/index.js.map +1 -0
- package/dist/src/fs/limits.d.ts +34 -0
- package/dist/src/fs/limits.js +74 -0
- package/dist/src/fs/limits.js.map +1 -0
- package/dist/src/fs/listDirTool.d.ts +2 -0
- package/dist/src/fs/listDirTool.js +68 -0
- package/dist/src/fs/listDirTool.js.map +1 -0
- package/dist/src/fs/readFileTool.d.ts +2 -0
- package/dist/src/fs/readFileTool.js +102 -0
- package/dist/src/fs/readFileTool.js.map +1 -0
- package/dist/src/fs/walk.d.ts +11 -0
- package/dist/src/fs/walk.js +38 -0
- package/dist/src/fs/walk.js.map +1 -0
- package/dist/src/fs/workspaceGuard.d.ts +27 -0
- package/dist/src/fs/workspaceGuard.js +96 -0
- package/dist/src/fs/workspaceGuard.js.map +1 -0
- package/dist/src/index.js +47 -3
- package/dist/src/index.js.map +1 -1
- package/dist/src/mcp/mediaTools.d.ts +63 -0
- package/dist/src/mcp/mediaTools.js +385 -0
- package/dist/src/mcp/mediaTools.js.map +1 -0
- package/dist/src/mcp/server.d.ts +6 -2
- package/dist/src/mcp/server.js +19 -9
- package/dist/src/mcp/server.js.map +1 -1
- package/dist/src/media/aiApiClient.d.ts +5 -0
- package/dist/src/media/aiApiClient.js +12 -1
- package/dist/src/media/aiApiClient.js.map +1 -1
- package/dist/src/media/budget.d.ts +42 -0
- package/dist/src/media/budget.js +95 -0
- package/dist/src/media/budget.js.map +1 -0
- package/dist/src/media/executor.d.ts +9 -0
- package/dist/src/media/executor.js +1 -1
- package/dist/src/media/executor.js.map +1 -1
- package/dist/src/media/generateImageTool.d.ts +8 -2
- package/dist/src/media/generateImageTool.js +51 -3
- package/dist/src/media/generateImageTool.js.map +1 -1
- package/dist/src/media/promptSanitizer.d.ts +11 -0
- package/dist/src/media/promptSanitizer.js +33 -0
- package/dist/src/media/promptSanitizer.js.map +1 -0
- package/dist/src/media/taskManager.d.ts +8 -1
- package/dist/src/media/taskManager.js +1 -1
- package/dist/src/media/taskManager.js.map +1 -1
- package/dist/src/tui/App.js +30 -21
- package/dist/src/tui/App.js.map +1 -1
- package/dist/src/tui/ParamEditor.d.ts +11 -2
- package/dist/src/tui/ParamEditor.js +17 -6
- package/dist/src/tui/ParamEditor.js.map +1 -1
- package/dist/src/tui/atPopup.d.ts +8 -0
- package/dist/src/tui/atPopup.js +1 -1
- package/dist/src/tui/atPopup.js.map +1 -1
- package/dist/src/tui/chatController.d.ts +58 -2
- package/dist/src/tui/chatController.js +231 -40
- package/dist/src/tui/chatController.js.map +1 -1
- package/dist/src/tui/models.d.ts +6 -0
- package/dist/src/tui/models.js +14 -6
- package/dist/src/tui/models.js.map +1 -1
- package/dist/src/tui/run.js +50 -16
- package/dist/src/tui/run.js.map +1 -1
- package/dist/src/util/brokenPipe.d.ts +10 -0
- package/dist/src/util/brokenPipe.js +19 -0
- package/dist/src/util/brokenPipe.js.map +1 -0
- package/package.json +3 -2
- package/skills/globalgpt/SKILL.md +94 -0
- package/skills/globalgpt/references/troubleshooting.md +34 -0
- package/skills/globalgpt-coding/SKILL.md +65 -0
- package/skills/globalgpt-coding/references/troubleshooting.md +34 -0
- package/skills/globalgpt-image/SKILL.md +109 -0
- package/skills/globalgpt-image/references/recipes.md +52 -0
- package/skills/globalgpt-image/references/troubleshooting.md +49 -0
- package/skills/globalgpt-video/SKILL.md +109 -0
- package/skills/globalgpt-video/references/recipes.md +50 -0
- package/skills/globalgpt-video/references/troubleshooting.md +49 -0
package/README.md
CHANGED
|
@@ -4,12 +4,12 @@ GlobalGPT in your terminal — chat, image and video generation, and an `exec` e
|
|
|
4
4
|
scripts and other agents. You sign in with your GlobalGPT account (no API key); billing is your
|
|
5
5
|
normal account balance.
|
|
6
6
|
|
|
7
|
-
>
|
|
7
|
+
> Requires Node.js ≥ 18.
|
|
8
8
|
|
|
9
9
|
## Install
|
|
10
10
|
|
|
11
11
|
```bash
|
|
12
|
-
npm install -g @glbgpt/cli
|
|
12
|
+
npm install -g @glbgpt/cli
|
|
13
13
|
```
|
|
14
14
|
|
|
15
15
|
Installs two interchangeable commands: **`glbgpt`** and **`globalgpt`**.
|
|
@@ -35,6 +35,8 @@ Inside the TUI, type `/` for commands: `/model` `/models` `/image` `/video` `/ta
|
|
|
35
35
|
`/account` `/transactions` `/cost` `/login` `/logout` `/new` `/resume` `/help` `/exit`.
|
|
36
36
|
Attach images with `@image` (last generation), `Ctrl+V` or `@clipboard`, or `@./photo.png`.
|
|
37
37
|
Multi-line: end a line with `\` then Enter (or Ctrl+J); plain Enter sends; Esc interrupts.
|
|
38
|
+
On tool-capable models the assistant can also read files under the directory you started
|
|
39
|
+
`glbgpt` in (read-only — list, read, glob, grep) to answer questions about them.
|
|
38
40
|
|
|
39
41
|
### Account
|
|
40
42
|
|
|
@@ -82,18 +84,86 @@ glbgpt exec "say hi" --jsonl # streaming events, one JSON per
|
|
|
82
84
|
```
|
|
83
85
|
|
|
84
86
|
Flags: `-m/--model`, `--system <text>`, `--file <path...>`, `-i/--image <path|url...>`,
|
|
85
|
-
`--output-schema <file>` (structured output), `--json`, `--jsonl`, `-o/--output-last-message <file
|
|
87
|
+
`--output-schema <file>` (structured output), `--json`, `--jsonl`, `-o/--output-last-message <file>`,
|
|
88
|
+
`--max-credits <n>` (media budget for this run, default 4000; `0` disables media).
|
|
86
89
|
Exit code is `0` on success, non-zero on a usage/auth/turn error.
|
|
87
90
|
|
|
91
|
+
On tool-capable models the assistant can also read files under the current directory (read-only)
|
|
92
|
+
and generate images/videos: exec waits for in-flight generations before exiting and reports each
|
|
93
|
+
as a `media_result` event (`--jsonl`) or a stderr line.
|
|
94
|
+
|
|
88
95
|
### mcp — use from other agents
|
|
89
96
|
|
|
90
97
|
`glbgpt mcp` runs a [Model Context Protocol](https://modelcontextprotocol.io) server over stdio,
|
|
91
|
-
|
|
98
|
+
so agents like Claude Code, Codex, or Cursor can chat and generate media through your GlobalGPT
|
|
99
|
+
account. Sign in once with `glbgpt login` first.
|
|
100
|
+
|
|
101
|
+
| Tool | What it does |
|
|
102
|
+
|---|---|
|
|
103
|
+
| `glbgpt_chat` | One chat turn: question in, answer out (system prompt, vision, JSON schema supported). |
|
|
104
|
+
| `glbgpt_generate_image` | Generate an image; usually returns the finished result (URL + local file) in one call. |
|
|
105
|
+
| `glbgpt_generate_video` | Generate a video; returns a `task_id` to check. |
|
|
106
|
+
| `glbgpt_check_task` | Check a generation task. Waits server-side — the agent can just call it again immediately until done. |
|
|
107
|
+
| `glbgpt_list_models` | List available chat/image/video models and what parameters each supports. |
|
|
108
|
+
|
|
109
|
+
Register it:
|
|
92
110
|
|
|
93
111
|
```bash
|
|
112
|
+
# Claude Code
|
|
94
113
|
claude mcp add glbgpt -- glbgpt mcp
|
|
114
|
+
|
|
115
|
+
# Codex — add to ~/.codex/config.toml
|
|
116
|
+
[mcp_servers.glbgpt]
|
|
117
|
+
command = "glbgpt"
|
|
118
|
+
args = ["mcp"]
|
|
95
119
|
```
|
|
96
120
|
|
|
121
|
+
Cursor and other JSON-config clients:
|
|
122
|
+
|
|
123
|
+
```json
|
|
124
|
+
{ "mcpServers": { "glbgpt": { "command": "glbgpt", "args": ["mcp"] } } }
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
**Spending control.** Media generation spends real credits, so unattended use is capped by a
|
|
128
|
+
session budget: **4000 credits per server session by default**. Adjust with
|
|
129
|
+
`glbgpt mcp --max-credits <n>` in the client config (`"args": ["mcp", "--max-credits", "8000"]`),
|
|
130
|
+
persistently via `glbgpt config set max-credits <n>`, or `--max-credits 0` to disable media
|
|
131
|
+
generation entirely. When the cap would be exceeded the tool refuses and tells the agent how to
|
|
132
|
+
ask you to raise it — nothing is charged.
|
|
133
|
+
|
|
134
|
+
Generated files are saved under `glbgpt-output/` in the directory the server was started in
|
|
135
|
+
(usually your project directory), alongside the hosted URL.
|
|
136
|
+
|
|
137
|
+
### skill — teach agents to drive the CLI
|
|
138
|
+
|
|
139
|
+
`glbgpt skill install` drops four bundled [Agent Skills](https://agentskills.io) into the
|
|
140
|
+
directories coding agents read: **globalgpt** (the all-in-one entry — `/globalgpt` for a
|
|
141
|
+
menu of everything plus balance, spend, and task queries), **globalgpt-image** and
|
|
142
|
+
**globalgpt-video** (say "make me an image/video" — or invoke `/globalgpt-image` bare to
|
|
143
|
+
pick a model from a live menu first) and **globalgpt-coding** (`/globalgpt-coding`:
|
|
144
|
+
delegate a code subtask to a GlobalGPT chat model you choose; the delegate reads code
|
|
145
|
+
via the CLI, so delegated content is sent to GlobalGPT).
|
|
146
|
+
|
|
147
|
+
```bash
|
|
148
|
+
glbgpt skill install # symlinks into ~/.claude/skills and ~/.agents/skills
|
|
149
|
+
glbgpt skill install --copy # copy instead of symlink
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
Symlinks are the default, so updating the CLI updates the skill content automatically.
|
|
153
|
+
To update: `npm i -g @glbgpt/cli && glbgpt skill install` — the reinstall is
|
|
154
|
+
idempotent and picks up newly added skills (and cleans up retired ones). Restart your
|
|
155
|
+
agent afterwards. Re-running `--copy` overwrites whatever is in the installed directory
|
|
156
|
+
— any edits you made to a copied skill are lost — while the symlink default just
|
|
157
|
+
re-points the link and leaves nothing to lose.
|
|
158
|
+
|
|
159
|
+
**Which surface should you use?**
|
|
160
|
+
|
|
161
|
+
| | Use it when |
|
|
162
|
+
|---|---|
|
|
163
|
+
| **Skill** | Your agent runs shell commands (Claude Code, Cursor, Codex). Zero config — install once and ask for an image. |
|
|
164
|
+
| **MCP** | Your agent speaks MCP but cannot run shell commands, or you want the session credit budget enforced (`--max-credits`). |
|
|
165
|
+
| **CLI / exec** | You are scripting it yourself, in CI, or piping output between tools. |
|
|
166
|
+
|
|
97
167
|
### config
|
|
98
168
|
|
|
99
169
|
| Command | What it does |
|
|
@@ -101,8 +171,11 @@ claude mcp add glbgpt -- glbgpt mcp
|
|
|
101
171
|
| `glbgpt config list` | Show persisted settings. |
|
|
102
172
|
| `glbgpt config get <key>` · `set <key> <value>` · `unset <key>` | Manage settings. |
|
|
103
173
|
|
|
104
|
-
Keys: `
|
|
105
|
-
|
|
174
|
+
Keys: `lang`, `max-credits` (unattended media budget), `context-pruning` (set `false` to
|
|
175
|
+
keep old tool results in long chats), `update-check` (set `false` to disable the startup
|
|
176
|
+
notice about newer versions). One-shot overrides via env vars (`GLBGPT_LANG`,
|
|
177
|
+
`GLBGPT_TOKEN`, `GLBGPT_MAX_CREDITS`, `GLBGPT_CONTEXT_PRUNING`, `GLBGPT_UPDATE_CHECK`)
|
|
178
|
+
always win.
|
|
106
179
|
|
|
107
180
|
## Notes
|
|
108
181
|
|
|
@@ -1,9 +1,28 @@
|
|
|
1
1
|
export interface UserInfo {
|
|
2
2
|
email?: string;
|
|
3
3
|
name?: string;
|
|
4
|
-
balance
|
|
4
|
+
/** Top-up (recharge) credits alone — the backend's `balance` field (the `user` table). */
|
|
5
|
+
topUpCredits?: number;
|
|
6
|
+
/**
|
|
7
|
+
* Total usable credits — the backend's `amount` field: top-up + subscription balance
|
|
8
|
+
* (incl. gifted) minus subscription holds. This is the site header's number and the
|
|
9
|
+
* honest answer to "how much can I spend"; subscription-only users have topUp 0 but a
|
|
10
|
+
* real total. Falls back to topUpCredits on an older backend without `amount`.
|
|
11
|
+
*/
|
|
12
|
+
totalCredits?: number;
|
|
13
|
+
/** Human plan name from currentSubscription.plan_package (e.g. "Pro", "Unlimited (lifetime)"). */
|
|
5
14
|
plan?: string;
|
|
15
|
+
/** The whole subscription's validity end (yyyy-MM-dd), when there is one. */
|
|
16
|
+
planEndDate?: string;
|
|
17
|
+
/** End of the CURRENT credit period (yyyy-MM-dd) — subscription credits reset then. */
|
|
18
|
+
creditPeriodEnd?: string;
|
|
6
19
|
}
|
|
20
|
+
/**
|
|
21
|
+
* One human line for the usable balance: the total first, with the top-up/subscription
|
|
22
|
+
* split in parentheses when a subscription share exists. (` + ` on purpose, not ` · ` —
|
|
23
|
+
* the TUI status line splits label pairs on ` · `.)
|
|
24
|
+
*/
|
|
25
|
+
export declare function describeCredits(info: UserInfo): string | null;
|
|
7
26
|
export interface BillRecord {
|
|
8
27
|
model: string;
|
|
9
28
|
/** Cost in USD (1 credit ≈ $0.001). */
|
|
@@ -12,7 +31,7 @@ export interface BillRecord {
|
|
|
12
31
|
createdAt?: string;
|
|
13
32
|
}
|
|
14
33
|
export interface AuthClientOptions {
|
|
15
|
-
/** GlobalGPT API base, e.g. https://
|
|
34
|
+
/** GlobalGPT API base, e.g. https://api2.glbgpt.com. */
|
|
16
35
|
baseUrl: string;
|
|
17
36
|
fetchImpl?: typeof fetch;
|
|
18
37
|
}
|
|
@@ -6,6 +6,59 @@
|
|
|
6
6
|
* expected payload, not solely the code.
|
|
7
7
|
*/
|
|
8
8
|
import { fetchOrDescribe, hostOf } from '../util/retry.js';
|
|
9
|
+
/**
|
|
10
|
+
* The plan display name, from `currentSubscription.plan_package` — the field the site
|
|
11
|
+
* renders. NOT `subscription_tag`, which is a 0/1 "has ever subscribed" flag.
|
|
12
|
+
* "pro" → "Pro"; "lifetime_unlimited" → "Unlimited (lifetime)".
|
|
13
|
+
*/
|
|
14
|
+
function planName(data) {
|
|
15
|
+
const pkg = data.currentSubscription?.plan_package;
|
|
16
|
+
if (typeof pkg !== 'string' || !pkg)
|
|
17
|
+
return undefined;
|
|
18
|
+
const lifetime = pkg.startsWith('lifetime_');
|
|
19
|
+
const base = lifetime ? pkg.slice('lifetime_'.length) : pkg;
|
|
20
|
+
const capitalized = base.charAt(0).toUpperCase() + base.slice(1);
|
|
21
|
+
return lifetime ? `${capitalized} (lifetime)` : capitalized;
|
|
22
|
+
}
|
|
23
|
+
const CREDIT_FORMAT = { maximumFractionDigits: 2 };
|
|
24
|
+
function credits(v) {
|
|
25
|
+
if (v === null || v === undefined || (typeof v === 'string' && v.trim() === ''))
|
|
26
|
+
return undefined;
|
|
27
|
+
const n = Number(v);
|
|
28
|
+
return Number.isFinite(n) ? n : undefined;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* One human line for the usable balance: the total first, with the top-up/subscription
|
|
32
|
+
* split in parentheses when a subscription share exists. (` + ` on purpose, not ` · ` —
|
|
33
|
+
* the TUI status line splits label pairs on ` · `.)
|
|
34
|
+
*/
|
|
35
|
+
export function describeCredits(info) {
|
|
36
|
+
if (info.totalCredits === undefined)
|
|
37
|
+
return null;
|
|
38
|
+
const fmt = (n) => n.toLocaleString('en-US', CREDIT_FORMAT);
|
|
39
|
+
const subscription = Math.max(0, info.totalCredits - (info.topUpCredits ?? 0));
|
|
40
|
+
// Subscribers always get the breakdown — an exhausted plan ("subscription 0") plus its
|
|
41
|
+
// reset date answers exactly what a 0 balance raises: when do credits come back?
|
|
42
|
+
// Without a plan there is nothing to break down: show the total alone. And when the
|
|
43
|
+
// parts cannot sum to the total (backend holds can make amount < balance), a breakdown
|
|
44
|
+
// would contradict itself — show the honest total alone instead.
|
|
45
|
+
const showBreakdown = info.topUpCredits !== undefined &&
|
|
46
|
+
info.totalCredits >= info.topUpCredits &&
|
|
47
|
+
(subscription > 0 || Boolean(info.plan));
|
|
48
|
+
if (!showBreakdown)
|
|
49
|
+
return `${fmt(info.totalCredits)} credits`;
|
|
50
|
+
// The subscription share is the CURRENT month's allocation. When another credit period
|
|
51
|
+
// follows (period end < subscription end), say when it resets — otherwise a yearly
|
|
52
|
+
// subscriber reads this month's remainder as their whole year. No "resets" on the last
|
|
53
|
+
// period: nothing follows it.
|
|
54
|
+
// Compare date-only prefixes: a datetime on one side must not defeat the
|
|
55
|
+
// last-period equality check (which suppresses a bogus "resets" claim).
|
|
56
|
+
const day = (d) => d.slice(0, 10);
|
|
57
|
+
const resets = info.creditPeriodEnd && info.planEndDate && day(info.creditPeriodEnd) < day(info.planEndDate)
|
|
58
|
+
? `, resets ${day(info.creditPeriodEnd)}`
|
|
59
|
+
: '';
|
|
60
|
+
return `${fmt(info.totalCredits)} credits (top-up ${fmt(info.topUpCredits ?? 0)} + subscription ${fmt(subscription)}${resets})`;
|
|
61
|
+
}
|
|
9
62
|
export class AuthClient {
|
|
10
63
|
baseUrl;
|
|
11
64
|
fetchImpl;
|
|
@@ -62,11 +115,18 @@ export class AuthClient {
|
|
|
62
115
|
if (!data || typeof data !== 'object') {
|
|
63
116
|
throw new Error(errorMessage(body) ?? 'Failed to fetch account info.');
|
|
64
117
|
}
|
|
118
|
+
const topUp = credits(data.balance);
|
|
65
119
|
return {
|
|
66
120
|
email: data.email,
|
|
67
121
|
name: data.name,
|
|
68
|
-
|
|
69
|
-
|
|
122
|
+
topUpCredits: topUp,
|
|
123
|
+
totalCredits: credits(data.amount) ?? topUp,
|
|
124
|
+
plan: planName(data),
|
|
125
|
+
// subscription.end_date = the LAST valid plan row's end — the whole subscription's
|
|
126
|
+
// validity. (currentSubscription.end_date is only the CURRENT credit period: yearly
|
|
127
|
+
// plans allocate 12 monthly rows, so that date can be "today" right after an upgrade.)
|
|
128
|
+
planEndDate: typeof data.subscription?.end_date === 'string' ? data.subscription.end_date : undefined,
|
|
129
|
+
creditPeriodEnd: typeof data.currentSubscription?.end_date === 'string' ? data.currentSubscription.end_date : undefined,
|
|
70
130
|
};
|
|
71
131
|
}
|
|
72
132
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"authClient.js","sourceRoot":"","sources":["../../../src/auth/authClient.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,EAAE,eAAe,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"authClient.js","sourceRoot":"","sources":["../../../src/auth/authClient.ts"],"names":[],"mappings":"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"}
|
|
@@ -34,9 +34,12 @@ export function parsePastedCode(pasted, expectedState) {
|
|
|
34
34
|
export async function browserLogin(deps) {
|
|
35
35
|
const state = (deps.genState ?? defaultState)();
|
|
36
36
|
const server = new LoopbackServer(state, deps.timeoutMs);
|
|
37
|
-
const {
|
|
37
|
+
const { port } = await server.listen();
|
|
38
38
|
const base = `${trimSlash(deps.webBaseUrl)}/${deps.lang}/cli-auth`;
|
|
39
|
-
|
|
39
|
+
// Send only the PORT — the auth page constructs http://127.0.0.1:{port}/callback itself.
|
|
40
|
+
// A full loopback URL in the query trips production WAF SSRF rules (403), and port-only
|
|
41
|
+
// means the page structurally cannot redirect anywhere but this machine.
|
|
42
|
+
const loopbackUrl = `${base}?port=${port}&state=${encodeURIComponent(state)}`;
|
|
40
43
|
// The code page echoes this state back appended to the one-time code so the paste path can
|
|
41
44
|
// bind it to this login attempt (see parsePastedCode).
|
|
42
45
|
const codeUrl = `${base}?mode=code&state=${encodeURIComponent(state)}`;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"loginFlow.js","sourceRoot":"","sources":["../../../src/auth/loginFlow.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,aAAa,CAAC;AACjC,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAkCrD,kEAAkE;AAClE,MAAM,OAAO,eAAgB,SAAQ,KAAK;CAAG;AAE7C;;;;;;GAMG;AACH,MAAM,UAAU,eAAe,CAAC,MAAc,EAAE,aAAqB;IACnE,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,EAAE,CAAC;IAC9B,MAAM,IAAI,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IAClC,IAAI,IAAI,GAAG,CAAC,EAAE,CAAC;QACb,MAAM,IAAI,eAAe,CAAC,sEAAsE,CAAC,CAAC;IACpG,CAAC;IACD,MAAM,IAAI,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC;IACpC,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC;IACtC,MAAM,CAAC,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAC7B,MAAM,CAAC,GAAG,MAAM,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;IACrC,MAAM,EAAE,GAAG,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC,MAAM,IAAI,MAAM,CAAC,eAAe,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IACjE,IAAI,CAAC,IAAI,IAAI,CAAC,EAAE,EAAE,CAAC;QACjB,MAAM,IAAI,eAAe,CAAC,uFAAuF,CAAC,CAAC;IACrH,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AASD;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,IAAsB;IACvD,MAAM,KAAK,GAAG,CAAC,IAAI,CAAC,QAAQ,IAAI,YAAY,CAAC,EAAE,CAAC;IAChD,MAAM,MAAM,GAAG,IAAI,cAAc,CAAC,KAAK,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC;IACzD,MAAM,EAAE,
|
|
1
|
+
{"version":3,"file":"loginFlow.js","sourceRoot":"","sources":["../../../src/auth/loginFlow.ts"],"names":[],"mappings":"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"}
|
|
@@ -25,9 +25,10 @@ export declare class LoopbackServer {
|
|
|
25
25
|
private resolveResult;
|
|
26
26
|
private rejectResult;
|
|
27
27
|
constructor(expectedState: string, timeoutMs?: number);
|
|
28
|
-
/** Bind the server and return the
|
|
28
|
+
/** Bind the server and return the callback the browser comes back to (and its bare port). */
|
|
29
29
|
listen(): Promise<{
|
|
30
30
|
redirectUri: string;
|
|
31
|
+
port: number;
|
|
31
32
|
}>;
|
|
32
33
|
/** Resolve with the one-time code once the browser hits the callback with a matching state. */
|
|
33
34
|
waitForCode(): Promise<string>;
|
|
@@ -26,7 +26,10 @@ export class LoopbackServer {
|
|
|
26
26
|
result;
|
|
27
27
|
resolveResult;
|
|
28
28
|
rejectResult;
|
|
29
|
-
constructor(expectedState,
|
|
29
|
+
constructor(expectedState,
|
|
30
|
+
// 10 min: the auth page signs a logged-out visitor in first (possibly a fresh
|
|
31
|
+
// registration with an email code), which can take several minutes before Authorize.
|
|
32
|
+
timeoutMs = 600_000) {
|
|
30
33
|
this.expectedState = expectedState;
|
|
31
34
|
this.timeoutMs = timeoutMs;
|
|
32
35
|
// Create the deferred up front so a callback that arrives before waitForCode() is not lost.
|
|
@@ -35,7 +38,7 @@ export class LoopbackServer {
|
|
|
35
38
|
this.rejectResult = reject;
|
|
36
39
|
});
|
|
37
40
|
}
|
|
38
|
-
/** Bind the server and return the
|
|
41
|
+
/** Bind the server and return the callback the browser comes back to (and its bare port). */
|
|
39
42
|
async listen() {
|
|
40
43
|
this.server = http.createServer((req, res) => this.handle(req, res));
|
|
41
44
|
this.server.on('error', () => { }); // ignore post-bind socket errors
|
|
@@ -48,7 +51,7 @@ export class LoopbackServer {
|
|
|
48
51
|
});
|
|
49
52
|
});
|
|
50
53
|
this.port = this.server.address().port;
|
|
51
|
-
return { redirectUri: `http://127.0.0.1:${this.port}/callback
|
|
54
|
+
return { redirectUri: `http://127.0.0.1:${this.port}/callback`, port: this.port };
|
|
52
55
|
}
|
|
53
56
|
/** Resolve with the one-time code once the browser hits the callback with a matching state. */
|
|
54
57
|
waitForCode() {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"loopbackServer.js","sourceRoot":"","sources":["../../../src/auth/loopbackServer.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,MAAM,MAAM,aAAa,CAAC;AAGjC;;;;;;;;;;;;;;;GAeG;AACH,MAAM,OAAO,cAAc;IAUN;
|
|
1
|
+
{"version":3,"file":"loopbackServer.js","sourceRoot":"","sources":["../../../src/auth/loopbackServer.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { AuthClient } from '../auth/authClient.js';
|
|
1
|
+
import { AuthClient, describeCredits } from '../auth/authClient.js';
|
|
2
2
|
import { resolveToken } from '../auth/token.js';
|
|
3
3
|
import { apiBaseUrl } from '../config/env.js';
|
|
4
4
|
/**
|
|
@@ -22,9 +22,15 @@ export async function runAccount() {
|
|
|
22
22
|
const info = await new AuthClient({ baseUrl: apiBaseUrl() }).userInfo(token);
|
|
23
23
|
console.log(`Account: ${info.email ?? '(unknown)'}`);
|
|
24
24
|
if (info.plan)
|
|
25
|
-
console.log(`Plan: ${info.plan}`);
|
|
26
|
-
|
|
27
|
-
|
|
25
|
+
console.log(`Plan: ${info.plan}${info.planEndDate ? ` (through ${info.planEndDate})` : ''}`);
|
|
26
|
+
const balance = describeCredits(info);
|
|
27
|
+
if (balance)
|
|
28
|
+
console.log(`Balance: ${balance}`);
|
|
29
|
+
if (info.totalCredits !== undefined && info.totalCredits <= 0) {
|
|
30
|
+
console.error(info.plan
|
|
31
|
+
? '\nTop up at glbgpt.com if you need credits before they reset.'
|
|
32
|
+
: '\nTop up or subscribe at glbgpt.com to start generating.');
|
|
33
|
+
}
|
|
28
34
|
console.error('\nRun `glbgpt account transactions` for recent spend.');
|
|
29
35
|
}
|
|
30
36
|
catch (err) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"accountCommand.js","sourceRoot":"","sources":["../../../src/commands/accountCommand.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;
|
|
1
|
+
{"version":3,"file":"accountCommand.js","sourceRoot":"","sources":["../../../src/commands/accountCommand.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
import { type ConfigKey } from '../config/configFile.js';
|
|
2
|
+
export declare function effective(key: ConfigKey): {
|
|
3
|
+
value: string;
|
|
4
|
+
source: 'env' | 'config' | 'default';
|
|
5
|
+
};
|
|
1
6
|
export declare function runConfigList(): Promise<void>;
|
|
2
7
|
export declare function runConfigGet(key: string): Promise<void>;
|
|
3
8
|
export declare function runConfigSet(key: string, value: string): Promise<void>;
|
|
@@ -1,16 +1,29 @@
|
|
|
1
1
|
import { CONFIG_KEYS, isConfigKey, readConfigSync, writeConfigValue } from '../config/configFile.js';
|
|
2
2
|
import { apiBaseUrl, webBaseUrl, lang } from '../config/env.js';
|
|
3
|
+
import { DEFAULT_SESSION_MAX_CREDITS } from '../fs/limits.js';
|
|
3
4
|
/**
|
|
4
5
|
* `glbgpt config list|get|set|unset` — persistent CLI settings.
|
|
5
6
|
*
|
|
6
7
|
* `list` shows the EFFECTIVE value per key (env override > file > default) and where it
|
|
7
8
|
* came from, so a user can always see why the CLI is talking to a given host.
|
|
8
9
|
*/
|
|
9
|
-
|
|
10
|
+
/** Built-in default per key, for keys whose default doesn't come from an env helper. */
|
|
11
|
+
const KEY_DEFAULTS = {
|
|
12
|
+
'context-pruning': 'true',
|
|
13
|
+
'max-credits': String(DEFAULT_SESSION_MAX_CREDITS),
|
|
14
|
+
'update-check': 'true',
|
|
15
|
+
};
|
|
16
|
+
export function effective(key) {
|
|
10
17
|
const envName = CONFIG_KEYS[key].env;
|
|
11
18
|
const fromEnv = process.env[envName];
|
|
12
19
|
const stored = readConfigSync()[key];
|
|
13
|
-
const value = key === 'api-base-url'
|
|
20
|
+
const value = key === 'api-base-url'
|
|
21
|
+
? apiBaseUrl()
|
|
22
|
+
: key === 'web-base-url'
|
|
23
|
+
? webBaseUrl()
|
|
24
|
+
: key === 'lang'
|
|
25
|
+
? lang()
|
|
26
|
+
: (fromEnv ?? stored ?? KEY_DEFAULTS[key] ?? '');
|
|
14
27
|
return { value, source: fromEnv ? 'env' : stored ? 'config' : 'default' };
|
|
15
28
|
}
|
|
16
29
|
function badKey(key) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"configCommand.js","sourceRoot":"","sources":["../../../src/commands/configCommand.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,cAAc,EAAE,gBAAgB,EAAkB,MAAM,yBAAyB,CAAC;AACrH,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"configCommand.js","sourceRoot":"","sources":["../../../src/commands/configCommand.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { type OutputSinks } from '../exec/output.js';
|
|
2
|
+
import { type ExecMedia } from '../exec/media.js';
|
|
2
3
|
import type { ChatBackend } from '../core/types.js';
|
|
3
4
|
/** Flags parsed from the `exec` subcommand. */
|
|
4
5
|
export interface ExecOptions {
|
|
@@ -11,6 +12,7 @@ export interface ExecOptions {
|
|
|
11
12
|
json?: boolean;
|
|
12
13
|
jsonl?: boolean;
|
|
13
14
|
outputLastMessage?: string;
|
|
15
|
+
maxCredits?: number;
|
|
14
16
|
}
|
|
15
17
|
/** Injectable dependencies (production defaults; overridden in tests). */
|
|
16
18
|
export interface ExecDeps {
|
|
@@ -23,6 +25,10 @@ export interface ExecDeps {
|
|
|
23
25
|
readImage?: (p: string) => Promise<Buffer>;
|
|
24
26
|
writeFile?: (p: string, data: string) => Promise<void>;
|
|
25
27
|
resolveToken?: () => Promise<string | null>;
|
|
28
|
+
/** Override the workspace root the fs tools are jailed to (tests; default `process.cwd()`). */
|
|
29
|
+
workspaceRootDir?: string;
|
|
30
|
+
/** Injectable media surface (tests). */
|
|
31
|
+
execMedia?: ExecMedia;
|
|
26
32
|
}
|
|
27
33
|
/**
|
|
28
34
|
* Run one non-interactive model call and render it per the chosen output mode.
|
|
@@ -1,13 +1,19 @@
|
|
|
1
1
|
import { promises as fs } from 'node:fs';
|
|
2
|
+
import path from 'node:path';
|
|
2
3
|
import { HttpChatBackend } from '../core/httpChatBackend.js';
|
|
3
4
|
import { runChatTurn } from '../core/runChat.js';
|
|
5
|
+
import { ToolRegistry } from '../core/toolRegistry.js';
|
|
4
6
|
import { resolveToken as defaultResolveToken } from '../auth/token.js';
|
|
5
|
-
import { apiBaseUrl } from '../config/env.js';
|
|
7
|
+
import { apiBaseUrl, baseUrlOverrideWarnings } from '../config/env.js';
|
|
6
8
|
import { ensureCatalog } from '../core/catalog.js';
|
|
7
|
-
import { getDefaultChatModel, resolveChatModel } from '../tui/models.js';
|
|
9
|
+
import { getDefaultChatModel, resolveChatModel, modelSupportsTools } from '../tui/models.js';
|
|
8
10
|
import { UsageError, resolvePromptText, injectFiles, loadOutputSchema } from '../exec/input.js';
|
|
9
11
|
import { ExecOutput } from '../exec/output.js';
|
|
12
|
+
import { createFsTools, workspaceRoot } from '../fs/index.js';
|
|
10
13
|
import { resolveImageRef, ImageRefError } from '../util/imageRef.js';
|
|
14
|
+
import { AiApiClient } from '../media/aiApiClient.js';
|
|
15
|
+
import { SessionBudget, resolveMaxCredits } from '../media/budget.js';
|
|
16
|
+
import { createExecMedia } from '../exec/media.js';
|
|
11
17
|
/**
|
|
12
18
|
* Run one non-interactive model call and render it per the chosen output mode.
|
|
13
19
|
* Returns the process exit code (0 success; 1 usage/auth/turn failure) rather than exiting,
|
|
@@ -18,6 +24,10 @@ export async function runExec(positional, opts, deps = {}) {
|
|
|
18
24
|
out: (s) => process.stdout.write(s),
|
|
19
25
|
err: (s) => process.stderr.write(s),
|
|
20
26
|
};
|
|
27
|
+
// Unattended surface: an overridden base URL must be visible in the logs even when
|
|
28
|
+
// nobody is watching the terminal.
|
|
29
|
+
for (const warning of baseUrlOverrideWarnings())
|
|
30
|
+
sinks.err(`${warning}\n`);
|
|
21
31
|
if (opts.json && opts.jsonl) {
|
|
22
32
|
sinks.err('Use either --json or --jsonl, not both.\n');
|
|
23
33
|
return 1;
|
|
@@ -86,28 +96,70 @@ export async function runExec(positional, opts, deps = {}) {
|
|
|
86
96
|
sinks.err('Not signed in. Run `glbgpt login` first (or set GLBGPT_TOKEN).\n');
|
|
87
97
|
return 1;
|
|
88
98
|
}
|
|
89
|
-
// 3.
|
|
99
|
+
// 3. Assemble tools when the resolved model supports tool_use (catalog-driven):
|
|
100
|
+
// fs read tools + budget-gated media generation (spec 2026-07-19-mcp-media-tools-design.md).
|
|
101
|
+
const registry = new ToolRegistry();
|
|
102
|
+
let media;
|
|
103
|
+
if (modelSupportsTools(model)) {
|
|
104
|
+
const root = await workspaceRoot(deps.workspaceRootDir);
|
|
105
|
+
for (const t of createFsTools(root))
|
|
106
|
+
registry.register(t);
|
|
107
|
+
media =
|
|
108
|
+
deps.execMedia ??
|
|
109
|
+
createExecMedia({
|
|
110
|
+
client: new AiApiClient({ baseUrl: apiBaseUrl(), token }),
|
|
111
|
+
budget: new SessionBudget(resolveMaxCredits(opts.maxCredits)),
|
|
112
|
+
outputDir: path.join(process.cwd(), 'glbgpt-output'),
|
|
113
|
+
});
|
|
114
|
+
for (const t of media.tools)
|
|
115
|
+
registry.register(t);
|
|
116
|
+
}
|
|
117
|
+
// 4. Run one chat turn through the shared core, driving the output emitter live.
|
|
90
118
|
const backend = deps.backend ?? new HttpChatBackend({ baseUrl: apiBaseUrl(), token });
|
|
91
119
|
const output = new ExecOutput(mode, model, sinks);
|
|
92
120
|
output.start();
|
|
93
121
|
let result;
|
|
94
122
|
try {
|
|
95
|
-
result = await runChatTurn({ backend, model, prompt: promptContent, system: opts.system, responseFormat }, (event) => {
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
123
|
+
result = await runChatTurn({ backend, model, prompt: promptContent, system: opts.system, responseFormat, registry }, (event) => {
|
|
124
|
+
switch (event.type) {
|
|
125
|
+
case 'assistant_delta':
|
|
126
|
+
output.delta(event.text);
|
|
127
|
+
break;
|
|
128
|
+
case 'usage':
|
|
129
|
+
output.usageEvent(event.promptTokens, event.completionTokens);
|
|
130
|
+
break;
|
|
131
|
+
case 'tool_call_begin':
|
|
132
|
+
output.toolBegin(event.name, event.args);
|
|
133
|
+
break;
|
|
134
|
+
case 'tool_call_end':
|
|
135
|
+
output.toolEnd(event.name, event.result);
|
|
136
|
+
break;
|
|
137
|
+
}
|
|
100
138
|
});
|
|
101
139
|
}
|
|
102
140
|
catch (err) {
|
|
141
|
+
// A failed turn may still have spent money — surface any in-flight results first.
|
|
142
|
+
if (media) {
|
|
143
|
+
if (media.pendingCount() > 0)
|
|
144
|
+
sinks.err('Waiting for media generation to finish…\n');
|
|
145
|
+
for (const r of await media.drain())
|
|
146
|
+
output.mediaResult(r);
|
|
147
|
+
}
|
|
103
148
|
output.finishError(err instanceof Error ? err.message : String(err));
|
|
104
149
|
return 1;
|
|
105
150
|
}
|
|
106
|
-
//
|
|
151
|
+
// 5. Write the last-message file on success only, then render the result.
|
|
107
152
|
if (opts.outputLastMessage) {
|
|
108
153
|
const write = deps.writeFile ?? ((p, data) => fs.writeFile(p, data));
|
|
109
154
|
await write(opts.outputLastMessage, result.content);
|
|
110
155
|
}
|
|
156
|
+
// 5b. Wait for in-flight media tasks — the result files must exist before we exit.
|
|
157
|
+
if (media) {
|
|
158
|
+
if (media.pendingCount() > 0)
|
|
159
|
+
sinks.err('Waiting for media generation to finish…\n');
|
|
160
|
+
for (const r of await media.drain())
|
|
161
|
+
output.mediaResult(r);
|
|
162
|
+
}
|
|
111
163
|
output.finishResult(result.structured);
|
|
112
164
|
return 0;
|
|
113
165
|
}
|