@caddis/cli 0.4.45 → 0.4.46
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/bundles/antigravity-plugin/plugin.json +1 -1
- package/bundles/antigravity-plugin/skills/flow-studio/README.md +46 -7
- package/bundles/antigravity-plugin/skills/flow-studio/SKILL.md +80 -81
- package/bundles/antigravity-plugin/skills/flow-studio/examples/README.md +8 -0
- package/bundles/antigravity-plugin/skills/flow-studio/examples/agent-journey.json +103 -0
- package/bundles/antigravity-plugin/skills/flow-studio/examples/approval-flow.json +134 -0
- package/bundles/antigravity-plugin/skills/flow-studio/examples/ci-cd-pipeline.json +132 -0
- package/bundles/antigravity-plugin/skills/flow-studio/examples/incident-timeline.json +109 -0
- package/bundles/antigravity-plugin/skills/flow-studio/examples/order-desk.json +99 -0
- package/bundles/antigravity-plugin/skills/flow-studio/examples/service-map.json +133 -0
- package/bundles/antigravity-plugin/skills/flow-studio/examples/state-machine.json +106 -0
- package/bundles/antigravity-plugin/skills/flow-studio/examples/ticket-lifecycle.json +107 -0
- package/bundles/antigravity-plugin/skills/flow-studio/model.schema.json +27 -8
- package/bundles/antigravity-plugin/skills/flow-studio/react/FlowStudioView.test.tsx +82 -0
- package/bundles/antigravity-plugin/skills/flow-studio/react/FlowStudioView.tsx +67 -0
- package/bundles/antigravity-plugin/skills/flow-studio/react/README.md +37 -0
- package/bundles/antigravity-plugin/skills/flow-studio/react/index.ts +3 -0
- package/bundles/antigravity-plugin/skills/flow-studio/react/native/FlowCanvas.tsx +58 -0
- package/bundles/antigravity-plugin/skills/flow-studio/react/native/Inspector.tsx +27 -0
- package/bundles/antigravity-plugin/skills/flow-studio/react/native/index.ts +6 -0
- package/bundles/antigravity-plugin/skills/flow-studio/react/native/native.css +18 -0
- package/bundles/antigravity-plugin/skills/flow-studio/react/native/native.test.tsx +161 -0
- package/bundles/antigravity-plugin/skills/flow-studio/react/native/useFlowGeometry.ts +22 -0
- package/bundles/antigravity-plugin/skills/flow-studio/react/native/useTrace.ts +29 -0
- package/bundles/antigravity-plugin/skills/flow-studio/react/native/useViewport.ts +75 -0
- package/bundles/antigravity-plugin/skills/flow-studio/react/states.tsx +13 -0
- package/bundles/antigravity-plugin/skills/flow-studio/references/design-language.md +169 -0
- package/bundles/antigravity-plugin/skills/flow-studio/references/implement-in-app.md +213 -0
- package/bundles/antigravity-plugin/skills/flow-studio/references/model-schema.md +254 -0
- package/bundles/antigravity-plugin/skills/flow-studio/references/notes-and-spec.md +74 -0
- package/bundles/antigravity-plugin/skills/flow-studio/references/patterns.md +385 -49
- package/bundles/antigravity-plugin/skills/flow-studio/references/ux-rules.md +91 -0
- package/bundles/antigravity-plugin/skills/flow-studio/references/verify.md +124 -0
- package/bundles/antigravity-plugin/skills/flow-studio/scripts/build-engine.mjs +54 -14
- package/bundles/antigravity-plugin/skills/flow-studio/scripts/build.mjs +21 -4
- package/bundles/antigravity-plugin/skills/flow-studio/scripts/check.mjs +320 -28
- package/bundles/antigravity-plugin/skills/flow-studio/scripts/default-notes.json +67 -0
- package/bundles/antigravity-plugin/skills/flow-studio/scripts/lib/auto-entry-guard.mjs +5 -0
- package/bundles/antigravity-plugin/skills/flow-studio/scripts/lib/auto-entry-guard.test.mjs +14 -0
- package/bundles/antigravity-plugin/skills/flow-studio/scripts/lib/auto-entry.test.mjs +31 -0
- package/bundles/antigravity-plugin/skills/flow-studio/scripts/lib/build-engine.test.mjs +30 -2
- package/bundles/antigravity-plugin/skills/flow-studio/scripts/lib/check-args.mjs +18 -0
- package/bundles/antigravity-plugin/skills/flow-studio/scripts/lib/check-args.test.mjs +15 -0
- package/bundles/antigravity-plugin/skills/flow-studio/scripts/lib/check-selftest.test.mjs +64 -4
- package/bundles/antigravity-plugin/skills/flow-studio/scripts/lib/cli.test.mjs +115 -0
- package/bundles/antigravity-plugin/skills/flow-studio/scripts/lib/demo-pack.mjs +23 -0
- package/bundles/antigravity-plugin/skills/flow-studio/scripts/lib/demo-pack.test.mjs +34 -0
- package/bundles/antigravity-plugin/skills/flow-studio/scripts/lib/docs.test.mjs +128 -0
- package/bundles/antigravity-plugin/skills/flow-studio/scripts/lib/library.test.mjs +26 -0
- package/bundles/antigravity-plugin/skills/flow-studio/scripts/lib/react-proof-cleanup.mjs +12 -0
- package/bundles/antigravity-plugin/skills/flow-studio/scripts/lib/react-proof-cleanup.test.mjs +45 -0
- package/bundles/antigravity-plugin/skills/flow-studio/scripts/lib/react-proof-page.mjs +3 -0
- package/bundles/antigravity-plugin/skills/flow-studio/scripts/lib/react-proof-page.test.mjs +9 -0
- package/bundles/antigravity-plugin/skills/flow-studio/scripts/react-proof.mjs +92 -0
- package/bundles/antigravity-plugin/skills/flow-studio/scripts/validate.mjs +5 -1
- package/bundles/antigravity-plugin/skills/flow-studio/src/autolayout.test.ts +78 -0
- package/bundles/antigravity-plugin/skills/flow-studio/src/autolayout.ts +132 -0
- package/bundles/antigravity-plugin/skills/flow-studio/src/chrome.ts +11 -7
- package/bundles/antigravity-plugin/skills/flow-studio/src/controls.ts +8 -0
- package/bundles/antigravity-plugin/skills/flow-studio/src/ctx.ts +16 -0
- package/bundles/antigravity-plugin/skills/flow-studio/src/diff.test.ts +31 -0
- package/bundles/antigravity-plugin/skills/flow-studio/src/diff.ts +34 -0
- package/bundles/antigravity-plugin/skills/flow-studio/src/engine.ts +83 -32
- package/bundles/antigravity-plugin/skills/flow-studio/src/inspector.ts +23 -5
- package/bundles/antigravity-plugin/skills/flow-studio/src/interact.ts +21 -8
- package/bundles/antigravity-plugin/skills/flow-studio/src/layout.test.ts +75 -0
- package/bundles/antigravity-plugin/skills/flow-studio/src/layout.ts +49 -11
- package/bundles/antigravity-plugin/skills/flow-studio/src/lib.ts +20 -0
- package/bundles/antigravity-plugin/skills/flow-studio/src/metrics.test.ts +57 -0
- package/bundles/antigravity-plugin/skills/flow-studio/src/metrics.ts +29 -0
- package/bundles/antigravity-plugin/skills/flow-studio/src/model.test.ts +62 -2
- package/bundles/antigravity-plugin/skills/flow-studio/src/model.ts +101 -16
- package/bundles/antigravity-plugin/skills/flow-studio/src/notes.ts +8 -0
- package/bundles/antigravity-plugin/skills/flow-studio/src/page.ts +21 -0
- package/bundles/antigravity-plugin/skills/flow-studio/src/playback.test.ts +104 -0
- package/bundles/antigravity-plugin/skills/flow-studio/src/playback.ts +106 -0
- package/bundles/antigravity-plugin/skills/flow-studio/src/playbackui.ts +193 -0
- package/bundles/antigravity-plugin/skills/flow-studio/src/render.ts +66 -18
- package/bundles/antigravity-plugin/skills/flow-studio/src/routing.test.ts +21 -1
- package/bundles/antigravity-plugin/skills/flow-studio/src/routing.ts +32 -0
- package/bundles/antigravity-plugin/skills/flow-studio/src/rules.test.ts +48 -1
- package/bundles/antigravity-plugin/skills/flow-studio/src/rules.ts +52 -1
- package/bundles/antigravity-plugin/skills/flow-studio/src/selection.test.ts +12 -0
- package/bundles/antigravity-plugin/skills/flow-studio/src/selection.ts +4 -0
- package/bundles/antigravity-plugin/skills/flow-studio/src/stateCss.test.ts +7 -0
- package/bundles/antigravity-plugin/skills/flow-studio/src/stateCss.ts +1 -0
- package/bundles/antigravity-plugin/skills/flow-studio/src/styles.css +35 -2
- package/bundles/antigravity-plugin/skills/flow-studio/src/trace.test.ts +21 -1
- package/bundles/antigravity-plugin/skills/flow-studio/src/trace.ts +18 -0
- package/bundles/antigravity-plugin/skills/flow-studio/templates/engine.html +986 -74
- package/bundles/antigravity-plugin/skills/flow-studio/templates/engine.shell.html +1 -39
- package/bundles/antigravity-plugin/skills/flow-studio/templates/flow-studio.css +190 -0
- package/bundles/antigravity-plugin/skills/flow-studio/templates/flow-studio.lib.d.mts +1 -0
- package/bundles/antigravity-plugin/skills/flow-studio/templates/flow-studio.lib.mjs +2491 -0
- package/bundles/antigravity-plugin/skills/flow-studio/templates/shell-body.html +50 -0
- package/bundles/codex/.codex/skills/frontend/flow-studio/README.md +46 -7
- package/bundles/codex/.codex/skills/frontend/flow-studio/SKILL.md +80 -81
- package/bundles/codex/.codex/skills/frontend/flow-studio/examples/README.md +8 -0
- package/bundles/codex/.codex/skills/frontend/flow-studio/examples/agent-journey.json +103 -0
- package/bundles/codex/.codex/skills/frontend/flow-studio/examples/approval-flow.json +134 -0
- package/bundles/codex/.codex/skills/frontend/flow-studio/examples/ci-cd-pipeline.json +132 -0
- package/bundles/codex/.codex/skills/frontend/flow-studio/examples/incident-timeline.json +109 -0
- package/bundles/codex/.codex/skills/frontend/flow-studio/examples/order-desk.json +99 -0
- package/bundles/codex/.codex/skills/frontend/flow-studio/examples/service-map.json +133 -0
- package/bundles/codex/.codex/skills/frontend/flow-studio/examples/state-machine.json +106 -0
- package/bundles/codex/.codex/skills/frontend/flow-studio/examples/ticket-lifecycle.json +107 -0
- package/bundles/codex/.codex/skills/frontend/flow-studio/model.schema.json +27 -8
- package/bundles/codex/.codex/skills/frontend/flow-studio/react/FlowStudioView.test.tsx +82 -0
- package/bundles/codex/.codex/skills/frontend/flow-studio/react/FlowStudioView.tsx +67 -0
- package/bundles/codex/.codex/skills/frontend/flow-studio/react/README.md +37 -0
- package/bundles/codex/.codex/skills/frontend/flow-studio/react/index.ts +3 -0
- package/bundles/codex/.codex/skills/frontend/flow-studio/react/native/FlowCanvas.tsx +58 -0
- package/bundles/codex/.codex/skills/frontend/flow-studio/react/native/Inspector.tsx +27 -0
- package/bundles/codex/.codex/skills/frontend/flow-studio/react/native/index.ts +6 -0
- package/bundles/codex/.codex/skills/frontend/flow-studio/react/native/native.css +18 -0
- package/bundles/codex/.codex/skills/frontend/flow-studio/react/native/native.test.tsx +161 -0
- package/bundles/codex/.codex/skills/frontend/flow-studio/react/native/useFlowGeometry.ts +22 -0
- package/bundles/codex/.codex/skills/frontend/flow-studio/react/native/useTrace.ts +29 -0
- package/bundles/codex/.codex/skills/frontend/flow-studio/react/native/useViewport.ts +75 -0
- package/bundles/codex/.codex/skills/frontend/flow-studio/react/states.tsx +13 -0
- package/bundles/codex/.codex/skills/frontend/flow-studio/references/design-language.md +169 -0
- package/bundles/codex/.codex/skills/frontend/flow-studio/references/implement-in-app.md +213 -0
- package/bundles/codex/.codex/skills/frontend/flow-studio/references/model-schema.md +254 -0
- package/bundles/codex/.codex/skills/frontend/flow-studio/references/notes-and-spec.md +74 -0
- package/bundles/codex/.codex/skills/frontend/flow-studio/references/patterns.md +385 -49
- package/bundles/codex/.codex/skills/frontend/flow-studio/references/ux-rules.md +91 -0
- package/bundles/codex/.codex/skills/frontend/flow-studio/references/verify.md +124 -0
- package/bundles/codex/.codex/skills/frontend/flow-studio/scripts/build-engine.mjs +54 -14
- package/bundles/codex/.codex/skills/frontend/flow-studio/scripts/build.mjs +21 -4
- package/bundles/codex/.codex/skills/frontend/flow-studio/scripts/check.mjs +320 -28
- package/bundles/codex/.codex/skills/frontend/flow-studio/scripts/default-notes.json +67 -0
- package/bundles/codex/.codex/skills/frontend/flow-studio/scripts/lib/auto-entry-guard.mjs +5 -0
- package/bundles/codex/.codex/skills/frontend/flow-studio/scripts/lib/auto-entry-guard.test.mjs +14 -0
- package/bundles/codex/.codex/skills/frontend/flow-studio/scripts/lib/auto-entry.test.mjs +31 -0
- package/bundles/codex/.codex/skills/frontend/flow-studio/scripts/lib/build-engine.test.mjs +30 -2
- package/bundles/codex/.codex/skills/frontend/flow-studio/scripts/lib/check-args.mjs +18 -0
- package/bundles/codex/.codex/skills/frontend/flow-studio/scripts/lib/check-args.test.mjs +15 -0
- package/bundles/codex/.codex/skills/frontend/flow-studio/scripts/lib/check-selftest.test.mjs +64 -4
- package/bundles/codex/.codex/skills/frontend/flow-studio/scripts/lib/cli.test.mjs +115 -0
- package/bundles/codex/.codex/skills/frontend/flow-studio/scripts/lib/demo-pack.mjs +23 -0
- package/bundles/codex/.codex/skills/frontend/flow-studio/scripts/lib/demo-pack.test.mjs +34 -0
- package/bundles/codex/.codex/skills/frontend/flow-studio/scripts/lib/docs.test.mjs +128 -0
- package/bundles/codex/.codex/skills/frontend/flow-studio/scripts/lib/library.test.mjs +26 -0
- package/bundles/codex/.codex/skills/frontend/flow-studio/scripts/lib/react-proof-cleanup.mjs +12 -0
- package/bundles/codex/.codex/skills/frontend/flow-studio/scripts/lib/react-proof-cleanup.test.mjs +45 -0
- package/bundles/codex/.codex/skills/frontend/flow-studio/scripts/lib/react-proof-page.mjs +3 -0
- package/bundles/codex/.codex/skills/frontend/flow-studio/scripts/lib/react-proof-page.test.mjs +9 -0
- package/bundles/codex/.codex/skills/frontend/flow-studio/scripts/react-proof.mjs +92 -0
- package/bundles/codex/.codex/skills/frontend/flow-studio/scripts/validate.mjs +5 -1
- package/bundles/codex/.codex/skills/frontend/flow-studio/src/autolayout.test.ts +78 -0
- package/bundles/codex/.codex/skills/frontend/flow-studio/src/autolayout.ts +132 -0
- package/bundles/codex/.codex/skills/frontend/flow-studio/src/chrome.ts +11 -7
- package/bundles/codex/.codex/skills/frontend/flow-studio/src/controls.ts +8 -0
- package/bundles/codex/.codex/skills/frontend/flow-studio/src/ctx.ts +16 -0
- package/bundles/codex/.codex/skills/frontend/flow-studio/src/diff.test.ts +31 -0
- package/bundles/codex/.codex/skills/frontend/flow-studio/src/diff.ts +34 -0
- package/bundles/codex/.codex/skills/frontend/flow-studio/src/engine.ts +83 -32
- package/bundles/codex/.codex/skills/frontend/flow-studio/src/inspector.ts +23 -5
- package/bundles/codex/.codex/skills/frontend/flow-studio/src/interact.ts +21 -8
- package/bundles/codex/.codex/skills/frontend/flow-studio/src/layout.test.ts +75 -0
- package/bundles/codex/.codex/skills/frontend/flow-studio/src/layout.ts +49 -11
- package/bundles/codex/.codex/skills/frontend/flow-studio/src/lib.ts +20 -0
- package/bundles/codex/.codex/skills/frontend/flow-studio/src/metrics.test.ts +57 -0
- package/bundles/codex/.codex/skills/frontend/flow-studio/src/metrics.ts +29 -0
- package/bundles/codex/.codex/skills/frontend/flow-studio/src/model.test.ts +62 -2
- package/bundles/codex/.codex/skills/frontend/flow-studio/src/model.ts +101 -16
- package/bundles/codex/.codex/skills/frontend/flow-studio/src/notes.ts +8 -0
- package/bundles/codex/.codex/skills/frontend/flow-studio/src/page.ts +21 -0
- package/bundles/codex/.codex/skills/frontend/flow-studio/src/playback.test.ts +104 -0
- package/bundles/codex/.codex/skills/frontend/flow-studio/src/playback.ts +106 -0
- package/bundles/codex/.codex/skills/frontend/flow-studio/src/playbackui.ts +193 -0
- package/bundles/codex/.codex/skills/frontend/flow-studio/src/render.ts +66 -18
- package/bundles/codex/.codex/skills/frontend/flow-studio/src/routing.test.ts +21 -1
- package/bundles/codex/.codex/skills/frontend/flow-studio/src/routing.ts +32 -0
- package/bundles/codex/.codex/skills/frontend/flow-studio/src/rules.test.ts +48 -1
- package/bundles/codex/.codex/skills/frontend/flow-studio/src/rules.ts +52 -1
- package/bundles/codex/.codex/skills/frontend/flow-studio/src/selection.test.ts +12 -0
- package/bundles/codex/.codex/skills/frontend/flow-studio/src/selection.ts +4 -0
- package/bundles/codex/.codex/skills/frontend/flow-studio/src/stateCss.test.ts +7 -0
- package/bundles/codex/.codex/skills/frontend/flow-studio/src/stateCss.ts +1 -0
- package/bundles/codex/.codex/skills/frontend/flow-studio/src/styles.css +35 -2
- package/bundles/codex/.codex/skills/frontend/flow-studio/src/trace.test.ts +21 -1
- package/bundles/codex/.codex/skills/frontend/flow-studio/src/trace.ts +18 -0
- package/bundles/codex/.codex/skills/frontend/flow-studio/templates/engine.html +986 -74
- package/bundles/codex/.codex/skills/frontend/flow-studio/templates/engine.shell.html +1 -39
- package/bundles/codex/.codex/skills/frontend/flow-studio/templates/flow-studio.css +190 -0
- package/bundles/codex/.codex/skills/frontend/flow-studio/templates/flow-studio.lib.d.mts +1 -0
- package/bundles/codex/.codex/skills/frontend/flow-studio/templates/flow-studio.lib.mjs +2491 -0
- package/bundles/codex/.codex/skills/frontend/flow-studio/templates/shell-body.html +50 -0
- package/bundles/manifest.json +2 -2
- package/package.json +1 -1
|
@@ -70,15 +70,21 @@
|
|
|
70
70
|
.bandlabel b { font-size:13px; } .bandlabel .bd { font-size:10.5px; font-weight:700; padding:0 6px; border:1px solid currentColor; color:var(--muted); letter-spacing:.03em; text-transform:uppercase; }
|
|
71
71
|
.bandlabel .bd.t-ok { color:var(--ok); } .bandlabel .bd.t-warn { color:var(--warn); } .bandlabel .bn { font-size:11.5px; color:var(--muted); }
|
|
72
72
|
.node { position:absolute; background:var(--panel); border:1px solid var(--edge); border-radius:8px; padding:5px 10px 7px; box-shadow:var(--shadow); transition:opacity .35s, transform .35s, box-shadow .2s, border-color .2s; cursor:pointer; z-index:2; }
|
|
73
|
+
.node.gateway { border:0; background:transparent; box-shadow:none; padding:0; border-radius:0; display:flex; align-items:center; justify-content:center; }
|
|
74
|
+
.node.gateway svg.gw { position:absolute; inset:0; width:100%; height:100%; overflow:visible; }
|
|
75
|
+
.node.gateway polygon { stroke-width:2; vector-effect:non-scaling-stroke; }
|
|
76
|
+
.node.gateway .gw-title { position:relative; width:58%; text-align:center; font-size:11px; font-weight:600; line-height:1.2; color:var(--fg); overflow:hidden; display:-webkit-box; -webkit-line-clamp:2; -webkit-box-orient:vertical; overflow-wrap:anywhere; }
|
|
77
|
+
.node.gateway:hover, .node.gateway.lit, .node.gateway.sel { filter:drop-shadow(0 0 7px var(--accent)); }
|
|
73
78
|
.node.wide { overflow:hidden; }
|
|
74
79
|
.node:hover { border-color:var(--accent); box-shadow:0 0 0 3px var(--glow), var(--shadow); }
|
|
75
80
|
.node .t { display:flex; gap:4px; align-items:flex-start; font-weight:600; line-height:1.25; font-size:13px; }
|
|
76
81
|
.node .t .name { overflow-wrap:anywhere; display:-webkit-box; -webkit-line-clamp:2; -webkit-box-orient:vertical; overflow:hidden; }
|
|
82
|
+
.node .fold { flex:none; color:var(--accent); font-size:11px; }
|
|
77
83
|
.node .s { color:var(--muted); font-size:12px; line-height:1.3; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
|
|
78
84
|
.ev { font-size:10.5px; font-weight:700; letter-spacing:.03em; }
|
|
79
85
|
.node.wide .t { font-weight:500; } .node.wide .s { white-space:normal; }
|
|
80
|
-
.node.ref { padding:4px 9px; border-style:dashed; box-shadow:none; background:color-mix(in srgb, var(--panel) 70%, transparent); } .node.ref .t { font-size:12px; } .node.ref .s { font-size:11px; }
|
|
81
|
-
.node.sel { outline:2px solid var(--accent); outline-offset:2px; } .node.dim { opacity:.28; } .node.off { opacity:0; transform:translateY(8px); pointer-events:none; }
|
|
86
|
+
.node.ref { padding:4px 9px; border-style:dashed; box-shadow:none; background:color-mix(in srgb, var(--panel) 70%, transparent); } .node.ref .t { font-size:12px; } .node.ref .t .name { display:block; min-width:0; white-space:nowrap; text-overflow:ellipsis; } .node.ref .s { font-size:11px; }
|
|
87
|
+
.node.sel { outline:2px solid var(--accent); outline-offset:2px; } .node.dim { opacity:.28; } .node.off { opacity:0; visibility:hidden; transform:translateY(8px); pointer-events:none; }
|
|
82
88
|
.node .bar { position:absolute; left:0; right:0; bottom:0; display:flex; height:4px; overflow:hidden; border-radius:0 0 7px 7px; background:var(--panel2); } .node .bar i { display:block; height:100%; } .bar .good { background:var(--ok); } .bar .neutral { background:var(--muted); } .bar .gap { background:var(--warn); }
|
|
83
89
|
.newdot { display:none; width:7px; height:7px; border-radius:50%; background:var(--accent); margin:5px 4px 0 0; flex:none; } body.alt .node.isnew .newdot { display:inline-block; }
|
|
84
90
|
body.alt .node.isnew.pulse { animation:newring 1.8s ease-out 1; }
|
|
@@ -155,3 +161,30 @@
|
|
|
155
161
|
@keyframes beat { 0%{box-shadow:0 0 0 0 color-mix(in srgb, var(--ok) 60%, transparent);} 70%,100%{box-shadow:0 0 0 9px transparent;} }
|
|
156
162
|
@media (prefers-reduced-motion: reduce) { *, *::before, *::after { animation:none !important; transition:none !important; } path.edge.hot { stroke-dasharray:none; } }
|
|
157
163
|
@media (max-width: 1100px) { .summary { grid-template-columns:1fr; } .workspace { height:auto; } .workspace .canvaswrap { height:75vh; } .insp { width:min(340px, 92%); } #drawer { width:100%; } .layerstrip { grid-template-columns:repeat(3,1fr) !important; } }
|
|
164
|
+
#banner:not([hidden]) { margin:0 14px 10px; padding:8px 12px; color:var(--crit); background:var(--crit-bg); border:1px solid var(--crit); font-size:12px; }
|
|
165
|
+
#playbar:not([hidden]) { display:flex; flex-wrap:wrap; align-items:center; gap:7px; padding:7px 12px; border-top:1px solid var(--rule); background:var(--panel); font-size:12px; }
|
|
166
|
+
#playbar select, #playbar button { font-size:11px; }
|
|
167
|
+
#pbScrub { flex:1 1 140px; min-width:90px; }
|
|
168
|
+
#pbCaption { flex:1 1 100%; color:var(--fg); }
|
|
169
|
+
#pbCounter { font:11px var(--mono); color:var(--fg); }
|
|
170
|
+
#pbCounter.warn { color:var(--warn); } #pbCounter.breach { color:var(--crit); font-weight:700; }
|
|
171
|
+
#pbChoices { display:flex; gap:5px; flex-wrap:wrap; } #pbChoices:empty { display:none; }
|
|
172
|
+
#pbChoices .suggested { border-color:var(--accent); box-shadow:inset 0 -2px 0 var(--accent); }
|
|
173
|
+
circle.token { fill:var(--accent); stroke:var(--panel); stroke-width:2; filter:drop-shadow(0 0 5px var(--accent)); pointer-events:none; }
|
|
174
|
+
path.edge.playing { stroke:var(--accent); stroke-width:3; filter:drop-shadow(0 0 5px var(--accent)); opacity:1; }
|
|
175
|
+
path.edge.visited { stroke:var(--accent); opacity:.7; }
|
|
176
|
+
.node.playing { outline:2px solid var(--accent); outline-offset:2px; }
|
|
177
|
+
/* The pulse runs only while the player really plays; a paused step keeps the plain outline. */
|
|
178
|
+
body.playing .node.playing { animation:selpulse 1.8s ease-out infinite; }
|
|
179
|
+
.node.visited::after { content:"✓"; position:absolute; right:3px; bottom:1px; color:var(--accent); font-size:11px; }
|
|
180
|
+
.node.updated { animation:newring 1.2s ease-out 1; }
|
|
181
|
+
.node.added { animation:rise 1.2s ease-out 1; }
|
|
182
|
+
.node .t .name { min-width:0; flex:1 1 auto; }
|
|
183
|
+
.node .metric-badge { flex:none; max-width:72px; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; position:relative; padding-bottom:3px; text-align:right; font:11px var(--mono); color:var(--accent); }
|
|
184
|
+
.node .metric-badge i { display:block; height:2px; position:absolute; bottom:0; left:0; background:var(--accent); }
|
|
185
|
+
.node .s.has-spark { padding-right:60px; }
|
|
186
|
+
.node .spark { position:absolute; right:6px; bottom:4px; overflow:visible; }
|
|
187
|
+
.node.gateway .metric-badge { position:absolute; right:9px; top:18px; }
|
|
188
|
+
.node.gateway:has(.metric-badge) .gw-title, .node.gateway.has-metrics .gw-title { width:45%; margin-right:42px; }
|
|
189
|
+
.node .spark polyline, .metrics polyline { fill:none; stroke:var(--accent); stroke-width:1.5; }
|
|
190
|
+
.metrics svg { max-width:100%; margin-top:8px; } .metric-range { display:flex; justify-content:space-between; width:300px; max-width:100%; font:10px var(--mono); color:var(--muted); }
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { test } from "node:test";
|
|
2
2
|
import assert from "node:assert/strict";
|
|
3
|
-
import { relatives, connected } from "./trace.ts";
|
|
3
|
+
import { relatives, connected, withinHops } from "./trace.ts";
|
|
4
4
|
|
|
5
5
|
const edges = [{ from: "a", to: "b" }, { from: "b", to: "c" }, { from: "x", to: "c" }, { from: "c", to: "d" }];
|
|
6
6
|
const id = (s: string) => s;
|
|
@@ -17,4 +17,24 @@ test("a cycle terminates", () => {
|
|
|
17
17
|
const cyc = [{ from: "a", to: "b" }, { from: "b", to: "a" }];
|
|
18
18
|
assert.deepEqual([...relatives(cyc, id, "a", "down")].sort(), ["a", "b"]);
|
|
19
19
|
});
|
|
20
|
+
test("a loop-back does not break relatives", () => {
|
|
21
|
+
const cycle = [{ from: "a", to: "b" }, { from: "b", to: "c" }, { from: "c", to: "a" }];
|
|
22
|
+
assert.deepEqual([...relatives(cycle, id, "a", "down")].sort(), ["a", "b", "c"]);
|
|
23
|
+
assert.deepEqual([...relatives(cycle, id, "c", "up")].sort(), ["a", "b", "c"]);
|
|
24
|
+
});
|
|
20
25
|
test("an unknown start returns only itself", () => assert.deepEqual([...relatives(edges, id, "nope", "down")], ["nope"]));
|
|
26
|
+
|
|
27
|
+
test("withinHops includes starts and walks links in either direction", () => {
|
|
28
|
+
assert.deepEqual([...withinHops(edges, id, ["b"], 0)].sort(), ["b"]);
|
|
29
|
+
assert.deepEqual([...withinHops(edges, id, ["b"], 1)].sort(), ["a", "b", "c"]);
|
|
30
|
+
assert.deepEqual([...withinHops(edges, id, ["b"], 2)].sort(), ["a", "b", "c", "d", "x"]);
|
|
31
|
+
});
|
|
32
|
+
test("withinHops canonicalizes aliases and joins multiple starts", () => {
|
|
33
|
+
const canon = (s: string) => s === "b2" ? "b" : s;
|
|
34
|
+
assert.deepEqual([...withinHops(edges, canon, ["b2", "x"], 1)].sort(), ["a", "b", "c", "x"]);
|
|
35
|
+
});
|
|
36
|
+
test("withinHops terminates on cycles and treats a negative radius as zero", () => {
|
|
37
|
+
const cycle = [{ from: "a", to: "b" }, { from: "b", to: "a" }];
|
|
38
|
+
assert.deepEqual([...withinHops(cycle, id, ["a"], 9)].sort(), ["a", "b"]);
|
|
39
|
+
assert.deepEqual([...withinHops(cycle, id, ["a"], -1)], ["a"]);
|
|
40
|
+
});
|
|
@@ -20,3 +20,21 @@ export function relatives(edges: Edge[], canonOf: (id: string) => string, start:
|
|
|
20
20
|
export function connected(edges: Edge[], canonOf: (id: string) => string, start: string): Set<string> {
|
|
21
21
|
return new Set([...relatives(edges, canonOf, start, "up"), ...relatives(edges, canonOf, start, "down")]);
|
|
22
22
|
}
|
|
23
|
+
|
|
24
|
+
/** Undirected breadth-first radius around one or more nodes. */
|
|
25
|
+
export function withinHops(edges: Edge[], canonOf: (id: string) => string, starts: string[], n: number): Set<string> {
|
|
26
|
+
const found = new Set(starts.map(canonOf));
|
|
27
|
+
const radius = Number.isFinite(n) ? Math.max(0, Math.floor(n)) : 0;
|
|
28
|
+
let frontier = [...found];
|
|
29
|
+
for (let hop = 0; hop < radius && frontier.length; hop++) {
|
|
30
|
+
const next: string[] = [];
|
|
31
|
+
const current = new Set(frontier);
|
|
32
|
+
for (const edge of edges) {
|
|
33
|
+
const a = canonOf(edge.from), b = canonOf(edge.to);
|
|
34
|
+
if (current.has(a) && !found.has(b)) { found.add(b); next.push(b); }
|
|
35
|
+
if (current.has(b) && !found.has(a)) { found.add(a); next.push(a); }
|
|
36
|
+
}
|
|
37
|
+
frontier = next;
|
|
38
|
+
}
|
|
39
|
+
return found;
|
|
40
|
+
}
|