@cortexkit/aft-pi 0.18.2 → 0.18.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/bg-notifications.d.ts +16 -1
- package/dist/bg-notifications.d.ts.map +1 -1
- package/dist/bridge.d.ts +25 -0
- package/dist/bridge.d.ts.map +1 -1
- package/dist/config.d.ts +3 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/index.d.ts +35 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +350 -42
- package/dist/logger.d.ts.map +1 -1
- package/dist/notifications.d.ts.map +1 -1
- package/dist/pool.d.ts +2 -0
- package/dist/pool.d.ts.map +1 -1
- package/dist/tools/bash.d.ts +1 -0
- package/dist/tools/bash.d.ts.map +1 -1
- package/dist/tools/hoisted.d.ts +16 -0
- package/dist/tools/hoisted.d.ts.map +1 -1
- package/dist/tools/reading.d.ts +13 -0
- package/dist/tools/reading.d.ts.map +1 -1
- package/dist/workflow-hints.d.ts +31 -0
- package/dist/workflow-hints.d.ts.map +1 -0
- package/package.json +7 -6
|
@@ -7,6 +7,10 @@ export interface BgCompletion {
|
|
|
7
7
|
duration_ms?: number;
|
|
8
8
|
runtime_ms?: number;
|
|
9
9
|
runtime?: number;
|
|
10
|
+
/** Tail of stdout+stderr captured at completion (≤300 bytes from Rust). */
|
|
11
|
+
output_preview?: string;
|
|
12
|
+
/** True when the captured tail is shorter than the actual output. */
|
|
13
|
+
output_truncated?: boolean;
|
|
10
14
|
}
|
|
11
15
|
type SessionBgState = {
|
|
12
16
|
outstandingTaskIds: Set<string>;
|
|
@@ -16,6 +20,11 @@ type SessionBgState = {
|
|
|
16
20
|
firstCompletionAt: number | null;
|
|
17
21
|
scheduledFireAt: number | null;
|
|
18
22
|
scheduledCompletionCount: number;
|
|
23
|
+
retryDelayMs: number | null;
|
|
24
|
+
unknownCompletions: Array<{
|
|
25
|
+
completion: BgCompletion;
|
|
26
|
+
receivedAt: number;
|
|
27
|
+
}>;
|
|
19
28
|
lastSeenAt: number;
|
|
20
29
|
};
|
|
21
30
|
type TextContent = {
|
|
@@ -30,7 +39,9 @@ type ImageContent = {
|
|
|
30
39
|
};
|
|
31
40
|
type ContentBlock = TextContent | ImageContent;
|
|
32
41
|
type SendUserMessageRuntime = {
|
|
33
|
-
sendUserMessage: (content: string
|
|
42
|
+
sendUserMessage: (content: string, options?: {
|
|
43
|
+
deliverAs?: "steer" | "followUp";
|
|
44
|
+
}) => void;
|
|
34
45
|
};
|
|
35
46
|
export declare const sessionBgStates: Map<string, SessionBgState>;
|
|
36
47
|
export declare const SESSION_BG_STATE_IDLE_TTL_MS: number;
|
|
@@ -38,9 +49,13 @@ interface DrainContext {
|
|
|
38
49
|
ctx: PluginContext;
|
|
39
50
|
directory: string;
|
|
40
51
|
sessionID?: string;
|
|
52
|
+
isActive?: () => boolean;
|
|
41
53
|
}
|
|
42
54
|
export declare function trackBgTask(sessionID: string | undefined, taskId: string): void;
|
|
43
55
|
export declare function ingestBgCompletions(sessionID: string | undefined, completions: unknown): BgCompletion[];
|
|
56
|
+
export declare function handlePushedBgCompletion(drainContext: DrainContext & {
|
|
57
|
+
runtime: SendUserMessageRuntime;
|
|
58
|
+
}, completion: unknown): Promise<void>;
|
|
44
59
|
export declare function appendToolResultBgCompletions(drainContext: DrainContext, content: ContentBlock[]): Promise<ContentBlock[] | undefined>;
|
|
45
60
|
export declare function handleTurnEndBgCompletions(drainContext: DrainContext & {
|
|
46
61
|
runtime: SendUserMessageRuntime;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bg-notifications.d.ts","sourceRoot":"","sources":["../src/bg-notifications.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAEhD,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"bg-notifications.d.ts","sourceRoot":"","sources":["../src/bg-notifications.ts"],"names":[],"mappings":"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"}
|
package/dist/bridge.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { BgCompletion } from "./bg-notifications.js";
|
|
1
2
|
/**
|
|
2
3
|
* Compare two semver version strings (major.minor.patch plus pre-release).
|
|
3
4
|
* Returns: negative if a < b, 0 if equal, positive if a > b.
|
|
@@ -20,6 +21,12 @@ export interface BridgeOptions {
|
|
|
20
21
|
onVersionMismatch?: (binaryVersion: string, minVersion: string) => void;
|
|
21
22
|
/** Called after the first successful configure returns user-visible warnings. */
|
|
22
23
|
onConfigureWarnings?: (context: ConfigureWarningsContext) => void | Promise<void>;
|
|
24
|
+
/** Called for server-pushed background bash completions. */
|
|
25
|
+
onBashCompletion?: (completion: BashCompletedPayload, bridge: BinaryBridge) => void | Promise<void>;
|
|
26
|
+
}
|
|
27
|
+
export interface BashCompletedPayload extends BgCompletion {
|
|
28
|
+
type: "bash_completed";
|
|
29
|
+
session_id: string;
|
|
23
30
|
}
|
|
24
31
|
export interface BridgeRequestOptions {
|
|
25
32
|
onProgress?: (chunk: {
|
|
@@ -28,6 +35,22 @@ export interface BridgeRequestOptions {
|
|
|
28
35
|
}) => void;
|
|
29
36
|
/** Per-call transport timeout in milliseconds. Defaults to the bridge-wide timeout. */
|
|
30
37
|
transportTimeoutMs?: number;
|
|
38
|
+
/**
|
|
39
|
+
* Skip the "kill the child process on timeout" behavior for this request.
|
|
40
|
+
*
|
|
41
|
+
* The default (false) treats a transport-level timeout as evidence the bridge
|
|
42
|
+
* is wedged — Rust normally responds well within the budget, so silence past
|
|
43
|
+
* the deadline almost always means a stuck child. Killing forces a clean
|
|
44
|
+
* respawn on the next call.
|
|
45
|
+
*
|
|
46
|
+
* Some commands enforce their own timeouts on the Rust side (notably `bash`,
|
|
47
|
+
* which uses a watchdog thread to terminate the child shell and return a
|
|
48
|
+
* timeout response). For those, a transport timeout means the response was
|
|
49
|
+
* lost or queued behind something else — the bridge itself is still healthy
|
|
50
|
+
* and should keep its warm state. Pass `keepBridgeOnTimeout: true` to
|
|
51
|
+
* reject the request without tearing down the bridge.
|
|
52
|
+
*/
|
|
53
|
+
keepBridgeOnTimeout?: boolean;
|
|
31
54
|
}
|
|
32
55
|
interface SendOptions extends BridgeRequestOptions {
|
|
33
56
|
timeoutMs?: number;
|
|
@@ -60,12 +83,14 @@ export declare class BinaryBridge {
|
|
|
60
83
|
private minVersion;
|
|
61
84
|
private onVersionMismatch;
|
|
62
85
|
private onConfigureWarnings;
|
|
86
|
+
private onBashCompletion;
|
|
63
87
|
private restartResetTimer;
|
|
64
88
|
constructor(binaryPath: string, cwd: string, options?: BridgeOptions, configOverrides?: Record<string, unknown>);
|
|
65
89
|
/** Number of times the binary has been restarted after a crash. */
|
|
66
90
|
get restartCount(): number;
|
|
67
91
|
/** Whether the child process is currently alive. */
|
|
68
92
|
isAlive(): boolean;
|
|
93
|
+
hasPendingRequests(): boolean;
|
|
69
94
|
/**
|
|
70
95
|
* Send a command to the binary and return the parsed response.
|
|
71
96
|
* Lazy-spawns the binary on first call.
|
package/dist/bridge.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bridge.d.ts","sourceRoot":"","sources":["../src/bridge.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"bridge.d.ts","sourceRoot":"","sources":["../src/bridge.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAiB1D;;;GAGG;AACH,wBAAgB,aAAa,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAkC1D;AA6CD,UAAU,wBAAwB;IAChC,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,QAAQ,EAAE,OAAO,EAAE,CAAC;CACrB;AAED,MAAM,WAAW,aAAa;IAC5B,sDAAsD;IACtD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,4DAA4D;IAC5D,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,qGAAqG;IACrG,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,iGAAiG;IACjG,iBAAiB,CAAC,EAAE,CAAC,aAAa,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,KAAK,IAAI,CAAC;IACxE,iFAAiF;IACjF,mBAAmB,CAAC,EAAE,CAAC,OAAO,EAAE,wBAAwB,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAClF,4DAA4D;IAC5D,gBAAgB,CAAC,EAAE,CACjB,UAAU,EAAE,oBAAoB,EAChC,MAAM,EAAE,YAAY,KACjB,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC3B;AAED,MAAM,WAAW,oBAAqB,SAAQ,YAAY;IACxD,IAAI,EAAE,gBAAgB,CAAC;IACvB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,oBAAoB;IACnC,UAAU,CAAC,EAAE,CAAC,KAAK,EAAE;QAAE,IAAI,EAAE,QAAQ,GAAG,QAAQ,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,KAAK,IAAI,CAAC;IAC1E,uFAAuF;IACvF,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B;;;;;;;;;;;;;;OAcG;IACH,mBAAmB,CAAC,EAAE,OAAO,CAAC;CAC/B;AAED,UAAU,WAAY,SAAQ,oBAAoB;IAChD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,sBAAsB,CAAC,EAAE,OAAO,CAAC;CAClC;AAED;;;;GAIG;AACH,qBAAa,YAAY;IACvB,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,gBAAgB,CAAiB;IACzD,kEAAkE;IAClE,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,eAAe,CAAM;IAE7C,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,GAAG,CAAS;IACpB,OAAO,CAAC,OAAO,CAA6B;IAC5C,OAAO,CAAC,OAAO,CAAqC;IACpD,OAAO,CAAC,MAAM,CAAK;IACnB,OAAO,CAAC,YAAY,CAAM;IAC1B,sEAAsE;IACtE,OAAO,CAAC,UAAU,CAAgB;IAClC,OAAO,CAAC,aAAa,CAAK;IAC1B,OAAO,CAAC,aAAa,CAAS;IAC9B,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,iBAAiB,CAA8B;IACvD,OAAO,CAAC,eAAe,CAA0B;IACjD,OAAO,CAAC,UAAU,CAAqB;IACvC,OAAO,CAAC,iBAAiB,CAAoE;IAC7F,OAAO,CAAC,mBAAmB,CAEb;IACd,OAAO,CAAC,gBAAgB,CAEV;IACd,OAAO,CAAC,iBAAiB,CAA8C;gBAGrE,UAAU,EAAE,MAAM,EAClB,GAAG,EAAE,MAAM,EACX,OAAO,CAAC,EAAE,aAAa,EACvB,eAAe,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAa3C,mEAAmE;IACnE,IAAI,YAAY,IAAI,MAAM,CAEzB;IAED,oDAAoD;IACpD,OAAO,IAAI,OAAO;IAIlB,kBAAkB,IAAI,OAAO;IAI7B;;;OAGG;IACG,IAAI,CACR,OAAO,EAAE,MAAM,EACf,MAAM,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,EACpC,OAAO,CAAC,EAAE,WAAW,GACpB,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;YAyIrB,wBAAwB;IAuBtC,8DAA8D;IACxD,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IA4B/B,gGAAgG;YAClF,YAAY;IAoB1B,OAAO,CAAC,aAAa;IAKrB,OAAO,CAAC,YAAY;IA6GpB,OAAO,CAAC,cAAc;IAOtB,OAAO,CAAC,gBAAgB;IAMxB,OAAO,CAAC,YAAY;IA+DpB,OAAO,CAAC,aAAa;IA+BrB,OAAO,CAAC,WAAW;IAoDnB,OAAO,CAAC,gBAAgB;IAQxB,OAAO,CAAC,yBAAyB;IAQjC,OAAO,CAAC,sBAAsB;CAM/B"}
|
package/dist/config.d.ts
CHANGED
|
@@ -50,6 +50,8 @@ export interface ConfigureExperimentalOverrides {
|
|
|
50
50
|
export type ToolSurface = "minimal" | "recommended" | "all";
|
|
51
51
|
export interface AftConfig {
|
|
52
52
|
format_on_edit?: boolean;
|
|
53
|
+
/** Maximum formatter subprocess wallclock seconds. Bounded 1..=600. Default 10. */
|
|
54
|
+
formatter_timeout_secs?: number;
|
|
53
55
|
validate_on_edit?: "syntax" | "full";
|
|
54
56
|
formatter?: Record<string, Formatter>;
|
|
55
57
|
checker?: Record<string, Checker>;
|
|
@@ -81,6 +83,7 @@ export declare const LspServerSchema: z.ZodObject<{
|
|
|
81
83
|
}, z.core.$strip>;
|
|
82
84
|
export declare const AftConfigSchema: z.ZodObject<{
|
|
83
85
|
format_on_edit: z.ZodOptional<z.ZodBoolean>;
|
|
86
|
+
formatter_timeout_secs: z.ZodOptional<z.ZodNumber>;
|
|
84
87
|
validate_on_edit: z.ZodOptional<z.ZodEnum<{
|
|
85
88
|
syntax: "syntax";
|
|
86
89
|
full: "full";
|
package/dist/config.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -30,10 +30,45 @@
|
|
|
30
30
|
* - /aft-status Status dialog (index states, LSP servers, storage dir)
|
|
31
31
|
*/
|
|
32
32
|
import type { ExtensionAPI } from "@mariozechner/pi-coding-agent";
|
|
33
|
+
import { loadAftConfig } from "./config.js";
|
|
34
|
+
/**
|
|
35
|
+
* Tool surface mirrors opencode-plugin: navigate/delete/move/transform/refactor
|
|
36
|
+
* are all-only. recommended exposes hoisted + read/safety/import/ast/lsp/conflicts
|
|
37
|
+
* + experimental search/semantic when enabled.
|
|
38
|
+
*
|
|
39
|
+
* Returns the set of AFT tool names that should be registered given the
|
|
40
|
+
* configured surface + disabled_tools filter. Pi's built-in tools are always
|
|
41
|
+
* present; registering an AFT tool with the same name replaces them.
|
|
42
|
+
*/
|
|
43
|
+
declare function resolveToolSurface(config: ReturnType<typeof loadAftConfig>): {
|
|
44
|
+
hoistBash: boolean;
|
|
45
|
+
hoistRead: boolean;
|
|
46
|
+
hoistWrite: boolean;
|
|
47
|
+
hoistEdit: boolean;
|
|
48
|
+
hoistGrep: boolean;
|
|
49
|
+
outline: boolean;
|
|
50
|
+
zoom: boolean;
|
|
51
|
+
semantic: boolean;
|
|
52
|
+
navigate: boolean;
|
|
53
|
+
conflicts: boolean;
|
|
54
|
+
importTool: boolean;
|
|
55
|
+
safety: boolean;
|
|
56
|
+
delete: boolean;
|
|
57
|
+
move: boolean;
|
|
58
|
+
astSearch: boolean;
|
|
59
|
+
astReplace: boolean;
|
|
60
|
+
lspDiagnostics: boolean;
|
|
61
|
+
structure: boolean;
|
|
62
|
+
refactor: boolean;
|
|
63
|
+
};
|
|
33
64
|
/**
|
|
34
65
|
* Pi extension default export.
|
|
35
66
|
*
|
|
36
67
|
* Called once per session. Registers tools, commands, and session shutdown hooks.
|
|
37
68
|
*/
|
|
38
69
|
export default function (pi: ExtensionAPI): Promise<void>;
|
|
70
|
+
export declare const __test__: {
|
|
71
|
+
resolveToolSurface: typeof resolveToolSurface;
|
|
72
|
+
};
|
|
73
|
+
export {};
|
|
39
74
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AAKH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AAKH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AAQlE,OAAO,EACL,aAAa,EAGd,MAAM,aAAa,CAAC;AAkFrB;;;;;;;;GAQG;AACH,iBAAS,kBAAkB,CAAC,MAAM,EAAE,UAAU,CAAC,OAAO,aAAa,CAAC,GAAG;IACrE,SAAS,EAAE,OAAO,CAAC;IACnB,SAAS,EAAE,OAAO,CAAC;IACnB,UAAU,EAAE,OAAO,CAAC;IACpB,SAAS,EAAE,OAAO,CAAC;IACnB,SAAS,EAAE,OAAO,CAAC;IACnB,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,EAAE,OAAO,CAAC;IACd,QAAQ,EAAE,OAAO,CAAC;IAClB,QAAQ,EAAE,OAAO,CAAC;IAClB,SAAS,EAAE,OAAO,CAAC;IACnB,UAAU,EAAE,OAAO,CAAC;IACpB,MAAM,EAAE,OAAO,CAAC;IAChB,MAAM,EAAE,OAAO,CAAC;IAChB,IAAI,EAAE,OAAO,CAAC;IACd,SAAS,EAAE,OAAO,CAAC;IACnB,UAAU,EAAE,OAAO,CAAC;IACpB,cAAc,EAAE,OAAO,CAAC;IACxB,SAAS,EAAE,OAAO,CAAC;IACnB,QAAQ,EAAE,OAAO,CAAC;CACnB,CAiEA;AAED;;;;GAIG;AACH,yBAA+B,EAAE,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CA6T9D;AAED,eAAO,MAAM,QAAQ;;CAAyB,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -7893,7 +7893,8 @@ import * as fs from "node:fs";
|
|
|
7893
7893
|
import * as os from "node:os";
|
|
7894
7894
|
import * as path from "node:path";
|
|
7895
7895
|
var TAG = "[aft-pi]";
|
|
7896
|
-
var
|
|
7896
|
+
var isTestEnv = process.env.BUN_TEST === "1" || false;
|
|
7897
|
+
var logFile = path.join(os.tmpdir(), isTestEnv ? "aft-pi-test.log" : "aft-pi.log");
|
|
7897
7898
|
var useStderr = process.env.AFT_LOG_STDERR === "1";
|
|
7898
7899
|
var buffer = [];
|
|
7899
7900
|
var flushTimer = null;
|
|
@@ -7951,6 +7952,9 @@ function warn(message, data) {
|
|
|
7951
7952
|
function error(message, data) {
|
|
7952
7953
|
write("ERROR", message, data);
|
|
7953
7954
|
}
|
|
7955
|
+
function sessionLog(sessionId, message, data) {
|
|
7956
|
+
write("INFO", message, data, sessionId);
|
|
7957
|
+
}
|
|
7954
7958
|
function sessionWarn(sessionId, message, data) {
|
|
7955
7959
|
write("WARN", message, data, sessionId);
|
|
7956
7960
|
}
|
|
@@ -7963,10 +7967,24 @@ var sessionBgStates = new Map;
|
|
|
7963
7967
|
var SESSION_BG_STATE_IDLE_TTL_MS = 60 * 60 * 1000;
|
|
7964
7968
|
var DEBOUNCE_STEP_MS = 200;
|
|
7965
7969
|
var DEBOUNCE_CAP_MS = 1000;
|
|
7970
|
+
var UNKNOWN_COMPLETION_TTL_MS = 5000;
|
|
7971
|
+
var UNKNOWN_COMPLETION_CAP = 32;
|
|
7966
7972
|
var DEFAULT_SESSION_ID = "__default__";
|
|
7967
7973
|
var LOG_PREFIX = "[aft-pi] bg-notifications:";
|
|
7968
7974
|
function trackBgTask(sessionID, taskId) {
|
|
7969
|
-
stateFor(sessionID)
|
|
7975
|
+
const state = stateFor(sessionID);
|
|
7976
|
+
pruneUnknownCompletions(state, Date.now());
|
|
7977
|
+
const buffered = state.unknownCompletions.filter((entry) => entry.completion.task_id === taskId);
|
|
7978
|
+
state.unknownCompletions = state.unknownCompletions.filter((entry) => entry.completion.task_id !== taskId);
|
|
7979
|
+
if (buffered.length > 0) {
|
|
7980
|
+
for (const entry of buffered) {
|
|
7981
|
+
if (!state.pendingCompletions.some((pending) => pending.task_id === taskId)) {
|
|
7982
|
+
state.pendingCompletions.push(entry.completion);
|
|
7983
|
+
}
|
|
7984
|
+
}
|
|
7985
|
+
return;
|
|
7986
|
+
}
|
|
7987
|
+
state.outstandingTaskIds.add(taskId);
|
|
7970
7988
|
}
|
|
7971
7989
|
function ingestBgCompletions(sessionID, completions) {
|
|
7972
7990
|
if (!Array.isArray(completions) || completions.length === 0)
|
|
@@ -7976,8 +7994,10 @@ function ingestBgCompletions(sessionID, completions) {
|
|
|
7976
7994
|
for (const completion of completions) {
|
|
7977
7995
|
if (!isBgCompletion(completion))
|
|
7978
7996
|
continue;
|
|
7979
|
-
if (!state.outstandingTaskIds.has(completion.task_id))
|
|
7997
|
+
if (!state.outstandingTaskIds.has(completion.task_id)) {
|
|
7998
|
+
bufferUnknownCompletion(state, completion);
|
|
7980
7999
|
continue;
|
|
8000
|
+
}
|
|
7981
8001
|
state.outstandingTaskIds.delete(completion.task_id);
|
|
7982
8002
|
if (!state.pendingCompletions.some((pending) => pending.task_id === completion.task_id) && !accepted.some((pending) => pending.task_id === completion.task_id)) {
|
|
7983
8003
|
accepted.push(completion);
|
|
@@ -7986,6 +8006,10 @@ function ingestBgCompletions(sessionID, completions) {
|
|
|
7986
8006
|
state.pendingCompletions.push(...accepted);
|
|
7987
8007
|
return accepted;
|
|
7988
8008
|
}
|
|
8009
|
+
async function handlePushedBgCompletion(drainContext, completion) {
|
|
8010
|
+
ingestBgCompletions(drainContext.sessionID, [completion]);
|
|
8011
|
+
await triggerWakeIfPending(drainContext, true);
|
|
8012
|
+
}
|
|
7989
8013
|
async function appendToolResultBgCompletions(drainContext, content) {
|
|
7990
8014
|
const state = stateFor(drainContext.sessionID);
|
|
7991
8015
|
if (state.outstandingTaskIds.size === 0 && state.pendingCompletions.length === 0)
|
|
@@ -8000,50 +8024,56 @@ async function appendToolResultBgCompletions(drainContext, content) {
|
|
|
8000
8024
|
return [...content, { type: "text", text: reminder }];
|
|
8001
8025
|
}
|
|
8002
8026
|
async function handleTurnEndBgCompletions(drainContext) {
|
|
8027
|
+
await triggerWakeIfPending(drainContext, false);
|
|
8028
|
+
}
|
|
8029
|
+
async function triggerWakeIfPending(drainContext, skipDrain) {
|
|
8003
8030
|
const state = stateFor(drainContext.sessionID);
|
|
8004
8031
|
if (state.wakeFiredThisIdle)
|
|
8005
8032
|
return;
|
|
8006
|
-
if (
|
|
8033
|
+
if (drainContext.isActive?.())
|
|
8034
|
+
return;
|
|
8035
|
+
if (!skipDrain && state.outstandingTaskIds.size > 0) {
|
|
8007
8036
|
await drainCompletions(drainContext);
|
|
8008
8037
|
}
|
|
8009
8038
|
if (state.pendingCompletions.length === 0)
|
|
8010
8039
|
return;
|
|
8011
8040
|
scheduleWake(state, async (reminder) => {
|
|
8012
|
-
|
|
8013
|
-
|
|
8014
|
-
}
|
|
8015
|
-
warn(`${LOG_PREFIX} wake send failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
8016
|
-
}
|
|
8041
|
+
drainContext.runtime.sendUserMessage(reminder, { deliverAs: "followUp" });
|
|
8042
|
+
}, (err) => {
|
|
8043
|
+
sessionWarn(drainContext.sessionID ?? "", `${LOG_PREFIX} wake send failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
8017
8044
|
});
|
|
8018
8045
|
}
|
|
8019
8046
|
function resetBgWake(sessionID) {
|
|
8020
8047
|
stateFor(sessionID).wakeFiredThisIdle = false;
|
|
8021
8048
|
}
|
|
8022
8049
|
function formatSystemReminder(completions) {
|
|
8023
|
-
const bullets = completions.map((completion) =>
|
|
8050
|
+
const bullets = completions.map((completion) => formatCompletion(completion)).join(`
|
|
8024
8051
|
`);
|
|
8052
|
+
const anyTruncated = completions.some((c) => c.output_truncated === true);
|
|
8053
|
+
const tail = anyTruncated ? `
|
|
8054
|
+
|
|
8055
|
+
For truncated tasks, use bash_status({ task_id: "..." }) to retrieve full output.` : "";
|
|
8025
8056
|
return `<system-reminder>
|
|
8026
8057
|
[BACKGROUND BASH COMPLETED]
|
|
8027
|
-
${bullets}
|
|
8028
|
-
|
|
8029
|
-
Use bash_status({ task_id: "..." }) to retrieve full output.
|
|
8058
|
+
${bullets}${tail}
|
|
8030
8059
|
</system-reminder>`;
|
|
8031
8060
|
}
|
|
8032
8061
|
async function drainCompletions({ ctx, directory, sessionID }) {
|
|
8033
8062
|
try {
|
|
8034
8063
|
const bridge = ctx.pool.getAnyActiveBridge(directory) ?? ctx.pool.getBridge(directory);
|
|
8035
|
-
|
|
8036
|
-
|
|
8064
|
+
if (!sessionID)
|
|
8065
|
+
return;
|
|
8066
|
+
const response = await bridge.send("bash_drain_completions", { session_id: sessionID });
|
|
8037
8067
|
if (response.success === false) {
|
|
8038
|
-
|
|
8068
|
+
sessionWarn(sessionID ?? "", `${LOG_PREFIX} drain failed: ${String(response.message ?? "unknown error")}`);
|
|
8039
8069
|
return;
|
|
8040
8070
|
}
|
|
8041
8071
|
ingestBgCompletions(sessionID, response.bg_completions);
|
|
8042
8072
|
} catch (err) {
|
|
8043
|
-
|
|
8073
|
+
sessionWarn(sessionID ?? "", `${LOG_PREFIX} drain failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
8044
8074
|
}
|
|
8045
8075
|
}
|
|
8046
|
-
function scheduleWake(state, sendWake) {
|
|
8076
|
+
function scheduleWake(state, sendWake, onSendFailure) {
|
|
8047
8077
|
const now = Date.now();
|
|
8048
8078
|
if (state.debounceTimer && state.pendingCompletions.length <= state.scheduledCompletionCount) {
|
|
8049
8079
|
return;
|
|
@@ -8058,16 +8088,24 @@ function scheduleWake(state, sendWake) {
|
|
|
8058
8088
|
state.scheduledCompletionCount = state.pendingCompletions.length;
|
|
8059
8089
|
if (state.debounceTimer)
|
|
8060
8090
|
clearTimeout(state.debounceTimer);
|
|
8061
|
-
const delay = Math.max(0, (state.scheduledFireAt ?? now) - now);
|
|
8091
|
+
const delay = state.retryDelayMs ?? Math.max(0, (state.scheduledFireAt ?? now) - now);
|
|
8062
8092
|
state.debounceTimer = setTimeout(() => {
|
|
8063
|
-
const
|
|
8093
|
+
const pending = state.pendingCompletions;
|
|
8094
|
+
const reminder = formatSystemReminder(pending);
|
|
8064
8095
|
state.pendingCompletions = [];
|
|
8065
8096
|
state.debounceTimer = null;
|
|
8066
|
-
state.wakeFiredThisIdle = true;
|
|
8067
8097
|
state.firstCompletionAt = null;
|
|
8068
8098
|
state.scheduledFireAt = null;
|
|
8069
8099
|
state.scheduledCompletionCount = 0;
|
|
8070
|
-
sendWake(reminder)
|
|
8100
|
+
sendWake(reminder).then(() => {
|
|
8101
|
+
state.retryDelayMs = null;
|
|
8102
|
+
state.wakeFiredThisIdle = true;
|
|
8103
|
+
}).catch((err) => {
|
|
8104
|
+
state.pendingCompletions = [...pending, ...state.pendingCompletions];
|
|
8105
|
+
state.retryDelayMs = Math.min((delay || DEBOUNCE_STEP_MS) * 2, DEBOUNCE_CAP_MS);
|
|
8106
|
+
onSendFailure(err);
|
|
8107
|
+
scheduleWake(state, sendWake, onSendFailure);
|
|
8108
|
+
});
|
|
8071
8109
|
}, delay);
|
|
8072
8110
|
state.debounceTimer.unref?.();
|
|
8073
8111
|
}
|
|
@@ -8085,6 +8123,8 @@ function stateFor(sessionID) {
|
|
|
8085
8123
|
firstCompletionAt: null,
|
|
8086
8124
|
scheduledFireAt: null,
|
|
8087
8125
|
scheduledCompletionCount: 0,
|
|
8126
|
+
retryDelayMs: null,
|
|
8127
|
+
unknownCompletions: [],
|
|
8088
8128
|
lastSeenAt: now
|
|
8089
8129
|
};
|
|
8090
8130
|
sessionBgStates.set(key, state);
|
|
@@ -8105,6 +8145,18 @@ function cleanupIdleSessionStates(now = Date.now()) {
|
|
|
8105
8145
|
sessionBgStates.delete(sessionID);
|
|
8106
8146
|
}
|
|
8107
8147
|
}
|
|
8148
|
+
function bufferUnknownCompletion(state, completion) {
|
|
8149
|
+
const now = Date.now();
|
|
8150
|
+
pruneUnknownCompletions(state, now);
|
|
8151
|
+
state.unknownCompletions = state.unknownCompletions.filter((entry) => entry.completion.task_id !== completion.task_id);
|
|
8152
|
+
state.unknownCompletions.push({ completion, receivedAt: now });
|
|
8153
|
+
if (state.unknownCompletions.length > UNKNOWN_COMPLETION_CAP) {
|
|
8154
|
+
state.unknownCompletions.splice(0, state.unknownCompletions.length - UNKNOWN_COMPLETION_CAP);
|
|
8155
|
+
}
|
|
8156
|
+
}
|
|
8157
|
+
function pruneUnknownCompletions(state, now) {
|
|
8158
|
+
state.unknownCompletions = state.unknownCompletions.filter((entry) => now - entry.receivedAt <= UNKNOWN_COMPLETION_TTL_MS);
|
|
8159
|
+
}
|
|
8108
8160
|
function isBgCompletion(value) {
|
|
8109
8161
|
if (!value || typeof value !== "object" || Array.isArray(value))
|
|
8110
8162
|
return false;
|
|
@@ -8114,10 +8166,26 @@ function isBgCompletion(value) {
|
|
|
8114
8166
|
function formatCompletion(completion) {
|
|
8115
8167
|
const status = formatStatus(completion);
|
|
8116
8168
|
const duration = formatDuration(completion);
|
|
8117
|
-
|
|
8169
|
+
const header = `- task ${completion.task_id} (${status}${duration ? `, ${duration}` : ""})`;
|
|
8170
|
+
const previewBlock = formatOutputPreview(completion);
|
|
8171
|
+
return previewBlock ? `${header}
|
|
8172
|
+
${previewBlock}` : header;
|
|
8173
|
+
}
|
|
8174
|
+
function formatOutputPreview(completion) {
|
|
8175
|
+
const ansiRegex = /\x1b\[[0-9;]*[a-zA-Z]/g;
|
|
8176
|
+
const raw = (completion.output_preview ?? "").replace(ansiRegex, "");
|
|
8177
|
+
if (!raw.trim())
|
|
8178
|
+
return "";
|
|
8179
|
+
const trimmed = raw.replace(/\n+$/, "");
|
|
8180
|
+
const ellipsis = completion.output_truncated ? "…" : "";
|
|
8181
|
+
const indented = trimmed.split(`
|
|
8182
|
+
`).map((line) => ` ${line}`).join(`
|
|
8183
|
+
`);
|
|
8184
|
+
return ellipsis ? ` ${ellipsis}
|
|
8185
|
+
${indented}` : indented;
|
|
8118
8186
|
}
|
|
8119
8187
|
function formatStatus(completion) {
|
|
8120
|
-
if (completion.status === "timeout")
|
|
8188
|
+
if (completion.status === "timed_out" || completion.status === "timeout")
|
|
8121
8189
|
return "timed out";
|
|
8122
8190
|
if (completion.status === "killed")
|
|
8123
8191
|
return "killed";
|
|
@@ -21949,6 +22017,7 @@ var ExperimentalConfigSchema = exports_external.object({
|
|
|
21949
22017
|
});
|
|
21950
22018
|
var AftConfigSchema = exports_external.object({
|
|
21951
22019
|
format_on_edit: exports_external.boolean().optional(),
|
|
22020
|
+
formatter_timeout_secs: exports_external.number().int().min(1).max(600).optional(),
|
|
21952
22021
|
validate_on_edit: exports_external.enum(["syntax", "full"]).optional(),
|
|
21953
22022
|
formatter: exports_external.record(exports_external.string(), FormatterEnum).optional(),
|
|
21954
22023
|
checker: exports_external.record(exports_external.string(), CheckerEnum).optional(),
|
|
@@ -22038,6 +22107,18 @@ function isWritableMigrationError(errorValue) {
|
|
|
22038
22107
|
const code = errorValue?.code;
|
|
22039
22108
|
return code === "EROFS" || code === "EACCES" || code === "EPERM";
|
|
22040
22109
|
}
|
|
22110
|
+
function extractCommentsForPreservation(content) {
|
|
22111
|
+
const comments = [];
|
|
22112
|
+
const linePattern = /\/\/[^\n]*/g;
|
|
22113
|
+
for (const match of content.match(linePattern) ?? []) {
|
|
22114
|
+
comments.push(match.trim());
|
|
22115
|
+
}
|
|
22116
|
+
const blockPattern = /\/\*[\s\S]*?\*\//g;
|
|
22117
|
+
for (const match of content.match(blockPattern) ?? []) {
|
|
22118
|
+
comments.push(match.replace(/\s+/g, " ").trim());
|
|
22119
|
+
}
|
|
22120
|
+
return comments;
|
|
22121
|
+
}
|
|
22041
22122
|
function ensureRecordAtPath(root, path2) {
|
|
22042
22123
|
let current = root;
|
|
22043
22124
|
for (const segment of path2) {
|
|
@@ -22096,10 +22177,9 @@ function migrateAftConfigFile(configPath, logger = { log, warn }) {
|
|
|
22096
22177
|
if (oldKeys.length === 0) {
|
|
22097
22178
|
return { migrated: false, oldKeys: [] };
|
|
22098
22179
|
}
|
|
22099
|
-
const comments = content.match(/^\s*\/\/.*$/gm) ?? [];
|
|
22100
22180
|
const serialized = `${import_comment_json.stringify(rawConfig, null, 2)}
|
|
22101
22181
|
`;
|
|
22102
|
-
const preservedComments =
|
|
22182
|
+
const preservedComments = extractCommentsForPreservation(content).filter((comment) => !serialized.includes(comment.trim()));
|
|
22103
22183
|
const nextContent = preservedComments.length > 0 ? `${preservedComments.join(`
|
|
22104
22184
|
`)}
|
|
22105
22185
|
${serialized}` : serialized;
|
|
@@ -23738,7 +23818,7 @@ import { join as join6 } from "node:path";
|
|
|
23738
23818
|
var WARNING_MARKER = "\uD83D\uDD27 AFT: ⚠️";
|
|
23739
23819
|
var FEATURE_MARKER = "\uD83D\uDD27 AFT: ✨";
|
|
23740
23820
|
var WARNED_TOOLS_FILE = "warned_tools.json";
|
|
23741
|
-
function sendIgnoredMessage(client,
|
|
23821
|
+
function sendIgnoredMessage(client, sessionId, text) {
|
|
23742
23822
|
const typedClient = client;
|
|
23743
23823
|
if (typeof typedClient.ui?.notify !== "function")
|
|
23744
23824
|
return false;
|
|
@@ -23746,7 +23826,7 @@ function sendIgnoredMessage(client, _sessionId, text) {
|
|
|
23746
23826
|
typedClient.ui.notify(text, "warning");
|
|
23747
23827
|
return true;
|
|
23748
23828
|
} catch (err) {
|
|
23749
|
-
|
|
23829
|
+
sessionLog(sessionId, `[aft-pi] notification send failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
23750
23830
|
return false;
|
|
23751
23831
|
}
|
|
23752
23832
|
}
|
|
@@ -24387,6 +24467,7 @@ class BinaryBridge {
|
|
|
24387
24467
|
minVersion;
|
|
24388
24468
|
onVersionMismatch;
|
|
24389
24469
|
onConfigureWarnings;
|
|
24470
|
+
onBashCompletion;
|
|
24390
24471
|
restartResetTimer = null;
|
|
24391
24472
|
constructor(binaryPath, cwd, options, configOverrides) {
|
|
24392
24473
|
this.binaryPath = binaryPath;
|
|
@@ -24397,6 +24478,7 @@ class BinaryBridge {
|
|
|
24397
24478
|
this.minVersion = options?.minVersion;
|
|
24398
24479
|
this.onVersionMismatch = options?.onVersionMismatch;
|
|
24399
24480
|
this.onConfigureWarnings = options?.onConfigureWarnings;
|
|
24481
|
+
this.onBashCompletion = options?.onBashCompletion;
|
|
24400
24482
|
}
|
|
24401
24483
|
get restartCount() {
|
|
24402
24484
|
return this._restartCount;
|
|
@@ -24404,6 +24486,9 @@ class BinaryBridge {
|
|
|
24404
24486
|
isAlive() {
|
|
24405
24487
|
return this.process !== null && this.process.exitCode === null && !this.process.killed;
|
|
24406
24488
|
}
|
|
24489
|
+
hasPendingRequests() {
|
|
24490
|
+
return this.pending.size > 0;
|
|
24491
|
+
}
|
|
24407
24492
|
async send(command, params = {}, options) {
|
|
24408
24493
|
if (this._shuttingDown) {
|
|
24409
24494
|
throw new Error(`[aft-pi] Bridge is shutting down, cannot send "${command}"`);
|
|
@@ -24457,17 +24542,21 @@ class BinaryBridge {
|
|
|
24457
24542
|
`;
|
|
24458
24543
|
const effectiveTimeoutMs = options?.transportTimeoutMs ?? options?.timeoutMs ?? this.timeoutMs;
|
|
24459
24544
|
const requestSessionId = typeof params.session_id === "string" && params.session_id.length > 0 ? params.session_id : undefined;
|
|
24545
|
+
const keepBridgeOnTimeout = options?.keepBridgeOnTimeout === true;
|
|
24460
24546
|
return new Promise((resolve3, reject) => {
|
|
24461
24547
|
const timer = setTimeout(() => {
|
|
24462
24548
|
this.pending.delete(id);
|
|
24463
|
-
const
|
|
24549
|
+
const restartSuffix = keepBridgeOnTimeout ? "" : " — restarting bridge";
|
|
24550
|
+
const timeoutMsg = `Request "${command}" (id=${id}) timed out after ${effectiveTimeoutMs}ms${restartSuffix}`;
|
|
24464
24551
|
if (requestSessionId) {
|
|
24465
24552
|
sessionWarn(requestSessionId, timeoutMsg);
|
|
24466
24553
|
} else {
|
|
24467
24554
|
warn(timeoutMsg);
|
|
24468
24555
|
}
|
|
24469
24556
|
reject(new Error(`[aft-pi] Request "${command}" (id=${id}) timed out after ${effectiveTimeoutMs}ms`));
|
|
24470
|
-
|
|
24557
|
+
if (!keepBridgeOnTimeout) {
|
|
24558
|
+
this.handleTimeout();
|
|
24559
|
+
}
|
|
24471
24560
|
}, effectiveTimeoutMs);
|
|
24472
24561
|
this.pending.set(id, { resolve: resolve3, reject, timer, onProgress: options?.onProgress });
|
|
24473
24562
|
if (!this.process?.stdin?.writable) {
|
|
@@ -24672,6 +24761,10 @@ class BinaryBridge {
|
|
|
24672
24761
|
}
|
|
24673
24762
|
continue;
|
|
24674
24763
|
}
|
|
24764
|
+
if (response.type === "bash_completed") {
|
|
24765
|
+
this.onBashCompletion?.(response, this);
|
|
24766
|
+
continue;
|
|
24767
|
+
}
|
|
24675
24768
|
const id = response.id;
|
|
24676
24769
|
if (id && this.pending.has(id)) {
|
|
24677
24770
|
const entry = this.pending.get(id);
|
|
@@ -24681,6 +24774,8 @@ class BinaryBridge {
|
|
|
24681
24774
|
clearTimeout(entry.timer);
|
|
24682
24775
|
this.scheduleRestartCountReset();
|
|
24683
24776
|
entry.resolve(response);
|
|
24777
|
+
} else if (typeof response.type === "string") {
|
|
24778
|
+
log(`Ignoring unknown stdout push frame type: ${response.type}`);
|
|
24684
24779
|
}
|
|
24685
24780
|
} catch (_err) {
|
|
24686
24781
|
warn(`Failed to parse stdout line: ${line}`);
|
|
@@ -24778,7 +24873,8 @@ class BridgePool {
|
|
|
24778
24873
|
maxRestarts: options.maxRestarts,
|
|
24779
24874
|
minVersion: options.minVersion,
|
|
24780
24875
|
onVersionMismatch: options.onVersionMismatch,
|
|
24781
|
-
onConfigureWarnings: options.onConfigureWarnings
|
|
24876
|
+
onConfigureWarnings: options.onConfigureWarnings,
|
|
24877
|
+
onBashCompletion: options.onBashCompletion
|
|
24782
24878
|
};
|
|
24783
24879
|
this.configOverrides = configOverrides;
|
|
24784
24880
|
if (Number.isFinite(this.idleTimeoutMs)) {
|
|
@@ -24801,6 +24897,14 @@ class BridgePool {
|
|
|
24801
24897
|
}
|
|
24802
24898
|
return null;
|
|
24803
24899
|
}
|
|
24900
|
+
getActiveBridgeForRoot(directory) {
|
|
24901
|
+
const key = canonicalKey(directory);
|
|
24902
|
+
const entry = this.bridges.get(key);
|
|
24903
|
+
if (!entry?.bridge.isAlive())
|
|
24904
|
+
return null;
|
|
24905
|
+
entry.lastUsed = Date.now();
|
|
24906
|
+
return entry.bridge;
|
|
24907
|
+
}
|
|
24804
24908
|
getBridge(directory) {
|
|
24805
24909
|
const key = canonicalKey(directory);
|
|
24806
24910
|
const existing = this.bridges.get(key);
|
|
@@ -25674,6 +25778,7 @@ function registerBashTool(pi, ctx) {
|
|
|
25674
25778
|
compressed: params.compressed
|
|
25675
25779
|
}, extCtx, {
|
|
25676
25780
|
transportTimeoutMs: bashTransportTimeoutMs(params.timeout),
|
|
25781
|
+
keepBridgeOnTimeout: true,
|
|
25677
25782
|
onProgress: ({ text }) => {
|
|
25678
25783
|
streamed += text;
|
|
25679
25784
|
const displayText = truncateToVisualLines(streamed, 100);
|
|
@@ -25748,7 +25853,7 @@ function createBashKillTool(ctx) {
|
|
|
25748
25853
|
throw new Error(data.message ?? "bash_kill failed");
|
|
25749
25854
|
}
|
|
25750
25855
|
const details = data;
|
|
25751
|
-
return bashKillResult(`Task ${params.task_id}:
|
|
25856
|
+
return bashKillResult(`Task ${params.task_id}: ${details.status}`, details);
|
|
25752
25857
|
}
|
|
25753
25858
|
};
|
|
25754
25859
|
}
|
|
@@ -25779,10 +25884,11 @@ function bashKillResult(output, details) {
|
|
|
25779
25884
|
}
|
|
25780
25885
|
function formatBashStatus(taskId, details) {
|
|
25781
25886
|
const exit = typeof details.exit_code === "number" ? ` (exit ${details.exit_code})` : "";
|
|
25782
|
-
|
|
25887
|
+
const dur = typeof details.duration_ms === "number" ? ` ${Math.round(details.duration_ms / 1000)}s` : "";
|
|
25888
|
+
let text = `Task ${taskId}: ${details.status}${exit}${dur}`;
|
|
25783
25889
|
if (isTerminalStatus(details.status) && details.output_preview) {
|
|
25784
25890
|
text += `
|
|
25785
|
-
${details.output_preview.slice(0,
|
|
25891
|
+
${details.output_preview.slice(0, 2000)}`;
|
|
25786
25892
|
}
|
|
25787
25893
|
return text;
|
|
25788
25894
|
}
|
|
@@ -25810,6 +25916,17 @@ ${theme.fg("error", errorText || "bash failed")}`);
|
|
|
25810
25916
|
const container = reuseContainer2(context.lastComponent);
|
|
25811
25917
|
container.clear();
|
|
25812
25918
|
container.addChild(new Spacer2(1));
|
|
25919
|
+
const rawOutput = result.content.filter((c) => c.type === "text").map((c) => c.text ?? "").join(`
|
|
25920
|
+
`).trim();
|
|
25921
|
+
if (rawOutput) {
|
|
25922
|
+
const lines = rawOutput.split(`
|
|
25923
|
+
`);
|
|
25924
|
+
const preview = lines.length > 25 ? `... (${lines.length - 25} lines omitted)
|
|
25925
|
+
${lines.slice(-25).join(`
|
|
25926
|
+
`)}` : rawOutput;
|
|
25927
|
+
container.addChild(new Text2(preview, 1, 0));
|
|
25928
|
+
container.addChild(new Spacer2(1));
|
|
25929
|
+
}
|
|
25813
25930
|
if (exitCode !== undefined) {
|
|
25814
25931
|
const exitColor = exitCode === 0 ? "success" : "error";
|
|
25815
25932
|
const exitText = theme.fg(exitColor, `exit ${exitCode}`);
|
|
@@ -26248,12 +26365,15 @@ function buildMutationResult(filePath, response) {
|
|
|
26248
26365
|
const replacements = response.replacements;
|
|
26249
26366
|
const diagnostics = response.lsp_diagnostics;
|
|
26250
26367
|
const truncated = diffObj?.truncated === true;
|
|
26368
|
+
const formatted = response.formatted;
|
|
26369
|
+
const formatSkippedReason = response.format_skipped_reason;
|
|
26370
|
+
const globFormatSkipReasons = response.format_skip_reasons;
|
|
26251
26371
|
let diffText;
|
|
26252
26372
|
let firstChangedLine;
|
|
26253
26373
|
if (diffObj && !truncated && typeof diffObj.before === "string" && typeof diffObj.after === "string") {
|
|
26254
|
-
const
|
|
26255
|
-
diffText =
|
|
26256
|
-
firstChangedLine =
|
|
26374
|
+
const piDiff = formatDiffForPi(diffObj.before, diffObj.after);
|
|
26375
|
+
diffText = piDiff.diff;
|
|
26376
|
+
firstChangedLine = piDiff.firstChangedLine;
|
|
26257
26377
|
}
|
|
26258
26378
|
const summaryHeader = replacements !== undefined ? `Edited ${filePath} (+${additions}/-${deletions}, ${replacements} replacement${replacements === 1 ? "" : "s"})` : `Wrote ${filePath} (+${additions}/-${deletions})`;
|
|
26259
26379
|
let text = summaryHeader;
|
|
@@ -26266,6 +26386,16 @@ ${diffText}`;
|
|
|
26266
26386
|
|
|
26267
26387
|
(diff truncated — file too large to include before/after content)`;
|
|
26268
26388
|
}
|
|
26389
|
+
const skipNote = formatSkipReasonNote(formatSkippedReason);
|
|
26390
|
+
if (skipNote)
|
|
26391
|
+
text += `
|
|
26392
|
+
|
|
26393
|
+
${skipNote}`;
|
|
26394
|
+
const globSkipNote = formatGlobSkipReasonsNote(globFormatSkipReasons);
|
|
26395
|
+
if (globSkipNote)
|
|
26396
|
+
text += `
|
|
26397
|
+
|
|
26398
|
+
${globSkipNote}`;
|
|
26269
26399
|
if (diagnostics && diagnostics.length > 0) {
|
|
26270
26400
|
text += `
|
|
26271
26401
|
|
|
@@ -26281,10 +26411,34 @@ ${formatDiagnosticsText(diagnostics)}`;
|
|
|
26281
26411
|
deletions,
|
|
26282
26412
|
replacements,
|
|
26283
26413
|
diagnostics,
|
|
26284
|
-
truncated: truncated || undefined
|
|
26414
|
+
truncated: truncated || undefined,
|
|
26415
|
+
formatted,
|
|
26416
|
+
formatSkippedReason
|
|
26285
26417
|
}
|
|
26286
26418
|
};
|
|
26287
26419
|
}
|
|
26420
|
+
function formatGlobSkipReasonsNote(reasons) {
|
|
26421
|
+
if (!Array.isArray(reasons))
|
|
26422
|
+
return;
|
|
26423
|
+
const actionable = reasons.filter((reason) => typeof reason === "string").filter((reason) => ["formatter_not_installed", "formatter_excluded_path", "timeout", "error"].includes(reason));
|
|
26424
|
+
if (actionable.length === 0)
|
|
26425
|
+
return;
|
|
26426
|
+
return `Note: formatter skipped some glob edit result file(s): ${[...new Set(actionable)].sort().join(", ")}. See per-file format_skipped_reason values for details.`;
|
|
26427
|
+
}
|
|
26428
|
+
function formatSkipReasonNote(reason) {
|
|
26429
|
+
switch (reason) {
|
|
26430
|
+
case "formatter_not_installed":
|
|
26431
|
+
return "Note: formatter binary not installed; file written unformatted.";
|
|
26432
|
+
case "timeout":
|
|
26433
|
+
return "Note: formatter timed out; file written unformatted. Raise formatter_timeout_secs or check the formatter for hangs.";
|
|
26434
|
+
case "formatter_excluded_path":
|
|
26435
|
+
return "Note: formatter is configured to ignore this path (e.g. biome.json files.includes, .prettierignore). File written unformatted.";
|
|
26436
|
+
case "error":
|
|
26437
|
+
return "Note: formatter exited with an unrecognized error; file written unformatted.";
|
|
26438
|
+
default:
|
|
26439
|
+
return;
|
|
26440
|
+
}
|
|
26441
|
+
}
|
|
26288
26442
|
function formatDiagnosticsText(diagnostics) {
|
|
26289
26443
|
try {
|
|
26290
26444
|
return diagnostics.map((d) => {
|
|
@@ -26856,6 +27010,29 @@ function buildOutlineSections(text, theme) {
|
|
|
26856
27010
|
`)];
|
|
26857
27011
|
}
|
|
26858
27012
|
function buildZoomSections(args, payload, theme) {
|
|
27013
|
+
const batch = asRecord2(payload);
|
|
27014
|
+
if (Array.isArray(batch?.symbols)) {
|
|
27015
|
+
const header = batch.complete === false ? [theme.fg("warning", "Incomplete zoom results")] : [];
|
|
27016
|
+
const items2 = batch.symbols;
|
|
27017
|
+
return [
|
|
27018
|
+
...header,
|
|
27019
|
+
...items2.map((item) => {
|
|
27020
|
+
const record2 = asRecord2(item);
|
|
27021
|
+
if (!record2)
|
|
27022
|
+
return theme.fg("muted", "No zoom result available.");
|
|
27023
|
+
const name = asString(record2.name) ?? "(unknown symbol)";
|
|
27024
|
+
if (record2.success === false) {
|
|
27025
|
+
return theme.fg("error", `Symbol "${name}" not found: ${asString(record2.error) ?? "zoom failed"}`);
|
|
27026
|
+
}
|
|
27027
|
+
const content = asString(record2.content);
|
|
27028
|
+
return [
|
|
27029
|
+
`${theme.fg("accent", name)} ${theme.fg("muted", shortenPath(args.filePath))}`,
|
|
27030
|
+
content
|
|
27031
|
+
].filter(Boolean).join(`
|
|
27032
|
+
`);
|
|
27033
|
+
})
|
|
27034
|
+
];
|
|
27035
|
+
}
|
|
26859
27036
|
const items = Array.isArray(payload) ? payload : payload ? [payload] : [];
|
|
26860
27037
|
if (items.length === 0)
|
|
26861
27038
|
return [theme.fg("muted", "No zoom result available.")];
|
|
@@ -26974,9 +27151,13 @@ function registerReadingTools(pi, ctx, surface) {
|
|
|
26974
27151
|
const req2 = { file: params.filePath, symbol: sym };
|
|
26975
27152
|
if (params.contextLines !== undefined)
|
|
26976
27153
|
req2.context_lines = params.contextLines;
|
|
26977
|
-
return callBridge(bridge, "zoom", req2, extCtx)
|
|
27154
|
+
return callBridge(bridge, "zoom", req2, extCtx).catch((err) => ({
|
|
27155
|
+
success: false,
|
|
27156
|
+
message: err instanceof Error ? err.message : String(err)
|
|
27157
|
+
}));
|
|
26978
27158
|
}));
|
|
26979
|
-
|
|
27159
|
+
const batch = formatZoomBatchResult(params.symbols, results);
|
|
27160
|
+
return textResult(batch.text, batch);
|
|
26980
27161
|
}
|
|
26981
27162
|
const req = { file: params.filePath };
|
|
26982
27163
|
if (params.symbol)
|
|
@@ -26995,6 +27176,40 @@ function registerReadingTools(pi, ctx, surface) {
|
|
|
26995
27176
|
});
|
|
26996
27177
|
}
|
|
26997
27178
|
}
|
|
27179
|
+
function formatZoomBatchResult(symbols, responses) {
|
|
27180
|
+
const entries = symbols.map((name, index) => {
|
|
27181
|
+
const response = responses[index] ?? { success: false, message: "missing zoom response" };
|
|
27182
|
+
if (response.success === false) {
|
|
27183
|
+
const message = typeof response.message === "string" && response.message.length > 0 ? response.message : "zoom failed";
|
|
27184
|
+
return { name, success: false, error: message };
|
|
27185
|
+
}
|
|
27186
|
+
return { name, success: true, content: zoomResponseContent(response) };
|
|
27187
|
+
});
|
|
27188
|
+
const complete = entries.every((entry) => entry.success);
|
|
27189
|
+
const lines = [];
|
|
27190
|
+
if (!complete) {
|
|
27191
|
+
lines.push("Incomplete zoom results: one or more symbols failed.");
|
|
27192
|
+
}
|
|
27193
|
+
for (const entry of entries) {
|
|
27194
|
+
if (entry.success) {
|
|
27195
|
+
lines.push(`Symbol "${entry.name}":
|
|
27196
|
+
${entry.content ?? ""}`.trimEnd());
|
|
27197
|
+
} else {
|
|
27198
|
+
lines.push(`Symbol "${entry.name}" not found: ${entry.error ?? "zoom failed"}`);
|
|
27199
|
+
}
|
|
27200
|
+
}
|
|
27201
|
+
return { complete, symbols: entries, text: lines.join(`
|
|
27202
|
+
|
|
27203
|
+
`) };
|
|
27204
|
+
}
|
|
27205
|
+
function zoomResponseContent(response) {
|
|
27206
|
+
if (typeof response.content === "string")
|
|
27207
|
+
return response.content;
|
|
27208
|
+
if (typeof response.text === "string")
|
|
27209
|
+
return response.text;
|
|
27210
|
+
const { success: _success2, ...rest } = response;
|
|
27211
|
+
return JSON.stringify(rest, null, 2);
|
|
27212
|
+
}
|
|
26998
27213
|
function formatOutlineText(response) {
|
|
26999
27214
|
const text = response.text ?? "";
|
|
27000
27215
|
const skipped = response.skipped_files;
|
|
@@ -27486,6 +27701,83 @@ function validateTransformParams(params) {
|
|
|
27486
27701
|
}
|
|
27487
27702
|
}
|
|
27488
27703
|
|
|
27704
|
+
// src/workflow-hints.ts
|
|
27705
|
+
var HEADING = "## Prefer AFT tools for token efficiency";
|
|
27706
|
+
function buildWorkflowHints(opts) {
|
|
27707
|
+
const sections = [];
|
|
27708
|
+
const grepName = opts.hoistBuiltins ? "grep" : "aft_grep";
|
|
27709
|
+
const bashName = opts.hoistBuiltins ? "bash" : "aft_bash";
|
|
27710
|
+
const hasOutline = !opts.absentTools.has("aft_outline");
|
|
27711
|
+
const hasZoom = !opts.absentTools.has("aft_zoom");
|
|
27712
|
+
const hasGrep = opts.toolSurface !== "minimal" && !opts.absentTools.has(grepName);
|
|
27713
|
+
const hasSearch = opts.toolSurface !== "minimal" && opts.semanticEnabled && !opts.absentTools.has("aft_search");
|
|
27714
|
+
const hasNavigate = opts.toolSurface === "all" && !opts.absentTools.has("aft_navigate");
|
|
27715
|
+
const hasBgBash = opts.bashBackgroundEnabled && !opts.absentTools.has(bashName) && !opts.absentTools.has("bash_status");
|
|
27716
|
+
if (hasOutline && hasZoom) {
|
|
27717
|
+
sections.push(`**Web/URL access**: \`aft_outline({ url })\` first for structure, then \`aft_zoom({ url, symbol: "<heading>" })\` for the specific section.`);
|
|
27718
|
+
}
|
|
27719
|
+
if (hasOutline && hasZoom && (hasGrep || hasSearch)) {
|
|
27720
|
+
const locator = hasGrep && hasSearch ? `\`${grepName}\` or \`aft_search\`` : hasGrep ? `\`${grepName}\`` : "`aft_search`";
|
|
27721
|
+
sections.push(`**Code exploration**: ${locator} to locate → \`aft_outline\` for structure → \`aft_zoom\` for symbol(s).`);
|
|
27722
|
+
}
|
|
27723
|
+
if (hasNavigate) {
|
|
27724
|
+
sections.push([
|
|
27725
|
+
"Use `aft_navigate` instead of grep + read chains for relationship questions:",
|
|
27726
|
+
"- `callers` — find all call sites before changing a function signature",
|
|
27727
|
+
"- `impact` — blast radius (which functions/files will need updates)",
|
|
27728
|
+
"- `trace_to` — how execution reaches this code from entry points (routes, exports, main)",
|
|
27729
|
+
"- `trace_data` — follow a value through assignments and parameters across files"
|
|
27730
|
+
].join(`
|
|
27731
|
+
`));
|
|
27732
|
+
}
|
|
27733
|
+
if (hasBgBash) {
|
|
27734
|
+
sections.push(`**Long-running commands** (builds, installs, full test suites): \`${bashName}({ background: true })\` returns immediately with a \`taskId\`. Check progress with \`bash_status({ taskId })\`.`);
|
|
27735
|
+
}
|
|
27736
|
+
if (sections.length === 0) {
|
|
27737
|
+
return null;
|
|
27738
|
+
}
|
|
27739
|
+
return `${HEADING}
|
|
27740
|
+
|
|
27741
|
+
${sections.join(`
|
|
27742
|
+
|
|
27743
|
+
`)}`;
|
|
27744
|
+
}
|
|
27745
|
+
function buildHintsFromConfig(config2, absentTools, hoistBuiltins) {
|
|
27746
|
+
return buildWorkflowHints({
|
|
27747
|
+
toolSurface: config2.tool_surface ?? "recommended",
|
|
27748
|
+
hoistBuiltins,
|
|
27749
|
+
semanticEnabled: config2.semantic_search === true,
|
|
27750
|
+
bashBackgroundEnabled: config2.experimental?.bash?.background === true,
|
|
27751
|
+
absentTools
|
|
27752
|
+
});
|
|
27753
|
+
}
|
|
27754
|
+
function registerWorkflowHints(pi, config2, surface) {
|
|
27755
|
+
const absent = new Set;
|
|
27756
|
+
if (!surface.outline)
|
|
27757
|
+
absent.add("aft_outline");
|
|
27758
|
+
if (!surface.zoom)
|
|
27759
|
+
absent.add("aft_zoom");
|
|
27760
|
+
if (!surface.semantic)
|
|
27761
|
+
absent.add("aft_search");
|
|
27762
|
+
if (!surface.navigate)
|
|
27763
|
+
absent.add("aft_navigate");
|
|
27764
|
+
if (!surface.hoistGrep)
|
|
27765
|
+
absent.add("grep");
|
|
27766
|
+
if (!surface.hoistBash) {
|
|
27767
|
+
absent.add("bash");
|
|
27768
|
+
absent.add("bash_status");
|
|
27769
|
+
}
|
|
27770
|
+
const hintsBlock = buildHintsFromConfig(config2, absent, true);
|
|
27771
|
+
if (!hintsBlock)
|
|
27772
|
+
return;
|
|
27773
|
+
log(`Workflow hints injected (${hintsBlock.length} chars)`);
|
|
27774
|
+
pi.on("before_agent_start", (event) => {
|
|
27775
|
+
return { systemPrompt: `${event.systemPrompt}
|
|
27776
|
+
|
|
27777
|
+
${hintsBlock}` };
|
|
27778
|
+
});
|
|
27779
|
+
}
|
|
27780
|
+
|
|
27489
27781
|
// src/index.ts
|
|
27490
27782
|
var PLUGIN_VERSION = (() => {
|
|
27491
27783
|
try {
|
|
@@ -27531,6 +27823,7 @@ function resolveToolSurface(config2) {
|
|
|
27531
27823
|
const allOnly = (name) => ALL_ONLY_TOOLS.has(name) && ok(name);
|
|
27532
27824
|
if (surface === "minimal") {
|
|
27533
27825
|
return {
|
|
27826
|
+
hoistBash: ok("bash"),
|
|
27534
27827
|
hoistRead: false,
|
|
27535
27828
|
hoistWrite: false,
|
|
27536
27829
|
hoistEdit: false,
|
|
@@ -27552,6 +27845,7 @@ function resolveToolSurface(config2) {
|
|
|
27552
27845
|
};
|
|
27553
27846
|
}
|
|
27554
27847
|
const base = {
|
|
27848
|
+
hoistBash: ok("bash"),
|
|
27555
27849
|
hoistRead: ok("read"),
|
|
27556
27850
|
hoistWrite: ok("write"),
|
|
27557
27851
|
hoistEdit: ok("edit"),
|
|
@@ -27608,6 +27902,8 @@ async function src_default(pi) {
|
|
|
27608
27902
|
const configOverrides = {};
|
|
27609
27903
|
if (config2.format_on_edit !== undefined)
|
|
27610
27904
|
configOverrides.format_on_edit = config2.format_on_edit;
|
|
27905
|
+
if (config2.formatter_timeout_secs !== undefined)
|
|
27906
|
+
configOverrides.formatter_timeout_secs = config2.formatter_timeout_secs;
|
|
27611
27907
|
if (config2.validate_on_edit !== undefined)
|
|
27612
27908
|
configOverrides.validate_on_edit = config2.validate_on_edit;
|
|
27613
27909
|
if (config2.formatter !== undefined)
|
|
@@ -27709,6 +28005,15 @@ ${lines}
|
|
|
27709
28005
|
pluginVersion: PLUGIN_VERSION,
|
|
27710
28006
|
projectRoot
|
|
27711
28007
|
}, validWarnings);
|
|
28008
|
+
},
|
|
28009
|
+
onBashCompletion: (completion, bridge) => {
|
|
28010
|
+
handlePushedBgCompletion({
|
|
28011
|
+
ctx,
|
|
28012
|
+
directory: process.cwd(),
|
|
28013
|
+
sessionID: completion.session_id,
|
|
28014
|
+
runtime: pi,
|
|
28015
|
+
isActive: () => bridge.hasPendingRequests()
|
|
28016
|
+
}, completion);
|
|
27712
28017
|
}
|
|
27713
28018
|
}, configOverrides);
|
|
27714
28019
|
const ctx = { pool, config: config2, storageDir };
|
|
@@ -27716,7 +28021,7 @@ ${lines}
|
|
|
27716
28021
|
sendFeatureAnnouncement(ANNOUNCEMENT_VERSION, ANNOUNCEMENT_FEATURES, storageDir);
|
|
27717
28022
|
}
|
|
27718
28023
|
const surface = resolveToolSurface(config2);
|
|
27719
|
-
if (surface.
|
|
28024
|
+
if (surface.hoistBash) {
|
|
27720
28025
|
registerBashTool(pi, ctx);
|
|
27721
28026
|
}
|
|
27722
28027
|
registerHoistedTools(pi, ctx, surface);
|
|
@@ -27753,6 +28058,7 @@ ${lines}
|
|
|
27753
28058
|
if (surface.refactor) {
|
|
27754
28059
|
registerRefactorTool(pi, ctx);
|
|
27755
28060
|
}
|
|
28061
|
+
registerWorkflowHints(pi, config2, surface);
|
|
27756
28062
|
registerStatusCommand(pi, ctx);
|
|
27757
28063
|
pi.on("tool_result", async (event, extCtx) => {
|
|
27758
28064
|
const content = await appendToolResultBgCompletions({ ctx, directory: extCtx.cwd, sessionID: resolveSessionId(extCtx) }, event.content);
|
|
@@ -27791,6 +28097,8 @@ ${lines}
|
|
|
27791
28097
|
});
|
|
27792
28098
|
log(`AFT extension ready (surface=${config2.tool_surface ?? "recommended"})`);
|
|
27793
28099
|
}
|
|
28100
|
+
var __test__ = { resolveToolSurface };
|
|
27794
28101
|
export {
|
|
27795
|
-
src_default as default
|
|
28102
|
+
src_default as default,
|
|
28103
|
+
__test__
|
|
27796
28104
|
};
|
package/dist/logger.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../src/logger.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../src/logger.ts"],"names":[],"mappings":"AAmEA,wBAAgB,GAAG,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,GAAG,IAAI,CAEzD;AAED,wBAAgB,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,GAAG,IAAI,CAE1D;AAED,wBAAgB,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,GAAG,IAAI,CAE3D;AAED;;;;;GAKG;AACH,wBAAgB,UAAU,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,GAAG,IAAI,CAEnF;AAED,wBAAgB,WAAW,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,GAAG,IAAI,CAEpF;AAED,wBAAgB,YAAY,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,GAAG,IAAI,CAErF;AAED,wBAAgB,cAAc,IAAI,MAAM,CAEvC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"notifications.d.ts","sourceRoot":"","sources":["../src/notifications.ts"],"names":[],"mappings":"AAQA,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,yBAAyB,GAAG,uBAAuB,GAAG,oBAAoB,CAAC;IACjF,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,uBAAuB;IACtC,MAAM,EAAE,OAAO,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,EAAE,MAAM,CAAC;IACtB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;
|
|
1
|
+
{"version":3,"file":"notifications.d.ts","sourceRoot":"","sources":["../src/notifications.ts"],"names":[],"mappings":"AAQA,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,yBAAyB,GAAG,uBAAuB,GAAG,oBAAoB,CAAC;IACjF,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,uBAAuB;IACtC,MAAM,EAAE,OAAO,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,EAAE,MAAM,CAAC;IACtB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AA8FD,wBAAsB,wBAAwB,CAC5C,IAAI,EAAE,uBAAuB,EAC7B,QAAQ,EAAE,gBAAgB,EAAE,GAC3B,OAAO,CAAC,IAAI,CAAC,CAqBf;AAED,wBAAgB,uBAAuB,CACrC,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,MAAM,EAAE,EAClB,UAAU,EAAE,MAAM,GACjB,IAAI,CAqBN"}
|
package/dist/pool.d.ts
CHANGED
|
@@ -22,6 +22,8 @@ export declare class BridgePool {
|
|
|
22
22
|
constructor(binaryPath: string, options?: PoolOptions, configOverrides?: Record<string, unknown>);
|
|
23
23
|
/** Get any existing alive bridge, preferring the given directory. */
|
|
24
24
|
getAnyActiveBridge(directory: string): BinaryBridge | null;
|
|
25
|
+
/** Get an alive bridge only when it belongs to the requested directory. */
|
|
26
|
+
getActiveBridgeForRoot(directory: string): BinaryBridge | null;
|
|
25
27
|
/** Get or create a bridge for the given directory. */
|
|
26
28
|
getBridge(directory: string): BinaryBridge;
|
|
27
29
|
private cleanup;
|
package/dist/pool.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pool.d.ts","sourceRoot":"","sources":["../src/pool.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,KAAK,aAAa,EAAE,MAAM,aAAa,CAAC;AAY/D,MAAM,WAAW,WAAY,SAAQ,aAAa;IAChD,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED;;;;;;;GAOG;AACH,qBAAa,UAAU;IACrB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAgC;IACxD,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAS;IACrC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAS;IACvC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAgB;IAC9C,OAAO,CAAC,QAAQ,CAAC,eAAe,CAA0B;IAC1D,OAAO,CAAC,YAAY,CAA+C;gBAGjE,UAAU,EAAE,MAAM,EAClB,OAAO,GAAE,WAAgB,EACzB,eAAe,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM;
|
|
1
|
+
{"version":3,"file":"pool.d.ts","sourceRoot":"","sources":["../src/pool.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,KAAK,aAAa,EAAE,MAAM,aAAa,CAAC;AAY/D,MAAM,WAAW,WAAY,SAAQ,aAAa;IAChD,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED;;;;;;;GAOG;AACH,qBAAa,UAAU;IACrB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAgC;IACxD,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAS;IACrC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAS;IACvC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAgB;IAC9C,OAAO,CAAC,QAAQ,CAAC,eAAe,CAA0B;IAC1D,OAAO,CAAC,YAAY,CAA+C;gBAGjE,UAAU,EAAE,MAAM,EAClB,OAAO,GAAE,WAAgB,EACzB,eAAe,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM;IAoB/C,qEAAqE;IACrE,kBAAkB,CAAC,SAAS,EAAE,MAAM,GAAG,YAAY,GAAG,IAAI;IAgB1D,2EAA2E;IAC3E,sBAAsB,CAAC,SAAS,EAAE,MAAM,GAAG,YAAY,GAAG,IAAI;IAQ9D,sDAAsD;IACtD,SAAS,CAAC,SAAS,EAAE,MAAM,GAAG,YAAY;IAiB1C,OAAO,CAAC,OAAO;IAUf,OAAO,CAAC,QAAQ;IAgBV,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IAUzB,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAQnD,IAAI,IAAI,IAAI,MAAM,CAEjB;CACF"}
|
package/dist/tools/bash.d.ts
CHANGED
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":"AAAA,OAAO,KAAK,EACV,eAAe,EACf,YAAY,EACZ,gBAAgB,EAEjB,MAAM,+BAA+B,CAAC;AAEvC,OAAO,EAAE,KAAK,MAAM,EAAQ,MAAM,mBAAmB,CAAC;AAEtD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AA2DjD,QAAA,MAAM,cAAc;;EAIlB,CAAC;AAWH,UAAU,iBAAiB;IACzB,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,UAAU,eAAe;IACvB,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;CAChB;AAsCD,wBAAgB,gBAAgB,CAAC,EAAE,EAAE,YAAY,EAAE,GAAG,EAAE,aAAa,GAAG,IAAI,
|
|
1
|
+
{"version":3,"file":"bash.d.ts","sourceRoot":"","sources":["../../src/tools/bash.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,eAAe,EACf,YAAY,EACZ,gBAAgB,EAEjB,MAAM,+BAA+B,CAAC;AAEvC,OAAO,EAAE,KAAK,MAAM,EAAQ,MAAM,mBAAmB,CAAC;AAEtD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AA2DjD,QAAA,MAAM,cAAc;;EAIlB,CAAC;AAWH,UAAU,iBAAiB;IACzB,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,UAAU,eAAe;IACvB,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;CAChB;AAsCD,wBAAgB,gBAAgB,CAAC,EAAE,EAAE,YAAY,EAAE,GAAG,EAAE,aAAa,GAAG,IAAI,CA2G3E;AAOD,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,aAAa;;;;;;;;yBASpC,MAAM,UACX,MAAM,CAAC,OAAO,cAAc,CAAC,WAC5B,WAAW,GAAG,SAAS,aACrB,CAAC,CAAC,MAAM,EAAE,eAAe,CAAC,iBAAiB,CAAC,KAAK,IAAI,CAAC,GAAG,SAAS,UACrE,gBAAgB;EAW7B;AAED,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,aAAa;;;;;;;;yBASlC,MAAM,UACX,MAAM,CAAC,OAAO,cAAc,CAAC,WAC5B,WAAW,GAAG,SAAS,aACrB,CAAC,CAAC,MAAM,EAAE,eAAe,CAAC,eAAe,CAAC,KAAK,IAAI,CAAC,GAAG,SAAS,UACnE,gBAAgB;EAW7B"}
|
package/dist/tools/hoisted.d.ts
CHANGED
|
@@ -39,6 +39,22 @@ interface FileMutationDetails {
|
|
|
39
39
|
* surface this explicitly rather than silently showing a summary.
|
|
40
40
|
*/
|
|
41
41
|
truncated?: boolean;
|
|
42
|
+
/**
|
|
43
|
+
* Whether AFT's auto-formatter ran on the post-write content. Mirrors the
|
|
44
|
+
* `data.formatted` field from the Rust write/edit response. When true,
|
|
45
|
+
* the file content on disk is what the formatter produced; when false,
|
|
46
|
+
* `formatSkippedReason` explains why.
|
|
47
|
+
*/
|
|
48
|
+
formatted?: boolean;
|
|
49
|
+
/**
|
|
50
|
+
* Reason the formatter was skipped, when `formatted=false`. One of the
|
|
51
|
+
* documented values from `crates/aft/src/format.rs::auto_format`:
|
|
52
|
+
* `"unsupported_language"`, `"no_formatter_configured"`,
|
|
53
|
+
* `"formatter_not_installed"`, `"formatter_excluded_path"`, `"timeout"`,
|
|
54
|
+
* `"error"`. Pi agents read this to decide whether to retry, fix config,
|
|
55
|
+
* or accept the unformatted result.
|
|
56
|
+
*/
|
|
57
|
+
formatSkippedReason?: string;
|
|
42
58
|
}
|
|
43
59
|
export declare function registerHoistedTools(pi: ExtensionAPI, ctx: PluginContext, surface: ToolSurfaceFlags): void;
|
|
44
60
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hoisted.d.ts","sourceRoot":"","sources":["../../src/tools/hoisted.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAKH,OAAO,EACL,KAAK,eAAe,EACpB,KAAK,YAAY,EAGlB,MAAM,+BAA+B,CAAC;AAGvC,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AA2DjD,MAAM,WAAW,gBAAgB;IAC/B,SAAS,EAAE,OAAO,CAAC;IACnB,UAAU,EAAE,OAAO,CAAC;IACpB,SAAS,EAAE,OAAO,CAAC;IACnB,SAAS,EAAE,OAAO,CAAC;CACpB;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;
|
|
1
|
+
{"version":3,"file":"hoisted.d.ts","sourceRoot":"","sources":["../../src/tools/hoisted.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAKH,OAAO,EACL,KAAK,eAAe,EACpB,KAAK,YAAY,EAGlB,MAAM,+BAA+B,CAAC;AAGvC,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AA2DjD,MAAM,WAAW,gBAAgB;IAC/B,SAAS,EAAE,OAAO,CAAC;IACnB,UAAU,EAAE,OAAO,CAAC;IACpB,SAAS,EAAE,OAAO,CAAC;IACnB,SAAS,EAAE,OAAO,CAAC;CACpB;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;CAC9B;AAED,wBAAgB,oBAAoB,CAClC,EAAE,EAAE,YAAY,EAChB,GAAG,EAAE,aAAa,EAClB,OAAO,EAAE,gBAAgB,GACxB,IAAI,CAmLN;AAMD;;;;GAIG;AACH,wBAAgB,mBAAmB,CACjC,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAChC,eAAe,CAAC,mBAAmB,CAAC,CAiFtC;AAwJD;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAC9B,mBAAmB,EAAE,OAAO,EAC5B,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC5B,MAAM,CAgBR"}
|
package/dist/tools/reading.d.ts
CHANGED
|
@@ -21,6 +21,17 @@ export interface ReadingSurface {
|
|
|
21
21
|
outline: boolean;
|
|
22
22
|
zoom: boolean;
|
|
23
23
|
}
|
|
24
|
+
interface ZoomBatchSymbolResult {
|
|
25
|
+
name: string;
|
|
26
|
+
success: boolean;
|
|
27
|
+
content?: string;
|
|
28
|
+
error?: string;
|
|
29
|
+
}
|
|
30
|
+
interface ZoomBatchResult {
|
|
31
|
+
complete: boolean;
|
|
32
|
+
symbols: ZoomBatchSymbolResult[];
|
|
33
|
+
text: string;
|
|
34
|
+
}
|
|
24
35
|
/** Exported for renderer unit tests. */
|
|
25
36
|
export declare function buildOutlineSections(text: string, theme: Theme): string[];
|
|
26
37
|
/** Exported for renderer unit tests. */
|
|
@@ -34,5 +45,7 @@ export declare function renderZoomCall(args: Static<typeof ZoomParams>, theme: T
|
|
|
34
45
|
/** Exported for renderer unit tests. */
|
|
35
46
|
export declare function renderZoomResult(result: AgentToolResult<unknown>, args: Static<typeof ZoomParams>, theme: Theme, context: RenderContextLike): import("@mariozechner/pi-tui").Text | import("@mariozechner/pi-tui").Container;
|
|
36
47
|
export declare function registerReadingTools(pi: ExtensionAPI, ctx: PluginContext, surface: ReadingSurface): void;
|
|
48
|
+
/** Exported for regression tests. */
|
|
49
|
+
export declare function formatZoomBatchResult(symbols: string[], responses: Record<string, unknown>[]): ZoomBatchResult;
|
|
37
50
|
export {};
|
|
38
51
|
//# sourceMappingURL=reading.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"reading.d.ts","sourceRoot":"","sources":["../../src/tools/reading.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,OAAO,KAAK,EAAE,eAAe,EAAE,YAAY,EAAE,KAAK,EAAE,MAAM,+BAA+B,CAAC;AAC1F,OAAO,EAAE,KAAK,MAAM,EAAQ,MAAM,mBAAmB,CAAC;AAEtD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAEjD,OAAO,EAOL,KAAK,iBAAiB,EAKvB,MAAM,qBAAqB,CAAC;AAE7B,QAAA,MAAM,aAAa;;;;EAYjB,CAAC;AAEH,QAAA,MAAM,UAAU;;;;;EAWd,CAAC;AAEH,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,EAAE,OAAO,CAAC;CACf;AAED,wCAAwC;AACxC,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,GAAG,MAAM,EAAE,CAOzE;AAED,wCAAwC;AACxC,wBAAgB,iBAAiB,CAC/B,IAAI,EAAE,MAAM,CAAC,OAAO,UAAU,CAAC,EAC/B,OAAO,EAAE,OAAO,EAChB,KAAK,EAAE,KAAK,GACX,MAAM,EAAE,
|
|
1
|
+
{"version":3,"file":"reading.d.ts","sourceRoot":"","sources":["../../src/tools/reading.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,OAAO,KAAK,EAAE,eAAe,EAAE,YAAY,EAAE,KAAK,EAAE,MAAM,+BAA+B,CAAC;AAC1F,OAAO,EAAE,KAAK,MAAM,EAAQ,MAAM,mBAAmB,CAAC;AAEtD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAEjD,OAAO,EAOL,KAAK,iBAAiB,EAKvB,MAAM,qBAAqB,CAAC;AAE7B,QAAA,MAAM,aAAa;;;;EAYjB,CAAC;AAEH,QAAA,MAAM,UAAU;;;;;EAWd,CAAC;AAEH,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,EAAE,OAAO,CAAC;CACf;AAED,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,wCAAwC;AACxC,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,GAAG,MAAM,EAAE,CAOzE;AAED,wCAAwC;AACxC,wBAAgB,iBAAiB,CAC/B,IAAI,EAAE,MAAM,CAAC,OAAO,UAAU,CAAC,EAC/B,OAAO,EAAE,OAAO,EAChB,KAAK,EAAE,KAAK,GACX,MAAM,EAAE,CAuFV;AAED,wCAAwC;AACxC,wBAAgB,iBAAiB,CAC/B,IAAI,EAAE,MAAM,CAAC,OAAO,aAAa,CAAC,EAClC,KAAK,EAAE,KAAK,EACZ,OAAO,EAAE,iBAAiB,uCAU3B;AAED,wCAAwC;AACxC,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,eAAe,CAAC,OAAO,CAAC,EAChC,KAAK,EAAE,KAAK,EACZ,OAAO,EAAE,iBAAiB,kFAI3B;AAED,wCAAwC;AACxC,wBAAgB,cAAc,CAC5B,IAAI,EAAE,MAAM,CAAC,OAAO,UAAU,CAAC,EAC/B,KAAK,EAAE,KAAK,EACZ,OAAO,EAAE,iBAAiB,uCAQ3B;AAED,wCAAwC;AACxC,wBAAgB,gBAAgB,CAC9B,MAAM,EAAE,eAAe,CAAC,OAAO,CAAC,EAChC,IAAI,EAAE,MAAM,CAAC,OAAO,UAAU,CAAC,EAC/B,KAAK,EAAE,KAAK,EACZ,OAAO,EAAE,iBAAiB,kFAI3B;AAED,wBAAgB,oBAAoB,CAClC,EAAE,EAAE,YAAY,EAChB,GAAG,EAAE,aAAa,EAClB,OAAO,EAAE,cAAc,GACtB,IAAI,CAsHN;AAED,qCAAqC;AACrC,wBAAgB,qBAAqB,CACnC,OAAO,EAAE,MAAM,EAAE,EACjB,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,GACnC,eAAe,CA0BjB"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { ExtensionAPI } from "@mariozechner/pi-coding-agent";
|
|
2
|
+
import type { AftConfig } from "./config.js";
|
|
3
|
+
export interface WorkflowHintsOpts {
|
|
4
|
+
toolSurface: "minimal" | "recommended" | "all";
|
|
5
|
+
hoistBuiltins: boolean;
|
|
6
|
+
semanticEnabled: boolean;
|
|
7
|
+
bashBackgroundEnabled: boolean;
|
|
8
|
+
/** Set of tool names KNOWN-ABSENT from the registered surface. */
|
|
9
|
+
absentTools: Set<string>;
|
|
10
|
+
}
|
|
11
|
+
export declare function buildWorkflowHints(opts: WorkflowHintsOpts): string | null;
|
|
12
|
+
export declare function buildHintsFromConfig(config: AftConfig, absentTools: Set<string>, hoistBuiltins: boolean): string | null;
|
|
13
|
+
interface ToolSurfaceFlags {
|
|
14
|
+
outline: boolean;
|
|
15
|
+
zoom: boolean;
|
|
16
|
+
semantic: boolean;
|
|
17
|
+
navigate: boolean;
|
|
18
|
+
hoistGrep: boolean;
|
|
19
|
+
hoistBash: boolean;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Register the workflow-hints extension on Pi via `before_agent_start`.
|
|
23
|
+
*
|
|
24
|
+
* Pi assembles a fresh system prompt for every turn, then fires
|
|
25
|
+
* `before_agent_start` with the assembled prompt. Our handler appends the
|
|
26
|
+
* AFT workflow hints block to that prompt. If multiple extensions return a
|
|
27
|
+
* `systemPrompt`, Pi chains them — so we always append (never replace).
|
|
28
|
+
*/
|
|
29
|
+
export declare function registerWorkflowHints(pi: ExtensionAPI, config: AftConfig, surface: ToolSurfaceFlags): void;
|
|
30
|
+
export {};
|
|
31
|
+
//# sourceMappingURL=workflow-hints.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"workflow-hints.d.ts","sourceRoot":"","sources":["../src/workflow-hints.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AAClE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAG7C,MAAM,WAAW,iBAAiB;IAChC,WAAW,EAAE,SAAS,GAAG,aAAa,GAAG,KAAK,CAAC;IAC/C,aAAa,EAAE,OAAO,CAAC;IACvB,eAAe,EAAE,OAAO,CAAC;IACzB,qBAAqB,EAAE,OAAO,CAAC;IAC/B,kEAAkE;IAClE,WAAW,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;CAC1B;AAID,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,iBAAiB,GAAG,MAAM,GAAG,IAAI,CA8DzE;AAED,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,SAAS,EACjB,WAAW,EAAE,GAAG,CAAC,MAAM,CAAC,EACxB,aAAa,EAAE,OAAO,GACrB,MAAM,GAAG,IAAI,CAQf;AAMD,UAAU,gBAAgB;IACxB,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,EAAE,OAAO,CAAC;IACd,QAAQ,EAAE,OAAO,CAAC;IAClB,QAAQ,EAAE,OAAO,CAAC;IAClB,SAAS,EAAE,OAAO,CAAC;IACnB,SAAS,EAAE,OAAO,CAAC;CACpB;AAED;;;;;;;GAOG;AACH,wBAAgB,qBAAqB,CACnC,EAAE,EAAE,YAAY,EAChB,MAAM,EAAE,SAAS,EACjB,OAAO,EAAE,gBAAgB,GACxB,IAAI,CA8BN"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cortexkit/aft-pi",
|
|
3
|
-
"version": "0.18.
|
|
3
|
+
"version": "0.18.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",
|
|
@@ -18,6 +18,7 @@
|
|
|
18
18
|
"build": "bun build src/index.ts --outdir dist --target node --format esm --external @mariozechner/pi-coding-agent --external @mariozechner/pi-ai --external @mariozechner/pi-tui --external @sinclair/typebox --external diff && tsc --emitDeclarationOnly",
|
|
19
19
|
"typecheck": "tsc --noEmit",
|
|
20
20
|
"test": "bun test src/__tests__/",
|
|
21
|
+
"lint": "biome check src",
|
|
21
22
|
"prepublishOnly": "bun run build"
|
|
22
23
|
},
|
|
23
24
|
"dependencies": {
|
|
@@ -27,11 +28,11 @@
|
|
|
27
28
|
"zod": "^4.1.8"
|
|
28
29
|
},
|
|
29
30
|
"optionalDependencies": {
|
|
30
|
-
"@cortexkit/aft-darwin-arm64": "0.18.
|
|
31
|
-
"@cortexkit/aft-darwin-x64": "0.18.
|
|
32
|
-
"@cortexkit/aft-linux-arm64": "0.18.
|
|
33
|
-
"@cortexkit/aft-linux-x64": "0.18.
|
|
34
|
-
"@cortexkit/aft-win32-x64": "0.18.
|
|
31
|
+
"@cortexkit/aft-darwin-arm64": "0.18.4",
|
|
32
|
+
"@cortexkit/aft-darwin-x64": "0.18.4",
|
|
33
|
+
"@cortexkit/aft-linux-arm64": "0.18.4",
|
|
34
|
+
"@cortexkit/aft-linux-x64": "0.18.4",
|
|
35
|
+
"@cortexkit/aft-win32-x64": "0.18.4"
|
|
35
36
|
},
|
|
36
37
|
"devDependencies": {
|
|
37
38
|
"@mariozechner/pi-coding-agent": "*",
|