@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.
- package/.pi/themes/turri-dark.json +1 -1
- package/README.md +1 -1
- 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 +36 -10
- package/dist/genome.d.ts +62 -0
- package/dist/graph.d.ts +52 -0
- package/dist/host.d.ts +20 -0
- package/dist/host.js +23 -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 +51 -0
- package/docs/installation.md +1 -1
- package/docs/theming.md +2 -2
- package/package.json +8 -1
package/README.md
CHANGED
|
@@ -190,7 +190,7 @@ Start at the [documentation index](docs/README.md), or go straight to a page:
|
|
|
190
190
|
| | |
|
|
191
191
|
| --- | --- |
|
|
192
192
|
| [Installation](docs/installation.md) | doctor, what turri needs of this machine, **turri** and `pi`, environment variables |
|
|
193
|
-
| [Examples](examples/README.md) | projects to build with turri step by step: cognio from an empty folder, a CLI, a backend service with conformance tests, a REST API integration |
|
|
193
|
+
| [Examples](examples/README.md) | projects to build with turri step by step: cognio from an empty folder, guestbook - a backend and a frontend in minutes - a CLI, a backend service with conformance tests, a REST API integration |
|
|
194
194
|
| [Using **turri**](docs/using.md) | the conversation, skills, tools, pulses and regen, choosing models, the command line |
|
|
195
195
|
| [The project config](docs/config.md) | `config.turri.yaml` and each stack's `config.turri.<stack>.yaml`: every key, models and their inheritance, conformance, the testing scripts, stacks and choosing one, the old `config.yaml` |
|
|
196
196
|
| [Deploy](docs/deploy.md) | trying what is built: the last commit in `dist/<module>`, started on your machine, nothing installed without asking |
|
package/dist/ask.d.ts
ADDED
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* How a skill step puts a question to the person running it.
|
|
3
|
+
*
|
|
4
|
+
* The interaction policy lives here rather than in the extension so it is the same from
|
|
5
|
+
* the TUI and the CLI, and so it can be tested without a terminal.
|
|
6
|
+
*/
|
|
7
|
+
export interface AskUserRequest {
|
|
8
|
+
question: string;
|
|
9
|
+
/** Concrete choices. Selecting beats typing whenever the answer space is known. */
|
|
10
|
+
options?: string[];
|
|
11
|
+
/** Let the user pick several: each option a box to tick and untick. Their picks come back comma-separated. */
|
|
12
|
+
multiSelect?: boolean;
|
|
13
|
+
/** Deliberately asking without options, for a genuinely open question. */
|
|
14
|
+
freeForm?: boolean;
|
|
15
|
+
/**
|
|
16
|
+
* What the person must read to answer - the brief to confirm, the plan to approve - shown above the question, as the
|
|
17
|
+
* asker gives it. A skill's agent talks in a session of its own that nobody sees, so without it "Is this the right
|
|
18
|
+
* brief?" arrives with no brief.
|
|
19
|
+
*/
|
|
20
|
+
context?: string;
|
|
21
|
+
/**
|
|
22
|
+
* What the asker said last before asking - its account of the work, a probe, a regeneration - kept with the answer in the
|
|
23
|
+
* run's record and the transcript, never shown in the dialog.
|
|
24
|
+
*/
|
|
25
|
+
said?: string;
|
|
26
|
+
/**
|
|
27
|
+
* Offer "Chat about this": an agent asked, and can answer what the person says about the question before they answer
|
|
28
|
+
* it. Not for a question the harness asks itself - nobody would answer.
|
|
29
|
+
*/
|
|
30
|
+
chattable?: boolean;
|
|
31
|
+
}
|
|
32
|
+
export type AskUser = (request: AskUserRequest) => Promise<string>;
|
|
33
|
+
/**
|
|
34
|
+
* The two dialogs an implementation has to provide. `context` is what to read to answer, given apart from the question so
|
|
35
|
+
* a dialog can show a long one without losing the question and its options under it - the TUI's scrolls it.
|
|
36
|
+
*/
|
|
37
|
+
export interface AskUserIO {
|
|
38
|
+
/** `at`: the option the cursor starts on - the one just ticked, in a question of several. */
|
|
39
|
+
select(title: string, options: string[], context?: string, at?: number): Promise<string | undefined>;
|
|
40
|
+
input(title: string, context?: string): Promise<string | undefined>;
|
|
41
|
+
}
|
|
42
|
+
export declare const OTHER_OPTION = "Something else\u2026";
|
|
43
|
+
export declare const CHAT_OPTION = "Chat about this";
|
|
44
|
+
export declare const DONE_OPTION = "Done \u2014 that's all of them";
|
|
45
|
+
/** An option's box in a question of several, ticked and not. */
|
|
46
|
+
export declare const TICKED = "\u2611";
|
|
47
|
+
export declare const UNTICKED = "\u2610";
|
|
48
|
+
export declare const DISMISSED = "The user dismissed the question without answering.";
|
|
49
|
+
/** How an answer that is no answer starts: the person chose to talk about the question first. */
|
|
50
|
+
export declare const CHAT_PREFIX = "The user has not answered this question yet: they chose to talk about it first.";
|
|
51
|
+
/** What comes back when the person chose "Chat about this": what they said, and what they had picked so far. */
|
|
52
|
+
export declare function chatAnswer(said: string, picked?: string[]): string;
|
|
53
|
+
/** Whether an answer is the person choosing to talk about the question, rather than answering it. */
|
|
54
|
+
export declare function isChat(answer: string): boolean;
|
|
55
|
+
/**
|
|
56
|
+
* A question with no options and no `free_form` is refused rather than asked.
|
|
57
|
+
*
|
|
58
|
+
* Offering choices is the thing that makes an interview quick to answer, and an optional
|
|
59
|
+
* field is one a model quietly skips. Making the free-form case explicit means asking
|
|
60
|
+
* without options is a decision rather than an omission.
|
|
61
|
+
*/
|
|
62
|
+
export declare function missingOptions(request: AskUserRequest): string | null;
|
|
63
|
+
/**
|
|
64
|
+
* The request as the person should see it: tool-call markup cut out of the question and the
|
|
65
|
+
* options - an option that was nothing but markup dropped - and a `multi_select` that leaked into
|
|
66
|
+
* the text taken as the argument it was meant to be. `leaked` when there was any.
|
|
67
|
+
*/
|
|
68
|
+
export declare function cleanRequest(request: AskUserRequest): {
|
|
69
|
+
request: AskUserRequest;
|
|
70
|
+
leaked: boolean;
|
|
71
|
+
};
|
|
72
|
+
export declare function runAsk(asked: AskUserRequest, io: AskUserIO): Promise<string>;
|
|
73
|
+
/**
|
|
74
|
+
* While a question is open, what catches ctrl+h on the terminal's input: pi gives an extension's shortcut only the keys
|
|
75
|
+
* its editor sees, and a question has the focus. It opens the side panel - the question waits under it - unless the
|
|
76
|
+
* panel shows already: its own listener has ctrl+h then, to close it. A key's release and its repeats are left alone.
|
|
77
|
+
*/
|
|
78
|
+
export declare function peekKeyListener(panel: {
|
|
79
|
+
open(): void;
|
|
80
|
+
shown(): boolean;
|
|
81
|
+
}): (data: string) => {
|
|
82
|
+
consume: true;
|
|
83
|
+
} | undefined;
|
package/dist/brand.d.ts
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export declare const brand: {
|
|
2
|
+
/** turri's accent: what to look at - a heading, a choice's number, the command to run. */
|
|
3
|
+
accent: (text: string) => string;
|
|
4
|
+
/** Done, and what was written. */
|
|
5
|
+
success: (text: string) => string;
|
|
6
|
+
/** What is wrong: what stops turri. */
|
|
7
|
+
error: (text: string) => string;
|
|
8
|
+
/** What works, with limits. */
|
|
9
|
+
warning: (text: string) => string;
|
|
10
|
+
/** What goes with it, and can be skimmed. */
|
|
11
|
+
muted: (text: string) => string;
|
|
12
|
+
bold: (text: string) => string;
|
|
13
|
+
};
|
package/dist/btw.d.ts
ADDED
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* /btw: a question on the side, answered while the conversation is busy - a skill's interview, its long steps - without
|
|
3
|
+
* waiting for it, and without changing it.
|
|
4
|
+
*
|
|
5
|
+
* A skill runs inside one tool call, so the chat model can answer nothing until the skill returns, and whatever the
|
|
6
|
+
* person types meanwhile waits for it as a message. pi runs an extension's command at once, even mid-turn: /btw starts
|
|
7
|
+
* an agent of its own - fresh, read only - that is shown the conversation, what the running skill has done and said so
|
|
8
|
+
* far, and what is regenerating, and answers. Its answer is shown and kept out of every model's context: the
|
|
9
|
+
* conversation and the skill go on as if nothing was asked. While a question of the skill's has the keys, the same is
|
|
10
|
+
* typed into its "Something else…" - answered, and the question asked again with the answer above it.
|
|
11
|
+
*/
|
|
12
|
+
import type { AskUser, AskUserRequest } from "./ask.ts";
|
|
13
|
+
/** How many tool calls the side agent may make before it is told to answer. */
|
|
14
|
+
export declare const SIDE_CALLS = 20;
|
|
15
|
+
/** "/btw what is a frid?" -> "what is a frid?"; "/btw" alone -> ""; anything else is not a side question. */
|
|
16
|
+
export declare function sideQuestionOf(text: string): string | undefined;
|
|
17
|
+
/** The skill running now, as the side agent is told of it. */
|
|
18
|
+
export interface SkillRunNow {
|
|
19
|
+
skill: string;
|
|
20
|
+
/** Its folder: turri's own, or the project's. */
|
|
21
|
+
dir: string;
|
|
22
|
+
/** The step it is in, and its attempt - "" before the first. */
|
|
23
|
+
step(): string;
|
|
24
|
+
/** Its trace so far: steps, gates, each question and answer. */
|
|
25
|
+
trace(): string[];
|
|
26
|
+
/** Its run folder: run.json there names the agent's saved session. */
|
|
27
|
+
runDir: string;
|
|
28
|
+
}
|
|
29
|
+
/** Says a skill is running, until the function it returns is called. */
|
|
30
|
+
export declare function skillRunStarted(run: SkillRunNow): () => void;
|
|
31
|
+
export declare function runningSkill(): SkillRunNow | undefined;
|
|
32
|
+
/**
|
|
33
|
+
* A session's messages as plain text - who said what, tool calls named - its last `maxChars`. Thinking and tool
|
|
34
|
+
* results are left out: what was said, and what was done, is what a side question is about.
|
|
35
|
+
*/
|
|
36
|
+
export declare function transcriptOf(entries: unknown[], maxChars: number): string;
|
|
37
|
+
/** The running skill's agent's session, as text: its last turns, read from the session file run.json names. */
|
|
38
|
+
export declare function skillSessionText(runDir: string, maxChars?: number): string;
|
|
39
|
+
export interface SideQuestion {
|
|
40
|
+
question: string;
|
|
41
|
+
/** The conversation so far, as text. */
|
|
42
|
+
conversation: string;
|
|
43
|
+
/** The skill running now, if one is. */
|
|
44
|
+
skill?: {
|
|
45
|
+
name: string;
|
|
46
|
+
dir: string;
|
|
47
|
+
step: string;
|
|
48
|
+
trace: string[];
|
|
49
|
+
session: string;
|
|
50
|
+
};
|
|
51
|
+
/** What is regenerating and has been regenerated this session, a line a pulse. */
|
|
52
|
+
pulses: string[];
|
|
53
|
+
projectDir: string;
|
|
54
|
+
/** turri's own folder: its source, skills, rules and docs. */
|
|
55
|
+
harnessDir: string;
|
|
56
|
+
}
|
|
57
|
+
export declare function sideQuestionPrompt(side: SideQuestion): string;
|
|
58
|
+
/** Answers a side question with an agent of its own, read only, on `model`. */
|
|
59
|
+
export declare function answerSideQuestion(side: SideQuestion, model?: string): Promise<string>;
|
|
60
|
+
/** The answer to a side question, as it is shown above the question it was asked under. */
|
|
61
|
+
export declare function asideBlock(question: string, answer: string): string;
|
|
62
|
+
export declare const BTW_HOW = "Type your question after /btw - /btw what does this step do?";
|
|
63
|
+
/**
|
|
64
|
+
* A question put to the person, where "/btw ..." typed as the answer is a side question: answered, and the same
|
|
65
|
+
* question asked again with the answer above it - the asker never sees it. Only the latest is kept above the question.
|
|
66
|
+
*/
|
|
67
|
+
export declare function askWithAsides(request: AskUserRequest, askUser: AskUser, aside: (question: string) => Promise<string>): Promise<string>;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { type ProjectConfig } from "./config.ts";
|
|
2
|
+
/**
|
|
3
|
+
* The two models of `turri`, from its arguments and the project's config.turri.yaml.
|
|
4
|
+
*
|
|
5
|
+
* The harness model is the one the person talks to: pi's own `--model`, which `--harness-model`
|
|
6
|
+
* is another name for, or else `harness-model:` in config.turri.yaml. The coding model is the one
|
|
7
|
+
* every render runs on: `--coding-model`, or else `coding-model:` in config.turri.yaml - pi knows
|
|
8
|
+
* nothing of it, so it reaches the extension through the environment. Either can still be
|
|
9
|
+
* changed in the conversation: pi's /model, engine.
|
|
10
|
+
*/
|
|
11
|
+
/** The environment variable a chat's --coding-model reaches the extension through. */
|
|
12
|
+
export declare const CODING_MODEL_ENV = "TURRI_CODING_MODEL";
|
|
13
|
+
/** Take a `--name value` or `--name=value` out of the arguments: its value, and the rest. The last one wins. */
|
|
14
|
+
export declare function takeOption(args: string[], name: string): {
|
|
15
|
+
value?: string;
|
|
16
|
+
rest: string[];
|
|
17
|
+
};
|
|
18
|
+
/** pi's arguments, with the harness model in them, and the coding model for the extension. */
|
|
19
|
+
export declare function chatModels(args: string[], config: Pick<ProjectConfig, "harnessModel" | "codingModel" | "judgeModel">): {
|
|
20
|
+
piArgs: string[];
|
|
21
|
+
codingModel?: string;
|
|
22
|
+
};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The pi skills the conversation is not offered, because turri has them already.
|
|
3
|
+
*
|
|
4
|
+
* pi lists for the conversation every skill it finds: `~/.pi/agent/skills`, `~/.agents/skills`, and the `.agents/skills`
|
|
5
|
+
* of every folder from the one turri started in up to its git root - so a folder above a project can hand the chat
|
|
6
|
+
* another tool's ***plain skills, a `load-plain-reference` it then loads at the start of a session. turri needs none of
|
|
7
|
+
* them: the whole ***plain reference - the authoring rules - is in the conversation's system prompt already, and turri
|
|
8
|
+
* runs its own skills, and the project's, with `cultivate`, steps and gates and all. A skill the chat followed by hand
|
|
9
|
+
* instead would skip those gates, and one from another tool may say otherwise than turri's rules. So the conversation
|
|
10
|
+
* is offered neither: no skill turri runs itself, and none about ***plain. A skill about anything else - a commit
|
|
11
|
+
* message, a deploy - is offered as pi offers it.
|
|
12
|
+
*/
|
|
13
|
+
/** Whether turri has what a pi skill offers: it runs a skill of that name itself, or the skill is about ***plain. */
|
|
14
|
+
export declare function supersededByTurri(skill: {
|
|
15
|
+
name: string;
|
|
16
|
+
description: string;
|
|
17
|
+
}, turriRuns: ReadonlySet<string>): boolean;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The command line of turri's commands: their words, and the options that stand for the config's own keys - kept apart
|
|
3
|
+
* from the commands that use them, so a light one (doctor) reads them as a regenerate does without loading it.
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* A command's arguments: the positional ones, `--flag`s and `--name value` options (`--name=value` too) -
|
|
7
|
+
* `--coding-model` is `--model`. An option it does not take is refused, rather than taking the word after it, and so is an
|
|
8
|
+
* option with no value - the end of the words, or another option where its value should be.
|
|
9
|
+
*/
|
|
10
|
+
export declare function parseArgs(argv: string[], flags: string[], usage: string, valued?: string[]): {
|
|
11
|
+
positional: string[];
|
|
12
|
+
options: Record<string, string | undefined>;
|
|
13
|
+
};
|
|
14
|
+
/** An option's value, as parseArgs left it: refused when it was given with none. */
|
|
15
|
+
export declare function optionValue(options: Record<string, string | undefined>, name: string): string | undefined;
|
|
16
|
+
/**
|
|
17
|
+
* The options that stand for the config's own keys - `--harness-model`, `--coding-model` (`--model`), `--judge-model`
|
|
18
|
+
* and, as asked, `--review`, `--mutation-testing` and `--conformance-tests` - read as if config.turri.yaml had them, in their place in the
|
|
19
|
+
* order the config resolves them in (overrideConfig): a run, or doctor, with them is the same as one with them in the
|
|
20
|
+
* file. Exits on a value it cannot read.
|
|
21
|
+
*/
|
|
22
|
+
export declare function configKeyOptions(options: Record<string, string | undefined>, take?: {
|
|
23
|
+
conformance?: boolean;
|
|
24
|
+
review?: boolean;
|
|
25
|
+
}): void;
|
package/dist/cli.d.ts
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* One entry point, so the tools can be used from wherever the specification lives.
|
|
4
|
+
*
|
|
5
|
+
* Paths are resolved against the current working directory, and a .plain file's linked
|
|
6
|
+
* resources are too - so the intended use is to `cd` to the module and name the file,
|
|
7
|
+
* rather than to run from this repo and reach across with absolute paths.
|
|
8
|
+
*/
|
|
9
|
+
export {};
|
package/dist/cli.js
CHANGED
|
@@ -19,7 +19,7 @@ import { dirname, join } from "node:path";
|
|
|
19
19
|
import { fileURLToPath } from "node:url";
|
|
20
20
|
import { CODING_MODEL_ENV, chatModels } from "./chat-models.js";
|
|
21
21
|
import { readProjectConfig } from "./config.js";
|
|
22
|
-
import { extensionInstalledGlobally, PACKAGE_ROOT, themesInstalledGlobally } from "./environment.js";
|
|
22
|
+
import { extensionInstalledGlobally, PACKAGE_ROOT, themesInstalledGlobally, versionLine } from "./environment.js";
|
|
23
23
|
import { dropNoise } from "./quiet.js";
|
|
24
24
|
/**
|
|
25
25
|
* Start pi with this project's extension and themes already wired in.
|
|
@@ -92,6 +92,7 @@ const SETUP_COMMANDS = {
|
|
|
92
92
|
const USAGE = [
|
|
93
93
|
"usage: turri [options] open the conversation here: pi, with turri's tools and themes loaded",
|
|
94
94
|
" turri <command> [args]",
|
|
95
|
+
" turri --version turri's version, and pi's",
|
|
95
96
|
"",
|
|
96
97
|
` ${"options".padEnd(12)} --harness-model <m> the model you chat with --coding-model <m> the model renders run on`,
|
|
97
98
|
` ${"".padEnd(12)} --stack <name> build with config.turri.<name>.yaml over config.turri.yaml - here and in every command`,
|
|
@@ -139,6 +140,11 @@ if (command === "-h" || command === "--help") {
|
|
|
139
140
|
console.log(USAGE);
|
|
140
141
|
process.exit(0);
|
|
141
142
|
}
|
|
143
|
+
// turri's version, not pi's alone: pi's --version would answer for it.
|
|
144
|
+
if (command === "-v" || command === "--version") {
|
|
145
|
+
console.log(versionLine());
|
|
146
|
+
process.exit(0);
|
|
147
|
+
}
|
|
142
148
|
// turri alone is the conversation, and so is turri with pi's options - `turri -c`, `turri --harness-model <m>`. A word
|
|
143
149
|
// turri does not know is an error below, not a conversation started on it.
|
|
144
150
|
if (command === undefined || command.startsWith("-"))
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { ExtensionAPI, ExtensionContext } from "@earendil-works/pi-coding-agent";
|
|
2
|
+
/**
|
|
3
|
+
* `/turri-config`: every setting of the project's config.turri.yaml from the chat - `/turri-config` alone lists them,
|
|
4
|
+
* `/turri-config review` asks for review's value, `/turri-config review false` sets it. Each is written into the file
|
|
5
|
+
* and takes effect as it says - now, at your next message, at the next pulse - never only once turri starts again:
|
|
6
|
+
* what turri fixes at its start is changed live here (live).
|
|
7
|
+
*/
|
|
8
|
+
/** What a change does to turri as it runs, beside the file: each says what it did, or nothing. */
|
|
9
|
+
export interface LiveHooks {
|
|
10
|
+
/** The chat's model is now this - provider/id:thinking - or, undefined, no longer set in the file. */
|
|
11
|
+
chatModel(spec: string | undefined, ctx: ExtensionContext): Promise<string | undefined>;
|
|
12
|
+
/** The coding model changed in the file: one chosen this session - --coding-model, engine - gives way to it. */
|
|
13
|
+
codingModel(): string | undefined;
|
|
14
|
+
/** How many pulses run at once: the number, or the machine's default. */
|
|
15
|
+
parallelJobs(count: number | undefined): string | undefined;
|
|
16
|
+
}
|
|
17
|
+
export interface TurriConfigOptions {
|
|
18
|
+
/** The folder whose config.turri.yaml the chat reads. */
|
|
19
|
+
cwd: string;
|
|
20
|
+
/** The ***plain rules there are, by name - what rules-off takes. */
|
|
21
|
+
rules: () => string[];
|
|
22
|
+
/** The chat's model, provider/id:thinking, after a change - read as the file has it now. */
|
|
23
|
+
chatSpec: () => string | undefined;
|
|
24
|
+
live: LiveHooks;
|
|
25
|
+
}
|
|
26
|
+
export declare function registerTurriConfig(pi: ExtensionAPI, options: TurriConfigOptions): void;
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `/turri-config`'s side of config.turri.yaml: every setting turri reads, what it takes - a yes or no, one of a few words, a
|
|
3
|
+
* number, a model, a list - and when a change to it takes effect, so the person knows whether to wait for the next
|
|
4
|
+
* pulse or not at all. A change is written into the file line by line, its comments and the commented-out examples
|
|
5
|
+
* kept; `models:` and `agent-env:`, which nest, are written again whole, their own comments lost.
|
|
6
|
+
*/
|
|
7
|
+
/** When a change takes effect. Nothing turri reads needs a restart: what is fixed at its start is changed live. */
|
|
8
|
+
export type Effect = "now" | "next-message" | "next-pulse" | "next-plan" | "next-test-run" | "next-landing" | "next-regenerate";
|
|
9
|
+
export type SettingKind = "boolean" | "choice" | "number" | "model" | "list" | "path" | "budget";
|
|
10
|
+
export interface Setting {
|
|
11
|
+
/** As written in the file - a nested one by its path: `models.coding`, `models.coding.turn-limit`, `agent-env.files`. */
|
|
12
|
+
key: string;
|
|
13
|
+
/** What it does, in a line. */
|
|
14
|
+
about: string;
|
|
15
|
+
kind: SettingKind;
|
|
16
|
+
/** What it is when it is not set. */
|
|
17
|
+
unset: string;
|
|
18
|
+
effect: Effect;
|
|
19
|
+
/** The words it takes (choice), or the values offered first (number, budget, list). */
|
|
20
|
+
options?: string[];
|
|
21
|
+
/** The least a number may be. */
|
|
22
|
+
min?: number;
|
|
23
|
+
/** Set in the project's config.turri.yaml only: a stack's file does not change it. */
|
|
24
|
+
projectOnly?: boolean;
|
|
25
|
+
}
|
|
26
|
+
/** What each effect is, said to the person. */
|
|
27
|
+
export declare const EFFECT_TEXT: Record<Effect, string>;
|
|
28
|
+
/** Every setting, in the order the list shows them. */
|
|
29
|
+
export declare function settings(rules?: string[]): Setting[];
|
|
30
|
+
/** A setting by its key - `review`, `models.coding` - or nothing. */
|
|
31
|
+
export declare function settingOf(key: string, rules?: string[]): Setting | undefined;
|
|
32
|
+
/** A value read from what was typed: what to write, or that it is to be unset, or why it cannot be. */
|
|
33
|
+
export type Parsed = {
|
|
34
|
+
value: unknown;
|
|
35
|
+
} | {
|
|
36
|
+
unset: true;
|
|
37
|
+
} | {
|
|
38
|
+
error: string;
|
|
39
|
+
};
|
|
40
|
+
/**
|
|
41
|
+
* What was typed for a setting, read as the file takes it: `true`/`false`, one of its words, a number at least its least,
|
|
42
|
+
* a model `provider/id` with an optional `:thinking`, a list by commas. `known`: whether a model can be reached here -
|
|
43
|
+
* when it is given, one that cannot is refused.
|
|
44
|
+
*/
|
|
45
|
+
export declare function parseValue(setting: Setting, typed: string, known?: (model: string) => boolean): Parsed;
|
|
46
|
+
/** The file with a top-level key set to a value as it is - a block, such as `models:`, written whole - in its line, or under its commented-out example. */
|
|
47
|
+
export declare function withTopLevelValue(text: string, key: string, value: unknown): string;
|
|
48
|
+
/**
|
|
49
|
+
* The file with a setting set to a value, or unset (`undefined`). A top-level one is changed in its line; one under
|
|
50
|
+
* `models:` or `agent-env:` has that block written again whole.
|
|
51
|
+
*/
|
|
52
|
+
export declare function withSetting(text: string, key: string, value: unknown): string;
|
|
53
|
+
/** A setting's value as the file has it - the raw value, before turri reads it - or undefined when it is not set. */
|
|
54
|
+
export declare function currentValue(text: string, key: string): unknown;
|
|
55
|
+
/** A value for showing: `true`, `anthropic/claude-opus-5-5:low`, `[.env, .env.local]`. */
|
|
56
|
+
export declare function shownValue(value: unknown): string;
|
|
57
|
+
/** The project's config.turri.yaml - or the config.yaml it is read from until it has one - its text, empty when there is neither. */
|
|
58
|
+
export declare function readConfigText(dir: string): string;
|
|
59
|
+
/** What a change does beside setting the value: the files and settings that win over it, said to the person. */
|
|
60
|
+
export declare function overriddenBy(dir: string, text: string, setting: Setting): string[];
|
|
61
|
+
/**
|
|
62
|
+
* Write a setting into the project's config.turri.yaml - made when it is not there, from config.yaml and each stack's
|
|
63
|
+
* file in the old naming when they are what the project is read from - and give back the file as written.
|
|
64
|
+
*/
|
|
65
|
+
export declare function writeSetting(dir: string, key: string, value: unknown): string;
|
|
66
|
+
/** The files a path setting is offered: the testing scripts in the root and test_scripts/, or the .plain files of the folder. */
|
|
67
|
+
export declare function pathOptions(dir: string, key: string): string[];
|
|
68
|
+
/** The dotenv files of the project root, for agent-env.files. */
|
|
69
|
+
export declare function dotenvFiles(dir: string): string[];
|