@turri-dev/cli 0.1.4-next.318a98a → 0.1.4-next.5a8c6e5
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 +67 -66
- package/.pi/themes/turri-light.json +71 -73
- package/README.md +40 -128
- 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/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/dist/ask.js +34 -15
- package/dist/brand.js +7 -7
- package/dist/cli-options.js +12 -6
- package/dist/config-edit.js +1 -0
- package/dist/config.js +5 -2
- package/dist/cultivate-cli.js +16 -23
- package/dist/extension.js +59 -67
- package/dist/init-config.js +5 -0
- package/dist/jellyfish.js +130 -0
- package/dist/loop-cli.js +19 -7
- package/dist/loop-tools.js +11 -5
- package/dist/module-report.js +5 -4
- package/dist/pi.js +76 -19
- package/dist/question-dialog.js +1 -0
- package/dist/regenerate/activity.js +21 -0
- package/dist/regenerate/list-arguments.js +121 -0
- package/dist/regenerate/loop.js +21 -8
- package/dist/regenerate/plain-palette.js +52 -37
- package/dist/regenerate/regenerate.js +4 -2
- package/dist/regenerate/self-check.js +13 -6
- package/dist/regenerate/side-panel.js +1 -1
- package/dist/regenerate/spec-map-view.js +9 -5
- package/dist/regenerate/test-scripts.js +54 -10
- package/dist/regenerate/unit-review.js +1 -1
- package/dist/regenerate-cli.js +11 -5
- package/dist/release-cli.js +3 -8
- package/dist/review/live.js +2 -1
- package/dist/run-report.js +39 -1
- package/dist/validate-cli.js +3 -8
- package/docs/README.md +5 -12
- package/docs/authoring-plain.md +37 -119
- package/docs/config.md +53 -178
- package/docs/deploy.md +21 -80
- package/docs/development.md +13 -41
- package/docs/headless.md +45 -121
- package/docs/images/how-turri-works.svg +29 -31
- package/docs/images/turri-banner.png +0 -0
- package/docs/installation.md +13 -40
- package/docs/parser.md +15 -43
- package/docs/regenerating.md +229 -938
- package/docs/sandbox.md +38 -152
- package/docs/skills-and-gates.md +50 -171
- package/docs/theming.md +45 -46
- package/docs/using.md +69 -345
- package/genome/rules/bullet-continuation.md +5 -13
- package/genome/rules/concise-specs-examples.md +2 -4
- package/genome/rules/concise-specs-integration-examples.md +2 -6
- package/genome/rules/concise-specs.md +1 -2
- package/genome/rules/func-specs.md +1 -0
- package/genome/rules/integration-embedded-testing.md +1 -4
- package/genome/rules/integrations.md +1 -2
- package/genome/rules/project-model.md +14 -35
- package/genome/rules/stdlib.md +14 -49
- package/genome/rules/turri-regeneration.md +48 -0
- package/genome/skills/add-implementation-requirement/SKILL.md +1 -2
- package/genome/skills/analyze-if-func-spec-too-complex/SKILL.md +3 -8
- package/genome/skills/brood/SKILL.md +37 -127
- package/genome/skills/brood/references/intent.md +4 -12
- package/genome/skills/brood/references/product.md +24 -76
- package/genome/skills/brood/references/stack.md +7 -29
- package/genome/skills/brood/references/testing.md +11 -42
- package/genome/skills/bud/SKILL.md +32 -109
- package/genome/skills/bud/references/intent.md +4 -11
- package/genome/skills/implement-conformance-testing-script/SKILL.md +3 -6
- package/genome/skills/implement-unit-testing-script/SKILL.md +1 -2
- package/genome/skills/mature/SKILL.md +21 -69
- package/genome/skills/refactor-module/SKILL.md +24 -2
- package/genome/skills/spawn/SKILL.md +28 -113
- package/package.json +1 -1
- 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/fallback.txt +0 -252
- 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/docs/config.md
CHANGED
|
@@ -1,16 +1,8 @@
|
|
|
1
1
|
# The project config
|
|
2
2
|
|
|
3
|
-
A project says how its specs are built in `config.turri.yaml`, at the project root. Everything in it
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
parts are on different stacks - a backend and a frontend - adds a file per stack,
|
|
7
|
-
`config.turri.<stack>.yaml`, beside it, and chooses the stack to build with (see
|
|
8
|
-
[stacks](#stacks)). turri never writes a `config.yaml`: it may be another tool's, and
|
|
9
|
-
is read only by a project that has no file of turri's yet (see [the old config.yaml](#the-old-configyaml)).
|
|
10
|
-
|
|
11
|
-
`turri init-config` starts one: the two models, a strong one to talk to and a smaller one to write the code. It
|
|
12
|
-
asks which vendor's models you use - `--vendor` says it without asking, and with neither, as from a script, it is
|
|
13
|
-
`other`:
|
|
3
|
+
A project says how its specs are built in `config.turri.yaml`, at the project root. Everything in it is optional: with no file at all, turri finds the testing scripts on its own, turns conformance tests on wherever a module has test reqs, and runs on pi's configured model. A project whose parts are on different stacks - a backend and a frontend - adds a file per stack, `config.turri.<stack>.yaml`, beside it, and chooses the stack to build with (see [stacks](#stacks)). turri never writes a `config.yaml`: it may be another tool's, and is read only by a project that has no file of turri's yet (see [the old config.yaml](#the-old-configyaml)).
|
|
4
|
+
|
|
5
|
+
`turri init-config` starts one: the two models, a strong one to talk to and a smaller one to write the code. It asks which vendor's models you use - `--vendor` says it without asking, and with neither, as from a script, it is `other`:
|
|
14
6
|
|
|
15
7
|
| vendor | harness-model | coding-model | key pi reads |
|
|
16
8
|
| --- | --- | --- | --- |
|
|
@@ -21,79 +13,42 @@ asks which vendor's models you use - `--vendor` says it without asking, and with
|
|
|
21
13
|
| `amazon-bedrock`, OpenAI | `amazon-bedrock/<region>.openai.gpt-6-astra` | `amazon-bedrock/<region>.openai.gpt-6-luna` | `AWS_PROFILE` or `AWS_BEARER_TOKEN_BEDROCK`, and `AWS_REGION` |
|
|
22
14
|
| `other` | `anthropic/claude-opus-5-5` | `google/gemini-3.1-flash-lite` | `ANTHROPIC_API_KEY`, `GEMINI_API_KEY` |
|
|
23
15
|
|
|
24
|
-
Amazon Bedrock asks two more things - whose models, Anthropic's or OpenAI's (`--maker`), and the region of the
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
They are an example, not a requirement - any model [pi](https://pi.dev) supports works, signed in any way pi
|
|
34
|
-
supports; `other` is the starting point for another provider. What we recommend is that split, a capable model to
|
|
35
|
-
talk to and a smaller, cheaper one for the coding. Once written, it says what to do next: the key to set in your
|
|
36
|
-
shell - or `/login` in turri, which pi keeps in `~/.pi/agent/auth.json` - and that the file belongs to that folder:
|
|
37
|
-
turri reads the nearest `config.turri.yaml` upwards from where it starts, so one written anywhere else is not seen.
|
|
38
|
-
|
|
39
|
-
Below them it writes every other setting out, each with what it does and the value turri uses for it - `review: false`,
|
|
40
|
-
`turn-limit: 120`, `parallel-jobs` as this machine's cores make it - so the file says how the project is built, and you
|
|
41
|
-
change one by changing it. The optional ones, which have no value of their own - the testing scripts (written in by the
|
|
42
|
-
skill that writes them), `module`, `conformance-budget`, `judge-model`, `models` - are there commented out, each with an
|
|
43
|
-
example: uncomment one to use it. A key taken out of the file is still read as the table below says.
|
|
44
|
-
|
|
45
|
-
Beside a `config.yaml` - another tool's, say - the new file takes from it the keys turri reads too, each in its place, its
|
|
46
|
-
testing scripts above all, and says which it left (see [the old config.yaml](#the-old-configyaml)); `config.yaml`
|
|
47
|
-
is left as it is. A `config.turri.yaml` already there keeps everything but its two models, which it sets - `--force` writes the whole
|
|
48
|
-
file again - and a `config.yaml` turri read until then is copied to it first. It takes a folder other than the current
|
|
49
|
-
one as its argument.
|
|
16
|
+
Amazon Bedrock asks two more things - whose models, Anthropic's or OpenAI's (`--maker`), and the region of the inference profile they run in (`--region`): `global`, `us`, `eu`, `jp` or `au` for Anthropic's, `global` or `us` for OpenAI's. It says which `AWS_REGION` to set for it - pi calls Bedrock in `us-east-1` when none is. A `config.turri.yaml` already there keeps everything but its two models, which it sets; `--force` writes the whole file again.
|
|
17
|
+
|
|
18
|
+
Each is written with how hard it thinks - `harness-model: openai/gpt-6-astra:medium`, `coding-model: openai/gpt-6-luna:low` - so the file shows it. The reviews and judges run on the coding model but think medium (see [models per role](#models-per-role)).
|
|
19
|
+
|
|
20
|
+
They are an example, not a requirement - any model [pi](https://pi.dev) supports works, signed in any way pi supports; `other` is the starting point for another provider. What we recommend is that split, a capable model to talk to and a smaller, cheaper one for the coding. Once written, it says what to do next: the key to set in your shell - or `/login` in turri, which pi keeps in `~/.pi/agent/auth.json` - and that the file belongs to that folder: turri reads the nearest `config.turri.yaml` upwards from where it starts, so one written anywhere else is not seen.
|
|
21
|
+
|
|
22
|
+
Below them it writes every other setting out, each with what it does and the value turri uses for it - `review: false`, `turn-limit: 120`, `parallel-jobs` as this machine's cores make it - so the file says how the project is built, and you change one by changing it. The optional ones, which have no value of their own - the testing scripts (written in by the skill that writes them), `module`, `conformance-budget`, `judge-model`, `models` - are there commented out, each with an example: uncomment one to use it. A key taken out of the file is still read as the table below says.
|
|
23
|
+
|
|
24
|
+
Beside a `config.yaml` - another tool's, say - the new file takes from it the keys turri reads too, each in its place, its testing scripts above all, and says which it left (see [the old config.yaml](#the-old-configyaml)); `config.yaml` is left as it is. A `config.turri.yaml` already there keeps everything but its two models, which it sets - `--force` writes the whole file again - and a `config.yaml` turri read until then is copied to it first. It takes a folder other than the current one as its argument.
|
|
50
25
|
|
|
51
26
|
## Where it is read from
|
|
52
27
|
|
|
53
|
-
A spec belongs to its **project**: the nearest folder, from the spec's own folder up, that holds a
|
|
54
|
-
`config.turri.yaml`, a stack's `config.turri.<stack>.yaml`, the old `config.yaml` or a `plain_modules/`.
|
|
55
|
-
Without any of them, the spec's own folder is the project. That folder's config is the one read, and
|
|
56
|
-
its `plain_modules/` is where the code is built, wherever turri was started. So a project that keeps
|
|
57
|
-
its specs in `plain/`, with `plain/config.turri.yaml`, builds `plain/app.plain` by
|
|
58
|
-
`plain/config.turri.yaml` even when `turri` runs in the folder above.
|
|
28
|
+
A spec belongs to its **project**: the nearest folder, from the spec's own folder up, that holds a `config.turri.yaml`, a stack's `config.turri.<stack>.yaml`, the old `config.yaml` or a `plain_modules/`. Without any of them, the spec's own folder is the project. That folder's config is the one read, and its `plain_modules/` is where the code is built, wherever turri was started. So a project that keeps its specs in `plain/`, with `plain/config.turri.yaml`, builds `plain/app.plain` by `plain/config.turri.yaml` even when `turri` runs in the folder above.
|
|
59
29
|
|
|
60
30
|
When it is read:
|
|
61
31
|
|
|
62
|
-
- **In the chat**, afresh: the chat's agent is told what it says on every turn, and each render
|
|
63
|
-
|
|
64
|
-
no restart. The agent is told the config of the session's folder and of the projects one folder
|
|
65
|
-
down.
|
|
66
|
-
- **On the command line**, once, when the command starts. `turri regenerate` takes `module:` from
|
|
67
|
-
the folder it is run in, and the rest from the spec's own project.
|
|
32
|
+
- **In the chat**, afresh: the chat's agent is told what it says on every turn, and each render reads it when it is queued. An edit to the file holds from the next turn and the next render, with no restart. The agent is told the config of the session's folder and of the projects one folder down.
|
|
33
|
+
- **On the command line**, once, when the command starts. `turri regenerate` takes `module:` from the folder it is run in, and the rest from the spec's own project.
|
|
68
34
|
|
|
69
35
|
## Changing it from the chat
|
|
70
36
|
|
|
71
|
-
`/turri-config` changes any key in the chat, and writes it into the `config.turri.yaml` of the folder turri was started in -
|
|
72
|
-
its comments, and the commented-out examples, kept. Alone, it lists every key with what it is now, and asks for the
|
|
73
|
-
value of the one you pick the way the key takes it: `true` or `false`, one of its words, a number from a few offered or
|
|
74
|
-
typed, a model from those this machine can reach and then how hard it thinks, a script or a `.plain` file the project
|
|
75
|
-
has, rules ticked on and off. `/turri-config review` asks for review's value; `/turri-config review false` sets it, and
|
|
76
|
-
`/turri-config review unset` takes it out, back to its default. Completion offers the keys, then each one's values.
|
|
77
|
-
Each role's model and turn limit is `models.<role>` and `models.<role>.turn-limit` - `models.coding`,
|
|
78
|
-
`models.planner.turn-limit`.
|
|
37
|
+
`/turri-config` changes any key in the chat, and writes it into the `config.turri.yaml` of the folder turri was started in - its comments, and the commented-out examples, kept. Alone, it lists every key with what it is now, and asks for the value of the one you pick the way the key takes it: `true` or `false`, one of its words, a number from a few offered or typed, a model from those this machine can reach and then how hard it thinks, a script or a `.plain` file the project has, rules ticked on and off. `/turri-config review` asks for review's value; `/turri-config review false` sets it, and `/turri-config review unset` takes it out, back to its default. Completion offers the keys, then each one's values. Each role's model and turn limit is `models.<role>` and `models.<role>.turn-limit` - `models.coding`, `models.planner.turn-limit`.
|
|
79
38
|
|
|
80
|
-
Each change says when it takes effect. None needs turri started again - what turri fixes as it starts is changed as it
|
|
81
|
-
runs:
|
|
39
|
+
Each change says when it takes effect. None needs turri started again - what turri fixes as it starts is changed as it runs:
|
|
82
40
|
|
|
83
41
|
| when | keys |
|
|
84
42
|
| --- | --- |
|
|
85
43
|
| now | `harness-model` and `models.chat` - the conversation switches to it; `parallel-jobs` - a pulse waiting for a slot starts if there is one now; `allow-to-stop-jobs` |
|
|
86
44
|
| your next message | `rules-off` - for the conversation; a skill's agents from the next skill run |
|
|
87
|
-
| the next pulse - one running keeps what it started with | `coding-model`, `judge-model`, every other `models.<role>`, `review`, `turn-limit`, `compact-at`, `agent-env`, `toolchains` |
|
|
45
|
+
| the next pulse - one running keeps what it started with | `coding-model`, `judge-model`, every other `models.<role>`, `review`, `mutation-testing`, `turn-limit`, `compact-at`, `agent-env`, `toolchains` |
|
|
88
46
|
| the next time the work is planned | `conformance-tests`, `conformance-budget`, `max-specs-per-pulse`, `max-lines-per-pulse` |
|
|
89
47
|
| the next test run - the running pulse's too | the testing scripts, `testing-scripts-run-on` |
|
|
90
48
|
| the next pulse that lands - the running one too | `release-after-pulse` |
|
|
91
49
|
| the next regeneration that names no `.plain` file | `module` |
|
|
92
50
|
|
|
93
|
-
A coding model chosen this session - `--coding-model`, or `engine` - gives way to one set here: the last word wins. It
|
|
94
|
-
says, too, what wins over the change: `models.chat` over `harness-model` (and so on), and a stack's
|
|
95
|
-
`config.turri.<stack>.yaml`, which is not changed here, while that stack is chosen. In a project still read from
|
|
96
|
-
`config.yaml`, the first change copies it to `config.turri.yaml` first - see [the old config.yaml](#the-old-configyaml).
|
|
51
|
+
A coding model chosen this session - `--coding-model`, or `engine` - gives way to one set here: the last word wins. It says, too, what wins over the change: `models.chat` over `harness-model` (and so on), and a stack's `config.turri.<stack>.yaml`, which is not changed here, while that stack is chosen. In a project still read from `config.yaml`, the first change copies it to `config.turri.yaml` first - see [the old config.yaml](#the-old-configyaml).
|
|
97
52
|
|
|
98
53
|
## The keys
|
|
99
54
|
|
|
@@ -128,6 +83,7 @@ models: # each agent role's model, thinking and tur
|
|
|
128
83
|
| `conformance-tests` | `all` (or `true`): conformance tests for every functional spec of every module with test reqs, written once each module's code is built, before anything is built on it. `chosen`: for the functional specs chosen - every one with acceptance tests, and those the chooser picks as each code pulse ends, from what that pulse regenerated. `module`: the same, but the chooser is asked once, when the whole module is regenerated, and plans the conformance pulses too. Under both, the choice is made inside the pulse, before anything is built on the module, and the pulse's report says what was chosen and why; those the person asks for with `conform` are written too; once chosen, a functional spec keeps them, and they are rewritten when it changes - see [who chooses, and when](regenerating.md#conformance-tests-in-the-work-loop). `false`: none written, and none of the existing ones run - until the conversation asks with `conform` | `false` |
|
|
129
84
|
| `conformance-budget` | under `conformance-tests: chosen` or `module`: how many of a module's functional specs may be chosen for conformance tests, beside those with acceptance tests - a count (`2`) or a share of its functional specs (`30%`, rounded up, at least one). Every choice for the module counts, whenever it was made; the chooser is told what is left, and can choose no more. Your own `conform` is not limited. A stack's `config.turri.<stack>.yaml` can set its own | no limit |
|
|
130
85
|
| `review` | `true` or `false`: whether the code and its unit tests - and the conformance tests - are reviewed once they pass: two reviews at most, the second weighed by the arbiter; off, a job lands once its tests pass - see [regenerating the code](regenerating.md#the-code-and-its-unit-tests-are-reviewed) | `false` |
|
|
86
|
+
| `mutation-testing` | `true` or `false`: whether the coding agent and the reviewer have `can_it_fail` - one change put in the code for one run of the unit testing script, to see that a test catches it; on a copy of the code, or in place and put back after the run (see [regenerating the code](regenerating.md#checking-its-own-work)). `turri regenerate --mutation-testing false` for one run | `true` |
|
|
131
87
|
| `rules-off` | a list of rule names - `integrations`, `concise-specs`, the files of `genome/rules/` without `.md` - left out of the conversation's prompt and every spec-writing agent's: a rule this project's own skills or AGENTS.md replace, such as one that says to probe a live API before any spec is written. The project's alone | none |
|
|
132
88
|
| `allow-to-stop-jobs` | `true` or `false`: whether turri stops a running job the spec has moved on from - a functional spec it regenerates changed, or a file one links was edited - rolls it back and regenerates the spec as it now is. `false`: the job runs to its end and lands, and what changed since is regenerated on top of it by the next job - see [regenerating the code](regenerating.md). Your own `halt` stops a job either way | `true` |
|
|
133
89
|
| `release-after-pulse` | `true` or `false`: whether every pulse that lands code releases it, in the chat, as its last stage - before the module's next pulse starts, whatever the chat is doing: an agent on the coding model looks for the project's release guidance as the chat does (what was passed to `release` this conversation, AGENTS.md, the project's skills) and, when it says to release after a build, does what it says - see [deploy](deploy.md#after-every-pulse). One release a pulse that lands; a release that fails is said in the pulse's report, and what it landed stays | `false` |
|
|
@@ -142,17 +98,13 @@ models: # each agent role's model, thinking and tur
|
|
|
142
98
|
| `toolchains` | folders of this machine an agent's commands may read beside the system's, the `PATH`'s and those the toolchain variables point at - a toolchain installed somewhere unusual (`[/srv/zig]`). A stack's add to the project's. See [the OS sandbox](sandbox.md#the-os-sandbox) | none |
|
|
143
99
|
| `turn-limit` | seconds each turn of an agent a job starts has, for every role without its own (`models:`); `0` for none. The config is the only place it is set. A turn past it ends at its next request to the model - see [regenerating the code](regenerating.md) | 120 |
|
|
144
100
|
| `models` | each agent role's own model, thinking and turn limit - see [models per role](#models-per-role) | every role on `coding-model`, the conversation's side on `harness-model` |
|
|
145
|
-
| `testing-scripts-run-on` | what the testing scripts run on - always on this machine, in your environment. `in-place`: the real build and tests folders, the script at its own path, from the project - so a script that finds a host codebase from its own path finds it. `copy`: a fresh copy of the code, staged in `plain_modules/.turri/scripts/`, with the script copied beside it
|
|
101
|
+
| `testing-scripts-run-on` | what the testing scripts run on - always on this machine, in your environment. `in-place`: the real build and tests folders, the script at its own path, from the project - so a script that finds a host codebase from its own path finds it. `copy`: a fresh copy of the code, staged in `plain_modules/.turri/scripts/`, with the script copied beside it. `can_it_fail` works on either: on a copy it changes the copy, in place the code itself for the one run, put back after it (see [the testing scripts](regenerating.md#the-testing-scripts)) | `in-place` |
|
|
146
102
|
|
|
147
|
-
Keys are written with dashes; underscores are read the same (`conformance_tests`). A key turri
|
|
148
|
-
does not know is ignored - another tool's `config.yaml`, read while it is the old file, may carry several - and so is a value of the
|
|
149
|
-
wrong type, as if it were not there. `model:`, from before there were separate models, is read as
|
|
150
|
-
`coding-model`.
|
|
103
|
+
Keys are written with dashes; underscores are read the same (`conformance_tests`). A key turri does not know is ignored - another tool's `config.yaml`, read while it is the old file, may carry several - and so is a value of the wrong type, as if it were not there. `model:`, from before there were separate models, is read as `coding-model`.
|
|
151
104
|
|
|
152
105
|
## Models per role
|
|
153
106
|
|
|
154
|
-
`models:` gives each kind of agent its own model, thinking level and turn limit. Each entry is a model
|
|
155
|
-
(`provider/id`, or `provider/id:thinking`) or `{ model, thinking, turn-limit }`, any of which may be left out:
|
|
107
|
+
`models:` gives each kind of agent its own model, thinking level and turn limit. Each entry is a model (`provider/id`, or `provider/id:thinking`) or `{ model, thinking, turn-limit }`, any of which may be left out:
|
|
156
108
|
|
|
157
109
|
| role | the agents |
|
|
158
110
|
| --- | --- |
|
|
@@ -170,37 +122,21 @@ wrong type, as if it were not there. `model:`, from before there were separate m
|
|
|
170
122
|
| `arbiter` | the arbiters that weigh a second review |
|
|
171
123
|
| `debugger` | the fresh look at unit tests that keep failing the same way, or a coding agent going round in circles. Unnamed, `judge-model` when it is set, else the harness model - not `default` |
|
|
172
124
|
|
|
173
|
-
What an entry leaves out it takes from `default`: `reviewer: { thinking: low }` runs the default model, thinking
|
|
174
|
-
little. A turn limit is the role's own, else `default`'s, else `turn-limit:`, else two minutes. A stack's `config.turri.<stack>.yaml` lays its own `models:` over the project's, role by role - all but
|
|
175
|
-
`chat`, the project's alone.
|
|
125
|
+
What an entry leaves out it takes from `default`: `reviewer: { thinking: low }` runs the default model, thinking little. A turn limit is the role's own, else `default`'s, else `turn-limit:`, else two minutes. A stack's `config.turri.<stack>.yaml` lays its own `models:` over the project's, role by role - all but `chat`, the project's alone.
|
|
176
126
|
|
|
177
|
-
A role whose thinking nothing names - neither its entry, `default`'s, nor a `:level` on the model it runs on - thinks
|
|
178
|
-
as its kind of work needs: **low** for the agents that do the work (`coding`, `conformance`, `explorer`, `release`),
|
|
179
|
-
which work from specs that leave little to guess and take many turns, and **medium** for the ones that judge
|
|
180
|
-
(`reviewer`, `test-reviewer`, `judge`, `arbiter`, `debugger`, `planner`, `chooser`, `diagnosis`), where a wrong
|
|
181
|
-
call costs pulses. A judging role that falls back on the coding model takes its model alone, not its thinking. The
|
|
182
|
-
conversation keeps its own level, as pi sets it.
|
|
127
|
+
A role whose thinking nothing names - neither its entry, `default`'s, nor a `:level` on the model it runs on - thinks as its kind of work needs: **low** for the agents that do the work (`coding`, `conformance`, `explorer`, `release`), which work from specs that leave little to guess and take many turns, and **medium** for the ones that judge (`reviewer`, `test-reviewer`, `judge`, `arbiter`, `debugger`, `planner`, `chooser`, `diagnosis`), where a wrong call costs pulses. A judging role that falls back on the coding model takes its model alone, not its thinking. The conversation keeps its own level, as pi sets it.
|
|
183
128
|
|
|
184
|
-
The thinking level reaches the model as each provider takes it. OpenAI's models on Bedrock are sent it as their
|
|
185
|
-
reasoning effort (`none`, `low`, `medium`, `high`, `xhigh`) by turri itself, as pi sends them none.
|
|
129
|
+
The thinking level reaches the model as each provider takes it. OpenAI's models on Bedrock are sent it as their reasoning effort (`none`, `low`, `medium`, `high`, `xhigh`) by turri itself, as pi sends them none.
|
|
186
130
|
|
|
187
131
|
## How many jobs at once
|
|
188
132
|
|
|
189
|
-
Jobs on the same module, or on modules of one `requires` chain, always run one after another.
|
|
190
|
-
Modules that share nothing - a backend, a frontend, a worker, ten of them - build side by side, each
|
|
191
|
-
pulse's builds and tests running on this machine beside your own work. So the chat runs at most `parallel-jobs` jobs
|
|
192
|
-
at once; a job whose turn has come waits for a free slot past that, and its line says so. Unset, it is half this
|
|
193
|
-
machine's cores, at least one and at most four. The config is the only place it is set. It is the project's alone,
|
|
194
|
-
never read from a stack's file.
|
|
133
|
+
Jobs on the same module, or on modules of one `requires` chain, always run one after another. Modules that share nothing - a backend, a frontend, a worker, ten of them - build side by side, each pulse's builds and tests running on this machine beside your own work. So the chat runs at most `parallel-jobs` jobs at once; a job whose turn has come waits for a free slot past that, and its line says so. Unset, it is half this machine's cores, at least one and at most four. The config is the only place it is set. It is the project's alone, never read from a stack's file.
|
|
195
134
|
|
|
196
|
-
The testing scripts all run on this machine, each on a copy of its module's code, so they never
|
|
197
|
-
share files - but they do share its network: two modules whose conformance scripts start a server
|
|
198
|
-
on the same port collide when they run at once. Give each its own.
|
|
135
|
+
The testing scripts all run on this machine, each on a copy of its module's code, so they never share files - but they do share its network: two modules whose conformance scripts start a server on the same port collide when they run at once. Give each its own.
|
|
199
136
|
|
|
200
137
|
## Models
|
|
201
138
|
|
|
202
|
-
Each model is a model reference and a thinking level - `off`, `minimal`, `low`, `medium`, `high`,
|
|
203
|
-
`xhigh` or `max` - and either may be left out:
|
|
139
|
+
Each model is a model reference and a thinking level - `off`, `minimal`, `low`, `medium`, `high`, `xhigh` or `max` - and either may be left out:
|
|
204
140
|
|
|
205
141
|
```yaml
|
|
206
142
|
coding-model:
|
|
@@ -210,9 +146,7 @@ judge-model: google/gemini-3.1-pro:high # the same, as one string
|
|
|
210
146
|
harness-model: anthropic/claude-opus-5-5 # a model alone
|
|
211
147
|
```
|
|
212
148
|
|
|
213
|
-
What a model leaves out it takes from the one it inherits: `judge-model` from `coding-model` - its model, not its
|
|
214
|
-
thinking, which the judging roles have their own of - and `coding-model` from `harness-model`. So with only a harness model, everything runs on it;
|
|
215
|
-
`coding-model: {thinking: low}` renders on the harness model, thinking less.
|
|
149
|
+
What a model leaves out it takes from the one it inherits: `judge-model` from `coding-model` - its model, not its thinking, which the judging roles have their own of - and `coding-model` from `harness-model`. So with only a harness model, everything runs on it; `coding-model: {thinking: low}` renders on the harness model, thinking less.
|
|
216
150
|
|
|
217
151
|
They are defaults. What is asked for wins over them:
|
|
218
152
|
|
|
@@ -222,52 +156,31 @@ They are defaults. What is asked for wins over them:
|
|
|
222
156
|
| coding | `turri --coding-model <m>`, `engine` in the conversation |
|
|
223
157
|
| judge | - |
|
|
224
158
|
|
|
225
|
-
`turri regenerate`, `conform` and `spec-diff` read `--harness-model`, `--coding-model` (or `--model`),
|
|
226
|
-
`--judge-model`, `--review` and `--conformance-tests` differently: as the keys themselves, as if the file had
|
|
227
|
-
them. Each takes its key's value and its place in the order above - a `models:` entry still wins over it - so a
|
|
228
|
-
headless run is the same as a chat with those keys in the file.
|
|
159
|
+
`turri regenerate`, `conform` and `spec-diff` read `--harness-model`, `--coding-model` (or `--model`), `--judge-model`, `--review` and `--conformance-tests` differently: as the keys themselves, as if the file had them. Each takes its key's value and its place in the order above - a `models:` entry still wins over it - so a headless run is the same as a chat with those keys in the file.
|
|
229
160
|
|
|
230
161
|
A job keeps the model it was queued with: choosing another holds for what is queued after.
|
|
231
162
|
|
|
232
163
|
## Conformance tests
|
|
233
164
|
|
|
234
|
-
`conformance-tests:` is the one switch, and the chat, every render and `brood`'s testing phase
|
|
235
|
-
follow it. `false` turns them off entirely: no conformance tests are written, the ones already in a
|
|
236
|
-
codebase are not run, and no agent is shown the conformance testing script. No key is the same as
|
|
237
|
-
`false`: conformance tests are off by default. `all` (or `true`) means on wherever a module has
|
|
238
|
-
`***test reqs***` - a module without them has nothing to write conformance tests from, so it writes
|
|
239
|
-
none, but still keeps the codebase's existing ones passing. Asked in the
|
|
240
|
-
conversation (`conform`), or with `--conformance-tests all|chosen|module|false` on `turri regenerate` and
|
|
241
|
-
`spec-diff` - for that run, the file left as it is - a render does otherwise.
|
|
165
|
+
`conformance-tests:` is the one switch, and the chat, every render and `brood`'s testing phase follow it. `false` turns them off entirely: no conformance tests are written, the ones already in a codebase are not run, and no agent is shown the conformance testing script. No key is the same as `false`: conformance tests are off by default. `all` (or `true`) means on wherever a module has `***test reqs***` - a module without them has nothing to write conformance tests from, so it writes none, but still keeps the codebase's existing ones passing. Asked in the conversation (`conform`), or with `--conformance-tests all|chosen|module|false` on `turri regenerate` and `spec-diff` - for that run, the file left as it is - a render does otherwise.
|
|
242
166
|
|
|
243
|
-
`spawn` writes `conformance-tests: false` into a new project unless you ask for tests;
|
|
244
|
-
`brood` asks, whatever the key says, offering what it says first.
|
|
167
|
+
`spawn` writes `conformance-tests: false` into a new project unless you ask for tests; `brood` asks, whatever the key says, offering what it says first.
|
|
245
168
|
|
|
246
169
|
## The testing scripts
|
|
247
170
|
|
|
248
|
-
A build needs a unit testing script - and, with conformance on, a conformance testing script - to
|
|
249
|
-
decide when it is done. They are looked for at the project root, in this order:
|
|
171
|
+
A build needs a unit testing script - and, with conformance on, a conformance testing script - to decide when it is done. They are looked for at the project root, in this order:
|
|
250
172
|
|
|
251
173
|
1. named in the config - the chosen stack's file first, then `config.turri.yaml` - by path from the root;
|
|
252
174
|
2. the one `run_unittests*.sh` / `run_conformance_tests*.sh` in the project root;
|
|
253
175
|
3. the one of each in `test_scripts/`.
|
|
254
176
|
|
|
255
|
-
The optional prepare script - `prepare-environment-script:`, else the one `prepare_environment*.sh` - is looked for the
|
|
256
|
-
same way, and run on the build before the conformance testing script.
|
|
177
|
+
The optional prepare script - `prepare-environment-script:`, else the one `prepare_environment*.sh` - is looked for the same way, and run on the build before the conformance testing script.
|
|
257
178
|
|
|
258
|
-
A folder holding two of a kind is not guessed between: name the one to use. A script named inside
|
|
259
|
-
`plain_modules/` is refused - agents write there, so it could be changed by the work it judges. The
|
|
260
|
-
scripts are never linked from the specs. What they are and how they run is in
|
|
261
|
-
[regenerating the code](regenerating.md#the-testing-scripts).
|
|
179
|
+
A folder holding two of a kind is not guessed between: name the one to use. A script named inside `plain_modules/` is refused - agents write there, so it could be changed by the work it judges. The scripts are never linked from the specs. What they are and how they run is in [regenerating the code](regenerating.md#the-testing-scripts).
|
|
262
180
|
|
|
263
181
|
## Credentials for the agents
|
|
264
182
|
|
|
265
|
-
An agent's commands do not get the environment turri was started in: it holds your providers' API keys, cloud
|
|
266
|
-
credentials and tokens. They get only the path, the locale, the terminal and the user, the variables that locate your
|
|
267
|
-
toolchains (`JAVA_HOME`, `NVM_DIR`, `RUSTUP_HOME`, ... - the ones in your home found even when your shell sets none),
|
|
268
|
-
and turri's own: a home folder of the module's own (`plain_modules/.turri/home/<module>`, kept between pulses, with a
|
|
269
|
-
git identity of its own), a `TMPDIR`, the package caches in `plain_modules/.turri/cache`, and git stopped at the module
|
|
270
|
-
folder, so a project that is itself a repository is never found from the code.
|
|
183
|
+
An agent's commands do not get the environment turri was started in: it holds your providers' API keys, cloud credentials and tokens. They get only the path, the locale, the terminal and the user, the variables that locate your toolchains (`JAVA_HOME`, `NVM_DIR`, `RUSTUP_HOME`, ... - the ones in your home found even when your shell sets none), and turri's own: a home folder of the module's own (`plain_modules/.turri/home/<module>`, kept between pulses, with a git identity of its own), a `TMPDIR`, the package caches in `plain_modules/.turri/cache`, and git stopped at the module folder, so a project that is itself a repository is never found from the code.
|
|
271
184
|
|
|
272
185
|
A project whose agents need a credential while they work names it:
|
|
273
186
|
|
|
@@ -277,24 +190,13 @@ agent-env:
|
|
|
277
190
|
vars: [D365_TENANT_ID] # these variables, from the environment turri was started in
|
|
278
191
|
```
|
|
279
192
|
|
|
280
|
-
What it names reaches every agent with a shell, as environment variables of its commands only - the file stays where
|
|
281
|
-
it is, outside every agent's reach - and never replaces turri's own home, `TMPDIR` or caches. A stack's file adds
|
|
282
|
-
to the project's. A file that is not there, or a variable unset or empty, is reported as missing. The testing scripts
|
|
283
|
-
are not affected: they run in your own environment.
|
|
193
|
+
What it names reaches every agent with a shell, as environment variables of its commands only - the file stays where it is, outside every agent's reach - and never replaces turri's own home, `TMPDIR` or caches. A stack's file adds to the project's. A file that is not there, or a variable unset or empty, is reported as missing. The testing scripts are not affected: they run in your own environment.
|
|
284
194
|
|
|
285
|
-
Their values never appear in what an agent is shown or what turri writes: each is replaced by its name -
|
|
286
|
-
`[D365_CLIENT_SECRET]` - whole, URL-encoded, or split over a command's output as it streams: in every tool result and
|
|
287
|
-
refusal an agent is given (and so in the session transcripts, which hold only those), in the whole outputs kept for
|
|
288
|
-
`read_output`, and in the job and debug logs. A value shorter than four characters is not masked - `1` or `eu` is
|
|
289
|
-
everywhere in ordinary output.
|
|
195
|
+
Their values never appear in what an agent is shown or what turri writes: each is replaced by its name - `[D365_CLIENT_SECRET]` - whole, URL-encoded, or split over a command's output as it streams: in every tool result and refusal an agent is given (and so in the session transcripts, which hold only those), in the whole outputs kept for `read_output`, and in the job and debug logs. A value shorter than four characters is not masked - `1` or `eu` is everywhere in ordinary output.
|
|
290
196
|
|
|
291
197
|
## Stacks
|
|
292
198
|
|
|
293
|
-
One project can hold parts that share nothing but a common module - a Python backend and a React
|
|
294
|
-
frontend side by side, each importing `base` from `template/`, neither requiring the other - each
|
|
295
|
-
needing its own testing scripts. Each stack gets a file of its own beside `config.turri.yaml`,
|
|
296
|
-
`config.turri.<stack>.yaml`, holding what differs for it - typically its testing scripts, its
|
|
297
|
-
`toolchains:`, its models:
|
|
199
|
+
One project can hold parts that share nothing but a common module - a Python backend and a React frontend side by side, each importing `base` from `template/`, neither requiring the other - each needing its own testing scripts. Each stack gets a file of its own beside `config.turri.yaml`, `config.turri.<stack>.yaml`, holding what differs for it - typically its testing scripts, its `toolchains:`, its models:
|
|
298
200
|
|
|
299
201
|
```
|
|
300
202
|
config.turri.yaml # the project's: harness-model, coding-model, conformance-tests
|
|
@@ -316,50 +218,23 @@ coding-model:
|
|
|
316
218
|
|
|
317
219
|
A stack is chosen, never worked out from the spec:
|
|
318
220
|
|
|
319
|
-
- **In the chat**, with `/stack` - a list of the project's stacks and none - or `/stack backend`, `/stack none`.
|
|
320
|
-
|
|
321
|
-
stack builds. `/stack` alone says which is chosen now.
|
|
322
|
-
- **On the command line**, with `--stack <name>` on any command - `turri regenerate`, `conform`, `spec-diff`, `glimpse`,
|
|
323
|
-
`release`, `cultivate` - and on `turri --stack backend` for the chat; or with `TURRI_STACK` in the environment.
|
|
221
|
+
- **In the chat**, with `/stack` - a list of the project's stacks and none - or `/stack backend`, `/stack none`. The chat's model has a `stack` tool too, and switches the stack when you ask it to, or for work on a part another stack builds. `/stack` alone says which is chosen now.
|
|
222
|
+
- **On the command line**, with `--stack <name>` on any command - `turri regenerate`, `conform`, `spec-diff`, `glimpse`, `release`, `cultivate` - and on `turri --stack backend` for the chat; or with `TURRI_STACK` in the environment.
|
|
324
223
|
|
|
325
|
-
The choice lasts for the session only: nothing remembers it, and turri started again has none chosen. A stack the
|
|
326
|
-
project has no file for is refused, with the stacks it has. With none chosen, `config.turri.yaml` alone is used.
|
|
224
|
+
The choice lasts for the session only: nothing remembers it, and turri started again has none chosen. A stack the project has no file for is refused, with the stacks it has. With none chosen, `config.turri.yaml` alone is used.
|
|
327
225
|
|
|
328
226
|
How a stack's config is made:
|
|
329
227
|
|
|
330
|
-
- **Laid over `config.turri.yaml`, key by key.** What the stack's file gives wins; what it leaves out
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
started with. Choose the stack before building the part it is for: `/stack backend`, then
|
|
336
|
-
`regenerate backend.plain`.
|
|
337
|
-
- **The project's alone.** `module:`, `harness-model:`, `parallel-jobs:`, `rules-off:` and `compact-at:` are read
|
|
338
|
-
only from `config.turri.yaml` - there is one conversation, one module built when none is named, one machine.
|
|
339
|
-
`agent-env:` and `toolchains:` in a stack's file add to the project's.
|
|
340
|
-
|
|
341
|
-
The chat is told each stack's config and the one chosen. The skills that write testing scripts put
|
|
342
|
-
each stack's in its own file once a project has two stacks, and say which stack to choose before
|
|
343
|
-
building each part.
|
|
228
|
+
- **Laid over `config.turri.yaml`, key by key.** What the stack's file gives wins; what it leaves out is the project's. A model it names takes what it leaves out from the project's same model - above, with the stack frontend chosen, everything renders on the project's coding model, thinking `high`.
|
|
229
|
+
- **For everything built while it is chosen.** Every pulse that starts, every test run and every script found from then on is the chosen stack's; a pulse already running keeps the stack it started with. Choose the stack before building the part it is for: `/stack backend`, then `regenerate backend.plain`.
|
|
230
|
+
- **The project's alone.** `module:`, `harness-model:`, `parallel-jobs:`, `rules-off:` and `compact-at:` are read only from `config.turri.yaml` - there is one conversation, one module built when none is named, one machine. `agent-env:` and `toolchains:` in a stack's file add to the project's.
|
|
231
|
+
|
|
232
|
+
The chat is told each stack's config and the one chosen. The skills that write testing scripts put each stack's in its own file once a project has two stacks, and say which stack to choose before building each part.
|
|
344
233
|
|
|
345
234
|
## The old config.yaml
|
|
346
235
|
|
|
347
|
-
turri's settings were once in `config.yaml`, and a stack's in `config.<stack>.yaml`. A `config.yaml`
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
`config.turri.yaml` and each `config.<name>.yaml` to `config.turri.<name>.yaml` first, leaves the old
|
|
353
|
-
files as they are, and from then on reads only the new ones. `turri init-config` copies the stacks'
|
|
354
|
-
files the same way, but writes `config.turri.yaml` as its quick start, taking from `config.yaml` only
|
|
355
|
-
the keys turri reads too - `unittests-script`, `conformance-tests-script` and
|
|
356
|
-
`prepare-environment-script`, say - each in its place in the file, and saying which keys it left:
|
|
357
|
-
`template_dir`, `verbose`, `api`, the other tool's alone. The two models are the vendor's, never taken. To change a
|
|
358
|
-
setting by hand in such a project, do the same: copy the files to their new names, and edit the
|
|
359
|
-
copies - never `config.yaml`. Writing a `config.turri.yaml` of your own beside it is the same move: from then on
|
|
360
|
-
`config.yaml` is not read, its testing scripts with it. For a headless run that only needs conformance tests or
|
|
361
|
-
another judge, or review, those options leave the files alone: `--conformance-tests`, `--judge-model`, `--review true|false`, and the models' too.
|
|
362
|
-
|
|
363
|
-
Keys turri does not read - another tool's `verbose`, `api-key`, `build-folder`, ... - are ignored without a word, and so
|
|
364
|
-
is a value of the wrong type. A file that does not parse as YAML is read as empty, so its testing scripts are then
|
|
365
|
-
looked for by name.
|
|
236
|
+
turri's settings were once in `config.yaml`, and a stack's in `config.<stack>.yaml`. A `config.yaml` may be another tool's, so turri never writes one. While a project folder has no `config.turri*.yaml` at all, turri still reads its `config.yaml`, and each `config.<name>.yaml` as the stack `<name>`.
|
|
237
|
+
|
|
238
|
+
The first time turri itself writes a setting there with `/turri-config`, it copies `config.yaml` to `config.turri.yaml` and each `config.<name>.yaml` to `config.turri.<name>.yaml` first, leaves the old files as they are, and from then on reads only the new ones. `turri init-config` copies the stacks' files the same way, but writes `config.turri.yaml` as its quick start, taking from `config.yaml` only the keys turri reads too - `unittests-script`, `conformance-tests-script` and `prepare-environment-script`, say - each in its place in the file, and saying which keys it left: `template_dir`, `verbose`, `api`, the other tool's alone. The two models are the vendor's, never taken. To change a setting by hand in such a project, do the same: copy the files to their new names, and edit the copies - never `config.yaml`. Writing a `config.turri.yaml` of your own beside it is the same move: from then on `config.yaml` is not read, its testing scripts with it. For a headless run that only needs conformance tests or another judge, or review, those options leave the files alone: `--conformance-tests`, `--judge-model`, `--review true|false`, and the models' too.
|
|
239
|
+
|
|
240
|
+
Keys turri does not read - another tool's `verbose`, `api-key`, `build-folder`, ... - are ignored without a word, and so is a value of the wrong type. A file that does not parse as YAML is read as empty, so its testing scripts are then looked for by name.
|
package/docs/deploy.md
CHANGED
|
@@ -1,95 +1,41 @@
|
|
|
1
1
|
# Trying what is built: deploy
|
|
2
2
|
|
|
3
|
-
Ask to try it - "let me try it", "run the app" - at any time, even while a render is running. The
|
|
4
|
-
chat calls `deploy`: it puts the module's code, as it was last built, in `dist/<module>` in the
|
|
5
|
-
project, and starts it on your machine. An app with a backend and a frontend is started whole, and
|
|
6
|
-
you are told where to open your browser. For a command-line tool or a library you get a few commands
|
|
7
|
-
to paste, run from `dist/<module>`, and what they print.
|
|
3
|
+
Ask to try it - "let me try it", "run the app" - at any time, even while a render is running. The chat calls `deploy`: it puts the module's code, as it was last built, in `dist/<module>` in the project, and starts it on your machine. An app with a backend and a frontend is started whole, and you are told where to open your browser. For a command-line tool or a library you get a few commands to paste, run from `dist/<module>`, and what they print.
|
|
8
4
|
|
|
9
|
-
Every pulse that lands code - a render, a spec diff, a conformance run, a functionality regenerated - ends with
|
|
10
|
-
"Want to try it? Just ask me - I'll set it up from what's built so far." When a render's conformance
|
|
11
|
-
tests follow as a pulse of their own, the conformance pulse says it, once they pass too.
|
|
5
|
+
Every pulse that lands code - a render, a spec diff, a conformance run, a functionality regenerated - ends with "Want to try it? Just ask me - I'll set it up from what's built so far." When a render's conformance tests follow as a pulse of their own, the conformance pulse says it, once they pass too.
|
|
12
6
|
|
|
13
7
|
## When the project says how it is released
|
|
14
8
|
|
|
15
|
-
Every release starts the same way: the module's last commit - what last landed whole - goes in
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
is started. So the model asks itself whether there is guidance for how this project is released -
|
|
19
|
-
in what you said, the project's AGENTS.md, a skill, anything it was given - and passes it to
|
|
20
|
-
`release` whole:
|
|
21
|
-
|
|
22
|
-
- **There is guidance.** The code goes on from `dist/<module>` as the guidance says, on your machine,
|
|
23
|
-
from the host codebase - the git repository the project is in, or else where **turri** runs: the
|
|
24
|
-
scripts it names, in their order, and any change it says the host needs. The code is taken from
|
|
25
|
-
`dist`, never from `plain_modules`, where a pulse may be writing; where the host's tooling reads
|
|
26
|
-
`plain_modules` itself, the model points it at `dist`, or does by hand from `dist` what it does. When
|
|
27
|
-
to release - after every pulse, say - is the guidance's to say too. The rules below hold as they do for `dist`: the
|
|
28
|
-
model runs the project's scripts and installs what they need itself, and what keeps running - a
|
|
29
|
-
start script, a server - is started with `activate`. Nothing built is changed.
|
|
9
|
+
Every release starts the same way: the module's last commit - what last landed whole - goes in `dist/<module>`, as below. Not everything is tried from there, though. An integration that a host application loads goes on into the host's own tree, with the host's own scripts, and then the host is started. So the model asks itself whether there is guidance for how this project is released - in what you said, the project's AGENTS.md, a skill, anything it was given - and passes it to `release` whole:
|
|
10
|
+
|
|
11
|
+
- **There is guidance.** The code goes on from `dist/<module>` as the guidance says, on your machine, from the host codebase - the git repository the project is in, or else where **turri** runs: the scripts it names, in their order, and any change it says the host needs. The code is taken from `dist`, never from `plain_modules`, where a pulse may be writing; where the host's tooling reads `plain_modules` itself, the model points it at `dist`, or does by hand from `dist` what it does. When to release - after every pulse, say - is the guidance's to say too. The rules below hold as they do for `dist`: the model runs the project's scripts and installs what they need itself, and what keeps running - a start script, a server - is started with `activate`. Nothing built is changed.
|
|
30
12
|
- **There is none.** The default: it is started from `dist/<module>`, as below, as best it can be.
|
|
31
13
|
|
|
32
|
-
Guidance is whatever says it, in any words - a line in AGENTS.md such as *integrations are released
|
|
33
|
-
with `scripts/deploy_integrations.sh`, then the app is started with `scripts/start.sh`*, or the
|
|
34
|
-
same said in the chat.
|
|
14
|
+
Guidance is whatever says it, in any words - a line in AGENTS.md such as *integrations are released with `scripts/deploy_integrations.sh`, then the app is started with `scripts/start.sh`*, or the same said in the chat.
|
|
35
15
|
|
|
36
|
-
The chat reacts to every pulse that finishes as it finishes, without waiting for you to speak: guidance
|
|
37
|
-
that says to release after a build - *release each integration once it is regenerated* - is followed then.
|
|
38
|
-
It never has to work out whether what a pulse landed is already out: `release` does. When the module's
|
|
39
|
-
last commit is what its last release in this conversation shipped, it does nothing - nothing exported,
|
|
40
|
-
nothing stopped, what runs left running - and says so; `again: true` releases it anyway, for when what
|
|
41
|
-
that release said to do was not done.
|
|
16
|
+
The chat reacts to every pulse that finishes as it finishes, without waiting for you to speak: guidance that says to release after a build - *release each integration once it is regenerated* - is followed then. It never has to work out whether what a pulse landed is already out: `release` does. When the module's last commit is what its last release in this conversation shipped, it does nothing - nothing exported, nothing stopped, what runs left running - and says so; `again: true` releases it anyway, for when what that release said to do was not done.
|
|
42
17
|
|
|
43
18
|
## What goes in dist
|
|
44
19
|
|
|
45
|
-
- **The module on top.** Code accumulates up a `requires` chain: a module starts from a copy of the
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
anything built, it takes the nearest one below it that has, and says so.
|
|
49
|
-
- **Its last commit.** Each `plain_modules/<module>` is a git repository (`.plaingit`), and every unit
|
|
50
|
-
of work starts from a commit and ends with one. What a pulse is writing right now is half-done, so it
|
|
51
|
-
is left out: deploy exports the commit - `git archive` of `code/` - which is the working tree with
|
|
52
|
-
every unstaged and untracked change put back, and no `node_modules`, `.venv`, `target` or other
|
|
53
|
-
build leftovers, whatever the stack. The working tree the pulse is using is never read or touched.
|
|
54
|
-
The harness's own files - `.turri.json`, the agents' notes - are left out too.
|
|
55
|
-
- **Replaced whole.** Each deploy stops what the last one of the module started, empties
|
|
56
|
-
`dist/<module>` and exports again. Change nothing there you want to keep. `dist/` is not added to
|
|
57
|
-
`.gitignore`: whether it is committed is yours to decide.
|
|
20
|
+
- **The module on top.** Code accumulates up a `requires` chain: a module starts from a copy of the code of the one it requires. So deploy always takes the module on top of the spec's chain - the project's `module` from `config.turri.yaml` unless another spec is named. Before the module on top has anything built, it takes the nearest one below it that has, and says so.
|
|
21
|
+
- **Its last commit.** Each `plain_modules/<module>` is a git repository (`.plaingit`), and every unit of work starts from a commit and ends with one. What a pulse is writing right now is half-done, so it is left out: deploy exports the commit - `git archive` of `code/` - which is the working tree with every unstaged and untracked change put back, and no `node_modules`, `.venv`, `target` or other build leftovers, whatever the stack. The working tree the pulse is using is never read or touched. The harness's own files - `.turri.json`, the agents' notes - are left out too.
|
|
22
|
+
- **Replaced whole.** Each deploy stops what the last one of the module started, empties `dist/<module>` and exports again. Change nothing there you want to keep. `dist/` is not added to `.gitignore`: whether it is committed is yours to decide.
|
|
58
23
|
|
|
59
24
|
## Starting it
|
|
60
25
|
|
|
61
|
-
It runs on your machine, outside the [sandbox](sandbox.md) - with your toolchains, where your
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
build that downloads packages, an image pull, a guided release's project scripts: it runs them in
|
|
69
|
-
its own shell, as any agent with a shell would, and fixes what fails. Nothing is put to you - there
|
|
70
|
-
is no dialog to answer.
|
|
71
|
-
3. **Starts what serves** with `activate`: in the background, in its own process group, its
|
|
72
|
-
output in `.turri/deploy/<module>-<name>.log`. It waits until something answers at the
|
|
73
|
-
server's URL - up to a minute - so the URL you are given has answered once; one that exits first
|
|
74
|
-
comes back with the end of its output. A port something else holds is said, with what holds it,
|
|
75
|
-
and nothing is started there: the app is not moved to a port you were not told about.
|
|
76
|
-
|
|
77
|
-
What it started is listed by the `pulses` tool and by **`/halt`**, and stopped by **`/halt activated <name>`**, by
|
|
78
|
-
`halt`, by the next deploy of the module, and when the chat exits.
|
|
26
|
+
It runs on your machine, outside the [sandbox](sandbox.md) - with your toolchains, where your browser can reach it. The chat reads how the code runs (its README, manifests and entry points), then:
|
|
27
|
+
|
|
28
|
+
1. **Checks the toolchains** it needs (`node`, `python3`, `go`, ...). One is missing: it installs it with the machine's package manager (`brew` on macOS, `apt` or `dnf` on Linux).
|
|
29
|
+
2. **Installs what it needs itself.** Dependencies into a virtual environment or `node_modules`, a build that downloads packages, an image pull, a guided release's project scripts: it runs them in its own shell, as any agent with a shell would, and fixes what fails. Nothing is put to you - there is no dialog to answer.
|
|
30
|
+
3. **Starts what serves** with `activate`: in the background, in its own process group, its output in `.turri/deploy/<module>-<name>.log`. It waits until something answers at the server's URL - up to a minute - so the URL you are given has answered once; one that exits first comes back with the end of its output. A port something else holds is said, with what holds it, and nothing is started there: the app is not moved to a port you were not told about.
|
|
31
|
+
|
|
32
|
+
What it started is listed by the `pulses` tool and by **`/halt`**, and stopped by **`/halt activated <name>`**, by `halt`, by the next deploy of the module, and when the chat exits.
|
|
79
33
|
|
|
80
34
|
## After every pulse
|
|
81
35
|
|
|
82
|
-
With `release-after-pulse: true` in `config.turri.yaml`, turri releases what each pulse lands itself, as the
|
|
83
|
-
pulse's last stage (`releasing what this pulse landed`): the pulse ends once it is released, so the
|
|
84
|
-
module's next pulse starts on what is out, and the chat - waiting on your answer to a question, say - has
|
|
85
|
-
no part in it. One release a pulse that lands, in order.
|
|
36
|
+
With `release-after-pulse: true` in `config.turri.yaml`, turri releases what each pulse lands itself, as the pulse's last stage (`releasing what this pulse landed`): the pulse ends once it is released, so the module's next pulse starts on what is out, and the chat - waiting on your answer to a question, say - has no part in it. One release a pulse that lands, in order.
|
|
86
37
|
|
|
87
|
-
The release is done by an agent on the coding model, thinking low - it follows steps, and a small model does that
|
|
88
|
-
well - the same one `turri release` runs, and it finds
|
|
89
|
-
the guidance as the chat would: what was passed to `release` earlier in the conversation, the project's
|
|
90
|
-
AGENTS.md and its skills. When nothing there says to release after a build, it releases nothing and says
|
|
91
|
-
so. Its last words go in the pulse's report - "Released after the pulse: ..." - and the chat, seeing them,
|
|
92
|
-
does not release it again. A release that fails is said there too; what the pulse landed stays.
|
|
38
|
+
The release is done by an agent on the coding model, thinking low - it follows steps, and a small model does that well - the same one `turri release` runs, and it finds the guidance as the chat would: what was passed to `release` earlier in the conversation, the project's AGENTS.md and its skills. When nothing there says to release after a build, it releases nothing and says so. Its last words go in the pulse's report - "Released after the pulse: ..." - and the chat, seeing them, does not release it again. A release that fails is said there too; what the pulse landed stays.
|
|
93
39
|
|
|
94
40
|
Off by default: without the key, releasing after a pulse is the chat's, when its guidance says so.
|
|
95
41
|
|
|
@@ -99,11 +45,6 @@ Off by default: without the key, releasing after a pulse is the chat's, when its
|
|
|
99
45
|
turri release [file.plain] [--in-module <module>] [--guidance <text>] [--model <provider/id>]
|
|
100
46
|
```
|
|
101
47
|
|
|
102
|
-
The same, without the chat: a one-off agent on `coding-model`, thinking low (or `--model`; without either,
|
|
103
|
-
pi's default) is given the project's AGENTS.md and what `--guidance <text>` says, looks for guidance in
|
|
104
|
-
them, and releases as above - as the guidance says, or to `dist/<module>` - then works out how to
|
|
105
|
-
start it and starts it here, installing what it needs without asking. It stays in the foreground with the servers'
|
|
106
|
-
output; `Ctrl-C` stops them. If it does not get there, deploy from the chat instead.
|
|
48
|
+
The same, without the chat: a one-off agent on `coding-model`, thinking low (or `--model`; without either, pi's default) is given the project's AGENTS.md and what `--guidance <text>` says, looks for guidance in them, and releases as above - as the guidance says, or to `dist/<module>` - then works out how to start it and starts it here, installing what it needs without asking. It stays in the foreground with the servers' output; `Ctrl-C` stops them. If it does not get there, deploy from the chat instead.
|
|
107
49
|
|
|
108
|
-
`turri regenerate`, `spec-diff` and `conform` end a build that landed with
|
|
109
|
-
`To try it: turri release <spec>`.
|
|
50
|
+
`turri regenerate`, `spec-diff` and `conform` end a build that landed with `To try it: turri release <spec>`.
|