@wrongstack/cli 1.0.19 → 1.0.26
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/data/providers.json +44 -0
- package/dist/{acp-INCNOH42.js → acp-LI665LO2.js} +18 -7
- package/dist/arg-parser.d.ts +1 -0
- package/dist/ascii-mode-SG4PRNLP.js +7 -0
- package/dist/{auth-YXK3EDUL.js → auth-TE55JF4Z.js} +68 -22
- package/dist/auth-menu/direct.d.ts +1 -0
- package/dist/auth-menu/local.d.ts +2 -0
- package/dist/auth-menu/oauth-menu.d.ts +3 -1
- package/dist/auth-menu/panel-service.d.ts +20 -0
- package/dist/{bench-YBU6BVQP.js → bench-GTLPM22B.js} +2 -2
- package/dist/boot/append-system-prompt.d.ts +10 -0
- package/dist/boot/ascii-mode.d.ts +12 -0
- package/dist/boot/config-backup-recovery.d.ts +2 -1
- package/dist/boot/container-wiring.d.ts +4 -2
- package/dist/boot/dispatch-singleshot.d.ts +4 -1
- package/dist/boot/dispatch-webui.d.ts +11 -0
- package/dist/boot/mcp-config-flag.d.ts +22 -0
- package/dist/boot/piped-stdin.d.ts +40 -0
- package/dist/boot/restricted-mode.d.ts +15 -0
- package/dist/boot/safe-mode.d.ts +30 -0
- package/dist/boot/short-circuit-desktop.d.ts +1 -0
- package/dist/boot/single-shot-budget.d.ts +30 -0
- package/dist/boot/stream-json.d.ts +36 -0
- package/dist/boot/structured-output.d.ts +16 -0
- package/dist/boot/system-prompt-builder.d.ts +2 -0
- package/dist/boot/tool-restriction-flags.d.ts +36 -0
- package/dist/boot/tui-project-picker-callback.d.ts +1 -1
- package/dist/boot/tui-settings-adapter.d.ts +15 -2
- package/dist/boot/worktree-sessions.d.ts +21 -0
- package/dist/{boot-auto-thin-MANHOYHE.js → boot-auto-thin-6Q56FY3F.js} +3 -2
- package/dist/boot-provider-selection.d.ts +67 -0
- package/dist/boot.d.ts +1 -38
- package/dist/{chunk-JY52HWL6.js → chunk-2EBVTYJR.js} +2 -2
- package/dist/{chunk-RDHFXOJM.js → chunk-2ERX3RPN.js} +112 -65
- package/dist/chunk-4TVYGG6G.js +62 -0
- package/dist/chunk-5JYDKG5B.js +154 -0
- package/dist/{chunk-KEPABQYT.js → chunk-5SEYGOCH.js} +8 -82
- package/dist/{chunk-3VXYY5JC.js → chunk-5UZBUV2H.js} +3 -19
- package/dist/chunk-BBHWW6LR.js +549 -0
- package/dist/chunk-BEHGRNOQ.js +58 -0
- package/dist/chunk-CZTXF6HY.js +140 -0
- package/dist/{chunk-JX6KL7OF.js → chunk-EPR42SWM.js} +39 -8
- package/dist/chunk-F5DCFAKI.js +36 -0
- package/dist/chunk-HLSHFXTO.js +97 -0
- package/dist/{chunk-CJTBLTS4.js → chunk-KJS5543T.js} +4 -3
- package/dist/{chunk-DE7BZDNK.js → chunk-KOEO4CJG.js} +27 -4
- package/dist/{chunk-SIS37L3W.js → chunk-L2RVEQWO.js} +211 -193
- package/dist/chunk-LBPLTTZ6.js +105 -0
- package/dist/chunk-LDCGZJTC.js +46 -0
- package/dist/chunk-LKPEBZBE.js +143 -0
- package/dist/chunk-LUMETJFO.js +171 -0
- package/dist/{chunk-KK2LB3ZS.js → chunk-OAVBM55Q.js} +9 -5
- package/dist/chunk-PZQBGUVZ.js +18 -0
- package/dist/{chunk-C3Z4N6A6.js → chunk-Q4INH2DG.js} +51 -3
- package/dist/chunk-R4QGL6GB.js +10 -0
- package/dist/{chunk-YLQEGYV4.js → chunk-RZ4ZDRYA.js} +14 -4
- package/dist/chunk-S4FFHDJG.js +93 -0
- package/dist/chunk-SFBFYIOW.js +271 -0
- package/dist/{chunk-RMQNCHGO.js → chunk-TI7KLHYX.js} +136 -11
- package/dist/{chunk-2ENZU66X.js → chunk-WQV2NP57.js} +5 -5
- package/dist/{chunk-B4JLSXZB.js → chunk-WSTVGC2C.js} +73 -45
- package/dist/chunk-X756ZS72.js +329 -0
- package/dist/{chunk-XJ7K67PP.js → chunk-YHYINL47.js} +63 -24
- package/dist/{chunk-2VMJ3E5Z.js → chunk-YTEOAWOJ.js} +6 -2
- package/dist/{chunk-GPPRNAKW.js → chunk-ZMX5HRLI.js} +2 -2
- package/dist/{cli-context-33F74CSZ.js → cli-context-UVGAN3NO.js} +496 -384
- package/dist/cli-entry-point.d.ts +2 -0
- package/dist/{cli-main-FNGMKPBA.js → cli-main-TN3KZ2P6.js} +3561 -2724
- package/dist/cli-update-notice.d.ts +2 -1
- package/dist/config-doctor.d.ts +10 -2
- package/dist/{config-transfer-2YF3CRTN.js → config-transfer-RUWLDCNK.js} +34 -13
- package/dist/{diag-doctor-ANPRUYFM.js → diag-doctor-BIZAFIAT.js} +2 -2
- package/dist/execute-deps.d.ts +2 -1
- package/dist/{execution-A6WJLSOC.js → execution-7QIP6GRY.js} +2384 -2055
- package/dist/fleet/host-types.d.ts +3 -1
- package/dist/goal-commands.d.ts +47 -0
- package/dist/goal-host.d.ts +1 -14
- package/dist/{hq-XQWQTRDA.js → hq-GLZ7QESM.js} +277 -261
- package/dist/hq-command-controller.d.ts +1 -1
- package/dist/{hq-server-IIBZQZU4.js → hq-server-YTKDVQPY.js} +2 -2
- package/dist/{hq-service-L5INQFM4.js → hq-service-BMMJAHRT.js} +11 -4
- package/dist/import-claude-code-32PCSIQI.js +236 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.js +19 -10
- package/dist/kanban-supervisor-67ECABTD.js +7 -0
- package/dist/live-settings-input.d.ts +7 -0
- package/dist/{mailbox-serve-3GFOK2I7.js → mailbox-serve-NW5VZG7R.js} +3 -3
- package/dist/{mcp-DC5WSBOO.js → mcp-LBS45HWZ.js} +4 -4
- package/dist/modeldiag-36VODVIH.js +828 -0
- package/dist/{per-subcommand-help-DHTYU524.js → per-subcommand-help-QDAQASPZ.js} +3 -3
- package/dist/permission-prompt-mirror.d.ts +1 -1
- package/dist/permission-prompt.d.ts +16 -2
- package/dist/permission-rules-view.d.ts +18 -0
- package/dist/{permissions-CFDLXETM.js → permissions-PL27UHYD.js} +67 -45
- package/dist/plugin-config.d.ts +12 -0
- package/dist/plugin-management-types.d.ts +31 -0
- package/dist/plugin-management.d.ts +2 -30
- package/dist/plugin-package-install.d.ts +3 -0
- package/dist/{plugin-usage-M6KET4OZ.js → plugin-usage-CIGOOTX3.js} +6 -5
- package/dist/{plugins-WJLW6ULV.js → plugins-HQTXUD6A.js} +6 -3
- package/dist/preflight.d.ts +1 -1
- package/dist/{projects-LMNAGGEU.js → projects-T4CZCA25.js} +3 -6
- package/dist/provider-config-utils.d.ts +1 -6
- package/dist/provider-helpers.d.ts +7 -11
- package/dist/{providers-models-LFNZ5WI7.js → providers-models-5Z2PJTEW.js} +44 -34
- package/dist/release-asset-download.d.ts +13 -0
- package/dist/release-attestation.d.ts +28 -0
- package/dist/remote/remote-session.d.ts +64 -0
- package/dist/remote/remote-target.d.ts +69 -0
- package/dist/remote-O5WXHLWV.js +561 -0
- package/dist/{replay-Z3FTJEMM.js → replay-DEI566CW.js} +2 -2
- package/dist/services/commit-message.d.ts +2 -1
- package/dist/services/dispatch-classifier.d.ts +39 -5
- package/dist/session-move-P2EC2COA.js +44 -0
- package/dist/session-move.d.ts +20 -0
- package/dist/session-stats.d.ts +10 -0
- package/dist/{sessions-config-UL45XKX7.js → sessions-config-SXTTLNXA.js} +47 -9
- package/dist/settings-menu.d.ts +2 -0
- package/dist/short-circuit-flags-74Y5N6CF.js +10 -0
- package/dist/{simpleui-dist-CXSIDAXZ.js → simpleui-dist-7BQISSEP.js} +7 -3
- package/dist/skill-suggest-L2EVWB6R.js +290 -0
- package/dist/slash-commands/command-context.d.ts +15 -5
- package/dist/slash-commands/effort.d.ts +1 -1
- package/dist/slash-commands/fallback.d.ts +1 -1
- package/dist/slash-commands/gitid.d.ts +1 -1
- package/dist/slash-commands/goal-refiner.d.ts +4 -49
- package/dist/slash-commands/jev.d.ts +4 -0
- package/dist/slash-commands/mcp.d.ts +2 -1
- package/dist/slash-commands/openai-quota.d.ts +15 -0
- package/dist/slash-commands/permissions.d.ts +4 -0
- package/dist/slash-commands/sdd-task-mutations.d.ts +4 -0
- package/dist/slash-commands/settings-context-mutations.d.ts +5 -0
- package/dist/slash-commands/settings-keys.d.ts +2 -0
- package/dist/slash-commands/settings-limits-mutations.d.ts +12 -0
- package/dist/slash-commands/settings-reset.d.ts +6 -0
- package/dist/standalone-auto-update-TOTRGCSA.js +249 -0
- package/dist/standalone-auto-update.d.ts +65 -0
- package/dist/standalone-update-LZO3MNLH.js +24 -0
- package/dist/standalone-update.d.ts +55 -0
- package/dist/subcommands/handlers/hq-alerts.d.ts +3 -0
- package/dist/subcommands/handlers/hq-audit.d.ts +46 -0
- package/dist/subcommands/handlers/hq-data-dir.d.ts +13 -0
- package/dist/subcommands/handlers/import-claude-code.d.ts +42 -0
- package/dist/subcommands/handlers/permissions.d.ts +9 -3
- package/dist/subcommands/handlers/remote.d.ts +6 -0
- package/dist/subcommands/handlers/skill-suggest.d.ts +21 -0
- package/dist/subcommands/handlers/typesafe-brain-replay.d.ts +26 -0
- package/dist/subcommands/handlers/typesafe-judgment-check.d.ts +3 -0
- package/dist/subcommands/handlers/typesafe-topic-replay.d.ts +19 -0
- package/dist/subcommands/handlers/typesafe-triage-replay.d.ts +18 -0
- package/dist/subcommands/handlers/typesafe.d.ts +23 -0
- package/dist/subcommands/handlers/version-help.d.ts +5 -0
- package/dist/{subcommands-XSLXMIDP.js → subcommands-Q6ORSB2E.js} +2 -2
- package/dist/tui-resume-callback.d.ts +18 -0
- package/dist/typesafe-U7YB2RRV.js +316 -0
- package/dist/typesafe-brain-replay-C5276FVR.js +222 -0
- package/dist/typesafe-judgment-check-GGYYV5UF.js +29 -0
- package/dist/typesafe-topic-replay-ZILIU3WS.js +234 -0
- package/dist/typesafe-triage-replay-FGAW7QM7.js +215 -0
- package/dist/{update-5DPB4YD4.js → update-TDZX4IL2.js} +4 -3
- package/dist/{update-check-BS3DHTSI.js → update-check-J5ZVKS73.js} +3 -2
- package/dist/update-check.d.ts +1 -1
- package/dist/version-JB2UAV2A.js +11 -0
- package/dist/version-help-XJJQ7YSH.js +10 -0
- package/dist/version.d.ts +3 -2
- package/dist/webui-client-observability.d.ts +7 -0
- package/dist/webui-server/route-contexts.d.ts +1 -1
- package/dist/webui-server/session-start-payload.d.ts +5 -1
- package/dist/{webui-server-MRPGTTKL.js → webui-server-YTHLRFD2.js} +577 -370
- package/dist/webui-server-lifecycle.d.ts +57 -0
- package/dist/webui-server-options.d.ts +11 -0
- package/dist/webui-server.d.ts +1 -1
- package/dist/wiring/brain-and-orchestration.d.ts +3 -1
- package/dist/wiring/cli-prompt-and-tools-setup.d.ts +9 -0
- package/dist/wiring/cli-slash-commands-setup.d.ts +1 -0
- package/dist/wiring/domain-glossary.d.ts +5 -4
- package/dist/wiring/lifecycle-plugins.d.ts +4 -2
- package/dist/wiring/metrics.d.ts +9 -1
- package/dist/wiring/pipeline.d.ts +2 -7
- package/dist/wiring/plugins.d.ts +4 -1
- package/dist/wiring/provider-persisters.d.ts +24 -0
- package/dist/wiring/provider-runtime.d.ts +9 -1
- package/dist/wiring/provider-status.d.ts +1 -0
- package/dist/wiring/provider-utility-tools.d.ts +3 -1
- package/dist/wiring/runtime-dispatch-state.d.ts +3 -1
- package/package.json +28 -28
- package/dist/chunk-2CZEORLV.js +0 -54
- package/dist/chunk-672UXYL3.js +0 -65
- package/dist/chunk-6WRKAACA.js +0 -96
- package/dist/chunk-DR2OXU46.js +0 -174
- package/dist/chunk-JACOMTIH.js +0 -275
- package/dist/chunk-XJXDOF63.js +0 -28
- package/dist/modeldiag-CJSFHZ3J.js +0 -1356
- package/dist/short-circuit-flags-7GQIGMVD.js +0 -10
- package/dist/version-help-WXI42PZ3.js +0 -10
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `--output-format stream-json`: single-shot progress as JSON Lines on stdout.
|
|
3
|
+
*
|
|
4
|
+
* One object per line, each with a `type`:
|
|
5
|
+
* init session id, provider/model, cwd, tool names — first line
|
|
6
|
+
* text_delta streamed answer text (only with --include-partial-messages)
|
|
7
|
+
* assistant one model response: text and tool_use blocks, stop reason, usage
|
|
8
|
+
* tool_result one finished tool call: id, name, ok, duration, output preview
|
|
9
|
+
* result the `--output-json` payload — always the last line
|
|
10
|
+
*
|
|
11
|
+
* Only the leader's own activity is streamed. Subagents report through their
|
|
12
|
+
* `subagent.*` events; the ones that reach the host bus under the plain names
|
|
13
|
+
* carry a non-leader `agentId` and are dropped, so a delegating run does not
|
|
14
|
+
* interleave several conversations on one stream.
|
|
15
|
+
*/
|
|
16
|
+
import type { EventBus } from '@wrongstack/core/kernel';
|
|
17
|
+
export type OutputFormat = 'text' | 'json' | 'stream-json';
|
|
18
|
+
/** `undefined` when the flag is absent. Throws on an unknown format. */
|
|
19
|
+
export declare function parseOutputFormat(value: string | boolean | undefined): OutputFormat | undefined;
|
|
20
|
+
export interface StreamJsonOptions {
|
|
21
|
+
events: Pick<EventBus, 'on'>;
|
|
22
|
+
/** Writes one line (the caller adds nothing; this function appends `\n`). */
|
|
23
|
+
write: (line: string) => void;
|
|
24
|
+
includePartialMessages: boolean;
|
|
25
|
+
}
|
|
26
|
+
/** Subscribe and start writing. Returns the unsubscribe function. */
|
|
27
|
+
export declare function startStreamJson(opts: StreamJsonOptions): () => void;
|
|
28
|
+
/** The first line of the stream. */
|
|
29
|
+
export declare function streamJsonInit(info: {
|
|
30
|
+
sessionId: string | null;
|
|
31
|
+
provider: string | null;
|
|
32
|
+
model: string | null;
|
|
33
|
+
cwd: string;
|
|
34
|
+
tools: readonly string[];
|
|
35
|
+
}): string;
|
|
36
|
+
//# sourceMappingURL=stream-json.d.ts.map
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { JSONSchema } from '@wrongstack/core/types';
|
|
2
|
+
/** Inline JSON when the value starts with `{`, otherwise a path relative to `cwd`. */
|
|
3
|
+
export declare function resolveJsonSchemaFlag(value: string | boolean | undefined, cwd: string): Promise<JSONSchema | undefined>;
|
|
4
|
+
/** Appended to the user's task. The task stays first: it is the instruction. */
|
|
5
|
+
export declare function withSchemaInstruction(query: string, schema: JSONSchema): string;
|
|
6
|
+
export type StructuredCheck = {
|
|
7
|
+
ok: true;
|
|
8
|
+
value: unknown;
|
|
9
|
+
} | {
|
|
10
|
+
ok: false;
|
|
11
|
+
errors: string[];
|
|
12
|
+
};
|
|
13
|
+
/** Parse and validate a final answer. */
|
|
14
|
+
export declare function checkStructuredAnswer(text: string | undefined, schema: JSONSchema): StructuredCheck;
|
|
15
|
+
export declare function repairPrompt(errors: readonly string[]): string;
|
|
16
|
+
//# sourceMappingURL=structured-output.d.ts.map
|
|
@@ -86,6 +86,8 @@ interface BindSystemPromptBuilderDeps {
|
|
|
86
86
|
tokenSavingMode?: TokenSavingTier | boolean | undefined;
|
|
87
87
|
/** `config.systemPrompt.variant` — selects system.md, system-lite.md, or system-pro.md. */
|
|
88
88
|
systemPromptVariant?: SystemInstructionVariant | undefined;
|
|
89
|
+
/** `--append-system-prompt[-file]` text; appended to the host prompt only. */
|
|
90
|
+
appendedInstructions?: string | undefined;
|
|
89
91
|
paths: SystemPromptBuilderPaths;
|
|
90
92
|
/** Project root, for the Atlas brief. Omit to leave the brief out entirely. */
|
|
91
93
|
projectRoot?: string | undefined;
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `--only-tools <names>` and `--disallowed-tools <names>`: a launch-time tool
|
|
3
|
+
* restriction applied to the tool registry (see `ToolRegistry.setSessionRestriction`).
|
|
4
|
+
*
|
|
5
|
+
* `--only-tools` rather than Claude Code's `--tools`: `--tools` is already a
|
|
6
|
+
* boolean of `wstack models add` and the CSV of `wstack mcp serve`, so a value
|
|
7
|
+
* form here would swallow the prompt in `wstack --tools read "task"`.
|
|
8
|
+
*
|
|
9
|
+
* Names are comma- or space-separated; a trailing `*` matches a prefix
|
|
10
|
+
* (`mcp__github__*`). Claude Code's scoped rules (`Bash(git *)`) are refused
|
|
11
|
+
* instead of ignored: dropping a deny rule silently would leave the operator
|
|
12
|
+
* believing a command is blocked when it is not.
|
|
13
|
+
*/
|
|
14
|
+
export interface ToolRestriction {
|
|
15
|
+
only?: string[] | undefined;
|
|
16
|
+
deny: string[];
|
|
17
|
+
/** Set by `--restricted` only (see restricted-mode.ts). */
|
|
18
|
+
denyCapabilities?: readonly string[] | undefined;
|
|
19
|
+
requireDeclaredCapabilities?: boolean | undefined;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* `--allowed-tools <names>`: pre-approve tools (no permission prompt) for this
|
|
23
|
+
* process. Same list syntax and the same refusal of scoped rules — a scoped
|
|
24
|
+
* allow like `Bash(git *)` widened to all of `bash` would approve far more
|
|
25
|
+
* than the operator asked for.
|
|
26
|
+
*/
|
|
27
|
+
export declare function resolveLaunchAllowedTools(flags: Readonly<Record<string, string | boolean>>): string[] | undefined;
|
|
28
|
+
/** `undefined` when neither flag is set. Throws on an unusable value. */
|
|
29
|
+
export declare function resolveToolRestriction(flags: Readonly<Record<string, string | boolean>>): ToolRestriction | undefined;
|
|
30
|
+
/**
|
|
31
|
+
* Names in the restriction that match no registered tool — most likely typos.
|
|
32
|
+
* Globs and MCP-style names (`server__tool`) are skipped: MCP servers
|
|
33
|
+
* register after boot, so their absence here proves nothing.
|
|
34
|
+
*/
|
|
35
|
+
export declare function unknownRestrictedToolNames(restriction: ToolRestriction, isRegistered: (name: string) => boolean): string[];
|
|
36
|
+
//# sourceMappingURL=tool-restriction-flags.d.ts.map
|
|
@@ -26,5 +26,5 @@ export declare function getProjectPickerItems(ctx: ProjectPickerContext): Promis
|
|
|
26
26
|
* per-project session writer, rebuilt system prompt, and no spawned
|
|
27
27
|
* replacement process.
|
|
28
28
|
*/
|
|
29
|
-
export declare function onProjectSelect(ctx: ProjectPickerContext, slug: string, kind: 'project' | 'action'): Promise<
|
|
29
|
+
export declare function onProjectSelect(ctx: ProjectPickerContext, slug: string, kind: 'project' | 'action'): Promise<string | null>;
|
|
30
30
|
//# sourceMappingURL=tui-project-picker-callback.d.ts.map
|
|
@@ -1,9 +1,22 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
/**
|
|
2
|
+
* TUI Settings adapter — extracted from the runTui() options literal.
|
|
3
|
+
*
|
|
4
|
+
* Phase C step 1. The getSettings/saveSettings pair (~337 lines) reads
|
|
5
|
+
* config from the ConfigStore and persists changes to disk. This module
|
|
6
|
+
* owns both functions, receiving its dependencies through a typed context.
|
|
7
|
+
*
|
|
8
|
+
* `getSettings()` maps the full Config into the flat LiveSettingsInput
|
|
9
|
+
* shape the TUI SettingsPicker consumes. `saveSettings()` does the
|
|
10
|
+
* reverse: read → modify → encrypt → atomic-write for every section,
|
|
11
|
+
* then syncs the in-memory store and applies live runtime effects.
|
|
12
|
+
*/
|
|
13
|
+
import type { ConfigStore, FleetChatVerbosity, SecretVault } from '@wrongstack/core/types';
|
|
14
|
+
import type { WstackPaths } from '@wrongstack/core/utils';
|
|
3
15
|
import type { LiveSettingsInput } from '../live-settings-input.js';
|
|
4
16
|
interface SettingsAdapterContext {
|
|
5
17
|
configStore: ConfigStore;
|
|
6
18
|
wpaths: WstackPaths;
|
|
19
|
+
vault: SecretVault;
|
|
7
20
|
fleetStreamController: {
|
|
8
21
|
setMode?: ((mode: FleetChatVerbosity) => void) | undefined;
|
|
9
22
|
} | undefined;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { SessionSummary } from '@wrongstack/core/types';
|
|
2
|
+
import type { GitWorktreeEntry } from '@wrongstack/core/worktree';
|
|
3
|
+
export interface WorktreeRef {
|
|
4
|
+
root: string;
|
|
5
|
+
name: string;
|
|
6
|
+
branch?: string | undefined;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* The other worktree a session belongs to, or undefined when it ran in the
|
|
10
|
+
* current checkout, in a checkout git no longer lists (resuming it here is
|
|
11
|
+
* the only option left), or before checkouts were recorded.
|
|
12
|
+
*/
|
|
13
|
+
export declare function worktreeOfSession(summary: Pick<SessionSummary, 'checkout'>, worktrees: readonly GitWorktreeEntry[]): WorktreeRef | undefined;
|
|
14
|
+
/**
|
|
15
|
+
* Wrap the resume callback: a session that belongs to another worktree
|
|
16
|
+
* (per `lookup`, filled from the last listing) first switches the TUI to that
|
|
17
|
+
* worktree, then resumes there. A failed switch rejects, which the picker
|
|
18
|
+
* shows, and leaves the current project untouched.
|
|
19
|
+
*/
|
|
20
|
+
export declare function withWorktreeSwitch<A extends unknown[], R>(resume: (sessionId: string, ...rest: A) => Promise<R>, lookup: (sessionId: string) => WorktreeRef | undefined, switchProject: (root: string, name: string) => Promise<string | null>): (sessionId: string, ...rest: A) => Promise<R>;
|
|
21
|
+
//# sourceMappingURL=worktree-sessions.d.ts.map
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import {
|
|
2
2
|
persistConfigSetting
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-SFBFYIOW.js";
|
|
4
4
|
import {
|
|
5
5
|
activeProfileConfigPath
|
|
6
6
|
} from "./chunk-YMXXOOFN.js";
|
|
7
|
+
import "./chunk-WSTVGC2C.js";
|
|
7
8
|
|
|
8
9
|
// src/boot/boot-auto-thin.ts
|
|
9
10
|
import {
|
|
@@ -98,4 +99,4 @@ async function runBootAutoThin(deps) {
|
|
|
98
99
|
export {
|
|
99
100
|
runBootAutoThin
|
|
100
101
|
};
|
|
101
|
-
//# sourceMappingURL=boot-auto-thin-
|
|
102
|
+
//# sourceMappingURL=boot-auto-thin-6Q56FY3F.js.map
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import type { Config, ModelsRegistry } from '@wrongstack/core/types';
|
|
2
|
+
import type { ReadlineInputReader } from './input-reader.js';
|
|
3
|
+
import type { TerminalRenderer } from './renderer.js';
|
|
4
|
+
/**
|
|
5
|
+
* Resolve the bundled overlay `providers.json`. It ships at `<pkg>/data/` —
|
|
6
|
+
* a sibling of both `src/` (dev) and `dist/` (published) — so `../data/…`
|
|
7
|
+
* relative to this module resolves in both. Returns undefined if anything
|
|
8
|
+
* about the resolution looks off (the overlay is optional).
|
|
9
|
+
*/
|
|
10
|
+
export declare function resolveBundledOverlayFile(): string | undefined;
|
|
11
|
+
export interface SavedDefaultStatus {
|
|
12
|
+
ok: boolean;
|
|
13
|
+
reason?: string;
|
|
14
|
+
}
|
|
15
|
+
export declare function validateSavedProviderModel(config: Config, modelsRegistry: ModelsRegistry): Promise<SavedDefaultStatus>;
|
|
16
|
+
/**
|
|
17
|
+
* Resolve a usable `{ provider, model }` from saved config when the active
|
|
18
|
+
* pointers are unset — the non-interactive (WebUI / --no-interactive) analogue
|
|
19
|
+
* of the TUI's interactive picker. Mirrors the standalone WebUI's auto-select
|
|
20
|
+
* (packages/webui-server start-webui.ts) so a config whose only entry is a
|
|
21
|
+
* custom provider still boots instead of erroring out. Prefers an already-set
|
|
22
|
+
* `config.provider`, otherwise the first saved provider; the model comes from
|
|
23
|
+
* the provider's saved `models` allowlist, falling back to the catalog's first
|
|
24
|
+
* model. Returns undefined when no provider yields a concrete model.
|
|
25
|
+
*/
|
|
26
|
+
export declare function autoSelectSavedProvider(config: Config, modelsRegistry: ModelsRegistry): Promise<{
|
|
27
|
+
provider: string;
|
|
28
|
+
model: string;
|
|
29
|
+
} | undefined>;
|
|
30
|
+
export declare function resolveBundledSkillsDir(): string | undefined;
|
|
31
|
+
export declare function resolveBundledPromptsDir(): string | undefined;
|
|
32
|
+
/**
|
|
33
|
+
* Determine whether a directory is the user's home directory. Used by the
|
|
34
|
+
* startup guard to refuse launching wstack in `~` — where it would risk
|
|
35
|
+
* creating a `.git` repo at the top of the user's filesystem.
|
|
36
|
+
*
|
|
37
|
+
* Resolves both paths so trailing slashes and relative segments are
|
|
38
|
+
* normalized before the comparison. Case is compared as-is (matches
|
|
39
|
+
* `os.homedir()` and `process.cwd()` output on every platform). Symlinks
|
|
40
|
+
* are NOT followed: the common case (`cwd === os.homedir()` literally) is
|
|
41
|
+
* what this guard targets.
|
|
42
|
+
*
|
|
43
|
+
* Exported for testing — the call site in {@link boot} performs the actual
|
|
44
|
+
* warning + exit.
|
|
45
|
+
*/
|
|
46
|
+
export declare function isHomeDirectory(cwd: string, userHome: string): boolean;
|
|
47
|
+
/**
|
|
48
|
+
* Determine whether the first-run YOLO disclosure notice should be printed
|
|
49
|
+
* to stderr. Exported for testing.
|
|
50
|
+
*
|
|
51
|
+
* @param lastChoices Saved launch preferences from config (undefined = first run)
|
|
52
|
+
* @param yoloPinned Explicit --yolo/--no-yolo flag (undefined = not provided)
|
|
53
|
+
* @param yolo Resolved YOLO state
|
|
54
|
+
*/
|
|
55
|
+
export declare function shouldPrintYoloNotice(lastChoices: unknown, yoloPinned: boolean | undefined, yolo: boolean): boolean;
|
|
56
|
+
/**
|
|
57
|
+
* Check whether the current working directory has a `.git` repository.
|
|
58
|
+
* If not, prompt the user before the path resolver walks up to a parent.
|
|
59
|
+
* When the parent directory contains a `.git`, also inform the user so
|
|
60
|
+
* they know why the project root was resolved to a different directory.
|
|
61
|
+
*/
|
|
62
|
+
export declare function checkGitInCwd(opts: {
|
|
63
|
+
cwd: string;
|
|
64
|
+
renderer: TerminalRenderer;
|
|
65
|
+
reader: ReadlineInputReader;
|
|
66
|
+
}): Promise<void>;
|
|
67
|
+
//# sourceMappingURL=boot-provider-selection.d.ts.map
|
package/dist/boot.d.ts
CHANGED
|
@@ -1,23 +1,10 @@
|
|
|
1
|
+
export { autoSelectSavedProvider, isHomeDirectory, shouldPrintYoloNotice, } from './boot-provider-selection.js';
|
|
1
2
|
import { DefaultLogger } from '@wrongstack/core/infrastructure';
|
|
2
3
|
import type { Config, ModelsRegistry, SecretVault } from '@wrongstack/core/types';
|
|
3
4
|
import { type WstackPaths } from '@wrongstack/core/utils';
|
|
4
5
|
import { ReadlineInputReader } from './input-reader.js';
|
|
5
6
|
import { TerminalRenderer } from './renderer.js';
|
|
6
7
|
import type { UpdateInfo } from './update-check.js';
|
|
7
|
-
/**
|
|
8
|
-
* Resolve a usable `{ provider, model }` from saved config when the active
|
|
9
|
-
* pointers are unset — the non-interactive (WebUI / --no-interactive) analogue
|
|
10
|
-
* of the TUI's interactive picker. Mirrors the standalone WebUI's auto-select
|
|
11
|
-
* (packages/webui-server start-webui.ts) so a config whose only entry is a
|
|
12
|
-
* custom provider still boots instead of erroring out. Prefers an already-set
|
|
13
|
-
* `config.provider`, otherwise the first saved provider; the model comes from
|
|
14
|
-
* the provider's saved `models` allowlist, falling back to the catalog's first
|
|
15
|
-
* model. Returns undefined when no provider yields a concrete model.
|
|
16
|
-
*/
|
|
17
|
-
export declare function autoSelectSavedProvider(config: Config, modelsRegistry: ModelsRegistry): Promise<{
|
|
18
|
-
provider: string;
|
|
19
|
-
model: string;
|
|
20
|
-
} | undefined>;
|
|
21
8
|
export interface BootContext {
|
|
22
9
|
config: Config;
|
|
23
10
|
vault: SecretVault;
|
|
@@ -36,30 +23,6 @@ export interface BootContext {
|
|
|
36
23
|
/** True when running in --webui/--no-interactive mode but provider/model not configured */
|
|
37
24
|
needsSetup?: boolean | undefined;
|
|
38
25
|
}
|
|
39
|
-
/**
|
|
40
|
-
* Determine whether a directory is the user's home directory. Used by the
|
|
41
|
-
* startup guard to refuse launching wstack in `~` — where it would risk
|
|
42
|
-
* creating a `.git` repo at the top of the user's filesystem.
|
|
43
|
-
*
|
|
44
|
-
* Resolves both paths so trailing slashes and relative segments are
|
|
45
|
-
* normalized before the comparison. Case is compared as-is (matches
|
|
46
|
-
* `os.homedir()` and `process.cwd()` output on every platform). Symlinks
|
|
47
|
-
* are NOT followed: the common case (`cwd === os.homedir()` literally) is
|
|
48
|
-
* what this guard targets.
|
|
49
|
-
*
|
|
50
|
-
* Exported for testing — the call site in {@link boot} performs the actual
|
|
51
|
-
* warning + exit.
|
|
52
|
-
*/
|
|
53
|
-
export declare function isHomeDirectory(cwd: string, userHome: string): boolean;
|
|
54
|
-
/**
|
|
55
|
-
* Determine whether the first-run YOLO disclosure notice should be printed
|
|
56
|
-
* to stderr. Exported for testing.
|
|
57
|
-
*
|
|
58
|
-
* @param lastChoices Saved launch preferences from config (undefined = first run)
|
|
59
|
-
* @param yoloPinned Explicit --yolo/--no-yolo flag (undefined = not provided)
|
|
60
|
-
* @param yolo Resolved YOLO state
|
|
61
|
-
*/
|
|
62
|
-
export declare function shouldPrintYoloNotice(lastChoices: unknown, yoloPinned: boolean | undefined, yolo: boolean): boolean;
|
|
63
26
|
/**
|
|
64
27
|
* Boot the CLI: parse args, load config, handle subcommand dispatch
|
|
65
28
|
* (early exit), run interactive prompts (project check, provider picker,
|
|
@@ -246,7 +246,7 @@ async function dispatch(controller, commandId, type, payload) {
|
|
|
246
246
|
}
|
|
247
247
|
const toolUseId = typeof payload["toolUseId"] === "string" ? payload["toolUseId"] : "";
|
|
248
248
|
const decision = payload["decision"];
|
|
249
|
-
if (toolUseId.length === 0 || decision !== "yes" && decision !== "no" && decision !== "always" && decision !== "deny") {
|
|
249
|
+
if (toolUseId.length === 0 || decision !== "yes" && decision !== "no" && decision !== "always" && decision !== "always-exact" && decision !== "always-command" && decision !== "always-tool" && decision !== "deny") {
|
|
250
250
|
return { commandId, status: "rejected", message: "malformed approve command" };
|
|
251
251
|
}
|
|
252
252
|
const applied = resolveApproval(toolUseId, decision, sessionId);
|
|
@@ -320,4 +320,4 @@ export {
|
|
|
320
320
|
createProjectKanbanAssignHandler,
|
|
321
321
|
createHqCommandDispatcher
|
|
322
322
|
};
|
|
323
|
-
//# sourceMappingURL=chunk-
|
|
323
|
+
//# sourceMappingURL=chunk-2EBVTYJR.js.map
|
|
@@ -1,15 +1,8 @@
|
|
|
1
|
-
import {
|
|
2
|
-
appendHistory,
|
|
3
|
-
backupCurrent
|
|
4
|
-
} from "./chunk-B4JLSXZB.js";
|
|
5
1
|
import {
|
|
6
2
|
hasApiKey,
|
|
7
3
|
isKeylessLocalProvider,
|
|
8
4
|
visibleModelIds
|
|
9
|
-
} from "./chunk-
|
|
10
|
-
import {
|
|
11
|
-
openBrowser
|
|
12
|
-
} from "./chunk-DAKVBMD4.js";
|
|
5
|
+
} from "./chunk-5UZBUV2H.js";
|
|
13
6
|
import {
|
|
14
7
|
activeLabel,
|
|
15
8
|
loadConfigProviders,
|
|
@@ -17,8 +10,16 @@ import {
|
|
|
17
10
|
mutateConfigProviders,
|
|
18
11
|
normalizeKeys,
|
|
19
12
|
nowIso,
|
|
13
|
+
resolveActiveApiKey,
|
|
20
14
|
writeKeysBack
|
|
21
|
-
} from "./chunk-
|
|
15
|
+
} from "./chunk-LUMETJFO.js";
|
|
16
|
+
import {
|
|
17
|
+
openBrowser
|
|
18
|
+
} from "./chunk-DAKVBMD4.js";
|
|
19
|
+
import {
|
|
20
|
+
appendHistory,
|
|
21
|
+
backupCurrent
|
|
22
|
+
} from "./chunk-WSTVGC2C.js";
|
|
22
23
|
|
|
23
24
|
// src/auth-menu/auth-menu-audit.ts
|
|
24
25
|
import { appendFileSync } from "node:fs";
|
|
@@ -260,10 +261,12 @@ async function runProviderAuthLogin(deps, strategyId, opts = {}) {
|
|
|
260
261
|
deps.renderer.write(color.dim(" Sign-in cancelled or timed out.\n"));
|
|
261
262
|
return 1;
|
|
262
263
|
}
|
|
264
|
+
controller.signal.throwIfAborted();
|
|
263
265
|
await mutateConfigProviders(
|
|
264
266
|
deps.profileConfigPath,
|
|
265
267
|
deps.vault,
|
|
266
268
|
(providers) => {
|
|
269
|
+
controller.signal.throwIfAborted();
|
|
267
270
|
applyProviderAuthOutcome(providers, outcome, { targetProviderId: opts.providerId });
|
|
268
271
|
},
|
|
269
272
|
deps.profileConfigPath
|
|
@@ -287,6 +290,7 @@ async function runProviderAuthLogin(deps, strategyId, opts = {}) {
|
|
|
287
290
|
// src/auth-menu/local.ts
|
|
288
291
|
import { DefaultSecretScrubber as DefaultSecretScrubber2 } from "@wrongstack/core/security";
|
|
289
292
|
import { color as color3 } from "@wrongstack/core/utils";
|
|
293
|
+
import { authProfileAliasError } from "@wrongstack/providers";
|
|
290
294
|
import { probeLocalLlm } from "@wrongstack/runtime/probe";
|
|
291
295
|
|
|
292
296
|
// src/auth-menu/helpers.ts
|
|
@@ -423,10 +427,8 @@ ${color2.bold("WrongStack")} ${color2.dim("\u2014 API key manager")}
|
|
|
423
427
|
);
|
|
424
428
|
renderer.write(` ${color2.bold("c")} Add a custom provider
|
|
425
429
|
`);
|
|
426
|
-
renderer.write(
|
|
427
|
-
|
|
428
|
-
`
|
|
429
|
-
);
|
|
430
|
+
renderer.write(` ${color2.bold("s")} Login with provider OAuth
|
|
431
|
+
`);
|
|
430
432
|
if (ids.length > 0) {
|
|
431
433
|
renderer.write(
|
|
432
434
|
` ${color2.dim("1-")}${color2.dim(String(ids.length))} ${color2.bold("Manage a provider")}
|
|
@@ -479,10 +481,27 @@ async function runAuthLocal(deps, opts = {}) {
|
|
|
479
481
|
if (!chosen) {
|
|
480
482
|
return 0;
|
|
481
483
|
}
|
|
482
|
-
const
|
|
484
|
+
const profileId = opts.alias?.trim() || chosen.id;
|
|
485
|
+
const aliasError = authProfileAliasError(
|
|
486
|
+
opts.alias !== void 0 ? opts.alias.trim() : profileId
|
|
487
|
+
);
|
|
488
|
+
if (aliasError) {
|
|
489
|
+
deps.renderer.writeError(aliasError);
|
|
490
|
+
return 1;
|
|
491
|
+
}
|
|
492
|
+
const aliasedProfile = opts.alias !== void 0 ? (await loadProviders(deps))[profileId] : void 0;
|
|
493
|
+
if (aliasedProfile && !opts.probeOnly) {
|
|
494
|
+
deps.renderer.writeError(
|
|
495
|
+
`Auth profile "${profileId}" already exists. Choose another alias or manage its keys explicitly.`
|
|
496
|
+
);
|
|
497
|
+
return 1;
|
|
498
|
+
}
|
|
499
|
+
const baseUrl = opts.baseUrl?.trim() || (opts.probeOnly ? aliasedProfile?.baseUrl : void 0) || chosen.defaultBaseUrl;
|
|
483
500
|
let apiKey;
|
|
484
501
|
if (opts.apiKey !== void 0) {
|
|
485
502
|
apiKey = opts.apiKey.trim() || void 0;
|
|
503
|
+
} else if (opts.probeOnly && aliasedProfile) {
|
|
504
|
+
apiKey = resolveActiveApiKey(aliasedProfile);
|
|
486
505
|
} else if (chosen.noAuth) {
|
|
487
506
|
apiKey = void 0;
|
|
488
507
|
} else if (opts.skipKey) {
|
|
@@ -528,7 +547,7 @@ async function runAuthLocal(deps, opts = {}) {
|
|
|
528
547
|
const resolvedModels = resolveModelList(opts.models, probe, scrubber);
|
|
529
548
|
const label = opts.label?.trim() || "default";
|
|
530
549
|
const providers = await loadProviders(deps);
|
|
531
|
-
const existing = providers[
|
|
550
|
+
const existing = providers[profileId];
|
|
532
551
|
const previousModels = existing?.models ? [...existing.models] : existing?.models === void 0 ? void 0 : [...existing.models];
|
|
533
552
|
const usedLabels = new Set(existing ? normalizeKeys(existing).map((k) => k.label) : []);
|
|
534
553
|
let finalLabel = label;
|
|
@@ -543,7 +562,9 @@ async function runAuthLocal(deps, opts = {}) {
|
|
|
543
562
|
deps.profileConfigPath,
|
|
544
563
|
deps.vault,
|
|
545
564
|
(all) => {
|
|
546
|
-
|
|
565
|
+
if (opts.alias !== void 0 && all[profileId])
|
|
566
|
+
throw new Error(`Auth profile "${profileId}" already exists.`);
|
|
567
|
+
const p = all[profileId] ?? { type: chosen.id };
|
|
547
568
|
if (!p.type) p.type = chosen.id;
|
|
548
569
|
if (!p.family) p.family = "openai-compatible";
|
|
549
570
|
if (!p.baseUrl) p.baseUrl = baseUrl;
|
|
@@ -557,16 +578,16 @@ async function runAuthLocal(deps, opts = {}) {
|
|
|
557
578
|
writeKeysBack(p, list);
|
|
558
579
|
if (!p.activeKey) p.activeKey = finalLabel;
|
|
559
580
|
}
|
|
560
|
-
all[
|
|
581
|
+
all[profileId] = p;
|
|
561
582
|
},
|
|
562
583
|
deps.profileConfigPath
|
|
563
584
|
);
|
|
564
585
|
} catch (err) {
|
|
565
|
-
deps.renderer.writeError(`Failed to save ${
|
|
586
|
+
deps.renderer.writeError(`Failed to save ${profileId}: ${err.message}`);
|
|
566
587
|
return 1;
|
|
567
588
|
}
|
|
568
589
|
const events = decideAuthLocalEvents({
|
|
569
|
-
providerId:
|
|
590
|
+
providerId: profileId,
|
|
570
591
|
baseUrl,
|
|
571
592
|
previousModels,
|
|
572
593
|
newModels: resolvedModels,
|
|
@@ -581,19 +602,19 @@ async function runAuthLocal(deps, opts = {}) {
|
|
|
581
602
|
}
|
|
582
603
|
if (apiKey) {
|
|
583
604
|
deps.renderer.write(
|
|
584
|
-
` ${color3.green("\u2713")} Saved ${color3.bold(
|
|
605
|
+
` ${color3.green("\u2713")} Saved ${color3.bold(profileId)}/${color3.bold(finalLabel)} \u2192 ${color3.cyan(baseUrl)}
|
|
585
606
|
`
|
|
586
607
|
);
|
|
587
608
|
} else {
|
|
588
609
|
deps.renderer.write(
|
|
589
|
-
` ${color3.green("\u2713")} Saved ${color3.bold(
|
|
610
|
+
` ${color3.green("\u2713")} Saved ${color3.bold(profileId)} (no key) \u2192 ${color3.cyan(baseUrl)}
|
|
590
611
|
`
|
|
591
612
|
);
|
|
592
613
|
}
|
|
593
614
|
const firstModel = resolvedModels && resolvedModels.length > 0 ? resolvedModels[0] : null;
|
|
594
615
|
const modelHint = firstModel ? color3.cyan(firstModel) : color3.dim("<model-id>");
|
|
595
616
|
deps.renderer.write(
|
|
596
|
-
color3.dim(` Launch: wstack --provider ${
|
|
617
|
+
color3.dim(` Launch: wstack --provider ${profileId} --model ${modelHint} "<task>"
|
|
597
618
|
`)
|
|
598
619
|
);
|
|
599
620
|
return 0;
|
|
@@ -746,11 +767,19 @@ function resolveOAuthKind(choice, opts = {}) {
|
|
|
746
767
|
async function runOAuthLoginChoice(deps, choice, opts = {}) {
|
|
747
768
|
const kind = resolveOAuthKind(choice, { ...opts, deps });
|
|
748
769
|
if (!kind) return false;
|
|
749
|
-
|
|
770
|
+
const sourceId = providerAuthRegistryFor(deps).get(kind)?.providerId ?? kind;
|
|
771
|
+
const profiles = await loadProviders(deps);
|
|
772
|
+
let suggestedAlias = sourceId;
|
|
773
|
+
for (let n = 2; profiles[suggestedAlias]; n++) suggestedAlias = `${sourceId}-${n}`;
|
|
774
|
+
const alias = (await deps.reader.readLine(
|
|
775
|
+
` Auth profile alias [${suggestedAlias}] (existing alias re-authenticates; q cancels): `
|
|
776
|
+
)).trim();
|
|
777
|
+
if (alias.toLowerCase() !== "q")
|
|
778
|
+
await runOAuthLoginKind(deps, kind, { providerId: alias || suggestedAlias });
|
|
750
779
|
return true;
|
|
751
780
|
}
|
|
752
|
-
async function runOAuthLoginKind(deps, kind) {
|
|
753
|
-
return runProviderAuthLogin(deps, kind);
|
|
781
|
+
async function runOAuthLoginKind(deps, kind, opts) {
|
|
782
|
+
return opts ? runProviderAuthLogin(deps, kind, opts) : runProviderAuthLogin(deps, kind);
|
|
754
783
|
}
|
|
755
784
|
async function runOAuthLoginMenu(deps) {
|
|
756
785
|
const entries = providerAuthRegistryFor(deps).list();
|
|
@@ -777,6 +806,7 @@ import {
|
|
|
777
806
|
setRawMode as setRawMode2,
|
|
778
807
|
stripAnsi as stripAnsi2,
|
|
779
808
|
toErrorMessage,
|
|
809
|
+
withFileLock,
|
|
780
810
|
writeOut as writeOut2
|
|
781
811
|
} from "@wrongstack/core/utils";
|
|
782
812
|
|
|
@@ -1053,6 +1083,7 @@ var PROVIDER_FAMILY_PREFERRED_ORDER = [
|
|
|
1053
1083
|
"openai-codex",
|
|
1054
1084
|
"github-copilot",
|
|
1055
1085
|
"google",
|
|
1086
|
+
"google-antigravity",
|
|
1056
1087
|
"openai-compatible"
|
|
1057
1088
|
];
|
|
1058
1089
|
function orderProvidersForDisplay(filtered) {
|
|
@@ -1129,41 +1160,44 @@ function renderLiveProviderList(query, filtered, selectedIdx, savedSet) {
|
|
|
1129
1160
|
}
|
|
1130
1161
|
async function saveToGlobalConfig(configPath, provider, model, homeFn = () => process.env.HOME ?? os.homedir()) {
|
|
1131
1162
|
try {
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
await
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1163
|
+
return await withFileLock(configPath, async () => {
|
|
1164
|
+
const { atomicWrite } = await import("@wrongstack/core/utils");
|
|
1165
|
+
const fs = await import("node:fs/promises");
|
|
1166
|
+
let existing = {};
|
|
1167
|
+
try {
|
|
1168
|
+
const raw = await fs.readFile(configPath, "utf8");
|
|
1169
|
+
existing = JSON.parse(raw);
|
|
1170
|
+
} catch (err) {
|
|
1171
|
+
if (err.code !== "ENOENT") throw err;
|
|
1172
|
+
}
|
|
1173
|
+
const oldCfg = { ...existing };
|
|
1174
|
+
existing.provider = provider;
|
|
1175
|
+
existing.model = model;
|
|
1176
|
+
try {
|
|
1177
|
+
await backupCurrent(homeFn, configPath);
|
|
1178
|
+
} catch (err) {
|
|
1179
|
+
console.warn(
|
|
1180
|
+
JSON.stringify({
|
|
1181
|
+
level: "warn",
|
|
1182
|
+
event: "picker.backup_failed",
|
|
1183
|
+
message: toErrorMessage(err),
|
|
1184
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
1185
|
+
})
|
|
1186
|
+
);
|
|
1187
|
+
}
|
|
1188
|
+
await atomicWrite(configPath, JSON.stringify(existing, null, 2), { mode: 384 });
|
|
1189
|
+
try {
|
|
1190
|
+
await appendHistory(
|
|
1191
|
+
oldCfg,
|
|
1192
|
+
existing,
|
|
1193
|
+
`Provider/model changed: ${oldCfg.provider ?? "(none)"} \u2192 ${provider}, ${oldCfg.model ?? "(none)"} \u2192 ${model}`,
|
|
1194
|
+
homeFn,
|
|
1195
|
+
configPath
|
|
1196
|
+
);
|
|
1197
|
+
} catch {
|
|
1198
|
+
}
|
|
1199
|
+
return true;
|
|
1200
|
+
});
|
|
1167
1201
|
} catch (err) {
|
|
1168
1202
|
console.warn(
|
|
1169
1203
|
JSON.stringify({
|
|
@@ -1357,6 +1391,7 @@ ${theme.accent(color7.bold("\u258C WrongStack"))} ${color7.dim("Provider & Mode
|
|
|
1357
1391
|
"openai-codex",
|
|
1358
1392
|
"github-copilot",
|
|
1359
1393
|
"google",
|
|
1394
|
+
"google-antigravity",
|
|
1360
1395
|
"openai-compatible"
|
|
1361
1396
|
];
|
|
1362
1397
|
const familyOrder = [
|
|
@@ -1585,7 +1620,11 @@ async function resolveModelSelection(answer, models, provider, _registry, render
|
|
|
1585
1620
|
|
|
1586
1621
|
// src/auth-menu/add-provider.ts
|
|
1587
1622
|
import { color as color8 } from "@wrongstack/core/utils";
|
|
1588
|
-
import {
|
|
1623
|
+
import {
|
|
1624
|
+
authProfileAliasError as authProfileAliasError2,
|
|
1625
|
+
catalogProviderIdFor,
|
|
1626
|
+
PROVIDER_DEFINITIONS
|
|
1627
|
+
} from "@wrongstack/providers";
|
|
1589
1628
|
|
|
1590
1629
|
// src/provider-id.ts
|
|
1591
1630
|
function nextCustomProviderId(existing) {
|
|
@@ -1640,9 +1679,7 @@ async function addFromCatalog(deps) {
|
|
|
1640
1679
|
${color8.dim("OAuth login options: enter a registered strategy name, or q to quit.")}
|
|
1641
1680
|
`
|
|
1642
1681
|
);
|
|
1643
|
-
const answer = (await deps.reader.readLine(
|
|
1644
|
-
` ${color8.amber("?")} OAuth strategy ${color8.dim("(or q)")}: `
|
|
1645
|
-
)).trim();
|
|
1682
|
+
const answer = (await deps.reader.readLine(` ${color8.amber("?")} OAuth strategy ${color8.dim("(or q)")}: `)).trim();
|
|
1646
1683
|
if (answer && await runOAuthLoginChoice(deps, answer, { allowNumeric: false })) {
|
|
1647
1684
|
return true;
|
|
1648
1685
|
}
|
|
@@ -1678,6 +1715,7 @@ async function addKeyForCatalogProvider(deps, chosen) {
|
|
|
1678
1715
|
const baseUrl = baseRaw || chosen.apiBase;
|
|
1679
1716
|
const providersNow = await loadProviders(deps);
|
|
1680
1717
|
let suggestedAlias = chosen.id;
|
|
1718
|
+
for (let n = 2; providersNow[suggestedAlias]; n++) suggestedAlias = `${chosen.id}-${n}`;
|
|
1681
1719
|
if (family !== chosen.family) {
|
|
1682
1720
|
let candidate = `${chosen.id}-${family}`;
|
|
1683
1721
|
let n = 2;
|
|
@@ -1691,6 +1729,11 @@ async function addKeyForCatalogProvider(deps, chosen) {
|
|
|
1691
1729
|
` ${color8.amber("?")} Save as alias ${color8.dim(`[${suggestedAlias}]`)} ${color8.dim("(used with --provider <alias>)")}: `
|
|
1692
1730
|
)).trim();
|
|
1693
1731
|
const alias = aliasRaw || suggestedAlias;
|
|
1732
|
+
const aliasError = authProfileAliasError2(alias);
|
|
1733
|
+
if (aliasError) {
|
|
1734
|
+
deps.renderer.writeError(aliasError);
|
|
1735
|
+
return false;
|
|
1736
|
+
}
|
|
1694
1737
|
const existing = providersNow[alias];
|
|
1695
1738
|
if (existing) {
|
|
1696
1739
|
const sameFamily = (existing.family ?? chosen.family) === family;
|
|
@@ -1704,6 +1747,10 @@ async function addKeyForCatalogProvider(deps, chosen) {
|
|
|
1704
1747
|
);
|
|
1705
1748
|
return false;
|
|
1706
1749
|
}
|
|
1750
|
+
deps.renderer.writeError(
|
|
1751
|
+
`Auth profile "${alias}" already exists. Choose another alias or manage its keys explicitly.`
|
|
1752
|
+
);
|
|
1753
|
+
return false;
|
|
1707
1754
|
}
|
|
1708
1755
|
return addKeyForProvider(alias, deps, {
|
|
1709
1756
|
type: chosen.id,
|
|
@@ -1897,4 +1944,4 @@ export {
|
|
|
1897
1944
|
addCustomProvider,
|
|
1898
1945
|
addKeyForProvider
|
|
1899
1946
|
};
|
|
1900
|
-
//# sourceMappingURL=chunk-
|
|
1947
|
+
//# sourceMappingURL=chunk-2ERX3RPN.js.map
|