@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 +12 -0
- package/README.md +1 -1
- package/RELEASE.md +20 -13
- package/ROADMAP.md +5 -6
- package/package.json +1 -1
- package/src/extension/commands/commands.ts +5 -1
- package/src/extension/commands/powerline-completions.ts +107 -0
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
|
|
22
|
-
|
|
23
|
-
`
|
|
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
|
|
66
|
+
## CI publish
|
|
63
67
|
|
|
64
|
-
`.github/workflows/release.yml`
|
|
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. `
|
|
69
|
-
4. `npm
|
|
70
|
-
5. `npm
|
|
71
|
-
6. `npm
|
|
72
|
-
7. `npm
|
|
73
|
-
8.
|
|
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.
|
|
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.
|
|
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 |
|
|
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
|
-
- [
|
|
373
|
-
|
|
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
|
@@ -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
|
+
}
|