@wrongstack/cli 0.299.0 → 0.300.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/dist/{acp-S4LZQB66.js → acp-IDNS2YVE.js} +3 -3
- package/dist/{auth-G5YKKSRH.js → auth-6T6ZOT2R.js} +5 -5
- package/dist/auth-menu/loopback-server.d.ts +41 -55
- package/dist/auth-menu/openai-codex-oauth.d.ts +36 -123
- package/dist/auto-discover-providers-DRW4OZHG.js +8 -0
- package/dist/boot/dispatch-webui.d.ts +3 -0
- package/dist/{chunk-PEKUKUCH.js → chunk-3MWUZMOL.js} +19 -12
- package/dist/{chunk-TGDHN4LM.js → chunk-4GVH7V3S.js} +4 -24
- package/dist/{chunk-4U3DMA2Y.js → chunk-4WJKVQJY.js} +15 -20
- package/dist/{chunk-2SLSUDYS.js → chunk-GYDQABMA.js} +269 -180
- package/dist/{chunk-4HH3YGG4.js → chunk-MRLYDHQ7.js} +8 -5
- package/dist/{chunk-66T43Q4Y.js → chunk-N7ULWBO5.js} +4 -3
- package/dist/{chunk-ZNZJ34RF.js → chunk-PEMN4T5O.js} +2 -2
- package/dist/chunk-PYTFS4MC.js +238 -0
- package/dist/{chunk-L5CE52XW.js → chunk-V76R7DC5.js} +25 -19
- package/dist/{cli-main-3MQDFSYK.js → cli-main-7B3G2YSG.js} +528 -156
- package/dist/{execution-ANOYMWPO.js → execution-SHGM7BVC.js} +50 -5
- package/dist/fleet/budget-source.d.ts +18 -0
- package/dist/fleet/host-status.d.ts +31 -0
- package/dist/fleet/host-types.d.ts +8 -0
- package/dist/fleet/host.d.ts +5 -0
- package/dist/{hq-BDO56CX6.js → hq-DVDD4XPV.js} +22 -3
- package/dist/hq-server/auth-state.d.ts +29 -1
- package/dist/hq-server/auth.d.ts +16 -0
- package/dist/hq-server/client-address.d.ts +56 -0
- package/dist/hq-server/login-attempt-store.d.ts +30 -10
- package/dist/hq-server/routes/auth-handlers.d.ts +66 -26
- package/dist/hq-server/routes.d.ts +13 -0
- package/dist/hq-server/types.d.ts +10 -0
- package/dist/{hq-server-RJLJJZU7.js → hq-server-DQHLNHDL.js} +2 -2
- package/dist/hq-server.d.ts +19 -0
- package/dist/index.js +20 -20
- package/dist/{modeldiag-HENYJ4N7.js → modeldiag-YOQZHBQV.js} +2 -2
- package/dist/{plugin-usage-VTL7ZTVC.js → plugin-usage-EOG4ET4S.js} +2 -2
- package/dist/{plugins-ETY6W3DC.js → plugins-56CMWMPR.js} +3 -3
- package/dist/{providers-models-GDELBHZK.js → providers-models-K6RT7ABI.js} +34 -9
- package/dist/slash-commands/command-context.d.ts +19 -0
- package/dist/webui-server/setup-events.d.ts +17 -0
- package/dist/webui-server/terminal-log-view.d.ts +29 -12
- package/dist/{webui-server-PCLSXX6L.js → webui-server-G3EKFXLL.js} +109 -38
- package/dist/webui-server-options.d.ts +16 -0
- package/dist/wiring/brain-and-orchestration.d.ts +3 -0
- package/dist/wiring/director-setup.d.ts +4 -0
- package/dist/wiring/fallback-gate.d.ts +31 -0
- package/dist/wiring/fleet-command-handlers.d.ts +1 -1
- package/dist/wiring/plugins.d.ts +2 -8
- package/dist/wiring/provider-utility-tools.d.ts +26 -1
- package/package.json +23 -23
- package/dist/chunk-GO3TJICK.js +0 -489
|
@@ -3,8 +3,8 @@ import {
|
|
|
3
3
|
loadCachedAcpRegistry,
|
|
4
4
|
refreshAcpRegistry,
|
|
5
5
|
setupProvider
|
|
6
|
-
} from "./chunk-
|
|
7
|
-
import "./chunk-
|
|
6
|
+
} from "./chunk-MRLYDHQ7.js";
|
|
7
|
+
import "./chunk-PYTFS4MC.js";
|
|
8
8
|
import "./chunk-PJHET45A.js";
|
|
9
9
|
import "./chunk-7OCVIDC7.js";
|
|
10
10
|
|
|
@@ -889,4 +889,4 @@ ${renderAcpBenchText(result)}
|
|
|
889
889
|
export {
|
|
890
890
|
acpCmd
|
|
891
891
|
};
|
|
892
|
-
//# sourceMappingURL=acp-
|
|
892
|
+
//# sourceMappingURL=acp-IDNS2YVE.js.map
|
|
@@ -13,12 +13,12 @@ import {
|
|
|
13
13
|
runOAuthLoginKind,
|
|
14
14
|
runOAuthLoginMenu,
|
|
15
15
|
validateFamily
|
|
16
|
-
} from "./chunk-
|
|
16
|
+
} from "./chunk-V76R7DC5.js";
|
|
17
17
|
import {
|
|
18
18
|
parseAuthFlags
|
|
19
|
-
} from "./chunk-
|
|
20
|
-
import "./chunk-
|
|
21
|
-
import "./chunk-
|
|
19
|
+
} from "./chunk-PEMN4T5O.js";
|
|
20
|
+
import "./chunk-N7ULWBO5.js";
|
|
21
|
+
import "./chunk-PYTFS4MC.js";
|
|
22
22
|
import {
|
|
23
23
|
loadConfigProviders,
|
|
24
24
|
maskedKey,
|
|
@@ -501,4 +501,4 @@ async function runAuthRemove(deps, providerId) {
|
|
|
501
501
|
export {
|
|
502
502
|
authCmd
|
|
503
503
|
};
|
|
504
|
-
//# sourceMappingURL=auth-
|
|
504
|
+
//# sourceMappingURL=auth-6T6ZOT2R.js.map
|
|
@@ -1,40 +1,29 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* Terminal-side adapter for the OAuth loopback callback server.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
4
|
+
* The server itself — HTTP listener, port fallback, `state` validation, the
|
|
5
|
+
* static callback page and its CSP/anti-framing headers, abort handling — lives
|
|
6
|
+
* in `@wrongstack/providers/oauth`. This file used to carry a second, complete
|
|
7
|
+
* implementation of all of it.
|
|
8
8
|
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
9
|
+
* The copies were not identical, and the difference mattered: this one
|
|
10
|
+
* registered its abort listener with `{ once: true }` and never removed it, so
|
|
11
|
+
* every completed login leaked a listener on the caller's long-lived
|
|
12
|
+
* AbortSignal (the TUI hands the same signal to each attempt). The providers
|
|
13
|
+
* copy had the `detachAbort` cleanup. Neither file had any way to notice the
|
|
14
|
+
* other had drifted.
|
|
13
15
|
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
16
|
+
* What legitimately stays here is {@link openBrowser}: spawning the platform
|
|
17
|
+
* browser is terminal-only behaviour, and the headless WebUI flows deliberately
|
|
18
|
+
* hand the authorize URL to the client instead of opening anything.
|
|
17
19
|
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
* ```
|
|
20
|
+
* The positional signature below is preserved so the three CLI OAuth flows and
|
|
21
|
+
* their tests keep working unchanged.
|
|
21
22
|
*
|
|
22
23
|
* @module auth-menu/loopback-server
|
|
23
24
|
*/
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
* Shared by all loopback-based OAuth flows so the success/error page styling
|
|
27
|
-
* is consistent and the HTML generation isn't duplicated.
|
|
28
|
-
*/
|
|
29
|
-
export declare function callbackHtml(ok: boolean, message: string): string;
|
|
30
|
-
/**
|
|
31
|
-
* Open a URL in the user's default browser. Best-effort — never throws.
|
|
32
|
-
*
|
|
33
|
-
* - Windows: `cmd /c start "" <url>`
|
|
34
|
-
* - macOS: `open <url>`
|
|
35
|
-
* - Linux: `xdg-open <url>`
|
|
36
|
-
*/
|
|
37
|
-
export declare function openBrowser(url: string): void;
|
|
25
|
+
import { type LoopbackServer } from '@wrongstack/providers/oauth';
|
|
26
|
+
export { callbackHtml, type LoopbackServer } from '@wrongstack/providers/oauth';
|
|
38
27
|
/** Result of waiting for the OAuth callback. */
|
|
39
28
|
export interface LoopbackCallback {
|
|
40
29
|
/** The authorization code from the provider. */
|
|
@@ -42,35 +31,32 @@ export interface LoopbackCallback {
|
|
|
42
31
|
/** The OAuth state parameter from the callback (validated against expected). */
|
|
43
32
|
state: string;
|
|
44
33
|
}
|
|
45
|
-
export interface LoopbackServer {
|
|
46
|
-
/**
|
|
47
|
-
* Wait for the browser to redirect back with the authorization code.
|
|
48
|
-
* Resolves with the code and state, or `null` if cancelled/failed.
|
|
49
|
-
*/
|
|
50
|
-
waitForCode(): Promise<LoopbackCallback | null>;
|
|
51
|
-
/** Close the HTTP server and release the port. */
|
|
52
|
-
close(): void;
|
|
53
|
-
/** True when the server bound to a registered callback port. */
|
|
54
|
-
readonly bound: boolean;
|
|
55
|
-
/** The actual port the server is listening on (matches the authorize URL redirect_uri). */
|
|
56
|
-
readonly port: number;
|
|
57
|
-
}
|
|
58
34
|
/**
|
|
59
|
-
*
|
|
60
|
-
*
|
|
61
|
-
* The server listens on the first available port from `ports`. If all ports
|
|
62
|
-
* are busy, `bound` is `false` and the caller should fall back to a manual
|
|
63
|
-
* paste prompt.
|
|
35
|
+
* Open a URL in the user's default browser. Best-effort — never throws.
|
|
64
36
|
*
|
|
65
|
-
*
|
|
66
|
-
*
|
|
67
|
-
*
|
|
37
|
+
* - Windows: `cmd /c start "" <url>`
|
|
38
|
+
* - macOS: `open <url>`
|
|
39
|
+
* - Linux: `xdg-open <url>`
|
|
68
40
|
*
|
|
69
|
-
*
|
|
70
|
-
*
|
|
71
|
-
*
|
|
72
|
-
*
|
|
73
|
-
|
|
41
|
+
* Not `detached`: the CLI flows wait on the loopback callback in the
|
|
42
|
+
* foreground, so the opener is a short-lived handoff. (The WebUI server's
|
|
43
|
+
* `openBrowser` is deliberately different — it detaches and registers the pid
|
|
44
|
+
* as protected because it launches a browser the session must outlive.)
|
|
45
|
+
*/
|
|
46
|
+
export declare function openBrowser(url: string): void;
|
|
47
|
+
/**
|
|
48
|
+
* Start a loopback HTTP server for the OAuth authorization-code callback.
|
|
49
|
+
*
|
|
50
|
+
* Binds the first available port from `ports`. If all are busy, `bound` is
|
|
51
|
+
* `false` and the caller falls back to a manual paste prompt. When `signal`
|
|
52
|
+
* aborts (Ctrl+C, TUI Esc), the pending `waitForCode()` resolves to `null` and
|
|
53
|
+
* the server is torn down.
|
|
54
|
+
*
|
|
55
|
+
* @param expectedState - the OAuth `state` to validate the callback against
|
|
56
|
+
* @param ports - ordered ports to try; first available wins
|
|
57
|
+
* @param signal - optional external cancellation
|
|
58
|
+
* @param callbackPath - path the provider redirects to (default `/auth/callback`)
|
|
59
|
+
* @param redirectHost - hostname to listen on (default `127.0.0.1`)
|
|
74
60
|
*/
|
|
75
61
|
export declare function startLoopbackServer(expectedState: string, ports: readonly number[], signal?: AbortSignal, callbackPath?: string, redirectHost?: string): Promise<LoopbackServer>;
|
|
76
62
|
//# sourceMappingURL=loopback-server.d.ts.map
|
|
@@ -1,138 +1,51 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* OpenAI Codex — "Sign in with ChatGPT"
|
|
2
|
+
* OpenAI Codex — "Sign in with ChatGPT", terminal flow.
|
|
3
3
|
*
|
|
4
|
-
* This is
|
|
5
|
-
*
|
|
4
|
+
* This module is now only the *terminal* half of the login: the rendered
|
|
5
|
+
* instructions, the SIGINT / TUI-signal cancellation contract, the
|
|
6
|
+
* manual-paste prompt, and writing the resulting tokens into the encrypted
|
|
7
|
+
* profile config.
|
|
6
8
|
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
* 6. Store the tokens in the vault as an `oauth` ProviderApiKey.
|
|
9
|
+
* The protocol itself — client id, endpoints, PKCE, the authorize URL, the
|
|
10
|
+
* token exchange and refresh, the JWT account-id claim, and model discovery —
|
|
11
|
+
* lives in `@wrongstack/providers/oauth`. It used to live here AND in
|
|
12
|
+
* `providers/src/oauth/chatgpt.ts` (the headless WebUI flow) AND in
|
|
13
|
+
* `providers/src/openai-codex.ts` (the runtime refresh path), whose header
|
|
14
|
+
* said outright that it was mirroring this file.
|
|
14
15
|
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
16
|
+
* Three copies is what let the OAuth abort-listener leak sit in two of them
|
|
17
|
+
* while a third flow in this same directory was already correct — nothing
|
|
18
|
+
* forced them to agree, so a fix applied to one silently left the others
|
|
19
|
+
* broken. A rotated client id or a changed token-endpoint contract carries the
|
|
20
|
+
* same risk, with the failure being "one surface stops authenticating" rather
|
|
21
|
+
* than a compile error.
|
|
21
22
|
*
|
|
22
|
-
*
|
|
23
|
-
*
|
|
24
|
-
*
|
|
23
|
+
* The protocol constants live in `providers` (not here) because the dependency
|
|
24
|
+
* edge runs `cli → providers → core`: the runtime provider needs them to
|
|
25
|
+
* refresh a token and must never import from `cli`.
|
|
26
|
+
*
|
|
27
|
+
* Everything the protocol layer defines is re-exported below, so existing
|
|
28
|
+
* importers (`auth-menu/index.ts`, `wiring/provider.ts`, the CLI tests) keep
|
|
29
|
+
* working against this module unchanged.
|
|
25
30
|
*/
|
|
31
|
+
import { buildCodexAuthorizeUrl, exchangeCodexAuthorizationCode, refreshCodexTokens } from '@wrongstack/providers/oauth';
|
|
26
32
|
import { type LoopbackServer } from './loopback-server.js';
|
|
27
|
-
import { type ModelsRegistry } from '@wrongstack/core/types';
|
|
28
33
|
import type { AuthMenuDeps } from './types.js';
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
* Codex-specific compatibility wrapper retained for callers that imported the
|
|
35
|
-
* helper from this module before the shared OAuth loopback server extraction.
|
|
36
|
-
*/
|
|
37
|
-
export declare function startLoopbackServer(expectedState: string, signal?: AbortSignal): Promise<LoopbackServer>;
|
|
38
|
-
/**
|
|
39
|
-
* Fallback model list used when BOTH the live backend AND the models.dev
|
|
40
|
-
* catalog are unreachable. This should never happen in practice — the
|
|
41
|
-
* catalog is cached locally and the only scenario where both fail is a
|
|
42
|
-
* fresh install with no network on first login.
|
|
43
|
-
*
|
|
44
|
-
* The primary resolution order in `resolveCodexModels()` is:
|
|
45
|
-
* 1. Live backend (`GET /models`)
|
|
46
|
-
* 2. models.dev catalog (`family: gpt-codex*` under `openai` provider)
|
|
47
|
-
* 3. This inline fallback
|
|
48
|
-
*/
|
|
49
|
-
export interface CodexTokens {
|
|
50
|
-
access: string;
|
|
51
|
-
refresh: string;
|
|
52
|
-
/** Absolute expiry in epoch milliseconds. */
|
|
53
|
-
expires: number;
|
|
54
|
-
idToken?: string | undefined;
|
|
55
|
-
}
|
|
56
|
-
export interface Pkce {
|
|
57
|
-
verifier: string;
|
|
58
|
-
challenge: string;
|
|
59
|
-
}
|
|
60
|
-
/** Generate a PKCE verifier + S256 challenge. */
|
|
61
|
-
export declare function generatePkce(): Pkce;
|
|
62
|
-
/** Build the full authorize URL with all Codex-required query params. */
|
|
63
|
-
export declare function buildAuthorizeUrl(challenge: string, state: string, port?: number): string;
|
|
64
|
-
/**
|
|
65
|
-
* Extract `chatgpt_account_id` from an access/id token JWT. Returns null when
|
|
66
|
-
* the token isn't a JWT or lacks the claim (the caller decides whether that
|
|
67
|
-
* is fatal — for login it is; for a cached display value it isn't).
|
|
68
|
-
*/
|
|
69
|
-
export declare function extractAccountId(token: string): string | null;
|
|
70
|
-
/**
|
|
71
|
-
* Recommended Codex models for ChatGPT sign-in. Live backend discovery
|
|
72
|
-
* wins; these values are only used when the backend/catalog cannot
|
|
73
|
-
* provide a list. Derived from `CODEX_MODELS` in core (the single source of
|
|
74
|
-
* truth for Codex id/name/description) — used both by OAuth login
|
|
75
|
-
* (resolveCodexModels → tier 3) and by the provider-boot synthesis
|
|
76
|
-
* path (wiring/provider.ts when the catalog is unavailable).
|
|
77
|
-
*/
|
|
78
|
-
export declare const FALLBACK_CODEX_MODELS: ReadonlyArray<{
|
|
79
|
-
id: string;
|
|
80
|
-
name: string;
|
|
81
|
-
}>;
|
|
82
|
-
/** Families in the models.dev catalog that indicate Codex / Responses API compatibility. */
|
|
83
|
-
export declare const CODEX_CATALOG_FAMILIES: Set<string>;
|
|
84
|
-
export declare function fallbackCodexModelIds(): string[];
|
|
85
|
-
export declare function fallbackCodexProviderModels(): Array<{
|
|
86
|
-
id: string;
|
|
87
|
-
name: string;
|
|
88
|
-
}>;
|
|
89
|
-
/**
|
|
90
|
-
* Filter a list of available model ids down to the ones that are still
|
|
91
|
-
* current for ChatGPT sign-in (i.e. present in FALLBACK_CODEX_MODELS).
|
|
92
|
-
* Used by both OAuth login (to drop deprecated ids from the live /models
|
|
93
|
-
* response) and by the provider-boot synthesis (to pick current ids out
|
|
94
|
-
* of the models.dev catalog).
|
|
95
|
-
*/
|
|
96
|
-
export declare function filterCurrentCodexModelIds(ids: Iterable<string>): string[];
|
|
97
|
-
export declare function isCodexCatalogModel(model: {
|
|
98
|
-
family?: string | undefined;
|
|
99
|
-
}): boolean;
|
|
100
|
-
/**
|
|
101
|
-
* Resolve the list of available Codex models using a 3-tier fallback chain:
|
|
102
|
-
*
|
|
103
|
-
* 1. **Live backend** — `fetchCodexModels()` hits `GET <baseUrl>/models`
|
|
104
|
-
* and keeps only current Codex model ids.
|
|
105
|
-
* 2. **models.dev catalog** — queries the `openai` provider in the cached
|
|
106
|
-
* models.dev registry and picks models whose `family` is `gpt-codex` or
|
|
107
|
-
* `gpt-codex-spark` and whose ids are current for ChatGPT sign-in.
|
|
108
|
-
* 3. **Inline fallback** — a minimal list of documented mainstream models
|
|
109
|
-
* (`gpt-5.6-sol`, `gpt-5.5`, `gpt-5.6-terra`, `gpt-5.6-luna`,
|
|
110
|
-
* `gpt-5.4`, `gpt-5.4-mini`, `gpt-5.3-codex-spark`).
|
|
111
|
-
*
|
|
112
|
-
* The live/catalog tiers gate account availability, while the shared current
|
|
113
|
-
* model list filters out deprecated ChatGPT sign-in ids before config is saved.
|
|
114
|
-
*/
|
|
115
|
-
export declare function resolveCodexModels(modelsRegistry: ModelsRegistry, accessToken: Promise<string> | string, baseUrl?: string | undefined, signal?: AbortSignal): Promise<string[]>;
|
|
34
|
+
export { CODEX_BASE_URL, CODEX_CATALOG_FAMILIES, CODEX_PROVIDER_ID, type CodexTokens, extractAccountId, FALLBACK_CODEX_MODELS, fallbackCodexModelIds, fallbackCodexProviderModels, fetchCodexModels, filterCurrentCodexModelIds, generatePkce, isCodexCatalogModel, parseAuthorizationInput, type Pkce, resolveCodexModels, } from '@wrongstack/providers/oauth';
|
|
35
|
+
/** Build the Codex authorize URL. Alias kept for the historical local name. */
|
|
36
|
+
export declare const buildAuthorizeUrl: typeof buildCodexAuthorizeUrl;
|
|
37
|
+
/** Exchange an authorization code (+ PKCE verifier) for tokens. */
|
|
38
|
+
export declare const exchangeAuthorizationCode: typeof exchangeCodexAuthorizationCode;
|
|
116
39
|
/**
|
|
117
|
-
*
|
|
118
|
-
*
|
|
119
|
-
* Hits `GET <baseUrl>/models` — the standard OpenAI-compatible model listing
|
|
120
|
-
* endpoint, which the Codex backend may expose. Best-effort: returns an empty
|
|
121
|
-
* array on any failure so login still succeeds with the hardcoded fallback.
|
|
40
|
+
* Refresh an expired access token. Alias kept for the historical local name;
|
|
41
|
+
* `wiring/provider.ts` and the CLI tests import it from here.
|
|
122
42
|
*/
|
|
123
|
-
export declare
|
|
124
|
-
/** Exchange an authorization code (+ PKCE verifier) for tokens. */
|
|
125
|
-
export declare function exchangeAuthorizationCode(code: string, verifier: string, signal?: AbortSignal, port?: number): Promise<CodexTokens>;
|
|
43
|
+
export declare const refreshCodexToken: typeof refreshCodexTokens;
|
|
126
44
|
/**
|
|
127
|
-
*
|
|
128
|
-
*
|
|
45
|
+
* Codex-specific loopback wrapper. Stays CLI-side because this flow pairs it
|
|
46
|
+
* with {@link openBrowser}, which is terminal-only.
|
|
129
47
|
*/
|
|
130
|
-
export declare function
|
|
131
|
-
/** Parse a pasted authorization code or full redirect URL into { code, state }. */
|
|
132
|
-
export declare function parseAuthorizationInput(input: string): {
|
|
133
|
-
code?: string | undefined;
|
|
134
|
-
state?: string | undefined;
|
|
135
|
-
};
|
|
48
|
+
export declare function startLoopbackServer(expectedState: string, signal?: AbortSignal): Promise<LoopbackServer>;
|
|
136
49
|
export interface CodexLoginOptions {
|
|
137
50
|
/** Storage provider id. Defaults to the canonical `openai-codex`. */
|
|
138
51
|
providerId?: string;
|
|
@@ -22,6 +22,7 @@ import type { Config, MemoryPort, ModelsRegistry, ModeStore, SessionStore, Sessi
|
|
|
22
22
|
import type { MCPRegistry } from '@wrongstack/mcp';
|
|
23
23
|
import type { TerminalRenderer } from '../renderer.js';
|
|
24
24
|
import type { AutonomyMode } from '../services/autonomy-mode.js';
|
|
25
|
+
import type { CliWebUIOptions } from '../webui-server-options.js';
|
|
25
26
|
export interface WebUIDispatchContext {
|
|
26
27
|
agent: Agent;
|
|
27
28
|
events: EventBus;
|
|
@@ -96,6 +97,8 @@ export interface WebUIDispatchContext {
|
|
|
96
97
|
error?: string | undefined;
|
|
97
98
|
}) => void | Promise<void>) | undefined;
|
|
98
99
|
}) => Promise<string>) | undefined;
|
|
100
|
+
/** Live fleet budget for WebUI concurrency/spawn gauges (issue #323). */
|
|
101
|
+
getFleetBudget?: CliWebUIOptions['getFleetBudget'];
|
|
99
102
|
}
|
|
100
103
|
/**
|
|
101
104
|
* Run the WebUI server and block until it shuts down.
|
|
@@ -2,6 +2,9 @@
|
|
|
2
2
|
// src/plugin-management.ts
|
|
3
3
|
import * as fs from "node:fs/promises";
|
|
4
4
|
import { atomicWrite } from "@wrongstack/core/utils";
|
|
5
|
+
import {
|
|
6
|
+
resolvePluginEnablement
|
|
7
|
+
} from "@wrongstack/core/plugin";
|
|
5
8
|
import {
|
|
6
9
|
PLUGIN_AUDIT_ENTRIES
|
|
7
10
|
} from "@wrongstack/plugins/plugin-audit-catalog";
|
|
@@ -311,6 +314,7 @@ function renderPluginAuditReport(config) {
|
|
|
311
314
|
const lines = [
|
|
312
315
|
"Plugin audit report:",
|
|
313
316
|
" State shows the effective boot state. Default-active plugins run unless disabled in config.",
|
|
317
|
+
" Source: config = plugins[] entry, ext = extensions.<name>.enabled, feature = features.plugins.",
|
|
314
318
|
" Built-in audit rows are toggleable unless a future row explicitly marks itself locked.",
|
|
315
319
|
"",
|
|
316
320
|
" Built-in audit entries:"
|
|
@@ -359,19 +363,22 @@ function pluginMatchesToggleSpec(p, spec) {
|
|
|
359
363
|
if (spec === "telegram") return name === "telegram" || name === "@wrongstack/telegram";
|
|
360
364
|
return name === spec;
|
|
361
365
|
}
|
|
366
|
+
var AUDIT_STATE_SOURCE_LABEL = {
|
|
367
|
+
"feature-flag": "feature",
|
|
368
|
+
"plugin-entry": "config",
|
|
369
|
+
extension: "ext",
|
|
370
|
+
default: "default"
|
|
371
|
+
};
|
|
362
372
|
function effectiveAuditState(config, entry) {
|
|
363
|
-
const
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
source: "config"
|
|
370
|
-
};
|
|
371
|
-
}
|
|
373
|
+
const { enabled, source } = resolvePluginEnablement({
|
|
374
|
+
name: entry.name,
|
|
375
|
+
defaultState: entry.defaultState,
|
|
376
|
+
config,
|
|
377
|
+
matches: (spec) => pluginMatchesToggleSpec(spec, entry.name)
|
|
378
|
+
});
|
|
372
379
|
return {
|
|
373
|
-
state:
|
|
374
|
-
source:
|
|
380
|
+
state: enabled ? "enabled" : "disabled",
|
|
381
|
+
source: AUDIT_STATE_SOURCE_LABEL[source]
|
|
375
382
|
};
|
|
376
383
|
}
|
|
377
384
|
function lockedReason(entry) {
|
|
@@ -490,4 +497,4 @@ export {
|
|
|
490
497
|
PLUGIN_AUDIT_ENTRIES,
|
|
491
498
|
runPluginManagementCommand
|
|
492
499
|
};
|
|
493
|
-
//# sourceMappingURL=chunk-
|
|
500
|
+
//# sourceMappingURL=chunk-3MWUZMOL.js.map
|
|
@@ -2,26 +2,7 @@
|
|
|
2
2
|
// src/boot/auto-discover-providers.ts
|
|
3
3
|
import * as fs from "node:fs/promises";
|
|
4
4
|
import * as path from "node:path";
|
|
5
|
-
import {
|
|
6
|
-
function resolveKey(cfg) {
|
|
7
|
-
if (Array.isArray(cfg.apiKeys) && cfg.apiKeys.length > 0) {
|
|
8
|
-
const active = cfg.activeKey ? cfg.apiKeys.find((k) => k.label === cfg.activeKey) : void 0;
|
|
9
|
-
return (active ?? cfg.apiKeys[0])?.apiKey;
|
|
10
|
-
}
|
|
11
|
-
return cfg.apiKey && cfg.apiKey.length > 0 ? cfg.apiKey : void 0;
|
|
12
|
-
}
|
|
13
|
-
function eligibleProviders(config) {
|
|
14
|
-
const out = [];
|
|
15
|
-
for (const [id, cfg] of Object.entries(config.providers ?? {})) {
|
|
16
|
-
const preset = COMPATIBLE_PRESETS[id];
|
|
17
|
-
const enabled = cfg.autoDiscoverModels ?? preset?.autoDiscover ?? false;
|
|
18
|
-
if (!enabled) continue;
|
|
19
|
-
const baseUrl = cfg.baseUrl ?? preset?.defaultBaseUrl;
|
|
20
|
-
if (!baseUrl) continue;
|
|
21
|
-
out.push({ id, cfg, baseUrl, apiKey: resolveKey(cfg) });
|
|
22
|
-
}
|
|
23
|
-
return out;
|
|
24
|
-
}
|
|
5
|
+
import { discoverOpenAICompatibleModels, resolveDiscoveryTargets } from "@wrongstack/providers";
|
|
25
6
|
async function readCache(file) {
|
|
26
7
|
try {
|
|
27
8
|
return JSON.parse(await fs.readFile(file, "utf8"));
|
|
@@ -30,14 +11,13 @@ async function readCache(file) {
|
|
|
30
11
|
}
|
|
31
12
|
}
|
|
32
13
|
async function discoverAndMergeProviders(opts) {
|
|
33
|
-
const targets =
|
|
14
|
+
const targets = resolveDiscoveryTargets(opts.config);
|
|
34
15
|
if (targets.length === 0) return;
|
|
35
16
|
const cacheFile = path.join(opts.cacheDir, "discovered-models-cache.json");
|
|
36
17
|
const cache = await readCache(cacheFile);
|
|
37
18
|
let cacheDirty = false;
|
|
38
19
|
await Promise.all(
|
|
39
|
-
targets.map(async ({ id, cfg, baseUrl, apiKey }) => {
|
|
40
|
-
const cacheKey = `${id}\0${baseUrl}`;
|
|
20
|
+
targets.map(async ({ id, cfg, baseUrl, apiKey, cacheKey }) => {
|
|
41
21
|
const provider = await discoverOpenAICompatibleModels(id, {
|
|
42
22
|
baseUrl,
|
|
43
23
|
apiKey,
|
|
@@ -78,4 +58,4 @@ async function discoverAndMergeProviders(opts) {
|
|
|
78
58
|
export {
|
|
79
59
|
discoverAndMergeProviders
|
|
80
60
|
};
|
|
81
|
-
//# sourceMappingURL=chunk-
|
|
61
|
+
//# sourceMappingURL=chunk-4GVH7V3S.js.map
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import {
|
|
2
2
|
PLUGIN_AUDIT_ENTRIES
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-3MWUZMOL.js";
|
|
4
4
|
import {
|
|
5
5
|
patchConfig
|
|
6
6
|
} from "./chunk-TYO2OVAD.js";
|
|
7
7
|
|
|
8
8
|
// src/wiring/plugins.ts
|
|
9
9
|
import { join } from "node:path";
|
|
10
|
-
import { loadPlugins, resolvePluginConfig } from "@wrongstack/core/plugin";
|
|
10
|
+
import { loadPlugins, resolvePluginConfig, resolvePluginEnablement } from "@wrongstack/core/plugin";
|
|
11
11
|
import { OFFICIAL_PLUGIN_FACTORIES } from "@wrongstack/plugins/factories";
|
|
12
12
|
|
|
13
13
|
// src/plugin-api-factory.ts
|
|
@@ -112,30 +112,25 @@ async function setupPlugins(params) {
|
|
|
112
112
|
hookRegistry
|
|
113
113
|
} = params;
|
|
114
114
|
const builtinPlugins = [];
|
|
115
|
-
const disabledBuiltins = new Set(
|
|
116
|
-
(config.plugins ?? []).filter(
|
|
117
|
-
(p) => typeof p === "object" && p.enabled === false
|
|
118
|
-
).flatMap((p) => {
|
|
119
|
-
const builtinName = builtinPluginNameFromSpec(p.name);
|
|
120
|
-
return builtinName && builtinName !== p.name ? [p.name, builtinName] : [p.name];
|
|
121
|
-
})
|
|
122
|
-
);
|
|
123
115
|
if (paths && config.features?.plugins !== false) {
|
|
124
116
|
for (const factory of BUILTIN_PLUGIN_FACTORIES) {
|
|
125
117
|
try {
|
|
126
118
|
const plugin = await factory();
|
|
127
119
|
if (!plugin) continue;
|
|
128
120
|
const auditEntry = PLUGIN_AUDIT_ENTRIES.find((entry) => entry.name === plugin.name);
|
|
129
|
-
const
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
121
|
+
const { enabled, source } = resolvePluginEnablement({
|
|
122
|
+
name: plugin.name,
|
|
123
|
+
aliases: plugin.configAliases,
|
|
124
|
+
// Built-ins outside the audit catalog (prompts, sync, skills, …)
|
|
125
|
+
// are infrastructure — they run unless explicitly turned off.
|
|
126
|
+
defaultState: auditEntry?.defaultState ?? "active",
|
|
127
|
+
config,
|
|
128
|
+
matches: (spec) => (builtinPluginNameFromSpec(spec) ?? spec) === plugin.name
|
|
133
129
|
});
|
|
134
|
-
if (
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
log.info(`[setupPlugins] built-in plugin "${plugin.name}" disabled by config`);
|
|
130
|
+
if (!enabled) {
|
|
131
|
+
if (source !== "default") {
|
|
132
|
+
log.info(`[setupPlugins] built-in plugin "${plugin.name}" disabled by ${source}`);
|
|
133
|
+
}
|
|
139
134
|
continue;
|
|
140
135
|
}
|
|
141
136
|
if (warnIfDeprecatedPluginName(plugin.name, log)) continue;
|
|
@@ -255,4 +250,4 @@ export {
|
|
|
255
250
|
BUILTIN_PLUGIN_FACTORIES,
|
|
256
251
|
setupPlugins
|
|
257
252
|
};
|
|
258
|
-
//# sourceMappingURL=chunk-
|
|
253
|
+
//# sourceMappingURL=chunk-4WJKVQJY.js.map
|