@euqns/nudge-mcp 0.6.11 → 0.8.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/runner.js ADDED
@@ -0,0 +1,467 @@
1
+ // Nudge self-hosted runner — the local half of the GitHub-Actions-style runner.
2
+ //
3
+ // A long-lived process on the user's own machine that registers against one
4
+ // Nudge board, waits for jobs queued from that board's cards, and works each one
5
+ // inside a local checkout of the board's repository — using either Codex or
6
+ // Claude Code, whichever the job asks for and this machine has installed.
7
+ //
8
+ // Every job runs in two phases. First a read-only TRIAGE turn, where the agent
9
+ // says whether it can actually do the task; only if it says yes does the second,
10
+ // write-enabled phase start. A job the agent can't finish stops as `needs_human`
11
+ // with its questions attached, instead of half-editing the working copy.
12
+ //
13
+ // The delivery mechanism is the interesting part. GitHub's runner long-polls an
14
+ // /acquirejob endpoint; this one holds a Convex websocket subscription, so a
15
+ // queued job arrives the moment it is created, and a cancellation reaches an
16
+ // in-flight turn just as fast. There is no poll interval to tune.
17
+ //
18
+ // Everything it writes back — log chunks, heartbeats — is batched. A mutation
19
+ // per output line would be one database write per line of agent output; see the
20
+ // write-discipline note in the repo's CLAUDE.md.
21
+ import crypto from "node:crypto";
22
+ import os from "node:os";
23
+ import path from "node:path";
24
+ import { ConvexClient } from "convex/browser";
25
+ import { makeFunctionReference } from "convex/server";
26
+ import { addUsage, detectEngines, emptyUsage, pickEngine, } from "./engines/index.js";
27
+ import { readCredentials, readRunnerConfig, writeRunnerConfig, RUNNER_CONFIG_PATH, } from "./credentials.js";
28
+ import { NUDGE_MCP_VERSION } from "./version.js";
29
+ // Renew the lease ~4.5x more often than the server's 90s expiry, so a couple of
30
+ // dropped beats never costs us a job we're actively working on.
31
+ const HEARTBEAT_MS = 20_000;
32
+ // Log flush cadence. Batched rather than per-event; see the header note.
33
+ const LOG_FLUSH_MS = 750;
34
+ const LOG_FLUSH_CHUNKS = 32;
35
+ // Convex function references. Built by path rather than importing the generated
36
+ // api, matching how mcp/src/index.ts talks to the deployment — this package is
37
+ // published standalone and must not depend on the app's generated types.
38
+ const fns = {
39
+ register: makeFunctionReference("runners:register"),
40
+ nextJob: makeFunctionReference("runners:nextJob"),
41
+ claim: makeFunctionReference("runners:claim"),
42
+ submitTriage: makeFunctionReference("runners:submitTriage"),
43
+ heartbeat: makeFunctionReference("runners:heartbeat"),
44
+ appendLogs: makeFunctionReference("runners:appendLogs"),
45
+ finish: makeFunctionReference("runners:finish"),
46
+ };
47
+ function parseArgs(argv) {
48
+ const out = {};
49
+ for (let i = 0; i < argv.length; i++) {
50
+ const arg = argv[i];
51
+ const takeValue = (flag) => {
52
+ if (arg === flag)
53
+ return argv[++i] ?? null;
54
+ if (arg.startsWith(`${flag}=`))
55
+ return arg.slice(flag.length + 1);
56
+ return null;
57
+ };
58
+ const url = takeValue("--convex-url");
59
+ if (url !== null) {
60
+ out.convexUrl = url;
61
+ continue;
62
+ }
63
+ const token = takeValue("--token");
64
+ if (token !== null) {
65
+ out.token = token;
66
+ continue;
67
+ }
68
+ const cwd = takeValue("--cwd");
69
+ if (cwd !== null) {
70
+ out.cwd = path.resolve(cwd);
71
+ continue;
72
+ }
73
+ const name = takeValue("--name");
74
+ if (name !== null) {
75
+ out.name = name;
76
+ continue;
77
+ }
78
+ const labels = takeValue("--labels");
79
+ if (labels !== null) {
80
+ out.labels = labels.split(",").map((l) => l.trim()).filter(Boolean);
81
+ continue;
82
+ }
83
+ const model = takeValue("--model");
84
+ if (model !== null) {
85
+ out.model = model;
86
+ continue;
87
+ }
88
+ const effort = takeValue("--effort");
89
+ if (effort !== null) {
90
+ out.effort = effort;
91
+ continue;
92
+ }
93
+ if (arg === "--save") {
94
+ out.save = true;
95
+ continue;
96
+ }
97
+ if (arg === "--no-save") {
98
+ out.save = false;
99
+ continue;
100
+ }
101
+ throw new Error(`Unknown runner option: ${arg}`);
102
+ }
103
+ return out;
104
+ }
105
+ // Resolve options from flags, then the saved runner config, then env. Minting a
106
+ // machineId here if there isn't one is what makes restarts idempotent server-side.
107
+ async function resolveOptions(argv) {
108
+ const flags = parseArgs(argv);
109
+ const saved = await readRunnerConfig();
110
+ const convexUrl = flags.convexUrl ?? process.env.NUDGE_CONVEX_URL ?? saved?.convexUrl;
111
+ const token = flags.token ?? process.env.NUDGE_RUNNER_TOKEN ?? saved?.token;
112
+ if (!convexUrl || !token) {
113
+ throw new Error([
114
+ "The runner needs a Convex URL and a board runner token.",
115
+ "",
116
+ " nudge-mcp runner --convex-url https://<deployment>.convex.cloud \\",
117
+ " --token nrun_... --cwd /path/to/checkout",
118
+ "",
119
+ "Mint the token in Nudge under the board's settings → Self-hosted runners.",
120
+ `Pass --save once and it is remembered in ${RUNNER_CONFIG_PATH}.`,
121
+ ].join("\n"));
122
+ }
123
+ const machineId = saved?.machineId ?? crypto.randomUUID();
124
+ const cwd = flags.cwd ?? saved?.cwd ?? process.cwd();
125
+ const name = flags.name ?? saved?.name ?? os.hostname();
126
+ const options = {
127
+ convexUrl,
128
+ token,
129
+ cwd: path.resolve(cwd),
130
+ name,
131
+ labels: flags.labels ?? [],
132
+ model: flags.model ?? null,
133
+ effort: flags.effort ?? null,
134
+ save: flags.save ?? false,
135
+ };
136
+ if (options.save) {
137
+ const config = {
138
+ token: options.token,
139
+ convexUrl: options.convexUrl,
140
+ machineId,
141
+ cwd: options.cwd,
142
+ name: options.name,
143
+ };
144
+ await writeRunnerConfig(config);
145
+ }
146
+ return { options, machineId };
147
+ }
148
+ // Buffers agent output and flushes it as one batched mutation. The whole point
149
+ // is that a talkative turn costs a couple of writes per second rather than one
150
+ // write per line.
151
+ class LogBatcher {
152
+ client;
153
+ token;
154
+ runnerId;
155
+ jobId;
156
+ buffer = [];
157
+ timer = null;
158
+ inFlight = Promise.resolve();
159
+ constructor(client, token, runnerId, jobId) {
160
+ this.client = client;
161
+ this.token = token;
162
+ this.runnerId = runnerId;
163
+ this.jobId = jobId;
164
+ }
165
+ push(stream, text) {
166
+ if (!text)
167
+ return;
168
+ this.buffer.push({ stream, text });
169
+ if (this.buffer.length >= LOG_FLUSH_CHUNKS) {
170
+ void this.flush();
171
+ return;
172
+ }
173
+ this.timer ??= setTimeout(() => void this.flush(), LOG_FLUSH_MS);
174
+ }
175
+ async flush() {
176
+ if (this.timer) {
177
+ clearTimeout(this.timer);
178
+ this.timer = null;
179
+ }
180
+ if (this.buffer.length === 0)
181
+ return this.inFlight;
182
+ const chunks = this.buffer;
183
+ this.buffer = [];
184
+ // Chain rather than fire-and-forget so chunks land in the order produced.
185
+ this.inFlight = this.inFlight
186
+ .then(() => this.client.mutation(fns.appendLogs, {
187
+ token: this.token,
188
+ runnerId: this.runnerId,
189
+ jobId: this.jobId,
190
+ chunks,
191
+ }))
192
+ .then(() => undefined, (err) => {
193
+ // Losing a log batch must never kill the job it belongs to.
194
+ console.error("[runner] log flush failed:", err instanceof Error ? err.message : err);
195
+ });
196
+ return this.inFlight;
197
+ }
198
+ }
199
+ export async function runNudgeRunner(argv) {
200
+ const { options, machineId } = await resolveOptions(argv);
201
+ // Probe both agents once. Whichever are usable get reported to the server,
202
+ // which then only offers this machine jobs it can actually run.
203
+ const detected = await detectEngines();
204
+ const availableEngines = detected
205
+ .filter((d) => d.available)
206
+ .map((d) => d.engine.id);
207
+ if (availableEngines.length === 0) {
208
+ throw new Error([
209
+ "No usable coding agent found on this machine.",
210
+ ...detected.map((d) => ` ${d.engine.displayName}: ${d.detail}`),
211
+ "",
212
+ "Install and log in to at least one:",
213
+ " Codex — npx -y @openai/codex login (choose ChatGPT, never an API key)",
214
+ " Claude Code — https://claude.com/code, then `claude` once to sign in",
215
+ ].join("\n"));
216
+ }
217
+ // The agent reaches the board through the Nudge MCP server, which reads the
218
+ // user-scoped credentials. Without them it can still edit files, so this is a
219
+ // warning and not a hard stop.
220
+ if (!(await readCredentials())) {
221
+ console.warn("[runner] No Nudge MCP credentials found — the agent will be able to edit files\n" +
222
+ " but not read or update cards. Run `nudge-mcp setup` to fix.");
223
+ }
224
+ const client = new ConvexClient(options.convexUrl);
225
+ const registration = (await client.mutation(fns.register, {
226
+ token: options.token,
227
+ machineId,
228
+ name: options.name,
229
+ os: `${os.platform()} ${os.release()}`,
230
+ arch: os.arch(),
231
+ version: NUDGE_MCP_VERSION,
232
+ cwd: options.cwd,
233
+ labels: options.labels,
234
+ engines: availableEngines,
235
+ }));
236
+ const { runnerId, board } = registration;
237
+ console.log("");
238
+ console.log("Nudge self-hosted runner is online");
239
+ console.log(` Board: ${board.title}`);
240
+ console.log(` Repo: ${board.repo?.name ?? "(none linked)"}`);
241
+ console.log(` Workspace: ${options.cwd}`);
242
+ console.log(` Machine: ${options.name} (${machineId.slice(0, 8)})`);
243
+ for (const d of detected) {
244
+ console.log(` ${d.engine.displayName.padEnd(11)}${d.available ? "ready" : "unavailable"} — ${d.detail}`);
245
+ }
246
+ console.log(" Files: writable inside the workspace (triage is read-only)");
247
+ console.log("");
248
+ console.log("Waiting for jobs. Keep this terminal open.");
249
+ console.log("");
250
+ // ---- job execution ------------------------------------------------------
251
+ let active = null;
252
+ let claiming = false;
253
+ let stopped = false;
254
+ const heartbeat = setInterval(() => {
255
+ void (async () => {
256
+ try {
257
+ const result = (await client.mutation(fns.heartbeat, {
258
+ token: options.token,
259
+ runnerId,
260
+ jobId: active?.jobId,
261
+ }));
262
+ // Covers the case where the live subscription dropped: if the server
263
+ // says the job is no longer ours (reaped, cancelled), stop working.
264
+ if (active && result.cancelRequested)
265
+ active.abort.abort();
266
+ }
267
+ catch (err) {
268
+ console.error("[runner] heartbeat failed:", err instanceof Error ? err.message : err);
269
+ }
270
+ })();
271
+ }, HEARTBEAT_MS);
272
+ async function runJob(job) {
273
+ const abort = new AbortController();
274
+ active = { jobId: job.id, abort };
275
+ const logs = new LogBatcher(client, options.token, runnerId, job.id);
276
+ const engine = pickEngine(detected, job.engine);
277
+ console.log(`[runner] ▶ job ${job.id} on ${job.engine} (attempt ${job.attempt}/${job.maxAttempts})`);
278
+ // Should be unreachable — the server filters on our reported engines — but
279
+ // a runner that lost an engine since registering would otherwise loop.
280
+ if (!engine) {
281
+ logs.push("stderr", `This machine cannot run ${job.engine} jobs.`);
282
+ await logs.flush();
283
+ await report(job.id, "failed", {
284
+ error: `Runner has no usable ${job.engine} engine`,
285
+ });
286
+ active = null;
287
+ return;
288
+ }
289
+ const runOptions = {
290
+ prompt: job.prompt,
291
+ cwd: options.cwd,
292
+ model: job.model ?? options.model,
293
+ effort: job.effort ?? options.effort,
294
+ threadId: job.threadId,
295
+ signal: abort.signal,
296
+ log: (stream, text) => logs.push(stream, text),
297
+ };
298
+ let usage = emptyUsage();
299
+ let status = "succeeded";
300
+ let summary = "";
301
+ let error;
302
+ let threadId = job.threadId;
303
+ let costUsd;
304
+ let costBasis = "subscription";
305
+ try {
306
+ // ---- phase 1: triage (read-only) ----
307
+ logs.push("event", `${engine.displayName} is checking whether it can do this task…`);
308
+ const triage = await engine.triage(runOptions);
309
+ usage = addUsage(usage, triage.usage);
310
+ logs.push("event", `Verdict: ${triage.verdict.verdict === "can_do" ? "can do it" : "needs a human"} — ${triage.verdict.reason}`);
311
+ const gate = (await client.mutation(fns.submitTriage, {
312
+ token: options.token,
313
+ runnerId,
314
+ jobId: job.id,
315
+ verdict: triage.verdict.verdict,
316
+ reason: triage.verdict.reason,
317
+ questions: triage.verdict.questions,
318
+ confidence: triage.verdict.confidence,
319
+ usage,
320
+ }));
321
+ // needs_human, cancelled, or the lease was lost — either way the server
322
+ // has already put the job in its terminal state. Don't touch the checkout.
323
+ if (!gate.proceed) {
324
+ await logs.flush();
325
+ console.log(`[runner] ■ job ${job.id} → stopped at triage`);
326
+ active = null;
327
+ return;
328
+ }
329
+ // ---- phase 2: execute (write-enabled) ----
330
+ const result = await engine.execute(runOptions);
331
+ usage = addUsage(usage, result.usage);
332
+ summary = result.summary;
333
+ threadId = result.threadId ?? threadId;
334
+ costUsd = result.costUsd;
335
+ costBasis = result.costBasis;
336
+ if (result.error) {
337
+ status = "failed";
338
+ error = result.error;
339
+ }
340
+ }
341
+ catch (err) {
342
+ if (abort.signal.aborted) {
343
+ status = "cancelled";
344
+ logs.push("event", "Job cancelled.");
345
+ }
346
+ else {
347
+ status = "failed";
348
+ error = err instanceof Error ? err.message : String(err);
349
+ logs.push("stderr", error);
350
+ }
351
+ }
352
+ // Flush before finishing so the terminal state never lands ahead of the
353
+ // logs explaining it.
354
+ await logs.flush();
355
+ await report(job.id, status, {
356
+ summary: summary || undefined,
357
+ error,
358
+ threadId: threadId ?? undefined,
359
+ usage,
360
+ costUsd,
361
+ costBasis,
362
+ });
363
+ console.log(`[runner] ■ job ${job.id} → ${status}${costUsd !== undefined ? ` ($${costUsd.toFixed(4)})` : ""}`);
364
+ active = null;
365
+ }
366
+ // Report a terminal state. Never throws — a job whose completion couldn't be
367
+ // recorded is the reaper's problem, not a reason to kill the runner.
368
+ async function report(jobId, status, extra) {
369
+ try {
370
+ await client.mutation(fns.finish, {
371
+ token: options.token,
372
+ runnerId,
373
+ jobId,
374
+ status,
375
+ ...extra,
376
+ });
377
+ }
378
+ catch (err) {
379
+ console.error("[runner] could not report completion:", err instanceof Error ? err.message : err);
380
+ }
381
+ }
382
+ async function tryClaim(job) {
383
+ if (active || claiming || stopped)
384
+ return;
385
+ claiming = true;
386
+ try {
387
+ const result = (await client.mutation(fns.claim, {
388
+ token: options.token,
389
+ runnerId,
390
+ jobId: job.id,
391
+ }));
392
+ // Lost the race to another runner, or it was cancelled first. Nothing to
393
+ // do — the subscription will push the next candidate.
394
+ if (!result.claimed || !result.job)
395
+ return;
396
+ claiming = false;
397
+ await runJob(result.job);
398
+ }
399
+ catch (err) {
400
+ console.error("[runner] claim failed:", err instanceof Error ? err.message : err);
401
+ }
402
+ finally {
403
+ claiming = false;
404
+ }
405
+ }
406
+ // ---- the subscription ---------------------------------------------------
407
+ // This replaces GitHub's long-poll entirely. Convex pushes a new result
408
+ // whenever the queue changes or our own job row is touched, which means both
409
+ // "here is work" and "stop what you're doing" arrive with no latency budget
410
+ // spent on polling.
411
+ // Declared before the subscription so `shutdown` can never observe it in the
412
+ // temporal dead zone if a result arrives synchronously.
413
+ let unsubscribe = null;
414
+ unsubscribe = client.onUpdate(fns.nextJob, { token: options.token, runnerId }, (result) => {
415
+ if (!result.valid) {
416
+ console.error("[runner] token was revoked — shutting down.");
417
+ void shutdown();
418
+ return;
419
+ }
420
+ // Cancellation of the job we're currently executing.
421
+ if (active && result.assigned?.cancelRequested) {
422
+ console.log("[runner] cancellation requested — aborting turn");
423
+ active.abort.abort();
424
+ return;
425
+ }
426
+ if (!active && result.available)
427
+ void tryClaim(result.available);
428
+ }, (err) => {
429
+ console.error("[runner] subscription error:", err.message);
430
+ });
431
+ // ---- shutdown -----------------------------------------------------------
432
+ async function shutdown() {
433
+ if (stopped)
434
+ return;
435
+ stopped = true;
436
+ clearInterval(heartbeat);
437
+ unsubscribe?.();
438
+ // Hand back an in-flight job rather than letting it sit until the lease
439
+ // expires — a clean Ctrl-C should requeue immediately.
440
+ if (active) {
441
+ const jobId = active.jobId;
442
+ active.abort.abort();
443
+ try {
444
+ await client.mutation(fns.finish, {
445
+ token: options.token,
446
+ runnerId,
447
+ jobId,
448
+ status: "failed",
449
+ error: "Runner shut down mid-job",
450
+ });
451
+ }
452
+ catch {
453
+ // Best effort — the reaper will requeue it either way.
454
+ }
455
+ }
456
+ await client.close();
457
+ }
458
+ await new Promise((resolve) => {
459
+ const stop = () => {
460
+ console.log("\n[runner] shutting down…");
461
+ void shutdown().then(resolve);
462
+ };
463
+ process.once("SIGINT", stop);
464
+ process.once("SIGTERM", stop);
465
+ });
466
+ }
467
+ //# sourceMappingURL=runner.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runner.js","sourceRoot":"","sources":["../src/runner.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ // Single source of truth for the package version inside src/.
2
+ //
3
+ // This exists because the version was previously hardcoded in four places and
4
+ // drifted: the published 0.6.11 had no `runner` subcommand while a local build
5
+ // reported the same number, which made "why is my runner not starting?"
6
+ // needlessly hard to diagnose. Keep this in sync with package.json — those two
7
+ // are the only places the number appears.
8
+ export const NUDGE_MCP_VERSION = "0.8.0";
9
+ //# sourceMappingURL=version.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"version.js","sourceRoot":"","sources":["../src/version.ts"],"names":[],"mappings":"AAAA,8DAA8D;AAC9D,EAAE;AACF,8EAA8E;AAC9E,+EAA+E;AAC/E,wEAAwE;AACxE,+EAA+E;AAC/E,0CAA0C;AAC1C,MAAM,CAAC,MAAM,iBAAiB,GAAG,OAAO,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@euqns/nudge-mcp",
3
- "version": "0.6.11",
3
+ "version": "0.8.0",
4
4
  "type": "module",
5
5
  "description": "Model Context Protocol server for the Nudge board (the in-house Trello).",
6
6
  "bin": {
@@ -21,6 +21,8 @@
21
21
  "start": "node dist/index.js",
22
22
  "dev": "tsx src/index.ts",
23
23
  "test": "tsx --test src/codex-companion.test.ts",
24
+ "gen:convex": "npm run build && node scripts/gen-convex-tooldefs.mjs",
25
+ "gen:convex:check": "npm run build && node scripts/gen-convex-tooldefs.mjs --check",
24
26
  "prepublishOnly": "npm run build"
25
27
  },
26
28
  "dependencies": {