otacon 0.1.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 (175) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +88 -0
  3. package/dist/cli/client.js +188 -0
  4. package/dist/cli/client.js.map +1 -0
  5. package/dist/cli/commands/answer.js +63 -0
  6. package/dist/cli/commands/answer.js.map +1 -0
  7. package/dist/cli/commands/ask.js +117 -0
  8. package/dist/cli/commands/ask.js.map +1 -0
  9. package/dist/cli/commands/clean.js +48 -0
  10. package/dist/cli/commands/clean.js.map +1 -0
  11. package/dist/cli/commands/doctor.js +86 -0
  12. package/dist/cli/commands/doctor.js.map +1 -0
  13. package/dist/cli/commands/expose.js +104 -0
  14. package/dist/cli/commands/expose.js.map +1 -0
  15. package/dist/cli/commands/implement-done.js +53 -0
  16. package/dist/cli/commands/implement-done.js.map +1 -0
  17. package/dist/cli/commands/install.js +113 -0
  18. package/dist/cli/commands/install.js.map +1 -0
  19. package/dist/cli/commands/open.js +37 -0
  20. package/dist/cli/commands/open.js.map +1 -0
  21. package/dist/cli/commands/progress.js +45 -0
  22. package/dist/cli/commands/progress.js.map +1 -0
  23. package/dist/cli/commands/start.js +66 -0
  24. package/dist/cli/commands/start.js.map +1 -0
  25. package/dist/cli/commands/status.js +44 -0
  26. package/dist/cli/commands/status.js.map +1 -0
  27. package/dist/cli/commands/submit.js +64 -0
  28. package/dist/cli/commands/submit.js.map +1 -0
  29. package/dist/cli/commands/wait.js +66 -0
  30. package/dist/cli/commands/wait.js.map +1 -0
  31. package/dist/cli/install/assets.js +285 -0
  32. package/dist/cli/install/assets.js.map +1 -0
  33. package/dist/cli/install/locations.js +92 -0
  34. package/dist/cli/install/locations.js.map +1 -0
  35. package/dist/cli/install/tailscale.js +39 -0
  36. package/dist/cli/install/tailscale.js.map +1 -0
  37. package/dist/cli/main.js +73 -0
  38. package/dist/cli/main.js.map +1 -0
  39. package/dist/cli/output.js +39 -0
  40. package/dist/cli/output.js.map +1 -0
  41. package/dist/cli/session.js +77 -0
  42. package/dist/cli/session.js.map +1 -0
  43. package/dist/daemon/activity.js +56 -0
  44. package/dist/daemon/activity.js.map +1 -0
  45. package/dist/daemon/anchor.js +143 -0
  46. package/dist/daemon/anchor.js.map +1 -0
  47. package/dist/daemon/app.js +1081 -0
  48. package/dist/daemon/app.js.map +1 -0
  49. package/dist/daemon/approve.js +71 -0
  50. package/dist/daemon/approve.js.map +1 -0
  51. package/dist/daemon/desktop-notify.js +69 -0
  52. package/dist/daemon/desktop-notify.js.map +1 -0
  53. package/dist/daemon/diff.js +187 -0
  54. package/dist/daemon/diff.js.map +1 -0
  55. package/dist/daemon/linter/index.js +19 -0
  56. package/dist/daemon/linter/index.js.map +1 -0
  57. package/dist/daemon/linter/parse.js +350 -0
  58. package/dist/daemon/linter/parse.js.map +1 -0
  59. package/dist/daemon/linter/rules.js +359 -0
  60. package/dist/daemon/linter/rules.js.map +1 -0
  61. package/dist/daemon/main.js +48 -0
  62. package/dist/daemon/main.js.map +1 -0
  63. package/dist/daemon/notify.js +23 -0
  64. package/dist/daemon/notify.js.map +1 -0
  65. package/dist/daemon/presence.js +37 -0
  66. package/dist/daemon/presence.js.map +1 -0
  67. package/dist/daemon/queue.js +160 -0
  68. package/dist/daemon/queue.js.map +1 -0
  69. package/dist/daemon/store.js +393 -0
  70. package/dist/daemon/store.js.map +1 -0
  71. package/dist/daemon/threads.js +153 -0
  72. package/dist/daemon/threads.js.map +1 -0
  73. package/dist/daemon/transcript.js +89 -0
  74. package/dist/daemon/transcript.js.map +1 -0
  75. package/dist/daemon/ui.js +175 -0
  76. package/dist/daemon/ui.js.map +1 -0
  77. package/dist/shared/config.js +93 -0
  78. package/dist/shared/config.js.map +1 -0
  79. package/dist/shared/gwt.js +69 -0
  80. package/dist/shared/gwt.js.map +1 -0
  81. package/dist/shared/paths.js +67 -0
  82. package/dist/shared/paths.js.map +1 -0
  83. package/dist/shared/question-spec.js +44 -0
  84. package/dist/shared/question-spec.js.map +1 -0
  85. package/dist/shared/types.js +35 -0
  86. package/dist/shared/types.js.map +1 -0
  87. package/dist/shared/version.js +5 -0
  88. package/dist/shared/version.js.map +1 -0
  89. package/dist/ui/assets/arc-HhPfdCPZ.js +1 -0
  90. package/dist/ui/assets/architecture-7EHR7CIX-BPLblcyi.js +1 -0
  91. package/dist/ui/assets/architectureDiagram-3BPJPVTR-D2PIxGOb.js +36 -0
  92. package/dist/ui/assets/array-BifhSqXX.js +1 -0
  93. package/dist/ui/assets/blockDiagram-GPEHLZMM-DQ3Dn17h.js +132 -0
  94. package/dist/ui/assets/c4Diagram-AAUBKEIU-DxITrQgS.js +10 -0
  95. package/dist/ui/assets/channel-ipcU8ZNI.js +1 -0
  96. package/dist/ui/assets/chunk-2J33WTMH-Du1JoPx5.js +1 -0
  97. package/dist/ui/assets/chunk-3OPIFGDE-Dn7x2Yqf.js +62 -0
  98. package/dist/ui/assets/chunk-4BX2VUAB-DVnrE-4n.js +1 -0
  99. package/dist/ui/assets/chunk-55IACEB6-BAhFAimA.js +1 -0
  100. package/dist/ui/assets/chunk-5ZQYHXKU-0hEZptem.js +2 -0
  101. package/dist/ui/assets/chunk-727SXJPM-C1FN_cI3.js +206 -0
  102. package/dist/ui/assets/chunk-AQP2D5EJ-A656OBd4.js +231 -0
  103. package/dist/ui/assets/chunk-BSJP7CBP-D8oMbjm8.js +1 -0
  104. package/dist/ui/assets/chunk-CSCIHK7Q-DjIL8GLi.js +122 -0
  105. package/dist/ui/assets/chunk-FMBD7UC4-Otblfqvz.js +15 -0
  106. package/dist/ui/assets/chunk-KSCS5N6A-BOjTvm3H.js +10 -0
  107. package/dist/ui/assets/chunk-L5ZTLDWV-CaTLaw6L.js +1 -0
  108. package/dist/ui/assets/chunk-LZXEDZCA-Dq5p7qrD.js +2 -0
  109. package/dist/ui/assets/chunk-ND2GUHAM-jZ_NNnWi.js +1 -0
  110. package/dist/ui/assets/chunk-NNHCCRGN-DlpIbxXb.js +159 -0
  111. package/dist/ui/assets/chunk-NZK2D7GU-U_7l_sCh.js +1 -0
  112. package/dist/ui/assets/chunk-O5CBEL6O-MewqqNB7.js +70 -0
  113. package/dist/ui/assets/chunk-QZHKN3VN-DzGPH44B.js +1 -0
  114. package/dist/ui/assets/chunk-WU5MYG2G-DyEIVjoo.js +1 -0
  115. package/dist/ui/assets/chunk-XPW4576I-D5ArxNEF.js +32 -0
  116. package/dist/ui/assets/classDiagram-4FO5ZUOK-Byg2Hl9D.js +1 -0
  117. package/dist/ui/assets/classDiagram-v2-Q7XG4LA2-Byg2Hl9D.js +1 -0
  118. package/dist/ui/assets/cose-bilkent-S5V4N54A-PFXzf7WV.js +1 -0
  119. package/dist/ui/assets/cytoscape.esm-h6BdjjI9.js +321 -0
  120. package/dist/ui/assets/dagre-BM42HDAG-xrCfjZuZ.js +4 -0
  121. package/dist/ui/assets/dagre-Bx709z4p.js +1 -0
  122. package/dist/ui/assets/defaultLocale-C8Fc0cco.js +1 -0
  123. package/dist/ui/assets/diagram-2AECGRRQ-BFf-cyKY.js +43 -0
  124. package/dist/ui/assets/diagram-5GNKFQAL-kNPV4NfV.js +10 -0
  125. package/dist/ui/assets/diagram-KO2AKTUF-ByC1IUwG.js +3 -0
  126. package/dist/ui/assets/diagram-LMA3HP47-DZIJMPK0.js +24 -0
  127. package/dist/ui/assets/diagram-OG6HWLK6-CSDED9A-.js +24 -0
  128. package/dist/ui/assets/dist-YwjsDswi.js +1 -0
  129. package/dist/ui/assets/erDiagram-TEJ5UH35-yuzvjE6J.js +85 -0
  130. package/dist/ui/assets/eventmodeling-FCH6USID-CZR4eNG-.js +1 -0
  131. package/dist/ui/assets/flowDiagram-I6XJVG4X-ApPtVyYM.js +162 -0
  132. package/dist/ui/assets/ganttDiagram-6RSMTGT7-BeMLXtAr.js +292 -0
  133. package/dist/ui/assets/gitGraph-WXDBUCRP-JmTTBa7j.js +1 -0
  134. package/dist/ui/assets/gitGraphDiagram-PVQCEYII-Cjjnjs71.js +106 -0
  135. package/dist/ui/assets/graphlib-B8gBHxth.js +1 -0
  136. package/dist/ui/assets/index-BFQVRcSI.js +11 -0
  137. package/dist/ui/assets/index-Bj_kTrwP.css +1 -0
  138. package/dist/ui/assets/info-J43DQDTF-8vZ3gome.js +1 -0
  139. package/dist/ui/assets/infoDiagram-5YYISTIA-CnMk1cA-.js +2 -0
  140. package/dist/ui/assets/init-D6jRqBbL.js +1 -0
  141. package/dist/ui/assets/ishikawaDiagram-YF4QCWOH-Bl8z6huD.js +70 -0
  142. package/dist/ui/assets/journeyDiagram-JHISSGLW-DYIVfMpS.js +139 -0
  143. package/dist/ui/assets/kanban-definition-UN3LZRKU-BnR0ZzOz.js +89 -0
  144. package/dist/ui/assets/katex-Vhh-h91d.js +257 -0
  145. package/dist/ui/assets/line-DcBdQit6.js +1 -0
  146. package/dist/ui/assets/linear-HKjRHFAO.js +1 -0
  147. package/dist/ui/assets/mermaid-parser.core-DkYXrPlA.js +4 -0
  148. package/dist/ui/assets/mermaid.core-BmkfCI3b.js +9 -0
  149. package/dist/ui/assets/mindmap-definition-RKZ34NQL-sIAd4nDi.js +96 -0
  150. package/dist/ui/assets/ordinal-hYBb2elL.js +1 -0
  151. package/dist/ui/assets/otacon-DPXGiaVj.svg +11 -0
  152. package/dist/ui/assets/packet-YPE3B663-BxbxcfXN.js +1 -0
  153. package/dist/ui/assets/path-BWPyau1x.js +1 -0
  154. package/dist/ui/assets/pie-LRSECV5Y-BJxazjNs.js +1 -0
  155. package/dist/ui/assets/pieDiagram-4H26LBE5-BiOhc9GR.js +30 -0
  156. package/dist/ui/assets/plan-view-CH6NzUDb.js +74 -0
  157. package/dist/ui/assets/purify.es-CDvCXckx.js +3 -0
  158. package/dist/ui/assets/quadrantDiagram-W4KKPZXB-CVyHbWgo.js +7 -0
  159. package/dist/ui/assets/radar-GUYGQ44K-D9ohbnbV.js +1 -0
  160. package/dist/ui/assets/requirementDiagram-4Y6WPE33-Ba24_hqc.js +84 -0
  161. package/dist/ui/assets/rough.esm-CSKSodPl.js +1 -0
  162. package/dist/ui/assets/sankeyDiagram-5OEKKPKP-CxD4wiPL.js +40 -0
  163. package/dist/ui/assets/sequenceDiagram-3UESZ5HK-7qA7lD61.js +162 -0
  164. package/dist/ui/assets/src-IM8AE8MK.js +1 -0
  165. package/dist/ui/assets/stateDiagram-AJRCARHV-DNElRCuH.js +1 -0
  166. package/dist/ui/assets/stateDiagram-v2-BHNVJYJU-D6qTYpY3.js +1 -0
  167. package/dist/ui/assets/timeline-definition-PNZ67QCA-ChYC4Grd.js +120 -0
  168. package/dist/ui/assets/treeView-BLDUP644-Il0KnMi_.js +1 -0
  169. package/dist/ui/assets/treemap-LRROVOQU-CIiKcdRo.js +1 -0
  170. package/dist/ui/assets/vennDiagram-CIIHVFJN-Ulhkum9i.js +34 -0
  171. package/dist/ui/assets/wardley-L42UT6IY-BNd4ljz7.js +1 -0
  172. package/dist/ui/assets/wardleyDiagram-YWT4CUSO-BicXxh84.js +78 -0
  173. package/dist/ui/assets/xychartDiagram-2RQKCTM6-Duf-m_th.js +7 -0
  174. package/dist/ui/index.html +20 -0
  175. package/package.json +66 -0
@@ -0,0 +1,160 @@
1
+ // Per-session disk-backed FIFO event queue with waiter parking (DESIGN.md §6, §7).
2
+ //
3
+ // Every method is synchronous: Node's single thread therefore cannot interleave
4
+ // an enqueue between a queue-empty check and a waiter parking — the whole
5
+ // no-lost-wakeup argument (DECISIONS.md "SessionQueue: synchronous methods only").
6
+ //
7
+ // Delivery is at-least-once (DECISIONS.md "Event delivery: at-least-once"):
8
+ // take() and waiter wake-ups move the event to an in-flight list — still
9
+ // persisted by every flush — and the caller acks it with flush(event) only
10
+ // after the response goes out. A crash inside that window re-delivers the event
11
+ // on the next daemon start instead of losing it, even if other enqueues flushed
12
+ // in between. An event seq is minted by the caller (Store.bumpCounter
13
+ // "eventSeq") so seqs survive queue drains.
14
+ import { existsSync, readFileSync } from "node:fs";
15
+ import { quarantineCorruptFile, stringify, writeFileAtomic } from "./store.js";
16
+ export class SessionQueue {
17
+ filePath;
18
+ events = [];
19
+ /** Dequeued (taken or delivered to a waiter) but not yet acked via flush(event). */
20
+ inFlight = [];
21
+ waiters = [];
22
+ closed = false;
23
+ constructor(filePath) {
24
+ this.filePath = filePath;
25
+ if (!existsSync(filePath))
26
+ return;
27
+ let raw;
28
+ try {
29
+ raw = JSON.parse(readFileSync(filePath, "utf8"));
30
+ }
31
+ catch {
32
+ raw = undefined;
33
+ }
34
+ const file = raw;
35
+ if (file?.version !== 1 || !Array.isArray(file.events)) {
36
+ // Quarantine, never wedge (DECISIONS.md "Corrupt state files are
37
+ // quarantined, not fatal"): pending events are preserved in the
38
+ // quarantined file for manual recovery, and the session keeps working
39
+ // instead of every events call throwing forever.
40
+ quarantineCorruptFile(filePath, "events queue");
41
+ this.flush(); // re-seed an empty file so the next instance reads clean
42
+ return;
43
+ }
44
+ this.events = file.events;
45
+ }
46
+ /** Undelivered events currently queued in memory. */
47
+ get size() {
48
+ return this.events.length;
49
+ }
50
+ /** Delivered events awaiting their post-response flush(event) ack. */
51
+ get inFlightCount() {
52
+ return this.inFlight.length;
53
+ }
54
+ get waiterCount() {
55
+ return this.waiters.length;
56
+ }
57
+ /** Durably append (flushes before any waiter sees it), then wake the first waiter. */
58
+ enqueue(payload, seq) {
59
+ const event = { seq, queuedAt: new Date().toISOString(), payload };
60
+ this.events.push(event);
61
+ this.flush();
62
+ this.dispatch();
63
+ return event;
64
+ }
65
+ /** Fast path: dequeue into the in-flight list. Respond, then flush(event) to ack. */
66
+ take() {
67
+ const event = this.events.shift();
68
+ if (event)
69
+ this.inFlight.push(event);
70
+ return event;
71
+ }
72
+ /** Park a waiter, FIFO behind earlier ones; wakes immediately if events are queued. */
73
+ park(waiter) {
74
+ const entry = { waiter };
75
+ this.waiters.push(entry);
76
+ this.dispatch();
77
+ return {
78
+ cancel: () => {
79
+ const index = this.waiters.indexOf(entry);
80
+ if (index !== -1)
81
+ this.waiters.splice(index, 1);
82
+ },
83
+ };
84
+ }
85
+ /**
86
+ * Detach from disk forever (DELETE /api/sessions/:id evicted this instance):
87
+ * flush and requeue become no-ops. A delivered-but-unacked event's
88
+ * post-response ack callback can fire after `otacon clean` archives the
89
+ * session dir — writing then would recreate .otacon/<id>/ next to the
90
+ * archive (writeFileAtomic mkdirs). The events file leaves with the dir.
91
+ */
92
+ close() {
93
+ this.closed = true;
94
+ }
95
+ /**
96
+ * Detach from disk AND wake every parked waiter with one terminal event
97
+ * (DELETE of a *pending* session, DESIGN.md §12): set `closed` first so
98
+ * flush/requeue/dispatch all become no-ops — the synthetic event is never
99
+ * persisted or requeued, and a late post-response ack can't recreate the
100
+ * `.otacon/<id>/` dir the caller is about to hard-remove — then hand each
101
+ * parked waiter the same payload so its long-poll resolves cleanly instead of
102
+ * 404ing on the next call. No waiter parked = nobody to wake (an agent that
103
+ * is not parked discovers the delete via its next call's 404). The synthetic
104
+ * seq is -1: it never touches disk or the eventSeq counter.
105
+ */
106
+ closeWith(payload) {
107
+ this.close(); // share the detach-from-disk semantics — closed first, see above
108
+ const event = { seq: -1, queuedAt: new Date().toISOString(), payload };
109
+ for (const { waiter } of this.waiters.splice(0))
110
+ waiter(event);
111
+ }
112
+ /** Return an undeliverable event (e.g. wait aborted after wake) to the head, durably. */
113
+ requeue(event) {
114
+ if (this.closed)
115
+ return;
116
+ this.dropInFlight(event);
117
+ this.events.unshift(event);
118
+ this.flush();
119
+ this.dispatch();
120
+ }
121
+ /**
122
+ * Persist the queue: in-flight events first (they were dequeued earlier, so
123
+ * FIFO order survives a restart), then the queued tail. Pass the event a
124
+ * response just went out for to ack it — only an ack removes it from disk.
125
+ */
126
+ flush(acked) {
127
+ if (this.closed)
128
+ return;
129
+ if (acked)
130
+ this.dropInFlight(acked);
131
+ const file = { version: 1, events: [...this.inFlight, ...this.events] };
132
+ writeFileAtomic(this.filePath, stringify(file));
133
+ }
134
+ dropInFlight(event) {
135
+ const index = this.inFlight.indexOf(event);
136
+ if (index !== -1)
137
+ this.inFlight.splice(index, 1);
138
+ }
139
+ /**
140
+ * Pair queued events with parked waiters, FIFO on both sides, one event each.
141
+ * A waiter that throws gets its event back at the head (still durable) so the
142
+ * next dispatch can deliver it; the throw propagates to the caller.
143
+ */
144
+ dispatch() {
145
+ while (this.waiters.length > 0 && this.events.length > 0) {
146
+ const entry = this.waiters.shift();
147
+ const event = this.events.shift();
148
+ this.inFlight.push(event);
149
+ try {
150
+ entry.waiter(event);
151
+ }
152
+ catch (error) {
153
+ this.dropInFlight(event);
154
+ this.events.unshift(event);
155
+ throw error;
156
+ }
157
+ }
158
+ }
159
+ }
160
+ //# sourceMappingURL=queue.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"queue.js","sourceRoot":"","sources":["../../src/daemon/queue.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,393 @@
1
+ // Global session registry, per-session daemon state, and revision snapshots
2
+ // (DESIGN.md §7, §12). All state is plain JSON written atomically — temp file +
3
+ // rename — so a crash can never leave a half-written file (DECISIONS.md
4
+ // "Storage: plain JSON files, not SQLite"). A file that is corrupt anyway
5
+ // (manual edit, disk fault) is quarantined, never fatal: it is renamed aside
6
+ // and the daemon continues with a fresh structure (DECISIONS.md "Corrupt state
7
+ // files are quarantined, not fatal") — a permanently wedged daemon is worse
8
+ // than one recoverable file.
9
+ import { randomBytes } from "node:crypto";
10
+ import { existsSync, mkdirSync, readdirSync, readFileSync, renameSync, rmSync, writeFileSync } from "node:fs";
11
+ import { dirname, join } from "node:path";
12
+ import * as paths from "../shared/paths.js";
13
+ let tmpSerial = 0;
14
+ let quarantineSerial = 0;
15
+ /** Atomic write: temp file in the destination directory (created if needed) + rename. */
16
+ export function writeFileAtomic(path, data) {
17
+ const dir = dirname(path);
18
+ mkdirSync(dir, { recursive: true });
19
+ const tmp = join(dir, `.tmp-${process.pid}-${tmpSerial++}`);
20
+ writeFileSync(tmp, data);
21
+ renameSync(tmp, path);
22
+ }
23
+ /** Canonical on-disk JSON formatting for all otacon state files. */
24
+ export function stringify(value) {
25
+ return JSON.stringify(value, null, 2) + "\n";
26
+ }
27
+ /**
28
+ * Move a corrupt state file aside to `<name>.corrupt-<timestamp>` (atomic
29
+ * rename), log to stderr, and let the caller continue with a fresh structure.
30
+ * The serial suffix keeps two quarantines in the same millisecond from
31
+ * overwriting each other.
32
+ */
33
+ export function quarantineCorruptFile(path, what) {
34
+ const aside = `${path}.corrupt-${Date.now()}-${quarantineSerial++}`;
35
+ try {
36
+ renameSync(path, aside);
37
+ }
38
+ catch (error) {
39
+ // The file vanished (deleted out from under us mid-recovery) or the rename
40
+ // itself failed. Quarantine exists to keep the daemon alive — moving the
41
+ // evidence aside must never become the new fatal path; the caller's fresh
42
+ // rebuild overwrites whatever is (or is not) left at `path`.
43
+ const message = error instanceof Error ? error.message : String(error);
44
+ process.stderr.write(`otacond: ${what} at ${path} is corrupt and could not be moved aside (${message}); continuing with fresh state\n`);
45
+ return aside;
46
+ }
47
+ process.stderr.write(`otacond: ${what} at ${path} is corrupt; moved it to ${aside} and continuing with fresh state\n`);
48
+ return aside;
49
+ }
50
+ export function readJsonOr(path) {
51
+ try {
52
+ return JSON.parse(readFileSync(path, "utf8"));
53
+ }
54
+ catch {
55
+ return undefined; // unreadable or not JSON — caller quarantines
56
+ }
57
+ }
58
+ function parseRegistry(raw) {
59
+ const file = raw;
60
+ const valid = typeof file === "object" &&
61
+ file !== null &&
62
+ file.version === 1 &&
63
+ typeof file.sessions === "object" &&
64
+ file.sessions !== null;
65
+ return valid ? file : undefined;
66
+ }
67
+ function parseState(raw) {
68
+ const file = raw;
69
+ const counters = file?.counters;
70
+ const valid = typeof file === "object" &&
71
+ file !== null &&
72
+ typeof file.id === "string" &&
73
+ typeof file.revision === "number" &&
74
+ typeof counters === "object" &&
75
+ counters !== null &&
76
+ typeof counters.batch === "number" &&
77
+ typeof counters.thread === "number" &&
78
+ typeof counters.question === "number" &&
79
+ typeof counters.eventSeq === "number";
80
+ if (!valid)
81
+ return undefined;
82
+ // Pre-M3 state files lack the field; a hand-edited/restored file may carry a
83
+ // non-integer or a value beyond the current revision, which would poison the
84
+ // diff endpoint's default baseline (400 on a parameterless GET, or a 500 via
85
+ // readRevision(1.5)). Defaulting/clamping beats quarantining either way.
86
+ const reviewed = file.lastReviewedRevision;
87
+ file.lastReviewedRevision =
88
+ typeof reviewed === "number" && Number.isInteger(reviewed) && reviewed > 0
89
+ ? Math.min(reviewed, file.revision)
90
+ : 0;
91
+ return file;
92
+ }
93
+ /** Highest r<N>.md snapshot on disk — the revision counter's source of truth. */
94
+ function recoverRevision(repo, id) {
95
+ let max = 0;
96
+ try {
97
+ for (const name of readdirSync(paths.sessionDir(repo, id))) {
98
+ const match = /^r(\d+)\.md$/.exec(name);
99
+ if (match)
100
+ max = Math.max(max, Number(match[1]));
101
+ }
102
+ }
103
+ catch {
104
+ // no session dir yet — revision 0
105
+ }
106
+ return max;
107
+ }
108
+ /**
109
+ * High-water scan of threads.json and events.json so rebuilt counters never
110
+ * re-mint a live id (DECISIONS.md "Quarantine counter recovery") — duplicate
111
+ * thread ids would cross-wire resolutions now that threads carry state. Reads
112
+ * loosely (no thread validation): a half-corrupt file should still surrender
113
+ * every id it can.
114
+ */
115
+ function recoverCounters(repo, id) {
116
+ const counters = { batch: 0, thread: 0, question: 0, eventSeq: 0 };
117
+ const see = (key, raw, re) => {
118
+ const match = typeof raw === "string" ? re.exec(raw) : null;
119
+ if (match)
120
+ counters[key] = Math.max(counters[key], Number(match[1]));
121
+ };
122
+ const threadsRaw = readJsonOr(paths.threadsPath(repo, id));
123
+ for (const t of Array.isArray(threadsRaw?.threads) ? threadsRaw.threads : []) {
124
+ const thread = t;
125
+ see("thread", thread?.id, /^t(\d+)$/);
126
+ see("question", thread?.id, /^q(\d+)$/);
127
+ see("batch", thread?.batch, /^b(\d+)$/);
128
+ }
129
+ // Agent grill questions share the q counter with user-question threads.
130
+ const transcriptRaw = readJsonOr(paths.transcriptPath(repo, id));
131
+ for (const e of Array.isArray(transcriptRaw?.entries) ? transcriptRaw.entries : []) {
132
+ see("question", e?.id, /^q(\d+)$/);
133
+ }
134
+ const eventsRaw = readJsonOr(paths.eventsPath(repo, id));
135
+ for (const e of Array.isArray(eventsRaw?.events) ? eventsRaw.events : []) {
136
+ const event = e;
137
+ if (typeof event?.seq === "number") {
138
+ counters.eventSeq = Math.max(counters.eventSeq, event.seq);
139
+ }
140
+ see("batch", event?.payload?.batch, /^b(\d+)$/);
141
+ see("question", event?.payload?.id, /^q(\d+)$/);
142
+ for (const item of Array.isArray(event?.payload?.items) ? event.payload.items : []) {
143
+ see("thread", item?.thread, /^t(\d+)$/);
144
+ }
145
+ }
146
+ return counters;
147
+ }
148
+ const BASE36 = "0123456789abcdefghijklmnopqrstuvwxyz";
149
+ /**
150
+ * Owns `$OTACON_HOME/registry.json` plus each session's `.otacon/<id>/` state in
151
+ * its repo. Event seqs and the b/t/q stable ids are minted here (bumpCounter)
152
+ * so they survive queue drains and daemon restarts.
153
+ */
154
+ export class Store {
155
+ registryFile;
156
+ registry;
157
+ constructor() {
158
+ this.registryFile = paths.registryPath();
159
+ if (!existsSync(this.registryFile)) {
160
+ this.registry = { version: 1, sessions: {} };
161
+ return;
162
+ }
163
+ const parsed = parseRegistry(readJsonOr(this.registryFile));
164
+ if (parsed) {
165
+ this.registry = parsed;
166
+ return;
167
+ }
168
+ // Sessions registered there are forgotten (their .otacon/ dirs survive for
169
+ // manual recovery); the alternative is a daemon that can never boot again.
170
+ quarantineCorruptFile(this.registryFile, "session registry");
171
+ this.registry = { version: 1, sessions: {} };
172
+ this.flushRegistry();
173
+ }
174
+ listSessions() {
175
+ return Object.values(this.registry.sessions).map((s) => ({ ...s }));
176
+ }
177
+ getSession(id) {
178
+ const session = this.registry.sessions[id];
179
+ return session ? { ...session } : undefined;
180
+ }
181
+ createSession(input) {
182
+ const id = this.mintId();
183
+ const now = new Date().toISOString();
184
+ const session = {
185
+ id,
186
+ title: input.title,
187
+ repo: input.repo,
188
+ branch: input.branch ?? "",
189
+ quick: input.quick ?? false,
190
+ status: "draft",
191
+ createdAt: now,
192
+ updatedAt: now,
193
+ };
194
+ // State files first, registry entry last: the registry is the commit point.
195
+ // A crash in between leaves an orphan .otacon/<id>/ dir (harmless), never a
196
+ // registered session whose state files are missing (wedged forever).
197
+ const state = {
198
+ id,
199
+ revision: 0,
200
+ lastReviewedRevision: 0,
201
+ counters: { batch: 0, thread: 0, question: 0, eventSeq: 0 },
202
+ };
203
+ writeFileAtomic(paths.sessionStatePath(input.repo, id), stringify(state));
204
+ writeFileAtomic(paths.eventsPath(input.repo, id), stringify({ version: 1, events: [] }));
205
+ this.registry.sessions[id] = session;
206
+ this.flushRegistry();
207
+ return { ...session };
208
+ }
209
+ updateSession(id, patch) {
210
+ const session = this.require(id);
211
+ Object.assign(session, patch);
212
+ session.updatedAt = new Date().toISOString();
213
+ this.flushRegistry();
214
+ return { ...session };
215
+ }
216
+ /**
217
+ * Remove a session from the registry (otacon clean, DESIGN.md §12); the
218
+ * .otacon/<id>/ dir in its repo is the CLI's to archive afterwards.
219
+ */
220
+ deleteSession(id) {
221
+ const session = this.require(id);
222
+ delete this.registry.sessions[id];
223
+ this.flushRegistry();
224
+ return { ...session };
225
+ }
226
+ /**
227
+ * Hard-remove a session's working dir `.otacon/<id>/` (the UI deleting a
228
+ * *pending* session, DESIGN.md §12): permanent, no archive — for a session
229
+ * with no committed artifact. `repo` is passed explicitly because the caller
230
+ * deregisters first, so require() would already throw. Idempotent: a missing
231
+ * dir is fine (force).
232
+ */
233
+ removeSessionDir(repo, id) {
234
+ rmSync(paths.sessionDir(repo, id), { recursive: true, force: true });
235
+ }
236
+ /**
237
+ * Archive a session's working dir `.otacon/<id>/` → `.otacon/archive/<id>/`
238
+ * in its repo (numeric suffix on name collision); returns the destination, or
239
+ * null when there was no dir. The recoverable counterpart to removeSessionDir,
240
+ * for a session whose plan is committed (approved): `otacon clean` and the
241
+ * UI's delete of an approved session both archive through here. `repo` is
242
+ * passed explicitly because the caller deregisters first (require() throws).
243
+ */
244
+ archiveSessionDir(repo, id) {
245
+ const source = paths.sessionDir(repo, id);
246
+ if (!existsSync(source))
247
+ return null;
248
+ const base = join(paths.otaconDir(repo), "archive");
249
+ mkdirSync(base, { recursive: true });
250
+ let dest = join(base, id);
251
+ for (let n = 2; existsSync(dest); n++)
252
+ dest = join(base, `${id}-${n}`);
253
+ renameSync(source, dest);
254
+ return dest;
255
+ }
256
+ readState(id) {
257
+ const session = this.require(id);
258
+ const path = paths.sessionStatePath(session.repo, id);
259
+ if (existsSync(path)) {
260
+ const parsed = parseState(readJsonOr(path));
261
+ if (parsed && parsed.id === id)
262
+ return parsed;
263
+ quarantineCorruptFile(path, `session state for ${id}`);
264
+ }
265
+ // Rebuild: revision comes from the r<N>.md snapshots (they are the actual
266
+ // plan history — restarting at r1 would overwrite them); counters from a
267
+ // high-water scan of threads.json and events.json, so rebuilt counters
268
+ // cannot mint duplicate live ids (DECISIONS.md "Quarantine counter
269
+ // recovery"). lastReviewedRevision restarts at 0 — the diff baseline
270
+ // degrades to "previous revision", which the user can re-select.
271
+ const state = {
272
+ id,
273
+ revision: recoverRevision(session.repo, id),
274
+ lastReviewedRevision: 0,
275
+ counters: recoverCounters(session.repo, id),
276
+ };
277
+ writeFileAtomic(path, stringify(state));
278
+ return state;
279
+ }
280
+ /**
281
+ * Record that the user has reviewed revision n (a comment-batch flush, or
282
+ * the UI's explicit mark-reviewed). Monotonic: the stored value never moves
283
+ * backwards — older baselines stay reachable via the diff endpoint's ?from=.
284
+ */
285
+ markReviewed(id, n) {
286
+ const session = this.require(id);
287
+ const state = this.readState(id);
288
+ if (n > state.lastReviewedRevision) {
289
+ state.lastReviewedRevision = Math.min(n, state.revision);
290
+ writeFileAtomic(paths.sessionStatePath(session.repo, id), stringify(state));
291
+ }
292
+ return state.lastReviewedRevision;
293
+ }
294
+ /** Increment one daemon-owned counter (DESIGN.md §6 stable ids) and persist it. */
295
+ bumpCounter(id, key) {
296
+ return this.bumpCounters(id, { [key]: 1 })[key];
297
+ }
298
+ /**
299
+ * Increment several counters in one read + one atomic write (a comment batch
300
+ * mints N thread ids, a batch id, and an event seq together); returns the
301
+ * updated counter values.
302
+ */
303
+ bumpCounters(id, by) {
304
+ const session = this.require(id);
305
+ const state = this.readState(id);
306
+ for (const key of Object.keys(by)) {
307
+ state.counters[key] += by[key] ?? 0;
308
+ }
309
+ writeFileAtomic(paths.sessionStatePath(session.repo, id), stringify(state));
310
+ return { ...state.counters };
311
+ }
312
+ /**
313
+ * Store the next revision snapshot r<N>.md plus the lint warnings it was
314
+ * accepted with (r<N>.warnings.json — the UI's L6 badges; DESIGN.md §12)
315
+ * and the agent's changelog when one accompanied it (r<N>.changelog.md);
316
+ * returns N.
317
+ */
318
+ saveRevision(id, content, warnings = [], changelog) {
319
+ const session = this.require(id);
320
+ const state = this.readState(id);
321
+ state.revision += 1;
322
+ writeFileAtomic(paths.revisionPath(session.repo, id, state.revision), content);
323
+ writeFileAtomic(paths.revisionWarningsPath(session.repo, id, state.revision), stringify(warnings));
324
+ if (changelog !== undefined && changelog.trim() !== "") {
325
+ writeFileAtomic(paths.revisionChangelogPath(session.repo, id, state.revision), changelog);
326
+ }
327
+ writeFileAtomic(paths.sessionStatePath(session.repo, id), stringify(state));
328
+ session.updatedAt = new Date().toISOString();
329
+ this.flushRegistry();
330
+ return state.revision;
331
+ }
332
+ readRevision(id, n) {
333
+ const session = this.require(id);
334
+ return readFileSync(paths.revisionPath(session.repo, id, n), "utf8");
335
+ }
336
+ /** The changelog submitted with r<n>.md; null when none was (r1, typically). */
337
+ readRevisionChangelog(id, n) {
338
+ const session = this.require(id);
339
+ try {
340
+ return readFileSync(paths.revisionChangelogPath(session.repo, id, n), "utf8");
341
+ }
342
+ catch {
343
+ return null;
344
+ }
345
+ }
346
+ /**
347
+ * Warnings recorded with r<n>.md. Missing or corrupt files read as [] — the
348
+ * badges are presentation metadata, never worth quarantine machinery.
349
+ */
350
+ readRevisionWarnings(id, n) {
351
+ const session = this.require(id);
352
+ const raw = readJsonOr(paths.revisionWarningsPath(session.repo, id, n));
353
+ return Array.isArray(raw) ? raw : [];
354
+ }
355
+ /** Where this session's SessionQueue persists — for the daemon to wire queues. */
356
+ eventsPath(id) {
357
+ return paths.eventsPath(this.require(id).repo, id);
358
+ }
359
+ /** Where this session's review threads persist (src/daemon/threads.ts). */
360
+ threadsPath(id) {
361
+ return paths.threadsPath(this.require(id).repo, id);
362
+ }
363
+ /** Where this session's grill transcript persists (src/daemon/transcript.ts). */
364
+ transcriptPath(id) {
365
+ return paths.transcriptPath(this.require(id).repo, id);
366
+ }
367
+ /** Where this session's live-activity feed persists (src/daemon/activity.ts). */
368
+ activityPath(id) {
369
+ return paths.activityPath(this.require(id).repo, id);
370
+ }
371
+ require(id) {
372
+ const session = this.registry.sessions[id];
373
+ if (!session)
374
+ throw new Error(`unknown session: ${id}`);
375
+ return session;
376
+ }
377
+ /** `otc_` + 6 base36 chars, collision-checked (DECISIONS.md "Session ids"). */
378
+ mintId() {
379
+ for (let attempt = 0; attempt < 64; attempt++) {
380
+ let suffix = "";
381
+ for (const byte of randomBytes(6))
382
+ suffix += BASE36[byte % 36];
383
+ const id = `otc_${suffix}`;
384
+ if (!(id in this.registry.sessions))
385
+ return id;
386
+ }
387
+ throw new Error("could not mint a unique session id");
388
+ }
389
+ flushRegistry() {
390
+ writeFileAtomic(this.registryFile, stringify(this.registry));
391
+ }
392
+ }
393
+ //# sourceMappingURL=store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"store.js","sourceRoot":"","sources":["../../src/daemon/store.ts"],"names":[],"mappings":"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"}