@turri-dev/cli 0.1.6-next.336dd6e → 0.1.7-next.9aec40e

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 (146) hide show
  1. package/.pi/themes/turri-dark.json +1 -1
  2. package/README.md +1 -1
  3. package/dist/ask.d.ts +83 -0
  4. package/dist/brand.d.ts +13 -0
  5. package/dist/btw.d.ts +67 -0
  6. package/dist/chat-models.d.ts +22 -0
  7. package/dist/chat-skills.d.ts +17 -0
  8. package/dist/cli-options.d.ts +25 -0
  9. package/dist/cli.d.ts +9 -0
  10. package/dist/cli.js +7 -1
  11. package/dist/config-command.d.ts +26 -0
  12. package/dist/config-edit.d.ts +69 -0
  13. package/dist/config.d.ts +321 -0
  14. package/dist/conform-cli.d.ts +1 -0
  15. package/dist/cultivate-cli.d.ts +1 -0
  16. package/dist/drift-cli.d.ts +1 -0
  17. package/dist/environment.d.ts +39 -0
  18. package/dist/environment.js +26 -0
  19. package/dist/extension.d.ts +147 -0
  20. package/dist/extension.js +36 -10
  21. package/dist/genome.d.ts +62 -0
  22. package/dist/graph.d.ts +52 -0
  23. package/dist/host.d.ts +20 -0
  24. package/dist/host.js +23 -0
  25. package/dist/identity.d.ts +2 -0
  26. package/dist/init-config.d.ts +106 -0
  27. package/dist/jellyfish.d.ts +25 -0
  28. package/dist/judge.d.ts +25 -0
  29. package/dist/lineage-cli.d.ts +1 -0
  30. package/dist/loop-cli.d.ts +34 -0
  31. package/dist/loop-tools.d.ts +80 -0
  32. package/dist/mature-tools.d.ts +53 -0
  33. package/dist/model-check.d.ts +42 -0
  34. package/dist/module-report.d.ts +9 -0
  35. package/dist/pi-launch.d.ts +1 -0
  36. package/dist/pi.d.ts +246 -0
  37. package/dist/picture-row.d.ts +10 -0
  38. package/dist/plain/check.d.ts +23 -0
  39. package/dist/plain/concepts.d.ts +11 -0
  40. package/dist/plain/errors.d.ts +22 -0
  41. package/dist/plain/files.d.ts +12 -0
  42. package/dist/plain/highlight.d.ts +42 -0
  43. package/dist/plain/index.d.ts +15 -0
  44. package/dist/plain/liquid.d.ts +22 -0
  45. package/dist/plain/markdown.d.ts +74 -0
  46. package/dist/plain/parser.d.ts +87 -0
  47. package/dist/plain/spec.d.ts +90 -0
  48. package/dist/plain/stdlib.d.ts +14 -0
  49. package/dist/question-dialog.d.ts +51 -0
  50. package/dist/questioning.d.ts +55 -0
  51. package/dist/quiet.d.ts +34 -0
  52. package/dist/regenerate/activity.d.ts +207 -0
  53. package/dist/regenerate/agent-env.d.ts +44 -0
  54. package/dist/regenerate/agent-shell.d.ts +49 -0
  55. package/dist/regenerate/arbiter.d.ts +68 -0
  56. package/dist/regenerate/audit.d.ts +69 -0
  57. package/dist/regenerate/cases.d.ts +9 -0
  58. package/dist/regenerate/change-view.d.ts +18 -0
  59. package/dist/regenerate/choose-conformance.d.ts +32 -0
  60. package/dist/regenerate/chunk-plan.d.ts +164 -0
  61. package/dist/regenerate/codebase.d.ts +21 -0
  62. package/dist/regenerate/command-check.d.ts +40 -0
  63. package/dist/regenerate/compaction.d.ts +13 -0
  64. package/dist/regenerate/confine.d.ts +62 -0
  65. package/dist/regenerate/conform.d.ts +63 -0
  66. package/dist/regenerate/conformance-agents.d.ts +405 -0
  67. package/dist/regenerate/conformance.d.ts +189 -0
  68. package/dist/regenerate/conversation-writes.d.ts +10 -0
  69. package/dist/regenerate/credentials.d.ts +18 -0
  70. package/dist/regenerate/debug-log.d.ts +54 -0
  71. package/dist/regenerate/debugger.d.ts +31 -0
  72. package/dist/regenerate/delivery.d.ts +6 -0
  73. package/dist/regenerate/diagnose-job.d.ts +2 -0
  74. package/dist/regenerate/diagnose.d.ts +46 -0
  75. package/dist/regenerate/diff-view.d.ts +61 -0
  76. package/dist/regenerate/drift.d.ts +84 -0
  77. package/dist/regenerate/engine.d.ts +52 -0
  78. package/dist/regenerate/environment-error.d.ts +136 -0
  79. package/dist/regenerate/job-log.d.ts +28 -0
  80. package/dist/regenerate/job-panel.d.ts +122 -0
  81. package/dist/regenerate/jobs-tree.d.ts +71 -0
  82. package/dist/regenerate/jobs.d.ts +186 -0
  83. package/dist/regenerate/lanes.d.ts +16 -0
  84. package/dist/regenerate/lineage.d.ts +95 -0
  85. package/dist/regenerate/list-arguments.d.ts +21 -0
  86. package/dist/regenerate/loop.d.ts +392 -0
  87. package/dist/regenerate/masking.d.ts +19 -0
  88. package/dist/regenerate/notes.d.ts +159 -0
  89. package/dist/regenerate/os-sandbox.d.ts +89 -0
  90. package/dist/regenerate/panel-dock.d.ts +23 -0
  91. package/dist/regenerate/paths.d.ts +92 -0
  92. package/dist/regenerate/plain-palette.d.ts +34 -0
  93. package/dist/regenerate/prompt.d.ts +192 -0
  94. package/dist/regenerate/records.d.ts +88 -0
  95. package/dist/regenerate/regenerate.d.ts +108 -0
  96. package/dist/regenerate/regression.d.ts +58 -0
  97. package/dist/regenerate/release.d.ts +123 -0
  98. package/dist/regenerate/requires.d.ts +96 -0
  99. package/dist/regenerate/resources.d.ts +53 -0
  100. package/dist/regenerate/self-check.d.ts +29 -0
  101. package/dist/regenerate/services.d.ts +28 -0
  102. package/dist/regenerate/shell.d.ts +91 -0
  103. package/dist/regenerate/side-panel.d.ts +57 -0
  104. package/dist/regenerate/spec-map-view.d.ts +139 -0
  105. package/dist/regenerate/spec-map.d.ts +138 -0
  106. package/dist/regenerate/spec-steps.d.ts +137 -0
  107. package/dist/regenerate/state.d.ts +20 -0
  108. package/dist/regenerate/steer.d.ts +34 -0
  109. package/dist/regenerate/steering.d.ts +56 -0
  110. package/dist/regenerate/stop-report.d.ts +43 -0
  111. package/dist/regenerate/submit-work.d.ts +42 -0
  112. package/dist/regenerate/test-kinds.d.ts +42 -0
  113. package/dist/regenerate/test-scripts.d.ts +221 -0
  114. package/dist/regenerate/testing.d.ts +141 -0
  115. package/dist/regenerate/transcript-view.d.ts +21 -0
  116. package/dist/regenerate/unit-gate.d.ts +27 -0
  117. package/dist/regenerate/unit-review.d.ts +152 -0
  118. package/dist/regenerate/web.d.ts +61 -0
  119. package/dist/regenerate/workspace.d.ts +12 -0
  120. package/dist/regenerate-cli.d.ts +1 -0
  121. package/dist/release-agent.d.ts +26 -0
  122. package/dist/release-cli.d.ts +1 -0
  123. package/dist/release-tools.d.ts +38 -0
  124. package/dist/resume-line.d.ts +2 -0
  125. package/dist/review/live.d.ts +72 -0
  126. package/dist/rules.d.ts +20 -0
  127. package/dist/run-report.d.ts +88 -0
  128. package/dist/screen-padding.d.ts +28 -0
  129. package/dist/self-invocation.d.ts +25 -0
  130. package/dist/setup.d.ts +43 -0
  131. package/dist/skill-progress.d.ts +46 -0
  132. package/dist/skill.d.ts +98 -0
  133. package/dist/skills.d.ts +30 -0
  134. package/dist/spec-diff-cli.d.ts +1 -0
  135. package/dist/spec-tools.d.ts +36 -0
  136. package/dist/stack.d.ts +58 -0
  137. package/dist/stacks.d.ts +12 -0
  138. package/dist/stdlib.d.ts +27 -0
  139. package/dist/terminal-images.d.ts +2 -0
  140. package/dist/tools.d.ts +101 -0
  141. package/dist/validate-cli.d.ts +1 -0
  142. package/docs/README.md +2 -0
  143. package/docs/hosting.md +51 -0
  144. package/docs/installation.md +1 -1
  145. package/docs/theming.md +2 -2
  146. package/package.json +8 -1
@@ -0,0 +1,138 @@
1
+ import { type MarshalledPlainSource } from "../plain/spec.ts";
2
+ import { type MapCodebase, type MapPlan, type MapPulse } from "./loop.ts";
3
+ /**
4
+ * The regeneration: the spec itself, with the build drawn onto it - see docs/using.md.
5
+ *
6
+ * Nothing new is stored. A page a module, read from what turri keeps already: the code record (what is built, and the
7
+ * old side of each change), the .plain files now (the lines, and what differs), the tests record (which functional
8
+ * specs have conformance tests) - so the map is right from the files alone, the moment turri opens a project. The work
9
+ * loop's plan is laid over it (`markSpecMap`): the pulse regenerating each item, the pulse planned to, or why there is
10
+ * none.
11
+ *
12
+ * An item is what turri plans and diffs by: a definition, a req, a functional spec with its sub-bullets and acceptance
13
+ * tests. Items are matched to pulses by their lines in the trees each pulse goes between, as the loop has them.
14
+ */
15
+ /** Where an item stands against the code record. A test req is the conformance track's: it is never built. */
16
+ export type ItemState = "built" | "new" | "changed" | "removed" | "test";
17
+ export interface MapItem {
18
+ /** Stable while the item reads the same: what the cursor stays on. */
19
+ key: string;
20
+ section: string;
21
+ /** The imported file it is written in, as shown; undefined, the module's own file. */
22
+ file?: string;
23
+ state: ItemState;
24
+ /** Its text now - for one taken out, the code record's. */
25
+ text: string;
26
+ /** The code record's text, for a changed item. */
27
+ was?: string;
28
+ /** Its acceptance tests, as the spec has them now. */
29
+ acceptance: string[];
30
+ /** Its line in the code's tree now, and in the code record's: what a pulse's trees are matched by. */
31
+ line?: string;
32
+ wasLine?: string;
33
+ /** A functional spec's conformance tests: written for it as it reads now, for an earlier text, or for one taken out. */
34
+ tests?: "now" | "older" | "removed";
35
+ }
36
+ export interface MapPage {
37
+ module: string;
38
+ plainFile: string;
39
+ /** The codebase its code lives in: whose record it is read from, and whose pulses regenerate it. */
40
+ buildDir: string;
41
+ /** The files it imports, as shown, in the order it reads them. */
42
+ imports: string[];
43
+ /** The module it requires - whose code it is built on - when it requires one. */
44
+ requires?: string;
45
+ /** Its conformance tests are on, as its config has it: `conformance-tests:` is not false. */
46
+ conformance?: boolean;
47
+ items: MapItem[];
48
+ /** Its spec does not parse, or could not be read. */
49
+ error?: string;
50
+ }
51
+ /** An item's mark in the gutter. */
52
+ export type Mark = "built" | "regenerating" | "planned" | "waiting" | "planning" | "stuck" | "removing" | "none";
53
+ export interface MarkedItem extends MapItem {
54
+ mark: Mark;
55
+ /** The pulse regenerating it, or planned to: running, or its provisional number. */
56
+ pulse?: MapPulse;
57
+ /** In the pulse that did not land: that pulse's number - rolled back, and waiting. */
58
+ rolledBack?: number;
59
+ /** A conformance pulse is writing its tests now. */
60
+ testing?: boolean;
61
+ /** The conformance pulse planned to write its tests, not running yet: what its provisional number is read from. */
62
+ testsPulse?: MapPulse;
63
+ }
64
+ export interface MarkedPage extends MapPage {
65
+ items: MarkedItem[];
66
+ /** The loop looks after its codebase: something asked for it. */
67
+ tracked: boolean;
68
+ /** Its codebase, as the loop has it. */
69
+ codebase?: MapCodebase;
70
+ /** The top line's reason: what is happening, or why nothing is. */
71
+ status: string;
72
+ /** It needs the person: halted, or the planner found no plan, or its spec does not parse. */
73
+ stuck: boolean;
74
+ }
75
+ /**
76
+ * A module's items, from what its code is built from and what its spec says now: every item of the spec in its place,
77
+ * each built, new or changed, and between them the items taken out that the code still has.
78
+ *
79
+ * `spec` and `record` are the codebase's trees - the module's items untagged when `own`, tagged with it otherwise. `full`
80
+ * is the spec with its acceptance tests and test reqs.
81
+ */
82
+ export declare function pageItems(input: {
83
+ module: string;
84
+ own: boolean;
85
+ spec: MarshalledPlainSource;
86
+ record: MarshalledPlainSource | null;
87
+ tested?: MarshalledPlainSource | null;
88
+ }): MapItem[];
89
+ /** A spec file as the map names it: a template of turri's standard library by its import path, others from the project. */
90
+ export declare function importLabel(path: string, projectDir: string, stdlibRoot?: string): string;
91
+ /**
92
+ * The items laid out as the files have them: the module's own file first - its sections in its order, its definitions
93
+ * in its order - then each file it imports, the same way. A ghost keeps its place after the item before it.
94
+ */
95
+ export declare function layOut(items: MapItem[], files: Array<{
96
+ label?: string;
97
+ text: string;
98
+ }>): MapItem[];
99
+ /**
100
+ * The pages of the files given, from the files alone: one a module of each file's requires chain, bottom first, each
101
+ * once. A module below the furthest-built one is read from that one's codebase, whose record has every module's items;
102
+ * a module above it from its own, empty until its turn comes.
103
+ */
104
+ export declare function readSpecMap(files: string[]): MapPage[];
105
+ /** The pages, and the files they were read from: while none of them changes, the pages read the same. */
106
+ export declare function readSpecMapWithDeps(files: string[]): {
107
+ pages: MapPage[];
108
+ deps: string[];
109
+ };
110
+ /** The count a page's top line starts with: how many of its functional specs are built as the spec has them. */
111
+ export declare function countOf(page: MapPage): {
112
+ built: number;
113
+ total: number;
114
+ };
115
+ /**
116
+ * The plan laid over the pages: each item that differs from the code marked with the pulse regenerating it, the pulse
117
+ * planned to, or - with none - planning, stuck or waiting; and each page's reason on its top line.
118
+ */
119
+ export declare function markSpecMap(pages: MapPage[], plan: MapPlan): MarkedPage[];
120
+ /**
121
+ * The .plain files the map shows when nothing has been asked for: the project's module from config.turri.yaml, else the
122
+ * .plain files in the folder that no other one there imports or requires.
123
+ */
124
+ export declare function defaultMapFiles(cwd: string): string[];
125
+ /**
126
+ * The map as the side panel reads it on every frame: read again from the files and laid over the plan at most every
127
+ * `every` ms - git runs for the records and the diffs - and the same pages in between.
128
+ */
129
+ export declare function createSpecMapSource(options: {
130
+ files: () => string[];
131
+ plan: () => MapPlan;
132
+ every?: number;
133
+ now?: () => number;
134
+ }): {
135
+ read(): MarkedPage[];
136
+ /** Read the files again on the next frame, whatever they look like. */
137
+ refresh(): void;
138
+ };
@@ -0,0 +1,137 @@
1
+ import { type MarshalledPlainSource } from "../plain/spec.ts";
2
+ /**
3
+ * The steps from one spec to another: a sequence of spec diffs that, rendered one after the
4
+ * other, take code built from the first spec to code built from the second.
5
+ *
6
+ * Both specs are marshalled trees, written out as text with one JSON value per line - a
7
+ * section's name, then each of its items on a line of its own - and compared with git. So an
8
+ * item is the unit of change: a functional spec with its acceptance tests and linked resources,
9
+ * a definition, a req. Git lines them up, so a spec inserted in the middle is one addition and
10
+ * the specs after it are untouched, though their numbers moved.
11
+ *
12
+ * The planner (`chunk-plan.ts`) cuts the changes into steps - which go together, which go first. It
13
+ * picks changes by id; it never writes a diff. `makeStep` applies what it picked, and `inconsistencies`
14
+ * checks that each step leaves a spec that holds together - no concept used before a step defines it.
15
+ */
16
+ /** The sections of a tree, in the order they are written. Written even when empty, so they never change. */
17
+ export declare const TREE_SECTIONS: string[];
18
+ /**
19
+ * A tree as text: each section's name on a line - `["definitions"]` - then one JSON value per
20
+ * item, keys sorted. No commas and no brackets around a section, so adding an item at the end
21
+ * changes nothing before it.
22
+ */
23
+ export declare function serializeTree(tree: MarshalledPlainSource): string;
24
+ /**
25
+ * Whether two trees are the same spec, however it is laid out across files: the definitions, the
26
+ * implementation and test reqs the same - in any order, from the module's own file or an imported
27
+ * one - and the functional specs the same, in order, those it inherits then its own, whichever
28
+ * module each is written in. Specs moved between a module and the ones it requires are the same
29
+ * spec: the code holds them all. But a module required now that was not before is not - its code
30
+ * is not in this codebase - so `after` may only drop required modules, never gain one.
31
+ *
32
+ * What it takes to tell a restructuring of the specs - definitions moved to a common module,
33
+ * sections reordered - from a change: one of these has nothing to render.
34
+ */
35
+ export declare function sameSpec(before: MarshalledPlainSource, after: MarshalledPlainSource): boolean;
36
+ /** A serialized tree read back. A known section with no items is left out, as the parser leaves it. */
37
+ export declare function parseTree(text: string): MarshalledPlainSource;
38
+ /** git's diff of two serialized trees, with `context` lines around each change. */
39
+ export declare function diffTrees(before: string, after: string, context?: number): string;
40
+ /**
41
+ * One change between two serialized trees: an item added, removed, or changed in place. Where it
42
+ * goes is given in the lines of the tree it applies to, so any selection of changes applies to
43
+ * that tree on its own, in any order.
44
+ */
45
+ export interface SpecChange {
46
+ id: string;
47
+ /** The section the item is in. */
48
+ section: string;
49
+ kind: "add" | "remove" | "change";
50
+ /** The item's line as it is, for a removal or a change. */
51
+ before?: string;
52
+ /** The item's line as it becomes, for an addition or a change. */
53
+ after?: string;
54
+ /** Its number in its section, from 1: where it is now, or - for an addition - where it lands in the target. */
55
+ position: number;
56
+ /** The line it removes, in the tree it applies to. */
57
+ removes?: number;
58
+ /** The line it goes in front of, and its place among others that go there. */
59
+ inserts?: {
60
+ at: number;
61
+ order: number;
62
+ };
63
+ }
64
+ /** The changes that take one serialized tree to another, in the order git lists them. */
65
+ export declare function changesBetween(before: string, after: string): SpecChange[];
66
+ /** How alike two items are: the share of their words they have in common. */
67
+ export declare function similarity(a: string, b: string): number;
68
+ /** A selection of changes, applied to the serialized tree they were found in. */
69
+ export declare function applyChanges(before: string, changes: SpecChange[]): string;
70
+ /** A serialized tree as a person reads it, section by section. */
71
+ export declare function treeText(serialized: string): string;
72
+ /** A change as the planning agent is shown it. */
73
+ export declare function describeChange(change: SpecChange): string;
74
+ /** One step of the sequence: a spec diff, and the spec before and after it. */
75
+ export interface SpecStep {
76
+ title: string;
77
+ reason: string;
78
+ /** The changes it makes. */
79
+ changes: SpecChange[];
80
+ /** The spec before and after it, serialized. */
81
+ before: string;
82
+ after: string;
83
+ /** The spec after it, as a tree: what a render of this step builds from. */
84
+ tree: MarshalledPlainSource;
85
+ /** git's diff of `before` to `after`, as serialized. */
86
+ diff: string;
87
+ /**
88
+ * The same change as a person - or a coding agent - reads a spec change: git's diff of the spec
89
+ * before and after, written out as ***plain text, section by section.
90
+ */
91
+ textDiff: string;
92
+ /** The sections it changes. */
93
+ sections: string[];
94
+ /** Made by the harness for what the agent never placed, after its rounds ran out. */
95
+ fallback?: boolean;
96
+ }
97
+ /**
98
+ * What makes a spec not hold together that neither end already has: a concept used before any
99
+ * step defines it, or defined twice - the parser's own concept checks.
100
+ */
101
+ export declare function inconsistencies(tree: MarshalledPlainSource, endpoints: Set<string>): string[];
102
+ /** How the module's `.plain` file is laid out, for writing a tree out as that file would have it. */
103
+ export interface SpecLayout {
104
+ /** Everything before the first section: the frontmatter, imports and requires. */
105
+ preamble: string;
106
+ /** The sections, in the order the file has them. */
107
+ sections: string[];
108
+ /** Each concept's place in the file's definitions - the parser orders them by what uses what. */
109
+ concepts: Map<string, number>;
110
+ /** The sections whose items the file writes with no blank line between them. */
111
+ tight: Set<string>;
112
+ }
113
+ export declare function layoutOf(text: string): SpecLayout;
114
+ /**
115
+ * A serialized tree as the module's `.plain` file would have it: only its own sections, and only
116
+ * the ones with something in them. The functional specs it inherits are the required modules'
117
+ * - `required functional specs` is the parser's key for them, not a section anyone writes. With
118
+ * the file's layout, it is written as the file is: its preamble, its sections in its order, a
119
+ * blank line between items, and the definitions in the file's order rather than the parser's -
120
+ * so a spec diff reads as an edit to the file, at the file's line numbers.
121
+ */
122
+ export declare function plainText(serialized: string, layout?: SpecLayout): string;
123
+ /** git's diff of two serialized trees, as ***plain text - see plainText. */
124
+ export declare function diffSpecText(before: string, after: string, file?: string, layout?: SpecLayout): string;
125
+ /** The linked resources of a changed item whose content is different now - each hashed on its own: by their path, with both hashes. */
126
+ export declare function resourcesChanged(before: string | undefined, after: string | undefined): Array<{
127
+ target: string;
128
+ was?: string;
129
+ now?: string;
130
+ }>;
131
+ /**
132
+ * The linked resources a step's changes find changed, as a diff of their own beside the spec's: a file the spec links
133
+ * holds something else now, though the spec's text may read as it did. The trees keep each one's hash, not what it
134
+ * held before - so the hunk says that it changed, and what it holds now is the file itself.
135
+ */
136
+ export declare function resourceDiff(changes: SpecChange[], file?: string): string;
137
+ export declare function makeStep(title: string, reason: string, changes: SpecChange[], before: string, after: string, file: string, layout?: SpecLayout): SpecStep;
@@ -0,0 +1,20 @@
1
+ import { DEFINITIONS, NON_FUNCTIONAL_REQUIREMENTS, TEST_REQUIREMENTS, type MarshalledPlainSource } from "../plain/spec.ts";
2
+ /**
3
+ * A module's spec as the prompts read it: the sections every functional spec shares, and a
4
+ * functional spec a module inherits. What the code and the tests are built from is in `records.ts`.
5
+ */
6
+ /** The sections a module shares across all its functionalities, as text. */
7
+ export interface SharedSections {
8
+ [DEFINITIONS]: string[];
9
+ [NON_FUNCTIONAL_REQUIREMENTS]: string[];
10
+ [TEST_REQUIREMENTS]: string[];
11
+ }
12
+ /** A functional spec of a module this one requires: documented, not built here. */
13
+ export interface RequiredSpec {
14
+ module: string;
15
+ frid: string;
16
+ spec: string;
17
+ acceptanceTests?: string[];
18
+ }
19
+ /** A module's shared sections as they stand, with or without a functional spec to read them through. */
20
+ export declare function sectionsOf(tree: MarshalledPlainSource): SharedSections;
@@ -0,0 +1,34 @@
1
+ /**
2
+ * How the person wants the queue planned - which functional specs go together, what goes first, how big a job is -
3
+ * given to the planner's agents with every plan, as a strong preference.
4
+ *
5
+ * It comes from three places. The conversation sets it (`steer`), for the whole project or one module, and it
6
+ * holds for the session. The project's AGENTS.md can say it once for good: a section whose heading names the queue
7
+ * ("## Queue guidance") is read with every plan, so an edit to it holds from the next. And whatever queues work can
8
+ * pass guidance for that work (a tool's `guidance`), which the queue keeps with it.
9
+ */
10
+ /** Everything the conversation's steering applies to: every module of the project. */
11
+ export declare const EVERY_MODULE = "*";
12
+ export interface SteeringStore {
13
+ /** The steering for a scope - a module's name, or EVERY_MODULE - in the order it was given. */
14
+ get(scope: string): string[];
15
+ set(scope: string, texts: string[]): void;
16
+ scopes(): string[];
17
+ }
18
+ export declare function createSteeringStore(): SteeringStore;
19
+ /** A module's name as the steering names it: its spec file's name, without `.plain`. */
20
+ export declare function moduleNameOf(plainFile: string): string;
21
+ /**
22
+ * What an AGENTS.md says of the queue: every section whose heading names it - "Queue", "Queue guidance", "How the
23
+ * render queue is planned" - up to the next heading of its level or above. Empty when there is none.
24
+ */
25
+ export declare function queueSectionOf(markdown: string): string;
26
+ /** The steering a plan of this spec's codebase follows - AGENTS.md's, then the conversation's for every module and for this one. */
27
+ export declare function steeringFor(plainFile: string, cwd: string, store: SteeringStore): Steering[];
28
+ /** How the person or the harness wants the queue planned: a strong preference, each with where it came from. */
29
+ export interface Steering {
30
+ source: string;
31
+ text: string;
32
+ }
33
+ /** The steering, for an agent's task: each with where it came from, and how binding it is. */
34
+ export declare function steeringBlock(steering: Steering[] | undefined): string[];
@@ -0,0 +1,56 @@
1
+ import { type MarshalledPlainSource } from "../plain/spec.ts";
2
+ import { type SpecChange } from "./spec-steps.ts";
3
+ /**
4
+ * JobSteering a running code job: the spec changed while it regenerates, inside what it is regenerating - a functional
5
+ * spec it builds reworded, a sub-bullet added under one, a definition or an implementation req it is given edited, a
6
+ * file one links edited - and the coding agent is told, rather than the job stopped or the change left to the next
7
+ * one. A new or removed item is not a steer: the work changes shape, and that is the next job's. At most MAX_STEERS a
8
+ * job; the one after is the next job's, or stops this one, as `allow-to-stop-jobs` says.
9
+ *
10
+ * Three trees. `target`: what the job lands as built from - its code record. `agent`: what its agent is to build -
11
+ * the target, and a definition or req edited that functional specs built before the job use too: the agent is told,
12
+ * but the record keeps what those were built from, so the loop patches them - this one's with them - once it lands.
13
+ * `told`: what the agent has been told. A steer is waiting while `told` is not `agent`; edits made before it is
14
+ * given are one steer, the newest of each item.
15
+ */
16
+ export declare const MAX_STEERS = 2;
17
+ export interface JobSteering {
18
+ target: MarshalledPlainSource;
19
+ agent: MarshalledPlainSource;
20
+ told: MarshalledPlainSource;
21
+ /** Steers so far: each counted as it is made - edits merged into one waiting are one. */
22
+ steers: number;
23
+ /** What each steer was, in a line, for the job's report. */
24
+ notes: string[];
25
+ /** Set by the running job while its coding agent can be reached: tells it now, in its turn, and says whether it could. */
26
+ deliver?: (text: string) => boolean;
27
+ /** The module whose codebase it regenerates: the change is told with each item's module (`describeSpecChange`). */
28
+ module?: string;
29
+ }
30
+ export declare function createSteering(tree: MarshalledPlainSource, module?: string): JobSteering;
31
+ /** What the agent is to be told and has not been: the steer waiting, or undefined when there is none. */
32
+ export declare function waitingSteer(steering: JobSteering): string | undefined;
33
+ /** The agent has it now. */
34
+ export declare function markTold(steering: JobSteering): void;
35
+ /** The message a steer is: the change since it was last told, as its first one was - and to make the code match. */
36
+ export declare function steerText(changes: SpecChange[], moduleName?: string): string;
37
+ /**
38
+ * The part of `changes` - from a tree the job regenerates towards, to the spec - that steers it: changes to items it
39
+ * already has, never one added or removed. A functional spec only when it is one of the job's own (`mine`, as the job
40
+ * regenerates it); a definition or an implementation req always. `shared`: those of them that functional specs built
41
+ * before the job (`built`) use too - the agent is told, but they stay out of the record.
42
+ */
43
+ export declare function steerableChanges(changes: SpecChange[], mine: Set<string>, built: string[]): {
44
+ steer: SpecChange[];
45
+ shared: SpecChange[];
46
+ };
47
+ /**
48
+ * Steer a job, when the spec moved on inside what it regenerates: the trees it moves to, or undefined when nothing in
49
+ * the change steers it. `toSpec(tree)` is the work from a tree to the spec, as the job's track sees it; `own` the job's
50
+ * changes, from its record `from` to what it regenerates towards now.
51
+ */
52
+ export declare function steer(steering: JobSteering, from: MarshalledPlainSource, own: SpecChange[], toSpec: (tree: MarshalledPlainSource) => SpecChange[]): {
53
+ target: MarshalledPlainSource;
54
+ agent: MarshalledPlainSource;
55
+ steered: SpecChange[];
56
+ } | undefined;
@@ -0,0 +1,43 @@
1
+ import type { SpecConflict } from "./activity.ts";
2
+ import type { RenderConformanceTestsResult } from "./conformance.ts";
3
+ import type { MissingToolchain, TestRun } from "./testing.ts";
4
+ /**
5
+ * What to tell the person when a build gives up.
6
+ *
7
+ * A build stops at one of three gates - its unit tests, its conformance tests, or the tests of
8
+ * what was built before it - after the harness has tried as many times as it will. "Stopped at
9
+ * regression" says where, not why, and not what to do; this says all three, in the words of
10
+ * someone who has not read the harness.
11
+ */
12
+ export type StopPoint = "unit tests" | "conformance" | "regression";
13
+ /** How many times each gate is tried before a build stops there. */
14
+ export declare const ATTEMPTS: Record<StopPoint, number>;
15
+ export interface StopFacts {
16
+ moduleName: string;
17
+ /** The functionality it stopped at; none for a spec change. */
18
+ frid?: string;
19
+ at: StopPoint;
20
+ /** The unit test runs, the last of which is the failing one. */
21
+ runs?: TestRun[];
22
+ conformance?: Pick<RenderConformanceTestsResult, "runs" | "rounds" | "specConflict" | "stuck" | "environment" | "escalation" | "review" | "unlabelled">;
23
+ /** Repairs made to earlier functionalities' code before it gave up. */
24
+ repairs?: number;
25
+ /** How many times the harness judged it before it stopped - the unit tests' attempts. */
26
+ attempts?: number;
27
+ /** The unit testing script could not run: what it needs is not installed where it runs. */
28
+ missingToolchain?: MissingToolchain;
29
+ /** The unit tests passed in the end, and the unit testing script's static checks - which count as the tests do - did not. */
30
+ staticChecks?: boolean;
31
+ }
32
+ /**
33
+ * Where it stopped, why, and what to do about it - for the person, in a few lines, and in terms
34
+ * of the spec. The spec is all the person works on: the code is generated from it, so every fix
35
+ * offered here is a change to a `.plain` file, never to code, tests or the machine.
36
+ */
37
+ export declare function describeStop(facts: StopFacts): string;
38
+ /**
39
+ * A spec that contradicts itself, for the person: exactly which two functional specs, as they
40
+ * read, and what cannot hold - then that the decision is theirs. Nothing about code or tests: the
41
+ * spec is all they work on, and the fix is theirs to choose.
42
+ */
43
+ export declare function describeSpecConflict(conflict: SpecConflict): string;
@@ -0,0 +1,42 @@
1
+ import { type ToolDefinition } from "@earendil-works/pi-coding-agent";
2
+ /**
3
+ * The work, handed over for review: what the agent that did it says it did.
4
+ *
5
+ * A reviewer kept through a job reads the work once, then only what changed since - and a diff says what changed,
6
+ * not why, nor which of the problems it raised a change answers, nor which ones the agent chose not to take up. So
7
+ * the agent that did the work ends each turn that goes to review with an account: what it did, and for each problem
8
+ * the last review raised, whether it fixed it or declined it, why, and where. The account is a claim: the reviewer
9
+ * gets it beside the diff the harness takes itself, never instead of it, and checks the one against the other.
10
+ */
11
+ export interface WorkAnswer {
12
+ /** The problem's number, as the review's list gave it. */
13
+ problem: number;
14
+ outcome: "fixed" | "declined";
15
+ why: string;
16
+ files?: string[];
17
+ }
18
+ export interface WorkAccount {
19
+ summary: string;
20
+ answers: WorkAnswer[];
21
+ }
22
+ /** What the agent is told, at the end of its task: how it hands its work over. */
23
+ export declare const SUBMIT_WORK_NOTE: string[];
24
+ /** What the agent is told with a review's problems: how it answers them. */
25
+ export declare const SUBMIT_AFTER_REVIEW: string[];
26
+ /** The tool, and what was handed over through it since the harness last took it. */
27
+ export interface WorkLedger {
28
+ tool: ToolDefinition;
29
+ /** What was handed over since the last take, left where it is. */
30
+ peek: () => WorkAccount[];
31
+ /** What was handed over since the last take - and from now, nothing. */
32
+ take: () => WorkAccount[];
33
+ }
34
+ export declare function createWorkLedger(): WorkLedger;
35
+ /** The problems, numbered from 1, that no account answered. */
36
+ export declare function unanswered(accounts: WorkAccount[], problems: number): number[];
37
+ /** The prompt that sends the agent back once for the problems its account left out. */
38
+ export declare function unansweredPrompt(numbers: number[]): string;
39
+ /** The accounts, for the reviewer: labelled as a claim, the problems they answer named. */
40
+ export declare function describeAccounts(accounts: WorkAccount[], problems?: Array<{
41
+ what: string;
42
+ }>): string;
@@ -0,0 +1,42 @@
1
+ /**
2
+ * The two kinds of test the conformance step writes, and how each is told apart in the code.
3
+ *
4
+ * Conformance tests are written from the functional spec itself: what the functionality does,
5
+ * its edge cases, its errors - as if no acceptance tests had been given. Acceptance tests are the
6
+ * ones the spec's author wrote, each implemented as a test of its own, doing what it says. The
7
+ * two are kept apart even when the acceptance tests would seem to cover the functionality: tests
8
+ * derived only from the acceptance tests check what the author thought to check, and nothing
9
+ * the spec says beyond it.
10
+ *
11
+ * Each kind is labelled where anyone reading the tests can see it - in its file names, and in a
12
+ * comment the harness looks for - so which test is which, and which acceptance test a test
13
+ * implements, never has to be guessed.
14
+ */
15
+ export declare function conformanceLabel(frid: string): string;
16
+ export declare function acceptanceLabel(frid: string, n: number): string;
17
+ /** An acceptance test as the spec gives it, without its bullet. */
18
+ export declare function acceptanceText(item: string): string;
19
+ /**
20
+ * What is missing from the labelling of a functionality's tests: the conformance label, when no
21
+ * test file carries it, and each acceptance test no test is labelled as implementing.
22
+ */
23
+ export declare function missingTestLabels(testsDir: string, frid: string, acceptanceTests: string[]): string[];
24
+ /** Sent back when the labels are missing: which, and how to label them. */
25
+ export declare function labelsPrompt(frid: string, missing: string[], empty?: boolean, hasAcceptance?: boolean): string;
26
+ /**
27
+ * Sent back when the labels of several functionalities are missing - a spec change that touches them: every one that is
28
+ * missing, in one request, so none is asked for in place of another.
29
+ */
30
+ export declare function labelsPromptFor(items: Array<{
31
+ frid: string;
32
+ missing: string[];
33
+ }>, empty?: boolean, hasAcceptance?: boolean): string;
34
+ /**
35
+ * Conformance and acceptance tests in the code folder, where they do not belong: they live in the
36
+ * module's tests folder, which the harness runs as the conformance suite. Found by their label, or
37
+ * by a test file under a name or folder that says conformance or acceptance - one written without
38
+ * a label is misplaced all the same.
39
+ */
40
+ export declare function misplacedConformanceTests(codeDir: string): string[];
41
+ /** Sent back when there are: to the agent writing the code, or to the one writing the tests. */
42
+ export declare function misplacedTestsPrompt(files: string[], codeDir: string, testsDir?: string): string;