@open-tomato/rafa 0.35.0 → 0.37.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.
@@ -1,43 +1,49 @@
1
1
  // @bun
2
2
  import {
3
+ CONFIG_DEFAULTS,
4
+ CONFIG_FILE,
5
+ ConfigError,
6
+ FINDING_DOMAINS,
7
+ FINDING_KINDS,
8
+ FINDING_SIGNALS,
9
+ activeOutput,
10
+ activeOutputMode,
11
+ configFilePath,
12
+ createTextOutput,
13
+ hubContextOf,
14
+ isStampableStub,
15
+ parseConfigText,
16
+ readRafaBlocks,
17
+ resolveConfig
18
+ } from "./index-jfas157k.js";
19
+ import {
20
+ bless,
21
+ merge
22
+ } from "./index-d6d0942q.js";
23
+ import {
24
+ CommandExit,
25
+ commandSpelling
26
+ } from "./index-3mzw3kzh.js";
27
+ import {
28
+ BUSY_TIMEOUT_MAX_MS,
29
+ BUSY_TIMEOUT_MIN_MS,
3
30
  RAFA_INSTINCTS_PATH,
4
- bundledBinDirectory,
5
- resolveInstinctScopes,
6
- tierExists,
31
+ STORE_BACKENDS,
32
+ SYNC_STRATEGIES,
7
33
  TEST_SCOPES,
8
- isMapping,
34
+ bundledBinDirectory,
9
35
  describeValue,
10
- messageOf,
11
- STORE_BACKENDS2,
12
- SYNC_STRATEGIES2,
13
- BUSY_TIMEOUT_MIN_MS,
14
- BUSY_TIMEOUT_MAX_MS,
15
36
  isBusyTimeoutMs,
16
37
  isGitHubLogin,
17
- hubContextOf,
18
- CONFIG_FILE2,
19
- CONFIG_DEFAULTS2,
20
- ConfigError2,
21
- configFilePath2,
22
- parseConfigText2,
23
- resolveConfig2,
24
- isStampableStub,
25
- createTextOutput,
26
- activeOutput,
27
- activeOutputMode,
28
- readRafaBlocks2,
29
- FINDING_KINDS2,
30
- FINDING_SIGNALS2,
31
- FINDING_DOMAINS
32
- } from "./index-2tjmxwvp.js";
33
- import {
34
- bless2,
35
- merge2
36
- } from "./index-hgcvjke7.js";
38
+ isMapping,
39
+ messageOf,
40
+ resolveInstinctScopes,
41
+ tierExists
42
+ } from "./index-fzhd3d4y.js";
37
43
  import {
38
- actionHash2,
39
- triggerKey2
40
- } from "./index-21jcfatr.js";
44
+ actionHash,
45
+ triggerKey
46
+ } from "./index-wp8c28fd.js";
41
47
 
42
48
  // src/adapters/registry.ts
43
49
  import { homedir } from "os";
@@ -211,7 +217,7 @@ function guardTestProcess(path, probe = currentProbe()) {
211
217
  function keyOrNull(value) {
212
218
  return typeof value === "string" && value.length > 0 ? value : null;
213
219
  }
214
- var EFFORT_KEY_PROJECTIONS2 = {
220
+ var EFFORT_KEY_PROJECTIONS = {
215
221
  sessions: (row) => keyOrNull(row.sessionId),
216
222
  commits: (row) => keyOrNull(row.sha)
217
223
  };
@@ -230,13 +236,13 @@ function readKind(repoRoot, kind) {
230
236
  }
231
237
  function keysOfKind(repoRoot, kind) {
232
238
  const path = openedKindPath(repoRoot, kind);
233
- return collectedKeys(path, EFFORT_KEY_PROJECTIONS2[kind]);
239
+ return collectedKeys(path, EFFORT_KEY_PROJECTIONS[kind]);
234
240
  }
235
241
  function appendKind(repoRoot, kind, rows) {
236
242
  const path = openedKindPath(repoRoot, kind);
237
- return appendRows(path, rows, EFFORT_KEY_PROJECTIONS2[kind]);
243
+ return appendRows(path, rows, EFFORT_KEY_PROJECTIONS[kind]);
238
244
  }
239
- function openNdjsonStore2(repoRoot) {
245
+ function openNdjsonStore(repoRoot) {
240
246
  return {
241
247
  append: (kind, rows) => appendKind(repoRoot, kind, rows),
242
248
  keys: (kind) => keysOfKind(repoRoot, kind),
@@ -253,7 +259,7 @@ import { Database as Database2 } from "bun:sqlite";
253
259
 
254
260
  // package.json
255
261
  var name = "@open-tomato/rafa";
256
- var version = "0.35.0";
262
+ var version = "0.37.0";
257
263
 
258
264
  // src/cli/version.ts
259
265
  var RAFA_VERSION = version;
@@ -346,36 +352,36 @@ function mainCheckoutOf(dir, seams = {}) {
346
352
  }
347
353
 
348
354
  // src/project/scope.ts
349
- var SCOPE_DIR2 = dirname3(CONFIG_FILE2);
350
- var INIT_COMMAND2 = "rafa init";
351
- var DISK_FILE_SYSTEM2 = Object.freeze({
355
+ var SCOPE_DIR = dirname3(CONFIG_FILE);
356
+ var INIT_COMMAND = "rafa init";
357
+ var DISK_FILE_SYSTEM = Object.freeze({
352
358
  exists: (path) => existsSync3(path),
353
359
  realpath: (path) => realpathSync2(path)
354
360
  });
355
361
 
356
- class ScopeError2 extends Error {
362
+ class ScopeError extends Error {
357
363
  constructor(message, options) {
358
364
  super(`rafa scope: ${message}`, options);
359
365
  this.name = "ScopeError";
360
366
  }
361
367
  }
362
- function scopeAt2(base) {
363
- return { dir: join4(base, SCOPE_DIR2), configFile: configFilePath2(base) };
368
+ function scopeAt(base) {
369
+ return { dir: join4(base, SCOPE_DIR), configFile: configFilePath(base) };
364
370
  }
365
- function initHint2(start, passedUserConfig = null, probedMainCheckout = null) {
371
+ function initHint(start, passedUserConfig = null, probedMainCheckout = null) {
366
372
  const passed = passedUserConfig === null ? [] : [`${passedUserConfig} is the user scope's config and marks no project`];
367
373
  const main = probedMainCheckout === null ? [] : [`nor in ${probedMainCheckout}, the main checkout of the repository holding it`];
368
374
  return [
369
- `not inside a rafa project: no ${CONFIG_FILE2} in ${start} or any directory above it`,
375
+ `not inside a rafa project: no ${CONFIG_FILE} in ${start} or any directory above it`,
370
376
  ...main,
371
377
  ...passed,
372
- `run \`${INIT_COMMAND2}\` to set one up`
378
+ `run \`${INIT_COMMAND}\` to set one up`
373
379
  ].join(`
374
380
  `);
375
381
  }
376
382
  function requireAbsolute(label, path) {
377
383
  if (!isAbsolute3(path)) {
378
- throw new ScopeError2(`${label} is ${describeValue(path)}, expected an absolute path`);
384
+ throw new ScopeError(`${label} is ${describeValue(path)}, expected an absolute path`);
379
385
  }
380
386
  }
381
387
  function realStartOf(start, fs) {
@@ -383,7 +389,7 @@ function realStartOf(start, fs) {
383
389
  return fs.realpath(start);
384
390
  } catch (error) {
385
391
  const message = `start directory ${start} does not resolve (${messageOf(error)})`;
386
- throw new ScopeError2(message, { cause: error });
392
+ throw new ScopeError(message, { cause: error });
387
393
  }
388
394
  }
389
395
  function realHomeOf(home, fs) {
@@ -393,15 +399,15 @@ function realHomeOf(home, fs) {
393
399
  return null;
394
400
  }
395
401
  }
396
- function selfAndAncestors2(path) {
402
+ function selfAndAncestors(path) {
397
403
  const parent = dirname3(path);
398
- return parent === path ? [path] : [path, ...selfAndAncestors2(parent)];
404
+ return parent === path ? [path] : [path, ...selfAndAncestors(parent)];
399
405
  }
400
406
  var GIT_MARKER = ".git";
401
407
  function walkUp(dirs, realHome, fs, stopAtTopLevel) {
402
408
  let passedUserConfig = false;
403
409
  for (const dir of dirs) {
404
- if (fs.exists(configFilePath2(dir))) {
410
+ if (fs.exists(configFilePath(dir))) {
405
411
  if (dir !== realHome)
406
412
  return { root: dir, passedUserConfig, topLevel: null };
407
413
  passedUserConfig = true;
@@ -418,39 +424,39 @@ function mainCheckoutAt(realStart, mainCheckout) {
418
424
  } catch (error) {
419
425
  if (!(error instanceof WorktreeRootError))
420
426
  throw error;
421
- throw new ScopeError2(`cannot read the main checkout of ${realStart} (${error.message})`, { cause: error });
427
+ throw new ScopeError(`cannot read the main checkout of ${realStart} (${error.message})`, { cause: error });
422
428
  }
423
429
  }
424
430
  function fallBack(realStart, realHome, fs, mainCheckout) {
425
431
  const main = mainCheckoutAt(realStart, mainCheckout);
426
- if (main === null || main === realHome || selfAndAncestors2(realStart).includes(main)) {
432
+ if (main === null || main === realHome || selfAndAncestors(realStart).includes(main)) {
427
433
  return { root: null, probed: null };
428
434
  }
429
- return fs.exists(configFilePath2(main)) ? { root: main, probed: main } : { root: null, probed: main };
435
+ return fs.exists(configFilePath(main)) ? { root: main, probed: main } : { root: null, probed: main };
430
436
  }
431
437
  function walkAbove(lower, realHome, fs) {
432
438
  if (lower.topLevel === null)
433
439
  return lower;
434
- const above = selfAndAncestors2(lower.topLevel).slice(1);
440
+ const above = selfAndAncestors(lower.topLevel).slice(1);
435
441
  const upper = walkUp(above, realHome, fs, false);
436
442
  return { ...upper, passedUserConfig: lower.passedUserConfig || upper.passedUserConfig };
437
443
  }
438
- function resolveScope2(start, seams) {
439
- const { home, fs = DISK_FILE_SYSTEM2, mainCheckout = mainCheckoutOf } = seams;
444
+ function resolveScope(start, seams) {
445
+ const { home, fs = DISK_FILE_SYSTEM, mainCheckout = mainCheckoutOf } = seams;
440
446
  requireAbsolute("start directory", start);
441
447
  requireAbsolute("home directory", home);
442
- const user = scopeAt2(home);
448
+ const user = scopeAt(home);
443
449
  const realStart = realStartOf(start, fs);
444
450
  const realHome = realHomeOf(home, fs);
445
- const lower = walkUp(selfAndAncestors2(realStart), realHome, fs, true);
451
+ const lower = walkUp(selfAndAncestors(realStart), realHome, fs, true);
446
452
  const fallback = lower.root === null ? fallBack(realStart, realHome, fs, mainCheckout) : { root: lower.root, probed: null };
447
453
  const walk = fallback.root === null ? walkAbove(lower, realHome, fs) : lower;
448
454
  const root = fallback.root ?? walk.root;
449
455
  if (root === null) {
450
456
  const passed = walk.passedUserConfig ? user.configFile : null;
451
- return { found: false, start, home, user, hint: initHint2(start, passed, fallback.probed) };
457
+ return { found: false, start, home, user, hint: initHint(start, passed, fallback.probed) };
452
458
  }
453
- return { found: true, root, home, project: scopeAt2(root), user };
459
+ return { found: true, root, home, project: scopeAt(root), user };
454
460
  }
455
461
 
456
462
  // src/loop/session-record-parse.ts
@@ -467,7 +473,7 @@ import { mkdirSync as mkdirSync2, readFileSync as readFileSync2, renameSync, rmS
467
473
  import { dirname as dirname4, join as join5 } from "path";
468
474
  var POSITION_FILE = "position.json";
469
475
  function positionFilePath(root) {
470
- return join5(scopeAt2(root).dir, POSITION_FILE);
476
+ return join5(scopeAt(root).dir, POSITION_FILE);
471
477
  }
472
478
  function isRecord(value) {
473
479
  return typeof value === "object" && value !== null && !Array.isArray(value);
@@ -544,7 +550,7 @@ var HOP_FILE = "hop.json";
544
550
  var HOP_KINDS = ["blocker", "dry"];
545
551
  var HOP_STATES = ["away", "waiting", "merged", "halted"];
546
552
  function hopFilePath(root) {
547
- return join6(scopeAt2(root).dir, HOP_FILE);
553
+ return join6(scopeAt(root).dir, HOP_FILE);
548
554
  }
549
555
  function isRecord2(value) {
550
556
  return typeof value === "object" && value !== null && !Array.isArray(value);
@@ -650,6 +656,7 @@ var DEFAULT_PHASE = "task";
650
656
  var RECORD_EXTENSION = ".json";
651
657
  var SESSION_ID_PATTERN = /^[A-Za-z0-9][A-Za-z0-9._-]{0,127}$/;
652
658
  var SESSION_STEP_KINDS = Object.freeze(["baseline", "task", "stage", "pre-wrap-up"]);
659
+ var SESSION_STEP_REASONS = Object.freeze(["declared", "trigger", "fallback", "no-module-tests", "stage"]);
653
660
 
654
661
  class SessionRecordError extends Error {
655
662
  file;
@@ -690,8 +697,8 @@ function taskProblem(task) {
690
697
  function hopProblem(fields) {
691
698
  if (!Object.hasOwn(fields, "hop"))
692
699
  return null;
693
- const hop = field(fields, "hop");
694
- return asHopRecord(hop) === null ? `hop is ${describeValue2(hop)}, expected a hop record` : null;
700
+ const hop2 = field(fields, "hop");
701
+ return asHopRecord(hop2) === null ? `hop is ${describeValue2(hop2)}, expected a hop record` : null;
695
702
  }
696
703
  function worktreeProblem(fields) {
697
704
  if (!Object.hasOwn(fields, "worktree"))
@@ -793,16 +800,23 @@ function phaseEntry(phase) {
793
800
  return isSessionPhase(phase) ? { phase } : {};
794
801
  }
795
802
  function freezeHop(value) {
796
- const hop = asHopRecord(value);
797
- return Object.freeze({ ...hop, home: Object.freeze(hop.home), from: Object.freeze(hop.from) });
803
+ const hop2 = asHopRecord(value);
804
+ return Object.freeze({ ...hop2, home: Object.freeze(hop2.home), from: Object.freeze(hop2.from) });
798
805
  }
799
806
  function freezeFailures(failures) {
800
807
  return Object.freeze(failures.map((failure) => Object.freeze({ file: failure.file, name: failure.name })));
801
808
  }
809
+ function isSessionStepReason(value) {
810
+ return SESSION_STEP_REASONS.includes(value);
811
+ }
812
+ function reasonEntry(reason) {
813
+ return isSessionStepReason(reason) ? { reason } : {};
814
+ }
802
815
  function freezeStep(step) {
803
816
  return Object.freeze({
804
817
  kind: step.kind,
805
818
  scope: typeof step.scope === "string" ? step.scope : Object.freeze([...step.scope]),
819
+ ...reasonEntry(field(step, "reason")),
806
820
  command: Object.freeze([...step.command]),
807
821
  exitCode: step.exitCode,
808
822
  summary: step.summary,
@@ -818,7 +832,7 @@ function stepsEntry(steps) {
818
832
  }
819
833
  function freezeRecord(fields) {
820
834
  const task = field(fields, "task");
821
- const hop = field(fields, "hop");
835
+ const hop2 = field(fields, "hop");
822
836
  const worktree = field(fields, "worktree");
823
837
  return Object.freeze({
824
838
  sessionId: field(fields, "sessionId"),
@@ -830,7 +844,7 @@ function freezeRecord(fields) {
830
844
  state: field(fields, "state"),
831
845
  task: isObject(task) ? Object.freeze({ line: field(task, "line"), text: field(task, "text") }) : null,
832
846
  ...phaseEntry(field(fields, "phase")),
833
- ...hop === undefined ? {} : { hop: freezeHop(hop) },
847
+ ...hop2 === undefined ? {} : { hop: freezeHop(hop2) },
834
848
  ...worktree === undefined ? {} : { worktree },
835
849
  ...stepsEntry(field(fields, "steps"))
836
850
  });
@@ -881,7 +895,7 @@ class SessionStateError extends Error {
881
895
  }
882
896
  }
883
897
  function runsDir(root) {
884
- return join7(scopeAt2(root).dir, RUNS_DIR);
898
+ return join7(scopeAt(root).dir, RUNS_DIR);
885
899
  }
886
900
  function sessionFilePath(root, sessionId) {
887
901
  if (!isSessionId(sessionId)) {
@@ -931,7 +945,7 @@ function byStart(a, b) {
931
945
  function readSessions(root, seams = {}) {
932
946
  const dir = runsDir(root);
933
947
  const isAlive = seams.isAlive ?? isPidAlive;
934
- const records = recordNames(dir).filter((name) => name.endsWith(RECORD_EXTENSION)).map((name) => readRecordFile(join7(dir, name))).map((record) => Object.freeze({ ...record, state: readState(record, isAlive) }));
948
+ const records = recordNames(dir).filter((name2) => name2.endsWith(RECORD_EXTENSION)).map((name2) => readRecordFile(join7(dir, name2))).map((record) => Object.freeze({ ...record, state: readState(record, isAlive) }));
935
949
  return Object.freeze(records.sort(byStart));
936
950
  }
937
951
  function readSession(root, sessionId, seams = {}) {
@@ -1017,8 +1031,8 @@ function manifestName(file) {
1017
1031
  }
1018
1032
  if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed))
1019
1033
  return null;
1020
- const name = parsed["name"];
1021
- return typeof name === "string" ? name : null;
1034
+ const name2 = parsed["name"];
1035
+ return typeof name2 === "string" ? name2 : null;
1022
1036
  }
1023
1037
  function nearestRafaPackage(start) {
1024
1038
  let dir = start;
@@ -1063,7 +1077,7 @@ class DevelopmentBuildRefusedError extends Error {
1063
1077
  function storeProjectRoot(path) {
1064
1078
  const storeDir = dirname8(path);
1065
1079
  const scopeDir = dirname8(storeDir);
1066
- if (basename3(storeDir) !== EFFORT_DIR_NAME || basename3(scopeDir) !== SCOPE_DIR2)
1080
+ if (basename3(storeDir) !== EFFORT_DIR_NAME || basename3(scopeDir) !== SCOPE_DIR)
1067
1081
  return null;
1068
1082
  return dirname8(scopeDir);
1069
1083
  }
@@ -1470,6 +1484,13 @@ var SQLITE_MIGRATIONS = [
1470
1484
  sql: `
1471
1485
  ALTER TABLE store_meta ADD COLUMN generation TEXT CHECK (generation <> '');
1472
1486
  `
1487
+ },
1488
+ {
1489
+ id: "session-worktree",
1490
+ breaks: [],
1491
+ sql: `
1492
+ ALTER TABLE sessions ADD COLUMN worktree TEXT;
1493
+ `
1473
1494
  }
1474
1495
  ];
1475
1496
  var SQLITE_SCHEMA_VERSION = SQLITE_MIGRATIONS.length;
@@ -1683,7 +1704,7 @@ function stampedValues(table) {
1683
1704
 
1684
1705
  // src/effort/store/settings.ts
1685
1706
  var DEFAULT_STORE_SETTINGS = Object.freeze({
1686
- busyTimeoutMs: CONFIG_DEFAULTS2.effortBusyTimeoutMs
1707
+ busyTimeoutMs: CONFIG_DEFAULTS.effortBusyTimeoutMs
1687
1708
  });
1688
1709
  var active = DEFAULT_STORE_SETTINGS;
1689
1710
  function setActiveStoreSettings(settings) {
@@ -2008,8 +2029,12 @@ function sqliteStorePath(repoRoot) {
2008
2029
  return join9(effortStoreDir(repoRoot), SQLITE_STORE_FILE_NAME);
2009
2030
  }
2010
2031
  var KIND_TABLES = {
2011
- sessions: { name: "sessions", keyColumn: "session_id" },
2012
- commits: { name: "commits", keyColumn: "sha" }
2032
+ sessions: {
2033
+ name: "sessions",
2034
+ keyColumn: "session_id",
2035
+ fieldColumns: [{ column: "worktree", value: (row) => row.worktree ?? null }]
2036
+ },
2037
+ commits: { name: "commits", keyColumn: "sha", fieldColumns: [] }
2013
2038
  };
2014
2039
  var LONE_SURROGATE = /[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?<![\uD800-\uDBFF])[\uDC00-\uDFFF]/;
2015
2040
  function hasKey(entry) {
@@ -2019,7 +2044,8 @@ function refused(index, length, reason) {
2019
2044
  return new Error(`effort store: row ${index} of ${length} ${reason}; batch refused`);
2020
2045
  }
2021
2046
  function batchEntries(kind, rows) {
2022
- const keyOf = EFFORT_KEY_PROJECTIONS2[kind];
2047
+ const keyOf = EFFORT_KEY_PROJECTIONS[kind];
2048
+ const fieldColumns = KIND_TABLES[kind].fieldColumns;
2023
2049
  const projected = rows.map((row) => ({ key: keyOf(row), row }));
2024
2050
  const keyed = projected.filter(hasKey);
2025
2051
  if (keyed.length < projected.length) {
@@ -2031,7 +2057,11 @@ function batchEntries(kind, rows) {
2031
2057
  const reason = "carries a key with a lone UTF-16 surrogate," + " which SQLite text cannot hold";
2032
2058
  throw refused(unholdableAt, rows.length, reason);
2033
2059
  }
2034
- return keyed.map(({ key, row }) => ({ key, body: JSON.stringify(row) }));
2060
+ return keyed.map(({ key, row }) => ({
2061
+ key,
2062
+ body: JSON.stringify(row),
2063
+ fields: fieldColumns.map(({ value }) => value(row))
2064
+ }));
2035
2065
  }
2036
2066
  function withSqliteStore(path, access, create, use, identity = {}) {
2037
2067
  guardTestProcess(path);
@@ -2048,8 +2078,11 @@ function withSqliteStore(path, access, create, use, identity = {}) {
2048
2078
  }
2049
2079
  }
2050
2080
  function insertBatch(db, table, entries) {
2051
- const insert = db.query(`INSERT INTO ${table.name} (${table.keyColumn}, row_json, ${STAMPED_COLUMNS})` + ` VALUES (?, ?, ${stampedValues(table.name)})` + ` ON CONFLICT (${table.keyColumn}) DO NOTHING`);
2052
- const insertAll = db.transaction(() => entries.reduce((appended, { key, body }) => appended + insert.run(key, body).changes, 0));
2081
+ const fieldNames = table.fieldColumns.map(({ column }) => column);
2082
+ const columns = [table.keyColumn, "row_json", ...fieldNames].join(", ");
2083
+ const placeholders = ["?", "?", ...fieldNames.map(() => "?")].join(", ");
2084
+ const insert = db.query(`INSERT INTO ${table.name} (${columns}, ${STAMPED_COLUMNS})` + ` VALUES (${placeholders}, ${stampedValues(table.name)})` + ` ON CONFLICT (${table.keyColumn}) DO NOTHING`);
2085
+ const insertAll = db.transaction(() => entries.reduce((appended, { key, body, fields }) => appended + insert.run(key, body, ...fields).changes, 0));
2053
2086
  return insertAll.immediate();
2054
2087
  }
2055
2088
  function writeSqliteStore(path, rowCount, empty, insert) {
@@ -2071,8 +2104,8 @@ function appendKind2(path, kind, rows) {
2071
2104
  function keysOfKind2(path, kind) {
2072
2105
  if (!existsSync5(path))
2073
2106
  return new Set;
2074
- const { name, keyColumn } = KIND_TABLES[kind];
2075
- const keys = withSqliteStore(path, "read", false, (db) => db.query(`SELECT ${keyColumn} AS key FROM ${name} ORDER BY seq`).all());
2107
+ const { name: name2, keyColumn } = KIND_TABLES[kind];
2108
+ const keys = withSqliteStore(path, "read", false, (db) => db.query(`SELECT ${keyColumn} AS key FROM ${name2} ORDER BY seq`).all());
2076
2109
  return new Set(keys.map(({ key }) => key));
2077
2110
  }
2078
2111
  function parsedObject(body) {
@@ -2093,11 +2126,11 @@ function rowOf(body, where) {
2093
2126
  function readKind2(path, kind) {
2094
2127
  if (!existsSync5(path))
2095
2128
  return [];
2096
- const { name } = KIND_TABLES[kind];
2097
- const stored = withSqliteStore(path, "read", false, (db) => db.query(`SELECT seq, row_json AS body FROM ${name} ORDER BY seq`).all());
2098
- return stored.map(({ seq, body }) => rowOf(body, `${path}: ${name} row ${seq}`));
2129
+ const { name: name2 } = KIND_TABLES[kind];
2130
+ const stored = withSqliteStore(path, "read", false, (db) => db.query(`SELECT seq, row_json AS body FROM ${name2} ORDER BY seq`).all());
2131
+ return stored.map(({ seq, body }) => rowOf(body, `${path}: ${name2} row ${seq}`));
2099
2132
  }
2100
- function openSqliteStore2(repoRoot) {
2133
+ function openSqliteStore(repoRoot) {
2101
2134
  const path = sqliteStorePath(repoRoot);
2102
2135
  return {
2103
2136
  append: (kind, rows) => appendKind2(path, kind, rows),
@@ -2111,129 +2144,6 @@ function openSqliteStore2(repoRoot) {
2111
2144
  import { existsSync as existsSync12 } from "fs";
2112
2145
  import { join as join12, resolve as resolve5 } from "path";
2113
2146
 
2114
- // src/cli/spends.ts
2115
- var SPENDS_GLYPH = "\uD83E\uDE99";
2116
- var SPENDS_WHEN = ["always", "with", "unless", "through"];
2117
- var FLAGGED = ["with", "unless"];
2118
- var FLAG_SPELLING = /^--[^\s-]\S*$/;
2119
- function flagProblem(when, flag) {
2120
- if (FLAGGED.includes(when)) {
2121
- return typeof flag === "string" && FLAG_SPELLING.test(flag) ? null : `spends.flag is ${describeValue(flag)}, expected a flag as typed, starting with --`;
2122
- }
2123
- return flag === undefined ? null : `spends.flag is ${describeValue(flag)}, expected absent when spends.when is "${when}"`;
2124
- }
2125
- function spendsProblem(value) {
2126
- if (value === undefined)
2127
- return null;
2128
- if (typeof value !== "object" || value === null || Array.isArray(value)) {
2129
- return `spends is ${describeValue(value)}, expected absent or a mapping`;
2130
- }
2131
- const { when, what, flag } = value;
2132
- if (!SPENDS_WHEN.includes(when)) {
2133
- return `spends.when is ${describeValue(when)}, expected one of ${SPENDS_WHEN.join(", ")}`;
2134
- }
2135
- if (typeof what !== "string") {
2136
- return `spends.what is ${describeValue(what)}, expected a string`;
2137
- }
2138
- return flagProblem(when, flag);
2139
- }
2140
-
2141
- // src/cli/command.ts
2142
- var COMMAND_OUTPUTS = ["text", "json", "events", "tui"];
2143
- var MAX_EXIT_CODE = 255;
2144
-
2145
- class CommandExit extends Error {
2146
- exitCode;
2147
- constructor(exitCode, message = "") {
2148
- super(message);
2149
- if (!Number.isInteger(exitCode) || exitCode < 0 || exitCode > MAX_EXIT_CODE) {
2150
- throw new TypeError(`CommandExit: exit code is ${describeValue(exitCode)}, expected a whole number from 0 to ${MAX_EXIT_CODE}`);
2151
- }
2152
- this.name = "CommandExit";
2153
- this.exitCode = exitCode;
2154
- }
2155
- }
2156
- function isListOf(value, check) {
2157
- return Array.isArray(value) && value.every(check);
2158
- }
2159
- function hasStrings(value, keys) {
2160
- if (typeof value !== "object" || value === null)
2161
- return false;
2162
- const record = value;
2163
- return keys.every((key) => typeof record[key] === "string");
2164
- }
2165
- function isRoutingWord(value) {
2166
- return typeof value === "string" && /^[^\s/-][^\s/]*$/.test(value);
2167
- }
2168
- function isFlag(item) {
2169
- if (!hasStrings(item, ["name"]))
2170
- return false;
2171
- const { deprecated } = item;
2172
- return deprecated === undefined || hasStrings(deprecated, ["use"]);
2173
- }
2174
- function fieldProblem(fields) {
2175
- const checks = [
2176
- ["subject", isRoutingWord(fields.subject), "a word with no space, no slash and no leading dash"],
2177
- ["action", isRoutingWord(fields.action), "a word with no space, no slash and no leading dash"],
2178
- ["name", typeof fields.name === "string", "a string"],
2179
- ["summary", typeof fields.summary === "string", "a string"],
2180
- ["description", typeof fields.description === "string", "a string"],
2181
- ["args", isListOf(fields.args, (item) => hasStrings(item, ["name"])), "a list of named arguments"],
2182
- ["flags", isListOf(fields.flags, isFlag), "a list of named flags, each deprecation naming its use"],
2183
- ["examples", isListOf(fields.examples, (item) => hasStrings(item, ["cmd", "note"])), "a list of examples"],
2184
- [
2185
- "outputs",
2186
- isListOf(fields.outputs, (item) => COMMAND_OUTPUTS.includes(item)),
2187
- `a list of ${COMMAND_OUTPUTS.join(", ")}`
2188
- ],
2189
- [
2190
- "aliases",
2191
- fields.aliases === undefined || isListOf(fields.aliases, (item) => typeof item === "string"),
2192
- "absent or a list of strings"
2193
- ],
2194
- [
2195
- "lastingAliases",
2196
- fields.lastingAliases === undefined || isListOf(fields.lastingAliases, (item) => typeof item === "string"),
2197
- "absent or a list of strings"
2198
- ],
2199
- [
2200
- "deprecated",
2201
- fields.deprecated === undefined || hasStrings(fields.deprecated, ["since", "use"]),
2202
- "absent or a mapping of since and use"
2203
- ],
2204
- ["hidden", fields.hidden === undefined || typeof fields.hidden === "boolean", "absent or a boolean"],
2205
- [
2206
- "needsProject",
2207
- fields.needsProject === undefined || typeof fields.needsProject === "boolean",
2208
- "absent or a boolean"
2209
- ],
2210
- ["exec", fields.exec === undefined || fields.exec === true, "absent or true"],
2211
- ["run", typeof fields.run === "function", "a function"]
2212
- ];
2213
- const failed = checks.find(([, passes]) => !passes);
2214
- if (failed === undefined)
2215
- return null;
2216
- const [key, , expected] = failed;
2217
- return `${key} is ${describeValue(fields[key])}, expected ${expected}`;
2218
- }
2219
- function commandProblem(value) {
2220
- if (typeof value !== "object" || value === null || Array.isArray(value)) {
2221
- return `a command is ${describeValue(value)}, expected a mapping`;
2222
- }
2223
- const fields = value;
2224
- const problem = fieldProblem(fields) ?? spendsProblem(fields.spends);
2225
- if (problem === null)
2226
- return null;
2227
- const named = isRoutingWord(fields.subject) && isRoutingWord(fields.action) ? `command "${commandSpelling(fields)}"` : "a command";
2228
- return `${named}: ${problem}`;
2229
- }
2230
- function isTopLevel(command) {
2231
- return command.subject === command.action;
2232
- }
2233
- function commandSpelling(command) {
2234
- return isTopLevel(command) ? command.subject : `${command.subject} ${command.action}`;
2235
- }
2236
-
2237
2147
  // src/effort/store/fix-schema.ts
2238
2148
  import { existsSync as existsSync8 } from "fs";
2239
2149
  import { Database as Database4 } from "bun:sqlite";
@@ -2285,18 +2195,18 @@ function vacuumInto(source, target) {
2285
2195
  db.close();
2286
2196
  }
2287
2197
  }
2288
- function copyOne(name, source, target) {
2289
- if (name === SQLITE_STORE_FILE_NAME) {
2290
- vacuumInto(join10(source, name), join10(target, name));
2198
+ function copyOne(name2, source, target) {
2199
+ if (name2 === SQLITE_STORE_FILE_NAME) {
2200
+ vacuumInto(join10(source, name2), join10(target, name2));
2291
2201
  return;
2292
2202
  }
2293
- copyFileSync(join10(source, name), join10(target, name), constants.COPYFILE_EXCL);
2203
+ copyFileSync(join10(source, name2), join10(target, name2), constants.COPYFILE_EXCL);
2294
2204
  }
2295
2205
  function undo(target, written, madeDir) {
2296
2206
  try {
2297
2207
  if (madeDir === undefined) {
2298
- for (const name of written)
2299
- rmSync5(join10(target, name), { force: true });
2208
+ for (const name2 of written)
2209
+ rmSync5(join10(target, name2), { force: true });
2300
2210
  } else {
2301
2211
  rmSync5(madeDir, { recursive: true, force: true });
2302
2212
  }
@@ -2310,7 +2220,7 @@ function copyEffortStore(request) {
2310
2220
  const target = resolve3(request.target);
2311
2221
  guardTestProcess(source);
2312
2222
  guardTestProcess(target);
2313
- const files = EFFORT_COPY_FILE_NAMES.filter((name) => existsSync6(join10(source, name)));
2223
+ const files = EFFORT_COPY_FILE_NAMES.filter((name2) => existsSync6(join10(source, name2)));
2314
2224
  if (files.length === 0) {
2315
2225
  throw new EffortCopyRefusal(`no effort store at ${source}: it holds none of ${EFFORT_COPY_FILE_NAMES.join(", ")}. Nothing to copy.`);
2316
2226
  }
@@ -2319,9 +2229,9 @@ function copyEffortStore(request) {
2319
2229
  let madeDir;
2320
2230
  try {
2321
2231
  madeDir = mkdirSync6(target, { recursive: true });
2322
- for (const name of files) {
2323
- written.push(name);
2324
- copyOne(name, source, target);
2232
+ for (const name2 of files) {
2233
+ written.push(name2);
2234
+ copyOne(name2, source, target);
2325
2235
  }
2326
2236
  } catch (error) {
2327
2237
  const left = undo(target, written, madeDir);
@@ -2337,8 +2247,8 @@ class RebuildRefusal extends Error {
2337
2247
  this.name = "RebuildRefusal";
2338
2248
  }
2339
2249
  }
2340
- function quoted(name) {
2341
- return `"${name.replaceAll('"', '""')}"`;
2250
+ function quoted(name2) {
2251
+ return `"${name2.replaceAll('"', '""')}"`;
2342
2252
  }
2343
2253
  function count(db, sql) {
2344
2254
  return db.query(sql).get()?.n ?? 0;
@@ -2544,8 +2454,8 @@ function buildParallel(path, parallelPath, migrations, stamp) {
2544
2454
  db.close();
2545
2455
  }
2546
2456
  }
2547
- function asidePaths(path, version, stamp) {
2548
- return { parallelPath: `${path}.fix-${stamp}`, backupPath: `${path}.v${String(version)}-${stamp}.bak` };
2457
+ function asidePaths(path, version2, stamp) {
2458
+ return { parallelPath: `${path}.fix-${stamp}`, backupPath: `${path}.v${String(version2)}-${stamp}.bak` };
2549
2459
  }
2550
2460
  function isRepairable(reason) {
2551
2461
  return REPAIRABLE_REASONS.includes(reason);
@@ -2578,8 +2488,8 @@ function fixStoreSchema(options) {
2578
2488
  const plan = planSchema(store, sqliteCatalogue(migrations), "write", "open");
2579
2489
  if (plan.verdict === "use") {
2580
2490
  const pending = writeNames(plan);
2581
- const status = pending.length === 0 ? "current" : "behind";
2582
- return { ...found, ...nothing, status, reason: null, refusal: null, pending };
2491
+ const status2 = pending.length === 0 ? "current" : "behind";
2492
+ return { ...found, ...nothing, status: status2, reason: null, refusal: null, pending };
2583
2493
  }
2584
2494
  if (!isRepairable(plan.reason)) {
2585
2495
  throw new RebuildRefusal(`a rebuild at this rafa's migrations does not repair ${plan.reason}. ${plan.message}`);
@@ -2611,8 +2521,8 @@ import { resolve as resolve4 } from "path";
2611
2521
  // src/config-load.ts
2612
2522
  import { existsSync as existsSync9, readFileSync as readFileSync8, realpathSync as realpathSync5 } from "fs";
2613
2523
  import { isAbsolute as isAbsolute6 } from "path";
2614
- function readConfigFile2(root) {
2615
- const path = configFilePath2(root);
2524
+ function readConfigFile(root) {
2525
+ const path = configFilePath(root);
2616
2526
  if (!existsSync9(path))
2617
2527
  return null;
2618
2528
  let text;
@@ -2620,9 +2530,9 @@ function readConfigFile2(root) {
2620
2530
  text = readFileSync8(path, "utf8");
2621
2531
  } catch (error) {
2622
2532
  const problem = `${path}: cannot be read (${messageOf(error)})`;
2623
- throw new ConfigError2([problem], { cause: error });
2533
+ throw new ConfigError([problem], { cause: error });
2624
2534
  }
2625
- return parseConfigText2(text, path);
2535
+ return parseConfigText(text, path);
2626
2536
  }
2627
2537
  function isSameDirectory(first, second) {
2628
2538
  try {
@@ -2633,19 +2543,19 @@ function isSameDirectory(first, second) {
2633
2543
  }
2634
2544
  function readUserConfigFile({ root, home }) {
2635
2545
  if (!isAbsolute6(home)) {
2636
- throw new ConfigError2([
2546
+ throw new ConfigError([
2637
2547
  `home directory is ${describeValue(home)}, expected an absolute path`
2638
2548
  ]);
2639
2549
  }
2640
- return isSameDirectory(root, home) ? null : readConfigFile2(home);
2550
+ return isSameDirectory(root, home) ? null : readConfigFile(home);
2641
2551
  }
2642
2552
  function printWarning(message) {
2643
2553
  activeOutput().warn(message);
2644
2554
  }
2645
- function loadConfig2(roots, cli = {}, warn = printWarning) {
2555
+ function loadConfig(roots, cli = {}, warn = printWarning) {
2646
2556
  const user = readUserConfigFile(roots);
2647
- const file = readConfigFile2(roots.root);
2648
- const resolved = resolveConfig2({ cli, file, user });
2557
+ const file = readConfigFile(roots.root);
2558
+ const resolved = resolveConfig({ cli, file, user });
2649
2559
  for (const warning of resolved.warnings)
2650
2560
  warn(warning);
2651
2561
  setActiveStoreSettings({ busyTimeoutMs: resolved.config.effortBusyTimeoutMs });
@@ -2666,9 +2576,9 @@ function resolvePlansDir(project, command, warn) {
2666
2576
  }
2667
2577
  function resolveProjectConfig(project, command, warn) {
2668
2578
  try {
2669
- return loadConfig2({ root: project.root, home: project.home }, {}, warn).config;
2579
+ return loadConfig({ root: project.root, home: project.home }, {}, warn).config;
2670
2580
  } catch (error) {
2671
- if (!(error instanceof ConfigError2))
2581
+ if (!(error instanceof ConfigError))
2672
2582
  throw error;
2673
2583
  throw new CommandExit(1, [
2674
2584
  `\u274C ${command}: the config cannot be used:`,
@@ -2696,8 +2606,8 @@ function checkbox(status) {
2696
2606
  function planFileName(stub, tracker) {
2697
2607
  return tracker ? `PLAN_TRACKER-${stub}.md` : `PLAN-${stub}.md`;
2698
2608
  }
2699
- function stubOfPlanFile(name) {
2700
- const stub = /^PLAN-(.+)\.md$/.exec(name)?.[1];
2609
+ function stubOfPlanFile(name2) {
2610
+ const stub = /^PLAN-(.+)\.md$/.exec(name2)?.[1];
2701
2611
  return stub !== undefined && isStampableStub(stub) ? stub : null;
2702
2612
  }
2703
2613
  function isFile(path) {
@@ -2706,8 +2616,8 @@ function isFile(path) {
2706
2616
  function issueLine(file, issue) {
2707
2617
  return `${file}:${issue.line}: ${issue.reason}: ${issue.text}`;
2708
2618
  }
2709
- function plural(count, noun) {
2710
- return count === 1 ? `${count} ${noun}` : `${count} ${noun}s`;
2619
+ function plural(count2, noun) {
2620
+ return count2 === 1 ? `${count2} ${noun}` : `${count2} ${noun}s`;
2711
2621
  }
2712
2622
  function expectNoArgument(args, usage) {
2713
2623
  if (args.length === 0)
@@ -2732,12 +2642,12 @@ function expectAtMostOneArgument(args, usage) {
2732
2642
  throw new CommandExit(1, `\u274C Expected at most one argument, got ${args.length}: ${args.join(" ")}
2733
2643
  Usage: ${usage}`);
2734
2644
  }
2735
- function readSwitch(name, value, hint) {
2645
+ function readSwitch(name2, value, hint) {
2736
2646
  if (value === undefined || value === false || value === "false")
2737
2647
  return false;
2738
2648
  if (value === true || value === "true")
2739
2649
  return true;
2740
- throw new CommandExit(1, `\u274C --${name} takes no value, and read "${value}" as one. ${hint}`);
2650
+ throw new CommandExit(1, `\u274C --${name2} takes no value, and read "${value}" as one. ${hint}`);
2741
2651
  }
2742
2652
 
2743
2653
  // src/commands/effort/fix-schema.ts
@@ -2899,8 +2809,8 @@ function normaliseBranch(source) {
2899
2809
  return null;
2900
2810
  return source.startsWith("refs/heads/") ? source.slice("refs/heads/".length) : source;
2901
2811
  }
2902
- function parseStatCount(field) {
2903
- return /^\d+$/.test(field) ? Number(field) : null;
2812
+ function parseStatCount(field2) {
2813
+ return /^\d+$/.test(field2) ? Number(field2) : null;
2904
2814
  }
2905
2815
  function parseCommitHeader(line) {
2906
2816
  const parts = line.split(FIELD_SEPARATOR);
@@ -3128,7 +3038,7 @@ function mergedTables() {
3128
3038
  return Object.entries(MERGE_RULES).flatMap(([table, rule]) => rule.scope === "merged" ? [{ table, identity: rule.identity }] : []);
3129
3039
  }
3130
3040
  function carriedColumns(db, table) {
3131
- return db.query(`PRAGMA table_info(${quoted(table)})`).all().map(({ name }) => name).filter((name) => name !== "seq");
3041
+ return db.query(`PRAGMA table_info(${quoted(table)})`).all().map(({ name: name2 }) => name2).filter((name2) => name2 !== "seq");
3132
3042
  }
3133
3043
  function refuseColumnMismatch(local, other, tables) {
3134
3044
  const faults = tables.flatMap(({ table }) => {
@@ -3219,29 +3129,29 @@ function sameValue(left, right) {
3219
3129
  return Buffer.from(left).equals(right);
3220
3130
  return (left ?? null) === (right ?? null);
3221
3131
  }
3222
- function fillStatement(table, field) {
3223
- const statement = SET_ONCE_FILLS[`${table}.${field}`];
3132
+ function fillStatement(table, field2) {
3133
+ const statement = SET_ONCE_FILLS[`${table}.${field2}`];
3224
3134
  if (statement === undefined) {
3225
- throw new Error(`${table}.${field} is set-once in MERGE_RULES and has no statement in SET_ONCE_FILLS`);
3135
+ throw new Error(`${table}.${field2} is set-once in MERGE_RULES and has no statement in SET_ONCE_FILLS`);
3226
3136
  }
3227
3137
  return statement;
3228
3138
  }
3229
- function settleSetOnce(local, table, field, here, there) {
3230
- const incoming = there[field] ?? null;
3139
+ function settleSetOnce(local, table, field2, here, there) {
3140
+ const incoming = there[field2] ?? null;
3231
3141
  if (incoming === null)
3232
3142
  return { skipped: true, filled: [], conflictFields: [] };
3233
- if ((here[field] ?? null) !== null)
3234
- return { skipped: false, filled: [], conflictFields: [field] };
3235
- local.query(fillStatement(table, field)).run(incoming, Number(here.seq));
3236
- return { skipped: true, filled: [field], conflictFields: [] };
3143
+ if ((here[field2] ?? null) !== null)
3144
+ return { skipped: false, filled: [], conflictFields: [field2] };
3145
+ local.query(fillStatement(table, field2)).run(incoming, Number(here.seq));
3146
+ return { skipped: true, filled: [field2], conflictFields: [] };
3237
3147
  }
3238
- function settleRecomputed(table, field, here, there) {
3239
- const comparable = RECOMPUTED_COMPARISONS[`${table}.${field}`];
3148
+ function settleRecomputed(table, field2, here, there) {
3149
+ const comparable = RECOMPUTED_COMPARISONS[`${table}.${field2}`];
3240
3150
  if (comparable === undefined) {
3241
- throw new Error(`${table}.${field} is recomputed in MERGE_RULES and has no entry in RECOMPUTED_COMPARISONS`);
3151
+ throw new Error(`${table}.${field2} is recomputed in MERGE_RULES and has no entry in RECOMPUTED_COMPARISONS`);
3242
3152
  }
3243
- const hereValue = here[field];
3244
- const thereValue = there[field];
3153
+ const hereValue = here[field2];
3154
+ const thereValue = there[field2];
3245
3155
  const same = typeof hereValue === "string" && typeof thereValue === "string" && comparable(hereValue) === comparable(thereValue);
3246
3156
  return same ? { skipped: true, filled: [], conflictFields: [] } : { skipped: false, filled: [], conflictFields: [null] };
3247
3157
  }
@@ -3251,12 +3161,12 @@ function settlePair(local, table, edited, here, there) {
3251
3161
  return { skipped: true, filled: [], conflictFields: [] };
3252
3162
  if (differing.some((column) => !Object.hasOwn(edited, column)))
3253
3163
  return { skipped: false, filled: [], conflictFields: [null] };
3254
- const outcomes = differing.map((field) => {
3255
- if (edited[field] === SET_ONCE)
3256
- return settleSetOnce(local, table, field, here, there);
3257
- if (edited[field] === RECOMPUTED)
3258
- return settleRecomputed(table, field, here, there);
3259
- throw new Error(`${table}.${field} has the rule ${edited[field]}, which the merge does not apply`);
3164
+ const outcomes = differing.map((field2) => {
3165
+ if (edited[field2] === SET_ONCE)
3166
+ return settleSetOnce(local, table, field2, here, there);
3167
+ if (edited[field2] === RECOMPUTED)
3168
+ return settleRecomputed(table, field2, here, there);
3169
+ throw new Error(`${table}.${field2} has the rule ${edited[field2]}, which the merge does not apply`);
3260
3170
  });
3261
3171
  return {
3262
3172
  skipped: outcomes.every((outcome) => outcome.skipped),
@@ -3273,16 +3183,16 @@ function settleTable(local, other, union, trail) {
3273
3183
  const here = rowAt(local, union.table, columns, match.localSeq, "here");
3274
3184
  const there = rowAt(other, union.table, columns, match.incomingSeq, "in the other store");
3275
3185
  const outcome = settlePair(local, union.table, rule.edited, here, there);
3276
- const conflicts = outcome.conflictFields.map((field) => {
3277
- local.query(INSERT_CONFLICT).run(trail.mergeId, union.table, match.localSeq, field, JSON.stringify(there), trail.recordedAt);
3278
- return { localSeq: match.localSeq, incomingSeq: match.incomingSeq, field };
3186
+ const conflicts = outcome.conflictFields.map((field2) => {
3187
+ local.query(INSERT_CONFLICT).run(trail.mergeId, union.table, match.localSeq, field2, JSON.stringify(there), trail.recordedAt);
3188
+ return { localSeq: match.localSeq, incomingSeq: match.incomingSeq, field: field2 };
3279
3189
  });
3280
3190
  return { match, outcome, conflicts };
3281
3191
  });
3282
3192
  return {
3283
3193
  table: union.table,
3284
3194
  skipped: settled.flatMap(({ match, outcome }) => outcome.skipped ? [match.localSeq] : []),
3285
- filled: settled.flatMap(({ match, outcome }) => outcome.filled.map((field) => ({ localSeq: match.localSeq, field }))),
3195
+ filled: settled.flatMap(({ match, outcome }) => outcome.filled.map((field2) => ({ localSeq: match.localSeq, field: field2 }))),
3286
3196
  conflicts: settled.flatMap(({ conflicts }) => conflicts)
3287
3197
  };
3288
3198
  }
@@ -3492,7 +3402,7 @@ function mergeInto(db, other, mergeId, otherStore, mergedAt) {
3492
3402
  collided: union.collided.length
3493
3403
  };
3494
3404
  });
3495
- const sum = (field) => tables.reduce((total, entry) => total + entry[field], 0);
3405
+ const sum = (field2) => tables.reduce((total, entry) => total + entry[field2], 0);
3496
3406
  const totals = { rowsAdded: sum("added"), rowsSkipped: sum("skipped"), rowsInConflict: sum("inConflict") };
3497
3407
  db.query(INSERT_MERGE).run(mergeId, otherStore, mergedAt, totals.rowsAdded, totals.rowsSkipped, totals.rowsInConflict);
3498
3408
  return { tables, ...totals, gapsRewritten: gaps.length };
@@ -3505,18 +3415,18 @@ function addedRows(merged) {
3505
3415
  merge_conflicts: merged.rowsInConflict
3506
3416
  };
3507
3417
  }
3508
- function buildMerged(path, parallelPath, other, merge) {
3418
+ function buildMerged(path, parallelPath, other, merge2) {
3509
3419
  vacuumInto(path, parallelPath);
3510
3420
  const db = new Database6(parallelPath, { readwrite: true });
3511
3421
  try {
3512
- bringForward(db, parallelPath, "write", "open", { ...merge.stamp, builtAside: true });
3513
- const merged = mergeInto(db, other, merge.id, merge.otherStore, merge.stamp.now().toISOString());
3422
+ bringForward(db, parallelPath, "write", "open", { ...merge2.stamp, builtAside: true });
3423
+ const merged = mergeInto(db, other, merge2.id, merge2.otherStore, merge2.stamp.now().toISOString());
3514
3424
  db.run(`ATTACH DATABASE ? AS ${LIVE3}`, [path]);
3515
3425
  const live = new Set(tableNames(db, LIVE3));
3516
3426
  checkedCounts(db, tableNames(db, "main").filter((table) => live.has(table)), LIVE3, addedRows(merged));
3517
3427
  db.run(`DETACH DATABASE ${LIVE3}`);
3518
3428
  refuseCorrupt(db);
3519
- refuseUnusable(db, parallelPath, merge.stamp.migrations);
3429
+ refuseUnusable(db, parallelPath, merge2.stamp.migrations);
3520
3430
  return merged;
3521
3431
  } finally {
3522
3432
  db.close();
@@ -3539,7 +3449,7 @@ function refuseUnmergeable(options, migrations) {
3539
3449
  }
3540
3450
  return { otherPlan, otherStore };
3541
3451
  }
3542
- function mergeStore2(options) {
3452
+ function mergeStore(options) {
3543
3453
  const { path, otherPath, dryRun, stamp } = options;
3544
3454
  guardTestProcess(path);
3545
3455
  guardTestProcess(otherPath);
@@ -3574,10 +3484,10 @@ var NOTHING_COPIED = "Nothing was copied.";
3574
3484
  class FileSyncRefusal extends Error {
3575
3485
  name = "FileSyncRefusal";
3576
3486
  }
3577
- function requirePath(field, value) {
3487
+ function requirePath(field2, value) {
3578
3488
  if (typeof value === "string" && value !== "")
3579
3489
  return value;
3580
- throw new TypeError(`${REFUSAL}: ${field} is ${describeValue(value)}, expected a path`);
3490
+ throw new TypeError(`${REFUSAL}: ${field2} is ${describeValue(value)}, expected a path`);
3581
3491
  }
3582
3492
  function refuseUncarriable(backend, source) {
3583
3493
  if (backend === "ndjson") {
@@ -3607,8 +3517,8 @@ function createFileSync(options) {
3607
3517
  const otherPath = resolve5(repoRoot, requirePath("from", from));
3608
3518
  const path = join12(storeDir(), SQLITE_STORE_FILE_NAME);
3609
3519
  const stamp = fileStamp(now());
3610
- const merge = mergeStore2({ ...mergeSeams(options), path, otherPath, backend, dryRun, stamp, now, sessionId });
3611
- return Object.freeze({ status: "pulled", merge });
3520
+ const merge2 = mergeStore({ ...mergeSeams(options), path, otherPath, backend, dryRun, stamp, now, sessionId });
3521
+ return Object.freeze({ status: "pulled", merge: merge2 });
3612
3522
  };
3613
3523
  return Object.freeze({ kind: "file", push, pull });
3614
3524
  }
@@ -3659,7 +3569,7 @@ function contextOf(repoRoot, config) {
3659
3569
  ...hub === undefined ? {} : { hub }
3660
3570
  };
3661
3571
  }
3662
- function selectSync(repoRoot, config, registry = CORE_ADAPTER_REGISTRY2) {
3572
+ function selectSync(repoRoot, config, registry = CORE_ADAPTER_REGISTRY) {
3663
3573
  const kind = config.effortSync;
3664
3574
  const adapter = typeof kind === "string" ? registry.find("sync", kind) : undefined;
3665
3575
  if (adapter !== undefined)
@@ -3667,8 +3577,8 @@ function selectSync(repoRoot, config, registry = CORE_ADAPTER_REGISTRY2) {
3667
3577
  const registered = registry.kinds("sync");
3668
3578
  if (isModuleStrategy(kind))
3669
3579
  throw new SyncModuleMissing(kind, registered);
3670
- const known = SYNC_STRATEGIES2.includes(kind);
3671
- const expected = known ? `registered: ${listed(registered)}` : `expected one of: ${SYNC_STRATEGIES2.join(", ")}`;
3580
+ const known = SYNC_STRATEGIES.includes(kind);
3581
+ const expected = known ? `registered: ${listed(registered)}` : `expected one of: ${SYNC_STRATEGIES.join(", ")}`;
3672
3582
  throw new TypeError(`${REFUSAL2}: effort.sync is ${describeValue(kind)}, and no sync adapter is registered under it; ${expected}`);
3673
3583
  }
3674
3584
 
@@ -3683,7 +3593,7 @@ import { join as join14 } from "path";
3683
3593
  // src/check/layout.ts
3684
3594
  import { readdirSync as readdirSync3, statSync as statSync4 } from "fs";
3685
3595
  import { join as join13, relative as relative2 } from "path";
3686
- var SKILL_FILE2 = "SKILL.md";
3596
+ var SKILL_FILE = "SKILL.md";
3687
3597
  var MARKDOWN_EXTENSION = ".md";
3688
3598
  var LAYOUT_SEVERITY = Object.freeze({
3689
3599
  "flat-grouped-layout": "failure",
@@ -3711,13 +3621,13 @@ function entryKind(path) {
3711
3621
  }
3712
3622
  }
3713
3623
  function visibleNames(dir) {
3714
- return readdirSync3(dir).filter((name) => !name.startsWith(".")).sort((left, right) => left.localeCompare(right));
3624
+ return readdirSync3(dir).filter((name2) => !name2.startsWith(".")).sort((left, right) => left.localeCompare(right));
3715
3625
  }
3716
- function isMarkdown(name) {
3717
- return name.endsWith(MARKDOWN_EXTENSION);
3626
+ function isMarkdown(name2) {
3627
+ return name2.endsWith(MARKDOWN_EXTENSION);
3718
3628
  }
3719
- function markdownStem(name) {
3720
- return name.slice(0, -MARKDOWN_EXTENSION.length);
3629
+ function markdownStem(name2) {
3630
+ return name2.slice(0, -MARKDOWN_EXTENSION.length);
3721
3631
  }
3722
3632
  function shown(root, path) {
3723
3633
  return relative2(root, path) || ".";
@@ -3742,37 +3652,37 @@ function unreadableEntry(kind, root, path) {
3742
3652
  issues: [layoutIssue("unreadable-entry", `${shown(root, path)} cannot be read (a broken symlink, or a path stat refuses)`)]
3743
3653
  };
3744
3654
  }
3745
- function skillFileEntry(path, name) {
3746
- return { kind: "skill", path, isFile: true, shape: "skill-file", name, issues: [] };
3655
+ function skillFileEntry(path, name2) {
3656
+ return { kind: "skill", path, isFile: true, shape: "skill-file", name: name2, issues: [] };
3747
3657
  }
3748
- function flatGroupedEntry(root, path, name) {
3658
+ function flatGroupedEntry(root, path, name2) {
3749
3659
  return {
3750
3660
  kind: "skill",
3751
3661
  path,
3752
3662
  isFile: true,
3753
3663
  shape: "flat-grouped",
3754
- name,
3755
- issues: [layoutIssue("flat-grouped-layout", `${shown(root, path)} is the flat grouped layout <dir>/<group>/<name>.md,` + ` which does not register; move it to <dir>/${name}/${SKILL_FILE2}`)]
3664
+ name: name2,
3665
+ issues: [layoutIssue("flat-grouped-layout", `${shown(root, path)} is the flat grouped layout <dir>/<group>/<name>.md,` + ` which does not register; move it to <dir>/${name2}/${SKILL_FILE}`)]
3756
3666
  };
3757
3667
  }
3758
- function nestedGroupEntry(root, path, name) {
3668
+ function nestedGroupEntry(root, path, name2) {
3759
3669
  return {
3760
3670
  kind: "skill",
3761
3671
  path,
3762
3672
  isFile: true,
3763
3673
  shape: "nested-group",
3764
- name,
3765
- issues: [layoutIssue("nested-group-layout", `${shown(root, path)} is the nested layout <dir>/<group>/<name>/${SKILL_FILE2},` + ` which does not register; move it to <dir>/${name}/${SKILL_FILE2}`)]
3674
+ name: name2,
3675
+ issues: [layoutIssue("nested-group-layout", `${shown(root, path)} is the nested layout <dir>/<group>/<name>/${SKILL_FILE},` + ` which does not register; move it to <dir>/${name2}/${SKILL_FILE}`)]
3766
3676
  };
3767
3677
  }
3768
- function looseFileEntry(root, path, name) {
3678
+ function looseFileEntry(root, path, name2) {
3769
3679
  return {
3770
3680
  kind: "skill",
3771
3681
  path,
3772
3682
  isFile: true,
3773
3683
  shape: "loose-file",
3774
- name,
3775
- issues: [layoutIssue("loose-file", `${shown(root, path)} sits directly under the skills directory, which registers` + ` only <dir>/<name>/${SKILL_FILE2}; move it to <dir>/${name}/${SKILL_FILE2}`)]
3684
+ name: name2,
3685
+ issues: [layoutIssue("loose-file", `${shown(root, path)} sits directly under the skills directory, which registers` + ` only <dir>/<name>/${SKILL_FILE}; move it to <dir>/${name2}/${SKILL_FILE}`)]
3776
3686
  };
3777
3687
  }
3778
3688
  function noSkillFileEntry(root, dir) {
@@ -3782,26 +3692,26 @@ function noSkillFileEntry(root, dir) {
3782
3692
  isFile: false,
3783
3693
  shape: "no-skill-file",
3784
3694
  name: null,
3785
- issues: [layoutIssue("missing-skill-file", `${shown(root, dir)}/ holds no ${SKILL_FILE2}, so it registers no skill`)]
3695
+ issues: [layoutIssue("missing-skill-file", `${shown(root, dir)}/ holds no ${SKILL_FILE}, so it registers no skill`)]
3786
3696
  };
3787
3697
  }
3788
- function nestedInstinctEntry(root, path, name) {
3698
+ function nestedInstinctEntry(root, path, name2) {
3789
3699
  return {
3790
3700
  kind: "instinct",
3791
3701
  path,
3792
3702
  isFile: true,
3793
3703
  shape: "nested-instinct",
3794
- name,
3795
- issues: [layoutIssue("nested-instinct-file", `${shown(root, path)} sits below the instincts directory, which is flat;` + ` move it to <dir>/${name}${MARKDOWN_EXTENSION}`)]
3704
+ name: name2,
3705
+ issues: [layoutIssue("nested-instinct-file", `${shown(root, path)} sits below the instincts directory, which is flat;` + ` move it to <dir>/${name2}${MARKDOWN_EXTENSION}`)]
3796
3706
  };
3797
3707
  }
3798
- function scanGroupMember(root, dir, name) {
3708
+ function scanGroupMember(root, dir, name2) {
3799
3709
  const children = visibleNames(dir);
3800
3710
  if (children.length === 0)
3801
3711
  return [dotfileOnlyEntry("skill", root, dir)];
3802
- const skillPath = join13(dir, SKILL_FILE2);
3803
- if (children.includes(SKILL_FILE2) && entryKind(skillPath) === "file") {
3804
- return [nestedGroupEntry(root, skillPath, name)];
3712
+ const skillPath = join13(dir, SKILL_FILE);
3713
+ if (children.includes(SKILL_FILE) && entryKind(skillPath) === "file") {
3714
+ return [nestedGroupEntry(root, skillPath, name2)];
3805
3715
  }
3806
3716
  return [noSkillFileEntry(root, dir)];
3807
3717
  }
@@ -3825,31 +3735,31 @@ function scanSkillGroup(root, dir, children) {
3825
3735
  return [noSkillFileEntry(root, dir)];
3826
3736
  return entries;
3827
3737
  }
3828
- function scanSkillDirectory(root, dir, name) {
3738
+ function scanSkillDirectory(root, dir, name2) {
3829
3739
  const children = visibleNames(dir);
3830
3740
  if (children.length === 0)
3831
3741
  return [dotfileOnlyEntry("skill", root, dir)];
3832
- const skillPath = join13(dir, SKILL_FILE2);
3833
- if (children.includes(SKILL_FILE2) && entryKind(skillPath) === "file") {
3834
- return [skillFileEntry(skillPath, name)];
3742
+ const skillPath = join13(dir, SKILL_FILE);
3743
+ if (children.includes(SKILL_FILE) && entryKind(skillPath) === "file") {
3744
+ return [skillFileEntry(skillPath, name2)];
3835
3745
  }
3836
3746
  return scanSkillGroup(root, dir, children);
3837
3747
  }
3838
3748
  function scanSkillRoot(root) {
3839
3749
  const entries = [];
3840
- for (const name of visibleNames(root)) {
3841
- const path = join13(root, name);
3750
+ for (const name2 of visibleNames(root)) {
3751
+ const path = join13(root, name2);
3842
3752
  const found = entryKind(path);
3843
3753
  if (found === null) {
3844
3754
  entries.push(unreadableEntry("skill", root, path));
3845
3755
  continue;
3846
3756
  }
3847
3757
  if (found === "directory") {
3848
- entries.push(...scanSkillDirectory(root, path, name));
3758
+ entries.push(...scanSkillDirectory(root, path, name2));
3849
3759
  continue;
3850
3760
  }
3851
- if (isMarkdown(name))
3852
- entries.push(looseFileEntry(root, path, markdownStem(name)));
3761
+ if (isMarkdown(name2))
3762
+ entries.push(looseFileEntry(root, path, markdownStem(name2)));
3853
3763
  }
3854
3764
  return entries;
3855
3765
  }
@@ -3876,8 +3786,8 @@ function scanInstinctSubdirectory(root, dir) {
3876
3786
  }
3877
3787
  function scanInstinctRoot(root) {
3878
3788
  const entries = [];
3879
- for (const name of visibleNames(root)) {
3880
- const path = join13(root, name);
3789
+ for (const name2 of visibleNames(root)) {
3790
+ const path = join13(root, name2);
3881
3791
  const found = entryKind(path);
3882
3792
  if (found === null) {
3883
3793
  entries.push(unreadableEntry("instinct", root, path));
@@ -3887,14 +3797,14 @@ function scanInstinctRoot(root) {
3887
3797
  entries.push(...scanInstinctSubdirectory(root, path));
3888
3798
  continue;
3889
3799
  }
3890
- if (!isMarkdown(name))
3800
+ if (!isMarkdown(name2))
3891
3801
  continue;
3892
3802
  entries.push({
3893
3803
  kind: "instinct",
3894
3804
  path,
3895
3805
  isFile: true,
3896
3806
  shape: "instinct-file",
3897
- name: markdownStem(name),
3807
+ name: markdownStem(name2),
3898
3808
  issues: []
3899
3809
  });
3900
3810
  }
@@ -3914,9 +3824,9 @@ function scanLayout(root, kind) {
3914
3824
  function declaredNameIssue(entry, declared) {
3915
3825
  if (entry.name === null || declared === null || declared === entry.name)
3916
3826
  return null;
3917
- const field = entry.kind === "skill" ? "name" : "id";
3827
+ const field2 = entry.kind === "skill" ? "name" : "id";
3918
3828
  const source = entry.kind === "skill" ? "directory name" : "file name";
3919
- return layoutIssue("name-mismatch", `frontmatter ${field} "${declared}" is not the ${source} "${entry.name}"`);
3829
+ return layoutIssue("name-mismatch", `frontmatter ${field2} "${declared}" is not the ${source} "${entry.name}"`);
3920
3830
  }
3921
3831
 
3922
3832
  // src/schema/frontmatter.ts
@@ -4005,8 +3915,8 @@ function writeFrontmatter(document, data) {
4005
3915
  }
4006
3916
 
4007
3917
  // src/schema/instinct.ts
4008
- var INSTINCT_KINDS = FINDING_KINDS2;
4009
- var INSTINCT_SIGNALS = FINDING_SIGNALS2;
3918
+ var INSTINCT_KINDS = FINDING_KINDS;
3919
+ var INSTINCT_SIGNALS = FINDING_SIGNALS;
4010
3920
  var INSTINCT_DOMAINS = FINDING_DOMAINS;
4011
3921
  var INSTINCT_SCOPES = ["project", "user"];
4012
3922
  var INSTINCT_SOURCES = ["task-report", "loop-observed", "imported", "demoted"];
@@ -4036,8 +3946,8 @@ var INSTINCT_KEY_ORDER = [
4036
3946
  "created_at",
4037
3947
  "updated_at"
4038
3948
  ];
4039
- function issue(code, field, message) {
4040
- return { code, field, message };
3949
+ function issue(code, field2, message) {
3950
+ return { code, field: field2, message };
4041
3951
  }
4042
3952
  function typeName(value) {
4043
3953
  if (value === null)
@@ -4052,25 +3962,25 @@ function typeName(value) {
4052
3962
  return "a number";
4053
3963
  return `a ${typeof value}`;
4054
3964
  }
4055
- function requiredString(data, field) {
4056
- const value = data[field];
3965
+ function requiredString(data, field2) {
3966
+ const value = data[field2];
4057
3967
  if (value === undefined || value === null) {
4058
- return [issue("missing-field", field, `${field} is required and is absent`)];
3968
+ return [issue("missing-field", field2, `${field2} is required and is absent`)];
4059
3969
  }
4060
3970
  if (typeof value !== "string") {
4061
- return [issue("wrong-type", field, `${field} must be a string, not ${typeName(value)}`)];
3971
+ return [issue("wrong-type", field2, `${field2} must be a string, not ${typeName(value)}`)];
4062
3972
  }
4063
3973
  if (value.trim() === "") {
4064
- return [issue("missing-field", field, `${field} is required and is empty`)];
3974
+ return [issue("missing-field", field2, `${field2} is required and is empty`)];
4065
3975
  }
4066
3976
  return [];
4067
3977
  }
4068
- function requiredChoice(data, field, allowed, code) {
4069
- const issues = requiredString(data, field);
3978
+ function requiredChoice(data, field2, allowed, code) {
3979
+ const issues = requiredString(data, field2);
4070
3980
  if (issues.length > 0)
4071
3981
  return issues;
4072
- const value = data[field];
4073
- return allowed.includes(value) ? [] : [issue(code, field, `${field} "${value}" is not one of ${allowed.join(", ")}`)];
3982
+ const value = data[field2];
3983
+ return allowed.includes(value) ? [] : [issue(code, field2, `${field2} "${value}" is not one of ${allowed.join(", ")}`)];
4074
3984
  }
4075
3985
  function checkId(data) {
4076
3986
  const issues = requiredString(data, "id");
@@ -4106,11 +4016,11 @@ function checkSources(data) {
4106
4016
  return [issue("wrong-type", "sources", `sources must be a list, not ${typeName(value)}`)];
4107
4017
  }
4108
4018
  return value.flatMap((entry, index) => {
4109
- const field = `sources[${index}]`;
4019
+ const field2 = `sources[${index}]`;
4110
4020
  if (typeof entry !== "string") {
4111
- return [issue("wrong-type", field, `sources entries must be strings, and this one is ${typeName(entry)}`)];
4021
+ return [issue("wrong-type", field2, `sources entries must be strings, and this one is ${typeName(entry)}`)];
4112
4022
  }
4113
- return entry.trim() === "" ? [issue("wrong-type", field, "sources entries must name a source, and this one is blank")] : [];
4023
+ return entry.trim() === "" ? [issue("wrong-type", field2, "sources entries must name a source, and this one is blank")] : [];
4114
4024
  });
4115
4025
  }
4116
4026
  function checkPromotedTo(data) {
@@ -4139,26 +4049,26 @@ function checkProjectId(data) {
4139
4049
  }
4140
4050
  return PROJECT_ID_PATTERN.test(value) ? [] : [issue("invalid-project-id", "project_id", `project_id "${value}" is not ${PROJECT_ID_LENGTH} lowercase hex characters`)];
4141
4051
  }
4142
- function checkTimestamp(data, field) {
4143
- const issues = requiredString(data, field);
4052
+ function checkTimestamp(data, field2) {
4053
+ const issues = requiredString(data, field2);
4144
4054
  if (issues.length > 0)
4145
4055
  return issues;
4146
- const value = data[field];
4147
- return TIMESTAMP_PATTERN.test(value) && !Number.isNaN(Date.parse(value)) ? [] : [issue("invalid-timestamp", field, `${field} "${value}" is not an ISO 8601 instant such as 2026-09-11T10:00:00Z`)];
4056
+ const value = data[field2];
4057
+ return TIMESTAMP_PATTERN.test(value) && !Number.isNaN(Date.parse(value)) ? [] : [issue("invalid-timestamp", field2, `${field2} "${value}" is not an ISO 8601 instant such as 2026-09-11T10:00:00Z`)];
4148
4058
  }
4149
4059
  function isScalar(value) {
4150
4060
  return typeof value === "string" || typeof value === "number" || typeof value === "boolean";
4151
4061
  }
4152
4062
  function checkEvidenceEntry(entry, index) {
4153
- const field = `evidence[${index}]`;
4063
+ const field2 = `evidence[${index}]`;
4154
4064
  if (typeof entry !== "object" || entry === null || Array.isArray(entry)) {
4155
- return [issue("wrong-type", field, `evidence entries must be mappings, and this one is ${typeName(entry)}`)];
4065
+ return [issue("wrong-type", field2, `evidence entries must be mappings, and this one is ${typeName(entry)}`)];
4156
4066
  }
4157
4067
  const entries = Object.entries(entry);
4158
4068
  if (entries.length === 0) {
4159
- return [issue("wrong-type", field, "evidence entries must say something, and this one is empty")];
4069
+ return [issue("wrong-type", field2, "evidence entries must say something, and this one is empty")];
4160
4070
  }
4161
- return entries.flatMap(([key, value]) => isScalar(value) ? [] : [issue("wrong-type", `${field}.${key}`, `evidence values must be text, numbers or booleans, and this one is ${typeName(value)}`)]);
4071
+ return entries.flatMap(([key, value]) => isScalar(value) ? [] : [issue("wrong-type", `${field2}.${key}`, `evidence values must be text, numbers or booleans, and this one is ${typeName(value)}`)]);
4162
4072
  }
4163
4073
  function checkEvidence(data) {
4164
4074
  const value = data["evidence"];
@@ -4271,7 +4181,7 @@ function buildInstinct(data, body) {
4271
4181
  updatedAt: data["updated_at"],
4272
4182
  action,
4273
4183
  cause: sectionText(body, CAUSE_HEADING) ?? "",
4274
- actionHash: actionHash2(action)
4184
+ actionHash: actionHash(action)
4275
4185
  };
4276
4186
  }
4277
4187
  function instinctFrontmatter(instinct) {
@@ -4318,11 +4228,11 @@ function writeInstinct(instinct, newline = `
4318
4228
  }
4319
4229
 
4320
4230
  // src/commands/instinct/instinct-records.ts
4321
- function isRecordFile(name) {
4322
- return !name.startsWith(".") && name.endsWith(MARKDOWN_EXTENSION) && name !== MARKDOWN_EXTENSION;
4231
+ function isRecordFile(name2) {
4232
+ return !name2.startsWith(".") && name2.endsWith(MARKDOWN_EXTENSION) && name2 !== MARKDOWN_EXTENSION;
4323
4233
  }
4324
- function recordId(name) {
4325
- return name.slice(0, -MARKDOWN_EXTENSION.length);
4234
+ function recordId(name2) {
4235
+ return name2.slice(0, -MARKDOWN_EXTENSION.length);
4326
4236
  }
4327
4237
  function unreadableIssue(message) {
4328
4238
  return { code: "missing-frontmatter", field: "file", message: `the file could not be read: ${message}` };
@@ -4346,7 +4256,7 @@ function isFile2(path) {
4346
4256
  }
4347
4257
  }
4348
4258
  function recordFiles(dir) {
4349
- return readdirSync4(dir).filter((name) => isRecordFile(name) && isFile2(join14(dir, name))).sort((left, right) => left.localeCompare(right));
4259
+ return readdirSync4(dir).filter((name2) => isRecordFile(name2) && isFile2(join14(dir, name2))).sort((left, right) => left.localeCompare(right));
4350
4260
  }
4351
4261
  function readScope(scope, dir) {
4352
4262
  if (!tierExists(dir))
@@ -4355,7 +4265,7 @@ function readScope(scope, dir) {
4355
4265
  scope,
4356
4266
  dir,
4357
4267
  exists: true,
4358
- records: recordFiles(dir).map((name) => readRecord(join14(dir, name), scope, recordId(name)))
4268
+ records: recordFiles(dir).map((name2) => readRecord(join14(dir, name2), scope, recordId(name2)))
4359
4269
  };
4360
4270
  }
4361
4271
  function readScopes(seams) {
@@ -4367,9 +4277,9 @@ function allRecords(listings) {
4367
4277
  function findRecords(listings, id) {
4368
4278
  return allRecords(listings).filter((entry) => entry.id === id);
4369
4279
  }
4370
- function instinctProject(context, name) {
4280
+ function instinctProject(context, name2) {
4371
4281
  if (context.project === null)
4372
- throw new Error(`${name} runs inside a project, and was handed none`);
4282
+ throw new Error(`${name2} runs inside a project, and was handed none`);
4373
4283
  return context.project;
4374
4284
  }
4375
4285
 
@@ -4406,17 +4316,17 @@ function toHeldRecord(instinct) {
4406
4316
  function toHeldRecords(held) {
4407
4317
  const actions = new Map;
4408
4318
  for (const instinct of held) {
4409
- const key = triggerKey2(instinct.trigger);
4319
+ const key = triggerKey(instinct.trigger);
4410
4320
  actions.set(key, (actions.get(key) ?? new Set).add(instinct.actionHash));
4411
4321
  }
4412
4322
  return held.map((instinct) => {
4413
4323
  const record = toHeldRecord(instinct);
4414
- return actions.get(triggerKey2(instinct.trigger)).size > 1 ? { ...record, status: "flagged" } : record;
4324
+ return actions.get(triggerKey(instinct.trigger)).size > 1 ? { ...record, status: "flagged" } : record;
4415
4325
  });
4416
4326
  }
4417
4327
  function earliestHeldMember(record, held) {
4418
- const key = triggerKey2(record.trigger);
4419
- const members = held.filter((instinct) => instinct.actionHash === record.action_hash && triggerKey2(instinct.trigger) === key);
4328
+ const key = triggerKey(record.trigger);
4329
+ const members = held.filter((instinct) => instinct.actionHash === record.action_hash && triggerKey(instinct.trigger) === key);
4420
4330
  return [...members].sort(byAge)[0] ?? null;
4421
4331
  }
4422
4332
  function toHeldInstinct(record, held, fallback) {
@@ -4443,7 +4353,7 @@ function toHeldInstinct(record, held, fallback) {
4443
4353
  updatedAt: record.updated_at,
4444
4354
  action: record.action,
4445
4355
  cause: description.cause,
4446
- actionHash: actionHash2(record.action)
4356
+ actionHash: actionHash(record.action)
4447
4357
  };
4448
4358
  }
4449
4359
 
@@ -4525,7 +4435,7 @@ function recordProblem(record, index) {
4525
4435
  if (problem !== null)
4526
4436
  return problem;
4527
4437
  const { action, action_hash: hash, description } = record;
4528
- if (hash !== actionHash2(action)) {
4438
+ if (hash !== actionHash(action)) {
4529
4439
  return `action_hash is ${describeValue(hash)} in ${at}, expected the sha256 of its trimmed, lower-cased action`;
4530
4440
  }
4531
4441
  return description === undefined ? null : fieldsProblem(description, DESCRIPTION_CHECKS, `${at}.description`);
@@ -4537,7 +4447,7 @@ function payloadProblem(payload) {
4537
4447
  const { instincts } = payload;
4538
4448
  return instincts.map(recordProblem).find((found) => found !== null) ?? null;
4539
4449
  }
4540
- function flagProblem2(value) {
4450
+ function flagProblem(value) {
4541
4451
  return fieldsProblem(value, FLAG_CHECKS, "the flag");
4542
4452
  }
4543
4453
  function copyInstinct(record) {
@@ -4614,9 +4524,9 @@ function unflagged(records, flagged) {
4614
4524
  return records.filter((record) => !flagged.has(record.id));
4615
4525
  }
4616
4526
  function userAdditions(userBlessed, projectHeld, flagged) {
4617
- const heldTriggers = new Set(projectHeld.map((record) => triggerKey2(record.trigger)));
4527
+ const heldTriggers = new Set(projectHeld.map((record) => triggerKey(record.trigger)));
4618
4528
  const heldIds = new Set(projectHeld.map((record) => record.id));
4619
- return unflagged(userBlessed, flagged).filter((record) => !heldTriggers.has(triggerKey2(record.trigger)) && !heldIds.has(record.id));
4529
+ return unflagged(userBlessed, flagged).filter((record) => !heldTriggers.has(triggerKey(record.trigger)) && !heldIds.has(record.id));
4620
4530
  }
4621
4531
  function byAge2(left, right) {
4622
4532
  if (left.created_at !== right.created_at) {
@@ -4627,8 +4537,8 @@ function byAge2(left, right) {
4627
4537
  return left.id < right.id ? -1 : 1;
4628
4538
  }
4629
4539
  function payloadDescription(record, described) {
4630
- const key = triggerKey2(record.trigger);
4631
- const members = described.filter((candidate) => candidate.description !== undefined && candidate.action_hash === record.action_hash && triggerKey2(candidate.trigger) === key);
4540
+ const key = triggerKey(record.trigger);
4541
+ const members = described.filter((candidate) => candidate.description !== undefined && candidate.action_hash === record.action_hash && triggerKey(candidate.trigger) === key);
4632
4542
  return [...members].sort(byAge2)[0]?.description;
4633
4543
  }
4634
4544
  function producedRecords(result) {
@@ -4654,35 +4564,35 @@ function heldChanges(dir, held, result, described) {
4654
4564
  throw new Error(`${PUSH_REFUSAL}: ${file} has no held member and no payload description to be written with`);
4655
4565
  }
4656
4566
  const text = writeInstinct(instinct);
4657
- const [issue] = parseInstinct(text).issues;
4658
- if (issue !== undefined) {
4659
- throw new Error(`${PUSH_REFUSAL}: ${file} would not read back: ${issue.field}: ${issue.message}`);
4567
+ const [issue2] = parseInstinct(text).issues;
4568
+ if (issue2 !== undefined) {
4569
+ throw new Error(`${PUSH_REFUSAL}: ${file} would not read back: ${issue2.field}: ${issue2.message}`);
4660
4570
  }
4661
4571
  const path = join15(dir, file);
4662
4572
  if (held.unreadable.has(path)) {
4663
4573
  throw new Error(`${PUSH_REFUSAL}: it would overwrite ${path}, which could not be read`);
4664
4574
  }
4665
4575
  const before = heldAt.get(path);
4666
- if (before !== undefined && triggerKey2(before.trigger) !== triggerKey2(record.trigger)) {
4576
+ if (before !== undefined && triggerKey(before.trigger) !== triggerKey(record.trigger)) {
4667
4577
  throw new Error(`${PUSH_REFUSAL}: it would overwrite ${path}, which holds another trigger`);
4668
4578
  }
4669
4579
  kept.add(path);
4670
4580
  if (before === undefined || writeInstinct(before) !== text)
4671
4581
  writes.push({ path, text });
4672
4582
  }
4673
- const touched = new Set(result.decisions.map((decision) => triggerKey2(decision.incoming.trigger)));
4674
- const removals = held.files.filter((file) => touched.has(triggerKey2(file.instinct.trigger)) && !kept.has(file.path)).map((file) => file.path);
4583
+ const touched = new Set(result.decisions.map((decision) => triggerKey(decision.incoming.trigger)));
4584
+ const removals = held.files.filter((file) => touched.has(triggerKey(file.instinct.trigger)) && !kept.has(file.path)).map((file) => file.path);
4675
4585
  return { writes, removals };
4676
4586
  }
4677
4587
  function pushLogLines(sourceId, described, result) {
4678
4588
  return result.decisions.map((decision, index) => {
4679
- const key = triggerKey2(decision.incoming.trigger);
4589
+ const key = triggerKey(decision.incoming.trigger);
4680
4590
  const line = {
4681
4591
  source_id: sourceId,
4682
4592
  rule: decision.rule,
4683
4593
  incoming: loggedIncoming(described[index]),
4684
4594
  produced: decision.produced.map((record) => record.id),
4685
- discarded: result.discarded.filter((record) => triggerKey2(record.trigger) === key).map((record) => record.id)
4595
+ discarded: result.discarded.filter((record) => triggerKey(record.trigger) === key).map((record) => record.id)
4686
4596
  };
4687
4597
  return JSON.stringify(line);
4688
4598
  });
@@ -4707,7 +4617,7 @@ function createLocalLearning(options) {
4707
4617
  for (const entry of records) {
4708
4618
  if (entry.instinct === null) {
4709
4619
  unreadable.add(entry.path);
4710
- const problems = entry.issues.map((issue) => `${issue.field}: ${issue.message}`).join("; ");
4620
+ const problems = entry.issues.map((issue2) => `${issue2.field}: ${issue2.message}`).join("; ");
4711
4621
  warn(`${PREFIX}: ${entry.path} is not a held instinct, so it was skipped: ${problems}`);
4712
4622
  } else {
4713
4623
  files.push({ path: entry.path, instinct: entry.instinct });
@@ -4724,7 +4634,7 @@ function createLocalLearning(options) {
4724
4634
  async function flaggedIds() {
4725
4635
  const lines = numberedLines(await readIfPresent(flagsPath));
4726
4636
  return new Set(lines.map(([number, line]) => {
4727
- const reading = readLine(line, flagProblem2);
4637
+ const reading = readLine(line, flagProblem);
4728
4638
  if (reading.ok)
4729
4639
  return reading.value.id;
4730
4640
  throw new Error(`${PREFIX}: line ${number} of ${flagsPath} is not a flag,` + ` and a bundle skipping it could hold an instinct it flags: ${reading.problem}`);
@@ -4738,7 +4648,7 @@ function createLocalLearning(options) {
4738
4648
  }
4739
4649
  const described = payload.instincts;
4740
4650
  const held = heldSet();
4741
- const result = merge2(toHeldRecords(held.files.map((file) => file.instinct)), { source_id: payload.source_id, instincts: described.map(copyInstinct) }, now());
4651
+ const result = merge(toHeldRecords(held.files.map((file) => file.instinct)), { source_id: payload.source_id, instincts: described.map(copyInstinct) }, now());
4742
4652
  const changes = heldChanges(instinctsDir, held, result, described);
4743
4653
  const lines = pushLogLines(payload.source_id, described, result);
4744
4654
  if (lines.length > 0) {
@@ -4756,13 +4666,13 @@ function createLocalLearning(options) {
4756
4666
  pullBlessed: async () => {
4757
4667
  const flagged = await flaggedIds();
4758
4668
  const projectHeld = heldRecords(heldSet());
4759
- const project = bless2(unflagged(projectHeld, flagged), { minConfidence }).instincts;
4760
- const user = bless2(heldRecords(readHeld("user", userDir)), { minConfidence }).instincts;
4669
+ const project = bless(unflagged(projectHeld, flagged), { minConfidence }).instincts;
4670
+ const user = bless(heldRecords(readHeld("user", userDir)), { minConfidence }).instincts;
4761
4671
  return { version: now(), instincts: [...project, ...userAdditions(user, projectHeld, flagged)] };
4762
4672
  },
4763
4673
  flag: async (id, reason) => {
4764
4674
  const flag = { id, reason, flagged_at: now() };
4765
- const problem = flagProblem2(flag);
4675
+ const problem = flagProblem(flag);
4766
4676
  if (problem !== null) {
4767
4677
  throw new TypeError(`${PREFIX}: refused to write an invalid flag: ${problem}`);
4768
4678
  }
@@ -4882,8 +4792,8 @@ function describeValue3(value) {
4882
4792
  function messageOf2(error) {
4883
4793
  return error instanceof Error ? error.message : String(error);
4884
4794
  }
4885
- function counted(count, noun) {
4886
- return count === 1 ? `1 ${noun}` : `${String(count)} ${noun}s`;
4795
+ function counted(count2, noun) {
4796
+ return count2 === 1 ? `1 ${noun}` : `${String(count2)} ${noun}s`;
4887
4797
  }
4888
4798
  function valueAt(mapping, key) {
4889
4799
  return Object.hasOwn(mapping, key) ? mapping[key] ?? null : null;
@@ -4901,39 +4811,39 @@ function verdictOf(value) {
4901
4811
  const word = spelled.replace(VERDICT_BREAK, "-");
4902
4812
  return SPEC_REVIEW_VERDICTS.includes(word) ? word : null;
4903
4813
  }
4904
- function issueAt(field, text) {
4905
- return { field, text };
4814
+ function issueAt(field2, text) {
4815
+ return { field: field2, text };
4906
4816
  }
4907
- function readBlocking(item, field, issues) {
4817
+ function readBlocking(item, field2, issues) {
4908
4818
  const value = valueAt(item, "blocking");
4909
4819
  if (typeof value === "boolean")
4910
4820
  return value;
4911
- const text = `${field}.blocking is ${describeValue3(value)}, not true or false; ` + "the gap is read as blocking";
4912
- issues.push(issueAt(`${field}.blocking`, text));
4821
+ const text = `${field2}.blocking is ${describeValue3(value)}, not true or false; ` + "the gap is read as blocking";
4822
+ issues.push(issueAt(`${field2}.blocking`, text));
4913
4823
  return true;
4914
4824
  }
4915
- function readGap(item, field, issues) {
4825
+ function readGap(item, field2, issues) {
4916
4826
  if (!isMapping2(item)) {
4917
- const text = `${field} is ${describeValue3(item)}, not a mapping of heading and what; dropped`;
4918
- issues.push(issueAt(field, text));
4827
+ const text = `${field2} is ${describeValue3(item)}, not a mapping of heading and what; dropped`;
4828
+ issues.push(issueAt(field2, text));
4919
4829
  return null;
4920
4830
  }
4921
4831
  const what = stringAt(item, "what");
4922
4832
  if (what === null) {
4923
- const text = `${field}.what is ${describeValue3(valueAt(item, "what"))}, ` + "not a sentence; the gap is dropped";
4924
- issues.push(issueAt(`${field}.what`, text));
4833
+ const text = `${field2}.what is ${describeValue3(valueAt(item, "what"))}, ` + "not a sentence; the gap is dropped";
4834
+ issues.push(issueAt(`${field2}.what`, text));
4925
4835
  return null;
4926
4836
  }
4927
4837
  const heading = stringAt(item, "heading");
4928
4838
  if (heading === null) {
4929
- const text = `${field}.heading is ${describeValue3(valueAt(item, "heading"))}, ` + `not a heading; the gap is filed under ${REVIEW_HEADING}`;
4930
- issues.push(issueAt(`${field}.heading`, text));
4839
+ const text = `${field2}.heading is ${describeValue3(valueAt(item, "heading"))}, ` + `not a heading; the gap is filed under ${REVIEW_HEADING}`;
4840
+ issues.push(issueAt(`${field2}.heading`, text));
4931
4841
  }
4932
- const blocking = readBlocking(item, field, issues);
4842
+ const blocking = readBlocking(item, field2, issues);
4933
4843
  const assumption = stringAt(item, "assumption");
4934
4844
  if (!blocking && assumption === null) {
4935
- const text = `${field}.assumption is ${describeValue3(valueAt(item, "assumption"))}, ` + "not what a non-blocking gap would be planned under; the gap is read as blocking";
4936
- issues.push(issueAt(`${field}.assumption`, text));
4845
+ const text = `${field2}.assumption is ${describeValue3(valueAt(item, "assumption"))}, ` + "not what a non-blocking gap would be planned under; the gap is read as blocking";
4846
+ issues.push(issueAt(`${field2}.assumption`, text));
4937
4847
  return { heading: heading ?? REVIEW_HEADING, what, blocking: true, assumption: null };
4938
4848
  }
4939
4849
  return { heading: heading ?? REVIEW_HEADING, what, blocking, assumption };
@@ -4982,7 +4892,7 @@ function judged(verdict, gaps, block, issues) {
4982
4892
  };
4983
4893
  }
4984
4894
  function parseSpecReview(output) {
4985
- const reviews = readRafaBlocks2(output).filter((found) => found.kind === SPEC_REVIEW_KIND);
4895
+ const reviews = readRafaBlocks(output).filter((found) => found.kind === SPEC_REVIEW_KIND);
4986
4896
  const block = reviews.at(-1);
4987
4897
  if (block === undefined) {
4988
4898
  return unreadable("absent", null, "the session output holds no rafa:spec-review block");
@@ -5051,16 +4961,16 @@ class UndeclaredSpendError extends Error {
5051
4961
  name = "UndeclaredSpendError";
5052
4962
  }
5053
4963
  function carriesFlag(flags, flag) {
5054
- const name = flag.replace(/^--/, "");
5055
- const value = flags[name];
4964
+ const name2 = flag.replace(/^--/, "");
4965
+ const value = flags[name2];
5056
4966
  if (value !== undefined && value !== false)
5057
4967
  return true;
5058
- return name.startsWith("no-") && flags[name.slice(3)] === false;
4968
+ return name2.startsWith("no-") && flags[name2.slice(3)] === false;
5059
4969
  }
5060
- function spendRefusal(running) {
5061
- if (running === null)
4970
+ function spendRefusal(running2) {
4971
+ if (running2 === null)
5062
4972
  return null;
5063
- const { command, flags } = running;
4973
+ const { command, flags } = running2;
5064
4974
  const spend = command.spends;
5065
4975
  const named = `rafa ${commandSpelling(command)}`;
5066
4976
  const remedy = "declare spends on the command to cover this run";
@@ -5210,6 +5120,62 @@ function createClaudePlanner(options) {
5210
5120
  return Object.freeze({ create });
5211
5121
  }
5212
5122
 
5123
+ // src/adapters/tracker/github-edit.ts
5124
+ var PREFIX2 = "github tracker";
5125
+ var EDITABLE_FIELDS = "title,body,state,labels,author";
5126
+ function viewedEditable(payload, labelNames) {
5127
+ if (!isMapping(payload))
5128
+ return `${describeValue(payload)}, expected a mapping`;
5129
+ const { title, body, state, author } = payload;
5130
+ if (typeof title !== "string")
5131
+ return `title ${describeValue(title)}, expected a string`;
5132
+ if (typeof body !== "string")
5133
+ return `body ${describeValue(body)}, expected a string`;
5134
+ if (state !== "OPEN" && state !== "CLOSED")
5135
+ return `state ${describeValue(state)}, expected "OPEN" or "CLOSED"`;
5136
+ const labels = labelNames(payload["labels"]);
5137
+ if (labels === null)
5138
+ return "labels that are not a list of named labels";
5139
+ const login = isMapping(author) ? author["login"] : undefined;
5140
+ if (typeof login !== "string")
5141
+ return `author ${describeValue(author)}, expected a mapping holding a string login`;
5142
+ return { title, body, open: state === "OPEN", labels, author: login };
5143
+ }
5144
+ function editProblem(change) {
5145
+ if (!isMapping(change))
5146
+ return `the change is ${describeValue(change)}, expected a mapping`;
5147
+ const { body, title } = change;
5148
+ if (body === undefined && title === undefined)
5149
+ return "the change names neither a body nor a title";
5150
+ if (body !== undefined && typeof body !== "string")
5151
+ return `body is ${describeValue(body)}, expected a string`;
5152
+ return title !== undefined && typeof title !== "string" ? `title is ${describeValue(title)}, expected a string` : null;
5153
+ }
5154
+ function optionalFlag(name2, value) {
5155
+ return value === undefined ? [] : [name2, value];
5156
+ }
5157
+ function createGithubEditMembers(readers) {
5158
+ const { run, issueNumberOf, parseJson, labelNames } = readers;
5159
+ const editable = async (ref) => {
5160
+ const number = issueNumberOf(ref);
5161
+ const command = `gh issue view ${number}`;
5162
+ const stdout = await run(["issue", "view", number, ...optionalFlag("--repo", ref.repo), "--json", EDITABLE_FIELDS], command);
5163
+ const viewed = viewedEditable(parseJson(stdout, command), labelNames);
5164
+ if (typeof viewed === "string")
5165
+ throw new Error(`${PREFIX2}: ${command} answered ${viewed}`);
5166
+ return { ref, ...viewed };
5167
+ };
5168
+ const edit = async (ref, change) => {
5169
+ const number = issueNumberOf(ref);
5170
+ const problem = editProblem(change);
5171
+ if (problem !== null)
5172
+ throw new TypeError(`${PREFIX2}: refused an edit of issue #${number}: ${problem}`);
5173
+ const bodyFlag = change.body === undefined ? [] : ["--body-file", "-"];
5174
+ await run(["issue", "edit", number, ...optionalFlag("--repo", ref.repo), ...optionalFlag("--title", change.title), ...bodyFlag], `gh issue edit ${number}`, change.body);
5175
+ };
5176
+ return Object.freeze({ editable, edit });
5177
+ }
5178
+
5213
5179
  // src/adapters/tracker/issue-values.ts
5214
5180
  var TYPE_MEMBERS = {
5215
5181
  code: true,
@@ -5218,7 +5184,8 @@ var TYPE_MEMBERS = {
5218
5184
  adr: true,
5219
5185
  chore: true,
5220
5186
  "package-api": true,
5221
- epic: true
5187
+ epic: true,
5188
+ spec: true
5222
5189
  };
5223
5190
  var PRIORITY_MEMBERS = {
5224
5191
  urgent: true,
@@ -5240,13 +5207,14 @@ var ISSUE_PRIORITIES = Object.freeze(Object.keys(PRIORITY_MEMBERS));
5240
5207
  var ISSUE_STATES = Object.freeze(Object.keys(STATE_MEMBERS));
5241
5208
 
5242
5209
  // src/adapters/tracker/github.ts
5243
- var PREFIX2 = "github tracker";
5210
+ var PREFIX3 = "github tracker";
5244
5211
  var GITHUB_LABELS = Object.freeze({
5245
5212
  modulePrefix: "module:",
5246
5213
  typePrefix: "type:",
5247
5214
  priorityPrefix: "priority:",
5248
5215
  needsTriage: "needs-triage",
5249
- blockedByPrefix: "blocked-by:OPT-"
5216
+ blockedByPrefix: "blocked-by:OPT-",
5217
+ specBlocked: "spec:blocked"
5250
5218
  });
5251
5219
  var VIEW_FIELDS = "number,title,body,state,stateReason,labels,url";
5252
5220
  var LIST_COMMAND = "gh issue list";
@@ -5269,7 +5237,7 @@ var REST_STATES = {
5269
5237
  };
5270
5238
  function createGhRunner(options) {
5271
5239
  const { cwd, command = "gh", env, timeoutMs } = options;
5272
- return async (args) => {
5240
+ return async (args, stdin) => {
5273
5241
  const executable = env === undefined ? command : Bun.which(command, { PATH: env.PATH ?? "", cwd });
5274
5242
  if (executable === null) {
5275
5243
  return { ok: false, stdout: "", stderr: notOnPath(command, cwd, env?.PATH) };
@@ -5278,7 +5246,7 @@ function createGhRunner(options) {
5278
5246
  const proc = Bun.spawn([executable, ...args], {
5279
5247
  cwd,
5280
5248
  ...env === undefined ? {} : { env: { ...env } },
5281
- stdin: "ignore",
5249
+ stdin: stdin === undefined ? "ignore" : new TextEncoder().encode(stdin),
5282
5250
  stdout: "pipe",
5283
5251
  stderr: "pipe"
5284
5252
  });
@@ -5305,8 +5273,8 @@ async function withDeadline(work, timeoutMs) {
5305
5273
  if (timeoutMs === undefined)
5306
5274
  return work;
5307
5275
  let timer;
5308
- const deadline = new Promise((resolve) => {
5309
- timer = setTimeout(() => resolve(TIMED_OUT), timeoutMs);
5276
+ const deadline = new Promise((resolve7) => {
5277
+ timer = setTimeout(() => resolve7(TIMED_OUT), timeoutMs);
5310
5278
  });
5311
5279
  try {
5312
5280
  return await Promise.race([work, deadline]);
@@ -5333,8 +5301,8 @@ function isRepoName(value) {
5333
5301
  function isLabelPart(value) {
5334
5302
  return typeof value === "string" && !value.includes(",");
5335
5303
  }
5336
- function optionalFlag(name, value) {
5337
- return value === undefined ? [] : [name, value];
5304
+ function optionalFlag2(name2, value) {
5305
+ return value === undefined ? [] : [name2, value];
5338
5306
  }
5339
5307
  function detailOf(result) {
5340
5308
  return result.stderr.trim() || result.stdout.trim() || "it exited non-zero and wrote nothing";
@@ -5355,7 +5323,8 @@ var DRAFT_CHECKS = [
5355
5323
  "blockedBy",
5356
5324
  (value) => Array.isArray(value) && value.every((item) => Number.isSafeInteger(item) && item > 0),
5357
5325
  "a list of positive whole numbers"
5358
- ]
5326
+ ],
5327
+ ["specBlocked", (value) => value === undefined || typeof value === "boolean", "absent or a boolean"]
5359
5328
  ];
5360
5329
  function draftProblem(draft) {
5361
5330
  if (!isMapping(draft))
@@ -5369,18 +5338,19 @@ function labelsFor(draft) {
5369
5338
  `${GITHUB_LABELS.modulePrefix}${draft.module}`,
5370
5339
  `${GITHUB_LABELS.typePrefix}${draft.type}`,
5371
5340
  ...draft.blockedBy.map((opt) => `${GITHUB_LABELS.blockedByPrefix}${opt}`),
5341
+ ...draft.specBlocked === true ? [GITHUB_LABELS.specBlocked] : [],
5372
5342
  priority
5373
5343
  ];
5374
5344
  }
5375
5345
  function issueNumberOfRef(ref) {
5376
5346
  if (ref.kind !== "github") {
5377
- throw new Error(`${PREFIX2}: refused a ref of kind ${describeValue(ref.kind)}; this tracker reads github refs only`);
5347
+ throw new Error(`${PREFIX3}: refused a ref of kind ${describeValue(ref.kind)}; this tracker reads github refs only`);
5378
5348
  }
5379
5349
  if (!isIssueNumber3(ref.externalId)) {
5380
- throw new Error(`${PREFIX2}: externalId ${describeValue(ref.externalId)} is not a GitHub issue number,` + " expected a positive whole number with no leading zero");
5350
+ throw new Error(`${PREFIX3}: externalId ${describeValue(ref.externalId)} is not a GitHub issue number,` + " expected a positive whole number with no leading zero");
5381
5351
  }
5382
5352
  if (ref.repo !== undefined && !isRepoName(ref.repo)) {
5383
- throw new Error(`${PREFIX2}: repo ${describeValue(ref.repo)} is not a repository, expected owner/name`);
5353
+ throw new Error(`${PREFIX3}: repo ${describeValue(ref.repo)} is not a repository, expected owner/name`);
5384
5354
  }
5385
5355
  return ref.externalId;
5386
5356
  }
@@ -5388,7 +5358,7 @@ function parseJson(stdout, command) {
5388
5358
  try {
5389
5359
  return JSON.parse(stdout);
5390
5360
  } catch (error) {
5391
- throw new Error(`${PREFIX2}: ${command} wrote output that is not JSON: ${messageOf(error)}`, {
5361
+ throw new Error(`${PREFIX3}: ${command} wrote output that is not JSON: ${messageOf(error)}`, {
5392
5362
  cause: error
5393
5363
  });
5394
5364
  }
@@ -5397,7 +5367,7 @@ function labelNames(value) {
5397
5367
  if (!Array.isArray(value))
5398
5368
  return null;
5399
5369
  const names = value.map((label) => isMapping(label) && typeof label["name"] === "string" ? label["name"] : null);
5400
- return names.every((name) => name !== null) ? names : null;
5370
+ return names.every((name2) => name2 !== null) ? names : null;
5401
5371
  }
5402
5372
  function viewProblem(payload, number) {
5403
5373
  if (!isMapping(payload))
@@ -5422,19 +5392,19 @@ function viewedIssue(stdout, number) {
5422
5392
  const payload = parseJson(stdout, command);
5423
5393
  const problem = viewProblem(payload, number);
5424
5394
  if (problem !== null)
5425
- throw new Error(`${PREFIX2}: ${command} answered ${problem}`);
5395
+ throw new Error(`${PREFIX3}: ${command} answered ${problem}`);
5426
5396
  const checked = payload;
5427
5397
  return { ...checked, labels: labelNames(checked.labels) ?? [] };
5428
5398
  }
5429
5399
  function listedRows(stdout) {
5430
5400
  const payload = parseJson(stdout, LIST_COMMAND);
5431
5401
  if (!Array.isArray(payload)) {
5432
- throw new Error(`${PREFIX2}: ${LIST_COMMAND} answered ${describeValue(payload)}, expected a list`);
5402
+ throw new Error(`${PREFIX3}: ${LIST_COMMAND} answered ${describeValue(payload)}, expected a list`);
5433
5403
  }
5434
5404
  return payload;
5435
5405
  }
5436
5406
  function rowRefusal(index, problem) {
5437
- return new Error(`${PREFIX2}: ${LIST_COMMAND} answered row ${index} ${problem}`);
5407
+ return new Error(`${PREFIX3}: ${LIST_COMMAND} answered row ${index} ${problem}`);
5438
5408
  }
5439
5409
  function listedRow(row, index) {
5440
5410
  if (!isMapping(row))
@@ -5455,13 +5425,13 @@ function listedIssues(stdout) {
5455
5425
  }
5456
5426
  function listedOpenIssues(stdout) {
5457
5427
  return listedRows(stdout).map((row, index) => {
5458
- const listed = listedRow(row, index);
5428
+ const listed2 = listedRow(row, index);
5459
5429
  const { title, body } = row;
5460
5430
  if (typeof title !== "string")
5461
5431
  throw rowRefusal(index, `with title ${describeValue(title)}, expected a string`);
5462
5432
  if (typeof body !== "string")
5463
5433
  throw rowRefusal(index, `with body ${describeValue(body)}, expected a string`);
5464
- return { ...listed, title, body };
5434
+ return { ...listed2, title, body };
5465
5435
  });
5466
5436
  }
5467
5437
  function refOfRow(row) {
@@ -5507,21 +5477,21 @@ function readBackState(state) {
5507
5477
  function stateQueryRefusal(state) {
5508
5478
  const bucket = REST_STATES[state];
5509
5479
  const siblings = ISSUE_STATES.filter((other) => other !== state && REST_STATES[other] === bucket);
5510
- return `${PREFIX2}: find cannot narrow by state ${describeValue(state)}: GitHub holds an issue open or` + ` closed, and ${state} shares ${bucket} with ${siblings.join(", ")}, so a result would include` + " those too. Search without a state, then read each issue with get.";
5480
+ return `${PREFIX3}: find cannot narrow by state ${describeValue(state)}: GitHub holds an issue open or` + ` closed, and ${state} shares ${bucket} with ${siblings.join(", ")}, so a result would include` + " those too. Search without a state, then read each issue with get.";
5511
5481
  }
5512
5482
  function createGithubTracker(options) {
5513
5483
  const { gh } = options;
5514
5484
  let knownLabels = new Set;
5515
- async function run(args, command) {
5516
- const result = await gh(args);
5485
+ async function run(args, command, stdin) {
5486
+ const result = await gh(args, stdin);
5517
5487
  if (!result.ok)
5518
- throw new Error(`${PREFIX2}: ${command} failed: ${detailOf(result)}`);
5488
+ throw new Error(`${PREFIX3}: ${command} failed: ${detailOf(result)}`);
5519
5489
  return result.stdout;
5520
5490
  }
5521
5491
  async function ensureLabels(names) {
5522
- const missing = [...new Set(names)].filter((name) => !knownLabels.has(name));
5523
- for (const name of missing) {
5524
- await run(["label", "create", name, "--force"], `gh label create ${describeValue(name)}`);
5492
+ const missing = [...new Set(names)].filter((name2) => !knownLabels.has(name2));
5493
+ for (const name2 of missing) {
5494
+ await run(["label", "create", name2, "--force"], `gh label create ${describeValue(name2)}`);
5525
5495
  }
5526
5496
  knownLabels = new Set([...knownLabels, ...missing]);
5527
5497
  }
@@ -5548,7 +5518,7 @@ function createGithubTracker(options) {
5548
5518
  create: async (draft) => {
5549
5519
  const problem = draftProblem(draft);
5550
5520
  if (problem !== null)
5551
- throw new TypeError(`${PREFIX2}: refused to file an invalid draft: ${problem}`);
5521
+ throw new TypeError(`${PREFIX3}: refused to file an invalid draft: ${problem}`);
5552
5522
  const labels = labelsFor(draft);
5553
5523
  await ensureLabels(labels);
5554
5524
  const stdout = await run([
@@ -5564,20 +5534,20 @@ function createGithubTracker(options) {
5564
5534
  `).at(-1) ?? "";
5565
5535
  const number = CREATED_ISSUE_URL.exec(url)?.[1];
5566
5536
  if (number === undefined) {
5567
- throw new Error(`${PREFIX2}: gh issue create exited 0 and printed no issue URL, so the issue may exist` + ` unrecorded; it wrote ${describeValue(stdout)}`);
5537
+ throw new Error(`${PREFIX3}: gh issue create exited 0 and printed no issue URL, so the issue may exist` + ` unrecorded; it wrote ${describeValue(stdout)}`);
5568
5538
  }
5569
5539
  return { opt: draft.opt, kind: "github", externalId: number, url, module: draft.module };
5570
5540
  },
5571
5541
  get: async (ref) => {
5572
5542
  const number = issueNumberOfRef(ref);
5573
- const stdout = await run(["issue", "view", number, ...optionalFlag("--repo", ref.repo), "--json", VIEW_FIELDS], `gh issue view ${number}`);
5543
+ const stdout = await run(["issue", "view", number, ...optionalFlag2("--repo", ref.repo), "--json", VIEW_FIELDS], `gh issue view ${number}`);
5574
5544
  return issueOf(ref, viewedIssue(stdout, number));
5575
5545
  },
5576
5546
  find: async (query) => {
5577
5547
  if (query.state !== undefined)
5578
5548
  throw new Error(stateQueryRefusal(query.state));
5579
5549
  if (query.module !== undefined && !isLabelPart(query.module)) {
5580
- throw new TypeError(`${PREFIX2}: find refused module ${describeValue(query.module)}, expected a string holding no comma`);
5550
+ throw new TypeError(`${PREFIX3}: find refused module ${describeValue(query.module)}, expected a string holding no comma`);
5581
5551
  }
5582
5552
  const moduleLabel = query.module === undefined ? undefined : `${GITHUB_LABELS.modulePrefix}${query.module}`;
5583
5553
  const typeLabel = query.type === undefined ? undefined : `${GITHUB_LABELS.typePrefix}${query.type}`;
@@ -5590,15 +5560,15 @@ function createGithubTracker(options) {
5590
5560
  LIST_FIELDS,
5591
5561
  "--limit",
5592
5562
  String(query.limit ?? DEFAULT_FIND_LIMIT),
5593
- ...optionalFlag("--label", moduleLabel),
5594
- ...optionalFlag("--label", typeLabel),
5595
- ...optionalFlag("--search", query.text)
5563
+ ...optionalFlag2("--label", moduleLabel),
5564
+ ...optionalFlag2("--label", typeLabel),
5565
+ ...optionalFlag2("--search", query.text)
5596
5566
  ], LIST_COMMAND);
5597
5567
  return listedIssues(stdout).map(refOfRow);
5598
5568
  },
5599
5569
  openIssues: async (type) => {
5600
5570
  if (!isOneOf(ISSUE_TYPES, type)) {
5601
- throw new TypeError(`${PREFIX2}: openIssues refused type ${describeValue(type)}, expected one of: ${ISSUE_TYPES.join(", ")}`);
5571
+ throw new TypeError(`${PREFIX3}: openIssues refused type ${describeValue(type)}, expected one of: ${ISSUE_TYPES.join(", ")}`);
5602
5572
  }
5603
5573
  const stdout = await run([
5604
5574
  "issue",
@@ -5617,21 +5587,21 @@ function createGithubTracker(options) {
5617
5587
  comment: async (ref, body) => {
5618
5588
  const number = issueNumberOfRef(ref);
5619
5589
  if (typeof body !== "string") {
5620
- throw new TypeError(`${PREFIX2}: refused a comment body ${describeValue(body)}, expected a string`);
5590
+ throw new TypeError(`${PREFIX3}: refused a comment body ${describeValue(body)}, expected a string`);
5621
5591
  }
5622
- await run(["issue", "comment", number, ...optionalFlag("--repo", ref.repo), "--body", body], `gh issue comment ${number}`);
5592
+ await run(["issue", "comment", number, ...optionalFlag2("--repo", ref.repo), "--body", body], `gh issue comment ${number}`);
5623
5593
  },
5624
5594
  transition: async (ref, state) => {
5625
5595
  const number = issueNumberOfRef(ref);
5626
5596
  if (!isOneOf(ISSUE_STATES, state)) {
5627
- throw new TypeError(`${PREFIX2}: refused state ${describeValue(state)}, expected one of: ${ISSUE_STATES.join(", ")}`);
5597
+ throw new TypeError(`${PREFIX3}: refused state ${describeValue(state)}, expected one of: ${ISSUE_STATES.join(", ")}`);
5628
5598
  }
5629
5599
  if (REST_STATES[state] === "closed") {
5630
5600
  const path = `repos/${ref.repo ?? "{owner}/{repo}"}/issues/${number}`;
5631
5601
  const reason = state === "cancelled" ? "not_planned" : "completed";
5632
5602
  await run(["api", path, "-X", "PATCH", "-f", "state=closed", "-f", `state_reason=${reason}`], `gh api PATCH ${path}`);
5633
5603
  } else {
5634
- await run(["issue", "reopen", number, ...optionalFlag("--repo", ref.repo)], `gh issue reopen ${number}`);
5604
+ await run(["issue", "reopen", number, ...optionalFlag2("--repo", ref.repo)], `gh issue reopen ${number}`);
5635
5605
  }
5636
5606
  const readBack = readBackState(state);
5637
5607
  if (readBack === state)
@@ -5639,7 +5609,8 @@ function createGithubTracker(options) {
5639
5609
  return {
5640
5610
  warning: `issue #${number} is now ${REST_STATES[state]}, but GitHub Issues without a board` + ` holds no ${state} state, so get reads it back as ${readBack}`
5641
5611
  };
5642
- }
5612
+ },
5613
+ ...createGithubEditMembers({ run, issueNumberOf: issueNumberOfRef, parseJson, labelNames })
5643
5614
  };
5644
5615
  return Object.freeze(tracker);
5645
5616
  }
@@ -5647,7 +5618,7 @@ function createGithubTracker(options) {
5647
5618
  // src/adapters/tracker/local.ts
5648
5619
  import { mkdir as mkdir3, readdir, readFile as readFile3, writeFile as writeFile2 } from "fs/promises";
5649
5620
  import { join as join16 } from "path";
5650
- var PREFIX3 = "local tracker";
5621
+ var PREFIX4 = "local tracker";
5651
5622
  var FRONTMATTER = /^---\n([\s\S]*?)\n---\n([\s\S]*)$/;
5652
5623
  var ISSUE_NUMBER2 = /^[1-9]\d*$/;
5653
5624
  var CLOSED_STATES = new Set(["done", "released", "cancelled"]);
@@ -5664,6 +5635,12 @@ function oneOf2(members) {
5664
5635
  function orNull(accepts) {
5665
5636
  return (value) => value === null || accepts(value);
5666
5637
  }
5638
+ function orAbsent(accepts) {
5639
+ return (value) => value === undefined || accepts(value);
5640
+ }
5641
+ function isBoolean(value) {
5642
+ return typeof value === "boolean";
5643
+ }
5667
5644
  function listOf(accepts) {
5668
5645
  return (value) => Array.isArray(value) && value.every(accepts);
5669
5646
  }
@@ -5675,6 +5652,7 @@ var FIELD_CHECKS = {
5675
5652
  project: [orNull(isString2), "a string or null"],
5676
5653
  title: [isString2, "a string"],
5677
5654
  blockedBy: [listOf(isFiniteNumber), "a list of numbers"],
5655
+ specBlocked: [orAbsent(isBoolean), "absent or a boolean"],
5678
5656
  state: [oneOf2(ISSUE_STATES), `one of: ${ISSUE_STATES.join(", ")}`],
5679
5657
  fallbackReason: [orNull(isString2), "a string or null"],
5680
5658
  capturedAt: [isString2, "a string"],
@@ -5700,8 +5678,8 @@ function parseIssueNumber(text) {
5700
5678
  const number = Number(text);
5701
5679
  return Number.isSafeInteger(number) ? number : null;
5702
5680
  }
5703
- function issueNumberOfFile(name) {
5704
- return name.endsWith(ISSUE_EXTENSION) ? parseIssueNumber(name.slice(0, -ISSUE_EXTENSION.length)) : null;
5681
+ function issueNumberOfFile(name2) {
5682
+ return name2.endsWith(ISSUE_EXTENSION) ? parseIssueNumber(name2.slice(0, -ISSUE_EXTENSION.length)) : null;
5705
5683
  }
5706
5684
  function issuePath(issuesDir, number) {
5707
5685
  return join16(issuesDir, `${number}${ISSUE_EXTENSION}`);
@@ -5730,6 +5708,7 @@ function renderLocalIssue(record) {
5730
5708
  project: draft.project,
5731
5709
  title: draft.title,
5732
5710
  blockedBy: draft.blockedBy,
5711
+ ...draft.specBlocked === undefined ? {} : { specBlocked: draft.specBlocked },
5733
5712
  state: record.state,
5734
5713
  fallbackReason: record.fallbackReason,
5735
5714
  capturedAt: record.capturedAt,
@@ -5737,7 +5716,7 @@ function renderLocalIssue(record) {
5737
5716
  };
5738
5717
  const problem = frontmatterProblem(frontmatter) ?? (typeof draft.body === "string" ? null : `body is ${describeValue(draft.body)}, expected a string`);
5739
5718
  if (problem !== null) {
5740
- throw new TypeError(`${PREFIX3}: refused to write an invalid issue: ${problem}`);
5719
+ throw new TypeError(`${PREFIX4}: refused to write an invalid issue: ${problem}`);
5741
5720
  }
5742
5721
  return `---
5743
5722
  ${Bun.YAML.stringify(frontmatter, null, 2)}
@@ -5748,18 +5727,18 @@ function parseLocalIssue(contents, sourcePath) {
5748
5727
  const at = sourcePath === undefined ? "" : ` at ${sourcePath}`;
5749
5728
  const match = FRONTMATTER.exec(contents);
5750
5729
  if (match === null) {
5751
- throw new Error(`${PREFIX3}: the issue${at} has no YAML frontmatter block`);
5730
+ throw new Error(`${PREFIX4}: the issue${at} has no YAML frontmatter block`);
5752
5731
  }
5753
5732
  const [, block = "", body = ""] = match;
5754
5733
  let meta;
5755
5734
  try {
5756
5735
  meta = Bun.YAML.parse(block);
5757
5736
  } catch (error) {
5758
- throw new Error(`${PREFIX3}: invalid issue${at}: ${messageOf(error)}`, { cause: error });
5737
+ throw new Error(`${PREFIX4}: invalid issue${at}: ${messageOf(error)}`, { cause: error });
5759
5738
  }
5760
5739
  const problem = frontmatterProblem(meta);
5761
5740
  if (problem !== null) {
5762
- throw new Error(`${PREFIX3}: invalid issue${at}: ${problem}`);
5741
+ throw new Error(`${PREFIX4}: invalid issue${at}: ${problem}`);
5763
5742
  }
5764
5743
  const fields = meta;
5765
5744
  return {
@@ -5771,7 +5750,8 @@ function parseLocalIssue(contents, sourcePath) {
5771
5750
  module: fields.module,
5772
5751
  priority: fields.priority,
5773
5752
  project: fields.project,
5774
- blockedBy: fields.blockedBy
5753
+ blockedBy: fields.blockedBy,
5754
+ ...fields.specBlocked === undefined ? {} : { specBlocked: fields.specBlocked }
5775
5755
  },
5776
5756
  fallbackReason: fields.fallbackReason,
5777
5757
  capturedAt: fields.capturedAt,
@@ -5790,7 +5770,7 @@ async function listLocalIssues(issuesDir, warn = warnThroughActiveOutput2, reade
5790
5770
  try {
5791
5771
  contents = await readFile3(path, "utf8");
5792
5772
  } catch (error) {
5793
- throw new Error(`${PREFIX3}: could not read ${path}: ${messageOf(error)}`, { cause: error });
5773
+ throw new Error(`${PREFIX4}: could not read ${path}: ${messageOf(error)}`, { cause: error });
5794
5774
  }
5795
5775
  return { number, path, record: parseLocalIssue(contents, path) };
5796
5776
  }));
@@ -5819,11 +5799,11 @@ function refFor(number, opt) {
5819
5799
  }
5820
5800
  function issueNumberOfRef2(ref) {
5821
5801
  if (ref.kind !== "local") {
5822
- throw new Error(`${PREFIX3}: refused a ref of kind ${describeValue(ref.kind)}; this tracker reads local refs only`);
5802
+ throw new Error(`${PREFIX4}: refused a ref of kind ${describeValue(ref.kind)}; this tracker reads local refs only`);
5823
5803
  }
5824
5804
  const number = typeof ref.externalId === "string" ? parseIssueNumber(ref.externalId) : null;
5825
5805
  if (number === null) {
5826
- throw new Error(`${PREFIX3}: externalId ${describeValue(ref.externalId)} is not a local issue number,` + " expected a positive whole number with no leading zero");
5806
+ throw new Error(`${PREFIX4}: externalId ${describeValue(ref.externalId)} is not a local issue number,` + " expected a positive whole number with no leading zero");
5827
5807
  }
5828
5808
  return number;
5829
5809
  }
@@ -5838,7 +5818,7 @@ function createLocalTracker(options) {
5838
5818
  try {
5839
5819
  contents = await readFile3(path, "utf8");
5840
5820
  } catch (cause) {
5841
- throw new Error(`${PREFIX3}: no issue ${number} under ${issuesDir}`, { cause });
5821
+ throw new Error(`${PREFIX4}: no issue ${number} under ${issuesDir}`, { cause });
5842
5822
  }
5843
5823
  return { number, record: parseLocalIssue(contents, path) };
5844
5824
  }
@@ -5873,7 +5853,7 @@ function createLocalTracker(options) {
5873
5853
  throw error;
5874
5854
  }
5875
5855
  }
5876
- throw new Error(`${PREFIX3}: no issue number is left under ${issuesDir}`);
5856
+ throw new Error(`${PREFIX4}: no issue number is left under ${issuesDir}`);
5877
5857
  },
5878
5858
  get: async (ref) => {
5879
5859
  const { record } = await read(ref);
@@ -5899,6 +5879,29 @@ function createLocalTracker(options) {
5899
5879
  const { number, record } = await read(ref);
5900
5880
  await rewrite(number, { ...record, state });
5901
5881
  return {};
5882
+ },
5883
+ editable: async (ref) => {
5884
+ const { number, record } = await read(ref);
5885
+ return {
5886
+ ref: refFor(number, record.draft.opt),
5887
+ title: record.draft.title,
5888
+ body: record.draft.body,
5889
+ open: !CLOSED_STATES.has(record.state),
5890
+ labels: [],
5891
+ author: ""
5892
+ };
5893
+ },
5894
+ edit: async (ref, change) => {
5895
+ if (change.body === undefined && change.title === undefined) {
5896
+ throw new TypeError(`${PREFIX4}: refused an edit naming neither a body nor a title`);
5897
+ }
5898
+ const { number, record } = await read(ref);
5899
+ const draft = {
5900
+ ...record.draft,
5901
+ ...change.body === undefined ? {} : { body: change.body },
5902
+ ...change.title === undefined ? {} : { title: change.title }
5903
+ };
5904
+ await rewrite(number, { ...record, draft });
5902
5905
  }
5903
5906
  };
5904
5907
  return Object.freeze(tracker);
@@ -5906,7 +5909,7 @@ function createLocalTracker(options) {
5906
5909
 
5907
5910
  // src/adapters/registry.ts
5908
5911
  var REFUSAL3 = "adapter registry";
5909
- var PORT_VERSIONS2 = Object.freeze({
5912
+ var PORT_VERSIONS = Object.freeze({
5910
5913
  tracker: 1,
5911
5914
  store: 1,
5912
5915
  learning: 1,
@@ -5914,7 +5917,7 @@ var PORT_VERSIONS2 = Object.freeze({
5914
5917
  planner: 1,
5915
5918
  sync: 1
5916
5919
  });
5917
- var SERVED_VERSIONS = new Map(Object.entries(PORT_VERSIONS2));
5920
+ var SERVED_VERSIONS = new Map(Object.entries(PORT_VERSIONS));
5918
5921
  var PORT_TYPE_LIST = [...SERVED_VERSIONS.keys()].join(", ");
5919
5922
  function checkPortType(port) {
5920
5923
  if (!SERVED_VERSIONS.has(port)) {
@@ -5954,11 +5957,11 @@ function indexByPort(adapters) {
5954
5957
  sync: only("sync")
5955
5958
  };
5956
5959
  }
5957
- function createAdapterRegistry2(adapters = []) {
5960
+ function createAdapterRegistry(adapters = []) {
5958
5961
  const held = adapters.reduce((accepted, adapter) => [...accepted, accept(adapter, accepted)], []);
5959
5962
  const byPort = indexByPort(held);
5960
5963
  const registry = {
5961
- register: (adapter) => createAdapterRegistry2([...held, adapter]),
5964
+ register: (adapter) => createAdapterRegistry([...held, adapter]),
5962
5965
  find: (port, kind) => SERVED_VERSIONS.has(port) ? byPort[port].get(kind) : undefined,
5963
5966
  resolve: (port, kind) => {
5964
5967
  checkPortType(port);
@@ -5966,8 +5969,8 @@ function createAdapterRegistry2(adapters = []) {
5966
5969
  if (adapter !== undefined)
5967
5970
  return adapter;
5968
5971
  const registered = [...byPort[port].keys()];
5969
- const listed = registered.length === 0 ? "none" : registered.join(", ");
5970
- throw new Error(`${REFUSAL3}: no ${port} adapter is registered as ${describeValue(kind)};` + ` registered: ${listed}`);
5972
+ const listed2 = registered.length === 0 ? "none" : registered.join(", ");
5973
+ throw new Error(`${REFUSAL3}: no ${port} adapter is registered as ${describeValue(kind)};` + ` registered: ${listed2}`);
5971
5974
  },
5972
5975
  kinds: (port) => {
5973
5976
  checkPortType(port);
@@ -5977,38 +5980,38 @@ function createAdapterRegistry2(adapters = []) {
5977
5980
  return Object.freeze(registry);
5978
5981
  }
5979
5982
  var STORE_OPENERS = {
5980
- sqlite: openSqliteStore2,
5981
- ndjson: openNdjsonStore2
5983
+ sqlite: openSqliteStore,
5984
+ ndjson: openNdjsonStore
5982
5985
  };
5983
5986
  var CORE_ADAPTERS = [
5984
- ...STORE_BACKENDS2.map((backend) => ({
5987
+ ...STORE_BACKENDS.map((backend) => ({
5985
5988
  port: "store",
5986
5989
  kind: backend,
5987
- portVersion: PORT_VERSIONS2.store,
5990
+ portVersion: PORT_VERSIONS.store,
5988
5991
  create: ({ repoRoot }) => STORE_OPENERS[backend](repoRoot)
5989
5992
  })),
5990
5993
  {
5991
5994
  port: "output",
5992
5995
  kind: "text",
5993
- portVersion: PORT_VERSIONS2.output,
5996
+ portVersion: PORT_VERSIONS.output,
5994
5997
  create: ({ stream = process.stdout, verbosity = 0 }) => createTextOutput({ verbosity, stream })
5995
5998
  },
5996
5999
  {
5997
6000
  port: "output",
5998
6001
  kind: "json",
5999
- portVersion: PORT_VERSIONS2.output,
6002
+ portVersion: PORT_VERSIONS.output,
6000
6003
  create: ({ stream = process.stdout }) => createJsonOutput({ stream })
6001
6004
  },
6002
6005
  {
6003
6006
  port: "output",
6004
6007
  kind: "events",
6005
- portVersion: PORT_VERSIONS2.output,
6008
+ portVersion: PORT_VERSIONS.output,
6006
6009
  create: ({ stream = process.stdout }) => createEventsOutput({ stream })
6007
6010
  },
6008
6011
  {
6009
6012
  port: "tracker",
6010
6013
  kind: "local",
6011
- portVersion: PORT_VERSIONS2.tracker,
6014
+ portVersion: PORT_VERSIONS.tracker,
6012
6015
  create: ({ repoRoot, fallbackReason = null }) => createLocalTracker({
6013
6016
  issuesDir: localIssuesDir(repoRoot),
6014
6017
  fallbackReason
@@ -6017,17 +6020,17 @@ var CORE_ADAPTERS = [
6017
6020
  {
6018
6021
  port: "tracker",
6019
6022
  kind: "github",
6020
- portVersion: PORT_VERSIONS2.tracker,
6023
+ portVersion: PORT_VERSIONS.tracker,
6021
6024
  create: ({ repoRoot, gh }) => createGithubTracker({ gh: gh ?? createGhRunner({ cwd: repoRoot }) })
6022
6025
  },
6023
6026
  {
6024
6027
  port: "learning",
6025
6028
  kind: "local",
6026
- portVersion: PORT_VERSIONS2.learning,
6029
+ portVersion: PORT_VERSIONS.learning,
6027
6030
  create: ({
6028
6031
  repoRoot,
6029
6032
  home = homedir(),
6030
- learningBlessMinConfidence = CONFIG_DEFAULTS2.learningBlessMinConfidence
6033
+ learningBlessMinConfidence = CONFIG_DEFAULTS.learningBlessMinConfidence
6031
6034
  }) => createLocalLearning({
6032
6035
  instinctsDir: localInstinctsDir(repoRoot),
6033
6036
  home,
@@ -6037,7 +6040,7 @@ var CORE_ADAPTERS = [
6037
6040
  {
6038
6041
  port: "planner",
6039
6042
  kind: "claude",
6040
- portVersion: PORT_VERSIONS2.planner,
6043
+ portVersion: PORT_VERSIONS.planner,
6041
6044
  create: ({ repoRoot, settingSources, planPrompt, planDir, claude }) => {
6042
6045
  if (!Array.isArray(settingSources)) {
6043
6046
  throw new TypeError(`${REFUSAL3}: planner/claude has settingSources ${describeValue(settingSources)} in its context,` + " expected a list of setting sources");
@@ -6054,26 +6057,26 @@ var CORE_ADAPTERS = [
6054
6057
  {
6055
6058
  port: "sync",
6056
6059
  kind: "local",
6057
- portVersion: PORT_VERSIONS2.sync,
6060
+ portVersion: PORT_VERSIONS.sync,
6058
6061
  create: () => createLocalSync()
6059
6062
  },
6060
6063
  {
6061
6064
  port: "sync",
6062
6065
  kind: "file",
6063
- portVersion: PORT_VERSIONS2.sync,
6066
+ portVersion: PORT_VERSIONS.sync,
6064
6067
  create: ({ repoRoot, store }) => {
6065
- if (!STORE_BACKENDS2.includes(store)) {
6066
- throw new TypeError(`${REFUSAL3}: sync/file has store ${describeValue(store)} in its context,` + ` expected one of: ${STORE_BACKENDS2.join(", ")}`);
6068
+ if (!STORE_BACKENDS.includes(store)) {
6069
+ throw new TypeError(`${REFUSAL3}: sync/file has store ${describeValue(store)} in its context,` + ` expected one of: ${STORE_BACKENDS.join(", ")}`);
6067
6070
  }
6068
6071
  return createFileSync({ repoRoot, backend: store });
6069
6072
  }
6070
6073
  }
6071
6074
  ];
6072
- var CORE_ADAPTER_REGISTRY2 = createAdapterRegistry2(CORE_ADAPTERS);
6075
+ var CORE_ADAPTER_REGISTRY = createAdapterRegistry(CORE_ADAPTERS);
6073
6076
 
6074
6077
  // src/board/trust.ts
6075
6078
  var REPO_PATH = "{owner}/{repo}";
6076
- var TRUSTED_PERMISSIONS2 = ["admin", "maintain", "write"];
6079
+ var TRUSTED_PERMISSIONS = ["admin", "maintain", "write"];
6077
6080
  var TRUST_REFUSAL_EXIT = 2;
6078
6081
  var REMEDY = Object.freeze({
6079
6082
  issue: "a member must open the spec",
@@ -6085,7 +6088,7 @@ function failureDetail(reading) {
6085
6088
  return detail === "" ? UNREPORTED : detail;
6086
6089
  }
6087
6090
  function isTrustedPermission(value) {
6088
- return TRUSTED_PERMISSIONS2.some((permission) => permission === value);
6091
+ return TRUSTED_PERMISSIONS.some((permission) => permission === value);
6089
6092
  }
6090
6093
  function stringOrNull(value) {
6091
6094
  return typeof value === "string" ? value : null;
@@ -6135,8 +6138,8 @@ async function readAuthorTrust(options) {
6135
6138
  };
6136
6139
  }
6137
6140
  const wanted = login.toLowerCase();
6138
- const listed = trustedAuthors.some((author) => author.toLowerCase() === wanted);
6139
- if (listed) {
6141
+ const listed2 = trustedAuthors.some((author) => author.toLowerCase() === wanted);
6142
+ if (listed2) {
6140
6143
  return { login, trusted: true, source: "allow-list", refusal: null, permission: null };
6141
6144
  }
6142
6145
  const permission = await permissions(login);
@@ -6187,19 +6190,73 @@ function requireTrustedAuthor(item, reading) {
6187
6190
  return;
6188
6191
  throw new CommandExit(TRUST_REFUSAL_EXIT, trustRefusalMessage(item, reading));
6189
6192
  }
6193
+ var USER_COMMAND = "gh api user";
6194
+ function noLogin(detail) {
6195
+ return { login: null, detail };
6196
+ }
6197
+ function createGhEditorLogin(options) {
6198
+ const { gh } = options;
6199
+ return async () => {
6200
+ const result = await gh(["api", "user"]);
6201
+ if (!result.ok)
6202
+ return noLogin(detailOf2(result, USER_COMMAND));
6203
+ let payload;
6204
+ try {
6205
+ payload = JSON.parse(result.stdout);
6206
+ } catch (error) {
6207
+ return noLogin(`${USER_COMMAND} wrote output that is not JSON: ${messageOf(error)}`);
6208
+ }
6209
+ if (!isMapping(payload)) {
6210
+ return noLogin(`${USER_COMMAND} answered ${describeValue(payload)}, expected a mapping`);
6211
+ }
6212
+ const login = payload["login"];
6213
+ return typeof login === "string" && isGitHubLogin(login) ? { login, detail: "" } : noLogin(`${USER_COMMAND} answered ${describeValue(login)} as its login, which is not a GitHub login`);
6214
+ };
6215
+ }
6216
+ async function readEditorTrust(trust, editor) {
6217
+ const read = await editor();
6218
+ if (read.login === null) {
6219
+ return { login: null, trusted: false, refusal: "ownership-unknown", reading: null, detail: read.detail };
6220
+ }
6221
+ const reading = await readBoardTrust(trust, read.login);
6222
+ return {
6223
+ login: read.login,
6224
+ trusted: reading.trusted,
6225
+ refusal: editorRefusalOf(reading),
6226
+ reading,
6227
+ detail: ""
6228
+ };
6229
+ }
6230
+ function editorRefusalOf(reading) {
6231
+ if (reading.trusted)
6232
+ return null;
6233
+ return reading.refusal === "lookup-failed" ? "ownership-unknown" : "ownership";
6234
+ }
6235
+ function editorRefusalMessage(item, reading) {
6236
+ const what = `${item.kind} #${String(item.number)}`;
6237
+ if (reading.reading !== null) {
6238
+ const because = trustRefusalClause(item.repo, reading.reading);
6239
+ return `${what} cannot be edited by ${reading.reading.login}, ${because}; a member must make the edit`;
6240
+ }
6241
+ if (reading.trusted) {
6242
+ throw new TypeError("board trust: a trusted editor has no refusal to name");
6243
+ }
6244
+ const detail = reading.detail === "" ? UNREPORTED : reading.detail;
6245
+ return `${what} cannot be edited: the account running the edit could not be read (${detail}); ` + "log gh in with `gh auth login` and run it again";
6246
+ }
6190
6247
  // src/effort/sync/wire.ts
6191
6248
  import { existsSync as existsSync14, mkdtempSync as mkdtempSync2, rmSync as rmSync8 } from "fs";
6192
6249
  import { tmpdir as tmpdir4 } from "os";
6193
6250
  import { join as join17 } from "path";
6194
6251
  import { Database as Database7, SQLiteError as SQLiteError3 } from "bun:sqlite";
6195
- var WIRE_FORMAT2 = "rafa-effort-wire";
6196
- var WIRE_VERSION2 = 1;
6252
+ var WIRE_FORMAT = "rafa-effort-wire";
6253
+ var WIRE_VERSION = 1;
6197
6254
 
6198
- class WireFormatError2 extends Error {
6255
+ class WireFormatError extends Error {
6199
6256
  name = "WireFormatError";
6200
6257
  }
6201
6258
 
6202
- class WireExportRefusal2 extends Error {
6259
+ class WireExportRefusal extends Error {
6203
6260
  name = "WireExportRefusal";
6204
6261
  }
6205
6262
  var MERGED_TABLES = Object.entries(MERGE_RULES).filter(([, rule]) => rule.scope === "merged").map(([table]) => table);
@@ -6210,17 +6267,17 @@ function isRecord4(value) {
6210
6267
  function isCount(value) {
6211
6268
  return typeof value === "number" && Number.isSafeInteger(value) && value >= 0;
6212
6269
  }
6213
- function isMergedTable(name) {
6214
- return MERGED_TABLES.includes(name);
6270
+ function isMergedTable(name2) {
6271
+ return MERGED_TABLES.includes(name2);
6215
6272
  }
6216
6273
  function checkCursor(value) {
6217
6274
  if (!isRecord4(value))
6218
- throw new WireFormatError2("wire: cursor is not an object");
6275
+ throw new WireFormatError("wire: cursor is not an object");
6219
6276
  const entries = Object.entries(value).map(([table, seq]) => {
6220
6277
  if (!isMergedTable(table))
6221
- throw new WireFormatError2(`wire: cursor names ${JSON.stringify(table)}, which is no merged table`);
6278
+ throw new WireFormatError(`wire: cursor names ${JSON.stringify(table)}, which is no merged table`);
6222
6279
  if (!isCount(seq))
6223
- throw new WireFormatError2(`wire: cursor for ${table} is ${JSON.stringify(seq)}, expected a whole number of 0 or more`);
6280
+ throw new WireFormatError(`wire: cursor for ${table} is ${JSON.stringify(seq)}, expected a whole number of 0 or more`);
6224
6281
  return [table, seq];
6225
6282
  });
6226
6283
  return Object.freeze(Object.fromEntries(entries));
@@ -6228,67 +6285,67 @@ function checkCursor(value) {
6228
6285
  function checkRow(table, value, index) {
6229
6286
  const where = `wire: ${table} row ${String(index)}`;
6230
6287
  if (!isRecord4(value))
6231
- throw new WireFormatError2(`${where} is not an object`);
6288
+ throw new WireFormatError(`${where} is not an object`);
6232
6289
  for (const [column, cell] of Object.entries(value)) {
6233
6290
  const carried = cell === null || typeof cell === "string" || typeof cell === "number" && Number.isFinite(cell);
6234
6291
  if (!carried)
6235
- throw new WireFormatError2(`${where} holds ${JSON.stringify(cell) ?? typeof cell} in ${column}, expected a string, a number or null`);
6292
+ throw new WireFormatError(`${where} holds ${JSON.stringify(cell) ?? typeof cell} in ${column}, expected a string, a number or null`);
6236
6293
  }
6237
6294
  const seq = value.seq;
6238
6295
  if (!isCount(seq) || seq === 0)
6239
- throw new WireFormatError2(`${where} has seq ${JSON.stringify(seq) ?? "undefined"}, expected a whole number above 0`);
6296
+ throw new WireFormatError(`${where} has seq ${JSON.stringify(seq) ?? "undefined"}, expected a whole number above 0`);
6240
6297
  return Object.freeze({ ...value });
6241
6298
  }
6242
6299
  function checkMigrations(value) {
6243
6300
  if (!Array.isArray(value))
6244
- throw new WireFormatError2("wire: migrations is not a list");
6301
+ throw new WireFormatError("wire: migrations is not a list");
6245
6302
  const ids = value.map((id) => {
6246
6303
  if (typeof id !== "string" || id === "")
6247
- throw new WireFormatError2(`wire: migration id ${JSON.stringify(id)} is not a name`);
6304
+ throw new WireFormatError(`wire: migration id ${JSON.stringify(id)} is not a name`);
6248
6305
  return id;
6249
6306
  });
6250
6307
  const twice = ids.filter((id, index) => ids.indexOf(id) !== index);
6251
6308
  if (twice.length > 0)
6252
- throw new WireFormatError2(`wire: migrations name ${twice.join(", ")} more than once`);
6309
+ throw new WireFormatError(`wire: migrations name ${twice.join(", ")} more than once`);
6253
6310
  return Object.freeze(ids);
6254
6311
  }
6255
6312
  function checkTables(value) {
6256
6313
  if (!isRecord4(value))
6257
- throw new WireFormatError2("wire: tables is not an object");
6314
+ throw new WireFormatError("wire: tables is not an object");
6258
6315
  const entries = Object.entries(value).map(([table, rows]) => {
6259
6316
  if (!isMergedTable(table))
6260
- throw new WireFormatError2(`wire: tables names ${JSON.stringify(table)}, which is no merged table`);
6317
+ throw new WireFormatError(`wire: tables names ${JSON.stringify(table)}, which is no merged table`);
6261
6318
  if (!Array.isArray(rows))
6262
- throw new WireFormatError2(`wire: tables.${table} is not a list`);
6319
+ throw new WireFormatError(`wire: tables.${table} is not a list`);
6263
6320
  return [table, Object.freeze(rows.map((row, index) => checkRow(table, row, index)))];
6264
6321
  });
6265
6322
  return Object.freeze(Object.fromEntries(entries));
6266
6323
  }
6267
6324
  function checkPayload(value) {
6268
6325
  if (!isRecord4(value))
6269
- throw new WireFormatError2("wire: the payload is not an object");
6270
- if (value.format !== WIRE_FORMAT2)
6271
- throw new WireFormatError2(`wire: format is ${JSON.stringify(value.format) ?? "undefined"}, expected ${JSON.stringify(WIRE_FORMAT2)}`);
6272
- if (value.version !== WIRE_VERSION2)
6273
- throw new WireFormatError2(`wire: version is ${JSON.stringify(value.version) ?? "undefined"}; this rafa reads version ${String(WIRE_VERSION2)}`);
6326
+ throw new WireFormatError("wire: the payload is not an object");
6327
+ if (value.format !== WIRE_FORMAT)
6328
+ throw new WireFormatError(`wire: format is ${JSON.stringify(value.format) ?? "undefined"}, expected ${JSON.stringify(WIRE_FORMAT)}`);
6329
+ if (value.version !== WIRE_VERSION)
6330
+ throw new WireFormatError(`wire: version is ${JSON.stringify(value.version) ?? "undefined"}; this rafa reads version ${String(WIRE_VERSION)}`);
6274
6331
  return Object.freeze({
6275
- format: WIRE_FORMAT2,
6276
- version: WIRE_VERSION2,
6332
+ format: WIRE_FORMAT,
6333
+ version: WIRE_VERSION,
6277
6334
  migrations: checkMigrations(value.migrations),
6278
6335
  tables: checkTables(value.tables),
6279
6336
  cursor: checkCursor(value.cursor)
6280
6337
  });
6281
6338
  }
6282
- function encodeWirePayload2(payload) {
6339
+ function encodeWirePayload(payload) {
6283
6340
  return JSON.stringify(payload);
6284
6341
  }
6285
- function decodeWirePayload2(text) {
6342
+ function decodeWirePayload(text) {
6286
6343
  let parsed;
6287
6344
  try {
6288
6345
  parsed = JSON.parse(text);
6289
6346
  } catch (error) {
6290
6347
  const reason = error instanceof Error ? error.message : String(error);
6291
- throw new WireFormatError2(`wire: the payload is not JSON (${reason})`);
6348
+ throw new WireFormatError(`wire: the payload is not JSON (${reason})`);
6292
6349
  }
6293
6350
  return checkPayload(parsed);
6294
6351
  }
@@ -6299,17 +6356,17 @@ function readLoggedIds(db) {
6299
6356
  return db.query(`SELECT id FROM ${MIGRATION_LOG_TABLE} ORDER BY seq`).all().map(({ id }) => id);
6300
6357
  }
6301
6358
  function columnsOf(db, table) {
6302
- return db.query(`PRAGMA table_info(${quoted(table)})`).all().map(({ name }) => name);
6359
+ return db.query(`PRAGMA table_info(${quoted(table)})`).all().map(({ name: name2 }) => name2);
6303
6360
  }
6304
6361
  function wireValue(value, where) {
6305
6362
  if (typeof value === "bigint") {
6306
6363
  const number = Number(value);
6307
6364
  if (Number.isSafeInteger(number))
6308
6365
  return number;
6309
- throw new WireExportRefusal2(`wire: ${where} holds ${String(value)}, past the whole numbers JSON carries exactly`);
6366
+ throw new WireExportRefusal(`wire: ${where} holds ${String(value)}, past the whole numbers JSON carries exactly`);
6310
6367
  }
6311
6368
  if (value instanceof Uint8Array)
6312
- throw new WireExportRefusal2(`wire: ${where} holds a BLOB, which the wire does not carry`);
6369
+ throw new WireExportRefusal(`wire: ${where} holds a BLOB, which the wire does not carry`);
6313
6370
  return value;
6314
6371
  }
6315
6372
  function readRows(db, table, columns, after, path) {
@@ -6322,7 +6379,7 @@ function readRows(db, table, columns, after, path) {
6322
6379
  function readPayload(db, path, cursor) {
6323
6380
  const migrations = readLoggedIds(db);
6324
6381
  if (migrations === null) {
6325
- throw new WireExportRefusal2(`wire: ${path} has no migration log; any rafa command that writes the store brings it forward`);
6382
+ throw new WireExportRefusal(`wire: ${path} has no migration log; any rafa command that writes the store brings it forward`);
6326
6383
  }
6327
6384
  const tables = {};
6328
6385
  const next = { ...cursor };
@@ -6332,7 +6389,7 @@ function readPayload(db, path, cursor) {
6332
6389
  continue;
6333
6390
  const missing = ORIGIN_COLUMNS.filter((column) => !columns.includes(column));
6334
6391
  if (missing.length > 0) {
6335
- throw new WireExportRefusal2(`wire: ${path} holds no ${missing.map((column) => `${table}.${column}`).join(", ")}, so its rows carry no origin pair`);
6392
+ throw new WireExportRefusal(`wire: ${path} holds no ${missing.map((column) => `${table}.${column}`).join(", ")}, so its rows carry no origin pair`);
6336
6393
  }
6337
6394
  const rows = readRows(db, table, columns, cursor[table] ?? 0, path);
6338
6395
  tables[table] = Object.freeze(rows);
@@ -6340,19 +6397,19 @@ function readPayload(db, path, cursor) {
6340
6397
  next[table] = last === undefined ? cursor[table] ?? 0 : Number(last.seq);
6341
6398
  }
6342
6399
  return Object.freeze({
6343
- format: WIRE_FORMAT2,
6344
- version: WIRE_VERSION2,
6400
+ format: WIRE_FORMAT,
6401
+ version: WIRE_VERSION,
6345
6402
  migrations: Object.freeze([...migrations]),
6346
6403
  tables: Object.freeze(tables),
6347
6404
  cursor: Object.freeze(next)
6348
6405
  });
6349
6406
  }
6350
- function exportWirePayload2(options) {
6407
+ function exportWirePayload(options) {
6351
6408
  const { path } = options;
6352
6409
  const cursor = checkCursor(options.cursor ?? {});
6353
6410
  guardTestProcess(path);
6354
6411
  if (!existsSync14(path))
6355
- throw new WireExportRefusal2(`wire: ${path} is not there`);
6412
+ throw new WireExportRefusal(`wire: ${path} is not there`);
6356
6413
  const db = new Database7(path, { readonly: true, safeIntegers: true });
6357
6414
  try {
6358
6415
  db.run(`PRAGMA busy_timeout = ${String(activeStoreSettings().busyTimeoutMs)}`);
@@ -6365,28 +6422,28 @@ function namedMigrations(ids, catalogue) {
6365
6422
  const known = new Set(catalogue.map(({ id }) => id));
6366
6423
  const unknown = ids.filter((id) => !known.has(id));
6367
6424
  if (unknown.length > 0) {
6368
- throw new WireFormatError2(`wire: the payload's store holds migration ${unknown.join(", ")}, which this rafa does not know; update rafa to take its rows`);
6425
+ throw new WireFormatError(`wire: the payload's store holds migration ${unknown.join(", ")}, which this rafa does not know; update rafa to take its rows`);
6369
6426
  }
6370
6427
  return catalogue.filter(({ id }) => ids.includes(id));
6371
6428
  }
6372
6429
  function insertRows(db, table, rows) {
6373
6430
  const columns = columnsOf(db, table);
6374
6431
  if (columns.length === 0)
6375
- throw new WireFormatError2(`wire: the payload carries ${table}, which its migrations do not make`);
6432
+ throw new WireFormatError(`wire: the payload carries ${table}, which its migrations do not make`);
6376
6433
  const statement = db.query(`INSERT INTO ${quoted(table)} (${columns.map(quoted).join(", ")}) VALUES (${columns.map(() => "?").join(", ")})`);
6377
6434
  const expected = [...columns].sort().join(",");
6378
6435
  rows.forEach((row, index) => {
6379
6436
  const where = `wire: ${table} row ${String(index)}`;
6380
6437
  const held = Object.keys(row);
6381
6438
  if ([...held].sort().join(",") !== expected) {
6382
- throw new WireFormatError2(`${where} holds columns ${held.join(", ")}; its migrations make ${columns.join(", ")}`);
6439
+ throw new WireFormatError(`${where} holds columns ${held.join(", ")}; its migrations make ${columns.join(", ")}`);
6383
6440
  }
6384
6441
  try {
6385
6442
  statement.run(...columns.map((column) => row[column] ?? null));
6386
6443
  } catch (error) {
6387
6444
  if (!(error instanceof SQLiteError3))
6388
6445
  throw error;
6389
- throw new WireFormatError2(`${where} (seq ${String(row.seq)}) is refused by the table: ${error.message}`);
6446
+ throw new WireFormatError(`${where} (seq ${String(row.seq)}) is refused by the table: ${error.message}`);
6390
6447
  }
6391
6448
  });
6392
6449
  }
@@ -6408,7 +6465,7 @@ function buildStore(path, payload, options) {
6408
6465
  db.close();
6409
6466
  }
6410
6467
  }
6411
- function materialiseWirePayload2(payload, options = {}) {
6468
+ function materialiseWirePayload(payload, options = {}) {
6412
6469
  const checked = checkPayload(payload);
6413
6470
  const directory = mkdtempSync2(join17(options.tempDir ?? tmpdir4(), "rafa-wire-"));
6414
6471
  const release = () => rmSync8(directory, { recursive: true, force: true });
@@ -6431,13 +6488,13 @@ function describeValue4(value) {
6431
6488
  return "an object";
6432
6489
  return String(value);
6433
6490
  }
6434
- function selectEffortStore2(repoRoot, config) {
6435
- const adapter = CORE_ADAPTER_REGISTRY2.find("store", config.store);
6491
+ function selectEffortStore(repoRoot, config) {
6492
+ const adapter = CORE_ADAPTER_REGISTRY.find("store", config.store);
6436
6493
  if (adapter === undefined) {
6437
- const expected = CORE_ADAPTER_REGISTRY2.kinds("store").join(", ");
6494
+ const expected = CORE_ADAPTER_REGISTRY.kinds("store").join(", ");
6438
6495
  throw new TypeError(`effort store: store is ${describeValue4(config.store)},` + ` expected one of: ${expected}`);
6439
6496
  }
6440
6497
  return adapter.create({ repoRoot });
6441
6498
  }
6442
6499
 
6443
- export { EFFORT_STORE_DIR, effortStoreFileName, EFFORT_DIR_VARIABLE, effortStoreDir, guardTestProcess, EFFORT_KEY_PROJECTIONS2, openNdjsonStore2, name, version, RAFA_VERSION, versionLine, createGitRunner, gitSaid, NOT_A_REPOSITORY, mainCheckoutOf, SCOPE_DIR2, INIT_COMMAND2, DISK_FILE_SYSTEM2, ScopeError2, scopeAt2, initHint2, selfAndAncestors2, resolveScope2, POSITION_FILE, positionFilePath, readPositionFile, writePositionFile, positionAt, rehome, hop, goHome, HOP_FILE, hopFilePath, readHopRecord, writeHopRecord, staleAgainst, SessionRecordError, isSessionId, sessionPhase, SessionConflictError, SessionStateError, runsDir, sessionFilePath, errorCode, isPidAlive, readSessions, readSession, beginSession, updateSession, DEVELOPMENT_NEXT_STEP, DEVELOPMENT_MARK, DevelopmentBuildRefusedError, refuseUnownedDevelopmentWrite, LEGACY_GATE_OPEN, LEGACY_GATE_CLOSED, SQLITE_MIGRATIONS, sqliteCatalogue, planSchema, SchemaRefusedError, readStoreSchema, writeNames, ACROSS_STORES_ORDER, STAMPED_COLUMNS, stampedValues, activeStoreSettings, normalizeRemote, gitRemoteUrl, readStoreMeta, SQLITE_STORE_FILE_NAME, sqliteStorePath, LONE_SURROGATE, withSqliteStore, writeSqliteStore, openSqliteStore2, SPENDS_GLYPH, CommandExit, isRoutingWord, commandProblem, isTopLevel, commandSpelling, EffortCopyRefusal, EffortCopyFailure, copyEffortStore, RebuildRefusal, readConfigFile2, loadConfig2, plansDirAt, requireProject, resolvePlansDir, resolveProjectConfig, countTasks, formatCounts, checkbox, planFileName, stubOfPlanFile, isFile, issueLine, plural, expectNoArgument, expectOneArgument, expectAtMostOneArgument, readSwitch, fileStamp, keepsIdLine, fix_schema_default, minutesBetween, readCommitLog, UnionSchemaMismatch, migrateStore, MOVE_TO_SQLITE, MergeRefusal, mergeStore2, createFileSync, SyncModuleMissing, selectSync, SKILL_FILE2, MARKDOWN_EXTENSION, scanLayout, declaredNameIssue, readFrontmatterDocument, readFrontmatter, renderFrontmatter, mergeFrontmatter, writeFrontmatter, ACTION_HEADING, CAUSE_HEADING, parseInstinct, writeInstinct, readScopes, allRecords, findRecords, instinctProject, toHeldRecords, padKind, oneLine, sessionSpawnEnv, CLAUDE_BIN, claudeArgs, interruptClaudeSessions, spawnClaude, runClaude, spawnClaudeCaptured, runClaudeCaptured, planFilePath, ClaudePlannerError, ISSUE_TYPES, ISSUE_PRIORITIES, ISSUE_STATES, GITHUB_LABELS, createGhRunner, typeOfLabels, moduleOfLabels, createLocalTracker, PORT_VERSIONS2, createAdapterRegistry2, CORE_ADAPTER_REGISTRY2, TRUSTED_PERMISSIONS2, createGhPermissions, readAuthorTrust, ghBoardTrust, readBoardTrust, requireTrustedBoardAuthor, trustRefusalClause, requireTrustedAuthor, WIRE_FORMAT2, WIRE_VERSION2, WireFormatError2, WireExportRefusal2, encodeWirePayload2, decodeWirePayload2, exportWirePayload2, materialiseWirePayload2, selectEffortStore2 };
6500
+ export { EFFORT_STORE_DIR, effortStoreFileName, EFFORT_DIR_VARIABLE, effortStoreDir, guardTestProcess, EFFORT_KEY_PROJECTIONS, openNdjsonStore, name, version, RAFA_VERSION, versionLine, createGitRunner, gitSaid, NOT_A_REPOSITORY, mainCheckoutOf, SCOPE_DIR, INIT_COMMAND, DISK_FILE_SYSTEM, ScopeError, scopeAt, initHint, selfAndAncestors, resolveScope, POSITION_FILE, positionFilePath, readPositionFile, writePositionFile, positionAt, rehome, hop, goHome, HOP_FILE, hopFilePath, readHopRecord, writeHopRecord, staleAgainst, SessionRecordError, isSessionId, sessionPhase, SessionConflictError, SessionStateError, runsDir, sessionFilePath, errorCode, isPidAlive, readSessions, readSession, beginSession, updateSession, DEVELOPMENT_NEXT_STEP, DEVELOPMENT_MARK, DevelopmentBuildRefusedError, refuseUnownedDevelopmentWrite, LEGACY_GATE_OPEN, LEGACY_GATE_CLOSED, SQLITE_MIGRATIONS, sqliteCatalogue, planSchema, SchemaRefusedError, readStoreSchema, writeNames, ACROSS_STORES_ORDER, STAMPED_COLUMNS, stampedValues, activeStoreSettings, normalizeRemote, gitRemoteUrl, readStoreMeta, SQLITE_STORE_FILE_NAME, sqliteStorePath, LONE_SURROGATE, withSqliteStore, writeSqliteStore, openSqliteStore, EffortCopyRefusal, EffortCopyFailure, copyEffortStore, RebuildRefusal, readConfigFile, loadConfig, plansDirAt, requireProject, resolvePlansDir, resolveProjectConfig, countTasks, formatCounts, checkbox, planFileName, stubOfPlanFile, isFile, issueLine, plural, expectNoArgument, expectOneArgument, expectAtMostOneArgument, readSwitch, fileStamp, keepsIdLine, fix_schema_default, minutesBetween, readCommitLog, UnionSchemaMismatch, migrateStore, MOVE_TO_SQLITE, MergeRefusal, mergeStore, createFileSync, SyncModuleMissing, selectSync, SKILL_FILE, MARKDOWN_EXTENSION, scanLayout, declaredNameIssue, readFrontmatterDocument, readFrontmatter, renderFrontmatter, mergeFrontmatter, writeFrontmatter, ACTION_HEADING, CAUSE_HEADING, parseInstinct, writeInstinct, readScopes, allRecords, findRecords, instinctProject, toHeldRecords, EVENT_PREFIX, padKind, oneLine, sessionSpawnEnv, CLAUDE_BIN, claudeArgs, interruptClaudeSessions, spawnClaude, runClaude, spawnClaudeCaptured, runClaudeCaptured, planFilePath, ClaudePlannerError, ISSUE_TYPES, ISSUE_PRIORITIES, ISSUE_STATES, GITHUB_LABELS, createGhRunner, typeOfLabels, moduleOfLabels, createLocalTracker, PORT_VERSIONS, createAdapterRegistry, CORE_ADAPTER_REGISTRY, TRUSTED_PERMISSIONS, TRUST_REFUSAL_EXIT, createGhPermissions, readAuthorTrust, ghBoardTrust, readBoardTrust, requireTrustedBoardAuthor, trustRefusalClause, trustRefusalMessage, requireTrustedAuthor, createGhEditorLogin, readEditorTrust, editorRefusalMessage, WIRE_FORMAT, WIRE_VERSION, WireFormatError, WireExportRefusal, encodeWirePayload, decodeWirePayload, exportWirePayload, materialiseWirePayload, selectEffortStore };