@turri-dev/cli 0.1.3-next.26f08c5 → 0.1.3-next.79e2ad0
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/dist/environment.js +0 -19
- package/dist/extension.js +11 -7
- package/dist/pi-launch.js +4 -13
- package/dist/run-report.js +22 -2
- package/docs/development.md +0 -6
- package/docs/using.md +2 -4
- package/package.json +1 -1
package/dist/environment.js
CHANGED
|
@@ -68,22 +68,3 @@ export function turriOnPath() {
|
|
|
68
68
|
const found = which.status === 0 ? which.stdout.trim().split("\n")[0] : undefined;
|
|
69
69
|
return found === "" ? undefined : found;
|
|
70
70
|
}
|
|
71
|
-
/** turri's version, and the commit when it runs from a clone. */
|
|
72
|
-
export function turriIdentity() {
|
|
73
|
-
let version = null;
|
|
74
|
-
try {
|
|
75
|
-
version = JSON.parse(readFileSync(join(PACKAGE_ROOT, "package.json"), "utf8")).version ?? null;
|
|
76
|
-
}
|
|
77
|
-
catch {
|
|
78
|
-
/* no package.json: left out */
|
|
79
|
-
}
|
|
80
|
-
if (!existsSync(join(PACKAGE_ROOT, ".git")))
|
|
81
|
-
return { version, git_commit: null, git_dirty: null };
|
|
82
|
-
const commit = spawnSync("git", ["-C", PACKAGE_ROOT, "rev-parse", "HEAD"], { encoding: "utf8" });
|
|
83
|
-
const status = spawnSync("git", ["-C", PACKAGE_ROOT, "status", "--porcelain", "--untracked-files=no"], { encoding: "utf8" });
|
|
84
|
-
return {
|
|
85
|
-
version,
|
|
86
|
-
git_commit: commit.status === 0 ? commit.stdout.trim() : null,
|
|
87
|
-
git_dirty: status.status === 0 ? status.stdout.trim() !== "" : null,
|
|
88
|
-
};
|
|
89
|
-
}
|
package/dist/extension.js
CHANGED
|
@@ -52,7 +52,6 @@ import { registerStacks } from "./stacks.js";
|
|
|
52
52
|
import { catalogueLine, discoverSkills, leftOutNote } from "./skills.js";
|
|
53
53
|
import { supersededByTurri } from "./chat-skills.js";
|
|
54
54
|
import { TURRI_IDENTITY } from "./identity.js";
|
|
55
|
-
import { turriIdentity } from "./environment.js";
|
|
56
55
|
import { conformanceChooser } from "./regenerate/choose-conformance.js";
|
|
57
56
|
import { answerSideQuestion, askWithAsides, BTW_HOW, runningSkill, skillRunStarted, skillSessionText, transcriptOf } from "./btw.js";
|
|
58
57
|
import { createJobRegistry, defaultParallelJobs, describeJob, formatDuration, pulseName, shouldWait, STOPPED_ON_REQUEST, } from "./regenerate/jobs.js";
|
|
@@ -2159,8 +2158,7 @@ function registerBranding(pi, ruleCount, skills) {
|
|
|
2159
2158
|
if (data === undefined)
|
|
2160
2159
|
return undefined;
|
|
2161
2160
|
const lines = [
|
|
2162
|
-
`${theme.fg("accent", "turri")} ${theme.fg("muted", `v${data.version}`)}
|
|
2163
|
-
(data.commit !== undefined ? theme.fg("dim", ` from a clone, ${data.commit}${data.changed ? " with changes" : ""}`) : ""),
|
|
2161
|
+
`${theme.fg("accent", "turri")} ${theme.fg("muted", `v${data.version}`)}`,
|
|
2164
2162
|
theme.fg("text", "regenerative software - the code is regenerated from the spec"),
|
|
2165
2163
|
theme.fg("muted", `${data.rules} rules · ${data.skills} skill${data.skills === 1 ? "" : "s"}` +
|
|
2166
2164
|
(data.projectSkills !== undefined && data.projectSkills > 0 ? ` (${data.projectSkills} the project's)` : "") +
|
|
@@ -2182,11 +2180,8 @@ function registerBranding(pi, ruleCount, skills) {
|
|
|
2182
2180
|
if (ctx.hasUI)
|
|
2183
2181
|
animateJellyfish(ctx);
|
|
2184
2182
|
try {
|
|
2185
|
-
const identity = turriIdentity();
|
|
2186
2183
|
pi.appendEntry(BANNER_ENTRY, {
|
|
2187
|
-
version:
|
|
2188
|
-
commit: identity.git_commit?.slice(0, 7),
|
|
2189
|
-
changed: identity.git_dirty === true,
|
|
2184
|
+
version: packageVersion(),
|
|
2190
2185
|
rules: ruleCount,
|
|
2191
2186
|
skills: skills.skills.length,
|
|
2192
2187
|
projectSkills: skills.skills.filter((skill) => skill.origin !== "turri").length,
|
|
@@ -2366,3 +2361,12 @@ function jellyfishArt(appearance, ink) {
|
|
|
2366
2361
|
return undefined;
|
|
2367
2362
|
}
|
|
2368
2363
|
}
|
|
2364
|
+
function packageVersion() {
|
|
2365
|
+
try {
|
|
2366
|
+
const raw = readFileSync(join(PACKAGE_ROOT, "package.json"), "utf8");
|
|
2367
|
+
return JSON.parse(raw).version ?? "0.0.0";
|
|
2368
|
+
}
|
|
2369
|
+
catch {
|
|
2370
|
+
return "0.0.0";
|
|
2371
|
+
}
|
|
2372
|
+
}
|
package/dist/pi-launch.js
CHANGED
|
@@ -9,28 +9,19 @@ var __rewriteRelativeImportExtension = (this && this.__rewriteRelativeImportExte
|
|
|
9
9
|
import { dirname, join } from "node:path";
|
|
10
10
|
import { fileURLToPath, pathToFileURL } from "node:url";
|
|
11
11
|
import { main, SettingsManager } from "@earendil-works/pi-coding-agent";
|
|
12
|
-
import { ProcessTerminal } from "@earendil-works/pi-tui";
|
|
13
12
|
import "./terminal-images.js";
|
|
14
13
|
/**
|
|
15
14
|
* pi, started the way its own CLI starts it, for `turri`.
|
|
16
15
|
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
16
|
+
* The one difference: pi's startup header - its version, key hints and the list of every
|
|
17
|
+
* loaded skill, extension and theme - is left out, because turri shows its own. pi only
|
|
18
|
+
* takes that from the `quietStartup` setting, and a setting would quiet every `pi` on the
|
|
19
|
+
* machine, so it is answered for this run instead. `--verbose` still shows it.
|
|
21
20
|
*/
|
|
22
21
|
const args = process.argv.slice(2);
|
|
23
22
|
if (!args.includes("--verbose")) {
|
|
24
23
|
SettingsManager.prototype.getQuietStartup = () => true;
|
|
25
24
|
}
|
|
26
|
-
// pi's "Update Available" notice is left out: the pi turri runs is its pinned dependency, which `pi update`
|
|
27
|
-
// does not touch - it moves when turri does.
|
|
28
|
-
process.env.PI_SKIP_VERSION_CHECK = "1";
|
|
29
|
-
// The terminal's tab title: pi writes `π - <folder>` (its APP_TITLE, a constant), turri a jellyfish and its name.
|
|
30
|
-
const setTitle = ProcessTerminal.prototype.setTitle;
|
|
31
|
-
ProcessTerminal.prototype.setTitle = function (title) {
|
|
32
|
-
setTitle.call(this, title.replace(/^π(?= |$)/, "🪼 turri"));
|
|
33
|
-
};
|
|
34
25
|
// pi's own keys stand: a new line is shift+enter or ctrl+j. turri's side panel is on ctrl+h (job-panel.ts PANEL_KEY).
|
|
35
26
|
// What pi's CLI does before main: the process title, pi's environment markers, the HTTP
|
|
36
27
|
// dispatcher. Not exported, so loaded from the file - beside pi's entry point, wherever npm put it.
|
package/dist/run-report.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { spawnSync } from "node:child_process";
|
|
2
|
+
import { existsSync, mkdirSync, readFileSync, renameSync, rmSync, writeFileSync } from "node:fs";
|
|
2
3
|
import { basename, dirname, join, relative, resolve } from "node:path";
|
|
3
|
-
import {
|
|
4
|
+
import { PACKAGE_ROOT } from "./environment.js";
|
|
4
5
|
import { onModelEvent } from "./regenerate/activity.js";
|
|
5
6
|
/**
|
|
6
7
|
* A headless run's report: one JSON file, `turri regenerate --report <file>`, saying what the run did - how it ended,
|
|
@@ -56,6 +57,25 @@ function sumTotals(a, b) {
|
|
|
56
57
|
function rounded(totals) {
|
|
57
58
|
return { ...totals, cost_usd: Math.round(totals.cost_usd * 1e6) / 1e6, model_seconds: Math.round(totals.model_seconds * 10) / 10 };
|
|
58
59
|
}
|
|
60
|
+
/** turri's version, and the commit when it runs from a clone. */
|
|
61
|
+
function turriIdentity() {
|
|
62
|
+
let version = null;
|
|
63
|
+
try {
|
|
64
|
+
version = JSON.parse(readFileSync(join(PACKAGE_ROOT, "package.json"), "utf8")).version ?? null;
|
|
65
|
+
}
|
|
66
|
+
catch {
|
|
67
|
+
/* no package.json: left out */
|
|
68
|
+
}
|
|
69
|
+
if (!existsSync(join(PACKAGE_ROOT, ".git")))
|
|
70
|
+
return { version, git_commit: null, git_dirty: null };
|
|
71
|
+
const commit = spawnSync("git", ["-C", PACKAGE_ROOT, "rev-parse", "HEAD"], { encoding: "utf8" });
|
|
72
|
+
const status = spawnSync("git", ["-C", PACKAGE_ROOT, "status", "--porcelain", "--untracked-files=no"], { encoding: "utf8" });
|
|
73
|
+
return {
|
|
74
|
+
version,
|
|
75
|
+
git_commit: commit.status === 0 ? commit.stdout.trim() : null,
|
|
76
|
+
git_dirty: status.status === 0 ? status.stdout.trim() !== "" : null,
|
|
77
|
+
};
|
|
78
|
+
}
|
|
59
79
|
const pulseKind = (job) => (job.kind === "regenerate" ? "code" : job.kind);
|
|
60
80
|
const firstLines = (text) => {
|
|
61
81
|
const trimmed = text?.trim();
|
package/docs/development.md
CHANGED
|
@@ -18,12 +18,6 @@ which tests reach which mutant (`vitest.stryker.config.ts`, the suite without th
|
|
|
18
18
|
mutant against those tests. `scripts/mutation.mjs` sets two things in Stryker's vitest runner the suite needs - forked
|
|
19
19
|
workers, and a test-name filter that matches vitest 5's names - again after every `npm install`.
|
|
20
20
|
|
|
21
|
-
The `mutation` workflow (`.github/workflows/mutation.yml`) runs it on GitHub, started by hand: Actions, mutation, Run
|
|
22
|
-
workflow. It takes the parts to run, space-separated (empty for every part), each a job of its own side by side, on
|
|
23
|
-
four cores (`TURRI_MUTATION_CONCURRENCY`; six here). Each part's `mutation.html` and `mutation.json` are uploaded as an
|
|
24
|
-
artifact, `mutation-<part>`, and summed up on the run's page. Stryker's incremental file is cached from run to run, so
|
|
25
|
-
a run tests again only the mutants whose code or tests changed; tick `fresh` to test every one again.
|
|
26
|
-
|
|
27
21
|
Working on turri itself, `npm link` points the global `turri` at this clone, so edits
|
|
28
22
|
take effect immediately. `npm run chat` starts pi with the extension loaded from `src/`.
|
|
29
23
|
|
package/docs/using.md
CHANGED
|
@@ -13,10 +13,8 @@ banner - the jellyfish it is named after, swimming until the conversation fills
|
|
|
13
13
|
terminal that shows images (Kitty, Ghostty, WezTerm, Warp, iTerm2), and drawn in text in any other, tmux
|
|
14
14
|
included - swimming a stroke a loop, its tentacles following its bell, frames `scripts/jellyfish-frames.mjs`
|
|
15
15
|
writes -
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
those too. pi's "Update Available" notice is left out - turri's pi is a pinned dependency `pi update` never
|
|
19
|
-
touches - and the terminal's tab reads `🪼 turri - <folder>`, not pi's `π`. Talk to it: ask it to start a
|
|
16
|
+
where commands will run, the rules and skills loaded - rather than pi's startup header
|
|
17
|
+
and resource list; `turri --verbose` shows those too. Talk to it: ask it to start a
|
|
20
18
|
project, add a feature, render a module, fix a spec. It decides which skill or tool applies - but
|
|
21
19
|
not *how* a skill runs: `cultivate` hands the work to the gated runner, which owns the steps, the
|
|
22
20
|
gates and the judges (see [skills and gates](skills-and-gates.md)).
|