glimmervoid 0.46.2-next.133 → 0.46.2-next.134

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 (82) hide show
  1. package/dist/bin/glimmervoid.js +4 -4
  2. package/dist/chunks/{adapters-DVtQx5Fs.js → adapters-DMeOQP2O.js} +1 -1
  3. package/dist/chunks/{adapters-Czb4h3s-.js → adapters-i2Es-0GX.js} +1 -1
  4. package/dist/chunks/{build-channel-CwCQx6A3.js → build-channel-BagN5O58.js} +11 -1
  5. package/dist/chunks/{config-store-4G4l-YqH.js → config-store-BAXTD5pl.js} +1 -1
  6. package/dist/chunks/config-store-D7eZueBf.js +1 -0
  7. package/dist/chunks/{main-Dktf7LHr.js → main-DEhHLmq9.js} +40 -12
  8. package/dist/chunks/{pair-cli-D6nQSpfp.js → pair-cli-DFm5XuQE.js} +2 -2
  9. package/dist/chunks/{remote-config-CboQE2_Q.js → remote-config-Bv4Nal9G.js} +1 -1
  10. package/dist/chunks/{settings-cli-BZ-gcH89.js → settings-cli-BF3SEUx0.js} +2 -2
  11. package/dist/chunks/{settings-readout-core-DSYFlRYP.js → settings-readout-core-BpZxCRUo.js} +1 -1
  12. package/dist/client/assets/{alert-sound-Bz56fKhi.js → alert-sound-gcFWc22f.js} +1 -1
  13. package/dist/client/assets/alert-sound-gcFWc22f.js.br +0 -0
  14. package/dist/client/assets/{benchmark-panel-BhfqPNeE.js → benchmark-panel-DYYirG4l.js} +1 -1
  15. package/dist/client/assets/benchmark-panel-DYYirG4l.js.br +0 -0
  16. package/dist/client/assets/{celebration-player-ktXp__K7.js → celebration-player-DV0icaa2.js} +1 -1
  17. package/dist/client/assets/celebration-player-DV0icaa2.js.br +0 -0
  18. package/dist/client/assets/{dialogs-DhsL9BJn.js → dialogs-DIef9tyM.js} +1 -1
  19. package/dist/client/assets/dialogs-DIef9tyM.js.br +0 -0
  20. package/dist/client/assets/{doc-editor-ui-BguQQD4O.js → doc-editor-ui-BJQVHhbH.js} +1 -1
  21. package/dist/client/assets/doc-editor-ui-BJQVHhbH.js.br +0 -0
  22. package/dist/client/assets/{first-run-checklist-DNjehQ7c.js → first-run-checklist-CYo1l6SW.js} +1 -1
  23. package/dist/client/assets/first-run-checklist-CYo1l6SW.js.br +0 -0
  24. package/dist/client/assets/{hooks-panel-CrhWNnIW.js → hooks-panel-BFCJKAoL.js} +1 -1
  25. package/dist/client/assets/hooks-panel-BFCJKAoL.js.br +0 -0
  26. package/dist/client/assets/{index-CAztrZ9Y.js → index-BZuCoMuc.js} +5 -5
  27. package/dist/client/assets/index-BZuCoMuc.js.br +0 -0
  28. package/dist/client/assets/{issues-panel-ClEW4Uuh.js → issues-panel-zwRfcpoK.js} +1 -1
  29. package/dist/client/assets/issues-panel-zwRfcpoK.js.br +0 -0
  30. package/dist/client/assets/{nyan-cat-PAcq3ZKA.js → nyan-cat-DU1rwXss.js} +1 -1
  31. package/dist/client/assets/nyan-cat-DU1rwXss.js.br +0 -0
  32. package/dist/client/assets/{phone-shell-DtLwDM1N.js → phone-shell-Bcfl7FwR.js} +1 -1
  33. package/dist/client/assets/phone-shell-Bcfl7FwR.js.br +0 -0
  34. package/dist/client/assets/{plan-face-BhNGxYSa.js → plan-face-CX7gzssd.js} +1 -1
  35. package/dist/client/assets/plan-face-CX7gzssd.js.br +0 -0
  36. package/dist/client/assets/{plan-render-BtAm6TFY.js → plan-render-BILDNp_T.js} +1 -1
  37. package/dist/client/assets/plan-render-BILDNp_T.js.br +0 -0
  38. package/dist/client/assets/{pr-scope-tabs-C-PX4ICw.js → pr-scope-tabs-BXnmNtAC.js} +1 -1
  39. package/dist/client/assets/pr-scope-tabs-BXnmNtAC.js.br +0 -0
  40. package/dist/client/assets/{radar-panel-jjWD9x_D.js → radar-panel-BjIjdKOE.js} +1 -1
  41. package/dist/client/assets/radar-panel-BjIjdKOE.js.br +0 -0
  42. package/dist/client/assets/{resume-dialog-DyN3q3Ne.js → resume-dialog-CWAcGzUY.js} +1 -1
  43. package/dist/client/assets/resume-dialog-CWAcGzUY.js.br +0 -0
  44. package/dist/client/assets/{review-queue-panel-DbQMpyWR.js → review-queue-panel-D83S71YV.js} +1 -1
  45. package/dist/client/assets/review-queue-panel-D83S71YV.js.br +0 -0
  46. package/dist/client/assets/{settings-panel-N_ndnZWU.js → settings-panel-C1PBX3EX.js} +2 -2
  47. package/dist/client/assets/settings-panel-C1PBX3EX.js.br +0 -0
  48. package/dist/client/assets/{shown-lightbox-DNPty4Yy.js → shown-lightbox-BUxkUxwi.js} +1 -1
  49. package/dist/client/assets/shown-lightbox-BUxkUxwi.js.br +0 -0
  50. package/dist/client/assets/{trace-panel-B2Hx0xW7.js → trace-panel-Cho6aIw1.js} +1 -1
  51. package/dist/client/assets/trace-panel-Cho6aIw1.js.br +0 -0
  52. package/dist/client/assets/{usage-panel-DT-7cOAk.js → usage-panel-C_ehLta0.js} +1 -1
  53. package/dist/client/assets/usage-panel-C_ehLta0.js.br +0 -0
  54. package/dist/client/assets/{visions-panel-DxWaIZcY.js → visions-panel-Bt-bf727.js} +1 -1
  55. package/dist/client/assets/visions-panel-Bt-bf727.js.br +0 -0
  56. package/dist/client/index.html +1 -1
  57. package/dist/client/index.html.br +0 -0
  58. package/dist/server/index.js +1 -1
  59. package/package.json +1 -1
  60. package/dist/chunks/config-store-BfQmvWFI.js +0 -1
  61. package/dist/client/assets/alert-sound-Bz56fKhi.js.br +0 -0
  62. package/dist/client/assets/benchmark-panel-BhfqPNeE.js.br +0 -0
  63. package/dist/client/assets/celebration-player-ktXp__K7.js.br +0 -0
  64. package/dist/client/assets/dialogs-DhsL9BJn.js.br +0 -0
  65. package/dist/client/assets/doc-editor-ui-BguQQD4O.js.br +0 -0
  66. package/dist/client/assets/first-run-checklist-DNjehQ7c.js.br +0 -0
  67. package/dist/client/assets/hooks-panel-CrhWNnIW.js.br +0 -0
  68. package/dist/client/assets/index-CAztrZ9Y.js.br +0 -0
  69. package/dist/client/assets/issues-panel-ClEW4Uuh.js.br +0 -0
  70. package/dist/client/assets/nyan-cat-PAcq3ZKA.js.br +0 -0
  71. package/dist/client/assets/phone-shell-DtLwDM1N.js.br +0 -0
  72. package/dist/client/assets/plan-face-BhNGxYSa.js.br +0 -0
  73. package/dist/client/assets/plan-render-BtAm6TFY.js.br +0 -0
  74. package/dist/client/assets/pr-scope-tabs-C-PX4ICw.js.br +0 -0
  75. package/dist/client/assets/radar-panel-jjWD9x_D.js.br +0 -0
  76. package/dist/client/assets/resume-dialog-DyN3q3Ne.js.br +0 -0
  77. package/dist/client/assets/review-queue-panel-DbQMpyWR.js.br +0 -0
  78. package/dist/client/assets/settings-panel-N_ndnZWU.js.br +0 -0
  79. package/dist/client/assets/shown-lightbox-DNPty4Yy.js.br +0 -0
  80. package/dist/client/assets/trace-panel-B2Hx0xW7.js.br +0 -0
  81. package/dist/client/assets/usage-panel-DT-7cOAk.js.br +0 -0
  82. package/dist/client/assets/visions-panel-DxWaIZcY.js.br +0 -0
@@ -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-D6nQSpfp.js");
68
+ const { runPairCli } = await import("../chunks/pair-cli-DFm5XuQE.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-BZ-gcH89.js");
76
+ const { runSettingsCli } = await import("../chunks/settings-cli-BF3SEUx0.js");
77
77
  return runSettingsCli(subcommandArgs);
78
78
  }],
79
79
  ["visions", async (subcommandArgs) => {
@@ -158,7 +158,7 @@ async function readDeclaredCustomAgents() {
158
158
  declared: [],
159
159
  error: null
160
160
  };
161
- const { loadConfigFile } = await import("../chunks/config-store-BfQmvWFI.js");
161
+ const { loadConfigFile } = await import("../chunks/config-store-D7eZueBf.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-Czb4h3s-.js");
237
+ const { listAgentIds, describeAgentResolvability, setCustomAgents } = await import("../chunks/adapters-i2Es-0GX.js");
238
238
  const declaredCustomAgents = await readDeclaredCustomAgents();
239
239
  if (declaredCustomAgents.error) line("config", declaredCustomAgents.error);
240
240
  setCustomAgents(declaredCustomAgents.declared);
@@ -8,7 +8,7 @@ import { n as resolveAgentCommand, t as buildAgentSpawnCommand } from "./spawn-c
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-B0SXkBAj.js";
10
10
  import { t as buildHookCommand } from "./hook-command-core-qTNK-xMF.js";
11
- import { n as isExperimentalBuild, t as compareReleaseVersions } from "./build-channel-CwCQx6A3.js";
11
+ import { n as isExperimentalBuild, t as compareReleaseVersions } from "./build-channel-BagN5O58.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";
@@ -1 +1 @@
1
- export { a as describeAgentResolvability, l as listAgentIds, f as setCustomAgents } from "./adapters-DVtQx5Fs.js";
1
+ export { a as describeAgentResolvability, l as listAgentIds, f as setCustomAgents } from "./adapters-DMeOQP2O.js";
@@ -311,6 +311,13 @@ function parseDataClientMessage(raw) {
311
311
  if (!parsed.success) return null;
312
312
  return parsed.data;
313
313
  }
314
+ var FAST_TERMINAL_CLOSE_MS = 1e3;
315
+ var LOGGED_FAST_CLOSE_COUNTS = /* @__PURE__ */ new Set([
316
+ 1,
317
+ 5,
318
+ 25,
319
+ 100
320
+ ]);
314
321
  function attachQueryOf(rawUrl) {
315
322
  if (typeof rawUrl !== "string") return new URLSearchParams();
316
323
  const queryAt = rawUrl.indexOf("?");
@@ -325,6 +332,9 @@ function parseDataAttach(rawUrl) {
325
332
  isOutputPaused: query.get(DATA_ATTACH_OUTPUT_PARAM) === DATA_ATTACH_PAUSED_OUTPUT
326
333
  };
327
334
  }
335
+ function describeDataAttach(attach) {
336
+ return attach.isOutputPaused ? `${attach.history} paused` : attach.history;
337
+ }
328
338
  //#endregion
329
339
  //#region shared/contracts/hooks.ts
330
340
  var HTTP_URL_RE = /^https?:\/\/\S+$/i;
@@ -381,4 +391,4 @@ function isExperimentalBuild(version) {
381
391
  return parsed !== null && parsed.experimentalBuildNumber !== null;
382
392
  }
383
393
  //#endregion
384
- export { DEEP_HISTORY_SCROLLBACK_LINES as a, DashboardTelemetryReport as c, TELEMETRY_EVENT_SCHEMAS as d, TELEMETRY_KILL_SWITCH_FLAG as f, HookEnvelope as i, FeatureFlagsResponse as l, isExperimentalBuild as n, parseDataAttach as o, TelemetryState as p, HTTP_URL_RE as r, parseDataClientMessage as s, compareReleaseVersions as t, PendingCrashReport as u };
394
+ export { DEEP_HISTORY_SCROLLBACK_LINES as a, describeDataAttach as c, DashboardTelemetryReport as d, FeatureFlagsResponse as f, TelemetryState as g, TELEMETRY_KILL_SWITCH_FLAG as h, HookEnvelope as i, parseDataAttach as l, TELEMETRY_EVENT_SCHEMAS as m, isExperimentalBuild as n, FAST_TERMINAL_CLOSE_MS as o, PendingCrashReport as p, HTTP_URL_RE as r, LOGGED_FAST_CLOSE_COUNTS as s, compareReleaseVersions as t, parseDataClientMessage as u };
@@ -6,7 +6,7 @@ import { $ as PORT_RANGE, J as FLYING_ANIMALS_GAP_RANGE, K as FLYING_ANIMALS_DEF
6
6
  import { n as isRecord } from "./coerce-NSst8oRP.js";
7
7
  import { t as DEFAULT_TIMER_FNS } from "./timer-deps-u2DAQLok.js";
8
8
  import { d as writeJsonAtomicSync, f as writeTextAtomic, p as writeTextAtomicSync } from "./json-file-BjFK_eSH.js";
9
- import { f as TELEMETRY_KILL_SWITCH_FLAG, l as FeatureFlagsResponse, n as isExperimentalBuild } from "./build-channel-CwCQx6A3.js";
9
+ import { f as FeatureFlagsResponse, h as TELEMETRY_KILL_SWITCH_FLAG, n as isExperimentalBuild } from "./build-channel-BagN5O58.js";
10
10
  import fs from "node:fs";
11
11
  import path from "node:path";
12
12
  import os from "node:os";
@@ -0,0 +1 @@
1
+ export { c as loadConfigFile } from "./config-store-BAXTD5pl.js";
@@ -22,13 +22,13 @@ import { n as unrefTimer, t as DEFAULT_TIMER_FNS } from "./timer-deps-u2DAQLok.j
22
22
  import { a as readPageTitle, i as filesAfterRetention, n as decideShownKind, o as shownMimeForFilename, r as describeOverCap, t as SHOWN_SNIFF_BYTES } from "./shown-files-core-C7ER2sw2.js";
23
23
  import { n as shellQuote } from "./hook-command-core-qTNK-xMF.js";
24
24
  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-BjFK_eSH.js";
25
- import { $ as resolveProjectToken, B as buildAiGenerationEvents, G as claudeAccountUuidOf, H as buildExceptionProperties, I as FIRST_RUN_NOTICE, J as decideRemoteTelemetryState, K as codexUserIdOf, L as TELEMETRY_BATCH_URL, Q as parsePosthogReleaseId, R as TELEMETRY_FLAGS_URL, S as validateSettingsBlock, U as buildPersonProperties, V as buildBrowserExceptionProperties, W as classifySessionExit, X as exceptionFingerprint, Y as decideTelemetryConsent, Z as nodeMajorVersion, _ as isRtkBinaryName, a as ensureProjectIds, at as matchedPrefix, b as mergeSettingsBlock, ct as sessionIdFromBranch, dt as canonicalizePath, ft as comparableDirectoryPath, g as installTargetPath, h as findEscapingArchiveMember, i as createConfigStore, it as DEFAULT_BRANCH_GC_PREFIXES, lt as usablePrefixes, m as decideRtkInstall, n as DEFAULT_CONFIG, nt as stableConfigKey, o as generateProjectId, ot as planBranchGc, p as assetForPlatform, pt as isSameDirectoryPath, q as decideIsDevInstall, s as glimmervoidHomeDir$1, st as planWorktreeGc, t as ABORT_CONFIG_SAVE, ut as worktreeIntegrationTips, v as verifyDigest, x as settingsBlockSpecFor, z as adapterBucket } from "./config-store-4G4l-YqH.js";
26
- import { a as DEEP_HISTORY_SCROLLBACK_LINES, c as DashboardTelemetryReport, d as TELEMETRY_EVENT_SCHEMAS, i as HookEnvelope, o as parseDataAttach, p as TelemetryState, r as HTTP_URL_RE, s as parseDataClientMessage, u as PendingCrashReport } from "./build-channel-CwCQx6A3.js";
27
- import { A as decideFileRead, B as shouldEvaluateDespiteIoFailures, C as pickNewestPublished, D as codexRootCandidates, E as codexHomes, F as isUsageFile, H as splitLines$1, I as passOutcome, L as projectDirCandidates, M as expandTilde, N as grokHomes, O as codexSessionIdFromPath, P as grokRootCandidates, R as resolveProjectsDirs, S as parseResolvedSha, T as codexFallbackRoots, U as claudeCode, V as shouldPersistWarehouse, _ 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 dedupeCodexFiles, k as continuationDelayMs, 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 shortSha$1, x as parseRegistryLatest, y as normalizeUpdateChannel, z as scopedClaudeRoots } from "./adapters-DVtQx5Fs.js";
25
+ import { $ as resolveProjectToken, B as buildAiGenerationEvents, G as claudeAccountUuidOf, H as buildExceptionProperties, I as FIRST_RUN_NOTICE, J as decideRemoteTelemetryState, K as codexUserIdOf, L as TELEMETRY_BATCH_URL, Q as parsePosthogReleaseId, R as TELEMETRY_FLAGS_URL, S as validateSettingsBlock, U as buildPersonProperties, V as buildBrowserExceptionProperties, W as classifySessionExit, X as exceptionFingerprint, Y as decideTelemetryConsent, Z as nodeMajorVersion, _ as isRtkBinaryName, a as ensureProjectIds, at as matchedPrefix, b as mergeSettingsBlock, ct as sessionIdFromBranch, dt as canonicalizePath, ft as comparableDirectoryPath, g as installTargetPath, h as findEscapingArchiveMember, i as createConfigStore, it as DEFAULT_BRANCH_GC_PREFIXES, lt as usablePrefixes, m as decideRtkInstall, n as DEFAULT_CONFIG, nt as stableConfigKey, o as generateProjectId, ot as planBranchGc, p as assetForPlatform, pt as isSameDirectoryPath, q as decideIsDevInstall, s as glimmervoidHomeDir$1, st as planWorktreeGc, t as ABORT_CONFIG_SAVE, ut as worktreeIntegrationTips, v as verifyDigest, x as settingsBlockSpecFor, z as adapterBucket } from "./config-store-BAXTD5pl.js";
26
+ import { a as DEEP_HISTORY_SCROLLBACK_LINES, c as describeDataAttach, d as DashboardTelemetryReport, g as TelemetryState, i as HookEnvelope, l as parseDataAttach, m as TELEMETRY_EVENT_SCHEMAS, p as PendingCrashReport, r as HTTP_URL_RE, s as LOGGED_FAST_CLOSE_COUNTS, u as parseDataClientMessage } from "./build-channel-BagN5O58.js";
27
+ import { A as decideFileRead, B as shouldEvaluateDespiteIoFailures, C as pickNewestPublished, D as codexRootCandidates, E as codexHomes, F as isUsageFile, H as splitLines$1, I as passOutcome, L as projectDirCandidates, M as expandTilde, N as grokHomes, O as codexSessionIdFromPath, P as grokRootCandidates, R as resolveProjectsDirs, S as parseResolvedSha, T as codexFallbackRoots, U as claudeCode, V as shouldPersistWarehouse, _ 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 dedupeCodexFiles, k as continuationDelayMs, 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 shortSha$1, x as parseRegistryLatest, y as normalizeUpdateChannel, z as scopedClaudeRoots } from "./adapters-DMeOQP2O.js";
28
28
  import { t as HOOK_TOOLS } from "./hook-tools-Dl7-r2Eb.js";
29
29
  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";
30
- 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-CboQE2_Q.js";
31
- import { n as configFileViewOf, u as readSettingsForAgent } from "./settings-readout-core-DSYFlRYP.js";
30
+ 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-Bv4Nal9G.js";
31
+ import { n as configFileViewOf, u as readSettingsForAgent } from "./settings-readout-core-BpZxCRUo.js";
32
32
  import { _ as escapeMarkup, g as createLaneLog, n as createVisionsSetup } from "./visions-setup-VMMyqOpl.js";
33
33
  import { t as getRtkPath } from "./rtk-resolver-C_IReILP.js";
34
34
  import { createRequire } from "node:module";
@@ -5621,6 +5621,7 @@ function sendPtySizeFrame(sender, size) {
5621
5621
  sender.sendOutOfBand(Buffer.from(JSON.stringify(frame), "utf8"));
5622
5622
  }
5623
5623
  var OUTPUT_BEAT_FRAME = Buffer.from(JSON.stringify({ type: "output-beat" }), "utf8");
5624
+ var NO_LIVE_SESSION_KEY = "";
5624
5625
  function frameType(stamped) {
5625
5626
  return typeof stamped.type === "string" ? stamped.type : "";
5626
5627
  }
@@ -5642,6 +5643,8 @@ function createBackendWebSockets(dependencies) {
5642
5643
  });
5643
5644
  const controlReplayLog = createReplayLog();
5644
5645
  const sessionDataClients = /* @__PURE__ */ new Map();
5646
+ const fastCloseCountBySessionKey = /* @__PURE__ */ new Map();
5647
+ const socketsClosedByServer = /* @__PURE__ */ new WeakSet();
5645
5648
  let nextViewerResizeSeq = 0;
5646
5649
  function controlClients() {
5647
5650
  return controlWss.clients;
@@ -5662,25 +5665,50 @@ function createBackendWebSockets(dependencies) {
5662
5665
  function closeSessionDataClients(sessionId) {
5663
5666
  const clients = sessionDataClients.get(sessionId);
5664
5667
  if (!clients) return;
5665
- for (const socket of clients.keys()) socket.close(1001, "Session removed");
5668
+ for (const socket of clients.keys()) closeDataSocketFromServer(socket, 1001, "Session removed");
5666
5669
  sessionDataClients.delete(sessionId);
5670
+ fastCloseCountBySessionKey.delete(sessionId);
5671
+ }
5672
+ function closeDataSocketFromServer(socket, code, reason) {
5673
+ socketsClosedByServer.add(socket);
5674
+ socket.close(code, reason);
5675
+ }
5676
+ function logDataSocketClose(socket, sessionId, attachDescription, openedAtMs, code, reason) {
5677
+ const openMs = Date.now() - openedAtMs;
5678
+ const isReject = code === 1008;
5679
+ const session = sessionId === null ? null : getSession(sessionId);
5680
+ const sessionKey = session ? session.id : NO_LIVE_SESSION_KEY;
5681
+ if (openMs >= 1e3 && !isReject) {
5682
+ fastCloseCountBySessionKey.delete(sessionKey);
5683
+ return;
5684
+ }
5685
+ const fastCloseCount = (fastCloseCountBySessionKey.get(sessionKey) ?? 0) + 1;
5686
+ fastCloseCountBySessionKey.set(sessionKey, fastCloseCount);
5687
+ if (!LOGGED_FAST_CLOSE_COUNTS.has(fastCloseCount)) return;
5688
+ const label = session ? session.name : `unknown session ${sessionId ?? "(invalid id)"}`;
5689
+ const closer = socketsClosedByServer.has(socket) ? "server" : "peer";
5690
+ logger.warn(`[data-ws] ${label} closed after ${openMs} ms by ${closer}: code ${code}, reason '${reason}', attach ${attachDescription}, fast close ${fastCloseCount}x`);
5667
5691
  }
5668
5692
  function attachDataConnection() {
5669
5693
  dataWss.on("connection", (socket, request) => {
5670
5694
  recordOutcome("dataWsOpened");
5671
- socket.on("close", () => recordOutcome("dataWsClosed"));
5695
+ const openedAtMs = Date.now();
5672
5696
  const sessionId = dataSessionIdFromUrl(request.url);
5697
+ const attach = parseDataAttach(request.url);
5698
+ socket.on("close", (code, reason) => {
5699
+ recordOutcome("dataWsClosed");
5700
+ logDataSocketClose(socket, sessionId, describeDataAttach(attach), openedAtMs, code, reason.toString());
5701
+ });
5673
5702
  if (sessionId === null) {
5674
- socket.close(1008, "Invalid session id");
5703
+ closeDataSocketFromServer(socket, 1008, "Invalid session id");
5675
5704
  return;
5676
5705
  }
5677
5706
  const session = getSession(sessionId);
5678
5707
  if (!session) {
5679
- socket.close(1008, "Session not found");
5708
+ closeDataSocketFromServer(socket, 1008, "Session not found");
5680
5709
  return;
5681
5710
  }
5682
5711
  socket.on("error", (error) => reportDataSocketError(session, error));
5683
- const attach = parseDataAttach(request.url);
5684
5712
  if (attach.history === "screen") {
5685
5713
  wireDataSocket(socket, session, sessionId, session.getScreenSnapshot(), {
5686
5714
  isAttachedPaused: attach.isOutputPaused,
@@ -5697,7 +5725,7 @@ function createBackendWebSockets(dependencies) {
5697
5725
  socket.off("message", holdMessage);
5698
5726
  if (socket.readyState !== WebSocket.OPEN) return;
5699
5727
  if (getSession(sessionId) !== session) {
5700
- socket.close(1008, "Session not found");
5728
+ closeDataSocketFromServer(socket, 1008, "Session not found");
5701
5729
  return;
5702
5730
  }
5703
5731
  wireDataSocket(socket, session, sessionId, snapshot, {
@@ -5707,7 +5735,7 @@ function createBackendWebSockets(dependencies) {
5707
5735
  for (const raw of messagesBeforeWiring) socket.emit("message", raw, false);
5708
5736
  }, (error) => {
5709
5737
  logger.warn(`[data-ws] Deep history failed for ${session.name}: ${String(error)}`);
5710
- socket.close(1011, "History unavailable");
5738
+ closeDataSocketFromServer(socket, 1011, "History unavailable");
5711
5739
  });
5712
5740
  });
5713
5741
  }
@@ -1,6 +1,6 @@
1
1
  import { r as errorMessage } from "./text-DoirglWV.js";
2
- import { l as resolveConfigPath } from "./config-store-4G4l-YqH.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-CboQE2_Q.js";
2
+ import { l as resolveConfigPath } from "./config-store-BAXTD5pl.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-Bv4Nal9G.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-BjFK_eSH.js";
6
- import { dt as canonicalizePath, s as glimmervoidHomeDir } from "./config-store-4G4l-YqH.js";
6
+ import { dt as canonicalizePath, s as glimmervoidHomeDir } from "./config-store-BAXTD5pl.js";
7
7
  import fs from "node:fs";
8
8
  import path from "node:path";
9
9
  import crypto from "node:crypto";
@@ -4,8 +4,8 @@ import { f as AgentSettingsReply } from "./session-B2Wieg0a.js";
4
4
  import { r as BrowserConfig } from "./config-DCY3jSvU.js";
5
5
  import { n as isRecord } from "./coerce-NSst8oRP.js";
6
6
  import { t as renderTable } from "./ascii-figure-core-pDAwtlKO.js";
7
- import { A as setValueAtPath, F as SETTINGS_REGISTRY, N as valueAtPath, O as parsePosthogProjectSelection, T as deleteValueAtPath, c as loadConfigFile, d as validateConfig, et as ENV_SECRET_BINDINGS, f as isSettingAvailable, k as scoreSettingsSearch, r as IS_EXPERIMENTAL_BUILD, rt as withEnvSecrets, tt as readEnvSecrets, u as saveConfigFileOnce, w as cloneValue } from "./config-store-4G4l-YqH.js";
8
- import { a as fail, c as listSettings, d as renderSectionTables, f as requireConfigFileSetting, g as valueText, h as succeed, i as describeSetting, l as readSetting, m as settingsRequestForServer, n as configFileViewOf, o as fitColumn, p as sectionOf, r as defaultText, s as getSetting, t as availableSettings } from "./settings-readout-core-DSYFlRYP.js";
7
+ import { A as setValueAtPath, F as SETTINGS_REGISTRY, N as valueAtPath, O as parsePosthogProjectSelection, T as deleteValueAtPath, c as loadConfigFile, d as validateConfig, et as ENV_SECRET_BINDINGS, f as isSettingAvailable, k as scoreSettingsSearch, r as IS_EXPERIMENTAL_BUILD, rt as withEnvSecrets, tt as readEnvSecrets, u as saveConfigFileOnce, w as cloneValue } from "./config-store-BAXTD5pl.js";
8
+ import { a as fail, c as listSettings, d as renderSectionTables, f as requireConfigFileSetting, g as valueText, h as succeed, i as describeSetting, l as readSetting, m as settingsRequestForServer, n as configFileViewOf, o as fitColumn, p as sectionOf, r as defaultText, s as getSetting, t as availableSettings } from "./settings-readout-core-BpZxCRUo.js";
9
9
  import fs from "node:fs";
10
10
  import os from "node:os";
11
11
  import { parseArgs } from "node:util";
@@ -1,6 +1,6 @@
1
1
  import { p as AgentSettingsRequest } from "./session-B2Wieg0a.js";
2
2
  import { t as renderTable } from "./ascii-figure-core-pDAwtlKO.js";
3
- import { C as SETTINGS_INDEX, D as hasScaledUnit, E as displayText, F as SETTINGS_REGISTRY, M as settingsOf, N as valueAtPath, P as FILE_ONLY_GROUPS, f as isSettingAvailable, j as settingsGroupOf, tt as readEnvSecrets, w as cloneValue } from "./config-store-4G4l-YqH.js";
3
+ import { C as SETTINGS_INDEX, D as hasScaledUnit, E as displayText, F as SETTINGS_REGISTRY, M as settingsOf, N as valueAtPath, P as FILE_ONLY_GROUPS, f as isSettingAvailable, j as settingsGroupOf, tt as readEnvSecrets, w as cloneValue } from "./config-store-BAXTD5pl.js";
4
4
  import { parseArgs } from "node:util";
5
5
  //#region server/core/settings-readout-core.ts
6
6
  var VALUE_COLUMN_WIDTH = 40;
@@ -1 +1 @@
1
- import{Bi as e,Gi as t,Hi as n,Ki as r,Ui as i,Vi as a,Wi as o,zi as s}from"./index-CAztrZ9Y.js";var c=.3,l=null;function u(){return r(l)}function d(e){return t(e,l)}async function f(){try{let e=await fetch(s,{credentials:`same-origin`,cache:`no-store`});e.ok&&(l=o(await e.json()))}catch{}}function p(){let e=new AudioContext;return e.state===`suspended`&&e.resume(),e}function m(e,t){setTimeout(()=>e.close().catch(()=>{}),(t+.1)*1e3)}function h(e){g(a[e]??a.chime)}function g(e){let t=p(),n=t.createGain();n.gain.value=e.peakGain,n.connect(t.destination);let r=t.currentTime,i=0;for(let a of e.tones){let e=r+a.startSeconds,o=e+a.durationSeconds,s=t.createOscillator(),c=t.createGain();s.type=a.waveform,s.frequency.setValueAtTime(a.frequency,e),a.endFrequency&&s.frequency.exponentialRampToValueAtTime(a.endFrequency,o),c.gain.setValueAtTime(.001,e),c.gain.exponentialRampToValueAtTime(a.gain??1,e+.01),c.gain.exponentialRampToValueAtTime(.001,o),s.connect(c),c.connect(n),s.start(e),s.stop(o),i=Math.max(i,a.startSeconds+a.durationSeconds)}m(t,i)}async function _(e){try{let t=await fetch(i(e),{credentials:`same-origin`});return t.ok?await t.arrayBuffer():null}catch{return null}}async function v(e){let t=await _(e);if(!t)return!1;let n=p();try{let e=await n.decodeAudioData(t),r=n.createGain();r.gain.value=c,r.connect(n.destination);let i=n.createBufferSource();return i.buffer=e,i.connect(r),i.start(),m(n,e.duration),!0}catch{return n.close().catch(()=>{}),!1}}var y=[659.25,830.61,987.77,1108.73,987.77,830.61,739.99,659.25,739.99,830.61,987.77,1108.73,987.77,830.61];function b(){try{let e=new AudioContext;if(e.state===`suspended`&&e.resume(),e.state===`suspended`)return;let t=e.createGain();t.gain.value=.05,t.connect(e.destination);let n=.125,r=e.currentTime;for(let i=0;i<y.length;i++){let a=r+i*n,o=e.createOscillator(),s=e.createGain();o.type=`square`,o.frequency.value=y[i],s.gain.setValueAtTime(.001,a),s.gain.exponentialRampToValueAtTime(1,a+.01),s.gain.exponentialRampToValueAtTime(.001,a+n*.9),o.connect(s),s.connect(t),o.start(a),o.stop(a+n)}let i=r+y.length*n;t.gain.setValueAtTime(.05,i-.05),t.gain.exponentialRampToValueAtTime(.001,i),setTimeout(()=>e.close().catch(()=>{}),(i-r+.1)*1e3)}catch{}}function x(){try{h(e)}catch{}}function S(e){try{let t=d(e),r=n(t);if(!r){h(t);return}v(r).then(e=>{e||x()})}catch{}}export{f as loadCustomSounds,S as playAlertSound,b as playNyanJingle,g as playToneSequence,d as resolveSoundId,u as soundOptions};
1
+ import{Bi as e,Gi as t,Hi as n,Ki as r,Ui as i,Vi as a,Wi as o,zi as s}from"./index-BZuCoMuc.js";var c=.3,l=null;function u(){return r(l)}function d(e){return t(e,l)}async function f(){try{let e=await fetch(s,{credentials:`same-origin`,cache:`no-store`});e.ok&&(l=o(await e.json()))}catch{}}function p(){let e=new AudioContext;return e.state===`suspended`&&e.resume(),e}function m(e,t){setTimeout(()=>e.close().catch(()=>{}),(t+.1)*1e3)}function h(e){g(a[e]??a.chime)}function g(e){let t=p(),n=t.createGain();n.gain.value=e.peakGain,n.connect(t.destination);let r=t.currentTime,i=0;for(let a of e.tones){let e=r+a.startSeconds,o=e+a.durationSeconds,s=t.createOscillator(),c=t.createGain();s.type=a.waveform,s.frequency.setValueAtTime(a.frequency,e),a.endFrequency&&s.frequency.exponentialRampToValueAtTime(a.endFrequency,o),c.gain.setValueAtTime(.001,e),c.gain.exponentialRampToValueAtTime(a.gain??1,e+.01),c.gain.exponentialRampToValueAtTime(.001,o),s.connect(c),c.connect(n),s.start(e),s.stop(o),i=Math.max(i,a.startSeconds+a.durationSeconds)}m(t,i)}async function _(e){try{let t=await fetch(i(e),{credentials:`same-origin`});return t.ok?await t.arrayBuffer():null}catch{return null}}async function v(e){let t=await _(e);if(!t)return!1;let n=p();try{let e=await n.decodeAudioData(t),r=n.createGain();r.gain.value=c,r.connect(n.destination);let i=n.createBufferSource();return i.buffer=e,i.connect(r),i.start(),m(n,e.duration),!0}catch{return n.close().catch(()=>{}),!1}}var y=[659.25,830.61,987.77,1108.73,987.77,830.61,739.99,659.25,739.99,830.61,987.77,1108.73,987.77,830.61];function b(){try{let e=new AudioContext;if(e.state===`suspended`&&e.resume(),e.state===`suspended`)return;let t=e.createGain();t.gain.value=.05,t.connect(e.destination);let n=.125,r=e.currentTime;for(let i=0;i<y.length;i++){let a=r+i*n,o=e.createOscillator(),s=e.createGain();o.type=`square`,o.frequency.value=y[i],s.gain.setValueAtTime(.001,a),s.gain.exponentialRampToValueAtTime(1,a+.01),s.gain.exponentialRampToValueAtTime(.001,a+n*.9),o.connect(s),s.connect(t),o.start(a),o.stop(a+n)}let i=r+y.length*n;t.gain.setValueAtTime(.05,i-.05),t.gain.exponentialRampToValueAtTime(.001,i),setTimeout(()=>e.close().catch(()=>{}),(i-r+.1)*1e3)}catch{}}function x(){try{h(e)}catch{}}function S(e){try{let t=d(e),r=n(t);if(!r){h(t);return}v(r).then(e=>{e||x()})}catch{}}export{f as loadCustomSounds,S as playAlertSound,b as playNyanJingle,g as playToneSequence,d as resolveSoundId,u as soundOptions};
@@ -1 +1 @@
1
- import"./updates-view-core-Z-HI1v-s.js";import{n as e,o as t,r as n}from"./dom-helpers-C7P3_59O.js";import{J as r,Y as i,q as a}from"./index-CAztrZ9Y.js";var o={mine:`Mine`,run:`Run`,cancel:`Cancel`},s=null;function c(e){return e===null?`n/a`:`${Math.round(e*100)}%`}function l(e){if(e===null)return`n/a`;let t=Math.round(e*100);return t>0?`+${t}`:String(t)}function u(e,n,i){let a=t(`button`,`bench-action-button`,o[n]);return a.type=`button`,a.disabled=i,a.addEventListener(`click`,()=>r(e.id,n)),a}function d(e,t){let n=e.inFlight;if(!n||n.suiteId!==t.id)return``;let r=n.caseId?`case ${n.caseId}, `:``;return`Cell ${n.cellIndex+1} of ${n.cellCount}: ${r}arm ${n.armId}, trial ${n.trial}, ${n.phase}.`}function f(e){let n=t(`td`,`bench-score`,c(e?.recall??null));return e&&e.invalid>0&&(n.title=`${e.invalid} invalid or failed cell(s)`),e&&e.degraded>0&&(n.dataset.degraded=`true`),n}function p(e){let n=e.armIds.filter(t=>t!==e.baselineArm),r=t(`table`,`bench-table`),i=t(`tr`);i.append(t(`th`,null,`Case`),...e.armIds.map(n=>t(`th`,null,n===e.baselineArm?`${n} (baseline)`:n))),i.append(...n.map(e=>t(`th`,null,`${e} vs baseline`))),r.append(i);for(let i of e.rows){let a=t(`tr`);a.append(t(`td`,`bench-case`,i.caseId),...e.armIds.map(e=>f(i.arms[e]))),a.append(...n.map(e=>t(`td`,`bench-delta`,l(i.deltaVsBaseline[e]??null)))),r.append(a)}let a=[...new Set(e.armIds.flatMap(t=>Object.keys(e.totals[t]?.recallByTag??{})))].sort(),o=t(`tr`,`bench-total`);o.append(t(`td`,`bench-case`,`Paired recall`),...e.armIds.map(t=>f(e.totals[t]))),r.append(o);for(let n of a){let i=t(`tr`,`bench-total`);i.append(t(`td`,`bench-case`,`Recall, ${n}`),...e.armIds.map(r=>t(`td`,`bench-score`,c(e.totals[r]?.recallByTag[n]??null)))),r.append(i)}return r}function m(e,r){let{isServerConnected:i,pendingActionBySuite:o,outcomeBySuite:s}=a(),c=t(`div`,`bench-suite`),l=e.inFlight?.suiteId===r.id,f=!!e.inFlight&&!l,m=o.has(r.id)||!i,h=t(`div`,`bench-summary`);h.append(t(`span`,`bench-suite-title`,r.title),n(`bench`,r.caseCount===1?`case`:`cases`,String(r.caseCount)),n(`bench`,r.candidateCount===1?`candidate`:`candidates`,String(r.candidateCount)),n(`bench`,`arms`,String(r.armIds.length))),c.append(h);let g=t(`div`,`bench-controls`),_=e.configured===!0&&r.error===null;g.append(u(r,`mine`,!_||m||l),u(r,`run`,!_||m||l||f||r.caseCount===0),u(r,`cancel`,m||!l));let v=t(`span`,`bench-status`,(i?``:`Not connected to the server. Reconnecting.`)||d(e,r)||s.get(r.id)||``);if(v.setAttribute(`role`,`status`),g.append(v),c.append(g),r.error)return c.append(t(`p`,`bench-error`,r.error)),c;let y=r.latestReport;return y?(c.append(t(`p`,`bench-run-line`,`Latest run ${y.runId}: ${y.status}. Only cases every arm scored count toward paired recall.`)),y.rows.length>0&&c.append(p(y)),c):(c.append(t(`p`,`bench-empty`,r.caseCount===0?`Move approved candidates into the cases folder, then choose Run.`:`No run yet.`)),c)}function h(){if(!s)return;s.textContent=``;let{status:n}=a(),r=e(`bench`,`Benchmarks`,`Suites from the benchmarks folder of the Glimmervoid home, one run at a time.`);if(s.append(r),!n)s.append(t(`p`,`bench-empty`,`Waiting for the server.`));else if(!n.configured)s.append(t(`p`,`bench-empty`,n.reason||`Benchmarks are off.`));else if(n.suites.length===0)s.append(t(`p`,`bench-empty`,`No suites yet. Create a folder holding suite.json under benchmarks in the Glimmervoid home.`));else for(let e of n.suites)s.append(m(n,e))}function g(e){s||(s=t(`div`,`bench-content`),e.append(s),i(h),h())}var _={mount:g};export{_ as view};
1
+ import"./updates-view-core-Z-HI1v-s.js";import{n as e,o as t,r as n}from"./dom-helpers-C7P3_59O.js";import{J as r,Y as i,q as a}from"./index-BZuCoMuc.js";var o={mine:`Mine`,run:`Run`,cancel:`Cancel`},s=null;function c(e){return e===null?`n/a`:`${Math.round(e*100)}%`}function l(e){if(e===null)return`n/a`;let t=Math.round(e*100);return t>0?`+${t}`:String(t)}function u(e,n,i){let a=t(`button`,`bench-action-button`,o[n]);return a.type=`button`,a.disabled=i,a.addEventListener(`click`,()=>r(e.id,n)),a}function d(e,t){let n=e.inFlight;if(!n||n.suiteId!==t.id)return``;let r=n.caseId?`case ${n.caseId}, `:``;return`Cell ${n.cellIndex+1} of ${n.cellCount}: ${r}arm ${n.armId}, trial ${n.trial}, ${n.phase}.`}function f(e){let n=t(`td`,`bench-score`,c(e?.recall??null));return e&&e.invalid>0&&(n.title=`${e.invalid} invalid or failed cell(s)`),e&&e.degraded>0&&(n.dataset.degraded=`true`),n}function p(e){let n=e.armIds.filter(t=>t!==e.baselineArm),r=t(`table`,`bench-table`),i=t(`tr`);i.append(t(`th`,null,`Case`),...e.armIds.map(n=>t(`th`,null,n===e.baselineArm?`${n} (baseline)`:n))),i.append(...n.map(e=>t(`th`,null,`${e} vs baseline`))),r.append(i);for(let i of e.rows){let a=t(`tr`);a.append(t(`td`,`bench-case`,i.caseId),...e.armIds.map(e=>f(i.arms[e]))),a.append(...n.map(e=>t(`td`,`bench-delta`,l(i.deltaVsBaseline[e]??null)))),r.append(a)}let a=[...new Set(e.armIds.flatMap(t=>Object.keys(e.totals[t]?.recallByTag??{})))].sort(),o=t(`tr`,`bench-total`);o.append(t(`td`,`bench-case`,`Paired recall`),...e.armIds.map(t=>f(e.totals[t]))),r.append(o);for(let n of a){let i=t(`tr`,`bench-total`);i.append(t(`td`,`bench-case`,`Recall, ${n}`),...e.armIds.map(r=>t(`td`,`bench-score`,c(e.totals[r]?.recallByTag[n]??null)))),r.append(i)}return r}function m(e,r){let{isServerConnected:i,pendingActionBySuite:o,outcomeBySuite:s}=a(),c=t(`div`,`bench-suite`),l=e.inFlight?.suiteId===r.id,f=!!e.inFlight&&!l,m=o.has(r.id)||!i,h=t(`div`,`bench-summary`);h.append(t(`span`,`bench-suite-title`,r.title),n(`bench`,r.caseCount===1?`case`:`cases`,String(r.caseCount)),n(`bench`,r.candidateCount===1?`candidate`:`candidates`,String(r.candidateCount)),n(`bench`,`arms`,String(r.armIds.length))),c.append(h);let g=t(`div`,`bench-controls`),_=e.configured===!0&&r.error===null;g.append(u(r,`mine`,!_||m||l),u(r,`run`,!_||m||l||f||r.caseCount===0),u(r,`cancel`,m||!l));let v=t(`span`,`bench-status`,(i?``:`Not connected to the server. Reconnecting.`)||d(e,r)||s.get(r.id)||``);if(v.setAttribute(`role`,`status`),g.append(v),c.append(g),r.error)return c.append(t(`p`,`bench-error`,r.error)),c;let y=r.latestReport;return y?(c.append(t(`p`,`bench-run-line`,`Latest run ${y.runId}: ${y.status}. Only cases every arm scored count toward paired recall.`)),y.rows.length>0&&c.append(p(y)),c):(c.append(t(`p`,`bench-empty`,r.caseCount===0?`Move approved candidates into the cases folder, then choose Run.`:`No run yet.`)),c)}function h(){if(!s)return;s.textContent=``;let{status:n}=a(),r=e(`bench`,`Benchmarks`,`Suites from the benchmarks folder of the Glimmervoid home, one run at a time.`);if(s.append(r),!n)s.append(t(`p`,`bench-empty`,`Waiting for the server.`));else if(!n.configured)s.append(t(`p`,`bench-empty`,n.reason||`Benchmarks are off.`));else if(n.suites.length===0)s.append(t(`p`,`bench-empty`,`No suites yet. Create a folder holding suite.json under benchmarks in the Glimmervoid home.`));else for(let e of n.suites)s.append(m(n,e))}function g(e){s||(s=t(`div`,`bench-content`),e.append(s),i(h),h())}var _={mount:g};export{_ as view};
@@ -1 +1 @@
1
- import{_ as e,o as t,s as n}from"./dom-helpers-C7P3_59O.js";import{Qi as r,gi as i}from"./index-CAztrZ9Y.js";import{playToneSequence as a}from"./alert-sound-Bz56fKhi.js";var o=1.2,s=1.55,c=.12,l=523.25,u=2,d=8,f=(e,t,n)=>({semitone:e,startBeat:t,beats:n}),p={melody:[f(7,4,.5),f(11,4.5,.5),f(12,5,3)],bass:[f(-5,4,1),f(-12,5,3)]},m=[{melody:[f(0,0,1),f(4,1,1),f(7,2,1),f(9,3,1)],bass:[f(-12,0,2),f(-8,2,2)]},{melody:[f(7,0,.67),f(7,.67,.67),f(7,1.33,.67),f(9,2,1),f(5,3,1)],bass:[f(-12,0,2),f(-7,2,2)]},{melody:[f(5,0,1),f(9,1,1),f(7,2,1),f(4,3,1)],bass:[f(-7,0,2),f(-12,2,2)]},{melody:[f(12,0,.5),f(7,.5,.5),f(12,1,.5),f(16,1.5,.5),f(16,2,1),f(14,3,1)],bass:[f(-12,0,2),f(-3,2,2)]},{melody:[f(4,0,1),f(7,1,1),f(4,2,.5),f(5,2.5,.5),f(7,3,.5),f(4,3.5,.5)],bass:[f(-8,0,2),f(-12,2,2)]}].map(e=>({melody:[...e.melody,...p.melody],bass:[...e.bass,...p.bass]}));function h(e,t){return l*2**((e+t)/12)}function g(e,t){let n=(e,n,r)=>e.map(e=>({frequency:h(e.semitone,t),startSeconds:s+e.startBeat*c,durationSeconds:e.beats*c,waveform:n,gain:r}));return[...n(e.melody,`square`,.2),...n(e.melody,`triangle`,.5),...n(e.bass,`triangle`,.6)]}var ee=[{frequency:220,endFrequency:880,startSeconds:0,durationSeconds:.32,waveform:`triangle`,gain:.25},{frequency:160,endFrequency:45,startSeconds:o,durationSeconds:.28,waveform:`sine`,gain:1},{frequency:1400,endFrequency:380,startSeconds:o,durationSeconds:.06,waveform:`square`,gain:.12}];function te(e){let t=m[e%m.length],n=Math.min(e*u,d);return{peakGain:.1,tones:[...ee,...g(t,n)]}}function _(e){return Math.round(Math.sqrt(2*e/780)*1e3)}function v(e,t,n=Math.random){return Math.round(e+n()*(t-e))}function y(e,t=Math.random){let n=[...e];for(let e=n.length-1;e>0;--e){let r=Math.floor(t()*(e+1));[n[e],n[r]]=[n[r],n[e]]}return n}var ne=.6,re=.25,ie=1.6;function ae(e){return Math.min(ne+e*re,ie)}var b=[`var(--accent)`,`var(--state-running)`,`var(--state-idle)`,`var(--state-waiting)`,`var(--state-failed)`];function oe(e,t=Math.random){let n=v(320,520,t),r=v(1800,2800,t);return[[`--confetti-start-x`,`${v(4,96,t)}%`],[`--confetti-x`,`${v(-140,140,t)}px`],[`--confetti-rise`,`${-v(20,55,t)}px`],[`--confetti-fall`,`${v(45,70,t)}vh`],[`--confetti-rise-ms`,`${n}ms`],[`--confetti-fall-ms`,`${r}ms`],[`--confetti-flight-ms`,`${n+r}ms`],[`--confetti-tilt`,`${v(0,180,t)}deg`],[`--confetti-spin`,`${v(-360,360,t)}deg`],[`--confetti-flutter-ms`,`${v(160,340,t)}ms`],[`--confetti-delay`,`${v(0,160,t)}ms`],[`--confetti-color`,b[e%b.length]]]}var se=`<svg viewBox="0 0 36 36" aria-hidden="true"><circle class="merge-bullseye-ring-light" cx="18" cy="18" r="17"/><circle class="merge-bullseye-ring-red" cx="18" cy="18" r="13"/><circle class="merge-bullseye-ring-light" cx="18" cy="18" r="9"/><circle class="merge-bullseye-ring-red" cx="18" cy="18" r="5"/></svg>`,ce=`<svg viewBox="0 0 26 8" aria-hidden="true"><path class="merge-bullseye-dart-flight" d="M0 0L7 3V5L0 8L2 4Z"/><rect class="merge-bullseye-dart-shaft" x="6" y="3.3" width="8" height="1.4"/><rect class="merge-bullseye-dart-barrel" x="13" y="2.5" width="7" height="3" rx="1"/><path class="merge-bullseye-dart-tip" d="M20 3L26 4L20 5Z"/></svg>`;function le(){let e=n(`div`,`merge-bullseye-target`,se);return e.append(t(`span`,`merge-bullseye-ripple`)),e}function ue(){let e=t(`div`,`merge-bullseye-dart-drift`),r=t(`div`,`merge-bullseye-dart-arc`),i=t(`div`,`merge-bullseye-dart-aim`);return i.append(n(`div`,`merge-bullseye-dart`,ce)),r.append(i),e.append(r),e}function de(){let e=t(`div`,`merge-bullseye-range`),n=t(`div`,`merge-bullseye-track`);return n.append(ue()),e.append(le(),n),e}var fe={title:`BULLSEYE!`,buildScene:de},pe=6,x=30,S=-14,C=16;function w(e=Math.random){return[[`--crosshair-start-left`,`${v(pe,x,e)}%`],[`--crosshair-start-offset-y`,`${v(S,C,e)}px`]]}var T=`<svg viewBox="0 0 26 40" aria-hidden="true"><path class="merge-headshot-target-body" d="M9 13H17L18 16Q25 18 25 24V40H1V24Q1 18 8 16Z"/><circle class="merge-headshot-target-head" cx="13" cy="7" r="6"/><circle class="merge-headshot-target-ring" cx="13" cy="7" r="3"/><circle class="merge-headshot-target-ring" cx="13" cy="27" r="6"/><circle class="merge-headshot-target-ring" cx="13" cy="27" r="2.5"/></svg>`,E=`<svg viewBox="0 0 22 22" aria-hidden="true"><circle cx="11" cy="11" r="7"/><path d="M11 0V5M11 17V22M0 11H5M17 11H22"/><circle class="merge-headshot-crosshair-dot" cx="11" cy="11" r="1"/></svg>`,D=`<svg viewBox="0 0 24 24" aria-hidden="true"><path d="M3 3L8 8M21 3L16 8M3 21L8 16M21 21L16 16"/></svg>`;function O(){let r=t(`div`,`merge-headshot-sweep`);e(r,w());let i=t(`div`,`merge-headshot-aim`);i.append(n(`div`,`merge-headshot-crosshair`,E));let a=t(`div`,`merge-headshot-bob`);return a.append(i,n(`div`,`merge-headshot-hitmarker`,D)),r.append(a),r}function k(){let e=t(`div`,`merge-headshot-range`),r=t(`div`,`merge-headshot-track`);return r.append(O()),e.append(n(`div`,`merge-headshot-target`,T),r),e}var A={title:`HEADSHOT!`,buildScene:k},j=[`10`,`J`,`Q`,`K`,`A`],M=160,N=19,P=5,F=9,I=780,L=70,R=70,z=35;function B(e){let t=j.length-1,n=e-t/2;return{offsetPx:n*N,titleSpreadFraction:n/t,tiltDegrees:n*P,bottomPx:F-n**2,dealLeadMs:I-e*L,flipLeadMs:M+(t-e)*R,waveDelayMs:e*z}}function me(e){return[[`--card-offset`,`${e.offsetPx}px`],[`--card-title-spread`,String(e.titleSpreadFraction)],[`--card-tilt`,`${e.tiltDegrees}deg`],[`--card-bottom`,`${e.bottomPx}px`],[`--card-deal-lead-ms`,`${e.dealLeadMs}ms`],[`--card-flip-lead-ms`,`${e.flipLeadMs}ms`],[`--card-wave-delay-ms`,`${e.waveDelayMs}ms`]]}function he(){return[[`--card-flip-ms`,`${M}ms`]]}var ge=`<svg viewBox="0 0 10 9" aria-hidden="true"><path d="M5 8.5C5 8.5 0 5.3 0 2.6C0 1.1 1.2 0 2.6 0C3.6 0 4.5 .6 5 1.4C5.5 .6 6.4 0 7.4 0C8.8 0 10 1.1 10 2.6C10 5.3 5 8.5 5 8.5Z"/></svg>`;function _e(n,r){let i=t(`div`,`merge-flush-deal`);e(i,me(B(r)));let a=t(`div`,`merge-flush-hop`),o=t(`div`,`merge-flush-card`),s=t(`div`,`merge-flush-face`);return s.append(t(`span`,`merge-flush-rank`,n)),s.insertAdjacentHTML(`beforeend`,ge),o.append(t(`div`,`merge-flush-back`),s),a.append(o),i.append(a),i}function ve(){let n=t(`div`,`merge-flush-table`);return e(n,he()),n.append(...j.map(_e)),n}var ye={title:`ROYAL FLUSH!`,buildScene:ve},be=[1,2,3,4],xe=14,Se=3,Ce=3,V=10,we=20,Te=2,H=28,U=18,Ee=.01,De=1.5,Oe=2200,ke=1,W=120,G=.35,Ae=15,je=105,Me=4,Ne=65,Pe=145;function Fe(e){return Math.round(e/(Math.PI*U)*360)}function K(e){return we-e*Te}function q(e){return e.rowIndex*xe+e.depthIndex*Se}function J(e,t,n){return Array.from({length:n},(r,i)=>e+(t-e)*i/(n-1))}function Y(){return be.flatMap((e,t)=>Array.from({length:e},(n,r)=>({rowIndex:t,depthIndex:e-1-r})))}function Ie(e,t){let n=y(J(Ae,je,e),t),r=y(J(Ne,Pe,e),t);return n.map((e,n)=>({angleDegrees:e+v(-4,Me,t),depthScalePercent:Math.round(r[n])}))}function Le(e,t,n){let r=v(240,380,n),i=t.angleDegrees*Math.PI/180,a=r*Math.cos(i),o=(r*Math.sin(i))**2/1560,s=v(15,45,n),c=_(o),l=_(o+s),u=c+l,d=v(540,1080,n),f=a>=0?1:-1,p=q(e);return{depthIndex:e.depthIndex,launchAngleDegrees:t.angleDegrees,distanceFromHeadPinPx:p,layer:K(e.depthIndex),flyXPx:Math.round(a*u/1e3),peakRisePx:Math.round(o),landingDropPx:s,riseMs:c,fallMs:l,flightMs:u,spinDegrees:Math.round(f*d*u/1e3),glintMs:Math.round(180/d*1e3),depthScalePercent:t.depthScalePercent,delayMs:Math.round(p/G)}}function Re(e=Math.random){let t=Y(),n=Ie(t.length,e);return t.map((t,r)=>Le(t,n[r],e))}function ze(e){return[[`--pin-left`,`${e.distanceFromHeadPinPx}px`],[`--pin-raise`,`${e.depthIndex*Ce}px`],[`--pin-shade`,`${100-e.depthIndex*12}%`],[`--pin-fly-x`,`${e.flyXPx}px`],[`--pin-peak-y`,`${-e.peakRisePx}px`],[`--pin-land-y`,`${e.landingDropPx}px`],[`--pin-rise-ms`,`${e.riseMs}ms`],[`--pin-fall-ms`,`${e.fallMs}ms`],[`--pin-flight-ms`,`${e.flightMs}ms`],[`--pin-spin`,`${e.spinDegrees}deg`],[`--pin-glint-ms`,`${e.glintMs}ms`],[`--pin-depth-scale`,`${e.depthScalePercent}%`],[`--pin-depth-shade`,`${e.depthScalePercent-10}%`],[`--pin-delay`,`${e.delayMs}ms`],[`--pin-layer`,String(e.layer)]]}function Be(){return K(De)}function Ve(){return Math.max(...Y().map(q))+V}function He(){let e=Ve(),t=H+e+U-ke;return[[`--ball-follow-px`,`${W}px`],[`--ball-follow-ms`,`${Math.round(W/G)}ms`],[`--ball-follow-spin`,`${Fe(W)}deg`],[`--ball-size`,`${U}px`],[`--ball-approach-spin`,`${Oe}deg`],[`--ball-impact-inset`,`${t}px`],[`--ball-layer`,String(Be())],[`--rack-right`,`${H}px`],[`--rack-width`,`${e}px`],[`--pin-width`,`${V}px`]]}function Ue(e=Math.random){return e()>=Ee?null:r[Math.floor(e()*r.length)].sprite}var We=`<svg viewBox="0 0 10 24" aria-hidden="true"><path class="merge-strike-pin-body" d="M5 0C7 0 7.6 2 7.2 4C6.9 5.6 6.3 6.6 6.4 8C6.6 10 9.6 12 9.6 16C9.6 19.5 8.4 22 7.6 24H2.4C1.6 22 .4 19.5 .4 16C.4 12 3.4 10 3.6 8C3.7 6.6 3.1 5.6 2.8 4C2.4 2 3 0 5 0Z"/><path class="merge-strike-pin-stripe" d="M3.1 5.2H6.9V6.2H3.1ZM3.4 7H6.6V8H3.4Z"/></svg>`;function Ge(r){let i=t(`span`,`merge-strike-pin`);return i.append(n(`span`,`merge-strike-pin-arc`,We)),e(i,ze(r)),i}function Ke(){let e=Ue();if(!e)return t(`span`,`merge-strike-ball`);let n=t(`span`,`merge-strike-ball is-animal`);return n.append(t(`span`,`nyan-sprite ${e}`)),n}function qe(){let n=t(`div`,`merge-strike-lane`);e(n,He());let r=t(`div`,`merge-strike-rack`);r.append(...Re().map(Ge));let i=t(`div`,`merge-strike-track`);return i.append(Ke()),n.append(r,i),n}var Je={title:`STRIKE!`,buildScene:qe},Ye=20,Xe=92,Ze=23,Qe=7,$e=-40;function et(){let e=_(72),t=_(69),n=780*t/1e3;return{launchHeightPx:Ye,peakHeightPx:Xe,heightThroughRimPx:Ze,heightLeavingNetPx:Qe,heightOutOfCardPx:$e,riseMs:e,fallToRimMs:t,speedThroughRimPxPerSecond:n,netCatchMs:Math.round(32/n*1e3),dropMs:_(47)}}function tt(e=et()){return[[`--ball-launch-y`,`${-e.launchHeightPx}px`],[`--ball-peak-y`,`${-e.peakHeightPx}px`],[`--ball-rim-y`,`${-e.heightThroughRimPx}px`],[`--ball-net-exit-y`,`${-e.heightLeavingNetPx}px`],[`--ball-drop-out-y`,`${-e.heightOutOfCardPx}px`],[`--ball-rise-ms`,`${e.riseMs}ms`],[`--ball-fall-to-rim-ms`,`${e.fallToRimMs}ms`],[`--ball-to-rim-ms`,`${e.riseMs+e.fallToRimMs}ms`],[`--ball-net-catch-ms`,`${e.netCatchMs}ms`],[`--ball-drop-ms`,`${e.dropMs}ms`]]}var nt=`<svg viewBox="0 0 40 48" aria-hidden="true"><rect class="merge-swish-pole" x="36" y="28" width="2" height="20"/><rect class="merge-swish-backboard" x="35" y="2" width="3" height="26" rx="1"/><path class="merge-swish-rim" d="M31 18H35M7 18A12 2.5 0 0 1 31 18"/></svg>`,rt=`<svg viewBox="0 0 40 48" aria-hidden="true"><g class="merge-swish-net"><path d="M8 18L12 32M13.5 18L15.5 32M19 18V32M24.5 18L22.5 32M30 18L26 32M9.5 23Q19 25 28.5 23M11 28Q19 29.5 27 28"/></g><path class="merge-swish-rim" d="M7 18A12 2.5 0 0 0 31 18"/></svg>`;function it(){let e=t(`div`,`merge-swish-ball-drift`),n=t(`div`,`merge-swish-ball-arc`);return n.append(t(`span`,`merge-swish-ball`)),e.append(n),e}function X(){let r=t(`div`,`merge-swish-court`);e(r,tt());let i=t(`div`,`merge-swish-track`);return i.append(it()),r.append(n(`div`,`merge-swish-hoop-back`,nt),i,n(`div`,`merge-swish-hoop-front`,rt)),r}var Z=[Je,{title:`SWISH!`,buildScene:X},fe,A,ye],at=48,Q=5600,$=null;function ot(n){let r=t(`span`,`merge-confetti-piece`),i=t(`span`,`merge-confetti-arc`);return i.append(t(`span`,`merge-confetti-paper`)),r.append(i),e(r,oe(n)),r}function st(e){let n=t(`p`,`merge-celebration-title`);return n.setAttribute(`aria-hidden`,`true`),Array.from(e).forEach((e,r)=>{let i=t(`span`,`merge-celebration-letter`,e);i.style.setProperty(`--letter-delay`,`${r*45}ms`),n.append(i)}),n}function ct(e,t,n){let r=t.firstElementChild,i=t.lastElementChild;r instanceof HTMLElement&&i instanceof HTMLElement&&(e.style.setProperty(`--celebration-title-width`,`${i.offsetLeft+i.offsetWidth-r.offsetLeft}px`),e.style.setProperty(`--celebration-title-center-y`,`${t.offsetTop+t.offsetHeight/2-n.offsetTop}px`))}function lt(e){let n=t(`div`,`merge-celebration-scene`);return n.setAttribute(`aria-hidden`,`true`),n.append(e.buildScene()),n}function ut(){return Z[Math.floor(Math.random()*Z.length)]}function dt(e){if(i())try{a(te(e))}catch{}}function ft(e){let n=t(`ul`,`merge-celebration-details`);for(let r of e)n.append(t(`li`,`merge-celebration-detail`,r));return n}function pt(e,n){let r=ut();$?.remove(),dt(n);let i=t(`div`,`merge-celebration`);i.setAttribute(`role`,`status`);let a=t(`div`,`merge-celebration-card`),o=t(`div`,`merge-celebration-stage`),s=st(r.title),c=lt(r);o.append(s,t(`p`,`merge-celebration-message`,e.message),ft(e.detailLines),c);let l=t(`div`,`merge-confetti`);l.style.setProperty(`--confetti-scale`,String(ae(n)));for(let e=0;e<at;e+=1)l.append(ot(e));a.append(l,o),i.append(a),document.body.append(i),ct(o,s,c),$=i,window.setTimeout(()=>{i.remove(),$===i&&($=null)},Q)}export{Q as CELEBRATION_DURATION_MS,pt as playCelebration};
1
+ import{_ as e,o as t,s as n}from"./dom-helpers-C7P3_59O.js";import{Qi as r,gi as i}from"./index-BZuCoMuc.js";import{playToneSequence as a}from"./alert-sound-gcFWc22f.js";var o=1.2,s=1.55,c=.12,l=523.25,u=2,d=8,f=(e,t,n)=>({semitone:e,startBeat:t,beats:n}),p={melody:[f(7,4,.5),f(11,4.5,.5),f(12,5,3)],bass:[f(-5,4,1),f(-12,5,3)]},m=[{melody:[f(0,0,1),f(4,1,1),f(7,2,1),f(9,3,1)],bass:[f(-12,0,2),f(-8,2,2)]},{melody:[f(7,0,.67),f(7,.67,.67),f(7,1.33,.67),f(9,2,1),f(5,3,1)],bass:[f(-12,0,2),f(-7,2,2)]},{melody:[f(5,0,1),f(9,1,1),f(7,2,1),f(4,3,1)],bass:[f(-7,0,2),f(-12,2,2)]},{melody:[f(12,0,.5),f(7,.5,.5),f(12,1,.5),f(16,1.5,.5),f(16,2,1),f(14,3,1)],bass:[f(-12,0,2),f(-3,2,2)]},{melody:[f(4,0,1),f(7,1,1),f(4,2,.5),f(5,2.5,.5),f(7,3,.5),f(4,3.5,.5)],bass:[f(-8,0,2),f(-12,2,2)]}].map(e=>({melody:[...e.melody,...p.melody],bass:[...e.bass,...p.bass]}));function h(e,t){return l*2**((e+t)/12)}function g(e,t){let n=(e,n,r)=>e.map(e=>({frequency:h(e.semitone,t),startSeconds:s+e.startBeat*c,durationSeconds:e.beats*c,waveform:n,gain:r}));return[...n(e.melody,`square`,.2),...n(e.melody,`triangle`,.5),...n(e.bass,`triangle`,.6)]}var ee=[{frequency:220,endFrequency:880,startSeconds:0,durationSeconds:.32,waveform:`triangle`,gain:.25},{frequency:160,endFrequency:45,startSeconds:o,durationSeconds:.28,waveform:`sine`,gain:1},{frequency:1400,endFrequency:380,startSeconds:o,durationSeconds:.06,waveform:`square`,gain:.12}];function te(e){let t=m[e%m.length],n=Math.min(e*u,d);return{peakGain:.1,tones:[...ee,...g(t,n)]}}function _(e){return Math.round(Math.sqrt(2*e/780)*1e3)}function v(e,t,n=Math.random){return Math.round(e+n()*(t-e))}function y(e,t=Math.random){let n=[...e];for(let e=n.length-1;e>0;--e){let r=Math.floor(t()*(e+1));[n[e],n[r]]=[n[r],n[e]]}return n}var ne=.6,re=.25,ie=1.6;function ae(e){return Math.min(ne+e*re,ie)}var b=[`var(--accent)`,`var(--state-running)`,`var(--state-idle)`,`var(--state-waiting)`,`var(--state-failed)`];function oe(e,t=Math.random){let n=v(320,520,t),r=v(1800,2800,t);return[[`--confetti-start-x`,`${v(4,96,t)}%`],[`--confetti-x`,`${v(-140,140,t)}px`],[`--confetti-rise`,`${-v(20,55,t)}px`],[`--confetti-fall`,`${v(45,70,t)}vh`],[`--confetti-rise-ms`,`${n}ms`],[`--confetti-fall-ms`,`${r}ms`],[`--confetti-flight-ms`,`${n+r}ms`],[`--confetti-tilt`,`${v(0,180,t)}deg`],[`--confetti-spin`,`${v(-360,360,t)}deg`],[`--confetti-flutter-ms`,`${v(160,340,t)}ms`],[`--confetti-delay`,`${v(0,160,t)}ms`],[`--confetti-color`,b[e%b.length]]]}var se=`<svg viewBox="0 0 36 36" aria-hidden="true"><circle class="merge-bullseye-ring-light" cx="18" cy="18" r="17"/><circle class="merge-bullseye-ring-red" cx="18" cy="18" r="13"/><circle class="merge-bullseye-ring-light" cx="18" cy="18" r="9"/><circle class="merge-bullseye-ring-red" cx="18" cy="18" r="5"/></svg>`,ce=`<svg viewBox="0 0 26 8" aria-hidden="true"><path class="merge-bullseye-dart-flight" d="M0 0L7 3V5L0 8L2 4Z"/><rect class="merge-bullseye-dart-shaft" x="6" y="3.3" width="8" height="1.4"/><rect class="merge-bullseye-dart-barrel" x="13" y="2.5" width="7" height="3" rx="1"/><path class="merge-bullseye-dart-tip" d="M20 3L26 4L20 5Z"/></svg>`;function le(){let e=n(`div`,`merge-bullseye-target`,se);return e.append(t(`span`,`merge-bullseye-ripple`)),e}function ue(){let e=t(`div`,`merge-bullseye-dart-drift`),r=t(`div`,`merge-bullseye-dart-arc`),i=t(`div`,`merge-bullseye-dart-aim`);return i.append(n(`div`,`merge-bullseye-dart`,ce)),r.append(i),e.append(r),e}function de(){let e=t(`div`,`merge-bullseye-range`),n=t(`div`,`merge-bullseye-track`);return n.append(ue()),e.append(le(),n),e}var fe={title:`BULLSEYE!`,buildScene:de},pe=6,x=30,S=-14,C=16;function w(e=Math.random){return[[`--crosshair-start-left`,`${v(pe,x,e)}%`],[`--crosshair-start-offset-y`,`${v(S,C,e)}px`]]}var T=`<svg viewBox="0 0 26 40" aria-hidden="true"><path class="merge-headshot-target-body" d="M9 13H17L18 16Q25 18 25 24V40H1V24Q1 18 8 16Z"/><circle class="merge-headshot-target-head" cx="13" cy="7" r="6"/><circle class="merge-headshot-target-ring" cx="13" cy="7" r="3"/><circle class="merge-headshot-target-ring" cx="13" cy="27" r="6"/><circle class="merge-headshot-target-ring" cx="13" cy="27" r="2.5"/></svg>`,E=`<svg viewBox="0 0 22 22" aria-hidden="true"><circle cx="11" cy="11" r="7"/><path d="M11 0V5M11 17V22M0 11H5M17 11H22"/><circle class="merge-headshot-crosshair-dot" cx="11" cy="11" r="1"/></svg>`,D=`<svg viewBox="0 0 24 24" aria-hidden="true"><path d="M3 3L8 8M21 3L16 8M3 21L8 16M21 21L16 16"/></svg>`;function O(){let r=t(`div`,`merge-headshot-sweep`);e(r,w());let i=t(`div`,`merge-headshot-aim`);i.append(n(`div`,`merge-headshot-crosshair`,E));let a=t(`div`,`merge-headshot-bob`);return a.append(i,n(`div`,`merge-headshot-hitmarker`,D)),r.append(a),r}function k(){let e=t(`div`,`merge-headshot-range`),r=t(`div`,`merge-headshot-track`);return r.append(O()),e.append(n(`div`,`merge-headshot-target`,T),r),e}var A={title:`HEADSHOT!`,buildScene:k},j=[`10`,`J`,`Q`,`K`,`A`],M=160,N=19,P=5,F=9,I=780,L=70,R=70,z=35;function B(e){let t=j.length-1,n=e-t/2;return{offsetPx:n*N,titleSpreadFraction:n/t,tiltDegrees:n*P,bottomPx:F-n**2,dealLeadMs:I-e*L,flipLeadMs:M+(t-e)*R,waveDelayMs:e*z}}function me(e){return[[`--card-offset`,`${e.offsetPx}px`],[`--card-title-spread`,String(e.titleSpreadFraction)],[`--card-tilt`,`${e.tiltDegrees}deg`],[`--card-bottom`,`${e.bottomPx}px`],[`--card-deal-lead-ms`,`${e.dealLeadMs}ms`],[`--card-flip-lead-ms`,`${e.flipLeadMs}ms`],[`--card-wave-delay-ms`,`${e.waveDelayMs}ms`]]}function he(){return[[`--card-flip-ms`,`${M}ms`]]}var ge=`<svg viewBox="0 0 10 9" aria-hidden="true"><path d="M5 8.5C5 8.5 0 5.3 0 2.6C0 1.1 1.2 0 2.6 0C3.6 0 4.5 .6 5 1.4C5.5 .6 6.4 0 7.4 0C8.8 0 10 1.1 10 2.6C10 5.3 5 8.5 5 8.5Z"/></svg>`;function _e(n,r){let i=t(`div`,`merge-flush-deal`);e(i,me(B(r)));let a=t(`div`,`merge-flush-hop`),o=t(`div`,`merge-flush-card`),s=t(`div`,`merge-flush-face`);return s.append(t(`span`,`merge-flush-rank`,n)),s.insertAdjacentHTML(`beforeend`,ge),o.append(t(`div`,`merge-flush-back`),s),a.append(o),i.append(a),i}function ve(){let n=t(`div`,`merge-flush-table`);return e(n,he()),n.append(...j.map(_e)),n}var ye={title:`ROYAL FLUSH!`,buildScene:ve},be=[1,2,3,4],xe=14,Se=3,Ce=3,V=10,we=20,Te=2,H=28,U=18,Ee=.01,De=1.5,Oe=2200,ke=1,W=120,G=.35,Ae=15,je=105,Me=4,Ne=65,Pe=145;function Fe(e){return Math.round(e/(Math.PI*U)*360)}function K(e){return we-e*Te}function q(e){return e.rowIndex*xe+e.depthIndex*Se}function J(e,t,n){return Array.from({length:n},(r,i)=>e+(t-e)*i/(n-1))}function Y(){return be.flatMap((e,t)=>Array.from({length:e},(n,r)=>({rowIndex:t,depthIndex:e-1-r})))}function Ie(e,t){let n=y(J(Ae,je,e),t),r=y(J(Ne,Pe,e),t);return n.map((e,n)=>({angleDegrees:e+v(-4,Me,t),depthScalePercent:Math.round(r[n])}))}function Le(e,t,n){let r=v(240,380,n),i=t.angleDegrees*Math.PI/180,a=r*Math.cos(i),o=(r*Math.sin(i))**2/1560,s=v(15,45,n),c=_(o),l=_(o+s),u=c+l,d=v(540,1080,n),f=a>=0?1:-1,p=q(e);return{depthIndex:e.depthIndex,launchAngleDegrees:t.angleDegrees,distanceFromHeadPinPx:p,layer:K(e.depthIndex),flyXPx:Math.round(a*u/1e3),peakRisePx:Math.round(o),landingDropPx:s,riseMs:c,fallMs:l,flightMs:u,spinDegrees:Math.round(f*d*u/1e3),glintMs:Math.round(180/d*1e3),depthScalePercent:t.depthScalePercent,delayMs:Math.round(p/G)}}function Re(e=Math.random){let t=Y(),n=Ie(t.length,e);return t.map((t,r)=>Le(t,n[r],e))}function ze(e){return[[`--pin-left`,`${e.distanceFromHeadPinPx}px`],[`--pin-raise`,`${e.depthIndex*Ce}px`],[`--pin-shade`,`${100-e.depthIndex*12}%`],[`--pin-fly-x`,`${e.flyXPx}px`],[`--pin-peak-y`,`${-e.peakRisePx}px`],[`--pin-land-y`,`${e.landingDropPx}px`],[`--pin-rise-ms`,`${e.riseMs}ms`],[`--pin-fall-ms`,`${e.fallMs}ms`],[`--pin-flight-ms`,`${e.flightMs}ms`],[`--pin-spin`,`${e.spinDegrees}deg`],[`--pin-glint-ms`,`${e.glintMs}ms`],[`--pin-depth-scale`,`${e.depthScalePercent}%`],[`--pin-depth-shade`,`${e.depthScalePercent-10}%`],[`--pin-delay`,`${e.delayMs}ms`],[`--pin-layer`,String(e.layer)]]}function Be(){return K(De)}function Ve(){return Math.max(...Y().map(q))+V}function He(){let e=Ve(),t=H+e+U-ke;return[[`--ball-follow-px`,`${W}px`],[`--ball-follow-ms`,`${Math.round(W/G)}ms`],[`--ball-follow-spin`,`${Fe(W)}deg`],[`--ball-size`,`${U}px`],[`--ball-approach-spin`,`${Oe}deg`],[`--ball-impact-inset`,`${t}px`],[`--ball-layer`,String(Be())],[`--rack-right`,`${H}px`],[`--rack-width`,`${e}px`],[`--pin-width`,`${V}px`]]}function Ue(e=Math.random){return e()>=Ee?null:r[Math.floor(e()*r.length)].sprite}var We=`<svg viewBox="0 0 10 24" aria-hidden="true"><path class="merge-strike-pin-body" d="M5 0C7 0 7.6 2 7.2 4C6.9 5.6 6.3 6.6 6.4 8C6.6 10 9.6 12 9.6 16C9.6 19.5 8.4 22 7.6 24H2.4C1.6 22 .4 19.5 .4 16C.4 12 3.4 10 3.6 8C3.7 6.6 3.1 5.6 2.8 4C2.4 2 3 0 5 0Z"/><path class="merge-strike-pin-stripe" d="M3.1 5.2H6.9V6.2H3.1ZM3.4 7H6.6V8H3.4Z"/></svg>`;function Ge(r){let i=t(`span`,`merge-strike-pin`);return i.append(n(`span`,`merge-strike-pin-arc`,We)),e(i,ze(r)),i}function Ke(){let e=Ue();if(!e)return t(`span`,`merge-strike-ball`);let n=t(`span`,`merge-strike-ball is-animal`);return n.append(t(`span`,`nyan-sprite ${e}`)),n}function qe(){let n=t(`div`,`merge-strike-lane`);e(n,He());let r=t(`div`,`merge-strike-rack`);r.append(...Re().map(Ge));let i=t(`div`,`merge-strike-track`);return i.append(Ke()),n.append(r,i),n}var Je={title:`STRIKE!`,buildScene:qe},Ye=20,Xe=92,Ze=23,Qe=7,$e=-40;function et(){let e=_(72),t=_(69),n=780*t/1e3;return{launchHeightPx:Ye,peakHeightPx:Xe,heightThroughRimPx:Ze,heightLeavingNetPx:Qe,heightOutOfCardPx:$e,riseMs:e,fallToRimMs:t,speedThroughRimPxPerSecond:n,netCatchMs:Math.round(32/n*1e3),dropMs:_(47)}}function tt(e=et()){return[[`--ball-launch-y`,`${-e.launchHeightPx}px`],[`--ball-peak-y`,`${-e.peakHeightPx}px`],[`--ball-rim-y`,`${-e.heightThroughRimPx}px`],[`--ball-net-exit-y`,`${-e.heightLeavingNetPx}px`],[`--ball-drop-out-y`,`${-e.heightOutOfCardPx}px`],[`--ball-rise-ms`,`${e.riseMs}ms`],[`--ball-fall-to-rim-ms`,`${e.fallToRimMs}ms`],[`--ball-to-rim-ms`,`${e.riseMs+e.fallToRimMs}ms`],[`--ball-net-catch-ms`,`${e.netCatchMs}ms`],[`--ball-drop-ms`,`${e.dropMs}ms`]]}var nt=`<svg viewBox="0 0 40 48" aria-hidden="true"><rect class="merge-swish-pole" x="36" y="28" width="2" height="20"/><rect class="merge-swish-backboard" x="35" y="2" width="3" height="26" rx="1"/><path class="merge-swish-rim" d="M31 18H35M7 18A12 2.5 0 0 1 31 18"/></svg>`,rt=`<svg viewBox="0 0 40 48" aria-hidden="true"><g class="merge-swish-net"><path d="M8 18L12 32M13.5 18L15.5 32M19 18V32M24.5 18L22.5 32M30 18L26 32M9.5 23Q19 25 28.5 23M11 28Q19 29.5 27 28"/></g><path class="merge-swish-rim" d="M7 18A12 2.5 0 0 0 31 18"/></svg>`;function it(){let e=t(`div`,`merge-swish-ball-drift`),n=t(`div`,`merge-swish-ball-arc`);return n.append(t(`span`,`merge-swish-ball`)),e.append(n),e}function X(){let r=t(`div`,`merge-swish-court`);e(r,tt());let i=t(`div`,`merge-swish-track`);return i.append(it()),r.append(n(`div`,`merge-swish-hoop-back`,nt),i,n(`div`,`merge-swish-hoop-front`,rt)),r}var Z=[Je,{title:`SWISH!`,buildScene:X},fe,A,ye],at=48,Q=5600,$=null;function ot(n){let r=t(`span`,`merge-confetti-piece`),i=t(`span`,`merge-confetti-arc`);return i.append(t(`span`,`merge-confetti-paper`)),r.append(i),e(r,oe(n)),r}function st(e){let n=t(`p`,`merge-celebration-title`);return n.setAttribute(`aria-hidden`,`true`),Array.from(e).forEach((e,r)=>{let i=t(`span`,`merge-celebration-letter`,e);i.style.setProperty(`--letter-delay`,`${r*45}ms`),n.append(i)}),n}function ct(e,t,n){let r=t.firstElementChild,i=t.lastElementChild;r instanceof HTMLElement&&i instanceof HTMLElement&&(e.style.setProperty(`--celebration-title-width`,`${i.offsetLeft+i.offsetWidth-r.offsetLeft}px`),e.style.setProperty(`--celebration-title-center-y`,`${t.offsetTop+t.offsetHeight/2-n.offsetTop}px`))}function lt(e){let n=t(`div`,`merge-celebration-scene`);return n.setAttribute(`aria-hidden`,`true`),n.append(e.buildScene()),n}function ut(){return Z[Math.floor(Math.random()*Z.length)]}function dt(e){if(i())try{a(te(e))}catch{}}function ft(e){let n=t(`ul`,`merge-celebration-details`);for(let r of e)n.append(t(`li`,`merge-celebration-detail`,r));return n}function pt(e,n){let r=ut();$?.remove(),dt(n);let i=t(`div`,`merge-celebration`);i.setAttribute(`role`,`status`);let a=t(`div`,`merge-celebration-card`),o=t(`div`,`merge-celebration-stage`),s=st(r.title),c=lt(r);o.append(s,t(`p`,`merge-celebration-message`,e.message),ft(e.detailLines),c);let l=t(`div`,`merge-confetti`);l.style.setProperty(`--confetti-scale`,String(ae(n)));for(let e=0;e<at;e+=1)l.append(ot(e));a.append(l,o),i.append(a),document.body.append(i),ct(o,s,c),$=i,window.setTimeout(()=>{i.remove(),$===i&&($=null)},Q)}export{Q as CELEBRATION_DURATION_MS,pt as playCelebration};
@@ -1,4 +1,4 @@
1
- import{G as e,U as t,W as n,dt as r,ft as i,x as a}from"./updates-view-core-Z-HI1v-s.js";import{h as o,m as s,o as c}from"./dom-helpers-C7P3_59O.js";import{u as l}from"./control-ws-CklsyQBG.js";import{n as u,r as d,t as f}from"./modal-Bh-cVr-I.js";import{n as p}from"./session-tick-BVBhKkDl.js";import{Cn as m,Fr as h,Ir as g,Rr as _,_r as v,cr as y,ei as b,gr as x,m as S,ni as C,ti as w}from"./index-CAztrZ9Y.js";import{d as T,l as E,t as D,u as ee}from"./repo-roots-adder-CfQRgYuh.js";var te=`<h2 class="dialog-title" id="add-session-title">Add Session</h2>
1
+ import{G as e,U as t,W as n,dt as r,ft as i,x as a}from"./updates-view-core-Z-HI1v-s.js";import{h as o,m as s,o as c}from"./dom-helpers-C7P3_59O.js";import{u as l}from"./control-ws-CklsyQBG.js";import{n as u,r as d,t as f}from"./modal-Bh-cVr-I.js";import{n as p}from"./session-tick-BVBhKkDl.js";import{Cn as m,Fr as h,Ir as g,Rr as _,_r as v,cr as y,ei as b,gr as x,m as S,ni as C,ti as w}from"./index-BZuCoMuc.js";import{d as T,l as E,t as D,u as ee}from"./repo-roots-adder-CfQRgYuh.js";var te=`<h2 class="dialog-title" id="add-session-title">Add Session</h2>
2
2
  <fieldset class="dialog-mode-controls" aria-label="Session kind">
3
3
  <button type="button" class="dialog-mode-button" id="add-session-single-mode" aria-pressed="true">Single repo</button>
4
4
  <button type="button" class="dialog-mode-button" id="add-session-workspace-mode" aria-pressed="false">Workspace</button>
@@ -1 +1 @@
1
- import{o as e}from"./dom-helpers-C7P3_59O.js";import{u as t}from"./control-ws-CklsyQBG.js";import{a as n,r,t as i}from"./modal-Bh-cVr-I.js";import{Fr as a,Qr as o,Rr as s,pn as c}from"./index-CAztrZ9Y.js";import{i as l,t as u}from"./plan-render-BtAm6TFY.js";var d=null;function f(t){let n=o(t.sessionId);t.select.replaceChildren(...n.map(n=>{let r=e(`option`,null,n.name);return r.value=n.path,r.selected=n.path===t.docPath,r})),t.select.hidden=n.length<2,t.title.textContent=n.find(e=>e.path===t.docPath)?.name??t.title.textContent}function p(e){let t=o(e.sessionId).some(t=>t.path===e.docPath);e.btnEdit.setAttribute(`aria-pressed`,String(e.mode===`edit`)),e.btnPreview.setAttribute(`aria-pressed`,String(e.mode===`preview`)),e.textarea.hidden=e.mode!==`edit`,e.preview.hidden=e.mode!==`preview`,e.select.disabled=e.isBusy,e.btnReload.disabled=e.isBusy||!t,e.btnSave.disabled=e.isBusy||!t||e.baseHash===null||!e.hasUnsavedChanges}function m(e,t,n=`quiet`){e.status.textContent=t,e.status.dataset.tone=n}function h(e){e.preview.replaceChildren(u(l(e.textarea.value)))}function g(e,t){n({title:e,message:`Your unsaved edits will be lost.`,confirmLabel:`Discard`,danger:!0,onConfirm:t})}function _(e,t,n){e.hasUnsavedChanges?g(t,n):n()}async function v(e,n){try{return{reply:await t(e,n,{timeoutMs:a}),failureText:null}}catch(e){return{reply:null,failureText:s(e,a)}}}async function y(e,t){e.docPath=t,e.isBusy=!0,e.baseHash=null,e.textarea.readOnly=!0,f(e),m(e,`Loading`),p(e);let{reply:n,failureText:r}=await v(`session-doc-read`,{id:e.sessionId,path:t});if(d!==e||e.docPath!==t)return;e.isBusy=!1,e.textarea.readOnly=!1;let i=n?.type===`session-doc-response`?n:null;!i?.ok||i.text===void 0||i.hash===void 0?(m(e,i?.error||r||`Could not open this doc`,`warn`),p(e)):(e.textarea.value=i.text,e.baseHash=i.hash,e.hasUnsavedChanges=!1,e.mode===`preview`&&h(e),m(e,``),p(e))}async function b(e){if(e.btnSave.disabled||e.baseHash===null)return;e.isBusy=!0,m(e,`Saving`),p(e);let t=e.docPath,n=e.textarea.value,{reply:r,failureText:i}=await v(`session-doc-save`,{id:e.sessionId,path:t,text:n,baseHash:e.baseHash});if(d!==e||e.docPath!==t)return;e.isBusy=!1;let a=r?.type===`session-doc-save-result`?r:null;!a?.ok||a.hash===void 0?(m(e,a?.conflict?`The agent changed this file since you opened it. Reload to see its version.`:a?.error||i||`Save failed`,`warn`),p(e)):(e.baseHash=a.hash,e.hasUnsavedChanges=e.textarea.value!==n,m(e,e.hasUnsavedChanges?`Unsaved changes`:`Saved`),p(e))}function x(e,t){e.mode=t,t===`preview`&&h(e),p(e),t===`edit`&&e.textarea.focus()}function S(t,n){let r=e(`button`,`plan-control ${n}`,t);return r.type=`button`,r}function C(t){let n=o(t)[0];if(!n||d)return;let a=()=>_(M,`Close this doc?`,()=>M.close()),s=r({dialogClass:`doc-editor`,closeOnBackdrop:!1,onEscape:a}),l=`doc-editor-title-${t}`,u=e(`h3`,`doc-editor-title`,n.name);u.id=l;let f=e(`select`,`plan-control doc-editor-picker`);f.setAttribute(`aria-label`,`Doc`);let h=e(`span`,`doc-editor-status`);h.setAttribute(`role`,`status`);let g=S(`Edit`,`doc-editor-mode`),v=S(`Preview`,`doc-editor-mode`),C=S(`Reload`,`doc-editor-reload`),w=S(`Save`,`doc-editor-save`),T=S(`Close`,`doc-editor-close`),E=e(`div`,`doc-editor-modes`);E.append(g,v);let D=e(`div`,`doc-editor-actions`);D.append(h,C,w,T);let O=e(`div`,`doc-editor-header`);O.append(u,f,E,D);let k=e(`textarea`,`plan-editor doc-editor-text`);k.spellcheck=!0,k.setAttribute(`aria-labelledby`,l);let A=e(`div`,`doc-editor-preview`),j=e(`div`,`doc-editor-body`);j.append(k,A),s.dialog.append(O,j),i(s.dialog,l);let M={sessionId:t,docPath:n.path,baseHash:null,hasUnsavedChanges:!1,isBusy:!1,mode:c()?`preview`:`edit`,title:u,select:f,textarea:k,preview:A,status:h,btnEdit:g,btnPreview:v,btnReload:C,btnSave:w,close:()=>{d=null,s.close()}};d=M,k.addEventListener(`input`,()=>{M.hasUnsavedChanges||(M.hasUnsavedChanges=!0,m(M,`Unsaved changes`),p(M))}),k.addEventListener(`keydown`,e=>{(e.ctrlKey||e.metaKey)&&e.key.toLowerCase()===`s`&&(e.preventDefault(),b(M))}),f.addEventListener(`change`,()=>{let e=f.value;f.value=M.docPath,_(M,`Open another doc?`,()=>{y(M,e)})}),g.addEventListener(`click`,()=>x(M,`edit`)),v.addEventListener(`click`,()=>x(M,`preview`)),C.addEventListener(`click`,()=>{_(M,`Reload this doc?`,()=>{y(M,M.docPath)})}),w.addEventListener(`click`,()=>{b(M)}),T.addEventListener(`click`,a),y(M,n.path),M.mode===`edit`&&k.focus()}function w(e){d&&d.sessionId===e&&(f(d),p(d),!o(e).some(e=>e.path===d?.docPath)&&m(d,`This doc is no longer surfaced, so it cannot be saved.`,`warn`))}export{w as applyDocsToOpenEditor,C as openDocEditor};
1
+ import{o as e}from"./dom-helpers-C7P3_59O.js";import{u as t}from"./control-ws-CklsyQBG.js";import{a as n,r,t as i}from"./modal-Bh-cVr-I.js";import{Fr as a,Qr as o,Rr as s,pn as c}from"./index-BZuCoMuc.js";import{i as l,t as u}from"./plan-render-BILDNp_T.js";var d=null;function f(t){let n=o(t.sessionId);t.select.replaceChildren(...n.map(n=>{let r=e(`option`,null,n.name);return r.value=n.path,r.selected=n.path===t.docPath,r})),t.select.hidden=n.length<2,t.title.textContent=n.find(e=>e.path===t.docPath)?.name??t.title.textContent}function p(e){let t=o(e.sessionId).some(t=>t.path===e.docPath);e.btnEdit.setAttribute(`aria-pressed`,String(e.mode===`edit`)),e.btnPreview.setAttribute(`aria-pressed`,String(e.mode===`preview`)),e.textarea.hidden=e.mode!==`edit`,e.preview.hidden=e.mode!==`preview`,e.select.disabled=e.isBusy,e.btnReload.disabled=e.isBusy||!t,e.btnSave.disabled=e.isBusy||!t||e.baseHash===null||!e.hasUnsavedChanges}function m(e,t,n=`quiet`){e.status.textContent=t,e.status.dataset.tone=n}function h(e){e.preview.replaceChildren(u(l(e.textarea.value)))}function g(e,t){n({title:e,message:`Your unsaved edits will be lost.`,confirmLabel:`Discard`,danger:!0,onConfirm:t})}function _(e,t,n){e.hasUnsavedChanges?g(t,n):n()}async function v(e,n){try{return{reply:await t(e,n,{timeoutMs:a}),failureText:null}}catch(e){return{reply:null,failureText:s(e,a)}}}async function y(e,t){e.docPath=t,e.isBusy=!0,e.baseHash=null,e.textarea.readOnly=!0,f(e),m(e,`Loading`),p(e);let{reply:n,failureText:r}=await v(`session-doc-read`,{id:e.sessionId,path:t});if(d!==e||e.docPath!==t)return;e.isBusy=!1,e.textarea.readOnly=!1;let i=n?.type===`session-doc-response`?n:null;!i?.ok||i.text===void 0||i.hash===void 0?(m(e,i?.error||r||`Could not open this doc`,`warn`),p(e)):(e.textarea.value=i.text,e.baseHash=i.hash,e.hasUnsavedChanges=!1,e.mode===`preview`&&h(e),m(e,``),p(e))}async function b(e){if(e.btnSave.disabled||e.baseHash===null)return;e.isBusy=!0,m(e,`Saving`),p(e);let t=e.docPath,n=e.textarea.value,{reply:r,failureText:i}=await v(`session-doc-save`,{id:e.sessionId,path:t,text:n,baseHash:e.baseHash});if(d!==e||e.docPath!==t)return;e.isBusy=!1;let a=r?.type===`session-doc-save-result`?r:null;!a?.ok||a.hash===void 0?(m(e,a?.conflict?`The agent changed this file since you opened it. Reload to see its version.`:a?.error||i||`Save failed`,`warn`),p(e)):(e.baseHash=a.hash,e.hasUnsavedChanges=e.textarea.value!==n,m(e,e.hasUnsavedChanges?`Unsaved changes`:`Saved`),p(e))}function x(e,t){e.mode=t,t===`preview`&&h(e),p(e),t===`edit`&&e.textarea.focus()}function S(t,n){let r=e(`button`,`plan-control ${n}`,t);return r.type=`button`,r}function C(t){let n=o(t)[0];if(!n||d)return;let a=()=>_(M,`Close this doc?`,()=>M.close()),s=r({dialogClass:`doc-editor`,closeOnBackdrop:!1,onEscape:a}),l=`doc-editor-title-${t}`,u=e(`h3`,`doc-editor-title`,n.name);u.id=l;let f=e(`select`,`plan-control doc-editor-picker`);f.setAttribute(`aria-label`,`Doc`);let h=e(`span`,`doc-editor-status`);h.setAttribute(`role`,`status`);let g=S(`Edit`,`doc-editor-mode`),v=S(`Preview`,`doc-editor-mode`),C=S(`Reload`,`doc-editor-reload`),w=S(`Save`,`doc-editor-save`),T=S(`Close`,`doc-editor-close`),E=e(`div`,`doc-editor-modes`);E.append(g,v);let D=e(`div`,`doc-editor-actions`);D.append(h,C,w,T);let O=e(`div`,`doc-editor-header`);O.append(u,f,E,D);let k=e(`textarea`,`plan-editor doc-editor-text`);k.spellcheck=!0,k.setAttribute(`aria-labelledby`,l);let A=e(`div`,`doc-editor-preview`),j=e(`div`,`doc-editor-body`);j.append(k,A),s.dialog.append(O,j),i(s.dialog,l);let M={sessionId:t,docPath:n.path,baseHash:null,hasUnsavedChanges:!1,isBusy:!1,mode:c()?`preview`:`edit`,title:u,select:f,textarea:k,preview:A,status:h,btnEdit:g,btnPreview:v,btnReload:C,btnSave:w,close:()=>{d=null,s.close()}};d=M,k.addEventListener(`input`,()=>{M.hasUnsavedChanges||(M.hasUnsavedChanges=!0,m(M,`Unsaved changes`),p(M))}),k.addEventListener(`keydown`,e=>{(e.ctrlKey||e.metaKey)&&e.key.toLowerCase()===`s`&&(e.preventDefault(),b(M))}),f.addEventListener(`change`,()=>{let e=f.value;f.value=M.docPath,_(M,`Open another doc?`,()=>{y(M,e)})}),g.addEventListener(`click`,()=>x(M,`edit`)),v.addEventListener(`click`,()=>x(M,`preview`)),C.addEventListener(`click`,()=>{_(M,`Reload this doc?`,()=>{y(M,M.docPath)})}),w.addEventListener(`click`,()=>{b(M)}),T.addEventListener(`click`,a),y(M,n.path),M.mode===`edit`&&k.focus()}function w(e){d&&d.sessionId===e&&(f(d),p(d),!o(e).some(e=>e.path===d?.docPath)&&m(d,`This doc is no longer surfaced, so it cannot be saved.`,`warn`))}export{w as applyDocsToOpenEditor,C as openDocEditor};
@@ -1 +1 @@
1
- import{o as e,y as t}from"./dom-helpers-C7P3_59O.js";import{l as n,u as r}from"./control-ws-CklsyQBG.js";import{Fr as i,Ir as a,Rr as o,bn as s,or as c,ur as l}from"./index-CAztrZ9Y.js";import{a as u,c as d,i as f,n as p,o as m,r as h,s as g,t as _}from"./repo-roots-adder-CfQRgYuh.js";var v=`npm install -g @anthropic-ai/claude-code`,y={done:`<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" role="img" aria-label="Done"><circle cx="12" cy="12" r="10"></circle><path d="M7.5 12.5l3 3 6-6.5"></path></svg>`,current:`<svg width="18" height="18" viewBox="0 0 24 24" role="img" aria-label="Needed"><path d="M12 3l9 9-9 9-9-9z" fill="currentColor"></path></svg>`,upcoming:`<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" role="img" aria-label="Not started"><circle cx="12" cy="12" r="10"></circle></svg>`},b=null,x=null,S=null,C=null,w={steps:h,agentSummary:``,repoRoots:[]},T=0,E=!1,D=!1,O=new Set,k=a(`first-run-load-status`),A=s();function j(e){n({type:`dashboard-telemetry`,event:`operator_action`,properties:{surface:`onboarding`,action:e}})}function M(e){for(let t of m(O,e))n({type:`dashboard-telemetry`,event:`onboarding_step`,properties:t})&&O.add(g(t))}function N({title:t,state:n,summary:r,badge:i,body:a}){let o=e(`li`,`first-run-step`);o.dataset.state=n,n===`current`&&o.setAttribute(`aria-current`,`step`);let s=e(`div`,`first-run-step-head`),c=e(`span`,`first-run-step-icon`);if(c.innerHTML=y[n],s.append(c,e(`span`,`first-run-step-title`,t)),n===`done`&&r&&s.append(e(`span`,`first-run-step-summary`,r)),n===`current`&&i&&s.append(e(`span`,`first-run-step-badge`,i)),o.append(s),n!==`current`)return o;let l=e(`div`,`first-run-step-body`);return l.append(...a()),o.append(l),o}function P(){return c()?`No supported agent is on PATH of the machine running Glimmervoid. Install Claude Code, Codex or Grok there, then rescan.`:`No supported agent is on PATH. Install Claude Code, Codex or Grok, then rescan.`}function F(){let n=e(`div`,`first-run-command-row`);if(n.append(e(`code`,`first-run-command`,v)),!navigator.clipboard?.writeText)return n;let r=e(`button`,`btn-dialog btn-dialog-cancel`,`Copy`);r.type=`button`;let i=e(`span`,`first-run-copy-status`);return i.setAttribute(`role`,`status`),r.addEventListener(`click`,async()=>{let e=t(v);i.textContent=e?await e.then(()=>`Copied`,()=>`Copy failed`):`Copy failed`}),n.append(r,i),n}function I(){let t=e(`div`,`first-run-step-actions`);S=e(`button`,`btn-dialog btn-dialog-cancel`,`Rescan`),S.type=`button`,S.addEventListener(`click`,()=>{j(`rescan`),B({rescanAgents:!0})}),t.append(S);let n=[e(`p`,`first-run-step-text`,P()),F(),t];return E?[...n,e(`p`,`first-run-step-hint`,`Still missing after a rescan? Restart Glimmervoid from a terminal where the command runs. Other terminal agents go under customAgents.`)]:n}function L(){let t=C??_({onAdded:e=>{j(e===`typed`?`add-root-typed`:`add-root-suggested`),B({rescanAgents:!1})}});return C=t,[e(`p`,`first-run-step-text`,`The folder that holds your git checkouts. Each subfolder becomes a project you can start a session in.`),t.element]}function R(){let t=e(`div`,`first-run-step-actions`),n=e(`button`,`btn-dialog btn-dialog-confirm`,`+ Session`);return n.type=`button`,n.addEventListener(`click`,()=>{j(`add-session`),l()}),t.append(n),[e(`p`,`first-run-step-text`,`Pick a project and an agent. The session runs in its own git worktree, so your checkout is never touched.`),t]}function z(){if(!x)return;let{steps:e,agentSummary:t,repoRoots:n}=w;x.replaceChildren(N({title:`1. Agent CLI`,state:e.agent,summary:t,badge:`MISSING`,body:I}),N({title:`2. Repository roots`,state:e.repoRoots,summary:n.join(`, `),badge:`NEEDED`,body:L}),N({title:`3. First session`,state:e.firstSession,summary:``,badge:``,body:R}))}async function B({rescanAgents:e}){T+=1;let t=T;S&&(S.disabled=!0);try{let[n,a]=await Promise.all([r(`list-agents`,e?{rescan:!0}:{},{timeoutMs:i}),r(`scan-repo-roots`,{includeSuggestions:!0},{timeoutMs:i})]);if(t!==T)return;let o=a.type===`repo-roots-scanned`,s=o?a.directories.map(e=>e.root):[],c=o?a.suggestions??[]:[],l=d(s,c);if(l.length>0&&!D){D=!0;let e=await p(l).catch(e=>String(e));if(t!==T)return;if(!e){B({rescanAgents:!1});return}}let m=u({agentListing:n,repoRoots:s});e&&(E=m.agent===`current`),w={steps:m,agentSummary:f(n),repoRoots:s},k.clear(),z(),M(w.steps),C?.setSuggestions(c)}catch(e){if(S&&(S.disabled=!1),t!==T)return;k.show(`error`,`The checklist could not load: ${o(e,i)} It loads again once the server answers. If it stays like this, check the terminal running Glimmervoid, or run glimmervoid doctor.`)}}function V(){if(b)return b;let t=e(`section`,`first-run-checklist`);t.setAttribute(`aria-labelledby`,`first-run-title`);let n=e(`h2`,`first-run-title`,`Get to your first session`);n.id=`first-run-title`,x=e(`ol`,`first-run-steps`);let r=e(`div`,`first-run-optional`);return r.append(e(`span`,`first-run-eyebrow`,`OPTIONAL`),A.element),t.append(e(`span`,`first-run-eyebrow`,`FIRST RUN`),n,x,k.element,r),b=t,z(),t}function H(e,t){if(!t){b?.parentElement===e&&!b.hidden&&(b.hidden=!0);return}let n=V(),r=!n.hidden&&n.parentElement===e;n.parentElement!==e&&e.append(n),n.hidden=!1,A.refresh(),r||B({rescanAgents:!1})}function U(){b&&!b.hidden&&b.isConnected&&B({rescanAgents:!1})}export{U as refreshFirstRunChecklist,H as showFirstRunChecklist};
1
+ import{o as e,y as t}from"./dom-helpers-C7P3_59O.js";import{l as n,u as r}from"./control-ws-CklsyQBG.js";import{Fr as i,Ir as a,Rr as o,bn as s,or as c,ur as l}from"./index-BZuCoMuc.js";import{a as u,c as d,i as f,n as p,o as m,r as h,s as g,t as _}from"./repo-roots-adder-CfQRgYuh.js";var v=`npm install -g @anthropic-ai/claude-code`,y={done:`<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" role="img" aria-label="Done"><circle cx="12" cy="12" r="10"></circle><path d="M7.5 12.5l3 3 6-6.5"></path></svg>`,current:`<svg width="18" height="18" viewBox="0 0 24 24" role="img" aria-label="Needed"><path d="M12 3l9 9-9 9-9-9z" fill="currentColor"></path></svg>`,upcoming:`<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" role="img" aria-label="Not started"><circle cx="12" cy="12" r="10"></circle></svg>`},b=null,x=null,S=null,C=null,w={steps:h,agentSummary:``,repoRoots:[]},T=0,E=!1,D=!1,O=new Set,k=a(`first-run-load-status`),A=s();function j(e){n({type:`dashboard-telemetry`,event:`operator_action`,properties:{surface:`onboarding`,action:e}})}function M(e){for(let t of m(O,e))n({type:`dashboard-telemetry`,event:`onboarding_step`,properties:t})&&O.add(g(t))}function N({title:t,state:n,summary:r,badge:i,body:a}){let o=e(`li`,`first-run-step`);o.dataset.state=n,n===`current`&&o.setAttribute(`aria-current`,`step`);let s=e(`div`,`first-run-step-head`),c=e(`span`,`first-run-step-icon`);if(c.innerHTML=y[n],s.append(c,e(`span`,`first-run-step-title`,t)),n===`done`&&r&&s.append(e(`span`,`first-run-step-summary`,r)),n===`current`&&i&&s.append(e(`span`,`first-run-step-badge`,i)),o.append(s),n!==`current`)return o;let l=e(`div`,`first-run-step-body`);return l.append(...a()),o.append(l),o}function P(){return c()?`No supported agent is on PATH of the machine running Glimmervoid. Install Claude Code, Codex or Grok there, then rescan.`:`No supported agent is on PATH. Install Claude Code, Codex or Grok, then rescan.`}function F(){let n=e(`div`,`first-run-command-row`);if(n.append(e(`code`,`first-run-command`,v)),!navigator.clipboard?.writeText)return n;let r=e(`button`,`btn-dialog btn-dialog-cancel`,`Copy`);r.type=`button`;let i=e(`span`,`first-run-copy-status`);return i.setAttribute(`role`,`status`),r.addEventListener(`click`,async()=>{let e=t(v);i.textContent=e?await e.then(()=>`Copied`,()=>`Copy failed`):`Copy failed`}),n.append(r,i),n}function I(){let t=e(`div`,`first-run-step-actions`);S=e(`button`,`btn-dialog btn-dialog-cancel`,`Rescan`),S.type=`button`,S.addEventListener(`click`,()=>{j(`rescan`),B({rescanAgents:!0})}),t.append(S);let n=[e(`p`,`first-run-step-text`,P()),F(),t];return E?[...n,e(`p`,`first-run-step-hint`,`Still missing after a rescan? Restart Glimmervoid from a terminal where the command runs. Other terminal agents go under customAgents.`)]:n}function L(){let t=C??_({onAdded:e=>{j(e===`typed`?`add-root-typed`:`add-root-suggested`),B({rescanAgents:!1})}});return C=t,[e(`p`,`first-run-step-text`,`The folder that holds your git checkouts. Each subfolder becomes a project you can start a session in.`),t.element]}function R(){let t=e(`div`,`first-run-step-actions`),n=e(`button`,`btn-dialog btn-dialog-confirm`,`+ Session`);return n.type=`button`,n.addEventListener(`click`,()=>{j(`add-session`),l()}),t.append(n),[e(`p`,`first-run-step-text`,`Pick a project and an agent. The session runs in its own git worktree, so your checkout is never touched.`),t]}function z(){if(!x)return;let{steps:e,agentSummary:t,repoRoots:n}=w;x.replaceChildren(N({title:`1. Agent CLI`,state:e.agent,summary:t,badge:`MISSING`,body:I}),N({title:`2. Repository roots`,state:e.repoRoots,summary:n.join(`, `),badge:`NEEDED`,body:L}),N({title:`3. First session`,state:e.firstSession,summary:``,badge:``,body:R}))}async function B({rescanAgents:e}){T+=1;let t=T;S&&(S.disabled=!0);try{let[n,a]=await Promise.all([r(`list-agents`,e?{rescan:!0}:{},{timeoutMs:i}),r(`scan-repo-roots`,{includeSuggestions:!0},{timeoutMs:i})]);if(t!==T)return;let o=a.type===`repo-roots-scanned`,s=o?a.directories.map(e=>e.root):[],c=o?a.suggestions??[]:[],l=d(s,c);if(l.length>0&&!D){D=!0;let e=await p(l).catch(e=>String(e));if(t!==T)return;if(!e){B({rescanAgents:!1});return}}let m=u({agentListing:n,repoRoots:s});e&&(E=m.agent===`current`),w={steps:m,agentSummary:f(n),repoRoots:s},k.clear(),z(),M(w.steps),C?.setSuggestions(c)}catch(e){if(S&&(S.disabled=!1),t!==T)return;k.show(`error`,`The checklist could not load: ${o(e,i)} It loads again once the server answers. If it stays like this, check the terminal running Glimmervoid, or run glimmervoid doctor.`)}}function V(){if(b)return b;let t=e(`section`,`first-run-checklist`);t.setAttribute(`aria-labelledby`,`first-run-title`);let n=e(`h2`,`first-run-title`,`Get to your first session`);n.id=`first-run-title`,x=e(`ol`,`first-run-steps`);let r=e(`div`,`first-run-optional`);return r.append(e(`span`,`first-run-eyebrow`,`OPTIONAL`),A.element),t.append(e(`span`,`first-run-eyebrow`,`FIRST RUN`),n,x,k.element,r),b=t,z(),t}function H(e,t){if(!t){b?.parentElement===e&&!b.hidden&&(b.hidden=!0);return}let n=V(),r=!n.hidden&&n.parentElement===e;n.parentElement!==e&&e.append(n),n.hidden=!1,A.refresh(),r||B({rescanAgents:!1})}function U(){b&&!b.hidden&&b.isConnected&&B({rescanAgents:!1})}export{U as refreshFirstRunChecklist,H as showFirstRunChecklist};
@@ -1 +1 @@
1
- import{_ as e,a as t,f as n,l as r,m as i,n as a,r as o,u as s}from"./zod-BRLv4KqJ.js";import{n as c}from"./updates-view-core-Z-HI1v-s.js";import{n as l,o as u,p as d,r as f,u as p}from"./dom-helpers-C7P3_59O.js";import{u as m}from"./control-ws-CklsyQBG.js";import{a as h}from"./modal-Bh-cVr-I.js";import{Fr as g,Gt as _,Ir as ee,Rr as v,Ut as y,Wt as b}from"./index-CAztrZ9Y.js";var te=n(i(),e());s({glimmervoidId:i().min(1),event:i().min(1),token:i().nullable().optional(),payload:te}),s({id:i().min(1),name:i().min(1),event:i().min(1),matcher:i().optional(),type:a([`command`,`http`]),command:i().optional(),url:i().optional(),timeout:r().int().positive().optional(),enabled:t(),projects:o(i()).optional()}).passthrough();var ne=`Claude Code hooks injected into every session Glimmervoid spawns.`,re=`Loading hooks`,ie=`No hooks yet. A hook runs a command, or calls a URL, when a Claude Code event fires in a Glimmervoid session. Start from one of these, or add your own.`,ae=`Start from`,oe=`Filter by name, event or command`,se=`Nothing matches that filter.`,ce=`Preview`,le=`The entry this becomes in the per-session settings file.`,ue=`Duplicate`,de=`Discard changes`,fe=`Close the editor and lose the unsaved changes?`,pe=`Esc cancels. Ctrl+Enter saves.`,me=4,he=`A change reaches a session at its next start or restart. Claude Code sessions only; Codex and Grok sessions do not read this file.`,ge=`Glimmervoid's own hooks`,_e=`Always present, read-only. Status detection depends on them.`,ve=`Your hooks`,ye=`New hook`,be=`Edit hook`,xe=`Saved to config.json.`,x=`All projects`,Se=`This event takes no matcher.`,Ce=`Blank uses Claude Code's default for the event.`,we=Object.freeze([{value:`command`,label:`Command`,hint:`Run a shell command. It receives the event JSON on stdin.`},{value:`http`,label:`HTTP`,hint:`POST the event JSON to a URL.`}]),Te=Object.freeze([{id:`lint`,label:`Lint after edits`,summary:`PostToolUse on Edit|Write`,draft:{name:`Lint after edits`,event:`PostToolUse`,matcher:`Edit|Write`,type:`command`,command:`npx biome check --write "$(jq -r .tool_input.file_path)"`}},{id:`notify`,label:`Notify on Stop`,summary:`Stop, command`,draft:{name:`Notify on Stop`,event:`Stop`,matcher:``,type:`command`,command:`command -v notify-send >/dev/null 2>&1 && notify-send "Claude finished a turn" || { command -v osascript >/dev/null 2>&1 && osascript -e 'display notification "Claude finished a turn" with title "Claude Code"'; }`}},{id:`guard`,label:`Guard destructive Bash`,summary:`PreToolUse on Bash, exit 2 blocks`,draft:{name:`Guard destructive Bash`,event:`PreToolUse`,matcher:`Bash`,type:`command`,command:`jq -r .tool_input.command | grep -Eq "rm -rf|git push --force" && exit 2 || exit 0`}},{id:`log`,label:`Log every prompt`,summary:`UserPromptSubmit, appends JSON`,draft:{name:`Log every prompt`,event:`UserPromptSubmit`,matcher:``,type:`command`,command:`cat >> ~/.claude/prompts.jsonl`}}]),Ee=Object.freeze({hooks:[],builtin:[],events:[]});function De(e){return!e||typeof e.error==`string`}function Oe(e){return!e||typeof e.error!=`string`?``:e.error}function S(e,t){let n=e?.[t];return Array.isArray(n)?n:Ee[t]}var C=e=>S(e,`hooks`),w=e=>S(e,`builtin`),T=e=>S(e,`events`);function E(e){let t=e?.limits?.maxTimeoutSec;return typeof t==`number`&&Number.isInteger(t)&&t>0?t:600}function ke(e){let t=C(e),n=t.filter(e=>e.enabled!==!1).length;return[{label:`yours`,value:String(t.length),tone:null},{label:`enabled`,value:String(n),tone:t.length>0&&n===0?`warn`:null},{label:`built in`,value:String(w(e).length),tone:null}]}function Ae(e,t){let n=new Map(t.map((e,t)=>[e.name,t])),r=e=>n.get(e.event)??t.length;return[...e].sort((e,t)=>{let n=r(e)-r(t);return n===0?String(e.name).localeCompare(String(t.name)):n})}function je(e,t){let n=String(t||``).trim().toLowerCase();return n?e.filter(e=>[e.name,e.event,e.matcher,e.command,e.url].some(e=>typeof e==`string`&&e.toLowerCase().includes(n))):e}function Me(e){return e.length>=me}function Ne(e){let t=[];for(let n of e){let e=t[t.length-1];e&&e.event===n.event?e.hooks.push(n):t.push({event:n.event,hooks:[n]})}return t}function Pe(e){let t=e.type===`http`?{type:`http`,url:e.url||``}:{type:`command`,command:e.command||``};Number.isInteger(e.timeout)&&Number(e.timeout)>0&&(t.timeout=e.timeout);let n=e.matcher?{matcher:e.matcher,hooks:[t]}:{hooks:[t]};return JSON.stringify({hooks:{[e.event]:[n]}},null,2)}function Fe(e){return`${e} copy`}function D(e,t){return e.find(e=>e.name===t)||null}function O(e,t){let n=D(e,t);return n?n.matcher?`Matches ${n.matcher}. Blank matches every ${n.name}.`:Se:``}function Ie(e){return e.type===`http`?e.url||``:e.command||``}function Le(e){let t=we.find(t=>t.value===e);return t?t.label:String(e||``)}function Re(e){return!Number.isInteger(e.timeout)||Number(e.timeout)<=0?``:`${e.timeout}s timeout`}function ze(e,t){let n=Array.isArray(e.projects)?e.projects:[];return n.length===0?x:n.map(e=>{let n=t.find(t=>t.id===e);return n?n.name:e}).join(`, `)}function Be(e){return e.matcher?`${e.event} / ${e.matcher}`:e.event}function Ve(e){return Be(e)}function He(e,t){let n=Array.isArray(e.projects)?e.projects:[],r=new Set(t.map(e=>e.id));return n.filter(e=>!r.has(e))}function k(e){let t=e[0];return{id:null,name:``,event:t?t.name:``,matcher:``,type:`command`,command:``,url:``,timeout:``,enabled:!0,projects:[]}}function A(e){return{id:e.id??null,name:e.name||``,event:e.event||``,matcher:e.matcher||``,type:e.type===`http`?`http`:`command`,command:e.command||``,url:e.url||``,timeout:Number.isInteger(e.timeout)?String(e.timeout):``,enabled:e.enabled!==!1,projects:Array.isArray(e.projects)?[...e.projects]:[]}}function Ue(e,t,n=600){if(!e.name.trim())return`Give the hook a name.`;let r=D(t,e.event);if(!r)return`Pick an event.`;if(e.matcher.trim()&&!r.matcher)return`${r.name} takes no matcher.`;if(e.type===`http`&&r.http===!1)return`${r.name} does not support HTTP hooks.`;if(e.type===`command`&&!e.command.trim())return`Enter the command to run.`;if(e.type===`http`&&!/^https?:\/\/\S+$/i.test(e.url.trim()))return`Enter a URL starting with http:// or https://.`;if(e.timeout.trim()!==``){let t=Number(e.timeout);if(!Number.isInteger(t)||t<1||t>n)return`Timeout must be a whole number of seconds from 1 to ${n}.`}return null}function j(e){let t={name:e.name.trim(),event:e.event,type:e.type,enabled:e.enabled!==!1};return e.id&&(t.id=e.id),e.matcher.trim()&&(t.matcher=e.matcher.trim()),e.type===`command`&&(t.command=e.command.trim()),e.type===`http`&&(t.url=e.url.trim()),e.timeout.trim()!==``&&(t.timeout=Number(e.timeout)),e.projects.length>0&&(t.projects=[...e.projects]),t}function We(e,t){let n={...k(t),...e.draft};return D(t,n.event)||(n.event=k(t).event),n}function Ge(e,t){return JSON.stringify(j(e))!==JSON.stringify(t)}function Ke(e){return{...e,enabled:e.enabled===!1}}function qe(e){return`Delete the hook "${e.name}"? Sessions already running keep it until they restart.`}var M=y(),N=null,P=null,F=null,I=null,L=null,R=null,z=!1,B=``,V=new Set,H=new Set,U=new Map,W=!1,G=(e,t)=>l(`hooks`,e,t);function K(e,t,n){let r=u(`p`,e,t);return n&&(r.dataset.tone=n),r}function q(e,t,n,r){let i=u(`button`,e,t);return i.type=`button`,r&&i.setAttribute(`aria-label`,r),i.addEventListener(`click`,n),i}async function Je(e,t){try{let n=await m(e,t,{timeoutMs:g});if((n.type===`save-hook-result`||n.type===`delete-hook-result`)&&n.ok)return null;let r=e===`save-hook`?`Could not save the hook.`:`Could not delete the hook.`;return`error`in n&&typeof n.error==`string`&&n.error?n.error:r}catch(e){return v(e,g)}}async function Ye(e,t,n,r){H.add(e),U.set(e,{tone:`busy`,text:r}),$({force:!0});let i=await Je(t,n);H.delete(e),i&&U.set(e,{tone:`error`,text:i}),i||U.delete(e),$({force:!0}),b()}function J(e,t,n){let r=u(`label`,`hooks-field`);return r.append(u(`span`,`hooks-field-label`,e),t),n&&r.append(u(`span`,`hooks-field-hint`,n)),r}function Y(e,t,n){let r=u(`input`,`settings-view-input`);return r.type=`text`,r.value=e,r.autocomplete=`off`,r.spellcheck=!1,t&&(r.placeholder=t),r.addEventListener(`input`,()=>n(r.value)),r}function Xe(e,t){let n=u(`textarea`,`settings-view-input hooks-command`);return n.rows=3,n.value=e,n.spellcheck=!1,n.addEventListener(`input`,()=>t(n.value)),n}function Ze(e,t,n){let r=u(`select`,`settings-view-input hooks-select`);for(let n of t){let t=u(`option`,null,n.name);t.value=n.name,t.title=n.description,n.name===e.event&&(t.selected=!0),r.append(t)}return r.addEventListener(`change`,()=>n(r.value)),r}function Qe(e,t){let n=u(`div`,`hooks-type-row`);n.setAttribute(`role`,`radiogroup`);for(let r of we){let i=u(`label`,`settings-view-toggle hooks-choice`),a=u(`input`,`settings-view-checkbox`);a.type=`radio`,a.name=`hooks-type`,a.value=r.value,a.checked=e.type===r.value,a.title=r.hint,a.addEventListener(`change`,()=>{a.checked&&t(r.value)}),i.append(a,u(`span`,null,r.label)),n.append(i)}return n}function $e(e,t){let n=u(`div`,`hooks-projects`);if(t.length===0)return n.append(u(`span`,`hooks-field-hint`,x)),n;let r=u(`label`,`settings-view-project-choice hooks-choice`),i=u(`input`,`settings-view-checkbox`);i.type=`checkbox`,i.checked=e.projects.length===0,r.append(i,u(`span`,null,x)),n.append(r);let a=[];for(let r of t){let t=u(`label`,`settings-view-project-choice hooks-choice`),o=u(`input`,`settings-view-checkbox`);o.type=`checkbox`,o.value=r.id,o.checked=e.projects.includes(r.id),o.addEventListener(`change`,()=>{e.projects=a.filter(e=>e.checked).map(e=>e.value),i.checked=e.projects.length===0}),a.push(o),t.append(o,u(`span`,null,r.name)),r.agent!==`claude-code`&&(t.append(u(`span`,`hooks-choice-note`,r.agent)),t.title=`Not a Claude Code project: this hook will not reach its sessions.`),n.append(t)}return i.addEventListener(`change`,()=>{if(!i.checked)i.checked=e.projects.length===0;else{for(let e of a)e.checked=!1;e.projects=[]}}),n}function et(e){let t=u(`div`,`hooks-templates`);t.append(u(`span`,`hooks-templates-label`,ae));for(let n of Te){let r=q(`hooks-chip`,n.label,()=>Z(null,We(n,e)));r.title=n.summary,t.append(r)}return t}function X(e){L&&(e?L.show(`error`,e):L.clear())}function tt(e){let t=T(M.report),n=d(M.report),r=G(e.id?be:ye,xe);r.classList.add(`hooks-editor`);let i=u(`form`,`hooks-form`);i.addEventListener(`submit`,e=>{e.preventDefault(),rt()}),i.addEventListener(`keydown`,e=>{e.key===`Escape`?(e.preventDefault(),nt()):e.key===`Enter`&&(e.ctrlKey||e.metaKey)&&(e.preventDefault(),rt())}),e.id||i.append(et(t));let a=u(`span`,`hooks-field-hint`,O(t,e.event)),o=Y(e.matcher,``,t=>{e.matcher=t}),s=J(`Command`,Xe(e.command,t=>{e.command=t}),`Runs through the shell with the event JSON on stdin. Exit 2 blocks the action where the event allows it.`),c=J(`URL`,Y(e.url,`http://127.0.0.1:8080/hook`,t=>{e.url=t}),`Claude Code POSTs the event JSON to it.`),l=()=>{s.hidden=e.type!==`command`,c.hidden=e.type!==`http`};l();let f=J(`Matcher`,o,null);f.append(a);let p=()=>{let n=t.find(t=>t.name===e.event);a.textContent=O(t,e.event),o.disabled=!!n&&!n.matcher,o.disabled&&(o.value=``,e.matcher=``)};p();let m=u(`input`,`settings-view-input hooks-timeout`);m.type=`number`,m.inputMode=`numeric`,m.min=`1`,m.max=String(E(M.report)),m.value=e.timeout,m.addEventListener(`input`,()=>{e.timeout=m.value});let h=u(`label`,`settings-view-toggle hooks-choice`),g=u(`input`,`settings-view-checkbox`);g.type=`checkbox`,g.checked=e.enabled,g.addEventListener(`change`,()=>{e.enabled=g.checked}),h.append(g,u(`span`,null,`Enabled`)),i.append(J(`Name`,Y(e.name,`Lint after edits`,t=>{e.name=t}),null),J(`Event`,Ze(e,t,t=>{e.event=t,p()}),null),f,J(`Type`,Qe(e,t=>{e.type=t,l()}),null),s,c,J(`Timeout (seconds)`,m,Ce),J(`Projects`,$e(e,n),null),J(``,h,null)),L=ee(`hooks-editor-status`);let _=u(`div`,`hooks-editor-footer`),v=u(`span`,`hooks-editor-shortcut`,pe),y=q(`btn-dialog btn-dialog-cancel`,`Cancel`,nt),b=u(`button`,`btn-dialog btn-dialog-confirm`,e.id?`Save changes`:`Add hook`);return b.type=`submit`,R=b,_.append(L.element,v,y,b),i.append(_),r.append(i),r}function Z(e,t=null){P=t||(e?A(e):k(T(M.report))),F=j(e?A(e):k(T(M.report))),I=tt(P),$({force:!0}),I.scrollIntoView({block:`nearest`});let n=I.querySelector(`input[type=text]`);n instanceof HTMLInputElement&&n.focus()}function Q(){P=null,F=null,I=null,L=null,R=null,z=!1,W=!0,$({force:!0})}function nt(){!P||!F||!Ge(P,F)?Q():h({title:de,message:fe,confirmLabel:`Discard`,danger:!0,onConfirm:Q})}async function rt(){if(!P||z)return;let e=Ue(P,T(M.report),E(M.report));if(e){X(e);return}let t=L,n=R;z=!0,t?.show(`busy`,`Saving the hook.`),n&&(n.disabled=!0);let r=await Je(`save-hook`,{hook:j(P)});z=!1,n&&(n.disabled=!1),t===L&&(r?X(r):(Q(),b()))}function it(e){let t=u(`details`,`hooks-preview`);t.open=V.has(e.id),t.addEventListener(`toggle`,()=>{t.open?V.add(e.id):V.delete(e.id)});let n=u(`summary`,`hooks-preview-summary`,ce);n.title=le;let r=u(`pre`,`hooks-preview-code`,Pe(e));return t.append(n,r),t}function at(e,{grouped:t=!1}={}){let n=d(M.report),r=u(`article`,`hooks-row`);r.setAttribute(`aria-label`,e.name),e.enabled===!1&&(r.dataset.state=`off`);let i=u(`div`,`hooks-row-main`),a=u(`div`,`hooks-row-head`);a.append(u(`span`,`hooks-row-name`,e.name));let o=t?e.matcher||``:Be(e);o&&a.append(u(`span`,`hooks-row-event`,o));let s=u(`code`,`hooks-row-target`,Ie(e));s.title=Ie(e);let c=u(`p`,`hooks-row-meta`,[Le(e.type),Re(e),ze(e,n)].filter(Boolean).join(` / `));i.append(a,s,c);let l=He(e,n);l.length>0&&i.append(K(`hooks-row-meta`,`Scoped to a project no longer in config: ${l.join(`, `)}`,`warn`)),i.append(it(e));let f=U.get(e.id);if(f){let e=ee(`hooks-row-status`);e.show(f.tone,f.text),i.append(e.element)}let p=u(`div`,`hooks-row-actions`),m=u(`label`,`settings-view-toggle hooks-choice`),g=u(`input`,`settings-view-checkbox`);g.type=`checkbox`,g.checked=e.enabled!==!1,g.disabled=H.has(e.id),g.setAttribute(`aria-label`,`${e.name} enabled`),g.addEventListener(`change`,()=>{Ye(e.id,`save-hook`,{hook:Ke(e)},g.checked?`Turning the hook on.`:`Turning the hook off.`)}),m.append(g,u(`span`,null,`On`));let _=q(`hooks-btn`,`Edit`,()=>Z(e),`Edit ${e.name}`),v=q(`hooks-btn`,ue,()=>{let t=A({...e,name:Fe(e.name)});t.id=null,Z(null,t)},`Duplicate ${e.name}`),y=q(`hooks-btn hooks-btn-danger`,`Delete`,()=>{h({title:`Delete hook`,message:qe(e),confirmLabel:`Delete`,danger:!0,onConfirm:()=>{Ye(e.id,`delete-hook`,{id:e.id},`Deleting the hook.`)}})},`Delete ${e.name}`);return y.disabled=H.has(e.id),p.append(m,_,v,y),r.append(i,p),r}function ot(e){let t=u(`article`,`hooks-row hooks-row-builtin`),n=u(`div`,`hooks-row-main`);return n.append(u(`span`,`hooks-row-event`,Ve(e)),u(`p`,`hooks-row-meta`,e.purpose)),t.append(n),t}function st(){let e=G(`Hooks`,ne),t=u(`div`,`hooks-stats`);for(let e of ke(M.report))t.append(f(`hooks`,e.label,e.value,e.tone));return e.append(t,K(`hooks-meta`,he)),e}function ct(){let e=u(`input`,`settings-view-input hooks-filter`);return e.type=`search`,e.value=B,e.placeholder=oe,e.setAttribute(`aria-label`,oe),e.addEventListener(`input`,()=>{B=e.value;let t=N?.querySelector(`.hooks-list-yours`);t&&t.replaceWith(ut())}),e}function lt(){let e=u(`div`,`hooks-empty-state`);return e.append(K(`hooks-empty`,ie),et(T(M.report))),e}function ut(){let e=u(`div`,`hooks-list-yours`),t=C(M.report);if(t.length===0)return e.append(lt()),e;let n=je(Ae(t,T(M.report)),B);if(n.length===0)return e.append(K(`hooks-empty`,se)),e;for(let t of Ne(n)){let n=u(`div`,`hooks-group`);n.append(u(`h3`,`hooks-group-title`,t.event));let r=u(`div`,`hooks-list`);for(let e of t.hooks)r.append(at(e,{grouped:!0}));n.append(r),e.append(n)}return e}function dt(){let e=G(ve,null),t=q(`hooks-btn hooks-btn-add`,`+ New hook`,()=>Z(null));t.disabled=!!P;let n=e.querySelector(`.hooks-section-head`);return n&&n.append(t),Me(C(M.report))&&e.append(ct()),e.append(ut()),e}function ft(){let e=u(`details`,`hooks-builtin`),t=u(`summary`,`hooks-builtin-summary`);t.append(u(`span`,`hooks-section-title`,`${ge} (${w(M.report).length})`),u(`span`,`hooks-section-hint`,_e));let n=u(`div`,`hooks-list`);for(let e of w(M.report))n.append(ot(e));return e.append(t,n),e}function pt(){let e=u(`div`,`hooks-content`);return M.report?De(M.report)?(e.append(K(`hooks-warning`,Oe(M.report))),e):(e.append(st()),I&&e.append(I),e.append(dt(),ft()),e):(e.append(M.hasReportSendFailed?K(`hooks-warning`,c):K(`hooks-empty`,re)),e)}function $({force:e=!1}={}){if(!N||!e&&p(N)||(M=y(),N.replaceChildren(pt()),!W))return;W=!1;let t=N.querySelector(`.hooks-btn-add`);t instanceof HTMLButtonElement&&t.focus()}function mt(e){N||(N=u(`div`,`hooks-panel`),e.append(N),_(()=>$()),$({force:!0}))}function ht(e){e===`shown`&&$({force:!0}),b()}var gt={mount:mt,refresh:ht};export{gt as view};
1
+ import{_ as e,a as t,f as n,l as r,m as i,n as a,r as o,u as s}from"./zod-BRLv4KqJ.js";import{n as c}from"./updates-view-core-Z-HI1v-s.js";import{n as l,o as u,p as d,r as f,u as p}from"./dom-helpers-C7P3_59O.js";import{u as m}from"./control-ws-CklsyQBG.js";import{a as h}from"./modal-Bh-cVr-I.js";import{Fr as g,Gt as _,Ir as ee,Rr as v,Ut as y,Wt as b}from"./index-BZuCoMuc.js";var te=n(i(),e());s({glimmervoidId:i().min(1),event:i().min(1),token:i().nullable().optional(),payload:te}),s({id:i().min(1),name:i().min(1),event:i().min(1),matcher:i().optional(),type:a([`command`,`http`]),command:i().optional(),url:i().optional(),timeout:r().int().positive().optional(),enabled:t(),projects:o(i()).optional()}).passthrough();var ne=`Claude Code hooks injected into every session Glimmervoid spawns.`,re=`Loading hooks`,ie=`No hooks yet. A hook runs a command, or calls a URL, when a Claude Code event fires in a Glimmervoid session. Start from one of these, or add your own.`,ae=`Start from`,oe=`Filter by name, event or command`,se=`Nothing matches that filter.`,ce=`Preview`,le=`The entry this becomes in the per-session settings file.`,ue=`Duplicate`,de=`Discard changes`,fe=`Close the editor and lose the unsaved changes?`,pe=`Esc cancels. Ctrl+Enter saves.`,me=4,he=`A change reaches a session at its next start or restart. Claude Code sessions only; Codex and Grok sessions do not read this file.`,ge=`Glimmervoid's own hooks`,_e=`Always present, read-only. Status detection depends on them.`,ve=`Your hooks`,ye=`New hook`,be=`Edit hook`,xe=`Saved to config.json.`,x=`All projects`,Se=`This event takes no matcher.`,Ce=`Blank uses Claude Code's default for the event.`,we=Object.freeze([{value:`command`,label:`Command`,hint:`Run a shell command. It receives the event JSON on stdin.`},{value:`http`,label:`HTTP`,hint:`POST the event JSON to a URL.`}]),Te=Object.freeze([{id:`lint`,label:`Lint after edits`,summary:`PostToolUse on Edit|Write`,draft:{name:`Lint after edits`,event:`PostToolUse`,matcher:`Edit|Write`,type:`command`,command:`npx biome check --write "$(jq -r .tool_input.file_path)"`}},{id:`notify`,label:`Notify on Stop`,summary:`Stop, command`,draft:{name:`Notify on Stop`,event:`Stop`,matcher:``,type:`command`,command:`command -v notify-send >/dev/null 2>&1 && notify-send "Claude finished a turn" || { command -v osascript >/dev/null 2>&1 && osascript -e 'display notification "Claude finished a turn" with title "Claude Code"'; }`}},{id:`guard`,label:`Guard destructive Bash`,summary:`PreToolUse on Bash, exit 2 blocks`,draft:{name:`Guard destructive Bash`,event:`PreToolUse`,matcher:`Bash`,type:`command`,command:`jq -r .tool_input.command | grep -Eq "rm -rf|git push --force" && exit 2 || exit 0`}},{id:`log`,label:`Log every prompt`,summary:`UserPromptSubmit, appends JSON`,draft:{name:`Log every prompt`,event:`UserPromptSubmit`,matcher:``,type:`command`,command:`cat >> ~/.claude/prompts.jsonl`}}]),Ee=Object.freeze({hooks:[],builtin:[],events:[]});function De(e){return!e||typeof e.error==`string`}function Oe(e){return!e||typeof e.error!=`string`?``:e.error}function S(e,t){let n=e?.[t];return Array.isArray(n)?n:Ee[t]}var C=e=>S(e,`hooks`),w=e=>S(e,`builtin`),T=e=>S(e,`events`);function E(e){let t=e?.limits?.maxTimeoutSec;return typeof t==`number`&&Number.isInteger(t)&&t>0?t:600}function ke(e){let t=C(e),n=t.filter(e=>e.enabled!==!1).length;return[{label:`yours`,value:String(t.length),tone:null},{label:`enabled`,value:String(n),tone:t.length>0&&n===0?`warn`:null},{label:`built in`,value:String(w(e).length),tone:null}]}function Ae(e,t){let n=new Map(t.map((e,t)=>[e.name,t])),r=e=>n.get(e.event)??t.length;return[...e].sort((e,t)=>{let n=r(e)-r(t);return n===0?String(e.name).localeCompare(String(t.name)):n})}function je(e,t){let n=String(t||``).trim().toLowerCase();return n?e.filter(e=>[e.name,e.event,e.matcher,e.command,e.url].some(e=>typeof e==`string`&&e.toLowerCase().includes(n))):e}function Me(e){return e.length>=me}function Ne(e){let t=[];for(let n of e){let e=t[t.length-1];e&&e.event===n.event?e.hooks.push(n):t.push({event:n.event,hooks:[n]})}return t}function Pe(e){let t=e.type===`http`?{type:`http`,url:e.url||``}:{type:`command`,command:e.command||``};Number.isInteger(e.timeout)&&Number(e.timeout)>0&&(t.timeout=e.timeout);let n=e.matcher?{matcher:e.matcher,hooks:[t]}:{hooks:[t]};return JSON.stringify({hooks:{[e.event]:[n]}},null,2)}function Fe(e){return`${e} copy`}function D(e,t){return e.find(e=>e.name===t)||null}function O(e,t){let n=D(e,t);return n?n.matcher?`Matches ${n.matcher}. Blank matches every ${n.name}.`:Se:``}function Ie(e){return e.type===`http`?e.url||``:e.command||``}function Le(e){let t=we.find(t=>t.value===e);return t?t.label:String(e||``)}function Re(e){return!Number.isInteger(e.timeout)||Number(e.timeout)<=0?``:`${e.timeout}s timeout`}function ze(e,t){let n=Array.isArray(e.projects)?e.projects:[];return n.length===0?x:n.map(e=>{let n=t.find(t=>t.id===e);return n?n.name:e}).join(`, `)}function Be(e){return e.matcher?`${e.event} / ${e.matcher}`:e.event}function Ve(e){return Be(e)}function He(e,t){let n=Array.isArray(e.projects)?e.projects:[],r=new Set(t.map(e=>e.id));return n.filter(e=>!r.has(e))}function k(e){let t=e[0];return{id:null,name:``,event:t?t.name:``,matcher:``,type:`command`,command:``,url:``,timeout:``,enabled:!0,projects:[]}}function A(e){return{id:e.id??null,name:e.name||``,event:e.event||``,matcher:e.matcher||``,type:e.type===`http`?`http`:`command`,command:e.command||``,url:e.url||``,timeout:Number.isInteger(e.timeout)?String(e.timeout):``,enabled:e.enabled!==!1,projects:Array.isArray(e.projects)?[...e.projects]:[]}}function Ue(e,t,n=600){if(!e.name.trim())return`Give the hook a name.`;let r=D(t,e.event);if(!r)return`Pick an event.`;if(e.matcher.trim()&&!r.matcher)return`${r.name} takes no matcher.`;if(e.type===`http`&&r.http===!1)return`${r.name} does not support HTTP hooks.`;if(e.type===`command`&&!e.command.trim())return`Enter the command to run.`;if(e.type===`http`&&!/^https?:\/\/\S+$/i.test(e.url.trim()))return`Enter a URL starting with http:// or https://.`;if(e.timeout.trim()!==``){let t=Number(e.timeout);if(!Number.isInteger(t)||t<1||t>n)return`Timeout must be a whole number of seconds from 1 to ${n}.`}return null}function j(e){let t={name:e.name.trim(),event:e.event,type:e.type,enabled:e.enabled!==!1};return e.id&&(t.id=e.id),e.matcher.trim()&&(t.matcher=e.matcher.trim()),e.type===`command`&&(t.command=e.command.trim()),e.type===`http`&&(t.url=e.url.trim()),e.timeout.trim()!==``&&(t.timeout=Number(e.timeout)),e.projects.length>0&&(t.projects=[...e.projects]),t}function We(e,t){let n={...k(t),...e.draft};return D(t,n.event)||(n.event=k(t).event),n}function Ge(e,t){return JSON.stringify(j(e))!==JSON.stringify(t)}function Ke(e){return{...e,enabled:e.enabled===!1}}function qe(e){return`Delete the hook "${e.name}"? Sessions already running keep it until they restart.`}var M=y(),N=null,P=null,F=null,I=null,L=null,R=null,z=!1,B=``,V=new Set,H=new Set,U=new Map,W=!1,G=(e,t)=>l(`hooks`,e,t);function K(e,t,n){let r=u(`p`,e,t);return n&&(r.dataset.tone=n),r}function q(e,t,n,r){let i=u(`button`,e,t);return i.type=`button`,r&&i.setAttribute(`aria-label`,r),i.addEventListener(`click`,n),i}async function Je(e,t){try{let n=await m(e,t,{timeoutMs:g});if((n.type===`save-hook-result`||n.type===`delete-hook-result`)&&n.ok)return null;let r=e===`save-hook`?`Could not save the hook.`:`Could not delete the hook.`;return`error`in n&&typeof n.error==`string`&&n.error?n.error:r}catch(e){return v(e,g)}}async function Ye(e,t,n,r){H.add(e),U.set(e,{tone:`busy`,text:r}),$({force:!0});let i=await Je(t,n);H.delete(e),i&&U.set(e,{tone:`error`,text:i}),i||U.delete(e),$({force:!0}),b()}function J(e,t,n){let r=u(`label`,`hooks-field`);return r.append(u(`span`,`hooks-field-label`,e),t),n&&r.append(u(`span`,`hooks-field-hint`,n)),r}function Y(e,t,n){let r=u(`input`,`settings-view-input`);return r.type=`text`,r.value=e,r.autocomplete=`off`,r.spellcheck=!1,t&&(r.placeholder=t),r.addEventListener(`input`,()=>n(r.value)),r}function Xe(e,t){let n=u(`textarea`,`settings-view-input hooks-command`);return n.rows=3,n.value=e,n.spellcheck=!1,n.addEventListener(`input`,()=>t(n.value)),n}function Ze(e,t,n){let r=u(`select`,`settings-view-input hooks-select`);for(let n of t){let t=u(`option`,null,n.name);t.value=n.name,t.title=n.description,n.name===e.event&&(t.selected=!0),r.append(t)}return r.addEventListener(`change`,()=>n(r.value)),r}function Qe(e,t){let n=u(`div`,`hooks-type-row`);n.setAttribute(`role`,`radiogroup`);for(let r of we){let i=u(`label`,`settings-view-toggle hooks-choice`),a=u(`input`,`settings-view-checkbox`);a.type=`radio`,a.name=`hooks-type`,a.value=r.value,a.checked=e.type===r.value,a.title=r.hint,a.addEventListener(`change`,()=>{a.checked&&t(r.value)}),i.append(a,u(`span`,null,r.label)),n.append(i)}return n}function $e(e,t){let n=u(`div`,`hooks-projects`);if(t.length===0)return n.append(u(`span`,`hooks-field-hint`,x)),n;let r=u(`label`,`settings-view-project-choice hooks-choice`),i=u(`input`,`settings-view-checkbox`);i.type=`checkbox`,i.checked=e.projects.length===0,r.append(i,u(`span`,null,x)),n.append(r);let a=[];for(let r of t){let t=u(`label`,`settings-view-project-choice hooks-choice`),o=u(`input`,`settings-view-checkbox`);o.type=`checkbox`,o.value=r.id,o.checked=e.projects.includes(r.id),o.addEventListener(`change`,()=>{e.projects=a.filter(e=>e.checked).map(e=>e.value),i.checked=e.projects.length===0}),a.push(o),t.append(o,u(`span`,null,r.name)),r.agent!==`claude-code`&&(t.append(u(`span`,`hooks-choice-note`,r.agent)),t.title=`Not a Claude Code project: this hook will not reach its sessions.`),n.append(t)}return i.addEventListener(`change`,()=>{if(!i.checked)i.checked=e.projects.length===0;else{for(let e of a)e.checked=!1;e.projects=[]}}),n}function et(e){let t=u(`div`,`hooks-templates`);t.append(u(`span`,`hooks-templates-label`,ae));for(let n of Te){let r=q(`hooks-chip`,n.label,()=>Z(null,We(n,e)));r.title=n.summary,t.append(r)}return t}function X(e){L&&(e?L.show(`error`,e):L.clear())}function tt(e){let t=T(M.report),n=d(M.report),r=G(e.id?be:ye,xe);r.classList.add(`hooks-editor`);let i=u(`form`,`hooks-form`);i.addEventListener(`submit`,e=>{e.preventDefault(),rt()}),i.addEventListener(`keydown`,e=>{e.key===`Escape`?(e.preventDefault(),nt()):e.key===`Enter`&&(e.ctrlKey||e.metaKey)&&(e.preventDefault(),rt())}),e.id||i.append(et(t));let a=u(`span`,`hooks-field-hint`,O(t,e.event)),o=Y(e.matcher,``,t=>{e.matcher=t}),s=J(`Command`,Xe(e.command,t=>{e.command=t}),`Runs through the shell with the event JSON on stdin. Exit 2 blocks the action where the event allows it.`),c=J(`URL`,Y(e.url,`http://127.0.0.1:8080/hook`,t=>{e.url=t}),`Claude Code POSTs the event JSON to it.`),l=()=>{s.hidden=e.type!==`command`,c.hidden=e.type!==`http`};l();let f=J(`Matcher`,o,null);f.append(a);let p=()=>{let n=t.find(t=>t.name===e.event);a.textContent=O(t,e.event),o.disabled=!!n&&!n.matcher,o.disabled&&(o.value=``,e.matcher=``)};p();let m=u(`input`,`settings-view-input hooks-timeout`);m.type=`number`,m.inputMode=`numeric`,m.min=`1`,m.max=String(E(M.report)),m.value=e.timeout,m.addEventListener(`input`,()=>{e.timeout=m.value});let h=u(`label`,`settings-view-toggle hooks-choice`),g=u(`input`,`settings-view-checkbox`);g.type=`checkbox`,g.checked=e.enabled,g.addEventListener(`change`,()=>{e.enabled=g.checked}),h.append(g,u(`span`,null,`Enabled`)),i.append(J(`Name`,Y(e.name,`Lint after edits`,t=>{e.name=t}),null),J(`Event`,Ze(e,t,t=>{e.event=t,p()}),null),f,J(`Type`,Qe(e,t=>{e.type=t,l()}),null),s,c,J(`Timeout (seconds)`,m,Ce),J(`Projects`,$e(e,n),null),J(``,h,null)),L=ee(`hooks-editor-status`);let _=u(`div`,`hooks-editor-footer`),v=u(`span`,`hooks-editor-shortcut`,pe),y=q(`btn-dialog btn-dialog-cancel`,`Cancel`,nt),b=u(`button`,`btn-dialog btn-dialog-confirm`,e.id?`Save changes`:`Add hook`);return b.type=`submit`,R=b,_.append(L.element,v,y,b),i.append(_),r.append(i),r}function Z(e,t=null){P=t||(e?A(e):k(T(M.report))),F=j(e?A(e):k(T(M.report))),I=tt(P),$({force:!0}),I.scrollIntoView({block:`nearest`});let n=I.querySelector(`input[type=text]`);n instanceof HTMLInputElement&&n.focus()}function Q(){P=null,F=null,I=null,L=null,R=null,z=!1,W=!0,$({force:!0})}function nt(){!P||!F||!Ge(P,F)?Q():h({title:de,message:fe,confirmLabel:`Discard`,danger:!0,onConfirm:Q})}async function rt(){if(!P||z)return;let e=Ue(P,T(M.report),E(M.report));if(e){X(e);return}let t=L,n=R;z=!0,t?.show(`busy`,`Saving the hook.`),n&&(n.disabled=!0);let r=await Je(`save-hook`,{hook:j(P)});z=!1,n&&(n.disabled=!1),t===L&&(r?X(r):(Q(),b()))}function it(e){let t=u(`details`,`hooks-preview`);t.open=V.has(e.id),t.addEventListener(`toggle`,()=>{t.open?V.add(e.id):V.delete(e.id)});let n=u(`summary`,`hooks-preview-summary`,ce);n.title=le;let r=u(`pre`,`hooks-preview-code`,Pe(e));return t.append(n,r),t}function at(e,{grouped:t=!1}={}){let n=d(M.report),r=u(`article`,`hooks-row`);r.setAttribute(`aria-label`,e.name),e.enabled===!1&&(r.dataset.state=`off`);let i=u(`div`,`hooks-row-main`),a=u(`div`,`hooks-row-head`);a.append(u(`span`,`hooks-row-name`,e.name));let o=t?e.matcher||``:Be(e);o&&a.append(u(`span`,`hooks-row-event`,o));let s=u(`code`,`hooks-row-target`,Ie(e));s.title=Ie(e);let c=u(`p`,`hooks-row-meta`,[Le(e.type),Re(e),ze(e,n)].filter(Boolean).join(` / `));i.append(a,s,c);let l=He(e,n);l.length>0&&i.append(K(`hooks-row-meta`,`Scoped to a project no longer in config: ${l.join(`, `)}`,`warn`)),i.append(it(e));let f=U.get(e.id);if(f){let e=ee(`hooks-row-status`);e.show(f.tone,f.text),i.append(e.element)}let p=u(`div`,`hooks-row-actions`),m=u(`label`,`settings-view-toggle hooks-choice`),g=u(`input`,`settings-view-checkbox`);g.type=`checkbox`,g.checked=e.enabled!==!1,g.disabled=H.has(e.id),g.setAttribute(`aria-label`,`${e.name} enabled`),g.addEventListener(`change`,()=>{Ye(e.id,`save-hook`,{hook:Ke(e)},g.checked?`Turning the hook on.`:`Turning the hook off.`)}),m.append(g,u(`span`,null,`On`));let _=q(`hooks-btn`,`Edit`,()=>Z(e),`Edit ${e.name}`),v=q(`hooks-btn`,ue,()=>{let t=A({...e,name:Fe(e.name)});t.id=null,Z(null,t)},`Duplicate ${e.name}`),y=q(`hooks-btn hooks-btn-danger`,`Delete`,()=>{h({title:`Delete hook`,message:qe(e),confirmLabel:`Delete`,danger:!0,onConfirm:()=>{Ye(e.id,`delete-hook`,{id:e.id},`Deleting the hook.`)}})},`Delete ${e.name}`);return y.disabled=H.has(e.id),p.append(m,_,v,y),r.append(i,p),r}function ot(e){let t=u(`article`,`hooks-row hooks-row-builtin`),n=u(`div`,`hooks-row-main`);return n.append(u(`span`,`hooks-row-event`,Ve(e)),u(`p`,`hooks-row-meta`,e.purpose)),t.append(n),t}function st(){let e=G(`Hooks`,ne),t=u(`div`,`hooks-stats`);for(let e of ke(M.report))t.append(f(`hooks`,e.label,e.value,e.tone));return e.append(t,K(`hooks-meta`,he)),e}function ct(){let e=u(`input`,`settings-view-input hooks-filter`);return e.type=`search`,e.value=B,e.placeholder=oe,e.setAttribute(`aria-label`,oe),e.addEventListener(`input`,()=>{B=e.value;let t=N?.querySelector(`.hooks-list-yours`);t&&t.replaceWith(ut())}),e}function lt(){let e=u(`div`,`hooks-empty-state`);return e.append(K(`hooks-empty`,ie),et(T(M.report))),e}function ut(){let e=u(`div`,`hooks-list-yours`),t=C(M.report);if(t.length===0)return e.append(lt()),e;let n=je(Ae(t,T(M.report)),B);if(n.length===0)return e.append(K(`hooks-empty`,se)),e;for(let t of Ne(n)){let n=u(`div`,`hooks-group`);n.append(u(`h3`,`hooks-group-title`,t.event));let r=u(`div`,`hooks-list`);for(let e of t.hooks)r.append(at(e,{grouped:!0}));n.append(r),e.append(n)}return e}function dt(){let e=G(ve,null),t=q(`hooks-btn hooks-btn-add`,`+ New hook`,()=>Z(null));t.disabled=!!P;let n=e.querySelector(`.hooks-section-head`);return n&&n.append(t),Me(C(M.report))&&e.append(ct()),e.append(ut()),e}function ft(){let e=u(`details`,`hooks-builtin`),t=u(`summary`,`hooks-builtin-summary`);t.append(u(`span`,`hooks-section-title`,`${ge} (${w(M.report).length})`),u(`span`,`hooks-section-hint`,_e));let n=u(`div`,`hooks-list`);for(let e of w(M.report))n.append(ot(e));return e.append(t,n),e}function pt(){let e=u(`div`,`hooks-content`);return M.report?De(M.report)?(e.append(K(`hooks-warning`,Oe(M.report))),e):(e.append(st()),I&&e.append(I),e.append(dt(),ft()),e):(e.append(M.hasReportSendFailed?K(`hooks-warning`,c):K(`hooks-empty`,re)),e)}function $({force:e=!1}={}){if(!N||!e&&p(N)||(M=y(),N.replaceChildren(pt()),!W))return;W=!1;let t=N.querySelector(`.hooks-btn-add`);t instanceof HTMLButtonElement&&t.focus()}function mt(e){N||(N=u(`div`,`hooks-panel`),e.append(N),_(()=>$()),$({force:!0}))}function ht(e){e===`shown`&&$({force:!0}),b()}var gt={mount:mt,refresh:ht};export{gt as view};