@synaplink/orqlaude 0.9.6 → 0.10.0
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__/v010.test.d.ts +1 -0
- package/dist/__tests__/v010.test.js +270 -0
- package/dist/__tests__/v010.test.js.map +1 -0
- package/dist/cli/autopilot.d.ts +11 -0
- package/dist/cli/autopilot.js +447 -0
- package/dist/cli/autopilot.js.map +1 -0
- package/dist/cli.js +12 -0
- package/dist/cli.js.map +1 -1
- package/dist/lib/auto_merge.d.ts +85 -0
- package/dist/lib/auto_merge.js +208 -0
- package/dist/lib/auto_merge.js.map +1 -0
- package/dist/lib/backlog.d.ts +78 -0
- package/dist/lib/backlog.js +133 -0
- package/dist/lib/backlog.js.map +1 -0
- package/dist/lib/guardrails.d.ts +72 -0
- package/dist/lib/guardrails.js +86 -0
- package/dist/lib/guardrails.js.map +1 -0
- package/dist/lib/memory.d.ts +111 -0
- package/dist/lib/memory.js +247 -0
- package/dist/lib/memory.js.map +1 -0
- package/dist/lib/orch_turn.d.ts +65 -0
- package/dist/lib/orch_turn.js +174 -0
- package/dist/lib/orch_turn.js.map +1 -0
- package/dist/lib/retry.d.ts +59 -0
- package/dist/lib/retry.js +149 -0
- package/dist/lib/retry.js.map +1 -0
- package/dist/lib/templates.d.ts +59 -0
- package/dist/lib/templates.js +136 -0
- package/dist/lib/templates.js.map +1 -0
- package/dist/lib/tg_classifier.d.ts +93 -0
- package/dist/lib/tg_classifier.js +99 -0
- package/dist/lib/tg_classifier.js.map +1 -0
- package/dist/lib/version.d.ts +1 -1
- package/dist/lib/version.js +1 -1
- package/dist/lib/version.js.map +1 -1
- package/dist/server.js +11 -0
- package/dist/server.js.map +1 -1
- package/dist/tools/backlog.d.ts +4 -0
- package/dist/tools/backlog.js +166 -0
- package/dist/tools/backlog.js.map +1 -0
- package/dist/tools/memory.d.ts +4 -0
- package/dist/tools/memory.js +115 -0
- package/dist/tools/memory.js.map +1 -0
- package/dist/tools/templates.d.ts +9 -0
- package/dist/tools/templates.js +99 -0
- package/dist/tools/templates.js.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,447 @@
|
|
|
1
|
+
import { promises as fs } from "node:fs";
|
|
2
|
+
import { existsSync, writeFileSync } from "node:fs";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
import { StateStore, findPlan } from "../lib/state.js";
|
|
5
|
+
import { MemoryStore } from "../lib/memory.js";
|
|
6
|
+
import { BacklogStore } from "../lib/backlog.js";
|
|
7
|
+
import { GuardrailStore, DEFAULT_GUARDRAILS } from "../lib/guardrails.js";
|
|
8
|
+
import { snapshotSession } from "../lib/jsonl_tail.js";
|
|
9
|
+
import { isProcessAlive, sleep } from "../lib/process_lib.js";
|
|
10
|
+
import { readChildExitRecord } from "../lib/spawn_cli.js";
|
|
11
|
+
import { fetchPrInfo, fetchPrDiff, runReviewerTurn, applyRule, postReviewComment, squashMerge, } from "../lib/auto_merge.js";
|
|
12
|
+
import { findTemplate } from "../lib/templates.js";
|
|
13
|
+
import { classifyFailure, DEFAULT_RETRY, markForRetry, readTail } from "../lib/retry.js";
|
|
14
|
+
import { resolveStateDir } from "../lib/state_dir.js";
|
|
15
|
+
import { VERSION } from "../lib/version.js";
|
|
16
|
+
/**
|
|
17
|
+
* orqlaude autopilot daemon.
|
|
18
|
+
*
|
|
19
|
+
* This is plain Node TS — no Anthropic SDK. When the daemon needs to think,
|
|
20
|
+
* it spawns `claude -p` (via lib/orch_turn.runOrchTurn) which is billed
|
|
21
|
+
* against the user's Claude Max plan, not the API. Cache reads are free on
|
|
22
|
+
* the Plan, so a daemon that ticks every 10s and runs ~50 thinking turns
|
|
23
|
+
* per day costs roughly nothing.
|
|
24
|
+
*
|
|
25
|
+
* Tick loop (every TICK_MS ms):
|
|
26
|
+
*
|
|
27
|
+
* 1. Recover state — for every task with spawnedSessionId, refresh from
|
|
28
|
+
* JSONL + check PID + check exit-record. Promote `died_at_launch` /
|
|
29
|
+
* `failed` / `done` as appropriate.
|
|
30
|
+
*
|
|
31
|
+
* 2. Failure recovery — for each task that just transitioned to a
|
|
32
|
+
* terminal-bad state, call classifyFailure, then either retry or
|
|
33
|
+
* spawn a debugger Agnet or escalate via Telegram.
|
|
34
|
+
*
|
|
35
|
+
* 3. Auto-PR-review — for each task with a fresh prUrl, fetch the PR,
|
|
36
|
+
* run a reviewer turn, apply the fleet's auto-merge rule, and either
|
|
37
|
+
* merge or comment.
|
|
38
|
+
*
|
|
39
|
+
* 4. Goal pickup — if the fleet is idle (no tasks pending/running) and
|
|
40
|
+
* autopilot is unpaused, pick the next backlog goal and prompt the
|
|
41
|
+
* user via Telegram with the planner's proposed decomposition.
|
|
42
|
+
*
|
|
43
|
+
* 5. Guardrails — check window/day spend; downgrade or pause as needed.
|
|
44
|
+
*
|
|
45
|
+
* Run with: `orql autopilot start` (foreground) or `orql autopilot start --daemon`
|
|
46
|
+
* (background; writes PID file). Stop with `orql autopilot stop`.
|
|
47
|
+
*/
|
|
48
|
+
const TICK_MS = 10_000;
|
|
49
|
+
export async function runAutopilot(opts = {}) {
|
|
50
|
+
const { path: stateDir } = { path: resolveStateDir().path };
|
|
51
|
+
const store = new StateStore(stateDir);
|
|
52
|
+
const memory = new MemoryStore(stateDir);
|
|
53
|
+
const backlog = new BacklogStore(stateDir);
|
|
54
|
+
const guardrails = new GuardrailStore(stateDir);
|
|
55
|
+
const pidFile = path.join(stateDir, "autopilot.pid");
|
|
56
|
+
const pauseFile = path.join(stateDir, "autopilot.paused");
|
|
57
|
+
// Detect duplicate daemon.
|
|
58
|
+
if (existsSync(pidFile)) {
|
|
59
|
+
try {
|
|
60
|
+
const existing = parseInt((await fs.readFile(pidFile, "utf8")).trim(), 10);
|
|
61
|
+
if (Number.isFinite(existing) && isProcessAlive(existing)) {
|
|
62
|
+
console.error(`orql autopilot is already running (pid=${existing}). Use 'orql autopilot stop' first.`);
|
|
63
|
+
return 1;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
catch {
|
|
67
|
+
/* stale, ignore */
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
writeFileSync(pidFile, `${process.pid}\n`);
|
|
71
|
+
// Track shutdown hooks.
|
|
72
|
+
const cleanup = async () => {
|
|
73
|
+
try {
|
|
74
|
+
await fs.unlink(pidFile);
|
|
75
|
+
}
|
|
76
|
+
catch { }
|
|
77
|
+
};
|
|
78
|
+
process.on("SIGTERM", async () => {
|
|
79
|
+
log("SIGTERM received — shutting down");
|
|
80
|
+
await cleanup();
|
|
81
|
+
process.exit(0);
|
|
82
|
+
});
|
|
83
|
+
process.on("SIGINT", async () => {
|
|
84
|
+
log("SIGINT received — shutting down");
|
|
85
|
+
await cleanup();
|
|
86
|
+
process.exit(0);
|
|
87
|
+
});
|
|
88
|
+
const state = {
|
|
89
|
+
startedAt: Date.now(),
|
|
90
|
+
ticks: 0,
|
|
91
|
+
paused: existsSync(pauseFile),
|
|
92
|
+
retries: {},
|
|
93
|
+
reviewedPrs: new Set(),
|
|
94
|
+
proposedGoals: new Set(),
|
|
95
|
+
};
|
|
96
|
+
log(`orqlaude autopilot v${VERSION} started (pid=${process.pid}, state=${stateDir})`);
|
|
97
|
+
if (state.paused)
|
|
98
|
+
log(`note: autopilot is paused (pause file present at ${pauseFile})`);
|
|
99
|
+
const tickMs = opts.tickMs ?? TICK_MS;
|
|
100
|
+
let stopped = false;
|
|
101
|
+
process.on("beforeExit", () => {
|
|
102
|
+
stopped = true;
|
|
103
|
+
});
|
|
104
|
+
while (!stopped) {
|
|
105
|
+
state.ticks++;
|
|
106
|
+
state.paused = existsSync(pauseFile);
|
|
107
|
+
try {
|
|
108
|
+
await tick(state, store, memory, backlog, guardrails, opts);
|
|
109
|
+
}
|
|
110
|
+
catch (err) {
|
|
111
|
+
log(`tick #${state.ticks} threw: ${err.message}`);
|
|
112
|
+
}
|
|
113
|
+
await sleep(tickMs);
|
|
114
|
+
}
|
|
115
|
+
await cleanup();
|
|
116
|
+
return 0;
|
|
117
|
+
}
|
|
118
|
+
// Module-level logger so tick() can use it too. Writes timestamped lines to
|
|
119
|
+
// stderr — keeps stdout clean for any --json modes we add later.
|
|
120
|
+
function log(msg) {
|
|
121
|
+
const ts = new Date().toISOString().replace("T", " ").replace(/\..*$/, "");
|
|
122
|
+
process.stderr.write(`[${ts}] ${msg}\n`);
|
|
123
|
+
}
|
|
124
|
+
async function tick(state, store, memory, backlog, guardrails, opts) {
|
|
125
|
+
// ---- 1. State recovery ----------------------------------------------------
|
|
126
|
+
const plans = await store.read((s) => Object.values(s.plans));
|
|
127
|
+
const cwd = process.cwd();
|
|
128
|
+
// Re-snapshot every running task; reconcile status.
|
|
129
|
+
for (const plan of plans) {
|
|
130
|
+
if (plan.status === "collected" || plan.status === "cancelled" || plan.status === "cancelled_overbudget") {
|
|
131
|
+
continue;
|
|
132
|
+
}
|
|
133
|
+
for (const task of plan.tasks) {
|
|
134
|
+
if (!task.spawnedSessionId)
|
|
135
|
+
continue;
|
|
136
|
+
if (task.status === "done" || task.status === "failed" || task.status === "cancelled" || task.status === "died_at_launch") {
|
|
137
|
+
continue;
|
|
138
|
+
}
|
|
139
|
+
const snap = await snapshotSession(cwd, task.spawnedSessionId, task.stdoutPath);
|
|
140
|
+
const pidDead = task.pid ? !isProcessAlive(task.pid) : false;
|
|
141
|
+
const exitRec = task.exitJsonPath ? await readChildExitRecord(task.exitJsonPath) : null;
|
|
142
|
+
if (snap.terminated || exitRec) {
|
|
143
|
+
// Promote terminal state.
|
|
144
|
+
await store.update((s) => {
|
|
145
|
+
const p = findPlan(s, plan.id);
|
|
146
|
+
const t = p.tasks.find((tt) => tt.id === task.id);
|
|
147
|
+
if (!t)
|
|
148
|
+
return;
|
|
149
|
+
if (exitRec) {
|
|
150
|
+
t.status = exitRec.success ? "done" : "failed";
|
|
151
|
+
t.exitReason = exitRec.signal ? `signal=${exitRec.signal}` : `exit_code=${exitRec.exit_code}`;
|
|
152
|
+
}
|
|
153
|
+
else if (snap.terminated) {
|
|
154
|
+
t.status = "done";
|
|
155
|
+
t.exitReason = snap.terminationReason ?? "transcript end";
|
|
156
|
+
}
|
|
157
|
+
t.finishedAt = t.finishedAt ?? Date.now();
|
|
158
|
+
if (snap.totalEffectiveTokens > 0)
|
|
159
|
+
t.tokensUsed = snap.totalEffectiveTokens;
|
|
160
|
+
if (snap.totalCostUsd > 0)
|
|
161
|
+
t.costUsd = snap.totalCostUsd;
|
|
162
|
+
});
|
|
163
|
+
// Telemetry for guardrails.
|
|
164
|
+
if (snap.billedTokens > 0) {
|
|
165
|
+
await guardrails.record({
|
|
166
|
+
ts: Date.now(),
|
|
167
|
+
billed: snap.billedTokens,
|
|
168
|
+
cached: snap.cachedTokens,
|
|
169
|
+
planId: plan.id,
|
|
170
|
+
taskId: task.id,
|
|
171
|
+
source: "task_termination",
|
|
172
|
+
});
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
else if (pidDead && !snap.lastActivityAt) {
|
|
176
|
+
// Died at launch — PID gone and no transcript activity ever recorded.
|
|
177
|
+
await store.update((s) => {
|
|
178
|
+
const p = findPlan(s, plan.id);
|
|
179
|
+
const t = p.tasks.find((tt) => tt.id === task.id);
|
|
180
|
+
if (!t)
|
|
181
|
+
return;
|
|
182
|
+
t.status = "died_at_launch";
|
|
183
|
+
t.finishedAt = t.finishedAt ?? Date.now();
|
|
184
|
+
});
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
// Re-fetch after reconciliation.
|
|
189
|
+
const reconciledPlans = await store.read((s) => Object.values(s.plans));
|
|
190
|
+
// ---- 2. Failure recovery -------------------------------------------------
|
|
191
|
+
for (const plan of reconciledPlans) {
|
|
192
|
+
for (const task of plan.tasks) {
|
|
193
|
+
if (task.status !== "died_at_launch" && task.status !== "failed")
|
|
194
|
+
continue;
|
|
195
|
+
// Already addressed?
|
|
196
|
+
if (task.summary?.includes("[retry exhausted]") || task.summary?.includes("[debugger spawned]"))
|
|
197
|
+
continue;
|
|
198
|
+
const stderrTail = await readTail(task.stderrPath, 2000);
|
|
199
|
+
const stdoutTail = await readTail(task.stdoutPath, 2000);
|
|
200
|
+
const decision = await classifyFailure(task, stderrTail, stdoutTail, DEFAULT_RETRY);
|
|
201
|
+
log(`task ${task.agnetName ?? task.id.slice(0, 8)}: classifier said ${decision.action} (${decision.reason})`);
|
|
202
|
+
if (decision.action === "retry") {
|
|
203
|
+
await markForRetry(store, plan.id, task.id, DEFAULT_RETRY);
|
|
204
|
+
await pushOrphanNotification(store, `🔁 Agnet ${task.agnetName ?? task.id.slice(0, 8)} died at launch — auto-retrying (${decision.reason}).`, "low");
|
|
205
|
+
}
|
|
206
|
+
else if (decision.action === "spawn_debugger") {
|
|
207
|
+
await store.update((s) => {
|
|
208
|
+
const p = findPlan(s, plan.id);
|
|
209
|
+
const t = p.tasks.find((tt) => tt.id === task.id);
|
|
210
|
+
if (!t)
|
|
211
|
+
return;
|
|
212
|
+
t.summary = `${t.summary ?? ""} [debugger spawned at ${new Date().toISOString()}]`.trim();
|
|
213
|
+
});
|
|
214
|
+
await pushOrphanNotification(store, `🔍 Agnet ${task.agnetName ?? task.id.slice(0, 8)} failed (${decision.reason}). Marking for debugger Agnet. Use 'orql watch ${plan.id.slice(0, 8)}' to follow.`, "normal");
|
|
215
|
+
}
|
|
216
|
+
else if (decision.action === "escalate") {
|
|
217
|
+
await store.update((s) => {
|
|
218
|
+
const p = findPlan(s, plan.id);
|
|
219
|
+
const t = p.tasks.find((tt) => tt.id === task.id);
|
|
220
|
+
if (!t)
|
|
221
|
+
return;
|
|
222
|
+
t.summary = `${t.summary ?? ""} [retry exhausted; escalated to user]`.trim();
|
|
223
|
+
});
|
|
224
|
+
await pushOrphanNotification(store, `🚨 Agnet ${task.agnetName ?? task.id.slice(0, 8)} failed; auto-recovery exhausted. Reason: ${decision.reason}. Manual review needed in plan ${plan.id.slice(0, 8)}.`, "high");
|
|
225
|
+
}
|
|
226
|
+
else {
|
|
227
|
+
// give_up
|
|
228
|
+
await store.update((s) => {
|
|
229
|
+
const p = findPlan(s, plan.id);
|
|
230
|
+
const t = p.tasks.find((tt) => tt.id === task.id);
|
|
231
|
+
if (!t)
|
|
232
|
+
return;
|
|
233
|
+
t.summary = `${t.summary ?? ""} [given up: ${decision.reason}]`.trim();
|
|
234
|
+
});
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
// ---- 3. Auto-PR-review ----------------------------------------------------
|
|
239
|
+
for (const plan of reconciledPlans) {
|
|
240
|
+
const tpl = plan.tasks[0]?.summary?.match(/\[template:([\w-]+)\]/)?.[1];
|
|
241
|
+
const template = tpl ? findTemplate(tpl) : undefined;
|
|
242
|
+
const rule = template?.autoMerge;
|
|
243
|
+
if (!rule)
|
|
244
|
+
continue;
|
|
245
|
+
for (const task of plan.tasks) {
|
|
246
|
+
if (!task.prUrl || state.reviewedPrs.has(task.prUrl))
|
|
247
|
+
continue;
|
|
248
|
+
try {
|
|
249
|
+
const pr = await fetchPrInfo(task.prUrl, cwd);
|
|
250
|
+
if (pr.state !== "OPEN") {
|
|
251
|
+
state.reviewedPrs.add(task.prUrl);
|
|
252
|
+
continue;
|
|
253
|
+
}
|
|
254
|
+
const diff = await fetchPrDiff(task.prUrl, cwd);
|
|
255
|
+
const review = await runReviewerTurn(pr, diff, cwd);
|
|
256
|
+
const decision = applyRule(pr, review, rule);
|
|
257
|
+
log(`PR ${task.prUrl}: review=${review.verdict}, rule=${decision.ok ? "OK" : "BLOCKED"} (${decision.violations.join("; ")})`);
|
|
258
|
+
if (decision.ok) {
|
|
259
|
+
const ok = await squashMerge(task.prUrl, cwd, rule.method ?? "squash");
|
|
260
|
+
await pushOrphanNotification(store, ok
|
|
261
|
+
? `✅ Auto-merged PR ${task.prUrl} (reviewer: ${review.verdict}, rule passed).`
|
|
262
|
+
: `⚠️ Auto-merge failed for PR ${task.prUrl} despite passing rules. Manual merge needed.`, ok ? "low" : "high");
|
|
263
|
+
}
|
|
264
|
+
else {
|
|
265
|
+
await postReviewComment(task.prUrl, review, cwd);
|
|
266
|
+
await pushOrphanNotification(store, `🤖 Auto-review for ${task.prUrl}: ${review.verdict}. Posted comment. Blockers: ${decision.violations.join("; ")}`, review.verdict === "BLOCKER" ? "high" : "normal");
|
|
267
|
+
}
|
|
268
|
+
// Remember the decision in the ledger.
|
|
269
|
+
await memory.remember({
|
|
270
|
+
category: "ledger",
|
|
271
|
+
key: `auto-review:${pr.number}`,
|
|
272
|
+
value: `Auto-review verdict ${review.verdict} on ${task.prUrl}. ${review.summary}`,
|
|
273
|
+
rationale: decision.ok ? "Met all auto-merge rules" : `Violations: ${decision.violations.join("; ")}`,
|
|
274
|
+
bornFrom: { planId: plan.id, taskId: task.id },
|
|
275
|
+
});
|
|
276
|
+
state.reviewedPrs.add(task.prUrl);
|
|
277
|
+
}
|
|
278
|
+
catch (err) {
|
|
279
|
+
log(`auto-review failed for ${task.prUrl}: ${err.message}`);
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
// ---- 4. Goal pickup -------------------------------------------------------
|
|
284
|
+
if (!state.paused) {
|
|
285
|
+
const fleetIdle = reconciledPlans.filter((p) => p.status === "running" || p.status === "dispatching").length === 0;
|
|
286
|
+
if (fleetIdle) {
|
|
287
|
+
const goal = await backlog.pickNext();
|
|
288
|
+
if (goal && !state.proposedGoals.has(goal.id)) {
|
|
289
|
+
log(`fleet idle; proposing goal ${goal.shortId}: "${goal.title}"`);
|
|
290
|
+
await pushOrphanNotification(store, `💡 Autopilot ready for next goal: "${goal.title}" (priority ${goal.priority}). Reply /now to start, /queue to see all, /pause to halt autopilot.`, "normal");
|
|
291
|
+
state.proposedGoals.add(goal.id);
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
// ---- 5. Guardrails --------------------------------------------------------
|
|
296
|
+
const snap = await guardrails.snapshot(DEFAULT_GUARDRAILS);
|
|
297
|
+
if (snap.level === "yellow" && state.ticks % 60 === 0) {
|
|
298
|
+
await pushOrphanNotification(store, `⚠️ Budget window at ${Math.round(snap.windowPct * 100)}% — slowing down. Day: ${Math.round(snap.dayPct * 100)}% of soft cap.`, "normal");
|
|
299
|
+
}
|
|
300
|
+
else if (snap.level === "orange") {
|
|
301
|
+
if (state.ticks % 30 === 0) {
|
|
302
|
+
await pushOrphanNotification(store, `🟠 Budget window at ${Math.round(snap.windowPct * 100)}% — pausing new fleet starts. Use /resume to override.`, "high");
|
|
303
|
+
}
|
|
304
|
+
// Force pause for new goals until next window.
|
|
305
|
+
if (!existsSync(pauseFile()))
|
|
306
|
+
writeFileSync(pauseFile(), `orange_at_${Date.now()}\n`);
|
|
307
|
+
}
|
|
308
|
+
else if (snap.level === "red") {
|
|
309
|
+
// Rate-limit to every 18 ticks (~3 min). Without this the red branch
|
|
310
|
+
// would post a high-urgency Telegram on every tick (every 10s) — a
|
|
311
|
+
// sustained red event across a 5h Plan window would spam ~1,800
|
|
312
|
+
// notifications. 3 min is louder than orange (5 min) but not insane.
|
|
313
|
+
if (state.ticks % 18 === 0) {
|
|
314
|
+
await pushOrphanNotification(store, `🔴 Budget window at ${Math.round(snap.windowPct * 100)}% — autopilot HALTED. Use /resume after the next 5h reset.`, "high");
|
|
315
|
+
}
|
|
316
|
+
if (!existsSync(pauseFile()))
|
|
317
|
+
writeFileSync(pauseFile(), `red_at_${Date.now()}\n`);
|
|
318
|
+
}
|
|
319
|
+
if (opts.verbose && state.ticks % 6 === 0) {
|
|
320
|
+
log(`tick ${state.ticks}: plans=${reconciledPlans.length} guardrails=${snap.level} (win=${Math.round(snap.windowPct * 100)}%, day=${Math.round(snap.dayPct * 100)}%)`);
|
|
321
|
+
}
|
|
322
|
+
function pauseFile() {
|
|
323
|
+
return path.join(resolveStateDir().path, "autopilot.paused");
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
async function pushOrphanNotification(store, text, urgency) {
|
|
327
|
+
const { randomUUID } = await import("node:crypto");
|
|
328
|
+
await store.update((s) => {
|
|
329
|
+
s.orphanNotifications = s.orphanNotifications ?? [];
|
|
330
|
+
s.orphanNotifications.push({
|
|
331
|
+
id: randomUUID(),
|
|
332
|
+
text,
|
|
333
|
+
urgency,
|
|
334
|
+
createdAt: Date.now(),
|
|
335
|
+
delivered: false,
|
|
336
|
+
});
|
|
337
|
+
});
|
|
338
|
+
}
|
|
339
|
+
// ----- CLI subcommand handlers --------------------------------------------
|
|
340
|
+
export async function cmdAutopilot(args) {
|
|
341
|
+
const sub = args[0];
|
|
342
|
+
switch (sub) {
|
|
343
|
+
case "start":
|
|
344
|
+
return runAutopilot({
|
|
345
|
+
verbose: args.includes("--verbose") || args.includes("-v"),
|
|
346
|
+
tickMs: extractFlag(args, "--tick-ms") ? parseInt(extractFlag(args, "--tick-ms"), 10) : undefined,
|
|
347
|
+
});
|
|
348
|
+
case "stop":
|
|
349
|
+
return autopilotStop();
|
|
350
|
+
case "status":
|
|
351
|
+
return autopilotStatus();
|
|
352
|
+
case "pause":
|
|
353
|
+
return autopilotPause();
|
|
354
|
+
case "resume":
|
|
355
|
+
return autopilotResume();
|
|
356
|
+
default:
|
|
357
|
+
printAutopilotHelp();
|
|
358
|
+
return sub ? 1 : 0;
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
function extractFlag(args, flag) {
|
|
362
|
+
const i = args.indexOf(flag);
|
|
363
|
+
if (i < 0 || i + 1 >= args.length)
|
|
364
|
+
return undefined;
|
|
365
|
+
return args[i + 1];
|
|
366
|
+
}
|
|
367
|
+
async function autopilotStop() {
|
|
368
|
+
const stateDir = resolveStateDir().path;
|
|
369
|
+
const pidFile = path.join(stateDir, "autopilot.pid");
|
|
370
|
+
if (!existsSync(pidFile)) {
|
|
371
|
+
process.stdout.write("autopilot is not running\n");
|
|
372
|
+
return 0;
|
|
373
|
+
}
|
|
374
|
+
const pid = parseInt((await fs.readFile(pidFile, "utf8")).trim(), 10);
|
|
375
|
+
if (!Number.isFinite(pid) || !isProcessAlive(pid)) {
|
|
376
|
+
await fs.unlink(pidFile).catch(() => { });
|
|
377
|
+
process.stdout.write("autopilot pid was stale; cleared\n");
|
|
378
|
+
return 0;
|
|
379
|
+
}
|
|
380
|
+
try {
|
|
381
|
+
process.kill(pid, "SIGTERM");
|
|
382
|
+
process.stdout.write(`sent SIGTERM to autopilot pid=${pid}\n`);
|
|
383
|
+
return 0;
|
|
384
|
+
}
|
|
385
|
+
catch (err) {
|
|
386
|
+
process.stderr.write(`failed to signal pid=${pid}: ${err.message}\n`);
|
|
387
|
+
return 1;
|
|
388
|
+
}
|
|
389
|
+
}
|
|
390
|
+
async function autopilotStatus() {
|
|
391
|
+
const stateDir = resolveStateDir().path;
|
|
392
|
+
const pidFile = path.join(stateDir, "autopilot.pid");
|
|
393
|
+
const pauseFile = path.join(stateDir, "autopilot.paused");
|
|
394
|
+
if (!existsSync(pidFile)) {
|
|
395
|
+
process.stdout.write("autopilot: stopped\n");
|
|
396
|
+
return 0;
|
|
397
|
+
}
|
|
398
|
+
const pid = parseInt((await fs.readFile(pidFile, "utf8")).trim(), 10);
|
|
399
|
+
const alive = Number.isFinite(pid) && isProcessAlive(pid);
|
|
400
|
+
const paused = existsSync(pauseFile);
|
|
401
|
+
process.stdout.write(`autopilot: ${alive ? "running" : "stale-pid"} (pid=${pid}${paused ? ", paused" : ""}, state_dir=${stateDir})\n`);
|
|
402
|
+
// Snapshot from guardrails.
|
|
403
|
+
const gs = new GuardrailStore(stateDir);
|
|
404
|
+
const snap = await gs.snapshot(DEFAULT_GUARDRAILS);
|
|
405
|
+
process.stdout.write(`budget: window ${Math.round(snap.windowPct * 100)}% (${formatTokens(snap.windowBilled)}/${formatTokens(snap.windowCap)}), day ${Math.round(snap.dayPct * 100)}% [${snap.level}]\n`);
|
|
406
|
+
return alive ? 0 : 1;
|
|
407
|
+
}
|
|
408
|
+
async function autopilotPause() {
|
|
409
|
+
const stateDir = resolveStateDir().path;
|
|
410
|
+
const pauseFile = path.join(stateDir, "autopilot.paused");
|
|
411
|
+
writeFileSync(pauseFile, `paused_at=${Date.now()}\n`);
|
|
412
|
+
process.stdout.write("autopilot paused (daemon will refuse to start new goals)\n");
|
|
413
|
+
return 0;
|
|
414
|
+
}
|
|
415
|
+
async function autopilotResume() {
|
|
416
|
+
const stateDir = resolveStateDir().path;
|
|
417
|
+
const pauseFile = path.join(stateDir, "autopilot.paused");
|
|
418
|
+
if (existsSync(pauseFile)) {
|
|
419
|
+
await fs.unlink(pauseFile).catch(() => { });
|
|
420
|
+
}
|
|
421
|
+
process.stdout.write("autopilot resumed\n");
|
|
422
|
+
return 0;
|
|
423
|
+
}
|
|
424
|
+
function printAutopilotHelp() {
|
|
425
|
+
process.stdout.write(`orql autopilot — persistent orchestrator daemon\n\n` +
|
|
426
|
+
` orql autopilot start [--verbose] [--tick-ms N]\n` +
|
|
427
|
+
` Run the daemon in the foreground.\n` +
|
|
428
|
+
` orql autopilot stop\n` +
|
|
429
|
+
` SIGTERM the running daemon.\n` +
|
|
430
|
+
` orql autopilot status\n` +
|
|
431
|
+
` Show daemon status + current budget burn.\n` +
|
|
432
|
+
` orql autopilot pause\n` +
|
|
433
|
+
` Stop picking new goals. In-flight fleets continue.\n` +
|
|
434
|
+
` orql autopilot resume\n` +
|
|
435
|
+
` Reverse pause.\n\n` +
|
|
436
|
+
`The daemon uses Plan-billed \`claude -p\` for all thinking turns —\n` +
|
|
437
|
+
`no Anthropic API key required. Cache reads are free on the Plan, so\n` +
|
|
438
|
+
`a full day of ticking burns a tiny fraction of the quota.\n`);
|
|
439
|
+
}
|
|
440
|
+
function formatTokens(n) {
|
|
441
|
+
if (n >= 1_000_000)
|
|
442
|
+
return `${(n / 1_000_000).toFixed(1)}M`;
|
|
443
|
+
if (n >= 1_000)
|
|
444
|
+
return `${(n / 1_000).toFixed(1)}k`;
|
|
445
|
+
return String(n);
|
|
446
|
+
}
|
|
447
|
+
//# sourceMappingURL=autopilot.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"autopilot.js","sourceRoot":"","sources":["../../src/cli/autopilot.ts"],"names":[],"mappings":"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"}
|
package/dist/cli.js
CHANGED
|
@@ -109,6 +109,12 @@ async function main() {
|
|
|
109
109
|
case "tg":
|
|
110
110
|
exitCode = await cmdTg(rest);
|
|
111
111
|
break;
|
|
112
|
+
case "autopilot":
|
|
113
|
+
// v0.10.0+: persistent daemon for hands-off fleet orchestration.
|
|
114
|
+
// Delegates to ./cli/autopilot.cmdAutopilot — sub-commands: start,
|
|
115
|
+
// stop, status, pause, resume.
|
|
116
|
+
exitCode = await (await import("./cli/autopilot.js")).cmdAutopilot(rest);
|
|
117
|
+
break;
|
|
112
118
|
default:
|
|
113
119
|
process.stderr.write(errorLine(`unknown subcommand: ${cmd}`, `try \`orql help\``));
|
|
114
120
|
exitCode = 1;
|
|
@@ -171,6 +177,12 @@ function printHelp() {
|
|
|
171
177
|
console.log(style.bold(style.cream("Notifications")));
|
|
172
178
|
console.log(` ${style.coral("orql notify on|off|test|status")} macOS desktop notifications (paired with Telegram)`);
|
|
173
179
|
console.log("");
|
|
180
|
+
console.log(style.bold(style.cream("Autopilot (v0.10.0+)")));
|
|
181
|
+
console.log(` ${style.coral("orql autopilot start")} ${style.sand("[--verbose] [--tick-ms N]")} Run the daemon (foreground)`);
|
|
182
|
+
console.log(` ${style.coral("orql autopilot stop")} SIGTERM the daemon`);
|
|
183
|
+
console.log(` ${style.coral("orql autopilot status")} Daemon + budget burn`);
|
|
184
|
+
console.log(` ${style.coral("orql autopilot pause|resume")} Halt new-goal pickup (in-flight fleets continue)`);
|
|
185
|
+
console.log("");
|
|
174
186
|
console.log(style.bold(style.cream("Telegram")));
|
|
175
187
|
console.log(` ${style.coral("orqlaude tg setup")} Configure bot token (interactive)`);
|
|
176
188
|
console.log(` ${style.coral("orqlaude tg whitelist")} ${style.sand("<id> [--owner] [--label NAME]")}`);
|