agent-coord-mcp 0.26.16 → 0.26.18

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 (79) hide show
  1. package/hooks/replay.mjs +107 -0
  2. package/hooks/tier.mjs +11 -0
  3. package/hooks/tmux-pusher.mjs +27 -0
  4. package/package.json +1 -1
  5. package/scripts/coord-pusher.mjs +16 -32
  6. package/src/server.ts +40 -20
  7. package/src/tools/admin.ts +8 -1
  8. package/src/tools/away.ts +48 -4
  9. package/src/tools/board-ref.ts +47 -2
  10. package/src/tools/messaging.ts +43 -2
  11. package/src/tools/records.ts +381 -25
  12. package/src/tools/registry.ts +5 -2
  13. package/src/tools/rooms.ts +2 -1
  14. package/src/tools/shared.ts +28 -0
  15. package/src/tools/stall.ts +29 -1
  16. package/src/tools/transport.ts +79 -10
  17. package/src/tools/work.ts +70 -4
  18. package/src/tools/worktrees.ts +64 -2
  19. package/src/work.ts +4 -0
  20. package/dist/build.js +0 -113
  21. package/dist/build.js.map +0 -1
  22. package/dist/capabilities.js +0 -158
  23. package/dist/capabilities.js.map +0 -1
  24. package/dist/prefix.js +0 -64
  25. package/dist/prefix.js.map +0 -1
  26. package/dist/roles.js +0 -132
  27. package/dist/roles.js.map +0 -1
  28. package/dist/server-identity.js +0 -82
  29. package/dist/server-identity.js.map +0 -1
  30. package/dist/server.js +0 -625
  31. package/dist/server.js.map +0 -1
  32. package/dist/store.js +0 -553
  33. package/dist/store.js.map +0 -1
  34. package/dist/tools/admin.js +0 -317
  35. package/dist/tools/admin.js.map +0 -1
  36. package/dist/tools/attention.js +0 -73
  37. package/dist/tools/attention.js.map +0 -1
  38. package/dist/tools/away.js +0 -243
  39. package/dist/tools/away.js.map +0 -1
  40. package/dist/tools/board-ref.js +0 -164
  41. package/dist/tools/board-ref.js.map +0 -1
  42. package/dist/tools/event-kinds.js +0 -39
  43. package/dist/tools/event-kinds.js.map +0 -1
  44. package/dist/tools/events.js +0 -234
  45. package/dist/tools/events.js.map +0 -1
  46. package/dist/tools/index.js +0 -14
  47. package/dist/tools/index.js.map +0 -1
  48. package/dist/tools/logwatch.js +0 -85
  49. package/dist/tools/logwatch.js.map +0 -1
  50. package/dist/tools/messaging.js +0 -667
  51. package/dist/tools/messaging.js.map +0 -1
  52. package/dist/tools/record-events.js +0 -380
  53. package/dist/tools/record-events.js.map +0 -1
  54. package/dist/tools/records.js +0 -686
  55. package/dist/tools/records.js.map +0 -1
  56. package/dist/tools/registry.js +0 -497
  57. package/dist/tools/registry.js.map +0 -1
  58. package/dist/tools/render.js +0 -2
  59. package/dist/tools/render.js.map +0 -1
  60. package/dist/tools/rooms.js +0 -210
  61. package/dist/tools/rooms.js.map +0 -1
  62. package/dist/tools/rotate.js +0 -143
  63. package/dist/tools/rotate.js.map +0 -1
  64. package/dist/tools/scopes.js +0 -126
  65. package/dist/tools/scopes.js.map +0 -1
  66. package/dist/tools/shared.js +0 -86
  67. package/dist/tools/shared.js.map +0 -1
  68. package/dist/tools/stall.js +0 -387
  69. package/dist/tools/stall.js.map +0 -1
  70. package/dist/tools/transport.js +0 -1810
  71. package/dist/tools/transport.js.map +0 -1
  72. package/dist/tools/work.js +0 -319
  73. package/dist/tools/work.js.map +0 -1
  74. package/dist/tools/worktrees.js +0 -339
  75. package/dist/tools/worktrees.js.map +0 -1
  76. package/dist/typed-records.js +0 -174
  77. package/dist/typed-records.js.map +0 -1
  78. package/dist/work.js +0 -2
  79. package/dist/work.js.map +0 -1
@@ -1,210 +0,0 @@
1
- import { z } from "zod";
2
- import path from "node:path";
3
- import { CURSOR_DIR, DEFAULT_ROOM, ROOM_FILE, ROOMS_FILE, addMember, appendJsonl, cursorFile, deleteFile, ensureRoom, getRooms, listCursorFiles, normalizeRoom, readJson, readJsonl, removeMember, roomFile, setRoomMeta, updateJson, } from "../store.js";
4
- import { getOffset, sysMsg, } from "./shared.js";
5
- // ---------- room / channel tools ----------
6
- export const listRoomsSchema = {};
7
- export async function listRoomsTool() {
8
- const reg = await getRooms();
9
- const rooms = [];
10
- for (const [room, e] of Object.entries(reg)) {
11
- const msgs = await readJsonl(roomFile(room));
12
- rooms.push({
13
- room,
14
- topic: e.topic,
15
- motd: e.motd,
16
- members: e.members ?? [],
17
- memberCount: (e.members ?? []).length,
18
- messageCount: msgs.length,
19
- lastTs: msgs.length ? msgs[msgs.length - 1].ts : undefined,
20
- createdAt: e.createdAt,
21
- createdBy: e.createdBy,
22
- });
23
- }
24
- return { rooms };
25
- }
26
- export const joinRoomSchema = {
27
- agentId: z.string().min(1),
28
- room: z.string().min(1),
29
- };
30
- export async function joinRoomTool(args) {
31
- const chan = normalizeRoom(args.room);
32
- await ensureRoom(chan, args.agentId);
33
- await addMember(chan, args.agentId);
34
- await appendJsonl(roomFile(chan), sysMsg(args.agentId, chan, `${args.agentId} has joined`));
35
- const reg = await getRooms();
36
- const e = reg[chan];
37
- const all = await readJsonl(roomFile(chan));
38
- const cursor = await readJson(cursorFile(args.agentId), {});
39
- const unread = Math.max(0, all.length - getOffset(cursor, "room", chan));
40
- return {
41
- ok: true,
42
- room: chan,
43
- topic: e?.topic,
44
- motd: e?.motd,
45
- members: e?.members ?? [],
46
- unread,
47
- };
48
- }
49
- export const leaveRoomSchema = {
50
- agentId: z.string().min(1),
51
- room: z.string().min(1),
52
- };
53
- export async function leaveRoomTool(args) {
54
- const chan = normalizeRoom(args.room);
55
- if (chan === DEFAULT_ROOM) {
56
- return { ok: false, error: "cannot leave the default channel" };
57
- }
58
- await removeMember(chan, args.agentId);
59
- return { ok: true, room: chan };
60
- }
61
- export const setRoomTopicSchema = {
62
- agentId: z.string().min(1),
63
- room: z.string().min(1),
64
- topic: z.string(),
65
- };
66
- export async function setRoomTopicTool(args) {
67
- const chan = normalizeRoom(args.room);
68
- await ensureRoom(chan, args.agentId);
69
- await setRoomMeta(chan, { topic: args.topic }, args.agentId);
70
- await appendJsonl(roomFile(chan), sysMsg(args.agentId, chan, `changed topic to: ${args.topic}`));
71
- return { ok: true, room: chan, topic: args.topic };
72
- }
73
- // Whole-string-only writes made a one-clause edit cost a full rewrite, and the
74
- // bill was paid in STALE DOCTRINE, not tokens. One room's MOTD reached 33,870
75
- // bytes (every other room on the bus: 0–739). At that size a one-line rule
76
- // change costs ~34KB in AND ~34KB back out in the echoed response, so a rule
77
- // routing escalations to a role that had just been deleted was LEFT STANDING —
78
- // another 34KB write "wasn't worth one stale clause". A MOTD nobody can afford
79
- // to correct is worse than a short one that is merely incomplete.
80
- //
81
- // So: append and find/replace, and the response no longer echoes the body back.
82
- const MOTD_SOFT_LIMIT = 4096;
83
- export const setRoomMotdSchema = {
84
- agentId: z.string().min(1),
85
- room: z.string().min(1),
86
- // Exactly one of these. `motd` stays first and stays supported — this is an
87
- // addition, not a migration.
88
- motd: z.string().optional(),
89
- // Append a clause. Joined with a newline; no separator is invented.
90
- motdAppend: z.string().min(1).optional(),
91
- // Replace the FIRST occurrence of `find`. Refuses on no match and on multiple
92
- // matches: a patch that silently hits nothing is the failure mode this whole
93
- // item exists to remove, and one that hits the wrong clause of several is
94
- // worse than refusing.
95
- motdPatch: z.object({ find: z.string().min(1), replace: z.string() }).optional(),
96
- };
97
- export async function setRoomMotdTool(args) {
98
- const chan = normalizeRoom(args.room);
99
- const given = ["motd", "motdAppend", "motdPatch"].filter((k) => args[k] !== undefined);
100
- if (given.length === 0) {
101
- return {
102
- ok: false,
103
- error: "pass exactly one of motd (replace whole), motdAppend (add a clause), motdPatch {find, replace}",
104
- };
105
- }
106
- if (given.length > 1) {
107
- return { ok: false, error: `pass ONE of motd/motdAppend/motdPatch — got ${given.join(", ")}` };
108
- }
109
- await ensureRoom(chan, args.agentId);
110
- const rooms = await getRooms();
111
- const before = rooms[chan]?.motd ?? "";
112
- let next;
113
- let how;
114
- if (args.motd !== undefined) {
115
- next = args.motd;
116
- how = "replaced";
117
- }
118
- else if (args.motdAppend !== undefined) {
119
- next = before ? `${before}\n${args.motdAppend}` : args.motdAppend;
120
- how = "appended to";
121
- }
122
- else {
123
- const { find, replace } = args.motdPatch;
124
- const first = before.indexOf(find);
125
- if (first === -1) {
126
- return {
127
- ok: false,
128
- error: `motdPatch found no match for ${JSON.stringify(find)} — the MOTD is unchanged. Read it with list_rooms and patch a string that is actually in it.`,
129
- };
130
- }
131
- if (before.indexOf(find, first + find.length) !== -1) {
132
- return {
133
- ok: false,
134
- error: `motdPatch matched ${JSON.stringify(find)} more than once — refusing rather than guessing which clause you meant. Extend 'find' until it is unique.`,
135
- };
136
- }
137
- next = before.slice(0, first) + replace + before.slice(first + find.length);
138
- how = "patched";
139
- }
140
- await setRoomMeta(chan, { motd: next }, args.agentId);
141
- await appendJsonl(roomFile(chan), sysMsg(args.agentId, chan, `updated the room rules (MOTD)`));
142
- // Deliberately NOT echoing `motd` back. It cost as much as the write itself,
143
- // for a value the caller either just supplied or can read with list_rooms.
144
- return {
145
- ok: true,
146
- room: chan,
147
- how,
148
- bytes: Buffer.byteLength(next, "utf8"),
149
- bytesBefore: Buffer.byteLength(before, "utf8"),
150
- ...(Buffer.byteLength(next, "utf8") > MOTD_SOFT_LIMIT
151
- ? {
152
- warning: `MOTD is ${Buffer.byteLength(next, "utf8")} bytes (soft limit ${MOTD_SOFT_LIMIT}). Every agent reads this on join. ` +
153
- `Past this size the doctrine belongs in a repo file with a short pointer here — an MOTD too expensive to correct goes stale, ` +
154
- `which costs more than it saves. motdAppend/motdPatch make small corrections cheap either way.`,
155
- }
156
- : {}),
157
- };
158
- }
159
- // ---------- delete_room ----------
160
- export const deleteRoomSchema = {
161
- agentId: z.string().min(1),
162
- room: z.string().min(1),
163
- // When true, kick remaining members instead of refusing.
164
- force: z.boolean().optional(),
165
- };
166
- export async function deleteRoomTool(args) {
167
- const chan = normalizeRoom(args.room);
168
- if (chan === DEFAULT_ROOM)
169
- return { ok: false, error: "cannot delete the default channel" };
170
- const rooms = await getRooms();
171
- const entry = rooms[chan];
172
- if (!entry)
173
- return { ok: false, error: `room '${chan}' does not exist` };
174
- const members = entry.members ?? [];
175
- if (members.length > 0 && !args.force) {
176
- return {
177
- ok: false,
178
- error: `room '${chan}' still has ${members.length} member(s): ${members.join(", ")}. Pass force=true to delete anyway.`,
179
- members,
180
- };
181
- }
182
- // Remove from rooms registry.
183
- await updateJson(ROOMS_FILE, {}, (current) => {
184
- delete current[chan];
185
- return current;
186
- });
187
- // Delete the backing JSONL file.
188
- const file = roomFile(chan);
189
- const fileDeleted = await deleteFile(file);
190
- // Drop the channel offset from every agent's cursor so no offset points into
191
- // a now-deleted file.
192
- const cursorsAdjusted = [];
193
- for (const fname of await listCursorFiles()) {
194
- const id = fname.replace(/\.json$/, "");
195
- const cursorPath = path.join(CURSOR_DIR, fname);
196
- let touched = false;
197
- await updateJson(cursorPath, {}, (current) => {
198
- if (current.roomOffsets?.[chan] !== undefined) {
199
- delete current.roomOffsets[chan];
200
- touched = true;
201
- }
202
- return current;
203
- });
204
- if (touched)
205
- cursorsAdjusted.push(id);
206
- }
207
- await appendJsonl(ROOM_FILE, sysMsg(args.agentId, DEFAULT_ROOM, `deleted channel #${chan}`));
208
- return { ok: true, room: chan, fileDeleted, members, cursorsAdjusted };
209
- }
210
- //# sourceMappingURL=rooms.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"rooms.js","sourceRoot":"","sources":["../../src/tools/rooms.ts"],"names":[],"mappings":"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"}
@@ -1,143 +0,0 @@
1
- /*
2
- * `rotate` — handover-to-self across a context clear (Phase 5 Task 5).
3
- *
4
- * THE PACKET IS A SNAPSHOT, AND A CONTEXT RESET IS PRECISELY WHEN NOBODY CAN
5
- * CHECK IT. After `/clear` the agent has no memory to contradict the packet
6
- * with: whatever it says becomes the world. So the packet is written from
7
- * TOOLS AND `gh`, never from chat memory — memory is the one source that
8
- * cannot be re-derived after the reset it is meant to survive — and on the
9
- * far side it is RECONCILED against live state before any work is done.
10
- *
11
- * A packet that is merely READ on resume is a stale world restored with
12
- * confidence. That is the failure this verb exists to prevent, so `missionHint`
13
- * is named a HINT in the type and treated as one in code: it is the only field
14
- * that cannot be verified, and it never gets to assert anything.
15
- */
16
- import { existsSync, readFileSync, writeFileSync, mkdirSync } from "node:fs";
17
- import { execFileSync } from "node:child_process";
18
- import path from "node:path";
19
- import { z } from "zod";
20
- import { ROOT } from "../store.js";
21
- /*
22
- * 5.4 — JOB IDS ARE AN ALLOWLIST.
23
- *
24
- * `archive-done` is deliberately ABSENT and stays absent: it is an arithmetic
25
- * job over DONE.md that belongs to Groundwork and an existing QUEUE item, and
26
- * a rotation is the worst possible moment to run one. Rotation exists to carry
27
- * state ACROSS a reset intact; a verb that also rewrites the records it is
28
- * carrying cannot be checked afterwards by the agent that ran it.
29
- */
30
- export const ROTATE_JOBS = ["reseed-only", "phase-boundary"];
31
- const packetFile = (agentId) => path.join(ROOT, "rotate", `${agentId}.json`);
32
- const realFacts = (repo) => {
33
- const git = (args) => execFileSync("git", args, { cwd: repo, encoding: "utf8", stdio: ["ignore", "pipe", "ignore"] }).trim();
34
- const out = execFileSync("gh", ["pr", "list", "--state", "open", "--json", "number,headRefOid"], { cwd: repo, encoding: "utf8", stdio: ["ignore", "pipe", "ignore"] });
35
- return {
36
- dirty: git(["status", "--porcelain"]),
37
- sha: git(["rev-parse", "HEAD"]),
38
- openPrs: JSON.parse(out).map((p) => ({ n: p.number, headRefOid: p.headRefOid })),
39
- };
40
- };
41
- export const rotateSchema = {
42
- agentId: z.string().min(1),
43
- job: z.string().min(1),
44
- repo: z.string().optional(),
45
- rooms: z.array(z.string()).optional(),
46
- missionHint: z.string().optional(),
47
- write: z.boolean().optional(),
48
- };
49
- export async function rotateTool(args, facts = realFacts) {
50
- const repo = args.repo ?? process.cwd();
51
- // 5.4 — unknown job refused BY NAME, and `archive-done` gets its own reason
52
- // so the refusal reads as a decision rather than a typo.
53
- if (!ROTATE_JOBS.includes(args.job)) {
54
- const extra = args.job === "archive-done" ? ` 'archive-done' is deliberately not a rotation job: it rewrites the records the rotation is carrying, and a reset is the one moment nobody can check the result. It belongs to Groundwork and its existing QUEUE item.` : "";
55
- return { ok: false, error: `'${args.job}' is not a rotate job. Allowed: ${ROTATE_JOBS.join(", ")}.${extra}` };
56
- }
57
- let f;
58
- try {
59
- f = facts(repo);
60
- }
61
- catch (e) {
62
- return { ok: false, error: `could not read live state (${String(e.message).split("\n")[0]}) — a packet built from anything but live state is chat memory with a filename.` };
63
- }
64
- // 5.2 — MID-SLICE DIRTY REFUSES THE CLEAR.
65
- //
66
- // Uncommitted work is the one thing a packet cannot carry: it is not in the
67
- // repo, not on a branch, and not in any tool's answer, so after `/clear` no
68
- // reconciliation can discover it ever existed. It does not get lost loudly —
69
- // it gets lost silently, which is why this is a refusal and not a warning.
70
- if (f.dirty) {
71
- const n = f.dirty.split("\n").filter(Boolean).length;
72
- return {
73
- ok: false,
74
- error: `${n} uncommitted change(s) — refusing to rotate mid-slice. Uncommitted work is the one thing a packet cannot carry: after the clear, nothing can discover it existed. Commit it or stash it deliberately, then rotate.`,
75
- dirty: f.dirty.split("\n").filter(Boolean),
76
- };
77
- }
78
- const packet = {
79
- agentId: args.agentId,
80
- job: args.job,
81
- rooms: args.rooms ?? [],
82
- name: args.agentId,
83
- missionHint: args.missionHint ?? "",
84
- atSha: f.sha,
85
- openPrs: f.openPrs,
86
- at: new Date().toISOString(),
87
- };
88
- if (!args.write)
89
- return { ok: true, written: false, packet, note: `packet built from live state; pass write:true to persist it before /clear.` };
90
- mkdirSync(path.dirname(packetFile(args.agentId)), { recursive: true });
91
- writeFileSync(packetFile(args.agentId), `${JSON.stringify(packet, null, 2)}\n`);
92
- return { ok: true, written: true, packet, path: packetFile(args.agentId) };
93
- }
94
- export const rotateReconcileSchema = { agentId: z.string().min(1), repo: z.string().optional() };
95
- export async function rotateReconcileTool(args, facts = realFacts) {
96
- const repo = args.repo ?? process.cwd();
97
- const f0 = packetFile(args.agentId);
98
- if (!existsSync(f0))
99
- return { ok: false, error: `no rotate packet for '${args.agentId}'. A reseeded agent with no packet has nothing to reconcile against and must not infer its state — ask for a GO.` };
100
- let packet;
101
- try {
102
- packet = JSON.parse(readFileSync(f0, "utf8"));
103
- }
104
- catch (e) {
105
- return { ok: false, error: `packet for '${args.agentId}' is unreadable (${String(e.message).split("\n")[0]}) — an unparseable packet is not an empty one; do not proceed as if there were no prior state.` };
106
- }
107
- let f;
108
- try {
109
- f = facts(repo);
110
- }
111
- catch (e) {
112
- // NOT RECONCILED IS NOT RECONCILED-CLEAN.
113
- return { ok: false, error: `could not read live state to reconcile (${String(e.message).split("\n")[0]}) — NOT checked, which is not the same as checked and matching.`, packet };
114
- }
115
- const live = new Map(f.openPrs.map((p) => [p.n, p.headRefOid]));
116
- const divergences = [];
117
- // 5.5 — THE PACKET'S OPEN PRs ARE CLAIMS, NOT FACTS.
118
- //
119
- // A PR that merged during the reset is the dangerous direction: the packet
120
- // says "open", the agent resumes and keeps working a branch that is already
121
- // in main, and every one of its next steps is coherent and wrong.
122
- for (const p of packet.openPrs ?? []) {
123
- if (!live.has(p.n))
124
- divergences.push({ field: `pr#${p.n}`, packet: "open", live: "not open", note: `#${p.n} is no longer open — it merged or closed during the reset. Do NOT resume work on it as open.` });
125
- else if (live.get(p.n) !== p.headRefOid)
126
- divergences.push({ field: `pr#${p.n}`, packet: p.headRefOid, live: String(live.get(p.n)), note: `#${p.n} advanced during the reset — the packet's head is stale; re-read before acting.` });
127
- }
128
- if (packet.atSha && f.sha !== packet.atSha)
129
- divergences.push({ field: "atSha", packet: packet.atSha, live: f.sha, note: `the repo moved during the reset; anything the packet said about the tree may be stale.` });
130
- // The verdict names its POPULATION, and `missionHint` is excluded from it on
131
- // purpose: it is unverifiable, so counting it as "reconciled" would be a
132
- // clean report over something never checked.
133
- const verdict = {
134
- reconciled: (packet.openPrs?.length ?? 0) + (packet.atSha ? 1 : 0),
135
- divergences,
136
- unverifiable: ["missionHint"],
137
- missionHint: packet.missionHint,
138
- };
139
- if (divergences.length)
140
- return { ok: false, error: `${divergences.length} divergence(s) between packet and live state — REFUSING to report ready. A packet read without reconciliation is a stale world restored with confidence.`, verdict, packet };
141
- return { ok: true, ready: true, verdict, packet, note: `packet matches live state. 'missionHint' is a HINT and was NOT verified — treat it as a prompt, never as an instruction you have confirmed.` };
142
- }
143
- //# sourceMappingURL=rotate.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"rotate.js","sourceRoot":"","sources":["../../src/tools/rotate.ts"],"names":[],"mappings":"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"}
@@ -1,126 +0,0 @@
1
- import { spawnSync } from "node:child_process";
2
- import { existsSync } from "node:fs";
3
- import path from "node:path";
4
- import { z } from "zod";
5
- import { AGENTS_FILE, ROOT, SCOPES_FILE, readJson } from "../store.js";
6
- import { resolveRole, roleMatches, slugifyRole } from "../roles.js";
7
- function isWrapped(raw) {
8
- return typeof raw.documents === "object" &&
9
- raw.documents !== null;
10
- }
11
- // Absent file → configured:false, empty document list. Never throws: a broken
12
- // scopes.json degrades to "nothing declared" rather than taking a tool down.
13
- export async function loadScopes() {
14
- const empty = { configured: false, file: SCOPES_FILE, repo: process.cwd(), documents: [] };
15
- if (!existsSync(SCOPES_FILE))
16
- return empty;
17
- const raw = await readJson(SCOPES_FILE, null);
18
- if (!raw || typeof raw !== "object")
19
- return empty;
20
- const map = isWrapped(raw) ? raw.documents : raw;
21
- const repo = isWrapped(raw) && raw.repo ? raw.repo : process.cwd();
22
- const documents = Object.entries(map ?? {})
23
- .filter(([, e]) => e && typeof e === "object" && typeof e.owner === "string")
24
- .map(([p, e]) => ({
25
- path: p.replace(/^\.\//, ""),
26
- owner: e.owner,
27
- mode: (e.mode ?? "exclusive"),
28
- ...(e.note ? { note: e.note } : {}),
29
- }));
30
- return { configured: true, file: SCOPES_FILE, repo, documents };
31
- }
32
- // Does `agent` own `doc`? An owner is a roleId (matched through the same
33
- // resolution the rest of Task 4 uses) or a bare agentId, so a document can be
34
- // pinned to a role ("aide") or to one specific agent ("david-worker-2").
35
- export function ownsDocument(agentId, entry, owner) {
36
- const target = slugifyRole(owner);
37
- if (agentId && slugifyRole(agentId) === target)
38
- return true;
39
- return roleMatches(entry, new Set([target]));
40
- }
41
- export const listScopesSchema = {
42
- // Ask about one document instead of listing everything.
43
- path: z.string().optional(),
44
- // Whose write is being contemplated (defaults to nobody — a pure listing).
45
- agentId: z.string().optional(),
46
- };
47
- export async function listScopesTool(args) {
48
- const scopes = await loadScopes();
49
- const reg = await readJson(AGENTS_FILE, {});
50
- const entry = args.agentId ? reg[args.agentId] : undefined;
51
- // Every answer carries `advisory: true`. A caller that stores this verdict
52
- // is storing an opinion, not a permission.
53
- const base = {
54
- ok: true,
55
- advisory: true,
56
- configured: scopes.configured,
57
- file: scopes.file,
58
- repo: scopes.repo,
59
- note: scopes.configured
60
- ? "declared scopes are advisory — the bus does not mediate file writes (Phase 8 Task 5)"
61
- : `no ${path.basename(SCOPES_FILE)} in ${ROOT} — no document is owned, nothing is checked (opt-in)`,
62
- };
63
- if (args.path === undefined) {
64
- return {
65
- ...base,
66
- documents: scopes.documents,
67
- ...(args.agentId
68
- ? { you: { agentId: args.agentId, role: resolveRole(entry) ?? null } }
69
- : {}),
70
- };
71
- }
72
- const wanted = args.path.replace(/^\.\//, "");
73
- const doc = scopes.documents.find((d) => d.path === wanted);
74
- if (!doc) {
75
- return { ...base, path: wanted, owned: false, mayWrite: true, reason: "no scope declared for this document" };
76
- }
77
- const mine = args.agentId ? ownsDocument(args.agentId, entry, doc.owner) : false;
78
- return {
79
- ...base,
80
- path: doc.path,
81
- owned: true,
82
- owner: doc.owner,
83
- mode: doc.mode,
84
- ...(doc.note ? { docNote: doc.note } : {}),
85
- mayWrite: mine || doc.mode === "shared",
86
- reason: mine
87
- ? `'${args.agentId}' matches the declared owner '${doc.owner}'`
88
- : doc.mode === "shared"
89
- ? `declared shared — any agent may write, '${doc.owner}' is the maintainer`
90
- : `owned by '${doc.owner}' (${doc.mode})${args.agentId ? `; '${args.agentId}' does not match` : ""} — coordinate before writing`,
91
- };
92
- }
93
- export function isGitRepo(repo) {
94
- if (!existsSync(repo))
95
- return false;
96
- const r = spawnSync("git", ["-C", repo, "rev-parse", "--is-inside-work-tree"], { encoding: "utf8" });
97
- return r.status === 0 && String(r.stdout).trim() === "true";
98
- }
99
- // Last commit that touched `file`, or null if git has never seen it. Cheap
100
- // (`-1`), read-only, and confined to `repo`.
101
- export function lastWriterOf(repo, file) {
102
- const r = spawnSync("git", ["-C", repo, "log", "-1", "--format=%an%x00%ae%x00%h%x00%aI", "--", file], { encoding: "utf8" });
103
- if (r.status !== 0)
104
- return null;
105
- const line = String(r.stdout).trim();
106
- if (!line)
107
- return null;
108
- const [author = "", email = "", commit = "", when = ""] = line.split("\0");
109
- return { author, email, commit, when };
110
- }
111
- // Map a commit author back to a bus agent. Git records humans (or one shared
112
- // machine account), not agent ids, so this only succeeds when the author name
113
- // or email local-part IS a registered agentId or its role id — which is the
114
- // honest limit of the check. Unmappable authors are reported as such by doctor
115
- // instead of being counted as drift.
116
- export function attributeWriter(writer, reg) {
117
- const candidates = new Set([writer.author, writer.email.split("@")[0] ?? ""].map(slugifyRole).filter(Boolean));
118
- for (const [agentId, entry] of Object.entries(reg)) {
119
- const resolved = resolveRole(entry);
120
- if (candidates.has(slugifyRole(agentId)) || (resolved && candidates.has(resolved.roleId))) {
121
- return { agentId, ...(resolved ? { roleId: resolved.roleId } : {}) };
122
- }
123
- }
124
- return null;
125
- }
126
- //# sourceMappingURL=scopes.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"scopes.js","sourceRoot":"","sources":["../../src/tools/scopes.ts"],"names":[],"mappings":"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"}
@@ -1,86 +0,0 @@
1
- import { randomUUID } from "node:crypto";
2
- import { existsSync } from "node:fs";
3
- import { promises as fsp } from "node:fs";
4
- import path from "node:path";
5
- import { DEFAULT_ROOM, STATUS_FILE, inboxFile, normalizeRoom, roomFile, } from "../store.js";
6
- /**
7
- * How to REPORT a transport's room capability.
8
- *
9
- * Three states, not two. `undefined` is a marker written before the field
10
- * existed: it cannot answer, and "unknown" is the only truthful report. The
11
- * defect being fixed is precisely a two-state reading of a three-state world —
12
- * `attached: true` covered "full", "DM-only", and "cannot say" alike.
13
- */
14
- export const roomFeedOf = (m) => !m || m.rooms === undefined ? "unknown" : m.rooms ? "on" : "off";
15
- // THE retention predicate — one definition, three call sites (prune,
16
- // live compaction, overflow-digest quoting). It lived as three copies of
17
- // `e.kind === "decision"`, and they drifted: a v2 agent doing exactly what
18
- // Phase 8 asks — sending `record:{type:"decision"}` and omitting the legacy
19
- // `kind` — had its decisions compacted at chatter rate and dropped from
20
- // digests. A protocol whose correct usage loses data.
21
- //
22
- // MONOTONE, like the tier floor: `||` can only ever GRANT the long retention,
23
- // never remove it. So there is no cutover, no migration, and no existing file
24
- // whose behaviour changes — a legacy `kind:"decision"` keeps exactly the
25
- // retention it had. Two sources that can each override each other is the
26
- // disagreement this phase deletes; a source that can only raise is not that.
27
- //
28
- // Deliberately structural about `record`: it takes anything with the two
29
- // fields, so status entries and archive rows can be passed without a cast.
30
- export { isDecision } from "@davidbalzan/groundwork-seam/protocol";
31
- // Resolve the physical file for a (source, agent, channel) tuple.
32
- export function sourceFile(source, agentId, room) {
33
- if (source === "inbox")
34
- return inboxFile(agentId);
35
- if (source === "status")
36
- return STATUS_FILE;
37
- return roomFile(room ?? DEFAULT_ROOM);
38
- }
39
- // Read/write the cursor offset for a (source, channel). `general` keeps using
40
- // the flat roomOffset key (hook compat); other channels use roomOffsets[chan].
41
- export function getOffset(cursor, source, room) {
42
- if (source === "inbox")
43
- return cursor.inboxOffset ?? 0;
44
- if (source === "status")
45
- return cursor.statusOffset ?? 0;
46
- const chan = normalizeRoom(room);
47
- return chan === DEFAULT_ROOM ? cursor.roomOffset ?? 0 : cursor.roomOffsets?.[chan] ?? 0;
48
- }
49
- export function setOffset(cursor, source, room, n) {
50
- if (source === "inbox") {
51
- cursor.inboxOffset = n;
52
- return;
53
- }
54
- if (source === "status") {
55
- cursor.statusOffset = n;
56
- return;
57
- }
58
- const chan = normalizeRoom(room);
59
- if (chan === DEFAULT_ROOM)
60
- cursor.roomOffset = n;
61
- else
62
- (cursor.roomOffsets ??= {})[chan] = n;
63
- }
64
- export function sysMsg(from, room, text) {
65
- return { id: randomUUID(), ts: Date.now(), from, room, text, system: true };
66
- }
67
- export const STALE_MS = 5 * 60 * 1000;
68
- export const EVICT_MS = 24 * 60 * 60 * 1000;
69
- export const MAX_WAIT_MS = 60_000;
70
- // ---------- helpers ----------
71
- export async function moveFile(from, to) {
72
- if (!existsSync(from))
73
- return false;
74
- await fsp.mkdir(path.dirname(to), { recursive: true });
75
- try {
76
- await fsp.rename(from, to);
77
- }
78
- catch {
79
- // Cross-device or other rename failure — fall back to copy + unlink.
80
- const data = await fsp.readFile(from);
81
- await fsp.writeFile(to, data);
82
- await fsp.unlink(from);
83
- }
84
- return true;
85
- }
86
- //# sourceMappingURL=shared.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"shared.js","sourceRoot":"","sources":["../../src/tools/shared.ts"],"names":[],"mappings":"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"}