pi-keyboard 0.1.4 → 0.1.6
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/README.md +19 -1
- package/features/keyboard.feature +4 -0
- package/index.ts +1 -0
- package/package.json +6 -2
- package/src/index.ts +10 -10
- package/src/state-machine.ts +1 -1
package/README.md
CHANGED
|
@@ -29,6 +29,24 @@ Supports discrete control for keyboard lighting channels:
|
|
|
29
29
|
|
|
30
30
|
---
|
|
31
31
|
|
|
32
|
+
## Structure
|
|
33
|
+
|
|
34
|
+
```
|
|
35
|
+
keyboard/
|
|
36
|
+
├── index.ts — Package-root extension entry point
|
|
37
|
+
├── src/
|
|
38
|
+
│ ├── config.ts — Keyboard config read/write helpers
|
|
39
|
+
│ ├── driver.ts — via-rgb binary resolution & CLI execution
|
|
40
|
+
│ ├── protocol.ts — VIA RAW HID packet building
|
|
41
|
+
│ ├── state-machine.ts — State transitions and LED apply logic
|
|
42
|
+
│ ├── global-sessions.ts — Per-cwd session glow record registry
|
|
43
|
+
│ ├── types.ts — KeyboardState, KeyboardZone, KeyboardConfig
|
|
44
|
+
│ └── index.ts — Pi lifecycle hooks, /keyboard command
|
|
45
|
+
├── features/ — BDD contract
|
|
46
|
+
├── tests/ — Package E2E tests
|
|
47
|
+
└── README.md
|
|
48
|
+
```
|
|
49
|
+
|
|
32
50
|
## Installation
|
|
33
51
|
|
|
34
52
|
Install from this monorepo or local path:
|
|
@@ -37,7 +55,7 @@ Install from this monorepo or local path:
|
|
|
37
55
|
pi install ~/Developer/FradSer/pi-packages/packages/keyboard
|
|
38
56
|
```
|
|
39
57
|
|
|
40
|
-
|
|
58
|
+
Published on npm:
|
|
41
59
|
|
|
42
60
|
```bash
|
|
43
61
|
pi install npm:pi-keyboard
|
|
@@ -134,3 +134,7 @@ Feature: Pi Keyboard Lighting Indicator
|
|
|
134
134
|
Then all keyboard lighting updates are disabled
|
|
135
135
|
When the user runs "/keyboard test thinking"
|
|
136
136
|
Then the keyboard lighting displays the blue thinking state
|
|
137
|
+
|
|
138
|
+
Scenario: Keyboard state notifications use Pi's native notification surface
|
|
139
|
+
Given the keyboard extension reports an interactive command outcome
|
|
140
|
+
Then it uses ctx.ui.notify without a custom notification renderer
|
package/index.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default } from "./src/index.ts";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pi-keyboard",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.6",
|
|
4
4
|
"description": "Dynamic VIA/QMK keyboard RGB lighting indicator reflecting Pi states (idle, thinking, unread, need-approval, error)",
|
|
5
5
|
"author": "Frad LEE <fradser@gmail.com>",
|
|
6
6
|
"license": "MIT",
|
|
@@ -22,6 +22,7 @@
|
|
|
22
22
|
"access": "public"
|
|
23
23
|
},
|
|
24
24
|
"files": [
|
|
25
|
+
"index.ts",
|
|
25
26
|
"src",
|
|
26
27
|
"features",
|
|
27
28
|
"README.md",
|
|
@@ -29,11 +30,14 @@
|
|
|
29
30
|
],
|
|
30
31
|
"pi": {
|
|
31
32
|
"extensions": [
|
|
32
|
-
"./
|
|
33
|
+
"./index.ts"
|
|
33
34
|
]
|
|
34
35
|
},
|
|
35
36
|
"peerDependencies": {
|
|
36
37
|
"@earendil-works/pi-coding-agent": "*",
|
|
37
38
|
"@earendil-works/pi-tui": "*"
|
|
39
|
+
},
|
|
40
|
+
"dependencies": {
|
|
41
|
+
"@fradser/pi-kit": "0.4.2"
|
|
38
42
|
}
|
|
39
43
|
}
|
package/src/index.ts
CHANGED
|
@@ -2,12 +2,12 @@ import type {
|
|
|
2
2
|
ExtensionAPI,
|
|
3
3
|
ExtensionCommandContext,
|
|
4
4
|
} from "@earendil-works/pi-coding-agent";
|
|
5
|
+
import { notifyPi } from "@fradser/pi-kit";
|
|
5
6
|
import { readKeyboardConfig, writeKeyboardConfig } from "./config";
|
|
6
7
|
import { fetchKeyboardStatus } from "./driver";
|
|
7
8
|
import { KeyboardStateMachine } from "./state-machine";
|
|
8
9
|
import {
|
|
9
10
|
KEYBOARD_STATE_DEFINITIONS,
|
|
10
|
-
type KeyboardConfig,
|
|
11
11
|
type KeyboardState,
|
|
12
12
|
type KeyboardZone,
|
|
13
13
|
} from "./types";
|
|
@@ -148,14 +148,14 @@ export default function (pi: ExtensionAPI): void {
|
|
|
148
148
|
if (trimmed === "on") {
|
|
149
149
|
sm.updateConfig({ enabled: true });
|
|
150
150
|
writeKeyboardConfig(sm.getConfig());
|
|
151
|
-
ctx.ui
|
|
151
|
+
notifyPi(ctx.ui, "Keyboard lighting indicator enabled", "info");
|
|
152
152
|
return;
|
|
153
153
|
}
|
|
154
154
|
|
|
155
155
|
if (trimmed === "off") {
|
|
156
156
|
sm.updateConfig({ enabled: false });
|
|
157
157
|
writeKeyboardConfig(sm.getConfig());
|
|
158
|
-
ctx.ui
|
|
158
|
+
notifyPi(ctx.ui, "Keyboard lighting indicator disabled", "info");
|
|
159
159
|
return;
|
|
160
160
|
}
|
|
161
161
|
|
|
@@ -169,9 +169,9 @@ export default function (pi: ExtensionAPI): void {
|
|
|
169
169
|
const targetState = (parts[1] || "thinking") as KeyboardState;
|
|
170
170
|
if (targetState in KEYBOARD_STATE_DEFINITIONS) {
|
|
171
171
|
await sm.transitionTo(targetState, true);
|
|
172
|
-
ctx.ui
|
|
172
|
+
notifyPi(ctx.ui, `Testing state: ${KEYBOARD_STATE_DEFINITIONS[targetState].labelZh}`, "info");
|
|
173
173
|
} else {
|
|
174
|
-
ctx.ui
|
|
174
|
+
notifyPi(ctx.ui, `Unknown test state. Options: ${Object.keys(KEYBOARD_STATE_DEFINITIONS).join(", ")}`, "error");
|
|
175
175
|
}
|
|
176
176
|
return;
|
|
177
177
|
}
|
|
@@ -195,7 +195,7 @@ async function showStatus(ctx: ExtensionCommandContext, sm: KeyboardStateMachine
|
|
|
195
195
|
`Hardware Status : ${hw.connected ? `Connected (${hw.device?.product || "VIA Keyboard"})` : "Not connected / Not detected"}`,
|
|
196
196
|
];
|
|
197
197
|
|
|
198
|
-
ctx.ui
|
|
198
|
+
notifyPi(ctx.ui, lines.join("\n"), "info");
|
|
199
199
|
}
|
|
200
200
|
|
|
201
201
|
async function openKeyboardMenu(
|
|
@@ -225,7 +225,7 @@ async function openKeyboardMenu(
|
|
|
225
225
|
const next = !config.enabled;
|
|
226
226
|
sm.updateConfig({ enabled: next });
|
|
227
227
|
writeKeyboardConfig(sm.getConfig());
|
|
228
|
-
ctx.ui
|
|
228
|
+
notifyPi(ctx.ui, `Keyboard lighting indicator is now ${next ? "ON" : "OFF"}`, "info");
|
|
229
229
|
return;
|
|
230
230
|
}
|
|
231
231
|
|
|
@@ -238,7 +238,7 @@ async function openKeyboardMenu(
|
|
|
238
238
|
const chosenState = stateKeys[idx];
|
|
239
239
|
if (chosenState) {
|
|
240
240
|
await sm.transitionTo(chosenState, true);
|
|
241
|
-
ctx.ui
|
|
241
|
+
notifyPi(ctx.ui, `Applied state: ${KEYBOARD_STATE_DEFINITIONS[chosenState].labelZh}`, "info");
|
|
242
242
|
}
|
|
243
243
|
}
|
|
244
244
|
return;
|
|
@@ -260,7 +260,7 @@ async function openKeyboardMenu(
|
|
|
260
260
|
const zone = zoneMap[zoneChoice] || "all";
|
|
261
261
|
sm.updateConfig({ zone });
|
|
262
262
|
writeKeyboardConfig(sm.getConfig());
|
|
263
|
-
ctx.ui
|
|
263
|
+
notifyPi(ctx.ui, `Active zone set to: ${zone.toUpperCase()}`, "info");
|
|
264
264
|
}
|
|
265
265
|
return;
|
|
266
266
|
}
|
|
@@ -278,7 +278,7 @@ async function openKeyboardMenu(
|
|
|
278
278
|
const scale = scaleMap[scaleChoice] ?? 1.0;
|
|
279
279
|
sm.updateConfig({ brightnessScale: scale });
|
|
280
280
|
writeKeyboardConfig(sm.getConfig());
|
|
281
|
-
ctx.ui
|
|
281
|
+
notifyPi(ctx.ui, `Brightness scale set to ${Math.round(scale * 100)}%`, "info");
|
|
282
282
|
}
|
|
283
283
|
return;
|
|
284
284
|
}
|
package/src/state-machine.ts
CHANGED
|
@@ -107,7 +107,7 @@ export class KeyboardStateMachine {
|
|
|
107
107
|
await this.applyCurrentState(force);
|
|
108
108
|
}
|
|
109
109
|
|
|
110
|
-
private async applyCurrentState(
|
|
110
|
+
private async applyCurrentState(_force = false): Promise<void> {
|
|
111
111
|
await applyKeyboardState(this.currentState, this.config);
|
|
112
112
|
}
|
|
113
113
|
|