@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.
Files changed (140) hide show
  1. package/README.md +255 -23
  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 +101 -18
  14. package/dist/cli.js +74726 -62960
  15. package/dist/config/entry.d.ts +119 -0
  16. package/dist/config/index.d.ts +36 -0
  17. package/dist/config/index.js +51 -0
  18. package/dist/config/shape.d.ts +232 -0
  19. package/dist/config-registry.d.ts +127 -0
  20. package/dist/config-schema-board-project.d.ts +157 -0
  21. package/dist/config-schema-bugs.d.ts +71 -0
  22. package/dist/config-schema-errors.d.ts +54 -0
  23. package/dist/config-schema-features.d.ts +64 -0
  24. package/dist/config-schema-hub.d.ts +150 -0
  25. package/dist/config-schema-issues.d.ts +95 -0
  26. package/dist/config-schema-logger.d.ts +91 -0
  27. package/dist/config-schema-loop-continue.d.ts +122 -0
  28. package/dist/config-schema-loop-retries.d.ts +94 -0
  29. package/dist/config-schema-release.d.ts +307 -0
  30. package/dist/config-schema-tests.d.ts +170 -0
  31. package/dist/config-schema-triage.d.ts +142 -0
  32. package/dist/config-schema-wrap-up.d.ts +96 -0
  33. package/dist/core/command/command.d.ts +228 -0
  34. package/dist/core/command/confirm.d.ts +67 -0
  35. package/dist/core/command/index.d.ts +112 -0
  36. package/dist/core/command/lazy.d.ts +54 -0
  37. package/dist/core/command/registry-types.d.ts +96 -0
  38. package/dist/core/command/running.d.ts +96 -0
  39. package/dist/core/command/spends.d.ts +39 -0
  40. package/dist/core/command/types.d.ts +92 -0
  41. package/dist/core/command/version.d.ts +4 -0
  42. package/dist/core/config/branch-template.d.ts +20 -0
  43. package/dist/core/config/config-items.d.ts +86 -0
  44. package/dist/core/config/config-load.d.ts +47 -0
  45. package/dist/core/config/config-origins.d.ts +57 -0
  46. package/dist/core/config/config-readers.d.ts +167 -0
  47. package/dist/core/config/config-schema.d.ts +207 -0
  48. package/dist/core/config/config-sections.d.ts +493 -0
  49. package/dist/core/config/config.d.ts +320 -0
  50. package/dist/core/config/core-section.d.ts +39 -0
  51. package/dist/core/config/dangerous.d.ts +58 -0
  52. package/dist/core/config/default-routing.d.ts +16 -0
  53. package/dist/core/config/index.d.ts +141 -0
  54. package/dist/core/config/scope.d.ts +42 -0
  55. package/dist/core/config/section.d.ts +206 -0
  56. package/dist/core/config/sections.d.ts +45 -0
  57. package/dist/core/config/standard-schema.d.ts +27 -0
  58. package/dist/core/git/commit.d.ts +232 -0
  59. package/dist/core/git/gh-runner.d.ts +24 -0
  60. package/dist/core/git/git.d.ts +22 -0
  61. package/dist/core/git/index.d.ts +85 -0
  62. package/dist/core/loop/claude.d.ts +388 -0
  63. package/dist/core/loop/hop-record.d.ts +52 -0
  64. package/dist/core/loop/index.d.ts +179 -0
  65. package/dist/core/loop/session-env.d.ts +20 -0
  66. package/dist/core/loop/session-record-parse.d.ts +63 -0
  67. package/dist/core/loop/sessions.d.ts +408 -0
  68. package/dist/core/loop/suite-failure.d.ts +25 -0
  69. package/dist/core/output/active.d.ts +100 -0
  70. package/dist/core/output/stream.d.ts +20 -0
  71. package/dist/core/output/text.d.ts +55 -0
  72. package/dist/core/plan/block-reader.d.ts +46 -0
  73. package/dist/core/plan/blocks.d.ts +139 -0
  74. package/dist/core/plan/declaration.d.ts +366 -0
  75. package/dist/core/plan/plan-stamp.d.ts +75 -0
  76. package/dist/core/runtime/identity.d.ts +21 -0
  77. package/dist/core/runtime/index.d.ts +46 -0
  78. package/dist/effort/store/bring-forward.d.ts +131 -0
  79. package/dist/effort/store/check-rows.d.ts +31 -0
  80. package/dist/effort/store/commit-stats.d.ts +42 -0
  81. package/dist/effort/store/copy.d.ts +35 -0
  82. package/dist/effort/store/development-build.d.ts +105 -0
  83. package/dist/effort/store/effort-levels.d.ts +13 -0
  84. package/dist/effort/store/findings.d.ts +214 -0
  85. package/dist/effort/store/fix-schema.d.ts +184 -0
  86. package/dist/effort/store/index.js +10 -7
  87. package/dist/effort/store/location.d.ts +44 -0
  88. package/dist/effort/store/merge-commit-gaps.d.ts +68 -0
  89. package/dist/effort/store/merge-conflicts.d.ts +91 -0
  90. package/dist/effort/store/merge-rules.d.ts +82 -0
  91. package/dist/effort/store/merge-store.d.ts +211 -0
  92. package/dist/effort/store/merge-union.d.ts +92 -0
  93. package/dist/effort/store/migrate.d.ts +146 -0
  94. package/dist/effort/store/migrations.d.ts +92 -0
  95. package/dist/effort/store/ndjson-files.d.ts +114 -0
  96. package/dist/effort/store/origins.d.ts +116 -0
  97. package/dist/effort/store/plan-stubs.d.ts +79 -0
  98. package/dist/effort/store/rebuild-aside.d.ts +172 -0
  99. package/dist/effort/store/schema-plan.d.ts +102 -0
  100. package/dist/effort/store/session-row-types.d.ts +64 -0
  101. package/dist/effort/store/settings.d.ts +13 -0
  102. package/dist/effort/store/sqlite.d.ts +340 -0
  103. package/dist/effort/store/store-generation.d.ts +17 -0
  104. package/dist/effort/store/store-identity.d.ts +220 -0
  105. package/dist/effort/store/store-meta.d.ts +305 -0
  106. package/dist/effort/store/store-replaced.d.ts +72 -0
  107. package/dist/effort/store/types.d.ts +223 -0
  108. package/dist/errors/codes.d.ts +56 -0
  109. package/dist/errors/rafa-codes.d.ts +36 -0
  110. package/dist/index-2a7nb3an.js +125 -0
  111. package/dist/{index-r28fzsvc.js → index-39kbcw68.js} +350 -165
  112. package/dist/{index-nv34ptht.js → index-77ajfffn.js} +14 -9
  113. package/dist/index-cy98y87p.js +2597 -0
  114. package/dist/index-gqz4jn6j.js +13447 -0
  115. package/dist/index-gvek4r8m.js +710 -0
  116. package/dist/index-j4k2vdz3.js +1125 -0
  117. package/dist/index-jh1r4kcn.js +1067 -0
  118. package/dist/{index-mgh2s9bj.js → index-ykggr043.js} +58 -455
  119. package/dist/index-z1w83f81.js +4 -0
  120. package/dist/index.js +14715 -21516
  121. package/dist/learning/index.js +5 -6
  122. package/dist/plan/index.js +12 -11
  123. package/dist/plan-prompt.md +3 -1
  124. package/dist/ports/index.d.ts +732 -0
  125. package/dist/ports/learning.d.ts +101 -0
  126. package/dist/ports/log-level.d.ts +13 -0
  127. package/dist/ports/spec-review.d.ts +66 -0
  128. package/dist/pr/checks.d.ts +133 -0
  129. package/dist/pr/types.d.ts +422 -0
  130. package/dist/ready-4f8edezt.js +2016 -0
  131. package/dist/release-templates/release-bot-fragment.yml +153 -0
  132. package/dist/release-templates/release-publish.yml +110 -0
  133. package/dist/release-templates/release-settle.yml +122 -0
  134. package/dist/release-templates/release-tag.yml +102 -0
  135. package/dist/report/parse.d.ts +415 -0
  136. package/dist/schema/project-id.d.ts +79 -0
  137. package/dist/schema/tiers.d.ts +107 -0
  138. package/package.json +41 -3
  139. package/dist/index-hf2k497d.js +0 -16
  140. package/dist/index-nsr78ct2.js +0 -8219
@@ -0,0 +1,320 @@
1
+ /**
2
+ * Reading rafa's settings: the phase 1 schema of the project's config
3
+ * (`.rafa/config.yaml`, `rafa.config.ts` or `rafa.config.mjs`).
4
+ *
5
+ * Every setting takes the value the COMMAND LINE gave it, else the
6
+ * value the project's config gave it, else the value the user scope's
7
+ * config under `~/.rafa/` gave it, else its default. Each
8
+ * setting is ranked on its own, so a flag naming one leaves the others
9
+ * to the files and a project file naming one leaves the others to the
10
+ * user's, and {@link ResolvedConfig.sources} records which layer
11
+ * answered each. That record keeps precedence observable when two
12
+ * layers agree: a file spelling the default still reports `file`, where
13
+ * the value alone could not tell a file that was read from one that was
14
+ * skipped. `file` names the project's file, as it did when that was the
15
+ * only file read, and `user` names the user scope's.
16
+ *
17
+ * This module is the pure half: text, or a document already parsed,
18
+ * into a layer, and layers into one resolution. Finding and reading each
19
+ * scope's file, behind a home seam, is `config-load.ts`, which reads a
20
+ * module file's merged entries through the same {@link readConfigDocument}
21
+ * a YAML file's document goes through. Scope resolution and `rafa init`
22
+ * are not here.
23
+ *
24
+ * ## Where the rules live
25
+ *
26
+ * The reader is three modules and a helper of the schema's, and a name
27
+ * moving between them is a refactor, never a change of behaviour. This
28
+ * file is intended as the public surface, re-exporting everything the
29
+ * other two modules export for a caller to import rather than reaching
30
+ * into a sibling; however, most
31
+ * callers import `config-sections.ts`'s names directly,
32
+ * through its barrel `core/config/sections.js`. The pull request port
33
+ * owns `MergeMethod`: a caller reading {@link RafaConfig.prMergeMethod}
34
+ * imports it from `./pr/index.js`, and neither this module nor
35
+ * `config-sections.ts` re-exports it, which would make the config a
36
+ * second place to learn it from.
37
+ *
38
+ * - `config-sections.ts` holds every rule about a VALUE: the readers,
39
+ * the closed lists of values, and why nothing is coerced.
40
+ * - `config-items.ts` holds the prerequisite item and module source
41
+ * shapes, read through the helpers `config-sections.ts` exports.
42
+ * This module re-exports its types and kind lists, as it did while
43
+ * they sat in `config-sections.ts`.
44
+ * - The rules about a KEY sit in three modules. `config-schema.ts`
45
+ * declares {@link RafaConfig}'s core fields and the setting types,
46
+ * and exports no value. `core-section.ts` holds core's file keys,
47
+ * specs and defaults, and {@link CONFIG_FILE}. `section.ts` holds
48
+ * the registry the sections are handed to, and the setting, section
49
+ * and known-key indexes it reads off the registered specs. This
50
+ * module reads each spec, each default and every index off that
51
+ * registry, and names no section. `src/config-registry.ts`, outside
52
+ * `packages/rafa/src/core/`, lists the sections and exports the merged schema,
53
+ * `CONFIG_DEFAULTS` and `SETTINGS` among it. The four readings the
54
+ * spec leaves to the reader — open tracker kinds, empty
55
+ * prerequisite tiers, `version: 1` alone, and `loop.settingSources`
56
+ * as an ordered list — are argued in `core-section.ts`; the readings each
57
+ * later section's spec leaves are argued in
58
+ * `config-schema-readings.ts`, a note that exports nothing, except
59
+ * the `pr` and `release` sections', which sit with their fields in
60
+ * `config-schema-release.ts`, the `tests` section's, which sit
61
+ * with theirs in `config-schema-tests.ts`, the `triage`
62
+ * section's, in `config-schema-triage.ts`, and the `errors`
63
+ * section's, in `config-schema-errors.ts`, each handed to core as
64
+ * a section by `src/config-registry.ts`.
65
+ * - `config-readers.ts` holds `mapOf` and the named readers
66
+ * `core-section.ts` reads its settings through. No caller reads a
67
+ * setting through them but the schema, so nothing here re-exports
68
+ * them.
69
+ * - This module holds the rules about LAYERS: which layer answers a
70
+ * setting, what a file may carry, and what is refused.
71
+ *
72
+ * The split is what keeps each under the 800-line cap of
73
+ * `context/source.md`, which no gate reads. Measured with `wc -l` at the
74
+ * commit that added the `pr` section: `config.ts` is 506 lines,
75
+ * `config-schema.ts` 396 and `config-sections.ts` 478. A new setting is
76
+ * one field in `config-schema.ts` with one default and one spec in
77
+ * `core-section.ts` (in
78
+ * `config-schema-release.ts` for a `pr` or `release` key, in
79
+ * `config-schema-tests.ts` for a `tests` key, in
80
+ * `config-schema-triage.ts` for a `triage` key, in
81
+ * `config-schema-errors.ts` for an `errors` key), and its reader
82
+ * in `config-sections.ts`. Nothing here names it: {@link readLayer}
83
+ * and {@link resolveConfig} loop over the names registered with
84
+ * `section.ts` (`activeSettings()`) and take each default from
85
+ * `activeDefaults()`, so a layer and a resolution hold every registered
86
+ * setting, in registration order. `src/config-registry.ts`, outside
87
+ * `packages/rafa/src/core/`, registers the fourteen sections when its
88
+ * `registerCoreConfigSections` is called; a process that has not called
89
+ * it reads no setting at all, where the
90
+ * literal this loop replaced held every setting whatever was registered.
91
+ *
92
+ * {@link parseConfigText} turns YAML text into one file layer and
93
+ * {@link resolveConfig} ranks the layers. Both are pure, so every
94
+ * precedence case is tested without a disk. The only read and the only
95
+ * place that prints are in `config-load.ts`.
96
+ *
97
+ * ## Unknown keys and unusable values
98
+ *
99
+ * The two are treated differently, and the difference is who the file
100
+ * was written for.
101
+ *
102
+ * - An UNKNOWN key is retained and warned about, never refused. It
103
+ * lands in {@link ConfigFile.extras} under its path (`nonesuch`,
104
+ * `plan.depth`, `prerequisites.required[0].timeout`) with the value
105
+ * it carried, and acts on nothing. A file written for a later phase
106
+ * names keys this one has never heard of; refusing them would make
107
+ * every addition to the schema a breaking change for older
108
+ * installs. That is the reason `core/plan/declaration.ts` keeps an
109
+ * unrecognised declaration key in its `extras`, and it holds here
110
+ * unchanged. The warning lists the keys known where the unknown one
111
+ * sits: the top level's, a section's, or an item's.
112
+ * - An UNUSABLE value for a key this module DOES answer to is
113
+ * refused with a {@link ConfigError}. `store: postgres` asks for a
114
+ * backend nothing here provides, and falling back to the default
115
+ * would write rows into a store other than the one the operator
116
+ * named — a silent success, the failure the collector refuses an
117
+ * unrecognised argument to prevent. Every problem is collected
118
+ * before the throw, so one run names all of them. A section that is
119
+ * not a mapping is one: `tracker: linear` is refused, where a
120
+ * phase 0 file could carry it as an unknown key.
121
+ *
122
+ * A refusal that reads two settings at once is a section's `checks`
123
+ * (`section.ts`), since the two may come from different files:
124
+ * {@link resolveConfig} runs every registered section's checks once
125
+ * every setting is ranked and throws one {@link ConfigError} with every
126
+ * problem they report. The one check today is the `hub` section's,
127
+ * `effort.sync: service` with no `hub.url` in any layer, naming the
128
+ * file that chose `service`; `config-schema-hub.ts` argues it.
129
+ *
130
+ * A file is judged whole, whatever the command line says. A flag that
131
+ * outranks an unusable file value does not excuse it, because the next
132
+ * run without the flag reads it.
133
+ *
134
+ * A `null` value says nothing; it is neither a value nor a problem.
135
+ * YAML makes `null` of a key whose children are all commented out —
136
+ * `plan:` above ` # inject: full` parses to `{ plan: null }` — and
137
+ * refusing it would punish the commonest edit a config file receives.
138
+ * Three settings RESOLVE to null — `pr.provider`, `pr.base` and
139
+ * `roadmap.issue` — and the rule holds for them unchanged: a file naming one with no value is
140
+ * silent, and silence there resolves to the same null from the defaults
141
+ * layer, reported as `default` rather than `file`. What null means to a
142
+ * caller is `core-section.ts`'s and `config-schema-release.ts`'s to say.
143
+ *
144
+ * A setting's dotted path is built by joining keys, so `plan.inject`
145
+ * written flat at the top level reaches the same setting as `inject`
146
+ * nested under `plan`. Both spellings are accepted, and a file giving
147
+ * one setting in both is refused: they are different YAML keys, so the
148
+ * parser keeps both, and letting one win would be a silent choice.
149
+ *
150
+ * Every key here is looked up in the `Map` and the `Set` `section.ts`
151
+ * builds off the registered settings, never with `in` or an object
152
+ * index; the reason is argued there.
153
+ *
154
+ * ## The parser, measured on bun 1.3.14
155
+ *
156
+ * `Bun.YAML.parse` is the whole parser; the repo takes no YAML
157
+ * dependency. Six of its behaviours shape the rules above, each read
158
+ * off the parser rather than its documentation:
159
+ *
160
+ * - An empty file, a whitespace-only one, a comment-only one and a
161
+ * bare `---` all parse to `null`, and read as a file that says
162
+ * nothing.
163
+ * - A multi-document stream parses to a LIST of documents, which is
164
+ * refused with every other top level that is not a mapping.
165
+ * - A duplicated key is not an error: the last occurrence wins and
166
+ * the first leaves no trace, so nothing here can warn about it.
167
+ * - Malformed YAML throws a `SyntaxError` whose message carries no
168
+ * line or column. The refusal names the file; it cannot name the
169
+ * line.
170
+ * - A child indented with a TAB parses differently by version: on
171
+ * bun 1.3.14 `plan:` over a tab-indented `inject: full` parses as
172
+ * `plan: null` beside a top-level `inject`, and on bun 1.4.2 it
173
+ * throws `Tab characters cannot be used as indentation`. So a line
174
+ * whose indentation holds a tab is refused, by line number, before
175
+ * the parser sees the text, and every bun gives one answer. A blank
176
+ * or comment line may carry one, and a tab inside a value parses as
177
+ * the value's own on both. One cost: a block scalar line whose
178
+ * content opens with a tab after its spaces is refused too.
179
+ * - `yes` and `on` parse as strings, and `True` and `TRUE` as the
180
+ * boolean. So a `tracking` flag spelled `yes` is refused rather
181
+ * than read as true.
182
+ */
183
+ import type { SettingOrigin, ShadowedFile } from './config-origins.js';
184
+ import type { CommandLineSetting, ConfigSetting, RafaConfig } from './config-schema.js';
185
+ import type { ConfigExtra } from './config-sections.js';
186
+ export type { CommandLineSetting, ConfigSetting, RafaConfig, } from './config-schema.js';
187
+ export { CONFIG_FILE } from './core-section.js';
188
+ export type { BoardRelationshipMode, ClaimsAhead, ClaimsStaleAfter, ClaudeSettingSource, ConfigExtra, ConfigVersion, InjectMode, LessonSwitch, OutputMode, PrProvider, ReleaseEnabled, RouteTarget, SkillResolverName, StoreBackend, SyncStrategy, TierPin, TierSwitch, } from './config-sections.js';
189
+ export { BOARD_PROJECT_TEMPLATE_DEFAULT, BOARD_RELATIONSHIP_MODES, CLAUDE_SETTING_SOURCES, CONFIG_VERSIONS, INJECT_MODES, OUTPUT_MODES, PR_PROVIDERS, RELEASE_AUTO, STORE_BACKENDS, SYNC_STRATEGIES, } from './config-sections.js';
190
+ export type { ModuleSource, ModuleSourceKind, OptionalPrerequisiteItem, PrerequisiteItem, PrerequisiteKind, PrerequisiteScope, } from './config-items.js';
191
+ export { MODULE_SOURCE_KINDS, PREREQUISITE_KINDS } from './config-items.js';
192
+ /**
193
+ * The layer that answered a setting: the command line, the project's
194
+ * file, the user scope's file, or the default.
195
+ */
196
+ export type ConfigSource = 'cli' | 'file' | 'user' | 'default';
197
+ /**
198
+ * One layer's say on every setting: a value, or undefined for silence.
199
+ *
200
+ * Every key is REQUIRED, with undefined standing for silence, so a
201
+ * setting added to {@link RafaConfig} is a compile error wherever a
202
+ * layer is built rather than a setting some layer forgot.
203
+ */
204
+ export type ConfigLayer = {
205
+ readonly [K in ConfigSetting]: RafaConfig[K] | undefined;
206
+ };
207
+ /**
208
+ * Command-line values as a flag parser hands them over: the raw string,
209
+ * or undefined when the flag was not given. {@link resolveConfig}
210
+ * validates them and refuses what the file would refuse, an empty
211
+ * string included. A key naming no {@link CommandLineSetting} is not
212
+ * read.
213
+ */
214
+ export type ConfigOverrides = {
215
+ readonly [K in CommandLineSetting]?: string | undefined;
216
+ };
217
+ /** What one config file said. */
218
+ export interface ConfigFile {
219
+ /** The file, as the caller named it. */
220
+ path: string;
221
+ /** Its value for each setting, or undefined where it said nothing. */
222
+ values: ConfigLayer;
223
+ /** Every key that names no setting and opens no section. */
224
+ extras: readonly ConfigExtra[];
225
+ /**
226
+ * The zero-based entry that last set each setting, for a file of
227
+ * several entries. Absent for a file of one, a YAML file, whose every
228
+ * setting is entry 0.
229
+ */
230
+ entries?: ReadonlyMap<ConfigSetting, number>;
231
+ }
232
+ /** The layers {@link resolveConfig} ranks, highest first. */
233
+ export interface ConfigLayers {
234
+ /** Command-line values. Absent is the same as no flag given. */
235
+ cli?: ConfigOverrides;
236
+ /** The project's parsed file, or null when there is none. */
237
+ file?: ConfigFile | null;
238
+ /** The user scope's parsed file, or null when there is none. */
239
+ user?: ConfigFile | null;
240
+ }
241
+ /** Every setting resolved, with the layer each value came from. */
242
+ export interface ResolvedConfig {
243
+ /** The value each setting resolved to. */
244
+ config: RafaConfig;
245
+ /** The layer that answered each setting. */
246
+ sources: Readonly<Record<ConfigSetting, ConfigSource>>;
247
+ /** The project's file consulted, or null when there was none. */
248
+ path: string | null;
249
+ /** The user scope's file consulted, or null when there was none. */
250
+ userPath: string | null;
251
+ /** The project file's unknown keys, retained. Empty with no file. */
252
+ extras: readonly ConfigExtra[];
253
+ /** The user file's unknown keys, retained. Empty with no file. */
254
+ userExtras: readonly ConfigExtra[];
255
+ /** One sentence per retained unknown key, the user file's first. */
256
+ warnings: readonly string[];
257
+ /**
258
+ * The file and entry that answered each setting, or null where the
259
+ * command line or a default did (`config-origins.ts`).
260
+ */
261
+ provenance: Readonly<Record<ConfigSetting, SettingOrigin | null>>;
262
+ /** The YAML files a module file of their scope left unread. Empty here; `config-load.ts` fills it. */
263
+ shadowed: readonly ShadowedFile[];
264
+ }
265
+ /**
266
+ * A config the loop cannot run on: unreadable, not YAML, not a
267
+ * mapping, or naming a value a setting does not accept.
268
+ *
269
+ * Its own class so a caller can tell a refusal it should print and
270
+ * exit on from a fault it should not swallow.
271
+ */
272
+ export declare class ConfigError extends Error {
273
+ /** Every problem found, one sentence each. */
274
+ readonly problems: readonly string[];
275
+ constructor(problems: readonly string[], options?: ErrorOptions);
276
+ }
277
+ /**
278
+ * Parses YAML into its document, refusing text that is not YAML with
279
+ * the file named. A tab in a line's indentation is refused before the
280
+ * parser sees the text, because bun's parser answers it differently by
281
+ * version. Judges no key: {@link readConfigDocument} does.
282
+ */
283
+ export declare function parseConfigDocument(text: string, path: string): unknown;
284
+ /** The config file's path under `root`. */
285
+ export declare function configFilePath(root: string): string;
286
+ /**
287
+ * Reads config text into one file layer. Pure: `path` only labels the
288
+ * layer and the refusals.
289
+ *
290
+ * Throws a {@link ConfigError} naming every problem the text has — a
291
+ * line indented with a tab, not YAML, not a mapping at the top, a section that is not a mapping, a
292
+ * setting given twice, a value a setting does not accept. An unknown
293
+ * key is none of these: it is retained in {@link ConfigFile.extras},
294
+ * the keys an item carried after the keys of the document.
295
+ */
296
+ export declare function parseConfigText(text: string, path: string): ConfigFile;
297
+ /**
298
+ * Reads a parsed document into one file layer, as {@link parseConfigText}
299
+ * reads the text it parses: null says nothing, anything but a mapping at
300
+ * the top is refused, and every key is judged. Pure; `path` only labels.
301
+ */
302
+ export declare function readConfigDocument(parsed: unknown, path: string): ConfigFile;
303
+ /**
304
+ * Ranks the layers: for each registered setting, the command line over
305
+ * the project's file, the project's over the user scope's, and the
306
+ * user's over its registered default (`activeDefaults()` in
307
+ * `section.ts`).
308
+ *
309
+ * Pure. Warnings come back as data — one per unknown key either file
310
+ * retained, the user file's first — and are never printed here. A command-line value no
311
+ * setting accepts throws a {@link ConfigError} naming every one, and
312
+ * is never downgraded to the file's value: an operator who mistyped a
313
+ * flag asked for something, and running on something else is the
314
+ * silent success the module note refuses. Every registered section's
315
+ * checks then run over the resolution, and any problem one reports
316
+ * throws a {@link ConfigError} too naming every such problem: the
317
+ * `hub` section's refuses `effort.sync: service` with no `hub.url` in
318
+ * any layer, naming the file that chose `service`.
319
+ */
320
+ export declare function resolveConfig(layers?: ConfigLayers): ResolvedConfig;
@@ -0,0 +1,39 @@
1
+ import type { RafaConfig, SettingSpec } from './config-schema.js';
2
+ import type { ConfigSection } from './section.js';
3
+ /**
4
+ * The config file, relative to the directory it sits under: the project
5
+ * root for the project's, the home directory for the user scope's.
6
+ *
7
+ * `join` rather than a literal, as `effort/store/ndjson-files.ts` spells
8
+ * its own directory, so a path built here compares equal to one a
9
+ * caller built with `join` of its own.
10
+ */
11
+ export declare const CONFIG_FILE: string;
12
+ /**
13
+ * The directory a scope keeps its files in, relative to the project
14
+ * root or the home: `.rafa`. Taken from `CONFIG_FILE`, so the two
15
+ * cannot name different directories.
16
+ */
17
+ export declare const SCOPE_DIR: string;
18
+ /**
19
+ * The name of one of core's own settings: every field `config-schema.ts`
20
+ * declares on `RafaConfig`, in the order problems are reported. Spelled
21
+ * rather than read off a value, since `isolatedDeclarations` asks every
22
+ * exported type to be written out.
23
+ */
24
+ export type CoreSetting = 'version' | 'store' | 'effortBusyTimeoutMs' | 'effortSync' | 'inject' | 'planDir' | 'specsDir' | 'trackerDefault' | 'trackerFallback' | 'learningAdapter' | 'learningBlessMinConfidence' | 'learningPromoteAfter' | 'learningPromoteMinConfidence' | 'outputMode' | 'prerequisitesRequired' | 'prerequisitesOptional' | 'trackingSpecs' | 'trackingPlans' | 'trackingAll' | 'modules' | 'allowList' | 'settingSources' | 'loopWorktreeDir' | 'boardTrustedAuthors' | 'boardRelationships' | 'boardProjectTemplate' | 'boardProjectNumber' | 'roadmapIssue' | 'claimsStaleAfter' | 'claimsAhead' | 'cleanupStaleDays' | 'cleanupWorktreeIdleDays' | 'cleanupKeep' | 'dangerousAcceptStaleRefs' | 'dangerousSelfUpdateDuringLoop' | 'statusNotice' | 'tiersRafa' | 'tiersSkills' | 'tiersAgents' | 'routing' | 'taskSkills' | 'taskLessons' | 'mergeDuplicates' | 'namingBranch';
25
+ /** Core's section: its package, the spec and the default of each of its settings, and no check. */
26
+ export interface CoreSection extends ConfigSection {
27
+ /** Each of core's settings, by name, in the order problems are reported. */
28
+ readonly settings: {
29
+ readonly [K in CoreSetting]: SettingSpec<K>;
30
+ };
31
+ /** What each of core's settings resolves to when no layer names it. */
32
+ readonly defaults: Readonly<Pick<RafaConfig, CoreSetting>>;
33
+ }
34
+ /**
35
+ * Core's own settings, handed in as a section: package `core`, every
36
+ * setting `config-schema.ts` declares with its spec and its default, and
37
+ * no cross-key check. Frozen, with its settings record.
38
+ */
39
+ export declare const CORE_SECTION: CoreSection;
@@ -0,0 +1,58 @@
1
+ import type { ResolvedConfig } from './config.js';
2
+ /** What a command does under each `dangerous.*` key it declares, by key. */
3
+ export type DangerousPhrases = Readonly<Record<string, string>>;
4
+ /**
5
+ * Runs `run` with `phrases` as the running command's in an async scope
6
+ * of its own, and answers what `run` answers; see the module note.
7
+ *
8
+ * @param phrases - The command's `dangerous` field, absent for none.
9
+ * @param run - The command's run.
10
+ * @returns What `run` answers.
11
+ */
12
+ export declare function runWithDangerousPhrases<T>(phrases: DangerousPhrases | undefined, run: () => T): T;
13
+ /**
14
+ * Sets `phrases` at module level; see the module note.
15
+ *
16
+ * @param phrases - The phrases to set, absent for none.
17
+ * @returns The module-level phrases replaced, for {@link restoreDangerousPhrases}.
18
+ */
19
+ export declare function setDangerousPhrases(phrases: DangerousPhrases | undefined): DangerousPhrases;
20
+ /**
21
+ * Puts back phrases {@link setDangerousPhrases} answered.
22
+ *
23
+ * @param previous - The phrases it answered.
24
+ */
25
+ export declare function restoreDangerousPhrases(previous: DangerousPhrases): void;
26
+ /**
27
+ * The running command's phrases: the scope's, else the module-level ones.
28
+ *
29
+ * @returns The phrases by key, empty when none is declared.
30
+ */
31
+ export declare function dangerousPhrases(): DangerousPhrases;
32
+ /**
33
+ * Every key of the active registry that opens with `dangerous.`, in
34
+ * registration order; see the module note.
35
+ *
36
+ * @returns The keys, such as `dangerous.acceptStaleRefs`; empty while
37
+ * no section is registered.
38
+ */
39
+ export declare function dangerousKeys(): readonly string[];
40
+ /**
41
+ * One pass line per dangerous key `resolved` holds off its default; see
42
+ * the module note.
43
+ *
44
+ * @param resolved - A resolution `loadConfig` or `resolveConfig` answered.
45
+ * @returns The lines, such as
46
+ * `dangerous.acceptStaleRefs: true (/repo/rafa.config.ts, entry 1)`,
47
+ * each ending with `; <phrase>` for a key the running command declares.
48
+ */
49
+ export declare function dangerousPassLines(resolved: ResolvedConfig): readonly string[];
50
+ /**
51
+ * Writes through `warn` each of `resolved`'s pass lines not yet written
52
+ * for `invocation`; see the module note.
53
+ *
54
+ * @param resolved - The resolution just loaded.
55
+ * @param warn - The warning sink `loadConfig` writes through.
56
+ * @param invocation - The object one invocation is known by.
57
+ */
58
+ export declare function writeDangerousPassLines(resolved: ResolvedConfig, warn: (message: string) => void, invocation: object): void;
@@ -0,0 +1,16 @@
1
+ /**
2
+ * rafa's routing defaults: which agent a task of each shape goes to
3
+ * when no config layer says otherwise.
4
+ *
5
+ * The table moved here from `src/tiers/routing.ts`, which re-exports
6
+ * each name, so `core-section.ts` reads {@link DEFAULT_ROUTING} without
7
+ * importing above core. What the rows mean, and why the map is one
8
+ * shared `Map` while the list is frozen, is `routing.ts`'s module note.
9
+ */
10
+ import type { RouteTarget } from './config-sections.js';
11
+ /** One default row: a task shape and the agent that takes it. */
12
+ export type Route = readonly [shape: string, agent: string];
13
+ /** rafa's routing table, in the order the spec lists it. */
14
+ export declare const DEFAULT_ROUTES: readonly Route[];
15
+ /** {@link DEFAULT_ROUTES} as the map `routing` resolves to by default. */
16
+ export declare const DEFAULT_ROUTING: ReadonlyMap<string, RouteTarget>;
@@ -0,0 +1,141 @@
1
+ /**
2
+ * The barrel over the config's schema and its layers: every name
3
+ * `config-items.ts`, `config-schema.ts`, `core-section.ts`, `section.ts`,
4
+ * `config.ts`, `dangerous.ts`, `scope.ts` and `default-routing.ts` export, less the names the
5
+ * `sections.ts` barrel holds, and nothing else.
6
+ *
7
+ * A file outside `packages/rafa/src/core/` imports this file and never the eight
8
+ * behind it (`scripts/survey/core-barrels.ts` measures that, and
9
+ * `src/tests/core-barrels.sweep.test.ts` holds it against the tree). A
10
+ * file inside `packages/rafa/src/core/` imports the eight directly and never this
11
+ * file.
12
+ *
13
+ * ## The barrels hold no name in common
14
+ *
15
+ * `packages/rafa/src/core/config/` has three barrels, all listed under `CORE_BARRELS`
16
+ * in `scripts/survey/core-moves.ts`. `sections.ts` holds the leaf pair,
17
+ * `config-sections.ts` and `config-readers.ts`, with `branch-template.ts`
18
+ * beside it, and argues why the pair has a barrel of its own. `load.ts` holds `config-load.ts` alone, and
19
+ * argues the same for it. This one holds the four files that read a
20
+ * key or rank a layer, and `section.ts`, the contract a section file
21
+ * outside `packages/rafa/src/core/` is typed by, the registry it is handed to and the
22
+ * key indexes read off that registry. `dangerous.ts` joined it with the
23
+ * running command's phrases (`runWithDangerousPhrases`), which the
24
+ * dispatcher sets around every command. It fits neither other barrel:
25
+ * it imports `config-sections.ts`, so it is no leaf for `sections.ts`,
26
+ * and `src/index.ts` publishes `load.ts` whole, where the phrases and
27
+ * pass lines are no published name.
28
+ *
29
+ * `scope.ts` joined it with a scope's paths, `Scope`, the project the
30
+ * dispatcher resolved, `ProjectFound`, and `scopeAt`, whose walk,
31
+ * `resolveScope`, stays in `src/project/scope.ts`. It reads `config.ts`
32
+ * and `core-section.ts` by value and `config-load.ts` as a type, so it
33
+ * is no leaf for `sections.ts`, and `load.ts` holds `config-load.ts`
34
+ * alone.
35
+ *
36
+ * `config.ts` re-exports twenty-seven names of `config-sections.ts`
37
+ * (`InjectMode`, `OUTPUT_MODES`, `ConfigExtra` and the like), as it did
38
+ * before it moved. None of them is exported here: a caller outside
39
+ * `packages/rafa/src/core/` takes each from `sections.ts`, so a name has one barrel to
40
+ * be learned from. A file that used to take `ConfigError` and
41
+ * `OUTPUT_MODES` in one line from `config.js` now spells two lines.
42
+ *
43
+ * ## Why one barrel can hold all eight
44
+ *
45
+ * A barrel that groups a file with a file outside `packages/rafa/src/core/` that
46
+ * imports the barrel back by value is a runtime cycle. None of the
47
+ * eight files behind this one imports outward by value:
48
+ * `core-section.ts` reads the routing defaults from `default-routing.ts`
49
+ * beside it, and `src/tiers/routing.ts` imports them from this barrel by
50
+ * value with nothing here importing it back. No file behind it
51
+ * imports a section file (`src/config-schema-*.ts`), by value or as a
52
+ * type: `config-merged.ts`, which spread the eleven into one schema,
53
+ * was retired when its importers moved to `src/config-registry.ts`,
54
+ * `config.ts` reads every key index and runs every section's checks
55
+ * off `section.ts`, and `src/tests/core-config-sections.sweep.test.ts`
56
+ * holds the rule for every file under `packages/rafa/src/core/`. The registry imports
57
+ * this barrel by value and nothing here imports the registry. A section
58
+ * file reads its values from `sections.ts`, which imports none of the
59
+ * eight, and adds its fields to `RafaConfig` with a `declare module` on
60
+ * `config-schema.ts`, which the checker follows and which loads
61
+ * nothing. `config-schema.ts` and `section.ts` import types alone.
62
+ *
63
+ * Measured when the three moved: the value imports of the non-test files
64
+ * under `src/`, `scripts/` and `packages/` held six cycles before the
65
+ * move and the same six after it, none through a file of this folder,
66
+ * and each barrel, each of the three files and each section file loaded
67
+ * first in a fresh `bun` process, `SETTINGS` holding its 89 entries
68
+ * each time.
69
+ *
70
+ * Measured again when core's keys moved into `core-section.ts`, on bun
71
+ * 1.3.14: each barrel, each of the five files, `section.ts`,
72
+ * `src/tiers/routing.ts` and each section file loaded first in a fresh
73
+ * `bun` process, `SETTINGS` and `CONFIG_DEFAULTS` holding 89 entries and
74
+ * `CORE_SECTION` 42 each time. The control, `config-schema-hub.ts`
75
+ * reading `SETTINGS` off this barrel at load, threw `Cannot access
76
+ * 'HUB_DEFAULTS' before initialization` when loaded first.
77
+ *
78
+ * Measured again when `section.ts` joined and each section file took a
79
+ * `ConfigSection` of its own, on bun 1.3.14: each config barrel,
80
+ * `section.ts`, the since-retired `config-merged.ts`, `config.ts` and
81
+ * each section file loaded first in a fresh `bun` process with
82
+ * `SETTINGS` holding 89 entries, and core's section and the eleven
83
+ * merged by `mergeConfigSections` into the same 89 settings and the
84
+ * same defaults as `SETTINGS` and `CONFIG_DEFAULTS`, with one check.
85
+ *
86
+ * Measured again when `config-merged.ts` was retired, on bun 1.3.14:
87
+ * the value imports of the five files behind this one reach no section
88
+ * file and not the registry, and each config barrel, each of the five
89
+ * files, `config-load.ts`, the registry, `packages/rafa/src/effort/store/settings.ts`,
90
+ * `src/tiers/routing.ts`, `packages/rafa/src/core/adapters/registry.ts` and each
91
+ * section file loaded first in a fresh `bun` process, the registry then
92
+ * answering 89 registered settings and 89 defaults each time.
93
+ *
94
+ * Measured again when `dangerous.ts` joined, on bun 1.3.14: this
95
+ * barrel, `dangerous.ts`, `config-load.ts`, the registry,
96
+ * `src/cli/dispatch.ts` and `packages/rafa/src/core/command/command.ts` each loaded
97
+ * first in a fresh `bun` process, the registry then holding 91 settings
98
+ * and `dangerousKeys` three keys each time.
99
+ *
100
+ * ## What it exports
101
+ *
102
+ * Each name is spelled, types apart from values, as `sections.ts` spells
103
+ * its own, and taken from the file that declares it: `config.ts`
104
+ * re-exports `RafaConfig` from `config-schema.ts`, `CONFIG_FILE` from
105
+ * `core-section.ts` and the item types and kind lists from
106
+ * `config-items.ts`, and each is exported here once. The merged schema
107
+ * (`SETTINGS`, `CONFIG_DEFAULTS`, `SETTING_NAMES`, `SETTING_BY_KEY`,
108
+ * `SECTIONS` and `knownKeysAbove`) is not here: a file outside
109
+ * `packages/rafa/src/core/` imports it from `src/config-registry.ts`, and core reads
110
+ * the registered settings, defaults and key indexes off `section.ts`.
111
+ * Neither are the hub's `HubContext` and `HubTimeout`, which a file
112
+ * imports from `src/config-schema-hub.ts`.
113
+ *
114
+ * The published surface is narrower than this file. `src/index.ts`
115
+ * re-exports part of it, and of the runtime names leaves out core's
116
+ * section, the routing defaults, the item readers, `config.ts`'s two
117
+ * document readers the loader reads a scope through, and the section
118
+ * registry with its key indexes (`CORE_SECTION`, `moduleSource`, `registerConfigSections`,
119
+ * `activeSettingByKey` and twenty-eight more), which `src/index.test.ts`
120
+ * spells under `CONFIG_BARREL_ONLY`. Its `CONFIG_DEFAULTS` is
121
+ * `src/config-registry.ts`'s.
122
+ *
123
+ * `index.test.ts` holds the list to the eight files: every name any of
124
+ * them exports and `sections.ts` does not is here once, as the same
125
+ * binding, and no other name is here.
126
+ */
127
+ export type { ModuleSource, ModuleSourceKind, OptionalPrerequisiteItem, PrerequisiteItem, PrerequisiteKind, PrerequisiteScope, } from './config-items.js';
128
+ export type { CommandLineSetting, ConfigSetting, RafaConfig, SettingSpec, } from './config-schema.js';
129
+ export type { CoreSection, CoreSetting } from './core-section.js';
130
+ export type { ConfigCheck, ConfigCheckInput, ConfigLoadHook, ConfigSection, ConfigSectionRegistry, SettingsRecord, } from './section.js';
131
+ export type { ConfigFile, ConfigLayer, ConfigLayers, ConfigOverrides, ConfigSource, ResolvedConfig, } from './config.js';
132
+ export type { DangerousPhrases } from './dangerous.js';
133
+ export type { ProjectFound, Scope } from './scope.js';
134
+ export type { Route } from './default-routing.js';
135
+ export { MODULE_SOURCE_KEYS, MODULE_SOURCE_KINDS, moduleSource, OPTIONAL_ITEM_KEYS, optionalPrerequisite, PREREQUISITE_KINDS, REQUIRED_ITEM_KEYS, requiredPrerequisite, } from './config-items.js';
136
+ export { CONFIG_FILE, CORE_SECTION, SCOPE_DIR } from './core-section.js';
137
+ export { activeChecks, activeConfigLoadHook, activeDefaults, activeKnownKeysAbove, activeSectionPaths, activeSections, activeSettingByKey, activeSettings, ConfigSectionError, EMPTY_CONFIG_REGISTRY, mergeConfigSections, registerConfigSections, restoreConfigSections, setConfigLoadHook, } from './section.js';
138
+ export { ConfigError, configFilePath, parseConfigDocument, parseConfigText, readConfigDocument, resolveConfig, } from './config.js';
139
+ export { dangerousKeys, dangerousPassLines, dangerousPhrases, restoreDangerousPhrases, runWithDangerousPhrases, setDangerousPhrases, writeDangerousPassLines, } from './dangerous.js';
140
+ export { scopeAt } from './scope.js';
141
+ export { DEFAULT_ROUTES, DEFAULT_ROUTING } from './default-routing.js';
@@ -0,0 +1,42 @@
1
+ /**
2
+ * One scope's paths, and the project the dispatcher resolved: the
3
+ * shapes `resolveScope` answers in `src/project/scope.ts`, and
4
+ * {@link scopeAt}, which builds a scope from its base directory.
5
+ *
6
+ * The walk itself, `resolveScope` with its refusals and its hint, stays
7
+ * in `src/project/scope.ts`, which imports these names from the config
8
+ * barrel and re-exports them under the same names. Core holds the
9
+ * shapes alone, so `RafaContext` can name the project a command runs in
10
+ * and the session store can find a project's `.rafa` directory without
11
+ * importing a file above core.
12
+ */
13
+ import type { ConfigRoots } from './config-load.js';
14
+ /** One scope's paths: its `.rafa` directory and its config file. */
15
+ export interface Scope {
16
+ /** `<base>/.rafa`. */
17
+ readonly dir: string;
18
+ /**
19
+ * The config file. For a project found, the first of
20
+ * {@link CONFIG_LOOKUP} its root holds; otherwise, and for the user
21
+ * scope, `<base>/.rafa/config.yaml`, the file `rafa init` writes.
22
+ */
23
+ readonly configFile: string;
24
+ }
25
+ /**
26
+ * The walk found a project. The answer is the `ConfigRoots` for
27
+ * `loadConfig`: `root` is the project root, a real path, and `home` is
28
+ * the home as the caller gave it.
29
+ */
30
+ export interface ProjectFound extends ConfigRoots {
31
+ readonly found: true;
32
+ /** The project scope, under `root`. */
33
+ readonly project: Scope;
34
+ /** The user scope, under `home`. */
35
+ readonly user: Scope;
36
+ }
37
+ /**
38
+ * The scope under `base`: `base` is a project root or a home directory.
39
+ * `configFile` is `file` when given, the lookup name found under
40
+ * `base`, and `<base>/.rafa/config.yaml` otherwise.
41
+ */
42
+ export declare function scopeAt(base: string, file?: string): Scope;