glimmervoid 0.43.2 → 0.43.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 (37) hide show
  1. package/dist/bin/glimmervoid.js +14 -14
  2. package/dist/chunks/{adapters-Ce0I__TH.js → adapters-C7wGqlhU.js} +1 -1
  3. package/dist/chunks/{adapters-CjtgWEdg.js → adapters-Du4HJLMG.js} +16 -10
  4. package/dist/chunks/{agent-api-cli-DYwXyAmN.js → agent-api-cli-BC2i4XNI.js} +1 -1
  5. package/dist/chunks/{agent-api-cli-B0fpc41n.js → agent-api-cli-DRTVOR2W.js} +2 -2
  6. package/dist/chunks/agent-api-core-9mdbvlfc.js +782 -0
  7. package/dist/chunks/{agent-setup-cli-NfJQxNdp.js → agent-setup-cli-DAPHGpRA.js} +1 -1
  8. package/dist/chunks/{control-messages-CD99vE0V.js → config-D0YwCXFd.js} +557 -2
  9. package/dist/chunks/{config-store-2noiIsTg.js → config-store-BpsH_oWP.js} +59 -5
  10. package/dist/chunks/config-store-DcJKvInM.js +1 -0
  11. package/dist/chunks/contracts-Dxc9Gp0Y.js +295 -0
  12. package/dist/chunks/{grok-DPmX1ozS.js → grok-2z-LqPHN.js} +2 -2
  13. package/dist/chunks/{main-BGJ7PAA2.js → main-Bzy6xXUF.js} +248 -468
  14. package/dist/chunks/{pair-cli-CPv7mDTg.js → pair-cli-DSZFFEkT.js} +2 -2
  15. package/dist/chunks/{remote-config-DZWZ5fVJ.js → remote-config-Cd_FC7bd.js} +1 -1
  16. package/dist/chunks/runtime-paths-Cc0_ZR6V.js +1 -0
  17. package/dist/chunks/{runtime-paths-BkeftE60.js → runtime-paths-ghcH9CeW.js} +1 -1
  18. package/dist/chunks/{session-routes-DdeSkLqC.js → session-routes-BQPy81dm.js} +6 -3
  19. package/dist/chunks/{settings-cli-4fX1olS3.js → settings-cli-DOpMn6-A.js} +5 -5
  20. package/dist/chunks/{settings-readout-core-NoTHBGL6.js → settings-readout-core-D1ZP4UIs.js} +1 -1
  21. package/dist/chunks/{ssh-sign-cli-CvqtQNQe.js → ssh-sign-cli-ynkhYkLs.js} +1 -1
  22. package/dist/chunks/{visions-cli-CVRB9IWA.js → visions-cli-COYRIdXy.js} +1 -1
  23. package/dist/chunks/{visions-setup-DB2P8JUL.js → visions-setup-VMMyqOpl.js} +2 -2
  24. package/dist/client/assets/{index-DEbBUagP.css → index-583DiM8X.css} +1 -1
  25. package/dist/client/assets/index-CsyFNXR2.js +177 -0
  26. package/dist/client/index.html +2 -2
  27. package/dist/server/index.js +2 -2
  28. package/dist/session/remote-setup/SKILL.md +120 -0
  29. package/dist/session/remote-setup/glimmervoid.service +20 -0
  30. package/dist/session/statusline-relay.js +1 -1
  31. package/dist/session/visions-relay.js +1 -1
  32. package/package.json +1 -1
  33. package/dist/chunks/agent-api-core-BeSecYrA.js +0 -336
  34. package/dist/chunks/config-store-DW0ONWV5.js +0 -1
  35. package/dist/chunks/contracts-CFm0dprb.js +0 -835
  36. package/dist/chunks/runtime-paths-DSmormp7.js +0 -1
  37. package/dist/client/assets/index-CNDdyYn0.js +0 -177
@@ -1,5 +1,5 @@
1
1
  import { a as isMissingFileError, r as errorMessage } from "./text-DoirglWV.js";
2
- import { a as classifyGrokHooksFile, o as renderGrokHooksFile, t as grok } from "./grok-DPmX1ozS.js";
2
+ import { a as classifyGrokHooksFile, o as renderGrokHooksFile, t as grok } from "./grok-2z-LqPHN.js";
3
3
  import { p as writeTextAtomicSync } from "./json-file-DFCTvPjj.js";
4
4
  import fs from "node:fs";
5
5
  import path from "node:path";
@@ -1,4 +1,6 @@
1
- import { $ as MyPrMergeWhenReadyResult, At as TeamReviewStatus, B as LinkedPr, C as PendingWakeup, D as SESSION_DOC_PATH_MAX_CHARS, Et as TeamReviewActionResult, G as MyPrKeepMergeableRequest, Gt as GithubPollingRefreshRequest, It as hasRequiredActionHead, Jt as githubPollingShape, K as MyPrKeepMergeableResult, Kt as GithubPollingRefreshResult, M as SessionDoc, N as SessionSnapshot, P as SessionState, Q as MyPrMergeWhenReadyRequest, R as TaskTitle, Tt as TeamReviewActionRequest, Ut as REPO_SLUG_RE, V as MyPr, Vt as GH_SEGMENT, X as MyPrMergeResult, Y as MyPrMergeRequest, at as MyPrsStatus, b as ConversationApproval, ct as repositoryName, et as MyPrSearchNode, lt as CommitSha, ot as SessionPrLinks, pt as GithubReviewDecision, qt as GithubPrsFreshness, st as pullRequestKeyFormat, v as CoherenceHooksState, vt as ReviewChecksState, x as ConversationApprovalDecision, y as ConversationAnswers, z as UnseenOutcome } from "./session-BUcx9uJa.js";
1
+ import { $ as MyPrMergeWhenReadyResult, At as TeamReviewStatus, B as LinkedPr, C as PendingWakeup, D as SESSION_DOC_PATH_MAX_CHARS, Et as TeamReviewActionResult, G as MyPrKeepMergeableRequest, Gt as GithubPollingRefreshRequest, It as hasRequiredActionHead, Jt as githubPollingShape, K as MyPrKeepMergeableResult, Kt as GithubPollingRefreshResult, M as SessionDoc, N as SessionSnapshot, P as SessionState, Q as MyPrMergeWhenReadyRequest, R as TaskTitle, Tt as TeamReviewActionRequest, Ut as REPO_SLUG_RE, V as MyPr, Vt as GH_SEGMENT, Wt as repoParts, X as MyPrMergeResult, Y as MyPrMergeRequest, at as MyPrsStatus, b as ConversationApproval, ct as repositoryName, et as MyPrSearchNode, lt as CommitSha, ot as SessionPrLinks, pt as GithubReviewDecision, qt as GithubPrsFreshness, st as pullRequestKeyFormat, v as CoherenceHooksState, vt as ReviewChecksState, x as ConversationApprovalDecision, y as ConversationAnswers, z as UnseenOutcome } from "./session-BUcx9uJa.js";
2
+ import { n as isRecord } from "./coerce-NSst8oRP.js";
3
+ import path from "node:path";
2
4
  import { z } from "zod";
3
5
  //#region shared/contracts/issues.ts
4
6
  var IssueRepoSlug = z.string().regex(REPO_SLUG_RE);
@@ -1541,6 +1543,10 @@ var clientVariants = [
1541
1543
  loose("ping", { requestId }),
1542
1544
  loose("get-settings", { requestId }),
1543
1545
  loose("get-agent-logins", { requestId }),
1546
+ loose("start-remote-setup", {
1547
+ agent: ConnectableAgent,
1548
+ requestId
1549
+ }),
1544
1550
  loose("agent-connect", {
1545
1551
  agent: ConnectableAgent,
1546
1552
  action: z.enum(["start", "cancel"]),
@@ -1710,6 +1716,7 @@ Object.freeze([
1710
1716
  "hooks-report",
1711
1717
  "save-hook-result",
1712
1718
  "add-session-result",
1719
+ "start-remote-setup-result",
1713
1720
  "remove-session-result",
1714
1721
  "agent-logins",
1715
1722
  "delete-hook-result",
@@ -1852,6 +1859,13 @@ var serverVariants = [
1852
1859
  logins: AgentLoginStatuses,
1853
1860
  error: optionalError
1854
1861
  }),
1862
+ loose("start-remote-setup-result", {
1863
+ requestId,
1864
+ ok: z.boolean(),
1865
+ error: optionalError,
1866
+ sessionId: z.string().optional(),
1867
+ sessionName: z.string().optional()
1868
+ }),
1855
1869
  loose("delete-hook-result", {
1856
1870
  requestId,
1857
1871
  ok: z.boolean(),
@@ -2359,4 +2373,545 @@ var serverVariants = [
2359
2373
  ];
2360
2374
  z.discriminatedUnion("type", serverVariants);
2361
2375
  //#endregion
2362
- export { TASK_TITLE_TIMEOUT_RANGE as $, BRANCH_GC_STALE_DAYS_RANGE as A, GithubIssueResponse as At, POSTHOG_ESCALATION_RANGE as B, comparablePrKey as C, PLAN_RESULT_HOOK_EVENT as Ct, WorkflowsSettingsUpdate as D, parseExitPlanModeHookPayload as Dt, WorkflowsSettings as E, PlanRevision as Et, KEEP_MERGEABLE_TIMEOUT_MINUTES_RANGE as F, IssuesStatus as Ft, POSTHOG_MIN_USERS_RANGE as G, POSTHOG_INTERVAL_RANGE as H, MEMORY_RESERVE_MB_RANGE as I, issuePullRequestStateFromGithub as It, POSTHOG_TRAFFIC_COOLDOWN_RANGE as J, POSTHOG_RECURRENCE_WINDOW_RANGE as K, NON_NEGATIVE_NUMBER_RANGE as L, FLYING_ANIMALS_DURATION_RANGE as M, IssueUpdate as Mt, FLYING_ANIMALS_GAP_RANGE as N, IssuesSearchResponse as Nt, WorkflowsState as O, planTitle as Ot, FLYING_ANIMALS_SCALE_RANGE as P, IssuesState as Pt, REPLAY_BUFFER_KB_RANGE as Q, PORT_RANGE as R, GithubPrsFrame as S, PLAN_HOOK_OUTPUT_MAX_CHARS as St, WorkflowLabelName as T, PlanDecision as Tt, POSTHOG_INVESTIGATION_TIMEOUT_RANGE as U, POSTHOG_FIX_TIMEOUT_RANGE as V, POSTHOG_MAX_CONCURRENT_RANGE as W, POSTHOG_TRAFFIC_MULTIPLIER_RANGE as X, POSTHOG_TRAFFIC_MIN_USERS_RANGE as Y, POSTHOG_TRANSIENT_RECURRENCE_RANGE as Z, MinedPrReviewData as _, CoherenceJournalOutput as _t, OPERATOR_ACTIONS_BY_SURFACE as a, VISIONS_COOLDOWN_MS_RANGE as at, GithubPrKey as b, PLAN_BODY_CAP_BYTES as bt, BenchmarkActionRequest as c, VISIONS_MAX_PER_HOUR_RANGE as ct, BenchmarkJudgement as d, WORKFLOWS_MAX_CONCURRENT_SESSIONS_RANGE as dt, USAGE_BUDGET_RANGE as et, BenchmarkRun as f, UpdateJournal as ft, MergedPrListing as g, TraceRecord as gt, CommitComparison as h, TraceCheckpoint as ht, InstallFlavor as i, VISIONS_ACTIVITY_MAX_PER_HOUR_RANGE as it, FLYING_ANIMALS_DEFAULTS as j, IssueKey as jt, BRANCH_GC_INTERVAL_MS_RANGE as k, GithubIssuePullRequestsRepository as kt, BenchmarkCase as l, VISIONS_QUIET_MS_RANGE as lt, BenchmarkSuite as m, MAX_RAW_LINE_CHARS as mt, ClientMessage as n, USAGE_RETAIN_DAYS_RANGE as nt, OPERATOR_SURFACES as o, VISIONS_DISPATCH_TIMEOUT_RANGE as ot, BenchmarkStatus as p, SessionSetup as pt, POSTHOG_TRAFFIC_BASELINE_RANGE as q, DASHBOARD_VIEWS as r, USAGE_SCAN_INTERVAL_RANGE as rt, pullRequestKeyFromReference as s, VISIONS_INTENT_THREAD_TTL_MS_RANGE as st, CONTROL_FRAME_MAX_BYTES as t, USAGE_INTEGER_RANGES as tt, BenchmarkId as u, WORKFLOWS_MAX_ACTIONS_PER_POLL_RANGE as ut, PrCheckoutCaseInput as v, ChangeMap as vt, WorkflowCommentBody as w, PLAN_TOOL_NAME as wt, GithubPrLightSearchNode as x, PLAN_HOOK_EVENT as xt, GithubPrDetailNode as y, changeMapFactId as yt, POSITIVE_NUMBER_RANGE as z };
2376
+ //#region shared/contracts/config-numbers-core.ts
2377
+ var POSTHOG_WHOLE_NUMBER_ROUNDING = {
2378
+ maxConcurrentInvestigations: Math.ceil,
2379
+ minUsersToInvestigate: Math.ceil,
2380
+ userEscalationThreshold: Math.ceil,
2381
+ trafficSpikeMinUsers: Math.ceil,
2382
+ trafficSpikeBaselineDays: Math.floor
2383
+ };
2384
+ var LEGACY_INTEGER_FIELDS = [
2385
+ {
2386
+ path: [
2387
+ "visions",
2388
+ "dispatch",
2389
+ "quietMs"
2390
+ ],
2391
+ min: 1,
2392
+ round: Math.floor
2393
+ },
2394
+ {
2395
+ path: [
2396
+ "visions",
2397
+ "dispatch",
2398
+ "cooldownMs"
2399
+ ],
2400
+ min: 1,
2401
+ round: Math.floor
2402
+ },
2403
+ {
2404
+ path: [
2405
+ "visions",
2406
+ "dispatch",
2407
+ "maxPerHour"
2408
+ ],
2409
+ min: 1,
2410
+ round: Math.floor
2411
+ },
2412
+ {
2413
+ path: [
2414
+ "visions",
2415
+ "dispatch",
2416
+ "activityMaxPerHour"
2417
+ ],
2418
+ min: 0,
2419
+ round: Math.floor
2420
+ },
2421
+ {
2422
+ path: [
2423
+ "visions",
2424
+ "dispatch",
2425
+ "dispatchTimeoutSeconds"
2426
+ ],
2427
+ min: 1,
2428
+ round: Math.floor
2429
+ },
2430
+ {
2431
+ path: [
2432
+ "visions",
2433
+ "intent",
2434
+ "threadTtlMs"
2435
+ ],
2436
+ min: 1,
2437
+ round: Math.floor
2438
+ },
2439
+ ...Object.entries(POSTHOG_WHOLE_NUMBER_ROUNDING).map(([key, round]) => ({
2440
+ path: ["posthog", key],
2441
+ min: 1,
2442
+ round
2443
+ }))
2444
+ ];
2445
+ function normalizeIntegerField(config, path, min, round) {
2446
+ let target = config;
2447
+ for (const segment of path.slice(0, -1)) {
2448
+ const block = target[segment];
2449
+ if (!isRecord(block)) return;
2450
+ target[segment] = { ...block };
2451
+ target = target[segment];
2452
+ }
2453
+ const key = path.at(-1);
2454
+ const value = target[key];
2455
+ if (typeof value !== "number" || !Number.isFinite(value) || value < 0) return;
2456
+ if (Number.isInteger(value)) return;
2457
+ target[key] = Math.min(Number.MAX_SAFE_INTEGER, Math.max(min, round(value)));
2458
+ }
2459
+ function normalizeLegacyConfigNumbers(candidate) {
2460
+ const normalized = { ...candidate };
2461
+ const replayBufferKB = candidate.replayBufferKB;
2462
+ if (typeof replayBufferKB === "number" && Number.isFinite(replayBufferKB) && replayBufferKB >= 0 && replayBufferKB <= REPLAY_BUFFER_KB_RANGE.max) normalized.replayBufferKB = Math.max(REPLAY_BUFFER_KB_RANGE.min, Math.floor(replayBufferKB));
2463
+ for (const { path, min, round } of LEGACY_INTEGER_FIELDS) normalizeIntegerField(normalized, path, min, round);
2464
+ return normalized;
2465
+ }
2466
+ //#endregion
2467
+ //#region shared/usage-config.ts
2468
+ var USAGE_COST_MODES = Object.freeze([
2469
+ "auto",
2470
+ "calculate",
2471
+ "display"
2472
+ ]);
2473
+ var USAGE_VENDOR_KEYS = Object.freeze(["codex", "grok"]);
2474
+ var USAGE_BUDGET_KEYS = Object.freeze(["dailyUsd", "monthlyUsd"]);
2475
+ //#endregion
2476
+ //#region shared/contracts/browser-config.ts
2477
+ var optionalBoolean = (field) => z.boolean({ error: `${field} must be a boolean` }).optional();
2478
+ var optionalString = (field, trim = false) => {
2479
+ const schema = z.string({ error: `${field} must be a string` });
2480
+ return (trim ? schema.transform((value) => value.trim()) : schema).optional();
2481
+ };
2482
+ var numberRangeLabel = (range) => {
2483
+ if (range.label) return range.label;
2484
+ if (range.max != null) return `between ${range.min} and ${range.max}`;
2485
+ if (range.exclusiveMin) return `greater than ${range.min}`;
2486
+ return `at least ${range.min}`;
2487
+ };
2488
+ var optionalNumber = (field, range = POSITIVE_NUMBER_RANGE) => z.number({ error: `${field} must be ${numberRangeLabel(range)}` }).finite().refine((value) => !range.exclusiveMin || value > range.min, { message: `${field} must be ${numberRangeLabel(range)}` }).refine((value) => range.exclusiveMin || value >= range.min, { message: `${field} must be ${numberRangeLabel(range)}` }).refine((value) => range.max == null || value <= range.max, { message: `${field} must be ${numberRangeLabel(range)}` }).optional();
2489
+ var optionalWholeNumber = (field, range) => optionalNumber(field, range).unwrap().int({ error: `${field} must be a whole number ${numberRangeLabel(range)}` }).optional();
2490
+ var optionalInteger = (field, range) => z.number({ error: `${field} must be an integer between ${range.min} and ${range.max}` }).int({ error: `${field} must be an integer between ${range.min} and ${range.max}` }).min(range.min, { error: `${field} must be an integer between ${range.min} and ${range.max}` }).max(range.max, { error: `${field} must be an integer between ${range.min} and ${range.max}` }).optional();
2491
+ var optionalObject = (field, shape) => z.object(shape, { error: `${field} must be an object` }).nullable().optional();
2492
+ var optionalLooseObject = (field) => z.object({}, { error: `${field} must be an object` }).passthrough().nullable().optional();
2493
+ var UPDATE_CHANNELS = Object.freeze(["release", "main"]);
2494
+ var POST_TURN_CHECK_MODES = Object.freeze(["report", "fix"]);
2495
+ var TaskTitleSettings = z.object({ refiner: z.object({
2496
+ enabled: optionalBoolean("taskTitle.refiner.enabled"),
2497
+ model: optionalString("taskTitle.refiner.model", true),
2498
+ minIntervalSeconds: optionalNumber("taskTitle.refiner.minIntervalSeconds", { min: 0 }),
2499
+ timeoutSeconds: optionalNumber("taskTitle.refiner.timeoutSeconds", TASK_TITLE_TIMEOUT_RANGE)
2500
+ }, { error: "taskTitle.refiner must be an object" }).nullable().optional() }, { error: "taskTitle must be an object" }).nullable().optional();
2501
+ var BRANCH_GC_SETTINGS_SHAPE = {
2502
+ enabled: optionalBoolean("branchGc.enabled"),
2503
+ worktrees: optionalBoolean("branchGc.worktrees"),
2504
+ prefixes: z.array(z.string({ error: "branchGc.prefixes must be an array of strings" }).min(1, { error: "branchGc.prefixes entries must be non-empty strings" }), { error: "branchGc.prefixes must be an array of strings" }).optional(),
2505
+ dryRun: optionalBoolean("branchGc.dryRun"),
2506
+ staleDays: optionalNumber("branchGc.staleDays", BRANCH_GC_STALE_DAYS_RANGE),
2507
+ deleteUnmerged: optionalBoolean("branchGc.deleteUnmerged"),
2508
+ intervalMs: optionalNumber("branchGc.intervalMs", BRANCH_GC_INTERVAL_MS_RANGE)
2509
+ };
2510
+ var BranchGcFileSettings = z.object(BRANCH_GC_SETTINGS_SHAPE, { error: "branchGc must be an object" });
2511
+ var BranchGcSettings = optionalObject("branchGc", BRANCH_GC_SETTINGS_SHAPE);
2512
+ var BranchGcControlSettings = BranchGcFileSettings.omit({
2513
+ prefixes: true,
2514
+ dryRun: true,
2515
+ worktrees: true
2516
+ }).nullable().optional();
2517
+ Object.freeze(["enabled", "deleteUnmerged"]);
2518
+ Object.freeze(["staleDays", "intervalMs"]);
2519
+ var PostTurnChecksSettings = optionalObject("postTurnChecks", { mode: z.enum(POST_TURN_CHECK_MODES, { error: "postTurnChecks.mode must be one of report, fix" }).optional() });
2520
+ var VisionsSettings = optionalObject("visions", {
2521
+ enabled: optionalBoolean("visions.enabled"),
2522
+ autoFix: optionalBoolean("visions.autoFix"),
2523
+ projects: z.array(z.string({ error: "visions.projects must be an array of strings" }), { error: "visions.projects must be an array of strings" }).optional(),
2524
+ dispatch: optionalObject("visions.dispatch", {
2525
+ enabled: optionalBoolean("visions.dispatch.enabled"),
2526
+ model: optionalString("visions.dispatch.model", true),
2527
+ quietMs: optionalWholeNumber("visions.dispatch.quietMs", VISIONS_QUIET_MS_RANGE),
2528
+ cooldownMs: optionalWholeNumber("visions.dispatch.cooldownMs", VISIONS_COOLDOWN_MS_RANGE),
2529
+ maxPerHour: optionalWholeNumber("visions.dispatch.maxPerHour", VISIONS_MAX_PER_HOUR_RANGE),
2530
+ activityMaxPerHour: optionalWholeNumber("visions.dispatch.activityMaxPerHour", VISIONS_ACTIVITY_MAX_PER_HOUR_RANGE),
2531
+ dispatchTimeoutSeconds: optionalWholeNumber("visions.dispatch.dispatchTimeoutSeconds", VISIONS_DISPATCH_TIMEOUT_RANGE)
2532
+ }),
2533
+ intent: optionalObject("visions.intent", { threadTtlMs: optionalWholeNumber("visions.intent.threadTtlMs", VISIONS_INTENT_THREAD_TTL_MS_RANGE) })
2534
+ });
2535
+ var GithubSettings = z.object({ teams: z.array(z.string({ error: "github.teams must be an array of org/slug strings" }).refine((team) => repoParts(team) !== null, { message: "github.teams entries must be org/slug with valid GitHub segments" }), { error: "github.teams must be an array of org/slug strings" }).optional() }, { error: "github must be an object" }).nullable().optional();
2536
+ var TeamReviewSettings = optionalObject("teamReview", {
2537
+ enabled: optionalBoolean("teamReview.enabled"),
2538
+ autoRebaseMyPrs: optionalBoolean("teamReview.autoRebaseMyPrs"),
2539
+ keepMergeableEnabled: optionalBoolean("teamReview.keepMergeableEnabled"),
2540
+ mergeQueueEnabled: optionalBoolean("teamReview.mergeQueueEnabled"),
2541
+ keepMergeableTimeoutMinutes: optionalInteger("teamReview.keepMergeableTimeoutMinutes", KEEP_MERGEABLE_TIMEOUT_MINUTES_RANGE),
2542
+ org: optionalString("teamReview.org", true),
2543
+ team: optionalString("teamReview.team", true),
2544
+ skill: optionalString("teamReview.skill", true),
2545
+ reReviewAfterHours: optionalNumber("teamReview.reReviewAfterHours"),
2546
+ skipIdleAfterDays: optionalNumber("teamReview.skipIdleAfterDays")
2547
+ });
2548
+ var BenchmarksSettings = optionalObject("benchmarks", { enabled: optionalBoolean("benchmarks.enabled") });
2549
+ var CoherenceSettings = optionalObject("coherence", { enabled: optionalBoolean("coherence.enabled") });
2550
+ var posthogNumberRanges = {
2551
+ intervalMinutes: POSTHOG_INTERVAL_RANGE,
2552
+ maxConcurrentInvestigations: POSTHOG_MAX_CONCURRENT_RANGE,
2553
+ investigationTimeoutSeconds: POSTHOG_INVESTIGATION_TIMEOUT_RANGE,
2554
+ fixTimeoutSeconds: POSTHOG_FIX_TIMEOUT_RANGE,
2555
+ minUsersToInvestigate: POSTHOG_MIN_USERS_RANGE,
2556
+ userEscalationThreshold: POSTHOG_ESCALATION_RANGE,
2557
+ recurrenceWindowDays: POSTHOG_RECURRENCE_WINDOW_RANGE,
2558
+ transientRecurrenceLimit: POSTHOG_TRANSIENT_RECURRENCE_RANGE,
2559
+ trafficSpikeMultiplier: POSTHOG_TRAFFIC_MULTIPLIER_RANGE,
2560
+ trafficSpikeMinUsers: POSTHOG_TRAFFIC_MIN_USERS_RANGE,
2561
+ trafficSpikeCooldownMinutes: POSTHOG_TRAFFIC_COOLDOWN_RANGE,
2562
+ trafficSpikeBaselineDays: POSTHOG_TRAFFIC_BASELINE_RANGE
2563
+ };
2564
+ var PosthogSettings = optionalObject("posthog", {
2565
+ enabled: optionalBoolean("posthog.enabled"),
2566
+ recurrenceDedupe: optionalBoolean("posthog.recurrenceDedupe"),
2567
+ trafficSpikeEnabled: optionalBoolean("posthog.trafficSpikeEnabled"),
2568
+ autoFix: optionalBoolean("posthog.autoFix"),
2569
+ host: optionalString("posthog.host", true).refine((value) => value == null || !value || /^https?:\/\//i.test(value), { message: "posthog.host must be an http(s) URL" }),
2570
+ apiKey: optionalString("posthog.apiKey", true),
2571
+ repoPath: optionalString("posthog.repoPath", true),
2572
+ projects: z.union([z.literal("all"), z.array(z.number({ error: "posthog.projects must be \"all\" or an array of positive integer project ids" }).int({ error: "posthog.projects must be \"all\" or an array of positive integer project ids" }).positive({ error: "posthog.projects must be \"all\" or an array of positive integer project ids" }), { error: "posthog.projects must be \"all\" or an array of positive integer project ids" })], { error: "posthog.projects must be \"all\" or an array of positive integer project ids" }).optional(),
2573
+ projectMap: z.record(z.string(), z.unknown(), { error: "posthog.projectMap must be an object" }).optional(),
2574
+ ...Object.fromEntries(Object.entries(posthogNumberRanges).map(([key, range]) => [key, Object.hasOwn(POSTHOG_WHOLE_NUMBER_ROUNDING, key) ? optionalWholeNumber(`posthog.${key}`, range) : optionalNumber(`posthog.${key}`, range)]))
2575
+ });
2576
+ var usageCostModeMessage = `usage.costMode must be one of ${USAGE_COST_MODES.join(", ")}`;
2577
+ var usageVendorShape = Object.fromEntries(USAGE_VENDOR_KEYS.map((key) => [key, optionalBoolean(`usage.vendors.${key}`)]));
2578
+ var usageBudgetShape = Object.fromEntries(USAGE_BUDGET_KEYS.map((key) => [key, z.number({ error: `usage.budget.${key} must be a positive number or null` }).positive({ error: `usage.budget.${key} must be a positive number or null` }).nullable().optional()]));
2579
+ var createUsageSettings = (isAbsolutePath) => optionalObject("usage", {
2580
+ enabled: optionalBoolean("usage.enabled"),
2581
+ fetchPricing: optionalBoolean("usage.fetchPricing"),
2582
+ planLimits: optionalBoolean("usage.planLimits"),
2583
+ rtkSavings: optionalBoolean("usage.rtkSavings"),
2584
+ scanIntervalMinutes: optionalInteger("usage.scanIntervalMinutes", USAGE_INTEGER_RANGES.scanIntervalMinutes),
2585
+ retainDays: optionalInteger("usage.retainDays", USAGE_INTEGER_RANGES.retainDays),
2586
+ warehouseRetainDays: optionalInteger("usage.warehouseRetainDays", USAGE_INTEGER_RANGES.warehouseRetainDays),
2587
+ sessionBlockHours: optionalInteger("usage.sessionBlockHours", USAGE_INTEGER_RANGES.sessionBlockHours),
2588
+ costMode: z.enum(USAGE_COST_MODES, { error: usageCostModeMessage }).optional(),
2589
+ vendors: optionalObject("usage.vendors", usageVendorShape),
2590
+ budget: optionalObject("usage.budget", usageBudgetShape),
2591
+ extraProjectsDirs: z.array(z.string({ error: "usage.extraProjectsDirs must be an array of absolute paths" }), { error: "usage.extraProjectsDirs must be an array of absolute paths" }).transform((directories) => directories.map((directory) => directory.trim())).refine((directories) => directories.every((directory) => directory && isAbsolutePath(directory)), { message: "usage.extraProjectsDirs entries must be absolute paths" }).optional()
2592
+ });
2593
+ var TelegramSettings = optionalObject("telegram", {
2594
+ botToken: optionalString("telegram.botToken", true),
2595
+ chatId: optionalString("telegram.chatId", true)
2596
+ });
2597
+ var IngestSettings = z.object({ enabled: optionalBoolean("ingest.enabled") }, { error: "ingest must be an object" }).passthrough().optional();
2598
+ var TraceSettings = z.object({ enabled: optionalBoolean("trace.enabled") }, { error: "trace must be an object" }).optional();
2599
+ var PlanReviewSettings = z.object({ enabled: optionalBoolean("planReview.enabled") }, { error: "planReview must be an object" }).optional();
2600
+ var optionalPathList = (field) => z.array(z.string({ error: `${field} must be an array of paths` }).trim().min(1, { error: `${field} must be an array of paths` }), { error: `${field} must be an array of paths` }).optional();
2601
+ var guardrailsShape = {
2602
+ unguardedRepos: optionalPathList("guardrails.unguardedRepos"),
2603
+ blockedPaths: optionalPathList("guardrails.blockedPaths"),
2604
+ unreadablePaths: optionalPathList("guardrails.unreadablePaths")
2605
+ };
2606
+ var isHomeRelativePath = (entry) => entry === "~" || entry.startsWith("~/") || entry.startsWith("~\\");
2607
+ var createGuardrailsSettings = (isAbsolutePath) => z.object({
2608
+ ...guardrailsShape,
2609
+ blockedPaths: z.array(z.string({ error: "guardrails.blockedPaths must be an array of paths" }).trim().min(1, { error: "guardrails.blockedPaths must be an array of paths" }).refine((entry) => isHomeRelativePath(entry) || isAbsolutePath(entry), { message: "guardrails.blockedPaths entries must be absolute paths or start with ~/" }), { error: "guardrails.blockedPaths must be an array of paths" }).optional()
2610
+ }, { error: "guardrails must be an object" }).strict().optional();
2611
+ var GuardrailsFileSettings = z.object(guardrailsShape, { error: "guardrails must be an object" }).passthrough().optional();
2612
+ var telemetryShape = { enabled: optionalBoolean("telemetry.enabled") };
2613
+ var TelemetrySettings = z.object(telemetryShape, { error: "telemetry must be an object" }).strict().optional();
2614
+ var TelemetryFileSettings = z.object(telemetryShape, { error: "telemetry must be an object" }).passthrough().optional();
2615
+ var createBrowserConfigShape = (isAbsolutePath) => ({
2616
+ port: z.number().int().min(PORT_RANGE.min).max(PORT_RANGE.max).optional(),
2617
+ notifyDebounceMs: z.number().finite().nonnegative().optional(),
2618
+ phoneEscalationMs: z.number().finite().nonnegative().optional(),
2619
+ replayBufferKB: optionalWholeNumber("replayBufferKB", REPLAY_BUFFER_KB_RANGE),
2620
+ sessionMemoryReserveMB: optionalWholeNumber("sessionMemoryReserveMB", MEMORY_RESERVE_MB_RANGE),
2621
+ cursorBlink: optionalBoolean("cursorBlink"),
2622
+ debugMode: optionalBoolean("debugMode"),
2623
+ conversationView: optionalBoolean("conversationView"),
2624
+ streamerMode: optionalBoolean("streamerMode"),
2625
+ zenView: optionalBoolean("zenView"),
2626
+ viewTabOrder: z.array(z.string({ error: "viewTabOrder must be an array of view ids" }), { error: "viewTabOrder must be an array of view ids" }).optional(),
2627
+ remoteSessions: optionalBoolean("remoteSessions"),
2628
+ detectBackgroundAgents: optionalBoolean("detectBackgroundAgents"),
2629
+ recordSignals: optionalBoolean("recordSignals"),
2630
+ rtk: optionalBoolean("rtk"),
2631
+ saneYolo: optionalBoolean("saneYolo"),
2632
+ skipPermissionsByDefault: optionalBoolean("skipPermissionsByDefault"),
2633
+ checkForUpdates: optionalBoolean("checkForUpdates"),
2634
+ updateChannel: z.enum(UPDATE_CHANNELS, { error: "updateChannel must be one of release, main" }).optional(),
2635
+ autoResume: optionalBoolean("autoResume"),
2636
+ telegramNotifications: optionalBoolean("telegramNotifications"),
2637
+ integrationBranch: optionalString("integrationBranch").nullable(),
2638
+ worktreeRoot: optionalString("worktreeRoot"),
2639
+ worktreeShare: z.array(z.string()).optional(),
2640
+ repoRoots: z.array(z.string()).optional(),
2641
+ taskTitle: TaskTitleSettings,
2642
+ branchGc: BranchGcSettings,
2643
+ postTurnChecks: PostTurnChecksSettings,
2644
+ visions: VisionsSettings,
2645
+ github: GithubSettings,
2646
+ teamReview: TeamReviewSettings,
2647
+ benchmarks: BenchmarksSettings,
2648
+ coherence: CoherenceSettings,
2649
+ posthog: PosthogSettings,
2650
+ usage: createUsageSettings(isAbsolutePath),
2651
+ telegram: TelegramSettings,
2652
+ ingest: IngestSettings,
2653
+ guardrails: createGuardrailsSettings(isAbsolutePath),
2654
+ telemetry: TelemetrySettings,
2655
+ workflows: WorkflowsSettings.nullable().optional()
2656
+ });
2657
+ var createBrowserConfig = (isAbsolutePath) => z.object(createBrowserConfigShape(isAbsolutePath));
2658
+ //#endregion
2659
+ //#region shared/contracts/config.ts
2660
+ var BrowserConfig = createBrowserConfig(path.isAbsolute);
2661
+ var BROWSER_CONFIG_SHAPE = BrowserConfig.shape;
2662
+ var ConfigUpdate = z.object({
2663
+ ...BROWSER_CONFIG_SHAPE,
2664
+ notifyDebounceMs: z.number({ error: "notifyDebounceMs must be a positive number" }).finite().positive({ error: "notifyDebounceMs must be a positive number" }).optional(),
2665
+ phoneEscalationMs: z.number({ error: "phoneEscalationMs must be a positive number" }).finite().positive({ error: "phoneEscalationMs must be a positive number" }).optional(),
2666
+ branchGc: BranchGcControlSettings,
2667
+ worktreeAutoRebase: optionalBoolean("worktreeAutoRebase"),
2668
+ worktreeSyncOnStart: optionalBoolean("worktreeSyncOnStart"),
2669
+ worktreeRerere: optionalBoolean("worktreeRerere"),
2670
+ workflows: WorkflowsSettingsUpdate.optional()
2671
+ }).omit({
2672
+ port: true,
2673
+ worktreeShare: true
2674
+ }).strict();
2675
+ var AGENT_ID_RE = /^[a-z][a-z0-9-]{1,31}$/;
2676
+ var BUILTIN_AGENT_IDS = Object.freeze([
2677
+ "claude-code",
2678
+ "codex",
2679
+ "grok"
2680
+ ]);
2681
+ var AGENT_ID_SHAPE_MESSAGE = "an agent id of 2 to 32 characters of lowercase letters, digits and dashes, starting with a letter";
2682
+ var AGENT_COMMAND_BASENAME_RE = /^[A-Za-z0-9._+-]+$/;
2683
+ var AGENT_COMMAND_ABSOLUTE_RE = /^(?:\/|[A-Za-z]:[\\/])[A-Za-z0-9._+\-\\/]*[A-Za-z0-9._+-]$/;
2684
+ var AGENT_COMMAND_SHAPE_MESSAGE = "a bare command name or an absolute path, built only from letters, digits, dot, underscore, plus, dash and path separators";
2685
+ function isSpawnableCommand(command) {
2686
+ if (AGENT_COMMAND_BASENAME_RE.test(command)) return true;
2687
+ return AGENT_COMMAND_ABSOLUTE_RE.test(command);
2688
+ }
2689
+ var GIT_BRANCH_FORBIDDEN_PUNCTUATION_RE = /[~^:?*[\\]/;
2690
+ var GIT_BRANCH_FORBIDDEN_SEQUENCES = [
2691
+ "..",
2692
+ "@{",
2693
+ "//"
2694
+ ];
2695
+ function isControlOrSpaceCharacter(character) {
2696
+ const codePoint = character.charCodeAt(0);
2697
+ return codePoint <= 32 || codePoint === 127;
2698
+ }
2699
+ function isGitBranchName(name) {
2700
+ if (name === "" || name === "@" || name === "HEAD") return false;
2701
+ if (name.startsWith("-") || name.startsWith("/") || name.endsWith("/") || name.endsWith(".")) return false;
2702
+ if (GIT_BRANCH_FORBIDDEN_SEQUENCES.some((sequence) => name.includes(sequence))) return false;
2703
+ if (GIT_BRANCH_FORBIDDEN_PUNCTUATION_RE.test(name) || [...name].some(isControlOrSpaceCharacter)) return false;
2704
+ return name.split("/").every((component) => !component.startsWith(".") && !component.endsWith(".lock"));
2705
+ }
2706
+ var CODER_WORKSPACE_NAME_RE = /^gv-[0-9a-f]{12}$/;
2707
+ var CODER_ENVIRONMENT_NAME_RE = /^[a-z][a-z0-9-]{0,31}$/;
2708
+ var CODER_STOP_AFTER_RE = /^[1-9][0-9]*[hm]$/;
2709
+ var absolutePosixPath = (field) => z.string({ error: `${field} must be a string` }).refine((value) => path.posix.isAbsolute(value), { error: `${field} must be an absolute path` });
2710
+ var positiveInteger = (field) => z.number({ error: `${field} must be a number` }).int({ error: `${field} must be a whole number` }).positive({ error: `${field} must be positive` });
2711
+ var PARAMETERS_MESSAGE = "coder.environments[].parameters must map names to strings";
2712
+ var CoderEnvironment = z.object({
2713
+ name: z.string({ error: "coder.environments[].name must be a string" }).regex(CODER_ENVIRONMENT_NAME_RE, { error: "coder.environments[].name must be 1 to 32 lowercase letters, digits and dashes, starting with a letter" }),
2714
+ template: z.string({ error: "coder.environments[].template must be a string" }).min(1, { error: "coder.environments[].template must not be empty" }).refine((value) => !value.startsWith("-"), { error: "coder.environments[].template must not start with a dash" }),
2715
+ parameters: z.record(z.string(), z.string({ error: PARAMETERS_MESSAGE }), { error: PARAMETERS_MESSAGE }).optional(),
2716
+ nodePath: absolutePosixPath("coder.environments[].nodePath"),
2717
+ checkoutRoot: absolutePosixPath("coder.environments[].checkoutRoot"),
2718
+ readyUrl: z.url({
2719
+ protocol: /^https?$/,
2720
+ error: "coder.environments[].readyUrl must be an http or https URL"
2721
+ }).optional(),
2722
+ idleStopMinutes: positiveInteger("coder.environments[].idleStopMinutes").optional(),
2723
+ stopAfter: z.string().regex(CODER_STOP_AFTER_RE, { error: "coder.environments[].stopAfter must be a duration like 4h or 90m" }).optional(),
2724
+ maxLive: positiveInteger("coder.environments[].maxLive").optional(),
2725
+ deleteAfterStoppedDays: positiveInteger("coder.environments[].deleteAfterStoppedDays").optional(),
2726
+ hourlyCostUsd: z.number({ error: "coder.environments[].hourlyCostUsd must be a number" }).nonnegative({ error: "coder.environments[].hourlyCostUsd must not be negative" }).optional()
2727
+ }).strict();
2728
+ var CoderSettings = z.object({
2729
+ appSlug: z.string().optional(),
2730
+ environments: z.array(CoderEnvironment).optional().refine((environments) => {
2731
+ const names = (environments ?? []).map((environment) => environment.name);
2732
+ return new Set(names).size === names.length;
2733
+ }, { error: "coder.environments[].name must be unique" })
2734
+ }).loose().optional();
2735
+ var PORT_MESSAGE = "projects[].environment.remotePort must be a port from 1 to 65535";
2736
+ var ProjectEnvironment = z.object({
2737
+ name: z.string().regex(CODER_ENVIRONMENT_NAME_RE, { error: "projects[].environment.name must name a coder environment" }),
2738
+ workspace: z.string().regex(CODER_WORKSPACE_NAME_RE, { error: "projects[].environment.workspace must be gv- and 12 hex digits" }),
2739
+ remotePort: z.number({ error: PORT_MESSAGE }).int({ error: PORT_MESSAGE }).min(1, { error: PORT_MESSAGE }).max(65535, { error: PORT_MESSAGE }),
2740
+ branch: z.string().refine(isGitBranchName, { error: "projects[].environment.branch must be a git branch name" })
2741
+ }).strict();
2742
+ var CustomAgentDeclaration = z.object({
2743
+ id: z.string({ error: "customAgents[].id must be a string" }).regex(AGENT_ID_RE, { error: `customAgents[].id must be ${AGENT_ID_SHAPE_MESSAGE}` }),
2744
+ label: z.string({ error: "customAgents[].label must be a string" }).min(1, { error: "customAgents[].label must not be empty" }).max(60, { error: "customAgents[].label must be at most 60 characters" }),
2745
+ command: z.string({ error: "customAgents[].command must be a string" }).min(1, { error: "customAgents[].command must not be empty" }).refine((command) => command.trim().length > 0, { error: "customAgents[].command must not be blank" }).refine(isSpawnableCommand, { error: `customAgents[].command must be ${AGENT_COMMAND_SHAPE_MESSAGE}` }),
2746
+ args: z.array(z.string({ error: "customAgents[].args must be an array of strings" }), { error: "customAgents[].args must be an array of strings" }).default([]),
2747
+ idleTitle: z.string({ error: "customAgents[].idleTitle must be a string" }).optional(),
2748
+ busyTitle: z.string({ error: "customAgents[].busyTitle must be a string" }).optional()
2749
+ }).strict();
2750
+ var CustomAgentDeclarations = z.array(CustomAgentDeclaration, { error: "customAgents must be an array" }).superRefine((declarations, ctx) => {
2751
+ const claimedIds = new Set(BUILTIN_AGENT_IDS);
2752
+ for (const [index, declaration] of declarations.entries()) {
2753
+ if (!claimedIds.has(declaration.id)) {
2754
+ claimedIds.add(declaration.id);
2755
+ continue;
2756
+ }
2757
+ const message = BUILTIN_AGENT_IDS.some((builtinAgentId) => builtinAgentId === declaration.id) ? `customAgents[${index}].id "${declaration.id}" collides with the builtin agent of the same id` : `customAgents[${index}].id "${declaration.id}" is declared more than once`;
2758
+ ctx.addIssue({
2759
+ code: "custom",
2760
+ path: [index, "id"],
2761
+ message
2762
+ });
2763
+ }
2764
+ });
2765
+ var TaskTitleSources = z.object({
2766
+ customTitle: TaskTitle.nullable().optional(),
2767
+ pendingPromptTitle: TaskTitle.nullable().optional(),
2768
+ refinedTitle: TaskTitle.nullable().optional(),
2769
+ aiTitle: TaskTitle.nullable().optional(),
2770
+ oscTitle: TaskTitle.nullable().optional(),
2771
+ promptTitle: TaskTitle.nullable().optional()
2772
+ }).strict();
2773
+ var TASK_TITLE_SOURCE_PRIORITY = [
2774
+ "customTitle",
2775
+ "pendingPromptTitle",
2776
+ "refinedTitle",
2777
+ "aiTitle",
2778
+ "oscTitle",
2779
+ "promptTitle"
2780
+ ];
2781
+ var PersistedTaskTitle = z.object({
2782
+ taskTitle: TaskTitle.min(1),
2783
+ isCustom: z.boolean(),
2784
+ sources: TaskTitleSources
2785
+ }).strict().refine(({ taskTitle, isCustom, sources }) => {
2786
+ const source = TASK_TITLE_SOURCE_PRIORITY.find((candidate) => sources[candidate]?.trim());
2787
+ if (!source) return false;
2788
+ return sources[source]?.replace(/\s+/g, " ").trim() === taskTitle && isCustom === (source === "customTitle");
2789
+ });
2790
+ var ProjectConfig = z.object({
2791
+ id: z.string().optional(),
2792
+ name: z.string().optional(),
2793
+ customTitle: TaskTitle.optional(),
2794
+ taskTitleState: PersistedTaskTitle.optional().catch(void 0),
2795
+ prLinks: SessionPrLinks.optional().catch(void 0),
2796
+ path: z.string(),
2797
+ repos: z.array(z.string()).min(2).optional(),
2798
+ baseBranch: z.string().refine(isGitBranchName, { error: "projects[].baseBranch must be a git branch name" }).optional(),
2799
+ agent: z.string({ error: "projects[].agent must be a string" }).regex(AGENT_ID_RE, { error: `projects[].agent must be ${AGENT_ID_SHAPE_MESSAGE}` }).optional(),
2800
+ codexBypassHookTrust: z.boolean().optional(),
2801
+ conversationView: z.boolean({ error: "projects[].conversationView must be a boolean" }).optional(),
2802
+ dangerouslySkipPermissions: z.boolean({ error: "projects[].dangerouslySkipPermissions must be a boolean" }).optional(),
2803
+ unguarded: z.boolean({ error: "projects[].unguarded must be a boolean" }).optional(),
2804
+ environment: ProjectEnvironment.optional()
2805
+ }).passthrough();
2806
+ var FILE_CONFIG_SHAPE = {
2807
+ ...BROWSER_CONFIG_SHAPE,
2808
+ branchGc: optionalLooseObject("branchGc"),
2809
+ coder: CoderSettings,
2810
+ visions: optionalLooseObject("visions"),
2811
+ github: GithubSettings,
2812
+ teamReview: optionalLooseObject("teamReview"),
2813
+ benchmarks: optionalLooseObject("benchmarks"),
2814
+ coherence: optionalLooseObject("coherence"),
2815
+ posthog: optionalLooseObject("posthog"),
2816
+ usage: optionalLooseObject("usage"),
2817
+ telegram: optionalLooseObject("telegram"),
2818
+ ingest: optionalLooseObject("ingest"),
2819
+ workflows: optionalLooseObject("workflows"),
2820
+ guardrails: GuardrailsFileSettings,
2821
+ telemetry: TelemetryFileSettings,
2822
+ trace: TraceSettings,
2823
+ planReview: PlanReviewSettings,
2824
+ customAgents: CustomAgentDeclarations.optional()
2825
+ };
2826
+ var Config = z.object({
2827
+ ...FILE_CONFIG_SHAPE,
2828
+ detectScheduledWakeups: optionalBoolean("detectScheduledWakeups"),
2829
+ worktreeAutoRebase: optionalBoolean("worktreeAutoRebase"),
2830
+ worktreeSyncOnStart: optionalBoolean("worktreeSyncOnStart"),
2831
+ worktreeRerere: optionalBoolean("worktreeRerere"),
2832
+ postTurnChecks: z.record(z.string(), z.unknown()).optional(),
2833
+ hooks: z.unknown().optional(),
2834
+ remote: z.object({
2835
+ enabled: z.boolean().optional(),
2836
+ port: z.number().int().min(1).max(65535).nullable().optional(),
2837
+ publicHost: z.string().optional(),
2838
+ allowedOrigins: z.array(z.string()).optional(),
2839
+ ownerLogin: z.string().optional()
2840
+ }).passthrough().optional(),
2841
+ projects: z.array(ProjectConfig)
2842
+ }).passthrough().superRefine((config, ctx) => {
2843
+ if (!Array.isArray(config.projects)) return;
2844
+ const declaredAgentIds = new Set(BUILTIN_AGENT_IDS);
2845
+ for (const declaration of config.customAgents ?? []) declaredAgentIds.add(declaration.id);
2846
+ for (const [index, project] of config.projects.entries()) {
2847
+ const agent = project?.agent;
2848
+ if (typeof agent !== "string" || !AGENT_ID_RE.test(agent)) continue;
2849
+ if (declaredAgentIds.has(agent)) continue;
2850
+ ctx.addIssue({
2851
+ code: "custom",
2852
+ path: [
2853
+ "projects",
2854
+ index,
2855
+ "agent"
2856
+ ],
2857
+ message: `projects[${index}].agent "${agent}" names no known agent; declare it under customAgents or use one of ${[...declaredAgentIds].join(", ")}`
2858
+ });
2859
+ }
2860
+ const declaredEnvironmentNames = new Set((config.coder?.environments ?? []).map((environment) => environment.name));
2861
+ for (const [index, project] of config.projects.entries()) {
2862
+ const environmentName = project?.environment?.name;
2863
+ if (environmentName === void 0 || declaredEnvironmentNames.has(environmentName)) continue;
2864
+ ctx.addIssue({
2865
+ code: "custom",
2866
+ path: [
2867
+ "projects",
2868
+ index,
2869
+ "environment",
2870
+ "name"
2871
+ ],
2872
+ message: `projects[${index}].environment "${environmentName}" must be declared under coder.environments`
2873
+ });
2874
+ }
2875
+ });
2876
+ var CONFIG_BLOCK_KEYS = Object.freeze([
2877
+ "taskTitle",
2878
+ "branchGc",
2879
+ "postTurnChecks",
2880
+ "visions",
2881
+ "github",
2882
+ "teamReview",
2883
+ "benchmarks",
2884
+ "coherence",
2885
+ "posthog",
2886
+ "usage",
2887
+ "telegram",
2888
+ "ingest",
2889
+ "guardrails",
2890
+ "telemetry",
2891
+ "workflows",
2892
+ "coder"
2893
+ ]);
2894
+ var CONFIG_SCALAR_KEYS = Object.freeze(Object.keys(BROWSER_CONFIG_SHAPE).filter((key) => {
2895
+ if (CONFIG_BLOCK_KEYS.includes(key)) return false;
2896
+ return key !== "port" && key !== "repoRoots" && key !== "worktreeShare";
2897
+ }));
2898
+ var RUNTIME_CONFIG_SCALAR_KEYS = Object.freeze([
2899
+ ...CONFIG_SCALAR_KEYS,
2900
+ "worktreeAutoRebase",
2901
+ "worktreeSyncOnStart",
2902
+ "worktreeRerere"
2903
+ ]);
2904
+ Object.freeze([
2905
+ "detectScheduledWakeups",
2906
+ "worktreeAutoRebase",
2907
+ "worktreeSyncOnStart",
2908
+ "worktreeRerere",
2909
+ "hooks",
2910
+ "remote",
2911
+ "projects"
2912
+ ]);
2913
+ function configIssueMessage(error) {
2914
+ return error.issues[0]?.message || "settings are invalid";
2915
+ }
2916
+ //#endregion
2917
+ export { POSTHOG_TRAFFIC_BASELINE_RANGE as $, CommitComparison as A, IssueUpdate as At, WorkflowLabelName as B, BenchmarkActionRequest as C, PlanDecision as Ct, BenchmarkRun as D, GithubIssuePullRequestsRepository as Dt, BenchmarkJudgement as E, planTitle as Et, GithubPrKey as F, FLYING_ANIMALS_GAP_RANGE as G, WorkflowsState as H, GithubPrLightSearchNode as I, MEMORY_RESERVE_MB_RANGE as J, FLYING_ANIMALS_SCALE_RANGE as K, GithubPrsFrame as L, MinedPrReviewData as M, IssuesState as Mt, PrCheckoutCaseInput as N, IssuesStatus as Nt, BenchmarkStatus as O, GithubIssueResponse as Ot, GithubPrDetailNode as P, issuePullRequestStateFromGithub as Pt, POSTHOG_FIX_TIMEOUT_RANGE as Q, comparablePrKey as R, pullRequestKeyFromReference as S, PLAN_TOOL_NAME as St, BenchmarkId as T, parseExitPlanModeHookPayload as Tt, FLYING_ANIMALS_DEFAULTS as U, WorkflowsSettings as V, FLYING_ANIMALS_DURATION_RANGE as W, PORT_RANGE as X, NON_NEGATIVE_NUMBER_RANGE as Y, POSITIVE_NUMBER_RANGE as Z, ClientMessage as _, changeMapFactId as _t, ConfigUpdate as a, USAGE_INTEGER_RANGES as at, OPERATOR_ACTIONS_BY_SURFACE as b, PLAN_HOOK_OUTPUT_MAX_CHARS as bt, TASK_TITLE_SOURCE_PRIORITY as c, WORKFLOWS_MAX_ACTIONS_PER_POLL_RANGE as ct, POST_TURN_CHECK_MODES as d, SessionSetup as dt, POSTHOG_TRAFFIC_MIN_USERS_RANGE as et, UPDATE_CHANNELS as f, MAX_RAW_LINE_CHARS as ft, CONTROL_FRAME_MAX_BYTES as g, ChangeMap as gt, normalizeLegacyConfigNumbers as h, CoherenceJournalOutput as ht, Config as i, USAGE_BUDGET_RANGE as it, MergedPrListing as j, IssuesSearchResponse as jt, BenchmarkSuite as k, IssueKey as kt, configIssueMessage as l, WORKFLOWS_MAX_CONCURRENT_SESSIONS_RANGE as lt, USAGE_VENDOR_KEYS as m, TraceRecord as mt, BUILTIN_AGENT_IDS as n, REPLAY_BUFFER_KB_RANGE as nt, PersistedTaskTitle as o, USAGE_RETAIN_DAYS_RANGE as ot, USAGE_COST_MODES as p, TraceCheckpoint as pt, KEEP_MERGEABLE_TIMEOUT_MINUTES_RANGE as q, BrowserConfig as r, TASK_TITLE_TIMEOUT_RANGE as rt, RUNTIME_CONFIG_SCALAR_KEYS as s, USAGE_SCAN_INTERVAL_RANGE as st, AGENT_ID_SHAPE_MESSAGE as t, POSTHOG_TRAFFIC_MULTIPLIER_RANGE as tt, BranchGcFileSettings as u, UpdateJournal as ut, DASHBOARD_VIEWS as v, PLAN_BODY_CAP_BYTES as vt, BenchmarkCase as w, PlanRevision as wt, OPERATOR_SURFACES as x, PLAN_RESULT_HOOK_EVENT as xt, InstallFlavor as y, PLAN_HOOK_EVENT as yt, WorkflowCommentBody as z };