@open-tomato/rafa 0.44.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.
Files changed (142) hide show
  1. package/README.md +280 -42
  2. package/dist/PROMPT.md +18 -1
  3. package/dist/adapters/logger/settings.d.ts +132 -0
  4. package/dist/bugs/closest.d.ts +19 -0
  5. package/dist/bugs/fenced.d.ts +8 -0
  6. package/dist/bugs/places.d.ts +20 -0
  7. package/dist/bugs/record.d.ts +145 -0
  8. package/dist/bugs/title.d.ts +83 -0
  9. package/dist/bundled/agents/doc-updater.md +17 -3
  10. package/dist/bundled/agents/loop-implementer.md +14 -2
  11. package/dist/bundled/operators/skills/rafa-stretch-pit-stop/SKILL.md +10 -3
  12. package/dist/bundled/operators/skills/rafa-stretch-sweep/SKILL.md +5 -0
  13. package/dist/bundled/skills/dev-planner/SKILL.md +120 -24
  14. package/dist/bundled/skills/documentation/SKILL.md +2 -12
  15. package/dist/cli.js +72387 -59411
  16. package/dist/config/entry.d.ts +119 -0
  17. package/dist/config/index.d.ts +36 -0
  18. package/dist/config/index.js +51 -0
  19. package/dist/config/shape.d.ts +232 -0
  20. package/dist/config-registry.d.ts +127 -0
  21. package/dist/config-schema-board-project.d.ts +157 -0
  22. package/dist/config-schema-bugs.d.ts +71 -0
  23. package/dist/config-schema-errors.d.ts +54 -0
  24. package/dist/config-schema-features.d.ts +64 -0
  25. package/dist/config-schema-hub.d.ts +150 -0
  26. package/dist/config-schema-issues.d.ts +95 -0
  27. package/dist/config-schema-logger.d.ts +91 -0
  28. package/dist/config-schema-loop-continue.d.ts +122 -0
  29. package/dist/config-schema-loop-retries.d.ts +94 -0
  30. package/dist/config-schema-release.d.ts +307 -0
  31. package/dist/config-schema-tests.d.ts +170 -0
  32. package/dist/config-schema-triage.d.ts +142 -0
  33. package/dist/config-schema-wrap-up.d.ts +96 -0
  34. package/dist/core/command/command.d.ts +228 -0
  35. package/dist/core/command/confirm.d.ts +67 -0
  36. package/dist/core/command/index.d.ts +112 -0
  37. package/dist/core/command/lazy.d.ts +54 -0
  38. package/dist/core/command/registry-types.d.ts +96 -0
  39. package/dist/core/command/running.d.ts +96 -0
  40. package/dist/core/command/spends.d.ts +39 -0
  41. package/dist/core/command/types.d.ts +92 -0
  42. package/dist/core/command/version.d.ts +4 -0
  43. package/dist/core/config/branch-template.d.ts +20 -0
  44. package/dist/core/config/config-items.d.ts +86 -0
  45. package/dist/core/config/config-load.d.ts +47 -0
  46. package/dist/core/config/config-origins.d.ts +57 -0
  47. package/dist/core/config/config-readers.d.ts +167 -0
  48. package/dist/core/config/config-schema.d.ts +207 -0
  49. package/dist/core/config/config-sections.d.ts +493 -0
  50. package/dist/core/config/config.d.ts +320 -0
  51. package/dist/core/config/core-section.d.ts +39 -0
  52. package/dist/core/config/dangerous.d.ts +58 -0
  53. package/dist/core/config/default-routing.d.ts +16 -0
  54. package/dist/core/config/index.d.ts +141 -0
  55. package/dist/core/config/scope.d.ts +42 -0
  56. package/dist/core/config/section.d.ts +206 -0
  57. package/dist/core/config/sections.d.ts +45 -0
  58. package/dist/core/config/standard-schema.d.ts +27 -0
  59. package/dist/core/git/commit.d.ts +232 -0
  60. package/dist/core/git/gh-runner.d.ts +24 -0
  61. package/dist/core/git/git.d.ts +22 -0
  62. package/dist/core/git/index.d.ts +85 -0
  63. package/dist/core/loop/claude.d.ts +388 -0
  64. package/dist/core/loop/hop-record.d.ts +52 -0
  65. package/dist/core/loop/index.d.ts +179 -0
  66. package/dist/core/loop/session-env.d.ts +20 -0
  67. package/dist/core/loop/session-record-parse.d.ts +63 -0
  68. package/dist/core/loop/sessions.d.ts +408 -0
  69. package/dist/core/loop/suite-failure.d.ts +25 -0
  70. package/dist/core/output/active.d.ts +100 -0
  71. package/dist/core/output/stream.d.ts +20 -0
  72. package/dist/core/output/text.d.ts +55 -0
  73. package/dist/core/plan/block-reader.d.ts +46 -0
  74. package/dist/core/plan/blocks.d.ts +139 -0
  75. package/dist/core/plan/declaration.d.ts +366 -0
  76. package/dist/core/plan/plan-stamp.d.ts +75 -0
  77. package/dist/core/runtime/identity.d.ts +21 -0
  78. package/dist/core/runtime/index.d.ts +46 -0
  79. package/dist/effort/store/bring-forward.d.ts +131 -0
  80. package/dist/effort/store/check-rows.d.ts +31 -0
  81. package/dist/effort/store/commit-stats.d.ts +42 -0
  82. package/dist/effort/store/copy.d.ts +35 -0
  83. package/dist/effort/store/development-build.d.ts +105 -0
  84. package/dist/effort/store/effort-levels.d.ts +13 -0
  85. package/dist/effort/store/findings.d.ts +214 -0
  86. package/dist/effort/store/fix-schema.d.ts +184 -0
  87. package/dist/effort/store/index.js +10 -7
  88. package/dist/effort/store/location.d.ts +44 -0
  89. package/dist/effort/store/merge-commit-gaps.d.ts +68 -0
  90. package/dist/effort/store/merge-conflicts.d.ts +91 -0
  91. package/dist/effort/store/merge-rules.d.ts +82 -0
  92. package/dist/effort/store/merge-store.d.ts +211 -0
  93. package/dist/effort/store/merge-union.d.ts +92 -0
  94. package/dist/effort/store/migrate.d.ts +146 -0
  95. package/dist/effort/store/migrations.d.ts +92 -0
  96. package/dist/effort/store/ndjson-files.d.ts +114 -0
  97. package/dist/effort/store/origins.d.ts +116 -0
  98. package/dist/effort/store/plan-stubs.d.ts +79 -0
  99. package/dist/effort/store/rebuild-aside.d.ts +172 -0
  100. package/dist/effort/store/schema-plan.d.ts +102 -0
  101. package/dist/effort/store/session-row-types.d.ts +64 -0
  102. package/dist/effort/store/settings.d.ts +13 -0
  103. package/dist/effort/store/sqlite.d.ts +340 -0
  104. package/dist/effort/store/store-generation.d.ts +17 -0
  105. package/dist/effort/store/store-identity.d.ts +220 -0
  106. package/dist/effort/store/store-meta.d.ts +305 -0
  107. package/dist/effort/store/store-replaced.d.ts +72 -0
  108. package/dist/effort/store/types.d.ts +223 -0
  109. package/dist/errors/codes.d.ts +56 -0
  110. package/dist/errors/rafa-codes.d.ts +36 -0
  111. package/dist/index-2a7nb3an.js +125 -0
  112. package/dist/{index-57mmzkcn.js → index-39kbcw68.js} +516 -217
  113. package/dist/{index-nv34ptht.js → index-77ajfffn.js} +14 -9
  114. package/dist/index-cy98y87p.js +2597 -0
  115. package/dist/index-gqz4jn6j.js +13447 -0
  116. package/dist/index-gvek4r8m.js +710 -0
  117. package/dist/index-j4k2vdz3.js +1125 -0
  118. package/dist/index-jh1r4kcn.js +1067 -0
  119. package/dist/index-ykggr043.js +540 -0
  120. package/dist/index-z1w83f81.js +4 -0
  121. package/dist/index.js +16091 -22798
  122. package/dist/learning/index.js +5 -6
  123. package/dist/plan/index.js +12 -11
  124. package/dist/plan-prompt.md +11 -2
  125. package/dist/ports/index.d.ts +732 -0
  126. package/dist/ports/learning.d.ts +101 -0
  127. package/dist/ports/log-level.d.ts +13 -0
  128. package/dist/ports/spec-review.d.ts +66 -0
  129. package/dist/pr/checks.d.ts +133 -0
  130. package/dist/pr/types.d.ts +422 -0
  131. package/dist/ready-4f8edezt.js +2016 -0
  132. package/dist/release-templates/release-bot-fragment.yml +153 -0
  133. package/dist/release-templates/release-publish.yml +110 -0
  134. package/dist/release-templates/release-settle.yml +122 -0
  135. package/dist/release-templates/release-tag.yml +102 -0
  136. package/dist/report/parse.d.ts +415 -0
  137. package/dist/schema/project-id.d.ts +79 -0
  138. package/dist/schema/tiers.d.ts +107 -0
  139. package/package.json +42 -4
  140. package/dist/index-6q30dtgm.js +0 -6342
  141. package/dist/index-cknayrpc.js +0 -2414
  142. package/dist/index-hf2k497d.js +0 -16
@@ -0,0 +1,170 @@
1
+ /**
2
+ * The `tests` section of the config schema: the three settings the
3
+ * runner reads when it chooses which tests a recorded step runs, the one
4
+ * that names the contract tests, and the one that says whether a step reruns a newly red file alone, each one's
5
+ * field, its default, its spec and its reader. {@link TESTS_SECTION}
6
+ * hands them to core as one `ConfigSection`, package `tests`, and the
7
+ * `declare module` below adds {@link TestsSettings} to `RafaConfig`.
8
+ * {@link TestsShape} holds the keys a file writes, which
9
+ * `src/config/shape.ts` composes into `ConfigShape`, the nested file shape.
10
+ * `config-registry.ts`'s `CONFIG_DEFAULTS` and `SETTINGS`
11
+ * spread the objects below last, after the `task` section, so the order
12
+ * settings are reported in holds the section.
13
+ *
14
+ * The section has its own module, as `config-schema-release.ts` does,
15
+ * because `config-sections.ts` stood at 699 lines, measured with
16
+ * `wc -l`, when these keys were added, and takes nothing new under the
17
+ * 800-line cap of `context/source.md`. The one reader the four glob keys
18
+ * share, {@link globList}, is a rule about a VALUE and sits here all the
19
+ * same, for that reason. `config-registry.ts` imports this file to spread
20
+ * it; a caller reads these settings off the resolved `RafaConfig`.
21
+ *
22
+ * ## The four glob keys
23
+ *
24
+ * `.rafa/plans/PLAN-rafa-479-loop-task-sessions-run.md` names the first
25
+ * two, the plan `rafa-683-content-sweeps-lint-run` the third, and the
26
+ * plan `rafa-807-spec-monorepo-bootstrap-turbo` the fourth. Each
27
+ * is a list of glob patterns, matched against a path relative to the
28
+ * repository root, the form `git diff --name-only` answers with:
29
+ *
30
+ * - `tests.fullSuiteTriggers` names the files a task's diff runs the
31
+ * full suite for, however the task line scoped its tests. Its
32
+ * default is the five files whose change can move a test no import
33
+ * graph reaches: `bunfig.toml`, `tsconfig*.json`, `package.json`,
34
+ * `bun.lock` and `bun.lockb`. The plan adds the preload files
35
+ * `bunfig.toml`'s `[test] preload` names, and those are NOT in this
36
+ * default: a default is a value this module can spell, and which
37
+ * files a project preloads is a question about its disk, answered
38
+ * at run time by the reader of the scope. A project that sets this
39
+ * key replaces the five, and the preload files are added to its own
40
+ * list all the same.
41
+ * - `tests.integration` names the test files a stage step runs beside
42
+ * the tests under the folders the stage touched, because they drive
43
+ * the whole CLI rather than one folder's modules. Its default is the
44
+ * four spellings this repository gives such a file, in any folder:
45
+ * a name ending `-integration.test.ts` or `.integration.test.ts`,
46
+ * one holding `-spawned` and ending `.test.ts`, and one ending
47
+ * `-cli.test.ts`. Each default pattern opens with the any-folder
48
+ * prefix, two stars and a slash, which this note cannot spell
49
+ * because it would close the comment.
50
+ * - `tests.contract` names the contract tests. A contract test checks
51
+ * the promise a package makes to others, with a fixture, and runs in
52
+ * that package's own `test` task in ring 1 of CI, where a use-case
53
+ * test matching `tests.integration` runs in ring 0's full run. Its
54
+ * default is one pattern: a name ending `.contract.test.ts`, in any
55
+ * folder, under the same any-folder prefix. No step reads the key
56
+ * yet; its readers come with the CI rings that run each kind.
57
+ * - `tests.alwaysRun` names the test files a task's scoped run takes
58
+ * beside the ones `bun test --changed=<base>` selects. A content
59
+ * sweep, a test that imports no project file and reads the tree at
60
+ * run time, sits outside every import graph, so no changed file ever
61
+ * selects one. Its default is one pattern: any file under `src/`
62
+ * whose name ends `.sweep.test.ts`, the suffix this repository gives
63
+ * a content sweep. A pattern that matches no file today is accepted,
64
+ * since the sweeps it names may not have been written yet. The task
65
+ * prompt reads it (`start/task-gate-lines.ts`), naming the files it
66
+ * resolves to, and so does the runner's task step
67
+ * (`start/task-always-run.ts`), running those files beside a
68
+ * `module` or `affected` scope.
69
+ *
70
+ * An empty list is a value every glob key accepts, and means what it says:
71
+ * no file triggers the full suite beyond the preload files, a stage
72
+ * runs no integration tier, no file is a contract test, or a task runs no sweep beside its scoped
73
+ * tests. It is not read as "the default", since a list written `[]`
74
+ * has been said.
75
+ *
76
+ * ## The reader
77
+ *
78
+ * {@link globList} takes a list whose every entry is a non-empty
79
+ * string, as `cleanup.keep` does, and refuses one more entry `text`
80
+ * would take: an absolute path. The paths a pattern is matched against
81
+ * are relative to the repository root, so a pattern opening with `/`
82
+ * matches nothing, and a trigger that can never fire is the silent
83
+ * failure this key exists to prevent. No other check is made on the
84
+ * pattern: `Bun.Glob` builds a matcher from any string, so there is no
85
+ * malformed glob to refuse.
86
+ *
87
+ * ## The switch
88
+ *
89
+ * `tests.retakeRedAlone` says whether a task, stage or pre-wrap-up step
90
+ * that reads new failures reruns each newly red test file alone, once,
91
+ * before it settles (`start/suite-retake-alone.ts`). A file green alone
92
+ * was red only in the step's own file order, by state another test file
93
+ * left in the shared process, and is reported as such rather than handed
94
+ * to a repair task (issue 926: one run of 2026-10-10 inserted five repair
95
+ * tasks for a file each repair session found green). Two readings:
96
+ *
97
+ * - It defaults to `true`. The retake costs one `bun test <file>` per
98
+ * newly red file and only on a step already red, and what it saves is
99
+ * a repair session per order-dependent file. `false` switches the
100
+ * retake off and nothing else: every new failure blocks, and no file
101
+ * is run a second time. The error lines a step keeps for each failed
102
+ * case (`suite/failure-lines.ts`), on its record, in its output file
103
+ * and in its blocker, are kept either way; no key turns them off.
104
+ * - It is read through `flag` (`config-sections.ts`), a YAML boolean
105
+ * and nothing spelled like one, as `status.notice` is.
106
+ *
107
+ * No key here is a `CommandLineSetting`: four are lists, which the
108
+ * command line has no spelling for, as `config-schema.ts` says, and the
109
+ * switch is none for the reason the `pr` section gives
110
+ * (`config-schema-readings.ts`): a global flag nobody typed would be one
111
+ * this module invented.
112
+ */
113
+ import type { ConfigSection, SettingSpec } from '@open-tomato/rafa/core/config';
114
+ import type { Reader } from '@open-tomato/rafa/core/config/sections';
115
+ declare module '@open-tomato/rafa/core/config/config-schema' {
116
+ /** The `tests` section's fields, added to core's. */
117
+ interface RafaConfig extends TestsSettings {
118
+ }
119
+ }
120
+ /** The `tests` keys a file writes; `src/config/shape.ts` composes them into `ConfigShape`. */
121
+ export interface TestsShape {
122
+ readonly tests: {
123
+ readonly fullSuiteTriggers: readonly string[];
124
+ readonly integration: readonly string[];
125
+ readonly contract: readonly string[];
126
+ readonly alwaysRun: readonly string[];
127
+ readonly retakeRedAlone: boolean;
128
+ };
129
+ }
130
+ /** The `tests` section's settings, resolved. */
131
+ export interface TestsSettings {
132
+ /**
133
+ * Globs naming the files whose change runs the full suite at a task
134
+ * step, beside `bunfig.toml`'s preload files. `tests.fullSuiteTriggers`.
135
+ */
136
+ testsFullSuiteTriggers: readonly string[];
137
+ /**
138
+ * Globs naming the test files every stage step runs.
139
+ * `tests.integration`.
140
+ */
141
+ testsIntegration: readonly string[];
142
+ /**
143
+ * Globs naming the contract tests, each checking the promise a package
144
+ * makes to others. `tests.contract`.
145
+ */
146
+ testsContract: readonly string[];
147
+ /**
148
+ * Globs naming the test files a task's scoped run takes beside the
149
+ * changed-file selection. `tests.alwaysRun`.
150
+ */
151
+ testsAlwaysRun: readonly string[];
152
+ /**
153
+ * Whether a step reading new failures reruns each newly red test file
154
+ * alone, once, before it settles. `tests.retakeRedAlone`.
155
+ */
156
+ testsRetakeRedAlone: boolean;
157
+ }
158
+ /**
159
+ * The reader the four glob settings share: a list of glob patterns, each
160
+ * relative to the repository root, answered frozen in the order written.
161
+ */
162
+ export declare const globList: Reader<readonly string[]>;
163
+ /** What every `tests` setting resolves to when no layer names it. */
164
+ export declare const TESTS_DEFAULTS: Readonly<TestsSettings>;
165
+ /** The `tests` section's setting specs, in the order problems are reported. */
166
+ export declare const TESTS_SETTINGS: {
167
+ readonly [K in keyof TestsSettings]: SettingSpec<K>;
168
+ };
169
+ /** The `tests` section: the five `tests` keys, with their defaults and no check. */
170
+ export declare const TESTS_SECTION: ConfigSection;
@@ -0,0 +1,142 @@
1
+ /**
2
+ * The `triage` section of the config schema: the five settings triage
3
+ * reads when it looks for the nearest open bug a report repeats and ranks
4
+ * the ones a new bug lists, each one's field, its default, its spec and
5
+ * its reader.
6
+ * {@link TRIAGE_SECTION} hands them to core as one `ConfigSection`,
7
+ * package `triage`, and the `declare module` below adds
8
+ * {@link TriageSettings} to `RafaConfig`.
9
+ * {@link TriageShape} holds the keys a file writes, which
10
+ * `src/config/shape.ts` composes into `ConfigShape`, the nested file shape.
11
+ * `config-registry.ts`'s `CONFIG_DEFAULTS` and `SETTINGS`
12
+ * spread the objects below right after the `claims` section.
13
+ *
14
+ * The section has its own module, as `config-schema-tests.ts` and
15
+ * `config-schema-wrap-up.ts` do, because `config-schema.ts` stood at 592
16
+ * lines and `config-sections.ts` at 705, measured with `wc -l`, when
17
+ * these keys were added: the schema module's own note asks a new
18
+ * section for a sibling, and the readers are rules about a VALUE that
19
+ * only these keys read, so they sit here beside them. Only
20
+ * `config-registry.ts` imports this file; a caller reads the settings off
21
+ * the resolved `RafaConfig`.
22
+ *
23
+ * ## The five keys
24
+ *
25
+ * Step 3 of a public bug's lookup (`triage/triage.ts`) scores the
26
+ * report against each open bug by Jaccard similarity of their word
27
+ * sets, after the exact-key lookups have missed:
28
+ *
29
+ * - `triage.similarity.threshold` is the least score at which the
30
+ * nearest open bug is taken for the same bug and commented on. It
31
+ * defaults to `0.3` and accepts a number above 0 and at most 1: a
32
+ * Jaccard score lies in 0..1, so a threshold above 1 could never be
33
+ * met, and one of 0 or below would match every open bug, words
34
+ * shared or not. `false` turns step 3 off, so triage files with the
35
+ * exact-key lookups alone. `true` is refused: it names no score, and
36
+ * reading it as the default would be a choice nobody wrote.
37
+ * - `triage.similarity.candidates` is how many of the nearest open
38
+ * bugs a new bug's `Possible duplicates` section lists. It defaults
39
+ * to `3` and accepts a whole number from 1 to 10; the cap keeps that
40
+ * section short enough to read. It takes no `false`: turning step 3
41
+ * off is the threshold's to say.
42
+ * - `triage.similarity.weights.causeLeaf`, `.causeFamily` and
43
+ * `.boundary` are the bonuses `rankedCandidates`
44
+ * (`triage/similarity.ts`) adds to an open bug's word score when it
45
+ * shares the new bug's cause code, only its cause family, or its
46
+ * module and action; the sum is capped at 1 and orders the
47
+ * `Possible duplicates` list, never the same-bug decision. They
48
+ * default to `0.15`, `0.05` and `0.10` and each accepts a number from
49
+ * 0 to 1 inclusive: `0` turns its signal off, which is why it is
50
+ * accepted here and refused by the threshold, and a bonus above 1
51
+ * could only ever hit the cap. `true` and `false` are refused, as the
52
+ * threshold refuses `true`: `0` already says off.
53
+ *
54
+ * A quoted number is refused, as every other reader refuses a string
55
+ * spelled like its type. No key is a `CommandLineSetting`: the
56
+ * command line has no spelling for `false` or a number this module
57
+ * would not have to invent.
58
+ */
59
+ import type { ConfigSection, SettingSpec } from '@open-tomato/rafa/core/config';
60
+ import type { Reader } from '@open-tomato/rafa/core/config/sections';
61
+ declare module '@open-tomato/rafa/core/config/config-schema' {
62
+ /** The `triage` section's fields, added to core's. */
63
+ interface RafaConfig extends TriageSettings {
64
+ }
65
+ }
66
+ /** The `triage` keys a file writes; `src/config/shape.ts` composes them into `ConfigShape`. */
67
+ export interface TriageShape {
68
+ readonly triage: {
69
+ readonly similarity: {
70
+ readonly threshold: SimilarityThreshold;
71
+ readonly candidates: number;
72
+ readonly weights: {
73
+ readonly causeLeaf: number;
74
+ readonly causeFamily: number;
75
+ readonly boundary: number;
76
+ };
77
+ };
78
+ };
79
+ }
80
+ /** The most `triage.similarity.threshold` accepts. */
81
+ export declare const SIMILARITY_THRESHOLD_MAX = 1;
82
+ /** The least a `triage.similarity.weights.*` bonus accepts; `0` turns its signal off. */
83
+ export declare const SIMILARITY_WEIGHT_MIN = 0;
84
+ /** The most a `triage.similarity.weights.*` bonus accepts. */
85
+ export declare const SIMILARITY_WEIGHT_MAX = 1;
86
+ /** The fewest nearest issues `triage.similarity.candidates` accepts. */
87
+ export declare const SIMILARITY_CANDIDATES_MIN = 1;
88
+ /** The most nearest issues `triage.similarity.candidates` accepts. */
89
+ export declare const SIMILARITY_CANDIDATES_MAX = 10;
90
+ /**
91
+ * The least Jaccard score at which the nearest open bug is taken for the
92
+ * report's, or `false` with the similarity step turned off.
93
+ */
94
+ export type SimilarityThreshold = number | false;
95
+ /** The `triage` section's settings, resolved. */
96
+ export interface TriageSettings {
97
+ /**
98
+ * The least score at which the nearest open bug is commented on, or
99
+ * `false` to skip the similarity step. `triage.similarity.threshold`.
100
+ */
101
+ triageSimilarityThreshold: SimilarityThreshold;
102
+ /**
103
+ * How many nearest open bugs a new bug's `Possible duplicates`
104
+ * section lists. `triage.similarity.candidates`.
105
+ */
106
+ triageSimilarityCandidates: number;
107
+ /**
108
+ * The bonus an open bug with the same cause code earns in the
109
+ * `Possible duplicates` rank. `triage.similarity.weights.causeLeaf`.
110
+ */
111
+ triageSimilarityWeightsCauseLeaf: number;
112
+ /**
113
+ * The bonus an open bug with the same cause family and another leaf
114
+ * earns in that rank. `triage.similarity.weights.causeFamily`.
115
+ */
116
+ triageSimilarityWeightsCauseFamily: number;
117
+ /**
118
+ * The bonus an open bug with the same module and action earns in that
119
+ * rank. `triage.similarity.weights.boundary`.
120
+ */
121
+ triageSimilarityWeightsBoundary: number;
122
+ }
123
+ /**
124
+ * Accepts `false` or a number above 0 and at most 1, each as itself; the
125
+ * module note says why `0`, `true` and a quoted number are refused.
126
+ */
127
+ export declare const similarityThreshold: Reader<SimilarityThreshold>;
128
+ /** Accepts a whole number from 1 to 10 as itself. */
129
+ export declare const similarityCandidates: Reader<number>;
130
+ /**
131
+ * Accepts a number from 0 to 1 inclusive as itself; the module note says
132
+ * why `0` is accepted and `true`, `false` and a quoted number are refused.
133
+ */
134
+ export declare const similarityWeight: Reader<number>;
135
+ /** What every `triage` setting resolves to when no layer names it. */
136
+ export declare const TRIAGE_DEFAULTS: Readonly<TriageSettings>;
137
+ /** The `triage` section's setting specs, in the order problems are reported. */
138
+ export declare const TRIAGE_SETTINGS: {
139
+ readonly [K in keyof TriageSettings]: SettingSpec<K>;
140
+ };
141
+ /** The `triage` section: the five `triage` keys, with their defaults and no check. */
142
+ export declare const TRIAGE_SECTION: ConfigSection;
@@ -0,0 +1,96 @@
1
+ /**
2
+ * The `loop.wrapUp` section of the config schema: the one setting the
3
+ * wrap-up reads when its session ends without an open pull request, with
4
+ * its field, its default, its spec and its reader.
5
+ * {@link WRAP_UP_SECTION} hands it to core as one `ConfigSection`,
6
+ * package `wrap-up`, and the `declare module` below adds
7
+ * {@link WrapUpSettings} to `RafaConfig`.
8
+ * {@link WrapUpShape} holds its part of the shared `loop` namespace,
9
+ * which `src/config/shape.ts` composes into `LoopShape` of `ConfigShape`,
10
+ * the nested file shape.
11
+ * `config-registry.ts`'s `CONFIG_DEFAULTS` and `SETTINGS`
12
+ * spread the objects below right after `loop.worktreeDir`, so the order
13
+ * settings are reported in holds the `loop` section together.
14
+ *
15
+ * The section has its own module, as `config-schema-release.ts` and
16
+ * `config-schema-tests.ts` do, because `config-schema.ts` stood at 578
17
+ * lines and `config-sections.ts` at 642, measured with `wc -l`, when
18
+ * this key was added: the schema module's own note asks a new section
19
+ * for a sibling, and the reader is a rule about a VALUE that only this
20
+ * key reads, so it sits here beside it. `config-registry.ts` imports this
21
+ * file to spread it; a caller reads the setting off the resolved
22
+ * `RafaConfig`.
23
+ *
24
+ * ## The key
25
+ *
26
+ * `.rafa/specs/rafa-579-loop-run-ends-delivered.md` has a loop run end
27
+ * with its pull request open. When the wrap-up session ends and no pull
28
+ * request is open for the branch, the runner spawns another wrap-up
29
+ * session that is told the pull request is missing, and
30
+ * `loop.wrapUp.retries` is how many of those it spawns before opening
31
+ * the pull request itself:
32
+ *
33
+ * - It defaults to `1`: one retry session, which costs one more
34
+ * session's spend on the run that needed it and nothing on a run
35
+ * whose first wrap-up opened the pull request.
36
+ * - It accepts a whole number from 1 to 3. Each retry is a full
37
+ * session, so the cap of 3 bounds what a run whose wrap-up keeps
38
+ * missing the pull request can spend before the runner opens it.
39
+ * - `false` means no retry: the runner goes straight to opening the
40
+ * pull request itself. It is spelled `false` and not `0`, so a
41
+ * number always names sessions that run; `0` is refused, as are a
42
+ * negative number, a fraction and anything above 3. `true` is
43
+ * refused too: it names no count, and reading it as the default
44
+ * would be a choice nobody wrote.
45
+ *
46
+ * A quoted `"2"` is refused, as every other reader refuses a string
47
+ * spelled like its type. The key is not a `CommandLineSetting`: the
48
+ * command line has no spelling for `false` or a number this module
49
+ * would not have to invent.
50
+ */
51
+ import type { ConfigSection, SettingSpec } from '@open-tomato/rafa/core/config';
52
+ import type { Reader } from '@open-tomato/rafa/core/config/sections';
53
+ declare module '@open-tomato/rafa/core/config/config-schema' {
54
+ /** The `wrap-up` section's fields, added to core's. */
55
+ interface RafaConfig extends WrapUpSettings {
56
+ }
57
+ }
58
+ /**
59
+ * `loop.wrapUp.retries`, the section's part of the shared `loop`
60
+ * namespace; `src/config/shape.ts` composes it into `LoopShape`.
61
+ */
62
+ export interface WrapUpShape {
63
+ readonly wrapUp: {
64
+ readonly retries: WrapUpRetries;
65
+ };
66
+ }
67
+ /** The fewest retry sessions `loop.wrapUp.retries` accepts as a number. */
68
+ export declare const WRAP_UP_RETRIES_MIN = 1;
69
+ /** The most retry sessions `loop.wrapUp.retries` accepts. */
70
+ export declare const WRAP_UP_RETRIES_MAX = 3;
71
+ /**
72
+ * How many retry wrap-up sessions a run spawns when its wrap-up ends
73
+ * with no pull request open, or `false` for none.
74
+ */
75
+ export type WrapUpRetries = number | false;
76
+ /** The `loop.wrapUp` section's settings, resolved. */
77
+ export interface WrapUpSettings {
78
+ /**
79
+ * The retry wrap-up sessions spawned before the runner opens the pull
80
+ * request itself, or `false` for none. `loop.wrapUp.retries`.
81
+ */
82
+ loopWrapUpRetries: WrapUpRetries;
83
+ }
84
+ /**
85
+ * Accepts `false` or a whole number from 1 to 3, each as itself; the
86
+ * module note says why `0`, `true` and a quoted number are refused.
87
+ */
88
+ export declare const wrapUpRetries: Reader<WrapUpRetries>;
89
+ /** What the `loop.wrapUp` setting resolves to when no layer names it. */
90
+ export declare const WRAP_UP_DEFAULTS: Readonly<WrapUpSettings>;
91
+ /** The `loop.wrapUp` section's setting spec. */
92
+ export declare const WRAP_UP_SETTINGS: {
93
+ readonly [K in keyof WrapUpSettings]: SettingSpec<K>;
94
+ };
95
+ /** The `wrap-up` section: `loop.wrapUp.retries`, with their defaults and no check. */
96
+ export declare const WRAP_UP_SECTION: ConfigSection;
@@ -0,0 +1,228 @@
1
+ /**
2
+ * The command rafa's dispatcher routes to: `RafaCommand`, the context it
3
+ * runs with, and `CommandExit`, the one way it refuses.
4
+ *
5
+ * The CLI surface spec declares `RafaCommand` as a superset of `cli-core`'s
6
+ * `CliCommand`, so a `cli-core` command still loads. The superset is spelled
7
+ * here over the copy in `types.ts` beside this file.
8
+ *
9
+ * ## Routing keys
10
+ *
11
+ * `subject` and `action` are the words a line routes by: `rafa loop start`
12
+ * runs the command whose subject is `loop` and whose action is `start`.
13
+ * A command whose action is its subject is a top-level command, reached
14
+ * by its one word: `status`, with subject and action both `status`. That is
15
+ * open-tomato's rule for a single-token verb, which it registers with
16
+ * tool and command equal. `name` is for display, and routes nothing.
17
+ *
18
+ * ## The context
19
+ *
20
+ * {@link RafaContext} is `CliContext` plus `argv`, the words of the line
21
+ * after the last word the dispatcher routed by, as they were typed. The
22
+ * phase 0 commands read their own flags, so a wrapper hands `argv` to
23
+ * the parser it already has. `args` and `flags` are the rest of the
24
+ * line read against the command's own `args` and `flags`, flags typed
25
+ * ahead of the subject included.
26
+ *
27
+ * It also carries `registry`, the registry the dispatcher routed the line
28
+ * through, every module mounted for the invocation included. `describe`
29
+ * reads it, so the roster it gives is the dispatcher's own and never a
30
+ * second one.
31
+ *
32
+ * And it carries `project`, the project the command runs in as
33
+ * `resolveScope` answers it (`src/project/scope.ts`): its root, the home,
34
+ * and both scopes' paths. A command runs inside a project unless it
35
+ * declares `needsProject: false`. The dispatcher resolves the project
36
+ * before any other command runs, and runs none outside a project, so
37
+ * such a command's `project` is never null. For a command declaring
38
+ * `needsProject: false`, as `module exec`, `init` and `describe` do, it resolves
39
+ * nothing, and `project` is null inside a project as outside one.
40
+ *
41
+ * `run` takes a `RafaContext`, where `CliCommand.run` takes a
42
+ * `CliContext`, so the interface extends `CliCommand` without its `run`.
43
+ * A `RafaContext` is a `CliContext`, so a `run` written against
44
+ * `CliContext` is assignable to this one.
45
+ *
46
+ * ## Refusing
47
+ *
48
+ * A command refuses by throwing {@link CommandExit} with an exit code. The
49
+ * dispatcher is the only place that turns one into the process's exit
50
+ * code and the invocation's terminal event. A `process.exitCode` a
51
+ * command sets is not read, and a command setting one and returning is
52
+ * a success to the dispatcher.
53
+ *
54
+ * ## The shape check
55
+ *
56
+ * {@link commandProblem} answers what keeps a value from being a
57
+ * `RafaCommand`, for a roster the type checker never saw: a module's
58
+ * command entry is imported at run time. It checks the shape and not
59
+ * the content, so an empty `summary` or an empty `examples` list passes.
60
+ * The registry refuses a core command it answers for, and the module
61
+ * loader skips the file of a module command it answers for.
62
+ *
63
+ * `spends` is checked last, by `spendsProblem` (`spends.ts` beside this file),
64
+ * whose sentence names the field inside it: `spends.flag is "resolve",
65
+ * expected a flag as typed, starting with --`. A module entry declaring a
66
+ * malformed `spends` is therefore skipped like any other bad shape.
67
+ *
68
+ * ## Dangerous phrases
69
+ *
70
+ * `dangerous` maps a `dangerous.*` key to the phrase naming what the
71
+ * command does under it: `{ 'dangerous.acceptVersionCollision': 'a
72
+ * release guard reading collision merges anyway' }`. The dispatcher
73
+ * runs the command inside `runWithDangerousPhrases`
74
+ * (`packages/rafa/src/core/config/dangerous.ts`) with it, so a pass line the loader
75
+ * writes for a declared key during the run ends with `; <phrase>`. The
76
+ * shape check refuses a key not opening with `dangerous.` and a phrase
77
+ * that is not a non-empty string.
78
+ *
79
+ * ## Deprecated flags
80
+ *
81
+ * A flag a command declares is a {@link RafaFlagSpec}: a `FlagSpec` that
82
+ * may carry `deprecated`, naming the spelling to type instead. The
83
+ * dispatcher reads such a flag, typed bare, as that spelling and writes
84
+ * one deprecation line (`src/cli/dispatch.ts`), so
85
+ * `rafa effort report --json` runs as `rafa effort report --output=json`.
86
+ * The field is declared here rather than on `FlagSpec`, so the copy of
87
+ * `cli-core`'s contracts in `types.ts` keeps the source's shape.
88
+ */
89
+ import type { CommandRegistry } from './registry-types.js';
90
+ import type { CommandSpend } from './spends.js';
91
+ import type { CliCommand, CliContext, FlagSpec } from './types.js';
92
+ import type { DangerousPhrases } from '../config/dangerous.js';
93
+ import type { ProjectFound } from '../config/scope.js';
94
+ /** What an action can render: text a person reads, NDJSON events, one line per loop event, or the TUI. */
95
+ export declare const COMMAND_OUTPUTS: readonly ["text", "json", "events", "tui"];
96
+ /** One of the four renderings an action declares. */
97
+ export type CommandOutput = (typeof COMMAND_OUTPUTS)[number];
98
+ /** One example a command's help lists. */
99
+ export interface CommandExample {
100
+ /** The line as a person types it: `rafa loop start --plan=PLAN-x.md`. */
101
+ readonly cmd: string;
102
+ /** What the line does, in a sentence. */
103
+ readonly note: string;
104
+ }
105
+ /** Why a command is deprecated, and what to type instead. */
106
+ export interface CommandDeprecation {
107
+ /** The version the command was deprecated in. */
108
+ readonly since: string;
109
+ /** The spelling to use instead, after `rafa`: `loop start`. */
110
+ readonly use: string;
111
+ }
112
+ /** What a deprecated flag is read as, which is also what to type instead. */
113
+ export interface FlagDeprecation {
114
+ /**
115
+ * The spelling to type instead, `--output=json`: the words, joined by
116
+ * one space, the dispatcher reads the flag as.
117
+ */
118
+ readonly use: string;
119
+ }
120
+ /** A flag a rafa command declares: a `FlagSpec`, which may be a deprecated spelling. */
121
+ export interface RafaFlagSpec extends FlagSpec {
122
+ /** Set when the flag is a deprecated spelling; see the module note. */
123
+ readonly deprecated?: FlagDeprecation;
124
+ }
125
+ /** Everything a rafa command runs with. */
126
+ export interface RafaContext extends CliContext {
127
+ /** The words after the last word the line was routed by, as typed. */
128
+ readonly argv: readonly string[];
129
+ /** The registry the line was routed through, every module mounted for the invocation included. */
130
+ readonly registry: CommandRegistry;
131
+ /** The project the command runs in, or null for a command declaring `needsProject: false`; see the module note. */
132
+ readonly project: ProjectFound | null;
133
+ }
134
+ /** A command the dispatcher routes to by its subject and action. */
135
+ export interface RafaCommand extends Omit<CliCommand, 'run'> {
136
+ /** The first routing word: `loop` in `rafa loop start`. */
137
+ readonly subject: string;
138
+ /** The second routing word: `start`. Equal to `subject` for a top-level command. */
139
+ readonly action: string;
140
+ /** One line for the subject's roster. `description` may be longer. */
141
+ readonly summary: string;
142
+ /** The flags, any of them a deprecated spelling. */
143
+ flags: RafaFlagSpec[];
144
+ /** The examples help lists. */
145
+ readonly examples: readonly CommandExample[];
146
+ /**
147
+ * Whole other spellings of the command, each printing one deprecation
148
+ * line when typed, `start` for `loop start`, unless it is also one of
149
+ * {@link RafaCommand.lastingAliases}. Routed for a core command only; a
150
+ * module's command is reached through an `exec` action alone.
151
+ */
152
+ readonly aliases?: readonly string[];
153
+ /**
154
+ * The aliases, each also listed in `aliases`, kept for good rather than
155
+ * for one release: typed, they print no deprecation line. `epic` for
156
+ * `epic show`, which `rafa epics` reaches through the subject's plural.
157
+ */
158
+ readonly lastingAliases?: readonly string[];
159
+ /** What the action can render. */
160
+ readonly outputs: readonly CommandOutput[];
161
+ /** Set when the command itself is deprecated; typing it prints one deprecation line. */
162
+ readonly deprecated?: CommandDeprecation;
163
+ /** Out of every roster, and still dispatched. */
164
+ readonly hidden?: boolean;
165
+ /**
166
+ * The action delegates to a module: the word after it names a module
167
+ * mounted as `module/<name>`, and the word after that one of the
168
+ * module's actions.
169
+ */
170
+ readonly exec?: true;
171
+ /**
172
+ * False for a command that runs outside a project too, which the
173
+ * dispatcher resolves no project for: `module exec`, `init` and
174
+ * `describe`. Absent,
175
+ * the command runs inside a project; see the module note.
176
+ */
177
+ readonly needsProject?: boolean;
178
+ /**
179
+ * Whether running the command can start a Claude Code session, and
180
+ * under what condition; absent, it spends nothing. See `spends.ts`
181
+ * beside this file.
182
+ */
183
+ readonly spends?: CommandSpend;
184
+ /**
185
+ * What the command does under each `dangerous.*` key it declares, as a
186
+ * phrase the loader's pass line for that key ends with after `; `.
187
+ * The dispatcher sets it for the command's run; see "Dangerous
188
+ * phrases" in the module note.
189
+ */
190
+ readonly dangerous?: DangerousPhrases;
191
+ /** Runs the command. Throws {@link CommandExit} to refuse. */
192
+ readonly run: (context: RafaContext) => Promise<void>;
193
+ }
194
+ /**
195
+ * Thrown by a command to end its invocation with an exit code: nonzero to
196
+ * refuse, 0 to stop early as a success.
197
+ *
198
+ * The message, when it is not empty, is what the dispatcher tells the
199
+ * reader: on stderr in text mode, in the terminal event in json mode.
200
+ *
201
+ * `options` goes to `Error` as it is, so a `cause` given there is kept on
202
+ * the refusal: `new CommandExit(3, 'refused', { cause: error })` reads the
203
+ * error back as `exit.cause`.
204
+ */
205
+ export declare class CommandExit extends Error {
206
+ /** The exit code the invocation ends with, from 0 to 255. */
207
+ readonly exitCode: number;
208
+ /**
209
+ * Throws a `TypeError` when `exitCode` is not a whole number from 0 to 255,
210
+ * whatever `options` holds.
211
+ */
212
+ constructor(exitCode: number, message?: string, options?: ErrorOptions);
213
+ }
214
+ /**
215
+ * True when a value is a word a line can route by: no space, no slash and
216
+ * no leading dash. The slash is kept for the `module/<name>` mount keys,
217
+ * so no subject is spelled as one.
218
+ */
219
+ export declare function isRoutingWord(value: unknown): value is string;
220
+ /**
221
+ * What keeps `value` from being a `RafaCommand`, as a sentence naming the
222
+ * command when it can, or null when nothing does. See the module note.
223
+ */
224
+ export declare function commandProblem(value: unknown): string | null;
225
+ /** True when a command is top-level: its action is its subject. */
226
+ export declare function isTopLevel(command: Pick<RafaCommand, 'subject' | 'action'>): boolean;
227
+ /** A command's canonical spelling after `rafa`: `loop start`, or `status` for a top-level command. */
228
+ export declare function commandSpelling(command: Pick<RafaCommand, 'subject' | 'action'>): string;