@eventmodelers/cli 1.0.89 → 1.0.90
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/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@eventmodelers/cli",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.90",
|
|
4
4
|
"description": "Eventmodelers CLI — real-time Claude agent + skills for Claude Code, for any stack (Node, Supabase, Axon, OpenCQRS, UmaDB, Kurrent, or modeling-only)",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -28,21 +28,19 @@ async function fetchJSON(url, options) {
|
|
|
28
28
|
return res.json();
|
|
29
29
|
}
|
|
30
30
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
process.exit(1);
|
|
43
|
-
}
|
|
44
|
-
throw err;
|
|
31
|
+
// A 401 from the platform always means the token itself is missing, invalid or revoked (see
|
|
32
|
+
// requireApiToken on the platform) — retrying the same token can't fix that, and neither can
|
|
33
|
+
// waiting, so the first one ends the process with a message saying what to fix.
|
|
34
|
+
async function exitOn401(label, fn) {
|
|
35
|
+
try {
|
|
36
|
+
return await fn();
|
|
37
|
+
} catch (err) {
|
|
38
|
+
if (err instanceof HttpError && err.status === 401) {
|
|
39
|
+
console.error(`[agent] ${label} — 401, the token was rejected: ${err.message}`);
|
|
40
|
+
console.error('[agent] Check the token in .eventmodelers/config.json (or EVENTMODELERS_TOKEN) — shutting down');
|
|
41
|
+
process.exit(1);
|
|
45
42
|
}
|
|
43
|
+
throw err;
|
|
46
44
|
}
|
|
47
45
|
}
|
|
48
46
|
|
|
@@ -273,7 +271,7 @@ async function writeTask(payload, kitDir) {
|
|
|
273
271
|
|
|
274
272
|
async function handleSliceChanged(payload, cfg, kitDir, queueAllStatuses) {
|
|
275
273
|
console.log(`[agent] slice:changed — slice="${payload.sliceTitle}" status="${payload.sliceStatus}"`);
|
|
276
|
-
await
|
|
274
|
+
await exitOn401('fetchAndPersistSlices', () => fetchAndPersistSlices(cfg, kitDir)).catch((err) =>
|
|
277
275
|
console.error('[agent] Slice persist error:', err),
|
|
278
276
|
);
|
|
279
277
|
// This agent's own status writes (claim → InProgress, → Done, → Blocked) come straight back
|
|
@@ -295,9 +293,9 @@ async function handleSliceChanged(payload, cfg, kitDir, queueAllStatuses) {
|
|
|
295
293
|
}
|
|
296
294
|
|
|
297
295
|
async function startRealtimeAgent(cfg, kitDir, { agentType = 'BUILD', queueAllStatuses = false } = {}) {
|
|
298
|
-
let realtimeToken = await
|
|
296
|
+
let realtimeToken = await exitOn401('getRealtimeToken', () => getRealtimeToken(cfg));
|
|
299
297
|
|
|
300
|
-
await
|
|
298
|
+
await exitOn401('fetchAndPersistSlices', () => fetchAndPersistSlices(cfg, kitDir)).catch((err) =>
|
|
301
299
|
console.error('[agent] Initial slice fetch error:', err),
|
|
302
300
|
);
|
|
303
301
|
|
|
@@ -315,7 +313,7 @@ async function startRealtimeAgent(cfg, kitDir, { agentType = 'BUILD', queueAllSt
|
|
|
315
313
|
console.log(`[agent] ${ts()} Refreshing realtime token (reason: ${reason})...`);
|
|
316
314
|
refreshing = (async () => {
|
|
317
315
|
try {
|
|
318
|
-
realtimeToken = await
|
|
316
|
+
realtimeToken = await exitOn401('getRealtimeToken (refresh)', () => getRealtimeToken(cfg));
|
|
319
317
|
await realtime.setAuth(realtimeToken);
|
|
320
318
|
console.log(`[agent] ${ts()} Token refreshed (reason: ${reason}, took ${Date.now() - startedAt}ms)`);
|
|
321
319
|
} catch (err) {
|
|
@@ -335,7 +333,7 @@ async function startRealtimeAgent(cfg, kitDir, { agentType = 'BUILD', queueAllSt
|
|
|
335
333
|
// the cap used to leave the channel dead for good — the scheduled refresh only calls
|
|
336
334
|
// setAuth, it never re-joins — while the backoff alone keeps a genuinely revoked
|
|
337
335
|
// access from hammering the platform. A revoked token ends the process anyway, via
|
|
338
|
-
//
|
|
336
|
+
// exitOn401 inside refreshToken.
|
|
339
337
|
let channelErrorStreak = 0;
|
|
340
338
|
let resubscribeTimer = null;
|
|
341
339
|
const onChannelFailure = (reason) => {
|
|
@@ -383,7 +381,7 @@ async function startRealtimeAgent(cfg, kitDir, { agentType = 'BUILD', queueAllSt
|
|
|
383
381
|
// Broadcasts sent while the channel was down are gone. Re-read the slices once so a
|
|
384
382
|
// slice set to Planned during the gap still gets built — .slices/ is what ralphLoop
|
|
385
383
|
// picks Planned work from.
|
|
386
|
-
|
|
384
|
+
exitOn401('fetchAndPersistSlices (after reconnect)', () => fetchAndPersistSlices(cfg, kitDir)).catch((err) =>
|
|
387
385
|
console.error(`[agent] ${ts()} Slice re-fetch after reconnect failed:`, err),
|
|
388
386
|
);
|
|
389
387
|
},
|
|
@@ -642,7 +640,7 @@ async function ralphLoop(kitDir, cfg, onTask, onPlannedSlice, localOnly = false)
|
|
|
642
640
|
|
|
643
641
|
// ── Public API ────────────────────────────────────────────────────────────────
|
|
644
642
|
|
|
645
|
-
export { loadLocalConfig, fetchPlatformConfig,
|
|
643
|
+
export { loadLocalConfig, fetchPlatformConfig, exitOn401, startRealtimeAgent };
|
|
646
644
|
|
|
647
645
|
// Who this process is. RALPH_AGENT_ID/RALPH_AGENT_NAME are `eventmodelers run --id/--name`,
|
|
648
646
|
// passed down as env (see cli.js's run dispatcher): a per-run identity override so a second
|
|
@@ -676,7 +674,7 @@ export async function startRalph({ kitDir, projectDir, onTask, onPlannedSlice, a
|
|
|
676
674
|
return;
|
|
677
675
|
}
|
|
678
676
|
|
|
679
|
-
const cfg = await
|
|
677
|
+
const cfg = await exitOn401('fetchPlatformConfig', () => fetchPlatformConfig(local));
|
|
680
678
|
console.log(` org=${cfg.organizationId}, board=${cfg.boardId}, base=${cfg.baseUrl}\n`);
|
|
681
679
|
|
|
682
680
|
await Promise.all([
|
|
@@ -4,14 +4,14 @@
|
|
|
4
4
|
// only need this if you want to run the agent independently (e.g. separate terminal).
|
|
5
5
|
// Usage: node realtime-agent.js [kit_dir]
|
|
6
6
|
|
|
7
|
-
import { loadLocalConfig, fetchPlatformConfig,
|
|
7
|
+
import { loadLocalConfig, fetchPlatformConfig, exitOn401, startRealtimeAgent } from './lib/ralph.js';
|
|
8
8
|
import { dirname, resolve } from 'path';
|
|
9
9
|
import { fileURLToPath } from 'url';
|
|
10
10
|
|
|
11
11
|
const kitDir = process.argv[2] ? resolve(process.argv[2]) : dirname(fileURLToPath(import.meta.url));
|
|
12
12
|
|
|
13
13
|
const local = loadLocalConfig(kitDir);
|
|
14
|
-
const cfg = await
|
|
14
|
+
const cfg = await exitOn401('fetchPlatformConfig', () => fetchPlatformConfig(local));
|
|
15
15
|
|
|
16
16
|
console.log(`[agent] Starting — org=${cfg.organizationId}${cfg.boardId ? `, board=${cfg.boardId}` : ''}, base=${cfg.baseUrl}`);
|
|
17
17
|
|