@open-tomato/rafa 0.45.0 → 0.46.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +255 -23
- package/dist/PROMPT.md +18 -1
- package/dist/adapters/logger/settings.d.ts +132 -0
- package/dist/bugs/closest.d.ts +19 -0
- package/dist/bugs/fenced.d.ts +8 -0
- package/dist/bugs/places.d.ts +20 -0
- package/dist/bugs/record.d.ts +145 -0
- package/dist/bugs/title.d.ts +83 -0
- package/dist/bundled/agents/doc-updater.md +17 -3
- package/dist/bundled/agents/loop-implementer.md +14 -2
- package/dist/bundled/operators/skills/rafa-stretch-pit-stop/SKILL.md +10 -3
- package/dist/bundled/operators/skills/rafa-stretch-sweep/SKILL.md +5 -0
- package/dist/bundled/skills/dev-planner/SKILL.md +101 -18
- package/dist/cli.js +74726 -62960
- package/dist/config/entry.d.ts +119 -0
- package/dist/config/index.d.ts +36 -0
- package/dist/config/index.js +51 -0
- package/dist/config/shape.d.ts +232 -0
- package/dist/config-registry.d.ts +127 -0
- package/dist/config-schema-board-project.d.ts +157 -0
- package/dist/config-schema-bugs.d.ts +71 -0
- package/dist/config-schema-errors.d.ts +54 -0
- package/dist/config-schema-features.d.ts +64 -0
- package/dist/config-schema-hub.d.ts +150 -0
- package/dist/config-schema-issues.d.ts +95 -0
- package/dist/config-schema-logger.d.ts +91 -0
- package/dist/config-schema-loop-continue.d.ts +122 -0
- package/dist/config-schema-loop-retries.d.ts +94 -0
- package/dist/config-schema-release.d.ts +307 -0
- package/dist/config-schema-tests.d.ts +170 -0
- package/dist/config-schema-triage.d.ts +142 -0
- package/dist/config-schema-wrap-up.d.ts +96 -0
- package/dist/core/command/command.d.ts +228 -0
- package/dist/core/command/confirm.d.ts +67 -0
- package/dist/core/command/index.d.ts +112 -0
- package/dist/core/command/lazy.d.ts +54 -0
- package/dist/core/command/registry-types.d.ts +96 -0
- package/dist/core/command/running.d.ts +96 -0
- package/dist/core/command/spends.d.ts +39 -0
- package/dist/core/command/types.d.ts +92 -0
- package/dist/core/command/version.d.ts +4 -0
- package/dist/core/config/branch-template.d.ts +20 -0
- package/dist/core/config/config-items.d.ts +86 -0
- package/dist/core/config/config-load.d.ts +47 -0
- package/dist/core/config/config-origins.d.ts +57 -0
- package/dist/core/config/config-readers.d.ts +167 -0
- package/dist/core/config/config-schema.d.ts +207 -0
- package/dist/core/config/config-sections.d.ts +493 -0
- package/dist/core/config/config.d.ts +320 -0
- package/dist/core/config/core-section.d.ts +39 -0
- package/dist/core/config/dangerous.d.ts +58 -0
- package/dist/core/config/default-routing.d.ts +16 -0
- package/dist/core/config/index.d.ts +141 -0
- package/dist/core/config/scope.d.ts +42 -0
- package/dist/core/config/section.d.ts +206 -0
- package/dist/core/config/sections.d.ts +45 -0
- package/dist/core/config/standard-schema.d.ts +27 -0
- package/dist/core/git/commit.d.ts +232 -0
- package/dist/core/git/gh-runner.d.ts +24 -0
- package/dist/core/git/git.d.ts +22 -0
- package/dist/core/git/index.d.ts +85 -0
- package/dist/core/loop/claude.d.ts +388 -0
- package/dist/core/loop/hop-record.d.ts +52 -0
- package/dist/core/loop/index.d.ts +179 -0
- package/dist/core/loop/session-env.d.ts +20 -0
- package/dist/core/loop/session-record-parse.d.ts +63 -0
- package/dist/core/loop/sessions.d.ts +408 -0
- package/dist/core/loop/suite-failure.d.ts +25 -0
- package/dist/core/output/active.d.ts +100 -0
- package/dist/core/output/stream.d.ts +20 -0
- package/dist/core/output/text.d.ts +55 -0
- package/dist/core/plan/block-reader.d.ts +46 -0
- package/dist/core/plan/blocks.d.ts +139 -0
- package/dist/core/plan/declaration.d.ts +366 -0
- package/dist/core/plan/plan-stamp.d.ts +75 -0
- package/dist/core/runtime/identity.d.ts +21 -0
- package/dist/core/runtime/index.d.ts +46 -0
- package/dist/effort/store/bring-forward.d.ts +131 -0
- package/dist/effort/store/check-rows.d.ts +31 -0
- package/dist/effort/store/commit-stats.d.ts +42 -0
- package/dist/effort/store/copy.d.ts +35 -0
- package/dist/effort/store/development-build.d.ts +105 -0
- package/dist/effort/store/effort-levels.d.ts +13 -0
- package/dist/effort/store/findings.d.ts +214 -0
- package/dist/effort/store/fix-schema.d.ts +184 -0
- package/dist/effort/store/index.js +10 -7
- package/dist/effort/store/location.d.ts +44 -0
- package/dist/effort/store/merge-commit-gaps.d.ts +68 -0
- package/dist/effort/store/merge-conflicts.d.ts +91 -0
- package/dist/effort/store/merge-rules.d.ts +82 -0
- package/dist/effort/store/merge-store.d.ts +211 -0
- package/dist/effort/store/merge-union.d.ts +92 -0
- package/dist/effort/store/migrate.d.ts +146 -0
- package/dist/effort/store/migrations.d.ts +92 -0
- package/dist/effort/store/ndjson-files.d.ts +114 -0
- package/dist/effort/store/origins.d.ts +116 -0
- package/dist/effort/store/plan-stubs.d.ts +79 -0
- package/dist/effort/store/rebuild-aside.d.ts +172 -0
- package/dist/effort/store/schema-plan.d.ts +102 -0
- package/dist/effort/store/session-row-types.d.ts +64 -0
- package/dist/effort/store/settings.d.ts +13 -0
- package/dist/effort/store/sqlite.d.ts +340 -0
- package/dist/effort/store/store-generation.d.ts +17 -0
- package/dist/effort/store/store-identity.d.ts +220 -0
- package/dist/effort/store/store-meta.d.ts +305 -0
- package/dist/effort/store/store-replaced.d.ts +72 -0
- package/dist/effort/store/types.d.ts +223 -0
- package/dist/errors/codes.d.ts +56 -0
- package/dist/errors/rafa-codes.d.ts +36 -0
- package/dist/index-2a7nb3an.js +125 -0
- package/dist/{index-r28fzsvc.js → index-39kbcw68.js} +350 -165
- package/dist/{index-nv34ptht.js → index-77ajfffn.js} +14 -9
- package/dist/index-cy98y87p.js +2597 -0
- package/dist/index-gqz4jn6j.js +13447 -0
- package/dist/index-gvek4r8m.js +710 -0
- package/dist/index-j4k2vdz3.js +1125 -0
- package/dist/index-jh1r4kcn.js +1067 -0
- package/dist/{index-mgh2s9bj.js → index-ykggr043.js} +58 -455
- package/dist/index-z1w83f81.js +4 -0
- package/dist/index.js +14715 -21516
- package/dist/learning/index.js +5 -6
- package/dist/plan/index.js +12 -11
- package/dist/plan-prompt.md +3 -1
- package/dist/ports/index.d.ts +732 -0
- package/dist/ports/learning.d.ts +101 -0
- package/dist/ports/log-level.d.ts +13 -0
- package/dist/ports/spec-review.d.ts +66 -0
- package/dist/pr/checks.d.ts +133 -0
- package/dist/pr/types.d.ts +422 -0
- package/dist/ready-4f8edezt.js +2016 -0
- package/dist/release-templates/release-bot-fragment.yml +153 -0
- package/dist/release-templates/release-publish.yml +110 -0
- package/dist/release-templates/release-settle.yml +122 -0
- package/dist/release-templates/release-tag.yml +102 -0
- package/dist/report/parse.d.ts +415 -0
- package/dist/schema/project-id.d.ts +79 -0
- package/dist/schema/tiers.d.ts +107 -0
- package/package.json +41 -3
- package/dist/index-hf2k497d.js +0 -16
- package/dist/index-nsr78ct2.js +0 -8219
|
@@ -1,20 +1,5 @@
|
|
|
1
1
|
// @bun
|
|
2
|
-
|
|
3
|
-
CONFIDENCE_MAX,
|
|
4
|
-
CONFIDENCE_MIN
|
|
5
|
-
} from "./index-hf2k497d.js";
|
|
6
|
-
|
|
7
|
-
// src/pr/types.ts
|
|
8
|
-
var MERGE_METHODS = Object.freeze([
|
|
9
|
-
"squash",
|
|
10
|
-
"merge",
|
|
11
|
-
"rebase"
|
|
12
|
-
]);
|
|
13
|
-
function isMergeMethod(value) {
|
|
14
|
-
return typeof value === "string" && MERGE_METHODS.includes(value);
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
// src/schema/tiers.ts
|
|
2
|
+
// packages/rafa/src/schema/tiers.ts
|
|
18
3
|
import { existsSync, realpathSync } from "fs";
|
|
19
4
|
import { dirname, join } from "path";
|
|
20
5
|
var SKILL_TIERS = ["project", "rafa", "user"];
|
|
@@ -73,7 +58,16 @@ function tierExists(dir) {
|
|
|
73
58
|
return existsSync(dir);
|
|
74
59
|
}
|
|
75
60
|
|
|
76
|
-
// src/
|
|
61
|
+
// packages/rafa/src/effort/store/effort-levels.ts
|
|
62
|
+
var EFFORT_LEVELS = [
|
|
63
|
+
"low",
|
|
64
|
+
"medium",
|
|
65
|
+
"high",
|
|
66
|
+
"xhigh",
|
|
67
|
+
"max"
|
|
68
|
+
];
|
|
69
|
+
|
|
70
|
+
// packages/rafa/src/core/plan/declaration.ts
|
|
77
71
|
var DECLARATION_KEYS = [
|
|
78
72
|
"agent",
|
|
79
73
|
"model",
|
|
@@ -81,20 +75,15 @@ var DECLARATION_KEYS = [
|
|
|
81
75
|
"budget",
|
|
82
76
|
"tools",
|
|
83
77
|
"skills",
|
|
84
|
-
"tests"
|
|
78
|
+
"tests",
|
|
79
|
+
"docs"
|
|
85
80
|
];
|
|
86
81
|
var GRANULAR_KEYS = ["model", "effort", "tools"];
|
|
87
82
|
var AGENT_OWNED_KEYS = ["model", "tools"];
|
|
88
83
|
var MODEL_ALIASES = ["opus", "sonnet", "haiku", "fable"];
|
|
89
|
-
var EFFORT_LEVELS = [
|
|
90
|
-
"low",
|
|
91
|
-
"medium",
|
|
92
|
-
"high",
|
|
93
|
-
"xhigh",
|
|
94
|
-
"max"
|
|
95
|
-
];
|
|
96
84
|
var TEST_SCOPES = ["affected", "module", "full"];
|
|
97
85
|
var DEFAULT_TEST_SCOPE = "affected";
|
|
86
|
+
var DOCS_ROLES = ["repair"];
|
|
98
87
|
var DECLARATION_BLOCK = /\{([^{}]*)\}$/;
|
|
99
88
|
var ENTRY_TOKEN = /^([A-Za-z_][A-Za-z0-9_-]*)=(.*)$/;
|
|
100
89
|
var FULL_MODEL_NAME = /^claude-[a-z0-9][a-z0-9.-]*$/;
|
|
@@ -121,6 +110,12 @@ function isTestScope(value) {
|
|
|
121
110
|
function readTestScope(declaration) {
|
|
122
111
|
return declaration?.tests ?? DEFAULT_TEST_SCOPE;
|
|
123
112
|
}
|
|
113
|
+
function isDocsRole(value) {
|
|
114
|
+
return DOCS_ROLES.includes(value);
|
|
115
|
+
}
|
|
116
|
+
function readDocsRole(declaration) {
|
|
117
|
+
return declaration?.docs ?? null;
|
|
118
|
+
}
|
|
124
119
|
function isModelValue(value) {
|
|
125
120
|
if (MODEL_ALIASES.includes(value))
|
|
126
121
|
return true;
|
|
@@ -176,6 +171,7 @@ function readBlock(raw, body) {
|
|
|
176
171
|
let tools = null;
|
|
177
172
|
let skills = null;
|
|
178
173
|
let tests = null;
|
|
174
|
+
let docs = null;
|
|
179
175
|
for (const token of tokenise(body)) {
|
|
180
176
|
const match = token.match(ENTRY_TOKEN);
|
|
181
177
|
const key = match?.[1];
|
|
@@ -239,6 +235,13 @@ function readBlock(raw, body) {
|
|
|
239
235
|
issues.push(unusableValue(key, token));
|
|
240
236
|
continue;
|
|
241
237
|
}
|
|
238
|
+
if (key === "docs") {
|
|
239
|
+
if (isDocsRole(value))
|
|
240
|
+
docs = value;
|
|
241
|
+
else
|
|
242
|
+
issues.push(unusableValue(key, token));
|
|
243
|
+
continue;
|
|
244
|
+
}
|
|
242
245
|
const named = parseSkillList(value);
|
|
243
246
|
if (named === null)
|
|
244
247
|
issues.push(unusableValue(key, token));
|
|
@@ -258,7 +261,8 @@ function readBlock(raw, body) {
|
|
|
258
261
|
budget,
|
|
259
262
|
tools,
|
|
260
263
|
skills,
|
|
261
|
-
tests
|
|
264
|
+
tests,
|
|
265
|
+
docs
|
|
262
266
|
};
|
|
263
267
|
}
|
|
264
268
|
function parseTaskDeclaration(taskText) {
|
|
@@ -310,7 +314,7 @@ function resolveDeclarationFlags(declaration, agentDeclaresEffort) {
|
|
|
310
314
|
return { args, suppressed: [] };
|
|
311
315
|
}
|
|
312
316
|
|
|
313
|
-
// src/core/config/config-sections.ts
|
|
317
|
+
// packages/rafa/src/core/config/config-sections.ts
|
|
314
318
|
function isMapping(value) {
|
|
315
319
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
316
320
|
}
|
|
@@ -337,6 +341,7 @@ var OUTPUT_MODES = ["text", "json", "events"];
|
|
|
337
341
|
var CLAUDE_SETTING_SOURCES = ["user", "project", "local"];
|
|
338
342
|
var PR_PROVIDERS = ["gh", "none"];
|
|
339
343
|
var RELEASE_AUTO = "auto";
|
|
344
|
+
var DUPLICATE_LEVELS = ["warn", "error", "allow"];
|
|
340
345
|
var TIER_SWITCHES = ["on", "off"];
|
|
341
346
|
var SKILL_RESOLVERS = ["planner", "tag", "none"];
|
|
342
347
|
var LESSON_SWITCHES = ["on", "off"];
|
|
@@ -369,7 +374,6 @@ function text(expected) {
|
|
|
369
374
|
return (raw, at) => typeof raw === "string" && raw.trim() !== "" ? accepted(raw) : refused(at, raw, expected);
|
|
370
375
|
}
|
|
371
376
|
var flag = (raw, at) => typeof raw === "boolean" ? accepted(raw) : refused(at, raw, "true or false");
|
|
372
|
-
var mergeMethod = oneOf(MERGE_METHODS);
|
|
373
377
|
var usdAmount = (raw, at) => {
|
|
374
378
|
const usd = typeof raw === "number" ? parseBudgetUsd(String(raw)) : null;
|
|
375
379
|
return usd === null ? refused(at, raw, "a number of US dollars above zero, at most six digits either side of the point") : accepted(usd);
|
|
@@ -382,12 +386,15 @@ function isBusyTimeoutMs(raw) {
|
|
|
382
386
|
return typeof raw === "number" && Number.isSafeInteger(raw) && raw >= BUSY_TIMEOUT_MIN_MS && raw <= BUSY_TIMEOUT_MAX_MS;
|
|
383
387
|
}
|
|
384
388
|
var busyTimeoutMs = (raw, at) => isBusyTimeoutMs(raw) ? accepted(raw) : refused(at, raw, `a lock wait in milliseconds, a whole number from ${String(BUSY_TIMEOUT_MIN_MS)} to ${String(BUSY_TIMEOUT_MAX_MS)}`);
|
|
389
|
+
var CONFIDENCE_MIN = 0.3;
|
|
390
|
+
var CONFIDENCE_MAX = 0.9;
|
|
385
391
|
var confidence = (raw, at) => typeof raw === "number" && Number.isFinite(raw) && toHundredths(raw) >= toHundredths(CONFIDENCE_MIN) && toHundredths(raw) <= toHundredths(CONFIDENCE_MAX) ? accepted(raw) : refused(at, raw, `a confidence from ${String(CONFIDENCE_MIN)} to ${String(CONFIDENCE_MAX)}`);
|
|
386
392
|
function toHundredths(value) {
|
|
387
393
|
return Math.round(value * 100);
|
|
388
394
|
}
|
|
389
395
|
var recurrenceCount = (raw, at) => typeof raw === "number" && Number.isSafeInteger(raw) && raw >= 1 ? accepted(raw) : refused(at, raw, "a count, a whole number of 1 or more");
|
|
390
396
|
var releaseEnabled = (raw, at) => typeof raw === "boolean" || raw === RELEASE_AUTO ? accepted(raw) : refused(at, raw, `true, false or ${RELEASE_AUTO}`);
|
|
397
|
+
var duplicatesLevel = oneOf(DUPLICATE_LEVELS);
|
|
391
398
|
var tierSwitch = oneOf(TIER_SWITCHES);
|
|
392
399
|
var tierPin = (raw, at) => {
|
|
393
400
|
if (raw === false)
|
|
@@ -447,7 +454,7 @@ function subsetOf(values) {
|
|
|
447
454
|
};
|
|
448
455
|
}
|
|
449
456
|
|
|
450
|
-
// src/core/config/config-readers.ts
|
|
457
|
+
// packages/rafa/src/core/config/config-readers.ts
|
|
451
458
|
import { isAbsolute, normalize } from "path";
|
|
452
459
|
function mapOf(value, expected) {
|
|
453
460
|
return (raw, at) => {
|
|
@@ -483,10 +490,12 @@ var routeTable = mapOf(routeTarget, "false or an agent name");
|
|
|
483
490
|
var RELEASE_STRATEGIES = ["semver-by-level"];
|
|
484
491
|
var RELEASE_SETTLE_MODES = ["push", "pr"];
|
|
485
492
|
var RELEASE_TAG_MODES = ["manual", "settle"];
|
|
493
|
+
var RELEASE_PUBLISH_MODES = ["manual", "ci"];
|
|
486
494
|
var VERSION_COLLISION_MODES = ["allow", "report", "ask", "refuse"];
|
|
487
495
|
var releaseStrategy = oneOf(RELEASE_STRATEGIES);
|
|
488
496
|
var releaseSettleMode = oneOf(RELEASE_SETTLE_MODES);
|
|
489
497
|
var releaseTagMode = oneOf(RELEASE_TAG_MODES);
|
|
498
|
+
var releasePublishMode = oneOf(RELEASE_PUBLISH_MODES);
|
|
490
499
|
var versionCollisionMode = oneOf(VERSION_COLLISION_MODES);
|
|
491
500
|
var UNTRACKED_DIRECTORY = ".rafa";
|
|
492
501
|
var FRAGMENTS_EXPECTED = `a relative directory path not under ${UNTRACKED_DIRECTORY}/`;
|
|
@@ -502,436 +511,30 @@ var fragmentsDirectory = (raw, at) => {
|
|
|
502
511
|
const problem = `${at.label} is ${describeValue(raw)}, expected ${FRAGMENTS_EXPECTED}`;
|
|
503
512
|
return { value: undefined, problems: [problem], extras: [] };
|
|
504
513
|
};
|
|
505
|
-
|
|
506
|
-
var
|
|
507
|
-
|
|
508
|
-
"
|
|
509
|
-
"stage-context",
|
|
510
|
-
"report"
|
|
511
|
-
];
|
|
512
|
-
var RAFA_PREFIX = "rafa:";
|
|
513
|
-
var FENCE_RUN = /^( {0,3})(`{3,}|~{3,})/;
|
|
514
|
-
var CLOSING_FENCE = /^ {0,3}(`{3,}|~{3,})[ \t]*$/;
|
|
515
|
-
function isRafaBlockKind(kind) {
|
|
516
|
-
return RAFA_BLOCK_KINDS.includes(kind);
|
|
517
|
-
}
|
|
518
|
-
function linesOf(markdown) {
|
|
519
|
-
const lines = markdown.split(`
|
|
520
|
-
`);
|
|
521
|
-
if (lines[lines.length - 1] === "")
|
|
522
|
-
lines.pop();
|
|
523
|
-
return lines.map((line) => line.endsWith("\r") ? line.slice(0, -1) : line);
|
|
524
|
-
}
|
|
525
|
-
function kindOf(info) {
|
|
526
|
-
const word = info.trim().split(/\s+/)[0] ?? "";
|
|
527
|
-
return word.startsWith(RAFA_PREFIX) ? word.slice(RAFA_PREFIX.length) : null;
|
|
528
|
-
}
|
|
529
|
-
function openingFence(line) {
|
|
530
|
-
const match = FENCE_RUN.exec(line);
|
|
531
|
-
const opener = match?.[0];
|
|
532
|
-
const indent = match?.[1];
|
|
533
|
-
const run = match?.[2];
|
|
534
|
-
if (opener === undefined || indent === undefined || run === undefined) {
|
|
535
|
-
return null;
|
|
536
|
-
}
|
|
537
|
-
const marker = run.charAt(0);
|
|
538
|
-
const info = line.slice(opener.length);
|
|
539
|
-
if (marker === "`" && info.includes("`"))
|
|
540
|
-
return null;
|
|
541
|
-
return { marker, length: run.length, indent: indent.length, kind: kindOf(info) };
|
|
542
|
-
}
|
|
543
|
-
function closes(line, fence) {
|
|
544
|
-
const run = CLOSING_FENCE.exec(line)?.[1];
|
|
545
|
-
return run !== undefined && run.charAt(0) === fence.marker && run.length >= fence.length;
|
|
546
|
-
}
|
|
547
|
-
function closingIndex(lines, from, fence) {
|
|
548
|
-
for (let index = from;index < lines.length; index += 1) {
|
|
549
|
-
if (closes(lines[index] ?? "", fence))
|
|
550
|
-
return index;
|
|
551
|
-
}
|
|
552
|
-
return lines.length;
|
|
553
|
-
}
|
|
554
|
-
function dedent(line, indent) {
|
|
555
|
-
let cut = 0;
|
|
556
|
-
while (cut < indent && line.charAt(cut) === " ")
|
|
557
|
-
cut += 1;
|
|
558
|
-
return line.slice(cut);
|
|
559
|
-
}
|
|
560
|
-
function readRafaBlocks(markdown) {
|
|
561
|
-
const lines = linesOf(markdown);
|
|
562
|
-
const blocks = [];
|
|
563
|
-
let index = 0;
|
|
564
|
-
while (index < lines.length) {
|
|
565
|
-
const fence = openingFence(lines[index] ?? "");
|
|
566
|
-
if (fence === null) {
|
|
567
|
-
index += 1;
|
|
568
|
-
continue;
|
|
569
|
-
}
|
|
570
|
-
const closing = closingIndex(lines, index + 1, fence);
|
|
571
|
-
const closed = closing < lines.length;
|
|
572
|
-
if (fence.kind !== null) {
|
|
573
|
-
const body = lines.slice(index + 1, closing).map((line) => dedent(line, fence.indent)).join(`
|
|
574
|
-
`);
|
|
575
|
-
const last = closed ? closing + 1 : lines.length;
|
|
576
|
-
blocks.push({ kind: fence.kind, body, span: { first: index + 1, last }, closed });
|
|
577
|
-
}
|
|
578
|
-
index = closing + 1;
|
|
579
|
-
}
|
|
580
|
-
return blocks;
|
|
581
|
-
}
|
|
582
|
-
// src/report/parse.ts
|
|
583
|
-
var REPORT_STATUSES = ["done", "blocked"];
|
|
584
|
-
var FINDING_KINDS = ["gotcha", "pattern", "location", "skill-suggestion"];
|
|
585
|
-
var FINDING_SIGNALS = ["loud", "silent"];
|
|
586
|
-
var FINDING_DOMAINS = [
|
|
587
|
-
"code-style",
|
|
588
|
-
"testing",
|
|
589
|
-
"git",
|
|
590
|
-
"debugging",
|
|
591
|
-
"workflow",
|
|
592
|
-
"security",
|
|
593
|
-
"general-best-practices"
|
|
594
|
-
];
|
|
595
|
-
var CHANGE_LEVELS = ["patch", "minor", "major", "none"];
|
|
596
|
-
var REPORT_KIND = "report";
|
|
597
|
-
var REQUIRED = true;
|
|
598
|
-
var OPTIONAL = false;
|
|
599
|
-
var REPORT_KEYS = [
|
|
600
|
-
"status",
|
|
601
|
-
"feedback",
|
|
602
|
-
"findings",
|
|
603
|
-
"skills_used",
|
|
604
|
-
"blockers",
|
|
605
|
-
"out_of_scope_bugs",
|
|
606
|
-
"changes"
|
|
607
|
-
];
|
|
608
|
-
var FINDING_KEYS = [
|
|
609
|
-
"trigger",
|
|
610
|
-
"kind",
|
|
611
|
-
"what",
|
|
612
|
-
"cause",
|
|
613
|
-
"resolution",
|
|
614
|
-
"artifact",
|
|
615
|
-
"signal",
|
|
616
|
-
"domain"
|
|
617
|
-
];
|
|
618
|
-
var BLOCKER_KEYS = ["what", "artifact"];
|
|
619
|
-
var BUG_KEYS = ["what", "artifact", "security"];
|
|
620
|
-
var CHANGE_KEYS = ["level", "area", "summary"];
|
|
621
|
-
function isMapping2(value) {
|
|
622
|
-
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
514
|
+
var BRANCH_STUB = "{stub}";
|
|
515
|
+
var DEFAULT_BRANCH_TEMPLATE = `feat/${BRANCH_STUB}`;
|
|
516
|
+
function isBranchTemplate(raw) {
|
|
517
|
+
return typeof raw === "string" && raw.split(BRANCH_STUB).length === 2;
|
|
623
518
|
}
|
|
624
|
-
|
|
625
|
-
|
|
519
|
+
var branchTemplate = (raw, at) => isBranchTemplate(raw) ? { value: raw, problems: [], extras: [] } : refused(at, raw, `a branch name template holding ${BRANCH_STUB} exactly once`);
|
|
520
|
+
function branchFromTemplate(template, stub) {
|
|
521
|
+
return template.replace(BRANCH_STUB, () => stub);
|
|
626
522
|
}
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
if (Array.isArray(value))
|
|
633
|
-
return "a list";
|
|
634
|
-
if (typeof value === "object")
|
|
635
|
-
return "a mapping";
|
|
636
|
-
return `the ${typeof value} ${String(value)}`;
|
|
637
|
-
}
|
|
638
|
-
function messageOf2(error) {
|
|
639
|
-
return error instanceof Error ? error.message : String(error);
|
|
640
|
-
}
|
|
641
|
-
function reportIssue(reason, field, text2) {
|
|
642
|
-
return { reason, field, text: text2 };
|
|
643
|
-
}
|
|
644
|
-
function absent(reason, block, text2) {
|
|
645
|
-
return { present: false, reason, block, text: text2 };
|
|
646
|
-
}
|
|
647
|
-
function scopeOf(mapping, keys, prefix, issues) {
|
|
648
|
-
const fields = new Map;
|
|
649
|
-
const extras = [];
|
|
650
|
-
for (const [key, value] of Object.entries(mapping)) {
|
|
651
|
-
if (keys.includes(key))
|
|
652
|
-
fields.set(key, value);
|
|
653
|
-
else
|
|
654
|
-
extras.push({ key, value });
|
|
655
|
-
}
|
|
656
|
-
return { fields, extras, prefix, issues };
|
|
523
|
+
|
|
524
|
+
// packages/rafa/src/core/config/branch-template.ts
|
|
525
|
+
var STUB_PREFIX = "rafa-";
|
|
526
|
+
function branchGlob(template) {
|
|
527
|
+
return template.replace(BRANCH_STUB, () => `${STUB_PREFIX}*`);
|
|
657
528
|
}
|
|
658
|
-
function
|
|
659
|
-
|
|
660
|
-
if (value === null && required) {
|
|
661
|
-
const field = `${scope.prefix}${key}`;
|
|
662
|
-
scope.issues.push(reportIssue("missing-field", field, `${field} is missing`));
|
|
663
|
-
}
|
|
664
|
-
return value;
|
|
665
|
-
}
|
|
666
|
-
function unusable(scope, key, why) {
|
|
667
|
-
const field = `${scope.prefix}${key}`;
|
|
668
|
-
scope.issues.push(reportIssue("unusable-field", field, `${field} ${why}`));
|
|
669
|
-
return null;
|
|
670
|
-
}
|
|
671
|
-
function stringProblem(value) {
|
|
672
|
-
if (typeof value !== "string")
|
|
673
|
-
return `is ${describeValue2(value)}, not a string; quote it`;
|
|
674
|
-
if (value.trim().length === 0)
|
|
675
|
-
return "is blank";
|
|
676
|
-
return null;
|
|
677
|
-
}
|
|
678
|
-
function stringField(scope, key, required) {
|
|
679
|
-
const value = valueOf(scope, key, required);
|
|
680
|
-
if (value === null)
|
|
529
|
+
function stubOfBranch(template, branch) {
|
|
530
|
+
if (!isBranchTemplate(template))
|
|
681
531
|
return null;
|
|
682
|
-
const
|
|
683
|
-
|
|
684
|
-
}
|
|
685
|
-
function choiceField(scope, key, choices, required) {
|
|
686
|
-
const value = valueOf(scope, key, required);
|
|
687
|
-
if (value === null || isOneOf(choices, value))
|
|
688
|
-
return value;
|
|
689
|
-
return unusable(scope, key, `is ${describeValue2(value)}, not one of ${choices.join(", ")}`);
|
|
690
|
-
}
|
|
691
|
-
function booleanField(scope, key, required) {
|
|
692
|
-
const value = valueOf(scope, key, required);
|
|
693
|
-
if (value === null || typeof value === "boolean")
|
|
694
|
-
return value;
|
|
695
|
-
return unusable(scope, key, `is ${describeValue2(value)}, not true or false; write it unquoted`);
|
|
696
|
-
}
|
|
697
|
-
function listField(scope, key, readEntry) {
|
|
698
|
-
const value = valueOf(scope, key, OPTIONAL);
|
|
699
|
-
if (value === null)
|
|
700
|
-
return [];
|
|
701
|
-
if (!Array.isArray(value)) {
|
|
702
|
-
unusable(scope, key, `is ${describeValue2(value)}, not a list`);
|
|
703
|
-
return [];
|
|
704
|
-
}
|
|
705
|
-
const entries = [];
|
|
706
|
-
const items = value;
|
|
707
|
-
for (const [index, item] of items.entries()) {
|
|
708
|
-
const entry = readEntry(item, `${scope.prefix}${key}[${index}]`, scope.issues);
|
|
709
|
-
if (entry !== null)
|
|
710
|
-
entries.push(entry);
|
|
711
|
-
}
|
|
712
|
-
return entries;
|
|
713
|
-
}
|
|
714
|
-
function entryScope(item, field, keys, issues) {
|
|
715
|
-
if (isMapping2(item))
|
|
716
|
-
return scopeOf(item, keys, `${field}.`, issues);
|
|
717
|
-
const text2 = `${field} is ${describeValue2(item)}, not a mapping of ${keys.join(", ")}; dropped`;
|
|
718
|
-
issues.push(reportIssue("unusable-field", field, text2));
|
|
719
|
-
return null;
|
|
720
|
-
}
|
|
721
|
-
function readSkill(item, field, issues) {
|
|
722
|
-
const problem = stringProblem(item);
|
|
723
|
-
if (problem === null)
|
|
724
|
-
return item;
|
|
725
|
-
issues.push(reportIssue("unusable-field", field, `${field} ${problem}; dropped`));
|
|
726
|
-
return null;
|
|
727
|
-
}
|
|
728
|
-
function readFinding(item, field, issues) {
|
|
729
|
-
const scope = entryScope(item, field, FINDING_KEYS, issues);
|
|
730
|
-
if (scope === null)
|
|
532
|
+
const [prefix = "", suffix = ""] = template.split(BRANCH_STUB);
|
|
533
|
+
if (branch.length < prefix.length + suffix.length)
|
|
731
534
|
return null;
|
|
732
|
-
|
|
733
|
-
trigger: stringField(scope, "trigger", REQUIRED),
|
|
734
|
-
kind: choiceField(scope, "kind", FINDING_KINDS, REQUIRED),
|
|
735
|
-
what: stringField(scope, "what", REQUIRED),
|
|
736
|
-
cause: stringField(scope, "cause", OPTIONAL),
|
|
737
|
-
resolution: stringField(scope, "resolution", OPTIONAL),
|
|
738
|
-
artifact: stringField(scope, "artifact", OPTIONAL),
|
|
739
|
-
signal: choiceField(scope, "signal", FINDING_SIGNALS, REQUIRED),
|
|
740
|
-
domain: choiceField(scope, "domain", FINDING_DOMAINS, OPTIONAL),
|
|
741
|
-
extras: scope.extras
|
|
742
|
-
};
|
|
743
|
-
}
|
|
744
|
-
function readBlocker(item, field, issues) {
|
|
745
|
-
const scope = entryScope(item, field, BLOCKER_KEYS, issues);
|
|
746
|
-
if (scope === null)
|
|
535
|
+
if (!branch.startsWith(prefix) || !branch.endsWith(suffix))
|
|
747
536
|
return null;
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
artifact: stringField(scope, "artifact", OPTIONAL),
|
|
751
|
-
extras: scope.extras
|
|
752
|
-
};
|
|
537
|
+
const stub = branch.slice(prefix.length, branch.length - suffix.length);
|
|
538
|
+
return stub.startsWith(STUB_PREFIX) ? stub : null;
|
|
753
539
|
}
|
|
754
|
-
|
|
755
|
-
const scope = entryScope(item, field, BUG_KEYS, issues);
|
|
756
|
-
if (scope === null)
|
|
757
|
-
return null;
|
|
758
|
-
return {
|
|
759
|
-
what: stringField(scope, "what", REQUIRED),
|
|
760
|
-
artifact: stringField(scope, "artifact", OPTIONAL),
|
|
761
|
-
security: booleanField(scope, "security", REQUIRED),
|
|
762
|
-
extras: scope.extras
|
|
763
|
-
};
|
|
764
|
-
}
|
|
765
|
-
function readChange(item, field, issues) {
|
|
766
|
-
const scope = entryScope(item, field, CHANGE_KEYS, issues);
|
|
767
|
-
if (scope === null)
|
|
768
|
-
return null;
|
|
769
|
-
return {
|
|
770
|
-
level: choiceField(scope, "level", CHANGE_LEVELS, REQUIRED),
|
|
771
|
-
area: stringField(scope, "area", OPTIONAL),
|
|
772
|
-
summary: stringField(scope, "summary", REQUIRED),
|
|
773
|
-
extras: scope.extras
|
|
774
|
-
};
|
|
775
|
-
}
|
|
776
|
-
function readReport(document, issues) {
|
|
777
|
-
const scope = scopeOf(document, REPORT_KEYS, "", issues);
|
|
778
|
-
return {
|
|
779
|
-
status: choiceField(scope, "status", REPORT_STATUSES, REQUIRED),
|
|
780
|
-
feedback: stringField(scope, "feedback", OPTIONAL),
|
|
781
|
-
findings: listField(scope, "findings", readFinding),
|
|
782
|
-
skillsUsed: listField(scope, "skills_used", readSkill),
|
|
783
|
-
blockers: listField(scope, "blockers", readBlocker),
|
|
784
|
-
outOfScopeBugs: listField(scope, "out_of_scope_bugs", readBug),
|
|
785
|
-
changes: listField(scope, "changes", readChange),
|
|
786
|
-
extras: scope.extras
|
|
787
|
-
};
|
|
788
|
-
}
|
|
789
|
-
function parseReport(output) {
|
|
790
|
-
const reports = readRafaBlocks(output).filter((block2) => block2.kind === REPORT_KIND);
|
|
791
|
-
const block = reports.at(-1);
|
|
792
|
-
if (block === undefined) {
|
|
793
|
-
return absent("no-block", null, "the session output holds no rafa:report block");
|
|
794
|
-
}
|
|
795
|
-
const line = block.span.first;
|
|
796
|
-
if (!block.closed) {
|
|
797
|
-
return absent("unclosed-block", block, `rafa:report block at line ${line} is never closed, so its body may have been cut short ` + "and is not read");
|
|
798
|
-
}
|
|
799
|
-
let document;
|
|
800
|
-
try {
|
|
801
|
-
document = Bun.YAML.parse(block.body);
|
|
802
|
-
} catch (error) {
|
|
803
|
-
const text2 = `rafa:report block at line ${line} is not valid YAML (${messageOf2(error)})`;
|
|
804
|
-
return absent("malformed-block", block, text2);
|
|
805
|
-
}
|
|
806
|
-
if (!isMapping2(document)) {
|
|
807
|
-
const text2 = `rafa:report block at line ${line} holds ${describeValue2(document)}, ` + "not a mapping of report fields";
|
|
808
|
-
return absent("malformed-block", block, text2);
|
|
809
|
-
}
|
|
810
|
-
const issues = [];
|
|
811
|
-
const report = readReport(document, issues);
|
|
812
|
-
return { present: true, report, block, issues };
|
|
813
|
-
}
|
|
814
|
-
|
|
815
|
-
// src/adapters/output/text.ts
|
|
816
|
-
var DEBUG_VERBOSITY = 2;
|
|
817
|
-
function formatPayload(payload) {
|
|
818
|
-
return typeof payload === "string" ? payload : JSON.stringify(payload);
|
|
819
|
-
}
|
|
820
|
-
function resultLine(event) {
|
|
821
|
-
if (event.ok) {
|
|
822
|
-
return event.data === undefined ? "result: ok" : `result: ok ${formatPayload(event.data)}`;
|
|
823
|
-
}
|
|
824
|
-
const code = event.error?.code ?? "unknown";
|
|
825
|
-
const message = event.error?.message ?? "";
|
|
826
|
-
return message === "" ? `result: error ${code}` : `result: error ${code}: ${message}`;
|
|
827
|
-
}
|
|
828
|
-
function createTextOutput({ verbosity, stream }) {
|
|
829
|
-
const writeLine = (line) => {
|
|
830
|
-
stream.write(`${line}
|
|
831
|
-
`);
|
|
832
|
-
};
|
|
833
|
-
const debug = (message) => {
|
|
834
|
-
if (verbosity >= DEBUG_VERBOSITY)
|
|
835
|
-
writeLine(`debug: ${message}`);
|
|
836
|
-
};
|
|
837
|
-
const info = (message) => {
|
|
838
|
-
writeLine(message);
|
|
839
|
-
};
|
|
840
|
-
const warn = (message) => {
|
|
841
|
-
writeLine(`warn: ${message}`);
|
|
842
|
-
};
|
|
843
|
-
const error = (message) => {
|
|
844
|
-
writeLine(`error: ${message}`);
|
|
845
|
-
};
|
|
846
|
-
const result = (payload) => {
|
|
847
|
-
writeLine(`result: ${formatPayload(payload)}`);
|
|
848
|
-
};
|
|
849
|
-
const writeLog = (event) => {
|
|
850
|
-
switch (event.level) {
|
|
851
|
-
case "debug": {
|
|
852
|
-
debug(event.message);
|
|
853
|
-
return;
|
|
854
|
-
}
|
|
855
|
-
case "info": {
|
|
856
|
-
info(event.message);
|
|
857
|
-
return;
|
|
858
|
-
}
|
|
859
|
-
case "warn": {
|
|
860
|
-
warn(event.message);
|
|
861
|
-
return;
|
|
862
|
-
}
|
|
863
|
-
case "error": {
|
|
864
|
-
error(event.message);
|
|
865
|
-
return;
|
|
866
|
-
}
|
|
867
|
-
}
|
|
868
|
-
};
|
|
869
|
-
const emit = (event) => {
|
|
870
|
-
switch (event.type) {
|
|
871
|
-
case "start": {
|
|
872
|
-
writeLine(`start: ${event.command}`);
|
|
873
|
-
return;
|
|
874
|
-
}
|
|
875
|
-
case "step": {
|
|
876
|
-
writeLine(`step: ${event.name}`);
|
|
877
|
-
return;
|
|
878
|
-
}
|
|
879
|
-
case "log": {
|
|
880
|
-
writeLog(event);
|
|
881
|
-
return;
|
|
882
|
-
}
|
|
883
|
-
case "result": {
|
|
884
|
-
writeLine(resultLine(event));
|
|
885
|
-
return;
|
|
886
|
-
}
|
|
887
|
-
case "event": {
|
|
888
|
-
return;
|
|
889
|
-
}
|
|
890
|
-
}
|
|
891
|
-
};
|
|
892
|
-
return Object.freeze({ info, warn, error, debug, emit, result });
|
|
893
|
-
}
|
|
894
|
-
|
|
895
|
-
// src/core/output/active.ts
|
|
896
|
-
import { AsyncLocalStorage } from "async_hooks";
|
|
897
|
-
var scopes = new AsyncLocalStorage;
|
|
898
|
-
var DEFAULT_OUTPUT = createTextOutput({ verbosity: 0, stream: process.stdout });
|
|
899
|
-
var active = DEFAULT_OUTPUT;
|
|
900
|
-
var activeMode = "text";
|
|
901
|
-
function activeOutput() {
|
|
902
|
-
return scopes.getStore()?.output ?? active;
|
|
903
|
-
}
|
|
904
|
-
function activeOutputMode() {
|
|
905
|
-
return scopes.getStore()?.mode ?? activeMode;
|
|
906
|
-
}
|
|
907
|
-
// src/utils/plan-stamp.ts
|
|
908
|
-
var STUB_PATTERN = "[A-Za-z0-9._-]+";
|
|
909
|
-
var STAMP_PATTERN = new RegExp(`<!--\\s*ralph:plan=(${STUB_PATTERN})\\s*-->`);
|
|
910
|
-
function isStampableStub(stub) {
|
|
911
|
-
return new RegExp(`^${STUB_PATTERN}$`).test(stub);
|
|
912
|
-
}
|
|
913
|
-
function planStampLine(stub) {
|
|
914
|
-
if (!isStampableStub(stub)) {
|
|
915
|
-
throw new Error(`rafa plan stamp: unusable stub ${JSON.stringify(stub)}`);
|
|
916
|
-
}
|
|
917
|
-
return `<!-- ralph:plan=${stub} -->`;
|
|
918
|
-
}
|
|
919
|
-
function planStubFromPrompt(content) {
|
|
920
|
-
if (typeof content !== "string" || content.length === 0)
|
|
921
|
-
return null;
|
|
922
|
-
const match = STAMP_PATTERN.exec(content);
|
|
923
|
-
const stub = match?.[1];
|
|
924
|
-
return stub !== undefined && isStampableStub(stub) ? stub : null;
|
|
925
|
-
}
|
|
926
|
-
function stampPrompt(stub, prompt) {
|
|
927
|
-
return `${prompt}
|
|
928
|
-
${planStampLine(stub)}`;
|
|
929
|
-
}
|
|
930
|
-
function planStubFromPath(planPath) {
|
|
931
|
-
const base = planPath.split("/").pop() ?? planPath;
|
|
932
|
-
const match = /^PLAN(?:_TRACKER)?-(.+)\.md$/.exec(base);
|
|
933
|
-
const stub = match?.[1];
|
|
934
|
-
return stub !== undefined && isStampableStub(stub) ? stub : null;
|
|
935
|
-
}
|
|
936
|
-
|
|
937
|
-
export { MERGE_METHODS, isMergeMethod, SKILL_TIERS, RAFA_INSTINCTS_PATH, BUNDLED_SKILLS_DIR, isSkillTier, realEntry, bundledBinDirectory, skillTierDirectory, resolveSkillTiers, resolveInstinctScopes, tierExists, TEST_SCOPES, isAgentName, BUDGET_FLAG, readTestScope, parseTaskDeclaration, stripTaskDeclaration, resolveDeclarationFlags, isMapping, describeValue, messageOf, CONFIG_VERSIONS, STORE_BACKENDS, SYNC_STRATEGIES, BOARD_RELATIONSHIP_MODES, INJECT_MODES, OUTPUT_MODES, CLAUDE_SETTING_SOURCES, PR_PROVIDERS, RELEASE_AUTO, SKILL_RESOLVERS, CLAIMS_STALE_DISABLED, refused, refusedWith, mapReading, below, oneOf, text, flag, mergeMethod, usdAmount, issueNumber, dayCount, BUSY_TIMEOUT_MIN_MS, BUSY_TIMEOUT_MAX_MS, isBusyTimeoutMs, busyTimeoutMs, confidence, recurrenceCount, releaseEnabled, tierSwitch, skillResolverName, lessonSwitch, claimDurationHours, claimsStaleAfter, claimsAhead, isGitHubLogin, githubLogin, BOARD_PROJECT_TEMPLATE_DEFAULT, projectUrl, projectNumber, listOf, subsetOf, mapOf, directory, trackerKind, releaseFile, tierPins, routeTable, releaseStrategy, releaseSettleMode, releaseTagMode, versionCollisionMode, fragmentsDirectory, createTextOutput, activeOutput, activeOutputMode, RAFA_BLOCK_KINDS, isRafaBlockKind, readRafaBlocks, REPORT_STATUSES, FINDING_KINDS, FINDING_SIGNALS, FINDING_DOMAINS, CHANGE_LEVELS, parseReport, isStampableStub, planStubFromPrompt, stampPrompt, planStubFromPath };
|
|
540
|
+
export { SKILL_TIERS, RAFA_INSTINCTS_PATH, BUNDLED_SKILLS_DIR, isSkillTier, realEntry, bundledBinDirectory, skillTierDirectory, resolveSkillTiers, resolveInstinctScopes, tierExists, TEST_SCOPES, isAgentName, BUDGET_FLAG, readTestScope, readDocsRole, parseTaskDeclaration, stripTaskDeclaration, resolveDeclarationFlags, isMapping, describeValue, messageOf, CONFIG_VERSIONS, STORE_BACKENDS, SYNC_STRATEGIES, BOARD_RELATIONSHIP_MODES, INJECT_MODES, OUTPUT_MODES, CLAUDE_SETTING_SOURCES, PR_PROVIDERS, RELEASE_AUTO, DUPLICATE_LEVELS, SKILL_RESOLVERS, CLAIMS_STALE_DISABLED, refused, refusedWith, mapReading, below, oneOf, text, flag, usdAmount, issueNumber, dayCount, BUSY_TIMEOUT_MIN_MS, BUSY_TIMEOUT_MAX_MS, isBusyTimeoutMs, busyTimeoutMs, confidence, recurrenceCount, releaseEnabled, duplicatesLevel, tierSwitch, skillResolverName, lessonSwitch, claimDurationHours, claimsStaleAfter, claimsAhead, isGitHubLogin, githubLogin, BOARD_PROJECT_TEMPLATE_DEFAULT, projectUrl, projectNumber, listOf, subsetOf, mapOf, directory, trackerKind, releaseFile, tierPins, routeTable, releaseStrategy, releaseSettleMode, releaseTagMode, releasePublishMode, versionCollisionMode, fragmentsDirectory, BRANCH_STUB, DEFAULT_BRANCH_TEMPLATE, isBranchTemplate, branchTemplate, branchFromTemplate, branchGlob, stubOfBranch };
|