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.
@@ -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 fs14 = __require("fs");
57
- function checkPathExt(path16, options) {
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 && path16.substr(-p.length).toLowerCase() === 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, path16, options) {
74
+ function checkStat(stat, path17, options) {
75
75
  if (!stat.isSymbolicLink() && !stat.isFile()) {
76
76
  return false;
77
77
  }
78
- return checkPathExt(path16, options);
78
+ return checkPathExt(path17, options);
79
79
  }
80
- function isexe(path16, options, cb) {
81
- fs14.stat(path16, function(er, stat) {
82
- cb(er, er ? false : checkStat(stat, path16, options));
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(path16, options) {
86
- return checkStat(fs14.statSync(path16), path16, options);
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 fs14 = __require("fs");
97
- function isexe(path16, options, cb) {
98
- fs14.stat(path16, function(er, stat) {
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(path16, options) {
103
- return checkStat(fs14.statSync(path16), options);
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 fs14 = __require("fs");
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(path16, options, cb) {
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(path16, options || {}, function(er, is) {
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(path16, options || {}, function(er, is) {
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(path16, options) {
165
+ function sync(path17, options) {
166
166
  try {
167
- return core.sync(path16, options || {});
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 path16 = __require("path");
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 = path16.join(pathPart, cmd);
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 = path16.join(pathPart, cmd);
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 path16 = __require("path");
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 ? path16.delimiter : void 0
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 = path16.resolve(hasCustomCwd ? parsed.options.cwd : "", 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 [path16, argument] = match[0].replace(/#! ?/, "").split(" ");
378
- const binary = path16.split("/").pop();
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 fs14 = __require("fs");
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 = fs14.openSync(command, "r");
399
- fs14.readSync(fd, buffer, 0, size, 0);
400
- fs14.closeSync(fd);
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 path16 = __require("path");
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 = path16.normalize(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 spawn3(command, args, options) {
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 spawnSync(command, args, options) {
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 = spawn3;
541
- module.exports.spawn = spawn3;
542
- module.exports.sync = spawnSync;
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 path16 = new Path2D();
36027
+ const path17 = new Path2D();
36028
36028
  if (!data) {
36029
- return path16;
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
- path16.moveTo(data[i++], data[i++]);
36034
+ path17.moveTo(data[i++], data[i++]);
36035
36035
  break;
36036
36036
  case DrawOPS.lineTo:
36037
- path16.lineTo(data[i++], data[i++]);
36037
+ path17.lineTo(data[i++], data[i++]);
36038
36038
  break;
36039
36039
  case DrawOPS.curveTo:
36040
- path16.bezierCurveTo(data[i++], data[i++], data[i++], data[i++], data[i++], data[i++]);
36040
+ path17.bezierCurveTo(data[i++], data[i++], data[i++], data[i++], data[i++], data[i++]);
36041
36041
  break;
36042
36042
  case DrawOPS.quadraticCurveTo:
36043
- path16.quadraticCurveTo(data[i++], data[i++], data[i++], data[i++]);
36043
+ path17.quadraticCurveTo(data[i++], data[i++], data[i++], data[i++]);
36044
36044
  break;
36045
36045
  case DrawOPS.closePath:
36046
- path16.closePath();
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 path16;
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 fs14 = process.getBuiltinModule("fs/promises");
36162
- const data = await fs14.readFile(url);
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 fs14 = process.getBuiltinModule("fs");
36801
+ const fs15 = process.getBuiltinModule("fs");
36802
36802
  const {
36803
36803
  Readable
36804
36804
  } = process.getBuiltinModule("stream");
36805
- const readStream = fs14.createReadStream(url, opts);
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 path16 = makePathFromDrawOPS(cmds?.path);
48464
+ const path17 = makePathFromDrawOPS(cmds?.path);
48465
48465
  if (!this.fontExtraProperties) {
48466
48466
  objs.delete(objId);
48467
48467
  }
48468
- return this.compiledGlyphs[character] = path16;
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, path16, useEOFill = false, [n, m2], opIdx) {
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(path16, "evenodd");
50372
+ owner.ctx.clip(path17, "evenodd");
50373
50373
  } else {
50374
- owner.ctx.clip(path16);
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 path16 = new Path2D();
51466
- path16.rect(layerOffsetX, layerOffsetY, layerWidth, layerHeight);
51465
+ const path17 = new Path2D();
51466
+ path17.rect(layerOffsetX, layerOffsetY, layerWidth, layerHeight);
51467
51467
  if (hasInnerCutout) {
51468
- path16.rect(maskX0, maskY0, maskX1 - maskX0, maskY1 - maskY0);
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(path16, "evenodd");
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 [path16] = data;
51531
+ let [path17] = data;
51532
51532
  if (!minMax) {
51533
- path16 ||= data[0] = new Path2D();
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, path16);
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 (!(path16 instanceof Path2D)) {
51545
- path16 = data[0] = makePathFromDrawOPS(path16);
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, path16);
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, path16, consumePath = true) {
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(path16, ctx.getTransform().invertSelf().multiplySelf(baseTransform));
51576
- path16 = newPath;
51575
+ newPath.addPath(path17, ctx.getTransform().invertSelf().multiplySelf(baseTransform));
51576
+ path17 = newPath;
51577
51577
  }
51578
- this.rescaleAndStroke(path16, false);
51578
+ this.rescaleAndStroke(path17, false);
51579
51579
  ctx.restore();
51580
51580
  } else {
51581
- this.rescaleAndStroke(path16, true);
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, path16, this.current.getClippedPathBoundingBox(PathType.STROKE, getCurrentTransform(this.ctx)));
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, path16) {
51592
- this.stroke(opIdx, path16);
51591
+ closeStroke(opIdx, path17) {
51592
+ this.stroke(opIdx, path17);
51593
51593
  }
51594
- fill(opIdx, path16, consumePath = true) {
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, path16, this.pendingEOFill, tileIdx, opIdx);
51606
+ fillColor.drawPattern(this, path17, this.pendingEOFill, tileIdx, opIdx);
51607
51607
  this.pendingEOFill = false;
51608
51608
  if (consumePath) {
51609
- this.consumePath(opIdx, path16, intersect2);
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(path16, ctx.getTransform().invertSelf().multiplySelf(baseTransform));
51622
- path16 = newPath;
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(path16, "evenodd");
51628
+ ctx.fill(path17, "evenodd");
51629
51629
  this.pendingEOFill = false;
51630
51630
  } else {
51631
- ctx.fill(path16);
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, path16, intersect2);
51639
+ this.consumePath(opIdx, path17, intersect2);
51640
51640
  }
51641
51641
  this.#endKnockoutElement(started);
51642
51642
  }
51643
- eoFill(opIdx, path16) {
51643
+ eoFill(opIdx, path17) {
51644
51644
  this.pendingEOFill = true;
51645
- this.fill(opIdx, path16);
51645
+ this.fill(opIdx, path17);
51646
51646
  }
51647
- fillStroke(opIdx, path16) {
51647
+ fillStroke(opIdx, path17) {
51648
51648
  const started = this.#beginKnockoutElement(Math.min(this.current.fillAlpha, this.current.strokeAlpha));
51649
- this.fill(opIdx, path16, false);
51650
- this.stroke(opIdx, path16, false);
51651
- this.consumePath(opIdx, path16);
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, path16) {
51654
+ eoFillStroke(opIdx, path17) {
51655
51655
  this.pendingEOFill = true;
51656
- this.fillStroke(opIdx, path16);
51656
+ this.fillStroke(opIdx, path17);
51657
51657
  }
51658
- closeFillStroke(opIdx, path16) {
51659
- this.fillStroke(opIdx, path16);
51658
+ closeFillStroke(opIdx, path17) {
51659
+ this.fillStroke(opIdx, path17);
51660
51660
  }
51661
- closeEOFillStroke(opIdx, path16) {
51661
+ closeEOFillStroke(opIdx, path17) {
51662
51662
  this.pendingEOFill = true;
51663
- this.fillStroke(opIdx, path16);
51663
+ this.fillStroke(opIdx, path17);
51664
51664
  }
51665
- endPath(opIdx, path16) {
51666
- this.consumePath(opIdx, path16);
51665
+ endPath(opIdx, path17) {
51666
+ this.consumePath(opIdx, path17);
51667
51667
  }
51668
- rawFillPath(opIdx, path16) {
51668
+ rawFillPath(opIdx, path17) {
51669
51669
  const started = this.#beginKnockoutElement(this.current.fillAlpha);
51670
- this.ctx.fill(path16);
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: path16
51709
+ path: path17
51710
51710
  } of paths) {
51711
- if (!path16) {
51711
+ if (!path17) {
51712
51712
  continue;
51713
51713
  }
51714
- newPath.addPath(path16, new DOMMatrix(transform).preMultiplySelf(invTransf).translate(x2, y2).scale(fontSize, -fontSize));
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(path16, currentTransform, transform) {
51802
+ #getScaledPath(path17, currentTransform, transform) {
51803
51803
  const newPath = new Path2D();
51804
- newPath.addPath(path16, new DOMMatrix(transform).invertSelf().multiplySelf(currentTransform));
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 path16;
51817
+ let path17;
51818
51818
  if ((font.disableFontFace || isAddToPathSet || patternFill || patternStroke) && !font.missingFile) {
51819
- path16 = font.getPathGenerator(this.commonObjs, character);
51819
+ path17 = font.getPathGenerator(this.commonObjs, character);
51820
51820
  }
51821
- if (path16 && (font.disableFontFace || patternFill || patternStroke)) {
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(path16, currentTransform, patternFillTransform);
51831
+ const scaledPath = this.#getScaledPath(path17, currentTransform, patternFillTransform);
51832
51832
  ctx.fill(scaledPath);
51833
51833
  } else {
51834
- ctx.fill(path16);
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(path16, currentTransform, patternStrokeTransform));
51851
+ ctx.stroke(this.#getScaledPath(path17, currentTransform, patternStrokeTransform));
51852
51852
  } else {
51853
51853
  ctx.lineWidth /= fontSize;
51854
- ctx.stroke(path16);
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: path16
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 path16 = new Path2D();
52268
- path16.addPath(clip, new DOMMatrix(group.matrix));
52269
- clip = path16;
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 path16 = new Path2D();
52329
- path16.addPath(clip, new DOMMatrix(group.matrix));
52330
- clip = path16;
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, path16, clipBox) {
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(path16, "evenodd");
52868
+ ctx.clip(path17, "evenodd");
52869
52869
  } else {
52870
- ctx.clip(path16);
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(path16, saveRestore) {
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(path16);
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(path16, SCALE_MATRIX);
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 fs14 = process.getBuiltinModule("fs/promises");
53692
- fs14.lstat(url).then((stat) => {
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 path16 = super.toSVGPath();
64108
- if (!path16.endsWith("Z")) {
64109
- path16 += "Z";
64107
+ let path17 = super.toSVGPath();
64108
+ if (!path17.endsWith("Z")) {
64109
+ path17 += "Z";
64110
64110
  }
64111
- return path16;
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 path16 = textLayerData.path;
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
- path16 = _DrawLayer._svgFactory.createElement("path");
66835
- clipPath.append(path16);
66834
+ path17 = _DrawLayer._svgFactory.createElement("path");
66835
+ clipPath.append(path17);
66836
66836
  svg.append(clipPath);
66837
66837
  div.append(svg);
66838
- textLayerData.path = path16;
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
- path16.setAttribute("d", boxes.join(" "));
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 path16 = _DrawLayer._svgFactory.createElement("path");
66893
- defs.append(path16);
66892
+ const path17 = _DrawLayer._svgFactory.createElement("path");
66893
+ defs.append(path17);
66894
66894
  const pathId = `path_${id}`;
66895
- path16.setAttribute("id", pathId);
66896
- path16.setAttribute("vector-effect", "non-scaling-stroke");
66895
+ path17.setAttribute("id", pathId);
66896
+ path17.setAttribute("vector-effect", "non-scaling-stroke");
66897
66897
  if (isPathUpdatable) {
66898
- this.#toUpdate.set(id, path16);
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 path16 = _DrawLayer._svgFactory.createElement("path");
66917
- defs.append(path16);
66916
+ const path17 = _DrawLayer._svgFactory.createElement("path");
66917
+ defs.append(path17);
66918
66918
  const pathId = `path_${id}`;
66919
- path16.setAttribute("id", pathId);
66920
- path16.setAttribute("vector-effect", "non-scaling-stroke");
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: path16
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 (path16) {
66987
+ if (path17) {
66988
66988
  const defs = element.firstElementChild;
66989
66989
  const pathElement = defs.firstElementChild;
66990
- this.#updateProperties(pathElement, path16);
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 fs13 from "node:fs/promises";
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(path16) {
82941
- return normalizePath(path16);
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 path16 = error.instancePath || "/";
83291
- otherErrors.push(` - ${path16}: ${error.message}`);
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 path16 = [];
84879
+ const path17 = [];
84880
84880
  const walk = (node) => {
84881
- path16.push(node.entry);
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
- path16.pop();
84886
+ path17.pop();
84887
84887
  return false;
84888
84888
  };
84889
84889
  for (const root of this.treeRoots) {
84890
- if (walk(root)) return path16;
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 path15 from "node:path";
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/fileBrowser.ts
98121
- import { constants as constants2 } from "node:fs";
98122
- import fs12 from "node:fs/promises";
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 path13.extname(relPath).toLowerCase() === ".pdf";
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 fs12.realpath(config2.sandbox?.root ?? config2.cwd);
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 fs12.realpath(config2.sandbox.writableRoot) : browserRoot;
98147
- return path13.relative(browserRoot, target).split(path13.sep).join("/");
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 = path13.resolve(root, relPath);
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 fs12.readdir(resolved, { withFileTypes: true });
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 fs12.stat(path13.join(resolved, dirent.name));
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 fs12.stat(resolved);
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 fs12.readFile(resolved);
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 fs12.stat(resolved);
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 fs12.readFile(resolved);
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 : path13.resolve(root, writableRel);
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 fs12.writeFile(resolved, "", { flag: "wx" });
98508
+ await fs13.writeFile(resolved, "", { flag: "wx" });
98277
98509
  } catch (error) {
98278
98510
  throw creationError(error, relPath);
98279
98511
  }
98280
- const stat = await fs12.stat(resolved);
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 fs12.mkdir(resolved);
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 = path13.extname(name);
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 : path13.resolve(root, writableRel);
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 (path13.resolve(root, destinationDirectory) !== path13.resolve(writableRoot, UPLOADS_DIRECTORY)) {
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 fs12.mkdir(destination, { recursive: true });
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 = path13.join(confirmed, `.pi-outpost-upload-${randomBytes(12).toString("hex")}.tmp`);
98592
+ const tmp = path14.join(confirmed, `.pi-outpost-upload-${randomBytes(12).toString("hex")}.tmp`);
98361
98593
  try {
98362
98594
  try {
98363
- await fs12.writeFile(tmp, buffer, { flag: "wx" });
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 = path13.join(confirmed, candidate);
98601
+ const target = path14.join(confirmed, candidate);
98370
98602
  try {
98371
- await fs12.link(tmp, target);
98372
- return path13.relative(root, target).split(path13.sep).join("/");
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 fs12.rm(tmp, { force: true }).catch(() => {
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 = spawn2(command, args, { shell: false, stdio: "ignore", windowsHide: true });
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 fs12.stat(resolved);
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 fs12.lstat(path13.resolve(root, relPath))).isFile()) {
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 : path13.resolve(root, writableRel);
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 : path13.resolve(root, writableRel);
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 fs12.stat(resolved)).isDirectory()) {
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 fs12.link(source, destination);
98697
+ await fs13.link(source, destination);
98466
98698
  } catch (error) {
98467
98699
  throw lifecycleError(error, destinationRel, verb);
98468
98700
  }
98469
98701
  try {
98470
- await fs12.unlink(source);
98702
+ await fs13.unlink(source);
98471
98703
  } catch (error) {
98472
- await fs12.unlink(destination).catch(() => {
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 fs12.unlink(source);
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 = path13.join(destinationDir, name);
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 = path13.join(destinationDir, name);
98743
+ const destination = path14.join(destinationDir, name);
98512
98744
  await resolveConfined(root, destinationRel);
98513
98745
  try {
98514
- await fs12.copyFile(source, destination, constants2.COPYFILE_EXCL);
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 : path13.resolve(root, writableRel);
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 fs12.stat(resolved);
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 fs12.writeFile(tmp, buffer, { mode: stat.mode, flag: "wx" });
98555
- await fs12.rename(tmp, resolved);
98786
+ await fs13.writeFile(tmp, buffer, { mode: stat.mode, flag: "wx" });
98787
+ await fs13.rename(tmp, resolved);
98556
98788
  } catch (error) {
98557
- await fs12.rm(tmp, { force: true }).catch(() => {
98789
+ await fs13.rm(tmp, { force: true }).catch(() => {
98558
98790
  });
98559
98791
  throw error;
98560
98792
  }
98561
- const written = await fs12.stat(resolved);
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 fs12.readdir(dir, { withFileTypes: true });
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(path13.join(dir, dirent.name), relPath);
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 path14 from "node:path";
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 = path14.relative(toplevel, root).split(path14.sep).join("/");
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 = path14.relative(toplevel, root).split(path14.sep).join("/");
98927
+ const prefix = path15.relative(toplevel, root).split(path15.sep).join("/");
98696
98928
  if (prefix === "") return toplevelRel;
98697
- return path14.posix.relative(prefix, toplevelRel);
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.10.0" : "dev";
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 ? path15.join(config.agentDir, "sessions") : void 0;
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[path15.extname(relPath).toLowerCase()];
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) => fs13.stat(path15.join(candidate, "index.html")).then((s) => s.isFile()).catch(() => false);
99283
- var skillRoots = [path15.resolve(import.meta.dirname, "./skills"), path15.resolve(import.meta.dirname, "../../skills")];
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 fs13.readdir(root, { withFileTypes: true }).catch(() => []);
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 = path15.join(root, entry.name);
99290
- if (await fs13.stat(path15.join(skill, "SKILL.md")).then((file) => file.isFile()).catch(() => false)) {
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 ? [path15.resolve(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
- path15.resolve(import.meta.dirname, "./web/dist"),
99301
- path15.resolve(import.meta.dirname, "./web"),
99302
- path15.resolve(import.meta.dirname, "../../web/dist")
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
- console.log(`[server] http://${HOST}:${PORT}/`);
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 fs13.realpath(cwd)],
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 fs13.realpath(cwd)
99674
+ writableRoot: await fs14.realpath(cwd)
99418
99675
  }),
99419
99676
  createDocxExtractToolDefinition({
99420
99677
  cwd,
99421
- allowedRoots: [await fs13.realpath(cwd)],
99678
+ allowedRoots: [await fs14.realpath(cwd)],
99422
99679
  maxBytes: config.docx.maxBytes,
99423
- writableRoot: await fs13.realpath(cwd)
99680
+ writableRoot: await fs14.realpath(cwd)
99424
99681
  }),
99425
99682
  createXlsxExtractToolDefinition({
99426
99683
  cwd,
99427
- allowedRoots: [await fs13.realpath(cwd)],
99684
+ allowedRoots: [await fs14.realpath(cwd)],
99428
99685
  maxBytes: config.xlsx.maxBytes,
99429
- writableRoot: await fs13.realpath(cwd)
99686
+ writableRoot: await fs14.realpath(cwd)
99430
99687
  }),
99431
99688
  createPptxExtractToolDefinition({
99432
99689
  cwd,
99433
- allowedRoots: [await fs13.realpath(cwd)],
99690
+ allowedRoots: [await fs14.realpath(cwd)],
99434
99691
  maxBytes: config.pptx.maxBytes,
99435
- writableRoot: await fs13.realpath(cwd)
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 ? path15.resolve(process.env.WS_LOG_PATH) : void 0;
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
- fs13.appendFile(WS_LOG_PATH, data + "\n").catch(() => {
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
- fs13.appendFile(WS_LOG_PATH, data + "\n").catch(() => {
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(path15.resolve(BROWSER_ROOT, targetPath));
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 = path15.relative(BROWSER_ROOT, resolved).split(path15.sep).join("/");
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(path16) {
100146
+ async function isKnownSessionPath(path17) {
99890
100147
  const sessions = await SessionManager.list(AGENT_CWD, SESSION_DIR);
99891
- return sessions.some((info2) => info2.path === path16);
100148
+ return sessions.some((info2) => info2.path === path17);
99892
100149
  }
99893
- async function deleteSession(socket, path16) {
99894
- const live = liveSessionMatch(path16);
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(path16)) {
100160
+ if (!await isKnownSessionPath(path17)) {
99904
100161
  send(socket, { type: "error", message: "Unknown session" });
99905
100162
  return;
99906
100163
  }
99907
- await fs13.unlink(path16);
100164
+ await fs14.unlink(path17);
99908
100165
  invalidateSessionScan();
99909
100166
  await listSessions(socket);
99910
100167
  }
99911
- async function switchSession(socket, path16) {
99912
- if (!await isKnownSessionPath(path16)) {
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(path16));
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, path16, rawName) {
99941
- if (!await isKnownSessionPath(path16)) {
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(path16);
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(path16, SESSION_DIR, AGENT_CWD).appendSessionInfo(name);
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 path15.resolve(candidate) === path15.resolve(live) ? "live" : "not-live";
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) {