@herbertgao/pi-extensions 2026.8.5 → 2026.8.6
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/README.md +5 -5
- package/node_modules/@herbertgao/pi-cc-extensions/README.en.md +1 -1
- package/node_modules/@herbertgao/pi-cc-extensions/README.md +1 -1
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/feature/context.ts +74 -5
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/markdown-enhance.ts +48 -6
- package/node_modules/@herbertgao/pi-cc-extensions/package.json +3 -3
- package/node_modules/@herbertgao/pi-subagents/CHANGELOG.md +10 -0
- package/node_modules/@herbertgao/pi-subagents/package.json +3 -3
- package/node_modules/@herbertgao/pi-subagents/src/agent-runner.ts +5 -2
- package/node_modules/@herbertgao/pi-subagents/src/ui/fleet-list.ts +15 -6
- package/node_modules/@herbertgao/pi-subagents/src/worktree.ts +9 -5
- package/node_modules/@juicesharp/rpiv-ask-user-question/README.md +2 -0
- package/node_modules/@juicesharp/rpiv-ask-user-question/ask-user-question.ts +20 -0
- package/node_modules/@juicesharp/rpiv-ask-user-question/docs/hosts.md +6 -0
- package/node_modules/@juicesharp/rpiv-ask-user-question/package.json +2 -2
- package/node_modules/@narumitw/pi-btw/README.md +24 -17
- package/node_modules/@narumitw/pi-btw/package.json +5 -5
- package/node_modules/@narumitw/pi-btw/src/btw.ts +4 -2
- package/node_modules/@narumitw/pi-btw/src/menu.ts +33 -13
- package/node_modules/@narumitw/pi-btw/src/settings.ts +22 -2
- package/node_modules/pi-lens/CHANGELOG.md +95 -0
- package/node_modules/pi-lens/dist/clients/advisory-provenance.js +314 -0
- package/node_modules/pi-lens/dist/clients/agent-nudge.js +14 -7
- package/node_modules/pi-lens/dist/clients/biome-client.js +121 -13
- package/node_modules/pi-lens/dist/clients/bus-events-logger.js +62 -6
- package/node_modules/pi-lens/dist/clients/bus-publish.js +11 -3
- package/node_modules/pi-lens/dist/clients/cascade-format.js +57 -2
- package/node_modules/pi-lens/dist/clients/console-guard-install.js +16 -4
- package/node_modules/pi-lens/dist/clients/dead-code-client.js +135 -30
- package/node_modules/pi-lens/dist/clients/dependency-checker.js +19 -7
- package/node_modules/pi-lens/dist/clients/diagnostic-dispositions.js +6 -4
- package/node_modules/pi-lens/dist/clients/diagnostics-publish.js +10 -3
- package/node_modules/pi-lens/dist/clients/dispatch/dispatcher.js +114 -10
- package/node_modules/pi-lens/dist/clients/dispatch/integration.js +101 -16
- package/node_modules/pi-lens/dist/clients/dispatch/runners/lsp.js +37 -4
- package/node_modules/pi-lens/dist/clients/dispatch/runners/utils/availability-policy.js +226 -0
- package/node_modules/pi-lens/dist/clients/dispatch/runners/utils/candidate-probe.js +69 -0
- package/node_modules/pi-lens/dist/clients/dispatch/runners/utils/runner-helpers.js +230 -50
- package/node_modules/pi-lens/dist/clients/dispatch/runners/utils/toolchain-availability.js +97 -0
- package/node_modules/pi-lens/dist/clients/disposition-publish.js +10 -3
- package/node_modules/pi-lens/dist/clients/eval-timestamp.js +17 -0
- package/node_modules/pi-lens/dist/clients/extension-log.js +296 -3
- package/node_modules/pi-lens/dist/clients/fix-worklog.js +5 -1
- package/node_modules/pi-lens/dist/clients/format-events-publish.js +39 -8
- package/node_modules/pi-lens/dist/clients/git-guard.js +18 -21
- package/node_modules/pi-lens/dist/clients/go-client.js +21 -39
- package/node_modules/pi-lens/dist/clients/govulncheck-client.js +116 -7
- package/node_modules/pi-lens/dist/clients/host-ports.js +1 -1
- package/node_modules/pi-lens/dist/clients/installer/index.js +5 -1
- package/node_modules/pi-lens/dist/clients/jscpd-client.js +4 -9
- package/node_modules/pi-lens/dist/clients/knip-client.js +51 -14
- package/node_modules/pi-lens/dist/clients/latency-logger.js +50 -1
- package/node_modules/pi-lens/dist/clients/lens-events.js +56 -25
- package/node_modules/pi-lens/dist/clients/lens-flag-registry.js +8 -0
- package/node_modules/pi-lens/dist/clients/live-bus-emitter.js +45 -2
- package/node_modules/pi-lens/dist/clients/lsp/aggregation.js +30 -4
- package/node_modules/pi-lens/dist/clients/lsp/cascade-tier.js +58 -13
- package/node_modules/pi-lens/dist/clients/lsp/client.js +169 -8
- package/node_modules/pi-lens/dist/clients/lsp/diagnostic-binding.js +29 -0
- package/node_modules/pi-lens/dist/clients/lsp/index.js +264 -66
- package/node_modules/pi-lens/dist/clients/lsp/server.js +247 -60
- package/node_modules/pi-lens/dist/clients/lsp/tsserver-sync.js +96 -0
- package/node_modules/pi-lens/dist/clients/lsp/wait-policy/classification.js +21 -5
- package/node_modules/pi-lens/dist/clients/lsp/wait-policy/strategies.js +18 -3
- package/node_modules/pi-lens/dist/clients/mcp/analyze.js +4 -0
- package/node_modules/pi-lens/dist/clients/mcp/session.js +30 -17
- package/node_modules/pi-lens/dist/clients/model-provider.js +53 -0
- package/node_modules/pi-lens/dist/clients/pipeline.js +29 -2
- package/node_modules/pi-lens/dist/clients/project-diagnostics/fresh-fetch.js +1 -1
- package/node_modules/pi-lens/dist/clients/project-diagnostics/runner-adapters/runner-findings.js +23 -2
- package/node_modules/pi-lens/dist/clients/review-graph/query.js +24 -0
- package/node_modules/pi-lens/dist/clients/run-duration.js +55 -0
- package/node_modules/pi-lens/dist/clients/runtime-agent-end.js +153 -7
- package/node_modules/pi-lens/dist/clients/runtime-context.js +104 -11
- package/node_modules/pi-lens/dist/clients/runtime-coordinator.js +170 -22
- package/node_modules/pi-lens/dist/clients/runtime-session.js +28 -5
- package/node_modules/pi-lens/dist/clients/runtime-tool-result.js +124 -10
- package/node_modules/pi-lens/dist/clients/runtime-turn.js +388 -35
- package/node_modules/pi-lens/dist/clients/rust-client.js +21 -37
- package/node_modules/pi-lens/dist/clients/security-scan-client.js +88 -5
- package/node_modules/pi-lens/dist/clients/sg-runner.js +141 -23
- package/node_modules/pi-lens/dist/clients/smells-rollup.js +18 -11
- package/node_modules/pi-lens/dist/clients/startup-timing.js +7 -1
- package/node_modules/pi-lens/dist/clients/test-runner-client.js +431 -24
- package/node_modules/pi-lens/dist/clients/tool-policy.js +2 -0
- package/node_modules/pi-lens/dist/clients/tool-set-policy.js +76 -0
- package/node_modules/pi-lens/dist/clients/warm-attach.js +17 -0
- package/node_modules/pi-lens/dist/clients/word-index.js +305 -33
- package/node_modules/pi-lens/dist/index.js +4827 -1633
- package/node_modules/pi-lens/dist/mcp/server.js +8 -2
- package/node_modules/pi-lens/dist/tools/activate-tools.js +17 -5
- package/node_modules/pi-lens/dist/tools/ast-grep-replace.js +9 -4
- package/node_modules/pi-lens/dist/tools/lens-diagnostic-mark.js +5 -2
- package/node_modules/pi-lens/dist/tools/lens-diagnostics.js +3 -2
- package/node_modules/pi-lens/dist/tools/lsp-diagnostics.js +62 -7
- package/node_modules/pi-lens/dist/tools/symbol-search.js +1 -1
- package/node_modules/pi-lens/docs/agent-guide.md +38 -13
- package/node_modules/pi-lens/docs/ast-grep_rules_catalog.md +11 -3
- package/node_modules/pi-lens/docs/features.md +14 -1
- package/node_modules/pi-lens/docs/globalconfig.md +11 -0
- package/node_modules/pi-lens/docs/servercapabilities.md +1 -1
- package/node_modules/pi-lens/docs/settings.md +6 -0
- package/node_modules/pi-lens/docs/usage.md +23 -5
- package/node_modules/pi-lens/docs/word-index.md +35 -0
- package/node_modules/pi-lens/package.json +1 -1
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-chained-type-assertions-test.yml +8 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-conditional-empty-object-spread-js-test.yml +9 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-conditional-empty-object-spread-test.yml +9 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-reflect-apply-js-test.yml +7 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-reflect-apply-test.yml +7 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-reflect-get-js-test.yml +8 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-reflect-get-test.yml +8 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-unknown-laundering-test.yml +11 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-chained-type-assertions.yml +21 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-conditional-empty-object-spread-js.yml +21 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-conditional-empty-object-spread.yml +29 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-reflect-apply-js.yml +9 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-reflect-apply.yml +9 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-reflect-get-js.yml +13 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-reflect-get.yml +16 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-unknown-laundering.yml +27 -0
- package/node_modules/pi-lens/scripts/analyze-pi-lens-logs.mjs +79 -0
- package/node_modules/pi-lens/skills/pi-lens-ast-grep/SKILL.md +10 -11
- package/node_modules/pi-lens/skills/pi-lens-lsp-navigation/SKILL.md +22 -22
- package/node_modules/pi-lens/skills/pi-lens-write-ast-grep-rule/SKILL.md +8 -114
- package/node_modules/pi-lens/skills/pi-lens-write-ast-grep-rule/reference.md +129 -0
- package/node_modules/pi-lens/skills/pi-lens-write-tree-sitter-rule/SKILL.md +3 -1
- package/node_modules/pi-mcp-adapter/CHANGELOG.md +13 -0
- package/node_modules/pi-mcp-adapter/README.md +4 -1
- package/node_modules/pi-mcp-adapter/agent-dir.ts +12 -4
- package/node_modules/pi-mcp-adapter/cli.js +25 -4
- package/node_modules/pi-mcp-adapter/config.ts +4 -4
- package/node_modules/pi-mcp-adapter/direct-tools.ts +18 -15
- package/node_modules/pi-mcp-adapter/mcp-setup-panel.ts +2 -1
- package/node_modules/pi-mcp-adapter/metadata-cache.ts +18 -8
- package/node_modules/pi-mcp-adapter/package.json +2 -1
- package/node_modules/pi-mcp-adapter/request-headers-command.ts +336 -0
- package/node_modules/pi-mcp-adapter/server-manager.ts +5 -0
- package/node_modules/pi-mcp-adapter/tool-metadata.ts +38 -18
- package/node_modules/pi-mcp-adapter/types.ts +93 -10
- package/node_modules/pi-web-access/CHANGELOG.md +14 -0
- package/node_modules/pi-web-access/README.md +18 -12
- package/node_modules/pi-web-access/auth-fetch.ts +148 -0
- package/node_modules/pi-web-access/chrome-cookies.ts +110 -23
- package/node_modules/pi-web-access/curator-page.ts +5 -3
- package/node_modules/pi-web-access/curator-server.ts +2 -1
- package/node_modules/pi-web-access/extract.ts +106 -34
- package/node_modules/pi-web-access/fetch-params.ts +17 -3
- package/node_modules/pi-web-access/firecrawl.ts +172 -12
- package/node_modules/pi-web-access/gemini-search.ts +18 -4
- package/node_modules/pi-web-access/index.ts +120 -48
- package/node_modules/pi-web-access/package.json +2 -2
- package/node_modules/pi-web-access/summary-review.ts +11 -5
- package/node_modules/pi-web-access/youtube-extract.ts +2 -2
- package/package.json +9 -9
|
@@ -16,6 +16,8 @@ import { runPipeline } from "./pipeline.js";
|
|
|
16
16
|
import { appendProjectChange, } from "./project-changes.js";
|
|
17
17
|
import { syncGitGuardRecord } from "./git-guard.js";
|
|
18
18
|
import { scheduleWordIndexPersist } from "./word-index.js";
|
|
19
|
+
import { RUNTIME_CONFIG } from "./runtime-config.js";
|
|
20
|
+
const AUTHORITATIVE_CONTENT_MAX_BYTES = RUNTIME_CONFIG.pipeline.lspMaxFileBytes;
|
|
19
21
|
function parseDiffRanges(diff) {
|
|
20
22
|
const changedLines = [];
|
|
21
23
|
for (const line of diff.split("\n")) {
|
|
@@ -207,6 +209,8 @@ export async function handleToolResult(deps) {
|
|
|
207
209
|
: path.resolve(workspaceRoot, rawFilePath)
|
|
208
210
|
: rawFilePath;
|
|
209
211
|
const behaviorWarnings = agentBehaviorRecord(event.toolName, filePath);
|
|
212
|
+
const syntheticWriteContent = [];
|
|
213
|
+
let syntheticAttachmentBytes = 0;
|
|
210
214
|
// Bash writes (redirects, tee, sed -i, cp/mv, touch, git checkout/restore) —
|
|
211
215
|
// these change file content but never go through the edit tool, so bash
|
|
212
216
|
// early-returns before the dispatch pipeline below. For each in-project file
|
|
@@ -224,11 +228,59 @@ export async function handleToolResult(deps) {
|
|
|
224
228
|
for (const wp of written) {
|
|
225
229
|
if (!getFlag("no-read-guard"))
|
|
226
230
|
deps.readGuard?.recordWritten(wp);
|
|
227
|
-
|
|
231
|
+
const receipt = runtime.recordMutationToolReceipt;
|
|
232
|
+
const autofixMode = receipt
|
|
233
|
+
? receipt.call(runtime, wp, "write").autofixMode
|
|
234
|
+
: "immediate";
|
|
235
|
+
const syntheticResult = await handleToolResult({
|
|
228
236
|
...deps,
|
|
229
237
|
event: { ...event, toolName: "write", input: { path: wp } },
|
|
230
238
|
_bypassDebounce: true,
|
|
239
|
+
_autofixMode: autofixMode,
|
|
231
240
|
});
|
|
241
|
+
if (syntheticResult) {
|
|
242
|
+
// The per-attachment cap bounds each file, but a multi-file bash
|
|
243
|
+
// write (`sed -i` over globs, `;`-chained rewrites) appends one
|
|
244
|
+
// attachment per path — share ONE authoritative-content budget
|
|
245
|
+
// across the whole command so the aggregate tool result stays
|
|
246
|
+
// bounded too. Past the budget, degrade to the re-read warning.
|
|
247
|
+
for (const block of syntheticResult.content.slice(event.content.length)) {
|
|
248
|
+
const blockBytes = typeof block.text === "string"
|
|
249
|
+
? Buffer.byteLength(block.text, "utf-8")
|
|
250
|
+
: 0;
|
|
251
|
+
const isAuthoritativeAttachment = typeof block.text === "string" &&
|
|
252
|
+
block.text.startsWith("pi-lens applied autofix to ");
|
|
253
|
+
if (isAuthoritativeAttachment &&
|
|
254
|
+
syntheticAttachmentBytes + blockBytes >
|
|
255
|
+
AUTHORITATIVE_CONTENT_MAX_BYTES) {
|
|
256
|
+
// S3e (#1432 review): this is the SECOND
|
|
257
|
+
// `authoritative_content_attachment_decision` row for `wp` —
|
|
258
|
+
// the synthetic `handleToolResult` call above already logged
|
|
259
|
+
// an "attached" row for the same path under its per-file
|
|
260
|
+
// cap. This outer, aggregate-budget row is logged later and
|
|
261
|
+
// is the one that matches what the caller actually sees
|
|
262
|
+
// (the re-read warning below, not the attachment), so it
|
|
263
|
+
// wins for `wp`; the inner "attached" row is a stale
|
|
264
|
+
// per-file view superseded by this shared-budget decision.
|
|
265
|
+
logLatency({
|
|
266
|
+
type: "phase",
|
|
267
|
+
phase: "authoritative_content_attachment_decision",
|
|
268
|
+
filePath: wp,
|
|
269
|
+
durationMs: 0,
|
|
270
|
+
metadata: { path: wp, bytes: blockBytes, decision: "aggregate-budget-degraded" },
|
|
271
|
+
});
|
|
272
|
+
syntheticWriteContent.push({
|
|
273
|
+
type: "text",
|
|
274
|
+
text: `⚠️ **File was modified by auto-format/fix. You MUST re-read ${wp} before making any further edits — the aggregate authoritative content for this command is too large to attach.**`,
|
|
275
|
+
});
|
|
276
|
+
continue;
|
|
277
|
+
}
|
|
278
|
+
if (isAuthoritativeAttachment) {
|
|
279
|
+
syntheticAttachmentBytes += blockBytes;
|
|
280
|
+
}
|
|
281
|
+
syntheticWriteContent.push(block);
|
|
282
|
+
}
|
|
283
|
+
}
|
|
232
284
|
}
|
|
233
285
|
if (event.isError !== true && !getFlag("no-read-guard")) {
|
|
234
286
|
for (const span of extractReadPathsFromCommand(command, workspaceRoot)) {
|
|
@@ -277,7 +329,9 @@ export async function handleToolResult(deps) {
|
|
|
277
329
|
}
|
|
278
330
|
if (event.toolName !== "write" && event.toolName !== "edit") {
|
|
279
331
|
dbg(`tool_result: skipped turn tracking - toolName="${event.toolName}" (not write/edit)`);
|
|
280
|
-
return
|
|
332
|
+
return syntheticWriteContent.length > 0
|
|
333
|
+
? { content: [...event.content, ...syntheticWriteContent] }
|
|
334
|
+
: undefined;
|
|
281
335
|
}
|
|
282
336
|
if (!filePath) {
|
|
283
337
|
dbg(`tool_result: skipped turn tracking - no filePath for toolName="${event.toolName}"`);
|
|
@@ -324,6 +378,16 @@ export async function handleToolResult(deps) {
|
|
|
324
378
|
});
|
|
325
379
|
return { content: event.content, isError: true };
|
|
326
380
|
}
|
|
381
|
+
// Must happen before debounce admission: latestDeps intentionally retains only
|
|
382
|
+
// the latest event, but write -> edit is a sticky turn transition.
|
|
383
|
+
const receipt = runtime.recordMutationToolReceipt;
|
|
384
|
+
const autofixMode = deps._bypassDebounce
|
|
385
|
+
? (deps._autofixMode ?? (event.toolName === "edit" ? "deferred" : "immediate"))
|
|
386
|
+
: receipt
|
|
387
|
+
? receipt.call(runtime, filePath, event.toolName).autofixMode
|
|
388
|
+
: event.toolName === "edit"
|
|
389
|
+
? "deferred"
|
|
390
|
+
: "immediate";
|
|
327
391
|
// Coalesce sequential edits to the same file into one pipeline run against
|
|
328
392
|
// the final state. Only the debounce-fired call (with _bypassDebounce=true)
|
|
329
393
|
// proceeds to the pipeline body; in-window callers share its promise.
|
|
@@ -332,6 +396,7 @@ export async function handleToolResult(deps) {
|
|
|
332
396
|
if (debounceMs > 0) {
|
|
333
397
|
return scheduleDebounced(filePath, debounceMs, {
|
|
334
398
|
...deps,
|
|
399
|
+
_autofixMode: autofixMode,
|
|
335
400
|
_telemetryParticipantIds: [readGuardCorrelationId],
|
|
336
401
|
_telemetryParticipantTotal: 1,
|
|
337
402
|
});
|
|
@@ -469,12 +534,15 @@ export async function handleToolResult(deps) {
|
|
|
469
534
|
cwd: dispatchCwd,
|
|
470
535
|
projectRoot: turnStateCwd,
|
|
471
536
|
toolName: event.toolName,
|
|
537
|
+
autofixMode,
|
|
472
538
|
modifiedRanges,
|
|
473
539
|
telemetry: {
|
|
474
540
|
model: runtime.telemetryModel,
|
|
475
541
|
sessionId: runtime.telemetrySessionId,
|
|
476
542
|
turnIndex: runtime.turnIndex,
|
|
477
543
|
writeIndex,
|
|
544
|
+
modelId: runtime.telemetryModelId,
|
|
545
|
+
provider: runtime.telemetryProviderId,
|
|
478
546
|
},
|
|
479
547
|
getFlag,
|
|
480
548
|
getFlagSource,
|
|
@@ -638,11 +706,19 @@ export async function handleToolResult(deps) {
|
|
|
638
706
|
}
|
|
639
707
|
}
|
|
640
708
|
}
|
|
709
|
+
let autofixNewlyQueued = false;
|
|
710
|
+
if (!result.isError && autofixMode === "deferred" && nodeFs.existsSync(filePath)) {
|
|
711
|
+
autofixNewlyQueued =
|
|
712
|
+
runtime.deferMutation?.call(runtime, filePath, dispatchCwd, event.toolName, turnStateCwd, "autofix", deps.sessionId) ?? false;
|
|
713
|
+
dbg(`tool_result: queued deferred autofix for ${filePath}`);
|
|
714
|
+
}
|
|
715
|
+
let formatQueued = false;
|
|
641
716
|
if (!result.isError &&
|
|
642
717
|
!getFlag("no-autoformat", filePath) &&
|
|
643
|
-
!getFlag("immediate-format") &&
|
|
718
|
+
(autofixMode === "deferred" || !getFlag("immediate-format")) &&
|
|
644
719
|
nodeFs.existsSync(filePath)) {
|
|
645
720
|
const isNewlyQueued = runtime.deferFormat(filePath, dispatchCwd, event.toolName, turnStateCwd, deps.sessionId);
|
|
721
|
+
formatQueued = true;
|
|
646
722
|
dbg(`tool_result: queued deferred format for ${filePath}`);
|
|
647
723
|
logLatency({
|
|
648
724
|
type: "phase",
|
|
@@ -652,19 +728,21 @@ export async function handleToolResult(deps) {
|
|
|
652
728
|
durationMs: 0,
|
|
653
729
|
metadata: { cwd: dispatchCwd },
|
|
654
730
|
});
|
|
655
|
-
//
|
|
656
|
-
//
|
|
657
|
-
|
|
658
|
-
// queue", so re-emitting would be spam with zero new information.
|
|
659
|
-
if (isNewlyQueued) {
|
|
731
|
+
// Publish a file's first queue entry and each newly added kind. A same-kind
|
|
732
|
+
// re-touch before agent_end carries no new information and stays silent.
|
|
733
|
+
if (isNewlyQueued || autofixNewlyQueued) {
|
|
660
734
|
publishFormatQueued({
|
|
661
735
|
filePath,
|
|
662
736
|
cwd: dispatchCwd,
|
|
663
737
|
tool: event.toolName,
|
|
664
738
|
dbg,
|
|
739
|
+
kinds: autofixMode === "deferred" ? ["autofix", "format"] : ["format"],
|
|
665
740
|
});
|
|
666
741
|
}
|
|
667
742
|
}
|
|
743
|
+
if (autofixNewlyQueued && !formatQueued) {
|
|
744
|
+
publishFormatQueued({ filePath, cwd: dispatchCwd, tool: event.toolName, kinds: ["autofix"], dbg });
|
|
745
|
+
}
|
|
668
746
|
for (const changedFile of result.changedFiles ?? []) {
|
|
669
747
|
const resolvedChanged = path.resolve(changedFile);
|
|
670
748
|
if (!nodeFs.existsSync(resolvedChanged))
|
|
@@ -764,9 +842,45 @@ export async function handleToolResult(deps) {
|
|
|
764
842
|
result: output ? "completed" : "no_output",
|
|
765
843
|
});
|
|
766
844
|
runtime.reportedThisTurn.add(filePath);
|
|
767
|
-
|
|
845
|
+
const postMutation = result.postMutation;
|
|
846
|
+
const attachAuthoritativeContent = postMutation !== undefined &&
|
|
847
|
+
Buffer.byteLength(postMutation.content, "utf-8") <= AUTHORITATIVE_CONTENT_MAX_BYTES;
|
|
848
|
+
if (postMutation) {
|
|
849
|
+
const bytes = Buffer.byteLength(postMutation.content, "utf-8");
|
|
850
|
+
// S3e (#1432 review): when this call is the synthetic per-file
|
|
851
|
+
// `handleToolResult` recursion a multi-file bash write drives (see the
|
|
852
|
+
// bash branch above), the OUTER aggregate-budget loop may log a SECOND
|
|
853
|
+
// `authoritative_content_attachment_decision` row for this same
|
|
854
|
+
// `filePath` right after this one, downgrading an "attached" here to
|
|
855
|
+
// "aggregate-budget-degraded" once the shared budget is exhausted.
|
|
856
|
+
// Both rows are intentional (this one reflects the per-file cap
|
|
857
|
+
// decision; the outer one reflects the aggregate-budget decision that
|
|
858
|
+
// can override it) — the outer row, logged later, wins for that path.
|
|
859
|
+
logLatency({
|
|
860
|
+
type: "phase",
|
|
861
|
+
phase: "authoritative_content_attachment_decision",
|
|
862
|
+
filePath: postMutation.filePath,
|
|
863
|
+
durationMs: 0,
|
|
864
|
+
metadata: { path: postMutation.filePath, bytes, decision: attachAuthoritativeContent ? "attached" : "size-capped" },
|
|
865
|
+
});
|
|
866
|
+
}
|
|
867
|
+
const returnedContent = attachAuthoritativeContent
|
|
868
|
+
? [
|
|
869
|
+
...event.content,
|
|
870
|
+
{
|
|
871
|
+
type: "text",
|
|
872
|
+
text: `pi-lens applied autofix to ${postMutation.filePath}. The following full content is authoritative for subsequent edits:\n\n${postMutation.content}`,
|
|
873
|
+
},
|
|
874
|
+
]
|
|
875
|
+
: event.content;
|
|
876
|
+
if (postMutation && !attachAuthoritativeContent) {
|
|
877
|
+
output = `${output ? `${output}\n\n` : ""}⚠️ **File was modified by auto-format/fix. You MUST re-read ${postMutation.filePath} before making any further edits — the authoritative content is too large to attach.**`;
|
|
878
|
+
}
|
|
879
|
+
if (!output && !result.postMutation)
|
|
768
880
|
return;
|
|
769
881
|
return {
|
|
770
|
-
content:
|
|
882
|
+
content: output
|
|
883
|
+
? [...returnedContent, { type: "text", text: output }]
|
|
884
|
+
: returnedContent,
|
|
771
885
|
};
|
|
772
886
|
}
|