@afokapu/atdd-bun 0.10.23 → 0.10.25
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/conventions/delivery/delivery.board.convention.yaml +2 -1
- package/detectors/bun_interlocking_infrastructure/checks/wagon_contract_honoured.mjs +11 -3
- package/detectors/bun_interlocking_infrastructure/fixtures/clean/wagon_contract_honoured/plan/_trains/checkout.yaml +5 -0
- package/detectors/bun_interlocking_infrastructure/fixtures/dirty/wagon_contract_honoured/plan/_trains/checkout.yaml +5 -0
- package/integrity.json +7 -5
- package/package.json +1 -1
- package/src/board.ts +13 -0
- package/src/cli.ts +1 -0
|
@@ -27,11 +27,12 @@ terms:
|
|
|
27
27
|
atdd-bun chat post writes the header: from, to, participants and conversation always; kind (task, result, review-request, verdict, rebuttal, status, blocked, heartbeat), stage, reply-to, repo, branch, worktree, goal, base and sha when they apply. The body carries the whole instruction or answer, however long: the thread is the history. A heartbeat carries nothing else; anything that needs an answer goes as blocked, never inside a heartbeat.
|
|
28
28
|
- term_id: commands
|
|
29
29
|
text: >-
|
|
30
|
-
Post with the body on standard input; read what is on a topic; wait for the next message addressed to you on one or several topics (comma-separated), skipping kinds you do not act on (--skip heartbeat), bounded by --timeout so a tool call ends (exit 2: nothing yet). wait remembers where each identity stopped on each set of topics (~/.atdd-board/cursors), so re-arming a watcher is always the same command; --since still overrides it; and, for a human, atdd-bun chat alone opens the board: every topic on the left, the selected conversation on the right, live.
|
|
30
|
+
Post with the body on standard input; read what is on a topic; wait for the next message addressed to you on one or several topics (comma-separated), skipping kinds you do not act on (--skip heartbeat), bounded by --timeout so a tool call ends (exit 2: nothing yet). wait remembers where each identity stopped on each set of topics (~/.atdd-board/cursors), so re-arming a watcher is always the same command; --since still overrides it; follow is the listener for a host that wakes its agent on each line a running process prints (Claude Code's Monitor tool): it streams every message addressed to the identity as it arrives and keeps running, keeping the same saved place; a host that wakes its agent only when a process exits runs wait and re-arms it after each wake-up. One listener per identity. And, for a human, atdd-bun chat alone opens the board: every topic on the left, the selected conversation on the right, live.
|
|
31
31
|
values:
|
|
32
32
|
post: atdd-bun chat post <topic> --to <agent> --kind <kind> [--reply-to <id>] < message.md
|
|
33
33
|
read: atdd-bun chat read <topic> [--mine]
|
|
34
34
|
wait: atdd-bun chat wait <topic>[,<topic>...] [--since <id>] [--skip heartbeat] --timeout 540
|
|
35
|
+
follow: atdd-bun chat follow <topic>[,<topic>...] [--skip heartbeat,progress] [--timeout <seconds>]
|
|
35
36
|
board: atdd-bun chat
|
|
36
37
|
- term_id: server
|
|
37
38
|
text: >-
|
|
@@ -111,10 +111,17 @@ const violations = [];
|
|
|
111
111
|
|
|
112
112
|
for (const root of parseJsonEnv("ATDD_SCAN_ROOTS", [])) {
|
|
113
113
|
for (const croot of consumerRoots(root, excludes)) {
|
|
114
|
-
|
|
114
|
+
// Only a wagon some train carries moves Cargo, so only its contract can be honoured or broken in Cargo-moving code.
|
|
115
|
+
// A wagon no train's sequence carries yet (implemented, composed in a later tranche) is not judged until one does
|
|
116
|
+
// (S4 #qSWeDfXJVXcv; the convention's exception is per wagon, not per repository).
|
|
117
|
+
const contracts = [], carried = new Set();
|
|
115
118
|
for (const f of walk(join(croot, PLAN_ROOT), (p) => /\.ya?ml$/.test(p), excludes)) {
|
|
116
|
-
const
|
|
117
|
-
if (c) contracts.push({ file: f, ...c });
|
|
119
|
+
const text = read(f), c = wagonContract(text);
|
|
120
|
+
if (c) contracts.push({ file: f, wagon: text.match(/^wagon:\s*["']?([^"'#\s]+)/m)?.[1] ?? null, ...c });
|
|
121
|
+
let doc;
|
|
122
|
+
try { doc = Bun.YAML.parse(text); } catch { continue; }
|
|
123
|
+
if (doc && typeof doc.train_id === "string" && Array.isArray(doc.sequence))
|
|
124
|
+
for (const step of doc.sequence) for (const end of [step?.from, step?.to]) if (typeof end === "string" && end.startsWith("wagon:")) carried.add(end.slice(6).trim());
|
|
118
125
|
}
|
|
119
126
|
if (!contracts.length) continue; // no declared contract
|
|
120
127
|
|
|
@@ -128,6 +135,7 @@ for (const root of parseJsonEnv("ATDD_SCAN_ROOTS", [])) {
|
|
|
128
135
|
|
|
129
136
|
const blob = wagonCode.map((s) => maskComments(s.text)).join("\n");
|
|
130
137
|
for (const c of contracts) {
|
|
138
|
+
if (c.wagon && !carried.has(c.wagon)) continue; // no train carries this wagon yet
|
|
131
139
|
for (const [kind, names] of [["produce", c.produce], ["consume", c.consume]]) {
|
|
132
140
|
for (const name of names) {
|
|
133
141
|
if (blob.includes(name)) continue;
|
package/integrity.json
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"version": "0.10.
|
|
2
|
+
"version": "0.10.25",
|
|
3
3
|
"files": {
|
|
4
4
|
"HOOK_AUDIT.md": "5329d840db37671b1918f688ead26865473b87db73dbc75f7c8b2a8bbe8d6d43",
|
|
5
5
|
"PLANNER_PORT.md": "fb5935bac8b7ac18994de21e43ace3a5ef8cd55f85b0e3349fca261280054f11",
|
|
@@ -93,7 +93,7 @@
|
|
|
93
93
|
"conventions/coder.htmx/coder.htmx.verb-endpoint-same-origin.convention.yaml": "2128d26153e2d1f19c65a1e1665d4f82c78395daedb336d6ef1256e82b74aedb",
|
|
94
94
|
"conventions/coder.htmx/coder.htmx.verb-mutation-signals-progress.convention.yaml": "ae85c5ea01a09a3c41b939988088a8e5da91848d2710a1f0a1e0c86308638ac9",
|
|
95
95
|
"conventions/delivery/delivery.approved-sha-resolves.convention.yaml": "68f2ecc10870e780abb05bb31d211b1923d47b56672df4b3950f437aa9cf8ca8",
|
|
96
|
-
"conventions/delivery/delivery.board.convention.yaml": "
|
|
96
|
+
"conventions/delivery/delivery.board.convention.yaml": "4c544f51de80b09961a8df41028867023ab802aa4b31dcb0a1ce29e890552e6d",
|
|
97
97
|
"conventions/delivery/delivery.config-schema.convention.yaml": "4c7b449074a8bd9f89b70c702ab3e0df229105ddb4458772f894f0bf37813e9f",
|
|
98
98
|
"conventions/delivery/delivery.evidence-schema.convention.yaml": "9c6a22495dfb3e2fcbca700392866c3b5660084b1f5594230eb320b499d5e5cb",
|
|
99
99
|
"conventions/delivery/delivery.findings-resolved.convention.yaml": "f6574e93a9a2d4bdd6d6f5645720b1a647fc0048d95f7675fe783d2ddb62c05b",
|
|
@@ -437,7 +437,7 @@
|
|
|
437
437
|
"detectors/bun_interlocking_infrastructure/checks/interlocking_station_routing.mjs": "0221f5a8b49763388affefff670bc2a452e539e7658b08f6230a52f13edd36bd",
|
|
438
438
|
"detectors/bun_interlocking_infrastructure/checks/journey_runner_boundary.mjs": "570e4aef423881aed982b8f25a8d553f939d1ab82271236525c14efe3a20cd4a",
|
|
439
439
|
"detectors/bun_interlocking_infrastructure/checks/journey_station_routing.mjs": "bfd4899a604c34de621475ce155e527b9281d1174c6daa13a2abc7bebabf2cde",
|
|
440
|
-
"detectors/bun_interlocking_infrastructure/checks/wagon_contract_honoured.mjs": "
|
|
440
|
+
"detectors/bun_interlocking_infrastructure/checks/wagon_contract_honoured.mjs": "91f612dc6e1d5ef4ab29b4442f3e3d6ef972c7aac0abac9777d7d207a6ad6ba3",
|
|
441
441
|
"detectors/bun_interlocking_infrastructure/detect.mjs": "54c02f428596e057f828def0d68360b220b55dbf962b46694a21bc423ce57218",
|
|
442
442
|
"detectors/bun_interlocking_infrastructure/fixtures/clean/interlocking_delegates/server.ts": "36913357fdd3c5e375829a0554c605d70f5c05e2e83349f47505741598f6eb15",
|
|
443
443
|
"detectors/bun_interlocking_infrastructure/fixtures/clean/interlocking_delegates/src/match/wagon.ts": "ea202fa15fdf9d1391b1ae23343c9d1b09fcf8ef14f1dccfb8114ffaedea97c1",
|
|
@@ -464,6 +464,7 @@
|
|
|
464
464
|
"detectors/bun_interlocking_infrastructure/fixtures/clean/journey_station_routing/plan/_journeys/public.yaml": "840aac51f72c481650eea661e9fc414a9d157350234b67cfb7a977c201a0bdee",
|
|
465
465
|
"detectors/bun_interlocking_infrastructure/fixtures/clean/journey_station_routing/server.ts": "7fdfdeb8727d654bffec15d30cc65463791dc9c002557f364eb04e51fe5f27f4",
|
|
466
466
|
"detectors/bun_interlocking_infrastructure/fixtures/clean/journey_station_routing/src/trains/journey.ts": "2729867d88b4e5c955451b8d812392a91ca6da7d5601c64d27a84a3deb879d01",
|
|
467
|
+
"detectors/bun_interlocking_infrastructure/fixtures/clean/wagon_contract_honoured/plan/_trains/checkout.yaml": "8bcf77e3d624e538472e778b4b3058809c1f4931c172b863f0826f0f07bcb892",
|
|
467
468
|
"detectors/bun_interlocking_infrastructure/fixtures/clean/wagon_contract_honoured/plan/orders/_orders.yaml": "502aabeeb5a23a538f3a67ae4bb9dbd91ed4e7302f1bed5248186d07d035e47e",
|
|
468
469
|
"detectors/bun_interlocking_infrastructure/fixtures/clean/wagon_contract_honoured/src/orders/wagon.ts": "ba4ab28f3a576135a12de1390663ed107cf04652f554c9f28d6ce1fff43d4c08",
|
|
469
470
|
"detectors/bun_interlocking_infrastructure/fixtures/dirty/interlocking_delegates/server.ts": "36913357fdd3c5e375829a0554c605d70f5c05e2e83349f47505741598f6eb15",
|
|
@@ -491,6 +492,7 @@
|
|
|
491
492
|
"detectors/bun_interlocking_infrastructure/fixtures/dirty/journey_station_routing/plan/_journeys/public.yaml": "840aac51f72c481650eea661e9fc414a9d157350234b67cfb7a977c201a0bdee",
|
|
492
493
|
"detectors/bun_interlocking_infrastructure/fixtures/dirty/journey_station_routing/server.ts": "20d41fe5d1da6fa6f8b9e9800d83d3278638a555fac80f25a9b6b49cac973bf5",
|
|
493
494
|
"detectors/bun_interlocking_infrastructure/fixtures/dirty/journey_station_routing/src/trains/journey.ts": "2729867d88b4e5c955451b8d812392a91ca6da7d5601c64d27a84a3deb879d01",
|
|
495
|
+
"detectors/bun_interlocking_infrastructure/fixtures/dirty/wagon_contract_honoured/plan/_trains/checkout.yaml": "8bcf77e3d624e538472e778b4b3058809c1f4931c172b863f0826f0f07bcb892",
|
|
494
496
|
"detectors/bun_interlocking_infrastructure/fixtures/dirty/wagon_contract_honoured/plan/orders/_orders.yaml": "502aabeeb5a23a538f3a67ae4bb9dbd91ed4e7302f1bed5248186d07d035e47e",
|
|
495
497
|
"detectors/bun_interlocking_infrastructure/fixtures/dirty/wagon_contract_honoured/src/orders/wagon.ts": "23807627b7bb3e08355f23fe712c0060313e89588507f720929ff1998a2e2c69",
|
|
496
498
|
"detectors/bun_responsive_detector/atdd.implementation.yaml": "419f71d76c00b9cff615d7a66bcad47a85af083ec5efc5e3b7781e5aab23367a",
|
|
@@ -1194,9 +1196,9 @@
|
|
|
1194
1196
|
"relationships.yaml": "1cb713364aff54fb6e299e0737fe75a5d7b2e1dbd0a79b16b793aa1d269207b5",
|
|
1195
1197
|
"src/agent.ts": "65e4579adb5a54977f557f8c783aba0e2a2a1d5cf3cea9f017b67ffe598b2f65",
|
|
1196
1198
|
"src/board-ui.ts": "16a843705552f8f18e0e328e90e4a2a9148d771ca69f2708fe4a91302947dfad",
|
|
1197
|
-
"src/board.ts": "
|
|
1199
|
+
"src/board.ts": "72893289118461fbcee460d43f91e93fe4b078cabf171c03152c447eb8b71bb9",
|
|
1198
1200
|
"src/ci.ts": "67e54d2cbfc44a9e42837d5e750af526d6255c539d3c452a4d5fca3226c0d9ac",
|
|
1199
|
-
"src/cli.ts": "
|
|
1201
|
+
"src/cli.ts": "c1a7becd490ef9bf024569a869abc3b62ef48c0382897455e40fac9142d5ce46",
|
|
1200
1202
|
"src/delivery.ts": "f6bb6a7c42693d795b964c77b6186e1ca3a1556fd43932911a0ad42e72e7e441",
|
|
1201
1203
|
"src/docs-capability.ts": "115cf27049a5cf19c133bac5ec237072be6f969a59a2ef6767e054108a21dc5c",
|
|
1202
1204
|
"src/enforce.ts": "41a6f8c058a2a034996c817f224191403cc66ccc4ed4e04bbefc430014c783d8",
|
package/package.json
CHANGED
package/src/board.ts
CHANGED
|
@@ -164,6 +164,19 @@ export async function chat(args: string[], env: Record<string, string | undefine
|
|
|
164
164
|
console.log(format(message, topics.length > 1));
|
|
165
165
|
return 0;
|
|
166
166
|
}
|
|
167
|
+
if (command === "follow") {
|
|
168
|
+
// The listener for a host that wakes its agent on each line a running process prints: every message addressed to
|
|
169
|
+
// this identity, as it arrives, until --timeout (seconds; none = until stopped). Same place-keeping as wait.
|
|
170
|
+
const file = cursorFile(me, topics, env), skip = list(flag("skip")), total = Number(flag("timeout") ?? 0);
|
|
171
|
+
const deadline = total > 0 ? Date.now() + total * 1000 : Infinity;
|
|
172
|
+
let since = flag("since") || loadCursor(file) || "all";
|
|
173
|
+
for (;;) {
|
|
174
|
+
const left = Math.ceil((deadline - Date.now()) / 1000);
|
|
175
|
+
if (left <= 0) return 0;
|
|
176
|
+
const message = await waitFor(url, topics, me, since, Math.min(60, left), skip, 500, id => { since = id; saveCursor(file, id); });
|
|
177
|
+
if (message) console.log(format(message, topics.length > 1));
|
|
178
|
+
}
|
|
179
|
+
}
|
|
167
180
|
if (topics.length !== 1) throw new Error(`${command} takes one topic`);
|
|
168
181
|
const topic = topics[0];
|
|
169
182
|
if (command === "post") {
|
package/src/cli.ts
CHANGED
|
@@ -26,6 +26,7 @@ const usage = {
|
|
|
26
26
|
"atdd-bun chat post <topic> --to <agent,...> [--kind K] [--stage S] [--reply-to ID] [--repo R] [--branch B] [--worktree W] [--goal G] (body on stdin)",
|
|
27
27
|
"atdd-bun chat read <topic> [--mine] [--since ID]",
|
|
28
28
|
"atdd-bun chat wait <topic[,topic...]> [--since ID] [--skip KIND,...] [--timeout SECONDS]",
|
|
29
|
+
"atdd-bun chat follow <topic[,topic...]> [--since ID] [--skip KIND,...] [--timeout SECONDS]",
|
|
29
30
|
"atdd-bun chat (the board: every topic on the left, the conversation on the right)",
|
|
30
31
|
],
|
|
31
32
|
profiles: profileNames,
|