@cortexkit/aft-opencode 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.d.ts.map +1 -1
- package/dist/index.js +173 -78
- package/dist/shared/ignored-message.d.ts +19 -0
- package/dist/shared/ignored-message.d.ts.map +1 -0
- package/dist/tools/ast.d.ts.map +1 -1
- package/dist/tools/bash_watch.d.ts +1 -1
- package/dist/tools/bash_watch.d.ts.map +1 -1
- package/dist/tools/navigation.d.ts.map +1 -1
- package/dist/tools/permissions.d.ts +2 -1
- package/dist/tools/permissions.d.ts.map +1 -1
- package/dist/tools/reading.d.ts.map +1 -1
- package/dist/tools/search.d.ts.map +1 -1
- package/dist/tui.js +1 -1
- package/package.json +8 -8
- package/src/shared/ignored-message.ts +61 -0
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AA0KlD;;;;;;;;;;;;;;;;GAgBG;AAQH,QAAA,MAAM,MAAM,EAAE,MAA6D,CAAC;AA63B5E,eAAe,MAAM,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -12101,6 +12101,21 @@ class BridgeReplacedDuringVersionCheck extends Error {
|
|
|
12101
12101
|
}
|
|
12102
12102
|
}
|
|
12103
12103
|
|
|
12104
|
+
class BridgeTransportTimeoutError extends Error {
|
|
12105
|
+
command;
|
|
12106
|
+
timeoutMs;
|
|
12107
|
+
code = "transport_timeout";
|
|
12108
|
+
constructor(command, timeoutMs, message) {
|
|
12109
|
+
super(message);
|
|
12110
|
+
this.command = command;
|
|
12111
|
+
this.timeoutMs = timeoutMs;
|
|
12112
|
+
this.name = "BridgeTransportTimeoutError";
|
|
12113
|
+
}
|
|
12114
|
+
}
|
|
12115
|
+
function isBridgeTransportTimeout(err) {
|
|
12116
|
+
return err instanceof Error && err.code === "transport_timeout";
|
|
12117
|
+
}
|
|
12118
|
+
|
|
12104
12119
|
class BinaryBridge {
|
|
12105
12120
|
static RESTART_RESET_MS = 5 * 60 * 1000;
|
|
12106
12121
|
static STDERR_TAIL_MAX = 20;
|
|
@@ -12328,7 +12343,7 @@ class BinaryBridge {
|
|
|
12328
12343
|
} else {
|
|
12329
12344
|
this.warnVia(timeoutMsg2);
|
|
12330
12345
|
}
|
|
12331
|
-
entry.reject(new
|
|
12346
|
+
entry.reject(new BridgeTransportTimeoutError(command, effectiveTimeoutMs, `${this.errorPrefix} Request "${command}" (id=${id}) timed out after ${effectiveTimeoutMs}ms`));
|
|
12332
12347
|
return;
|
|
12333
12348
|
}
|
|
12334
12349
|
const childActiveSinceRequest = this.lastChildActivityAt > requestSentAt;
|
|
@@ -12898,13 +12913,17 @@ function joinNonEmpty(parts, separator = " · ") {
|
|
|
12898
12913
|
function treeLine(depth, text) {
|
|
12899
12914
|
return `${" ".repeat(depth)}${depth === 0 ? "" : "↳ "}${text}`;
|
|
12900
12915
|
}
|
|
12916
|
+
function nameMatchEdgeMarker(record, theme) {
|
|
12917
|
+
return asString(record.resolved_by) === "name_match" ? ` ${theme.fg("warning", "~")}` : "";
|
|
12918
|
+
}
|
|
12901
12919
|
function renderCallTreeNode(node, depth, lines, theme) {
|
|
12902
12920
|
const name = asString(node.name) ?? "(unknown)";
|
|
12903
12921
|
const file = shortenPath(asString(node.file) ?? "(unknown file)");
|
|
12904
12922
|
const line = asNumber(node.line);
|
|
12905
12923
|
const unresolved = node.resolved === false ? ` ${theme.fg("warning", "[unresolved]")}` : "";
|
|
12924
|
+
const nameMatch = nameMatchEdgeMarker(node, theme);
|
|
12906
12925
|
const location = line !== undefined ? `[${file}:${line}]` : `[${file}]`;
|
|
12907
|
-
lines.push(treeLine(depth, `${name} ${location}${unresolved}`));
|
|
12926
|
+
lines.push(treeLine(depth, `${name} ${location}${unresolved}${nameMatch}`));
|
|
12908
12927
|
asRecords(node.children).forEach((child) => {
|
|
12909
12928
|
renderCallTreeNode(child, depth + 1, lines, theme);
|
|
12910
12929
|
});
|
|
@@ -12917,34 +12936,39 @@ function depthWarning(response, theme, depthField = "depth_limited", truncatedFi
|
|
|
12917
12936
|
const detail = truncated > 0 ? `, ${truncated} truncated` : "";
|
|
12918
12937
|
return theme.fg("warning", `(depth limited${detail})`);
|
|
12919
12938
|
}
|
|
12920
|
-
function renderTracePath(path2, index, lines) {
|
|
12939
|
+
function renderTracePath(path2, index, lines, theme) {
|
|
12921
12940
|
lines.push(`Path ${index + 1}`);
|
|
12922
12941
|
asRecords(path2.hops).forEach((hop, hopIndex) => {
|
|
12923
12942
|
const symbol = asString(hop.symbol) ?? "(unknown)";
|
|
12924
12943
|
const file = shortenPath(asString(hop.file) ?? "(unknown file)");
|
|
12925
12944
|
const line = asNumber(hop.line);
|
|
12926
12945
|
const entry = hop.is_entry_point === true ? " [entry]" : "";
|
|
12927
|
-
|
|
12946
|
+
const nameMatch = nameMatchEdgeMarker(hop, theme);
|
|
12947
|
+
lines.push(treeLine(hopIndex + 1, `${symbol}${entry} ${line !== undefined ? `[${file}:${line}]` : `[${file}]`}${nameMatch}`));
|
|
12928
12948
|
});
|
|
12929
12949
|
}
|
|
12930
12950
|
function renderCallersGroupLines(group, theme) {
|
|
12931
12951
|
const file = shortenPath(asString(group.file) ?? "(unknown file)");
|
|
12932
12952
|
const lines = [theme.fg("accent", file)];
|
|
12933
12953
|
const callers = asRecords(group.callers);
|
|
12934
|
-
const
|
|
12954
|
+
const bySymbolProvenance = new Map;
|
|
12935
12955
|
for (const caller of callers) {
|
|
12936
12956
|
const symbol = asString(caller.symbol) ?? "(unknown)";
|
|
12957
|
+
const provenanceKey = asString(caller.resolved_by) === "name_match" ? `${symbol}\x00name_match` : `${symbol}\x00exact`;
|
|
12937
12958
|
const line = asNumber(caller.line);
|
|
12938
|
-
const bucket =
|
|
12959
|
+
const bucket = bySymbolProvenance.get(provenanceKey) ?? [];
|
|
12939
12960
|
if (line !== undefined)
|
|
12940
12961
|
bucket.push(line);
|
|
12941
|
-
|
|
12962
|
+
bySymbolProvenance.set(provenanceKey, bucket);
|
|
12942
12963
|
}
|
|
12943
|
-
const
|
|
12944
|
-
for (const
|
|
12945
|
-
const
|
|
12964
|
+
const keys = [...bySymbolProvenance.keys()].sort((a, b) => a.localeCompare(b));
|
|
12965
|
+
for (const key of keys) {
|
|
12966
|
+
const symbol = key.split("\x00")[0] ?? "(unknown)";
|
|
12967
|
+
const isNameMatch = key.endsWith("\x00name_match");
|
|
12968
|
+
const lineNums = (bySymbolProvenance.get(key) ?? []).sort((a, b) => a - b);
|
|
12946
12969
|
const linePart = lineNums.length > 0 ? lineNums.map(String).join(", ") : "?";
|
|
12947
|
-
|
|
12970
|
+
const marker = isNameMatch ? ` ${theme.fg("warning", "~")}` : "";
|
|
12971
|
+
lines.push(` ↳ ${symbol}:${linePart}${marker}`);
|
|
12948
12972
|
}
|
|
12949
12973
|
return lines;
|
|
12950
12974
|
}
|
|
@@ -12990,7 +13014,8 @@ function formatCallgraphSections(op, response, theme = PLAIN_CALLGRAPH_THEME) {
|
|
|
12990
13014
|
const symbol = asString(hop.symbol) ?? "(unknown)";
|
|
12991
13015
|
const file = shortenPath(asString(hop.file) ?? "(unknown file)");
|
|
12992
13016
|
const line = asNumber(hop.line);
|
|
12993
|
-
|
|
13017
|
+
const nameMatch = nameMatchEdgeMarker(hop, theme);
|
|
13018
|
+
lines.push(treeLine(index + 1, `${symbol} ${line !== undefined ? `[${file}:${line}]` : `[${file}]`}${nameMatch}`));
|
|
12994
13019
|
});
|
|
12995
13020
|
return lines;
|
|
12996
13021
|
}
|
|
@@ -13010,7 +13035,7 @@ function formatCallgraphSections(op, response, theme = PLAIN_CALLGRAPH_THEME) {
|
|
|
13010
13035
|
sections2.push(theme.fg("muted", "No entry paths found."));
|
|
13011
13036
|
paths.forEach((path2, index) => {
|
|
13012
13037
|
const lines = [];
|
|
13013
|
-
renderTracePath(path2, index, lines);
|
|
13038
|
+
renderTracePath(path2, index, lines, theme);
|
|
13014
13039
|
sections2.push(lines.join(`
|
|
13015
13040
|
`));
|
|
13016
13041
|
});
|
|
@@ -13035,11 +13060,12 @@ function formatCallgraphSections(op, response, theme = PLAIN_CALLGRAPH_THEME) {
|
|
|
13035
13060
|
const symbol = asString(caller.caller_symbol) ?? "(unknown)";
|
|
13036
13061
|
const line = asNumber(caller.line) ?? 0;
|
|
13037
13062
|
const entry = caller.is_entry_point === true ? ` ${theme.fg("warning", "[entry]")}` : "";
|
|
13063
|
+
const nameMatch = nameMatchEdgeMarker(caller, theme);
|
|
13038
13064
|
const expression = asString(caller.call_expression);
|
|
13039
13065
|
const params = Array.isArray(caller.parameters) ? caller.parameters.map(String).join(", ") : "";
|
|
13040
13066
|
sections2.push([
|
|
13041
13067
|
`${theme.fg("accent", file)}:${line}`,
|
|
13042
|
-
` ↳ ${symbol}${entry}`,
|
|
13068
|
+
` ↳ ${symbol}${entry}${nameMatch}`,
|
|
13043
13069
|
expression ? ` ${theme.fg("muted", expression)}` : undefined,
|
|
13044
13070
|
params ? ` ${theme.fg("muted", `params: ${params}`)}` : undefined
|
|
13045
13071
|
].filter(Boolean).join(`
|
|
@@ -13062,7 +13088,8 @@ function formatCallgraphSections(op, response, theme = PLAIN_CALLGRAPH_THEME) {
|
|
|
13062
13088
|
const variable = asString(hop.variable) ?? "(unknown)";
|
|
13063
13089
|
const line = asNumber(hop.line) ?? 0;
|
|
13064
13090
|
const approximate = hop.approximate === true ? ` ${theme.fg("warning", "[approx]")}` : "";
|
|
13065
|
-
|
|
13091
|
+
const nameMatch = nameMatchEdgeMarker(hop, theme);
|
|
13092
|
+
sections.push(treeLine(index, `${variable} ${theme.fg("muted", `${asString(hop.flow_type) ?? "flow"}`)} ${symbol} [${file}:${line}]${approximate}${nameMatch}`));
|
|
13066
13093
|
});
|
|
13067
13094
|
return sections;
|
|
13068
13095
|
}
|
|
@@ -13405,7 +13432,7 @@ function formatEditSummary(data) {
|
|
|
13405
13432
|
if (data.created === true) {
|
|
13406
13433
|
let s2 = `Created file (${counts}).`;
|
|
13407
13434
|
if (data.formatted)
|
|
13408
|
-
s2 +=
|
|
13435
|
+
s2 += formatAutoFormattedSuffix(data);
|
|
13409
13436
|
return s2;
|
|
13410
13437
|
}
|
|
13411
13438
|
let detail = counts;
|
|
@@ -13416,9 +13443,21 @@ function formatEditSummary(data) {
|
|
|
13416
13443
|
}
|
|
13417
13444
|
let s = `Edited (${detail}).`;
|
|
13418
13445
|
if (data.formatted)
|
|
13419
|
-
s +=
|
|
13446
|
+
s += formatAutoFormattedSuffix(data);
|
|
13420
13447
|
return s;
|
|
13421
13448
|
}
|
|
13449
|
+
function formatAutoFormattedSuffix(data) {
|
|
13450
|
+
const reflowText = data.reformatted?.text;
|
|
13451
|
+
if (typeof reflowText === "string" && reflowText.length > 0) {
|
|
13452
|
+
return `
|
|
13453
|
+
Auto-formatted — the formatter reflowed your edit. On disk now:
|
|
13454
|
+
${reflowText}`;
|
|
13455
|
+
}
|
|
13456
|
+
if (data.reformatted?.extensive === true) {
|
|
13457
|
+
return " Auto-formatted — extensive reflow; re-read the file before your next anchored edit.";
|
|
13458
|
+
}
|
|
13459
|
+
return " Auto-formatted.";
|
|
13460
|
+
}
|
|
13422
13461
|
// ../aft-bridge/dist/jsonc.js
|
|
13423
13462
|
function stripJsoncSymbols(value) {
|
|
13424
13463
|
if (Array.isArray(value)) {
|
|
@@ -33555,6 +33594,34 @@ function normalizeToolMap(tools) {
|
|
|
33555
33594
|
}
|
|
33556
33595
|
return tools;
|
|
33557
33596
|
}
|
|
33597
|
+
// src/shared/ignored-message.ts
|
|
33598
|
+
async function sendIgnoredMessage2(client, sessionID, text) {
|
|
33599
|
+
const typedClient = client;
|
|
33600
|
+
let agent;
|
|
33601
|
+
try {
|
|
33602
|
+
const ctx = await resolvePromptContext(client, sessionID);
|
|
33603
|
+
agent = ctx?.agent;
|
|
33604
|
+
} catch {
|
|
33605
|
+
agent = undefined;
|
|
33606
|
+
}
|
|
33607
|
+
const body = {
|
|
33608
|
+
noReply: true,
|
|
33609
|
+
parts: [{ type: "text", text, ignored: true }]
|
|
33610
|
+
};
|
|
33611
|
+
if (agent)
|
|
33612
|
+
body.agent = agent;
|
|
33613
|
+
const promptInput = { path: { id: sessionID }, body };
|
|
33614
|
+
if (typeof typedClient.session?.prompt === "function") {
|
|
33615
|
+
await Promise.resolve(typedClient.session.prompt(promptInput));
|
|
33616
|
+
return;
|
|
33617
|
+
}
|
|
33618
|
+
if (typeof typedClient.session?.promptAsync === "function") {
|
|
33619
|
+
await typedClient.session.promptAsync(promptInput);
|
|
33620
|
+
return;
|
|
33621
|
+
}
|
|
33622
|
+
throw new Error("[aft-plugin] client.session.prompt is unavailable");
|
|
33623
|
+
}
|
|
33624
|
+
|
|
33558
33625
|
// src/shared/pty-cache.ts
|
|
33559
33626
|
var import_headless = __toESM(require_xterm_headless(), 1);
|
|
33560
33627
|
import * as fs2 from "node:fs/promises";
|
|
@@ -34495,6 +34562,27 @@ async function callBashBridge(ctx, runtime, command, params = {}, options) {
|
|
|
34495
34562
|
import * as fs4 from "node:fs";
|
|
34496
34563
|
import * as path4 from "node:path";
|
|
34497
34564
|
var UNSUPPORTED_ASK_HOST = "AFT requires OpenCode 1.15.5 or newer for permission asks; please upgrade OpenCode";
|
|
34565
|
+
var RESTRICT_NOTICE_THROTTLE_MS = 5 * 60 * 1000;
|
|
34566
|
+
var restrictNoticeLastSentAt = new Map;
|
|
34567
|
+
function restrictNoticeWording(target) {
|
|
34568
|
+
return `AFT blocked access to a path outside the project:
|
|
34569
|
+
${target}
|
|
34570
|
+
` + "`restrict_to_project_root` is enabled (full isolation), so AFT does not access paths " + "outside the project root. To allow external paths, set `restrict_to_project_root: false` " + "in your aft.jsonc.";
|
|
34571
|
+
}
|
|
34572
|
+
function notifyRestrictBlocked(ctx, context, target) {
|
|
34573
|
+
const sessionID = context.sessionID;
|
|
34574
|
+
if (!sessionID)
|
|
34575
|
+
return;
|
|
34576
|
+
const now = Date.now();
|
|
34577
|
+
const last = restrictNoticeLastSentAt.get(sessionID);
|
|
34578
|
+
if (last !== undefined && now - last < RESTRICT_NOTICE_THROTTLE_MS)
|
|
34579
|
+
return;
|
|
34580
|
+
restrictNoticeLastSentAt.set(sessionID, now);
|
|
34581
|
+
sendIgnoredMessage2(ctx.client, sessionID, restrictNoticeWording(target)).catch(() => {});
|
|
34582
|
+
}
|
|
34583
|
+
function restrictDenialMessage(target) {
|
|
34584
|
+
return `Blocked: '${target}' 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.";
|
|
34585
|
+
}
|
|
34498
34586
|
async function runAsk(maybe) {
|
|
34499
34587
|
await maybe;
|
|
34500
34588
|
}
|
|
@@ -34574,11 +34662,9 @@ function normalizePathPattern(p) {
|
|
|
34574
34662
|
const dir = /^[A-Za-z]:$/.test(match[1]) ? `${match[1]}\\` : match[1];
|
|
34575
34663
|
return path4.join(normalizePath(dir), match[2]);
|
|
34576
34664
|
}
|
|
34577
|
-
async function assertExternalDirectoryPermission(context, target, options) {
|
|
34665
|
+
async function assertExternalDirectoryPermission(ctx, context, target, options) {
|
|
34578
34666
|
if (!target)
|
|
34579
34667
|
return;
|
|
34580
|
-
if (typeof context.ask !== "function")
|
|
34581
|
-
return UNSUPPORTED_ASK_HOST;
|
|
34582
34668
|
const resolved = resolveAbsolutePath(context, target);
|
|
34583
34669
|
const absoluteTarget = normalizePath(resolved);
|
|
34584
34670
|
const root = projectRootFor(context);
|
|
@@ -34590,6 +34676,12 @@ async function assertExternalDirectoryPermission(context, target, options) {
|
|
|
34590
34676
|
if (worktree && worktree !== "/" && worktree !== directory && containsPath(worktree, absoluteTarget)) {
|
|
34591
34677
|
return;
|
|
34592
34678
|
}
|
|
34679
|
+
if (ctx.config.restrict_to_project_root === true) {
|
|
34680
|
+
notifyRestrictBlocked(ctx, context, absoluteTarget);
|
|
34681
|
+
return restrictDenialMessage(absoluteTarget);
|
|
34682
|
+
}
|
|
34683
|
+
if (typeof context.ask !== "function")
|
|
34684
|
+
return UNSUPPORTED_ASK_HOST;
|
|
34593
34685
|
const kind = options?.kind ?? "file";
|
|
34594
34686
|
const parentDir = kind === "directory" ? absoluteTarget : path4.dirname(absoluteTarget);
|
|
34595
34687
|
const rawGlob = process.platform === "win32" ? normalizePathPattern(path4.join(parentDir, "*")) : path4.join(parentDir, "*").replaceAll("\\", "/");
|
|
@@ -34686,12 +34778,12 @@ async function resolveAstPaths(ctx, context, paths) {
|
|
|
34686
34778
|
const resolved = await Promise.all(paths.filter((p) => typeof p === "string" && p.length > 0).map((p) => resolvePathArg(ctx, context, p)));
|
|
34687
34779
|
return resolved.length > 0 ? resolved : undefined;
|
|
34688
34780
|
}
|
|
34689
|
-
async function checkAstPathsPermission(context, paths) {
|
|
34781
|
+
async function checkAstPathsPermission(ctx, context, paths) {
|
|
34690
34782
|
if (paths === undefined)
|
|
34691
34783
|
return;
|
|
34692
34784
|
const uniquePaths = Array.from(new Set(paths));
|
|
34693
34785
|
for (const p of uniquePaths) {
|
|
34694
|
-
const denial = await assertExternalDirectoryPermission(context, p, { kind: "directory" });
|
|
34786
|
+
const denial = await assertExternalDirectoryPermission(ctx, context, p, { kind: "directory" });
|
|
34695
34787
|
if (denial)
|
|
34696
34788
|
return denial;
|
|
34697
34789
|
}
|
|
@@ -34725,7 +34817,7 @@ function astTools(ctx) {
|
|
|
34725
34817
|
},
|
|
34726
34818
|
execute: async (args, context) => {
|
|
34727
34819
|
const paths = await resolveAstPaths(ctx, context, args.paths);
|
|
34728
|
-
const externalDenied = await checkAstPathsPermission(context, paths);
|
|
34820
|
+
const externalDenied = await checkAstPathsPermission(ctx, context, paths);
|
|
34729
34821
|
if (externalDenied)
|
|
34730
34822
|
return permissionDeniedResponse(externalDenied);
|
|
34731
34823
|
const params = {
|
|
@@ -34823,13 +34915,13 @@ ${hint}`;
|
|
|
34823
34915
|
execute: async (args, context) => {
|
|
34824
34916
|
const isDryRun = args.dryRun === true;
|
|
34825
34917
|
const paths = await resolveAstPaths(ctx, context, args.paths);
|
|
34826
|
-
const externalDenied = await checkAstPathsPermission(context, paths);
|
|
34918
|
+
const externalDenied = await checkAstPathsPermission(ctx, context, paths);
|
|
34827
34919
|
if (externalDenied)
|
|
34828
34920
|
return permissionDeniedResponse(externalDenied);
|
|
34829
34921
|
if (!isDryRun) {
|
|
34830
34922
|
if (!Array.isArray(args.paths)) {
|
|
34831
34923
|
const targetPath = await resolvePathArg(ctx, context, ".");
|
|
34832
|
-
const denial = await assertExternalDirectoryPermission(context, targetPath, {
|
|
34924
|
+
const denial = await assertExternalDirectoryPermission(ctx, context, targetPath, {
|
|
34833
34925
|
kind: "directory"
|
|
34834
34926
|
});
|
|
34835
34927
|
if (denial)
|
|
@@ -35391,7 +35483,7 @@ function conflictTools(ctx) {
|
|
|
35391
35483
|
const expanded = expandTilde2(String(args.path));
|
|
35392
35484
|
const projectRoot = await resolveProjectRoot(ctx, context);
|
|
35393
35485
|
const resolved = resolvePathFromProjectRoot(projectRoot, expanded);
|
|
35394
|
-
const denied = await assertExternalDirectoryPermission(context, resolved, {
|
|
35486
|
+
const denied = await assertExternalDirectoryPermission(ctx, context, resolved, {
|
|
35395
35487
|
kind: "directory"
|
|
35396
35488
|
});
|
|
35397
35489
|
if (denied)
|
|
@@ -35719,6 +35811,9 @@ var BASH_WAIT_POLL_INTERVAL_MS = 100;
|
|
|
35719
35811
|
var DEFAULT_BASH_STATUS_WAIT_TIMEOUT_MS = 30000;
|
|
35720
35812
|
var MAX_BASH_STATUS_WAIT_TIMEOUT_MS = 30 * 60 * 1000;
|
|
35721
35813
|
var REGEX_WAIT_SCAN_WINDOW_BYTES = 64 * 1024;
|
|
35814
|
+
function unavailableSnapshot() {
|
|
35815
|
+
return { status: "unknown" };
|
|
35816
|
+
}
|
|
35722
35817
|
function createBashWatchTool(ctx) {
|
|
35723
35818
|
return {
|
|
35724
35819
|
description: "Watch a background bash task. Sync (default) blocks until a pattern matches, the task exits, or timeout — use it when the result is the next thing you need, even for long builds/tests/installs (pass timeoutMs up to 30 min for those). The user can interrupt anytime; the wait auto-converts to an async notification. Async (background:true, requires pattern) registers a non-blocking notification and returns immediately — use when you have parallel work or want to end your turn. Never loop bash_status to wait.",
|
|
@@ -35823,6 +35918,9 @@ Waited ${waited.elapsed_ms}ms; matched ${JSON.stringify(waited.match ?? "")} at
|
|
|
35823
35918
|
} else if (waited.reason === "timeout") {
|
|
35824
35919
|
text += `
|
|
35825
35920
|
Waited ${waited.elapsed_ms}ms; timeout reached without match.`;
|
|
35921
|
+
} else if (waited.reason === "unavailable") {
|
|
35922
|
+
text += `
|
|
35923
|
+
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 }).`;
|
|
35826
35924
|
} else {
|
|
35827
35925
|
const stat = String(data.status ?? "unknown");
|
|
35828
35926
|
const e = typeof data.exit_code === "number" ? `, exit ${data.exit_code}` : "";
|
|
@@ -35856,9 +35954,31 @@ async function waitForBashStatus(ctx, runtime, taskId, outputMode, waitFor, effe
|
|
|
35856
35954
|
clearSyncWatchAbort(runtime.sessionID);
|
|
35857
35955
|
markTaskWaiting(runtime.sessionID, taskId);
|
|
35858
35956
|
let sawTerminal = false;
|
|
35957
|
+
let lastData;
|
|
35859
35958
|
try {
|
|
35860
35959
|
while (true) {
|
|
35861
|
-
|
|
35960
|
+
let data;
|
|
35961
|
+
try {
|
|
35962
|
+
data = await bashStatusSnapshot2(ctx, runtime, taskId, outputMode, bridgeOptions);
|
|
35963
|
+
} catch (err) {
|
|
35964
|
+
if (!isBridgeTransportTimeout(err))
|
|
35965
|
+
throw err;
|
|
35966
|
+
if (isSyncWatchAborted(runtime.sessionID)) {
|
|
35967
|
+
return withWaited(lastData ?? unavailableSnapshot(), {
|
|
35968
|
+
reason: "user_message",
|
|
35969
|
+
elapsed_ms: Date.now() - startedAt
|
|
35970
|
+
});
|
|
35971
|
+
}
|
|
35972
|
+
if (Date.now() >= deadline) {
|
|
35973
|
+
return withWaited(lastData ?? unavailableSnapshot(), {
|
|
35974
|
+
reason: "unavailable",
|
|
35975
|
+
elapsed_ms: Date.now() - startedAt
|
|
35976
|
+
});
|
|
35977
|
+
}
|
|
35978
|
+
await sleep(Math.min(BASH_WAIT_POLL_INTERVAL_MS, Math.max(0, deadline - Date.now())));
|
|
35979
|
+
continue;
|
|
35980
|
+
}
|
|
35981
|
+
lastData = data;
|
|
35862
35982
|
const terminal = isTerminalStatus(data.status);
|
|
35863
35983
|
if (waitFor) {
|
|
35864
35984
|
const scan = await readNewTaskOutput(runtime, taskId, data, spillCursor);
|
|
@@ -36392,7 +36512,7 @@ function createReadTool(ctx) {
|
|
|
36392
36512
|
const projectRoot = await resolveProjectRoot(ctx, context);
|
|
36393
36513
|
const filePath = resolvePathFromProjectRoot(projectRoot, file2);
|
|
36394
36514
|
{
|
|
36395
|
-
const denial = await assertExternalDirectoryPermission(context, filePath);
|
|
36515
|
+
const denial = await assertExternalDirectoryPermission(ctx, context, filePath);
|
|
36396
36516
|
if (denial)
|
|
36397
36517
|
return permissionDeniedResponse(denial);
|
|
36398
36518
|
}
|
|
@@ -36503,7 +36623,7 @@ function createWriteTool(ctx, editToolName = "edit") {
|
|
|
36503
36623
|
const filePath = resolvePathFromProjectRoot(projectRoot, file2);
|
|
36504
36624
|
const relPath = path5.relative(projectRoot, filePath);
|
|
36505
36625
|
{
|
|
36506
|
-
const denial2 = await assertExternalDirectoryPermission(context, filePath);
|
|
36626
|
+
const denial2 = await assertExternalDirectoryPermission(ctx, context, filePath);
|
|
36507
36627
|
if (denial2)
|
|
36508
36628
|
return permissionDeniedResponse(denial2);
|
|
36509
36629
|
}
|
|
@@ -36654,7 +36774,7 @@ function createEditTool(ctx, writeToolName = "write") {
|
|
|
36654
36774
|
const filePath = resolvePathFromProjectRoot(projectRoot, file2);
|
|
36655
36775
|
const relPath = path5.relative(projectRoot, filePath);
|
|
36656
36776
|
{
|
|
36657
|
-
const denial2 = await assertExternalDirectoryPermission(context, filePath);
|
|
36777
|
+
const denial2 = await assertExternalDirectoryPermission(ctx, context, filePath);
|
|
36658
36778
|
if (denial2)
|
|
36659
36779
|
return permissionDeniedResponse(denial2);
|
|
36660
36780
|
}
|
|
@@ -36890,7 +37010,7 @@ function createApplyPatchTool(ctx) {
|
|
|
36890
37010
|
if (asked.has(filePath))
|
|
36891
37011
|
continue;
|
|
36892
37012
|
asked.add(filePath);
|
|
36893
|
-
const denial2 = await assertExternalDirectoryPermission(context, filePath);
|
|
37013
|
+
const denial2 = await assertExternalDirectoryPermission(ctx, context, filePath);
|
|
36894
37014
|
if (denial2)
|
|
36895
37015
|
return permissionDeniedResponse(denial2);
|
|
36896
37016
|
}
|
|
@@ -37201,7 +37321,7 @@ function createDeleteTool(ctx) {
|
|
|
37201
37321
|
if (asked.has(filePath))
|
|
37202
37322
|
continue;
|
|
37203
37323
|
asked.add(filePath);
|
|
37204
|
-
const denial = await assertExternalDirectoryPermission(context, filePath);
|
|
37324
|
+
const denial = await assertExternalDirectoryPermission(ctx, context, filePath);
|
|
37205
37325
|
if (denial)
|
|
37206
37326
|
return permissionDeniedResponse(denial);
|
|
37207
37327
|
}
|
|
@@ -37249,13 +37369,13 @@ function createMoveTool(ctx) {
|
|
|
37249
37369
|
const filePath = resolvePathFromProjectRoot(projectRoot, args.filePath);
|
|
37250
37370
|
const destPath = resolvePathFromProjectRoot(projectRoot, args.destination);
|
|
37251
37371
|
{
|
|
37252
|
-
const sourceDenial = await assertExternalDirectoryPermission(context, filePath, {
|
|
37372
|
+
const sourceDenial = await assertExternalDirectoryPermission(ctx, context, filePath, {
|
|
37253
37373
|
kind: "file"
|
|
37254
37374
|
});
|
|
37255
37375
|
if (sourceDenial)
|
|
37256
37376
|
return permissionDeniedResponse(sourceDenial);
|
|
37257
37377
|
if (destPath !== filePath) {
|
|
37258
|
-
const destDenial = await assertExternalDirectoryPermission(context, destPath);
|
|
37378
|
+
const destDenial = await assertExternalDirectoryPermission(ctx, context, destPath);
|
|
37259
37379
|
if (destDenial)
|
|
37260
37380
|
return permissionDeniedResponse(destDenial);
|
|
37261
37381
|
}
|
|
@@ -37317,7 +37437,7 @@ function aftPrefixedTools(ctx) {
|
|
|
37317
37437
|
const filePath = resolvePathFromProjectRoot(projectRoot, file2);
|
|
37318
37438
|
const relPath = path5.relative(projectRoot, filePath);
|
|
37319
37439
|
{
|
|
37320
|
-
const denial2 = await assertExternalDirectoryPermission(context, filePath);
|
|
37440
|
+
const denial2 = await assertExternalDirectoryPermission(ctx, context, filePath);
|
|
37321
37441
|
if (denial2)
|
|
37322
37442
|
return permissionDeniedResponse(denial2);
|
|
37323
37443
|
}
|
|
@@ -37394,7 +37514,7 @@ function importTools(ctx) {
|
|
|
37394
37514
|
}
|
|
37395
37515
|
const filePath = await resolvePathArg(ctx, context, args.filePath);
|
|
37396
37516
|
{
|
|
37397
|
-
const denial = await assertExternalDirectoryPermission(context, filePath);
|
|
37517
|
+
const denial = await assertExternalDirectoryPermission(ctx, context, filePath);
|
|
37398
37518
|
if (denial)
|
|
37399
37519
|
return permissionDeniedResponse(denial);
|
|
37400
37520
|
}
|
|
@@ -37544,7 +37664,7 @@ async function resolveAndGateScope(ctx, context, scope) {
|
|
|
37544
37664
|
if (checked.has(target))
|
|
37545
37665
|
continue;
|
|
37546
37666
|
checked.add(target);
|
|
37547
|
-
const denial = await assertExternalDirectoryPermission(context, target);
|
|
37667
|
+
const denial = await assertExternalDirectoryPermission(ctx, context, target);
|
|
37548
37668
|
if (denial)
|
|
37549
37669
|
return { scope: undefined, denial };
|
|
37550
37670
|
}
|
|
@@ -37641,6 +37761,7 @@ function navigationTools(ctx) {
|
|
|
37641
37761
|
|
|
37642
37762
|
` + `All ops require both 'filePath' and 'symbol'. 'expression' is additionally required for trace_data; 'toSymbol' for trace_to_symbol.
|
|
37643
37763
|
|
|
37764
|
+
` + `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.
|
|
37644
37765
|
`,
|
|
37645
37766
|
args: {
|
|
37646
37767
|
op: z11.enum(["call_tree", "callers", "trace_to", "trace_to_symbol", "impact", "trace_data"]).describe("Navigation operation"),
|
|
@@ -37671,7 +37792,7 @@ function navigationTools(ctx) {
|
|
|
37671
37792
|
if (checked.has(target))
|
|
37672
37793
|
continue;
|
|
37673
37794
|
checked.add(target);
|
|
37674
|
-
const denial = await assertExternalDirectoryPermission(context, target);
|
|
37795
|
+
const denial = await assertExternalDirectoryPermission(ctx, context, target);
|
|
37675
37796
|
if (denial)
|
|
37676
37797
|
return permissionDeniedResponse(denial);
|
|
37677
37798
|
}
|
|
@@ -37748,7 +37869,7 @@ function readingTools(ctx) {
|
|
|
37748
37869
|
throw new Error("'target' must be a non-empty string or array of strings");
|
|
37749
37870
|
}
|
|
37750
37871
|
const resolvedTargets = await Promise.all(target.map((entry) => resolvePathArg(ctx, context, entry)));
|
|
37751
|
-
const permissionDenied3 = await assertPathExternalPermissions(context, resolvedTargets, "directory");
|
|
37872
|
+
const permissionDenied3 = await assertPathExternalPermissions(ctx, context, resolvedTargets, "directory");
|
|
37752
37873
|
if (permissionDenied3)
|
|
37753
37874
|
return permissionDeniedResponse(permissionDenied3);
|
|
37754
37875
|
const response3 = await callBridge(ctx, context, "outline", {
|
|
@@ -37770,7 +37891,7 @@ function readingTools(ctx) {
|
|
|
37770
37891
|
const st = await stat(resolvedPath);
|
|
37771
37892
|
isDirectory2 = st.isDirectory();
|
|
37772
37893
|
} catch {}
|
|
37773
|
-
const permissionDenied2 = await assertPathExternalPermissions(context, resolvedPath, isDirectory2 ? "directory" : "file");
|
|
37894
|
+
const permissionDenied2 = await assertPathExternalPermissions(ctx, context, resolvedPath, isDirectory2 ? "directory" : "file");
|
|
37774
37895
|
if (permissionDenied2)
|
|
37775
37896
|
return permissionDeniedResponse(permissionDenied2);
|
|
37776
37897
|
const params = isDirectory2 ? { directory: resolvedPath, files: true } : { file: resolvedPath, files: true };
|
|
@@ -37789,7 +37910,7 @@ function readingTools(ctx) {
|
|
|
37789
37910
|
}
|
|
37790
37911
|
if (isArray) {
|
|
37791
37912
|
const resolvedTargets = await Promise.all(target.map((entry) => resolvePathArg(ctx, context, entry)));
|
|
37792
|
-
const permissionDenied2 = await assertPathExternalPermissions(context, resolvedTargets);
|
|
37913
|
+
const permissionDenied2 = await assertPathExternalPermissions(ctx, context, resolvedTargets);
|
|
37793
37914
|
if (permissionDenied2)
|
|
37794
37915
|
return permissionDeniedResponse(permissionDenied2);
|
|
37795
37916
|
const response2 = await callBridge(ctx, context, "outline", {
|
|
@@ -37810,7 +37931,7 @@ function readingTools(ctx) {
|
|
|
37810
37931
|
const st = await stat(resolvedTarget);
|
|
37811
37932
|
isDirectory = st.isDirectory();
|
|
37812
37933
|
} catch {}
|
|
37813
|
-
const permissionDenied = await assertPathExternalPermissions(context, resolvedTarget, isDirectory ? "directory" : "file");
|
|
37934
|
+
const permissionDenied = await assertPathExternalPermissions(ctx, context, resolvedTarget, isDirectory ? "directory" : "file");
|
|
37814
37935
|
if (permissionDenied)
|
|
37815
37936
|
return permissionDeniedResponse(permissionDenied);
|
|
37816
37937
|
if (isDirectory) {
|
|
@@ -37905,7 +38026,7 @@ function readingTools(ctx) {
|
|
|
37905
38026
|
}
|
|
37906
38027
|
}
|
|
37907
38028
|
const resolvedTargets = await Promise.all(targets.map((t) => resolvePathArg(ctx, context, t.filePath)));
|
|
37908
|
-
const permissionDenied = await assertPathExternalPermissions(context, resolvedTargets);
|
|
38029
|
+
const permissionDenied = await assertPathExternalPermissions(ctx, context, resolvedTargets);
|
|
37909
38030
|
if (permissionDenied)
|
|
37910
38031
|
return permissionDeniedResponse(permissionDenied);
|
|
37911
38032
|
const responses = await Promise.all(targets.map((t, index) => {
|
|
@@ -37937,7 +38058,7 @@ function readingTools(ctx) {
|
|
|
37937
38058
|
}
|
|
37938
38059
|
const file2 = hasUrl ? args.url : await resolvePathArg(ctx, context, args.filePath);
|
|
37939
38060
|
if (!hasUrl) {
|
|
37940
|
-
const permissionDenied = await assertPathExternalPermissions(context, file2);
|
|
38061
|
+
const permissionDenied = await assertPathExternalPermissions(ctx, context, file2);
|
|
37941
38062
|
if (permissionDenied)
|
|
37942
38063
|
return permissionDeniedResponse(permissionDenied);
|
|
37943
38064
|
}
|
|
@@ -38009,7 +38130,7 @@ function formatZoomBatchResult(targetLabel, symbols, responses) {
|
|
|
38009
38130
|
`) };
|
|
38010
38131
|
}
|
|
38011
38132
|
var MAX_UNCHECKED_FILES_IN_FOOTER = 10;
|
|
38012
|
-
async function assertPathExternalPermissions(context, target, kind = "file") {
|
|
38133
|
+
async function assertPathExternalPermissions(ctx, context, target, kind = "file") {
|
|
38013
38134
|
const targets = Array.isArray(target) ? target : [target];
|
|
38014
38135
|
const checked = new Set;
|
|
38015
38136
|
for (const resolvedPath of targets) {
|
|
@@ -38019,7 +38140,7 @@ async function assertPathExternalPermissions(context, target, kind = "file") {
|
|
|
38019
38140
|
if (checked.has(key))
|
|
38020
38141
|
continue;
|
|
38021
38142
|
checked.add(key);
|
|
38022
|
-
const denial = await assertExternalDirectoryPermission(context, resolvedPath, { kind });
|
|
38143
|
+
const denial = await assertExternalDirectoryPermission(ctx, context, resolvedPath, { kind });
|
|
38023
38144
|
if (denial)
|
|
38024
38145
|
return denial;
|
|
38025
38146
|
}
|
|
@@ -38185,7 +38306,7 @@ function refactoringTools(ctx) {
|
|
|
38185
38306
|
if (asked.has(affectedPath))
|
|
38186
38307
|
continue;
|
|
38187
38308
|
asked.add(affectedPath);
|
|
38188
|
-
const denial = await assertExternalDirectoryPermission(context, affectedPath);
|
|
38309
|
+
const denial = await assertExternalDirectoryPermission(ctx, context, affectedPath);
|
|
38189
38310
|
if (denial)
|
|
38190
38311
|
return permissionDeniedResponse(denial);
|
|
38191
38312
|
}
|
|
@@ -38293,7 +38414,7 @@ function safetyTools(ctx) {
|
|
|
38293
38414
|
}
|
|
38294
38415
|
const previewPaths = Array.from(new Set(responsePaths(preview2)));
|
|
38295
38416
|
for (const filePath2 of previewPaths) {
|
|
38296
|
-
const denial = await assertExternalDirectoryPermission(context, filePath2);
|
|
38417
|
+
const denial = await assertExternalDirectoryPermission(ctx, context, filePath2);
|
|
38297
38418
|
if (denial)
|
|
38298
38419
|
return permissionDeniedResponse(denial);
|
|
38299
38420
|
}
|
|
@@ -38317,7 +38438,7 @@ function safetyTools(ctx) {
|
|
|
38317
38438
|
if (uniqueParents.has(parent))
|
|
38318
38439
|
continue;
|
|
38319
38440
|
uniqueParents.add(parent);
|
|
38320
|
-
const denial = await assertExternalDirectoryPermission(context, abs, {
|
|
38441
|
+
const denial = await assertExternalDirectoryPermission(ctx, context, abs, {
|
|
38321
38442
|
kind: "file"
|
|
38322
38443
|
});
|
|
38323
38444
|
if (denial)
|
|
@@ -38331,7 +38452,7 @@ function safetyTools(ctx) {
|
|
|
38331
38452
|
throw new Error(bridgeErrorMessage(preview2, "checkpoint path preview failed"));
|
|
38332
38453
|
}
|
|
38333
38454
|
for (const filePath of new Set(responsePaths(preview2))) {
|
|
38334
|
-
const denial = await assertExternalDirectoryPermission(context, filePath);
|
|
38455
|
+
const denial = await assertExternalDirectoryPermission(ctx, context, filePath);
|
|
38335
38456
|
if (denial)
|
|
38336
38457
|
return permissionDeniedResponse(denial);
|
|
38337
38458
|
}
|
|
@@ -38526,7 +38647,7 @@ function searchTools(ctx) {
|
|
|
38526
38647
|
return permissionDeniedResponse(grepDenied);
|
|
38527
38648
|
if (pathSplit) {
|
|
38528
38649
|
for (const target of searchPathTargets(projectRoot, pathSplit, "file")) {
|
|
38529
|
-
const externalDenied = await assertExternalDirectoryPermission(context, target.target, {
|
|
38650
|
+
const externalDenied = await assertExternalDirectoryPermission(ctx, context, target.target, {
|
|
38530
38651
|
kind: target.kind
|
|
38531
38652
|
});
|
|
38532
38653
|
if (externalDenied)
|
|
@@ -38579,7 +38700,7 @@ function searchTools(ctx) {
|
|
|
38579
38700
|
return permissionDeniedResponse(globDenied);
|
|
38580
38701
|
if (pathSplit) {
|
|
38581
38702
|
for (const target of searchPathTargets(projectRoot, pathSplit, "directory")) {
|
|
38582
|
-
const externalDenied = await assertExternalDirectoryPermission(context, target.target, {
|
|
38703
|
+
const externalDenied = await assertExternalDirectoryPermission(ctx, context, target.target, {
|
|
38583
38704
|
kind: target.kind
|
|
38584
38705
|
});
|
|
38585
38706
|
if (externalDenied)
|
|
@@ -38787,32 +38908,6 @@ function isTuiMode2() {
|
|
|
38787
38908
|
function throwSentinel(command) {
|
|
38788
38909
|
throw new Error(`${SENTINEL_PREFIX}${command.toUpperCase().replace(/-/g, "_")}_HANDLED__`);
|
|
38789
38910
|
}
|
|
38790
|
-
async function sendIgnoredMessage2(client, sessionID, text) {
|
|
38791
|
-
const typedClient = client;
|
|
38792
|
-
let agent;
|
|
38793
|
-
try {
|
|
38794
|
-
const ctx = await resolvePromptContext(client, sessionID);
|
|
38795
|
-
agent = ctx?.agent;
|
|
38796
|
-
} catch {
|
|
38797
|
-
agent = undefined;
|
|
38798
|
-
}
|
|
38799
|
-
const body = {
|
|
38800
|
-
noReply: true,
|
|
38801
|
-
parts: [{ type: "text", text, ignored: true }]
|
|
38802
|
-
};
|
|
38803
|
-
if (agent)
|
|
38804
|
-
body.agent = agent;
|
|
38805
|
-
const promptInput = { path: { id: sessionID }, body };
|
|
38806
|
-
if (typeof typedClient.session?.prompt === "function") {
|
|
38807
|
-
await Promise.resolve(typedClient.session.prompt(promptInput));
|
|
38808
|
-
return;
|
|
38809
|
-
}
|
|
38810
|
-
if (typeof typedClient.session?.promptAsync === "function") {
|
|
38811
|
-
await typedClient.session.promptAsync(promptInput);
|
|
38812
|
-
return;
|
|
38813
|
-
}
|
|
38814
|
-
throw new Error("[aft-plugin] client.session.prompt is unavailable");
|
|
38815
|
-
}
|
|
38816
38911
|
var PLUGIN_VERSION = (() => {
|
|
38817
38912
|
try {
|
|
38818
38913
|
const req = createRequire3(import.meta.url);
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Append an `ignored: true` synthetic user message to a session.
|
|
3
|
+
*
|
|
4
|
+
* Used for user-facing informational panels that must NOT trigger an agent
|
|
5
|
+
* turn (e.g. status output, the external-directory restriction notice). The
|
|
6
|
+
* message renders under the current agent (resolved from recent messages) so
|
|
7
|
+
* it shows in the right place in the OpenCode UI, and carries `noReply: true`
|
|
8
|
+
* so no LLM call is made.
|
|
9
|
+
*
|
|
10
|
+
* IMPORTANT (cache + crash safety): this path deliberately passes ONLY `agent`
|
|
11
|
+
* (never model/variant). OpenCode crashes if model/variant are supplied on a
|
|
12
|
+
* `noReply: true` prompt, and omitting them keeps the synthetic message from
|
|
13
|
+
* busting the provider prefix cache the previous assistant turn warmed.
|
|
14
|
+
*
|
|
15
|
+
* Lives in `shared/` (not `index.ts`) because `index.ts` must export only the
|
|
16
|
+
* plugin default; both the plugin entry and `tools/permissions.ts` call this.
|
|
17
|
+
*/
|
|
18
|
+
export declare function sendIgnoredMessage(client: unknown, sessionID: string, text: string): Promise<void>;
|
|
19
|
+
//# sourceMappingURL=ignored-message.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ignored-message.d.ts","sourceRoot":"","sources":["../../src/shared/ignored-message.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAsB,kBAAkB,CACtC,MAAM,EAAE,OAAO,EACf,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE,MAAM,GACX,OAAO,CAAC,IAAI,CAAC,CAqCf"}
|
package/dist/tools/ast.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ast.d.ts","sourceRoot":"","sources":["../../src/tools/ast.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAMH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAC1D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"ast.d.ts","sourceRoot":"","sources":["../../src/tools/ast.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAMH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAC1D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAoFjD,wBAAgB,QAAQ,CAAC,GAAG,EAAE,aAAa,GAAG,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CA8S3E"}
|
|
@@ -8,7 +8,7 @@ export type BashWaitPattern = {
|
|
|
8
8
|
source: string;
|
|
9
9
|
};
|
|
10
10
|
export type BashStatusWaited = {
|
|
11
|
-
reason: "matched" | "exited" | "timeout" | "user_message";
|
|
11
|
+
reason: "matched" | "exited" | "timeout" | "user_message" | "unavailable";
|
|
12
12
|
elapsed_ms: number;
|
|
13
13
|
match?: string;
|
|
14
14
|
match_offset?: number;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bash_watch.d.ts","sourceRoot":"","sources":["../../src/tools/bash_watch.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"bash_watch.d.ts","sourceRoot":"","sources":["../../src/tools/bash_watch.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAcvE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AASjD,MAAM,MAAM,eAAe,GACvB;IAAE,IAAI,EAAE,WAAW,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GACpC;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AACtC,MAAM,MAAM,gBAAgB,GAAG;IAC7B,MAAM,EAAE,SAAS,GAAG,QAAQ,GAAG,SAAS,GAAG,cAAc,GAAG,aAAa,CAAC;IAC1E,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB,CAAC;AAUF,KAAK,kBAAkB,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG;IAAE,MAAM,CAAC,EAAE,gBAAgB,CAAA;CAAE,CAAC;AAGlF,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,aAAa,GAAG,cAAc,CAwGtE;AAgHD,wBAAsB,iBAAiB,CACrC,GAAG,EAAE,aAAa,EAClB,OAAO,EAAE,WAAW,EACpB,MAAM,EAAE,MAAM,EACd,UAAU,EAAE,MAAM,GAAG,SAAS,EAC9B,OAAO,EAAE,eAAe,GAAG,SAAS,EACpC,eAAe,EAAE,MAAM,GACtB,OAAO,CAAC,kBAAkB,CAAC,CA0G7B;AA6DD,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,OAAO,GAAG,eAAe,GAAG,SAAS,CAI5E;AAkGD,wBAAgB,4BAA4B,CAC1C,IAAI,EAAE,MAAM,EACZ,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,eAAe,GACvB;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,CAEtC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"navigation.d.ts","sourceRoot":"","sources":["../../src/tools/navigation.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAE1D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAqBjD;;GAEG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,aAAa,GAAG,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,
|
|
1
|
+
{"version":3,"file":"navigation.d.ts","sourceRoot":"","sources":["../../src/tools/navigation.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAE1D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAqBjD;;GAEG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,aAAa,GAAG,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAmGlF"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { ToolContext } from "@opencode-ai/plugin";
|
|
2
|
+
import type { PluginContext } from "../types.js";
|
|
2
3
|
/**
|
|
3
4
|
* Execute a `ctx.ask(...)` result.
|
|
4
5
|
*
|
|
@@ -61,7 +62,7 @@ export declare const _permissionsInternalsForTest: {
|
|
|
61
62
|
* external-directory rule is `allow` (e.g. for `${os.tmpdir()}/opencode/*`), the
|
|
62
63
|
* call short-circuits and the regular permission flow continues normally.
|
|
63
64
|
*/
|
|
64
|
-
export declare function assertExternalDirectoryPermission(context: ToolContext, target: string, options?: {
|
|
65
|
+
export declare function assertExternalDirectoryPermission(ctx: PluginContext, context: ToolContext, target: string, options?: {
|
|
65
66
|
kind?: "file" | "directory";
|
|
66
67
|
}): Promise<string | undefined>;
|
|
67
68
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"permissions.d.ts","sourceRoot":"","sources":["../../src/tools/permissions.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"permissions.d.ts","sourceRoot":"","sources":["../../src/tools/permissions.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAEvD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAoDjD;;;;;;;;;;;GAWG;AACH,wBAAsB,MAAM,CAAC,KAAK,EAAE,OAAO,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAEhE;AAED,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAEhF;AAED,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAEnF;AAED,wBAAgB,kCAAkC,CAChD,OAAO,EAAE,WAAW,EACpB,YAAY,EAAE,MAAM,GACnB,MAAM,CAER;AAED,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE,CAazF;AAED,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,WAAW,GAAG,MAAM,CAE9D;AAED,wBAAsB,iBAAiB,CACrC,OAAO,EAAE,WAAW,EACpB,QAAQ,EAAE,MAAM,EAAE,EAClB,QAAQ,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,GACrC,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAkB7B;AAED;;;GAGG;AACH,iBAAS,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAI5D;AA6CD;;;;;;;;;;;;GAYG;AACH,iBAAS,oBAAoB,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAO/C;AAED,eAAO,MAAM,4BAA4B;;;CAAyC,CAAC;AAEnF;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAsB,iCAAiC,CACrD,GAAG,EAAE,aAAa,EAClB,OAAO,EAAE,WAAW,EACpB,MAAM,EAAE,MAAM,EACd,OAAO,CAAC,EAAE;IAAE,IAAI,CAAC,EAAE,MAAM,GAAG,WAAW,CAAA;CAAE,GACxC,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAmE7B;AAED;;;;;;;GAOG;AACH,wBAAsB,iBAAiB,CACrC,OAAO,EAAE,WAAW,EACpB,OAAO,EAAE,MAAM,EACf,QAAQ,GAAE;IAAE,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAA;CAAO,GACjD,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAkB7B;AAED;;;;;;GAMG;AACH,wBAAsB,iBAAiB,CACrC,OAAO,EAAE,WAAW,EACpB,OAAO,EAAE,MAAM,EACf,QAAQ,GAAE;IAAE,IAAI,CAAC,EAAE,MAAM,CAAA;CAAO,GAC/B,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAkB7B;AAED,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAOhE"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"reading.d.ts","sourceRoot":"","sources":["../../src/tools/reading.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAe,cAAc,EAAc,MAAM,qBAAqB,CAAC;AAEnF,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAoCjD,UAAU,qBAAqB;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,UAAU,eAAe;IACvB,QAAQ,EAAE,OAAO,CAAC;IAClB,OAAO,EAAE,qBAAqB,EAAE,CAAC;IACjC,IAAI,EAAE,MAAM,CAAC;CACd;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,aAAa,GAAG,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,
|
|
1
|
+
{"version":3,"file":"reading.d.ts","sourceRoot":"","sources":["../../src/tools/reading.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAe,cAAc,EAAc,MAAM,qBAAqB,CAAC;AAEnF,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAoCjD,UAAU,qBAAqB;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,UAAU,eAAe;IACvB,QAAQ,EAAE,OAAO,CAAC;IAClB,OAAO,EAAE,qBAAqB,EAAE,CAAC;IACjC,IAAI,EAAE,MAAM,CAAC;CACd;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,aAAa,GAAG,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAyY/E;AAED;;;;;;GAMG;AACH,wBAAgB,qBAAqB,CACnC,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,MAAM,EAAE,EACjB,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,GACnC,eAAe,CAyBjB;AAgDD,wBAAgB,sBAAsB,CAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CA2ChF"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"search.d.ts","sourceRoot":"","sources":["../../src/tools/search.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAE1D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAuJjD;;;;;;;;;;GAUG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,EAAE,CA0BrD;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,GAAG,EAAE,aAAa,GAAG,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,
|
|
1
|
+
{"version":3,"file":"search.d.ts","sourceRoot":"","sources":["../../src/tools/search.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAE1D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAuJjD;;;;;;;;;;GAUG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,EAAE,CA0BrD;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,GAAG,EAAE,aAAa,GAAG,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAsK9E"}
|
package/dist/tui.js
CHANGED
|
@@ -7790,7 +7790,7 @@ var require_src2 = __commonJS((exports, module) => {
|
|
|
7790
7790
|
// src/tui/index.tsx
|
|
7791
7791
|
import { createMemo as createMemo2, createSignal as createSignal2, onCleanup as onCleanup2 } from "solid-js";
|
|
7792
7792
|
// package.json
|
|
7793
|
-
var version = "0.39.
|
|
7793
|
+
var version = "0.39.4";
|
|
7794
7794
|
|
|
7795
7795
|
// src/shared/rpc-client.ts
|
|
7796
7796
|
import { existsSync, readdirSync, readFileSync, unlinkSync } from "node:fs";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cortexkit/aft-opencode",
|
|
3
|
-
"version": "0.39.
|
|
3
|
+
"version": "0.39.4",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "OpenCode plugin for Agent File Tools (AFT) — tree-sitter and lsp powered code analysis",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -30,19 +30,19 @@
|
|
|
30
30
|
},
|
|
31
31
|
"dependencies": {
|
|
32
32
|
"@clack/prompts": "^1.2.0",
|
|
33
|
-
"@cortexkit/aft-bridge": "0.39.
|
|
33
|
+
"@cortexkit/aft-bridge": "0.39.4",
|
|
34
34
|
"@xterm/headless": "^5.5.0",
|
|
35
35
|
"comment-json": "^4.6.2",
|
|
36
36
|
"undici": "^7.25.0",
|
|
37
37
|
"zod": "^4.1.8"
|
|
38
38
|
},
|
|
39
39
|
"optionalDependencies": {
|
|
40
|
-
"@cortexkit/aft-darwin-arm64": "0.39.
|
|
41
|
-
"@cortexkit/aft-darwin-x64": "0.39.
|
|
42
|
-
"@cortexkit/aft-linux-arm64": "0.39.
|
|
43
|
-
"@cortexkit/aft-linux-x64": "0.39.
|
|
44
|
-
"@cortexkit/aft-win32-arm64": "0.39.
|
|
45
|
-
"@cortexkit/aft-win32-x64": "0.39.
|
|
40
|
+
"@cortexkit/aft-darwin-arm64": "0.39.4",
|
|
41
|
+
"@cortexkit/aft-darwin-x64": "0.39.4",
|
|
42
|
+
"@cortexkit/aft-linux-arm64": "0.39.4",
|
|
43
|
+
"@cortexkit/aft-linux-x64": "0.39.4",
|
|
44
|
+
"@cortexkit/aft-win32-arm64": "0.39.4",
|
|
45
|
+
"@cortexkit/aft-win32-x64": "0.39.4"
|
|
46
46
|
},
|
|
47
47
|
"devDependencies": {
|
|
48
48
|
"@opencode-ai/plugin": "^1.17.7",
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { resolvePromptContext } from "./last-assistant-model.js";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Append an `ignored: true` synthetic user message to a session.
|
|
5
|
+
*
|
|
6
|
+
* Used for user-facing informational panels that must NOT trigger an agent
|
|
7
|
+
* turn (e.g. status output, the external-directory restriction notice). The
|
|
8
|
+
* message renders under the current agent (resolved from recent messages) so
|
|
9
|
+
* it shows in the right place in the OpenCode UI, and carries `noReply: true`
|
|
10
|
+
* so no LLM call is made.
|
|
11
|
+
*
|
|
12
|
+
* IMPORTANT (cache + crash safety): this path deliberately passes ONLY `agent`
|
|
13
|
+
* (never model/variant). OpenCode crashes if model/variant are supplied on a
|
|
14
|
+
* `noReply: true` prompt, and omitting them keeps the synthetic message from
|
|
15
|
+
* busting the provider prefix cache the previous assistant turn warmed.
|
|
16
|
+
*
|
|
17
|
+
* Lives in `shared/` (not `index.ts`) because `index.ts` must export only the
|
|
18
|
+
* plugin default; both the plugin entry and `tools/permissions.ts` call this.
|
|
19
|
+
*/
|
|
20
|
+
export async function sendIgnoredMessage(
|
|
21
|
+
client: unknown,
|
|
22
|
+
sessionID: string,
|
|
23
|
+
text: string,
|
|
24
|
+
): Promise<void> {
|
|
25
|
+
const typedClient = client as {
|
|
26
|
+
session?: {
|
|
27
|
+
prompt?: (input: unknown) => unknown;
|
|
28
|
+
promptAsync?: (input: unknown) => unknown;
|
|
29
|
+
};
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
let agent: string | undefined;
|
|
33
|
+
try {
|
|
34
|
+
const ctx = await resolvePromptContext(
|
|
35
|
+
client as Parameters<typeof resolvePromptContext>[0],
|
|
36
|
+
sessionID,
|
|
37
|
+
);
|
|
38
|
+
agent = ctx?.agent;
|
|
39
|
+
} catch {
|
|
40
|
+
agent = undefined;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
const body: Record<string, unknown> = {
|
|
44
|
+
noReply: true,
|
|
45
|
+
parts: [{ type: "text", text, ignored: true }],
|
|
46
|
+
};
|
|
47
|
+
if (agent) body.agent = agent;
|
|
48
|
+
const promptInput = { path: { id: sessionID }, body };
|
|
49
|
+
|
|
50
|
+
if (typeof typedClient.session?.prompt === "function") {
|
|
51
|
+
await Promise.resolve(typedClient.session.prompt(promptInput));
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
if (typeof typedClient.session?.promptAsync === "function") {
|
|
56
|
+
await typedClient.session.promptAsync(promptInput);
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
throw new Error("[aft-plugin] client.session.prompt is unavailable");
|
|
61
|
+
}
|