@fangyb/ahchat-bridge 0.1.40 → 0.1.42

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/cli.cjs CHANGED
@@ -269,7 +269,7 @@ var require_errorUtils = __commonJS({
269
269
  var WARNING_MESSAGES = {
270
270
  [types_js_1.OfficeWarningType.PERFORMANCE_TIP]: (tip) => `\u26A1\uFE0F Performance Tip: ${tip}`,
271
271
  [types_js_1.OfficeWarningType.OCR_FAILED]: (name) => `OCR failed for ${name}:`,
272
- [types_js_1.OfficeWarningType.CHART_DATA_EXTRACTION_FAILED]: (path36) => `Failed to extract chart data from ${path36}:`,
272
+ [types_js_1.OfficeWarningType.CHART_DATA_EXTRACTION_FAILED]: (path37) => `Failed to extract chart data from ${path37}:`,
273
273
  [types_js_1.OfficeWarningType.PDF_WORKER_FALLBACK]: `Could not auto-resolve local worker path, falling back to CDN:`,
274
274
  [types_js_1.OfficeWarningType.ATTACHMENT_EXTRACTION_FAILED]: `Error extracting embedded attachments:`,
275
275
  [types_js_1.OfficeWarningType.PAGE_LOAD_FAILED]: (page) => `Error loading page ${page}:`,
@@ -14008,11 +14008,11 @@ var require_defaultOptions2 = __commonJS({
14008
14008
  "../../node_modules/.pnpm/tesseract.js@7.0.0/node_modules/tesseract.js/src/worker/node/defaultOptions.js"(exports2, module2) {
14009
14009
  "use strict";
14010
14010
  init_cjs_shims();
14011
- var path36 = require("path");
14011
+ var path37 = require("path");
14012
14012
  var defaultOptions = require_defaultOptions();
14013
14013
  module2.exports = {
14014
14014
  ...defaultOptions,
14015
- workerPath: path36.join(__dirname, "..", "..", "worker-script", "node", "index.js")
14015
+ workerPath: path37.join(__dirname, "..", "..", "worker-script", "node", "index.js")
14016
14016
  };
14017
14017
  }
14018
14018
  });
@@ -14796,14 +14796,14 @@ var require_url_state_machine = __commonJS({
14796
14796
  return url2.replace(/\u0009|\u000A|\u000D/g, "");
14797
14797
  }
14798
14798
  function shortenPath(url2) {
14799
- const path36 = url2.path;
14800
- if (path36.length === 0) {
14799
+ const path37 = url2.path;
14800
+ if (path37.length === 0) {
14801
14801
  return;
14802
14802
  }
14803
- if (url2.scheme === "file" && path36.length === 1 && isNormalizedWindowsDriveLetter(path36[0])) {
14803
+ if (url2.scheme === "file" && path37.length === 1 && isNormalizedWindowsDriveLetter(path37[0])) {
14804
14804
  return;
14805
14805
  }
14806
- path36.pop();
14806
+ path37.pop();
14807
14807
  }
14808
14808
  function includesCredentials(url2) {
14809
14809
  return url2.username !== "" || url2.password !== "";
@@ -17109,10 +17109,10 @@ var require_loadImage = __commonJS({
17109
17109
  "use strict";
17110
17110
  init_cjs_shims();
17111
17111
  var util = require("util");
17112
- var fs26 = require("fs");
17112
+ var fs27 = require("fs");
17113
17113
  var fetch3 = global.fetch || (init_lib(), __toCommonJS(lib_exports));
17114
17114
  var isURL = require_is_url();
17115
- var readFile3 = util.promisify(fs26.readFile);
17115
+ var readFile3 = util.promisify(fs27.readFile);
17116
17116
  module2.exports = async (image) => {
17117
17117
  let data = image;
17118
17118
  if (typeof image === "undefined") {
@@ -17220,20 +17220,20 @@ var require_createWorker = __commonJS({
17220
17220
  action: "load",
17221
17221
  payload: { options: { lstmOnly: lstmOnlyCore, corePath: options.corePath, logging: options.logging } }
17222
17222
  }));
17223
- const writeText = (path36, text, jobId) => startJob(createJob({
17223
+ const writeText = (path37, text, jobId) => startJob(createJob({
17224
17224
  id: jobId,
17225
17225
  action: "FS",
17226
- payload: { method: "writeFile", args: [path36, text] }
17226
+ payload: { method: "writeFile", args: [path37, text] }
17227
17227
  }));
17228
- const readText = (path36, jobId) => startJob(createJob({
17228
+ const readText = (path37, jobId) => startJob(createJob({
17229
17229
  id: jobId,
17230
17230
  action: "FS",
17231
- payload: { method: "readFile", args: [path36, { encoding: "utf8" }] }
17231
+ payload: { method: "readFile", args: [path37, { encoding: "utf8" }] }
17232
17232
  }));
17233
- const removeFile = (path36, jobId) => startJob(createJob({
17233
+ const removeFile = (path37, jobId) => startJob(createJob({
17234
17234
  id: jobId,
17235
17235
  action: "FS",
17236
- payload: { method: "unlink", args: [path36] }
17236
+ payload: { method: "unlink", args: [path37] }
17237
17237
  }));
17238
17238
  const FS = (method, args, jobId) => startJob(createJob({
17239
17239
  id: jobId,
@@ -17895,8 +17895,8 @@ var require_zipUtils = __commonJS({
17895
17895
  (0, fflate_1.unzip)(new Uint8Array(zipInput.buffer, zipInput.byteOffset, zipInput.byteLength), { filter: (file2) => filterFn(file2.name) }, (err, decompressed) => {
17896
17896
  if (err)
17897
17897
  return reject(err);
17898
- resolve(Object.entries(decompressed).map(([path36, data]) => ({
17899
- path: path36,
17898
+ resolve(Object.entries(decompressed).map(([path37, data]) => ({
17899
+ path: path37,
17900
17900
  content: Buffer.from(data)
17901
17901
  })));
17902
17902
  });
@@ -24266,8 +24266,8 @@ async function fileTypeFromTokenizer(tokenizer, options) {
24266
24266
  async function fileTypeStream(webStream, options) {
24267
24267
  return new FileTypeParser(options).toDetectionStream(webStream, options);
24268
24268
  }
24269
- async function fileTypeFromFile(path36, options) {
24270
- return new FileTypeParser(options).fromFile(path36);
24269
+ async function fileTypeFromFile(path37, options) {
24270
+ return new FileTypeParser(options).fromFile(path37);
24271
24271
  }
24272
24272
  var reasonableDetectionSizeInBytes, maximumMpegOffsetTolerance, maximumNestedGzipDetectionSizeInBytes, maximumNestedGzipProbeDepth, unknownSizeGzipProbeTimeoutInMilliseconds, maximumId3HeaderSizeInBytes, maximumTiffTagCount, maximumDetectionReentryCount, maximumTiffStreamIfdOffsetInBytes, maximumTiffIfdOffsetInBytes, FileTypeParser, supportedExtensions, supportedMimeTypes;
24273
24273
  var init_source = __esm({
@@ -24371,13 +24371,13 @@ var init_source = __esm({
24371
24371
  const tokenizer = this.createTokenizerFromWebStream(stream);
24372
24372
  return this.fromTokenizer(tokenizer);
24373
24373
  }
24374
- async fromFile(path36) {
24374
+ async fromFile(path37) {
24375
24375
  this.options.signal?.throwIfAborted();
24376
24376
  const [{ default: fsPromises }, { FileTokenizer }] = await Promise.all([
24377
24377
  importAtRuntime("node:fs/promises"),
24378
24378
  importAtRuntime("strtok3")
24379
24379
  ]);
24380
- const fileHandle = await fsPromises.open(path36, fsPromises.constants.O_RDONLY | fsPromises.constants.O_NONBLOCK);
24380
+ const fileHandle = await fsPromises.open(path37, fsPromises.constants.O_RDONLY | fsPromises.constants.O_NONBLOCK);
24381
24381
  const fileStat = await fileHandle.stat();
24382
24382
  if (!fileStat.isFile()) {
24383
24383
  await fileHandle.close();
@@ -24385,7 +24385,7 @@ var init_source = __esm({
24385
24385
  }
24386
24386
  const tokenizer = new FileTokenizer(fileHandle, {
24387
24387
  ...this.getTokenizerOptions(),
24388
- fileInfo: { path: path36, size: fileStat.size }
24388
+ fileInfo: { path: path37, size: fileStat.size }
24389
24389
  });
24390
24390
  return this.fromTokenizer(tokenizer);
24391
24391
  }
@@ -26267,33 +26267,33 @@ function renderRichText({
26267
26267
  container.append(fragment);
26268
26268
  }
26269
26269
  function makePathFromDrawOPS(data) {
26270
- const path36 = new Path2D();
26270
+ const path37 = new Path2D();
26271
26271
  if (!data) {
26272
- return path36;
26272
+ return path37;
26273
26273
  }
26274
26274
  for (let i = 0, ii = data.length; i < ii; ) {
26275
26275
  switch (data[i++]) {
26276
26276
  case DrawOPS.moveTo:
26277
- path36.moveTo(data[i++], data[i++]);
26277
+ path37.moveTo(data[i++], data[i++]);
26278
26278
  break;
26279
26279
  case DrawOPS.lineTo:
26280
- path36.lineTo(data[i++], data[i++]);
26280
+ path37.lineTo(data[i++], data[i++]);
26281
26281
  break;
26282
26282
  case DrawOPS.curveTo:
26283
- path36.bezierCurveTo(data[i++], data[i++], data[i++], data[i++], data[i++], data[i++]);
26283
+ path37.bezierCurveTo(data[i++], data[i++], data[i++], data[i++], data[i++], data[i++]);
26284
26284
  break;
26285
26285
  case DrawOPS.quadraticCurveTo:
26286
- path36.quadraticCurveTo(data[i++], data[i++], data[i++], data[i++]);
26286
+ path37.quadraticCurveTo(data[i++], data[i++], data[i++], data[i++]);
26287
26287
  break;
26288
26288
  case DrawOPS.closePath:
26289
- path36.closePath();
26289
+ path37.closePath();
26290
26290
  break;
26291
26291
  default:
26292
26292
  warn(`Unrecognized drawing path operator: ${data[i - 1]}`);
26293
26293
  break;
26294
26294
  }
26295
26295
  }
26296
- return path36;
26296
+ return path37;
26297
26297
  }
26298
26298
  function bindEvents(obj, element, names) {
26299
26299
  for (const name of names) {
@@ -26373,8 +26373,8 @@ function wrapReason(ex) {
26373
26373
  return new UnknownErrorException(ex.message, ex.toString());
26374
26374
  }
26375
26375
  async function node_utils_fetchData(url2) {
26376
- const fs26 = process.getBuiltinModule("fs");
26377
- const data = await fs26.promises.readFile(url2);
26376
+ const fs27 = process.getBuiltinModule("fs");
26377
+ const data = await fs27.promises.readFile(url2);
26378
26378
  return new Uint8Array(data);
26379
26379
  }
26380
26380
  function initWebGPUMesh() {
@@ -34466,11 +34466,11 @@ var init_pdf = __esm({
34466
34466
  } catch (ex) {
34467
34467
  warn(`getPathGenerator - ignoring character: "${ex}".`);
34468
34468
  }
34469
- const path36 = makePathFromDrawOPS(cmds?.path);
34469
+ const path37 = makePathFromDrawOPS(cmds?.path);
34470
34470
  if (!this.fontExtraProperties) {
34471
34471
  objs.delete(objId);
34472
34472
  }
34473
- return this.compiledGlyphs[character] = path36;
34473
+ return this.compiledGlyphs[character] = path37;
34474
34474
  }
34475
34475
  get black() {
34476
34476
  return this.#fontData.black;
@@ -37112,27 +37112,27 @@ fn fs_main(in : VertexOutput) -> @location(0) vec4<f32> {
37112
37112
  this._cachedGetSinglePixelWidth = null;
37113
37113
  }
37114
37114
  constructPath(opIdx, op, data, minMax) {
37115
- let [path36] = data;
37115
+ let [path37] = data;
37116
37116
  if (!minMax) {
37117
- path36 ||= data[0] = new Path2D();
37118
- this[op](opIdx, path36);
37117
+ path37 ||= data[0] = new Path2D();
37118
+ this[op](opIdx, path37);
37119
37119
  return;
37120
37120
  }
37121
37121
  if (this.dependencyTracker !== null) {
37122
37122
  const outerExtraSize = op === OPS.stroke ? this.current.lineWidth / 2 : 0;
37123
37123
  this.dependencyTracker.resetBBox(opIdx).recordBBox(opIdx, this.ctx, minMax[0] - outerExtraSize, minMax[2] + outerExtraSize, minMax[1] - outerExtraSize, minMax[3] + outerExtraSize).recordDependencies(opIdx, ["transform"]);
37124
37124
  }
37125
- if (!(path36 instanceof Path2D)) {
37126
- path36 = data[0] = makePathFromDrawOPS(path36);
37125
+ if (!(path37 instanceof Path2D)) {
37126
+ path37 = data[0] = makePathFromDrawOPS(path37);
37127
37127
  }
37128
37128
  Util.axialAlignedBoundingBox(minMax, getCurrentTransform(this.ctx), this.current.minMax);
37129
- this[op](opIdx, path36);
37129
+ this[op](opIdx, path37);
37130
37130
  this._pathStartIdx = opIdx;
37131
37131
  }
37132
37132
  closePath(opIdx) {
37133
37133
  this.ctx.closePath();
37134
37134
  }
37135
- stroke(opIdx, path36, consumePath = true) {
37135
+ stroke(opIdx, path37, consumePath = true) {
37136
37136
  const ctx = this.ctx;
37137
37137
  const strokeColor = this.current.strokeColor;
37138
37138
  ctx.globalAlpha = this.current.strokeAlpha;
@@ -37143,25 +37143,25 @@ fn fs_main(in : VertexOutput) -> @location(0) vec4<f32> {
37143
37143
  ctx.strokeStyle = strokeColor.getPattern(ctx, this, getCurrentTransformInverse(ctx), PathType.STROKE, opIdx);
37144
37144
  if (baseTransform) {
37145
37145
  const newPath = new Path2D();
37146
- newPath.addPath(path36, ctx.getTransform().invertSelf().multiplySelf(baseTransform));
37147
- path36 = newPath;
37146
+ newPath.addPath(path37, ctx.getTransform().invertSelf().multiplySelf(baseTransform));
37147
+ path37 = newPath;
37148
37148
  }
37149
- this.rescaleAndStroke(path36, false);
37149
+ this.rescaleAndStroke(path37, false);
37150
37150
  ctx.restore();
37151
37151
  } else {
37152
- this.rescaleAndStroke(path36, true);
37152
+ this.rescaleAndStroke(path37, true);
37153
37153
  }
37154
37154
  }
37155
37155
  this.dependencyTracker?.recordDependencies(opIdx, Dependencies.stroke);
37156
37156
  if (consumePath) {
37157
- this.consumePath(opIdx, path36, this.current.getClippedPathBoundingBox(PathType.STROKE, getCurrentTransform(this.ctx)));
37157
+ this.consumePath(opIdx, path37, this.current.getClippedPathBoundingBox(PathType.STROKE, getCurrentTransform(this.ctx)));
37158
37158
  }
37159
37159
  ctx.globalAlpha = this.current.fillAlpha;
37160
37160
  }
37161
- closeStroke(opIdx, path36) {
37162
- this.stroke(opIdx, path36);
37161
+ closeStroke(opIdx, path37) {
37162
+ this.stroke(opIdx, path37);
37163
37163
  }
37164
- fill(opIdx, path36, consumePath = true) {
37164
+ fill(opIdx, path37, consumePath = true) {
37165
37165
  const ctx = this.ctx;
37166
37166
  const fillColor = this.current.fillColor;
37167
37167
  const isPatternFill = this.current.patternFill;
@@ -37173,18 +37173,18 @@ fn fs_main(in : VertexOutput) -> @location(0) vec4<f32> {
37173
37173
  ctx.fillStyle = fillColor.getPattern(ctx, this, getCurrentTransformInverse(ctx), PathType.FILL, opIdx);
37174
37174
  if (baseTransform) {
37175
37175
  const newPath = new Path2D();
37176
- newPath.addPath(path36, ctx.getTransform().invertSelf().multiplySelf(baseTransform));
37177
- path36 = newPath;
37176
+ newPath.addPath(path37, ctx.getTransform().invertSelf().multiplySelf(baseTransform));
37177
+ path37 = newPath;
37178
37178
  }
37179
37179
  needRestore = true;
37180
37180
  }
37181
37181
  const intersect = this.current.getClippedPathBoundingBox();
37182
37182
  if (this.contentVisible && intersect !== null) {
37183
37183
  if (this.pendingEOFill) {
37184
- ctx.fill(path36, "evenodd");
37184
+ ctx.fill(path37, "evenodd");
37185
37185
  this.pendingEOFill = false;
37186
37186
  } else {
37187
- ctx.fill(path36);
37187
+ ctx.fill(path37);
37188
37188
  }
37189
37189
  }
37190
37190
  this.dependencyTracker?.recordDependencies(opIdx, Dependencies.fill);
@@ -37193,34 +37193,34 @@ fn fs_main(in : VertexOutput) -> @location(0) vec4<f32> {
37193
37193
  this.dependencyTracker?.restore(opIdx);
37194
37194
  }
37195
37195
  if (consumePath) {
37196
- this.consumePath(opIdx, path36, intersect);
37196
+ this.consumePath(opIdx, path37, intersect);
37197
37197
  }
37198
37198
  }
37199
- eoFill(opIdx, path36) {
37199
+ eoFill(opIdx, path37) {
37200
37200
  this.pendingEOFill = true;
37201
- this.fill(opIdx, path36);
37201
+ this.fill(opIdx, path37);
37202
37202
  }
37203
- fillStroke(opIdx, path36) {
37204
- this.fill(opIdx, path36, false);
37205
- this.stroke(opIdx, path36, false);
37206
- this.consumePath(opIdx, path36);
37203
+ fillStroke(opIdx, path37) {
37204
+ this.fill(opIdx, path37, false);
37205
+ this.stroke(opIdx, path37, false);
37206
+ this.consumePath(opIdx, path37);
37207
37207
  }
37208
- eoFillStroke(opIdx, path36) {
37208
+ eoFillStroke(opIdx, path37) {
37209
37209
  this.pendingEOFill = true;
37210
- this.fillStroke(opIdx, path36);
37210
+ this.fillStroke(opIdx, path37);
37211
37211
  }
37212
- closeFillStroke(opIdx, path36) {
37213
- this.fillStroke(opIdx, path36);
37212
+ closeFillStroke(opIdx, path37) {
37213
+ this.fillStroke(opIdx, path37);
37214
37214
  }
37215
- closeEOFillStroke(opIdx, path36) {
37215
+ closeEOFillStroke(opIdx, path37) {
37216
37216
  this.pendingEOFill = true;
37217
- this.fillStroke(opIdx, path36);
37217
+ this.fillStroke(opIdx, path37);
37218
37218
  }
37219
- endPath(opIdx, path36) {
37220
- this.consumePath(opIdx, path36);
37219
+ endPath(opIdx, path37) {
37220
+ this.consumePath(opIdx, path37);
37221
37221
  }
37222
- rawFillPath(opIdx, path36) {
37223
- this.ctx.fill(path36);
37222
+ rawFillPath(opIdx, path37) {
37223
+ this.ctx.fill(path37);
37224
37224
  this.dependencyTracker?.recordDependencies(opIdx, Dependencies.rawFillPath).recordOperation(opIdx);
37225
37225
  }
37226
37226
  clip(opIdx) {
@@ -37258,12 +37258,12 @@ fn fs_main(in : VertexOutput) -> @location(0) vec4<f32> {
37258
37258
  x,
37259
37259
  y,
37260
37260
  fontSize,
37261
- path: path36
37261
+ path: path37
37262
37262
  } of paths) {
37263
- if (!path36) {
37263
+ if (!path37) {
37264
37264
  continue;
37265
37265
  }
37266
- newPath.addPath(path36, new DOMMatrix(transform2).preMultiplySelf(invTransf).translate(x, y).scale(fontSize, -fontSize));
37266
+ newPath.addPath(path37, new DOMMatrix(transform2).preMultiplySelf(invTransf).translate(x, y).scale(fontSize, -fontSize));
37267
37267
  }
37268
37268
  ctx.clip(newPath);
37269
37269
  }
@@ -37356,9 +37356,9 @@ fn fs_main(in : VertexOutput) -> @location(0) vec4<f32> {
37356
37356
  this.moveText(opIdx, 0, this.current.leading);
37357
37357
  this.dependencyTracker?.recordIncrementalData("moveText", this.dependencyTracker.getSimpleIndex("leading") ?? opIdx);
37358
37358
  }
37359
- #getScaledPath(path36, currentTransform, transform2) {
37359
+ #getScaledPath(path37, currentTransform, transform2) {
37360
37360
  const newPath = new Path2D();
37361
- newPath.addPath(path36, new DOMMatrix(transform2).invertSelf().multiplySelf(currentTransform));
37361
+ newPath.addPath(path37, new DOMMatrix(transform2).invertSelf().multiplySelf(currentTransform));
37362
37362
  return newPath;
37363
37363
  }
37364
37364
  paintChar(opIdx, character, x, y, patternFillTransform, patternStrokeTransform) {
@@ -37371,11 +37371,11 @@ fn fs_main(in : VertexOutput) -> @location(0) vec4<f32> {
37371
37371
  const isAddToPathSet = !!(textRenderingMode & TextRenderingMode.ADD_TO_PATH_FLAG);
37372
37372
  const patternFill = current.patternFill && !font.missingFile;
37373
37373
  const patternStroke = current.patternStroke && !font.missingFile;
37374
- let path36;
37374
+ let path37;
37375
37375
  if ((font.disableFontFace || isAddToPathSet || patternFill || patternStroke) && !font.missingFile) {
37376
- path36 = font.getPathGenerator(this.commonObjs, character);
37376
+ path37 = font.getPathGenerator(this.commonObjs, character);
37377
37377
  }
37378
- if (path36 && (font.disableFontFace || patternFill || patternStroke)) {
37378
+ if (path37 && (font.disableFontFace || patternFill || patternStroke)) {
37379
37379
  ctx.save();
37380
37380
  ctx.translate(x, y);
37381
37381
  ctx.scale(fontSize, -fontSize);
@@ -37385,10 +37385,10 @@ fn fs_main(in : VertexOutput) -> @location(0) vec4<f32> {
37385
37385
  if (patternFillTransform) {
37386
37386
  currentTransform = ctx.getTransform();
37387
37387
  ctx.setTransform(...patternFillTransform);
37388
- const scaledPath = this.#getScaledPath(path36, currentTransform, patternFillTransform);
37388
+ const scaledPath = this.#getScaledPath(path37, currentTransform, patternFillTransform);
37389
37389
  ctx.fill(scaledPath);
37390
37390
  } else {
37391
- ctx.fill(path36);
37391
+ ctx.fill(path37);
37392
37392
  }
37393
37393
  }
37394
37394
  if (fillStrokeMode === TextRenderingMode.STROKE || fillStrokeMode === TextRenderingMode.FILL_STROKE) {
@@ -37405,10 +37405,10 @@ fn fs_main(in : VertexOutput) -> @location(0) vec4<f32> {
37405
37405
  const transf = Util.transform([a, b, c, d, 0, 0], invPatternTransform);
37406
37406
  Util.singularValueDecompose2dScale(transf, XY);
37407
37407
  ctx.lineWidth *= Math.max(XY[0], XY[1]) / fontSize;
37408
- ctx.stroke(this.#getScaledPath(path36, currentTransform, patternStrokeTransform));
37408
+ ctx.stroke(this.#getScaledPath(path37, currentTransform, patternStrokeTransform));
37409
37409
  } else {
37410
37410
  ctx.lineWidth /= fontSize;
37411
- ctx.stroke(path36);
37411
+ ctx.stroke(path37);
37412
37412
  }
37413
37413
  }
37414
37414
  ctx.restore();
@@ -37431,7 +37431,7 @@ fn fs_main(in : VertexOutput) -> @location(0) vec4<f32> {
37431
37431
  x,
37432
37432
  y,
37433
37433
  fontSize,
37434
- path: path36
37434
+ path: path37
37435
37435
  });
37436
37436
  this.dependencyTracker?.recordCharacterBBox(opIdx, ctx, font, fontSize, x, y);
37437
37437
  }
@@ -37844,9 +37844,9 @@ fn fs_main(in : VertexOutput) -> @location(0) vec4<f32> {
37844
37844
  const [x0, y0, x1, y1] = group.bbox;
37845
37845
  clip.rect(x0, y0, x1 - x0, y1 - y0);
37846
37846
  if (group.matrix) {
37847
- const path36 = new Path2D();
37848
- path36.addPath(clip, new DOMMatrix(group.matrix));
37849
- clip = path36;
37847
+ const path37 = new Path2D();
37848
+ path37.addPath(clip, new DOMMatrix(group.matrix));
37849
+ clip = path37;
37850
37850
  }
37851
37851
  groupCtx.clip(clip);
37852
37852
  }
@@ -38224,7 +38224,7 @@ fn fs_main(in : VertexOutput) -> @location(0) vec4<f32> {
38224
38224
  }
38225
38225
  endCompat(opIdx) {
38226
38226
  }
38227
- consumePath(opIdx, path36, clipBox) {
38227
+ consumePath(opIdx, path37, clipBox) {
38228
38228
  const isEmpty = this.current.isEmptyClip();
38229
38229
  if (this.pendingClip) {
38230
38230
  this.current.updateClipFromPath();
@@ -38236,9 +38236,9 @@ fn fs_main(in : VertexOutput) -> @location(0) vec4<f32> {
38236
38236
  if (this.pendingClip) {
38237
38237
  if (!isEmpty) {
38238
38238
  if (this.pendingClip === EO_CLIP) {
38239
- ctx.clip(path36, "evenodd");
38239
+ ctx.clip(path37, "evenodd");
38240
38240
  } else {
38241
- ctx.clip(path36);
38241
+ ctx.clip(path37);
38242
38242
  }
38243
38243
  }
38244
38244
  this.pendingClip = null;
@@ -38311,7 +38311,7 @@ fn fs_main(in : VertexOutput) -> @location(0) vec4<f32> {
38311
38311
  }
38312
38312
  return this._cachedScaleForStroking;
38313
38313
  }
38314
- rescaleAndStroke(path36, saveRestore) {
38314
+ rescaleAndStroke(path37, saveRestore) {
38315
38315
  const {
38316
38316
  ctx,
38317
38317
  current: {
@@ -38321,7 +38321,7 @@ fn fs_main(in : VertexOutput) -> @location(0) vec4<f32> {
38321
38321
  const [scaleX, scaleY] = this.getScaleForStroking();
38322
38322
  if (scaleX === scaleY) {
38323
38323
  ctx.lineWidth = (lineWidth || 1) * scaleX;
38324
- ctx.stroke(path36);
38324
+ ctx.stroke(path37);
38325
38325
  return;
38326
38326
  }
38327
38327
  const dashes = ctx.getLineDash();
@@ -38332,7 +38332,7 @@ fn fs_main(in : VertexOutput) -> @location(0) vec4<f32> {
38332
38332
  SCALE_MATRIX.a = 1 / scaleX;
38333
38333
  SCALE_MATRIX.d = 1 / scaleY;
38334
38334
  const newPath = new Path2D();
38335
- newPath.addPath(path36, SCALE_MATRIX);
38335
+ newPath.addPath(path37, SCALE_MATRIX);
38336
38336
  if (dashes.length > 0) {
38337
38337
  const scale = Math.max(scaleX, scaleY);
38338
38338
  ctx.setLineDash(dashes.map((x) => x / scale));
@@ -39057,9 +39057,9 @@ fn fs_main(in : VertexOutput) -> @location(0) vec4<f32> {
39057
39057
  url: url2
39058
39058
  } = stream._source;
39059
39059
  this._isStreamingSupported = !disableStream;
39060
- const fs26 = process.getBuiltinModule("fs");
39061
- fs26.promises.lstat(url2).then((stat3) => {
39062
- const readStream = fs26.createReadStream(url2);
39060
+ const fs27 = process.getBuiltinModule("fs");
39061
+ fs27.promises.lstat(url2).then((stat3) => {
39062
+ const readStream = fs27.createReadStream(url2);
39063
39063
  const readableStream = getReadableStream(readStream);
39064
39064
  this._reader = readableStream.getReader();
39065
39065
  const {
@@ -39109,9 +39109,9 @@ fn fs_main(in : VertexOutput) -> @location(0) vec4<f32> {
39109
39109
  const {
39110
39110
  url: url2
39111
39111
  } = stream._source;
39112
- const fs26 = process.getBuiltinModule("fs");
39112
+ const fs27 = process.getBuiltinModule("fs");
39113
39113
  try {
39114
- const readStream = fs26.createReadStream(url2, {
39114
+ const readStream = fs27.createReadStream(url2, {
39115
39115
  start: begin,
39116
39116
  end: end - 1
39117
39117
  });
@@ -49140,11 +49140,11 @@ fn fs_main(in : VertexOutput) -> @location(0) vec4<f32> {
49140
49140
  };
49141
49141
  ContourDrawOutline = class extends InkDrawOutline {
49142
49142
  toSVGPath() {
49143
- let path36 = super.toSVGPath();
49144
- if (!path36.endsWith("Z")) {
49145
- path36 += "Z";
49143
+ let path37 = super.toSVGPath();
49144
+ if (!path37.endsWith("Z")) {
49145
+ path37 += "Z";
49146
49146
  }
49147
- return path36;
49147
+ return path37;
49148
49148
  }
49149
49149
  };
49150
49150
  BASE_HEADER_LENGTH = 8;
@@ -51614,13 +51614,13 @@ fn fs_main(in : VertexOutput) -> @location(0) vec4<f32> {
51614
51614
  const root = this.#createSVG();
51615
51615
  const defs = _DrawLayer._svgFactory.createElement("defs");
51616
51616
  root.append(defs);
51617
- const path36 = _DrawLayer._svgFactory.createElement("path");
51618
- defs.append(path36);
51617
+ const path37 = _DrawLayer._svgFactory.createElement("path");
51618
+ defs.append(path37);
51619
51619
  const pathId = `path_${id}`;
51620
- path36.setAttribute("id", pathId);
51621
- path36.setAttribute("vector-effect", "non-scaling-stroke");
51620
+ path37.setAttribute("id", pathId);
51621
+ path37.setAttribute("vector-effect", "non-scaling-stroke");
51622
51622
  if (isPathUpdatable) {
51623
- this.#toUpdate.set(id, path36);
51623
+ this.#toUpdate.set(id, path37);
51624
51624
  }
51625
51625
  const clipPathId = hasClip ? this.#createClipPath(defs, pathId) : null;
51626
51626
  const use = _DrawLayer._svgFactory.createElement("use");
@@ -51638,11 +51638,11 @@ fn fs_main(in : VertexOutput) -> @location(0) vec4<f32> {
51638
51638
  const root = this.#createSVG();
51639
51639
  const defs = _DrawLayer._svgFactory.createElement("defs");
51640
51640
  root.append(defs);
51641
- const path36 = _DrawLayer._svgFactory.createElement("path");
51642
- defs.append(path36);
51641
+ const path37 = _DrawLayer._svgFactory.createElement("path");
51642
+ defs.append(path37);
51643
51643
  const pathId = `path_${id}`;
51644
- path36.setAttribute("id", pathId);
51645
- path36.setAttribute("vector-effect", "non-scaling-stroke");
51644
+ path37.setAttribute("id", pathId);
51645
+ path37.setAttribute("vector-effect", "non-scaling-stroke");
51646
51646
  let maskId;
51647
51647
  if (mustRemoveSelfIntersections) {
51648
51648
  const mask = _DrawLayer._svgFactory.createElement("mask");
@@ -51689,7 +51689,7 @@ fn fs_main(in : VertexOutput) -> @location(0) vec4<f32> {
51689
51689
  root,
51690
51690
  bbox,
51691
51691
  rootClass,
51692
- path: path36
51692
+ path: path37
51693
51693
  } = properties;
51694
51694
  const element = typeof elementOrId === "number" ? this.#mapping.get(elementOrId) : elementOrId;
51695
51695
  if (!element) {
@@ -51709,10 +51709,10 @@ fn fs_main(in : VertexOutput) -> @location(0) vec4<f32> {
51709
51709
  classList.toggle(className, value);
51710
51710
  }
51711
51711
  }
51712
- if (path36) {
51712
+ if (path37) {
51713
51713
  const defs = element.firstElementChild;
51714
51714
  const pathElement = defs.firstElementChild;
51715
- this.#updateProperties(pathElement, path36);
51715
+ this.#updateProperties(pathElement, path37);
51716
51716
  }
51717
51717
  }
51718
51718
  updateParent(id, layer) {
@@ -55435,14 +55435,14 @@ var require_OfficeParser = __commonJS({
55435
55435
  } else if (typeof file2 === "string") {
55436
55436
  filePath = file2;
55437
55437
  (0, envUtils_js_1.assertNode)("path-parsing");
55438
- const fs26 = await import("fs");
55439
- if (!fs26.existsSync(file2)) {
55438
+ const fs27 = await import("fs");
55439
+ if (!fs27.existsSync(file2)) {
55440
55440
  throw (0, errorUtils_js_1.getOfficeError)(types_js_1.OfficeErrorType.FILE_DOES_NOT_EXIST, internalConfig, file2);
55441
55441
  }
55442
- if (fs26.lstatSync(file2).isDirectory()) {
55442
+ if (fs27.lstatSync(file2).isDirectory()) {
55443
55443
  throw (0, errorUtils_js_1.getOfficeError)(types_js_1.OfficeErrorType.LOCATION_NOT_FOUND, internalConfig, file2);
55444
55444
  }
55445
- buffer = fs26.readFileSync(file2);
55445
+ buffer = fs27.readFileSync(file2);
55446
55446
  ext = ext || file2.split(".").pop() || "";
55447
55447
  } else {
55448
55448
  throw (0, errorUtils_js_1.getOfficeError)(types_js_1.OfficeErrorType.INVALID_INPUT, internalConfig);
@@ -57093,8 +57093,8 @@ function dateNF_fix(str, dateNF, match) {
57093
57093
  if (Y == -1 && m == -1 && d == -1) return timestr;
57094
57094
  return datestr + "T" + timestr;
57095
57095
  }
57096
- function set_fs(fs26) {
57097
- _fs = fs26;
57096
+ function set_fs(fs27) {
57097
+ _fs = fs27;
57098
57098
  }
57099
57099
  function blobify(data) {
57100
57100
  if (typeof data === "string") return s2ab(data);
@@ -57158,11 +57158,11 @@ function write_dl(fname, payload, enc) {
57158
57158
  }
57159
57159
  throw new Error("cannot save file " + fname);
57160
57160
  }
57161
- function read_binary(path36) {
57162
- if (typeof _fs !== "undefined") return _fs.readFileSync(path36);
57163
- if (typeof Deno !== "undefined") return Deno.readFileSync(path36);
57161
+ function read_binary(path37) {
57162
+ if (typeof _fs !== "undefined") return _fs.readFileSync(path37);
57163
+ if (typeof Deno !== "undefined") return Deno.readFileSync(path37);
57164
57164
  if (typeof $ !== "undefined" && typeof File !== "undefined" && typeof Folder !== "undefined") try {
57165
- var infile = File(path36);
57165
+ var infile = File(path37);
57166
57166
  infile.open("r");
57167
57167
  infile.encoding = "binary";
57168
57168
  var data = infile.read();
@@ -57171,7 +57171,7 @@ function read_binary(path36) {
57171
57171
  } catch (e) {
57172
57172
  if (!e.message || !e.message.match(/onstruct/)) throw e;
57173
57173
  }
57174
- throw new Error("Cannot access file " + path36);
57174
+ throw new Error("Cannot access file " + path37);
57175
57175
  }
57176
57176
  function keys(o) {
57177
57177
  var ks = Object.keys(o), o2 = [];
@@ -57428,16 +57428,16 @@ function zipentries(zip) {
57428
57428
  for (var i = 0; i < k.length; ++i) if (k[i].slice(-1) != "/") o.push(k[i].replace(/^Root Entry[\/]/, ""));
57429
57429
  return o.sort();
57430
57430
  }
57431
- function zip_add_file(zip, path36, content) {
57431
+ function zip_add_file(zip, path37, content) {
57432
57432
  if (zip.FullPaths) {
57433
57433
  if (typeof content == "string") {
57434
57434
  var res;
57435
57435
  if (has_buf) res = Buffer_from(content);
57436
57436
  else res = utf8decode(content);
57437
- return CFB.utils.cfb_add(zip, path36, res);
57437
+ return CFB.utils.cfb_add(zip, path37, res);
57438
57438
  }
57439
- CFB.utils.cfb_add(zip, path36, content);
57440
- } else zip.file(path36, content);
57439
+ CFB.utils.cfb_add(zip, path37, content);
57440
+ } else zip.file(path37, content);
57441
57441
  }
57442
57442
  function zip_new() {
57443
57443
  return CFB.utils.cfb_new();
@@ -57454,11 +57454,11 @@ function zip_read(d, o) {
57454
57454
  }
57455
57455
  throw new Error("Unrecognized type " + o.type);
57456
57456
  }
57457
- function resolve_path(path36, base) {
57458
- if (path36.charAt(0) == "/") return path36.slice(1);
57457
+ function resolve_path(path37, base) {
57458
+ if (path37.charAt(0) == "/") return path37.slice(1);
57459
57459
  var result = base.split("/");
57460
57460
  if (base.slice(-1) != "/") result.pop();
57461
- var target = path36.split("/");
57461
+ var target = path37.split("/");
57462
57462
  while (target.length !== 0) {
57463
57463
  var step = target.shift();
57464
57464
  if (step === "..") result.pop();
@@ -72023,19 +72023,19 @@ function safe_parse_wbrels(wbrels, sheets) {
72023
72023
  }
72024
72024
  return !wbrels || wbrels.length === 0 ? null : wbrels;
72025
72025
  }
72026
- function safe_parse_sheet(zip, path36, relsPath, sheet, idx, sheetRels, sheets, stype, opts, wb, themes, styles3) {
72026
+ function safe_parse_sheet(zip, path37, relsPath, sheet, idx, sheetRels, sheets, stype, opts, wb, themes, styles3) {
72027
72027
  try {
72028
- sheetRels[sheet] = parse_rels(getzipstr(zip, relsPath, true), path36);
72029
- var data = getzipdata(zip, path36);
72028
+ sheetRels[sheet] = parse_rels(getzipstr(zip, relsPath, true), path37);
72029
+ var data = getzipdata(zip, path37);
72030
72030
  var _ws;
72031
72031
  switch (stype) {
72032
72032
  case "sheet":
72033
- _ws = parse_ws(data, path36, idx, opts, sheetRels[sheet], wb, themes, styles3);
72033
+ _ws = parse_ws(data, path37, idx, opts, sheetRels[sheet], wb, themes, styles3);
72034
72034
  break;
72035
72035
  case "chart":
72036
- _ws = parse_cs(data, path36, idx, opts, sheetRels[sheet], wb, themes, styles3);
72036
+ _ws = parse_cs(data, path37, idx, opts, sheetRels[sheet], wb, themes, styles3);
72037
72037
  if (!_ws || !_ws["!drawel"]) break;
72038
- var dfile = resolve_path(_ws["!drawel"].Target, path36);
72038
+ var dfile = resolve_path(_ws["!drawel"].Target, path37);
72039
72039
  var drelsp = get_rels_path(dfile);
72040
72040
  var draw = parse_drawing(getzipstr(zip, dfile, true), parse_rels(getzipstr(zip, drelsp, true), dfile));
72041
72041
  var chartp = resolve_path(draw, dfile);
@@ -72043,10 +72043,10 @@ function safe_parse_sheet(zip, path36, relsPath, sheet, idx, sheetRels, sheets,
72043
72043
  _ws = parse_chart(getzipstr(zip, chartp, true), chartp, opts, parse_rels(getzipstr(zip, crelsp, true), chartp), wb, _ws);
72044
72044
  break;
72045
72045
  case "macro":
72046
- _ws = parse_ms(data, path36, idx, opts, sheetRels[sheet], wb, themes, styles3);
72046
+ _ws = parse_ms(data, path37, idx, opts, sheetRels[sheet], wb, themes, styles3);
72047
72047
  break;
72048
72048
  case "dialog":
72049
- _ws = parse_ds(data, path36, idx, opts, sheetRels[sheet], wb, themes, styles3);
72049
+ _ws = parse_ds(data, path37, idx, opts, sheetRels[sheet], wb, themes, styles3);
72050
72050
  break;
72051
72051
  default:
72052
72052
  throw new Error("Unrecognized sheet type " + stype);
@@ -72056,13 +72056,13 @@ function safe_parse_sheet(zip, path36, relsPath, sheet, idx, sheetRels, sheets,
72056
72056
  if (sheetRels && sheetRels[sheet]) keys(sheetRels[sheet]).forEach(function(n) {
72057
72057
  var dfile2 = "";
72058
72058
  if (sheetRels[sheet][n].Type == RELS.CMNT) {
72059
- dfile2 = resolve_path(sheetRels[sheet][n].Target, path36);
72059
+ dfile2 = resolve_path(sheetRels[sheet][n].Target, path37);
72060
72060
  var comments = parse_cmnt(getzipdata(zip, dfile2, true), dfile2, opts);
72061
72061
  if (!comments || !comments.length) return;
72062
72062
  sheet_insert_comments(_ws, comments, false);
72063
72063
  }
72064
72064
  if (sheetRels[sheet][n].Type == RELS.TCMNT) {
72065
- dfile2 = resolve_path(sheetRels[sheet][n].Target, path36);
72065
+ dfile2 = resolve_path(sheetRels[sheet][n].Target, path37);
72066
72066
  tcomments = tcomments.concat(parse_tcmnt_xml(getzipdata(zip, dfile2, true), opts));
72067
72067
  }
72068
72068
  });
@@ -72166,7 +72166,7 @@ function parse_zip(zip, opts) {
72166
72166
  if (opts.bookDeps && dir.calcchain) deps = parse_cc(getzipdata(zip, strip_front_slash(dir.calcchain)), dir.calcchain, opts);
72167
72167
  var i = 0;
72168
72168
  var sheetRels = {};
72169
- var path36, relsPath;
72169
+ var path37, relsPath;
72170
72170
  {
72171
72171
  var wbsheets = wb.Sheets;
72172
72172
  props.Worksheets = wbsheets.length;
@@ -72191,15 +72191,15 @@ function parse_zip(zip, opts) {
72191
72191
  wsloop: for (i = 0; i != props.Worksheets; ++i) {
72192
72192
  var stype = "sheet";
72193
72193
  if (wbrels && wbrels[i]) {
72194
- path36 = "xl/" + wbrels[i][1].replace(/[\/]?xl\//, "");
72195
- if (!safegetzipfile(zip, path36)) path36 = wbrels[i][1];
72196
- if (!safegetzipfile(zip, path36)) path36 = wbrelsfile.replace(/_rels\/.*$/, "") + wbrels[i][1];
72194
+ path37 = "xl/" + wbrels[i][1].replace(/[\/]?xl\//, "");
72195
+ if (!safegetzipfile(zip, path37)) path37 = wbrels[i][1];
72196
+ if (!safegetzipfile(zip, path37)) path37 = wbrelsfile.replace(/_rels\/.*$/, "") + wbrels[i][1];
72197
72197
  stype = wbrels[i][2];
72198
72198
  } else {
72199
- path36 = "xl/worksheets/sheet" + (i + 1 - nmode) + "." + wbext;
72200
- path36 = path36.replace(/sheet0\./, "sheet.");
72199
+ path37 = "xl/worksheets/sheet" + (i + 1 - nmode) + "." + wbext;
72200
+ path37 = path37.replace(/sheet0\./, "sheet.");
72201
72201
  }
72202
- relsPath = path36.replace(/^(.*)(\/)([^\/]*)$/, "$1/_rels/$3.rels");
72202
+ relsPath = path37.replace(/^(.*)(\/)([^\/]*)$/, "$1/_rels/$3.rels");
72203
72203
  if (opts && opts.sheets != null) switch (typeof opts.sheets) {
72204
72204
  case "number":
72205
72205
  if (i != opts.sheets) continue wsloop;
@@ -72217,7 +72217,7 @@ function parse_zip(zip, opts) {
72217
72217
  if (!snjseen) continue wsloop;
72218
72218
  }
72219
72219
  }
72220
- safe_parse_sheet(zip, path36, relsPath, props.SheetNames[i], i, sheetRels, sheets, stype, opts, wb, themes, styles3);
72220
+ safe_parse_sheet(zip, path37, relsPath, props.SheetNames[i], i, sheetRels, sheets, stype, opts, wb, themes, styles3);
72221
72221
  }
72222
72222
  out = {
72223
72223
  Directory: dir,
@@ -73114,7 +73114,7 @@ function sheet_to_json(sheet, opts) {
73114
73114
  out.length = outi;
73115
73115
  return out;
73116
73116
  }
73117
- function make_csv_row(sheet, r, R, cols, fs26, rs, FS, o) {
73117
+ function make_csv_row(sheet, r, R, cols, fs27, rs, FS, o) {
73118
73118
  var isempty = true;
73119
73119
  var row = [], txt = "", rr = encode_row(R);
73120
73120
  for (var C = r.s.c; C <= r.e.c; ++C) {
@@ -73124,7 +73124,7 @@ function make_csv_row(sheet, r, R, cols, fs26, rs, FS, o) {
73124
73124
  else if (val.v != null) {
73125
73125
  isempty = false;
73126
73126
  txt = "" + (o.rawNumbers && val.t == "n" ? val.v : format_cell(val, null, o));
73127
- for (var i = 0, cc = 0; i !== txt.length; ++i) if ((cc = txt.charCodeAt(i)) === fs26 || cc === rs || cc === 34 || o.forceQuotes) {
73127
+ for (var i = 0, cc = 0; i !== txt.length; ++i) if ((cc = txt.charCodeAt(i)) === fs27 || cc === rs || cc === 34 || o.forceQuotes) {
73128
73128
  txt = '"' + txt.replace(qreg, '""') + '"';
73129
73129
  break;
73130
73130
  }
@@ -73144,7 +73144,7 @@ function sheet_to_csv(sheet, opts) {
73144
73144
  var o = opts == null ? {} : opts;
73145
73145
  if (sheet == null || sheet["!ref"] == null) return "";
73146
73146
  var r = safe_decode_range(sheet["!ref"]);
73147
- var FS = o.FS !== void 0 ? o.FS : ",", fs26 = FS.charCodeAt(0);
73147
+ var FS = o.FS !== void 0 ? o.FS : ",", fs27 = FS.charCodeAt(0);
73148
73148
  var RS = o.RS !== void 0 ? o.RS : "\n", rs = RS.charCodeAt(0);
73149
73149
  var endregex = new RegExp((FS == "|" ? "\\|" : FS) + "+$");
73150
73150
  var row = "", cols = [];
@@ -73155,7 +73155,7 @@ function sheet_to_csv(sheet, opts) {
73155
73155
  var w = 0;
73156
73156
  for (var R = r.s.r; R <= r.e.r; ++R) {
73157
73157
  if ((rowinfo[R] || {}).hidden) continue;
73158
- row = make_csv_row(sheet, r, R, cols, fs26, rs, FS, o);
73158
+ row = make_csv_row(sheet, r, R, cols, fs27, rs, FS, o);
73159
73159
  if (row == null) {
73160
73160
  continue;
73161
73161
  }
@@ -73387,7 +73387,7 @@ function write_csv_stream(sheet, opts) {
73387
73387
  return stream;
73388
73388
  }
73389
73389
  var r = safe_decode_range(sheet["!ref"]);
73390
- var FS = o.FS !== void 0 ? o.FS : ",", fs26 = FS.charCodeAt(0);
73390
+ var FS = o.FS !== void 0 ? o.FS : ",", fs27 = FS.charCodeAt(0);
73391
73391
  var RS = o.RS !== void 0 ? o.RS : "\n", rs = RS.charCodeAt(0);
73392
73392
  var endregex = new RegExp((FS == "|" ? "\\|" : FS) + "+$");
73393
73393
  var row = "", cols = [];
@@ -73405,7 +73405,7 @@ function write_csv_stream(sheet, opts) {
73405
73405
  while (R <= r.e.r) {
73406
73406
  ++R;
73407
73407
  if ((rowinfo[R - 1] || {}).hidden) continue;
73408
- row = make_csv_row(sheet, r, R - 1, cols, fs26, rs, FS, o);
73408
+ row = make_csv_row(sheet, r, R - 1, cols, fs27, rs, FS, o);
73409
73409
  if (row != null) {
73410
73410
  if (o.strip) row = row.replace(endregex, "");
73411
73411
  if (row || o.blankrows !== false) return stream.push((w++ ? RS : "") + row);
@@ -74035,9 +74035,9 @@ var init_xlsx = __esm({
74035
74035
  }
74036
74036
  return o;
74037
74037
  }
74038
- var fs26;
74038
+ var fs27;
74039
74039
  function get_fs() {
74040
- return fs26 || (fs26 = {});
74040
+ return fs27 || (fs27 = {});
74041
74041
  }
74042
74042
  function parse3(file2, options) {
74043
74043
  if (file2[0] == 80 && file2[1] == 75) return parse_zip2(file2, options);
@@ -74320,7 +74320,7 @@ var init_xlsx = __esm({
74320
74320
  }
74321
74321
  function read_file(filename2, options) {
74322
74322
  get_fs();
74323
- return parse3(fs26.readFileSync(filename2), options);
74323
+ return parse3(fs27.readFileSync(filename2), options);
74324
74324
  }
74325
74325
  function read2(blob, options) {
74326
74326
  var type = options && options.type;
@@ -74601,7 +74601,7 @@ var init_xlsx = __esm({
74601
74601
  }
74602
74602
  return o;
74603
74603
  }
74604
- function find2(cfb, path36) {
74604
+ function find2(cfb, path37) {
74605
74605
  var UCFullPaths = cfb.FullPaths.map(function(x) {
74606
74606
  return x.toUpperCase();
74607
74607
  });
@@ -74610,11 +74610,11 @@ var init_xlsx = __esm({
74610
74610
  return y[y.length - (x.slice(-1) == "/" ? 2 : 1)];
74611
74611
  });
74612
74612
  var k = false;
74613
- if (path36.charCodeAt(0) === 47) {
74613
+ if (path37.charCodeAt(0) === 47) {
74614
74614
  k = true;
74615
- path36 = UCFullPaths[0].slice(0, -1) + path36;
74616
- } else k = path36.indexOf("/") !== -1;
74617
- var UCPath = path36.toUpperCase();
74615
+ path37 = UCFullPaths[0].slice(0, -1) + path37;
74616
+ } else k = path37.indexOf("/") !== -1;
74617
+ var UCPath = path37.toUpperCase();
74618
74618
  var w = k === true ? UCFullPaths.indexOf(UCPath) : UCPaths.indexOf(UCPath);
74619
74619
  if (w !== -1) return cfb.FileIndex[w];
74620
74620
  var m = !UCPath.match(chr1);
@@ -74650,7 +74650,7 @@ var init_xlsx = __esm({
74650
74650
  function write_file(cfb, filename2, options) {
74651
74651
  get_fs();
74652
74652
  var o = _write(cfb, options);
74653
- fs26.writeFileSync(filename2, o);
74653
+ fs27.writeFileSync(filename2, o);
74654
74654
  }
74655
74655
  function a2s2(o) {
74656
74656
  var out = new Array(o.length);
@@ -74662,7 +74662,7 @@ var init_xlsx = __esm({
74662
74662
  switch (options && options.type || "buffer") {
74663
74663
  case "file":
74664
74664
  get_fs();
74665
- fs26.writeFileSync(options.filename, o);
74665
+ fs27.writeFileSync(options.filename, o);
74666
74666
  return o;
74667
74667
  case "binary":
74668
74668
  return typeof o == "string" ? o : a2s2(o);
@@ -91236,7 +91236,7 @@ var require_websocket_server = __commonJS({
91236
91236
 
91237
91237
  // src/cli.ts
91238
91238
  init_cjs_shims();
91239
- var import_node_path33 = __toESM(require("path"), 1);
91239
+ var import_node_path34 = __toESM(require("path"), 1);
91240
91240
  var import_node_fs19 = __toESM(require("fs"), 1);
91241
91241
 
91242
91242
  // ../../node_modules/.pnpm/cac@6.7.14/node_modules/cac/dist/index.mjs
@@ -92832,11 +92832,11 @@ var RotatingFileStream = class extends import_stream.Writable {
92832
92832
  timeout;
92833
92833
  timeoutPromise;
92834
92834
  constructor(generator, options) {
92835
- const { encoding, history, maxFiles, maxSize, path: path36 } = options;
92835
+ const { encoding, history, maxFiles, maxSize, path: path37 } = options;
92836
92836
  super({ decodeStrings: true, defaultEncoding: encoding });
92837
92837
  this.createGzip = import_zlib.createGzip;
92838
92838
  this.exec = import_child_process.exec;
92839
- this.filename = path36 + generator(null);
92839
+ this.filename = path37 + generator(null);
92840
92840
  this.fsCreateReadStream = import_fs.createReadStream;
92841
92841
  this.fsCreateWriteStream = import_fs.createWriteStream;
92842
92842
  this.fsOpen = import_promises.open;
@@ -92848,7 +92848,7 @@ var RotatingFileStream = class extends import_stream.Writable {
92848
92848
  this.options = options;
92849
92849
  this.stdout = process.stdout;
92850
92850
  if (maxFiles || maxSize)
92851
- options.history = path36 + (history ? history : this.generator(null) + ".txt");
92851
+ options.history = path37 + (history ? history : this.generator(null) + ".txt");
92852
92852
  this.on("close", () => this.finished ? null : this.emit("finish"));
92853
92853
  this.on("finish", () => this.finished = this.clear());
92854
92854
  (async () => {
@@ -92976,9 +92976,9 @@ var RotatingFileStream = class extends import_stream.Writable {
92976
92976
  return this.move();
92977
92977
  }
92978
92978
  async findName() {
92979
- const { interval, path: path36, intervalBoundary } = this.options;
92979
+ const { interval, path: path37, intervalBoundary } = this.options;
92980
92980
  for (let index = 1; index < 1e3; ++index) {
92981
- const filename = path36 + this.generator(interval && intervalBoundary ? new Date(this.prev) : this.rotation, index);
92981
+ const filename = path37 + this.generator(interval && intervalBoundary ? new Date(this.prev) : this.rotation, index);
92982
92982
  if (!await exists(filename))
92983
92983
  return filename;
92984
92984
  }
@@ -93008,11 +93008,11 @@ var RotatingFileStream = class extends import_stream.Writable {
93008
93008
  return this.unlink(filename);
93009
93009
  }
93010
93010
  async classical() {
93011
- const { compress, path: path36, rotate } = this.options;
93011
+ const { compress, path: path37, rotate } = this.options;
93012
93012
  let rotatedName = "";
93013
93013
  for (let count = rotate; count > 0; --count) {
93014
- const currName = path36 + this.generator(count);
93015
- const prevName = count === 1 ? this.filename : path36 + this.generator(count - 1);
93014
+ const currName = path37 + this.generator(count);
93015
+ const prevName = count === 1 ? this.filename : path37 + this.generator(count - 1);
93016
93016
  if (!await exists(prevName))
93017
93017
  continue;
93018
93018
  if (!rotatedName)
@@ -94007,7 +94007,7 @@ function logClaudeRuntimeResolution(resolution) {
94007
94007
  // src/start.ts
94008
94008
  init_cjs_shims();
94009
94009
  var import_node_os15 = __toESM(require("os"), 1);
94010
- var import_node_path31 = __toESM(require("path"), 1);
94010
+ var import_node_path32 = __toESM(require("path"), 1);
94011
94011
  var import_node_crypto6 = __toESM(require("crypto"), 1);
94012
94012
 
94013
94013
  // ../shared/src/index.ts
@@ -94678,6 +94678,25 @@ Transform tasks into verifiable goals:
94678
94678
  - "Refactor X" \u2192 ensure tests pass before and after.
94679
94679
  For multi-step tasks, state a brief plan with verification checks.
94680
94680
  `.trim();
94681
+ var GROUP_ONLY_SECTION_HEADERS = [
94682
+ "# \u7FA4\u804A\u516C\u7406\uFF08Group Chat Axiom \u2014 \u6700\u9AD8\u4F18\u5148\u7EA7\uFF09",
94683
+ "# Runtime payload \u2014 how to read unread messages",
94684
+ "# Group chat \u2014 when to speak",
94685
+ "# Group chat \u2014 recency & commitment",
94686
+ "# Length & conciseness in group chat",
94687
+ "# Group chat \u2014 shared task board",
94688
+ "# Group chat \u2014 batched inbox handling",
94689
+ "# \u7FA4\u804A\u4EA7\u7269\u7EAA\u5F8B\uFF08What to capture in group chats\uFF09",
94690
+ "# When a user joins or leaves your group"
94691
+ ];
94692
+ function stripGroupOnlySections(full, headers) {
94693
+ const headerSet = new Set(headers);
94694
+ return full.split(/\n(?=# )/).filter((section) => !headerSet.has(section.split("\n", 1)[0].trim())).join("\n").trim();
94695
+ }
94696
+ var PLATFORM_AGENT_RULES_SINGLE = stripGroupOnlySections(
94697
+ PLATFORM_AGENT_RULES,
94698
+ GROUP_ONLY_SECTION_HEADERS
94699
+ );
94681
94700
  var FAN_OUT_TRACE_TTL_MS = 10 * 6e4;
94682
94701
  var MAX_FILE_SIZE = 20 * 1024 * 1024;
94683
94702
  var MAX_IMAGE_SIZE = 10 * 1024 * 1024;
@@ -94849,6 +94868,14 @@ function assertArrayPayloadField(type, payload, field) {
94849
94868
  throw invalidWsMessage(type, field);
94850
94869
  }
94851
94870
  }
94871
+ function assertWorkdirSignalsPayloadField(type, payload, field) {
94872
+ assertArrayPayloadField(type, payload, field);
94873
+ for (const [index, item] of payload[field].entries()) {
94874
+ if (!isPlainRecord(item) || typeof item.toolName !== "string") {
94875
+ throw invalidWsMessage(type, `${field}[${index}].toolName`);
94876
+ }
94877
+ }
94878
+ }
94852
94879
  function assertRecordPayloadField(type, payload, field) {
94853
94880
  if (!isPlainRecord(payload[field])) {
94854
94881
  throw invalidWsMessage(type, field);
@@ -94929,6 +94956,9 @@ function validateWSMessageShape(msg) {
94929
94956
  "traceId"
94930
94957
  ]);
94931
94958
  assertArrayPayloadField(type, payload, "contentBlocks");
94959
+ if ("workdirSignals" in payload && payload.workdirSignals !== void 0) {
94960
+ assertWorkdirSignalsPayloadField(type, payload, "workdirSignals");
94961
+ }
94932
94962
  return;
94933
94963
  }
94934
94964
  case "agent:turn_complete": {
@@ -97144,14 +97174,14 @@ function agentIdArray(value) {
97144
97174
  function normalizeModelScopeSkill(value) {
97145
97175
  if (!isRecord2(value)) return null;
97146
97176
  const id = stringValue(value.id);
97147
- const path36 = stringValue(value.path);
97177
+ const path37 = stringValue(value.path);
97148
97178
  const name = stringValue(value.name);
97149
97179
  const displayName = stringValue(value.displayName, name);
97150
97180
  const url2 = stringValue(value.url);
97151
- if (!id || !path36 || !name || !displayName || !url2) return null;
97181
+ if (!id || !path37 || !name || !displayName || !url2) return null;
97152
97182
  return {
97153
97183
  id,
97154
- path: path36,
97184
+ path: path37,
97155
97185
  name,
97156
97186
  displayName,
97157
97187
  description: stringValue(value.description),
@@ -97498,9 +97528,9 @@ init_cjs_shims();
97498
97528
  var import_node_child_process3 = require("child_process");
97499
97529
  var import_node_crypto3 = require("crypto");
97500
97530
  var import_node_fs6 = __toESM(require("fs"), 1);
97501
- var import_promises3 = __toESM(require("fs/promises"), 1);
97531
+ var import_promises4 = __toESM(require("fs/promises"), 1);
97502
97532
  var import_node_os7 = __toESM(require("os"), 1);
97503
- var import_node_path13 = __toESM(require("path"), 1);
97533
+ var import_node_path14 = __toESM(require("path"), 1);
97504
97534
  var sdk2 = __toESM(require("@anthropic-ai/claude-agent-sdk"), 1);
97505
97535
 
97506
97536
  // src/attachmentAdapter.ts
@@ -98391,6 +98421,8 @@ var HttpMcpAuditClient = class {
98391
98421
 
98392
98422
  // src/neuralMcpServer.ts
98393
98423
  init_cjs_shims();
98424
+ var import_promises3 = __toESM(require("fs/promises"), 1);
98425
+ var import_node_path11 = __toESM(require("path"), 1);
98394
98426
  var sdk = __toESM(require("@anthropic-ai/claude-agent-sdk"), 1);
98395
98427
 
98396
98428
  // ../../node_modules/.pnpm/zod@4.4.3/node_modules/zod/index.js
@@ -99172,10 +99204,10 @@ function mergeDefs(...defs) {
99172
99204
  function cloneDef(schema) {
99173
99205
  return mergeDefs(schema._zod.def);
99174
99206
  }
99175
- function getElementAtPath(obj, path36) {
99176
- if (!path36)
99207
+ function getElementAtPath(obj, path37) {
99208
+ if (!path37)
99177
99209
  return obj;
99178
- return path36.reduce((acc, key) => acc?.[key], obj);
99210
+ return path37.reduce((acc, key) => acc?.[key], obj);
99179
99211
  }
99180
99212
  function promiseAllObject(promisesObj) {
99181
99213
  const keys2 = Object.keys(promisesObj);
@@ -99584,11 +99616,11 @@ function explicitlyAborted(x, startIndex = 0) {
99584
99616
  }
99585
99617
  return false;
99586
99618
  }
99587
- function prefixIssues(path36, issues) {
99619
+ function prefixIssues(path37, issues) {
99588
99620
  return issues.map((iss) => {
99589
99621
  var _a3;
99590
99622
  (_a3 = iss).path ?? (_a3.path = []);
99591
- iss.path.unshift(path36);
99623
+ iss.path.unshift(path37);
99592
99624
  return iss;
99593
99625
  });
99594
99626
  }
@@ -99735,16 +99767,16 @@ function flattenError(error51, mapper = (issue2) => issue2.message) {
99735
99767
  }
99736
99768
  function formatError(error51, mapper = (issue2) => issue2.message) {
99737
99769
  const fieldErrors = { _errors: [] };
99738
- const processError = (error52, path36 = []) => {
99770
+ const processError = (error52, path37 = []) => {
99739
99771
  for (const issue2 of error52.issues) {
99740
99772
  if (issue2.code === "invalid_union" && issue2.errors.length) {
99741
- issue2.errors.map((issues) => processError({ issues }, [...path36, ...issue2.path]));
99773
+ issue2.errors.map((issues) => processError({ issues }, [...path37, ...issue2.path]));
99742
99774
  } else if (issue2.code === "invalid_key") {
99743
- processError({ issues: issue2.issues }, [...path36, ...issue2.path]);
99775
+ processError({ issues: issue2.issues }, [...path37, ...issue2.path]);
99744
99776
  } else if (issue2.code === "invalid_element") {
99745
- processError({ issues: issue2.issues }, [...path36, ...issue2.path]);
99777
+ processError({ issues: issue2.issues }, [...path37, ...issue2.path]);
99746
99778
  } else {
99747
- const fullpath = [...path36, ...issue2.path];
99779
+ const fullpath = [...path37, ...issue2.path];
99748
99780
  if (fullpath.length === 0) {
99749
99781
  fieldErrors._errors.push(mapper(issue2));
99750
99782
  } else {
@@ -99771,17 +99803,17 @@ function formatError(error51, mapper = (issue2) => issue2.message) {
99771
99803
  }
99772
99804
  function treeifyError(error51, mapper = (issue2) => issue2.message) {
99773
99805
  const result = { errors: [] };
99774
- const processError = (error52, path36 = []) => {
99806
+ const processError = (error52, path37 = []) => {
99775
99807
  var _a3, _b;
99776
99808
  for (const issue2 of error52.issues) {
99777
99809
  if (issue2.code === "invalid_union" && issue2.errors.length) {
99778
- issue2.errors.map((issues) => processError({ issues }, [...path36, ...issue2.path]));
99810
+ issue2.errors.map((issues) => processError({ issues }, [...path37, ...issue2.path]));
99779
99811
  } else if (issue2.code === "invalid_key") {
99780
- processError({ issues: issue2.issues }, [...path36, ...issue2.path]);
99812
+ processError({ issues: issue2.issues }, [...path37, ...issue2.path]);
99781
99813
  } else if (issue2.code === "invalid_element") {
99782
- processError({ issues: issue2.issues }, [...path36, ...issue2.path]);
99814
+ processError({ issues: issue2.issues }, [...path37, ...issue2.path]);
99783
99815
  } else {
99784
- const fullpath = [...path36, ...issue2.path];
99816
+ const fullpath = [...path37, ...issue2.path];
99785
99817
  if (fullpath.length === 0) {
99786
99818
  result.errors.push(mapper(issue2));
99787
99819
  continue;
@@ -99813,8 +99845,8 @@ function treeifyError(error51, mapper = (issue2) => issue2.message) {
99813
99845
  }
99814
99846
  function toDotPath(_path) {
99815
99847
  const segs = [];
99816
- const path36 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
99817
- for (const seg of path36) {
99848
+ const path37 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
99849
+ for (const seg of path37) {
99818
99850
  if (typeof seg === "number")
99819
99851
  segs.push(`[${seg}]`);
99820
99852
  else if (typeof seg === "symbol")
@@ -112587,13 +112619,13 @@ function resolveRef(ref, ctx) {
112587
112619
  if (!ref.startsWith("#")) {
112588
112620
  throw new Error("External $ref is not supported, only local refs (#/...) are allowed");
112589
112621
  }
112590
- const path36 = ref.slice(1).split("/").filter(Boolean);
112591
- if (path36.length === 0) {
112622
+ const path37 = ref.slice(1).split("/").filter(Boolean);
112623
+ if (path37.length === 0) {
112592
112624
  return ctx.rootSchema;
112593
112625
  }
112594
112626
  const defsKey = ctx.version === "draft-2020-12" ? "$defs" : "definitions";
112595
- if (path36[0] === defsKey) {
112596
- const key = path36[1];
112627
+ if (path37[0] === defsKey) {
112628
+ const key = path37[1];
112597
112629
  if (!key || !ctx.defs[key]) {
112598
112630
  throw new Error(`Reference not found: ${ref}`);
112599
112631
  }
@@ -113388,6 +113420,138 @@ function normalizeDocumentText(value) {
113388
113420
  var logger10 = createModuleLogger("neural.mcpServer");
113389
113421
  var VIDEO_GENERATION_SKILL_ID = OFFICIAL_MEDIA_SKILL_IDS[0];
113390
113422
  var AUTO_LOCAL_ENHANCER_LIMIT = 2;
113423
+ var WORKDIR_ATTACHMENT_MARKER_KIND = "ahchat_workdir_attachment";
113424
+ var WORKDIR_FIND_DEFAULT_MAX_RESULTS = 20;
113425
+ var WORKDIR_FIND_MAX_RESULTS = 50;
113426
+ var WORKDIR_FIND_MAX_SCANNED_FILES = 5e3;
113427
+ var WORKDIR_FIND_MAX_DEPTH = 8;
113428
+ var WORKDIR_FIND_SKIP_DIRS = /* @__PURE__ */ new Set([
113429
+ ".ahchat-attachments",
113430
+ ".git",
113431
+ ".next",
113432
+ ".turbo",
113433
+ "build",
113434
+ "coverage",
113435
+ "dist",
113436
+ "node_modules"
113437
+ ]);
113438
+ var WORKDIR_FILE_MIME_BY_EXT = {
113439
+ ".csv": "text/csv",
113440
+ ".doc": "application/msword",
113441
+ ".docx": "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
113442
+ ".gif": "image/gif",
113443
+ ".htm": "text/html",
113444
+ ".html": "text/html",
113445
+ ".jpeg": "image/jpeg",
113446
+ ".jpg": "image/jpeg",
113447
+ ".json": "application/json",
113448
+ ".m4a": "audio/mp4",
113449
+ ".md": "text/markdown",
113450
+ ".mp3": "audio/mpeg",
113451
+ ".mp4": "video/mp4",
113452
+ ".pdf": "application/pdf",
113453
+ ".png": "image/png",
113454
+ ".ppt": "application/vnd.ms-powerpoint",
113455
+ ".pptx": "application/vnd.openxmlformats-officedocument.presentationml.presentation",
113456
+ ".svg": "image/svg+xml",
113457
+ ".txt": "text/plain",
113458
+ ".wav": "audio/wav",
113459
+ ".webm": "video/webm",
113460
+ ".webp": "image/webp",
113461
+ ".xls": "application/vnd.ms-excel",
113462
+ ".xlsx": "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
113463
+ };
113464
+ function normalizeWorkdirRelativePath(value) {
113465
+ return value.split(import_node_path11.default.sep).join("/");
113466
+ }
113467
+ function inferWorkdirFileMimeType(filePath) {
113468
+ return WORKDIR_FILE_MIME_BY_EXT[import_node_path11.default.extname(filePath).toLowerCase()] ?? "application/octet-stream";
113469
+ }
113470
+ function boundedWorkdirResultLimit(value) {
113471
+ if (!Number.isFinite(value)) return WORKDIR_FIND_DEFAULT_MAX_RESULTS;
113472
+ return Math.min(WORKDIR_FIND_MAX_RESULTS, Math.max(1, Math.floor(value)));
113473
+ }
113474
+ async function resolveWorkdirRoot(cwd) {
113475
+ const rawCwd = (cwd ?? process.cwd()).trim();
113476
+ if (!rawCwd) throw new Error("\u5F53\u524D scope \u6CA1\u6709\u53EF\u7528\u5DE5\u4F5C\u76EE\u5F55\u3002");
113477
+ const resolvedCwd = import_node_path11.default.resolve(rawCwd);
113478
+ const stat3 = await import_promises3.default.stat(resolvedCwd).catch(() => null);
113479
+ if (!stat3?.isDirectory()) throw new Error(`\u5DE5\u4F5C\u76EE\u5F55\u4E0D\u53EF\u7528\uFF1A${resolvedCwd}`);
113480
+ return { cwd: resolvedCwd, realCwd: await import_promises3.default.realpath(resolvedCwd) };
113481
+ }
113482
+ async function resolveWorkdirFilePath(requestedPath, cwd) {
113483
+ const trimmed = requestedPath.trim();
113484
+ if (!trimmed) throw new Error("path \u4E0D\u80FD\u4E3A\u7A7A\u3002");
113485
+ const root = await resolveWorkdirRoot(cwd);
113486
+ const candidate = import_node_path11.default.resolve(root.cwd, trimmed);
113487
+ let realTarget;
113488
+ try {
113489
+ realTarget = await import_promises3.default.realpath(candidate);
113490
+ } catch {
113491
+ throw new Error(`\u6587\u4EF6\u4E0D\u5B58\u5728\uFF1A${trimmed}`);
113492
+ }
113493
+ if (!isPathInside(root.realCwd, realTarget)) {
113494
+ throw new Error("\u53EA\u80FD\u8BBF\u95EE\u5F53\u524D scope \u5DE5\u4F5C\u76EE\u5F55\u5185\u7684\u6587\u4EF6\u3002");
113495
+ }
113496
+ const stat3 = await import_promises3.default.stat(realTarget);
113497
+ if (!stat3.isFile()) throw new Error(`\u4E0D\u662F\u53EF\u53D1\u9001\u6587\u4EF6\uFF1A${trimmed}`);
113498
+ const relativePath = normalizeWorkdirRelativePath(import_node_path11.default.relative(root.realCwd, realTarget));
113499
+ return {
113500
+ absolutePath: realTarget,
113501
+ fileName: import_node_path11.default.basename(realTarget),
113502
+ relativePath,
113503
+ size: stat3.size,
113504
+ mtimeMs: stat3.mtimeMs
113505
+ };
113506
+ }
113507
+ function formatWorkdirFileSize(bytes) {
113508
+ if (bytes < 1024) return `${bytes} B`;
113509
+ if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;
113510
+ return `${(bytes / 1024 / 1024).toFixed(1)} MB`;
113511
+ }
113512
+ async function findWorkdirFiles(args) {
113513
+ const root = await resolveWorkdirRoot(args.cwd);
113514
+ const needle = args.query?.trim().toLowerCase() ?? "";
113515
+ const limit = boundedWorkdirResultLimit(args.maxResults);
113516
+ const results = [];
113517
+ let scanned = 0;
113518
+ async function walk(dir, depth) {
113519
+ if (results.length >= limit || scanned >= WORKDIR_FIND_MAX_SCANNED_FILES || depth > WORKDIR_FIND_MAX_DEPTH) return;
113520
+ let entries;
113521
+ try {
113522
+ entries = await import_promises3.default.readdir(dir, { withFileTypes: true });
113523
+ } catch {
113524
+ return;
113525
+ }
113526
+ entries.sort((a, b) => a.name.localeCompare(b.name));
113527
+ for (const entry of entries) {
113528
+ if (results.length >= limit || scanned >= WORKDIR_FIND_MAX_SCANNED_FILES) break;
113529
+ if (entry.isDirectory()) {
113530
+ if (!WORKDIR_FIND_SKIP_DIRS.has(entry.name)) {
113531
+ await walk(import_node_path11.default.join(dir, entry.name), depth + 1);
113532
+ }
113533
+ continue;
113534
+ }
113535
+ if (!entry.isFile()) continue;
113536
+ scanned++;
113537
+ const absolutePath = import_node_path11.default.join(dir, entry.name);
113538
+ const relativePath = normalizeWorkdirRelativePath(import_node_path11.default.relative(root.realCwd, absolutePath));
113539
+ if (needle && !relativePath.toLowerCase().includes(needle) && !entry.name.toLowerCase().includes(needle)) {
113540
+ continue;
113541
+ }
113542
+ const stat3 = await import_promises3.default.stat(absolutePath).catch(() => null);
113543
+ if (!stat3?.isFile()) continue;
113544
+ results.push({
113545
+ relativePath,
113546
+ fileName: entry.name,
113547
+ size: stat3.size,
113548
+ mtimeMs: stat3.mtimeMs
113549
+ });
113550
+ }
113551
+ }
113552
+ await walk(root.realCwd, 0);
113553
+ return results.sort((a, b) => b.mtimeMs - a.mtimeMs).slice(0, limit);
113554
+ }
113391
113555
  function formatSkillEntry(entry, index) {
113392
113556
  return [
113393
113557
  `${index + 1}. ${entry.displayName} (${entry.name})`,
@@ -114342,6 +114506,122 @@ ${result.warnings.map((warning) => `- ${warning}`).join("\n")}
114342
114506
  },
114343
114507
  {}
114344
114508
  );
114509
+ const findWorkdirFilesTool = sdk.tool(
114510
+ "find_workdir_files",
114511
+ `Find files inside the current scope working directory only.
114512
+ Use this when the user asks you to locate a generated/output file before sending it as an attachment. It returns relative paths that can be passed to send_workdir_file.`,
114513
+ {
114514
+ query: external_exports.string().optional().describe("Optional case-insensitive substring to match against file names or relative paths."),
114515
+ max_results: external_exports.number().int().min(1).max(WORKDIR_FIND_MAX_RESULTS).optional().describe(
114516
+ `Maximum files to return. Defaults to ${WORKDIR_FIND_DEFAULT_MAX_RESULTS}, hard max ${WORKDIR_FIND_MAX_RESULTS}.`
114517
+ )
114518
+ },
114519
+ async (args) => {
114520
+ const query4 = args.query?.trim();
114521
+ const maxResults = boundedWorkdirResultLimit(args.max_results);
114522
+ logger10.info("find_workdir_files tool called", {
114523
+ agentId: deps.agentId,
114524
+ scope: currentScopeKey,
114525
+ query: query4 ?? null,
114526
+ maxResults
114527
+ });
114528
+ try {
114529
+ const files = await findWorkdirFiles({
114530
+ cwd: deps.cwd,
114531
+ query: query4,
114532
+ maxResults
114533
+ });
114534
+ if (files.length === 0) {
114535
+ return {
114536
+ content: [{
114537
+ type: "text",
114538
+ text: `[find_workdir_files] \u672A\u627E\u5230\u5339\u914D\u6587\u4EF6\u3002scope=${currentScopeKey}`
114539
+ }]
114540
+ };
114541
+ }
114542
+ const lines = files.map((file2, index) => {
114543
+ const modified = new Date(file2.mtimeMs).toISOString();
114544
+ return `${index + 1}. ${file2.relativePath} (${formatWorkdirFileSize(file2.size)}, modified ${modified})`;
114545
+ });
114546
+ return {
114547
+ content: [{
114548
+ type: "text",
114549
+ text: [
114550
+ `[find_workdir_files] \u627E\u5230 ${files.length} \u4E2A\u6587\u4EF6\uFF08\u53EA\u80FD\u53D1\u9001\u5F53\u524D scope \u5DE5\u4F5C\u76EE\u5F55\u5185\u6587\u4EF6\uFF09\uFF1A`,
114551
+ ...lines,
114552
+ "",
114553
+ '\u8981\u53D1\u7ED9\u7528\u6237\u65F6\uFF0C\u8C03\u7528 send_workdir_file(path="<\u4E0A\u9762\u7684\u76F8\u5BF9\u8DEF\u5F84>")\u3002'
114554
+ ].join("\n")
114555
+ }]
114556
+ };
114557
+ } catch (e) {
114558
+ const message = e instanceof Error ? e.message : String(e);
114559
+ logger10.error("find_workdir_files failed", {
114560
+ agentId: deps.agentId,
114561
+ scope: currentScopeKey,
114562
+ query: query4 ?? null,
114563
+ error: e
114564
+ });
114565
+ return {
114566
+ content: [{ type: "text", text: `[find_workdir_files] failed: ${message}` }],
114567
+ isError: true
114568
+ };
114569
+ }
114570
+ },
114571
+ {}
114572
+ );
114573
+ const sendWorkdirFileTool = sdk.tool(
114574
+ "send_workdir_file",
114575
+ `Send a real file from the current scope working directory as a clickable AHChat attachment on this visible reply.
114576
+ Only files inside the current scope cwd are allowed. Directories, missing files, and paths outside cwd are rejected. Pass a relative path from find_workdir_files when possible.`,
114577
+ {
114578
+ path: external_exports.string().min(1).describe("File path to send. Prefer a relative path returned by find_workdir_files; absolute paths are accepted only when they are inside the current scope cwd.")
114579
+ },
114580
+ async (args) => {
114581
+ const requestedPath = args.path.trim();
114582
+ logger10.info("send_workdir_file tool called", {
114583
+ agentId: deps.agentId,
114584
+ scope: currentScopeKey,
114585
+ path: requestedPath
114586
+ });
114587
+ try {
114588
+ const file2 = await resolveWorkdirFilePath(requestedPath, deps.cwd);
114589
+ const marker = {
114590
+ ok: true,
114591
+ kind: WORKDIR_ATTACHMENT_MARKER_KIND,
114592
+ path: file2.absolutePath,
114593
+ relative_path: file2.relativePath,
114594
+ file_name: file2.fileName,
114595
+ mime_type: inferWorkdirFileMimeType(file2.absolutePath),
114596
+ size: file2.size,
114597
+ attachment_source: "agent_explicit_send"
114598
+ };
114599
+ return {
114600
+ content: [{
114601
+ type: "text",
114602
+ text: [
114603
+ JSON.stringify(marker),
114604
+ "",
114605
+ `[send_workdir_file] \u5DF2\u51C6\u5907\u53D1\u9001\u9644\u4EF6\uFF1A${file2.relativePath} (${formatWorkdirFileSize(file2.size)})\u3002\u8BF7\u5728\u672C\u8F6E\u53EF\u89C1\u56DE\u590D\u91CC\u7B80\u77ED\u8BF4\u660E\u9644\u4EF6\u5DF2\u9644\u4E0A\uFF0C\u4E0D\u8981\u91CD\u590D\u8F93\u51FA\u6587\u4EF6\u5168\u6587\u3002`
114606
+ ].join("\n")
114607
+ }]
114608
+ };
114609
+ } catch (e) {
114610
+ const message = e instanceof Error ? e.message : String(e);
114611
+ logger10.error("send_workdir_file failed", {
114612
+ agentId: deps.agentId,
114613
+ scope: currentScopeKey,
114614
+ path: requestedPath,
114615
+ error: e
114616
+ });
114617
+ return {
114618
+ content: [{ type: "text", text: `[send_workdir_file] failed: ${message}` }],
114619
+ isError: true
114620
+ };
114621
+ }
114622
+ },
114623
+ {}
114624
+ );
114345
114625
  const createGroupIssueTool = deps.serverApiUrl ? sdk.tool(
114346
114626
  "create_group_issue",
114347
114627
  `\u628A\u5F53\u524D\u7FA4\u91CC\u7684\u771F\u5B9E\u95EE\u9898\u5199\u5165\u95EE\u9898\u9762\u677F\u3002
@@ -115629,7 +115909,7 @@ nextOffset=${json2.nextOffset}\uFF08\u7EE7\u7EED\u67E5\u8BE2\u65F6\u4F20 offset=
115629
115909
  system_prompt: external_exports.string().describe("\u8BE5 Agent \u7684 system prompt\uFF0C\u5B9A\u4E49\u4EBA\u683C\u3001\u4E13\u957F\u3001\u884C\u4E3A\u51C6\u5219\u3002\u4E0D\u80FD\u4E3A\u7A7A\u3002"),
115630
115910
  tier: external_exports.enum(["smart", "balanced", "fast"]).describe("\u80FD\u529B\u6863\u4F4D\uFF1Asmart\uFF08\u65D7\u8230\uFF0C\u590D\u6742\u4EFB\u52A1\uFF09\u3001balanced\uFF08\u6807\u51C6\uFF0C\u5E38\u89C4\u4EFB\u52A1\uFF09\u3001fast\uFF08\u8F7B\u91CF\uFF0C\u7B80\u5355\u4EFB\u52A1\uFF09\u3002"),
115631
115911
  avatar: external_exports.string().optional().describe(
115632
- "\u5934\u50CF key\uFF0C\u4ECE\u4EE5\u4E0B\u9009\u4E00\u4E2A\u6700\u5339\u914D\u89D2\u8272\u7684\uFF1Aavatar_dev\uFF08\u5F00\u53D1\uFF09, avatar_pm\uFF08\u4EA7\u54C1/\u7BA1\u7406\uFF09, avatar_designer\uFF08\u8BBE\u8BA1\uFF09, avatar_qa\uFF08\u6D4B\u8BD5/QA\uFF09, avatar_writer\uFF08\u5199\u4F5C/\u6587\u6863\uFF09, avatar_analyst\uFF08\u5206\u6790/\u6570\u636E\uFF09, avatar_coach\uFF08\u654F\u6377\u6559\u7EC3/\u5E26\u6559\uFF09, avatar_scientist\uFF08\u7814\u7A76/\u7B97\u6CD5\uFF09, avatar_lawyer\uFF08\u6CD5\u52A1/\u5408\u89C4\uFF09, avatar_human_man\uFF08\u901A\u7528\u7537\u6027\uFF09, avatar_human_woman\uFF08\u901A\u7528\u5973\u6027\uFF09, avatar_human_nerd\uFF08\u6781\u5BA2\uFF09, avatar_human_cool\uFF08\u9177\uFF09, avatar_human_cowboy\uFF08\u72C2\u91CE\uFF09, avatar_human_artist\uFF08\u827A\u672F\u5BB6\uFF09\u3002\u7559\u7A7A\u5219\u7528\u9ED8\u8BA4 avatar_default\uFF08\u{1F916}\uFF09\u3002"
115912
+ "\u53EF\u9009\u5934\u50CF key\u3002\u901A\u5E38\u7559\u7A7A\uFF0C\u7531\u7CFB\u7EDF\u6839\u636E Agent \u540D\u5B57\u3001\u89D2\u8272\u548C\u63D0\u793A\u8BCD\u81EA\u52A8\u5206\u914D\u673A\u5668\u4EBA\u5934\u50CF\u5E76\u5F02\u6B65\u751F\u6210\u6700\u7EC8\u5934\u50CF\u3002\u4E0D\u8981\u7ED9 Agent \u4F7F\u7528 avatar_human_*\uFF0C\u8FD9\u4E9B\u53EA\u7ED9\u771F\u5B9E\u4EBA\u7C7B\u7528\u6237\u4F7F\u7528\u3002"
115633
115913
  ),
115634
115914
  initial_instruction: external_exports.string().optional().describe(
115635
115915
  '\u53EF\u9009\u3002\u521B\u5EFA\u540E\u7ACB\u5373\u4E0B\u53D1\u7ED9\u65B0 Agent \u7684\u4E00\u53E5\u8BDD\u6307\u4EE4\u3002\u5178\u578B\uFF1A"\u8BF7\u7528 1-2 \u53E5\u8BDD\u5411\u7528\u6237\u505A\u81EA\u6211\u4ECB\u7ECD\uFF0C\u8BF4\u660E\u4F60\u7684\u4E13\u957F"\u3002\u53EA\u5728\u7528\u6237\u660E\u786E\u8981"\u521B\u5EFA\u4E00\u4E2A\u5355 Agent"\u4E14\u5E0C\u671B\u8BE5 Agent \u7ACB\u5373\u9732\u9762\u65F6\u4F20\u3002\u56E2\u961F\u573A\u666F\u8BF7\u52FF\u4F20\u2014\u2014\u7531 Leader \u5728\u7FA4\u91CC\u6253\u62DB\u547C\u3002'
@@ -115972,7 +116252,7 @@ nextOffset=${json2.nextOffset}\uFF08\u7EE7\u7EED\u67E5\u8BE2\u65F6\u4F20 offset=
115972
116252
  system_prompt: external_exports.string().optional().describe("\u65B0\u7684 system prompt\uFF08\u5B9A\u4E49\u4EBA\u683C\u3001\u4E13\u957F\u3001\u884C\u4E3A\u51C6\u5219\uFF09\u3002"),
115973
116253
  tier: external_exports.enum(["smart", "balanced", "fast"]).optional().describe("\u80FD\u529B\u6863\u4F4D\u3002\u4F20\u6B64\u53C2\u6570\u4F1A\u66F4\u65B0\u8BE5 Agent \u4F7F\u7528\u7684\u6A21\u578B\u3002"),
115974
116254
  avatar: external_exports.string().optional().describe(
115975
- "\u5934\u50CF key\uFF08\u5982 avatar_dev / avatar_pm / avatar_human_man \u7B49\uFF09\u3002"
116255
+ "\u5934\u50CF key\uFF08\u5982 avatar_dev / avatar_pm / avatar_default \u7B49\uFF09\u3002\u4E0D\u8981\u7ED9 Agent \u4F7F\u7528 avatar_human_*\uFF0C\u8FD9\u4E9B\u53EA\u7ED9\u771F\u5B9E\u4EBA\u7C7B\u7528\u6237\u4F7F\u7528\u3002"
115976
116256
  ),
115977
116257
  machine_bridge_key: external_exports.string().optional().describe(
115978
116258
  '\u53EF\u9009\u3002\u65B0\u7684\u8FD0\u884C\u673A\u5668 bridgeKey\uFF0C\u6765\u81EA list_contacts \u7684"\u53EF\u7528\u673A\u5668"\u3002\u7701\u7565\u8868\u793A\u4E0D\u6539\uFF1B\u4F20 auto \u6216\u7A7A\u5B57\u7B26\u4E32\u6E05\u9664\u673A\u5668\u504F\u597D\u3002'
@@ -116673,7 +116953,13 @@ nextOffset=${json2.nextOffset}\uFF08\u7EE7\u7EED\u67E5\u8BE2\u65F6\u4F20 offset=
116673
116953
  },
116674
116954
  {}
116675
116955
  ) : null;
116676
- const tools = [neuralSend, neuralListScopes, readDocumentTool];
116956
+ const tools = [
116957
+ neuralSend,
116958
+ neuralListScopes,
116959
+ readDocumentTool,
116960
+ findWorkdirFilesTool,
116961
+ sendWorkdirFileTool
116962
+ ];
116677
116963
  if (readChatHistory) tools.push(readChatHistory);
116678
116964
  if (selfNote) tools.push(selfNote);
116679
116965
  if (listContacts) tools.push(listContacts);
@@ -116705,7 +116991,7 @@ nextOffset=${json2.nextOffset}\uFF08\u7EE7\u7EED\u67E5\u8BE2\u65F6\u4F20 offset=
116705
116991
  version: "2.3.0",
116706
116992
  tools
116707
116993
  });
116708
- const toolNames = ["neural_send", "neural_list_scopes", "read_document"];
116994
+ const toolNames = ["neural_send", "neural_list_scopes", "read_document", "find_workdir_files", "send_workdir_file"];
116709
116995
  if (readChatHistory) toolNames.push("read_chat_history");
116710
116996
  if (selfNote) toolNames.push("self_note");
116711
116997
  if (listContacts) toolNames.push("list_contacts");
@@ -116974,9 +117260,11 @@ function buildGroupInboxPrompt(entries, opts = {}) {
116974
117260
  // src/sdkEventMapper.ts
116975
117261
  init_cjs_shims();
116976
117262
  var logger12 = createModuleLogger("sdk.mapper");
117263
+ var DEBUG_ONLY_SYSTEM_SUBTYPES = /* @__PURE__ */ new Set(["status", "thinking_tokens"]);
116977
117264
  var HIGH_WATERMARK_INPUT_TOKENS = 12e4;
116978
117265
  var WARN_THRESHOLD_INPUT_TOKENS = 1e5;
116979
117266
  var LIVE_INPUT_PREVIEW_TOOLS = /* @__PURE__ */ new Set(["Write", "Edit"]);
117267
+ var WORKDIR_MUTATION_TOOL_NAMES = /* @__PURE__ */ new Set(["write", "edit", "multiedit", "notebookedit", "bash"]);
116980
117268
  var CONTEXT_OVERFLOW_LOCK_MS = 6e4;
116981
117269
  function parseJsonRecord(text) {
116982
117270
  try {
@@ -116998,6 +117286,17 @@ function isSuccessfulOfficialMediaOutput(toolName, output) {
116998
117286
  if (!["succeeded", "success", "completed", "done"].includes(state)) return false;
116999
117287
  return Array.isArray(parsed.images) && parsed.images.length > 0 || typeof parsed.video_url === "string" || typeof parsed.videoUrl === "string";
117000
117288
  }
117289
+ function isWorkdirMutationToolName(toolName) {
117290
+ return WORKDIR_MUTATION_TOOL_NAMES.has(toolName.trim().toLowerCase());
117291
+ }
117292
+ function recordWorkdirSignal(proc, toolName, isError) {
117293
+ if (isError || !isGroupTask(proc) || !isWorkdirMutationToolName(toolName)) return;
117294
+ const signals = proc.workdirSignals ?? [];
117295
+ if (!signals.some((signal) => signal.toolName === toolName)) {
117296
+ signals.push({ toolName });
117297
+ }
117298
+ proc.workdirSignals = signals;
117299
+ }
117001
117300
  function isContextOverflowText(text) {
117002
117301
  const trimmed = text.trim();
117003
117302
  return /^prompt is too long\b/i.test(trimmed) || /context length .* exceed/i.test(trimmed);
@@ -117502,6 +117801,7 @@ function countByStatus(todos) {
117502
117801
  function emitGroupSegment(proc, emit, base, content, contentBlocks, isSilent = false) {
117503
117802
  const groupId = proc.currentTask?.groupId;
117504
117803
  if (!groupId) return;
117804
+ const workdirSignals = proc.workdirSignals?.length ? [...proc.workdirSignals] : void 0;
117505
117805
  proc.segmentCount += 1;
117506
117806
  logger12.info("Group segment emitted", {
117507
117807
  agentId: base.agentId,
@@ -117511,6 +117811,7 @@ function emitGroupSegment(proc, emit, base, content, contentBlocks, isSilent = f
117511
117811
  contentLen: content.length,
117512
117812
  blockCount: contentBlocks.length,
117513
117813
  blockTypes: contentBlocks.map((b) => b.type),
117814
+ workdirSignalCount: workdirSignals?.length ?? 0,
117514
117815
  traceId: base.traceId,
117515
117816
  isAuditOnly: content.length === 0,
117516
117817
  isSilent
@@ -117523,9 +117824,11 @@ function emitGroupSegment(proc, emit, base, content, contentBlocks, isSilent = f
117523
117824
  groupId,
117524
117825
  content,
117525
117826
  contentBlocks: [...contentBlocks],
117827
+ ...workdirSignals ? { workdirSignals } : {},
117526
117828
  ...isSilent ? { isSilent: true } : {}
117527
117829
  }
117528
117830
  });
117831
+ proc.workdirSignals = [];
117529
117832
  }
117530
117833
  function flushTextSegmentOnBlockStop(proc, emit, base) {
117531
117834
  const trimmed = proc.segmentBuffer.trim();
@@ -117544,7 +117847,7 @@ function flushTextSegmentOnBlockStop(proc, emit, base) {
117544
117847
  traceId: base.traceId
117545
117848
  });
117546
117849
  }
117547
- } else if (proc.contentBlocks.length > 0) {
117850
+ } else if (proc.contentBlocks.length > 0 || (proc.workdirSignals?.length ?? 0) > 0) {
117548
117851
  const blockCount = proc.contentBlocks.length;
117549
117852
  emitGroupSegment(proc, emit, base, "", proc.contentBlocks, true);
117550
117853
  proc.contentBlocks = [];
@@ -117634,7 +117937,8 @@ function mapSDKMessage(proc, message, rawEmit, sessionStore, onCompleted, onPost
117634
117937
  proc.activeSubagentTaskIds?.delete(subagentTaskId);
117635
117938
  }
117636
117939
  }
117637
- logger12.info("SDK system subtype unhandled", {
117940
+ const logUnhandledSystemSubtype = DEBUG_ONLY_SYSTEM_SUBTYPES.has(String(sysMsg.subtype ?? "")) ? logger12.debug.bind(logger12) : logger12.info.bind(logger12);
117941
+ logUnhandledSystemSubtype("SDK system subtype unhandled", {
117638
117942
  agentId: proc.agentId,
117639
117943
  scope: proc.scope.kind === "single" ? "single" : proc.scope.groupId,
117640
117944
  subtype: sysMsg.subtype ?? "(none)",
@@ -117691,6 +117995,8 @@ function mapSDKMessage(proc, message, rawEmit, sessionStore, onCompleted, onPost
117691
117995
  input: {}
117692
117996
  }
117693
117997
  });
117998
+ }
117999
+ if (shouldStreamInternals(proc) && !proc.suppressCurrentToolUse && toolName !== "ExitPlanMode" && !isAskUserQuestionToolName(toolName)) {
117694
118000
  proc.contentBlocks.push({
117695
118001
  type: "tool_use",
117696
118002
  ...toolUseId ? { toolUseId } : {},
@@ -118031,6 +118337,7 @@ function mapSDKMessage(proc, message, rawEmit, sessionStore, onCompleted, onPost
118031
118337
  }
118032
118338
  }
118033
118339
  }
118340
+ recordWorkdirSignal(proc, toolName, isError);
118034
118341
  proc.activeToolUseStartedAt = void 0;
118035
118342
  proc.currentToolUseId = null;
118036
118343
  }
@@ -118092,7 +118399,7 @@ function mapSDKMessage(proc, message, rawEmit, sessionStore, onCompleted, onPost
118092
118399
  if (isNoReplyText(trimmed, { allowSdkSyntheticNoResponse: groupMode })) {
118093
118400
  checkInputTokenWatermark(proc, watermarkUsage, base.traceId);
118094
118401
  emitUsageReported(proc, emit, base, usage);
118095
- if (groupMode && proc.contentBlocks.length > 0) {
118402
+ if (groupMode && (proc.contentBlocks.length > 0 || (proc.workdirSignals?.length ?? 0) > 0)) {
118096
118403
  emitGroupSegment(
118097
118404
  proc,
118098
118405
  emit,
@@ -118137,11 +118444,12 @@ function mapSDKMessage(proc, message, rawEmit, sessionStore, onCompleted, onPost
118137
118444
  proc.segmentBuffer = proc.accumulatedText;
118138
118445
  flushTextSegmentOnBlockStop(proc, emit, base);
118139
118446
  }
118140
- if (proc.contentBlocks.length > 0) {
118447
+ if (proc.contentBlocks.length > 0 || (proc.workdirSignals?.length ?? 0) > 0) {
118141
118448
  logger12.info("Group turn trailing audit segment", {
118142
118449
  agentId: proc.agentId,
118143
118450
  replyMessageId: base.replyMessageId,
118144
118451
  blockCount: proc.contentBlocks.length,
118452
+ workdirSignalCount: proc.workdirSignals?.length ?? 0,
118145
118453
  traceId: base.traceId
118146
118454
  });
118147
118455
  emitGroupSegment(proc, emit, base, "", proc.contentBlocks, true);
@@ -118286,6 +118594,7 @@ function mapSDKMessage(proc, message, rawEmit, sessionStore, onCompleted, onPost
118286
118594
  payload: { ...wireBase(base), error: errorText }
118287
118595
  });
118288
118596
  proc.contentBlocks = [];
118597
+ proc.workdirSignals = [];
118289
118598
  proc.accumulatedText = "";
118290
118599
  proc.accumulatedThinking = "";
118291
118600
  proc.segmentBuffer = "";
@@ -118318,6 +118627,7 @@ function mapSDKMessage(proc, message, rawEmit, sessionStore, onCompleted, onPost
118318
118627
  proc.apiErrorEmitted = true;
118319
118628
  }
118320
118629
  proc.contentBlocks = [];
118630
+ proc.workdirSignals = [];
118321
118631
  proc.accumulatedText = "";
118322
118632
  proc.accumulatedThinking = "";
118323
118633
  proc.segmentBuffer = "";
@@ -118344,6 +118654,7 @@ function mapSDKMessage(proc, message, rawEmit, sessionStore, onCompleted, onPost
118344
118654
  proc.apiErrorEmitted = true;
118345
118655
  }
118346
118656
  proc.contentBlocks = [];
118657
+ proc.workdirSignals = [];
118347
118658
  proc.accumulatedText = "";
118348
118659
  proc.accumulatedThinking = "";
118349
118660
  proc.segmentBuffer = "";
@@ -118380,6 +118691,7 @@ function mapSDKMessage(proc, message, rawEmit, sessionStore, onCompleted, onPost
118380
118691
  });
118381
118692
  }
118382
118693
  proc.contentBlocks = [];
118694
+ proc.workdirSignals = [];
118383
118695
  proc.accumulatedText = "";
118384
118696
  proc.accumulatedThinking = "";
118385
118697
  proc.segmentBuffer = "";
@@ -118421,6 +118733,7 @@ function resetAccumulators(proc) {
118421
118733
  proc.activeToolUseStartedAt = void 0;
118422
118734
  proc.segmentBuffer = "";
118423
118735
  proc.segmentCount = 0;
118736
+ proc.workdirSignals = [];
118424
118737
  proc.accumulatedToolInput = "";
118425
118738
  proc.apiErrorEmitted = false;
118426
118739
  proc.peakContextUsage = void 0;
@@ -118433,24 +118746,24 @@ function resetAccumulators(proc) {
118433
118746
 
118434
118747
  // src/forkHistoryReplay.ts
118435
118748
  init_cjs_shims();
118436
- var fs5 = __toESM(require("fs/promises"), 1);
118437
- var path11 = __toESM(require("path"), 1);
118749
+ var fs6 = __toESM(require("fs/promises"), 1);
118750
+ var path12 = __toESM(require("path"), 1);
118438
118751
  var logger13 = createModuleLogger("bridge.forkHistoryReplay");
118439
118752
  function metaPath(dataDir, agentId) {
118440
- return path11.join(dataDir, "fork-meta", `${agentId}.json`);
118753
+ return path12.join(dataDir, "fork-meta", `${agentId}.json`);
118441
118754
  }
118442
118755
  async function writeForkMeta(dataDir, agentId, meta3) {
118443
118756
  const fp = metaPath(dataDir, agentId);
118444
- await fs5.mkdir(path11.dirname(fp), { recursive: true });
118445
- await fs5.writeFile(fp, JSON.stringify(meta3), "utf-8");
118757
+ await fs6.mkdir(path12.dirname(fp), { recursive: true });
118758
+ await fs6.writeFile(fp, JSON.stringify(meta3), "utf-8");
118446
118759
  logger13.info("Fork meta written", { agentId, fp, sourceConversationId: meta3.sourceConversationId });
118447
118760
  }
118448
118761
  async function consumeForkMeta(dataDir, agentId) {
118449
118762
  const fp = metaPath(dataDir, agentId);
118450
118763
  try {
118451
- const raw = await fs5.readFile(fp, "utf-8");
118764
+ const raw = await fs6.readFile(fp, "utf-8");
118452
118765
  const meta3 = JSON.parse(raw);
118453
- await fs5.unlink(fp);
118766
+ await fs6.unlink(fp);
118454
118767
  logger13.info("Fork meta consumed (one-shot)", { agentId, sourceConversationId: meta3.sourceConversationId });
118455
118768
  return meta3;
118456
118769
  } catch {
@@ -118478,21 +118791,21 @@ function buildForkHistorySection(messages) {
118478
118791
  // src/sessionSlug.ts
118479
118792
  init_cjs_shims();
118480
118793
  var import_node_os6 = __toESM(require("os"), 1);
118481
- var import_node_path11 = __toESM(require("path"), 1);
118482
- var CLAUDE_PROJECTS_DIR = import_node_path11.default.join(import_node_os6.default.homedir(), ".claude", "projects");
118794
+ var import_node_path12 = __toESM(require("path"), 1);
118795
+ var CLAUDE_PROJECTS_DIR = import_node_path12.default.join(import_node_os6.default.homedir(), ".claude", "projects");
118483
118796
  function cwdToSlug(cwd) {
118484
118797
  return cwd.replace(/[^a-zA-Z0-9-]/g, "-");
118485
118798
  }
118486
118799
  function sessionDirForCwd(cwd) {
118487
- return import_node_path11.default.join(CLAUDE_PROJECTS_DIR, cwdToSlug(cwd));
118800
+ return import_node_path12.default.join(CLAUDE_PROJECTS_DIR, cwdToSlug(cwd));
118488
118801
  }
118489
118802
  function sessionFilePath(cwd, sessionId) {
118490
- return import_node_path11.default.join(sessionDirForCwd(cwd), `${sessionId}.jsonl`);
118803
+ return import_node_path12.default.join(sessionDirForCwd(cwd), `${sessionId}.jsonl`);
118491
118804
  }
118492
118805
 
118493
118806
  // src/workdirMapper.ts
118494
118807
  init_cjs_shims();
118495
- var import_node_path12 = __toESM(require("path"), 1);
118808
+ var import_node_path13 = __toESM(require("path"), 1);
118496
118809
  function extractAhchatWorkspaceParts(requestedPath) {
118497
118810
  const normalized = requestedPath.trim().replace(/\\/g, "/");
118498
118811
  const marker = "/.ahchat/users/";
@@ -118528,15 +118841,15 @@ function extractAhchatWorkspaceParts(requestedPath) {
118528
118841
  function extractAhchatWorkspaceSuffix(requestedPath) {
118529
118842
  const parts = extractAhchatWorkspaceParts(requestedPath);
118530
118843
  if (!parts || parts.length === 0) return null;
118531
- return import_node_path12.default.join(...parts);
118844
+ return import_node_path13.default.join(...parts);
118532
118845
  }
118533
118846
  function remapServerWorkspacePath(requestedPath, workspacesDir) {
118534
118847
  const parts = extractAhchatWorkspaceParts(requestedPath);
118535
118848
  if (!parts) return { path: requestedPath, remapped: false };
118536
- const remappedPath = parts.length > 0 ? import_node_path12.default.join(workspacesDir, ...parts) : workspacesDir;
118849
+ const remappedPath = parts.length > 0 ? import_node_path13.default.join(workspacesDir, ...parts) : workspacesDir;
118537
118850
  return {
118538
118851
  path: remappedPath,
118539
- remapped: import_node_path12.default.normalize(requestedPath) !== import_node_path12.default.normalize(remappedPath)
118852
+ remapped: import_node_path13.default.normalize(requestedPath) !== import_node_path13.default.normalize(remappedPath)
118540
118853
  };
118541
118854
  }
118542
118855
 
@@ -118620,7 +118933,7 @@ function missingSubscriptionMessage(subscriptionId) {
118620
118933
  }
118621
118934
  var NODE_USER_UID = 1e3;
118622
118935
  var POST_MERGE_CONTINUATION_ROUTE_MS = 15e3;
118623
- var SCOPE_PROMPT_FINGERPRINT_REVISION = "workdir-scope-mcp-abi-prompt-v4";
118936
+ var SCOPE_PROMPT_FINGERPRINT_REVISION = "workdir-scope-mcp-abi-prompt-v6";
118624
118937
  var BINARY_ATTACHMENT_EXT_RE = /\.(?:7z|bmp|csv|doc|docx|gif|jpeg|jpg|m4a|mov|mp3|mp4|pdf|png|ppt|pptx|rar|rtf|wav|webm|webp|xls|xlsx|zip)$/i;
118625
118938
  var IMAGE_READ_EXT_RE = /\.(?:bmp|gif|jpeg|jpg|png|webp)$/i;
118626
118939
  var DOCUMENT_READING_RULES = `DOCUMENT READING:
@@ -118636,6 +118949,72 @@ var MEDIA_GENERATION_RULES = `MEDIA GENERATION:
118636
118949
  - Keep media replies short. Do not print raw media URLs, request_id, task_id, polling logs, or "let me check again" narration unless the user explicitly asks for diagnostics.
118637
118950
  - When a media task is submitted or completed, write only a natural one-line note such as "\u5DF2\u5F00\u59CB\u751F\u6210\uFF0C\u6211\u4F1A\u5728\u8FD9\u91CC\u66F4\u65B0\u7ED3\u679C\u3002" or "\u751F\u6210\u597D\u4E86\uFF0C\u53EF\u4EE5\u5728\u5361\u7247\u91CC\u67E5\u770B\u3002"; let the media card show status, preview, download, copy, and regenerate actions.
118638
118951
  - If the user asks whether a Seedance task is ready, call mcp__seedance__seedance_check_task once and answer from that result. Do not loop, sleep, or invent external Seedance API endpoints.`;
118952
+ var SMITH_ALLOWED_TOOLS = [
118953
+ // creation / configuration (Smith-only)
118954
+ "mcp__neural__create_agent",
118955
+ "mcp__neural__update_agent_profile",
118956
+ "mcp__neural__recommend_agent_skills",
118957
+ "mcp__neural__read_skill",
118958
+ // diagnostics (log detective)
118959
+ "mcp__neural__fetch_logs",
118960
+ // friend approval (Smith-only)
118961
+ "mcp__neural__list_friends",
118962
+ "mcp__neural__accept_friend",
118963
+ "mcp__neural__add_friend",
118964
+ // team assembly
118965
+ "mcp__neural__list_contacts",
118966
+ "mcp__neural__create_group",
118967
+ "mcp__neural__add_to_group",
118968
+ "mcp__neural__transfer_group_owner",
118969
+ "mcp__neural__leave_group",
118970
+ // neural bridge — cross-scope coordination when Smith is pulled into a group
118971
+ "mcp__neural__neural_send",
118972
+ "mcp__neural__neural_list_scopes",
118973
+ // bounded current-scope workdir attachments
118974
+ "mcp__neural__find_workdir_files",
118975
+ "mcp__neural__send_workdir_file",
118976
+ // interaction / planning
118977
+ "AskUserQuestion",
118978
+ "Write"
118979
+ ];
118980
+ function isVisionMcpServerName(serverName) {
118981
+ return serverName === "vision";
118982
+ }
118983
+ function selectSmithVisionMcp(resolved) {
118984
+ const resolvedMcpServers = resolved.mcpServers ?? {};
118985
+ const resolvedAllowedTools = resolved.allowedTools ?? [];
118986
+ const resolvedToolAbi = resolved.toolAbi ?? [];
118987
+ const visionServerNames = /* @__PURE__ */ new Set();
118988
+ for (const server of resolvedToolAbi) {
118989
+ if (server.providerId === "volcengine_vision" || isVisionMcpServerName(server.serverName)) {
118990
+ visionServerNames.add(server.serverName);
118991
+ }
118992
+ }
118993
+ for (const toolName of resolvedAllowedTools) {
118994
+ const parsed = parseMcpRuntimeToolName(toolName);
118995
+ if (parsed && isVisionMcpServerName(parsed.serverName)) {
118996
+ visionServerNames.add(parsed.serverName);
118997
+ }
118998
+ }
118999
+ for (const serverName of Object.keys(resolvedMcpServers)) {
119000
+ if (isVisionMcpServerName(serverName)) {
119001
+ visionServerNames.add(serverName);
119002
+ }
119003
+ }
119004
+ if (visionServerNames.size === 0) {
119005
+ return { mcpServers: {}, allowedTools: [], toolAbi: [] };
119006
+ }
119007
+ return {
119008
+ mcpServers: Object.fromEntries(
119009
+ Object.entries(resolvedMcpServers).filter(([serverName]) => visionServerNames.has(serverName))
119010
+ ),
119011
+ allowedTools: resolvedAllowedTools.filter((toolName) => {
119012
+ const parsed = parseMcpRuntimeToolName(toolName);
119013
+ return Boolean(parsed && visionServerNames.has(parsed.serverName));
119014
+ }),
119015
+ toolAbi: resolvedToolAbi.filter((server) => visionServerNames.has(server.serverName))
119016
+ };
119017
+ }
118639
119018
  function resolveVisionMcpToolHints(externalMcp) {
118640
119019
  let describe3 = null;
118641
119020
  let ocr = null;
@@ -118703,7 +119082,7 @@ function uniqueNormalizedPaths(paths) {
118703
119082
  for (const item of paths) {
118704
119083
  const trimmed = item.trim();
118705
119084
  if (!trimmed) continue;
118706
- const normalized = import_node_path13.default.normalize(trimmed);
119085
+ const normalized = import_node_path14.default.normalize(trimmed);
118707
119086
  const key = process.platform === "win32" ? normalized.toLowerCase() : normalized;
118708
119087
  if (seen.has(key)) continue;
118709
119088
  seen.add(key);
@@ -118733,7 +119112,7 @@ function resolveReadToolImagePath(input, cwd) {
118733
119112
  if (typeof raw !== "string" || raw.trim().length === 0) return null;
118734
119113
  const trimmed = raw.trim();
118735
119114
  if (!IMAGE_READ_EXT_RE.test(trimmed)) return null;
118736
- const abs = import_node_path13.default.isAbsolute(trimmed) ? import_node_path13.default.normalize(trimmed) : import_node_path13.default.resolve(cwd, trimmed);
119115
+ const abs = import_node_path14.default.isAbsolute(trimmed) ? import_node_path14.default.normalize(trimmed) : import_node_path14.default.resolve(cwd, trimmed);
118737
119116
  return { raw: trimmed, abs };
118738
119117
  }
118739
119118
  function usesIsolatedProjectBackend(cfg) {
@@ -118752,14 +119131,14 @@ function buildModelGatewayBaseUrl(serverApiUrl, subscriptionId) {
118752
119131
  }
118753
119132
  async function chownForRootSpawn(targetPath, target) {
118754
119133
  try {
118755
- await import_promises3.default.chown(targetPath, NODE_USER_UID, NODE_USER_UID);
119134
+ await import_promises4.default.chown(targetPath, NODE_USER_UID, NODE_USER_UID);
118756
119135
  } catch (error51) {
118757
119136
  logger15.error("Best-effort root chown failed", { error: error51, target, path: targetPath });
118758
119137
  }
118759
119138
  }
118760
119139
  function readCronLockSnapshot() {
118761
119140
  try {
118762
- const lockPath2 = import_node_path13.default.join(import_node_os7.default.homedir(), ".claude", "scheduled_tasks.lock");
119141
+ const lockPath2 = import_node_path14.default.join(import_node_os7.default.homedir(), ".claude", "scheduled_tasks.lock");
118763
119142
  if (!import_node_fs6.default.existsSync(lockPath2)) {
118764
119143
  return { exists: false, sessionId: null, pid: null };
118765
119144
  }
@@ -119031,8 +119410,8 @@ var AgentManager = class {
119031
119410
  this.emit = emit;
119032
119411
  if (typeof options === "function") {
119033
119412
  this.queryFn = options;
119034
- this.workspacesDir = import_node_path13.default.join(import_node_os7.default.homedir(), ".ahchat", "workspaces");
119035
- this.agentConfigDir = import_node_path13.default.join(import_node_os7.default.homedir(), ".ahchat", "agent-config");
119413
+ this.workspacesDir = import_node_path14.default.join(import_node_os7.default.homedir(), ".ahchat", "workspaces");
119414
+ this.agentConfigDir = import_node_path14.default.join(import_node_os7.default.homedir(), ".ahchat", "agent-config");
119036
119415
  this.queryConfig = DEFAULT_QUERY_CONFIG;
119037
119416
  this.askQuestionRegistry = new AskQuestionRegistry();
119038
119417
  this.groupRegistry = null;
@@ -119049,13 +119428,13 @@ var AgentManager = class {
119049
119428
  this.bridgeToken = null;
119050
119429
  this.currentBridgeKey = null;
119051
119430
  this.defaultModel = null;
119052
- this.dataDir = import_node_path13.default.join(import_node_os7.default.homedir(), ".ahchat");
119431
+ this.dataDir = import_node_path14.default.join(import_node_os7.default.homedir(), ".ahchat");
119053
119432
  this.workdirOverrideStore = null;
119054
119433
  this.officeCliRuntime = null;
119055
119434
  } else {
119056
119435
  this.queryFn = options?.queryFn ?? null;
119057
- this.workspacesDir = options?.workspacesDir ?? import_node_path13.default.join(import_node_os7.default.homedir(), ".ahchat", "workspaces");
119058
- this.agentConfigDir = options?.agentConfigDir ?? import_node_path13.default.join(import_node_os7.default.homedir(), ".ahchat", "agent-config");
119436
+ this.workspacesDir = options?.workspacesDir ?? import_node_path14.default.join(import_node_os7.default.homedir(), ".ahchat", "workspaces");
119437
+ this.agentConfigDir = options?.agentConfigDir ?? import_node_path14.default.join(import_node_os7.default.homedir(), ".ahchat", "agent-config");
119059
119438
  this.queryConfig = options?.queryConfig ?? DEFAULT_QUERY_CONFIG;
119060
119439
  this.askQuestionRegistry = options?.askQuestionRegistry ?? new AskQuestionRegistry();
119061
119440
  this.groupRegistry = options?.groupRegistry ?? null;
@@ -119072,7 +119451,7 @@ var AgentManager = class {
119072
119451
  this.mcpAuditRecorder = options?.mcpAuditRecorder ?? new HttpMcpAuditClient(this.serverApiUrl, this.bridgeToken);
119073
119452
  this.mcpBillingPreflightChecker = options?.mcpBillingPreflightChecker ?? new HttpMcpBillingClient(this.serverApiUrl, this.bridgeToken);
119074
119453
  this.defaultModel = options?.defaultModel ?? null;
119075
- this.dataDir = options?.dataDir ?? import_node_path13.default.join(import_node_os7.default.homedir(), ".ahchat");
119454
+ this.dataDir = options?.dataDir ?? import_node_path14.default.join(import_node_os7.default.homedir(), ".ahchat");
119076
119455
  this.workdirOverrideStore = options?.workdirOverrideStore ?? null;
119077
119456
  this.officeCliRuntime = options?.officeCliRuntime ?? null;
119078
119457
  }
@@ -119105,9 +119484,9 @@ var AgentManager = class {
119105
119484
  const normalized = requestedCwd.trim();
119106
119485
  const ahchatSuffix = extractAhchatWorkspaceSuffix(normalized);
119107
119486
  if (ahchatSuffix) {
119108
- return import_node_path13.default.join(this.workspacesDir, ahchatSuffix);
119487
+ return import_node_path14.default.join(this.workspacesDir, ahchatSuffix);
119109
119488
  }
119110
- return import_node_path13.default.join(this.workspacesDir, this.localScopeDirName(agentConfig, scope));
119489
+ return import_node_path14.default.join(this.workspacesDir, this.localScopeDirName(agentConfig, scope));
119111
119490
  }
119112
119491
  localScopeDirName(agentConfig, scope) {
119113
119492
  if (scope.kind === "group") return `Group-${scope.groupId}`;
@@ -119118,9 +119497,9 @@ var AgentManager = class {
119118
119497
  if (scope.kind === "group") {
119119
119498
  const groupCwd = this.groupRegistry?.getById(scope.groupId)?.workingDirectory?.trim();
119120
119499
  if (groupCwd) return groupCwd;
119121
- return import_node_path13.default.join(this.workspacesDir, this.localScopeDirName(agentConfig, scope));
119500
+ return import_node_path14.default.join(this.workspacesDir, this.localScopeDirName(agentConfig, scope));
119122
119501
  }
119123
- const local = import_node_path13.default.join(this.workspacesDir, this.localScopeDirName(agentConfig, scope));
119502
+ const local = import_node_path14.default.join(this.workspacesDir, this.localScopeDirName(agentConfig, scope));
119124
119503
  return agentConfig.workingDirectory?.trim() || local;
119125
119504
  }
119126
119505
  runtimeCwdInput(agentConfig, scope, cwd) {
@@ -119132,7 +119511,7 @@ var AgentManager = class {
119132
119511
  if (requested && (!agentCwd || !this.isSameRuntimeCwd(requested, agentCwd))) {
119133
119512
  return requested;
119134
119513
  }
119135
- return import_node_path13.default.join(this.workspacesDir, this.localScopeDirName(agentConfig, scope));
119514
+ return import_node_path14.default.join(this.workspacesDir, this.localScopeDirName(agentConfig, scope));
119136
119515
  }
119137
119516
  return agentConfig.workingDirectory?.trim() || requested || this.scopeCwdInput(agentConfig, scope);
119138
119517
  }
@@ -119167,7 +119546,7 @@ var AgentManager = class {
119167
119546
  let cwd = this.remapServerWorkspaceCwd(agentConfig, scope, requestedCwd);
119168
119547
  let fallbackForensicsId;
119169
119548
  if (!isFullyQualifiedAbsolutePath(cwd)) {
119170
- const fallback = import_node_path13.default.join(this.workspacesDir, this.localScopeDirName(agentConfig, scope));
119549
+ const fallback = import_node_path14.default.join(this.workspacesDir, this.localScopeDirName(agentConfig, scope));
119171
119550
  logger15.error(
119172
119551
  "Working directory is not usable on this machine; using local sandbox fallback",
119173
119552
  {
@@ -119203,7 +119582,7 @@ var AgentManager = class {
119203
119582
  cwd = this.fallbackCwd(agentConfig, scope, cwd);
119204
119583
  }
119205
119584
  try {
119206
- await import_promises3.default.mkdir(cwd, { recursive: true });
119585
+ await import_promises4.default.mkdir(cwd, { recursive: true });
119207
119586
  return cwd;
119208
119587
  } catch (e) {
119209
119588
  const fallback = this.fallbackCwd(agentConfig, scope, cwd);
@@ -119230,7 +119609,7 @@ var AgentManager = class {
119230
119609
  },
119231
119610
  outcome: { result: "second_layer_fallback" }
119232
119611
  });
119233
- await import_promises3.default.mkdir(fallback, { recursive: true });
119612
+ await import_promises4.default.mkdir(fallback, { recursive: true });
119234
119613
  return fallback;
119235
119614
  }
119236
119615
  }
@@ -119424,25 +119803,25 @@ var AgentManager = class {
119424
119803
  }
119425
119804
  settingsPathForConfig(cfg, effectiveConfigDir) {
119426
119805
  if (!usesIsolatedProjectBackend(cfg)) return void 0;
119427
- return import_node_path13.default.join(effectiveConfigDir, "settings.json");
119806
+ return import_node_path14.default.join(effectiveConfigDir, "settings.json");
119428
119807
  }
119429
119808
  isSameRuntimeCwd(a, b) {
119430
- const left = import_node_path13.default.normalize(a);
119431
- const right = import_node_path13.default.normalize(b);
119809
+ const left = import_node_path14.default.normalize(a);
119810
+ const right = import_node_path14.default.normalize(b);
119432
119811
  return process.platform === "win32" ? left.toLowerCase() === right.toLowerCase() : left === right;
119433
119812
  }
119434
119813
  sessionProjectDirs(agentConfig, effectiveConfigDir) {
119435
119814
  return uniqueNormalizedPaths([
119436
- import_node_path13.default.join(effectiveConfigDir, "api-key-agents", agentConfig.id, "projects"),
119437
- import_node_path13.default.join(effectiveConfigDir, "projects"),
119438
- import_node_path13.default.join(import_node_os7.default.homedir(), ".claude", "projects")
119815
+ import_node_path14.default.join(effectiveConfigDir, "api-key-agents", agentConfig.id, "projects"),
119816
+ import_node_path14.default.join(effectiveConfigDir, "projects"),
119817
+ import_node_path14.default.join(import_node_os7.default.homedir(), ".claude", "projects")
119439
119818
  ]);
119440
119819
  }
119441
119820
  sessionPathsForCwd(projectsDirs, cwd, sessionId) {
119442
119821
  return uniqueNormalizedPaths(
119443
119822
  projectsDirs.flatMap(
119444
119823
  (projectsDir) => claudeProjectSlugCandidates(cwd).map(
119445
- (slug) => import_node_path13.default.join(projectsDir, slug, `${sessionId}.jsonl`)
119824
+ (slug) => import_node_path14.default.join(projectsDir, slug, `${sessionId}.jsonl`)
119446
119825
  )
119447
119826
  )
119448
119827
  );
@@ -119463,7 +119842,7 @@ var AgentManager = class {
119463
119842
  }
119464
119843
  for (const entry of entries) {
119465
119844
  if (!entry.isDirectory()) continue;
119466
- const candidate = import_node_path13.default.join(projectsDir, entry.name, `${sessionId}.jsonl`);
119845
+ const candidate = import_node_path14.default.join(projectsDir, entry.name, `${sessionId}.jsonl`);
119467
119846
  if (import_node_fs6.default.existsSync(candidate)) found.push(candidate);
119468
119847
  }
119469
119848
  }
@@ -119478,12 +119857,12 @@ var AgentManager = class {
119478
119857
  }
119479
119858
  const currentPathSet = new Set(
119480
119859
  currentCwdPaths.map(
119481
- (candidate) => process.platform === "win32" ? import_node_path13.default.normalize(candidate).toLowerCase() : import_node_path13.default.normalize(candidate)
119860
+ (candidate) => process.platform === "win32" ? import_node_path14.default.normalize(candidate).toLowerCase() : import_node_path14.default.normalize(candidate)
119482
119861
  )
119483
119862
  );
119484
119863
  const foundElsewhere = this.findSessionJsonlFiles(projectsDirs, sessionId).filter(
119485
119864
  (candidate) => {
119486
- const normalized = process.platform === "win32" ? import_node_path13.default.normalize(candidate).toLowerCase() : import_node_path13.default.normalize(candidate);
119865
+ const normalized = process.platform === "win32" ? import_node_path14.default.normalize(candidate).toLowerCase() : import_node_path14.default.normalize(candidate);
119487
119866
  return !currentPathSet.has(normalized);
119488
119867
  }
119489
119868
  );
@@ -119504,7 +119883,7 @@ var AgentManager = class {
119504
119883
  return null;
119505
119884
  }
119506
119885
  scopePromptFingerprint(agentConfig, scope, agentCwd, scopesSection, externalMcpFingerprint, runtimeToolPolicyFingerprint = "") {
119507
- const hash2 = (0, import_node_crypto3.createHash)("sha256").update(SCOPE_PROMPT_FINGERPRINT_REVISION).update("\0").update(agentConfig.id).update("\0").update(agentConfig.name).update("\0").update(scopeKey(scope)).update("\0").update(import_node_path13.default.normalize(agentCwd)).update("\0").update(scopesSection).update("\0").update(externalMcpFingerprint);
119886
+ const hash2 = (0, import_node_crypto3.createHash)("sha256").update(SCOPE_PROMPT_FINGERPRINT_REVISION).update("\0").update(agentConfig.id).update("\0").update(agentConfig.name).update("\0").update(scopeKey(scope)).update("\0").update(import_node_path14.default.normalize(agentCwd)).update("\0").update(scopesSection).update("\0").update(externalMcpFingerprint);
119508
119887
  if (runtimeToolPolicyFingerprint) {
119509
119888
  hash2.update("\0runtimeToolPolicy\0").update(runtimeToolPolicyFingerprint);
119510
119889
  }
@@ -119861,7 +120240,7 @@ var AgentManager = class {
119861
120240
  const scopedInstructions = cfg.instructions?.trim() && scope.kind === "group" ? `# Agent project instructions
119862
120241
  ${cfg.instructions.trim()}` : "";
119863
120242
  if (cfg.instructions?.trim() && scope.kind === "single") {
119864
- await import_promises3.default.writeFile(import_node_path13.default.join(agentCwd, "CLAUDE.md"), cfg.instructions.trim(), "utf-8");
120243
+ await import_promises4.default.writeFile(import_node_path14.default.join(agentCwd, "CLAUDE.md"), cfg.instructions.trim(), "utf-8");
119865
120244
  logger15.info("CLAUDE.md written", {
119866
120245
  agentId: agentConfig.id,
119867
120246
  scope: scopeKey(scope),
@@ -119870,10 +120249,10 @@ ${cfg.instructions.trim()}` : "";
119870
120249
  }
119871
120250
  let effectiveConfigDir = this.agentConfigDir;
119872
120251
  if (cfg.subscriptionType !== "system" && cfg.apiKey) {
119873
- effectiveConfigDir = import_node_path13.default.join(this.agentConfigDir, "api-key-agents", agentConfig.id);
120252
+ effectiveConfigDir = import_node_path14.default.join(this.agentConfigDir, "api-key-agents", agentConfig.id);
119874
120253
  let isNew = false;
119875
120254
  try {
119876
- await import_promises3.default.access(effectiveConfigDir);
120255
+ await import_promises4.default.access(effectiveConfigDir);
119877
120256
  } catch (e) {
119878
120257
  logger15.debug("Agent API key config dir missing; creating isolated dir", {
119879
120258
  error: e,
@@ -119881,7 +120260,7 @@ ${cfg.instructions.trim()}` : "";
119881
120260
  });
119882
120261
  isNew = true;
119883
120262
  }
119884
- await import_promises3.default.mkdir(effectiveConfigDir, { recursive: true });
120263
+ await import_promises4.default.mkdir(effectiveConfigDir, { recursive: true });
119885
120264
  if (isNew) {
119886
120265
  this.sessionStore.delete(agentConfig.id, scope);
119887
120266
  this.dispatchMemory.deleteScope(agentConfig.id, scope);
@@ -119889,18 +120268,18 @@ ${cfg.instructions.trim()}` : "";
119889
120268
  agentId: agentConfig.id
119890
120269
  });
119891
120270
  }
119892
- const settingsPath = import_node_path13.default.join(effectiveConfigDir, "settings.json");
120271
+ const settingsPath = import_node_path14.default.join(effectiveConfigDir, "settings.json");
119893
120272
  const envEntries = buildAnthropicCredentialEnv(cfg);
119894
120273
  if (cfg.apiBaseUrl) envEntries.ANTHROPIC_BASE_URL = cfg.apiBaseUrl;
119895
120274
  let existingSettings = {};
119896
120275
  if (import_node_fs6.default.existsSync(settingsPath)) {
119897
120276
  try {
119898
- const raw = await import_promises3.default.readFile(settingsPath, "utf-8");
120277
+ const raw = await import_promises4.default.readFile(settingsPath, "utf-8");
119899
120278
  existingSettings = JSON.parse(raw);
119900
120279
  } catch (error51) {
119901
120280
  logger15.error("Failed to read existing API-key agent settings; starting fresh", {
119902
120281
  agentId: agentConfig.id,
119903
- settingsPath,
120282
+ settingsFile: "settings.json",
119904
120283
  error: error51
119905
120284
  });
119906
120285
  }
@@ -119910,10 +120289,10 @@ ${cfg.instructions.trim()}` : "";
119910
120289
  if (envEntries.ANTHROPIC_AUTH_TOKEN) delete mergedEnv.ANTHROPIC_API_KEY;
119911
120290
  if (envEntries.ANTHROPIC_API_KEY) delete mergedEnv.ANTHROPIC_AUTH_TOKEN;
119912
120291
  const mergedSettings = { ...existingSettings, env: mergedEnv };
119913
- await import_promises3.default.writeFile(settingsPath, JSON.stringify(mergedSettings, null, 2), "utf-8");
120292
+ await import_promises4.default.writeFile(settingsPath, JSON.stringify(mergedSettings, null, 2), "utf-8");
119914
120293
  logger15.info("API-key agent using isolated config dir", {
119915
120294
  agentId: agentConfig.id,
119916
- dir: effectiveConfigDir,
120295
+ configDirKind: "api-key-agent",
119917
120296
  isNew,
119918
120297
  hasBaseUrl: !!cfg.apiBaseUrl,
119919
120298
  settingsWritten: Object.keys(envEntries)
@@ -120007,12 +120386,23 @@ ${cfg.instructions.trim()}` : "";
120007
120386
  });
120008
120387
  }
120009
120388
  }
120010
- const externalMcp = this.mcpRegistry?.buildForAgent({
120389
+ const resolvedExternalMcp = this.mcpRegistry?.buildForAgent({
120011
120390
  agentId: agentConfig.id,
120012
120391
  capabilityTier: cfg.capabilityTier,
120013
120392
  isSmith: smithAgent,
120014
120393
  cwd: agentCwd
120015
120394
  }) ?? { mcpServers: {}, allowedTools: [], toolAbi: [] };
120395
+ const externalMcp = smithAgent ? selectSmithVisionMcp(resolvedExternalMcp) : resolvedExternalMcp;
120396
+ if (smithAgent && (Object.keys(resolvedExternalMcp.mcpServers).length !== Object.keys(externalMcp.mcpServers).length || resolvedExternalMcp.allowedTools.length !== externalMcp.allowedTools.length || (resolvedExternalMcp.toolAbi?.length ?? 0) !== (externalMcp.toolAbi?.length ?? 0))) {
120397
+ logger15.info("Smith external MCP filtered by fixed tool whitelist", {
120398
+ agentId: agentConfig.id,
120399
+ scope: scopeKey(scope),
120400
+ serverNames: Object.keys(resolvedExternalMcp.mcpServers),
120401
+ allowedToolCount: resolvedExternalMcp.allowedTools.length,
120402
+ retainedServerNames: Object.keys(externalMcp.mcpServers),
120403
+ retainedAllowedToolCount: externalMcp.allowedTools.length
120404
+ });
120405
+ }
120016
120406
  const visionMcpTools = resolveVisionMcpToolHints(externalMcp);
120017
120407
  logger15.info("External MCP resolved for runtime", {
120018
120408
  agentId: agentConfig.id,
@@ -120085,6 +120475,7 @@ ${cfg.instructions.trim()}` : "";
120085
120475
  logger15.info("Creating Agent query", {
120086
120476
  agentId: agentConfig.id,
120087
120477
  scope: scopeKey(scope),
120478
+ systemPromptMode: smithAgent ? "string" : "preset",
120088
120479
  cwd: agentCwd,
120089
120480
  resume: !!savedSessionId,
120090
120481
  sessionId: savedSessionId,
@@ -120105,71 +120496,65 @@ ${cfg.instructions.trim()}` : "";
120105
120496
  });
120106
120497
  const planModeRef = { active: false, denyCount: 0 };
120107
120498
  const mediaGenerationTurnGuard = createOfficialMediaGenerationTurnGuard();
120499
+ const platformRules = scope.kind === "group" ? PLATFORM_AGENT_RULES : PLATFORM_AGENT_RULES_SINGLE;
120500
+ const appendText = [
120501
+ platformRules,
120502
+ nativeReadToolDisabled ? buildNativeReadDisabledRules(visionMcpTools) : "",
120503
+ DOCUMENT_READING_RULES,
120504
+ MEDIA_GENERATION_RULES,
120505
+ agentConfig.systemPrompt,
120506
+ scopedInstructions,
120507
+ notebookSection,
120508
+ forkHistorySection,
120509
+ scopesSection
120510
+ ].filter((s) => typeof s === "string" && s.trim().length > 0).join("\n\n");
120511
+ const systemPrompt = smithAgent ? appendText : { type: "preset", preset: "claude_code", append: appendText };
120512
+ const universalAllowedTools = [
120513
+ ...nativeReadToolDisabled ? [] : ["Read"],
120514
+ "Edit",
120515
+ "Write",
120516
+ "Bash",
120517
+ "Glob",
120518
+ "Grep",
120519
+ ...builtinWebSearchAllowed ? ["WebSearch"] : [],
120520
+ "WebFetch",
120521
+ "TodoWrite",
120522
+ "TaskCreate",
120523
+ "TaskUpdate",
120524
+ "AskUserQuestion",
120525
+ "mcp__neural__neural_send",
120526
+ "mcp__neural__neural_list_scopes",
120527
+ "mcp__neural__find_workdir_files",
120528
+ "mcp__neural__send_workdir_file",
120529
+ "mcp__neural__self_note",
120530
+ "mcp__neural__list_contacts",
120531
+ "mcp__neural__create_group",
120532
+ "mcp__neural__add_to_group",
120533
+ "mcp__neural__leave_group",
120534
+ "mcp__neural__remove_from_group",
120535
+ "mcp__neural__create_group_issue",
120536
+ "mcp__neural__resolve_group_issue",
120537
+ "mcp__neural__list_group_tasks",
120538
+ "mcp__neural__update_group_task",
120539
+ "mcp__neural__transfer_group_owner",
120540
+ "mcp__neural__post_to_moments",
120541
+ "mcp__neural__post_to_forum",
120542
+ "mcp__neural__read_moments",
120543
+ "mcp__neural__read_chat_history",
120544
+ "mcp__neural__read_document",
120545
+ "mcp__neural__list_available_skills",
120546
+ "mcp__neural__list_skill_index"
120547
+ ];
120108
120548
  const options = {
120109
120549
  cwd: agentCwd,
120110
- systemPrompt: {
120111
- type: "preset",
120112
- preset: "claude_code",
120113
- append: [
120114
- PLATFORM_AGENT_RULES,
120115
- nativeReadToolDisabled ? buildNativeReadDisabledRules(visionMcpTools) : "",
120116
- DOCUMENT_READING_RULES,
120117
- MEDIA_GENERATION_RULES,
120118
- agentConfig.systemPrompt,
120119
- scopedInstructions,
120120
- notebookSection,
120121
- forkHistorySection,
120122
- scopesSection
120123
- ].filter((s) => typeof s === "string" && s.trim().length > 0).join("\n\n")
120124
- },
120550
+ systemPrompt,
120125
120551
  permissionMode: "bypassPermissions",
120126
120552
  allowDangerouslySkipPermissions: true,
120127
120553
  // allowedTools is the visibility whitelist passed to Claude Code. MCP tools
120128
120554
  // with always_ask must still be included here so the model can request them;
120129
120555
  // the MCP server policy/permission layer decides whether execution asks.
120130
120556
  allowedTools: [
120131
- ...nativeReadToolDisabled ? [] : ["Read"],
120132
- "Edit",
120133
- "Write",
120134
- "Bash",
120135
- "Glob",
120136
- "Grep",
120137
- ...builtinWebSearchAllowed ? ["WebSearch"] : [],
120138
- "WebFetch",
120139
- "TodoWrite",
120140
- "TaskCreate",
120141
- "TaskUpdate",
120142
- "AskUserQuestion",
120143
- "mcp__neural__neural_send",
120144
- "mcp__neural__neural_list_scopes",
120145
- "mcp__neural__self_note",
120146
- "mcp__neural__list_contacts",
120147
- "mcp__neural__create_group",
120148
- "mcp__neural__add_to_group",
120149
- "mcp__neural__leave_group",
120150
- "mcp__neural__remove_from_group",
120151
- "mcp__neural__create_group_issue",
120152
- "mcp__neural__resolve_group_issue",
120153
- "mcp__neural__list_group_tasks",
120154
- "mcp__neural__update_group_task",
120155
- "mcp__neural__transfer_group_owner",
120156
- "mcp__neural__post_to_moments",
120157
- "mcp__neural__post_to_forum",
120158
- "mcp__neural__read_moments",
120159
- "mcp__neural__read_chat_history",
120160
- "mcp__neural__read_document",
120161
- "mcp__neural__list_available_skills",
120162
- "mcp__neural__list_skill_index",
120163
- ...isSmithAgent2(agentConfig) ? [
120164
- "mcp__neural__create_agent",
120165
- "mcp__neural__update_agent_profile",
120166
- "mcp__neural__recommend_agent_skills",
120167
- "mcp__neural__read_skill",
120168
- "mcp__neural__list_friends",
120169
- "mcp__neural__accept_friend",
120170
- "mcp__neural__add_friend",
120171
- "mcp__neural__fetch_logs"
120172
- ] : [],
120557
+ ...smithAgent ? SMITH_ALLOWED_TOOLS : universalAllowedTools,
120173
120558
  ...externalMcp.allowedTools
120174
120559
  ],
120175
120560
  // Server-side WebSearch bypasses canUseTool; disallowedTools removes it from model context.
@@ -120181,7 +120566,7 @@ ${cfg.instructions.trim()}` : "";
120181
120566
  // instructions as the workflow body (replacing the default code-implementation
120182
120567
  // phases). The SDK wraps it with read-only enforcement + ExitPlanMode protocol.
120183
120568
  planModeInstructions: (() => {
120184
- const planTools = [
120569
+ const planTools = (smithAgent ? ["AskUserQuestion", "Write (plan file only)"] : [
120185
120570
  ...nativeReadToolDisabled ? [] : ["Read"],
120186
120571
  "Glob",
120187
120572
  "Grep",
@@ -120189,19 +120574,19 @@ ${cfg.instructions.trim()}` : "";
120189
120574
  "WebFetch",
120190
120575
  "AskUserQuestion",
120191
120576
  "Write (plan file only)"
120192
- ].join(", ");
120193
- const researchTools = [
120577
+ ]).join(", ");
120578
+ const researchTools = (smithAgent ? ["AskUserQuestion"] : [
120194
120579
  ...nativeReadToolDisabled ? [] : ["Read"],
120195
120580
  "Grep",
120196
120581
  ...builtinWebSearchAllowed ? ["WebSearch"] : []
120197
- ].join(", ");
120198
- const unavailableTools = [
120582
+ ]).join(", ");
120583
+ const unavailableTools = (smithAgent ? ["Read", "Edit", "Bash", "Glob", "Grep", "WebFetch", "TodoWrite", "ExitPlanMode"] : [
120199
120584
  "Edit",
120200
120585
  "Bash",
120201
120586
  "TodoWrite",
120202
120587
  "ExitPlanMode",
120203
120588
  ...nativeReadToolDisabled ? ["Read"] : []
120204
- ].join(", ");
120589
+ ]).join(", ");
120205
120590
  const smithTools = smithAgent ? "\nSMITH-SPECIFIC TOOLS (available in plan mode): mcp__neural__recommend_agent_skills, mcp__neural__read_skill, mcp__neural__fetch_logs, mcp__neural__create_agent, mcp__neural__update_agent_profile \u2014 use these to recommend initial skill sets, research existing skills, check logs, plan agent creation, and adjust Agent profiles." : "";
120206
120591
  return `You are a PLANNER, NOT an executor. The user will execute your plan later.
120207
120592
 
@@ -120431,17 +120816,17 @@ Do NOT use "..." as content \u2014 write specific, project-relevant content.`;
120431
120816
  }
120432
120817
  };
120433
120818
  const userPromptTrimmed = (agentConfig.systemPrompt ?? "").trim();
120434
- const appendStr = options.systemPrompt.append;
120435
120819
  logger15.info("Platform rules attached", {
120436
120820
  agentId: agentConfig.id,
120437
120821
  scope: scopeKey(scope),
120438
- platformRulesLen: PLATFORM_AGENT_RULES.length,
120822
+ systemPromptMode: smithAgent ? "string" : "preset",
120823
+ platformRulesLen: platformRules.length,
120439
120824
  userPromptLen: userPromptTrimmed.length,
120440
120825
  hasUserPrompt: userPromptTrimmed.length > 0,
120441
120826
  notebookLen: notebookSection.length,
120442
120827
  forkHistoryLen: forkHistorySection.length,
120443
120828
  scopesLen: scopesSection.length,
120444
- appendLen: appendStr.length,
120829
+ appendLen: appendText.length,
120445
120830
  hasCreateAgentTool: smithAgent,
120446
120831
  hasLogDetectiveTools: smithAgent && this.skillStore !== null
120447
120832
  });
@@ -120461,7 +120846,7 @@ Do NOT use "..." as content \u2014 write specific, project-relevant content.`;
120461
120846
  if (isRunningAsRoot()) {
120462
120847
  await chownForRootSpawn(effectiveConfigDir, "configDir");
120463
120848
  await chownForRootSpawn(agentCwd, "agentCwd");
120464
- const settingsFilePath = import_node_path13.default.join(effectiveConfigDir, "settings.json");
120849
+ const settingsFilePath = import_node_path14.default.join(effectiveConfigDir, "settings.json");
120465
120850
  await chownForRootSpawn(settingsFilePath, "settingsFile");
120466
120851
  options.spawnClaudeCodeProcess = (spawnOptions) => {
120467
120852
  const env2 = { ...spawnOptions.env, HOME: "/home/node" };
@@ -120511,6 +120896,7 @@ Do NOT use "..." as content \u2014 write specific, project-relevant content.`;
120511
120896
  mcpAuditRecorder: this.mcpAuditRecorder,
120512
120897
  segmentBuffer: "",
120513
120898
  segmentCount: 0,
120899
+ workdirSignals: [],
120514
120900
  accumulatedToolInput: "",
120515
120901
  planModeRef,
120516
120902
  mediaGenerationTurnGuard,
@@ -120530,7 +120916,7 @@ Do NOT use "..." as content \u2014 write specific, project-relevant content.`;
120530
120916
  mergedTasks: [],
120531
120917
  planModeBuffer: [],
120532
120918
  createdAt: Date.now(),
120533
- supportsVision: modelInputMode === "vision",
120919
+ supportsVision: cfg.supportsVision === true,
120534
120920
  modelInputMode,
120535
120921
  visionMcpTools,
120536
120922
  quietFlushTimer: null,
@@ -120718,7 +121104,7 @@ ${trimmed}`;
120718
121104
  promptWorkdir(agentConfig, scope, requestedCwd) {
120719
121105
  const remapped = this.remapServerWorkspaceCwd(agentConfig, scope, requestedCwd);
120720
121106
  if (!isFullyQualifiedAbsolutePath(remapped)) {
120721
- return import_node_path13.default.join(this.workspacesDir, this.localScopeDirName(agentConfig, scope));
121107
+ return import_node_path14.default.join(this.workspacesDir, this.localScopeDirName(agentConfig, scope));
120722
121108
  }
120723
121109
  return remapped;
120724
121110
  }
@@ -121423,12 +121809,12 @@ ${lines.join("\n")}`;
121423
121809
  }
121424
121810
  async materializeAttachment(runtime, attachment, buffer) {
121425
121811
  const safeFileName = this.safeAttachmentFileName(attachment.fileName);
121426
- const attachmentDir = import_node_path13.default.join(runtime.cwd, ".ahchat-attachments", attachment.id);
121812
+ const attachmentDir = import_node_path14.default.join(runtime.cwd, ".ahchat-attachments", attachment.id);
121427
121813
  let filePath = await this.resolveExistingWorkspaceAttachmentPath(runtime, attachment);
121428
121814
  if (!filePath) {
121429
- await import_promises3.default.mkdir(attachmentDir, { recursive: true });
121430
- filePath = import_node_path13.default.join(attachmentDir, safeFileName);
121431
- await import_promises3.default.writeFile(filePath, buffer);
121815
+ await import_promises4.default.mkdir(attachmentDir, { recursive: true });
121816
+ filePath = import_node_path14.default.join(attachmentDir, safeFileName);
121817
+ await import_promises4.default.writeFile(filePath, buffer);
121432
121818
  }
121433
121819
  const materialized = { filePath };
121434
121820
  if (isReadableDocumentPath(filePath)) {
@@ -121457,10 +121843,10 @@ ${lines.join("\n")}`;
121457
121843
  const rawPath = typeof localWorkspacePath === "string" && localWorkspacePath.trim() ? localWorkspacePath : workspacePath;
121458
121844
  if (typeof rawPath !== "string" || !rawPath.trim()) return null;
121459
121845
  const remapped = remapServerWorkspacePath(rawPath, this.workspacesDir);
121460
- const candidate = import_node_path13.default.resolve(remapped.path);
121846
+ const candidate = import_node_path14.default.resolve(remapped.path);
121461
121847
  if (!this.isPathInsideBase(candidate, runtime.cwd)) return null;
121462
121848
  try {
121463
- const stat3 = await import_promises3.default.stat(candidate);
121849
+ const stat3 = await import_promises4.default.stat(candidate);
121464
121850
  return stat3.isFile() ? candidate : null;
121465
121851
  } catch (e) {
121466
121852
  logger15.warn("Workspace attachment path unavailable", {
@@ -121475,13 +121861,13 @@ ${lines.join("\n")}`;
121475
121861
  }
121476
121862
  }
121477
121863
  isPathInsideBase(filePath, basePath) {
121478
- const resolvedFile = import_node_path13.default.resolve(filePath);
121479
- const resolvedBase = import_node_path13.default.resolve(basePath);
121480
- const relative = import_node_path13.default.relative(resolvedBase, resolvedFile);
121481
- return relative === "" || !relative.startsWith("..") && !import_node_path13.default.isAbsolute(relative);
121864
+ const resolvedFile = import_node_path14.default.resolve(filePath);
121865
+ const resolvedBase = import_node_path14.default.resolve(basePath);
121866
+ const relative = import_node_path14.default.relative(resolvedBase, resolvedFile);
121867
+ return relative === "" || !relative.startsWith("..") && !import_node_path14.default.isAbsolute(relative);
121482
121868
  }
121483
121869
  safeAttachmentFileName(fileName) {
121484
- const baseName = import_node_path13.default.basename(fileName).replace(/[\0/:\\]/g, "_").trim();
121870
+ const baseName = import_node_path14.default.basename(fileName).replace(/[\0/:\\]/g, "_").trim();
121485
121871
  return baseName || "attachment";
121486
121872
  }
121487
121873
  emitTaskPushError(runtime, task, error51) {
@@ -121544,6 +121930,7 @@ ${lines.join("\n")}`;
121544
121930
  proc.currentToolName = null;
121545
121931
  proc.segmentBuffer = "";
121546
121932
  proc.segmentCount = 0;
121933
+ proc.workdirSignals = [];
121547
121934
  }
121548
121935
  clearPostMergeContinuationTimer(runtime) {
121549
121936
  if (runtime.postMergeContinuationTimer) {
@@ -123859,8 +124246,8 @@ async function readJson(res) {
123859
124246
  return null;
123860
124247
  }
123861
124248
  }
123862
- function apiUrl(baseUrl, path36) {
123863
- return new URL(path36, baseUrl).toString();
124249
+ function apiUrl(baseUrl, path37) {
124250
+ return new URL(path37, baseUrl).toString();
123864
124251
  }
123865
124252
  async function fetchServerSkillSet(options) {
123866
124253
  try {
@@ -124115,8 +124502,8 @@ var HttpAgentRegistry = class {
124115
124502
  lastRefreshCount = null;
124116
124503
  apiUrl(suffix) {
124117
124504
  const base = this.serverApiUrl.replace(/\/$/, "");
124118
- const path36 = suffix.startsWith("/") ? suffix : `/${suffix}`;
124119
- return `${base}${path36}`;
124505
+ const path37 = suffix.startsWith("/") ? suffix : `/${suffix}`;
124506
+ return `${base}${path37}`;
124120
124507
  }
124121
124508
  async refresh() {
124122
124509
  const attempt = async () => {
@@ -124220,8 +124607,8 @@ var HttpSubscriptionRegistry = class {
124220
124607
  lastRefreshCount = null;
124221
124608
  apiUrl(suffix) {
124222
124609
  const base = this.serverApiUrl.replace(/\/$/, "");
124223
- const path36 = suffix.startsWith("/") ? suffix : `/${suffix}`;
124224
- return `${base}${path36}`;
124610
+ const path37 = suffix.startsWith("/") ? suffix : `/${suffix}`;
124611
+ return `${base}${path37}`;
124225
124612
  }
124226
124613
  rebuildPrimaryAlias() {
124227
124614
  this.subscriptions.delete(PRIMARY_COMPANY_SUBSCRIPTION_ID);
@@ -124301,7 +124688,7 @@ var HttpSubscriptionRegistry = class {
124301
124688
  // src/mcpRegistry.ts
124302
124689
  init_cjs_shims();
124303
124690
  var import_node_fs7 = __toESM(require("fs"), 1);
124304
- var import_node_path14 = __toESM(require("path"), 1);
124691
+ var import_node_path15 = __toESM(require("path"), 1);
124305
124692
  var import_node_url = require("url");
124306
124693
  var logger20 = createModuleLogger("mcp.registry");
124307
124694
  var AHCHAT_BUILTIN_MCP_COMMAND = "ahchat-builtin";
@@ -124319,11 +124706,12 @@ var HttpMcpRegistry = class {
124319
124706
  localStore;
124320
124707
  serverConnections = /* @__PURE__ */ new Map();
124321
124708
  localConnections = /* @__PURE__ */ new Map();
124709
+ missingSecretWarnedKeys = /* @__PURE__ */ new Set();
124322
124710
  lastRefreshCount = null;
124323
124711
  apiUrl(suffix) {
124324
124712
  const base = this.serverApiUrl.replace(/\/$/, "");
124325
- const path36 = suffix.startsWith("/") ? suffix : `/${suffix}`;
124326
- return `${base}${path36}`;
124713
+ const path37 = suffix.startsWith("/") ? suffix : `/${suffix}`;
124714
+ return `${base}${path37}`;
124327
124715
  }
124328
124716
  async refresh() {
124329
124717
  this.refreshLocal();
@@ -124419,13 +124807,19 @@ var HttpMcpRegistry = class {
124419
124807
  return false;
124420
124808
  });
124421
124809
  }
124810
+ warnMissingSecretOnce(connection) {
124811
+ const key = `${connection.id}:${connection.providerId}:${connection.serverName}`;
124812
+ if (this.missingSecretWarnedKeys.has(key)) return;
124813
+ this.missingSecretWarnedKeys.add(key);
124814
+ logger20.warn("Skipping MCP connection without required secret", {
124815
+ id: connection.id,
124816
+ providerId: connection.providerId,
124817
+ serverName: connection.serverName
124818
+ });
124819
+ }
124422
124820
  toSdkServerConfig(connection, ctx) {
124423
124821
  if (mcpConnectionRequiresSecret(connection) && !connection.hasAuthSecret) {
124424
- logger20.warn("Skipping MCP connection without required secret", {
124425
- id: connection.id,
124426
- providerId: connection.providerId,
124427
- serverName: connection.serverName
124428
- });
124822
+ this.warnMissingSecretOnce(connection);
124429
124823
  return null;
124430
124824
  }
124431
124825
  const policies = toolPolicies(connection);
@@ -124509,13 +124903,13 @@ function resolveVisionMcpExecutable(extraArgs, options = {}) {
124509
124903
  return resolveBundledMcpExecutable("visionMcpCli", extraArgs, options);
124510
124904
  }
124511
124905
  function resolveBundledMcpExecutable(cliBaseName, extraArgs, options = {}) {
124512
- const currentDir = options.currentDir ?? import_node_path14.default.dirname((0, import_node_url.fileURLToPath)(importMetaUrl));
124906
+ const currentDir = options.currentDir ?? import_node_path15.default.dirname((0, import_node_url.fileURLToPath)(importMetaUrl));
124513
124907
  const cwd = options.cwd ?? process.cwd();
124514
124908
  const execPath = options.execPath ?? process.execPath;
124515
124909
  const existsSync3 = options.existsSync ?? import_node_fs7.default.existsSync;
124516
124910
  const distCliPath = firstExistingPath(
124517
124911
  [
124518
- import_node_path14.default.join(currentDir, `${cliBaseName}.cjs`)
124912
+ import_node_path15.default.join(currentDir, `${cliBaseName}.cjs`)
124519
124913
  ],
124520
124914
  existsSync3
124521
124915
  );
@@ -124528,7 +124922,7 @@ function resolveBundledMcpExecutable(cliBaseName, extraArgs, options = {}) {
124528
124922
  }
124529
124923
  const sourceCliPath = firstExistingPath(
124530
124924
  [
124531
- import_node_path14.default.join(currentDir, `${cliBaseName}.ts`)
124925
+ import_node_path15.default.join(currentDir, `${cliBaseName}.ts`)
124532
124926
  ],
124533
124927
  existsSync3
124534
124928
  );
@@ -124537,9 +124931,9 @@ function resolveBundledMcpExecutable(cliBaseName, extraArgs, options = {}) {
124537
124931
  }
124538
124932
  const workspaceDistCliPath = firstExistingPath(
124539
124933
  [
124540
- import_node_path14.default.resolve(currentDir, `../../bridge/dist/${cliBaseName}.cjs`),
124541
- import_node_path14.default.resolve(cwd, `packages/desktop/dist/${cliBaseName}.cjs`),
124542
- import_node_path14.default.resolve(cwd, `packages/bridge/dist/${cliBaseName}.cjs`)
124934
+ import_node_path15.default.resolve(currentDir, `../../bridge/dist/${cliBaseName}.cjs`),
124935
+ import_node_path15.default.resolve(cwd, `packages/desktop/dist/${cliBaseName}.cjs`),
124936
+ import_node_path15.default.resolve(cwd, `packages/bridge/dist/${cliBaseName}.cjs`)
124543
124937
  ],
124544
124938
  existsSync3
124545
124939
  );
@@ -124552,8 +124946,8 @@ function resolveBundledMcpExecutable(cliBaseName, extraArgs, options = {}) {
124552
124946
  }
124553
124947
  const workspaceSourceCliPath = firstExistingPath(
124554
124948
  [
124555
- import_node_path14.default.resolve(currentDir, `../../bridge/src/${cliBaseName}.ts`),
124556
- import_node_path14.default.resolve(cwd, `packages/bridge/src/${cliBaseName}.ts`)
124949
+ import_node_path15.default.resolve(currentDir, `../../bridge/src/${cliBaseName}.ts`),
124950
+ import_node_path15.default.resolve(cwd, `packages/bridge/src/${cliBaseName}.ts`)
124557
124951
  ],
124558
124952
  existsSync3
124559
124953
  );
@@ -124574,7 +124968,7 @@ function firstExistingPath(paths, existsSync3) {
124574
124968
  function shouldRunExecPathAsNode(execPath, options) {
124575
124969
  if (typeof options.isElectron === "boolean") return options.isElectron;
124576
124970
  if (process.versions.electron) return true;
124577
- return import_node_path14.default.basename(execPath).toLowerCase().includes("electron");
124971
+ return import_node_path15.default.basename(execPath).toLowerCase().includes("electron");
124578
124972
  }
124579
124973
  function uniqueServerName(serverName, usedNames) {
124580
124974
  if (!usedNames.has(serverName)) return serverName;
@@ -124614,12 +125008,12 @@ function toolPolicies(connection) {
124614
125008
  // src/localMcpStore.ts
124615
125009
  init_cjs_shims();
124616
125010
  var import_node_fs8 = __toESM(require("fs"), 1);
124617
- var import_node_path15 = __toESM(require("path"), 1);
125011
+ var import_node_path16 = __toESM(require("path"), 1);
124618
125012
  var logger21 = createModuleLogger("bridge.localMcpStore");
124619
125013
  var LocalMcpStore = class {
124620
125014
  constructor(dataDir) {
124621
125015
  this.dataDir = dataDir;
124622
- this.filePath = import_node_path15.default.join(dataDir, LOCAL_MCP_CONNECTIONS_FILENAME);
125016
+ this.filePath = import_node_path16.default.join(dataDir, LOCAL_MCP_CONNECTIONS_FILENAME);
124623
125017
  }
124624
125018
  dataDir;
124625
125019
  filePath;
@@ -124651,12 +125045,12 @@ function isNodeErrorCode(error51, code) {
124651
125045
  // src/localSkillStore.ts
124652
125046
  init_cjs_shims();
124653
125047
  var import_node_fs9 = __toESM(require("fs"), 1);
124654
- var import_node_path16 = __toESM(require("path"), 1);
125048
+ var import_node_path17 = __toESM(require("path"), 1);
124655
125049
  var logger22 = createModuleLogger("bridge.localSkillStore");
124656
125050
  var LocalSkillStore = class {
124657
125051
  constructor(dataDir, runtimeScope = {}) {
124658
125052
  this.dataDir = dataDir;
124659
- this.filePath = import_node_path16.default.join(dataDir, LOCAL_SKILLS_FILENAME);
125053
+ this.filePath = import_node_path17.default.join(dataDir, LOCAL_SKILLS_FILENAME);
124660
125054
  this.runtimeScope = runtimeScope;
124661
125055
  }
124662
125056
  dataDir;
@@ -125416,9 +125810,9 @@ var ServerConnector = class {
125416
125810
 
125417
125811
  // src/contextDumper.ts
125418
125812
  init_cjs_shims();
125419
- var import_promises4 = __toESM(require("fs/promises"), 1);
125813
+ var import_promises5 = __toESM(require("fs/promises"), 1);
125420
125814
  var import_node_os9 = __toESM(require("os"), 1);
125421
- var import_node_path17 = __toESM(require("path"), 1);
125815
+ var import_node_path18 = __toESM(require("path"), 1);
125422
125816
  var sdk3 = __toESM(require("@anthropic-ai/claude-agent-sdk"), 1);
125423
125817
  var logger25 = createModuleLogger("bridge.contextDumper");
125424
125818
  var TRUNCATE_THRESHOLD = 5e4;
@@ -125448,11 +125842,11 @@ function cwdToProjectSlug(cwd) {
125448
125842
  }
125449
125843
  function resolveJsonlPathInProjectsDir(projectsDir, sessionId, cwd) {
125450
125844
  const slug = cwdToProjectSlug(cwd);
125451
- return import_node_path17.default.join(projectsDir, slug, `${sessionId}.jsonl`);
125845
+ return import_node_path18.default.join(projectsDir, slug, `${sessionId}.jsonl`);
125452
125846
  }
125453
125847
  function resolveProjectDirInProjectsDir(projectsDir, cwd) {
125454
125848
  const slug = cwdToProjectSlug(cwd);
125455
- return import_node_path17.default.join(projectsDir, slug);
125849
+ return import_node_path18.default.join(projectsDir, slug);
125456
125850
  }
125457
125851
  function errorCode(e) {
125458
125852
  if (e instanceof Error && "code" in e) {
@@ -125463,7 +125857,7 @@ function errorCode(e) {
125463
125857
  }
125464
125858
  async function isReadableFile(filePath) {
125465
125859
  try {
125466
- const stat3 = await import_promises4.default.stat(filePath);
125860
+ const stat3 = await import_promises5.default.stat(filePath);
125467
125861
  return stat3.isFile();
125468
125862
  } catch (e) {
125469
125863
  const code = errorCode(e);
@@ -125478,7 +125872,7 @@ function uniquePaths(paths) {
125478
125872
  for (const p of paths) {
125479
125873
  const trimmed = p.trim();
125480
125874
  if (!trimmed) continue;
125481
- const key = import_node_path17.default.normalize(trimmed);
125875
+ const key = import_node_path18.default.normalize(trimmed);
125482
125876
  if (seen.has(key)) continue;
125483
125877
  seen.add(key);
125484
125878
  out.push(trimmed);
@@ -125494,7 +125888,7 @@ function inferAhchatUserAgentConfigDir(workdir) {
125494
125888
  const userSlug = afterMarker.split("/").find(Boolean);
125495
125889
  if (!userSlug) return null;
125496
125890
  const userDataDir2 = normalized.slice(0, markerIndex + marker.length + userSlug.length);
125497
- return import_node_path17.default.join(import_node_path17.default.normalize(userDataDir2), "agent-config");
125891
+ return import_node_path18.default.join(import_node_path18.default.normalize(userDataDir2), "agent-config");
125498
125892
  }
125499
125893
  function inferredAgentConfigDirsFromWorkdirs(workdirs) {
125500
125894
  return uniquePaths(workdirs.map((workdir) => inferAhchatUserAgentConfigDir(workdir) ?? ""));
@@ -125507,19 +125901,19 @@ function claudeProjectsDirs(opts) {
125507
125901
  ]);
125508
125902
  return uniquePaths([
125509
125903
  ...configDirs.flatMap((configDir) => [
125510
- import_node_path17.default.join(configDir, "api-key-agents", opts.agentId, "projects"),
125511
- import_node_path17.default.join(configDir, "projects")
125904
+ import_node_path18.default.join(configDir, "api-key-agents", opts.agentId, "projects"),
125905
+ import_node_path18.default.join(configDir, "projects")
125512
125906
  ]),
125513
- import_node_path17.default.join(import_node_os9.default.homedir(), ".claude", "projects")
125907
+ import_node_path18.default.join(import_node_os9.default.homedir(), ".claude", "projects")
125514
125908
  ]);
125515
125909
  }
125516
125910
  function fallbackBridgeWorkspacePath(requestedCwd, workspacesDir, fallbackSegment) {
125517
125911
  const suffix = extractAhchatWorkspaceSuffix(requestedCwd);
125518
- if (suffix) return import_node_path17.default.join(workspacesDir, suffix);
125912
+ if (suffix) return import_node_path18.default.join(workspacesDir, suffix);
125519
125913
  const normalized = requestedCwd.trim();
125520
- const basename = normalized ? import_node_path17.default.basename(import_node_path17.default.normalize(normalized)) : "";
125521
- const segment = basename && basename !== "." && basename !== import_node_path17.default.sep ? basename : fallbackSegment;
125522
- return import_node_path17.default.join(workspacesDir, segment);
125914
+ const basename = normalized ? import_node_path18.default.basename(import_node_path18.default.normalize(normalized)) : "";
125915
+ const segment = basename && basename !== "." && basename !== import_node_path18.default.sep ? basename : fallbackSegment;
125916
+ return import_node_path18.default.join(workspacesDir, segment);
125523
125917
  }
125524
125918
  function cwdCandidatesForBridge(requestedCwd, opts) {
125525
125919
  const candidates = [requestedCwd];
@@ -125555,11 +125949,11 @@ async function resolveDumpWorkdir(requestedCwd, opts) {
125555
125949
  return remapped.path;
125556
125950
  }
125557
125951
  try {
125558
- await import_promises4.default.mkdir(requestedCwd, { recursive: true });
125952
+ await import_promises5.default.mkdir(requestedCwd, { recursive: true });
125559
125953
  return requestedCwd;
125560
125954
  } catch (e) {
125561
125955
  const fallback = fallbackBridgeWorkspacePath(requestedCwd, opts.workspacesDir, opts.fallbackSegment);
125562
- if (import_node_path17.default.normalize(fallback) === import_node_path17.default.normalize(requestedCwd)) throw e;
125956
+ if (import_node_path18.default.normalize(fallback) === import_node_path18.default.normalize(requestedCwd)) throw e;
125563
125957
  logger25.warn("Dump workdir inaccessible; using local Bridge workspace fallback", {
125564
125958
  agentId: opts.agentId,
125565
125959
  requested: requestedCwd,
@@ -125573,7 +125967,7 @@ async function findJsonlInClaudeProjects(sessionId, projectsDirs) {
125573
125967
  for (const projectsDir of projectsDirs) {
125574
125968
  let dirs;
125575
125969
  try {
125576
- dirs = await import_promises4.default.readdir(projectsDir, { withFileTypes: true });
125970
+ dirs = await import_promises5.default.readdir(projectsDir, { withFileTypes: true });
125577
125971
  } catch (e) {
125578
125972
  const code = errorCode(e);
125579
125973
  if (code === "ENOENT" || code === "ENOTDIR") continue;
@@ -125582,7 +125976,7 @@ async function findJsonlInClaudeProjects(sessionId, projectsDirs) {
125582
125976
  }
125583
125977
  for (const dir of dirs) {
125584
125978
  if (!dir.isDirectory()) continue;
125585
- const candidate = import_node_path17.default.join(projectsDir, dir.name, `${sessionId}.jsonl`);
125979
+ const candidate = import_node_path18.default.join(projectsDir, dir.name, `${sessionId}.jsonl`);
125586
125980
  if (await isReadableFile(candidate)) return candidate;
125587
125981
  }
125588
125982
  }
@@ -125591,7 +125985,7 @@ async function findJsonlInClaudeProjects(sessionId, projectsDirs) {
125591
125985
  async function latestJsonlInProjectDir(projectDir) {
125592
125986
  let entries;
125593
125987
  try {
125594
- entries = await import_promises4.default.readdir(projectDir, { withFileTypes: true });
125988
+ entries = await import_promises5.default.readdir(projectDir, { withFileTypes: true });
125595
125989
  } catch (e) {
125596
125990
  const code = errorCode(e);
125597
125991
  if (code === "ENOENT" || code === "ENOTDIR") return null;
@@ -125601,15 +125995,15 @@ async function latestJsonlInProjectDir(projectDir) {
125601
125995
  let latest = null;
125602
125996
  for (const entry of entries) {
125603
125997
  if (!entry.isFile() || !entry.name.endsWith(".jsonl")) continue;
125604
- const jsonlPath = import_node_path17.default.join(projectDir, entry.name);
125998
+ const jsonlPath = import_node_path18.default.join(projectDir, entry.name);
125605
125999
  let stat3;
125606
126000
  try {
125607
- stat3 = await import_promises4.default.stat(jsonlPath);
126001
+ stat3 = await import_promises5.default.stat(jsonlPath);
125608
126002
  } catch (e) {
125609
126003
  logger25.warn("Discovered JSONL stat failed", { jsonlPath, error: e });
125610
126004
  continue;
125611
126005
  }
125612
- const sessionId = import_node_path17.default.basename(entry.name, ".jsonl");
126006
+ const sessionId = import_node_path18.default.basename(entry.name, ".jsonl");
125613
126007
  const discovered = { sessionId, jsonlPath, lastModified: stat3.mtimeMs };
125614
126008
  if (!latest || discovered.lastModified > latest.lastModified) {
125615
126009
  latest = discovered;
@@ -125618,8 +126012,8 @@ async function latestJsonlInProjectDir(projectDir) {
125618
126012
  return latest;
125619
126013
  }
125620
126014
  function isAgentIsolatedProjectsDir(projectsDir, agentId) {
125621
- const normalized = import_node_path17.default.normalize(projectsDir).toLowerCase();
125622
- const marker = import_node_path17.default.normalize(import_node_path17.default.join("api-key-agents", agentId, "projects")).toLowerCase();
126015
+ const normalized = import_node_path18.default.normalize(projectsDir).toLowerCase();
126016
+ const marker = import_node_path18.default.normalize(import_node_path18.default.join("api-key-agents", agentId, "projects")).toLowerCase();
125623
126017
  return normalized.endsWith(marker);
125624
126018
  }
125625
126019
  async function discoverLatestJsonlForScope(opts) {
@@ -125638,7 +126032,7 @@ async function discoverLatestJsonlForScope(opts) {
125638
126032
  if (!isAgentIsolatedProjectsDir(projectsDir, opts.agentId)) continue;
125639
126033
  let dirs;
125640
126034
  try {
125641
- dirs = await import_promises4.default.readdir(projectsDir, { withFileTypes: true });
126035
+ dirs = await import_promises5.default.readdir(projectsDir, { withFileTypes: true });
125642
126036
  } catch (e) {
125643
126037
  const code = errorCode(e);
125644
126038
  if (code === "ENOENT" || code === "ENOTDIR") continue;
@@ -125647,7 +126041,7 @@ async function discoverLatestJsonlForScope(opts) {
125647
126041
  }
125648
126042
  for (const dir of dirs) {
125649
126043
  if (!dir.isDirectory()) continue;
125650
- const latest = await latestJsonlInProjectDir(import_node_path17.default.join(projectsDir, dir.name));
126044
+ const latest = await latestJsonlInProjectDir(import_node_path18.default.join(projectsDir, dir.name));
125651
126045
  if (latest) discovered.push(latest);
125652
126046
  }
125653
126047
  }
@@ -125684,7 +126078,7 @@ function friendlyScopeError(e) {
125684
126078
  }
125685
126079
  var RENDERABLE_TYPES = /* @__PURE__ */ new Set(["user", "assistant", "system", "attachment"]);
125686
126080
  async function readJsonlEntries(filePath) {
125687
- const raw = await import_promises4.default.readFile(filePath, "utf-8");
126081
+ const raw = await import_promises5.default.readFile(filePath, "utf-8");
125688
126082
  const entries = [];
125689
126083
  for (const line of raw.split("\n")) {
125690
126084
  const trimmed = line.trim();
@@ -126040,8 +126434,8 @@ async function dumpAgentContext(agentId, deps) {
126040
126434
  agentId,
126041
126435
  workdirOverrideStore: deps.workdirOverrideStore
126042
126436
  });
126043
- const dumpDir = import_node_path17.default.join(localWorkdir, "sessioninfo");
126044
- await import_promises4.default.mkdir(dumpDir, { recursive: true });
126437
+ const dumpDir = import_node_path18.default.join(localWorkdir, "sessioninfo");
126438
+ await import_promises5.default.mkdir(dumpDir, { recursive: true });
126045
126439
  const groupWorkdirs = deps.groupRegistry?.getMyGroups(agentId).map((group) => group.workingDirectory) ?? [];
126046
126440
  const inferredAgentConfigDirs = inferredAgentConfigDirsFromWorkdirs([
126047
126441
  workdir,
@@ -126119,7 +126513,7 @@ async function dumpAgentContext(agentId, deps) {
126119
126513
  projectsDirs,
126120
126514
  sessionStore: deps.sessionStore
126121
126515
  });
126122
- resolvedSessionId = recovered ? import_node_path17.default.basename(jsonlPath, ".jsonl") : resolvedSessionId;
126516
+ resolvedSessionId = recovered ? import_node_path18.default.basename(jsonlPath, ".jsonl") : resolvedSessionId;
126123
126517
  if (recovered) {
126124
126518
  try {
126125
126519
  const info2 = await sdk3.getSessionInfo(resolvedSessionId);
@@ -126168,10 +126562,10 @@ async function dumpAgentContext(agentId, deps) {
126168
126562
  jsonlPath
126169
126563
  });
126170
126564
  const filename = scopeFilename(agent.name, scopeKey2, groupName);
126171
- const filePath = import_node_path17.default.join(dumpDir, filename);
126172
- await import_promises4.default.writeFile(filePath, html, "utf-8");
126565
+ const filePath = import_node_path18.default.join(dumpDir, filename);
126566
+ await import_promises5.default.writeFile(filePath, html, "utf-8");
126173
126567
  dumpedFiles.push(filename);
126174
- const stat3 = await import_promises4.default.stat(filePath);
126568
+ const stat3 = await import_promises5.default.stat(filePath);
126175
126569
  logger25.info("Scope context dumped", {
126176
126570
  agentId,
126177
126571
  scopeKey: scopeKey2,
@@ -126212,9 +126606,9 @@ async function dumpAgentContext(agentId, deps) {
126212
126606
  init_cjs_shims();
126213
126607
  var import_node_child_process4 = require("child_process");
126214
126608
  var import_node_crypto4 = __toESM(require("crypto"), 1);
126215
- var import_promises5 = __toESM(require("fs/promises"), 1);
126609
+ var import_promises6 = __toESM(require("fs/promises"), 1);
126216
126610
  var import_node_os10 = __toESM(require("os"), 1);
126217
- var import_node_path18 = __toESM(require("path"), 1);
126611
+ var import_node_path19 = __toESM(require("path"), 1);
126218
126612
  var import_node_util2 = require("util");
126219
126613
  var logger26 = createModuleLogger("bridge.clipboardFiles");
126220
126614
  var execFileAsync2 = (0, import_node_util2.promisify)(import_node_child_process4.execFile);
@@ -126225,28 +126619,28 @@ function isRecord5(value) {
126225
126619
  }
126226
126620
  function normalizeLocalPath(targetPath) {
126227
126621
  const trimmed = targetPath.trim();
126228
- const expanded = trimmed === "~" || trimmed.startsWith("~/") || trimmed.startsWith("~\\") ? import_node_path18.default.join(import_node_os10.default.homedir(), trimmed.slice(2)) : trimmed;
126229
- return import_node_path18.default.normalize(import_node_path18.default.resolve(expanded));
126622
+ const expanded = trimmed === "~" || trimmed.startsWith("~/") || trimmed.startsWith("~\\") ? import_node_path19.default.join(import_node_os10.default.homedir(), trimmed.slice(2)) : trimmed;
126623
+ return import_node_path19.default.normalize(import_node_path19.default.resolve(expanded));
126230
126624
  }
126231
126625
  function normalizeClipboardIdentityKey(value) {
126232
126626
  return process.platform === "win32" ? value.toLowerCase() : value;
126233
126627
  }
126234
126628
  async function resolveClipboardPathKey(resolvedPath) {
126235
126629
  try {
126236
- return normalizeClipboardIdentityKey(await import_promises5.default.realpath(resolvedPath));
126630
+ return normalizeClipboardIdentityKey(await import_promises6.default.realpath(resolvedPath));
126237
126631
  } catch (e) {
126238
126632
  logger26.debug("Clipboard realpath read skipped", { error: e, path: resolvedPath });
126239
126633
  return normalizeClipboardIdentityKey(resolvedPath);
126240
126634
  }
126241
126635
  }
126242
126636
  function looksLikeWindowsShortFileName(fileName) {
126243
- return /~\d/i.test(import_node_path18.default.basename(fileName));
126637
+ return /~\d/i.test(import_node_path19.default.basename(fileName));
126244
126638
  }
126245
126639
  function fileContentHash(buffer) {
126246
126640
  return import_node_crypto4.default.createHash("sha256").update(buffer).digest("hex");
126247
126641
  }
126248
126642
  function mimeTypeForFileName(fileName) {
126249
- const ext = import_node_path18.default.extname(fileName).toLowerCase();
126643
+ const ext = import_node_path19.default.extname(fileName).toLowerCase();
126250
126644
  if (ext === ".jpg" || ext === ".jpeg") return "image/jpeg";
126251
126645
  if (ext === ".png") return "image/png";
126252
126646
  if (ext === ".webp") return "image/webp";
@@ -126311,7 +126705,7 @@ async function readWindowsClipboardPathCandidates() {
126311
126705
  }
126312
126706
  }
126313
126707
  async function filePayloadFromPath(resolvedPath) {
126314
- const stat3 = await import_promises5.default.stat(resolvedPath);
126708
+ const stat3 = await import_promises6.default.stat(resolvedPath);
126315
126709
  if (!stat3.isFile()) return null;
126316
126710
  if (stat3.size > MAX_CLIPBOARD_FILE_SIZE) {
126317
126711
  logger26.warn("Clipboard file skipped because it is too large", {
@@ -126320,10 +126714,10 @@ async function filePayloadFromPath(resolvedPath) {
126320
126714
  });
126321
126715
  return null;
126322
126716
  }
126323
- const buffer = await import_promises5.default.readFile(resolvedPath);
126717
+ const buffer = await import_promises6.default.readFile(resolvedPath);
126324
126718
  const mimeType = mimeTypeForFileName(resolvedPath);
126325
126719
  return {
126326
- fileName: import_node_path18.default.basename(resolvedPath),
126720
+ fileName: import_node_path19.default.basename(resolvedPath),
126327
126721
  mimeType,
126328
126722
  contentBase64: buffer.toString("base64"),
126329
126723
  size: buffer.length,
@@ -126347,7 +126741,7 @@ async function readClipboardFiles() {
126347
126741
  const contentIndexes = /* @__PURE__ */ new Map();
126348
126742
  for (const resolvedPath of pathCandidates) {
126349
126743
  try {
126350
- const stat3 = await import_promises5.default.stat(resolvedPath);
126744
+ const stat3 = await import_promises6.default.stat(resolvedPath);
126351
126745
  if (stat3.isDirectory()) {
126352
126746
  skippedDirectoryCount += 1;
126353
126747
  continue;
@@ -126397,8 +126791,8 @@ async function readClipboardFiles() {
126397
126791
 
126398
126792
  // src/listDir.ts
126399
126793
  init_cjs_shims();
126400
- var import_promises6 = __toESM(require("fs/promises"), 1);
126401
- var import_node_path19 = __toESM(require("path"), 1);
126794
+ var import_promises7 = __toESM(require("fs/promises"), 1);
126795
+ var import_node_path20 = __toESM(require("path"), 1);
126402
126796
  var logger27 = createModuleLogger("bridge.listDir");
126403
126797
  function shouldIncludeEntry(name) {
126404
126798
  if (!name.startsWith(".")) return true;
@@ -126407,16 +126801,16 @@ function shouldIncludeEntry(name) {
126407
126801
  async function listDirectoryEntries(dirPath) {
126408
126802
  const resolvedDirPath = resolveUserPath(dirPath);
126409
126803
  logger27.info("listDirectoryEntries start", { path: dirPath, resolvedPath: resolvedDirPath });
126410
- const raw = await import_promises6.default.readdir(resolvedDirPath, { withFileTypes: true });
126804
+ const raw = await import_promises7.default.readdir(resolvedDirPath, { withFileTypes: true });
126411
126805
  const entries = [];
126412
126806
  for (const entry of raw) {
126413
126807
  if (!shouldIncludeEntry(entry.name)) continue;
126414
- const fullPath = import_node_path19.default.join(resolvedDirPath, entry.name);
126808
+ const fullPath = import_node_path20.default.join(resolvedDirPath, entry.name);
126415
126809
  const isDir = entry.isDirectory();
126416
126810
  let size;
126417
126811
  let mtime;
126418
126812
  try {
126419
- const stat3 = await import_promises6.default.stat(fullPath);
126813
+ const stat3 = await import_promises7.default.stat(fullPath);
126420
126814
  mtime = stat3.mtime.toISOString();
126421
126815
  if (!isDir) size = stat3.size;
126422
126816
  } catch (statErr) {
@@ -126445,20 +126839,20 @@ function normalizeRelativePath(relativePath) {
126445
126839
  return normalized;
126446
126840
  }
126447
126841
  function ensureInsideBase(baseDir, targetPath) {
126448
- const relative = import_node_path19.default.relative(baseDir, targetPath);
126449
- if (relative.startsWith("..") || import_node_path19.default.isAbsolute(relative)) {
126842
+ const relative = import_node_path20.default.relative(baseDir, targetPath);
126843
+ if (relative.startsWith("..") || import_node_path20.default.isAbsolute(relative)) {
126450
126844
  throw new Error("path is outside working directory");
126451
126845
  }
126452
126846
  }
126453
126847
  function ensureNotBaseDir(baseDir, targetPath) {
126454
- if (import_node_path19.default.relative(baseDir, targetPath) === "") {
126848
+ if (import_node_path20.default.relative(baseDir, targetPath) === "") {
126455
126849
  throw new Error("refusing to delete working directory root");
126456
126850
  }
126457
126851
  }
126458
126852
  async function ensureRealPathInsideBase(baseDir, targetPath) {
126459
126853
  const [realBase, realTarget] = await Promise.all([
126460
- import_promises6.default.realpath(baseDir),
126461
- import_promises6.default.realpath(targetPath)
126854
+ import_promises7.default.realpath(baseDir),
126855
+ import_promises7.default.realpath(targetPath)
126462
126856
  ]);
126463
126857
  ensureInsideBase(realBase, realTarget);
126464
126858
  return realTarget;
@@ -126466,11 +126860,11 @@ async function ensureRealPathInsideBase(baseDir, targetPath) {
126466
126860
  async function writeWorkdirFile(opts) {
126467
126861
  const resolvedBaseDir = resolveUserPath(opts.baseDir);
126468
126862
  const safeRelativePath = normalizeRelativePath(opts.relativePath);
126469
- const targetPath = import_node_path19.default.resolve(resolvedBaseDir, safeRelativePath);
126863
+ const targetPath = import_node_path20.default.resolve(resolvedBaseDir, safeRelativePath);
126470
126864
  ensureInsideBase(resolvedBaseDir, targetPath);
126471
126865
  const buffer = Buffer.from(opts.contentBase64, "base64");
126472
- await import_promises6.default.mkdir(import_node_path19.default.dirname(targetPath), { recursive: true });
126473
- await import_promises6.default.writeFile(targetPath, buffer, { flag: opts.overwrite ? "w" : "wx" });
126866
+ await import_promises7.default.mkdir(import_node_path20.default.dirname(targetPath), { recursive: true });
126867
+ await import_promises7.default.writeFile(targetPath, buffer, { flag: opts.overwrite ? "w" : "wx" });
126474
126868
  logger27.info("writeWorkdirFile ok", {
126475
126869
  baseDir: opts.baseDir,
126476
126870
  path: targetPath,
@@ -126482,12 +126876,12 @@ async function writeWorkdirFile(opts) {
126482
126876
  async function readWorkdirFile(filePath, baseDir) {
126483
126877
  const resolvedPath = resolveUserPath(filePath);
126484
126878
  const safePath = baseDir ? await ensureRealPathInsideBase(resolveUserPath(baseDir), resolvedPath) : resolvedPath;
126485
- const stat3 = await import_promises6.default.stat(safePath);
126879
+ const stat3 = await import_promises7.default.stat(safePath);
126486
126880
  if (!stat3.isFile()) throw new Error("path is not a file");
126487
- const buffer = await import_promises6.default.readFile(safePath);
126881
+ const buffer = await import_promises7.default.readFile(safePath);
126488
126882
  logger27.info("readWorkdirFile ok", { path: filePath, baseDir, resolvedPath: safePath, size: buffer.length });
126489
126883
  return {
126490
- fileName: import_node_path19.default.basename(safePath),
126884
+ fileName: import_node_path20.default.basename(safePath),
126491
126885
  contentBase64: buffer.toString("base64"),
126492
126886
  size: buffer.length
126493
126887
  };
@@ -126497,9 +126891,9 @@ async function allocateTrashPath(trashDir, name) {
126497
126891
  const stamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
126498
126892
  for (let index = 0; index < 1e3; index += 1) {
126499
126893
  const suffix = index === 0 ? "" : `-${index}`;
126500
- const candidate = import_node_path19.default.join(trashDir, `${stamp}-${safeName}${suffix}`);
126894
+ const candidate = import_node_path20.default.join(trashDir, `${stamp}-${safeName}${suffix}`);
126501
126895
  try {
126502
- await import_promises6.default.lstat(candidate);
126896
+ await import_promises7.default.lstat(candidate);
126503
126897
  } catch (e) {
126504
126898
  if (e instanceof Error && "code" in e && e.code === "ENOENT") return candidate;
126505
126899
  throw e;
@@ -126515,15 +126909,15 @@ async function trashWorkdirPath(opts) {
126515
126909
  const resolvedBaseDir = resolveUserPath(opts.baseDir);
126516
126910
  const resolvedTargetPath = resolveUserPath(opts.targetPath);
126517
126911
  const [realBase, realTarget] = await Promise.all([
126518
- import_promises6.default.realpath(resolvedBaseDir),
126519
- import_promises6.default.realpath(resolvedTargetPath)
126912
+ import_promises7.default.realpath(resolvedBaseDir),
126913
+ import_promises7.default.realpath(resolvedTargetPath)
126520
126914
  ]);
126521
126915
  ensureInsideBase(realBase, realTarget);
126522
126916
  ensureNotBaseDir(realBase, realTarget);
126523
- const trashDir = import_node_path19.default.join(resolvedBaseDir, ".ahchat-trash");
126524
- await import_promises6.default.mkdir(trashDir, { recursive: true });
126525
- const trashedPath = await allocateTrashPath(trashDir, import_node_path19.default.basename(resolvedTargetPath));
126526
- await import_promises6.default.rename(resolvedTargetPath, trashedPath);
126917
+ const trashDir = import_node_path20.default.join(resolvedBaseDir, ".ahchat-trash");
126918
+ await import_promises7.default.mkdir(trashDir, { recursive: true });
126919
+ const trashedPath = await allocateTrashPath(trashDir, import_node_path20.default.basename(resolvedTargetPath));
126920
+ await import_promises7.default.rename(resolvedTargetPath, trashedPath);
126527
126921
  logger27.info("trashWorkdirPath ok", {
126528
126922
  path: opts.targetPath,
126529
126923
  baseDir: opts.baseDir,
@@ -126536,7 +126930,7 @@ async function trashWorkdirPath(opts) {
126536
126930
  // src/logScanner.ts
126537
126931
  init_cjs_shims();
126538
126932
  var import_node_fs10 = __toESM(require("fs"), 1);
126539
- var import_node_path20 = __toESM(require("path"), 1);
126933
+ var import_node_path21 = __toESM(require("path"), 1);
126540
126934
  var import_node_os11 = __toESM(require("os"), 1);
126541
126935
  var import_node_readline = __toESM(require("readline"), 1);
126542
126936
  var logger28 = createModuleLogger("bridge.logScanner");
@@ -126551,10 +126945,10 @@ function listLogFiles(logsDir, baseName) {
126551
126945
  }
126552
126946
  const escapedBaseName = baseName.replace(".", "\\.");
126553
126947
  const pattern = new RegExp(`^${escapedBaseName}(?:[.-].+)?$`);
126554
- return names.filter((n) => pattern.test(n)).map((n) => import_node_path20.default.join(logsDir, n));
126948
+ return names.filter((n) => pattern.test(n)).map((n) => import_node_path21.default.join(logsDir, n));
126555
126949
  }
126556
126950
  async function scanFile(filePath, source, filter, state) {
126557
- const file2 = import_node_path20.default.basename(filePath);
126951
+ const file2 = import_node_path21.default.basename(filePath);
126558
126952
  const stream = import_node_fs10.default.createReadStream(filePath, { encoding: "utf-8" });
126559
126953
  const rl = import_node_readline.default.createInterface({ input: stream, crlfDelay: Infinity });
126560
126954
  let lineNum = 0;
@@ -126598,7 +126992,7 @@ async function scanLocalLogs(logsDir, baseName, filter) {
126598
126992
  };
126599
126993
  }
126600
126994
  async function scanBridgeLogs(filter) {
126601
- const logDir = import_node_path20.default.join(loadBridgeConfig().dataDir || import_node_path20.default.join(import_node_os11.default.homedir(), ".ahchat"), "logs");
126995
+ const logDir = import_node_path21.default.join(loadBridgeConfig().dataDir || import_node_path21.default.join(import_node_os11.default.homedir(), ".ahchat"), "logs");
126602
126996
  logger28.info("scanBridgeLogs start", {
126603
126997
  logDir,
126604
126998
  startIso: filter.startIso,
@@ -126619,33 +127013,72 @@ async function scanBridgeLogs(filter) {
126619
127013
  // src/logUploader.ts
126620
127014
  init_cjs_shims();
126621
127015
  var import_node_fs11 = __toESM(require("fs"), 1);
126622
- var import_promises7 = __toESM(require("fs/promises"), 1);
126623
- var import_node_path21 = __toESM(require("path"), 1);
127016
+ var import_promises8 = __toESM(require("fs/promises"), 1);
127017
+ var import_node_path22 = __toESM(require("path"), 1);
126624
127018
  var logger29 = createModuleLogger("bridge.logUploader");
127019
+ var STALE_RATE_LIMIT_SKIP_AGE_MS = 7 * 24 * 60 * 60 * 1e3;
126625
127020
  var DEFAULT_LOG_UPLOAD_INTERVAL_MS = 24 * 60 * 60 * 1e3;
126626
127021
  var DEFAULT_BATCH_SIZE = 200;
127022
+ var MAX_UPLOAD_CHUNK_BODY_BYTES = 448 * 1024;
127023
+ var MAX_UPLOAD_RETRY_AFTER_MS = 24 * 60 * 60 * 1e3;
127024
+ var LogUploadHttpError = class extends Error {
127025
+ status;
127026
+ scope;
127027
+ retryAfterMs;
127028
+ constructor(status, bodyText) {
127029
+ const parsed = parseUploadErrorBody(bodyText);
127030
+ const summary = parsed.error ?? bodyText;
127031
+ super(`upload failed HTTP ${status}: ${summary.slice(0, 160)}`);
127032
+ this.name = "LogUploadHttpError";
127033
+ this.status = status;
127034
+ if (parsed.scope) this.scope = parsed.scope;
127035
+ if (parsed.retryAfterMs !== void 0) this.retryAfterMs = parsed.retryAfterMs;
127036
+ }
127037
+ };
127038
+ function normalizeRetryAfterMs(value) {
127039
+ if (typeof value !== "number" || !Number.isFinite(value) || value <= 0) return void 0;
127040
+ return Math.min(Math.ceil(value), MAX_UPLOAD_RETRY_AFTER_MS);
127041
+ }
127042
+ function parseUploadErrorBody(bodyText) {
127043
+ try {
127044
+ const parsed = JSON.parse(bodyText);
127045
+ if (typeof parsed !== "object" || parsed === null) return {};
127046
+ const body = parsed;
127047
+ return {
127048
+ ...typeof body.error === "string" && body.error.length > 0 ? { error: body.error } : {},
127049
+ ...typeof body.scope === "string" && body.scope.length > 0 ? { scope: body.scope } : {},
127050
+ ...(() => {
127051
+ const retryAfterMs = normalizeRetryAfterMs(body.retryAfterMs);
127052
+ return retryAfterMs === void 0 ? {} : { retryAfterMs };
127053
+ })()
127054
+ };
127055
+ } catch (e) {
127056
+ logger29.debug("Failed to parse log upload error body", { error: e });
127057
+ return {};
127058
+ }
127059
+ }
126627
127060
  function defaultLogFile(dataDir) {
126628
- return import_node_path21.default.join(dataDir, "logs", "bridge.log");
127061
+ return import_node_path22.default.join(dataDir, "logs", "bridge.log");
126629
127062
  }
126630
127063
  function defaultCursorFile(dataDir) {
126631
- return import_node_path21.default.join(dataDir, "log-upload-cursor.json");
127064
+ return import_node_path22.default.join(dataDir, "log-upload-cursor.json");
126632
127065
  }
126633
127066
  function uploadedFileName(logFile, explicit) {
126634
127067
  const trimmed = explicit?.trim();
126635
- return trimmed || import_node_path21.default.basename(logFile);
127068
+ return trimmed || import_node_path22.default.basename(logFile);
126636
127069
  }
126637
127070
  function normalizeTarget(file2, dataDir) {
126638
127071
  const fileName = uploadedFileName(file2.logFile, file2.uploadedFileName);
126639
127072
  const safeName = fileName.replace(/[^a-zA-Z0-9._-]/g, "_");
126640
127073
  return {
126641
127074
  logFile: file2.logFile,
126642
- cursorFile: file2.cursorFile ?? import_node_path21.default.join(dataDir, `log-upload-cursor-${safeName}.json`),
127075
+ cursorFile: file2.cursorFile ?? import_node_path22.default.join(dataDir, `log-upload-cursor-${safeName}.json`),
126643
127076
  uploadedFileName: fileName
126644
127077
  };
126645
127078
  }
126646
127079
  function cursorFileForLog(dataDir, fileName) {
126647
127080
  const safeName = fileName.replace(/[^a-zA-Z0-9._-]/g, "_");
126648
- return import_node_path21.default.join(dataDir, `log-upload-cursor-${safeName}.json`);
127081
+ return import_node_path22.default.join(dataDir, `log-upload-cursor-${safeName}.json`);
126649
127082
  }
126650
127083
  function logFileFingerprint(stat3) {
126651
127084
  if (typeof stat3.dev === "number" && typeof stat3.ino === "number" && stat3.ino > 0) {
@@ -126654,11 +127087,11 @@ function logFileFingerprint(stat3) {
126654
127087
  return void 0;
126655
127088
  }
126656
127089
  async function listRotatedBridgeTargets(primary, dataDir) {
126657
- const logDir = import_node_path21.default.dirname(primary.logFile);
126658
- const baseName = import_node_path21.default.basename(primary.logFile);
127090
+ const logDir = import_node_path22.default.dirname(primary.logFile);
127091
+ const baseName = import_node_path22.default.basename(primary.logFile);
126659
127092
  let names;
126660
127093
  try {
126661
- names = await import_promises7.default.readdir(logDir);
127094
+ names = await import_promises8.default.readdir(logDir);
126662
127095
  } catch (e) {
126663
127096
  if (e instanceof Error && "code" in e && e.code === "ENOENT") return [];
126664
127097
  throw e;
@@ -126668,7 +127101,7 @@ async function listRotatedBridgeTargets(primary, dataDir) {
126668
127101
  return names.filter((name) => pattern.test(name)).sort().map((name) => {
126669
127102
  if (name === baseName) return primary;
126670
127103
  return {
126671
- logFile: import_node_path21.default.join(logDir, name),
127104
+ logFile: import_node_path22.default.join(logDir, name),
126672
127105
  cursorFile: cursorFileForLog(dataDir, name),
126673
127106
  uploadedFileName: name
126674
127107
  };
@@ -126685,7 +127118,7 @@ function safeCursor(raw) {
126685
127118
  }
126686
127119
  async function readCursor(filePath) {
126687
127120
  try {
126688
- const raw = await import_promises7.default.readFile(filePath, "utf8");
127121
+ const raw = await import_promises8.default.readFile(filePath, "utf8");
126689
127122
  return safeCursor(JSON.parse(raw));
126690
127123
  } catch (e) {
126691
127124
  if (e instanceof Error && "code" in e && e.code === "ENOENT") {
@@ -126696,8 +127129,8 @@ async function readCursor(filePath) {
126696
127129
  }
126697
127130
  }
126698
127131
  async function writeCursor(filePath, cursor) {
126699
- await import_promises7.default.mkdir(import_node_path21.default.dirname(filePath), { recursive: true });
126700
- await import_promises7.default.writeFile(filePath, JSON.stringify(cursor), "utf8");
127132
+ await import_promises8.default.mkdir(import_node_path22.default.dirname(filePath), { recursive: true });
127133
+ await import_promises8.default.writeFile(filePath, JSON.stringify(cursor), "utf8");
126701
127134
  }
126702
127135
  async function readStreamText(filePath, start) {
126703
127136
  const stream = import_node_fs11.default.createReadStream(filePath, { start, encoding: "utf8" });
@@ -126713,26 +127146,38 @@ function parseProcessedLines(raw, cursor, fileName, fingerprint) {
126713
127146
  return { entries: [], nextCursor: cursor, advanced: false, reason: "partial_line" };
126714
127147
  }
126715
127148
  const processed = raw.slice(0, lastNewline + 1);
126716
- const lines = processed.split(/\r?\n/);
127149
+ const linePattern = /.*?\n/g;
126717
127150
  const entries = [];
126718
127151
  let lineNum = cursor.lineNum;
126719
- for (let i = 0; i < lines.length - 1; i += 1) {
126720
- const line = lines[i] ?? "";
127152
+ let offset = cursor.offset;
127153
+ let match;
127154
+ while ((match = linePattern.exec(processed)) !== null) {
127155
+ const rawLine = match[0];
127156
+ const line = rawLine.endsWith("\r\n") ? rawLine.slice(0, -2) : rawLine.slice(0, -1);
126721
127157
  lineNum += 1;
127158
+ offset += Buffer.byteLength(rawLine, "utf8");
127159
+ const cursorAfter = {
127160
+ offset,
127161
+ lineNum,
127162
+ ...fingerprint ? { fingerprint } : {}
127163
+ };
126722
127164
  if (line.length === 0) continue;
126723
127165
  const parsed = parseLogLine(line);
126724
127166
  if (!parsed) continue;
126725
127167
  entries.push({
126726
- ...parsed,
126727
- raw: line,
126728
- file: fileName,
126729
- lineNum
127168
+ entry: {
127169
+ ...parsed,
127170
+ raw: line,
127171
+ file: fileName,
127172
+ lineNum
127173
+ },
127174
+ cursorAfter
126730
127175
  });
126731
127176
  }
126732
127177
  return {
126733
127178
  entries,
126734
127179
  nextCursor: {
126735
- offset: cursor.offset + Buffer.byteLength(processed, "utf8"),
127180
+ offset,
126736
127181
  lineNum,
126737
127182
  ...fingerprint ? { fingerprint } : {}
126738
127183
  },
@@ -126740,15 +127185,35 @@ function parseProcessedLines(raw, cursor, fileName, fingerprint) {
126740
127185
  reason: "advanced"
126741
127186
  };
126742
127187
  }
126743
- function chunkEntries(entries, size) {
126744
- const chunks = [];
126745
- for (let i = 0; i < entries.length; i += size) {
126746
- chunks.push(entries.slice(i, i + size));
127188
+ function logEntryTimeRange(entries) {
127189
+ let minTime = Number.POSITIVE_INFINITY;
127190
+ let maxTime = Number.NEGATIVE_INFINITY;
127191
+ let minTs = "";
127192
+ let maxTs = "";
127193
+ for (const entry of entries) {
127194
+ const parsed = Date.parse(entry.ts);
127195
+ if (!Number.isFinite(parsed)) return null;
127196
+ if (parsed < minTime) {
127197
+ minTime = parsed;
127198
+ minTs = entry.ts;
127199
+ }
127200
+ if (parsed > maxTime) {
127201
+ maxTime = parsed;
127202
+ maxTs = entry.ts;
127203
+ }
126747
127204
  }
126748
- return chunks;
127205
+ if (!minTs || !maxTs) return null;
127206
+ return { minTs, maxTs, maxTime };
127207
+ }
127208
+ function isStaleRateLimitedChunk(entries, nowMs) {
127209
+ const range = logEntryTimeRange(entries);
127210
+ if (!range) return null;
127211
+ if (nowMs - range.maxTime <= STALE_RATE_LIMIT_SKIP_AGE_MS) return null;
127212
+ return { minTs: range.minTs, maxTs: range.maxTs };
126749
127213
  }
126750
127214
  var BridgeLogUploader = class {
126751
127215
  options;
127216
+ retryAfterByTarget = /* @__PURE__ */ new Map();
126752
127217
  timer = null;
126753
127218
  running = false;
126754
127219
  stopped = false;
@@ -126765,7 +127230,7 @@ var BridgeLogUploader = class {
126765
127230
  bridgeId: options.bridgeId,
126766
127231
  hostname: options.hostname,
126767
127232
  intervalMs: options.intervalMs ?? DEFAULT_LOG_UPLOAD_INTERVAL_MS,
126768
- batchSize: options.batchSize ?? DEFAULT_BATCH_SIZE,
127233
+ batchSize: Math.max(1, Math.floor(options.batchSize ?? DEFAULT_BATCH_SIZE)),
126769
127234
  primaryTarget,
126770
127235
  extraTargets: (options.extraLogFiles ?? []).map((file2) => normalizeTarget(file2, options.dataDir)),
126771
127236
  includeRotatedBridgeLogs: options.includeRotatedBridgeLogs ?? true
@@ -126807,13 +127272,26 @@ var BridgeLogUploader = class {
126807
127272
  bridgeEntryCount: 0,
126808
127273
  uploadedChunkCount: 0,
126809
127274
  accepted: 0,
126810
- skipped: 0
127275
+ skipped: 0,
127276
+ dropped: 0
126811
127277
  };
126812
127278
  try {
126813
127279
  const targets = await this.resolveTargets();
126814
127280
  summary.targetCount = targets.length;
126815
127281
  for (const target of targets) {
127282
+ const targetKey = this.targetKey(target);
126816
127283
  try {
127284
+ const retryUntil = this.retryAfterByTarget.get(targetKey);
127285
+ const now = Date.now();
127286
+ if (retryUntil && retryUntil > now) {
127287
+ summary.idleTargetCount += 1;
127288
+ logger29.debug("Bridge log upload target backoff active", {
127289
+ logFile: target.logFile,
127290
+ retryAfterMs: retryUntil - now
127291
+ });
127292
+ continue;
127293
+ }
127294
+ if (retryUntil) this.retryAfterByTarget.delete(targetKey);
126817
127295
  const cursor = await readCursor(target.cursorFile);
126818
127296
  const batch = await this.readNewEntries(target, cursor);
126819
127297
  if (!batch.advanced) {
@@ -126825,28 +127303,45 @@ var BridgeLogUploader = class {
126825
127303
  summary.advancedTargetCount += 1;
126826
127304
  summary.parsedEntryCount += batch.entries.length;
126827
127305
  if (batch.entries.length > 0) {
126828
- const result = await this.uploadEntries(batch.entries);
127306
+ const result = await this.uploadEntries(batch.entries, target.cursorFile, batch.nextCursor);
126829
127307
  summary.bridgeEntryCount += result.bridgeEntryCount;
126830
127308
  summary.uploadedChunkCount += result.uploadedChunkCount;
126831
127309
  summary.accepted += result.accepted;
126832
127310
  summary.skipped += result.skipped;
127311
+ summary.dropped += result.dropped;
127312
+ } else {
127313
+ await writeCursor(target.cursorFile, batch.nextCursor);
126833
127314
  }
126834
- await writeCursor(target.cursorFile, batch.nextCursor);
127315
+ this.retryAfterByTarget.delete(targetKey);
126835
127316
  } catch (e) {
126836
127317
  summary.failedTargetCount += 1;
126837
- logger29.warn("Bridge log upload target failed", { error: e, logFile: target.logFile });
127318
+ if (e instanceof LogUploadHttpError && e.retryAfterMs !== void 0) {
127319
+ this.retryAfterByTarget.set(targetKey, Date.now() + e.retryAfterMs);
127320
+ logger29.warn("Bridge log upload target failed", {
127321
+ error: e,
127322
+ logFile: target.logFile,
127323
+ status: e.status,
127324
+ quotaScope: e.scope,
127325
+ retryAfterMs: e.retryAfterMs
127326
+ });
127327
+ } else {
127328
+ logger29.warn("Bridge log upload target failed", { error: e, logFile: target.logFile });
127329
+ }
126838
127330
  }
126839
127331
  }
126840
127332
  } catch (e) {
126841
127333
  logger29.warn("Bridge log upload cycle failed", { error: e });
126842
127334
  } finally {
126843
- logger29.info("Bridge log upload cycle summary", {
127335
+ logger29.debug("Bridge log upload cycle summary", {
126844
127336
  ...summary,
126845
127337
  durationMs: Date.now() - startedAt
126846
127338
  });
126847
127339
  this.running = false;
126848
127340
  }
126849
127341
  }
127342
+ targetKey(target) {
127343
+ return `${target.logFile}\0${target.cursorFile}`;
127344
+ }
126850
127345
  async resolveTargets() {
126851
127346
  const bridgeTargets = this.options.includeRotatedBridgeLogs ? await listRotatedBridgeTargets(this.options.primaryTarget, this.options.dataDir) : [this.options.primaryTarget];
126852
127347
  const seen = /* @__PURE__ */ new Set();
@@ -126862,7 +127357,7 @@ var BridgeLogUploader = class {
126862
127357
  async readNewEntries(target, cursor) {
126863
127358
  let stat3;
126864
127359
  try {
126865
- stat3 = await import_promises7.default.stat(target.logFile);
127360
+ stat3 = await import_promises8.default.stat(target.logFile);
126866
127361
  } catch (e) {
126867
127362
  if (e instanceof Error && "code" in e && e.code === "ENOENT") {
126868
127363
  logger29.debug("Bridge log file not found for upload yet", { logFile: target.logFile });
@@ -126879,15 +127374,40 @@ var BridgeLogUploader = class {
126879
127374
  const raw = await readStreamText(target.logFile, normalizedCursor.offset);
126880
127375
  return parseProcessedLines(raw, normalizedCursor, target.uploadedFileName, fingerprint);
126881
127376
  }
126882
- async uploadEntries(entries) {
126883
- const bridgeEntries = entries.filter((entry) => entry.source === "bridge");
127377
+ uploadBodyBytes(entries) {
127378
+ return Buffer.byteLength(JSON.stringify({
127379
+ bridgeId: this.options.bridgeId,
127380
+ hostname: this.options.hostname,
127381
+ entries
127382
+ }), "utf8");
127383
+ }
127384
+ chunkUploadEntries(entries) {
127385
+ const chunks = [];
127386
+ let current = [];
127387
+ for (const entry of entries) {
127388
+ const next = [...current, entry];
127389
+ const nextBodyBytes = this.uploadBodyBytes(next.map((item) => item.entry));
127390
+ if (current.length > 0 && (current.length >= this.options.batchSize || nextBodyBytes > MAX_UPLOAD_CHUNK_BODY_BYTES)) {
127391
+ chunks.push(current);
127392
+ current = [entry];
127393
+ } else {
127394
+ current = next;
127395
+ }
127396
+ }
127397
+ if (current.length > 0) chunks.push(current);
127398
+ return chunks;
127399
+ }
127400
+ async uploadEntries(entries, cursorFile, finalCursor) {
127401
+ const bridgeEntries = entries.filter((item) => item.entry.source === "bridge");
126884
127402
  const result = {
126885
127403
  bridgeEntryCount: bridgeEntries.length,
126886
127404
  uploadedChunkCount: 0,
126887
127405
  accepted: 0,
126888
- skipped: 0
127406
+ skipped: 0,
127407
+ dropped: 0
126889
127408
  };
126890
- for (const chunk of chunkEntries(bridgeEntries, this.options.batchSize)) {
127409
+ for (const chunk of this.chunkUploadEntries(bridgeEntries)) {
127410
+ const payloadEntries = chunk.map((item) => item.entry);
126891
127411
  const res = await fetch(`${this.options.serverApiUrl}/api/logs/upload`, {
126892
127412
  method: "POST",
126893
127413
  headers: {
@@ -126897,7 +127417,7 @@ var BridgeLogUploader = class {
126897
127417
  body: JSON.stringify({
126898
127418
  bridgeId: this.options.bridgeId,
126899
127419
  hostname: this.options.hostname,
126900
- entries: chunk
127420
+ entries: payloadEntries
126901
127421
  })
126902
127422
  });
126903
127423
  if (!res.ok) {
@@ -126905,13 +127425,27 @@ var BridgeLogUploader = class {
126905
127425
  logger29.debug("Failed to read log upload error body", { error: e });
126906
127426
  return "";
126907
127427
  });
126908
- throw new Error(`upload failed HTTP ${res.status}: ${body2.slice(0, 160)}`);
127428
+ const staleChunk = res.status === 429 ? isStaleRateLimitedChunk(payloadEntries, Date.now()) : null;
127429
+ if (staleChunk) {
127430
+ result.dropped += chunk.length;
127431
+ logger29.warn("Skipping stale bridge log upload chunk after rate limit", {
127432
+ status: res.status,
127433
+ entryCount: chunk.length,
127434
+ minEntryTs: staleChunk.minTs,
127435
+ maxEntryTs: staleChunk.maxTs
127436
+ });
127437
+ continue;
127438
+ }
127439
+ throw new LogUploadHttpError(res.status, body2);
126909
127440
  }
126910
127441
  const body = await res.json();
126911
127442
  result.uploadedChunkCount += 1;
126912
127443
  result.accepted += typeof body.accepted === "number" ? body.accepted : 0;
126913
127444
  result.skipped += typeof body.skipped === "number" ? body.skipped : 0;
127445
+ const last = chunk[chunk.length - 1];
127446
+ if (last) await writeCursor(cursorFile, last.cursorAfter);
126914
127447
  }
127448
+ await writeCursor(cursorFile, finalCursor);
126915
127449
  return result;
126916
127450
  }
126917
127451
  };
@@ -126919,7 +127453,7 @@ var BridgeLogUploader = class {
126919
127453
  // src/skillStore.ts
126920
127454
  init_cjs_shims();
126921
127455
  var import_node_fs12 = __toESM(require("fs"), 1);
126922
- var import_node_path22 = __toESM(require("path"), 1);
127456
+ var import_node_path23 = __toESM(require("path"), 1);
126923
127457
  var logger30 = createModuleLogger("bridge.skillStore");
126924
127458
  var MANAGED_CACHE_MARKER = "<!-- ahchat-skill-cache";
126925
127459
  var SAFE_SKILL_NAME_RE = /^[a-zA-Z0-9_-]+$/;
@@ -126948,8 +127482,8 @@ var SkillStore = class {
126948
127482
  skillsDir;
126949
127483
  indexPath;
126950
127484
  constructor(dataDir) {
126951
- this.skillsDir = import_node_path22.default.join(dataDir, "skills");
126952
- this.indexPath = import_node_path22.default.join(this.skillsDir, INDEX_FILE_NAME);
127485
+ this.skillsDir = import_node_path23.default.join(dataDir, "skills");
127486
+ this.indexPath = import_node_path23.default.join(this.skillsDir, INDEX_FILE_NAME);
126953
127487
  import_node_fs12.default.mkdirSync(this.skillsDir, { recursive: true });
126954
127488
  logger30.info("SkillStore initialized", { skillsDir: this.skillsDir });
126955
127489
  }
@@ -126958,7 +127492,7 @@ var SkillStore = class {
126958
127492
  logger30.warn("Skill read: unsafe name", { name });
126959
127493
  return "";
126960
127494
  }
126961
- const filePath = import_node_path22.default.join(this.skillsDir, `${name}.md`);
127495
+ const filePath = import_node_path23.default.join(this.skillsDir, `${name}.md`);
126962
127496
  try {
126963
127497
  const content = import_node_fs12.default.readFileSync(filePath, "utf-8");
126964
127498
  logger30.info("Skill read", { name, bytes: content.length });
@@ -126986,7 +127520,7 @@ var SkillStore = class {
126986
127520
  if (!isSafeSkillName(name)) {
126987
127521
  throw new Error(`Unsafe skill name: ${name}`);
126988
127522
  }
126989
- const filePath = import_node_path22.default.join(this.skillsDir, `${name}.md`);
127523
+ const filePath = import_node_path23.default.join(this.skillsDir, `${name}.md`);
126990
127524
  const tmpPath = `${filePath}.tmp`;
126991
127525
  let existing = "";
126992
127526
  try {
@@ -126995,7 +127529,7 @@ var SkillStore = class {
126995
127529
  if (!isNotFoundError(e)) logger30.warn("Skill seed existing read failed", { name, filePath, error: e });
126996
127530
  }
126997
127531
  if (existing === content) {
126998
- logger30.info("Skill already in sync", { name, bytes: content.length });
127532
+ logger30.debug("Skill already in sync", { name, bytes: content.length });
126999
127533
  return;
127000
127534
  }
127001
127535
  import_node_fs12.default.writeFileSync(tmpPath, content, "utf-8");
@@ -127031,7 +127565,7 @@ var SkillStore = class {
127031
127565
  const content = this.readExisting(name);
127032
127566
  if (!isPrunableManagedSkillCache(content)) continue;
127033
127567
  try {
127034
- import_node_fs12.default.unlinkSync(import_node_path22.default.join(this.skillsDir, `${name}.md`));
127568
+ import_node_fs12.default.unlinkSync(import_node_path23.default.join(this.skillsDir, `${name}.md`));
127035
127569
  pruned += 1;
127036
127570
  logger30.info("Managed skill cache pruned", { name });
127037
127571
  } catch (e) {
@@ -127068,7 +127602,7 @@ var SkillStore = class {
127068
127602
  const content = this.readExisting(name);
127069
127603
  if (managedSkillCacheSource(content) !== source) continue;
127070
127604
  try {
127071
- import_node_fs12.default.unlinkSync(import_node_path22.default.join(this.skillsDir, `${name}.md`));
127605
+ import_node_fs12.default.unlinkSync(import_node_path23.default.join(this.skillsDir, `${name}.md`));
127072
127606
  pruned += 1;
127073
127607
  logger30.info("Managed skill cache pruned by source", { name, source });
127074
127608
  } catch (e) {
@@ -127092,7 +127626,7 @@ var SkillStore = class {
127092
127626
  }
127093
127627
  readExisting(name) {
127094
127628
  try {
127095
- return import_node_fs12.default.readFileSync(import_node_path22.default.join(this.skillsDir, `${name}.md`), "utf-8");
127629
+ return import_node_fs12.default.readFileSync(import_node_path23.default.join(this.skillsDir, `${name}.md`), "utf-8");
127096
127630
  } catch (e) {
127097
127631
  if (!isNotFoundError(e)) logger30.warn("Managed skill cache read failed", { name, error: e });
127098
127632
  return "";
@@ -127140,7 +127674,7 @@ function normalizeSkillIndexEntry(value) {
127140
127674
  init_cjs_shims();
127141
127675
  var childProcess = __toESM(require("child_process"), 1);
127142
127676
  var import_node_fs13 = __toESM(require("fs"), 1);
127143
- var import_node_path23 = __toESM(require("path"), 1);
127677
+ var import_node_path24 = __toESM(require("path"), 1);
127144
127678
  var logger31 = createModuleLogger("bridge.lockfile");
127145
127679
  var lockPath = null;
127146
127680
  var releaseRegistered = false;
@@ -127242,7 +127776,7 @@ function isLiveBridgeLockOwner(pid) {
127242
127776
  return false;
127243
127777
  }
127244
127778
  function acquireLock(dataDir) {
127245
- const file2 = import_node_path23.default.join(dataDir, "bridge.lock");
127779
+ const file2 = import_node_path24.default.join(dataDir, "bridge.lock");
127246
127780
  lockPath = file2;
127247
127781
  if (import_node_fs13.default.existsSync(file2)) {
127248
127782
  const raw = import_node_fs13.default.readFileSync(file2, "utf-8").trim();
@@ -127254,7 +127788,7 @@ function acquireLock(dataDir) {
127254
127788
  logger31.info("Removing stale bridge.lock", { pid, path: file2 });
127255
127789
  }
127256
127790
  }
127257
- import_node_fs13.default.mkdirSync(import_node_path23.default.dirname(file2), { recursive: true });
127791
+ import_node_fs13.default.mkdirSync(import_node_path24.default.dirname(file2), { recursive: true });
127258
127792
  import_node_fs13.default.writeFileSync(file2, String(process.pid), "utf-8");
127259
127793
  logger31.info("Acquired bridge lock", { path: file2, pid: process.pid });
127260
127794
  if (!releaseRegistered) {
@@ -127281,12 +127815,12 @@ function releaseLock() {
127281
127815
  // src/localWorkdirOverrideStore.ts
127282
127816
  init_cjs_shims();
127283
127817
  var import_node_fs14 = __toESM(require("fs"), 1);
127284
- var import_node_path24 = __toESM(require("path"), 1);
127818
+ var import_node_path25 = __toESM(require("path"), 1);
127285
127819
  var logger32 = createModuleLogger("bridge.localWorkdirOverride");
127286
127820
  var LocalWorkdirOverrideStore = class {
127287
127821
  filePath;
127288
127822
  constructor(dataDir) {
127289
- this.filePath = import_node_path24.default.join(dataDir, LOCAL_WORKDIR_OVERRIDES_FILENAME);
127823
+ this.filePath = import_node_path25.default.join(dataDir, LOCAL_WORKDIR_OVERRIDES_FILENAME);
127290
127824
  }
127291
127825
  read() {
127292
127826
  try {
@@ -127310,7 +127844,7 @@ var LocalWorkdirOverrideStore = class {
127310
127844
  const current = { version: 1, overrides: this.read() };
127311
127845
  const next = upsertLocalWorkdirOverride(current, args);
127312
127846
  import_node_fs14.default.mkdirSync(args.localWorkdir, { recursive: true });
127313
- import_node_fs14.default.mkdirSync(import_node_path24.default.dirname(this.filePath), { recursive: true });
127847
+ import_node_fs14.default.mkdirSync(import_node_path25.default.dirname(this.filePath), { recursive: true });
127314
127848
  import_node_fs14.default.writeFileSync(this.filePath, `${JSON.stringify(next, null, 2)}
127315
127849
  `, "utf8");
127316
127850
  const saved = next.overrides.find(
@@ -127735,7 +128269,7 @@ async function handleGroupArchivedPush(deps, payload) {
127735
128269
  // src/sessionStore.ts
127736
128270
  init_cjs_shims();
127737
128271
  var import_node_fs15 = __toESM(require("fs"), 1);
127738
- var import_node_path25 = __toESM(require("path"), 1);
128272
+ var import_node_path26 = __toESM(require("path"), 1);
127739
128273
  var logger35 = createModuleLogger("session.store");
127740
128274
  var SessionStore = class {
127741
128275
  filePath;
@@ -127743,8 +128277,8 @@ var SessionStore = class {
127743
128277
  cache;
127744
128278
  fingerprints;
127745
128279
  constructor(dataDir) {
127746
- this.filePath = import_node_path25.default.join(dataDir, "sessions.json");
127747
- this.fingerprintPath = import_node_path25.default.join(dataDir, "session-fingerprints.json");
128280
+ this.filePath = import_node_path26.default.join(dataDir, "sessions.json");
128281
+ this.fingerprintPath = import_node_path26.default.join(dataDir, "session-fingerprints.json");
127748
128282
  this.cache = this.loadFromDisk();
127749
128283
  this.fingerprints = this.loadMapFromDisk(this.fingerprintPath, "session fingerprints");
127750
128284
  }
@@ -127843,7 +128377,7 @@ var SessionStore = class {
127843
128377
  }
127844
128378
  saveToDisk() {
127845
128379
  try {
127846
- const dir = import_node_path25.default.dirname(this.filePath);
128380
+ const dir = import_node_path26.default.dirname(this.filePath);
127847
128381
  import_node_fs15.default.mkdirSync(dir, { recursive: true });
127848
128382
  import_node_fs15.default.writeFileSync(this.filePath, JSON.stringify(this.cache, null, 2), "utf-8");
127849
128383
  } catch (e) {
@@ -127852,7 +128386,7 @@ var SessionStore = class {
127852
128386
  }
127853
128387
  saveFingerprintsToDisk() {
127854
128388
  try {
127855
- const dir = import_node_path25.default.dirname(this.fingerprintPath);
128389
+ const dir = import_node_path26.default.dirname(this.fingerprintPath);
127856
128390
  import_node_fs15.default.mkdirSync(dir, { recursive: true });
127857
128391
  import_node_fs15.default.writeFileSync(
127858
128392
  this.fingerprintPath,
@@ -127871,7 +128405,7 @@ var SessionStore = class {
127871
128405
  // src/workdirEnsure.ts
127872
128406
  init_cjs_shims();
127873
128407
  var import_node_fs16 = __toESM(require("fs"), 1);
127874
- var import_node_path26 = __toESM(require("path"), 1);
128408
+ var import_node_path27 = __toESM(require("path"), 1);
127875
128409
  function resolveBridgeWorkdirPath(requestedPath, workspacesDir, workdirOverrideStore, target) {
127876
128410
  const overridden = target ? workdirOverrideStore?.resolvePath(requestedPath, target) : workdirOverrideStore?.resolvePath(requestedPath);
127877
128411
  if (overridden?.overridden) {
@@ -127883,15 +128417,15 @@ function ensureBridgeWorkdirExists(requestedPath, workspacesDir, workdirOverride
127883
128417
  const trimmed = requestedPath.trim();
127884
128418
  if (!trimmed) return null;
127885
128419
  const resolved = resolveBridgeWorkdirPath(trimmed, workspacesDir, workdirOverrideStore, target);
127886
- if (!import_node_path26.default.isAbsolute(resolved.path)) return { ...resolved, ensured: false };
128420
+ if (!import_node_path27.default.isAbsolute(resolved.path)) return { ...resolved, ensured: false };
127887
128421
  import_node_fs16.default.mkdirSync(resolved.path, { recursive: true });
127888
128422
  return { ...resolved, ensured: true };
127889
128423
  }
127890
128424
 
127891
128425
  // src/forkAgentFiles.ts
127892
128426
  init_cjs_shims();
127893
- var fs20 = __toESM(require("fs/promises"), 1);
127894
- var path28 = __toESM(require("path"), 1);
128427
+ var fs21 = __toESM(require("fs/promises"), 1);
128428
+ var path29 = __toESM(require("path"), 1);
127895
128429
  var logger36 = createModuleLogger("bridge.forkAgentFiles");
127896
128430
  async function forkAgentFiles(sourceAgentId, newAgentId, sourceWorkdir, newWorkdir, dataDir, sessionStore, sourceConversationId) {
127897
128431
  logger36.info("Fork file copy starting", {
@@ -127903,15 +128437,15 @@ async function forkAgentFiles(sourceAgentId, newAgentId, sourceWorkdir, newWorkd
127903
128437
  sourceConversationId
127904
128438
  });
127905
128439
  try {
127906
- const stat3 = await fs20.stat(sourceWorkdir).catch(() => null);
128440
+ const stat3 = await fs21.stat(sourceWorkdir).catch(() => null);
127907
128441
  if (stat3?.isDirectory()) {
127908
- await fs20.cp(sourceWorkdir, newWorkdir, { recursive: true });
128442
+ await fs21.cp(sourceWorkdir, newWorkdir, { recursive: true });
127909
128443
  logger36.info("Workdir copied", {
127910
128444
  from: sourceWorkdir,
127911
128445
  to: newWorkdir
127912
128446
  });
127913
128447
  } else {
127914
- await fs20.mkdir(newWorkdir, { recursive: true });
128448
+ await fs21.mkdir(newWorkdir, { recursive: true });
127915
128449
  logger36.info("Workdir created (source did not exist)", {
127916
128450
  newWorkdir
127917
128451
  });
@@ -127920,14 +128454,14 @@ async function forkAgentFiles(sourceAgentId, newAgentId, sourceWorkdir, newWorkd
127920
128454
  logger36.error("Workdir copy failed", { error: e });
127921
128455
  throw e;
127922
128456
  }
127923
- const srcNotebook = path28.join(dataDir, "agent-memory", sourceAgentId, "notebook.md");
127924
- const dstNotebookDir = path28.join(dataDir, "agent-memory", newAgentId);
127925
- const dstNotebook = path28.join(dstNotebookDir, "notebook.md");
128457
+ const srcNotebook = path29.join(dataDir, "agent-memory", sourceAgentId, "notebook.md");
128458
+ const dstNotebookDir = path29.join(dataDir, "agent-memory", newAgentId);
128459
+ const dstNotebook = path29.join(dstNotebookDir, "notebook.md");
127926
128460
  try {
127927
- const nbStat = await fs20.stat(srcNotebook).catch(() => null);
128461
+ const nbStat = await fs21.stat(srcNotebook).catch(() => null);
127928
128462
  if (nbStat?.isFile()) {
127929
- await fs20.mkdir(dstNotebookDir, { recursive: true });
127930
- await fs20.copyFile(srcNotebook, dstNotebook);
128463
+ await fs21.mkdir(dstNotebookDir, { recursive: true });
128464
+ await fs21.copyFile(srcNotebook, dstNotebook);
127931
128465
  logger36.info("Notebook copied", {
127932
128466
  from: srcNotebook,
127933
128467
  to: dstNotebook
@@ -127945,12 +128479,12 @@ async function forkAgentFiles(sourceAgentId, newAgentId, sourceWorkdir, newWorkd
127945
128479
  if (sourceSessionId) {
127946
128480
  try {
127947
128481
  const srcPath = sessionFilePath(sourceWorkdir, sourceSessionId);
127948
- const srcStat = await fs20.stat(srcPath).catch(() => null);
128482
+ const srcStat = await fs21.stat(srcPath).catch(() => null);
127949
128483
  if (srcStat?.isFile()) {
127950
128484
  const dstDir = sessionDirForCwd(newWorkdir);
127951
- await fs20.mkdir(dstDir, { recursive: true });
127952
- const dstPath = path28.join(dstDir, `${sourceSessionId}.jsonl`);
127953
- await fs20.copyFile(srcPath, dstPath);
128485
+ await fs21.mkdir(dstDir, { recursive: true });
128486
+ const dstPath = path29.join(dstDir, `${sourceSessionId}.jsonl`);
128487
+ await fs21.copyFile(srcPath, dstPath);
127954
128488
  sessionStore.set(newAgentId, { kind: "single" }, sourceSessionId);
127955
128489
  sessionCopied = true;
127956
128490
  logger36.info("Session JSONL copied and registered", {
@@ -127997,7 +128531,7 @@ async function forkAgentFiles(sourceAgentId, newAgentId, sourceWorkdir, newWorkd
127997
128531
  // src/feedbackCodexAnalyzer.ts
127998
128532
  init_cjs_shims();
127999
128533
  var import_node_child_process5 = require("child_process");
128000
- var import_node_path27 = __toESM(require("path"), 1);
128534
+ var import_node_path28 = __toESM(require("path"), 1);
128001
128535
  var logger37 = createModuleLogger("feedbackCodexAnalyzer");
128002
128536
  var DEFAULT_TIMEOUT_MS2 = 10 * 60 * 1e3;
128003
128537
  var MAX_OUTPUT_BYTES = 2 * 1024 * 1024;
@@ -128022,12 +128556,12 @@ function resolveFeedbackCodexOptions(defaultWorkdir, env2 = process.env) {
128022
128556
  const logDataDir = readOptionalEnv("AHCHAT_FEEDBACK_LOG_DATA_DIR", env2) ?? DEFAULT_LOG_DATA_DIR;
128023
128557
  return {
128024
128558
  executable: readOptionalEnv("AHCHAT_FEEDBACK_CODEX_EXECUTABLE", env2) ?? readOptionalEnv("CODEX_EXECUTABLE", env2) ?? "codex",
128025
- workdir: import_node_path27.default.resolve(readOptionalEnv("AHCHAT_FEEDBACK_CODEX_WORKDIR", env2) ?? defaultWorkdir),
128559
+ workdir: import_node_path28.default.resolve(readOptionalEnv("AHCHAT_FEEDBACK_CODEX_WORKDIR", env2) ?? defaultWorkdir),
128026
128560
  model: readOptionalEnv("AHCHAT_FEEDBACK_CODEX_MODEL", env2),
128027
128561
  timeoutMs: readPositiveIntEnv("AHCHAT_FEEDBACK_CODEX_TIMEOUT_MS", DEFAULT_TIMEOUT_MS2, env2),
128028
128562
  logSshTarget: readOptionalEnv("AHCHAT_FEEDBACK_LOG_SSH_TARGET", env2) ?? DEFAULT_LOG_SSH_TARGET,
128029
128563
  logDataDir,
128030
- logServerLogDir: readOptionalEnv("AHCHAT_FEEDBACK_LOG_SERVER_LOG_DIR", env2) ?? import_node_path27.default.posix.join(logDataDir, "logs"),
128564
+ logServerLogDir: readOptionalEnv("AHCHAT_FEEDBACK_LOG_SERVER_LOG_DIR", env2) ?? import_node_path28.default.posix.join(logDataDir, "logs"),
128031
128565
  logUploadTable: readOptionalEnv("AHCHAT_FEEDBACK_LOG_UPLOAD_TABLE", env2) ?? DEFAULT_LOG_UPLOAD_TABLE
128032
128566
  };
128033
128567
  }
@@ -128220,7 +128754,7 @@ function buildFeedbackAnalysisPrompt(payload, options, attachments) {
128220
128754
  - \u751F\u4EA7\u65E5\u5FD7\u76EE\u6807\uFF1A${options.logSshTarget}
128221
128755
  - AHChat \u6570\u636E\u76EE\u5F55\uFF1A${options.logDataDir}
128222
128756
  - \u670D\u52A1\u7AEF\u65E5\u5FD7\u76EE\u5F55\uFF1A${options.logServerLogDir}
128223
- - Bridge \u4E0A\u4F20\u65E5\u5FD7\u6570\u636E\u5E93\uFF1A${import_node_path27.default.posix.join(options.logDataDir, "data.db")}
128757
+ - Bridge \u4E0A\u4F20\u65E5\u5FD7\u6570\u636E\u5E93\uFF1A${import_node_path28.default.posix.join(options.logDataDir, "data.db")}
128224
128758
  - \u4E0A\u4F20\u65E5\u5FD7\u8868\uFF1A${options.logUploadTable}
128225
128759
  - \u5982\u679C\u76EE\u6807\u673A\u5668\u4E0A\u7684\u5B9A\u65F6\u4EFB\u52A1\u6216\u670D\u52A1\u914D\u7F6E\u663E\u793A\u65E5\u5FD7\u76EE\u5F55\u4E0D\u540C\uFF0C\u4EE5\u5B9E\u9645\u914D\u7F6E\u4E3A\u51C6\u3002
128226
128760
  - \u53EA\u505A\u53EA\u8BFB\u67E5\u8BE2\uFF1B\u4E0D\u8981\u590D\u5236\u6570\u636E\u5E93\uFF1B\u53EF\u7528 ssh \u5230\u76EE\u6807\u673A\u5668\u540E\u901A\u8FC7 python3/sqlite3 \u67E5\u8BE2\u3002
@@ -128396,15 +128930,15 @@ async function analyzeFeedbackWithLocalCodex(payload, options, attachments = [])
128396
128930
 
128397
128931
  // src/modelQuerier.ts
128398
128932
  init_cjs_shims();
128399
- var import_promises8 = __toESM(require("fs/promises"), 1);
128933
+ var import_promises9 = __toESM(require("fs/promises"), 1);
128400
128934
  var import_node_os12 = __toESM(require("os"), 1);
128401
- var import_node_path28 = __toESM(require("path"), 1);
128935
+ var import_node_path29 = __toESM(require("path"), 1);
128402
128936
  var sdk4 = __toESM(require("@anthropic-ai/claude-agent-sdk"), 1);
128403
128937
  var logger38 = createModuleLogger("bridge.modelQuerier");
128404
128938
  async function listModels(queryFn, opts = {}) {
128405
128939
  const t0 = Date.now();
128406
- const cwd = opts.cwd ?? import_node_path28.default.join(import_node_os12.default.homedir(), ".ahchat", "workspaces", "_list_models");
128407
- await import_promises8.default.mkdir(cwd, { recursive: true });
128940
+ const cwd = opts.cwd ?? import_node_path29.default.join(import_node_os12.default.homedir(), ".ahchat", "workspaces", "_list_models");
128941
+ await import_promises9.default.mkdir(cwd, { recursive: true });
128408
128942
  const fn = queryFn ?? sdk4.query;
128409
128943
  const ic = new InputController();
128410
128944
  ic.push("Reply with exactly: PING", "");
@@ -128470,9 +129004,9 @@ init_cjs_shims();
128470
129004
  var import_node_child_process6 = require("child_process");
128471
129005
  var import_node_crypto5 = __toESM(require("crypto"), 1);
128472
129006
  var import_node_fs17 = __toESM(require("fs"), 1);
128473
- var import_promises9 = __toESM(require("fs/promises"), 1);
129007
+ var import_promises10 = __toESM(require("fs/promises"), 1);
128474
129008
  var import_node_os13 = __toESM(require("os"), 1);
128475
- var import_node_path29 = __toESM(require("path"), 1);
129009
+ var import_node_path30 = __toESM(require("path"), 1);
128476
129010
  var import_node_util3 = require("util");
128477
129011
  var execFileAsync3 = (0, import_node_util3.promisify)(import_node_child_process6.execFile);
128478
129012
  var logger39 = createModuleLogger("bridge.officeRuntimeSetup");
@@ -128532,7 +129066,7 @@ async function fetchUrl2(url2, outputPath, timeoutMs) {
128532
129066
  const res = await fetch(url2, { signal: controller.signal });
128533
129067
  if (!res.ok) return false;
128534
129068
  const bytes = Buffer.from(await res.arrayBuffer());
128535
- await import_promises9.default.writeFile(outputPath, bytes);
129069
+ await import_promises10.default.writeFile(outputPath, bytes);
128536
129070
  return true;
128537
129071
  } catch (error51) {
128538
129072
  logger39.error("OfficeCLI runtime download failed", { error: error51, url: url2 });
@@ -128554,7 +129088,7 @@ function parseChecksumManifest(raw, asset) {
128554
129088
  return null;
128555
129089
  }
128556
129090
  async function sha256(filePath) {
128557
- return import_node_crypto5.default.createHash("sha256").update(await import_promises9.default.readFile(filePath)).digest("hex");
129091
+ return import_node_crypto5.default.createHash("sha256").update(await import_promises10.default.readFile(filePath)).digest("hex");
128558
129092
  }
128559
129093
  async function runBestEffort(command, args) {
128560
129094
  try {
@@ -128582,10 +129116,10 @@ async function installManagedOfficeCliRuntime(env2) {
128582
129116
  const githubBase = `https://github.com/${REPO}/releases/download/${version4}`;
128583
129117
  const mirrorAssetBase = `${mirrorBase(env2)}/releases/download/${version4}`;
128584
129118
  const timeoutMs = readTimeoutMs(env2);
128585
- await import_promises9.default.mkdir(binDir, { recursive: true });
128586
- const tmpDir = await import_promises9.default.mkdtemp(import_node_path29.default.join(import_node_os13.default.tmpdir(), "ahchat-officecli-"));
128587
- const tmpBinary = import_node_path29.default.join(tmpDir, asset);
128588
- const tmpSums = import_node_path29.default.join(tmpDir, "SHA256SUMS");
129119
+ await import_promises10.default.mkdir(binDir, { recursive: true });
129120
+ const tmpDir = await import_promises10.default.mkdtemp(import_node_path30.default.join(import_node_os13.default.tmpdir(), "ahchat-officecli-"));
129121
+ const tmpBinary = import_node_path30.default.join(tmpDir, asset);
129122
+ const tmpSums = import_node_path30.default.join(tmpDir, "SHA256SUMS");
128589
129123
  try {
128590
129124
  const binarySource = await fetchWithFallback(
128591
129125
  `${mirrorAssetBase}/${asset}`,
@@ -128601,21 +129135,21 @@ async function installManagedOfficeCliRuntime(env2) {
128601
129135
  timeoutMs
128602
129136
  );
128603
129137
  if (!checksumSource) throw new Error(`Could not download SHA256SUMS for OfficeCLI ${version4}`);
128604
- const expected = parseChecksumManifest(await import_promises9.default.readFile(tmpSums, "utf-8"), asset);
129138
+ const expected = parseChecksumManifest(await import_promises10.default.readFile(tmpSums, "utf-8"), asset);
128605
129139
  if (!expected) throw new Error(`SHA256SUMS does not contain ${asset}`);
128606
129140
  const actual = await sha256(tmpBinary);
128607
129141
  if (expected !== actual) {
128608
129142
  throw new Error(`Checksum mismatch for ${asset}: expected ${expected}, got ${actual}`);
128609
129143
  }
128610
- const staged = import_node_path29.default.join(binDir, `${import_node_path29.default.basename(target)}.new`);
128611
- await import_promises9.default.copyFile(tmpBinary, staged);
128612
- await import_promises9.default.chmod(staged, 493);
129144
+ const staged = import_node_path30.default.join(binDir, `${import_node_path30.default.basename(target)}.new`);
129145
+ await import_promises10.default.copyFile(tmpBinary, staged);
129146
+ await import_promises10.default.chmod(staged, 493);
128613
129147
  await codesignIfNeeded(staged);
128614
- await import_promises9.default.rm(target, { force: true });
128615
- await import_promises9.default.rename(staged, target);
129148
+ await import_promises10.default.rm(target, { force: true });
129149
+ await import_promises10.default.rename(staged, target);
128616
129150
  return { path: target, asset, binarySource, checksumSource };
128617
129151
  } finally {
128618
- await import_promises9.default.rm(tmpDir, { recursive: true, force: true });
129152
+ await import_promises10.default.rm(tmpDir, { recursive: true, force: true });
128619
129153
  }
128620
129154
  }
128621
129155
  async function ensureOfficeCliRuntime(env2 = process.env) {
@@ -128654,9 +129188,9 @@ async function ensureOfficeCliRuntime(env2 = process.env) {
128654
129188
 
128655
129189
  // src/promptOptimizer.ts
128656
129190
  init_cjs_shims();
128657
- var import_promises10 = __toESM(require("fs/promises"), 1);
129191
+ var import_promises11 = __toESM(require("fs/promises"), 1);
128658
129192
  var import_node_os14 = __toESM(require("os"), 1);
128659
- var import_node_path30 = __toESM(require("path"), 1);
129193
+ var import_node_path31 = __toESM(require("path"), 1);
128660
129194
  var sdk5 = __toESM(require("@anthropic-ai/claude-agent-sdk"), 1);
128661
129195
  var logger40 = createModuleLogger("bridge.promptOptimizer");
128662
129196
  var OPTIMIZER_SYSTEM_PROMPT = `You are an expert prompt editor for ALL-CAN Agent creation.
@@ -128700,8 +129234,8 @@ async function optimizePrompt(queryFn, opts) {
128700
129234
  const prompt = opts.systemPrompt.trim();
128701
129235
  if (!prompt) throw new Error("systemPrompt is required");
128702
129236
  const t0 = Date.now();
128703
- const cwd = opts.cwd ?? import_node_path30.default.join(import_node_os14.default.homedir(), ".ahchat", "workspaces", "_prompt_optimizer");
128704
- await import_promises10.default.mkdir(cwd, { recursive: true });
129237
+ const cwd = opts.cwd ?? import_node_path31.default.join(import_node_os14.default.homedir(), ".ahchat", "workspaces", "_prompt_optimizer");
129238
+ await import_promises11.default.mkdir(cwd, { recursive: true });
128705
129239
  const fn = queryFn ?? sdk5.query;
128706
129240
  const ic = new InputController();
128707
129241
  ic.push(buildUserPrompt(opts), "");
@@ -128965,10 +129499,10 @@ function agentRuntimeConfigSnapshot(rawConfig) {
128965
129499
  };
128966
129500
  }
128967
129501
  async function syncClaudeCredentialsToNodeAccessibleDir(agentConfigDir) {
128968
- const rootClaudeDir = import_node_path31.default.join(process.env.HOME ?? "/root", ".claude");
128969
- const fs26 = await import("fs/promises");
129502
+ const rootClaudeDir = import_node_path32.default.join(process.env.HOME ?? "/root", ".claude");
129503
+ const fs27 = await import("fs/promises");
128970
129504
  try {
128971
- await fs26.access(rootClaudeDir);
129505
+ await fs27.access(rootClaudeDir);
128972
129506
  } catch (e) {
128973
129507
  logger42.info("No /root/.claude to sync", { rootClaudeDir });
128974
129508
  logger42.debug("Root Claude dir access failed", { error: e });
@@ -128976,10 +129510,10 @@ async function syncClaudeCredentialsToNodeAccessibleDir(agentConfigDir) {
128976
129510
  }
128977
129511
  const filesToSync = [".credentials.json", "settings.json", ".credentials.backup.json"];
128978
129512
  for (const file2 of filesToSync) {
128979
- const src = import_node_path31.default.join(rootClaudeDir, file2);
128980
- const dest = import_node_path31.default.join(agentConfigDir, file2);
129513
+ const src = import_node_path32.default.join(rootClaudeDir, file2);
129514
+ const dest = import_node_path32.default.join(agentConfigDir, file2);
128981
129515
  try {
128982
- await fs26.copyFile(src, dest);
129516
+ await fs27.copyFile(src, dest);
128983
129517
  logger42.info("Synced credential file", { file: file2, from: src, to: dest });
128984
129518
  } catch (e) {
128985
129519
  logger42.debug("Credential file not present, skipping", { file: file2, src });
@@ -128988,26 +129522,26 @@ async function syncClaudeCredentialsToNodeAccessibleDir(agentConfigDir) {
128988
129522
  }
128989
129523
  }
128990
129524
  async function chownRecursive(dirPath, uid, gid) {
128991
- const fs26 = await import("fs/promises");
129525
+ const fs27 = await import("fs/promises");
128992
129526
  try {
128993
- await fs26.chown(dirPath, uid, gid);
129527
+ await fs27.chown(dirPath, uid, gid);
128994
129528
  } catch (e) {
128995
129529
  logger42.debug("chown skipped", { error: e, uid, gid });
128996
129530
  }
128997
129531
  let entries;
128998
129532
  try {
128999
- entries = await fs26.readdir(dirPath, { withFileTypes: true });
129533
+ entries = await fs27.readdir(dirPath, { withFileTypes: true });
129000
129534
  } catch (e) {
129001
129535
  logger42.debug("chown directory read skipped", { error: e });
129002
129536
  return;
129003
129537
  }
129004
129538
  for (const entry of entries) {
129005
- const fullPath = import_node_path31.default.join(dirPath, entry.name);
129539
+ const fullPath = import_node_path32.default.join(dirPath, entry.name);
129006
129540
  if (entry.isDirectory()) {
129007
129541
  await chownRecursive(fullPath, uid, gid);
129008
129542
  } else {
129009
129543
  try {
129010
- await fs26.chown(fullPath, uid, gid);
129544
+ await fs27.chown(fullPath, uid, gid);
129011
129545
  } catch (e) {
129012
129546
  logger42.debug("chown skipped", { error: e, uid, gid });
129013
129547
  }
@@ -129019,7 +129553,7 @@ async function startBridge(config2) {
129019
129553
  configureBridgeLogger(config2);
129020
129554
  ensureDir(config2.dataDir);
129021
129555
  ensureDir(config2.agentConfigDir);
129022
- const workspacesDir = import_node_path31.default.join(config2.dataDir, "workspaces");
129556
+ const workspacesDir = import_node_path32.default.join(config2.dataDir, "workspaces");
129023
129557
  ensureDir(workspacesDir);
129024
129558
  process.env.CLAUDE_CONFIG_DIR = config2.agentConfigDir;
129025
129559
  installBridgeFetchAuth(config2.serverApiUrl, config2.bridgeToken);
@@ -129114,7 +129648,7 @@ Bridge token (register this machine at Settings \u2192 \u5DF2\u8FDE\u63A5\u7684\
129114
129648
  wsMetrics.start(5e3);
129115
129649
  const sessionStore = new SessionStore(config2.dataDir);
129116
129650
  const workdirOverrideStore = new LocalWorkdirOverrideStore(config2.dataDir);
129117
- const memoryRoot = import_node_path31.default.join(config2.dataDir, "agent-memory");
129651
+ const memoryRoot = import_node_path32.default.join(config2.dataDir, "agent-memory");
129118
129652
  const memoryStore = new AgentMemoryStore(memoryRoot, config2.serverApiUrl, config2.bridgeToken);
129119
129653
  logger42.info("Agent memory store initialized", { rootDir: memoryRoot });
129120
129654
  const smithNotebook = memoryStore.read(SMITH_AGENT_ID);
@@ -130170,7 +130704,7 @@ init_cjs_shims();
130170
130704
  var import_node_child_process7 = require("child_process");
130171
130705
  var import_node_fs18 = __toESM(require("fs"), 1);
130172
130706
  var import_node_os16 = __toESM(require("os"), 1);
130173
- var import_node_path32 = __toESM(require("path"), 1);
130707
+ var import_node_path33 = __toESM(require("path"), 1);
130174
130708
  var logger44 = createModuleLogger("bridge.protocol");
130175
130709
  var MACOS_PROTOCOL_APP_NAME = "ALL-CAN Bridge.app";
130176
130710
  var LEGACY_MACOS_PROTOCOL_APP_NAME = "AHChatBridge.app";
@@ -130184,10 +130718,10 @@ function desktopExecQuote(value) {
130184
130718
  return `"${value.replace(/\\/g, "\\\\").replace(/"/g, '\\"')}"`;
130185
130719
  }
130186
130720
  function getStableCliPath() {
130187
- return import_node_path32.default.join(import_node_os16.default.homedir(), ".ahchat", "bridge", "cli.cjs");
130721
+ return import_node_path33.default.join(import_node_os16.default.homedir(), ".ahchat", "bridge", "cli.cjs");
130188
130722
  }
130189
130723
  function getStableExePath() {
130190
- const bridgeDir = import_node_path32.default.join(import_node_os16.default.homedir(), ".ahchat", "bridge");
130724
+ const bridgeDir = import_node_path33.default.join(import_node_os16.default.homedir(), ".ahchat", "bridge");
130191
130725
  import_node_fs18.default.mkdirSync(bridgeDir, { recursive: true });
130192
130726
  const stablePath = getStableCliPath();
130193
130727
  import_node_fs18.default.copyFileSync(__filename, stablePath);
@@ -130195,7 +130729,7 @@ function getStableExePath() {
130195
130729
  return stablePath;
130196
130730
  }
130197
130731
  function writePosixLauncher(bridgeDir, stableExePath) {
130198
- const launchScriptPath = import_node_path32.default.join(bridgeDir, "launch-bridge.sh");
130732
+ const launchScriptPath = import_node_path33.default.join(bridgeDir, "launch-bridge.sh");
130199
130733
  const augmentedPath = buildAugmentedPath();
130200
130734
  import_node_fs18.default.writeFileSync(
130201
130735
  launchScriptPath,
@@ -130233,9 +130767,9 @@ function registerProtocolHandler() {
130233
130767
  function registerWindows() {
130234
130768
  const nodeExe = process.execPath;
130235
130769
  const stableExePath = getStableExePath();
130236
- const bridgeDir = import_node_path32.default.join(import_node_os16.default.homedir(), ".ahchat", "bridge");
130770
+ const bridgeDir = import_node_path33.default.join(import_node_os16.default.homedir(), ".ahchat", "bridge");
130237
130771
  const augmentedPath = buildAugmentedPath();
130238
- const psLauncherPath = import_node_path32.default.join(bridgeDir, "launch-bridge.ps1");
130772
+ const psLauncherPath = import_node_path33.default.join(bridgeDir, "launch-bridge.ps1");
130239
130773
  import_node_fs18.default.writeFileSync(
130240
130774
  psLauncherPath,
130241
130775
  [
@@ -130263,7 +130797,7 @@ function registerWindows() {
130263
130797
  ].join("\r\n")
130264
130798
  );
130265
130799
  const handlerValue = `powershell -ExecutionPolicy Bypass -File "${psLauncherPath}" -url "%1"`;
130266
- const psRegisterPath = import_node_path32.default.join(bridgeDir, "register-protocol.ps1");
130800
+ const psRegisterPath = import_node_path33.default.join(bridgeDir, "register-protocol.ps1");
130267
130801
  import_node_fs18.default.writeFileSync(
130268
130802
  psRegisterPath,
130269
130803
  [
@@ -130287,10 +130821,10 @@ function registerWindows() {
130287
130821
  logger44.info("Windows protocol handler registered", { psLauncherPath });
130288
130822
  }
130289
130823
  function registerMacOS() {
130290
- const appDir = import_node_path32.default.join(import_node_os16.default.homedir(), "Applications", MACOS_PROTOCOL_APP_NAME);
130291
- const legacyAppDir = import_node_path32.default.join(import_node_os16.default.homedir(), "Applications", LEGACY_MACOS_PROTOCOL_APP_NAME);
130824
+ const appDir = import_node_path33.default.join(import_node_os16.default.homedir(), "Applications", MACOS_PROTOCOL_APP_NAME);
130825
+ const legacyAppDir = import_node_path33.default.join(import_node_os16.default.homedir(), "Applications", LEGACY_MACOS_PROTOCOL_APP_NAME);
130292
130826
  const stableExePath = getStableExePath();
130293
- const bridgeDir = import_node_path32.default.join(import_node_os16.default.homedir(), ".ahchat", "bridge");
130827
+ const bridgeDir = import_node_path33.default.join(import_node_os16.default.homedir(), ".ahchat", "bridge");
130294
130828
  const launchScriptPath = writePosixLauncher(bridgeDir, stableExePath);
130295
130829
  const escapedScriptPath = launchScriptPath.replace(/\\/g, "\\\\").replace(/"/g, '\\"');
130296
130830
  const appleScript = [
@@ -130299,7 +130833,7 @@ function registerMacOS() {
130299
130833
  ` do shell script "/bin/bash " & (quoted form of launchScript) & " " & (quoted form of thisURL) & " >/tmp/ahchat-bridge.log 2>&1 &"`,
130300
130834
  `end open location`
130301
130835
  ].join("\n");
130302
- const tmpScript = import_node_path32.default.join(import_node_os16.default.tmpdir(), "AHChatBridge.applescript");
130836
+ const tmpScript = import_node_path33.default.join(import_node_os16.default.tmpdir(), "AHChatBridge.applescript");
130303
130837
  import_node_fs18.default.writeFileSync(tmpScript, appleScript);
130304
130838
  try {
130305
130839
  import_node_fs18.default.rmSync(appDir, { recursive: true, force: true });
@@ -130317,7 +130851,7 @@ function registerMacOS() {
130317
130851
  } catch {
130318
130852
  }
130319
130853
  }
130320
- const plistPath = import_node_path32.default.join(appDir, "Contents", "Info.plist");
130854
+ const plistPath = import_node_path33.default.join(appDir, "Contents", "Info.plist");
130321
130855
  const urlTypes = JSON.stringify([{ CFBundleURLName: "ALL-CAN Bridge", CFBundleURLSchemes: ["ahchat"] }]);
130322
130856
  (0, import_node_child_process7.execSync)(
130323
130857
  `/usr/bin/plutil -insert CFBundleURLTypes -json ${JSON.stringify(urlTypes)} ${JSON.stringify(plistPath)}`,
@@ -130333,7 +130867,7 @@ function registerMacOS() {
130333
130867
  }
130334
130868
  function registerLinux() {
130335
130869
  const stableExePath = getStableExePath();
130336
- const bridgeDir = import_node_path32.default.join(import_node_os16.default.homedir(), ".ahchat", "bridge");
130870
+ const bridgeDir = import_node_path33.default.join(import_node_os16.default.homedir(), ".ahchat", "bridge");
130337
130871
  const launchScriptPath = writePosixLauncher(bridgeDir, stableExePath);
130338
130872
  const desktopFile = [
130339
130873
  `[Desktop Entry]`,
@@ -130343,8 +130877,8 @@ function registerLinux() {
130343
130877
  `NoDisplay=true`,
130344
130878
  `MimeType=x-scheme-handler/ahchat;`
130345
130879
  ].join("\n");
130346
- const desktopPath = import_node_path32.default.join(import_node_os16.default.homedir(), ".local", "share", "applications", "ahchat-bridge.desktop");
130347
- import_node_fs18.default.mkdirSync(import_node_path32.default.dirname(desktopPath), { recursive: true });
130880
+ const desktopPath = import_node_path33.default.join(import_node_os16.default.homedir(), ".local", "share", "applications", "ahchat-bridge.desktop");
130881
+ import_node_fs18.default.mkdirSync(import_node_path33.default.dirname(desktopPath), { recursive: true });
130348
130882
  import_node_fs18.default.writeFileSync(desktopPath, desktopFile);
130349
130883
  try {
130350
130884
  (0, import_node_child_process7.execSync)("update-desktop-database ~/.local/share/applications/", { stdio: "pipe" });
@@ -130361,10 +130895,10 @@ function unregisterProtocolHandler() {
130361
130895
  `powershell -ExecutionPolicy Bypass -Command "Remove-Item -Path 'HKCU:\\Software\\Classes\\ahchat' -Recurse -Force -ErrorAction SilentlyContinue"`,
130362
130896
  { stdio: "pipe" }
130363
130897
  );
130364
- const bridgeDir = import_node_path32.default.join(import_node_os16.default.homedir(), ".ahchat", "bridge");
130898
+ const bridgeDir = import_node_path33.default.join(import_node_os16.default.homedir(), ".ahchat", "bridge");
130365
130899
  for (const f of ["launch-bridge.ps1", "register-protocol.ps1"]) {
130366
130900
  try {
130367
- import_node_fs18.default.unlinkSync(import_node_path32.default.join(bridgeDir, f));
130901
+ import_node_fs18.default.unlinkSync(import_node_path33.default.join(bridgeDir, f));
130368
130902
  } catch {
130369
130903
  }
130370
130904
  }
@@ -130373,8 +130907,8 @@ function unregisterProtocolHandler() {
130373
130907
  logger44.warn("Failed to unregister Windows protocol handler", { error: e });
130374
130908
  }
130375
130909
  } else if (platform === "darwin") {
130376
- const appDir = import_node_path32.default.join(import_node_os16.default.homedir(), "Applications", MACOS_PROTOCOL_APP_NAME);
130377
- const legacyAppDir = import_node_path32.default.join(import_node_os16.default.homedir(), "Applications", LEGACY_MACOS_PROTOCOL_APP_NAME);
130910
+ const appDir = import_node_path33.default.join(import_node_os16.default.homedir(), "Applications", MACOS_PROTOCOL_APP_NAME);
130911
+ const legacyAppDir = import_node_path33.default.join(import_node_os16.default.homedir(), "Applications", LEGACY_MACOS_PROTOCOL_APP_NAME);
130378
130912
  try {
130379
130913
  import_node_fs18.default.rmSync(appDir, { recursive: true, force: true });
130380
130914
  import_node_fs18.default.rmSync(legacyAppDir, { recursive: true, force: true });
@@ -130383,7 +130917,7 @@ function unregisterProtocolHandler() {
130383
130917
  logger44.warn("Failed to unregister macOS protocol handler", { error: e });
130384
130918
  }
130385
130919
  } else {
130386
- const desktopPath = import_node_path32.default.join(import_node_os16.default.homedir(), ".local", "share", "applications", "ahchat-bridge.desktop");
130920
+ const desktopPath = import_node_path33.default.join(import_node_os16.default.homedir(), ".local", "share", "applications", "ahchat-bridge.desktop");
130387
130921
  try {
130388
130922
  import_node_fs18.default.unlinkSync(desktopPath);
130389
130923
  logger44.info("Linux protocol handler unregistered");
@@ -130403,10 +130937,10 @@ function isProtocolRegistered() {
130403
130937
  return false;
130404
130938
  }
130405
130939
  } else if (platform === "darwin") {
130406
- const appDir = import_node_path32.default.join(import_node_os16.default.homedir(), "Applications", MACOS_PROTOCOL_APP_NAME);
130407
- return stableCliExists && import_node_fs18.default.existsSync(import_node_path32.default.join(appDir, "Contents", "Info.plist"));
130940
+ const appDir = import_node_path33.default.join(import_node_os16.default.homedir(), "Applications", MACOS_PROTOCOL_APP_NAME);
130941
+ return stableCliExists && import_node_fs18.default.existsSync(import_node_path33.default.join(appDir, "Contents", "Info.plist"));
130408
130942
  } else {
130409
- const desktopPath = import_node_path32.default.join(import_node_os16.default.homedir(), ".local", "share", "applications", "ahchat-bridge.desktop");
130943
+ const desktopPath = import_node_path33.default.join(import_node_os16.default.homedir(), ".local", "share", "applications", "ahchat-bridge.desktop");
130410
130944
  return stableCliExists && import_node_fs18.default.existsSync(desktopPath);
130411
130945
  }
130412
130946
  }
@@ -130415,9 +130949,9 @@ function isProtocolRegistered() {
130415
130949
  var logger45 = createModuleLogger("bridge");
130416
130950
  function readCliVersion() {
130417
130951
  const candidates = [
130418
- import_node_path33.default.resolve(__dirname, "../package.json"),
130419
- import_node_path33.default.resolve(__dirname, "../../package.json"),
130420
- import_node_path33.default.resolve(process.cwd(), "packages/bridge/package.json")
130952
+ import_node_path34.default.resolve(__dirname, "../package.json"),
130953
+ import_node_path34.default.resolve(__dirname, "../../package.json"),
130954
+ import_node_path34.default.resolve(process.cwd(), "packages/bridge/package.json")
130421
130955
  ];
130422
130956
  for (const candidate of candidates) {
130423
130957
  if (!import_node_fs19.default.existsSync(candidate)) continue;
@@ -130494,7 +131028,7 @@ function buildDoctorReport(args) {
130494
131028
  dataDir: resolveBridgeDataDir(args) ?? resolveUserPath("~/.ahchat"),
130495
131029
  server,
130496
131030
  tokenProvided: Boolean(args.token),
130497
- pathPreview: (process.env.PATH ?? "").split(import_node_path33.default.delimiter).slice(0, 12)
131031
+ pathPreview: (process.env.PATH ?? "").split(import_node_path34.default.delimiter).slice(0, 12)
130498
131032
  };
130499
131033
  }
130500
131034
  function writeDoctorText(report) {