glimmervoid 0.38.2 → 0.39.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (37) hide show
  1. package/dist/bin/glimmervoid.js +23 -29
  2. package/dist/chunks/{adapters-CAHxZYT3.js → adapters-B9tP9MXC.js} +26 -14
  3. package/dist/chunks/{adapters-DDjC7_vG.js → adapters-Buu6yI71.js} +1 -1
  4. package/dist/chunks/{agent-api-cli-B5Tm0wXO.js → agent-api-cli-2_RwTTTJ.js} +4 -66
  5. package/dist/chunks/{agent-api-cli-BDu1CxZf.js → agent-api-cli-PfCov-qb.js} +1 -1
  6. package/dist/chunks/agent-api-core-D2HLgBEe.js +180 -0
  7. package/dist/chunks/{agent-setup-cli-DmMfCw5O.js → agent-setup-cli-C1nFdgFg.js} +2 -2
  8. package/dist/chunks/config-store-8Z9vkWvf.js +1 -0
  9. package/dist/chunks/{config-store-BUNZs4j7.js → config-store-n23JDU4E.js} +63 -268
  10. package/dist/chunks/{contracts-HVCEJfxs.js → contracts-DYQW11de.js} +1018 -171
  11. package/dist/chunks/{git-version-rWZjF2Px.js → git-version-DXozXVnb.js} +2 -2
  12. package/dist/chunks/{grok-B6bsCgdd.js → grok-DeGAXgZF.js} +7 -8
  13. package/dist/chunks/{guardrails-deps-Cb-ki4EU.js → guardrails-deps-CLxK4J-g.js} +1 -1
  14. package/dist/chunks/{json-file-CIJf0Cel.js → json-file-DFCTvPjj.js} +3 -7
  15. package/dist/chunks/{main-BNSbP-Yk.js → main-D4uwk-_M.js} +16436 -21253
  16. package/dist/chunks/{pair-cli-DNp8i5L4.js → pair-cli-D9DZBqk0.js} +2 -2
  17. package/dist/chunks/{remote-config-C_s2pnLC.js → remote-config-DiLwnzBq.js} +2 -2
  18. package/dist/chunks/{session-BlT68ppa.js → session-D2EbiysG.js} +20 -32
  19. package/dist/chunks/{session-routes-CT1JrjoT.js → session-routes-BQAZzMKZ.js} +3 -8
  20. package/dist/chunks/{settings-cli-BbzxCyG5.js → settings-cli-DP4t-I9U.js} +3 -3
  21. package/dist/chunks/{ssh-sign-cli-C74BGTQS.js → ssh-sign-cli-D2RIs-iN.js} +2 -2
  22. package/dist/client/assets/index-C0YUJwjz.css +2 -0
  23. package/dist/client/assets/index-w8lG-tk2.js +148 -0
  24. package/dist/client/assets/xterm-kR64YvZ-.js +79 -0
  25. package/dist/client/assets/zod-BRLv4KqJ.js +55 -0
  26. package/dist/client/index.html +5 -2
  27. package/dist/scripts/postinstall-path-check.js +21 -3
  28. package/dist/server/index.js +1 -1
  29. package/package.json +2 -3
  30. package/dist/chunks/agent-api-core-B_mUSenR.js +0 -341
  31. package/dist/chunks/browser-config-BrBT8269.js +0 -762
  32. package/dist/chunks/config-CjawSOBk.js +0 -219
  33. package/dist/chunks/config-store-MAVQhGMh.js +0 -1
  34. package/dist/chunks/factory-D7ryES9n.js +0 -240
  35. package/dist/chunks/knowledge-graph-cli-ByUJoKw_.js +0 -1354
  36. package/dist/client/assets/index-B5uVtedd.css +0 -1
  37. package/dist/client/assets/index-b13-NGGS.js +0 -275
@@ -2,10 +2,8 @@ import { n as errorLabel, r as errorMessage } from "./text-DoirglWV.js";
2
2
  import { n as equalsIgnoringCaseOnWindows } from "./paths-Bu4eH1Yd.js";
3
3
  import { n as glimmervoidHomeDir$1, t as decideConfigPath } from "./config-path-core-DFt-TemS.js";
4
4
  import { n as isRecord } from "./coerce-NSst8oRP.js";
5
- import { A as FLYING_ANIMALS_DURATION_RANGE, B as POSTHOG_TRAFFIC_MIN_USERS_RANGE, D as CHANGE_MAP_NARRATOR_TIMEOUT_RANGE, E as normalizeLegacyConfigNumbers, F as NON_NEGATIVE_NUMBER_RANGE, G as USAGE_INTEGER_RANGES, H as REPLAY_BUFFER_KB_RANGE, I as PORT_RANGE, J as WORKFLOWS_MAX_ACTIONS_PER_POLL_RANGE, K as USAGE_RETAIN_DAYS_RANGE, L as POSITIVE_NUMBER_RANGE, M as FLYING_ANIMALS_SCALE_RANGE, N as KEEP_MERGEABLE_TIMEOUT_MINUTES_RANGE, O as FACTORY_MAX_LIVE_WORKERS_RANGE, P as MEMORY_RESERVE_MB_RANGE, R as POSTHOG_FIX_TIMEOUT_RANGE, U as TASK_TITLE_TIMEOUT_RANGE, V as POSTHOG_TRAFFIC_MULTIPLIER_RANGE, W as USAGE_BUDGET_RANGE, Y as WORKFLOWS_MAX_CONCURRENT_SESSIONS_RANGE, a as DEFAULT_FACTORY_CHECKS, j as FLYING_ANIMALS_GAP_RANGE, k as FLYING_ANIMALS_DEFAULTS, m as UPDATE_CHANNELS, n as BranchGcFileSettings, o as DEFAULT_FACTORY_PROTECTED_PATHS, q as USAGE_SCAN_INTERVAL_RANGE, r as CHANGE_MAP_NARRATOR_ENGINES, u as POST_TURN_CHECK_MODES, w as USAGE_COST_MODES, z as POSTHOG_TRAFFIC_BASELINE_RANGE } from "./browser-config-BrBT8269.js";
6
- import { b as DEFAULT_CHECK_MEMORY_RESERVE_MB, d as writeJsonAtomicSync, f as writeTextAtomic, p as writeTextAtomicSync } from "./json-file-CIJf0Cel.js";
7
- import { c as RUNTIME_CONFIG_SCALAR_KEYS, i as Config, n as BUILTIN_AGENT_IDS, t as AGENT_ID_SHAPE_MESSAGE, u as configIssueMessage } from "./config-CjawSOBk.js";
8
- import { K as TELEMETRY_KILL_SWITCH_FLAG, U as FeatureFlagsResponse } from "./contracts-HVCEJfxs.js";
5
+ import { d as writeJsonAtomicSync, f as writeTextAtomic, p as writeTextAtomicSync } from "./json-file-DFCTvPjj.js";
6
+ import { $ as Config, At as POSTHOG_TRAFFIC_MULTIPLIER_RANGE, Ct as MEMORY_RESERVE_MB_RANGE, Dt as POSTHOG_FIX_TIMEOUT_RANGE, Et as POSITIVE_NUMBER_RANGE, Ft as USAGE_RETAIN_DAYS_RANGE, G as FeatureFlagsResponse, It as USAGE_SCAN_INTERVAL_RANGE, J as TELEMETRY_KILL_SWITCH_FLAG, Lt as WORKFLOWS_MAX_ACTIONS_PER_POLL_RANGE, Mt as TASK_TITLE_TIMEOUT_RANGE, Nt as USAGE_BUDGET_RANGE, Ot as POSTHOG_TRAFFIC_BASELINE_RANGE, Pt as USAGE_INTEGER_RANGES, Rt as WORKFLOWS_MAX_CONCURRENT_SESSIONS_RANGE, St as KEEP_MERGEABLE_TIMEOUT_MINUTES_RANGE, Tt as PORT_RANGE, X as AGENT_ID_SHAPE_MESSAGE, Z as BUILTIN_AGENT_IDS, _t as CHANGE_MAP_NARRATOR_TIMEOUT_RANGE, at as BranchGcFileSettings, bt as FLYING_ANIMALS_GAP_RANGE, ct as UPDATE_CHANNELS, gt as normalizeLegacyConfigNumbers, it as configIssueMessage, jt as REPLAY_BUFFER_KB_RANGE, kt as POSTHOG_TRAFFIC_MIN_USERS_RANGE, mt as USAGE_COST_MODES, nt as RUNTIME_CONFIG_SCALAR_KEYS, ot as CHANGE_MAP_NARRATOR_ENGINES, st as POST_TURN_CHECK_MODES, vt as FLYING_ANIMALS_DEFAULTS, wt as NON_NEGATIVE_NUMBER_RANGE, xt as FLYING_ANIMALS_SCALE_RANGE, yt as FLYING_ANIMALS_DURATION_RANGE } from "./contracts-DYQW11de.js";
9
7
  import fs from "node:fs";
10
8
  import path from "node:path";
11
9
  import os from "node:os";
@@ -574,15 +572,6 @@ function decideIsDevInstall({ installFlavor, isBundled, homeDir, defaultHomeDir
574
572
  if (installFlavor === "clone" || !isBundled) return true;
575
573
  return comparablePath(homeDir) !== comparablePath(defaultHomeDir);
576
574
  }
577
- function buildFactoryDecisionEvent(decision) {
578
- return {
579
- kind: decision.kind,
580
- outcome: decision.outcome,
581
- failure_class: decision.failureClass,
582
- duration_ms: decision.durationMs,
583
- attempt: decision.attempt
584
- };
585
- }
586
575
  function nodeMajorVersion(nodeVersion) {
587
576
  const major = Number.parseInt(nodeVersion.replace(/^v/, ""), 10);
588
577
  return Number.isFinite(major) ? major : 0;
@@ -632,10 +621,6 @@ var SESSIONS = {
632
621
  label: "sessions",
633
622
  storedPerDisplay: 1
634
623
  };
635
- var WORKERS = {
636
- label: "workers",
637
- storedPerDisplay: 1
638
- };
639
624
  var RECURRENCES = {
640
625
  label: "recurrences",
641
626
  storedPerDisplay: 1
@@ -711,7 +696,6 @@ var DIAGNOSTIC = "A diagnostic switch kept out of the Settings view; change it i
711
696
  var PROCESS_SETTING = "Changes how the server process or its worktrees behave, so it is set in config.json with a restart or new sessions in mind.";
712
697
  var STRUCTURED_VALUE = "A structured value with no dashboard control; edit it in config.json.";
713
698
  var BY_RULE = "Never editable from the dashboard by rule; edit it in config.json.";
714
- var LANES_SECTION_ID = "lanes";
715
699
  function capitalizedOptions(values) {
716
700
  return values.map((value) => ({
717
701
  value,
@@ -755,20 +739,6 @@ var SECTIONS = Object.freeze([
755
739
  defaultValue: "phyrexian",
756
740
  ...BROWSER_NOW
757
741
  },
758
- {
759
- id: "compact-status",
760
- path: "pref:compactStatusLabels",
761
- title: "Hide status words in sidebar",
762
- description: "Hide status words in the sidebar and on the phone Board while keeping the colored status mark and the phone Plan ready badge.",
763
- control: "toggle",
764
- keywords: [
765
- "sidebar",
766
- "status",
767
- "compact"
768
- ],
769
- defaultValue: false,
770
- ...BROWSER_NOW
771
- },
772
742
  {
773
743
  id: "session-usage-chips",
774
744
  path: "pref:sessionUsageChips",
@@ -785,6 +755,23 @@ var SECTIONS = Object.freeze([
785
755
  defaultValue: false,
786
756
  ...BROWSER_NOW
787
757
  },
758
+ {
759
+ id: "phone-arrow-pad",
760
+ path: "pref:phoneArrowPad",
761
+ title: "Swipe arrow pad on phone (experimental)",
762
+ description: "Replace the four arrow keys above the phone keyboard with one pad: swipe on it to send arrow keys, one per short drag.",
763
+ control: "toggle",
764
+ keywords: [
765
+ "experimental",
766
+ "mobile",
767
+ "keys",
768
+ "arrows",
769
+ "swipe",
770
+ "gesture"
771
+ ],
772
+ defaultValue: false,
773
+ ...BROWSER_NOW
774
+ },
788
775
  {
789
776
  id: "flying-animals",
790
777
  path: "pref:flyingAnimalsEnabled",
@@ -955,7 +942,7 @@ var SECTIONS = Object.freeze([
955
942
  id: "telegram-bot-token",
956
943
  path: "telegram.botToken",
957
944
  title: "Bot token",
958
- description: "Credential used by the shared Telegram bot. When GLIMMERVOID_TELEGRAM_BOT_TOKEN supplies it, this field is read-only.",
945
+ description: "Credential used by the shared Telegram bot. Create a bot by messaging @BotFather in Telegram and sending /newbot; it replies with this token. When GLIMMERVOID_TELEGRAM_BOT_TOKEN supplies it, this field is read-only.",
959
946
  control: "password",
960
947
  keywords: ["credential", "api"],
961
948
  defaultValue: "",
@@ -965,7 +952,7 @@ var SECTIONS = Object.freeze([
965
952
  id: "telegram-chat-id",
966
953
  path: "telegram.chatId",
967
954
  title: "Chat id",
968
- description: "Destination chat for enabled Telegram lanes.",
955
+ description: "Destination chat for enabled Telegram lanes. Send your bot any message, then open https://api.telegram.org/bot<token>/getUpdates in a browser and copy the number under message.chat.id.",
969
956
  control: "text",
970
957
  keywords: ["destination", "channel"],
971
958
  defaultValue: "",
@@ -977,8 +964,13 @@ var SECTIONS = Object.freeze([
977
964
  title: "Send session notifications",
978
965
  description: "Send session completion, input and failure alerts when no dashboard is open. Unacknowledged alerts also escalate after the phone escalation delay while a dashboard remains open.",
979
966
  control: "toggle",
980
- keywords: ["phone", "off dashboard"],
967
+ keywords: [
968
+ "phone",
969
+ "off dashboard",
970
+ "test"
971
+ ],
981
972
  defaultValue: false,
973
+ status: "telegram-delivery",
982
974
  ...MACHINE_NOW
983
975
  }
984
976
  ]
@@ -1312,20 +1304,13 @@ var SECTIONS = Object.freeze([
1312
1304
  }
1313
1305
  ]
1314
1306
  },
1315
- {
1316
- id: LANES_SECTION_ID,
1317
- level: "lanes",
1318
- title: "Lanes",
1319
- description: "The background work Glimmervoid runs for you, one sub-section per lane.",
1320
- settings: []
1321
- },
1322
1307
  {
1323
1308
  id: "lanes-visions",
1324
1309
  level: "lanes",
1325
- parent: LANES_SECTION_ID,
1326
1310
  title: "Visions",
1327
1311
  description: "Editor-buffer findings, bounded model comments, and the machine-context ingest behind them.",
1328
1312
  legacyIds: [
1313
+ "lanes",
1329
1314
  "visions",
1330
1315
  "lanes-ingest",
1331
1316
  "ingest"
@@ -1418,7 +1403,6 @@ var SECTIONS = Object.freeze([
1418
1403
  {
1419
1404
  id: "lanes-posthog",
1420
1405
  level: "lanes",
1421
- parent: LANES_SECTION_ID,
1422
1406
  title: "PostHog",
1423
1407
  description: "Error monitoring, investigations and traffic-spike alerts.",
1424
1408
  legacyIds: ["posthog"],
@@ -1531,7 +1515,6 @@ var SECTIONS = Object.freeze([
1531
1515
  {
1532
1516
  id: "lanes-team-review",
1533
1517
  level: "lanes",
1534
- parent: LANES_SECTION_ID,
1535
1518
  title: "Team review",
1536
1519
  description: "Draft reviews of teammates' pull requests for you to post from the Reviews tab.",
1537
1520
  legacyIds: ["team-review", "reviews"],
@@ -1666,7 +1649,6 @@ var SECTIONS = Object.freeze([
1666
1649
  {
1667
1650
  id: "lanes-workflows",
1668
1651
  level: "lanes",
1669
- parent: LANES_SECTION_ID,
1670
1652
  title: "Workflows",
1671
1653
  description: "Rules that act on pull request events in the repositories you choose.",
1672
1654
  legacyIds: ["workflows"],
@@ -1714,156 +1696,9 @@ var SECTIONS = Object.freeze([
1714
1696
  }
1715
1697
  ]
1716
1698
  },
1717
- {
1718
- id: "lanes-factory",
1719
- level: "lanes",
1720
- parent: LANES_SECTION_ID,
1721
- title: "Factory",
1722
- description: "Read Coherence reports from repositories whose integration branch holds a coherence.config.json and show their status in the Factory tab.",
1723
- legacyIds: ["factory"],
1724
- settings: [
1725
- {
1726
- id: "factory-enabled",
1727
- path: "factory.enabled",
1728
- title: "Enable the factory",
1729
- description: "Enable Coherence status polling and show the Factory tab. Off by default.",
1730
- control: "toggle",
1731
- keywords: [
1732
- "orchestrator",
1733
- "intents",
1734
- "queue",
1735
- "coherence",
1736
- "guardrails"
1737
- ],
1738
- defaultValue: false,
1739
- ...MACHINE_NOW
1740
- },
1741
- {
1742
- id: "factory-max-risk",
1743
- path: "factory.maxRisk",
1744
- title: "Worker risk ceiling",
1745
- description: "Highest risk admitted for a ticket.",
1746
- control: "select",
1747
- defaultValue: "medium",
1748
- options: [
1749
- "low",
1750
- "medium",
1751
- "high",
1752
- "critical"
1753
- ].map((value) => ({
1754
- value,
1755
- label: value
1756
- })),
1757
- keywords: ["risk", "admission"],
1758
- ...MACHINE_NOW
1759
- },
1760
- {
1761
- id: "factory-max-live-workers",
1762
- path: "factory.maxLiveWorkers",
1763
- title: "Live worker cap",
1764
- description: "Most live workers per factory project.",
1765
- control: "number",
1766
- range: FACTORY_MAX_LIVE_WORKERS_RANGE,
1767
- unit: WORKERS,
1768
- defaultValue: 2,
1769
- keywords: ["workers", "parallel"],
1770
- ...MACHINE_NOW
1771
- },
1772
- {
1773
- id: "factory-checks",
1774
- path: "factory.checks",
1775
- title: "Worker checks",
1776
- description: "Commands glimmervoid runs before merging worker commits.",
1777
- control: "list",
1778
- defaultValue: [
1779
- "npm run typecheck",
1780
- "npm run lint",
1781
- "npm test"
1782
- ],
1783
- keywords: ["tests", "checks"],
1784
- listPlaceholder: "npm test",
1785
- listEmptyText: "No checks run before a merge.",
1786
- ...MACHINE_NOW
1787
- },
1788
- {
1789
- id: "factory-protected-paths",
1790
- path: "factory.protectedPaths",
1791
- title: "Protected paths",
1792
- description: "Repo-relative files, directory prefixes ending in /, or **/NAME basenames workers cannot change.",
1793
- control: "list",
1794
- defaultValue: [
1795
- "coherence.config.json",
1796
- ".coherence/",
1797
- "package.json",
1798
- "package-lock.json",
1799
- "**/AGENTS.md",
1800
- "**/CLAUDE.md",
1801
- "**/CLAUDE.local.md",
1802
- ".claude/",
1803
- ".github/"
1804
- ],
1805
- keywords: ["fence", "scope"],
1806
- listPlaceholder: "path, prefix/ or **/NAME",
1807
- listEmptyText: "Workers may change any path.",
1808
- ...MACHINE_NOW
1809
- },
1810
- {
1811
- id: "factory-reviewer-model",
1812
- path: "factory.reviewerModel",
1813
- title: "Reviewer model",
1814
- description: "Claude model for independent worker review. Blank uses the CLI default.",
1815
- control: "text",
1816
- defaultValue: null,
1817
- nullable: true,
1818
- keywords: ["claude", "review"],
1819
- ...MACHINE_NOW
1820
- },
1821
- {
1822
- id: "factory-daily-budget",
1823
- path: "factory.dailyBudgetUsd",
1824
- title: "Factory daily budget",
1825
- description: "Factory lane spend ceiling. Blank means no ceiling. Needs usage tracking: with it off, dispatch refuses.",
1826
- control: "number",
1827
- range: NON_NEGATIVE_NUMBER_RANGE,
1828
- unit: USD,
1829
- integer: false,
1830
- nullable: true,
1831
- step: .01,
1832
- defaultValue: null,
1833
- keywords: ["spend", "budget"],
1834
- ...MACHINE_NOW
1835
- },
1836
- {
1837
- id: "factory-verifier-model",
1838
- path: "factory.verifierModel",
1839
- title: "Verifier model",
1840
- description: "Claude model for independent intent verification. Blank uses the CLI default.",
1841
- control: "text",
1842
- nullable: true,
1843
- defaultValue: null,
1844
- keywords: ["claude", "verification"],
1845
- ...MACHINE_NOW
1846
- },
1847
- {
1848
- id: "factory-mirror-harness-runs",
1849
- path: "factory.mirrorHarnessRuns",
1850
- title: "Mirror harness runs",
1851
- description: "Show the latest factory harness run as a read-only project in the Factory tab while it runs and for a day after. Needs factory.enabled on. The harness turns it off on the instance it boots.",
1852
- control: "toggle",
1853
- defaultValue: true,
1854
- keywords: [
1855
- "harness",
1856
- "test",
1857
- "read-only"
1858
- ],
1859
- ...MACHINE_NOW
1860
- }
1861
- ]
1862
- },
1863
1699
  {
1864
1700
  id: "lanes-benchmarks",
1865
1701
  level: "lanes",
1866
- parent: LANES_SECTION_ID,
1867
1702
  title: "Benchmarks",
1868
1703
  description: "Compare agent setups on frozen cases from the suites in the benchmarks folder of the Glimmervoid home.",
1869
1704
  legacyIds: ["benchmarks"],
@@ -1884,25 +1719,21 @@ var SECTIONS = Object.freeze([
1884
1719
  }]
1885
1720
  },
1886
1721
  {
1887
- id: "lanes-knowledge-graph",
1722
+ id: "lanes-coherence",
1888
1723
  level: "lanes",
1889
- parent: LANES_SECTION_ID,
1890
- title: "Knowledge graph (experimental)",
1891
- description: "A typed local graph of projects, tasks, notes, references and questions, driven from the glimmervoid kg command. Its SQLite database defaults to the Glimmervoid home; --db selects another path.",
1892
- legacyIds: ["knowledge-graph"],
1724
+ title: "Coherence (experimental)",
1725
+ description: "Per-session Coherence hook status and decision journal for agent sessions.",
1893
1726
  settings: [{
1894
- id: "knowledge-graph-enabled",
1895
- path: "knowledgeGraph.enabled",
1896
- title: "Enable the knowledge graph",
1897
- description: "Allow the glimmervoid kg command. It reads Coherence ledgers to report where your tasks and the agents' tickets disagree, without modifying those ledgers. Graph writes go to the selected SQLite database, which can be inside a repository when --db names that path. Off by default.",
1727
+ id: "coherence-enabled",
1728
+ path: "coherence.enabled",
1729
+ title: "Show session Coherence",
1730
+ description: "Shows each session's Coherence hook status and decision journal when the repository installed @posthog/coherence 1.8 or newer. Off by default.",
1898
1731
  control: "toggle",
1899
1732
  keywords: [
1900
1733
  "experimental",
1901
- "kg",
1902
- "tasks",
1903
- "notes",
1904
- "references",
1905
- "coherence"
1734
+ "coherence",
1735
+ "journal",
1736
+ "decisions"
1906
1737
  ],
1907
1738
  defaultValue: false,
1908
1739
  ...MACHINE_NOW
@@ -1911,7 +1742,6 @@ var SECTIONS = Object.freeze([
1911
1742
  {
1912
1743
  id: "lanes-change-map",
1913
1744
  level: "lanes",
1914
- parent: LANES_SECTION_ID,
1915
1745
  title: "Change map",
1916
1746
  description: "Optional model narration for deterministic change facts.",
1917
1747
  legacyIds: ["change-map"],
@@ -1963,7 +1793,7 @@ var SECTIONS = Object.freeze([
1963
1793
  id: "telemetry-enabled",
1964
1794
  path: "telemetry.enabled",
1965
1795
  title: "Send anonymous usage and error data",
1966
- description: "Version, platform, app starts, daily activity, session starts and ends with agent kind, exit kind and duration, errors as their type, error code and scrubbed stack frames, per session token counts, models and estimated costs from the usage scan, and factory outcomes as the kind of decision, how it came out, its duration and attempt number, under a random install id. Never error messages, paths, repository or branch names, prompts, objectives or terminal output. GLIMMERVOID_TELEMETRY=0, DO_NOT_TRACK=1 or CI=true turn it off regardless.",
1796
+ description: "Version, platform, app starts, daily activity, session starts and ends with agent kind, exit kind and duration, errors as their type, error code and scrubbed stack frames, per session token counts, models and estimated costs from the usage scan, under a random install id. Never error messages, paths, repository or branch names, prompts, objectives or terminal output. GLIMMERVOID_TELEMETRY=0, DO_NOT_TRACK=1 or CI=true turn it off regardless.",
1967
1797
  control: "toggle",
1968
1798
  keywords: [
1969
1799
  "telemetry",
@@ -2034,24 +1864,6 @@ var FILE_ONLY_SETTINGS = Object.freeze([
2034
1864
  fileOnlyReason: TUNING_KNOB,
2035
1865
  ...FILE_ONLY
2036
1866
  },
2037
- {
2038
- id: "file-check-memory-reserve",
2039
- path: "checkMemoryReserveMB",
2040
- title: "Check run memory reserve",
2041
- group: "machine-sessions",
2042
- description: "Free memory a factory check run waits for; 0 runs checks without checking.",
2043
- control: "number",
2044
- range: MEMORY_RESERVE_MB_RANGE,
2045
- unit: {
2046
- label: "MB",
2047
- storedPerDisplay: 1
2048
- },
2049
- keywords: ["memory", "factory"],
2050
- defaultValue: 1500,
2051
- takesEffect: "now",
2052
- fileOnlyReason: TUNING_KNOB,
2053
- ...FILE_ONLY
2054
- },
2055
1867
  {
2056
1868
  id: "file-cursor-blink",
2057
1869
  path: "cursorBlink",
@@ -3544,7 +3356,6 @@ var DEFAULT_CONFIG = {
3544
3356
  detectScheduledWakeups: true,
3545
3357
  replayBufferKB: 512,
3546
3358
  sessionMemoryReserveMB: 600,
3547
- checkMemoryReserveMB: DEFAULT_CHECK_MEMORY_RESERVE_MB,
3548
3359
  recordSignals: true,
3549
3360
  trace: { enabled: true },
3550
3361
  planReview: { enabled: true },
@@ -3560,17 +3371,6 @@ var DEFAULT_CONFIG = {
3560
3371
  model: "",
3561
3372
  timeoutSeconds: 90
3562
3373
  } },
3563
- factory: {
3564
- enabled: false,
3565
- maxRisk: "medium",
3566
- maxLiveWorkers: 2,
3567
- checks: DEFAULT_FACTORY_CHECKS,
3568
- protectedPaths: DEFAULT_FACTORY_PROTECTED_PATHS,
3569
- reviewerModel: null,
3570
- dailyBudgetUsd: null,
3571
- verifierModel: null,
3572
- mirrorHarnessRuns: true
3573
- },
3574
3374
  guardrails: {
3575
3375
  unguardedRepos: [],
3576
3376
  blockedPaths: [],
@@ -3649,7 +3449,7 @@ function resolveConfigPath() {
3649
3449
  }, (candidate) => fs.existsSync(candidate));
3650
3450
  if (decided.path) return decided.path;
3651
3451
  if (decided.source === "env") {
3652
- console.error(`Config file not found: ${decided.envPath}`);
3452
+ console.error(`Config file not found: ${decided.envPath}, the path GLIMMERVOID_CONFIG names. Create that file, or unset GLIMMERVOID_CONFIG to use ${decided.homePath}.`);
3653
3453
  process.exit(1);
3654
3454
  }
3655
3455
  const homeConfig = decided.homePath;
@@ -3795,11 +3595,14 @@ function isSuspectedExternalWipe(candidate, currentConfig) {
3795
3595
  branchGc: resolveBranchGc(candidate.branchGc)
3796
3596
  }) * 2 < currentKeyCount;
3797
3597
  }
3798
- function warnInvalidConfig(action, validation) {
3799
- console.warn(`[config] Refusing to ${action}; validation failed: ${validation.errors.join("; ")}. Recovery sources: config.json.bak and config.json.boot.bak.`);
3598
+ function invalidConfigWarning(action, validation) {
3599
+ return `[config] Refusing to ${action}; validation failed: ${validation.errors.join("; ")}. Recovery sources: config.json.bak and config.json.boot.bak.`;
3600
+ }
3601
+ function suspectedWipeWarning(action) {
3602
+ return `[config] Refusing to ${action}; config.json has fewer than half the top-level keys of the in-memory config. This looks like an external wipe. Recovery sources: config.json.bak and config.json.boot.bak.`;
3800
3603
  }
3801
3604
  function warnSuspectedWipe(action) {
3802
- console.warn(`[config] Refusing to ${action}; config.json has fewer than half the top-level keys of the in-memory config. This looks like an external wipe. Recovery sources: config.json.bak and config.json.boot.bak.`);
3605
+ console.warn(suspectedWipeWarning(action));
3803
3606
  }
3804
3607
  function ensureProjectIds(projects) {
3805
3608
  let changed = false;
@@ -3879,36 +3682,30 @@ function createConfigStore({ settingsDefaults } = {}) {
3879
3682
  let synchronousWriteRevision = 0;
3880
3683
  let lastSynchronousContent = null;
3881
3684
  let pendingSaves = Promise.resolve();
3685
+ let lastSaveFailureReason = null;
3686
+ function refuseSave(warning, operatorReason = warning.replace(/^\[config\] /, "")) {
3687
+ console.warn(warning);
3688
+ lastSaveFailureReason = operatorReason;
3689
+ return null;
3690
+ }
3882
3691
  function prepareSave(freshConfig, mutatorFn) {
3883
3692
  const freshValidation = validateConfig(freshConfig);
3884
- if (!freshValidation.ok) {
3885
- warnInvalidConfig("save config.json", freshValidation);
3886
- return null;
3887
- }
3888
- if (isSuspectedExternalWipe(freshConfig, config)) {
3889
- warnSuspectedWipe("save config.json");
3890
- return null;
3891
- }
3693
+ if (!freshValidation.ok) return refuseSave(invalidConfigWarning("save config.json", freshValidation));
3694
+ if (isSuspectedExternalWipe(freshConfig, config)) return refuseSave(suspectedWipeWarning("save config.json"));
3892
3695
  if (mutatorFn(freshConfig) === "abort-config-save") return null;
3893
3696
  const mutatedValidation = validateConfig(withEnvSecrets(freshConfig, envSecrets));
3894
- if (!mutatedValidation.ok) {
3895
- warnInvalidConfig("save config.json", mutatedValidation);
3896
- return null;
3897
- }
3697
+ if (!mutatedValidation.ok) return refuseSave(invalidConfigWarning("save config.json", mutatedValidation));
3898
3698
  return mutatedValidation.config;
3899
3699
  }
3900
3700
  function save(mutatorFn) {
3701
+ lastSaveFailureReason = null;
3901
3702
  let loaded;
3902
3703
  try {
3903
3704
  loaded = loadConfigFile(configPath, { exitOnError: false });
3904
3705
  } catch (err) {
3905
- console.warn("[config] Failed to read config.json for save:", errorLabel(err));
3906
- return null;
3907
- }
3908
- if ("error" in loaded) {
3909
- console.warn(loaded.message);
3910
- return null;
3706
+ return refuseSave(`[config] Failed to read config.json for save: ${errorLabel(err)}`);
3911
3707
  }
3708
+ if ("error" in loaded) return refuseSave(loaded.message, `${configPath} could not be read as a config file. The broken file was copied to ${loaded.invalidBackupPath} when possible. Fix it, or restore from ${configPath}.bak, then save again.`);
3912
3709
  const freshConfig = loaded.config;
3913
3710
  const freshContent = loaded.loadedContent;
3914
3711
  const effectiveConfig = prepareSave(freshConfig, mutatorFn);
@@ -3922,8 +3719,7 @@ function createConfigStore({ settingsDefaults } = {}) {
3922
3719
  lastSynchronousContent = nextContent;
3923
3720
  synchronousWriteRevision++;
3924
3721
  } catch (err) {
3925
- console.warn("[config] Failed to write config.json:", errorLabel(err));
3926
- return null;
3722
+ return refuseSave(`[config] Failed to write config.json: ${errorLabel(err)}`);
3927
3723
  }
3928
3724
  return effectiveConfig;
3929
3725
  }
@@ -4028,8 +3824,7 @@ function createConfigStore({ settingsDefaults } = {}) {
4028
3824
  github: pickBlock("github", config.github),
4029
3825
  teamReview: pickBlock("teamReview", config.teamReview),
4030
3826
  benchmarks: pickBlock("benchmarks", config.benchmarks),
4031
- factory: pickBlock("factory", config.factory),
4032
- knowledgeGraph: pickBlock("knowledgeGraph", config.knowledgeGraph),
3827
+ coherence: pickBlock("coherence", config.coherence),
4033
3828
  workflows: config.workflows ?? null,
4034
3829
  posthog: pickBlock("posthog", config.posthog),
4035
3830
  secretSources: secretSourcesOf(process.env),
@@ -4076,8 +3871,7 @@ function createConfigStore({ settingsDefaults } = {}) {
4076
3871
  if (newConfig.github != null) config.github = newConfig.github;
4077
3872
  if (newConfig.teamReview != null) config.teamReview = newConfig.teamReview;
4078
3873
  if (newConfig.benchmarks != null) config.benchmarks = newConfig.benchmarks;
4079
- if (newConfig.factory != null) config.factory = newConfig.factory;
4080
- if (newConfig.knowledgeGraph != null) config.knowledgeGraph = newConfig.knowledgeGraph;
3874
+ if (newConfig.coherence != null) config.coherence = newConfig.coherence;
4081
3875
  if (newConfig.posthog != null) config.posthog = newConfig.posthog;
4082
3876
  if (newConfig.usage != null) config.usage = newConfig.usage;
4083
3877
  if (newConfig.telegram != null) config.telegram = newConfig.telegram;
@@ -4147,6 +3941,7 @@ function createConfigStore({ settingsDefaults } = {}) {
4147
3941
  configPath,
4148
3942
  save,
4149
3943
  saveAsync,
3944
+ lastSaveFailureReason: () => lastSaveFailureReason,
4150
3945
  idle: () => pendingSaves,
4151
3946
  getSettings,
4152
3947
  applySettings,
@@ -4156,4 +3951,4 @@ function createConfigStore({ settingsDefaults } = {}) {
4156
3951
  };
4157
3952
  }
4158
3953
  //#endregion
4159
- export { withEnvSecrets as $, settingsOf as A, buildExceptionProperties as B, deleteValueAtPath as C, scoreSettingsSearch as D, parsePosthogProjectSelection as E, TELEMETRY_BATCH_URL as F, decideTelemetryConsent as G, classifySessionExit as H, TELEMETRY_FLAGS_URL as I, parsePosthogReleaseId as J, exceptionFingerprint as K, adapterBucket as L, FILE_ONLY_GROUPS as M, SETTINGS_REGISTRY as N, setValueAtPath as O, FIRST_RUN_NOTICE as P, stableConfigKey as Q, buildAiGenerationEvents as R, cloneValue as S, hasScaledUnit as T, decideIsDevInstall as U, buildFactoryDecisionEvent as V, decideRemoteTelemetryState as W, ENV_SECRET_BINDINGS as X, resolveProjectToken as Y, readEnvSecrets as Z, SECRET_PRESENCE_SUFFIX as _, generateProjectId as a, usablePrefixes as at, validateSettingsBlock as b, resolveConfigPath as c, comparableDirectoryPath as ct, assetForPlatform as d, DEFAULT_BRANCH_GC_PREFIXES as et, decideRtkInstall as f, verifyDigest as g, isRtkBinaryName as h, ensureProjectIds as i, sessionIdFromBranch as it, valueAtPath as j, settingsGroupOf as k, saveConfigFileOnce as l, isSameDirectoryPath as lt, installTargetPath as m, DEFAULT_CONFIG as n, planBranchGc as nt, glimmervoidHomeDir as o, worktreeIntegrationTips as ot, findEscapingArchiveMember as p, nodeMajorVersion as q, createConfigStore as r, planWorktreeGc as rt, loadConfigFile as s, canonicalizePath as st, ABORT_CONFIG_SAVE as t, matchedPrefix as tt, validateConfig as u, mergeSettingsBlock as v, displayText as w, SETTINGS_INDEX as x, settingsBlockSpecFor as y, buildBrowserExceptionProperties as z };
3954
+ export { DEFAULT_BRANCH_GC_PREFIXES as $, settingsOf as A, buildExceptionProperties as B, deleteValueAtPath as C, scoreSettingsSearch as D, parsePosthogProjectSelection as E, TELEMETRY_BATCH_URL as F, exceptionFingerprint as G, decideIsDevInstall as H, TELEMETRY_FLAGS_URL as I, resolveProjectToken as J, nodeMajorVersion as K, adapterBucket as L, FILE_ONLY_GROUPS as M, SETTINGS_REGISTRY as N, setValueAtPath as O, FIRST_RUN_NOTICE as P, withEnvSecrets as Q, buildAiGenerationEvents as R, cloneValue as S, hasScaledUnit as T, decideRemoteTelemetryState as U, classifySessionExit as V, decideTelemetryConsent as W, readEnvSecrets as X, ENV_SECRET_BINDINGS as Y, stableConfigKey as Z, SECRET_PRESENCE_SUFFIX as _, generateProjectId as a, worktreeIntegrationTips as at, validateSettingsBlock as b, resolveConfigPath as c, isSameDirectoryPath as ct, assetForPlatform as d, matchedPrefix as et, decideRtkInstall as f, verifyDigest as g, isRtkBinaryName as h, ensureProjectIds as i, usablePrefixes as it, valueAtPath as j, settingsGroupOf as k, saveConfigFileOnce as l, installTargetPath as m, DEFAULT_CONFIG as n, planWorktreeGc as nt, glimmervoidHomeDir as o, canonicalizePath as ot, findEscapingArchiveMember as p, parsePosthogReleaseId as q, createConfigStore as r, sessionIdFromBranch as rt, loadConfigFile as s, comparableDirectoryPath as st, ABORT_CONFIG_SAVE as t, planBranchGc as tt, validateConfig as u, mergeSettingsBlock as v, displayText as w, SETTINGS_INDEX as x, settingsBlockSpecFor as y, buildBrowserExceptionProperties as z };