jev-agent-tools 0.1.4 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +70 -1
- package/CONTRIBUTING.md +40 -0
- package/README.md +42 -9
- package/SECURITY.md +27 -0
- package/dist/adapters/analysis-context.js +75 -0
- package/dist/adapters/ask-files.js +189 -0
- package/dist/adapters/ask-proof.js +144 -0
- package/dist/adapters/ask-syntax.js +385 -0
- package/dist/adapters/canonical-path.js +17 -0
- package/dist/adapters/command.js +181 -0
- package/dist/adapters/docs.js +172 -0
- package/dist/adapters/exec.js +207 -0
- package/dist/adapters/files.js +293 -0
- package/dist/adapters/find.js +122 -0
- package/dist/adapters/git-base.js +26 -0
- package/dist/adapters/git-inventory.js +71 -0
- package/dist/adapters/git.js +439 -0
- package/dist/adapters/locate-file.js +159 -0
- package/dist/adapters/output-lines.js +46 -0
- package/dist/adapters/private-storage.js +98 -0
- package/dist/adapters/risk-callers.js +426 -0
- package/dist/adapters/runner-version.js +78 -0
- package/dist/adapters/shell.js +76 -0
- package/dist/adapters/syntax.js +187 -0
- package/dist/adapters/test-inventory.js +131 -0
- package/dist/adapters/usage.js +20 -0
- package/dist/adapters/utf8.js +47 -0
- package/dist/configuration.js +257 -0
- package/dist/constants.js +119 -0
- package/dist/core/ask-closure.js +282 -0
- package/dist/core/ask-proof.js +1 -0
- package/dist/core/ask-references.js +194 -0
- package/dist/core/asks.js +436 -0
- package/dist/core/batches.js +65 -0
- package/dist/core/command-output.js +224 -0
- package/dist/core/diff.js +178 -0
- package/dist/core/docs.js +302 -0
- package/dist/core/find.js +108 -0
- package/dist/core/git.js +1 -0
- package/dist/core/imports.js +550 -0
- package/dist/core/integrity.js +45 -0
- package/dist/core/lexical.js +132 -0
- package/dist/core/locate.js +169 -0
- package/dist/core/output.js +120 -0
- package/dist/core/pointer.js +29 -0
- package/dist/core/risk-callers.js +851 -0
- package/dist/core/runner-version.js +45 -0
- package/dist/core/sections.js +230 -0
- package/dist/core/state.js +44 -0
- package/dist/core/syntax.js +1 -0
- package/dist/core/test-commands.js +334 -0
- package/dist/core/test-coverage.js +74 -0
- package/dist/core/test-discovery.js +1382 -0
- package/dist/core/test-evidence.js +527 -0
- package/dist/core/test-state.js +81 -0
- package/dist/core/truncate.js +12 -0
- package/dist/core/units.js +349 -0
- package/dist/describe.js +23 -0
- package/dist/guide.js +33 -0
- package/dist/host.js +24 -0
- package/dist/jev/client.js +434 -0
- package/dist/jev/pool.js +54 -0
- package/dist/jev/types.js +1 -0
- package/dist/mcp/main.js +124 -0
- package/dist/mcp/protocol.js +187 -0
- package/dist/mcp/tools.js +116 -0
- package/dist/presets/docs.js +62 -0
- package/dist/presets/risk.js +179 -0
- package/dist/presets/spec.js +81 -0
- package/dist/presets/witnesses.js +249 -0
- package/dist/render.js +42 -0
- package/dist/result.js +3 -0
- package/dist/runtime.js +1 -0
- package/dist/session.js +147 -0
- package/dist/texts/ask-files.js +1 -0
- package/dist/texts/ask.js +2 -0
- package/dist/texts/check-diff.js +17 -0
- package/dist/texts/configuration.js +1 -0
- package/dist/texts/find.js +14 -0
- package/dist/texts/guide.js +16 -0
- package/dist/texts/locate.js +10 -0
- package/dist/texts/select-tests.js +2 -0
- package/dist/tools/ask-files.js +217 -0
- package/dist/tools/ask-schema.js +70 -0
- package/dist/tools/ask.js +686 -0
- package/dist/tools/check-diff.js +402 -0
- package/dist/tools/docs-check.js +299 -0
- package/dist/tools/find.js +389 -0
- package/dist/tools/locate.js +303 -0
- package/dist/tools/select-tests.js +567 -0
- package/dist/tools/spec-check.js +166 -0
- package/docs/adr/0001-strict-typescript-pure-core-offline-tests.md +31 -0
- package/docs/adr/0002-one-http-protocol-across-hosts.md +17 -0
- package/docs/adr/0003-explicit-scope-conservative-automation.md +19 -0
- package/docs/adr/0004-compiled-typed-intents.md +19 -0
- package/docs/adr/0005-evidence-construction-before-judgment.md +19 -0
- package/docs/adr/0006-visible-uncertainty-constrained-controls.md +21 -0
- package/docs/adr/0007-bounded-evidence-visible-limits.md +21 -0
- package/docs/adr/0008-static-test-discovery-conservative-plans.md +19 -0
- package/docs/adr/0009-session-cache-requested-model-identity.md +17 -0
- package/docs/adr/0010-mcp-server-thin-host.md +23 -0
- package/docs/agent-instructions.md +91 -0
- package/docs/design.md +3 -3
- package/docs/mcp.md +231 -0
- package/package.json +19 -4
- package/server.json +57 -0
- package/src/adapters/canonical-path.ts +18 -0
- package/src/adapters/command.ts +7 -4
- package/src/adapters/exec.ts +226 -0
- package/src/adapters/private-storage.ts +143 -0
- package/src/adapters/risk-callers.ts +4 -2
- package/src/adapters/shell.ts +97 -0
- package/src/configuration.ts +39 -12
- package/src/constants.ts +11 -0
- package/src/core/command-output.ts +17 -1
- package/src/host.ts +11 -0
- package/src/jev/client.ts +12 -0
- package/src/jev/types.ts +6 -0
- package/src/mcp/main.ts +135 -0
- package/src/mcp/protocol.ts +282 -0
- package/src/mcp/tools.ts +166 -0
- package/src/session.ts +59 -0
- package/src/setup.ts +13 -5
- package/src/tools/ask-files.ts +5 -7
- package/src/tools/ask.ts +26 -22
- package/src/tools/check-diff.ts +8 -5
- package/src/tools/docs-check.ts +1 -0
- package/src/tools/find.ts +5 -2
- package/src/tools/locate.ts +5 -8
- package/src/tools/select-tests.ts +7 -4
- package/src/tools/spec-check.ts +1 -0
package/src/tools/ask.ts
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import { createHash } from "node:crypto";
|
|
2
|
-
import { resolve } from "node:path";
|
|
2
|
+
import { isAbsolute, relative, resolve } from "node:path";
|
|
3
3
|
import type { ToolDefinition } from "@earendil-works/pi-coding-agent";
|
|
4
4
|
import { type Static, Type } from "@sinclair/typebox";
|
|
5
5
|
import { createAnalysisContext } from "../adapters/analysis-context.ts";
|
|
6
6
|
import { collectAskRepository, repositoryPath } from "../adapters/ask-proof.ts";
|
|
7
7
|
import { collectProofSyntax } from "../adapters/ask-syntax.ts";
|
|
8
|
+
import { canonicalPath } from "../adapters/canonical-path.ts";
|
|
8
9
|
import { captureCommand } from "../adapters/command.ts";
|
|
9
10
|
import { collectFiles } from "../adapters/files.ts";
|
|
10
11
|
import { shareGitInventory } from "../adapters/git-inventory.ts";
|
|
@@ -117,6 +118,7 @@ export function createAskTool(dependencies: ToolDependencies) {
|
|
|
117
118
|
};
|
|
118
119
|
}> {
|
|
119
120
|
const client = dependencies.client;
|
|
121
|
+
const cwd = await canonicalPath(ctx.cwd);
|
|
120
122
|
const started = performance.now();
|
|
121
123
|
const exec = shareGitInventory(execute);
|
|
122
124
|
const finish = (
|
|
@@ -159,7 +161,7 @@ export function createAskTool(dependencies: ToolDependencies) {
|
|
|
159
161
|
return textResult("Provide state, command or at least one path.");
|
|
160
162
|
const asks = compileAsks(args.asks, { surface: "ask" });
|
|
161
163
|
if (!asks.ok) return textResult(asks.error);
|
|
162
|
-
const files = await collectFiles(
|
|
164
|
+
const files = await collectFiles(cwd, args.paths ?? [], signal, {
|
|
163
165
|
exec,
|
|
164
166
|
allowEmpty: true,
|
|
165
167
|
skipInvalidUtf8: true,
|
|
@@ -178,12 +180,7 @@ export function createAskTool(dependencies: ToolDependencies) {
|
|
|
178
180
|
fact,
|
|
179
181
|
next: "Provide this file as UTF-8 text if the judgment needs it.",
|
|
180
182
|
}));
|
|
181
|
-
let repository = await collectAskRepository(
|
|
182
|
-
exec,
|
|
183
|
-
ctx.cwd,
|
|
184
|
-
args.base,
|
|
185
|
-
signal,
|
|
186
|
-
);
|
|
183
|
+
let repository = await collectAskRepository(exec, cwd, args.base, signal);
|
|
187
184
|
if (!repository.ok && args.base) return textResult(repository.error);
|
|
188
185
|
if (!repository.ok)
|
|
189
186
|
proofLimitations.push({
|
|
@@ -193,7 +190,7 @@ export function createAskTool(dependencies: ToolDependencies) {
|
|
|
193
190
|
const command = args.command
|
|
194
191
|
? await captureCommand(
|
|
195
192
|
exec,
|
|
196
|
-
repository.ok ? repository.root :
|
|
193
|
+
repository.ok ? repository.root : cwd,
|
|
197
194
|
args.command,
|
|
198
195
|
args.timeout_s,
|
|
199
196
|
signal,
|
|
@@ -201,12 +198,7 @@ export function createAskTool(dependencies: ToolDependencies) {
|
|
|
201
198
|
: undefined;
|
|
202
199
|
if (command && !command.ok) return textResult(command.error);
|
|
203
200
|
if (command?.ok) {
|
|
204
|
-
repository = await collectAskRepository(
|
|
205
|
-
exec,
|
|
206
|
-
ctx.cwd,
|
|
207
|
-
args.base,
|
|
208
|
-
signal,
|
|
209
|
-
);
|
|
201
|
+
repository = await collectAskRepository(exec, cwd, args.base, signal);
|
|
210
202
|
if (!repository.ok && args.base) return textResult(repository.error);
|
|
211
203
|
}
|
|
212
204
|
const initialState = assembleState(args.state, files.files);
|
|
@@ -220,6 +212,17 @@ export function createAskTool(dependencies: ToolDependencies) {
|
|
|
220
212
|
for (const target of command.targets) {
|
|
221
213
|
if (target.path.startsWith(`${repository.root}/`))
|
|
222
214
|
target.path = target.path.slice(repository.root.length + 1);
|
|
215
|
+
else if (isAbsolute(target.path)) {
|
|
216
|
+
// Windows reports C:/... or short 8.3 forms; compare canonically.
|
|
217
|
+
const local = relative(
|
|
218
|
+
repository.root,
|
|
219
|
+
await canonicalPath(target.path),
|
|
220
|
+
)
|
|
221
|
+
.split("\\")
|
|
222
|
+
.join("/");
|
|
223
|
+
if (local && !local.startsWith("../") && !isAbsolute(local))
|
|
224
|
+
target.path = local;
|
|
225
|
+
}
|
|
223
226
|
let matches = [...repository.known].filter(
|
|
224
227
|
(path) => path === target.path || path.endsWith(`/${target.path}`),
|
|
225
228
|
);
|
|
@@ -252,7 +255,7 @@ export function createAskTool(dependencies: ToolDependencies) {
|
|
|
252
255
|
}
|
|
253
256
|
const path = matches[0];
|
|
254
257
|
if (!path) continue;
|
|
255
|
-
const local = repositoryPath(
|
|
258
|
+
const local = repositoryPath(cwd, repository.root, path);
|
|
256
259
|
if (!Object.hasOwn(files.files, local)) {
|
|
257
260
|
const added = await collectFiles(repository.root, [path], signal, {
|
|
258
261
|
exec,
|
|
@@ -348,7 +351,7 @@ export function createAskTool(dependencies: ToolDependencies) {
|
|
|
348
351
|
if (repository?.ok) {
|
|
349
352
|
const canonical = Object.fromEntries(
|
|
350
353
|
Object.entries(files.files).map(([path, text]) => [
|
|
351
|
-
repositoryPath(repository.root,
|
|
354
|
+
repositoryPath(repository.root, cwd, path),
|
|
352
355
|
text,
|
|
353
356
|
]),
|
|
354
357
|
);
|
|
@@ -370,7 +373,7 @@ export function createAskTool(dependencies: ToolDependencies) {
|
|
|
370
373
|
const canonicalPath =
|
|
371
374
|
references.additions.find(
|
|
372
375
|
(addition) => addition.reference === path,
|
|
373
|
-
)?.path ?? repositoryPath(repository.root,
|
|
376
|
+
)?.path ?? repositoryPath(repository.root, cwd, path);
|
|
374
377
|
return [path, before[canonicalPath] ?? null];
|
|
375
378
|
}),
|
|
376
379
|
);
|
|
@@ -512,11 +515,11 @@ export function createAskTool(dependencies: ToolDependencies) {
|
|
|
512
515
|
const identities = files.identities.map((file) => {
|
|
513
516
|
const content = inserted[file.requestedPath];
|
|
514
517
|
const insertedPath = Object.keys(inserted).find(
|
|
515
|
-
(path) => resolve(
|
|
518
|
+
(path) => resolve(cwd, path) === file.resolvedPath,
|
|
516
519
|
);
|
|
517
520
|
return {
|
|
518
521
|
...file,
|
|
519
|
-
insertedPath: insertedPath ? resolve(
|
|
522
|
+
insertedPath: insertedPath ? resolve(cwd, insertedPath) : "",
|
|
520
523
|
content: typeof content === "string" ? content : "",
|
|
521
524
|
insertedSha256: createHash("sha256")
|
|
522
525
|
.update(typeof content === "string" ? content : "")
|
|
@@ -544,6 +547,7 @@ export function createAskTool(dependencies: ToolDependencies) {
|
|
|
544
547
|
const options = {
|
|
545
548
|
signal,
|
|
546
549
|
cache: !args.command,
|
|
550
|
+
...runtime.session.requestGate(),
|
|
547
551
|
beforeRequest: (questionCount: number) => {
|
|
548
552
|
if (args.max_calls !== undefined && sent >= args.max_calls) {
|
|
549
553
|
refusal = {
|
|
@@ -787,14 +791,14 @@ export function createAskTool(dependencies: ToolDependencies) {
|
|
|
787
791
|
const selectedPath = repository?.ok
|
|
788
792
|
? (references.additions.find(
|
|
789
793
|
(addition) => addition.reference === selected,
|
|
790
|
-
)?.path ?? repositoryPath(repository.root,
|
|
794
|
+
)?.path ?? repositoryPath(repository.root, cwd, selected))
|
|
791
795
|
: selected;
|
|
792
796
|
const retained = (path: string) => {
|
|
793
797
|
if (!repository?.ok) return path !== selected;
|
|
794
798
|
return (
|
|
795
799
|
(references.additions.find(
|
|
796
800
|
(addition) => addition.reference === path,
|
|
797
|
-
)?.path ?? repositoryPath(repository.root,
|
|
801
|
+
)?.path ?? repositoryPath(repository.root, cwd, path)) !==
|
|
798
802
|
selectedPath
|
|
799
803
|
);
|
|
800
804
|
};
|
package/src/tools/check-diff.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { createHash } from "node:crypto";
|
|
2
2
|
import { type Static, Type } from "@sinclair/typebox";
|
|
3
3
|
import { createAnalysisContext } from "../adapters/analysis-context.ts";
|
|
4
|
+
import { canonicalPath } from "../adapters/canonical-path.ts";
|
|
4
5
|
import { collectUnits } from "../adapters/git.ts";
|
|
5
6
|
import { resolveBase } from "../adapters/git-base.ts";
|
|
6
7
|
import { shareGitInventory } from "../adapters/git-inventory.ts";
|
|
@@ -107,19 +108,20 @@ export function createCheckDiffTool(dependencies: ToolDependencies) {
|
|
|
107
108
|
ctx: { cwd: string } & GuideContext,
|
|
108
109
|
) {
|
|
109
110
|
const client = dependencies.client;
|
|
111
|
+
const cwd = await canonicalPath(ctx.cwd);
|
|
110
112
|
const exec = shareGitInventory(execute);
|
|
111
113
|
if (args.check === "docs" || args.check === "spec") {
|
|
112
114
|
const deps = { client, host, runtime, exec };
|
|
113
115
|
const result =
|
|
114
116
|
args.check === "docs"
|
|
115
117
|
? await runDocsCheck(deps, {
|
|
116
|
-
cwd:
|
|
118
|
+
cwd: cwd,
|
|
117
119
|
base: args.base,
|
|
118
120
|
signal,
|
|
119
121
|
maxCalls: args.max_calls,
|
|
120
122
|
})
|
|
121
123
|
: await runSpecCheck(deps, {
|
|
122
|
-
cwd:
|
|
124
|
+
cwd: cwd,
|
|
123
125
|
base: args.base,
|
|
124
126
|
specPath: args.spec_path,
|
|
125
127
|
signal,
|
|
@@ -223,14 +225,14 @@ export function createCheckDiffTool(dependencies: ToolDependencies) {
|
|
|
223
225
|
};
|
|
224
226
|
};
|
|
225
227
|
if (!client) return finish(NOT_CONFIGURED);
|
|
226
|
-
const comparison = await resolveBase(exec,
|
|
228
|
+
const comparison = await resolveBase(exec, cwd, args.base, signal);
|
|
227
229
|
if (!comparison.ok) return finish(comparison.error);
|
|
228
230
|
const base = comparison.base;
|
|
229
231
|
const analysis = await createAnalysisContext();
|
|
230
232
|
const collected = await collectUnits(
|
|
231
233
|
exec,
|
|
232
234
|
{
|
|
233
|
-
cwd:
|
|
235
|
+
cwd: cwd,
|
|
234
236
|
base,
|
|
235
237
|
signal,
|
|
236
238
|
},
|
|
@@ -271,6 +273,7 @@ export function createCheckDiffTool(dependencies: ToolDependencies) {
|
|
|
271
273
|
let reservedMatrixCalls = batches.batches.length;
|
|
272
274
|
const optionsFor = (matrixRequest = false): JudgmentOptions => ({
|
|
273
275
|
signal,
|
|
276
|
+
...runtime.session.requestGate(),
|
|
274
277
|
beforeRequest(questionCount) {
|
|
275
278
|
if (matrixRequest && reservedMatrixCalls > 0) reservedMatrixCalls--;
|
|
276
279
|
const limit =
|
|
@@ -312,7 +315,7 @@ export function createCheckDiffTool(dependencies: ToolDependencies) {
|
|
|
312
315
|
)
|
|
313
316
|
? await collectRiskCallers(
|
|
314
317
|
exec,
|
|
315
|
-
{ cwd:
|
|
318
|
+
{ cwd: cwd, base, signal },
|
|
316
319
|
collected.units,
|
|
317
320
|
collected.files,
|
|
318
321
|
analysis.parser,
|
package/src/tools/docs-check.ts
CHANGED
package/src/tools/find.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { type Static, Type } from "@sinclair/typebox";
|
|
2
|
+
import { canonicalPath } from "../adapters/canonical-path.ts";
|
|
2
3
|
import { collectSearchExcerpts } from "../adapters/files.ts";
|
|
3
4
|
import { prefilter } from "../adapters/find.ts";
|
|
4
5
|
import { shareGitInventory } from "../adapters/git-inventory.ts";
|
|
@@ -74,6 +75,7 @@ export function createFindFilesTool(dependencies: ToolDependencies) {
|
|
|
74
75
|
ctx: { cwd: string } & GuideContext,
|
|
75
76
|
) {
|
|
76
77
|
const client = dependencies.client;
|
|
78
|
+
const cwd = await canonicalPath(ctx.cwd);
|
|
77
79
|
const started = performance.now();
|
|
78
80
|
const exec = shareGitInventory(execute);
|
|
79
81
|
const totals = {
|
|
@@ -130,7 +132,7 @@ export function createFindFilesTool(dependencies: ToolDependencies) {
|
|
|
130
132
|
: C.FIND_FILES_READ;
|
|
131
133
|
const candidates = await prefilter(
|
|
132
134
|
exec,
|
|
133
|
-
|
|
135
|
+
cwd,
|
|
134
136
|
keywords,
|
|
135
137
|
candidateLimit,
|
|
136
138
|
args.scope,
|
|
@@ -190,6 +192,7 @@ export function createFindFilesTool(dependencies: ToolDependencies) {
|
|
|
190
192
|
): Promise<Judgment> => {
|
|
191
193
|
const result = await client.judge(state, questions, {
|
|
192
194
|
signal,
|
|
195
|
+
...runtime.session.requestGate(),
|
|
193
196
|
beforeRequest: (count) => {
|
|
194
197
|
if (args.max_calls !== undefined && sent >= args.max_calls) {
|
|
195
198
|
budget = {
|
|
@@ -308,7 +311,7 @@ export function createFindFilesTool(dependencies: ToolDependencies) {
|
|
|
308
311
|
const contentResults = await Promise.all(
|
|
309
312
|
contentBatches.map(async (paths) => {
|
|
310
313
|
const read = await collectSearchExcerpts(
|
|
311
|
-
|
|
314
|
+
cwd,
|
|
312
315
|
paths,
|
|
313
316
|
keywords,
|
|
314
317
|
signal,
|
package/src/tools/locate.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { ToolDefinition } from "@earendil-works/pi-coding-agent";
|
|
2
2
|
import { type Static, Type } from "@sinclair/typebox";
|
|
3
|
+
import { canonicalPath } from "../adapters/canonical-path.ts";
|
|
3
4
|
import { shareGitInventory } from "../adapters/git-inventory.ts";
|
|
4
5
|
import { readLocateFile, scanRange } from "../adapters/locate-file.ts";
|
|
5
6
|
import { loadSyntaxParser } from "../adapters/syntax.ts";
|
|
@@ -74,6 +75,7 @@ export function createLocateTool(
|
|
|
74
75
|
ctx: { cwd: string } & GuideContext,
|
|
75
76
|
) {
|
|
76
77
|
const client = dependencies.client;
|
|
78
|
+
const cwd = await canonicalPath(ctx.cwd);
|
|
77
79
|
const started = performance.now();
|
|
78
80
|
const exec = shareGitInventory(execute);
|
|
79
81
|
const results: Judgment[] = [];
|
|
@@ -118,7 +120,7 @@ export function createLocateTool(
|
|
|
118
120
|
),
|
|
119
121
|
};
|
|
120
122
|
};
|
|
121
|
-
const file = await readLocateFile(
|
|
123
|
+
const file = await readLocateFile(cwd, args.path, signal, exec);
|
|
122
124
|
if (!file.ok) return finish({ refusal: file.error });
|
|
123
125
|
if (file.bytes < LOCATE_MIN_KB * 1000)
|
|
124
126
|
return finish({
|
|
@@ -182,6 +184,7 @@ export function createLocateTool(
|
|
|
182
184
|
},
|
|
183
185
|
{
|
|
184
186
|
signal,
|
|
187
|
+
...runtime.session.requestGate(),
|
|
185
188
|
beforeRequest: (n) => runtime.session.admit(n),
|
|
186
189
|
onUsage: (usage) => runtime.session.recordUsage(usage),
|
|
187
190
|
},
|
|
@@ -270,13 +273,7 @@ export function createLocateTool(
|
|
|
270
273
|
});
|
|
271
274
|
}
|
|
272
275
|
if (file.kind === "outline") {
|
|
273
|
-
const selected = await scanRange(
|
|
274
|
-
ctx.cwd,
|
|
275
|
-
args.path,
|
|
276
|
-
block,
|
|
277
|
-
signal,
|
|
278
|
-
exec,
|
|
279
|
-
);
|
|
276
|
+
const selected = await scanRange(cwd, args.path, block, signal, exec);
|
|
280
277
|
if (!selected.ok) return finish({ refusal: selected.error });
|
|
281
278
|
const lines = selected.text.split("\n");
|
|
282
279
|
sections = sections
|
|
@@ -2,6 +2,7 @@ import { matchesGlob, relative, resolve } from "node:path";
|
|
|
2
2
|
import type { ToolDefinition } from "@earendil-works/pi-coding-agent";
|
|
3
3
|
import { type Static, Type } from "@sinclair/typebox";
|
|
4
4
|
import { createAnalysisContext } from "../adapters/analysis-context.ts";
|
|
5
|
+
import { canonicalPath } from "../adapters/canonical-path.ts";
|
|
5
6
|
import { collectUnits } from "../adapters/git.ts";
|
|
6
7
|
import { resolveBase } from "../adapters/git-base.ts";
|
|
7
8
|
import { shareGitInventory } from "../adapters/git-inventory.ts";
|
|
@@ -125,6 +126,7 @@ export function createSelectTestsTool(dependencies: ToolDependencies) {
|
|
|
125
126
|
ctx: { cwd: string } & GuideContext,
|
|
126
127
|
) {
|
|
127
128
|
const client = dependencies.client;
|
|
129
|
+
const cwd = await canonicalPath(ctx.cwd);
|
|
128
130
|
const started = performance.now();
|
|
129
131
|
const exec = shareGitInventory(execute);
|
|
130
132
|
const totals = {
|
|
@@ -168,14 +170,14 @@ export function createSelectTestsTool(dependencies: ToolDependencies) {
|
|
|
168
170
|
...hostUsage(host.isOmp, costKnown ? totals.usage : undefined),
|
|
169
171
|
};
|
|
170
172
|
};
|
|
171
|
-
const comparison = await resolveBase(exec,
|
|
173
|
+
const comparison = await resolveBase(exec, cwd, args.base, signal);
|
|
172
174
|
if (!comparison.ok) return finish({ refusal: comparison.error });
|
|
173
175
|
const analysis = await createAnalysisContext();
|
|
174
176
|
const [inventory, diff] = await Promise.all([
|
|
175
|
-
collectTestInventory(exec,
|
|
177
|
+
collectTestInventory(exec, cwd, signal),
|
|
176
178
|
collectUnits(
|
|
177
179
|
exec,
|
|
178
|
-
{ cwd:
|
|
180
|
+
{ cwd: cwd, base: comparison.base, signal },
|
|
179
181
|
analysis.parser,
|
|
180
182
|
),
|
|
181
183
|
]);
|
|
@@ -387,6 +389,7 @@ export function createSelectTestsTool(dependencies: ToolDependencies) {
|
|
|
387
389
|
const result = await client.judge(state, questions, {
|
|
388
390
|
signal,
|
|
389
391
|
witnesses: witnessIds,
|
|
392
|
+
...runtime.session.requestGate(),
|
|
390
393
|
beforeRequest: (questionCount) => {
|
|
391
394
|
if (args.max_calls !== undefined && sent >= args.max_calls) {
|
|
392
395
|
budget = {
|
|
@@ -735,7 +738,7 @@ export function createSelectTestsTool(dependencies: ToolDependencies) {
|
|
|
735
738
|
lines: commands.commands.map((command) => ({
|
|
736
739
|
type: "command" as const,
|
|
737
740
|
...command,
|
|
738
|
-
cwd: relative(
|
|
741
|
+
cwd: relative(cwd, resolve(inventory.cwd, command.cwd)) || ".",
|
|
739
742
|
})),
|
|
740
743
|
});
|
|
741
744
|
},
|
package/src/tools/spec-check.ts
CHANGED
|
@@ -175,6 +175,7 @@ export async function runSpecCheck(
|
|
|
175
175
|
if (!units.length) return finish();
|
|
176
176
|
const judgment = await deps.client.judge(prepared.state, prepared.questions, {
|
|
177
177
|
signal: input.signal,
|
|
178
|
+
...deps.runtime.session.requestGate(),
|
|
178
179
|
beforeRequest(questionCount) {
|
|
179
180
|
if (input.maxCalls !== undefined && sent >= input.maxCalls) {
|
|
180
181
|
budget = {
|