mixdog 0.9.121 → 0.9.123
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/package.json +1 -1
- package/src/rules/shared/01-tool.md +43 -45
- package/src/runtime/agent/orchestrator/tools/builtin/builtin-tools.mjs +6 -6
- package/src/runtime/agent/orchestrator/tools/builtin/list-tool.mjs +60 -34
- package/src/runtime/agent/orchestrator/tools/builtin/native-search-client.mjs +10 -1
- package/src/runtime/agent/orchestrator/tools/builtin/shell-job-process.mjs +6 -0
- package/src/runtime/agent/orchestrator/tools/code-graph-tool-defs.mjs +1 -1
- package/src/runtime/agent/orchestrator/tools/graph-manifest.json +11 -11
- package/src/runtime/agent/orchestrator/tools/patch-tool-defs.mjs +1 -2
package/package.json
CHANGED
|
@@ -12,59 +12,57 @@
|
|
|
12
12
|
(`shell.cwd` is call-local and never changes the Project);
|
|
13
13
|
explicit user-requested conversation reset→`session_manage`.
|
|
14
14
|
Use only named tools present in the current tool surface.
|
|
15
|
-
- Act only on verified identities (task/cwd/project/user/tool-returned) —
|
|
16
|
-
module specifiers, symbols, data/record shapes alike; verify a
|
|
17
|
-
identity with one lookup or sample before the first call or edit
|
|
18
|
-
relies on it. Within the current project, pass
|
|
19
|
-
|
|
20
|
-
|
|
15
|
+
- Act only on verified identities (task/cwd/project/user/tool-returned) —
|
|
16
|
+
paths, module specifiers, symbols, data/record shapes alike; verify a
|
|
17
|
+
guessed identity with one lookup or sample before the first call or edit
|
|
18
|
+
that relies on it. Within the current project, pass project-relative
|
|
19
|
+
paths and omit optional scopes equal to its root; explicit paths may be
|
|
20
|
+
outside cwd only for targets outside the project.
|
|
21
21
|
- Plan the fewest dependent rounds, then the fewest calls. Known state —
|
|
22
22
|
anything the task supplied, a tool returned (applied patches and envelope
|
|
23
|
-
hints included), or a check already proved —
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
narrow only on verified cues — returned siblings/conventions or known
|
|
35
|
-
literals — and returned output is fully mined before the next round.
|
|
36
|
-
Symbol relations end at
|
|
23
|
+
hints included), or a check already proved — is never re-found,
|
|
24
|
+
re-derived, or re-verified; a change to its subject re-opens it. Batch
|
|
25
|
+
calls iff none needs another's output or can change another's
|
|
26
|
+
inputs/state; otherwise serialize. Before each batch, deduplicate the
|
|
27
|
+
facets still required by the request, route each once to the cheapest
|
|
28
|
+
sufficient tool with all required variants/scopes, and launch every
|
|
29
|
+
independent call together — never split or duplicate a facet across
|
|
30
|
+
tools, mutate merely to widen retrieval, reserve known work, or cap
|
|
31
|
+
fanout. Guesses go wide in one batch, scopes narrow only on verified
|
|
32
|
+
cues — returned siblings/conventions or known literals — and returned
|
|
33
|
+
output is fully mined before the next round. Symbol relations end at
|
|
37
34
|
`code_graph`; values/locations end at the context grep returns; `read`
|
|
38
35
|
covers only what returned spans cannot, as an anchored offset/limit
|
|
39
36
|
window. A conclusive result ends its facet; evidence that determines the
|
|
40
37
|
answer, edit, or deliverable ends retrieval — patch if needed.
|
|
41
|
-
-
|
|
42
|
-
|
|
43
|
-
an obstacle or unexpected state
|
|
44
|
-
evidence ends its search — report best effort.
|
|
38
|
+
- If inspection can change evidence or durable state, use read-only means;
|
|
39
|
+
mutate only when the deliverable requires it, first preserving evidence
|
|
40
|
+
at risk. Never mutate merely to clear an obstacle or unexpected state;
|
|
41
|
+
unrecoverably lost evidence ends its search — report best effort.
|
|
45
42
|
- Once the edit or deliverable is determined, finish in one assistant turn:
|
|
46
|
-
before `apply_patch`, obtain every target hunk's exact current content
|
|
47
|
-
anchor from `grep`, `code_graph`, `read`, or a prior successful patch
|
|
48
|
-
envelope; never infer patch context from
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
43
|
+
before `apply_patch`, obtain every target hunk's exact current content
|
|
44
|
+
and anchor from `grep`, `code_graph`, `read`, or a prior successful patch
|
|
45
|
+
envelope; never infer patch context from another file, a sample, or
|
|
46
|
+
expected text. Then issue `apply_patch` calls serially, never in
|
|
47
|
+
parallel; use one cohesive call with one file section per target, all
|
|
48
|
+
patches first, then their one batched verification `shell` in the same
|
|
49
|
+
turn — the runtime runs it after every patch and only if all succeeded,
|
|
50
|
+
so verification never needs its own turn. It runs the real required
|
|
51
|
+
postconditions on every changed file and produced artifact, never
|
|
52
|
+
echoing a claim; changes made through `shell` verify under the same
|
|
56
53
|
one-batch contract — one script proving every postcondition, value-level
|
|
57
|
-
included, never one check per round; a postcondition that did not
|
|
58
|
-
unresolved, not passed. Retry only failed envelopes;
|
|
59
|
-
after a change that can alter its outcome —
|
|
60
|
-
route or report it unresolved.
|
|
54
|
+
included, never one check per round; a postcondition that did not
|
|
55
|
+
actually run is unresolved, not passed. Retry only failed envelopes;
|
|
56
|
+
rerun a failed check only after a change that can alter its outcome —
|
|
57
|
+
commands alike; else switch route or report it unresolved.
|
|
61
58
|
Hand-authored text is edited only with `apply_patch`; computed artifacts
|
|
62
59
|
(data/reports/derived values) come from `shell` computation, never
|
|
63
60
|
hand-transcribed numbers. Earlier `shell` is only for runtime/state
|
|
64
|
-
evidence unavailable to file tools—an independent facet, batched with
|
|
65
|
-
the rest; independent probes are parallel shell calls, never one
|
|
66
|
-
|
|
67
|
-
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
61
|
+
evidence unavailable to file tools — an independent facet, batched with
|
|
62
|
+
the rest; independent probes are parallel shell calls, never one serial
|
|
63
|
+
script per round.
|
|
64
|
+
- Run long/uncertain commands async—never nohup—and omit timeout unless a real
|
|
65
|
+
total deadline is required; explicit timeout kills even async jobs. Do not
|
|
66
|
+
poll a notified `task_id`; completion resumes. Else poll only when requested
|
|
67
|
+
or no notification exists, with cadence/stop condition; task control only
|
|
68
|
+
serves recovery/blocking.
|
|
@@ -62,7 +62,7 @@ export const BUILTIN_TOOLS = [
|
|
|
62
62
|
minItems: 1,
|
|
63
63
|
},
|
|
64
64
|
],
|
|
65
|
-
description: '
|
|
65
|
+
description: 'File path, string[] files, [path,offset,limit?] range, or range[].',
|
|
66
66
|
},
|
|
67
67
|
offset: { type: 'number', minimum: 0, description: 'Lines to skip.' },
|
|
68
68
|
limit: { type: 'number', minimum: 1, description: 'Max lines; default 2000.' },
|
|
@@ -83,7 +83,7 @@ export const BUILTIN_TOOLS = [
|
|
|
83
83
|
cwd: { type: 'string', description: 'Omit to use the current Project root; use a project-relative subdir or explicit external path for this call only.' },
|
|
84
84
|
timeout: {
|
|
85
85
|
type: 'number',
|
|
86
|
-
description: `
|
|
86
|
+
description: `Total deadline ms. Omit for sync default ${_shellDefaultTimeoutMs()}; omit for unlimited async. Explicit values kill at deadline; sync may return task_id.`,
|
|
87
87
|
},
|
|
88
88
|
mode: { type: 'string', enum: ['sync', 'async'], description: executionModeSchemaDescription('sync') },
|
|
89
89
|
shell: { type: 'string', enum: ['bash', 'powershell'], description: 'Force shell.' },
|
|
@@ -128,7 +128,7 @@ export const BUILTIN_TOOLS = [
|
|
|
128
128
|
{ type: 'string' },
|
|
129
129
|
{ type: 'array', items: { type: 'string' }, minItems: 1 },
|
|
130
130
|
],
|
|
131
|
-
description: '
|
|
131
|
+
description: 'File/dir scope(s).',
|
|
132
132
|
},
|
|
133
133
|
glob: {
|
|
134
134
|
anyOf: [
|
|
@@ -169,7 +169,7 @@ export const BUILTIN_TOOLS = [
|
|
|
169
169
|
{ type: 'string' },
|
|
170
170
|
{ type: 'array', items: { type: 'string' }, minItems: 1 },
|
|
171
171
|
],
|
|
172
|
-
description: '
|
|
172
|
+
description: 'Base dir(s); path[] batches.',
|
|
173
173
|
},
|
|
174
174
|
limit: { type: 'number', description: 'Max entries; default 100; 0 unlimited.' },
|
|
175
175
|
offset: { type: 'number', minimum: 0, description: 'Entry offset.' },
|
|
@@ -193,7 +193,7 @@ export const BUILTIN_TOOLS = [
|
|
|
193
193
|
],
|
|
194
194
|
description: 'Filename or directory path fragments matched against path strings; query[] batches.',
|
|
195
195
|
},
|
|
196
|
-
path: { type: 'string', description: '
|
|
196
|
+
path: { type: 'string', description: 'Base path.' },
|
|
197
197
|
limit: { type: 'number', description: 'Max paths; default 25; 0 unlimited.' },
|
|
198
198
|
include_noise: { type: 'boolean', description: 'Also search gitignored/dependency trees.' },
|
|
199
199
|
},
|
|
@@ -214,7 +214,7 @@ export const BUILTIN_TOOLS = [
|
|
|
214
214
|
{ type: 'string' },
|
|
215
215
|
{ type: 'array', items: { type: 'string' }, minItems: 1 },
|
|
216
216
|
],
|
|
217
|
-
description: '
|
|
217
|
+
description: 'Directory; path[] batches.',
|
|
218
218
|
},
|
|
219
219
|
hidden: { type: 'boolean', description: 'Include dotfiles.' },
|
|
220
220
|
meta: { type: 'boolean', description: 'Per-entry size bytes, UTC mtime, octal mode.' },
|
|
@@ -447,6 +447,29 @@ function invalidateFindEnumerationRoot(root) {
|
|
|
447
447
|
if (findEnumerationRootFromKey(key) === root) FIND_ENUM_INFLIGHT.delete(key);
|
|
448
448
|
}
|
|
449
449
|
}
|
|
450
|
+
// Trailing-edge prewarm throttle: sustained write bursts (builds, installs)
|
|
451
|
+
// fire the watcher continuously; re-running the two full sweeps on every
|
|
452
|
+
// flush kept the serve bulk queue permanently busy. Invalidation stays
|
|
453
|
+
// immediate — only the warm rebuild is coalesced to one run per interval
|
|
454
|
+
// per root, scheduled at the trailing edge so the cache re-arms after the
|
|
455
|
+
// burst settles.
|
|
456
|
+
const FIND_ENUM_PREWARM_STATE = new Map(); // root -> { lastAt, timer }
|
|
457
|
+
const FIND_ENUM_PREWARM_MIN_INTERVAL_MS = 15_000;
|
|
458
|
+
function scheduleFindEnumerationPrewarm(root, delayMs = 100) {
|
|
459
|
+
let state = FIND_ENUM_PREWARM_STATE.get(root);
|
|
460
|
+
if (!state) {
|
|
461
|
+
state = { lastAt: 0, timer: null };
|
|
462
|
+
FIND_ENUM_PREWARM_STATE.set(root, state);
|
|
463
|
+
}
|
|
464
|
+
if (state.timer) return;
|
|
465
|
+
const wait = Math.max(delayMs, state.lastAt + FIND_ENUM_PREWARM_MIN_INTERVAL_MS - Date.now());
|
|
466
|
+
state.timer = setTimeout(() => {
|
|
467
|
+
state.timer = null;
|
|
468
|
+
state.lastAt = Date.now();
|
|
469
|
+
void prewarmFindEnumeration(root);
|
|
470
|
+
}, wait);
|
|
471
|
+
state.timer.unref?.();
|
|
472
|
+
}
|
|
450
473
|
function ensureFindEnumerationWatcher(root) {
|
|
451
474
|
const existing = FIND_ENUM_WATCHERS.get(root);
|
|
452
475
|
if (existing) {
|
|
@@ -461,8 +484,7 @@ function ensureFindEnumerationWatcher(root) {
|
|
|
461
484
|
const paths = [...pending];
|
|
462
485
|
pending.clear();
|
|
463
486
|
invalidateBuiltinResultCache(paths.length ? paths : [root]);
|
|
464
|
-
|
|
465
|
-
warm.unref?.();
|
|
487
|
+
scheduleFindEnumerationPrewarm(root);
|
|
466
488
|
};
|
|
467
489
|
record.watcher = watch(root, { recursive: true, persistent: false }, (_event, filename) => {
|
|
468
490
|
const rel = filename == null ? '' : String(filename);
|
|
@@ -649,6 +671,21 @@ async function getBroadEnumeration({ root, hidden, depth, includeNoise, ignoreMo
|
|
|
649
671
|
return subscribeToFindEnumeration(key, entry, signal);
|
|
650
672
|
}
|
|
651
673
|
|
|
674
|
+
// Cache-only peek: returns the SHARED files array of a still-valid broad
|
|
675
|
+
// sweep for these dimensions, or null. Never spawns, joins, or waits — the
|
|
676
|
+
// targeted find path below must not block behind a full-tree enumeration.
|
|
677
|
+
function peekBroadEnumeration({ root, hidden, depth, includeNoise, ignoreMode }) {
|
|
678
|
+
if (findEnumTtlMs() <= 0) return null;
|
|
679
|
+
const key = findEnumKey({ root, hidden, depth, includeNoise, ignoreMode });
|
|
680
|
+
const hit = FIND_ENUM_CACHE.get(key);
|
|
681
|
+
if (hit && hit.gen === FIND_ENUM_GEN
|
|
682
|
+
&& hit.rootGen === findEnumerationRootGeneration(root)
|
|
683
|
+
&& hit.expiresAt > Date.now()) {
|
|
684
|
+
return hit.files;
|
|
685
|
+
}
|
|
686
|
+
return null;
|
|
687
|
+
}
|
|
688
|
+
|
|
652
689
|
// Best-effort warm of the broad enumeration for a root using the `find` tool's
|
|
653
690
|
// DEFAULT flags (hidden:true, includeNoise:false, depth:unbounded). Swallows
|
|
654
691
|
// all errors — a failed prewarm must never surface or block the caller.
|
|
@@ -695,38 +732,27 @@ async function getTargetedFindEnumeration({
|
|
|
695
732
|
const key = JSON.stringify([root, hidden, depth ?? '', includeNoise, terms]);
|
|
696
733
|
const runs = context?.targetedRuns;
|
|
697
734
|
if (runs?.has(key)) return runs.get(key);
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
return {
|
|
720
|
-
files: inventory.files.filter((path) => {
|
|
721
|
-
const lower = path.toLowerCase();
|
|
722
|
-
return lowerTerms.some((term) => lower.includes(term));
|
|
723
|
-
}),
|
|
724
|
-
truncated: false,
|
|
725
|
-
partial: false,
|
|
726
|
-
};
|
|
727
|
-
}
|
|
728
|
-
} catch {
|
|
729
|
-
if (signal?.aborted) throw findEnumerationAbortError(signal);
|
|
735
|
+
// Reuse a WARM broad inventory only (cache peek). A cold cache goes
|
|
736
|
+
// straight to the cheap targeted --iglob batch below: front-running the
|
|
737
|
+
// full `--no-ignore` sweep made cold finds stall behind the serve bulk
|
|
738
|
+
// queue for tens of seconds.
|
|
739
|
+
const inventory = peekBroadEnumeration({
|
|
740
|
+
root: normalizeOutputPath(root),
|
|
741
|
+
hidden,
|
|
742
|
+
depth,
|
|
743
|
+
includeNoise,
|
|
744
|
+
ignoreMode: 'targeted-all',
|
|
745
|
+
});
|
|
746
|
+
if (inventory) {
|
|
747
|
+
const lowerTerms = terms.map((term) => term.toLowerCase());
|
|
748
|
+
return {
|
|
749
|
+
files: inventory.filter((path) => {
|
|
750
|
+
const lower = path.toLowerCase();
|
|
751
|
+
return lowerTerms.some((term) => lower.includes(term));
|
|
752
|
+
}),
|
|
753
|
+
truncated: false,
|
|
754
|
+
partial: false,
|
|
755
|
+
};
|
|
730
756
|
}
|
|
731
757
|
let batches = FIND_TARGETED_BATCHES_BY_RUNNER.get(runRgImpl);
|
|
732
758
|
if (!batches) {
|
|
@@ -154,6 +154,15 @@ export async function tryServeSearch(argsList, execOptions = {}, opts = {}) {
|
|
|
154
154
|
const server = _ensureServer();
|
|
155
155
|
if (!server) return null;
|
|
156
156
|
const id = ++server.sequence;
|
|
157
|
+
// Honor the caller's rg deadline: the resident server must never wait
|
|
158
|
+
// LONGER than the spawn fallback it replaces (glob passes 10s while the
|
|
159
|
+
// serve ceiling is 20s), otherwise a queued/stuck serve request delays the
|
|
160
|
+
// fallback instead of accelerating it. The fixed ceiling still bounds
|
|
161
|
+
// callers that pass no timeout.
|
|
162
|
+
const callerTimeoutMs = Number(execOptions.timeout);
|
|
163
|
+
const deadlineMs = Number.isFinite(callerTimeoutMs) && callerTimeoutMs > 0
|
|
164
|
+
? Math.min(callerTimeoutMs, REQUEST_TIMEOUT_MS)
|
|
165
|
+
: REQUEST_TIMEOUT_MS;
|
|
157
166
|
_setServerReferenced(server, true);
|
|
158
167
|
const request = {
|
|
159
168
|
id,
|
|
@@ -185,7 +194,7 @@ export async function tryServeSearch(argsList, execOptions = {}, opts = {}) {
|
|
|
185
194
|
const timer = setTimeout(() => {
|
|
186
195
|
server.pending.delete(id);
|
|
187
196
|
settle(null, true);
|
|
188
|
-
},
|
|
197
|
+
}, deadlineMs);
|
|
189
198
|
timer.unref?.();
|
|
190
199
|
server.pending.set(id, { resolve: settle, reject: () => settle(null) });
|
|
191
200
|
onAbort = () => {
|
|
@@ -76,6 +76,12 @@ export async function windowsPidDescendants(pid) {
|
|
|
76
76
|
if (process.platform !== 'win32') return new Map();
|
|
77
77
|
let rows = null;
|
|
78
78
|
try { rows = await windowsProcessSnapshot({ fresh: true }); } catch { rows = null; }
|
|
79
|
+
if (!rows) {
|
|
80
|
+
// One retry before giving up: a single missed 750ms native-snapshot
|
|
81
|
+
// deadline (server busy with a bulk enumeration) otherwise marks
|
|
82
|
+
// every standby dirty and collapses the pool into cold spawns.
|
|
83
|
+
try { rows = await windowsProcessSnapshot({ fresh: true }); } catch { rows = null; }
|
|
84
|
+
}
|
|
79
85
|
if (!rows) return null;
|
|
80
86
|
const owned = new Set([pid]);
|
|
81
87
|
const descendants = new Map();
|
|
@@ -8,7 +8,7 @@ export const CODE_GRAPH_TOOL_DEFS = [
|
|
|
8
8
|
type: 'object',
|
|
9
9
|
properties: {
|
|
10
10
|
mode: { type: 'string', enum: ['overview', 'imports', 'dependents', 'related', 'impact', 'symbols', 'find_symbol', 'symbol_search', 'search', 'references', 'callers', 'callees'], description: 'File modes: overview/imports/dependents/related/impact. symbols with files[] gives a file outline; others are symbol modes.' },
|
|
11
|
-
files: { anyOf: [{ type: 'string' }, { type: 'array', items: { type: 'string' }, minItems: 1 }], description: 'Project-relative source file path(s)
|
|
11
|
+
files: { anyOf: [{ type: 'string' }, { type: 'array', items: { type: 'string' }, minItems: 1 }], description: 'Project-relative source file path(s).' },
|
|
12
12
|
symbols: { anyOf: [{ type: 'string' }, { type: 'array', items: { type: 'string' }, minItems: 1 }], description: 'Exact identifiers or keywords (symbol-index terms); batch multiple in one symbols[] call.' },
|
|
13
13
|
body: { type: 'boolean', description: 'Include body.' },
|
|
14
14
|
limit: { type: 'number', minimum: 1, description: 'Max results.' },
|
|
@@ -1,26 +1,26 @@
|
|
|
1
1
|
{
|
|
2
|
-
"version": "0.1.
|
|
2
|
+
"version": "0.1.7",
|
|
3
3
|
"_comment": "Synced from immutable graph-v release assets.",
|
|
4
4
|
"assets": {
|
|
5
5
|
"darwin-arm64": {
|
|
6
|
-
"url": "https://github.com/tribgames/mixdog/releases/download/graph-v0.1.
|
|
7
|
-
"sha256": "
|
|
6
|
+
"url": "https://github.com/tribgames/mixdog/releases/download/graph-v0.1.7/mixdog-graph-darwin-arm64",
|
|
7
|
+
"sha256": "a8d95602fd2beb2901dded0b1fe728adfde8075d73557442e4c540b39e64fe8d"
|
|
8
8
|
},
|
|
9
9
|
"darwin-x64": {
|
|
10
|
-
"url": "https://github.com/tribgames/mixdog/releases/download/graph-v0.1.
|
|
11
|
-
"sha256": "
|
|
10
|
+
"url": "https://github.com/tribgames/mixdog/releases/download/graph-v0.1.7/mixdog-graph-darwin-x64",
|
|
11
|
+
"sha256": "788e6e0fb32d8d8ba3b4c22e31492dc99bba039a3186a5b3f2420df3778f45d6"
|
|
12
12
|
},
|
|
13
13
|
"linux-arm64": {
|
|
14
|
-
"url": "https://github.com/tribgames/mixdog/releases/download/graph-v0.1.
|
|
15
|
-
"sha256": "
|
|
14
|
+
"url": "https://github.com/tribgames/mixdog/releases/download/graph-v0.1.7/mixdog-graph-linux-arm64",
|
|
15
|
+
"sha256": "43f723df7b452e75bde9839c2ce027982fa329c08560f6888442c65ac0ef7ddf"
|
|
16
16
|
},
|
|
17
17
|
"linux-x64": {
|
|
18
|
-
"url": "https://github.com/tribgames/mixdog/releases/download/graph-v0.1.
|
|
19
|
-
"sha256": "
|
|
18
|
+
"url": "https://github.com/tribgames/mixdog/releases/download/graph-v0.1.7/mixdog-graph-linux-x64",
|
|
19
|
+
"sha256": "a7a390fb2e446fb7a9d16ac68c42c1989622beab0d6711b610a16e43360e7e84"
|
|
20
20
|
},
|
|
21
21
|
"win32-x64": {
|
|
22
|
-
"url": "https://github.com/tribgames/mixdog/releases/download/graph-v0.1.
|
|
23
|
-
"sha256": "
|
|
22
|
+
"url": "https://github.com/tribgames/mixdog/releases/download/graph-v0.1.7/mixdog-graph-win32-x64.exe",
|
|
23
|
+
"sha256": "75e7dafd4df2f56c889b3c77643cfe95526c8ada1c1ffd1711539677737950c2"
|
|
24
24
|
}
|
|
25
25
|
}
|
|
26
26
|
}
|
|
@@ -47,8 +47,7 @@ const APPLY_PATCH_JSON_DESCRIPTION = [
|
|
|
47
47
|
'Each section starts with exactly one: *** Add File: <path> (+ lines), *** Delete File: <path> (header only), or *** Update File: <path> (optional *** Move to: <new path>).',
|
|
48
48
|
'Hunks start with @@ or @@ <symbol|1-based line>; lines start space, -, or +; every Update hunk needs >=1 +/- line; optional *** End of File.',
|
|
49
49
|
'Use 3 verbatim context lines from newest output (post-patch body after edits); avoid overlap; stack @@ only if ambiguous.',
|
|
50
|
-
'
|
|
51
|
-
'A same-turn shell runs after all patches succeed.',
|
|
50
|
+
'+ prefixes every added line. Never send compacted-history markers; re-read first.',
|
|
52
51
|
].join('\n');
|
|
53
52
|
|
|
54
53
|
export const PATCH_TOOL_DEFS = [
|