@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.
- package/README.md +280 -42
- package/dist/PROMPT.md +18 -1
- package/dist/adapters/logger/settings.d.ts +132 -0
- package/dist/bugs/closest.d.ts +19 -0
- package/dist/bugs/fenced.d.ts +8 -0
- package/dist/bugs/places.d.ts +20 -0
- package/dist/bugs/record.d.ts +145 -0
- package/dist/bugs/title.d.ts +83 -0
- package/dist/bundled/agents/doc-updater.md +17 -3
- package/dist/bundled/agents/loop-implementer.md +14 -2
- package/dist/bundled/operators/skills/rafa-stretch-pit-stop/SKILL.md +10 -3
- package/dist/bundled/operators/skills/rafa-stretch-sweep/SKILL.md +5 -0
- package/dist/bundled/skills/dev-planner/SKILL.md +120 -24
- package/dist/bundled/skills/documentation/SKILL.md +2 -12
- package/dist/cli.js +72387 -59411
- package/dist/config/entry.d.ts +119 -0
- package/dist/config/index.d.ts +36 -0
- package/dist/config/index.js +51 -0
- package/dist/config/shape.d.ts +232 -0
- package/dist/config-registry.d.ts +127 -0
- package/dist/config-schema-board-project.d.ts +157 -0
- package/dist/config-schema-bugs.d.ts +71 -0
- package/dist/config-schema-errors.d.ts +54 -0
- package/dist/config-schema-features.d.ts +64 -0
- package/dist/config-schema-hub.d.ts +150 -0
- package/dist/config-schema-issues.d.ts +95 -0
- package/dist/config-schema-logger.d.ts +91 -0
- package/dist/config-schema-loop-continue.d.ts +122 -0
- package/dist/config-schema-loop-retries.d.ts +94 -0
- package/dist/config-schema-release.d.ts +307 -0
- package/dist/config-schema-tests.d.ts +170 -0
- package/dist/config-schema-triage.d.ts +142 -0
- package/dist/config-schema-wrap-up.d.ts +96 -0
- package/dist/core/command/command.d.ts +228 -0
- package/dist/core/command/confirm.d.ts +67 -0
- package/dist/core/command/index.d.ts +112 -0
- package/dist/core/command/lazy.d.ts +54 -0
- package/dist/core/command/registry-types.d.ts +96 -0
- package/dist/core/command/running.d.ts +96 -0
- package/dist/core/command/spends.d.ts +39 -0
- package/dist/core/command/types.d.ts +92 -0
- package/dist/core/command/version.d.ts +4 -0
- package/dist/core/config/branch-template.d.ts +20 -0
- package/dist/core/config/config-items.d.ts +86 -0
- package/dist/core/config/config-load.d.ts +47 -0
- package/dist/core/config/config-origins.d.ts +57 -0
- package/dist/core/config/config-readers.d.ts +167 -0
- package/dist/core/config/config-schema.d.ts +207 -0
- package/dist/core/config/config-sections.d.ts +493 -0
- package/dist/core/config/config.d.ts +320 -0
- package/dist/core/config/core-section.d.ts +39 -0
- package/dist/core/config/dangerous.d.ts +58 -0
- package/dist/core/config/default-routing.d.ts +16 -0
- package/dist/core/config/index.d.ts +141 -0
- package/dist/core/config/scope.d.ts +42 -0
- package/dist/core/config/section.d.ts +206 -0
- package/dist/core/config/sections.d.ts +45 -0
- package/dist/core/config/standard-schema.d.ts +27 -0
- package/dist/core/git/commit.d.ts +232 -0
- package/dist/core/git/gh-runner.d.ts +24 -0
- package/dist/core/git/git.d.ts +22 -0
- package/dist/core/git/index.d.ts +85 -0
- package/dist/core/loop/claude.d.ts +388 -0
- package/dist/core/loop/hop-record.d.ts +52 -0
- package/dist/core/loop/index.d.ts +179 -0
- package/dist/core/loop/session-env.d.ts +20 -0
- package/dist/core/loop/session-record-parse.d.ts +63 -0
- package/dist/core/loop/sessions.d.ts +408 -0
- package/dist/core/loop/suite-failure.d.ts +25 -0
- package/dist/core/output/active.d.ts +100 -0
- package/dist/core/output/stream.d.ts +20 -0
- package/dist/core/output/text.d.ts +55 -0
- package/dist/core/plan/block-reader.d.ts +46 -0
- package/dist/core/plan/blocks.d.ts +139 -0
- package/dist/core/plan/declaration.d.ts +366 -0
- package/dist/core/plan/plan-stamp.d.ts +75 -0
- package/dist/core/runtime/identity.d.ts +21 -0
- package/dist/core/runtime/index.d.ts +46 -0
- package/dist/effort/store/bring-forward.d.ts +131 -0
- package/dist/effort/store/check-rows.d.ts +31 -0
- package/dist/effort/store/commit-stats.d.ts +42 -0
- package/dist/effort/store/copy.d.ts +35 -0
- package/dist/effort/store/development-build.d.ts +105 -0
- package/dist/effort/store/effort-levels.d.ts +13 -0
- package/dist/effort/store/findings.d.ts +214 -0
- package/dist/effort/store/fix-schema.d.ts +184 -0
- package/dist/effort/store/index.js +10 -7
- package/dist/effort/store/location.d.ts +44 -0
- package/dist/effort/store/merge-commit-gaps.d.ts +68 -0
- package/dist/effort/store/merge-conflicts.d.ts +91 -0
- package/dist/effort/store/merge-rules.d.ts +82 -0
- package/dist/effort/store/merge-store.d.ts +211 -0
- package/dist/effort/store/merge-union.d.ts +92 -0
- package/dist/effort/store/migrate.d.ts +146 -0
- package/dist/effort/store/migrations.d.ts +92 -0
- package/dist/effort/store/ndjson-files.d.ts +114 -0
- package/dist/effort/store/origins.d.ts +116 -0
- package/dist/effort/store/plan-stubs.d.ts +79 -0
- package/dist/effort/store/rebuild-aside.d.ts +172 -0
- package/dist/effort/store/schema-plan.d.ts +102 -0
- package/dist/effort/store/session-row-types.d.ts +64 -0
- package/dist/effort/store/settings.d.ts +13 -0
- package/dist/effort/store/sqlite.d.ts +340 -0
- package/dist/effort/store/store-generation.d.ts +17 -0
- package/dist/effort/store/store-identity.d.ts +220 -0
- package/dist/effort/store/store-meta.d.ts +305 -0
- package/dist/effort/store/store-replaced.d.ts +72 -0
- package/dist/effort/store/types.d.ts +223 -0
- package/dist/errors/codes.d.ts +56 -0
- package/dist/errors/rafa-codes.d.ts +36 -0
- package/dist/index-2a7nb3an.js +125 -0
- package/dist/{index-57mmzkcn.js → index-39kbcw68.js} +516 -217
- package/dist/{index-nv34ptht.js → index-77ajfffn.js} +14 -9
- package/dist/index-cy98y87p.js +2597 -0
- package/dist/index-gqz4jn6j.js +13447 -0
- package/dist/index-gvek4r8m.js +710 -0
- package/dist/index-j4k2vdz3.js +1125 -0
- package/dist/index-jh1r4kcn.js +1067 -0
- package/dist/index-ykggr043.js +540 -0
- package/dist/index-z1w83f81.js +4 -0
- package/dist/index.js +16091 -22798
- package/dist/learning/index.js +5 -6
- package/dist/plan/index.js +12 -11
- package/dist/plan-prompt.md +11 -2
- package/dist/ports/index.d.ts +732 -0
- package/dist/ports/learning.d.ts +101 -0
- package/dist/ports/log-level.d.ts +13 -0
- package/dist/ports/spec-review.d.ts +66 -0
- package/dist/pr/checks.d.ts +133 -0
- package/dist/pr/types.d.ts +422 -0
- package/dist/ready-4f8edezt.js +2016 -0
- package/dist/release-templates/release-bot-fragment.yml +153 -0
- package/dist/release-templates/release-publish.yml +110 -0
- package/dist/release-templates/release-settle.yml +122 -0
- package/dist/release-templates/release-tag.yml +102 -0
- package/dist/report/parse.d.ts +415 -0
- package/dist/schema/project-id.d.ts +79 -0
- package/dist/schema/tiers.d.ts +107 -0
- package/package.json +42 -4
- package/dist/index-6q30dtgm.js +0 -6342
- package/dist/index-cknayrpc.js +0 -2414
- package/dist/index-hf2k497d.js +0 -16
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The two item shapes the schema's lists hold: a prerequisite item and
|
|
3
|
+
* a module source, each read by one reader of `config-sections.ts`'s
|
|
4
|
+
* {@link Reader} shape.
|
|
5
|
+
*
|
|
6
|
+
* Every other rule about a VALUE is `config-sections.ts`'s, and so are
|
|
7
|
+
* the rules every reader keeps, items included: a kind key matched with
|
|
8
|
+
* `===`, a null optional key saying nothing, and a key an item does not
|
|
9
|
+
* read retained as a {@link ConfigExtra}. The shapes moved here out of
|
|
10
|
+
* that module to keep it under the size cap of `context/source.md`: it
|
|
11
|
+
* stood at 792 lines before the move. `config.ts` re-exports the item
|
|
12
|
+
* types and kind lists, as it did while they lived there.
|
|
13
|
+
*
|
|
14
|
+
* The import runs one way. This module reads the reading helpers
|
|
15
|
+
* `config-sections.ts` exports, and that module imports nothing from
|
|
16
|
+
* this one, so the two form no cycle.
|
|
17
|
+
*
|
|
18
|
+
* ## The item shapes
|
|
19
|
+
*
|
|
20
|
+
* A prerequisite item names exactly one of `tool`, `env`, `service` or
|
|
21
|
+
* `lsp`, may carry a `probe`, and on the optional tier a `reason`. That
|
|
22
|
+
* is the shape of the block under "Config schema" in
|
|
23
|
+
* `.rafa/specs/phase-1-installable.md`. A `reason` on a required item is a
|
|
24
|
+
* key that tier does not read, so it is retained and warned about.
|
|
25
|
+
*
|
|
26
|
+
* A module source names exactly one of `npm`, `github` or `path`, and a
|
|
27
|
+
* `github` source may carry a `ref`: the source shapes of the registry
|
|
28
|
+
* example in `.rafa/specs/modules-and-addons.md`, which `modules:` lists
|
|
29
|
+
* "by source". This module accepts all three. Whether a source kind can
|
|
30
|
+
* be loaded is the module loader's answer, not the config's.
|
|
31
|
+
*/
|
|
32
|
+
import type { Reader } from './config-sections.js';
|
|
33
|
+
/** The keys one of which names a prerequisite item. */
|
|
34
|
+
export declare const PREREQUISITE_KINDS: readonly ["tool", "env", "service", "lsp"];
|
|
35
|
+
/** One of the four prerequisite kinds. */
|
|
36
|
+
export type PrerequisiteKind = (typeof PREREQUISITE_KINDS)[number];
|
|
37
|
+
/**
|
|
38
|
+
* Which of a run's dispatches need a plan's item: its tasks, its wrap-up,
|
|
39
|
+
* or both. Read from the `[tasks]` or `[wrap-up]` marker of a
|
|
40
|
+
* PREREQUISITES file (`src/preflight/prerequisites-md.ts`).
|
|
41
|
+
*/
|
|
42
|
+
export type PrerequisiteScope = 'tasks' | 'wrap-up' | 'both';
|
|
43
|
+
/** One item of `prerequisites.required`. */
|
|
44
|
+
export interface PrerequisiteItem {
|
|
45
|
+
/** Which of the four keys named it. */
|
|
46
|
+
kind: PrerequisiteKind;
|
|
47
|
+
/** What that key named: `bun`, `GITHUB_TOKEN`, a URL, `typescript`. */
|
|
48
|
+
name: string;
|
|
49
|
+
/** The command that proves it, or null to check presence alone. */
|
|
50
|
+
probe: string | null;
|
|
51
|
+
/**
|
|
52
|
+
* The scope a plan's PREREQUISITES file gave the item. Left out of an
|
|
53
|
+
* item the config names, which has no spelling for one.
|
|
54
|
+
*/
|
|
55
|
+
scope?: PrerequisiteScope;
|
|
56
|
+
}
|
|
57
|
+
/** One item of `prerequisites.optional`. */
|
|
58
|
+
export interface OptionalPrerequisiteItem extends PrerequisiteItem {
|
|
59
|
+
/** Why the item helps, for the line naming it missing; or null. */
|
|
60
|
+
reason: string | null;
|
|
61
|
+
}
|
|
62
|
+
/** The keys a required prerequisite item reads. */
|
|
63
|
+
export declare const REQUIRED_ITEM_KEYS: readonly string[];
|
|
64
|
+
/** The keys an optional prerequisite item reads. */
|
|
65
|
+
export declare const OPTIONAL_ITEM_KEYS: readonly string[];
|
|
66
|
+
/** Reads one `prerequisites.required` item. */
|
|
67
|
+
export declare const requiredPrerequisite: Reader<PrerequisiteItem>;
|
|
68
|
+
/** Reads one `prerequisites.optional` item. */
|
|
69
|
+
export declare const optionalPrerequisite: Reader<OptionalPrerequisiteItem>;
|
|
70
|
+
/** The keys one of which names a module source. */
|
|
71
|
+
export declare const MODULE_SOURCE_KINDS: readonly ["npm", "github", "path"];
|
|
72
|
+
/** One of the three module source kinds. */
|
|
73
|
+
export type ModuleSourceKind = (typeof MODULE_SOURCE_KINDS)[number];
|
|
74
|
+
/** One entry of `modules:`: where a module is installed from. */
|
|
75
|
+
export interface ModuleSource {
|
|
76
|
+
/** Which of the three keys named it. */
|
|
77
|
+
kind: ModuleSourceKind;
|
|
78
|
+
/** What that key named: a package name, an `owner/repo`, a path. */
|
|
79
|
+
location: string;
|
|
80
|
+
/** The git ref beside a `github` source; null for every other. */
|
|
81
|
+
ref: string | null;
|
|
82
|
+
}
|
|
83
|
+
/** The keys a module source reads, `ref` on a `github` one alone. */
|
|
84
|
+
export declare const MODULE_SOURCE_KEYS: readonly string[];
|
|
85
|
+
/** Reads one `modules:` entry. */
|
|
86
|
+
export declare const moduleSource: Reader<ModuleSource>;
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import type { ConfigFile, ConfigOverrides, ResolvedConfig } from './config.js';
|
|
2
|
+
/** The two directories {@link loadConfig} reads a config file under. */
|
|
3
|
+
export interface ConfigRoots {
|
|
4
|
+
/** The project root: its scope's files sit here and under its `.rafa/`. */
|
|
5
|
+
readonly root: string;
|
|
6
|
+
/** The home directory: the user scope's files sit under its `.rafa/`. */
|
|
7
|
+
readonly home: string;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Reads `.rafa/config.yaml` under `root`, or answers null when nothing
|
|
11
|
+
* is at that path. Anything there that cannot be read — a directory,
|
|
12
|
+
* a file without read permission — is refused with a
|
|
13
|
+
* {@link ConfigError} rather than read as absent; see the module note.
|
|
14
|
+
* Reads the YAML file alone: {@link loadConfig} is what looks up a
|
|
15
|
+
* scope's module files.
|
|
16
|
+
*/
|
|
17
|
+
export declare function readConfigFile(root: string): ConfigFile | null;
|
|
18
|
+
/**
|
|
19
|
+
* Reads the user scope's file under `roots.home` and the project's
|
|
20
|
+
* under `roots.root`, ranks both against `cli`, and prints a warning
|
|
21
|
+
* per shadowed YAML file, per key set twice in one file and per unknown
|
|
22
|
+
* key through `warn`, the active output's `warn` when none is given.
|
|
23
|
+
* After them it writes one pass line per `dangerous.*` key set off its
|
|
24
|
+
* default (`dangerous.ts`), once per invocation: the active output's
|
|
25
|
+
* when `warn` is the default, the sink's own when one is given.
|
|
26
|
+
*
|
|
27
|
+
* The resolved config is handed to the load hook (`activeConfigLoadHook`
|
|
28
|
+
* in `section.ts`) before any warning is printed. The registry,
|
|
29
|
+
* `src/config-registry.ts`, sets that hook to hand the logger
|
|
30
|
+
* (`adapters/logger/settings.ts`) its `logger` settings, so a
|
|
31
|
+
* `logger.level` of `error` also quiets the warnings of the load that
|
|
32
|
+
* set it. With no hook set the logger keeps the settings it had.
|
|
33
|
+
*
|
|
34
|
+
* The resolved `effort.busyTimeoutMs` is handed to the effort store
|
|
35
|
+
* (`effort/store/settings.ts`), so every store open after this call
|
|
36
|
+
* waits that long for a lock.
|
|
37
|
+
*
|
|
38
|
+
* The files are read and judged before the command line is looked at,
|
|
39
|
+
* the user's first, so a run with problems in all three reports the
|
|
40
|
+
* user file's alone. See the module note for the home, the lookup and
|
|
41
|
+
* every refusal.
|
|
42
|
+
*
|
|
43
|
+
* @returns The resolution, with `provenance` naming the file and entry
|
|
44
|
+
* of each setting a file answered, and `shadowed` the YAML files a
|
|
45
|
+
* module file left unread.
|
|
46
|
+
*/
|
|
47
|
+
export declare function loadConfig(roots: ConfigRoots, cli?: ConfigOverrides, warn?: (message: string) => void): Promise<ResolvedConfig>;
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Where a resolved setting came from, and which file a scope left
|
|
3
|
+
* unread: the two records `ResolvedConfig` carries beside its values,
|
|
4
|
+
* `provenance` and `shadowed` (`config.ts`).
|
|
5
|
+
*
|
|
6
|
+
* ## An origin
|
|
7
|
+
*
|
|
8
|
+
* A {@link SettingOrigin} names the file that answered one setting and
|
|
9
|
+
* the entry of that file that last set it, zero-based, as
|
|
10
|
+
* `@open-tomato/define-config` counts a module file's entries. A YAML
|
|
11
|
+
* file is one entry, so every setting it answers is entry 0. A setting
|
|
12
|
+
* the command line or a default answered has no origin: no file set it.
|
|
13
|
+
*
|
|
14
|
+
* {@link originOf} reads the origin off the layer `resolveConfig`
|
|
15
|
+
* ranked first, so it follows `sources` exactly: `file` names the
|
|
16
|
+
* project's file, `user` the user scope's, and `cli` and `default` name
|
|
17
|
+
* none. A map setting merged across both files names the project's,
|
|
18
|
+
* the file its source names.
|
|
19
|
+
*
|
|
20
|
+
* ## A shadowed file
|
|
21
|
+
*
|
|
22
|
+
* A scope is read from one file, the first of `rafa.config.ts`,
|
|
23
|
+
* `rafa.config.mjs` and its `.rafa/config.yaml` that is a file
|
|
24
|
+
* (`config-load.ts`). A {@link ShadowedFile} is a YAML file a module
|
|
25
|
+
* file of its scope left unread, named so the warning and `rafa doctor`
|
|
26
|
+
* can say which keys stopped applying.
|
|
27
|
+
*/
|
|
28
|
+
import type { ConfigFile, ConfigSetting, ConfigSource } from './config.js';
|
|
29
|
+
/** The two scopes a config file is read in. */
|
|
30
|
+
export type ConfigScopeName = 'user' | 'project';
|
|
31
|
+
/** The file and entry that answered one setting. */
|
|
32
|
+
export interface SettingOrigin {
|
|
33
|
+
/** The file, as its layer names it. */
|
|
34
|
+
readonly file: string;
|
|
35
|
+
/** The zero-based entry of that file that last set the setting. */
|
|
36
|
+
readonly entry: number;
|
|
37
|
+
}
|
|
38
|
+
/** A YAML file left unread because a module file holds its scope. */
|
|
39
|
+
export interface ShadowedFile {
|
|
40
|
+
/** The scope both files sit in. */
|
|
41
|
+
readonly layer: ConfigScopeName;
|
|
42
|
+
/** The YAML file left unread. */
|
|
43
|
+
readonly path: string;
|
|
44
|
+
/** The module file read in its place. */
|
|
45
|
+
readonly by: string;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* The origin of `setting`, answered by the layer `source` names; see
|
|
49
|
+
* the module note.
|
|
50
|
+
*
|
|
51
|
+
* @param source - The layer that answered the setting.
|
|
52
|
+
* @param setting - The setting.
|
|
53
|
+
* @param file - The project's file, or null when there was none.
|
|
54
|
+
* @param user - The user scope's file, or null when there was none.
|
|
55
|
+
* @returns The file and entry, or null for the command line or a default.
|
|
56
|
+
*/
|
|
57
|
+
export declare function originOf(source: ConfigSource, setting: ConfigSetting, file: ConfigFile | null, user: ConfigFile | null): SettingOrigin | null;
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The readers `core-section.ts` and `config-schema-release.ts` build
|
|
3
|
+
* their settings from, beyond the value readers `config-sections.ts`
|
|
4
|
+
* exports whole: {@link mapOf}, and
|
|
5
|
+
* the named readers the schema's settings are read through, each built
|
|
6
|
+
* on `mapOf` or on `config-sections.ts`'s `text` or `oneOf`. The readers a single
|
|
7
|
+
* setting spells inline, such as `oneOf(STORE_BACKENDS)`, stay beside
|
|
8
|
+
* their key in `core-section.ts`, or in `config-schema-release.ts` for
|
|
9
|
+
* a `pr` or `release` key.
|
|
10
|
+
*
|
|
11
|
+
* They sat in `config-schema.ts` until that module reached the 800-line
|
|
12
|
+
* cap of `context/source.md`, and moved out before any setting was added
|
|
13
|
+
* so a new key is not paid for by rewrapping prose. `config-sections.ts`
|
|
14
|
+
* still holds every rule about a VALUE but the release plan's, below,
|
|
15
|
+
* and the two item shapes, which `config-items.ts` reads;
|
|
16
|
+
* {@link mapOf} is here rather than there because what it rules on is a KEY: the names a map
|
|
17
|
+
* setting's file spells below its own key. Outside `packages/rafa/src/core/config/`
|
|
18
|
+
* no file imports this one by path: its names are read through the
|
|
19
|
+
* barrel `sections.ts`, by the release modules for the release plan's
|
|
20
|
+
* lists and by `tiers/routing.test.ts`, which reads a file's `routing`
|
|
21
|
+
* through {@link routeTable} as the schema does.
|
|
22
|
+
*
|
|
23
|
+
* The closed lists and readers of the release plan's keys —
|
|
24
|
+
* `release.strategy`, `release.settle`, `release.tag`,
|
|
25
|
+
* `release.publish`, `pr.versionCollision` and `release.fragments` —
|
|
26
|
+
* are value rules and
|
|
27
|
+
* sit here all the same: `config-sections.ts` stood at 781 lines,
|
|
28
|
+
* measured with `wc -l`, when they joined, and takes no new code under
|
|
29
|
+
* the 800-line cap of `context/source.md`. Each closed list is read
|
|
30
|
+
* through that module's `oneOf`, so an unknown value is refused in the
|
|
31
|
+
* words every other closed list is refused in.
|
|
32
|
+
*
|
|
33
|
+
* ## Path settings
|
|
34
|
+
*
|
|
35
|
+
* `release.fragments` names the directory a branch's wrap-up writes
|
|
36
|
+
* its change fragment into, and a fragment is committed data: settle
|
|
37
|
+
* reads the fragments present in the base branch's tree. So
|
|
38
|
+
* {@link fragmentsDirectory} refuses two paths `text` would take:
|
|
39
|
+
*
|
|
40
|
+
* - An absolute path. The directory is read off a scratch worktree
|
|
41
|
+
* of the base branch as well as off the caller's checkout, and an
|
|
42
|
+
* absolute path names one place on one disk rather than a place in
|
|
43
|
+
* every checkout.
|
|
44
|
+
* - `.rafa` or a path below it, after `normalize` has resolved `./`
|
|
45
|
+
* and `..` steps. `.rafa/` is gitignored, so a fragment written
|
|
46
|
+
* there would never reach a commit and no fold would ever see it.
|
|
47
|
+
*
|
|
48
|
+
* A path is kept as written, as every other path setting keeps one;
|
|
49
|
+
* a caller joins it under the repository root.
|
|
50
|
+
*
|
|
51
|
+
* ## Map settings
|
|
52
|
+
*
|
|
53
|
+
* A map setting holds names the schema cannot list — a skill, an agent,
|
|
54
|
+
* a task shape — each with a value an inner reader checks, and
|
|
55
|
+
* {@link mapOf} reads one. Three readings are this module's:
|
|
56
|
+
*
|
|
57
|
+
* - A name is a key the FILE spells, not one the schema knows, so it
|
|
58
|
+
* is kept in a `Map` and never in a plain object: a skill named
|
|
59
|
+
* `constructor` or `__proto__` is an ordinary name, and an object
|
|
60
|
+
* would match it against `Object.prototype` or reset the
|
|
61
|
+
* prototype. A name, like any string that names something, holds a
|
|
62
|
+
* character other than whitespace, and is kept as written.
|
|
63
|
+
* - Every entry is read, so a map with two unusable values names both,
|
|
64
|
+
* as `listOf` does for a list. An entry's label and key gain its
|
|
65
|
+
* name, `tiers.skills.tdd-guide`. A null value is handed to the
|
|
66
|
+
* inner reader like any other, which is what a map whose values
|
|
67
|
+
* include `false` needs: whether `false`, or null, means anything is
|
|
68
|
+
* the inner reader's answer.
|
|
69
|
+
* - The answer is a fresh `Map` per read, typed as a `ReadonlyMap`. A
|
|
70
|
+
* `Map` cannot be frozen the way a list is — `Object.freeze` leaves
|
|
71
|
+
* `set` working — so the promise that no caller edits a value for
|
|
72
|
+
* the next is kept by building a new one each time.
|
|
73
|
+
*
|
|
74
|
+
* ## The branch template
|
|
75
|
+
*
|
|
76
|
+
* `naming.branch` is the template a plan's branch is named from: it
|
|
77
|
+
* holds {@link BRANCH_STUB} exactly once, and the branch is the template
|
|
78
|
+
* with that marker replaced by the plan's stub
|
|
79
|
+
* ({@link branchFromTemplate}). The default,
|
|
80
|
+
* {@link DEFAULT_BRANCH_TEMPLATE}, names the `feat/<stub>` branch every
|
|
81
|
+
* run created before the key existed. Exactly once, because a template
|
|
82
|
+
* without the marker names one branch for every plan, and one holding it
|
|
83
|
+
* twice leaves a guess which of the two a reader of the branch takes the
|
|
84
|
+
* stub from. Nothing else is checked: what git takes as a ref name is
|
|
85
|
+
* git's to refuse when the branch is created, naming the branch.
|
|
86
|
+
*/
|
|
87
|
+
import type { Reader, RouteTarget, TierPin } from './config-sections.js';
|
|
88
|
+
/**
|
|
89
|
+
* Accepts a mapping of names to values `value` accepts, answered as a
|
|
90
|
+
* fresh `Map` in the order written; see "Map settings" in the module
|
|
91
|
+
* note. Every entry is read, so a map with two unusable entries names
|
|
92
|
+
* both. `expected` names the values, in the refusal of a value that is
|
|
93
|
+
* not a mapping.
|
|
94
|
+
*/
|
|
95
|
+
export declare function mapOf<T>(value: Reader<T>, expected: string): Reader<ReadonlyMap<string, T>>;
|
|
96
|
+
/** The reader every directory setting, `plan.dir`, `specs.dir` and `loop.worktreeDir`, shares. */
|
|
97
|
+
export declare const directory: Reader<string>;
|
|
98
|
+
/** The reader every tracker kind goes through, alone or in a list. */
|
|
99
|
+
export declare const trackerKind: Reader<string>;
|
|
100
|
+
/** The reader both `release` file settings share. */
|
|
101
|
+
export declare const releaseFile: Reader<string>;
|
|
102
|
+
/** The reader both `tiers` maps, `tiers.skills` and `tiers.agents`, share. */
|
|
103
|
+
export declare const tierPins: Reader<ReadonlyMap<string, TierPin>>;
|
|
104
|
+
/** The reader of `routing`: a task shape to an agent, or `false`. */
|
|
105
|
+
export declare const routeTable: Reader<ReadonlyMap<string, RouteTarget>>;
|
|
106
|
+
/**
|
|
107
|
+
* The strategies `release.strategy` may name. One today: the fold that
|
|
108
|
+
* bumps the base branch's version by the highest level among the
|
|
109
|
+
* fragments it folds.
|
|
110
|
+
*/
|
|
111
|
+
export declare const RELEASE_STRATEGIES: readonly ["semver-by-level"];
|
|
112
|
+
/** One of {@link RELEASE_STRATEGIES}. */
|
|
113
|
+
export type ReleaseStrategy = (typeof RELEASE_STRATEGIES)[number];
|
|
114
|
+
/**
|
|
115
|
+
* How `rafa release settle` lands a settled version on the base branch:
|
|
116
|
+
* a push to it, or a pull request into it.
|
|
117
|
+
*/
|
|
118
|
+
export declare const RELEASE_SETTLE_MODES: readonly ["push", "pr"];
|
|
119
|
+
/** One of {@link RELEASE_SETTLE_MODES}. */
|
|
120
|
+
export type ReleaseSettleMode = (typeof RELEASE_SETTLE_MODES)[number];
|
|
121
|
+
/**
|
|
122
|
+
* Who puts the release tag on a settled version: a person through
|
|
123
|
+
* `rafa release tag`, or settle itself.
|
|
124
|
+
*/
|
|
125
|
+
export declare const RELEASE_TAG_MODES: readonly ["manual", "settle"];
|
|
126
|
+
/** One of {@link RELEASE_TAG_MODES}. */
|
|
127
|
+
export type ReleaseTagMode = (typeof RELEASE_TAG_MODES)[number];
|
|
128
|
+
/**
|
|
129
|
+
* Who publishes a tagged version: a person running the publish command
|
|
130
|
+
* `rafa release tag` names, or the CI workflow a pushed tag starts.
|
|
131
|
+
*/
|
|
132
|
+
export declare const RELEASE_PUBLISH_MODES: readonly ["manual", "ci"];
|
|
133
|
+
/** One of {@link RELEASE_PUBLISH_MODES}. */
|
|
134
|
+
export type ReleasePublishMode = (typeof RELEASE_PUBLISH_MODES)[number];
|
|
135
|
+
/**
|
|
136
|
+
* How `rafa pr merge` reacts to a branch the release guard reads as
|
|
137
|
+
* `missing` or `stale`: stay silent, report it, ask, or refuse it.
|
|
138
|
+
*/
|
|
139
|
+
export declare const VERSION_COLLISION_MODES: readonly ["allow", "report", "ask", "refuse"];
|
|
140
|
+
/** One of {@link VERSION_COLLISION_MODES}. */
|
|
141
|
+
export type VersionCollisionMode = (typeof VERSION_COLLISION_MODES)[number];
|
|
142
|
+
/** The reader of `release.strategy`. */
|
|
143
|
+
export declare const releaseStrategy: Reader<ReleaseStrategy>;
|
|
144
|
+
/** The reader of `release.settle`. */
|
|
145
|
+
export declare const releaseSettleMode: Reader<ReleaseSettleMode>;
|
|
146
|
+
/** The reader of `release.tag`. */
|
|
147
|
+
export declare const releaseTagMode: Reader<ReleaseTagMode>;
|
|
148
|
+
/** The reader of `release.publish`. */
|
|
149
|
+
export declare const releasePublishMode: Reader<ReleasePublishMode>;
|
|
150
|
+
/** The reader of `pr.versionCollision`. */
|
|
151
|
+
export declare const versionCollisionMode: Reader<VersionCollisionMode>;
|
|
152
|
+
/**
|
|
153
|
+
* The reader of `release.fragments`: a directory path relative to the
|
|
154
|
+
* repository root and not under `.rafa/`, kept as written; see "Path
|
|
155
|
+
* settings" in the module note.
|
|
156
|
+
*/
|
|
157
|
+
export declare const fragmentsDirectory: Reader<string>;
|
|
158
|
+
/** The marker a branch template holds once, where the plan's stub goes. */
|
|
159
|
+
export declare const BRANCH_STUB = "{stub}";
|
|
160
|
+
/** What `naming.branch` resolves to when no layer names it. */
|
|
161
|
+
export declare const DEFAULT_BRANCH_TEMPLATE: string;
|
|
162
|
+
/** True when `raw` is a string holding {@link BRANCH_STUB} exactly once; see "The branch template". */
|
|
163
|
+
export declare function isBranchTemplate(raw: unknown): raw is string;
|
|
164
|
+
/** The reader of `naming.branch`: a template {@link isBranchTemplate} accepts, kept as written. */
|
|
165
|
+
export declare const branchTemplate: Reader<string>;
|
|
166
|
+
/** The branch `template` names for a plan with this stub. */
|
|
167
|
+
export declare function branchFromTemplate(template: string, stub: string): string;
|
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The type half of rafa's settings: {@link RafaConfig}, the name of a
|
|
3
|
+
* setting, the settings a command line can name, and what a section
|
|
4
|
+
* knows about each setting it defines. This module declares types alone
|
|
5
|
+
* and exports no value: which settings exist at runtime, the file key
|
|
6
|
+
* each is spelled with, its reader and its default are the sections'
|
|
7
|
+
* to say.
|
|
8
|
+
*
|
|
9
|
+
* {@link RafaConfig} declares core's own fields here, and nothing else.
|
|
10
|
+
* Their file keys, readers and defaults are `core-section.ts`'s, which
|
|
11
|
+
* hands them in as `CORE_SECTION`. The other fields are the eleven
|
|
12
|
+
* section files' (`src/config-schema-*.ts`), each declaring its own
|
|
13
|
+
* interface and adding it to {@link RafaConfig} by declaration merging,
|
|
14
|
+
* a `declare module` on this file, so this module names no section file
|
|
15
|
+
* and {@link ConfigSetting} still names every setting. Nothing merged —
|
|
16
|
+
* the settings record, the defaults, the key indexes — is exported
|
|
17
|
+
* here: `src/config-registry.ts` merges the sections into them, and
|
|
18
|
+
* core reads the registered ones off `section.ts`.
|
|
19
|
+
*
|
|
20
|
+
* `config.ts` re-exports {@link RafaConfig}, {@link ConfigSetting} and
|
|
21
|
+
* {@link CommandLineSetting}, and the config barrel `index.ts` every
|
|
22
|
+
* name here, so nothing outside `packages/rafa/src/core/config/` imports this file.
|
|
23
|
+
*/
|
|
24
|
+
import type { ModuleSource, OptionalPrerequisiteItem, PrerequisiteItem } from './config-items.js';
|
|
25
|
+
import type { BoardRelationshipMode, ClaimsAhead, ClaimsStaleAfter, ClaudeSettingSource, ConfigVersion, DuplicatesLevel, InjectMode, LessonSwitch, OutputMode, Reader, RouteTarget, SkillResolverName, StoreBackend, SyncStrategy, TierPin, TierSwitch } from './config-sections.js';
|
|
26
|
+
/**
|
|
27
|
+
* Every setting, resolved. The fields below are core's, each naming the
|
|
28
|
+
* file key it holds; `core-section.ts` gives each its spec and default.
|
|
29
|
+
* A section file's fields join them by declaration merging, as the
|
|
30
|
+
* module note says.
|
|
31
|
+
*/
|
|
32
|
+
export interface RafaConfig {
|
|
33
|
+
/** The schema version the file was written for. `version`. */
|
|
34
|
+
version: ConfigVersion;
|
|
35
|
+
/** The backend the effort store writes through. `store`. */
|
|
36
|
+
store: StoreBackend;
|
|
37
|
+
/**
|
|
38
|
+
* How long an effort store open waits for another process's write
|
|
39
|
+
* lock, in milliseconds. `effort.busyTimeoutMs`.
|
|
40
|
+
*/
|
|
41
|
+
effortBusyTimeoutMs: number;
|
|
42
|
+
/** How the effort store travels between devices. `effort.sync`. */
|
|
43
|
+
effortSync: SyncStrategy;
|
|
44
|
+
/** How much of the plan a task prompt receives. `plan.inject`. */
|
|
45
|
+
inject: InjectMode;
|
|
46
|
+
/** Where plans are written and read. `plan.dir`. */
|
|
47
|
+
planDir: string;
|
|
48
|
+
/** Where specs are read. `specs.dir`. */
|
|
49
|
+
specsDir: string;
|
|
50
|
+
/** The tracker kind tried first. `tracker.default`. */
|
|
51
|
+
trackerDefault: string;
|
|
52
|
+
/** The tracker kinds tried next, in order. `tracker.fallback`. */
|
|
53
|
+
trackerFallback: readonly string[];
|
|
54
|
+
/** The learning adapter kind. `learning.adapter`. */
|
|
55
|
+
learningAdapter: string;
|
|
56
|
+
/** The least confidence a lesson tasks may use. `learning.bless.minConfidence`. */
|
|
57
|
+
learningBlessMinConfidence: number;
|
|
58
|
+
/** The distinct sources a lesson needs to be promotable. `learning.promote.after`. */
|
|
59
|
+
learningPromoteAfter: number;
|
|
60
|
+
/** The least confidence of a promotable lesson. `learning.promote.minConfidence`. */
|
|
61
|
+
learningPromoteMinConfidence: number;
|
|
62
|
+
/** How commands write their output. `output.mode`. */
|
|
63
|
+
outputMode: OutputMode;
|
|
64
|
+
/** Items whose failure halts a run. `prerequisites.required`. */
|
|
65
|
+
prerequisitesRequired: readonly PrerequisiteItem[];
|
|
66
|
+
/** Items whose failure is only named. `prerequisites.optional`. */
|
|
67
|
+
prerequisitesOptional: readonly OptionalPrerequisiteItem[];
|
|
68
|
+
/** Whether `.rafa/specs/` is tracked by git. `tracking.specs`. */
|
|
69
|
+
trackingSpecs: boolean;
|
|
70
|
+
/** Whether `.rafa/plans/` is tracked by git. `tracking.plans`. */
|
|
71
|
+
trackingPlans: boolean;
|
|
72
|
+
/** Whether all of `.rafa/` is tracked by git. `tracking.all`. */
|
|
73
|
+
trackingAll: boolean;
|
|
74
|
+
/** Where modules are installed from. `modules`. */
|
|
75
|
+
modules: readonly ModuleSource[];
|
|
76
|
+
/** The module names enabled. `allowList`. */
|
|
77
|
+
allowList: readonly string[];
|
|
78
|
+
/** What each spawned session loads settings from. `loop.settingSources`. */
|
|
79
|
+
settingSources: readonly ClaudeSettingSource[];
|
|
80
|
+
/**
|
|
81
|
+
* The directory a loop adds its worktrees under, read from the
|
|
82
|
+
* project root. `loop.worktreeDir`.
|
|
83
|
+
*/
|
|
84
|
+
loopWorktreeDir: string;
|
|
85
|
+
/**
|
|
86
|
+
* The logins trusted with board text besides the repository's own
|
|
87
|
+
* write-holders. `board.trustedAuthors`.
|
|
88
|
+
*/
|
|
89
|
+
boardTrustedAuthors: readonly string[];
|
|
90
|
+
/**
|
|
91
|
+
* Where the board's epics and blockers are read and written: `labels`
|
|
92
|
+
* (`epic:` labels, `spec:blocked` and `Blocked by:` lines) or `native`
|
|
93
|
+
* (GitHub's sub-issue parent and blocked-by links).
|
|
94
|
+
* `board.relationships`.
|
|
95
|
+
*/
|
|
96
|
+
boardRelationships: BoardRelationshipMode;
|
|
97
|
+
/**
|
|
98
|
+
* The GitHub project `rafa init --board` copies the board's project
|
|
99
|
+
* from, by URL. `board.project.template`.
|
|
100
|
+
*/
|
|
101
|
+
boardProjectTemplate: string;
|
|
102
|
+
/**
|
|
103
|
+
* The number of the GitHub project the board is mirrored to, under the
|
|
104
|
+
* repository's owner, or null for a repository with no project.
|
|
105
|
+
* `board.project.number`.
|
|
106
|
+
*/
|
|
107
|
+
boardProjectNumber: number | null;
|
|
108
|
+
/**
|
|
109
|
+
* The issue whose task list `plan create --next` reads its order off,
|
|
110
|
+
* or null for the issue titled `Roadmap`. `roadmap.issue`.
|
|
111
|
+
*/
|
|
112
|
+
roadmapIssue: number | null;
|
|
113
|
+
/**
|
|
114
|
+
* How long a `rafa:claimed` claim stands before another device may
|
|
115
|
+
* take it over, or `disabled`. `claims.staleAfter`.
|
|
116
|
+
*/
|
|
117
|
+
claimsStaleAfter: ClaimsStaleAfter;
|
|
118
|
+
/** Whether a claim may reach one issue ahead. `claims.ahead`. */
|
|
119
|
+
claimsAhead: ClaimsAhead;
|
|
120
|
+
/**
|
|
121
|
+
* The age in days past which `rafa cleanup` lists a branch as Stale.
|
|
122
|
+
* `cleanup.staleDays`.
|
|
123
|
+
*/
|
|
124
|
+
cleanupStaleDays: number;
|
|
125
|
+
/**
|
|
126
|
+
* The idle days past which `rafa cleanup` lists a worktree.
|
|
127
|
+
* `cleanup.worktreeIdleDays`.
|
|
128
|
+
*/
|
|
129
|
+
cleanupWorktreeIdleDays: number;
|
|
130
|
+
/** Glob patterns naming branches `rafa cleanup` never lists. `cleanup.keep`. */
|
|
131
|
+
cleanupKeep: readonly string[];
|
|
132
|
+
/**
|
|
133
|
+
* Whether check 4 of the readiness gate accepts every dangling and
|
|
134
|
+
* suspect reference of a spec on every run, as `--accept-refs` does
|
|
135
|
+
* on one. `dangerous.acceptStaleRefs`.
|
|
136
|
+
*/
|
|
137
|
+
dangerousAcceptStaleRefs: boolean;
|
|
138
|
+
/**
|
|
139
|
+
* Whether `rafa self-update` replaces the install while a loop of the
|
|
140
|
+
* project is live, where it otherwise waits for that loop to finish.
|
|
141
|
+
* `dangerous.selfUpdateDuringLoop`.
|
|
142
|
+
*/
|
|
143
|
+
dangerousSelfUpdateDuringLoop: boolean;
|
|
144
|
+
/**
|
|
145
|
+
* Whether a command that runs inside a project prints the one-line
|
|
146
|
+
* since-last-command notice on stderr. `status.notice`.
|
|
147
|
+
*/
|
|
148
|
+
statusNotice: boolean;
|
|
149
|
+
/** Whether the tier rafa ships is loaded. `tiers.rafa`. */
|
|
150
|
+
tiersRafa: TierSwitch;
|
|
151
|
+
/**
|
|
152
|
+
* Skills turned off (`false`) or pinned to the tier that serves them,
|
|
153
|
+
* by name. `tiers.skills`.
|
|
154
|
+
*/
|
|
155
|
+
tiersSkills: ReadonlyMap<string, TierPin>;
|
|
156
|
+
/**
|
|
157
|
+
* Agents turned off (`false`) or pinned to the tier that serves them,
|
|
158
|
+
* by name. `tiers.agents`.
|
|
159
|
+
*/
|
|
160
|
+
tiersAgents: ReadonlyMap<string, TierPin>;
|
|
161
|
+
/**
|
|
162
|
+
* The agent each task shape is routed to, or `false` for a shape
|
|
163
|
+
* routed nowhere. `routing`.
|
|
164
|
+
*/
|
|
165
|
+
routing: ReadonlyMap<string, RouteTarget>;
|
|
166
|
+
/** The resolver that picks each task's skills at dispatch. `task.skills`. */
|
|
167
|
+
taskSkills: SkillResolverName;
|
|
168
|
+
/** Whether blessed lessons join each task's prompt. `task.lessons`. */
|
|
169
|
+
taskLessons: LessonSwitch;
|
|
170
|
+
/**
|
|
171
|
+
* How two entries of one config file setting one key are reported:
|
|
172
|
+
* `warn`, `error` or `allow`. `merge.duplicates`.
|
|
173
|
+
*/
|
|
174
|
+
mergeDuplicates: DuplicatesLevel;
|
|
175
|
+
/**
|
|
176
|
+
* The template a plan's branch is named from, holding `{stub}` exactly
|
|
177
|
+
* once; `loop start` creates the branch it names. `naming.branch`.
|
|
178
|
+
*/
|
|
179
|
+
namingBranch: string;
|
|
180
|
+
}
|
|
181
|
+
/** The name of one setting, as a field of {@link RafaConfig}. */
|
|
182
|
+
export type ConfigSetting = keyof RafaConfig;
|
|
183
|
+
/**
|
|
184
|
+
* The settings a command line can name. A flag parser hands over
|
|
185
|
+
* strings, so these are the settings the file spells as one string: a
|
|
186
|
+
* list, a boolean or a mapping has no command-line spelling this module
|
|
187
|
+
* would have to invent.
|
|
188
|
+
*/
|
|
189
|
+
export type CommandLineSetting = 'store' | 'inject' | 'planDir' | 'specsDir' | 'trackerDefault' | 'learningAdapter' | 'outputMode' | 'settingSources' | 'taskSkills';
|
|
190
|
+
/** What a section knows about one setting it defines. */
|
|
191
|
+
export interface SettingSpec<K extends ConfigSetting> {
|
|
192
|
+
/** Where the file spells it, as a dotted path. */
|
|
193
|
+
key: string;
|
|
194
|
+
/** The reader deciding which raw values it accepts. */
|
|
195
|
+
read: Reader<RafaConfig[K]>;
|
|
196
|
+
/** Whether a command line can name it; checked against the type. */
|
|
197
|
+
cli: K extends CommandLineSetting ? true : false;
|
|
198
|
+
/** For a list of mappings, the keys each item reads. */
|
|
199
|
+
itemKeys?: readonly string[];
|
|
200
|
+
/**
|
|
201
|
+
* Whether the value is a map that `resolveConfig` (`config.ts`) merges
|
|
202
|
+
* by key across the default, the user's file and the project's, the
|
|
203
|
+
* later layer's entry winning for a key both name. Unset, a layer's
|
|
204
|
+
* value replaces a lower layer's whole.
|
|
205
|
+
*/
|
|
206
|
+
map?: true;
|
|
207
|
+
}
|