@open-tomato/rafa 0.17.0 → 0.19.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.
Files changed (33) hide show
  1. package/NOTICE +9 -1
  2. package/README.md +40 -26
  3. package/dist/PROMPT.md +2 -1
  4. package/dist/bundled/agents/build-error-resolver.md +144 -0
  5. package/dist/bundled/agents/code-reviewer.md +335 -0
  6. package/dist/bundled/agents/doc-updater.md +108 -0
  7. package/dist/bundled/agents/loop-implementer.md +57 -0
  8. package/dist/bundled/agents/qa-bug-reporter.md +164 -0
  9. package/dist/bundled/agents/tdd-guide.md +121 -0
  10. package/dist/bundled/bin/ts-symbols +272 -0
  11. package/dist/{SKILL.md → bundled/skills/dev-planner/SKILL.md} +7 -5
  12. package/dist/bundled/skills/documentation/SKILL.md +93 -0
  13. package/dist/bundled/skills/git-workflow/SKILL.md +242 -0
  14. package/dist/bundled/skills/ts-symbols/SKILL.md +82 -0
  15. package/dist/cli.js +6952 -4721
  16. package/dist/{describe-wbn759vf.js → describe-cenk70n5.js} +4 -3
  17. package/dist/effort/store/index.js +6 -4
  18. package/dist/{index-64wec0k7.js → index-09p41s0n.js} +11 -224
  19. package/dist/{index-qzhpqmfy.js → index-c5cecsga.js} +2 -2
  20. package/dist/{index-4qd537z6.js → index-ca0fccvr.js} +3527 -1402
  21. package/dist/{index-n3rw8rhr.js → index-cedghpva.js} +78 -2
  22. package/dist/index-d6d0942q.js +218 -0
  23. package/dist/{index-7t0qz29r.js → index-gb51x34c.js} +1020 -58
  24. package/dist/{index-r7cnr44m.js → index-mh5hyw8g.js} +1681 -3101
  25. package/dist/index-pqrpcfaz.js +1020 -0
  26. package/dist/{index-p901zs2p.js → index-vg7ycs94.js} +1 -1
  27. package/dist/index-wp8c28fd.js +18 -0
  28. package/dist/index.js +13 -11
  29. package/dist/learning/index.js +25 -0
  30. package/dist/plan/index.js +8 -7
  31. package/dist/plan-prompt.md +2 -0
  32. package/package.json +4 -3
  33. package/dist/index-ps5sac9p.js +0 -531
@@ -1,531 +0,0 @@
1
- // @bun
2
- import {
3
- CLAUDE_SETTING_SOURCES,
4
- CONFIG_VERSIONS,
5
- INJECT_MODES,
6
- MODULE_SOURCE_KEYS,
7
- OPTIONAL_ITEM_KEYS,
8
- OUTPUT_MODES,
9
- PR_PROVIDERS,
10
- RELEASE_AUTO,
11
- REQUIRED_ITEM_KEYS,
12
- STORE_BACKENDS,
13
- dayCount,
14
- describeValue,
15
- flag,
16
- githubLogin,
17
- isMapping,
18
- issueNumber,
19
- listOf,
20
- mergeMethod,
21
- messageOf,
22
- moduleSource,
23
- oneOf,
24
- optionalPrerequisite,
25
- releaseEnabled,
26
- requiredPrerequisite,
27
- subsetOf,
28
- text,
29
- usdAmount
30
- } from "./index-n3rw8rhr.js";
31
-
32
- // src/config-schema.ts
33
- import { join } from "path";
34
- var CONFIG_FILE = join(".rafa", "config.yaml");
35
- var CONFIG_DEFAULTS = Object.freeze({
36
- version: 1,
37
- store: "sqlite",
38
- inject: "stage",
39
- planDir: join(".rafa", "plans"),
40
- specsDir: join(".rafa", "specs"),
41
- trackerDefault: "github",
42
- trackerFallback: Object.freeze(["local"]),
43
- learningAdapter: "local",
44
- outputMode: "text",
45
- prerequisitesRequired: Object.freeze([]),
46
- prerequisitesOptional: Object.freeze([]),
47
- trackingSpecs: false,
48
- trackingPlans: false,
49
- trackingAll: false,
50
- modules: Object.freeze([]),
51
- allowList: Object.freeze([]),
52
- settingSources: Object.freeze(["project", "local"]),
53
- prProvider: null,
54
- prMergeMethod: "squash",
55
- prBase: null,
56
- prResolveBudget: 2,
57
- boardTrustedAuthors: Object.freeze([]),
58
- roadmapIssue: null,
59
- releaseEnabled: RELEASE_AUTO,
60
- releaseVersionFile: "package.json",
61
- releaseChangelog: "CHANGELOG.md",
62
- releaseHeading: "## {version} \u2014 {date}, {title}",
63
- cleanupStaleDays: 30,
64
- cleanupWorktreeIdleDays: 7,
65
- cleanupKeep: Object.freeze([]),
66
- dangerousAcceptStaleRefs: false,
67
- statusNotice: true
68
- });
69
- var directory = text("a directory path");
70
- var trackerKind = text("a tracker kind name");
71
- var releaseFile = text("a file path");
72
- var SETTINGS = {
73
- version: { key: "version", read: oneOf(CONFIG_VERSIONS), cli: false },
74
- store: { key: "store", read: oneOf(STORE_BACKENDS), cli: true },
75
- inject: { key: "plan.inject", read: oneOf(INJECT_MODES), cli: true },
76
- planDir: { key: "plan.dir", read: directory, cli: true },
77
- specsDir: { key: "specs.dir", read: directory, cli: true },
78
- trackerDefault: { key: "tracker.default", read: trackerKind, cli: true },
79
- trackerFallback: {
80
- key: "tracker.fallback",
81
- read: listOf(trackerKind, "tracker kind names"),
82
- cli: false
83
- },
84
- learningAdapter: {
85
- key: "learning.adapter",
86
- read: text("a learning adapter name"),
87
- cli: true
88
- },
89
- outputMode: { key: "output.mode", read: oneOf(OUTPUT_MODES), cli: true },
90
- prerequisitesRequired: {
91
- key: "prerequisites.required",
92
- read: listOf(requiredPrerequisite, "prerequisite items"),
93
- cli: false,
94
- itemKeys: REQUIRED_ITEM_KEYS
95
- },
96
- prerequisitesOptional: {
97
- key: "prerequisites.optional",
98
- read: listOf(optionalPrerequisite, "prerequisite items"),
99
- cli: false,
100
- itemKeys: OPTIONAL_ITEM_KEYS
101
- },
102
- trackingSpecs: { key: "tracking.specs", read: flag, cli: false },
103
- trackingPlans: { key: "tracking.plans", read: flag, cli: false },
104
- trackingAll: { key: "tracking.all", read: flag, cli: false },
105
- modules: {
106
- key: "modules",
107
- read: listOf(moduleSource, "module sources"),
108
- cli: false,
109
- itemKeys: MODULE_SOURCE_KEYS
110
- },
111
- allowList: {
112
- key: "allowList",
113
- read: listOf(text("a module name"), "module names"),
114
- cli: false
115
- },
116
- settingSources: {
117
- key: "loop.settingSources",
118
- read: subsetOf(CLAUDE_SETTING_SOURCES),
119
- cli: true
120
- },
121
- prProvider: { key: "pr.provider", read: oneOf(PR_PROVIDERS), cli: false },
122
- prMergeMethod: { key: "pr.mergeMethod", read: mergeMethod, cli: false },
123
- prBase: { key: "pr.base", read: text("a branch name"), cli: false },
124
- prResolveBudget: { key: "pr.resolveBudget", read: usdAmount, cli: false },
125
- boardTrustedAuthors: {
126
- key: "board.trustedAuthors",
127
- read: listOf(githubLogin, "GitHub logins"),
128
- cli: false
129
- },
130
- roadmapIssue: { key: "roadmap.issue", read: issueNumber, cli: false },
131
- releaseEnabled: { key: "release.enabled", read: releaseEnabled, cli: false },
132
- releaseVersionFile: {
133
- key: "release.versionFile",
134
- read: releaseFile,
135
- cli: false
136
- },
137
- releaseChangelog: { key: "release.changelog", read: releaseFile, cli: false },
138
- releaseHeading: {
139
- key: "release.heading",
140
- read: text("a changelog heading template"),
141
- cli: false
142
- },
143
- cleanupStaleDays: { key: "cleanup.staleDays", read: dayCount, cli: false },
144
- cleanupWorktreeIdleDays: {
145
- key: "cleanup.worktreeIdleDays",
146
- read: dayCount,
147
- cli: false
148
- },
149
- cleanupKeep: {
150
- key: "cleanup.keep",
151
- read: listOf(text("a glob pattern"), "glob patterns"),
152
- cli: false
153
- },
154
- dangerousAcceptStaleRefs: {
155
- key: "dangerous.acceptStaleRefs",
156
- read: flag,
157
- cli: false
158
- },
159
- statusNotice: { key: "status.notice", read: flag, cli: false }
160
- };
161
- var SETTING_NAMES = Object.keys(SETTINGS);
162
- var SETTING_BY_KEY = new Map(SETTING_NAMES.map((setting) => [
163
- SETTINGS[setting].key,
164
- setting
165
- ]));
166
- function isCommandLineSetting(setting) {
167
- return SETTINGS[setting].cli;
168
- }
169
- function sectionsOf(key) {
170
- const parts = key.split(".");
171
- return parts.slice(1).map((_, index) => parts.slice(0, index + 1).join("."));
172
- }
173
- var SECTIONS = new Set([...SETTING_BY_KEY.keys()].flatMap(sectionsOf));
174
- function parentOf(key) {
175
- const cut = key.lastIndexOf(".");
176
- return cut < 0 ? "" : key.slice(0, cut);
177
- }
178
- var TRAILING_INDEX = /\[\d+\]$/;
179
- var KNOWN_UNDER = (() => {
180
- const known = new Map;
181
- const add = (parent, name) => {
182
- const names = known.get(parent) ?? [];
183
- if (!names.includes(name))
184
- known.set(parent, [...names, name]);
185
- };
186
- for (const setting of SETTING_NAMES) {
187
- const { key, itemKeys } = SETTINGS[setting];
188
- const parts = key.split(".");
189
- parts.forEach((part, index) => add(parts.slice(0, index).join("."), part));
190
- for (const name of itemKeys ?? [])
191
- add(`${key}[]`, name);
192
- }
193
- return known;
194
- })();
195
- function knownKeysAbove(key) {
196
- for (let parent = parentOf(key);parent !== ""; parent = parentOf(parent)) {
197
- const names = KNOWN_UNDER.get(parent.replace(TRAILING_INDEX, "[]"));
198
- if (names !== undefined)
199
- return [parent, names];
200
- }
201
- return ["", KNOWN_UNDER.get("") ?? []];
202
- }
203
-
204
- // src/config.ts
205
- import { join as join2 } from "path";
206
- class ConfigError extends Error {
207
- problems;
208
- constructor(problems, options) {
209
- super(`rafa config: ${problems.join("; ")}`, options);
210
- this.name = "ConfigError";
211
- this.problems = problems;
212
- }
213
- }
214
- function readLayer(rawOf, atOf) {
215
- const problems = [];
216
- const extras = [];
217
- const read = (setting) => {
218
- const raw = rawOf(setting);
219
- if (raw === undefined)
220
- return;
221
- const reading = SETTINGS[setting].read(raw, atOf(setting));
222
- problems.push(...reading.problems);
223
- extras.push(...reading.extras);
224
- return reading.value;
225
- };
226
- const layer = {
227
- version: read("version"),
228
- store: read("store"),
229
- inject: read("inject"),
230
- planDir: read("planDir"),
231
- specsDir: read("specsDir"),
232
- trackerDefault: read("trackerDefault"),
233
- trackerFallback: read("trackerFallback"),
234
- learningAdapter: read("learningAdapter"),
235
- outputMode: read("outputMode"),
236
- prerequisitesRequired: read("prerequisitesRequired"),
237
- prerequisitesOptional: read("prerequisitesOptional"),
238
- trackingSpecs: read("trackingSpecs"),
239
- trackingPlans: read("trackingPlans"),
240
- trackingAll: read("trackingAll"),
241
- modules: read("modules"),
242
- allowList: read("allowList"),
243
- settingSources: read("settingSources"),
244
- prProvider: read("prProvider"),
245
- prMergeMethod: read("prMergeMethod"),
246
- prBase: read("prBase"),
247
- prResolveBudget: read("prResolveBudget"),
248
- boardTrustedAuthors: read("boardTrustedAuthors"),
249
- roadmapIssue: read("roadmapIssue"),
250
- releaseEnabled: read("releaseEnabled"),
251
- releaseVersionFile: read("releaseVersionFile"),
252
- releaseChangelog: read("releaseChangelog"),
253
- releaseHeading: read("releaseHeading"),
254
- cleanupStaleDays: read("cleanupStaleDays"),
255
- cleanupWorktreeIdleDays: read("cleanupWorktreeIdleDays"),
256
- cleanupKeep: read("cleanupKeep"),
257
- dangerousAcceptStaleRefs: read("dangerousAcceptStaleRefs"),
258
- statusNotice: read("statusNotice")
259
- };
260
- return { layer, problems, extras };
261
- }
262
- function* entriesOf(mapping, prefix) {
263
- for (const [name, value] of Object.entries(mapping)) {
264
- const key = prefix === "" ? name : `${prefix}.${name}`;
265
- if (SECTIONS.has(key) && isMapping(value))
266
- yield* entriesOf(value, key);
267
- else
268
- yield { key, value };
269
- }
270
- }
271
- function sortKeys(document, path) {
272
- const named = new Map;
273
- const seen = new Set;
274
- const extras = [];
275
- const problems = [];
276
- for (const entry of entriesOf(document, "")) {
277
- const setting = SETTING_BY_KEY.get(entry.key);
278
- if (setting !== undefined) {
279
- if (seen.has(setting)) {
280
- problems.push(`${path}: ${entry.key} is given more than once`);
281
- } else if (entry.value !== null) {
282
- named.set(setting, entry.value);
283
- }
284
- seen.add(setting);
285
- continue;
286
- }
287
- if (!SECTIONS.has(entry.key)) {
288
- extras.push(entry);
289
- continue;
290
- }
291
- if (entry.value !== null) {
292
- const found = describeValue(entry.value);
293
- problems.push(`${path}: ${entry.key} must be a mapping, found ${found}`);
294
- }
295
- }
296
- return { named, extras, problems };
297
- }
298
- function parseYaml(text2, path) {
299
- try {
300
- return Bun.YAML.parse(text2);
301
- } catch (error) {
302
- const problem = `${path}: not valid YAML (${messageOf(error)})`;
303
- throw new ConfigError([problem], { cause: error });
304
- }
305
- }
306
- function configFilePath(root) {
307
- return join2(root, CONFIG_FILE);
308
- }
309
- function parseConfigText(text2, path) {
310
- const document = parseYaml(text2, path) ?? {};
311
- if (!isMapping(document)) {
312
- const found = describeValue(document);
313
- throw new ConfigError([
314
- `${path}: expected a mapping at the top level, found ${found}`
315
- ]);
316
- }
317
- const sorted = sortKeys(document, path);
318
- const read = readLayer((setting) => sorted.named.get(setting), (setting) => ({
319
- label: `${path}: ${SETTINGS[setting].key}`,
320
- key: SETTINGS[setting].key
321
- }));
322
- const all = [...sorted.problems, ...read.problems];
323
- if (all.length > 0)
324
- throw new ConfigError(all);
325
- return { path, values: read.layer, extras: [...sorted.extras, ...read.extras] };
326
- }
327
- function unknownKeyWarning(key, path) {
328
- const quoted = JSON.stringify(key);
329
- const [under, names] = knownKeysAbove(key);
330
- const where = under === "" ? "" : ` under ${under}`;
331
- return `rafa config: unknown key ${quoted} in ${path} has no effect ` + `in this version (known keys${where}: ${names.join(", ")})`;
332
- }
333
- function resolveConfig(layers = {}) {
334
- const file = layers.file ?? null;
335
- const user = layers.user ?? null;
336
- const overrides = layers.cli ?? {};
337
- const { layer: cli, problems } = readLayer((setting) => isCommandLineSetting(setting) ? overrides[setting] : undefined, (setting) => ({ label: `command line: ${setting}`, key: setting }));
338
- if (problems.length > 0)
339
- throw new ConfigError(problems);
340
- const rank = (setting) => {
341
- const fromCli = cli[setting];
342
- if (fromCli !== undefined)
343
- return { value: fromCli, source: "cli" };
344
- const fromFile = file?.values[setting];
345
- if (fromFile !== undefined)
346
- return { value: fromFile, source: "file" };
347
- const fromUser = user?.values[setting];
348
- if (fromUser !== undefined)
349
- return { value: fromUser, source: "user" };
350
- return { value: CONFIG_DEFAULTS[setting], source: "default" };
351
- };
352
- const ranked = SETTING_NAMES.map((setting) => [setting, rank(setting)]);
353
- const warnings = [user, file].flatMap((layer) => layer === null ? [] : layer.extras.map((extra) => unknownKeyWarning(extra.key, layer.path)));
354
- return {
355
- config: Object.fromEntries(ranked.map(([setting, { value }]) => [setting, value])),
356
- sources: Object.fromEntries(ranked.map(([setting, { source }]) => [setting, source])),
357
- path: file?.path ?? null,
358
- userPath: user?.path ?? null,
359
- extras: file?.extras ?? [],
360
- userExtras: user?.extras ?? [],
361
- warnings
362
- };
363
- }
364
-
365
- // src/plan/blocks.ts
366
- var RAFA_BLOCK_KINDS = [
367
- "plan",
368
- "context",
369
- "stage-context",
370
- "report"
371
- ];
372
- var RAFA_PREFIX = "rafa:";
373
- var FENCE_RUN = /^( {0,3})(`{3,}|~{3,})/;
374
- var CLOSING_FENCE = /^ {0,3}(`{3,}|~{3,})[ \t]*$/;
375
- function isRafaBlockKind(kind) {
376
- return RAFA_BLOCK_KINDS.includes(kind);
377
- }
378
- function linesOf(markdown) {
379
- const lines = markdown.split(`
380
- `);
381
- if (lines[lines.length - 1] === "")
382
- lines.pop();
383
- return lines.map((line) => line.endsWith("\r") ? line.slice(0, -1) : line);
384
- }
385
- function kindOf(info) {
386
- const word = info.trim().split(/\s+/)[0] ?? "";
387
- return word.startsWith(RAFA_PREFIX) ? word.slice(RAFA_PREFIX.length) : null;
388
- }
389
- function openingFence(line) {
390
- const match = FENCE_RUN.exec(line);
391
- const opener = match?.[0];
392
- const indent = match?.[1];
393
- const run = match?.[2];
394
- if (opener === undefined || indent === undefined || run === undefined) {
395
- return null;
396
- }
397
- const marker = run.charAt(0);
398
- const info = line.slice(opener.length);
399
- if (marker === "`" && info.includes("`"))
400
- return null;
401
- return { marker, length: run.length, indent: indent.length, kind: kindOf(info) };
402
- }
403
- function closes(line, fence) {
404
- const run = CLOSING_FENCE.exec(line)?.[1];
405
- return run !== undefined && run.charAt(0) === fence.marker && run.length >= fence.length;
406
- }
407
- function closingIndex(lines, from, fence) {
408
- for (let index = from;index < lines.length; index += 1) {
409
- if (closes(lines[index] ?? "", fence))
410
- return index;
411
- }
412
- return lines.length;
413
- }
414
- function dedent(line, indent) {
415
- let cut = 0;
416
- while (cut < indent && line.charAt(cut) === " ")
417
- cut += 1;
418
- return line.slice(cut);
419
- }
420
- function readRafaBlocks(markdown) {
421
- const lines = linesOf(markdown);
422
- const blocks = [];
423
- let index = 0;
424
- while (index < lines.length) {
425
- const fence = openingFence(lines[index] ?? "");
426
- if (fence === null) {
427
- index += 1;
428
- continue;
429
- }
430
- const closing = closingIndex(lines, index + 1, fence);
431
- const closed = closing < lines.length;
432
- if (fence.kind !== null) {
433
- const body = lines.slice(index + 1, closing).map((line) => dedent(line, fence.indent)).join(`
434
- `);
435
- const last = closed ? closing + 1 : lines.length;
436
- blocks.push({ kind: fence.kind, body, span: { first: index + 1, last }, closed });
437
- }
438
- index = closing + 1;
439
- }
440
- return blocks;
441
- }
442
-
443
- // src/adapters/output/text.ts
444
- var DEBUG_VERBOSITY = 2;
445
- function formatPayload(payload) {
446
- return typeof payload === "string" ? payload : JSON.stringify(payload);
447
- }
448
- function resultLine(event) {
449
- if (event.ok) {
450
- return event.data === undefined ? "result: ok" : `result: ok ${formatPayload(event.data)}`;
451
- }
452
- const code = event.error?.code ?? "unknown";
453
- const message = event.error?.message ?? "";
454
- return message === "" ? `result: error ${code}` : `result: error ${code}: ${message}`;
455
- }
456
- function createTextOutput({ verbosity, stream }) {
457
- const writeLine = (line) => {
458
- stream.write(`${line}
459
- `);
460
- };
461
- const debug = (message) => {
462
- if (verbosity >= DEBUG_VERBOSITY)
463
- writeLine(`debug: ${message}`);
464
- };
465
- const info = (message) => {
466
- writeLine(message);
467
- };
468
- const warn = (message) => {
469
- writeLine(`warn: ${message}`);
470
- };
471
- const error = (message) => {
472
- writeLine(`error: ${message}`);
473
- };
474
- const result = (payload) => {
475
- writeLine(`result: ${formatPayload(payload)}`);
476
- };
477
- const writeLog = (event) => {
478
- switch (event.level) {
479
- case "debug": {
480
- debug(event.message);
481
- return;
482
- }
483
- case "info": {
484
- info(event.message);
485
- return;
486
- }
487
- case "warn": {
488
- warn(event.message);
489
- return;
490
- }
491
- case "error": {
492
- error(event.message);
493
- return;
494
- }
495
- }
496
- };
497
- const emit = (event) => {
498
- switch (event.type) {
499
- case "start": {
500
- writeLine(`start: ${event.command}`);
501
- return;
502
- }
503
- case "step": {
504
- writeLine(`step: ${event.name}`);
505
- return;
506
- }
507
- case "log": {
508
- writeLog(event);
509
- return;
510
- }
511
- case "result": {
512
- writeLine(resultLine(event));
513
- return;
514
- }
515
- }
516
- };
517
- return Object.freeze({ info, warn, error, debug, emit, result });
518
- }
519
-
520
- // src/adapters/output/active.ts
521
- var DEFAULT_OUTPUT = createTextOutput({ verbosity: 0, stream: process.stdout });
522
- var active = DEFAULT_OUTPUT;
523
- var activeMode = "text";
524
- function activeOutput() {
525
- return active;
526
- }
527
- function activeOutputMode() {
528
- return activeMode;
529
- }
530
-
531
- export { CONFIG_FILE, CONFIG_DEFAULTS, SETTINGS, ConfigError, configFilePath, parseConfigText, resolveConfig, createTextOutput, activeOutput, activeOutputMode, RAFA_BLOCK_KINDS, isRafaBlockKind, readRafaBlocks };