@agentmeshhq/agent 0.4.6 → 0.4.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/__tests__/auth-doctor-integration.test.d.ts +14 -0
- package/dist/__tests__/auth-doctor-integration.test.js +130 -0
- package/dist/__tests__/auth-doctor-integration.test.js.map +1 -0
- package/dist/__tests__/auth-guard.integration.test.d.ts +12 -0
- package/dist/__tests__/auth-guard.integration.test.js +132 -0
- package/dist/__tests__/auth-guard.integration.test.js.map +1 -0
- package/dist/__tests__/auth-guard.test.d.ts +17 -0
- package/dist/__tests__/auth-guard.test.js +483 -0
- package/dist/__tests__/auth-guard.test.js.map +1 -0
- package/dist/__tests__/done-state-guard.integration.test.d.ts +1 -0
- package/dist/__tests__/done-state-guard.integration.test.js +281 -0
- package/dist/__tests__/done-state-guard.integration.test.js.map +1 -0
- package/dist/__tests__/done-state-guard.test.d.ts +1 -0
- package/dist/__tests__/done-state-guard.test.js +327 -0
- package/dist/__tests__/done-state-guard.test.js.map +1 -0
- package/dist/__tests__/registry.register.test.d.ts +8 -0
- package/dist/__tests__/registry.register.test.js +109 -0
- package/dist/__tests__/registry.register.test.js.map +1 -0
- package/dist/__tests__/start-team-id.test.d.ts +9 -0
- package/dist/__tests__/start-team-id.test.js +160 -0
- package/dist/__tests__/start-team-id.test.js.map +1 -0
- package/dist/__tests__/tmux-runtime.test.d.ts +1 -0
- package/dist/__tests__/tmux-runtime.test.js +113 -0
- package/dist/__tests__/tmux-runtime.test.js.map +1 -0
- package/dist/cli/auth.d.ts +11 -0
- package/dist/cli/auth.js +92 -0
- package/dist/cli/auth.js.map +1 -0
- package/dist/cli/index.js +132 -1
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/local.d.ts +4 -2
- package/dist/cli/local.js +257 -108
- package/dist/cli/local.js.map +1 -1
- package/dist/cli/migrate.d.ts +1 -0
- package/dist/cli/migrate.js +14 -10
- package/dist/cli/migrate.js.map +1 -1
- package/dist/cli/start.d.ts +11 -0
- package/dist/cli/start.js +46 -24
- package/dist/cli/start.js.map +1 -1
- package/dist/cli/test.d.ts +1 -0
- package/dist/cli/test.js +21 -10
- package/dist/cli/test.js.map +1 -1
- package/dist/cli/watcher.d.ts +27 -0
- package/dist/cli/watcher.js +365 -0
- package/dist/cli/watcher.js.map +1 -0
- package/dist/config/schema.d.ts +13 -0
- package/dist/config/schema.js.map +1 -1
- package/dist/core/auth-guard.d.ts +155 -0
- package/dist/core/auth-guard.js +498 -0
- package/dist/core/auth-guard.js.map +1 -0
- package/dist/core/auth-sync.d.ts +105 -0
- package/dist/core/auth-sync.js +263 -0
- package/dist/core/auth-sync.js.map +1 -0
- package/dist/core/daemon/context-template.js +65 -0
- package/dist/core/daemon/context-template.js.map +1 -1
- package/dist/core/daemon/done-state-guard.d.ts +63 -0
- package/dist/core/daemon/done-state-guard.js +102 -0
- package/dist/core/daemon/done-state-guard.js.map +1 -0
- package/dist/core/daemon/tmux-session.d.ts +1 -0
- package/dist/core/daemon/tmux-session.js +1 -1
- package/dist/core/daemon/tmux-session.js.map +1 -1
- package/dist/core/daemon.d.ts +18 -1
- package/dist/core/daemon.js +158 -37
- package/dist/core/daemon.js.map +1 -1
- package/dist/core/registry.d.ts +11 -1
- package/dist/core/registry.js +32 -1
- package/dist/core/registry.js.map +1 -1
- package/dist/core/tmux-runtime.d.ts +11 -2
- package/dist/core/tmux-runtime.js +45 -19
- package/dist/core/tmux-runtime.js.map +1 -1
- package/dist/core/tmux.d.ts +1 -1
- package/dist/core/tmux.js +7 -3
- package/dist/core/tmux.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,365 @@
|
|
|
1
|
+
import { spawn } from "node:child_process";
|
|
2
|
+
import * as fs from "node:fs";
|
|
3
|
+
import * as path from "node:path";
|
|
4
|
+
import { fileURLToPath } from "node:url";
|
|
5
|
+
import pc from "picocolors";
|
|
6
|
+
import { loadConfig, loadState } from "../config/loader.js";
|
|
7
|
+
const WATCHER_STATE_PATH = path.join(process.env.HOME || ".", ".agentmesh", "watcher-state.json");
|
|
8
|
+
function ensureConfigDir() {
|
|
9
|
+
const dir = path.dirname(WATCHER_STATE_PATH);
|
|
10
|
+
if (!fs.existsSync(dir))
|
|
11
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
12
|
+
}
|
|
13
|
+
function loadWatcherState() {
|
|
14
|
+
try {
|
|
15
|
+
if (!fs.existsSync(WATCHER_STATE_PATH))
|
|
16
|
+
return { watchers: [] };
|
|
17
|
+
return JSON.parse(fs.readFileSync(WATCHER_STATE_PATH, "utf-8"));
|
|
18
|
+
}
|
|
19
|
+
catch {
|
|
20
|
+
return { watchers: [] };
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
function saveWatcherState(state) {
|
|
24
|
+
ensureConfigDir();
|
|
25
|
+
fs.writeFileSync(WATCHER_STATE_PATH, JSON.stringify(state, null, 2));
|
|
26
|
+
}
|
|
27
|
+
function upsertWatcherState(entry) {
|
|
28
|
+
const state = loadWatcherState();
|
|
29
|
+
state.watchers = state.watchers.filter((w) => w.teamId !== entry.teamId);
|
|
30
|
+
state.watchers.push(entry);
|
|
31
|
+
saveWatcherState(state);
|
|
32
|
+
}
|
|
33
|
+
function patchWatcherState(teamId, updates) {
|
|
34
|
+
const state = loadWatcherState();
|
|
35
|
+
const idx = state.watchers.findIndex((w) => w.teamId === teamId);
|
|
36
|
+
if (idx === -1)
|
|
37
|
+
return;
|
|
38
|
+
state.watchers[idx] = { ...state.watchers[idx], ...updates };
|
|
39
|
+
saveWatcherState(state);
|
|
40
|
+
}
|
|
41
|
+
function resolveAuthContext(agentName) {
|
|
42
|
+
const config = loadConfig();
|
|
43
|
+
if (!config)
|
|
44
|
+
throw new Error("No config found. Run 'agentmesh init' first.");
|
|
45
|
+
const envToken = process.env.AGENT_TOKEN;
|
|
46
|
+
const envAgentId = process.env.AGENTMESH_AGENT_ID;
|
|
47
|
+
if (envToken && !agentName) {
|
|
48
|
+
return {
|
|
49
|
+
hubUrl: config.hubUrl,
|
|
50
|
+
workspace: config.workspace,
|
|
51
|
+
token: envToken,
|
|
52
|
+
agentId: envAgentId,
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
const state = loadState();
|
|
56
|
+
let agent = agentName ? state.agents.find((a) => a.name === agentName) : undefined;
|
|
57
|
+
if (!agent && !agentName && envAgentId) {
|
|
58
|
+
agent = state.agents.find((a) => a.agentId === envAgentId);
|
|
59
|
+
}
|
|
60
|
+
if (!agent && !agentName) {
|
|
61
|
+
if (state.agents.length === 1) {
|
|
62
|
+
agent = state.agents[0];
|
|
63
|
+
}
|
|
64
|
+
else if (state.agents.length > 1) {
|
|
65
|
+
throw new Error("Multiple agents found. Pass --name to select which agent token to use.");
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
if (!agent) {
|
|
69
|
+
if (agentName)
|
|
70
|
+
throw new Error(`Agent "${agentName}" not found.`);
|
|
71
|
+
throw new Error("No agent token available. Start an agent or run inside an agent session.");
|
|
72
|
+
}
|
|
73
|
+
if (!agent.token) {
|
|
74
|
+
throw new Error(`No token found for agent "${agent.name}". Run 'agentmesh token refresh --name ${agent.name}'.`);
|
|
75
|
+
}
|
|
76
|
+
return {
|
|
77
|
+
hubUrl: config.hubUrl,
|
|
78
|
+
workspace: config.workspace,
|
|
79
|
+
token: agent.token,
|
|
80
|
+
agentName: agent.name,
|
|
81
|
+
agentId: agent.agentId,
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
async function meshRequest(context, pathName, init = {}) {
|
|
85
|
+
const response = await fetch(`${context.hubUrl}${pathName}`, {
|
|
86
|
+
...init,
|
|
87
|
+
headers: {
|
|
88
|
+
Authorization: `Bearer ${context.token}`,
|
|
89
|
+
...(init.headers ?? {}),
|
|
90
|
+
},
|
|
91
|
+
});
|
|
92
|
+
if (!response.ok) {
|
|
93
|
+
const text = await response.text();
|
|
94
|
+
throw new Error(`Hub request failed (${response.status}): ${text}`);
|
|
95
|
+
}
|
|
96
|
+
if (response.status === 204)
|
|
97
|
+
return {};
|
|
98
|
+
return (await response.json());
|
|
99
|
+
}
|
|
100
|
+
function getWatcherState(teamId) {
|
|
101
|
+
return loadWatcherState().watchers.find((w) => w.teamId === teamId);
|
|
102
|
+
}
|
|
103
|
+
function validateIntervals(options) {
|
|
104
|
+
const intervalSeconds = options.intervalSeconds ?? 15;
|
|
105
|
+
const heartbeatSeconds = options.heartbeatSeconds ?? 10;
|
|
106
|
+
const ttlSeconds = options.ttlSeconds ?? 30;
|
|
107
|
+
if (!Number.isInteger(intervalSeconds) || intervalSeconds < 5 || intervalSeconds > 300) {
|
|
108
|
+
throw new Error("interval-seconds must be an integer between 5 and 300.");
|
|
109
|
+
}
|
|
110
|
+
if (!Number.isInteger(heartbeatSeconds) || heartbeatSeconds < 5 || heartbeatSeconds > 120) {
|
|
111
|
+
throw new Error("heartbeat-seconds must be an integer between 5 and 120.");
|
|
112
|
+
}
|
|
113
|
+
if (!Number.isInteger(ttlSeconds) || ttlSeconds < 10 || ttlSeconds > 300) {
|
|
114
|
+
throw new Error("ttl-seconds must be an integer between 10 and 300.");
|
|
115
|
+
}
|
|
116
|
+
return { intervalSeconds, heartbeatSeconds, ttlSeconds };
|
|
117
|
+
}
|
|
118
|
+
export async function startWatcher(options) {
|
|
119
|
+
if (!options.teamId?.trim())
|
|
120
|
+
throw new Error("team-id is required.");
|
|
121
|
+
const existing = getWatcherState(options.teamId);
|
|
122
|
+
if (existing && existing.pid > 0) {
|
|
123
|
+
try {
|
|
124
|
+
process.kill(existing.pid, 0);
|
|
125
|
+
throw new Error(`Watcher for team ${options.teamId} is already running (pid ${existing.pid}).`);
|
|
126
|
+
}
|
|
127
|
+
catch {
|
|
128
|
+
// stale pid, continue
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
const timings = validateIntervals(options);
|
|
132
|
+
if (!options.foreground) {
|
|
133
|
+
const cliPath = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "../cli/index.js");
|
|
134
|
+
const args = [
|
|
135
|
+
"watcher",
|
|
136
|
+
"start",
|
|
137
|
+
"--team-id",
|
|
138
|
+
options.teamId,
|
|
139
|
+
"--foreground",
|
|
140
|
+
"--interval-seconds",
|
|
141
|
+
String(timings.intervalSeconds),
|
|
142
|
+
"--heartbeat-seconds",
|
|
143
|
+
String(timings.heartbeatSeconds),
|
|
144
|
+
"--ttl-seconds",
|
|
145
|
+
String(timings.ttlSeconds),
|
|
146
|
+
];
|
|
147
|
+
if (options.name)
|
|
148
|
+
args.push("--name", options.name);
|
|
149
|
+
const child = spawn("node", [cliPath, ...args], {
|
|
150
|
+
detached: true,
|
|
151
|
+
stdio: "ignore",
|
|
152
|
+
env: process.env,
|
|
153
|
+
});
|
|
154
|
+
child.unref();
|
|
155
|
+
upsertWatcherState({
|
|
156
|
+
teamId: options.teamId,
|
|
157
|
+
pid: child.pid ?? 0,
|
|
158
|
+
startedAt: new Date().toISOString(),
|
|
159
|
+
status: "starting",
|
|
160
|
+
agentName: options.name,
|
|
161
|
+
});
|
|
162
|
+
console.log(pc.green(`Watcher starting for team ${options.teamId} (PID: ${child.pid}).`));
|
|
163
|
+
return;
|
|
164
|
+
}
|
|
165
|
+
const context = resolveAuthContext(options.name);
|
|
166
|
+
const holderName = context.agentName ?? "watcher";
|
|
167
|
+
const holderId = context.agentId ?? holderName;
|
|
168
|
+
const acquire = await meshRequest(context, `/api/v1/teams/${options.teamId}/watcher/acquire`, {
|
|
169
|
+
method: "POST",
|
|
170
|
+
headers: { "Content-Type": "application/json" },
|
|
171
|
+
body: JSON.stringify({
|
|
172
|
+
holder_id: holderId,
|
|
173
|
+
holder_name: holderName,
|
|
174
|
+
ttl_seconds: timings.ttlSeconds,
|
|
175
|
+
}),
|
|
176
|
+
});
|
|
177
|
+
if (!acquire.acquired || !acquire.lease_token) {
|
|
178
|
+
throw new Error(`Failed to acquire watcher lease for team ${options.teamId}${acquire.reason_code ? `: ${acquire.reason_code}` : ""}.`);
|
|
179
|
+
}
|
|
180
|
+
const leaseToken = acquire.lease_token;
|
|
181
|
+
const latest = await fetch(`${context.hubUrl}/api/v1/teams/${options.teamId}/watcher/snapshot/latest`, {
|
|
182
|
+
headers: { Authorization: `Bearer ${context.token}` },
|
|
183
|
+
});
|
|
184
|
+
let seq = 1;
|
|
185
|
+
if (latest.ok) {
|
|
186
|
+
const latestBody = (await latest.json());
|
|
187
|
+
if (typeof latestBody.seq === "number" && Number.isInteger(latestBody.seq)) {
|
|
188
|
+
seq = latestBody.seq + 1;
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
let stopping = false;
|
|
192
|
+
const shutdown = async () => {
|
|
193
|
+
if (stopping)
|
|
194
|
+
return;
|
|
195
|
+
stopping = true;
|
|
196
|
+
clearInterval(heartbeatTimer);
|
|
197
|
+
clearInterval(snapshotTimer);
|
|
198
|
+
try {
|
|
199
|
+
await meshRequest(context, `/api/v1/teams/${options.teamId}/watcher/snapshots`, {
|
|
200
|
+
method: "POST",
|
|
201
|
+
headers: { "Content-Type": "application/json" },
|
|
202
|
+
body: JSON.stringify({
|
|
203
|
+
seq,
|
|
204
|
+
status: "degraded",
|
|
205
|
+
reason_code: "watcher_stopped",
|
|
206
|
+
payload: {
|
|
207
|
+
holder_id: holderId,
|
|
208
|
+
stopped_at: new Date().toISOString(),
|
|
209
|
+
},
|
|
210
|
+
}),
|
|
211
|
+
});
|
|
212
|
+
seq += 1;
|
|
213
|
+
}
|
|
214
|
+
catch {
|
|
215
|
+
// best effort only
|
|
216
|
+
}
|
|
217
|
+
try {
|
|
218
|
+
await meshRequest(context, `/api/v1/teams/${options.teamId}/watcher/release`, {
|
|
219
|
+
method: "POST",
|
|
220
|
+
headers: { "Content-Type": "application/json" },
|
|
221
|
+
body: JSON.stringify({ lease_token: leaseToken }),
|
|
222
|
+
});
|
|
223
|
+
}
|
|
224
|
+
catch {
|
|
225
|
+
// best effort only
|
|
226
|
+
}
|
|
227
|
+
patchWatcherState(options.teamId, { status: "stopped" });
|
|
228
|
+
process.exit(0);
|
|
229
|
+
};
|
|
230
|
+
process.on("SIGINT", shutdown);
|
|
231
|
+
process.on("SIGTERM", shutdown);
|
|
232
|
+
upsertWatcherState({
|
|
233
|
+
teamId: options.teamId,
|
|
234
|
+
pid: process.pid,
|
|
235
|
+
startedAt: new Date().toISOString(),
|
|
236
|
+
status: "starting",
|
|
237
|
+
leaseToken,
|
|
238
|
+
agentName: options.name,
|
|
239
|
+
});
|
|
240
|
+
const heartbeatTimer = setInterval(async () => {
|
|
241
|
+
if (stopping)
|
|
242
|
+
return;
|
|
243
|
+
try {
|
|
244
|
+
const renewed = await meshRequest(context, `/api/v1/teams/${options.teamId}/watcher/renew`, {
|
|
245
|
+
method: "POST",
|
|
246
|
+
headers: { "Content-Type": "application/json" },
|
|
247
|
+
body: JSON.stringify({
|
|
248
|
+
lease_token: leaseToken,
|
|
249
|
+
ttl_seconds: timings.ttlSeconds,
|
|
250
|
+
}),
|
|
251
|
+
});
|
|
252
|
+
if (!renewed.ok) {
|
|
253
|
+
throw new Error(renewed.reason_code ?? "lease_renew_failed");
|
|
254
|
+
}
|
|
255
|
+
patchWatcherState(options.teamId, {
|
|
256
|
+
status: "running",
|
|
257
|
+
lastHeartbeatAt: new Date().toISOString(),
|
|
258
|
+
leaseToken,
|
|
259
|
+
});
|
|
260
|
+
}
|
|
261
|
+
catch (error) {
|
|
262
|
+
patchWatcherState(options.teamId, { status: "failed" });
|
|
263
|
+
console.error(pc.red(`Watcher lease renewal failed: ${error.message}`));
|
|
264
|
+
await shutdown();
|
|
265
|
+
}
|
|
266
|
+
}, timings.heartbeatSeconds * 1000);
|
|
267
|
+
const snapshotTimer = setInterval(async () => {
|
|
268
|
+
if (stopping)
|
|
269
|
+
return;
|
|
270
|
+
try {
|
|
271
|
+
await meshRequest(context, `/api/v1/teams/${options.teamId}/watcher/snapshots`, {
|
|
272
|
+
method: "POST",
|
|
273
|
+
headers: { "Content-Type": "application/json" },
|
|
274
|
+
body: JSON.stringify({
|
|
275
|
+
seq,
|
|
276
|
+
status: "ok",
|
|
277
|
+
payload: {
|
|
278
|
+
holder_id: holderId,
|
|
279
|
+
heartbeat_seconds: timings.heartbeatSeconds,
|
|
280
|
+
interval_seconds: timings.intervalSeconds,
|
|
281
|
+
uptime_seconds: Math.floor(process.uptime()),
|
|
282
|
+
},
|
|
283
|
+
}),
|
|
284
|
+
});
|
|
285
|
+
seq += 1;
|
|
286
|
+
}
|
|
287
|
+
catch (error) {
|
|
288
|
+
console.error(pc.yellow(`Snapshot publish skipped: ${error.message}`));
|
|
289
|
+
}
|
|
290
|
+
}, timings.intervalSeconds * 1000);
|
|
291
|
+
await meshRequest(context, `/api/v1/teams/${options.teamId}/watcher/snapshots`, {
|
|
292
|
+
method: "POST",
|
|
293
|
+
headers: { "Content-Type": "application/json" },
|
|
294
|
+
body: JSON.stringify({
|
|
295
|
+
seq,
|
|
296
|
+
status: "ok",
|
|
297
|
+
payload: {
|
|
298
|
+
holder_id: holderId,
|
|
299
|
+
started_at: new Date().toISOString(),
|
|
300
|
+
},
|
|
301
|
+
}),
|
|
302
|
+
});
|
|
303
|
+
seq += 1;
|
|
304
|
+
patchWatcherState(options.teamId, { leaseToken, status: "running" });
|
|
305
|
+
console.log(pc.green(`Watcher loop running for team ${options.teamId}. Lease token: ${leaseToken}`));
|
|
306
|
+
await new Promise(() => { });
|
|
307
|
+
}
|
|
308
|
+
export async function stopWatcher(options) {
|
|
309
|
+
const watcher = getWatcherState(options.teamId);
|
|
310
|
+
if (!watcher || watcher.pid <= 0) {
|
|
311
|
+
console.log(pc.yellow(`No local watcher process found for team ${options.teamId}.`));
|
|
312
|
+
return;
|
|
313
|
+
}
|
|
314
|
+
try {
|
|
315
|
+
process.kill(watcher.pid, "SIGTERM");
|
|
316
|
+
}
|
|
317
|
+
catch {
|
|
318
|
+
// process already gone
|
|
319
|
+
}
|
|
320
|
+
patchWatcherState(options.teamId, { status: "stopped" });
|
|
321
|
+
console.log(pc.green(`Stop signal sent to watcher for team ${options.teamId} (PID: ${watcher.pid}).`));
|
|
322
|
+
}
|
|
323
|
+
export async function watcherStatus(options) {
|
|
324
|
+
const context = resolveAuthContext(options.name);
|
|
325
|
+
const stale = options.staleAfterSeconds && Number.isInteger(options.staleAfterSeconds)
|
|
326
|
+
? `?stale_after_seconds=${options.staleAfterSeconds}`
|
|
327
|
+
: "";
|
|
328
|
+
const remote = await meshRequest(context, `/api/v1/teams/${options.teamId}/watcher/status${stale}`);
|
|
329
|
+
const local = getWatcherState(options.teamId) ?? null;
|
|
330
|
+
if (options.json) {
|
|
331
|
+
console.log(JSON.stringify({ local, remote }, null, 2));
|
|
332
|
+
return;
|
|
333
|
+
}
|
|
334
|
+
console.log(pc.bold(`Watcher status for team ${options.teamId}`));
|
|
335
|
+
console.log(`Remote status: ${String(remote.status)}`);
|
|
336
|
+
console.log(`Remote seq: ${String(remote.seq)}`);
|
|
337
|
+
const reasons = Array.isArray(remote.reason_codes) ? remote.reason_codes : [];
|
|
338
|
+
console.log(`Reason codes: ${reasons.length > 0 ? reasons.join(", ") : "-"}`);
|
|
339
|
+
if (local) {
|
|
340
|
+
console.log(`Local process: PID ${local.pid} (${local.status})`);
|
|
341
|
+
console.log(`Started at: ${local.startedAt}`);
|
|
342
|
+
if (local.lastHeartbeatAt)
|
|
343
|
+
console.log(`Last heartbeat: ${local.lastHeartbeatAt}`);
|
|
344
|
+
}
|
|
345
|
+
else {
|
|
346
|
+
console.log("Local process: not found");
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
export async function pullWatcher(options) {
|
|
350
|
+
const context = resolveAuthContext(options.name);
|
|
351
|
+
const snapshot = await meshRequest(context, `/api/v1/teams/${options.teamId}/watcher/snapshot/latest`);
|
|
352
|
+
if (options.json) {
|
|
353
|
+
console.log(JSON.stringify(snapshot, null, 2));
|
|
354
|
+
return;
|
|
355
|
+
}
|
|
356
|
+
console.log(pc.bold(`Latest watcher snapshot for team ${options.teamId}`));
|
|
357
|
+
console.log(`Seq: ${String(snapshot.seq)}`);
|
|
358
|
+
console.log(`Status: ${String(snapshot.status)}`);
|
|
359
|
+
console.log(`Reason: ${snapshot.reason_code ? String(snapshot.reason_code) : "-"}`);
|
|
360
|
+
console.log(`Generated at: ${String(snapshot.generated_at)}`);
|
|
361
|
+
if (snapshot.payload && typeof snapshot.payload === "object") {
|
|
362
|
+
console.log(`Payload: ${JSON.stringify(snapshot.payload)}`);
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
//# sourceMappingURL=watcher.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"watcher.js","sourceRoot":"","sources":["../../src/cli/watcher.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAC3C,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAC9B,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAClC,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,MAAM,YAAY,CAAC;AAC5B,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAkD5D,MAAM,kBAAkB,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,IAAI,GAAG,EAAE,YAAY,EAAE,oBAAoB,CAAC,CAAC;AAElG,SAAS,eAAe;IACtB,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,kBAAkB,CAAC,CAAC;IAC7C,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,GAAG,CAAC;QAAE,EAAE,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;AAClE,CAAC;AAED,SAAS,gBAAgB;IACvB,IAAI,CAAC;QACH,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,kBAAkB,CAAC;YAAE,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC;QAChE,OAAO,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,YAAY,CAAC,kBAAkB,EAAE,OAAO,CAAC,CAAqB,CAAC;IACtF,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC;IAC1B,CAAC;AACH,CAAC;AAED,SAAS,gBAAgB,CAAC,KAAuB;IAC/C,eAAe,EAAE,CAAC;IAClB,EAAE,CAAC,aAAa,CAAC,kBAAkB,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;AACvE,CAAC;AAED,SAAS,kBAAkB,CAAC,KAAyB;IACnD,MAAM,KAAK,GAAG,gBAAgB,EAAE,CAAC;IACjC,KAAK,CAAC,QAAQ,GAAG,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,KAAK,CAAC,MAAM,CAAC,CAAC;IACzE,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAC3B,gBAAgB,CAAC,KAAK,CAAC,CAAC;AAC1B,CAAC;AAED,SAAS,iBAAiB,CAAC,MAAc,EAAE,OAAoC;IAC7E,MAAM,KAAK,GAAG,gBAAgB,EAAE,CAAC;IACjC,MAAM,GAAG,GAAG,KAAK,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,MAAM,CAAC,CAAC;IACjE,IAAI,GAAG,KAAK,CAAC,CAAC;QAAE,OAAO;IACvB,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,EAAE,GAAG,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,GAAG,OAAO,EAAE,CAAC;IAC7D,gBAAgB,CAAC,KAAK,CAAC,CAAC;AAC1B,CAAC;AAED,SAAS,kBAAkB,CAAC,SAAkB;IAC5C,MAAM,MAAM,GAAG,UAAU,EAAE,CAAC;IAC5B,IAAI,CAAC,MAAM;QAAE,MAAM,IAAI,KAAK,CAAC,8CAA8C,CAAC,CAAC;IAE7E,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,WAAW,CAAC;IACzC,MAAM,UAAU,GAAG,OAAO,CAAC,GAAG,CAAC,kBAAkB,CAAC;IAClD,IAAI,QAAQ,IAAI,CAAC,SAAS,EAAE,CAAC;QAC3B,OAAO;YACL,MAAM,EAAE,MAAM,CAAC,MAAM;YACrB,SAAS,EAAE,MAAM,CAAC,SAAS;YAC3B,KAAK,EAAE,QAAQ;YACf,OAAO,EAAE,UAAU;SACpB,CAAC;IACJ,CAAC;IAED,MAAM,KAAK,GAAG,SAAS,EAAE,CAAC;IAC1B,IAAI,KAAK,GAAG,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IACnF,IAAI,CAAC,KAAK,IAAI,CAAC,SAAS,IAAI,UAAU,EAAE,CAAC;QACvC,KAAK,GAAG,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,KAAK,UAAU,CAAC,CAAC;IAC7D,CAAC;IACD,IAAI,CAAC,KAAK,IAAI,CAAC,SAAS,EAAE,CAAC;QACzB,IAAI,KAAK,CAAC,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC9B,KAAK,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;QAC1B,CAAC;aAAM,IAAI,KAAK,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACnC,MAAM,IAAI,KAAK,CAAC,wEAAwE,CAAC,CAAC;QAC5F,CAAC;IACH,CAAC;IACD,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,IAAI,SAAS;YAAE,MAAM,IAAI,KAAK,CAAC,UAAU,SAAS,cAAc,CAAC,CAAC;QAClE,MAAM,IAAI,KAAK,CAAC,0EAA0E,CAAC,CAAC;IAC9F,CAAC;IACD,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;QACjB,MAAM,IAAI,KAAK,CACb,6BAA6B,KAAK,CAAC,IAAI,0CAA0C,KAAK,CAAC,IAAI,IAAI,CAChG,CAAC;IACJ,CAAC;IACD,OAAO;QACL,MAAM,EAAE,MAAM,CAAC,MAAM;QACrB,SAAS,EAAE,MAAM,CAAC,SAAS;QAC3B,KAAK,EAAE,KAAK,CAAC,KAAK;QAClB,SAAS,EAAE,KAAK,CAAC,IAAI;QACrB,OAAO,EAAE,KAAK,CAAC,OAAO;KACvB,CAAC;AACJ,CAAC;AAED,KAAK,UAAU,WAAW,CACxB,OAAoB,EACpB,QAAgB,EAChB,OAAoB,EAAE;IAEtB,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,OAAO,CAAC,MAAM,GAAG,QAAQ,EAAE,EAAE;QAC3D,GAAG,IAAI;QACP,OAAO,EAAE;YACP,aAAa,EAAE,UAAU,OAAO,CAAC,KAAK,EAAE;YACxC,GAAG,CAAC,IAAI,CAAC,OAAO,IAAI,EAAE,CAAC;SACxB;KACF,CAAC,CAAC;IACH,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;QACjB,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;QACnC,MAAM,IAAI,KAAK,CAAC,uBAAuB,QAAQ,CAAC,MAAM,MAAM,IAAI,EAAE,CAAC,CAAC;IACtE,CAAC;IACD,IAAI,QAAQ,CAAC,MAAM,KAAK,GAAG;QAAE,OAAO,EAAO,CAAC;IAC5C,OAAO,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAM,CAAC;AACtC,CAAC;AAED,SAAS,eAAe,CAAC,MAAc;IACrC,OAAO,gBAAgB,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,MAAM,CAAC,CAAC;AACtE,CAAC;AAED,SAAS,iBAAiB,CAAC,OAA4B;IAKrD,MAAM,eAAe,GAAG,OAAO,CAAC,eAAe,IAAI,EAAE,CAAC;IACtD,MAAM,gBAAgB,GAAG,OAAO,CAAC,gBAAgB,IAAI,EAAE,CAAC;IACxD,MAAM,UAAU,GAAG,OAAO,CAAC,UAAU,IAAI,EAAE,CAAC;IAC5C,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,eAAe,CAAC,IAAI,eAAe,GAAG,CAAC,IAAI,eAAe,GAAG,GAAG,EAAE,CAAC;QACvF,MAAM,IAAI,KAAK,CAAC,wDAAwD,CAAC,CAAC;IAC5E,CAAC;IACD,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,gBAAgB,CAAC,IAAI,gBAAgB,GAAG,CAAC,IAAI,gBAAgB,GAAG,GAAG,EAAE,CAAC;QAC1F,MAAM,IAAI,KAAK,CAAC,yDAAyD,CAAC,CAAC;IAC7E,CAAC;IACD,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,UAAU,CAAC,IAAI,UAAU,GAAG,EAAE,IAAI,UAAU,GAAG,GAAG,EAAE,CAAC;QACzE,MAAM,IAAI,KAAK,CAAC,oDAAoD,CAAC,CAAC;IACxE,CAAC;IACD,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAE,UAAU,EAAE,CAAC;AAC3D,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,OAA4B;IAC7D,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,IAAI,EAAE;QAAE,MAAM,IAAI,KAAK,CAAC,sBAAsB,CAAC,CAAC;IAErE,MAAM,QAAQ,GAAG,eAAe,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;IACjD,IAAI,QAAQ,IAAI,QAAQ,CAAC,GAAG,GAAG,CAAC,EAAE,CAAC;QACjC,IAAI,CAAC;YACH,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;YAC9B,MAAM,IAAI,KAAK,CACb,oBAAoB,OAAO,CAAC,MAAM,4BAA4B,QAAQ,CAAC,GAAG,IAAI,CAC/E,CAAC;QACJ,CAAC;QAAC,MAAM,CAAC;YACP,sBAAsB;QACxB,CAAC;IACH,CAAC;IAED,MAAM,OAAO,GAAG,iBAAiB,CAAC,OAAO,CAAC,CAAC;IAE3C,IAAI,CAAC,OAAO,CAAC,UAAU,EAAE,CAAC;QACxB,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,iBAAiB,CAAC,CAAC;QAC9F,MAAM,IAAI,GAAG;YACX,SAAS;YACT,OAAO;YACP,WAAW;YACX,OAAO,CAAC,MAAM;YACd,cAAc;YACd,oBAAoB;YACpB,MAAM,CAAC,OAAO,CAAC,eAAe,CAAC;YAC/B,qBAAqB;YACrB,MAAM,CAAC,OAAO,CAAC,gBAAgB,CAAC;YAChC,eAAe;YACf,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC;SAC3B,CAAC;QACF,IAAI,OAAO,CAAC,IAAI;YAAE,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC;QAEpD,MAAM,KAAK,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,OAAO,EAAE,GAAG,IAAI,CAAC,EAAE;YAC9C,QAAQ,EAAE,IAAI;YACd,KAAK,EAAE,QAAQ;YACf,GAAG,EAAE,OAAO,CAAC,GAAG;SACjB,CAAC,CAAC;QACH,KAAK,CAAC,KAAK,EAAE,CAAC;QACd,kBAAkB,CAAC;YACjB,MAAM,EAAE,OAAO,CAAC,MAAM;YACtB,GAAG,EAAE,KAAK,CAAC,GAAG,IAAI,CAAC;YACnB,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;YACnC,MAAM,EAAE,UAAU;YAClB,SAAS,EAAE,OAAO,CAAC,IAAI;SACxB,CAAC,CAAC;QACH,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,KAAK,CAAC,6BAA6B,OAAO,CAAC,MAAM,UAAU,KAAK,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC;QAC1F,OAAO;IACT,CAAC;IAED,MAAM,OAAO,GAAG,kBAAkB,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IACjD,MAAM,UAAU,GAAG,OAAO,CAAC,SAAS,IAAI,SAAS,CAAC;IAClD,MAAM,QAAQ,GAAG,OAAO,CAAC,OAAO,IAAI,UAAU,CAAC;IAE/C,MAAM,OAAO,GAAG,MAAM,WAAW,CAI9B,OAAO,EAAE,iBAAiB,OAAO,CAAC,MAAM,kBAAkB,EAAE;QAC7D,MAAM,EAAE,MAAM;QACd,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;QAC/C,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;YACnB,SAAS,EAAE,QAAQ;YACnB,WAAW,EAAE,UAAU;YACvB,WAAW,EAAE,OAAO,CAAC,UAAU;SAChC,CAAC;KACH,CAAC,CAAC;IACH,IAAI,CAAC,OAAO,CAAC,QAAQ,IAAI,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC;QAC9C,MAAM,IAAI,KAAK,CACb,4CAA4C,OAAO,CAAC,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,KAAK,OAAO,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE,GAAG,CACtH,CAAC;IACJ,CAAC;IACD,MAAM,UAAU,GAAG,OAAO,CAAC,WAAW,CAAC;IAEvC,MAAM,MAAM,GAAG,MAAM,KAAK,CACxB,GAAG,OAAO,CAAC,MAAM,iBAAiB,OAAO,CAAC,MAAM,0BAA0B,EAC1E;QACE,OAAO,EAAE,EAAE,aAAa,EAAE,UAAU,OAAO,CAAC,KAAK,EAAE,EAAE;KACtD,CACF,CAAC;IACF,IAAI,GAAG,GAAG,CAAC,CAAC;IACZ,IAAI,MAAM,CAAC,EAAE,EAAE,CAAC;QACd,MAAM,UAAU,GAAG,CAAC,MAAM,MAAM,CAAC,IAAI,EAAE,CAAqB,CAAC;QAC7D,IAAI,OAAO,UAAU,CAAC,GAAG,KAAK,QAAQ,IAAI,MAAM,CAAC,SAAS,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;YAC3E,GAAG,GAAG,UAAU,CAAC,GAAG,GAAG,CAAC,CAAC;QAC3B,CAAC;IACH,CAAC;IAED,IAAI,QAAQ,GAAG,KAAK,CAAC;IACrB,MAAM,QAAQ,GAAG,KAAK,IAAI,EAAE;QAC1B,IAAI,QAAQ;YAAE,OAAO;QACrB,QAAQ,GAAG,IAAI,CAAC;QAChB,aAAa,CAAC,cAAc,CAAC,CAAC;QAC9B,aAAa,CAAC,aAAa,CAAC,CAAC;QAE7B,IAAI,CAAC;YACH,MAAM,WAAW,CAAC,OAAO,EAAE,iBAAiB,OAAO,CAAC,MAAM,oBAAoB,EAAE;gBAC9E,MAAM,EAAE,MAAM;gBACd,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;gBAC/C,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;oBACnB,GAAG;oBACH,MAAM,EAAE,UAAU;oBAClB,WAAW,EAAE,iBAAiB;oBAC9B,OAAO,EAAE;wBACP,SAAS,EAAE,QAAQ;wBACnB,UAAU,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;qBACrC;iBACF,CAAC;aACH,CAAC,CAAC;YACH,GAAG,IAAI,CAAC,CAAC;QACX,CAAC;QAAC,MAAM,CAAC;YACP,mBAAmB;QACrB,CAAC;QAED,IAAI,CAAC;YACH,MAAM,WAAW,CAAC,OAAO,EAAE,iBAAiB,OAAO,CAAC,MAAM,kBAAkB,EAAE;gBAC5E,MAAM,EAAE,MAAM;gBACd,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;gBAC/C,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,WAAW,EAAE,UAAU,EAAE,CAAC;aAClD,CAAC,CAAC;QACL,CAAC;QAAC,MAAM,CAAC;YACP,mBAAmB;QACrB,CAAC;QAED,iBAAiB,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC,CAAC;QACzD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC,CAAC;IAEF,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;IAC/B,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;IAEhC,kBAAkB,CAAC;QACjB,MAAM,EAAE,OAAO,CAAC,MAAM;QACtB,GAAG,EAAE,OAAO,CAAC,GAAG;QAChB,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;QACnC,MAAM,EAAE,UAAU;QAClB,UAAU;QACV,SAAS,EAAE,OAAO,CAAC,IAAI;KACxB,CAAC,CAAC;IAEH,MAAM,cAAc,GAAG,WAAW,CAAC,KAAK,IAAI,EAAE;QAC5C,IAAI,QAAQ;YAAE,OAAO;QACrB,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,MAAM,WAAW,CAC/B,OAAO,EACP,iBAAiB,OAAO,CAAC,MAAM,gBAAgB,EAC/C;gBACE,MAAM,EAAE,MAAM;gBACd,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;gBAC/C,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;oBACnB,WAAW,EAAE,UAAU;oBACvB,WAAW,EAAE,OAAO,CAAC,UAAU;iBAChC,CAAC;aACH,CACF,CAAC;YAEF,IAAI,CAAC,OAAO,CAAC,EAAE,EAAE,CAAC;gBAChB,MAAM,IAAI,KAAK,CAAC,OAAO,CAAC,WAAW,IAAI,oBAAoB,CAAC,CAAC;YAC/D,CAAC;YACD,iBAAiB,CAAC,OAAO,CAAC,MAAM,EAAE;gBAChC,MAAM,EAAE,SAAS;gBACjB,eAAe,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;gBACzC,UAAU;aACX,CAAC,CAAC;QACL,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,iBAAiB,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,CAAC;YACxD,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,iCAAkC,KAAe,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;YACnF,MAAM,QAAQ,EAAE,CAAC;QACnB,CAAC;IACH,CAAC,EAAE,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC,CAAC;IAEpC,MAAM,aAAa,GAAG,WAAW,CAAC,KAAK,IAAI,EAAE;QAC3C,IAAI,QAAQ;YAAE,OAAO;QACrB,IAAI,CAAC;YACH,MAAM,WAAW,CAAC,OAAO,EAAE,iBAAiB,OAAO,CAAC,MAAM,oBAAoB,EAAE;gBAC9E,MAAM,EAAE,MAAM;gBACd,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;gBAC/C,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;oBACnB,GAAG;oBACH,MAAM,EAAE,IAAI;oBACZ,OAAO,EAAE;wBACP,SAAS,EAAE,QAAQ;wBACnB,iBAAiB,EAAE,OAAO,CAAC,gBAAgB;wBAC3C,gBAAgB,EAAE,OAAO,CAAC,eAAe;wBACzC,cAAc,EAAE,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC;qBAC7C;iBACF,CAAC;aACH,CAAC,CAAC;YACH,GAAG,IAAI,CAAC,CAAC;QACX,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,MAAM,CAAC,6BAA8B,KAAe,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;QACpF,CAAC;IACH,CAAC,EAAE,OAAO,CAAC,eAAe,GAAG,IAAI,CAAC,CAAC;IAEnC,MAAM,WAAW,CAAC,OAAO,EAAE,iBAAiB,OAAO,CAAC,MAAM,oBAAoB,EAAE;QAC9E,MAAM,EAAE,MAAM;QACd,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;QAC/C,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;YACnB,GAAG;YACH,MAAM,EAAE,IAAI;YACZ,OAAO,EAAE;gBACP,SAAS,EAAE,QAAQ;gBACnB,UAAU,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;aACrC;SACF,CAAC;KACH,CAAC,CAAC;IACH,GAAG,IAAI,CAAC,CAAC;IACT,iBAAiB,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,UAAU,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC,CAAC;IACrE,OAAO,CAAC,GAAG,CACT,EAAE,CAAC,KAAK,CAAC,iCAAiC,OAAO,CAAC,MAAM,kBAAkB,UAAU,EAAE,CAAC,CACxF,CAAC;IACF,MAAM,IAAI,OAAO,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;AAC9B,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,OAA2B;IAC3D,MAAM,OAAO,GAAG,eAAe,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;IAChD,IAAI,CAAC,OAAO,IAAI,OAAO,CAAC,GAAG,IAAI,CAAC,EAAE,CAAC;QACjC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,MAAM,CAAC,2CAA2C,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;QACrF,OAAO;IACT,CAAC;IACD,IAAI,CAAC;QACH,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC;IACvC,CAAC;IAAC,MAAM,CAAC;QACP,uBAAuB;IACzB,CAAC;IACD,iBAAiB,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC,CAAC;IACzD,OAAO,CAAC,GAAG,CACT,EAAE,CAAC,KAAK,CAAC,wCAAwC,OAAO,CAAC,MAAM,UAAU,OAAO,CAAC,GAAG,IAAI,CAAC,CAC1F,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,OAA6B;IAC/D,MAAM,OAAO,GAAG,kBAAkB,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IACjD,MAAM,KAAK,GACT,OAAO,CAAC,iBAAiB,IAAI,MAAM,CAAC,SAAS,CAAC,OAAO,CAAC,iBAAiB,CAAC;QACtE,CAAC,CAAC,wBAAwB,OAAO,CAAC,iBAAiB,EAAE;QACrD,CAAC,CAAC,EAAE,CAAC;IACT,MAAM,MAAM,GAAG,MAAM,WAAW,CAC9B,OAAO,EACP,iBAAiB,OAAO,CAAC,MAAM,kBAAkB,KAAK,EAAE,CACzD,CAAC;IACF,MAAM,KAAK,GAAG,eAAe,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,IAAI,CAAC;IAEtD,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC;QACjB,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;QACxD,OAAO;IACT,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,2BAA2B,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;IAClE,OAAO,CAAC,GAAG,CAAC,kBAAkB,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;IACvD,OAAO,CAAC,GAAG,CAAC,eAAe,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IACjD,MAAM,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,CAAC,CAAE,MAAM,CAAC,YAAyB,CAAC,CAAC,CAAC,EAAE,CAAC;IAC5F,OAAO,CAAC,GAAG,CAAC,iBAAiB,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC;IAC9E,IAAI,KAAK,EAAE,CAAC;QACV,OAAO,CAAC,GAAG,CAAC,sBAAsB,KAAK,CAAC,GAAG,KAAK,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC;QACjE,OAAO,CAAC,GAAG,CAAC,eAAe,KAAK,CAAC,SAAS,EAAE,CAAC,CAAC;QAC9C,IAAI,KAAK,CAAC,eAAe;YAAE,OAAO,CAAC,GAAG,CAAC,mBAAmB,KAAK,CAAC,eAAe,EAAE,CAAC,CAAC;IACrF,CAAC;SAAM,CAAC;QACN,OAAO,CAAC,GAAG,CAAC,0BAA0B,CAAC,CAAC;IAC1C,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,OAA2B;IAC3D,MAAM,OAAO,GAAG,kBAAkB,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IACjD,MAAM,QAAQ,GAAG,MAAM,WAAW,CAChC,OAAO,EACP,iBAAiB,OAAO,CAAC,MAAM,0BAA0B,CAC1D,CAAC;IAEF,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC;QACjB,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;QAC/C,OAAO;IACT,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,oCAAoC,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;IAC3E,OAAO,CAAC,GAAG,CAAC,QAAQ,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAC5C,OAAO,CAAC,GAAG,CAAC,WAAW,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;IAClD,OAAO,CAAC,GAAG,CAAC,WAAW,QAAQ,CAAC,WAAW,CAAC,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC;IACpF,OAAO,CAAC,GAAG,CAAC,iBAAiB,MAAM,CAAC,QAAQ,CAAC,YAAY,CAAC,EAAE,CAAC,CAAC;IAC9D,IAAI,QAAQ,CAAC,OAAO,IAAI,OAAO,QAAQ,CAAC,OAAO,KAAK,QAAQ,EAAE,CAAC;QAC7D,OAAO,CAAC,GAAG,CAAC,YAAY,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;IAC9D,CAAC;AACH,CAAC"}
|
package/dist/config/schema.d.ts
CHANGED
|
@@ -5,6 +5,10 @@ export interface AgentConfig {
|
|
|
5
5
|
workdir?: string;
|
|
6
6
|
model?: string;
|
|
7
7
|
teams?: string[];
|
|
8
|
+
/** Team ID to assign this worker agent to on registration. Required for worker agents. */
|
|
9
|
+
teamId?: string;
|
|
10
|
+
/** agent_type sent to hub on registration. Defaults to "worker". */
|
|
11
|
+
agentType?: "worker" | "system" | "autonomous";
|
|
8
12
|
}
|
|
9
13
|
export interface Config {
|
|
10
14
|
apiKey: string;
|
|
@@ -62,6 +66,15 @@ export interface AgentState {
|
|
|
62
66
|
pendingHandoffOldestAgeMinutes?: number;
|
|
63
67
|
/** Most recent SLA alert timestamp */
|
|
64
68
|
pendingHandoffAlertAt?: string;
|
|
69
|
+
/**
|
|
70
|
+
* Last restart decision from the done-state guard (Epic #497).
|
|
71
|
+
* One of: "resumed" | "idle" | "blocked"
|
|
72
|
+
*/
|
|
73
|
+
lastRestartState?: string;
|
|
74
|
+
/** Human-readable reason for the last restart decision */
|
|
75
|
+
lastRestartReason?: string;
|
|
76
|
+
/** ISO timestamp of when the last restart decision was made */
|
|
77
|
+
lastRestartDecisionAt?: string;
|
|
65
78
|
}
|
|
66
79
|
export interface State {
|
|
67
80
|
agents: AgentState[];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"schema.js","sourceRoot":"","sources":["../../src/config/schema.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"schema.js","sourceRoot":"","sources":["../../src/config/schema.ts"],"names":[],"mappings":"AAwBA,MAAM,CAAC,MAAM,cAAc,GAAoB;IAC7C,MAAM,EAAE,yBAAyB;IACjC,QAAQ,EAAE;QACR,OAAO,EAAE,UAAU;QACnB,KAAK,EAAE,iBAAiB;KACzB;IACD,MAAM,EAAE,EAAE;CACX,CAAC;AAEF,MAAM,CAAC,MAAM,WAAW,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,IAAI,yBAAyB,CAAC;AACxE,MAAM,CAAC,MAAM,UAAU,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,IAAI,wBAAwB,CAAC"}
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OpenCode Auth Guard — Epics #470 + #490
|
|
3
|
+
*
|
|
4
|
+
* Implements symlink-first auth linking, startup preflight, schema validation,
|
|
5
|
+
* temp-path rejection, and periodic healthcheck to eliminate per-agent auth
|
|
6
|
+
* drift permanently and guard against runtime auth.type errors.
|
|
7
|
+
*
|
|
8
|
+
* Strategy:
|
|
9
|
+
* 1. Canonical store: ~/.local/share/opencode/auth.json
|
|
10
|
+
* 2. Per-agent auth: ~/.agentmesh/opencode-data/<agent>/opencode/auth.json
|
|
11
|
+
* -> Always a symlink pointing to canonical store (never a temp-path).
|
|
12
|
+
* -> If a stale regular file or temp-path symlink exists, replace safely.
|
|
13
|
+
* -> If canonical missing: write a validated real-file copy as fallback.
|
|
14
|
+
* 3. Schema validation: auth.json must contain a valid `type` field.
|
|
15
|
+
* 4. Startup preflight: validate before runner boot; one auto-repair attempt.
|
|
16
|
+
* 5. Periodic healthcheck: re-validate on interval + exponential backoff.
|
|
17
|
+
*/
|
|
18
|
+
export declare const CANONICAL_AUTH_PATH: string;
|
|
19
|
+
export declare const AGENTMESH_OPENCODE_DATA_ROOT: string;
|
|
20
|
+
export type AuthLinkStatus = "ok" | "repaired" | "degraded" | "no-canonical";
|
|
21
|
+
/** Structured result of auth schema validation (#490) */
|
|
22
|
+
export interface AuthSchemaValidation {
|
|
23
|
+
valid: boolean;
|
|
24
|
+
/** The raw parsed object, if parsing succeeded */
|
|
25
|
+
parsed?: Record<string, unknown>;
|
|
26
|
+
error?: string;
|
|
27
|
+
}
|
|
28
|
+
export interface AuthGuardResult {
|
|
29
|
+
status: AuthLinkStatus;
|
|
30
|
+
agentAuthPath: string;
|
|
31
|
+
canonicalAuthPath: string;
|
|
32
|
+
message: string;
|
|
33
|
+
}
|
|
34
|
+
export interface HealthCheckEvent {
|
|
35
|
+
type: "auth-health-ok" | "auth-health-degraded" | "auth-health-repaired";
|
|
36
|
+
agentName: string;
|
|
37
|
+
agentAuthPath: string;
|
|
38
|
+
message: string;
|
|
39
|
+
timestamp: string;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Returns the per-agent auth.json path.
|
|
43
|
+
*/
|
|
44
|
+
export declare function agentAuthPath(agentName: string): string;
|
|
45
|
+
/**
|
|
46
|
+
* Returns the per-agent opencode dir.
|
|
47
|
+
*/
|
|
48
|
+
export declare function agentOpencodeDir(agentName: string): string;
|
|
49
|
+
/**
|
|
50
|
+
* Validates that canonical auth.json exists and can be parsed as JSON.
|
|
51
|
+
*/
|
|
52
|
+
export declare function validateCanonicalAuth(canonicalPath?: string): boolean;
|
|
53
|
+
/**
|
|
54
|
+
* Checks whether agentAuthPath is already a valid symlink to a readable target.
|
|
55
|
+
*/
|
|
56
|
+
export declare function isValidAuthSymlink(authPath: string): boolean;
|
|
57
|
+
/**
|
|
58
|
+
* Returns true if the given path is a temp/ephemeral path that must not be
|
|
59
|
+
* used as an auth symlink target. (#490)
|
|
60
|
+
*/
|
|
61
|
+
export declare function isTempPath(p: string): boolean;
|
|
62
|
+
/**
|
|
63
|
+
* Validates that an auth.json file has the minimum required schema:
|
|
64
|
+
* - Parseable JSON
|
|
65
|
+
* - Contains a `type` field (string) — prevents `auth.type undefined` crash (#490)
|
|
66
|
+
*
|
|
67
|
+
* Reads from `authPath` (follows symlinks via readFileSync).
|
|
68
|
+
*/
|
|
69
|
+
export declare function validateAuthSchema(authPath: string): AuthSchemaValidation;
|
|
70
|
+
/**
|
|
71
|
+
* Checks if the symlink at authPath points to a temp path.
|
|
72
|
+
* Returns the target path if it's a temp path, null otherwise. (#490)
|
|
73
|
+
*/
|
|
74
|
+
export declare function getSymlinkTempTarget(authPath: string): string | null;
|
|
75
|
+
/**
|
|
76
|
+
* Writes a real validated auth file copy from canonical source. (#490)
|
|
77
|
+
*
|
|
78
|
+
* Used as fallback when canonical auth is present but symlinking fails,
|
|
79
|
+
* or as a recovery path when no persistent canonical exists yet.
|
|
80
|
+
* Strips non-Anthropic provider keys (e.g., xai) to keep agent minimal.
|
|
81
|
+
* Sets file permissions to 0o600.
|
|
82
|
+
*
|
|
83
|
+
* Returns true if written successfully.
|
|
84
|
+
*/
|
|
85
|
+
export declare function writeRealAuthFile(authPath: string, canonicalPath?: string): {
|
|
86
|
+
written: boolean;
|
|
87
|
+
backedUp?: string;
|
|
88
|
+
error?: string;
|
|
89
|
+
};
|
|
90
|
+
/**
|
|
91
|
+
* Safely replaces agentAuthPath with a symlink to canonicalPath.
|
|
92
|
+
* If a regular file already exists it is backed up first.
|
|
93
|
+
*/
|
|
94
|
+
export declare function linkAgentAuth(authPath: string, canonicalPath?: string): {
|
|
95
|
+
linked: boolean;
|
|
96
|
+
backedUp?: string;
|
|
97
|
+
error?: string;
|
|
98
|
+
};
|
|
99
|
+
/**
|
|
100
|
+
* Ensures the per-agent auth file is a valid symlink to canonical auth.
|
|
101
|
+
*
|
|
102
|
+
* Epics #470 + #490 hardening:
|
|
103
|
+
* - Rejects temp-path symlink targets (e.g., /tmp/...) and replaces them.
|
|
104
|
+
* - Validates auth schema (auth.type must be present) after linking.
|
|
105
|
+
* - Falls back to writeRealAuthFile() if symlinking fails but canonical is valid.
|
|
106
|
+
*
|
|
107
|
+
* Called from prepareOpenCodeRuntime() on every startup.
|
|
108
|
+
*/
|
|
109
|
+
export declare function ensureAgentAuthLink(agentName: string): AuthGuardResult;
|
|
110
|
+
/**
|
|
111
|
+
* Startup preflight: ensure auth link and validate once more.
|
|
112
|
+
*
|
|
113
|
+
* Returns true if auth is ready, false if agent should be marked degraded.
|
|
114
|
+
* Performs one auto-repair attempt on failure.
|
|
115
|
+
*/
|
|
116
|
+
export declare function preflightAgentAuth(agentName: string): {
|
|
117
|
+
ok: boolean;
|
|
118
|
+
result: AuthGuardResult;
|
|
119
|
+
};
|
|
120
|
+
export interface AuthHealthWatcher {
|
|
121
|
+
stop: () => void;
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* Starts a periodic auth healthcheck for an agent.
|
|
125
|
+
*
|
|
126
|
+
* On failure: emits a structured event and attempts repair.
|
|
127
|
+
* Uses exponential backoff up to MAX_BACKOFF_INTERVAL_MS on repeated failures.
|
|
128
|
+
*
|
|
129
|
+
* @param agentName Agent name
|
|
130
|
+
* @param onEvent Callback for health events (for structured logging/alerting)
|
|
131
|
+
*/
|
|
132
|
+
export declare function startAuthHealthWatcher(agentName: string, onEvent: (event: HealthCheckEvent) => void): AuthHealthWatcher;
|
|
133
|
+
export interface DoctorAgentReport {
|
|
134
|
+
agentName: string;
|
|
135
|
+
authPath: string;
|
|
136
|
+
isSymlink: boolean;
|
|
137
|
+
symlinkTarget: string | null;
|
|
138
|
+
isValid: boolean;
|
|
139
|
+
status: AuthLinkStatus;
|
|
140
|
+
message: string;
|
|
141
|
+
}
|
|
142
|
+
export interface DoctorReport {
|
|
143
|
+
canonicalAuthPath: string;
|
|
144
|
+
canonicalValid: boolean;
|
|
145
|
+
agents: DoctorAgentReport[];
|
|
146
|
+
overallOk: boolean;
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* Generates a diagnostic report for all agents (or a specific one).
|
|
150
|
+
* If `repair` is true, attempts to fix any broken links.
|
|
151
|
+
*/
|
|
152
|
+
export declare function runAuthDoctor(options: {
|
|
153
|
+
agentNames?: string[];
|
|
154
|
+
repair?: boolean;
|
|
155
|
+
}): DoctorReport;
|