@turri-dev/cli 0.1.6-next.336dd6e → 0.1.7-next.8f13f3a
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/.pi/themes/turri-dark.json +1 -1
- package/README.md +2 -4
- package/assets/jellyfish/dark-00.png +0 -0
- package/assets/jellyfish/dark-01.png +0 -0
- package/assets/jellyfish/dark-02.png +0 -0
- package/assets/jellyfish/dark-03.png +0 -0
- package/assets/jellyfish/dark-04.png +0 -0
- package/assets/jellyfish/dark-05.png +0 -0
- package/assets/jellyfish/dark-06.png +0 -0
- package/assets/jellyfish/dark-07.png +0 -0
- package/assets/jellyfish/dark-08.png +0 -0
- package/assets/jellyfish/dark-09.png +0 -0
- package/assets/jellyfish/dark-10.png +0 -0
- package/assets/jellyfish/dark-11.png +0 -0
- package/assets/jellyfish/dark-12.png +0 -0
- package/assets/jellyfish/dark-13.png +0 -0
- package/assets/jellyfish/dark-14.png +0 -0
- package/assets/jellyfish/dark-15.png +0 -0
- package/assets/jellyfish/dark-16.png +0 -0
- package/assets/jellyfish/dark-17.png +0 -0
- package/assets/jellyfish/dark-18.png +0 -0
- package/assets/jellyfish/dark-19.png +0 -0
- package/assets/jellyfish/dark-20.png +0 -0
- package/assets/jellyfish/dark-21.png +0 -0
- package/assets/jellyfish/dark-22.png +0 -0
- package/assets/jellyfish/dark-23.png +0 -0
- package/assets/jellyfish/dark-24.png +0 -0
- package/assets/jellyfish/dark-25.png +0 -0
- package/assets/jellyfish/dark-26.png +0 -0
- package/assets/jellyfish/dark-27.png +0 -0
- package/assets/jellyfish/dark-28.png +0 -0
- package/assets/jellyfish/dark-29.png +0 -0
- package/assets/jellyfish/dark-30.png +0 -0
- package/assets/jellyfish/dark-31.png +0 -0
- package/assets/jellyfish/dark-32.png +0 -0
- package/assets/jellyfish/dark-33.png +0 -0
- package/assets/jellyfish/dark-34.png +0 -0
- package/assets/jellyfish/dark-35.png +0 -0
- package/assets/jellyfish/dark-36.png +0 -0
- package/assets/jellyfish/dark-37.png +0 -0
- package/assets/jellyfish/dark-38.png +0 -0
- package/assets/jellyfish/dark-39.png +0 -0
- package/assets/jellyfish/dark-40.png +0 -0
- package/assets/jellyfish/light-00.png +0 -0
- package/assets/jellyfish/light-01.png +0 -0
- package/assets/jellyfish/light-02.png +0 -0
- package/assets/jellyfish/light-03.png +0 -0
- package/assets/jellyfish/light-04.png +0 -0
- package/assets/jellyfish/light-05.png +0 -0
- package/assets/jellyfish/light-06.png +0 -0
- package/assets/jellyfish/light-07.png +0 -0
- package/assets/jellyfish/light-08.png +0 -0
- package/assets/jellyfish/light-09.png +0 -0
- package/assets/jellyfish/light-10.png +0 -0
- package/assets/jellyfish/light-11.png +0 -0
- package/assets/jellyfish/light-12.png +0 -0
- package/assets/jellyfish/light-13.png +0 -0
- package/assets/jellyfish/light-14.png +0 -0
- package/assets/jellyfish/light-15.png +0 -0
- package/assets/jellyfish/light-16.png +0 -0
- package/assets/jellyfish/light-17.png +0 -0
- package/assets/jellyfish/light-18.png +0 -0
- package/assets/jellyfish/light-19.png +0 -0
- package/assets/jellyfish/light-20.png +0 -0
- package/assets/jellyfish/light-21.png +0 -0
- package/assets/jellyfish/light-22.png +0 -0
- package/assets/jellyfish/light-23.png +0 -0
- package/assets/jellyfish/light-24.png +0 -0
- package/assets/jellyfish/light-25.png +0 -0
- package/assets/jellyfish/light-26.png +0 -0
- package/assets/jellyfish/light-27.png +0 -0
- package/assets/jellyfish/light-28.png +0 -0
- package/assets/jellyfish/light-29.png +0 -0
- package/assets/jellyfish/light-30.png +0 -0
- package/assets/jellyfish/light-31.png +0 -0
- package/assets/jellyfish/light-32.png +0 -0
- package/assets/jellyfish/light-33.png +0 -0
- package/assets/jellyfish/light-34.png +0 -0
- package/assets/jellyfish/light-35.png +0 -0
- package/assets/jellyfish/light-36.png +0 -0
- package/assets/jellyfish/light-37.png +0 -0
- package/assets/jellyfish/light-38.png +0 -0
- package/assets/jellyfish/light-39.png +0 -0
- package/assets/jellyfish/light-40.png +0 -0
- package/dist/ask.d.ts +83 -0
- package/dist/brand.d.ts +13 -0
- package/dist/btw.d.ts +67 -0
- package/dist/chat-models.d.ts +22 -0
- package/dist/chat-skills.d.ts +17 -0
- package/dist/cli-options.d.ts +25 -0
- package/dist/cli.d.ts +9 -0
- package/dist/cli.js +7 -1
- package/dist/config-command.d.ts +26 -0
- package/dist/config-edit.d.ts +69 -0
- package/dist/config.d.ts +321 -0
- package/dist/conform-cli.d.ts +1 -0
- package/dist/cultivate-cli.d.ts +1 -0
- package/dist/drift-cli.d.ts +1 -0
- package/dist/environment.d.ts +39 -0
- package/dist/environment.js +26 -0
- package/dist/extension.d.ts +147 -0
- package/dist/extension.js +49 -18
- package/dist/genome.d.ts +62 -0
- package/dist/graph.d.ts +52 -0
- package/dist/host.d.ts +21 -0
- package/dist/host.js +25 -0
- package/dist/identity.d.ts +2 -0
- package/dist/init-config.d.ts +106 -0
- package/dist/jellyfish.d.ts +35 -0
- package/dist/jellyfish.js +230 -97
- package/dist/judge.d.ts +25 -0
- package/dist/lineage-cli.d.ts +1 -0
- package/dist/loop-cli.d.ts +34 -0
- package/dist/loop-tools.d.ts +80 -0
- package/dist/mature-tools.d.ts +53 -0
- package/dist/model-check.d.ts +42 -0
- package/dist/module-report.d.ts +9 -0
- package/dist/pi-launch.d.ts +1 -0
- package/dist/pi.d.ts +246 -0
- package/dist/picture-row.d.ts +10 -0
- package/dist/plain/check.d.ts +23 -0
- package/dist/plain/concepts.d.ts +11 -0
- package/dist/plain/errors.d.ts +22 -0
- package/dist/plain/files.d.ts +12 -0
- package/dist/plain/highlight.d.ts +42 -0
- package/dist/plain/index.d.ts +15 -0
- package/dist/plain/liquid.d.ts +22 -0
- package/dist/plain/markdown.d.ts +74 -0
- package/dist/plain/parser.d.ts +87 -0
- package/dist/plain/spec.d.ts +90 -0
- package/dist/plain/stdlib.d.ts +14 -0
- package/dist/question-dialog.d.ts +51 -0
- package/dist/questioning.d.ts +55 -0
- package/dist/quiet.d.ts +34 -0
- package/dist/regenerate/activity.d.ts +207 -0
- package/dist/regenerate/agent-env.d.ts +44 -0
- package/dist/regenerate/agent-shell.d.ts +49 -0
- package/dist/regenerate/arbiter.d.ts +68 -0
- package/dist/regenerate/audit.d.ts +69 -0
- package/dist/regenerate/cases.d.ts +9 -0
- package/dist/regenerate/change-view.d.ts +18 -0
- package/dist/regenerate/choose-conformance.d.ts +32 -0
- package/dist/regenerate/chunk-plan.d.ts +164 -0
- package/dist/regenerate/codebase.d.ts +21 -0
- package/dist/regenerate/command-check.d.ts +40 -0
- package/dist/regenerate/compaction.d.ts +13 -0
- package/dist/regenerate/confine.d.ts +62 -0
- package/dist/regenerate/conform.d.ts +63 -0
- package/dist/regenerate/conformance-agents.d.ts +405 -0
- package/dist/regenerate/conformance.d.ts +189 -0
- package/dist/regenerate/conversation-writes.d.ts +10 -0
- package/dist/regenerate/credentials.d.ts +18 -0
- package/dist/regenerate/debug-log.d.ts +54 -0
- package/dist/regenerate/debugger.d.ts +31 -0
- package/dist/regenerate/delivery.d.ts +6 -0
- package/dist/regenerate/diagnose-job.d.ts +2 -0
- package/dist/regenerate/diagnose.d.ts +46 -0
- package/dist/regenerate/diff-view.d.ts +61 -0
- package/dist/regenerate/drift.d.ts +84 -0
- package/dist/regenerate/engine.d.ts +52 -0
- package/dist/regenerate/environment-error.d.ts +136 -0
- package/dist/regenerate/job-log.d.ts +28 -0
- package/dist/regenerate/job-panel.d.ts +122 -0
- package/dist/regenerate/jobs-tree.d.ts +71 -0
- package/dist/regenerate/jobs.d.ts +186 -0
- package/dist/regenerate/lanes.d.ts +16 -0
- package/dist/regenerate/lineage.d.ts +95 -0
- package/dist/regenerate/list-arguments.d.ts +21 -0
- package/dist/regenerate/loop.d.ts +392 -0
- package/dist/regenerate/masking.d.ts +19 -0
- package/dist/regenerate/notes.d.ts +159 -0
- package/dist/regenerate/os-sandbox.d.ts +89 -0
- package/dist/regenerate/panel-dock.d.ts +23 -0
- package/dist/regenerate/paths.d.ts +92 -0
- package/dist/regenerate/plain-palette.d.ts +34 -0
- package/dist/regenerate/prompt.d.ts +192 -0
- package/dist/regenerate/records.d.ts +88 -0
- package/dist/regenerate/regenerate.d.ts +108 -0
- package/dist/regenerate/regression.d.ts +58 -0
- package/dist/regenerate/release.d.ts +123 -0
- package/dist/regenerate/requires.d.ts +96 -0
- package/dist/regenerate/resources.d.ts +53 -0
- package/dist/regenerate/self-check.d.ts +29 -0
- package/dist/regenerate/services.d.ts +28 -0
- package/dist/regenerate/shell.d.ts +91 -0
- package/dist/regenerate/side-panel.d.ts +57 -0
- package/dist/regenerate/spec-map-view.d.ts +139 -0
- package/dist/regenerate/spec-map.d.ts +138 -0
- package/dist/regenerate/spec-steps.d.ts +137 -0
- package/dist/regenerate/state.d.ts +20 -0
- package/dist/regenerate/steer.d.ts +34 -0
- package/dist/regenerate/steering.d.ts +56 -0
- package/dist/regenerate/stop-report.d.ts +43 -0
- package/dist/regenerate/submit-work.d.ts +42 -0
- package/dist/regenerate/test-kinds.d.ts +42 -0
- package/dist/regenerate/test-scripts.d.ts +221 -0
- package/dist/regenerate/testing.d.ts +141 -0
- package/dist/regenerate/transcript-view.d.ts +21 -0
- package/dist/regenerate/unit-gate.d.ts +27 -0
- package/dist/regenerate/unit-review.d.ts +152 -0
- package/dist/regenerate/web.d.ts +61 -0
- package/dist/regenerate/workspace.d.ts +12 -0
- package/dist/regenerate-cli.d.ts +1 -0
- package/dist/release-agent.d.ts +26 -0
- package/dist/release-cli.d.ts +1 -0
- package/dist/release-tools.d.ts +38 -0
- package/dist/resume-line.d.ts +2 -0
- package/dist/review/live.d.ts +72 -0
- package/dist/rules.d.ts +20 -0
- package/dist/run-report.d.ts +88 -0
- package/dist/screen-padding.d.ts +28 -0
- package/dist/self-invocation.d.ts +25 -0
- package/dist/setup.d.ts +43 -0
- package/dist/skill-progress.d.ts +46 -0
- package/dist/skill.d.ts +98 -0
- package/dist/skills.d.ts +30 -0
- package/dist/spec-diff-cli.d.ts +1 -0
- package/dist/spec-tools.d.ts +36 -0
- package/dist/stack.d.ts +58 -0
- package/dist/stacks.d.ts +12 -0
- package/dist/stdlib.d.ts +27 -0
- package/dist/terminal-images.d.ts +2 -0
- package/dist/tools.d.ts +101 -0
- package/dist/validate-cli.d.ts +1 -0
- package/docs/README.md +2 -0
- package/docs/hosting.md +52 -0
- package/docs/images/turri-banner.gif +0 -0
- package/docs/installation.md +1 -1
- package/docs/theming.md +8 -6
- package/docs/using.md +1 -1
- package/package.json +8 -1
- package/docs/images/turri-banner.png +0 -0
- package/docs/images/turri-screenshot.png +0 -0
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The audit after every agent command, on every platform: the net under the command check and the OS sandbox.
|
|
3
|
+
*
|
|
4
|
+
* Inside the project, what the command's role may not change is put back as it was before it ran - a changed file
|
|
5
|
+
* restored, a new one removed, a deleted one brought back: the specs, the config, the testing scripts, every credential
|
|
6
|
+
* file, the code record, the module's lineage, the other modules, and the folders the role only reads. Small files are
|
|
7
|
+
* kept before the command and put back from that copy; another module is put back as its last commit has it - unless a
|
|
8
|
+
* pulse is at work in it, whose writes are not this command's to undo. The role's own work is left alone, and the pulse
|
|
9
|
+
* goes on. Outside the project nothing can be put back: that is the OS sandbox's. Nor is a change the conversation
|
|
10
|
+
* itself made while the command ran - the person's model editing a spec beside a pulse (`conversation-writes.ts`): that
|
|
11
|
+
* is left, not taken for the command's.
|
|
12
|
+
*
|
|
13
|
+
* What changed is seen cheaply: each file's size and modification time before and after, skipping dependencies and
|
|
14
|
+
* build output, and contents compared only where those differ.
|
|
15
|
+
*/
|
|
16
|
+
export interface AuditScope {
|
|
17
|
+
/** The project: the folder holding the specs, the config, the testing scripts and plain_modules. */
|
|
18
|
+
project: string;
|
|
19
|
+
/** The module the agent works in: `plain_modules/<module>`. */
|
|
20
|
+
module: string;
|
|
21
|
+
/** The role's roots it may write - its own work, left alone but for the record and credential files in it. */
|
|
22
|
+
write: string[];
|
|
23
|
+
/** The role's roots it only reads: put back whole. */
|
|
24
|
+
readOnly: string[];
|
|
25
|
+
/** Whether a pulse is at work in another module - what changes there is that pulse's, and left. */
|
|
26
|
+
busy?: (moduleDir: string) => boolean;
|
|
27
|
+
}
|
|
28
|
+
export interface AuditResult {
|
|
29
|
+
/** Put back as it was, by path from the project. */
|
|
30
|
+
putBack: string[];
|
|
31
|
+
/** Changed where a pulse is at work, and left - for the job log. */
|
|
32
|
+
left: string[];
|
|
33
|
+
/** Changed, and nothing to put it back from. */
|
|
34
|
+
lost: string[];
|
|
35
|
+
/** Changed by the conversation itself while the command ran, and left. */
|
|
36
|
+
conversation: string[];
|
|
37
|
+
}
|
|
38
|
+
interface Seen {
|
|
39
|
+
size: number;
|
|
40
|
+
mtimeMs: number;
|
|
41
|
+
}
|
|
42
|
+
/** A tree's files by path, with their size and time - and, where kept, what they held. */
|
|
43
|
+
interface Tree {
|
|
44
|
+
root: string;
|
|
45
|
+
files: Map<string, Seen>;
|
|
46
|
+
/** What the files held, for those put back from a copy. */
|
|
47
|
+
kept?: Map<string, Buffer>;
|
|
48
|
+
/** How it is put back: from the copy, or from the module's last commit. */
|
|
49
|
+
from: "copy" | {
|
|
50
|
+
lineage: string;
|
|
51
|
+
};
|
|
52
|
+
/** Only its record and credential files are watched: the role writes the rest. */
|
|
53
|
+
watchOnly?: boolean;
|
|
54
|
+
/** Another module a pulse is at work in: what changes there is left. */
|
|
55
|
+
busy?: boolean;
|
|
56
|
+
}
|
|
57
|
+
export interface AuditSnapshot {
|
|
58
|
+
scope: AuditScope;
|
|
59
|
+
trees: Tree[];
|
|
60
|
+
/** When it was taken: a change the conversation made since is the conversation's, not the command's. */
|
|
61
|
+
at: number;
|
|
62
|
+
}
|
|
63
|
+
/** Take what the audit compares against, before a command runs. */
|
|
64
|
+
export declare function beforeCommand(scope: AuditScope): AuditSnapshot;
|
|
65
|
+
/** After the command: put back what it changed that its role may not, and say what. */
|
|
66
|
+
export declare function afterCommand(snapshot: AuditSnapshot): AuditResult;
|
|
67
|
+
/** What the agent is told in its command's result, or nothing when the audit put nothing back. */
|
|
68
|
+
export declare function auditMessage(result: AuditResult): string | undefined;
|
|
69
|
+
export {};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { JobCases } from "./drift.ts";
|
|
2
|
+
/** What the coding agent does, case by case. */
|
|
3
|
+
export declare function codeCasesBlock(cases: JobCases): string[];
|
|
4
|
+
/** What the unit reviewer holds the work to, case by case - in place of its checks, when the job is mechanical. */
|
|
5
|
+
export declare function codeReviewCasesBlock(cases: JobCases): string[];
|
|
6
|
+
/** What the conformance agent does, case by case. */
|
|
7
|
+
export declare function conformanceCasesBlock(cases: JobCases): string[];
|
|
8
|
+
/** What the conformance test reviewer holds the tests to, when the job is mechanical: in place of its checks. */
|
|
9
|
+
export declare function conformanceReviewCasesBlock(cases: JobCases): string[];
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { DiffWhere } from "./diff-view.ts";
|
|
2
|
+
import { type SpecChange } from "./spec-steps.ts";
|
|
3
|
+
/**
|
|
4
|
+
* `changes` as a diff of `file` - the module's .plain file, which the diff names - section by section: a removed
|
|
5
|
+
* item's lines taken out, an added one's put in, a changed one's both. A change to what a linked file holds
|
|
6
|
+
* follows, as the step's own diff has it.
|
|
7
|
+
*/
|
|
8
|
+
export declare function changeDiff(changes: SpecChange[], file: string): string;
|
|
9
|
+
/**
|
|
10
|
+
* `changeDiff`, each section's items in the order they are written - by file, then by line - rather than in the
|
|
11
|
+
* order the spec is read in, which puts a concept after those it uses: placed by `locate`, as the panels place it.
|
|
12
|
+
*/
|
|
13
|
+
export declare function changeDiffInFiles(changes: SpecChange[], file: string, locate: (diff: string) => DiffWhere): {
|
|
14
|
+
diff: string;
|
|
15
|
+
where: DiffWhere;
|
|
16
|
+
};
|
|
17
|
+
/** The changes a job's agent works from: a code job's leave out the test reqs, which are the conformance job's. */
|
|
18
|
+
export declare function agentChanges(changes: SpecChange[], track: "code" | "conformance"): SpecChange[];
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import type { TouchedSpec } from "./drift.ts";
|
|
2
|
+
/**
|
|
3
|
+
* Which functional specs get conformance tests, under `conformance-tests: chosen` or `module`, is this agent's to choose -
|
|
4
|
+
* in the chat and on the command line alike, on the chooser's model. Under chosen it is asked as each code pulse ends,
|
|
5
|
+
* of what that pulse regenerated; under module once, when the whole module is regenerated, and it plans the conformance
|
|
6
|
+
* pulses too. It reads the module's spec and names the ones worth black-box tests, and why. Being asked inside the pulse,
|
|
7
|
+
* the choice is made before anything can be built on the module: nothing has to be stopped for it.
|
|
8
|
+
*/
|
|
9
|
+
export interface ConformanceChoice {
|
|
10
|
+
frids: string[];
|
|
11
|
+
why: string;
|
|
12
|
+
/** Under module: the conformance pulses, each the functional specs it tests together. */
|
|
13
|
+
groups?: string[][];
|
|
14
|
+
}
|
|
15
|
+
/** What the chooser is asked: the module's spec, and the functional specs to choose from. */
|
|
16
|
+
export declare function choicePrompt(plainFile: string, specs: TouchedSpec[], spec: string, budget?: number, when?: "pulse" | "module"): string;
|
|
17
|
+
/** Ask the chooser, on `model`. Nothing chosen when it does not answer, or answers with numbers not offered. */
|
|
18
|
+
export declare function chooseConformance(options: {
|
|
19
|
+
plainFile: string;
|
|
20
|
+
specs: TouchedSpec[];
|
|
21
|
+
model?: string;
|
|
22
|
+
budget?: number;
|
|
23
|
+
when?: "pulse" | "module";
|
|
24
|
+
}): Promise<ConformanceChoice>;
|
|
25
|
+
/**
|
|
26
|
+
* The work loop's chooser, the chat's and the command line's alike: asked as a pulse ends, it asks chooseConformance on
|
|
27
|
+
* the harness model. A functional spec passed over is not offered again for the same text - only once it changes.
|
|
28
|
+
*/
|
|
29
|
+
export declare function conformanceChooser(options: {
|
|
30
|
+
model: () => string | undefined;
|
|
31
|
+
dryRun?: boolean;
|
|
32
|
+
}): (plainFile: string, specs: TouchedSpec[], budget: number | undefined, when: "pulse" | "module") => Promise<ConformanceChoice | undefined>;
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
import { type MarshalledPlainSource } from "../plain/spec.ts";
|
|
2
|
+
import { type Steering } from "./steer.ts";
|
|
3
|
+
import { type SpecChange, type SpecStep } from "./spec-steps.ts";
|
|
4
|
+
/**
|
|
5
|
+
* The queue's work, cut into jobs of a size worth rendering.
|
|
6
|
+
*
|
|
7
|
+
* A spec diff that renders the whole of a new spec is one job too big to build well, and a render per functional
|
|
8
|
+
* spec, the first carrying every definition and req of the spec, is no better: most of the work lands in one job,
|
|
9
|
+
* and the rest are a line each. So the work from what the code will be built from to the spec now is cut from the
|
|
10
|
+
* functional specs outward, in three steps:
|
|
11
|
+
*
|
|
12
|
+
* 1. Which new functional specs go together - next to each other, as the spec orders them, at most
|
|
13
|
+
* `max-specs-per-pulse` in a job (MAX_SPECS_PER_JOB unset): what builds one feature goes together, and only what
|
|
14
|
+
* stands on its own goes alone. An agent judges it: "builds the same thing" is a judgement.
|
|
15
|
+
* 2. The definitions each group uses: the concepts its functional specs name, and the concepts those
|
|
16
|
+
* definitions name in turn. A definition goes with the first group that uses it; later ones have it built.
|
|
17
|
+
* Code, not an agent: it is a lookup.
|
|
18
|
+
* 3. Where each new implementation req goes - the group it is about, or the first, when it is about
|
|
19
|
+
* everything - and each new test req: the group whose conformance tests need it first. An agent judges it.
|
|
20
|
+
*
|
|
21
|
+
* Changes to what is built already - an item edited or taken out, a functional spec built changed - go first, in a
|
|
22
|
+
* job of their own. Every answer is checked; one that does not hold goes back to its agent, twice at most, and then
|
|
23
|
+
* the plan falls back to a functional spec a job. A job past `max-lines-per-pulse` (MAX_LINES_PER_JOB unset) is split. The plan is the queue
|
|
24
|
+
* master's proposal: it reviews it, and may change it, held to the same checks.
|
|
25
|
+
*/
|
|
26
|
+
/** What the planner cuts: the work from `base` to `current`, and the module's .plain file for how the diffs read. */
|
|
27
|
+
export interface PlanInput {
|
|
28
|
+
/** What the work starts from: the record, or what the job running lands. */
|
|
29
|
+
base: MarshalledPlainSource;
|
|
30
|
+
/** What it ends on: the spec as the track sees it now. */
|
|
31
|
+
current: MarshalledPlainSource;
|
|
32
|
+
/** How the person wants the work cut and ordered. */
|
|
33
|
+
steering?: Steering[];
|
|
34
|
+
/** The module whose codebase it is: its own functional specs are given with it. */
|
|
35
|
+
moduleName?: string;
|
|
36
|
+
/** The module's .plain file, as the diffs name it, and its text - for the diffs' layout. */
|
|
37
|
+
specFile: string;
|
|
38
|
+
specText: string;
|
|
39
|
+
/**
|
|
40
|
+
* Which work it is. The conformance tests' is anchored on functional specs: a job of theirs tests at least one -
|
|
41
|
+
* the definitions and reqs they are written against go with the functional specs whose tests need them.
|
|
42
|
+
* Default: the code's.
|
|
43
|
+
*/
|
|
44
|
+
track?: "code" | "conformance";
|
|
45
|
+
/**
|
|
46
|
+
* For the conformance tests: a job a functional spec, as the person asked. Otherwise every functional spec tested is
|
|
47
|
+
* in one job, as far as the guardrail (`max-lines-per-pulse`) lets.
|
|
48
|
+
*/
|
|
49
|
+
separately?: boolean;
|
|
50
|
+
/**
|
|
51
|
+
* For the conformance tests: the functional specs asked for together, a group a request - `conform` called for 1-3, then
|
|
52
|
+
* for 4-6. Never two groups in one job; the functional specs in none are tested together, as before.
|
|
53
|
+
*/
|
|
54
|
+
groups?: string[][];
|
|
55
|
+
/** How big a pulse may be - the config's `max-specs-per-pulse` and `max-lines-per-pulse`; unset, MAX_SPECS_PER_JOB and MAX_LINES_PER_JOB. */
|
|
56
|
+
limits?: PulseLimits;
|
|
57
|
+
}
|
|
58
|
+
/** How big a pulse may be: how many functional specs, and how many lines of spec with the definitions they bring. */
|
|
59
|
+
export interface PulseLimits {
|
|
60
|
+
specs: number;
|
|
61
|
+
lines: number;
|
|
62
|
+
}
|
|
63
|
+
/** One job of a plan: a title, why, and the changes it makes, by id. */
|
|
64
|
+
export interface DraftJob {
|
|
65
|
+
title: string;
|
|
66
|
+
reason: string;
|
|
67
|
+
changes: string[];
|
|
68
|
+
}
|
|
69
|
+
/** The work the queue does: every change from the base to the spec as it is now, numbered. */
|
|
70
|
+
export declare function netChanges(base: MarshalledPlainSource, current: MarshalledPlainSource): SpecChange[];
|
|
71
|
+
/**
|
|
72
|
+
* What is wrong with a reworked queue, or nothing: every change in exactly one job, no job without
|
|
73
|
+
* one, and each job, applied after the ones before it, leaving a spec that holds together - the last
|
|
74
|
+
* exactly the spec as it is now.
|
|
75
|
+
*/
|
|
76
|
+
export declare function checkDraft(input: PlanInput, draft: DraftJob[]): string[];
|
|
77
|
+
/** A checked draft, as the queue runs it: each job's diff and the spec it leaves. */
|
|
78
|
+
export declare function stepsOf(input: PlanInput, draft: DraftJob[]): Array<DraftJob & {
|
|
79
|
+
step: SpecStep;
|
|
80
|
+
}>;
|
|
81
|
+
export declare const MAX_SPECS_PER_JOB = 3;
|
|
82
|
+
export declare const MAX_LINES_PER_JOB = 120;
|
|
83
|
+
/**
|
|
84
|
+
* A functional spec to build, for the grouping: the number the agent answers with, its text, and whether it is built
|
|
85
|
+
* already and regenerated again. `id` and `module` say which it is: each module numbers its own from 1, and a codebase
|
|
86
|
+
* regenerates again the functional specs of the modules it is built on too. No module: the codebase's own. No id: the
|
|
87
|
+
* number.
|
|
88
|
+
*/
|
|
89
|
+
export interface NewSpec {
|
|
90
|
+
number: number;
|
|
91
|
+
text: string;
|
|
92
|
+
again?: boolean;
|
|
93
|
+
id?: string;
|
|
94
|
+
module?: string;
|
|
95
|
+
}
|
|
96
|
+
export interface GroupAnswer {
|
|
97
|
+
groups: Array<{
|
|
98
|
+
specs: number[];
|
|
99
|
+
title: string;
|
|
100
|
+
}>;
|
|
101
|
+
/** What of the person's wishes it did not follow, and why. */
|
|
102
|
+
notes?: string;
|
|
103
|
+
}
|
|
104
|
+
export interface PlaceInput {
|
|
105
|
+
/** How the person or the harness wants the queue planned. */
|
|
106
|
+
steering?: Steering[];
|
|
107
|
+
groups: Array<{
|
|
108
|
+
number: number;
|
|
109
|
+
title: string;
|
|
110
|
+
specs: string[];
|
|
111
|
+
definitions: string[];
|
|
112
|
+
}>;
|
|
113
|
+
/** What is built already changes too: a job for that goes first, and a req can go with it. */
|
|
114
|
+
built: boolean;
|
|
115
|
+
implementationReqs: Array<{
|
|
116
|
+
number: number;
|
|
117
|
+
text: string;
|
|
118
|
+
}>;
|
|
119
|
+
testReqs: Array<{
|
|
120
|
+
number: number;
|
|
121
|
+
text: string;
|
|
122
|
+
}>;
|
|
123
|
+
}
|
|
124
|
+
/** Where a req goes: a group's number, "all" - the first job, it is about everything - or "built", with the changes to what is built. */
|
|
125
|
+
export type Target = number | "all" | "built";
|
|
126
|
+
export interface PlaceAnswer {
|
|
127
|
+
implementationReqs: Array<{
|
|
128
|
+
req: number;
|
|
129
|
+
to: Target;
|
|
130
|
+
}>;
|
|
131
|
+
testReqs: Array<{
|
|
132
|
+
req: number;
|
|
133
|
+
to: Target;
|
|
134
|
+
}>;
|
|
135
|
+
/** What of the person's wishes it did not follow, and why. */
|
|
136
|
+
notes?: string;
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* The two judgements, each asked again with what was wrong with its answer - the last answer given, whether it holds
|
|
140
|
+
* or not: the plan checks it again. Injectable, so the plan is testable without a model.
|
|
141
|
+
*/
|
|
142
|
+
export interface ChunkAgents {
|
|
143
|
+
group(specs: NewSpec[], check: (answer: GroupAnswer) => string[], steering?: Steering[], maxSpecs?: number): Promise<GroupAnswer | undefined>;
|
|
144
|
+
place(input: PlaceInput, check: (answer: PlaceAnswer) => string[]): Promise<PlaceAnswer | undefined>;
|
|
145
|
+
}
|
|
146
|
+
/** What is wrong with a grouping: every new functional spec once, in order, next to each other, none too big. */
|
|
147
|
+
export declare function groupProblems(specs: NewSpec[], answer: GroupAnswer, maxSpecs?: number): string[];
|
|
148
|
+
/** What is wrong with a placement: every new req once, each where there is such a job. */
|
|
149
|
+
export declare function placeProblems(input: PlaceInput, answer: PlaceAnswer): string[];
|
|
150
|
+
/**
|
|
151
|
+
* Cut the queue's work - from `input.base` to `input.current` - into jobs, as the three steps say. Returns the draft
|
|
152
|
+
* the work loop runs: checked (checkDraft), or, when nothing holds, the whole work as one job. `notes` is given what
|
|
153
|
+
* the plan did not do as asked - the person's wishes an agent did not follow and why, an answer that did not hold, a
|
|
154
|
+
* group split for its size - for the conversation to say, rather than guess.
|
|
155
|
+
*/
|
|
156
|
+
export declare function planChunks(input: PlanInput, agents?: ChunkAgents, notes?: string[]): Promise<DraftJob[]>;
|
|
157
|
+
export declare function groupPrompt(specs: NewSpec[], steering?: Steering[], maxSpecs?: number): string;
|
|
158
|
+
export declare function placePrompt(input: PlaceInput): string;
|
|
159
|
+
/** The chunking's two agents, on a model - fresh for every plan. */
|
|
160
|
+
export declare function llmChunkAgents(options: {
|
|
161
|
+
cwd: string;
|
|
162
|
+
model?: string;
|
|
163
|
+
label?: string;
|
|
164
|
+
}): ChunkAgents;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* What a render agent is told about the code before it starts.
|
|
3
|
+
*
|
|
4
|
+
* Every render is a fresh session, and without this each one begins by rediscovering the
|
|
5
|
+
* codebase - listing directories, grepping for where things are - which on a long module is
|
|
6
|
+
* the same exploration repeated once per functionality, getting longer as the code does. The
|
|
7
|
+
* harness already knows the answers, and knows them exactly: the files, which
|
|
8
|
+
* functionality put which of them there, and the test command that passed. None of it is
|
|
9
|
+
* the agent's recollection, so none of it can be stale.
|
|
10
|
+
*/
|
|
11
|
+
/** Files by content, so a change is noticed whatever happened to its timestamp. */
|
|
12
|
+
export declare function digestFiles(root: string): Map<string, string>;
|
|
13
|
+
export declare function diffFiles(before: Map<string, string>, after: Map<string, string>): {
|
|
14
|
+
added: string[];
|
|
15
|
+
changed: string[];
|
|
16
|
+
removed: string[];
|
|
17
|
+
};
|
|
18
|
+
/** Whether the work has written nothing in `root` since `atStart` - its working notes and the build record aside. */
|
|
19
|
+
export declare function wroteNothing(root: string, atStart: Map<string, string>): boolean;
|
|
20
|
+
/** The map of the codebase as it stands - or null when there is no code yet. */
|
|
21
|
+
export declare function codebaseMap(buildDir: string): string | null;
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The check every agent command passes before it runs, on every platform.
|
|
3
|
+
*
|
|
4
|
+
* A command is one string, and no check of its text can say for certain what it will read or write: a path built at
|
|
5
|
+
* run time, a script that reads one from a file, gets past any. So this is the first wall of three, not the only one -
|
|
6
|
+
* the OS sandbox stops what gets past it where the OS has one, and the audit after the command puts back what reached
|
|
7
|
+
* the project. What it is for is the honest mistake and the plain attempt, caught before anything runs, with a reason
|
|
8
|
+
* the agent can act on: a path outside its walls, the code record, a credential file written, software installed on
|
|
9
|
+
* the machine, a process killed that its pulse did not start. Pure: it reads the text and the fence, and runs nothing.
|
|
10
|
+
*/
|
|
11
|
+
export interface CommandFence {
|
|
12
|
+
/** Where the command starts: the agent's folder. */
|
|
13
|
+
cwd: string;
|
|
14
|
+
/** The role's roots it may read. */
|
|
15
|
+
read: string[];
|
|
16
|
+
/** The role's roots it may write. */
|
|
17
|
+
write: string[];
|
|
18
|
+
/** Its HOME, what `~` and `$HOME` mean. */
|
|
19
|
+
home?: string;
|
|
20
|
+
/** Its TMPDIR, what `$TMPDIR` means. */
|
|
21
|
+
tmp?: string;
|
|
22
|
+
/** Beside the roots: what its shell may write - the home, the TMPDIR, the package caches. Readable too. */
|
|
23
|
+
writable?: string[];
|
|
24
|
+
/** Beside the roots: what of the machine it may read - the system folders, the toolchains. */
|
|
25
|
+
readable?: string[];
|
|
26
|
+
/** Whose paths these are: drive letters, backslashes and any case on Windows. */
|
|
27
|
+
platform?: "posix" | "win32";
|
|
28
|
+
}
|
|
29
|
+
export type CheckRule = "path" | "record" | "credential" | "install" | "kill";
|
|
30
|
+
export type CheckResult = {
|
|
31
|
+
ok: true;
|
|
32
|
+
} | {
|
|
33
|
+
ok: false;
|
|
34
|
+
rule: CheckRule;
|
|
35
|
+
reason: string;
|
|
36
|
+
};
|
|
37
|
+
/** What of the machine an agent's command may read, beside its roots and its toolchains: the system's own folders. */
|
|
38
|
+
export declare function machineReadable(platform?: NodeJS.Platform): string[];
|
|
39
|
+
/** Check one command line against a role's fence: `{ ok: true }`, or which rule it breaks and what to do instead. */
|
|
40
|
+
export declare function checkCommand(command: string, fence: CommandFence): CheckResult;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* What an agent's work is summed up to when its session gets long - one set of instructions per role.
|
|
3
|
+
*
|
|
4
|
+
* An agent that keeps its session through a job is compacted between turns once its conversation - what it has
|
|
5
|
+
* done, not its instructions - passes the project's compact-at (see pi.ts compactIfDue). Its task is its system
|
|
6
|
+
* prompt and is never summed up, so these say only what of the work the summary must keep for it to go on.
|
|
7
|
+
*/
|
|
8
|
+
/** The coding agent, and the code fixer of a conformance run: what is done, what is not, and why. */
|
|
9
|
+
export declare const CODER_COMPACTION: string;
|
|
10
|
+
/** The conformance agent: the tests written, what they cover, and what is still open. */
|
|
11
|
+
export declare const CONFORMANCE_COMPACTION: string;
|
|
12
|
+
/** A reviewer: what it raised, and where each problem stands. */
|
|
13
|
+
export declare const REVIEWER_COMPACTION: string;
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { type ToolDefinition } from "@earendil-works/pi-coding-agent";
|
|
2
|
+
import { type AgentShell } from "./agent-shell.ts";
|
|
3
|
+
import type { BashOperations } from "@earendil-works/pi-coding-agent";
|
|
4
|
+
/**
|
|
5
|
+
* Keeping a rendering agent inside its own directory.
|
|
6
|
+
*
|
|
7
|
+
* pi's `cwd` is where relative paths start from, not a fence: an absolute path resolves to
|
|
8
|
+
* itself and `bash` can `cd` anywhere. That is fine for an agent working on the repo it was
|
|
9
|
+
* launched in, and wrong for these - a render agent is building one module and has no
|
|
10
|
+
* business reading the rest of the project, let alone writing to it.
|
|
11
|
+
*
|
|
12
|
+
* So the tools are rebuilt from pi's own factories with a check in front of every path, and
|
|
13
|
+
* `bash` runs on this machine behind every wall at once (see `agent-shell.ts`): the command check,
|
|
14
|
+
* the module's own environment, the OS sandbox where one is up, the audit. Both reach the agent's
|
|
15
|
+
* own folder - its module's `code/`, unless the role is given others - and nothing else: not another
|
|
16
|
+
* module, not turri's scratch area or the module's lineage, not the specs, not the rest of the project.
|
|
17
|
+
*/
|
|
18
|
+
export interface Confinement {
|
|
19
|
+
/** Where the agent starts and where relative paths resolve - and, unless `read` and `write` say otherwise, all its file tools reach. */
|
|
20
|
+
workdir: string;
|
|
21
|
+
/** The only folders its file tools may read: its workdir when not given. */
|
|
22
|
+
read?: string[];
|
|
23
|
+
/** The only folders they may write - its workdir when not given; none, and it has no write or edit tool at all. */
|
|
24
|
+
write?: string[];
|
|
25
|
+
/** No shell either - for an agent that only reads. */
|
|
26
|
+
noBash?: boolean;
|
|
27
|
+
/**
|
|
28
|
+
* It may report that the machine lacks what the work needs (report_environment_error) - only the agents that write
|
|
29
|
+
* and run code: the coding agents and the conformance agent. Observers, explorers and judges never do.
|
|
30
|
+
*/
|
|
31
|
+
reportsEnvironment?: boolean;
|
|
32
|
+
}
|
|
33
|
+
export declare class ConfinementError extends Error {
|
|
34
|
+
constructor(message: string);
|
|
35
|
+
}
|
|
36
|
+
export declare function insideAny(path: string, roots: string[]): boolean;
|
|
37
|
+
type AnyTool = ToolDefinition<any, any, any>;
|
|
38
|
+
export interface ConfinedTools {
|
|
39
|
+
tools: AnyTool[];
|
|
40
|
+
/** Tool names, for the session's `tools` list. */
|
|
41
|
+
names: string[];
|
|
42
|
+
/** One line for the log: what is enforced and how. */
|
|
43
|
+
description: string;
|
|
44
|
+
/** The agent's sandbox, as it is told it in its system prompt: what it can reach, and that nothing else exists. */
|
|
45
|
+
note: string;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* An agent's walls, in words, for its system prompt - from its fence itself, so it says exactly what is enforced, the
|
|
49
|
+
* same on every platform. An agent that does not know where its walls are spends its turns walking into them. Its own
|
|
50
|
+
* folders by absolute path and no other; matter-of-fact about what happens on a reach outside - refused, or put back -
|
|
51
|
+
* and no warning. `environmentTool`: the tool an agent reports a missing piece of the machine with, when it has one.
|
|
52
|
+
*/
|
|
53
|
+
export declare function sandboxNote(fence: {
|
|
54
|
+
read: string[];
|
|
55
|
+
write: string[];
|
|
56
|
+
shell: boolean;
|
|
57
|
+
environmentTool?: string;
|
|
58
|
+
}): string;
|
|
59
|
+
/** pi's bash tool over an agent's shell: each command checked, run behind its walls, audited. */
|
|
60
|
+
export declare function hostBashOperations(shell: AgentShell): BashOperations;
|
|
61
|
+
export declare function confinedTools(c: Confinement): ConfinedTools;
|
|
62
|
+
export {};
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import type { JobCases } from "./drift.ts";
|
|
2
|
+
import { type RenderConformanceTestsResult } from "./conformance.ts";
|
|
3
|
+
import { type RegressionResult } from "./regression.ts";
|
|
4
|
+
import { type SpecSnapshot } from "./regenerate.ts";
|
|
5
|
+
import { type SpecGap } from "./notes.ts";
|
|
6
|
+
/**
|
|
7
|
+
* The conformance tests brought in line with a spec change: a conformance job of the work loop
|
|
8
|
+
* (docs/regenerating.md).
|
|
9
|
+
*
|
|
10
|
+
* Rendering the code and conformance are separate jobs. A spec change is built in the code first
|
|
11
|
+
* and its tests follow, or it is a change the code does not need at all - test reqs, an acceptance
|
|
12
|
+
* test - and only the tests follow it. Either way one agent is given the diff and the
|
|
13
|
+
* spec as it stands, and brings the tests in line: writes, changes and removes them. It can fix
|
|
14
|
+
* the code where a test shows the code does not do what the spec says, as it can when it writes a
|
|
15
|
+
* functionality's tests; nothing here renders the change itself.
|
|
16
|
+
*
|
|
17
|
+
* Nothing records which changes the tests have followed: the tests carry that themselves, each
|
|
18
|
+
* labelled with its functionality, and the agent reads them against the whole spec.
|
|
19
|
+
*
|
|
20
|
+
* The tests are written in the chain's current codebase - the furthest-built module whose chain
|
|
21
|
+
* includes the one the change is to - because that is where the code they check lives, and
|
|
22
|
+
* where they are carried up from as later modules are built. A change to a module low in the
|
|
23
|
+
* chain is tested in the latest module built on it.
|
|
24
|
+
*/
|
|
25
|
+
export interface RenderSpecDiffConformanceOptions {
|
|
26
|
+
/** What the job does to each functional spec (work.ts): its agents are told case by case. */
|
|
27
|
+
cases?: JobCases;
|
|
28
|
+
/** A .plain file of the module the change is for. */
|
|
29
|
+
plainFile: string;
|
|
30
|
+
/** The change, as a git diff of the .plain files. */
|
|
31
|
+
diff: string;
|
|
32
|
+
/** That change section by section, as the render that landed it worked it out: shown to the agents in place of the diff. */
|
|
33
|
+
change?: string;
|
|
34
|
+
/** Where the diff's paths are relative to. Default: the working directory. */
|
|
35
|
+
cwd?: string;
|
|
36
|
+
templateDirs?: string[];
|
|
37
|
+
/** The codebase to test in, when modules built on this one branch. */
|
|
38
|
+
inModule?: string;
|
|
39
|
+
/** The diff was already put in when the job was asked for, and how that went. */
|
|
40
|
+
applied?: "applied" | "already applied";
|
|
41
|
+
/** The spec as parsed with the diff in. Taken now, after applying it, when not given. */
|
|
42
|
+
spec?: SpecSnapshot;
|
|
43
|
+
model?: string;
|
|
44
|
+
onDelta?: (delta: string) => void;
|
|
45
|
+
}
|
|
46
|
+
export interface RenderSpecDiffConformanceResult {
|
|
47
|
+
/** The codebase the tests were written and run in. */
|
|
48
|
+
moduleName: string;
|
|
49
|
+
buildDir: string;
|
|
50
|
+
conformanceDir: string;
|
|
51
|
+
diff: "applied" | "already applied";
|
|
52
|
+
conformance: RenderConformanceTestsResult;
|
|
53
|
+
regression?: RegressionResult;
|
|
54
|
+
/** The functionalities the codebase has conformance tests for, as their labels say, after the change. */
|
|
55
|
+
tested: string[];
|
|
56
|
+
passed: boolean;
|
|
57
|
+
stoppedAt: "conformance" | "regression" | null;
|
|
58
|
+
/** Spec gaps its agents reported: what the spec should say and does not, for the person to decide. */
|
|
59
|
+
specGaps?: SpecGap[];
|
|
60
|
+
}
|
|
61
|
+
export declare function renderSpecDiffConformance(options: RenderSpecDiffConformanceOptions): Promise<RenderSpecDiffConformanceResult>;
|
|
62
|
+
/** What the conformance for a spec change did, for the agent and the person. */
|
|
63
|
+
export declare function describeSpecDiffConformance(result: RenderSpecDiffConformanceResult): string;
|