@turri-dev/cli 0.1.11-next.fec1e14 → 0.1.12-next.8125d07

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. package/README.md +5 -5
  2. package/dist/{spec-diff-cli.js → change-plain-cli.js} +3 -3
  3. package/dist/cli.js +1 -1
  4. package/dist/extension.js +4 -4
  5. package/dist/genome.js +5 -5
  6. package/dist/identity.js +8 -6
  7. package/dist/loop-cli.d.ts +1 -1
  8. package/dist/loop-cli.js +1 -1
  9. package/dist/regenerate/activity.js +2 -2
  10. package/dist/self-invocation.js +6 -6
  11. package/dist/skill.d.ts +3 -3
  12. package/dist/skill.js +2 -2
  13. package/dist/spec-tools.js +2 -2
  14. package/dist/stacks.js +1 -1
  15. package/dist/tools.js +1 -1
  16. package/docs/README.md +13 -13
  17. package/docs/authoring-plain.md +34 -34
  18. package/docs/config.md +25 -25
  19. package/docs/deploy.md +5 -5
  20. package/docs/development.md +11 -11
  21. package/docs/headless.md +18 -18
  22. package/docs/hosting.md +14 -14
  23. package/docs/images/how-turri-works.svg +1 -1
  24. package/docs/installation.md +13 -13
  25. package/docs/parser.md +5 -5
  26. package/docs/regenerating.md +78 -78
  27. package/docs/sandbox.md +7 -7
  28. package/docs/skills-and-gates.md +19 -19
  29. package/docs/theming.md +11 -11
  30. package/docs/using.md +50 -50
  31. package/genome/skills/brood/SKILL.md +11 -11
  32. package/genome/skills/brood/references/product.md +4 -4
  33. package/genome/skills/brood/references/testing.md +1 -1
  34. package/genome/skills/bud/SKILL.md +6 -6
  35. package/genome/skills/mature/SKILL.md +4 -4
  36. package/genome/skills/spawn/SKILL.md +4 -4
  37. package/package.json +1 -1
  38. package/genome/skills/init-plain-project/SKILL.md +0 -117
  39. package/genome/skills/init-plain-project/references/checklist.md +0 -30
  40. /package/dist/{spec-diff-cli.d.ts → change-plain-cli.d.ts} +0 -0
@@ -1,6 +1,6 @@
1
1
  # Installation
2
2
 
3
- **turri** runs wherever pi runs - macOS, Linux, WSL - with git, bash and Node 22.19 or newer (a Linux distribution's own `nodejs` package is often older: take it from nodejs.org, nvm or NodeSource). Native Windows is best effort: it needs bash on the PATH (Git for Windows' Git Bash), and has no OS sandbox under the agents' commands.
3
+ **turri** runs wherever [pi](https://pi.dev) runs - macOS, Linux, WSL - with git, bash and Node 22.19 or newer (a Linux distribution's own `nodejs` package is often older: take it from nodejs.org, nvm or NodeSource). Native Windows is best effort: it needs bash on the PATH (Git for Windows' Git Bash), and has no OS sandbox under the agents' commands.
4
4
 
5
5
  The agents' commands run on this machine, with its toolchains - see [the sandbox](sandbox.md). Each is checked before it runs and audited after, on every platform; under them an OS sandbox fences it where the OS has one: Seatbelt on macOS, always there, and bubblewrap on Linux and WSL 2 - `apt install bubblewrap`, or your distribution's package.
6
6
 
@@ -9,7 +9,7 @@ npm install -g @turri-dev/cli # puts `turri` on your PATH
9
9
  turri doctor # checks the machine: what turri needs, and what is missing
10
10
  ```
11
11
 
12
- Then, in the project that holds your specs:
12
+ Then, in the project that holds your \*\*\*plain:
13
13
 
14
14
  ```bash
15
15
  cd ~/my-project
@@ -17,7 +17,7 @@ turri init-config # a config.turri.yaml with the model you talk to and the one
17
17
  turri # pi, with turri's tools, skills and themes loaded
18
18
  ```
19
19
 
20
- The package is `@turri-dev/cli` - npm keeps the name `turri` back, as too like another package's - and the command it puts on your PATH is `turri`. `npm install -g @turri-dev/cli@next` gets the latest prerelease instead, built from the last commit on `main`. Installed again - `@latest` or `@next` - it replaces the one there. `turri --version` says which turri runs, and the pi under it: `turri 0.1.6 (pi 1.3.0)`, and from a clone its commit too.
20
+ The package is `@turri-dev/cli` - npm keeps the name `turri` back, as too like another package's - and the command it puts on your PATH is `turri`. `npm install -g @turri-dev/cli@next` gets the latest prerelease instead, built from the last commit on `main`. Installed again - `@latest` or `@next` - it replaces the one there. `turri --version` says which turri runs, and the [pi](https://pi.dev) under it: `turri 0.1.6 (pi 1.3.0)`, and from a clone its commit too.
21
21
 
22
22
  ## From a clone
23
23
 
@@ -31,7 +31,7 @@ npm link # puts `turri` on your PATH, pointing at this clone
31
31
 
32
32
  A clone runs its TypeScript sources directly - Node strips the types - so edits take effect immediately. The package on npm runs JavaScript compiled from them instead (`npm run build`, into `dist/`, run by `npm pack` and `npm publish` before they pack), as Node runs no `.ts` file inside a `node_modules`. `bin/turri.mjs` runs `src/` where there is one, and `dist/` otherwise.
33
33
 
34
- To update, `git pull` and `npm install` - the second picks up a dependency that changed, pi's say. `npm link` needs running only once. A **turri** already running keeps the code it started with: start it again to run what you pulled.
34
+ To update, `git pull` and `npm install` - the second picks up a dependency that changed, [pi](https://pi.dev)'s say. `npm link` needs running only once. A **turri** already running keeps the code it started with: start it again to run what you pulled.
35
35
 
36
36
  ## In Docker
37
37
 
@@ -43,12 +43,12 @@ It checks, in order, and says exactly what to run for anything missing:
43
43
 
44
44
  | what | why | if it is missing |
45
45
  | --- | --- | --- |
46
- | Node 22.19+ | pi needs 22.19, as does a clone running turri's `.ts` sources directly | install a newer Node |
46
+ | Node 22.19+ | [pi](https://pi.dev) needs 22.19, as does a clone running turri's `.ts` sources directly | install a newer Node |
47
47
  | bash | every command an agent runs, and every testing script, runs with it | on Windows, Git for Windows; elsewhere, the system's package manager |
48
48
  | the OS sandbox | the wall under the command check and the audit | macOS has Seatbelt; on Linux, `apt install bubblewrap`. Where it does not start it says why and how to give it one - user namespaces off (Docker: a user that is not root, `--security-opt seccomp=unconfined`), AppArmor in the way (Docker: `--security-opt apparmor=unconfined`; Ubuntu 24.04: `sysctl -w kernel.apparmor_restrict_unprivileged_userns=0`), Docker's masked `/proc` (`--security-opt systempaths=unconfined`, or nothing: turri binds the container's `/proc` instead). Without one, the check and the audit hold alone |
49
49
  | a model provider | the agents need a model | run `pi` and `/login`, or set an API key (`ANTHROPIC_API_KEY`, `OPENAI_API_KEY`, `GEMINI_API_KEY`, ...) |
50
50
  | `turri` on PATH | so it runs from any project | `npm install -g @turri-dev/cli`, or `npm link` in a clone |
51
- | turri and `pi` apart | `turri` starts pi with turri; a plain `pi` stays pi | an older `turri setup` wrote a file that loads turri into every `pi` - `doctor` offers to remove it |
51
+ | turri and `pi` apart | `turri` starts [pi](https://pi.dev) with turri; a plain `pi` stays [pi](https://pi.dev) | an older `turri setup` wrote a file that loads turri into every `pi` - `doctor` offers to remove it |
52
52
 
53
53
  In a project - a folder with `config.turri.yaml` (or the old `config.yaml`) or `plain_modules` - it checks what the project needs of this machine too:
54
54
 
@@ -56,17 +56,17 @@ In a project - a folder with `config.turri.yaml` (or the old `config.yaml`) or `
56
56
  | --- | --- |
57
57
  | each module's toolchains | what its implementation reqs name - Python, Node, Java, Go, Rust, C/C++, Zig, ... - against this machine's PATH: the agents use this machine's toolchains and install none, so a missing one is yours to install |
58
58
  | the testing scripts | what in them this machine does not have: a program named by its whole path that is not here (a macOS-only `/usr/libexec/java_home` on Linux), a toolchain they run that is not on the PATH |
59
- | the models | each model `config.turri.yaml` names - `harness-model`, `coding-model`, `judge-model`, every role under `models:` - sent one short request through pi, with the credentials turri's agents will use, for any provider pi supports. One that answers is ready; for one that does not, it says what the provider said and what to do: the credentials pi reads for that provider (`AWS_PROFILE` and `AWS_REGION` for Amazon Bedrock, `OPENAI_API_KEY`, `/login`, ...), model access in the Bedrock console, the closest model ids pi knows for one it does not. `--harness-model`, `--coding-model` (`--model`) and `--judge-model` name models as the config's keys, as `turri regenerate` reads them - checked in a project or not. `--no-models` skips it |
59
+ | the models | each model `config.turri.yaml` names - `harness-model`, `coding-model`, `judge-model`, every role under `models:` - sent one short request through [pi](https://pi.dev), with the credentials turri's agents will use, for any provider [pi](https://pi.dev) supports. One that answers is ready; for one that does not, it says what the provider said and what to do: the credentials [pi](https://pi.dev) reads for that provider (`AWS_PROFILE` and `AWS_REGION` for Amazon Bedrock, `OPENAI_API_KEY`, `/login`, ...), model access in the Bedrock console, the closest model ids [pi](https://pi.dev) knows for one it does not. `--harness-model`, `--coding-model` (`--model`) and `--judge-model` name models as the config's keys, as `turri regenerate` reads them - checked in a project or not. `--no-models` skips it |
60
60
 
61
61
  Removing that file is the one thing `doctor` changes, and it asks first; `turri doctor --yes` says yes. Run without a terminal - piped, or in CI - it asks nothing and changes nothing. Run it again whenever something breaks; `turri doctor --no-models` leaves out the models' requests. In the chat, ask for a self check: the `doctor` tool runs the same checks, the models only when you ask. A host - a desktop app - runs the same checks through `doctor` and shows them itself (see [doctor in a host](hosting.md#doctor-in-a-host)).
62
62
 
63
- The chat is told every turn which wall is up and what the project's modules need of this machine that it lacks. What they need is worked out from every spec of the project - seconds, on a project of long requires chains - so it is worked out once the chat is up and again after a turn in which a spec changed, never while your message waits: a turn is told what was known last.
63
+ The chat is told every turn which wall is up and what the project's modules need of this machine that it lacks. What they need is worked out from all the project's \*\*\*plain - seconds, on a project of long requires chains - so it is worked out once the chat is up and again after a turn in which \*\*\*plain changed, never while your message waits: a turn is told what was known last.
64
64
 
65
65
  ## turri and `pi`
66
66
 
67
- `turri` runs pi from this project's `node_modules`, with turri loaded, so no global pi install is needed. A plain `pi` is left as it is: starting pi does not start turri, and turri puts nothing into pi's own folders.
67
+ `turri` runs [pi](https://pi.dev) from this project's `node_modules`, with turri loaded, so no global [pi](https://pi.dev) install is needed. A plain `pi` is left as it is: starting [pi](https://pi.dev) does not start turri, and turri puts nothing into [pi](https://pi.dev)'s own folders.
68
68
 
69
- An older `turri setup` could load turri into every `pi`, with a one-line file in `~/.pi/agent/extensions/` pointing at this clone. `turri doctor` says when it is there, and offers to remove it. Until it is gone, `turri` leaves out its own `-e`: pi treats a tool registered twice as an error.
69
+ An older `turri setup` could load turri into every `pi`, with a one-line file in `~/.pi/agent/extensions/` pointing at this clone. `turri doctor` says when it is there, and offers to remove it. Until it is gone, `turri` leaves out its own `-e`: [pi](https://pi.dev) treats a tool registered twice as an error.
70
70
 
71
71
  `turri` starts in the `turri-dark` theme. A plain `pi` keeps its own theme; to give it `turri-dark` too, in `~/.pi/agent/settings.json`:
72
72
 
@@ -76,18 +76,18 @@ An older `turri setup` could load turri into every `pi`, with a one-line file in
76
76
 
77
77
  ### Project trust
78
78
 
79
- pi will not auto-discover a project-local extension until you trust the project, and `-p` has no way to ask - so `npm run chat` and `npm run ask` pass `-e` explicitly. Once you have run `pi` interactively in this directory and accepted the trust prompt, plain `pi` picks the extension up on its own. A `defaultProjectTrust` key in `.pi/settings.json` does *not* work - a project cannot vouch for itself; that setting only counts in `~/.pi/agent/settings.json`.
79
+ [pi](https://pi.dev) will not auto-discover a project-local extension until you trust the project, and `-p` has no way to ask - so `npm run chat` and `npm run ask` pass `-e` explicitly. Once you have run `pi` interactively in this directory and accepted the trust prompt, plain `pi` picks the extension up on its own. A `defaultProjectTrust` key in `.pi/settings.json` does *not* work - a project cannot vouch for itself; that setting only counts in `~/.pi/agent/settings.json`.
80
80
 
81
81
  ## Environment
82
82
 
83
- Models and credentials come from your pi configuration (`~/.pi/agent`) or provider environment variables - the same resolution `pi` itself uses. Put the rest in your shell profile:
83
+ Models and credentials come from your [pi](https://pi.dev) configuration (`~/.pi/agent`) or provider environment variables - the same resolution `pi` itself uses. Put the rest in your shell profile:
84
84
 
85
85
  ```bash
86
86
  export PLAIN_TEMPLATE_DIRS=~/path/to/standard_template_library # shared templates
87
87
  export GEMINI_API_KEY=... # and leave GOOGLE_API_KEY unset
88
88
  ```
89
89
 
90
- For Gemini, `GEMINI_API_KEY` is what makes pi *offer* the google provider, but when `GOOGLE_API_KEY` is also set pi uses that one for the calls and says so.
90
+ For Gemini, `GEMINI_API_KEY` is what makes [pi](https://pi.dev) *offer* the google provider, but when `GOOGLE_API_KEY` is also set [pi](https://pi.dev) uses that one for the calls and says so.
91
91
 
92
92
  | variable | |
93
93
  | --- | --- |
package/docs/parser.md CHANGED
@@ -12,7 +12,7 @@
12
12
  | `src/plain/files.ts` | `file_utils.open_from` / `get_loaded_templates`, base64 blob detection |
13
13
  | `src/plain/stdlib.ts` | nothing - turri's own: `stdlib/` is a reserved import prefix, read from turri's standard library only, and a project module at such a path is an error (see [the standard library](authoring-plain.md#the-standard-library)) |
14
14
 
15
- ## Checking a spec
15
+ ## Checking \*\*\*plain
16
16
 
17
17
  ```bash
18
18
  turri validate <file.plain> # one spec
@@ -39,7 +39,7 @@ The exit code is 0 only when every file passed. In a conversation the same check
39
39
 
40
40
  ## The functional-spec iterator
41
41
 
42
- `getFrids` walks functionalities depth-first through nested sections; `getSpecificationsForFrid` builds what a single functionality is rendered with. `iterateFunctionalSpecs` pairs them:
42
+ `getFrids` walks functionalities depth-first through nested sections; `getSpecificationsForFrid` builds what a single functionality is regenerated with. `iterateFunctionalSpecs` pairs them:
43
43
 
44
44
  ```ts
45
45
  import { plainFileParser, iterateFunctionalSpecs } from "./src/plain/index.ts";
@@ -55,11 +55,11 @@ for (const { frid, specifications, codeVariables } of iterateFunctionalSpecs(tre
55
55
 
56
56
  ## Parsing once
57
57
 
58
- A module's parse reads its imports and the whole of its `requires` chain, so a long chain asks for the same files over and over: bringing an 18-module chain up to its spec parsed for minutes. Two caches keep it to once. Inside `withParseCache`, one question about the specs, each file is parsed once. Between calls, a parse is kept with a fingerprint of every file directly in its template folders and the current one - name, size, modification time, and a `.plain` file's text - and handed out again, as a copy, while the fingerprint is the same; a spec that does not parse is kept as that too. What a parse returns is unchanged: the cache only decides whether to parse again.
58
+ A module's parse reads its imports and the whole of its `requires` chain, so a long chain asks for the same files over and over: bringing an 18-module chain up to its \*\*\*plain parsed for minutes. Two caches keep it to once. Inside `withParseCache`, one question about \*\*\*plain, each file is parsed once. Between calls, a parse is kept with a fingerprint of every file directly in its template folders and the current one - name, size, modification time, and a `.plain` file's text - and handed out again, as a copy, while the fingerprint is the same; \*\*\*plain that does not parse is kept as that too. What a parse returns is unchanged: the cache only decides whether to parse again.
59
59
 
60
60
  ## Fidelity
61
61
 
62
- The port is checked against the Python implementation directly, not only against the ported assertions. Both parsers are run over a corpus and their module name, marshalled tree, required modules, functionality ids and per-functionality specifications compared:
62
+ The port is checked against the Python implementation directly, not only against the ported assertions. Both parsers are run over a corpus and their module name, marshalled tree, required modules, functionality ids and each functionality's \*\*\*plain compared:
63
63
 
64
64
  | corpus | files | identical | differences |
65
65
  |---|---|---|---|
@@ -68,7 +68,7 @@ The port is checked against the Python implementation directly, not only against
68
68
 
69
69
  The 4 differences are all the same thing: template partials (`implement.plain`, `implement_2.plain`, `header.plain`, `pr_implement.plain`) are meant to be included with arguments, not parsed alone. Both implementations reject them for the same reason - an undefined Liquid variable - but the message text comes from the template engine, and liquidjs phrases it differently from liquid2.
70
70
 
71
- Real specs exposed three places where mdast and mistletoe disagree, each covered by `tests/plain/renderer.test.ts`:
71
+ Real \*\*\*plain exposed three places where mdast and mistletoe disagree, each covered by `tests/plain/renderer.test.ts`:
72
72
 
73
73
  - **Inline decoding.** mdast resolves `\"` to `"` and forgets whether emphasis was written with `_` or `*`; mistletoe round-trips the source. Inline leaf nodes are pinned back to their original source slice at parse time.
74
74
  - **List geometry.** mistletoe indents an item's continuation lines by its `prepend`, measured in coordinates with the enclosing item's indentation stripped - not by the column gap between parent and child. An acceptance test rendered detached from its functionality keeps 6 and 10 spaces where the naive reading gives 4 and 8.