@tuongaz/seeflow 0.1.91 → 0.1.97
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.
- package/dist/web/assets/{architectureDiagram-3BPJPVTR-CLQb7I2I.js → architectureDiagram-3BPJPVTR-XQzgHME4.js} +1 -1
- package/dist/web/assets/{blockDiagram-GPEHLZMM-DN0OjtOL.js → blockDiagram-GPEHLZMM-D79pgdno.js} +1 -1
- package/dist/web/assets/{c4Diagram-AAUBKEIU-DMVbVbvl.js → c4Diagram-AAUBKEIU-DdpMasob.js} +1 -1
- package/dist/web/assets/channel-l7nIO4lY.js +1 -0
- package/dist/web/assets/{chart-Bx3ReVE3.js → chart-BS3qBv6b.js} +1 -1
- package/dist/web/assets/{chunk-2J33WTMH-9vQ1xqy3.js → chunk-2J33WTMH-DMiLaW3V.js} +1 -1
- package/dist/web/assets/{chunk-4BX2VUAB-DRGxmqVG.js → chunk-4BX2VUAB-BxRQSTSU.js} +1 -1
- package/dist/web/assets/{chunk-55IACEB6-DlboNFJr.js → chunk-55IACEB6-B8VO9ECP.js} +1 -1
- package/dist/web/assets/{chunk-727SXJPM-2Se8RGwW.js → chunk-727SXJPM-CtI4DnVU.js} +1 -1
- package/dist/web/assets/{chunk-AQP2D5EJ-DqZEBh23.js → chunk-AQP2D5EJ-BUDEtGcc.js} +1 -1
- package/dist/web/assets/{chunk-FMBD7UC4-BJX_21R2.js → chunk-FMBD7UC4-XRBBZk8O.js} +1 -1
- package/dist/web/assets/{chunk-ND2GUHAM-DFBKXknR.js → chunk-ND2GUHAM-D0exlO6X.js} +1 -1
- package/dist/web/assets/{chunk-QZHKN3VN-CHnWLNTw.js → chunk-QZHKN3VN-CnyiTlpq.js} +1 -1
- package/dist/web/assets/classDiagram-4FO5ZUOK-BPFTU8oh.js +1 -0
- package/dist/web/assets/classDiagram-v2-Q7XG4LA2-BPFTU8oh.js +1 -0
- package/dist/web/assets/{code-block-IJZcqBQa.js → code-block-CLrCA7Xe.js} +1 -1
- package/dist/web/assets/{cose-bilkent-S5V4N54A-B0LjjLKu.js → cose-bilkent-S5V4N54A-B4D1urlH.js} +1 -1
- package/dist/web/assets/{dagre-BM42HDAG-mMg_Ia_X.js → dagre-BM42HDAG-CNe7Uulx.js} +1 -1
- package/dist/web/assets/{diagram-2AECGRRQ-BUy1Taew.js → diagram-2AECGRRQ--mgpxm9o.js} +1 -1
- package/dist/web/assets/{diagram-5GNKFQAL-DH_tg4Cb.js → diagram-5GNKFQAL-CGHMTFDB.js} +1 -1
- package/dist/web/assets/{diagram-KO2AKTUF-CE1rkBey.js → diagram-KO2AKTUF-D31GLzm7.js} +1 -1
- package/dist/web/assets/{diagram-LMA3HP47-DS7ee5II.js → diagram-LMA3HP47-Bs2BLtxH.js} +1 -1
- package/dist/web/assets/{diagram-OG6HWLK6-DzCf3KBM.js → diagram-OG6HWLK6-CXUZ873r.js} +1 -1
- package/dist/web/assets/{erDiagram-TEJ5UH35-Spog-6po.js → erDiagram-TEJ5UH35-DL-eedkW.js} +1 -1
- package/dist/web/assets/{flowDiagram-I6XJVG4X-0VAojPZO.js → flowDiagram-I6XJVG4X-BQCu7G6G.js} +1 -1
- package/dist/web/assets/{ganttDiagram-6RSMTGT7-DcjKkuMU.js → ganttDiagram-6RSMTGT7-CyBhrhQa.js} +1 -1
- package/dist/web/assets/{gitGraphDiagram-PVQCEYII-Bq9UIINL.js → gitGraphDiagram-PVQCEYII-D9OqlmQL.js} +1 -1
- package/dist/web/assets/index-BKZTnCOL.js +8624 -0
- package/dist/web/assets/{index-CWGdrwRY.css → index-I8_SAWCr.css} +1 -1
- package/dist/web/assets/{index.es-BUxcZ9iL.js → index.es-BpDX3yd0.js} +1 -1
- package/dist/web/assets/{infoDiagram-5YYISTIA-yxIJiF1X.js → infoDiagram-5YYISTIA-CMxwx_2B.js} +1 -1
- package/dist/web/assets/{ishikawaDiagram-YF4QCWOH-BkcKepSB.js → ishikawaDiagram-YF4QCWOH-DD1y6qVy.js} +1 -1
- package/dist/web/assets/{journeyDiagram-JHISSGLW-KfXgvDdv.js → journeyDiagram-JHISSGLW-CHo991VZ.js} +1 -1
- package/dist/web/assets/{jspdf.es.min-BPfxcczM.js → jspdf.es.min-C8_HZhlK.js} +3 -3
- package/dist/web/assets/{kanban-definition-UN3LZRKU-B2m52Unk.js → kanban-definition-UN3LZRKU-CoYkI8Ob.js} +1 -1
- package/dist/web/assets/{linear-D-pwAWPr.js → linear-CQGcGLyB.js} +1 -1
- package/dist/web/assets/{markdown-lr17R9FO.js → markdown-Bud9JO0j.js} +1 -1
- package/dist/web/assets/{mermaid.core-CRo4rzDL.js → mermaid.core-1G8gw6AK.js} +4 -4
- package/dist/web/assets/{mindmap-definition-RKZ34NQL-DUpVPXgC.js → mindmap-definition-RKZ34NQL-CJHnwtSU.js} +1 -1
- package/dist/web/assets/{pieDiagram-4H26LBE5-CatVLCYi.js → pieDiagram-4H26LBE5-CXrXwuPG.js} +1 -1
- package/dist/web/assets/{quadrantDiagram-W4KKPZXB-TJ5_ZxiK.js → quadrantDiagram-W4KKPZXB-BVJKIfMF.js} +1 -1
- package/dist/web/assets/{requirementDiagram-4Y6WPE33-B7CTMFGC.js → requirementDiagram-4Y6WPE33-ZFgLHB2Y.js} +1 -1
- package/dist/web/assets/{sankeyDiagram-5OEKKPKP-C56xsvrm.js → sankeyDiagram-5OEKKPKP-cP9rHdFK.js} +1 -1
- package/dist/web/assets/{sequenceDiagram-3UESZ5HK-EPKxvTJ9.js → sequenceDiagram-3UESZ5HK-BbruCi6T.js} +1 -1
- package/dist/web/assets/{stateDiagram-AJRCARHV-Cma2F0T8.js → stateDiagram-AJRCARHV-CqGbTDXI.js} +1 -1
- package/dist/web/assets/stateDiagram-v2-BHNVJYJU-e0EPpmUp.js +1 -0
- package/dist/web/assets/{time-D6UR1Qac.js → time-CXSgtiIX.js} +1 -1
- package/dist/web/assets/{timeline-definition-PNZ67QCA-iYUvK9JO.js → timeline-definition-PNZ67QCA-B4in6942.js} +1 -1
- package/dist/web/assets/{vennDiagram-CIIHVFJN-CkLxULtS.js → vennDiagram-CIIHVFJN-D3Esdgtc.js} +1 -1
- package/dist/web/assets/{wardley-L42UT6IY-DPcFqZu2.js → wardley-L42UT6IY-CqOLhiLD.js} +1 -1
- package/dist/web/assets/{wardleyDiagram-YWT4CUSO-BKqSvb-r.js → wardleyDiagram-YWT4CUSO-DalbSLu7.js} +1 -1
- package/dist/web/assets/{xychartDiagram-2RQKCTM6-0L00Xzr6.js → xychartDiagram-2RQKCTM6-Bgnuf0j-.js} +1 -1
- package/dist/web/index.html +2 -2
- package/package.json +1 -1
- package/src/api.ts +63 -8
- package/src/cli-manifest.ts +50 -25
- package/src/cli.ts +34 -9
- package/src/mcp.ts +16 -2
- package/src/merge.ts +0 -1
- package/src/node-files.ts +39 -1
- package/src/operations.ts +81 -55
- package/src/schema-catalog.ts +167 -3
- package/src/schema.ts +11 -7
- package/src/server.ts +6 -1
- package/dist/web/assets/channel-CilAQwI4.js +0 -1
- package/dist/web/assets/classDiagram-4FO5ZUOK-fiT0MjXY.js +0 -1
- package/dist/web/assets/classDiagram-v2-Q7XG4LA2-fiT0MjXY.js +0 -1
- package/dist/web/assets/index-DFpY3RpV.js +0 -8624
- package/dist/web/assets/stateDiagram-v2-BHNVJYJU-DRP_iswg.js +0 -1
package/src/schema-catalog.ts
CHANGED
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
// module load — each call returns a fresh shallow copy so callers can't
|
|
6
6
|
// mutate the cached payload.
|
|
7
7
|
|
|
8
|
+
import { componentCatalog } from '@seeflow/canvas/catalog';
|
|
8
9
|
import type { ZodTypeAny } from 'zod';
|
|
9
10
|
import { zodToJsonSchema } from 'zod-to-json-schema';
|
|
10
11
|
import {
|
|
@@ -37,6 +38,9 @@ import {
|
|
|
37
38
|
export interface SchemaCategory {
|
|
38
39
|
name: string;
|
|
39
40
|
description: string;
|
|
41
|
+
// Every drill target valid for `seeflow schema <name> <subname>`. Lets the
|
|
42
|
+
// agent pick a variant without a second round-trip to listCategorySubnames.
|
|
43
|
+
subnames: string[];
|
|
40
44
|
}
|
|
41
45
|
|
|
42
46
|
export interface SchemaPayload {
|
|
@@ -44,13 +48,52 @@ export interface SchemaPayload {
|
|
|
44
48
|
notes: string[];
|
|
45
49
|
}
|
|
46
50
|
|
|
51
|
+
// Hint payload attached to every schema response so the agent can drill in
|
|
52
|
+
// further without round-tripping. `examples` are ready-to-paste jq paths;
|
|
53
|
+
// `dataFields` lists the node-variant `data.<field>` keys (single-variant
|
|
54
|
+
// lookups only — undefined for non-node categories or category-level
|
|
55
|
+
// responses). `rootPath` is the jq prefix that reaches the schema body at
|
|
56
|
+
// this response level (`.categories` on the index, `.schemas` on a category,
|
|
57
|
+
// `.schemas.<subname>` on a drill) — present in the plain (non-`--jq`)
|
|
58
|
+
// response the agent reads first, so it never has to guess the prefix.
|
|
59
|
+
export interface JqHints {
|
|
60
|
+
dataFields?: string[];
|
|
61
|
+
examples: string[];
|
|
62
|
+
rootPath: string;
|
|
63
|
+
tip?: string;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
// Appended to every `jqHints.tip`. The `--jq` filter runs against the schema
|
|
67
|
+
// object itself; the `{ result }` wrapper the CLI prints under `--jq` is
|
|
68
|
+
// presentational, so a filter must never be prefixed with `.result`.
|
|
69
|
+
const JQ_RESULT_TIP =
|
|
70
|
+
'`--jq` runs against this object directly; the `result` wrapper in `--jq` output is presentational — never prefix your filter with `.result`.';
|
|
71
|
+
|
|
72
|
+
const withResultTip = (hint: string): string => `${hint} ${JQ_RESULT_TIP}`;
|
|
73
|
+
|
|
47
74
|
// Draft-07 pin matches the widest tool support; the same target string is
|
|
48
75
|
// used by the MCP `tools/list` JSON Schemas (default in zod-to-json-schema)
|
|
49
76
|
// so consumers see one consistent dialect across the whole surface.
|
|
50
77
|
const toJsonSchema = (schema: ZodTypeAny): unknown =>
|
|
51
78
|
zodToJsonSchema(schema, { $refStrategy: 'none', target: 'jsonSchema7' });
|
|
52
79
|
|
|
53
|
-
|
|
80
|
+
// Recipe block returned on the schema index (CLI / REST / MCP) so the agent
|
|
81
|
+
// sees the drill + filter pattern in the response itself, not just in
|
|
82
|
+
// `seeflow help schema`.
|
|
83
|
+
export const SCHEMA_INDEX_USAGE = {
|
|
84
|
+
drill: 'seeflow schema <category> [<subname>]',
|
|
85
|
+
filter: 'seeflow schema <category> [<subname>] --jq <jq-path>',
|
|
86
|
+
examples: [
|
|
87
|
+
'seeflow schema node',
|
|
88
|
+
'seeflow schema node rectangle',
|
|
89
|
+
'seeflow schema node rectangle --jq .schemas.rectangle.properties.data.properties.playAction',
|
|
90
|
+
'seeflow schema action playAction',
|
|
91
|
+
],
|
|
92
|
+
} as const;
|
|
93
|
+
|
|
94
|
+
// Description metadata. `subnames` are filled in by listSchemaCategories()
|
|
95
|
+
// at call time from PAYLOADS, so the two stay in lockstep automatically.
|
|
96
|
+
const CATEGORY_META: Array<Omit<SchemaCategory, 'subnames'>> = [
|
|
54
97
|
{ name: 'flow', description: 'Top-level flow.json envelope.' },
|
|
55
98
|
{
|
|
56
99
|
name: 'node',
|
|
@@ -71,6 +114,11 @@ const CATEGORIES: SchemaCategory[] = [
|
|
|
71
114
|
description:
|
|
72
115
|
"Sidecar shape written to <project>/nodes/<id>/spec.json for type:'component' nodes. Carries the json-render element tree, initial state, and named actions the renderer dispatches on user input.",
|
|
73
116
|
},
|
|
117
|
+
{
|
|
118
|
+
name: 'componentCatalog',
|
|
119
|
+
description:
|
|
120
|
+
'The legal values for componentSpec.elements[].type and the props each accepts. Drill: seeflow schema componentCatalog <Name>.',
|
|
121
|
+
},
|
|
74
122
|
{ name: 'style', description: 'style.json (studio-owned).' },
|
|
75
123
|
];
|
|
76
124
|
|
|
@@ -101,6 +149,7 @@ const PAYLOADS: Record<string, SchemaPayload> = {
|
|
|
101
149
|
"type:'image' data.path must start with 'nodes/<id>/'.",
|
|
102
150
|
"scriptPath in playAction/statusAction is relative to nodes/<nodeId>/ and may not contain '..' or absolute paths.",
|
|
103
151
|
"type:'component' nodes have no `spec` field on disk — the spec lives in <project>/nodes/<id>/spec.json (see `seeflow schema componentSpec`). The resolver inlines it into data.spec for runtime / SSE broadcasts.",
|
|
152
|
+
'The legal `elements[].type` values and their props are listed under `seeflow schema componentCatalog`.',
|
|
104
153
|
"stateSource SHOULD be set on every node that has a statusAction — kind:'request' for poll-based (REST, healthcheck, DB query), kind:'event' for push-based (SSE, webhook, queue, message bus).",
|
|
105
154
|
'stateSource may also be set without a statusAction on representational/architecture diagrams to signal data-flow intent (poll vs push) without wiring a runtime probe.',
|
|
106
155
|
],
|
|
@@ -132,6 +181,22 @@ const PAYLOADS: Record<string, SchemaPayload> = {
|
|
|
132
181
|
"spec.json is the on-disk source of truth for type:'component' nodes; the resolver inlines it into data.spec at read time and splitFlow strips it back out before writing flow.json so the sidecar is never double-stored.",
|
|
133
182
|
'elements is keyed by element id; `root` names the entry element. Element ids referenced from children / actions must exist in elements.',
|
|
134
183
|
'state and actions are both keyed by user-chosen names. Action handles in the rendered UI reference these names; see `seeflow schema action` for the per-action shape.',
|
|
184
|
+
'The legal `elements[].type` values and their props are listed under `seeflow schema componentCatalog`.',
|
|
185
|
+
],
|
|
186
|
+
},
|
|
187
|
+
componentCatalog: {
|
|
188
|
+
// One subname per catalog entry; schema body = the props object that
|
|
189
|
+
// element type accepts. Built dynamically so adding a catalog component
|
|
190
|
+
// surfaces here automatically (the canvas catalog is the single source).
|
|
191
|
+
schemas: Object.fromEntries(
|
|
192
|
+
Object.entries(componentCatalog.components).map(([name, def]) => [
|
|
193
|
+
name,
|
|
194
|
+
toJsonSchema(def.props),
|
|
195
|
+
]),
|
|
196
|
+
),
|
|
197
|
+
notes: [
|
|
198
|
+
"Each key is a legal componentSpec.elements[].type; its schema is the props object that element type accepts. Set them on the element's `props` field.",
|
|
199
|
+
'Any prop value may instead be a { $state } / { $action } / { $cond,$then,$else } ref resolved by the json-render runtime at render time — the per-prop schema shows the concrete (non-ref) shape.',
|
|
135
200
|
],
|
|
136
201
|
},
|
|
137
202
|
style: {
|
|
@@ -141,7 +206,10 @@ const PAYLOADS: Record<string, SchemaPayload> = {
|
|
|
141
206
|
};
|
|
142
207
|
|
|
143
208
|
export function listSchemaCategories(): SchemaCategory[] {
|
|
144
|
-
return
|
|
209
|
+
return CATEGORY_META.map((c) => ({
|
|
210
|
+
...c,
|
|
211
|
+
subnames: Object.keys(PAYLOADS[c.name]?.schemas ?? {}),
|
|
212
|
+
}));
|
|
145
213
|
}
|
|
146
214
|
|
|
147
215
|
export function getSchemaCategory(name: string): SchemaPayload | null {
|
|
@@ -151,7 +219,7 @@ export function getSchemaCategory(name: string): SchemaPayload | null {
|
|
|
151
219
|
}
|
|
152
220
|
|
|
153
221
|
export function schemaCategoryNames(): string[] {
|
|
154
|
-
return
|
|
222
|
+
return CATEGORY_META.map((c) => c.name);
|
|
155
223
|
}
|
|
156
224
|
|
|
157
225
|
// Drill into one named schema inside a category — e.g. ('node', 'rectangle')
|
|
@@ -176,3 +244,99 @@ export function listCategorySubnames(category: string): string[] | null {
|
|
|
176
244
|
if (!payload) return null;
|
|
177
245
|
return Object.keys(payload.schemas);
|
|
178
246
|
}
|
|
247
|
+
|
|
248
|
+
// Top-level keys under `data.properties` for a single node variant — i.e.
|
|
249
|
+
// the per-shape data fields an author actually sets on a flow.json node
|
|
250
|
+
// (`name`, `icon`, `playAction`, etc.). Returns null when the variant has
|
|
251
|
+
// no `data.properties` wrapper (action / connector / style / componentSpec
|
|
252
|
+
// schemas, plus anything malformed). Pure helper consumed by buildJqHints
|
|
253
|
+
// to surface concrete drill-down paths.
|
|
254
|
+
export function getDataFieldNames(category: string, subname: string): string[] | null {
|
|
255
|
+
const sub = PAYLOADS[category]?.schemas[subname] as
|
|
256
|
+
| { properties?: { data?: { properties?: Record<string, unknown> } } }
|
|
257
|
+
| undefined;
|
|
258
|
+
const dataProps = sub?.properties?.data?.properties;
|
|
259
|
+
if (!dataProps) return null;
|
|
260
|
+
return Object.keys(dataProps);
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
// Build ready-to-paste jq path examples for a schema response. When `subname`
|
|
264
|
+
// is provided, the examples drill into that single variant — including one
|
|
265
|
+
// path per `data.<field>` so the agent can `--jq` straight to (say)
|
|
266
|
+
// `.schemas.rectangle.properties.data.properties.playAction` without first
|
|
267
|
+
// reading the whole envelope. When `subname` is omitted, the hints cover the
|
|
268
|
+
// whole category (iteration, one sample variant, notes). `dataFields` only
|
|
269
|
+
// surfaces on single-variant lookups for shapes that actually carry a
|
|
270
|
+
// `data.properties` wrapper.
|
|
271
|
+
export function buildJqHints(category: string, subname?: string): JqHints | null {
|
|
272
|
+
const payload = PAYLOADS[category];
|
|
273
|
+
if (!payload) return null;
|
|
274
|
+
if (subname) {
|
|
275
|
+
if (payload.schemas[subname] === undefined) return null;
|
|
276
|
+
const dataFields = getDataFieldNames(category, subname);
|
|
277
|
+
const examples = [
|
|
278
|
+
`.schemas.${subname}`,
|
|
279
|
+
`.schemas.${subname}.required`,
|
|
280
|
+
...(dataFields && dataFields.length > 0
|
|
281
|
+
? [
|
|
282
|
+
`.schemas.${subname}.properties.data.properties`,
|
|
283
|
+
...dataFields
|
|
284
|
+
.slice(0, 6)
|
|
285
|
+
.map((f) => `.schemas.${subname}.properties.data.properties.${f}`),
|
|
286
|
+
]
|
|
287
|
+
: [`.schemas.${subname}.properties`]),
|
|
288
|
+
'.notes',
|
|
289
|
+
'.notes[]',
|
|
290
|
+
];
|
|
291
|
+
const hint = dataFields
|
|
292
|
+
? `dataFields lists every \`data.<field>\` available on this variant — point \`--jq\` at any of them with \`.schemas.${subname}.properties.data.properties.<field>\`.`
|
|
293
|
+
: `Use \`--jq\` to pluck a single property — e.g. \`.schemas.${subname}.required\`.`;
|
|
294
|
+
return {
|
|
295
|
+
...(dataFields ? { dataFields } : {}),
|
|
296
|
+
examples,
|
|
297
|
+
rootPath: `.schemas.${subname}`,
|
|
298
|
+
tip: withResultTip(hint),
|
|
299
|
+
};
|
|
300
|
+
}
|
|
301
|
+
const subs = Object.keys(payload.schemas);
|
|
302
|
+
const sample = subs[0];
|
|
303
|
+
if (!sample) {
|
|
304
|
+
return {
|
|
305
|
+
examples: ['.schemas', '.notes', '.notes[]'],
|
|
306
|
+
rootPath: '.schemas',
|
|
307
|
+
tip: JQ_RESULT_TIP,
|
|
308
|
+
};
|
|
309
|
+
}
|
|
310
|
+
const examples = [
|
|
311
|
+
'.schemas',
|
|
312
|
+
`.schemas.${sample}`,
|
|
313
|
+
`.schemas.${sample}.required`,
|
|
314
|
+
`.schemas.${sample}.properties.data.properties`,
|
|
315
|
+
'.schemas[]',
|
|
316
|
+
'.notes',
|
|
317
|
+
'.notes[]',
|
|
318
|
+
];
|
|
319
|
+
return {
|
|
320
|
+
examples,
|
|
321
|
+
rootPath: '.schemas',
|
|
322
|
+
tip: withResultTip(
|
|
323
|
+
subs.length > 1
|
|
324
|
+
? `Pass \`seeflow schema ${category} <subname>\` (one of: ${subs.join(', ')}) to drop the other ${subs.length - 1} variant(s) from the payload before \`--jq\`-ing.`
|
|
325
|
+
: `Single-variant category — \`--jq\` paths drill straight into \`.schemas.${sample}\`.`,
|
|
326
|
+
),
|
|
327
|
+
};
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
// jqHints for the schema index (`seeflow schema` with no category). The index
|
|
331
|
+
// payload is `{ categories, usage }`, so `--jq` filters root at `.categories`.
|
|
332
|
+
// Surfaced so the index carries the same `rootPath` affordance as every drill
|
|
333
|
+
// level — the agent never has to guess the prefix.
|
|
334
|
+
export function buildIndexJqHints(): JqHints {
|
|
335
|
+
return {
|
|
336
|
+
examples: ['.categories', '.categories[].name', '.usage', '.usage.examples'],
|
|
337
|
+
rootPath: '.categories',
|
|
338
|
+
tip: withResultTip(
|
|
339
|
+
'Each entry under `.categories` names a drill target — pass its `name` as `<category>`.',
|
|
340
|
+
),
|
|
341
|
+
};
|
|
342
|
+
}
|
package/src/schema.ts
CHANGED
|
@@ -14,25 +14,26 @@ const HttpMethodSchema = z.enum(['GET', 'POST', 'PUT', 'PATCH', 'DELETE']);
|
|
|
14
14
|
// them to actual CSS values (theme-aware, light + dark).
|
|
15
15
|
export const ColorTokenSchema = z.enum([
|
|
16
16
|
// `'none'` renders transparent border / fill on nodes (no stroke, no fill).
|
|
17
|
-
// Hidden from the
|
|
18
|
-
// and
|
|
17
|
+
// Hidden from the connector-color picker — invisible edges aren't useful,
|
|
18
|
+
// and `'default'` already covers "inherit".
|
|
19
19
|
'none',
|
|
20
20
|
'default',
|
|
21
21
|
'white',
|
|
22
22
|
'slate',
|
|
23
23
|
'gray',
|
|
24
24
|
'red',
|
|
25
|
-
'rose',
|
|
26
25
|
'orange',
|
|
27
26
|
'amber',
|
|
27
|
+
'yellow',
|
|
28
28
|
'lime',
|
|
29
29
|
'green',
|
|
30
30
|
'teal',
|
|
31
31
|
'cyan',
|
|
32
|
+
'sky',
|
|
32
33
|
'blue',
|
|
33
34
|
'indigo',
|
|
34
35
|
'violet',
|
|
35
|
-
'
|
|
36
|
+
'fuchsia',
|
|
36
37
|
'pink',
|
|
37
38
|
]);
|
|
38
39
|
|
|
@@ -47,7 +48,6 @@ const NodeVisualBaseShape = {
|
|
|
47
48
|
borderSize: z.number().min(0).optional(),
|
|
48
49
|
borderStyle: z.enum(['solid', 'dashed', 'dotted']).optional(),
|
|
49
50
|
fontSize: z.number().positive().optional(),
|
|
50
|
-
textColor: ColorTokenSchema.optional(),
|
|
51
51
|
// Horizontal alignment for the node's text content. Defaults to 'center'
|
|
52
52
|
// at render time when omitted; explicit picks from the toolbar's Align
|
|
53
53
|
// toggle persist here.
|
|
@@ -218,7 +218,12 @@ export const NodeTypeSchema = z.enum([
|
|
|
218
218
|
// superRefine wired in a later story.
|
|
219
219
|
|
|
220
220
|
export const ComponentSpecElementSchema = z.object({
|
|
221
|
-
type: z
|
|
221
|
+
type: z
|
|
222
|
+
.string()
|
|
223
|
+
.min(1)
|
|
224
|
+
.describe(
|
|
225
|
+
'Component name from the catalog — see `seeflow schema componentCatalog` for the legal values and the props each type accepts.',
|
|
226
|
+
),
|
|
222
227
|
props: z.record(z.string(), z.unknown()).optional(),
|
|
223
228
|
children: z.array(z.string()).optional(),
|
|
224
229
|
watch: z.record(z.string(), z.unknown()).optional(),
|
|
@@ -711,7 +716,6 @@ const NodeStyleSchema = z
|
|
|
711
716
|
borderSize: z.number().min(0).optional(),
|
|
712
717
|
borderStyle: z.enum(['solid', 'dashed', 'dotted']).optional(),
|
|
713
718
|
fontSize: z.number().positive().optional(),
|
|
714
|
-
textColor: ColorTokenSchema.optional(),
|
|
715
719
|
textAlign: z.enum(['left', 'center', 'right']).optional(),
|
|
716
720
|
cornerRadius: z.number().min(0).optional(),
|
|
717
721
|
shadow: z.number().int().min(0).max(5).optional(),
|
package/src/server.ts
CHANGED
|
@@ -227,7 +227,12 @@ export function serve(options: ServeOptions = {}) {
|
|
|
227
227
|
const hostname = options.hostname ?? '0.0.0.0';
|
|
228
228
|
mkdirSync(seeflowHome(), { recursive: true });
|
|
229
229
|
const app = createApp(options);
|
|
230
|
-
|
|
230
|
+
// Bun's default per-connection idle timeout (~10s) reaps long-lived SSE
|
|
231
|
+
// streams between heartbeats, forcing the browser's EventSource to reconnect
|
|
232
|
+
// (each reconnect re-fires `hello` → a client refetch). Raise it well above
|
|
233
|
+
// the SSE heartbeat cadence so the keep-alive lands first and the stream
|
|
234
|
+
// stays warm. Max accepted by Bun is 255s.
|
|
235
|
+
return Bun.serve({ port, hostname, idleTimeout: 120, fetch: app.fetch });
|
|
231
236
|
}
|
|
232
237
|
|
|
233
238
|
if (import.meta.main) {
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{U as a,C as n}from"./mermaid.core-CRo4rzDL.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-2Se8RGwW.js";import{a as i}from"./mermaid.core-CRo4rzDL.js";import"./index-DFpY3RpV.js";import"./chunk-FMBD7UC4-BJX_21R2.js";import"./chunk-ND2GUHAM-DFBKXknR.js";import"./chunk-55IACEB6-DlboNFJr.js";import"./chunk-2J33WTMH-9vQ1xqy3.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-2Se8RGwW.js";import{a as i}from"./mermaid.core-CRo4rzDL.js";import"./index-DFpY3RpV.js";import"./chunk-FMBD7UC4-BJX_21R2.js";import"./chunk-ND2GUHAM-DFBKXknR.js";import"./chunk-55IACEB6-DlboNFJr.js";import"./chunk-2J33WTMH-9vQ1xqy3.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};
|