runtrim 0.1.4 → 0.1.6
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-cli/runtrim.js +71 -121
- package/package.json +1 -1
package/dist-cli/runtrim.js
CHANGED
|
@@ -29,104 +29,6 @@ import fs9 from "fs";
|
|
|
29
29
|
import path9 from "path";
|
|
30
30
|
import { execa as execa3 } from "execa";
|
|
31
31
|
|
|
32
|
-
// package.json
|
|
33
|
-
var package_default = {
|
|
34
|
-
name: "runtrim",
|
|
35
|
-
version: "0.1.3",
|
|
36
|
-
description: "CLI guard layer that scopes AI coding runs before they waste tokens.",
|
|
37
|
-
license: "MIT",
|
|
38
|
-
author: "RunTrim",
|
|
39
|
-
homepage: "https://runtrim.dev",
|
|
40
|
-
repository: {
|
|
41
|
-
type: "git",
|
|
42
|
-
url: "git+https://github.com/michelpronkk-oss/rtrim.git"
|
|
43
|
-
},
|
|
44
|
-
bugs: {
|
|
45
|
-
url: "https://github.com/michelpronkk-oss/rtrim/issues"
|
|
46
|
-
},
|
|
47
|
-
keywords: [
|
|
48
|
-
"cli",
|
|
49
|
-
"ai-coding",
|
|
50
|
-
"codex",
|
|
51
|
-
"claude",
|
|
52
|
-
"cursor",
|
|
53
|
-
"developer-tools",
|
|
54
|
-
"prompt-guard"
|
|
55
|
-
],
|
|
56
|
-
bin: {
|
|
57
|
-
runtrim: "dist-cli/runtrim.cjs"
|
|
58
|
-
},
|
|
59
|
-
files: [
|
|
60
|
-
"dist-cli",
|
|
61
|
-
"README.md",
|
|
62
|
-
"LICENSE",
|
|
63
|
-
"package.json"
|
|
64
|
-
],
|
|
65
|
-
scripts: {
|
|
66
|
-
dev: "next dev",
|
|
67
|
-
build: "next build",
|
|
68
|
-
"build:web": "next build",
|
|
69
|
-
"build:cli": "tsup --config tsup.config.ts && node scripts/fix-cli-runtime.mjs",
|
|
70
|
-
"build:all": "npm run build:cli && npm run build:web",
|
|
71
|
-
start: "next start",
|
|
72
|
-
lint: "eslint",
|
|
73
|
-
runtrim: "tsx cli/runtrim.ts",
|
|
74
|
-
"runtrim:build": "npm run build:cli"
|
|
75
|
-
},
|
|
76
|
-
dependencies: {
|
|
77
|
-
"@radix-ui/react-accordion": "^1.2.12",
|
|
78
|
-
"@radix-ui/react-avatar": "^1.1.11",
|
|
79
|
-
"@radix-ui/react-dialog": "^1.1.15",
|
|
80
|
-
"@radix-ui/react-dropdown-menu": "^2.1.16",
|
|
81
|
-
"@radix-ui/react-label": "^2.1.8",
|
|
82
|
-
"@radix-ui/react-progress": "^1.1.8",
|
|
83
|
-
"@radix-ui/react-select": "^2.2.6",
|
|
84
|
-
"@radix-ui/react-separator": "^1.1.8",
|
|
85
|
-
"@radix-ui/react-slot": "^1.2.4",
|
|
86
|
-
"@radix-ui/react-switch": "^1.2.6",
|
|
87
|
-
"@radix-ui/react-tabs": "^1.1.13",
|
|
88
|
-
"@radix-ui/react-tooltip": "^1.2.8",
|
|
89
|
-
"@supabase/supabase-js": "^2.57.4",
|
|
90
|
-
chalk: "^5.6.2",
|
|
91
|
-
"class-variance-authority": "^0.7.1",
|
|
92
|
-
clipboardy: "^5.3.1",
|
|
93
|
-
clsx: "^2.1.1",
|
|
94
|
-
commander: "^14.0.3",
|
|
95
|
-
execa: "^9.6.1",
|
|
96
|
-
"fast-glob": "^3.3.3",
|
|
97
|
-
"framer-motion": "^12.38.0",
|
|
98
|
-
"lucide-react": "^1.11.0",
|
|
99
|
-
motion: "^12.38.0",
|
|
100
|
-
nanoid: "^5.1.9",
|
|
101
|
-
next: "16.2.4",
|
|
102
|
-
"next-themes": "^0.4.6",
|
|
103
|
-
ora: "^9.4.0",
|
|
104
|
-
prompts: "^2.4.2",
|
|
105
|
-
"radix-ui": "^1.4.3",
|
|
106
|
-
react: "19.2.4",
|
|
107
|
-
"react-dom": "19.2.4",
|
|
108
|
-
resend: "^6.12.2",
|
|
109
|
-
shadcn: "^4.5.0",
|
|
110
|
-
sonner: "^2.0.7",
|
|
111
|
-
"tailwind-merge": "^3.5.0",
|
|
112
|
-
"tw-animate-css": "^1.4.0",
|
|
113
|
-
zod: "^4.3.6"
|
|
114
|
-
},
|
|
115
|
-
devDependencies: {
|
|
116
|
-
"@tailwindcss/postcss": "^4",
|
|
117
|
-
"@types/node": "^20",
|
|
118
|
-
"@types/prompts": "^2.4.9",
|
|
119
|
-
"@types/react": "^19",
|
|
120
|
-
"@types/react-dom": "^19",
|
|
121
|
-
eslint: "^9",
|
|
122
|
-
"eslint-config-next": "16.2.4",
|
|
123
|
-
tailwindcss: "^4",
|
|
124
|
-
tsup: "^8.5.1",
|
|
125
|
-
tsx: "^4.21.0",
|
|
126
|
-
typescript: "^5"
|
|
127
|
-
}
|
|
128
|
-
};
|
|
129
|
-
|
|
130
32
|
// src/lib/runtrim-config.ts
|
|
131
33
|
import fs from "fs";
|
|
132
34
|
import path from "path";
|
|
@@ -3315,6 +3217,49 @@ var SECTION = "-------------------------------------------------";
|
|
|
3315
3217
|
var OUTPUT_PREVIEW_MAX = 1600;
|
|
3316
3218
|
var STANDARD_RATE_PER_MILLION = 3;
|
|
3317
3219
|
var EXPENSIVE_RATE_PER_MILLION = 30;
|
|
3220
|
+
function resolveCliLauncherPath() {
|
|
3221
|
+
var _a2;
|
|
3222
|
+
const invokedPath = (_a2 = process.argv[1]) == null ? void 0 : _a2.trim();
|
|
3223
|
+
if (invokedPath) {
|
|
3224
|
+
const absolute = path9.resolve(invokedPath);
|
|
3225
|
+
if (fs9.existsSync(absolute)) return absolute;
|
|
3226
|
+
}
|
|
3227
|
+
const localFallback = path9.resolve(process.cwd(), "dist-cli", "runtrim.cjs");
|
|
3228
|
+
if (fs9.existsSync(localFallback)) return localFallback;
|
|
3229
|
+
return null;
|
|
3230
|
+
}
|
|
3231
|
+
function resolveCliRuntimeDir() {
|
|
3232
|
+
const launcher = resolveCliLauncherPath();
|
|
3233
|
+
if (launcher) return path9.dirname(launcher);
|
|
3234
|
+
return process.cwd();
|
|
3235
|
+
}
|
|
3236
|
+
function resolveCliVersion() {
|
|
3237
|
+
var _a2, _b;
|
|
3238
|
+
const cliDir = resolveCliRuntimeDir();
|
|
3239
|
+
const candidates = [
|
|
3240
|
+
path9.resolve(cliDir, "..", "package.json"),
|
|
3241
|
+
path9.resolve(cliDir, "package.json"),
|
|
3242
|
+
path9.resolve(process.cwd(), "package.json")
|
|
3243
|
+
];
|
|
3244
|
+
for (const packageJsonPath of candidates) {
|
|
3245
|
+
try {
|
|
3246
|
+
const raw = fs9.readFileSync(packageJsonPath, "utf-8");
|
|
3247
|
+
const parsed = JSON.parse(raw);
|
|
3248
|
+
if (parsed.version && parsed.version.trim()) return parsed.version.trim();
|
|
3249
|
+
} catch (e) {
|
|
3250
|
+
}
|
|
3251
|
+
}
|
|
3252
|
+
try {
|
|
3253
|
+
const fromNodeExecArgv = process.execArgv.find((arg) => arg.startsWith("--runtrim-version="));
|
|
3254
|
+
if (fromNodeExecArgv) {
|
|
3255
|
+
const v = (_a2 = fromNodeExecArgv.split("=")[1]) == null ? void 0 : _a2.trim();
|
|
3256
|
+
if (v) return v;
|
|
3257
|
+
}
|
|
3258
|
+
} catch (e) {
|
|
3259
|
+
}
|
|
3260
|
+
const envVersion = (_b = process.env.npm_package_version) == null ? void 0 : _b.trim();
|
|
3261
|
+
return envVersion || "0.0.0";
|
|
3262
|
+
}
|
|
3318
3263
|
function parseEstimatedNumber3(value) {
|
|
3319
3264
|
if (!value) return 0;
|
|
3320
3265
|
const n = parseFloat(value.replace(/[^\d.]/g, ""));
|
|
@@ -3812,8 +3757,8 @@ async function runPrepareTask(task, options) {
|
|
|
3812
3757
|
}
|
|
3813
3758
|
}
|
|
3814
3759
|
async function tryLaunchPanelMonitorDetached(cwd) {
|
|
3815
|
-
var _a2;
|
|
3816
|
-
const entry = path9.
|
|
3760
|
+
var _a2, _b;
|
|
3761
|
+
const entry = (_a2 = resolveCliLauncherPath()) != null ? _a2 : path9.resolve(cwd, "dist-cli", "runtrim.cjs");
|
|
3817
3762
|
if (!fs9.existsSync(entry)) return false;
|
|
3818
3763
|
try {
|
|
3819
3764
|
const child = execa3(process.execPath, [entry, "panel", "--monitor"], {
|
|
@@ -3822,13 +3767,13 @@ async function tryLaunchPanelMonitorDetached(cwd) {
|
|
|
3822
3767
|
stdio: "ignore",
|
|
3823
3768
|
windowsHide: true
|
|
3824
3769
|
});
|
|
3825
|
-
(
|
|
3770
|
+
(_b = child.unref) == null ? void 0 : _b.call(child);
|
|
3826
3771
|
return true;
|
|
3827
3772
|
} catch (e) {
|
|
3828
3773
|
return false;
|
|
3829
3774
|
}
|
|
3830
3775
|
}
|
|
3831
|
-
program.name("runtrim").description("CLI guard layer for AI coding runs").version(
|
|
3776
|
+
program.name("runtrim").description("CLI guard layer for AI coding runs").version(resolveCliVersion());
|
|
3832
3777
|
var commandStartAt = Date.now();
|
|
3833
3778
|
program.hook("preAction", async () => {
|
|
3834
3779
|
commandStartAt = Date.now();
|
|
@@ -4770,24 +4715,26 @@ program.command("check").description("Check the latest run and evaluate agent ou
|
|
|
4770
4715
|
if (scope.outOfScopeFiles.length > 0) riskFlags.add("Potential outside-scope changes detected");
|
|
4771
4716
|
if (changedFiles.length > maxFiles) riskFlags.add(`File count exceeded scope limit (${maxFiles})`);
|
|
4772
4717
|
const verificationDebt = /* @__PURE__ */ new Set();
|
|
4773
|
-
if (
|
|
4774
|
-
|
|
4775
|
-
|
|
4776
|
-
|
|
4777
|
-
|
|
4778
|
-
|
|
4779
|
-
|
|
4780
|
-
|
|
4781
|
-
|
|
4782
|
-
|
|
4783
|
-
|
|
4784
|
-
|
|
4785
|
-
|
|
4786
|
-
|
|
4787
|
-
|
|
4788
|
-
|
|
4718
|
+
if (changedFiles.length > 0) {
|
|
4719
|
+
if (run.status === "guarded") verificationDebt.add("Run is still guarded and not checked.");
|
|
4720
|
+
if (!run.evaluation) verificationDebt.add("Changed files exist but no post-run check was recorded.");
|
|
4721
|
+
if (scope.sensitiveFiles.length > 0) verificationDebt.add("Sensitive files changed. Review and verify before continuing.");
|
|
4722
|
+
if (scope.forbiddenFiles.length > 0) verificationDebt.add("Forbidden files changed. Manual containment required.");
|
|
4723
|
+
if (changedFiles.length > maxFiles) verificationDebt.add("Too many files changed for one scoped run. Split the task.");
|
|
4724
|
+
if (lowerChanged.some((f) => /(^|\/)(package-lock\.json|pnpm-lock\.yaml|yarn\.lock)$/.test(f))) {
|
|
4725
|
+
verificationDebt.add("Lockfile changed. Confirm dependency intent.");
|
|
4726
|
+
}
|
|
4727
|
+
if (lowerChanged.some((f) => /(migration|migrations|schema|database)/.test(f))) {
|
|
4728
|
+
verificationDebt.add("Database or migration-related changes need explicit verification.");
|
|
4729
|
+
}
|
|
4730
|
+
if (lowerChanged.some((f) => /(middleware|auth|login|session|jwt|payment|billing|stripe|webhook)/.test(f))) {
|
|
4731
|
+
verificationDebt.add("Auth, middleware, payment, or webhook surface changed. Run focused verification.");
|
|
4732
|
+
}
|
|
4733
|
+
if (scope.outOfScopeFiles.length > 0) {
|
|
4734
|
+
verificationDebt.add("Some changed files appear outside declared relevant scope.");
|
|
4735
|
+
}
|
|
4736
|
+
for (const item of (_j = (_i = run.evaluation) == null ? void 0 : _i.missingProofItems) != null ? _j : []) verificationDebt.add(item);
|
|
4789
4737
|
}
|
|
4790
|
-
for (const item of (_j = (_i = run.evaluation) == null ? void 0 : _i.missingProofItems) != null ? _j : []) verificationDebt.add(item);
|
|
4791
4738
|
let nextSafeAction = "Run is ready to continue.";
|
|
4792
4739
|
if (scope.forbiddenFiles.length > 0) {
|
|
4793
4740
|
nextSafeAction = "Stop and inspect forbidden files before continuing.";
|
|
@@ -5103,7 +5050,7 @@ program.command("panel").description("Open local RunTrim browser panel").option(
|
|
|
5103
5050
|
});
|
|
5104
5051
|
});
|
|
5105
5052
|
program.command("memory").description("Show project memory and latest next safe prompt").option("--prompt", "Print only latest next safe prompt").option("--full", "Print full memory markdown").action(async (options) => {
|
|
5106
|
-
var _a2, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m;
|
|
5053
|
+
var _a2, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r;
|
|
5107
5054
|
const cwd = process.cwd();
|
|
5108
5055
|
console.log("");
|
|
5109
5056
|
console.log(BOLD("RunTrim") + DIM(" memory"));
|
|
@@ -5221,7 +5168,10 @@ program.command("memory").description("Show project memory and latest next safe
|
|
|
5221
5168
|
}
|
|
5222
5169
|
console.log("");
|
|
5223
5170
|
console.log(BOLD("Continuation"));
|
|
5224
|
-
|
|
5171
|
+
const noChangesState = status === "no_changes_detected" || ((_r = (_q = (_n = latestRun.checkSummary) == null ? void 0 : _n.changedFilesCount) != null ? _q : (_p = (_o = latestRun.evaluation) == null ? void 0 : _o.changedFiles) == null ? void 0 : _p.length) != null ? _r : 0) === 0;
|
|
5172
|
+
if (noChangesState) {
|
|
5173
|
+
console.log(chalk.white("No continuation prompt needed yet. Run `runtrim continue --reason usage_limit` when context runs out."));
|
|
5174
|
+
} else if (latestPrompt) {
|
|
5225
5175
|
const compact = latestPrompt.replace(/\s+/g, " ").trim();
|
|
5226
5176
|
const isDrift = /scope drift detected/i.test(compact);
|
|
5227
5177
|
if (isDrift) {
|