runtrim 0.1.9 → 0.1.10
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 +171 -122
- package/package.json +1 -1
package/dist-cli/runtrim.js
CHANGED
|
@@ -1947,15 +1947,6 @@ import fs7 from "fs";
|
|
|
1947
1947
|
import path7 from "path";
|
|
1948
1948
|
var BRIDGE_START = "<!-- RUNTRIM_BRIDGE_START -->";
|
|
1949
1949
|
var BRIDGE_END = "<!-- RUNTRIM_BRIDGE_END -->";
|
|
1950
|
-
var BRIDGE_BLOCK = `
|
|
1951
|
-
${BRIDGE_START}
|
|
1952
|
-
Before editing code, read RUNTRIM.md and .runtrim/contracts/latest.md.
|
|
1953
|
-
Stay inside the active scoped contract.
|
|
1954
|
-
Do not touch forbidden files or unrelated systems.
|
|
1955
|
-
If scope expands, stop and ask for a new RunTrim run.
|
|
1956
|
-
After editing, run: runtrim finish
|
|
1957
|
-
${BRIDGE_END}
|
|
1958
|
-
`;
|
|
1959
1950
|
var TOKEN_BUDGET_MAP = {
|
|
1960
1951
|
low: 1e4,
|
|
1961
1952
|
medium: 25e3,
|
|
@@ -1967,10 +1958,9 @@ function deriveBridgeContext(task, contract, recentRuns, projectName) {
|
|
|
1967
1958
|
const c = contract.contract;
|
|
1968
1959
|
const riskLevel = (_a2 = contract.wasteRiskAfter) != null ? _a2 : "medium";
|
|
1969
1960
|
const tokenBudget = (_b = TOKEN_BUDGET_MAP[riskLevel]) != null ? _b : 25e3;
|
|
1970
|
-
const
|
|
1971
|
-
|
|
1972
|
-
|
|
1973
|
-
];
|
|
1961
|
+
const stopFromRules = (_c = c.stopRules) != null ? _c : [];
|
|
1962
|
+
const stopFromAsk = ((_d = c.whenToAsk) != null ? _d : []).map((s) => `Stop and ask before: ${s}`);
|
|
1963
|
+
const stopConditions = [...stopFromRules, ...stopFromAsk];
|
|
1974
1964
|
const verificationSteps = (_e = c.successCriteria) != null ? _e : [];
|
|
1975
1965
|
const lines = recentRuns.slice(0, 3).map((r) => {
|
|
1976
1966
|
const day = new Date(r.createdAt).toLocaleDateString("en-US", {
|
|
@@ -1994,6 +1984,126 @@ ${lines.join("\n")}` : "No prior runs. This is the first run for this project.";
|
|
|
1994
1984
|
projectName
|
|
1995
1985
|
};
|
|
1996
1986
|
}
|
|
1987
|
+
function writeCanonicalRuntrimMd(cwd = process.cwd(), projectName) {
|
|
1988
|
+
const lines = [
|
|
1989
|
+
"# RunTrim Protocol",
|
|
1990
|
+
"",
|
|
1991
|
+
...projectName ? [`Project: ${projectName}`, ""] : [],
|
|
1992
|
+
"This repo uses RunTrim as the guarded AI coding control layer.",
|
|
1993
|
+
"",
|
|
1994
|
+
"## How to start an AI coding task",
|
|
1995
|
+
"",
|
|
1996
|
+
"```",
|
|
1997
|
+
'runtrim go "<task>"',
|
|
1998
|
+
"```",
|
|
1999
|
+
"",
|
|
2000
|
+
"RunTrim creates a scoped contract, loads project memory, and generates a guarded prompt.",
|
|
2001
|
+
"",
|
|
2002
|
+
"## How to use your agent",
|
|
2003
|
+
"",
|
|
2004
|
+
"Paste the guarded prompt into Claude Code, Codex, Cursor, or any other coding agent.",
|
|
2005
|
+
"",
|
|
2006
|
+
"## After edits",
|
|
2007
|
+
"",
|
|
2008
|
+
"```",
|
|
2009
|
+
"runtrim finish",
|
|
2010
|
+
"```",
|
|
2011
|
+
"",
|
|
2012
|
+
"RunTrim checks changed files, detects drift, scores risk, and saves the run report.",
|
|
2013
|
+
"",
|
|
2014
|
+
"## If you are an AI coding agent",
|
|
2015
|
+
"",
|
|
2016
|
+
"1. Read `.runtrim/contracts/latest.md`.",
|
|
2017
|
+
" - If `Status: active` \u2014 a live task exists. Follow the contract strictly.",
|
|
2018
|
+
' - If `Status: none` \u2014 no active task. Ask the user to run `runtrim go "<task>"` first.',
|
|
2019
|
+
"2. Do not assume any prior task is still active.",
|
|
2020
|
+
"3. Stay inside the allowed scope defined in the contract.",
|
|
2021
|
+
"4. Stop and ask before touching any forbidden area.",
|
|
2022
|
+
"5. Do not read or write `.env` files or secrets.",
|
|
2023
|
+
"6. After editing, tell the user to run: `runtrim finish`",
|
|
2024
|
+
"",
|
|
2025
|
+
"---",
|
|
2026
|
+
`Protocol: runtrim init. Updated: ${(/* @__PURE__ */ new Date()).toISOString()}`
|
|
2027
|
+
];
|
|
2028
|
+
fs7.writeFileSync(path7.join(cwd, "RUNTRIM.md"), lines.join("\n"), "utf-8");
|
|
2029
|
+
}
|
|
2030
|
+
function writeRestingContract(cwd = process.cwd()) {
|
|
2031
|
+
const dir = path7.join(getConfigDir(cwd), "contracts");
|
|
2032
|
+
if (!fs7.existsSync(dir)) fs7.mkdirSync(dir, { recursive: true });
|
|
2033
|
+
const content = [
|
|
2034
|
+
"# RunTrim Contract",
|
|
2035
|
+
"",
|
|
2036
|
+
"Status: none",
|
|
2037
|
+
"",
|
|
2038
|
+
"No active RunTrim contract.",
|
|
2039
|
+
"",
|
|
2040
|
+
"Start one with:",
|
|
2041
|
+
"",
|
|
2042
|
+
"```",
|
|
2043
|
+
'runtrim go "<your task>"',
|
|
2044
|
+
"```",
|
|
2045
|
+
"",
|
|
2046
|
+
"---",
|
|
2047
|
+
`Reset by runtrim finish. Updated: ${(/* @__PURE__ */ new Date()).toISOString()}`
|
|
2048
|
+
].join("\n");
|
|
2049
|
+
fs7.writeFileSync(path7.join(dir, "latest.md"), content, "utf-8");
|
|
2050
|
+
}
|
|
2051
|
+
function writeRestingMemory(cwd = process.cwd()) {
|
|
2052
|
+
const dir = path7.join(getConfigDir(cwd), "memory");
|
|
2053
|
+
if (!fs7.existsSync(dir)) fs7.mkdirSync(dir, { recursive: true });
|
|
2054
|
+
const content = [
|
|
2055
|
+
"# RunTrim Memory",
|
|
2056
|
+
"",
|
|
2057
|
+
"Status: none",
|
|
2058
|
+
"",
|
|
2059
|
+
"No active RunTrim session.",
|
|
2060
|
+
"",
|
|
2061
|
+
"Project baseline is in `.runtrim/memory/baseline.md`.",
|
|
2062
|
+
"",
|
|
2063
|
+
"Start a new session with:",
|
|
2064
|
+
"",
|
|
2065
|
+
"```",
|
|
2066
|
+
'runtrim go "<your task>"',
|
|
2067
|
+
"```",
|
|
2068
|
+
"",
|
|
2069
|
+
"---",
|
|
2070
|
+
`Reset by runtrim finish. Updated: ${(/* @__PURE__ */ new Date()).toISOString()}`
|
|
2071
|
+
].join("\n");
|
|
2072
|
+
fs7.writeFileSync(path7.join(dir, "current.md"), content, "utf-8");
|
|
2073
|
+
}
|
|
2074
|
+
function archiveContract(cwd, runId) {
|
|
2075
|
+
const contractsDir = path7.join(getConfigDir(cwd), "contracts");
|
|
2076
|
+
const latestPath = path7.join(contractsDir, "latest.md");
|
|
2077
|
+
if (!fs7.existsSync(latestPath)) return;
|
|
2078
|
+
const content = fs7.readFileSync(latestPath, "utf-8");
|
|
2079
|
+
if (content.includes("Status: none")) return;
|
|
2080
|
+
const archiveDir = path7.join(contractsDir, "archive");
|
|
2081
|
+
if (!fs7.existsSync(archiveDir)) fs7.mkdirSync(archiveDir, { recursive: true });
|
|
2082
|
+
fs7.writeFileSync(path7.join(archiveDir, `${runId}.md`), content, "utf-8");
|
|
2083
|
+
}
|
|
2084
|
+
function archiveMemory(cwd, runId) {
|
|
2085
|
+
const memoryDir = path7.join(getConfigDir(cwd), "memory");
|
|
2086
|
+
const currentPath = path7.join(memoryDir, "current.md");
|
|
2087
|
+
if (!fs7.existsSync(currentPath)) return;
|
|
2088
|
+
const content = fs7.readFileSync(currentPath, "utf-8");
|
|
2089
|
+
if (content.includes("Status: none")) return;
|
|
2090
|
+
const archiveDir = path7.join(memoryDir, "archive");
|
|
2091
|
+
if (!fs7.existsSync(archiveDir)) fs7.mkdirSync(archiveDir, { recursive: true });
|
|
2092
|
+
fs7.writeFileSync(path7.join(archiveDir, `${runId}.md`), content, "utf-8");
|
|
2093
|
+
}
|
|
2094
|
+
function removeBridgeBlock(filePath) {
|
|
2095
|
+
if (!fs7.existsSync(filePath)) return false;
|
|
2096
|
+
const content = fs7.readFileSync(filePath, "utf-8");
|
|
2097
|
+
const startIdx = content.indexOf(BRIDGE_START);
|
|
2098
|
+
const endIdx = content.indexOf(BRIDGE_END);
|
|
2099
|
+
if (startIdx === -1 || endIdx === -1) return false;
|
|
2100
|
+
const before = content.slice(0, startIdx).trimEnd();
|
|
2101
|
+
const after = content.slice(endIdx + BRIDGE_END.length).replace(/^\n+/, "\n");
|
|
2102
|
+
const newContent = (before + after).trimEnd() + "\n";
|
|
2103
|
+
if (newContent === content) return false;
|
|
2104
|
+
fs7.writeFileSync(filePath, newContent, "utf-8");
|
|
2105
|
+
return true;
|
|
2106
|
+
}
|
|
1997
2107
|
function writeContractFile(ctx, cwd = process.cwd()) {
|
|
1998
2108
|
const dir = path7.join(getConfigDir(cwd), "contracts");
|
|
1999
2109
|
if (!fs7.existsSync(dir)) fs7.mkdirSync(dir, { recursive: true });
|
|
@@ -2001,13 +2111,15 @@ function writeContractFile(ctx, cwd = process.cwd()) {
|
|
|
2001
2111
|
const forbidLines = ctx.forbiddenScope.length > 0 ? ctx.forbiddenScope.map((s) => `- ${s}`) : ["- .env* files", "- auth logic", "- database schema / migrations", "- billing and payment logic"];
|
|
2002
2112
|
const stopLines = ctx.stopConditions.length > 0 ? ctx.stopConditions.map((s) => `- ${s}`) : [
|
|
2003
2113
|
"- Stop if scope must expand beyond the task.",
|
|
2004
|
-
"- Stop
|
|
2114
|
+
"- Stop and ask before touching any forbidden area.",
|
|
2005
2115
|
"- Stop if more than 5 files require changes."
|
|
2006
2116
|
];
|
|
2007
2117
|
const verifyLines = ctx.verificationSteps.length > 0 ? ctx.verificationSteps.map((s) => `- ${s}`) : ["- Verify the behavior described in the task.", "- Check no unrelated files changed."];
|
|
2008
2118
|
const lines = [
|
|
2009
2119
|
"# RunTrim Active Contract",
|
|
2010
2120
|
"",
|
|
2121
|
+
"Status: active",
|
|
2122
|
+
"",
|
|
2011
2123
|
`Task: ${ctx.task}`,
|
|
2012
2124
|
`Goal: ${ctx.goal}`,
|
|
2013
2125
|
`Risk: ${ctx.riskLevel}`,
|
|
@@ -2039,6 +2151,8 @@ function writeMemoryFile(ctx, cwd = process.cwd()) {
|
|
|
2039
2151
|
const lines = [
|
|
2040
2152
|
"# RunTrim Memory Pack",
|
|
2041
2153
|
"",
|
|
2154
|
+
"Status: active",
|
|
2155
|
+
"",
|
|
2042
2156
|
`Project: ${ctx.projectName}`,
|
|
2043
2157
|
`Current task: ${ctx.task}`,
|
|
2044
2158
|
`Updated: ${(/* @__PURE__ */ new Date()).toISOString()}`,
|
|
@@ -2067,15 +2181,17 @@ function writeBridgeInstructions(cwd = process.cwd()) {
|
|
|
2067
2181
|
"",
|
|
2068
2182
|
"## Before editing",
|
|
2069
2183
|
"",
|
|
2070
|
-
"Read
|
|
2071
|
-
"
|
|
2072
|
-
"- .
|
|
2073
|
-
|
|
2184
|
+
"1. Read `RUNTRIM.md`.",
|
|
2185
|
+
"2. Read `.runtrim/contracts/latest.md`.",
|
|
2186
|
+
" - If `Status: active` \u2014 follow the contract strictly.",
|
|
2187
|
+
' - If `Status: none` \u2014 stop. Ask the user to run `runtrim go "<task>"` first.',
|
|
2188
|
+
"3. If the contract is active, read `.runtrim/memory/current.md` for session context.",
|
|
2189
|
+
" If no active session, read `.runtrim/memory/baseline.md` for project baseline.",
|
|
2074
2190
|
"",
|
|
2075
2191
|
"## During editing",
|
|
2076
2192
|
"",
|
|
2077
2193
|
"- Stay within the allowed scope defined in the contract.",
|
|
2078
|
-
"-
|
|
2194
|
+
"- Stop and ask the user before touching any forbidden area.",
|
|
2079
2195
|
"- Make minimal, targeted changes only.",
|
|
2080
2196
|
"- Do not refactor, rename, or reorganize outside the task scope.",
|
|
2081
2197
|
"- Do not add console.log statements or debug artifacts.",
|
|
@@ -2088,56 +2204,10 @@ function writeBridgeInstructions(cwd = process.cwd()) {
|
|
|
2088
2204
|
"- Do not run runtrim commands yourself unless explicitly asked.",
|
|
2089
2205
|
"",
|
|
2090
2206
|
"---",
|
|
2091
|
-
"Generated by RunTrim
|
|
2207
|
+
"Generated by RunTrim. Do not edit manually."
|
|
2092
2208
|
];
|
|
2093
2209
|
fs7.writeFileSync(path7.join(dir, "agent-instructions.md"), lines.join("\n"), "utf-8");
|
|
2094
2210
|
}
|
|
2095
|
-
function writeRootProtocolFile(ctx, cwd = process.cwd()) {
|
|
2096
|
-
const lines = [
|
|
2097
|
-
"# RunTrim Protocol",
|
|
2098
|
-
"",
|
|
2099
|
-
"This project is guarded by RunTrim Bridge Mode.",
|
|
2100
|
-
"",
|
|
2101
|
-
"## Active session",
|
|
2102
|
-
"",
|
|
2103
|
-
`Task: ${ctx.task}`,
|
|
2104
|
-
`Risk: ${ctx.riskLevel}`,
|
|
2105
|
-
`Token budget: ~${ctx.tokenBudget.toLocaleString()}`,
|
|
2106
|
-
"",
|
|
2107
|
-
"## Before editing",
|
|
2108
|
-
"",
|
|
2109
|
-
"Read the active contract before making any changes:",
|
|
2110
|
-
"",
|
|
2111
|
-
"```",
|
|
2112
|
-
".runtrim/contracts/latest.md",
|
|
2113
|
-
"```",
|
|
2114
|
-
"",
|
|
2115
|
-
"## Rules",
|
|
2116
|
-
"",
|
|
2117
|
-
"- Stay inside the active scoped contract.",
|
|
2118
|
-
"- Do not touch forbidden files or unrelated systems.",
|
|
2119
|
-
"- If scope must expand, stop and ask the user to start a new RunTrim session.",
|
|
2120
|
-
"- Keep changes minimal and targeted.",
|
|
2121
|
-
"- Do not refactor, reorganize, or rename outside the direct task.",
|
|
2122
|
-
"",
|
|
2123
|
-
"## After editing",
|
|
2124
|
-
"",
|
|
2125
|
-
"The user will run: runtrim finish",
|
|
2126
|
-
"",
|
|
2127
|
-
"Do not attempt to run runtrim commands yourself.",
|
|
2128
|
-
"",
|
|
2129
|
-
"---",
|
|
2130
|
-
`Generated by RunTrim Bridge. Updated: ${(/* @__PURE__ */ new Date()).toISOString()}`
|
|
2131
|
-
];
|
|
2132
|
-
fs7.writeFileSync(path7.join(cwd, "RUNTRIM.md"), lines.join("\n"), "utf-8");
|
|
2133
|
-
}
|
|
2134
|
-
function appendBridgeBlock(filePath) {
|
|
2135
|
-
if (!fs7.existsSync(filePath)) return false;
|
|
2136
|
-
const content = fs7.readFileSync(filePath, "utf-8");
|
|
2137
|
-
if (content.includes(BRIDGE_START)) return false;
|
|
2138
|
-
fs7.writeFileSync(filePath, content.trimEnd() + "\n" + BRIDGE_BLOCK, "utf-8");
|
|
2139
|
-
return true;
|
|
2140
|
-
}
|
|
2141
2211
|
function writeBridgeFiles(ctx, cwd) {
|
|
2142
2212
|
const written = [];
|
|
2143
2213
|
const managedPaths = [];
|
|
@@ -2145,22 +2215,18 @@ function writeBridgeFiles(ctx, cwd) {
|
|
|
2145
2215
|
managedPaths.push(relativePath);
|
|
2146
2216
|
written.push(label != null ? label : relativePath);
|
|
2147
2217
|
};
|
|
2148
|
-
writeRootProtocolFile(ctx, cwd);
|
|
2149
|
-
track("RUNTRIM.md");
|
|
2150
2218
|
writeContractFile(ctx, cwd);
|
|
2151
2219
|
track(".runtrim/contracts/latest.md");
|
|
2152
2220
|
writeMemoryFile(ctx, cwd);
|
|
2153
2221
|
track(".runtrim/memory/current.md");
|
|
2154
2222
|
writeBridgeInstructions(cwd);
|
|
2155
2223
|
track(".runtrim/bridge/agent-instructions.md");
|
|
2156
|
-
if (appendBridgeBlock(path7.join(cwd, "CLAUDE.md"))) track("CLAUDE.md", "CLAUDE.md (bridge block appended)");
|
|
2157
|
-
if (appendBridgeBlock(path7.join(cwd, "AGENTS.md"))) track("AGENTS.md", "AGENTS.md (bridge block appended)");
|
|
2158
2224
|
return { written, managedPaths };
|
|
2159
2225
|
}
|
|
2160
2226
|
function buildBridgePrompt(contractText, ctx) {
|
|
2161
2227
|
const allowedList = ctx.allowedScope.length > 0 ? ctx.allowedScope.map((s) => ` - ${s}`).join("\n") : " - Defined in .runtrim/contracts/latest.md";
|
|
2162
2228
|
const forbidList = ctx.forbiddenScope.length > 0 ? ctx.forbiddenScope.map((s) => ` - ${s}`).join("\n") : " - .env files, auth, database schema, billing, payments";
|
|
2163
|
-
const stopList = ctx.stopConditions.length > 0 ? ctx.stopConditions.slice(0, 4).map((s) => ` - ${s}`).join("\n") : " - Stop if more than 5 files need changes.\n - Stop
|
|
2229
|
+
const stopList = ctx.stopConditions.length > 0 ? ctx.stopConditions.slice(0, 4).map((s) => ` - ${s}`).join("\n") : " - Stop if more than 5 files need changes.\n - Stop and ask before touching any forbidden area.";
|
|
2164
2230
|
const header = [
|
|
2165
2231
|
"RUNTRIM BRIDGE SESSION",
|
|
2166
2232
|
`Task: ${ctx.task}`,
|
|
@@ -2182,7 +2248,7 @@ function buildBridgePrompt(contractText, ctx) {
|
|
|
2182
2248
|
" - Read RUNTRIM.md and .runtrim/contracts/latest.md before touching any file.",
|
|
2183
2249
|
" - Inspect first. List relevant files before opening them.",
|
|
2184
2250
|
" - Make the minimal change required. No unrelated refactors.",
|
|
2185
|
-
" -
|
|
2251
|
+
" - Stop and ask before touching any forbidden area.",
|
|
2186
2252
|
" - After editing, tell the user which files changed. They will run: runtrim finish",
|
|
2187
2253
|
""
|
|
2188
2254
|
].join("\n");
|
|
@@ -4227,55 +4293,7 @@ function installProtocol(cwd, baseline, opts = {}) {
|
|
|
4227
4293
|
const testCmd = (_f = (_e = scripts["test"]) != null ? _e : scripts["test:run"]) != null ? _f : null;
|
|
4228
4294
|
const runtrimMdPath = path10.join(cwd, "RUNTRIM.md");
|
|
4229
4295
|
const runtrimMdExists = fs10.existsSync(runtrimMdPath);
|
|
4230
|
-
|
|
4231
|
-
"# RunTrim Protocol",
|
|
4232
|
-
"",
|
|
4233
|
-
"This repo uses RunTrim as the guarded AI coding control layer.",
|
|
4234
|
-
"",
|
|
4235
|
-
"## Starting an AI coding task",
|
|
4236
|
-
"",
|
|
4237
|
-
"Before any agent touches code, run:",
|
|
4238
|
-
"",
|
|
4239
|
-
"```",
|
|
4240
|
-
'runtrim go "<describe the task>"',
|
|
4241
|
-
"```",
|
|
4242
|
-
"",
|
|
4243
|
-
"This creates a scoped contract, loads project memory, and generates the guarded prompt for your agent.",
|
|
4244
|
-
"",
|
|
4245
|
-
"## Using your agent",
|
|
4246
|
-
"",
|
|
4247
|
-
"Paste the guarded prompt into Claude Code, Codex, Cursor, or any other AI coding agent.",
|
|
4248
|
-
"The agent receives allowed scope, forbidden areas, stop rules, and verification requirements.",
|
|
4249
|
-
"",
|
|
4250
|
-
"## After edits",
|
|
4251
|
-
"",
|
|
4252
|
-
"Run:",
|
|
4253
|
-
"",
|
|
4254
|
-
"```",
|
|
4255
|
-
"runtrim finish",
|
|
4256
|
-
"```",
|
|
4257
|
-
"",
|
|
4258
|
-
"This checks changed files, detects drift, scores risk, and saves the run report.",
|
|
4259
|
-
"",
|
|
4260
|
-
"## If you are an AI coding agent",
|
|
4261
|
-
"",
|
|
4262
|
-
"1. Read `.runtrim/contracts/latest.md` before touching any file.",
|
|
4263
|
-
"2. Stay inside the allowed scope defined in the contract.",
|
|
4264
|
-
"3. Do not touch forbidden systems or unrelated files.",
|
|
4265
|
-
"4. Stop immediately if scope must expand beyond the contract.",
|
|
4266
|
-
"5. Do not read, write, or reference `.env` files or secrets.",
|
|
4267
|
-
"6. Do not refactor code outside the direct task.",
|
|
4268
|
-
"7. After editing, tell the user to run: `runtrim finish`",
|
|
4269
|
-
"",
|
|
4270
|
-
"## Active contract",
|
|
4271
|
-
"",
|
|
4272
|
-
"If `.runtrim/contracts/latest.md` exists, it contains the active task contract.",
|
|
4273
|
-
"Follow it exactly.",
|
|
4274
|
-
"",
|
|
4275
|
-
"---",
|
|
4276
|
-
`Generated by RunTrim. Updated: ${now}`
|
|
4277
|
-
].join("\n");
|
|
4278
|
-
fs10.writeFileSync(runtrimMdPath, runtrimMd, "utf-8");
|
|
4296
|
+
writeCanonicalRuntrimMd(cwd, baseline.projectName);
|
|
4279
4297
|
const projectJsonPath = path10.join(configDir, "project.json");
|
|
4280
4298
|
const projectJsonExists = fs10.existsSync(projectJsonPath);
|
|
4281
4299
|
const projectJson = {
|
|
@@ -4369,8 +4387,9 @@ function installProtocol(cwd, baseline, opts = {}) {
|
|
|
4369
4387
|
for (const filename of agentTargets) {
|
|
4370
4388
|
const filePath = path10.join(cwd, filename);
|
|
4371
4389
|
if (fs10.existsSync(filePath)) {
|
|
4390
|
+
removeBridgeBlock(filePath);
|
|
4372
4391
|
const result = upsertProtocolBlock(filePath);
|
|
4373
|
-
|
|
4392
|
+
agentResults.push({ file: filename, result: result === "skipped" ? "unchanged" : result });
|
|
4374
4393
|
} else if (opts.agentFiles) {
|
|
4375
4394
|
createMinimalAgentPointerFile(filePath, filename);
|
|
4376
4395
|
agentResults.push({ file: filename, result: "created" });
|
|
@@ -4416,6 +4435,18 @@ function installProtocol(cwd, baseline, opts = {}) {
|
|
|
4416
4435
|
fs10.writeFileSync(mdcPath, cursorMdc, "utf-8");
|
|
4417
4436
|
cursorResult = existed ? "updated" : "created";
|
|
4418
4437
|
}
|
|
4438
|
+
const contractsDir = path10.join(configDir, "contracts");
|
|
4439
|
+
const latestContractPath = path10.join(contractsDir, "latest.md");
|
|
4440
|
+
const contractIsStale = fs10.existsSync(latestContractPath) && !fs10.readFileSync(latestContractPath, "utf-8").includes("Status: none");
|
|
4441
|
+
if (!fs10.existsSync(latestContractPath) || contractIsStale) {
|
|
4442
|
+
writeRestingContract(cwd);
|
|
4443
|
+
}
|
|
4444
|
+
const memoryDir = path10.join(configDir, "memory");
|
|
4445
|
+
const currentMemoryPath = path10.join(memoryDir, "current.md");
|
|
4446
|
+
const memoryIsStale = fs10.existsSync(currentMemoryPath) && !fs10.readFileSync(currentMemoryPath, "utf-8").includes("Status: none");
|
|
4447
|
+
if (!fs10.existsSync(currentMemoryPath) || memoryIsStale) {
|
|
4448
|
+
writeRestingMemory(cwd);
|
|
4449
|
+
}
|
|
4419
4450
|
return {
|
|
4420
4451
|
runtrimMd: runtrimMdExists ? "updated" : "created",
|
|
4421
4452
|
projectJson: projectJsonExists ? "updated" : "created",
|
|
@@ -6411,6 +6442,14 @@ program.command("finish").description("Bridge Mode: evaluate agent output, check
|
|
|
6411
6442
|
const freshRuns = loadAllRuns(cwd);
|
|
6412
6443
|
const updatedRun = (_k = freshRuns.find((r) => r.id === activeRun.id)) != null ? _k : activeRun;
|
|
6413
6444
|
writeMemoryFromRuns(updatedRun, freshRuns, config, cwd);
|
|
6445
|
+
archiveContract(cwd, activeRun.id);
|
|
6446
|
+
archiveMemory(cwd, activeRun.id);
|
|
6447
|
+
writeCanonicalRuntrimMd(cwd, projectName);
|
|
6448
|
+
writeRestingContract(cwd);
|
|
6449
|
+
writeRestingMemory(cwd);
|
|
6450
|
+
const bridgeRemovals = [];
|
|
6451
|
+
if (removeBridgeBlock(path10.join(cwd, "CLAUDE.md"))) bridgeRemovals.push("CLAUDE.md");
|
|
6452
|
+
if (removeBridgeBlock(path10.join(cwd, "AGENTS.md"))) bridgeRemovals.push("AGENTS.md");
|
|
6414
6453
|
let synced = false;
|
|
6415
6454
|
if (options.sync !== false) {
|
|
6416
6455
|
const globalAuth = loadGlobalAuth();
|
|
@@ -6501,6 +6540,16 @@ program.command("finish").description("Bridge Mode: evaluate agent output, check
|
|
|
6501
6540
|
console.log(DIM(" ") + (synced ? chalk.white("Completed.") : DIM("Skipped. Run runtrim login to connect your dashboard.")));
|
|
6502
6541
|
console.log("");
|
|
6503
6542
|
}
|
|
6543
|
+
console.log(GO_ACCENT.bold("Protocol"));
|
|
6544
|
+
console.log(DIM(" ") + chalk.white("RUNTRIM.md restored"));
|
|
6545
|
+
console.log(DIM(" ") + chalk.white("latest contract archived"));
|
|
6546
|
+
console.log(DIM(" ") + chalk.white("current memory reset"));
|
|
6547
|
+
if (bridgeRemovals.length > 0) {
|
|
6548
|
+
for (const f of bridgeRemovals) {
|
|
6549
|
+
console.log(DIM(" ") + chalk.white(`${f} bridge block removed`));
|
|
6550
|
+
}
|
|
6551
|
+
}
|
|
6552
|
+
console.log("");
|
|
6504
6553
|
});
|
|
6505
6554
|
program.command("sync").description("Sync local run history and project memory to your RunTrim dashboard").option("--dry-run", "Show what would be synced without uploading").action(async (opts) => {
|
|
6506
6555
|
var _a2, _b, _c, _d, _e, _f;
|