@hachej/boring-agent 0.1.80 → 0.1.82
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/{chunk-N4ES6PVX.js → chunk-5NAN3TAR.js} +9 -2
- package/dist/{chunk-URRIDA6O.js → chunk-7V3E6KHX.js} +160 -109
- package/dist/{chunk-UJQXCOHR.js → chunk-DC3S7SZG.js} +1 -1
- package/dist/{chunk-CCNXYCD5.js → chunk-PG2WOJ22.js} +8 -0
- package/dist/{chunk-BNZIE26N.js → chunk-TNN3LPXE.js} +1 -1
- package/dist/{chunk-CUF7ELFO.js → chunk-WODTQBXR.js} +86 -73
- package/dist/core/index.d.ts +3 -3
- package/dist/core/index.js +2 -2
- package/dist/{createHarness-EEA63XRC.js → createHarness-TGBJZISM.js} +2 -2
- package/dist/front/index.d.ts +1 -1
- package/dist/front/index.js +2 -2
- package/dist/front/styles.css +21 -0
- package/dist/{harness-BZW5Jiy3.d.ts → harness-C53mjCcq.d.ts} +1 -1
- package/dist/piChatEvent-3pFPXYPx.d.ts +367 -0
- package/dist/server/index.d.ts +13 -5
- package/dist/server/index.js +8 -6
- package/dist/server/worker/index.js +6 -6
- package/dist/shared/index.d.ts +282 -25
- package/dist/shared/index.js +159 -3
- package/dist/{workspaceAgentDispatcher-Wi6NIh2G.d.ts → workspaceAgentDispatcher-p4tlVvbM.d.ts} +25 -23
- package/docs/ERROR_CODES.md +1 -0
- package/package.json +2 -2
- package/dist/piChatEvent-CpoTZau1.d.ts +0 -358
|
@@ -3,16 +3,18 @@ import {
|
|
|
3
3
|
AgentDeploymentValidationError,
|
|
4
4
|
OpaqueRefSchema,
|
|
5
5
|
Sha256DigestSchema,
|
|
6
|
+
canonicalStringify,
|
|
6
7
|
createAgentAssetDigest,
|
|
7
8
|
createAgentDefinitionDigest,
|
|
8
9
|
createAgentDeploymentDigest,
|
|
10
|
+
sha256Bytes,
|
|
9
11
|
validateAgentDefinition,
|
|
10
12
|
validateAgentDeployment,
|
|
11
13
|
validateTool
|
|
12
|
-
} from "./chunk-
|
|
14
|
+
} from "./chunk-WODTQBXR.js";
|
|
13
15
|
import {
|
|
14
16
|
createAgentRuntimeBridge
|
|
15
|
-
} from "./chunk-
|
|
17
|
+
} from "./chunk-TNN3LPXE.js";
|
|
16
18
|
import {
|
|
17
19
|
sessionStreamPath
|
|
18
20
|
} from "./chunk-WSQ5QNIY.js";
|
|
@@ -27,7 +29,7 @@ import {
|
|
|
27
29
|
StopReceiptSchema,
|
|
28
30
|
extractToolUiMetadata,
|
|
29
31
|
sanitizeToolUiMetadata2 as sanitizeToolUiMetadata
|
|
30
|
-
} from "./chunk-
|
|
32
|
+
} from "./chunk-DC3S7SZG.js";
|
|
31
33
|
import {
|
|
32
34
|
createLogger,
|
|
33
35
|
createPiCodingAgentHarness,
|
|
@@ -38,7 +40,7 @@ import {
|
|
|
38
40
|
registerConfiguredModelProviders,
|
|
39
41
|
setEnvDefault,
|
|
40
42
|
withPiHarnessDefaults
|
|
41
|
-
} from "./chunk-
|
|
43
|
+
} from "./chunk-5NAN3TAR.js";
|
|
42
44
|
import {
|
|
43
45
|
safeCapture
|
|
44
46
|
} from "./chunk-AQBXNPMD.js";
|
|
@@ -46,7 +48,7 @@ import {
|
|
|
46
48
|
AgentDefinitionErrorCode,
|
|
47
49
|
AgentDeploymentErrorCode,
|
|
48
50
|
ErrorCode
|
|
49
|
-
} from "./chunk-
|
|
51
|
+
} from "./chunk-PG2WOJ22.js";
|
|
50
52
|
|
|
51
53
|
// src/server/sandbox/direct/createDirectSandbox.ts
|
|
52
54
|
import { spawn } from "child_process";
|
|
@@ -186,7 +188,7 @@ function createDirectSandbox(opts = {}) {
|
|
|
186
188
|
const maxOutputBytes = opts2?.maxOutputBytes ?? DEFAULT_MAX_OUTPUT_BYTES;
|
|
187
189
|
const workspaceRoot = runtimeContext.runtimeCwd;
|
|
188
190
|
const cwd = opts2?.cwd ?? workspaceRoot;
|
|
189
|
-
return await new Promise((
|
|
191
|
+
return await new Promise((resolve13, reject) => {
|
|
190
192
|
const child = spawn(cmd, {
|
|
191
193
|
cwd,
|
|
192
194
|
env: withWorkspacePythonEnv({ workspaceRoot, env: opts2?.env, preserveHostHome: true }),
|
|
@@ -215,7 +217,7 @@ function createDirectSandbox(opts = {}) {
|
|
|
215
217
|
if (settled) return;
|
|
216
218
|
settled = true;
|
|
217
219
|
cleanup();
|
|
218
|
-
|
|
220
|
+
resolve13({
|
|
219
221
|
stdout: new Uint8Array(Buffer.concat(stdoutChunks)),
|
|
220
222
|
stderr: new Uint8Array(Buffer.concat(stderrChunks)),
|
|
221
223
|
exitCode: typeof exitCode === "number" ? exitCode : timedOut ? 124 : 1,
|
|
@@ -564,9 +566,9 @@ function createNodeWatcher(root) {
|
|
|
564
566
|
}
|
|
565
567
|
startFsw();
|
|
566
568
|
if (fsw) {
|
|
567
|
-
await new Promise((
|
|
568
|
-
fsw.once("ready",
|
|
569
|
-
fsw.once("error", () =>
|
|
569
|
+
await new Promise((resolve13) => {
|
|
570
|
+
fsw.once("ready", resolve13);
|
|
571
|
+
fsw.once("error", () => resolve13());
|
|
570
572
|
});
|
|
571
573
|
}
|
|
572
574
|
if (closed) return { ok: false, reason: "closed" };
|
|
@@ -975,7 +977,7 @@ function createBwrapSandbox(opts = {}) {
|
|
|
975
977
|
...withSandboxCwd(baseArgs, sandboxCwd),
|
|
976
978
|
...buildCommandArgs(cmd, sandboxOptions.resourceLimits)
|
|
977
979
|
];
|
|
978
|
-
return await new Promise((
|
|
980
|
+
return await new Promise((resolve13, reject) => {
|
|
979
981
|
const child = spawn2("bwrap", args, {
|
|
980
982
|
env: {
|
|
981
983
|
...withWorkspacePythonEnv({ workspaceRoot, env: opts2?.env, sandboxRoot: SANDBOX_HOME2 }),
|
|
@@ -1005,7 +1007,7 @@ function createBwrapSandbox(opts = {}) {
|
|
|
1005
1007
|
if (settled) return;
|
|
1006
1008
|
settled = true;
|
|
1007
1009
|
cleanup();
|
|
1008
|
-
|
|
1010
|
+
resolve13({
|
|
1009
1011
|
stdout: new Uint8Array(Buffer.concat(stdoutChunks)),
|
|
1010
1012
|
stderr: new Uint8Array(Buffer.concat(stderrChunks)),
|
|
1011
1013
|
exitCode: typeof exitCode === "number" ? exitCode : timedOut ? 124 : 1,
|
|
@@ -2295,7 +2297,8 @@ function createRemoteWorkerModeAdapter(opts = {}) {
|
|
|
2295
2297
|
}
|
|
2296
2298
|
|
|
2297
2299
|
// src/server/http/routes/file.ts
|
|
2298
|
-
import { dirname as dirname5, extname as extname2, relative as
|
|
2300
|
+
import { dirname as dirname5, extname as extname2, relative as relative5 } from "path/posix";
|
|
2301
|
+
import { getAgentDir } from "@mariozechner/pi-coding-agent";
|
|
2299
2302
|
|
|
2300
2303
|
// src/server/http/middleware.ts
|
|
2301
2304
|
var ERROR_CODE_AUTH_REQUIRED = "auth_required";
|
|
@@ -2568,13 +2571,33 @@ function buildFileRecordsResult(args) {
|
|
|
2568
2571
|
|
|
2569
2572
|
// src/server/http/readonlySkillFiles.ts
|
|
2570
2573
|
import { readFile as readFile4, stat as stat4 } from "fs/promises";
|
|
2574
|
+
import { isAbsolute as isAbsolute4, relative as relative4, resolve as resolve5 } from "path";
|
|
2571
2575
|
function isReadonlySkillFilePath(path4) {
|
|
2572
2576
|
if (!path4.startsWith("/")) return false;
|
|
2573
2577
|
if (path4.includes("\0")) return false;
|
|
2574
2578
|
if (!path4.endsWith("/SKILL.md")) return false;
|
|
2579
|
+
if (path4.split("/").some((segment) => segment === "..")) return false;
|
|
2575
2580
|
return path4.includes("/.pi/agent/") && path4.includes("/skills/");
|
|
2576
2581
|
}
|
|
2577
|
-
|
|
2582
|
+
function isLexicallyInside(root, resolvedPath) {
|
|
2583
|
+
if (!root) return false;
|
|
2584
|
+
const rel = relative4(resolve5(root), resolvedPath);
|
|
2585
|
+
return !rel.startsWith("..") && !isAbsolute4(rel);
|
|
2586
|
+
}
|
|
2587
|
+
async function assertReadonlySkillFileConfined(path4, allowedRoots) {
|
|
2588
|
+
const resolved = resolve5(path4);
|
|
2589
|
+
const lexicalRoot = allowedRoots.find((root) => isLexicallyInside(root, resolved));
|
|
2590
|
+
if (!lexicalRoot) {
|
|
2591
|
+
throw Object.assign(new Error("read-only skill file escapes allowed roots"), {
|
|
2592
|
+
statusCode: 403,
|
|
2593
|
+
reason: "path-escape",
|
|
2594
|
+
requestedPath: path4
|
|
2595
|
+
});
|
|
2596
|
+
}
|
|
2597
|
+
await assertRealPathWithinWorkspace(lexicalRoot, resolved);
|
|
2598
|
+
}
|
|
2599
|
+
async function readReadonlySkillFile(path4, allowedRoots) {
|
|
2600
|
+
await assertReadonlySkillFileConfined(path4, allowedRoots);
|
|
2578
2601
|
const [content, fsStat] = await Promise.all([
|
|
2579
2602
|
readFile4(path4, "utf-8"),
|
|
2580
2603
|
stat4(path4)
|
|
@@ -2588,7 +2611,8 @@ async function readReadonlySkillFile(path4) {
|
|
|
2588
2611
|
}
|
|
2589
2612
|
};
|
|
2590
2613
|
}
|
|
2591
|
-
async function statReadonlySkillFile(path4) {
|
|
2614
|
+
async function statReadonlySkillFile(path4, allowedRoots) {
|
|
2615
|
+
await assertReadonlySkillFileConfined(path4, allowedRoots);
|
|
2592
2616
|
const fsStat = await stat4(path4);
|
|
2593
2617
|
return {
|
|
2594
2618
|
kind: fsStat.isDirectory() ? "directory" : "file",
|
|
@@ -2681,6 +2705,9 @@ function classifyError(err, reply, subject) {
|
|
|
2681
2705
|
function requestedFilesystem(value) {
|
|
2682
2706
|
return typeof value === "string" && value.length > 0 ? value : USER_FILESYSTEM_ID;
|
|
2683
2707
|
}
|
|
2708
|
+
function readonlySkillRoots(workspace) {
|
|
2709
|
+
return [workspace.root, getAgentDir()];
|
|
2710
|
+
}
|
|
2684
2711
|
function sendNotFoundOrDenied(reply) {
|
|
2685
2712
|
return reply.code(404).send({
|
|
2686
2713
|
error: { code: ERROR_CODE_NOT_FOUND_OR_DENIED, message: "not found or denied" }
|
|
@@ -2752,7 +2779,7 @@ function basenameForUpload(filename) {
|
|
|
2752
2779
|
function markdownUrlFor(sourcePath, assetPath) {
|
|
2753
2780
|
if (!sourcePath) return assetPath;
|
|
2754
2781
|
const fromDir = dirname5(sourcePath.replace(/\\/g, "/"));
|
|
2755
|
-
const rel =
|
|
2782
|
+
const rel = relative5(fromDir === "." ? "" : fromDir, assetPath);
|
|
2756
2783
|
return rel && !rel.startsWith(".") ? rel : rel || assetPath;
|
|
2757
2784
|
}
|
|
2758
2785
|
function contentTypeForPath(path4) {
|
|
@@ -2905,8 +2932,9 @@ function fileRoutes(app, opts, done) {
|
|
|
2905
2932
|
}
|
|
2906
2933
|
}
|
|
2907
2934
|
try {
|
|
2935
|
+
const workspace = await resolveWorkspace(request);
|
|
2908
2936
|
if (isReadonlySkillFilePath(path4)) {
|
|
2909
|
-
const { content: content2, stat: stat14 } = await readReadonlySkillFile(path4);
|
|
2937
|
+
const { content: content2, stat: stat14 } = await readReadonlySkillFile(path4, readonlySkillRoots(workspace));
|
|
2910
2938
|
if (stat14.kind !== "file") {
|
|
2911
2939
|
return reply.code(400).send({
|
|
2912
2940
|
error: { code: ERROR_CODE_VALIDATION_ERROR, message: "path is not a file", field: "path" }
|
|
@@ -2914,7 +2942,6 @@ function fileRoutes(app, opts, done) {
|
|
|
2914
2942
|
}
|
|
2915
2943
|
return { content: content2, mtimeMs: stat14.mtimeMs };
|
|
2916
2944
|
}
|
|
2917
|
-
const workspace = await resolveWorkspace(request);
|
|
2918
2945
|
if (workspace.readFileWithStat) {
|
|
2919
2946
|
const { content: content2, stat: stat14 } = await workspace.readFileWithStat(path4);
|
|
2920
2947
|
return { content: content2, mtimeMs: stat14.kind === "file" ? stat14.mtimeMs : void 0, access: "readwrite" };
|
|
@@ -3184,10 +3211,10 @@ function fileRoutes(app, opts, done) {
|
|
|
3184
3211
|
}
|
|
3185
3212
|
}
|
|
3186
3213
|
try {
|
|
3214
|
+
const workspace = await resolveWorkspace(request);
|
|
3187
3215
|
if (isReadonlySkillFilePath(path4)) {
|
|
3188
|
-
return await statReadonlySkillFile(path4);
|
|
3216
|
+
return await statReadonlySkillFile(path4, readonlySkillRoots(workspace));
|
|
3189
3217
|
}
|
|
3190
|
-
const workspace = await resolveWorkspace(request);
|
|
3191
3218
|
const stat13 = await workspace.stat(path4);
|
|
3192
3219
|
return stat13;
|
|
3193
3220
|
} catch (err) {
|
|
@@ -3201,7 +3228,7 @@ function fileRoutes(app, opts, done) {
|
|
|
3201
3228
|
import { createHash as createHash3 } from "crypto";
|
|
3202
3229
|
import { constants as constants2 } from "fs";
|
|
3203
3230
|
import { access as access2, chmod as chmod3, cp, mkdir as mkdir4, readdir as readdir3, readFile as readFile5, realpath as realpath2, stat as stat5, writeFile as writeFile4 } from "fs/promises";
|
|
3204
|
-
import { dirname as dirname6, isAbsolute as
|
|
3231
|
+
import { dirname as dirname6, isAbsolute as isAbsolute5, join as join4, relative as relative6, resolve as resolve6 } from "path";
|
|
3205
3232
|
import { fileURLToPath } from "url";
|
|
3206
3233
|
import { execFile } from "child_process";
|
|
3207
3234
|
import { promisify } from "util";
|
|
@@ -3310,10 +3337,10 @@ function resolveTemplateTarget(workspaceRoot, target) {
|
|
|
3310
3337
|
if (rawTarget.length === 0 || rawTarget.includes("\0") || rawTarget.includes("\\") || rawTarget.startsWith("/") || rawTarget.startsWith("//") || /^[A-Za-z]:[\\/]/.test(rawTarget) || rawTarget.split("/").includes("..")) {
|
|
3311
3338
|
throw new Error(`Unsafe runtime template target: ${JSON.stringify(rawTarget)}. Template targets must be relative paths inside the workspace.`);
|
|
3312
3339
|
}
|
|
3313
|
-
const root =
|
|
3314
|
-
const resolved =
|
|
3315
|
-
const rel =
|
|
3316
|
-
if (rel.startsWith("..") ||
|
|
3340
|
+
const root = resolve6(workspaceRoot);
|
|
3341
|
+
const resolved = resolve6(root, rawTarget);
|
|
3342
|
+
const rel = relative6(root, resolved);
|
|
3343
|
+
if (rel.startsWith("..") || isAbsolute5(rel)) {
|
|
3317
3344
|
throw new Error(`Unsafe runtime template target: ${JSON.stringify(rawTarget)} resolves outside the workspace.`);
|
|
3318
3345
|
}
|
|
3319
3346
|
return resolved;
|
|
@@ -3338,7 +3365,7 @@ function nodePackageTarget(workspaceRoot, packageName) {
|
|
|
3338
3365
|
}
|
|
3339
3366
|
async function copyIfExists(source, target) {
|
|
3340
3367
|
if (!await exists(source)) return false;
|
|
3341
|
-
if (
|
|
3368
|
+
if (resolve6(source) === resolve6(target)) return true;
|
|
3342
3369
|
if (await exists(target) && await realpath2(source) === await realpath2(target)) return true;
|
|
3343
3370
|
await cp(source, target, {
|
|
3344
3371
|
recursive: true,
|
|
@@ -3899,7 +3926,7 @@ function createVercelSandboxWorkspace(sandbox, workspaceOpts = {}) {
|
|
|
3899
3926
|
// src/server/workspace/provisioning/packArtifact.ts
|
|
3900
3927
|
import { execFile as execFile2 } from "child_process";
|
|
3901
3928
|
import { mkdir as mkdir5, mkdtemp, rename as rename4 } from "fs/promises";
|
|
3902
|
-
import { dirname as dirname7, isAbsolute as
|
|
3929
|
+
import { dirname as dirname7, isAbsolute as isAbsolute6, join as join5 } from "path";
|
|
3903
3930
|
import { tmpdir } from "os";
|
|
3904
3931
|
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
3905
3932
|
import { promisify as promisify2 } from "util";
|
|
@@ -3944,7 +3971,7 @@ async function packProvisioningArtifact(request) {
|
|
|
3944
3971
|
], { maxBuffer: 1024 * 1024 * 20 });
|
|
3945
3972
|
const packedName = stdout.trim().split(/\r?\n/).filter(Boolean).at(-1);
|
|
3946
3973
|
if (!packedName) throw new Error(`pnpm pack produced no artifact for ${sourcePath}`);
|
|
3947
|
-
const packedPath =
|
|
3974
|
+
const packedPath = isAbsolute6(packedName) ? packedName : join5(dirname7(request.outputPath), packedName);
|
|
3948
3975
|
await rename4(packedPath, request.outputPath);
|
|
3949
3976
|
return;
|
|
3950
3977
|
}
|
|
@@ -4074,7 +4101,7 @@ function createPythonRuntimeFingerprint(input) {
|
|
|
4074
4101
|
}
|
|
4075
4102
|
|
|
4076
4103
|
// src/server/workspace/provisioning/node.ts
|
|
4077
|
-
import { join as join6, relative as
|
|
4104
|
+
import { join as join6, relative as relative7, sep as sep3 } from "path";
|
|
4078
4105
|
var NODE_RUNTIME_REL = ".boring-agent/node";
|
|
4079
4106
|
var NODE_PACKAGE_JSON_REL = `${NODE_RUNTIME_REL}/package.json`;
|
|
4080
4107
|
var NODE_FINGERPRINT_REL = `${NODE_RUNTIME_REL}/.fingerprint`;
|
|
@@ -4119,7 +4146,7 @@ function expectedNodeOutputs(paths, packages) {
|
|
|
4119
4146
|
];
|
|
4120
4147
|
}
|
|
4121
4148
|
function toWorkspaceRel(paths, absolutePath) {
|
|
4122
|
-
return
|
|
4149
|
+
return relative7(paths.workspaceRoot, absolutePath).split(sep3).join("/");
|
|
4123
4150
|
}
|
|
4124
4151
|
async function shouldInstallNodeRuntime(options) {
|
|
4125
4152
|
const currentFingerprint = (await options.adapter.workspaceFs.readText(NODE_FINGERPRINT_REL))?.trim();
|
|
@@ -4205,7 +4232,7 @@ async function ensureNodeRuntime(options) {
|
|
|
4205
4232
|
}
|
|
4206
4233
|
|
|
4207
4234
|
// src/server/workspace/provisioning/python.ts
|
|
4208
|
-
import { dirname as dirname9, join as join7, relative as
|
|
4235
|
+
import { dirname as dirname9, join as join7, relative as relative8, sep as sep4 } from "path";
|
|
4209
4236
|
import { fileURLToPath as fileURLToPath3 } from "url";
|
|
4210
4237
|
var VENV_REL = ".boring-agent/venv";
|
|
4211
4238
|
var VENV_FINGERPRINT_REL = `${VENV_REL}/.fingerprint`;
|
|
@@ -4298,7 +4325,7 @@ function collectPythonEnv(packages) {
|
|
|
4298
4325
|
return env;
|
|
4299
4326
|
}
|
|
4300
4327
|
function toWorkspaceRel2(paths, absolutePath) {
|
|
4301
|
-
return
|
|
4328
|
+
return relative8(paths.workspaceRoot, absolutePath).split(sep4).join("/");
|
|
4302
4329
|
}
|
|
4303
4330
|
async function shouldInstallPythonRuntime(options) {
|
|
4304
4331
|
const currentFingerprint = (await options.adapter.workspaceFs.readText(VENV_FINGERPRINT_REL))?.trim();
|
|
@@ -4764,7 +4791,7 @@ async function copyTemplate(templatePath, workspaceRoot) {
|
|
|
4764
4791
|
// src/server/runtime/modes/provisioningAdapter.ts
|
|
4765
4792
|
import { spawn as spawn3 } from "child_process";
|
|
4766
4793
|
import { cp as cp3, lstat as lstat3, mkdir as mkdir7, readFile as readFile7, realpath as realpath3, rm as rm3, stat as stat8, writeFile as writeFile5 } from "fs/promises";
|
|
4767
|
-
import { dirname as dirname10, isAbsolute as
|
|
4794
|
+
import { dirname as dirname10, isAbsolute as isAbsolute7, relative as relative9, resolve as resolve7, sep as sep5 } from "path";
|
|
4768
4795
|
import { fileURLToPath as fileURLToPath6 } from "url";
|
|
4769
4796
|
var LOCAL_SANDBOX_WORKSPACE_ROOT = "/workspace";
|
|
4770
4797
|
function sourceToPath4(source) {
|
|
@@ -4852,8 +4879,8 @@ function defaultExecOptions(paths, opts) {
|
|
|
4852
4879
|
};
|
|
4853
4880
|
}
|
|
4854
4881
|
function mapWorkspacePathToLocalSandbox(paths, value) {
|
|
4855
|
-
const absolute =
|
|
4856
|
-
const relPath =
|
|
4882
|
+
const absolute = isAbsolute7(value) ? value : resolve7(paths.workspaceRoot, value);
|
|
4883
|
+
const relPath = relative9(paths.workspaceRoot, absolute);
|
|
4857
4884
|
if (relPath === "") return LOCAL_SANDBOX_WORKSPACE_ROOT;
|
|
4858
4885
|
if (relPath === ".." || relPath.startsWith(`..${sep5}`)) return value;
|
|
4859
4886
|
return `${LOCAL_SANDBOX_WORKSPACE_ROOT}/${relPath.split(sep5).join("/")}`;
|
|
@@ -4957,9 +4984,9 @@ function createLocalProvisioningAdapter(paths, runner = spawnCommand) {
|
|
|
4957
4984
|
const hostPath = sourceToPath4(source);
|
|
4958
4985
|
const realWorkspaceRoot = await realpath3(paths.workspaceRoot);
|
|
4959
4986
|
const realSource = await realpath3(hostPath);
|
|
4960
|
-
const relPath =
|
|
4987
|
+
const relPath = relative9(realWorkspaceRoot, realSource);
|
|
4961
4988
|
if (relPath === "") return LOCAL_SANDBOX_WORKSPACE_ROOT;
|
|
4962
|
-
if (!relPath.startsWith("..") && !
|
|
4989
|
+
if (!relPath.startsWith("..") && !isAbsolute7(relPath)) {
|
|
4963
4990
|
return `${LOCAL_SANDBOX_WORKSPACE_ROOT}/${relPath.split(sep5).join("/")}`;
|
|
4964
4991
|
}
|
|
4965
4992
|
return await resolveArtifactInstallSource({
|
|
@@ -5248,11 +5275,11 @@ async function buildTarGz(files) {
|
|
|
5248
5275
|
}
|
|
5249
5276
|
chunks.push(Buffer.alloc(1024));
|
|
5250
5277
|
const tarBuffer = Buffer.concat(chunks);
|
|
5251
|
-
return new Promise((
|
|
5278
|
+
return new Promise((resolve13, reject) => {
|
|
5252
5279
|
const gzip = createGzip({ level: 6 });
|
|
5253
5280
|
const gzChunks = [];
|
|
5254
5281
|
gzip.on("data", (chunk) => gzChunks.push(chunk));
|
|
5255
|
-
gzip.on("end", () =>
|
|
5282
|
+
gzip.on("end", () => resolve13(Buffer.concat(gzChunks)));
|
|
5256
5283
|
gzip.on("error", reject);
|
|
5257
5284
|
Readable.from(tarBuffer).pipe(gzip);
|
|
5258
5285
|
});
|
|
@@ -7612,11 +7639,11 @@ function bindingDisposedError() {
|
|
|
7612
7639
|
});
|
|
7613
7640
|
}
|
|
7614
7641
|
function deferred() {
|
|
7615
|
-
let
|
|
7642
|
+
let resolve13;
|
|
7616
7643
|
const promise = new Promise((nextResolve) => {
|
|
7617
|
-
|
|
7644
|
+
resolve13 = () => nextResolve();
|
|
7618
7645
|
});
|
|
7619
|
-
return { promise, resolve:
|
|
7646
|
+
return { promise, resolve: resolve13 };
|
|
7620
7647
|
}
|
|
7621
7648
|
|
|
7622
7649
|
// src/server/pi-chat/harnessPiChatService.ts
|
|
@@ -8290,13 +8317,13 @@ function promptCancelledError() {
|
|
|
8290
8317
|
});
|
|
8291
8318
|
}
|
|
8292
8319
|
function deferred2() {
|
|
8293
|
-
let
|
|
8320
|
+
let resolve13;
|
|
8294
8321
|
let reject;
|
|
8295
8322
|
const promise = new Promise((nextResolve, nextReject) => {
|
|
8296
|
-
|
|
8323
|
+
resolve13 = nextResolve;
|
|
8297
8324
|
reject = nextReject;
|
|
8298
8325
|
});
|
|
8299
|
-
return { promise, resolve:
|
|
8326
|
+
return { promise, resolve: resolve13, reject };
|
|
8300
8327
|
}
|
|
8301
8328
|
function rejectedReasons(results) {
|
|
8302
8329
|
return results.flatMap((result) => result.status === "rejected" ? [result.reason] : []);
|
|
@@ -8457,7 +8484,7 @@ function createAgentRuntimeBridge2(config, options = {}) {
|
|
|
8457
8484
|
});
|
|
8458
8485
|
}
|
|
8459
8486
|
async function createRuntime(config, options) {
|
|
8460
|
-
const harnessFactory = config.harnessFactory ?? (await import("./createHarness-
|
|
8487
|
+
const harnessFactory = config.harnessFactory ?? (await import("./createHarness-TGBJZISM.js")).createPiCodingAgentHarness;
|
|
8461
8488
|
const harnessInput = {
|
|
8462
8489
|
tools: config.tools ?? [],
|
|
8463
8490
|
cwd: config.workdir ?? DEFAULT_WORKDIR,
|
|
@@ -8497,7 +8524,7 @@ function stableAgentError(code, message) {
|
|
|
8497
8524
|
// src/server/agentDefinition/compileAgentDirectory.ts
|
|
8498
8525
|
import { constants as constants4 } from "fs";
|
|
8499
8526
|
import { open as open2, realpath as realpath4, stat as stat10 } from "fs/promises";
|
|
8500
|
-
import { isAbsolute as
|
|
8527
|
+
import { isAbsolute as isAbsolute8, relative as relative10, resolve as resolve8, sep as sep6 } from "path";
|
|
8501
8528
|
var AGENT_MANIFEST = "agent.json";
|
|
8502
8529
|
var AGENT_INSTRUCTIONS = "instructions.md";
|
|
8503
8530
|
var AgentDirectoryCompilerError = class extends Error {
|
|
@@ -8516,8 +8543,8 @@ function isNotFound(error) {
|
|
|
8516
8543
|
return error?.code === "ENOENT";
|
|
8517
8544
|
}
|
|
8518
8545
|
function isInsideRoot(root, target) {
|
|
8519
|
-
const pathFromRoot =
|
|
8520
|
-
return pathFromRoot === "" || pathFromRoot !== ".." && !pathFromRoot.startsWith(`..${sep6}`) && !
|
|
8546
|
+
const pathFromRoot = relative10(root, target);
|
|
8547
|
+
return pathFromRoot === "" || pathFromRoot !== ".." && !pathFromRoot.startsWith(`..${sep6}`) && !isAbsolute8(pathFromRoot);
|
|
8521
8548
|
}
|
|
8522
8549
|
async function resolveAgentRoot(directory) {
|
|
8523
8550
|
if (typeof directory !== "string" || directory.length === 0) {
|
|
@@ -8530,7 +8557,7 @@ async function resolveAgentRoot(directory) {
|
|
|
8530
8557
|
}
|
|
8531
8558
|
let root;
|
|
8532
8559
|
try {
|
|
8533
|
-
root = await realpath4(
|
|
8560
|
+
root = await realpath4(resolve8(directory));
|
|
8534
8561
|
} catch (error) {
|
|
8535
8562
|
throw new AgentDirectoryCompilerError({
|
|
8536
8563
|
code: isNotFound(error) ? ErrorCode.enum.PATH_NOT_FOUND : ErrorCode.enum.CONFIG_INVALID,
|
|
@@ -8567,7 +8594,7 @@ async function readContainedFile({
|
|
|
8567
8594
|
field,
|
|
8568
8595
|
kind
|
|
8569
8596
|
}) {
|
|
8570
|
-
const candidate =
|
|
8597
|
+
const candidate = resolve8(root, path4);
|
|
8571
8598
|
if (!isInsideRoot(root, candidate)) {
|
|
8572
8599
|
throw new AgentDirectoryCompilerError({
|
|
8573
8600
|
code: ErrorCode.enum.PATH_SYMLINK_ESCAPE,
|
|
@@ -8717,6 +8744,22 @@ var AuthorizedAgentDeploymentBindingSchema = z.object({
|
|
|
8717
8744
|
workspaceCompositionDigest: Sha256DigestSchema
|
|
8718
8745
|
});
|
|
8719
8746
|
var RESOLVED_AGENT_DIGEST_DOMAIN = "boring-agent/resolved-agent:v1";
|
|
8747
|
+
var ResolvedAgentDigestInputSchema = z.object({
|
|
8748
|
+
workspaceId: OpaqueRefSchema,
|
|
8749
|
+
defaultDeploymentId: OpaqueRefSchema,
|
|
8750
|
+
workspaceCompositionDigest: Sha256DigestSchema,
|
|
8751
|
+
definitionDigest: Sha256DigestSchema,
|
|
8752
|
+
deploymentDigest: Sha256DigestSchema
|
|
8753
|
+
}).strict();
|
|
8754
|
+
async function createResolvedAgentDigest(input) {
|
|
8755
|
+
const parsed = ResolvedAgentDigestInputSchema.safeParse(input);
|
|
8756
|
+
if (!parsed.success) {
|
|
8757
|
+
const field = parsed.error.issues[0]?.path[0];
|
|
8758
|
+
const digestField = typeof field === "string" ? field : "workspaceId";
|
|
8759
|
+
throw invalidDeployment(digestField, `${digestField} is invalid`);
|
|
8760
|
+
}
|
|
8761
|
+
return createAgentAssetDigest(canonicalStringify({ domain: RESOLVED_AGENT_DIGEST_DOMAIN, ...parsed.data }));
|
|
8762
|
+
}
|
|
8720
8763
|
function invalidDefinition(field, message) {
|
|
8721
8764
|
return new AgentDefinitionValidationError({
|
|
8722
8765
|
code: AgentDefinitionErrorCode.enum.AGENT_DEFINITION_INVALID,
|
|
@@ -8791,14 +8834,13 @@ async function resolveAgentDeployment(bundle, deployment, authorizedBinding) {
|
|
|
8791
8834
|
"instructionsRef must name an included verified asset"
|
|
8792
8835
|
);
|
|
8793
8836
|
}
|
|
8794
|
-
const resolvedDigest = await
|
|
8795
|
-
domain: RESOLVED_AGENT_DIGEST_DOMAIN,
|
|
8837
|
+
const resolvedDigest = await createResolvedAgentDigest({
|
|
8796
8838
|
workspaceId: binding.workspaceId,
|
|
8797
8839
|
defaultDeploymentId: binding.defaultDeploymentId,
|
|
8798
8840
|
workspaceCompositionDigest: binding.workspaceCompositionDigest,
|
|
8799
8841
|
definitionDigest,
|
|
8800
8842
|
deploymentDigest
|
|
8801
|
-
})
|
|
8843
|
+
});
|
|
8802
8844
|
const workspace = Object.freeze({
|
|
8803
8845
|
workspaceId: binding.workspaceId,
|
|
8804
8846
|
defaultDeploymentId: binding.defaultDeploymentId,
|
|
@@ -8830,7 +8872,7 @@ async function resolveAgentDeployment(bundle, deployment, authorizedBinding) {
|
|
|
8830
8872
|
}
|
|
8831
8873
|
|
|
8832
8874
|
// src/server/mcp/managedAgentDelegate.ts
|
|
8833
|
-
import {
|
|
8875
|
+
import { randomUUID } from "crypto";
|
|
8834
8876
|
var MANAGED_AGENT_MCP_ORIGIN_SURFACE = "mcp-managed-agent";
|
|
8835
8877
|
var MANAGED_AGENT_MCP_DELIVERY_RULE = "M1 DELIVERY v0: delegate_task returns bounded final assistant text and at most one complete authorized inline Markdown artifact; no artifact paths, truncation, or share-link delivery.";
|
|
8836
8878
|
var MAX_FINAL_ASSISTANT_TEXT_BYTES = 96 * 1024;
|
|
@@ -9326,7 +9368,7 @@ async function resolveMarkdownArtifact(candidate, workspace) {
|
|
|
9326
9368
|
validateMarkdownContent(content);
|
|
9327
9369
|
const artifact = {
|
|
9328
9370
|
content,
|
|
9329
|
-
sha256:
|
|
9371
|
+
sha256: await sha256Bytes(bytes),
|
|
9330
9372
|
byteSize,
|
|
9331
9373
|
mediaType: MARKDOWN_MEDIA_TYPE,
|
|
9332
9374
|
...candidate.title ? { title: candidate.title } : {}
|
|
@@ -9419,9 +9461,6 @@ function validateMarkdownContent(content) {
|
|
|
9419
9461
|
function sameStat(left, right) {
|
|
9420
9462
|
return left.kind === right.kind && left.size === right.size && left.mtimeMs === right.mtimeMs;
|
|
9421
9463
|
}
|
|
9422
|
-
function sha256(bytes) {
|
|
9423
|
-
return `sha256:${createHash6("sha256").update(bytes).digest("hex")}`;
|
|
9424
|
-
}
|
|
9425
9464
|
function safeDecodeArtifactPath(path4) {
|
|
9426
9465
|
try {
|
|
9427
9466
|
return decodeURIComponent(path4);
|
|
@@ -9586,13 +9625,13 @@ function resultTool(result) {
|
|
|
9586
9625
|
};
|
|
9587
9626
|
}
|
|
9588
9627
|
function deferred3() {
|
|
9589
|
-
let
|
|
9628
|
+
let resolve13;
|
|
9590
9629
|
let reject;
|
|
9591
9630
|
const promise = new Promise((res, rej) => {
|
|
9592
|
-
|
|
9631
|
+
resolve13 = res;
|
|
9593
9632
|
reject = rej;
|
|
9594
9633
|
});
|
|
9595
|
-
return { promise, resolve:
|
|
9634
|
+
return { promise, resolve: resolve13, reject };
|
|
9596
9635
|
}
|
|
9597
9636
|
function errorTool(error) {
|
|
9598
9637
|
const safe = safeError(error);
|
|
@@ -9659,7 +9698,7 @@ function withRuntimeEnvContributions(runtimeBundle, baseContext, contributions,
|
|
|
9659
9698
|
|
|
9660
9699
|
// src/server/harness/pi-coding-agent/pluginLoader.ts
|
|
9661
9700
|
import { readdir as readdir7, stat as stat11, readFile as readFile10 } from "fs/promises";
|
|
9662
|
-
import { join as join10, extname as extname3, resolve as
|
|
9701
|
+
import { join as join10, extname as extname3, resolve as resolve9, sep as sep7, relative as relative11 } from "path";
|
|
9663
9702
|
import { homedir as homedir3 } from "os";
|
|
9664
9703
|
import { pathToFileURL as pathToFileURL2 } from "url";
|
|
9665
9704
|
var VALID_EXTENSIONS = /* @__PURE__ */ new Set([".js", ".mjs"]);
|
|
@@ -9729,12 +9768,12 @@ async function loadNpmPlugin(pkgDir, importFn) {
|
|
|
9729
9768
|
if (!await fileExists(pkgJsonPath)) return [];
|
|
9730
9769
|
const pkgJson = JSON.parse(await readFile10(pkgJsonPath, "utf-8"));
|
|
9731
9770
|
const main = pkgJson.main ?? "index.js";
|
|
9732
|
-
const resolvedMain =
|
|
9733
|
-
const resolvedPkgDir =
|
|
9771
|
+
const resolvedMain = resolve9(pkgDir, main);
|
|
9772
|
+
const resolvedPkgDir = resolve9(pkgDir);
|
|
9734
9773
|
if (resolvedMain !== resolvedPkgDir && !resolvedMain.startsWith(resolvedPkgDir + sep7)) {
|
|
9735
9774
|
return [];
|
|
9736
9775
|
}
|
|
9737
|
-
const relPath =
|
|
9776
|
+
const relPath = relative11(resolvedPkgDir, resolvedMain);
|
|
9738
9777
|
if (relPath.startsWith("..")) {
|
|
9739
9778
|
return [];
|
|
9740
9779
|
}
|
|
@@ -9819,7 +9858,7 @@ import {
|
|
|
9819
9858
|
// src/server/tools/operations/bound.ts
|
|
9820
9859
|
import { constants as constants5 } from "fs";
|
|
9821
9860
|
import { access as access4, lstat as lstat4, mkdir as mkdir11, readFile as readFile11, readdir as readdir8, readlink, realpath as realpath5, stat as stat12, writeFile as writeFile6 } from "fs/promises";
|
|
9822
|
-
import { dirname as dirname11, isAbsolute as
|
|
9861
|
+
import { dirname as dirname11, isAbsolute as isAbsolute9, join as join11, relative as relative12, resolve as resolve10 } from "path";
|
|
9823
9862
|
function toPosixPath(value) {
|
|
9824
9863
|
return value.split("\\").join("/");
|
|
9825
9864
|
}
|
|
@@ -9875,8 +9914,8 @@ async function walkMatches(root, current, pattern, ignore, limit, out) {
|
|
|
9875
9914
|
const entries = await readdir8(current, { withFileTypes: true });
|
|
9876
9915
|
for (const entry of entries) {
|
|
9877
9916
|
if (out.length >= limit) return;
|
|
9878
|
-
const absolutePath =
|
|
9879
|
-
const relativePath = toPosixPath(
|
|
9917
|
+
const absolutePath = resolve10(current, entry.name);
|
|
9918
|
+
const relativePath = toPosixPath(relative12(root, absolutePath));
|
|
9880
9919
|
if (entry.isDirectory() && shouldSkipDir(relativePath, ignore)) continue;
|
|
9881
9920
|
if (matchesGlob(relativePath, pattern)) {
|
|
9882
9921
|
out.push(absolutePath);
|
|
@@ -9900,16 +9939,16 @@ async function findNearestExistingAncestor(absPath) {
|
|
|
9900
9939
|
}
|
|
9901
9940
|
}
|
|
9902
9941
|
async function assertWithinWorkspace(workspaceRoot, absPath) {
|
|
9903
|
-
const realRoot = await realpath5(
|
|
9942
|
+
const realRoot = await realpath5(resolve10(workspaceRoot));
|
|
9904
9943
|
try {
|
|
9905
9944
|
const s = await lstat4(absPath);
|
|
9906
9945
|
if (s.isSymbolicLink()) {
|
|
9907
9946
|
const target = await readlink(absPath);
|
|
9908
|
-
const resolvedTarget =
|
|
9947
|
+
const resolvedTarget = resolve10(dirname11(absPath), target);
|
|
9909
9948
|
const nearestAncestor = await findNearestExistingAncestor(resolvedTarget);
|
|
9910
9949
|
const realAncestor = await realpath5(nearestAncestor);
|
|
9911
|
-
const rel2 =
|
|
9912
|
-
if (rel2.startsWith("..") ||
|
|
9950
|
+
const rel2 = relative12(realRoot, realAncestor);
|
|
9951
|
+
if (rel2.startsWith("..") || isAbsolute9(rel2)) {
|
|
9913
9952
|
throw new Error(`path "${absPath}" is outside workspace`);
|
|
9914
9953
|
}
|
|
9915
9954
|
return;
|
|
@@ -9929,16 +9968,16 @@ async function assertWithinWorkspace(workspaceRoot, absPath) {
|
|
|
9929
9968
|
if (code === "ENOENT") {
|
|
9930
9969
|
const nearestAncestor = await findNearestExistingAncestor(dirname11(absPath));
|
|
9931
9970
|
const realAncestor = await realpath5(nearestAncestor);
|
|
9932
|
-
const rel2 =
|
|
9933
|
-
if (rel2.startsWith("..") ||
|
|
9971
|
+
const rel2 = relative12(realRoot, realAncestor);
|
|
9972
|
+
if (rel2.startsWith("..") || isAbsolute9(rel2)) {
|
|
9934
9973
|
throw new Error(`path "${absPath}" is outside workspace`);
|
|
9935
9974
|
}
|
|
9936
9975
|
return;
|
|
9937
9976
|
}
|
|
9938
9977
|
throw err;
|
|
9939
9978
|
}
|
|
9940
|
-
const rel =
|
|
9941
|
-
if (rel.startsWith("..") ||
|
|
9979
|
+
const rel = relative12(realRoot, realCandidate);
|
|
9980
|
+
if (rel.startsWith("..") || isAbsolute9(rel)) {
|
|
9942
9981
|
throw new Error(`path "${absPath}" is outside workspace`);
|
|
9943
9982
|
}
|
|
9944
9983
|
}
|
|
@@ -9956,9 +9995,9 @@ function boundFs(workspaceRoot, opts = {}) {
|
|
|
9956
9995
|
};
|
|
9957
9996
|
const toRuntimePath = (absolutePath) => {
|
|
9958
9997
|
if (!shouldMapRuntimeRoot || !runtimeRoot) return absolutePath;
|
|
9959
|
-
const rel =
|
|
9998
|
+
const rel = relative12(workspaceRoot, absolutePath);
|
|
9960
9999
|
if (rel === "") return runtimeRoot;
|
|
9961
|
-
if (rel.startsWith("..") ||
|
|
10000
|
+
if (rel.startsWith("..") || isAbsolute9(rel)) return absolutePath;
|
|
9962
10001
|
return `${runtimeRoot}/${toPosixPath(rel)}`;
|
|
9963
10002
|
};
|
|
9964
10003
|
const read = {
|
|
@@ -10070,7 +10109,7 @@ import {
|
|
|
10070
10109
|
} from "@mariozechner/pi-coding-agent";
|
|
10071
10110
|
|
|
10072
10111
|
// src/server/tools/operations/remoteWorkspace.ts
|
|
10073
|
-
import { isAbsolute as
|
|
10112
|
+
import { isAbsolute as isAbsolute10, relative as relative13 } from "path";
|
|
10074
10113
|
function unique(values) {
|
|
10075
10114
|
return Array.from(new Set(values));
|
|
10076
10115
|
}
|
|
@@ -10078,11 +10117,11 @@ function rootsFor(workspace, opts = {}) {
|
|
|
10078
10117
|
return unique([workspace.root, ...opts.rootAliases ?? []]);
|
|
10079
10118
|
}
|
|
10080
10119
|
function isOutsideWorkspaceRel(rel) {
|
|
10081
|
-
return rel === ".." || rel.startsWith("../") || rel.startsWith("..\\") ||
|
|
10120
|
+
return rel === ".." || rel.startsWith("../") || rel.startsWith("..\\") || isAbsolute10(rel);
|
|
10082
10121
|
}
|
|
10083
10122
|
function toRelPath(workspace, absolutePath, opts = {}) {
|
|
10084
10123
|
for (const root of rootsFor(workspace, opts)) {
|
|
10085
|
-
const rel =
|
|
10124
|
+
const rel = relative13(root, absolutePath);
|
|
10086
10125
|
if (!isOutsideWorkspaceRel(rel)) return rel;
|
|
10087
10126
|
}
|
|
10088
10127
|
const skillMarker = "/.agents/skills/";
|
|
@@ -10249,7 +10288,7 @@ import {
|
|
|
10249
10288
|
truncateHead,
|
|
10250
10289
|
truncateLine
|
|
10251
10290
|
} from "@mariozechner/pi-coding-agent";
|
|
10252
|
-
import { resolve as
|
|
10291
|
+
import { resolve as resolve11, relative as relative14 } from "path";
|
|
10253
10292
|
|
|
10254
10293
|
// src/server/catalog/tools/_shared.ts
|
|
10255
10294
|
function makeError(message) {
|
|
@@ -10352,15 +10391,15 @@ function isOutsideWorkspace(rel) {
|
|
|
10352
10391
|
return rel === ".." || rel.startsWith("../") || rel.startsWith("..\\") || rel.startsWith("/");
|
|
10353
10392
|
}
|
|
10354
10393
|
function isUnderRoot(root, path4) {
|
|
10355
|
-
const rel =
|
|
10394
|
+
const rel = relative14(root, path4);
|
|
10356
10395
|
return !isOutsideWorkspace(rel);
|
|
10357
10396
|
}
|
|
10358
10397
|
function normalizeSearchPath(rawPath, workspaceRoot, pathOptions) {
|
|
10359
10398
|
const path4 = optionalStringParam(rawPath) ?? ".";
|
|
10360
10399
|
if (!workspaceRoot) return { ok: true, path: pathOptions?.toRemotePath?.(path4) ?? path4 };
|
|
10361
10400
|
if (!path4.startsWith("/")) {
|
|
10362
|
-
const resolved =
|
|
10363
|
-
const rel =
|
|
10401
|
+
const resolved = resolve11(workspaceRoot, path4);
|
|
10402
|
+
const rel = relative14(workspaceRoot, resolved);
|
|
10364
10403
|
if (isOutsideWorkspace(rel)) return { ok: false, message: `path "${path4}" is outside workspace` };
|
|
10365
10404
|
return { ok: true, path: path4 };
|
|
10366
10405
|
}
|
|
@@ -11706,16 +11745,16 @@ function modelsRoutes(app, opts, done) {
|
|
|
11706
11745
|
}
|
|
11707
11746
|
|
|
11708
11747
|
// src/server/http/routes/skills.ts
|
|
11709
|
-
import { isAbsolute as
|
|
11748
|
+
import { isAbsolute as isAbsolute11, relative as relative15, resolve as resolve12, sep as sep8 } from "path";
|
|
11710
11749
|
import {
|
|
11711
11750
|
DefaultPackageManager,
|
|
11712
|
-
getAgentDir,
|
|
11751
|
+
getAgentDir as getAgentDir2,
|
|
11713
11752
|
loadSkills
|
|
11714
11753
|
} from "@mariozechner/pi-coding-agent";
|
|
11715
11754
|
var CACHE_TTL_MS2 = 3e4;
|
|
11716
11755
|
function pathForWorkspaceEditor(workspaceRoot, filePath) {
|
|
11717
|
-
const pathWithinWorkspace =
|
|
11718
|
-
if (pathWithinWorkspace === "" || pathWithinWorkspace === ".." || pathWithinWorkspace.startsWith(`..${sep8}`) ||
|
|
11756
|
+
const pathWithinWorkspace = relative15(resolve12(workspaceRoot), resolve12(filePath));
|
|
11757
|
+
if (pathWithinWorkspace === "" || pathWithinWorkspace === ".." || pathWithinWorkspace.startsWith(`..${sep8}`) || isAbsolute11(pathWithinWorkspace)) {
|
|
11719
11758
|
return filePath;
|
|
11720
11759
|
}
|
|
11721
11760
|
return pathWithinWorkspace.split(sep8).join("/");
|
|
@@ -11723,7 +11762,9 @@ function pathForWorkspaceEditor(workspaceRoot, filePath) {
|
|
|
11723
11762
|
function skillsRoutes(app, opts, done) {
|
|
11724
11763
|
const cached = /* @__PURE__ */ new Map();
|
|
11725
11764
|
async function resolveSkillsForRequest(request, refresh = false) {
|
|
11726
|
-
const
|
|
11765
|
+
const workspace = opts.getWorkspace ? await opts.getWorkspace(request) : opts.workspace;
|
|
11766
|
+
if (!workspace) throw new Error("skills route requires workspace or getWorkspace");
|
|
11767
|
+
const workspaceRoot = workspace.root;
|
|
11727
11768
|
const additionalSkillPaths = opts.getAdditionalSkillPaths ? await opts.getAdditionalSkillPaths(request) : opts.additionalSkillPaths;
|
|
11728
11769
|
const piPackages = opts.getPiPackages ? await opts.getPiPackages(request) : opts.piPackages;
|
|
11729
11770
|
const noSkills = (opts.getNoSkills ? await opts.getNoSkills(request) : opts.noSkills) ?? withPiHarnessDefaults().noSkills;
|
|
@@ -11734,7 +11775,7 @@ function skillsRoutes(app, opts, done) {
|
|
|
11734
11775
|
}
|
|
11735
11776
|
const cachedEntry = cached.get(cacheKey);
|
|
11736
11777
|
if (!refresh && cachedEntry && cachedEntry.expiresAt > now) return cachedEntry;
|
|
11737
|
-
const agentDir =
|
|
11778
|
+
const agentDir = getAgentDir2();
|
|
11738
11779
|
const packageSkillPaths = noSkills ? [] : await (async () => {
|
|
11739
11780
|
const settingsManager = createResourceSettingsManager(
|
|
11740
11781
|
workspaceRoot,
|
|
@@ -12489,7 +12530,7 @@ function searchRoutes(app, opts, done) {
|
|
|
12489
12530
|
}
|
|
12490
12531
|
|
|
12491
12532
|
// src/server/git/gitFileUrl.ts
|
|
12492
|
-
import { dirname as dirname12, relative as
|
|
12533
|
+
import { dirname as dirname12, relative as relative16 } from "path";
|
|
12493
12534
|
import { execFile as execFile3 } from "child_process";
|
|
12494
12535
|
import { promisify as promisify3 } from "util";
|
|
12495
12536
|
|
|
@@ -12572,7 +12613,7 @@ async function resolveGitFileUrl(workspaceRoot, path4) {
|
|
|
12572
12613
|
commitSha = null;
|
|
12573
12614
|
}
|
|
12574
12615
|
}
|
|
12575
|
-
const repoRelativePath =
|
|
12616
|
+
const repoRelativePath = relative16(repoRoot, absolutePath).replace(/\\/g, "/");
|
|
12576
12617
|
const url = buildGitFileUrl({ remoteUrl, repoRelativePath, branch, commitSha });
|
|
12577
12618
|
if (!url) {
|
|
12578
12619
|
return disabled("Only GitHub SSH/HTTPS remotes are supported right now.");
|
|
@@ -12598,8 +12639,8 @@ function requirePath(value, reply) {
|
|
|
12598
12639
|
}
|
|
12599
12640
|
function gitRoutes(app, opts, done) {
|
|
12600
12641
|
async function resolveWorkspaceRoot(request) {
|
|
12601
|
-
|
|
12602
|
-
return
|
|
12642
|
+
const workspace = opts.getWorkspace ? await opts.getWorkspace(request) : opts.workspace;
|
|
12643
|
+
return workspace === void 0 ? void 0 : getNodeWorkspaceHostRoot(workspace);
|
|
12603
12644
|
}
|
|
12604
12645
|
app.get("/api/v1/git/file-url", async (request, reply) => {
|
|
12605
12646
|
const query = request.query;
|
|
@@ -13038,6 +13079,8 @@ async function createWorkspaceAgentAppProfile(opts, sessionId, resolvedMode, app
|
|
|
13038
13079
|
requestId: request.id
|
|
13039
13080
|
});
|
|
13040
13081
|
} : void 0;
|
|
13082
|
+
const gitStorageRoot = getOptionalRuntimeBundleStorageRoot(runtimeBundle);
|
|
13083
|
+
const gitWorkspace = gitStorageRoot === void 0 ? runtimeBundle.workspace : createNodeWorkspace(gitStorageRoot);
|
|
13041
13084
|
return {
|
|
13042
13085
|
runtimeMode: resolvedMode,
|
|
13043
13086
|
capabilities: { tools: toolNames(tools) },
|
|
@@ -13061,12 +13104,12 @@ async function createWorkspaceAgentAppProfile(opts, sessionId, resolvedMode, app
|
|
|
13061
13104
|
// File search shares the same bound implementation as the model tool.
|
|
13062
13105
|
search: { fileSearch: runtimeBundle.fileSearch },
|
|
13063
13106
|
// Git metadata resolves against host storage, not a sandbox-internal cwd.
|
|
13064
|
-
git: {
|
|
13107
|
+
git: { workspace: gitWorkspace }
|
|
13065
13108
|
},
|
|
13066
13109
|
chat: { service: agentRuntime.service },
|
|
13067
13110
|
systemPrompt: { harness },
|
|
13068
13111
|
skills: {
|
|
13069
|
-
workspaceRoot,
|
|
13112
|
+
workspace: createNodeWorkspace(workspaceRoot),
|
|
13070
13113
|
additionalSkillPaths: runtimePi.additionalSkillPaths,
|
|
13071
13114
|
piPackages: runtimePi.packages,
|
|
13072
13115
|
noSkills: runtimePi.noSkills,
|
|
@@ -13277,20 +13320,20 @@ function createRuntimeBindingLifecycle(options) {
|
|
|
13277
13320
|
const requestLeaseLifetimes = /* @__PURE__ */ new WeakMap();
|
|
13278
13321
|
let admissionTail = Promise.resolve();
|
|
13279
13322
|
let resolveEntryChange;
|
|
13280
|
-
let entryChange = new Promise((
|
|
13281
|
-
resolveEntryChange =
|
|
13323
|
+
let entryChange = new Promise((resolve13) => {
|
|
13324
|
+
resolveEntryChange = resolve13;
|
|
13282
13325
|
});
|
|
13283
13326
|
function notifyEntryChange() {
|
|
13284
13327
|
resolveEntryChange();
|
|
13285
|
-
entryChange = new Promise((
|
|
13286
|
-
resolveEntryChange =
|
|
13328
|
+
entryChange = new Promise((resolve13) => {
|
|
13329
|
+
resolveEntryChange = resolve13;
|
|
13287
13330
|
});
|
|
13288
13331
|
}
|
|
13289
13332
|
async function withAdmissionLock(operation) {
|
|
13290
13333
|
const previous = admissionTail;
|
|
13291
13334
|
let release;
|
|
13292
|
-
admissionTail = new Promise((
|
|
13293
|
-
release =
|
|
13335
|
+
admissionTail = new Promise((resolve13) => {
|
|
13336
|
+
release = resolve13;
|
|
13294
13337
|
});
|
|
13295
13338
|
await previous;
|
|
13296
13339
|
try {
|
|
@@ -13390,8 +13433,8 @@ function createRuntimeBindingLifecycle(options) {
|
|
|
13390
13433
|
}
|
|
13391
13434
|
function waitForLeases(entry) {
|
|
13392
13435
|
if (entry.activeLeases === 0) return Promise.resolve();
|
|
13393
|
-
entry.leaseDrainPromise ??= new Promise((
|
|
13394
|
-
entry.resolveLeaseDrain =
|
|
13436
|
+
entry.leaseDrainPromise ??= new Promise((resolve13) => {
|
|
13437
|
+
entry.resolveLeaseDrain = resolve13;
|
|
13395
13438
|
});
|
|
13396
13439
|
return entry.leaseDrainPromise;
|
|
13397
13440
|
}
|
|
@@ -14285,6 +14328,9 @@ var registerAgentRoutes = async (app, opts) => {
|
|
|
14285
14328
|
try {
|
|
14286
14329
|
workspaceId = (await opts.getWorkspaceId(request)).trim();
|
|
14287
14330
|
} catch (error) {
|
|
14331
|
+
if (typeof error === "object" && error !== null && "status" in error && error.status === 421 && "code" in error && error.code === ErrorCode.enum.D1_HOST_SCOPE_VIOLATION) {
|
|
14332
|
+
throw error;
|
|
14333
|
+
}
|
|
14288
14334
|
const statusCode = typeof error?.statusCode === "number" ? error.statusCode : 400;
|
|
14289
14335
|
const message = statusCode >= 500 ? "workspace scope failed" : error instanceof Error ? error.message : "workspace id is required";
|
|
14290
14336
|
return reply.code(statusCode).send({
|
|
@@ -14331,7 +14377,11 @@ var registerAgentRoutes = async (app, opts) => {
|
|
|
14331
14377
|
getFileSearch: async (request) => (await getBindingForRequest(request)).runtimeBundle.fileSearch
|
|
14332
14378
|
});
|
|
14333
14379
|
await app.register(gitRoutes, {
|
|
14334
|
-
|
|
14380
|
+
getWorkspace: async (request) => {
|
|
14381
|
+
const runtimeBundle = (await getBindingForRequest(request)).runtimeBundle;
|
|
14382
|
+
const storageRoot = getOptionalRuntimeBundleStorageRoot(runtimeBundle);
|
|
14383
|
+
return storageRoot === void 0 ? runtimeBundle.workspace : createNodeWorkspace(storageRoot);
|
|
14384
|
+
}
|
|
14335
14385
|
});
|
|
14336
14386
|
await app.register(piChatRoutes, {
|
|
14337
14387
|
getService: async (request) => {
|
|
@@ -14347,7 +14397,7 @@ var registerAgentRoutes = async (app, opts) => {
|
|
|
14347
14397
|
filterModels: opts.filterModels
|
|
14348
14398
|
});
|
|
14349
14399
|
await app.register(skillsRoutes, {
|
|
14350
|
-
workspaceRoot,
|
|
14400
|
+
workspace: staticBinding ? createNodeWorkspace(workspaceRoot) : void 0,
|
|
14351
14401
|
additionalSkillPaths: [
|
|
14352
14402
|
...staticBinding?.runtimeProvisioning?.skillPaths ?? [],
|
|
14353
14403
|
...opts.pi?.additionalSkillPaths ?? []
|
|
@@ -14356,7 +14406,7 @@ var registerAgentRoutes = async (app, opts) => {
|
|
|
14356
14406
|
// Undefined is fine: skillsRoutes resolves it through the canonical
|
|
14357
14407
|
// harness policy (withPiHarnessDefaults), same as the factory above.
|
|
14358
14408
|
noSkills: opts.pi?.noSkills,
|
|
14359
|
-
|
|
14409
|
+
getWorkspace: staticBinding ? void 0 : async (request) => createNodeWorkspace((await getSkillsScopeForRequest(request)).root),
|
|
14360
14410
|
getAdditionalSkillPaths: staticBinding && !hasRuntimeProvisioningInput ? void 0 : async (request) => {
|
|
14361
14411
|
const scope = await getSkillsScopeForRequest(request);
|
|
14362
14412
|
if (!hasRuntimeProvisioningInput) return scope.pi.additionalSkillPaths;
|
|
@@ -14488,6 +14538,7 @@ export {
|
|
|
14488
14538
|
createAgent,
|
|
14489
14539
|
AgentDirectoryCompilerError,
|
|
14490
14540
|
compileAgentDirectory,
|
|
14541
|
+
createResolvedAgentDigest,
|
|
14491
14542
|
resolveAgentDeployment,
|
|
14492
14543
|
MANAGED_AGENT_MCP_ORIGIN_SURFACE,
|
|
14493
14544
|
MANAGED_AGENT_MCP_DELIVERY_RULE,
|