@groeponline/pi-wishcraft 0.19.0 → 0.19.2

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,5 +1,17 @@
1
1
  # Changelog
2
2
 
3
+ ## [Unreleased]
4
+
5
+ ## [0.19.2] - 2026-08-20
6
+
7
+ ### Added
8
+ - `/powerline` tab-completes built-in presets and `placement above|below|toggle`.
9
+
10
+ ## [0.19.1] - 2026-08-20
11
+
12
+ ### Fixed
13
+ - Release workflow publishes from the bump job. A `GITHUB_TOKEN` tag push does not start a second workflow, so waiting for the tag event left `v0.19.0` unpublished. `npm view` failures other than not-found abort; tests run on `origin/main` before the tag is cut.
14
+
3
15
  ## [0.19.0] - 2026-08-20
4
16
 
5
17
  ### Added
package/README.md CHANGED
@@ -68,7 +68,7 @@ Restart or `/reload` pi to activate.
68
68
 
69
69
  ## Usage
70
70
 
71
- Activates automatically. Toggle with `/powerline`, switch presets with `/powerline <name>`, and move the primary row with `/powerline placement above|below|toggle`.
71
+ Activates automatically. Toggle with `/powerline`, switch presets with `/powerline <name>`, and move the primary row with `/powerline placement above|below|toggle`. Tab after `/powerline` completes preset names and `placement`; tab again after `placement` completes `above`, `below`, or `toggle`.
72
72
 
73
73
  Use `/cd <path>` to continue the current conversation from another working directory. It supports relative paths, absolute paths, `~`, `~/...`, and directory completions. With no argument, `/cd` prints the current Pi session directory. The command switches into a cwd-updated session file so Pi tools and the footer path segment agree after the change.
74
74
 
package/RELEASE.md CHANGED
@@ -18,9 +18,13 @@ verify it.
18
18
  ## The release flow
19
19
 
20
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.
21
+ runs `node scripts/release.mjs auto --push` on `main` and publishes in that
22
+ same job (`scripts/npm-publish.sh`) with the GroepOnline org secret
23
+ `NPM_TOKEN`. A tag pushed with `GITHUB_TOKEN` does **not** start another
24
+ workflow, so publish cannot wait for the tag event. Manual SSH/PAT tag
25
+ pushes still run the tag job. `auto` reads commit subjects since the last
26
+ `v*` tag: `feat:` → minor, `feat!:` / `BREAKING CHANGE` → major, otherwise
27
+ patch.
24
28
 
25
29
  The first merge after `v0.18.0` therefore becomes **0.19.0** (the 0.19
26
30
  `feat:` commits are already on `main`). Later docs/fix merges become
@@ -59,18 +63,21 @@ GIT_SSH_COMMAND='ssh -F ~/.ssh/config-groeponline -o IdentityFile=~/.ssh/sheesh'
59
63
  - SSH host alias: `github.com-groeponline` (defined in `~/.ssh/config-groeponline` with `IdentityFile ~/.ssh/sheesh`, `IdentitiesOnly yes`).
60
64
  - Push actor: `chefadmin-netizen` (GroepOnline SSH). API/`gh` actor: `MisterWanted` (FG) via `chef-gh`.
61
65
 
62
- ## CI publish (on tag)
66
+ ## CI publish
63
67
 
64
- `.github/workflows/release.yml` triggers on `push: tags: ['v*']`:
68
+ `.github/workflows/release.yml` publishes from the **bump job** after tagging,
69
+ and also from a tag push (manual SSH/PAT). `GITHUB_TOKEN` tag pushes do not
70
+ start a second run.
65
71
 
66
- 1. `actions/checkout@v4`
72
+ 1. `actions/checkout@v4` (`fetch-depth: 0`, `fetch-tags: true`)
67
73
  2. `actions/setup-node@v4` (node 24, `registry-url: https://registry.npmjs.org`)
68
- 3. `npm ci --ignore-scripts` (installs devDependencies incl. `typescript`)
69
- 4. `npm run typecheck` (tsc)
70
- 5. `npm test` (node test runner)
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
74
+ 3. Fetch and `git reset --hard origin/main` (bump job only; tests the tree that will be tagged)
75
+ 4. `npm ci --ignore-scripts` (installs devDependencies incl. `typescript`)
76
+ 5. `npm run typecheck` (tsc)
77
+ 6. `npm test` (node test runner)
78
+ 7. `npm run verify:package` (catalog contract gate see `scripts/verify-package.mjs`)
79
+ 8. `node scripts/release.mjs auto --push` (main only)
80
+ 9. `sh scripts/npm-publish.sh` with `NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}` (fail-closed `npm view`, idempotent skip, then the Pi catalog URLs)
74
81
 
75
82
  `NPM_TOKEN` is the GroepOnline **org** Actions secret (publish rights to the
76
83
  `@groeponline` scope). This repo has no override; Actions inherits the org
@@ -130,7 +137,7 @@ A release is "done" when all four hold: local green, tag on origin, CI
130
137
  ## Versioning
131
138
 
132
139
  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`.
140
+ version (today: `0.19.0`) and append under `## [Unreleased]` in `CHANGELOG.md`.
134
141
  The bump happens on `main` in the release workflow, not in the feature PR.
135
142
 
136
143
  Never bump in the same PR as the feature work. Never tag from a stacked
package/ROADMAP.md CHANGED
@@ -3,7 +3,7 @@
3
3
  Herschreven 2026-08-18. Vierde pass 2026-08-20: conflict-restant uit
4
4
  `19d6cc0` weg. 0.19-code + catalogus staan op main (#12, #11). Overlay-
5
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).
6
+ geen 0.19-blocker. `v0.19.0` en `v0.19.1` staan op npm.
7
7
 
8
8
  Pi core is de engine. Wishcraft is de cockpit. Elke feature dient één van
9
9
  drie doelen: **grip** (skills, tokens, config), **prestatie** (repairs,
@@ -303,7 +303,7 @@ Pas na 0.20. Geen parallelle 1.0-tak.
303
303
  |---|---|
304
304
  | GRO-1060 fork cleanup | Deels gedaan (tags). Rest = PR A debris + concept-png. CHANGELOG niet inkorten. Versie niet resetten. |
305
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. |
306
+ | CHE-40 `/powerline` tab | In Progress. `/powerline` tab completes presets and placement above, below, or toggle. |
307
307
  | CHE-41 alt+i info | Wordt 1.0 detail-view. Ticket hernoemen of GRO-child. |
308
308
  | CHE-42 drill-down | = 0.20 PR G. Hernoemen naar wishcraft / GRO. |
309
309
 
@@ -369,9 +369,8 @@ die package nog leeft.
369
369
  Verify-trio groen. (#12)
370
370
  - [x] Gallery-contract gemerged (`chore/pi-dev-gallery`): keywords,
371
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.
372
+ - [x] PR C: merge to `main` tagged `v0.19.0` then `v0.19.1` and published
373
+ (`npm view` = `0.19.1`). Same-job bump publish via #16.
375
374
  - [ ] README skills-sectie waar; deze ROADMAP in sync.
376
- - [ ] CHE-40: `/powerline` subcommand-tab landt of blijft een
375
+ - [ ] CHE-40: `/powerline` subcommand-tab landt (deze branch) of blijft een
377
376
  open GRO-child. CHE-41/42 hernoemen.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@groeponline/pi-wishcraft",
3
- "version": "0.19.0",
3
+ "version": "0.19.2",
4
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": [
@@ -29,6 +29,7 @@ import {
29
29
  } from "../core/segment-context.ts";
30
30
  import { config, normalizePreset } from "../core/state.ts";
31
31
  import type { RuntimeState } from "../core/types.ts";
32
+ import { getPowerlineArgumentCompletions } from "./powerline-completions.ts";
32
33
 
33
34
  export function registerCommands(pi: ExtensionAPI, rt: RuntimeState): void {
34
35
  registerCdCommand(pi, () => rt.currentCtx?.cwd ?? process.cwd());
@@ -39,7 +40,10 @@ export function registerCommands(pi: ExtensionAPI, rt: RuntimeState): void {
39
40
 
40
41
  // Command to toggle/configure
41
42
  pi.registerCommand("powerline", {
42
- description: "Configure powerline status (toggle, preset)",
43
+ description: "Configure powerline status (toggle, preset, placement)",
44
+ getArgumentCompletions(argumentPrefix) {
45
+ return getPowerlineArgumentCompletions(argumentPrefix);
46
+ },
43
47
  handler: async (args, ctx) => {
44
48
  // Update context reference (command ctx may have more methods)
45
49
  rt.currentCtx = ctx;
@@ -0,0 +1,107 @@
1
+ import type { AutocompleteItem } from "@earendil-works/pi-tui";
2
+ import { PRESETS } from "../../config/presets.ts";
3
+
4
+ export const POWERLINE_PLACEMENT_VALUES = ["above", "below", "toggle"] as const;
5
+
6
+ export const POWERLINE_SUBCOMMANDS: ReadonlyArray<{
7
+ value: string;
8
+ description: string;
9
+ }> = [
10
+ {
11
+ value: "placement",
12
+ description: "Move the primary row above or below the editor",
13
+ },
14
+ ];
15
+
16
+ const PLACEMENT_DESCRIPTIONS: Record<(typeof POWERLINE_PLACEMENT_VALUES)[number], string> = {
17
+ above: "Primary row above the editor",
18
+ below: "Primary row below the editor",
19
+ toggle: "Switch between above and below",
20
+ };
21
+
22
+ export function listPowerlinePresetNames(
23
+ presetNames: readonly string[] = Object.keys(PRESETS),
24
+ ): string[] {
25
+ return [...presetNames];
26
+ }
27
+
28
+ function startsWithPrefix(value: string, prefix: string): boolean {
29
+ return value.toLowerCase().startsWith(prefix.toLowerCase());
30
+ }
31
+
32
+ function tokenizeArgs(argumentPrefix: string): {
33
+ tokens: string[];
34
+ lastComplete: boolean;
35
+ } {
36
+ const trimmedStart = argumentPrefix.replace(/^\s+/, "");
37
+ if (trimmedStart === "") {
38
+ return { tokens: [], lastComplete: true };
39
+ }
40
+ return {
41
+ tokens: trimmedStart.split(/\s+/).filter(Boolean),
42
+ lastComplete: /\s$/.test(argumentPrefix),
43
+ };
44
+ }
45
+
46
+ function placementCompletions(valuePrefix: string): AutocompleteItem[] {
47
+ return POWERLINE_PLACEMENT_VALUES.filter((value) =>
48
+ startsWithPrefix(value, valuePrefix),
49
+ ).map((value) => ({
50
+ value: `placement ${value}`,
51
+ label: value,
52
+ description: PLACEMENT_DESCRIPTIONS[value],
53
+ }));
54
+ }
55
+
56
+ export function getPowerlineArgumentCompletions(
57
+ argumentPrefix: string,
58
+ presetNames: readonly string[] = Object.keys(PRESETS),
59
+ ): AutocompleteItem[] | null {
60
+ const { tokens, lastComplete } = tokenizeArgs(argumentPrefix);
61
+ const first = tokens[0] ?? "";
62
+ // The command grammar has only one optional placement value. Do not offer
63
+ // a replacement once the user has started a third argument.
64
+ if (tokens.length > 2 || (tokens.length === 2 && lastComplete)) {
65
+ return null;
66
+ }
67
+
68
+ const completingSecond =
69
+ first.toLowerCase() === "placement" &&
70
+ ((tokens.length === 1 && lastComplete) ||
71
+ (tokens.length === 2 && !lastComplete));
72
+
73
+ if (completingSecond) {
74
+ const valuePrefix = tokens.length > 1 ? tokens[1] : "";
75
+ const items = placementCompletions(valuePrefix);
76
+ return items.length > 0 ? items : null;
77
+ }
78
+
79
+ if (tokens.length > 1) {
80
+ return null;
81
+ }
82
+
83
+ const prefix = first;
84
+ const items: AutocompleteItem[] = [];
85
+
86
+ for (const sub of POWERLINE_SUBCOMMANDS) {
87
+ if (!prefix || startsWithPrefix(sub.value, prefix)) {
88
+ items.push({
89
+ value: sub.value,
90
+ label: sub.value,
91
+ description: sub.description,
92
+ });
93
+ }
94
+ }
95
+
96
+ for (const name of listPowerlinePresetNames(presetNames)) {
97
+ if (!prefix || startsWithPrefix(name, prefix)) {
98
+ items.push({
99
+ value: name,
100
+ label: name,
101
+ description: `Switch to the ${name} preset`,
102
+ });
103
+ }
104
+ }
105
+
106
+ return items.length > 0 ? items : null;
107
+ }