@davidbalzan/groundwork-console 0.1.14 → 0.1.15

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 (98) hide show
  1. package/dist/bus.js +40 -0
  2. package/dist/kitresolve.js +11 -3
  3. package/dist/server.js +16 -6
  4. package/dist/skills.js +45 -1
  5. package/package.json +6 -3
  6. package/public/assets/{abnfDiagram-N423BO3Z-BSvB33qO.js → abnfDiagram-N423BO3Z-BazEjqqO.js} +1 -1
  7. package/public/assets/{arc-zFmco7vQ.js → arc-B7L9Wm_N.js} +1 -1
  8. package/public/assets/architecture-TIHT7OUA-CssFxMhM.js +1 -0
  9. package/public/assets/{architectureDiagram-T3A2C74G-Dq8B7QSd.js → architectureDiagram-T3A2C74G-MLhuSxpt.js} +1 -1
  10. package/public/assets/{blockDiagram-VBNYF7ZC-Dyx-2MxL.js → blockDiagram-VBNYF7ZC-BQPonMeH.js} +1 -1
  11. package/public/assets/{c4Diagram-5PPSVZJV-BcQgTpcV.js → c4Diagram-5PPSVZJV-Cz9rjAfz.js} +1 -1
  12. package/public/assets/channel-CEZ4Oy1C.js +1 -0
  13. package/public/assets/{chunk-2GRJ4B5K-0LJiHhVt.js → chunk-2GRJ4B5K-DX-wb55s.js} +1 -1
  14. package/public/assets/{chunk-4I5QYGJK-DU9jcgy8.js → chunk-4I5QYGJK-GtAn9Uuq.js} +1 -1
  15. package/public/assets/{chunk-5RXB4S5H-Dbb9fQEh.js → chunk-5RXB4S5H-CdlTe7Kd.js} +1 -1
  16. package/public/assets/{chunk-6Q2QTUOP-BEP7PF5q.js → chunk-6Q2QTUOP-DpEP78Fx.js} +1 -1
  17. package/public/assets/{chunk-7Z6QIM7H-BDULl8ao.js → chunk-7Z6QIM7H-D70dHZIb.js} +1 -1
  18. package/public/assets/{chunk-GF5L2VYU-CKmEMSg9.js → chunk-GF5L2VYU-Bj5gzsOF.js} +1 -1
  19. package/public/assets/{chunk-I66GZJ75-C8VZHfLH.js → chunk-I66GZJ75-DYvsApTB.js} +1 -1
  20. package/public/assets/{chunk-JQJVKLGR-DM2yoV15.js → chunk-JQJVKLGR-sPaAWMcl.js} +1 -1
  21. package/public/assets/{chunk-KBJHAD2P-BRAKI2QY.js → chunk-KBJHAD2P-sIJR9nWn.js} +1 -1
  22. package/public/assets/{chunk-NSK5VX7P-DV7uo6bZ.js → chunk-NSK5VX7P-BBXDYhCk.js} +1 -1
  23. package/public/assets/{chunk-QR6OTTB3-CIKpM1Nr.js → chunk-QR6OTTB3-0D3J_ldz.js} +1 -1
  24. package/public/assets/{chunk-RYQCIY6F-DrSpjyPL.js → chunk-RYQCIY6F-ByFYkZW5.js} +1 -1
  25. package/public/assets/{chunk-UBXNYLIW-CKJQ1y-l.js → chunk-UBXNYLIW-vH5z2CFq.js} +1 -1
  26. package/public/assets/{chunk-W5SLKNZC-BrvtgZ7x.js → chunk-W5SLKNZC-DXOAlDYx.js} +1 -1
  27. package/public/assets/{chunk-WRU74C26-D5OxzQZ_.js → chunk-WRU74C26-BDeea6GT.js} +1 -1
  28. package/public/assets/{chunk-XXDRQBXY-B7N0mEcW.js → chunk-XXDRQBXY-CyNmLpLK.js} +1 -1
  29. package/public/assets/classDiagram-JCYQIIEL-BTuFAVSb.js +1 -0
  30. package/public/assets/classDiagram-v2-OCEON4UE-BTuFAVSb.js +1 -0
  31. package/public/assets/{cose-bilkent-JH36ORCC-B4AeOPAc.js → cose-bilkent-JH36ORCC-DyR57pP4.js} +1 -1
  32. package/public/assets/{cynefin-VYW2F7L2-DzOwlGVY.js → cynefin-VYW2F7L2-BfcydoVY.js} +1 -1
  33. package/public/assets/{cynefinDiagram-MW4NZA55-SA4aXkpc.js → cynefinDiagram-MW4NZA55-D4C7d9xF.js} +1 -1
  34. package/public/assets/{dagre-VZM6K2ZE-C5ltS5m2.js → dagre-VZM6K2ZE-Bb3QdyiU.js} +1 -1
  35. package/public/assets/{diagram-7IWD3JNH-TU7uqjDX.js → diagram-7IWD3JNH-75Re1gEQ.js} +1 -1
  36. package/public/assets/{diagram-B4RE2ZJO-HCe8Z_RD.js → diagram-B4RE2ZJO-DBZrEAjD.js} +1 -1
  37. package/public/assets/{diagram-LBJQPF4R-9kRxXqkG.js → diagram-LBJQPF4R-DP03ppoa.js} +1 -1
  38. package/public/assets/{diagram-Q27KOJAE-DfLFPFvB.js → diagram-Q27KOJAE-Baaak7ET.js} +1 -1
  39. package/public/assets/{diagram-UB23O5K3-BUpWSI8L.js → diagram-UB23O5K3-DRtw-cVM.js} +1 -1
  40. package/public/assets/{dist-By9Jxne0.js → dist-oRJzdzK9.js} +1 -1
  41. package/public/assets/{ebnfDiagram-BXEA7PRR-Dz83w-0Y.js → ebnfDiagram-BXEA7PRR-DSIhRAUP.js} +1 -1
  42. package/public/assets/{erDiagram-JOGREHBK-DHZjXCza.js → erDiagram-JOGREHBK-tfCb8QEk.js} +1 -1
  43. package/public/assets/eventmodeling-45OFAUF4-Br197Gcb.js +1 -0
  44. package/public/assets/flowDiagram-UKHOOZJN-BDKCF_Nj.js +1 -0
  45. package/public/assets/{ganttDiagram-PKOTCBZU-B3tcBB-9.js → ganttDiagram-PKOTCBZU-BYZrkk6r.js} +1 -1
  46. package/public/assets/{gitGraph-TEB2WS4Q-BQKfiZNh.js → gitGraph-TEB2WS4Q-BtIPzVXt.js} +1 -1
  47. package/public/assets/{gitGraphDiagram-DS77QQ5N-BM480xTb.js → gitGraphDiagram-DS77QQ5N-B319uA7z.js} +1 -1
  48. package/public/assets/index-BmpLrTQR.css +2 -0
  49. package/public/assets/{index-Crr1PM3T.js → index-Dl33_YDJ.js} +8 -8
  50. package/public/assets/{info-DKCQHKI2-DW33_uuk.js → info-DKCQHKI2-CTIPSIKZ.js} +1 -1
  51. package/public/assets/{infoDiagram-6WML65LV-BeewbX8V.js → infoDiagram-6WML65LV-D-foqSEg.js} +1 -1
  52. package/public/assets/{ishikawaDiagram-WSZJBQD7-DcWSwP2B.js → ishikawaDiagram-WSZJBQD7-CsSDhWgz.js} +1 -1
  53. package/public/assets/{journeyDiagram-NVQOT4AX-BxT4Ea_S.js → journeyDiagram-NVQOT4AX-D4kgOJAw.js} +1 -1
  54. package/public/assets/{kanban-definition-27J2QSJJ-CEvqnKgz.js → kanban-definition-27J2QSJJ-B3kNYdeo.js} +1 -1
  55. package/public/assets/{line-DrJMZj-O.js → line-DI4sM6NI.js} +1 -1
  56. package/public/assets/{linear-cUeO7N7d.js → linear-CR-Nr7tu.js} +1 -1
  57. package/public/assets/{mermaid-parser.core-CIHTTkEa.js → mermaid-parser.core-Jx7mG9S9.js} +3 -3
  58. package/public/assets/{mermaid.core-Cc5OhPpa.js → mermaid.core-Dad-8IqK.js} +4 -4
  59. package/public/assets/{mindmap-definition-FAOFIHXS-DsHkrrK_.js → mindmap-definition-FAOFIHXS-DNeiGiTc.js} +1 -1
  60. package/public/assets/{packet-7NZHBO7P-C_T3uLvX.js → packet-7NZHBO7P-DDW1h-3U.js} +1 -1
  61. package/public/assets/{pegDiagram-VL7TDLO6-CBdlvXSc.js → pegDiagram-VL7TDLO6-BhFSf_Qi.js} +1 -1
  62. package/public/assets/{pie-RZYD4A2V-CpetmYJU.js → pie-RZYD4A2V-DlcS3vnT.js} +1 -1
  63. package/public/assets/{pieDiagram-7S7Q4E2Y-CT3wi9zO.js → pieDiagram-7S7Q4E2Y-bIpfrRof.js} +1 -1
  64. package/public/assets/{quadrantDiagram-CIZ2JOQS-Vuywai3l.js → quadrantDiagram-CIZ2JOQS-BOsxmZiJ.js} +1 -1
  65. package/public/assets/{radar-I7S5WNFK-rNDTWylh.js → radar-I7S5WNFK-y6e8oiKJ.js} +1 -1
  66. package/public/assets/{railroad-3IZDKUUU-B09wa8N5.js → railroad-3IZDKUUU-DSMAGu-t.js} +1 -1
  67. package/public/assets/railroad-abnf-AHOZXSZD-cMf5ZHgo.js +1 -0
  68. package/public/assets/railroad-ebnf-EBAXGLYW-C4ZEbGk2.js +1 -0
  69. package/public/assets/railroad-peg-LSFZ7HO6-KGZPMRIB.js +1 -0
  70. package/public/assets/{railroadDiagram-AXF67PYL-DxwqeTls.js → railroadDiagram-AXF67PYL-BRtEa2OT.js} +1 -1
  71. package/public/assets/{requirementDiagram-LRYGKXZP-UGxNbVIj.js → requirementDiagram-LRYGKXZP-Dikys7Ub.js} +1 -1
  72. package/public/assets/{sankeyDiagram-W5VNT64P-DpR73q2C.js → sankeyDiagram-W5VNT64P-BiYgVWtA.js} +1 -1
  73. package/public/assets/{sequenceDiagram-SI44F4Z6-xvxxzFmu.js → sequenceDiagram-SI44F4Z6-BUtXadia.js} +1 -1
  74. package/public/assets/{src-eh414mKr.js → src-BtDe6ofe.js} +1 -1
  75. package/public/assets/{stateDiagram-OKZ733FA-Cqt3c052.js → stateDiagram-OKZ733FA-5fho-t3_.js} +1 -1
  76. package/public/assets/stateDiagram-v2-UEYNNEHI-DFmJr5_x.js +1 -0
  77. package/public/assets/{swimlanes-SLNWSIFB-BJknsAAA.js → swimlanes-SLNWSIFB-BpmWJ8es.js} +1 -1
  78. package/public/assets/swimlanesDiagram-ULZ7WXOC-0uIZxCfL.js +8 -0
  79. package/public/assets/{timeline-definition-Z64GVDOM-Dkcqv4tL.js → timeline-definition-Z64GVDOM-_w3lytrY.js} +1 -1
  80. package/public/assets/{treeView-QDETBFTQ-C1uzwCFh.js → treeView-QDETBFTQ-D_l_9pyQ.js} +1 -1
  81. package/public/assets/{treemap-6X3UGDF4-C59GIx2E.js → treemap-6X3UGDF4-DvWVuWhL.js} +1 -1
  82. package/public/assets/{vennDiagram-T6HMQDX7-Cd3Zvctp.js → vennDiagram-T6HMQDX7-ClZPTfxU.js} +1 -1
  83. package/public/assets/{wardley-OPB4EBWU-D3P85e8V.js → wardley-OPB4EBWU-CgyA0GRV.js} +1 -1
  84. package/public/assets/{wardleyDiagram-T6FBY63Y-BLX8xtsj.js → wardleyDiagram-T6FBY63Y-DNhv1Bla.js} +1 -1
  85. package/public/assets/{xychartDiagram-ELKLHX3M-CUfF0x4C.js → xychartDiagram-ELKLHX3M-CNeebJO2.js} +1 -1
  86. package/public/index.html +2 -2
  87. package/public/assets/architecture-TIHT7OUA-BQFAhsKM.js +0 -1
  88. package/public/assets/channel-BBOBumsc.js +0 -1
  89. package/public/assets/classDiagram-JCYQIIEL-g9vVH4Bz.js +0 -1
  90. package/public/assets/classDiagram-v2-OCEON4UE-g9vVH4Bz.js +0 -1
  91. package/public/assets/eventmodeling-45OFAUF4-UQEvaa-G.js +0 -1
  92. package/public/assets/flowDiagram-UKHOOZJN-D3oCUrRO.js +0 -1
  93. package/public/assets/index-C40rGsvd.css +0 -2
  94. package/public/assets/railroad-abnf-AHOZXSZD-DPdRoDGL.js +0 -1
  95. package/public/assets/railroad-ebnf-EBAXGLYW-BWVVmeh0.js +0 -1
  96. package/public/assets/railroad-peg-LSFZ7HO6-CFlw0fDo.js +0 -1
  97. package/public/assets/stateDiagram-v2-UEYNNEHI-toMIf4-z.js +0 -1
  98. package/public/assets/swimlanesDiagram-ULZ7WXOC-BF4o5mrv.js +0 -8
package/dist/bus.js CHANGED
@@ -102,6 +102,23 @@ export function agentsSync(root, scanLines = SCAN_LINES) {
102
102
  return { ...a, transport: t?.transport ?? t?.kind ?? (t ? "tmux-push" : null), pane: t?.tmuxTarget ?? null, reachability: reachOf(age), heartbeatAgeMs: Number.isFinite(age) ? age : null, lastSeen: lastSeen || null, progress: progressOf(output.get(a.agentId), now, scanLines) };
103
103
  }).sort((a, b) => (b.lastSeen ?? 0) - (a.lastSeen ?? 0));
104
104
  }
105
+ export function busConditions(root) {
106
+ const halt = readJson(path.join(root, "halt.json"), null);
107
+ const away = readJson(path.join(root, "coord-away.json"), null);
108
+ const subs = readJson(path.join(root, "subscriptions.json"), {});
109
+ const stallFile = path.join(root, "stall-check.json");
110
+ const stallRaw = existsSync(stallFile) ? readJson(stallFile, {}) : null;
111
+ const runs = (stallRaw?.history ?? []).filter((r) => typeof r?.at === "number").sort((a, b) => a.at - b.at);
112
+ const last = runs.length ? runs[runs.length - 1] : null;
113
+ const list = subs.subscriptions ?? [];
114
+ const never = list.filter((x) => x.lastEvaluatedAt === null || x.lastEvaluatedAt === undefined);
115
+ return {
116
+ halt: halt ? { active: true, ...halt } : { active: false },
117
+ away: away ? { active: true, ...away } : { active: false },
118
+ subscriptions: { total: list.length, neverEvaluated: never.length, agents: [...new Set(never.map((x) => x.agentId).filter((a) => !!a))] },
119
+ stallClock: { inUse: stallRaw !== null, runs: runs.slice(-12), last, ageMs: last ? Date.now() - last.at : null },
120
+ };
121
+ }
105
122
  export function rooms(root) {
106
123
  const meta = readJson(path.join(root, "rooms.json"), {});
107
124
  const dir = path.join(root, "rooms");
@@ -135,3 +152,26 @@ export function scopes(root) { return readJson(path.join(root, "scopes.json"), {
135
152
  /* prefix classification — same table as seam/protocol/prefixes.ts (byte-0, case-sensitive) */
136
153
  export const PREFIXES = ["DAVID_DECISION", "SCOPE CHANGE", "AGENT_ACTION", "BLOCKER", "VERDICT", "RISK", "DONE", "FYI", "GO"];
137
154
  export function prefixOf(text) { return PREFIXES.find((p) => text.startsWith(p + ":") || text.startsWith(p + " ")) ?? null; }
155
+ /* A message's prefix from its TYPED RECORD where it has one, falling back to the text scan.
156
+ *
157
+ * The bus carries the same fact twice: `record.type` is structured, and the prose repeats it as a
158
+ * leading token. Reading only the prose meant a correctly-typed message whose author varied the
159
+ * wording was classified by a regex over free text — two sources for one fact, with the weaker one
160
+ * winning by default.
161
+ *
162
+ * The record wins where present because the SENDER declared it, and the bus enforces authority on
163
+ * the restricted types; the text scan stays for the messages that carry no record (175 of 214 in
164
+ * this store at time of writing), which is a fallback rather than a second opinion.
165
+ *
166
+ * One function, used at every call site. Three copies of this mapping is how the next divergence
167
+ * gets written. */
168
+ const RECORD_PREFIX = {
169
+ decision: "DAVID_DECISION", verdict: "VERDICT", done: "DONE", blocker: "BLOCKER",
170
+ risk: "RISK", fyi: "FYI", action: "AGENT_ACTION", go: "GO", scope: "SCOPE CHANGE",
171
+ };
172
+ export function prefixOfMessage(m) {
173
+ const t = m.record?.type;
174
+ if (typeof t === "string" && RECORD_PREFIX[t])
175
+ return RECORD_PREFIX[t];
176
+ return typeof m.text === "string" ? prefixOf(m.text) : null;
177
+ }
@@ -48,7 +48,6 @@ const pkgVersionNear = (file) => { if (!file)
48
48
  }
49
49
  d = path.dirname(d);
50
50
  } return null; };
51
- /** Installed versions the console actually resolves to (seam from node_modules; the rest from wherever the CLIs came from). */
52
51
  export function installedVersions(kitPath) {
53
52
  let seam = null;
54
53
  try {
@@ -56,7 +55,13 @@ export function installedVersions(kitPath) {
56
55
  }
57
56
  catch { /* not installed */ }
58
57
  const gw = groundworkCli(kitPath), pb = playbookCli(kitPath), mcp = mcpServer(kitPath);
59
- return { seam, groundwork: pkgVersionNear(gw), playbook: pkgVersionNear(pb), mcp: pkgVersionNear(mcp), paths: { groundwork: gw, playbook: pb, mcp, kitCheckout: hasKitCheckout(kitPath) ? kitPath : null } };
58
+ const root = hasKitCheckout(kitPath) ? path.resolve(kitPath) : null;
59
+ const from = (file) => (!file ? null : root && path.resolve(file).startsWith(root + path.sep) ? "kit checkout" : "global install");
60
+ return {
61
+ seam, groundwork: pkgVersionNear(gw), playbook: pkgVersionNear(pb), mcp: pkgVersionNear(mcp),
62
+ sources: { seam: (seam ? "console dependency" : null), groundwork: from(gw), playbook: from(pb), mcp: from(mcp) },
63
+ paths: { groundwork: gw, playbook: pb, mcp, kitCheckout: root },
64
+ };
60
65
  }
61
66
  /** Floor check: the console's requirement is a MINIMUM within the same major (kit packages bump minors often; 0.25.1 must satisfy "^0.24.0").
62
67
  Written as ^a.b.c for familiarity, evaluated as >= a.b.c and < (a+1).0.0 — NOT strict caret semantics for 0.x. */
@@ -76,7 +81,10 @@ export function satisfies(v, range) {
76
81
  }
77
82
  export function requiresReport(kitPath, caps) {
78
83
  const inst = installedVersions(kitPath);
79
- const check = (k) => ({ required: REQUIRES[k], installed: inst[k], ok: satisfies(inst[k], REQUIRES[k]) });
84
+ /* `source` rides along so a reader of /api/kit can tell WHICH question each number answers.
85
+ `requires.seam` is the console's own dependency; `packages.seam` (when a kit checkout exists)
86
+ is the kit's manifest. They differ legitimately and used to differ silently. */
87
+ const check = (k) => ({ required: REQUIRES[k], installed: inst[k], ok: satisfies(inst[k], REQUIRES[k]), source: inst.sources[k] });
80
88
  const r = { seam: check("seam"), mcp: { ...check("mcp"), capabilities: caps ?? { inReplyTo: null, sendCommand: null }, warnings: caps?.inReplyTo === false ? ["inReplyTo missing — decision replies will not be linked/cleared; upgrade agent-coord-mcp"] : [] }, groundwork: check("groundwork"), playbook: check("playbook") };
81
89
  return { ...r, paths: inst.paths, ok: Object.values(r).every((x) => x.ok !== false) };
82
90
  }
package/dist/server.js CHANGED
@@ -12,11 +12,11 @@ import { hostname as osHostname } from "node:os";
12
12
  import { loadConfig, saveProjects, validateProjectPath, CONFIG_FILE } from "./config.js";
13
13
  import { boardOf, docOf, docsIndex, phaseTasksOf } from "./seam.js";
14
14
  import { DocWriteError, sha256, writeDoc } from "./docwrite.js";
15
- import { agents, agentsAsync, rooms, roomMessages, roomMessageCount, statusStream, scopes, prefixOf } from "./bus.js";
15
+ import { agents, agentsAsync, rooms, roomMessages, roomMessageCount, statusStream, scopes, prefixOfMessage, busConditions } from "./bus.js";
16
16
  import { capturePane } from "./tmux.js";
17
17
  import { spawnAgent, suggestId, fleetStatus, FLEET_TEMPLATES, HARNESS_CMD, ROLE_SKILL } from "./provision.js";
18
18
  import { doctor, status, list, playbookList } from "./groundwork.js";
19
- import { detectedHarnesses, groundworkSkills, playbookCards } from "./skills.js";
19
+ import { detectedHarnesses, groundworkSkills, playbookCards, cardLoads } from "./skills.js";
20
20
  import { extensionsOf } from "./extensions.js";
21
21
  import { parseWorkDoc, workstreamsExtensionsOf } from "@davidbalzan/groundwork-seam";
22
22
  import { EventEngine } from "./events.js";
@@ -604,7 +604,7 @@ app.get("/bus/inbox", async (c) => {
604
604
  return null;
605
605
  } }).filter(Boolean) : [];
606
606
  const unreadIds = new Set(out.messages.map((m) => m.id));
607
- const messages = all.map((m) => ({ ...m, unread: unreadIds.has(m.id) && !isAnswered(m.id), answered: isAnswered(m.id), prefix: prefixOf(String(m.text ?? "")) }));
607
+ const messages = all.map((m) => ({ ...m, unread: unreadIds.has(m.id) && !isAnswered(m.id), answered: isAnswered(m.id), prefix: prefixOfMessage(m) }));
608
608
  // Pending decisions per sender: unread, unanswered DAVID_DECISION DMs — the avatar cue.
609
609
  const decisions = {};
610
610
  for (const m of messages)
@@ -629,7 +629,7 @@ app.get("/bus/dm/:agent", (c) => {
629
629
  } }).filter(Boolean) : [];
630
630
  const mine = readJsonl(path.join(cfg.coordDir, "inbox", "david.jsonl")).filter((m) => m.from === agent);
631
631
  const theirs = readJsonl(path.join(cfg.coordDir, "inbox", `${agent}.jsonl`)).filter((m) => m.from === "david");
632
- const messages = [...mine, ...theirs].sort((a, b) => Number(a.ts ?? 0) - Number(b.ts ?? 0)).slice(-limit).map((m) => ({ ...m, prefix: prefixOf(String(m.text ?? "")) }));
632
+ const messages = [...mine, ...theirs].sort((a, b) => Number(a.ts ?? 0) - Number(b.ts ?? 0)).slice(-limit).map((m) => ({ ...m, prefix: prefixOfMessage(m) }));
633
633
  return c.json({ agent, messages, lastFromAgent: mine.length ? Number(mine[mine.length - 1].ts ?? 0) : 0 });
634
634
  });
635
635
  app.post("/bus/inbox/read", async (c) => {
@@ -1058,11 +1058,13 @@ app.get("/bus/rooms/:room/messages", (c) => {
1058
1058
  const limit = Number(c.req.query("limit") ?? 100);
1059
1059
  const before = c.req.query("before") ? Number(c.req.query("before")) : undefined;
1060
1060
  const room = c.req.param("room");
1061
- const msgs = roomMessages(cfg.coordDir, room, limit, before).map((m) => ({ ...m, prefix: typeof m.text === "string" ? prefixOf(m.text) : null, answered: isAnswered(m.id) }));
1061
+ const msgs = roomMessages(cfg.coordDir, room, limit, before).map((m) => ({ ...m, prefix: prefixOfMessage(m), answered: isAnswered(m.id) }));
1062
1062
  return c.json({ room, total: roomMessageCount(cfg.coordDir, room), messages: msgs, oldestTs: msgs[0]?.ts ?? null });
1063
1063
  });
1064
1064
  app.get("/bus/status", (c) => c.json(statusStream(cfg.coordDir, Number(c.req.query("limit") ?? 50))));
1065
1065
  app.get("/bus/scopes", (c) => c.json(scopes(cfg.coordDir)));
1066
+ app.get("/bus/conditions", (c) => c.json(busConditions(cfg.coordDir)));
1067
+ app.get("/bus/card-loads", (c) => c.json(cardLoads()));
1066
1068
  events.start(15_000);
1067
1069
  notifier.start(15_000);
1068
1070
  /* Uploads TTL purge: at boot + every 30 min (unref'd so it never holds the process). A Run is logged only when something was deleted. */
@@ -1094,4 +1096,12 @@ if (existsSync(PUBLIC_DIR)) {
1094
1096
  }
1095
1097
  // Bind loopback only: the console can write to the bus and to docs/ and has no auth yet. Set GROUNDWORK_CONSOLE_HOST=0.0.0.0 to expose (put auth in front first).
1096
1098
  const hostname = process.env.GROUNDWORK_CONSOLE_HOST ?? "127.0.0.1";
1097
- serve({ fetch: root.fetch, port, hostname }, () => { const rq = requiresReport(cfg.kitPath); console.log(`kit resolve: ${rq.paths.kitCheckout ? "checkout " + rq.paths.kitCheckout : "installed packages (no kit checkout)"} · seam ${rq.seam.installed ?? "?"} mcp ${rq.mcp.installed ?? "?"} groundwork ${rq.groundwork.installed ?? "?"} playbook ${rq.playbook.installed ?? "?"} · requires ${rq.ok ? "OK" : "MISMATCH " + JSON.stringify(REQUIRES)}`); console.log(`groundwork-console api → http://${hostname}:${port}/api store=${cfg.coordDir} auth=${authEnabled ? `token (${tokenFile})` : "OFF"}`); });
1099
+ serve({ fetch: root.fetch, port, hostname }, () => {
1100
+ const rq = requiresReport(cfg.kitPath); /* Grouped BY SOURCE. Printing four numbers after one "checkout <path>" label said they all came
1101
+ from there; three do and `seam` is this console's own dependency, so our pin read as a stale
1102
+ kit. Same numbers, each now attributable. */
1103
+ const kitTrio = `mcp ${rq.mcp.installed ?? "?"} groundwork ${rq.groundwork.installed ?? "?"} playbook ${rq.playbook.installed ?? "?"}`;
1104
+ const kitFrom = rq.paths.kitCheckout ? `checkout ${rq.paths.kitCheckout}` : "global install (no kit checkout)";
1105
+ console.log(`kit resolve: ${kitFrom} · ${kitTrio} · seam ${rq.seam.installed ?? "?"} (this console's dependency, not the kit's) · requires ${rq.ok ? "OK" : "MISMATCH " + JSON.stringify(REQUIRES)}`);
1106
+ console.log(`groundwork-console api → http://${hostname}:${port}/api store=${cfg.coordDir} auth=${authEnabled ? `token (${tokenFile})` : "OFF"}`);
1107
+ });
package/dist/skills.js CHANGED
@@ -1,6 +1,6 @@
1
1
  /* Supplement to the CLIs' `list --json`: compare installed SKILL.md with what the installer would write (in-sync signal the CLIs do not report).
2
2
  groundwork: byte-copy → raw hash. playbook: per-harness placeholder rewrite → hash the rewritten source (see loadRewrite). */
3
- import { existsSync, readFileSync, readdirSync } from "node:fs";
3
+ import { existsSync, readFileSync, readdirSync, statSync } from "node:fs";
4
4
  import { createHash } from "node:crypto";
5
5
  import { homedir } from "node:os";
6
6
  import path from "node:path";
@@ -98,3 +98,47 @@ export async function playbookCards(kitPath) {
98
98
  legacyDirs: homes.flatMap(([h, d]) => ["coord-curator", "coord-liaison"].filter((n) => existsSync(path.join(d, n))).map((n) => `${h}:${n}`)),
99
99
  };
100
100
  }
101
+ export function cardLoads(root = homedir()) {
102
+ const home = path.join(root, ".claude/skills");
103
+ const cards = existsSync(home) ? readdirSync(home).map((d) => path.join(home, d, "SKILL.md")).filter((f) => existsSync(f)) : [];
104
+ /* NEWEST card write is the bar: any card changing means a session that predates it may be holding
105
+ a superseded copy of THAT one, and a per-card bar would claim precision this cannot support. */
106
+ const cardsWrittenAt = cards.length ? Math.max(...cards.map((f) => statSync(f).mtimeMs)) : null;
107
+ const dir = path.join(root, "agent-coord/sessions");
108
+ const files = existsSync(dir) ? readdirSync(dir).filter((f) => f.endsWith(".json")) : [];
109
+ const live = new Map();
110
+ let stale = 0;
111
+ for (const f of files) {
112
+ let s = {};
113
+ try {
114
+ s = JSON.parse(readFileSync(path.join(dir, f), "utf8"));
115
+ }
116
+ catch {
117
+ continue;
118
+ }
119
+ if (!s.agentId || typeof s.pid !== "number" || typeof s.boundAt !== "number")
120
+ continue;
121
+ if (!alive(s.pid)) {
122
+ stale++;
123
+ continue;
124
+ }
125
+ const prev = live.get(s.agentId);
126
+ if (!prev || s.boundAt > prev.boundAt) {
127
+ live.set(s.agentId, { agentId: s.agentId, boundAt: s.boundAt, pid: s.pid, pane: s.tmuxPane ?? null, state: cardsWrittenAt !== null && s.boundAt > cardsWrittenAt ? "current" : "unknown" });
128
+ }
129
+ }
130
+ return { cardsWrittenAt, skillsHome: home, agents: [...live.values()].sort((a, b) => a.agentId.localeCompare(b.agentId)), staleSessionFiles: stale };
131
+ }
132
+ /* Is this pid running? `kill(pid, 0)` signals nothing; it only asks.
133
+ ESRCH means no such process. EPERM means THE PROCESS EXISTS and is not ours — treating that as
134
+ dead would silently drop a live agent from the table, which is the failure direction that matters
135
+ here: a missing row reads as "no such agent" rather than as "could not tell". */
136
+ function alive(pid) {
137
+ try {
138
+ process.kill(pid, 0);
139
+ return true;
140
+ }
141
+ catch (e) {
142
+ return e?.code === "EPERM";
143
+ }
144
+ }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@davidbalzan/groundwork-console",
3
3
  "private": false,
4
- "version": "0.1.14",
4
+ "version": "0.1.15",
5
5
  "type": "module",
6
6
  "dependencies": {
7
7
  "@davidbalzan/groundwork-seam": "0.1.8",
@@ -48,12 +48,15 @@
48
48
  "publish-check": "node scripts/publish-check.mjs",
49
49
  "test:inject": "tsx test/inject.test.mts",
50
50
  "test:skills": "tsx test/skills.test.mts",
51
- "test": "pnpm run test:inject && pnpm run test:skills && pnpm run test:board && pnpm run test:panes && pnpm run test:seam-contract && pnpm run test:prref && pnpm run test:progress && pnpm run test:publish-check",
51
+ "test": "pnpm run test:inject && pnpm run test:skills && pnpm run test:board && pnpm run test:panes && pnpm run test:seam-contract && pnpm run test:prref && pnpm run test:progress && pnpm run test:publish-check && pnpm run test:record && pnpm run test:kitresolve && pnpm run test:cardloads",
52
52
  "test:board": "tsx test/board.test.mts",
53
53
  "test:panes": "tsx test/panes.test.mts",
54
54
  "test:seam-contract": "tsx test/seam-contract.test.mts",
55
55
  "test:prref": "tsx test/prref.test.mts",
56
56
  "test:progress": "tsx test/progress.test.mts",
57
- "test:publish-check": "tsx test/publish-check.test.mts"
57
+ "test:publish-check": "tsx test/publish-check.test.mts",
58
+ "test:record": "tsx test/record.test.mts",
59
+ "test:kitresolve": "tsx test/kitresolve.test.mts",
60
+ "test:cardloads": "tsx test/cardloads.test.mts"
58
61
  }
59
62
  }
@@ -1 +1 @@
1
- import{m as e,t}from"./mermaid-parser.core-CIHTTkEa.js";import{n}from"./chunk-Y2CYZVJY-DsF7k-Jl.js";import{m as r}from"./src-eh414mKr.js";import"./chunk-I66GZJ75-C8VZHfLH.js";import{n as i,r as a,t as o}from"./chunk-6Q2QTUOP-BEP7PF5q.js";import{t as s}from"./chunk-JWPE2WC7-DVXcaiue.js";import"./mermaid.core-Cc5OhPpa.js";var c=e().RailroadAbnf.parser.LangiumParser,l=n(e=>{let t=e.alternatives.map(u);return t.length===1?t[0]:{type:`choice`,alternatives:t}},`transformAlternation`),u=n(e=>{let t=e.elements.map(f);return t.length===1?t[0]:{type:`sequence`,elements:t}},`transformConcatenation`),d=n(e=>{if(e.includes(`*`)){let[t,n]=e.split(`*`);return{min:t?parseInt(t,10):0,max:n?parseInt(n,10):1/0}}let t=parseInt(e,10);return{min:t,max:t}},`parseRepeat`),f=n(e=>{let t=p(e.primary);if(!e.repeat)return t;let{min:n,max:r}=d(e.repeat);return n===0&&r===1?{type:`optional`,element:t}:{type:`repetition`,element:t,min:n,max:r}},`transformElement`),p=n(e=>{switch(e.$type){case`AbnfStringLiteral`:return{type:`terminal`,value:e.value};case`AbnfNumVal`:return{type:`terminal`,value:e.value};case`AbnfRuleName`:return{type:`nonterminal`,name:e.name};case`AbnfGroup`:return l(e.element);case`AbnfOptionalGroup`:return{type:`optional`,element:l(e.element)};default:throw Error(`Unsupported ABNF primary node: ${e.$type}`)}},`transformPrimary`),m=n(e=>({name:e.name,definition:l(e.definition)}),`transformRule`),h=n(e=>{s(e,o),e.title&&o.setTitle(e.title),e.rules.map(e=>o.addRule(m(e)))},`populateDb`),g={parser:{parse:n(e=>{o.clear(),r.debug(`[ABNF Parser] Starting Langium parse`);let n=c.parse(e);if(n.lexerErrors.length>0||n.parserErrors.length>0)throw new t(n);let i=n.value;r.debug(`[ABNF Parser] Parsed rules:`,i.rules.length),h(i),r.debug(`[ABNF Parser] Parse complete`)},`parse`),parser:{yy:o}},db:o,renderer:a,styles:i};export{g as diagram};
1
+ import{m as e,t}from"./mermaid-parser.core-Jx7mG9S9.js";import{n}from"./chunk-Y2CYZVJY-DsF7k-Jl.js";import{m as r}from"./src-BtDe6ofe.js";import"./chunk-I66GZJ75-DYvsApTB.js";import{n as i,r as a,t as o}from"./chunk-6Q2QTUOP-DpEP78Fx.js";import{t as s}from"./chunk-JWPE2WC7-DVXcaiue.js";import"./mermaid.core-Dad-8IqK.js";var c=e().RailroadAbnf.parser.LangiumParser,l=n(e=>{let t=e.alternatives.map(u);return t.length===1?t[0]:{type:`choice`,alternatives:t}},`transformAlternation`),u=n(e=>{let t=e.elements.map(f);return t.length===1?t[0]:{type:`sequence`,elements:t}},`transformConcatenation`),d=n(e=>{if(e.includes(`*`)){let[t,n]=e.split(`*`);return{min:t?parseInt(t,10):0,max:n?parseInt(n,10):1/0}}let t=parseInt(e,10);return{min:t,max:t}},`parseRepeat`),f=n(e=>{let t=p(e.primary);if(!e.repeat)return t;let{min:n,max:r}=d(e.repeat);return n===0&&r===1?{type:`optional`,element:t}:{type:`repetition`,element:t,min:n,max:r}},`transformElement`),p=n(e=>{switch(e.$type){case`AbnfStringLiteral`:return{type:`terminal`,value:e.value};case`AbnfNumVal`:return{type:`terminal`,value:e.value};case`AbnfRuleName`:return{type:`nonterminal`,name:e.name};case`AbnfGroup`:return l(e.element);case`AbnfOptionalGroup`:return{type:`optional`,element:l(e.element)};default:throw Error(`Unsupported ABNF primary node: ${e.$type}`)}},`transformPrimary`),m=n(e=>({name:e.name,definition:l(e.definition)}),`transformRule`),h=n(e=>{s(e,o),e.title&&o.setTitle(e.title),e.rules.map(e=>o.addRule(m(e)))},`populateDb`),g={parser:{parse:n(e=>{o.clear(),r.debug(`[ABNF Parser] Starting Langium parse`);let n=c.parse(e);if(n.lexerErrors.length>0||n.parserErrors.length>0)throw new t(n);let i=n.value;r.debug(`[ABNF Parser] Parsed rules:`,i.rules.length),h(i),r.debug(`[ABNF Parser] Parse complete`)},`parse`),parser:{yy:o}},db:o,renderer:a,styles:i};export{g as diagram};
@@ -1 +1 @@
1
- import{n as e,t}from"./path-fybaL0A-.js";import{a as n,c as r,d as i,f as a,i as o,l as s,m as c,n as l,o as u,p as d,r as f,u as p}from"./dist-By9Jxne0.js";function m(e){return e.innerRadius}function h(e){return e.outerRadius}function g(e){return e.startAngle}function _(e){return e.endAngle}function v(e){return e&&e.padAngle}function y(e,t,n,r,i,a,o,s){var c=n-e,l=r-t,u=o-i,d=s-a,f=d*c-u*l;if(!(f*f<1e-12))return f=(u*(t-a)-d*(e-i))/f,[e+f*c,t+f*l]}function b(e,t,n,r,i,a,o){var c=e-n,l=t-r,u=(o?a:-a)/d(c*c+l*l),f=u*l,p=-u*c,m=e+f,h=t+p,g=n+f,_=r+p,v=(m+g)/2,y=(h+_)/2,b=g-m,x=_-h,S=b*b+x*x,C=i-a,w=m*_-g*h,T=(x<0?-1:1)*d(s(0,C*C*S-w*w)),E=(w*x-b*T)/S,D=(-w*b-x*T)/S,O=(w*x+b*T)/S,k=(-w*b+x*T)/S,A=E-v,j=D-y,M=O-v,N=k-y;return A*A+j*j>M*M+N*N&&(E=O,D=k),{cx:E,cy:D,x01:-f,y01:-p,x11:E*(i/C-1),y11:D*(i/C-1)}}function x(){var s=m,x=h,S=e(0),C=null,w=g,T=_,E=v,D=null,O=t(k);function k(){var e,t,m=+s.apply(this,arguments),h=+x.apply(this,arguments),g=w.apply(this,arguments)-r,_=T.apply(this,arguments)-r,v=l(_-g),k=_>g;if(D||=e=O(),h<m&&(t=h,h=m,m=t),!(h>1e-12))D.moveTo(0,0);else if(v>c-1e-12)D.moveTo(h*u(g),h*a(g)),D.arc(0,0,h,g,_,!k),m>1e-12&&(D.moveTo(m*u(_),m*a(_)),D.arc(0,0,m,_,g,k));else{var A=g,j=_,M=g,N=_,P=v,F=v,I=E.apply(this,arguments)/2,L=I>1e-12&&(C?+C.apply(this,arguments):d(m*m+h*h)),R=p(l(h-m)/2,+S.apply(this,arguments)),z=R,B=R,V,H;if(L>1e-12){var U=o(L/m*a(I)),W=o(L/h*a(I));(P-=U*2)>1e-12?(U*=k?1:-1,M+=U,N-=U):(P=0,M=N=(g+_)/2),(F-=W*2)>1e-12?(W*=k?1:-1,A+=W,j-=W):(F=0,A=j=(g+_)/2)}var G=h*u(A),K=h*a(A),q=m*u(N),J=m*a(N);if(R>1e-12){var Y=h*u(j),X=h*a(j),Z=m*u(M),Q=m*a(M),$;if(v<i){if($=y(G,K,Z,Q,Y,X,q,J)){var ee=G-$[0],te=K-$[1],ne=Y-$[0],re=X-$[1],ie=1/a(f((ee*ne+te*re)/(d(ee*ee+te*te)*d(ne*ne+re*re)))/2),ae=d($[0]*$[0]+$[1]*$[1]);z=p(R,(m-ae)/(ie-1)),B=p(R,(h-ae)/(ie+1))}else z=B=0}}F>1e-12?B>1e-12?(V=b(Z,Q,G,K,h,B,k),H=b(Y,X,q,J,h,B,k),D.moveTo(V.cx+V.x01,V.cy+V.y01),B<R?D.arc(V.cx,V.cy,B,n(V.y01,V.x01),n(H.y01,H.x01),!k):(D.arc(V.cx,V.cy,B,n(V.y01,V.x01),n(V.y11,V.x11),!k),D.arc(0,0,h,n(V.cy+V.y11,V.cx+V.x11),n(H.cy+H.y11,H.cx+H.x11),!k),D.arc(H.cx,H.cy,B,n(H.y11,H.x11),n(H.y01,H.x01),!k))):(D.moveTo(G,K),D.arc(0,0,h,A,j,!k)):D.moveTo(G,K),!(m>1e-12)||!(P>1e-12)?D.lineTo(q,J):z>1e-12?(V=b(q,J,Y,X,m,-z,k),H=b(G,K,Z,Q,m,-z,k),D.lineTo(V.cx+V.x01,V.cy+V.y01),z<R?D.arc(V.cx,V.cy,z,n(V.y01,V.x01),n(H.y01,H.x01),!k):(D.arc(V.cx,V.cy,z,n(V.y01,V.x01),n(V.y11,V.x11),!k),D.arc(0,0,m,n(V.cy+V.y11,V.cx+V.x11),n(H.cy+H.y11,H.cx+H.x11),k),D.arc(H.cx,H.cy,z,n(H.y11,H.x11),n(H.y01,H.x01),!k))):D.arc(0,0,m,N,M,k)}if(D.closePath(),e)return D=null,e+``||null}return k.centroid=function(){var e=(+s.apply(this,arguments)+ +x.apply(this,arguments))/2,t=(+w.apply(this,arguments)+ +T.apply(this,arguments))/2-i/2;return[u(t)*e,a(t)*e]},k.innerRadius=function(t){return arguments.length?(s=typeof t==`function`?t:e(+t),k):s},k.outerRadius=function(t){return arguments.length?(x=typeof t==`function`?t:e(+t),k):x},k.cornerRadius=function(t){return arguments.length?(S=typeof t==`function`?t:e(+t),k):S},k.padRadius=function(t){return arguments.length?(C=t==null?null:typeof t==`function`?t:e(+t),k):C},k.startAngle=function(t){return arguments.length?(w=typeof t==`function`?t:e(+t),k):w},k.endAngle=function(t){return arguments.length?(T=typeof t==`function`?t:e(+t),k):T},k.padAngle=function(t){return arguments.length?(E=typeof t==`function`?t:e(+t),k):E},k.context=function(e){return arguments.length?(D=e??null,k):D},k}export{x as t};
1
+ import{n as e,t}from"./path-fybaL0A-.js";import{a as n,c as r,d as i,f as a,i as o,l as s,m as c,n as l,o as u,p as d,r as f,u as p}from"./dist-oRJzdzK9.js";function m(e){return e.innerRadius}function h(e){return e.outerRadius}function g(e){return e.startAngle}function _(e){return e.endAngle}function v(e){return e&&e.padAngle}function y(e,t,n,r,i,a,o,s){var c=n-e,l=r-t,u=o-i,d=s-a,f=d*c-u*l;if(!(f*f<1e-12))return f=(u*(t-a)-d*(e-i))/f,[e+f*c,t+f*l]}function b(e,t,n,r,i,a,o){var c=e-n,l=t-r,u=(o?a:-a)/d(c*c+l*l),f=u*l,p=-u*c,m=e+f,h=t+p,g=n+f,_=r+p,v=(m+g)/2,y=(h+_)/2,b=g-m,x=_-h,S=b*b+x*x,C=i-a,w=m*_-g*h,T=(x<0?-1:1)*d(s(0,C*C*S-w*w)),E=(w*x-b*T)/S,D=(-w*b-x*T)/S,O=(w*x+b*T)/S,k=(-w*b+x*T)/S,A=E-v,j=D-y,M=O-v,N=k-y;return A*A+j*j>M*M+N*N&&(E=O,D=k),{cx:E,cy:D,x01:-f,y01:-p,x11:E*(i/C-1),y11:D*(i/C-1)}}function x(){var s=m,x=h,S=e(0),C=null,w=g,T=_,E=v,D=null,O=t(k);function k(){var e,t,m=+s.apply(this,arguments),h=+x.apply(this,arguments),g=w.apply(this,arguments)-r,_=T.apply(this,arguments)-r,v=l(_-g),k=_>g;if(D||=e=O(),h<m&&(t=h,h=m,m=t),!(h>1e-12))D.moveTo(0,0);else if(v>c-1e-12)D.moveTo(h*u(g),h*a(g)),D.arc(0,0,h,g,_,!k),m>1e-12&&(D.moveTo(m*u(_),m*a(_)),D.arc(0,0,m,_,g,k));else{var A=g,j=_,M=g,N=_,P=v,F=v,I=E.apply(this,arguments)/2,L=I>1e-12&&(C?+C.apply(this,arguments):d(m*m+h*h)),R=p(l(h-m)/2,+S.apply(this,arguments)),z=R,B=R,V,H;if(L>1e-12){var U=o(L/m*a(I)),W=o(L/h*a(I));(P-=U*2)>1e-12?(U*=k?1:-1,M+=U,N-=U):(P=0,M=N=(g+_)/2),(F-=W*2)>1e-12?(W*=k?1:-1,A+=W,j-=W):(F=0,A=j=(g+_)/2)}var G=h*u(A),K=h*a(A),q=m*u(N),J=m*a(N);if(R>1e-12){var Y=h*u(j),X=h*a(j),Z=m*u(M),Q=m*a(M),$;if(v<i){if($=y(G,K,Z,Q,Y,X,q,J)){var ee=G-$[0],te=K-$[1],ne=Y-$[0],re=X-$[1],ie=1/a(f((ee*ne+te*re)/(d(ee*ee+te*te)*d(ne*ne+re*re)))/2),ae=d($[0]*$[0]+$[1]*$[1]);z=p(R,(m-ae)/(ie-1)),B=p(R,(h-ae)/(ie+1))}else z=B=0}}F>1e-12?B>1e-12?(V=b(Z,Q,G,K,h,B,k),H=b(Y,X,q,J,h,B,k),D.moveTo(V.cx+V.x01,V.cy+V.y01),B<R?D.arc(V.cx,V.cy,B,n(V.y01,V.x01),n(H.y01,H.x01),!k):(D.arc(V.cx,V.cy,B,n(V.y01,V.x01),n(V.y11,V.x11),!k),D.arc(0,0,h,n(V.cy+V.y11,V.cx+V.x11),n(H.cy+H.y11,H.cx+H.x11),!k),D.arc(H.cx,H.cy,B,n(H.y11,H.x11),n(H.y01,H.x01),!k))):(D.moveTo(G,K),D.arc(0,0,h,A,j,!k)):D.moveTo(G,K),!(m>1e-12)||!(P>1e-12)?D.lineTo(q,J):z>1e-12?(V=b(q,J,Y,X,m,-z,k),H=b(G,K,Z,Q,m,-z,k),D.lineTo(V.cx+V.x01,V.cy+V.y01),z<R?D.arc(V.cx,V.cy,z,n(V.y01,V.x01),n(H.y01,H.x01),!k):(D.arc(V.cx,V.cy,z,n(V.y01,V.x01),n(V.y11,V.x11),!k),D.arc(0,0,m,n(V.cy+V.y11,V.cx+V.x11),n(H.cy+H.y11,H.cx+H.x11),k),D.arc(H.cx,H.cy,z,n(H.y11,H.x11),n(H.y01,H.x01),!k))):D.arc(0,0,m,N,M,k)}if(D.closePath(),e)return D=null,e+``||null}return k.centroid=function(){var e=(+s.apply(this,arguments)+ +x.apply(this,arguments))/2,t=(+w.apply(this,arguments)+ +T.apply(this,arguments))/2-i/2;return[u(t)*e,a(t)*e]},k.innerRadius=function(t){return arguments.length?(s=typeof t==`function`?t:e(+t),k):s},k.outerRadius=function(t){return arguments.length?(x=typeof t==`function`?t:e(+t),k):x},k.cornerRadius=function(t){return arguments.length?(S=typeof t==`function`?t:e(+t),k):S},k.padRadius=function(t){return arguments.length?(C=t==null?null:typeof t==`function`?t:e(+t),k):C},k.startAngle=function(t){return arguments.length?(w=typeof t==`function`?t:e(+t),k):w},k.endAngle=function(t){return arguments.length?(T=typeof t==`function`?t:e(+t),k):T},k.padAngle=function(t){return arguments.length?(E=typeof t==`function`?t:e(+t),k):E},k.context=function(e){return arguments.length?(D=e??null,k):D},k}export{x as t};
@@ -0,0 +1 @@
1
+ import"./chunk-KEIR6QF5-BICK3FdT.js";import{M as e}from"./mermaid-parser.core-Jx7mG9S9.js";export{e as createArchitectureServices};