@tuongaz/seeflow 0.1.84 → 0.1.87

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 (71) hide show
  1. package/dist/web/assets/{architectureDiagram-3BPJPVTR-I46aqv2T.js → architectureDiagram-3BPJPVTR-ClNXtQtx.js} +1 -1
  2. package/dist/web/assets/{blockDiagram-GPEHLZMM-C08px5xi.js → blockDiagram-GPEHLZMM-BhKGvPcQ.js} +1 -1
  3. package/dist/web/assets/{c4Diagram-AAUBKEIU-iyIMetcW.js → c4Diagram-AAUBKEIU-BKBm_0HA.js} +1 -1
  4. package/dist/web/assets/channel-Blg0ESf3.js +1 -0
  5. package/dist/web/assets/{chart-BGNzA0s8.js → chart-CBngRDiH.js} +1 -1
  6. package/dist/web/assets/{chunk-2J33WTMH-CQFLt-Og.js → chunk-2J33WTMH-WcUKw8RK.js} +1 -1
  7. package/dist/web/assets/{chunk-4BX2VUAB-M_HU7fhX.js → chunk-4BX2VUAB-B9RKcbcq.js} +1 -1
  8. package/dist/web/assets/{chunk-55IACEB6-CZ6tcHFC.js → chunk-55IACEB6-B4GnCgpM.js} +1 -1
  9. package/dist/web/assets/{chunk-727SXJPM-ZXC_1s3s.js → chunk-727SXJPM-CHMq27YW.js} +1 -1
  10. package/dist/web/assets/{chunk-AQP2D5EJ-D1nyTSxR.js → chunk-AQP2D5EJ-D2ZFVUYL.js} +1 -1
  11. package/dist/web/assets/{chunk-FMBD7UC4-D8IemyXd.js → chunk-FMBD7UC4-qG6SQBY6.js} +1 -1
  12. package/dist/web/assets/{chunk-ND2GUHAM-aT_PIEvu.js → chunk-ND2GUHAM-BQ9mDdTH.js} +1 -1
  13. package/dist/web/assets/{chunk-QZHKN3VN-BKY6KT8K.js → chunk-QZHKN3VN-CIDw1jk1.js} +1 -1
  14. package/dist/web/assets/classDiagram-4FO5ZUOK-iwSPO53N.js +1 -0
  15. package/dist/web/assets/classDiagram-v2-Q7XG4LA2-iwSPO53N.js +1 -0
  16. package/dist/web/assets/{code-block-CMPt7Auf.js → code-block-DHA2onLV.js} +1 -1
  17. package/dist/web/assets/{cose-bilkent-S5V4N54A-Cr3EeHXE.js → cose-bilkent-S5V4N54A-CdkJxKQK.js} +1 -1
  18. package/dist/web/assets/{dagre-BM42HDAG-BfJiRz9t.js → dagre-BM42HDAG-B66Vessb.js} +1 -1
  19. package/dist/web/assets/{diagram-2AECGRRQ-CZ1Rti0o.js → diagram-2AECGRRQ-CTGbhRIQ.js} +1 -1
  20. package/dist/web/assets/{diagram-5GNKFQAL-COe7jS3C.js → diagram-5GNKFQAL-CXKhZ2RD.js} +1 -1
  21. package/dist/web/assets/{diagram-KO2AKTUF-lmIy3eJx.js → diagram-KO2AKTUF-Ciz8XXz9.js} +1 -1
  22. package/dist/web/assets/{diagram-LMA3HP47-Dv9UOOZz.js → diagram-LMA3HP47-CHwxluj7.js} +1 -1
  23. package/dist/web/assets/{diagram-OG6HWLK6-C8HoI5ul.js → diagram-OG6HWLK6-2HdAU1Uy.js} +1 -1
  24. package/dist/web/assets/{erDiagram-TEJ5UH35-CvqQcwx_.js → erDiagram-TEJ5UH35-CFuPdZHL.js} +1 -1
  25. package/dist/web/assets/{flowDiagram-I6XJVG4X-B0f8FFr8.js → flowDiagram-I6XJVG4X-D2SYUr84.js} +1 -1
  26. package/dist/web/assets/{ganttDiagram-6RSMTGT7-C0FgETUZ.js → ganttDiagram-6RSMTGT7-hi9oo-If.js} +1 -1
  27. package/dist/web/assets/{gitGraphDiagram-PVQCEYII-BSUklsqu.js → gitGraphDiagram-PVQCEYII-CP4UpnDZ.js} +1 -1
  28. package/dist/web/assets/index-BM5xp_5O.js +8619 -0
  29. package/dist/web/assets/{index-fl8DS9WO.css → index-DzEkjMbu.css} +1 -1
  30. package/dist/web/assets/{index.es-CcTdlE2B.js → index.es-B100nNVg.js} +1 -1
  31. package/dist/web/assets/{infoDiagram-5YYISTIA-qq3OPeKx.js → infoDiagram-5YYISTIA-CWn2ZmPz.js} +1 -1
  32. package/dist/web/assets/{ishikawaDiagram-YF4QCWOH-BxoH_vWZ.js → ishikawaDiagram-YF4QCWOH-BXG7Wqi5.js} +1 -1
  33. package/dist/web/assets/{journeyDiagram-JHISSGLW-ClnMLnWd.js → journeyDiagram-JHISSGLW-BYcudTZ3.js} +1 -1
  34. package/dist/web/assets/{jspdf.es.min-C17Fkx-5.js → jspdf.es.min-BjAnJa9n.js} +3 -3
  35. package/dist/web/assets/{kanban-definition-UN3LZRKU-BiBGcvgP.js → kanban-definition-UN3LZRKU-BPa8o2q1.js} +1 -1
  36. package/dist/web/assets/{linear-D--UMRYt.js → linear-DuxgdPQE.js} +1 -1
  37. package/dist/web/assets/{markdown-D-hxiBfP.js → markdown-CCL3i82k.js} +1 -1
  38. package/dist/web/assets/{mermaid.core-ClLm1p66.js → mermaid.core-BfL5QPbr.js} +4 -4
  39. package/dist/web/assets/{mindmap-definition-RKZ34NQL-CLSXYvAW.js → mindmap-definition-RKZ34NQL-CI-cniK5.js} +1 -1
  40. package/dist/web/assets/{pieDiagram-4H26LBE5-CjvKFGOn.js → pieDiagram-4H26LBE5-cf5aBEPi.js} +1 -1
  41. package/dist/web/assets/{quadrantDiagram-W4KKPZXB-BUYqMtGH.js → quadrantDiagram-W4KKPZXB-DYUrOveY.js} +1 -1
  42. package/dist/web/assets/{requirementDiagram-4Y6WPE33-DNCHy1eI.js → requirementDiagram-4Y6WPE33-93ks8rhf.js} +1 -1
  43. package/dist/web/assets/{sankeyDiagram-5OEKKPKP-zoL2eKAM.js → sankeyDiagram-5OEKKPKP-B_CejPlQ.js} +1 -1
  44. package/dist/web/assets/{sequenceDiagram-3UESZ5HK-DePRNn1e.js → sequenceDiagram-3UESZ5HK-DZS5Ade2.js} +1 -1
  45. package/dist/web/assets/{stateDiagram-AJRCARHV-uLinqFcr.js → stateDiagram-AJRCARHV-BPN2DC-C.js} +1 -1
  46. package/dist/web/assets/stateDiagram-v2-BHNVJYJU-B_a13tqM.js +1 -0
  47. package/dist/web/assets/{time-C9xT3sm_.js → time-BBP2Hxfw.js} +1 -1
  48. package/dist/web/assets/{timeline-definition-PNZ67QCA-BnQVT-CY.js → timeline-definition-PNZ67QCA-DCAE7DJl.js} +1 -1
  49. package/dist/web/assets/{vennDiagram-CIIHVFJN-BUyqbvsU.js → vennDiagram-CIIHVFJN-Cicq6guF.js} +1 -1
  50. package/dist/web/assets/{wardley-L42UT6IY-zz-5TvX0.js → wardley-L42UT6IY-CAXHDzax.js} +1 -1
  51. package/dist/web/assets/{wardleyDiagram-YWT4CUSO-DVnYIARL.js → wardleyDiagram-YWT4CUSO-DC5nEIz7.js} +1 -1
  52. package/dist/web/assets/{xychartDiagram-2RQKCTM6-BMxn2lA_.js → xychartDiagram-2RQKCTM6-DbZv6qnZ.js} +1 -1
  53. package/dist/web/index.html +2 -2
  54. package/package.json +1 -1
  55. package/src/api.ts +7 -95
  56. package/src/cli-manifest.ts +2 -2
  57. package/src/cli-ops.ts +2 -2
  58. package/src/events.ts +0 -1
  59. package/src/layout.ts +2 -0
  60. package/src/mcp.ts +6 -6
  61. package/src/merge.ts +0 -3
  62. package/src/operations.ts +2 -2
  63. package/src/proxy.ts +1 -193
  64. package/src/schema-catalog.ts +5 -3
  65. package/src/schema.ts +10 -11
  66. package/src/server.ts +1 -2
  67. package/dist/web/assets/channel-X0ALvlnb.js +0 -1
  68. package/dist/web/assets/classDiagram-4FO5ZUOK-mwGbzVrI.js +0 -1
  69. package/dist/web/assets/classDiagram-v2-Q7XG4LA2-mwGbzVrI.js +0 -1
  70. package/dist/web/assets/index-Cnz1Cpa9.js +0 -8619
  71. package/dist/web/assets/stateDiagram-v2-BHNVJYJU-hyQj-KY3.js +0 -1
package/src/mcp.ts CHANGED
@@ -293,9 +293,9 @@ const buildTools = (ops: Operations, ctx: ToolContext): McpTool[] => [
293
293
  "node variant; name='action', subname='playAction' → just the playAction " +
294
294
  'shape). Use this to learn what a node, connector, action, component ' +
295
295
  'spec, or flow envelope looks like before authoring writes. Categories: ' +
296
- '`flow`, `node` (13 flat variants — rectangle/ellipse/sticky/text/' +
297
- 'database/server/user/queue/cloud/image/html/icon/component), ' +
298
- '`connector`, `action` (playAction/statusAction/resetAction/statusReport/' +
296
+ '`flow`, `node` (15 flat variants — rectangle/ellipse/sticky/text/' +
297
+ 'database/server/user/queue/cloud/diamond/hexagon/image/html/icon/component), ' +
298
+ '`connector`, `action` (playAction/statusAction/statusReport/' +
299
299
  "componentAction), `componentSpec` (sidecar shape for type:'component' " +
300
300
  'nodes), `style`.',
301
301
  inputSchema: {
@@ -310,8 +310,8 @@ const buildTools = (ops: Operations, ctx: ToolContext): McpTool[] => [
310
310
  description:
311
311
  'Optional named schema within the category (requires `name`). For ' +
312
312
  "name='node': rectangle, ellipse, sticky, text, database, server, " +
313
- 'user, queue, cloud, image, html, icon, component. For ' +
314
- "name='action': playAction, statusAction, resetAction, statusReport, " +
313
+ 'user, queue, cloud, diamond, hexagon, image, html, icon, component. For ' +
314
+ "name='action': playAction, statusAction, statusReport, " +
315
315
  "componentAction. For name='componentSpec': componentSpec, " +
316
316
  'componentSpecElement.',
317
317
  },
@@ -763,7 +763,7 @@ const buildTools = (ops: Operations, ctx: ToolContext): McpTool[] => [
763
763
  {
764
764
  name: 'seeflow_patch_node',
765
765
  description:
766
- "Update fields on an existing node (position, name, description, detail, icon, colors, border, font, dimensions, autoSize, plus type:'icon'-only color/strokeWidth/alt and capabilities playAction/statusAction/stateSource). `type` can flip a node between any of the 12 visual variants (rectangle/ellipse/sticky/text/database/server/user/queue/cloud/image/html/icon); the post-merge schema reparse gates required fields on the new type (image.data.path, icon.data.icon). Setting detail (every node) or html (type:'html') writes the content to <project>/nodes/<id>/{detail.md|view.html}; the file:// ref on the node persists. Empty-string detail empties the file but keeps the ref.",
766
+ "Update fields on an existing node (position, name, description, detail, icon, colors, border, font, dimensions, autoSize, plus type:'icon'-only color/strokeWidth/alt and capabilities playAction/statusAction/stateSource). `type` can flip a node between any of the 14 visual variants (rectangle/ellipse/sticky/text/database/server/user/queue/cloud/diamond/hexagon/image/html/icon); the post-merge schema reparse gates required fields on the new type (image.data.path, icon.data.icon). Setting detail (every node) or html (type:'html') writes the content to <project>/nodes/<id>/{detail.md|view.html}; the file:// ref on the node persists. Empty-string detail empties the file but keeps the ref.",
767
767
  inputSchema: inputSchemaFromZod(PatchNodeInputSchema),
768
768
  handler: async (args) => {
769
769
  const parsed = PatchNodeInputSchema.safeParse(args);
package/src/merge.ts CHANGED
@@ -32,7 +32,6 @@ export function mergeFlowAndStyle(flow: Flow, style: Style): ResolvedFlow {
32
32
  version: flow.version,
33
33
  name: flow.name,
34
34
  ...(flow.description !== undefined ? { description: flow.description } : {}),
35
- ...(flow.resetAction ? { resetAction: flow.resetAction } : {}),
36
35
  nodes: mergedNodes,
37
36
  connectors: mergedConnectors,
38
37
  } as ResolvedFlow;
@@ -114,7 +113,6 @@ export function splitFlow(resolved: {
114
113
  version: number;
115
114
  name: string;
116
115
  description?: string;
117
- resetAction?: unknown;
118
116
  nodes: Array<Record<string, unknown>>;
119
117
  connectors: Array<Record<string, unknown>>;
120
118
  }): { flow: Record<string, unknown>; style: Record<string, unknown> } {
@@ -187,7 +185,6 @@ export function splitFlow(resolved: {
187
185
  connectors: flowConnectors,
188
186
  };
189
187
  if (resolved.description !== undefined) flow.description = resolved.description;
190
- if (resolved.resetAction !== undefined) flow.resetAction = resolved.resetAction;
191
188
 
192
189
  const style: Record<string, unknown> = {};
193
190
  if (Object.keys(styleNodes).length > 0) style.nodes = styleNodes;
package/src/operations.ts CHANGED
@@ -212,6 +212,8 @@ const SEMANTIC_KEYS_BY_TYPE: Record<z.infer<typeof NodeTypeSchema>, ReadonlySet<
212
212
  user: GEOMETRIC_SEMANTIC_KEYS,
213
213
  queue: GEOMETRIC_SEMANTIC_KEYS,
214
214
  cloud: GEOMETRIC_SEMANTIC_KEYS,
215
+ diamond: GEOMETRIC_SEMANTIC_KEYS,
216
+ hexagon: GEOMETRIC_SEMANTIC_KEYS,
215
217
  image: new Set([
216
218
  'name',
217
219
  'description',
@@ -762,7 +764,6 @@ function readRawFlowAndStyle(flowPath: string): ReadRawResult {
762
764
  type MutateMergedFlowMutator<E> = (flow: {
763
765
  version: number;
764
766
  name: string;
765
- resetAction?: unknown;
766
767
  nodes: Array<Record<string, unknown>>;
767
768
  connectors: Array<Record<string, unknown>>;
768
769
  }) => { kind: 'ok' } | E;
@@ -808,7 +809,6 @@ export async function mutateMergedFlow<E extends { kind: string }>(
808
809
  const merged = inlinedFlow as unknown as {
809
810
  version: number;
810
811
  name: string;
811
- resetAction?: unknown;
812
812
  nodes: Array<Record<string, unknown>>;
813
813
  connectors: Array<Record<string, unknown>>;
814
814
  };
package/src/proxy.ts CHANGED
@@ -16,7 +16,7 @@ import { realpathSync } from 'node:fs';
16
16
  import { join, resolve, sep } from 'node:path';
17
17
  import type { EventBus } from './events.ts';
18
18
  import { type ProcessSpawner, type SpawnHandle, defaultProcessSpawner } from './process-spawner.ts';
19
- import type { PlayAction, ResetAction } from './schema.ts';
19
+ import type { PlayAction } from './schema.ts';
20
20
  import { shortId } from './short-id.ts';
21
21
 
22
22
  export interface PlayResult {
@@ -73,31 +73,6 @@ function resolveScript(cwd: string, nodeId: string, scriptPath: string): Resolve
73
73
  return { ok: true, absPath: realTarget };
74
74
  }
75
75
 
76
- // Legacy anchor for resetAction (kept until resetAction gets its own design
77
- // round). Same realpath escape check as resolveScript, but rooted at the
78
- // project root rather than a per-node folder.
79
- function resolveResetScript(cwd: string, scriptPath: string): Resolved {
80
- const projectRoot = cwd;
81
- let realRoot: string;
82
- try {
83
- realRoot = realpathSync(projectRoot);
84
- } catch {
85
- return { ok: false };
86
- }
87
- const target = resolve(projectRoot, scriptPath);
88
- let realTarget: string;
89
- try {
90
- realTarget = realpathSync(target);
91
- } catch {
92
- return { ok: false };
93
- }
94
- const rootWithSep = realRoot.endsWith(sep) ? realRoot : realRoot + sep;
95
- if (realTarget !== realRoot && !realTarget.startsWith(rootWithSep)) {
96
- return { ok: false };
97
- }
98
- return { ok: true, absPath: realTarget };
99
- }
100
-
101
76
  // Copy `process.env` into a string-only record, then layer the per-run extras.
102
77
  // Bun.spawn's env contract is `Record<string, string>` so the undefineds that
103
78
  // `process.env` advertises in its type must be filtered out first.
@@ -130,54 +105,6 @@ async function writeStdinPayload(handle: SpawnHandle, input: unknown): Promise<v
130
105
  }
131
106
  }
132
107
 
133
- // Live play-script handles indexed by flowId. Populated by runPlay() on spawn;
134
- // entries are removed when each handle's `exited` promise resolves (success
135
- // AND error paths). `stopAllPlays(flowId)` consults this map to terminate
136
- // every in-flight play for a demo on /reset.
137
- const livePlayHandles = new Map<string, Set<SpawnHandle>>();
138
-
139
- function registerLiveHandle(flowId: string, handle: SpawnHandle): void {
140
- let set = livePlayHandles.get(flowId);
141
- if (!set) {
142
- set = new Set();
143
- livePlayHandles.set(flowId, set);
144
- }
145
- set.add(handle);
146
- handle.exited.finally(() => {
147
- const current = livePlayHandles.get(flowId);
148
- if (!current) return;
149
- current.delete(handle);
150
- if (current.size === 0) livePlayHandles.delete(flowId);
151
- });
152
- }
153
-
154
- async function killWithGrace(handle: SpawnHandle): Promise<void> {
155
- handle.kill('SIGTERM');
156
- let graceTimer: ReturnType<typeof setTimeout> | undefined;
157
- const gracePromise = new Promise<'grace'>((res) => {
158
- graceTimer = setTimeout(() => res('grace'), SIGKILL_GRACE_MS);
159
- });
160
- const winner = await Promise.race([handle.exited.then(() => 'exited' as const), gracePromise]);
161
- if (graceTimer) clearTimeout(graceTimer);
162
- if (winner === 'grace') {
163
- handle.kill('SIGKILL');
164
- await handle.exited;
165
- }
166
- }
167
-
168
- // Kill every live play-script for `flowId` (SIGTERM → 2s grace → SIGKILL in
169
- // parallel) and wait for each to exit. Idempotent on an unknown flowId. The
170
- // map is keyed by flowId so a stop on demo A never touches demo B.
171
- export async function stopAllPlays(flowId: string): Promise<void> {
172
- const set = livePlayHandles.get(flowId);
173
- if (!set || set.size === 0) return;
174
- const handles = [...set];
175
- // Clear eagerly so a parallel runPlay can't double-count an entry we're
176
- // about to await on. The exited.finally() will no-op the second delete.
177
- livePlayHandles.delete(flowId);
178
- await Promise.all(handles.map((h) => killWithGrace(h)));
179
- }
180
-
181
108
  export async function runPlay(options: RunPlayOptions): Promise<PlayResult> {
182
109
  const { events, flowId, nodeId, cwd, action } = options;
183
110
  const spawner = options.spawner ?? defaultProcessSpawner;
@@ -229,8 +156,6 @@ export async function runPlay(options: RunPlayOptions): Promise<PlayResult> {
229
156
  return { runId, error: message };
230
157
  }
231
158
 
232
- registerLiveHandle(flowId, handle);
233
-
234
159
  // Drain stdout AND stderr CONCURRENTLY with the process running so OS pipe
235
160
  // buffers (~64 KB) don't fill up and deadlock the child.
236
161
  const stdoutPromise = new Response(handle.stdout).text();
@@ -303,120 +228,3 @@ export async function runPlay(options: RunPlayOptions): Promise<PlayResult> {
303
228
  });
304
229
  return { runId, error: message };
305
230
  }
306
-
307
- export interface RunResetOptions {
308
- events: EventBus;
309
- flowId: string;
310
- /** Project root (`<repoPath>`). Script resolves under `<cwd>/`. */
311
- cwd: string;
312
- action: ResetAction;
313
- /** Injectable for tests; defaults to `defaultProcessSpawner`. */
314
- spawner?: ProcessSpawner;
315
- }
316
-
317
- export interface ResetResult {
318
- ok: boolean;
319
- body?: unknown;
320
- error?: string;
321
- }
322
-
323
- // Run the demo's one-shot `resetAction` script. Same spawn discipline as
324
- // runPlay (realpath-guarded scriptPath, concurrent stdout/stderr drain,
325
- // optional stdin payload, SIGTERM→2s→SIGKILL escalation on timeout) but the
326
- // lifecycle SSE event is the single `demo:reset` broadcast that mirrors the
327
- // returned shape. Callers (the /reset endpoint) decide what HTTP status to
328
- // surface; this returns `{ ok }` plus body/error so the endpoint can map.
329
- export async function runReset(options: RunResetOptions): Promise<ResetResult> {
330
- const { events, flowId, cwd, action } = options;
331
- const spawner = options.spawner ?? defaultProcessSpawner;
332
-
333
- // resetAction is anchored at the project root — design defers per-node
334
- // resetAction to a later round (decision #7).
335
- const resolved = resolveResetScript(cwd, action.scriptPath);
336
- if (!resolved.ok) {
337
- events.broadcast({
338
- type: 'demo:reset',
339
- flowId,
340
- payload: { ok: false, error: SCRIPT_PATH_ESCAPE },
341
- });
342
- return { ok: false, error: SCRIPT_PATH_ESCAPE };
343
- }
344
-
345
- const wantsStdin = action.input !== undefined;
346
- const env = buildChildEnv({ SEEFLOW_DEMO_ID: flowId });
347
-
348
- let handle: SpawnHandle;
349
- try {
350
- handle = spawner.spawn({
351
- cmd: [action.interpreter, ...(action.args ?? []), resolved.absPath],
352
- cwd,
353
- env,
354
- stdin: wantsStdin ? 'pipe' : 'ignore',
355
- });
356
- } catch (err) {
357
- const message = err instanceof Error ? err.message : String(err);
358
- events.broadcast({
359
- type: 'demo:reset',
360
- flowId,
361
- payload: { ok: false, error: message },
362
- });
363
- return { ok: false, error: message };
364
- }
365
-
366
- const stdoutPromise = new Response(handle.stdout).text();
367
- const stderrPromise = new Response(handle.stderr).text();
368
-
369
- if (wantsStdin) {
370
- await writeStdinPayload(handle, action.input);
371
- }
372
-
373
- const timeoutMs = action.timeoutMs ?? DEFAULT_TIMEOUT_MS;
374
- let timer: ReturnType<typeof setTimeout> | undefined;
375
- const timeoutPromise = new Promise<'timeout'>((res) => {
376
- timer = setTimeout(() => res('timeout'), timeoutMs);
377
- });
378
- const exitPromise = handle.exited.then((code) => ({ code }) as const);
379
-
380
- const race = await Promise.race([exitPromise, timeoutPromise]);
381
- if (timer) clearTimeout(timer);
382
-
383
- if (race === 'timeout') {
384
- await killWithGrace(handle);
385
- await Promise.allSettled([stdoutPromise, stderrPromise]);
386
- const message = `reset script timed out after ${timeoutMs}ms`;
387
- events.broadcast({
388
- type: 'demo:reset',
389
- flowId,
390
- payload: { ok: false, error: message },
391
- });
392
- return { ok: false, error: message };
393
- }
394
-
395
- const code = race.code;
396
- const [stdout, stderr] = await Promise.all([stdoutPromise, stderrPromise]);
397
-
398
- if (code === 0) {
399
- let body: unknown;
400
- try {
401
- body = JSON.parse(stdout);
402
- } catch {
403
- body = stdout;
404
- }
405
- events.broadcast({
406
- type: 'demo:reset',
407
- flowId,
408
- payload: { ok: true, body },
409
- });
410
- return { ok: true, body };
411
- }
412
-
413
- const lastLine = lastNonEmptyLine(stderr);
414
- const truncated = lastLine.slice(0, STDERR_TRUNCATE);
415
- const message = truncated.length > 0 ? truncated : `reset script exited with code ${code}`;
416
- events.broadcast({
417
- type: 'demo:reset',
418
- flowId,
419
- payload: { ok: false, error: message },
420
- });
421
- return { ok: false, error: message };
422
- }
@@ -15,8 +15,10 @@ import {
15
15
  FlowComponentNodeSchema,
16
16
  FlowConnectorSchema,
17
17
  FlowDatabaseNodeSchema,
18
+ FlowDiamondNodeSchema,
18
19
  FlowEllipseNodeSchema,
19
20
  FlowEnvelopeSchema,
21
+ FlowHexagonNodeSchema,
20
22
  FlowHtmlNodeSchema,
21
23
  FlowIconNodeSchema,
22
24
  FlowImageNodeSchema,
@@ -27,7 +29,6 @@ import {
27
29
  FlowTextNodeSchema,
28
30
  FlowUserNodeSchema,
29
31
  PlayActionSchema,
30
- ResetActionSchema,
31
32
  StatusActionSchema,
32
33
  StatusReportSchema,
33
34
  StyleSchema,
@@ -63,7 +64,7 @@ const CATEGORIES: SchemaCategory[] = [
63
64
  {
64
65
  name: 'action',
65
66
  description:
66
- 'playAction, statusAction, resetAction, statusReport, plus componentAction (the set | script discriminated union dispatched on component-node action handles).',
67
+ 'playAction, statusAction, statusReport, plus componentAction (the set | script discriminated union dispatched on component-node action handles).',
67
68
  },
68
69
  {
69
70
  name: 'componentSpec',
@@ -89,6 +90,8 @@ const PAYLOADS: Record<string, SchemaPayload> = {
89
90
  user: toJsonSchema(FlowUserNodeSchema),
90
91
  queue: toJsonSchema(FlowQueueNodeSchema),
91
92
  cloud: toJsonSchema(FlowCloudNodeSchema),
93
+ diamond: toJsonSchema(FlowDiamondNodeSchema),
94
+ hexagon: toJsonSchema(FlowHexagonNodeSchema),
92
95
  image: toJsonSchema(FlowImageNodeSchema),
93
96
  html: toJsonSchema(FlowHtmlNodeSchema),
94
97
  icon: toJsonSchema(FlowIconNodeSchema),
@@ -112,7 +115,6 @@ const PAYLOADS: Record<string, SchemaPayload> = {
112
115
  schemas: {
113
116
  playAction: toJsonSchema(PlayActionSchema),
114
117
  statusAction: toJsonSchema(StatusActionSchema),
115
- resetAction: toJsonSchema(ResetActionSchema),
116
118
  statusReport: toJsonSchema(StatusReportSchema),
117
119
  componentAction: toJsonSchema(ComponentActionSchema),
118
120
  },
package/src/schema.ts CHANGED
@@ -18,6 +18,7 @@ export const ColorTokenSchema = z.enum([
18
18
  // and edges aren't useful, and `'default'` already covers "inherit".
19
19
  'none',
20
20
  'default',
21
+ 'white',
21
22
  'slate',
22
23
  'gray',
23
24
  'red',
@@ -115,9 +116,6 @@ export const ScriptActionSchema = z.object({
115
116
 
116
117
  export const PlayActionSchema = ScriptActionSchema;
117
118
 
118
- // resetAction is a one-shot script with the same shape as a play script.
119
- export const ResetActionSchema = ScriptActionSchema;
120
-
121
119
  // Long-running status script. Same spawn shape as ScriptAction (interpreter +
122
120
  // args + scriptPath) but no stdin payload and a much longer max lifetime since
123
121
  // these processes tick continuously and stream StatusReports to stdout.
@@ -182,7 +180,7 @@ const NodeCapabilitiesShape = {
182
180
  ),
183
181
  };
184
182
 
185
- // 13 flat node types. The first 9 are geometric/illustrative and share
183
+ // 15 flat node types. The first 11 are geometric/illustrative and share
186
184
  // GeometricNodeData. `image`, `html`, `icon`, `component` carry per-type
187
185
  // fields. The renderer picks the SVG / chrome by `type`; the schema treats
188
186
  // them (apart from the per-type fields below) as identical.
@@ -196,6 +194,8 @@ export const GEOMETRIC_NODE_TYPES = [
196
194
  'user',
197
195
  'queue',
198
196
  'cloud',
197
+ 'diamond',
198
+ 'hexagon',
199
199
  ] as const;
200
200
 
201
201
  export const NodeTypeSchema = z.enum([
@@ -331,6 +331,8 @@ const NodeSchema = z.discriminatedUnion('type', [
331
331
  makeResolvedGeometricSchema('user'),
332
332
  makeResolvedGeometricSchema('queue'),
333
333
  makeResolvedGeometricSchema('cloud'),
334
+ makeResolvedGeometricSchema('diamond'),
335
+ makeResolvedGeometricSchema('hexagon'),
334
336
  z.object({ ...NodeBaseShape, type: z.literal('image'), data: ResolvedImageNodeData }),
335
337
  z.object({ ...NodeBaseShape, type: z.literal('html'), data: ResolvedHtmlNodeData }),
336
338
  z.object({ ...NodeBaseShape, type: z.literal('icon'), data: ResolvedIconNodeData }),
@@ -395,10 +397,6 @@ export const ResolvedFlowSchema = z
395
397
  description: z.string().optional(),
396
398
  nodes: z.array(NodeSchema),
397
399
  connectors: z.array(ConnectorSchema),
398
- // Optional one-shot script the studio runs when the user clicks Restart.
399
- // The studio kills every live play + status script for the flow BEFORE
400
- // invoking this script, so the script sees no stragglers.
401
- resetAction: ResetActionSchema.optional(),
402
400
  })
403
401
  .superRefine((resolved, ctx) => {
404
402
  const nodeIds = new Set(resolved.nodes.map((n) => n.id));
@@ -476,7 +474,6 @@ export type EdgePinSide = z.infer<typeof EdgePinSideSchema>;
476
474
  export type PlayAction = z.infer<typeof PlayActionSchema>;
477
475
  export type StatusAction = z.infer<typeof StatusActionSchema>;
478
476
  export type StatusReport = z.infer<typeof StatusReportSchema>;
479
- export type ResetAction = z.infer<typeof ResetActionSchema>;
480
477
  export type StateSource = z.infer<typeof StateSourceSchema>;
481
478
 
482
479
  // =============================================================================
@@ -577,6 +574,8 @@ export const FlowServerNodeSchema = makeFlowGeometricSchema('server');
577
574
  export const FlowUserNodeSchema = makeFlowGeometricSchema('user');
578
575
  export const FlowQueueNodeSchema = makeFlowGeometricSchema('queue');
579
576
  export const FlowCloudNodeSchema = makeFlowGeometricSchema('cloud');
577
+ export const FlowDiamondNodeSchema = makeFlowGeometricSchema('diamond');
578
+ export const FlowHexagonNodeSchema = makeFlowGeometricSchema('hexagon');
580
579
 
581
580
  export const FlowImageNodeSchema = z
582
581
  .object({
@@ -620,6 +619,8 @@ const FlowNodeSchema = z.discriminatedUnion('type', [
620
619
  FlowUserNodeSchema,
621
620
  FlowQueueNodeSchema,
622
621
  FlowCloudNodeSchema,
622
+ FlowDiamondNodeSchema,
623
+ FlowHexagonNodeSchema,
623
624
  FlowImageNodeSchema,
624
625
  FlowHtmlNodeSchema,
625
626
  FlowIconNodeSchema,
@@ -648,7 +649,6 @@ export const FlowSchema = z
648
649
  version: z.literal(2),
649
650
  name: z.string().min(1),
650
651
  description: z.string().optional(),
651
- resetAction: ResetActionSchema.optional(),
652
652
  nodes: z.array(FlowNodeSchema),
653
653
  connectors: z.array(FlowConnectorSchema),
654
654
  })
@@ -687,7 +687,6 @@ export const FlowEnvelopeSchema = z
687
687
  version: z.literal(2),
688
688
  name: z.string().min(1),
689
689
  description: z.string().optional(),
690
- resetAction: ResetActionSchema.optional(),
691
690
  nodes: z.array(z.unknown().describe('See `seeflow schema node`')),
692
691
  connectors: z.array(z.unknown().describe('See `seeflow schema connector`')),
693
692
  })
package/src/server.ts CHANGED
@@ -52,8 +52,7 @@ export interface CreateAppOptions {
52
52
  * proxy.ts pick `defaultProcessSpawner`. Tests use this to drive runPlay
53
53
  * with an in-memory fake spawner. */
54
54
  processSpawner?: ProcessSpawner;
55
- /** Inject a ProxyFacade — tests use this to short-circuit runPlay /
56
- * runReset / stopAllPlays and assert call order. */
55
+ /** Inject a ProxyFacade — tests use this to short-circuit runPlay. */
57
56
  proxy?: ProxyFacade;
58
57
  /** Per-process token gating `Origin: null` requests (sandboxed MCP App
59
58
  * iframe). Generated at studio boot; delivered to the iframe via
@@ -1 +0,0 @@
1
- import{U as a,C as n}from"./mermaid.core-ClLm1p66.js";const t=(r,o)=>a.lang.round(n.parse(r)[o]);export{t as c};
@@ -1 +0,0 @@
1
- import{s as a,a as s,c as e,C as t}from"./chunk-727SXJPM-ZXC_1s3s.js";import{a as i}from"./mermaid.core-ClLm1p66.js";import"./index-Cnz1Cpa9.js";import"./chunk-FMBD7UC4-D8IemyXd.js";import"./chunk-ND2GUHAM-aT_PIEvu.js";import"./chunk-55IACEB6-CZ6tcHFC.js";import"./chunk-2J33WTMH-CQFLt-Og.js";import"./purify.es-CLGrRn1w.js";import"./step-CWvwoXpJ.js";var b={parser:e,get db(){return new t},renderer:s,styles:a,init:i(r=>{r.class||(r.class={}),r.class.arrowMarkerAbsolute=r.arrowMarkerAbsolute},"init")};export{b as diagram};
@@ -1 +0,0 @@
1
- import{s as a,a as s,c as e,C as t}from"./chunk-727SXJPM-ZXC_1s3s.js";import{a as i}from"./mermaid.core-ClLm1p66.js";import"./index-Cnz1Cpa9.js";import"./chunk-FMBD7UC4-D8IemyXd.js";import"./chunk-ND2GUHAM-aT_PIEvu.js";import"./chunk-55IACEB6-CZ6tcHFC.js";import"./chunk-2J33WTMH-CQFLt-Og.js";import"./purify.es-CLGrRn1w.js";import"./step-CWvwoXpJ.js";var b={parser:e,get db(){return new t},renderer:s,styles:a,init:i(r=>{r.class||(r.class={}),r.class.arrowMarkerAbsolute=r.arrowMarkerAbsolute},"init")};export{b as diagram};