@turri-dev/cli 0.1.6 → 0.1.7-next.eb57c34
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/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/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/extension.d.ts +147 -0
- package/dist/extension.js +36 -10
- 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 +25 -0
- 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/package.json +8 -1
package/dist/genome.d.ts
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { type Reporter } from "./graph.ts";
|
|
2
|
+
import type { ToolDefinition } from "@earendil-works/pi-coding-agent";
|
|
3
|
+
import { type Skill } from "./skill.ts";
|
|
4
|
+
import { type AskUser } from "./tools.ts";
|
|
5
|
+
import type { JobRegistry } from "./regenerate/jobs.ts";
|
|
6
|
+
import type { WorkLoop } from "./regenerate/loop.ts";
|
|
7
|
+
export interface EscalationRequest {
|
|
8
|
+
step: string;
|
|
9
|
+
artifact: string;
|
|
10
|
+
critique: string;
|
|
11
|
+
question: string;
|
|
12
|
+
}
|
|
13
|
+
export interface RunSkillResult {
|
|
14
|
+
skill: Skill;
|
|
15
|
+
ok: boolean;
|
|
16
|
+
artifacts: Record<string, string>;
|
|
17
|
+
/** The last step's artifact - what the caller usually wants. */
|
|
18
|
+
output: string;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Run one skill to completion. The only entry point: the CLI and the Pi extension
|
|
22
|
+
* both go through here, so a skill behaves identically whether a human launched it
|
|
23
|
+
* or a conversational agent decided to.
|
|
24
|
+
*/
|
|
25
|
+
export declare function runSkill(opts: {
|
|
26
|
+
skillDir: string;
|
|
27
|
+
cwd: string;
|
|
28
|
+
runDir: string;
|
|
29
|
+
report: Reporter;
|
|
30
|
+
/** Called when a gate cannot be satisfied. Return true to accept the artifact anyway. */
|
|
31
|
+
escalate: (request: EscalationRequest) => Promise<boolean>;
|
|
32
|
+
/** Lets a step interview the user. Omitted: the skill runs with nobody to ask. */
|
|
33
|
+
askUser?: AskUser;
|
|
34
|
+
/** "provider/model-id" for the executor and the judges. Omitted: pi's default. */
|
|
35
|
+
model?: string;
|
|
36
|
+
/** Lets steps build functionalities in the background while the interview continues. */
|
|
37
|
+
renderQueue?: WorkLoop;
|
|
38
|
+
/** What the user has already said, so the skill does not re-ask it. */
|
|
39
|
+
context?: string;
|
|
40
|
+
/** Pick up the run of this skill that was interrupted here, rather than start a new one. */
|
|
41
|
+
resume?: boolean;
|
|
42
|
+
/**
|
|
43
|
+
* Tools the conversation's agent has that the skill's agent needs as well, because the person
|
|
44
|
+
* talks to the skill's agent while it runs - choosing the render model, for one.
|
|
45
|
+
*/
|
|
46
|
+
sharedTools?: ToolDefinition[];
|
|
47
|
+
/**
|
|
48
|
+
* The conversation's tools that act on the work loop (loop-tools.ts): drift, for every skill with the loop - how its
|
|
49
|
+
* builds stand - and regenerate and halt for a skill that names them in its allowed-tools.
|
|
50
|
+
*/
|
|
51
|
+
loopTools?: ToolDefinition[];
|
|
52
|
+
/** The jobs the render queue runs, for a skill that waits for its builds and reads what they recorded. */
|
|
53
|
+
jobs?: JobRegistry;
|
|
54
|
+
}): Promise<RunSkillResult>;
|
|
55
|
+
/** Whether there is a run of this skill here that was interrupted, and could be resumed. */
|
|
56
|
+
export declare function interruptedRun(runDir: string, skillName: string): {
|
|
57
|
+
step?: string;
|
|
58
|
+
updatedAt: string;
|
|
59
|
+
} | undefined;
|
|
60
|
+
/** Human-readable one-liner per step, for logs and tool output. */
|
|
61
|
+
export declare function describeGates(skill: Skill): string[];
|
|
62
|
+
export type { Reporter };
|
package/dist/graph.d.ts
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import type { AgentSession } from "@earendil-works/pi-coding-agent";
|
|
2
|
+
import { type LiveReviewer } from "./review/live.ts";
|
|
3
|
+
import { type Skill } from "./skill.ts";
|
|
4
|
+
export type Decision = "advance" | "retry" | "escalate" | "abort";
|
|
5
|
+
export declare const GenomeState: import("@langchain/langgraph").AnnotationRoot<{
|
|
6
|
+
artifacts: import("@langchain/langgraph").BaseChannel<Record<string, string>, Record<string, string> | import("@langchain/langgraph").OverwriteValue<Record<string, string>>, unknown>;
|
|
7
|
+
attempts: import("@langchain/langgraph").BaseChannel<Record<string, number>, Record<string, number> | import("@langchain/langgraph").OverwriteValue<Record<string, number>>, unknown>;
|
|
8
|
+
/** Judge feedback for the step currently being retried. */
|
|
9
|
+
critique: import("@langchain/langgraph").BaseChannel<string, string | import("@langchain/langgraph").OverwriteValue<string>, unknown>;
|
|
10
|
+
decision: import("@langchain/langgraph").BaseChannel<Decision, Decision | import("@langchain/langgraph").OverwriteValue<Decision>, unknown>;
|
|
11
|
+
}>;
|
|
12
|
+
export type GenomeStateType = typeof GenomeState.State;
|
|
13
|
+
export interface Reporter {
|
|
14
|
+
step(name: string, attempt: number): void;
|
|
15
|
+
artifact(path: string, body: string): void;
|
|
16
|
+
gate(name: string, judges: number): void;
|
|
17
|
+
/** One continuous-review pass finished while the step was still running. */
|
|
18
|
+
livePass?(step: string, scope: string, findings: number): void;
|
|
19
|
+
/** The continuous reviewer's closing word, read at the gate. */
|
|
20
|
+
liveReview?(name: string, passes: number, findings: number): void;
|
|
21
|
+
judge(index: number, model: string, verdict: string, violations: number): void;
|
|
22
|
+
outcome(name: string, decision: Decision, critique: string): void;
|
|
23
|
+
/** One thing the skill's agent just did - a tool call, as one short line - for a view of it while it works. */
|
|
24
|
+
activity?(line: string): void;
|
|
25
|
+
/** The skill's agent's words as they stream, from the start of each reply: `fresh` when a new one begins. */
|
|
26
|
+
said?(delta: string, fresh: boolean): void;
|
|
27
|
+
}
|
|
28
|
+
/** How many times a step whose turn ends on a question in its reply is sent back to carry on. */
|
|
29
|
+
export declare const QUESTION_NUDGES = 2;
|
|
30
|
+
/** Whether a reply ends on a question: its last line, its markdown left aside, ends with a question mark. */
|
|
31
|
+
export declare function endsOnQuestion(reply: string): boolean;
|
|
32
|
+
export declare function compileSkill(opts: {
|
|
33
|
+
skill: Skill;
|
|
34
|
+
cwd: string;
|
|
35
|
+
runDir: string;
|
|
36
|
+
executor: AgentSession;
|
|
37
|
+
report: Reporter;
|
|
38
|
+
/** Default model for the judges, when a gate does not name one of its own. */
|
|
39
|
+
model?: string;
|
|
40
|
+
/** What the user has already said, carried in from the conversation that started this. */
|
|
41
|
+
context?: string;
|
|
42
|
+
/** Reviewers already reading along, by step name. Their findings gate the step too. */
|
|
43
|
+
liveReviewers?: Map<string, LiveReviewer>;
|
|
44
|
+
/** Start at this step instead of the first: a resumed run, picking up where it stopped. */
|
|
45
|
+
startAt?: string;
|
|
46
|
+
/** Called as each step starts, with the state it starts from - what a resumed run restores. */
|
|
47
|
+
onStepStart?: (step: string, state: GenomeStateType) => void;
|
|
48
|
+
/** Called once a step is reported started, before its agent is prompted: the harness's own question goes here. */
|
|
49
|
+
beforeStep?: (step: string) => Promise<void>;
|
|
50
|
+
/** What the harness tells the agent as a step starts, beside its instructions - the questioning level, say. */
|
|
51
|
+
stepNote?: (step: string) => string | undefined;
|
|
52
|
+
}): any;
|
package/dist/host.d.ts
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* turri for a host that runs it itself - a desktop app, an editor - imported as `@turri-dev/cli/host`: the
|
|
3
|
+
* conversation as pi's extension, with the host told of its jobs and asking its questions (createTurriExtension), and
|
|
4
|
+
* what a host shows beside it - a spec parsed, checked and coloured, how far each functional spec is built, the work a
|
|
5
|
+
* spec change would plan. It is turri's own code, as the terminal runs it; a 0.x release may change any of it.
|
|
6
|
+
*/
|
|
7
|
+
export { createTurriExtension, type TurriHost } from "./extension.ts";
|
|
8
|
+
export type { AskUserIO } from "./ask.ts";
|
|
9
|
+
/** pi itself, as turri's extension is built against it: a host makes its session with this one, not another copy. */
|
|
10
|
+
export * as pi from "@earendil-works/pi-coding-agent";
|
|
11
|
+
export { configForSpec, hasProjectConfig, modelSpec, projectModels, readProjectConfig, stacksOf, type ProjectConfig } from "./config.ts";
|
|
12
|
+
export { MODULES_DIR, projectDirOf, resolveTemplateDirs } from "./regenerate/paths.ts";
|
|
13
|
+
export { BEDROCK_DEFAULT, BEDROCK_REGIONS, bedrockModels, initConfig, VENDORS, type BedrockChoice, type Vendor } from "./init-config.ts";
|
|
14
|
+
export { checkPlainFile, type CheckResult } from "./plain/check.ts";
|
|
15
|
+
export { plainFileParser } from "./plain/parser.ts";
|
|
16
|
+
export { FUNCTIONAL_REQUIREMENTS, iterateFunctionalSpecs } from "./plain/spec.ts";
|
|
17
|
+
export { highlightLines, roleOf, type PlainRole } from "./plain/highlight.ts";
|
|
18
|
+
export { createWorkLoop, describeModules, functionalityCompletion, promptOf, type DriftReport, type ModuleStatus, type WorkLoop } from "./regenerate/loop.ts";
|
|
19
|
+
export { createJobRegistry, defaultParallelJobs, type Job, type JobRegistry } from "./regenerate/jobs.ts";
|
|
20
|
+
export { describeTurnIncident, onModelEvent, type TranscriptEntry } from "./regenerate/activity.ts";
|
|
21
|
+
export { sweepOrphanedGroups } from "./regenerate/shell.ts";
|
package/dist/host.js
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* turri for a host that runs it itself - a desktop app, an editor - imported as `@turri-dev/cli/host`: the
|
|
3
|
+
* conversation as pi's extension, with the host told of its jobs and asking its questions (createTurriExtension), and
|
|
4
|
+
* what a host shows beside it - a spec parsed, checked and coloured, how far each functional spec is built, the work a
|
|
5
|
+
* spec change would plan. It is turri's own code, as the terminal runs it; a 0.x release may change any of it.
|
|
6
|
+
*/
|
|
7
|
+
// The conversation.
|
|
8
|
+
export { createTurriExtension } from "./extension.js";
|
|
9
|
+
/** pi itself, as turri's extension is built against it: a host makes its session with this one, not another copy. */
|
|
10
|
+
export * as pi from "@earendil-works/pi-coding-agent";
|
|
11
|
+
// The project and its settings.
|
|
12
|
+
export { configForSpec, hasProjectConfig, modelSpec, projectModels, readProjectConfig, stacksOf } from "./config.js";
|
|
13
|
+
export { MODULES_DIR, projectDirOf, resolveTemplateDirs } from "./regenerate/paths.js";
|
|
14
|
+
// A project's first config.turri.yaml, as `turri init-config` writes it - the vendor whose models it takes chosen by the host.
|
|
15
|
+
export { BEDROCK_DEFAULT, BEDROCK_REGIONS, bedrockModels, initConfig, VENDORS } from "./init-config.js";
|
|
16
|
+
// A spec: parsed, checked, coloured.
|
|
17
|
+
export { checkPlainFile } from "./plain/check.js";
|
|
18
|
+
export { plainFileParser } from "./plain/parser.js";
|
|
19
|
+
export { FUNCTIONAL_REQUIREMENTS, iterateFunctionalSpecs } from "./plain/spec.js";
|
|
20
|
+
export { highlightLines, roleOf } from "./plain/highlight.js";
|
|
21
|
+
// The work: what is built, what is left, and the jobs that build it.
|
|
22
|
+
export { createWorkLoop, describeModules, functionalityCompletion, promptOf } from "./regenerate/loop.js";
|
|
23
|
+
export { createJobRegistry, defaultParallelJobs } from "./regenerate/jobs.js";
|
|
24
|
+
export { describeTurnIncident, onModelEvent } from "./regenerate/activity.js";
|
|
25
|
+
export { sweepOrphanedGroups } from "./regenerate/shell.js";
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `turri init-config`: a project's first config.turri.yaml - the two models, a strong one to talk to and a smaller one to
|
|
3
|
+
* write the code - so a new project starts with a choice that works rather than an empty file. It asks which vendor's
|
|
4
|
+
* models you use and fills in theirs. Every other setting is written out with the value turri uses for it (DEFAULTS),
|
|
5
|
+
* so the file says how the project is built; the optional ones, which have no value of their own - the testing
|
|
6
|
+
* scripts, `module`, `judge-model`, `models` - are there commented out, with an example. docs/config.md has them all.
|
|
7
|
+
*
|
|
8
|
+
* Then it says what to do next: where the file is - turri reads it from that folder and the folders below it, nowhere
|
|
9
|
+
* else - and how to sign in to the vendor so pi, which turri runs on, can reach the models.
|
|
10
|
+
*
|
|
11
|
+
* Amazon Bedrock serves Anthropic's and OpenAI's models in a geography each - an inference profile, `eu.`, `us.`,
|
|
12
|
+
* `global.` - so it asks which of the two, and where. A config.turri.yaml already there keeps everything but the two models; a new one takes
|
|
13
|
+
* from a config.yaml beside it the keys turri reads too.
|
|
14
|
+
*/
|
|
15
|
+
/** A vendor whose models the quick start config is filled in with. */
|
|
16
|
+
export type Vendor = "anthropic" | "openai" | "google" | "amazon-bedrock" | "other";
|
|
17
|
+
/** Whose models Amazon Bedrock serves here. */
|
|
18
|
+
export type BedrockMaker = "anthropic" | "openai";
|
|
19
|
+
/** Amazon Bedrock's choice: whose models, and the geography of the inference profile they run in. */
|
|
20
|
+
export interface BedrockChoice {
|
|
21
|
+
maker: BedrockMaker;
|
|
22
|
+
region: string;
|
|
23
|
+
}
|
|
24
|
+
/** The geographies Bedrock serves each maker's two models in, as pi knows them - the first the default. */
|
|
25
|
+
export declare const BEDROCK_REGIONS: Record<BedrockMaker, string[]>;
|
|
26
|
+
/** Bedrock's models for a maker in a geography: Opus 5.5 and Haiku 5.5, or GPT-6 Astra and Luna. */
|
|
27
|
+
export declare function bedrockModels(choice: BedrockChoice): {
|
|
28
|
+
harness: string;
|
|
29
|
+
coding: string;
|
|
30
|
+
strong: string;
|
|
31
|
+
};
|
|
32
|
+
/** Bedrock's default: Anthropic's models, anywhere. */
|
|
33
|
+
export declare const BEDROCK_DEFAULT: BedrockChoice;
|
|
34
|
+
interface VendorPreset {
|
|
35
|
+
label: string;
|
|
36
|
+
/** The model you talk to: it writes the specs and plans the work. */
|
|
37
|
+
harness: string;
|
|
38
|
+
/** The smaller, cheaper one that writes the code. */
|
|
39
|
+
coding: string;
|
|
40
|
+
/** A strong model for the commented-out judge, reviewer and debugger examples. */
|
|
41
|
+
strong: string;
|
|
42
|
+
/** The environment variables pi reads the vendor's keys from - pi's own names (pi.dev, providers). */
|
|
43
|
+
keys: Array<{
|
|
44
|
+
vendor: string;
|
|
45
|
+
variable: string;
|
|
46
|
+
}>;
|
|
47
|
+
}
|
|
48
|
+
export declare const VENDORS: Record<Vendor, VendorPreset>;
|
|
49
|
+
/**
|
|
50
|
+
* A config.turri.yaml with its two models set to these lines, and nothing else changed: each key's line - and the lines
|
|
51
|
+
* indented under it, when it is written as a block - replaced where it is, or put at the top when it is not there.
|
|
52
|
+
*/
|
|
53
|
+
export declare function withModels(text: string, lines: [string, string]): string;
|
|
54
|
+
/**
|
|
55
|
+
* What turri does with each setting the config leaves out, written into the quick start config so it says so. They
|
|
56
|
+
* must stay what the code falls back to - tests/init-config.test.ts holds them to the constants they mirror.
|
|
57
|
+
*/
|
|
58
|
+
export declare const DEFAULTS: {
|
|
59
|
+
readonly conformanceTests: false;
|
|
60
|
+
readonly review: false;
|
|
61
|
+
readonly mutationTesting: true;
|
|
62
|
+
readonly allowToStopJobs: true;
|
|
63
|
+
readonly releaseAfterPulse: false;
|
|
64
|
+
readonly testingScriptsRunOn: "in-place";
|
|
65
|
+
readonly turnLimit: 120;
|
|
66
|
+
readonly compactAt: 100000;
|
|
67
|
+
readonly maxSpecsPerPulse: 3;
|
|
68
|
+
readonly maxLinesPerPulse: 120;
|
|
69
|
+
};
|
|
70
|
+
/** How many pulses run at once without a setting: half this machine's cores, one to four - as regenerate/jobs.ts has it. */
|
|
71
|
+
export declare function defaultParallel(cores?: number): number;
|
|
72
|
+
/** The quick start config.turri.yaml for a vendor's models - for Bedrock, the maker and geography chosen. */
|
|
73
|
+
export declare function quickStartConfig(vendor?: Vendor, bedrock?: BedrockChoice): string;
|
|
74
|
+
/** The quick start config for the mix of vendors: what turri wrote before it asked. */
|
|
75
|
+
export declare const QUICK_START_CONFIG: string;
|
|
76
|
+
/** A vendor from what was typed: its number in the list, or its name. */
|
|
77
|
+
export declare function vendorOf(answer: string): Vendor | undefined;
|
|
78
|
+
/** Bedrock's maker from what was typed: its number - 1 Anthropic, 2 OpenAI - or its name. */
|
|
79
|
+
export declare function bedrockMakerOf(answer: string): BedrockMaker | undefined;
|
|
80
|
+
/** A geography the maker's models are served in, from what was typed: its number in the list, or its name. */
|
|
81
|
+
export declare function bedrockRegionOf(maker: BedrockMaker, answer: string): string | undefined;
|
|
82
|
+
/**
|
|
83
|
+
* What a config.yaml in `folder` says that turri reads too - another tool's testing scripts, say - by turri's names
|
|
84
|
+
* (`template_dir` read as `template-dir`), in the file's order; and the keys it leaves, turri reading none of them. The
|
|
85
|
+
* two models are the vendor's, so they are not taken.
|
|
86
|
+
*/
|
|
87
|
+
export declare function sharedWithLegacy(folder: string): {
|
|
88
|
+
carried: Array<[string, unknown]>;
|
|
89
|
+
left: string[];
|
|
90
|
+
};
|
|
91
|
+
/**
|
|
92
|
+
* Write the quick start config.turri.yaml in `dir`, with what a config.yaml beside it says that turri reads too. One already
|
|
93
|
+
* there keeps everything but its two models, which are set to the vendor's - `force` writes the whole of it again. Says
|
|
94
|
+
* what it did.
|
|
95
|
+
*/
|
|
96
|
+
export declare function initConfig(dir: string, options?: {
|
|
97
|
+
force?: boolean;
|
|
98
|
+
vendor?: Vendor;
|
|
99
|
+
bedrock?: BedrockChoice;
|
|
100
|
+
}): {
|
|
101
|
+
written: boolean;
|
|
102
|
+
message: string;
|
|
103
|
+
};
|
|
104
|
+
/** `turri init-config [--vendor <vendor>] [--maker <maker>] [--region <geography>] [--force] [folder]`. */
|
|
105
|
+
export declare function main(args: string[]): Promise<number>;
|
|
106
|
+
export {};
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The jellyfish turri is named after, in pixels: a pink bell, an orange gut, neon tentacles coming apart into code at
|
|
3
|
+
* their tips - the design system's colours, swimming a stroke a loop. Drawn at two sizes from one design: the banner's
|
|
4
|
+
* pictures are rendered from the large one (scripts/jellyfish-frames.mjs writes assets/jellyfish/), and where a terminal
|
|
5
|
+
* shows no images the small one is drawn here in half blocks, two pixels a cell - drawn at its size, not shrunk, so no
|
|
6
|
+
* pixel of it is lost.
|
|
7
|
+
*/
|
|
8
|
+
/** What a pixel is: the bell, its glint and shine, the gut, the underside, a tentacle, an oral arm, a tip fading. */
|
|
9
|
+
type Pixel = "p" | "h" | "w" | "o" | "e" | "N" | "n" | "l" | "g";
|
|
10
|
+
/** The pixels' colours on a dark background and a light one - the tentacles darker on light, where neon does not show. */
|
|
11
|
+
export declare const JELLYFISH_COLOURS: Record<"dark" | "light", Record<Pixel, string>>;
|
|
12
|
+
export declare const JELLYFISH_WIDTH: number;
|
|
13
|
+
export declare const JELLYFISH_HEIGHT: number;
|
|
14
|
+
/** The large jellyfish's frames, a stroke: what the pictures are rendered from. */
|
|
15
|
+
export declare const JELLYFISH_FRAMES: string[][];
|
|
16
|
+
/** The small jellyfish's frames, a stroke: what a terminal without images draws, in half blocks. */
|
|
17
|
+
export declare const JELLYFISH_TEXT_FRAMES: string[][];
|
|
18
|
+
/** How long each frame shows. */
|
|
19
|
+
export declare const JELLYFISH_FRAME_MS = 250;
|
|
20
|
+
/**
|
|
21
|
+
* A frame drawn in half blocks for a terminal that shows no images: two pixels a cell, the upper one the text's colour
|
|
22
|
+
* and the lower one the background's, in as many colours as the terminal has: a column a pixel, a row every two.
|
|
23
|
+
*/
|
|
24
|
+
export declare function halfBlocks(pixels: string[], appearance: "dark" | "light", truecolor: boolean): string[];
|
|
25
|
+
export {};
|
package/dist/judge.d.ts
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { AgentSession } from "@earendil-works/pi-coding-agent";
|
|
2
|
+
import { type Verdict } from "./tools.ts";
|
|
3
|
+
import type { ReviewSpec } from "./skill.ts";
|
|
4
|
+
export interface JudgeResult {
|
|
5
|
+
index: number;
|
|
6
|
+
model: string;
|
|
7
|
+
verdict: Verdict | undefined;
|
|
8
|
+
}
|
|
9
|
+
export interface GateOutcome {
|
|
10
|
+
passed: boolean;
|
|
11
|
+
results: JudgeResult[];
|
|
12
|
+
/** Feedback handed back to the executor on retry. Empty when the gate passed. */
|
|
13
|
+
critique: string;
|
|
14
|
+
}
|
|
15
|
+
export declare function runGate(opts: {
|
|
16
|
+
cwd: string;
|
|
17
|
+
review: ReviewSpec;
|
|
18
|
+
rubric: string;
|
|
19
|
+
artifactPath: string;
|
|
20
|
+
artifact: string;
|
|
21
|
+
executor: AgentSession;
|
|
22
|
+
/** Used when the gate does not name a model - normally the conversation's. */
|
|
23
|
+
defaultModel?: string;
|
|
24
|
+
onJudgeStart?: (index: number, model: string) => void;
|
|
25
|
+
}): Promise<GateOutcome>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { type DriftReport, type ModuleStatus, type WorkLoop } from "./regenerate/loop.ts";
|
|
2
|
+
import { type ModuleState } from "./run-report.ts";
|
|
3
|
+
/**
|
|
4
|
+
* What every command that builds - `turri regenerate`, `conform`, `spec-diff` - does around its own
|
|
5
|
+
* request of the work loop, as the chat does it: the project's models, a job that fails run once more and, failing again,
|
|
6
|
+
* diagnosed, a line as each job starts and ends; then the loop run until nothing more can start, how each job ended,
|
|
7
|
+
* and exit 1 when any failed or a module is not complete. With `dryRun`, the work is planned and the prompt of the first job each codebase would
|
|
8
|
+
* start printed, and nothing runs.
|
|
9
|
+
*/
|
|
10
|
+
export declare function runLoop(options: {
|
|
11
|
+
plainFile: string;
|
|
12
|
+
/** Where the code is exported to as the run ends, however it ends: the furthest-built codebase's last commit. */
|
|
13
|
+
buildDir?: string;
|
|
14
|
+
/** The run report's file (`--report`): see run-report.ts. */
|
|
15
|
+
report?: string;
|
|
16
|
+
/** The command, as the report gives it: its name and its arguments. */
|
|
17
|
+
command?: string[];
|
|
18
|
+
dryRun?: boolean;
|
|
19
|
+
/** Start over, unasked, a codebase that has to be on a module it now requires (`--start-over`). */
|
|
20
|
+
startOver?: boolean;
|
|
21
|
+
/** The request: bring up, regenerate, conformance. */
|
|
22
|
+
ask: (loop: WorkLoop) => Promise<ModuleStatus[]>;
|
|
23
|
+
}): Promise<never>;
|
|
24
|
+
/** How each codebase stands, from what is left to regenerate there. */
|
|
25
|
+
export declare function moduleStates(reports: DriftReport[]): ModuleState[];
|
|
26
|
+
/**
|
|
27
|
+
* The options every command that regenerates takes for a headless run: `--report` and `--build-dir`, and the config's
|
|
28
|
+
* own keys (configKeyOptions) - `--harness-model`, `--coding-model` (`--model`), `--judge-model`, `--review`, `--mutation-testing` and, where
|
|
29
|
+
* `conformance` is true, `--conformance-tests` - read as if config.turri.yaml had them. Exits on a value it cannot read.
|
|
30
|
+
*/
|
|
31
|
+
export declare function headlessOptions(options: Record<string, string | undefined>, conformance: boolean): {
|
|
32
|
+
report?: string;
|
|
33
|
+
buildDir?: string;
|
|
34
|
+
};
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import { type ExtensionContext, type ToolDefinition } from "@earendil-works/pi-coding-agent";
|
|
2
|
+
import { Type } from "typebox";
|
|
3
|
+
import { type ModuleStatus, type WorkLoop } from "./regenerate/loop.ts";
|
|
4
|
+
import type { RenderWork } from "./regenerate/engine.ts";
|
|
5
|
+
import { type JobRegistry } from "./regenerate/jobs.ts";
|
|
6
|
+
/**
|
|
7
|
+
* The tools that act on the work loop - `regenerate`, `drift` and `halt` - defined once, for the conversation and for the
|
|
8
|
+
* skills alike: a skill that regenerates what a spec holds, or reads how far it is regenerated, uses the conversation's
|
|
9
|
+
* own tools, on the conversation's loop, never copies of them.
|
|
10
|
+
*/
|
|
11
|
+
type AnyTool = ToolDefinition<any, any, any>;
|
|
12
|
+
/** How the queue is to be planned, for the work this call queues - see regenerate/steer.ts. */
|
|
13
|
+
export declare const GUIDANCE_PARAM: Type.TOptional<Type.TString>;
|
|
14
|
+
export declare const WORKING_DIR_PARAM: Type.TOptional<Type.TString>;
|
|
15
|
+
export declare const MODEL_PARAM: Type.TOptional<Type.TString>;
|
|
16
|
+
export declare const STACK_PARAM: Type.TOptional<Type.TString>;
|
|
17
|
+
/**
|
|
18
|
+
* Why a module asked for with no stack named cannot be built: a project of stacks where it has no stack of its own and
|
|
19
|
+
* none is chosen, and config.turri.yaml alone names no unit testing script - every pulse would stop for want of one.
|
|
20
|
+
* The stacks and the script each names, and what to do. Undefined when it can be built.
|
|
21
|
+
*/
|
|
22
|
+
export declare function stacklessBuild(plainFile: string): string | undefined;
|
|
23
|
+
/**
|
|
24
|
+
* `work` with the stack a call names chosen for it - or, none named, as it is: each module is then built with its own
|
|
25
|
+
* (`stackForModule`). A module that could not be built that way is refused before anything is planned (`stacklessBuild`).
|
|
26
|
+
*/
|
|
27
|
+
export declare function withCallStack<T>(plainFile: string, named: string | undefined, work: () => T): T;
|
|
28
|
+
export declare const WAIT_PARAM: Type.TOptional<Type.TBoolean>;
|
|
29
|
+
/**
|
|
30
|
+
* A render tool's arguments as if turri had been started in `working_dir`: the .plain file
|
|
31
|
+
* and the build folder made absolute from there, and that folder as `base`.
|
|
32
|
+
*/
|
|
33
|
+
export declare function fromWorkingDir<T extends {
|
|
34
|
+
working_dir?: string;
|
|
35
|
+
plain_file?: string;
|
|
36
|
+
build_dir?: string;
|
|
37
|
+
}>(cwd: string, params: T): T & {
|
|
38
|
+
base: string;
|
|
39
|
+
};
|
|
40
|
+
/** What the loop is doing for a spec's modules, for the conversation - and, waiting, how each module ended. */
|
|
41
|
+
export declare function loopReply(loop: WorkLoop, statuses: ModuleStatus[], wait: boolean): Promise<{
|
|
42
|
+
content: {
|
|
43
|
+
type: "text";
|
|
44
|
+
text: string;
|
|
45
|
+
}[];
|
|
46
|
+
details: {
|
|
47
|
+
jobIds: string[];
|
|
48
|
+
};
|
|
49
|
+
}>;
|
|
50
|
+
/** Halt a pulse by its id, or the start of it: what it was, and what moves up behind it. `reason`: why, kept with it. */
|
|
51
|
+
export declare function stopJob(jobs: JobRegistry, named: string, reason?: string, loop?: WorkLoop): string;
|
|
52
|
+
export interface LoopToolsOptions {
|
|
53
|
+
/** Where turri was started: the folder plain_file and working_dir are relative to. */
|
|
54
|
+
cwd: string;
|
|
55
|
+
/** The pulses `halt` stops. Without them - the release agent's - it stops only what activate started. */
|
|
56
|
+
jobs?: JobRegistry;
|
|
57
|
+
/** The work loop the tools act on - the conversation's, for a call in it. */
|
|
58
|
+
loop?: (ctx: ExtensionContext) => WorkLoop;
|
|
59
|
+
/** The model a pulse of this call regenerates on: the one named, or the one chosen for the work. Default: the one named. */
|
|
60
|
+
model?: (ctx: ExtensionContext, plainFile: string, named?: string, work?: RenderWork) => string | undefined;
|
|
61
|
+
/** Whether a call waits for its work to finish, given what it asked. Default: only when it asked to. */
|
|
62
|
+
wait?: (ctx: ExtensionContext, asked?: boolean) => boolean;
|
|
63
|
+
}
|
|
64
|
+
/** Whether a /regenerate's words ask for the module from scratch: its code deleted, and all of it regenerated again. */
|
|
65
|
+
export declare function asksFromScratch(words: string): boolean;
|
|
66
|
+
/** Whether a /regenerate asking for its module from scratch asks for its whole requires chain with it. */
|
|
67
|
+
export declare function asksWholeChain(words: string): boolean;
|
|
68
|
+
/** regenerate: regenerate a module's code up to its spec as it is now. */
|
|
69
|
+
export declare function regenerateTool(options: LoopToolsOptions & {
|
|
70
|
+
loop: (ctx: ExtensionContext) => WorkLoop;
|
|
71
|
+
}): AnyTool;
|
|
72
|
+
/** drift: what is left to regenerate - planning nothing, starting nothing. */
|
|
73
|
+
export declare function driftTool(options: LoopToolsOptions & {
|
|
74
|
+
loop: (ctx: ExtensionContext) => WorkLoop;
|
|
75
|
+
}): AnyTool;
|
|
76
|
+
/** halt: stop a pulse, or what activate started. */
|
|
77
|
+
export declare function haltTool(options: Pick<LoopToolsOptions, "jobs"> & {
|
|
78
|
+
workLoop?: () => WorkLoop | undefined;
|
|
79
|
+
}): AnyTool;
|
|
80
|
+
export {};
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { type ToolDefinition } from "@earendil-works/pi-coding-agent";
|
|
2
|
+
import { type Job, type JobRegistry } from "./regenerate/jobs.ts";
|
|
3
|
+
/**
|
|
4
|
+
* The tools a skill that matures a spec works with, besides the conversation's regenerate, drift and halt: wait for
|
|
5
|
+
* the builds, and read back where the spec left the agents to decide.
|
|
6
|
+
*
|
|
7
|
+
* A render that passes can still have been built on a guess: where the spec is silent, the agent
|
|
8
|
+
* decides, and says so in the working notes' assumptions. Those, the pitfalls, a failed job's
|
|
9
|
+
* diagnosis and a spec that contradicts itself are what the spec should have said - and a skill
|
|
10
|
+
* reading them can write it in, so the next build does not have to guess.
|
|
11
|
+
*/
|
|
12
|
+
type AnyTool = ToolDefinition<any, any, any>;
|
|
13
|
+
/** What a maturing skill found: where it came from, and what it says. */
|
|
14
|
+
export interface SpecFinding {
|
|
15
|
+
id: string;
|
|
16
|
+
kind: "assumption" | "pitfall" | "diagnosis" | "conflict";
|
|
17
|
+
/** The module whose codebase it came from, or the job it came from. */
|
|
18
|
+
where: string;
|
|
19
|
+
text: string;
|
|
20
|
+
}
|
|
21
|
+
/** A time as the notes stamp their lines: "2026-09-28 17:40". */
|
|
22
|
+
export declare function noteStamp(date: Date): string;
|
|
23
|
+
/**
|
|
24
|
+
* What the agents and the harness recorded since `since`: the assumptions and pitfalls in every
|
|
25
|
+
* codebase's working notes, the diagnosis of every job that failed for good, and every spec that
|
|
26
|
+
* contradicts itself.
|
|
27
|
+
*/
|
|
28
|
+
export declare function collectFindings(options: {
|
|
29
|
+
project: string;
|
|
30
|
+
jobs: Job[];
|
|
31
|
+
since: Date;
|
|
32
|
+
}): Omit<SpecFinding, "id">[];
|
|
33
|
+
/** Why a build is struggling: a key for what kind of struggle it is - handed out once each - and what it says. */
|
|
34
|
+
export interface Struggle {
|
|
35
|
+
key: string;
|
|
36
|
+
why: string;
|
|
37
|
+
}
|
|
38
|
+
/** How long a build may run before it counts as struggling on its length alone. */
|
|
39
|
+
export declare const LONG_BUILD_MS: number;
|
|
40
|
+
/**
|
|
41
|
+
* Whether a running build is struggling, and how: sent back four times or more in one loop, five
|
|
42
|
+
* setbacks or more, a spec conflict raised, a failure being run again, or running far longer than a
|
|
43
|
+
* build should. Each kind comes once per build - a round count again only every four rounds more.
|
|
44
|
+
*/
|
|
45
|
+
export declare function struggling(job: Job, now?: number): Struggle | undefined;
|
|
46
|
+
export declare function createMatureTools(options: {
|
|
47
|
+
jobs: JobRegistry;
|
|
48
|
+
cwd: string;
|
|
49
|
+
startedAt?: Date;
|
|
50
|
+
}): AnyTool[];
|
|
51
|
+
/** The names of the maturing tools, as a skill's allowed-tools names them: its own - it regenerates, halts and reads drift with the conversation's (loop-tools.ts). */
|
|
52
|
+
export declare const MATURE_TOOLS: string[];
|
|
53
|
+
export {};
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { type ProjectConfig } from "./config.ts";
|
|
2
|
+
/**
|
|
3
|
+
* Whether the models a project's config names answer, with the credentials this machine has - for any provider pi
|
|
4
|
+
* supports. Each model the config uses (harness-model, coding-model, judge-model and every role under models:) is sent
|
|
5
|
+
* one short request through pi's own model runtime, the one turri's agents use, so the credentials are found as they
|
|
6
|
+
* will be when it builds: an API key in the environment, pi's /login, an AWS profile. A model pi does not know, a key
|
|
7
|
+
* it rejects, an account without access to the model - each is said, with what to do about it.
|
|
8
|
+
*/
|
|
9
|
+
/** A model the config uses, and which of its settings name it. */
|
|
10
|
+
export interface UsedModel {
|
|
11
|
+
spec: string;
|
|
12
|
+
usedBy: string[];
|
|
13
|
+
}
|
|
14
|
+
/** Every model the config uses, each once, with the settings that name it - the two models first. */
|
|
15
|
+
export declare function modelsInUse(config: Pick<ProjectConfig, "harnessModel" | "codingModel" | "judgeModel" | "models">): UsedModel[];
|
|
16
|
+
export type ModelVerdict = {
|
|
17
|
+
ok: true;
|
|
18
|
+
spec: string;
|
|
19
|
+
usedBy: string[];
|
|
20
|
+
ms: number;
|
|
21
|
+
} | {
|
|
22
|
+
ok: false;
|
|
23
|
+
spec: string;
|
|
24
|
+
usedBy: string[];
|
|
25
|
+
problem: string;
|
|
26
|
+
fix: string;
|
|
27
|
+
};
|
|
28
|
+
/** What it takes to talk to a model: pi's runtime, or a stand-in for tests. */
|
|
29
|
+
export interface ModelAccess {
|
|
30
|
+
/** The model, as pi knows it - undefined when it does not. */
|
|
31
|
+
find(provider: string, id: string): unknown;
|
|
32
|
+
/** Other models of the provider pi knows, to suggest from. */
|
|
33
|
+
known(provider: string): string[];
|
|
34
|
+
/** One short request: the error the provider gave, or nothing when it answered. */
|
|
35
|
+
ask(model: unknown): Promise<string | undefined>;
|
|
36
|
+
}
|
|
37
|
+
/** pi's own model runtime, with pi's credentials - auth.json, models.json and the environment - as turri's agents have them. */
|
|
38
|
+
export declare function piModelAccess(): Promise<ModelAccess>;
|
|
39
|
+
/** What to do about a provider's error, from what it says. */
|
|
40
|
+
export declare function fixFor(provider: string, problem: string): string;
|
|
41
|
+
/** Each model the config uses, tried: answered, or what is wrong and what to do. One request a model. */
|
|
42
|
+
export declare function checkModels(models: UsedModel[], access: ModelAccess): Promise<ModelVerdict[]>;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/** Colours for what the command line prints. */
|
|
2
|
+
export declare const c: {
|
|
3
|
+
dim: (s: string) => string;
|
|
4
|
+
bold: (s: string) => string;
|
|
5
|
+
success: (text: string) => string;
|
|
6
|
+
error: (text: string) => string;
|
|
7
|
+
warning: (text: string) => string;
|
|
8
|
+
accent: (text: string) => string;
|
|
9
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import "./terminal-images.ts";
|