@cortexkit/aft-pi 0.39.3 → 0.39.4

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/index.js CHANGED
@@ -12177,6 +12177,21 @@ class BridgeReplacedDuringVersionCheck extends Error {
12177
12177
  }
12178
12178
  }
12179
12179
 
12180
+ class BridgeTransportTimeoutError extends Error {
12181
+ command;
12182
+ timeoutMs;
12183
+ code = "transport_timeout";
12184
+ constructor(command, timeoutMs, message) {
12185
+ super(message);
12186
+ this.command = command;
12187
+ this.timeoutMs = timeoutMs;
12188
+ this.name = "BridgeTransportTimeoutError";
12189
+ }
12190
+ }
12191
+ function isBridgeTransportTimeout(err) {
12192
+ return err instanceof Error && err.code === "transport_timeout";
12193
+ }
12194
+
12180
12195
  class BinaryBridge {
12181
12196
  static RESTART_RESET_MS = 5 * 60 * 1000;
12182
12197
  static STDERR_TAIL_MAX = 20;
@@ -12404,7 +12419,7 @@ class BinaryBridge {
12404
12419
  } else {
12405
12420
  this.warnVia(timeoutMsg2);
12406
12421
  }
12407
- entry.reject(new Error(`${this.errorPrefix} Request "${command}" (id=${id}) timed out after ${effectiveTimeoutMs}ms`));
12422
+ entry.reject(new BridgeTransportTimeoutError(command, effectiveTimeoutMs, `${this.errorPrefix} Request "${command}" (id=${id}) timed out after ${effectiveTimeoutMs}ms`));
12408
12423
  return;
12409
12424
  }
12410
12425
  const childActiveSinceRequest = this.lastChildActivityAt > requestSentAt;
@@ -12974,13 +12989,17 @@ function joinNonEmpty(parts, separator = " · ") {
12974
12989
  function treeLine(depth, text) {
12975
12990
  return `${" ".repeat(depth)}${depth === 0 ? "" : "↳ "}${text}`;
12976
12991
  }
12992
+ function nameMatchEdgeMarker(record, theme) {
12993
+ return asString(record.resolved_by) === "name_match" ? ` ${theme.fg("warning", "~")}` : "";
12994
+ }
12977
12995
  function renderCallTreeNode(node, depth, lines, theme) {
12978
12996
  const name = asString(node.name) ?? "(unknown)";
12979
12997
  const file = shortenPath(asString(node.file) ?? "(unknown file)");
12980
12998
  const line = asNumber(node.line);
12981
12999
  const unresolved = node.resolved === false ? ` ${theme.fg("warning", "[unresolved]")}` : "";
13000
+ const nameMatch = nameMatchEdgeMarker(node, theme);
12982
13001
  const location = line !== undefined ? `[${file}:${line}]` : `[${file}]`;
12983
- lines.push(treeLine(depth, `${name} ${location}${unresolved}`));
13002
+ lines.push(treeLine(depth, `${name} ${location}${unresolved}${nameMatch}`));
12984
13003
  asRecords(node.children).forEach((child) => {
12985
13004
  renderCallTreeNode(child, depth + 1, lines, theme);
12986
13005
  });
@@ -12993,34 +13012,39 @@ function depthWarning(response, theme, depthField = "depth_limited", truncatedFi
12993
13012
  const detail = truncated > 0 ? `, ${truncated} truncated` : "";
12994
13013
  return theme.fg("warning", `(depth limited${detail})`);
12995
13014
  }
12996
- function renderTracePath(path2, index, lines) {
13015
+ function renderTracePath(path2, index, lines, theme) {
12997
13016
  lines.push(`Path ${index + 1}`);
12998
13017
  asRecords(path2.hops).forEach((hop, hopIndex) => {
12999
13018
  const symbol = asString(hop.symbol) ?? "(unknown)";
13000
13019
  const file = shortenPath(asString(hop.file) ?? "(unknown file)");
13001
13020
  const line = asNumber(hop.line);
13002
13021
  const entry = hop.is_entry_point === true ? " [entry]" : "";
13003
- lines.push(treeLine(hopIndex + 1, `${symbol}${entry} ${line !== undefined ? `[${file}:${line}]` : `[${file}]`}`));
13022
+ const nameMatch = nameMatchEdgeMarker(hop, theme);
13023
+ lines.push(treeLine(hopIndex + 1, `${symbol}${entry} ${line !== undefined ? `[${file}:${line}]` : `[${file}]`}${nameMatch}`));
13004
13024
  });
13005
13025
  }
13006
13026
  function renderCallersGroupLines(group, theme) {
13007
13027
  const file = shortenPath(asString(group.file) ?? "(unknown file)");
13008
13028
  const lines = [theme.fg("accent", file)];
13009
13029
  const callers = asRecords(group.callers);
13010
- const bySymbol = new Map;
13030
+ const bySymbolProvenance = new Map;
13011
13031
  for (const caller of callers) {
13012
13032
  const symbol = asString(caller.symbol) ?? "(unknown)";
13033
+ const provenanceKey = asString(caller.resolved_by) === "name_match" ? `${symbol}\x00name_match` : `${symbol}\x00exact`;
13013
13034
  const line = asNumber(caller.line);
13014
- const bucket = bySymbol.get(symbol) ?? [];
13035
+ const bucket = bySymbolProvenance.get(provenanceKey) ?? [];
13015
13036
  if (line !== undefined)
13016
13037
  bucket.push(line);
13017
- bySymbol.set(symbol, bucket);
13038
+ bySymbolProvenance.set(provenanceKey, bucket);
13018
13039
  }
13019
- const symbols = [...bySymbol.keys()].sort((a, b) => a.localeCompare(b));
13020
- for (const symbol of symbols) {
13021
- const lineNums = (bySymbol.get(symbol) ?? []).sort((a, b) => a - b);
13040
+ const keys = [...bySymbolProvenance.keys()].sort((a, b) => a.localeCompare(b));
13041
+ for (const key of keys) {
13042
+ const symbol = key.split("\x00")[0] ?? "(unknown)";
13043
+ const isNameMatch = key.endsWith("\x00name_match");
13044
+ const lineNums = (bySymbolProvenance.get(key) ?? []).sort((a, b) => a - b);
13022
13045
  const linePart = lineNums.length > 0 ? lineNums.map(String).join(", ") : "?";
13023
- lines.push(` ${symbol}:${linePart}`);
13046
+ const marker = isNameMatch ? ` ${theme.fg("warning", "~")}` : "";
13047
+ lines.push(` ↳ ${symbol}:${linePart}${marker}`);
13024
13048
  }
13025
13049
  return lines;
13026
13050
  }
@@ -13066,7 +13090,8 @@ function formatCallgraphSections(op, response, theme = PLAIN_CALLGRAPH_THEME) {
13066
13090
  const symbol = asString(hop.symbol) ?? "(unknown)";
13067
13091
  const file = shortenPath(asString(hop.file) ?? "(unknown file)");
13068
13092
  const line = asNumber(hop.line);
13069
- lines.push(treeLine(index + 1, `${symbol} ${line !== undefined ? `[${file}:${line}]` : `[${file}]`}`));
13093
+ const nameMatch = nameMatchEdgeMarker(hop, theme);
13094
+ lines.push(treeLine(index + 1, `${symbol} ${line !== undefined ? `[${file}:${line}]` : `[${file}]`}${nameMatch}`));
13070
13095
  });
13071
13096
  return lines;
13072
13097
  }
@@ -13086,7 +13111,7 @@ function formatCallgraphSections(op, response, theme = PLAIN_CALLGRAPH_THEME) {
13086
13111
  sections2.push(theme.fg("muted", "No entry paths found."));
13087
13112
  paths.forEach((path2, index) => {
13088
13113
  const lines = [];
13089
- renderTracePath(path2, index, lines);
13114
+ renderTracePath(path2, index, lines, theme);
13090
13115
  sections2.push(lines.join(`
13091
13116
  `));
13092
13117
  });
@@ -13111,11 +13136,12 @@ function formatCallgraphSections(op, response, theme = PLAIN_CALLGRAPH_THEME) {
13111
13136
  const symbol = asString(caller.caller_symbol) ?? "(unknown)";
13112
13137
  const line = asNumber(caller.line) ?? 0;
13113
13138
  const entry = caller.is_entry_point === true ? ` ${theme.fg("warning", "[entry]")}` : "";
13139
+ const nameMatch = nameMatchEdgeMarker(caller, theme);
13114
13140
  const expression = asString(caller.call_expression);
13115
13141
  const params = Array.isArray(caller.parameters) ? caller.parameters.map(String).join(", ") : "";
13116
13142
  sections2.push([
13117
13143
  `${theme.fg("accent", file)}:${line}`,
13118
- ` ↳ ${symbol}${entry}`,
13144
+ ` ↳ ${symbol}${entry}${nameMatch}`,
13119
13145
  expression ? ` ${theme.fg("muted", expression)}` : undefined,
13120
13146
  params ? ` ${theme.fg("muted", `params: ${params}`)}` : undefined
13121
13147
  ].filter(Boolean).join(`
@@ -13138,7 +13164,8 @@ function formatCallgraphSections(op, response, theme = PLAIN_CALLGRAPH_THEME) {
13138
13164
  const variable = asString(hop.variable) ?? "(unknown)";
13139
13165
  const line = asNumber(hop.line) ?? 0;
13140
13166
  const approximate = hop.approximate === true ? ` ${theme.fg("warning", "[approx]")}` : "";
13141
- sections.push(treeLine(index, `${variable} ${theme.fg("muted", `${asString(hop.flow_type) ?? "flow"}`)} ${symbol} [${file}:${line}]${approximate}`));
13167
+ const nameMatch = nameMatchEdgeMarker(hop, theme);
13168
+ sections.push(treeLine(index, `${variable} ${theme.fg("muted", `${asString(hop.flow_type) ?? "flow"}`)} ${symbol} [${file}:${line}]${approximate}${nameMatch}`));
13142
13169
  });
13143
13170
  return sections;
13144
13171
  }
@@ -13495,7 +13522,7 @@ function formatEditSummary(data) {
13495
13522
  if (data.created === true) {
13496
13523
  let s2 = `Created file (${counts}).`;
13497
13524
  if (data.formatted)
13498
- s2 += " Auto-formatted.";
13525
+ s2 += formatAutoFormattedSuffix(data);
13499
13526
  return s2;
13500
13527
  }
13501
13528
  let detail = counts;
@@ -13506,9 +13533,21 @@ function formatEditSummary(data) {
13506
13533
  }
13507
13534
  let s = `Edited (${detail}).`;
13508
13535
  if (data.formatted)
13509
- s += " Auto-formatted.";
13536
+ s += formatAutoFormattedSuffix(data);
13510
13537
  return s;
13511
13538
  }
13539
+ function formatAutoFormattedSuffix(data) {
13540
+ const reflowText = data.reformatted?.text;
13541
+ if (typeof reflowText === "string" && reflowText.length > 0) {
13542
+ return `
13543
+ Auto-formatted — the formatter reflowed your edit. On disk now:
13544
+ ${reflowText}`;
13545
+ }
13546
+ if (data.reformatted?.extensive === true) {
13547
+ return " Auto-formatted — extensive reflow; re-read the file before your next anchored edit.";
13548
+ }
13549
+ return " Auto-formatted.";
13550
+ }
13512
13551
  // ../aft-bridge/dist/format.js
13513
13552
  function compressionSavingsPercent(original, compressed) {
13514
13553
  if (original <= 0)
@@ -16275,7 +16314,7 @@ import {
16275
16314
  // package.json
16276
16315
  var package_default = {
16277
16316
  name: "@cortexkit/aft-pi",
16278
- version: "0.39.3",
16317
+ version: "0.39.4",
16279
16318
  type: "module",
16280
16319
  description: "Pi coding agent extension for Agent File Tools (AFT) — tree-sitter and LSP-powered code analysis",
16281
16320
  main: "dist/index.js",
@@ -16298,7 +16337,7 @@ var package_default = {
16298
16337
  "test:unit": "bun test src/__tests__ --path-ignore-patterns 'src/__tests__/e2e/**'"
16299
16338
  },
16300
16339
  dependencies: {
16301
- "@cortexkit/aft-bridge": "0.39.3",
16340
+ "@cortexkit/aft-bridge": "0.39.4",
16302
16341
  "@xterm/headless": "^5.5.0",
16303
16342
  "comment-json": "^5.0.0",
16304
16343
  diff: "^8.0.4",
@@ -16306,12 +16345,12 @@ var package_default = {
16306
16345
  zod: "^4.1.8"
16307
16346
  },
16308
16347
  optionalDependencies: {
16309
- "@cortexkit/aft-darwin-arm64": "0.39.3",
16310
- "@cortexkit/aft-darwin-x64": "0.39.3",
16311
- "@cortexkit/aft-linux-arm64": "0.39.3",
16312
- "@cortexkit/aft-linux-x64": "0.39.3",
16313
- "@cortexkit/aft-win32-arm64": "0.39.3",
16314
- "@cortexkit/aft-win32-x64": "0.39.3"
16348
+ "@cortexkit/aft-darwin-arm64": "0.39.4",
16349
+ "@cortexkit/aft-darwin-x64": "0.39.4",
16350
+ "@cortexkit/aft-linux-arm64": "0.39.4",
16351
+ "@cortexkit/aft-linux-x64": "0.39.4",
16352
+ "@cortexkit/aft-win32-arm64": "0.39.4",
16353
+ "@cortexkit/aft-win32-x64": "0.39.4"
16315
16354
  },
16316
16355
  devDependencies: {
16317
16356
  "@earendil-works/pi-coding-agent": "*",
@@ -33296,14 +33335,7 @@ function appendSkippedSearchPaths(text, missing) {
33296
33335
 
33297
33336
  ${note}` : note;
33298
33337
  }
33299
- function externalDirectoryPromptTimeoutMs() {
33300
- const raw = process.env.AFT_PI_EXTERNAL_PROMPT_TIMEOUT_MS;
33301
- if (raw === undefined)
33302
- return 30000;
33303
- const parsed = Number.parseInt(raw, 10);
33304
- return Number.isFinite(parsed) && parsed > 0 ? parsed : 30000;
33305
- }
33306
- async function assertExternalDirectoryPermission(extCtx, target, action = "modify", options = {}) {
33338
+ async function assertExternalDirectoryPermission(extCtx, target, options = {}) {
33307
33339
  if (!target)
33308
33340
  return;
33309
33341
  const expanded = expandTilde2(target);
@@ -33312,30 +33344,7 @@ async function assertExternalDirectoryPermission(extCtx, target, action = "modif
33312
33344
  return;
33313
33345
  if (options.restrictToProjectRoot === false)
33314
33346
  return;
33315
- const confirmFn = extCtx.ui?.confirm;
33316
- if (extCtx.hasUI === false || !confirmFn) {
33317
- throw new Error(`Permission denied: cannot prompt for ${action} outside the project (${absoluteTarget}).`);
33318
- }
33319
- const timeoutMs = externalDirectoryPromptTimeoutMs();
33320
- let timer;
33321
- const timeoutPromise = new Promise((resolve5) => {
33322
- timer = setTimeout(() => resolve5("timeout"), timeoutMs);
33323
- });
33324
- try {
33325
- const result = await Promise.race([
33326
- confirmFn("Allow external directory access?", `AFT wants to ${action} outside the project: ${absoluteTarget}`),
33327
- timeoutPromise
33328
- ]);
33329
- if (result === true)
33330
- return;
33331
- if (result === "timeout") {
33332
- throw new Error(`Permission denied: external directory prompt timed out after ${timeoutMs}ms.`);
33333
- }
33334
- throw new Error("Permission denied: external directory access was cancelled.");
33335
- } finally {
33336
- if (timer !== undefined)
33337
- clearTimeout(timer);
33338
- }
33347
+ throw new Error(`Blocked: '${absoluteTarget}' is outside the project root and restrict_to_project_root is ` + "enabled (AFT full isolation). Not overridable per-call; set restrict_to_project_root: false " + "in aft.jsonc to allow external paths.");
33339
33348
  }
33340
33349
  var ReadParams = Type2.Object({
33341
33350
  path: Type2.String({
@@ -33384,7 +33393,7 @@ function registerHoistedTools(pi, ctx, surface) {
33384
33393
  const offset = coerceOptionalInt(params.offset, "offset", 1, Number.MAX_SAFE_INTEGER);
33385
33394
  const limit = coerceOptionalInt(params.limit, "limit", 1, Number.MAX_SAFE_INTEGER);
33386
33395
  const filePath = await resolvePathArg(extCtx.cwd, params.path);
33387
- await assertExternalDirectoryPermission(extCtx, filePath, "read", {
33396
+ await assertExternalDirectoryPermission(extCtx, filePath, {
33388
33397
  restrictToProjectRoot: surface.restrictToProjectRoot
33389
33398
  });
33390
33399
  const req = {
@@ -33422,7 +33431,7 @@ function registerHoistedTools(pi, ctx, surface) {
33422
33431
  parameters: WriteParams,
33423
33432
  async execute(_toolCallId, params, _signal, _onUpdate, extCtx) {
33424
33433
  const filePath = await resolvePathArg(extCtx.cwd, params.filePath);
33425
- await assertExternalDirectoryPermission(extCtx, filePath, "modify", {
33434
+ await assertExternalDirectoryPermission(extCtx, filePath, {
33426
33435
  restrictToProjectRoot: surface.restrictToProjectRoot
33427
33436
  });
33428
33437
  const bridge = bridgeFor(ctx, extCtx.cwd);
@@ -33456,7 +33465,7 @@ function registerHoistedTools(pi, ctx, surface) {
33456
33465
  parameters: EditParams,
33457
33466
  async execute(_toolCallId, params, _signal, _onUpdate, extCtx) {
33458
33467
  const filePath = await resolvePathArg(extCtx.cwd, params.filePath);
33459
- await assertExternalDirectoryPermission(extCtx, filePath, "modify", {
33468
+ await assertExternalDirectoryPermission(extCtx, filePath, {
33460
33469
  restrictToProjectRoot: surface.restrictToProjectRoot
33461
33470
  });
33462
33471
  const bridge = bridgeFor(ctx, extCtx.cwd);
@@ -33509,7 +33518,7 @@ function registerHoistedTools(pi, ctx, surface) {
33509
33518
  if (params.path) {
33510
33519
  pathSplit = await splitSearchPathArg(extCtx.cwd, params.path);
33511
33520
  for (const target of pathSplit.paths) {
33512
- await assertExternalDirectoryPermission(extCtx, absoluteSearchPath(extCtx.cwd, target), "search", {
33521
+ await assertExternalDirectoryPermission(extCtx, absoluteSearchPath(extCtx.cwd, target), {
33513
33522
  restrictToProjectRoot: surface.restrictToProjectRoot
33514
33523
  });
33515
33524
  }
@@ -33930,7 +33939,7 @@ async function resolveAstPaths(extCtx, paths) {
33930
33939
  return;
33931
33940
  return Promise.all(paths.filter((path3) => typeof path3 === "string").map((path3) => resolvePathArg(extCtx.cwd, path3)));
33932
33941
  }
33933
- async function assertAstPathsPermission(extCtx, paths, action, restrictToProjectRoot) {
33942
+ async function assertAstPathsPermission(extCtx, paths, restrictToProjectRoot) {
33934
33943
  if (paths === undefined || paths.length === 0)
33935
33944
  return;
33936
33945
  const checked = new Set;
@@ -33938,7 +33947,7 @@ async function assertAstPathsPermission(extCtx, paths, action, restrictToProject
33938
33947
  if (checked.has(path3))
33939
33948
  continue;
33940
33949
  checked.add(path3);
33941
- await assertExternalDirectoryPermission(extCtx, path3, action, { restrictToProjectRoot });
33950
+ await assertExternalDirectoryPermission(extCtx, path3, { restrictToProjectRoot });
33942
33951
  }
33943
33952
  }
33944
33953
  function buildAstSearchSections(payload, theme) {
@@ -34057,7 +34066,7 @@ function registerAstTools(pi, ctx, surface) {
34057
34066
  parameters: SearchParams,
34058
34067
  async execute(_toolCallId, params, _signal, _onUpdate, extCtx) {
34059
34068
  const paths = await resolveAstPaths(extCtx, params.paths);
34060
- await assertAstPathsPermission(extCtx, paths, "search", ctx.config.restrict_to_project_root ?? false);
34069
+ await assertAstPathsPermission(extCtx, paths, ctx.config.restrict_to_project_root ?? false);
34061
34070
  const bridge = bridgeFor(ctx, extCtx.cwd);
34062
34071
  const req = {
34063
34072
  pattern: params.pattern,
@@ -34088,7 +34097,7 @@ function registerAstTools(pi, ctx, surface) {
34088
34097
  parameters: ReplaceParams,
34089
34098
  async execute(_toolCallId, params, _signal, _onUpdate, extCtx) {
34090
34099
  const paths = await resolveAstPaths(extCtx, params.paths);
34091
- await assertAstPathsPermission(extCtx, paths, params.dryRun === true ? "search" : "modify", ctx.config.restrict_to_project_root ?? false);
34100
+ await assertAstPathsPermission(extCtx, paths, ctx.config.restrict_to_project_root ?? false);
34092
34101
  const bridge = bridgeFor(ctx, extCtx.cwd);
34093
34102
  const req = {
34094
34103
  pattern: params.pattern,
@@ -34215,6 +34224,9 @@ var BashWriteParams = Type4.Object({
34215
34224
  description: "Either a string of verbatim bytes (e.g. 'print(1)\\n') OR an array mixing strings " + "and { key: '<name>' } objects for atomic text+key sequences. " + "Example: [ 'iHello', { key: 'esc' }, ':wq', { key: 'enter' } ]. " + "Allowed key names: enter, return, tab, space, backspace, esc, escape, up, down, " + "left, right, home, end, page-up, page-down, delete, insert, f1..f12, ctrl-a..ctrl-z."
34216
34225
  })
34217
34226
  });
34227
+ function unavailableSnapshot() {
34228
+ return { status: "unknown" };
34229
+ }
34218
34230
  async function callBashBridge(bridge, command, params = {}, extCtx, options) {
34219
34231
  return await callBridge(bridge, command, params, extCtx, {
34220
34232
  transportTimeoutMs: BASH_TRANSPORT_TIMEOUT_MS,
@@ -34561,9 +34573,31 @@ async function waitForBashStatus(ctx, bridge, extCtx, taskId, outputMode, waitFo
34561
34573
  if (waitForExit)
34562
34574
  markTaskWaiting(sessionId, taskId);
34563
34575
  let sawTerminal = false;
34576
+ let lastData;
34564
34577
  try {
34565
34578
  while (true) {
34566
- const data = await bashStatusSnapshot(bridge, extCtx, taskId, outputMode, bridgeOptions);
34579
+ let data;
34580
+ try {
34581
+ data = await bashStatusSnapshot(bridge, extCtx, taskId, outputMode, bridgeOptions);
34582
+ } catch (err) {
34583
+ if (!isBridgeTransportTimeout(err))
34584
+ throw err;
34585
+ if (isSyncWatchAborted(sessionId)) {
34586
+ return withWaited(lastData ?? unavailableSnapshot(), {
34587
+ reason: "user_message",
34588
+ elapsed_ms: Date.now() - startedAt
34589
+ });
34590
+ }
34591
+ if (Date.now() >= deadline) {
34592
+ return withWaited(lastData ?? unavailableSnapshot(), {
34593
+ reason: "unavailable",
34594
+ elapsed_ms: Date.now() - startedAt
34595
+ });
34596
+ }
34597
+ await sleep(Math.min(BASH_WAIT_POLL_INTERVAL_MS, Math.max(0, deadline - Date.now())));
34598
+ continue;
34599
+ }
34600
+ lastData = data;
34567
34601
  const terminal = isTerminalStatus(data.status);
34568
34602
  if (waitFor) {
34569
34603
  const scan = await readNewTaskOutput(extCtx, taskId, data, spillCursor);
@@ -34755,6 +34789,9 @@ function formatWaitSummary(waited, details) {
34755
34789
  if (waited.reason === "timeout") {
34756
34790
  return `Waited ${waited.elapsed_ms}ms; timeout reached without match.`;
34757
34791
  }
34792
+ if (waited.reason === "unavailable") {
34793
+ return `Waited ${waited.elapsed_ms}ms; the bridge stayed busy and status couldn't be read. The task may still be running — check with bash_status({ taskId }).`;
34794
+ }
34758
34795
  const exit = typeof details.exit_code === "number" ? `, exit ${details.exit_code}` : "";
34759
34796
  return `Waited ${waited.elapsed_ms}ms; task exited (${details.status}${exit}).`;
34760
34797
  }
@@ -34924,7 +34961,7 @@ function registerConflictsTool(pi, ctx) {
34924
34961
  const reqParams = {};
34925
34962
  const path3 = params?.path;
34926
34963
  if (typeof path3 === "string" && path3.trim() !== "") {
34927
- await assertExternalDirectoryPermission(extCtx, path3, "inspect", {
34964
+ await assertExternalDirectoryPermission(extCtx, path3, {
34928
34965
  restrictToProjectRoot: ctx.config.restrict_to_project_root ?? false
34929
34966
  });
34930
34967
  reqParams.path = await resolvePathArg(extCtx.cwd, path3);
@@ -35015,7 +35052,7 @@ function registerFsTools(pi, ctx, surface) {
35015
35052
  if (checked.has(file2))
35016
35053
  continue;
35017
35054
  checked.add(file2);
35018
- await assertExternalDirectoryPermission(extCtx, file2, "modify", {
35055
+ await assertExternalDirectoryPermission(extCtx, file2, {
35019
35056
  restrictToProjectRoot: ctx.config.restrict_to_project_root ?? false
35020
35057
  });
35021
35058
  }
@@ -35059,7 +35096,7 @@ function registerFsTools(pi, ctx, surface) {
35059
35096
  const destination = await resolvePathArg(extCtx.cwd, params.destination);
35060
35097
  const checked = new Set([filePath, destination]);
35061
35098
  for (const file2 of checked) {
35062
- await assertExternalDirectoryPermission(extCtx, file2, "modify", {
35099
+ await assertExternalDirectoryPermission(extCtx, file2, {
35063
35100
  restrictToProjectRoot: ctx.config.restrict_to_project_root ?? false
35064
35101
  });
35065
35102
  }
@@ -35163,7 +35200,7 @@ function registerImportTools(pi, ctx) {
35163
35200
  throw new Error(`op='${params.op}' requires 'module'`);
35164
35201
  }
35165
35202
  const filePath = await resolvePathArg(extCtx.cwd, params.filePath);
35166
- await assertExternalDirectoryPermission(extCtx, filePath, "modify", {
35203
+ await assertExternalDirectoryPermission(extCtx, filePath, {
35167
35204
  restrictToProjectRoot: ctx.config.restrict_to_project_root ?? false
35168
35205
  });
35169
35206
  const bridge = bridgeFor(ctx, extCtx.cwd);
@@ -35239,7 +35276,7 @@ async function resolveAndGateScope(extCtx, ctx, scope) {
35239
35276
  if (checked.has(target))
35240
35277
  continue;
35241
35278
  checked.add(target);
35242
- await assertExternalDirectoryPermission(extCtx, target, "read", {
35279
+ await assertExternalDirectoryPermission(extCtx, target, {
35243
35280
  restrictToProjectRoot: ctx.config.restrict_to_project_root ?? false
35244
35281
  });
35245
35282
  }
@@ -35476,7 +35513,10 @@ function registerInspectTool(pi, ctx) {
35476
35513
  runPendingTier2Categories(bridge, tier2RefreshCategories(response), extCtx);
35477
35514
  const body = response.text;
35478
35515
  if (typeof body === "string") {
35479
- const diagnostics = diagnosticsSummaryPart(asRecord3(response.summary));
35516
+ const diagnosticsSummary = diagnosticsSummaryPart(asRecord3(response.summary));
35517
+ const diagnosticsDetail = diagnosticsDetailSection(asRecord3(response.details));
35518
+ const diagnostics = [diagnosticsSummary, diagnosticsDetail].filter(Boolean).join(`
35519
+ `);
35480
35520
  const text = diagnostics ? body ? `${body}
35481
35521
 
35482
35522
  ${diagnostics}` : diagnostics : body;
@@ -35540,7 +35580,7 @@ function registerNavigateTool(pi, ctx) {
35540
35580
  pi.registerTool({
35541
35581
  name: "aft_callgraph",
35542
35582
  label: "callgraph",
35543
- description: "Answer code-relationship questions from a real call graph — instead of grep + read chains. Reach for this whenever the question is about how symbols connect. All ops require both `filePath` and `symbol`. Use `callers` for call sites (before renaming/signature changes), `impact` for blast radius (what breaks if a symbol changes), `call_tree` for what a function calls, `trace_to` for how execution reaches a symbol from entry points, `trace_to_symbol` for the shortest path from one symbol to another (requires `toSymbol`; if ambiguous, the error returns candidate files — retry with `toFile`), `trace_data` to follow a value across assignments/params.",
35583
+ description: "Answer code-relationship questions from a real call graph — instead of grep + read chains. Reach for this whenever the question is about how symbols connect. All ops require both `filePath` and `symbol`. Use `callers` for call sites (before renaming/signature changes), `impact` for blast radius (what breaks if a symbol changes), `call_tree` for what a function calls, `trace_to` for how execution reaches a symbol from entry points, `trace_to_symbol` for the shortest path from one symbol to another (requires `toSymbol`; if ambiguous, the error returns candidate files — retry with `toFile`), `trace_data` to follow a value across assignments/params. Markers: ~ = edge resolved by name only (may point at the wrong same-named symbol); [unresolved] = callee not resolved to a definition, so the location shown is the call site. Unmarked edges are resolved exactly.",
35544
35584
  parameters: navigateParamsSchema(),
35545
35585
  async execute(_toolCallId, params, _signal, _onUpdate, extCtx) {
35546
35586
  if (isEmptyParam(params.filePath)) {
@@ -35562,7 +35602,7 @@ function registerNavigateTool(pi, ctx) {
35562
35602
  if (checked.has(target))
35563
35603
  continue;
35564
35604
  checked.add(target);
35565
- await assertExternalDirectoryPermission(extCtx, target, "read", {
35605
+ await assertExternalDirectoryPermission(extCtx, target, {
35566
35606
  restrictToProjectRoot: ctx.config.restrict_to_project_root ?? false
35567
35607
  });
35568
35608
  }
@@ -35642,7 +35682,7 @@ async function assertReadPathPermissions(extCtx, ctx, paths) {
35642
35682
  if (!target || checked.has(target))
35643
35683
  continue;
35644
35684
  checked.add(target);
35645
- await assertExternalDirectoryPermission(extCtx, target, "read", {
35685
+ await assertExternalDirectoryPermission(extCtx, target, {
35646
35686
  restrictToProjectRoot: ctx.config.restrict_to_project_root ?? false
35647
35687
  });
35648
35688
  }
@@ -36137,7 +36177,7 @@ function registerRefactorTool(pi, ctx) {
36137
36177
  if (checked.has(target))
36138
36178
  continue;
36139
36179
  checked.add(target);
36140
- await assertExternalDirectoryPermission(extCtx, target, "modify", {
36180
+ await assertExternalDirectoryPermission(extCtx, target, {
36141
36181
  restrictToProjectRoot: ctx.config.restrict_to_project_root ?? false
36142
36182
  });
36143
36183
  }
@@ -36290,7 +36330,7 @@ function registerSafetyTool(pi, ctx) {
36290
36330
  previewReq.file = filePath;
36291
36331
  const preview = await callBridge(bridge, "undo_preview", previewReq, extCtx);
36292
36332
  for (const file2 of new Set(responsePaths(preview))) {
36293
- await assertExternalDirectoryPermission(extCtx, file2, "modify", {
36333
+ await assertExternalDirectoryPermission(extCtx, file2, {
36294
36334
  restrictToProjectRoot
36295
36335
  });
36296
36336
  }
@@ -36303,7 +36343,7 @@ function registerSafetyTool(pi, ctx) {
36303
36343
  if (checked.has(file2))
36304
36344
  continue;
36305
36345
  checked.add(file2);
36306
- await assertExternalDirectoryPermission(extCtx, file2, "modify", {
36346
+ await assertExternalDirectoryPermission(extCtx, file2, {
36307
36347
  restrictToProjectRoot
36308
36348
  });
36309
36349
  }
@@ -36312,7 +36352,7 @@ function registerSafetyTool(pi, ctx) {
36312
36352
  if (params.op === "restore" && params.name) {
36313
36353
  const preview = await callBridge(bridge, "checkpoint_paths", { name: params.name }, extCtx);
36314
36354
  for (const file2 of new Set(responsePaths(preview))) {
36315
- await assertExternalDirectoryPermission(extCtx, file2, "modify", {
36355
+ await assertExternalDirectoryPermission(extCtx, file2, {
36316
36356
  restrictToProjectRoot
36317
36357
  });
36318
36358
  }
@@ -1 +1 @@
1
- {"version":3,"file":"ast.d.ts","sourceRoot":"","sources":["../../src/tools/ast.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,KAAK,EACV,eAAe,EACf,YAAY,EAEZ,KAAK,EACN,MAAM,iCAAiC,CAAC;AACzC,OAAO,EAAE,KAAK,MAAM,EAAE,IAAI,EAAE,MAAM,SAAS,CAAC;AAC5C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAGjD,OAAO,EASL,KAAK,iBAAiB,EAMvB,MAAM,qBAAqB,CAAC;AAS7B,QAAA,MAAM,YAAY;;;;;;EAehB,CAAC;AAEH,QAAA,MAAM,aAAa;;;;;;;EAOjB,CAAC;AAEH,MAAM,WAAW,UAAU;IACzB,SAAS,EAAE,OAAO,CAAC;IACnB,UAAU,EAAE,OAAO,CAAC;CACrB;AA4DD,wCAAwC;AACxC,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,GAAG,MAAM,EAAE,CAqD/E;AAED,wCAAwC;AACxC,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,GAAG,MAAM,EAAE,CAmDhF;AAED,wCAAwC;AACxC,wBAAgB,aAAa,CAC3B,QAAQ,EAAE,iBAAiB,GAAG,kBAAkB,EAChD,IAAI,EAAE,MAAM,CAAC,OAAO,YAAY,CAAC,GAAG,MAAM,CAAC,OAAO,aAAa,CAAC,EAChE,KAAK,EAAE,KAAK,EACZ,OAAO,EAAE,iBAAiB,yCAa3B;AAED,wCAAwC;AACxC,wBAAgB,eAAe,CAC7B,QAAQ,EAAE,iBAAiB,GAAG,kBAAkB,EAChD,MAAM,EAAE,eAAe,CAAC,OAAO,CAAC,EAChC,KAAK,EAAE,KAAK,EACZ,OAAO,EAAE,iBAAiB,sFAiB3B;AAED,wBAAgB,gBAAgB,CAAC,EAAE,EAAE,YAAY,EAAE,GAAG,EAAE,aAAa,EAAE,OAAO,EAAE,UAAU,GAAG,IAAI,CA0FhG"}
1
+ {"version":3,"file":"ast.d.ts","sourceRoot":"","sources":["../../src/tools/ast.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,KAAK,EACV,eAAe,EACf,YAAY,EAEZ,KAAK,EACN,MAAM,iCAAiC,CAAC;AACzC,OAAO,EAAE,KAAK,MAAM,EAAE,IAAI,EAAE,MAAM,SAAS,CAAC;AAC5C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAGjD,OAAO,EASL,KAAK,iBAAiB,EAMvB,MAAM,qBAAqB,CAAC;AAS7B,QAAA,MAAM,YAAY;;;;;;EAehB,CAAC;AAEH,QAAA,MAAM,aAAa;;;;;;;EAOjB,CAAC;AAEH,MAAM,WAAW,UAAU;IACzB,SAAS,EAAE,OAAO,CAAC;IACnB,UAAU,EAAE,OAAO,CAAC;CACrB;AA2DD,wCAAwC;AACxC,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,GAAG,MAAM,EAAE,CAqD/E;AAED,wCAAwC;AACxC,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,GAAG,MAAM,EAAE,CAmDhF;AAED,wCAAwC;AACxC,wBAAgB,aAAa,CAC3B,QAAQ,EAAE,iBAAiB,GAAG,kBAAkB,EAChD,IAAI,EAAE,MAAM,CAAC,OAAO,YAAY,CAAC,GAAG,MAAM,CAAC,OAAO,aAAa,CAAC,EAChE,KAAK,EAAE,KAAK,EACZ,OAAO,EAAE,iBAAiB,yCAa3B;AAED,wCAAwC;AACxC,wBAAgB,eAAe,CAC7B,QAAQ,EAAE,iBAAiB,GAAG,kBAAkB,EAChD,MAAM,EAAE,eAAe,CAAC,OAAO,CAAC,EAChC,KAAK,EAAE,KAAK,EACZ,OAAO,EAAE,iBAAiB,sFAiB3B;AAED,wBAAgB,gBAAgB,CAAC,EAAE,EAAE,YAAY,EAAE,GAAG,EAAE,aAAa,EAAE,OAAO,EAAE,UAAU,GAAG,IAAI,CAgFhG"}
@@ -24,7 +24,7 @@ declare const BashWriteParams: Type.TObject<{
24
24
  }>]>>]>;
25
25
  }>;
26
26
  interface BashStatusWaited {
27
- reason: "matched" | "exited" | "timeout" | "user_message";
27
+ reason: "matched" | "exited" | "timeout" | "user_message" | "unavailable";
28
28
  elapsed_ms: number;
29
29
  match?: string;
30
30
  match_offset?: number;
@@ -1 +1 @@
1
- {"version":3,"file":"bash.d.ts","sourceRoot":"","sources":["../../src/tools/bash.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"bash.d.ts","sourceRoot":"","sources":["../../src/tools/bash.ts"],"names":[],"mappings":"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"}
@@ -18,13 +18,19 @@
18
18
  */
19
19
  import { type AgentToolResult, type ExtensionAPI } from "@earendil-works/pi-coding-agent";
20
20
  import type { PluginContext } from "../types.js";
21
+ /**
22
+ * Enforce AFT's `restrict_to_project_root` isolation for an out-of-root target.
23
+ *
24
+ * Pi has no host-level permission/allow-list system to bubble to. So the knob
25
+ * is binary: when `restrict_to_project_root` is false (Pi default) the path is
26
+ * allowed (Rust accepts it); when true, the path is hard-blocked with a clear,
27
+ * actionable error — never a prompt. A per-call grant could never override the
28
+ * Rust-side boundary anyway, which is exactly the issue #125 footgun this
29
+ * avoids. The thrown error surfaces as the tool result (Pi's user surface).
30
+ */
21
31
  export declare function assertExternalDirectoryPermission(extCtx: {
22
32
  cwd: string;
23
- hasUI?: boolean;
24
- ui?: {
25
- confirm?: (title: string, message: string) => Promise<boolean>;
26
- };
27
- }, target: string, action?: string, options?: {
33
+ }, target: string, options?: {
28
34
  restrictToProjectRoot?: boolean;
29
35
  }): Promise<void>;
30
36
  export interface ToolSurfaceFlags {
@@ -1 +1 @@
1
- {"version":3,"file":"hoisted.d.ts","sourceRoot":"","sources":["../../src/tools/hoisted.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AASH,OAAO,EACL,KAAK,eAAe,EACpB,KAAK,YAAY,EAGlB,MAAM,iCAAiC,CAAC;AAGzC,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAyHjD,wBAAsB,iCAAiC,CACrD,MAAM,EAAE;IACN,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,EAAE,CAAC,EAAE;QAAE,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAA;KAAE,CAAC;CACzE,EACD,MAAM,EAAE,MAAM,EACd,MAAM,SAAW,EACjB,OAAO,GAAE;IAAE,qBAAqB,CAAC,EAAE,OAAO,CAAA;CAAO,GAChD,OAAO,CAAC,IAAI,CAAC,CAkDf;AAgDD,MAAM,WAAW,gBAAgB;IAC/B,SAAS,EAAE,OAAO,CAAC;IACnB,UAAU,EAAE,OAAO,CAAC;IACpB,SAAS,EAAE,OAAO,CAAC;IACnB,SAAS,EAAE,OAAO,CAAC;IACnB;;;;;;;;;;;OAWG;IACH,qBAAqB,EAAE,OAAO,CAAC;CAChC;AAED,kEAAkE;AAClE,UAAU,mBAAmB;IAC3B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,WAAW,CAAC,EAAE,OAAO,EAAE,CAAC;IACxB;;;;;OAKG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB;;;;;OAKG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB;;;;;;;OAOG;IACH,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B;;;;;OAKG;IACH,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAED,wBAAgB,oBAAoB,CAClC,EAAE,EAAE,YAAY,EAChB,GAAG,EAAE,aAAa,EAClB,OAAO,EAAE,gBAAgB,GACxB,IAAI,CAqON;AAMD;;;;GAIG;AACH,wBAAgB,mBAAmB,CACjC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAChC,eAAe,CAAC,mBAAmB,CAAC,CA6FtC;AA8ID,+EAA+E;AAC/E,wBAAsB,cAAc,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAS/E;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,EAAE,CA0B3D;AAED;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAC9B,mBAAmB,EAAE,OAAO,EAC5B,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC5B,MAAM,CAER"}
1
+ {"version":3,"file":"hoisted.d.ts","sourceRoot":"","sources":["../../src/tools/hoisted.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AASH,OAAO,EACL,KAAK,eAAe,EACpB,KAAK,YAAY,EAGlB,MAAM,iCAAiC,CAAC;AAGzC,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAyGjD;;;;;;;;;GASG;AACH,wBAAsB,iCAAiC,CACrD,MAAM,EAAE;IAAE,GAAG,EAAE,MAAM,CAAA;CAAE,EACvB,MAAM,EAAE,MAAM,EACd,OAAO,GAAE;IAAE,qBAAqB,CAAC,EAAE,OAAO,CAAA;CAAO,GAChD,OAAO,CAAC,IAAI,CAAC,CAwBf;AAgDD,MAAM,WAAW,gBAAgB;IAC/B,SAAS,EAAE,OAAO,CAAC;IACnB,UAAU,EAAE,OAAO,CAAC;IACpB,SAAS,EAAE,OAAO,CAAC;IACnB,SAAS,EAAE,OAAO,CAAC;IACnB;;;;;;;;;;;OAWG;IACH,qBAAqB,EAAE,OAAO,CAAC;CAChC;AAED,kEAAkE;AAClE,UAAU,mBAAmB;IAC3B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,WAAW,CAAC,EAAE,OAAO,EAAE,CAAC;IACxB;;;;;OAKG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB;;;;;OAKG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB;;;;;;;OAOG;IACH,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B;;;;;OAKG;IACH,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAED,wBAAgB,oBAAoB,CAClC,EAAE,EAAE,YAAY,EAChB,GAAG,EAAE,aAAa,EAClB,OAAO,EAAE,gBAAgB,GACxB,IAAI,CAoON;AAMD;;;;GAIG;AACH,wBAAgB,mBAAmB,CACjC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAChC,eAAe,CAAC,mBAAmB,CAAC,CA6FtC;AA8ID,+EAA+E;AAC/E,wBAAsB,cAAc,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAS/E;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,EAAE,CA0B3D;AAED;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAC9B,mBAAmB,EAAE,OAAO,EAC5B,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC5B,MAAM,CAER"}
@@ -1 +1 @@
1
- {"version":3,"file":"inspect.d.ts","sourceRoot":"","sources":["../../src/tools/inspect.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EACV,eAAe,EACf,YAAY,EAEZ,KAAK,EACN,MAAM,iCAAiC,CAAC;AACzC,OAAO,EAAE,KAAK,MAAM,EAAE,IAAI,EAAE,MAAM,SAAS,CAAC;AAC5C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAGjD,OAAO,EAML,KAAK,iBAAiB,EAIvB,MAAM,qBAAqB,CAAC;AAE7B,QAAA,MAAM,aAAa;;;;EAqBjB,CAAC;AAuPH,wCAAwC;AACxC,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,GAAG,MAAM,EAAE,CA8C7E;AAED,wCAAwC;AACxC,wBAAgB,iBAAiB,CAC/B,IAAI,EAAE,MAAM,CAAC,OAAO,aAAa,CAAC,EAClC,KAAK,EAAE,KAAK,EACZ,OAAO,EAAE,iBAAiB,yCAe3B;AAED,wCAAwC;AACxC,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,eAAe,CAAC,OAAO,CAAC,EAChC,KAAK,EAAE,KAAK,EACZ,OAAO,EAAE,iBAAiB,sFAI3B;AAED,wBAAgB,mBAAmB,CAAC,EAAE,EAAE,YAAY,EAAE,GAAG,EAAE,aAAa,GAAG,IAAI,CA2C9E"}
1
+ {"version":3,"file":"inspect.d.ts","sourceRoot":"","sources":["../../src/tools/inspect.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EACV,eAAe,EACf,YAAY,EAEZ,KAAK,EACN,MAAM,iCAAiC,CAAC;AACzC,OAAO,EAAE,KAAK,MAAM,EAAE,IAAI,EAAE,MAAM,SAAS,CAAC;AAC5C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAGjD,OAAO,EAML,KAAK,iBAAiB,EAIvB,MAAM,qBAAqB,CAAC;AAE7B,QAAA,MAAM,aAAa;;;;EAqBjB,CAAC;AAuPH,wCAAwC;AACxC,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,GAAG,MAAM,EAAE,CA8C7E;AAED,wCAAwC;AACxC,wBAAgB,iBAAiB,CAC/B,IAAI,EAAE,MAAM,CAAC,OAAO,aAAa,CAAC,EAClC,KAAK,EAAE,KAAK,EACZ,OAAO,EAAE,iBAAiB,yCAe3B;AAED,wCAAwC;AACxC,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,eAAe,CAAC,OAAO,CAAC,EAChC,KAAK,EAAE,KAAK,EACZ,OAAO,EAAE,iBAAiB,sFAI3B;AAED,wBAAgB,mBAAmB,CAAC,EAAE,EAAE,YAAY,EAAE,GAAG,EAAE,aAAa,GAAG,IAAI,CAkD9E"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cortexkit/aft-pi",
3
- "version": "0.39.3",
3
+ "version": "0.39.4",
4
4
  "type": "module",
5
5
  "description": "Pi coding agent extension for Agent File Tools (AFT) — tree-sitter and LSP-powered code analysis",
6
6
  "main": "dist/index.js",
@@ -23,7 +23,7 @@
23
23
  "test:unit": "bun test src/__tests__ --path-ignore-patterns 'src/__tests__/e2e/**'"
24
24
  },
25
25
  "dependencies": {
26
- "@cortexkit/aft-bridge": "0.39.3",
26
+ "@cortexkit/aft-bridge": "0.39.4",
27
27
  "@xterm/headless": "^5.5.0",
28
28
  "comment-json": "^5.0.0",
29
29
  "diff": "^8.0.4",
@@ -31,12 +31,12 @@
31
31
  "zod": "^4.1.8"
32
32
  },
33
33
  "optionalDependencies": {
34
- "@cortexkit/aft-darwin-arm64": "0.39.3",
35
- "@cortexkit/aft-darwin-x64": "0.39.3",
36
- "@cortexkit/aft-linux-arm64": "0.39.3",
37
- "@cortexkit/aft-linux-x64": "0.39.3",
38
- "@cortexkit/aft-win32-arm64": "0.39.3",
39
- "@cortexkit/aft-win32-x64": "0.39.3"
34
+ "@cortexkit/aft-darwin-arm64": "0.39.4",
35
+ "@cortexkit/aft-darwin-x64": "0.39.4",
36
+ "@cortexkit/aft-linux-arm64": "0.39.4",
37
+ "@cortexkit/aft-linux-x64": "0.39.4",
38
+ "@cortexkit/aft-win32-arm64": "0.39.4",
39
+ "@cortexkit/aft-win32-x64": "0.39.4"
40
40
  },
41
41
  "devDependencies": {
42
42
  "@earendil-works/pi-coding-agent": "*",