glimmervoid 0.40.0 → 0.41.0

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 (42) hide show
  1. package/dist/bin/glimmervoid.js +18 -18
  2. package/dist/chunks/{adapters-CXQfLoyj.js → adapters-JDV45XpZ.js} +1 -1
  3. package/dist/chunks/{adapters-B6tbX3Aj.js → adapters-yVOK5me4.js} +293 -15
  4. package/dist/chunks/{agent-api-cli-BNHJTmNW.js → agent-api-cli-1xk9WryE.js} +12 -3
  5. package/dist/chunks/{agent-api-cli-BBech5lF.js → agent-api-cli-BSY2jR0P.js} +1 -1
  6. package/dist/chunks/{agent-api-core-DDrJQEdE.js → agent-api-core-syEPHs7j.js} +22 -4
  7. package/dist/chunks/{agent-setup-cli-CeBBwKuL.js → agent-setup-cli-py1gUMvJ.js} +1 -1
  8. package/dist/chunks/child-process-safe-CjVtRjDD.js +1 -0
  9. package/dist/chunks/{child-process-safe-CbQnyh7D.js → child-process-safe-D4hyVIXj.js} +4 -1
  10. package/dist/chunks/{config-store-DqMScSdg.js → config-store-BEaaXTd5.js} +38 -2
  11. package/dist/chunks/config-store-DE_r4DP8.js +1 -0
  12. package/dist/chunks/{contracts-CloExMlS.js → contracts-V_hfT23R.js} +167 -6
  13. package/dist/chunks/{control-messages-DpBaniJi.js → control-messages-Ci4g6gD1.js} +110 -2
  14. package/dist/chunks/{git-version-CJQMfxtZ.js → git-version-D_iXgYTZ.js} +2 -2
  15. package/dist/chunks/{grok-BLzhApwT.js → grok-BUGgQVE3.js} +1 -1
  16. package/dist/chunks/{guardrails-deps-CLxK4J-g.js → guardrails-deps-BjPzk1rE.js} +1 -1
  17. package/dist/chunks/{main-DDU8IvFD.js → main-Bbh8ky2x.js} +8458 -5740
  18. package/dist/chunks/{pair-cli-CsOVTQGJ.js → pair-cli-DkItUGpT.js} +2 -2
  19. package/dist/chunks/{remote-config-HlABuLTp.js → remote-config-DFwmHWed.js} +1 -1
  20. package/dist/chunks/{rtk-resolver-BgoPsEhT.js → rtk-resolver-BDHi6RMv.js} +1 -1
  21. package/dist/chunks/rtk-resolver-Dr4iJsiS.js +1 -0
  22. package/dist/chunks/{session-BwB43SCa.js → session-C8IpFmGQ.js} +39 -3
  23. package/dist/chunks/{session-routes-DNJzsckH.js → session-routes-nySS7DUE.js} +36 -2
  24. package/dist/chunks/{settings-cli-DkkbK-dj.js → settings-cli-CaYd3bUH.js} +5 -5
  25. package/dist/chunks/{settings-readout-core-DrXT4aWm.js → settings-readout-core-Du7n-zyD.js} +2 -2
  26. package/dist/chunks/{ssh-sign-cli-CYeKRevK.js → ssh-sign-cli-BLzmQ3Vh.js} +3 -3
  27. package/dist/chunks/{visions-cli-CYujESdJ.js → visions-cli-CVRB9IWA.js} +1 -1
  28. package/dist/chunks/{visions-setup-B-ZeRdsi.js → visions-setup-DB2P8JUL.js} +1 -1
  29. package/dist/client/assets/index-D7QFo-gy.js +176 -0
  30. package/dist/client/assets/index-DKnOk67Z.css +2 -0
  31. package/dist/client/index.html +2 -3
  32. package/dist/scripts/postinstall-path-check.js +1 -1
  33. package/dist/server/index.js +1 -1
  34. package/dist/session/guardrails-open-launcher.js +1 -1
  35. package/dist/session/hook-tool-relay.js +1 -1
  36. package/dist/session/statusline-relay.js +1 -1
  37. package/package.json +1 -1
  38. package/dist/chunks/child-process-safe-ChRmWAJP.js +0 -1
  39. package/dist/chunks/config-store-BZpN2djp.js +0 -1
  40. package/dist/chunks/rtk-resolver-BGE6Hd_L.js +0 -1
  41. package/dist/client/assets/index-BK9jLR47.js +0 -148
  42. package/dist/client/assets/index-CU_uqJmi.css +0 -2
@@ -2,13 +2,13 @@
2
2
  import { o as nodePtyRebuildHint, r as firstLine, t as probeNodePty } from "../chunks/node-pty-preflight-C8QIlrtU.js";
3
3
  import { i as errorText } from "../chunks/text-DoirglWV.js";
4
4
  import { a as packageRoot } from "../chunks/runtime-paths-BkeftE60.js";
5
- import { t as AGENT_API_VERBS } from "../chunks/session-BwB43SCa.js";
6
- import { i as execSync } from "../chunks/child-process-safe-CbQnyh7D.js";
7
- import { r as agentCommandHelpLines } from "../chunks/agent-api-core-DDrJQEdE.js";
5
+ import { t as AGENT_API_VERBS } from "../chunks/session-C8IpFmGQ.js";
6
+ import { i as execSync } from "../chunks/child-process-safe-D4hyVIXj.js";
7
+ import { r as agentCommandHelpLines } from "../chunks/agent-api-core-syEPHs7j.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
- import { i as parseCommandLine, r as gitDoctorRows, t as probeGitVersion } from "../chunks/git-version-CJQMfxtZ.js";
11
- import { i as guardrailsDoctorRows, r as probeGuardrailsDependencies } from "../chunks/guardrails-deps-CLxK4J-g.js";
10
+ import { i as parseCommandLine, r as gitDoctorRows, t as probeGitVersion } from "../chunks/git-version-D_iXgYTZ.js";
11
+ import { i as guardrailsDoctorRows, r as probeGuardrailsDependencies } from "../chunks/guardrails-deps-BjPzk1rE.js";
12
12
  import { i as pnpmGlobalBinDir, n as npmGlobalBinDir, r as onPath, t as formatPathNotice } from "../chunks/path-doctor-C23VAqeu.js";
13
13
  import fs from "node:fs";
14
14
  import path from "node:path";
@@ -65,29 +65,29 @@ var OWN_SUBCOMMAND_RUNNERS = [
65
65
  return 0;
66
66
  }],
67
67
  ["pair", async (subcommandArgs) => {
68
- const { runPairCli } = await import("../chunks/pair-cli-CsOVTQGJ.js");
68
+ const { runPairCli } = await import("../chunks/pair-cli-DkItUGpT.js");
69
69
  return runPairCli(subcommandArgs);
70
70
  }],
71
71
  ["agent", async (subcommandArgs) => {
72
- const { runAgentSetupCli } = await import("../chunks/agent-setup-cli-CeBBwKuL.js");
72
+ const { runAgentSetupCli } = await import("../chunks/agent-setup-cli-py1gUMvJ.js");
73
73
  return runAgentSetupCli(subcommandArgs);
74
74
  }],
75
75
  ["settings", async (subcommandArgs) => {
76
- const { runSettingsCli } = await import("../chunks/settings-cli-DkkbK-dj.js");
76
+ const { runSettingsCli } = await import("../chunks/settings-cli-CaYd3bUH.js");
77
77
  return runSettingsCli(subcommandArgs);
78
78
  }],
79
79
  ["visions", async (subcommandArgs) => {
80
- const { runVisionsCli } = await import("../chunks/visions-cli-CYujESdJ.js");
80
+ const { runVisionsCli } = await import("../chunks/visions-cli-CVRB9IWA.js");
81
81
  return runVisionsCli(subcommandArgs);
82
82
  }],
83
83
  ["ssh-sign", async (subcommandArgs) => {
84
- const { runSshSignCli } = await import("../chunks/ssh-sign-cli-CYeKRevK.js");
84
+ const { runSshSignCli } = await import("../chunks/ssh-sign-cli-BLzmQ3Vh.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-BBech5lF.js");
90
+ const { runAgentApiCli } = await import("../chunks/agent-api-cli-BSY2jR0P.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-BBech5lF.js");
104
+ const { sessionLimitsHelpLines } = await import("../chunks/agent-api-cli-BSY2jR0P.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-BZpN2djp.js");
161
+ const { loadConfigFile } = await import("../chunks/config-store-DE_r4DP8.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-CXQfLoyj.js");
237
+ const { listAgentIds, describeAgentResolvability, setCustomAgents } = await import("../chunks/adapters-JDV45XpZ.js");
238
238
  const declaredCustomAgents = await readDeclaredCustomAgents();
239
239
  if (declaredCustomAgents.error) line("config", declaredCustomAgents.error);
240
240
  setCustomAgents(declaredCustomAgents.declared);
@@ -242,7 +242,7 @@ async function runDoctor() {
242
242
  const { label, path: resolvedPath } = describeAgentResolvability(id);
243
243
  line(`${id} (${label})`, resolvedPath ?? missingAgentText(id));
244
244
  }
245
- const { inspectGrokAgentSetup } = await import("../chunks/agent-setup-cli-CeBBwKuL.js");
245
+ const { inspectGrokAgentSetup } = await import("../chunks/agent-setup-cli-py1gUMvJ.js");
246
246
  const grokSetup = inspectGrokAgentSetup();
247
247
  line("grok hook setup", `${grokSetup.classification}: ${grokSetup.filePath}`);
248
248
  } catch (err) {
@@ -250,7 +250,7 @@ async function runDoctor() {
250
250
  }
251
251
  switchSection("rtk");
252
252
  try {
253
- const { getRtkPath } = await import("../chunks/rtk-resolver-BGE6Hd_L.js");
253
+ const { getRtkPath } = await import("../chunks/rtk-resolver-Dr4iJsiS.js");
254
254
  line("rtk", getRtkPath() || "not installed (Glimmervoid installs it when the rtk setting is on)");
255
255
  } catch (err) {
256
256
  line("rtk", `probe failed: ${firstLine(errorText(err))}`);
@@ -258,8 +258,8 @@ async function runDoctor() {
258
258
  switchSection("Sane YOLO");
259
259
  try {
260
260
  const { resolvePackageBin } = await import("../chunks/runtime-paths-DSmormp7.js");
261
- const { execFileSync } = await import("../chunks/child-process-safe-ChRmWAJP.js");
262
- const { inspectGrokAgentSetup } = await import("../chunks/agent-setup-cli-CeBBwKuL.js");
261
+ const { execFileSync } = await import("../chunks/child-process-safe-CjVtRjDD.js");
262
+ const { inspectGrokAgentSetup } = await import("../chunks/agent-setup-cli-py1gUMvJ.js");
263
263
  const binPath = resolvePackageBin("cc-safety-net", "cc-safety-net");
264
264
  line("Sane YOLO", binPath || "not installed");
265
265
  if (binPath) line("cc-safety-net version", execFileSync(process.execPath, [binPath, "--version"], {
@@ -1 +1 @@
1
- export { a as describeAgentResolvability, l as listAgentIds, f as setCustomAgents } from "./adapters-B6tbX3Aj.js";
1
+ export { a as describeAgentResolvability, l as listAgentIds, f as setCustomAgents } from "./adapters-yVOK5me4.js";
@@ -1,13 +1,14 @@
1
1
  import { o as relayPath } from "./runtime-paths-BkeftE60.js";
2
- import { r as execFileSync } from "./child-process-safe-CbQnyh7D.js";
3
- import "./control-messages-DpBaniJi.js";
4
- import { o as supervisionLine } from "./session-routes-DNJzsckH.js";
2
+ import { Lt as FULL_SHA_RE, zt as shortSha$1 } from "./session-C8IpFmGQ.js";
3
+ import { n as execFileAsync, r as execFileSync } from "./child-process-safe-D4hyVIXj.js";
4
+ import { a as InstallFlavor } from "./control-messages-Ci4g6gD1.js";
5
+ import { o as supervisionLine } from "./session-routes-nySS7DUE.js";
5
6
  import { n as resolveAgentCommand, t as buildAgentSpawnCommand } from "./spawn-command-Cc40FiZI.js";
6
- import { s as rawTextOr } from "./coerce-NSst8oRP.js";
7
+ import { c as textOr, s as rawTextOr } from "./coerce-NSst8oRP.js";
7
8
  import { r as nextBackoffMs } from "./backoff-DjVpfHk7.js";
8
- import { i as isSpinnerChar, n as classifyAgentTitle, r as isBrailleChar, s as buildAgentEnv, t as grok } from "./grok-BLzhApwT.js";
9
+ import { i as isSpinnerChar, n as classifyAgentTitle, r as isBrailleChar, s as buildAgentEnv, t as grok } from "./grok-BUGgQVE3.js";
9
10
  import { t as buildHookCommand } from "./hook-command-core-qTNK-xMF.js";
10
- import "./contracts-CloExMlS.js";
11
+ import "./contracts-V_hfT23R.js";
11
12
  import { n as mergeCodexPreToolUse, t as HOOK_TOOLS } from "./hook-tools-Dl7-r2Eb.js";
12
13
  import fs from "node:fs";
13
14
  import path from "node:path";
@@ -77,6 +78,7 @@ function mapHookToSignal$1(event, payload) {
77
78
  case "sessionend": return "session-end";
78
79
  case "userpromptsubmit": return "resume";
79
80
  case "stop": return "ready";
81
+ case "stopfailure": return payload?.error === "authentication_failed" ? "auth-failed" : "ready";
80
82
  case "subagentstart": return "subagent-start";
81
83
  case "subagentstop": return "subagent-stop";
82
84
  case "taskcreated": return "task-created";
@@ -396,18 +398,240 @@ function codexSessionIdFromPath(filePath) {
396
398
  return base || null;
397
399
  }
398
400
  //#endregion
399
- //#region session/adapters/codex.ts
400
- var ID = "codex";
401
- var COMMAND_NAME = "codex";
402
- var RELAY_PATH = relayPath("hook-relay");
403
- var HOOK_TOOL_RELAY_PATH = relayPath("hook-tool-relay");
404
- var HOOK_EVENTS = [
401
+ //#region shared/repo.ts
402
+ var REPO_SLUG = "johncwaters/glimmervoid";
403
+ //#endregion
404
+ //#region server/core/update-core.ts
405
+ var NPM_PACKAGE_NAME = "glimmervoid";
406
+ var NPM_GLOBAL_COMMAND = `npm install -g ${NPM_PACKAGE_NAME}@latest`;
407
+ var NODE_PTY_INSTALL_SCRIPT_FLAG = "--allow-scripts=node-pty";
408
+ var NPX_CACHE_DIRECTORY_NAME = "_npx";
409
+ var CLONE_COMMAND = "git pull --ff-only && npm ci && npm run build";
410
+ var INSTALL_FLAVORS = new Set(InstallFlavor.options);
411
+ var TAG_VERSION_RE = /^v(\d+\.\d+\.\d+)$/;
412
+ var UPDATE_CHANNELS = /* @__PURE__ */ new Set(["release", "main"]);
413
+ var DEPRECATION_MESSAGE_MAX_CHARS = 500;
414
+ function normalizeSha(value) {
415
+ if (typeof value !== "string") return null;
416
+ const sha = value.trim().toLowerCase();
417
+ if (!FULL_SHA_RE.test(sha)) return null;
418
+ return sha;
419
+ }
420
+ function shortSha(value) {
421
+ return shortSha$1(normalizeSha(value) ?? "");
422
+ }
423
+ function parseResolvedSha(resolved) {
424
+ if (typeof resolved !== "string") return null;
425
+ const fragmentAt = resolved.lastIndexOf("#");
426
+ if (fragmentAt === -1) return null;
427
+ return normalizeSha(resolved.slice(fragmentAt + 1));
428
+ }
429
+ function parseTagVersion(ref) {
430
+ if (typeof ref !== "string") return null;
431
+ const normalized = ref.trim().replace(/^refs\/tags\//, "").replace(/\^\{\}$/, "");
432
+ const matched = TAG_VERSION_RE.exec(normalized);
433
+ if (!matched) return null;
434
+ return matched[1];
435
+ }
436
+ function isNpxCachePath(packageRoot) {
437
+ if (typeof packageRoot !== "string") return false;
438
+ return packageRoot.split(/[\\/]/).includes(NPX_CACHE_DIRECTORY_NAME);
439
+ }
440
+ function decideInstallFlavor({ packageRoot, lockfileSha, gitHeadSha, hasGitDir, isInsideNodeModules } = {}) {
441
+ const fromLockfile = normalizeSha(lockfileSha);
442
+ if (isNpxCachePath(packageRoot)) return {
443
+ flavor: "npx",
444
+ installedSha: fromLockfile ?? normalizeSha(gitHeadSha)
445
+ };
446
+ if (fromLockfile) return {
447
+ flavor: "npm-global",
448
+ installedSha: fromLockfile
449
+ };
450
+ const fromGitHead = normalizeSha(gitHeadSha);
451
+ if (fromGitHead) return {
452
+ flavor: "npm-global",
453
+ installedSha: fromGitHead
454
+ };
455
+ if (hasGitDir) return {
456
+ flavor: "clone",
457
+ installedSha: null
458
+ };
459
+ if (isInsideNodeModules) return {
460
+ flavor: "npm-global",
461
+ installedSha: null
462
+ };
463
+ return {
464
+ flavor: "unknown",
465
+ installedSha: null
466
+ };
467
+ }
468
+ function buildNpxCommand(latestVersion, platform) {
469
+ const packageSpec = `${NPM_PACKAGE_NAME}@${textOr(latestVersion, null) ?? "latest"}`;
470
+ if (platform === "linux") return `npx ${NODE_PTY_INSTALL_SCRIPT_FLAG} ${packageSpec}`;
471
+ return `npx ${packageSpec}`;
472
+ }
473
+ function buildNpmGlobalCommand(latestVersion, platform) {
474
+ const version = textOr(latestVersion, null);
475
+ const installCommand = version ? `npm install -g ${NPM_PACKAGE_NAME}@${version}` : NPM_GLOBAL_COMMAND;
476
+ if (platform === "linux") return `${installCommand} ${NODE_PTY_INSTALL_SCRIPT_FLAG}`;
477
+ return installCommand;
478
+ }
479
+ function buildUpdateCommand(flavor, latestVersion, platform) {
480
+ if (flavor === "npx") return buildNpxCommand(latestVersion, platform);
481
+ if (flavor === "npm-global") return buildNpmGlobalCommand(latestVersion, platform);
482
+ return CLONE_COMMAND;
483
+ }
484
+ function buildReleaseUrl(version) {
485
+ const releaseVersion = textOr(version, null);
486
+ if (!releaseVersion) return null;
487
+ return `https://github.com/${REPO_SLUG}/releases/tag/v${releaseVersion}`;
488
+ }
489
+ function parseVersionTriple(version) {
490
+ if (typeof version !== "string") return null;
491
+ const parts = version.trim().replace(/^v/, "").split(/[-+]/)[0].split(".");
492
+ if (parts.length !== 3) return null;
493
+ const triple = [];
494
+ for (const part of parts) {
495
+ if (!/^\d+$/.test(part)) return null;
496
+ triple.push(Number.parseInt(part, 10));
497
+ }
498
+ return triple;
499
+ }
500
+ function compareSemver(a, b) {
501
+ const ta = parseVersionTriple(a);
502
+ const tb = parseVersionTriple(b);
503
+ if (!ta || !tb) return 0;
504
+ for (let i = 0; i < 3; i += 1) {
505
+ if (ta[i] > tb[i]) return 1;
506
+ if (ta[i] < tb[i]) return -1;
507
+ }
508
+ return 0;
509
+ }
510
+ function parseRegistryLatest(doc) {
511
+ if (!doc || typeof doc !== "object") return null;
512
+ const registryDocument = doc;
513
+ const publishedVersion = textOr(registryDocument.version, null);
514
+ if (!publishedVersion) return null;
515
+ const version = parseTagVersion(`v${publishedVersion}`);
516
+ if (!version) return null;
517
+ return {
518
+ version,
519
+ sha: normalizeSha(registryDocument.gitHead)
520
+ };
521
+ }
522
+ function parseRegistryDeprecation(doc) {
523
+ if (!doc || typeof doc !== "object") return null;
524
+ const deprecated = doc.deprecated;
525
+ if (typeof deprecated !== "string") return null;
526
+ const message = deprecated.trim();
527
+ if (!message) return null;
528
+ return message.slice(0, DEPRECATION_MESSAGE_MAX_CHARS);
529
+ }
530
+ function normalizeFlavor(flavor) {
531
+ if (typeof flavor === "string" && INSTALL_FLAVORS.has(flavor)) return flavor;
532
+ return "unknown";
533
+ }
534
+ function normalizeUpdateChannel(channel) {
535
+ if (typeof channel === "string" && UPDATE_CHANNELS.has(channel)) return channel;
536
+ return "release";
537
+ }
538
+ function normalizeBehindCount(value) {
539
+ if (!Number.isInteger(value)) return null;
540
+ const count = Number(value);
541
+ if (count < 0) return null;
542
+ return count;
543
+ }
544
+ function decideUpdateReason({ isReleaseAlreadyCheckedOut, reason }) {
545
+ if (isReleaseAlreadyCheckedOut) return "release-already-checked-out";
546
+ return textOr(reason, null);
547
+ }
548
+ function decideUpdateStatus({ installedSha, latestSha: remoteSha, currentVersion, latestVersion, flavor, platform, channel, behindCount, reason, isLatestReleaseAncestorOfHead, deprecation } = {}) {
549
+ const currentSha = normalizeSha(installedSha);
550
+ const latestSha = normalizeSha(remoteSha);
551
+ const current = textOr(currentVersion, null);
552
+ const latest = textOr(latestVersion, null);
553
+ const normalizedFlavor = normalizeFlavor(flavor);
554
+ const normalizedChannel = normalizeUpdateChannel(channel);
555
+ const normalizedBehindCount = normalizeBehindCount(behindCount);
556
+ const isReleaseAlreadyCheckedOut = normalizedChannel === "release" && normalizedFlavor === "clone" && isLatestReleaseAncestorOfHead === true && compareSemver(latest, current) > 0;
557
+ return {
558
+ updateAvailable: normalizedChannel === "main" ? normalizedBehindCount !== null && normalizedBehindCount > 0 && currentSha !== latestSha : !isReleaseAlreadyCheckedOut && compareSemver(latest, current) > 0,
559
+ current,
560
+ latest,
561
+ currentSha,
562
+ latestSha,
563
+ releaseUrl: buildReleaseUrl(latest),
564
+ command: buildUpdateCommand(flavor, latest, platform),
565
+ flavor: normalizedFlavor,
566
+ channel: normalizedChannel,
567
+ behindCount: normalizedBehindCount,
568
+ reason: decideUpdateReason({
569
+ isReleaseAlreadyCheckedOut,
570
+ reason
571
+ }),
572
+ deprecation: isReleaseAlreadyCheckedOut ? null : parseRegistryDeprecation({ deprecated: deprecation })
573
+ };
574
+ }
575
+ function isCheckFresh(lastCheckAt, nowMs, ttlMs) {
576
+ if (!Number.isFinite(lastCheckAt)) return false;
577
+ if (!Number.isFinite(nowMs)) return false;
578
+ if (!Number.isFinite(ttlMs)) return false;
579
+ const age = Number(nowMs) - Number(lastCheckAt);
580
+ if (age < 0) return false;
581
+ return age < Number(ttlMs);
582
+ }
583
+ //#endregion
584
+ //#region session/core/codex-version-core.ts
585
+ var CODEX_EXTENDED_HOOKS_FLOOR = "0.163.0";
586
+ var LEGACY_HOOK_EVENTS = [
405
587
  "SessionStart",
406
588
  "SessionEnd",
407
589
  "UserPromptSubmit",
408
590
  "Stop",
409
591
  "PermissionRequest"
410
592
  ];
593
+ var EXTENDED_HOOK_EVENTS = [
594
+ ...LEGACY_HOOK_EVENTS,
595
+ "PreCompact",
596
+ "PostCompact",
597
+ "SubagentStart",
598
+ "SubagentStop"
599
+ ];
600
+ var EXTENDED_MATCHED_RELAY_HOOKS = [{
601
+ event: "PreToolUse",
602
+ matcher: "request_user_input"
603
+ }, {
604
+ event: "PostToolUse",
605
+ matcher: "Bash"
606
+ }];
607
+ var CODEX_VERSION_RE = /\bcodex-cli\s+(\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?)\b/;
608
+ var PRERELEASE_SUFFIX_RE = /^[^+]*-/;
609
+ function parseCodexVersion(versionOutput) {
610
+ if (typeof versionOutput !== "string") return null;
611
+ return CODEX_VERSION_RE.exec(versionOutput)?.[1] ?? null;
612
+ }
613
+ function isAtOrAboveExtendedHooksFloor(installedVersion) {
614
+ const releaseOrder = compareSemver(installedVersion, CODEX_EXTENDED_HOOKS_FLOOR);
615
+ if (releaseOrder !== 0) return releaseOrder > 0;
616
+ return !PRERELEASE_SUFFIX_RE.test(installedVersion);
617
+ }
618
+ function codexHookPlanFor(installedVersion) {
619
+ if (!(installedVersion !== null && isAtOrAboveExtendedHooksFloor(installedVersion))) return {
620
+ events: [...LEGACY_HOOK_EVENTS],
621
+ matchedRelayHooks: []
622
+ };
623
+ return {
624
+ events: [...EXTENDED_HOOK_EVENTS],
625
+ matchedRelayHooks: EXTENDED_MATCHED_RELAY_HOOKS
626
+ };
627
+ }
628
+ //#endregion
629
+ //#region session/adapters/codex.ts
630
+ var ID = "codex";
631
+ var COMMAND_NAME = "codex";
632
+ var RELAY_PATH = relayPath("hook-relay");
633
+ var HOOK_TOOL_RELAY_PATH = relayPath("hook-tool-relay");
634
+ var HOOK_EVENTS = LEGACY_HOOK_EVENTS;
411
635
  var envProfile$1 = {
412
636
  scrub: [],
413
637
  set: {}
@@ -468,7 +692,7 @@ function userConfigFolders(env) {
468
692
  return codexHomes(env, null);
469
693
  }
470
694
  var TOML_LITERAL_STRING_FORBIDDEN = /[\x00-\x08\x0a-\x1f\x27\x7f]/;
471
- function buildHookArgs({ relayPath = RELAY_PATH, events = HOOK_EVENTS, bypassHookTrust = false, hookTools = [], hookToolRelayPath = HOOK_TOOL_RELAY_PATH, userHooks = [] } = {}) {
695
+ function buildHookArgs({ relayPath = RELAY_PATH, events = HOOK_EVENTS, matchedRelayHooks = [], bypassHookTrust = false, hookTools = [], hookToolRelayPath = HOOK_TOOL_RELAY_PATH, userHooks = [] } = {}) {
472
696
  const args = bypassHookTrust ? [TRUST_BYPASS_FLAG] : [];
473
697
  const preToolUseGroups = [];
474
698
  const groupsByEvent = /* @__PURE__ */ new Map();
@@ -481,6 +705,16 @@ function buildHookArgs({ relayPath = RELAY_PATH, events = HOOK_EVENTS, bypassHoo
481
705
  }
482
706
  groupsByEvent.set(event, [`{hooks=[{type='command',command='${command}'}]}`]);
483
707
  }
708
+ for (const { event, matcher } of matchedRelayHooks) {
709
+ const command = buildHookCommand(relayPath, event);
710
+ if (!command) return null;
711
+ const group = `{matcher='${matcher}',hooks=[{type='command',command='${command}'}]}`;
712
+ if (event === "PreToolUse") {
713
+ preToolUseGroups.push(group);
714
+ continue;
715
+ }
716
+ groupsByEvent.set(event, [...groupsByEvent.get(event) ?? [], group]);
717
+ }
484
718
  const groups = hookTools.flatMap((tool) => {
485
719
  const group = HOOK_TOOLS[tool.id].codexGroup(tool, hookToolRelayPath);
486
720
  return group ? [group] : [];
@@ -505,6 +739,50 @@ function buildHookArgs({ relayPath = RELAY_PATH, events = HOOK_EVENTS, bypassHoo
505
739
  args.push(...mergeCodexPreToolUse(preToolUseGroups));
506
740
  return args;
507
741
  }
742
+ var installedHookPlan = null;
743
+ function probeInstalledCodexVersion() {
744
+ const versionCommand = buildSpawnCommand({
745
+ platform: process.platform,
746
+ resolved: resolveCommand(),
747
+ agentArgs: ["--version"]
748
+ });
749
+ try {
750
+ return parseCodexVersion(execFileSync(versionCommand.file, versionCommand.args, {
751
+ encoding: "utf8",
752
+ timeout: 3e3,
753
+ windowsHide: true
754
+ }));
755
+ } catch {
756
+ return null;
757
+ }
758
+ }
759
+ async function readHostCodexVersion() {
760
+ const versionCommand = buildSpawnCommand({
761
+ platform: process.platform,
762
+ resolved: resolveCommand(),
763
+ agentArgs: ["--version"]
764
+ });
765
+ try {
766
+ const { stdout } = await execFileAsync(versionCommand.file, versionCommand.args, {
767
+ encoding: "utf8",
768
+ timeout: 3e3,
769
+ windowsHide: true
770
+ });
771
+ return parseCodexVersion(stdout);
772
+ } catch {
773
+ return null;
774
+ }
775
+ }
776
+ function hookPlanForInstalledCodex() {
777
+ installedHookPlan ??= codexHookPlanFor(probeInstalledCodexVersion());
778
+ return installedHookPlan;
779
+ }
780
+ function buildInstalledHookArgs(options = {}) {
781
+ return buildHookArgs({
782
+ ...hookPlanForInstalledCodex(),
783
+ ...options
784
+ });
785
+ }
508
786
  var hooks = {
509
787
  mapSignal: mapHookToSignal,
510
788
  mapConfidence: mapHookConfidence,
@@ -513,7 +791,7 @@ var hooks = {
513
791
  kind: "argv-config",
514
792
  relayPath: RELAY_PATH,
515
793
  events: HOOK_EVENTS,
516
- buildHookArgs,
794
+ buildHookArgs: buildInstalledHookArgs,
517
795
  projectConfigCandidates: PROJECT_CONFIG_CANDIDATES,
518
796
  userConfigFolders,
519
797
  mayContributeHooks
@@ -803,4 +1081,4 @@ function resetCommandCache() {
803
1081
  resolvedCommands.clear();
804
1082
  }
805
1083
  //#endregion
806
- export { splitLines as A, isUsageFile as C, scopedClaudeRoots as D, resolveProjectsDirs as E, shouldEvaluateDespiteIoFailures as O, grokRootCandidates as S, projectDirCandidates as T, continuationDelayMs as _, describeAgentResolvability as a, expandTilde as b, isKnownAgentId as c, resolveAdapter as d, setCustomAgents as f, codexSessionIdFromPath as g, codexRootCandidates as h, customAgentFingerprint as i, claudeCode as j, shouldPersistWarehouse as k, listAgentIds as l, codexHomes as m, cachedAgentResolvability as n, getAdapter as o, codexFallbackRoots as p, commandFor as r, hookProfileOf as s, DEFAULT_AGENT_ID as t, resetCommandCache as u, decideFileRead as v, passOutcome as w, grokHomes as x, dedupeCodexFiles as y };
1084
+ export { dedupeCodexFiles as A, shouldPersistWarehouse as B, shortSha as C, codexSessionIdFromPath as D, codexRootCandidates as E, passOutcome as F, claudeCode as H, projectDirCandidates as I, resolveProjectsDirs as L, grokHomes as M, grokRootCandidates as N, continuationDelayMs as O, isUsageFile as P, scopedClaudeRoots as R, parseResolvedSha as S, codexHomes as T, splitLines as V, isCheckFresh as _, describeAgentResolvability as a, parseRegistryDeprecation as b, isKnownAgentId as c, resolveAdapter as d, setCustomAgents as f, decideUpdateStatus as g, decideInstallFlavor as h, customAgentFingerprint as i, expandTilde as j, decideFileRead as k, listAgentIds as l, readHostCodexVersion as m, cachedAgentResolvability as n, getAdapter as o, codex as p, commandFor as r, hookProfileOf as s, DEFAULT_AGENT_ID as t, resetCommandCache as u, normalizeSha as v, codexFallbackRoots as w, parseRegistryLatest as x, normalizeUpdateChannel as y, shouldEvaluateDespiteIoFailures as z };
@@ -1,7 +1,7 @@
1
1
  import { t as errorCode } from "./text-DoirglWV.js";
2
- import { n as AGENT_URL_ENV, o as AgentLimitsReply } from "./session-BwB43SCa.js";
3
- import { i as formatSessionLimits } from "./session-routes-DNJzsckH.js";
4
- import { l as isAgentApiVerb, t as AGENT_COMMAND_HELP } from "./agent-api-core-DDrJQEdE.js";
2
+ import { n as AGENT_URL_ENV, s as AgentLimitsReply } from "./session-C8IpFmGQ.js";
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";
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";
@@ -20,6 +20,15 @@ var BODY_BUILDERS = {
20
20
  const prompt = rest.join(" ").trim();
21
21
  return prompt ? { prompt } : null;
22
22
  },
23
+ send: (rest) => rest.join(" ").trim() ? { words: rest } : null,
24
+ read: (rest) => {
25
+ const child = rest.join(" ").trim();
26
+ return child ? { child } : {};
27
+ },
28
+ close: (rest) => {
29
+ const child = rest.join(" ").trim();
30
+ return child ? { child } : null;
31
+ },
23
32
  attention: (rest) => {
24
33
  const note = rest.join(" ").trim();
25
34
  return note ? { note } : null;
@@ -1 +1 @@
1
- export { t as askAgentApi, r as runAgentApiCli, i as sessionLimitsHelpLines } from "./agent-api-cli-BNHJTmNW.js";
1
+ export { t as askAgentApi, r as runAgentApiCli, i as sessionLimitsHelpLines } from "./agent-api-cli-1xk9WryE.js";
@@ -1,6 +1,6 @@
1
- import { a as AgentEditRequest, i as AgentAttentionRequest, l as AgentSettingsRequest, s as AgentPullRequestRequest, t as AGENT_API_VERBS, u as AgentSpawnRequest } from "./session-BwB43SCa.js";
2
- import { a as pullRequestKeyFromReference } from "./control-messages-DpBaniJi.js";
3
- import { n as NO_OWN_WORKTREE_REASON, t as COMMAND_ROUTES } from "./session-routes-DNJzsckH.js";
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";
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;
6
6
  var REFUSAL_REASON = "unknown session";
@@ -117,6 +117,9 @@ var parsePullRequestBody = (payload) => {
117
117
  };
118
118
  var REQUEST_PARSERS = Object.freeze({
119
119
  spawn: bodyParser(AgentSpawnRequest),
120
+ send: bodyParser(AgentSendRequest),
121
+ read: bodyParser(AgentReadRequest),
122
+ close: bodyParser(AgentCloseRequest),
120
123
  attention: bodyParser(AgentAttentionRequest),
121
124
  board: parseEmptyBody,
122
125
  push: parseEmptyBody,
@@ -243,9 +246,24 @@ var USAGE_COLUMN_WIDTH = 20;
243
246
  var AGENT_COMMAND_HELP = Object.freeze({
244
247
  spawn: {
245
248
  usage: "spawn <prompt>",
246
- summary: "Start a sibling session on that prompt",
249
+ summary: "Start a session on that prompt that this session owns until its task is done",
247
250
  missingArgumentHint: "glimmervoid spawn: this command needs text, for example \"glimmervoid spawn check the failing test\""
248
251
  },
252
+ send: {
253
+ usage: "send [child] <text>",
254
+ summary: "Message a session this one spawned; a spawned session messages its parent with send <text>",
255
+ missingArgumentHint: "glimmervoid send: this command needs text, for example \"glimmervoid send the tests pass\" or, to a spawned session, \"glimmervoid send <child> fix the failing test\""
256
+ },
257
+ read: {
258
+ usage: "read [child]",
259
+ summary: "Read what this session's spawned sessions sent; a spawned session reads its parent's messages",
260
+ missingArgumentHint: null
261
+ },
262
+ close: {
263
+ usage: "close <child>",
264
+ summary: "End a session this one spawned, once its task is done",
265
+ missingArgumentHint: "glimmervoid close: this command needs the spawned session, for example \"glimmervoid close <child>\""
266
+ },
249
267
  attention: {
250
268
  usage: "attention <note>",
251
269
  summary: "Flag this session as needing the operator",
@@ -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-BLzhApwT.js";
2
+ import { a as classifyGrokHooksFile, o as renderGrokHooksFile, t as grok } from "./grok-BUGgQVE3.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";
@@ -0,0 +1 @@
1
+ export { r as execFileSync } from "./child-process-safe-D4hyVIXj.js";
@@ -47,7 +47,10 @@ var execFile = Object.assign(function execFile(file, ...rest) {
47
47
  const child = cp.execFile(file, args, execOptions, callback);
48
48
  if (typeof input !== "string") return;
49
49
  if (!child.stdin) return reject(/* @__PURE__ */ new Error("execFile stdin unavailable"));
50
- child.stdin.on("error", reject);
50
+ child.stdin.on("error", (error) => {
51
+ if (error.code === "EPIPE") return;
52
+ reject(error);
53
+ });
51
54
  child.stdin.end(input);
52
55
  }) });
53
56
  function execFileSync(file, ...rest) {