reasonix 0.47.0 → 0.47.1
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/{acp-QK3DMC53.js → acp-GEOAKSTU.js} +21 -49
- package/dist/cli/acp-GEOAKSTU.js.map +1 -0
- package/dist/cli/{chat-VV5UWY4V.js → chat-YTPATMMG.js} +23 -23
- package/dist/cli/{chunk-FDKOUJKZ.js → chunk-2XY77LW7.js} +7 -7
- package/dist/cli/{chunk-QVDWH2A2.js → chunk-4MFCAZ2W.js} +3 -3
- package/dist/cli/{chunk-24A7FHGJ.js → chunk-6CRPCJAU.js} +14 -1
- package/dist/cli/chunk-6CRPCJAU.js.map +1 -0
- package/dist/cli/{chunk-VKYSZKH2.js → chunk-6QC5RQLE.js} +2 -2
- package/dist/cli/chunk-BQ6HC66J.js +530 -0
- package/dist/cli/chunk-BQ6HC66J.js.map +1 -0
- package/dist/cli/{chunk-OJVITDGB.js → chunk-CCJAP7G3.js} +2 -2
- package/dist/cli/{chunk-R6GQKKBW.js → chunk-CNG32VAB.js} +2 -2
- package/dist/cli/{chunk-QVUFWDD2.js → chunk-DN4B5S6Y.js} +2 -2
- package/dist/cli/{chunk-LBLR4CUZ.js → chunk-DQ6K5ZQ7.js} +2 -2
- package/dist/cli/{chunk-VNQGCA3Q.js → chunk-DWPAKZTY.js} +14 -3
- package/dist/cli/chunk-DWPAKZTY.js.map +1 -0
- package/dist/cli/{chunk-BWYVFFKR.js → chunk-GH7DC2Y5.js} +2 -2
- package/dist/cli/{chunk-BYYVYJDX.js → chunk-HUILPCYX.js} +3 -3
- package/dist/cli/{chunk-ICAFSZHS.js → chunk-JBH5RM7X.js} +174 -65
- package/dist/cli/chunk-JBH5RM7X.js.map +1 -0
- package/dist/cli/{chunk-K6GUKSXH.js → chunk-KVZZ5U75.js} +2 -2
- package/dist/cli/{chunk-WF7TPVZM.js → chunk-KYQVQ5X4.js} +84 -9
- package/dist/cli/chunk-KYQVQ5X4.js.map +1 -0
- package/dist/cli/{chunk-KDRUEXII.js → chunk-NRQ5UP5T.js} +20 -6
- package/dist/cli/chunk-NRQ5UP5T.js.map +1 -0
- package/dist/cli/{chunk-VJMBISEI.js → chunk-QCFLPSPH.js} +2 -2
- package/dist/cli/{chunk-YDPLF7XR.js → chunk-T5A7EY6B.js} +2 -2
- package/dist/cli/{chunk-VMUUFWFF.js → chunk-TDHXB2ER.js} +2 -2
- package/dist/cli/{chunk-GDKB2PPK.js → chunk-TRSAHHCL.js} +107 -11
- package/dist/cli/chunk-TRSAHHCL.js.map +1 -0
- package/dist/cli/{chunk-6J6BSUCR.js → chunk-TRWHTFG7.js} +2 -2
- package/dist/cli/{chunk-VC2CQA5D.js → chunk-XD6P7AFH.js} +26 -29
- package/dist/cli/chunk-XD6P7AFH.js.map +1 -0
- package/dist/cli/{chunk-ICSYGIPN.js → chunk-XMHP7BEE.js} +421 -80
- package/dist/cli/chunk-XMHP7BEE.js.map +1 -0
- package/dist/cli/{chunk-COWPEX54.js → chunk-YFP3MYMY.js} +5 -5
- package/dist/cli/{chunk-CI2PF5QX.js → chunk-ZXSCAODE.js} +8 -8
- package/dist/cli/{chunk-CI2PF5QX.js.map → chunk-ZXSCAODE.js.map} +1 -1
- package/dist/cli/{code-C24TUAE5.js → code-Q4NRVEDG.js} +29 -27
- package/dist/cli/code-Q4NRVEDG.js.map +1 -0
- package/dist/cli/{commands-RR3GIYOK.js → commands-4CDI4GFM.js} +4 -4
- package/dist/cli/{commit-FSHPIINM.js → commit-GW7LDQP5.js} +3 -3
- package/dist/cli/{desktop-7NCHPEFB.js → desktop-EG6P5SF2.js} +80 -22
- package/dist/cli/desktop-EG6P5SF2.js.map +1 -0
- package/dist/cli/{diff-RAAHHLHV.js → diff-VI2YX4FN.js} +8 -8
- package/dist/cli/{doctor-PKVQIXRT.js → doctor-CQTTZP27.js} +8 -8
- package/dist/cli/index.js +45 -37
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/{mcp-CRJ26PP4.js → mcp-J2UCD4RZ.js} +2 -2
- package/dist/cli/{mcp-browse-QPAOWZOP.js → mcp-browse-GSX34JEK.js} +2 -2
- package/dist/cli/{mcp-inspect-CVCLABRS.js → mcp-inspect-RRFYF4ZV.js} +2 -2
- package/dist/cli/{prompt-SKYXERSI.js → prompt-5TQPIVHV.js} +3 -3
- package/dist/cli/{replay-KPDW2ZMJ.js → replay-MJCEMODU.js} +8 -8
- package/dist/cli/{run-WIKDIXTG.js → run-P4D5VDYE.js} +13 -13
- package/dist/cli/{server-P6V2G3P6.js → server-C25JNNZV.js} +11 -11
- package/dist/cli/{sessions-2NULRMSA.js → sessions-QIONZJQ6.js} +12 -12
- package/dist/cli/{setup-Y5WDBQFL.js → setup-NLQ6G5G4.js} +6 -6
- package/dist/cli/setup-NLQ6G5G4.js.map +1 -0
- package/dist/cli/{stats-T7BL2YOR.js → stats-DFZEXHP4.js} +6 -6
- package/dist/cli/{version-3KWDNWLN.js → version-GR3X3MPI.js} +12 -12
- package/dist/index.d.ts +40 -48
- package/dist/index.js +286 -237
- package/dist/index.js.map +1 -1
- package/package.json +3 -1
- package/dist/cli/acp-QK3DMC53.js.map +0 -1
- package/dist/cli/chunk-24A7FHGJ.js.map +0 -1
- package/dist/cli/chunk-GDKB2PPK.js.map +0 -1
- package/dist/cli/chunk-ICAFSZHS.js.map +0 -1
- package/dist/cli/chunk-ICSYGIPN.js.map +0 -1
- package/dist/cli/chunk-KDRUEXII.js.map +0 -1
- package/dist/cli/chunk-UDVFBEXC.js +0 -642
- package/dist/cli/chunk-UDVFBEXC.js.map +0 -1
- package/dist/cli/chunk-VC2CQA5D.js.map +0 -1
- package/dist/cli/chunk-VNQGCA3Q.js.map +0 -1
- package/dist/cli/chunk-WF7TPVZM.js.map +0 -1
- package/dist/cli/code-C24TUAE5.js.map +0 -1
- package/dist/cli/desktop-7NCHPEFB.js.map +0 -1
- package/dist/cli/setup-Y5WDBQFL.js.map +0 -1
- /package/dist/cli/{chat-VV5UWY4V.js.map → chat-YTPATMMG.js.map} +0 -0
- /package/dist/cli/{chunk-FDKOUJKZ.js.map → chunk-2XY77LW7.js.map} +0 -0
- /package/dist/cli/{chunk-QVDWH2A2.js.map → chunk-4MFCAZ2W.js.map} +0 -0
- /package/dist/cli/{chunk-VKYSZKH2.js.map → chunk-6QC5RQLE.js.map} +0 -0
- /package/dist/cli/{chunk-OJVITDGB.js.map → chunk-CCJAP7G3.js.map} +0 -0
- /package/dist/cli/{chunk-R6GQKKBW.js.map → chunk-CNG32VAB.js.map} +0 -0
- /package/dist/cli/{chunk-QVUFWDD2.js.map → chunk-DN4B5S6Y.js.map} +0 -0
- /package/dist/cli/{chunk-LBLR4CUZ.js.map → chunk-DQ6K5ZQ7.js.map} +0 -0
- /package/dist/cli/{chunk-BWYVFFKR.js.map → chunk-GH7DC2Y5.js.map} +0 -0
- /package/dist/cli/{chunk-BYYVYJDX.js.map → chunk-HUILPCYX.js.map} +0 -0
- /package/dist/cli/{chunk-K6GUKSXH.js.map → chunk-KVZZ5U75.js.map} +0 -0
- /package/dist/cli/{chunk-VJMBISEI.js.map → chunk-QCFLPSPH.js.map} +0 -0
- /package/dist/cli/{chunk-YDPLF7XR.js.map → chunk-T5A7EY6B.js.map} +0 -0
- /package/dist/cli/{chunk-VMUUFWFF.js.map → chunk-TDHXB2ER.js.map} +0 -0
- /package/dist/cli/{chunk-6J6BSUCR.js.map → chunk-TRWHTFG7.js.map} +0 -0
- /package/dist/cli/{chunk-COWPEX54.js.map → chunk-YFP3MYMY.js.map} +0 -0
- /package/dist/cli/{commands-RR3GIYOK.js.map → commands-4CDI4GFM.js.map} +0 -0
- /package/dist/cli/{commit-FSHPIINM.js.map → commit-GW7LDQP5.js.map} +0 -0
- /package/dist/cli/{diff-RAAHHLHV.js.map → diff-VI2YX4FN.js.map} +0 -0
- /package/dist/cli/{doctor-PKVQIXRT.js.map → doctor-CQTTZP27.js.map} +0 -0
- /package/dist/cli/{mcp-CRJ26PP4.js.map → mcp-J2UCD4RZ.js.map} +0 -0
- /package/dist/cli/{mcp-browse-QPAOWZOP.js.map → mcp-browse-GSX34JEK.js.map} +0 -0
- /package/dist/cli/{mcp-inspect-CVCLABRS.js.map → mcp-inspect-RRFYF4ZV.js.map} +0 -0
- /package/dist/cli/{prompt-SKYXERSI.js.map → prompt-5TQPIVHV.js.map} +0 -0
- /package/dist/cli/{replay-KPDW2ZMJ.js.map → replay-MJCEMODU.js.map} +0 -0
- /package/dist/cli/{run-WIKDIXTG.js.map → run-P4D5VDYE.js.map} +0 -0
- /package/dist/cli/{server-P6V2G3P6.js.map → server-C25JNNZV.js.map} +0 -0
- /package/dist/cli/{sessions-2NULRMSA.js.map → sessions-QIONZJQ6.js.map} +0 -0
- /package/dist/cli/{stats-T7BL2YOR.js.map → stats-DFZEXHP4.js.map} +0 -0
- /package/dist/cli/{version-3KWDNWLN.js.map → version-GR3X3MPI.js.map} +0 -0
|
@@ -3,7 +3,7 @@ import { createRequire as __cr } from 'node:module'; if (typeof globalThis.requi
|
|
|
3
3
|
import {
|
|
4
4
|
MemoryStore,
|
|
5
5
|
sanitizeMemoryName
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-BQ6HC66J.js";
|
|
7
7
|
import {
|
|
8
8
|
countTokens,
|
|
9
9
|
countTokensBounded,
|
|
@@ -12,12 +12,12 @@ import {
|
|
|
12
12
|
} from "./chunk-6OWJV3YW.js";
|
|
13
13
|
import {
|
|
14
14
|
Usage
|
|
15
|
-
} from "./chunk-
|
|
15
|
+
} from "./chunk-DWPAKZTY.js";
|
|
16
16
|
import {
|
|
17
17
|
applyEdit,
|
|
18
18
|
applyMultiEdit,
|
|
19
19
|
pauseGate
|
|
20
|
-
} from "./chunk-
|
|
20
|
+
} from "./chunk-TRSAHHCL.js";
|
|
21
21
|
import {
|
|
22
22
|
NEGATIVE_CLAIM_RULE,
|
|
23
23
|
PROJECT_MEMORY_FILES,
|
|
@@ -28,7 +28,7 @@ import {
|
|
|
28
28
|
import {
|
|
29
29
|
formatHookOutcomeMessage,
|
|
30
30
|
runHooks
|
|
31
|
-
} from "./chunk-
|
|
31
|
+
} from "./chunk-GH7DC2Y5.js";
|
|
32
32
|
import {
|
|
33
33
|
ignoredByLayers,
|
|
34
34
|
loadGitignoreAt,
|
|
@@ -46,10 +46,10 @@ import {
|
|
|
46
46
|
DEEPSEEK_CONTEXT_TOKENS,
|
|
47
47
|
DEFAULT_CONTEXT_TOKENS,
|
|
48
48
|
SessionStats
|
|
49
|
-
} from "./chunk-
|
|
49
|
+
} from "./chunk-QCFLPSPH.js";
|
|
50
50
|
import {
|
|
51
51
|
t
|
|
52
|
-
} from "./chunk-
|
|
52
|
+
} from "./chunk-NRQ5UP5T.js";
|
|
53
53
|
import {
|
|
54
54
|
DEFAULT_INDEX_EXCLUDES,
|
|
55
55
|
addProjectPathAllowed,
|
|
@@ -60,7 +60,7 @@ import {
|
|
|
60
60
|
require_picomatch,
|
|
61
61
|
webSearchEndpoint,
|
|
62
62
|
webSearchEngine
|
|
63
|
-
} from "./chunk-
|
|
63
|
+
} from "./chunk-6CRPCJAU.js";
|
|
64
64
|
import {
|
|
65
65
|
__commonJS,
|
|
66
66
|
__esm,
|
|
@@ -6309,10 +6309,13 @@ var ToolRegistry = class {
|
|
|
6309
6309
|
_autoFlatten;
|
|
6310
6310
|
_planMode = false;
|
|
6311
6311
|
_interceptor = null;
|
|
6312
|
+
_interceptors = [];
|
|
6312
6313
|
_auditListener = null;
|
|
6313
6314
|
_resultAugmenter = null;
|
|
6314
6315
|
/** Per-tool fingerprint of the last call that failed schema validation. Cleared by any successful validation for that tool. */
|
|
6315
6316
|
_lastMalformed = /* @__PURE__ */ new Map();
|
|
6317
|
+
/** Per-tool fingerprint of the last host-side interceptor rejection. */
|
|
6318
|
+
_lastInterceptorRejection = /* @__PURE__ */ new Map();
|
|
6316
6319
|
constructor(opts = {}) {
|
|
6317
6320
|
this._autoFlatten = opts.autoFlatten !== false;
|
|
6318
6321
|
}
|
|
@@ -6328,6 +6331,18 @@ var ToolRegistry = class {
|
|
|
6328
6331
|
setToolInterceptor(fn) {
|
|
6329
6332
|
this._interceptor = fn;
|
|
6330
6333
|
}
|
|
6334
|
+
/** Ordered host-side interceptors. They run before the legacy single interceptor. */
|
|
6335
|
+
addToolInterceptor(id, fn) {
|
|
6336
|
+
const normalized = id.trim();
|
|
6337
|
+
if (!normalized) throw new Error("tool interceptor requires a non-empty id");
|
|
6338
|
+
const existing = this._interceptors.findIndex((entry) => entry.id === normalized);
|
|
6339
|
+
if (existing >= 0) this._interceptors.splice(existing, 1);
|
|
6340
|
+
this._interceptors.push({ id: normalized, fn });
|
|
6341
|
+
return () => {
|
|
6342
|
+
const idx = this._interceptors.findIndex((entry) => entry.id === normalized);
|
|
6343
|
+
if (idx >= 0) this._interceptors.splice(idx, 1);
|
|
6344
|
+
};
|
|
6345
|
+
}
|
|
6331
6346
|
setAuditListener(fn) {
|
|
6332
6347
|
this._auditListener = fn;
|
|
6333
6348
|
}
|
|
@@ -6416,16 +6431,21 @@ var ToolRegistry = class {
|
|
|
6416
6431
|
rejectedReason: "plan-mode"
|
|
6417
6432
|
});
|
|
6418
6433
|
}
|
|
6419
|
-
|
|
6434
|
+
const chain = this._interceptor ? [...this._interceptors.map((entry) => entry.fn), this._interceptor] : this._interceptors.map((entry) => entry.fn);
|
|
6435
|
+
for (const interceptor of chain) {
|
|
6420
6436
|
try {
|
|
6421
|
-
const short = await
|
|
6422
|
-
if (typeof short === "string")
|
|
6437
|
+
const short = await interceptor(name, args);
|
|
6438
|
+
if (typeof short === "string") {
|
|
6439
|
+
const guarded = this._noteInterceptorRejection(name, fingerprint, short);
|
|
6440
|
+
return this._augmentResult(name, args, guarded);
|
|
6441
|
+
}
|
|
6423
6442
|
} catch (err) {
|
|
6424
6443
|
return JSON.stringify({
|
|
6425
6444
|
error: `${name}: interceptor failed \u2014 ${err.message}`
|
|
6426
6445
|
});
|
|
6427
6446
|
}
|
|
6428
6447
|
}
|
|
6448
|
+
this._lastInterceptorRejection.delete(name);
|
|
6429
6449
|
if (opts.signal?.aborted) {
|
|
6430
6450
|
return JSON.stringify({
|
|
6431
6451
|
error: `${name}: aborted before dispatch (user interrupt)`,
|
|
@@ -6463,13 +6483,16 @@ var ToolRegistry = class {
|
|
|
6463
6483
|
finalResult = JSON.stringify({ error: `${e.name}: ${e.message}` });
|
|
6464
6484
|
}
|
|
6465
6485
|
}
|
|
6486
|
+
return this._augmentResult(name, args, finalResult);
|
|
6487
|
+
}
|
|
6488
|
+
_augmentResult(name, args, result) {
|
|
6466
6489
|
if (this._resultAugmenter) {
|
|
6467
6490
|
try {
|
|
6468
|
-
return this._resultAugmenter(name, args,
|
|
6491
|
+
return this._resultAugmenter(name, args, result);
|
|
6469
6492
|
} catch {
|
|
6470
6493
|
}
|
|
6471
6494
|
}
|
|
6472
|
-
return
|
|
6495
|
+
return result;
|
|
6473
6496
|
}
|
|
6474
6497
|
/** Records the failed call's fingerprint; on the 2nd consecutive identical malformed call to the same tool, returns a sharper error that tells the model to stop retrying. */
|
|
6475
6498
|
_noteMalformed(name, fingerprint, detail) {
|
|
@@ -6483,7 +6506,35 @@ var ToolRegistry = class {
|
|
|
6483
6506
|
}
|
|
6484
6507
|
return JSON.stringify({ error: `${name}: ${detail}` });
|
|
6485
6508
|
}
|
|
6509
|
+
_noteInterceptorRejection(name, fingerprint, result) {
|
|
6510
|
+
const reason = rejectedReason(result);
|
|
6511
|
+
if (!reason) {
|
|
6512
|
+
this._lastInterceptorRejection.delete(name);
|
|
6513
|
+
return result;
|
|
6514
|
+
}
|
|
6515
|
+
const key = `${reason}:${fingerprint}`;
|
|
6516
|
+
const prev = this._lastInterceptorRejection.get(name);
|
|
6517
|
+
this._lastInterceptorRejection.set(name, key);
|
|
6518
|
+
if (prev === key) {
|
|
6519
|
+
return JSON.stringify({
|
|
6520
|
+
error: `${name}: same call was just rejected by ${reason} \u2014 do not retry identical args. Switch to read-only exploration, submit or revise the plan, or choose a different tool call.`,
|
|
6521
|
+
rejectedReason: reason,
|
|
6522
|
+
consecutiveInterceptorRejection: true
|
|
6523
|
+
});
|
|
6524
|
+
}
|
|
6525
|
+
return result;
|
|
6526
|
+
}
|
|
6486
6527
|
};
|
|
6528
|
+
function rejectedReason(result) {
|
|
6529
|
+
try {
|
|
6530
|
+
const parsed = JSON.parse(result);
|
|
6531
|
+
if (!parsed || typeof parsed !== "object") return null;
|
|
6532
|
+
const reason = parsed.rejectedReason;
|
|
6533
|
+
return typeof reason === "string" && reason ? reason : null;
|
|
6534
|
+
} catch {
|
|
6535
|
+
return null;
|
|
6536
|
+
}
|
|
6537
|
+
}
|
|
6487
6538
|
function isReadOnlyCall(tool, args) {
|
|
6488
6539
|
if (tool.readOnlyCheck) {
|
|
6489
6540
|
try {
|
|
@@ -8998,7 +9049,7 @@ function registerMemoryTools(registry, opts = {}) {
|
|
|
8998
9049
|
}
|
|
8999
9050
|
registry.register({
|
|
9000
9051
|
name: "remember",
|
|
9001
|
-
description: "Save a memory for future sessions
|
|
9052
|
+
description: "Save a memory for future sessions \u2014 preferences, corrections, non-obvious project facts. Not for transient task state. Loads into the system prompt on next `/new` or launch.",
|
|
9002
9053
|
parameters: {
|
|
9003
9054
|
type: "object",
|
|
9004
9055
|
properties: {
|
|
@@ -9009,29 +9060,29 @@ function registerMemoryTools(registry, opts = {}) {
|
|
|
9009
9060
|
scope: {
|
|
9010
9061
|
type: "string",
|
|
9011
9062
|
enum: ["global", "project"],
|
|
9012
|
-
description: "
|
|
9063
|
+
description: "global = across all projects; project = current sandbox only (needs `reasonix code`)."
|
|
9013
9064
|
},
|
|
9014
9065
|
name: {
|
|
9015
9066
|
type: "string",
|
|
9016
|
-
description: "
|
|
9067
|
+
description: "Filename-safe id, 3-40 chars, alnum + _ - . (no separators, no leading dot)."
|
|
9017
9068
|
},
|
|
9018
9069
|
description: {
|
|
9019
9070
|
type: "string",
|
|
9020
|
-
description: "
|
|
9071
|
+
description: "\u2264150 char one-liner shown in MEMORY.md."
|
|
9021
9072
|
},
|
|
9022
9073
|
content: {
|
|
9023
9074
|
type: "string",
|
|
9024
|
-
description: "
|
|
9075
|
+
description: "Markdown body. For feedback/project, structure as rule + **Why:** + **How to apply:**."
|
|
9025
9076
|
},
|
|
9026
9077
|
priority: {
|
|
9027
9078
|
type: "string",
|
|
9028
9079
|
enum: ["low", "medium", "high"],
|
|
9029
|
-
description: "
|
|
9080
|
+
description: "`high` injects entry into HIGH PRIORITY block \u2014 use sparingly."
|
|
9030
9081
|
},
|
|
9031
9082
|
expires: {
|
|
9032
9083
|
type: "string",
|
|
9033
9084
|
enum: ["project_end"],
|
|
9034
|
-
description: "
|
|
9085
|
+
description: "`project_end` lets /memory clear project remove this even at global scope."
|
|
9035
9086
|
}
|
|
9036
9087
|
},
|
|
9037
9088
|
required: ["type", "scope", "name", "description", "content"]
|
|
@@ -9148,26 +9199,26 @@ function sanitizeOptions(raw) {
|
|
|
9148
9199
|
function registerChoiceTool(registry, opts = {}) {
|
|
9149
9200
|
registry.register({
|
|
9150
9201
|
name: "ask_choice",
|
|
9151
|
-
description: "
|
|
9202
|
+
description: "Render an arrow-key picker with 2\u20136 alternatives. Use when the user is supposed to pick \u2014 never enumerate choices as prose. Skip when one option is clearly best (just do it) or a free-form text answer fits. Max 6 options; set `allowCustom:true` when their real answer might not fit.",
|
|
9152
9203
|
readOnly: true,
|
|
9153
9204
|
parameters: {
|
|
9154
9205
|
type: "object",
|
|
9155
9206
|
properties: {
|
|
9156
9207
|
question: {
|
|
9157
9208
|
type: "string",
|
|
9158
|
-
description: "
|
|
9209
|
+
description: "One-sentence question. Don't repeat the options here \u2014 the picker renders them."
|
|
9159
9210
|
},
|
|
9160
9211
|
options: {
|
|
9161
9212
|
type: "array",
|
|
9162
|
-
description: "2\
|
|
9213
|
+
description: "2\u20136 alternatives. Each: stable id + short title; summary optional.",
|
|
9163
9214
|
items: {
|
|
9164
9215
|
type: "object",
|
|
9165
9216
|
properties: {
|
|
9166
|
-
id: { type: "string", description: "
|
|
9167
|
-
title: { type: "string", description: "One-line
|
|
9217
|
+
id: { type: "string", description: "Stable id (A, B, C or option-1)." },
|
|
9218
|
+
title: { type: "string", description: "One-line label." },
|
|
9168
9219
|
summary: {
|
|
9169
9220
|
type: "string",
|
|
9170
|
-
description: "Optional
|
|
9221
|
+
description: "Optional dimmed second line, \u226480 chars."
|
|
9171
9222
|
}
|
|
9172
9223
|
},
|
|
9173
9224
|
required: ["id", "title"]
|
|
@@ -9175,7 +9226,7 @@ function registerChoiceTool(registry, opts = {}) {
|
|
|
9175
9226
|
},
|
|
9176
9227
|
allowCustom: {
|
|
9177
9228
|
type: "boolean",
|
|
9178
|
-
description: "
|
|
9229
|
+
description: "Shows a 'type my own answer' escape hatch. Default false."
|
|
9179
9230
|
}
|
|
9180
9231
|
},
|
|
9181
9232
|
required: ["question", "options"]
|
|
@@ -9660,8 +9711,8 @@ function registerWebTools(registry, opts = {}) {
|
|
|
9660
9711
|
required: ["query"]
|
|
9661
9712
|
},
|
|
9662
9713
|
fn: async (args, ctx) => {
|
|
9663
|
-
const engine =
|
|
9664
|
-
const endpoint =
|
|
9714
|
+
const engine = webSearchEngine();
|
|
9715
|
+
const endpoint = webSearchEndpoint();
|
|
9665
9716
|
const results = await webSearch(args.query, {
|
|
9666
9717
|
topK: args.topK ?? defaultTopK,
|
|
9667
9718
|
signal: ctx?.signal,
|
|
@@ -10368,7 +10419,7 @@ async function searchContent(ctx, startAbs, args) {
|
|
|
10368
10419
|
}
|
|
10369
10420
|
|
|
10370
10421
|
// src/tools/filesystem.ts
|
|
10371
|
-
var DEFAULT_OUTLINE_THRESHOLD_BYTES =
|
|
10422
|
+
var DEFAULT_OUTLINE_THRESHOLD_BYTES = 64 * 1024;
|
|
10372
10423
|
var DEFAULT_MAX_LIST_BYTES = 256 * 1024;
|
|
10373
10424
|
var HARD_MAX_FILE_BYTES = 32 * 1024 * 1024;
|
|
10374
10425
|
var OUTLINE_HEAD_LINES = 80;
|
|
@@ -10510,11 +10561,7 @@ ${body}`;
|
|
|
10510
10561
|
registry.register({
|
|
10511
10562
|
name: "read_file",
|
|
10512
10563
|
parallelSafe: true,
|
|
10513
|
-
description: `Read a file under the sandbox root. Default
|
|
10514
|
-
- head: N \u2192 first N lines (cheap probe of imports / config head)
|
|
10515
|
-
- tail: N \u2192 last N lines (recent-tail of a log)
|
|
10516
|
-
- range: "A-B" \u2192 inclusive 1-indexed range (e.g. "120-180" around an edit site)
|
|
10517
|
-
Files OVER the threshold auto-switch to outline mode: file metadata + first ${OUTLINE_HEAD_LINES} lines + a top-level symbol outline (TS/JS exports, Python def/class, Go func/type, Rust fn/struct/impl/trait, Markdown headings, Protobuf message/service/rpc, plain-text chapter markers) + concrete next-step commands. No middle bytes \u2014 drill in with range / search_content. Files over ${Math.round(HARD_MAX_FILE_BYTES / (1024 * 1024))} MiB are refused entirely (use grep / range). Binary files are refused \u2014 use get_file_info if you only need stat.`,
|
|
10564
|
+
description: `Read a file under the sandbox root. Default returns FULL CONTENT for files \u2264 ${Math.round(DEFAULT_OUTLINE_THRESHOLD_BYTES / 1024)} KiB. Optional scoping: head/tail (N lines), range "A-B" (1-indexed inclusive). Larger files auto-switch to outline mode (metadata + head + symbol outline for TS/JS/Python/Go/Rust/Markdown/Protobuf/text) \u2014 drill in with range or search_content. Files over ${Math.round(HARD_MAX_FILE_BYTES / (1024 * 1024))} MiB and binaries are refused \u2014 use get_file_info for stat.`,
|
|
10518
10565
|
readOnly: true,
|
|
10519
10566
|
stormExempt: true,
|
|
10520
10567
|
parameters: {
|
|
@@ -10632,11 +10679,7 @@ ${slice.join("\n")}`);
|
|
|
10632
10679
|
registry.register({
|
|
10633
10680
|
name: "directory_tree",
|
|
10634
10681
|
parallelSafe: true,
|
|
10635
|
-
description: `Recursively list entries
|
|
10636
|
-
- maxDepth defaults to 2 (root + one level). A depth-4 tree on a real repo blew ~5K tokens in one call. If you truly need deeper, pass maxDepth:N explicitly.
|
|
10637
|
-
- Skips ${[...SKIP_DIR_NAMES].sort().join(", ")} unless include_deps:true. Traversing into node_modules / .git / dist is almost always token-waste.
|
|
10638
|
-
- Large subtrees (>50 children) auto-collapse to "[N files, M dirs hidden \u2014 list_directory <path> to inspect]" so one huge folder can't dominate the output.
|
|
10639
|
-
Prefer \`list_directory\` for a single-level view, \`search_files\` to find specific paths, and \`search_content\` to find code.`,
|
|
10682
|
+
description: `Recursively list entries with indented tree structure (dirs marked '/'). Budget-aware: maxDepth defaults to 2, large subtrees (>50 children) auto-collapse to "[N hidden \u2014 list_directory to inspect]", and ${[...SKIP_DIR_NAMES].sort().join(" / ")} are skipped unless include_deps:true. For single-level use list_directory; for path lookups use search_files; for code lookups use search_content.`,
|
|
10640
10683
|
readOnly: true,
|
|
10641
10684
|
parameters: {
|
|
10642
10685
|
type: "object",
|
|
@@ -10737,38 +10780,38 @@ Prefer \`list_directory\` for a single-level view, \`search_files\` to find spec
|
|
|
10737
10780
|
registry.register({
|
|
10738
10781
|
name: "search_content",
|
|
10739
10782
|
parallelSafe: true,
|
|
10740
|
-
description: "Recursively grep file CONTENTS for a substring or regex
|
|
10783
|
+
description: "Recursively grep file CONTENTS for a substring or regex \u2014 'where is X called', 'what files contain Y'. Returns one match per line as `path:line: text`. Per-file hit cap 30; when the byte budget is mostly spent, remaining files switch to a `rel: N matches` histogram. Pass `summary_only:true` for just the histogram. Skips dependency / VCS / build dirs and binary files. For file NAMES use search_files.",
|
|
10741
10784
|
readOnly: true,
|
|
10742
10785
|
parameters: {
|
|
10743
10786
|
type: "object",
|
|
10744
10787
|
properties: {
|
|
10745
10788
|
pattern: {
|
|
10746
10789
|
type: "string",
|
|
10747
|
-
description: "Substring
|
|
10790
|
+
description: "Substring or regex."
|
|
10748
10791
|
},
|
|
10749
10792
|
path: {
|
|
10750
10793
|
type: "string",
|
|
10751
|
-
description: "
|
|
10794
|
+
description: "Search root (default: sandbox root)."
|
|
10752
10795
|
},
|
|
10753
10796
|
glob: {
|
|
10754
10797
|
type: "string",
|
|
10755
|
-
description: "
|
|
10798
|
+
description: "Filename filter. Glob when it contains `*`/`?`/`{`/`[`; otherwise substring. Patterns with `/` match the path relative to the search root."
|
|
10756
10799
|
},
|
|
10757
10800
|
case_sensitive: {
|
|
10758
10801
|
type: "boolean",
|
|
10759
|
-
description: "
|
|
10802
|
+
description: "Default false."
|
|
10760
10803
|
},
|
|
10761
10804
|
include_deps: {
|
|
10762
10805
|
type: "boolean",
|
|
10763
|
-
description: "
|
|
10806
|
+
description: "Also search node_modules / .git / dist / build / etc. Default off."
|
|
10764
10807
|
},
|
|
10765
10808
|
context: {
|
|
10766
10809
|
type: "integer",
|
|
10767
|
-
description: "Lines of context
|
|
10810
|
+
description: "Lines of context around each match (both sides). Default 0, capped 20. Ripgrep-style output."
|
|
10768
10811
|
},
|
|
10769
10812
|
summary_only: {
|
|
10770
10813
|
type: "boolean",
|
|
10771
|
-
description: "
|
|
10814
|
+
description: "Skip line content, return `rel: N matches` per file. Use for 'where does this exist at all' before drilling in."
|
|
10772
10815
|
}
|
|
10773
10816
|
},
|
|
10774
10817
|
required: ["pattern"]
|
|
@@ -10881,7 +10924,7 @@ Prefer \`list_directory\` for a single-level view, \`search_files\` to find spec
|
|
|
10881
10924
|
});
|
|
10882
10925
|
registry.register({
|
|
10883
10926
|
name: "multi_edit",
|
|
10884
|
-
description: "Apply N SEARCH/REPLACE edits across ONE OR MORE files in
|
|
10927
|
+
description: "Apply N SEARCH/REPLACE edits across ONE OR MORE files in one call. Edits validate across the full batch before writing. Validation failures leave all files untouched; disk write failures trigger best-effort rollback of files that may have been modified. Per-file edits run in array order, so a later edit can match text inserted by an earlier one. Same per-edit rules as edit_file: `search` is exact text (whitespace sensitive, no regex) and must be unique in its target file at the moment that edit applies. Use this for renames spanning multiple files, cross-file refactors, or any batch where you'd otherwise loop edit_file.",
|
|
10885
10928
|
parameters: {
|
|
10886
10929
|
type: "object",
|
|
10887
10930
|
properties: {
|
|
@@ -11023,19 +11066,33 @@ Prefer \`list_directory\` for a single-level view, \`search_files\` to find spec
|
|
|
11023
11066
|
}
|
|
11024
11067
|
|
|
11025
11068
|
// src/tools/plan-core.ts
|
|
11026
|
-
var SUBMIT_PLAN_DESCRIPTION = "Submit ONE concrete plan
|
|
11027
|
-
var MARK_STEP_COMPLETE_DESCRIPTION = "Mark one
|
|
11028
|
-
var REVISE_PLAN_DESCRIPTION = "
|
|
11069
|
+
var SUBMIT_PLAN_DESCRIPTION = "Submit ONE concrete plan for review. The user approves / refines / cancels \u2014 write a markdown plan body and (strongly preferred) a structured `steps` array. Use for multi-file refactors, architecture changes, anything expensive to undo. Skip for small fixes. Do NOT use for A/B/C menus \u2014 the picker has no branch selector, so a menu plan strands the user; call `ask_choice` for branching decisions. See the system prompt for fuller guidance.";
|
|
11070
|
+
var MARK_STEP_COMPLETE_DESCRIPTION = "Mark one approved-plan step as done. Call exactly once after finishing each step, before starting the next. After the FINAL step, write a brief reply summarizing what was done and end the turn. Skip if the plan didn't include structured steps.";
|
|
11071
|
+
var REVISE_PLAN_DESCRIPTION = "Replace the REMAINING steps of an in-flight plan when checkpoint feedback warrants a structural change. Pass `reason`, the new `remainingSteps` tail (done steps are untouched \u2014 keep them out), and optional updated `summary`. Don't call submit_plan for revisions \u2014 it resets the whole plan.";
|
|
11029
11072
|
var STEP_ITEM_SCHEMA = {
|
|
11030
11073
|
type: "object",
|
|
11031
11074
|
properties: {
|
|
11032
11075
|
id: { type: "string", description: "Stable id, e.g. step-1." },
|
|
11033
11076
|
title: { type: "string", description: "Short imperative title." },
|
|
11034
|
-
action: { type: "string", description: "One-sentence
|
|
11077
|
+
action: { type: "string", description: "One-sentence concrete action." },
|
|
11035
11078
|
risk: {
|
|
11036
11079
|
type: "string",
|
|
11037
11080
|
enum: ["low", "med", "high"],
|
|
11038
|
-
description: "
|
|
11081
|
+
description: "high = hard-to-undo / prod / API break; med = reversible multi-file; low = safe local. Omit if unsure."
|
|
11082
|
+
},
|
|
11083
|
+
targets: {
|
|
11084
|
+
type: "array",
|
|
11085
|
+
description: "Optional. Files/dirs/modules this step touches.",
|
|
11086
|
+
items: { type: "string" }
|
|
11087
|
+
},
|
|
11088
|
+
acceptance: {
|
|
11089
|
+
type: "string",
|
|
11090
|
+
description: "Optional. One-sentence completion criterion."
|
|
11091
|
+
},
|
|
11092
|
+
verification: {
|
|
11093
|
+
type: "array",
|
|
11094
|
+
description: "Optional. Verification commands/checks for this step.",
|
|
11095
|
+
items: { type: "string" }
|
|
11039
11096
|
}
|
|
11040
11097
|
},
|
|
11041
11098
|
required: ["id", "title", "action"]
|
|
@@ -11057,10 +11114,42 @@ function sanitizeSteps(raw) {
|
|
|
11057
11114
|
const step = { id, title, action };
|
|
11058
11115
|
const risk = sanitizeRisk(e.risk);
|
|
11059
11116
|
if (risk) step.risk = risk;
|
|
11117
|
+
const targets = sanitizeStringList(e.targets);
|
|
11118
|
+
if (targets) step.targets = targets;
|
|
11119
|
+
const acceptance = typeof e.acceptance === "string" ? e.acceptance.trim() : "";
|
|
11120
|
+
if (acceptance) step.acceptance = acceptance;
|
|
11121
|
+
const verification = sanitizeStringList(e.verification);
|
|
11122
|
+
if (verification) step.verification = verification;
|
|
11060
11123
|
steps.push(step);
|
|
11061
11124
|
}
|
|
11062
11125
|
return steps.length > 0 ? steps : void 0;
|
|
11063
11126
|
}
|
|
11127
|
+
function sanitizeStringList(raw) {
|
|
11128
|
+
if (!Array.isArray(raw)) return void 0;
|
|
11129
|
+
const out = raw.map((entry) => typeof entry === "string" ? entry.trim() : "").filter((entry) => entry.length > 0);
|
|
11130
|
+
return out.length > 0 ? out : void 0;
|
|
11131
|
+
}
|
|
11132
|
+
function sanitizeEvidence(raw) {
|
|
11133
|
+
if (!Array.isArray(raw)) return void 0;
|
|
11134
|
+
const out = [];
|
|
11135
|
+
for (const item of raw) {
|
|
11136
|
+
if (!item || typeof item !== "object") continue;
|
|
11137
|
+
const e = item;
|
|
11138
|
+
const kind = e.kind;
|
|
11139
|
+
if (kind !== "verification" && kind !== "diff" && kind !== "checkpoint" && kind !== "manual") {
|
|
11140
|
+
continue;
|
|
11141
|
+
}
|
|
11142
|
+
const summary = typeof e.summary === "string" ? e.summary.trim() : "";
|
|
11143
|
+
if (!summary) continue;
|
|
11144
|
+
const evidence = { kind, summary };
|
|
11145
|
+
const command = typeof e.command === "string" ? e.command.trim() : "";
|
|
11146
|
+
if (command) evidence.command = command;
|
|
11147
|
+
const paths = sanitizeStringList(e.paths);
|
|
11148
|
+
if (paths) evidence.paths = paths;
|
|
11149
|
+
out.push(evidence);
|
|
11150
|
+
}
|
|
11151
|
+
return out.length > 0 ? out : void 0;
|
|
11152
|
+
}
|
|
11064
11153
|
function registerSubmitPlan(registry, opts) {
|
|
11065
11154
|
registry.register({
|
|
11066
11155
|
name: "submit_plan",
|
|
@@ -11071,16 +11160,16 @@ function registerSubmitPlan(registry, opts) {
|
|
|
11071
11160
|
properties: {
|
|
11072
11161
|
plan: {
|
|
11073
11162
|
type: "string",
|
|
11074
|
-
description: "Markdown
|
|
11163
|
+
description: "Markdown plan: one-line summary, file-by-file breakdown, risks/open questions."
|
|
11075
11164
|
},
|
|
11076
11165
|
steps: {
|
|
11077
11166
|
type: "array",
|
|
11078
|
-
description: "Structured step list
|
|
11167
|
+
description: "Structured step list \u2014 strongly recommended for >1 step. Stable ids (step-1, step-2, ...).",
|
|
11079
11168
|
items: STEP_ITEM_SCHEMA
|
|
11080
11169
|
},
|
|
11081
11170
|
summary: {
|
|
11082
11171
|
type: "string",
|
|
11083
|
-
description: "Optional
|
|
11172
|
+
description: "Optional ~80-char plan title for the picker header and /plans listings."
|
|
11084
11173
|
}
|
|
11085
11174
|
},
|
|
11086
11175
|
required: ["plan"]
|
|
@@ -11118,19 +11207,33 @@ function registerMarkStepComplete(registry, opts) {
|
|
|
11118
11207
|
properties: {
|
|
11119
11208
|
stepId: {
|
|
11120
11209
|
type: "string",
|
|
11121
|
-
description: "
|
|
11210
|
+
description: "Step id from submit_plan's steps array."
|
|
11122
11211
|
},
|
|
11123
11212
|
title: {
|
|
11124
11213
|
type: "string",
|
|
11125
|
-
description: "Optional.
|
|
11214
|
+
description: "Optional. Echoed for the UI; falls back to id."
|
|
11126
11215
|
},
|
|
11127
11216
|
result: {
|
|
11128
11217
|
type: "string",
|
|
11129
|
-
description: "One-sentence summary of what was done
|
|
11218
|
+
description: "One-sentence summary of what was done."
|
|
11130
11219
|
},
|
|
11131
11220
|
notes: {
|
|
11132
11221
|
type: "string",
|
|
11133
|
-
description: "Optional.
|
|
11222
|
+
description: "Optional. Surprises \u2014 blockers, revised assumptions, follow-ups."
|
|
11223
|
+
},
|
|
11224
|
+
evidence: {
|
|
11225
|
+
type: "array",
|
|
11226
|
+
description: "Optional. Verification summary / diff / checkpoint ref / manual note.",
|
|
11227
|
+
items: {
|
|
11228
|
+
type: "object",
|
|
11229
|
+
properties: {
|
|
11230
|
+
kind: { type: "string", enum: ["verification", "diff", "checkpoint", "manual"] },
|
|
11231
|
+
summary: { type: "string" },
|
|
11232
|
+
command: { type: "string" },
|
|
11233
|
+
paths: { type: "array", items: { type: "string" } }
|
|
11234
|
+
},
|
|
11235
|
+
required: ["kind", "summary"]
|
|
11236
|
+
}
|
|
11134
11237
|
}
|
|
11135
11238
|
},
|
|
11136
11239
|
required: ["stepId", "result"]
|
|
@@ -11148,9 +11251,15 @@ function registerMarkStepComplete(registry, opts) {
|
|
|
11148
11251
|
}
|
|
11149
11252
|
const title = typeof args?.title === "string" ? args.title.trim() || void 0 : void 0;
|
|
11150
11253
|
const notes = typeof args?.notes === "string" ? args.notes.trim() || void 0 : void 0;
|
|
11254
|
+
const evidence = sanitizeEvidence(args?.evidence);
|
|
11255
|
+
const evidenceReason = opts.requireStepEvidence?.({ stepId, title });
|
|
11256
|
+
if (evidenceReason && (!evidence || evidence.length === 0)) {
|
|
11257
|
+
throw new Error(`mark_step_complete: evidence required \u2014 ${evidenceReason}`);
|
|
11258
|
+
}
|
|
11151
11259
|
const update = { kind: "step_completed", stepId, result };
|
|
11152
11260
|
if (title) update.title = title;
|
|
11153
11261
|
if (notes) update.notes = notes;
|
|
11262
|
+
if (evidence) update.evidence = evidence;
|
|
11154
11263
|
opts.onStepCompleted?.(update);
|
|
11155
11264
|
const verdict = await (ctx?.confirmationGate ?? pauseGate).ask({
|
|
11156
11265
|
kind: "plan_checkpoint",
|
|
@@ -11175,16 +11284,16 @@ function registerRevisePlan(registry, opts) {
|
|
|
11175
11284
|
properties: {
|
|
11176
11285
|
reason: {
|
|
11177
11286
|
type: "string",
|
|
11178
|
-
description: "One sentence
|
|
11287
|
+
description: "One sentence \u2014 why you're revising / what the user asked for."
|
|
11179
11288
|
},
|
|
11180
11289
|
remainingSteps: {
|
|
11181
11290
|
type: "array",
|
|
11182
|
-
description: "
|
|
11291
|
+
description: "New tail of the plan. Reuse old ids when adjusting; new ids for new steps.",
|
|
11183
11292
|
items: STEP_ITEM_SCHEMA
|
|
11184
11293
|
},
|
|
11185
11294
|
summary: {
|
|
11186
11295
|
type: "string",
|
|
11187
|
-
description: "Optional. Updated one-line
|
|
11296
|
+
description: "Optional. Updated one-line summary when framing has shifted."
|
|
11188
11297
|
}
|
|
11189
11298
|
},
|
|
11190
11299
|
required: ["reason", "remainingSteps"]
|
|
@@ -11222,7 +11331,7 @@ function registerPlanTool(registry, opts = {}) {
|
|
|
11222
11331
|
}
|
|
11223
11332
|
|
|
11224
11333
|
// src/tools/todo.ts
|
|
11225
|
-
var DESCRIPTION =
|
|
11334
|
+
var DESCRIPTION = "In-session task tracker for 3+ step work. NOT a plan \u2014 no approval gate, no checkpoint, no files touched. Each call REPLACES the entire list (set semantics) \u2014 pass the FULL list. Exactly one item may be in_progress at a time; flip to completed the moment that step's done. Pass `[]` to clear. For approval gates use submit_plan; for branching choices use ask_choice.";
|
|
11226
11335
|
function validateTodos(raw) {
|
|
11227
11336
|
if (!Array.isArray(raw)) {
|
|
11228
11337
|
throw new Error("todo_write: `todos` must be an array");
|
|
@@ -11848,4 +11957,4 @@ export {
|
|
|
11848
11957
|
he/he.js:
|
|
11849
11958
|
(*! https://mths.be/he v1.2.0 by @mathias | MIT license *)
|
|
11850
11959
|
*/
|
|
11851
|
-
//# sourceMappingURL=chunk-
|
|
11960
|
+
//# sourceMappingURL=chunk-JBH5RM7X.js.map
|