@caddis/cli 0.4.48 → 0.4.50

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 (47) hide show
  1. package/bundles/antigravity-plugin/plugin.json +1 -1
  2. package/bundles/antigravity-plugin/skills/flow-studio/SKILL.md +2 -2
  3. package/bundles/antigravity-plugin/skills/flow-studio/model.schema.json +4 -1
  4. package/bundles/antigravity-plugin/skills/flow-studio/react/FlowStudioView.test.tsx +18 -1
  5. package/bundles/antigravity-plugin/skills/flow-studio/react/FlowStudioView.tsx +6 -1
  6. package/bundles/antigravity-plugin/skills/flow-studio/react/README.md +1 -1
  7. package/bundles/antigravity-plugin/skills/flow-studio/references/design-language.md +5 -5
  8. package/bundles/antigravity-plugin/skills/flow-studio/references/model-schema.md +16 -0
  9. package/bundles/antigravity-plugin/skills/flow-studio/scripts/lib/styles.test.mjs +13 -4
  10. package/bundles/antigravity-plugin/skills/flow-studio/src/bars.test.ts +90 -0
  11. package/bundles/antigravity-plugin/skills/flow-studio/src/bars.ts +53 -0
  12. package/bundles/antigravity-plugin/skills/flow-studio/src/ctx.ts +3 -0
  13. package/bundles/antigravity-plugin/skills/flow-studio/src/engine.ts +8 -3
  14. package/bundles/antigravity-plugin/skills/flow-studio/src/layout.test.ts +17 -0
  15. package/bundles/antigravity-plugin/skills/flow-studio/src/layout.ts +2 -1
  16. package/bundles/antigravity-plugin/skills/flow-studio/src/model.ts +11 -0
  17. package/bundles/antigravity-plugin/skills/flow-studio/src/playbackui.ts +1 -1
  18. package/bundles/antigravity-plugin/skills/flow-studio/src/render.ts +4 -2
  19. package/bundles/antigravity-plugin/skills/flow-studio/src/styles.css +6 -1
  20. package/bundles/antigravity-plugin/skills/flow-studio/templates/engine.html +64 -7
  21. package/bundles/antigravity-plugin/skills/flow-studio/templates/flow-studio.css +6 -1
  22. package/bundles/antigravity-plugin/skills/flow-studio/templates/flow-studio.lib.mjs +58 -6
  23. package/bundles/antigravity-plugin/skills/flow-studio/templates/shell-body.html +1 -1
  24. package/bundles/codex/.codex/skills/frontend/flow-studio/SKILL.md +2 -2
  25. package/bundles/codex/.codex/skills/frontend/flow-studio/model.schema.json +4 -1
  26. package/bundles/codex/.codex/skills/frontend/flow-studio/react/FlowStudioView.test.tsx +18 -1
  27. package/bundles/codex/.codex/skills/frontend/flow-studio/react/FlowStudioView.tsx +6 -1
  28. package/bundles/codex/.codex/skills/frontend/flow-studio/react/README.md +1 -1
  29. package/bundles/codex/.codex/skills/frontend/flow-studio/references/design-language.md +5 -5
  30. package/bundles/codex/.codex/skills/frontend/flow-studio/references/model-schema.md +16 -0
  31. package/bundles/codex/.codex/skills/frontend/flow-studio/scripts/lib/styles.test.mjs +13 -4
  32. package/bundles/codex/.codex/skills/frontend/flow-studio/src/bars.test.ts +90 -0
  33. package/bundles/codex/.codex/skills/frontend/flow-studio/src/bars.ts +53 -0
  34. package/bundles/codex/.codex/skills/frontend/flow-studio/src/ctx.ts +3 -0
  35. package/bundles/codex/.codex/skills/frontend/flow-studio/src/engine.ts +8 -3
  36. package/bundles/codex/.codex/skills/frontend/flow-studio/src/layout.test.ts +17 -0
  37. package/bundles/codex/.codex/skills/frontend/flow-studio/src/layout.ts +2 -1
  38. package/bundles/codex/.codex/skills/frontend/flow-studio/src/model.ts +11 -0
  39. package/bundles/codex/.codex/skills/frontend/flow-studio/src/playbackui.ts +1 -1
  40. package/bundles/codex/.codex/skills/frontend/flow-studio/src/render.ts +4 -2
  41. package/bundles/codex/.codex/skills/frontend/flow-studio/src/styles.css +6 -1
  42. package/bundles/codex/.codex/skills/frontend/flow-studio/templates/engine.html +64 -7
  43. package/bundles/codex/.codex/skills/frontend/flow-studio/templates/flow-studio.css +6 -1
  44. package/bundles/codex/.codex/skills/frontend/flow-studio/templates/flow-studio.lib.mjs +58 -6
  45. package/bundles/codex/.codex/skills/frontend/flow-studio/templates/shell-body.html +1 -1
  46. package/bundles/manifest.json +2 -2
  47. package/package.json +1 -1
@@ -69,6 +69,8 @@ function validateModel(input) {
69
69
  const metric = n.metrics;
70
70
  const invalidSeries = metric?.series !== void 0 && (!Array.isArray(metric.series) || metric.series.length > 60 || metric.series.some((v) => !Number.isFinite(v)));
71
71
  if (metric !== void 0 && (!metric || !Number.isFinite(metric.value) || metric.max != null && !Number.isFinite(metric.max) || invalidSeries)) add("error", "metric-invalid", w, "Metrics need finite values and at most 60 finite series points.");
72
+ const badBars = n.bars !== void 0 && (!Array.isArray(n.bars) || n.bars.length > 120 || n.bars.some((b) => !b || typeof b.key !== "string" || b.value !== null && (typeof b.value !== "number" || !Number.isFinite(b.value) || b.value < 0)));
73
+ if (badBars) add("error", "bars-invalid", w, "Bars need a list of at most 120 items, each with a string key and a finite, non-negative value or null.");
72
74
  if (n.sla !== void 0 && (!Number.isFinite(n.sla) || n.sla <= 0)) add("error", "sla-invalid", w, "SLA must be a positive finite number of seconds.");
73
75
  }
74
76
  for (const n of nodes) {
@@ -749,6 +751,7 @@ function on(ctx, target, type, fn, opts) {
749
751
 
750
752
  // src/layout.ts
751
753
  var DEFAULTS = { pitch: 62, top: 64, gap: 34, padX: 24, visible: () => true };
754
+ var BARS_EXTRA = 26;
752
755
  var LANE_PAD_TOP = 38;
753
756
  var LANE_PAD_BOTTOM = 14;
754
757
  function computeGeometry(m, opt = {}) {
@@ -762,7 +765,7 @@ function computeGeometry(m, opt = {}) {
762
765
  const world = { w: Math.max(1, x - o.gap + o.padX), h: 1 };
763
766
  const nodes = {};
764
767
  for (const n of m.nodes) {
765
- const h = NODE_HEIGHT[n.kind] ?? 54;
768
+ const h = (NODE_HEIGHT[n.kind] ?? 54) + (n.bars?.length ? BARS_EXTRA : 0);
766
769
  if (m.layout === "free") {
767
770
  nodes[n.id] = { id: n.id, x: n.x ?? 0, y: n.y ?? 0, w: n.w ?? 190, h: n.h ?? h };
768
771
  continue;
@@ -884,6 +887,47 @@ function sparkline(metric, width = 56, height = 12) {
884
887
  return `<svg class="spark" width="${width}" height="${height}" viewBox="0 0 ${width} ${height}" aria-hidden="true"><polyline points="${points}"/></svg>`;
885
888
  }
886
889
 
890
+ // src/bars.ts
891
+ var BAR_UNIT = 4;
892
+ function barsHtml(bars, height = 22) {
893
+ if (!bars || bars.length === 0) return "";
894
+ const width = bars.length * BAR_UNIT;
895
+ const max = Math.max(1, ...bars.map((b) => b.value ?? 0));
896
+ const lastWithData = bars.map((b) => b.value !== null).lastIndexOf(true);
897
+ const rects = bars.map((b, i) => {
898
+ const x = i * BAR_UNIT;
899
+ const w = BAR_UNIT - 1;
900
+ const label = esc(b.label ?? (b.value === null ? `${b.key}: no data` : `${b.key}: ${b.value}`));
901
+ if (b.value === null) {
902
+ return `<rect class="miss" data-key="${esc(b.key)}" x="${x}" y="${height - 4}" width="${w}" height="4"><title>${label}</title></rect>`;
903
+ }
904
+ const h = Math.max(1, b.value / max * (height - 5));
905
+ const cls = b.kind === "low" ? "low" : i === lastWithData ? "last" : "";
906
+ return `<rect${cls ? ` class="${cls}"` : ""} data-key="${esc(b.key)}" x="${x}" y="${height - h}" width="${w}" height="${h}"><title>${label}</title></rect>`;
907
+ });
908
+ const first = esc(bars[0].key), last = esc(bars[bars.length - 1].key);
909
+ return `<svg class="bars" viewBox="0 0 ${width} ${height}" preserveAspectRatio="none" role="img" aria-label="Bars, ${first} to ${last}">${rects.join("")}</svg>`;
910
+ }
911
+ function markKey(root, key) {
912
+ for (const r of Array.from(root.querySelectorAll("rect[data-key]"))) {
913
+ if (key !== null && r.getAttribute("data-key") === key) r.setAttribute("data-hl", "true");
914
+ else r.removeAttribute("data-hl");
915
+ }
916
+ }
917
+ function installBars(ctx) {
918
+ const set = (key) => {
919
+ if (ctx.hoverKey === key) return;
920
+ ctx.hoverKey = key;
921
+ markKey(ctx.els.world, key);
922
+ ctx.onHoverKey?.(key);
923
+ };
924
+ on(ctx, ctx.els.world, "mouseover", (e) => {
925
+ const bar = e.target?.closest?.("rect[data-key]");
926
+ set(bar ? bar.getAttribute("data-key") : null);
927
+ });
928
+ on(ctx, ctx.els.world, "mouseleave", () => set(null));
929
+ }
930
+
887
931
  // src/render.ts
888
932
  function loopRoute(ctx, fromId, toId, from, to, channel) {
889
933
  const detourFor = (end, other) => {
@@ -920,7 +964,7 @@ function nodeHtml(ctx, n) {
920
964
  const arrow = n.kind === "chip" ? '<span aria-hidden="true">\u2191 </span>' : "";
921
965
  const lead = showWord ? `<b class="ev st-${cssId(sid)}">${esc(word)}</b> \xB7 ` : "";
922
966
  const fold = n.kind === "group" && n.contains?.length ? `<span class="fold">\u25B8 ${n.contains.length}</span>` : "";
923
- return `<div class="t"><span class="newdot" title="Added in this view"></span><span class="name">${arrow}${esc(n.title)}</span>${fold}${badge}</div><div class="s${spark ? " has-spark" : ""}" title="${esc(sub)}">${lead}${esc(sub)}</div>${spark}${bar}${improved}${upgrade}`;
967
+ return `<div class="t"><span class="newdot" title="Added in this view"></span><span class="name">${arrow}${esc(n.title)}</span>${fold}${badge}</div><div class="s${spark ? " has-spark" : ""}" title="${esc(sub)}">${lead}${esc(sub)}</div>${spark}${barsHtml(n.bars)}${bar}${improved}${upgrade}`;
924
968
  }
925
969
  function build(ctx) {
926
970
  const { model, els } = ctx;
@@ -955,7 +999,7 @@ function build(ctx) {
955
999
  for (const n of model.nodes) {
956
1000
  const p = ctx.geom.nodes[n.id];
957
1001
  if (!p) continue;
958
- const d = el("div", "node" + (n.kind === "chip" ? " ref" : "") + ((n.colSpan ?? 1) > 1 ? " wide" : ""));
1002
+ const d = el("div", "node" + (n.kind === "chip" ? " ref" : "") + ((n.colSpan ?? 1) > 1 ? " wide" : "") + (n.bars?.length ? " has-bars" : ""));
959
1003
  d.id = "n_" + n.id;
960
1004
  d.tabIndex = 0;
961
1005
  d.setAttribute("role", "button");
@@ -1090,6 +1134,7 @@ function paint(ctx, fromSwitch = false) {
1090
1134
  d.style.height = r.h + "px";
1091
1135
  }
1092
1136
  }
1137
+ markKey(ctx.els.world, ctx.hoverKey);
1093
1138
  ctx.fn.buildChrome();
1094
1139
  ctx.fn.trace(ctx.selected);
1095
1140
  ctx.fn.renderInspector();
@@ -1983,7 +2028,7 @@ function install7(ctx) {
1983
2028
  let t = 0, idx = -1, playing = false, frame = 0, timer = 0, stamp = 0, choicesKey = "";
1984
2029
  let markedEdges = [];
1985
2030
  let markedNodes = [];
1986
- const token = sv("circle", { id: "token", class: "token", r: "6" });
2031
+ const token = sv("circle", { id: "token", class: "token", r: "4" });
1987
2032
  e.layer.appendChild(token);
1988
2033
  const pathOf = (link) => ctx.edgeEls[ctx.links.findIndex((l) => l.id === link)];
1989
2034
  const nodeOf = (id) => ctx.nodeEls.get(id);
@@ -2310,6 +2355,8 @@ function mount(root, model, opts = {}) {
2310
2355
  root,
2311
2356
  els,
2312
2357
  onSelect: opts.onSelect,
2358
+ onHoverKey: opts.onHoverKey,
2359
+ hoverKey: null,
2313
2360
  notes: opts.notes && opts.notes.length ? opts.notes : model.notes ?? [],
2314
2361
  nodes: new Map(model.nodes.map((n) => [n.id, n])),
2315
2362
  links: model.links,
@@ -2352,6 +2399,7 @@ function mount(root, model, opts = {}) {
2352
2399
  style.textContent = stateCss(model.states);
2353
2400
  install(ctx);
2354
2401
  install2(ctx);
2402
+ installBars(ctx);
2355
2403
  install3(ctx);
2356
2404
  install4(ctx);
2357
2405
  install5(ctx);
@@ -2398,6 +2446,10 @@ function mount(root, model, opts = {}) {
2398
2446
  ctx.fn.fit(animate);
2399
2447
  },
2400
2448
  select: (id) => ctx.fn.select(id),
2449
+ highlightKey: (key) => {
2450
+ ctx.hoverKey = key;
2451
+ markKey(ctx.els.world, key);
2452
+ },
2401
2453
  selected: () => ctx.selected,
2402
2454
  mode: () => ctx.mode,
2403
2455
  setMode: (id) => ctx.fn.setMode(id),
@@ -2423,7 +2475,7 @@ function mount(root, model, opts = {}) {
2423
2475
  const changes = diffModels(ctx.model, prepared);
2424
2476
  const saved = { view: { ...ctx.view }, mode: ctx.mode, selected: ctx.selected, inspectorOpen: els.inspector.classList.contains("open"), query: ctx.query, hops: ctx.hops, filter: ctx.filter, collapsed: new Set(ctx.collapsed), knownGroups: new Set(ctx.model.nodes.filter((n) => n.kind === "group").map((n) => n.id)), playback: playback.playback() };
2425
2477
  api.destroy();
2426
- const replacement = mount(root, prepared, { notes: opts.notes, onSelect: opts.onSelect, restore: saved });
2478
+ const replacement = mount(root, prepared, { notes: opts.notes, onSelect: opts.onSelect, onHoverKey: opts.onHoverKey, restore: saved });
2427
2479
  notifySelection(saved.selected, replacement.selected(), opts.onSelect);
2428
2480
  Object.assign(api, replacement);
2429
2481
  window.FlowStudio = api;
@@ -2448,7 +2500,7 @@ function mount(root, model, opts = {}) {
2448
2500
  }
2449
2501
 
2450
2502
  // src/lib.ts
2451
- var SHELL_BODY_HTML = "<header class=\"top\">\r\n <span class=\"brand\"><i></i>flow-studio</span>\r\n <span class=\"spacer\"></span>\r\n <button id=\"notesBtn\" type=\"button\" aria-pressed=\"false\">Implementation notes (N)</button>\r\n <button id=\"theme\" type=\"button\" aria-label=\"Toggle light and dark\">☀ / ☾</button>\r\n</header>\r\n<main>\r\n <div class=\"titlerow\"><h1 id=\"title\"></h1><span class=\"readline\" id=\"readat\"></span></div>\r\n <p class=\"help\" id=\"help\"></p>\r\n <div id=\"banner\" role=\"alert\" hidden></div>\r\n\r\n <section class=\"summary\"><div class=\"layerstrip\" id=\"layerstrip\" aria-label=\"Completeness by column\"></div><div class=\"tiles\" id=\"kpis\" aria-label=\"Summary\"></div></section>\r\n\r\n <div class=\"toolbar\">\r\n <div class=\"seggrp\" role=\"tablist\" aria-label=\"View\" id=\"modeSwitch\"></div>\r\n <input id=\"q\" type=\"search\" placeholder=\"Find a group or member… ( / )\" aria-label=\"Find a group or member\">\r\n <select id=\"hops\" aria-label=\"Search radius\"><option value=\"0\">This group</option><option value=\"1\">+1 hop</option><option value=\"2\">+2 hops</option><option value=\"3\">+3 hops</option></select>\r\n <span id=\"matchinfo\" class=\"note\" style=\"margin:0\"></span>\r\n </div>\r\n\r\n <div class=\"workspace\" id=\"workspace\">\r\n <section class=\"canvaswrap\">\r\n <div id=\"viewport\" tabindex=\"0\" role=\"application\" aria-label=\"Flow canvas. Scroll to zoom, drag to pan. Keys: V select, H hand, plus and minus zoom, 0 fit, 1 actual size, F zoom to selection, arrows pan.\">\r\n <div id=\"world\"><svg id=\"edges\" aria-hidden=\"true\"><defs><marker id=\"arr\" viewBox=\"0 0 8 8\" refX=\"7\" refY=\"4\" markerWidth=\"9\" markerHeight=\"9\" markerUnits=\"userSpaceOnUse\" orient=\"auto\"><path d=\"M0 0 L8 4 L0 8 z\" fill=\"context-stroke\"/></marker></defs><g id=\"edgeLayer\"></g></svg></div>\r\n <div id=\"cols\" aria-hidden=\"true\"></div>\r\n <div id=\"tools\" role=\"toolbar\" aria-label=\"Canvas controls\" aria-orientation=\"vertical\"></div>\r\n <div id=\"zoomLabel\" aria-hidden=\"true\">100%</div>\r\n </div>\r\n <div id=\"playbar\" hidden aria-label=\"Scenario playback\">\r\n <select id=\"pbScenario\" aria-label=\"Scenario\"></select>\r\n <button id=\"pbPlay\" type=\"button\" aria-label=\"Play\">▶</button>\r\n <button id=\"pbStep\" type=\"button\" aria-label=\"Step\">Step</button>\r\n <button id=\"pbReset\" type=\"button\" aria-label=\"Reset\">Reset</button>\r\n <select id=\"pbSpeed\" aria-label=\"Speed\"><option value=\"0.5\">0.5x</option><option value=\"1\" selected>1x</option><option value=\"2\">2x</option></select>\r\n <input id=\"pbScrub\" type=\"range\" min=\"0\" max=\"1000\" value=\"0\" aria-label=\"Playback position\" aria-valuetext=\"Step 1 of 1\">\r\n <span id=\"pbCaption\"></span><span id=\"pbCounter\"></span><span id=\"pbChoices\"></span>\r\n </div>\r\n <div class=\"keyline\" id=\"legend\" aria-label=\"Legend\"></div>\r\n <aside class=\"insp\" id=\"inspector\" aria-label=\"Inspector\" aria-hidden=\"true\"></aside>\r\n </section>\r\n </div>\r\n <div id=\"live\" class=\"sr\" role=\"status\" aria-live=\"polite\"></div>\r\n\r\n <div class=\"ledger\" id=\"ledger\"></div>\r\n <details class=\"tableview\"><summary>Table view</summary><table class=\"sources\" id=\"tbl\"></table></details>\r\n <details class=\"spec\" id=\"spec\"><summary>Model reference (for the person or agent who builds this)</summary><div id=\"specbody\"></div></details>\r\n</main>\r\n<footer id=\"footer\"></footer>\r\n<aside id=\"drawer\" aria-label=\"Implementation notes\"><h2>Implementation notes</h2><p class=\"note\">Numbered markers on the page match these cards. Hover a card to find its place; click a marker to jump to its card.</p><div id=\"notelist\"></div></aside>\r\n\r\n";
2503
+ var SHELL_BODY_HTML = "<header class=\"top\">\r\n <span class=\"brand\"><i></i>flow-studio</span>\r\n <span class=\"spacer\"></span>\r\n <button id=\"notesBtn\" type=\"button\" aria-pressed=\"false\">Implementation notes (N)</button>\r\n <button id=\"theme\" type=\"button\" aria-label=\"Toggle light and dark\">☀ / ☾</button>\r\n</header>\r\n<main>\r\n <div class=\"titlerow\"><h1 id=\"title\"></h1><span class=\"readline\" id=\"readat\"></span></div>\r\n <p class=\"help\" id=\"help\"></p>\r\n <div id=\"banner\" role=\"alert\" hidden></div>\r\n\r\n <section class=\"summary\"><div class=\"layerstrip\" id=\"layerstrip\" aria-label=\"Completeness by column\"></div><div class=\"tiles\" id=\"kpis\" aria-label=\"Summary\"></div></section>\r\n\r\n <div class=\"toolbar\">\r\n <div class=\"seggrp\" role=\"tablist\" aria-label=\"View\" id=\"modeSwitch\"></div>\r\n <input id=\"q\" type=\"search\" placeholder=\"Find a group or member… ( / )\" aria-label=\"Find a group or member\">\r\n <select id=\"hops\" aria-label=\"Search radius\"><option value=\"0\">This group</option><option value=\"1\">+1 hop</option><option value=\"2\">+2 hops</option><option value=\"3\">+3 hops</option></select>\r\n <span id=\"matchinfo\" class=\"note\" style=\"margin:0\"></span>\r\n </div>\r\n\r\n <div class=\"workspace\" id=\"workspace\">\r\n <section class=\"canvaswrap\">\r\n <div id=\"viewport\" tabindex=\"0\" role=\"application\" aria-label=\"Flow canvas. Scroll to zoom, drag to pan. Keys: V select, H hand, plus and minus zoom, 0 fit, 1 actual size, F zoom to selection, arrows pan.\">\r\n <div id=\"world\"><svg id=\"edges\" aria-hidden=\"true\"><defs><marker id=\"arr\" viewBox=\"0 0 8 8\" refX=\"7\" refY=\"4\" markerWidth=\"6\" markerHeight=\"6\" markerUnits=\"userSpaceOnUse\" orient=\"auto\"><path d=\"M0 0 L8 4 L0 8 z\" fill=\"context-stroke\"/></marker></defs><g id=\"edgeLayer\"></g></svg></div>\r\n <div id=\"cols\" aria-hidden=\"true\"></div>\r\n <div id=\"tools\" role=\"toolbar\" aria-label=\"Canvas controls\" aria-orientation=\"vertical\"></div>\r\n <div id=\"zoomLabel\" aria-hidden=\"true\">100%</div>\r\n </div>\r\n <div id=\"playbar\" hidden aria-label=\"Scenario playback\">\r\n <select id=\"pbScenario\" aria-label=\"Scenario\"></select>\r\n <button id=\"pbPlay\" type=\"button\" aria-label=\"Play\">▶</button>\r\n <button id=\"pbStep\" type=\"button\" aria-label=\"Step\">Step</button>\r\n <button id=\"pbReset\" type=\"button\" aria-label=\"Reset\">Reset</button>\r\n <select id=\"pbSpeed\" aria-label=\"Speed\"><option value=\"0.5\">0.5x</option><option value=\"1\" selected>1x</option><option value=\"2\">2x</option></select>\r\n <input id=\"pbScrub\" type=\"range\" min=\"0\" max=\"1000\" value=\"0\" aria-label=\"Playback position\" aria-valuetext=\"Step 1 of 1\">\r\n <span id=\"pbCaption\"></span><span id=\"pbCounter\"></span><span id=\"pbChoices\"></span>\r\n </div>\r\n <div class=\"keyline\" id=\"legend\" aria-label=\"Legend\"></div>\r\n <aside class=\"insp\" id=\"inspector\" aria-label=\"Inspector\" aria-hidden=\"true\"></aside>\r\n </section>\r\n </div>\r\n <div id=\"live\" class=\"sr\" role=\"status\" aria-live=\"polite\"></div>\r\n\r\n <div class=\"ledger\" id=\"ledger\"></div>\r\n <details class=\"tableview\"><summary>Table view</summary><table class=\"sources\" id=\"tbl\"></table></details>\r\n <details class=\"spec\" id=\"spec\"><summary>Model reference (for the person or agent who builds this)</summary><div id=\"specbody\"></div></details>\r\n</main>\r\n<footer id=\"footer\"></footer>\r\n<aside id=\"drawer\" aria-label=\"Implementation notes\"><h2>Implementation notes</h2><p class=\"note\">Numbered markers on the page match these cards. Hover a card to find its place; click a marker to jump to its card.</p><div id=\"notelist\"></div></aside>\r\n\r\n";
2452
2504
  export {
2453
2505
  K_MAX,
2454
2506
  K_MIN,
@@ -21,7 +21,7 @@
21
21
  <div class="workspace" id="workspace">
22
22
  <section class="canvaswrap">
23
23
  <div id="viewport" tabindex="0" role="application" aria-label="Flow canvas. Scroll to zoom, drag to pan. Keys: V select, H hand, plus and minus zoom, 0 fit, 1 actual size, F zoom to selection, arrows pan.">
24
- <div id="world"><svg id="edges" aria-hidden="true"><defs><marker id="arr" viewBox="0 0 8 8" refX="7" refY="4" markerWidth="9" markerHeight="9" markerUnits="userSpaceOnUse" orient="auto"><path d="M0 0 L8 4 L0 8 z" fill="context-stroke"/></marker></defs><g id="edgeLayer"></g></svg></div>
24
+ <div id="world"><svg id="edges" aria-hidden="true"><defs><marker id="arr" viewBox="0 0 8 8" refX="7" refY="4" markerWidth="6" markerHeight="6" markerUnits="userSpaceOnUse" orient="auto"><path d="M0 0 L8 4 L0 8 z" fill="context-stroke"/></marker></defs><g id="edgeLayer"></g></svg></div>
25
25
  <div id="cols" aria-hidden="true"></div>
26
26
  <div id="tools" role="toolbar" aria-label="Canvas controls" aria-orientation="vertical"></div>
27
27
  <div id="zoomLabel" aria-hidden="true">100%</div>
@@ -1,7 +1,7 @@
1
1
  {
2
- "poolVersion": "1.3.134",
2
+ "poolVersion": "1.3.136",
3
3
  "bundles": {
4
- "antigravity-plugin": "1.3.134",
4
+ "antigravity-plugin": "1.3.136",
5
5
  "antigravity-plugin-extras": "1.3.41",
6
6
  "codex": "unknown"
7
7
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@caddis/cli",
3
- "version": "0.4.48",
3
+ "version": "0.4.50",
4
4
  "description": "Install, update and diagnose the caddis dev harness across every coding agent you use (Claude Code, agy/Antigravity, and more).",
5
5
  "keywords": [
6
6
  "caddis",