From 5d902349d1388b7327b53c5a25c8632bf871d9c6 Mon Sep 17 00:00:00 2001 From: GRayHook Date: Wed, 17 Jun 2026 12:57:38 +0700 Subject: [PATCH] =?UTF-8?q?Phase=2011:=20footer=20status=20line=20on=C2=B7?= =?UTF-8?q?N=20=E2=80=94=20SPEC=20=C2=A77.2.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Update skill-reinject status after toggles, clear, skill tracking, and session restore. Co-authored-by: Cursor --- src/commands.ts | 30 ++++++++++++++++++++++++++---- src/index.ts | 13 +++++++++---- 2 files changed, 35 insertions(+), 8 deletions(-) diff --git a/src/commands.ts b/src/commands.ts index ba7ad44..61d0d81 100644 --- a/src/commands.ts +++ b/src/commands.ts @@ -1,7 +1,7 @@ -import type { ExtensionAPI, ExtensionCommandContext, Skill } from "@earendil-works/pi-coding-agent"; +import type { ExtensionAPI, ExtensionCommandContext, ExtensionContext, Skill } from "@earendil-works/pi-coding-agent"; import { resolveDeliveryMode } from "./auto-compact.js"; import { reinjectNow } from "./reinject.js"; -import { readSettings, writeGlobalSettings, type SkillReinjectSettings } from "./settings.js"; +import { effectiveEnabled, readSettings, writeGlobalSettings, type SkillReinjectSettings } from "./settings.js"; import type { AutoCompactIntegration, ExtensionState, RuntimeFlags } from "./state.js"; export interface SkillReinjectCommandDeps { @@ -12,6 +12,20 @@ export interface SkillReinjectCommandDeps { persistState: () => void; } +/** Footer status `on·N` / `off·N` (SPEC §7.2). */ +export function updateSkillReinjectStatusLine( + ctx: ExtensionContext, + state: ExtensionState, + settings?: SkillReinjectSettings, +): void { + if (!ctx.hasUI) { + return; + } + const resolvedSettings = settings ?? readSettings(ctx); + const label = effectiveEnabled(state.sessionOverride, resolvedSettings) ? "on" : "off"; + ctx.ui.setStatus("skill-reinject", `${label}·${state.skills.length}`); +} + const SKILL_REINJECT_COMMAND_NAMES = ["skill-reinject", "sr", "skills-reinject"] as const; export function registerSkillReinjectCommand(pi: ExtensionAPI, deps: SkillReinjectCommandDeps): void { @@ -93,6 +107,7 @@ function showSkillReinjectStatus(ctx: ExtensionCommandContext, deps: SkillReinje } const settings = readSettings(ctx); ctx.ui.notify(formatSkillReinjectStatus(deps.state, settings, deps.runtime, deps.state.sessionIntegrationOverride), "info"); + updateSkillReinjectStatusLine(ctx, deps.state, settings); } async function handleSkillReinjectCommand( @@ -112,7 +127,7 @@ async function handleSkillReinjectCommand( return; } if (subcommand === "global") { - handleGlobalToggle(trimmed, ctx); + handleGlobalToggle(trimmed, ctx, deps); return; } if (subcommand === "list") { @@ -160,9 +175,14 @@ function handleSessionToggle( const settings = readSettings(ctx); const enabledLine = formatEnabledLine(deps.state.sessionOverride, settings); ctx.ui.notify(enabledLine, "info"); + updateSkillReinjectStatusLine(ctx, deps.state, settings); } -function handleGlobalToggle(args: string, ctx: ExtensionCommandContext): void { +function handleGlobalToggle( + args: string, + ctx: ExtensionCommandContext, + deps: SkillReinjectCommandDeps, +): void { const parts = args.trim().split(/\s+/); const action = parts[1]; if (action !== "on" && action !== "off") { @@ -176,6 +196,7 @@ function handleGlobalToggle(args: string, ctx: ExtensionCommandContext): void { return; } ctx.ui.notify(`skill-reinject: global ${action}`, "info"); + updateSkillReinjectStatusLine(ctx, deps.state, readSettings(ctx)); } function showTrackedSkillsList(ctx: ExtensionCommandContext, deps: SkillReinjectCommandDeps): void { @@ -199,6 +220,7 @@ function handleClearTrackedSkills(ctx: ExtensionCommandContext, deps: SkillReinj return; } ctx.ui.notify("skill-reinject: cleared tracked skills", "info"); + updateSkillReinjectStatusLine(ctx, deps.state); } const INTEGRATION_VALUES: readonly AutoCompactIntegration[] = ["auto", "defer", "immediate", "off"]; diff --git a/src/index.ts b/src/index.ts index 786796d..cc05330 100644 --- a/src/index.ts +++ b/src/index.ts @@ -7,7 +7,7 @@ import { type Skill, } from "@earendil-works/pi-coding-agent"; import { detectAndCachePiAutoCompact, resolveDeliveryMode } from "./auto-compact.js"; -import { registerSkillReinjectCommand } from "./commands.js"; +import { registerSkillReinjectCommand, updateSkillReinjectStatusLine } from "./commands.js"; import { consumeCompactionOnSessionCompact, createCompactionRuntime, @@ -53,9 +53,12 @@ export default function skillReinject(pi: ExtensionAPI): void { persistState, }); - function trackSkillAndPersist(input: TrackSkillInput): void { + function trackSkillAndPersist(input: TrackSkillInput, ctx?: ExtensionContext): void { trackSkill(state, input); persistState(); + if (ctx) { + updateSkillReinjectStatusLine(ctx, state, readSettings(ctx)); + } } function trackReadSkillPath(path: string, ctx: ExtensionContext): void { @@ -70,7 +73,7 @@ export default function skillReinject(pi: ExtensionAPI): void { filePath: matched.filePath, baseDir: matched.baseDir, source: "read", - }); + }, ctx); } function restoreSessionState(ctx: ExtensionContext): void { @@ -82,6 +85,7 @@ export default function skillReinject(pi: ExtensionAPI): void { if (!loaded) { rescanSkillsFromBranch(state, branch, ctx.cwd, registeredSkills, settings.trackReadPaths); } + updateSkillReinjectStatusLine(ctx, state, settings); } function handleSessionCompact(event: SessionCompactEvent, ctx: ExtensionContext): void { @@ -169,7 +173,7 @@ export default function skillReinject(pi: ExtensionAPI): void { filePath: skill.filePath, baseDir: skill.baseDir, source: "slash", - }); + }, ctx); } } @@ -197,6 +201,7 @@ export default function skillReinject(pi: ExtensionAPI): void { }); } persistState(); + updateSkillReinjectStatusLine(ctx, state, readSettings(ctx)); }); pi.on("tool_call", async (event, ctx) => {