quotacap 0.0.23 → 0.0.25
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 +29 -6
- package/dist/adapters/index.js +3 -0
- package/dist/adapters/muse.d.ts +8 -0
- package/dist/adapters/muse.js +96 -0
- package/dist/adapters/pty.d.ts +35 -0
- package/dist/adapters/pty.js +282 -46
- package/dist/advisory/provider-names.d.ts +14 -0
- package/dist/advisory/provider-names.js +98 -0
- package/dist/advisory/snapshot.d.ts +1 -0
- package/dist/advisory/snapshot.js +7 -0
- package/dist/advisory/types.d.ts +5 -0
- package/dist/advisory/validation.d.ts +9 -0
- package/dist/advisory/validation.js +39 -0
- package/dist/cli/advise.js +2 -1
- package/dist/cli/clients.js +2 -0
- package/dist/cli/providers.d.ts +3 -0
- package/dist/cli/providers.js +174 -0
- package/dist/cli/snapshot-source.d.ts +3 -1
- package/dist/cli/snapshot-source.js +44 -5
- package/dist/cli/status.js +8 -0
- package/dist/cli/takeover.d.ts +1 -0
- package/dist/cli/takeover.js +3 -2
- package/dist/cli/update.js +5 -2
- package/dist/config.d.ts +36 -0
- package/dist/config.js +180 -1
- package/dist/diagnostics/failure.d.ts +26 -0
- package/dist/diagnostics/failure.js +417 -0
- package/dist/format/issues.d.ts +2 -0
- package/dist/format/issues.js +17 -0
- package/dist/format/markdown.js +1 -1
- package/dist/format/rows.js +2 -0
- package/dist/format/terminal.js +6 -6
- package/dist/http/server.d.ts +2 -0
- package/dist/http/server.js +75 -2
- package/dist/mcp/server.js +2 -0
- package/dist/runtime/client.d.ts +1 -0
- package/dist/runtime/client.js +21 -1
- package/dist/runtime/poll.d.ts +12 -4
- package/dist/runtime/poll.js +49 -39
- package/dist/runtime/service.js +18 -5
- package/dist/runtime/spawn.js +14 -4
- package/dist/service/index.js +4 -1
- package/dist/service/macos.d.ts +11 -0
- package/dist/service/macos.js +35 -4
- package/dist/service/systemd.d.ts +2 -0
- package/dist/service/systemd.js +12 -4
- package/dist/store/attempts.d.ts +6 -0
- package/dist/store/attempts.js +27 -20
- package/dist/store/db.js +6 -1
- package/dist/version.js +1 -1
- package/dist/web/src/App.js +1 -1
- package/dist/web/src/api.d.ts +2 -0
- package/dist/web/src/api.js +20 -0
- package/dist/web/src/components/AdviceDrawer.js +3 -4
- package/dist/web/src/components/FaultBanner.js +2 -3
- package/dist/web/src/components/ProviderCard.js +1 -2
- package/dist/web/src/components/ProviderDrawer.d.ts +8 -1
- package/dist/web/src/components/ProviderDrawer.js +103 -7
- package/dist/web/src/components/ProviderIcon.js +1 -0
- package/dist/web/src/components/ProviderRow.js +1 -2
- package/dist/web/src/components/Recommendation.js +2 -3
- package/dist/web/src/components/ResetRail.js +5 -6
- package/dist/web/src/components/SubscriptionList.js +1 -2
- package/dist/web/src/components/settings/ProvidersPanel.js +1 -2
- package/dist/web/src/pages/Onboarding.js +4 -5
- package/dist/web/src/state.d.ts +11 -0
- package/dist/web/src/state.js +18 -0
- package/dist/webAssets.js +1 -1
- package/dist/webHtml.js +1 -1
- package/package.json +3 -1
- package/web/dist/assets/index-ClNhsr1-.js +12 -0
- package/web/dist/assets/index-TJk_KDbS.css +1 -0
- package/web/dist/index.html +2 -2
- package/dist/src/adapters/agy.d.ts +0 -3
- package/dist/src/adapters/agy.js +0 -81
- package/dist/src/adapters/claude.d.ts +0 -9
- package/dist/src/adapters/claude.js +0 -30
- package/dist/src/adapters/codex.d.ts +0 -7
- package/dist/src/adapters/codex.js +0 -140
- package/dist/src/adapters/grok.d.ts +0 -7
- package/dist/src/adapters/grok.js +0 -126
- package/dist/src/adapters/index.d.ts +0 -21
- package/dist/src/adapters/index.js +0 -66
- package/dist/src/adapters/kimi.d.ts +0 -7
- package/dist/src/adapters/kimi.js +0 -76
- package/dist/src/adapters/manual.d.ts +0 -8
- package/dist/src/adapters/manual.js +0 -28
- package/dist/src/adapters/parse.d.ts +0 -1
- package/dist/src/adapters/parse.js +0 -81
- package/dist/src/adapters/pty.d.ts +0 -41
- package/dist/src/adapters/pty.js +0 -579
- package/dist/src/adapters/types.d.ts +0 -21
- package/dist/src/adapters/types.js +0 -1
- package/dist/src/advisory/engine.d.ts +0 -28
- package/dist/src/advisory/engine.js +0 -149
- package/dist/src/advisory/snapshot.d.ts +0 -22
- package/dist/src/advisory/snapshot.js +0 -213
- package/dist/src/advisory/types.d.ts +0 -63
- package/dist/src/advisory/types.js +0 -1
- package/dist/src/advisory/validate.d.ts +0 -5
- package/dist/src/advisory/validate.js +0 -18
- package/dist/src/cli/advise.d.ts +0 -3
- package/dist/src/cli/advise.js +0 -128
- package/dist/src/cli/clients.d.ts +0 -28
- package/dist/src/cli/clients.js +0 -11
- package/dist/src/cli/index.d.ts +0 -2
- package/dist/src/cli/index.js +0 -27
- package/dist/src/cli/ingest.d.ts +0 -3
- package/dist/src/cli/ingest.js +0 -31
- package/dist/src/cli/init.d.ts +0 -2
- package/dist/src/cli/init.js +0 -29
- package/dist/src/cli/runtime.d.ts +0 -33
- package/dist/src/cli/runtime.js +0 -252
- package/dist/src/cli/snapshot-source.d.ts +0 -26
- package/dist/src/cli/snapshot-source.js +0 -232
- package/dist/src/cli/status.d.ts +0 -3
- package/dist/src/cli/status.js +0 -150
- package/dist/src/cli/takeover.d.ts +0 -64
- package/dist/src/cli/takeover.js +0 -175
- package/dist/src/cli/update.d.ts +0 -61
- package/dist/src/cli/update.js +0 -392
- package/dist/src/config.d.ts +0 -47
- package/dist/src/config.js +0 -185
- package/dist/src/daemon.d.ts +0 -4
- package/dist/src/daemon.js +0 -15
- package/dist/src/format/markdown.d.ts +0 -3
- package/dist/src/format/markdown.js +0 -24
- package/dist/src/format/rows.d.ts +0 -27
- package/dist/src/format/rows.js +0 -241
- package/dist/src/format/terminal.d.ts +0 -12
- package/dist/src/format/terminal.js +0 -144
- package/dist/src/http/server.d.ts +0 -33
- package/dist/src/http/server.js +0 -314
- package/dist/src/mcp/server.d.ts +0 -46
- package/dist/src/mcp/server.js +0 -163
- package/dist/src/runtime/client.d.ts +0 -24
- package/dist/src/runtime/client.js +0 -72
- package/dist/src/runtime/owner.d.ts +0 -35
- package/dist/src/runtime/owner.js +0 -393
- package/dist/src/runtime/poll.d.ts +0 -50
- package/dist/src/runtime/poll.js +0 -229
- package/dist/src/runtime/service.d.ts +0 -24
- package/dist/src/runtime/service.js +0 -268
- package/dist/src/runtime/spawn.d.ts +0 -17
- package/dist/src/runtime/spawn.js +0 -97
- package/dist/src/runtime/token.d.ts +0 -3
- package/dist/src/runtime/token.js +0 -64
- package/dist/src/runtime/updates.d.ts +0 -74
- package/dist/src/runtime/updates.js +0 -445
- package/dist/src/runtime/versions.d.ts +0 -2
- package/dist/src/runtime/versions.js +0 -26
- package/dist/src/service/index.d.ts +0 -9
- package/dist/src/service/index.js +0 -103
- package/dist/src/service/macos.d.ts +0 -100
- package/dist/src/service/macos.js +0 -602
- package/dist/src/service/systemd.d.ts +0 -40
- package/dist/src/service/systemd.js +0 -387
- package/dist/src/store/attempts.d.ts +0 -12
- package/dist/src/store/attempts.js +0 -29
- package/dist/src/store/db.d.ts +0 -2
- package/dist/src/store/db.js +0 -74
- package/dist/src/store/quotas.d.ts +0 -6
- package/dist/src/store/quotas.js +0 -98
- package/dist/src/version.d.ts +0 -1
- package/dist/src/version.js +0 -2
- package/dist/src/webAssets.d.ts +0 -1
- package/dist/src/webAssets.js +0 -2
- package/dist/src/webHtml.d.ts +0 -1
- package/dist/src/webHtml.js +0 -2
- package/dist/tests/adapters/agy.test.d.ts +0 -1
- package/dist/tests/adapters/agy.test.js +0 -337
- package/dist/tests/adapters/claude.test.d.ts +0 -1
- package/dist/tests/adapters/claude.test.js +0 -83
- package/dist/tests/adapters/codex.test.d.ts +0 -1
- package/dist/tests/adapters/codex.test.js +0 -246
- package/dist/tests/adapters/credential-free.test.d.ts +0 -1
- package/dist/tests/adapters/credential-free.test.js +0 -211
- package/dist/tests/adapters/grok.test.d.ts +0 -1
- package/dist/tests/adapters/grok.test.js +0 -269
- package/dist/tests/adapters/kimi.test.d.ts +0 -1
- package/dist/tests/adapters/kimi.test.js +0 -235
- package/dist/tests/adapters/manual.test.d.ts +0 -1
- package/dist/tests/adapters/manual.test.js +0 -28
- package/dist/tests/adapters/pty-perms.test.d.ts +0 -1
- package/dist/tests/adapters/pty-perms.test.js +0 -78
- package/dist/tests/adapters/pty.test.d.ts +0 -1
- package/dist/tests/adapters/pty.test.js +0 -240
- package/dist/tests/adapters/registry.test.d.ts +0 -1
- package/dist/tests/adapters/registry.test.js +0 -25
- package/dist/tests/advisory/engine.test.d.ts +0 -1
- package/dist/tests/advisory/engine.test.js +0 -222
- package/dist/tests/advisory/pace.test.d.ts +0 -1
- package/dist/tests/advisory/pace.test.js +0 -60
- package/dist/tests/advisory/snapshot.test.d.ts +0 -1
- package/dist/tests/advisory/snapshot.test.js +0 -65
- package/dist/tests/advisory/validate.test.d.ts +0 -1
- package/dist/tests/advisory/validate.test.js +0 -19
- package/dist/tests/bootstrap.test.d.ts +0 -1
- package/dist/tests/bootstrap.test.js +0 -14
- package/dist/tests/cli/advise.test.d.ts +0 -1
- package/dist/tests/cli/advise.test.js +0 -367
- package/dist/tests/cli/cli.test.d.ts +0 -1
- package/dist/tests/cli/cli.test.js +0 -46
- package/dist/tests/cli/helpers.d.ts +0 -9
- package/dist/tests/cli/helpers.js +0 -93
- package/dist/tests/cli/ingest.test.d.ts +0 -1
- package/dist/tests/cli/ingest.test.js +0 -188
- package/dist/tests/cli/init.test.d.ts +0 -1
- package/dist/tests/cli/init.test.js +0 -55
- package/dist/tests/cli/launcher.test.d.ts +0 -1
- package/dist/tests/cli/launcher.test.js +0 -271
- package/dist/tests/cli/parity.test.d.ts +0 -1
- package/dist/tests/cli/parity.test.js +0 -225
- package/dist/tests/cli/snapshot-source.test.d.ts +0 -1
- package/dist/tests/cli/snapshot-source.test.js +0 -305
- package/dist/tests/cli/status.test.d.ts +0 -1
- package/dist/tests/cli/status.test.js +0 -536
- package/dist/tests/cli/takeover.test.d.ts +0 -1
- package/dist/tests/cli/takeover.test.js +0 -325
- package/dist/tests/cli/update.test.d.ts +0 -1
- package/dist/tests/cli/update.test.js +0 -382
- package/dist/tests/daemon.test.d.ts +0 -1
- package/dist/tests/daemon.test.js +0 -164
- package/dist/tests/fixtures/stable-state.d.ts +0 -22
- package/dist/tests/fixtures/stable-state.js +0 -152
- package/dist/tests/fixtures/stable-state.test.d.ts +0 -1
- package/dist/tests/fixtures/stable-state.test.js +0 -17
- package/dist/tests/format/markdown.test.d.ts +0 -1
- package/dist/tests/format/markdown.test.js +0 -49
- package/dist/tests/format/terminal.test.d.ts +0 -1
- package/dist/tests/format/terminal.test.js +0 -476
- package/dist/tests/http/api.test.d.ts +0 -1
- package/dist/tests/http/api.test.js +0 -236
- package/dist/tests/integration.test.d.ts +0 -1
- package/dist/tests/integration.test.js +0 -61
- package/dist/tests/mcp/protocol.test.d.ts +0 -1
- package/dist/tests/mcp/protocol.test.js +0 -134
- package/dist/tests/mcp/quotas.test.d.ts +0 -1
- package/dist/tests/mcp/quotas.test.js +0 -56
- package/dist/tests/mcp/server.test.d.ts +0 -1
- package/dist/tests/mcp/server.test.js +0 -7
- package/dist/tests/mcp/tools.test.d.ts +0 -1
- package/dist/tests/mcp/tools.test.js +0 -291
- package/dist/tests/runtime/cancel.test.d.ts +0 -1
- package/dist/tests/runtime/cancel.test.js +0 -264
- package/dist/tests/runtime/cli.test.d.ts +0 -1
- package/dist/tests/runtime/cli.test.js +0 -426
- package/dist/tests/runtime/config.test.d.ts +0 -1
- package/dist/tests/runtime/config.test.js +0 -144
- package/dist/tests/runtime/http.test.d.ts +0 -1
- package/dist/tests/runtime/http.test.js +0 -346
- package/dist/tests/runtime/lifecycle.test.d.ts +0 -1
- package/dist/tests/runtime/lifecycle.test.js +0 -303
- package/dist/tests/runtime/ownership.test.d.ts +0 -1
- package/dist/tests/runtime/ownership.test.js +0 -355
- package/dist/tests/runtime/poll.test.d.ts +0 -1
- package/dist/tests/runtime/poll.test.js +0 -438
- package/dist/tests/runtime/status.test.d.ts +0 -1
- package/dist/tests/runtime/status.test.js +0 -232
- package/dist/tests/runtime/updates.test.d.ts +0 -1
- package/dist/tests/runtime/updates.test.js +0 -509
- package/dist/tests/service/macos.test.d.ts +0 -1
- package/dist/tests/service/macos.test.js +0 -450
- package/dist/tests/service/systemd.test.d.ts +0 -1
- package/dist/tests/service/systemd.test.js +0 -330
- package/dist/tests/smoke/dashboard.e2e.d.ts +0 -1
- package/dist/tests/smoke/dashboard.e2e.js +0 -142
- package/dist/tests/smoke/playwright.config.d.ts +0 -2
- package/dist/tests/smoke/playwright.config.js +0 -11
- package/dist/tests/store/attempts.test.d.ts +0 -1
- package/dist/tests/store/attempts.test.js +0 -29
- package/dist/tests/store/db.test.d.ts +0 -1
- package/dist/tests/store/db.test.js +0 -96
- package/dist/tests/store/migration.test.d.ts +0 -1
- package/dist/tests/store/migration.test.js +0 -41
- package/dist/tests/web/advice-drawer.test.d.ts +0 -1
- package/dist/tests/web/advice-drawer.test.js +0 -45
- package/dist/tests/web/build.test.d.ts +0 -1
- package/dist/tests/web/build.test.js +0 -8
- package/dist/tests/web/dashboard.e2e.d.ts +0 -1
- package/dist/tests/web/dashboard.e2e.js +0 -670
- package/dist/tests/web/header.test.d.ts +0 -1
- package/dist/tests/web/header.test.js +0 -82
- package/dist/tests/web/names.test.d.ts +0 -1
- package/dist/tests/web/names.test.js +0 -19
- package/dist/tests/web/onboarding.test.d.ts +0 -1
- package/dist/tests/web/onboarding.test.js +0 -21
- package/dist/tests/web/pacing.test.d.ts +0 -1
- package/dist/tests/web/pacing.test.js +0 -62
- package/dist/tests/web/playwright.config.d.ts +0 -2
- package/dist/tests/web/playwright.config.js +0 -10
- package/dist/tests/web/provider-drawer.test.d.ts +0 -1
- package/dist/tests/web/provider-drawer.test.js +0 -68
- package/dist/tests/web/recommendation.test.d.ts +0 -1
- package/dist/tests/web/recommendation.test.js +0 -38
- package/dist/tests/web/reset-rail.test.d.ts +0 -1
- package/dist/tests/web/reset-rail.test.js +0 -63
- package/dist/tests/web/responsive.test.d.ts +0 -1
- package/dist/tests/web/responsive.test.js +0 -21
- package/dist/tests/web/settings.test.d.ts +0 -1
- package/dist/tests/web/settings.test.js +0 -32
- package/dist/tests/web/state-catalog.test.d.ts +0 -1
- package/dist/tests/web/state-catalog.test.js +0 -206
- package/dist/tests/web/state.test.d.ts +0 -1
- package/dist/tests/web/state.test.js +0 -27
- package/dist/tests/web/stub-server.d.ts +0 -37
- package/dist/tests/web/stub-server.js +0 -132
- package/dist/tests/web/theme.test.d.ts +0 -1
- package/dist/tests/web/theme.test.js +0 -12
- package/dist/web/src/names.d.ts +0 -3
- package/dist/web/src/names.js +0 -19
- package/web/dist/assets/index-BEBqgvq8.css +0 -1
- package/web/dist/assets/index-DZfttQgo.js +0 -12
package/dist/adapters/pty.js
CHANGED
|
@@ -3,6 +3,7 @@ import os from "node:os";
|
|
|
3
3
|
import path from "node:path";
|
|
4
4
|
import { createRequire } from "node:module";
|
|
5
5
|
import { registerTrackedChild } from "../runtime/spawn.js";
|
|
6
|
+
import { diagnosticError, DiagnosticError } from "../diagnostics/failure.js";
|
|
6
7
|
export function stripAnsi(s) {
|
|
7
8
|
return s
|
|
8
9
|
.replace(/\x1b\[[^A-Za-z]*[A-Za-z]/g, "")
|
|
@@ -18,6 +19,51 @@ function regexTest(re, s) {
|
|
|
18
19
|
const fresh = new RegExp(re.source, re.flags.replace("g", ""));
|
|
19
20
|
return fresh.test(s);
|
|
20
21
|
}
|
|
22
|
+
/**
|
|
23
|
+
* Canned answers to terminal capability queries, table-driven so a future
|
|
24
|
+
* query type is a one-line row. Replies are static: colour answers never
|
|
25
|
+
* affect parsing because styling is stripped before matching.
|
|
26
|
+
*/
|
|
27
|
+
export const TERMINAL_QUERY_RESPONSES = [
|
|
28
|
+
// DSR (device status report): cursor position request. Unanswered, some
|
|
29
|
+
// TUIs exit outright ("cursor position could not be read").
|
|
30
|
+
{ match: /\x1b\[[0-9;]*6n/, reply: () => "\x1b[1;1R" },
|
|
31
|
+
// DA1 (primary device attributes): `CSI c` is exclusively a DA request.
|
|
32
|
+
{ match: /\x1b\[[0-9;]*c/, reply: () => "\x1b[?1;2c" },
|
|
33
|
+
// OSC 4/10/11 colour queries, BEL- or ST-terminated. The palette index is
|
|
34
|
+
// echoed back; 16 OSC 4 queries were measured in a single Muse startup.
|
|
35
|
+
{ match: /\x1b\]4;(\d+);\?(?:\x07|\x1b\\)/, reply: (m) => `\x1b]4;${m[1]};rgb:0000/0000/0000\x07` },
|
|
36
|
+
{ match: /\x1b\]10;\?(?:\x07|\x1b\\)/, reply: () => "\x1b]10;rgb:ffff/ffff/ffff\x07" },
|
|
37
|
+
{ match: /\x1b\]11;\?(?:\x07|\x1b\\)/, reply: () => "\x1b]11;rgb:0000/0000/0000\x07" },
|
|
38
|
+
];
|
|
39
|
+
/**
|
|
40
|
+
* Stateful feeder for `TERMINAL_QUERY_RESPONSES`. Consumes each matched query
|
|
41
|
+
* from an internal buffer, so a query split across chunks is answered once it
|
|
42
|
+
* completes and never answered twice. Plain output passes through silently.
|
|
43
|
+
*/
|
|
44
|
+
export function createTerminalQueryResponder(write) {
|
|
45
|
+
let buf = "";
|
|
46
|
+
return (chunk) => {
|
|
47
|
+
buf += chunk;
|
|
48
|
+
let progress = true;
|
|
49
|
+
while (progress) {
|
|
50
|
+
progress = false;
|
|
51
|
+
for (const rule of TERMINAL_QUERY_RESPONSES) {
|
|
52
|
+
const m = rule.match.exec(buf);
|
|
53
|
+
if (m?.index !== undefined) {
|
|
54
|
+
write(rule.reply(m));
|
|
55
|
+
buf = buf.slice(0, m.index) + buf.slice(m.index + m[0].length);
|
|
56
|
+
progress = true;
|
|
57
|
+
break;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
// Bounded tail: a partial query can only straddle the end of the stream,
|
|
62
|
+
// and the longest query is well under 64 bytes.
|
|
63
|
+
if (buf.length > 64)
|
|
64
|
+
buf = buf.slice(-64);
|
|
65
|
+
};
|
|
66
|
+
}
|
|
21
67
|
/**
|
|
22
68
|
* Lazy replacement for the removed postinstall: best-effort `chmod 0o755`
|
|
23
69
|
* over every prebuilds entry `spawn-helper` under the given node-pty roots.
|
|
@@ -143,8 +189,8 @@ function getPty() {
|
|
|
143
189
|
catch { }
|
|
144
190
|
}
|
|
145
191
|
const repairNote = describeSpawnHelperRepairs(repairs);
|
|
146
|
-
throw new Error("pty: node-pty not available — install with build tools (Xcode on macOS, build-essential + python3 on Linux) or use exec-based adapters only; for compiled binaries, ensure the pty sidecar is installed alongside the binary (see install.sh)" +
|
|
147
|
-
(repairNote ? `; ${repairNote}` : ""));
|
|
192
|
+
throw diagnosticError(new Error("pty: node-pty not available — install with build tools (Xcode on macOS, build-essential + python3 on Linux) or use exec-based adapters only; for compiled binaries, ensure the pty sidecar is installed alongside the binary (see install.sh)" +
|
|
193
|
+
(repairNote ? `; ${repairNote}` : "")), { source: "pty" });
|
|
148
194
|
}
|
|
149
195
|
function isBunRuntime() {
|
|
150
196
|
return typeof globalThis.Bun !== "undefined" && typeof globalThis.Bun.spawn === "function";
|
|
@@ -155,9 +201,9 @@ async function runPtyBun(opts) {
|
|
|
155
201
|
const rows = opts.rows ?? 50;
|
|
156
202
|
const readyTimeoutMs = opts.readyTimeoutMs ?? 6000;
|
|
157
203
|
if (opts.timeoutMs <= 0)
|
|
158
|
-
throw new Error("pty: timeoutMs must be > 0");
|
|
204
|
+
throw diagnosticError(new Error("pty: timeoutMs must be > 0"), { source: "pty" });
|
|
159
205
|
if (opts.signal?.aborted)
|
|
160
|
-
throw new Error("pty aborted");
|
|
206
|
+
throw diagnosticError(new Error("pty aborted"), { source: "pty", checkpoint: "abort" });
|
|
161
207
|
let aborted = false;
|
|
162
208
|
const onAbort = () => {
|
|
163
209
|
aborted = true;
|
|
@@ -166,7 +212,7 @@ async function runPtyBun(opts) {
|
|
|
166
212
|
opts.signal.addEventListener("abort", onAbort, { once: true });
|
|
167
213
|
const checkAborted = () => {
|
|
168
214
|
if (aborted)
|
|
169
|
-
throw new Error("pty aborted");
|
|
215
|
+
throw diagnosticError(new Error("pty aborted"), { source: "pty", checkpoint: "abort", stdout: transcript });
|
|
170
216
|
};
|
|
171
217
|
const teardownAbort = () => {
|
|
172
218
|
if (opts.signal)
|
|
@@ -181,6 +227,7 @@ async function runPtyBun(opts) {
|
|
|
181
227
|
// through proc.terminal.write, and merged output arrives in `data`.
|
|
182
228
|
// proc.stdin/stdout/stderr are null in this mode.
|
|
183
229
|
const decoder = new TextDecoder();
|
|
230
|
+
let feedQueries = null;
|
|
184
231
|
const proc = BunGlobal.spawn([opts.file, ...(opts.args ?? [])], {
|
|
185
232
|
cwd: opts.cwd ?? process.cwd(),
|
|
186
233
|
env: {
|
|
@@ -193,7 +240,9 @@ async function runPtyBun(opts) {
|
|
|
193
240
|
rows,
|
|
194
241
|
data(_term, chunk) {
|
|
195
242
|
try {
|
|
196
|
-
|
|
243
|
+
const text = typeof chunk === "string" ? chunk : decoder.decode(chunk, { stream: true });
|
|
244
|
+
transcript += text;
|
|
245
|
+
feedQueries?.(text);
|
|
197
246
|
}
|
|
198
247
|
catch { }
|
|
199
248
|
},
|
|
@@ -206,7 +255,15 @@ async function runPtyBun(opts) {
|
|
|
206
255
|
proc.kill();
|
|
207
256
|
}
|
|
208
257
|
catch { }
|
|
209
|
-
throw new Error("pty: Bun runtime lacks terminal (PTY) support (Bun.spawn terminal option unavailable) — rebuild the standalone binary with a newer Bun version");
|
|
258
|
+
throw diagnosticError(new Error("pty: Bun runtime lacks terminal (PTY) support (Bun.spawn terminal option unavailable) — rebuild the standalone binary with a newer Bun version"), { source: "pty" });
|
|
259
|
+
}
|
|
260
|
+
if (opts.respondToQueries) {
|
|
261
|
+
feedQueries = createTerminalQueryResponder((s) => {
|
|
262
|
+
try {
|
|
263
|
+
proc.terminal.write(s);
|
|
264
|
+
}
|
|
265
|
+
catch { }
|
|
266
|
+
});
|
|
210
267
|
}
|
|
211
268
|
// Poll for exit
|
|
212
269
|
const exitPoll = (async () => {
|
|
@@ -220,12 +277,20 @@ async function runPtyBun(opts) {
|
|
|
220
277
|
void exitPoll;
|
|
221
278
|
const checkCap = () => {
|
|
222
279
|
if (Buffer.byteLength(transcript, "utf8") > maxBytes) {
|
|
223
|
-
throw new Error(`pty transcript exceeds ${maxBytes} bytes`)
|
|
280
|
+
throw diagnosticError(new Error(`pty transcript exceeds ${maxBytes} bytes`), {
|
|
281
|
+
source: "pty",
|
|
282
|
+
checkpoint: "transcript overflow",
|
|
283
|
+
stdout: transcript,
|
|
284
|
+
});
|
|
224
285
|
}
|
|
225
286
|
};
|
|
226
287
|
const checkAbort = (clean) => {
|
|
227
288
|
if (opts.abortOn && regexTest(opts.abortOn, clean)) {
|
|
228
|
-
throw new Error(`pty: untrusted workspace — trust prompt detected in ${opts.cwd ?? process.cwd()} — run \`${opts.file}\` there and select Trust this folder`)
|
|
289
|
+
throw diagnosticError(new Error(`pty: untrusted workspace — trust prompt detected in ${opts.cwd ?? process.cwd()} — run \`${opts.file}\` there and select Trust this folder`), {
|
|
290
|
+
source: "pty",
|
|
291
|
+
checkpoint: "trust prompt",
|
|
292
|
+
stdout: transcript,
|
|
293
|
+
});
|
|
229
294
|
}
|
|
230
295
|
};
|
|
231
296
|
const kill = async () => {
|
|
@@ -267,8 +332,14 @@ async function runPtyBun(opts) {
|
|
|
267
332
|
while (Date.now() < deadline) {
|
|
268
333
|
checkCap();
|
|
269
334
|
checkAborted();
|
|
270
|
-
if (exited)
|
|
271
|
-
throw new Error(`pty exited before ready (code ${exitCode})`)
|
|
335
|
+
if (exited) {
|
|
336
|
+
throw diagnosticError(new Error(`pty exited before ready (code ${exitCode})`), {
|
|
337
|
+
source: "pty",
|
|
338
|
+
checkpoint: "before ready",
|
|
339
|
+
exitCode,
|
|
340
|
+
stdout: transcript,
|
|
341
|
+
});
|
|
342
|
+
}
|
|
272
343
|
const clean = stripAnsi(transcript);
|
|
273
344
|
checkAbort(clean);
|
|
274
345
|
if (regexTest(opts.readyRegex, clean)) {
|
|
@@ -279,13 +350,24 @@ async function runPtyBun(opts) {
|
|
|
279
350
|
}
|
|
280
351
|
if (!matched) {
|
|
281
352
|
await kill();
|
|
282
|
-
throw new Error(`pty ready timeout after ${readyTimeoutMs}ms`)
|
|
353
|
+
throw diagnosticError(new Error(`pty ready timeout after ${readyTimeoutMs}ms`), {
|
|
354
|
+
source: "pty",
|
|
355
|
+
checkpoint: "ready timeout",
|
|
356
|
+
durationMs: readyTimeoutMs,
|
|
357
|
+
stdout: transcript,
|
|
358
|
+
});
|
|
283
359
|
}
|
|
284
|
-
await delay(200);
|
|
360
|
+
await delay(opts.settleDelayMs ?? 200);
|
|
285
361
|
checkCap();
|
|
286
362
|
checkAborted();
|
|
287
|
-
if (exited)
|
|
288
|
-
throw new Error(`pty exited before input (code ${exitCode})`)
|
|
363
|
+
if (exited) {
|
|
364
|
+
throw diagnosticError(new Error(`pty exited before input (code ${exitCode})`), {
|
|
365
|
+
source: "pty",
|
|
366
|
+
checkpoint: "before input",
|
|
367
|
+
exitCode,
|
|
368
|
+
stdout: transcript,
|
|
369
|
+
});
|
|
370
|
+
}
|
|
289
371
|
const postReadyClean = stripAnsi(transcript);
|
|
290
372
|
checkAbort(postReadyClean);
|
|
291
373
|
}
|
|
@@ -293,18 +375,57 @@ async function runPtyBun(opts) {
|
|
|
293
375
|
await delay(opts.settleDelayMs);
|
|
294
376
|
checkCap();
|
|
295
377
|
checkAborted();
|
|
296
|
-
if (exited)
|
|
297
|
-
throw new Error(`pty exited during settle (code ${exitCode})`)
|
|
378
|
+
if (exited) {
|
|
379
|
+
throw diagnosticError(new Error(`pty exited during settle (code ${exitCode})`), {
|
|
380
|
+
source: "pty",
|
|
381
|
+
checkpoint: "during settle",
|
|
382
|
+
exitCode,
|
|
383
|
+
stdout: transcript,
|
|
384
|
+
});
|
|
385
|
+
}
|
|
298
386
|
const c = stripAnsi(transcript);
|
|
299
387
|
checkAbort(c);
|
|
300
388
|
}
|
|
301
|
-
if (exited)
|
|
302
|
-
throw new Error(`pty exited before input (code ${exitCode})`)
|
|
389
|
+
if (exited) {
|
|
390
|
+
throw diagnosticError(new Error(`pty exited before input (code ${exitCode})`), {
|
|
391
|
+
source: "pty",
|
|
392
|
+
checkpoint: "before input",
|
|
393
|
+
exitCode,
|
|
394
|
+
stdout: transcript,
|
|
395
|
+
});
|
|
396
|
+
}
|
|
303
397
|
try {
|
|
304
398
|
proc.terminal.write(opts.input);
|
|
305
399
|
}
|
|
306
400
|
catch (e) {
|
|
307
|
-
throw new Error(`pty write failed: ${e.message}`)
|
|
401
|
+
throw diagnosticError(new Error(`pty write failed: ${e.message}`), {
|
|
402
|
+
source: "pty",
|
|
403
|
+
checkpoint: "write",
|
|
404
|
+
stdout: transcript,
|
|
405
|
+
});
|
|
406
|
+
}
|
|
407
|
+
if (opts.submitInput !== undefined && opts.submitAfterMs !== undefined) {
|
|
408
|
+
await delay(opts.submitAfterMs);
|
|
409
|
+
checkCap();
|
|
410
|
+
checkAborted();
|
|
411
|
+
if (exited) {
|
|
412
|
+
throw diagnosticError(new Error(`pty exited before input (code ${exitCode})`), {
|
|
413
|
+
source: "pty",
|
|
414
|
+
checkpoint: "before input",
|
|
415
|
+
exitCode,
|
|
416
|
+
stdout: transcript,
|
|
417
|
+
});
|
|
418
|
+
}
|
|
419
|
+
try {
|
|
420
|
+
proc.terminal.write(opts.submitInput);
|
|
421
|
+
}
|
|
422
|
+
catch (e) {
|
|
423
|
+
throw diagnosticError(new Error(`pty write failed: ${e.message}`), {
|
|
424
|
+
source: "pty",
|
|
425
|
+
checkpoint: "write",
|
|
426
|
+
stdout: transcript,
|
|
427
|
+
});
|
|
428
|
+
}
|
|
308
429
|
}
|
|
309
430
|
if (opts.completionRegex) {
|
|
310
431
|
const deadline = Date.now() + opts.timeoutMs;
|
|
@@ -320,7 +441,12 @@ async function runPtyBun(opts) {
|
|
|
320
441
|
}
|
|
321
442
|
if (exited) {
|
|
322
443
|
if (!regexTest(opts.completionRegex, clean)) {
|
|
323
|
-
throw new Error(`pty exited before completion (code ${exitCode})`)
|
|
444
|
+
throw diagnosticError(new Error(`pty exited before completion (code ${exitCode})`), {
|
|
445
|
+
source: "pty",
|
|
446
|
+
checkpoint: "before completion",
|
|
447
|
+
exitCode,
|
|
448
|
+
stdout: transcript,
|
|
449
|
+
});
|
|
324
450
|
}
|
|
325
451
|
done = true;
|
|
326
452
|
break;
|
|
@@ -329,7 +455,12 @@ async function runPtyBun(opts) {
|
|
|
329
455
|
}
|
|
330
456
|
if (!done) {
|
|
331
457
|
await kill();
|
|
332
|
-
throw new Error(`pty completion timeout after ${opts.timeoutMs}ms`)
|
|
458
|
+
throw diagnosticError(new Error(`pty completion timeout after ${opts.timeoutMs}ms`), {
|
|
459
|
+
source: "pty",
|
|
460
|
+
checkpoint: "completion timeout",
|
|
461
|
+
durationMs: opts.timeoutMs,
|
|
462
|
+
stdout: transcript,
|
|
463
|
+
});
|
|
333
464
|
}
|
|
334
465
|
}
|
|
335
466
|
else {
|
|
@@ -372,7 +503,9 @@ async function runPtyBun(opts) {
|
|
|
372
503
|
catch { }
|
|
373
504
|
unregisterChild();
|
|
374
505
|
teardownAbort();
|
|
375
|
-
|
|
506
|
+
if (e instanceof DiagnosticError)
|
|
507
|
+
throw e;
|
|
508
|
+
throw diagnosticError(e, { source: "pty", stdout: transcript, exitCode });
|
|
376
509
|
}
|
|
377
510
|
}
|
|
378
511
|
async function runPtyNode(opts) {
|
|
@@ -381,9 +514,9 @@ async function runPtyNode(opts) {
|
|
|
381
514
|
const rows = opts.rows ?? 50;
|
|
382
515
|
const readyTimeoutMs = opts.readyTimeoutMs ?? 6000;
|
|
383
516
|
if (opts.timeoutMs <= 0)
|
|
384
|
-
throw new Error("pty: timeoutMs must be > 0");
|
|
517
|
+
throw diagnosticError(new Error("pty: timeoutMs must be > 0"), { source: "pty" });
|
|
385
518
|
if (opts.signal?.aborted)
|
|
386
|
-
throw new Error("pty aborted");
|
|
519
|
+
throw diagnosticError(new Error("pty aborted"), { source: "pty", checkpoint: "abort" });
|
|
387
520
|
let aborted = false;
|
|
388
521
|
const onAbort = () => {
|
|
389
522
|
aborted = true;
|
|
@@ -392,7 +525,7 @@ async function runPtyNode(opts) {
|
|
|
392
525
|
opts.signal.addEventListener("abort", onAbort, { once: true });
|
|
393
526
|
const checkAborted = () => {
|
|
394
527
|
if (aborted)
|
|
395
|
-
throw new Error("pty aborted");
|
|
528
|
+
throw diagnosticError(new Error("pty aborted"), { source: "pty", checkpoint: "abort", stdout: transcript });
|
|
396
529
|
};
|
|
397
530
|
const teardownAbort = () => {
|
|
398
531
|
if (opts.signal)
|
|
@@ -417,7 +550,10 @@ async function runPtyNode(opts) {
|
|
|
417
550
|
});
|
|
418
551
|
}
|
|
419
552
|
catch (e) {
|
|
420
|
-
throw new Error(`pty spawn failed for ${opts.file}: ${e.message}`)
|
|
553
|
+
throw diagnosticError(new Error(`pty spawn failed for ${opts.file}: ${e.message}`), {
|
|
554
|
+
source: "pty",
|
|
555
|
+
checkpoint: "spawn",
|
|
556
|
+
});
|
|
421
557
|
}
|
|
422
558
|
const unregisterChild = registerTrackedChild(() => {
|
|
423
559
|
try {
|
|
@@ -425,9 +561,21 @@ async function runPtyNode(opts) {
|
|
|
425
561
|
}
|
|
426
562
|
catch { }
|
|
427
563
|
}, opts.label ?? opts.file);
|
|
564
|
+
const feedQueries = opts.respondToQueries
|
|
565
|
+
? createTerminalQueryResponder((s) => {
|
|
566
|
+
try {
|
|
567
|
+
ptyProcess.write(s);
|
|
568
|
+
}
|
|
569
|
+
catch { }
|
|
570
|
+
})
|
|
571
|
+
: null;
|
|
428
572
|
const disposables = [];
|
|
429
573
|
disposables.push(ptyProcess.onData((data) => {
|
|
430
574
|
transcript += data;
|
|
575
|
+
try {
|
|
576
|
+
feedQueries?.(data);
|
|
577
|
+
}
|
|
578
|
+
catch { }
|
|
431
579
|
}));
|
|
432
580
|
disposables.push(ptyProcess.onExit(({ exitCode: c }) => {
|
|
433
581
|
exited = true;
|
|
@@ -465,12 +613,20 @@ async function runPtyNode(opts) {
|
|
|
465
613
|
};
|
|
466
614
|
const checkCap = () => {
|
|
467
615
|
if (Buffer.byteLength(transcript, "utf8") > maxBytes) {
|
|
468
|
-
throw new Error(`pty transcript exceeds ${maxBytes} bytes`)
|
|
616
|
+
throw diagnosticError(new Error(`pty transcript exceeds ${maxBytes} bytes`), {
|
|
617
|
+
source: "pty",
|
|
618
|
+
checkpoint: "transcript overflow",
|
|
619
|
+
stdout: transcript,
|
|
620
|
+
});
|
|
469
621
|
}
|
|
470
622
|
};
|
|
471
623
|
const checkAbort = (clean) => {
|
|
472
624
|
if (opts.abortOn && regexTest(opts.abortOn, clean)) {
|
|
473
|
-
throw new Error(`pty: untrusted workspace — trust prompt detected in ${opts.cwd ?? process.cwd()} — run \`${opts.file}\` there and select Trust this folder`)
|
|
625
|
+
throw diagnosticError(new Error(`pty: untrusted workspace — trust prompt detected in ${opts.cwd ?? process.cwd()} — run \`${opts.file}\` there and select Trust this folder`), {
|
|
626
|
+
source: "pty",
|
|
627
|
+
checkpoint: "trust prompt",
|
|
628
|
+
stdout: transcript,
|
|
629
|
+
});
|
|
474
630
|
}
|
|
475
631
|
};
|
|
476
632
|
try {
|
|
@@ -480,8 +636,14 @@ async function runPtyNode(opts) {
|
|
|
480
636
|
while (Date.now() < deadline) {
|
|
481
637
|
checkCap();
|
|
482
638
|
checkAborted();
|
|
483
|
-
if (exited)
|
|
484
|
-
throw new Error(`pty exited before ready (code ${exitCode})`)
|
|
639
|
+
if (exited) {
|
|
640
|
+
throw diagnosticError(new Error(`pty exited before ready (code ${exitCode})`), {
|
|
641
|
+
source: "pty",
|
|
642
|
+
checkpoint: "before ready",
|
|
643
|
+
exitCode,
|
|
644
|
+
stdout: transcript,
|
|
645
|
+
});
|
|
646
|
+
}
|
|
485
647
|
const clean = stripAnsi(transcript);
|
|
486
648
|
checkAbort(clean);
|
|
487
649
|
if (regexTest(opts.readyRegex, clean)) {
|
|
@@ -492,13 +654,24 @@ async function runPtyNode(opts) {
|
|
|
492
654
|
}
|
|
493
655
|
if (!matched) {
|
|
494
656
|
await kill();
|
|
495
|
-
throw new Error(`pty ready timeout after ${readyTimeoutMs}ms`)
|
|
657
|
+
throw diagnosticError(new Error(`pty ready timeout after ${readyTimeoutMs}ms`), {
|
|
658
|
+
source: "pty",
|
|
659
|
+
checkpoint: "ready timeout",
|
|
660
|
+
durationMs: readyTimeoutMs,
|
|
661
|
+
stdout: transcript,
|
|
662
|
+
});
|
|
496
663
|
}
|
|
497
|
-
await delay(200);
|
|
664
|
+
await delay(opts.settleDelayMs ?? 200);
|
|
498
665
|
checkCap();
|
|
499
666
|
checkAborted();
|
|
500
|
-
if (exited)
|
|
501
|
-
throw new Error(`pty exited before input (code ${exitCode})`)
|
|
667
|
+
if (exited) {
|
|
668
|
+
throw diagnosticError(new Error(`pty exited before input (code ${exitCode})`), {
|
|
669
|
+
source: "pty",
|
|
670
|
+
checkpoint: "before input",
|
|
671
|
+
exitCode,
|
|
672
|
+
stdout: transcript,
|
|
673
|
+
});
|
|
674
|
+
}
|
|
502
675
|
const postReadyClean = stripAnsi(transcript);
|
|
503
676
|
checkAbort(postReadyClean);
|
|
504
677
|
}
|
|
@@ -506,14 +679,58 @@ async function runPtyNode(opts) {
|
|
|
506
679
|
await delay(opts.settleDelayMs);
|
|
507
680
|
checkCap();
|
|
508
681
|
checkAborted();
|
|
509
|
-
if (exited)
|
|
510
|
-
throw new Error(`pty exited during settle (code ${exitCode})`)
|
|
682
|
+
if (exited) {
|
|
683
|
+
throw diagnosticError(new Error(`pty exited during settle (code ${exitCode})`), {
|
|
684
|
+
source: "pty",
|
|
685
|
+
checkpoint: "during settle",
|
|
686
|
+
exitCode,
|
|
687
|
+
stdout: transcript,
|
|
688
|
+
});
|
|
689
|
+
}
|
|
511
690
|
const c = stripAnsi(transcript);
|
|
512
691
|
checkAbort(c);
|
|
513
692
|
}
|
|
514
|
-
if (exited)
|
|
515
|
-
throw new Error(`pty exited before input (code ${exitCode})`)
|
|
516
|
-
|
|
693
|
+
if (exited) {
|
|
694
|
+
throw diagnosticError(new Error(`pty exited before input (code ${exitCode})`), {
|
|
695
|
+
source: "pty",
|
|
696
|
+
checkpoint: "before input",
|
|
697
|
+
exitCode,
|
|
698
|
+
stdout: transcript,
|
|
699
|
+
});
|
|
700
|
+
}
|
|
701
|
+
try {
|
|
702
|
+
ptyProcess.write(opts.input);
|
|
703
|
+
}
|
|
704
|
+
catch (e) {
|
|
705
|
+
throw diagnosticError(new Error(`pty write failed: ${e.message}`), {
|
|
706
|
+
source: "pty",
|
|
707
|
+
checkpoint: "write",
|
|
708
|
+
stdout: transcript,
|
|
709
|
+
});
|
|
710
|
+
}
|
|
711
|
+
if (opts.submitInput !== undefined && opts.submitAfterMs !== undefined) {
|
|
712
|
+
await delay(opts.submitAfterMs);
|
|
713
|
+
checkCap();
|
|
714
|
+
checkAborted();
|
|
715
|
+
if (exited) {
|
|
716
|
+
throw diagnosticError(new Error(`pty exited before input (code ${exitCode})`), {
|
|
717
|
+
source: "pty",
|
|
718
|
+
checkpoint: "before input",
|
|
719
|
+
exitCode,
|
|
720
|
+
stdout: transcript,
|
|
721
|
+
});
|
|
722
|
+
}
|
|
723
|
+
try {
|
|
724
|
+
ptyProcess.write(opts.submitInput);
|
|
725
|
+
}
|
|
726
|
+
catch (e) {
|
|
727
|
+
throw diagnosticError(new Error(`pty write failed: ${e.message}`), {
|
|
728
|
+
source: "pty",
|
|
729
|
+
checkpoint: "write",
|
|
730
|
+
stdout: transcript,
|
|
731
|
+
});
|
|
732
|
+
}
|
|
733
|
+
}
|
|
517
734
|
if (opts.completionRegex) {
|
|
518
735
|
const deadline = Date.now() + opts.timeoutMs;
|
|
519
736
|
let done = false;
|
|
@@ -528,7 +745,12 @@ async function runPtyNode(opts) {
|
|
|
528
745
|
}
|
|
529
746
|
if (exited) {
|
|
530
747
|
if (!regexTest(opts.completionRegex, clean)) {
|
|
531
|
-
throw new Error(`pty exited before completion (code ${exitCode})`)
|
|
748
|
+
throw diagnosticError(new Error(`pty exited before completion (code ${exitCode})`), {
|
|
749
|
+
source: "pty",
|
|
750
|
+
checkpoint: "before completion",
|
|
751
|
+
exitCode,
|
|
752
|
+
stdout: transcript,
|
|
753
|
+
});
|
|
532
754
|
}
|
|
533
755
|
done = true;
|
|
534
756
|
break;
|
|
@@ -537,7 +759,12 @@ async function runPtyNode(opts) {
|
|
|
537
759
|
}
|
|
538
760
|
if (!done) {
|
|
539
761
|
await kill();
|
|
540
|
-
throw new Error(`pty completion timeout after ${opts.timeoutMs}ms`)
|
|
762
|
+
throw diagnosticError(new Error(`pty completion timeout after ${opts.timeoutMs}ms`), {
|
|
763
|
+
source: "pty",
|
|
764
|
+
checkpoint: "completion timeout",
|
|
765
|
+
durationMs: opts.timeoutMs,
|
|
766
|
+
stdout: transcript,
|
|
767
|
+
});
|
|
541
768
|
}
|
|
542
769
|
}
|
|
543
770
|
else {
|
|
@@ -563,7 +790,9 @@ async function runPtyNode(opts) {
|
|
|
563
790
|
}
|
|
564
791
|
catch (e) {
|
|
565
792
|
await kill();
|
|
566
|
-
|
|
793
|
+
if (e instanceof DiagnosticError)
|
|
794
|
+
throw e;
|
|
795
|
+
throw diagnosticError(e, { source: "pty", stdout: transcript, exitCode });
|
|
567
796
|
}
|
|
568
797
|
finally {
|
|
569
798
|
cleanup();
|
|
@@ -572,8 +801,15 @@ async function runPtyNode(opts) {
|
|
|
572
801
|
}
|
|
573
802
|
}
|
|
574
803
|
export async function runPty(opts) {
|
|
575
|
-
|
|
576
|
-
|
|
804
|
+
try {
|
|
805
|
+
if (isBunRuntime()) {
|
|
806
|
+
return await runPtyBun(opts);
|
|
807
|
+
}
|
|
808
|
+
return await runPtyNode(opts);
|
|
809
|
+
}
|
|
810
|
+
catch (e) {
|
|
811
|
+
if (e instanceof DiagnosticError)
|
|
812
|
+
throw e;
|
|
813
|
+
throw diagnosticError(e, { source: "pty" });
|
|
577
814
|
}
|
|
578
|
-
return runPtyNode(opts);
|
|
579
815
|
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export interface ProviderIdentity {
|
|
2
|
+
displayName: string;
|
|
3
|
+
builtinName: string | null;
|
|
4
|
+
vendor: string | null;
|
|
5
|
+
harness: string | null;
|
|
6
|
+
description: string | null;
|
|
7
|
+
}
|
|
8
|
+
export declare const REGISTRY: Map<string, {
|
|
9
|
+
displayName: string;
|
|
10
|
+
vendor: string | null;
|
|
11
|
+
harness: string | null;
|
|
12
|
+
description: string;
|
|
13
|
+
}>;
|
|
14
|
+
export declare function providerIdentity(id: string, overrides?: Record<string, string>): ProviderIdentity;
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
// One server-side home for provider identity. Unknown ids (manual pastes)
|
|
2
|
+
// degrade to the raw id with null metadata instead of throwing. Map, not a
|
|
3
|
+
// plain object: Object.prototype keys such as __proto__ and constructor would
|
|
4
|
+
// otherwise resolve as inherited values, not literals.
|
|
5
|
+
export const REGISTRY = new Map([
|
|
6
|
+
[
|
|
7
|
+
"claude",
|
|
8
|
+
{
|
|
9
|
+
displayName: "Claude",
|
|
10
|
+
vendor: "Anthropic",
|
|
11
|
+
harness: "Claude Code",
|
|
12
|
+
description: "Anthropic's Claude Code subscription, metered as a weekly window with a shorter session window inside it.",
|
|
13
|
+
},
|
|
14
|
+
],
|
|
15
|
+
[
|
|
16
|
+
"codex",
|
|
17
|
+
{
|
|
18
|
+
displayName: "Codex",
|
|
19
|
+
vendor: "OpenAI",
|
|
20
|
+
harness: "Codex CLI",
|
|
21
|
+
description: "OpenAI's Codex CLI subscription, metered as weekly and 5-hour windows.",
|
|
22
|
+
},
|
|
23
|
+
],
|
|
24
|
+
[
|
|
25
|
+
"kimi",
|
|
26
|
+
{
|
|
27
|
+
displayName: "Kimi",
|
|
28
|
+
vendor: "Moonshot AI",
|
|
29
|
+
harness: "Kimi Code",
|
|
30
|
+
description: "Moonshot's Kimi Code subscription, metered as weekly and 5-hour windows.",
|
|
31
|
+
},
|
|
32
|
+
],
|
|
33
|
+
[
|
|
34
|
+
"grok",
|
|
35
|
+
{
|
|
36
|
+
displayName: "Grok",
|
|
37
|
+
vendor: "xAI",
|
|
38
|
+
harness: "Grok CLI",
|
|
39
|
+
description: "xAI's Grok CLI subscription, metered weekly, with a separate pay-as-you-go credit balance.",
|
|
40
|
+
},
|
|
41
|
+
],
|
|
42
|
+
[
|
|
43
|
+
"agy",
|
|
44
|
+
{
|
|
45
|
+
displayName: "Antigravity",
|
|
46
|
+
vendor: "Google",
|
|
47
|
+
harness: "Antigravity",
|
|
48
|
+
description: "The Gemini model pool in Google's Antigravity, metered weekly with a 5-hour window inside it.",
|
|
49
|
+
},
|
|
50
|
+
],
|
|
51
|
+
[
|
|
52
|
+
"agy:3p",
|
|
53
|
+
{
|
|
54
|
+
displayName: "Antigravity 3P",
|
|
55
|
+
vendor: "Google",
|
|
56
|
+
harness: "Antigravity",
|
|
57
|
+
description: "The third-party model pool in Google's Antigravity — Claude and GPT models billed against your Google plan and metered separately from Gemini.",
|
|
58
|
+
},
|
|
59
|
+
],
|
|
60
|
+
[
|
|
61
|
+
"muse",
|
|
62
|
+
{
|
|
63
|
+
displayName: "Muse",
|
|
64
|
+
vendor: "Meta",
|
|
65
|
+
harness: "Muse Code",
|
|
66
|
+
description: "Meta's Muse Code subscription, running Muse Spark models, metered as a weekly window with a shorter current window inside it.",
|
|
67
|
+
},
|
|
68
|
+
],
|
|
69
|
+
[
|
|
70
|
+
"manual",
|
|
71
|
+
{
|
|
72
|
+
displayName: "Manual",
|
|
73
|
+
vendor: null,
|
|
74
|
+
harness: null,
|
|
75
|
+
description: "A quota you pasted in by hand. QuotaCap does not poll it.",
|
|
76
|
+
},
|
|
77
|
+
],
|
|
78
|
+
]);
|
|
79
|
+
export function providerIdentity(id, overrides) {
|
|
80
|
+
const entry = REGISTRY.get(id);
|
|
81
|
+
const override = overrides && typeof overrides[id] === "string" && overrides[id].trim().length > 0
|
|
82
|
+
? overrides[id].trim()
|
|
83
|
+
: undefined;
|
|
84
|
+
if (!entry) {
|
|
85
|
+
return {
|
|
86
|
+
displayName: override ?? id,
|
|
87
|
+
builtinName: null,
|
|
88
|
+
vendor: null,
|
|
89
|
+
harness: null,
|
|
90
|
+
description: null,
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
return {
|
|
94
|
+
...entry,
|
|
95
|
+
displayName: override ?? entry.displayName,
|
|
96
|
+
builtinName: entry.displayName,
|
|
97
|
+
};
|
|
98
|
+
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { getAllLatest, getBurnRates } from "../store/quotas.js";
|
|
2
2
|
import { getAttempts } from "../store/attempts.js";
|
|
3
3
|
import { recommend, averagePace, computeAdvisory } from "./engine.js";
|
|
4
|
+
import { providerIdentity } from "./provider-names.js";
|
|
4
5
|
export const STALE_MS = 60 * 60 * 1000;
|
|
5
6
|
function normalizeAdvisory(adv) {
|
|
6
7
|
if (!adv)
|
|
@@ -141,6 +142,7 @@ export function buildSnapshot(db, opts) {
|
|
|
141
142
|
}
|
|
142
143
|
providerSnapshots.push({
|
|
143
144
|
id,
|
|
145
|
+
...providerIdentity(id, opts.providerNames),
|
|
144
146
|
enabled,
|
|
145
147
|
quota,
|
|
146
148
|
lastAttempt: attempt,
|
|
@@ -202,6 +204,11 @@ export function projectQuotasResponse(s) {
|
|
|
202
204
|
.filter((p) => p.quota !== null)
|
|
203
205
|
.map((p) => ({
|
|
204
206
|
...p.quota,
|
|
207
|
+
displayName: p.displayName,
|
|
208
|
+
builtinName: p.builtinName ?? null,
|
|
209
|
+
vendor: p.vendor,
|
|
210
|
+
harness: p.harness,
|
|
211
|
+
description: p.description,
|
|
205
212
|
stale: p.stale,
|
|
206
213
|
ageMs: p.ageMs,
|
|
207
214
|
evidence: p.evidence,
|