pi-outpost 0.10.0 → 0.11.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/dist/pi-outpost.mjs +509 -252
- package/dist/pi-outpost.sea.mjs +2429 -2164
- package/dist/sea-prep.blob +0 -0
- package/package.json +1 -1
package/dist/pi-outpost.mjs
CHANGED
|
@@ -53,8 +53,8 @@ var require_windows = __commonJS({
|
|
|
53
53
|
"../node_modules/@earendil-works/pi-coding-agent/node_modules/isexe/windows.js"(exports, module) {
|
|
54
54
|
module.exports = isexe;
|
|
55
55
|
isexe.sync = sync;
|
|
56
|
-
var
|
|
57
|
-
function checkPathExt(
|
|
56
|
+
var fs15 = __require("fs");
|
|
57
|
+
function checkPathExt(path17, options) {
|
|
58
58
|
var pathext = options.pathExt !== void 0 ? options.pathExt : process.env.PATHEXT;
|
|
59
59
|
if (!pathext) {
|
|
60
60
|
return true;
|
|
@@ -65,25 +65,25 @@ var require_windows = __commonJS({
|
|
|
65
65
|
}
|
|
66
66
|
for (var i = 0; i < pathext.length; i++) {
|
|
67
67
|
var p = pathext[i].toLowerCase();
|
|
68
|
-
if (p &&
|
|
68
|
+
if (p && path17.substr(-p.length).toLowerCase() === p) {
|
|
69
69
|
return true;
|
|
70
70
|
}
|
|
71
71
|
}
|
|
72
72
|
return false;
|
|
73
73
|
}
|
|
74
|
-
function checkStat(stat,
|
|
74
|
+
function checkStat(stat, path17, options) {
|
|
75
75
|
if (!stat.isSymbolicLink() && !stat.isFile()) {
|
|
76
76
|
return false;
|
|
77
77
|
}
|
|
78
|
-
return checkPathExt(
|
|
78
|
+
return checkPathExt(path17, options);
|
|
79
79
|
}
|
|
80
|
-
function isexe(
|
|
81
|
-
|
|
82
|
-
cb(er, er ? false : checkStat(stat,
|
|
80
|
+
function isexe(path17, options, cb) {
|
|
81
|
+
fs15.stat(path17, function(er, stat) {
|
|
82
|
+
cb(er, er ? false : checkStat(stat, path17, options));
|
|
83
83
|
});
|
|
84
84
|
}
|
|
85
|
-
function sync(
|
|
86
|
-
return checkStat(
|
|
85
|
+
function sync(path17, options) {
|
|
86
|
+
return checkStat(fs15.statSync(path17), path17, options);
|
|
87
87
|
}
|
|
88
88
|
}
|
|
89
89
|
});
|
|
@@ -93,14 +93,14 @@ var require_mode = __commonJS({
|
|
|
93
93
|
"../node_modules/@earendil-works/pi-coding-agent/node_modules/isexe/mode.js"(exports, module) {
|
|
94
94
|
module.exports = isexe;
|
|
95
95
|
isexe.sync = sync;
|
|
96
|
-
var
|
|
97
|
-
function isexe(
|
|
98
|
-
|
|
96
|
+
var fs15 = __require("fs");
|
|
97
|
+
function isexe(path17, options, cb) {
|
|
98
|
+
fs15.stat(path17, function(er, stat) {
|
|
99
99
|
cb(er, er ? false : checkStat(stat, options));
|
|
100
100
|
});
|
|
101
101
|
}
|
|
102
|
-
function sync(
|
|
103
|
-
return checkStat(
|
|
102
|
+
function sync(path17, options) {
|
|
103
|
+
return checkStat(fs15.statSync(path17), options);
|
|
104
104
|
}
|
|
105
105
|
function checkStat(stat, options) {
|
|
106
106
|
return stat.isFile() && checkMode(stat, options);
|
|
@@ -124,7 +124,7 @@ var require_mode = __commonJS({
|
|
|
124
124
|
// ../node_modules/@earendil-works/pi-coding-agent/node_modules/isexe/index.js
|
|
125
125
|
var require_isexe = __commonJS({
|
|
126
126
|
"../node_modules/@earendil-works/pi-coding-agent/node_modules/isexe/index.js"(exports, module) {
|
|
127
|
-
var
|
|
127
|
+
var fs15 = __require("fs");
|
|
128
128
|
var core;
|
|
129
129
|
if (process.platform === "win32" || global.TESTING_WINDOWS) {
|
|
130
130
|
core = require_windows();
|
|
@@ -133,7 +133,7 @@ var require_isexe = __commonJS({
|
|
|
133
133
|
}
|
|
134
134
|
module.exports = isexe;
|
|
135
135
|
isexe.sync = sync;
|
|
136
|
-
function isexe(
|
|
136
|
+
function isexe(path17, options, cb) {
|
|
137
137
|
if (typeof options === "function") {
|
|
138
138
|
cb = options;
|
|
139
139
|
options = {};
|
|
@@ -143,7 +143,7 @@ var require_isexe = __commonJS({
|
|
|
143
143
|
throw new TypeError("callback not provided");
|
|
144
144
|
}
|
|
145
145
|
return new Promise(function(resolve2, reject) {
|
|
146
|
-
isexe(
|
|
146
|
+
isexe(path17, options || {}, function(er, is) {
|
|
147
147
|
if (er) {
|
|
148
148
|
reject(er);
|
|
149
149
|
} else {
|
|
@@ -152,7 +152,7 @@ var require_isexe = __commonJS({
|
|
|
152
152
|
});
|
|
153
153
|
});
|
|
154
154
|
}
|
|
155
|
-
core(
|
|
155
|
+
core(path17, options || {}, function(er, is) {
|
|
156
156
|
if (er) {
|
|
157
157
|
if (er.code === "EACCES" || options && options.ignoreErrors) {
|
|
158
158
|
er = null;
|
|
@@ -162,9 +162,9 @@ var require_isexe = __commonJS({
|
|
|
162
162
|
cb(er, is);
|
|
163
163
|
});
|
|
164
164
|
}
|
|
165
|
-
function sync(
|
|
165
|
+
function sync(path17, options) {
|
|
166
166
|
try {
|
|
167
|
-
return core.sync(
|
|
167
|
+
return core.sync(path17, options || {});
|
|
168
168
|
} catch (er) {
|
|
169
169
|
if (options && options.ignoreErrors || er.code === "EACCES") {
|
|
170
170
|
return false;
|
|
@@ -180,7 +180,7 @@ var require_isexe = __commonJS({
|
|
|
180
180
|
var require_which = __commonJS({
|
|
181
181
|
"../node_modules/@earendil-works/pi-coding-agent/node_modules/which/which.js"(exports, module) {
|
|
182
182
|
var isWindows = process.platform === "win32" || process.env.OSTYPE === "cygwin" || process.env.OSTYPE === "msys";
|
|
183
|
-
var
|
|
183
|
+
var path17 = __require("path");
|
|
184
184
|
var COLON = isWindows ? ";" : ":";
|
|
185
185
|
var isexe = require_isexe();
|
|
186
186
|
var getNotFoundError = (cmd) => Object.assign(new Error(`not found: ${cmd}`), { code: "ENOENT" });
|
|
@@ -218,7 +218,7 @@ var require_which = __commonJS({
|
|
|
218
218
|
return opt.all && found.length ? resolve2(found) : reject(getNotFoundError(cmd));
|
|
219
219
|
const ppRaw = pathEnv[i];
|
|
220
220
|
const pathPart = /^".*"$/.test(ppRaw) ? ppRaw.slice(1, -1) : ppRaw;
|
|
221
|
-
const pCmd =
|
|
221
|
+
const pCmd = path17.join(pathPart, cmd);
|
|
222
222
|
const p = !pathPart && /^\.[\\\/]/.test(cmd) ? cmd.slice(0, 2) + pCmd : pCmd;
|
|
223
223
|
resolve2(subStep(p, i, 0));
|
|
224
224
|
});
|
|
@@ -245,7 +245,7 @@ var require_which = __commonJS({
|
|
|
245
245
|
for (let i = 0; i < pathEnv.length; i++) {
|
|
246
246
|
const ppRaw = pathEnv[i];
|
|
247
247
|
const pathPart = /^".*"$/.test(ppRaw) ? ppRaw.slice(1, -1) : ppRaw;
|
|
248
|
-
const pCmd =
|
|
248
|
+
const pCmd = path17.join(pathPart, cmd);
|
|
249
249
|
const p = !pathPart && /^\.[\\\/]/.test(cmd) ? cmd.slice(0, 2) + pCmd : pCmd;
|
|
250
250
|
for (let j2 = 0; j2 < pathExt.length; j2++) {
|
|
251
251
|
const cur = p + pathExt[j2];
|
|
@@ -293,7 +293,7 @@ var require_path_key = __commonJS({
|
|
|
293
293
|
var require_resolveCommand = __commonJS({
|
|
294
294
|
"../node_modules/@earendil-works/pi-coding-agent/node_modules/cross-spawn/lib/util/resolveCommand.js"(exports, module) {
|
|
295
295
|
"use strict";
|
|
296
|
-
var
|
|
296
|
+
var path17 = __require("path");
|
|
297
297
|
var which = require_which();
|
|
298
298
|
var getPathKey = require_path_key();
|
|
299
299
|
function resolveCommandAttempt(parsed, withoutPathExt) {
|
|
@@ -311,7 +311,7 @@ var require_resolveCommand = __commonJS({
|
|
|
311
311
|
try {
|
|
312
312
|
resolved = which.sync(parsed.command, {
|
|
313
313
|
path: env2[getPathKey({ env: env2 })],
|
|
314
|
-
pathExt: withoutPathExt ?
|
|
314
|
+
pathExt: withoutPathExt ? path17.delimiter : void 0
|
|
315
315
|
});
|
|
316
316
|
} catch (e) {
|
|
317
317
|
} finally {
|
|
@@ -320,7 +320,7 @@ var require_resolveCommand = __commonJS({
|
|
|
320
320
|
}
|
|
321
321
|
}
|
|
322
322
|
if (resolved) {
|
|
323
|
-
resolved =
|
|
323
|
+
resolved = path17.resolve(hasCustomCwd ? parsed.options.cwd : "", resolved);
|
|
324
324
|
}
|
|
325
325
|
return resolved;
|
|
326
326
|
}
|
|
@@ -374,8 +374,8 @@ var require_shebang_command = __commonJS({
|
|
|
374
374
|
if (!match) {
|
|
375
375
|
return null;
|
|
376
376
|
}
|
|
377
|
-
const [
|
|
378
|
-
const binary =
|
|
377
|
+
const [path17, argument] = match[0].replace(/#! ?/, "").split(" ");
|
|
378
|
+
const binary = path17.split("/").pop();
|
|
379
379
|
if (binary === "env") {
|
|
380
380
|
return argument;
|
|
381
381
|
}
|
|
@@ -388,16 +388,16 @@ var require_shebang_command = __commonJS({
|
|
|
388
388
|
var require_readShebang = __commonJS({
|
|
389
389
|
"../node_modules/@earendil-works/pi-coding-agent/node_modules/cross-spawn/lib/util/readShebang.js"(exports, module) {
|
|
390
390
|
"use strict";
|
|
391
|
-
var
|
|
391
|
+
var fs15 = __require("fs");
|
|
392
392
|
var shebangCommand = require_shebang_command();
|
|
393
393
|
function readShebang(command) {
|
|
394
394
|
const size = 150;
|
|
395
395
|
const buffer = Buffer.alloc(size);
|
|
396
396
|
let fd;
|
|
397
397
|
try {
|
|
398
|
-
fd =
|
|
399
|
-
|
|
400
|
-
|
|
398
|
+
fd = fs15.openSync(command, "r");
|
|
399
|
+
fs15.readSync(fd, buffer, 0, size, 0);
|
|
400
|
+
fs15.closeSync(fd);
|
|
401
401
|
} catch (e) {
|
|
402
402
|
}
|
|
403
403
|
return shebangCommand(buffer.toString());
|
|
@@ -410,7 +410,7 @@ var require_readShebang = __commonJS({
|
|
|
410
410
|
var require_parse = __commonJS({
|
|
411
411
|
"../node_modules/@earendil-works/pi-coding-agent/node_modules/cross-spawn/lib/parse.js"(exports, module) {
|
|
412
412
|
"use strict";
|
|
413
|
-
var
|
|
413
|
+
var path17 = __require("path");
|
|
414
414
|
var resolveCommand = require_resolveCommand();
|
|
415
415
|
var escape2 = require_escape();
|
|
416
416
|
var readShebang = require_readShebang();
|
|
@@ -435,7 +435,7 @@ var require_parse = __commonJS({
|
|
|
435
435
|
const needsShell = !isExecutableRegExp.test(commandFile);
|
|
436
436
|
if (parsed.options.forceShell || needsShell) {
|
|
437
437
|
const needsDoubleEscapeMetaChars = isCmdShimRegExp.test(commandFile);
|
|
438
|
-
parsed.command =
|
|
438
|
+
parsed.command = path17.normalize(parsed.command);
|
|
439
439
|
parsed.command = escape2.command(parsed.command);
|
|
440
440
|
parsed.args = parsed.args.map((arg) => escape2.argument(arg, needsDoubleEscapeMetaChars));
|
|
441
441
|
const shellCommand = [parsed.command].concat(parsed.args).join(" ");
|
|
@@ -525,21 +525,21 @@ var require_cross_spawn = __commonJS({
|
|
|
525
525
|
var cp = __require("child_process");
|
|
526
526
|
var parse = require_parse();
|
|
527
527
|
var enoent = require_enoent();
|
|
528
|
-
function
|
|
528
|
+
function spawn4(command, args, options) {
|
|
529
529
|
const parsed = parse(command, args, options);
|
|
530
530
|
const spawned = cp.spawn(parsed.command, parsed.args, parsed.options);
|
|
531
531
|
enoent.hookChildProcess(spawned, parsed);
|
|
532
532
|
return spawned;
|
|
533
533
|
}
|
|
534
|
-
function
|
|
534
|
+
function spawnSync2(command, args, options) {
|
|
535
535
|
const parsed = parse(command, args, options);
|
|
536
536
|
const result = cp.spawnSync(parsed.command, parsed.args, parsed.options);
|
|
537
537
|
result.error = result.error || enoent.verifyENOENTSync(result.status, parsed);
|
|
538
538
|
return result;
|
|
539
539
|
}
|
|
540
|
-
module.exports =
|
|
541
|
-
module.exports.spawn =
|
|
542
|
-
module.exports.sync =
|
|
540
|
+
module.exports = spawn4;
|
|
541
|
+
module.exports.spawn = spawn4;
|
|
542
|
+
module.exports.sync = spawnSync2;
|
|
543
543
|
module.exports._parse = parse;
|
|
544
544
|
module.exports._enoent = enoent;
|
|
545
545
|
}
|
|
@@ -36024,33 +36024,33 @@ function renderRichText({
|
|
|
36024
36024
|
container.append(fragment);
|
|
36025
36025
|
}
|
|
36026
36026
|
function makePathFromDrawOPS(data) {
|
|
36027
|
-
const
|
|
36027
|
+
const path17 = new Path2D();
|
|
36028
36028
|
if (!data) {
|
|
36029
|
-
return
|
|
36029
|
+
return path17;
|
|
36030
36030
|
}
|
|
36031
36031
|
for (let i = 0, ii = data.length; i < ii; ) {
|
|
36032
36032
|
switch (data[i++]) {
|
|
36033
36033
|
case DrawOPS.moveTo:
|
|
36034
|
-
|
|
36034
|
+
path17.moveTo(data[i++], data[i++]);
|
|
36035
36035
|
break;
|
|
36036
36036
|
case DrawOPS.lineTo:
|
|
36037
|
-
|
|
36037
|
+
path17.lineTo(data[i++], data[i++]);
|
|
36038
36038
|
break;
|
|
36039
36039
|
case DrawOPS.curveTo:
|
|
36040
|
-
|
|
36040
|
+
path17.bezierCurveTo(data[i++], data[i++], data[i++], data[i++], data[i++], data[i++]);
|
|
36041
36041
|
break;
|
|
36042
36042
|
case DrawOPS.quadraticCurveTo:
|
|
36043
|
-
|
|
36043
|
+
path17.quadraticCurveTo(data[i++], data[i++], data[i++], data[i++]);
|
|
36044
36044
|
break;
|
|
36045
36045
|
case DrawOPS.closePath:
|
|
36046
|
-
|
|
36046
|
+
path17.closePath();
|
|
36047
36047
|
break;
|
|
36048
36048
|
default:
|
|
36049
36049
|
warn(`Unrecognized drawing path operator: ${data[i - 1]}`);
|
|
36050
36050
|
break;
|
|
36051
36051
|
}
|
|
36052
36052
|
}
|
|
36053
|
-
return
|
|
36053
|
+
return path17;
|
|
36054
36054
|
}
|
|
36055
36055
|
function bindEvents(obj, element, names3) {
|
|
36056
36056
|
for (const name of names3) {
|
|
@@ -36158,8 +36158,8 @@ function blend(fg, bg, alpha) {
|
|
|
36158
36158
|
return Math.round(alpha * fg + (1 - alpha) * bg);
|
|
36159
36159
|
}
|
|
36160
36160
|
async function node_utils_fetchData(url) {
|
|
36161
|
-
const
|
|
36162
|
-
const data = await
|
|
36161
|
+
const fs15 = process.getBuiltinModule("fs/promises");
|
|
36162
|
+
const data = await fs15.readFile(url);
|
|
36163
36163
|
return new Uint8Array(data);
|
|
36164
36164
|
}
|
|
36165
36165
|
function convertBlackAndWhiteToRGBA({
|
|
@@ -36798,11 +36798,11 @@ function network_getArrayBuffer(val) {
|
|
|
36798
36798
|
return typeof val !== "string" ? val : stringToBytes(val).buffer;
|
|
36799
36799
|
}
|
|
36800
36800
|
function getReadableStream(url, opts = null) {
|
|
36801
|
-
const
|
|
36801
|
+
const fs15 = process.getBuiltinModule("fs");
|
|
36802
36802
|
const {
|
|
36803
36803
|
Readable
|
|
36804
36804
|
} = process.getBuiltinModule("stream");
|
|
36805
|
-
const readStream =
|
|
36805
|
+
const readStream = fs15.createReadStream(url, opts);
|
|
36806
36806
|
return Readable.toWeb(readStream);
|
|
36807
36807
|
}
|
|
36808
36808
|
function getNetworkStream(url) {
|
|
@@ -48461,11 +48461,11 @@ var init_pdf = __esm({
|
|
|
48461
48461
|
} catch (ex) {
|
|
48462
48462
|
warn(`getPathGenerator - ignoring character: "${ex}".`);
|
|
48463
48463
|
}
|
|
48464
|
-
const
|
|
48464
|
+
const path17 = makePathFromDrawOPS(cmds?.path);
|
|
48465
48465
|
if (!this.fontExtraProperties) {
|
|
48466
48466
|
objs.delete(objId);
|
|
48467
48467
|
}
|
|
48468
|
-
return this.compiledGlyphs[character] =
|
|
48468
|
+
return this.compiledGlyphs[character] = path17;
|
|
48469
48469
|
}
|
|
48470
48470
|
get black() {
|
|
48471
48471
|
return this.#fontData.black;
|
|
@@ -50361,7 +50361,7 @@ fn fs_main(in : VertexOutput) -> @location(0) vec4<f32> {
|
|
|
50361
50361
|
Util.singularValueDecompose2dScale(this.baseTransform, scale);
|
|
50362
50362
|
return [matrixScaleX * scale[0], matrixScaleY * scale[1]];
|
|
50363
50363
|
}
|
|
50364
|
-
drawPattern(owner,
|
|
50364
|
+
drawPattern(owner, path17, useEOFill = false, [n, m2], opIdx) {
|
|
50365
50365
|
const [x0, y0, x1, y1] = this.bbox;
|
|
50366
50366
|
const dependencyTracker = owner.dependencyTracker;
|
|
50367
50367
|
if (dependencyTracker) {
|
|
@@ -50369,9 +50369,9 @@ fn fs_main(in : VertexOutput) -> @location(0) vec4<f32> {
|
|
|
50369
50369
|
}
|
|
50370
50370
|
owner.save();
|
|
50371
50371
|
if (useEOFill) {
|
|
50372
|
-
owner.ctx.clip(
|
|
50372
|
+
owner.ctx.clip(path17, "evenodd");
|
|
50373
50373
|
} else {
|
|
50374
|
-
owner.ctx.clip(
|
|
50374
|
+
owner.ctx.clip(path17);
|
|
50375
50375
|
}
|
|
50376
50376
|
owner.ctx.setTransform(...this.patternBaseMatrix);
|
|
50377
50377
|
owner.ctx.translate(n * this.xstep, m2 * this.ystep);
|
|
@@ -51462,15 +51462,15 @@ fn fs_main(in : VertexOutput) -> @location(0) vec4<f32> {
|
|
|
51462
51462
|
if (hasInnerCutout && maskX0 === layerOffsetX && maskY0 === layerOffsetY && maskX1 === layerOffsetX + layerWidth && maskY1 === layerOffsetY + layerHeight) {
|
|
51463
51463
|
return;
|
|
51464
51464
|
}
|
|
51465
|
-
const
|
|
51466
|
-
|
|
51465
|
+
const path17 = new Path2D();
|
|
51466
|
+
path17.rect(layerOffsetX, layerOffsetY, layerWidth, layerHeight);
|
|
51467
51467
|
if (hasInnerCutout) {
|
|
51468
|
-
|
|
51468
|
+
path17.rect(maskX0, maskY0, maskX1 - maskX0, maskY1 - maskY0);
|
|
51469
51469
|
}
|
|
51470
51470
|
layerCtx.save();
|
|
51471
51471
|
layerCtx.globalAlpha = alpha / 255;
|
|
51472
51472
|
layerCtx.setTransform(1, 0, 0, 1, 0, 0);
|
|
51473
|
-
layerCtx.clip(
|
|
51473
|
+
layerCtx.clip(path17, "evenodd");
|
|
51474
51474
|
layerCtx.globalCompositeOperation = "destination-in";
|
|
51475
51475
|
layerCtx.fillStyle = "#000000";
|
|
51476
51476
|
layerCtx.fillRect(layerOffsetX, layerOffsetY, layerWidth, layerHeight);
|
|
@@ -51528,21 +51528,21 @@ fn fs_main(in : VertexOutput) -> @location(0) vec4<f32> {
|
|
|
51528
51528
|
this._cachedGetSinglePixelWidth = null;
|
|
51529
51529
|
}
|
|
51530
51530
|
constructPath(opIdx, op, data, minMax) {
|
|
51531
|
-
let [
|
|
51531
|
+
let [path17] = data;
|
|
51532
51532
|
if (!minMax) {
|
|
51533
|
-
|
|
51533
|
+
path17 ||= data[0] = new Path2D();
|
|
51534
51534
|
if (op !== OPS.stroke && op !== OPS.closeStroke) {
|
|
51535
51535
|
this.current.tilingPatternDims = null;
|
|
51536
51536
|
}
|
|
51537
|
-
this[op](opIdx,
|
|
51537
|
+
this[op](opIdx, path17);
|
|
51538
51538
|
return;
|
|
51539
51539
|
}
|
|
51540
51540
|
if (this.dependencyTracker !== null) {
|
|
51541
51541
|
const outerExtraSize = op === OPS.stroke ? this.current.lineWidth / 2 : 0;
|
|
51542
51542
|
this.dependencyTracker.resetBBox(opIdx).recordBBox(opIdx, this.ctx, minMax[0] - outerExtraSize, minMax[2] + outerExtraSize, minMax[1] - outerExtraSize, minMax[3] + outerExtraSize).recordDependencies(opIdx, ["transform"]);
|
|
51543
51543
|
}
|
|
51544
|
-
if (!(
|
|
51545
|
-
|
|
51544
|
+
if (!(path17 instanceof Path2D)) {
|
|
51545
|
+
path17 = data[0] = makePathFromDrawOPS(path17);
|
|
51546
51546
|
}
|
|
51547
51547
|
Util.axialAlignedBoundingBox(minMax, getCurrentTransform(this.ctx), this.current.minMax);
|
|
51548
51548
|
const tilingDims = this.current.tilingPatternDims;
|
|
@@ -51554,13 +51554,13 @@ fn fs_main(in : VertexOutput) -> @location(0) vec4<f32> {
|
|
|
51554
51554
|
this.current.fillColor.updatePatternDims(clippedBBox, tilingDims);
|
|
51555
51555
|
}
|
|
51556
51556
|
}
|
|
51557
|
-
this[op](opIdx,
|
|
51557
|
+
this[op](opIdx, path17);
|
|
51558
51558
|
this._pathStartIdx = opIdx;
|
|
51559
51559
|
}
|
|
51560
51560
|
closePath(opIdx) {
|
|
51561
51561
|
this.ctx.closePath();
|
|
51562
51562
|
}
|
|
51563
|
-
stroke(opIdx,
|
|
51563
|
+
stroke(opIdx, path17, consumePath = true) {
|
|
51564
51564
|
const started = consumePath && this.#beginKnockoutElement(this.current.strokeAlpha);
|
|
51565
51565
|
const ctx = this.ctx;
|
|
51566
51566
|
const strokeColor = this.current.strokeColor;
|
|
@@ -51572,26 +51572,26 @@ fn fs_main(in : VertexOutput) -> @location(0) vec4<f32> {
|
|
|
51572
51572
|
ctx.strokeStyle = strokeColor.getPattern(ctx, this, getCurrentTransformInverse(ctx), PathType.STROKE, opIdx);
|
|
51573
51573
|
if (baseTransform) {
|
|
51574
51574
|
const newPath = new Path2D();
|
|
51575
|
-
newPath.addPath(
|
|
51576
|
-
|
|
51575
|
+
newPath.addPath(path17, ctx.getTransform().invertSelf().multiplySelf(baseTransform));
|
|
51576
|
+
path17 = newPath;
|
|
51577
51577
|
}
|
|
51578
|
-
this.rescaleAndStroke(
|
|
51578
|
+
this.rescaleAndStroke(path17, false);
|
|
51579
51579
|
ctx.restore();
|
|
51580
51580
|
} else {
|
|
51581
|
-
this.rescaleAndStroke(
|
|
51581
|
+
this.rescaleAndStroke(path17, true);
|
|
51582
51582
|
}
|
|
51583
51583
|
}
|
|
51584
51584
|
this.dependencyTracker?.recordDependencies(opIdx, Dependencies.stroke);
|
|
51585
51585
|
if (consumePath) {
|
|
51586
|
-
this.consumePath(opIdx,
|
|
51586
|
+
this.consumePath(opIdx, path17, this.current.getClippedPathBoundingBox(PathType.STROKE, getCurrentTransform(this.ctx)));
|
|
51587
51587
|
}
|
|
51588
51588
|
ctx.globalAlpha = this.current.fillAlpha;
|
|
51589
51589
|
this.#endKnockoutElement(started);
|
|
51590
51590
|
}
|
|
51591
|
-
closeStroke(opIdx,
|
|
51592
|
-
this.stroke(opIdx,
|
|
51591
|
+
closeStroke(opIdx, path17) {
|
|
51592
|
+
this.stroke(opIdx, path17);
|
|
51593
51593
|
}
|
|
51594
|
-
fill(opIdx,
|
|
51594
|
+
fill(opIdx, path17, consumePath = true) {
|
|
51595
51595
|
const started = consumePath && this.#beginKnockoutElement(this.current.fillAlpha);
|
|
51596
51596
|
const ctx = this.ctx;
|
|
51597
51597
|
const fillColor = this.current.fillColor;
|
|
@@ -51603,10 +51603,10 @@ fn fs_main(in : VertexOutput) -> @location(0) vec4<f32> {
|
|
|
51603
51603
|
const dims = this.current.tilingPatternDims;
|
|
51604
51604
|
const tileIdx = dims && fillColor.canSkipPatternCanvas(dims);
|
|
51605
51605
|
if (tileIdx) {
|
|
51606
|
-
fillColor.drawPattern(this,
|
|
51606
|
+
fillColor.drawPattern(this, path17, this.pendingEOFill, tileIdx, opIdx);
|
|
51607
51607
|
this.pendingEOFill = false;
|
|
51608
51608
|
if (consumePath) {
|
|
51609
|
-
this.consumePath(opIdx,
|
|
51609
|
+
this.consumePath(opIdx, path17, intersect2);
|
|
51610
51610
|
}
|
|
51611
51611
|
this.current.tilingPatternDims = null;
|
|
51612
51612
|
this.#endKnockoutElement(started);
|
|
@@ -51618,17 +51618,17 @@ fn fs_main(in : VertexOutput) -> @location(0) vec4<f32> {
|
|
|
51618
51618
|
ctx.fillStyle = fillColor.getPattern(ctx, this, getCurrentTransformInverse(ctx), PathType.FILL, opIdx);
|
|
51619
51619
|
if (baseTransform) {
|
|
51620
51620
|
const newPath = new Path2D();
|
|
51621
|
-
newPath.addPath(
|
|
51622
|
-
|
|
51621
|
+
newPath.addPath(path17, ctx.getTransform().invertSelf().multiplySelf(baseTransform));
|
|
51622
|
+
path17 = newPath;
|
|
51623
51623
|
}
|
|
51624
51624
|
needRestore = true;
|
|
51625
51625
|
}
|
|
51626
51626
|
if (this.contentVisible && intersect2 !== null) {
|
|
51627
51627
|
if (this.pendingEOFill) {
|
|
51628
|
-
ctx.fill(
|
|
51628
|
+
ctx.fill(path17, "evenodd");
|
|
51629
51629
|
this.pendingEOFill = false;
|
|
51630
51630
|
} else {
|
|
51631
|
-
ctx.fill(
|
|
51631
|
+
ctx.fill(path17);
|
|
51632
51632
|
}
|
|
51633
51633
|
}
|
|
51634
51634
|
if (needRestore) {
|
|
@@ -51636,38 +51636,38 @@ fn fs_main(in : VertexOutput) -> @location(0) vec4<f32> {
|
|
|
51636
51636
|
this.dependencyTracker?.restore(opIdx);
|
|
51637
51637
|
}
|
|
51638
51638
|
if (consumePath) {
|
|
51639
|
-
this.consumePath(opIdx,
|
|
51639
|
+
this.consumePath(opIdx, path17, intersect2);
|
|
51640
51640
|
}
|
|
51641
51641
|
this.#endKnockoutElement(started);
|
|
51642
51642
|
}
|
|
51643
|
-
eoFill(opIdx,
|
|
51643
|
+
eoFill(opIdx, path17) {
|
|
51644
51644
|
this.pendingEOFill = true;
|
|
51645
|
-
this.fill(opIdx,
|
|
51645
|
+
this.fill(opIdx, path17);
|
|
51646
51646
|
}
|
|
51647
|
-
fillStroke(opIdx,
|
|
51647
|
+
fillStroke(opIdx, path17) {
|
|
51648
51648
|
const started = this.#beginKnockoutElement(Math.min(this.current.fillAlpha, this.current.strokeAlpha));
|
|
51649
|
-
this.fill(opIdx,
|
|
51650
|
-
this.stroke(opIdx,
|
|
51651
|
-
this.consumePath(opIdx,
|
|
51649
|
+
this.fill(opIdx, path17, false);
|
|
51650
|
+
this.stroke(opIdx, path17, false);
|
|
51651
|
+
this.consumePath(opIdx, path17);
|
|
51652
51652
|
this.#endKnockoutElement(started);
|
|
51653
51653
|
}
|
|
51654
|
-
eoFillStroke(opIdx,
|
|
51654
|
+
eoFillStroke(opIdx, path17) {
|
|
51655
51655
|
this.pendingEOFill = true;
|
|
51656
|
-
this.fillStroke(opIdx,
|
|
51656
|
+
this.fillStroke(opIdx, path17);
|
|
51657
51657
|
}
|
|
51658
|
-
closeFillStroke(opIdx,
|
|
51659
|
-
this.fillStroke(opIdx,
|
|
51658
|
+
closeFillStroke(opIdx, path17) {
|
|
51659
|
+
this.fillStroke(opIdx, path17);
|
|
51660
51660
|
}
|
|
51661
|
-
closeEOFillStroke(opIdx,
|
|
51661
|
+
closeEOFillStroke(opIdx, path17) {
|
|
51662
51662
|
this.pendingEOFill = true;
|
|
51663
|
-
this.fillStroke(opIdx,
|
|
51663
|
+
this.fillStroke(opIdx, path17);
|
|
51664
51664
|
}
|
|
51665
|
-
endPath(opIdx,
|
|
51666
|
-
this.consumePath(opIdx,
|
|
51665
|
+
endPath(opIdx, path17) {
|
|
51666
|
+
this.consumePath(opIdx, path17);
|
|
51667
51667
|
}
|
|
51668
|
-
rawFillPath(opIdx,
|
|
51668
|
+
rawFillPath(opIdx, path17) {
|
|
51669
51669
|
const started = this.#beginKnockoutElement(this.current.fillAlpha);
|
|
51670
|
-
this.ctx.fill(
|
|
51670
|
+
this.ctx.fill(path17);
|
|
51671
51671
|
this.dependencyTracker?.recordDependencies(opIdx, Dependencies.rawFillPath).recordOperation(opIdx);
|
|
51672
51672
|
this.#endKnockoutElement(started);
|
|
51673
51673
|
}
|
|
@@ -51706,12 +51706,12 @@ fn fs_main(in : VertexOutput) -> @location(0) vec4<f32> {
|
|
|
51706
51706
|
x: x2,
|
|
51707
51707
|
y: y2,
|
|
51708
51708
|
fontSize,
|
|
51709
|
-
path:
|
|
51709
|
+
path: path17
|
|
51710
51710
|
} of paths) {
|
|
51711
|
-
if (!
|
|
51711
|
+
if (!path17) {
|
|
51712
51712
|
continue;
|
|
51713
51713
|
}
|
|
51714
|
-
newPath.addPath(
|
|
51714
|
+
newPath.addPath(path17, new DOMMatrix(transform).preMultiplySelf(invTransf).translate(x2, y2).scale(fontSize, -fontSize));
|
|
51715
51715
|
}
|
|
51716
51716
|
ctx.clip(newPath);
|
|
51717
51717
|
}
|
|
@@ -51799,9 +51799,9 @@ fn fs_main(in : VertexOutput) -> @location(0) vec4<f32> {
|
|
|
51799
51799
|
this.moveText(opIdx, 0, this.current.leading);
|
|
51800
51800
|
this.dependencyTracker?.recordIncrementalData("moveText", this.dependencyTracker.getSimpleIndex("leading") ?? opIdx);
|
|
51801
51801
|
}
|
|
51802
|
-
#getScaledPath(
|
|
51802
|
+
#getScaledPath(path17, currentTransform, transform) {
|
|
51803
51803
|
const newPath = new Path2D();
|
|
51804
|
-
newPath.addPath(
|
|
51804
|
+
newPath.addPath(path17, new DOMMatrix(transform).invertSelf().multiplySelf(currentTransform));
|
|
51805
51805
|
return newPath;
|
|
51806
51806
|
}
|
|
51807
51807
|
paintChar(opIdx, character, x2, y2, patternFillTransform, patternStrokeTransform) {
|
|
@@ -51814,11 +51814,11 @@ fn fs_main(in : VertexOutput) -> @location(0) vec4<f32> {
|
|
|
51814
51814
|
const isAddToPathSet = !!(textRenderingMode & TextRenderingMode.ADD_TO_PATH_FLAG);
|
|
51815
51815
|
const patternFill = current.patternFill && !font.missingFile;
|
|
51816
51816
|
const patternStroke = current.patternStroke && !font.missingFile;
|
|
51817
|
-
let
|
|
51817
|
+
let path17;
|
|
51818
51818
|
if ((font.disableFontFace || isAddToPathSet || patternFill || patternStroke) && !font.missingFile) {
|
|
51819
|
-
|
|
51819
|
+
path17 = font.getPathGenerator(this.commonObjs, character);
|
|
51820
51820
|
}
|
|
51821
|
-
if (
|
|
51821
|
+
if (path17 && (font.disableFontFace || patternFill || patternStroke)) {
|
|
51822
51822
|
ctx.save();
|
|
51823
51823
|
ctx.translate(x2, y2);
|
|
51824
51824
|
ctx.scale(fontSize, -fontSize);
|
|
@@ -51828,10 +51828,10 @@ fn fs_main(in : VertexOutput) -> @location(0) vec4<f32> {
|
|
|
51828
51828
|
if (patternFillTransform) {
|
|
51829
51829
|
currentTransform = ctx.getTransform();
|
|
51830
51830
|
ctx.setTransform(...patternFillTransform);
|
|
51831
|
-
const scaledPath = this.#getScaledPath(
|
|
51831
|
+
const scaledPath = this.#getScaledPath(path17, currentTransform, patternFillTransform);
|
|
51832
51832
|
ctx.fill(scaledPath);
|
|
51833
51833
|
} else {
|
|
51834
|
-
ctx.fill(
|
|
51834
|
+
ctx.fill(path17);
|
|
51835
51835
|
}
|
|
51836
51836
|
}
|
|
51837
51837
|
if (fillStrokeMode === TextRenderingMode.STROKE || fillStrokeMode === TextRenderingMode.FILL_STROKE) {
|
|
@@ -51848,10 +51848,10 @@ fn fs_main(in : VertexOutput) -> @location(0) vec4<f32> {
|
|
|
51848
51848
|
const transf = Util.transform([a, b2, c, d2, 0, 0], invPatternTransform);
|
|
51849
51849
|
Util.singularValueDecompose2dScale(transf, XY);
|
|
51850
51850
|
ctx.lineWidth *= Math.max(XY[0], XY[1]) / fontSize;
|
|
51851
|
-
ctx.stroke(this.#getScaledPath(
|
|
51851
|
+
ctx.stroke(this.#getScaledPath(path17, currentTransform, patternStrokeTransform));
|
|
51852
51852
|
} else {
|
|
51853
51853
|
ctx.lineWidth /= fontSize;
|
|
51854
|
-
ctx.stroke(
|
|
51854
|
+
ctx.stroke(path17);
|
|
51855
51855
|
}
|
|
51856
51856
|
}
|
|
51857
51857
|
ctx.restore();
|
|
@@ -51874,7 +51874,7 @@ fn fs_main(in : VertexOutput) -> @location(0) vec4<f32> {
|
|
|
51874
51874
|
x: x2,
|
|
51875
51875
|
y: y2,
|
|
51876
51876
|
fontSize,
|
|
51877
|
-
path:
|
|
51877
|
+
path: path17
|
|
51878
51878
|
});
|
|
51879
51879
|
this.dependencyTracker?.recordCharacterBBox(opIdx, ctx, font, fontSize, x2, y2);
|
|
51880
51880
|
}
|
|
@@ -52264,9 +52264,9 @@ fn fs_main(in : VertexOutput) -> @location(0) vec4<f32> {
|
|
|
52264
52264
|
const [x0, y0, x1, y1] = group.bbox;
|
|
52265
52265
|
clip.rect(x0, y0, x1 - x0, y1 - y0);
|
|
52266
52266
|
if (group.matrix) {
|
|
52267
|
-
const
|
|
52268
|
-
|
|
52269
|
-
clip =
|
|
52267
|
+
const path17 = new Path2D();
|
|
52268
|
+
path17.addPath(clip, new DOMMatrix(group.matrix));
|
|
52269
|
+
clip = path17;
|
|
52270
52270
|
}
|
|
52271
52271
|
currentCtx.clip(clip);
|
|
52272
52272
|
}
|
|
@@ -52325,9 +52325,9 @@ fn fs_main(in : VertexOutput) -> @location(0) vec4<f32> {
|
|
|
52325
52325
|
const [x0, y0, x1, y1] = group.bbox;
|
|
52326
52326
|
clip.rect(x0, y0, x1 - x0, y1 - y0);
|
|
52327
52327
|
if (group.matrix) {
|
|
52328
|
-
const
|
|
52329
|
-
|
|
52330
|
-
clip =
|
|
52328
|
+
const path17 = new Path2D();
|
|
52329
|
+
path17.addPath(clip, new DOMMatrix(group.matrix));
|
|
52330
|
+
clip = path17;
|
|
52331
52331
|
}
|
|
52332
52332
|
groupCtx.clip(clip);
|
|
52333
52333
|
}
|
|
@@ -52853,7 +52853,7 @@ fn fs_main(in : VertexOutput) -> @location(0) vec4<f32> {
|
|
|
52853
52853
|
}
|
|
52854
52854
|
endCompat(opIdx) {
|
|
52855
52855
|
}
|
|
52856
|
-
consumePath(opIdx,
|
|
52856
|
+
consumePath(opIdx, path17, clipBox) {
|
|
52857
52857
|
const isEmpty = this.current.isEmptyClip();
|
|
52858
52858
|
if (this.pendingClip) {
|
|
52859
52859
|
this.current.updateClipFromPath();
|
|
@@ -52865,9 +52865,9 @@ fn fs_main(in : VertexOutput) -> @location(0) vec4<f32> {
|
|
|
52865
52865
|
if (this.pendingClip) {
|
|
52866
52866
|
if (!isEmpty) {
|
|
52867
52867
|
if (this.pendingClip === EO_CLIP) {
|
|
52868
|
-
ctx.clip(
|
|
52868
|
+
ctx.clip(path17, "evenodd");
|
|
52869
52869
|
} else {
|
|
52870
|
-
ctx.clip(
|
|
52870
|
+
ctx.clip(path17);
|
|
52871
52871
|
}
|
|
52872
52872
|
}
|
|
52873
52873
|
this.pendingClip = null;
|
|
@@ -52940,7 +52940,7 @@ fn fs_main(in : VertexOutput) -> @location(0) vec4<f32> {
|
|
|
52940
52940
|
}
|
|
52941
52941
|
return this._cachedScaleForStroking;
|
|
52942
52942
|
}
|
|
52943
|
-
rescaleAndStroke(
|
|
52943
|
+
rescaleAndStroke(path17, saveRestore) {
|
|
52944
52944
|
const {
|
|
52945
52945
|
ctx,
|
|
52946
52946
|
current: {
|
|
@@ -52950,7 +52950,7 @@ fn fs_main(in : VertexOutput) -> @location(0) vec4<f32> {
|
|
|
52950
52950
|
const [scaleX, scaleY] = this.getScaleForStroking();
|
|
52951
52951
|
if (scaleX === scaleY) {
|
|
52952
52952
|
ctx.lineWidth = (lineWidth || 1) * scaleX;
|
|
52953
|
-
ctx.stroke(
|
|
52953
|
+
ctx.stroke(path17);
|
|
52954
52954
|
return;
|
|
52955
52955
|
}
|
|
52956
52956
|
const dashes = ctx.getLineDash();
|
|
@@ -52961,7 +52961,7 @@ fn fs_main(in : VertexOutput) -> @location(0) vec4<f32> {
|
|
|
52961
52961
|
SCALE_MATRIX.a = 1 / scaleX;
|
|
52962
52962
|
SCALE_MATRIX.d = 1 / scaleY;
|
|
52963
52963
|
const newPath = new Path2D();
|
|
52964
|
-
newPath.addPath(
|
|
52964
|
+
newPath.addPath(path17, SCALE_MATRIX);
|
|
52965
52965
|
if (dashes.length > 0) {
|
|
52966
52966
|
const scale = Math.max(scaleX, scaleY);
|
|
52967
52967
|
ctx.setLineDash(dashes.map((x2) => x2 / scale));
|
|
@@ -53688,8 +53688,8 @@ fn fs_main(in : VertexOutput) -> @location(0) vec4<f32> {
|
|
|
53688
53688
|
url
|
|
53689
53689
|
} = stream._source;
|
|
53690
53690
|
this._isStreamingSupported = !disableStream;
|
|
53691
|
-
const
|
|
53692
|
-
|
|
53691
|
+
const fs15 = process.getBuiltinModule("fs/promises");
|
|
53692
|
+
fs15.lstat(url).then((stat) => {
|
|
53693
53693
|
const readableStream = getReadableStream(url);
|
|
53694
53694
|
this._reader = readableStream.getReader();
|
|
53695
53695
|
const {
|
|
@@ -64104,11 +64104,11 @@ fn fs_main(in : VertexOutput) -> @location(0) vec4<f32> {
|
|
|
64104
64104
|
};
|
|
64105
64105
|
ContourDrawOutline = class extends InkDrawOutline {
|
|
64106
64106
|
toSVGPath() {
|
|
64107
|
-
let
|
|
64108
|
-
if (!
|
|
64109
|
-
|
|
64107
|
+
let path17 = super.toSVGPath();
|
|
64108
|
+
if (!path17.endsWith("Z")) {
|
|
64109
|
+
path17 += "Z";
|
|
64110
64110
|
}
|
|
64111
|
-
return
|
|
64111
|
+
return path17;
|
|
64112
64112
|
}
|
|
64113
64113
|
};
|
|
64114
64114
|
es_uint8_array_from_base64 = __webpack_require__(5213);
|
|
@@ -66812,7 +66812,7 @@ fn fs_main(in : VertexOutput) -> @location(0) vec4<f32> {
|
|
|
66812
66812
|
}
|
|
66813
66813
|
const drawLayer = textLayerData.drawLayer;
|
|
66814
66814
|
let div = textLayerData.selectionDiv;
|
|
66815
|
-
let
|
|
66815
|
+
let path17 = textLayerData.path;
|
|
66816
66816
|
if (!div) {
|
|
66817
66817
|
const clipPathId = `clip_selection_${_DrawLayer.#selectionId++}`;
|
|
66818
66818
|
div = document.createElement("div");
|
|
@@ -66831,18 +66831,18 @@ fn fs_main(in : VertexOutput) -> @location(0) vec4<f32> {
|
|
|
66831
66831
|
const clipPath = _DrawLayer._svgFactory.createElement("clipPath");
|
|
66832
66832
|
clipPath.setAttribute("id", clipPathId);
|
|
66833
66833
|
clipPath.setAttribute("clipPathUnits", "objectBoundingBox");
|
|
66834
|
-
|
|
66835
|
-
clipPath.append(
|
|
66834
|
+
path17 = _DrawLayer._svgFactory.createElement("path");
|
|
66835
|
+
clipPath.append(path17);
|
|
66836
66836
|
svg.append(clipPath);
|
|
66837
66837
|
div.append(svg);
|
|
66838
|
-
textLayerData.path =
|
|
66838
|
+
textLayerData.path = path17;
|
|
66839
66839
|
textLayerData.selectionDiv = div;
|
|
66840
66840
|
}
|
|
66841
66841
|
if (!div.parentNode && drawLayer.#parent) {
|
|
66842
66842
|
drawLayer.#parent.append(div);
|
|
66843
66843
|
this.#selections.add(div);
|
|
66844
66844
|
}
|
|
66845
|
-
|
|
66845
|
+
path17.setAttribute("d", boxes.join(" "));
|
|
66846
66846
|
}
|
|
66847
66847
|
}
|
|
66848
66848
|
static get _svgFactory() {
|
|
@@ -66889,13 +66889,13 @@ fn fs_main(in : VertexOutput) -> @location(0) vec4<f32> {
|
|
|
66889
66889
|
const root = this.#createSVG();
|
|
66890
66890
|
const defs = _DrawLayer._svgFactory.createElement("defs");
|
|
66891
66891
|
root.append(defs);
|
|
66892
|
-
const
|
|
66893
|
-
defs.append(
|
|
66892
|
+
const path17 = _DrawLayer._svgFactory.createElement("path");
|
|
66893
|
+
defs.append(path17);
|
|
66894
66894
|
const pathId = `path_${id}`;
|
|
66895
|
-
|
|
66896
|
-
|
|
66895
|
+
path17.setAttribute("id", pathId);
|
|
66896
|
+
path17.setAttribute("vector-effect", "non-scaling-stroke");
|
|
66897
66897
|
if (isPathUpdatable) {
|
|
66898
|
-
this.#toUpdate.set(id,
|
|
66898
|
+
this.#toUpdate.set(id, path17);
|
|
66899
66899
|
}
|
|
66900
66900
|
const clipPathId = hasClip ? this.#createClipPath(defs, pathId) : null;
|
|
66901
66901
|
const use = _DrawLayer._svgFactory.createElement("use");
|
|
@@ -66913,11 +66913,11 @@ fn fs_main(in : VertexOutput) -> @location(0) vec4<f32> {
|
|
|
66913
66913
|
const root = this.#createSVG();
|
|
66914
66914
|
const defs = _DrawLayer._svgFactory.createElement("defs");
|
|
66915
66915
|
root.append(defs);
|
|
66916
|
-
const
|
|
66917
|
-
defs.append(
|
|
66916
|
+
const path17 = _DrawLayer._svgFactory.createElement("path");
|
|
66917
|
+
defs.append(path17);
|
|
66918
66918
|
const pathId = `path_${id}`;
|
|
66919
|
-
|
|
66920
|
-
|
|
66919
|
+
path17.setAttribute("id", pathId);
|
|
66920
|
+
path17.setAttribute("vector-effect", "non-scaling-stroke");
|
|
66921
66921
|
let maskId;
|
|
66922
66922
|
if (mustRemoveSelfIntersections) {
|
|
66923
66923
|
const mask = _DrawLayer._svgFactory.createElement("mask");
|
|
@@ -66964,7 +66964,7 @@ fn fs_main(in : VertexOutput) -> @location(0) vec4<f32> {
|
|
|
66964
66964
|
root,
|
|
66965
66965
|
bbox,
|
|
66966
66966
|
rootClass,
|
|
66967
|
-
path:
|
|
66967
|
+
path: path17
|
|
66968
66968
|
} = properties;
|
|
66969
66969
|
const element = typeof elementOrId === "number" ? this.#mapping.get(elementOrId) : elementOrId;
|
|
66970
66970
|
if (!element) {
|
|
@@ -66984,10 +66984,10 @@ fn fs_main(in : VertexOutput) -> @location(0) vec4<f32> {
|
|
|
66984
66984
|
classList.toggle(className, value);
|
|
66985
66985
|
}
|
|
66986
66986
|
}
|
|
66987
|
-
if (
|
|
66987
|
+
if (path17) {
|
|
66988
66988
|
const defs = element.firstElementChild;
|
|
66989
66989
|
const pathElement = defs.firstElementChild;
|
|
66990
|
-
this.#updateProperties(pathElement,
|
|
66990
|
+
this.#updateProperties(pathElement, path17);
|
|
66991
66991
|
}
|
|
66992
66992
|
}
|
|
66993
66993
|
updateParent(id, layer) {
|
|
@@ -67204,7 +67204,7 @@ fn fs_main(in : VertexOutput) -> @location(0) vec4<f32> {
|
|
|
67204
67204
|
|
|
67205
67205
|
// ../server/src/index.ts
|
|
67206
67206
|
import { createHash, timingSafeEqual } from "node:crypto";
|
|
67207
|
-
import
|
|
67207
|
+
import fs14 from "node:fs/promises";
|
|
67208
67208
|
import fastifyStatic from "@fastify/static";
|
|
67209
67209
|
import websocket from "@fastify/websocket";
|
|
67210
67210
|
import Fastify from "fastify";
|
|
@@ -82937,8 +82937,8 @@ var CONFIG_DIR_NAME = pkg.piConfig?.configDir || ".pi";
|
|
|
82937
82937
|
var VERSION = pkg.version || "0.0.0";
|
|
82938
82938
|
var ENV_AGENT_DIR = `${APP_NAME.toUpperCase()}_CODING_AGENT_DIR`;
|
|
82939
82939
|
var ENV_SESSION_DIR = `${APP_NAME.toUpperCase()}_CODING_AGENT_SESSION_DIR`;
|
|
82940
|
-
function expandTildePath(
|
|
82941
|
-
return normalizePath(
|
|
82940
|
+
function expandTildePath(path17) {
|
|
82941
|
+
return normalizePath(path17);
|
|
82942
82942
|
}
|
|
82943
82943
|
function getAgentDir() {
|
|
82944
82944
|
const envDir = process.env[ENV_AGENT_DIR];
|
|
@@ -83287,8 +83287,8 @@ function parseThemeJson(label, json) {
|
|
|
83287
83287
|
}
|
|
83288
83288
|
continue;
|
|
83289
83289
|
}
|
|
83290
|
-
const
|
|
83291
|
-
otherErrors.push(` - ${
|
|
83290
|
+
const path17 = error.instancePath || "/";
|
|
83291
|
+
otherErrors.push(` - ${path17}: ${error.message}`);
|
|
83292
83292
|
}
|
|
83293
83293
|
let errorMessage = `Invalid theme "${label}":
|
|
83294
83294
|
`;
|
|
@@ -84876,18 +84876,18 @@ var RpcRuntime = class {
|
|
|
84876
84876
|
contextEntries() {
|
|
84877
84877
|
const leaf = this.leafId;
|
|
84878
84878
|
if (leaf === null) return [];
|
|
84879
|
-
const
|
|
84879
|
+
const path17 = [];
|
|
84880
84880
|
const walk = (node) => {
|
|
84881
|
-
|
|
84881
|
+
path17.push(node.entry);
|
|
84882
84882
|
if (node.entry.id === leaf) return true;
|
|
84883
84883
|
for (const child of node.children) {
|
|
84884
84884
|
if (walk(child)) return true;
|
|
84885
84885
|
}
|
|
84886
|
-
|
|
84886
|
+
path17.pop();
|
|
84887
84887
|
return false;
|
|
84888
84888
|
};
|
|
84889
84889
|
for (const root of this.treeRoots) {
|
|
84890
|
-
if (walk(root)) return
|
|
84890
|
+
if (walk(root)) return path17;
|
|
84891
84891
|
}
|
|
84892
84892
|
return [];
|
|
84893
84893
|
}
|
|
@@ -90664,6 +90664,7 @@ function loadConfig(launchDir, flags = {}, env2 = process.env) {
|
|
|
90664
90664
|
config2.appendSystemPrompt = optionalStringArray(raw, "appendSystemPrompt") ?? [];
|
|
90665
90665
|
config2.webContext = optionalBoolean(raw, "webContext", true);
|
|
90666
90666
|
config2.offline = optionalBoolean(raw, "offline", false);
|
|
90667
|
+
if (raw.openBrowser !== void 0) config2.openBrowser = optionalBoolean(raw, "openBrowser", true);
|
|
90667
90668
|
if (raw.server !== void 0) {
|
|
90668
90669
|
const server = asObject(raw.server, "server");
|
|
90669
90670
|
if (server.port !== void 0) {
|
|
@@ -97891,7 +97892,7 @@ function createStructuredExchangeToolDefinition(options = {}) {
|
|
|
97891
97892
|
var TOOLS_ENV_VAR = "PI_OUTPOST_TOOLS";
|
|
97892
97893
|
|
|
97893
97894
|
// ../server/src/index.ts
|
|
97894
|
-
import
|
|
97895
|
+
import path16 from "node:path";
|
|
97895
97896
|
|
|
97896
97897
|
// ../server/src/cli.ts
|
|
97897
97898
|
import fs11 from "node:fs";
|
|
@@ -97927,6 +97928,7 @@ Usage
|
|
|
97927
97928
|
pi-outpost config [options] print the configuration that would be used, and where it came from
|
|
97928
97929
|
pi-outpost login --provider <name>
|
|
97929
97930
|
store an API key for a provider in <agentDir>/auth.json
|
|
97931
|
+
pi-outpost build-exe [options] build a standalone executable from this installation
|
|
97930
97932
|
|
|
97931
97933
|
Options
|
|
97932
97934
|
--config <path> configuration file to use
|
|
@@ -97936,6 +97938,8 @@ Options
|
|
|
97936
97938
|
--port <n> port to listen on (default: 3141)
|
|
97937
97939
|
--host <addr> address to bind (default: 127.0.0.1)
|
|
97938
97940
|
--offline never fetch remote model catalogs (air-gapped hosts)
|
|
97941
|
+
--open open the interface in your browser once the server is listening
|
|
97942
|
+
--no-open do not (the default wherever no desktop session exists)
|
|
97939
97943
|
-h, --help show this help
|
|
97940
97944
|
-v, --version show the version
|
|
97941
97945
|
|
|
@@ -97946,6 +97950,14 @@ init options
|
|
|
97946
97950
|
login options
|
|
97947
97951
|
--provider <name> provider to store a key for (e.g. anthropic, openai, mistral)
|
|
97948
97952
|
|
|
97953
|
+
build-exe options
|
|
97954
|
+
--out <path> where to write it (default: ./pi-outpost, ./pi-outpost.exe on Windows)
|
|
97955
|
+
--force replace an existing file at that path
|
|
97956
|
+
|
|
97957
|
+
The executable carries the server and the web UI and needs nothing installed to run.
|
|
97958
|
+
Released builds are attached to https://github.com/laurentftech/pi-outpost/releases \u2014
|
|
97959
|
+
this command is for building one from the version you have.
|
|
97960
|
+
|
|
97949
97961
|
The key itself has no flag, for the same reason the auth token has none: argv is
|
|
97950
97962
|
world-readable. It is prompted for on a terminal, or read from stdin when piped:
|
|
97951
97963
|
echo "$KEY" | pi-outpost login --provider anthropic
|
|
@@ -98010,7 +98022,7 @@ Agent runtime
|
|
|
98010
98022
|
`;
|
|
98011
98023
|
var CliError = class extends Error {
|
|
98012
98024
|
};
|
|
98013
|
-
var COMMANDS = ["init", "config", "login"];
|
|
98025
|
+
var COMMANDS = ["init", "config", "login", "build-exe"];
|
|
98014
98026
|
function integerFlag(value, name) {
|
|
98015
98027
|
if (value === void 0) return void 0;
|
|
98016
98028
|
const parsed = Number(value);
|
|
@@ -98036,6 +98048,9 @@ function parseCli(argv) {
|
|
|
98036
98048
|
global: { type: "boolean", default: false },
|
|
98037
98049
|
force: { type: "boolean", default: false },
|
|
98038
98050
|
provider: { type: "string" },
|
|
98051
|
+
out: { type: "string" },
|
|
98052
|
+
open: { type: "boolean", default: false },
|
|
98053
|
+
"no-open": { type: "boolean", default: false },
|
|
98039
98054
|
help: { type: "boolean", short: "h", default: false },
|
|
98040
98055
|
version: { type: "boolean", short: "v", default: false }
|
|
98041
98056
|
}
|
|
@@ -98051,6 +98066,18 @@ function parseCli(argv) {
|
|
|
98051
98066
|
throw new CliError(`unknown command "${positional}" \u2014 see "pi-outpost --help"`);
|
|
98052
98067
|
}
|
|
98053
98068
|
const command = positional;
|
|
98069
|
+
if (values.out !== void 0 && command !== "build-exe") {
|
|
98070
|
+
throw new CliError('"--out" belongs to "pi-outpost build-exe" \u2014 see "pi-outpost --help"');
|
|
98071
|
+
}
|
|
98072
|
+
if (values.provider !== void 0 && command !== "login") {
|
|
98073
|
+
throw new CliError('"--provider" belongs to "pi-outpost login" \u2014 see "pi-outpost --help"');
|
|
98074
|
+
}
|
|
98075
|
+
if (values.global && command !== "init") {
|
|
98076
|
+
throw new CliError('"--global" belongs to "pi-outpost init" \u2014 see "pi-outpost --help"');
|
|
98077
|
+
}
|
|
98078
|
+
if (values.open && values["no-open"]) {
|
|
98079
|
+
throw new CliError('"--open" and "--no-open" contradict each other \u2014 see "pi-outpost --help"');
|
|
98080
|
+
}
|
|
98054
98081
|
const flags = {
|
|
98055
98082
|
config: values.config,
|
|
98056
98083
|
profile: values.profile,
|
|
@@ -98066,7 +98093,10 @@ function parseCli(argv) {
|
|
|
98066
98093
|
command: kind,
|
|
98067
98094
|
flags,
|
|
98068
98095
|
init: { global: values.global, force: values.force },
|
|
98069
|
-
login: { provider: values.provider }
|
|
98096
|
+
login: { provider: values.provider },
|
|
98097
|
+
buildExe: { out: values.out, force: values.force },
|
|
98098
|
+
// Left undefined unless asked for, so configuration still has its say.
|
|
98099
|
+
...values.open ? { open: true } : values["no-open"] ? { open: false } : {}
|
|
98070
98100
|
};
|
|
98071
98101
|
}
|
|
98072
98102
|
async function readSecret(prompt) {
|
|
@@ -98117,18 +98147,220 @@ function helpText() {
|
|
|
98117
98147
|
return HELP;
|
|
98118
98148
|
}
|
|
98119
98149
|
|
|
98120
|
-
// ../server/src/
|
|
98121
|
-
import {
|
|
98122
|
-
import fs12 from "node:fs
|
|
98150
|
+
// ../server/src/buildExe.ts
|
|
98151
|
+
import { spawnSync } from "node:child_process";
|
|
98152
|
+
import fs12 from "node:fs";
|
|
98153
|
+
import os4 from "node:os";
|
|
98123
98154
|
import path13 from "node:path";
|
|
98155
|
+
function seaConfigFor(main, output) {
|
|
98156
|
+
return { main, output, mainFormat: "module", disableExperimentalSEAWarning: true };
|
|
98157
|
+
}
|
|
98158
|
+
function seaConfigBytes(config2) {
|
|
98159
|
+
return Buffer.from(JSON.stringify(config2, null, 2), "utf8");
|
|
98160
|
+
}
|
|
98161
|
+
function executableName(base, platform = process.platform) {
|
|
98162
|
+
return platform === "win32" ? `${base}.exe` : base;
|
|
98163
|
+
}
|
|
98164
|
+
var MINIMUM_DIRECT_BUILD_MAJOR = 26;
|
|
98165
|
+
function majorOf(version2) {
|
|
98166
|
+
return Number(version2.replace(/^v/, "").split(".")[0]);
|
|
98167
|
+
}
|
|
98168
|
+
function canBuildDirectly(version2 = process.version) {
|
|
98169
|
+
return majorOf(version2) >= MINIMUM_DIRECT_BUILD_MAJOR;
|
|
98170
|
+
}
|
|
98171
|
+
function findBuildInputs(from) {
|
|
98172
|
+
from = from ?? import.meta.dirname;
|
|
98173
|
+
const roots = [from, path13.resolve(from, "../../cli/dist")];
|
|
98174
|
+
const found = {};
|
|
98175
|
+
for (const root of roots) {
|
|
98176
|
+
const bundle = path13.join(root, "pi-outpost.sea.mjs");
|
|
98177
|
+
const blob = path13.join(root, "sea-prep.blob");
|
|
98178
|
+
if (found.bundle === void 0 && fs12.existsSync(bundle)) found.bundle = bundle;
|
|
98179
|
+
if (found.blob === void 0 && fs12.existsSync(blob)) found.blob = blob;
|
|
98180
|
+
}
|
|
98181
|
+
return found;
|
|
98182
|
+
}
|
|
98183
|
+
var BuildExeError = class extends Error {
|
|
98184
|
+
};
|
|
98185
|
+
var FUSE_PARTS = ["NODE", "SEA", "FUSE", "fce680ab2cc467b6", "e072b8b5df1996b2"];
|
|
98186
|
+
var SEA_SENTINEL_FUSE = `${FUSE_PARTS.slice(0, 3).join("_")}_${FUSE_PARTS.slice(3).join("")}`;
|
|
98187
|
+
function carriesSeaSentinel(binary = process.execPath) {
|
|
98188
|
+
const CHUNK = 1 << 20;
|
|
98189
|
+
const overlap = Buffer.byteLength(SEA_SENTINEL_FUSE);
|
|
98190
|
+
const handle = fs12.openSync(binary, "r");
|
|
98191
|
+
try {
|
|
98192
|
+
const buffer = Buffer.alloc(CHUNK + overlap);
|
|
98193
|
+
let position = 0;
|
|
98194
|
+
let carried = 0;
|
|
98195
|
+
for (; ; ) {
|
|
98196
|
+
const read = fs12.readSync(handle, buffer, carried, CHUNK, position);
|
|
98197
|
+
if (read === 0) return false;
|
|
98198
|
+
if (buffer.subarray(0, carried + read).includes(SEA_SENTINEL_FUSE)) return true;
|
|
98199
|
+
buffer.copy(buffer, 0, carried + read - overlap, carried + read);
|
|
98200
|
+
carried = overlap;
|
|
98201
|
+
position += read;
|
|
98202
|
+
}
|
|
98203
|
+
} finally {
|
|
98204
|
+
fs12.closeSync(handle);
|
|
98205
|
+
}
|
|
98206
|
+
}
|
|
98207
|
+
function run(command, args) {
|
|
98208
|
+
const result = spawnSync(command, args, { encoding: "utf8" });
|
|
98209
|
+
const output = `${result.stdout ?? ""}${result.stderr ?? ""}`.trim();
|
|
98210
|
+
if (result.error !== void 0) {
|
|
98211
|
+
const missing = result.error.code === "ENOENT";
|
|
98212
|
+
return { ok: false, output: result.error.message, missing };
|
|
98213
|
+
}
|
|
98214
|
+
return { ok: result.status === 0, output, missing: false };
|
|
98215
|
+
}
|
|
98216
|
+
function resignMacho(target) {
|
|
98217
|
+
run("codesign", ["--remove-signature", target]);
|
|
98218
|
+
const signed = run("codesign", ["--sign", "-", target]);
|
|
98219
|
+
if (signed.missing) {
|
|
98220
|
+
throw new BuildExeError(
|
|
98221
|
+
"codesign is required on macOS to make the executable launchable \u2014 install the Xcode command line tools (xcode-select --install)"
|
|
98222
|
+
);
|
|
98223
|
+
}
|
|
98224
|
+
if (!signed.ok) throw new BuildExeError(`could not sign the executable: ${signed.output}`);
|
|
98225
|
+
}
|
|
98226
|
+
function producedExecutableRuns(target) {
|
|
98227
|
+
const result = spawnSync(target, ["--version"], { encoding: "utf8", timeout: 3e4 });
|
|
98228
|
+
if (result.error !== void 0) return { ok: false, detail: result.error.message };
|
|
98229
|
+
if (result.signal !== null) return { ok: false, detail: `killed by ${result.signal}` };
|
|
98230
|
+
if (result.status !== 0) {
|
|
98231
|
+
return { ok: false, detail: `exited ${result.status}: ${`${result.stdout ?? ""}${result.stderr ?? ""}`.trim()}` };
|
|
98232
|
+
}
|
|
98233
|
+
return { ok: true, detail: (result.stdout ?? "").trim() };
|
|
98234
|
+
}
|
|
98235
|
+
function buildExecutable(options = {}) {
|
|
98236
|
+
const platform = options.platform ?? process.platform;
|
|
98237
|
+
const cwd = options.cwd ?? process.cwd();
|
|
98238
|
+
const log = options.log ?? ((line) => console.log(line));
|
|
98239
|
+
const version2 = options.nodeVersion ?? process.version;
|
|
98240
|
+
const target = path13.resolve(cwd, options.out ?? executableName("pi-outpost", platform));
|
|
98241
|
+
if (fs12.existsSync(target) && options.force !== true) {
|
|
98242
|
+
throw new BuildExeError(`${target} already exists \u2014 pass --force to replace it`);
|
|
98243
|
+
}
|
|
98244
|
+
const { bundle, blob } = findBuildInputs(options.inputsFrom);
|
|
98245
|
+
if (bundle === void 0 && blob === void 0) {
|
|
98246
|
+
throw new BuildExeError(
|
|
98247
|
+
"no build inputs beside this installation \u2014 build an executable from an installed package (npm i pi-outpost) or a clone, not from an executable"
|
|
98248
|
+
);
|
|
98249
|
+
}
|
|
98250
|
+
if (canBuildDirectly(version2) && bundle !== void 0) {
|
|
98251
|
+
const configPath = path13.join(fs12.mkdtempSync(path13.join(os4.tmpdir(), "pi-outpost-sea-")), "sea-config.json");
|
|
98252
|
+
fs12.writeFileSync(configPath, seaConfigBytes(seaConfigFor(bundle, target)));
|
|
98253
|
+
try {
|
|
98254
|
+
log(`[build-exe] building with node --build-sea (node ${version2})`);
|
|
98255
|
+
const built = run(process.execPath, ["--build-sea", configPath]);
|
|
98256
|
+
if (!built.ok) throw new BuildExeError(`node --build-sea failed: ${built.output}`);
|
|
98257
|
+
} finally {
|
|
98258
|
+
fs12.rmSync(path13.dirname(configPath), { recursive: true, force: true });
|
|
98259
|
+
}
|
|
98260
|
+
if (platform === "darwin") resignMacho(target);
|
|
98261
|
+
const verdict = options.skipSmokeTest === true ? { ok: true, detail: "" } : producedExecutableRuns(target);
|
|
98262
|
+
if (verdict.ok) return { path: target, method: "build-sea" };
|
|
98263
|
+
if (blob === void 0 || !carriesSeaSentinel()) {
|
|
98264
|
+
throw new BuildExeError(
|
|
98265
|
+
`built ${target} with node --build-sea but it does not run \u2014 ${verdict.detail}. This runtime's --build-sea is failing, not your configuration; a one-line hello-world built the same way fails the same way.`
|
|
98266
|
+
);
|
|
98267
|
+
}
|
|
98268
|
+
log(`[build-exe] the direct build does not run here (${verdict.detail}) \u2014 falling back to the blob`);
|
|
98269
|
+
fs12.rmSync(target, { force: true });
|
|
98270
|
+
}
|
|
98271
|
+
if (blob === void 0) {
|
|
98272
|
+
throw new BuildExeError(
|
|
98273
|
+
`node ${version2} cannot build directly (needs ${MINIMUM_DIRECT_BUILD_MAJOR} or newer) and sea-prep.blob is missing from this installation`
|
|
98274
|
+
);
|
|
98275
|
+
}
|
|
98276
|
+
if (!carriesSeaSentinel()) {
|
|
98277
|
+
throw new BuildExeError(
|
|
98278
|
+
`this node (${process.execPath}) was built without single-executable support, so a blob cannot be injected into it \u2014 install Node ${MINIMUM_DIRECT_BUILD_MAJOR} or newer and the executable is built directly, with no injection at all`
|
|
98279
|
+
);
|
|
98280
|
+
}
|
|
98281
|
+
if (!canBuildDirectly(version2)) {
|
|
98282
|
+
log(`[build-exe] node ${version2} is older than ${MINIMUM_DIRECT_BUILD_MAJOR} \u2014 injecting sea-prep.blob instead`);
|
|
98283
|
+
}
|
|
98284
|
+
fs12.copyFileSync(process.execPath, target);
|
|
98285
|
+
fs12.chmodSync(target, 493);
|
|
98286
|
+
const injected = run("npx", [
|
|
98287
|
+
"--yes",
|
|
98288
|
+
"postject",
|
|
98289
|
+
target,
|
|
98290
|
+
"NODE_SEA_BLOB",
|
|
98291
|
+
blob,
|
|
98292
|
+
"--sentinel-fuse",
|
|
98293
|
+
SEA_SENTINEL_FUSE,
|
|
98294
|
+
...platform === "darwin" ? ["--macho-segment-name", "NODE_SEA"] : [],
|
|
98295
|
+
"--overwrite"
|
|
98296
|
+
]);
|
|
98297
|
+
if (!injected.ok) {
|
|
98298
|
+
fs12.rmSync(target, { force: true });
|
|
98299
|
+
throw new BuildExeError(`postject failed: ${injected.output}`);
|
|
98300
|
+
}
|
|
98301
|
+
if (platform === "darwin") resignMacho(target);
|
|
98302
|
+
assertItRuns(target, "postject", options);
|
|
98303
|
+
return { path: target, method: "postject" };
|
|
98304
|
+
}
|
|
98305
|
+
function assertItRuns(target, method, options) {
|
|
98306
|
+
if (options.skipSmokeTest === true) return;
|
|
98307
|
+
const verdict = producedExecutableRuns(target);
|
|
98308
|
+
if (verdict.ok) return;
|
|
98309
|
+
throw new BuildExeError(
|
|
98310
|
+
`built ${target} (${method}) but it does not run \u2014 ${verdict.detail}. The file is left in place. This is the runtime's single-executable support failing, not your configuration: a one-line hello-world built the same way will fail the same way, which is worth checking before looking further.`
|
|
98311
|
+
);
|
|
98312
|
+
}
|
|
98313
|
+
|
|
98314
|
+
// ../server/src/openBrowser.ts
|
|
98124
98315
|
import { spawn as spawn2 } from "node:child_process";
|
|
98316
|
+
function shouldOpenBrowser({
|
|
98317
|
+
explicit,
|
|
98318
|
+
configured,
|
|
98319
|
+
platform = process.platform,
|
|
98320
|
+
env: env2 = process.env
|
|
98321
|
+
} = {}) {
|
|
98322
|
+
if (explicit !== void 0) return explicit;
|
|
98323
|
+
if (configured !== void 0) return configured;
|
|
98324
|
+
if (env2.CI !== void 0 && env2.CI !== "" && env2.CI !== "false") return false;
|
|
98325
|
+
if (platform === "darwin" || platform === "win32") return true;
|
|
98326
|
+
return Boolean(env2.DISPLAY ?? env2.WAYLAND_DISPLAY);
|
|
98327
|
+
}
|
|
98328
|
+
function browsableUrl(address) {
|
|
98329
|
+
const host = address.address === "0.0.0.0" || address.address === "::" || address.address === "" ? "127.0.0.1" : address.address;
|
|
98330
|
+
const authority = host.includes(":") ? `[${host}]` : host;
|
|
98331
|
+
return `http://${authority}:${address.port}/`;
|
|
98332
|
+
}
|
|
98333
|
+
function openerFor(platform, url) {
|
|
98334
|
+
if (platform === "darwin") return { command: "open", args: [url] };
|
|
98335
|
+
if (platform === "win32") return { command: "cmd", args: ["/c", "start", "", url] };
|
|
98336
|
+
return { command: "xdg-open", args: [url] };
|
|
98337
|
+
}
|
|
98338
|
+
function openBrowser(url, platform = process.platform) {
|
|
98339
|
+
const { command, args } = openerFor(platform, url);
|
|
98340
|
+
return new Promise((resolve2) => {
|
|
98341
|
+
try {
|
|
98342
|
+
const child = spawn2(command, args, { detached: true, stdio: "ignore" });
|
|
98343
|
+
child.on("error", () => resolve2(false));
|
|
98344
|
+
child.unref();
|
|
98345
|
+
resolve2(true);
|
|
98346
|
+
} catch {
|
|
98347
|
+
resolve2(false);
|
|
98348
|
+
}
|
|
98349
|
+
});
|
|
98350
|
+
}
|
|
98351
|
+
|
|
98352
|
+
// ../server/src/fileBrowser.ts
|
|
98353
|
+
import { constants as constants2 } from "node:fs";
|
|
98354
|
+
import fs13 from "node:fs/promises";
|
|
98355
|
+
import path14 from "node:path";
|
|
98356
|
+
import { spawn as spawn3 } from "node:child_process";
|
|
98125
98357
|
import { randomBytes } from "node:crypto";
|
|
98126
98358
|
var MAX_PREVIEW_BYTES = 1048576;
|
|
98127
98359
|
var MAX_UPLOAD_BYTES = 26214400;
|
|
98128
98360
|
var MAX_UPLOAD_BASE64_LENGTH = Math.ceil(MAX_UPLOAD_BYTES / 3) * 4;
|
|
98129
98361
|
var UPLOADS_DIRECTORY = "uploads";
|
|
98130
98362
|
function isPdfPath(relPath) {
|
|
98131
|
-
return
|
|
98363
|
+
return path14.extname(relPath).toLowerCase() === ".pdf";
|
|
98132
98364
|
}
|
|
98133
98365
|
var FileBrowserError = class extends Error {
|
|
98134
98366
|
constructor(reason, message) {
|
|
@@ -98138,16 +98370,16 @@ var FileBrowserError = class extends Error {
|
|
|
98138
98370
|
reason;
|
|
98139
98371
|
};
|
|
98140
98372
|
async function resolveBrowserRoot(config2) {
|
|
98141
|
-
return
|
|
98373
|
+
return fs13.realpath(config2.sandbox?.root ?? config2.cwd);
|
|
98142
98374
|
}
|
|
98143
98375
|
async function resolveWritableRoot(config2, browserRoot) {
|
|
98144
98376
|
if (!config2.sandbox) return void 0;
|
|
98145
98377
|
if (!config2.sandbox.allowWrite) return null;
|
|
98146
|
-
const target = config2.sandbox.writableRoot ? await
|
|
98147
|
-
return
|
|
98378
|
+
const target = config2.sandbox.writableRoot ? await fs13.realpath(config2.sandbox.writableRoot) : browserRoot;
|
|
98379
|
+
return path14.relative(browserRoot, target).split(path14.sep).join("/");
|
|
98148
98380
|
}
|
|
98149
98381
|
async function resolveConfined(root, relPath) {
|
|
98150
|
-
const target =
|
|
98382
|
+
const target = path14.resolve(root, relPath);
|
|
98151
98383
|
const resolved = await realResolve(target);
|
|
98152
98384
|
if (!isWithin(root, resolved)) {
|
|
98153
98385
|
throw new FileBrowserError("outside-root", `"${relPath}" is outside the browser root`);
|
|
@@ -98165,7 +98397,7 @@ async function listDirectory(root, relPath) {
|
|
|
98165
98397
|
const resolved = await resolveConfined(root, relPath);
|
|
98166
98398
|
let dirents;
|
|
98167
98399
|
try {
|
|
98168
|
-
dirents = await
|
|
98400
|
+
dirents = await fs13.readdir(resolved, { withFileTypes: true });
|
|
98169
98401
|
} catch (error) {
|
|
98170
98402
|
if (error.code === "ENOENT") {
|
|
98171
98403
|
throw new FileBrowserError("not-found", `"${relPath}" does not exist`);
|
|
@@ -98178,7 +98410,7 @@ async function listDirectory(root, relPath) {
|
|
|
98178
98410
|
return { name: dirent.name, type: dirent.isDirectory() ? "directory" : dirent.isFile() ? "file" : "other" };
|
|
98179
98411
|
}
|
|
98180
98412
|
try {
|
|
98181
|
-
const stat = await
|
|
98413
|
+
const stat = await fs13.stat(path14.join(resolved, dirent.name));
|
|
98182
98414
|
return { name: dirent.name, type: classify(dirent, stat.isDirectory() ? "directory" : stat.isFile() ? "file" : "other") };
|
|
98183
98415
|
} catch {
|
|
98184
98416
|
return { name: dirent.name, type: "other" };
|
|
@@ -98200,7 +98432,7 @@ async function readFileForPreview(root, relPath) {
|
|
|
98200
98432
|
const resolved = await resolveConfined(root, relPath);
|
|
98201
98433
|
let stat;
|
|
98202
98434
|
try {
|
|
98203
|
-
stat = await
|
|
98435
|
+
stat = await fs13.stat(resolved);
|
|
98204
98436
|
} catch {
|
|
98205
98437
|
throw new FileBrowserError("not-found", `"${relPath}" does not exist`);
|
|
98206
98438
|
}
|
|
@@ -98211,7 +98443,7 @@ async function readFileForPreview(root, relPath) {
|
|
|
98211
98443
|
const mb = (stat.size / (1024 * 1024)).toFixed(1);
|
|
98212
98444
|
throw new FileBrowserError("too-large", `File is ${mb} MB, larger than the 1 MB preview limit`);
|
|
98213
98445
|
}
|
|
98214
|
-
const buffer = await
|
|
98446
|
+
const buffer = await fs13.readFile(resolved);
|
|
98215
98447
|
if (looksBinary(buffer)) {
|
|
98216
98448
|
throw new FileBrowserError("binary", "Binary file \u2014 preview not supported");
|
|
98217
98449
|
}
|
|
@@ -98221,7 +98453,7 @@ async function readFileRaw(root, relPath, pdfMaxBytes = MAX_PREVIEW_BYTES) {
|
|
|
98221
98453
|
const resolved = await resolveConfined(root, relPath);
|
|
98222
98454
|
let stat;
|
|
98223
98455
|
try {
|
|
98224
|
-
stat = await
|
|
98456
|
+
stat = await fs13.stat(resolved);
|
|
98225
98457
|
} catch {
|
|
98226
98458
|
throw new FileBrowserError("not-found", `"${relPath}" does not exist`);
|
|
98227
98459
|
}
|
|
@@ -98233,7 +98465,7 @@ async function readFileRaw(root, relPath, pdfMaxBytes = MAX_PREVIEW_BYTES) {
|
|
|
98233
98465
|
const mb = (limit / (1024 * 1024)).toFixed(0);
|
|
98234
98466
|
throw new FileBrowserError("too-large", `File is larger than the ${mb} MB limit`);
|
|
98235
98467
|
}
|
|
98236
|
-
return
|
|
98468
|
+
return fs13.readFile(resolved);
|
|
98237
98469
|
}
|
|
98238
98470
|
function assertCreatableName(relPath) {
|
|
98239
98471
|
const name = relPath.split("/").pop() ?? "";
|
|
@@ -98255,7 +98487,7 @@ async function resolveForCreation(root, writableRel, relPath) {
|
|
|
98255
98487
|
throw new FileBrowserError("denied", "The sandbox is read-only");
|
|
98256
98488
|
}
|
|
98257
98489
|
assertCreatableName(relPath);
|
|
98258
|
-
const writableRoot = writableRel === void 0 ? root :
|
|
98490
|
+
const writableRoot = writableRel === void 0 ? root : path14.resolve(root, writableRel);
|
|
98259
98491
|
const resolved = await resolveConfined(root, relPath);
|
|
98260
98492
|
if (!isWithin(writableRoot, resolved)) {
|
|
98261
98493
|
throw new FileBrowserError("denied", `"${relPath}" is outside the writable zone`);
|
|
@@ -98273,17 +98505,17 @@ function creationError(error, relPath) {
|
|
|
98273
98505
|
async function createFileFromBrowser(root, writableRel, relPath) {
|
|
98274
98506
|
const resolved = await resolveForCreation(root, writableRel, relPath);
|
|
98275
98507
|
try {
|
|
98276
|
-
await
|
|
98508
|
+
await fs13.writeFile(resolved, "", { flag: "wx" });
|
|
98277
98509
|
} catch (error) {
|
|
98278
98510
|
throw creationError(error, relPath);
|
|
98279
98511
|
}
|
|
98280
|
-
const stat = await
|
|
98512
|
+
const stat = await fs13.stat(resolved);
|
|
98281
98513
|
return { size: stat.size, mtimeMs: stat.mtimeMs };
|
|
98282
98514
|
}
|
|
98283
98515
|
async function createDirectoryFromBrowser(root, writableRel, relPath) {
|
|
98284
98516
|
const resolved = await resolveForCreation(root, writableRel, relPath);
|
|
98285
98517
|
try {
|
|
98286
|
-
await
|
|
98518
|
+
await fs13.mkdir(resolved);
|
|
98287
98519
|
} catch (error) {
|
|
98288
98520
|
throw creationError(error, relPath);
|
|
98289
98521
|
}
|
|
@@ -98323,7 +98555,7 @@ function assertBase64(content) {
|
|
|
98323
98555
|
}
|
|
98324
98556
|
function suffixed(name, attempt) {
|
|
98325
98557
|
if (attempt === 0) return name;
|
|
98326
|
-
const ext =
|
|
98558
|
+
const ext = path14.extname(name);
|
|
98327
98559
|
return `${name.slice(0, name.length - ext.length)}-${attempt}${ext}`;
|
|
98328
98560
|
}
|
|
98329
98561
|
var MAX_UPLOAD_NAME_ATTEMPTS = 1e3;
|
|
@@ -98332,12 +98564,12 @@ async function uploadFileFromBrowser(root, writableRel, destinationDirectory, na
|
|
|
98332
98564
|
throw new FileBrowserError("denied", "The sandbox is read-only");
|
|
98333
98565
|
}
|
|
98334
98566
|
assertUploadName(name);
|
|
98335
|
-
const writableRoot = writableRel === void 0 ? root :
|
|
98567
|
+
const writableRoot = writableRel === void 0 ? root : path14.resolve(root, writableRel);
|
|
98336
98568
|
const destination = await resolveConfined(root, destinationDirectory);
|
|
98337
98569
|
if (!isWithin(writableRoot, destination)) {
|
|
98338
98570
|
throw new FileBrowserError("denied", `"${destinationDirectory}" is outside the writable zone`);
|
|
98339
98571
|
}
|
|
98340
|
-
if (
|
|
98572
|
+
if (path14.resolve(root, destinationDirectory) !== path14.resolve(writableRoot, UPLOADS_DIRECTORY)) {
|
|
98341
98573
|
throw new FileBrowserError("denied", `Uploads may only be written to "${UPLOADS_DIRECTORY}"`);
|
|
98342
98574
|
}
|
|
98343
98575
|
if (contentBase64.length > MAX_UPLOAD_BASE64_LENGTH) {
|
|
@@ -98349,7 +98581,7 @@ async function uploadFileFromBrowser(root, writableRel, destinationDirectory, na
|
|
|
98349
98581
|
throw new FileBrowserError("too-large", `Uploads are limited to ${MAX_UPLOAD_BYTES / (1024 * 1024)} MB`);
|
|
98350
98582
|
}
|
|
98351
98583
|
try {
|
|
98352
|
-
await
|
|
98584
|
+
await fs13.mkdir(destination, { recursive: true });
|
|
98353
98585
|
} catch (error) {
|
|
98354
98586
|
throw creationError(error, destinationDirectory);
|
|
98355
98587
|
}
|
|
@@ -98357,32 +98589,32 @@ async function uploadFileFromBrowser(root, writableRel, destinationDirectory, na
|
|
|
98357
98589
|
if (!isWithin(root, confirmed) || !isWithin(writableRoot, confirmed)) {
|
|
98358
98590
|
throw new FileBrowserError("outside-root", `"${destinationDirectory}" is outside the browser root`);
|
|
98359
98591
|
}
|
|
98360
|
-
const tmp =
|
|
98592
|
+
const tmp = path14.join(confirmed, `.pi-outpost-upload-${randomBytes(12).toString("hex")}.tmp`);
|
|
98361
98593
|
try {
|
|
98362
98594
|
try {
|
|
98363
|
-
await
|
|
98595
|
+
await fs13.writeFile(tmp, buffer, { flag: "wx" });
|
|
98364
98596
|
} catch (error) {
|
|
98365
98597
|
throw creationError(error, name);
|
|
98366
98598
|
}
|
|
98367
98599
|
for (let attempt = 0; attempt < MAX_UPLOAD_NAME_ATTEMPTS; attempt++) {
|
|
98368
98600
|
const candidate = suffixed(name, attempt);
|
|
98369
|
-
const target =
|
|
98601
|
+
const target = path14.join(confirmed, candidate);
|
|
98370
98602
|
try {
|
|
98371
|
-
await
|
|
98372
|
-
return
|
|
98603
|
+
await fs13.link(tmp, target);
|
|
98604
|
+
return path14.relative(root, target).split(path14.sep).join("/");
|
|
98373
98605
|
} catch (error) {
|
|
98374
98606
|
if (error.code !== "EEXIST") throw creationError(error, candidate);
|
|
98375
98607
|
}
|
|
98376
98608
|
}
|
|
98377
98609
|
throw new FileBrowserError("conflict", `Too many files named "${name}" already`);
|
|
98378
98610
|
} finally {
|
|
98379
|
-
await
|
|
98611
|
+
await fs13.rm(tmp, { force: true }).catch(() => {
|
|
98380
98612
|
});
|
|
98381
98613
|
}
|
|
98382
98614
|
}
|
|
98383
98615
|
async function launchNative(command, args) {
|
|
98384
98616
|
await new Promise((resolve2, reject) => {
|
|
98385
|
-
const child =
|
|
98617
|
+
const child = spawn3(command, args, { shell: false, stdio: "ignore", windowsHide: true });
|
|
98386
98618
|
let settled = false;
|
|
98387
98619
|
child.once("error", (error) => {
|
|
98388
98620
|
if (settled) return;
|
|
@@ -98401,7 +98633,7 @@ async function openFileNative(root, relPath, launcher = launchNative, platform =
|
|
|
98401
98633
|
const resolved = await resolveConfined(root, relPath);
|
|
98402
98634
|
let stat;
|
|
98403
98635
|
try {
|
|
98404
|
-
stat = await
|
|
98636
|
+
stat = await fs13.stat(resolved);
|
|
98405
98637
|
} catch {
|
|
98406
98638
|
throw new FileBrowserError("not-found", `"${relPath}" does not exist`);
|
|
98407
98639
|
}
|
|
@@ -98416,7 +98648,7 @@ async function openFileNative(root, relPath, launcher = launchNative, platform =
|
|
|
98416
98648
|
async function resolveRegularFile(root, relPath) {
|
|
98417
98649
|
const resolved = await resolveConfined(root, relPath);
|
|
98418
98650
|
try {
|
|
98419
|
-
if (!(await
|
|
98651
|
+
if (!(await fs13.lstat(path14.resolve(root, relPath))).isFile()) {
|
|
98420
98652
|
throw new FileBrowserError("not-found", `"${relPath}" is not a regular file`);
|
|
98421
98653
|
}
|
|
98422
98654
|
} catch (error) {
|
|
@@ -98428,7 +98660,7 @@ async function resolveRegularFile(root, relPath) {
|
|
|
98428
98660
|
async function resolveWritableFile(root, writableRel, relPath) {
|
|
98429
98661
|
if (writableRel === null) throw new FileBrowserError("denied", "The sandbox is read-only");
|
|
98430
98662
|
const resolved = await resolveRegularFile(root, relPath);
|
|
98431
|
-
const writableRoot = writableRel === void 0 ? root :
|
|
98663
|
+
const writableRoot = writableRel === void 0 ? root : path14.resolve(root, writableRel);
|
|
98432
98664
|
if (!isWithin(writableRoot, resolved)) {
|
|
98433
98665
|
throw new FileBrowserError("denied", `"${relPath}" is outside the writable zone`);
|
|
98434
98666
|
}
|
|
@@ -98437,12 +98669,12 @@ async function resolveWritableFile(root, writableRel, relPath) {
|
|
|
98437
98669
|
async function resolveWritableDirectory(root, writableRel, relPath) {
|
|
98438
98670
|
if (writableRel === null) throw new FileBrowserError("denied", "The sandbox is read-only");
|
|
98439
98671
|
const resolved = await resolveConfined(root, relPath);
|
|
98440
|
-
const writableRoot = writableRel === void 0 ? root :
|
|
98672
|
+
const writableRoot = writableRel === void 0 ? root : path14.resolve(root, writableRel);
|
|
98441
98673
|
if (!isWithin(writableRoot, resolved)) {
|
|
98442
98674
|
throw new FileBrowserError("denied", `"${relPath}" is outside the writable zone`);
|
|
98443
98675
|
}
|
|
98444
98676
|
try {
|
|
98445
|
-
if (!(await
|
|
98677
|
+
if (!(await fs13.stat(resolved)).isDirectory()) {
|
|
98446
98678
|
throw new FileBrowserError("not-found", `"${relPath}" is not a directory`);
|
|
98447
98679
|
}
|
|
98448
98680
|
} catch (error) {
|
|
@@ -98462,14 +98694,14 @@ function lifecycleError(error, relPath, verb) {
|
|
|
98462
98694
|
}
|
|
98463
98695
|
async function linkThenUnlink(source, destination, destinationRel, verb) {
|
|
98464
98696
|
try {
|
|
98465
|
-
await
|
|
98697
|
+
await fs13.link(source, destination);
|
|
98466
98698
|
} catch (error) {
|
|
98467
98699
|
throw lifecycleError(error, destinationRel, verb);
|
|
98468
98700
|
}
|
|
98469
98701
|
try {
|
|
98470
|
-
await
|
|
98702
|
+
await fs13.unlink(source);
|
|
98471
98703
|
} catch (error) {
|
|
98472
|
-
await
|
|
98704
|
+
await fs13.unlink(destination).catch(() => {
|
|
98473
98705
|
});
|
|
98474
98706
|
throw lifecycleError(error, destinationRel, verb);
|
|
98475
98707
|
}
|
|
@@ -98488,7 +98720,7 @@ async function renameFileFromBrowser(root, writableRel, relPath, name) {
|
|
|
98488
98720
|
async function deleteFileFromBrowser(root, writableRel, relPath) {
|
|
98489
98721
|
const source = await resolveWritableFile(root, writableRel, relPath);
|
|
98490
98722
|
try {
|
|
98491
|
-
await
|
|
98723
|
+
await fs13.unlink(source);
|
|
98492
98724
|
} catch (error) {
|
|
98493
98725
|
throw lifecycleError(error, relPath, "delete");
|
|
98494
98726
|
}
|
|
@@ -98498,7 +98730,7 @@ async function moveFileFromBrowser(root, writableRel, relPath, destinationDirect
|
|
|
98498
98730
|
const destinationDir = await resolveWritableDirectory(root, writableRel, destinationDirectory);
|
|
98499
98731
|
const name = relPath.split("/").pop() ?? "";
|
|
98500
98732
|
const destinationRel = destinationDirectory ? `${destinationDirectory}/${name}` : name;
|
|
98501
|
-
const destination =
|
|
98733
|
+
const destination = path14.join(destinationDir, name);
|
|
98502
98734
|
await resolveConfined(root, destinationRel);
|
|
98503
98735
|
await linkThenUnlink(source, destination, destinationRel, "move");
|
|
98504
98736
|
return destinationRel;
|
|
@@ -98508,10 +98740,10 @@ async function copyFileFromBrowser(root, writableRel, relPath, destinationDirect
|
|
|
98508
98740
|
const destinationDir = await resolveWritableDirectory(root, writableRel, destinationDirectory);
|
|
98509
98741
|
const name = relPath.split("/").pop() ?? "";
|
|
98510
98742
|
const destinationRel = destinationDirectory ? `${destinationDirectory}/${name}` : name;
|
|
98511
|
-
const destination =
|
|
98743
|
+
const destination = path14.join(destinationDir, name);
|
|
98512
98744
|
await resolveConfined(root, destinationRel);
|
|
98513
98745
|
try {
|
|
98514
|
-
await
|
|
98746
|
+
await fs13.copyFile(source, destination, constants2.COPYFILE_EXCL);
|
|
98515
98747
|
} catch (error) {
|
|
98516
98748
|
throw lifecycleError(error, destinationRel, "copy");
|
|
98517
98749
|
}
|
|
@@ -98521,7 +98753,7 @@ async function writeFileFromBrowser(root, writableRel, relPath, content, expecte
|
|
|
98521
98753
|
if (writableRel === null) {
|
|
98522
98754
|
throw new FileBrowserError("denied", "The sandbox is read-only");
|
|
98523
98755
|
}
|
|
98524
|
-
const writableRoot = writableRel === void 0 ? root :
|
|
98756
|
+
const writableRoot = writableRel === void 0 ? root : path14.resolve(root, writableRel);
|
|
98525
98757
|
const resolved = await resolveConfined(root, relPath);
|
|
98526
98758
|
if (!isWithin(writableRoot, resolved)) {
|
|
98527
98759
|
throw new FileBrowserError("denied", `"${relPath}" is outside the writable zone`);
|
|
@@ -98539,7 +98771,7 @@ async function writeFileFromBrowser(root, writableRel, relPath, content, expecte
|
|
|
98539
98771
|
}
|
|
98540
98772
|
let stat;
|
|
98541
98773
|
try {
|
|
98542
|
-
stat = await
|
|
98774
|
+
stat = await fs13.stat(resolved);
|
|
98543
98775
|
} catch {
|
|
98544
98776
|
throw new FileBrowserError("conflict", `"${relPath}" no longer exists`);
|
|
98545
98777
|
}
|
|
@@ -98551,14 +98783,14 @@ async function writeFileFromBrowser(root, writableRel, relPath, content, expecte
|
|
|
98551
98783
|
}
|
|
98552
98784
|
const tmp = `${resolved}.pi-outpost-${randomBytes(12).toString("hex")}.tmp`;
|
|
98553
98785
|
try {
|
|
98554
|
-
await
|
|
98555
|
-
await
|
|
98786
|
+
await fs13.writeFile(tmp, buffer, { mode: stat.mode, flag: "wx" });
|
|
98787
|
+
await fs13.rename(tmp, resolved);
|
|
98556
98788
|
} catch (error) {
|
|
98557
|
-
await
|
|
98789
|
+
await fs13.rm(tmp, { force: true }).catch(() => {
|
|
98558
98790
|
});
|
|
98559
98791
|
throw error;
|
|
98560
98792
|
}
|
|
98561
|
-
const written = await
|
|
98793
|
+
const written = await fs13.stat(resolved);
|
|
98562
98794
|
return { size: written.size, mtimeMs: written.mtimeMs };
|
|
98563
98795
|
}
|
|
98564
98796
|
var SEARCH_IGNORED_NAMES = /* @__PURE__ */ new Set(["node_modules", "dist", "build", ".git", ".next", ".turbo", "__pycache__"]);
|
|
@@ -98572,7 +98804,7 @@ async function searchFiles(root, query, limit = 20) {
|
|
|
98572
98804
|
if (results.length >= limit || visited3 >= SEARCH_MAX_VISITED) return;
|
|
98573
98805
|
let dirents;
|
|
98574
98806
|
try {
|
|
98575
|
-
dirents = await
|
|
98807
|
+
dirents = await fs13.readdir(dir, { withFileTypes: true });
|
|
98576
98808
|
} catch {
|
|
98577
98809
|
return;
|
|
98578
98810
|
}
|
|
@@ -98586,7 +98818,7 @@ async function searchFiles(root, query, limit = 20) {
|
|
|
98586
98818
|
results.push({ path: relPath, type: isDirectory ? "directory" : dirent.isFile() ? "file" : "other" });
|
|
98587
98819
|
}
|
|
98588
98820
|
if (isDirectory) {
|
|
98589
|
-
await walk(
|
|
98821
|
+
await walk(path14.join(dir, dirent.name), relPath);
|
|
98590
98822
|
}
|
|
98591
98823
|
}
|
|
98592
98824
|
}
|
|
@@ -98597,7 +98829,7 @@ async function searchFiles(root, query, limit = 20) {
|
|
|
98597
98829
|
|
|
98598
98830
|
// ../server/src/git.ts
|
|
98599
98831
|
import { execFile } from "node:child_process";
|
|
98600
|
-
import
|
|
98832
|
+
import path15 from "node:path";
|
|
98601
98833
|
import { promisify } from "node:util";
|
|
98602
98834
|
var execFileAsync = promisify(execFile);
|
|
98603
98835
|
var GIT_TIMEOUT_MS = 1e4;
|
|
@@ -98688,13 +98920,13 @@ async function gitStatus(root) {
|
|
|
98688
98920
|
return result;
|
|
98689
98921
|
}
|
|
98690
98922
|
function toToplevelRelative(root, toplevel, relPath) {
|
|
98691
|
-
const prefix =
|
|
98923
|
+
const prefix = path15.relative(toplevel, root).split(path15.sep).join("/");
|
|
98692
98924
|
return prefix === "" ? relPath : `${prefix}/${relPath}`;
|
|
98693
98925
|
}
|
|
98694
98926
|
function toRootRelative(root, toplevel, toplevelRel) {
|
|
98695
|
-
const prefix =
|
|
98927
|
+
const prefix = path15.relative(toplevel, root).split(path15.sep).join("/");
|
|
98696
98928
|
if (prefix === "") return toplevelRel;
|
|
98697
|
-
return
|
|
98929
|
+
return path15.posix.relative(prefix, toplevelRel);
|
|
98698
98930
|
}
|
|
98699
98931
|
async function gitHeadContent(root, toplevel, relPath) {
|
|
98700
98932
|
const toplevelRel = toToplevelRelative(root, toplevel, relPath);
|
|
@@ -99039,7 +99271,7 @@ var EMBEDDED_WEB = {
|
|
|
99039
99271
|
};
|
|
99040
99272
|
|
|
99041
99273
|
// ../server/src/index.ts
|
|
99042
|
-
var VERSION2 = true ? "0.
|
|
99274
|
+
var VERSION2 = true ? "0.11.0" : "dev";
|
|
99043
99275
|
var PI_SDK_VERSION = true ? "0.84.1" : "dev";
|
|
99044
99276
|
var LAUNCH_DIR = process.env.INIT_CWD ?? process.cwd();
|
|
99045
99277
|
function complain(error) {
|
|
@@ -99073,6 +99305,21 @@ if (cli.command === "init") {
|
|
|
99073
99305
|
process.exit(1);
|
|
99074
99306
|
}
|
|
99075
99307
|
}
|
|
99308
|
+
if (cli.command === "build-exe") {
|
|
99309
|
+
try {
|
|
99310
|
+
const built = buildExecutable({ out: cli.buildExe.out, force: cli.buildExe.force, cwd: LAUNCH_DIR });
|
|
99311
|
+
console.log(`[pi] wrote ${built.path} (${built.method})
|
|
99312
|
+
[pi] run it: ${built.path}`);
|
|
99313
|
+
process.exit(0);
|
|
99314
|
+
} catch (error) {
|
|
99315
|
+
if (error instanceof BuildExeError) {
|
|
99316
|
+
console.error(`[pi] ${error.message}`);
|
|
99317
|
+
process.exit(1);
|
|
99318
|
+
}
|
|
99319
|
+
complain(error);
|
|
99320
|
+
process.exit(1);
|
|
99321
|
+
}
|
|
99322
|
+
}
|
|
99076
99323
|
var config = (() => {
|
|
99077
99324
|
try {
|
|
99078
99325
|
return loadConfig(LAUNCH_DIR, cli.flags);
|
|
@@ -99103,7 +99350,7 @@ var PORT = config.port;
|
|
|
99103
99350
|
var HOST = config.host;
|
|
99104
99351
|
var AGENT_CWD = config.cwd;
|
|
99105
99352
|
var AGENT_DIR = config.agentDir ?? getAgentDir2();
|
|
99106
|
-
var SESSION_DIR = config.agentDir ?
|
|
99353
|
+
var SESSION_DIR = config.agentDir ? path16.join(config.agentDir, "sessions") : void 0;
|
|
99107
99354
|
if (cli.command === "login") {
|
|
99108
99355
|
try {
|
|
99109
99356
|
if (!validProviderId(cli.login.provider)) {
|
|
@@ -99260,7 +99507,7 @@ app.get("/files/raw", async (req, reply) => {
|
|
|
99260
99507
|
const bytes = await readFileRaw(BROWSER_ROOT, relPath, config.pdf.maxBytes);
|
|
99261
99508
|
reply.header("X-Content-Type-Options", "nosniff");
|
|
99262
99509
|
reply.header("Cache-Control", "no-store");
|
|
99263
|
-
const contentType = IMAGE_CONTENT_TYPES[
|
|
99510
|
+
const contentType = IMAGE_CONTENT_TYPES[path16.extname(relPath).toLowerCase()];
|
|
99264
99511
|
if (contentType !== void 0) {
|
|
99265
99512
|
if (contentType === "image/svg+xml") {
|
|
99266
99513
|
reply.header("Content-Security-Policy", "default-src 'none'; style-src 'unsafe-inline'");
|
|
@@ -99279,27 +99526,27 @@ app.get("/files/raw", async (req, reply) => {
|
|
|
99279
99526
|
throw error;
|
|
99280
99527
|
}
|
|
99281
99528
|
});
|
|
99282
|
-
var hasIndexHtml = (candidate) =>
|
|
99283
|
-
var skillRoots = [
|
|
99529
|
+
var hasIndexHtml = (candidate) => fs14.stat(path16.join(candidate, "index.html")).then((s) => s.isFile()).catch(() => false);
|
|
99530
|
+
var skillRoots = [path16.resolve(import.meta.dirname, "./skills"), path16.resolve(import.meta.dirname, "../../skills")];
|
|
99284
99531
|
var BUNDLED_SKILLS = [];
|
|
99285
99532
|
for (const root of skillRoots) {
|
|
99286
|
-
const entries = await
|
|
99533
|
+
const entries = await fs14.readdir(root, { withFileTypes: true }).catch(() => []);
|
|
99287
99534
|
for (const entry of entries) {
|
|
99288
99535
|
if (!entry.isDirectory()) continue;
|
|
99289
|
-
const skill =
|
|
99290
|
-
if (await
|
|
99536
|
+
const skill = path16.join(root, entry.name);
|
|
99537
|
+
if (await fs14.stat(path16.join(skill, "SKILL.md")).then((file) => file.isFile()).catch(() => false)) {
|
|
99291
99538
|
BUNDLED_SKILLS.push(skill);
|
|
99292
99539
|
}
|
|
99293
99540
|
}
|
|
99294
99541
|
if (BUNDLED_SKILLS.length > 0) break;
|
|
99295
99542
|
}
|
|
99296
|
-
var webDistCandidates = process.env.PI_OUTPOST_WEB_DIST ? [
|
|
99543
|
+
var webDistCandidates = process.env.PI_OUTPOST_WEB_DIST ? [path16.resolve(process.env.PI_OUTPOST_WEB_DIST)] : [
|
|
99297
99544
|
// Prefer the production build (Vite output) over the source web/ directory,
|
|
99298
99545
|
// which contains a Vite-dev index.html referencing /src/main.tsx — that file
|
|
99299
99546
|
// would be served as application/octet-stream and fail ESM module loading.
|
|
99300
|
-
|
|
99301
|
-
|
|
99302
|
-
|
|
99547
|
+
path16.resolve(import.meta.dirname, "./web/dist"),
|
|
99548
|
+
path16.resolve(import.meta.dirname, "./web"),
|
|
99549
|
+
path16.resolve(import.meta.dirname, "../../web/dist")
|
|
99303
99550
|
];
|
|
99304
99551
|
var WEB_DIST;
|
|
99305
99552
|
for (const candidate of webDistCandidates) {
|
|
@@ -99331,7 +99578,17 @@ if (EMBEDDED_WEB && Object.keys(EMBEDDED_WEB).length > 0) {
|
|
|
99331
99578
|
console.log(`[server] serving web UI from ${WEB_DIST}`);
|
|
99332
99579
|
}
|
|
99333
99580
|
await app.listen({ port: PORT, host: HOST });
|
|
99334
|
-
|
|
99581
|
+
{
|
|
99582
|
+
const bound = app.server.address();
|
|
99583
|
+
const url = typeof bound === "object" && bound !== null ? browsableUrl(bound) : `http://${HOST}:${PORT}/`;
|
|
99584
|
+
console.log(`[server] ${url}`);
|
|
99585
|
+
const servesTheInterface = EMBEDDED_WEB && Object.keys(EMBEDDED_WEB).length > 0 || WEB_DIST !== void 0;
|
|
99586
|
+
if (servesTheInterface && shouldOpenBrowser({ explicit: cli.open, configured: config.openBrowser })) {
|
|
99587
|
+
void openBrowser(url).then((opened) => {
|
|
99588
|
+
if (!opened) console.log(`[server] could not open a browser \u2014 open ${url} yourself`);
|
|
99589
|
+
});
|
|
99590
|
+
}
|
|
99591
|
+
}
|
|
99335
99592
|
var WEB_UI_CONTEXT = [
|
|
99336
99593
|
"You are running inside pi-outpost, a web chat UI \u2014 not a terminal.",
|
|
99337
99594
|
"Replies render as markdown with syntax-highlighted code, LaTeX math and mermaid diagrams.",
|
|
@@ -99410,29 +99667,29 @@ var createRuntime = async ({
|
|
|
99410
99667
|
customTools: [
|
|
99411
99668
|
createPdfExtractToolDefinition({
|
|
99412
99669
|
cwd,
|
|
99413
|
-
allowedRoots: [await
|
|
99670
|
+
allowedRoots: [await fs14.realpath(cwd)],
|
|
99414
99671
|
maxBytes: config.pdf.maxBytes,
|
|
99415
99672
|
// No sandbox: anything under the workspace is writable, the same
|
|
99416
99673
|
// rule writeFileFromBrowser applies to the browser's own writes.
|
|
99417
|
-
writableRoot: await
|
|
99674
|
+
writableRoot: await fs14.realpath(cwd)
|
|
99418
99675
|
}),
|
|
99419
99676
|
createDocxExtractToolDefinition({
|
|
99420
99677
|
cwd,
|
|
99421
|
-
allowedRoots: [await
|
|
99678
|
+
allowedRoots: [await fs14.realpath(cwd)],
|
|
99422
99679
|
maxBytes: config.docx.maxBytes,
|
|
99423
|
-
writableRoot: await
|
|
99680
|
+
writableRoot: await fs14.realpath(cwd)
|
|
99424
99681
|
}),
|
|
99425
99682
|
createXlsxExtractToolDefinition({
|
|
99426
99683
|
cwd,
|
|
99427
|
-
allowedRoots: [await
|
|
99684
|
+
allowedRoots: [await fs14.realpath(cwd)],
|
|
99428
99685
|
maxBytes: config.xlsx.maxBytes,
|
|
99429
|
-
writableRoot: await
|
|
99686
|
+
writableRoot: await fs14.realpath(cwd)
|
|
99430
99687
|
}),
|
|
99431
99688
|
createPptxExtractToolDefinition({
|
|
99432
99689
|
cwd,
|
|
99433
|
-
allowedRoots: [await
|
|
99690
|
+
allowedRoots: [await fs14.realpath(cwd)],
|
|
99434
99691
|
maxBytes: config.pptx.maxBytes,
|
|
99435
|
-
writableRoot: await
|
|
99692
|
+
writableRoot: await fs14.realpath(cwd)
|
|
99436
99693
|
}),
|
|
99437
99694
|
structuredExchangeTool
|
|
99438
99695
|
]
|
|
@@ -99551,11 +99808,11 @@ function snapshot() {
|
|
|
99551
99808
|
};
|
|
99552
99809
|
}
|
|
99553
99810
|
var clients = /* @__PURE__ */ new Set();
|
|
99554
|
-
var WS_LOG_PATH = process.env.WS_LOG_PATH ?
|
|
99811
|
+
var WS_LOG_PATH = process.env.WS_LOG_PATH ? path16.resolve(process.env.WS_LOG_PATH) : void 0;
|
|
99555
99812
|
function broadcast(message) {
|
|
99556
99813
|
const data = JSON.stringify(message);
|
|
99557
99814
|
if (WS_LOG_PATH) {
|
|
99558
|
-
|
|
99815
|
+
fs14.appendFile(WS_LOG_PATH, data + "\n").catch(() => {
|
|
99559
99816
|
});
|
|
99560
99817
|
}
|
|
99561
99818
|
for (const socket of clients) {
|
|
@@ -99565,7 +99822,7 @@ function broadcast(message) {
|
|
|
99565
99822
|
function send(socket, message) {
|
|
99566
99823
|
const data = JSON.stringify(message);
|
|
99567
99824
|
if (WS_LOG_PATH) {
|
|
99568
|
-
|
|
99825
|
+
fs14.appendFile(WS_LOG_PATH, data + "\n").catch(() => {
|
|
99569
99826
|
});
|
|
99570
99827
|
}
|
|
99571
99828
|
if (socket.readyState === socket.OPEN) socket.send(data);
|
|
@@ -99587,12 +99844,12 @@ async function announceFileChange(args) {
|
|
|
99587
99844
|
console.log("[announceFileChange] args type=", typeof args, "targetPath=", targetPath);
|
|
99588
99845
|
if (typeof targetPath !== "string") return;
|
|
99589
99846
|
try {
|
|
99590
|
-
const resolved = await realResolve(
|
|
99847
|
+
const resolved = await realResolve(path16.resolve(BROWSER_ROOT, targetPath));
|
|
99591
99848
|
if (!isWithin(BROWSER_ROOT, resolved)) {
|
|
99592
99849
|
console.log("[announceFileChange] not within BROWSER_ROOT, skipping");
|
|
99593
99850
|
return;
|
|
99594
99851
|
}
|
|
99595
|
-
const relPath =
|
|
99852
|
+
const relPath = path16.relative(BROWSER_ROOT, resolved).split(path16.sep).join("/");
|
|
99596
99853
|
console.log("[announceFileChange] broadcasting file_changed path=", relPath);
|
|
99597
99854
|
broadcast({ type: "file_changed", path: relPath });
|
|
99598
99855
|
} catch (e) {
|
|
@@ -99886,12 +100143,12 @@ async function editPrompt(socket, entryId, text, images) {
|
|
|
99886
100143
|
}
|
|
99887
100144
|
await handlePrompt(text, images);
|
|
99888
100145
|
}
|
|
99889
|
-
async function isKnownSessionPath(
|
|
100146
|
+
async function isKnownSessionPath(path17) {
|
|
99890
100147
|
const sessions = await SessionManager.list(AGENT_CWD, SESSION_DIR);
|
|
99891
|
-
return sessions.some((info2) => info2.path ===
|
|
100148
|
+
return sessions.some((info2) => info2.path === path17);
|
|
99892
100149
|
}
|
|
99893
|
-
async function deleteSession(socket,
|
|
99894
|
-
const live = liveSessionMatch(
|
|
100150
|
+
async function deleteSession(socket, path17) {
|
|
100151
|
+
const live = liveSessionMatch(path17);
|
|
99895
100152
|
if (live === "live") {
|
|
99896
100153
|
send(socket, { type: "error", message: "Cannot delete the active session" });
|
|
99897
100154
|
return;
|
|
@@ -99900,20 +100157,20 @@ async function deleteSession(socket, path16) {
|
|
|
99900
100157
|
send(socket, { type: "error", message: `${UNKNOWN_LIVE_SESSION} \u2014 deleting it could remove the running conversation` });
|
|
99901
100158
|
return;
|
|
99902
100159
|
}
|
|
99903
|
-
if (!await isKnownSessionPath(
|
|
100160
|
+
if (!await isKnownSessionPath(path17)) {
|
|
99904
100161
|
send(socket, { type: "error", message: "Unknown session" });
|
|
99905
100162
|
return;
|
|
99906
100163
|
}
|
|
99907
|
-
await
|
|
100164
|
+
await fs14.unlink(path17);
|
|
99908
100165
|
invalidateSessionScan();
|
|
99909
100166
|
await listSessions(socket);
|
|
99910
100167
|
}
|
|
99911
|
-
async function switchSession(socket,
|
|
99912
|
-
if (!await isKnownSessionPath(
|
|
100168
|
+
async function switchSession(socket, path17) {
|
|
100169
|
+
if (!await isKnownSessionPath(path17)) {
|
|
99913
100170
|
send(socket, { type: "error", message: "Unknown session" });
|
|
99914
100171
|
return;
|
|
99915
100172
|
}
|
|
99916
|
-
await replaceSession(socket, () => runtime.switchSession(
|
|
100173
|
+
await replaceSession(socket, () => runtime.switchSession(path17));
|
|
99917
100174
|
}
|
|
99918
100175
|
var SESSION_LIST_LIMIT = 50;
|
|
99919
100176
|
var SESSION_SCAN_TTL_MS = 1e3;
|
|
@@ -99937,13 +100194,13 @@ async function listSessions(socket) {
|
|
|
99937
100194
|
async function broadcastSessions() {
|
|
99938
100195
|
broadcast({ type: "sessions", sessions: await sessionList() });
|
|
99939
100196
|
}
|
|
99940
|
-
async function renameSession(socket,
|
|
99941
|
-
if (!await isKnownSessionPath(
|
|
100197
|
+
async function renameSession(socket, path17, rawName) {
|
|
100198
|
+
if (!await isKnownSessionPath(path17)) {
|
|
99942
100199
|
send(socket, { type: "error", message: "Unknown session" });
|
|
99943
100200
|
return;
|
|
99944
100201
|
}
|
|
99945
100202
|
const name = sanitizeName(rawName);
|
|
99946
|
-
const live = liveSessionMatch(
|
|
100203
|
+
const live = liveSessionMatch(path17);
|
|
99947
100204
|
if (live === "unknown") {
|
|
99948
100205
|
send(socket, { type: "error", message: `${UNKNOWN_LIVE_SESSION} \u2014 renaming could corrupt the running conversation` });
|
|
99949
100206
|
return;
|
|
@@ -99951,7 +100208,7 @@ async function renameSession(socket, path16, rawName) {
|
|
|
99951
100208
|
if (live === "live") {
|
|
99952
100209
|
await runtime.setSessionName(name);
|
|
99953
100210
|
} else {
|
|
99954
|
-
SessionManager.open(
|
|
100211
|
+
SessionManager.open(path17, SESSION_DIR, AGENT_CWD).appendSessionInfo(name);
|
|
99955
100212
|
}
|
|
99956
100213
|
invalidateSessionScan();
|
|
99957
100214
|
await broadcastSessions();
|
|
@@ -99959,7 +100216,7 @@ async function renameSession(socket, path16, rawName) {
|
|
|
99959
100216
|
function liveSessionMatch(candidate) {
|
|
99960
100217
|
const live = runtime.snapshot().sessionFile;
|
|
99961
100218
|
if (live === void 0) return "unknown";
|
|
99962
|
-
return
|
|
100219
|
+
return path16.resolve(candidate) === path16.resolve(live) ? "live" : "not-live";
|
|
99963
100220
|
}
|
|
99964
100221
|
var UNKNOWN_LIVE_SESSION = "The agent runtime does not report which session file it is using, so this cannot be done safely";
|
|
99965
100222
|
async function handleSearchSessions(socket, query, requestId) {
|