@open-tomato/rafa 0.28.0 → 0.32.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.
@@ -4,10 +4,10 @@ import {
4
4
  commandSpelling,
5
5
  isRoutingWord,
6
6
  isTopLevel
7
- } from "./index-4j1e3h26.js";
7
+ } from "./index-mt6hpsry.js";
8
8
  import {
9
9
  describeValue
10
- } from "./index-sf2brh4w.js";
10
+ } from "./index-rs79dq9e.js";
11
11
 
12
12
  // src/cli/registry.ts
13
13
  var REFUSAL = "command registry";
@@ -1,17 +1,19 @@
1
1
  // @bun
2
2
  import {
3
+ BOARD_RELATIONSHIP_MODES,
3
4
  CLAUDE_SETTING_SOURCES,
4
5
  CONFIG_VERSIONS,
5
6
  INJECT_MODES,
6
- MODULE_SOURCE_KEYS,
7
- OPTIONAL_ITEM_KEYS,
8
7
  OUTPUT_MODES,
9
8
  PR_PROVIDERS,
10
9
  RELEASE_AUTO,
11
- REQUIRED_ITEM_KEYS,
12
10
  SKILL_TIERS,
13
11
  STORE_BACKENDS,
12
+ SYNC_STRATEGIES,
13
+ below,
14
14
  busyTimeoutMs,
15
+ claimsAhead,
16
+ claimsStaleAfter,
15
17
  confidence,
16
18
  dayCount,
17
19
  describeValue,
@@ -22,14 +24,14 @@ import {
22
24
  issueNumber,
23
25
  lessonSwitch,
24
26
  listOf,
27
+ mapReading,
25
28
  mergeMethod,
26
29
  messageOf,
27
- moduleSource,
28
30
  oneOf,
29
- optionalPrerequisite,
30
31
  recurrenceCount,
32
+ refused,
33
+ refusedWith,
31
34
  releaseEnabled,
32
- requiredPrerequisite,
33
35
  routeTarget,
34
36
  skillResolverName,
35
37
  subsetOf,
@@ -37,12 +39,85 @@ import {
37
39
  tierPin,
38
40
  tierSwitch,
39
41
  usdAmount
40
- } from "./index-sf2brh4w.js";
42
+ } from "./index-rs79dq9e.js";
43
+
44
+ // src/config-items.ts
45
+ var itemText = text("a non-empty string");
46
+ function readKeyedItem(shape, raw, at) {
47
+ const choices = shape.kinds.join(", ");
48
+ if (!isMapping(raw))
49
+ return refused(at, raw, `a mapping naming one of: ${choices}`);
50
+ const entries = Object.entries(raw);
51
+ const kinds = shape.kinds.filter((kind2) => entries.some(([name]) => name === kind2));
52
+ const [kind] = kinds;
53
+ if (kind === undefined)
54
+ return refusedWith([`${at.label} names none of: ${choices}`]);
55
+ if (kinds.length > 1) {
56
+ const named2 = kinds.join(" and ");
57
+ return refusedWith([`${at.label} names ${named2}, expected exactly one of: ${choices}`]);
58
+ }
59
+ const optionalKeys = shape.optionalFor(kind);
60
+ const problems = [];
61
+ const extras = [];
62
+ const optional = new Map;
63
+ let named;
64
+ for (const [name, value] of entries) {
65
+ if (name !== kind && !optionalKeys.includes(name)) {
66
+ extras.push({ key: `${at.key}.${name}`, value });
67
+ continue;
68
+ }
69
+ if (name !== kind && value === null)
70
+ continue;
71
+ const reading = itemText(value, below(at, `.${name}`));
72
+ problems.push(...reading.problems);
73
+ if (reading.value === undefined)
74
+ continue;
75
+ if (name === kind)
76
+ named = reading.value;
77
+ else
78
+ optional.set(name, reading.value);
79
+ }
80
+ return problems.length > 0 || named === undefined ? { value: undefined, problems, extras } : { value: { kind, named, optional }, problems, extras };
81
+ }
82
+ var PREREQUISITE_KINDS = ["tool", "env", "service", "lsp"];
83
+ var REQUIRED_ITEM_KEYS = [...PREREQUISITE_KINDS, "probe"];
84
+ var OPTIONAL_ITEM_KEYS = [...REQUIRED_ITEM_KEYS, "reason"];
85
+ var requiredPrerequisite = (raw, at) => {
86
+ const shape = { kinds: PREREQUISITE_KINDS, optionalFor: () => ["probe"] };
87
+ return mapReading(readKeyedItem(shape, raw, at), (item) => Object.freeze({
88
+ kind: item.kind,
89
+ name: item.named,
90
+ probe: item.optional.get("probe") ?? null
91
+ }));
92
+ };
93
+ var optionalPrerequisite = (raw, at) => {
94
+ const shape = { kinds: PREREQUISITE_KINDS, optionalFor: () => ["probe", "reason"] };
95
+ return mapReading(readKeyedItem(shape, raw, at), (item) => Object.freeze({
96
+ kind: item.kind,
97
+ name: item.named,
98
+ probe: item.optional.get("probe") ?? null,
99
+ reason: item.optional.get("reason") ?? null
100
+ }));
101
+ };
102
+ var MODULE_SOURCE_KINDS = ["npm", "github", "path"];
103
+ var MODULE_SOURCE_KEYS = [...MODULE_SOURCE_KINDS, "ref"];
104
+ var moduleSource = (raw, at) => {
105
+ const shape = {
106
+ kinds: MODULE_SOURCE_KINDS,
107
+ optionalFor: (kind) => kind === "github" ? ["ref"] : []
108
+ };
109
+ return mapReading(readKeyedItem(shape, raw, at), (item) => Object.freeze({
110
+ kind: item.kind,
111
+ location: item.named,
112
+ ref: item.optional.get("ref") ?? null
113
+ }));
114
+ };
41
115
 
42
116
  // src/config-schema.ts
43
117
  import { join } from "path";
44
118
 
45
119
  // src/config-readers.ts
120
+ import { isAbsolute, normalize } from "path";
46
121
  function mapOf(value, expected) {
47
122
  return (raw, at) => {
48
123
  if (!isMapping(raw)) {
@@ -74,6 +149,96 @@ var trackerKind = text("a tracker kind name");
74
149
  var releaseFile = text("a file path");
75
150
  var tierPins = mapOf(tierPin, "false or a tier");
76
151
  var routeTable = mapOf(routeTarget, "false or an agent name");
152
+ var RELEASE_STRATEGIES = ["semver-by-level"];
153
+ var RELEASE_SETTLE_MODES = ["push", "pr"];
154
+ var RELEASE_TAG_MODES = ["manual", "settle"];
155
+ var VERSION_COLLISION_MODES = ["allow", "report", "ask", "refuse"];
156
+ var releaseStrategy = oneOf(RELEASE_STRATEGIES);
157
+ var releaseSettleMode = oneOf(RELEASE_SETTLE_MODES);
158
+ var releaseTagMode = oneOf(RELEASE_TAG_MODES);
159
+ var versionCollisionMode = oneOf(VERSION_COLLISION_MODES);
160
+ var UNTRACKED_DIRECTORY = ".rafa";
161
+ var FRAGMENTS_EXPECTED = `a relative directory path not under ${UNTRACKED_DIRECTORY}/`;
162
+ function isUnderUntracked(path) {
163
+ const [first] = normalize(path).split(/[\\/]/);
164
+ return first === UNTRACKED_DIRECTORY;
165
+ }
166
+ var fragmentsDirectory = (raw, at) => {
167
+ const reading = text(FRAGMENTS_EXPECTED)(raw, at);
168
+ const path = reading.value;
169
+ if (path === undefined || !isAbsolute(path) && !isUnderUntracked(path))
170
+ return reading;
171
+ const problem = `${at.label} is ${describeValue(raw)}, expected ${FRAGMENTS_EXPECTED}`;
172
+ return { value: undefined, problems: [problem], extras: [] };
173
+ };
174
+
175
+ // src/config-schema-release.ts
176
+ var PR_DEFAULTS = Object.freeze({
177
+ prProvider: null,
178
+ prMergeMethod: "squash",
179
+ prBase: null,
180
+ prResolveBudget: 2,
181
+ prVersionCollision: "report"
182
+ });
183
+ var RELEASE_DEFAULTS = Object.freeze({
184
+ releaseEnabled: RELEASE_AUTO,
185
+ releaseVersionFile: "package.json",
186
+ releaseChangelog: "CHANGELOG.md",
187
+ releaseHeading: "## {version} \u2014 {date}, {title}",
188
+ releaseFragments: ".changes",
189
+ releaseStrategy: "semver-by-level",
190
+ releaseSettle: "push",
191
+ releaseTag: "manual",
192
+ releasePublishCommand: "npm publish"
193
+ });
194
+ var DANGEROUS_RELEASE_DEFAULTS = Object.freeze({
195
+ dangerousAcceptVersionCollision: false
196
+ });
197
+ var PR_SETTINGS = {
198
+ prProvider: { key: "pr.provider", read: oneOf(PR_PROVIDERS), cli: false },
199
+ prMergeMethod: { key: "pr.mergeMethod", read: mergeMethod, cli: false },
200
+ prBase: { key: "pr.base", read: text("a branch name"), cli: false },
201
+ prResolveBudget: { key: "pr.resolveBudget", read: usdAmount, cli: false },
202
+ prVersionCollision: {
203
+ key: "pr.versionCollision",
204
+ read: versionCollisionMode,
205
+ cli: false
206
+ }
207
+ };
208
+ var RELEASE_SETTINGS = {
209
+ releaseEnabled: { key: "release.enabled", read: releaseEnabled, cli: false },
210
+ releaseVersionFile: {
211
+ key: "release.versionFile",
212
+ read: releaseFile,
213
+ cli: false
214
+ },
215
+ releaseChangelog: { key: "release.changelog", read: releaseFile, cli: false },
216
+ releaseHeading: {
217
+ key: "release.heading",
218
+ read: text("a changelog heading template"),
219
+ cli: false
220
+ },
221
+ releaseFragments: {
222
+ key: "release.fragments",
223
+ read: fragmentsDirectory,
224
+ cli: false
225
+ },
226
+ releaseStrategy: { key: "release.strategy", read: releaseStrategy, cli: false },
227
+ releaseSettle: { key: "release.settle", read: releaseSettleMode, cli: false },
228
+ releaseTag: { key: "release.tag", read: releaseTagMode, cli: false },
229
+ releasePublishCommand: {
230
+ key: "release.publishCommand",
231
+ read: text("a publish command"),
232
+ cli: false
233
+ }
234
+ };
235
+ var DANGEROUS_RELEASE_SETTINGS = {
236
+ dangerousAcceptVersionCollision: {
237
+ key: "dangerous.acceptVersionCollision",
238
+ read: flag,
239
+ cli: false
240
+ }
241
+ };
77
242
 
78
243
  // src/tiers/resolve.ts
79
244
  import { readFileSync } from "fs";
@@ -245,6 +410,7 @@ var CONFIG_DEFAULTS = Object.freeze({
245
410
  version: 1,
246
411
  store: "sqlite",
247
412
  effortBusyTimeoutMs: 5000,
413
+ effortSync: "local",
248
414
  inject: "stage",
249
415
  planDir: join(".rafa", "plans"),
250
416
  specsDir: join(".rafa", "specs"),
@@ -263,20 +429,20 @@ var CONFIG_DEFAULTS = Object.freeze({
263
429
  modules: Object.freeze([]),
264
430
  allowList: Object.freeze([]),
265
431
  settingSources: Object.freeze(["project", "local"]),
266
- prProvider: null,
267
- prMergeMethod: "squash",
268
- prBase: null,
269
- prResolveBudget: 2,
432
+ loopWorktreeDir: join(".rafa", "worktrees"),
433
+ ...PR_DEFAULTS,
270
434
  boardTrustedAuthors: Object.freeze([]),
435
+ boardRelationships: "labels",
271
436
  roadmapIssue: null,
272
- releaseEnabled: RELEASE_AUTO,
273
- releaseVersionFile: "package.json",
274
- releaseChangelog: "CHANGELOG.md",
275
- releaseHeading: "## {version} \u2014 {date}, {title}",
437
+ claimsStaleAfter: "3d",
438
+ claimsAhead: "off",
439
+ ...RELEASE_DEFAULTS,
276
440
  cleanupStaleDays: 30,
277
441
  cleanupWorktreeIdleDays: 7,
278
442
  cleanupKeep: Object.freeze([]),
279
443
  dangerousAcceptStaleRefs: false,
444
+ ...DANGEROUS_RELEASE_DEFAULTS,
445
+ dangerousSelfUpdateDuringLoop: false,
280
446
  statusNotice: true,
281
447
  tiersRafa: "on",
282
448
  tiersSkills: new Map,
@@ -289,6 +455,7 @@ var SETTINGS = {
289
455
  version: { key: "version", read: oneOf(CONFIG_VERSIONS), cli: false },
290
456
  store: { key: "store", read: oneOf(STORE_BACKENDS), cli: true },
291
457
  effortBusyTimeoutMs: { key: "effort.busyTimeoutMs", read: busyTimeoutMs, cli: false },
458
+ effortSync: { key: "effort.sync", read: oneOf(SYNC_STRATEGIES), cli: false },
292
459
  inject: { key: "plan.inject", read: oneOf(INJECT_MODES), cli: true },
293
460
  planDir: { key: "plan.dir", read: directory, cli: true },
294
461
  specsDir: { key: "specs.dir", read: directory, cli: true },
@@ -338,28 +505,22 @@ var SETTINGS = {
338
505
  read: subsetOf(CLAUDE_SETTING_SOURCES),
339
506
  cli: true
340
507
  },
341
- prProvider: { key: "pr.provider", read: oneOf(PR_PROVIDERS), cli: false },
342
- prMergeMethod: { key: "pr.mergeMethod", read: mergeMethod, cli: false },
343
- prBase: { key: "pr.base", read: text("a branch name"), cli: false },
344
- prResolveBudget: { key: "pr.resolveBudget", read: usdAmount, cli: false },
508
+ loopWorktreeDir: { key: "loop.worktreeDir", read: directory, cli: false },
509
+ ...PR_SETTINGS,
345
510
  boardTrustedAuthors: {
346
511
  key: "board.trustedAuthors",
347
512
  read: listOf(githubLogin, "GitHub logins"),
348
513
  cli: false
349
514
  },
350
- roadmapIssue: { key: "roadmap.issue", read: issueNumber, cli: false },
351
- releaseEnabled: { key: "release.enabled", read: releaseEnabled, cli: false },
352
- releaseVersionFile: {
353
- key: "release.versionFile",
354
- read: releaseFile,
355
- cli: false
356
- },
357
- releaseChangelog: { key: "release.changelog", read: releaseFile, cli: false },
358
- releaseHeading: {
359
- key: "release.heading",
360
- read: text("a changelog heading template"),
515
+ boardRelationships: {
516
+ key: "board.relationships",
517
+ read: oneOf(BOARD_RELATIONSHIP_MODES),
361
518
  cli: false
362
519
  },
520
+ roadmapIssue: { key: "roadmap.issue", read: issueNumber, cli: false },
521
+ claimsStaleAfter: { key: "claims.staleAfter", read: claimsStaleAfter, cli: false },
522
+ claimsAhead: { key: "claims.ahead", read: claimsAhead, cli: false },
523
+ ...RELEASE_SETTINGS,
363
524
  cleanupStaleDays: { key: "cleanup.staleDays", read: dayCount, cli: false },
364
525
  cleanupWorktreeIdleDays: {
365
526
  key: "cleanup.worktreeIdleDays",
@@ -376,6 +537,12 @@ var SETTINGS = {
376
537
  read: flag,
377
538
  cli: false
378
539
  },
540
+ ...DANGEROUS_RELEASE_SETTINGS,
541
+ dangerousSelfUpdateDuringLoop: {
542
+ key: "dangerous.selfUpdateDuringLoop",
543
+ read: flag,
544
+ cli: false
545
+ },
379
546
  statusNotice: { key: "status.notice", read: flag, cli: false },
380
547
  tiersRafa: { key: "tiers.rafa", read: tierSwitch, cli: false },
381
548
  tiersSkills: { key: "tiers.skills", read: tierPins, cli: false },
@@ -453,6 +620,7 @@ function readLayer(rawOf, atOf) {
453
620
  version: read("version"),
454
621
  store: read("store"),
455
622
  effortBusyTimeoutMs: read("effortBusyTimeoutMs"),
623
+ effortSync: read("effortSync"),
456
624
  inject: read("inject"),
457
625
  planDir: read("planDir"),
458
626
  specsDir: read("specsDir"),
@@ -471,20 +639,32 @@ function readLayer(rawOf, atOf) {
471
639
  modules: read("modules"),
472
640
  allowList: read("allowList"),
473
641
  settingSources: read("settingSources"),
642
+ loopWorktreeDir: read("loopWorktreeDir"),
474
643
  prProvider: read("prProvider"),
475
644
  prMergeMethod: read("prMergeMethod"),
476
645
  prBase: read("prBase"),
477
646
  prResolveBudget: read("prResolveBudget"),
647
+ prVersionCollision: read("prVersionCollision"),
478
648
  boardTrustedAuthors: read("boardTrustedAuthors"),
649
+ boardRelationships: read("boardRelationships"),
479
650
  roadmapIssue: read("roadmapIssue"),
651
+ claimsStaleAfter: read("claimsStaleAfter"),
652
+ claimsAhead: read("claimsAhead"),
480
653
  releaseEnabled: read("releaseEnabled"),
481
654
  releaseVersionFile: read("releaseVersionFile"),
482
655
  releaseChangelog: read("releaseChangelog"),
483
656
  releaseHeading: read("releaseHeading"),
657
+ releaseFragments: read("releaseFragments"),
658
+ releaseStrategy: read("releaseStrategy"),
659
+ releaseSettle: read("releaseSettle"),
660
+ releaseTag: read("releaseTag"),
661
+ releasePublishCommand: read("releasePublishCommand"),
484
662
  cleanupStaleDays: read("cleanupStaleDays"),
485
663
  cleanupWorktreeIdleDays: read("cleanupWorktreeIdleDays"),
486
664
  cleanupKeep: read("cleanupKeep"),
487
665
  dangerousAcceptStaleRefs: read("dangerousAcceptStaleRefs"),
666
+ dangerousAcceptVersionCollision: read("dangerousAcceptVersionCollision"),
667
+ dangerousSelfUpdateDuringLoop: read("dangerousSelfUpdateDuringLoop"),
488
668
  statusNotice: read("statusNotice"),
489
669
  tiersRafa: read("tiersRafa"),
490
670
  tiersSkills: read("tiersSkills"),
@@ -1058,4 +1238,4 @@ function activeOutputMode() {
1058
1238
  return activeMode;
1059
1239
  }
1060
1240
 
1061
- export { pinKey, pinLine, collisionMessage, readItemBytes, resolveTiers, findTierItem, DEFAULT_ROUTES, DEFAULT_ROUTING, CONFIG_FILE, CONFIG_DEFAULTS, SETTINGS, ConfigError, configFilePath, parseConfigText, resolveConfig, isStampableStub, planStubFromPrompt, stampPrompt, planStubFromPath, RAFA_BLOCK_KINDS, isRafaBlockKind, readRafaBlocks, REPORT_STATUSES, FINDING_KINDS, FINDING_SIGNALS, FINDING_DOMAINS, CHANGE_LEVELS, parseReport, createTextOutput, activeOutput, activeOutputMode };
1241
+ export { PREREQUISITE_KINDS, requiredPrerequisite, optionalPrerequisite, MODULE_SOURCE_KINDS, pinKey, pinLine, collisionMessage, readItemBytes, resolveTiers, findTierItem, DEFAULT_ROUTES, DEFAULT_ROUTING, CONFIG_FILE, CONFIG_DEFAULTS, SETTINGS, ConfigError, configFilePath, parseConfigText, resolveConfig, isStampableStub, planStubFromPrompt, stampPrompt, planStubFromPath, createTextOutput, activeOutput, activeOutputMode, RAFA_BLOCK_KINDS, isRafaBlockKind, readRafaBlocks, REPORT_STATUSES, FINDING_KINDS, FINDING_SIGNALS, FINDING_DOMAINS, CHANGE_LEVELS, parseReport };
@@ -1,7 +1,7 @@
1
1
  // @bun
2
2
  import {
3
3
  describeValue
4
- } from "./index-sf2brh4w.js";
4
+ } from "./index-rs79dq9e.js";
5
5
 
6
6
  // src/cli/spends.ts
7
7
  var SPENDS_GLYPH = "\uD83E\uDE99";
@@ -3,11 +3,11 @@ import {
3
3
  activeOutput,
4
4
  isStampableStub,
5
5
  readRafaBlocks
6
- } from "./index-rv7y8y1j.js";
6
+ } from "./index-9aph6ft9.js";
7
7
  import {
8
8
  messageOf,
9
9
  parseTaskDeclaration
10
- } from "./index-sf2brh4w.js";
10
+ } from "./index-rs79dq9e.js";
11
11
  // src/preflight/prerequisites-md.ts
12
12
  import { basename, dirname, join } from "path";
13
13
  var SECTION_AUTO_RE = /\[auto\]/i;
@@ -871,4 +871,4 @@ function renderInjection(request) {
871
871
  }
872
872
  return { requested: mode, mode, text: RENDERERS[mode](model, location.task), fallback: null };
873
873
  }
874
- export { escapeBlockerText, splitBlockerComment, findNextTask, updateTrackerLine, writeTrackerBlocker, trackerPathFor, PLAN_BLOCK_KINDS, PLAN_HEADER_FIELDS, parsePlan, parsePrerequisites, planPrerequisites, malformedPrerequisiteLines, mergePlanPrerequisites, prerequisitesPathForPlan, loadPlanPrerequisites, PROBE_TIMEOUT_MS, runShellProbe, runPreflight, renderInjection };
874
+ export { escapeBlockerText, splitBlockerComment, findNextTask, updateTrackerLine, writeTrackerBlocker, trackerPathFor, PLAN_BLOCK_KINDS, PLAN_HEADER_FIELDS, PLAN_RELEASE_LEVELS, parsePlan, parsePrerequisites, planPrerequisites, malformedPrerequisiteLines, mergePlanPrerequisites, prerequisitesPathForPlan, loadPlanPrerequisites, PROBE_TIMEOUT_MS, runShellProbe, runPreflight, renderInjection };