@cortexkit/aft-opencode 0.35.4 → 0.36.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +303 -39
- package/dist/shared/bash-hints.d.ts +1 -1
- package/dist/shared/bash-hints.d.ts.map +1 -1
- package/dist/tools/bash.d.ts.map +1 -1
- package/dist/tools/hoisted.d.ts.map +1 -1
- package/dist/tools/navigation.d.ts.map +1 -1
- package/dist/tools/safety.d.ts.map +1 -1
- package/dist/tui.js +1 -1
- package/dist/workflow-hints.d.ts +2 -0
- package/dist/workflow-hints.d.ts.map +1 -1
- package/package.json +8 -8
- package/src/shared/bash-hints.ts +1 -1
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;AA4MlD;;;;;;;;;;;;;;;;;GAiBG;AAQH,QAAA,MAAM,MAAM,EAAE,MAA6D,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AA4MlD;;;;;;;;;;;;;;;;;GAiBG;AAQH,QAAA,MAAM,MAAM,EAAE,MAA6D,CAAC;AAq1B5E,eAAe,MAAM,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -11597,9 +11597,6 @@ function error(message, meta) {
|
|
|
11597
11597
|
var CONFLICT_HINT = `
|
|
11598
11598
|
|
|
11599
11599
|
[Hint] Use aft_conflicts to see all conflict regions across files in a single call.`;
|
|
11600
|
-
var GREP_HINT = `
|
|
11601
|
-
|
|
11602
|
-
[Hint] Use the grep tool instead of bash for faster indexed search.`;
|
|
11603
11600
|
function maybeAppendConflictsHint(output) {
|
|
11604
11601
|
if (!output.includes("Automatic merge failed; fix conflicts"))
|
|
11605
11602
|
return output;
|
|
@@ -11607,12 +11604,12 @@ function maybeAppendConflictsHint(output) {
|
|
|
11607
11604
|
return output;
|
|
11608
11605
|
return output + CONFLICT_HINT;
|
|
11609
11606
|
}
|
|
11610
|
-
|
|
11611
|
-
|
|
11612
|
-
|
|
11613
|
-
|
|
11614
|
-
|
|
11615
|
-
return
|
|
11607
|
+
// ../aft-bridge/dist/bash-timeout.js
|
|
11608
|
+
function resolveBashKillTimeout(modelTimeout, foregroundWaitMs) {
|
|
11609
|
+
if (modelTimeout !== undefined && modelTimeout >= foregroundWaitMs) {
|
|
11610
|
+
return modelTimeout;
|
|
11611
|
+
}
|
|
11612
|
+
return;
|
|
11616
11613
|
}
|
|
11617
11614
|
// ../aft-bridge/dist/bridge.js
|
|
11618
11615
|
import { spawn } from "node:child_process";
|
|
@@ -12467,6 +12464,27 @@ class BinaryBridge {
|
|
|
12467
12464
|
}
|
|
12468
12465
|
}
|
|
12469
12466
|
}
|
|
12467
|
+
// ../aft-bridge/dist/coerce.js
|
|
12468
|
+
function coerceStringArray(value) {
|
|
12469
|
+
if (Array.isArray(value)) {
|
|
12470
|
+
return value.filter((entry) => typeof entry === "string" && entry.length > 0);
|
|
12471
|
+
}
|
|
12472
|
+
if (typeof value === "string") {
|
|
12473
|
+
const trimmed = value.trim();
|
|
12474
|
+
if (trimmed.length === 0)
|
|
12475
|
+
return [];
|
|
12476
|
+
if (trimmed.startsWith("[") && trimmed.endsWith("]")) {
|
|
12477
|
+
try {
|
|
12478
|
+
const parsed = JSON.parse(trimmed);
|
|
12479
|
+
if (Array.isArray(parsed)) {
|
|
12480
|
+
return parsed.filter((entry) => typeof entry === "string" && entry.length > 0);
|
|
12481
|
+
}
|
|
12482
|
+
} catch {}
|
|
12483
|
+
}
|
|
12484
|
+
return [value];
|
|
12485
|
+
}
|
|
12486
|
+
return [];
|
|
12487
|
+
}
|
|
12470
12488
|
// ../aft-bridge/dist/downloader.js
|
|
12471
12489
|
import { spawnSync } from "node:child_process";
|
|
12472
12490
|
import { createHash, randomUUID } from "node:crypto";
|
|
@@ -13975,6 +13993,221 @@ function isProcessAlive(pid) {
|
|
|
13975
13993
|
return true;
|
|
13976
13994
|
}
|
|
13977
13995
|
}
|
|
13996
|
+
// ../aft-bridge/dist/pipe-strip.js
|
|
13997
|
+
var NOISE_FILTERS = new Set(["grep", "rg", "head", "tail", "cat", "less", "more"]);
|
|
13998
|
+
var GREP_GUARD_FLAGS = new Set([
|
|
13999
|
+
"c",
|
|
14000
|
+
"count",
|
|
14001
|
+
"q",
|
|
14002
|
+
"quiet",
|
|
14003
|
+
"o",
|
|
14004
|
+
"only-matching",
|
|
14005
|
+
"l",
|
|
14006
|
+
"files-with-matches"
|
|
14007
|
+
]);
|
|
14008
|
+
function maybeStripCompressorPipe(command, compressionEnabled) {
|
|
14009
|
+
if (!compressionEnabled)
|
|
14010
|
+
return { command, stripped: false };
|
|
14011
|
+
const chain = splitTopLevelAndChain(command);
|
|
14012
|
+
if (chain === null)
|
|
14013
|
+
return { command, stripped: false };
|
|
14014
|
+
const prefix = chain.slice(0, -1).map((segment) => segment.trim()).filter(Boolean);
|
|
14015
|
+
const pipeline3 = chain[chain.length - 1] ?? "";
|
|
14016
|
+
const stages = splitTopLevelPipeline(pipeline3);
|
|
14017
|
+
if (stages.length < 2)
|
|
14018
|
+
return { command, stripped: false };
|
|
14019
|
+
const firstStage = stages[0]?.trim() ?? "";
|
|
14020
|
+
if (!isCompressorHandledRunner(firstStage))
|
|
14021
|
+
return { command, stripped: false };
|
|
14022
|
+
const filterStages = stages.slice(1).map((stage) => stage.trim());
|
|
14023
|
+
for (const stage of filterStages) {
|
|
14024
|
+
if (!isPlainNoiseFilter(stage))
|
|
14025
|
+
return { command, stripped: false };
|
|
14026
|
+
}
|
|
14027
|
+
const filters = filterStages.join(" | ");
|
|
14028
|
+
const rebuilt = [...prefix, firstStage].join(" && ");
|
|
14029
|
+
return {
|
|
14030
|
+
command: rebuilt,
|
|
14031
|
+
stripped: true,
|
|
14032
|
+
note: `[AFT dropped \`| ${filters}\` (compressed:false to keep)]`
|
|
14033
|
+
};
|
|
14034
|
+
}
|
|
14035
|
+
function splitTopLevelAndChain(command) {
|
|
14036
|
+
const segments = [];
|
|
14037
|
+
let start = 0;
|
|
14038
|
+
let quote = null;
|
|
14039
|
+
let escaped = false;
|
|
14040
|
+
for (let index = 0;index < command.length; index++) {
|
|
14041
|
+
const char = command[index];
|
|
14042
|
+
const next = command[index + 1];
|
|
14043
|
+
if (escaped) {
|
|
14044
|
+
escaped = false;
|
|
14045
|
+
continue;
|
|
14046
|
+
}
|
|
14047
|
+
if (char === "\\" && quote !== "'") {
|
|
14048
|
+
escaped = true;
|
|
14049
|
+
continue;
|
|
14050
|
+
}
|
|
14051
|
+
if (quote) {
|
|
14052
|
+
if (char === quote)
|
|
14053
|
+
quote = null;
|
|
14054
|
+
continue;
|
|
14055
|
+
}
|
|
14056
|
+
if (char === "'" || char === '"') {
|
|
14057
|
+
quote = char;
|
|
14058
|
+
continue;
|
|
14059
|
+
}
|
|
14060
|
+
if (char === "&" && next === "&") {
|
|
14061
|
+
segments.push(command.slice(start, index));
|
|
14062
|
+
start = index + 2;
|
|
14063
|
+
index++;
|
|
14064
|
+
continue;
|
|
14065
|
+
}
|
|
14066
|
+
if (char === "|" && next === "|")
|
|
14067
|
+
return null;
|
|
14068
|
+
if (char === ";")
|
|
14069
|
+
return null;
|
|
14070
|
+
}
|
|
14071
|
+
segments.push(command.slice(start));
|
|
14072
|
+
return segments;
|
|
14073
|
+
}
|
|
14074
|
+
function splitTopLevelPipeline(command) {
|
|
14075
|
+
const stages = [];
|
|
14076
|
+
let start = 0;
|
|
14077
|
+
let quote = null;
|
|
14078
|
+
let escaped = false;
|
|
14079
|
+
for (let index = 0;index < command.length; index++) {
|
|
14080
|
+
const char = command[index];
|
|
14081
|
+
const next = command[index + 1];
|
|
14082
|
+
const previous = command[index - 1];
|
|
14083
|
+
if (escaped) {
|
|
14084
|
+
escaped = false;
|
|
14085
|
+
continue;
|
|
14086
|
+
}
|
|
14087
|
+
if (char === "\\" && quote !== "'") {
|
|
14088
|
+
escaped = true;
|
|
14089
|
+
continue;
|
|
14090
|
+
}
|
|
14091
|
+
if (quote) {
|
|
14092
|
+
if (char === quote)
|
|
14093
|
+
quote = null;
|
|
14094
|
+
continue;
|
|
14095
|
+
}
|
|
14096
|
+
if (char === "'" || char === '"') {
|
|
14097
|
+
quote = char;
|
|
14098
|
+
continue;
|
|
14099
|
+
}
|
|
14100
|
+
if (char === "|" && previous !== "|" && next !== "|") {
|
|
14101
|
+
stages.push(command.slice(start, index));
|
|
14102
|
+
start = index + 1;
|
|
14103
|
+
}
|
|
14104
|
+
}
|
|
14105
|
+
stages.push(command.slice(start));
|
|
14106
|
+
return stages;
|
|
14107
|
+
}
|
|
14108
|
+
function isCompressorHandledRunner(stage) {
|
|
14109
|
+
const tokens = tokenizeStage(stage);
|
|
14110
|
+
if (tokens.length === 0)
|
|
14111
|
+
return false;
|
|
14112
|
+
const [first, second, third] = tokens;
|
|
14113
|
+
if (!first)
|
|
14114
|
+
return false;
|
|
14115
|
+
if (tokens.some((token) => token === "&&" || token === "||" || token.includes(";"))) {
|
|
14116
|
+
return false;
|
|
14117
|
+
}
|
|
14118
|
+
if (first === "bun")
|
|
14119
|
+
return second === "test" || second === "run" && startsWithTest(third);
|
|
14120
|
+
if (first === "cargo")
|
|
14121
|
+
return ["test", "build", "check", "clippy"].includes(second ?? "");
|
|
14122
|
+
if (first === "go")
|
|
14123
|
+
return second === "test" || second === "build";
|
|
14124
|
+
if (["npm", "pnpm"].includes(first)) {
|
|
14125
|
+
return second === "test" || second === "run" && startsWithTest(third);
|
|
14126
|
+
}
|
|
14127
|
+
if (first === "yarn")
|
|
14128
|
+
return second === "test";
|
|
14129
|
+
if (first === "playwright")
|
|
14130
|
+
return second === "test";
|
|
14131
|
+
if (first === "npx")
|
|
14132
|
+
return ["tsc", "eslint", "vitest", "jest"].includes(second ?? "");
|
|
14133
|
+
return ["vitest", "jest", "pytest", "tsc", "eslint", "biome", "ruff", "mypy"].includes(first);
|
|
14134
|
+
}
|
|
14135
|
+
function startsWithTest(token) {
|
|
14136
|
+
return token?.startsWith("test") === true;
|
|
14137
|
+
}
|
|
14138
|
+
function isPlainNoiseFilter(stage) {
|
|
14139
|
+
const tokens = tokenizeStage(stage);
|
|
14140
|
+
const head = tokens[0];
|
|
14141
|
+
if (!head)
|
|
14142
|
+
return false;
|
|
14143
|
+
if (head === "wc")
|
|
14144
|
+
return false;
|
|
14145
|
+
if (!NOISE_FILTERS.has(head))
|
|
14146
|
+
return false;
|
|
14147
|
+
if ((head === "grep" || head === "rg") && hasIntentChangingGrepFlag(tokens.slice(1)))
|
|
14148
|
+
return false;
|
|
14149
|
+
return true;
|
|
14150
|
+
}
|
|
14151
|
+
function hasIntentChangingGrepFlag(args) {
|
|
14152
|
+
for (const arg of args) {
|
|
14153
|
+
if (arg === "--")
|
|
14154
|
+
return false;
|
|
14155
|
+
if (!arg.startsWith("-") || arg === "-")
|
|
14156
|
+
continue;
|
|
14157
|
+
if (arg.startsWith("--")) {
|
|
14158
|
+
const flag = arg.slice(2).split("=", 1)[0];
|
|
14159
|
+
if (GREP_GUARD_FLAGS.has(flag))
|
|
14160
|
+
return true;
|
|
14161
|
+
continue;
|
|
14162
|
+
}
|
|
14163
|
+
for (const flag of arg.slice(1)) {
|
|
14164
|
+
if (GREP_GUARD_FLAGS.has(flag))
|
|
14165
|
+
return true;
|
|
14166
|
+
}
|
|
14167
|
+
}
|
|
14168
|
+
return false;
|
|
14169
|
+
}
|
|
14170
|
+
function tokenizeStage(stage) {
|
|
14171
|
+
const tokens = [];
|
|
14172
|
+
let current = "";
|
|
14173
|
+
let quote = null;
|
|
14174
|
+
let escaped = false;
|
|
14175
|
+
for (let index = 0;index < stage.length; index++) {
|
|
14176
|
+
const char = stage[index];
|
|
14177
|
+
if (escaped) {
|
|
14178
|
+
current += char;
|
|
14179
|
+
escaped = false;
|
|
14180
|
+
continue;
|
|
14181
|
+
}
|
|
14182
|
+
if (char === "\\" && quote !== "'") {
|
|
14183
|
+
escaped = true;
|
|
14184
|
+
continue;
|
|
14185
|
+
}
|
|
14186
|
+
if (quote) {
|
|
14187
|
+
if (char === quote) {
|
|
14188
|
+
quote = null;
|
|
14189
|
+
} else {
|
|
14190
|
+
current += char;
|
|
14191
|
+
}
|
|
14192
|
+
continue;
|
|
14193
|
+
}
|
|
14194
|
+
if (char === "'" || char === '"') {
|
|
14195
|
+
quote = char;
|
|
14196
|
+
continue;
|
|
14197
|
+
}
|
|
14198
|
+
if (/\s/.test(char)) {
|
|
14199
|
+
if (current.length > 0) {
|
|
14200
|
+
tokens.push(current);
|
|
14201
|
+
current = "";
|
|
14202
|
+
}
|
|
14203
|
+
continue;
|
|
14204
|
+
}
|
|
14205
|
+
current += char;
|
|
14206
|
+
}
|
|
14207
|
+
if (current.length > 0)
|
|
14208
|
+
tokens.push(current);
|
|
14209
|
+
return tokens;
|
|
14210
|
+
}
|
|
13978
14211
|
// ../aft-bridge/dist/pool.js
|
|
13979
14212
|
import { realpathSync as realpathSync2 } from "node:fs";
|
|
13980
14213
|
var DEFAULT_IDLE_TIMEOUT_MS = Infinity;
|
|
@@ -33964,6 +34197,15 @@ var z5 = tool5.schema;
|
|
|
33964
34197
|
var METADATA_PREVIEW_LIMIT = 30 * 1024;
|
|
33965
34198
|
var FOREGROUND_POLL_INTERVAL_MS = 100;
|
|
33966
34199
|
var DEFAULT_HARD_TIMEOUT_MS = 30 * 60 * 1000;
|
|
34200
|
+
function resolveForegroundWaitMs(configured) {
|
|
34201
|
+
const override = process.env.AFT_TEST_FOREGROUND_WAIT_MS;
|
|
34202
|
+
if (override !== undefined) {
|
|
34203
|
+
const parsed = Number(override);
|
|
34204
|
+
if (Number.isFinite(parsed) && parsed >= 0)
|
|
34205
|
+
return parsed;
|
|
34206
|
+
}
|
|
34207
|
+
return configured;
|
|
34208
|
+
}
|
|
33967
34209
|
var BASH_DESCRIPTION = `Hoisted bash tool with output compression, command rewriting to AFT tools, optional background execution, and PTY mode for interactive programs. By default, output is compressed; pass compressed: false for raw output. Pass background: true to spawn in the background and get a taskId for bash_status/bash_kill. Pass pty: true for interactive REPLs and drive them with bash_status({ outputMode: "screen" }) plus bash_write (pty implies background automatically). Use bash_watch to block on or register for pattern matches and exit events.`;
|
|
33968
34210
|
async function withPermissionLoop(ctx, runtime, params, bridgeCall, options) {
|
|
33969
34211
|
const first = await bridgeCall(ctx, runtime, "bash", params, options);
|
|
@@ -34006,7 +34248,10 @@ function createBashTool(ctx) {
|
|
|
34006
34248
|
let accumulatedOutput = "";
|
|
34007
34249
|
const description = args.description;
|
|
34008
34250
|
const metadata = context.metadata;
|
|
34009
|
-
const
|
|
34251
|
+
const rawCommand = args.command;
|
|
34252
|
+
const compressionEnabled = bashCfg.compress && args.compressed !== false;
|
|
34253
|
+
const pipeStrip = maybeStripCompressorPipe(rawCommand, compressionEnabled);
|
|
34254
|
+
const command = pipeStrip.command;
|
|
34010
34255
|
const cwd = args.workdir ?? context.directory;
|
|
34011
34256
|
const isSubagent = await resolveIsSubagent(ctx.client, context.sessionID, context.directory);
|
|
34012
34257
|
const requestedPty = args.pty === true;
|
|
@@ -34017,13 +34262,15 @@ function createBashTool(ctx) {
|
|
|
34017
34262
|
const allowSubagentBg = bashCfg.subagent_background;
|
|
34018
34263
|
const subagentForcedForeground = isSubagent && !allowSubagentBg;
|
|
34019
34264
|
const effectiveBackground = subagentForcedForeground ? false : requestedBackground;
|
|
34265
|
+
const rawTimeout = args.timeout;
|
|
34266
|
+
const effectiveTimeout = effectiveBackground ? rawTimeout : resolveBashKillTimeout(rawTimeout, bashCfg.foreground_wait_window_ms);
|
|
34020
34267
|
if (subagentForcedForeground && requestedBackground) {
|
|
34021
34268
|
sessionLog(context.sessionID, "[bash] subagent + background:true → converting to foreground (subagent would lose task_id)");
|
|
34022
34269
|
}
|
|
34023
34270
|
const shellEnv = await ctx.plugin?.trigger?.("shell.env", { cwd, sessionID: context.sessionID, callID: getCallID(context) }, { env: {} });
|
|
34024
34271
|
const data = await withPermissionLoop(ctx, context, {
|
|
34025
34272
|
command,
|
|
34026
|
-
timeout:
|
|
34273
|
+
timeout: effectiveTimeout,
|
|
34027
34274
|
workdir: args.workdir,
|
|
34028
34275
|
env: shellEnv?.env ?? {},
|
|
34029
34276
|
description,
|
|
@@ -34061,9 +34308,8 @@ function createBashTool(ctx) {
|
|
|
34061
34308
|
}
|
|
34062
34309
|
return startedLine;
|
|
34063
34310
|
}
|
|
34064
|
-
const
|
|
34065
|
-
const
|
|
34066
|
-
const waitTimeoutMs = subagentForcedForeground ? argTimeout ?? DEFAULT_HARD_TIMEOUT_MS : argTimeout !== undefined ? Math.min(argTimeout, foregroundWaitMs) : foregroundWaitMs;
|
|
34311
|
+
const foregroundWaitMs = resolveForegroundWaitMs(bashCfg.foreground_wait_window_ms);
|
|
34312
|
+
const waitTimeoutMs = subagentForcedForeground ? effectiveTimeout ?? DEFAULT_HARD_TIMEOUT_MS : effectiveTimeout !== undefined ? Math.min(effectiveTimeout, foregroundWaitMs) : foregroundWaitMs;
|
|
34067
34313
|
const startedAt = Date.now();
|
|
34068
34314
|
while (true) {
|
|
34069
34315
|
const status = await callBashBridge(ctx, context, "bash_status", { task_id: taskId });
|
|
@@ -34071,7 +34317,7 @@ function createBashTool(ctx) {
|
|
|
34071
34317
|
throw new Error(status.message ?? "bash_status failed");
|
|
34072
34318
|
}
|
|
34073
34319
|
if (isTerminalStatus(status.status)) {
|
|
34074
|
-
const rendered2 = formatForegroundResult(status);
|
|
34320
|
+
const rendered2 = appendPipeStripNote(formatForegroundResult(status), pipeStrip.note);
|
|
34075
34321
|
const metadataPayload2 = foregroundMetadata(description, status, rendered2);
|
|
34076
34322
|
metadata?.(metadataPayload2);
|
|
34077
34323
|
if (callID2) {
|
|
@@ -34094,7 +34340,7 @@ function createBashTool(ctx) {
|
|
|
34094
34340
|
throw new Error(promoted.message ?? "bash_promote failed");
|
|
34095
34341
|
}
|
|
34096
34342
|
trackBgTask(context.sessionID, taskId);
|
|
34097
|
-
let message = formatPromotionMessage(taskId,
|
|
34343
|
+
let message = formatPromotionMessage(taskId, effectiveTimeout, foregroundWaitMs);
|
|
34098
34344
|
if (isSubagent && allowSubagentBg)
|
|
34099
34345
|
message += subagentGuidance(taskId);
|
|
34100
34346
|
const metadataPayload2 = { description, output: message, status: "running", taskId };
|
|
@@ -34144,10 +34390,16 @@ function createBashTool(ctx) {
|
|
|
34144
34390
|
rendered += `
|
|
34145
34391
|
[exit code: ${exit}]`;
|
|
34146
34392
|
}
|
|
34393
|
+
rendered = appendPipeStripNote(rendered, pipeStrip.note);
|
|
34147
34394
|
return rendered;
|
|
34148
34395
|
}
|
|
34149
34396
|
};
|
|
34150
34397
|
}
|
|
34398
|
+
function appendPipeStripNote(output, note) {
|
|
34399
|
+
return note ? `${output}
|
|
34400
|
+
|
|
34401
|
+
${note}` : output;
|
|
34402
|
+
}
|
|
34151
34403
|
function createBashStatusTool(ctx) {
|
|
34152
34404
|
return {
|
|
34153
34405
|
description: "Read-only snapshot of a background or PTY bash task's current state and output. Returns immediately. Never waits. Use bash_watch to block on or register for pattern matches and exit events.",
|
|
@@ -34202,7 +34454,7 @@ async function formatBashStatusText(runtime, taskId, data, requestedOutputMode)
|
|
|
34202
34454
|
const preview = data.output_preview;
|
|
34203
34455
|
if (preview && status !== "running") {
|
|
34204
34456
|
text += `
|
|
34205
|
-
${preview
|
|
34457
|
+
${preview}`;
|
|
34206
34458
|
}
|
|
34207
34459
|
if (status === "running") {
|
|
34208
34460
|
text += `
|
|
@@ -34326,7 +34578,7 @@ var MAX_BASH_STATUS_WAIT_TIMEOUT_MS = 300000;
|
|
|
34326
34578
|
var REGEX_WAIT_SCAN_WINDOW_BYTES = 64 * 1024;
|
|
34327
34579
|
function createBashWatchTool(ctx) {
|
|
34328
34580
|
return {
|
|
34329
|
-
description: "
|
|
34581
|
+
description: "Watch a background bash task. Two modes. Async (background:true, requires pattern) registers a non-blocking notification and returns immediately — use this to be pinged when a specific line appears or the task exits, without freezing your turn. Sync (default) blocks until a pattern matches/the task exits/timeout, and is ONLY for short bounded waits (seconds, e.g. a dev server printing a readiness line). Do NOT sync-wait for a long task (build/test/install): blocking locks the user out until it ends — instead end your turn and let the automatic completion reminder arrive, or use async mode.",
|
|
34330
34582
|
args: {
|
|
34331
34583
|
taskId: z6.string().describe("Background task ID returned by bash({ background: true })."),
|
|
34332
34584
|
pattern: z6.union([z6.string(), z6.object({ regex: z6.string() })]).optional().describe("Substring or regex pattern. Optional in sync mode; required with background:true. Sync substring watches keep only the overlap tail needed for boundary matches; sync regex watches use a 64 KB rolling output window."),
|
|
@@ -34407,7 +34659,7 @@ Waited ${waited.elapsed_ms}ms; task exited (${stat}${e}).`;
|
|
|
34407
34659
|
const preview2 = data.output_preview;
|
|
34408
34660
|
if (preview2 && status !== "running") {
|
|
34409
34661
|
text += `
|
|
34410
|
-
${preview2
|
|
34662
|
+
${preview2}`;
|
|
34411
34663
|
}
|
|
34412
34664
|
return text;
|
|
34413
34665
|
}
|
|
@@ -35647,7 +35899,10 @@ function createDeleteTool(ctx) {
|
|
|
35647
35899
|
recursive: z8.boolean().optional().describe("Required to delete a directory and its contents. Defaults to false; passing a directory without this returns an error.")
|
|
35648
35900
|
},
|
|
35649
35901
|
execute: async (args, context) => {
|
|
35650
|
-
const inputs = args.files;
|
|
35902
|
+
const inputs = coerceStringArray(args.files);
|
|
35903
|
+
if (inputs.length === 0) {
|
|
35904
|
+
throw new Error("delete: `files` must be a non-empty array of paths");
|
|
35905
|
+
}
|
|
35651
35906
|
const recursive = args.recursive === true;
|
|
35652
35907
|
const projectRoot = await resolveProjectRoot(ctx, context);
|
|
35653
35908
|
const absolutePaths = inputs.map((f) => resolvePathFromProjectRoot(projectRoot, f));
|
|
@@ -36073,6 +36328,7 @@ ${diagnostics}` : json2;
|
|
|
36073
36328
|
// src/tools/navigation.ts
|
|
36074
36329
|
import { tool as tool11 } from "@opencode-ai/plugin";
|
|
36075
36330
|
var z11 = tool11.schema;
|
|
36331
|
+
var CALLGRAPH_SOFT_CODES = new Set(["symbol_not_found", "callgraph_building"]);
|
|
36076
36332
|
function navigationTools(ctx) {
|
|
36077
36333
|
return {
|
|
36078
36334
|
aft_callgraph: {
|
|
@@ -36136,7 +36392,12 @@ function navigationTools(ctx) {
|
|
|
36136
36392
|
params.toFile = toFile;
|
|
36137
36393
|
const response = await callBridge(ctx, context, args.op, params);
|
|
36138
36394
|
if (response.success === false) {
|
|
36139
|
-
|
|
36395
|
+
const message = formatBridgeErrorMessage(args.op, response, params);
|
|
36396
|
+
const code = typeof response.code === "string" ? response.code : "";
|
|
36397
|
+
if (CALLGRAPH_SOFT_CODES.has(code)) {
|
|
36398
|
+
return message;
|
|
36399
|
+
}
|
|
36400
|
+
throw new Error(message);
|
|
36140
36401
|
}
|
|
36141
36402
|
return JSON.stringify(response);
|
|
36142
36403
|
}
|
|
@@ -36747,7 +37008,8 @@ function safetyTools(ctx) {
|
|
|
36747
37008
|
return permissionDeniedResponse(permissionError);
|
|
36748
37009
|
}
|
|
36749
37010
|
if (op === "checkpoint") {
|
|
36750
|
-
const
|
|
37011
|
+
const coercedFiles = coerceStringArray(args.files);
|
|
37012
|
+
const checkpointFiles = coercedFiles.length > 0 ? coercedFiles : typeof args.filePath === "string" ? [args.filePath] : undefined;
|
|
36751
37013
|
if (Array.isArray(checkpointFiles)) {
|
|
36752
37014
|
const projectRoot = await resolveProjectRoot(ctx, context);
|
|
36753
37015
|
const uniqueParents = new Set;
|
|
@@ -36793,17 +37055,18 @@ function safetyTools(ctx) {
|
|
|
36793
37055
|
const params = {};
|
|
36794
37056
|
if (args.name !== undefined)
|
|
36795
37057
|
params.name = args.name;
|
|
37058
|
+
const payloadFiles = coerceStringArray(args.files);
|
|
36796
37059
|
if (op === "checkpoint") {
|
|
36797
|
-
if (
|
|
36798
|
-
params.files =
|
|
37060
|
+
if (payloadFiles.length > 0) {
|
|
37061
|
+
params.files = payloadFiles;
|
|
36799
37062
|
} else if (args.filePath !== undefined) {
|
|
36800
37063
|
params.files = [args.filePath];
|
|
36801
37064
|
}
|
|
36802
37065
|
} else {
|
|
36803
37066
|
if (args.filePath !== undefined)
|
|
36804
37067
|
params.file = args.filePath;
|
|
36805
|
-
if (
|
|
36806
|
-
params.files =
|
|
37068
|
+
if (payloadFiles.length > 0)
|
|
37069
|
+
params.files = payloadFiles;
|
|
36807
37070
|
}
|
|
36808
37071
|
const response = await callBridge(ctx, context, commandMap[op], params);
|
|
36809
37072
|
if (response.success === false) {
|
|
@@ -37229,16 +37492,15 @@ function buildWorkflowHints(opts) {
|
|
|
37229
37492
|
const hasInspect = opts.toolSurface !== "minimal" && !opts.disabledTools.has("aft_inspect");
|
|
37230
37493
|
const hasBash = !opts.disabledTools.has(bashName);
|
|
37231
37494
|
const hasBgBash = hasBash && opts.bashBackgroundEnabled && !opts.disabledTools.has(bashStatusName);
|
|
37495
|
+
if (hasBash && opts.bashCompressionEnabled) {
|
|
37496
|
+
sections.push("When AFT bash output compression is on, do NOT pipe test/build commands through grep/head/tail (e.g. `bun test | grep fail`) to summarize. The compressor already keeps failures and the summary; piping hides failures. Run the command bare.");
|
|
37497
|
+
}
|
|
37232
37498
|
if (hasOutline && hasZoom) {
|
|
37233
37499
|
sections.push(`**Web/URL access**: \`aft_outline({ target: url })\` first for structure, then \`aft_zoom({ url, symbols: "<heading>" })\` for the specific section.`);
|
|
37234
37500
|
}
|
|
37235
37501
|
if (hasOutline && hasZoom && (hasGrep || hasSearch)) {
|
|
37236
|
-
|
|
37237
|
-
|
|
37238
|
-
sections.push(`**Code exploration**: \`aft_search\` is the primary code-search tool. It auto-routes by query shape — exact identifiers, regex, error messages, natural language all use the same call. Very short queries fall back to literal scans; pass \`hint: "regex"\` / \`hint: "literal"\` / \`hint: "semantic"\` to override routing if needed. Then \`aft_outline\` for structure → \`aft_zoom\` for symbol(s).${grepFallback}`);
|
|
37239
|
-
} else {
|
|
37240
|
-
sections.push(`**Code exploration**: \`${grepName}\` to locate → \`aft_outline\` for structure → \`aft_zoom\` for symbol(s).`);
|
|
37241
|
-
}
|
|
37502
|
+
const locate = hasSearch ? '`aft_search` is the primary code-search tool: one call auto-routes concepts, identifiers, regex, error strings, and literals (pass `hint: "regex"`/`"literal"`/`"semantic"` to force a lane).' : `\`${grepName}\` (the tool — indexed and ranked) locates code.`;
|
|
37503
|
+
sections.push(`**Code exploration**: fire independent lookups in ONE parallel tool-call wave — do NOT serialize them. ${locate} Then \`aft_outline\` for structure → \`aft_zoom\` for symbol(s). DO NOT run \`grep\`/\`rg\`/\`find\` through \`bash\` to locate code — the bash path is unindexed, unranked, serial, and routinely surfaces the wrong hit. Keep \`bash\` for shell facts (git state, file metadata, processes).`);
|
|
37242
37504
|
}
|
|
37243
37505
|
if (hasInspect) {
|
|
37244
37506
|
sections.push("**Codebase health & diagnostics**: AFT does not surface compile/type errors automatically after edits — pull them with `aft_inspect`. Run it after a batch of edits and before you run tests or commit, when starting in unfamiliar code, or before a refactor/review. One call summarizes diagnostics (compile/type errors), TODOs, metrics, dead code, unused exports, and duplicates; pass `sections` for focused drill-down and `scope` to actively pull diagnostics for a specific file or directory. Its diagnostics are a fast checkpoint, not the authority — a clean `tsc` / `cargo check` / `pyright` run is the real gate. Treat `stale_categories` as a genuine stale-cache signal while an async Tier 2 refresh catches up.");
|
|
@@ -37256,12 +37518,13 @@ function buildWorkflowHints(opts) {
|
|
|
37256
37518
|
`));
|
|
37257
37519
|
}
|
|
37258
37520
|
if (hasBash && hasBgBash) {
|
|
37259
|
-
sections.push(`**Long-running commands** (builds, installs, full test suites): \`${bashName}({ background: true })\` returns immediately with a \`taskId
|
|
37521
|
+
sections.push(`**Long-running commands** (builds, installs, full test suites): \`${bashName}({ background: true })\` returns immediately with a \`taskId\`, then **end your turn** — a completion reminder arrives automatically when it finishes. Do not poll \`${bashStatusName}({ taskId })\`, and do not sync-wait with \`bash_watch\` for a long task: blocking freezes your turn and locks the user out until it ends. For an early non-blocking ping on a specific output line, register an async watch \`bash_watch({ taskId, pattern, background: true })\`. \`bash_watch\` synchronous mode is only for short bounded waits (seconds, e.g. a dev server printing a readiness line), never for multi-minute jobs.`);
|
|
37260
37522
|
sections.push(`**PTY / interactive commands**: PTY mode is for interactive REPLs and terminal apps (python, node, bash itself, vim). Start with \`${bashName}({ command: "python", pty: true, background: true })\`, read the screen with \`${bashStatusName}({ taskId, outputMode: "screen" })\`, and send input with \`${bashWriteName}({ taskId, input: "..." })\`.`);
|
|
37261
37523
|
}
|
|
37262
37524
|
if (sections.length === 0) {
|
|
37263
37525
|
return null;
|
|
37264
37526
|
}
|
|
37527
|
+
sections.unshift("**Parallel tool calls**: when several read-only operations are independent, emit them in ONE response instead of serializing — file reads, structure and symbol lookups, code search, diagnostics, and git status/diff/log. Sequence only when a call depends on a prior result or when a command mutates state.");
|
|
37265
37528
|
return `${HEADING}
|
|
37266
37529
|
|
|
37267
37530
|
${sections.join(`
|
|
@@ -37274,6 +37537,7 @@ function buildHintsFromConfig(config2, disabledTools) {
|
|
|
37274
37537
|
hoistBuiltins: config2.hoist_builtin_tools !== false,
|
|
37275
37538
|
semanticEnabled: config2.semantic_search === true,
|
|
37276
37539
|
bashBackgroundEnabled: resolveBashConfig(config2).background,
|
|
37540
|
+
bashCompressionEnabled: resolveBashConfig(config2).compress,
|
|
37277
37541
|
disabledTools
|
|
37278
37542
|
});
|
|
37279
37543
|
}
|
|
@@ -37322,12 +37586,12 @@ var PLUGIN_VERSION = (() => {
|
|
|
37322
37586
|
return "0.0.0";
|
|
37323
37587
|
}
|
|
37324
37588
|
})();
|
|
37325
|
-
var ANNOUNCEMENT_VERSION = "0.
|
|
37589
|
+
var ANNOUNCEMENT_VERSION = "0.36.0";
|
|
37326
37590
|
var ANNOUNCEMENT_FEATURES = [
|
|
37327
|
-
"
|
|
37328
|
-
"
|
|
37329
|
-
"
|
|
37330
|
-
"
|
|
37591
|
+
"Persisted call graph: dead-code analysis runs on large repositories again (the file-count cap is gone), `aft_callgraph` queries resolve from disk, and method-call edges are more accurate across more languages.",
|
|
37592
|
+
"Bash output stops hiding failures: piping a test/build through `grep`/`head` with compression on now keeps the failures and summary instead of stripping them.",
|
|
37593
|
+
"Code search steering: guidance and hints now point to `aft_search` and parallel `aft_*` tools instead of `grep`/`find` in bash.",
|
|
37594
|
+
"Fixes: a small `timeout` no longer kills a foreground `bash` command (#102), and `aft_delete`/`aft_safety checkpoint` no longer crash on a mistyped `files` argument."
|
|
37331
37595
|
];
|
|
37332
37596
|
var ANNOUNCEMENT_FOOTER = "Join us on Discord: https://discord.gg/DSa65w8wuf";
|
|
37333
37597
|
var plugin = async (input) => initializePluginForDirectory(input);
|
|
@@ -37699,6 +37963,7 @@ Install: ${getManualInstallHint()}`).catch(() => {});
|
|
|
37699
37963
|
"bash_status"
|
|
37700
37964
|
];
|
|
37701
37965
|
const registeredTools = new Set(Object.keys(allTools));
|
|
37966
|
+
pool.setConfigureOverride("aft_search_registered", registeredTools.has("aft_search"));
|
|
37702
37967
|
const hintsAbsentTools = new Set;
|
|
37703
37968
|
for (const name of HINTS_TOOL_NAMES) {
|
|
37704
37969
|
if (!registeredTools.has(name))
|
|
@@ -37794,7 +38059,6 @@ Install: ${getManualInstallHint()}`).catch(() => {});
|
|
|
37794
38059
|
}
|
|
37795
38060
|
if (toolInput.tool === "bash" && output.output) {
|
|
37796
38061
|
output.output = maybeAppendConflictsHint(output.output);
|
|
37797
|
-
output.output = maybeAppendGrepHint(output.output);
|
|
37798
38062
|
}
|
|
37799
38063
|
const sessionDir = getSessionDirectoryCached(toolInput.sessionID) ?? input.directory;
|
|
37800
38064
|
await appendInTurnBgCompletions({ ctx, directory: sessionDir, sessionID: toolInput.sessionID }, output);
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export { maybeAppendConflictsHint
|
|
1
|
+
export { maybeAppendConflictsHint } from "@cortexkit/aft-bridge";
|
|
2
2
|
//# sourceMappingURL=bash-hints.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bash-hints.d.ts","sourceRoot":"","sources":["../../src/shared/bash-hints.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,wBAAwB,EAAE,
|
|
1
|
+
{"version":3,"file":"bash-hints.d.ts","sourceRoot":"","sources":["../../src/shared/bash-hints.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,wBAAwB,EAAE,MAAM,uBAAuB,CAAC"}
|
package/dist/tools/bash.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bash.d.ts","sourceRoot":"","sources":["../../src/tools/bash.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"bash.d.ts","sourceRoot":"","sources":["../../src/tools/bash.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAe,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAavE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAiFjD,wBAAgB,cAAc,CAAC,GAAG,EAAE,aAAa,GAAG,cAAc,CAsRjE;AAMD,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,aAAa,GAAG,cAAc,CAyBvE;AAED,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,aAAa,GAAG,cAAc,CAuBrE"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hoisted.d.ts","sourceRoot":"","sources":["../../src/tools/hoisted.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAKH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAK1D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AA8EjD,wEAAwE;AACxE,eAAO,MAAM,wBAAwB,GAAI,IAAI,MAAM,EAAE,QAAQ,MAAM,EAAE,OAAO,MAAM,KAAG,MAChD,CAAC;AA0RtC;;GAEG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,aAAa,GAAG,cAAc,CAmKjE;
|
|
1
|
+
{"version":3,"file":"hoisted.d.ts","sourceRoot":"","sources":["../../src/tools/hoisted.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAKH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAK1D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AA8EjD,wEAAwE;AACxE,eAAO,MAAM,wBAAwB,GAAI,IAAI,MAAM,EAAE,QAAQ,MAAM,EAAE,OAAO,MAAM,KAAG,MAChD,CAAC;AA0RtC;;GAEG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,aAAa,GAAG,cAAc,CAmKjE;AAwnCD;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,aAAa,GAAG,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CA0B/E;AAMD;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,aAAa,GAAG,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CA+FnF"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"navigation.d.ts","sourceRoot":"","sources":["../../src/tools/navigation.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAE1D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"navigation.d.ts","sourceRoot":"","sources":["../../src/tools/navigation.ts"],"names":[],"mappings":"AAAA,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,CAkGlF"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"safety.d.ts","sourceRoot":"","sources":["../../src/tools/safety.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"safety.d.ts","sourceRoot":"","sources":["../../src/tools/safety.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAe,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAEvE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAwCjD;;;GAGG;AACH,wBAAgB,WAAW,CAAC,GAAG,EAAE,aAAa,GAAG,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAkJ9E"}
|
package/dist/tui.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// src/tui/index.tsx
|
|
2
2
|
import { createMemo as createMemo2, createSignal as createSignal2, onCleanup as onCleanup2 } from "solid-js";
|
|
3
3
|
// package.json
|
|
4
|
-
var version = "0.
|
|
4
|
+
var version = "0.36.0";
|
|
5
5
|
|
|
6
6
|
// src/shared/rpc-client.ts
|
|
7
7
|
import { existsSync, readdirSync, readFileSync, unlinkSync } from "node:fs";
|
package/dist/workflow-hints.d.ts
CHANGED
|
@@ -8,6 +8,8 @@ export interface WorkflowHintsOpts {
|
|
|
8
8
|
semanticEnabled: boolean;
|
|
9
9
|
/** `experimental.bash.background` — gates background-bash paragraph. */
|
|
10
10
|
bashBackgroundEnabled: boolean;
|
|
11
|
+
/** Resolved bash compression flag. */
|
|
12
|
+
bashCompressionEnabled: boolean;
|
|
11
13
|
/** Set of disabled tool names (after surface filtering). */
|
|
12
14
|
disabledTools: Set<string>;
|
|
13
15
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"workflow-hints.d.ts","sourceRoot":"","sources":["../src/workflow-hints.ts"],"names":[],"mappings":"AAUA,OAAO,EAAE,KAAK,SAAS,EAAqB,MAAM,aAAa,CAAC;AAEhE,MAAM,WAAW,iBAAiB;IAChC,oEAAoE;IACpE,WAAW,EAAE,SAAS,GAAG,aAAa,GAAG,KAAK,CAAC;IAC/C,4EAA4E;IAC5E,aAAa,EAAE,OAAO,CAAC;IACvB,mEAAmE;IACnE,eAAe,EAAE,OAAO,CAAC;IACzB,wEAAwE;IACxE,qBAAqB,EAAE,OAAO,CAAC;IAC/B,4DAA4D;IAC5D,aAAa,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;CAC5B;AAID;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,iBAAiB,GAAG,MAAM,GAAG,IAAI,
|
|
1
|
+
{"version":3,"file":"workflow-hints.d.ts","sourceRoot":"","sources":["../src/workflow-hints.ts"],"names":[],"mappings":"AAUA,OAAO,EAAE,KAAK,SAAS,EAAqB,MAAM,aAAa,CAAC;AAEhE,MAAM,WAAW,iBAAiB;IAChC,oEAAoE;IACpE,WAAW,EAAE,SAAS,GAAG,aAAa,GAAG,KAAK,CAAC;IAC/C,4EAA4E;IAC5E,aAAa,EAAE,OAAO,CAAC;IACvB,mEAAmE;IACnE,eAAe,EAAE,OAAO,CAAC;IACzB,wEAAwE;IACxE,qBAAqB,EAAE,OAAO,CAAC;IAC/B,sCAAsC;IACtC,sBAAsB,EAAE,OAAO,CAAC;IAChC,4DAA4D;IAC5D,aAAa,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;CAC5B;AAID;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,iBAAiB,GAAG,MAAM,GAAG,IAAI,CA8GzE;AAED;;;;;;;GAOG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,SAAS,EAAE,aAAa,EAAE,GAAG,CAAC,MAAM,CAAC,GAAG,MAAM,GAAG,IAAI,CASjG"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cortexkit/aft-opencode",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.36.0",
|
|
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.
|
|
33
|
+
"@cortexkit/aft-bridge": "0.36.0",
|
|
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.
|
|
41
|
-
"@cortexkit/aft-darwin-x64": "0.
|
|
42
|
-
"@cortexkit/aft-linux-arm64": "0.
|
|
43
|
-
"@cortexkit/aft-linux-x64": "0.
|
|
44
|
-
"@cortexkit/aft-win32-arm64": "0.
|
|
45
|
-
"@cortexkit/aft-win32-x64": "0.
|
|
40
|
+
"@cortexkit/aft-darwin-arm64": "0.36.0",
|
|
41
|
+
"@cortexkit/aft-darwin-x64": "0.36.0",
|
|
42
|
+
"@cortexkit/aft-linux-arm64": "0.36.0",
|
|
43
|
+
"@cortexkit/aft-linux-x64": "0.36.0",
|
|
44
|
+
"@cortexkit/aft-win32-arm64": "0.36.0",
|
|
45
|
+
"@cortexkit/aft-win32-x64": "0.36.0"
|
|
46
46
|
},
|
|
47
47
|
"devDependencies": {
|
|
48
48
|
"@opencode-ai/plugin": "^1.15.11",
|
package/src/shared/bash-hints.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
// Bash-output hint nudges now live in the shared bridge package so both plugin
|
|
2
2
|
// hosts use one implementation. Re-exported here to keep the existing OpenCode
|
|
3
3
|
// import path stable.
|
|
4
|
-
export { maybeAppendConflictsHint
|
|
4
|
+
export { maybeAppendConflictsHint } from "@cortexkit/aft-bridge";
|