mindweave 3.0.1 → 3.2.0
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/README.md +36 -4
- package/dist/alternator/chassis/lsp.js +36 -4
- package/dist/alternator/chassis/lsp.js.map +1 -1
- package/dist/alternator/chassis/provision.js +54 -6
- package/dist/alternator/chassis/provision.js.map +1 -1
- package/dist/alternator/chassis/servers.js +34 -21
- package/dist/alternator/chassis/servers.js.map +1 -1
- package/dist/cli/App.js +118 -16
- package/dist/cli/App.js.map +1 -1
- package/dist/cli/attachments.js +37 -1
- package/dist/cli/attachments.js.map +1 -1
- package/dist/cli/bootstrap.js +25 -3
- package/dist/cli/bootstrap.js.map +1 -1
- package/dist/cli/components/BlockView.js +5 -5
- package/dist/cli/components/BlockView.js.map +1 -1
- package/dist/cli/components/CommandGroup.js +100 -0
- package/dist/cli/components/CommandGroup.js.map +1 -0
- package/dist/cli/components/MarathonBox.js +2 -1
- package/dist/cli/components/MarathonBox.js.map +1 -1
- package/dist/cli/components/TipLine.js +1 -0
- package/dist/cli/components/TipLine.js.map +1 -1
- package/dist/cli/components/ToolLine.js +69 -14
- package/dist/cli/components/ToolLine.js.map +1 -1
- package/dist/cli/components/WorkGroup.js +115 -0
- package/dist/cli/components/WorkGroup.js.map +1 -0
- package/dist/cli/diffWrap.js +24 -0
- package/dist/cli/diffWrap.js.map +1 -0
- package/dist/cli/expandHits.js +74 -0
- package/dist/cli/expandHits.js.map +1 -0
- package/dist/cli/marathonUi.js +2 -0
- package/dist/cli/marathonUi.js.map +1 -1
- package/dist/cli/mouse.js +16 -8
- package/dist/cli/mouse.js.map +1 -1
- package/dist/cli/scrollGlide.js +72 -0
- package/dist/cli/scrollGlide.js.map +1 -0
- package/dist/cli/scrollPill.js +21 -1
- package/dist/cli/scrollPill.js.map +1 -1
- package/dist/cli/selfUpdate.js +7 -0
- package/dist/cli/selfUpdate.js.map +1 -1
- package/dist/cli/terminalRestore.js +1 -1
- package/dist/cli/terminalRestore.js.map +1 -1
- package/dist/cli/toolDisplay.js +14 -10
- package/dist/cli/toolDisplay.js.map +1 -1
- package/dist/cli/transcript.js +100 -29
- package/dist/cli/transcript.js.map +1 -1
- package/dist/cli/uiLines.js +60 -0
- package/dist/cli/uiLines.js.map +1 -0
- package/dist/cli/wheelStep.js +29 -0
- package/dist/cli/wheelStep.js.map +1 -0
- package/dist/cli/workLines.js +84 -0
- package/dist/cli/workLines.js.map +1 -0
- package/dist/core/permissions.js +26 -1
- package/dist/core/permissions.js.map +1 -1
- package/dist/core/spendView.js +8 -1
- package/dist/core/spendView.js.map +1 -1
- package/dist/core/turnRunner.js +36 -8
- package/dist/core/turnRunner.js.map +1 -1
- package/dist/drivers/deepseek/inlineTools.js +36 -2
- package/dist/drivers/deepseek/inlineTools.js.map +1 -1
- package/dist/drivers/ollama/endpoint.js +25 -0
- package/dist/drivers/ollama/endpoint.js.map +1 -1
- package/dist/dynamo/engine.js +414 -88
- package/dist/dynamo/engine.js.map +1 -1
- package/dist/dynamo/guard.js +11 -4
- package/dist/dynamo/guard.js.map +1 -1
- package/dist/dynamo/hooks.js +209 -0
- package/dist/dynamo/hooks.js.map +1 -0
- package/dist/dynamo/marathon.js +67 -10
- package/dist/dynamo/marathon.js.map +1 -1
- package/dist/dynamo/todoReminder.js +26 -0
- package/dist/dynamo/todoReminder.js.map +1 -0
- package/dist/governor/forbidden.js +19 -0
- package/dist/governor/forbidden.js.map +1 -1
- package/dist/governor/freshness.js +1 -1
- package/dist/governor/freshness.js.map +1 -1
- package/dist/governor/index.js +8 -1
- package/dist/governor/index.js.map +1 -1
- package/dist/governor/rules.js +1 -0
- package/dist/governor/rules.js.map +1 -1
- package/dist/governor/write.js +50 -2
- package/dist/governor/write.js.map +1 -1
- package/dist/mcp/config.js +0 -41
- package/dist/mcp/config.js.map +1 -1
- package/dist/mcp/projectApproval.js +117 -0
- package/dist/mcp/projectApproval.js.map +1 -0
- package/dist/mcp/resultStore.js +19 -5
- package/dist/mcp/resultStore.js.map +1 -1
- package/dist/mcp/transport/stdio.js +4 -1
- package/dist/mcp/transport/stdio.js.map +1 -1
- package/dist/memory/allMetas.js +1 -1
- package/dist/memory/allMetas.js.map +1 -1
- package/dist/memory/autoMemory.js +1 -0
- package/dist/memory/autoMemory.js.map +1 -1
- package/dist/memory/clearedArchive.js +120 -0
- package/dist/memory/clearedArchive.js.map +1 -0
- package/dist/memory/compaction.js +178 -15
- package/dist/memory/compaction.js.map +1 -1
- package/dist/memory/counters.js +64 -0
- package/dist/memory/counters.js.map +1 -0
- package/dist/memory/projectNotes.js +61 -13
- package/dist/memory/projectNotes.js.map +1 -1
- package/dist/memory/rewind.js +6 -2
- package/dist/memory/rewind.js.map +1 -1
- package/dist/memory/session.js +13 -5
- package/dist/memory/session.js.map +1 -1
- package/dist/memory/sessionMemory.js +6 -2
- package/dist/memory/sessionMemory.js.map +1 -1
- package/dist/memory/store.js +3 -0
- package/dist/memory/store.js.map +1 -1
- package/dist/memory/types.js.map +1 -1
- package/dist/memory/workingSet.js +0 -375
- package/dist/memory/workingSet.js.map +1 -1
- package/dist/project/context.js +54 -7
- package/dist/project/context.js.map +1 -1
- package/dist/tools/approval.js +19 -4
- package/dist/tools/approval.js.map +1 -1
- package/dist/tools/backgroundShells.js +8 -1
- package/dist/tools/backgroundShells.js.map +1 -1
- package/dist/tools/browser.js +2 -1
- package/dist/tools/browser.js.map +1 -1
- package/dist/tools/checkpoints.js +28 -4
- package/dist/tools/checkpoints.js.map +1 -1
- package/dist/tools/childEnv.js +50 -0
- package/dist/tools/childEnv.js.map +1 -0
- package/dist/tools/codeIntel.js +4 -1
- package/dist/tools/codeIntel.js.map +1 -1
- package/dist/tools/commandParse.js +238 -0
- package/dist/tools/commandParse.js.map +1 -0
- package/dist/tools/commandPolicy.js +283 -0
- package/dist/tools/commandPolicy.js.map +1 -0
- package/dist/tools/detail.js +113 -1
- package/dist/tools/detail.js.map +1 -1
- package/dist/tools/edit.js +2 -1
- package/dist/tools/edit.js.map +1 -1
- package/dist/tools/editRipple.js +18 -3
- package/dist/tools/editRipple.js.map +1 -1
- package/dist/tools/editTarget.js +11 -6
- package/dist/tools/editTarget.js.map +1 -1
- package/dist/tools/governorTools.js +61 -1
- package/dist/tools/governorTools.js.map +1 -1
- package/dist/tools/grep.js +13 -5
- package/dist/tools/grep.js.map +1 -1
- package/dist/tools/guard.js +249 -2
- package/dist/tools/guard.js.map +1 -1
- package/dist/tools/invisible.js +62 -0
- package/dist/tools/invisible.js.map +1 -0
- package/dist/tools/killTree.js +3 -0
- package/dist/tools/killTree.js.map +1 -1
- package/dist/tools/readFile.js +11 -3
- package/dist/tools/readFile.js.map +1 -1
- package/dist/tools/readSymbol.js +5 -24
- package/dist/tools/readSymbol.js.map +1 -1
- package/dist/tools/rebuildDetail.js +155 -0
- package/dist/tools/rebuildDetail.js.map +1 -0
- package/dist/tools/replaceSymbol.js +1 -1
- package/dist/tools/replaceSymbol.js.map +1 -1
- package/dist/tools/ripgrepShell.js +56 -0
- package/dist/tools/ripgrepShell.js.map +1 -0
- package/dist/tools/runCommand.js +77 -18
- package/dist/tools/runCommand.js.map +1 -1
- package/dist/tools/runsLater.js +50 -0
- package/dist/tools/runsLater.js.map +1 -0
- package/dist/tools/serverConsent.js +27 -0
- package/dist/tools/serverConsent.js.map +1 -0
- package/dist/tools/ui.js +81 -1
- package/dist/tools/ui.js.map +1 -1
- package/dist/tools/untrusted.js +22 -1
- package/dist/tools/untrusted.js.map +1 -1
- package/dist/tools/viewImage.js +2 -2
- package/dist/tools/viewImage.js.map +1 -1
- package/dist/tools/webFetch.js +76 -8
- package/dist/tools/webFetch.js.map +1 -1
- package/dist/tools/workspace.js +87 -24
- package/dist/tools/workspace.js.map +1 -1
- package/dist/tools/writeFile.js +9 -4
- package/dist/tools/writeFile.js.map +1 -1
- package/package.json +4 -4
package/dist/tools/readSymbol.js
CHANGED
|
@@ -13,10 +13,11 @@
|
|
|
13
13
|
*/
|
|
14
14
|
import { promises as fs } from "node:fs";
|
|
15
15
|
import { relativize, resolvePath, nextTouch, markScope } from "./paths.js";
|
|
16
|
-
import { addFocus
|
|
16
|
+
import { addFocus } from "./focus.js";
|
|
17
17
|
import { allChassis, symbolSpans } from "./chassisMux.js";
|
|
18
18
|
import { sliceBody } from "./spanCore.js";
|
|
19
19
|
import { fail, failQuietly } from "./results.js";
|
|
20
|
+
import { guardedPathReason } from "./guard.js";
|
|
20
21
|
// Even a single symbol can be huge (a 900-line class). Cap what we return so one
|
|
21
22
|
// read_symbol can't flood the context; the model can read_file a range for more.
|
|
22
23
|
const MAX_SYMBOL_LINES = 400;
|
|
@@ -85,6 +86,9 @@ export const readSymbolTool = {
|
|
|
85
86
|
}
|
|
86
87
|
const span = spans[0];
|
|
87
88
|
const abs = resolvePath(ctx, span.file);
|
|
89
|
+
const blocked = await guardedPathReason(abs);
|
|
90
|
+
if (blocked)
|
|
91
|
+
return fail(`Refusing to read ${relativize(ctx, span.file)}: it is ${blocked}.`);
|
|
88
92
|
let content;
|
|
89
93
|
let stat;
|
|
90
94
|
try {
|
|
@@ -113,29 +117,6 @@ export const readSymbolTool = {
|
|
|
113
117
|
touchedAt: nextTouch(),
|
|
114
118
|
focus: addFocus(prior?.focus, { start: span.start, end: span.end }),
|
|
115
119
|
});
|
|
116
|
-
// DEDUP, the same contract read_file has had and this tool never did. Once a file
|
|
117
|
-
// is in the working set, its content is rebuilt into the volatile tail on EVERY
|
|
118
|
-
// turn — so re-sending a symbol body the model is already looking at pays for the
|
|
119
|
-
// same lines twice, every time. Measured across terminal coding agents,
|
|
120
|
-
// repeated reads are ~42% of avoidable token spend, and this was our version of it:
|
|
121
|
-
// a session re-read the same four functions over and over while all four sat in
|
|
122
|
-
// <working_files>.
|
|
123
|
-
//
|
|
124
|
-
// Checked against what the working set actually PUT ON SCREEN this turn, not
|
|
125
|
-
// against the read ledger. The ledger records what was read once; it does not
|
|
126
|
-
// prove the text is still visible, and a sub-agent or a headless run has no
|
|
127
|
-
// working set at all — so trusting it would tell the model "you already have
|
|
128
|
-
// this" about content it cannot see. A wasted read is cheap; a phantom one makes
|
|
129
|
-
// the model work from text it never received. Also requires the file to be
|
|
130
|
-
// UNCHANGED: after an edit the new body has to come back.
|
|
131
|
-
const alreadyShown = unchanged && coversSpan(ctx.workingSetSpans?.get(abs), span.start, span.end);
|
|
132
|
-
if (alreadyShown) {
|
|
133
|
-
return {
|
|
134
|
-
output: `${span.kind} ${span.name} — ${shown}:${span.start}-${span.end} is already in your ` +
|
|
135
|
-
`<working_files> block, unchanged. Read it there rather than calling this again.`,
|
|
136
|
-
summary: `${span.name} (already in context)`,
|
|
137
|
-
};
|
|
138
|
-
}
|
|
139
120
|
return {
|
|
140
121
|
output: `${span.kind} ${span.name} — ${shown}:${span.start}-${span.end}\n${body}${truncated}${caveat}`,
|
|
141
122
|
summary: `read ${span.name} (${shown}:${span.start}-${span.end})`,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"readSymbol.js","sourceRoot":"","sources":["../../src/tools/readSymbol.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AACH,OAAO,EAAE,QAAQ,IAAI,EAAE,EAAE,MAAM,SAAS,CAAC;AAEzC,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAC3E,OAAO,EAAE,QAAQ,EAAE,
|
|
1
|
+
{"version":3,"file":"readSymbol.js","sourceRoot":"","sources":["../../src/tools/readSymbol.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* rebuildDetail.ts — the uncut block of a tool row, put back together for a session that
|
|
3
|
+
* was saved before the uncut text was kept (pure).
|
|
4
|
+
*
|
|
5
|
+
* A session file has always held what a row needs to be DRAWN (`detail`, cut short) and
|
|
6
|
+
* what the model needs (`content`), and it holds the call's own arguments. Those three
|
|
7
|
+
* are enough to rebuild the rest for the calls that matter most:
|
|
8
|
+
*
|
|
9
|
+
* - a written file: the call carries the whole file
|
|
10
|
+
* - an edit: the call carries every old and new string
|
|
11
|
+
* - a command: the model's copy of the output is the output
|
|
12
|
+
*
|
|
13
|
+
* It is a reconstruction, and says so by being limited to those three. A search, a read
|
|
14
|
+
* or any other tool has no uncut block worth opening and gets none. The command's copy is
|
|
15
|
+
* what the model was shown, which can already have had its middle cut, and that cut is
|
|
16
|
+
* kept as it was rather than papered over.
|
|
17
|
+
*/
|
|
18
|
+
import { FULL_DETAIL_MAX, multiEditDetail, oneLineSteps, sessionDetailFull, shellOutput, uiOpenedText, withScope, writeDetail } from "./detail.js";
|
|
19
|
+
import { pageLine } from "./ui.js";
|
|
20
|
+
/** The rows of `detail` that come before the body: the scope line of a diff. */
|
|
21
|
+
function leadingScope(detail) {
|
|
22
|
+
if (!detail)
|
|
23
|
+
return undefined;
|
|
24
|
+
const first = detail.split("\n")[0];
|
|
25
|
+
return /^[+-] /.test(first) || first.startsWith("$ ") ? undefined : first;
|
|
26
|
+
}
|
|
27
|
+
/** The `$ command` line and the closing verdict of a shell block, which the output does not hold. */
|
|
28
|
+
function shellFrame(detail) {
|
|
29
|
+
if (!detail)
|
|
30
|
+
return {};
|
|
31
|
+
const lines = detail.split("\n");
|
|
32
|
+
const head = lines[0]?.startsWith("$ ") ? lines[0] : undefined;
|
|
33
|
+
const last = lines[lines.length - 1];
|
|
34
|
+
const tail = last && /^[✓✗✖]/.test(last) ? last : undefined;
|
|
35
|
+
return { head, tail };
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* The block as the live row would have held it, bounded the way a saved session bounds it,
|
|
39
|
+
* or undefined when this call has nothing more to open.
|
|
40
|
+
*/
|
|
41
|
+
export function rebuildFull(tool, args, entry) {
|
|
42
|
+
if (!tool || !entry.detail)
|
|
43
|
+
return undefined;
|
|
44
|
+
let full;
|
|
45
|
+
if (tool === "write_file" && typeof args?.content === "string") {
|
|
46
|
+
const scope = leadingScope(entry.detail);
|
|
47
|
+
const body = writeDetail(args.content, FULL_DETAIL_MAX);
|
|
48
|
+
full = scope ? withScope(scope, body) : body;
|
|
49
|
+
}
|
|
50
|
+
else if (tool === "edit" && Array.isArray(args?.edits)) {
|
|
51
|
+
const ops = args.edits
|
|
52
|
+
.filter((e) => e && typeof e.old_string === "string" && typeof e.new_string === "string")
|
|
53
|
+
.map((e) => ({ oldString: e.old_string, newString: e.new_string }));
|
|
54
|
+
if (ops.length === 0)
|
|
55
|
+
return undefined;
|
|
56
|
+
const scope = leadingScope(entry.detail);
|
|
57
|
+
const body = multiEditDetail(ops, FULL_DETAIL_MAX);
|
|
58
|
+
full = scope ? withScope(scope, body) : body;
|
|
59
|
+
}
|
|
60
|
+
else if (tool === "run_command") {
|
|
61
|
+
// Output that context clearing has already replaced is not the output: rebuilding from it
|
|
62
|
+
// would show the model's note as if the command had printed it.
|
|
63
|
+
if (entry.content.includes("[old tool result cleared"))
|
|
64
|
+
return undefined;
|
|
65
|
+
const { head, tail } = shellFrame(entry.detail);
|
|
66
|
+
const out = shellOutput(entry.content, FULL_DETAIL_MAX);
|
|
67
|
+
full = [head, out || undefined, tail].filter((l) => !!l).join("\n");
|
|
68
|
+
}
|
|
69
|
+
return sessionDetailFull(entry.detail, full);
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* A written file's block taken from the file as it is now, for a saved session whose call no
|
|
73
|
+
* longer holds what it wrote (pure). Clearing old context empties a write call's text, and an
|
|
74
|
+
* older session never kept the uncut block, so the only copy left is the file itself.
|
|
75
|
+
*
|
|
76
|
+
* Used only when the file still has the line count the row said it wrote ("whole file · 846
|
|
77
|
+
* lines"): a file that has since changed size would show something that was not written, and
|
|
78
|
+
* a row that cannot be opened is better than one that opens onto the wrong text.
|
|
79
|
+
*/
|
|
80
|
+
export function writtenFromDisk(detail, onDisk) {
|
|
81
|
+
const scope = leadingScope(detail);
|
|
82
|
+
const said = scope?.match(/^(?:whole|new) file · ([\d,]+) lines?$/);
|
|
83
|
+
if (!said)
|
|
84
|
+
return undefined;
|
|
85
|
+
const lines = onDisk === "" ? 0 : onDisk.split("\n").length;
|
|
86
|
+
if (lines !== Number(said[1].replace(/,/g, "")))
|
|
87
|
+
return undefined;
|
|
88
|
+
return sessionDetailFull(detail, withScope(scope, writeDetail(onDisk, FULL_DETAIL_MAX)));
|
|
89
|
+
}
|
|
90
|
+
/** A control line as the model's list prints it: `[7] button "1. Chapter 1" (disabled)`. */
|
|
91
|
+
const CONTROL_LINE = /^\s*\[\d+\] (.+)$/;
|
|
92
|
+
/**
|
|
93
|
+
* A UI test's row as it was saved BEFORE it became a two-part row: the steps, then every
|
|
94
|
+
* control on the page, as one block of text (pure).
|
|
95
|
+
*
|
|
96
|
+
* Returns what the row shows now and, when there is something behind it, what opens. A run
|
|
97
|
+
* that went well becomes the steps and one line about the page, with the titled whole behind
|
|
98
|
+
* a click. A run that failed, or that had the page's own reports after the control list, is
|
|
99
|
+
* shown whole, but in the same titled form instead of the flat block. Undefined when this is
|
|
100
|
+
* not a control list at all (a list that says no control could be read), so the row is left
|
|
101
|
+
* exactly as it was.
|
|
102
|
+
*
|
|
103
|
+
* The kind of each control is the words before its name or its flags, which is how the list
|
|
104
|
+
* has always printed them.
|
|
105
|
+
*/
|
|
106
|
+
export function compactUiDetail(detail, isError) {
|
|
107
|
+
if (!detail)
|
|
108
|
+
return undefined;
|
|
109
|
+
const lines = detail.split("\n");
|
|
110
|
+
const first = lines.findIndex((l) => CONTROL_LINE.test(l) || /^In ".*":$/.test(l));
|
|
111
|
+
if (first < 0)
|
|
112
|
+
return undefined;
|
|
113
|
+
const counts = new Map();
|
|
114
|
+
const listed = [];
|
|
115
|
+
const after = [];
|
|
116
|
+
let off = 0;
|
|
117
|
+
let total = 0;
|
|
118
|
+
let inList = true;
|
|
119
|
+
for (const line of lines.slice(first)) {
|
|
120
|
+
if (!inList) {
|
|
121
|
+
after.push(line);
|
|
122
|
+
continue;
|
|
123
|
+
}
|
|
124
|
+
if (line.trim() === "" || /^\s*In ".*":$/.test(line) || /^\s*\u2026 and \d+ more not listed/.test(line)) {
|
|
125
|
+
if (line.trim() !== "")
|
|
126
|
+
listed.push(line.trim());
|
|
127
|
+
continue;
|
|
128
|
+
}
|
|
129
|
+
const m = CONTROL_LINE.exec(line);
|
|
130
|
+
if (!m) {
|
|
131
|
+
inList = false;
|
|
132
|
+
after.push(line);
|
|
133
|
+
continue;
|
|
134
|
+
}
|
|
135
|
+
listed.push(line.trim());
|
|
136
|
+
const kind = /^(.*?)(?: "| \(| =|$)/.exec(m[1])[1].trim();
|
|
137
|
+
counts.set(kind, (counts.get(kind) ?? 0) + 1);
|
|
138
|
+
if (/\(([^)]*,\s*)?out of view(,[^)]*)?\)/.test(m[1]))
|
|
139
|
+
off++;
|
|
140
|
+
total++;
|
|
141
|
+
}
|
|
142
|
+
if (total === 0)
|
|
143
|
+
return undefined;
|
|
144
|
+
const before = lines.slice(0, first).join("\n").trim();
|
|
145
|
+
const reports = after.join("\n").trim();
|
|
146
|
+
const whole = uiOpenedText({ did: before, list: listed.join("\n"), total, off, reports });
|
|
147
|
+
if (isError || reports)
|
|
148
|
+
return { detail: whole };
|
|
149
|
+
const steps = before.startsWith("Ran ") ? oneLineSteps(before) : before ? [before.split("\n").map((l) => l.trim()).filter(Boolean).join("\u21b5")] : [];
|
|
150
|
+
const kept = sessionDetailFull("", whole);
|
|
151
|
+
if (!kept)
|
|
152
|
+
return undefined;
|
|
153
|
+
return { detail: [...steps, pageLine(counts, off, total)].join("\n"), detailFull: kept };
|
|
154
|
+
}
|
|
155
|
+
//# sourceMappingURL=rebuildDetail.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rebuildDetail.js","sourceRoot":"","sources":["../../src/tools/rebuildDetail.ts"],"names":[],"mappings":"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"}
|
|
@@ -75,7 +75,7 @@ export const replaceSymbolBody = {
|
|
|
75
75
|
}
|
|
76
76
|
const span = spans[0];
|
|
77
77
|
const abs = resolvePath(ctx, span.file);
|
|
78
|
-
const target = await prepareEditTarget(ctx, abs, "editing");
|
|
78
|
+
const target = await prepareEditTarget(ctx, abs, "editing", typeof args.new_definition === "string" ? args.new_definition : "");
|
|
79
79
|
if (!target.ok)
|
|
80
80
|
return target.error;
|
|
81
81
|
// Unlike `edit`, this tool quotes NOTHING of what is already there — it names a
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"replaceSymbol.js","sourceRoot":"","sources":["../../src/tools/replaceSymbol.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"replaceSymbol.js","sourceRoot":"","sources":["../../src/tools/replaceSymbol.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ripgrepShell.ts — the bundled rg, for commands the agent runs, with the same exclusions
|
|
3
|
+
* the search tool applies.
|
|
4
|
+
*
|
|
5
|
+
* Mindweave ships ripgrep for its search tool, but a command the model ran could not use
|
|
6
|
+
* it: unless the user had installed rg themselves, `rg` was not found. And where it was
|
|
7
|
+
* found, it searched .env files and key folders that the search tool leaves out. So a
|
|
8
|
+
* command gets the bundled rg's folder at the front of PATH, and RIPGREP_CONFIG_PATH
|
|
9
|
+
* pointing at a policy file that excludes the same names (secrets, other agents' data).
|
|
10
|
+
* A user's own rg config is kept: its lines come first and the exclusions are added.
|
|
11
|
+
*
|
|
12
|
+
* Honest limit: rg obeys a config only when asked to; `--no-config` or `-uu` skips it.
|
|
13
|
+
* That is a command reading files by choice, which the command guard judges, not this.
|
|
14
|
+
*/
|
|
15
|
+
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
16
|
+
import { dirname, isAbsolute, join, delimiter } from "node:path";
|
|
17
|
+
import { ripgrepPath } from "./ripgrep.js";
|
|
18
|
+
import { SEARCH_EXCLUDE_GLOBS } from "./guard.js";
|
|
19
|
+
import { stateRoot } from "../memory/store.js";
|
|
20
|
+
let written = null;
|
|
21
|
+
/** Where the generated policy file lives, written once per process. */
|
|
22
|
+
function policyFile() {
|
|
23
|
+
if (written && existsSync(written))
|
|
24
|
+
return written;
|
|
25
|
+
try {
|
|
26
|
+
const dir = join(stateRoot(), "ripgrep");
|
|
27
|
+
mkdirSync(dir, { recursive: true });
|
|
28
|
+
const file = join(dir, "ripgreprc");
|
|
29
|
+
const own = process.env.RIPGREP_CONFIG_PATH;
|
|
30
|
+
let base = "";
|
|
31
|
+
if (own && own !== file && existsSync(own))
|
|
32
|
+
base = readFileSync(own, "utf8").trimEnd() + "\n";
|
|
33
|
+
const rules = SEARCH_EXCLUDE_GLOBS.map((g) => `--glob=!${g}`).join("\n");
|
|
34
|
+
writeFileSync(file, `${base}# Added by Mindweave: the files its search tool leaves out.\n${rules}\n`);
|
|
35
|
+
written = file;
|
|
36
|
+
return file;
|
|
37
|
+
}
|
|
38
|
+
catch {
|
|
39
|
+
return null;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
/** The environment additions for a command: PATH with the bundled rg, and the policy file. */
|
|
43
|
+
export function ripgrepShellEnv() {
|
|
44
|
+
const out = {};
|
|
45
|
+
const rg = ripgrepPath();
|
|
46
|
+
if (isAbsolute(rg) && existsSync(rg)) {
|
|
47
|
+
// Windows spells it "Path"; reuse whatever name is there so there is only one.
|
|
48
|
+
const key = Object.keys(process.env).find((k) => k.toUpperCase() === "PATH") ?? "PATH";
|
|
49
|
+
out[key] = `${dirname(rg)}${delimiter}${process.env[key] ?? ""}`;
|
|
50
|
+
}
|
|
51
|
+
const policy = policyFile();
|
|
52
|
+
if (policy)
|
|
53
|
+
out["RIPGREP_CONFIG_PATH"] = policy;
|
|
54
|
+
return out;
|
|
55
|
+
}
|
|
56
|
+
//# sourceMappingURL=ripgrepShell.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ripgrepShell.js","sourceRoot":"","sources":["../../src/tools/ripgrepShell.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AACH,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAC7E,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AACjE,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAC3C,OAAO,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AAClD,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAE/C,IAAI,OAAO,GAAkB,IAAI,CAAC;AAElC,uEAAuE;AACvE,SAAS,UAAU;IACjB,IAAI,OAAO,IAAI,UAAU,CAAC,OAAO,CAAC;QAAE,OAAO,OAAO,CAAC;IACnD,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,IAAI,CAAC,SAAS,EAAE,EAAE,SAAS,CAAC,CAAC;QACzC,SAAS,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QACpC,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,EAAE,WAAW,CAAC,CAAC;QACpC,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,mBAAmB,CAAC;QAC5C,IAAI,IAAI,GAAG,EAAE,CAAC;QACd,IAAI,GAAG,IAAI,GAAG,KAAK,IAAI,IAAI,UAAU,CAAC,GAAG,CAAC;YAAE,IAAI,GAAG,YAAY,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC,OAAO,EAAE,GAAG,IAAI,CAAC;QAC9F,MAAM,KAAK,GAAG,oBAAoB,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACzE,aAAa,CAAC,IAAI,EAAE,GAAG,IAAI,gEAAgE,KAAK,IAAI,CAAC,CAAC;QACtG,OAAO,GAAG,IAAI,CAAC;QACf,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,8FAA8F;AAC9F,MAAM,UAAU,eAAe;IAC7B,MAAM,GAAG,GAA2B,EAAE,CAAC;IACvC,MAAM,EAAE,GAAG,WAAW,EAAE,CAAC;IACzB,IAAI,UAAU,CAAC,EAAE,CAAC,IAAI,UAAU,CAAC,EAAE,CAAC,EAAE,CAAC;QACrC,+EAA+E;QAC/E,MAAM,GAAG,GAAG,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,EAAE,KAAK,MAAM,CAAC,IAAI,MAAM,CAAC;QACvF,GAAG,CAAC,GAAG,CAAC,GAAG,GAAG,OAAO,CAAC,EAAE,CAAC,GAAG,SAAS,GAAG,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,EAAE,EAAE,CAAC;IACnE,CAAC;IACD,MAAM,MAAM,GAAG,UAAU,EAAE,CAAC;IAC5B,IAAI,MAAM;QAAE,GAAG,CAAC,qBAAqB,CAAC,GAAG,MAAM,CAAC;IAChD,OAAO,GAAG,CAAC;AACb,CAAC"}
|
package/dist/tools/runCommand.js
CHANGED
|
@@ -2,11 +2,14 @@ import { randomBytes } from "node:crypto";
|
|
|
2
2
|
import { promises as fs, writeFileSync } from "node:fs";
|
|
3
3
|
import { tmpdir } from "node:os";
|
|
4
4
|
import { join } from "node:path";
|
|
5
|
-
import { catastrophicCommandReason, sensitiveCommandReason } from "./guard.js";
|
|
5
|
+
import { catastrophicCommandReason, riskyCommandReason, sensitiveCommandReason } from "./guard.js";
|
|
6
6
|
import { forbiddenCommandReason, forbiddenCommandPatternReason } from "../governor/forbidden.js";
|
|
7
7
|
import { requestForbiddenLift } from "./approval.js";
|
|
8
8
|
import { posixShell, shellMismatchNote } from "./posixShell.js";
|
|
9
9
|
import { killTree, spawnManaged } from "./killTree.js";
|
|
10
|
+
import { childEnv } from "./childEnv.js";
|
|
11
|
+
import { ripgrepShellEnv } from "./ripgrepShell.js";
|
|
12
|
+
import { dialectFor, parseCommand, protectedArgsReason, ruleVerdict } from "./commandPolicy.js";
|
|
10
13
|
import { captureAfterCommand, looksReadOnly, snapshotBeforeCommand } from "./shellCheckpoint.js";
|
|
11
14
|
import { canonicalRoot, relativize } from "./paths.js";
|
|
12
15
|
import { FULL_DETAIL_MAX, SHELL_ROWS_FAILED, SHELL_ROWS_OK, formatDuration, shellOutput, withOutcome } from "./detail.js";
|
|
@@ -163,6 +166,34 @@ export const runCommand = {
|
|
|
163
166
|
if (blocked) {
|
|
164
167
|
return fail(`Refusing to run this command: it looks like ${blocked}.`);
|
|
165
168
|
}
|
|
169
|
+
// The command read as the commands it contains, for the user's own rules and for the
|
|
170
|
+
// files it names (see commandPolicy.ts). Anything this cannot read is left to the
|
|
171
|
+
// checks above and below, which never depended on it.
|
|
172
|
+
const parsed = parseCommand(command, dialectFor(args));
|
|
173
|
+
const verdict = ruleVerdict(parsed, ctx.governance?.commandRules ?? []);
|
|
174
|
+
if (verdict.forbid) {
|
|
175
|
+
const why = verdict.forbid.justification ? ` ${verdict.forbid.justification}` : "";
|
|
176
|
+
return fail(`Refusing to run this command: your rule forbids \`${verdict.forbid.words.join(" ")}\`.${why}`);
|
|
177
|
+
}
|
|
178
|
+
const named = await protectedArgsReason(parsed, ctx.cwd);
|
|
179
|
+
if (named) {
|
|
180
|
+
return fail(`Refusing to run this command: ${named}. A command may list it, delete it, or write to it, but not read it, copy it out or send it. ` +
|
|
181
|
+
`Nothing here can read it for you; ask the user for the value you need.`);
|
|
182
|
+
}
|
|
183
|
+
// Commands that throw work away or run code from the internet ask first in every mode,
|
|
184
|
+
// with what they would lose. In a mode that already asked about this exact call, once
|
|
185
|
+
// is enough.
|
|
186
|
+
const risky = riskyCommandReason(command) ?? (verdict.prompt ? `matches your rule to ask first (\`${verdict.prompt.words.join(" ")}\`)` : null);
|
|
187
|
+
const justAsked = ctx.guarded === true && !ctx.guardAllowed?.has("run_command") && !ctx.governance?.sentinelAllow?.includes("run_command");
|
|
188
|
+
if (risky && !justAsked) {
|
|
189
|
+
if (!ctx.requestApproval) {
|
|
190
|
+
return fail(`Refusing to run this command: it ${risky}, which needs the user's agreement and there is no way to ask from here.`);
|
|
191
|
+
}
|
|
192
|
+
const choice = await ctx.requestApproval(`Run this command? It ${risky}.`, ["Yes, run it", "No"], command, "Permission Request");
|
|
193
|
+
if (!choice.startsWith("Yes")) {
|
|
194
|
+
return fail(`Stopped: the user declined running a command that ${risky}. Find another way, or explain why it is needed.`);
|
|
195
|
+
}
|
|
196
|
+
}
|
|
166
197
|
// A shell would sidestep every per-file gate the read/write tools enforce.
|
|
167
198
|
const sensitive = sensitiveCommandReason(command);
|
|
168
199
|
if (sensitive) {
|
|
@@ -364,26 +395,37 @@ async function runShell(command, ctx, timeoutMs, background, shell, declaredNoti
|
|
|
364
395
|
: [...VIRTUAL_DISPLAY_ARGS, bin, ...args, wrapped]
|
|
365
396
|
: [...args, wrapped], {
|
|
366
397
|
cwd: ctx.cwd,
|
|
367
|
-
// stdin
|
|
368
|
-
//
|
|
369
|
-
//
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
398
|
+
// stdin is the null device: nobody will ever type into this command, so a prompt
|
|
399
|
+
// ("Proceed? [y/N]", a credential request) sees end-of-input straight away and takes
|
|
400
|
+
// its default or gives up instead of waiting out the timeout. It used to be a pipe
|
|
401
|
+
// closed at once, which looks like piped input: `rg pattern` with no path then
|
|
402
|
+
// searched that empty pipe instead of the folder and found nothing, silently.
|
|
403
|
+
// stdout and stderr are the SAME descriptor, so the two interleave in the order they
|
|
404
|
+
// were written instead of being reassembled after.
|
|
405
|
+
stdio: ["ignore", outFile.handle.fd, outFile.handle.fd],
|
|
406
|
+
// The user's environment, not Mindweave's: no provider keys (see childEnv.ts).
|
|
407
|
+
env: childEnv({
|
|
373
408
|
GIT_EDITOR: "true", // never drop into an interactive editor and hang
|
|
374
409
|
GIT_PAGER: "cat",
|
|
410
|
+
GIT_TERMINAL_PROMPT: "0", // a credential prompt would wait on input that never comes
|
|
375
411
|
PAGER: "cat",
|
|
376
|
-
|
|
412
|
+
NO_COLOR: "1", // colour codes are noise in a transcript
|
|
413
|
+
// Python writes its output in the ANSI code page when piped on Windows, and fails
|
|
414
|
+
// outright on text that page cannot hold. The shell now reads UTF-8 (see UTF8_PRELUDE).
|
|
415
|
+
...(IS_WINDOWS ? { PYTHONIOENCODING: "utf-8" } : {}),
|
|
416
|
+
// The bundled rg, with the search tool's exclusions (see ripgrepShell.ts).
|
|
417
|
+
...ripgrepShellEnv(),
|
|
418
|
+
}),
|
|
377
419
|
});
|
|
378
|
-
// Nobody will ever type into this command, so its input ends now. Left open, a prompt
|
|
379
|
-
// ("Proceed? [y/N]", `npm init`, a credential request) waited on a stream that never
|
|
380
|
-
// closed until the two-minute timeout, and then got moved to the background still
|
|
381
|
-
// waiting. Closed, it sees end-of-input straight away and takes its default or gives up.
|
|
382
|
-
child.stdin?.end();
|
|
383
420
|
// Our copy of the descriptor. The child dup'd it at spawn, so closing here leaves it
|
|
384
421
|
// writing happily and means the file is released the moment the command ends rather
|
|
385
422
|
// than whenever this process happens to exit.
|
|
386
|
-
|
|
423
|
+
//
|
|
424
|
+
// NOT awaited. Nothing may yield between the spawn and the `exit` / `close` listeners that are attached
|
|
425
|
+
// further down (and `mgr.adopt`'s, for a background command): a fast command can finish inside that gap,
|
|
426
|
+
// its events then fire with nobody listening, and the call waits out the whole timeout for an exit it
|
|
427
|
+
// already missed. Seen on Linux under CPU load as a two-minute hang on `echo`. `finish` waits for this.
|
|
428
|
+
const descriptorClosed = outFile.handle.close().catch(() => { });
|
|
387
429
|
const mgr = ctx.backgroundShells;
|
|
388
430
|
// Explicit background: hand off immediately, don't wait for it.
|
|
389
431
|
//
|
|
@@ -549,6 +591,7 @@ async function runShell(command, ctx, timeoutMs, background, shell, declaredNoti
|
|
|
549
591
|
clearTimeout(startProgress);
|
|
550
592
|
stopProgress();
|
|
551
593
|
detachAbort();
|
|
594
|
+
await descriptorClosed;
|
|
552
595
|
await applyCwd(cwdFile, ctx);
|
|
553
596
|
if (tempFile)
|
|
554
597
|
await fs.rm(tempFile, { force: true }).catch(() => { });
|
|
@@ -658,6 +701,20 @@ function backgroundedResult(id, command, lead, notify) {
|
|
|
658
701
|
summary: `Backgrounded as shell #${id}`,
|
|
659
702
|
};
|
|
660
703
|
}
|
|
704
|
+
/**
|
|
705
|
+
* Make Windows PowerShell 5.1 speak UTF-8. By default it writes its output in the old
|
|
706
|
+
* console code page and reads a file without a byte-order mark as ANSI, so any text
|
|
707
|
+
* outside that page came back as "?" or as mojibake: a file named résumé-数据.txt was
|
|
708
|
+
* listed as r?sum?-??.txt, and the model then asked for a file that does not exist.
|
|
709
|
+
* Output, programs piped through the shell, and the file cmdlets now all use UTF-8
|
|
710
|
+
* (writing UTF-8 with a byte-order mark, the only form 5.1 offers, where `>` used to
|
|
711
|
+
* write UTF-16). An explicit -Encoding still wins. Setting the console encoding can fail
|
|
712
|
+
* when there is no console, which changes nothing else.
|
|
713
|
+
*/
|
|
714
|
+
const UTF8_PRELUDE = `try { [Console]::OutputEncoding = [System.Text.UTF8Encoding]::new($false) } catch {}; ` +
|
|
715
|
+
`$OutputEncoding = [System.Text.UTF8Encoding]::new($false); ` +
|
|
716
|
+
`foreach ($__c in 'Get-Content','Set-Content','Add-Content','Out-File','Select-String','Import-Csv','Export-Csv') ` +
|
|
717
|
+
`{ $PSDefaultParameterValues["$($__c):Encoding"] = 'utf8' }`;
|
|
661
718
|
/** Build the shell invocation: which binary, its flags, and the wrapped command. */
|
|
662
719
|
function buildInvocation(command, cwdFile, shell) {
|
|
663
720
|
if (IS_WINDOWS && shell === "cmd") {
|
|
@@ -697,7 +754,9 @@ function buildInvocation(command, cwdFile, shell) {
|
|
|
697
754
|
// so a successful build read as a broken one. So when `$?` is false, the
|
|
698
755
|
// command failed only if an error was recorded that is neither a native
|
|
699
756
|
// program's stderr line nor raised by a command that asked for silence.
|
|
700
|
-
|
|
757
|
+
// UTF8_PRELUDE shares the first line so the line numbers PowerShell reports for the
|
|
758
|
+
// command stay what they were.
|
|
759
|
+
const wrapped = `${UTF8_PRELUDE}; $global:LASTEXITCODE = $null; $Error.Clear()\n` +
|
|
701
760
|
`${command}\n` +
|
|
702
761
|
`$__ok = $?\n` +
|
|
703
762
|
`$__native = $LASTEXITCODE\n` +
|
|
@@ -886,9 +945,9 @@ keptPath) {
|
|
|
886
945
|
detail: testRun
|
|
887
946
|
? testDetail(testRun, formatDuration)
|
|
888
947
|
: withOutcome(shellBody(command, body, failed), timedOut, exitCode, signal, timeoutMs, elapsedMs, pid),
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
948
|
+
// A recognised test run shows its result, and the whole log is what opens: the summary is
|
|
949
|
+
// the right thing to read first and the wrong thing to be unable to go behind.
|
|
950
|
+
detailFull: withOutcome(shellBody(command, body, failed, FULL_DETAIL_MAX), timedOut, exitCode, signal, timeoutMs, elapsedMs, pid),
|
|
892
951
|
detailKind: "shell",
|
|
893
952
|
};
|
|
894
953
|
}
|