agy-worker-mcp 0.3.1
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/CHANGELOG.md +141 -0
- package/LICENSE +21 -0
- package/README.md +309 -0
- package/commands/agy-ceiling.md +31 -0
- package/dist/broker/blockers.d.ts +86 -0
- package/dist/broker/blockers.d.ts.map +1 -0
- package/dist/broker/blockers.js +390 -0
- package/dist/broker/blockers.js.map +1 -0
- package/dist/broker/outcome.d.ts +85 -0
- package/dist/broker/outcome.d.ts.map +1 -0
- package/dist/broker/outcome.js +147 -0
- package/dist/broker/outcome.js.map +1 -0
- package/dist/broker/reconcile.d.ts +74 -0
- package/dist/broker/reconcile.d.ts.map +1 -0
- package/dist/broker/reconcile.js +415 -0
- package/dist/broker/reconcile.js.map +1 -0
- package/dist/broker/result.d.ts +88 -0
- package/dist/broker/result.d.ts.map +1 -0
- package/dist/broker/result.js +234 -0
- package/dist/broker/result.js.map +1 -0
- package/dist/broker/verify.d.ts +52 -0
- package/dist/broker/verify.d.ts.map +1 -0
- package/dist/broker/verify.js +174 -0
- package/dist/broker/verify.js.map +1 -0
- package/dist/contract/errors.d.ts +119 -0
- package/dist/contract/errors.d.ts.map +1 -0
- package/dist/contract/errors.js +99 -0
- package/dist/contract/errors.js.map +1 -0
- package/dist/contract/index.d.ts +10 -0
- package/dist/contract/index.d.ts.map +1 -0
- package/dist/contract/index.js +10 -0
- package/dist/contract/index.js.map +1 -0
- package/dist/contract/paths.d.ts +139 -0
- package/dist/contract/paths.d.ts.map +1 -0
- package/dist/contract/paths.js +359 -0
- package/dist/contract/paths.js.map +1 -0
- package/dist/contract/schema.sql +64 -0
- package/dist/contract/types.d.ts +1113 -0
- package/dist/contract/types.d.ts.map +1 -0
- package/dist/contract/types.js +114 -0
- package/dist/contract/types.js.map +1 -0
- package/dist/events/cursor.d.ts +65 -0
- package/dist/events/cursor.d.ts.map +1 -0
- package/dist/events/cursor.js +286 -0
- package/dist/events/cursor.js.map +1 -0
- package/dist/events/detect.d.ts +58 -0
- package/dist/events/detect.d.ts.map +1 -0
- package/dist/events/detect.js +183 -0
- package/dist/events/detect.js.map +1 -0
- package/dist/events/normalize.d.ts +30 -0
- package/dist/events/normalize.d.ts.map +1 -0
- package/dist/events/normalize.js +158 -0
- package/dist/events/normalize.js.map +1 -0
- package/dist/events/parse.d.ts +41 -0
- package/dist/events/parse.d.ts.map +1 -0
- package/dist/events/parse.js +89 -0
- package/dist/events/parse.js.map +1 -0
- package/dist/gate/bind.d.ts +28 -0
- package/dist/gate/bind.d.ts.map +1 -0
- package/dist/gate/bind.js +154 -0
- package/dist/gate/bind.js.map +1 -0
- package/dist/gate/gate.d.ts +139 -0
- package/dist/gate/gate.d.ts.map +1 -0
- package/dist/gate/gate.js +488 -0
- package/dist/gate/gate.js.map +1 -0
- package/dist/gate/hooks-file.d.ts +55 -0
- package/dist/gate/hooks-file.d.ts.map +1 -0
- package/dist/gate/hooks-file.js +104 -0
- package/dist/gate/hooks-file.js.map +1 -0
- package/dist/gate.d.ts +3 -0
- package/dist/gate.d.ts.map +1 -0
- package/dist/gate.js +20 -0
- package/dist/gate.js.map +1 -0
- package/dist/policy/ceiling-review.d.ts +22 -0
- package/dist/policy/ceiling-review.d.ts.map +1 -0
- package/dist/policy/ceiling-review.js +170 -0
- package/dist/policy/ceiling-review.js.map +1 -0
- package/dist/policy/ceiling.d.ts +128 -0
- package/dist/policy/ceiling.d.ts.map +1 -0
- package/dist/policy/ceiling.js +273 -0
- package/dist/policy/ceiling.js.map +1 -0
- package/dist/policy/containment.d.ts +100 -0
- package/dist/policy/containment.d.ts.map +1 -0
- package/dist/policy/containment.js +1071 -0
- package/dist/policy/containment.js.map +1 -0
- package/dist/policy/hard-deny.d.ts +28 -0
- package/dist/policy/hard-deny.d.ts.map +1 -0
- package/dist/policy/hard-deny.js +78 -0
- package/dist/policy/hard-deny.js.map +1 -0
- package/dist/policy/profiles.d.ts +82 -0
- package/dist/policy/profiles.d.ts.map +1 -0
- package/dist/policy/profiles.js +317 -0
- package/dist/policy/profiles.js.map +1 -0
- package/dist/policy/rules.d.ts +138 -0
- package/dist/policy/rules.d.ts.map +1 -0
- package/dist/policy/rules.js +1180 -0
- package/dist/policy/rules.js.map +1 -0
- package/dist/policy/seatbelt.d.ts +32 -0
- package/dist/policy/seatbelt.d.ts.map +1 -0
- package/dist/policy/seatbelt.js +59 -0
- package/dist/policy/seatbelt.js.map +1 -0
- package/dist/policy/tools.d.ts +36 -0
- package/dist/policy/tools.d.ts.map +1 -0
- package/dist/policy/tools.js +94 -0
- package/dist/policy/tools.js.map +1 -0
- package/dist/runner/gate-watchdog.d.ts +93 -0
- package/dist/runner/gate-watchdog.d.ts.map +1 -0
- package/dist/runner/gate-watchdog.js +153 -0
- package/dist/runner/gate-watchdog.js.map +1 -0
- package/dist/runner/idle.d.ts +51 -0
- package/dist/runner/idle.d.ts.map +1 -0
- package/dist/runner/idle.js +81 -0
- package/dist/runner/idle.js.map +1 -0
- package/dist/runner/inbox.d.ts +56 -0
- package/dist/runner/inbox.d.ts.map +1 -0
- package/dist/runner/inbox.js +134 -0
- package/dist/runner/inbox.js.map +1 -0
- package/dist/runner/reap.d.ts +65 -0
- package/dist/runner/reap.d.ts.map +1 -0
- package/dist/runner/reap.js +168 -0
- package/dist/runner/reap.js.map +1 -0
- package/dist/runner/runner.d.ts +51 -0
- package/dist/runner/runner.d.ts.map +1 -0
- package/dist/runner/runner.js +289 -0
- package/dist/runner/runner.js.map +1 -0
- package/dist/runner/spawn.d.ts +98 -0
- package/dist/runner/spawn.d.ts.map +1 -0
- package/dist/runner/spawn.js +230 -0
- package/dist/runner/spawn.js.map +1 -0
- package/dist/runner/verify.d.ts +24 -0
- package/dist/runner/verify.d.ts.map +1 -0
- package/dist/runner/verify.js +108 -0
- package/dist/runner/verify.js.map +1 -0
- package/dist/runner.d.ts +3 -0
- package/dist/runner.d.ts.map +1 -0
- package/dist/runner.js +15 -0
- package/dist/runner.js.map +1 -0
- package/dist/server/context.d.ts +41 -0
- package/dist/server/context.d.ts.map +1 -0
- package/dist/server/context.js +59 -0
- package/dist/server/context.js.map +1 -0
- package/dist/server/instructions.d.ts +13 -0
- package/dist/server/instructions.d.ts.map +1 -0
- package/dist/server/instructions.js +121 -0
- package/dist/server/instructions.js.map +1 -0
- package/dist/server/server.d.ts +20 -0
- package/dist/server/server.d.ts.map +1 -0
- package/dist/server/server.js +55 -0
- package/dist/server/server.js.map +1 -0
- package/dist/server/tools/cancel.d.ts +24 -0
- package/dist/server/tools/cancel.d.ts.map +1 -0
- package/dist/server/tools/cancel.js +59 -0
- package/dist/server/tools/cancel.js.map +1 -0
- package/dist/server/tools/capabilities.d.ts +36 -0
- package/dist/server/tools/capabilities.d.ts.map +1 -0
- package/dist/server/tools/capabilities.js +116 -0
- package/dist/server/tools/capabilities.js.map +1 -0
- package/dist/server/tools/ceiling.d.ts +31 -0
- package/dist/server/tools/ceiling.d.ts.map +1 -0
- package/dist/server/tools/ceiling.js +121 -0
- package/dist/server/tools/ceiling.js.map +1 -0
- package/dist/server/tools/index.d.ts +38 -0
- package/dist/server/tools/index.d.ts.map +1 -0
- package/dist/server/tools/index.js +115 -0
- package/dist/server/tools/index.js.map +1 -0
- package/dist/server/tools/listJobs.d.ts +30 -0
- package/dist/server/tools/listJobs.d.ts.map +1 -0
- package/dist/server/tools/listJobs.js +37 -0
- package/dist/server/tools/listJobs.js.map +1 -0
- package/dist/server/tools/logs.d.ts +31 -0
- package/dist/server/tools/logs.d.ts.map +1 -0
- package/dist/server/tools/logs.js +96 -0
- package/dist/server/tools/logs.js.map +1 -0
- package/dist/server/tools/result.d.ts +32 -0
- package/dist/server/tools/result.d.ts.map +1 -0
- package/dist/server/tools/result.js +95 -0
- package/dist/server/tools/result.js.map +1 -0
- package/dist/server/tools/send.d.ts +37 -0
- package/dist/server/tools/send.d.ts.map +1 -0
- package/dist/server/tools/send.js +71 -0
- package/dist/server/tools/send.js.map +1 -0
- package/dist/server/tools/sessions.d.ts +28 -0
- package/dist/server/tools/sessions.d.ts.map +1 -0
- package/dist/server/tools/sessions.js +54 -0
- package/dist/server/tools/sessions.js.map +1 -0
- package/dist/server/tools/start.d.ts +107 -0
- package/dist/server/tools/start.d.ts.map +1 -0
- package/dist/server/tools/start.js +482 -0
- package/dist/server/tools/start.js.map +1 -0
- package/dist/server/tools/wait.d.ts +29 -0
- package/dist/server/tools/wait.d.ts.map +1 -0
- package/dist/server/tools/wait.js +120 -0
- package/dist/server/tools/wait.js.map +1 -0
- package/dist/server.d.ts +3 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +17 -0
- package/dist/server.js.map +1 -0
- package/dist/setup/install.d.ts +52 -0
- package/dist/setup/install.d.ts.map +1 -0
- package/dist/setup/install.js +108 -0
- package/dist/setup/install.js.map +1 -0
- package/dist/setup.d.ts +3 -0
- package/dist/setup.d.ts.map +1 -0
- package/dist/setup.js +24 -0
- package/dist/setup.js.map +1 -0
- package/dist/store/db.d.ts +49 -0
- package/dist/store/db.d.ts.map +1 -0
- package/dist/store/db.js +101 -0
- package/dist/store/db.js.map +1 -0
- package/dist/store/jobs.d.ts +45 -0
- package/dist/store/jobs.d.ts.map +1 -0
- package/dist/store/jobs.js +150 -0
- package/dist/store/jobs.js.map +1 -0
- package/dist/store/locks.d.ts +60 -0
- package/dist/store/locks.d.ts.map +1 -0
- package/dist/store/locks.js +172 -0
- package/dist/store/locks.js.map +1 -0
- package/dist/store/sessions.d.ts +37 -0
- package/dist/store/sessions.d.ts.map +1 -0
- package/dist/store/sessions.js +117 -0
- package/dist/store/sessions.js.map +1 -0
- package/dist/trace/digest.d.ts +77 -0
- package/dist/trace/digest.d.ts.map +1 -0
- package/dist/trace/digest.js +481 -0
- package/dist/trace/digest.js.map +1 -0
- package/package.json +68 -0
- package/skills/agy-ceiling/SKILL.md +72 -0
|
@@ -0,0 +1,481 @@
|
|
|
1
|
+
import { existsSync, readFileSync } from 'node:fs';
|
|
2
|
+
import { basename, join } from 'node:path';
|
|
3
|
+
import { GATE_DENIAL_MARKER } from '../contract/types.js';
|
|
4
|
+
import { extractRequiredRule } from '../events/detect.js';
|
|
5
|
+
/** Collapse runs of whitespace into a single space and trim. */
|
|
6
|
+
function collapseWhitespace(text) {
|
|
7
|
+
return text.replace(/\s+/g, ' ').trim();
|
|
8
|
+
}
|
|
9
|
+
/** Strip workspace prefix from a file path when contained under workspace. */
|
|
10
|
+
function toRelativePath(filePath, workspace) {
|
|
11
|
+
if (!workspace)
|
|
12
|
+
return filePath;
|
|
13
|
+
const normalizedWs = workspace.replace(/\/+$/, '');
|
|
14
|
+
const normalizedPath = filePath.replace(/\/+$/, '');
|
|
15
|
+
if (normalizedPath === normalizedWs)
|
|
16
|
+
return '.';
|
|
17
|
+
const prefix = normalizedWs + '/';
|
|
18
|
+
if (filePath.startsWith(prefix)) {
|
|
19
|
+
return filePath.slice(prefix.length);
|
|
20
|
+
}
|
|
21
|
+
return filePath;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Extract target path from a tool's parameters.
|
|
25
|
+
* Matches the file tools recognized across agy execution.
|
|
26
|
+
*/
|
|
27
|
+
function extractPathFromTool(tool, params) {
|
|
28
|
+
if (tool === 'view_file') {
|
|
29
|
+
return typeof params.AbsolutePath === 'string' && params.AbsolutePath.length > 0 ? params.AbsolutePath : null;
|
|
30
|
+
}
|
|
31
|
+
if (tool === 'grep_search') {
|
|
32
|
+
return typeof params.SearchPath === 'string' && params.SearchPath.length > 0 ? params.SearchPath : null;
|
|
33
|
+
}
|
|
34
|
+
if (tool === 'find_by_name') {
|
|
35
|
+
return typeof params.SearchDirectory === 'string' && params.SearchDirectory.length > 0 ? params.SearchDirectory : null;
|
|
36
|
+
}
|
|
37
|
+
if (tool === 'list_dir') {
|
|
38
|
+
return typeof params.DirectoryPath === 'string' && params.DirectoryPath.length > 0 ? params.DirectoryPath : null;
|
|
39
|
+
}
|
|
40
|
+
if (tool === 'write_to_file' || tool === 'replace_file_content') {
|
|
41
|
+
return typeof params.TargetFile === 'string' && params.TargetFile.length > 0 ? params.TargetFile : null;
|
|
42
|
+
}
|
|
43
|
+
return null;
|
|
44
|
+
}
|
|
45
|
+
const READ_TOOLS = new Set(['view_file', 'grep_search', 'find_by_name', 'list_dir']);
|
|
46
|
+
const EDIT_TOOLS = new Set(['write_to_file', 'replace_file_content']);
|
|
47
|
+
/**
|
|
48
|
+
* Pure digest computation over in-memory string captures.
|
|
49
|
+
*/
|
|
50
|
+
export function digestJob(input) {
|
|
51
|
+
const hasGateLog = typeof input.gateLog === 'string' && input.gateLog.trim().length > 0;
|
|
52
|
+
const hasEvents = typeof input.events === 'string' && input.events.trim().length > 0;
|
|
53
|
+
let trace;
|
|
54
|
+
if (!hasGateLog && !hasEvents) {
|
|
55
|
+
trace = 'empty';
|
|
56
|
+
}
|
|
57
|
+
else if (!hasGateLog) {
|
|
58
|
+
trace = 'no_gate_log';
|
|
59
|
+
}
|
|
60
|
+
else {
|
|
61
|
+
trace = 'full';
|
|
62
|
+
}
|
|
63
|
+
let outcome = null;
|
|
64
|
+
let exit_code = null;
|
|
65
|
+
let duration_ms = null;
|
|
66
|
+
let turns = null;
|
|
67
|
+
if (input.brokerResult && typeof input.brokerResult === 'object') {
|
|
68
|
+
const br = input.brokerResult;
|
|
69
|
+
if (br.broker_summary && typeof br.broker_summary === 'object') {
|
|
70
|
+
const bs = br.broker_summary;
|
|
71
|
+
outcome = typeof bs.outcome === 'string' ? bs.outcome : null;
|
|
72
|
+
exit_code = typeof bs.exit_code === 'number' ? bs.exit_code : null;
|
|
73
|
+
duration_ms = typeof bs.duration_ms === 'number' ? bs.duration_ms : null;
|
|
74
|
+
if (bs.counts && typeof bs.counts === 'object') {
|
|
75
|
+
const counts = bs.counts;
|
|
76
|
+
turns = typeof counts.turns === 'number' ? counts.turns : null;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
const gateEntries = [];
|
|
81
|
+
const gateByStep = new Map();
|
|
82
|
+
if (hasGateLog && input.gateLog) {
|
|
83
|
+
const lines = input.gateLog.trim().split('\n');
|
|
84
|
+
for (const line of lines) {
|
|
85
|
+
if (!line.trim())
|
|
86
|
+
continue;
|
|
87
|
+
try {
|
|
88
|
+
const parsed = JSON.parse(line);
|
|
89
|
+
gateEntries.push(parsed);
|
|
90
|
+
if (typeof parsed.step_idx === 'number') {
|
|
91
|
+
gateByStep.set(parsed.step_idx, parsed);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
catch {
|
|
95
|
+
// Skip malformed gate log lines
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
// 1. Commands
|
|
100
|
+
const cmdMap = new Map();
|
|
101
|
+
if (hasGateLog) {
|
|
102
|
+
for (const entry of gateEntries) {
|
|
103
|
+
if (entry.tool === 'run_command' && typeof entry.command === 'string') {
|
|
104
|
+
const cmd = collapseWhitespace(entry.command);
|
|
105
|
+
if (cmd.length === 0)
|
|
106
|
+
continue;
|
|
107
|
+
let item = cmdMap.get(cmd);
|
|
108
|
+
if (!item) {
|
|
109
|
+
item = { command: cmd, count: 0, denied: 0 };
|
|
110
|
+
cmdMap.set(cmd, item);
|
|
111
|
+
}
|
|
112
|
+
item.count++;
|
|
113
|
+
if (entry.decision === 'deny') {
|
|
114
|
+
item.denied++;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
else if (hasEvents && input.events) {
|
|
120
|
+
// Fallback when gate log is absent: scan events for run_command invocations
|
|
121
|
+
const seenCommandStepIndices = new Set();
|
|
122
|
+
const lines = input.events.trim().split('\n');
|
|
123
|
+
for (const line of lines) {
|
|
124
|
+
if (!line.trim())
|
|
125
|
+
continue;
|
|
126
|
+
try {
|
|
127
|
+
const ev = JSON.parse(line);
|
|
128
|
+
if (ev.event !== 'step_update' || !ev.step_update || typeof ev.step_update !== 'object')
|
|
129
|
+
continue;
|
|
130
|
+
const su = ev.step_update;
|
|
131
|
+
if (su.step_type !== 'tool')
|
|
132
|
+
continue;
|
|
133
|
+
const tool = typeof su.tool_name === 'string' ? su.tool_name : undefined;
|
|
134
|
+
if (tool !== 'run_command')
|
|
135
|
+
continue;
|
|
136
|
+
const stepIdx = typeof su.step_index === 'number' ? su.step_index : null;
|
|
137
|
+
if (stepIdx !== null) {
|
|
138
|
+
if (seenCommandStepIndices.has(stepIdx))
|
|
139
|
+
continue;
|
|
140
|
+
seenCommandStepIndices.add(stepIdx);
|
|
141
|
+
}
|
|
142
|
+
const toolInfo = su.tool_info;
|
|
143
|
+
const params = toolInfo?.parameters;
|
|
144
|
+
const rawCmd = params?.CommandLine;
|
|
145
|
+
if (typeof rawCmd === 'string') {
|
|
146
|
+
const cmd = collapseWhitespace(rawCmd);
|
|
147
|
+
if (cmd.length > 0) {
|
|
148
|
+
let item = cmdMap.get(cmd);
|
|
149
|
+
if (!item) {
|
|
150
|
+
item = { command: cmd, count: 0, denied: 0 };
|
|
151
|
+
cmdMap.set(cmd, item);
|
|
152
|
+
}
|
|
153
|
+
item.count++;
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
catch {
|
|
158
|
+
// Skip malformed event lines
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
const commands = Array.from(cmdMap.values()).sort((a, b) => b.count - a.count || a.command.localeCompare(b.command));
|
|
163
|
+
// 2. Denials
|
|
164
|
+
const denialMap = new Map();
|
|
165
|
+
if (hasGateLog) {
|
|
166
|
+
for (const entry of gateEntries) {
|
|
167
|
+
if (entry.decision === 'deny') {
|
|
168
|
+
const tool = entry.tool ?? 'unknown';
|
|
169
|
+
const command = typeof entry.command === 'string' ? collapseWhitespace(entry.command) : null;
|
|
170
|
+
const stage = entry.policy ?? 'unknown';
|
|
171
|
+
const required_rule = extractRequiredRule(entry.reason ?? '');
|
|
172
|
+
const key = `${tool}::${command ?? ''}::${stage}::${required_rule ?? ''}`;
|
|
173
|
+
let item = denialMap.get(key);
|
|
174
|
+
if (!item) {
|
|
175
|
+
item = { tool, command, stage, required_rule, count: 0 };
|
|
176
|
+
denialMap.set(key, item);
|
|
177
|
+
}
|
|
178
|
+
item.count++;
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
const denials = Array.from(denialMap.values()).sort((a, b) => b.count - a.count || a.tool.localeCompare(b.tool) || (a.command ?? '').localeCompare(b.command ?? ''));
|
|
183
|
+
// 3. Files and Tool Errors
|
|
184
|
+
const readSet = new Set();
|
|
185
|
+
const editedSet = new Set();
|
|
186
|
+
const toolErrors = [];
|
|
187
|
+
const seenFileStepIndices = new Set();
|
|
188
|
+
if (hasEvents && input.events) {
|
|
189
|
+
const lines = input.events.trim().split('\n');
|
|
190
|
+
for (const line of lines) {
|
|
191
|
+
if (!line.trim())
|
|
192
|
+
continue;
|
|
193
|
+
try {
|
|
194
|
+
const ev = JSON.parse(line);
|
|
195
|
+
if (ev.event !== 'step_update' || !ev.step_update || typeof ev.step_update !== 'object')
|
|
196
|
+
continue;
|
|
197
|
+
const su = ev.step_update;
|
|
198
|
+
if (su.step_type !== 'tool')
|
|
199
|
+
continue;
|
|
200
|
+
const stepIdx = typeof su.step_index === 'number' ? su.step_index : null;
|
|
201
|
+
const toolInfo = su.tool_info;
|
|
202
|
+
const tool = typeof su.tool_name === 'string'
|
|
203
|
+
? su.tool_name
|
|
204
|
+
: typeof toolInfo?.name === 'string'
|
|
205
|
+
? toolInfo.name
|
|
206
|
+
: 'unknown';
|
|
207
|
+
// Tool errors: state === 'ERROR' that are NOT gate denials
|
|
208
|
+
if (su.state === 'ERROR') {
|
|
209
|
+
const errorInfo = toolInfo?.error;
|
|
210
|
+
const msg = typeof errorInfo?.message === 'string' ? errorInfo.message : '';
|
|
211
|
+
if (!msg.includes(GATE_DENIAL_MARKER)) {
|
|
212
|
+
if (stepIdx === null || !toolErrors.some((e) => e.step_idx === stepIdx)) {
|
|
213
|
+
toolErrors.push({
|
|
214
|
+
step_idx: stepIdx,
|
|
215
|
+
tool,
|
|
216
|
+
message: msg,
|
|
217
|
+
});
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
// Dedupe step updates for file accounting
|
|
222
|
+
if (stepIdx !== null) {
|
|
223
|
+
if (seenFileStepIndices.has(stepIdx))
|
|
224
|
+
continue;
|
|
225
|
+
seenFileStepIndices.add(stepIdx);
|
|
226
|
+
}
|
|
227
|
+
// Join to gate log: only count if decision was allow (or no gate row)
|
|
228
|
+
const gateRow = stepIdx !== null ? gateByStep.get(stepIdx) : undefined;
|
|
229
|
+
if (gateRow && gateRow.decision !== 'allow') {
|
|
230
|
+
continue;
|
|
231
|
+
}
|
|
232
|
+
const params = toolInfo?.parameters ?? {};
|
|
233
|
+
const targetPath = extractPathFromTool(tool, params);
|
|
234
|
+
if (targetPath) {
|
|
235
|
+
const rel = toRelativePath(targetPath, input.workspace);
|
|
236
|
+
if (EDIT_TOOLS.has(tool)) {
|
|
237
|
+
editedSet.add(rel);
|
|
238
|
+
}
|
|
239
|
+
else if (READ_TOOLS.has(tool)) {
|
|
240
|
+
readSet.add(rel);
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
catch {
|
|
245
|
+
// Skip malformed event lines
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
const read = Array.from(readSet).sort();
|
|
250
|
+
const edited = Array.from(editedSet).sort();
|
|
251
|
+
return {
|
|
252
|
+
job_id: input.job_id,
|
|
253
|
+
outcome,
|
|
254
|
+
exit_code,
|
|
255
|
+
duration_ms,
|
|
256
|
+
turns,
|
|
257
|
+
commands,
|
|
258
|
+
files: {
|
|
259
|
+
read,
|
|
260
|
+
edited,
|
|
261
|
+
read_count: read.length,
|
|
262
|
+
edited_count: edited.length,
|
|
263
|
+
},
|
|
264
|
+
denials,
|
|
265
|
+
tool_errors: toolErrors,
|
|
266
|
+
trace,
|
|
267
|
+
};
|
|
268
|
+
}
|
|
269
|
+
/**
|
|
270
|
+
* Cross-job roll-up across multiple job digests and their gate logs.
|
|
271
|
+
*/
|
|
272
|
+
export function digestProject(digests, gateLogsById) {
|
|
273
|
+
const outcomes = {};
|
|
274
|
+
for (const d of digests) {
|
|
275
|
+
if (d.outcome !== null) {
|
|
276
|
+
outcomes[d.outcome] = (outcomes[d.outcome] ?? 0) + 1;
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
// Aggregate denied rules with last seen job_id and timestamp
|
|
280
|
+
const ruleMap = new Map();
|
|
281
|
+
for (const [jobId, gateLog] of Object.entries(gateLogsById)) {
|
|
282
|
+
if (!gateLog)
|
|
283
|
+
continue;
|
|
284
|
+
const lines = gateLog.trim().split('\n');
|
|
285
|
+
for (const line of lines) {
|
|
286
|
+
if (!line.trim())
|
|
287
|
+
continue;
|
|
288
|
+
try {
|
|
289
|
+
const entry = JSON.parse(line);
|
|
290
|
+
if (entry.decision !== 'deny')
|
|
291
|
+
continue;
|
|
292
|
+
const reason = typeof entry.reason === 'string' ? entry.reason : '';
|
|
293
|
+
const requiredRule = extractRequiredRule(reason);
|
|
294
|
+
if (!requiredRule)
|
|
295
|
+
continue;
|
|
296
|
+
const entryJobId = typeof entry.job_id === 'string' ? entry.job_id : jobId;
|
|
297
|
+
const entryTs = typeof entry.ts === 'number' ? entry.ts : 0;
|
|
298
|
+
const existing = ruleMap.get(requiredRule);
|
|
299
|
+
if (!existing) {
|
|
300
|
+
ruleMap.set(requiredRule, {
|
|
301
|
+
required_rule: requiredRule,
|
|
302
|
+
count: 1,
|
|
303
|
+
last_job_id: entryJobId,
|
|
304
|
+
last_ts: entryTs,
|
|
305
|
+
});
|
|
306
|
+
}
|
|
307
|
+
else {
|
|
308
|
+
existing.count++;
|
|
309
|
+
if (entryTs >= existing.last_ts) {
|
|
310
|
+
existing.last_ts = entryTs;
|
|
311
|
+
existing.last_job_id = entryJobId;
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
catch {
|
|
316
|
+
// Skip malformed lines
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
const denied_rules = Array.from(ruleMap.values()).sort((a, b) => b.count - a.count || b.last_ts - a.last_ts || a.required_rule.localeCompare(b.required_rule));
|
|
321
|
+
// Top commands across jobs
|
|
322
|
+
const commandMap = new Map();
|
|
323
|
+
for (const d of digests) {
|
|
324
|
+
for (const cmd of d.commands) {
|
|
325
|
+
const existing = commandMap.get(cmd.command);
|
|
326
|
+
if (!existing) {
|
|
327
|
+
commandMap.set(cmd.command, { ...cmd });
|
|
328
|
+
}
|
|
329
|
+
else {
|
|
330
|
+
existing.count += cmd.count;
|
|
331
|
+
existing.denied += cmd.denied;
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
const top_commands = Array.from(commandMap.values())
|
|
336
|
+
.sort((a, b) => b.count - a.count || a.command.localeCompare(b.command))
|
|
337
|
+
.slice(0, 20);
|
|
338
|
+
return {
|
|
339
|
+
jobs: digests.length,
|
|
340
|
+
outcomes,
|
|
341
|
+
denied_rules,
|
|
342
|
+
top_commands,
|
|
343
|
+
};
|
|
344
|
+
}
|
|
345
|
+
/**
|
|
346
|
+
* Load a job's files from its job directory and compute its digest.
|
|
347
|
+
*/
|
|
348
|
+
export function loadJobDigest(jobDir, workspace) {
|
|
349
|
+
const gateLogPath = join(jobDir, 'gate-log.jsonl');
|
|
350
|
+
const eventsPath = join(jobDir, 'events.ndjson');
|
|
351
|
+
const brokerResultPath = join(jobDir, 'broker-result.json');
|
|
352
|
+
const gateLog = existsSync(gateLogPath) ? readFileSync(gateLogPath, 'utf8') : null;
|
|
353
|
+
const events = existsSync(eventsPath) ? readFileSync(eventsPath, 'utf8') : null;
|
|
354
|
+
let brokerResult = null;
|
|
355
|
+
if (existsSync(brokerResultPath)) {
|
|
356
|
+
try {
|
|
357
|
+
brokerResult = JSON.parse(readFileSync(brokerResultPath, 'utf8'));
|
|
358
|
+
}
|
|
359
|
+
catch {
|
|
360
|
+
brokerResult = null;
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
let resolvedWorkspace = workspace;
|
|
364
|
+
if (!resolvedWorkspace) {
|
|
365
|
+
if (brokerResult &&
|
|
366
|
+
typeof brokerResult === 'object' &&
|
|
367
|
+
'cwd' in brokerResult &&
|
|
368
|
+
typeof brokerResult.cwd === 'string') {
|
|
369
|
+
resolvedWorkspace = brokerResult.cwd;
|
|
370
|
+
}
|
|
371
|
+
else {
|
|
372
|
+
const requestPath = join(jobDir, 'request.json');
|
|
373
|
+
if (existsSync(requestPath)) {
|
|
374
|
+
try {
|
|
375
|
+
const req = JSON.parse(readFileSync(requestPath, 'utf8'));
|
|
376
|
+
if (typeof req.cwd === 'string') {
|
|
377
|
+
resolvedWorkspace = req.cwd;
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
catch {
|
|
381
|
+
// Ignore
|
|
382
|
+
}
|
|
383
|
+
}
|
|
384
|
+
}
|
|
385
|
+
}
|
|
386
|
+
const jobId = brokerResult &&
|
|
387
|
+
typeof brokerResult === 'object' &&
|
|
388
|
+
'job_id' in brokerResult &&
|
|
389
|
+
typeof brokerResult.job_id === 'string'
|
|
390
|
+
? brokerResult.job_id
|
|
391
|
+
: basename(jobDir);
|
|
392
|
+
return digestJob({
|
|
393
|
+
job_id: jobId,
|
|
394
|
+
workspace: resolvedWorkspace,
|
|
395
|
+
gateLog,
|
|
396
|
+
events,
|
|
397
|
+
brokerResult,
|
|
398
|
+
});
|
|
399
|
+
}
|
|
400
|
+
/** Format milliseconds into a readable duration (s or min). */
|
|
401
|
+
function formatDuration(ms) {
|
|
402
|
+
if (ms === null || ms < 0)
|
|
403
|
+
return '?min';
|
|
404
|
+
if (ms < 60_000)
|
|
405
|
+
return `${(ms / 1000).toFixed(1)}s`;
|
|
406
|
+
return `${(ms / 60_000).toFixed(1)}min`;
|
|
407
|
+
}
|
|
408
|
+
/** Truncate a single line to max characters, appending an ellipsis if truncated. */
|
|
409
|
+
function truncateLine(line, max = 200) {
|
|
410
|
+
if (line.length <= max)
|
|
411
|
+
return line;
|
|
412
|
+
return line.slice(0, max - 1) + '…';
|
|
413
|
+
}
|
|
414
|
+
/** Format file list showing at most 8 items, collapsing the rest into `… +N more`. */
|
|
415
|
+
function formatFileList(paths) {
|
|
416
|
+
if (paths.length === 0)
|
|
417
|
+
return 'none';
|
|
418
|
+
const MAX_SHOWN = 8;
|
|
419
|
+
if (paths.length <= MAX_SHOWN) {
|
|
420
|
+
return paths.join(', ');
|
|
421
|
+
}
|
|
422
|
+
const shown = paths.slice(0, MAX_SHOWN).join(', ');
|
|
423
|
+
const remaining = paths.length - MAX_SHOWN;
|
|
424
|
+
return `${shown}, … +${remaining} more`;
|
|
425
|
+
}
|
|
426
|
+
/**
|
|
427
|
+
* Render a JobDigest into human-readable text layout under ~40 lines.
|
|
428
|
+
*/
|
|
429
|
+
export function renderDigest(d) {
|
|
430
|
+
const lines = [];
|
|
431
|
+
// Header line: job <id> · <outcome> · exit <code|?> · <duration> · <N> turn(s)
|
|
432
|
+
const outcomeStr = d.outcome ?? 'unknown';
|
|
433
|
+
const exitStr = d.exit_code !== null ? `exit ${d.exit_code}` : 'exit ?';
|
|
434
|
+
const durStr = formatDuration(d.duration_ms);
|
|
435
|
+
const turnsCount = d.turns ?? 0;
|
|
436
|
+
const turnsStr = `${turnsCount} turn${turnsCount === 1 ? '' : 's'}`;
|
|
437
|
+
lines.push(`job ${d.job_id} · ${outcomeStr} · ${exitStr} · ${durStr} · ${turnsStr}`);
|
|
438
|
+
// Commands section
|
|
439
|
+
const totalAllowed = d.commands.reduce((sum, c) => sum + (c.count - c.denied), 0);
|
|
440
|
+
const totalDenied = d.commands.reduce((sum, c) => sum + c.denied, 0);
|
|
441
|
+
lines.push(`commands (${totalAllowed} allowed, ${totalDenied} denied)`);
|
|
442
|
+
const MAX_COMMANDS = 15;
|
|
443
|
+
const shownCommands = d.commands.slice(0, MAX_COMMANDS);
|
|
444
|
+
for (const c of shownCommands) {
|
|
445
|
+
const deniedStr = c.denied > 0 ? ` (${c.denied} denied)` : '';
|
|
446
|
+
lines.push(` ×${c.count} ${c.command}${deniedStr}`);
|
|
447
|
+
}
|
|
448
|
+
if (d.commands.length > MAX_COMMANDS) {
|
|
449
|
+
lines.push(` … +${d.commands.length - MAX_COMMANDS} more`);
|
|
450
|
+
}
|
|
451
|
+
// Files section
|
|
452
|
+
lines.push('files');
|
|
453
|
+
lines.push(` read ${d.files.read_count}: ${formatFileList(d.files.read)}`);
|
|
454
|
+
lines.push(` edited ${d.files.edited_count}: ${formatFileList(d.files.edited)}`);
|
|
455
|
+
// Denials section
|
|
456
|
+
if (d.denials.length === 0) {
|
|
457
|
+
lines.push('denials 0');
|
|
458
|
+
}
|
|
459
|
+
else {
|
|
460
|
+
const totalDenials = d.denials.reduce((sum, den) => sum + den.count, 0);
|
|
461
|
+
lines.push(`denials ${totalDenials}`);
|
|
462
|
+
for (const den of d.denials) {
|
|
463
|
+
const cmdStr = den.command ? `: ${den.command}` : '';
|
|
464
|
+
const ruleStr = den.required_rule ? ` [${den.required_rule}]` : '';
|
|
465
|
+
lines.push(` ×${den.count} ${den.tool}${cmdStr}${ruleStr} (${den.stage})`);
|
|
466
|
+
}
|
|
467
|
+
}
|
|
468
|
+
// Tool errors section
|
|
469
|
+
if (d.tool_errors.length === 0) {
|
|
470
|
+
lines.push('tool_errors 0');
|
|
471
|
+
}
|
|
472
|
+
else {
|
|
473
|
+
lines.push(`tool_errors ${d.tool_errors.length}`);
|
|
474
|
+
for (const err of d.tool_errors) {
|
|
475
|
+
const stepStr = err.step_idx !== null ? `#${err.step_idx} ` : '';
|
|
476
|
+
lines.push(` ${stepStr}${err.tool}: ${err.message}`);
|
|
477
|
+
}
|
|
478
|
+
}
|
|
479
|
+
return lines.map((l) => truncateLine(l, 200)).join('\n');
|
|
480
|
+
}
|
|
481
|
+
//# sourceMappingURL=digest.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"digest.js","sourceRoot":"","sources":["../../src/trace/digest.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "agy-worker-mcp",
|
|
3
|
+
"version": "0.3.1",
|
|
4
|
+
"description": "Unofficial MCP server that drives Google's Antigravity CLI (agy) as an asynchronous worker agent",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"author": "Siwoo Ryu",
|
|
8
|
+
"homepage": "https://github.com/thezoot3/agy-worker-mcp#readme",
|
|
9
|
+
"repository": {
|
|
10
|
+
"type": "git",
|
|
11
|
+
"url": "git+https://github.com/thezoot3/agy-worker-mcp.git"
|
|
12
|
+
},
|
|
13
|
+
"bugs": {
|
|
14
|
+
"url": "https://github.com/thezoot3/agy-worker-mcp/issues"
|
|
15
|
+
},
|
|
16
|
+
"keywords": [
|
|
17
|
+
"mcp",
|
|
18
|
+
"model-context-protocol",
|
|
19
|
+
"antigravity",
|
|
20
|
+
"agy",
|
|
21
|
+
"agent",
|
|
22
|
+
"worker",
|
|
23
|
+
"claude-code",
|
|
24
|
+
"codex"
|
|
25
|
+
],
|
|
26
|
+
"engines": {
|
|
27
|
+
"node": ">=22.5.0"
|
|
28
|
+
},
|
|
29
|
+
"bin": {
|
|
30
|
+
"agy-worker-mcp": "dist/server.js",
|
|
31
|
+
"agy-worker-runner": "dist/runner.js",
|
|
32
|
+
"agy-worker-gate": "dist/gate.js",
|
|
33
|
+
"agy-worker-setup": "dist/setup.js"
|
|
34
|
+
},
|
|
35
|
+
"main": "dist/server.js",
|
|
36
|
+
"exports": {
|
|
37
|
+
".": "./dist/server.js",
|
|
38
|
+
"./contract": "./dist/contract/index.js"
|
|
39
|
+
},
|
|
40
|
+
"files": [
|
|
41
|
+
"dist",
|
|
42
|
+
"skills",
|
|
43
|
+
"commands",
|
|
44
|
+
"README.md",
|
|
45
|
+
"CHANGELOG.md"
|
|
46
|
+
],
|
|
47
|
+
"publishConfig": {
|
|
48
|
+
"access": "public"
|
|
49
|
+
},
|
|
50
|
+
"scripts": {
|
|
51
|
+
"build": "tsc -p tsconfig.build.json && node -e \"require('node:fs').copyFileSync('src/contract/schema.sql','dist/contract/schema.sql')\"",
|
|
52
|
+
"prepare": "npm run build",
|
|
53
|
+
"prepublishOnly": "npm run typecheck && npm test",
|
|
54
|
+
"typecheck": "tsc --noEmit",
|
|
55
|
+
"test": "vitest run",
|
|
56
|
+
"test:watch": "vitest",
|
|
57
|
+
"test:live": "AGY_LIVE=1 vitest run --config vitest.live.config.ts"
|
|
58
|
+
},
|
|
59
|
+
"dependencies": {
|
|
60
|
+
"@modelcontextprotocol/sdk": "^1.12.1",
|
|
61
|
+
"zod": "^3.25.0"
|
|
62
|
+
},
|
|
63
|
+
"devDependencies": {
|
|
64
|
+
"@types/node": "^22.15.0",
|
|
65
|
+
"typescript": "^5.8.3",
|
|
66
|
+
"vitest": "^3.1.4"
|
|
67
|
+
}
|
|
68
|
+
}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: agy-ceiling
|
|
3
|
+
description: Propose a project permission ceiling (policy.json) for agy-worker-mcp jobs from denial history and the repo, and never write it without the user's explicit, in-conversation approval.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# agy-ceiling
|
|
7
|
+
|
|
8
|
+
Use this when an `agy_result` blocker says the remedy is the project ceiling
|
|
9
|
+
(`~/.agy-worker/projects/<hash>/policy.json`), when `agy_start({ dry_run: true,
|
|
10
|
+
expected_commands })` reports a command the policy would deny, or when the user
|
|
11
|
+
asks what a project's ceiling should look like.
|
|
12
|
+
|
|
13
|
+
## What the ceiling is
|
|
14
|
+
|
|
15
|
+
Four layers say "no" to a job, and each has exactly one key that opens it
|
|
16
|
+
(`docs/permissions.md`):
|
|
17
|
+
|
|
18
|
+
| Layer | Opened by |
|
|
19
|
+
| --- | --- |
|
|
20
|
+
| `HARD_DENY` (`.agents/**` writes, credential reads, subagent tools) | Nothing. Do not propose it. |
|
|
21
|
+
| Profile deny (`git push`, `curl`, `wget`, `ssh`, `scp`, `sudo`, `docker`, `rm -rf`, `git reset --hard`, `npm install`, …) | `exceptions` — exact rule string |
|
|
22
|
+
| Not on the allow list (`cargo build`, `make`, `go test`, …) | `allow`, or `command_policy: "denylist"` |
|
|
23
|
+
| Reads outside the workspace | `read_roots` |
|
|
24
|
+
|
|
25
|
+
No ceiling file means the profile as shipped. That is the safe default; the
|
|
26
|
+
ceiling is where a human says "this project may do more".
|
|
27
|
+
|
|
28
|
+
## Procedure
|
|
29
|
+
|
|
30
|
+
1. **Never work around a ceiling blocker in the prompt.** Telling the next job
|
|
31
|
+
"do not run X" only moves the check back to you. Report the rule and the file
|
|
32
|
+
path, then follow this procedure.
|
|
33
|
+
2. `agy_ceiling()` with no arguments → the ceiling file path, whether it exists,
|
|
34
|
+
the effective allow/deny/hard-deny lists, and the project's denial history
|
|
35
|
+
(which `required_rule`s were refused, how often, in which job).
|
|
36
|
+
3. Read the repository yourself to decide what the project actually needs:
|
|
37
|
+
build files, test runners, scripts in `package.json`, `Makefile`, `Cargo.toml`,
|
|
38
|
+
`build.gradle`, CI config. The server does not guess this for you — you are
|
|
39
|
+
better at reading a repo than a marker-file heuristic.
|
|
40
|
+
4. Draft a `version: 2` `policy.json`. Put ordinary build/test commands in
|
|
41
|
+
`allow`; put a profile-denied rule in `exceptions` only when the task cannot
|
|
42
|
+
be done without it, and say why on that line. Never propose
|
|
43
|
+
`command_policy: "denylist"` unless the user asked for it.
|
|
44
|
+
5. `agy_ceiling({ draft })` → syntax errors, `HARD_DENY` conflicts, duplicates of
|
|
45
|
+
what the profile already allows, and a risk class per rule
|
|
46
|
+
(`read_utility | build | vcs_remote | network | install | destructive`). Pass
|
|
47
|
+
`expected_commands` too, to see how the draft would judge the commands the
|
|
48
|
+
task needs. Fix the draft until `ok: true`.
|
|
49
|
+
6. Show the user the full file as a diff against the current one (or as a new
|
|
50
|
+
file), with one line of rationale per rule and the risk class beside every
|
|
51
|
+
`exceptions` entry.
|
|
52
|
+
|
|
53
|
+
## The rule that matters
|
|
54
|
+
|
|
55
|
+
**Do not write `~/.agy-worker/projects/*/policy.json` unless the user, in this
|
|
56
|
+
conversation, after seeing the draft, explicitly approves it.** A standing
|
|
57
|
+
"just do it" or "you have permission" from earlier is not approval of this
|
|
58
|
+
file. `exceptions` entries and `command_policy: "denylist"` need the user to
|
|
59
|
+
approve them line by line — they widen what an unattended job can do to
|
|
60
|
+
network, remote repositories, and the filesystem.
|
|
61
|
+
|
|
62
|
+
If the user prefers to write it themselves, give them the command:
|
|
63
|
+
|
|
64
|
+
```sh
|
|
65
|
+
cat > ~/.agy-worker/projects/<hash>/policy.json <<'JSON'
|
|
66
|
+
{ ...the approved draft... }
|
|
67
|
+
JSON
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
The server enforces the other half of this: agy-worker-mcp has no code path
|
|
71
|
+
that writes the ceiling. `agy_ceiling` reads and validates only. This skill is
|
|
72
|
+
the second wall; the first is that the tool cannot do it at all.
|