@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,75 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The plan marker the loop stamps onto every prompt it dispatches.
|
|
3
|
+
*
|
|
4
|
+
* Effort attribution used to reach a session's plan through its BRANCH
|
|
5
|
+
* NAME, which works only while a run happens on a branch whose stub
|
|
6
|
+
* resolves. Measured after one run executed on `main`: all 74 of its
|
|
7
|
+
* sessions attributed to the `main` branch group instead of the plan,
|
|
8
|
+
* and the group they landed in mixes every main-branch session ever
|
|
9
|
+
* recorded, so the plan's figures were not recoverable from the store
|
|
10
|
+
* without knowing the run's wall-clock window by hand.
|
|
11
|
+
*
|
|
12
|
+
* Two of those sessions in three could not have been recovered by any
|
|
13
|
+
* derivation either. A task session carries the tracker line it was
|
|
14
|
+
* dispatched with, so its plan is at least derivable from the tracker
|
|
15
|
+
* text; a compaction and a wrap-up session carried neither the plan
|
|
16
|
+
* path nor the stub anywhere in their prompts, measured across both
|
|
17
|
+
* shapes before the wrap-up was handed its plan.
|
|
18
|
+
* So the signal did not exist to be inferred, and the fix is to WRITE
|
|
19
|
+
* one rather than to guess better.
|
|
20
|
+
*
|
|
21
|
+
* The marker is an HTML comment because every prompt this loop builds
|
|
22
|
+
* is markdown handed to a model: a comment carries no instruction, and
|
|
23
|
+
* a model that echoes the prompt back cannot turn it into one.
|
|
24
|
+
*
|
|
25
|
+
* It is APPENDED and never prepended, and that is load-bearing rather
|
|
26
|
+
* than cosmetic. `effort/classify.ts` buckets a session by
|
|
27
|
+
* `content.startsWith(shape.prefix)` over the WHOLE prompt, so one
|
|
28
|
+
* line above the body re-buckets every one of the four shapes as
|
|
29
|
+
* `other` — silently, because that module's drift guard is a
|
|
30
|
+
* containment check that would stay green. `start/wrap-up.ts` states
|
|
31
|
+
* the same rule at its wrap-up builder: add lines after line 1, never
|
|
32
|
+
* before it. {@link planStubFromPrompt} therefore SEARCHES rather than
|
|
33
|
+
* matching a prefix, which is what lets the marker sit at the end.
|
|
34
|
+
*
|
|
35
|
+
* A stub is written verbatim and matched against the same character
|
|
36
|
+
* class `readPlanStubs` derives from a filename, so a stamp can never
|
|
37
|
+
* name a stub the store could not also have resolved from a branch.
|
|
38
|
+
*/
|
|
39
|
+
/** True when the text is usable as a stamped stub. */
|
|
40
|
+
export declare function isStampableStub(stub: string): boolean;
|
|
41
|
+
/**
|
|
42
|
+
* Builds the marker line for one plan stub.
|
|
43
|
+
*
|
|
44
|
+
* Throws on a stub the pattern would not match, rather than writing a
|
|
45
|
+
* marker {@link planStubFromPrompt} could not read back. A stamp that
|
|
46
|
+
* silently fails to parse is worse than no stamp: it reports as an
|
|
47
|
+
* unattributed session while looking like it was handled.
|
|
48
|
+
*/
|
|
49
|
+
export declare function planStampLine(stub: string): string;
|
|
50
|
+
/**
|
|
51
|
+
* Reads the stub back out of a dispatched prompt, or null.
|
|
52
|
+
*
|
|
53
|
+
* Null for absent content, for a prompt carrying no marker, and for a
|
|
54
|
+
* marker whose stub does not match the class — the three cases a
|
|
55
|
+
* caller treats alike, since each means the session has no stamped
|
|
56
|
+
* plan and must fall back to its branch.
|
|
57
|
+
*/
|
|
58
|
+
export declare function planStubFromPrompt(content: string | null | undefined): string | null;
|
|
59
|
+
/**
|
|
60
|
+
* Appends the marker to a prompt the loop is about to dispatch.
|
|
61
|
+
*
|
|
62
|
+
* Never prepends: the first line is a classifier key, and the module
|
|
63
|
+
* note above carries the measurement.
|
|
64
|
+
*/
|
|
65
|
+
export declare function stampPrompt(stub: string, prompt: string): string;
|
|
66
|
+
/**
|
|
67
|
+
* Derives a plan stub from a plan or tracker path.
|
|
68
|
+
*
|
|
69
|
+
* `PLAN-q16a-compose-n8n.md` and `PLAN_TRACKER-q16a-compose-n8n.md`
|
|
70
|
+
* both answer `q16a-compose-n8n`; a bare `PLAN.md` answers null,
|
|
71
|
+
* having no stub to name. Null rather than a fallback string: an
|
|
72
|
+
* unstubbed plan is exactly the case a stamp must not invent a group
|
|
73
|
+
* for, and the caller reports it instead.
|
|
74
|
+
*/
|
|
75
|
+
export declare function planStubFromPath(planPath: string): string | null;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/** An installed runtime: a runtime copy, or the package installed from npm. */
|
|
2
|
+
export interface InstalledIdentity {
|
|
3
|
+
readonly kind: 'installed';
|
|
4
|
+
/** The entry file, through its real path when it exists. */
|
|
5
|
+
readonly entry: string;
|
|
6
|
+
}
|
|
7
|
+
/** A development build: rafa run from a checkout. */
|
|
8
|
+
export interface DevelopmentIdentity {
|
|
9
|
+
readonly kind: 'development';
|
|
10
|
+
/** The entry file, through its real path when it exists. */
|
|
11
|
+
readonly entry: string;
|
|
12
|
+
/** The checkout's root, the directory holding its `package.json` and `src/rafa.ts`. */
|
|
13
|
+
readonly checkout: string;
|
|
14
|
+
}
|
|
15
|
+
/** Which build is running; see the module note. */
|
|
16
|
+
export type RuntimeIdentity = InstalledIdentity | DevelopmentIdentity;
|
|
17
|
+
/**
|
|
18
|
+
* Which build runs from `entry`, `Bun.main` by default. See the module
|
|
19
|
+
* note for the walk.
|
|
20
|
+
*/
|
|
21
|
+
export declare function readRuntimeIdentity(entry?: string): RuntimeIdentity;
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The barrel over the runtime identity: every name `identity.ts`
|
|
3
|
+
* exports, and nothing else.
|
|
4
|
+
*
|
|
5
|
+
* A file outside `packages/rafa/src/core/` imports this file and never the one behind
|
|
6
|
+
* it (`scripts/survey/core-barrels.ts` measures that, and
|
|
7
|
+
* `src/tests/core-barrels.sweep.test.ts` holds it against the tree). A
|
|
8
|
+
* file inside `packages/rafa/src/core/` imports `identity.ts` directly and never this
|
|
9
|
+
* file. The effort store under `packages/rafa/src/effort/store/` is core by
|
|
10
|
+
* assignment and not by folder, so it is outside `packages/rafa/src/core/` for the
|
|
11
|
+
* rule and imports this file.
|
|
12
|
+
*
|
|
13
|
+
* ## What sits behind it
|
|
14
|
+
*
|
|
15
|
+
* `identity.ts` alone: {@link readRuntimeIdentity}, which reads whether
|
|
16
|
+
* the running build is an installed runtime or a development build run
|
|
17
|
+
* from a checkout, and the three types it answers with. It moved here
|
|
18
|
+
* from `src/runtime/identity.ts` (#1088), so the effort store, which
|
|
19
|
+
* asks it before it migrates a live store, imports nothing above core
|
|
20
|
+
* for it.
|
|
21
|
+
*
|
|
22
|
+
* ## Why one barrel can hold it
|
|
23
|
+
*
|
|
24
|
+
* A barrel that groups a file with a file outside `packages/rafa/src/core/` that
|
|
25
|
+
* imports the barrel back by value is a runtime cycle. `identity.ts`
|
|
26
|
+
* imports `node:fs`, `node:path` and the root `package.json`, and no
|
|
27
|
+
* file under `src/`, so no file behind this barrel reaches a file that
|
|
28
|
+
* imports it back.
|
|
29
|
+
*
|
|
30
|
+
* ## The old path
|
|
31
|
+
*
|
|
32
|
+
* `src/runtime/identity.ts` re-exported this file's names under the same
|
|
33
|
+
* names until core moved into its package (#1090), which deleted it and
|
|
34
|
+
* pointed its importers at `@open-tomato/rafa/core/runtime`.
|
|
35
|
+
*
|
|
36
|
+
* ## What it exports
|
|
37
|
+
*
|
|
38
|
+
* Each name is spelled, types apart from values, as the other core
|
|
39
|
+
* barrels spell theirs. No name here is part of the published surface:
|
|
40
|
+
* `src/index.ts` re-exports nothing from this file.
|
|
41
|
+
*
|
|
42
|
+
* `index.test.ts` holds the list to the file: every name `identity.ts`
|
|
43
|
+
* exports is here once, as the same binding, and no other name is here.
|
|
44
|
+
*/
|
|
45
|
+
export type { DevelopmentIdentity, InstalledIdentity, RuntimeIdentity } from './identity.js';
|
|
46
|
+
export { readRuntimeIdentity } from './identity.js';
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The log-aware open: bring a SQLite store to this build's migrations,
|
|
3
|
+
* recording each one in the store's migration log, or refuse it.
|
|
4
|
+
*
|
|
5
|
+
* ## The migration log
|
|
6
|
+
*
|
|
7
|
+
* `schema_migrations` holds one row per migration the store holds: its
|
|
8
|
+
* id, the sha256 of its SQL, what it `breaks` as a JSON array of words,
|
|
9
|
+
* when it was applied and by which rafa. {@link bringForward} creates the
|
|
10
|
+
* table in the same transaction as the rows it first records, so a store
|
|
11
|
+
* never holds an empty log it was not given in that transaction.
|
|
12
|
+
*
|
|
13
|
+
* ## What an open does
|
|
14
|
+
*
|
|
15
|
+
* {@link bringForward} reads the log and `user_version`, and hands them
|
|
16
|
+
* to `planSchema` (`schema-plan.ts`), which decides. A refusal is thrown
|
|
17
|
+
* as a {@link SchemaRefusedError} carrying the plan's reason, message and
|
|
18
|
+
* next step, and nothing is written. A plan with nothing to adopt or
|
|
19
|
+
* apply returns at once, taking no lock and writing nothing, so a read
|
|
20
|
+
* open of a current store never writes.
|
|
21
|
+
*
|
|
22
|
+
* Otherwise the open takes the write lock with `BEGIN IMMEDIATE`, reads
|
|
23
|
+
* the store again and plans again, since another process may have
|
|
24
|
+
* brought the store forward, or recorded a migration this build does
|
|
25
|
+
* not know, while this one waited. Under that second plan, and in one
|
|
26
|
+
* transaction, it:
|
|
27
|
+
*
|
|
28
|
+
* - creates `schema_migrations` when the store has none;
|
|
29
|
+
* - adopts a store with no log: the legacy entries its `user_version`
|
|
30
|
+
* counts are logged with this build's checksums and not run, since
|
|
31
|
+
* a shipped entry is frozen and so is what ran;
|
|
32
|
+
* - runs each pending migration's SQL and logs it, in catalogue order;
|
|
33
|
+
* - sets `user_version` to the gate the plan answers.
|
|
34
|
+
*
|
|
35
|
+
* A throw anywhere rolls all of it back, `user_version` included, and
|
|
36
|
+
* leaves the store as it was found. The second plan can find nothing
|
|
37
|
+
* left to do, which is the answer when another process applied the same
|
|
38
|
+
* migrations first; the transaction then writes nothing.
|
|
39
|
+
*
|
|
40
|
+
* A store with a log and nothing pending keeps the `user_version` it
|
|
41
|
+
* holds, even when its log would give another gate: only a transaction
|
|
42
|
+
* that records a migration moves the gate.
|
|
43
|
+
*
|
|
44
|
+
* ## A development build never migrates the live store
|
|
45
|
+
*
|
|
46
|
+
* Between the first plan and the lock, an open with something to write
|
|
47
|
+
* asks `refuseUnownedDevelopmentWrite` (`development-build.ts`), which
|
|
48
|
+
* throws a `DevelopmentBuildRefusedError` when this rafa is a
|
|
49
|
+
* development build and the store lies outside the temporary directory
|
|
50
|
+
* and `RAFA_EFFORT_DIR`. The refusal comes before the lock and before
|
|
51
|
+
* any write, adoption included, so the store keeps its bytes. With
|
|
52
|
+
* nothing to write the open returns before that question is asked, so
|
|
53
|
+
* a development build uses a current store as any rafa does. That
|
|
54
|
+
* module's note says which stores it owns and what the text names.
|
|
55
|
+
*
|
|
56
|
+
* An open with {@link BringForwardOptions.builtAside} set skips that
|
|
57
|
+
* question: its file is one the caller built beside a store, which
|
|
58
|
+
* reaches the store only through the build-aside swap
|
|
59
|
+
* (`rebuild-aside.ts`), so the caller asks the question of the swap.
|
|
60
|
+
* `fix-schema.ts` builds its rebuild this way, since the parallel file
|
|
61
|
+
* sits in the project's store directory where the question would
|
|
62
|
+
* otherwise refuse even a dry run.
|
|
63
|
+
*
|
|
64
|
+
* ## What this module does not decide
|
|
65
|
+
*
|
|
66
|
+
* `planSchema` owns every refusal and its text. Which rafa counts as the
|
|
67
|
+
* one applying a migration is the caller's to say through
|
|
68
|
+
* {@link BringForwardOptions.appliedBy}; with none given it is this
|
|
69
|
+
* build's package version.
|
|
70
|
+
*/
|
|
71
|
+
import type { DevelopmentProbe } from './development-build.js';
|
|
72
|
+
import type { SqliteMigration } from './migrations.js';
|
|
73
|
+
import type { RefusalReason, SchemaCaller, SchemaRefusal, SchemaUse, StoreAccess, StoreSchema } from './schema-plan.js';
|
|
74
|
+
import type { Database } from 'bun:sqlite';
|
|
75
|
+
/** The migration log's table. */
|
|
76
|
+
export declare const MIGRATION_LOG_TABLE = "schema_migrations";
|
|
77
|
+
/** A store refused by `planSchema`, carrying the plan's answer. */
|
|
78
|
+
export declare class SchemaRefusedError extends Error {
|
|
79
|
+
/** Which of the seven refusals this is. */
|
|
80
|
+
readonly reason: RefusalReason;
|
|
81
|
+
/** The one command to run next, which the message also ends with. */
|
|
82
|
+
readonly nextStep: string;
|
|
83
|
+
constructor(refusal: SchemaRefusal);
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* What an open may vary; each field has the running build's default.
|
|
87
|
+
* The {@link DevelopmentProbe} fields say which build runs and which
|
|
88
|
+
* stores it owns (`development-build.ts`).
|
|
89
|
+
*/
|
|
90
|
+
export interface BringForwardOptions extends DevelopmentProbe {
|
|
91
|
+
/** The catalogue to bring the store to; a test passes a synthetic tail here. */
|
|
92
|
+
readonly migrations?: readonly SqliteMigration[];
|
|
93
|
+
/** The `applied_by` of every row this open logs; this build's version by default. */
|
|
94
|
+
readonly appliedBy?: string;
|
|
95
|
+
/** The clock `applied_at` is read from. */
|
|
96
|
+
readonly now?: () => Date;
|
|
97
|
+
/**
|
|
98
|
+
* True when `db` is a file the caller built beside a store and swaps
|
|
99
|
+
* in only through the build-aside steps; the development-build
|
|
100
|
+
* question is then the caller's, and this open does not ask it.
|
|
101
|
+
*/
|
|
102
|
+
readonly builtAside?: boolean;
|
|
103
|
+
}
|
|
104
|
+
/** What an open wrote. Both lists are empty when it wrote nothing. */
|
|
105
|
+
export interface BroughtForward {
|
|
106
|
+
/** Legacy ids logged without running, in catalogue order. */
|
|
107
|
+
readonly adopted: readonly string[];
|
|
108
|
+
/** Ids whose SQL ran and was logged, in the order it ran. */
|
|
109
|
+
readonly applied: readonly string[];
|
|
110
|
+
/** The store's `user_version` once the open is done. */
|
|
111
|
+
readonly userVersion: number;
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Bring the store open on `db` to this build's migrations for an open
|
|
115
|
+
* with `access` from `caller`, or throw {@link SchemaRefusedError}.
|
|
116
|
+
* `path` is what a refusal names the store as. The module note says
|
|
117
|
+
* what is written, and when.
|
|
118
|
+
*/
|
|
119
|
+
export declare function bringForward(db: Database, path: string, access: StoreAccess, caller: SchemaCaller, options?: BringForwardOptions): BroughtForward;
|
|
120
|
+
/**
|
|
121
|
+
* The store's `user_version` and its migration log, or a null log when
|
|
122
|
+
* it has no `schema_migrations` table. Reads only.
|
|
123
|
+
*/
|
|
124
|
+
export declare function readStoreSchema(db: Database, path: string): StoreSchema;
|
|
125
|
+
/**
|
|
126
|
+
* What a plan's write would record: the log first when it adopts, then
|
|
127
|
+
* each pending id. Empty when the plan writes nothing. `rafa effort
|
|
128
|
+
* schema` names the same list when it asks the development-build
|
|
129
|
+
* question an open would ask (`schema-report.ts`).
|
|
130
|
+
*/
|
|
131
|
+
export declare function writeNames(plan: SchemaUse): readonly string[];
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The check rows of a pull request and the verdict over them, which the
|
|
3
|
+
* store's plan CI writer (`./plan-ci.ts`) reads and `src/pr/checks.ts`
|
|
4
|
+
* re-exports for the poll and the provider that parse and wait on them.
|
|
5
|
+
*
|
|
6
|
+
* They sit in core so the store reads a verdict without importing the
|
|
7
|
+
* `pr` module above it.
|
|
8
|
+
*/
|
|
9
|
+
/** Whether a single check has passed, failed, or is still in flight. */
|
|
10
|
+
export type CheckOutcome = 'pass' | 'fail' | 'pending';
|
|
11
|
+
/** One row of `gh pr checks --json name,state,link`. */
|
|
12
|
+
export interface CheckRow {
|
|
13
|
+
name: string;
|
|
14
|
+
/** GitHub's raw state, kept verbatim so an unknown one stays reportable. */
|
|
15
|
+
state: string;
|
|
16
|
+
link: string;
|
|
17
|
+
outcome: CheckOutcome;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* The verdict over every row: `none` when the PR has no checks at all,
|
|
21
|
+
* which is the shape a conflicting PR produces, and the shape of a head
|
|
22
|
+
* pushed seconds ago whose first check has not registered yet.
|
|
23
|
+
*/
|
|
24
|
+
export type ChecksVerdict = 'green' | 'red' | 'pending' | 'none';
|
|
25
|
+
/**
|
|
26
|
+
* Reduces rows to one verdict. Pending outranks failure so a run that is
|
|
27
|
+
* still going is never reported as red on a partial reading.
|
|
28
|
+
*/
|
|
29
|
+
export declare function verdictOf(rows: readonly CheckRow[]): ChecksVerdict;
|
|
30
|
+
/** Rows the caller should act on: the failing ones, for a repair prompt. */
|
|
31
|
+
export declare function failingRows(rows: readonly CheckRow[]): CheckRow[];
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The commit row of the effort store and the gap arithmetic its rows
|
|
3
|
+
* carry.
|
|
4
|
+
*
|
|
5
|
+
* Moved down from `src/effort/commits.ts`, which parses `git log` into
|
|
6
|
+
* these rows and re-exports both names under the same names: the
|
|
7
|
+
* store's row types (`types.ts`), the merge's gap recompute
|
|
8
|
+
* (`merge-commit-gaps.ts`) and its scenario fixtures
|
|
9
|
+
* (`testdata/merge-scenarios.ts`) need the row and the arithmetic but
|
|
10
|
+
* not the parser, so they import them here and the store imports
|
|
11
|
+
* nothing above core for them. The parser's module note in
|
|
12
|
+
* `commits.ts` still describes how each field is read from the log.
|
|
13
|
+
*/
|
|
14
|
+
/** One row per commit. */
|
|
15
|
+
export interface CommitStats {
|
|
16
|
+
/** Full 40-character sha, and the store's key projection. */
|
|
17
|
+
sha: string;
|
|
18
|
+
/** Author date, ISO 8601 with offset, as `%aI` emits it. */
|
|
19
|
+
timestamp: string;
|
|
20
|
+
/** Subject line only. No commit message body reaches the row. */
|
|
21
|
+
subject: string;
|
|
22
|
+
/** Author name, as `%an` emits it. */
|
|
23
|
+
author: string;
|
|
24
|
+
/** Ref the walk reached this commit from, or null for `HEAD`. */
|
|
25
|
+
branch: string | null;
|
|
26
|
+
/** Numstat lines attributed to the commit, binary files included. */
|
|
27
|
+
filesChanged: number;
|
|
28
|
+
/** Summed added lines; a binary file contributes zero. */
|
|
29
|
+
insertions: number;
|
|
30
|
+
/** Summed removed lines; a binary file contributes zero. */
|
|
31
|
+
deletions: number;
|
|
32
|
+
/** Parents. Two or more is a merge, which prints no diff. */
|
|
33
|
+
parentCount: number;
|
|
34
|
+
/** Minutes since the preceding commit in time order, or null. */
|
|
35
|
+
minutesSincePrevious: number | null;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Minutes between two ISO timestamps, or null when either fails to
|
|
39
|
+
* parse. Rounded to {@link ELAPSED_DECIMALS}; never negative, because
|
|
40
|
+
* the caller orders the pair before asking.
|
|
41
|
+
*/
|
|
42
|
+
export declare function minutesBetween(earlier: string, later: string): number | null;
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/** The store files a directory can hold, the SQLite file first. */
|
|
2
|
+
export declare const EFFORT_COPY_FILE_NAMES: readonly string[];
|
|
3
|
+
/** A copy that was never started; nothing was made. */
|
|
4
|
+
export declare class EffortCopyRefusal extends Error {
|
|
5
|
+
readonly name = "EffortCopyRefusal";
|
|
6
|
+
}
|
|
7
|
+
/** A read or a write that failed once the copy started; what it made is removed. */
|
|
8
|
+
export declare class EffortCopyFailure extends Error {
|
|
9
|
+
readonly name = "EffortCopyFailure";
|
|
10
|
+
}
|
|
11
|
+
/** What one copy is handed. */
|
|
12
|
+
export interface EffortCopyRequest {
|
|
13
|
+
/** The store directory copied from. */
|
|
14
|
+
readonly source: string;
|
|
15
|
+
/** The directory copied into: absent, or an empty directory. */
|
|
16
|
+
readonly target: string;
|
|
17
|
+
}
|
|
18
|
+
/** What one copy did. */
|
|
19
|
+
export interface EffortCopyResult {
|
|
20
|
+
/** The store directory copied from, resolved. */
|
|
21
|
+
readonly source: string;
|
|
22
|
+
/** The directory copied into, resolved. */
|
|
23
|
+
readonly directory: string;
|
|
24
|
+
/** The store files copied, by name, in {@link EFFORT_COPY_FILE_NAMES} order. */
|
|
25
|
+
readonly files: readonly string[];
|
|
26
|
+
}
|
|
27
|
+
/** Writes `source`'s SQLite store to `target` as one snapshot, reading only. */
|
|
28
|
+
export declare function vacuumInto(source: string, target: string): void;
|
|
29
|
+
/**
|
|
30
|
+
* Copies the store in `request.source` into `request.target`, answering
|
|
31
|
+
* what it copied. Throws {@link EffortCopyRefusal} with nothing made, and
|
|
32
|
+
* {@link EffortCopyFailure} with what it made removed; see the module
|
|
33
|
+
* note.
|
|
34
|
+
*/
|
|
35
|
+
export declare function copyEffortStore(request: EffortCopyRequest): EffortCopyResult;
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A development build never migrates the live store: the refusal
|
|
3
|
+
* `bringForward` (`bring-forward.ts`) raises before it writes a store
|
|
4
|
+
* this build does not own.
|
|
5
|
+
*
|
|
6
|
+
* ## When it refuses
|
|
7
|
+
*
|
|
8
|
+
* `bringForward` asks {@link refuseUnownedDevelopmentWrite} once its
|
|
9
|
+
* first plan leaves something to write: a store to adopt, or a pending
|
|
10
|
+
* migration. It refuses when both hold:
|
|
11
|
+
*
|
|
12
|
+
* - the running rafa is a development build, as `readRuntimeIdentity`
|
|
13
|
+
* (`packages/rafa/src/core/runtime/identity.ts`) reads it: `bun src/rafa.ts`, a
|
|
14
|
+
* checkout's `dist/cli.js` or a `bun test` process;
|
|
15
|
+
* - the store is not one it owns ({@link isOwnedStore}).
|
|
16
|
+
*
|
|
17
|
+
* A plan with nothing to write never gets here, so a development build
|
|
18
|
+
* reads and writes the live store as it always did while the store is
|
|
19
|
+
* current. An installed runtime is never refused here. Adoption counts
|
|
20
|
+
* as a write, so a development build never adopts the live store
|
|
21
|
+
* either, and the refusal names `schema_migrations` for it, ahead of
|
|
22
|
+
* the pending ids.
|
|
23
|
+
*
|
|
24
|
+
* ## The stores a development build owns
|
|
25
|
+
*
|
|
26
|
+
* A store under the temporary directory (`tmpdir()`, read at each call,
|
|
27
|
+
* or its real path), which is where every test's store is, and a store
|
|
28
|
+
* under the directory `RAFA_EFFORT_DIR` names, which is where a copy
|
|
29
|
+
* made by `rafa effort copy` is. A store that sits in a project's own
|
|
30
|
+
* `<root>/.rafa/effort/` directory is owned under the temporary
|
|
31
|
+
* directory only, never through the variable: a variable naming a
|
|
32
|
+
* directory above a project would otherwise let branch code migrate
|
|
33
|
+
* that project's live store. `location.ts` already refuses a variable
|
|
34
|
+
* naming the project's own store where it resolves the directory, and
|
|
35
|
+
* a relative value, which counts for nothing here.
|
|
36
|
+
*
|
|
37
|
+
* ## The text
|
|
38
|
+
*
|
|
39
|
+
* The spec's, verbatim, naming the ids and the checkout:
|
|
40
|
+
*
|
|
41
|
+
* effort store: <path> needs migration <ids> and this rafa is a
|
|
42
|
+
* development build (<checkout>); a development build migrates only
|
|
43
|
+
* a store under the temp directory or RAFA_EFFORT_DIR. Copy it with
|
|
44
|
+
* 'rafa effort copy' and run this command with
|
|
45
|
+
* RAFA_EFFORT_DIR=<the copy>.
|
|
46
|
+
*
|
|
47
|
+
* When the store is a project's own (`<root>/.rafa/effort/`), each loop
|
|
48
|
+
* record under `<root>/.rafa/runs/` that reads `running` or `paused`
|
|
49
|
+
* with its pid alive (`readSessions`, `packages/rafa/src/core/loop/sessions.ts`) adds
|
|
50
|
+
* ` Loop <sessionId> (pid <pid>, plan <stub>) is running on this
|
|
51
|
+
* store.`, oldest first; a record with no stub names its plan's path.
|
|
52
|
+
* When the records cannot be read, the text says so and names the
|
|
53
|
+
* error, rather than dropping the sentence in silence. The refusal is
|
|
54
|
+
* thrown before any write, so the store's bytes are left as they were.
|
|
55
|
+
*/
|
|
56
|
+
import type { StoreEnvironment } from './location.js';
|
|
57
|
+
import type { PidProbe } from '../../core/loop/index.js';
|
|
58
|
+
import type { RuntimeIdentity } from '../../core/runtime/index.js';
|
|
59
|
+
/** The command a refused development build is sent to. */
|
|
60
|
+
export declare const DEVELOPMENT_NEXT_STEP = "rafa effort copy";
|
|
61
|
+
/** What the refusal names in place of an id when the write would adopt the store. */
|
|
62
|
+
export declare const ADOPTION_NAME = "schema_migrations";
|
|
63
|
+
/** What the refusal reads about the process it runs in; each field has a default. */
|
|
64
|
+
export interface DevelopmentProbe {
|
|
65
|
+
/** Which build is running; `readRuntimeIdentity()` by default. */
|
|
66
|
+
readonly identity?: RuntimeIdentity;
|
|
67
|
+
/** The environment `RAFA_EFFORT_DIR` is read from; `process.env` by default. */
|
|
68
|
+
readonly env?: StoreEnvironment;
|
|
69
|
+
/** The temporary directory; `tmpdir()` by default. */
|
|
70
|
+
readonly tempDir?: string;
|
|
71
|
+
/** Whether a loop record's pid is alive; `isPidAlive` by default. */
|
|
72
|
+
readonly isAlive?: PidProbe;
|
|
73
|
+
}
|
|
74
|
+
/** What follows the version in the `applied_by` of a row a development build logged, ahead of its checkout. */
|
|
75
|
+
export declare const DEVELOPMENT_MARK = "+dev:";
|
|
76
|
+
/**
|
|
77
|
+
* The running rafa as a migration log's `applied_by` names it: its
|
|
78
|
+
* version for an installed runtime, and `<version>+dev:<checkout>` for a
|
|
79
|
+
* development build, so a row a checkout logged says which one.
|
|
80
|
+
*/
|
|
81
|
+
export declare function appliedByName(identity: RuntimeIdentity): string;
|
|
82
|
+
/** A development build refused a write to a store it does not own. */
|
|
83
|
+
export declare class DevelopmentBuildRefusedError extends Error {
|
|
84
|
+
/** The store refused. */
|
|
85
|
+
readonly path: string;
|
|
86
|
+
/** The one command to run next. */
|
|
87
|
+
readonly nextStep: string;
|
|
88
|
+
constructor(path: string, message: string);
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* The project root a store file sits in, when its directory is that
|
|
92
|
+
* project's `<root>/.rafa/effort/`, and null for a store anywhere else.
|
|
93
|
+
*/
|
|
94
|
+
export declare function storeProjectRoot(path: string): string | null;
|
|
95
|
+
/** True when the store at `path` is one a development build may write; see the module note. */
|
|
96
|
+
export declare function isOwnedStore(path: string, env: StoreEnvironment, tempDir: string): boolean;
|
|
97
|
+
/** The refusal's text; see the module note. */
|
|
98
|
+
export declare function developmentRefusalText(path: string, needs: readonly string[], checkout: string, loops: string): string;
|
|
99
|
+
/**
|
|
100
|
+
* Throws {@link DevelopmentBuildRefusedError} when a development build
|
|
101
|
+
* would write the store at `path`, which it does not own, and does
|
|
102
|
+
* nothing otherwise. `needs` names what the write would record, in the
|
|
103
|
+
* order it would record it. Reads, and writes nothing.
|
|
104
|
+
*/
|
|
105
|
+
export declare function refuseUnownedDevelopmentWrite(path: string, needs: readonly string[], probe?: DevelopmentProbe): void;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The effort levels a task's declaration may name, held in core so the
|
|
3
|
+
* store's dispatch writer (`dispatches.ts`) can type a declared effort
|
|
4
|
+
* without importing the declaration parser above core.
|
|
5
|
+
*
|
|
6
|
+
* The declaration parser, `core/plan/declaration.ts`, imports
|
|
7
|
+
* `EffortLevel` from here, and is where a task line's `effort=` value is
|
|
8
|
+
* read and checked.
|
|
9
|
+
*/
|
|
10
|
+
/** Levels `--effort` accepts, taken from the CLI's own help text. */
|
|
11
|
+
export declare const EFFORT_LEVELS: readonly ["low", "medium", "high", "xhigh", "max"];
|
|
12
|
+
/** One of the five levels `--effort` accepts. */
|
|
13
|
+
export type EffortLevel = (typeof EFFORT_LEVELS)[number];
|