feat(prompt): implement prompt injection slice 4

This commit is contained in:
2026-06-11 22:54:51 +02:00
parent 19666c900e
commit 58e8bd31d3
5 changed files with 965 additions and 18 deletions
+55 -4
View File
@@ -9,8 +9,11 @@ import {
reinitPath,
retrieveContext,
buildPreInitHint,
buildAdvisoryReminder,
buildStrictBypassGuard,
modeAllowsPreInitHint,
modeAllowsInjection,
evaluateStrictBypass,
discoverContextWindow,
buildInjectionPayload,
shouldReinjectForEvent,
@@ -372,7 +375,19 @@ export default function (pi: ExtensionAPI) {
};
}
// Maps exist but advisory mode does not permit automatic artifact injection yet.
// Slice 4: advisory mode shows a visible lightweight reminder after init.
// No root-pair preload, no per-turn reinjection.
if (config.promptInjectionMode === "advisory") {
return {
message: {
customType: "pi-project-map-hint",
content: buildAdvisoryReminder(),
display: true,
},
};
}
// Maps exist but mode does not permit automatic artifact injection.
if (!modeAllowsInjection(config.promptInjectionMode)) {
return {};
}
@@ -424,7 +439,8 @@ export default function (pi: ExtensionAPI) {
return {};
}
// Slice 3b: detect root-pair artifact changes
// Slice 3b: detect root-pair artifact changes early. Invalidation always
// forces reinjection, even in strict mode, because the context is stale.
const currentMtimes = getRootPairMtimes(ctx.cwd);
const hasPrevious =
lastRootPairMtimes.mapMtime !== undefined ||
@@ -433,12 +449,47 @@ export default function (pi: ExtensionAPI) {
hasPrevious && rootPairChanged(currentMtimes, lastRootPairMtimes);
lastRootPairMtimes = currentMtimes;
const eventType = artifactChanged ? "artifact_change" : event?.type;
if (artifactChanged) {
const decision = shouldReinjectForEvent(
{
messages: event?.messages,
type: "artifact_change",
payload: event?.payload,
},
config.promptInjectionMode,
);
if (!decision.needed) {
return {};
}
const contextWindow = discoverContextWindow(ctx);
const payload = buildInjectionPayload(ctx.cwd, config, contextWindow);
return {
message: {
customType: "pi-project-map-hint",
content: payload.content,
display: payload.display,
},
};
}
// Slice 4: strict-mode bypass guard for sensitive actions with missing protocol path.
if (config.promptInjectionMode === "strict") {
const bypass = evaluateStrictBypass(event, config.promptInjectionMode);
if (bypass.guard) {
return {
message: {
customType: "pi-project-map-hint",
content: buildStrictBypassGuard(bypass.reason),
display: true,
},
};
}
}
const decision = shouldReinjectForEvent(
{
messages: event?.messages,
type: eventType,
type: event?.type,
payload: event?.payload,
},
config.promptInjectionMode,