pi-skillful 0.3.2 → 0.3.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/CHANGELOG.md
CHANGED
|
@@ -6,6 +6,18 @@ This project follows the spirit of [Keep a Changelog](https://keepachangelog.com
|
|
|
6
6
|
|
|
7
7
|
## [Unreleased]
|
|
8
8
|
|
|
9
|
+
## [0.3.4] - 2026-05-12
|
|
10
|
+
|
|
11
|
+
### Changed
|
|
12
|
+
|
|
13
|
+
- Preserve session skill toggle state across `/new` within the same Pi process.
|
|
14
|
+
|
|
15
|
+
## [0.3.3] - 2026-05-12
|
|
16
|
+
|
|
17
|
+
### Fixed
|
|
18
|
+
|
|
19
|
+
- Fixed session skill toggles so hidden skills toggled active are included in the next system prompt.
|
|
20
|
+
|
|
9
21
|
## [0.3.2] - 2026-05-10
|
|
10
22
|
|
|
11
23
|
### Fixed
|
package/README.md
CHANGED
|
@@ -88,7 +88,7 @@ Configured slots appear on the prompt editor's top border as `N skill-name`. Lon
|
|
|
88
88
|
|
|
89
89
|
`toggleModifier` defaults to `"alt"`. Supported values are `"alt"`, `"ctrl"`, `"ctrl+shift"`, `"alt+shift"`, `"ctrl+alt"`, and `"ctrl+alt+shift"`. Change it if your terminal reserves `alt+number` shortcuts.
|
|
90
90
|
|
|
91
|
-
On
|
|
91
|
+
On app startup, non-hidden skills are active and hidden skills are inactive. Within a running Pi process, `/new` preserves the current toggle state for the new session. Resuming, forking, cloning, reloading, or restarting Pi resets toggle state from settings. Inline `/skill:name` invocation remains explicit and works even when that skill is inactive.
|
|
92
92
|
|
|
93
93
|
## Installation
|
|
94
94
|
|
package/package.json
CHANGED
|
@@ -39,6 +39,7 @@ interface SessionToggleState {
|
|
|
39
39
|
}
|
|
40
40
|
|
|
41
41
|
let state: SessionToggleState = createEmptyState();
|
|
42
|
+
let preservedNewSessionActiveBySkill: { cwd: string; activeBySkill: Map<string, boolean> } | undefined;
|
|
42
43
|
|
|
43
44
|
export default function sessionSkillToggles(pi: ExtensionAPI) {
|
|
44
45
|
for (const modifier of SUPPORTED_TOGGLE_MODIFIERS) {
|
|
@@ -53,7 +54,7 @@ export default function sessionSkillToggles(pi: ExtensionAPI) {
|
|
|
53
54
|
}
|
|
54
55
|
}
|
|
55
56
|
|
|
56
|
-
pi.on("session_start", async (
|
|
57
|
+
pi.on("session_start", async (event, ctx) => {
|
|
57
58
|
const settings = await readEffectiveSkillfulSettings(ctx.cwd);
|
|
58
59
|
const loadedSkillNames = new Set(listLoadedSkills(pi.getCommands()).map((s) => s.name));
|
|
59
60
|
const slots = SKILL_TOGGLE_SLOTS.flatMap((slot): ToggleSlotState[] => {
|
|
@@ -62,12 +63,23 @@ export default function sessionSkillToggles(pi: ExtensionAPI) {
|
|
|
62
63
|
return [{ slot, skillName }];
|
|
63
64
|
});
|
|
64
65
|
|
|
66
|
+
const preservedActiveBySkill =
|
|
67
|
+
event.reason === "new" && preservedNewSessionActiveBySkill?.cwd === ctx.cwd
|
|
68
|
+
? preservedNewSessionActiveBySkill.activeBySkill
|
|
69
|
+
: undefined;
|
|
70
|
+
preservedNewSessionActiveBySkill = undefined;
|
|
71
|
+
|
|
65
72
|
state = {
|
|
66
73
|
cwd: ctx.cwd,
|
|
67
74
|
modifier: settings.toggleModifier,
|
|
68
75
|
hiddenSkills: settings.hiddenSkillSet,
|
|
69
76
|
slots,
|
|
70
|
-
activeBySkill: new Map(
|
|
77
|
+
activeBySkill: new Map(
|
|
78
|
+
slots.map(({ skillName }) => [
|
|
79
|
+
skillName,
|
|
80
|
+
preservedActiveBySkill?.get(skillName) ?? !settings.hiddenSkillSet.has(skillName),
|
|
81
|
+
]),
|
|
82
|
+
),
|
|
71
83
|
installedEditor: false,
|
|
72
84
|
installedWidget: false,
|
|
73
85
|
previousEditorFactory: undefined,
|
|
@@ -92,9 +104,11 @@ export default function sessionSkillToggles(pi: ExtensionAPI) {
|
|
|
92
104
|
return { systemPrompt };
|
|
93
105
|
});
|
|
94
106
|
|
|
95
|
-
pi.on("session_shutdown", (
|
|
107
|
+
pi.on("session_shutdown", (event, ctx) => {
|
|
96
108
|
if (state.installedEditor) ctx.ui.setEditorComponent(state.previousEditorFactory);
|
|
97
109
|
if (state.installedWidget) ctx.ui.setWidget(WIDGET_KEY, undefined);
|
|
110
|
+
preservedNewSessionActiveBySkill =
|
|
111
|
+
event.reason === "new" ? { cwd: state.cwd, activeBySkill: new Map(state.activeBySkill) } : undefined;
|
|
98
112
|
state = createEmptyState();
|
|
99
113
|
});
|
|
100
114
|
}
|
|
@@ -114,6 +128,10 @@ function createEmptyState(): SessionToggleState {
|
|
|
114
128
|
};
|
|
115
129
|
}
|
|
116
130
|
|
|
131
|
+
export function hasActiveSessionSkillToggles(): boolean {
|
|
132
|
+
return state.slots.length > 0;
|
|
133
|
+
}
|
|
134
|
+
|
|
117
135
|
function isSkillActive(skillName: string): boolean {
|
|
118
136
|
return state.activeBySkill.get(skillName) ?? !state.hiddenSkills.has(skillName);
|
|
119
137
|
}
|
|
@@ -17,6 +17,7 @@ import {
|
|
|
17
17
|
} from "../config.js";
|
|
18
18
|
import { replaceSkillsSection } from "../skill-prompt.js";
|
|
19
19
|
import { listLoadedSkills, type LoadedSkillInfo } from "../skills.js";
|
|
20
|
+
import { hasActiveSessionSkillToggles } from "./session-skill-toggles.js";
|
|
20
21
|
const SCOPES: SkillfulScope[] = ["global", "project"];
|
|
21
22
|
const STORE_KEY = Symbol.for("pi-skillful.skillVisibilityStore");
|
|
22
23
|
const STARTUP_PATCH_KEY = Symbol.for("pi-skillful.startupPatchV2");
|
|
@@ -60,6 +61,8 @@ export default function skillVisibility(pi: ExtensionAPI) {
|
|
|
60
61
|
});
|
|
61
62
|
|
|
62
63
|
pi.on("before_agent_start", async (event, ctx) => {
|
|
64
|
+
if (hasActiveSessionSkillToggles()) return;
|
|
65
|
+
|
|
63
66
|
const hidden = await refreshHiddenSkillCache(ctx.cwd);
|
|
64
67
|
if (hidden.size === 0 || !event.systemPromptOptions.skills?.length) return;
|
|
65
68
|
|