@onepointfour-packs/flaredeck-agent 0.2.209 → 0.2.211
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/agent.js +2 -1
- package/dist/agent.js.map +1 -1
- package/dist/assistant.d.ts +1 -1
- package/dist/assistant.js +4 -2
- package/dist/assistant.js.map +1 -1
- package/dist/check.d.ts +32 -0
- package/dist/check.js +251 -0
- package/dist/check.js.map +1 -0
- package/dist/config.d.ts +8 -0
- package/dist/config.js.map +1 -1
- package/dist/environment.d.ts +13 -3
- package/dist/environment.js +25 -15
- package/dist/environment.js.map +1 -1
- package/dist/envtools.d.ts +29 -0
- package/dist/envtools.js +67 -5
- package/dist/envtools.js.map +1 -1
- package/dist/features/card-folder.d.ts +69 -0
- package/dist/features/card-folder.js +305 -0
- package/dist/features/card-folder.js.map +1 -0
- package/dist/features/chat.d.ts +45 -0
- package/dist/features/chat.js +90 -0
- package/dist/features/chat.js.map +1 -0
- package/dist/features/dispatch.d.ts +55 -0
- package/dist/features/dispatch.js +101 -0
- package/dist/features/dispatch.js.map +1 -0
- package/dist/features/hand-back.d.ts +60 -0
- package/dist/features/hand-back.js +127 -0
- package/dist/features/hand-back.js.map +1 -0
- package/dist/features/manage-pane.d.ts +31 -0
- package/dist/features/manage-pane.js +60 -0
- package/dist/features/manage-pane.js.map +1 -0
- package/dist/features/release-wiring.d.ts +18 -0
- package/dist/features/release-wiring.js +56 -0
- package/dist/features/release-wiring.js.map +1 -0
- package/dist/features/services.d.ts +45 -0
- package/dist/features/services.js +147 -0
- package/dist/features/services.js.map +1 -0
- package/dist/features/sign-in-request.d.ts +81 -0
- package/dist/features/sign-in-request.js +91 -0
- package/dist/features/sign-in-request.js.map +1 -0
- package/dist/github.d.ts +14 -0
- package/dist/github.js +39 -8
- package/dist/github.js.map +1 -1
- package/dist/harness/events.d.ts +58 -0
- package/dist/harness/events.js +126 -0
- package/dist/harness/events.js.map +1 -0
- package/dist/harness/handover.d.ts +39 -0
- package/dist/harness/handover.js +63 -0
- package/dist/harness/handover.js.map +1 -0
- package/dist/harness/pause.d.ts +67 -0
- package/dist/harness/pause.js +128 -0
- package/dist/harness/pause.js.map +1 -0
- package/dist/harness/plan-usage.d.ts +49 -0
- package/dist/harness/plan-usage.js +69 -0
- package/dist/harness/plan-usage.js.map +1 -0
- package/dist/harness/prompt.d.ts +59 -0
- package/dist/harness/prompt.js +289 -0
- package/dist/harness/prompt.js.map +1 -0
- package/dist/harness/repo-notes.d.ts +1 -0
- package/dist/harness/repo-notes.js +26 -0
- package/dist/harness/repo-notes.js.map +1 -0
- package/dist/harness/restarter.d.ts +33 -0
- package/dist/harness/restarter.js +78 -0
- package/dist/harness/restarter.js.map +1 -0
- package/dist/harness/start-scripts.d.ts +7 -0
- package/dist/harness/start-scripts.js +44 -0
- package/dist/harness/start-scripts.js.map +1 -0
- package/dist/harness/tools.d.ts +37 -0
- package/dist/harness/tools.js +17 -0
- package/dist/harness/tools.js.map +1 -0
- package/dist/hydrate.d.ts +5 -0
- package/dist/hydrate.js +1 -0
- package/dist/hydrate.js.map +1 -1
- package/dist/main.js +32 -1
- package/dist/main.js.map +1 -1
- package/dist/profile.d.ts +80 -0
- package/dist/profile.js +77 -0
- package/dist/profile.js.map +1 -0
- package/dist/release.js +3 -0
- package/dist/release.js.map +1 -1
- package/dist/sandbox.js +3 -1
- package/dist/sandbox.js.map +1 -1
- package/dist/serve.d.ts +21 -115
- package/dist/serve.js +971 -1612
- package/dist/serve.js.map +1 -1
- package/dist/stream.d.ts +5 -0
- package/dist/stream.js.map +1 -1
- package/dist/workspace.d.ts +6 -0
- package/dist/workspace.js +19 -0
- package/dist/workspace.js.map +1 -1
- package/dist/worktree.d.ts +55 -2
- package/dist/worktree.js +130 -5
- package/dist/worktree.js.map +1 -1
- package/package.json +2 -2
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* When a card session ends, whether it writes a handover note to the card, and on which plan.
|
|
3
|
+
* Split out of serve.ts (docs/spec-harness-profiles.md, step 2).
|
|
4
|
+
*/
|
|
5
|
+
/** Tools that only look: reading files, searching, asking FlareDeck or a service what is there. */
|
|
6
|
+
export function onlyLooks(tool) {
|
|
7
|
+
if (['Read', 'Grep', 'Glob', 'LS', 'ToolSearch', 'TodoWrite', 'TaskOutput', 'LSP', 'WebFetch', 'WebSearch', 'Monitor', 'Skill'].includes(tool))
|
|
8
|
+
return true;
|
|
9
|
+
const op = tool.startsWith('mcp__') ? tool.split('__').slice(2).join('__') : '';
|
|
10
|
+
return /^(get|find|list|read|search|health|hello|whats|check|describe|site_map|see_screen|browser_look|browser_screenshot|browser_events|pull_request_status|preview)/i.test(op);
|
|
11
|
+
}
|
|
12
|
+
/** Record a tool call against the session it ran in. */
|
|
13
|
+
export function noteHandoverTool(logs, key, tool, at) {
|
|
14
|
+
const l = logs.get(key) ?? {};
|
|
15
|
+
if (/__set-card-notes$/.test(tool))
|
|
16
|
+
l.notesAt = at;
|
|
17
|
+
else if (!onlyLooks(tool))
|
|
18
|
+
l.changedAt = at;
|
|
19
|
+
logs.set(key, l);
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Whether a session ending needs a handover note: it changed something, after its last notes.
|
|
23
|
+
* Unknown (no record) is treated as needed, as before.
|
|
24
|
+
*/
|
|
25
|
+
export function handoverNeeded(l) {
|
|
26
|
+
if (!l)
|
|
27
|
+
return true;
|
|
28
|
+
if (!l.changedAt)
|
|
29
|
+
return false;
|
|
30
|
+
return !l.notesAt || l.changedAt > l.notesAt;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Whether a worker's card has gone to someone else, so its notes are no longer the worker's to
|
|
34
|
+
* write. FlareDeck refuses them (set-card-notes: "not assigned to you"), and the handover turn
|
|
35
|
+
* reopened a whole session only to be told so — CASE on HR-1128, TARS on HR-1141 (20 Oct).
|
|
36
|
+
* Unknown (no card, no assignee, no id) is not "someone else": the handover runs as before.
|
|
37
|
+
*/
|
|
38
|
+
export function cardWentElsewhere(card, selfId) {
|
|
39
|
+
const holder = card?.assigned_to?.uid;
|
|
40
|
+
return !!selfId && !!holder && holder !== selfId;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Which Claude token a handover runs on: a fresh pick from FlareDeck, because the plan the turn
|
|
44
|
+
* used may have run out since; the turn's own plan when FlareDeck cannot be asked; 'none' when
|
|
45
|
+
* every plan is spent; null to fall back to this machine's own login (no subscriptions set up).
|
|
46
|
+
*/
|
|
47
|
+
export async function handoverSubscription(subs, lastUsed) {
|
|
48
|
+
try {
|
|
49
|
+
const s = await subs();
|
|
50
|
+
if (!s)
|
|
51
|
+
return lastUsed ?? null;
|
|
52
|
+
const pick = await s.choose([]);
|
|
53
|
+
if (pick.use === 'token' && pick.token)
|
|
54
|
+
return pick.token;
|
|
55
|
+
if (pick.use === 'none')
|
|
56
|
+
return 'none';
|
|
57
|
+
return lastUsed ?? null;
|
|
58
|
+
}
|
|
59
|
+
catch {
|
|
60
|
+
return lastUsed ?? null;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
//# sourceMappingURL=handover.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"handover.js","sourceRoot":"","sources":["../../src/harness/handover.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,mGAAmG;AACnG,MAAM,UAAU,SAAS,CAAC,IAAY;IACpC,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,YAAY,EAAE,WAAW,EAAE,YAAY,EAAE,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,SAAS,EAAE,OAAO,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC;QAAE,OAAO,IAAI,CAAC;IAC5J,MAAM,EAAE,GAAG,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IAChF,OAAO,gKAAgK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;AACnL,CAAC;AAED,wDAAwD;AACxD,MAAM,UAAU,gBAAgB,CAAC,IAA8B,EAAE,GAAW,EAAE,IAAY,EAAE,EAAU;IACpG,MAAM,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC;IAC9B,IAAI,mBAAmB,CAAC,IAAI,CAAC,IAAI,CAAC;QAAE,CAAC,CAAC,OAAO,GAAG,EAAE,CAAC;SAC9C,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC;QAAE,CAAC,CAAC,SAAS,GAAG,EAAE,CAAC;IAC5C,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;AACnB,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,cAAc,CAAC,CAA0B;IACvD,IAAI,CAAC,CAAC;QAAE,OAAO,IAAI,CAAC;IACpB,IAAI,CAAC,CAAC,CAAC,SAAS;QAAE,OAAO,KAAK,CAAC;IAC/B,OAAO,CAAC,CAAC,CAAC,OAAO,IAAI,CAAC,CAAC,SAAS,GAAG,CAAC,CAAC,OAAO,CAAC;AAC/C,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,iBAAiB,CAAC,IAAkE,EAAE,MAAc;IAClH,MAAM,MAAM,GAAG,IAAI,EAAE,WAAW,EAAE,GAAG,CAAC;IACtC,OAAO,CAAC,CAAC,MAAM,IAAI,CAAC,CAAC,MAAM,IAAI,MAAM,KAAK,MAAM,CAAC;AACnD,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,oBAAoB,CACxC,IAAqG,EACrG,QAA4B;IAE5B,IAAI,CAAC;QACH,MAAM,CAAC,GAAG,MAAM,IAAI,EAAE,CAAC;QACvB,IAAI,CAAC,CAAC;YAAE,OAAO,QAAQ,IAAI,IAAI,CAAC;QAChC,MAAM,IAAI,GAAG,MAAM,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;QAChC,IAAI,IAAI,CAAC,GAAG,KAAK,OAAO,IAAI,IAAI,CAAC,KAAK;YAAE,OAAO,IAAI,CAAC,KAAK,CAAC;QAC1D,IAAI,IAAI,CAAC,GAAG,KAAK,MAAM;YAAE,OAAO,MAAM,CAAC;QACvC,OAAO,QAAQ,IAAI,IAAI,CAAC;IAC1B,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,QAAQ,IAAI,IAAI,CAAC;IAC1B,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Paused: a wall this agent cannot get past by itself — GitHub refusing it, a required MCP server
|
|
3
|
+
* not connected, the disk full — so it does no work at all, no turns and no tokens, until it is
|
|
4
|
+
* resumed. See flaredeck-mcp/src/mcp/pause.ts for the why.
|
|
5
|
+
*
|
|
6
|
+
* Who resumes it: a wall that clears on its own (disk, MCP) is resumed by the agent the moment it
|
|
7
|
+
* clears; one that needs a person (GitHub) is reported fixed to the lead, once, and the lead
|
|
8
|
+
* resumes it — or, with no lead to ask, the agent resumes itself.
|
|
9
|
+
* Split out of serve.ts (docs/spec-harness-profiles.md, step 2).
|
|
10
|
+
*/
|
|
11
|
+
export type Wall = {
|
|
12
|
+
check: string;
|
|
13
|
+
reason: string;
|
|
14
|
+
};
|
|
15
|
+
/** FlareDeck's record of the pause (flaredeck.ts). */
|
|
16
|
+
export type PauseRecord = {
|
|
17
|
+
pauseState: () => Promise<{
|
|
18
|
+
check: string;
|
|
19
|
+
reason: string;
|
|
20
|
+
since: string;
|
|
21
|
+
ready?: boolean;
|
|
22
|
+
} | null>;
|
|
23
|
+
pause: (check: string, reason: string) => Promise<{
|
|
24
|
+
already: boolean;
|
|
25
|
+
handedBack: string[];
|
|
26
|
+
lead: string | null;
|
|
27
|
+
}>;
|
|
28
|
+
resumeSelf: () => Promise<{
|
|
29
|
+
resumed: boolean;
|
|
30
|
+
why?: string;
|
|
31
|
+
}>;
|
|
32
|
+
ready: () => Promise<void>;
|
|
33
|
+
};
|
|
34
|
+
export type PauseDeps = {
|
|
35
|
+
/** Undefined when this harness has no FlareDeck REST access: nothing is recorded or asked. */
|
|
36
|
+
record: PauseRecord | undefined;
|
|
37
|
+
/** The walls, checked in code — never by asking the model. Null: none. */
|
|
38
|
+
walls: () => Promise<Wall | null>;
|
|
39
|
+
/** A wall that clears on its own, checked every minute: null while it stands, else what cleared it. */
|
|
40
|
+
cleared: (check: 'disk' | 'mcp') => Promise<string | null>;
|
|
41
|
+
hasLead: () => boolean;
|
|
42
|
+
/** Stop the turn running now, if any. */
|
|
43
|
+
stopRun: () => void;
|
|
44
|
+
/** What the pane shows: the reason while paused, undefined when not. */
|
|
45
|
+
show: (reason: string | undefined) => void;
|
|
46
|
+
/** Back to work: pick up the card in progress or the next one. */
|
|
47
|
+
resume: () => void;
|
|
48
|
+
log: (kind: 'warn' | 'event', text: string) => void;
|
|
49
|
+
now?: () => number;
|
|
50
|
+
};
|
|
51
|
+
/** The walls slower to check (they ask GitHub) are looked at again this often while paused. */
|
|
52
|
+
export declare const WALL_RECHECK_MS: number;
|
|
53
|
+
export declare function createPause(d: PauseDeps): {
|
|
54
|
+
paused: () => Wall | null;
|
|
55
|
+
enter: (wall: Wall) => Promise<void>;
|
|
56
|
+
/**
|
|
57
|
+
* At start, before any card is picked up. A restart while paused picks the pause back up from
|
|
58
|
+
* FlareDeck rather than re-announcing it — and checks the wall now, not in ten minutes: a
|
|
59
|
+
* restart is often BECAUSE somebody fixed it (C3PO, 16 Oct, sat paused for a lead it lacks).
|
|
60
|
+
*/
|
|
61
|
+
start(): Promise<void>;
|
|
62
|
+
/**
|
|
63
|
+
* Every minute while paused: has the lead resumed it (one REST call, no model)? Has a wall that
|
|
64
|
+
* clears on its own cleared? Every ten minutes, are the other walls gone?
|
|
65
|
+
*/
|
|
66
|
+
tick(): Promise<void>;
|
|
67
|
+
};
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Paused: a wall this agent cannot get past by itself — GitHub refusing it, a required MCP server
|
|
3
|
+
* not connected, the disk full — so it does no work at all, no turns and no tokens, until it is
|
|
4
|
+
* resumed. See flaredeck-mcp/src/mcp/pause.ts for the why.
|
|
5
|
+
*
|
|
6
|
+
* Who resumes it: a wall that clears on its own (disk, MCP) is resumed by the agent the moment it
|
|
7
|
+
* clears; one that needs a person (GitHub) is reported fixed to the lead, once, and the lead
|
|
8
|
+
* resumes it — or, with no lead to ask, the agent resumes itself.
|
|
9
|
+
* Split out of serve.ts (docs/spec-harness-profiles.md, step 2).
|
|
10
|
+
*/
|
|
11
|
+
/** The walls slower to check (they ask GitHub) are looked at again this often while paused. */
|
|
12
|
+
export const WALL_RECHECK_MS = 10 * 60 * 1000;
|
|
13
|
+
export function createPause(d) {
|
|
14
|
+
const now = d.now ?? Date.now;
|
|
15
|
+
let paused = null;
|
|
16
|
+
let readyReported = false;
|
|
17
|
+
let lastWallCheck = 0;
|
|
18
|
+
const unpause = (why) => {
|
|
19
|
+
d.log('event', why);
|
|
20
|
+
paused = null;
|
|
21
|
+
readyReported = false;
|
|
22
|
+
d.show(undefined);
|
|
23
|
+
d.resume();
|
|
24
|
+
};
|
|
25
|
+
/** The wall is gone. No lead to ask: resume. Otherwise tell the lead, once, and wait. */
|
|
26
|
+
const fixed = async (check) => {
|
|
27
|
+
if (!d.hasLead()) {
|
|
28
|
+
const r = await d.record?.resumeSelf().catch(() => null);
|
|
29
|
+
if (r?.resumed) {
|
|
30
|
+
unpause(`${check} is fixed — resumed myself (no lead to ask)`);
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
if (readyReported)
|
|
35
|
+
return;
|
|
36
|
+
readyReported = true;
|
|
37
|
+
d.log('event', `${check} is fixed — told the lead; waiting to be resumed`);
|
|
38
|
+
await d.record?.ready().catch(() => { });
|
|
39
|
+
};
|
|
40
|
+
const enter = async (wall) => {
|
|
41
|
+
if (paused?.check === wall.check)
|
|
42
|
+
return;
|
|
43
|
+
paused = wall;
|
|
44
|
+
readyReported = false;
|
|
45
|
+
d.show(wall.reason);
|
|
46
|
+
d.log('warn', `PAUSED (${wall.check}): ${wall.reason}`);
|
|
47
|
+
d.stopRun();
|
|
48
|
+
try {
|
|
49
|
+
const r = await d.record?.pause(wall.check, wall.reason);
|
|
50
|
+
/* A solo agent has no lead: its cards stay with it (each gets a comment) and nobody is
|
|
51
|
+
messaged. "told the lead, handed back …" would describe something that never happened. */
|
|
52
|
+
if (r && !r.already) {
|
|
53
|
+
d.log('event', r.lead
|
|
54
|
+
? `told the lead${r.handedBack.length ? `, handed back ${r.handedBack.join(', ')}` : ''} — doing nothing until resumed`
|
|
55
|
+
: `no lead to tell — ${r.handedBack.length ? `left a note on ${r.handedBack.join(', ')}; they stay mine` : 'nothing handed back'}. ${wall.check === 'disk' ? 'I resume myself once the disk is clear.' : wall.check === 'mcp' ? 'I resume myself once it is connected.' : 'A person resumes me.'}`);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
catch (e) {
|
|
59
|
+
d.log('warn', `could not tell FlareDeck I am paused: ${e instanceof Error ? e.message : String(e)}`);
|
|
60
|
+
}
|
|
61
|
+
};
|
|
62
|
+
return {
|
|
63
|
+
paused: () => paused,
|
|
64
|
+
enter,
|
|
65
|
+
/**
|
|
66
|
+
* At start, before any card is picked up. A restart while paused picks the pause back up from
|
|
67
|
+
* FlareDeck rather than re-announcing it — and checks the wall now, not in ten minutes: a
|
|
68
|
+
* restart is often BECAUSE somebody fixed it (C3PO, 16 Oct, sat paused for a lead it lacks).
|
|
69
|
+
*/
|
|
70
|
+
async start() {
|
|
71
|
+
const server = await d.record?.pauseState().catch(() => undefined);
|
|
72
|
+
if (server) {
|
|
73
|
+
paused = { check: server.check, reason: server.reason };
|
|
74
|
+
readyReported = !!server.ready;
|
|
75
|
+
d.show(server.reason);
|
|
76
|
+
d.log('warn', `PAUSED since ${server.since.slice(0, 16).replace('T', ' ')} (${server.check}) — doing nothing until the lead resumes me`);
|
|
77
|
+
if (!(await d.walls())) {
|
|
78
|
+
lastWallCheck = now();
|
|
79
|
+
await fixed(server.check);
|
|
80
|
+
}
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
const wall = await d.walls();
|
|
84
|
+
if (wall)
|
|
85
|
+
await enter(wall);
|
|
86
|
+
},
|
|
87
|
+
/**
|
|
88
|
+
* Every minute while paused: has the lead resumed it (one REST call, no model)? Has a wall that
|
|
89
|
+
* clears on its own cleared? Every ten minutes, are the other walls gone?
|
|
90
|
+
*/
|
|
91
|
+
async tick() {
|
|
92
|
+
if (!paused)
|
|
93
|
+
return;
|
|
94
|
+
const server = await d.record?.pauseState().catch(() => undefined);
|
|
95
|
+
if (server === null) {
|
|
96
|
+
const still = await d.walls();
|
|
97
|
+
if (still) {
|
|
98
|
+
paused = null;
|
|
99
|
+
await enter(still);
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
102
|
+
unpause('resumed by the lead — back to work');
|
|
103
|
+
return;
|
|
104
|
+
}
|
|
105
|
+
/* Disk is a statfs call, so it is checked every tick; MCP is one HTTP call. A wall that has
|
|
106
|
+
cleared resumes the agent at once — there is nothing for a lead to decide about a number,
|
|
107
|
+
and waiting for one left the agent idle for hours after the space had been freed. */
|
|
108
|
+
const selfClearing = paused.check === 'disk' || paused.check === 'mcp';
|
|
109
|
+
if (selfClearing) {
|
|
110
|
+
const cleared = await d.cleared(paused.check);
|
|
111
|
+
if (!cleared)
|
|
112
|
+
return;
|
|
113
|
+
const r = await d.record?.resumeSelf().catch(() => null);
|
|
114
|
+
if (r?.resumed) {
|
|
115
|
+
unpause(`${cleared} — resumed myself and told the lead`);
|
|
116
|
+
return;
|
|
117
|
+
}
|
|
118
|
+
// An older server without self-resume: fall through to telling the lead, as before.
|
|
119
|
+
}
|
|
120
|
+
if ((!selfClearing && now() - lastWallCheck < WALL_RECHECK_MS) || readyReported)
|
|
121
|
+
return;
|
|
122
|
+
lastWallCheck = now();
|
|
123
|
+
if (!(await d.walls()))
|
|
124
|
+
await fixed(paused.check);
|
|
125
|
+
},
|
|
126
|
+
};
|
|
127
|
+
}
|
|
128
|
+
//# sourceMappingURL=pause.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pause.js","sourceRoot":"","sources":["../../src/harness/pause.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A turn's Claude subscription: what it reports to FlareDeck's ledger while it runs, and whether
|
|
3
|
+
* the turn has to run again on another one when it is over.
|
|
4
|
+
* Split out of serve.ts (docs/spec-harness-profiles.md, step 2).
|
|
5
|
+
*/
|
|
6
|
+
import type { AgentEvent } from '../agent.js';
|
|
7
|
+
import { CouldNotWork } from '../engine.js';
|
|
8
|
+
import type { SubscriptionsClient } from '../subscriptions.js';
|
|
9
|
+
/** The run failed on its Claude subscription — capped or token rejected — not on its work. */
|
|
10
|
+
export declare class RetryOnAnotherPlan extends CouldNotWork {
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* How many plans one event may switch through. Each retry spends one plan, so the plans that exist
|
|
14
|
+
* bound it already; this is the backstop.
|
|
15
|
+
*/
|
|
16
|
+
export declare const MAX_PLAN_SWITCHES = 4;
|
|
17
|
+
/** A rejected token, as the CLI words it — not capacity, so never filed as spent. */
|
|
18
|
+
export declare const TOKEN_REJECTED: RegExp;
|
|
19
|
+
export type PlanUsageDeps = {
|
|
20
|
+
/** The plan this turn runs on; null when it runs on this machine's own login. */
|
|
21
|
+
plan: {
|
|
22
|
+
id: string;
|
|
23
|
+
label: string;
|
|
24
|
+
} | null;
|
|
25
|
+
subs: Pick<SubscriptionsClient, 'spent' | 'seen'> | null;
|
|
26
|
+
/**
|
|
27
|
+
* Plans that failed on an event, by event id, so its retry is offered a different one. A plan
|
|
28
|
+
* that hit its cap or had its token rejected used to fail the card while the other plans sat
|
|
29
|
+
* unused; now the event goes straight back on the queue and `choose` is told what not to offer.
|
|
30
|
+
*/
|
|
31
|
+
failed: Map<string, string[]>;
|
|
32
|
+
eventId: string;
|
|
33
|
+
/** What the turn was on, for the ledger's note. */
|
|
34
|
+
during: string;
|
|
35
|
+
log: (kind: 'warn', text: string) => void;
|
|
36
|
+
/** The run reported its plan's usage itself, so no separate read is needed after it. */
|
|
37
|
+
onSeen: () => void;
|
|
38
|
+
};
|
|
39
|
+
export declare function planUsage(d: PlanUsageDeps): {
|
|
40
|
+
/** Every event of the run. Reported, never interpreted here. */
|
|
41
|
+
observe(out: AgentEvent): void;
|
|
42
|
+
/**
|
|
43
|
+
* The run is over. The plan failed, not the work: throw RetryOnAnotherPlan so the event runs
|
|
44
|
+
* again now, on another plan. A spent window was filed above (awaited here, so `choose` sees
|
|
45
|
+
* it); a rejected token — a mis-pasted or revoked setup-token — is excluded for this event and
|
|
46
|
+
* said plainly. The retry resumes the same session, so work done in the turn is not lost.
|
|
47
|
+
*/
|
|
48
|
+
settle(runError: unknown, doneText: string): Promise<void>;
|
|
49
|
+
};
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { CouldNotWork } from '../engine.js';
|
|
2
|
+
/** The run failed on its Claude subscription — capped or token rejected — not on its work. */
|
|
3
|
+
export class RetryOnAnotherPlan extends CouldNotWork {
|
|
4
|
+
}
|
|
5
|
+
/**
|
|
6
|
+
* How many plans one event may switch through. Each retry spends one plan, so the plans that exist
|
|
7
|
+
* bound it already; this is the backstop.
|
|
8
|
+
*/
|
|
9
|
+
export const MAX_PLAN_SWITCHES = 4;
|
|
10
|
+
/** A rejected token, as the CLI words it — not capacity, so never filed as spent. */
|
|
11
|
+
export const TOKEN_REJECTED = /API Error: 401|invalid bearer token|OAuth token has expired|OAuth token (was )?revoked/i;
|
|
12
|
+
export function planUsage(d) {
|
|
13
|
+
/**
|
|
14
|
+
* One cap is usually seen two or three times in a run: the structured `rate_limit_event` (which
|
|
15
|
+
* knows the window and the reset), then the error on the assistant message and the result text
|
|
16
|
+
* (which know neither). Reporting all of them filed an `unknown` window with a guessed five-hour
|
|
17
|
+
* block on top of the real one — keeping a plan out hours past its reset. Once a named window is
|
|
18
|
+
* reported, the anonymous echoes are dropped.
|
|
19
|
+
*/
|
|
20
|
+
let spentNamed = false;
|
|
21
|
+
let spentAny = false;
|
|
22
|
+
const reports = [];
|
|
23
|
+
return {
|
|
24
|
+
/** Every event of the run. Reported, never interpreted here. */
|
|
25
|
+
observe(out) {
|
|
26
|
+
if (out.kind !== 'limits' || !d.plan)
|
|
27
|
+
return;
|
|
28
|
+
/* 'allowed_warning' arrives while the plan still works — treating it as spent would retire
|
|
29
|
+
every subscription at about half capacity, with each account still having headroom. */
|
|
30
|
+
if (out.spent) {
|
|
31
|
+
const named = !!out.window && out.window !== 'unknown';
|
|
32
|
+
spentAny = true;
|
|
33
|
+
if (named || !spentNamed) {
|
|
34
|
+
spentNamed ||= named;
|
|
35
|
+
reports.push(d.subs?.spent(d.plan.id, out.window, out.resetsAt, out.why ?? `hit during ${d.during}`) ?? Promise.resolve());
|
|
36
|
+
d.log('warn', `claude: ${d.plan.label} hit its ${out.window ?? 'usage'} limit (${out.source ?? 'unknown signal'})`);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
else if (out.window && typeof out.utilization === 'number') {
|
|
40
|
+
d.onSeen();
|
|
41
|
+
void d.subs?.seen(d.plan.id, out.window, out.utilization, out.resetsAt);
|
|
42
|
+
}
|
|
43
|
+
},
|
|
44
|
+
/**
|
|
45
|
+
* The run is over. The plan failed, not the work: throw RetryOnAnotherPlan so the event runs
|
|
46
|
+
* again now, on another plan. A spent window was filed above (awaited here, so `choose` sees
|
|
47
|
+
* it); a rejected token — a mis-pasted or revoked setup-token — is excluded for this event and
|
|
48
|
+
* said plainly. The retry resumes the same session, so work done in the turn is not lost.
|
|
49
|
+
*/
|
|
50
|
+
async settle(runError, doneText) {
|
|
51
|
+
if (d.plan) {
|
|
52
|
+
const said = `${runError instanceof Error ? runError.message : runError ?? ''} ${doneText}`;
|
|
53
|
+
const rejected = TOKEN_REJECTED.test(said);
|
|
54
|
+
if (rejected || spentAny) {
|
|
55
|
+
await Promise.allSettled(reports);
|
|
56
|
+
const tried = [...(d.failed.get(d.eventId) ?? []), d.plan.id];
|
|
57
|
+
if (rejected)
|
|
58
|
+
d.log('warn', `claude: ${d.plan.label} — its token was rejected. Replace it on Integrations → Secrets.`);
|
|
59
|
+
if (tried.length <= MAX_PLAN_SWITCHES) {
|
|
60
|
+
d.failed.set(d.eventId, tried);
|
|
61
|
+
throw new RetryOnAnotherPlan(`${d.plan.label} ${rejected ? 'rejected its token' : 'is at its limit'} — switching subscription and trying again`);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
d.failed.delete(d.eventId);
|
|
66
|
+
},
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
//# sourceMappingURL=plan-usage.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plan-usage.js","sourceRoot":"","sources":["../../src/harness/plan-usage.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* What a turn is told: the prompt for an event, and the standing briefs for a lead and a manager.
|
|
3
|
+
* Split out of serve.ts (docs/spec-harness-profiles.md, step 2).
|
|
4
|
+
*/
|
|
5
|
+
import type { StreamEvent } from '../stream.js';
|
|
6
|
+
import type { Profile } from '../profile.js';
|
|
7
|
+
import { type AssistantPerson } from '../assistant.js';
|
|
8
|
+
/**
|
|
9
|
+
* What the agent is actually asked.
|
|
10
|
+
*
|
|
11
|
+
* The event's own one-line rendering is the instruction — it already says what happened and to
|
|
12
|
+
* whom — with only enough added to make clear that acting is expected and that stopping quietly
|
|
13
|
+
* is not an option.
|
|
14
|
+
*/
|
|
15
|
+
/** What a pull request should target — the repo's own default, not a guess. */
|
|
16
|
+
/**
|
|
17
|
+
* A few words for the pane from a needs-human reason: its first sentence, without a leading
|
|
18
|
+
* "1." — a reason written as a numbered list was shown as "waiting on a person (1)".
|
|
19
|
+
*/
|
|
20
|
+
export declare function parkLabel(reason: string): string;
|
|
21
|
+
export declare const LEAD_SWEEP_GOAL: string;
|
|
22
|
+
/**
|
|
23
|
+
* What a manager is told on every turn, on top of its own description in FlareDeck.
|
|
24
|
+
*
|
|
25
|
+
* It says what this harness gives a manager TODAY and, as plainly, what it does not yet stop:
|
|
26
|
+
* the approval, heads-up and escalation steps of docs/spec-manager-role.md are not built, so the
|
|
27
|
+
* limits below are instructions rather than guards. They come out as each guard goes in.
|
|
28
|
+
*/
|
|
29
|
+
export declare const MANAGER_BRIEF: string;
|
|
30
|
+
/** A manager's regular check is of its TEAMS, not of cards assigned to it. */
|
|
31
|
+
export declare const MANAGER_SWEEP_BRIEF: string;
|
|
32
|
+
/** For a lead handed a card in a folder with no code of its own. See leadWithoutCode. */
|
|
33
|
+
/** For an agent whose profile does not change code (an analyst): what its work is instead. */
|
|
34
|
+
export declare const READ_ONLY_BRIEF: string;
|
|
35
|
+
export declare const LEAD_WITHOUT_CODE_BRIEF: string;
|
|
36
|
+
/**
|
|
37
|
+
* An event that waited behind other work says so. Norm (15 Oct): "by the time I act, the thing has
|
|
38
|
+
* often already been done" — it re-checked everything before every action, not knowing which
|
|
39
|
+
* events were fresh. Only past a few minutes; a fresh one needs no warning.
|
|
40
|
+
*/
|
|
41
|
+
export declare function waitedNote(event: Pick<StreamEvent, 'receivedAt'>, now?: number): string;
|
|
42
|
+
/** A card assigned to a lead in a lane where work has not started: the lead hands it out. */
|
|
43
|
+
export declare function isLeadDispatch(event: Pick<StreamEvent, 'event' | 'laneName'>, isLead: boolean): boolean;
|
|
44
|
+
export declare function prompt(event: StreamEvent, isLead?: boolean): string;
|
|
45
|
+
/**
|
|
46
|
+
* The parts of a turn's brief that depend on what kind of agent this is, by feature: a lead's
|
|
47
|
+
* (a worker free, a card with no code here), a manager's, a chat with one person, and one that
|
|
48
|
+
* does not change code. In this order, after the card's own brief.
|
|
49
|
+
*/
|
|
50
|
+
export declare function roleBriefs(p: Profile, o: {
|
|
51
|
+
event: StreamEvent;
|
|
52
|
+
/** This turn is the conversation with the agent's person (not a card it works). */
|
|
53
|
+
chat: boolean;
|
|
54
|
+
person: AssistantPerson | null;
|
|
55
|
+
/** A lead handed a card to build, with no code here: its job is to pass it on. */
|
|
56
|
+
leadWithoutCode: boolean;
|
|
57
|
+
/** The card in progress this event waits behind, if any. */
|
|
58
|
+
queuedBehind: string;
|
|
59
|
+
}): string;
|