@turri-dev/cli 0.0.0-stage → 0.1.2-next.48dacfc
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 +80 -0
- package/.pi/themes/turri-light.json +82 -0
- package/LICENSE +21 -0
- package/README.md +272 -2
- 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/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 +252 -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/assets/jellyfish/light-12.png +0 -0
- package/assets/jellyfish/light-13.png +0 -0
- package/assets/jellyfish/light-14.png +0 -0
- package/bin/turri.mjs +29 -0
- package/dist/ask.js +149 -0
- package/dist/brand.js +50 -0
- package/dist/btw.js +174 -0
- package/dist/chat-models.js +37 -0
- package/dist/chat-skills.js +18 -0
- package/dist/cli.js +178 -0
- package/dist/config-command.js +197 -0
- package/dist/config-edit.js +367 -0
- package/dist/config.js +489 -0
- package/dist/conform-cli.js +29 -0
- package/dist/cultivate-cli.js +110 -0
- package/dist/drift-cli.js +25 -0
- package/dist/environment.js +70 -0
- package/dist/extension.js +2372 -0
- package/dist/genome.js +301 -0
- package/dist/graph.js +246 -0
- package/dist/identity.js +35 -0
- package/dist/init-config.js +511 -0
- package/dist/judge.js +62 -0
- package/dist/lineage-cli.js +13 -0
- package/dist/loop-cli.js +132 -0
- package/dist/loop-tools.js +225 -0
- package/dist/mature-tools.js +193 -0
- package/dist/model-check.js +117 -0
- package/dist/module-report.js +9 -0
- package/dist/pi-launch.js +31 -0
- package/dist/pi.js +813 -0
- package/dist/plain/check.js +76 -0
- package/dist/plain/concepts.js +213 -0
- package/dist/plain/errors.js +43 -0
- package/dist/plain/files.js +57 -0
- package/dist/plain/highlight.js +195 -0
- package/dist/plain/index.js +15 -0
- package/dist/plain/liquid.js +129 -0
- package/dist/plain/markdown.js +208 -0
- package/dist/plain/parser.js +752 -0
- package/dist/plain/plain.tmLanguage.json +124 -0
- package/dist/plain/spec.js +291 -0
- package/dist/plain/stdlib.js +44 -0
- package/dist/question-dialog.js +125 -0
- package/dist/questioning.js +109 -0
- package/dist/quiet.js +125 -0
- package/dist/regenerate/activity.js +187 -0
- package/dist/regenerate/agent-env.js +190 -0
- package/dist/regenerate/agent-shell.js +114 -0
- package/dist/regenerate/arbiter.js +133 -0
- package/dist/regenerate/audit.js +203 -0
- package/dist/regenerate/cases.js +83 -0
- package/dist/regenerate/change-view.js +102 -0
- package/dist/regenerate/choose-conformance.js +117 -0
- package/dist/regenerate/chunk-plan.js +625 -0
- package/dist/regenerate/codebase.js +75 -0
- package/dist/regenerate/command-check.js +312 -0
- package/dist/regenerate/compaction.js +20 -0
- package/dist/regenerate/confine.js +310 -0
- package/dist/regenerate/conform.js +133 -0
- package/dist/regenerate/conformance-agents.js +955 -0
- package/dist/regenerate/conformance.js +936 -0
- package/dist/regenerate/conversation-writes.js +100 -0
- package/dist/regenerate/credentials.js +88 -0
- package/dist/regenerate/debug-log.js +228 -0
- package/dist/regenerate/debugger.js +90 -0
- package/dist/regenerate/delivery.js +19 -0
- package/dist/regenerate/diagnose-job.js +40 -0
- package/dist/regenerate/diagnose.js +81 -0
- package/dist/regenerate/diff-view.js +240 -0
- package/dist/regenerate/drift.js +194 -0
- package/dist/regenerate/engine.js +118 -0
- package/dist/regenerate/environment-error.js +220 -0
- package/dist/regenerate/job-log.js +102 -0
- package/dist/regenerate/job-panel.js +336 -0
- package/dist/regenerate/jobs-tree.js +300 -0
- package/dist/regenerate/jobs.js +427 -0
- package/dist/regenerate/lanes.js +32 -0
- package/dist/regenerate/lineage.js +384 -0
- package/dist/regenerate/loop.js +1435 -0
- package/dist/regenerate/masking.js +95 -0
- package/dist/regenerate/notes.js +397 -0
- package/dist/regenerate/os-sandbox.js +243 -0
- package/dist/regenerate/paths.js +165 -0
- package/dist/regenerate/plain-palette.js +83 -0
- package/dist/regenerate/prompt.js +704 -0
- package/dist/regenerate/records.js +294 -0
- package/dist/regenerate/regenerate.js +598 -0
- package/dist/regenerate/regression.js +181 -0
- package/dist/regenerate/release.js +262 -0
- package/dist/regenerate/requires.js +241 -0
- package/dist/regenerate/resources.js +164 -0
- package/dist/regenerate/self-check.js +111 -0
- package/dist/regenerate/services.js +155 -0
- package/dist/regenerate/shell.js +320 -0
- package/dist/regenerate/side-panel.js +278 -0
- package/dist/regenerate/spec-map-view.js +574 -0
- package/dist/regenerate/spec-map.js +561 -0
- package/dist/regenerate/spec-steps.js +527 -0
- package/dist/regenerate/state.js +10 -0
- package/dist/regenerate/steer.js +91 -0
- package/dist/regenerate/steering.js +119 -0
- package/dist/regenerate/stop-report.js +161 -0
- package/dist/regenerate/submit-work.js +71 -0
- package/dist/regenerate/test-kinds.js +124 -0
- package/dist/regenerate/test-scripts.js +695 -0
- package/dist/regenerate/testing.js +406 -0
- package/dist/regenerate/transcript-view.js +1 -0
- package/dist/regenerate/unit-gate.js +20 -0
- package/dist/regenerate/unit-review.js +347 -0
- package/dist/regenerate/web.js +256 -0
- package/dist/regenerate/workspace.js +99 -0
- package/dist/regenerate-cli.js +68 -0
- package/dist/release-agent.js +114 -0
- package/dist/release-cli.js +131 -0
- package/dist/release-tools.js +148 -0
- package/dist/review/live.js +165 -0
- package/dist/rules.js +47 -0
- package/dist/self-invocation.js +110 -0
- package/dist/setup.js +245 -0
- package/dist/skill-progress.js +78 -0
- package/dist/skill.js +149 -0
- package/dist/skills.js +74 -0
- package/dist/spec-diff-cli.js +37 -0
- package/dist/spec-tools.js +155 -0
- package/dist/stack.js +158 -0
- package/dist/stacks.js +97 -0
- package/dist/stdlib.js +100 -0
- package/dist/terminal-images.js +46 -0
- package/dist/tools.js +242 -0
- package/dist/validate-cli.js +52 -0
- package/docs/README.md +58 -0
- package/docs/authoring-plain.md +245 -0
- package/docs/config.md +353 -0
- package/docs/deploy.md +109 -0
- package/docs/development.md +88 -0
- package/docs/headless.md +148 -0
- package/docs/images/how-turri-works.svg +50 -0
- package/docs/images/turri-banner.png +0 -0
- package/docs/installation.md +119 -0
- package/docs/parser.md +108 -0
- package/docs/regenerating.md +1116 -0
- package/docs/sandbox.md +233 -0
- package/docs/skills-and-gates.md +254 -0
- package/docs/theming.md +76 -0
- package/docs/using.md +454 -0
- package/genome/rules/bullet-continuation.md +69 -0
- package/genome/rules/concise-specs-examples.md +431 -0
- package/genome/rules/concise-specs-integration-examples.md +270 -0
- package/genome/rules/concise-specs.md +80 -0
- package/genome/rules/definitions.md +107 -0
- package/genome/rules/examples/integration-embedded-testing/run_conformance_tests_java.sh +163 -0
- package/genome/rules/examples/integration-embedded-testing/run_unittests_java.sh +51 -0
- package/genome/rules/exported-concepts.md +39 -0
- package/genome/rules/func-specs.md +129 -0
- package/genome/rules/impl-reqs.md +68 -0
- package/genome/rules/import-modules.md +48 -0
- package/genome/rules/integration-embedded-testing.md +276 -0
- package/genome/rules/integration-embedded.md +171 -0
- package/genome/rules/integration-standalone.md +135 -0
- package/genome/rules/integrations.md +137 -0
- package/genome/rules/linked-resources.md +69 -0
- package/genome/rules/module-structure.md +105 -0
- package/genome/rules/project-model.md +88 -0
- package/genome/rules/required-concepts.md +44 -0
- package/genome/rules/requires-modules.md +80 -0
- package/genome/rules/stdlib.md +73 -0
- package/genome/rules/test-reqs.md +57 -0
- package/genome/skills/add-acceptance-test/SKILL.md +100 -0
- package/genome/skills/add-concept/SKILL.md +71 -0
- package/genome/skills/add-functional-spec/SKILL.md +84 -0
- package/genome/skills/add-functional-specs/SKILL.md +118 -0
- package/genome/skills/add-implementation-requirement/SKILL.md +86 -0
- package/genome/skills/add-resource/SKILL.md +105 -0
- package/genome/skills/add-template/SKILL.md +64 -0
- package/genome/skills/add-test-requirement/SKILL.md +73 -0
- package/genome/skills/analyze-2-func-specs/SKILL.md +101 -0
- package/genome/skills/analyze-func-specs/SKILL.md +123 -0
- package/genome/skills/analyze-if-func-spec-too-complex/SKILL.md +211 -0
- package/genome/skills/break-down-func-spec/SKILL.md +205 -0
- package/genome/skills/brood/SKILL.md +229 -0
- package/genome/skills/brood/references/intent.md +35 -0
- package/genome/skills/brood/references/product.md +101 -0
- package/genome/skills/brood/references/stack.md +61 -0
- package/genome/skills/brood/references/testing.md +56 -0
- package/genome/skills/bud/SKILL.md +148 -0
- package/genome/skills/bud/references/checklist.md +44 -0
- package/genome/skills/bud/references/intent.md +30 -0
- package/genome/skills/check-plain-env/SKILL.md +285 -0
- package/genome/skills/consolidate-concepts/SKILL.md +192 -0
- package/genome/skills/create-import-module/SKILL.md +104 -0
- package/genome/skills/create-requires-module/SKILL.md +109 -0
- package/genome/skills/debug-specs/SKILL.md +188 -0
- package/genome/skills/implement-conformance-testing-script/SKILL.md +238 -0
- package/genome/skills/implement-conformance-testing-script/assets/run_conformance_tests_cypress.ps1 +337 -0
- package/genome/skills/implement-conformance-testing-script/assets/run_conformance_tests_golang.ps1 +111 -0
- package/genome/skills/implement-conformance-testing-script/assets/run_conformance_tests_java.sh +136 -0
- package/genome/skills/implement-conformance-testing-script/assets/run_conformance_tests_python.ps1 +103 -0
- package/genome/skills/implement-conformance-testing-script/assets/run_conformance_tests_python.sh +150 -0
- package/genome/skills/implement-unit-testing-script/SKILL.md +160 -0
- package/genome/skills/implement-unit-testing-script/assets/run_unittests_flutter.ps1 +87 -0
- package/genome/skills/implement-unit-testing-script/assets/run_unittests_golang.ps1 +73 -0
- package/genome/skills/implement-unit-testing-script/assets/run_unittests_java.sh +72 -0
- package/genome/skills/implement-unit-testing-script/assets/run_unittests_python.ps1 +81 -0
- package/genome/skills/implement-unit-testing-script/assets/run_unittests_python.sh +98 -0
- package/genome/skills/implement-unit-testing-script/assets/run_unittests_react.ps1 +87 -0
- package/genome/skills/init-plain-project/SKILL.md +117 -0
- package/genome/skills/init-plain-project/references/checklist.md +30 -0
- package/genome/skills/mature/SKILL.md +126 -0
- package/genome/skills/refactor-module/SKILL.md +196 -0
- package/genome/skills/resolve-section-ownership/SKILL.md +64 -0
- package/genome/skills/resolve-spec-conflict/SKILL.md +96 -0
- package/genome/skills/spawn/SKILL.md +163 -0
- package/package.json +68 -4
- package/stdlib/backend/common.plain +25 -0
- package/stdlib/backend/conformance/common.plain +12 -0
- package/stdlib/backend/conformance/go-gin.plain +9 -0
- package/stdlib/backend/conformance/go-nethttp.plain +9 -0
- package/stdlib/backend/conformance/java-springboot.plain +9 -0
- package/stdlib/backend/conformance/python-django.plain +9 -0
- package/stdlib/backend/conformance/python-fastapi.plain +9 -0
- package/stdlib/backend/conformance/python-flask.plain +9 -0
- package/stdlib/backend/conformance/rust-axum.plain +9 -0
- package/stdlib/backend/conformance/typescript-express.plain +9 -0
- package/stdlib/backend/conformance/typescript-fastify.plain +9 -0
- package/stdlib/backend/conformance/typescript-nestjs.plain +9 -0
- package/stdlib/backend/go-gin.plain +18 -0
- package/stdlib/backend/go-nethttp.plain +18 -0
- package/stdlib/backend/java-springboot.plain +19 -0
- package/stdlib/backend/python-django.plain +19 -0
- package/stdlib/backend/python-fastapi.plain +23 -0
- package/stdlib/backend/python-flask.plain +23 -0
- package/stdlib/backend/rust-axum.plain +17 -0
- package/stdlib/backend/typescript-express.plain +19 -0
- package/stdlib/backend/typescript-fastify.plain +19 -0
- package/stdlib/backend/typescript-nestjs.plain +19 -0
- package/stdlib/cli/common.plain +17 -0
- package/stdlib/cli/conformance/common.plain +11 -0
- package/stdlib/cli/conformance/go-cobra.plain +9 -0
- package/stdlib/cli/conformance/go-flag.plain +9 -0
- package/stdlib/cli/conformance/java-picocli.plain +9 -0
- package/stdlib/cli/conformance/python-argparse.plain +9 -0
- package/stdlib/cli/conformance/python-click.plain +9 -0
- package/stdlib/cli/conformance/python-typer.plain +9 -0
- package/stdlib/cli/conformance/rust-clap.plain +9 -0
- package/stdlib/cli/conformance/typescript-commander.plain +9 -0
- package/stdlib/cli/go-cobra.plain +14 -0
- package/stdlib/cli/go-flag.plain +14 -0
- package/stdlib/cli/java-picocli.plain +15 -0
- package/stdlib/cli/python-argparse.plain +18 -0
- package/stdlib/cli/python-click.plain +16 -0
- package/stdlib/cli/python-typer.plain +16 -0
- package/stdlib/cli/rust-clap.plain +14 -0
- package/stdlib/cli/typescript-commander.plain +17 -0
- package/stdlib/frontend/angular.plain +17 -0
- package/stdlib/frontend/common.plain +17 -0
- package/stdlib/frontend/conformance/angular.plain +5 -0
- package/stdlib/frontend/conformance/common.plain +11 -0
- package/stdlib/frontend/conformance/react-vite.plain +5 -0
- package/stdlib/frontend/conformance/sveltekit-spa.plain +5 -0
- package/stdlib/frontend/conformance/vue-vite.plain +5 -0
- package/stdlib/frontend/react-vite.plain +16 -0
- package/stdlib/frontend/sveltekit-spa.plain +16 -0
- package/stdlib/frontend/vue-vite.plain +16 -0
- package/stdlib/lang/go.plain +13 -0
- package/stdlib/lang/java.plain +12 -0
- package/stdlib/lang/python.plain +18 -0
- package/stdlib/lang/rust.plain +12 -0
- package/stdlib/lang/typescript.plain +13 -0
- package/stdlib/library/common.plain +15 -0
- package/stdlib/library/conformance/common.plain +9 -0
- package/stdlib/library/conformance/go.plain +9 -0
- package/stdlib/library/conformance/java-gradle.plain +9 -0
- package/stdlib/library/conformance/java-maven.plain +9 -0
- package/stdlib/library/conformance/python.plain +9 -0
- package/stdlib/library/conformance/rust.plain +9 -0
- package/stdlib/library/conformance/typescript.plain +9 -0
- package/stdlib/library/go.plain +12 -0
- package/stdlib/library/java-gradle.plain +13 -0
- package/stdlib/library/java-maven.plain +13 -0
- package/stdlib/library/python.plain +13 -0
- package/stdlib/library/rust.plain +12 -0
- package/stdlib/library/typescript.plain +15 -0
|
@@ -0,0 +1,252 @@
|
|
|
1
|
+
|
|
2
|
+
▄▄▆▆██▆▆▄▄
|
|
3
|
+
▄▆█▓▒░░░░░░▒▓█▆▄
|
|
4
|
+
▄█▓▒░ ░▒▒▒▒░ ░▒▓█▄
|
|
5
|
+
▐█▒░ ░▒▓████▓▒░ ░▒█▌
|
|
6
|
+
▝█▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄█▘
|
|
7
|
+
) ) ) ║║ ╱ ) )
|
|
8
|
+
( ╱ ╱ ╱╱ ( ( )
|
|
9
|
+
╱ ╱ ) )) ) ) )
|
|
10
|
+
╱ ( ( ) ⁏ ) ) (
|
|
11
|
+
) ⁏ ) ⁏ @ ) ⁏ )
|
|
12
|
+
⁏ $ ⁏ ; ⁏ * ⁏
|
|
13
|
+
# % & .
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
▄▆▆██▆▆▄
|
|
17
|
+
▄▆█▓▒░░░░▒▓█▆▄
|
|
18
|
+
▄█▓▒░ ░▒▒▒▒░ ░▒▓█▄
|
|
19
|
+
▐█▒░ ░▒▓████▓▒░ ░▒█▌
|
|
20
|
+
▝█▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄█▘
|
|
21
|
+
) ) ) ║║ ) ) )
|
|
22
|
+
( ( ( (╱ ( ( (
|
|
23
|
+
╱ ╱ ╱ ╱ ) ) )
|
|
24
|
+
╱ ( ) ) ⁏ ) ) )
|
|
25
|
+
) ⁏ ) ⁏ @ ) ⁏ ╱
|
|
26
|
+
⁏ $ ⁏ ; ⁏ * ⁏
|
|
27
|
+
# % & .
|
|
28
|
+
---
|
|
29
|
+
▄▆██▆▄
|
|
30
|
+
▄▆█▓▒░░▒▓█▆▄
|
|
31
|
+
▄█▓▒░░▒▓▓▒░░▒▓█▄
|
|
32
|
+
▐█▒░░▒▓████▓▒░░▒█▌
|
|
33
|
+
▝█▄▄▄▄▄▄▄▄▄▄▄▄▄▄█▘
|
|
34
|
+
) ) ) ║║ ) ) )
|
|
35
|
+
( ( ( (( ( ( )
|
|
36
|
+
) ) ) )) ) ) )
|
|
37
|
+
╱ ╱ ( (⁏ ) ) )
|
|
38
|
+
) ⁏ ) ⁏ @ ) ⁏ ╱
|
|
39
|
+
⁏ $ ⁏ ; ⁏ *⁏
|
|
40
|
+
# % & .
|
|
41
|
+
|
|
42
|
+
---
|
|
43
|
+
▄▆██▆▄
|
|
44
|
+
▄▆█▓▒░░▒▓█▆▄
|
|
45
|
+
▄█▓▒░░▒▓▓▒░░▒▓█▄
|
|
46
|
+
▐█▒░░▒▓████▓▒░░▒█▌
|
|
47
|
+
▝█▄▄▄▄▄▄▄▄▄▄▄▄▄▄█▘
|
|
48
|
+
) ) ) ║║ ) ) )
|
|
49
|
+
( ( ) (( ( ) (
|
|
50
|
+
) ) ))) ) ) )
|
|
51
|
+
╱ ╱ ( (⁏ ( ( )
|
|
52
|
+
) ⁏ ) ⁏@ ) ⁏ )
|
|
53
|
+
⁏ $ ⁏ ; ⁏ * ⁏
|
|
54
|
+
# % & .
|
|
55
|
+
|
|
56
|
+
---
|
|
57
|
+
▄▆██▆▄
|
|
58
|
+
▄▆█▓▒░░▒▓█▆▄
|
|
59
|
+
▄█▓▒░░▒▓▓▒░░▒▓█▄
|
|
60
|
+
▐█▒░░▒▓████▓▒░░▒█▌
|
|
61
|
+
▝█▄▄▄▄▄▄▄▄▄▄▄▄▄▄█▘
|
|
62
|
+
) ) ) ║║ ) ) )
|
|
63
|
+
( ) ) )) ) ) (
|
|
64
|
+
) ) ) )) ) ) )
|
|
65
|
+
( ( ( (⁏ ( ( )
|
|
66
|
+
) ⁏ ) ⁏@ ) ⁏ )
|
|
67
|
+
⁏ $ ⁏ ; ⁏ * ⁏
|
|
68
|
+
# % & .
|
|
69
|
+
|
|
70
|
+
---
|
|
71
|
+
▄▆██▆▄
|
|
72
|
+
▄▆█▓▒░░▒▓█▆▄
|
|
73
|
+
▄█▓▒░░▒▓▓▒░░▒▓█▄
|
|
74
|
+
▐█▒░░▒▓████▓▒░░▒█▌
|
|
75
|
+
▝█▄▄▄▄▄▄▄▄▄▄▄▄▄▄█▘
|
|
76
|
+
) ) ) ║║ ) ) )
|
|
77
|
+
( ( ) )) ( ) )
|
|
78
|
+
) ) ) ))) ) )
|
|
79
|
+
( ( ( (⁏ ( ( )
|
|
80
|
+
) ⁏ ) ⁏@ ) ⁏ )
|
|
81
|
+
⁏ $ ⁏ ; ⁏ * ⁏
|
|
82
|
+
# % & .
|
|
83
|
+
|
|
84
|
+
---
|
|
85
|
+
▄▆██▆▄
|
|
86
|
+
▄▆█▓▒░░▒▓█▆▄
|
|
87
|
+
▄█▓▒░░▒▓▓▒░░▒▓█▄
|
|
88
|
+
▐█▒░░▒▓████▓▒░░▒█▌
|
|
89
|
+
▝█▄▄▄▄▄▄▄▄▄▄▄▄▄▄█▘
|
|
90
|
+
) ) ) ║║ ) ) )
|
|
91
|
+
( ( ((( ( ) )
|
|
92
|
+
) ) ))) ) ) )
|
|
93
|
+
) ( ( (⁏ ( ( )
|
|
94
|
+
) ⁏ ) ⁏@ ) ⁏ )
|
|
95
|
+
⁏ $ ⁏ ; ⁏ * ⁏
|
|
96
|
+
# % & .
|
|
97
|
+
|
|
98
|
+
---
|
|
99
|
+
|
|
100
|
+
▄▆▆██▆▆▄
|
|
101
|
+
▄▆█▓▒░░░░▒▓█▆▄
|
|
102
|
+
▄█▓▒░ ░▒▒▒▒░ ░▒▓█▄
|
|
103
|
+
▐█▒░ ░▒▓████▓▒░ ░▒█▌
|
|
104
|
+
▝█▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄█▘
|
|
105
|
+
) ) ) ║║ ) ) )
|
|
106
|
+
( ( ( (( ( ( )
|
|
107
|
+
) ) ) )) ) ) )
|
|
108
|
+
( ( ) ) ⁏ ( ( (
|
|
109
|
+
) ⁏ ) ⁏@ ) ⁏ )
|
|
110
|
+
⁏ $ ⁏ ; ⁏ * ⁏
|
|
111
|
+
# % & .
|
|
112
|
+
---
|
|
113
|
+
|
|
114
|
+
▄▆▆██▆▆▄
|
|
115
|
+
▄▆█▓▒░░░░▒▓█▆▄
|
|
116
|
+
▄█▓▒░ ░▒▒▒▒░ ░▒▓█▄
|
|
117
|
+
▐█▒░ ░▒▓████▓▒░ ░▒█▌
|
|
118
|
+
▝█▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄█▘
|
|
119
|
+
) ) ) ║║ ) ) )
|
|
120
|
+
( ( ( (( ( ) )
|
|
121
|
+
╱ ) ) )) ) ) )
|
|
122
|
+
) ( ) )⁏ ( ( )
|
|
123
|
+
) ⁏ ) ⁏@ ) ⁏ )
|
|
124
|
+
⁏ $ ⁏ ; ⁏ * ⁏
|
|
125
|
+
# % & .
|
|
126
|
+
---
|
|
127
|
+
|
|
128
|
+
▄▆▆██▆▆▄
|
|
129
|
+
▄▆█▓▒░░░░▒▓█▆▄
|
|
130
|
+
▄█▓▒░ ░▒▒▒▒░ ░▒▓█▄
|
|
131
|
+
▐█▒░ ░▒▓████▓▒░ ░▒█▌
|
|
132
|
+
▝█▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄█▘
|
|
133
|
+
) ) ) ║║ ) ) )
|
|
134
|
+
( ( ( (( ( ) (
|
|
135
|
+
╱ ) ) )) ) ) )
|
|
136
|
+
( ( ( )⁏ ( ) )
|
|
137
|
+
) ⁏ ) ⁏@ ) ⁏ )
|
|
138
|
+
⁏ $ ⁏ ; ⁏ * ⁏
|
|
139
|
+
# % & .
|
|
140
|
+
---
|
|
141
|
+
|
|
142
|
+
▄▆▆██▆▆▄
|
|
143
|
+
▄▆█▓▒░░░░▒▓█▆▄
|
|
144
|
+
▄█▓▒░ ░▒▒▒▒░ ░▒▓█▄
|
|
145
|
+
▐█▒░ ░▒▓████▓▒░ ░▒█▌
|
|
146
|
+
▝█▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄█▘
|
|
147
|
+
) ) ) ║ ) ) )
|
|
148
|
+
( ( ( (( ( ) (
|
|
149
|
+
╱ ╱ ) )) ) ) )
|
|
150
|
+
( ) ( )⁏ ( ) )
|
|
151
|
+
) ⁏ ) ⁏@ ) ⁏ )
|
|
152
|
+
⁏ $ ⁏ ; ⁏ * ⁏
|
|
153
|
+
# % & .
|
|
154
|
+
---
|
|
155
|
+
|
|
156
|
+
▄▄▆▆██▆▆▄▄
|
|
157
|
+
▄▆█▓▒░░░░░░▒▓█▆▄
|
|
158
|
+
▄█▓▒░ ░▒▒▒▒░ ░▒▓█▄
|
|
159
|
+
▐█▒░ ░▒▓████▓▒░ ░▒█▌
|
|
160
|
+
▝█▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄█▘
|
|
161
|
+
) ) ) ║ ╱ ) )
|
|
162
|
+
( ╱ ( (( ( ( )
|
|
163
|
+
╱ ) ╱ )) ) ) )
|
|
164
|
+
( ( ) (⁏ ) ) (
|
|
165
|
+
) ⁏ ) ⁏ @ ) ⁏ )
|
|
166
|
+
⁏ $ ⁏ ; ⁏ * ⁏
|
|
167
|
+
# % & .
|
|
168
|
+
---
|
|
169
|
+
|
|
170
|
+
▄▄▆▆██▆▆▄▄
|
|
171
|
+
▄▆█▓▒░░░░░░▒▓█▆▄
|
|
172
|
+
▄█▓▒░ ░▒▒▒▒░ ░▒▓█▄
|
|
173
|
+
▐█▒░ ░▒▓████▓▒░ ░▒█▌
|
|
174
|
+
▝█▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄█▘
|
|
175
|
+
) ) ) ║║ ╱ ) )
|
|
176
|
+
( ╱ ( (( ( ( )
|
|
177
|
+
╱ ) ╱ )) ) ) )
|
|
178
|
+
( ( ) (⁏ ) ) (
|
|
179
|
+
) ⁏ ) ⁏ @ ) ⁏ )
|
|
180
|
+
⁏ $ ⁏ ; ⁏ * ⁏
|
|
181
|
+
# % & .
|
|
182
|
+
---
|
|
183
|
+
|
|
184
|
+
▄▄▆▆██▆▆▄▄
|
|
185
|
+
▄▆█▓▒░░░░░░▒▓█▆▄
|
|
186
|
+
▄█▓▒░ ░▒▒▒▒░ ░▒▓█▄
|
|
187
|
+
▐█▒░ ░▒▓████▓▒░ ░▒█▌
|
|
188
|
+
▝█▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄█▘
|
|
189
|
+
) ) ) ║║ ╱ ) )
|
|
190
|
+
( ╱ ( (( ( ( )
|
|
191
|
+
╱ ) ╱ )) ) ) )
|
|
192
|
+
( ( ) (⁏ ) ) (
|
|
193
|
+
) ⁏ ) ⁏ @ ) ⁏ )
|
|
194
|
+
⁏ $ ⁏ ; ⁏ * ⁏
|
|
195
|
+
# % & .
|
|
196
|
+
---
|
|
197
|
+
|
|
198
|
+
▄▄▆▆██▆▆▄▄
|
|
199
|
+
▄▆█▓▒░░░░░░▒▓█▆▄
|
|
200
|
+
▄█▓▒░ ░▒▒▒▒░ ░▒▓█▄
|
|
201
|
+
▐█▒░ ░▒▓████▓▒░ ░▒█▌
|
|
202
|
+
▝█▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄█▘
|
|
203
|
+
) ) ) ║║ ╱ ╱ )
|
|
204
|
+
( ╱ ╱ ╱╱ ( ) )
|
|
205
|
+
╱ ╱ ) )) ) ) )
|
|
206
|
+
( ( ( ) ⁏ ) ) (
|
|
207
|
+
) ⁏ ) ⁏ @ ) ⁏ )
|
|
208
|
+
⁏ $ ⁏ ; ⁏ * ⁏
|
|
209
|
+
# % & .
|
|
210
|
+
---
|
|
211
|
+
|
|
212
|
+
▄▄▆▆██▆▆▄▄
|
|
213
|
+
▄▆█▓▒░░░░░░▒▓█▆▄
|
|
214
|
+
▄█▓▒░ ░▒▒▒▒░ ░▒▓█▄
|
|
215
|
+
▐█▒░ ░▒▓████▓▒░ ░▒█▌
|
|
216
|
+
▝█▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄█▘
|
|
217
|
+
) ) ╱ ║║ ╱ ╱ )
|
|
218
|
+
( ╱ ╱ ╱╱ ( ) )
|
|
219
|
+
╱ ╱ ) )) ) ) )
|
|
220
|
+
( ( ( ) ⁏ ) ) (
|
|
221
|
+
) ⁏ ) ⁏ @ ) ⁏ )
|
|
222
|
+
⁏ $ ⁏ ; ⁏ * ⁏
|
|
223
|
+
# % & .
|
|
224
|
+
---
|
|
225
|
+
|
|
226
|
+
▄▄▆▆██▆▆▄▄
|
|
227
|
+
▄▆█▓▒░░░░░░▒▓█▆▄
|
|
228
|
+
▄█▓▒░ ░▒▒▒▒░ ░▒▓█▄
|
|
229
|
+
▐█▒░ ░▒▓████▓▒░ ░▒█▌
|
|
230
|
+
▝█▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄█▘
|
|
231
|
+
) ) ╱ ║║ ╱ ╱ )
|
|
232
|
+
( ╱ ╱ ╱╱ ( ) )
|
|
233
|
+
╱ ╱ ) )) ) ) )
|
|
234
|
+
( ( ( ) ⁏ ) ) (
|
|
235
|
+
) ⁏ ) ⁏ @ ) ⁏ )
|
|
236
|
+
⁏ $ ⁏ ; ⁏ * ⁏
|
|
237
|
+
# % & .
|
|
238
|
+
---
|
|
239
|
+
|
|
240
|
+
▄▄▆▆██▆▆▄▄
|
|
241
|
+
▄▆█▓▒░░░░░░▒▓█▆▄
|
|
242
|
+
▄█▓▒░ ░▒▒▒▒░ ░▒▓█▄
|
|
243
|
+
▐█▒░ ░▒▓████▓▒░ ░▒█▌
|
|
244
|
+
▝█▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄█▘
|
|
245
|
+
) ) ) ║║ ╱ ╱ )
|
|
246
|
+
( ╱ ╱ ╱╱ ( ) )
|
|
247
|
+
╱ ╱ ) )) ) ) )
|
|
248
|
+
( ( ( ) ⁏ ) ) (
|
|
249
|
+
) ⁏ ) ⁏ @ ) ⁏ )
|
|
250
|
+
⁏ $ ⁏ ; ⁏ * ⁏
|
|
251
|
+
# % & .
|
|
252
|
+
---
|
|
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
|
|
Binary file
|
|
Binary file
|
package/bin/turri.mjs
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// The launcher: plain JavaScript, so it runs on any Node and can say what is wrong before turri itself is loaded -
|
|
3
|
+
// the TypeScript sources in a clone, which Node runs itself, or in an installed package the files compiled from them
|
|
4
|
+
// (npm run build), as Node runs no .ts file inside node_modules.
|
|
5
|
+
const [major, minor] = process.versions.node.split(".").map(Number);
|
|
6
|
+
if (major < 22 || (major === 22 && minor < 19)) {
|
|
7
|
+
console.error(
|
|
8
|
+
`turri needs Node 22.19 or newer; this is ${process.versions.node}.\n` +
|
|
9
|
+
(process.platform === "darwin"
|
|
10
|
+
? "Install a newer one (`brew install node`, or https://nodejs.org) and run it again."
|
|
11
|
+
: "Install a newer one - a Linux distribution's own package is often older: use https://nodejs.org/en/download " +
|
|
12
|
+
"(nvm, or NodeSource's packages) - and run it again."),
|
|
13
|
+
);
|
|
14
|
+
process.exit(1);
|
|
15
|
+
}
|
|
16
|
+
// A terminal still sitting in a folder that was removed - or removed and made again under the same
|
|
17
|
+
// path - has no working directory, and everything after this needs one.
|
|
18
|
+
try {
|
|
19
|
+
process.cwd();
|
|
20
|
+
} catch {
|
|
21
|
+
console.error(
|
|
22
|
+
"The folder this terminal is in no longer exists - it was removed, or removed and made again, while the terminal was in it.\n" +
|
|
23
|
+
`Go into it again - cd "${process.env.PWD ?? "<your project>"}" - or into your project, and run turri again.`,
|
|
24
|
+
);
|
|
25
|
+
process.exit(1);
|
|
26
|
+
}
|
|
27
|
+
const { existsSync } = await import("node:fs");
|
|
28
|
+
const sources = new URL("../src/cli.ts", import.meta.url);
|
|
29
|
+
await import(existsSync(sources) ? sources.href : new URL("../dist/cli.js", import.meta.url).href);
|
package/dist/ask.js
ADDED
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* How a skill step puts a question to the person running it.
|
|
3
|
+
*
|
|
4
|
+
* The interaction policy lives here rather than in the extension so it is the same from
|
|
5
|
+
* the TUI and the CLI, and so it can be tested without a terminal.
|
|
6
|
+
*/
|
|
7
|
+
import { isKeyRelease, isKeyRepeat, matchesKey } from "@earendil-works/pi-tui";
|
|
8
|
+
import { PANEL_KEY } from "./regenerate/job-panel.js";
|
|
9
|
+
export const OTHER_OPTION = "Something else…";
|
|
10
|
+
export const CHAT_OPTION = "Chat about this";
|
|
11
|
+
export const DONE_OPTION = "Done — that's all of them";
|
|
12
|
+
export const DISMISSED = "The user dismissed the question without answering.";
|
|
13
|
+
/** How an answer that is no answer starts: the person chose to talk about the question first. */
|
|
14
|
+
export const CHAT_PREFIX = "The user has not answered this question yet: they chose to talk about it first.";
|
|
15
|
+
/** What comes back when the person chose "Chat about this": what they said, and what they had picked so far. */
|
|
16
|
+
export function chatAnswer(said, picked = []) {
|
|
17
|
+
return [CHAT_PREFIX, `They said: ${said.trim()}`, ...(picked.length > 0 ? [`They had picked so far: ${picked.join(", ")}.`] : [])].join("\n");
|
|
18
|
+
}
|
|
19
|
+
/** Whether an answer is the person choosing to talk about the question, rather than answering it. */
|
|
20
|
+
export function isChat(answer) {
|
|
21
|
+
return answer.startsWith(CHAT_PREFIX);
|
|
22
|
+
}
|
|
23
|
+
/** The input after "Something else…" or "Chat about this": with nothing typed, or Esc, the options again. */
|
|
24
|
+
const BACK = "(Esc, or nothing typed: back to the options)";
|
|
25
|
+
const typedNothing = (typed) => typed === undefined || typed.trim() === "";
|
|
26
|
+
/**
|
|
27
|
+
* A question with no options and no `free_form` is refused rather than asked.
|
|
28
|
+
*
|
|
29
|
+
* Offering choices is the thing that makes an interview quick to answer, and an optional
|
|
30
|
+
* field is one a model quietly skips. Making the free-form case explicit means asking
|
|
31
|
+
* without options is a decision rather than an omission.
|
|
32
|
+
*/
|
|
33
|
+
export function missingOptions(request) {
|
|
34
|
+
const hasOptions = request.options !== undefined && request.options.length > 0;
|
|
35
|
+
if (hasOptions || request.freeForm === true)
|
|
36
|
+
return null;
|
|
37
|
+
return ("This question was not asked. Offer concrete options so the user can pick one, or set " +
|
|
38
|
+
"free_form to true if the answer genuinely cannot be anticipated (\"What is the app?\"). " +
|
|
39
|
+
"Call ask_user again.");
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* A model's own tool-call syntax, leaked into an argument: `<parameter name="multi_select">false`
|
|
43
|
+
* written inside an option instead of as the argument it is. Never shown to the person.
|
|
44
|
+
*/
|
|
45
|
+
const TOOL_MARKUP = /<\/?(?:antml:)?(?:parameter|invoke|function_calls|function|tool_call|arg_key|arg_value)\b[^>]*>/i;
|
|
46
|
+
/**
|
|
47
|
+
* The request as the person should see it: tool-call markup cut out of the question and the
|
|
48
|
+
* options - an option that was nothing but markup dropped - and a `multi_select` that leaked into
|
|
49
|
+
* the text taken as the argument it was meant to be. `leaked` when there was any.
|
|
50
|
+
*/
|
|
51
|
+
export function cleanRequest(request) {
|
|
52
|
+
let leaked = false;
|
|
53
|
+
let multiSelect = request.multiSelect;
|
|
54
|
+
const clean = (text) => {
|
|
55
|
+
const flag = /<(?:antml:)?parameter\s+name="multi_select"\s*>\s*(true|false)/i.exec(text);
|
|
56
|
+
if (flag && multiSelect === undefined)
|
|
57
|
+
multiSelect = flag[1].toLowerCase() === "true";
|
|
58
|
+
const at = text.search(TOOL_MARKUP);
|
|
59
|
+
if (at === -1)
|
|
60
|
+
return text.trim();
|
|
61
|
+
leaked = true;
|
|
62
|
+
return text.slice(0, at).trim();
|
|
63
|
+
};
|
|
64
|
+
const question = clean(request.question);
|
|
65
|
+
const options = request.options === undefined ? undefined : [...new Set(request.options.map(clean).filter((option) => option !== ""))];
|
|
66
|
+
return { request: { ...request, question, options, multiSelect }, leaked };
|
|
67
|
+
}
|
|
68
|
+
export async function runAsk(asked, io) {
|
|
69
|
+
const { request, leaked } = cleanRequest(asked);
|
|
70
|
+
// What was left once the markup was cut out is not a question worth putting to anyone.
|
|
71
|
+
if (leaked && (request.question === "" || (request.options?.length === 0 && request.freeForm !== true))) {
|
|
72
|
+
return ("This question was not asked: its question or options held tool-call markup (<parameter ...>) " +
|
|
73
|
+
"instead of text. Call ask_user again, with question, options and multi_select as separate arguments.");
|
|
74
|
+
}
|
|
75
|
+
const refusal = missingOptions(request);
|
|
76
|
+
if (refusal !== null)
|
|
77
|
+
return refusal;
|
|
78
|
+
// The question, and apart from it what it is about: the dialog shows that above it.
|
|
79
|
+
const trimmed = request.context?.trim() ?? "";
|
|
80
|
+
const context = trimmed !== "" ? trimmed : undefined;
|
|
81
|
+
const options = request.options ?? [];
|
|
82
|
+
if (options.length === 0) {
|
|
83
|
+
return (await io.input(request.question, context)) ?? DISMISSED;
|
|
84
|
+
}
|
|
85
|
+
// Beside the options: typing an answer instead, and - when an agent asked - talking about the question first. Either
|
|
86
|
+
// can be backed out of, to the options again: picked by accident, it costs nothing.
|
|
87
|
+
const extras = [OTHER_OPTION, ...(request.chattable === true ? [CHAT_OPTION] : [])];
|
|
88
|
+
const typeInstead = () => io.input(`${request.question}\n\n${BACK}`, context);
|
|
89
|
+
const chatAbout = () => io.input(`${request.question}\n\nWhat would you like to talk about? ${BACK}`, context);
|
|
90
|
+
if (request.multiSelect !== true) {
|
|
91
|
+
for (;;) {
|
|
92
|
+
const choice = await io.select(request.question, [...options, ...extras], context);
|
|
93
|
+
if (choice === undefined)
|
|
94
|
+
return DISMISSED;
|
|
95
|
+
if (choice === OTHER_OPTION) {
|
|
96
|
+
const typed = await typeInstead();
|
|
97
|
+
if (typedNothing(typed))
|
|
98
|
+
continue;
|
|
99
|
+
return typed;
|
|
100
|
+
}
|
|
101
|
+
if (choice === CHAT_OPTION) {
|
|
102
|
+
const said = await chatAbout();
|
|
103
|
+
if (typedNothing(said))
|
|
104
|
+
continue;
|
|
105
|
+
return chatAnswer(said);
|
|
106
|
+
}
|
|
107
|
+
return choice;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
// Pick several: keep offering what is left until they say they are done.
|
|
111
|
+
const chosen = [];
|
|
112
|
+
let remaining = [...options];
|
|
113
|
+
while (remaining.length > 0) {
|
|
114
|
+
const title = chosen.length === 0 ? request.question : `${request.question} [so far: ${chosen.join(", ")}]`;
|
|
115
|
+
const choice = await io.select(title, [...remaining, ...extras, DONE_OPTION], context);
|
|
116
|
+
if (choice === undefined)
|
|
117
|
+
break;
|
|
118
|
+
if (choice === DONE_OPTION)
|
|
119
|
+
break;
|
|
120
|
+
if (choice === OTHER_OPTION) {
|
|
121
|
+
const typed = await typeInstead();
|
|
122
|
+
if (!typedNothing(typed))
|
|
123
|
+
chosen.push(typed.trim());
|
|
124
|
+
continue;
|
|
125
|
+
}
|
|
126
|
+
if (choice === CHAT_OPTION) {
|
|
127
|
+
const said = await chatAbout();
|
|
128
|
+
if (typedNothing(said))
|
|
129
|
+
continue;
|
|
130
|
+
return chatAnswer(said, chosen);
|
|
131
|
+
}
|
|
132
|
+
chosen.push(choice);
|
|
133
|
+
remaining = remaining.filter((option) => option !== choice);
|
|
134
|
+
}
|
|
135
|
+
return chosen.length > 0 ? chosen.join(", ") : DISMISSED;
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* While a question is open, what catches ctrl+h on the terminal's input: pi gives an extension's shortcut only the keys
|
|
139
|
+
* its editor sees, and a question has the focus. It opens the side panel - the question waits under it - unless the
|
|
140
|
+
* panel shows already: its own listener has ctrl+h then, to close it. A key's release and its repeats are left alone.
|
|
141
|
+
*/
|
|
142
|
+
export function peekKeyListener(panel) {
|
|
143
|
+
return (data) => {
|
|
144
|
+
if (isKeyRelease(data) || isKeyRepeat(data) || !matchesKey(data, PANEL_KEY) || panel.shown())
|
|
145
|
+
return undefined;
|
|
146
|
+
panel.open();
|
|
147
|
+
return { consume: true };
|
|
148
|
+
};
|
|
149
|
+
}
|
package/dist/brand.js
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
2
|
+
import { homedir } from "node:os";
|
|
3
|
+
import { join } from "node:path";
|
|
4
|
+
/**
|
|
5
|
+
* turri's colours for what its command line prints - the ones its themes use (.pi/themes): on a dark terminal its lime
|
|
6
|
+
* accent and green, on a light one its blue. Nothing is coloured when the output is not a terminal, or NO_COLOR is set;
|
|
7
|
+
* a terminal without 24-bit colour gets the nearest of its sixteen.
|
|
8
|
+
*/
|
|
9
|
+
/** Whether the terminal is light: COLORFGBG says so (a light background, 7 or 15), or pi's theme is a light one. */
|
|
10
|
+
function lightTerminal() {
|
|
11
|
+
const background = process.env.COLORFGBG?.split(";").at(-1);
|
|
12
|
+
if (background === "7" || background === "15")
|
|
13
|
+
return true;
|
|
14
|
+
try {
|
|
15
|
+
const settings = join(process.env.PI_CODING_AGENT_DIR ?? join(homedir(), ".pi", "agent"), "settings.json");
|
|
16
|
+
if (existsSync(settings))
|
|
17
|
+
return /light/i.test(String(JSON.parse(readFileSync(settings, "utf8")).theme ?? ""));
|
|
18
|
+
}
|
|
19
|
+
catch {
|
|
20
|
+
/* no settings to go by */
|
|
21
|
+
}
|
|
22
|
+
return false;
|
|
23
|
+
}
|
|
24
|
+
function paint(stream = process.stdout) {
|
|
25
|
+
const on = stream.isTTY === true && process.env.NO_COLOR === undefined;
|
|
26
|
+
const truecolor = /truecolor|24bit/i.test(process.env.COLORTERM ?? "");
|
|
27
|
+
const light = on && lightTerminal();
|
|
28
|
+
const ink = (hex, basic) => (text) => {
|
|
29
|
+
if (!on)
|
|
30
|
+
return text;
|
|
31
|
+
if (!truecolor)
|
|
32
|
+
return `\x1b[${basic}m${text}\x1b[39m`;
|
|
33
|
+
const [r, g, b] = [1, 3, 5].map((at) => Number.parseInt(hex.slice(at, at + 2), 16));
|
|
34
|
+
return `\x1b[38;2;${r};${g};${b}m${text}\x1b[39m`;
|
|
35
|
+
};
|
|
36
|
+
return {
|
|
37
|
+
/** turri's accent: what to look at - a heading, a choice's number, the command to run. */
|
|
38
|
+
accent: light ? ink("#0a1fd4", 34) : ink("#e0ff6e", 93),
|
|
39
|
+
/** Done, and what was written. */
|
|
40
|
+
success: light ? ink("#223936", 32) : ink("#79fc96", 92),
|
|
41
|
+
/** What is wrong: what stops turri. */
|
|
42
|
+
error: light ? ink("#d00505", 31) : ink("#dd5353", 91),
|
|
43
|
+
/** What works, with limits. */
|
|
44
|
+
warning: ink("#dc6803", 33),
|
|
45
|
+
/** What goes with it, and can be skimmed. */
|
|
46
|
+
muted: ink("#808080", 90),
|
|
47
|
+
bold: (text) => (on ? `\x1b[1m${text}\x1b[22m` : text),
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
export const brand = paint();
|