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.
- package/hooks/replay.mjs +107 -0
- package/hooks/tier.mjs +11 -0
- package/hooks/tmux-pusher.mjs +27 -0
- package/package.json +1 -1
- package/scripts/coord-pusher.mjs +16 -32
- package/src/server.ts +40 -20
- package/src/tools/admin.ts +8 -1
- package/src/tools/away.ts +48 -4
- package/src/tools/board-ref.ts +47 -2
- package/src/tools/messaging.ts +43 -2
- package/src/tools/records.ts +381 -25
- package/src/tools/registry.ts +5 -2
- package/src/tools/rooms.ts +2 -1
- package/src/tools/shared.ts +28 -0
- package/src/tools/stall.ts +29 -1
- package/src/tools/transport.ts +79 -10
- package/src/tools/work.ts +70 -4
- package/src/tools/worktrees.ts +64 -2
- package/src/work.ts +4 -0
- package/dist/build.js +0 -113
- package/dist/build.js.map +0 -1
- package/dist/capabilities.js +0 -158
- package/dist/capabilities.js.map +0 -1
- package/dist/prefix.js +0 -64
- package/dist/prefix.js.map +0 -1
- package/dist/roles.js +0 -132
- package/dist/roles.js.map +0 -1
- package/dist/server-identity.js +0 -82
- package/dist/server-identity.js.map +0 -1
- package/dist/server.js +0 -625
- package/dist/server.js.map +0 -1
- package/dist/store.js +0 -553
- package/dist/store.js.map +0 -1
- package/dist/tools/admin.js +0 -317
- package/dist/tools/admin.js.map +0 -1
- package/dist/tools/attention.js +0 -73
- package/dist/tools/attention.js.map +0 -1
- package/dist/tools/away.js +0 -243
- package/dist/tools/away.js.map +0 -1
- package/dist/tools/board-ref.js +0 -164
- package/dist/tools/board-ref.js.map +0 -1
- package/dist/tools/event-kinds.js +0 -39
- package/dist/tools/event-kinds.js.map +0 -1
- package/dist/tools/events.js +0 -234
- package/dist/tools/events.js.map +0 -1
- package/dist/tools/index.js +0 -14
- package/dist/tools/index.js.map +0 -1
- package/dist/tools/logwatch.js +0 -85
- package/dist/tools/logwatch.js.map +0 -1
- package/dist/tools/messaging.js +0 -667
- package/dist/tools/messaging.js.map +0 -1
- package/dist/tools/record-events.js +0 -380
- package/dist/tools/record-events.js.map +0 -1
- package/dist/tools/records.js +0 -686
- package/dist/tools/records.js.map +0 -1
- package/dist/tools/registry.js +0 -497
- package/dist/tools/registry.js.map +0 -1
- package/dist/tools/render.js +0 -2
- package/dist/tools/render.js.map +0 -1
- package/dist/tools/rooms.js +0 -210
- package/dist/tools/rooms.js.map +0 -1
- package/dist/tools/rotate.js +0 -143
- package/dist/tools/rotate.js.map +0 -1
- package/dist/tools/scopes.js +0 -126
- package/dist/tools/scopes.js.map +0 -1
- package/dist/tools/shared.js +0 -86
- package/dist/tools/shared.js.map +0 -1
- package/dist/tools/stall.js +0 -387
- package/dist/tools/stall.js.map +0 -1
- package/dist/tools/transport.js +0 -1810
- package/dist/tools/transport.js.map +0 -1
- package/dist/tools/work.js +0 -319
- package/dist/tools/work.js.map +0 -1
- package/dist/tools/worktrees.js +0 -339
- package/dist/tools/worktrees.js.map +0 -1
- package/dist/typed-records.js +0 -174
- package/dist/typed-records.js.map +0 -1
- package/dist/work.js +0 -2
- package/dist/work.js.map +0 -1
package/dist/tools/rooms.js
DELETED
|
@@ -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
|
package/dist/tools/rooms.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"rooms.js","sourceRoot":"","sources":["../../src/tools/rooms.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAEL,UAAU,EACV,YAAY,EAGZ,SAAS,EAET,UAAU,EAEV,SAAS,EACT,WAAW,EACX,UAAU,EACV,UAAU,EACV,UAAU,EAEV,QAAQ,EAER,eAAe,EAKf,aAAa,EAEb,QAAQ,EACR,SAAS,EAGT,YAAY,EAEZ,QAAQ,EAER,WAAW,EAMX,UAAU,GAEX,MAAM,aAAa,CAAC;AACrB,OAAO,EASL,SAAS,EAET,MAAM,GAKP,MAAM,aAAa,CAAC;AAErB,6CAA6C;AAE7C,MAAM,CAAC,MAAM,eAAe,GAAG,EAAW,CAAC;AAE3C,MAAM,CAAC,KAAK,UAAU,aAAa;IACjC,MAAM,GAAG,GAAG,MAAM,QAAQ,EAAE,CAAC;IAC7B,MAAM,KAAK,GAAG,EAAE,CAAC;IACjB,KAAK,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;QAC5C,MAAM,IAAI,GAAG,MAAM,SAAS,CAAU,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC;QACtD,KAAK,CAAC,IAAI,CAAC;YACT,IAAI;YACJ,KAAK,EAAE,CAAC,CAAC,KAAK;YACd,IAAI,EAAE,CAAC,CAAC,IAAI;YACZ,OAAO,EAAE,CAAC,CAAC,OAAO,IAAI,EAAE;YACxB,WAAW,EAAE,CAAC,CAAC,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC,MAAM;YACrC,YAAY,EAAE,IAAI,CAAC,MAAM;YACzB,MAAM,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS;YAC1D,SAAS,EAAE,CAAC,CAAC,SAAS;YACtB,SAAS,EAAE,CAAC,CAAC,SAAS;SACvB,CAAC,CAAC;IACL,CAAC;IACD,OAAO,EAAE,KAAK,EAAE,CAAC;AACnB,CAAC;AAED,MAAM,CAAC,MAAM,cAAc,GAAG;IAC5B,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IAC1B,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;CACxB,CAAC;AAEF,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,IAAuC;IACxE,MAAM,IAAI,GAAG,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACtC,MAAM,UAAU,CAAC,IAAI,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC;IACrC,MAAM,SAAS,CAAC,IAAI,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC;IACpC,MAAM,WAAW,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,EAAE,GAAG,IAAI,CAAC,OAAO,aAAa,CAAC,CAAC,CAAC;IAC5F,MAAM,GAAG,GAAG,MAAM,QAAQ,EAAE,CAAC;IAC7B,MAAM,CAAC,GAAG,GAAG,CAAC,IAAI,CAAC,CAAC;IACpB,MAAM,GAAG,GAAG,MAAM,SAAS,CAAU,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC;IACrD,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAS,UAAU,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,EAAE,CAAC,CAAC;IACpE,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,GAAG,CAAC,MAAM,GAAG,SAAS,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,CAAC,CAAC,CAAC;IACzE,OAAO;QACL,EAAE,EAAE,IAAI;QACR,IAAI,EAAE,IAAI;QACV,KAAK,EAAE,CAAC,EAAE,KAAK;QACf,IAAI,EAAE,CAAC,EAAE,IAAI;QACb,OAAO,EAAE,CAAC,EAAE,OAAO,IAAI,EAAE;QACzB,MAAM;KACP,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,MAAM,eAAe,GAAG;IAC7B,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IAC1B,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;CACxB,CAAC;AAEF,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,IAAuC;IACzE,MAAM,IAAI,GAAG,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACtC,IAAI,IAAI,KAAK,YAAY,EAAE,CAAC;QAC1B,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,kCAAkC,EAAE,CAAC;IAClE,CAAC;IACD,MAAM,YAAY,CAAC,IAAI,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC;IACvC,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;AAClC,CAAC;AAED,MAAM,CAAC,MAAM,kBAAkB,GAAG;IAChC,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IAC1B,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IACvB,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE;CAClB,CAAC;AAEF,MAAM,CAAC,KAAK,UAAU,gBAAgB,CAAC,IAAsD;IAC3F,MAAM,IAAI,GAAG,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACtC,MAAM,UAAU,CAAC,IAAI,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC;IACrC,MAAM,WAAW,CAAC,IAAI,EAAE,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC;IAC7D,MAAM,WAAW,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,EAAE,qBAAqB,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;IACjG,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,CAAC;AACrD,CAAC;AAED,+EAA+E;AAC/E,8EAA8E;AAC9E,2EAA2E;AAC3E,6EAA6E;AAC7E,+EAA+E;AAC/E,+EAA+E;AAC/E,kEAAkE;AAClE,EAAE;AACF,gFAAgF;AAChF,MAAM,eAAe,GAAG,IAAI,CAAC;AAE7B,MAAM,CAAC,MAAM,iBAAiB,GAAG;IAC/B,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IAC1B,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IACvB,4EAA4E;IAC5E,6BAA6B;IAC7B,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAC3B,oEAAoE;IACpE,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE;IACxC,8EAA8E;IAC9E,6EAA6E;IAC7E,0EAA0E;IAC1E,uBAAuB;IACvB,SAAS,EAAE,CAAC,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,QAAQ,EAAE;CACjF,CAAC;AAUF,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,IAAc;IAClD,MAAM,IAAI,GAAG,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACtC,MAAM,KAAK,GAAG,CAAC,MAAM,EAAE,YAAY,EAAE,WAAW,CAAC,CAAC,MAAM,CACtD,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,CAAmB,CAAC,KAAK,SAAS,CAC/C,CAAC;IACF,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACvB,OAAO;YACL,EAAE,EAAE,KAAc;YAClB,KAAK,EAAE,gGAAgG;SACxG,CAAC;IACJ,CAAC;IACD,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACrB,OAAO,EAAE,EAAE,EAAE,KAAc,EAAE,KAAK,EAAE,+CAA+C,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC;IAC1G,CAAC;IAED,MAAM,UAAU,CAAC,IAAI,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC;IACrC,MAAM,KAAK,GAAG,MAAM,QAAQ,EAAE,CAAC;IAC/B,MAAM,MAAM,GAAG,KAAK,CAAC,IAAI,CAAC,EAAE,IAAI,IAAI,EAAE,CAAC;IAEvC,IAAI,IAAY,CAAC;IACjB,IAAI,GAAW,CAAC;IAChB,IAAI,IAAI,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;QAC5B,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC;QACjB,GAAG,GAAG,UAAU,CAAC;IACnB,CAAC;SAAM,IAAI,IAAI,CAAC,UAAU,KAAK,SAAS,EAAE,CAAC;QACzC,IAAI,GAAG,MAAM,CAAC,CAAC,CAAC,GAAG,MAAM,KAAK,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC;QAClE,GAAG,GAAG,aAAa,CAAC;IACtB,CAAC;SAAM,CAAC;QACN,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC,SAAU,CAAC;QAC1C,MAAM,KAAK,GAAG,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QACnC,IAAI,KAAK,KAAK,CAAC,CAAC,EAAE,CAAC;YACjB,OAAO;gBACL,EAAE,EAAE,KAAc;gBAClB,KAAK,EAAE,gCAAgC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,8FAA8F;aAC1J,CAAC;QACJ,CAAC;QACD,IAAI,MAAM,CAAC,OAAO,CAAC,IAAI,EAAE,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC;YACrD,OAAO;gBACL,EAAE,EAAE,KAAc;gBAClB,KAAK,EAAE,qBAAqB,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,2GAA2G;aAC5J,CAAC;QACJ,CAAC;QACD,IAAI,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,GAAG,OAAO,GAAG,MAAM,CAAC,KAAK,CAAC,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC;QAC5E,GAAG,GAAG,SAAS,CAAC;IAClB,CAAC;IAED,MAAM,WAAW,CAAC,IAAI,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC;IACtD,MAAM,WAAW,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,EAAE,+BAA+B,CAAC,CAAC,CAAC;IAE/F,6EAA6E;IAC7E,2EAA2E;IAC3E,OAAO;QACL,EAAE,EAAE,IAAa;QACjB,IAAI,EAAE,IAAI;QACV,GAAG;QACH,KAAK,EAAE,MAAM,CAAC,UAAU,CAAC,IAAI,EAAE,MAAM,CAAC;QACtC,WAAW,EAAE,MAAM,CAAC,UAAU,CAAC,MAAM,EAAE,MAAM,CAAC;QAC9C,GAAG,CAAC,MAAM,CAAC,UAAU,CAAC,IAAI,EAAE,MAAM,CAAC,GAAG,eAAe;YACnD,CAAC,CAAC;gBACE,OAAO,EACL,WAAW,MAAM,CAAC,UAAU,CAAC,IAAI,EAAE,MAAM,CAAC,sBAAsB,eAAe,qCAAqC;oBACpH,8HAA8H;oBAC9H,+FAA+F;aAClG;YACH,CAAC,CAAC,EAAE,CAAC;KACR,CAAC;AACJ,CAAC;AAED,oCAAoC;AAEpC,MAAM,CAAC,MAAM,gBAAgB,GAAG;IAC9B,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IAC1B,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IACvB,yDAAyD;IACzD,KAAK,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE;CAC9B,CAAC;AAEF,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,IAAwD;IAC3F,MAAM,IAAI,GAAG,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACtC,IAAI,IAAI,KAAK,YAAY;QAAE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,mCAAmC,EAAE,CAAC;IAE5F,MAAM,KAAK,GAAG,MAAM,QAAQ,EAAE,CAAC;IAC/B,MAAM,KAAK,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC;IAC1B,IAAI,CAAC,KAAK;QAAE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,SAAS,IAAI,kBAAkB,EAAE,CAAC;IAEzE,MAAM,OAAO,GAAG,KAAK,CAAC,OAAO,IAAI,EAAE,CAAC;IACpC,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC;QACtC,OAAO;YACL,EAAE,EAAE,KAAK;YACT,KAAK,EAAE,SAAS,IAAI,eAAe,OAAO,CAAC,MAAM,eAAe,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,qCAAqC;YACvH,OAAO;SACR,CAAC;IACJ,CAAC;IAED,8BAA8B;IAC9B,MAAM,UAAU,CAAe,UAAU,EAAE,EAAE,EAAE,CAAC,OAAO,EAAE,EAAE;QACzD,OAAO,OAAO,CAAC,IAAI,CAAC,CAAC;QACrB,OAAO,OAAO,CAAC;IACjB,CAAC,CAAC,CAAC;IAEH,iCAAiC;IACjC,MAAM,IAAI,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC;IAC5B,MAAM,WAAW,GAAG,MAAM,UAAU,CAAC,IAAI,CAAC,CAAC;IAE3C,6EAA6E;IAC7E,sBAAsB;IACtB,MAAM,eAAe,GAAa,EAAE,CAAC;IACrC,KAAK,MAAM,KAAK,IAAI,MAAM,eAAe,EAAE,EAAE,CAAC;QAC5C,MAAM,EAAE,GAAG,KAAK,CAAC,OAAO,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC;QACxC,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,KAAK,CAAC,CAAC;QAChD,IAAI,OAAO,GAAG,KAAK,CAAC;QACpB,MAAM,UAAU,CAAS,UAAU,EAAE,EAAE,EAAE,CAAC,OAAO,EAAE,EAAE;YACnD,IAAI,OAAO,CAAC,WAAW,EAAE,CAAC,IAAI,CAAC,KAAK,SAAS,EAAE,CAAC;gBAC9C,OAAO,OAAO,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;gBACjC,OAAO,GAAG,IAAI,CAAC;YACjB,CAAC;YACD,OAAO,OAAO,CAAC;QACjB,CAAC,CAAC,CAAC;QACH,IAAI,OAAO;YAAE,eAAe,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACxC,CAAC;IAED,MAAM,WAAW,CAAC,SAAS,EAAE,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,YAAY,EAAE,oBAAoB,IAAI,EAAE,CAAC,CAAC,CAAC;IAC7F,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,WAAW,EAAE,OAAO,EAAE,eAAe,EAAE,CAAC;AACzE,CAAC"}
|
package/dist/tools/rotate.js
DELETED
|
@@ -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
|
package/dist/tools/rotate.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"rotate.js","sourceRoot":"","sources":["../../src/tools/rotate.ts"],"names":[],"mappings":"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"}
|
package/dist/tools/scopes.js
DELETED
|
@@ -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
|
package/dist/tools/scopes.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"scopes.js","sourceRoot":"","sources":["../../src/tools/scopes.ts"],"names":[],"mappings":"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"}
|
package/dist/tools/shared.js
DELETED
|
@@ -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
|
package/dist/tools/shared.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"shared.js","sourceRoot":"","sources":["../../src/tools/shared.ts"],"names":[],"mappings":"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"}
|