pi-skill-shiori 0.2.1 → 0.3.0

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.
Files changed (3) hide show
  1. package/README.md +9 -12
  2. package/package.json +1 -1
  3. package/src/index.ts +53 -25
package/README.md CHANGED
@@ -15,7 +15,7 @@ It is built for vaults or projects with many Agent Skills where the default cata
15
15
 
16
16
  ## Status
17
17
 
18
- `0.2.1` is an early working release. It is useful for local Pi workflows, but the prompt-boundary suppression logic is intentionally conservative: if Shiori cannot safely recognize a catalog boundary, it leaves the prompt untouched and warns instead of deleting too much.
18
+ `0.3.0` is an early working release. It is useful for local Pi workflows, but the prompt-boundary suppression logic is intentionally conservative: if Shiori cannot safely recognize a catalog boundary, it leaves the prompt untouched and warns instead of deleting too much.
19
19
 
20
20
  ## Requirements
21
21
 
@@ -37,7 +37,7 @@ Pi core packages are peer dependencies and should be supplied by the Pi runtime:
37
37
  After the package is published to npm:
38
38
 
39
39
  ```bash
40
- pi install npm:pi-skill-shiori@0.2.1
40
+ pi install npm:pi-skill-shiori@0.3.0
41
41
  ```
42
42
 
43
43
  Without a version pin:
@@ -51,7 +51,7 @@ pi install npm:pi-skill-shiori
51
51
  Use `-l` to write the package to the current project’s `.pi/settings.json`:
52
52
 
53
53
  ```bash
54
- pi install -l npm:pi-skill-shiori@0.2.1
54
+ pi install -l npm:pi-skill-shiori@0.3.0
55
55
  ```
56
56
 
57
57
  Without a version pin:
@@ -65,7 +65,7 @@ Equivalent pinned manual `.pi/settings.json` entry:
65
65
  ```json
66
66
  {
67
67
  "packages": [
68
- "npm:pi-skill-shiori@0.2.1"
68
+ "npm:pi-skill-shiori@0.3.0"
69
69
  ]
70
70
  }
71
71
  ```
@@ -83,7 +83,7 @@ Equivalent unpinned manual `.pi/settings.json` entry:
83
83
  ### Global install from GitHub
84
84
 
85
85
  ```bash
86
- pi install git:github.com/eiei114/pi-skill-shiori@v0.2.1
86
+ pi install git:github.com/eiei114/pi-skill-shiori@v0.3.0
87
87
  ```
88
88
 
89
89
  Without a tag pin:
@@ -95,7 +95,7 @@ pi install git:github.com/eiei114/pi-skill-shiori
95
95
  ### Project-local install from GitHub
96
96
 
97
97
  ```bash
98
- pi install -l git:github.com/eiei114/pi-skill-shiori@v0.2.1
98
+ pi install -l git:github.com/eiei114/pi-skill-shiori@v0.3.0
99
99
  ```
100
100
 
101
101
  Without a tag pin:
@@ -184,11 +184,8 @@ This writes a generated review file next to `.pi/skill-shiori.yml`. Review it be
184
184
  |---|---|
185
185
  | `/shiori:doctor` | Show policy path, inventory count, retrieval backend, suppression status, and code marker. |
186
186
  | `/shiori:bootstrap` | Generate a review draft policy from discovered skill descriptions. |
187
- | `/shiori:reload` | Rebuild Shiori’s skill inventory and retrieval index. |
188
- | `/shiori:reload --runtime` | Rebuild Shiori and ask Pi to reload runtime resources. Code changes may still need full restart. |
189
- | `/shiori:recommend <text>` | Pre-load up to 5 matching skills and queue the task for the agent in one shot. Planning phrases (e.g. `計画を立てたい`) return the dev-plan intake template without dumping SKILL bodies. |
190
- | `/shiori:recommend` | Ask what you need help with, then pre-load matches and queue for the agent (Pi UI input). |
191
- | `/shiori:recommend --pick <text>` | Recommend skills only (compact list + manual pick UI, no agent turn). |
187
+ | `/shiori:reload` | Ask what to reload, then rebuild Shiori’s skill inventory and optionally ask Pi to reload runtime resources. Code changes may still need full restart. |
188
+ | `/shiori:recommend` | Ask what you need help with, then either pre-load matches and queue the task for the agent or review recommendations only. Planning phrases (e.g. `計画を立てたい`) return the dev-plan intake template without dumping SKILL bodies. |
192
189
  | `/shiori:stats` | Show operational counters. |
193
190
 
194
191
  ## Tool
@@ -279,7 +276,7 @@ npm login
279
276
  After publishing, verify the Pi install path:
280
277
 
281
278
  ```bash
282
- pi install npm:pi-skill-shiori@0.2.1
279
+ pi install npm:pi-skill-shiori@0.3.0
283
280
  pi install npm:pi-skill-shiori
284
281
  pi list
285
282
  /shiori:doctor
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pi-skill-shiori",
3
- "version": "0.2.1",
3
+ "version": "0.3.0",
4
4
  "description": "Pi extension that reduces Agent Skill catalog tokens with policy-based skill retrieval and on-demand skill loading.",
5
5
  "type": "module",
6
6
  "license": "MIT",
package/src/index.ts CHANGED
@@ -27,6 +27,11 @@ interface ShioriLoadDetails {
27
27
 
28
28
  const SHIORI_CODE_MARKER = "prompt-boundary-v3";
29
29
  const RECOMMEND_MAX_CANDIDATES = 5;
30
+ const RELOAD_INVENTORY_ONLY = "Shiori inventory only";
31
+ const RELOAD_WITH_RUNTIME = "Shiori inventory + Pi runtime resources";
32
+ const RECOMMEND_QUEUE_TASK = "Pre-load matches and queue task for agent";
33
+ const RECOMMEND_REVIEW_ONLY = "Review recommendations only";
34
+ const CANCEL_CHOICE = "Cancel";
30
35
 
31
36
  export default function piSkillShiori(pi: ExtensionAPI) {
32
37
  let index: SkillIndex | undefined;
@@ -62,6 +67,11 @@ export default function piSkillShiori(pi: ExtensionAPI) {
62
67
  await reload(ctx.cwd);
63
68
  });
64
69
 
70
+ pi.on("session_shutdown", () => {
71
+ index?.close?.();
72
+ index = undefined;
73
+ });
74
+
65
75
  pi.on("input", async (event) => {
66
76
  if (/^\/(skill:|shiori:)/.test(event.text.trim())) {
67
77
  stats.explicitInvocationCount += 1;
@@ -196,9 +206,23 @@ export default function piSkillShiori(pi: ExtensionAPI) {
196
206
 
197
207
  pi.registerCommand("shiori:reload", {
198
208
  description: "Rebuild Pi Skill Shiori inventory and optional Pi runtime resources",
199
- handler: async (args, ctx) => {
209
+ handler: async (_args, ctx) => {
210
+ let target = RELOAD_INVENTORY_ONLY;
211
+ if (ctx.hasUI) {
212
+ const choice = await ctx.ui.select("Reload what?", [
213
+ RELOAD_INVENTORY_ONLY,
214
+ RELOAD_WITH_RUNTIME,
215
+ CANCEL_CHOICE,
216
+ ]);
217
+ if (!choice || choice === CANCEL_CHOICE) {
218
+ ctx.ui.notify("Reload cancelled.", "info");
219
+ return;
220
+ }
221
+ target = choice;
222
+ }
223
+
200
224
  await reload(ctx.cwd);
201
- if (args.includes("--runtime")) {
225
+ if (target === RELOAD_WITH_RUNTIME) {
202
226
  await ctx.reload();
203
227
  return;
204
228
  }
@@ -208,35 +232,39 @@ export default function piSkillShiori(pi: ExtensionAPI) {
208
232
 
209
233
  pi.registerCommand("shiori:recommend", {
210
234
  description: "Recommend Agent Skills for a natural-language task and queue it for the agent",
211
- handler: async (args, ctx) => {
235
+ handler: async (_args, ctx) => {
212
236
  const current = await ensureIndex(ctx.cwd);
213
- const pickOnly = args.trimStart().startsWith("--pick");
214
- let query = (pickOnly ? args.replace(/^--pick\s*/, "") : args).trim();
237
+ if (!ctx.hasUI) {
238
+ ctx.ui.notify("Run /shiori:recommend in the Pi UI to enter a task description.", "warning");
239
+ return;
240
+ }
215
241
 
242
+ const input = await ctx.ui.input(
243
+ "What do you want help with?",
244
+ "Describe your task in natural language…",
245
+ );
246
+ const query = input?.trim();
216
247
  if (!query) {
217
- if (!ctx.hasUI) {
218
- ctx.ui.notify(
219
- "Provide a task description: /shiori:recommend <what you want to do>",
220
- "warning",
221
- );
222
- return;
223
- }
224
- const input = await ctx.ui.input(
225
- "What do you want help with?",
226
- "Describe your task in natural language…",
227
- );
228
- if (!input?.trim()) {
229
- ctx.ui.notify("Recommendation cancelled.", "info");
230
- return;
231
- }
232
- query = input.trim();
248
+ ctx.ui.notify("Recommendation cancelled.", "info");
249
+ return;
250
+ }
251
+
252
+ const action = await ctx.ui.select("How should Shiori use these recommendations?", [
253
+ RECOMMEND_QUEUE_TASK,
254
+ RECOMMEND_REVIEW_ONLY,
255
+ CANCEL_CHOICE,
256
+ ]);
257
+ if (!action || action === CANCEL_CHOICE) {
258
+ ctx.ui.notify("Recommendation cancelled.", "info");
259
+ return;
233
260
  }
234
261
 
235
262
  const policy = withRecommendLimits(current);
236
263
  const candidates = retrieveCandidatesExpanded(query, current.skills, policy, current);
237
264
  const planning = isPlanningIntent(query);
238
- const loaded = planning ? [] : await loadRecommendedSkills(candidates);
239
- const summary = planning
265
+ const reviewOnly = action === RECOMMEND_REVIEW_ONLY;
266
+ const loaded = planning || reviewOnly ? [] : await loadRecommendedSkills(candidates);
267
+ const summary = planning || reviewOnly
240
268
  ? candidates.length > 0
241
269
  ? `Matched ${candidates.length} skill(s): ${candidates.map((c) => c.skill.name).join(", ")}`
242
270
  : ""
@@ -248,7 +276,7 @@ export default function piSkillShiori(pi: ExtensionAPI) {
248
276
  ctx.ui.notify("No matching skills for that request.", "warning");
249
277
  }
250
278
 
251
- if (!pickOnly) {
279
+ if (!reviewOnly) {
252
280
  const kickoff = isPlanningIntent(query)
253
281
  ? formatPlanningKickoffMessage(query, candidates)
254
282
  : formatRecommendKickoffMessage(query, loaded);
@@ -264,7 +292,7 @@ export default function piSkillShiori(pi: ExtensionAPI) {
264
292
  return;
265
293
  }
266
294
 
267
- if (candidates.length === 0 || !ctx.hasUI) {
295
+ if (candidates.length === 0) {
268
296
  return;
269
297
  }
270
298