glimmervoid 0.41.0 → 0.41.1

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 (23) hide show
  1. package/dist/bin/glimmervoid.js +8 -8
  2. package/dist/chunks/{adapters-yVOK5me4.js → adapters-CyDflXHy.js} +27 -12
  3. package/dist/chunks/{adapters-JDV45XpZ.js → adapters-D8BJffFW.js} +1 -1
  4. package/dist/chunks/{agent-api-cli-1xk9WryE.js → agent-api-cli-B7-ToJul.js} +1 -1
  5. package/dist/chunks/{agent-api-cli-BSY2jR0P.js → agent-api-cli-CvCov9_e.js} +1 -1
  6. package/dist/chunks/{agent-api-core-syEPHs7j.js → agent-api-core-CLxZAole.js} +1 -1
  7. package/dist/chunks/{config-store-BEaaXTd5.js → config-store-CxYqTNbe.js} +2 -2
  8. package/dist/chunks/config-store-DcVWBJOV.js +1 -0
  9. package/dist/chunks/{contracts-V_hfT23R.js → contracts-C9Jj9iDo.js} +1 -1
  10. package/dist/chunks/{control-messages-Ci4g6gD1.js → control-messages-C6JGCTuy.js} +2 -1
  11. package/dist/chunks/{main-Bbh8ky2x.js → main-CRU5ahjl.js} +135 -44
  12. package/dist/chunks/{pair-cli-DkItUGpT.js → pair-cli-CL1D9xc7.js} +2 -2
  13. package/dist/chunks/{remote-config-DFwmHWed.js → remote-config-CaW0mpwr.js} +1 -1
  14. package/dist/chunks/{settings-cli-CaYd3bUH.js → settings-cli-Duculey3.js} +4 -4
  15. package/dist/chunks/{settings-readout-core-Du7n-zyD.js → settings-readout-core-CX7DmEuG.js} +1 -1
  16. package/dist/chunks/{ssh-sign-cli-BLzmQ3Vh.js → ssh-sign-cli-BEAAFjXg.js} +1 -1
  17. package/dist/client/assets/{index-D7QFo-gy.js → index-CBjFGcSs.js} +14 -14
  18. package/dist/client/assets/index-Cbb5NKHK.css +2 -0
  19. package/dist/client/index.html +2 -2
  20. package/dist/server/index.js +1 -1
  21. package/package.json +1 -1
  22. package/dist/chunks/config-store-DE_r4DP8.js +0 -1
  23. package/dist/client/assets/index-DKnOk67Z.css +0 -2
@@ -4,7 +4,7 @@ import { i as errorText } from "../chunks/text-DoirglWV.js";
4
4
  import { a as packageRoot } from "../chunks/runtime-paths-BkeftE60.js";
5
5
  import { t as AGENT_API_VERBS } from "../chunks/session-C8IpFmGQ.js";
6
6
  import { i as execSync } from "../chunks/child-process-safe-D4hyVIXj.js";
7
- import { r as agentCommandHelpLines } from "../chunks/agent-api-core-syEPHs7j.js";
7
+ import { r as agentCommandHelpLines } from "../chunks/agent-api-core-CLxZAole.js";
8
8
  import { t as renderTable } from "../chunks/ascii-figure-core-pDAwtlKO.js";
9
9
  import { n as glimmervoidHomeDir, t as decideConfigPath } from "../chunks/config-path-core-DFt-TemS.js";
10
10
  import { i as parseCommandLine, r as gitDoctorRows, t as probeGitVersion } from "../chunks/git-version-D_iXgYTZ.js";
@@ -65,7 +65,7 @@ var OWN_SUBCOMMAND_RUNNERS = [
65
65
  return 0;
66
66
  }],
67
67
  ["pair", async (subcommandArgs) => {
68
- const { runPairCli } = await import("../chunks/pair-cli-DkItUGpT.js");
68
+ const { runPairCli } = await import("../chunks/pair-cli-CL1D9xc7.js");
69
69
  return runPairCli(subcommandArgs);
70
70
  }],
71
71
  ["agent", async (subcommandArgs) => {
@@ -73,7 +73,7 @@ var OWN_SUBCOMMAND_RUNNERS = [
73
73
  return runAgentSetupCli(subcommandArgs);
74
74
  }],
75
75
  ["settings", async (subcommandArgs) => {
76
- const { runSettingsCli } = await import("../chunks/settings-cli-CaYd3bUH.js");
76
+ const { runSettingsCli } = await import("../chunks/settings-cli-Duculey3.js");
77
77
  return runSettingsCli(subcommandArgs);
78
78
  }],
79
79
  ["visions", async (subcommandArgs) => {
@@ -81,13 +81,13 @@ var OWN_SUBCOMMAND_RUNNERS = [
81
81
  return runVisionsCli(subcommandArgs);
82
82
  }],
83
83
  ["ssh-sign", async (subcommandArgs) => {
84
- const { runSshSignCli } = await import("../chunks/ssh-sign-cli-BLzmQ3Vh.js");
84
+ const { runSshSignCli } = await import("../chunks/ssh-sign-cli-BEAAFjXg.js");
85
85
  return runSshSignCli(subcommandArgs);
86
86
  }]
87
87
  ];
88
88
  var ownSubcommandNames = new Set(OWN_SUBCOMMAND_RUNNERS.map(([name]) => name));
89
89
  var SUBCOMMAND_RUNNERS = new Map([...OWN_SUBCOMMAND_RUNNERS, ...AGENT_API_VERBS.filter((verb) => !ownSubcommandNames.has(verb)).map((verb) => [verb, async (subcommandArgs, subcommandName) => {
90
- const { runAgentApiCli } = await import("../chunks/agent-api-cli-BSY2jR0P.js");
90
+ const { runAgentApiCli } = await import("../chunks/agent-api-cli-CvCov9_e.js");
91
91
  return runAgentApiCli([subcommandName, ...subcommandArgs]);
92
92
  }])]);
93
93
  var AGENT_INSTALL_COMMAND_BY_ID = {
@@ -101,7 +101,7 @@ function missingAgentText(agentId) {
101
101
  }
102
102
  async function printSessionLimits() {
103
103
  if (!process.env["GLIMMERVOID_AGENT_URL"]) return;
104
- const { sessionLimitsHelpLines } = await import("../chunks/agent-api-cli-BSY2jR0P.js");
104
+ const { sessionLimitsHelpLines } = await import("../chunks/agent-api-cli-CvCov9_e.js");
105
105
  const limitsLines = await sessionLimitsHelpLines();
106
106
  console.log(`\n${limitsLines.join("\n")}`);
107
107
  }
@@ -158,7 +158,7 @@ async function readDeclaredCustomAgents() {
158
158
  declared: [],
159
159
  error: null
160
160
  };
161
- const { loadConfigFile } = await import("../chunks/config-store-DE_r4DP8.js");
161
+ const { loadConfigFile } = await import("../chunks/config-store-DcVWBJOV.js");
162
162
  try {
163
163
  const loaded = loadConfigFile(decided.path, { exitOnError: false });
164
164
  if (!loaded.config) return {
@@ -234,7 +234,7 @@ async function runDoctor() {
234
234
  }
235
235
  switchSection("Agents");
236
236
  try {
237
- const { listAgentIds, describeAgentResolvability, setCustomAgents } = await import("../chunks/adapters-JDV45XpZ.js");
237
+ const { listAgentIds, describeAgentResolvability, setCustomAgents } = await import("../chunks/adapters-D8BJffFW.js");
238
238
  const declaredCustomAgents = await readDeclaredCustomAgents();
239
239
  if (declaredCustomAgents.error) line("config", declaredCustomAgents.error);
240
240
  setCustomAgents(declaredCustomAgents.declared);
@@ -1,14 +1,14 @@
1
1
  import { o as relayPath } from "./runtime-paths-BkeftE60.js";
2
2
  import { Lt as FULL_SHA_RE, zt as shortSha$1 } from "./session-C8IpFmGQ.js";
3
3
  import { n as execFileAsync, r as execFileSync } from "./child-process-safe-D4hyVIXj.js";
4
- import { a as InstallFlavor } from "./control-messages-Ci4g6gD1.js";
4
+ import { a as InstallFlavor } from "./control-messages-C6JGCTuy.js";
5
5
  import { o as supervisionLine } from "./session-routes-nySS7DUE.js";
6
6
  import { n as resolveAgentCommand, t as buildAgentSpawnCommand } from "./spawn-command-Cc40FiZI.js";
7
7
  import { c as textOr, s as rawTextOr } from "./coerce-NSst8oRP.js";
8
8
  import { r as nextBackoffMs } from "./backoff-DjVpfHk7.js";
9
9
  import { i as isSpinnerChar, n as classifyAgentTitle, r as isBrailleChar, s as buildAgentEnv, t as grok } from "./grok-BUGgQVE3.js";
10
10
  import { t as buildHookCommand } from "./hook-command-core-qTNK-xMF.js";
11
- import "./contracts-V_hfT23R.js";
11
+ import "./contracts-C9Jj9iDo.js";
12
12
  import { n as mergeCodexPreToolUse, t as HOOK_TOOLS } from "./hook-tools-Dl7-r2Eb.js";
13
13
  import fs from "node:fs";
14
14
  import path from "node:path";
@@ -656,21 +656,34 @@ var titleProfile = {
656
656
  agentSuffix: ` - ${ID}`
657
657
  }
658
658
  };
659
- function mapHookToSignal(event) {
660
- switch (String(event || "").toLowerCase()) {
659
+ var REQUEST_USER_INPUT_TOOL_NAME = "request_user_input";
660
+ function isRequestUserInput(event, payload) {
661
+ return event === "pretooluse" && payload?.tool_name === REQUEST_USER_INPUT_TOOL_NAME;
662
+ }
663
+ function mapHookToSignal(event, payload) {
664
+ const e = String(event || "").toLowerCase();
665
+ switch (e) {
661
666
  case "sessionstart": return "session-start";
662
667
  case "sessionend": return "session-end";
663
668
  case "userpromptsubmit": return "resume";
664
669
  case "stop": return "ready";
665
670
  case "permissionrequest": return "awaiting-input";
671
+ case "precompact": return "compaction-start";
672
+ case "postcompact": return "compaction-end";
673
+ case "subagentstart": return "subagent-start";
674
+ case "subagentstop": return "subagent-stop";
675
+ case "pretooluse": return isRequestUserInput(e, payload) ? "awaiting-input" : null;
666
676
  default: return null;
667
677
  }
668
678
  }
669
679
  function mapHookConfidence() {
670
680
  return null;
671
681
  }
672
- function mapHookPromptKind(event) {
673
- return String(event || "").toLowerCase() === "permissionrequest" ? "permission" : null;
682
+ function mapHookPromptKind(event, payload) {
683
+ const e = String(event || "").toLowerCase();
684
+ if (e === "permissionrequest") return "permission";
685
+ if (isRequestUserInput(e, payload)) return "elicitation";
686
+ return null;
674
687
  }
675
688
  function sessionIdOf(payload) {
676
689
  return payload?.session_id;
@@ -692,11 +705,13 @@ function userConfigFolders(env) {
692
705
  return codexHomes(env, null);
693
706
  }
694
707
  var TOML_LITERAL_STRING_FORBIDDEN = /[\x00-\x08\x0a-\x1f\x27\x7f]/;
695
- function buildHookArgs({ relayPath = RELAY_PATH, events = HOOK_EVENTS, matchedRelayHooks = [], bypassHookTrust = false, hookTools = [], hookToolRelayPath = HOOK_TOOL_RELAY_PATH, userHooks = [] } = {}) {
708
+ function buildHookArgs({ relayPath = RELAY_PATH, events = HOOK_EVENTS, matchedRelayHooks = [], bypassHookTrust = false, hookTools = [], hookToolRelayPath = HOOK_TOOL_RELAY_PATH, userHooks = [], observeToolCalls = false } = {}) {
696
709
  const args = bypassHookTrust ? [TRUST_BYPASS_FLAG] : [];
697
710
  const preToolUseGroups = [];
698
711
  const groupsByEvent = /* @__PURE__ */ new Map();
699
- for (const event of events) {
712
+ const relayedEvents = observeToolCalls && !events.includes("PreToolUse") ? [...events, "PreToolUse"] : events;
713
+ const relayedMatchedHooks = observeToolCalls ? matchedRelayHooks.filter(({ event }) => event !== "PreToolUse") : matchedRelayHooks;
714
+ for (const event of relayedEvents) {
700
715
  const command = buildHookCommand(relayPath, event);
701
716
  if (!command) return null;
702
717
  if (event === "PreToolUse") {
@@ -705,7 +720,7 @@ function buildHookArgs({ relayPath = RELAY_PATH, events = HOOK_EVENTS, matchedRe
705
720
  }
706
721
  groupsByEvent.set(event, [`{hooks=[{type='command',command='${command}'}]}`]);
707
722
  }
708
- for (const { event, matcher } of matchedRelayHooks) {
723
+ for (const { event, matcher } of relayedMatchedHooks) {
709
724
  const command = buildHookCommand(relayPath, event);
710
725
  if (!command) return null;
711
726
  const group = `{matcher='${matcher}',hooks=[{type='command',command='${command}'}]}`;
@@ -890,12 +905,12 @@ var codex = {
890
905
  capabilities: {
891
906
  hooks: true,
892
907
  awaitingInput: true,
893
- backgroundAgents: false,
908
+ backgroundAgents: true,
894
909
  resume: true,
895
- statusLine: false,
910
+ statusLine: true,
896
911
  rtk: true,
897
912
  saneYolo: true,
898
- compactQuiet: false,
913
+ compactQuiet: true,
899
914
  skipPermissionsFlag: true,
900
915
  headless: true
901
916
  }
@@ -1 +1 @@
1
- export { a as describeAgentResolvability, l as listAgentIds, f as setCustomAgents } from "./adapters-yVOK5me4.js";
1
+ export { a as describeAgentResolvability, l as listAgentIds, f as setCustomAgents } from "./adapters-CyDflXHy.js";
@@ -1,7 +1,7 @@
1
1
  import { t as errorCode } from "./text-DoirglWV.js";
2
2
  import { n as AGENT_URL_ENV, s as AgentLimitsReply } from "./session-C8IpFmGQ.js";
3
3
  import { i as formatSessionLimits } from "./session-routes-nySS7DUE.js";
4
- import { l as isAgentApiVerb, t as AGENT_COMMAND_HELP } from "./agent-api-core-syEPHs7j.js";
4
+ import { l as isAgentApiVerb, t as AGENT_COMMAND_HELP } from "./agent-api-core-CLxZAole.js";
5
5
  import { i as resolveHookTarget } from "./hook-relay-core-DA_bz2KA.js";
6
6
  import { n as decideGuardrailsProxy } from "./guardrails-proxy-core-BI3rdY-m.js";
7
7
  import { t as parseJsonOrNull } from "./json-core-dfa_7Fak.js";
@@ -1 +1 @@
1
- export { t as askAgentApi, r as runAgentApiCli, i as sessionLimitsHelpLines } from "./agent-api-cli-1xk9WryE.js";
1
+ export { t as askAgentApi, r as runAgentApiCli, i as sessionLimitsHelpLines } from "./agent-api-cli-B7-ToJul.js";
@@ -1,5 +1,5 @@
1
1
  import { a as AgentCloseRequest, c as AgentPullRequestRequest, f as AgentSettingsRequest, i as AgentAttentionRequest, l as AgentReadRequest, o as AgentEditRequest, p as AgentSpawnRequest, t as AGENT_API_VERBS, u as AgentSendRequest } from "./session-C8IpFmGQ.js";
2
- import { c as pullRequestKeyFromReference } from "./control-messages-Ci4g6gD1.js";
2
+ import { c as pullRequestKeyFromReference } from "./control-messages-C6JGCTuy.js";
3
3
  import { n as NO_OWN_WORKTREE_REASON, t as COMMAND_ROUTES } from "./session-routes-nySS7DUE.js";
4
4
  import crypto from "node:crypto";
5
5
  var MAX_SPAWNS_IN_FLIGHT = 1;
@@ -1,10 +1,10 @@
1
1
  import { n as errorLabel, r as errorMessage } from "./text-DoirglWV.js";
2
2
  import { n as equalsIgnoringCaseOnWindows } from "./paths-Bu4eH1Yd.js";
3
- import { B as PORT_RANGE, F as FLYING_ANIMALS_GAP_RANGE, I as FLYING_ANIMALS_SCALE_RANGE, L as KEEP_MERGEABLE_TIMEOUT_MINUTES_RANGE, M as CHANGE_MAP_NARRATOR_TIMEOUT_RANGE, N as FLYING_ANIMALS_DEFAULTS, P as FLYING_ANIMALS_DURATION_RANGE, Q as POSTHOG_TRAFFIC_MULTIPLIER_RANGE, R as MEMORY_RESERVE_MB_RANGE, U as POSTHOG_FIX_TIMEOUT_RANGE, V as POSITIVE_NUMBER_RANGE, Y as POSTHOG_TRAFFIC_BASELINE_RANGE, Z as POSTHOG_TRAFFIC_MIN_USERS_RANGE, at as USAGE_SCAN_INTERVAL_RANGE, et as REPLAY_BUFFER_KB_RANGE, ft as WORKFLOWS_MAX_ACTIONS_PER_POLL_RANGE, it as USAGE_RETAIN_DAYS_RANGE, nt as USAGE_BUDGET_RANGE, pt as WORKFLOWS_MAX_CONCURRENT_SESSIONS_RANGE, rt as USAGE_INTEGER_RANGES, tt as TASK_TITLE_TIMEOUT_RANGE, z as NON_NEGATIVE_NUMBER_RANGE } from "./control-messages-Ci4g6gD1.js";
3
+ import { B as PORT_RANGE, F as FLYING_ANIMALS_GAP_RANGE, I as FLYING_ANIMALS_SCALE_RANGE, L as KEEP_MERGEABLE_TIMEOUT_MINUTES_RANGE, M as CHANGE_MAP_NARRATOR_TIMEOUT_RANGE, N as FLYING_ANIMALS_DEFAULTS, P as FLYING_ANIMALS_DURATION_RANGE, Q as POSTHOG_TRAFFIC_MULTIPLIER_RANGE, R as MEMORY_RESERVE_MB_RANGE, U as POSTHOG_FIX_TIMEOUT_RANGE, V as POSITIVE_NUMBER_RANGE, Y as POSTHOG_TRAFFIC_BASELINE_RANGE, Z as POSTHOG_TRAFFIC_MIN_USERS_RANGE, at as USAGE_SCAN_INTERVAL_RANGE, et as REPLAY_BUFFER_KB_RANGE, ft as WORKFLOWS_MAX_ACTIONS_PER_POLL_RANGE, it as USAGE_RETAIN_DAYS_RANGE, nt as USAGE_BUDGET_RANGE, pt as WORKFLOWS_MAX_CONCURRENT_SESSIONS_RANGE, rt as USAGE_INTEGER_RANGES, tt as TASK_TITLE_TIMEOUT_RANGE, z as NON_NEGATIVE_NUMBER_RANGE } from "./control-messages-C6JGCTuy.js";
4
4
  import { n as glimmervoidHomeDir$1, t as decideConfigPath } from "./config-path-core-DFt-TemS.js";
5
5
  import { n as isRecord } from "./coerce-NSst8oRP.js";
6
6
  import { d as writeJsonAtomicSync, f as writeTextAtomic, p as writeTextAtomicSync } from "./json-file-DFCTvPjj.js";
7
- import { C as POST_TURN_CHECK_MODES, D as normalizeLegacyConfigNumbers, S as CHANGE_MAP_NARRATOR_ENGINES, T as USAGE_COST_MODES, b as configIssueMessage, f as AGENT_ID_SHAPE_MESSAGE, h as Config, p as BUILTIN_AGENT_IDS, s as FeatureFlagsResponse, u as TELEMETRY_KILL_SWITCH_FLAG, v as RUNTIME_CONFIG_SCALAR_KEYS, w as UPDATE_CHANNELS, x as BranchGcFileSettings } from "./contracts-V_hfT23R.js";
7
+ import { C as POST_TURN_CHECK_MODES, D as normalizeLegacyConfigNumbers, S as CHANGE_MAP_NARRATOR_ENGINES, T as USAGE_COST_MODES, b as configIssueMessage, f as AGENT_ID_SHAPE_MESSAGE, h as Config, p as BUILTIN_AGENT_IDS, s as FeatureFlagsResponse, u as TELEMETRY_KILL_SWITCH_FLAG, v as RUNTIME_CONFIG_SCALAR_KEYS, w as UPDATE_CHANNELS, x as BranchGcFileSettings } from "./contracts-C9Jj9iDo.js";
8
8
  import fs from "node:fs";
9
9
  import path from "node:path";
10
10
  import os from "node:os";
@@ -0,0 +1 @@
1
+ export { s as loadConfigFile } from "./config-store-CxYqTNbe.js";
@@ -1,5 +1,5 @@
1
1
  import { R as TaskTitle, Ut as repoParts, at as SessionPrLinks } from "./session-C8IpFmGQ.js";
2
- import { $ as POSTHOG_TRANSIENT_RECURRENCE_RANGE, A as BRANCH_GC_INTERVAL_MS_RANGE, B as PORT_RANGE, D as WorkflowsSettings, G as POSTHOG_INVESTIGATION_TIMEOUT_RANGE, H as POSTHOG_ESCALATION_RANGE, J as POSTHOG_RECURRENCE_WINDOW_RANGE, K as POSTHOG_MAX_CONCURRENT_RANGE, L as KEEP_MERGEABLE_TIMEOUT_MINUTES_RANGE, M as CHANGE_MAP_NARRATOR_TIMEOUT_RANGE, O as WorkflowsSettingsUpdate, Q as POSTHOG_TRAFFIC_MULTIPLIER_RANGE, R as MEMORY_RESERVE_MB_RANGE, U as POSTHOG_FIX_TIMEOUT_RANGE, V as POSITIVE_NUMBER_RANGE, W as POSTHOG_INTERVAL_RANGE, X as POSTHOG_TRAFFIC_COOLDOWN_RANGE, Y as POSTHOG_TRAFFIC_BASELINE_RANGE, Z as POSTHOG_TRAFFIC_MIN_USERS_RANGE, ct as VISIONS_DISPATCH_TIMEOUT_RANGE, dt as VISIONS_QUIET_MS_RANGE, et as REPLAY_BUFFER_KB_RANGE, j as BRANCH_GC_STALE_DAYS_RANGE, lt as VISIONS_INTENT_THREAD_TTL_MS_RANGE, o as OPERATOR_ACTIONS_BY_SURFACE, ot as VISIONS_ACTIVITY_MAX_PER_HOUR_RANGE, q as POSTHOG_MIN_USERS_RANGE, r as DASHBOARD_VIEWS, rt as USAGE_INTEGER_RANGES, s as OPERATOR_SURFACES, st as VISIONS_COOLDOWN_MS_RANGE, tt as TASK_TITLE_TIMEOUT_RANGE, ut as VISIONS_MAX_PER_HOUR_RANGE } from "./control-messages-Ci4g6gD1.js";
2
+ import { $ as POSTHOG_TRANSIENT_RECURRENCE_RANGE, A as BRANCH_GC_INTERVAL_MS_RANGE, B as PORT_RANGE, D as WorkflowsSettings, G as POSTHOG_INVESTIGATION_TIMEOUT_RANGE, H as POSTHOG_ESCALATION_RANGE, J as POSTHOG_RECURRENCE_WINDOW_RANGE, K as POSTHOG_MAX_CONCURRENT_RANGE, L as KEEP_MERGEABLE_TIMEOUT_MINUTES_RANGE, M as CHANGE_MAP_NARRATOR_TIMEOUT_RANGE, O as WorkflowsSettingsUpdate, Q as POSTHOG_TRAFFIC_MULTIPLIER_RANGE, R as MEMORY_RESERVE_MB_RANGE, U as POSTHOG_FIX_TIMEOUT_RANGE, V as POSITIVE_NUMBER_RANGE, W as POSTHOG_INTERVAL_RANGE, X as POSTHOG_TRAFFIC_COOLDOWN_RANGE, Y as POSTHOG_TRAFFIC_BASELINE_RANGE, Z as POSTHOG_TRAFFIC_MIN_USERS_RANGE, ct as VISIONS_DISPATCH_TIMEOUT_RANGE, dt as VISIONS_QUIET_MS_RANGE, et as REPLAY_BUFFER_KB_RANGE, j as BRANCH_GC_STALE_DAYS_RANGE, lt as VISIONS_INTENT_THREAD_TTL_MS_RANGE, o as OPERATOR_ACTIONS_BY_SURFACE, ot as VISIONS_ACTIVITY_MAX_PER_HOUR_RANGE, q as POSTHOG_MIN_USERS_RANGE, r as DASHBOARD_VIEWS, rt as USAGE_INTEGER_RANGES, s as OPERATOR_SURFACES, st as VISIONS_COOLDOWN_MS_RANGE, tt as TASK_TITLE_TIMEOUT_RANGE, ut as VISIONS_MAX_PER_HOUR_RANGE } from "./control-messages-C6JGCTuy.js";
3
3
  import { n as isRecord } from "./coerce-NSst8oRP.js";
4
4
  import path from "node:path";
5
5
  import { z } from "zod";
@@ -2321,7 +2321,8 @@ var serverVariants = [
2321
2321
  ts: timestamp,
2322
2322
  fiveHour: z.unknown().nullable(),
2323
2323
  sevenDay: z.unknown().nullable(),
2324
- source: z.string()
2324
+ source: z.string(),
2325
+ vendor: z.enum(["claude", "codex"]).optional()
2325
2326
  }),
2326
2327
  loose("usage-budget-alert", {
2327
2328
  scope: z.string(),
@@ -4,9 +4,9 @@ import { a as sanitizeWorktreeName, i as safePathSegment, n as equalsIgnoringCas
4
4
  import { a as packageRoot, n as cliPath, o as relayPath, r as clientDir, s as resolvePackageBin, t as bundled } from "./runtime-paths-BkeftE60.js";
5
5
  import { A as SIGN_URL_ENV, At as TeamReviewThreadCommentsResponse, B as MyPr, Bt as GH_SEGMENT, Ct as ReviewVerdict, Dt as TeamReviewResolveResponse, E as SESSION_DOC_BODY_CAP_BYTES, Et as TeamReviewCompareFiles, H as MyPrCheckContext, Ht as REPO_SLUG_RE, I as SshSignRequest, It as hasStandingViewerApproval, J as MyPrMergeRequest, Jt as BADGE_LABELS, K as MyPrLaneEntry, L as TASK_TITLE_CONTROL_CHARACTERS, Mt as TeamReviewThreadsRepository, Nt as canApproveAfterComment, O as SESSION_NAME_PATTERN, Ot as TeamReviewStateEntry, Pt as decisionAsIfApprovalRequired, Qt as STATES, R as TaskTitle, Rt as HEX_SHA_RE, S as ConversationQuestion, St as ReviewThreadId, U as MyPrCheckContextsResponse, Ut as repoParts, V as MyPrAutoRebase, Vt as NODE_ID_RE, W as MyPrKeepMergeableRequest, X as MyPrMergeStateResponse, Xt as MERGEABLE_LIVE_STATES, Yt as KILLABLE_STATES, Z as MyPrMergeWhenReadyRequest, Zt as RESTARTABLE_STATES, _ as CONVERSATION_TOOL_RESULT_HOOK_EVENT, bt as ReviewFinding, ct as CommitSha, dt as FindingSeverity, et as MyPrThreadNode, g as CONVERSATION_PERMISSION_HOOK_EVENT, gt as QueuedReview, h as CONVERSATION_APPROVAL_SUMMARY_MAX_CHARS, ht as PrDetail, j as SSH_SIGN_BODY_CAP_BYTES, jt as TeamReviewThreadResult, k as SESSION_NAME_RULE_TEXT, kt as TeamReviewStatus, lt as DECIDING_REVIEW_STATES, m as COHERENCE_HOOKS_INACTIVE, mt as PostingPlan, n as AGENT_URL_ENV, nt as MyPrsSnapshot, pt as GithubReviewState, q as MyPrMergeMethod, r as ASK_USER_QUESTION_TOOL_NAME, rt as MyPrsState, tt as MyPrThreadsResponse, ut as EarlierReview, vt as ReviewComment, w as RefinedTaskTitle, wt as TeamReviewActionRequest, xt as ReviewResult, yt as ReviewDraft, z as LinkedPr, zt as shortSha } from "./session-C8IpFmGQ.js";
6
6
  import { n as execFileAsync, o as spawn, r as execFileSync, t as execFile } from "./child-process-safe-D4hyVIXj.js";
7
- import { At as planTitle, C as GithubPrsFrame, Ct as PLAN_HOOK_EVENT, D as WorkflowsSettings, Dt as PlanDecision, E as WorkflowLabelName, Et as PLAN_TOOL_NAME, Ft as IssuesSearchResponse, It as IssuesState, L as KEEP_MERGEABLE_TIMEOUT_MINUTES_RANGE, Lt as IssuesStatus, Mt as GithubIssueResponse, Nt as IssueKey, Ot as PlanRevision, Pt as IssueUpdate, Rt as issuePullRequestStateFromGithub, S as GithubPrLightSearchNode, St as PLAN_BODY_CAP_BYTES, T as WorkflowCommentBody, Tt as PLAN_RESULT_HOOK_EVENT, _ as MergedPrListing, _t as TraceCheckpoint, b as GithubPrDetailNode, bt as ChangeMap, c as pullRequestKeyFromReference, d as BenchmarkId, f as BenchmarkJudgement, g as CommitComparison, gt as MAX_RAW_LINE_CHARS, h as BenchmarkSuite, ht as SessionSetup, i as DIFF_ANNOTATION_NOTE_MAX_CHARS, jt as GithubIssuePullRequestsRepository, k as WorkflowsState, kt as parseExitPlanModeHookPayload, l as BenchmarkActionRequest, m as BenchmarkStatus, mt as UpdateJournal, n as ClientMessage, p as BenchmarkRun, rt as USAGE_INTEGER_RANGES, t as CONTROL_FRAME_MAX_BYTES, u as BenchmarkCase, v as MinedPrReviewData, vt as TraceRecord, w as comparablePrKey, wt as PLAN_HOOK_OUTPUT_MAX_CHARS, x as GithubPrKey, xt as changeMapFactId, y as PrCheckoutCaseInput, yt as CoherenceJournalOutput } from "./control-messages-Ci4g6gD1.js";
7
+ import { At as planTitle, C as GithubPrsFrame, Ct as PLAN_HOOK_EVENT, D as WorkflowsSettings, Dt as PlanDecision, E as WorkflowLabelName, Et as PLAN_TOOL_NAME, Ft as IssuesSearchResponse, It as IssuesState, L as KEEP_MERGEABLE_TIMEOUT_MINUTES_RANGE, Lt as IssuesStatus, Mt as GithubIssueResponse, Nt as IssueKey, Ot as PlanRevision, Pt as IssueUpdate, Rt as issuePullRequestStateFromGithub, S as GithubPrLightSearchNode, St as PLAN_BODY_CAP_BYTES, T as WorkflowCommentBody, Tt as PLAN_RESULT_HOOK_EVENT, _ as MergedPrListing, _t as TraceCheckpoint, b as GithubPrDetailNode, bt as ChangeMap, c as pullRequestKeyFromReference, d as BenchmarkId, f as BenchmarkJudgement, g as CommitComparison, gt as MAX_RAW_LINE_CHARS, h as BenchmarkSuite, ht as SessionSetup, i as DIFF_ANNOTATION_NOTE_MAX_CHARS, jt as GithubIssuePullRequestsRepository, k as WorkflowsState, kt as parseExitPlanModeHookPayload, l as BenchmarkActionRequest, m as BenchmarkStatus, mt as UpdateJournal, n as ClientMessage, p as BenchmarkRun, rt as USAGE_INTEGER_RANGES, t as CONTROL_FRAME_MAX_BYTES, u as BenchmarkCase, v as MinedPrReviewData, vt as TraceRecord, w as comparablePrKey, wt as PLAN_HOOK_OUTPUT_MAX_CHARS, x as GithubPrKey, xt as changeMapFactId, y as PrCheckoutCaseInput, yt as CoherenceJournalOutput } from "./control-messages-C6JGCTuy.js";
8
8
  import { a as permitsHelpCommand, r as describeSessionLimits } from "./session-routes-nySS7DUE.js";
9
- import { a as decideSpawnAllowance, c as describeRoleRefusal, d as projectMyPrs, f as projectReviews, i as decideAgentRequest, n as REFUSAL_REASON, o as deriveChildSessionName, s as describePushLanding, u as parseAgentVerb } from "./agent-api-core-syEPHs7j.js";
9
+ import { a as decideSpawnAllowance, c as describeRoleRefusal, d as projectMyPrs, f as projectReviews, i as decideAgentRequest, n as REFUSAL_REASON, o as deriveChildSessionName, s as describePushLanding, u as parseAgentVerb } from "./agent-api-core-CLxZAole.js";
10
10
  import { n as glimmervoidHomeDir, t as decideConfigPath } from "./config-path-core-DFt-TemS.js";
11
11
  import { i as parseCommandLine, n as warnWhenGitIsTooOld } from "./git-version-D_iXgYTZ.js";
12
12
  import { n as checkGuardrailsDependencies, t as allowGuardedSpawn } from "./guardrails-deps-BjPzk1rE.js";
@@ -21,13 +21,13 @@ import { n as DEFAULT_MAX_MS, r as nextBackoffMs, t as DEFAULT_BASE_MS } from ".
21
21
  import { n as unrefTimer, t as DEFAULT_TIMER_FNS } from "./timer-deps-u2DAQLok.js";
22
22
  import { n as shellQuote } from "./hook-command-core-qTNK-xMF.js";
23
23
  import { C as parseCgroupBytes, S as memoryReserveBytes, T as parseMemAvailableBytes, _ as createSpawnGate, a as jsonStateLoadError, b as cgroupLimitBytes, c as loadedJsonValue, d as writeJsonAtomicSync, f as writeTextAtomic, g as createSerialQueue, h as createMemoryAdmission, i as createJsonStateWriter, m as createKeyedSerialQueue, n as appendJsonLines, o as loadJsonStateFile, p as writeTextAtomicSync, r as createJsonStateStore, s as loadJsonStateFileSync, t as appendJsonLine, u as writeJsonAtomic, v as isQueueAdmissionTimeout, w as parseCgroupV2Path, x as headroomFromReadings, y as cgroupAncestorPaths } from "./json-file-DFCTvPjj.js";
24
- import { $ as DEFAULT_BRANCH_GC_PREFIXES, B as buildExceptionProperties, F as TELEMETRY_BATCH_URL, G as exceptionFingerprint, H as decideIsDevInstall, I as TELEMETRY_FLAGS_URL, J as resolveProjectToken, K as nodeMajorVersion, L as adapterBucket, P as FIRST_RUN_NOTICE, R as buildAiGenerationEvents, U as decideRemoteTelemetryState, V as classifySessionExit, W as decideTelemetryConsent, Z as stableConfigKey, a as generateProjectId, at as worktreeIntegrationTips, b as validateSettingsBlock, ct as isSameDirectoryPath, d as assetForPlatform, et as matchedPrefix, f as decideRtkInstall, g as verifyDigest, h as isRtkBinaryName, i as ensureProjectIds, it as usablePrefixes, m as installTargetPath, n as DEFAULT_CONFIG, nt as planWorktreeGc, o as glimmervoidHomeDir$1, ot as canonicalizePath, p as findEscapingArchiveMember, q as parsePosthogReleaseId, r as createConfigStore, rt as sessionIdFromBranch, st as comparableDirectoryPath, t as ABORT_CONFIG_SAVE, tt as planBranchGc, v as mergeSettingsBlock, y as settingsBlockSpecFor, z as buildBrowserExceptionProperties } from "./config-store-BEaaXTd5.js";
25
- import { E as USAGE_VENDOR_KEYS, T as USAGE_COST_MODES, _ as PersistedTaskTitle, a as parseDataClientMessage, b as configIssueMessage, c as PendingCrashReport, d as TelemetryState, g as ConfigUpdate, i as parseDataAttachHistory, l as TELEMETRY_EVENT_SCHEMAS, m as BrowserConfig, n as HookEnvelope, o as DashboardTelemetryReport, r as DEEP_HISTORY_SCROLLBACK_LINES, t as HTTP_URL_RE, v as RUNTIME_CONFIG_SCALAR_KEYS, y as TASK_TITLE_SOURCE_PRIORITY } from "./contracts-V_hfT23R.js";
26
- import { A as dedupeCodexFiles, B as shouldPersistWarehouse, C as shortSha$1, D as codexSessionIdFromPath, E as codexRootCandidates, F as passOutcome, H as claudeCode, I as projectDirCandidates, L as resolveProjectsDirs, M as grokHomes, N as grokRootCandidates, O as continuationDelayMs, P as isUsageFile, R as scopedClaudeRoots, S as parseResolvedSha, T as codexHomes, V as splitLines$1, _ as isCheckFresh, a as describeAgentResolvability, b as parseRegistryDeprecation, c as isKnownAgentId, d as resolveAdapter, f as setCustomAgents, g as decideUpdateStatus, h as decideInstallFlavor, i as customAgentFingerprint, j as expandTilde, k as decideFileRead, l as listAgentIds, m as readHostCodexVersion, n as cachedAgentResolvability, o as getAdapter, p as codex, r as commandFor, s as hookProfileOf, t as DEFAULT_AGENT_ID, u as resetCommandCache, v as normalizeSha, w as codexFallbackRoots, x as parseRegistryLatest, y as normalizeUpdateChannel, z as shouldEvaluateDespiteIoFailures } from "./adapters-yVOK5me4.js";
24
+ import { $ as DEFAULT_BRANCH_GC_PREFIXES, B as buildExceptionProperties, F as TELEMETRY_BATCH_URL, G as exceptionFingerprint, H as decideIsDevInstall, I as TELEMETRY_FLAGS_URL, J as resolveProjectToken, K as nodeMajorVersion, L as adapterBucket, P as FIRST_RUN_NOTICE, R as buildAiGenerationEvents, U as decideRemoteTelemetryState, V as classifySessionExit, W as decideTelemetryConsent, Z as stableConfigKey, a as generateProjectId, at as worktreeIntegrationTips, b as validateSettingsBlock, ct as isSameDirectoryPath, d as assetForPlatform, et as matchedPrefix, f as decideRtkInstall, g as verifyDigest, h as isRtkBinaryName, i as ensureProjectIds, it as usablePrefixes, m as installTargetPath, n as DEFAULT_CONFIG, nt as planWorktreeGc, o as glimmervoidHomeDir$1, ot as canonicalizePath, p as findEscapingArchiveMember, q as parsePosthogReleaseId, r as createConfigStore, rt as sessionIdFromBranch, st as comparableDirectoryPath, t as ABORT_CONFIG_SAVE, tt as planBranchGc, v as mergeSettingsBlock, y as settingsBlockSpecFor, z as buildBrowserExceptionProperties } from "./config-store-CxYqTNbe.js";
25
+ import { E as USAGE_VENDOR_KEYS, T as USAGE_COST_MODES, _ as PersistedTaskTitle, a as parseDataClientMessage, b as configIssueMessage, c as PendingCrashReport, d as TelemetryState, g as ConfigUpdate, i as parseDataAttachHistory, l as TELEMETRY_EVENT_SCHEMAS, m as BrowserConfig, n as HookEnvelope, o as DashboardTelemetryReport, r as DEEP_HISTORY_SCROLLBACK_LINES, t as HTTP_URL_RE, v as RUNTIME_CONFIG_SCALAR_KEYS, y as TASK_TITLE_SOURCE_PRIORITY } from "./contracts-C9Jj9iDo.js";
26
+ import { A as dedupeCodexFiles, B as shouldPersistWarehouse, C as shortSha$1, D as codexSessionIdFromPath, E as codexRootCandidates, F as passOutcome, H as claudeCode, I as projectDirCandidates, L as resolveProjectsDirs, M as grokHomes, N as grokRootCandidates, O as continuationDelayMs, P as isUsageFile, R as scopedClaudeRoots, S as parseResolvedSha, T as codexHomes, V as splitLines$1, _ as isCheckFresh, a as describeAgentResolvability, b as parseRegistryDeprecation, c as isKnownAgentId, d as resolveAdapter, f as setCustomAgents, g as decideUpdateStatus, h as decideInstallFlavor, i as customAgentFingerprint, j as expandTilde, k as decideFileRead, l as listAgentIds, m as readHostCodexVersion, n as cachedAgentResolvability, o as getAdapter, p as codex, r as commandFor, s as hookProfileOf, t as DEFAULT_AGENT_ID, u as resetCommandCache, v as normalizeSha, w as codexFallbackRoots, x as parseRegistryLatest, y as normalizeUpdateChannel, z as shouldEvaluateDespiteIoFailures } from "./adapters-CyDflXHy.js";
27
27
  import { t as HOOK_TOOLS } from "./hook-tools-Dl7-r2Eb.js";
28
28
  import { a as formatSshPublicKey, c as orderAgentSockets, i as commitSigningShimText, l as parseSshPublicKey, n as NO_AGENT_HOLDS_KEY, o as isForwardedAgentDirName, r as agentListsKey, s as isSignableGitObject, t as COMMIT_SIGNING_SHIM_NAME } from "./ssh-signing-core-CRhVVWNW.js";
29
- import { a as configSiblingPath, c as defaultPairingsPath, d as decideDeviceAuth, f as deviceNameFromUserAgent, l as defaultSeenPath, n as normalizeRemoteConfig, o as createPairingsStore, p as hashSecret, r as validateRemoteConfig, s as createSeenStore, t as decideBindHost, u as DEFAULT_DEVICE_MAX_AGE_MS } from "./remote-config-DFwmHWed.js";
30
- import { n as configFileViewOf, u as readSettingsForAgent } from "./settings-readout-core-Du7n-zyD.js";
29
+ import { a as configSiblingPath, c as defaultPairingsPath, d as decideDeviceAuth, f as deviceNameFromUserAgent, l as defaultSeenPath, n as normalizeRemoteConfig, o as createPairingsStore, p as hashSecret, r as validateRemoteConfig, s as createSeenStore, t as decideBindHost, u as DEFAULT_DEVICE_MAX_AGE_MS } from "./remote-config-CaW0mpwr.js";
30
+ import { n as configFileViewOf, u as readSettingsForAgent } from "./settings-readout-core-CX7DmEuG.js";
31
31
  import { _ as escapeMarkup, g as createLaneLog, n as createVisionsSetup } from "./visions-setup-DB2P8JUL.js";
32
32
  import { t as getRtkPath } from "./rtk-resolver-BDHi6RMv.js";
33
33
  import { createRequire } from "node:module";
@@ -12813,7 +12813,11 @@ function seedTaskTitleSources({ persistedTitle, resumeSessionId, customTitle, in
12813
12813
  customTitle
12814
12814
  };
12815
12815
  }
12816
- var PROMPT_ENVELOPE_PATTERNS = ["pasted_content", "system-reminder"].map((tag) => new RegExp(`<${tag}\\b[^>]*>[\\s\\S]*?</${tag}\\s*>`, "gi"));
12816
+ var PROMPT_ENVELOPE_PATTERNS = [
12817
+ "pasted_content",
12818
+ "system-reminder",
12819
+ "task-notification"
12820
+ ].map((tag) => new RegExp(`<${tag}\\b[^>]*>[\\s\\S]*?</${tag}\\s*>`, "gi"));
12817
12821
  var MIN_SUBSTANTIVE_WORDS = 3;
12818
12822
  var CONTINUATION_PROMPTS = new Set([
12819
12823
  "yes please continue",
@@ -13391,6 +13395,7 @@ function coderCreateArgs({ workspace, template, stopAfter, parameters = {} }) {
13391
13395
  "--stop-after",
13392
13396
  stopAfter,
13393
13397
  ...parameterArgs,
13398
+ "--use-parameter-defaults",
13394
13399
  "--yes"
13395
13400
  ];
13396
13401
  }
@@ -15882,7 +15887,8 @@ function createSessionHookLifecycle(options) {
15882
15887
  const args = injection.buildHookArgs({
15883
15888
  bypassHookTrust: isTrustBypassed,
15884
15889
  hookTools: options.hookTools,
15885
- userHooks: glimmervoidSuppliedHooks()
15890
+ userHooks: glimmervoidSuppliedHooks(),
15891
+ observeToolCalls: options.observeToolCalls
15886
15892
  });
15887
15893
  if (!args) {
15888
15894
  console.warn(`[session:${options.name}] hook injection skipped: the relay path cannot be expressed for ${options.agentId} - falling back to OSC title only`);
@@ -23737,25 +23743,30 @@ function createTeamReviewPoller(deps) {
23737
23743
  }
23738
23744
  return false;
23739
23745
  }
23740
- function closedPostedKeys(candidateKeys) {
23741
- const departedPosted = Object.entries(state).filter(([key, entry]) => !candidateKeys.has(key) && !entry.inFlight && entry.draft?.status === "posted");
23742
- store.setWatchedKeys("team-review-departed", departedPosted.flatMap(([, entry]) => entry.draft ? [comparablePrKey(entry.draft)] : []));
23746
+ function closedEntryKeys() {
23743
23747
  const prs = store.getSnapshot().prs;
23744
- return new Set(departedPosted.filter(([, entry]) => {
23745
- const pr = entry.draft ? prs[comparablePrKey(entry.draft)] : void 0;
23746
- return pr !== void 0 && pr.state !== "OPEN";
23747
- }).map(([key]) => key));
23748
+ return new Set(Object.keys(state).filter((key) => {
23749
+ const pr = prs[key.toLowerCase()];
23750
+ return !state[key]?.inFlight && pr !== void 0 && pr.state !== "OPEN";
23751
+ }));
23752
+ }
23753
+ function watchDeparted(candidateKeys) {
23754
+ const departedKeys = Object.keys(state).filter((key) => !candidateKeys.has(key) && !state[key]?.inFlight);
23755
+ store.setWatchedKeys("team-review-departed", departedKeys.map((key) => key.toLowerCase()));
23748
23756
  }
23749
- async function pruneDeparted(candidateKeys) {
23757
+ async function pruneDeparted(candidateKeys, isComplete) {
23750
23758
  let isDirty = false;
23751
- const closedKeys = closedPostedKeys(candidateKeys);
23759
+ watchDeparted(candidateKeys);
23760
+ const closedKeys = closedEntryKeys();
23752
23761
  for (const [key, entry] of Object.entries(state)) {
23753
- if (!candidateKeys.has(key) && entry.resumable) {
23762
+ const isClosed = closedKeys.has(key);
23763
+ if (candidateKeys.has(key) || !isComplete && !isClosed) continue;
23764
+ if (entry.resumable) {
23754
23765
  await discardResumable(entry.resumable);
23755
23766
  entry.resumable = null;
23756
23767
  isDirty = true;
23757
23768
  }
23758
- if (!shouldPruneEntry(entry, candidateKeys.has(key), now(), closedKeys.has(key))) continue;
23769
+ if (!shouldPruneEntry(entry, false, now(), isClosed)) continue;
23759
23770
  delete state[key];
23760
23771
  isDirty = true;
23761
23772
  }
@@ -23996,6 +24007,10 @@ function createTeamReviewPoller(deps) {
23996
24007
  const planned = headsToReview(candidates);
23997
24008
  if (planned.isDirty) loop.track(persist());
23998
24009
  emitStatus();
24010
+ if (closedEntryKeys().size > 0) {
24011
+ loop.tickSoon();
24012
+ return;
24013
+ }
23999
24014
  if (planned.queue.length === 0 || !canStartReview()) return;
24000
24015
  const queueSignature = queuedHeadsSignature(planned.queue);
24001
24016
  if (queueSignature === lastRebuildQueueSignature) return;
@@ -24049,7 +24064,7 @@ function createTeamReviewPoller(deps) {
24049
24064
  retryAfterMs: rateLimitWaitMs
24050
24065
  };
24051
24066
  }
24052
- const isPruned = isComplete ? await pruneDeparted(new Set(candidates.map((candidate) => candidate.key))) : false;
24067
+ const isPruned = await pruneDeparted(new Set(candidates.map((candidate) => candidate.key)), isComplete);
24053
24068
  if (isPruned) watchAskedFor();
24054
24069
  const planned = headsToReview(candidates);
24055
24070
  const isStarted = await startReviewsUnlessGuardrailsRefused(planned.queue);
@@ -29690,9 +29705,16 @@ function liveLimitRefusal({ liveCount, maxLive, environmentName }) {
29690
29705
  if (liveCount < maxLive) return null;
29691
29706
  return `${environmentName} already has ${liveCount} of ${maxLive} live workspaces; close one first`;
29692
29707
  }
29708
+ var CODER_ERROR_DETAIL_LIMIT = 200;
29693
29709
  function remoteCheckoutDirectory({ checkoutRoot, workspace }) {
29694
29710
  return path.posix.join(checkoutRoot, workspace);
29695
29711
  }
29712
+ function coderErrorDetail(stderr) {
29713
+ if (typeof stderr !== "string") return null;
29714
+ const errorLine = stderr.split("\n").map((line) => line.trim()).findLast((line) => line.startsWith("error:"));
29715
+ if (!errorLine) return null;
29716
+ return errorLine.slice(6).trim().slice(0, CODER_ERROR_DETAIL_LIMIT) || null;
29717
+ }
29696
29718
  //#endregion
29697
29719
  //#region server/coder/coder-env-poller.ts
29698
29720
  function createCoderEnvPoller({ listWorkspaces, stopWorkspace, deleteWorkspace, sessionsForIdleCheck, mappings, busyWorkspaces, isReconcilePending, deleteAfterStoppedDays, onReconciled, now = Date.now, log = console, ...loopOptions }) {
@@ -29797,8 +29819,9 @@ function createCoderEnvWiring({ config, persistMapping, onReconciled = () => {},
29797
29819
  encoding: "utf8",
29798
29820
  maxBuffer: 16777216
29799
29821
  });
29800
- } catch {
29801
- throw new Error(`Coder ${args[0]} failed`);
29822
+ } catch (error) {
29823
+ const detail = coderErrorDetail(error instanceof Error && "stderr" in error ? error.stderr : null);
29824
+ throw new Error(detail ? `Coder ${args[0]} failed: ${detail}` : `Coder ${args[0]} failed`);
29802
29825
  }
29803
29826
  }
29804
29827
  function command(args, timeoutMs = 3e4) {
@@ -29967,6 +29990,9 @@ function createCoderEnvWiring({ config, persistMapping, onReconciled = () => {},
29967
29990
  ])).stdout);
29968
29991
  if (reason) throw new Error(reason);
29969
29992
  }
29993
+ async function isWorkspaceListed(workspace) {
29994
+ return (await listWorkspaces().catch(() => null))?.some((candidate) => candidate.name === workspace) ?? true;
29995
+ }
29970
29996
  async function failAttempt({ workspace, didCreate, didStart, reason }) {
29971
29997
  const cleanup = failedProvisionCleanup({
29972
29998
  didCreate,
@@ -29980,7 +30006,7 @@ function createCoderEnvWiring({ config, persistMapping, onReconciled = () => {},
29980
30006
  "--yes"
29981
30007
  ]);
29982
30008
  } catch {
29983
- reasons.push(`Coder cleanup ${cleanup} failed for ${workspace}`);
30009
+ if (await isWorkspaceListed(workspace)) reasons.push(`Coder cleanup ${cleanup} failed for ${workspace}`);
29984
30010
  }
29985
30011
  return {
29986
30012
  ok: false,
@@ -41312,17 +41338,19 @@ function resetsAtMs(value) {
41312
41338
  if (numeric > SECONDS_CEILING) return Math.round(numeric);
41313
41339
  return Math.round(numeric * 1e3);
41314
41340
  }
41315
- function normalizeWindow(raw) {
41316
- if (!isRecord(raw)) return null;
41317
- const window = raw;
41318
- const pct = roundPct(window.used_percentage);
41319
- const resetsAt = resetsAtMs(window.resets_at);
41320
- if (pct === null && resetsAt === null) return null;
41341
+ function rateLimitWindow(usedPct, resetsAt) {
41342
+ const pct = roundPct(usedPct);
41343
+ const resetsAtMsValue = resetsAtMs(resetsAt);
41344
+ if (pct === null && resetsAtMsValue === null) return null;
41321
41345
  return {
41322
41346
  pct,
41323
- resetsAtMs: resetsAt
41347
+ resetsAtMs: resetsAtMsValue
41324
41348
  };
41325
41349
  }
41350
+ function normalizeWindow(raw) {
41351
+ if (!isRecord(raw)) return null;
41352
+ return rateLimitWindow(raw.used_percentage, raw.resets_at);
41353
+ }
41326
41354
  function normalizeRateLimits(raw) {
41327
41355
  if (!isRecord(raw)) return null;
41328
41356
  const limits = raw;
@@ -41362,14 +41390,19 @@ function shouldBroadcastPlanLimits(previous, next) {
41362
41390
  if (nextSignature === null) return false;
41363
41391
  return nextSignature !== planLimitsSignature(previous);
41364
41392
  }
41365
- function buildPlanLimitsMessage(snapshot) {
41393
+ var PLAN_LIMITS_SOURCE_BY_VENDOR = Object.freeze({
41394
+ claude: "statusline",
41395
+ codex: "rollout"
41396
+ });
41397
+ function buildPlanLimitsMessage(snapshot, vendor = "claude") {
41366
41398
  if (!snapshot?.rateLimits) return null;
41367
41399
  return {
41368
41400
  type: "plan-limits",
41369
41401
  ts: snapshot.ts,
41370
41402
  fiveHour: snapshot.rateLimits.fiveHour,
41371
41403
  sevenDay: snapshot.rateLimits.sevenDay,
41372
- source: "statusline"
41404
+ source: PLAN_LIMITS_SOURCE_BY_VENDOR[vendor],
41405
+ vendor
41373
41406
  };
41374
41407
  }
41375
41408
  function selectOfficialSessionCost(costMode, recordedCostUSD) {
@@ -41728,6 +41761,39 @@ function parseCodexUsageLine(line, state = createCodexUsageState(), { sessionId
41728
41761
  vendor: "codex"
41729
41762
  });
41730
41763
  }
41764
+ var RATE_LIMITS_MARKER = "\"rate_limits\"";
41765
+ var CODEX_PLAN_LIMIT_ID = "codex";
41766
+ var FIVE_HOUR_WINDOW_MINUTES = 300;
41767
+ var SEVEN_DAY_WINDOW_MINUTES = 10080;
41768
+ function codexPlanWindows(rawWindows) {
41769
+ const windowsByMinutes = /* @__PURE__ */ new Map();
41770
+ for (const rawWindow of rawWindows) {
41771
+ if (!isRecord(rawWindow)) continue;
41772
+ windowsByMinutes.set(numberOr(rawWindow.window_minutes, 0), rateLimitWindow(rawWindow.used_percent, rawWindow.resets_at));
41773
+ }
41774
+ return {
41775
+ fiveHour: windowsByMinutes.get(FIVE_HOUR_WINDOW_MINUTES) ?? null,
41776
+ sevenDay: windowsByMinutes.get(SEVEN_DAY_WINDOW_MINUTES) ?? null
41777
+ };
41778
+ }
41779
+ function parseCodexRateLimitsLine(line) {
41780
+ if (typeof line !== "string" || !line.includes(RATE_LIMITS_MARKER)) return null;
41781
+ const raw = parseJsonLine(line);
41782
+ if (!raw) return null;
41783
+ const parsed = raw;
41784
+ if (parsed.payload?.type !== "token_count") return null;
41785
+ const rateLimits = parsed.payload.rate_limits;
41786
+ if (!isRecord(rateLimits)) return null;
41787
+ if (rateLimits.limit_id != null && rateLimits.limit_id !== CODEX_PLAN_LIMIT_ID) return null;
41788
+ const ts = Date.parse(String(parsed.timestamp));
41789
+ if (!Number.isFinite(ts)) return null;
41790
+ const windows = codexPlanWindows([rateLimits.primary, rateLimits.secondary]);
41791
+ if (!windows.fiveHour && !windows.sevenDay) return null;
41792
+ return {
41793
+ rateLimits: windows,
41794
+ ts
41795
+ };
41796
+ }
41731
41797
  function codexDedupIdentity(entry) {
41732
41798
  if (!entry) return null;
41733
41799
  return [
@@ -42193,6 +42259,7 @@ function createUsageScanner(deps = {}) {
42193
42259
  let lastPartial = false;
42194
42260
  let lastOutcome = null;
42195
42261
  let lastIoFailures = 0;
42262
+ let latestCodexRateLimitSnapshot = null;
42196
42263
  let activePass = null;
42197
42264
  let pendingForce = false;
42198
42265
  let pendingScopeDirs = null;
@@ -42333,6 +42400,14 @@ function createUsageScanner(deps = {}) {
42333
42400
  markDirty();
42334
42401
  return false;
42335
42402
  }
42403
+ function noteCodexRateLimits(snapshot) {
42404
+ if (!snapshot) return;
42405
+ if (latestCodexRateLimitSnapshot && snapshot.ts < latestCodexRateLimitSnapshot.ts) return;
42406
+ latestCodexRateLimitSnapshot = snapshot;
42407
+ }
42408
+ function latestCodexRateLimits() {
42409
+ return latestCodexRateLimitSnapshot;
42410
+ }
42336
42411
  function ingestVendorLine(parsed, file) {
42337
42412
  if (!parsed) return 0;
42338
42413
  return storeEntry(stripIngestFields(priceEntry({
@@ -42342,6 +42417,7 @@ function createUsageScanner(deps = {}) {
42342
42417
  }
42343
42418
  function ingestLine({ line, file, vendor, vendorState, dirs: claudeRoots, lineOrdinal }) {
42344
42419
  if (vendor === "codex") {
42420
+ noteCodexRateLimits(parseCodexRateLimitsLine(line));
42345
42421
  const parsedCodexEntry = parseCodexUsageLine(line, vendorState ?? createCodexUsageState());
42346
42422
  if (!parsedCodexEntry) return 0;
42347
42423
  return ingestVendorLine({
@@ -42903,6 +42979,7 @@ function createUsageScanner(deps = {}) {
42903
42979
  sessionTotals,
42904
42980
  stats,
42905
42981
  budgetSpend,
42982
+ latestCodexRateLimits,
42906
42983
  _entriesForTest: () => entries.map((entry) => entry)
42907
42984
  };
42908
42985
  Object.defineProperty(api, "_entriesForTest", { enumerable: false });
@@ -43019,6 +43096,7 @@ function createUsageWiring({ config, sessions = /* @__PURE__ */ new Map(), broad
43019
43096
  let ioFailureStreak = 0;
43020
43097
  let ioFailureStreakId = 0;
43021
43098
  let planLimits = null;
43099
+ let codexPlanLimits = null;
43022
43100
  const officialCostByClaudeId = /* @__PURE__ */ new Map();
43023
43101
  let budgetFiredState = {
43024
43102
  daily: {},
@@ -43119,13 +43197,16 @@ function createUsageWiring({ config, sessions = /* @__PURE__ */ new Map(), broad
43119
43197
  passInFlight = false;
43120
43198
  }
43121
43199
  if (stopped) return result;
43122
- if (result) laneLog.debugNote(() => "pass complete", () => ({
43123
- files: result.files,
43124
- entries: result.entries,
43125
- newEntries: result.newEntries,
43126
- durationMs: result.durationMs,
43127
- outcome: result.outcome
43128
- }));
43200
+ if (result) {
43201
+ ingestCodexRateLimits(scanner.latestCodexRateLimits());
43202
+ laneLog.debugNote(() => "pass complete", () => ({
43203
+ files: result.files,
43204
+ entries: result.entries,
43205
+ newEntries: result.newEntries,
43206
+ durationMs: result.durationMs,
43207
+ outcome: result.outcome
43208
+ }));
43209
+ }
43129
43210
  if (result?.outcome === "io-failed") {
43130
43211
  ioFailureStreak += 1;
43131
43212
  laneLog.warnOnce(`scan-io:${ioFailureStreakId}`, "scan pass lost files to io errors", {
@@ -43267,8 +43348,18 @@ function createUsageWiring({ config, sessions = /* @__PURE__ */ new Map(), broad
43267
43348
  const message = buildPlanLimitsMessage(snapshot);
43268
43349
  if (message) broadcast(message);
43269
43350
  }
43270
- function getPlanLimitsMessage() {
43351
+ function ingestCodexRateLimits(snapshot) {
43352
+ if (stopped || !cfg.enabled || !cfg.planLimits || !snapshot) return;
43353
+ if (codexPlanLimits && snapshot.ts < codexPlanLimits.ts) return;
43354
+ const changed = shouldBroadcastPlanLimits(codexPlanLimits, snapshot);
43355
+ codexPlanLimits = snapshot;
43356
+ if (!changed) return;
43357
+ const message = buildPlanLimitsMessage(snapshot, "codex");
43358
+ if (message) broadcast(message);
43359
+ }
43360
+ function getPlanLimitsMessage(vendor = "claude") {
43271
43361
  if (!cfg.enabled || !cfg.planLimits) return null;
43362
+ if (vendor === "codex") return buildPlanLimitsMessage(codexPlanLimits, "codex");
43272
43363
  return buildPlanLimitsMessage(planLimits);
43273
43364
  }
43274
43365
  function loadBudgetState() {
@@ -52449,8 +52540,8 @@ function registerControlHandlers(controlWss, deps) {
52449
52540
  if (usageSessions) ws.send(JSON.stringify(usageSessions));
52450
52541
  const usageReport = typeof getUsageReport === "function" ? getUsageReport() : null;
52451
52542
  if (usageReport) ws.send(JSON.stringify(usageReport));
52452
- const planLimits = typeof getPlanLimits === "function" ? getPlanLimits() : null;
52453
- if (planLimits) ws.send(JSON.stringify(planLimits));
52543
+ const planLimitsMessages = typeof getPlanLimits === "function" ? getPlanLimits() : [];
52544
+ for (const planLimits of planLimitsMessages) if (planLimits) ws.send(JSON.stringify(planLimits));
52454
52545
  const since = parseSinceParam(req?.url);
52455
52546
  if (controlReplayLog && since !== null) {
52456
52547
  const { entries, evicted } = controlReplayLog.entriesSince(since);
@@ -52532,7 +52623,7 @@ function createBackendControl(dependencies) {
52532
52623
  getUsageSessions: () => usage.getSessionsMessage(),
52533
52624
  getUsageReport: () => usage.getCachedReport(),
52534
52625
  requestUsageReport: (args) => usage.requestReport(args),
52535
- getPlanLimits: () => usage.getPlanLimitsMessage(),
52626
+ getPlanLimits: () => [usage.getPlanLimitsMessage("claude"), usage.getPlanLimitsMessage("codex")],
52536
52627
  readTracePage: dependencies.readTracePage,
52537
52628
  readPlanRevision: dependencies.readPlanRevision,
52538
52629
  decidePlanReview: dependencies.decidePlanReview,
@@ -1,6 +1,6 @@
1
1
  import { r as errorMessage } from "./text-DoirglWV.js";
2
- import { c as resolveConfigPath } from "./config-store-BEaaXTd5.js";
3
- import { c as defaultPairingsPath, i as REVOCATION_PROPAGATION_SECONDS, l as defaultSeenPath, n as normalizeRemoteConfig, o as createPairingsStore, s as createSeenStore } from "./remote-config-DFwmHWed.js";
2
+ import { c as resolveConfigPath } from "./config-store-CxYqTNbe.js";
3
+ import { c as defaultPairingsPath, i as REVOCATION_PROPAGATION_SECONDS, l as defaultSeenPath, n as normalizeRemoteConfig, o as createPairingsStore, s as createSeenStore } from "./remote-config-CaW0mpwr.js";
4
4
  import fs from "node:fs";
5
5
  //#region server/text-format.ts
6
6
  function trimIso(iso) {
@@ -3,7 +3,7 @@ import { n as equalsIgnoringCaseOnWindows } from "./paths-Bu4eH1Yd.js";
3
3
  import { n as isRecord } from "./coerce-NSst8oRP.js";
4
4
  import { n as unrefTimer, t as DEFAULT_TIMER_FNS } from "./timer-deps-u2DAQLok.js";
5
5
  import { a as jsonStateLoadError, d as writeJsonAtomicSync, l as sleepSync, s as loadJsonStateFileSync, u as writeJsonAtomic } from "./json-file-DFCTvPjj.js";
6
- import { o as glimmervoidHomeDir, ot as canonicalizePath } from "./config-store-BEaaXTd5.js";
6
+ import { o as glimmervoidHomeDir, ot as canonicalizePath } from "./config-store-CxYqTNbe.js";
7
7
  import fs from "node:fs";
8
8
  import path from "node:path";
9
9
  import crypto from "node:crypto";