@groeponline/pi-wishcraft 0.18.0 → 0.19.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.
package/CHANGELOG.md CHANGED
@@ -1,6 +1,12 @@
1
1
  # Changelog
2
2
 
3
- ## [Unreleased]
3
+ ## [0.19.0] - 2026-08-20
4
+
5
+ ### Added
6
+ - Every merge to `main` cuts an npm release: CI chooses patch/minor/major from commits since the last `v*` tag, pushes `vX.Y.Z`, and publishes with the GroepOnline org secret `NPM_TOKEN`. `[skip release]` opts out.
7
+
8
+ ### Changed
9
+ - Pi catalog contract: `pi-extension` / `wishcraft` keywords, public `publishConfig`, and a `pi.image` banner so the next npm publish lands on [pi.dev/packages](https://pi.dev/packages?name=groeponline) next to the other GroepOnline packages.
4
10
 
5
11
  ## [0.18.0] - 2026-08-16
6
12
 
package/README.md CHANGED
@@ -54,6 +54,8 @@ Inspired by [Powerlevel10k](https://github.com/romkatv/powerlevel10k) and [oh-my
54
54
  pi install npm:@groeponline/pi-wishcraft
55
55
  ```
56
56
 
57
+ Listed on the [Pi package catalog](https://pi.dev/packages?name=wishcraft) as `@groeponline/pi-wishcraft` next to the other GroepOnline pi packages.
58
+
57
59
  ### Method 2: One-Liner / Cloud Agent Startup Script (Cursor Cloud, Freebuff, Devcontainers, CI)
58
60
 
59
61
  For ephemeral VMs, cloud agents, or dev environments without manual intervention:
package/RELEASE.md CHANGED
@@ -12,20 +12,31 @@ verify it.
12
12
  - **GitHub repo:** `GroepOnline/pi-wishcraft` (forked from `nicobailon/pi-powerline-footer`, independently maintained)
13
13
  - **npm package:** `@groeponline/pi-wishcraft` (scoped, `--access public`)
14
14
  - **Default branch:** `main`
15
- - **Local checkout:** `/home/joep/pi-wishcraft`
16
- - **Pi settings (`~/.pi/agent/settings.json`):** packages entry `/home/joep/pi-wishcraft` (local path, not the npm name) and `"powerline": "chef"`. Local edits are picked up on `/reload` — no reinstall needed.
15
+ - **Local checkout:** `~/Documents/Github/GroepOnline/pi-wishcraft`
16
+ - **Pi settings (`~/.pi/agent/settings.json`):** packages entry `npm:@groeponline/pi-wishcraft` and `"powerline": "chef"`. For active development, temporarily swap the entry to the local checkout path so edits are picked up on `/reload` — no reinstall needed; switch back to the npm name for the installed release.
17
17
 
18
18
  ## The release flow
19
19
 
20
- A release is: bump version roll CHANGELOG → commit → tag → push. The tag
21
- triggers CI which tests and publishes to npm.
20
+ **Default:** every merge to `main` is a release. `.github/workflows/release.yml`
21
+ runs `node scripts/release.mjs auto --push` on `main`, then publishes when
22
+ the `v*` tag lands. `auto` reads commit subjects since the last `v*` tag:
23
+ `feat:` → minor, `feat!:` / `BREAKING CHANGE` → major, otherwise patch.
24
+
25
+ The first merge after `v0.18.0` therefore becomes **0.19.0** (the 0.19
26
+ `feat:` commits are already on `main`). Later docs/fix merges become
27
+ `0.19.1`, `0.19.2`, …
28
+
29
+ Put `[skip release]` in the merge-commit subject to opt out. The follow-up
30
+ `chore: release X.Y.Z` commit does not tag again.
31
+
32
+ Manual still works when you want an explicit version before pushing tags:
22
33
 
23
34
  ```bash
24
35
  # 1. Make sure the working tree is clean and tests/typecheck pass (see Verification)
25
36
  npm run typecheck # tsc --noEmit
26
37
  npm test # node --experimental-strip-types --test tests/**/*.test.ts
27
38
 
28
- # 2. Release (patch | minor | major | explicit 1.2.3)
39
+ # 2. Release (patch | minor | major | auto | explicit 1.2.3)
29
40
  npm run release minor # = node scripts/release.mjs minor
30
41
  ```
31
42
 
@@ -37,12 +48,12 @@ npm run release minor # = node scripts/release.mjs minor
37
48
  4. `git commit -m "chore: release <version>"`
38
49
  5. `git tag -a v<version> -m "Release <version>"`
39
50
 
40
- It does **not** push it prints the push command. Push with the GroepOnline SSH
41
- identity (the laptop default SSH key is denied for this org):
51
+ Locally it does **not** push unless you pass `--push` (CI does). Manual push
52
+ uses the GroepOnline SSH identity (the laptop default SSH key is denied):
42
53
 
43
54
  ```bash
44
55
  GIT_SSH_COMMAND='ssh -F ~/.ssh/config-groeponline -o IdentityFile=~/.ssh/sheesh' \
45
- git push origin HEAD --tags
56
+ git push origin HEAD refs/tags/vX.Y.Z
46
57
  ```
47
58
 
48
59
  - SSH host alias: `github.com-groeponline` (defined in `~/.ssh/config-groeponline` with `IdentityFile ~/.ssh/sheesh`, `IdentitiesOnly yes`).
@@ -57,12 +68,15 @@ GIT_SSH_COMMAND='ssh -F ~/.ssh/config-groeponline -o IdentityFile=~/.ssh/sheesh'
57
68
  3. `npm ci --ignore-scripts` (installs devDependencies incl. `typescript`)
58
69
  4. `npm run typecheck` (tsc)
59
70
  5. `npm test` (node test runner)
60
- 6. `npm publish --access public` with `NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}`
71
+ 6. `npm run verify:package` (catalog contract gate see `scripts/verify-package.mjs`)
72
+ 7. `npm publish --access public` with `NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}`
73
+ 8. Echoes the Pi catalog URLs (npm, pi.dev detail page, `?name=wishcraft`, `?name=groeponline`) for post-publish confirmation
61
74
 
62
- `NPM_TOKEN` is a GitHub Actions secret on the repo (publish rights to the
63
- `@groeponline` scope). It is **not** readable after being set; verify it works by
64
- checking that the publish step on a real release succeeds and `npm view` resolves
65
- the new version (see below).
75
+ `NPM_TOKEN` is the GroepOnline **org** Actions secret (publish rights to the
76
+ `@groeponline` scope). This repo has no override; Actions inherits the org
77
+ value. It is **not** readable after being set; verify it works by checking
78
+ that the publish step on a real release succeeds and `npm view` resolves the
79
+ new version (see below). The publish step fails closed if the secret is empty.
66
80
 
67
81
  The package has no build step — `*.ts` files are shipped directly (`pi.extensions:
68
82
  ["./index.ts"]`), and Pi loads them with TypeScript stripping at runtime.
@@ -115,6 +129,14 @@ A release is "done" when all four hold: local green, tag on origin, CI
115
129
 
116
130
  ## Versioning
117
131
 
118
- - **patch** (`0.15.0 0.15.1`): bug fixes, doc only.
119
- - **minor** (`0.15.x → 0.16.0`): new segments/presets, features, additive changes.
132
+ Feature PRs **do not bump** `package.json`. They stay on the last published npm
133
+ version (today: `0.18.0`) and append under `## [Unreleased]` in `CHANGELOG.md`.
134
+ The bump happens on `main` in the release workflow, not in the feature PR.
135
+
136
+ Never bump in the same PR as the feature work. Never tag from a stacked
137
+ feature branch. `0.19.0` exists only after `main` auto-tags (or a manual
138
+ `npm run release` on `main`).
139
+
140
+ - **patch** (`0.18.0 → 0.18.1`): bug fixes, doc only; escape hatch if 0.19 slips.
141
+ - **minor** (`0.18.x → 0.19.0`): new segments/presets, features, additive changes.
120
142
  - **major**: breaking changes to settings shape or exported API.
package/ROADMAP.md CHANGED
@@ -1,56 +1,377 @@
1
- # Roadmap — what to improve & how to integrate better
1
+ # Roadmap — pi-wishcraft
2
2
 
3
- Status after 0.18.0. Package is `@groeponline/pi-wishcraft` (renamed from `@groeponline/pi-powerline-footer` in 0.17.x; `src/` restructured by domain; `madge --circular` runs in CI). Concrete, prioritized. Not commitments — pick what Joep wants.
3
+ Herschreven 2026-08-18. Vierde pass 2026-08-20: conflict-restant uit
4
+ `19d6cc0` weg. 0.19-code + catalogus staan op main (#12, #11). Overlay-
5
+ submenus en de rest van de repairs blijven 0.20. CHE-40 is follow-up,
6
+ geen 0.19-blocker. Open: npm-tag 0.19.0 (PR C).
4
7
 
5
- ## Next release (0.19.0)
8
+ Pi core is de engine. Wishcraft is de cockpit. Elke feature dient één van
9
+ drie doelen: **grip** (skills, tokens, config), **prestatie** (repairs,
10
+ hooks, read-hints), of **leven** (overlays, vibes, detail views).
6
11
 
7
- - `npm deprecate @groeponline/pi-powerline-footer "Renamed to @groeponline/pi-wishcraft"` — the old package name still resolves on npm at 0.17.2 and is not deprecated yet. Needs the `@groeponline` scope owner's npm login (no publish auth on the laptop).
8
- - Generalize `segmentLabels` to every segment (today only tps/open_ports honor it; apply in `renderSegment`).
9
- - Per-segment `format`/`template` override (`segmentOptions.tps.template: "{value} tok/s"`).
10
- - Visibility toggle per segment from the `alt+p` menu (writes `powerline.disabledSegments` live).
11
- - `segmentOptions.tps.windowMs` — expose the 1s window length for fast models (Groq).
12
+ Elke release is één campagne met een done-criterium. P1 = deze release,
13
+ P2 = volgende, P3 = richting 1.0. Wat in 0.19 staat, shipt. Wat later
14
+ staat, start niet eerder.
12
15
 
13
- ## Already shipped
16
+ ---
14
17
 
15
- - 0.18.0 (wishcraft v2, #7): tab token completion, preset rework, git commit/ahead-behind extras, TPS in/out, `/skills` TUI, `src/extension` split into domain subfolders.
16
- - 0.17.x: package renamed to `@groeponline/pi-wishcraft`; `src/` restructure committed; `madge --circular` is a CI step in `test.yml`; inline skill/command invocation (`/` skills, `$` commands) landed in 0.17.3.
18
+ ## Waarom wij bestaan
17
19
 
18
- ## Correctness (done, keep honest)
20
+ De pi-extensiewereld heeft statusbalken. Ze heeft geen cockpit.
19
21
 
20
- - TPS = 1s sliding window over a 5s sample ring. **Verify it stays this way** if anyone touches `tpsSegment`. Do not regress to session-average or per-render EMA (both spike: `tps:12775`, `tps:1118`).
21
- - Open-ports = unique TCP by default; `openPorts.includeUdp` opts in. Column parsing is column-agnostic (ss + netstat).
22
- - Context segment hides on `contextWindow <= 0` (no more `NaN`/`??`).
22
+ **Upstream `nicobailon/pi-powerline-footer`** is een goede balk: git,
23
+ context, stash, compaction-queue, vibes, welcome, bash-mode. Wij zijn
24
+ daaruit gegroeid. Wat zij niet hebben, en wat onze publieke identiteit
25
+ is:
23
26
 
24
- ## Configurability improvements (next, low effort)
27
+ | Wij | Zij / de rest |
28
+ |---|---|
29
+ | Skills als OS: `/skills`, inline `/$`, usage, later doctor | Geen skill-manager |
30
+ | Idee → actie: `#`, `/idea`, `/ideas`, `/ideas issue` | Alleen compaction-hold queue |
31
+ | Eerlijke TPS: 1s-venster over 5s-ring, in/out gescheiden | Session-average of helemaal niks |
32
+ | Tab-token completion + git ahead/behind | Niet of later |
33
+ | Harness-laag (0.20): hooks + tool-input repairs op stock pi | Nergens in het extensie-ecosysteem |
25
34
 
26
- 1. **Labels for every segment, not just tps/open_ports.** Today `segmentLabels` is applied inside the two custom segments. Generalize: apply in `renderSegment` so `model`, `git`, `cost`, `context_pct`, `time`, … all honor a label. Small diff, big consistency win.
27
- 2. **Per-segment `format`/`template` override.** Let users set e.g. `segmentOptions.tps.template: "{value} tok/s"` or `time.format: "HH:mm"`. Template > label for full control.
28
- 3. **Visibility toggle per segment from the menu.** `Configure…` already changes preset/TPS/UDP/labels; add "disable segment" / "enable segment" that writes `powerline.disabledSegments` live (no edit-the-JSON round-trip).
29
- 4. **Preset editor in the menu.** Build a custom preset interactively (pick left/right segments) and save it to settings — today custom presets are JSON-only.
30
- 5. **`segmentOptions.tps.windowMs`** — expose the 1s window length so fast models (Groq) can widen it for a smoother read.
35
+ **oh-my-pi** is een hele agent-fork (~80k regels Rust-core, eigen tools,
36
+ LSP, DAP). Dat is een ander product. Wij forken Mario's pi niet. Alles
37
+ wat we willen van oh-my-pi vertalen we naar een extensie of we laten het
38
+ liggen. De weddenschap: de beste cockpit op stock pi wint van een
39
+ tweede engine.
31
40
 
32
- ## Interaction improvements (the "levendig + klikbaar" thread)
41
+ **Command Code** is een commerciële harness (hooks, tool-call repairs,
42
+ read-tool engineering). Hun inzicht klopt: open modellen falen op het
43
+ contract, niet op "slimheid". Wij kopiëren hun product niet. We gieten
44
+ dezelfde principes in wat Pi al native biedt:
33
45
 
34
- 1. **Sub-menus via stacked overlays.** `ctx.ui.custom()` closes on `done()`; a sub-menu opens a new `custom()`. Today the menu uses `ctx.ui.select` (flat). Upgrade the navigator + configure to overlay `SelectList` for arrow nav + descriptions, matching the segment-navigator chrome.
35
- 2. **Per-segment "more info" on a second key.** In the navigator, `enter` activates, `→`/`tab` opens a detail view for that segment (full ports list, git diff summary, cost breakdown, context window math). This is the "soort gelijk menu maar anders waar je bijv alle open ports kan zien" Joep asked for.
36
- 3. **Live refresh while the overlay is open.** Overlays re-render on `tui.requestRender()`; wire a light timer so the ports list / TPS detail tick while open.
37
- 4. **Mouse support** not available; Pi core owns the footer. Keep documenting that overlay nav is the equivalent.
46
+ - `pi.on("tool_call")` `event.input` is mutable; `block` + `reason` +
47
+ `terminate` bestaan (`pi-coding-agent` 0.84.x
48
+ `dist/core/extensions/types.d.ts`).
49
+ - `pi.on("tool_result")`resultaat muteren.
50
+ - `pi.on("session_start" | "input" | "turn_end")`.
38
51
 
39
- ## Integration with ChefGroep surfaces
52
+ Geen core-patch. Geen tweede agent. Iedereen die `pi` draait kan de
53
+ cockpit + harness installeren.
40
54
 
41
- 1. **ChefBar / command center.** Expose powerline state (preset, TPS, ports, cost) via `ctx.ui.setStatus("powerline-tps", …)` so ChefBar/other extensions can read it. Already partly there (extension statuses); formalize a stable key set (`powerline.tps`, `powerline.ports`, `powerline.preset`).
42
- 2. **joep-ops / Vault dashboard.** The same `ss`/token data could feed a fleet dashboard. Factor `countListeningPorts` + a token-rate sampler into a tiny shared module both can import (keep it in this repo, export it).
43
- 3. **PostHog.** Capture preset/menu usage events (`powerline.preset_changed`, `powerline.menu_opened`) per the org instrumentation rule — only if Joep opts in; the bar itself stays telemetry-free.
44
- 4. **Fleet (sofie/bc-scan-2).** `open_ports` is laptop-local. A fleet variant could SSH-probe a named host's ports; gate behind a `segmentOptions.openPorts.host` setting.
55
+ **ChefGroep** (ChefBar-statuskeys, fleet-ports) is een privé-bonus, niet
56
+ de publieke pitch. De npm-pagina moet leesbaar zijn voor iemand die pi
57
+ gisteren installeerde.
45
58
 
46
- ## Release/quality
59
+ Kort: **wij zijn de cockpit + harness voor stock pi.** Niet de balk.
60
+ Niet de fork. Niet de SaaS-agent.
47
61
 
48
- 1. **Dependabot vulns** — GitHub flagged 7 (3 high, 4 moderate) on default branch. Triage; most are devDep transitive. Add `npm audit` to CI as non-blocking info, or pin.
49
- 2. **Test the menu.** The overlay/menu functions aren't unit-tested (hard to test `ctx.ui.custom` headless). Add a thin `SelectList`-based pure function for "build segment items" and test that, leaving the overlay shell untested.
50
- 3. **Typecheck in pre-push.** `prepublishOnly` already runs `tsc` so a bad type never ships even if CI is skipped.
62
+ ---
51
63
 
52
- ## Not doing (YAGNI)
64
+ ## Wat wij niet worden
53
65
 
54
- - No mouse/click on the live footer (Pi core limitation; overlay nav is the path).
55
- - No custom "embed/component" registration for footer segments — segments are data (text), and `customItems` + `command/env/static` segments already cover user-defined content. `setWidget`/`registerEntryRenderer` are for chat, not the footer.
56
- - No third control surface — keep interactivity in this extension's overlays + commands.
66
+ - Geen agent-fork. Geen oh-my-pi-lite.
67
+ - Geen derde control surface naast ChefBar / Kater. Overlays blijven in
68
+ deze extensie.
69
+ - Geen muis op de live footer. Pi core bezit die; overlay-navigatie is
70
+ het pad.
71
+ - Geen eigen bulk-read tool. Core's verantwoordelijkheid; wij leveren
72
+ repairs + hints eromheen.
73
+ - Geen PostHog in de balk. Events alleen op expliciete Joep-opt-in.
74
+ - Geen custom embed/component-registratie voor footer-segments.
75
+ Segments zijn data; `customItems` + `command/env/static` dekken
76
+ gebruikerscontent.
77
+ - Geen skills-markt als identiteit vóór 1.0. Eerst discovery die klopt
78
+ en een manager die zoekt.
79
+ - Geen fleet-SSH `open_ports` totdat iemand het concreet vraagt.
80
+ - Geen versie-reset naar 1.0.0. We blijven op 0.19 → 0.20 → 1.0 wanneer
81
+ de cockpit stabiel is.
82
+
83
+ ---
84
+
85
+ ## Mijlpalen
86
+
87
+ - **0.19.0 — "Correctheid"** (deze campagne). Bugs en hygiëne eerst.
88
+ Kleine config-afmakers. Geen hooks, geen repairs, geen manager-v2-UI,
89
+ geen overlay-submenus. Done = npm 0.19.0 live, `/skills` filtert,
90
+ `$test` expandeert geen debris, `npm test` + `npm run typecheck` +
91
+ `madge --circular` groen op de tag. Als de config-PR uitloopt:
92
+ tag **0.18.1** met alleen PR A (bugs). Correctheid wacht niet op
93
+ labels.
94
+ - **0.20.0 — "Harness"**. Hooks + tool-input repairs + skills-manager
95
+ v2-UI + token-overlays. Done = drie README-hookvoorbeelden werken,
96
+ repair-teller zichtbaar, `/skills` zoekt op naam+beschrijving+pad.
97
+ - **1.0 — "Cockpit"**. Skills-doctor/install, declaratieve policy,
98
+ preset-editor, idee-review, stabiele ChefGroep-statuskeys,
99
+ documentatie die waar is. Done = README dekt alles wat we shipten,
100
+ geen kapotte footer-belofte.
101
+
102
+ ---
103
+
104
+ ## 0.19.0 — Correctheid
105
+
106
+ Eén campagne, drie stacked PRs. Volgorde vast. Elke PR: `npm run
107
+ typecheck && npm test && npx madge --circular src index.ts bash-mode
108
+ queue` groen vóór review. Overlay-submenus (CHE-42) zitten in 0.20.
109
+
110
+ ### PR A — runtime-bugs — ✅ geland in `feat/wishcraft-0.19` (samen met skills v2, hooks, lantern-welcome, `/wishcraft` config-TUI; supersedeert #10)
111
+
112
+ Alle zes punten uit het oorspronkelijke plan zitten in de ene 0.19-branch:
113
+ debris weg, filter werkend (v2: substring i.p.v. prefix), cache-invalide op
114
+ `session_start` + TTL, woordgrens op inline-triggers, unclosed-fence EOF,
115
+ bash-session tempdir + sentinel-colon, `permissions: contents: read`.
116
+ `npm pack --dry-run` bevat geen debris (113 files, geen `ook.md`/`test.md`).
117
+
118
+ ### PR B — config-afmakers — ✅ geland in `feat/wishcraft-0.19` / #12
119
+
120
+ Bestanden: `src/config/`, `src/segments/`, `src/extension/ui/`.
121
+
122
+ 1. `segmentLabels` toepassen in `renderSegment` voor **alle** segments
123
+ (nu alleen tps/open_ports/subagents).
124
+ 2. `segmentOptions.<seg>.template` wint van label
125
+ (`"{value} tok/s"`).
126
+ 3. `segmentOptions.tps.windowMs` (default 1000), `.mode`
127
+ (`both | out | in | total`), `.hideIdle` (default true).
128
+ 4. Visibility-toggle in het `alt+p`-menu schrijft live
129
+ `powerline.disabledSegments`.
130
+
131
+ Done: unit tests op label/template/windowMs-resolutie; handmatige
132
+ check: label op `git` + `cost` zichtbaar, TPS hidden bij 0 wanneer
133
+ `hideIdle`.
134
+
135
+ ### PR C — release 0.19.0
136
+
137
+ 1. Merge naar `main` triggert `release.yml`: `node scripts/release.mjs auto --push`.
138
+ Commits sinds `v0.18.0` bevatten `feat:` → **0.19.0**. Handmatig blijft
139
+ `npm run release minor` + tag-push mogelijk.
140
+ 2. Tag-job publiceert met org-secret `NPM_TOKEN` (geen repo-override).
141
+ 3. Verify: tag op origin, publish-job groen, `npm view @groeponline/pi-wishcraft version` = 0.19.0.
142
+ Catalogus (hard): `npm run verify:package` groen in de release-job;
143
+ `npm view @groeponline/pi-wishcraft keywords` bevat `pi-package`,
144
+ `pi-extension`, `wishcraft`; `pi.image` is de banner-URL.
145
+ Daarna:
146
+ - https://pi.dev/packages/@groeponline/pi-wishcraft toont 0.19.0
147
+ - https://pi.dev/packages?name=wishcraft toont de card
148
+ - https://pi.dev/packages?name=groeponline toont wishcraft naast
149
+ fff en orchestrator
150
+ Detailpagina bestaat al voor 0.18.0; de zoekindex niet. Nieuwe
151
+ publish + discovery-keywords is de refresh. Catalogus-lag tot
152
+ een paar uur is oké; ontbreken na 24u = 0.19.1 met dezelfde
153
+ metadata, geen stille "later wel".
154
+ 4. README: skills-sectie zegt dat filter werkt; geen `ook`/`test`
155
+ debris. ROADMAP sync (deze file).
156
+ 5. `npm deprecate @groeponline/pi-powerline-footer` blijft een
157
+ scope-owner actie buiten deze PR (`deprecate-old-name.yml`,
158
+ workflow_dispatch). Blokkeert 0.19 niet.
159
+
160
+ Hygiëne die al klaar is en niet opnieuw gepland wordt:
161
+
162
+ - Fork-tags weg (51 upstream-tags, 2026-08-18). Eigen reeks vanaf
163
+ `v0.10.0`.
164
+ - `banner.png` blijft (README). `wishcraft-concept.png` gaat weg in
165
+ PR A of een docs-PR, niet in de balk-runtime.
166
+ - CHANGELOG inkorten (GRO-1060) doen we **niet** in 0.19. Erfgoed
167
+ is history, geen cruft.
168
+ - Versie blijft 0.19, geen reset naar 1.0.0.
169
+
170
+ GRO-1061 (runner-queue) is ops, geen product-slice.
171
+
172
+ ---
173
+
174
+ ## 0.20.0 — Harness
175
+
176
+ Vier stacked PRs. Pas starten als 0.19 (of 0.18.1) op npm staat.
177
+
178
+ Overlay-chrome kit, één keer, daarna hergebruiken: box + ronde hoeken,
179
+ accent-kop, dim metadata, rechts uitgelijnde counts, `→` detail /
180
+ `←` terug / `esc` weg, consistente footer-hints. Eerste consument =
181
+ skills v2; tweede = `/usage`; derde = queue/idea. Pure render-
182
+ functies, geen `ctx.ui`-mock.
183
+
184
+ ### PR E — hooks — ✅ geland in `feat/wishcraft-0.19` (`src/extension/hooks/`, `/repairs` stats-command; README-voorbeelden volgen in de release-PR)
185
+
186
+ Settings: `wishcraft.hooks` met events
187
+ `preToolUse | postToolUse | sessionStart | turnEnd`. Per hook
188
+ `matcher` (toolName-regex) en `command` (JSON stdin/stdout, timeout
189
+ 30s, max 600s). PreToolUse: `allow | deny` + reason die het model
190
+ ziet. Exit 2 = deny, stderr-eerste-regel = reason. PostToolUse /
191
+ SessionStart: `additionalContext`. Kill-switch
192
+ `wishcraft.hooksEnabled: false`. PreToolUse sequentieel (eerste deny
193
+ stopt); PostToolUse/turnEnd parallel.
194
+
195
+ Done: `parseHookOutput` unit-testen. README met drie werkende
196
+ voorbeelden: bash-guard (`rm -rf /` blokkeren), write-audit
197
+ (append-only log), SessionStart git-status injectie.
198
+
199
+ ### PR F — tool-input repairs — ✅ geland in `feat/wishcraft-0.19` (schema-loze subset: null-for-optional + auto-link unwrap; schema-afhankelijke repairs wachten op validator-issues in pi core)
200
+
201
+ `tool_call`-handler repareert bekende malformaties vóór executie
202
+ (mutable input). Volgorde vast: json-parse vóór bare-wrap.
203
+
204
+ 1. `null` voor optioneel weglaten.
205
+ 2. JSON-string-array → array.
206
+ 3. `{}`-placeholder → array.
207
+ 4. bare-string → array-wrap.
208
+ 5. markdown-auto-link pads (`[x.md](http://x.md)` → `x.md`).
209
+ 6. pad-alias `filePath` / `absolutePath` / `target_file` → `path`.
210
+
211
+ Repair-teller per `(tool, repair)` als extension status.
212
+ `wishcraft.repairsEnabled` default true. Scope: custom tools +
213
+ extensie-tools. Pi core-tools laten we met rust — core valideert
214
+ zijn eigen schema's.
215
+
216
+ Done: pure `repairToolInput(tool, input)` + table-driven tests voor
217
+ de zes gevallen + de parse-vóór-wrap invariant.
218
+
219
+ ### PR G — overlay-submenus (CHE-42)
220
+
221
+ Het `alt+p`-menu krijgt gestapelde `SelectList`-overlays (pijltjes +
222
+ descriptions) in plaats van platte `ctx.ui.select`. Max drie
223
+ top-level ingangen. Pure functie `buildPowerlineMenuItems`
224
+ unit-testen. Sluit CHE-42. CHE-40 (`/powerline <tab>` subcommands)
225
+ blijft open — 0.18 shipped alleen bash token-step, niet deze
226
+ hiërarchie. Landt in 0.19 PR B of een kleine follow-up. CHE-41
227
+ wordt de per-segment detail view in 1.0, geen tweede `alt+i`-pad.
228
+
229
+ ### PR H — skills manager v2 UI + token-overlays
230
+
231
+ Vervangt `skill-manager.ts` (242 regels). Data-laag bouwt op Pi
232
+ core `loadSkills` / `loadSkillsFromDir` / `Skill` /
233
+ `SkillFrontmatter` (publiek geëxporteerd in
234
+ `@earendil-works/pi-coding-agent`).
235
+
236
+ UI, niet onderhandelbaar:
237
+
238
+ - Zoeken die werkt: substring op naam + beschrijving + pad,
239
+ case-insensitive; `ctrl+u` wist; lege match = rij
240
+ `geen skills voor '<q>'`.
241
+ - Categorieën met kopregels (bundled / global / project / prompts);
242
+ `tab` wisselt filter; `s` sorteert naam ↔ gebruik.
243
+ - `→` detail (frontmatter-tabel, usage, pad, body + scroll);
244
+ `enter` insert; `e` opent `$EDITOR` (default nvim) via extern
245
+ spawn zoals pi's `!`; `n` nieuwe skill in
246
+ `~/.pi/agent/skills/<naam>/SKILL.md`; `d` delete + confirm.
247
+ - Usage-ledger `~/.pi/agent/skill-usage.json` (naam, timestamp,
248
+ trigger-type). Best-effort, nooit blokkerend op de input hot path.
249
+ - Skill health: core-diagnostics als waarschuwingsicoon; `?` legt
250
+ het uit.
251
+
252
+ Zelfde chrome als de segment-navigator. Nederlands, direct.
253
+
254
+ Tegelijk, klein:
255
+
256
+ - `/tps` overlay: in/out, piek + gemiddelde over de bestaande ring.
257
+ Geen nieuwe sampler.
258
+ - `/usage` overlay: vandaag / deze week / deze sessie; per model;
259
+ cache-hit %; ASCII-sparkline. File
260
+ `~/.pi/agent/wishcraft-usage.json` (append-only, compaction bij
261
+ drempel).
262
+ - `wishcraft.tokenBudget.daily` kleurt het segment rood en waarschuwt
263
+ in welcome bij 80% / 100%. Nooit blokkerend.
264
+
265
+ Done: filter-tests op substring; usage-ledger tests; `/tps` leest
266
+ dezelfde ring als het segment (geen tweede waarheid).
267
+
268
+ ---
269
+
270
+ ## 1.0 — Cockpit
271
+
272
+ Pas na 0.20. Geen parallelle 1.0-tak.
273
+
274
+ 1. **`/skills doctor`** — kapot frontmatter, te lange descriptions
275
+ (prompt-budget), duplicates global/project, ongebruikte skills.
276
+ Tabel, geen essay.
277
+ 2. **`/skills new` templates** — standaard, browser-workflow,
278
+ CLI-workflow, review-checklist. Install-van-GitHub/npm is
279
+ post-1.0; 1.0 is doctor + templates, geen markt.
280
+ 3. **Policy engine** — hooks zonder spawn: `deny bash matching
281
+ "sudo rm"`, `context inject when reading .env`. Command-hooks
282
+ blijven voor alles wat niet in een regel past.
283
+ 4. **Preset editor** — links/rechts segmenten kiezen in het menu,
284
+ opslaan in settings. Vandaag is custom JSON-only.
285
+ 5. **Per-segment detail** (CHE-41): `→` in de navigator opent
286
+ ports-lijst, git-samenvatting, cost-breakdown, context-math.
287
+ Refresh bij openen, geen 500ms-timer.
288
+ 6. **Idee-review** — `/ideas` in dezelfde overlay-taal; status
289
+ idea / in-progress / done; tags; "verwerk met skill X".
290
+ Welcome queue-widget: item oppakken → prompt.
291
+ 7. **ChefGroep-keys** — stabiel `powerline.tps`, `powerline.ports`,
292
+ `powerline.preset`, `powerline.skills.count` via
293
+ `ctx.ui.setStatus`.
294
+ 8. **Read-tool hints** — `tool_result` op `read` verrijken met
295
+ "N regels, M–K getoond, volgende offset" alleen als core dat
296
+ niet zelf al geeft. Eerst meten, dan aanvullen.
297
+
298
+ ---
299
+
300
+ ## Linear
301
+
302
+ | Ticket | Actie |
303
+ |---|---|
304
+ | GRO-1060 fork cleanup | Deels gedaan (tags). Rest = PR A debris + concept-png. CHANGELOG niet inkorten. Versie niet resetten. |
305
+ | GRO-1061 CI queue | Ops, niet deze roadmap. |
306
+ | CHE-40 `/powerline` tab | Open. 0.18 shipped bash token-step, niet `/powerline set <tab>`. Fold in PR B of follow-up. |
307
+ | CHE-41 alt+i info | Wordt 1.0 detail-view. Ticket hernoemen of GRO-child. |
308
+ | CHE-42 drill-down | = 0.20 PR G. Hernoemen naar wishcraft / GRO. |
309
+
310
+ Oude `pi-powerline-footer`-projecttickets niet laten staan alsof
311
+ die package nog leeft.
312
+
313
+ ---
314
+
315
+ ## Kwaliteit (altijd)
316
+
317
+ - Overlay-logica testbaar via pure functies. Geen headless `ctx.ui`.
318
+ - `prepublishOnly` = `tsc --noEmit`. Een slecht type ship't niet.
319
+ - `madge --circular` blijft CI. Nieuwe map in `src/` → check mee.
320
+ - Dependabot-vulns (devDep-transitief): waiven, track op GRO-603.
321
+ Niet required in CI. Geen stille bump van TypeScript 7 of
322
+ `@types/node` 26 in een bug-PR.
323
+ - TPS-core blijft 1s sliding window over 5s-ring. Geen regressie
324
+ naar session-average of per-render EMA (beide spikten:
325
+ `tps:12775`).
326
+
327
+ ---
328
+
329
+ ## Residual risks
330
+
331
+ - `SelectList.setFilter` matcht alleen prefix op `value`. 0.19
332
+ accepteert dat; 0.20 vervangt het.
333
+ - `npm deprecate` van de oude naam faalt tot de scope-owner het
334
+ token verruimt. Gebruikers die `pi-powerline-footer` installeren
335
+ blijven op 0.17.2.
336
+ - Hooks spawnen processen. Default timeout 30s; kill-switch moet
337
+ in 0.20 vanaf dag één bestaan.
338
+ - Repairs op core-tools raken we niet aan. Als DeepSeek-achtige
339
+ modellen daar alsnog op stuklopen, is dat een gesprek met pi
340
+ core, geen stille override.
341
+ - `loadSkills` API-drift: we pinnen `@earendil-works/pi-coding-agent`
342
+ `>=0.81.0 <0.85.0`. 0.20 neemt de publieke export over; bij
343
+ breaking change blijven we op eigen scan tot de pin omhoog kan.
344
+ - Usage-ledger corruptie: best-effort write, kapot JSON → leeg
345
+ object, nooit throw op de input-path.
346
+ - ChefGroep-keys in 1.0 mogen de publieke README niet gijzelen.
347
+
348
+ ---
349
+
350
+ ## Rollback
351
+
352
+ - PR A–H: revert-commit op `main`. Geen force-push.
353
+ - 0.19-tag te vroeg: laat de tag staan, ship `0.19.1` met de fix.
354
+ Tags niet herschrijven.
355
+ - Fork-tags (51 stuks) zijn weg. Recovery = upstream remote
356
+ `nicobailon/pi-powerline-footer` opnieuw fetchen, niet onze
357
+ `v0.10.0+` overschrijven.
358
+ - DevDep-bumps (pi-* 0.84.2, TS 7) horen in een eigen PR met
359
+ `npm ci` + de verify-trio. Revert = die PR revert + `npm ci`.
360
+
361
+ ---
362
+
363
+ ## Checklist (1:1 met 0.19)
364
+
365
+ - [x] PR A gemerged: filter, debris, cache, triggers, bash-leaks,
366
+ CodeQL. Verify-trio groen. (#12)
367
+ - [x] `npm pack --dry-run` bevat geen `ook.md` / `test.md`.
368
+ - [x] PR B gemerged: labels, template, TPS-opties, visibility.
369
+ Verify-trio groen. (#12)
370
+ - [x] Gallery-contract gemerged (`chore/pi-dev-gallery`): keywords,
371
+ `publishConfig.access`, `pi.image`, `npm run verify:package`. (#11)
372
+ - [ ] PR C: `npm run release minor` → 0.19.0 (of 0.18.1 als alleen
373
+ A klaar is). Tag + publish + `npm view` klopt + pi.dev card
374
+ naast fff/orchestrator.
375
+ - [ ] README skills-sectie waar; deze ROADMAP in sync.
376
+ - [ ] CHE-40: `/powerline` subcommand-tab landt of blijft een
377
+ open GRO-child. CHE-41/42 hernoemen.
@@ -1,4 +1,4 @@
1
- import { mkdtempSync, writeFileSync } from "node:fs";
1
+ import { mkdtempSync, rmSync, writeFileSync } from "node:fs";
2
2
  import { tmpdir } from "node:os";
3
3
  import { basename, join } from "node:path";
4
4
  import { spawn, type ChildProcessWithoutNullStreams } from "node:child_process";
@@ -214,6 +214,11 @@ export class ManagedShellSession {
214
214
  this.readyPromise = null;
215
215
  this.readyResolve = null;
216
216
  this.readyReject = null;
217
+ try {
218
+ rmSync(this.tempDir, { recursive: true, force: true });
219
+ } catch {
220
+ // tempdir opruimen is best-effort
221
+ }
217
222
  if (!this.process) return;
218
223
  try {
219
224
  process.kill(-this.process.pid!, "SIGKILL");
@@ -252,7 +257,10 @@ export class ManagedShellSession {
252
257
  }
253
258
 
254
259
  if (line.startsWith(`${COMMAND_START_SENTINEL}:`)) {
255
- const [, id, cwd] = line.split(":");
260
+ // cwd kan zelf ':' bevatten: alles na het tweede veld is cwd
261
+ const parts = line.split(":");
262
+ const id = parts[1];
263
+ const cwd = parts.slice(2).join(":");
256
264
  if (cwd) this.state.cwd = cwd;
257
265
  this.currentCommandId = id ?? this.currentCommandId;
258
266
  this.onStateChange();
@@ -260,7 +268,10 @@ export class ManagedShellSession {
260
268
  }
261
269
 
262
270
  if (line.startsWith(`${COMMAND_DONE_SENTINEL}:`)) {
263
- const [, id, exitCodeText, cwd] = line.split(":");
271
+ const parts = line.split(":");
272
+ const id = parts[1];
273
+ const exitCodeText = parts[2];
274
+ const cwd = parts.slice(3).join(":");
264
275
  const exitCode = Number.parseInt(exitCodeText ?? "1", 10);
265
276
  this.state.running = false;
266
277
  this.state.lastExitCode = Number.isFinite(exitCode) ? exitCode : 1;
package/package.json CHANGED
@@ -1,26 +1,33 @@
1
1
  {
2
2
  "name": "@groeponline/pi-wishcraft",
3
- "version": "0.18.0",
4
- "description": "Wishcraft status bar & interaction layer for the pi coding agent — powerline segments, vibes, queue, bash mode, and full customization.",
3
+ "version": "0.19.0",
4
+ "description": "Wishcraft cockpit for the pi coding agent — powerline status, vibes, idea inbox, bash mode, and full customization.",
5
5
  "type": "module",
6
6
  "files": [
7
7
  "*.ts",
8
8
  "*.md",
9
9
  "*.json",
10
10
  "src/**/*.ts",
11
- "src/**/*.md",
12
11
  "src/**/*.txt",
13
12
  "bash-mode/**/*.ts",
14
13
  "queue/**/*.ts"
15
14
  ],
16
15
  "keywords": [
17
16
  "pi-package",
17
+ "pi-extension",
18
+ "pi-coding-agent",
18
19
  "pi",
20
+ "wishcraft",
21
+ "cockpit",
19
22
  "coding-agent",
20
23
  "powerline",
21
24
  "status-bar",
22
25
  "extension"
23
26
  ],
27
+ "publishConfig": {
28
+ "access": "public",
29
+ "registry": "https://registry.npmjs.org"
30
+ },
24
31
  "author": "GroepOnline",
25
32
  "license": "MIT",
26
33
  "homepage": "https://github.com/GroepOnline/pi-wishcraft#readme",
@@ -35,7 +42,8 @@
35
42
  "typecheck": "tsc --noEmit",
36
43
  "test": "node --experimental-strip-types --test tests/**/*.test.ts",
37
44
  "release": "node scripts/release.mjs",
38
- "prepublishOnly": "tsc --noEmit",
45
+ "prepublishOnly": "tsc --noEmit && node scripts/verify-package.mjs",
46
+ "verify:package": "node scripts/verify-package.mjs",
39
47
  "circular": "madge --circular src index.ts bash-mode queue"
40
48
  },
41
49
  "peerDependencies": {
@@ -54,6 +62,7 @@
54
62
  "pi": {
55
63
  "extensions": [
56
64
  "./index.ts"
57
- ]
65
+ ],
66
+ "image": "https://raw.githubusercontent.com/GroepOnline/pi-wishcraft/main/banner.png"
58
67
  }
59
68
  }