pi-skill-shiori 0.6.8 → 0.6.10

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
@@ -2,17 +2,31 @@
2
2
 
3
3
  ## Unreleased
4
4
 
5
- ### Changed
5
+ ## [0.6.10] - 2026-09-21
6
6
 
7
- - Bump package version to `0.6.7` for the next patch release.
7
+ ### Fixed
8
8
 
9
- - Add Buy Me a Coffee sponsor button to README and native GitHub funding link via `.github/FUNDING.yml`.
9
+ - Prune stale `.pi/cache/skill-shiori/index-*.sqlite` databases. Every index rebuild wrote a new `index-<pid>-<ts>.sqlite` file and never removed the older ones, so a long-lived vault accumulated hundreds of files (336 files / 33 MB in the local vault). Rebuilds now delete databases older than a one hour grace window; the live database, recent files, and locked files are left in place.
10
+
11
+ ## [0.6.9] - 2026-08-22
12
+
13
+ ### Changed
14
+
15
+ - Merge the 2026-08-22 managed OSS dependency and maintenance PR batch.
10
16
 
11
17
  ## [0.6.8] - 2026-08-04
12
18
 
13
19
  ### Changed
14
20
 
15
21
  - Bump package version for the Discord release webhook verification.
22
+ - Add dotfield.xyz Discord community badge to README.
23
+
24
+ ## [0.6.7] - 2026-07-20
25
+
26
+ ### Changed
27
+
28
+ - Bump package version to `0.6.7` for the next patch release.
29
+ - Add Buy Me a Coffee sponsor button to README and native GitHub funding link via `.github/FUNDING.yml`.
16
30
 
17
31
  ## [0.6.6] - 2026-07-07
18
32
 
package/Docs/usage.md CHANGED
@@ -100,7 +100,7 @@ Generate a starter policy from discovered skills:
100
100
  /shiori:bootstrap
101
101
  ```
102
102
 
103
- This writes a generated review file next to `.pi/skill-shiori.yml`. Review it before using it as your real policy.
103
+ This writes `.pi/skill-shiori.generated.yml` next to your project policy. Review the draft, copy the sections you want into `.pi/skill-shiori.yml`, then run `/shiori:reload`.
104
104
 
105
105
  ## Suppression statuses
106
106
 
@@ -167,6 +167,24 @@ command: offers=1, loaded=2, zeroHits=1
167
167
  top skills: auth-helper(1/2), deploy-kit(1/1)
168
168
  ```
169
169
 
170
+ ## Agent tools
171
+
172
+ Shiori registers two tools the agent can call after candidates appear:
173
+
174
+ ```ts
175
+ // Discover matching skills for a natural-language task (may pre-load multiple bodies)
176
+ shiori_recommend({ task: "browser scraping screenshot" })
177
+
178
+ // Load one selected skill body after a candidate matches
179
+ shiori_load_skill({ skill: "reddit-research" })
180
+ ```
181
+
182
+ `shiori_recommend` returns compact summaries and may pre-load matching `SKILL.md` bodies. The Pi UI shows a collapsed result like `✓ Shiori playwright-cli [trigger], gstack-browse [description]`.
183
+
184
+ `shiori_load_skill` loads one skill by name. The Pi UI shows a compact result like `✓ Loaded reddit-research (6.3KB)`.
185
+
186
+ See [Recommendation surface](recommendation-surface.md) for badge vocabulary and multi-skill examples.
187
+
170
188
  ## Related docs
171
189
 
172
190
  - [Recommendation surface](recommendation-surface.md) — reason badges, Always Visible policy, and metrics interplay
package/README.md CHANGED
@@ -19,7 +19,7 @@ For maintenance priorities and the phased plan, see [`ROADMAP.md`](ROADMAP.md).
19
19
 
20
20
  Pi Skill Shiori is a [Pi](https://pi.dev/) package for vaults or projects with many Agent Skills where the default catalog becomes noisy and expensive. It hides the normal skill catalog when safe, recommends triggerable skills with compact summaries, and loads full `SKILL.md` bodies on demand.
21
21
 
22
- `0.6.8` is the current working release. Prompt-boundary suppression is intentionally conservative: if Shiori cannot safely recognize a catalog boundary, it leaves the prompt untouched and warns instead of deleting too much.
22
+ `0.6.10` is the current working release. Prompt-boundary suppression is intentionally conservative: if Shiori cannot safely recognize a catalog boundary, it leaves the prompt untouched and warns instead of deleting too much.
23
23
 
24
24
  ## Features
25
25
 
@@ -37,7 +37,7 @@ Pi Skill Shiori is a [Pi](https://pi.dev/) package for vaults or projects with m
37
37
  ### Global install from npm
38
38
 
39
39
  ```bash
40
- pi install npm:pi-skill-shiori@0.6.8
40
+ pi install npm:pi-skill-shiori@0.6.10
41
41
  ```
42
42
 
43
43
  Without a version pin:
@@ -49,7 +49,7 @@ pi install npm:pi-skill-shiori
49
49
  ### Project-local install from npm
50
50
 
51
51
  ```bash
52
- pi install -l npm:pi-skill-shiori@0.6.8
52
+ pi install -l npm:pi-skill-shiori@0.6.10
53
53
  ```
54
54
 
55
55
  Without a version pin:
@@ -61,7 +61,7 @@ pi install -l npm:pi-skill-shiori
61
61
  ### Install from GitHub
62
62
 
63
63
  ```bash
64
- pi install git:github.com/eiei114/pi-skill-shiori@v0.6.8
64
+ pi install git:github.com/eiei114/pi-skill-shiori@v0.6.10
65
65
  pi install -l git:github.com/eiei114/pi-skill-shiori
66
66
  ```
67
67
 
@@ -83,7 +83,7 @@ pi install -l /absolute/path/to/pi-skill-shiori
83
83
  1. Install the package (see [Install](#install)).
84
84
  2. Create `.pi/skill-shiori.yml` in your Pi project (see [Docs/usage.md](Docs/usage.md#configure)).
85
85
  3. Start Pi and run `/shiori:doctor` to confirm policy path, indexed roots, and suppression status.
86
- 4. Use `/shiori:bootstrap` to draft a policy from discovered skills, then `/shiori:reload` after edits.
86
+ 4. Use `/shiori:bootstrap` to write `.pi/skill-shiori.generated.yml`, review it, copy needed sections into `.pi/skill-shiori.yml`, then run `/shiori:reload`.
87
87
  5. Ask the agent for help; Shiori injects compact candidates or use `/shiori:recommend` for an interactive flow.
88
88
 
89
89
  Commands take no inline arguments. Details are collected after launch via Pi UI prompts.
@@ -98,13 +98,19 @@ Commands take no inline arguments. Details are collected after launch via Pi UI
98
98
  | `/shiori:recommend` | Interactive recommendation flow with optional pre-load. |
99
99
  | `/shiori:stats` | Show operational counters and recommendation quality summary. |
100
100
 
101
- Shiori registers one tool:
101
+ Shiori registers two tools:
102
102
 
103
103
  ```ts
104
+ // Discover matching skills for a natural-language task (may pre-load multiple bodies)
105
+ shiori_recommend({ task: "browser scraping screenshot" })
106
+
107
+ // Load one selected skill body after a candidate matches
104
108
  shiori_load_skill({ skill: "reddit-research" })
105
109
  ```
106
110
 
107
- The model receives the full selected `SKILL.md` content. The Pi UI shows a compact result like `✓ Loaded reddit-research (6.3KB)`.
111
+ `shiori_recommend` returns compact summaries and may pre-load matching `SKILL.md` bodies. The Pi UI shows a collapsed result like `✓ Shiori playwright-cli [trigger], gstack-browse [description]`.
112
+
113
+ `shiori_load_skill` loads one skill by name. The Pi UI shows a compact result like `✓ Loaded reddit-research (6.3KB)`.
108
114
 
109
115
  Recommended skills show compact reason badges (`[trigger]`, `[description]`, `[low match]`). See [`Docs/recommendation-surface.md`](Docs/recommendation-surface.md) for badge vocabulary and metrics interplay.
110
116
 
@@ -173,4 +179,4 @@ For vulnerability reporting, see [`SECURITY.md`](SECURITY.md).
173
179
 
174
180
  ## License
175
181
 
176
- MIT
182
+ MIT
package/ROADMAP.md CHANGED
@@ -58,7 +58,7 @@ semver classification. Patches default to `patch`; `none` means no package publi
58
58
  | # | Slice | Bump | Status |
59
59
  |---|---|---|---|
60
60
  | 1 | Add README status badges (CI, Publish, npm version, npm downloads, License, Pi package, Trusted Publishing) | patch | done |
61
- | 2 | Add `version:check` CI gate (block publishable-path changes without a semver increase) | none | planned |
61
+ | 2 | Add `version:check` CI gate (validate semver and CHANGELOG policy on pull requests) | none | done |
62
62
  | 3 | Pin GitHub Actions to commit SHAs in `ci.yml`, `auto-release.yml`, `publish.yml` | none | planned |
63
63
 
64
64
  ### Month 2 — Stabilization and design boundaries
@@ -98,7 +98,7 @@ Current status against the shared Pi extension OSS policy. Gaps become Month 1 w
98
98
  - [x] `package.json` `files` is explicit (no `node_modules`, tests, or local state)
99
99
  - [x] No template `example-skill` / `example` / `example-theme` resources shipped
100
100
  - [ ] **README status badges** (CI, Publish, npm version, npm downloads, License, Pi package, Trusted Publishing) — *Month 1 #1*
101
- - [ ] **`version:check` CI gate** so publishable-path changes cannot merge without a bump — *Month 1 #2*
101
+ - [x] **`version:check` CI gate** validates semver/CHANGELOG policy on pull requests — *Month 1 #2*
102
102
  - [ ] **Pin GitHub Actions to commit SHAs** (currently floating `@v4`) — *Month 1 #3*
103
103
 
104
104
  ## Current backlog integration
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pi-skill-shiori",
3
- "version": "0.6.8",
3
+ "version": "0.6.10",
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",
@@ -54,9 +54,9 @@
54
54
  "typebox": "*"
55
55
  },
56
56
  "devDependencies": {
57
- "@earendil-works/pi-ai": "^0.83.0",
58
- "@earendil-works/pi-coding-agent": "^0.83.0",
59
- "@earendil-works/pi-tui": "^0.83.0",
57
+ "@earendil-works/pi-ai": "^0.85.0",
58
+ "@earendil-works/pi-coding-agent": "^0.84.1",
59
+ "@earendil-works/pi-tui": "^0.85.1",
60
60
  "@types/node": "^26.0.0",
61
61
  "tsx": "^4.22.4",
62
62
  "typebox": "latest",
package/src/indexer.ts CHANGED
@@ -1,8 +1,62 @@
1
- import { mkdir } from "node:fs/promises";
1
+ import { mkdir, readdir, stat, unlink } from "node:fs/promises";
2
2
  import { createRequire } from "node:module";
3
- import { join } from "node:path";
3
+ import { basename, join } from "node:path";
4
4
  import type { RetrievalBackend, ShioriPolicy, SkillRecord } from "./types.js";
5
5
 
6
+ const INDEX_FILE_PATTERN = /^index-\d+-\d+\.sqlite(?:-(?:wal|shm|journal))?$/;
7
+
8
+ /**
9
+ * Index databases are written with a per-process name, so every rebuild adds a
10
+ * file. Prune older ones after a grace window: long enough that a concurrent
11
+ * process keeps its database, short enough that a busy vault does not grow
12
+ * without bound.
13
+ */
14
+ export const DEFAULT_INDEX_GRACE_MS = 60 * 60 * 1000;
15
+
16
+ export interface PruneIndexOptions {
17
+ /** File name to keep, usually the database this process just opened. */
18
+ keep?: string;
19
+ /** Files newer than this window are left alone. */
20
+ graceMs?: number;
21
+ /** Clock override for tests. */
22
+ now?: number;
23
+ }
24
+
25
+ /**
26
+ * Best-effort cleanup of stale index databases. Locked files (a live process on
27
+ * Windows) and unreadable entries are skipped instead of failing the build.
28
+ */
29
+ export async function pruneStaleIndexFiles(cacheDir: string, options: PruneIndexOptions = {}): Promise<string[]> {
30
+ const graceMs = options.graceMs ?? DEFAULT_INDEX_GRACE_MS;
31
+ const now = options.now ?? Date.now();
32
+ const removed: string[] = [];
33
+
34
+ let entries: string[];
35
+ try {
36
+ entries = await readdir(cacheDir);
37
+ } catch {
38
+ return removed;
39
+ }
40
+
41
+ for (const entry of entries) {
42
+ if (!INDEX_FILE_PATTERN.test(entry)) continue;
43
+ if (options.keep && entry === options.keep) continue;
44
+
45
+ const target = join(cacheDir, entry);
46
+ try {
47
+ const info = await stat(target);
48
+ if (!info.isFile()) continue;
49
+ if (now - info.mtimeMs < graceMs) continue;
50
+ await unlink(target);
51
+ removed.push(entry);
52
+ } catch {
53
+ // Locked (a live process owns it) or already gone: leave it for next time.
54
+ }
55
+ }
56
+
57
+ return removed;
58
+ }
59
+
6
60
  export interface SkillIndex {
7
61
  skills: SkillRecord[];
8
62
  policy: ShioriPolicy;
@@ -24,6 +78,7 @@ export async function buildSkillIndex(cwd: string, skills: SkillRecord[], policy
24
78
  await mkdir(cacheDir, { recursive: true });
25
79
 
26
80
  const db = new sqlite.DatabaseSync(dbPath);
81
+ await pruneStaleIndexFiles(cacheDir, { keep: basename(dbPath) });
27
82
  db.exec(
28
83
  "CREATE VIRTUAL TABLE skill_fts USING fts5(name, description, triggers, path, tokenize='unicode61 remove_diacritics 2')",
29
84
  );