wildcrane-runner 0.6.8 → 0.6.9

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.
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- // ai4kanban 0.11.7 — built by runner/scripts/build.mjs. Do not edit.
2
+ // ai4kanban 0.11.8 — built by runner/scripts/build.mjs. Do not edit.
3
3
  import { createRequire as __ai4kanbanRequire } from 'node:module'
4
4
  const require = __ai4kanbanRequire(import.meta.url)
5
5
  var __create = Object.create;
@@ -5477,8 +5477,8 @@ var init_package = __esm({
5477
5477
  "../cli/package.json"() {
5478
5478
  package_default = {
5479
5479
  name: "wildcrane",
5480
- version: "0.11.7",
5481
- akbContract: 3,
5480
+ version: "0.11.8",
5481
+ akbContract: 4,
5482
5482
  description: "WildCrane's `akb` command \u2014 scaffold the Markdown board under docs/kanban/, put an agent on a card, and carry the flows the agent works by.",
5483
5483
  keywords: [
5484
5484
  "kanban",
@@ -11555,6 +11555,43 @@ var init_run_settings = __esm({
11555
11555
  }
11556
11556
  });
11557
11557
 
11558
+ // ../cli/src/lib/cloud/execution.ts
11559
+ function executionOf(value = process.env.AI4KANBAN_EXECUTION) {
11560
+ try {
11561
+ const held4 = typeof value === "string" ? JSON.parse(value) : value;
11562
+ if (held4 && UUID.test(held4.job) && UUID.test(held4.machine)) return { job: held4.job, machine: held4.machine };
11563
+ } catch {
11564
+ }
11565
+ return void 0;
11566
+ }
11567
+ async function executionHeld(execution) {
11568
+ if (!execution) return true;
11569
+ try {
11570
+ const auth = await accessToken();
11571
+ if (!auth.ok) return false;
11572
+ const response = await fetch(`${cloudEndpoints().api}/v1/runner/jobs/${execution.job}/renew`, {
11573
+ method: "POST",
11574
+ headers: { authorization: `Bearer ${auth.token}`, "content-type": "application/json" },
11575
+ body: JSON.stringify({ machineId: execution.machine }),
11576
+ signal: AbortSignal.timeout(2e4)
11577
+ });
11578
+ if (!response.ok) return false;
11579
+ const held4 = await response.json();
11580
+ return held4.renewed === true && held4.stop !== true;
11581
+ } catch {
11582
+ return false;
11583
+ }
11584
+ }
11585
+ var UUID;
11586
+ var init_execution = __esm({
11587
+ "../cli/src/lib/cloud/execution.ts"() {
11588
+ "use strict";
11589
+ init_config();
11590
+ init_session();
11591
+ UUID = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
11592
+ }
11593
+ });
11594
+
11558
11595
  // ../cli/src/lib/agent/log.ts
11559
11596
  import fs28 from "node:fs";
11560
11597
  import path31 from "node:path";
@@ -11887,6 +11924,7 @@ function readDeliveryRow(raw) {
11887
11924
  startedAt: typeof entry.startedAt === "number" ? entry.startedAt : Date.now(),
11888
11925
  endedAt: typeof entry.endedAt === "number" ? entry.endedAt : void 0,
11889
11926
  sessions: Array.isArray(entry.sessions) ? entry.sessions.filter((s) => typeof s === "string") : [],
11927
+ cloudExecution: executionOf(entry.cloudExecution ?? null),
11890
11928
  approved: typeof entry.approved === "string" ? entry.approved : "",
11891
11929
  // The plan a card-less build was started from (#481), where it was one.
11892
11930
  plan: text2(entry.plan),
@@ -12144,6 +12182,7 @@ var KEEP_RUNS, KEEP_DELIVERIES, logPathOf, eventsPathOf, WAS_CLARIFY, RETIRED_AC
12144
12182
  var init_store = __esm({
12145
12183
  "../cli/src/lib/agent/store.ts"() {
12146
12184
  "use strict";
12185
+ init_execution();
12147
12186
  init_file_memo();
12148
12187
  init_lock();
12149
12188
  init_paths();
@@ -16593,6 +16632,7 @@ function resumeRecord(id) {
16593
16632
  const at = Date.now();
16594
16633
  const resumed = {
16595
16634
  ...row,
16635
+ cloudExecution: executionOf() ?? row.cloudExecution,
16596
16636
  status: "active",
16597
16637
  endedAt: void 0,
16598
16638
  steps: [...row.steps, { step: "resume", at }],
@@ -16697,6 +16737,7 @@ function joinDelivery(store, run2, title, step, start, direct) {
16697
16737
  // The one read of the card this delivery will ever make for its requirements — or,
16698
16738
  // with no card, the sentence or the plan's words it was handed, which can never move
16699
16739
  // under it.
16740
+ cloudExecution: executionOf(),
16700
16741
  approved: cardId2 === null ? direct?.approved ?? "" : approvedRequirements(cardId2),
16701
16742
  // …and, where that was a plan, the file it was read from (#481) — the one way back to
16702
16743
  // it once the panel has let the plan go.
@@ -16893,6 +16934,7 @@ var auditPath, activeAudits, auditRow, lastSessionRunning, unknownDelivery, isRe
16893
16934
  var init_deliveries = __esm({
16894
16935
  "../cli/src/lib/agent/deliveries.ts"() {
16895
16936
  "use strict";
16937
+ init_execution();
16896
16938
  init_cards();
16897
16939
  init_frontmatter();
16898
16940
  init_paths();
@@ -17412,6 +17454,10 @@ function blockLanding(deliveryId, why) {
17412
17454
  return { ok: true };
17413
17455
  }
17414
17456
  async function move(delivery, tip, target) {
17457
+ if (!await executionHeld(delivery.cloudExecution)) {
17458
+ giveUpSlot(delivery, "\u65E0\u6CD5\u786E\u8BA4\u6267\u884C\u6743\uFF0C\u5DF2\u4FDD\u7559\u672C\u5730\u4EA4\u4ED8\u3002");
17459
+ return { done: true };
17460
+ }
17415
17461
  const branch = delivery.targetBranch;
17416
17462
  const checkout = branchWorktree(branch);
17417
17463
  const moved = checkout ? asMove(fastForward(tip, checkout)) : moveBranchRef(branch, tip, target);
@@ -17503,6 +17549,7 @@ var MAX_NAMED2, names2, some2, are, them, sayWhy, questionWhy, wasHeldOnQuestion
17503
17549
  var init_landing = __esm({
17504
17550
  "../cli/src/lib/agent/landing.ts"() {
17505
17551
  "use strict";
17552
+ init_execution();
17506
17553
  init_board();
17507
17554
  init_io();
17508
17555
  init_lock();
@@ -18232,13 +18279,17 @@ import { spawnSync as spawnSync4 } from "node:child_process";
18232
18279
  import { randomUUID as randomUUID5 } from "node:crypto";
18233
18280
  import fs47 from "node:fs";
18234
18281
  import os6 from "node:os";
18235
- function markedInProc(entry) {
18282
+ function markedInProc(entry, strict = false) {
18236
18283
  const pids = [];
18237
18284
  for (const name of fs47.readdirSync("/proc")) {
18238
18285
  if (!/^\d+$/.test(name)) continue;
18239
18286
  try {
18240
18287
  if (fs47.readFileSync(`/proc/${name}/environ`, "utf8").split("\0").includes(entry)) pids.push(Number(name));
18241
- } catch {
18288
+ } catch (error) {
18289
+ if (strict && !["ENOENT", "ESRCH"].includes(error.code ?? "")) {
18290
+ const stat = fs47.statSync(`/proc/${name}`, { throwIfNoEntry: false });
18291
+ if (stat?.uid === process.getuid?.()) throw error;
18292
+ }
18242
18293
  }
18243
18294
  }
18244
18295
  return pids;
@@ -18249,7 +18300,7 @@ function markedInPs(entry, roots) {
18249
18300
  maxBuffer: 64 * 1024 * 1024,
18250
18301
  timeout: 5e3
18251
18302
  });
18252
- if (ps.status !== 0 || !ps.stdout) return [];
18303
+ if (ps.status !== 0 || !ps.stdout) throw new Error("\u65E0\u6CD5\u67E5\u8BE2\u8FDB\u7A0B\u6811\u3002");
18253
18304
  const children = /* @__PURE__ */ new Map();
18254
18305
  const listed2 = /* @__PURE__ */ new Set();
18255
18306
  const found2 = /* @__PURE__ */ new Set();
@@ -23318,7 +23369,7 @@ var init_review_rejections = __esm({
23318
23369
  var refine_default;
23319
23370
  var init_refine = __esm({
23320
23371
  "../cli/src/guide/refine.md"() {
23321
- refine_default = '# Refine a card\n\nPlan one card in this session until it can be built. Change no project code.\n\n- **Unchecked card**: a card with `triage:` set and an empty `## Scope` was never checked\n against the project. Search the relevant code and docs first; when the project already does\n the work, or what it concerns no longer exists, run\n `akb raw reject <id> --reason "<what shows it>"` and stop.\n- **Gone or already done**: for any other card, append a question asking the user whether to\n discard it, run no preview agent, and stop.\n- **Split**: only when the card holds independently plannable areas and one is still vague,\n follow the group procedure in `akb guide add-task`, create each subtask, and stop: Cloud\n refines each one itself.\n- **Workflow rules**: write the card as the workflow rules at the end of this prompt say.\n- **Choose preview agents**: when the card\'s frontmatter has no `previews`, record every listed\n agent with no `When` and every one whose `When` the card meets with\n `akb raw update <id> --previews <agents>`, or `--previews ""` when none is met. Skip a met\n agent only for a reason its own `When` gives. Later, add or drop only an agent that has not run.\n- **Preview agents**: an agent\'s `After` names the previews it waits for; the board approves\n previews in stages, one stage per Approve. For example, with `copywriting`, `illustrator`\n and `ui-designer` chosen and `ui-designer` listed as `After: copywriting, illustrator`, this\n session runs the first two, and `ui-designer` runs in the planning that starts once the user\n approves them. Run each agent of the current stage whose section is missing or outdated with\n `akb spec <agent> <id> --print`, one at a time in this session; leave out `--print` only for\n an agent the list says runs in a session of its own.\n- **Stale mentions**: rewrite any sentence that relies on a card no longer on the board.\n- **Questions**: settle every decision you can and record the answers as `akb guide writing`\n says; ask only what `akb guide update-questions` says to ask.\n- **Write**: shape the card as `akb guide writing` says, then run `akb raw validate <id>` and\n fix every reported line.\n- **Think like the one who ships it**: settle every fact from the code and authoritative\n sources, and write what shipping takes beyond the happy path: existing data and settings,\n release and rollback, failure, access, and ongoing cost. Once the card validates and its\n `previews` are recorded, judge whether it can be built as written, or before its last\n Approve: if so, run `akb raw update <id> --status ready`; otherwise leave what blocks it as\n an open question.\n\nFollow any closing steps the flow printed, then stop: the user approves the previews or starts\nthe build.\n';
23372
+ refine_default = '# Refine a card\n\nPlan one card in this session until it can be built. Change no project code.\n\n- **\u91CD\u590D\u5361\u7247**: \u82E5\u53D1\u73B0\u53E6\u4E00\u5F20\u4EFB\u52A1\u5B8C\u6574\u8986\u76D6\u672C\u5361\uFF0C\u5373\u4F7F\u5BF9\u65B9\u5C1A\u672A\u5B9E\u65BD\uFF0C\u4E5F\u5148\u5C06\u5176\u7F3A\u5C11\u7684\u6709\u7528\u4FE1\u606F\u8865\u5165\u5E76\u786E\u8BA4\u4FDD\u5B58\u6210\u529F\uFF1B\n \u4FDD\u5B58\u5931\u8D25\u5219\u4FDD\u7559\u672C\u5361\u5E76\u505C\u6B62\u3002\u6CA1\u6709\u4FE1\u606F\u9700\u8981\u8865\u5145\u6216\u5DF2\u4FDD\u5B58\u6210\u529F\u540E\uFF0C\u8FD0\u884C\n `akb raw reject <id> --reason "<\u627F\u63A5\u4EFB\u52A1\u7F16\u53F7\u53CA\u5B8C\u6574\u8986\u76D6\u539F\u56E0>"` \u5E76\u505C\u6B62\u3002\n \u4E0D\u8BF7\u6C42\u786E\u8BA4\uFF0C\u4E0D\u8FD0\u884C\u9884\u89C8\uFF1B\u4EC5\u90E8\u5206\u91CD\u53E0\u4E0D\u4E22\u5F03\u3002\n- **Unchecked card**: a card with `triage:` set and an empty `## Scope` was never checked\n against the project. Search the relevant code and docs first; when the project already does\n the work, or what it concerns no longer exists, run\n `akb raw reject <id> --reason "<what shows it>"` and stop.\n- **Gone or already done**: for any other card, append a question asking the user whether to\n discard it, run no preview agent, and stop.\n- **Split**: only when the card holds independently plannable areas and one is still vague,\n follow the group procedure in `akb guide add-task`, create each subtask, and stop: Cloud\n refines each one itself.\n- **Workflow rules**: write the card as the workflow rules at the end of this prompt say.\n- **Choose preview agents**: when the card\'s frontmatter has no `previews`, record every listed\n agent with no `When` and every one whose `When` the card meets with\n `akb raw update <id> --previews <agents>`, or `--previews ""` when none is met. Skip a met\n agent only for a reason its own `When` gives. Later, add or drop only an agent that has not run.\n- **Preview agents**: an agent\'s `After` names the previews it waits for; the board approves\n previews in stages, one stage per Approve. For example, with `copywriting`, `illustrator`\n and `ui-designer` chosen and `ui-designer` listed as `After: copywriting, illustrator`, this\n session runs the first two, and `ui-designer` runs in the planning that starts once the user\n approves them. Run each agent of the current stage whose section is missing or outdated with\n `akb spec <agent> <id> --print`, one at a time in this session; leave out `--print` only for\n an agent the list says runs in a session of its own.\n- **Stale mentions**: rewrite any sentence that relies on a card no longer on the board.\n- **Questions**: settle every decision you can and record the answers as `akb guide writing`\n says; ask only what `akb guide update-questions` says to ask.\n- **Write**: shape the card as `akb guide writing` says, then run `akb raw validate <id>` and\n fix every reported line.\n- **Think like the one who ships it**: settle every fact from the code and authoritative\n sources, and write what shipping takes beyond the happy path: existing data and settings,\n release and rollback, failure, access, and ongoing cost. Once the card validates and its\n `previews` are recorded, judge whether it can be built as written, or before its last\n Approve: if so, run `akb raw update <id> --status ready`; otherwise leave what blocks it as\n an open question.\n\nFollow any closing steps the flow printed, then stop: the user approves the previews or starts\nthe build.\n';
23322
23373
  }
23323
23374
  });
23324
23375
 
@@ -1 +1 @@
1
- {"name":"wildcrane","version":"0.11.7","akbContract":3,"type":"module","private":true}
1
+ {"name":"wildcrane","version":"0.11.8","akbContract":4,"type":"module","private":true}
package/dist/launcher.mjs CHANGED
@@ -1,4 +1,4 @@
1
- // wildcrane-runner 0.6.8 — built by runner/scripts/build.mjs. Do not edit.
1
+ // wildcrane-runner 0.6.9 — built by runner/scripts/build.mjs. Do not edit.
2
2
  import { createRequire as __ai4kanbanRequire } from 'node:module'
3
3
  const require = __ai4kanbanRequire(import.meta.url)
4
4
 
@@ -107,7 +107,7 @@ function status(line) {
107
107
  }
108
108
 
109
109
  // src/protocol.ts
110
- var VERSION = true ? "0.6.8" : "0.0.0";
110
+ var VERSION = true ? "0.6.9" : "0.0.0";
111
111
  var EXIT_REFUSED = 10;
112
112
  var EXIT_OUTDATED = 11;
113
113
  var EXIT_UPDATE = 12;