@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.
Files changed (195) hide show
  1. package/data/providers.json +44 -0
  2. package/dist/{acp-INCNOH42.js → acp-LI665LO2.js} +18 -7
  3. package/dist/arg-parser.d.ts +1 -0
  4. package/dist/ascii-mode-SG4PRNLP.js +7 -0
  5. package/dist/{auth-YXK3EDUL.js → auth-TE55JF4Z.js} +68 -22
  6. package/dist/auth-menu/direct.d.ts +1 -0
  7. package/dist/auth-menu/local.d.ts +2 -0
  8. package/dist/auth-menu/oauth-menu.d.ts +3 -1
  9. package/dist/auth-menu/panel-service.d.ts +20 -0
  10. package/dist/{bench-YBU6BVQP.js → bench-GTLPM22B.js} +2 -2
  11. package/dist/boot/append-system-prompt.d.ts +10 -0
  12. package/dist/boot/ascii-mode.d.ts +12 -0
  13. package/dist/boot/config-backup-recovery.d.ts +2 -1
  14. package/dist/boot/container-wiring.d.ts +4 -2
  15. package/dist/boot/dispatch-singleshot.d.ts +4 -1
  16. package/dist/boot/dispatch-webui.d.ts +11 -0
  17. package/dist/boot/mcp-config-flag.d.ts +22 -0
  18. package/dist/boot/piped-stdin.d.ts +40 -0
  19. package/dist/boot/restricted-mode.d.ts +15 -0
  20. package/dist/boot/safe-mode.d.ts +30 -0
  21. package/dist/boot/short-circuit-desktop.d.ts +1 -0
  22. package/dist/boot/single-shot-budget.d.ts +30 -0
  23. package/dist/boot/stream-json.d.ts +36 -0
  24. package/dist/boot/structured-output.d.ts +16 -0
  25. package/dist/boot/system-prompt-builder.d.ts +2 -0
  26. package/dist/boot/tool-restriction-flags.d.ts +36 -0
  27. package/dist/boot/tui-project-picker-callback.d.ts +1 -1
  28. package/dist/boot/tui-settings-adapter.d.ts +15 -2
  29. package/dist/boot/worktree-sessions.d.ts +21 -0
  30. package/dist/{boot-auto-thin-MANHOYHE.js → boot-auto-thin-6Q56FY3F.js} +3 -2
  31. package/dist/boot-provider-selection.d.ts +67 -0
  32. package/dist/boot.d.ts +1 -38
  33. package/dist/{chunk-JY52HWL6.js → chunk-2EBVTYJR.js} +2 -2
  34. package/dist/{chunk-RDHFXOJM.js → chunk-2ERX3RPN.js} +112 -65
  35. package/dist/chunk-4TVYGG6G.js +62 -0
  36. package/dist/chunk-5JYDKG5B.js +154 -0
  37. package/dist/{chunk-KEPABQYT.js → chunk-5SEYGOCH.js} +8 -82
  38. package/dist/{chunk-3VXYY5JC.js → chunk-5UZBUV2H.js} +3 -19
  39. package/dist/chunk-BBHWW6LR.js +549 -0
  40. package/dist/chunk-BEHGRNOQ.js +58 -0
  41. package/dist/chunk-CZTXF6HY.js +140 -0
  42. package/dist/{chunk-JX6KL7OF.js → chunk-EPR42SWM.js} +39 -8
  43. package/dist/chunk-F5DCFAKI.js +36 -0
  44. package/dist/chunk-HLSHFXTO.js +97 -0
  45. package/dist/{chunk-CJTBLTS4.js → chunk-KJS5543T.js} +4 -3
  46. package/dist/{chunk-DE7BZDNK.js → chunk-KOEO4CJG.js} +27 -4
  47. package/dist/{chunk-SIS37L3W.js → chunk-L2RVEQWO.js} +211 -193
  48. package/dist/chunk-LBPLTTZ6.js +105 -0
  49. package/dist/chunk-LDCGZJTC.js +46 -0
  50. package/dist/chunk-LKPEBZBE.js +143 -0
  51. package/dist/chunk-LUMETJFO.js +171 -0
  52. package/dist/{chunk-KK2LB3ZS.js → chunk-OAVBM55Q.js} +9 -5
  53. package/dist/chunk-PZQBGUVZ.js +18 -0
  54. package/dist/{chunk-C3Z4N6A6.js → chunk-Q4INH2DG.js} +51 -3
  55. package/dist/chunk-R4QGL6GB.js +10 -0
  56. package/dist/{chunk-YLQEGYV4.js → chunk-RZ4ZDRYA.js} +14 -4
  57. package/dist/chunk-S4FFHDJG.js +93 -0
  58. package/dist/chunk-SFBFYIOW.js +271 -0
  59. package/dist/{chunk-RMQNCHGO.js → chunk-TI7KLHYX.js} +136 -11
  60. package/dist/{chunk-2ENZU66X.js → chunk-WQV2NP57.js} +5 -5
  61. package/dist/{chunk-B4JLSXZB.js → chunk-WSTVGC2C.js} +73 -45
  62. package/dist/chunk-X756ZS72.js +329 -0
  63. package/dist/{chunk-XJ7K67PP.js → chunk-YHYINL47.js} +63 -24
  64. package/dist/{chunk-2VMJ3E5Z.js → chunk-YTEOAWOJ.js} +6 -2
  65. package/dist/{chunk-GPPRNAKW.js → chunk-ZMX5HRLI.js} +2 -2
  66. package/dist/{cli-context-33F74CSZ.js → cli-context-UVGAN3NO.js} +496 -384
  67. package/dist/cli-entry-point.d.ts +2 -0
  68. package/dist/{cli-main-FNGMKPBA.js → cli-main-TN3KZ2P6.js} +3561 -2724
  69. package/dist/cli-update-notice.d.ts +2 -1
  70. package/dist/config-doctor.d.ts +10 -2
  71. package/dist/{config-transfer-2YF3CRTN.js → config-transfer-RUWLDCNK.js} +34 -13
  72. package/dist/{diag-doctor-ANPRUYFM.js → diag-doctor-BIZAFIAT.js} +2 -2
  73. package/dist/execute-deps.d.ts +2 -1
  74. package/dist/{execution-A6WJLSOC.js → execution-7QIP6GRY.js} +2384 -2055
  75. package/dist/fleet/host-types.d.ts +3 -1
  76. package/dist/goal-commands.d.ts +47 -0
  77. package/dist/goal-host.d.ts +1 -14
  78. package/dist/{hq-XQWQTRDA.js → hq-GLZ7QESM.js} +277 -261
  79. package/dist/hq-command-controller.d.ts +1 -1
  80. package/dist/{hq-server-IIBZQZU4.js → hq-server-YTKDVQPY.js} +2 -2
  81. package/dist/{hq-service-L5INQFM4.js → hq-service-BMMJAHRT.js} +11 -4
  82. package/dist/import-claude-code-32PCSIQI.js +236 -0
  83. package/dist/index.d.ts +1 -1
  84. package/dist/index.js +19 -10
  85. package/dist/kanban-supervisor-67ECABTD.js +7 -0
  86. package/dist/live-settings-input.d.ts +7 -0
  87. package/dist/{mailbox-serve-3GFOK2I7.js → mailbox-serve-NW5VZG7R.js} +3 -3
  88. package/dist/{mcp-DC5WSBOO.js → mcp-LBS45HWZ.js} +4 -4
  89. package/dist/modeldiag-36VODVIH.js +828 -0
  90. package/dist/{per-subcommand-help-DHTYU524.js → per-subcommand-help-QDAQASPZ.js} +3 -3
  91. package/dist/permission-prompt-mirror.d.ts +1 -1
  92. package/dist/permission-prompt.d.ts +16 -2
  93. package/dist/permission-rules-view.d.ts +18 -0
  94. package/dist/{permissions-CFDLXETM.js → permissions-PL27UHYD.js} +67 -45
  95. package/dist/plugin-config.d.ts +12 -0
  96. package/dist/plugin-management-types.d.ts +31 -0
  97. package/dist/plugin-management.d.ts +2 -30
  98. package/dist/plugin-package-install.d.ts +3 -0
  99. package/dist/{plugin-usage-M6KET4OZ.js → plugin-usage-CIGOOTX3.js} +6 -5
  100. package/dist/{plugins-WJLW6ULV.js → plugins-HQTXUD6A.js} +6 -3
  101. package/dist/preflight.d.ts +1 -1
  102. package/dist/{projects-LMNAGGEU.js → projects-T4CZCA25.js} +3 -6
  103. package/dist/provider-config-utils.d.ts +1 -6
  104. package/dist/provider-helpers.d.ts +7 -11
  105. package/dist/{providers-models-LFNZ5WI7.js → providers-models-5Z2PJTEW.js} +44 -34
  106. package/dist/release-asset-download.d.ts +13 -0
  107. package/dist/release-attestation.d.ts +28 -0
  108. package/dist/remote/remote-session.d.ts +64 -0
  109. package/dist/remote/remote-target.d.ts +69 -0
  110. package/dist/remote-O5WXHLWV.js +561 -0
  111. package/dist/{replay-Z3FTJEMM.js → replay-DEI566CW.js} +2 -2
  112. package/dist/services/commit-message.d.ts +2 -1
  113. package/dist/services/dispatch-classifier.d.ts +39 -5
  114. package/dist/session-move-P2EC2COA.js +44 -0
  115. package/dist/session-move.d.ts +20 -0
  116. package/dist/session-stats.d.ts +10 -0
  117. package/dist/{sessions-config-UL45XKX7.js → sessions-config-SXTTLNXA.js} +47 -9
  118. package/dist/settings-menu.d.ts +2 -0
  119. package/dist/short-circuit-flags-74Y5N6CF.js +10 -0
  120. package/dist/{simpleui-dist-CXSIDAXZ.js → simpleui-dist-7BQISSEP.js} +7 -3
  121. package/dist/skill-suggest-L2EVWB6R.js +290 -0
  122. package/dist/slash-commands/command-context.d.ts +15 -5
  123. package/dist/slash-commands/effort.d.ts +1 -1
  124. package/dist/slash-commands/fallback.d.ts +1 -1
  125. package/dist/slash-commands/gitid.d.ts +1 -1
  126. package/dist/slash-commands/goal-refiner.d.ts +4 -49
  127. package/dist/slash-commands/jev.d.ts +4 -0
  128. package/dist/slash-commands/mcp.d.ts +2 -1
  129. package/dist/slash-commands/openai-quota.d.ts +15 -0
  130. package/dist/slash-commands/permissions.d.ts +4 -0
  131. package/dist/slash-commands/sdd-task-mutations.d.ts +4 -0
  132. package/dist/slash-commands/settings-context-mutations.d.ts +5 -0
  133. package/dist/slash-commands/settings-keys.d.ts +2 -0
  134. package/dist/slash-commands/settings-limits-mutations.d.ts +12 -0
  135. package/dist/slash-commands/settings-reset.d.ts +6 -0
  136. package/dist/standalone-auto-update-TOTRGCSA.js +249 -0
  137. package/dist/standalone-auto-update.d.ts +65 -0
  138. package/dist/standalone-update-LZO3MNLH.js +24 -0
  139. package/dist/standalone-update.d.ts +55 -0
  140. package/dist/subcommands/handlers/hq-alerts.d.ts +3 -0
  141. package/dist/subcommands/handlers/hq-audit.d.ts +46 -0
  142. package/dist/subcommands/handlers/hq-data-dir.d.ts +13 -0
  143. package/dist/subcommands/handlers/import-claude-code.d.ts +42 -0
  144. package/dist/subcommands/handlers/permissions.d.ts +9 -3
  145. package/dist/subcommands/handlers/remote.d.ts +6 -0
  146. package/dist/subcommands/handlers/skill-suggest.d.ts +21 -0
  147. package/dist/subcommands/handlers/typesafe-brain-replay.d.ts +26 -0
  148. package/dist/subcommands/handlers/typesafe-judgment-check.d.ts +3 -0
  149. package/dist/subcommands/handlers/typesafe-topic-replay.d.ts +19 -0
  150. package/dist/subcommands/handlers/typesafe-triage-replay.d.ts +18 -0
  151. package/dist/subcommands/handlers/typesafe.d.ts +23 -0
  152. package/dist/subcommands/handlers/version-help.d.ts +5 -0
  153. package/dist/{subcommands-XSLXMIDP.js → subcommands-Q6ORSB2E.js} +2 -2
  154. package/dist/tui-resume-callback.d.ts +18 -0
  155. package/dist/typesafe-U7YB2RRV.js +316 -0
  156. package/dist/typesafe-brain-replay-C5276FVR.js +222 -0
  157. package/dist/typesafe-judgment-check-GGYYV5UF.js +29 -0
  158. package/dist/typesafe-topic-replay-ZILIU3WS.js +234 -0
  159. package/dist/typesafe-triage-replay-FGAW7QM7.js +215 -0
  160. package/dist/{update-5DPB4YD4.js → update-TDZX4IL2.js} +4 -3
  161. package/dist/{update-check-BS3DHTSI.js → update-check-J5ZVKS73.js} +3 -2
  162. package/dist/update-check.d.ts +1 -1
  163. package/dist/version-JB2UAV2A.js +11 -0
  164. package/dist/version-help-XJJQ7YSH.js +10 -0
  165. package/dist/version.d.ts +3 -2
  166. package/dist/webui-client-observability.d.ts +7 -0
  167. package/dist/webui-server/route-contexts.d.ts +1 -1
  168. package/dist/webui-server/session-start-payload.d.ts +5 -1
  169. package/dist/{webui-server-MRPGTTKL.js → webui-server-YTHLRFD2.js} +577 -370
  170. package/dist/webui-server-lifecycle.d.ts +57 -0
  171. package/dist/webui-server-options.d.ts +11 -0
  172. package/dist/webui-server.d.ts +1 -1
  173. package/dist/wiring/brain-and-orchestration.d.ts +3 -1
  174. package/dist/wiring/cli-prompt-and-tools-setup.d.ts +9 -0
  175. package/dist/wiring/cli-slash-commands-setup.d.ts +1 -0
  176. package/dist/wiring/domain-glossary.d.ts +5 -4
  177. package/dist/wiring/lifecycle-plugins.d.ts +4 -2
  178. package/dist/wiring/metrics.d.ts +9 -1
  179. package/dist/wiring/pipeline.d.ts +2 -7
  180. package/dist/wiring/plugins.d.ts +4 -1
  181. package/dist/wiring/provider-persisters.d.ts +24 -0
  182. package/dist/wiring/provider-runtime.d.ts +9 -1
  183. package/dist/wiring/provider-status.d.ts +1 -0
  184. package/dist/wiring/provider-utility-tools.d.ts +3 -1
  185. package/dist/wiring/runtime-dispatch-state.d.ts +3 -1
  186. package/package.json +28 -28
  187. package/dist/chunk-2CZEORLV.js +0 -54
  188. package/dist/chunk-672UXYL3.js +0 -65
  189. package/dist/chunk-6WRKAACA.js +0 -96
  190. package/dist/chunk-DR2OXU46.js +0 -174
  191. package/dist/chunk-JACOMTIH.js +0 -275
  192. package/dist/chunk-XJXDOF63.js +0 -28
  193. package/dist/modeldiag-CJSFHZ3J.js +0 -1356
  194. package/dist/short-circuit-flags-7GQIGMVD.js +0 -10
  195. 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<void>;
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
- import type { ConfigStore, FleetChatVerbosity } from '@wrongstack/core/types';
2
- import { type WstackPaths } from '@wrongstack/core/utils';
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-JACOMTIH.js";
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-MANHOYHE.js.map
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-JY52HWL6.js.map
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-3VXYY5JC.js";
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-DR2OXU46.js";
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
- ` ${color2.bold("s")} Login with provider OAuth
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 baseUrl = opts.baseUrl?.trim() || chosen.defaultBaseUrl;
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[chosen.id];
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
- const p = all[chosen.id] ?? { type: chosen.id };
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[chosen.id] = p;
581
+ all[profileId] = p;
561
582
  },
562
583
  deps.profileConfigPath
563
584
  );
564
585
  } catch (err) {
565
- deps.renderer.writeError(`Failed to save ${chosen.id}: ${err.message}`);
586
+ deps.renderer.writeError(`Failed to save ${profileId}: ${err.message}`);
566
587
  return 1;
567
588
  }
568
589
  const events = decideAuthLocalEvents({
569
- providerId: chosen.id,
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(chosen.id)}/${color3.bold(finalLabel)} \u2192 ${color3.cyan(baseUrl)}
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(chosen.id)} (no key) \u2192 ${color3.cyan(baseUrl)}
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 ${chosen.id} --model ${modelHint} "<task>"
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
- await runOAuthLoginKind(deps, kind);
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
- const { atomicWrite } = await import("@wrongstack/core/utils");
1133
- const fs = await import("node:fs/promises");
1134
- let existing = {};
1135
- try {
1136
- const raw = await fs.readFile(configPath, "utf8");
1137
- existing = JSON.parse(raw);
1138
- } catch {
1139
- }
1140
- const oldCfg = { ...existing };
1141
- existing.provider = provider;
1142
- existing.model = model;
1143
- try {
1144
- await backupCurrent(homeFn, configPath);
1145
- } catch (err) {
1146
- console.warn(
1147
- JSON.stringify({
1148
- level: "warn",
1149
- event: "picker.backup_failed",
1150
- message: toErrorMessage(err),
1151
- timestamp: (/* @__PURE__ */ new Date()).toISOString()
1152
- })
1153
- );
1154
- }
1155
- await atomicWrite(configPath, JSON.stringify(existing, null, 2), { mode: 384 });
1156
- try {
1157
- await appendHistory(
1158
- oldCfg,
1159
- existing,
1160
- `Provider/model changed: ${oldCfg.provider ?? "(none)"} \u2192 ${provider}, ${oldCfg.model ?? "(none)"} \u2192 ${model}`,
1161
- homeFn,
1162
- configPath
1163
- );
1164
- } catch {
1165
- }
1166
- return true;
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 { catalogProviderIdFor, PROVIDER_DEFINITIONS } from "@wrongstack/providers";
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-RDHFXOJM.js.map
1947
+ //# sourceMappingURL=chunk-2ERX3RPN.js.map