frizz 0.0.1 → 0.2.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 +276 -0
  3. package/dist/claude-agent-broker.js +21714 -0
  4. package/dist/codex-app-server-daemon.js +354 -0
  5. package/dist/dev-child.js +39342 -0
  6. package/dist/frizz.js +10517 -0
  7. package/package.json +54 -20
  8. package/runtime/board/agent-bindings.mjs +287 -0
  9. package/runtime/board/agent-liveness.mjs +367 -0
  10. package/runtime/board/agent-status.mjs +178 -0
  11. package/runtime/board/config.mjs +982 -0
  12. package/runtime/board/decisions.mjs +97 -0
  13. package/runtime/board/index.mjs +699 -0
  14. package/runtime/board/notify-shared.mjs +90 -0
  15. package/runtime/board/notify.mjs +81 -0
  16. package/runtime/board/ownership.mjs +120 -0
  17. package/runtime/board/rest-detect.mjs +213 -0
  18. package/runtime/board/thread-excerpt.mjs +162 -0
  19. package/runtime/board/thread-update.mjs +285 -0
  20. package/runtime/cc-worker/.claude-plugin/plugin.json +10 -0
  21. package/runtime/cc-worker/DECISIONS.md +1025 -0
  22. package/runtime/cc-worker/LICENSE +21 -0
  23. package/runtime/cc-worker/agents/fable-high.md +8 -0
  24. package/runtime/cc-worker/agents/fable-low.md +8 -0
  25. package/runtime/cc-worker/agents/fable-max.md +8 -0
  26. package/runtime/cc-worker/agents/fable-medium.md +8 -0
  27. package/runtime/cc-worker/agents/fable-xhigh.md +8 -0
  28. package/runtime/cc-worker/agents/haiku.md +7 -0
  29. package/runtime/cc-worker/agents/opus-high.md +8 -0
  30. package/runtime/cc-worker/agents/opus-low.md +8 -0
  31. package/runtime/cc-worker/agents/opus-max.md +8 -0
  32. package/runtime/cc-worker/agents/opus-medium.md +8 -0
  33. package/runtime/cc-worker/agents/opus-xhigh.md +8 -0
  34. package/runtime/cc-worker/agents/sonnet-high.md +8 -0
  35. package/runtime/cc-worker/agents/sonnet-low.md +8 -0
  36. package/runtime/cc-worker/agents/sonnet-max.md +8 -0
  37. package/runtime/cc-worker/agents/sonnet-medium.md +8 -0
  38. package/runtime/cc-worker/agents/sonnet-xhigh.md +8 -0
  39. package/runtime/cc-worker/bin/frizz +17 -0
  40. package/runtime/cc-worker/bin/frizz-mcp.mjs +564 -0
  41. package/runtime/cc-worker/bin/frizz-update +18 -0
  42. package/runtime/cc-worker/hooks/agent-bind.mjs +40 -0
  43. package/runtime/cc-worker/hooks/agent-dispatch.mjs +98 -0
  44. package/runtime/cc-worker/hooks/bash-background.d.mts +6 -0
  45. package/runtime/cc-worker/hooks/bash-background.mjs +236 -0
  46. package/runtime/cc-worker/hooks/deny-ask.mjs +38 -0
  47. package/runtime/cc-worker/hooks/deny-plan.mjs +61 -0
  48. package/runtime/cc-worker/hooks/hooks.json +111 -0
  49. package/runtime/cc-worker/hooks/perm-policy.mjs +211 -0
  50. package/runtime/cc-worker/hooks/precompact-instructions.mjs +122 -0
  51. package/runtime/cc-worker/hooks/scratchpad-stop.mjs +125 -0
  52. package/runtime/cc-worker/hooks/scratchpad.mjs +446 -0
  53. package/runtime/cc-worker/hooks/session-seed.mjs +106 -0
  54. package/runtime/cc-worker/scripts/frizz/agent-bindings.mjs +9 -0
  55. package/runtime/cc-worker/scripts/frizz/config.mjs +12 -0
  56. package/runtime/cc-worker/skills/gh/SKILL.md +154 -0
  57. package/runtime/cc-worker/skills/gh/scripts/ci-watch.mjs +60 -0
  58. package/runtime/cc-worker/skills/gh/scripts/github-watch.mjs +130 -0
  59. package/runtime/cc-worker/skills/gh/scripts/review-watch.mjs +54 -0
  60. package/runtime/cc-worker/skills/handoff/SKILL.md +209 -0
  61. package/runtime/cc-worker/skills/waits/SKILL.md +83 -0
  62. package/web-dist/apple-touch-icon.png +0 -0
  63. package/web-dist/assets/TerminalPane-ROKHp1ib.js +7 -0
  64. package/web-dist/assets/abnfDiagram-VRR7QNED-DcpdhBs3.js +1 -0
  65. package/web-dist/assets/arc-BSyeo0Gb.js +1 -0
  66. package/web-dist/assets/architecture-TIHT7OUA-CAviNivx.js +1 -0
  67. package/web-dist/assets/architectureDiagram-ZJ3FMSHR-CUAKf0mn.js +36 -0
  68. package/web-dist/assets/array-BifhSqXX.js +1 -0
  69. package/web-dist/assets/blockDiagram-677ZJIJ3-BPwpJIzx.js +132 -0
  70. package/web-dist/assets/c4Diagram-LMCZKHZV-1lptuHzZ.js +10 -0
  71. package/web-dist/assets/channel-CqKDIFQF.js +1 -0
  72. package/web-dist/assets/chunk-2Q5K7J3B-C1jixKkw.js +1 -0
  73. package/web-dist/assets/chunk-32BRIVSS-CFR9AKjY.js +1 -0
  74. package/web-dist/assets/chunk-52WLFC77-CM9uct7m.js +10 -0
  75. package/web-dist/assets/chunk-5VM5RSS4-ZNzvKenW.js +15 -0
  76. package/web-dist/assets/chunk-7BUUIJ7U-Bb538aSH.js +1 -0
  77. package/web-dist/assets/chunk-C7G6YPKG-DiveJARw.js +1 -0
  78. package/web-dist/assets/chunk-EX3LRPZG-BE1CBw8F.js +231 -0
  79. package/web-dist/assets/chunk-FWX5IMBZ-DL42uXiO.js +2 -0
  80. package/web-dist/assets/chunk-HOUHSVGY-DPhJWgDw.js +1 -0
  81. package/web-dist/assets/chunk-ICXQ74PX-CwYy-6AP.js +2 -0
  82. package/web-dist/assets/chunk-JWPE2WC7-DVXcaiue.js +1 -0
  83. package/web-dist/assets/chunk-KEIR6QF5-BfrZ3jm6.js +161 -0
  84. package/web-dist/assets/chunk-MOJQB5TN-Ds5I9wxq.js +88 -0
  85. package/web-dist/assets/chunk-OGEWGWER-DHiZJwQD.js +1 -0
  86. package/web-dist/assets/chunk-PUDLZKDR-B-eyQTsF.js +156 -0
  87. package/web-dist/assets/chunk-Q4XR5HBZ-DK7dB3Ti.js +70 -0
  88. package/web-dist/assets/chunk-RYQCIY6F-Cu_KplZW.js +1 -0
  89. package/web-dist/assets/chunk-V7JOEXUC-Dn59m74L.js +206 -0
  90. package/web-dist/assets/chunk-VAUOI2AC-DK7x36hd.js +1 -0
  91. package/web-dist/assets/chunk-VR4S4FIN-D7-CI3Yl.js +1 -0
  92. package/web-dist/assets/chunk-WYO6CB5R-B3l-mLCs.js +127 -0
  93. package/web-dist/assets/chunk-XXDRQBXY-DYlTP5J-.js +1 -0
  94. package/web-dist/assets/chunk-Y2CYZVJY-DsF7k-Jl.js +1 -0
  95. package/web-dist/assets/chunk-ZGVPDNZ5-Dobxlxie.js +62 -0
  96. package/web-dist/assets/chunk-ZIRB5QZD-C6fEPe3t.js +32 -0
  97. package/web-dist/assets/classDiagram-OUVF2IWQ-B_-6iXYY.js +1 -0
  98. package/web-dist/assets/classDiagram-v2-EOCWNBFH-B_-6iXYY.js +1 -0
  99. package/web-dist/assets/cose-bilkent-JH36ORCC-BUIsLrGc.js +1 -0
  100. package/web-dist/assets/cynefin-VYW2F7L2-Dh7RuEUJ.js +1 -0
  101. package/web-dist/assets/cynefinDiagram-TSTJHNR4-ClPi2mZZ.js +62 -0
  102. package/web-dist/assets/cytoscape.esm-B3I8pqwA.js +321 -0
  103. package/web-dist/assets/dagre-CXRCoUWR.js +1 -0
  104. package/web-dist/assets/dagre-VKFMJZFB-52_WP1QV.js +4 -0
  105. package/web-dist/assets/defaultLocale-C8Fc0cco.js +1 -0
  106. package/web-dist/assets/diagram-FQU43EPY-D_1zVsTL.js +3 -0
  107. package/web-dist/assets/diagram-G47NLZAW-CdZxuGUy.js +24 -0
  108. package/web-dist/assets/diagram-NH7WQ7WH-C8pSFu0P.js +24 -0
  109. package/web-dist/assets/diagram-OA4YK3LP-C5bjZLre.js +30 -0
  110. package/web-dist/assets/diagram-WEI45ONY-Bxzhiuzn.js +41 -0
  111. package/web-dist/assets/dist-DoH_9pyS.js +1 -0
  112. package/web-dist/assets/ebnfDiagram-CCIWWBDH-g-Z0J2wP.js +1 -0
  113. package/web-dist/assets/erDiagram-Q63AITRT-DVNkgIHp.js +85 -0
  114. package/web-dist/assets/eventmodeling-45OFAUF4-MpmeH5YZ.js +1 -0
  115. package/web-dist/assets/flowDiagram-23GEKE2U-D-QgjjhF.js +1 -0
  116. package/web-dist/assets/ganttDiagram-NO4QXBWP-_71pQYEK.js +292 -0
  117. package/web-dist/assets/gitGraph-TEB2WS4Q-ChIZiGZS.js +1 -0
  118. package/web-dist/assets/gitGraphDiagram-IHSO6WYX-DCHAFI0l.js +106 -0
  119. package/web-dist/assets/graphlib-B8gBHxth.js +1 -0
  120. package/web-dist/assets/index-w4v-GZEc.js +358 -0
  121. package/web-dist/assets/index-zyi22LPz.css +1 -0
  122. package/web-dist/assets/info-DKCQHKI2-BW-n_T1j.js +1 -0
  123. package/web-dist/assets/infoDiagram-FWYZ7A6U-CgDYsKi9.js +2 -0
  124. package/web-dist/assets/init-D6jRqBbL.js +1 -0
  125. package/web-dist/assets/ishikawaDiagram-FXEZZL3T-ClzGNt9N.js +70 -0
  126. package/web-dist/assets/journeyDiagram-5HDEW3XC-DSCQxkHC.js +139 -0
  127. package/web-dist/assets/kanban-definition-HUTT4EX6-CdrdX9N8.js +89 -0
  128. package/web-dist/assets/katex-CddkPoXu.js +257 -0
  129. package/web-dist/assets/line-ha38Dc-1.js +1 -0
  130. package/web-dist/assets/linear-z2V0wJk9.js +1 -0
  131. package/web-dist/assets/map-DsCK-0Cs.js +1 -0
  132. package/web-dist/assets/mermaid-parser.core-Z4uMcpip.js +7 -0
  133. package/web-dist/assets/mermaid.core-iZRq3hbu.js +11 -0
  134. package/web-dist/assets/mindmap-definition-LN4V7U3C-DmhInJO_.js +96 -0
  135. package/web-dist/assets/ordinal-hYBb2elL.js +1 -0
  136. package/web-dist/assets/packet-7NZHBO7P-DBPB36Kl.js +1 -0
  137. package/web-dist/assets/path-BWPyau1x.js +1 -0
  138. package/web-dist/assets/pegDiagram-2B236MQR-CAH3ljfj.js +1 -0
  139. package/web-dist/assets/pie-RZYD4A2V-_h_eX4Ca.js +1 -0
  140. package/web-dist/assets/pieDiagram-ENE6RG2P-DFBPus8j.js +39 -0
  141. package/web-dist/assets/quadrantDiagram-ABIIQ3AL-DMvOCjt8.js +7 -0
  142. package/web-dist/assets/radar-I7S5WNFK-2EzoPHEZ.js +1 -0
  143. package/web-dist/assets/railroad-3IZDKUUU-BPJnn-hm.js +1 -0
  144. package/web-dist/assets/railroad-abnf-AHOZXSZD-YeUoiySk.js +1 -0
  145. package/web-dist/assets/railroad-ebnf-EBAXGLYW-Ddw1SuGG.js +1 -0
  146. package/web-dist/assets/railroad-peg-LSFZ7HO6-Dd8BOGeW.js +1 -0
  147. package/web-dist/assets/railroadDiagram-RFXS5EU6-DKq5FagA.js +1 -0
  148. package/web-dist/assets/requirementDiagram-TGXJPOKE-BJ5tGazp.js +84 -0
  149. package/web-dist/assets/rolldown-runtime-Bh1tDfsg.js +1 -0
  150. package/web-dist/assets/rough.esm-CSKSodPl.js +1 -0
  151. package/web-dist/assets/sankeyDiagram-HTMAVEWB-XSJjcBhX.js +40 -0
  152. package/web-dist/assets/sequenceDiagram-DBY2YBRQ-CBb8emSe.js +162 -0
  153. package/web-dist/assets/sizeCapture-X5ZJPWSS-B0uUizjq.js +1 -0
  154. package/web-dist/assets/src-C4XfhTaE.js +1 -0
  155. package/web-dist/assets/stateDiagram-2N3HPSRC-DDfRW94V.js +1 -0
  156. package/web-dist/assets/stateDiagram-v2-6OUMAXLB-hc41W5Lx.js +1 -0
  157. package/web-dist/assets/swimlanes-5IMT3BWC-DvRYbkZi.js +2 -0
  158. package/web-dist/assets/swimlanesDiagram-G3AALYLV-BZyGdgSG.js +8 -0
  159. package/web-dist/assets/timeline-definition-FHXFAJF6-BNUa_DwI.js +120 -0
  160. package/web-dist/assets/treeView-QDETBFTQ-I6-IW6nJ.js +1 -0
  161. package/web-dist/assets/treemap-6X3UGDF4-CWWmEUYJ.js +1 -0
  162. package/web-dist/assets/vennDiagram-L72KCM5P-DTDrPGLk.js +34 -0
  163. package/web-dist/assets/wardley-OPB4EBWU-CNsdgXXA.js +1 -0
  164. package/web-dist/assets/wardleyDiagram-EHGQE667-YE0tq3Kh.js +78 -0
  165. package/web-dist/assets/xychartDiagram-FW5EYKEG-D0ofMX8C.js +7 -0
  166. package/web-dist/favicon-16.png +0 -0
  167. package/web-dist/favicon-32.png +0 -0
  168. package/web-dist/favicon.svg +78 -0
  169. package/web-dist/icon-192.png +0 -0
  170. package/web-dist/icon-512.png +0 -0
  171. package/web-dist/icon-maskable-512.png +0 -0
  172. package/web-dist/index.html +33 -0
  173. package/web-dist/manifest.webmanifest +16 -0
  174. package/index.d.ts +0 -1
  175. package/index.js +0 -2
@@ -0,0 +1,354 @@
1
+ import { createRequire as __frizzCreateRequire } from "node:module"; const require = __frizzCreateRequire(import.meta.url);
2
+
3
+ // packages/server/src/backend/codex-app-server-daemon.ts
4
+ import { spawn } from "node:child_process";
5
+ import { createServer } from "node:net";
6
+ import { existsSync, readFileSync, unlinkSync as unlinkSync2, writeFileSync } from "node:fs";
7
+ import { dirname } from "node:path";
8
+ import { StringDecoder } from "node:string_decoder";
9
+
10
+ // packages/server/src/backend/stale-socket-sweep.ts
11
+ import { execFile } from "node:child_process";
12
+ import { readdirSync, unlinkSync } from "node:fs";
13
+ import { connect as connectSocket } from "node:net";
14
+ import { join } from "node:path";
15
+ var defaultListReferenced = (prefix, done) => {
16
+ execFile("lsof", ["-U", "-F", "n"], { timeout: 3e4, maxBuffer: 16 * 1024 * 1024 }, (error, stdout) => {
17
+ if (!stdout) return done(null);
18
+ if (error && !stdout.includes(prefix)) return done(null);
19
+ const referenced = /* @__PURE__ */ new Set();
20
+ for (const line of stdout.split("\n")) if (line.startsWith("n/")) referenced.add(line.slice(1));
21
+ done(referenced);
22
+ }).unref?.();
23
+ };
24
+ var defaultProbe = (path, verdict) => {
25
+ const probe = connectSocket(path);
26
+ probe.unref?.();
27
+ probe.on("connect", () => {
28
+ probe.destroy();
29
+ verdict(false);
30
+ });
31
+ probe.on("error", (error) => {
32
+ probe.destroy();
33
+ verdict(error.code === "ECONNREFUSED" || error.code === "ENOENT");
34
+ });
35
+ };
36
+ function sweepStaleSockets(options, deps = {}) {
37
+ if (process.platform === "win32") return;
38
+ const keep = new Set(options.keep ?? []);
39
+ let candidates;
40
+ try {
41
+ candidates = (deps.readdir ?? readdirSync)(options.dir).filter((name) => name.startsWith(options.prefix) && name.endsWith(".sock")).map((name) => join(options.dir, name)).filter((path) => !keep.has(path));
42
+ } catch {
43
+ return;
44
+ }
45
+ if (candidates.length === 0) return;
46
+ const probe = deps.probe ?? defaultProbe;
47
+ const unlink = deps.unlink ?? ((path) => {
48
+ try {
49
+ unlinkSync(path);
50
+ } catch {
51
+ }
52
+ });
53
+ (deps.listReferenced ?? defaultListReferenced)(options.prefix, (referenced) => {
54
+ if (!referenced) return;
55
+ for (const path of candidates) {
56
+ if (referenced.has(path)) continue;
57
+ probe(path, (dead) => {
58
+ if (dead) unlink(path);
59
+ });
60
+ }
61
+ });
62
+ }
63
+
64
+ // packages/server/src/backend/codex-app-server-daemon.ts
65
+ var MAX_QUEUED_LINES = 2e4;
66
+ var MAX_QUEUED_BYTES = 64 * 1024 * 1024;
67
+ var MAX_LINE_BYTES = 8 * 1024 * 1024;
68
+ var IDLE_EXIT_MS = 6 * 60 * 60 * 1e3;
69
+ var HANDSHAKE_TIMEOUT_MS = 3e4;
70
+ var REACHABILITY_CHECK_MS = 3e4;
71
+ var REACHABILITY_STRIKES = 2;
72
+ function readConfig() {
73
+ const raw = process.env.FRIZZ_CODEX_APP_SERVER_DAEMON;
74
+ if (!raw) throw new Error("codex app-server daemon started without FRIZZ_CODEX_APP_SERVER_DAEMON");
75
+ const config = JSON.parse(raw);
76
+ if (!config.socketPath || !config.recordPath || !config.codexBin || !config.generation) {
77
+ throw new Error("codex app-server daemon config is incomplete");
78
+ }
79
+ return config;
80
+ }
81
+ function lineReader(onLine) {
82
+ const decoder = new StringDecoder("utf8");
83
+ let buffer = "";
84
+ let overflowed = false;
85
+ return (chunk) => {
86
+ buffer += decoder.write(typeof chunk === "string" ? Buffer.from(chunk) : chunk);
87
+ for (; ; ) {
88
+ const index = buffer.indexOf("\n");
89
+ if (index < 0) break;
90
+ const line = buffer.slice(0, index);
91
+ buffer = buffer.slice(index + 1);
92
+ if (overflowed) {
93
+ overflowed = false;
94
+ continue;
95
+ }
96
+ const trimmed = line.trim();
97
+ if (trimmed) onLine(trimmed);
98
+ }
99
+ if (Buffer.byteLength(buffer) > MAX_LINE_BYTES) {
100
+ buffer = "";
101
+ overflowed = true;
102
+ }
103
+ };
104
+ }
105
+ function main() {
106
+ const config = readConfig();
107
+ const child = spawn(config.codexBin, config.appServerArgs ?? ["app-server", "--stdio"], {
108
+ cwd: config.cwd,
109
+ env: config.env,
110
+ stdio: ["pipe", "pipe", "pipe"]
111
+ });
112
+ let client = null;
113
+ let queuedLines = [];
114
+ let queuedBytes = 0;
115
+ let dropped = 0;
116
+ let idleTimer = null;
117
+ let published = false;
118
+ const recordOwner = () => {
119
+ try {
120
+ const value = JSON.parse(readFileSync(config.recordPath, "utf8"));
121
+ return typeof value.daemonPid === "number" ? value.daemonPid : null;
122
+ } catch {
123
+ return null;
124
+ }
125
+ };
126
+ const cleanup = () => {
127
+ try {
128
+ client?.destroy();
129
+ } catch {
130
+ }
131
+ const owner = recordOwner();
132
+ if (owner === process.pid) {
133
+ try {
134
+ unlinkSync2(config.recordPath);
135
+ } catch {
136
+ }
137
+ }
138
+ if (published && owner !== null && owner !== process.pid) return;
139
+ if (published && process.platform !== "win32") {
140
+ try {
141
+ unlinkSync2(config.socketPath);
142
+ } catch {
143
+ }
144
+ }
145
+ };
146
+ const writeExitBreadcrumb = (reason) => {
147
+ try {
148
+ writeFileSync(`${config.recordPath}.exit`, JSON.stringify({
149
+ projectId: config.projectId,
150
+ generation: config.generation,
151
+ daemonPid: process.pid,
152
+ childPid: child.pid ?? null,
153
+ reason,
154
+ at: (/* @__PURE__ */ new Date()).toISOString()
155
+ }));
156
+ } catch {
157
+ }
158
+ };
159
+ const die = (code, reason) => {
160
+ writeExitBreadcrumb(reason);
161
+ cleanup();
162
+ process.exit(code);
163
+ };
164
+ const armIdleExit = () => {
165
+ if (idleTimer) clearTimeout(idleTimer);
166
+ idleTimer = setTimeout(() => {
167
+ try {
168
+ child.kill("SIGTERM");
169
+ } catch {
170
+ }
171
+ ;
172
+ die(0, "idle-timeout");
173
+ }, IDLE_EXIT_MS);
174
+ idleTimer.unref?.();
175
+ };
176
+ let unreachableStrikes = 0;
177
+ const checkReachable = () => {
178
+ if (client) {
179
+ unreachableStrikes = 0;
180
+ return;
181
+ }
182
+ if (recordOwner() === process.pid) {
183
+ unreachableStrikes = 0;
184
+ return;
185
+ }
186
+ if (++unreachableStrikes < REACHABILITY_STRIKES) return;
187
+ try {
188
+ child.kill("SIGTERM");
189
+ } catch {
190
+ }
191
+ die(0, "self-collected-record-reassigned");
192
+ };
193
+ const toClient = (line) => {
194
+ if (client) {
195
+ try {
196
+ client.write(`${line}
197
+ `);
198
+ return;
199
+ } catch {
200
+ }
201
+ }
202
+ if (queuedLines.length >= MAX_QUEUED_LINES || queuedBytes >= MAX_QUEUED_BYTES) {
203
+ dropped++;
204
+ return;
205
+ }
206
+ queuedLines.push(line);
207
+ queuedBytes += Buffer.byteLength(line) + 1;
208
+ };
209
+ const control = (payload) => JSON.stringify({ frizz: 1, ...payload });
210
+ const HANDSHAKE_ID = -1;
211
+ let initializeResult;
212
+ let handshakeDone = false;
213
+ const pendingFromClient = /* @__PURE__ */ new Map();
214
+ let nextDaemonId = 1e6;
215
+ const toServer = (message) => {
216
+ try {
217
+ child.stdin.write(`${JSON.stringify(message)}
218
+ `);
219
+ } catch {
220
+ }
221
+ };
222
+ const readServerLine = (line) => {
223
+ let message;
224
+ try {
225
+ message = JSON.parse(line);
226
+ } catch {
227
+ return;
228
+ }
229
+ if (!handshakeDone && message.id === HANDSHAKE_ID) {
230
+ if (message.error) die(3, "handshake-rejected");
231
+ initializeResult = message.result;
232
+ handshakeDone = true;
233
+ toServer({ method: "initialized" });
234
+ startListening();
235
+ return;
236
+ }
237
+ if (message.id !== void 0 && message.method === void 0 && typeof message.id === "number") {
238
+ const clientId = pendingFromClient.get(message.id);
239
+ if (clientId !== void 0) {
240
+ pendingFromClient.delete(message.id);
241
+ toClient(JSON.stringify({ ...message, id: clientId }));
242
+ return;
243
+ }
244
+ }
245
+ toClient(line);
246
+ };
247
+ const readClientLine = (line) => {
248
+ let message;
249
+ try {
250
+ message = JSON.parse(line);
251
+ } catch {
252
+ return;
253
+ }
254
+ if (message.method === "initialize") {
255
+ if (message.id !== void 0) toClient(JSON.stringify({ id: message.id, result: initializeResult }));
256
+ return;
257
+ }
258
+ if (message.method === "initialized") return;
259
+ if (message.id !== void 0 && message.method !== void 0) {
260
+ const daemonId = nextDaemonId++;
261
+ pendingFromClient.set(daemonId, message.id);
262
+ toServer({ ...message, id: daemonId });
263
+ return;
264
+ }
265
+ toServer(message);
266
+ };
267
+ const writeRecord = () => {
268
+ writeFileSync(config.recordPath, JSON.stringify({
269
+ projectId: config.projectId,
270
+ generation: config.generation,
271
+ daemonPid: process.pid,
272
+ childPid: child.pid,
273
+ socketPath: config.socketPath,
274
+ createdAt: (/* @__PURE__ */ new Date()).toISOString()
275
+ }));
276
+ };
277
+ const server = createServer((sock) => {
278
+ if (client) {
279
+ try {
280
+ client.destroy();
281
+ } catch {
282
+ }
283
+ }
284
+ client = sock;
285
+ if (idleTimer) {
286
+ clearTimeout(idleTimer);
287
+ idleTimer = null;
288
+ }
289
+ sock.setNoDelay(true);
290
+ try {
291
+ sock.write(`${control({ hello: 1, generation: config.generation, childPid: child.pid, droppedWhileDetached: dropped })}
292
+ `);
293
+ for (const line of queuedLines) sock.write(`${line}
294
+ `);
295
+ } catch {
296
+ }
297
+ queuedLines = [];
298
+ queuedBytes = 0;
299
+ dropped = 0;
300
+ sock.on("data", lineReader(readClientLine));
301
+ const drop = () => {
302
+ if (client !== sock) return;
303
+ client = null;
304
+ armIdleExit();
305
+ };
306
+ sock.on("close", drop);
307
+ sock.on("error", drop);
308
+ });
309
+ const sweepOwnFamily = () => sweepStaleSockets({ dir: dirname(config.socketPath), prefix: "frizz-codex-", keep: [config.socketPath] });
310
+ const startListening = () => {
311
+ if (process.platform !== "win32" && existsSync(config.socketPath)) {
312
+ try {
313
+ unlinkSync2(config.socketPath);
314
+ } catch {
315
+ }
316
+ }
317
+ server.on("error", () => die(6, "socket-listen-error"));
318
+ server.listen(config.socketPath, () => {
319
+ published = true;
320
+ writeRecord();
321
+ armIdleExit();
322
+ const reachability = setInterval(checkReachable, config.reachabilityCheckMs ?? REACHABILITY_CHECK_MS);
323
+ reachability.unref?.();
324
+ setTimeout(sweepOwnFamily, 5e3).unref?.();
325
+ });
326
+ };
327
+ child.stdout.on("data", lineReader(readServerLine));
328
+ child.stderr.resume();
329
+ child.on("exit", (code, signal) => die(0, signal ? `app-server-killed-${signal}` : `app-server-exited-code-${code ?? "null"}`));
330
+ child.on("error", () => die(4, "app-server-spawn-error"));
331
+ toServer({ id: HANDSHAKE_ID, method: "initialize", params: { clientInfo: config.clientInfo, capabilities: config.capabilities } });
332
+ const handshakeTimer = setTimeout(() => {
333
+ if (!handshakeDone) {
334
+ try {
335
+ child.kill("SIGTERM");
336
+ } catch {
337
+ }
338
+ ;
339
+ die(5, "handshake-timeout");
340
+ }
341
+ }, HANDSHAKE_TIMEOUT_MS);
342
+ handshakeTimer.unref?.();
343
+ for (const signal of ["SIGTERM", "SIGINT", "SIGHUP"]) {
344
+ process.on(signal, () => {
345
+ try {
346
+ child.kill("SIGTERM");
347
+ } catch {
348
+ }
349
+ ;
350
+ die(0, `signal-${signal}`);
351
+ });
352
+ }
353
+ }
354
+ main();