@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,101 @@
1
+ /**
2
+ * The records the Learning port passes, and the answers it gives: core's
3
+ * declaration of the six types `packages/rafa/src/ports/index.ts` names for it.
4
+ *
5
+ * The learning library declares the same six in `src/learning/types.ts`
6
+ * and keeps them there. `src/learning/` imports nothing from the rest of
7
+ * `src/`, and core imports nothing above it, so neither side can take
8
+ * the other's declaration: each declares its own, and
9
+ * `src/tests/learning-contract.test.ts` holds every pair mutually
10
+ * assignable, so a field added, dropped or retyped on one side alone
11
+ * fails to compile there.
12
+ *
13
+ * Types only, as `index.ts` and `log-level.ts` beside it are: the module
14
+ * holds no runtime value, so importing it runs nothing. The fields are
15
+ * snake case, as the distributed-learning spec spells the record a sync
16
+ * payload carries.
17
+ */
18
+ /**
19
+ * One instinct: a trigger, the action to take on it, and how far to
20
+ * trust that action.
21
+ */
22
+ export interface InstinctRecord {
23
+ id: string;
24
+ trigger: string;
25
+ action: string;
26
+ /** `sha256(trim(lower(action)))`: two records share an action by it. */
27
+ action_hash: string;
28
+ /** From 0.3 to 0.9. */
29
+ confidence: number;
30
+ /**
31
+ * The weight a merge gives the confidence. Once a record carries
32
+ * {@link InstinctRecord.sources}, it equals that list's length.
33
+ */
34
+ usage_count: number;
35
+ /**
36
+ * The distinct `source_id`s that confirmed the record. A merge takes
37
+ * the union, which is what makes a source pushing one record twice
38
+ * count once. Left out by a record written before sources were kept.
39
+ */
40
+ sources?: string[];
41
+ /** The recurrence key; phase 2's field. */
42
+ artifact?: string;
43
+ signal: 'loud' | 'silent';
44
+ /** A `flagged` record is excluded from every blessed bundle. */
45
+ status: 'active' | 'flagged';
46
+ /**
47
+ * The path of the page the wrap-up wrote the record into. A promoted
48
+ * record leaves every blessed bundle, because the page now carries it.
49
+ */
50
+ promoted_to?: string;
51
+ created_at: string;
52
+ updated_at: string;
53
+ }
54
+ /**
55
+ * What one source pushes. Under the `local` adapter the source is the
56
+ * task's session id, so two tasks of one plan are two sources.
57
+ */
58
+ export interface SyncPayload {
59
+ source_id: string;
60
+ instincts: InstinctRecord[];
61
+ }
62
+ /** What a pull answers: the instincts blessed for injection. */
63
+ export interface BlessedBundle {
64
+ version: string;
65
+ instincts: InstinctRecord[];
66
+ }
67
+ /**
68
+ * The rule a merge applied to one incoming record, one per row of the
69
+ * spec's merge table plus the record whose trigger nothing shares:
70
+ *
71
+ * - `new-trigger`: no held record shares the trigger, so it is kept.
72
+ * - `same-action`: the same `action_hash`, so the confidences are
73
+ * weighted by usage and the sources joined.
74
+ * - `higher-confidence`: a different action, confidences more than
75
+ * 0.10 apart, so the higher one wins.
76
+ * - `flagged`: a different action, confidences within 0.10, so both
77
+ * are kept and flagged.
78
+ */
79
+ export type MergeRule = 'new-trigger' | 'same-action' | 'higher-confidence' | 'flagged';
80
+ /** Which rule applied to one incoming record, and what it produced. */
81
+ export interface MergeDecision {
82
+ incoming: InstinctRecord;
83
+ rule: MergeRule;
84
+ /** The records the trigger is held as once the rule has applied. */
85
+ produced: InstinctRecord[];
86
+ }
87
+ /**
88
+ * What a merge did, so a consumer can log each decision.
89
+ *
90
+ * The spec names `discarded` and describes the rest, a list saying which
91
+ * rule applied to each incoming record and what it produced, without
92
+ * naming it; `decisions`, {@link MergeDecision} and the
93
+ * {@link MergeRule} names are the learning library's, and this module
94
+ * spells them as the library does.
95
+ */
96
+ export interface MergeResult {
97
+ /** One per incoming record, in the payload's order. */
98
+ decisions: MergeDecision[];
99
+ /** The records a higher-confidence action displaced; none is deleted. */
100
+ discarded: InstinctRecord[];
101
+ }
@@ -0,0 +1,13 @@
1
+ /**
2
+ * The logger's level, in a leaf of its own so a module that needs only
3
+ * the level (the logger's settings, the config section that reads them)
4
+ * imports it without reaching the rest of `./ports`. `packages/rafa/src/ports/index.ts`
5
+ * re-exports it, so the `./ports` subpath names it unchanged.
6
+ */
7
+ /**
8
+ * How loud a log entry is, or `api` for the metadata of one request and
9
+ * its response. `error`, `warn` and `debug` are ordered, quietest first;
10
+ * `api` sits outside that order and is turned on by itself. There is no
11
+ * `info`: that is a command's own text, which goes through `Output`.
12
+ */
13
+ export type LogLevel = 'error' | 'warn' | 'debug' | 'api';
@@ -0,0 +1,66 @@
1
+ /**
2
+ * The shapes a spec review is read into: the verdicts and readings a
3
+ * `rafa:spec-review` block answers, the gaps it names and the issues it
4
+ * reports. Core's `Planner` port names {@link SpecReviewReading}, so they
5
+ * sit here, below the board; `src/board/spec-review.ts` reads the block
6
+ * into them, re-exports them under the same names, and keeps the parser,
7
+ * the headings and the two fallback gaps.
8
+ */
9
+ import type { RafaBlock } from '../core/plan/block-reader.js';
10
+ /** The two words the block's `verdict` is spelled with. */
11
+ export declare const SPEC_REVIEW_VERDICTS: readonly ["ready", "not-ready"];
12
+ /** One of the two verdicts a session can write. */
13
+ export type SpecReviewVerdict = (typeof SPEC_REVIEW_VERDICTS)[number];
14
+ /**
15
+ * The four readings a session output answers. The first two are the
16
+ * verdicts as written; the last two are a block that could not be read,
17
+ * and are not-ready all the same.
18
+ */
19
+ export declare const SPEC_REVIEW_ANSWERS: readonly ["ready", "not-ready", "absent", "malformed"];
20
+ /** One of the four readings; see {@link SPEC_REVIEW_ANSWERS}. */
21
+ export type SpecReviewAnswer = (typeof SPEC_REVIEW_ANSWERS)[number];
22
+ /** One thing the planner found keeping a spec from being planned from. */
23
+ export interface SpecReviewGap {
24
+ /** The spec heading it sits under, as the comment names it. */
25
+ readonly heading: string;
26
+ /** What is wrong under that heading, as the session wrote it. */
27
+ readonly what: string;
28
+ /**
29
+ * True when guessing wrong here changes what ships or what is safe,
30
+ * so nothing can be planned until the spec answers it. True for
31
+ * every gap whose `blocking` was unreadable and for every
32
+ * non-blocking one that named no assumption; see the module note.
33
+ */
34
+ readonly blocking: boolean;
35
+ /**
36
+ * What the planner would plan under, as the session wrote it. Never
37
+ * null for a gap that is not blocking; null for a blocking gap that
38
+ * named none.
39
+ */
40
+ readonly assumption: string | null;
41
+ }
42
+ /** One thing the block said that this reading does not hold as written. */
43
+ export interface SpecReviewIssue {
44
+ /** Where, in the block's own key names: `gaps[2].what`. */
45
+ readonly field: string;
46
+ /** One sentence for an operator to read. */
47
+ readonly text: string;
48
+ }
49
+ /** A session output, read for its `rafa:spec-review` block. */
50
+ export interface SpecReviewReading {
51
+ /** Which of the four readings this is. */
52
+ readonly answer: SpecReviewAnswer;
53
+ /** True for `ready` alone; what the gate acts on. */
54
+ readonly ready: boolean;
55
+ /**
56
+ * Every gap to post. Empty only for a ready reading; see the module
57
+ * note for what fills it when the session named none.
58
+ */
59
+ readonly gaps: readonly SpecReviewGap[];
60
+ /** The last `rafa:spec-review` block, or null when there is none. */
61
+ readonly block: RafaBlock | null;
62
+ /** One sentence for an operator to read. */
63
+ readonly text: string;
64
+ /** What was not read as written. Empty for a clean block. */
65
+ readonly issues: readonly SpecReviewIssue[];
66
+ }
@@ -0,0 +1,133 @@
1
+ /**
2
+ * The check-row readers of a pull request: raw `gh pr checks` output in,
3
+ * one verdict out.
4
+ *
5
+ * A PR is not finished until CI has spoken about it, and two failure
6
+ * shapes made that worth automating rather than leaving to the session's
7
+ * judgement:
8
+ *
9
+ * - A CONFLICTING PR schedules no workflow run at all, because GitHub
10
+ * cannot build `refs/pull/<n>/merge` for a branch that does not merge
11
+ * cleanly. The loop would report a finished plan whose code had never
12
+ * been through CI once.
13
+ * - A resolved conflict can still red the whole battery at its first
14
+ * step (a lockfile out of step with the merged manifests fails
15
+ * `bun install --frozen-lockfile`, and nothing downstream runs).
16
+ *
17
+ * Both are invisible from inside the session that pushed.
18
+ *
19
+ * ## Zero rows is two readings, and the head's age tells them apart
20
+ *
21
+ * GitHub registers a push's runs some seconds after the push, so a poll
22
+ * in that gap reads zero rows off a pull request whose checks are about
23
+ * to appear. Zero rows on an OLD head is the settled reading above: no
24
+ * run is coming. So a caller that knows when the head was committed
25
+ * hands that time over ({@link WaitOptions.headCommittedAtMs}), and zero
26
+ * rows on a head younger than {@link FIRST_CHECK_GRACE_MS} is polled
27
+ * again like a pending reading. A caller that hands over no time gets
28
+ * `none` on the first poll, as every caller did before the grace
29
+ * existed: the loop's CI gate and `pr triage --resolve` hand over none.
30
+ *
31
+ * The time is the head commit's COMMITTED date, which is not the push
32
+ * time: a commit made an hour ago and pushed just now reads as old and
33
+ * gets no grace. A provider answers a committed date and no push time,
34
+ * and the wrong direction of that error is the cheap one, since it is
35
+ * the behaviour there was before.
36
+ *
37
+ * Everything here is pure: the only effect {@link waitForChecks} has is
38
+ * the `probe` handed to it, and its clock and its wait are injected too,
39
+ * so the polling logic is testable without a network or a timer. The
40
+ * `gh` invocations that feed it live with the rest of the port, not
41
+ * here, which is what keeps `checks.test.ts` free of a process spawn.
42
+ *
43
+ * {@link waitForChecks} polls ROWS rather than stdout, so the poll runs
44
+ * over `PullRequests.checks` (`./types.ts`) without either side naming
45
+ * the CLI. {@link parseChecks} is what turns one provider's stdout into
46
+ * those rows, and the `gh` adapter is its only caller.
47
+ *
48
+ * The row type, the verdict type, {@link verdictOf} and `failingRows`
49
+ * are core's (`packages/rafa/src/effort/store/check-rows.ts`), where the store's plan
50
+ * CI writer reads them; this file re-exports them under the same names.
51
+ */
52
+ import type { CheckOutcome, CheckRow, ChecksVerdict } from '@open-tomato/rafa/store/check-rows';
53
+ export type { CheckOutcome, CheckRow, ChecksVerdict } from '@open-tomato/rafa/store/check-rows';
54
+ export { failingRows, verdictOf } from '@open-tomato/rafa/store/check-rows';
55
+ /**
56
+ * Maps a GitHub check state onto an outcome.
57
+ *
58
+ * An UNRECOGNISED state counts as pending on purpose: the alternative is
59
+ * declaring a run green on a state nobody classified, and a wrong green
60
+ * here lands a plan whose CI never agreed. Waiting is recoverable — the
61
+ * deadline ends it and the raw state is printed in the summary.
62
+ */
63
+ export declare function classifyState(state: string): CheckOutcome;
64
+ /**
65
+ * Parses `gh pr checks --json name,state,link` output into rows.
66
+ *
67
+ * Returns an empty list for anything that is not a JSON array — `gh`
68
+ * writes a plain `no checks reported` message and exits non-zero when a
69
+ * PR has none, and that is a verdict here rather than an error.
70
+ */
71
+ export declare function parseChecks(stdout: string): CheckRow[];
72
+ /** One line per check, for the console and for a repair prompt. */
73
+ export declare function formatRows(rows: readonly CheckRow[]): string;
74
+ /**
75
+ * How long after a head commit zero rows still reads as "no check has
76
+ * registered yet" rather than "no check is coming": two minutes.
77
+ *
78
+ * Measured from the head commit's committed date, by the clock
79
+ * {@link waitForChecks} was handed. It is a ceiling on one wait as well:
80
+ * a head dated ahead of that clock is held no longer than this from the
81
+ * wait's own first poll.
82
+ */
83
+ export declare const FIRST_CHECK_GRACE_MS = 120000;
84
+ export interface WaitOptions {
85
+ /**
86
+ * The rows of one poll. A caller on the port hands
87
+ * `PullRequests.checks` here, and a caller holding raw
88
+ * `gh pr checks --json ...` stdout hands {@link parseChecks} of it.
89
+ */
90
+ probe: () => Promise<readonly CheckRow[]>;
91
+ timeoutMs: number;
92
+ intervalMs: number;
93
+ /** Injected for tests; defaults to the real clock. */
94
+ now?: () => number;
95
+ /** Injected for tests; defaults to a real timer. */
96
+ sleep?: (ms: number) => Promise<void>;
97
+ /**
98
+ * Called after every poll, for progress output. The verdict is the one
99
+ * the wait acts on, so a poll of zero rows the grace holds is reported
100
+ * `pending`, which is why it is polled again.
101
+ */
102
+ onPoll?: (rows: readonly CheckRow[], verdict: ChecksVerdict, elapsedMs: number) => void;
103
+ /**
104
+ * When the pull request's head was committed, in the milliseconds
105
+ * `now` answers in. Handed over, zero rows on a head younger than
106
+ * {@link FIRST_CHECK_GRACE_MS} is polled again; left out, or a value
107
+ * that is no finite number, zero rows ends `none` on the first poll.
108
+ */
109
+ headCommittedAtMs?: number;
110
+ }
111
+ export interface WaitResult {
112
+ /** `timeout` means the deadline passed while checks were still running. */
113
+ verdict: ChecksVerdict | 'timeout';
114
+ rows: readonly CheckRow[];
115
+ elapsedMs: number;
116
+ polls: number;
117
+ }
118
+ /**
119
+ * Polls a PR's checks until they settle, the deadline passes, or the PR
120
+ * reports no checks at all.
121
+ *
122
+ * `none` returns rather than waiting out the deadline: a PR with no
123
+ * checks is conflicting, has no workflow matching its changed paths, or
124
+ * was pushed so recently that none has registered. Only the last
125
+ * resolves by waiting, and only for {@link FIRST_CHECK_GRACE_MS}, so
126
+ * zero rows is polled again while {@link WaitOptions.headCommittedAtMs}
127
+ * says the head is that young and ends `none` otherwise. The caller
128
+ * tells the first two apart, since only it knows the merge state.
129
+ *
130
+ * A deadline that passes inside the grace ends `timeout`, with no rows,
131
+ * as it does for any reading that was still being polled.
132
+ */
133
+ export declare function waitForChecks(options: WaitOptions): Promise<WaitResult>;