wildcrane 0.11.7 → 0.11.8

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.
Files changed (2) hide show
  1. package/dist/kanban.mjs +58 -7
  2. package/package.json +2 -2
package/dist/kanban.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- // ai4kanban 0.11.7 — built from the CLI's TypeScript sources by cli/scripts/build.mjs.
2
+ // ai4kanban 0.11.8 — built from the CLI's TypeScript sources by cli/scripts/build.mjs.
3
3
  // Do not edit: every change belongs in cli/src/, and a build overwrites this file.
4
4
  import { createRequire as __ai4kanbanRequire } from 'node:module'
5
5
  const require = __ai4kanbanRequire(import.meta.url)
@@ -5478,8 +5478,8 @@ var init_package = __esm({
5478
5478
  "package.json"() {
5479
5479
  package_default = {
5480
5480
  name: "wildcrane",
5481
- version: "0.11.7",
5482
- akbContract: 3,
5481
+ version: "0.11.8",
5482
+ akbContract: 4,
5483
5483
  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.",
5484
5484
  keywords: [
5485
5485
  "kanban",
@@ -11556,6 +11556,43 @@ var init_run_settings = __esm({
11556
11556
  }
11557
11557
  });
11558
11558
 
11559
+ // src/lib/cloud/execution.ts
11560
+ function executionOf(value = process.env.AI4KANBAN_EXECUTION) {
11561
+ try {
11562
+ const held4 = typeof value === "string" ? JSON.parse(value) : value;
11563
+ if (held4 && UUID.test(held4.job) && UUID.test(held4.machine)) return { job: held4.job, machine: held4.machine };
11564
+ } catch {
11565
+ }
11566
+ return void 0;
11567
+ }
11568
+ async function executionHeld(execution) {
11569
+ if (!execution) return true;
11570
+ try {
11571
+ const auth = await accessToken();
11572
+ if (!auth.ok) return false;
11573
+ const response = await fetch(`${cloudEndpoints().api}/v1/runner/jobs/${execution.job}/renew`, {
11574
+ method: "POST",
11575
+ headers: { authorization: `Bearer ${auth.token}`, "content-type": "application/json" },
11576
+ body: JSON.stringify({ machineId: execution.machine }),
11577
+ signal: AbortSignal.timeout(2e4)
11578
+ });
11579
+ if (!response.ok) return false;
11580
+ const held4 = await response.json();
11581
+ return held4.renewed === true && held4.stop !== true;
11582
+ } catch {
11583
+ return false;
11584
+ }
11585
+ }
11586
+ var UUID;
11587
+ var init_execution = __esm({
11588
+ "src/lib/cloud/execution.ts"() {
11589
+ "use strict";
11590
+ init_config();
11591
+ init_session();
11592
+ UUID = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
11593
+ }
11594
+ });
11595
+
11559
11596
  // src/lib/agent/log.ts
11560
11597
  import fs28 from "node:fs";
11561
11598
  import path31 from "node:path";
@@ -11888,6 +11925,7 @@ function readDeliveryRow(raw) {
11888
11925
  startedAt: typeof entry.startedAt === "number" ? entry.startedAt : Date.now(),
11889
11926
  endedAt: typeof entry.endedAt === "number" ? entry.endedAt : void 0,
11890
11927
  sessions: Array.isArray(entry.sessions) ? entry.sessions.filter((s) => typeof s === "string") : [],
11928
+ cloudExecution: executionOf(entry.cloudExecution ?? null),
11891
11929
  approved: typeof entry.approved === "string" ? entry.approved : "",
11892
11930
  // The plan a card-less build was started from (#481), where it was one.
11893
11931
  plan: text2(entry.plan),
@@ -12145,6 +12183,7 @@ var KEEP_RUNS, KEEP_DELIVERIES, logPathOf, eventsPathOf, WAS_CLARIFY, RETIRED_AC
12145
12183
  var init_store = __esm({
12146
12184
  "src/lib/agent/store.ts"() {
12147
12185
  "use strict";
12186
+ init_execution();
12148
12187
  init_file_memo();
12149
12188
  init_lock();
12150
12189
  init_paths();
@@ -16594,6 +16633,7 @@ function resumeRecord(id) {
16594
16633
  const at = Date.now();
16595
16634
  const resumed = {
16596
16635
  ...row,
16636
+ cloudExecution: executionOf() ?? row.cloudExecution,
16597
16637
  status: "active",
16598
16638
  endedAt: void 0,
16599
16639
  steps: [...row.steps, { step: "resume", at }],
@@ -16698,6 +16738,7 @@ function joinDelivery(store, run2, title, step, start, direct) {
16698
16738
  // The one read of the card this delivery will ever make for its requirements — or,
16699
16739
  // with no card, the sentence or the plan's words it was handed, which can never move
16700
16740
  // under it.
16741
+ cloudExecution: executionOf(),
16701
16742
  approved: cardId2 === null ? direct?.approved ?? "" : approvedRequirements(cardId2),
16702
16743
  // …and, where that was a plan, the file it was read from (#481) — the one way back to
16703
16744
  // it once the panel has let the plan go.
@@ -16894,6 +16935,7 @@ var auditPath, activeAudits, auditRow, lastSessionRunning, unknownDelivery, isRe
16894
16935
  var init_deliveries = __esm({
16895
16936
  "src/lib/agent/deliveries.ts"() {
16896
16937
  "use strict";
16938
+ init_execution();
16897
16939
  init_cards();
16898
16940
  init_frontmatter();
16899
16941
  init_paths();
@@ -17413,6 +17455,10 @@ function blockLanding(deliveryId, why) {
17413
17455
  return { ok: true };
17414
17456
  }
17415
17457
  async function move(delivery, tip, target) {
17458
+ if (!await executionHeld(delivery.cloudExecution)) {
17459
+ giveUpSlot(delivery, "\u65E0\u6CD5\u786E\u8BA4\u6267\u884C\u6743\uFF0C\u5DF2\u4FDD\u7559\u672C\u5730\u4EA4\u4ED8\u3002");
17460
+ return { done: true };
17461
+ }
17416
17462
  const branch = delivery.targetBranch;
17417
17463
  const checkout = branchWorktree(branch);
17418
17464
  const moved = checkout ? asMove(fastForward(tip, checkout)) : moveBranchRef(branch, tip, target);
@@ -17504,6 +17550,7 @@ var MAX_NAMED2, names2, some2, are, them, sayWhy, questionWhy, wasHeldOnQuestion
17504
17550
  var init_landing = __esm({
17505
17551
  "src/lib/agent/landing.ts"() {
17506
17552
  "use strict";
17553
+ init_execution();
17507
17554
  init_board();
17508
17555
  init_io();
17509
17556
  init_lock();
@@ -18233,13 +18280,17 @@ import { spawnSync as spawnSync4 } from "node:child_process";
18233
18280
  import { randomUUID as randomUUID5 } from "node:crypto";
18234
18281
  import fs47 from "node:fs";
18235
18282
  import os6 from "node:os";
18236
- function markedInProc(entry) {
18283
+ function markedInProc(entry, strict = false) {
18237
18284
  const pids = [];
18238
18285
  for (const name of fs47.readdirSync("/proc")) {
18239
18286
  if (!/^\d+$/.test(name)) continue;
18240
18287
  try {
18241
18288
  if (fs47.readFileSync(`/proc/${name}/environ`, "utf8").split("\0").includes(entry)) pids.push(Number(name));
18242
- } catch {
18289
+ } catch (error) {
18290
+ if (strict && !["ENOENT", "ESRCH"].includes(error.code ?? "")) {
18291
+ const stat = fs47.statSync(`/proc/${name}`, { throwIfNoEntry: false });
18292
+ if (stat?.uid === process.getuid?.()) throw error;
18293
+ }
18243
18294
  }
18244
18295
  }
18245
18296
  return pids;
@@ -18250,7 +18301,7 @@ function markedInPs(entry, roots) {
18250
18301
  maxBuffer: 64 * 1024 * 1024,
18251
18302
  timeout: 5e3
18252
18303
  });
18253
- if (ps.status !== 0 || !ps.stdout) return [];
18304
+ if (ps.status !== 0 || !ps.stdout) throw new Error("\u65E0\u6CD5\u67E5\u8BE2\u8FDB\u7A0B\u6811\u3002");
18254
18305
  const children = /* @__PURE__ */ new Map();
18255
18306
  const listed2 = /* @__PURE__ */ new Set();
18256
18307
  const found2 = /* @__PURE__ */ new Set();
@@ -23319,7 +23370,7 @@ var init_review_rejections = __esm({
23319
23370
  var refine_default;
23320
23371
  var init_refine = __esm({
23321
23372
  "src/guide/refine.md"() {
23322
- 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';
23373
+ 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';
23323
23374
  }
23324
23375
  });
23325
23376
 
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "wildcrane",
3
- "version": "0.11.7",
4
- "akbContract": 3,
3
+ "version": "0.11.8",
4
+ "akbContract": 4,
5
5
  "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.",
6
6
  "keywords": [
7
7
  "kanban",