@dsh-electron/dsh-plugin-multi-root-workspace 0.1.8 → 0.1.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.en.md +22 -1
- package/CHANGELOG.md +22 -1
- package/README.en.md +39 -16
- package/README.md +47 -24
- package/cordis.patch.yml +10 -0
- package/lib/auto-review-packages-nRjnb4pU.js +15 -0
- package/lib/auto-review.js +166 -0
- package/lib/client.js +573 -131
- package/lib/client.js.map +1 -1
- package/lib/{command-CESuwlVt.js → command-BGdz7VBH.js} +68 -8
- package/lib/command.js +1 -1
- package/lib/{compat-DR2LvmYZ.js → compat-D-MljsPV.js} +13 -2
- package/lib/compat.js +1 -1
- package/lib/{contract-DZ4zczDT.js → contract-CStSEOcK.js} +44 -1
- package/lib/fork-CzbeWxHp.js +670 -0
- package/lib/fs.js +1 -1
- package/lib/index.js +9 -8
- package/lib/{instructions-D19jRxN0.js → instructions-MePoRigy.js} +213 -263
- package/lib/instructions.js +1 -1
- package/lib/llm-message-fYORacvh.js +206 -0
- package/lib/lsp.js +1 -1
- package/lib/metadata-DgqSdVX_.js +35 -0
- package/lib/{registry-DCxC5Lay.js → registry-KSsmU393.js} +66 -13
- package/lib/registry.js +1 -1
- package/lib/review-context-AH-SXHmj.js +98 -0
- package/lib/review-context.js +2 -0
- package/lib/{roots-B-0l8mNG.js → roots-Ca_W1S9n.js} +1 -1
- package/lib/{sandbox-CVAcT_gy.js → sandbox-CXk5h-ct.js} +3 -3
- package/lib/sandbox.js +1 -1
- package/lib/scope.js +15 -6
- package/lib/skills.js +790 -0
- package/lib/types/auto-review/entry.d.ts +5 -0
- package/lib/types/client/WorkspaceFoldersAction.d.ts +1 -1
- package/lib/types/client/locales.d.ts +26 -16
- package/lib/types/client/skills-client.d.ts +23 -0
- package/lib/types/client/skills-settings.d.ts +10 -0
- package/lib/types/client/skills.d.ts +36 -0
- package/lib/types/client/styles.d.ts +1 -1
- package/lib/types/command.d.ts +1 -1
- package/lib/types/compat/auto-review-contract.d.ts +3 -0
- package/lib/types/compat/auto-review-loader.d.ts +33 -0
- package/lib/types/compat/auto-review-packages.d.ts +1 -0
- package/lib/types/compat/client-session.d.ts +2 -0
- package/lib/types/compat/dsh-version.d.ts +5 -5
- package/lib/types/compat/instruction-activity.d.ts +17 -0
- package/lib/types/compat/review-session.d.ts +2 -0
- package/lib/types/compat/skill-content.d.ts +3 -0
- package/lib/types/compat/skills-client.d.ts +33 -0
- package/lib/types/compat/skills-settings.d.ts +8 -0
- package/lib/types/compat/skills.d.ts +13 -0
- package/lib/types/compat/storage-zod.d.ts +1 -0
- package/lib/types/contract.d.ts +12 -1
- package/lib/types/instructions.d.ts +18 -1
- package/lib/types/registry.d.ts +7 -0
- package/lib/types/review-context.d.ts +49 -0
- package/lib/types/roots.d.ts +4 -1
- package/lib/types/scope.d.ts +5 -0
- package/lib/types/skills/catalog.d.ts +34 -0
- package/lib/types/skills/invocation.d.ts +7 -0
- package/lib/types/skills/metadata.d.ts +13 -0
- package/lib/types/skills/pool.d.ts +19 -0
- package/lib/types/skills/reader.d.ts +3 -0
- package/lib/types/skills/routing.d.ts +2 -0
- package/lib/types/skills-contract.d.ts +39 -0
- package/lib/types/skills.d.ts +43 -0
- package/lib/windows-runner.js +2 -2
- package/lib/workspace-files.js +2 -2
- package/package.json +121 -68
- package/src/auto-review/FORK.md +26 -0
- package/src/auto-review/LICENSE +21 -0
- package/src/auto-review/README.en.md +22 -0
- package/src/auto-review/README.md +22 -0
- package/lib/{fs-Nlp2AiRX.js → fs-BTXySwSG.js} +1 -1
- package/lib/{registry-lease-win32-DTO6QpT9.js → registry-lease-win32-DVTq9d4D.js} +1 -1
- package/lib/{windows-runner-contract-CEfmZzu0.js → windows-runner-contract-B5R2K3mM.js} +1 -1
package/lib/index.js
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { a as composeInstructionMessage,
|
|
3
|
-
import { n as
|
|
4
|
-
import {
|
|
1
|
+
import { i as renderInstructions, n as instructionsApi, t as createInstructionMessage } from "./llm-message-fYORacvh.js";
|
|
2
|
+
import { a as composeInstructionMessage, r as PLUGIN_SOURCE, t as DEFAULT_MAX_BYTES } from "./instructions-MePoRigy.js";
|
|
3
|
+
import { a as classifyStoredRoots, c as indexedStatuses, i as canonicalRoot, l as isCanonicallyUnder, m as validateRootCandidate, n as additionalRootId, p as resolveRootRef, r as availableRoots, s as expandRootInput, t as RootValidationError, u as removeStatusAt } from "./roots-Ca_W1S9n.js";
|
|
4
|
+
import { _ as classifyInstallation, c as agentPtyMarkerVerdict, d as HOST_SERVICE_PACKAGES, f as OPTIONAL_CORE_PACKAGES, g as SUPPORTED_DSH_RELEASES, h as RUNTIME_OPTIONAL_PACKAGES, i as assertSupportedInstallation, l as assertAgentPtyMarker, m as RUNNER_ANCHORED_PACKAGES, n as MultiRootCompatService, o as AGENT_PTY_MARKER, p as REQUIRED_CORE_PACKAGES, s as PtyMarkerContractError, t as DshCompatUnsupportedError, u as CORE_PACKAGES, v as compatEnforcement, y as readInstalledVersion } from "./compat-D-MljsPV.js";
|
|
5
|
+
import { n as widenConfined, t as MultiRootSandboxProvider } from "./sandbox-CXk5h-ct.js";
|
|
5
6
|
import { MULTI_ROOT_PROVIDER_BRAND, MultiRootProviders, brandMultiRootProvider, isMultiRootProvider } from "./providers.js";
|
|
6
|
-
import { t as MultiRootFileSystem } from "./fs-
|
|
7
|
-
import { a as parseRevealedView, i as parsePanelCall, n as PANEL_ENDPOINTS, o as parseRootsView, t as PANEL_CHANNEL } from "./contract-
|
|
7
|
+
import { t as MultiRootFileSystem } from "./fs-BTXySwSG.js";
|
|
8
|
+
import { a as parseRevealedView, i as parsePanelCall, n as PANEL_ENDPOINTS, o as parseRootsView, t as PANEL_CHANNEL } from "./contract-CStSEOcK.js";
|
|
8
9
|
import { MultiRootScopeService, renderWorkspaceRootsContext, sanitizeAdditionalRoots } from "./scope.js";
|
|
9
|
-
import { a as MultiRootRegistry, c as multiRootDomainSpec, i as MAX_ALIAS_LENGTH, l as RegistryAuthorityLease, n as DOMAIN_NAME, o as REGISTRY_CONTENDED_MESSAGE, r as MAX_ADDITIONAL_ROOTS_CEILING, t as DEFAULT_MAX_ADDITIONAL_ROOTS, u as RegistryLeaseContendedError } from "./registry-
|
|
10
|
-
import { a as renderRootsReport, c as revealArgv, i as parseFoldersCommand, o as resolvePanelPrimaryRoot, t as COMMAND_NAME } from "./command-
|
|
10
|
+
import { a as MultiRootRegistry, c as multiRootDomainSpec, i as MAX_ALIAS_LENGTH, l as RegistryAuthorityLease, n as DOMAIN_NAME, o as REGISTRY_CONTENDED_MESSAGE, r as MAX_ADDITIONAL_ROOTS_CEILING, t as DEFAULT_MAX_ADDITIONAL_ROOTS, u as RegistryLeaseContendedError } from "./registry-KSsmU393.js";
|
|
11
|
+
import { a as renderRootsReport, c as revealArgv, i as parseFoldersCommand, o as resolvePanelPrimaryRoot, t as COMMAND_NAME } from "./command-BGdz7VBH.js";
|
|
11
12
|
//#region src/index.ts
|
|
12
13
|
/**
|
|
13
14
|
* Carrier plugin face for the bare-package-name loader row (see the module
|
|
@@ -1,216 +1,13 @@
|
|
|
1
1
|
import { t as effectiveDirectory } from "./session-directory-BLOstut1.js";
|
|
2
|
+
import { n as instructionsApi, t as createInstructionMessage } from "./llm-message-fYORacvh.js";
|
|
2
3
|
import { t as aroundTool } from "./tool-context-CpgIFcCB.js";
|
|
3
|
-
import { l as isCanonicallyUnder } from "./roots-
|
|
4
|
-
import { createRequire } from "node:module";
|
|
5
|
-
import "@deepseek-ai/cordis";
|
|
6
|
-
import { basename, dirname, isAbsolute, relative, resolve, sep } from "node:path";
|
|
4
|
+
import { l as isCanonicallyUnder } from "./roots-Ca_W1S9n.js";
|
|
7
5
|
import { createHash } from "node:crypto";
|
|
8
|
-
import {
|
|
6
|
+
import { basename, dirname, isAbsolute, relative, resolve, sep } from "node:path";
|
|
7
|
+
import "@deepseek-ai/cordis";
|
|
9
8
|
import { canonicalPath } from "@deepseek-ai/dsh-sandbox";
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
* Compatibility adapter for upstream's instruction discovery and rendering.
|
|
13
|
-
*
|
|
14
|
-
* `@deepseek-ai/dsh-agent-instructions` renamed its renderer between two
|
|
15
|
-
* releases this plugin supports, without changing its signature:
|
|
16
|
-
*
|
|
17
|
-
* ```text
|
|
18
|
-
* 0.1.5-rc.2 renderWorkspaceContext(files, options) RenderedWorkspaceContext
|
|
19
|
-
* 0.1.6-alpha.1 renderAgentInstructions(files, options) RenderedAgentInstructions
|
|
20
|
-
* ```
|
|
21
|
-
*
|
|
22
|
-
* `discoverBaselineInstructionFiles` kept both its name and its signature.
|
|
23
|
-
*
|
|
24
|
-
* All coupling to that package is concentrated here so the business layer
|
|
25
|
-
* (`src/instructions.ts`) only ever calls {@link renderInstructions} and
|
|
26
|
-
* {@link InstructionsApi.discover}. A future rename is one edit in this file,
|
|
27
|
-
* not a version check sprinkled through the provider.
|
|
28
|
-
*
|
|
29
|
-
* The export is picked by NAME rather than by comparing the release string:
|
|
30
|
-
* a structural probe also copes with upstream keeping both names for a release,
|
|
31
|
-
* or reshaping within one, which a version comparison does not.
|
|
32
|
-
*
|
|
33
|
-
* The package is loaded LAZILY, and its genuine ABSENCE is reported as absence
|
|
34
|
-
* rather than thrown. It is an optional peer: the default DSH bundle mounts it,
|
|
35
|
-
* but a minimal composition legitimately has neither it nor an agent, and in
|
|
36
|
-
* that case this plugin's instruction row must simply contribute nothing. A
|
|
37
|
-
* package that is present but cannot be evaluated is a different answer, and
|
|
38
|
-
* one this adapter reports instead of caching as absence.
|
|
39
|
-
*
|
|
40
|
-
* @module @dsh-electron/dsh-plugin-multi-root-workspace/compat/agent-instructions
|
|
41
|
-
*/
|
|
42
|
-
/** Raised when the package is present but carries neither renderer name. */
|
|
43
|
-
var DshInstructionApiError = class extends Error {
|
|
44
|
-
constructor(message) {
|
|
45
|
-
super(message);
|
|
46
|
-
this.name = "DshInstructionApiError";
|
|
47
|
-
}
|
|
48
|
-
};
|
|
49
|
-
/** Resolution is attempted once per process; `null` records a confirmed absence. */
|
|
50
|
-
let resolution;
|
|
51
|
-
/**
|
|
52
|
-
* Pick the renderer this release exports.
|
|
53
|
-
* @param module - the loaded upstream module.
|
|
54
|
-
* @returns the renderer.
|
|
55
|
-
* @throws {DshInstructionApiError} when neither name is present.
|
|
56
|
-
*/
|
|
57
|
-
function selectRenderer(module) {
|
|
58
|
-
const render = module.renderAgentInstructions ?? module.renderWorkspaceContext;
|
|
59
|
-
if (render === void 0) throw new DshInstructionApiError("multi-root workspace: @deepseek-ai/dsh-agent-instructions exports neither renderAgentInstructions (0.1.6 and later) nor renderWorkspaceContext (0.1.5); the additional roots' instruction files cannot be rendered. Adapt src/compat/agent-instructions.ts to the installed release.");
|
|
60
|
-
return render;
|
|
61
|
-
}
|
|
62
|
-
/**
|
|
63
|
-
* Adapt one loaded upstream module to {@link InstructionsApi}.
|
|
64
|
-
* @param module - the loaded upstream module.
|
|
65
|
-
* @returns the adapted surface.
|
|
66
|
-
* @throws {DshInstructionApiError} when a function this plugin needs is absent.
|
|
67
|
-
*/
|
|
68
|
-
function adaptInstructionsModule(module) {
|
|
69
|
-
const discover = module.discoverBaselineInstructionFiles;
|
|
70
|
-
if (discover === void 0) throw new DshInstructionApiError("multi-root workspace: @deepseek-ai/dsh-agent-instructions does not export discoverBaselineInstructionFiles; adapt src/compat/agent-instructions.ts to the installed release.");
|
|
71
|
-
return {
|
|
72
|
-
discover: (options) => discover(options),
|
|
73
|
-
render: selectRenderer(module)
|
|
74
|
-
};
|
|
75
|
-
}
|
|
76
|
-
/**
|
|
77
|
-
* Whether one package is installed at all, judged WITHOUT evaluating it.
|
|
78
|
-
*
|
|
79
|
-
* This is what separates "the optional peer is absent" from "the optional peer
|
|
80
|
-
* is installed but its evaluation fails" (a missing transitive dependency, a
|
|
81
|
-
* broken build). Only a genuine resolvability failure counts as absence: a
|
|
82
|
-
* resolution that fails for another reason (an `exports` map with no `require`
|
|
83
|
-
* condition, say) leaves the verdict to the `import()` below, which is the
|
|
84
|
-
* authority on whether the module can actually be loaded.
|
|
85
|
-
* @param specifier - the bare package specifier to probe.
|
|
86
|
-
* @returns whether the package resolves from this module.
|
|
87
|
-
*/
|
|
88
|
-
function isPackageInstalled(specifier) {
|
|
89
|
-
try {
|
|
90
|
-
createRequire(import.meta.url).resolve(specifier);
|
|
91
|
-
return true;
|
|
92
|
-
} catch (error) {
|
|
93
|
-
const code = error?.code;
|
|
94
|
-
return code !== "MODULE_NOT_FOUND" && code !== "ERR_MODULE_NOT_FOUND";
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
/**
|
|
98
|
-
* Load and adapt the upstream instruction surface, once.
|
|
99
|
-
*
|
|
100
|
-
* @returns the adapted surface, or `undefined` when the package is not
|
|
101
|
-
* installed. A package that IS installed but exports neither renderer throws
|
|
102
|
-
* instead: that is a compatibility break to fix, not an optional seam. So
|
|
103
|
-
* does one that is installed but cannot be evaluated at all — a missing
|
|
104
|
-
* transitive dependency, a broken build — because reporting that as absence
|
|
105
|
-
* would drop every additional root's instructions for the rest of the
|
|
106
|
-
* process. See {@link isPackageInstalled} for how the two are told apart.
|
|
107
|
-
*/
|
|
108
|
-
async function instructionsApi() {
|
|
109
|
-
resolution ??= (async () => {
|
|
110
|
-
if (!isPackageInstalled("@deepseek-ai/dsh-agent-instructions")) return null;
|
|
111
|
-
return adaptInstructionsModule(await import("@deepseek-ai/dsh-agent-instructions"));
|
|
112
|
-
})();
|
|
113
|
-
return await resolution ?? void 0;
|
|
114
|
-
}
|
|
115
|
-
/**
|
|
116
|
-
* Render loaded instruction files within a byte budget, through whichever
|
|
117
|
-
* renderer the installed release exports.
|
|
118
|
-
*
|
|
119
|
-
* This is the only rendering entry point the business layer uses.
|
|
120
|
-
* @param files - loaded files, ordered broadest to most specific.
|
|
121
|
-
* @param options - the byte budget.
|
|
122
|
-
* @returns the rendered text and its budget diagnostics.
|
|
123
|
-
* @throws {DshInstructionApiError} when no usable renderer is installed.
|
|
124
|
-
*/
|
|
125
|
-
async function renderInstructions(files, options) {
|
|
126
|
-
const api = await instructionsApi();
|
|
127
|
-
if (api === void 0) throw new DshInstructionApiError("multi-root workspace: @deepseek-ai/dsh-agent-instructions is not installed, so instruction files cannot be rendered. Check for its presence with instructionsApi() before calling renderInstructions().");
|
|
128
|
-
return api.render(files, options);
|
|
129
|
-
}
|
|
130
|
-
//#endregion
|
|
131
|
-
//#region src/compat/llm-message.ts
|
|
132
|
-
/**
|
|
133
|
-
* This plugin's own producer kind.
|
|
134
|
-
*
|
|
135
|
-
* Session format 4 rejects the shared `kind: 'plugin'` (`format v4 message
|
|
136
|
-
* requires a producer-owned source kind`). The kind is ours, not
|
|
137
|
-
* `agent-instructions`: upstream treats that kind's `changes` array as its
|
|
138
|
-
* own reconciliation authority.
|
|
139
|
-
*/
|
|
140
|
-
const PRODUCER_SOURCE_KIND = "multi-root-workspace";
|
|
141
|
-
/**
|
|
142
|
-
* The first session format whose encoder refuses `kind: 'plugin'`.
|
|
143
|
-
* Earlier formats declare that kind on `MessageSourceMap` and require it.
|
|
144
|
-
*/
|
|
145
|
-
const PRODUCER_OWNED_FORMAT = 4;
|
|
146
|
-
/**
|
|
147
|
-
* Which source kind the installed session format will persist.
|
|
148
|
-
* @param formatVersion - `SESSION_FORMAT_VERSION`, when the session package is installed.
|
|
149
|
-
* @returns `plugin` through format 3, and this plugin's own kind from format 4 on.
|
|
150
|
-
*/
|
|
151
|
-
function instructionSourceKind(formatVersion) {
|
|
152
|
-
return formatVersion !== void 0 && formatVersion >= PRODUCER_OWNED_FORMAT ? PRODUCER_SOURCE_KIND : "plugin";
|
|
153
|
-
}
|
|
154
|
-
/**
|
|
155
|
-
* The installed session format, when that package is present.
|
|
156
|
-
*
|
|
157
|
-
* A composition that never persists a session can omit the package; format 3
|
|
158
|
-
* is then the spelling that still declares `kind: 'plugin'`. Any other failure
|
|
159
|
-
* is a broken install and must surface.
|
|
160
|
-
* @returns the format version, or `undefined` when the package is not installed.
|
|
161
|
-
*/
|
|
162
|
-
async function installedFormatVersion() {
|
|
163
|
-
try {
|
|
164
|
-
const session = await import("@deepseek-ai/dsh-session");
|
|
165
|
-
return typeof session.SESSION_FORMAT_VERSION === "number" ? session.SESSION_FORMAT_VERSION : void 0;
|
|
166
|
-
} catch (error) {
|
|
167
|
-
const code = error.code;
|
|
168
|
-
if (code === "ERR_MODULE_NOT_FOUND" || code === "MODULE_NOT_FOUND") return void 0;
|
|
169
|
-
throw error;
|
|
170
|
-
}
|
|
171
|
-
}
|
|
172
|
-
/**
|
|
173
|
-
* Build one user-role instruction message.
|
|
174
|
-
*
|
|
175
|
-
* Format 3 and earlier: `{ kind: 'plugin', plugin, form: 'instructions' }`.
|
|
176
|
-
* Format 4 and later: `{ kind: 'multi-root-workspace', plugin, form: 'instructions' }`.
|
|
177
|
-
* @param input - the body and the plugin attribution.
|
|
178
|
-
* @returns the frozen message upstream's helper produced.
|
|
179
|
-
* @throws {Error} when the optional peer is absent: a step that has instruction
|
|
180
|
-
* text to deliver cannot be served without it, and staying silent would drop
|
|
181
|
-
* user-visible context instead of reporting a misconfigured composition.
|
|
182
|
-
*/
|
|
183
|
-
async function createInstructionMessage(input) {
|
|
184
|
-
let module;
|
|
185
|
-
try {
|
|
186
|
-
module = await import("@deepseek-ai/dsh-llm");
|
|
187
|
-
} catch (error) {
|
|
188
|
-
throw new Error(`multi-root workspace: @deepseek-ai/dsh-llm is not installed, so additional roots' instruction files cannot be delivered as messages (${error instanceof Error ? error.message : String(error)}).`);
|
|
189
|
-
}
|
|
190
|
-
const create = module.createUserMessage;
|
|
191
|
-
return create({
|
|
192
|
-
content: [{
|
|
193
|
-
type: "text",
|
|
194
|
-
text: input.text
|
|
195
|
-
}],
|
|
196
|
-
source: instructionSource(input.plugin, await installedFormatVersion())
|
|
197
|
-
});
|
|
198
|
-
}
|
|
199
|
-
/** The source object the installed format will persist. */
|
|
200
|
-
function instructionSource(plugin, formatVersion) {
|
|
201
|
-
const kind = instructionSourceKind(formatVersion);
|
|
202
|
-
if (kind === "plugin") return {
|
|
203
|
-
kind,
|
|
204
|
-
plugin,
|
|
205
|
-
form: "instructions"
|
|
206
|
-
};
|
|
207
|
-
return {
|
|
208
|
-
kind,
|
|
209
|
-
plugin,
|
|
210
|
-
form: "instructions"
|
|
211
|
-
};
|
|
212
|
-
}
|
|
213
|
-
//#endregion
|
|
9
|
+
import { stat } from "node:fs/promises";
|
|
10
|
+
import { AsyncLocalStorage } from "node:async_hooks";
|
|
214
11
|
//#region src/compat/tool-result.ts
|
|
215
12
|
/**
|
|
216
13
|
* Whether a tool-result message reports failure, on every supported release.
|
|
@@ -224,6 +21,95 @@ function toolResultFailed(message) {
|
|
|
224
21
|
return block.isError === true;
|
|
225
22
|
}
|
|
226
23
|
//#endregion
|
|
24
|
+
//#region src/compat/instruction-activity.ts
|
|
25
|
+
/** Public durable file activity, normalized without loading an optional tool runtime. */
|
|
26
|
+
function ptcFileActivity(event) {
|
|
27
|
+
const row = event;
|
|
28
|
+
const data = row.data;
|
|
29
|
+
if (typeof data?.subCallId !== "string") return void 0;
|
|
30
|
+
const id = `ptc:${data.subCallId}`;
|
|
31
|
+
if (row.type === "tool/ptc-dispatch-start" && typeof data.name === "string") {
|
|
32
|
+
const args = JSON.stringify(data.arguments);
|
|
33
|
+
if (args === void 0) throw new Error("review-context: incomplete durable PTC action");
|
|
34
|
+
return {
|
|
35
|
+
kind: "start",
|
|
36
|
+
id,
|
|
37
|
+
name: data.name,
|
|
38
|
+
arguments: args
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
if (row.type === "tool/ptc-dispatch") return {
|
|
42
|
+
kind: "end",
|
|
43
|
+
id,
|
|
44
|
+
failed: data.isError !== false || data.error !== void 0
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
/** Rebuild read-only discovery candidates from successful durable activity after resume. */
|
|
48
|
+
function replayedInstructionTargets(events, origin) {
|
|
49
|
+
let cwd = origin;
|
|
50
|
+
const pending = /* @__PURE__ */ new Map();
|
|
51
|
+
const paths = /* @__PURE__ */ new Set();
|
|
52
|
+
for (const raw of events) {
|
|
53
|
+
const event = raw;
|
|
54
|
+
if (event.type === "working-directory/change" && typeof event.data.cwd === "string") {
|
|
55
|
+
cwd = event.data.cwd;
|
|
56
|
+
for (const call of pending.values()) call.directories.add(cwd);
|
|
57
|
+
continue;
|
|
58
|
+
}
|
|
59
|
+
const ptc = ptcFileActivity(event);
|
|
60
|
+
if (event.type === "tool/call" || ptc?.kind === "start") {
|
|
61
|
+
const call = ptc?.kind === "start" ? {
|
|
62
|
+
callId: ptc.id,
|
|
63
|
+
name: ptc.name,
|
|
64
|
+
arguments: ptc.arguments
|
|
65
|
+
} : event.data;
|
|
66
|
+
if (typeof call.callId !== "string" || typeof call.name !== "string" || typeof call.arguments !== "string") throw new Error("review-context: incomplete durable file activity");
|
|
67
|
+
pending.set(call.callId, {
|
|
68
|
+
name: call.name,
|
|
69
|
+
arguments: call.arguments,
|
|
70
|
+
directories: new Set(cwd === void 0 ? [] : [cwd])
|
|
71
|
+
});
|
|
72
|
+
if (pending.size > 512) throw new Error("review-context: durable activity index exceeded");
|
|
73
|
+
continue;
|
|
74
|
+
}
|
|
75
|
+
if (event.type !== "tool/result" && ptc?.kind !== "end") continue;
|
|
76
|
+
const message = event.data.message;
|
|
77
|
+
const id = ptc?.kind === "end" ? ptc.id : message?.source?.callId;
|
|
78
|
+
if (typeof id !== "string") throw new Error("review-context: incomplete durable result");
|
|
79
|
+
const call = pending.get(id);
|
|
80
|
+
pending.delete(id);
|
|
81
|
+
if (call === void 0) continue;
|
|
82
|
+
if (ptc?.kind === "end" ? ptc.failed : event.data.error !== void 0 || toolResultFailed(message ?? {})) continue;
|
|
83
|
+
const path = touchedPathOfToolCall(call.name, call.arguments);
|
|
84
|
+
if (path === void 0) continue;
|
|
85
|
+
if (isAbsolute(path)) paths.add(path);
|
|
86
|
+
else {
|
|
87
|
+
if (call.directories.size === 0) throw new Error("review-context: durable file activity has no cwd");
|
|
88
|
+
for (const directory of call.directories) paths.add(resolve(directory, path));
|
|
89
|
+
}
|
|
90
|
+
if (paths.size > 512) throw new Error("review-context: durable work index exceeded");
|
|
91
|
+
}
|
|
92
|
+
return [...paths];
|
|
93
|
+
}
|
|
94
|
+
/** fs tools whose success touches the file at their `file_path` argument. */
|
|
95
|
+
const FILE_TOUCH_TOOL_NAMES = {
|
|
96
|
+
read: true,
|
|
97
|
+
write: true,
|
|
98
|
+
edit: true
|
|
99
|
+
};
|
|
100
|
+
/** One explicit fs-tool target, shared with live touch capture. */
|
|
101
|
+
function touchedPathOfToolCall(name, argumentsJson) {
|
|
102
|
+
if (FILE_TOUCH_TOOL_NAMES[name] !== true) return void 0;
|
|
103
|
+
let parsed;
|
|
104
|
+
try {
|
|
105
|
+
parsed = JSON.parse(argumentsJson);
|
|
106
|
+
} catch {
|
|
107
|
+
return;
|
|
108
|
+
}
|
|
109
|
+
if (typeof parsed !== "object" || parsed === null || !("file_path" in parsed) || typeof parsed.file_path !== "string") return void 0;
|
|
110
|
+
return parsed.file_path.trim() || void 0;
|
|
111
|
+
}
|
|
112
|
+
//#endregion
|
|
227
113
|
//#region src/compat/instruction-overlap.ts
|
|
228
114
|
/** Recognize files already represented by the native instruction baseline in this step. */
|
|
229
115
|
function nativeInstructionCopies(messages, cwd) {
|
|
@@ -327,12 +213,6 @@ const PLUGIN_SOURCE = "@dsh-electron/dsh-plugin-multi-root-workspace";
|
|
|
327
213
|
const DEFAULT_MAX_BYTES = 65536;
|
|
328
214
|
/** Largest instruction file this row will read; larger files are ignored. */
|
|
329
215
|
const DEFAULT_MAX_SOURCE_BYTES = 32768;
|
|
330
|
-
/** Tools whose SUCCESS makes the directories on the path to the file relevant. */
|
|
331
|
-
const FILE_TOUCH_TOOL_NAMES = {
|
|
332
|
-
read: true,
|
|
333
|
-
write: true,
|
|
334
|
-
edit: true
|
|
335
|
-
};
|
|
336
216
|
/** Cap on unanswered `tool/call` records remembered per session. */
|
|
337
217
|
const MAX_PENDING_CALLS = 128;
|
|
338
218
|
/** Cap on touched paths remembered per session; beyond it, touches are dropped. */
|
|
@@ -362,31 +242,6 @@ function relativeDirectoryOf(root, directory) {
|
|
|
362
242
|
return suffix.length === 0 ? "." : suffix;
|
|
363
243
|
}
|
|
364
244
|
/**
|
|
365
|
-
* The path one RAW tool call touched.
|
|
366
|
-
*
|
|
367
|
-
* `arguments` is the model-produced JSON string, so the path is only known after
|
|
368
|
-
* parsing it; a call that names no `file_path`, or is not one of the tools whose
|
|
369
|
-
* success makes a directory relevant, touched nothing this row cares about.
|
|
370
|
-
* @param name - the tool name the model called.
|
|
371
|
-
* @param argumentsJson - the tool call's raw arguments, exactly as produced.
|
|
372
|
-
* @returns the trimmed absolute-or-relative path, or `undefined`.
|
|
373
|
-
*/
|
|
374
|
-
function touchedPathOfToolCall(name, argumentsJson) {
|
|
375
|
-
if (FILE_TOUCH_TOOL_NAMES[name] !== true) return void 0;
|
|
376
|
-
let parsed;
|
|
377
|
-
try {
|
|
378
|
-
parsed = JSON.parse(argumentsJson);
|
|
379
|
-
} catch {
|
|
380
|
-
return;
|
|
381
|
-
}
|
|
382
|
-
if (typeof parsed !== "object" || parsed === null) return void 0;
|
|
383
|
-
if (!("file_path" in parsed)) return void 0;
|
|
384
|
-
const path = parsed.file_path;
|
|
385
|
-
if (typeof path !== "string") return void 0;
|
|
386
|
-
const trimmed = path.trim();
|
|
387
|
-
return trimmed.length > 0 ? trimmed : void 0;
|
|
388
|
-
}
|
|
389
|
-
/**
|
|
390
245
|
* The directory a touched path's instructions would live in.
|
|
391
246
|
*
|
|
392
247
|
* Tool arguments are the model's raw input, so a relative `file_path` is
|
|
@@ -460,7 +315,9 @@ function apply(ctx, config = {}) {
|
|
|
460
315
|
if (existing !== void 0) return existing;
|
|
461
316
|
const created = {
|
|
462
317
|
scopes: /* @__PURE__ */ new Map(),
|
|
463
|
-
|
|
318
|
+
provenanceRoots: /* @__PURE__ */ new Set(),
|
|
319
|
+
touched: /* @__PURE__ */ new Set(),
|
|
320
|
+
worked: /* @__PURE__ */ new Set()
|
|
464
321
|
};
|
|
465
322
|
states.set(session, created);
|
|
466
323
|
return created;
|
|
@@ -468,36 +325,88 @@ function apply(ctx, config = {}) {
|
|
|
468
325
|
ctx.on("session/event", (session, event) => {
|
|
469
326
|
const pendingCalls = callsBySession.get(session) ?? /* @__PURE__ */ new Map();
|
|
470
327
|
callsBySession.set(session, pendingCalls);
|
|
471
|
-
|
|
328
|
+
const ptc = ptcFileActivity(event);
|
|
329
|
+
if (event.type === "tool/call" || ptc?.kind === "start") {
|
|
472
330
|
if (pendingCalls.size >= MAX_PENDING_CALLS) {
|
|
473
331
|
const oldest = pendingCalls.keys().next();
|
|
474
332
|
if (!oldest.done) pendingCalls.delete(oldest.value);
|
|
475
333
|
}
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
334
|
+
const call = ptc?.kind === "start" ? {
|
|
335
|
+
callId: ptc.id,
|
|
336
|
+
name: ptc.name,
|
|
337
|
+
arguments: ptc.arguments
|
|
338
|
+
} : event.type === "tool/call" ? event.data : void 0;
|
|
339
|
+
if (call !== void 0) pendingCalls.set(call.callId, {
|
|
340
|
+
name: call.name,
|
|
341
|
+
arguments: call.arguments,
|
|
479
342
|
cwd: effectiveDirectory(ctx, session)
|
|
480
343
|
});
|
|
481
344
|
return;
|
|
482
345
|
}
|
|
483
|
-
if (event.type !== "tool/result") return;
|
|
484
|
-
const callId = event.data.message.source.callId;
|
|
346
|
+
if (event.type !== "tool/result" && ptc?.kind !== "end") return;
|
|
347
|
+
const callId = ptc?.kind === "end" ? ptc.id : event.type === "tool/result" ? event.data.message.source.callId : "";
|
|
485
348
|
const call = pendingCalls.get(callId);
|
|
486
349
|
pendingCalls.delete(callId);
|
|
487
350
|
if (call === void 0) return;
|
|
488
|
-
if (event.data.error !== void 0 || toolResultFailed(event.data.message)) return;
|
|
351
|
+
if (ptc?.kind === "end" ? ptc.failed : event.type === "tool/result" && (event.data.error !== void 0 || toolResultFailed(event.data.message))) return;
|
|
489
352
|
const path = call.observedPath ?? touchedPathOfToolCall(call.name, call.arguments);
|
|
490
353
|
if (path === void 0) return;
|
|
491
354
|
const state = stateOf(session);
|
|
355
|
+
const absolute = isAbsolute(path) ? path : call.cwd === void 0 ? void 0 : resolve(call.cwd, path);
|
|
356
|
+
if (absolute !== void 0) {
|
|
357
|
+
if (state.worked.size >= MAX_DELIVERED_SCOPES && !state.worked.has(absolute)) state.overflow = true;
|
|
358
|
+
else state.worked.add(absolute);
|
|
359
|
+
}
|
|
492
360
|
if (state.touched.size >= MAX_TOUCHED_PATHS) return;
|
|
493
361
|
if (isAbsolute(path)) state.touched.add(path);
|
|
494
362
|
else if (call.cwd !== void 0) state.touched.add(resolve(call.cwd, path));
|
|
495
363
|
});
|
|
496
364
|
ctx.inject(["fs"], (scope) => {
|
|
365
|
+
scope.provide("multiRootInstructions", {
|
|
366
|
+
knownRoots(session) {
|
|
367
|
+
return [...states.get(session)?.provenanceRoots ?? []];
|
|
368
|
+
},
|
|
369
|
+
async snapshot(agent, roots, target, signal) {
|
|
370
|
+
signal.throwIfAborted();
|
|
371
|
+
if (roots.length === 0) return [];
|
|
372
|
+
const api = await instructionsApi();
|
|
373
|
+
if (api === void 0) throw new Error("review-context: instruction discovery unavailable");
|
|
374
|
+
const existing = states.get(agent.session);
|
|
375
|
+
if (existing?.overflow) throw new Error("review-context: successful work index exceeded");
|
|
376
|
+
const state = {
|
|
377
|
+
scopes: new Map([...existing?.scopes ?? []].map(([key, value]) => [key, {
|
|
378
|
+
...value,
|
|
379
|
+
digest: void 0
|
|
380
|
+
}])),
|
|
381
|
+
provenanceRoots: new Set(existing?.provenanceRoots),
|
|
382
|
+
touched: /* @__PURE__ */ new Set([...existing?.touched ?? [], ...existing?.worked ?? []]),
|
|
383
|
+
worked: /* @__PURE__ */ new Set()
|
|
384
|
+
};
|
|
385
|
+
for (const path of replayedInstructionTargets(agent.session.snapshotEvents(), agent.session.header.cwd)) state.touched.add(path);
|
|
386
|
+
if (target !== void 0) state.touched.add(target);
|
|
387
|
+
const cwd = effectiveDirectory(scope, agent.session);
|
|
388
|
+
const reviewCwd = cwd === void 0 ? void 0 : canonicalPath(cwd);
|
|
389
|
+
const result = [];
|
|
390
|
+
for (const root of roots) {
|
|
391
|
+
const plan = await planRoot(scope, api, root, config, state, signal, true, reviewCwd);
|
|
392
|
+
for (const { file } of plan.deliveries) result.push({
|
|
393
|
+
root,
|
|
394
|
+
path: file.absolutePath,
|
|
395
|
+
relativeDirectory: relativeDirectoryOf(root, dirname(file.absolutePath)),
|
|
396
|
+
digest: digestOf(file.content),
|
|
397
|
+
text: file.content
|
|
398
|
+
});
|
|
399
|
+
}
|
|
400
|
+
signal.throwIfAborted();
|
|
401
|
+
if (Buffer.byteLength(JSON.stringify(result), "utf8") > maxBytes) throw new Error("review-context: instruction budget exceeded");
|
|
402
|
+
return result;
|
|
403
|
+
}
|
|
404
|
+
});
|
|
497
405
|
scope.on("fs/observed", (target, _observation, actor) => {
|
|
498
406
|
const exec = executions.getStore();
|
|
499
407
|
if (exec?.agent === void 0 || FILE_TOUCH_TOOL_NAMES[exec.name] !== true || actor !== exec) return;
|
|
500
|
-
const
|
|
408
|
+
const calls = callsBySession.get(exec.agent.session);
|
|
409
|
+
const call = calls?.get(exec.callId) ?? calls?.get(`ptc:${exec.callId}`);
|
|
501
410
|
if (call !== void 0) call.observedPath = scope.fs.processPath(target);
|
|
502
411
|
});
|
|
503
412
|
scope.on("agent/pre-step", async ({ agent, messages, signal }, next) => {
|
|
@@ -531,7 +440,9 @@ async function pending(ctx, states, agent, config, maxBytes, signal, messages) {
|
|
|
531
440
|
const session = agent.session;
|
|
532
441
|
const state = states.get(session) ?? {
|
|
533
442
|
scopes: /* @__PURE__ */ new Map(),
|
|
534
|
-
|
|
443
|
+
provenanceRoots: /* @__PURE__ */ new Set(),
|
|
444
|
+
touched: /* @__PURE__ */ new Set(),
|
|
445
|
+
worked: /* @__PURE__ */ new Set()
|
|
535
446
|
};
|
|
536
447
|
states.set(session, state);
|
|
537
448
|
const evaluatedTouches = new Set(state.touched);
|
|
@@ -610,7 +521,10 @@ async function pending(ctx, states, agent, config, maxBytes, signal, messages) {
|
|
|
610
521
|
if (text !== void 0 || liveUpdates.length > 0) {
|
|
611
522
|
for (const root of revoked) for (const [key, entry] of state.scopes) if (entry.root === root) state.scopes.delete(key);
|
|
612
523
|
for (const entry of gone) state.scopes.delete(entry.key);
|
|
613
|
-
for (const entry of liveUpdates)
|
|
524
|
+
for (const entry of liveUpdates) {
|
|
525
|
+
state.scopes.set(entry.key, entry.scope);
|
|
526
|
+
state.provenanceRoots.add(entry.scope.root);
|
|
527
|
+
}
|
|
614
528
|
}
|
|
615
529
|
return message;
|
|
616
530
|
}
|
|
@@ -626,15 +540,19 @@ async function pending(ctx, states, agent, config, maxBytes, signal, messages) {
|
|
|
626
540
|
* of that directory's ancestors up to the root, because discovery reports an
|
|
627
541
|
* intermediate directory's file but only the exact directory's candidates
|
|
628
542
|
* survive the filter below.
|
|
543
|
+
* A strict review can also seed its effective cwd chain without recording a
|
|
544
|
+
* successful touch; ordinary pre-step delivery never supplies that seed.
|
|
629
545
|
* @param ctx - the row's context, for `fs` and the logger.
|
|
630
546
|
* @param api - the adapted upstream instruction surface.
|
|
631
547
|
* @param root - the canonical additional root.
|
|
632
548
|
* @param config - the row's configuration.
|
|
633
549
|
* @param state - the session's delivery state.
|
|
634
550
|
* @param signal - the turn's cancellation signal.
|
|
551
|
+
* @param strict - fail on incomplete review discovery instead of deferring delivery.
|
|
552
|
+
* @param reviewCwd - review-only directory seed; never a successful touch.
|
|
635
553
|
* @returns the files to send and the deliveries to withdraw.
|
|
636
554
|
*/
|
|
637
|
-
async function planRoot(ctx, api, root, config, state, signal) {
|
|
555
|
+
async function planRoot(ctx, api, root, config, state, signal, strict = false, reviewCwd) {
|
|
638
556
|
const delivered = /* @__PURE__ */ new Map();
|
|
639
557
|
for (const [key, entry] of state.scopes) if (entry.root === root) delivered.set(key, entry);
|
|
640
558
|
const dirs = /* @__PURE__ */ new Set([root]);
|
|
@@ -642,8 +560,9 @@ async function planRoot(ctx, api, root, config, state, signal) {
|
|
|
642
560
|
const dir = dirname(entry.path);
|
|
643
561
|
if (dir !== root) dirs.add(dir);
|
|
644
562
|
}
|
|
645
|
-
|
|
646
|
-
|
|
563
|
+
const parents = [...state.touched].map(parentDirectoryOf);
|
|
564
|
+
if (reviewCwd !== void 0) parents.push(reviewCwd);
|
|
565
|
+
for (const parent of parents) {
|
|
647
566
|
if (parent === void 0 || !isCanonicallyUnder(parent, root)) continue;
|
|
648
567
|
let dir = parent;
|
|
649
568
|
for (;;) {
|
|
@@ -659,7 +578,7 @@ async function planRoot(ctx, api, root, config, state, signal) {
|
|
|
659
578
|
signal.throwIfAborted();
|
|
660
579
|
walks.push({
|
|
661
580
|
relativeDirectory: relativeDirectoryOf(root, dir),
|
|
662
|
-
read: await loadDirectory(ctx.fs, api, root, config, signal, dir)
|
|
581
|
+
read: await loadDirectory(ctx.fs, api, root, config, signal, dir, strict)
|
|
663
582
|
});
|
|
664
583
|
}
|
|
665
584
|
walks.sort((left, right) => left.relativeDirectory.split(sep).length - right.relativeDirectory.split(sep).length || (left.relativeDirectory < right.relativeDirectory ? -1 : left.relativeDirectory > right.relativeDirectory ? 1 : 0));
|
|
@@ -678,7 +597,7 @@ async function planRoot(ctx, api, root, config, state, signal) {
|
|
|
678
597
|
const previous = delivered.get(key);
|
|
679
598
|
if (previous !== void 0 && previous.digest === digestOf(file.content)) continue;
|
|
680
599
|
if (previous === void 0 && walk.relativeDirectory !== ".") {
|
|
681
|
-
if (state.scopes.size >= MAX_DELIVERED_SCOPES) {
|
|
600
|
+
if (!strict && state.scopes.size >= MAX_DELIVERED_SCOPES) {
|
|
682
601
|
if (!scopeCapWarned) {
|
|
683
602
|
scopeCapWarned = true;
|
|
684
603
|
ctx.logger.warn("multi-root workspace: additional-root instruction scopes capped at %d", MAX_DELIVERED_SCOPES);
|
|
@@ -708,6 +627,18 @@ async function planRoot(ctx, api, root, config, state, signal) {
|
|
|
708
627
|
gone
|
|
709
628
|
};
|
|
710
629
|
}
|
|
630
|
+
/** Bounded provider read; an over-budget source never becomes a partial constraint. */
|
|
631
|
+
async function readReviewInstruction(fs, target, signal, maxBytes) {
|
|
632
|
+
const chunks = [];
|
|
633
|
+
let bytes = 0;
|
|
634
|
+
for await (const chunk of await fs.streamText(target, signal)) {
|
|
635
|
+
signal.throwIfAborted();
|
|
636
|
+
bytes += Buffer.byteLength(chunk, "utf8");
|
|
637
|
+
if (bytes > maxBytes) throw new Error("review-context: instruction source budget exceeded");
|
|
638
|
+
chunks.push(chunk);
|
|
639
|
+
}
|
|
640
|
+
return chunks.join("");
|
|
641
|
+
}
|
|
711
642
|
/**
|
|
712
643
|
* Walk from `cwd` up to `root` and read the instruction candidates it reports.
|
|
713
644
|
*
|
|
@@ -734,9 +665,21 @@ async function planRoot(ctx, api, root, config, state, signal) {
|
|
|
734
665
|
* @param cwd - the directory the walk starts from; always inside `root`.
|
|
735
666
|
* @returns the directory read.
|
|
736
667
|
*/
|
|
737
|
-
async function loadDirectory(fs, api, root, config, signal, cwd) {
|
|
738
|
-
const
|
|
668
|
+
async function loadDirectory(fs, api, root, config, signal, cwd, strict = false) {
|
|
669
|
+
const configuredSourceBytes = config.maxSourceBytes ?? 32768;
|
|
670
|
+
if (strict && (!Number.isFinite(configuredSourceBytes) || configuredSourceBytes <= 0)) throw new Error("review-context: invalid source budget");
|
|
671
|
+
const maxSourceBytes = strict ? Math.min(configuredSourceBytes, DEFAULT_MAX_BYTES) : configuredSourceBytes;
|
|
739
672
|
let candidates;
|
|
673
|
+
if (strict) for (const name of [...config.instructionFileCandidates ?? ["AGENTS.md", "CLAUDE.md"], ...config.localInstructionFileCandidates ?? ["AGENTS.local.md", "CLAUDE.local.md"]]) {
|
|
674
|
+
if (basename(name) !== name || name === "." || name === "..") throw new Error("review-context: invalid instruction candidate");
|
|
675
|
+
signal.throwIfAborted();
|
|
676
|
+
try {
|
|
677
|
+
await stat(resolve(cwd, name));
|
|
678
|
+
} catch (error) {
|
|
679
|
+
const code = error.code;
|
|
680
|
+
if (code !== "ENOENT" && code !== "ENOTDIR") throw new Error("review-context: instruction probe failed");
|
|
681
|
+
}
|
|
682
|
+
}
|
|
740
683
|
try {
|
|
741
684
|
candidates = await api.discover({
|
|
742
685
|
cwd,
|
|
@@ -745,7 +688,8 @@ async function loadDirectory(fs, api, root, config, signal, cwd) {
|
|
|
745
688
|
...config.instructionFileCandidates === void 0 ? {} : { instructionFileCandidates: config.instructionFileCandidates },
|
|
746
689
|
...config.localInstructionFileCandidates === void 0 ? {} : { localInstructionFileCandidates: config.localInstructionFileCandidates }
|
|
747
690
|
});
|
|
748
|
-
} catch {
|
|
691
|
+
} catch (error) {
|
|
692
|
+
if (strict) throw error;
|
|
749
693
|
return {
|
|
750
694
|
candidates: [],
|
|
751
695
|
files: [],
|
|
@@ -762,15 +706,21 @@ async function loadDirectory(fs, api, root, config, signal, cwd) {
|
|
|
762
706
|
if (!isCanonicallyUnder(path, root)) continue;
|
|
763
707
|
const info = await fs.stat(target, signal);
|
|
764
708
|
if (info === void 0 || info.type !== "file") continue;
|
|
765
|
-
if (info.size !== void 0 && info.size > maxSourceBytes)
|
|
766
|
-
|
|
709
|
+
if (info.size !== void 0 && info.size > maxSourceBytes) {
|
|
710
|
+
if (strict) throw new Error("review-context: instruction source budget exceeded");
|
|
711
|
+
continue;
|
|
712
|
+
}
|
|
713
|
+
const content = strict ? await readReviewInstruction(fs, target, signal, maxSourceBytes) : await fs.readText(target, signal);
|
|
714
|
+
if (strict && Buffer.byteLength(content, "utf8") > maxSourceBytes) throw new Error("review-context: instruction source budget exceeded");
|
|
715
|
+
if (strict && canonicalPath(candidate.absolutePath) !== path) throw new Error("review-context: instruction identity changed");
|
|
767
716
|
if (canonicalPath(candidate.absolutePath) !== path || !isCanonicallyUnder(path, root)) continue;
|
|
768
717
|
files.push({
|
|
769
718
|
...candidate,
|
|
770
719
|
displayPath: candidate.absolutePath,
|
|
771
720
|
content
|
|
772
721
|
});
|
|
773
|
-
} catch {
|
|
722
|
+
} catch (error) {
|
|
723
|
+
if (strict) throw error;
|
|
774
724
|
continue;
|
|
775
725
|
}
|
|
776
726
|
}
|
|
@@ -781,4 +731,4 @@ async function loadDirectory(fs, api, root, config, signal, cwd) {
|
|
|
781
731
|
};
|
|
782
732
|
}
|
|
783
733
|
//#endregion
|
|
784
|
-
export { composeInstructionMessage as a,
|
|
734
|
+
export { composeInstructionMessage as a, apply as i, DEFAULT_MAX_SOURCE_BYTES as n, inject as o, PLUGIN_SOURCE as r, touchedPathOfToolCall as s, DEFAULT_MAX_BYTES as t };
|
package/lib/instructions.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { a as composeInstructionMessage, i as apply, n as DEFAULT_MAX_SOURCE_BYTES, o as inject, r as PLUGIN_SOURCE, s as touchedPathOfToolCall, t as DEFAULT_MAX_BYTES } from "./instructions-
|
|
1
|
+
import { a as composeInstructionMessage, i as apply, n as DEFAULT_MAX_SOURCE_BYTES, o as inject, r as PLUGIN_SOURCE, s as touchedPathOfToolCall, t as DEFAULT_MAX_BYTES } from "./instructions-MePoRigy.js";
|
|
2
2
|
export { DEFAULT_MAX_BYTES, DEFAULT_MAX_SOURCE_BYTES, PLUGIN_SOURCE, apply, composeInstructionMessage, inject, touchedPathOfToolCall };
|