@sajou/mcp-server 0.6.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 (130) hide show
  1. package/README.md +78 -0
  2. package/dist/app.d.ts +32 -0
  3. package/dist/app.d.ts.map +1 -0
  4. package/dist/app.js +76 -0
  5. package/dist/app.js.map +1 -0
  6. package/dist/index.d.ts +18 -0
  7. package/dist/index.d.ts.map +1 -0
  8. package/dist/index.js +65 -0
  9. package/dist/index.js.map +1 -0
  10. package/dist/mcp/transport.d.ts +18 -0
  11. package/dist/mcp/transport.d.ts.map +1 -0
  12. package/dist/mcp/transport.js +56 -0
  13. package/dist/mcp/transport.js.map +1 -0
  14. package/dist/middleware.d.ts +14 -0
  15. package/dist/middleware.d.ts.map +1 -0
  16. package/dist/middleware.js +14 -0
  17. package/dist/middleware.js.map +1 -0
  18. package/dist/routes/discovery.d.ts +8 -0
  19. package/dist/routes/discovery.d.ts.map +1 -0
  20. package/dist/routes/discovery.js +155 -0
  21. package/dist/routes/discovery.js.map +1 -0
  22. package/dist/routes/proxy.d.ts +10 -0
  23. package/dist/routes/proxy.d.ts.map +1 -0
  24. package/dist/routes/proxy.js +84 -0
  25. package/dist/routes/proxy.js.map +1 -0
  26. package/dist/routes/scene.d.ts +10 -0
  27. package/dist/routes/scene.d.ts.map +1 -0
  28. package/dist/routes/scene.js +298 -0
  29. package/dist/routes/scene.js.map +1 -0
  30. package/dist/routes/signals.d.ts +12 -0
  31. package/dist/routes/signals.d.ts.map +1 -0
  32. package/dist/routes/signals.js +61 -0
  33. package/dist/routes/signals.js.map +1 -0
  34. package/dist/routes/tap.d.ts +10 -0
  35. package/dist/routes/tap.d.ts.map +1 -0
  36. package/dist/routes/tap.js +115 -0
  37. package/dist/routes/tap.js.map +1 -0
  38. package/dist/server.d.ts +12 -0
  39. package/dist/server.d.ts.map +1 -0
  40. package/dist/server.js +103 -0
  41. package/dist/server.js.map +1 -0
  42. package/dist/state/mutations.d.ts +53 -0
  43. package/dist/state/mutations.d.ts.map +1 -0
  44. package/dist/state/mutations.js +409 -0
  45. package/dist/state/mutations.js.map +1 -0
  46. package/dist/state/store.d.ts +51 -0
  47. package/dist/state/store.d.ts.map +1 -0
  48. package/dist/state/store.js +149 -0
  49. package/dist/state/store.js.map +1 -0
  50. package/dist/tools/create-binding.d.ts +45 -0
  51. package/dist/tools/create-binding.d.ts.map +1 -0
  52. package/dist/tools/create-binding.js +82 -0
  53. package/dist/tools/create-binding.js.map +1 -0
  54. package/dist/tools/create-choreography.d.ts +76 -0
  55. package/dist/tools/create-choreography.d.ts.map +1 -0
  56. package/dist/tools/create-choreography.js +118 -0
  57. package/dist/tools/create-choreography.js.map +1 -0
  58. package/dist/tools/create-shader.d.ts +117 -0
  59. package/dist/tools/create-shader.d.ts.map +1 -0
  60. package/dist/tools/create-shader.js +150 -0
  61. package/dist/tools/create-shader.js.map +1 -0
  62. package/dist/tools/create-sketch.d.ts +96 -0
  63. package/dist/tools/create-sketch.d.ts.map +1 -0
  64. package/dist/tools/create-sketch.js +130 -0
  65. package/dist/tools/create-sketch.js.map +1 -0
  66. package/dist/tools/create-wire.d.ts +32 -0
  67. package/dist/tools/create-wire.d.ts.map +1 -0
  68. package/dist/tools/create-wire.js +84 -0
  69. package/dist/tools/create-wire.js.map +1 -0
  70. package/dist/tools/describe-scene.d.ts +22 -0
  71. package/dist/tools/describe-scene.d.ts.map +1 -0
  72. package/dist/tools/describe-scene.js +194 -0
  73. package/dist/tools/describe-scene.js.map +1 -0
  74. package/dist/tools/emit-signal.d.ts +36 -0
  75. package/dist/tools/emit-signal.d.ts.map +1 -0
  76. package/dist/tools/emit-signal.js +60 -0
  77. package/dist/tools/emit-signal.js.map +1 -0
  78. package/dist/tools/get-catalog.d.ts +27 -0
  79. package/dist/tools/get-catalog.d.ts.map +1 -0
  80. package/dist/tools/get-catalog.js +37 -0
  81. package/dist/tools/get-catalog.js.map +1 -0
  82. package/dist/tools/get-choreographies.d.ts +21 -0
  83. package/dist/tools/get-choreographies.d.ts.map +1 -0
  84. package/dist/tools/get-choreographies.js +70 -0
  85. package/dist/tools/get-choreographies.js.map +1 -0
  86. package/dist/tools/get-scene-state.d.ts +21 -0
  87. package/dist/tools/get-scene-state.d.ts.map +1 -0
  88. package/dist/tools/get-scene-state.js +48 -0
  89. package/dist/tools/get-scene-state.js.map +1 -0
  90. package/dist/tools/get-shaders.d.ts +16 -0
  91. package/dist/tools/get-shaders.d.ts.map +1 -0
  92. package/dist/tools/get-shaders.js +38 -0
  93. package/dist/tools/get-shaders.js.map +1 -0
  94. package/dist/tools/get-sketches.d.ts +16 -0
  95. package/dist/tools/get-sketches.d.ts.map +1 -0
  96. package/dist/tools/get-sketches.js +37 -0
  97. package/dist/tools/get-sketches.js.map +1 -0
  98. package/dist/tools/list-themes.d.ts +21 -0
  99. package/dist/tools/list-themes.d.ts.map +1 -0
  100. package/dist/tools/list-themes.js +32 -0
  101. package/dist/tools/list-themes.js.map +1 -0
  102. package/dist/tools/map-signals.d.ts +30 -0
  103. package/dist/tools/map-signals.d.ts.map +1 -0
  104. package/dist/tools/map-signals.js +44 -0
  105. package/dist/tools/map-signals.js.map +1 -0
  106. package/dist/tools/place-entity.d.ts +47 -0
  107. package/dist/tools/place-entity.d.ts.map +1 -0
  108. package/dist/tools/place-entity.js +85 -0
  109. package/dist/tools/place-entity.js.map +1 -0
  110. package/dist/tools/remove-item.d.ts +25 -0
  111. package/dist/tools/remove-item.d.ts.map +1 -0
  112. package/dist/tools/remove-item.js +55 -0
  113. package/dist/tools/remove-item.js.map +1 -0
  114. package/dist/tools/set-sketch-param.d.ts +29 -0
  115. package/dist/tools/set-sketch-param.d.ts.map +1 -0
  116. package/dist/tools/set-sketch-param.js +49 -0
  117. package/dist/tools/set-sketch-param.js.map +1 -0
  118. package/dist/tools/set-uniform.d.ts +29 -0
  119. package/dist/tools/set-uniform.d.ts.map +1 -0
  120. package/dist/tools/set-uniform.js +49 -0
  121. package/dist/tools/set-uniform.js.map +1 -0
  122. package/dist/tools/update-shader.d.ts +119 -0
  123. package/dist/tools/update-shader.d.ts.map +1 -0
  124. package/dist/tools/update-shader.js +81 -0
  125. package/dist/tools/update-shader.js.map +1 -0
  126. package/dist/tools/update-sketch.d.ts +99 -0
  127. package/dist/tools/update-sketch.d.ts.map +1 -0
  128. package/dist/tools/update-sketch.js +75 -0
  129. package/dist/tools/update-sketch.js.map +1 -0
  130. package/package.json +55 -0
@@ -0,0 +1,84 @@
1
+ /**
2
+ * CORS proxy route — forwards requests to external services.
3
+ *
4
+ * Extracted from corsProxyPlugin in vite.config.ts.
5
+ * Used by the browser to bypass CORS restrictions when probing
6
+ * LM Studio, Ollama, and other local services.
7
+ */
8
+ import { Router } from "express";
9
+ export function createProxyRoutes() {
10
+ const router = Router();
11
+ // GET/POST /__proxy/?target=<encoded-url>
12
+ router.all("/__proxy/", (req, res) => {
13
+ const target = req.query["target"];
14
+ if (!target) {
15
+ res.status(400).type("text/plain").send("Missing ?target= parameter");
16
+ return;
17
+ }
18
+ let targetUrl;
19
+ try {
20
+ targetUrl = new URL(target);
21
+ }
22
+ catch {
23
+ res.status(400).type("text/plain").send("Invalid target URL");
24
+ return;
25
+ }
26
+ // Build headers — forward auth-related headers
27
+ const headers = {};
28
+ for (const key of ["authorization", "content-type", "accept", "x-api-key", "anthropic-version"]) {
29
+ const val = req.headers[key];
30
+ if (val)
31
+ headers[key] = Array.isArray(val) ? val[0] : val;
32
+ }
33
+ const method = req.method ?? "GET";
34
+ const isBodyMethod = method !== "GET" && method !== "HEAD";
35
+ // Collect body for non-GET methods
36
+ const bodyChunks = [];
37
+ const doFetch = (body) => {
38
+ fetch(targetUrl.href, {
39
+ method,
40
+ headers,
41
+ body: isBodyMethod ? body : undefined,
42
+ })
43
+ .then(async (resp) => {
44
+ const respHeaders = {};
45
+ resp.headers.forEach((value, key) => {
46
+ if (key === "transfer-encoding" || key === "connection")
47
+ return;
48
+ respHeaders[key] = value;
49
+ });
50
+ respHeaders["access-control-allow-origin"] = "*";
51
+ res.writeHead(resp.status, respHeaders);
52
+ if (!resp.body) {
53
+ res.end();
54
+ return;
55
+ }
56
+ const reader = resp.body.getReader();
57
+ const pump = () => {
58
+ reader.read().then(({ done, value }) => {
59
+ if (done) {
60
+ res.end();
61
+ return;
62
+ }
63
+ res.write(Buffer.from(value));
64
+ pump();
65
+ }).catch(() => { res.end(); });
66
+ };
67
+ pump();
68
+ })
69
+ .catch((e) => {
70
+ res.writeHead(502, { "Content-Type": "text/plain" });
71
+ res.end(`Proxy error: ${e instanceof Error ? e.message : String(e)}`);
72
+ });
73
+ };
74
+ if (isBodyMethod) {
75
+ req.on("data", (chunk) => bodyChunks.push(chunk));
76
+ req.on("end", () => { doFetch(Buffer.concat(bodyChunks)); });
77
+ }
78
+ else {
79
+ doFetch(undefined);
80
+ }
81
+ });
82
+ return router;
83
+ }
84
+ //# sourceMappingURL=proxy.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"proxy.js","sourceRoot":"","sources":["../../src/routes/proxy.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Scene state routes — read state from store + write mutations directly.
3
+ *
4
+ * Combines the old stateSyncPlugin (GET reads) and commandQueuePlugin (POST writes).
5
+ * Key difference: POST endpoints now mutate the store directly instead of
6
+ * queuing commands for a browser client.
7
+ */
8
+ import { Router } from "express";
9
+ export declare function createSceneRoutes(): Router;
10
+ //# sourceMappingURL=scene.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scene.d.ts","sourceRoot":"","sources":["../../src/routes/scene.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AAsCjC,wBAAgB,iBAAiB,IAAI,MAAM,CAqT1C"}
@@ -0,0 +1,298 @@
1
+ /**
2
+ * Scene state routes — read state from store + write mutations directly.
3
+ *
4
+ * Combines the old stateSyncPlugin (GET reads) and commandQueuePlugin (POST writes).
5
+ * Key difference: POST endpoints now mutate the store directly instead of
6
+ * queuing commands for a browser client.
7
+ */
8
+ import { Router } from "express";
9
+ import { getFullState, getSceneSnapshot, getChoreographies, getWiring, getBindings, getSignalSources, getShaders, getP5, getEditor, getLastMutationAt, setFullState, subscribe, } from "../state/store.js";
10
+ import { executeCommand } from "../state/mutations.js";
11
+ // ---------------------------------------------------------------------------
12
+ // SSE for browser state updates
13
+ // ---------------------------------------------------------------------------
14
+ /** Active SSE clients for command/state change streaming. */
15
+ const commandClients = new Set();
16
+ /** Broadcast a state-change event to connected browsers. */
17
+ function broadcastStateChange(data) {
18
+ const frame = `event: state-change\ndata: ${JSON.stringify(data)}\n\n`;
19
+ for (const client of commandClients) {
20
+ client.write(frame);
21
+ }
22
+ }
23
+ // Subscribe to store changes to notify browsers
24
+ subscribe(() => {
25
+ broadcastStateChange({ version: Date.now() });
26
+ });
27
+ export function createSceneRoutes() {
28
+ const router = Router();
29
+ // -----------------------------------------------------------------------
30
+ // POST /api/state/push — browser pushes full state snapshot
31
+ // -----------------------------------------------------------------------
32
+ router.post("/api/state/push", (req, res) => {
33
+ const snapshot = req.body;
34
+ setFullState(snapshot);
35
+ res.json({ ok: true, receivedAt: Date.now() });
36
+ });
37
+ // -----------------------------------------------------------------------
38
+ // GET /api/scene/state — entities, positions, routes, dimensions, mode
39
+ // -----------------------------------------------------------------------
40
+ router.get("/api/scene/state", (_req, res) => {
41
+ const scene = getSceneSnapshot();
42
+ const editor = getEditor();
43
+ res.json({
44
+ ok: true,
45
+ lastPushAt: getLastMutationAt(),
46
+ data: {
47
+ dimensions: scene["dimensions"] ?? null,
48
+ background: scene["background"] ?? null,
49
+ layers: scene["layers"] ?? [],
50
+ entities: scene["entities"] ?? [],
51
+ positions: scene["positions"] ?? [],
52
+ routes: scene["routes"] ?? [],
53
+ zoneTypes: scene["zoneTypes"] ?? [],
54
+ lighting: scene["lighting"] ?? null,
55
+ particles: scene["particles"] ?? [],
56
+ mode: editor["activeTool"] ?? null,
57
+ viewMode: editor["viewMode"] ?? null,
58
+ },
59
+ });
60
+ });
61
+ // -----------------------------------------------------------------------
62
+ // GET /api/choreographies — enriched with wiring info
63
+ // -----------------------------------------------------------------------
64
+ router.get("/api/choreographies", (_req, res) => {
65
+ const choreoState = getChoreographies();
66
+ const choreographies = (choreoState["choreographies"] ?? []);
67
+ const wiringState = getWiring();
68
+ const wires = (wiringState["wires"] ?? []);
69
+ const enriched = choreographies.map((c) => {
70
+ const id = c["id"];
71
+ const incomingWires = wires.filter((w) => w["toZone"] === "choreographer" && w["toId"] === id && w["fromZone"] === "signal-type");
72
+ const wiredSignalTypes = incomingWires.map((w) => w["fromId"]);
73
+ const sourceWires = wires.filter((w) => w["fromZone"] === "signal" && w["toZone"] === "signal-type");
74
+ const sources = [];
75
+ for (const signalType of wiredSignalTypes) {
76
+ const sw = sourceWires.filter((w) => w["toId"] === signalType);
77
+ for (const w of sw) {
78
+ sources.push({ sourceId: w["fromId"], signalType });
79
+ }
80
+ }
81
+ const steps = (c["steps"] ?? []);
82
+ return {
83
+ id,
84
+ on: c["on"],
85
+ when: c["when"] ?? null,
86
+ interrupts: c["interrupts"] ?? false,
87
+ defaultTargetEntityId: c["defaultTargetEntityId"] ?? null,
88
+ stepCount: steps.length,
89
+ stepTypes: steps.map((s) => s["action"]),
90
+ wiredSignalTypes,
91
+ sources,
92
+ };
93
+ });
94
+ res.json({
95
+ ok: true,
96
+ lastPushAt: getLastMutationAt(),
97
+ data: { choreographies: enriched },
98
+ });
99
+ });
100
+ // -----------------------------------------------------------------------
101
+ // GET /api/bindings
102
+ // -----------------------------------------------------------------------
103
+ router.get("/api/bindings", (_req, res) => {
104
+ const bindingState = getBindings();
105
+ res.json({
106
+ ok: true,
107
+ lastPushAt: getLastMutationAt(),
108
+ data: { bindings: bindingState["bindings"] ?? [] },
109
+ });
110
+ });
111
+ // -----------------------------------------------------------------------
112
+ // GET /api/signals/sources
113
+ // -----------------------------------------------------------------------
114
+ router.get("/api/signals/sources", (_req, res) => {
115
+ const sourcesState = getSignalSources();
116
+ const sources = (sourcesState["sources"] ?? []).map((s) => ({
117
+ id: s["id"],
118
+ name: s["name"],
119
+ protocol: s["protocol"],
120
+ url: s["url"],
121
+ status: s["status"],
122
+ error: s["error"] ?? null,
123
+ category: s["category"],
124
+ eventsPerSecond: s["eventsPerSecond"] ?? 0,
125
+ streaming: s["streaming"] ?? false,
126
+ }));
127
+ res.json({
128
+ ok: true,
129
+ lastPushAt: getLastMutationAt(),
130
+ data: { sources },
131
+ });
132
+ });
133
+ // -----------------------------------------------------------------------
134
+ // GET /api/wiring
135
+ // -----------------------------------------------------------------------
136
+ router.get("/api/wiring", (_req, res) => {
137
+ const wiringState = getWiring();
138
+ const wires = (wiringState["wires"] ?? []);
139
+ res.json({
140
+ ok: true,
141
+ lastPushAt: getLastMutationAt(),
142
+ data: {
143
+ wires: wires.map((w) => ({
144
+ id: w["id"],
145
+ fromZone: w["fromZone"],
146
+ fromId: w["fromId"],
147
+ toZone: w["toZone"],
148
+ toId: w["toId"],
149
+ mapping: w["mapping"] ?? null,
150
+ })),
151
+ },
152
+ });
153
+ });
154
+ // -----------------------------------------------------------------------
155
+ // GET /api/shaders
156
+ // -----------------------------------------------------------------------
157
+ router.get("/api/shaders", (_req, res) => {
158
+ const shaderState = getShaders();
159
+ res.json({
160
+ ok: true,
161
+ lastPushAt: getLastMutationAt(),
162
+ data: { shaders: shaderState["shaders"] ?? [] },
163
+ });
164
+ });
165
+ // -----------------------------------------------------------------------
166
+ // GET /api/p5
167
+ // -----------------------------------------------------------------------
168
+ router.get("/api/p5", (_req, res) => {
169
+ const p5State = getP5();
170
+ res.json({
171
+ ok: true,
172
+ lastPushAt: getLastMutationAt(),
173
+ data: { sketches: p5State["sketches"] ?? [] },
174
+ });
175
+ });
176
+ // -----------------------------------------------------------------------
177
+ // Write endpoints — direct mutations (no command queue)
178
+ // -----------------------------------------------------------------------
179
+ // POST /api/scene/entities — add/remove/update
180
+ router.post("/api/scene/entities", (req, res) => {
181
+ const body = req.body;
182
+ const action = body["action"] ?? "add";
183
+ const data = body["data"] ?? body;
184
+ executeCommand({ action, type: "entity", data });
185
+ res.json({ ok: true, commandId: crypto.randomUUID() });
186
+ });
187
+ // POST /api/choreographies — add/remove/update
188
+ router.post("/api/choreographies", (req, res) => {
189
+ const body = req.body;
190
+ const action = body["action"] ?? "add";
191
+ const data = body["data"] ?? body;
192
+ executeCommand({ action, type: "choreography", data });
193
+ res.json({ ok: true, commandId: crypto.randomUUID() });
194
+ });
195
+ // POST /api/bindings — add/remove
196
+ router.post("/api/bindings", (req, res) => {
197
+ const body = req.body;
198
+ const action = body["action"] ?? "add";
199
+ const data = body["data"] ?? body;
200
+ executeCommand({ action, type: "binding", data });
201
+ res.json({ ok: true, commandId: crypto.randomUUID() });
202
+ });
203
+ // POST /api/wiring — add/remove
204
+ router.post("/api/wiring", (req, res) => {
205
+ const body = req.body;
206
+ const action = body["action"] ?? "add";
207
+ const data = body["data"] ?? body;
208
+ executeCommand({ action, type: "wire", data });
209
+ res.json({ ok: true, commandId: crypto.randomUUID() });
210
+ });
211
+ // POST /api/signals/sources — add/remove
212
+ router.post("/api/signals/sources", (req, res) => {
213
+ const body = req.body;
214
+ const action = body["action"] ?? "add";
215
+ const data = body["data"] ?? body;
216
+ executeCommand({ action, type: "source", data });
217
+ res.json({ ok: true, commandId: crypto.randomUUID() });
218
+ });
219
+ // POST /api/shaders — add
220
+ router.post("/api/shaders", (req, res) => {
221
+ const body = req.body;
222
+ executeCommand({ action: "add", type: "shader", data: body });
223
+ res.json({ ok: true, commandId: crypto.randomUUID() });
224
+ });
225
+ // PUT /api/shaders/:id — update
226
+ router.put("/api/shaders/:id", (req, res) => {
227
+ const body = req.body;
228
+ executeCommand({ action: "update", type: "shader", data: { ...body, id: req.params["id"] } });
229
+ res.json({ ok: true, commandId: crypto.randomUUID() });
230
+ });
231
+ // DELETE /api/shaders/:id — remove
232
+ router.delete("/api/shaders/:id", (req, res) => {
233
+ executeCommand({ action: "remove", type: "shader", data: { id: req.params["id"] } });
234
+ res.json({ ok: true, commandId: crypto.randomUUID() });
235
+ });
236
+ // POST /api/shaders/:id/uniforms — set-uniform
237
+ router.post("/api/shaders/:id/uniforms", (req, res) => {
238
+ const body = req.body;
239
+ executeCommand({ action: "set-uniform", type: "shader", data: { ...body, id: req.params["id"] } });
240
+ res.json({ ok: true, commandId: crypto.randomUUID() });
241
+ });
242
+ // POST /api/p5 — add
243
+ router.post("/api/p5", (req, res) => {
244
+ const body = req.body;
245
+ executeCommand({ action: "add", type: "p5", data: body });
246
+ res.json({ ok: true, commandId: crypto.randomUUID() });
247
+ });
248
+ // PUT /api/p5/:id — update
249
+ router.put("/api/p5/:id", (req, res) => {
250
+ const body = req.body;
251
+ executeCommand({ action: "update", type: "p5", data: { ...body, id: req.params["id"] } });
252
+ res.json({ ok: true, commandId: crypto.randomUUID() });
253
+ });
254
+ // DELETE /api/p5/:id — remove
255
+ router.delete("/api/p5/:id", (req, res) => {
256
+ executeCommand({ action: "remove", type: "p5", data: { id: req.params["id"] } });
257
+ res.json({ ok: true, commandId: crypto.randomUUID() });
258
+ });
259
+ // POST /api/p5/:id/params — set-param
260
+ router.post("/api/p5/:id/params", (req, res) => {
261
+ const body = req.body;
262
+ executeCommand({ action: "set-param", type: "p5", data: { ...body, id: req.params["id"] } });
263
+ res.json({ ok: true, commandId: crypto.randomUUID() });
264
+ });
265
+ // -----------------------------------------------------------------------
266
+ // SSE for browser command streaming (backwards compat)
267
+ // -----------------------------------------------------------------------
268
+ router.get("/__commands__/stream", (req, res) => {
269
+ res.writeHead(200, {
270
+ "Content-Type": "text/event-stream",
271
+ "Cache-Control": "no-cache",
272
+ "Connection": "keep-alive",
273
+ });
274
+ res.write(": connected\n\n");
275
+ commandClients.add(res);
276
+ req.on("close", () => {
277
+ commandClients.delete(res);
278
+ });
279
+ });
280
+ // GET /api/commands/pending — polling fallback (empty, mutations are instant)
281
+ router.get("/api/commands/pending", (_req, res) => {
282
+ res.json({ ok: true, commands: [] });
283
+ });
284
+ // POST /api/commands/ack — no-op (mutations are instant)
285
+ router.post("/api/commands/ack", (_req, res) => {
286
+ res.json({ ok: true, pruned: 0 });
287
+ });
288
+ // GET /api/state/full — returns full state (for browser init)
289
+ router.get("/api/state/full", (_req, res) => {
290
+ res.json({
291
+ ok: true,
292
+ lastPushAt: getLastMutationAt(),
293
+ data: getFullState(),
294
+ });
295
+ });
296
+ return router;
297
+ }
298
+ //# sourceMappingURL=scene.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scene.js","sourceRoot":"","sources":["../../src/routes/scene.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AAEjC,OAAO,EACL,YAAY,EACZ,gBAAgB,EAChB,iBAAiB,EACjB,SAAS,EACT,WAAW,EACX,gBAAgB,EAChB,UAAU,EACV,KAAK,EACL,SAAS,EACT,iBAAiB,EACjB,YAAY,EACZ,SAAS,GACV,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAEvD,8EAA8E;AAC9E,gCAAgC;AAChC,8EAA8E;AAE9E,6DAA6D;AAC7D,MAAM,cAAc,GAAG,IAAI,GAAG,EAAY,CAAC;AAE3C,4DAA4D;AAC5D,SAAS,oBAAoB,CAAC,IAA6B;IACzD,MAAM,KAAK,GAAG,8BAA8B,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,MAAM,CAAC;IACvE,KAAK,MAAM,MAAM,IAAI,cAAc,EAAE,CAAC;QACpC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IACtB,CAAC;AACH,CAAC;AAED,gDAAgD;AAChD,SAAS,CAAC,GAAG,EAAE;IACb,oBAAoB,CAAC,EAAE,OAAO,EAAE,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;AAChD,CAAC,CAAC,CAAC;AAEH,MAAM,UAAU,iBAAiB;IAC/B,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC;IAExB,0EAA0E;IAC1E,4DAA4D;IAC5D,0EAA0E;IAC1E,MAAM,CAAC,IAAI,CAAC,iBAAiB,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE;QAC1C,MAAM,QAAQ,GAAG,GAAG,CAAC,IAA+B,CAAC;QACrD,YAAY,CAAC,QAAQ,CAAC,CAAC;QACvB,GAAG,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,UAAU,EAAE,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;IACjD,CAAC,CAAC,CAAC;IAEH,0EAA0E;IAC1E,uEAAuE;IACvE,0EAA0E;IAC1E,MAAM,CAAC,GAAG,CAAC,kBAAkB,EAAE,CAAC,IAAI,EAAE,GAAG,EAAE,EAAE;QAC3C,MAAM,KAAK,GAAG,gBAAgB,EAAE,CAAC;QACjC,MAAM,MAAM,GAAG,SAAS,EAAE,CAAC;QAE3B,GAAG,CAAC,IAAI,CAAC;YACP,EAAE,EAAE,IAAI;YACR,UAAU,EAAE,iBAAiB,EAAE;YAC/B,IAAI,EAAE;gBACJ,UAAU,EAAE,KAAK,CAAC,YAAY,CAAC,IAAI,IAAI;gBACvC,UAAU,EAAE,KAAK,CAAC,YAAY,CAAC,IAAI,IAAI;gBACvC,MAAM,EAAE,KAAK,CAAC,QAAQ,CAAC,IAAI,EAAE;gBAC7B,QAAQ,EAAE,KAAK,CAAC,UAAU,CAAC,IAAI,EAAE;gBACjC,SAAS,EAAE,KAAK,CAAC,WAAW,CAAC,IAAI,EAAE;gBACnC,MAAM,EAAE,KAAK,CAAC,QAAQ,CAAC,IAAI,EAAE;gBAC7B,SAAS,EAAE,KAAK,CAAC,WAAW,CAAC,IAAI,EAAE;gBACnC,QAAQ,EAAE,KAAK,CAAC,UAAU,CAAC,IAAI,IAAI;gBACnC,SAAS,EAAE,KAAK,CAAC,WAAW,CAAC,IAAI,EAAE;gBACnC,IAAI,EAAE,MAAM,CAAC,YAAY,CAAC,IAAI,IAAI;gBAClC,QAAQ,EAAE,MAAM,CAAC,UAAU,CAAC,IAAI,IAAI;aACrC;SACF,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,0EAA0E;IAC1E,sDAAsD;IACtD,0EAA0E;IAC1E,MAAM,CAAC,GAAG,CAAC,qBAAqB,EAAE,CAAC,IAAI,EAAE,GAAG,EAAE,EAAE;QAC9C,MAAM,WAAW,GAAG,iBAAiB,EAAE,CAAC;QACxC,MAAM,cAAc,GAAG,CAAC,WAAW,CAAC,gBAAgB,CAAC,IAAI,EAAE,CAAmC,CAAC;QAC/F,MAAM,WAAW,GAAG,SAAS,EAAE,CAAC;QAChC,MAAM,KAAK,GAAG,CAAC,WAAW,CAAC,OAAO,CAAC,IAAI,EAAE,CAAmC,CAAC;QAE7E,MAAM,QAAQ,GAAG,cAAc,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE;YACxC,MAAM,EAAE,GAAG,CAAC,CAAC,IAAI,CAAW,CAAC;YAC7B,MAAM,aAAa,GAAG,KAAK,CAAC,MAAM,CAChC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,eAAe,IAAI,CAAC,CAAC,MAAM,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC,UAAU,CAAC,KAAK,aAAa,CAC9F,CAAC;YACF,MAAM,gBAAgB,GAAG,aAAa,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAW,CAAC,CAAC;YAEzE,MAAM,WAAW,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,KAAK,QAAQ,IAAI,CAAC,CAAC,QAAQ,CAAC,KAAK,aAAa,CAAC,CAAC;YACrG,MAAM,OAAO,GAAoD,EAAE,CAAC;YACpE,KAAK,MAAM,UAAU,IAAI,gBAAgB,EAAE,CAAC;gBAC1C,MAAM,EAAE,GAAG,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,UAAU,CAAC,CAAC;gBAC/D,KAAK,MAAM,CAAC,IAAI,EAAE,EAAE,CAAC;oBACnB,OAAO,CAAC,IAAI,CAAC,EAAE,QAAQ,EAAE,CAAC,CAAC,QAAQ,CAAW,EAAE,UAAU,EAAE,CAAC,CAAC;gBAChE,CAAC;YACH,CAAC;YAED,MAAM,KAAK,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,CAAmC,CAAC;YAEnE,OAAO;gBACL,EAAE;gBACF,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC;gBACX,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,IAAI,IAAI;gBACvB,UAAU,EAAE,CAAC,CAAC,YAAY,CAAC,IAAI,KAAK;gBACpC,qBAAqB,EAAE,CAAC,CAAC,uBAAuB,CAAC,IAAI,IAAI;gBACzD,SAAS,EAAE,KAAK,CAAC,MAAM;gBACvB,SAAS,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAW,CAAC;gBAClD,gBAAgB;gBAChB,OAAO;aACR,CAAC;QACJ,CAAC,CAAC,CAAC;QAEH,GAAG,CAAC,IAAI,CAAC;YACP,EAAE,EAAE,IAAI;YACR,UAAU,EAAE,iBAAiB,EAAE;YAC/B,IAAI,EAAE,EAAE,cAAc,EAAE,QAAQ,EAAE;SACnC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,0EAA0E;IAC1E,oBAAoB;IACpB,0EAA0E;IAC1E,MAAM,CAAC,GAAG,CAAC,eAAe,EAAE,CAAC,IAAI,EAAE,GAAG,EAAE,EAAE;QACxC,MAAM,YAAY,GAAG,WAAW,EAAE,CAAC;QACnC,GAAG,CAAC,IAAI,CAAC;YACP,EAAE,EAAE,IAAI;YACR,UAAU,EAAE,iBAAiB,EAAE;YAC/B,IAAI,EAAE,EAAE,QAAQ,EAAE,YAAY,CAAC,UAAU,CAAC,IAAI,EAAE,EAAE;SACnD,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,0EAA0E;IAC1E,2BAA2B;IAC3B,0EAA0E;IAC1E,MAAM,CAAC,GAAG,CAAC,sBAAsB,EAAE,CAAC,IAAI,EAAE,GAAG,EAAE,EAAE;QAC/C,MAAM,YAAY,GAAG,gBAAgB,EAAE,CAAC;QACxC,MAAM,OAAO,GAAI,CAAC,YAAY,CAAC,SAAS,CAAC,IAAI,EAAE,CAAoC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YAC9F,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC;YACX,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC;YACf,QAAQ,EAAE,CAAC,CAAC,UAAU,CAAC;YACvB,GAAG,EAAE,CAAC,CAAC,KAAK,CAAC;YACb,MAAM,EAAE,CAAC,CAAC,QAAQ,CAAC;YACnB,KAAK,EAAE,CAAC,CAAC,OAAO,CAAC,IAAI,IAAI;YACzB,QAAQ,EAAE,CAAC,CAAC,UAAU,CAAC;YACvB,eAAe,EAAE,CAAC,CAAC,iBAAiB,CAAC,IAAI,CAAC;YAC1C,SAAS,EAAE,CAAC,CAAC,WAAW,CAAC,IAAI,KAAK;SACnC,CAAC,CAAC,CAAC;QAEJ,GAAG,CAAC,IAAI,CAAC;YACP,EAAE,EAAE,IAAI;YACR,UAAU,EAAE,iBAAiB,EAAE;YAC/B,IAAI,EAAE,EAAE,OAAO,EAAE;SAClB,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,0EAA0E;IAC1E,kBAAkB;IAClB,0EAA0E;IAC1E,MAAM,CAAC,GAAG,CAAC,aAAa,EAAE,CAAC,IAAI,EAAE,GAAG,EAAE,EAAE;QACtC,MAAM,WAAW,GAAG,SAAS,EAAE,CAAC;QAChC,MAAM,KAAK,GAAG,CAAC,WAAW,CAAC,OAAO,CAAC,IAAI,EAAE,CAAmC,CAAC;QAE7E,GAAG,CAAC,IAAI,CAAC;YACP,EAAE,EAAE,IAAI;YACR,UAAU,EAAE,iBAAiB,EAAE;YAC/B,IAAI,EAAE;gBACJ,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;oBACvB,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC;oBACX,QAAQ,EAAE,CAAC,CAAC,UAAU,CAAC;oBACvB,MAAM,EAAE,CAAC,CAAC,QAAQ,CAAC;oBACnB,MAAM,EAAE,CAAC,CAAC,QAAQ,CAAC;oBACnB,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC;oBACf,OAAO,EAAE,CAAC,CAAC,SAAS,CAAC,IAAI,IAAI;iBAC9B,CAAC,CAAC;aACJ;SACF,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,0EAA0E;IAC1E,mBAAmB;IACnB,0EAA0E;IAC1E,MAAM,CAAC,GAAG,CAAC,cAAc,EAAE,CAAC,IAAI,EAAE,GAAG,EAAE,EAAE;QACvC,MAAM,WAAW,GAAG,UAAU,EAAE,CAAC;QACjC,GAAG,CAAC,IAAI,CAAC;YACP,EAAE,EAAE,IAAI;YACR,UAAU,EAAE,iBAAiB,EAAE;YAC/B,IAAI,EAAE,EAAE,OAAO,EAAE,WAAW,CAAC,SAAS,CAAC,IAAI,EAAE,EAAE;SAChD,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,0EAA0E;IAC1E,cAAc;IACd,0EAA0E;IAC1E,MAAM,CAAC,GAAG,CAAC,SAAS,EAAE,CAAC,IAAI,EAAE,GAAG,EAAE,EAAE;QAClC,MAAM,OAAO,GAAG,KAAK,EAAE,CAAC;QACxB,GAAG,CAAC,IAAI,CAAC;YACP,EAAE,EAAE,IAAI;YACR,UAAU,EAAE,iBAAiB,EAAE;YAC/B,IAAI,EAAE,EAAE,QAAQ,EAAE,OAAO,CAAC,UAAU,CAAC,IAAI,EAAE,EAAE;SAC9C,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,0EAA0E;IAC1E,wDAAwD;IACxD,0EAA0E;IAE1E,+CAA+C;IAC/C,MAAM,CAAC,IAAI,CAAC,qBAAqB,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE;QAC9C,MAAM,IAAI,GAAG,GAAG,CAAC,IAA+B,CAAC;QACjD,MAAM,MAAM,GAAI,IAAI,CAAC,QAAQ,CAAY,IAAI,KAAK,CAAC;QACnD,MAAM,IAAI,GAAI,IAAI,CAAC,MAAM,CAA6B,IAAI,IAAI,CAAC;QAC/D,cAAc,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC;QACjD,GAAG,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC;IACzD,CAAC,CAAC,CAAC;IAEH,+CAA+C;IAC/C,MAAM,CAAC,IAAI,CAAC,qBAAqB,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE;QAC9C,MAAM,IAAI,GAAG,GAAG,CAAC,IAA+B,CAAC;QACjD,MAAM,MAAM,GAAI,IAAI,CAAC,QAAQ,CAAY,IAAI,KAAK,CAAC;QACnD,MAAM,IAAI,GAAI,IAAI,CAAC,MAAM,CAA6B,IAAI,IAAI,CAAC;QAC/D,cAAc,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,cAAc,EAAE,IAAI,EAAE,CAAC,CAAC;QACvD,GAAG,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC;IACzD,CAAC,CAAC,CAAC;IAEH,kCAAkC;IAClC,MAAM,CAAC,IAAI,CAAC,eAAe,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE;QACxC,MAAM,IAAI,GAAG,GAAG,CAAC,IAA+B,CAAC;QACjD,MAAM,MAAM,GAAI,IAAI,CAAC,QAAQ,CAAY,IAAI,KAAK,CAAC;QACnD,MAAM,IAAI,GAAI,IAAI,CAAC,MAAM,CAA6B,IAAI,IAAI,CAAC;QAC/D,cAAc,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAClD,GAAG,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC;IACzD,CAAC,CAAC,CAAC;IAEH,gCAAgC;IAChC,MAAM,CAAC,IAAI,CAAC,aAAa,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE;QACtC,MAAM,IAAI,GAAG,GAAG,CAAC,IAA+B,CAAC;QACjD,MAAM,MAAM,GAAI,IAAI,CAAC,QAAQ,CAAY,IAAI,KAAK,CAAC;QACnD,MAAM,IAAI,GAAI,IAAI,CAAC,MAAM,CAA6B,IAAI,IAAI,CAAC;QAC/D,cAAc,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;QAC/C,GAAG,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC;IACzD,CAAC,CAAC,CAAC;IAEH,yCAAyC;IACzC,MAAM,CAAC,IAAI,CAAC,sBAAsB,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE;QAC/C,MAAM,IAAI,GAAG,GAAG,CAAC,IAA+B,CAAC;QACjD,MAAM,MAAM,GAAI,IAAI,CAAC,QAAQ,CAAY,IAAI,KAAK,CAAC;QACnD,MAAM,IAAI,GAAI,IAAI,CAAC,MAAM,CAA6B,IAAI,IAAI,CAAC;QAC/D,cAAc,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC;QACjD,GAAG,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC;IACzD,CAAC,CAAC,CAAC;IAEH,0BAA0B;IAC1B,MAAM,CAAC,IAAI,CAAC,cAAc,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE;QACvC,MAAM,IAAI,GAAG,GAAG,CAAC,IAA+B,CAAC;QACjD,cAAc,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;QAC9D,GAAG,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC;IACzD,CAAC,CAAC,CAAC;IAEH,gCAAgC;IAChC,MAAM,CAAC,GAAG,CAAC,kBAAkB,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE;QAC1C,MAAM,IAAI,GAAG,GAAG,CAAC,IAA+B,CAAC;QACjD,cAAc,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,EAAE,GAAG,IAAI,EAAE,EAAE,EAAE,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC;QAC9F,GAAG,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC;IACzD,CAAC,CAAC,CAAC;IAEH,mCAAmC;IACnC,MAAM,CAAC,MAAM,CAAC,kBAAkB,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE;QAC7C,cAAc,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,EAAE,EAAE,EAAE,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC;QACrF,GAAG,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC;IACzD,CAAC,CAAC,CAAC;IAEH,+CAA+C;IAC/C,MAAM,CAAC,IAAI,CAAC,2BAA2B,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE;QACpD,MAAM,IAAI,GAAG,GAAG,CAAC,IAA+B,CAAC;QACjD,cAAc,CAAC,EAAE,MAAM,EAAE,aAAa,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,EAAE,GAAG,IAAI,EAAE,EAAE,EAAE,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC;QACnG,GAAG,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC;IACzD,CAAC,CAAC,CAAC;IAEH,qBAAqB;IACrB,MAAM,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE;QAClC,MAAM,IAAI,GAAG,GAAG,CAAC,IAA+B,CAAC;QACjD,cAAc,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;QAC1D,GAAG,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC;IACzD,CAAC,CAAC,CAAC;IAEH,2BAA2B;IAC3B,MAAM,CAAC,GAAG,CAAC,aAAa,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE;QACrC,MAAM,IAAI,GAAG,GAAG,CAAC,IAA+B,CAAC;QACjD,cAAc,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE,GAAG,IAAI,EAAE,EAAE,EAAE,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC;QAC1F,GAAG,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC;IACzD,CAAC,CAAC,CAAC;IAEH,8BAA8B;IAC9B,MAAM,CAAC,MAAM,CAAC,aAAa,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE;QACxC,cAAc,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE,EAAE,EAAE,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC;QACjF,GAAG,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC;IACzD,CAAC,CAAC,CAAC;IAEH,sCAAsC;IACtC,MAAM,CAAC,IAAI,CAAC,oBAAoB,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE;QAC7C,MAAM,IAAI,GAAG,GAAG,CAAC,IAA+B,CAAC;QACjD,cAAc,CAAC,EAAE,MAAM,EAAE,WAAW,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE,GAAG,IAAI,EAAE,EAAE,EAAE,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC;QAC7F,GAAG,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC;IACzD,CAAC,CAAC,CAAC;IAEH,0EAA0E;IAC1E,uDAAuD;IACvD,0EAA0E;IAE1E,MAAM,CAAC,GAAG,CAAC,sBAAsB,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE;QAC9C,GAAG,CAAC,SAAS,CAAC,GAAG,EAAE;YACjB,cAAc,EAAE,mBAAmB;YACnC,eAAe,EAAE,UAAU;YAC3B,YAAY,EAAE,YAAY;SAC3B,CAAC,CAAC;QACH,GAAG,CAAC,KAAK,CAAC,iBAAiB,CAAC,CAAC;QAE7B,cAAc,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QACxB,GAAG,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE;YACnB,cAAc,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QAC7B,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,8EAA8E;IAC9E,MAAM,CAAC,GAAG,CAAC,uBAAuB,EAAE,CAAC,IAAI,EAAE,GAAG,EAAE,EAAE;QAChD,GAAG,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC,CAAC;IACvC,CAAC,CAAC,CAAC;IAEH,yDAAyD;IACzD,MAAM,CAAC,IAAI,CAAC,mBAAmB,EAAE,CAAC,IAAI,EAAE,GAAG,EAAE,EAAE;QAC7C,GAAG,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC,CAAC;IACpC,CAAC,CAAC,CAAC;IAEH,8DAA8D;IAC9D,MAAM,CAAC,GAAG,CAAC,iBAAiB,EAAE,CAAC,IAAI,EAAE,GAAG,EAAE,EAAE;QAC1C,GAAG,CAAC,IAAI,CAAC;YACP,EAAE,EAAE,IAAI;YACR,UAAU,EAAE,iBAAiB,EAAE;YAC/B,IAAI,EAAE,YAAY,EAAE;SACrB,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,OAAO,MAAM,CAAC;AAChB,CAAC"}
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Signal ingestion routes — HTTP POST → SSE broadcast.
3
+ *
4
+ * Extracted from the signalIngestionPlugin in vite.config.ts.
5
+ */
6
+ import { Router } from "express";
7
+ /** Broadcast a JSON string to all connected SSE clients. */
8
+ export declare function broadcastSignal(json: string): void;
9
+ /** Get the number of connected SSE signal clients. */
10
+ export declare function getSignalClientCount(): number;
11
+ export declare function createSignalRoutes(): Router;
12
+ //# sourceMappingURL=signals.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"signals.d.ts","sourceRoot":"","sources":["../../src/routes/signals.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AAMjC,4DAA4D;AAC5D,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAKlD;AAED,sDAAsD;AACtD,wBAAgB,oBAAoB,IAAI,MAAM,CAE7C;AAED,wBAAgB,kBAAkB,IAAI,MAAM,CA2C3C"}
@@ -0,0 +1,61 @@
1
+ /**
2
+ * Signal ingestion routes — HTTP POST → SSE broadcast.
3
+ *
4
+ * Extracted from the signalIngestionPlugin in vite.config.ts.
5
+ */
6
+ import { Router } from "express";
7
+ /** Active SSE client connections for signal streaming. */
8
+ const sseClients = new Set();
9
+ /** Broadcast a JSON string to all connected SSE clients. */
10
+ export function broadcastSignal(json) {
11
+ const frame = `data: ${json}\n\n`;
12
+ for (const client of sseClients) {
13
+ client.write(frame);
14
+ }
15
+ }
16
+ /** Get the number of connected SSE signal clients. */
17
+ export function getSignalClientCount() {
18
+ return sseClients.size;
19
+ }
20
+ export function createSignalRoutes() {
21
+ const router = Router();
22
+ // POST /api/signal — receive & broadcast
23
+ router.post("/api/signal", (req, res) => {
24
+ const body = req.body;
25
+ // Normalise: wrap raw JSON without "type" into { type: "event", payload: body }
26
+ let envelope;
27
+ if (typeof body["type"] === "string") {
28
+ envelope = { ...body };
29
+ }
30
+ else {
31
+ envelope = { type: "event", payload: body };
32
+ }
33
+ // Fill defaults
34
+ if (!envelope["id"])
35
+ envelope["id"] = crypto.randomUUID();
36
+ if (!envelope["timestamp"])
37
+ envelope["timestamp"] = Date.now();
38
+ if (!envelope["source"])
39
+ envelope["source"] = "http";
40
+ if (!envelope["payload"])
41
+ envelope["payload"] = {};
42
+ const json = JSON.stringify(envelope);
43
+ broadcastSignal(json);
44
+ res.json({ ok: true, id: envelope["id"], clients: sseClients.size });
45
+ });
46
+ // GET /__signals__/stream — SSE endpoint
47
+ router.get("/__signals__/stream", (req, res) => {
48
+ res.writeHead(200, {
49
+ "Content-Type": "text/event-stream",
50
+ "Cache-Control": "no-cache",
51
+ "Connection": "keep-alive",
52
+ });
53
+ res.write(": connected\n\n");
54
+ sseClients.add(res);
55
+ req.on("close", () => {
56
+ sseClients.delete(res);
57
+ });
58
+ });
59
+ return router;
60
+ }
61
+ //# sourceMappingURL=signals.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"signals.js","sourceRoot":"","sources":["../../src/routes/signals.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AAGjC,0DAA0D;AAC1D,MAAM,UAAU,GAAG,IAAI,GAAG,EAAY,CAAC;AAEvC,4DAA4D;AAC5D,MAAM,UAAU,eAAe,CAAC,IAAY;IAC1C,MAAM,KAAK,GAAG,SAAS,IAAI,MAAM,CAAC;IAClC,KAAK,MAAM,MAAM,IAAI,UAAU,EAAE,CAAC;QAChC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IACtB,CAAC;AACH,CAAC;AAED,sDAAsD;AACtD,MAAM,UAAU,oBAAoB;IAClC,OAAO,UAAU,CAAC,IAAI,CAAC;AACzB,CAAC;AAED,MAAM,UAAU,kBAAkB;IAChC,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC;IAExB,yCAAyC;IACzC,MAAM,CAAC,IAAI,CAAC,aAAa,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE;QACtC,MAAM,IAAI,GAAG,GAAG,CAAC,IAA+B,CAAC;QAEjD,gFAAgF;QAChF,IAAI,QAAiC,CAAC;QACtC,IAAI,OAAO,IAAI,CAAC,MAAM,CAAC,KAAK,QAAQ,EAAE,CAAC;YACrC,QAAQ,GAAG,EAAE,GAAG,IAAI,EAAE,CAAC;QACzB,CAAC;aAAM,CAAC;YACN,QAAQ,GAAG,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;QAC9C,CAAC;QAED,gBAAgB;QAChB,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC;YAAE,QAAQ,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,UAAU,EAAE,CAAC;QAC1D,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC;YAAE,QAAQ,CAAC,WAAW,CAAC,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAC/D,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC;YAAE,QAAQ,CAAC,QAAQ,CAAC,GAAG,MAAM,CAAC;QACrD,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC;YAAE,QAAQ,CAAC,SAAS,CAAC,GAAG,EAAE,CAAC;QAEnD,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC;QACtC,eAAe,CAAC,IAAI,CAAC,CAAC;QAEtB,GAAG,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE,QAAQ,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,UAAU,CAAC,IAAI,EAAE,CAAC,CAAC;IACvE,CAAC,CAAC,CAAC;IAEH,yCAAyC;IACzC,MAAM,CAAC,GAAG,CAAC,qBAAqB,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE;QAC7C,GAAG,CAAC,SAAS,CAAC,GAAG,EAAE;YACjB,cAAc,EAAE,mBAAmB;YACnC,eAAe,EAAE,UAAU;YAC3B,YAAY,EAAE,YAAY;SAC3B,CAAC,CAAC;QACH,GAAG,CAAC,KAAK,CAAC,iBAAiB,CAAC,CAAC;QAE7B,UAAU,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QACpB,GAAG,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE;YACnB,UAAU,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QACzB,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,OAAO,MAAM,CAAC;AAChB,CAAC"}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Tap hook management routes — install/uninstall Claude Code hooks.
3
+ *
4
+ * Extracted from tapHookPlugin in vite.config.ts.
5
+ */
6
+ import { Router } from "express";
7
+ /** Clean up hooks on process exit. */
8
+ export declare function cleanupTapHooks(): void;
9
+ export declare function createTapRoutes(): Router;
10
+ //# sourceMappingURL=tap.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tap.d.ts","sourceRoot":"","sources":["../../src/routes/tap.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AA+EjC,sCAAsC;AACtC,wBAAgB,eAAe,IAAI,IAAI,CAKtC;AAMD,wBAAgB,eAAe,IAAI,MAAM,CA4BxC"}
@@ -0,0 +1,115 @@
1
+ /**
2
+ * Tap hook management routes — install/uninstall Claude Code hooks.
3
+ *
4
+ * Extracted from tapHookPlugin in vite.config.ts.
5
+ */
6
+ import { Router } from "express";
7
+ import { readFile, writeFile, mkdir, stat } from "node:fs/promises";
8
+ import { join, dirname } from "node:path";
9
+ // ---------------------------------------------------------------------------
10
+ // Tap hook config
11
+ // ---------------------------------------------------------------------------
12
+ const TAP_HOOK_TAG = "sajou-tap";
13
+ const TAP_HOOK_EVENTS = ["PreToolUse", "PostToolUse", "PostToolUseFailure", "SubagentStart", "SubagentStop", "Stop"];
14
+ /** Find nearest .claude directory by walking up from cwd. */
15
+ async function findClaudeDir() {
16
+ let dir = process.cwd();
17
+ while (true) {
18
+ const candidate = join(dir, ".claude");
19
+ try {
20
+ const s = await stat(candidate);
21
+ if (s.isDirectory())
22
+ return candidate;
23
+ }
24
+ catch { /* keep walking */ }
25
+ const parent = dirname(dir);
26
+ if (parent === dir)
27
+ break;
28
+ dir = parent;
29
+ }
30
+ return join(process.cwd(), ".claude");
31
+ }
32
+ async function readSettings(path) {
33
+ try {
34
+ return JSON.parse(await readFile(path, "utf8"));
35
+ }
36
+ catch {
37
+ return {};
38
+ }
39
+ }
40
+ function isTapHook(h) { return h.statusMessage === TAP_HOOK_TAG; }
41
+ async function installTapHooks() {
42
+ const claudeDir = await findClaudeDir();
43
+ const settingsPath = join(claudeDir, "settings.local.json");
44
+ const settings = await readSettings(settingsPath);
45
+ if (!settings.hooks)
46
+ settings.hooks = {};
47
+ for (const event of TAP_HOOK_EVENTS) {
48
+ if (!settings.hooks[event])
49
+ settings.hooks[event] = [];
50
+ settings.hooks[event] = settings.hooks[event].filter(g => !g.hooks.some(isTapHook));
51
+ settings.hooks[event].push({
52
+ hooks: [{ type: "command", command: "npx sajou-emit --stdin", async: true, timeout: 5, statusMessage: TAP_HOOK_TAG }],
53
+ });
54
+ }
55
+ await mkdir(claudeDir, { recursive: true });
56
+ await writeFile(settingsPath, JSON.stringify(settings, null, 2) + "\n");
57
+ }
58
+ async function uninstallTapHooks() {
59
+ const claudeDir = await findClaudeDir();
60
+ const settingsPath = join(claudeDir, "settings.local.json");
61
+ const settings = await readSettings(settingsPath);
62
+ if (!settings.hooks)
63
+ return;
64
+ const cleaned = {};
65
+ for (const [event, groups] of Object.entries(settings.hooks)) {
66
+ const filtered = groups.filter(g => !g.hooks.some(isTapHook));
67
+ if (filtered.length > 0)
68
+ cleaned[event] = filtered;
69
+ }
70
+ settings.hooks = Object.keys(cleaned).length > 0 ? cleaned : undefined;
71
+ if (!settings.hooks)
72
+ delete settings.hooks;
73
+ await writeFile(settingsPath, JSON.stringify(settings, null, 2) + "\n");
74
+ }
75
+ // ---------------------------------------------------------------------------
76
+ // Track hook state for cleanup
77
+ // ---------------------------------------------------------------------------
78
+ let hooksInstalled = false;
79
+ /** Clean up hooks on process exit. */
80
+ export function cleanupTapHooks() {
81
+ if (hooksInstalled) {
82
+ uninstallTapHooks().catch(() => { });
83
+ hooksInstalled = false;
84
+ }
85
+ }
86
+ // ---------------------------------------------------------------------------
87
+ // Routes
88
+ // ---------------------------------------------------------------------------
89
+ export function createTapRoutes() {
90
+ const router = Router();
91
+ // POST /api/tap/connect — install hooks
92
+ router.post("/api/tap/connect", (_req, res) => {
93
+ installTapHooks()
94
+ .then(() => {
95
+ hooksInstalled = true;
96
+ res.json({ ok: true });
97
+ })
98
+ .catch((e) => {
99
+ res.status(500).json({ ok: false, error: e instanceof Error ? e.message : String(e) });
100
+ });
101
+ });
102
+ // POST /api/tap/disconnect — remove hooks
103
+ router.post("/api/tap/disconnect", (_req, res) => {
104
+ uninstallTapHooks()
105
+ .then(() => {
106
+ hooksInstalled = false;
107
+ res.json({ ok: true });
108
+ })
109
+ .catch((e) => {
110
+ res.status(500).json({ ok: false, error: e instanceof Error ? e.message : String(e) });
111
+ });
112
+ });
113
+ return router;
114
+ }
115
+ //# sourceMappingURL=tap.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tap.js","sourceRoot":"","sources":["../../src/routes/tap.ts"],"names":[],"mappings":"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"}