@humwick/server 0.130.3 → 0.130.4

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 (112) hide show
  1. package/docs/openapi.json +103 -1
  2. package/package.json +6 -6
  3. package/public/assets/{MessageBubble-Bq9kr21N.js → MessageBubble-BOkmEvgZ.js} +2 -2
  4. package/public/assets/{PlanGraphPanel-Dqiroy06.js → PlanGraphPanel-BkaDJp0r.js} +2 -2
  5. package/public/assets/{TraceView-DYU962-H.js → TraceView-B99Uu2yT.js} +2 -2
  6. package/public/assets/{VaultDecisionCard-DhPfzioE.js → VaultDecisionCard-DUIfTTFF.js} +2 -2
  7. package/public/assets/{activity-DzCcQTee.js → activity-ZIX0N1El.js} +2 -2
  8. package/public/assets/{agent-lineage-SgDt9i3T.js → agent-lineage-kq9TPYFw.js} +2 -2
  9. package/public/assets/agent-liveness-DSQY1Aa_.js +2 -0
  10. package/public/assets/{agent-name-CcY3Aijy.js → agent-name-C_7F4DFR.js} +2 -2
  11. package/public/assets/{agent-profiles-cxtRBn6O.js → agent-profiles-BNOcrGcY.js} +2 -2
  12. package/public/assets/{agent-project-badge-DGYbIhaI.js → agent-project-badge-B6yAh70a.js} +2 -2
  13. package/public/assets/{agent-tools-DHbftV0N.js → agent-tools-CcrhmOzF.js} +2 -2
  14. package/public/assets/{agent-type-icon-CY113sp-.js → agent-type-icon-CXSLrKiq.js} +2 -2
  15. package/public/assets/{agents-BPzY7IlQ.js → agents-DIZG97_X.js} +2 -2
  16. package/public/assets/{analytics-DENFPv_a.js → analytics-rasmoPjR.js} +2 -2
  17. package/public/assets/{artifact-viewer-KRvSc7sl.js → artifact-viewer-tBpTrEPb.js} +2 -2
  18. package/public/assets/{artifacts-C9gSmL3s.js → artifacts-BNkrynP1.js} +2 -2
  19. package/public/assets/{artifacts-DT-HkI5O.js → artifacts-Bjq-ZyBA.js} +2 -2
  20. package/public/assets/{automation-BsmjQhKD.js → automation-Cx422L3L.js} +2 -2
  21. package/public/assets/{backlog-8NYH_62t.js → backlog-RuFQ8PUu.js} +2 -2
  22. package/public/assets/{busy-health-D3hwvYb4.js → busy-health-BvNQ9g5x.js} +2 -2
  23. package/public/assets/{channels-DCJ5WL7O.js → channels-DNbKAS0I.js} +2 -2
  24. package/public/assets/{chat-DAIl357U.js → chat-Bp3Fx73h.js} +2 -2
  25. package/public/assets/{code-preview-CzrZfr9U.js → code-preview-KIRZA6cz.js} +2 -2
  26. package/public/assets/{connectors-xTxtlyou.js → connectors-k7vO4vvc.js} +2 -2
  27. package/public/assets/{cosmos-BpebFLK2.js → cosmos-BuVoq1aw.js} +2 -2
  28. package/public/assets/{crate-agent-BHvI5wXC.js → crate-agent-irqlt4NH.js} +2 -2
  29. package/public/assets/{dependency-graph-DGT0o3wJ.js → dependency-graph-D_rurNBz.js} +2 -2
  30. package/public/assets/{deploys-hqWOHSHE.js → deploys-yzZqIpxE.js} +2 -2
  31. package/public/assets/{display-CDeH4I8T.js → display-BemJG1f_.js} +2 -2
  32. package/public/assets/{files-BTeGVmTg.js → files-DXWcrxOz.js} +2 -2
  33. package/public/assets/{fleet-DgXtNgCa.js → fleet-TEuOCZXE.js} +2 -2
  34. package/public/assets/{fleet-metrics-BHEt5yc_.js → fleet-metrics-BGoDAFI-.js} +2 -2
  35. package/public/assets/{formatted-body-impl-CAe664Z8.js → formatted-body-impl-BB9eq9nN.js} +2 -2
  36. package/public/assets/{formatted-body-MLtodyPp.js → formatted-body-qy2nTD_1.js} +3 -3
  37. package/public/assets/{host-providers-dialog-mapF4Fj9.js → host-providers-dialog-BGPHxuwT.js} +2 -2
  38. package/public/assets/{index-CqqgOI5R.js → index-BC5XZc0z.js} +5 -5
  39. package/public/assets/{index-MYAIwYTX.css → index-D8Rp9pz2.css} +1 -1
  40. package/public/assets/{insights-DNyf7IzF.js → insights-C-KQG0h-.js} +2 -2
  41. package/public/assets/{integrations-DlYOHq7T.js → integrations-ClPRPyKU.js} +2 -2
  42. package/public/assets/{issue-ref-chip-CeWBNWn7.js → issue-ref-chip-DbH8J9Ak.js} +2 -2
  43. package/public/assets/{log-viewer-Cib8nqdE.js → log-viewer-PH4zVn24.js} +2 -2
  44. package/public/assets/{maintenance-DSn1cPm7.js → maintenance-5lV43uTL.js} +2 -2
  45. package/public/assets/{managed-agents-C3CkM81m.js → managed-agents-BdgU35aX.js} +2 -2
  46. package/public/assets/{markdown-preview-W4VQQPAv.js → markdown-preview-DNT4OUwQ.js} +3 -3
  47. package/public/assets/{markdown-preview-impl-CMsTdhjq.js → markdown-preview-impl-CnCcPy0A.js} +2 -2
  48. package/public/assets/{memory-BV17qtO4.js → memory--GgWH1gH.js} +2 -2
  49. package/public/assets/{messages-Bm_1AqSA.js → messages-CzFl_97O.js} +2 -2
  50. package/public/assets/{orchestrators-Dg-vfP09.js → orchestrators-CVvJVkzv.js} +2 -2
  51. package/public/assets/overview-DsrZvE86.js +2 -0
  52. package/public/assets/{pairs-8o9nuG3V.js → pairs-D2d0d2py.js} +2 -2
  53. package/public/assets/{profile-icon-BsRyBMea.js → profile-icon-_SMuSbYF.js} +2 -2
  54. package/public/assets/{project-profile-instructions-DETKFn_E.js → project-profile-instructions-Apn15y43.js} +2 -2
  55. package/public/assets/{projects-M_m6AHws.js → projects-D3B6kto5.js} +2 -2
  56. package/public/assets/{prompt-settings-C_mNCgeL.js → prompt-settings-DnPB6Ez6.js} +2 -2
  57. package/public/assets/provider-display-bWwiuedV.js +2 -0
  58. package/public/assets/{registry-DDHHHE5N.js → registry-D790cIhN.js} +2 -2
  59. package/public/assets/{run-card-Dt4I4jaP.js → run-card-BCro-Odj.js} +2 -2
  60. package/public/assets/{secrets-BkVwxI5O.js → secrets-CVXvfvbU.js} +2 -2
  61. package/public/assets/{service-access-settings-Crq-6a-B.js → service-access-settings-D3Xxqb9w.js} +2 -2
  62. package/public/assets/{settings-CYcavMFu.js → settings-CoUC7Jci.js} +2 -2
  63. package/public/assets/{shipping-H6gzEeZB.js → shipping-D_Lp9n_J.js} +2 -2
  64. package/public/assets/{stats-BJVeWkpV.js → stats-CXiNjB9S.js} +2 -2
  65. package/public/assets/{status-dot-BcHyw1Vw.js → status-dot-C703YIy1.js} +2 -2
  66. package/public/assets/store-BgDALGIX.js +9 -0
  67. package/public/assets/{tasks-qJjlQPpx.js → tasks-DO0WpJCx.js} +2 -2
  68. package/public/assets/{teams-Cd5Sk1uX.js → teams-FGkdi_tL.js} +2 -2
  69. package/public/assets/{terminal-viewer-CpY5_m7W.js → terminal-viewer-Dh8dSC7e.js} +3 -3
  70. package/public/assets/{terminal-viewer-impl-DI_2llFR.js → terminal-viewer-impl-B5Zriip3.js} +2 -2
  71. package/public/assets/{use-agent-terminal-0yJA_buM.js → use-agent-terminal-CRUVDvLC.js} +2 -2
  72. package/public/assets/{use-decisions-uJXHf34W.js → use-decisions-CoaqRh4l.js} +2 -2
  73. package/public/assets/{use-project-list-CpWl6eHQ.js → use-project-list-X-BgT53X.js} +2 -2
  74. package/public/assets/{use-selectors-BdxBW8mL.js → use-selectors-0X_UZkk-.js} +2 -2
  75. package/public/assets/{user-avatar-3IndfpOc.js → user-avatar-CkLhVBGu.js} +2 -2
  76. package/public/assets/{versioned-prompt-editor-CIVg7XB1.js → versioned-prompt-editor-BkTi7eim.js} +2 -2
  77. package/public/assets/{work-queue-B9rnLwHZ.js → work-queue-DDOLEyKo.js} +2 -2
  78. package/public/assets/{workflow-marker-X8wxyhzC.js → workflow-marker-CzOsB8BM.js} +2 -2
  79. package/public/assets/{workflows-o5YyMFW7.js → workflows-DJilvmRM.js} +2 -2
  80. package/public/assets/{workspaces-CzEGoAng.js → workspaces-CHcfbLR3.js} +2 -2
  81. package/public/cosmos.html +4 -4
  82. package/public/index.html +29 -29
  83. package/runner/plugins/claude/.claude-plugin/plugin.json +1 -1
  84. package/runner/src/adapters/claude-api.ts +1 -1
  85. package/runner/src/provider-setup.ts +2 -2
  86. package/src/auth/login-link.ts +35 -0
  87. package/src/cli/index.ts +7 -1
  88. package/src/cli/init.ts +53 -0
  89. package/src/cli/orchestrator.ts +1 -7
  90. package/src/cli/setup.ts +6 -4
  91. package/src/db/spawn-delegation.ts +2 -1
  92. package/src/db/workflow-execution.ts +3 -3
  93. package/src/dev.ts +4 -13
  94. package/src/init.ts +299 -0
  95. package/src/invite-link.ts +16 -9
  96. package/src/routes/auth.ts +30 -2
  97. package/src/routes/host-providers.ts +18 -0
  98. package/src/routes/index.ts +5 -2
  99. package/src/routes/orchestrator-bootstrap.ts +2 -0
  100. package/src/routes/secrets-backup.ts +2 -3
  101. package/src/routes/secrets-import.ts +2 -3
  102. package/src/routes/secrets-vault.ts +5 -7
  103. package/src/runtime-install.ts +30 -0
  104. package/src/server.ts +4 -4
  105. package/src/services/auth-context.ts +6 -0
  106. package/src/services/provider-api-key.ts +73 -0
  107. package/src/setup.ts +47 -8
  108. package/src/utils.ts +7 -0
  109. package/public/assets/agent-liveness-Bq-s73jW.js +0 -2
  110. package/public/assets/overview-DcYCrvlr.js +0 -2
  111. package/public/assets/provider-display-BEeLXC_D.js +0 -2
  112. package/public/assets/store-DKPDIZBe.js +0 -9
package/src/server.ts CHANGED
@@ -5,7 +5,7 @@ import { relayHeaderConflict, errMessage, reapEphemeralSelf, startArtifactChecko
5
5
  import { authorityDenied } from "./authority-audit";
6
6
  import { openTerminalProxy, sendTerminalProxyFrame, closeTerminalProxy, type TerminalProxySocketData, type TerminalProxySocket } from "./stream-proxy";
7
7
  import { startServerBackgroundJobs } from "./server-background";
8
- import { inviteLinkRedirect } from "./invite-link";
8
+ import { dashboardLinkRedirect } from "./invite-link";
9
9
  import { claudeAppBoundary, CLAUDE_APP_PATH, isClaudeAppPath } from "./claude-app-auth";
10
10
  import { handleClaudeApp } from "./claude-app-gateway";
11
11
  import { handleClaudeAppOAuth } from "./claude-app/oauth-http";
@@ -345,7 +345,7 @@ export function createFetchHandler(
345
345
  // the way a session is obtained. Each handler self-authenticates (login verifies credentials,
346
346
  // refresh validates the refresh token, logout revokes the presented token). Everything else
347
347
  // still flows through the component-token gate below.
348
- const publicAuthPaths = ["/api/auth/providers", "/api/auth/login", "/api/auth/refresh", "/api/auth/logout", "/api/auth/invites/accept"];
348
+ const publicAuthPaths = ["/api/auth/providers", "/api/auth/login", "/api/auth/refresh", "/api/auth/logout", "/api/auth/invites/accept", "/api/auth/login-links/redeem"];
349
349
  if (!isSecretUploadRequest(req, url.pathname, server) && !publicPaths.includes(url.pathname) && !publicAuthPaths.includes(url.pathname)) {
350
350
  const integrationAuth = getIntegrationAuth(req);
351
351
  const componentAuth = getComponentAuth(req);
@@ -380,8 +380,8 @@ export function createFetchHandler(
380
380
  return response;
381
381
  }
382
382
 
383
- const invite = inviteLinkRedirect(url.pathname);
384
- if (invite) return invite;
383
+ const linkRedirect = dashboardLinkRedirect(url.pathname);
384
+ if (linkRedirect) return linkRedirect;
385
385
  // Dashboard — serve static files, rejecting path traversal and directory requests
386
386
  let requested = url.pathname === "/" ? "/index.html" : url.pathname;
387
387
  if (requested.endsWith("/")) requested += "index.html";
@@ -111,6 +111,12 @@ export function authContextFromMcp(auth: {
111
111
  return { actor: { id: auth.actor, kind: "integration" }, scopes: auth.scopes ?? [] };
112
112
  }
113
113
 
114
+ /** Who an operator vault write is audited under: the caller, or `operator` for the admin token. */
115
+ export function vaultActorOf(req: Request): string {
116
+ const ctx = authContextFromRequest(req);
117
+ return ctx.actor.kind === "system" ? "operator" : ctx.actor.id;
118
+ }
119
+
114
120
  /** Address for human attribution; internal/admin calls retain the seeded operator (#3567). */
115
121
  export function actingUserSinkOf(ctx: AuthContext): string {
116
122
  return canonicalHumanAgentId(userSinkId(actingUserIdOf(ctx) ?? DEFAULT_USER_ID));
@@ -0,0 +1,73 @@
1
+ // T7689 — first-run provider setup from the dashboard. One operator intent: the key goes into the
2
+ // secrets vault, the host's provider config binds it by reference (spawns and host probes resolve
3
+ // it there, #3541/#3559), the host opts in, and the API credit window opens. No shell, no key file.
4
+ import { getManifest } from "@humwick/providers";
5
+ import { API_BUDGET_IDS, isRecord, type ApiBudgetId, type ApiBudgetStatus } from "@humwick/sdk";
6
+ import { getOrchestratorAsync, ValidationError } from "../db";
7
+ import { configureApiBudgetFields } from "../claude-api-budget-config";
8
+ import { apiBudgetStatusAsync } from "../claude-api-budget-async";
9
+ import { getProviderConfigEntry, setProviderConfigAsync } from "../provider-config-store";
10
+ import { createOperatorSecret, rotateOperatorSecret } from "../secrets-vault/service";
11
+ import { VaultError } from "../secrets-vault/keys";
12
+ import { emitConfigChanged } from "../sse";
13
+ import { setHostProviderEnabled } from "./host-providers";
14
+
15
+ /** What a first-run user gets unless they type another monthly limit. */
16
+ export const DEFAULT_MONTHLY_LIMIT_USD = 20;
17
+ const MAX_MONTHLY_LIMIT_USD = 100_000;
18
+
19
+ export interface ProviderApiKeyResult {
20
+ host: string;
21
+ provider: string;
22
+ /** Vault secret the host's provider config references; never the value. */
23
+ secret: string;
24
+ version: number;
25
+ budget: ApiBudgetStatus;
26
+ }
27
+
28
+ function cleanRequest(provider: string, body: unknown) {
29
+ const auth = getManifest(provider)?.apiAuth;
30
+ if (!auth || !(API_BUDGET_IDS as readonly string[]).includes(provider)) throw new ValidationError(`${provider} is not set up with an API key`);
31
+ if (!isRecord(body)) throw new ValidationError("body must be an object");
32
+ const apiKey = typeof body.apiKey === "string" ? body.apiKey.trim() : "";
33
+ if (!apiKey || /\s/.test(apiKey) || apiKey.length > 512 || (auth.keyPrefix && !apiKey.startsWith(auth.keyPrefix))) {
34
+ throw new ValidationError(`apiKey must be a single ${auth.keyPrefix ?? ""}… key`);
35
+ }
36
+ const limit = body.monthlyLimitUsd ?? DEFAULT_MONTHLY_LIMIT_USD;
37
+ if (typeof limit !== "number" || !Number.isFinite(limit) || limit <= 0 || limit > MAX_MONTHLY_LIMIT_USD) {
38
+ throw new ValidationError(`monthlyLimitUsd must be a number above 0 and at most ${MAX_MONTHLY_LIMIT_USD}`);
39
+ }
40
+ return { secret: auth.keyEnvVar, apiKey, ceilingMicroUsd: Math.round(limit * 1_000_000), budgetId: provider as ApiBudgetId };
41
+ }
42
+
43
+ /** Stores the key in the vault: a new secret, or a new version of the one already there. */
44
+ async function storeKey(actor: string, secret: string, value: string): Promise<number> {
45
+ const description = "Set during first-run provider setup";
46
+ try {
47
+ return (await createOperatorSecret(actor, { name: secret, value, description })).version;
48
+ } catch (cause) {
49
+ if (!(cause instanceof VaultError && cause.code === "exists")) throw cause;
50
+ return (await rotateOperatorSecret(actor, secret, { value, reason: description })).version;
51
+ }
52
+ }
53
+
54
+ export async function connectProviderApiKey(actor: string, hostId: string, provider: string, body: unknown, req: Request): Promise<ProviderApiKeyResult> {
55
+ const request = cleanRequest(provider, body);
56
+ if (!(await getOrchestratorAsync(hostId))) throw new ValidationError(`host ${hostId} is not registered`);
57
+ // The credit window first: a refused limit must leave nothing half set up.
58
+ const status = await apiBudgetStatusAsync(request.budgetId);
59
+ let budget: ApiBudgetStatus;
60
+ try {
61
+ budget = await configureApiBudgetFields({ budgetId: request.budgetId, enabled: true, ceilingMicroUsd: request.ceilingMicroUsd,
62
+ ...(status.baselineKnown ? {} : { baselineMicroUsd: 0 }) });
63
+ } catch (cause) {
64
+ throw new ValidationError(`monthly limit refused: ${cause instanceof Error ? cause.message : "invalid"}`);
65
+ }
66
+ const version = await storeKey(actor, request.secret, request.apiKey);
67
+ const current = getProviderConfigEntry(provider, hostId).value;
68
+ const config = await setProviderConfigAsync(provider, { ...current, env: { ...current.env, [request.secret]: `secret:${request.secret}` } },
69
+ { host: hostId, updatedBy: actor });
70
+ emitConfigChanged(config.namespace, config.key, config.version);
71
+ await setHostProviderEnabled(hostId, provider, { enabled: true, reason: "first-run provider setup", updatedBy: actor }, req);
72
+ return { host: hostId, provider, secret: request.secret, version, budget };
73
+ }
package/src/setup.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { writeChildEnv } from "@humwick/sdk/env";
1
+ import { relayEnv, writeChildEnv } from "@humwick/sdk/env";
2
2
  import { randomBytes } from "node:crypto";
3
3
  import { shellQuote } from "@humwick/sdk/shell-utils";
4
4
  import { access, mkdir, readFile, writeFile } from "node:fs/promises";
@@ -70,18 +70,24 @@ export function generateToken(): string {
70
70
  return randomBytes(24).toString("hex");
71
71
  }
72
72
 
73
+ /**
74
+ * The setup plan. `existing` holds the values of the managed env file already on disk: a re-run
75
+ * keeps them (above all the admin token) unless an option overrides them (#2680).
76
+ */
73
77
  export function createSetupPlan(
74
78
  options: SetupOptions = {},
75
79
  env: SetupEnvironment = {},
80
+ existing: Record<string, string> = {},
76
81
  ): SetupPlan {
77
82
  const configDir = defaultConfigDir(env);
78
83
  const stateDir = defaultStateDir(env);
79
84
  const logDir = defaultLogDir(env);
80
85
  const envFile = resolve(options.envFile ?? join(configDir, "env"));
81
- const host = options.host ?? DEFAULT_HOST;
82
- const port = normalizePort(options.port);
83
- const token = options.token ?? (options.generateToken === false ? "" : generateToken());
84
- const dbPath = resolve(options.dbPath ?? join(stateDir, "agent-relay.db"));
86
+ const host = options.host ?? existing.HOST ?? DEFAULT_HOST;
87
+ const port = normalizePort(options.port ?? (existing.PORT ? Number(existing.PORT) : undefined));
88
+ const token = options.token
89
+ ?? (options.generateToken === false ? "" : relayEnv(existing, "AGENT_RELAY_TOKEN") || generateToken());
90
+ const dbPath = resolve(options.dbPath ?? existing.DB_PATH ?? join(stateDir, "agent-relay.db"));
85
91
  const runtimePrefix = resolve(options.runtimePrefix ?? defaultRuntimePrefix(env));
86
92
  const tarballDir = runtimeTarballDir(runtimePrefix);
87
93
  const warnings: string[] = [];
@@ -91,12 +97,13 @@ export function createSetupPlan(
91
97
  }
92
98
 
93
99
  const values: Record<string, string> = {
100
+ RETENTION_DAYS: "30",
101
+ ...existing,
94
102
  PORT: String(port),
95
103
  HOST: host,
96
104
  DB_PATH: dbPath,
97
- RETENTION_DAYS: "30",
98
105
  };
99
- if (token) writeChildEnv(values, { "AGENT_RELAY_TOKEN": token });
106
+ writeChildEnv(values, token ? { "AGENT_RELAY_TOKEN": token } : {}, token ? [] : ["AGENT_RELAY_TOKEN"]);
100
107
 
101
108
  return {
102
109
  envFile,
@@ -111,6 +118,38 @@ export function createSetupPlan(
111
118
  };
112
119
  }
113
120
 
121
+ /** The admin token a plan writes, or "" for a token-less relay. */
122
+ export function setupPlanToken(plan: Pick<SetupPlan, "values">): string {
123
+ return relayEnv(plan.values, "AGENT_RELAY_TOKEN") ?? "";
124
+ }
125
+
126
+ /** `createSetupPlan` over the managed env file already at the target path, if any. */
127
+ export async function resolveSetupPlan(options: SetupOptions = {}, env: SetupEnvironment = {}): Promise<SetupPlan & { reused: boolean }> {
128
+ const envFile = resolve(options.envFile ?? join(defaultConfigDir(env), "env"));
129
+ const content = await readIfExists(envFile);
130
+ const existing = content?.includes(SETUP_MARKER) ? parseEnvFile(content) : undefined;
131
+ return { ...createSetupPlan(options, env, existing), reused: existing !== undefined };
132
+ }
133
+
134
+ /** The values of an env file in the format `renderEnvFile` writes. */
135
+ export function parseEnvFile(content: string): Record<string, string> {
136
+ const values: Record<string, string> = {};
137
+ for (const line of content.split("\n")) {
138
+ const match = /^([A-Za-z_][A-Za-z0-9_]*)=(.*)$/.exec(line.trim());
139
+ if (!match) continue;
140
+ const raw = match[2]!;
141
+ values[match[1]!] = raw.startsWith("'") && raw.endsWith("'") && raw.length >= 2 ? raw.slice(1, -1).replaceAll("'\\''", "'") : raw;
142
+ }
143
+ return values;
144
+ }
145
+
146
+ /** The plan without the admin token, for any output a person or a log may see. */
147
+ export function redactSetupPlan<T extends SetupPlan>(plan: T): T {
148
+ const values = { ...plan.values };
149
+ for (const key of ["AGENT_RELAY_TOKEN", "HUMWICK_TOKEN"]) if (values[key]) values[key] = "<redacted>";
150
+ return { ...plan, values, content: redactEnv(plan.content) };
151
+ }
152
+
114
153
  export async function executeSetupPlan(
115
154
  plan: SetupPlan,
116
155
  options: { dryRun?: boolean; force?: boolean } = {},
@@ -195,5 +234,5 @@ function normalizePort(port: number | undefined): number {
195
234
  }
196
235
 
197
236
  function redactEnv(content: string): string {
198
- return content.replace(/^(AGENT_RELAY_TOKEN=).+$/m, "$1'<generated-token>'");
237
+ return content.replace(/^((?:AGENT_RELAY|HUMWICK)_TOKEN=).+$/gm, "$1'<generated-token>'");
199
238
  }
package/src/utils.ts CHANGED
@@ -40,3 +40,10 @@ export function isOrchestratorLocalToRelay(orchestrator: { hostname?: string | n
40
40
  const self = hostname();
41
41
  return sameHostIdentity(orchestrator.hostname, self) || sameHostIdentity(orchestrator.id, self);
42
42
  }
43
+
44
+ /** An orchestrator id from a hostname or operator input: dots and other separators become dashes. */
45
+ export function sanitizeOrchestratorId(value: string): string {
46
+ const clean = value.trim().replace(/\./g, "-").replace(/[^A-Za-z0-9_.-]+/g, "-").replace(/^-+|-+$/g, "");
47
+ if (!clean) throw new Error("--id must contain at least one letter or number");
48
+ return clean.slice(0, 120);
49
+ }
@@ -1,2 +0,0 @@
1
- import{T as e}from"./display-CDeH4I8T.js";function t(t,n){return!!n&&n.status!==`offline`&&!e(t,n)}export{t};
2
- //# sourceMappingURL=agent-liveness-Bq-s73jW.js.map
@@ -1,2 +0,0 @@
1
- import{r as e}from"./rolldown-runtime-QTnfLwEv.js";import{o as t,p as n,u as r}from"./dist-DeW2Y1R5.js";import{A as i,Ct as a,J as o,K as s,t as c}from"./store-DKPDIZBe.js";import{R as l,_ as u,b as d,et as f,f as p,it as m,tt as h,wt as g}from"./display-CDeH4I8T.js";import{t as _}from"./scroll-area-CIN4KQse.js";import{t as v}from"./separator-t1cLZErD.js";import{t as y}from"./activity-TMzFOdh2.js";import{t as b}from"./bot-B0NpDNhr.js";import{n as x,t as S}from"./zap-DGuDTw4w.js";import{t as ee}from"./git-commit-horizontal-DS1pJ_SS.js";import{t as C}from"./inbox-Dfwk3Gt8.js";import{t as w}from"./link-6RR7Hy3-.js";import{t as T}from"./list-checks-CwnS3hly.js";import{t as E}from"./mail-DyaDmwfY.js";import{t as D}from"./message-square-C-1G8dMM.js";import{t as O}from"./triangle-alert-BBNhfgMi.js";import{t as k}from"./agent-type-icon-CY113sp-.js";import{t as A}from"./users-C7B3u9jv.js";import{t as j}from"./badge-DqJRtj_p.js";import{n as M,t as N}from"./agent-name-CcY3Aijy.js";import{i as P,l as F,r as I}from"./use-selectors-BdxBW8mL.js";import{t as L}from"./status-dot-BcHyw1Vw.js";import{o as R,r as z,s as B,t as V}from"./card-C4QJ4hCW.js";import{i as H,t as U}from"./use-decisions-uJXHf34W.js";var W=e(n(),1),G=r();function K(){let e=c(e=>e.openDecisions),n=c(e=>e.agentsById),r=c(e=>e.openInboxThread),i=c(e=>e.switchView),l=a(),[u,d]=(0,W.useState)(null);return e.length?(0,G.jsxs)(V,{"data-testid":`waiting-on-you`,className:`border-tone-warning/40`,children:[(0,G.jsx)(R,{className:`pb-2 pt-4 px-4`,children:(0,G.jsxs)(B,{className:`text-sm font-medium text-tone-warning-fg flex items-center gap-2`,children:[(0,G.jsx)(x,{className:`w-4 h-4`}),`Waiting on you (`,s(e,l),`)`]})}),(0,G.jsx)(z,{className:`px-4 pb-4 space-y-1.5`,children:e.map(e=>{let a=e.coordinatorId?n[e.coordinatorId]:void 0,s=u===e.id;return(0,G.jsxs)(`div`,{children:[(0,G.jsxs)(`div`,{className:t(`flex items-center gap-2 rounded-md px-2 py-1.5 hover:bg-muted/50`,s&&`bg-muted/40`),children:[(0,G.jsxs)(`button`,{type:`button`,className:`flex min-w-0 flex-1 items-center gap-2 text-left`,onClick:()=>d(s?null:e.id),children:[e.timeCritical&&(0,G.jsx)(S,{className:`h-3.5 w-3.5 shrink-0 text-tone-danger-fg`,"aria-label":`time-critical`}),e.kind===`action`&&(0,G.jsx)(`span`,{title:o(e)?`Secret to enter`:`To do for you`,className:`shrink-0 rounded bg-tone-sky/15 px-1 text-[10px] font-medium leading-4 text-tone-sky-fg`,children:o(e)?`Secret`:`To do`}),(0,G.jsx)(`span`,{className:`truncate text-sm`,children:e.title}),(0,G.jsxs)(`span`,{className:`shrink-0 text-[11px] text-muted-foreground`,children:[o(e)?(0,G.jsx)(N,{agent:n[e.filedBy],fallback:e.filedBy}):(0,G.jsx)(N,{agent:a,fallback:e.coordinatorId??`no coordinator`}),` · `,f(l,e.createdAt)]})]}),e.coordinatorId&&(0,G.jsx)(`button`,{type:`button`,title:`Open coordinator chat`,className:`shrink-0 rounded p-1 text-muted-foreground hover:text-foreground`,onClick:()=>{r(e.coordinatorId),i(`chat`)},children:(0,G.jsx)(D,{className:`h-3.5 w-3.5`})})]}),s&&(0,G.jsx)(H,{decision:e,className:`mt-1.5`},U(e))]},e.id)})})]}):null}function q(){let e=c(e=>e.stats),t=c(e=>e.agents),n=c(e=>e.messages),r=c(e=>e.health),o=a(),s=c(e=>e.agentsById),x=c(e=>e.switchView),S=c(e=>e.runHealthAction),N=c(e=>e.managedPolicies),H=c(e=>e.showOffline),U=F(),q=P(),J=I(),Y=(0,W.useMemo)(()=>{let e=m(t,!1,N);return H||(e=e.filter(e=>e.status!==`offline`)),[...e].sort((e,t)=>(g[e.status]??9)-(g[t.status]??9)||h(t.lastSeen)-h(e.lastSeen))},[t,H,N]),X=Y.slice(0,20),Z=[...n].sort((e,t)=>t.id-e.id).slice(0,15),Q=c(e=>i(e.sessionUser))&&r&&r.status!==`ok`?d(r.checks||[]):[];function $(e){x(e)}return(0,G.jsxs)(`div`,{className:`space-y-6`,children:[(0,G.jsx)(K,{}),(0,G.jsxs)(`div`,{className:`grid grid-cols-2 md:grid-cols-4 gap-4`,children:[(0,G.jsxs)(V,{className:`cursor-pointer hover:border-tone-neutral transition-colors`,onClick:()=>$(`agents`),children:[(0,G.jsx)(R,{className:`pb-1 pt-4 px-4`,children:(0,G.jsxs)(B,{className:`text-xs font-medium text-muted-foreground flex items-center gap-1.5`,children:[(0,G.jsx)(A,{className:`w-3.5 h-3.5`}),`Agents`]})}),(0,G.jsxs)(z,{className:`px-4 pb-4`,children:[(0,G.jsx)(`div`,{className:`text-2xl font-bold`,children:Y.length}),(0,G.jsxs)(`div`,{className:`text-xs text-muted-foreground mt-0.5`,children:[U,` online`]})]})]}),(0,G.jsxs)(V,{className:`cursor-pointer hover:border-tone-neutral transition-colors`,onClick:()=>$(`agents`),children:[(0,G.jsx)(R,{className:`pb-1 pt-4 px-4`,children:(0,G.jsxs)(B,{className:`text-xs font-medium text-muted-foreground flex items-center gap-1.5`,children:[(0,G.jsx)(y,{className:`w-3.5 h-3.5`}),`Busy`]})}),(0,G.jsxs)(z,{className:`px-4 pb-4`,children:[(0,G.jsx)(`div`,{className:`text-2xl font-bold`,children:q}),(0,G.jsx)(`div`,{className:`text-xs text-muted-foreground mt-0.5`,children:`in a turn now`})]})]}),(0,G.jsxs)(V,{className:`cursor-pointer hover:border-tone-neutral transition-colors`,onClick:()=>$(`messages`),children:[(0,G.jsx)(R,{className:`pb-1 pt-4 px-4`,children:(0,G.jsxs)(B,{className:`text-xs font-medium text-muted-foreground flex items-center gap-1.5`,children:[(0,G.jsx)(D,{className:`w-3.5 h-3.5`}),`Messages 24h`]})}),(0,G.jsxs)(z,{className:`px-4 pb-4`,children:[(0,G.jsx)(`div`,{className:`text-2xl font-bold`,children:e.messagesLast24h??`—`}),(0,G.jsx)(`div`,{className:`text-xs text-muted-foreground mt-0.5`,children:`last 24 hours`})]})]}),(0,G.jsxs)(V,{className:`cursor-pointer hover:border-tone-neutral transition-colors`,onClick:()=>$(`messages`),children:[(0,G.jsx)(R,{className:`pb-1 pt-4 px-4`,children:(0,G.jsxs)(B,{className:`text-xs font-medium text-muted-foreground flex items-center gap-1.5`,children:[(0,G.jsx)(E,{className:`w-3.5 h-3.5`}),`Total Messages`]})}),(0,G.jsxs)(z,{className:`px-4 pb-4`,children:[(0,G.jsx)(`div`,{className:`text-2xl font-bold`,children:e.messages??`—`}),(0,G.jsx)(`div`,{className:`text-xs text-muted-foreground mt-0.5`,children:`all time`})]})]})]}),(r?.gitSha||r?.mainSha)&&(0,G.jsxs)(`div`,{className:`flex items-center gap-2 text-xs text-muted-foreground px-1`,children:[(0,G.jsx)(ee,{className:`w-3.5 h-3.5 shrink-0`}),r.gitSha?(0,G.jsxs)(`span`,{children:[`running `,(0,G.jsx)(`span`,{className:`font-mono`,children:r.gitSha.slice(0,7)})]}):(0,G.jsx)(`span`,{children:`running sha unattested`}),r.mainSha===void 0?(0,G.jsx)(j,{variant:`outline`,className:`border-tone-neutral text-muted-foreground`,children:`main HEAD unknown`}):r.atMainHead===!0?(0,G.jsx)(j,{variant:`outline`,className:`border-tone-success/40 text-tone-success-fg`,children:`at origin/main HEAD`}):r.atMainHead===!1?(0,G.jsxs)(j,{variant:`outline`,className:`border-tone-yellow/40 text-tone-yellow-fg`,children:[`differs from origin/main (`,(0,G.jsx)(`span`,{className:`font-mono`,children:r.mainSha.slice(0,7)}),`)`]}):(0,G.jsxs)(j,{variant:`outline`,className:`border-tone-neutral text-muted-foreground`,children:[`origin/main `,(0,G.jsx)(`span`,{className:`font-mono`,children:r.mainSha.slice(0,7)})]})]}),Q.length>0&&(0,G.jsxs)(V,{className:`border-tone-yellow/40 bg-tone-yellow/5`,children:[(0,G.jsx)(R,{className:`pb-2 pt-4 px-4`,children:(0,G.jsxs)(B,{className:`text-sm font-medium text-tone-yellow-fg flex items-center gap-2`,children:[(0,G.jsx)(O,{className:`w-4 h-4`}),`Health Alerts (`,Q.length,`)`]})}),(0,G.jsx)(z,{className:`px-4 pb-4 space-y-2`,children:Q.map(e=>(0,G.jsxs)(`div`,{className:`text-sm space-y-1`,children:[(0,G.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,G.jsx)(j,{variant:`outline`,className:e.status===`error`?`border-tone-danger/40 text-tone-danger-fg`:`border-tone-yellow/40 text-tone-yellow-fg`,children:e.status}),(0,G.jsx)(`span`,{className:`font-medium`,children:e.name})]}),(0,G.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:e.detail}),e.subjects.length>0&&(0,G.jsx)(`div`,{className:`flex flex-wrap gap-1.5`,children:e.subjects.map(e=>(0,G.jsxs)(j,{variant:`secondary`,className:`max-w-full truncate text-[11px]`,title:[e.id,e.status,e.detail].filter(Boolean).join(` · `),children:[e.label||e.id,e.status?` · ${e.status}`:``,e.detail?` · ${e.detail}`:``]},e.id))}),e.actions.length>0&&(0,G.jsx)(`div`,{className:`flex flex-wrap gap-1.5 pt-0.5`,children:e.actions.slice(0,3).map(e=>(0,G.jsx)(`button`,{onClick:()=>S(e),className:`text-xs text-tone-info-fg hover:text-tone-info-fg underline underline-offset-2`,children:e.label},e.label))})]},e.name))})]}),(0,G.jsxs)(`div`,{className:`grid grid-cols-1 sm:grid-cols-3 gap-4`,children:[(0,G.jsx)(V,{className:`cursor-pointer hover:border-tone-neutral transition-colors ${J.unreadInbox>0?`border-tone-danger/40`:``}`,onClick:()=>$(`chat`),children:(0,G.jsxs)(z,{className:`p-4 flex items-center gap-3`,children:[(0,G.jsx)(`div`,{className:`p-2 rounded-lg ${J.unreadInbox>0?`bg-tone-danger/15`:`bg-muted`}`,children:(0,G.jsx)(C,{className:`w-4 h-4 ${J.unreadInbox>0?`text-tone-danger-fg`:`text-tone-neutral-fg`}`})}),(0,G.jsxs)(`div`,{children:[(0,G.jsx)(`div`,{className:`text-lg font-bold`,children:J.unreadInbox}),(0,G.jsx)(`div`,{className:`text-xs text-muted-foreground`,children:`Unread`})]})]})}),(0,G.jsx)(V,{className:`cursor-pointer hover:border-tone-neutral transition-colors ${J.pendingPairInvites>0?`border-tone-yellow/40`:``}`,onClick:()=>$(`pairs`),children:(0,G.jsxs)(z,{className:`p-4 flex items-center gap-3`,children:[(0,G.jsx)(`div`,{className:`p-2 rounded-lg ${J.pendingPairInvites>0?`bg-tone-yellow/15`:`bg-muted`}`,children:(0,G.jsx)(w,{className:`w-4 h-4 ${J.pendingPairInvites>0?`text-tone-yellow-fg`:`text-tone-neutral-fg`}`})}),(0,G.jsxs)(`div`,{children:[(0,G.jsx)(`div`,{className:`text-lg font-bold`,children:J.pendingPairInvites}),(0,G.jsx)(`div`,{className:`text-xs text-muted-foreground`,children:`Pair invites`})]})]})}),(0,G.jsx)(V,{className:`cursor-pointer hover:border-tone-neutral transition-colors ${J.claimableTasks>0?`border-tone-orange/40`:``}`,onClick:()=>$(`work`),children:(0,G.jsxs)(z,{className:`p-4 flex items-center gap-3`,children:[(0,G.jsx)(`div`,{className:`p-2 rounded-lg ${J.claimableTasks>0?`bg-tone-orange/15`:`bg-muted`}`,children:(0,G.jsx)(T,{className:`w-4 h-4 ${J.claimableTasks>0?`text-tone-orange-fg`:`text-tone-neutral-fg`}`})}),(0,G.jsxs)(`div`,{children:[(0,G.jsx)(`div`,{className:`text-lg font-bold`,children:J.claimableTasks}),(0,G.jsx)(`div`,{className:`text-xs text-muted-foreground`,children:`Claimable waiting`})]})]})})]}),(0,G.jsxs)(`div`,{className:`grid grid-cols-1 md:grid-cols-2 gap-6`,children:[(0,G.jsxs)(V,{children:[(0,G.jsx)(R,{className:`pb-2 pt-4 px-4`,children:(0,G.jsxs)(B,{className:`text-sm font-medium flex items-center gap-2`,children:[(0,G.jsx)(b,{className:`w-4 h-4 text-muted-foreground`}),`Agents`,(0,G.jsx)(`span`,{className:`ml-auto text-xs text-muted-foreground font-normal`,children:X.length})]})}),(0,G.jsx)(z,{className:`px-0 pb-0`,children:(0,G.jsx)(_,{className:`h-[340px]`,children:X.length===0?(0,G.jsx)(`div`,{className:`px-4 pb-4 text-sm text-muted-foreground`,children:`No agents registered.`}):(0,G.jsx)(`div`,{className:`space-y-0`,children:X.map((e,t)=>(0,G.jsxs)(`div`,{children:[t>0&&(0,G.jsx)(v,{}),(0,G.jsxs)(`div`,{className:`flex items-center gap-2.5 px-4 py-2.5 hover:bg-muted/50 transition-colors cursor-pointer`,onClick:()=>c.getState().openAgentDetail(e),children:[(0,G.jsx)(L,{agent:e,now:o}),(0,G.jsx)(k,{agent:e}),(0,G.jsxs)(`div`,{className:`flex-1 min-w-0`,children:[(0,G.jsx)(`div`,{className:`text-sm font-medium truncate`,children:p(e)}),e.tags.length>0&&(0,G.jsx)(`div`,{className:`flex gap-1 mt-0.5 flex-wrap`,children:e.tags.slice(0,2).map(e=>(0,G.jsx)(j,{variant:`outline`,className:`text-[9px] px-1 py-0 h-4`,children:e},e))})]}),(0,G.jsx)(`span`,{className:`text-xs text-muted-foreground shrink-0`,children:f(o,e.lastSeen)})]})]},e.id))})})})]}),(0,G.jsxs)(V,{children:[(0,G.jsx)(R,{className:`pb-2 pt-4 px-4`,children:(0,G.jsxs)(B,{className:`text-sm font-medium flex items-center gap-2`,children:[(0,G.jsx)(y,{className:`w-4 h-4 text-muted-foreground`}),`Recent Activity`,(0,G.jsx)(`span`,{className:`ml-auto text-xs text-muted-foreground font-normal`,children:Z.length})]})}),(0,G.jsx)(z,{className:`px-0 pb-0`,children:(0,G.jsx)(_,{className:`h-[340px]`,children:Z.length===0?(0,G.jsx)(`div`,{className:`px-4 pb-4 text-sm text-muted-foreground`,children:`No recent messages.`}):(0,G.jsx)(`div`,{className:`space-y-0`,children:Z.map((e,t)=>(0,G.jsxs)(`div`,{children:[t>0&&(0,G.jsx)(v,{}),(0,G.jsxs)(`div`,{className:`px-4 py-2.5 hover:bg-muted/50 transition-colors`,children:[(0,G.jsxs)(`div`,{className:`flex items-center gap-1 text-xs text-muted-foreground mb-0.5`,children:[(0,G.jsx)(`span`,{className:`text-foreground font-medium truncate max-w-[100px]`,children:(0,G.jsx)(M,{target:e.from,agentsById:s})}),(0,G.jsx)(`span`,{children:`→`}),(0,G.jsx)(`span`,{className:`truncate max-w-[100px]`,children:(0,G.jsx)(M,{target:e.to,agentsById:s})}),(0,G.jsxs)(`span`,{className:`ml-auto shrink-0 tabular-nums`,children:[(0,G.jsx)(`span`,{className:`opacity-40 mr-1`,children:u(e.id)}),f(o,e.createdAt)]})]}),(0,G.jsx)(`div`,{className:`text-xs text-foreground line-clamp-2 leading-snug`,children:l(e)})]})]},e.id))})})})]})]})]})}export{q as OverviewView};
2
- //# sourceMappingURL=overview-DcYCrvlr.js.map
@@ -1,2 +0,0 @@
1
- function e(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function t(e){if(typeof e!=`string`)return;let t=e.trim();return t.length>0?t:void 0}function n(e){return e instanceof Error?e.message:String(e)}var r=`provider-enablement`,i=`default`,a=`user`;function o(e){return`user:${e}`}var s=o(`claude-app`);function c(e){return e===`user`||typeof e==`string`&&e.startsWith(`user:`)}function ee(e){if(e===`user`)return i;if(typeof e==`string`&&e.startsWith(`user:`))return e.slice(5)||`default`}function te(e){return e===`user`||e===o(`default`)||e===`user:`?a:e}var ne=[`system`,`control`,`session`];function re(e){return ne.includes(e??``)}var ie=[`memory`,`memory-area`,`instructions`,`tools`,`comms`,`knowledge`,`context`];function ae(e){return typeof e==`string`&&ie.includes(e)}function oe(t){return e(t)&&(t.turnFinal===!0||t.final===!0)}function l(t){return e(t)&&e(t.finality)}function se(t){if(!e(t))return!1;if(l(t))return!0;let n=t.session;return e(n)&&n.final===!0&&n.turnFinal!==!0}function u(t){if(t.messageType===`final-turn`)return!0;let n=e(t.payload?.responseCapture)?t.payload.responseCapture:void 0;return oe(n)&&n.type===`response`}var d=[`decisions`,`actions`,`escalations`,`finalReports`,`failures`];Object.freeze({decisions:`all`,actions:`all`,escalations:`all`,finalReports:`all`,failures:`all`});var ce=/^[a-z][a-z0-9-]*$/,f=new Map,p=[`CLAUDE_CODE_OAUTH_TOKEN`,`ANTHROPIC_API_KEY`,`ANTHROPIC_AUTH_TOKEN`];function m(e){if(!ce.test(e.id))throw Error(`invalid provider id: ${e.id}`);if(!e.label.trim())throw Error(`provider ${e.id} is missing a label`);if(!e.icon.trim())throw Error(`provider ${e.id} is missing an icon`);if(f.has(e.id))throw Error(`provider already registered: ${e.id}`);f.set(e.id,e)}function h(e){return f.get(e)}function g(){return[...f.values()]}function le(e,t){let n=f.get(e)?.capabilityDefaults.session?.shellMode,r=t===`read-only`?n?.readOnly:n?.[t];return!!(r&&r!==`unsupported`)}function _(e){return[`open`,`guarded`,`read-only`].filter(t=>le(e,t))}var v=[`low`,`medium`,`high`,`max`],y=[`low`,`medium`,`high`,`xhigh`,`max`],b={value:2e5,source:`catalog`,confidence:`declared`},x={value:1e6,source:`catalog`,confidence:`declared`},ue={modalities:{input:{text:!0,image:!0},output:{text:!0}},tools:{code:!0,review:!0,debug:!0,refactor:!0},source:`catalog`,confidence:`declared`},S=[{name:`five_hour`,unit:`%`,reset:!0},{name:`seven_day`,unit:`%`,reset:!0}];function C(e){return{...e?{limits:e}:{},capabilities:ue}}var w={id:`claude`,credentialEnvKeys:p,label:`Claude`,icon:`🟠`,launchModes:[`interactive`,`headless`],effortSwitch:!0,launch:{managedPolicyPrompt:{alwaysOn:`append-system-prompt`},taskHydration:{channel:`append-system-prompt`}},catalog:{defaultModel:`sonnet`,models:[{alias:`haiku-5.5`,label:`Haiku 5.5`,providerModel:`claude-haiku-5-5`,efforts:y,defaultEffort:`medium`,...C({contextWindowTokens:x})},{alias:`opus-5.5`,label:`Opus 5.5`,providerModel:`claude-opus-5-5`,efforts:y,defaultEffort:`medium`,...C({contextWindowTokens:x})},{alias:`sonnet-5.5`,label:`Sonnet 5.5`,providerModel:`claude-sonnet-5-5`,efforts:y,defaultEffort:`medium`,...C({contextWindowTokens:x})},{alias:`fable-5.1`,label:`Fable 5.1`,providerModel:`claude-fable-5-1`,efforts:y,defaultEffort:`high`,...C({contextWindowTokens:x})},{alias:`fable-5`,label:`Fable 5`,providerModel:`claude-fable-5`,efforts:y,defaultEffort:`medium`,unavailable:`suspended by export-control directive, 2026-06-12`,...C({contextWindowTokens:x})},{alias:`opus-4.8`,label:`Opus 4.8`,providerModel:`claude-opus-4-8`,efforts:y,defaultEffort:`medium`,...C({contextWindowTokens:b})},{alias:`opus-4.8[1m]`,label:`Opus 4.8 1M`,providerModel:`claude-opus-4-8[1m]`,efforts:y,defaultEffort:`medium`,...C({contextWindowTokens:x})},{alias:`opus-4.7`,label:`Opus 4.7`,providerModel:`claude-opus-4-7`,efforts:y,defaultEffort:`medium`,...C({contextWindowTokens:b})},{alias:`opus-4.7[1m]`,label:`Opus 4.7 1M`,providerModel:`claude-opus-4-7[1m]`,efforts:y,defaultEffort:`medium`,...C({contextWindowTokens:x})},{alias:`opus-4.6`,label:`Opus 4.6`,providerModel:`claude-opus-4-6`,efforts:v,defaultEffort:`medium`,...C({contextWindowTokens:b})},{alias:`opus-4.6[1m]`,label:`Opus 4.6 1M`,providerModel:`claude-opus-4-6[1m]`,efforts:v,defaultEffort:`medium`,...C({contextWindowTokens:x})},{alias:`sonnet-5`,label:`Sonnet 5`,providerModel:`claude-sonnet-5`,efforts:y,defaultEffort:`medium`,...C({contextWindowTokens:b})},{alias:`sonnet-5[1m]`,label:`Sonnet 5 1M`,providerModel:`claude-sonnet-5[1m]`,efforts:y,defaultEffort:`medium`,...C({contextWindowTokens:x})},{alias:`haiku`,label:`Haiku`,providerModel:`claude-haiku-5-5`,efforts:y,defaultEffort:`medium`,...C({contextWindowTokens:x})},{alias:`fable`,label:`Fable`,providerModel:`claude-fable-5-1`,efforts:y,defaultEffort:`high`,...C({contextWindowTokens:x})},{alias:`opus`,label:`Opus`,providerModel:`claude-opus-5-5`,efforts:y,defaultEffort:`medium`,...C({contextWindowTokens:x})},{alias:`opus[1m]`,label:`Opus 1M`,providerModel:`claude-opus-5-5`,efforts:y,defaultEffort:`medium`,...C({contextWindowTokens:x})},{alias:`sonnet`,label:`Sonnet`,providerModel:`claude-sonnet-5-5`,efforts:y,defaultEffort:`medium`,...C({contextWindowTokens:x})},{alias:`sonnet[1m]`,label:`Sonnet 1M`,providerModel:`claude-sonnet-5-5`,efforts:y,defaultEffort:`medium`,...C({contextWindowTokens:x})}]},quotaWindows:[...S],capabilityDefaults:{lifecycle:{managed:!0,shutdownHard:{when:`headless`,value:!0,otherwise:!1},restartHard:{when:`headless`,value:!0,otherwise:!1},semanticStatus:!0,reconnect:!0},session:{fileRead:!0,fileWrite:{when:`approval:not-read-only`,value:!0,otherwise:!1},shell:!0,shellMode:{open:`unrestricted`,guarded:`guarded`,readOnly:`read-only-guarded`}},context:{managed:`headless`,compact:{when:`headless`,value:!0,otherwise:!1},clear:{when:`headless`,value:!0,otherwise:!1},inject:!0,resumePreference:[`native`,`clear-inject`,`none`]},quota:{supported:!0,source:`probe`,unit:`%`,windows:[...S]},terminal:{mode:`live`,condition:`headless`,live:{read:!0,write:!0}},liveSession:{capture:!0,inject:!0,interrupt:!0,promptEcho:!0,reasoning:!0,slashCommands:!0}},slashCommands:[`/clear`,`/compact`,`/model`,`/help`],resume:{supported:!0,idFormat:`uuid-v4`,idPattern:`[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}`},home:{configDir:`.claude`,envPrefix:`CLAUDE`,configDirEnvVar:`CLAUDE_CONFIG_DIR`,quotaCredentialFile:`.credentials.json`,authItems:[`.credentials.json`,`statsig`],globalInstructionFiles:[`CLAUDE.md`]},provisioning:{pluginManifestPath:`.claude-plugin/plugin.json`,bundledPlugin:{ref:`agent-relay-claude-plugin`,dir:`runner/plugins/claude`,title:`Humwick Claude plugin`,description:`Bundled Humwick Claude plugin, materialized whole through the provisioning registry.`,omitFiles:[`monitors/relay-monitor.provisioned.mjs`,`hooks/gate-run-guard.provisioned.mjs`,`hooks/kill-guard.provisioned.mjs`],fileOverrides:[{path:`monitors/relay-monitor.ts`,sourcePath:`monitors/relay-monitor.provisioned.mjs`},{path:`hooks/gate-run-guard.ts`,sourcePath:`hooks/gate-run-guard.provisioned.mjs`},{path:`hooks/kill-guard.ts`,sourcePath:`hooks/kill-guard.provisioned.mjs`}]},bundledHooks:[{ref:`agent-relay-rg-r-guard`,dir:`runner/hooks/rg-r-guard`,title:`Humwick baseline hook: rg -r guard`,description:"Baseline Humwick PreToolUse hook that blocks the ripgrep `rg -r` replace footgun.",baseline:!0},{ref:`agent-relay-fff-search-redirect`,dir:`runner/hooks/fff-search-redirect`,title:`Humwick fff search redirect`,description:`Redirects standalone repository searches to fff for Claude profiles with a configured fff MCP server.`,omitFiles:[`fff-search-redirect.test.ts`]},{ref:`agent-relay-web-tools-redirect`,dir:`runner/hooks/web-tools-redirect`,title:`Humwick web tools redirect`,description:`Redirects built-in WebSearch/WebFetch to the profile's Relay web_search and local-first page reader tools (#3024).`,omitFiles:[`web-tools-redirect.test.ts`]}]},upgrade:{packages:[`agent-relay-runner`,`agent-relay-plugin`],detectPackages:[`agent-relay-runner`],detectCommands:[`claude`]},harness:{upgrade:{strategy:`self-update`,args:[`update`]}},probe:{command:`claude`,args:[`--version`],healthCheck:`claude --version`,authCheck:{command:`claude`,args:[`auth`,`status`,`--json`],loginArgs:[`auth`,`login`]}},quotaPoll:{strategy:`none`},shim:{kind:`claude-relay`},mcpToolManifest:{clientNativeToolDeferral:!0,runnerManagedToolDeferral:!1}};m(w),m({...w,id:`claude-b`,label:`Claude B`,home:{...w.home,configDir:`.claude-b`,dedicatedHome:!0}}),m({...w,id:`claude-api`,label:`Claude API`,automaticFamilyRouting:!1,defaultEnabled:!1,resume:{supported:!1},credentialEnvKeys:[`ANTHROPIC_API_KEY`],apiAuth:{keyPrefix:`sk-ant-`,keyEnvVar:`ANTHROPIC_API_KEY`,defaultKeyFile:`~/.config/agent-relay/secrets/anthropic-api.key`,unsetEnvKeys:[...p,`ANTHROPIC_BASE_URL`,`CLAUDE_CODE_USE_BEDROCK`,`CLAUDE_CODE_USE_VERTEX`,`CLAUDE_CODE_USE_FOUNDRY`,`ANTHROPIC_CUSTOM_HEADERS`,`CLAUDE_CODE_API_KEY_HELPER_TTL_MS`]},home:{...w.home,configDir:`.claude-api`,sourceEnvVar:`CLAUDE_API_CONFIG_DIR`,dedicatedHome:!0,authItems:[]},launchModes:void 0,quotaWindows:[],capabilityDefaults:{...w.capabilityDefaults,quota:{supported:!1,source:`runtime`,unit:`USD`,windows:[]}}});var T=[`low`,`medium`,`high`,`xhigh`],E={value:2e5,source:`catalog`,confidence:`declared`},D={value:5e5,source:`catalog`,confidence:`declared`},de={modalities:{input:{text:!0,image:!0},output:{text:!0}},tools:{code:!0,review:!0,debug:!0,refactor:!0},source:`catalog`,confidence:`declared`},O=[{name:`primary`,unit:`%`,reset:!0},{name:`secondary`,unit:`%`,reset:!0}];function k(e){return{...e?{limits:e}:{},capabilities:de}}m({id:`codex`,credentialEnvKeys:[`OPENAI_API_KEY`],label:`Codex`,icon:`⌨️`,launchModes:[`interactive`,`headless`],launch:{secretEnvRequiresManagedHome:!0,managedPolicyPrompt:{alwaysOn:`prompt`},taskHydration:{channel:`prompt`}},catalog:{defaultModel:`sol`,models:[{alias:`sol`,label:`GPT-6.1 Sol`,providerModel:`gpt-6.1-sol`,efforts:T,defaultEffort:`medium`,...k({contextWindowTokens:D})},{alias:`luna`,label:`GPT-6 Luna`,providerModel:`gpt-6-luna`,efforts:T,defaultEffort:`medium`,...k({contextWindowTokens:E})},{alias:`gpt-6-sol`,label:`GPT-6 Sol`,providerModel:`gpt-6-sol`,efforts:T,defaultEffort:`medium`,...k({contextWindowTokens:E})},{alias:`gpt-6.1-sol`,label:`GPT-6.1 Sol`,providerModel:`gpt-6.1-sol`,efforts:T,defaultEffort:`medium`,...k({contextWindowTokens:D})},{alias:`gpt-6-luna`,label:`GPT-6 Luna`,providerModel:`gpt-6-luna`,efforts:T,defaultEffort:`medium`,...k({contextWindowTokens:E})},{alias:`gpt-5.6-terra`,label:`GPT-5.6 Terra`,providerModel:`gpt-5.6-terra`,efforts:T,defaultEffort:`medium`,...k({contextWindowTokens:E})},{alias:`gpt-5.5`,label:`GPT-5.5`,providerModel:`gpt-5.5`,efforts:T,defaultEffort:`medium`,...k({contextWindowTokens:E})},{alias:`gpt-5.4`,label:`GPT-5.4`,providerModel:`gpt-5.4`,efforts:T,defaultEffort:`medium`,...k({contextWindowTokens:E})},{alias:`gpt-5.4-mini`,label:`GPT-5.4 Mini`,providerModel:`gpt-5.4-mini`,efforts:T,defaultEffort:`medium`,...k({contextWindowTokens:E})},{alias:`gpt-5.3-codex`,label:`GPT-5.3 Codex`,providerModel:`gpt-5.3-codex`,efforts:T,defaultEffort:`medium`,...k({contextWindowTokens:E})},{alias:`gpt-5.3-codex-spark`,label:`GPT-5.3 Codex Spark`,providerModel:`gpt-5.3-codex-spark`,efforts:T,defaultEffort:`high`,...k({contextWindowTokens:E})},{alias:`gpt-5.2`,label:`GPT-5.2`,providerModel:`gpt-5.2`,efforts:T,defaultEffort:`medium`,...k({contextWindowTokens:E})}]},quotaWindows:[...O],capabilityDefaults:{lifecycle:{managed:!0,shutdownHard:!0,restartHard:!0,semanticStatus:!0,reconnect:!0},session:{fileRead:!0,fileWrite:{when:`approval:not-read-only`,value:!0,otherwise:!1},shell:{when:`approval:not-read-only`,value:!0,otherwise:!1},shellMode:{open:`unrestricted`,guarded:`guarded`,readOnly:`none`}},context:{managed:`always`,compact:!0,clear:!0,inject:!0,resumePreference:[`native`,`clear-inject`,`none`]},quota:{supported:!0,source:`probe`,unit:`%`,windows:[...O]},terminal:{mode:`attach`,attach:{create:!0,read:!0,write:!0,detach:!0}},liveSession:{capture:!0,inject:!0,interrupt:!0,promptEcho:!0,reasoning:!0,slashCommands:!0}},slashCommands:[`/compact`,`/new`],resume:{supported:!0,idFormat:`codex-thread-id`,idPattern:`[\\w-]+`},home:{configDir:`.codex`,envPrefix:`CODEX`,configDirEnvVar:`CODEX_HOME`,quotaCredentialFile:`auth.json`,authItems:[`auth.json`,`installation_id`],globalInstructionFiles:[`AGENTS.md`]},provisioning:{pluginManifestPath:`.codex-plugin/plugin.json`,bundledSkills:{refPrefix:`agent-relay-codex-`,dir:`runner/plugins/codex/skills`,titlePrefix:`Humwick Codex skill: `,description:`Bundled Humwick Codex skill, materialized through the provisioning registry.`,entryFile:`SKILL.md`},bundledHooks:[{ref:`agent-relay-rg-r-guard`,dir:`runner/hooks/rg-r-guard`,title:`Humwick baseline hook: rg -r guard`,description:"Baseline Humwick PreToolUse hook that blocks the ripgrep `rg -r` replace footgun.",baseline:!0}]},upgrade:{packages:[`agent-relay-runner`,`agent-relay-codex`],detectPackages:[`agent-relay-runner`,`agent-relay-codex`],detectCommands:[`codex-relay`,`agent-relay-runner`]},harness:{upgrade:{strategy:`self-update`,args:[`update`]}},probe:{command:`codex`,args:[`--version`],healthCheck:`codex --version`,authCheck:{command:`codex`,args:[`login`,`status`],loginArgs:[`login`]}},quotaPoll:{strategy:`codex-app-server`},resetCredits:{supported:!0},shim:{kind:`codex-relay`,extraBinPaths:[`codex/bin/codex`],cleanLegacyHooks:!0},mcpToolManifest:{clientNativeToolDeferral:!1,runnerManagedToolDeferral:!0,runnerManagedToolDeferralRoute:`meta-only-callmux`}});var A={mode:`attach`,attach:{create:!0,read:!0,write:!0,detach:!0}},j=`opencode-ai@latest`;m({id:`opencode`,label:`OpenCode`,icon:`⚡`,launch:{managedPolicyPrompt:{alwaysOn:`prompt`},taskHydration:{channel:`prompt`}},catalog:{defaultModel:`muse-spark`,models:[{alias:`muse-spark`,label:`Muse Spark 1.3 Contributor`,providerModel:`meta/muse-spark-1.3-contributor`,efforts:[],limits:{contextWindowTokens:{value:1048576,source:`catalog`,confidence:`declared`},maxOutputTokens:{value:943718,source:`catalog`,confidence:`declared`}},capabilities:{modalities:{input:{text:!0},output:{text:!0}},tools:{code:!0,shell:!0,fileRead:!0,fileWrite:!0},source:`provider`,confidence:`estimated`}},{alias:`openai/gpt-6.1-sol`,label:`GPT-6.1 Sol · OpenAI API`,providerModel:`openai/gpt-6.1-sol`,efforts:[],limits:{contextWindowTokens:{value:272e3,source:`catalog`,confidence:`declared`},maxOutputTokens:{value:128e3,source:`catalog`,confidence:`declared`}}}]},quotaWindows:[],capabilityDefaults:{lifecycle:{managed:!0,shutdownHard:!0,restartHard:!0,semanticStatus:!0,reconnect:!0},session:{fileRead:!0,fileWrite:!0,shell:!0,shellMode:{open:`unrestricted`,guarded:`unsupported`,readOnly:`unsupported`}},context:{managed:`always`,compact:!0,clear:!0,inject:!0,resumePreference:[`native`,`clear-inject`,`none`]},quota:{supported:!1,source:`runtime`,unit:`%`,windows:[]},terminal:A,liveSession:{capture:!0,inject:!0,interrupt:!0,promptEcho:!0,reasoning:!1,slashCommands:!1}},resume:{supported:!1},home:{configDir:`.config/opencode`,envPrefix:`OPENCODE`},opencode:{opencodeProviderID:`openrouter`,apiKeyEnvVar:`OPENROUTER_API_KEY`},upgrade:{packages:[`agent-relay-runner`],externalPackages:[j],detectPackages:[`opencode-ai`],detectCommands:[`opencode`]},harness:{upgrade:{strategy:`external-packages`}},probe:{command:`opencode`,args:[`--version`],healthCheck:`opencode --version`},shim:{kind:`opencode-relay`},quotaPoll:{strategy:`none`},mcpToolManifest:{clientNativeToolDeferral:!1,runnerManagedToolDeferral:!1}});var M=[{name:`rolling`,unit:`%`,reset:!0,description:`Rolling 5-hour usage window`},{name:`weekly`,unit:`%`,reset:!0,description:`Weekly usage window`},{name:`monthly`,unit:`%`,reset:!0,description:`Monthly usage window (display-only)`}],fe={modalities:{input:{text:!0},output:{text:!0}},tools:{code:!0,shell:!0,fileRead:!0,fileWrite:!0},source:`provider`,confidence:`estimated`};function N(e,t){return{alias:e,label:t,providerModel:e,efforts:[],capabilities:fe}}m({id:`opencode-go`,label:`OpenCode Go`,icon:`⚡`,defaultEnabled:!1,launch:{managedPolicyPrompt:{alwaysOn:`prompt`},taskHydration:{channel:`prompt`}},catalog:{defaultModel:`glm-5.3-flash`,models:[N(`claude-haiku-5-5`,`Claude Haiku 5.5`),N(`deepseek-v4-pro`,`DeepSeek V4 Pro`),N(`deepseek-v4.1-flash`,`DeepSeek V4.1 Flash`),N(`gemini-4-argon-contributor`,`Gemini 4 Argon Contributor`),N(`glm-5.2`,`GLM-5.2`),N(`glm-5.3`,`GLM-5.3`),N(`glm-5.3-flash`,`GLM-5.3 Flash`),N(`gpt-5.6-luna`,`GPT-5.6 Luna`),N(`gpt-6-luna`,`GPT-6 Luna`),N(`grok-4.6`,`Grok 4.6`),N(`grok-4.7`,`Grok 4.7`),N(`hy3`,`Hy3`),N(`hy4-preview`,`Hy4 Preview`),N(`kimi-k2.7-code`,`Kimi K2.7 Code`),N(`kimi-k3`,`Kimi K3`),N(`longcat-2.0`,`LongCat 2.0`),N(`mimo-v2.5`,`MiMo V2.5`),N(`mimo-v2.5-pro`,`MiMo V2.5 Pro`),N(`mimo-v2.6-flash`,`MiMo V2.6 Flash`),N(`mimo-v2.6-pro`,`MiMo V2.6 Pro`),N(`minimax-m2.7`,`MiniMax M2.7`),N(`minimax-m3`,`MiniMax M3`),N(`muse-spark-1.2-contributor`,`Muse Spark 1.2 Contributor`),N(`muse-spark-1.3-contributor`,`Muse Spark 1.3 Contributor`),N(`qwen3.7-plus`,`Qwen3.7 Plus`),N(`qwen3.8-flash`,`Qwen3.8 Flash`),N(`qwen3.8-max`,`Qwen3.8 Max`),N(`space-bunny`,`Space Bunny`)]},quotaWindows:[...M],capabilityDefaults:{lifecycle:{managed:!0,shutdownHard:!0,restartHard:!0,semanticStatus:!0,reconnect:!0},session:{fileRead:!0,fileWrite:!0,shell:!0,shellMode:{open:`unrestricted`,guarded:`unsupported`,readOnly:`unsupported`}},context:{managed:`always`,compact:!0,clear:!0,inject:!0,resumePreference:[`native`,`clear-inject`,`none`]},quota:{supported:!0,source:`runtime`,unit:`%`,windows:[...M]},terminal:A,liveSession:{capture:!0,inject:!0,interrupt:!0,promptEcho:!0,reasoning:!1,slashCommands:!1}},resume:{supported:!1},home:{configDir:`.local/share/opencode`,envPrefix:`OPENCODE_GO`,quotaCredentialFile:`auth.json`},opencode:{opencodeProviderID:`opencode-go`,apiKeyEnvVar:`OPENCODE_API_KEY`,hostAuth:!0},upgrade:{packages:[`agent-relay-runner`],externalPackages:[j],detectPackages:[`opencode-ai`],detectCommands:[`opencode`]},harness:{upgrade:{strategy:`external-packages`}},probe:{command:`opencode`,args:[`--version`],healthCheck:`opencode --version`},shim:{kind:`opencode-relay`},quotaPoll:{strategy:`opencode-go`},quotaAlsoWith:`opencode`,mcpToolManifest:{clientNativeToolDeferral:!1,runnerManagedToolDeferral:!1}});var P={value:1e6,source:`catalog`,confidence:`declared`},F={value:131072,source:`catalog`,confidence:`declared`},pe={modalities:{input:{text:!0},output:{text:!0}},tools:{code:!0,shell:!0,fileRead:!0,fileWrite:!0},source:`provider`,confidence:`declared`},me={modalities:{input:{text:!0,image:!0},output:{text:!0}},tools:{code:!0,shell:!0,fileRead:!0,fileWrite:!0},source:`provider`,confidence:`declared`},I=[{name:`five_hour`,unit:`%`,reset:!0,description:`Rolling 5-hour credit window`},{name:`seven_day`,unit:`%`,reset:!0,description:`Weekly credits, reset from the subscription timestamp`}];m({id:`zai`,label:`z.ai`,icon:`🟣`,launch:{managedPolicyPrompt:{alwaysOn:`prompt`},taskHydration:{channel:`prompt`}},catalog:{defaultModel:`glm-5.3-flash`,models:[{alias:`glm-5.3`,label:`GLM-5.3`,providerModel:`glm-5.3`,efforts:[],limits:{contextWindowTokens:P,maxOutputTokens:F},capabilities:pe},{alias:`glm-5.3-flash`,label:`GLM-5.3 Flash`,providerModel:`glm-5.3-flash`,efforts:[],limits:{contextWindowTokens:P,maxOutputTokens:F},capabilities:me}]},quotaWindows:[...I],capabilityDefaults:{lifecycle:{managed:!0,shutdownHard:!0,restartHard:!0,semanticStatus:!0,reconnect:!0},session:{fileRead:!0,fileWrite:!0,shell:!0,shellMode:{open:`unrestricted`,guarded:`unsupported`,readOnly:`unsupported`}},context:{managed:`always`,compact:!0,clear:!0,inject:!0,resumePreference:[`native`,`clear-inject`,`none`]},quota:{supported:!0,source:`runtime`,unit:`%`,windows:[...I]},terminal:A,liveSession:{capture:!0,inject:!0,interrupt:!0,promptEcho:!0,reasoning:!1,slashCommands:!1}},resume:{supported:!1},home:{configDir:`.config/opencode`,envPrefix:`ZAI`,quotaCredentialFile:`auth.json`},opencode:{opencodeProviderID:`zai`,baseURL:`https://api.z.ai/api/coding/paas/v4`,npm:`@ai-sdk/openai-compatible`,apiKeyEnvVar:`ZAI_API_KEY`},upgrade:{packages:[`agent-relay-runner`],externalPackages:[j],detectPackages:[`opencode-ai`],detectCommands:[`opencode`]},harness:{upgrade:{strategy:`external-packages`}},probe:{command:`opencode`,args:[`--version`],healthCheck:`opencode --version`},shim:{kind:`opencode-relay`},quotaPoll:{strategy:`zai`},mcpToolManifest:{clientNativeToolDeferral:!1,runnerManagedToolDeferral:!1}}),Object.freeze({codex:{"gpt-5.6-terra":`sol`,"gpt-5.6-sol":`sol`,"gpt-6-sol":`sol`,"gpt-6.1-sol":`sol`,"gpt-5.6-luna":`luna`,"gpt-6-luna":`luna`},claude:{"opus-4.8":`opus`,"sonnet-5":`sonnet`,"fable-5":`fable`},"claude-b":{"opus-4.8":`opus`,"sonnet-5":`sonnet`,"fable-5":`fable`}});var L={opencode:{envVar:`OPENCODE_API_KEY`},"opencode-go":{envVar:`OPENCODE_API_KEY`},anthropic:{envVar:`ANTHROPIC_API_KEY`},openai:{envVar:`OPENAI_API_KEY`},openrouter:{envVar:`OPENROUTER_API_KEY`},google:{envVar:`GOOGLE_GENERATIVE_AI_API_KEY`},mistral:{envVar:`MISTRAL_API_KEY`},deepseek:{envVar:`DEEPSEEK_API_KEY`},xai:{envVar:`XAI_API_KEY`},groq:{envVar:`GROQ_API_KEY`},azure:{envVar:`AZURE_API_KEY`},moonshotai:{envVar:`MOONSHOT_API_KEY`},cerebras:{envVar:`CEREBRAS_API_KEY`},cohere:{envVar:`COHERE_API_KEY`},"fireworks-ai":{envVar:`FIREWORKS_API_KEY`},togetherai:{envVar:`TOGETHER_API_KEY`},chutes:{envVar:`CHUTES_API_KEY`},zai:{envVar:`ZAI_API_KEY`,custom:!0}},R=class extends Error{candidates;constructor(e,t){super(e),this.candidates=t,this.name=`OpenCodeModelResolutionError`}},z=8;function B(e,t){let n=e.indexOf(`/`);return n<=0?{backendID:t,modelID:e,qualified:`${t}/${e}`}:{backendID:e.slice(0,n),modelID:e.slice(n+1),qualified:e}}function he(e,t,n){let r=e.trim();if(!r)throw new R(`OpenCode model id is empty.`,[]);let i=r.indexOf(`/`),a=i>0?r.slice(0,i):void 0;if(!n)return a&&(a===t||L[a]!==void 0)?B(r,t):{backendID:t,modelID:r,qualified:`${t}/${r}`};if(n.models.has(r))return B(r,t);if(n.models.has(`${t}/${r}`))return{backendID:t,modelID:r,qualified:`${t}/${r}`};if(a&&n.providers.has(a))return B(r,t);if(!a){let e=[...n.models].filter(e=>e.slice(e.indexOf(`/`)+1)===r);if(e.length===1)return B(e[0],t);if(e.length>1){let t=e.sort().slice(0,z);throw new R(`OpenCode model "${r}" is ambiguous on this host (${n.source} registry); qualify it as one of: ${t.join(`, `)}.`,t)}}let o=ge(r,n),s=o.length?` Did you mean: ${o.join(`, `)}?`:``;throw new R(`OpenCode model "${r}" is not available on this host (${n.source} registry: backend "${a??t}" is not a known opencode provider and no listed model matches).${s}`,o)}function ge(e,t){let n=e.slice(e.lastIndexOf(`/`)+1).toLowerCase();if(!n)return[];let r=[],i=[];for(let e of t.models){let t=e.slice(e.lastIndexOf(`/`)+1).toLowerCase();t===n?r.push(e):t.includes(n)&&i.push(e)}return[...r.sort(),...i.sort()].slice(0,z)}var _e=[`off`,`quiet`,`normal`,`verbose`];g().map(e=>e.id);var V=[`narration`,`tools`,`reasoning`,`memories`,`startup`,`injected`,`agentMessages`,`workflow`,`land`,`task`,`agents`,`other`,`undelivered`],ve=[`workflow`,`land`,`task`,`agents`,`other`];function H(e){return Object.fromEntries(V.map(t=>[t,e(t)]))}var U=H(e=>ve.includes(e)),W={calm:U,everything:H(()=>!0)};function ye(e){let t=e&&typeof e==`object`&&!Array.isArray(e)?e:{};return H(e=>typeof t[e]==`boolean`?t[e]:U[e])}function be(e){for(let[t,n]of Object.entries(W))if(V.every(t=>n[t]===e[t]))return t;return null}function xe(e,t){let n=e?.opencodeProviderID,r=t?.trim();if(!(!n||!r))return he(r,n).qualified}function Se(e){return!e?.disabled}var Ce=.1,we=.9,G=.8,K=.4,q=256e3,J=1e6;function Te(){return g().map(e=>({provider:e.id,label:e.label,models:[],...e.opencode?.opencodeProviderID?{opencodeProviderID:e.opencode.opencodeProviderID}:{},...e.launchModes?.length?{launchModes:[...e.launchModes]}:{},...e.effortSwitch?{effortSwitch:!0}:{}}))}function Ee(e){let t=De(e);return{selfCompactUtilization:t,warnUtilization:Oe(t),hardBackstopUtilization:Math.max(we,t)}}function De(e){return!Number.isFinite(e)||!e||e<=q?G:e>=J?K:Y(G-(e-q)/(J-q)*(G-K))}function Oe(e){return Y(Math.max(0,e-Ce))}function Y(e){return Math.round(e*1e3)/1e3}function X(e,t){if(e)return(t??Te()).find(t=>t.provider===e)}function ke(e,t,n={}){let r=(Array.isArray(t)?t:t?[t]:[]).map(e=>e.trim()).filter(Boolean);if(r.length){for(let t of r){let i=Ae(e,t,n.requireUnambiguous),a=je(e,i,r,n.observedWindowTokens);if(a)return a;if(i)return i}if(!(n.requireUnambiguous||n.exactOnly))for(let t of r){let n=e.models.find(e=>e.alias.startsWith(t+`-`));if(n)return n}}}function Ae(e,t,n=!1){let r=t.toLowerCase(),i=e.models.find(e=>e.alias===t)??e.models.find(e=>e.alias.toLowerCase()===r);if(i)return i;let a=e.models.filter(e=>e.providerModel.toLowerCase()===r);if(a.length>1&&n)throw Error(`ambiguous ${e.provider} provider model: ${t} (select an alias: ${a.map(e=>e.alias).join(`, `)})`);return a[0]}function je(e,t,n,r){if(!Number.isFinite(r)||!r)return;if(t?.limits?.contextWindowTokens?.value===r)return t;let i=new Set([...t?[t.alias,t.providerModel]:[],...n].map(Z));return e.models.find(e=>e.limits?.contextWindowTokens?.value===r&&(i.has(Z(e.alias))||i.has(Z(e.providerModel))))}function Z(e){return e.trim().toLowerCase().replace(/\[[^\]]+\]$/,``)}function Me(e){return!e.disabled&&!e.unavailable}function Ne(e){let t=e.defaultModel,n=t?e.models.find(e=>e.alias===t):void 0;return n&&Me(n)?{alias:n.alias,preferred:t,fellBack:!1}:{alias:void 0,preferred:t,fellBack:!0}}function Pe(e){return h(e)?.resetCredits?.supported===!0}var Q=[`bg-tone-warning/10 text-tone-warning-fg border-tone-warning/30`,`bg-tone-sky/10 text-tone-sky-fg border-tone-sky/30`,`bg-tone-violet/10 text-tone-violet-fg border-tone-violet/30`,`bg-tone-success/10 text-tone-success-fg border-tone-success/30`,`bg-tone-rose/10 text-tone-rose-fg border-tone-rose/30`];function Fe(e){let t=0;for(let n=0;n<e.length;n++)t=t*31+e.charCodeAt(n)>>>0;return t}var $=new Map(g().map((e,t)=>[e.id,Q[t%Q.length]]));function Ie(e){return e?h(e)?.label??e.charAt(0).toUpperCase()+e.slice(1):`Unknown provider`}function Le(e){let t=$.get(e);if(t)return t;let n=Q[Fe(e)%Q.length];return $.set(e,n),n}function Re(){return g().map(e=>e.id)}function ze(e){return h(e)}function Be(e,t){let n=e?.id||e?.alias;if(!e||!n)return;let r=X(e.provider,t),i=r?ke(r,[e.alias||``,n]):void 0;return{label:i?.label||n,...i?{entry:i}:{}}}export{o as A,se as C,te as D,a as E,n as M,e as N,c as O,t as P,ae as S,i as T,_,Pe as a,u as b,X as c,Ne as d,U as f,_e as g,ye as h,ze as i,r as j,ee as k,Se as l,be as m,Le as n,Be as o,W as p,Ie as r,Ee as s,Re as t,xe as u,d as v,s as w,re as x,l as y};
2
- //# sourceMappingURL=provider-display-BEeLXC_D.js.map