@davidbalzan/groundwork-console 0.1.13 → 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.
- package/dist/bus.js +44 -4
- package/dist/gitinfo.js +31 -17
- package/dist/kitresolve.js +11 -3
- package/dist/server.js +16 -6
- package/dist/skills.js +45 -1
- package/package.json +8 -4
- package/public/assets/{abnfDiagram-N423BO3Z-2g9UHdfw.js → abnfDiagram-N423BO3Z-BazEjqqO.js} +1 -1
- package/public/assets/{arc-EEINoaIY.js → arc-B7L9Wm_N.js} +1 -1
- package/public/assets/architecture-TIHT7OUA-CssFxMhM.js +1 -0
- package/public/assets/{architectureDiagram-T3A2C74G-D4F9rIiu.js → architectureDiagram-T3A2C74G-MLhuSxpt.js} +1 -1
- package/public/assets/{blockDiagram-VBNYF7ZC-CQZAhVXz.js → blockDiagram-VBNYF7ZC-BQPonMeH.js} +1 -1
- package/public/assets/{c4Diagram-5PPSVZJV-BlBzSIXs.js → c4Diagram-5PPSVZJV-Cz9rjAfz.js} +1 -1
- package/public/assets/channel-CEZ4Oy1C.js +1 -0
- package/public/assets/{chunk-2GRJ4B5K-ZVZxINuZ.js → chunk-2GRJ4B5K-DX-wb55s.js} +1 -1
- package/public/assets/{chunk-4I5QYGJK-8hqVPXHL.js → chunk-4I5QYGJK-GtAn9Uuq.js} +1 -1
- package/public/assets/{chunk-5RXB4S5H-D1s6L_89.js → chunk-5RXB4S5H-CdlTe7Kd.js} +1 -1
- package/public/assets/{chunk-6Q2QTUOP-BWLeyKxS.js → chunk-6Q2QTUOP-DpEP78Fx.js} +1 -1
- package/public/assets/{chunk-7Z6QIM7H-DjvOr6wh.js → chunk-7Z6QIM7H-D70dHZIb.js} +1 -1
- package/public/assets/{chunk-GF5L2VYU-BCFrJAqb.js → chunk-GF5L2VYU-Bj5gzsOF.js} +1 -1
- package/public/assets/{chunk-I66GZJ75-XdTCBJhL.js → chunk-I66GZJ75-DYvsApTB.js} +1 -1
- package/public/assets/{chunk-JQJVKLGR-BwEUHZBv.js → chunk-JQJVKLGR-sPaAWMcl.js} +1 -1
- package/public/assets/{chunk-KBJHAD2P-HjBUqR8F.js → chunk-KBJHAD2P-sIJR9nWn.js} +1 -1
- package/public/assets/{chunk-NSK5VX7P-DkHwHrKE.js → chunk-NSK5VX7P-BBXDYhCk.js} +1 -1
- package/public/assets/{chunk-QR6OTTB3-DF1_EWFH.js → chunk-QR6OTTB3-0D3J_ldz.js} +1 -1
- package/public/assets/{chunk-RYQCIY6F-BaBhRLGF.js → chunk-RYQCIY6F-ByFYkZW5.js} +1 -1
- package/public/assets/{chunk-UBXNYLIW-BNV3VrZA.js → chunk-UBXNYLIW-vH5z2CFq.js} +1 -1
- package/public/assets/{chunk-W5SLKNZC-5ymyg6B_.js → chunk-W5SLKNZC-DXOAlDYx.js} +1 -1
- package/public/assets/{chunk-WRU74C26-oznLCI2s.js → chunk-WRU74C26-BDeea6GT.js} +1 -1
- package/public/assets/{chunk-XXDRQBXY-sauNIYLc.js → chunk-XXDRQBXY-CyNmLpLK.js} +1 -1
- package/public/assets/classDiagram-JCYQIIEL-BTuFAVSb.js +1 -0
- package/public/assets/classDiagram-v2-OCEON4UE-BTuFAVSb.js +1 -0
- package/public/assets/{cose-bilkent-JH36ORCC-B0A4Je-o.js → cose-bilkent-JH36ORCC-DyR57pP4.js} +1 -1
- package/public/assets/{cynefin-VYW2F7L2-BtmksekA.js → cynefin-VYW2F7L2-BfcydoVY.js} +1 -1
- package/public/assets/{cynefinDiagram-MW4NZA55-DxlB0XWy.js → cynefinDiagram-MW4NZA55-D4C7d9xF.js} +1 -1
- package/public/assets/{dagre-VZM6K2ZE-BwX2jQEP.js → dagre-VZM6K2ZE-Bb3QdyiU.js} +1 -1
- package/public/assets/{diagram-7IWD3JNH-CRw4eKmV.js → diagram-7IWD3JNH-75Re1gEQ.js} +1 -1
- package/public/assets/{diagram-B4RE2ZJO-BhSHl_HC.js → diagram-B4RE2ZJO-DBZrEAjD.js} +1 -1
- package/public/assets/{diagram-LBJQPF4R-BLNDbOa-.js → diagram-LBJQPF4R-DP03ppoa.js} +1 -1
- package/public/assets/{diagram-Q27KOJAE-OI-WVr2z.js → diagram-Q27KOJAE-Baaak7ET.js} +1 -1
- package/public/assets/{diagram-UB23O5K3-Dw4v-DRV.js → diagram-UB23O5K3-DRtw-cVM.js} +1 -1
- package/public/assets/{dist-CkCHUIyI.js → dist-oRJzdzK9.js} +1 -1
- package/public/assets/{ebnfDiagram-BXEA7PRR-_CCtytYQ.js → ebnfDiagram-BXEA7PRR-DSIhRAUP.js} +1 -1
- package/public/assets/{erDiagram-JOGREHBK-DPwktZ67.js → erDiagram-JOGREHBK-tfCb8QEk.js} +1 -1
- package/public/assets/eventmodeling-45OFAUF4-Br197Gcb.js +1 -0
- package/public/assets/flowDiagram-UKHOOZJN-BDKCF_Nj.js +1 -0
- package/public/assets/{ganttDiagram-PKOTCBZU-ChHOAX0R.js → ganttDiagram-PKOTCBZU-BYZrkk6r.js} +1 -1
- package/public/assets/{gitGraph-TEB2WS4Q-DTKjAplS.js → gitGraph-TEB2WS4Q-BtIPzVXt.js} +1 -1
- package/public/assets/{gitGraphDiagram-DS77QQ5N-CetQtIP1.js → gitGraphDiagram-DS77QQ5N-B319uA7z.js} +1 -1
- package/public/assets/index-BmpLrTQR.css +2 -0
- package/public/assets/{index-CMeHHiB8.js → index-Dl33_YDJ.js} +8 -8
- package/public/assets/{info-DKCQHKI2-CEZZoshL.js → info-DKCQHKI2-CTIPSIKZ.js} +1 -1
- package/public/assets/{infoDiagram-6WML65LV-Dn0Ci1fh.js → infoDiagram-6WML65LV-D-foqSEg.js} +1 -1
- package/public/assets/{ishikawaDiagram-WSZJBQD7-C0yvCWyv.js → ishikawaDiagram-WSZJBQD7-CsSDhWgz.js} +1 -1
- package/public/assets/{journeyDiagram-NVQOT4AX-CpTSt3oh.js → journeyDiagram-NVQOT4AX-D4kgOJAw.js} +1 -1
- package/public/assets/{kanban-definition-27J2QSJJ-Co4MhtWb.js → kanban-definition-27J2QSJJ-B3kNYdeo.js} +1 -1
- package/public/assets/{line-CKdpDvRy.js → line-DI4sM6NI.js} +1 -1
- package/public/assets/{linear-BAY9SBNB.js → linear-CR-Nr7tu.js} +1 -1
- package/public/assets/{mermaid-parser.core-B-yKcreq.js → mermaid-parser.core-Jx7mG9S9.js} +3 -3
- package/public/assets/{mermaid.core-CW_jKbCL.js → mermaid.core-Dad-8IqK.js} +4 -4
- package/public/assets/{mindmap-definition-FAOFIHXS-CejNgzQn.js → mindmap-definition-FAOFIHXS-DNeiGiTc.js} +1 -1
- package/public/assets/{packet-7NZHBO7P-B53cyWv4.js → packet-7NZHBO7P-DDW1h-3U.js} +1 -1
- package/public/assets/{pegDiagram-VL7TDLO6-DAh-rohm.js → pegDiagram-VL7TDLO6-BhFSf_Qi.js} +1 -1
- package/public/assets/{pie-RZYD4A2V-Bbl6CzP-.js → pie-RZYD4A2V-DlcS3vnT.js} +1 -1
- package/public/assets/{pieDiagram-7S7Q4E2Y-BoiaUX85.js → pieDiagram-7S7Q4E2Y-bIpfrRof.js} +1 -1
- package/public/assets/{quadrantDiagram-CIZ2JOQS-2EgkGrDN.js → quadrantDiagram-CIZ2JOQS-BOsxmZiJ.js} +1 -1
- package/public/assets/{radar-I7S5WNFK-1Piyk_Oc.js → radar-I7S5WNFK-y6e8oiKJ.js} +1 -1
- package/public/assets/{railroad-3IZDKUUU-DcQG7hTA.js → railroad-3IZDKUUU-DSMAGu-t.js} +1 -1
- package/public/assets/railroad-abnf-AHOZXSZD-cMf5ZHgo.js +1 -0
- package/public/assets/railroad-ebnf-EBAXGLYW-C4ZEbGk2.js +1 -0
- package/public/assets/railroad-peg-LSFZ7HO6-KGZPMRIB.js +1 -0
- package/public/assets/{railroadDiagram-AXF67PYL-kPPDLWet.js → railroadDiagram-AXF67PYL-BRtEa2OT.js} +1 -1
- package/public/assets/{requirementDiagram-LRYGKXZP-B0wNE6wF.js → requirementDiagram-LRYGKXZP-Dikys7Ub.js} +1 -1
- package/public/assets/{sankeyDiagram-W5VNT64P-CyKEUx9w.js → sankeyDiagram-W5VNT64P-BiYgVWtA.js} +1 -1
- package/public/assets/{sequenceDiagram-SI44F4Z6-DT7UmiRF.js → sequenceDiagram-SI44F4Z6-BUtXadia.js} +1 -1
- package/public/assets/{src-EbLSa_z9.js → src-BtDe6ofe.js} +1 -1
- package/public/assets/{stateDiagram-OKZ733FA-BNk8YOH4.js → stateDiagram-OKZ733FA-5fho-t3_.js} +1 -1
- package/public/assets/stateDiagram-v2-UEYNNEHI-DFmJr5_x.js +1 -0
- package/public/assets/{swimlanes-SLNWSIFB-B7eUL04h.js → swimlanes-SLNWSIFB-BpmWJ8es.js} +1 -1
- package/public/assets/swimlanesDiagram-ULZ7WXOC-0uIZxCfL.js +8 -0
- package/public/assets/{timeline-definition-Z64GVDOM-CDLh-h94.js → timeline-definition-Z64GVDOM-_w3lytrY.js} +1 -1
- package/public/assets/{treeView-QDETBFTQ-BAscBSG9.js → treeView-QDETBFTQ-D_l_9pyQ.js} +1 -1
- package/public/assets/{treemap-6X3UGDF4-B2ahLgfF.js → treemap-6X3UGDF4-DvWVuWhL.js} +1 -1
- package/public/assets/{vennDiagram-T6HMQDX7-62WQ_264.js → vennDiagram-T6HMQDX7-ClZPTfxU.js} +1 -1
- package/public/assets/{wardley-OPB4EBWU-DUrXideD.js → wardley-OPB4EBWU-CgyA0GRV.js} +1 -1
- package/public/assets/{wardleyDiagram-T6FBY63Y-Ci4DF612.js → wardleyDiagram-T6FBY63Y-DNhv1Bla.js} +1 -1
- package/public/assets/{xychartDiagram-ELKLHX3M-D--O5thj.js → xychartDiagram-ELKLHX3M-CNeebJO2.js} +1 -1
- package/public/index.html +2 -2
- package/public/assets/architecture-TIHT7OUA-CFm6TN4T.js +0 -1
- package/public/assets/channel-CHLtdsMA.js +0 -1
- package/public/assets/classDiagram-JCYQIIEL-Wf8lPn9O.js +0 -1
- package/public/assets/classDiagram-v2-OCEON4UE-Wf8lPn9O.js +0 -1
- package/public/assets/eventmodeling-45OFAUF4-COOjM2XZ.js +0 -1
- package/public/assets/flowDiagram-UKHOOZJN-ipIqOWay.js +0 -1
- package/public/assets/index-C40rGsvd.css +0 -2
- package/public/assets/railroad-abnf-AHOZXSZD-CaviTNom.js +0 -1
- package/public/assets/railroad-ebnf-EBAXGLYW-K7l-WN0j.js +0 -1
- package/public/assets/railroad-peg-LSFZ7HO6-Bu22X3mO.js +0 -1
- package/public/assets/stateDiagram-v2-UEYNNEHI-8Oafa2Rm.js +0 -1
- package/public/assets/swimlanesDiagram-ULZ7WXOC-BT5Ebr7W.js +0 -8
package/dist/bus.js
CHANGED
|
@@ -22,8 +22,8 @@ const tailJsonl = (p, limit) => {
|
|
|
22
22
|
/* Thresholds are judgement, not measurement, and are stated here rather than buried: "producing"
|
|
23
23
|
is the working cadence, and >8h is the shape of an overnight stall. The 2h boundary exists
|
|
24
24
|
because the previous model put a coffee break and a seventeen-hour stall in one bucket. */
|
|
25
|
-
const
|
|
26
|
-
const
|
|
25
|
+
const EMITTING_MS = 2 * 3_600_000;
|
|
26
|
+
const SILENT_MS = 8 * 3_600_000;
|
|
27
27
|
const SCAN_LINES = 4000;
|
|
28
28
|
/** Newest emission per agent, from the room logs and the status stream. */
|
|
29
29
|
export function outputIndex(root, scanLines = SCAN_LINES) {
|
|
@@ -60,9 +60,9 @@ export function outputIndex(root, scanLines = SCAN_LINES) {
|
|
|
60
60
|
so a caller can tell the two apart. Collapsing them would be the same defect one level down. */
|
|
61
61
|
const progressOf = (hit, now, scanLines) => {
|
|
62
62
|
if (!hit)
|
|
63
|
-
return { lastOutputAt: null, ageMs: null, state: "unknown", basis: null, scannedLines: scanLines };
|
|
63
|
+
return { lastOutputAt: null, ageMs: null, state: "unknown", basis: null, scannedLines: scanLines, measures: "bus-emissions" };
|
|
64
64
|
const ageMs = now - hit.ts;
|
|
65
|
-
return { lastOutputAt: hit.ts, ageMs, state: ageMs <
|
|
65
|
+
return { lastOutputAt: hit.ts, ageMs, state: ageMs < EMITTING_MS ? "emitting" : ageMs < SILENT_MS ? "quiet-on-bus" : "silent-on-bus", basis: hit.basis, scannedLines: scanLines, measures: "bus-emissions" };
|
|
66
66
|
};
|
|
67
67
|
/* Reachability buckets. `idle` used to span 15 MINUTES to 24 HOURS, so a coffee break and an
|
|
68
68
|
overnight stall rendered identically; `dormant` splits that. */
|
|
@@ -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
|
+
}
|
package/dist/gitinfo.js
CHANGED
|
@@ -3,6 +3,7 @@ import { execFile } from "node:child_process";
|
|
|
3
3
|
import { promisify } from "node:util";
|
|
4
4
|
import { existsSync } from "node:fs";
|
|
5
5
|
import path from "node:path";
|
|
6
|
+
import { refsIn, refsMatch } from "@davidbalzan/groundwork-seam";
|
|
6
7
|
const run = promisify(execFile);
|
|
7
8
|
async function git(cwd, args) { try {
|
|
8
9
|
const r = await run("git", args, { cwd, maxBuffer: 8 << 20 });
|
|
@@ -150,35 +151,48 @@ async function ghPrs(projectPath) {
|
|
|
150
151
|
|
|
151
152
|
Same defect the kit found in queue-done-loop the same afternoon: a ref MENTIONED in a row is a
|
|
152
153
|
different fact from the ref that IDENTIFIES it. */
|
|
153
|
-
|
|
154
|
-
const m = /#(\d+)\b/.exec(cell ?? "");
|
|
155
|
-
return m ? Number(m[1]) : null;
|
|
156
|
-
};
|
|
157
|
-
/* `owner/name` from a remote URL, ssh or https. null when there is no origin — in which case the
|
|
158
|
-
repo check below is SKIPPED rather than guessed, and matching falls back to the pr cell alone. */
|
|
154
|
+
/* `owner/name` from a remote URL, ssh or https. null when there is no origin. */
|
|
159
155
|
export const slugFromRemoteUrl = (url) => {
|
|
160
156
|
const m = url ? /(?:[:/])([^/:]+\/[^/]+?)(?:\.git)?$/.exec(url.trim()) : null;
|
|
161
157
|
return m ? m[1] : null;
|
|
162
158
|
};
|
|
163
159
|
const originSlug = async (projectPath) => slugFromRemoteUrl(await git(projectPath, ["remote", "get-url", "origin"]));
|
|
164
|
-
/*
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
160
|
+
/* The ref a board row is ABOUT: its `pr` CELL, qualified by its `repo` CELL when it has one.
|
|
161
|
+
Never a `#ref` occurring anywhere else in the row — a Status reading "blocked by #39" used to
|
|
162
|
+
make that row answer for PR 39, and `find` returns the first hit, so a mention beat the row that
|
|
163
|
+
actually was that PR.
|
|
164
|
+
|
|
165
|
+
Ref parsing and comparison now come from the seam (0.1.8) instead of the local pair this file
|
|
166
|
+
used to carry. That pair was a re-derivation of a primitive the seam did not yet export; it does
|
|
167
|
+
now, and keeping our own would be a fifth matcher of the class the kit spent a day removing.
|
|
168
|
+
|
|
169
|
+
ONE DELIBERATE BEHAVIOUR CHANGE, adopted rather than worked around: with NO origin remote
|
|
170
|
+
(`contextRepo` null) and a row that names a repo, the local version ACCEPTED — it could not
|
|
171
|
+
establish a difference, so it declined to assert one. `refsMatch` returns false: an unresolvable
|
|
172
|
+
tie is not a tie. The seam's direction is the conservative one for this caller too — showing no
|
|
173
|
+
merge gate is better than showing another repo's — so the console takes the primitive's
|
|
174
|
+
semantics rather than keeping a private exception. */
|
|
175
|
+
const rowRef = (row) => {
|
|
176
|
+
const cell = (row.pr ?? "").trim();
|
|
177
|
+
const repo = (row.repo ?? "").trim();
|
|
178
|
+
/* Qualify with the repo column only when the cell is not ALREADY qualified. The test is a `/`,
|
|
179
|
+
not a `#`: an earlier draft checked for `#` and every pr cell contains one, so qualification
|
|
180
|
+
silently never happened and a cross-repo collision resolved to the first row. Caught by the
|
|
181
|
+
two-repos fixture, which is why that fixture exists. */
|
|
182
|
+
const [ref] = refsIn(repo && !cell.includes("/") ? `${repo}#${cell.replace(/^#/, "")}` : cell);
|
|
183
|
+
return ref ?? null;
|
|
184
|
+
};
|
|
168
185
|
/* The gate a board reports for PR `n` in THIS repo, or undefined. Exported and used by
|
|
169
186
|
gitBranches directly, so the test exercises this function rather than a copy of it — a test that
|
|
170
187
|
re-implements the matcher pins the fixture, not the code. */
|
|
171
188
|
export const gateForPr = (rows, n, slug) => {
|
|
172
|
-
const
|
|
189
|
+
const [target] = refsIn(slug ? `${slug}#${n}` : `#${n}`);
|
|
190
|
+
if (!target)
|
|
191
|
+
return undefined;
|
|
192
|
+
const row = rows?.find((r) => { const ref = rowRef(r); return ref ? refsMatch(target, ref, { contextRepo: slug }) : false; });
|
|
173
193
|
const qa = row?.mergeGate ?? row?.status;
|
|
174
194
|
return qa ? String(qa) : undefined;
|
|
175
195
|
};
|
|
176
|
-
export const repoMatches = (rowRepo, slug) => {
|
|
177
|
-
const cell = (rowRepo ?? "").trim();
|
|
178
|
-
if (!cell || !slug)
|
|
179
|
-
return true;
|
|
180
|
-
return cell === slug || cell.endsWith(`/${slug.split("/").pop()}`) || slug.endsWith(`/${cell}`) || cell === slug.split("/").pop();
|
|
181
|
-
};
|
|
182
196
|
export function gitBranches(projectPath, hints = {}) {
|
|
183
197
|
return cached(`branches:${projectPath}:${(hints.agentIds ?? []).join(",")}`, async () => {
|
|
184
198
|
const defaultBranch = "main";
|
package/dist/kitresolve.js
CHANGED
|
@@ -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
|
-
|
|
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
|
-
|
|
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,
|
|
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:
|
|
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:
|
|
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:
|
|
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 }, () => {
|
|
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,10 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@davidbalzan/groundwork-console",
|
|
3
3
|
"private": false,
|
|
4
|
-
"version": "0.1.
|
|
4
|
+
"version": "0.1.15",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"dependencies": {
|
|
7
|
-
"@davidbalzan/groundwork-seam": "0.1.
|
|
7
|
+
"@davidbalzan/groundwork-seam": "0.1.8",
|
|
8
8
|
"@hono/node-server": "^2.1.1",
|
|
9
9
|
"@modelcontextprotocol/sdk": "^1.30.0",
|
|
10
10
|
"hono": "^4.13.2",
|
|
@@ -48,11 +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",
|
|
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
|
-
"test:progress": "tsx test/progress.test.mts"
|
|
56
|
+
"test:progress": "tsx test/progress.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"
|
|
57
61
|
}
|
|
58
62
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{m as e,t}from"./mermaid-parser.core-
|
|
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-
|
|
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};
|