@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
|
@@ -2,79 +2,80 @@
|
|
|
2
2
|
"$schema": "https://raw.githubusercontent.com/earendil-works/pi/main/packages/coding-agent/src/modes/interactive/theme/theme-schema.json",
|
|
3
3
|
"name": "turri-dark",
|
|
4
4
|
"vars": {
|
|
5
|
-
"
|
|
6
|
-
"
|
|
7
|
-
"
|
|
8
|
-
"
|
|
9
|
-
"
|
|
10
|
-
"
|
|
11
|
-
"
|
|
12
|
-
"
|
|
13
|
-
"
|
|
14
|
-
"
|
|
15
|
-
"
|
|
5
|
+
"abyss": "#0a0f1a",
|
|
6
|
+
"blueWhale": "#1e3442",
|
|
7
|
+
"lines": "#22344a",
|
|
8
|
+
"path": "#3e5a6b",
|
|
9
|
+
"grauzone": "#85a3b2",
|
|
10
|
+
"white": "#f4f7f9",
|
|
11
|
+
"siestaTan": "#e9d8c8",
|
|
12
|
+
"pink": "#ff5c8d",
|
|
13
|
+
"pinkHover": "#ff7fa6",
|
|
14
|
+
"neon": "#5ce1e6",
|
|
15
|
+
"neonHover": "#8eebee",
|
|
16
|
+
"orange": "#ff7a3d"
|
|
16
17
|
},
|
|
17
18
|
"colors": {
|
|
18
|
-
"accent": "
|
|
19
|
-
"border": "
|
|
20
|
-
"borderAccent": "
|
|
21
|
-
"borderMuted": "
|
|
22
|
-
"success": "
|
|
23
|
-
"error": "
|
|
24
|
-
"warning": "
|
|
25
|
-
"muted": "
|
|
26
|
-
"dim": "
|
|
27
|
-
"text": "
|
|
28
|
-
"thinkingText": "
|
|
29
|
-
"selectedBg": "
|
|
30
|
-
"scrollbarTrack": "
|
|
31
|
-
"scrollbarThumb": "
|
|
32
|
-
"searchMatchBg": "
|
|
33
|
-
"searchMatchText": "
|
|
19
|
+
"accent": "neon",
|
|
20
|
+
"border": "path",
|
|
21
|
+
"borderAccent": "neon",
|
|
22
|
+
"borderMuted": "lines",
|
|
23
|
+
"success": "pink",
|
|
24
|
+
"error": "orange",
|
|
25
|
+
"warning": "orange",
|
|
26
|
+
"muted": "grauzone",
|
|
27
|
+
"dim": "path",
|
|
28
|
+
"text": "grauzone",
|
|
29
|
+
"thinkingText": "grauzone",
|
|
30
|
+
"selectedBg": "blueWhale",
|
|
31
|
+
"scrollbarTrack": "lines",
|
|
32
|
+
"scrollbarThumb": "path",
|
|
33
|
+
"searchMatchBg": "neon",
|
|
34
|
+
"searchMatchText": "abyss",
|
|
34
35
|
"userMessageBg": "",
|
|
35
|
-
"userMessageText": "
|
|
36
|
+
"userMessageText": "white",
|
|
36
37
|
"customMessageBg": "",
|
|
37
|
-
"customMessageText": "
|
|
38
|
-
"customMessageLabel": "
|
|
38
|
+
"customMessageText": "grauzone",
|
|
39
|
+
"customMessageLabel": "neon",
|
|
39
40
|
"toolPendingBg": "",
|
|
40
41
|
"toolSuccessBg": "",
|
|
41
42
|
"toolErrorBg": "",
|
|
42
|
-
"toolTitle": "
|
|
43
|
-
"toolOutput": "
|
|
44
|
-
"mdHeading": "
|
|
45
|
-
"mdLink": "
|
|
46
|
-
"mdLinkUrl": "
|
|
47
|
-
"mdCode": "
|
|
48
|
-
"mdCodeBlock": "
|
|
49
|
-
"mdCodeBlockBorder": "
|
|
50
|
-
"mdQuote": "
|
|
51
|
-
"mdQuoteBorder": "
|
|
52
|
-
"mdHr": "
|
|
53
|
-
"mdListBullet": "
|
|
54
|
-
"toolDiffAdded": "
|
|
55
|
-
"toolDiffRemoved": "
|
|
56
|
-
"toolDiffContext": "
|
|
57
|
-
"syntaxComment": "
|
|
58
|
-
"syntaxKeyword": "
|
|
59
|
-
"syntaxFunction": "
|
|
60
|
-
"syntaxVariable": "
|
|
61
|
-
"syntaxString": "
|
|
62
|
-
"syntaxNumber": "
|
|
63
|
-
"syntaxType": "
|
|
64
|
-
"syntaxOperator": "
|
|
65
|
-
"syntaxPunctuation": "
|
|
66
|
-
"thinkingOff": "
|
|
67
|
-
"thinkingMinimal": "
|
|
68
|
-
"thinkingLow": "
|
|
69
|
-
"thinkingMedium": "
|
|
70
|
-
"thinkingHigh": "
|
|
71
|
-
"thinkingXhigh": "
|
|
72
|
-
"thinkingMax": "
|
|
73
|
-
"bashMode": "
|
|
43
|
+
"toolTitle": "white",
|
|
44
|
+
"toolOutput": "grauzone",
|
|
45
|
+
"mdHeading": "white",
|
|
46
|
+
"mdLink": "neon",
|
|
47
|
+
"mdLinkUrl": "path",
|
|
48
|
+
"mdCode": "siestaTan",
|
|
49
|
+
"mdCodeBlock": "white",
|
|
50
|
+
"mdCodeBlockBorder": "lines",
|
|
51
|
+
"mdQuote": "grauzone",
|
|
52
|
+
"mdQuoteBorder": "path",
|
|
53
|
+
"mdHr": "lines",
|
|
54
|
+
"mdListBullet": "neon",
|
|
55
|
+
"toolDiffAdded": "neon",
|
|
56
|
+
"toolDiffRemoved": "pink",
|
|
57
|
+
"toolDiffContext": "grauzone",
|
|
58
|
+
"syntaxComment": "path",
|
|
59
|
+
"syntaxKeyword": "pinkHover",
|
|
60
|
+
"syntaxFunction": "neon",
|
|
61
|
+
"syntaxVariable": "white",
|
|
62
|
+
"syntaxString": "siestaTan",
|
|
63
|
+
"syntaxNumber": "pinkHover",
|
|
64
|
+
"syntaxType": "neonHover",
|
|
65
|
+
"syntaxOperator": "grauzone",
|
|
66
|
+
"syntaxPunctuation": "path",
|
|
67
|
+
"thinkingOff": "path",
|
|
68
|
+
"thinkingMinimal": "grauzone",
|
|
69
|
+
"thinkingLow": "siestaTan",
|
|
70
|
+
"thinkingMedium": "neonHover",
|
|
71
|
+
"thinkingHigh": "neon",
|
|
72
|
+
"thinkingXhigh": "pinkHover",
|
|
73
|
+
"thinkingMax": "pink",
|
|
74
|
+
"bashMode": "orange"
|
|
74
75
|
},
|
|
75
76
|
"export": {
|
|
76
|
-
"pageBg": "#
|
|
77
|
-
"cardBg": "#
|
|
78
|
-
"infoBg": "#
|
|
77
|
+
"pageBg": "#0a0f1a",
|
|
78
|
+
"cardBg": "#0d1420",
|
|
79
|
+
"infoBg": "#142030"
|
|
79
80
|
}
|
|
80
|
-
}
|
|
81
|
+
}
|
|
@@ -2,81 +2,79 @@
|
|
|
2
2
|
"$schema": "https://raw.githubusercontent.com/earendil-works/pi/main/packages/coding-agent/src/modes/interactive/theme/theme-schema.json",
|
|
3
3
|
"name": "turri-light",
|
|
4
4
|
"vars": {
|
|
5
|
-
"
|
|
6
|
-
"
|
|
7
|
-
"
|
|
8
|
-
"
|
|
9
|
-
"
|
|
10
|
-
"
|
|
11
|
-
"
|
|
12
|
-
"
|
|
13
|
-
"
|
|
14
|
-
"
|
|
15
|
-
"
|
|
16
|
-
"paleGreen": "#eef7f5",
|
|
17
|
-
"paleGray": "#f4f4f2"
|
|
5
|
+
"abyss": "#0a0f1a",
|
|
6
|
+
"blueWhale": "#1e3442",
|
|
7
|
+
"lines": "#22344a",
|
|
8
|
+
"path": "#3e5a6b",
|
|
9
|
+
"grauzone": "#85a3b2",
|
|
10
|
+
"white": "#f4f7f9",
|
|
11
|
+
"siestaTan": "#e9d8c8",
|
|
12
|
+
"eggplant": "#732553",
|
|
13
|
+
"pink": "#ff5c8d",
|
|
14
|
+
"neon": "#5ce1e6",
|
|
15
|
+
"orange": "#ff7a3d"
|
|
18
16
|
},
|
|
19
17
|
"colors": {
|
|
20
|
-
"accent": "
|
|
21
|
-
"border": "
|
|
22
|
-
"borderAccent": "
|
|
23
|
-
"borderMuted": "
|
|
24
|
-
"success": "
|
|
25
|
-
"error": "
|
|
26
|
-
"warning": "
|
|
27
|
-
"muted": "
|
|
28
|
-
"dim": "
|
|
29
|
-
"text": "
|
|
30
|
-
"thinkingText": "
|
|
31
|
-
"selectedBg": "
|
|
32
|
-
"scrollbarTrack": "
|
|
33
|
-
"scrollbarThumb": "
|
|
34
|
-
"searchMatchBg": "
|
|
35
|
-
"searchMatchText": "
|
|
36
|
-
"userMessageBg": "
|
|
37
|
-
"userMessageText": "
|
|
38
|
-
"customMessageBg": "
|
|
39
|
-
"customMessageText": "
|
|
40
|
-
"customMessageLabel": "
|
|
41
|
-
"toolPendingBg": "
|
|
42
|
-
"toolSuccessBg": "
|
|
43
|
-
"toolErrorBg": "
|
|
44
|
-
"toolTitle": "
|
|
45
|
-
"toolOutput": "
|
|
46
|
-
"mdHeading": "
|
|
47
|
-
"mdLink": "
|
|
48
|
-
"mdLinkUrl": "
|
|
49
|
-
"mdCode": "
|
|
50
|
-
"mdCodeBlock": "
|
|
51
|
-
"mdCodeBlockBorder": "
|
|
52
|
-
"mdQuote": "
|
|
53
|
-
"mdQuoteBorder": "
|
|
54
|
-
"mdHr": "
|
|
55
|
-
"mdListBullet": "
|
|
56
|
-
"toolDiffAdded": "
|
|
57
|
-
"toolDiffRemoved": "
|
|
58
|
-
"toolDiffContext": "
|
|
59
|
-
"syntaxComment": "
|
|
60
|
-
"syntaxKeyword": "
|
|
61
|
-
"syntaxFunction": "
|
|
62
|
-
"syntaxVariable": "
|
|
63
|
-
"syntaxString": "
|
|
64
|
-
"syntaxNumber": "
|
|
65
|
-
"syntaxType": "
|
|
66
|
-
"syntaxOperator": "
|
|
67
|
-
"syntaxPunctuation": "
|
|
68
|
-
"thinkingOff": "
|
|
69
|
-
"thinkingMinimal": "
|
|
70
|
-
"thinkingLow": "
|
|
71
|
-
"thinkingMedium": "
|
|
72
|
-
"thinkingHigh": "
|
|
73
|
-
"thinkingXhigh": "
|
|
74
|
-
"thinkingMax": "
|
|
75
|
-
"bashMode": "
|
|
18
|
+
"accent": "eggplant",
|
|
19
|
+
"border": "path",
|
|
20
|
+
"borderAccent": "eggplant",
|
|
21
|
+
"borderMuted": "grauzone",
|
|
22
|
+
"success": "eggplant",
|
|
23
|
+
"error": "orange",
|
|
24
|
+
"warning": "orange",
|
|
25
|
+
"muted": "path",
|
|
26
|
+
"dim": "grauzone",
|
|
27
|
+
"text": "abyss",
|
|
28
|
+
"thinkingText": "path",
|
|
29
|
+
"selectedBg": "siestaTan",
|
|
30
|
+
"scrollbarTrack": "siestaTan",
|
|
31
|
+
"scrollbarThumb": "path",
|
|
32
|
+
"searchMatchBg": "neon",
|
|
33
|
+
"searchMatchText": "abyss",
|
|
34
|
+
"userMessageBg": "white",
|
|
35
|
+
"userMessageText": "abyss",
|
|
36
|
+
"customMessageBg": "",
|
|
37
|
+
"customMessageText": "abyss",
|
|
38
|
+
"customMessageLabel": "eggplant",
|
|
39
|
+
"toolPendingBg": "",
|
|
40
|
+
"toolSuccessBg": "",
|
|
41
|
+
"toolErrorBg": "",
|
|
42
|
+
"toolTitle": "abyss",
|
|
43
|
+
"toolOutput": "path",
|
|
44
|
+
"mdHeading": "eggplant",
|
|
45
|
+
"mdLink": "blueWhale",
|
|
46
|
+
"mdLinkUrl": "path",
|
|
47
|
+
"mdCode": "eggplant",
|
|
48
|
+
"mdCodeBlock": "abyss",
|
|
49
|
+
"mdCodeBlockBorder": "grauzone",
|
|
50
|
+
"mdQuote": "path",
|
|
51
|
+
"mdQuoteBorder": "grauzone",
|
|
52
|
+
"mdHr": "grauzone",
|
|
53
|
+
"mdListBullet": "eggplant",
|
|
54
|
+
"toolDiffAdded": "blueWhale",
|
|
55
|
+
"toolDiffRemoved": "eggplant",
|
|
56
|
+
"toolDiffContext": "path",
|
|
57
|
+
"syntaxComment": "path",
|
|
58
|
+
"syntaxKeyword": "eggplant",
|
|
59
|
+
"syntaxFunction": "blueWhale",
|
|
60
|
+
"syntaxVariable": "abyss",
|
|
61
|
+
"syntaxString": "lines",
|
|
62
|
+
"syntaxNumber": "eggplant",
|
|
63
|
+
"syntaxType": "blueWhale",
|
|
64
|
+
"syntaxOperator": "path",
|
|
65
|
+
"syntaxPunctuation": "path",
|
|
66
|
+
"thinkingOff": "grauzone",
|
|
67
|
+
"thinkingMinimal": "path",
|
|
68
|
+
"thinkingLow": "lines",
|
|
69
|
+
"thinkingMedium": "blueWhale",
|
|
70
|
+
"thinkingHigh": "eggplant",
|
|
71
|
+
"thinkingXhigh": "pink",
|
|
72
|
+
"thinkingMax": "orange",
|
|
73
|
+
"bashMode": "orange"
|
|
76
74
|
},
|
|
77
75
|
"export": {
|
|
78
|
-
"pageBg": "#
|
|
79
|
-
"cardBg": "#
|
|
80
|
-
"infoBg": "#
|
|
76
|
+
"pageBg": "#f4f7f9",
|
|
77
|
+
"cardBg": "#f4f7f9",
|
|
78
|
+
"infoBg": "#e9d8c8"
|
|
81
79
|
}
|
|
82
|
-
}
|
|
80
|
+
}
|
package/README.md
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
<p align="center"><img src="docs/images/turri-banner.png" alt="turri - coding agent with the power of regenerative software:
|
|
1
|
+
<p align="center"><img src="docs/images/turri-banner.png" alt="turri - the first coding agent with the power of regenerative software, beside a pixel jellyfish: npm install -g @turri-dev/cli"></p>
|
|
2
2
|
|
|
3
3
|
<h1 align="center">turri<br>the first coding agent with the power of<br>regenerative software<br> </h1>
|
|
4
4
|
|
|
@@ -8,19 +8,13 @@
|
|
|
8
8
|
<a href="https://nodejs.org/en/download"><img src="https://img.shields.io/node/v/@turri-dev/cli" alt="Node version"></a>
|
|
9
9
|
</p>
|
|
10
10
|
|
|
11
|
-
You tell **turri** what the system should do
|
|
12
|
-
**turri** builds the code from it. From then on \*\*\*plain is the durable source of truth: the code can always be
|
|
13
|
-
regenerated from it, and healed against it, as it changes.
|
|
11
|
+
**turri** builds regenerative software: what lasts is the system's intent, and the code is derived from it - cheap to throw away and build again. You tell **turri** what the system should do; **turri** writes that down as durable intent, with the tests that say when it is met, and builds the code from it. From then on the durable intent is the source of truth: as it changes, the code is regenerated from it rather than patched in place, and never left to drift from it.
|
|
14
12
|
|
|
15
|
-
**turri** is named after *Turritopsis dohrnii*, the immortal jellyfish that regenerates itself from its young
|
|
16
|
-
form, again and again - as **turri** regenerates the code from \*\*\*plain - see [the name](#the-name).
|
|
13
|
+
**turri** is named after *Turritopsis dohrnii*, the immortal jellyfish that regenerates itself from its young form, again and again - as **turri** regenerates the code from the durable intent - see [the name](#the-name).
|
|
17
14
|
|
|
18
15
|
## Quick start
|
|
19
16
|
|
|
20
|
-
**turri** is built on [pi](https://pi.dev), the coding agent, and runs wherever pi runs: macOS, Linux, WSL; native
|
|
21
|
-
Windows best effort, with Git Bash. You need git, bash and [Node](https://nodejs.org/en/download) 22.19 or newer - a
|
|
22
|
-
Linux distribution's own `nodejs` package is often older. The agents use this machine's toolchains, fenced by a command check and an audit everywhere, and an OS sandbox where the
|
|
23
|
-
OS has one - Seatbelt on macOS, bubblewrap on Linux (`apt install bubblewrap`) - see [installation](docs/installation.md#installation).
|
|
17
|
+
**turri** is built on [pi](https://pi.dev), the coding agent, and runs wherever pi runs: macOS, Linux, WSL; native Windows best effort, with Git Bash. You need git, bash and [Node](https://nodejs.org/en/download) 22.19 or newer - a Linux distribution's own `nodejs` package is often older. The agents use this machine's toolchains, fenced by a command check and an audit everywhere, and an OS sandbox where the OS has one - Seatbelt on macOS, bubblewrap on Linux (`apt install bubblewrap`) - see [installation](docs/installation.md#installation).
|
|
24
18
|
|
|
25
19
|
```bash
|
|
26
20
|
npm install -g @turri-dev/cli # puts `turri` on your PATH
|
|
@@ -29,11 +23,7 @@ turri doctor # checks the machine
|
|
|
29
23
|
|
|
30
24
|
To follow `main` as it moves, or work on turri itself, run it [from a clone](#from-a-clone) instead.
|
|
31
25
|
|
|
32
|
-
`doctor` checks for Node 22.19+, bash, the OS sandbox and a model provider for pi; in a project, the toolchains its
|
|
33
|
-
modules need, what its testing scripts run against this machine, and that each model `config.turri.yaml` names
|
|
34
|
-
answers with your credentials. It changes nothing without asking: when a check fails - the OS sandbox does not start,
|
|
35
|
-
say - it says why, and the command for you to run. Run it again whenever something breaks. What each check means:
|
|
36
|
-
[installation](docs/installation.md).
|
|
26
|
+
`doctor` checks for Node 22.19+, bash, the OS sandbox and a model provider for pi; in a project, the toolchains its modules need, what its testing scripts run against this machine, and that each model `config.turri.yaml` names answers with your credentials. It changes nothing without asking: when a check fails - the OS sandbox does not start, say - it says why, and the command for you to run. Run it again whenever something breaks. What each check means: [installation](docs/installation.md).
|
|
37
27
|
|
|
38
28
|
Then start it in your project, signed in to your model providers:
|
|
39
29
|
|
|
@@ -44,26 +34,20 @@ export ANTHROPIC_API_KEY=... # the key it names - or skip it, and type /login
|
|
|
44
34
|
turri
|
|
45
35
|
```
|
|
46
36
|
|
|
47
|
-
`turri init-config` asks which vendor's models you use and writes the project's `config.turri.yaml` with two of theirs - a
|
|
48
|
-
capable one you talk to, which writes \*\*\*plain and plans the work, and a smaller, cheaper one that writes the code.
|
|
49
|
-
For Anthropic:
|
|
37
|
+
`turri init-config` asks which vendor's models you use and writes the project's `config.turri.yaml` with two of theirs - a capable one you talk to, which writes the durable intent and plans the work, and a smaller, cheaper one that writes the code. For Anthropic:
|
|
50
38
|
|
|
51
39
|
```yaml
|
|
52
|
-
harness-model: anthropic/claude-opus-5-5:medium # you talk to it
|
|
40
|
+
harness-model: anthropic/claude-opus-5-5:medium # you talk to it
|
|
53
41
|
coding-model: anthropic/claude-haiku-5-5:low # it writes the code
|
|
54
42
|
```
|
|
55
43
|
|
|
56
|
-
To skip the question, name the vendor - `anthropic`, `openai`, `google`, `amazon-bedrock` (with `--maker` and
|
|
57
|
-
`--region`) or `other`:
|
|
44
|
+
To skip the question, name the vendor - `anthropic`, `openai`, `google`, `amazon-bedrock` (with `--maker` and `--region`) or `other`:
|
|
58
45
|
|
|
59
46
|
```bash
|
|
60
47
|
turri init-config --vendor anthropic
|
|
61
48
|
```
|
|
62
49
|
|
|
63
|
-
It then tells you which API key to set - or to type `/login` once **turri** is running instead. **turri** loads the
|
|
64
|
-
`config.turri.yaml` in the folder you start it from.
|
|
65
|
-
Below the two models, the file sets every other setting to its default - change any of them in the file, or from the
|
|
66
|
-
chat with `/turri-config`. Any other model works too: [models](#models).
|
|
50
|
+
It then tells you which API key to set - or to type `/login` once **turri** is running instead. **turri** loads the `config.turri.yaml` in the folder you start it from. Below the two models, the file sets every other setting to its default - change any of them in the file, or from the chat with `/turri-config`. Any other model works too: [models](#models).
|
|
67
51
|
|
|
68
52
|
Once `turri` is running, say: *Let's start a new project: a small API where people can register and sign in.*
|
|
69
53
|
|
|
@@ -91,91 +75,44 @@ git pull
|
|
|
91
75
|
npm install # picks up any dependency that changed
|
|
92
76
|
```
|
|
93
77
|
|
|
94
|
-
A **turri** already running keeps the code it started with - start it again to run what you pulled. More in
|
|
95
|
-
[installation](docs/installation.md#from-a-clone).
|
|
78
|
+
A **turri** already running keeps the code it started with - start it again to run what you pulled. More in [installation](docs/installation.md#from-a-clone).
|
|
96
79
|
|
|
97
80
|
## Why
|
|
98
81
|
|
|
99
|
-
|
|
100
|
-
defining what the system should do. Agents can fix bugs, ask questions and keep getting more
|
|
101
|
-
capable - but they still cannot read your mind. The question is not only whether an agent can
|
|
102
|
-
write the code, but whether it understands what it is building.
|
|
82
|
+
Software has always been maintained: written once, then patched for as long as it lives and everything learnt while building it lived only in the code. Coding agents code in minutes what took a team weeks, and they get better at it with every model, so code is now cheap and a disposable asset. It no longer has to be maintained - it can be regenerated. What has to last instead is the intent: what the system should do, and the tests that say whether it does. Get that right and the code is replaceable. Get it wrong and no agent, however capable, can guess what you meant.
|
|
103
83
|
|
|
104
|
-
Code that is patched, prompt after prompt, drifts: every misunderstanding stays in it, and the
|
|
105
|
-
next change is made on top. When the software can always be regenerated from durable information
|
|
106
|
-
instead, that understanding is written down - explicit, reviewable and tested - and it evolves with
|
|
107
|
-
the software rather than against it.
|
|
84
|
+
Code that is patched, prompt after prompt, drifts: every misunderstanding stays in it, and the next change is made on top. When the software can always be regenerated from durable information instead, that understanding is written down - explicit, reviewable and tested - and it evolves with the software rather than against it.
|
|
108
85
|
|
|
109
86
|
## How it differs from ye old coding agent
|
|
110
87
|
|
|
111
|
-
With a coding agent you work on code: you ask for a change, it edits the code, and you review the
|
|
112
|
-
code it wrote.
|
|
88
|
+
With a coding agent you work on code: you ask for a change, it edits the code, and you review the code it wrote.
|
|
113
89
|
|
|
114
|
-
With **turri** you work on
|
|
115
|
-
and can always regenerate the code from that. You don't review the code or keep it - you review and
|
|
116
|
-
keep the intent: what the software must do, and what must hold as it changes. \*\*\*plain is the
|
|
117
|
-
durable part. The code is a disposable artefact, rebuilt from it whenever it changes.
|
|
90
|
+
With **turri** you work on the durable intent. You say what the software must do, and **turri** updates durable intent and can always regenerate the code from that. You don't review the code or keep it - you review and keep the intent: what the software must do, and what must hold as it changes. The code is a disposable artefact, rebuilt from it whenever it changes.
|
|
118
91
|
|
|
119
92
|
| | ye old coding agent | **turri** |
|
|
120
93
|
| --- | --- | --- |
|
|
121
|
-
| **What you maintain** | the code, patched prompt after prompt |
|
|
122
|
-
| **
|
|
123
|
-
| **
|
|
124
|
-
| **
|
|
125
|
-
| **What
|
|
126
|
-
| **
|
|
127
|
-
| **When it gets stuck** | it keeps
|
|
128
|
-
| **A change** | another patch on top | a change to \*\*\*plain: what it touches is rebuilt, everything built before is tested again, and code that disagrees with \*\*\*plain is healed to match |
|
|
129
|
-
| **History** | whatever you commit | every build, regeneration and repair is a commit; a build interrupted halfway starts again from the last one |
|
|
94
|
+
| **What you maintain** | the code, patched prompt after prompt | the durable intent |
|
|
95
|
+
| **What gets built, in what order** | whatever the agent decides, as it goes | the code is built from the durable intent step by step, in a fixed order, so no intent is skipped |
|
|
96
|
+
| **Who writes the code** | the agent, and it decides everything else too | the agent - **turri** decides what it builds, the agent only how, line by line |
|
|
97
|
+
| **How it works** | improvised, differently every time | a developer workflow baked in - build, unit test, review, conformance test, regression test, commit - the same every time |
|
|
98
|
+
| **What counts as done** | the agent says so | every unit of intent is tested and validated by **turri** itself: all its tests pass, or the work goes back |
|
|
99
|
+
| **Tests** | written and changed by the agent that writes the code | written from the durable intent, apart from the code; the agent writing the code cannot change them |
|
|
100
|
+
| **When it gets stuck** | it keeps going, or quietly works around the problem | it stops and tells you which intent to clarify |
|
|
130
101
|
|
|
131
102
|
## How it works
|
|
132
103
|
|
|
133
|
-
|
|
104
|
+
**turri** captures the durable intent in [\*\*\*plain](https://plainlang.org/), a language for saying what software should do. \*\*\*plain breaks the intent down into functionalities - small units, each a single thing the software does - and **turri** regenerates the code from them piece by piece.
|
|
134
105
|
|
|
135
|
-
1. **Define.** Write \*\*\*plain with **turri
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
before it, into `plain_modules/` - and builds each answer in the background while the interview
|
|
140
|
-
goes on.
|
|
141
|
-
3. **Validate.** The harness runs the unit tests, then conformance tests written from \*\*\*plain,
|
|
142
|
-
then everything built so far, and moves on only when all of it passes.
|
|
143
|
-
4. **Regenerate.** To change the system, change its definition. The functionalities whose \*\*\*plain
|
|
144
|
-
changed are rebuilt, and everything built before is tested again.
|
|
106
|
+
1. **Define.** Write \*\*\*plain with **turri**
|
|
107
|
+
2. **Review and refine.** You review \*\*\*plain and change it with **turri** until it says what you mean.
|
|
108
|
+
3. **Regenerate.** Agents write the code; **turri** decides what they write and when, step by step, the same way every time.
|
|
109
|
+
4. **Validate.** Agents write conformance tests from \*\*\*plain; **turri** runs them, and keeps the code only when it does what \*\*\*plain says.
|
|
145
110
|
|
|
146
|
-
A bug is fixed in \*\*\*plain; a new behaviour goes into \*\*\*plain; and the next regeneration carries
|
|
147
|
-
it. When a build is done, ask to try it: **turri** puts what is built in `dist/<module>` and
|
|
148
|
-
starts it on your machine - an app, and it tells you where to open your browser.
|
|
149
|
-
|
|
150
|
-
\*\*\*plain looks like this.
|
|
151
|
-
|
|
152
|
-
```plain
|
|
153
|
-
***definitions***
|
|
154
|
-
|
|
155
|
-
- :User: is a person with an account: an email address and a password.
|
|
156
|
-
|
|
157
|
-
***implementation reqs***
|
|
158
|
-
|
|
159
|
-
- :Implementation: is written in Python 3.12 with FastAPI.
|
|
160
|
-
|
|
161
|
-
***functional specs***
|
|
162
|
-
|
|
163
|
-
- A new :User: can register with an email address and a password.
|
|
164
|
-
- Registering with an email address already in use fails with status 400.
|
|
165
|
-
|
|
166
|
-
- A registered :User: can sign in and receives a bearer token.
|
|
167
|
-
```
|
|
168
|
-
|
|
169
|
-
Each item under `***functional specs***` is one functionality, built on top of the ones before it.
|
|
170
|
-
|
|
171
|
-
**turri** runs as an extension to [pi](https://github.com/earendil-works/pi), so you work with it
|
|
172
|
-
in a conversation, and as a command line for unattended runs.
|
|
111
|
+
These are not phases, one after the other: you don't spend hours writing \*\*\*plain and then hours waiting for the code. You go round the loop in small steps, in conversation with **turri** - while you refine the next functionality, the one before it is already being regenerated and validated. A bug is fixed in \*\*\*plain; a new behaviour goes into \*\*\*plain; and the next regeneration carries it. Ask to try it at any time: **turri** puts what is built in `dist` and starts it on your machine - an app, and it tells you where to open your browser.
|
|
173
112
|
|
|
174
113
|
## The name
|
|
175
114
|
|
|
176
|
-
**turri** is short for [*Turritopsis dohrnii*](https://en.wikipedia.org/wiki/Turritopsis_dohrnii), the immortal
|
|
177
|
-
jellyfish, which, when injured or old, turns back into its young self and regenerates - the same jellyfish, from the
|
|
178
|
-
same genes, again and again.
|
|
115
|
+
**turri** is short for [*Turritopsis dohrnii*](https://en.wikipedia.org/wiki/Turritopsis_dohrnii), the immortal jellyfish, which, when injured or old, turns back into its young self and regenerates - the same jellyfish, from the same genes, again and again.
|
|
179
116
|
|
|
180
117
|
That is what regenerative software asks of software, and what **turri** does:
|
|
181
118
|
|
|
@@ -186,23 +123,11 @@ That is what regenerative software asks of software, and what **turri** does:
|
|
|
186
123
|
| Every cell can become another, and it is still the same jellyfish. | Every line of code can be replaced, and it is still the same software - because what it is never lived in the code. |
|
|
187
124
|
| It can do it again and again, for as long as it lives. | The code can be regenerated whenever \*\*\*plain changes or a model gets better, for as long as \*\*\*plain is kept. |
|
|
188
125
|
|
|
189
|
-
So the tools speak its language: **`regenerate`** regenerates the code from \*\*\*plain as it is now - or the functionalities
|
|
190
|
-
you name, though nothing changed, or all of it from scratch - **`drift`** says how far the code has moved from it, and
|
|
191
|
-
**`lineage`** shows every generation of a module and what each was regenerated from.
|
|
126
|
+
So the tools speak its language: **`regenerate`** regenerates the code from \*\*\*plain as it is now - or the functionalities you name, though nothing changed, or all of it from scratch - **`drift`** says how far the code has moved from it, and **`lineage`** shows every generation of a module and what each was regenerated from.
|
|
192
127
|
|
|
193
128
|
## Models
|
|
194
129
|
|
|
195
|
-
`init-config`'s models are only a starting point. **turri** is built on [pi](https://github.com/earendil-works/pi),
|
|
196
|
-
so any model pi supports works - Anthropic, OpenAI, Google, Amazon Bedrock, OpenRouter, a local one. A model is reached
|
|
197
|
-
as pi reaches it - `/login`, in `turri` as in `pi`, the provider's API key in the environment (`ANTHROPIC_API_KEY`,
|
|
198
|
-
`OPENAI_API_KEY`, `GEMINI_API_KEY`, ...), or a cloud account - and named as pi names it, `provider/model-id`, with
|
|
199
|
-
`:high`, `:low` and so on for how hard it thinks. It uses three: the **harness** model you talk
|
|
200
|
-
to, which writes \*\*\*plain and plans the work - worth a capable one - and the **coding** and
|
|
201
|
-
**judge** models its agents build and judge with, which can be smaller and cheaper, such as GPT-6
|
|
202
|
-
Luna or Gemini 3.1 Flash Lite. `turri --harness-model` and `--coding-model` choose them for a
|
|
203
|
-
session, and pi's `/model` switches the one you talk to as you go; to keep them for the project,
|
|
204
|
-
set them with `/turri-config harness-model`, `/turri-config coding-model` and so on - each role's too, as
|
|
205
|
-
`models.<role>` - or write them in its `config.turri.yaml`:
|
|
130
|
+
`init-config`'s models are only a starting point. **turri** is built on [pi](https://github.com/earendil-works/pi), so any model pi supports works - Anthropic, OpenAI, Google, Amazon Bedrock, OpenRouter, a local one. A model is reached as pi reaches it - `/login`, in `turri` as in `pi`, the provider's API key in the environment (`ANTHROPIC_API_KEY`, `OPENAI_API_KEY`, `GEMINI_API_KEY`, ...), or a cloud account - and named as pi names it, `provider/model-id`, with `:high`, `:low` and so on for how hard it thinks. It uses three: the **harness** model you talk to, which writes \*\*\*plain and plans the work - worth a capable one - and the **coding** and **judge** models its agents build and judge with, which can be smaller and cheaper, such as GPT-6 Luna or Gemini 3.1 Flash Lite. `turri --harness-model` and `--coding-model` choose them for a session, and pi's `/model` switches the one you talk to as you go; to keep them for the project, set them with `/turri-config harness-model`, `/turri-config coding-model` and so on - each role's too, as `models.<role>` - or write them in its `config.turri.yaml`:
|
|
206
131
|
|
|
207
132
|
```yaml
|
|
208
133
|
harness-model: anthropic/claude-opus-5-5 # the model you talk to: a capable one
|
|
@@ -210,8 +135,7 @@ coding-model: openai/gpt-6-luna # writes the code and the tests: a s
|
|
|
210
135
|
judge-model: google/gemini-3.1-flash-lite # judges the conformance runs
|
|
211
136
|
```
|
|
212
137
|
|
|
213
|
-
One left out is the one before it: judge from coding, coding from harness. Every way to set them:
|
|
214
|
-
[models](docs/config.md#models).
|
|
138
|
+
One left out is the one before it: judge from coding, coding from harness. Every way to set them: [models](docs/config.md#models).
|
|
215
139
|
|
|
216
140
|
## Use
|
|
217
141
|
|
|
@@ -226,24 +150,15 @@ Then talk to it:
|
|
|
226
150
|
|
|
227
151
|
> Let's start a new project: a small API where people can register and sign in.
|
|
228
152
|
|
|
229
|
-
It runs the interview skill, asks you about the problem, the stack and the product, writes
|
|
230
|
-
\*\*\*plain, and builds each functionality as it is written. While it works:
|
|
153
|
+
It runs the interview skill, asks you about the problem, the stack and the product, writes \*\*\*plain, and builds each functionality as it is written. While it works:
|
|
231
154
|
|
|
232
|
-
- the **panel** above the input shows every build - its stage, what its agents are doing, its
|
|
233
|
-
|
|
234
|
-
- ask to try it at any time - "let me try it" - and **`release`** puts what is built so far in
|
|
235
|
-
`dist/<module>` and **`activate`** starts it, installing what it needs - nothing to approve;
|
|
155
|
+
- the **panel** above the input shows every build - its stage, what its agents are doing, its model and cost - and the queue behind it;
|
|
156
|
+
- ask to try it at any time - "let me try it" - and **`release`** puts what is built so far in `dist/<module>` and **`activate`** starts it, installing what it needs - nothing to approve;
|
|
236
157
|
- the **side panel** (`ctrl+h`) takes the screen and opens on **regen** - \*\*\*plain, every item marked planned, working, regenerated, validating, conform or needs you - and `p` turns it to the **pulses** (`/pulses`) - every pulse, running, queued and finished, and what each regenerates; what its agents did is in each pulse's log in `.turri/jobs/`;
|
|
237
|
-
- **`/halt`** halts a pulse, **`/lineage`** shows every generation of a
|
|
238
|
-
|
|
239
|
-
- **`/
|
|
240
|
-
|
|
241
|
-
- **`/turri-config`** changes any setting of the project's `config.turri.yaml` - the models, review, conformance tests,
|
|
242
|
-
how many pulses at once - and says when it takes effect: now, at your next message, or at the next pulse. No
|
|
243
|
-
restart: `/turri-config review false`, or `/turri-config` alone to pick from the list;
|
|
244
|
-
- **`/stack`** chooses the stack to build with, in a project whose backend and frontend each have their own testing
|
|
245
|
-
scripts in `config.turri.<stack>.yaml` - `/stack backend`, `/stack none` - for the session (`--stack <name>` on the
|
|
246
|
-
command line).
|
|
158
|
+
- **`/halt`** halts a pulse, **`/lineage`** shows every generation of a module, and the **`drift`** tool says what is left to regenerate;
|
|
159
|
+
- **`/btw <question>`** asks turri something on the side - answered at once, even in the middle of a skill's interview (typed as the answer, under "Something else…"), and left out of the conversation;
|
|
160
|
+
- **`/turri-config`** changes any setting of the project's `config.turri.yaml` - the models, review, conformance tests, how many pulses at once - and says when it takes effect: now, at your next message, or at the next pulse. No restart: `/turri-config review false`, or `/turri-config` alone to pick from the list;
|
|
161
|
+
- **`/stack`** chooses the stack to build with, in a project whose backend and frontend each have their own testing scripts in `config.turri.<stack>.yaml` - `/stack backend`, `/stack none` - for the session (`--stack <name>` on the command line).
|
|
247
162
|
|
|
248
163
|
Other things to ask for:
|
|
249
164
|
|
|
@@ -253,9 +168,7 @@ Other things to ask for:
|
|
|
253
168
|
>
|
|
254
169
|
> Regenerate changes to \*\*\*plain with a faster model.
|
|
255
170
|
|
|
256
|
-
The last one holds for the rest of the session; the model can be chosen separately for changes to
|
|
257
|
-
\*\*\*plain and for functionalities, and a name that fits more than one model is asked about rather
|
|
258
|
-
than guessed.
|
|
171
|
+
The last one holds for the rest of the session; the model can be chosen separately for changes to \*\*\*plain and for functionalities, and a name that fits more than one model is asked about rather than guessed.
|
|
259
172
|
|
|
260
173
|
Without a conversation, the same work is on the command line:
|
|
261
174
|
|
|
@@ -266,8 +179,7 @@ turri regenerate app.plain # regenerate the code from ***plain: planned int
|
|
|
266
179
|
turri regenerate app.plain 3 # regenerate functionality 3, changed or not
|
|
267
180
|
```
|
|
268
181
|
|
|
269
|
-
More: [using **turri**](docs/using.md); to render \*\*\*plain overnight, see
|
|
270
|
-
[running unattended](docs/headless.md).
|
|
182
|
+
More: [using **turri**](docs/using.md); to render \*\*\*plain overnight, see [running unattended](docs/headless.md).
|
|
271
183
|
|
|
272
184
|
## Documentation
|
|
273
185
|
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|