pi-widget-host 0.3.4 → 0.3.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/CHANGELOG.md CHANGED
@@ -1,16 +1,37 @@
1
1
  # Changelog
2
2
 
3
- ## Unreleased
3
+ All notable changes to this project will be documented in this file.
4
+
5
+ This project follows semantic versioning.
6
+
7
+ ## [0.3.6] - 2026-08-22
4
8
 
5
9
  ### Changed
6
10
 
7
- - Bump package version to `0.3.4` for the next patch release.
11
+ - Merge the 2026-08-22 managed OSS dependency and maintenance PR batch.
8
12
 
9
- - Add Buy Me a Coffee sponsor button to README and native GitHub funding link via `.github/FUNDING.yml`.
13
+ ## [0.3.5] - 2026-08-04
10
14
 
11
- All notable changes to this project will be documented in this file.
15
+ ### Changed
12
16
 
13
- This project follows semantic versioning.
17
+ - Bump package version for the Discord release webhook verification.
18
+
19
+ ## [0.3.4] - 2026-07-21
20
+
21
+ ### Added
22
+
23
+ - `ROADMAP.md` maintenance context for weekly portfolio seeds and bounded micro-tasks.
24
+
25
+ ### Changed
26
+
27
+ - CONTRIBUTING release instructions now match the auto-release and publish workflow (no `follow-tags`).
28
+ - Dependency updates for `pi-widget-core` and development tooling.
29
+
30
+ ## [0.3.3] - 2026-07-04
31
+
32
+ ### Added
33
+
34
+ - Buy Me a Coffee sponsor button to README and native GitHub funding link via `.github/FUNDING.yml`.
14
35
 
15
36
  ## [0.3.2] - 2026-06-26
16
37
 
@@ -50,4 +71,3 @@ This project follows semantic versioning.
50
71
  ### Changed
51
72
 
52
73
  - Replaced template placeholders and removed template-only skill, prompt, and theme resources.
53
-
package/README.md CHANGED
@@ -1,5 +1,7 @@
1
1
  # Pi Widget Host
2
2
 
3
+ [![Join dotfield.xyz on Discord](https://img.shields.io/badge/Join%20dotfield.xyz%20on%20Discord-5865F2?logo=discord&logoColor=white)](https://discord.gg/4945dXZVW5)
4
+
3
5
  [![CI](https://github.com/eiei114/pi-widget-host/actions/workflows/ci.yml/badge.svg)](https://github.com/eiei114/pi-widget-host/actions/workflows/ci.yml)
4
6
  [![Publish](https://github.com/eiei114/pi-widget-host/actions/workflows/publish.yml/badge.svg)](https://github.com/eiei114/pi-widget-host/actions/workflows/publish.yml)
5
7
  [![npm version](https://img.shields.io/npm/v/pi-widget-host.svg)](https://www.npmjs.com/package/pi-widget-host)
@@ -95,7 +97,7 @@ Future provider packages can publish to the host without importing this package
95
97
  - required fields: `providerId`, `available`, `lines`, `updatedAt`
96
98
  - optional fields: `priority`, `tags`, `mode`, `ttlMs`
97
99
 
98
- See [`docs/protocol.md`](docs/protocol.md).
100
+ See [`docs/protocol.md`](docs/protocol.md) and the copy-paste [`minimal provider example`](docs/provider-example.md).
99
101
 
100
102
  ## Built-in demo provider
101
103
 
@@ -112,7 +114,9 @@ The built-in demo provider exists to prove the host loop first:
112
114
  |---|---|
113
115
  | `extensions/index.ts` | Pi extension entrypoint and `/widget-host:*` command registration |
114
116
  | `lib/` | config store, registry protocol, policy evaluation, and demo provider |
117
+ | `docs/README.md` | documentation index for protocol, release, and maintenance docs |
115
118
  | `docs/protocol.md` | registry protocol reference for future provider packages |
119
+ | `docs/provider-example.md` | minimal copy-paste provider publishing through the registry |
116
120
  | `docs/release.md` | Trusted Publishing release notes |
117
121
 
118
122
  ## Development
@@ -150,4 +154,4 @@ For vulnerability reporting, see [`SECURITY.md`](SECURITY.md).
150
154
 
151
155
  ## License
152
156
 
153
- MIT
157
+ MIT
package/docs/README.md ADDED
@@ -0,0 +1,25 @@
1
+ # Documentation index
2
+
3
+ Entry point for `pi-widget-host` maintainer and provider-author docs.
4
+
5
+ ## Guides
6
+
7
+ | Doc | Purpose |
8
+ |---|---|
9
+ | [`config.md`](config.md) | `HostConfig` field contract, defaults, and `normalizeConfig` coercion rules. |
10
+ | [`protocol.md`](protocol.md) | Registry protocol reference (`globalThis`, required fields, tags, TTL). |
11
+ | [`provider-example.md`](provider-example.md) | Minimal copy-paste provider that publishes through the registry. |
12
+ | [`release.md`](release.md) | npm Trusted Publishing workflow and CI release automation. |
13
+
14
+ ## Maintenance context
15
+
16
+ | Doc | Purpose |
17
+ |---|---|
18
+ | [ROADMAP.md](https://github.com/eiei114/pi-widget-host/blob/main/ROADMAP.md) | Living release status, priorities, and bounded maintenance seeds. |
19
+ | [`npm-publish-run-2026-07-04.md`](npm-publish-run-2026-07-04.md) | Notes from the 2026-07-04 publish run (historical reference). |
20
+
21
+ ## Quick links
22
+
23
+ - Package README: [`../README.md`](../README.md)
24
+ - Contributing: [CONTRIBUTING.md](https://github.com/eiei114/pi-widget-host/blob/main/CONTRIBUTING.md)
25
+ - Changelog: [`../CHANGELOG.md`](../CHANGELOG.md)
package/docs/config.md ADDED
@@ -0,0 +1,110 @@
1
+ # Host config schema and normalization
2
+
3
+ `pi-widget-host` persists host settings in a JSON file under the Pi agent directory. Every read and write path runs the payload through `normalizeConfig` in `lib/config.ts` so callers always receive a stable `HostConfig` shape.
4
+
5
+ ## Storage location
6
+
7
+ | Item | Value |
8
+ |---|---|
9
+ | Default path | `~/.pi/agent/pi-widget-host-config.json` |
10
+ | Override | Set `PI_WIDGET_HOST_AGENT_DIR` to use `<dir>/pi-widget-host-config.json` instead |
11
+
12
+ If the file is missing, unreadable, or contains invalid JSON, `readHostConfig()` returns `createDefaultConfig()` without throwing.
13
+
14
+ ## `HostConfig` fields
15
+
16
+ All fields are required on the normalized object. Unknown keys in stored JSON are ignored.
17
+
18
+ | Field | Type | Default | `normalizeConfig` coercion |
19
+ |---|---|---|---|
20
+ | `schemaVersion` | `1` (literal) | `1` | Always rewritten to `1`. Any stored value is replaced. |
21
+ | `setupComplete` | `boolean` | `false` | `true` only when the input value is strictly `true`; every other value becomes `false`. |
22
+ | `demoProviderEnabled` | `boolean` | `false` | `true` only when the input value is strictly `true`; every other value becomes `false`. |
23
+ | `presetId` | `string` | `"always-demo"` | Valid built-in preset ids are preserved. Invalid ids, non-string values, and strings that do not exactly match a built-in id (including whitespace-wrapped values such as `" focus-day "`) normalize to `"always-demo"`. |
24
+ | `mutedProviderIds` | `string[]` | `[]` | When the input is an array, string elements with non-blank content (checked via `trim()`) are kept as written, including surrounding whitespace; duplicates removed, order preserved. Any non-array input becomes `[]`. |
25
+
26
+ Built-in preset ids (from `lib/policy.ts`):
27
+
28
+ - `always-demo` (default)
29
+ - `focus-day`
30
+ - `night-owl`
31
+
32
+ ## Normalization entry points
33
+
34
+ | Function | Behavior |
35
+ |---|---|
36
+ | `createDefaultConfig()` | Returns a fresh default object without touching disk. |
37
+ | `readHostConfig()` | Reads JSON from disk, parses it, then normalizes. On any I/O or parse failure, returns `createDefaultConfig()`. |
38
+ | `writeHostConfig(config)` | Normalizes the input, writes pretty-printed JSON, returns the normalized value. |
39
+ | `updateHostConfig(mutator)` | Reads current config, applies `mutator`, then writes through `writeHostConfig`. |
40
+
41
+ ## Non-object and partial payloads
42
+
43
+ When the parsed JSON root is not a plain object (`null`, array, string, number, boolean), normalization treats the payload as `{}` and produces the full default config shape.
44
+
45
+ Examples:
46
+
47
+ ```json
48
+ "hello"
49
+ ```
50
+
51
+ ```json
52
+ 42
53
+ ```
54
+
55
+ Both normalize to:
56
+
57
+ ```json
58
+ {
59
+ "schemaVersion": 1,
60
+ "setupComplete": false,
61
+ "demoProviderEnabled": false,
62
+ "presetId": "always-demo",
63
+ "mutedProviderIds": []
64
+ }
65
+ ```
66
+
67
+ Partial objects keep valid fields and coerce the rest:
68
+
69
+ ```json
70
+ {
71
+ "setupComplete": true,
72
+ "presetId": "focus-day",
73
+ "mutedProviderIds": ["alpha", "alpha", " "]
74
+ }
75
+ ```
76
+
77
+ Normalizes to:
78
+
79
+ ```json
80
+ {
81
+ "schemaVersion": 1,
82
+ "setupComplete": true,
83
+ "demoProviderEnabled": false,
84
+ "presetId": "focus-day",
85
+ "mutedProviderIds": ["alpha"]
86
+ }
87
+ ```
88
+
89
+ ## Malformed field examples
90
+
91
+ | Stored value | Normalized result |
92
+ |---|---|
93
+ | `"presetId": "not-a-real-preset"` | `"presetId": "always-demo"` |
94
+ | `"presetId": " focus-day "` | `"presetId": "always-demo"` |
95
+ | `"mutedProviderIds": "alpha"` | `"mutedProviderIds": []` |
96
+ | `"mutedProviderIds": [" alpha "]` | `"mutedProviderIds": [" alpha "]` |
97
+ | `"mutedProviderIds": ["ok", 42, "", " ", "ok"]` | `"mutedProviderIds": ["ok"]` |
98
+ | `"setupComplete": "yes"` | `"setupComplete": false` |
99
+ | `"demoProviderEnabled": 1` | `"demoProviderEnabled": false` |
100
+
101
+ ## Schema versioning
102
+
103
+ `schemaVersion` is pinned to `1`. There is no forward migration path yet; future versions would extend `normalizeConfig` to upgrade older shapes before returning `HostConfig`.
104
+
105
+ ## Related code
106
+
107
+ - Type definition: `lib/types.ts` (`HostConfig`)
108
+ - Normalization and persistence: `lib/config.ts`
109
+ - Preset catalog: `lib/policy.ts` (`PRESET_OPTIONS`, `getPreset`, `DEFAULT_PRESET_ID`)
110
+ - Tests: `tests/config.test.ts`
@@ -0,0 +1,35 @@
1
+ # Minimal provider example
2
+
3
+ Provider packages can publish widget lines without importing `pi-widget-host`. They only need to write a `ProviderEntry` into the process-local registry on `globalThis`.
4
+
5
+ ```ts
6
+ const registrySymbol = Symbol.for("pi-widget-host.registry.v1");
7
+
8
+ type ProviderEntry = {
9
+ providerId: string;
10
+ available: boolean;
11
+ lines: string[];
12
+ updatedAt: string;
13
+ priority?: number;
14
+ tags?: string[];
15
+ mode?: string;
16
+ ttlMs?: number;
17
+ };
18
+
19
+ type WidgetHostRegistry = {
20
+ set(entry: ProviderEntry): void;
21
+ };
22
+
23
+ const registry = Reflect.get(globalThis, registrySymbol) as WidgetHostRegistry | undefined;
24
+
25
+ registry?.set({
26
+ providerId: "example.now-playing",
27
+ available: true,
28
+ lines: ["Now Playing", "Example Artist — Example Song"],
29
+ updatedAt: new Date().toISOString(),
30
+ priority: 20,
31
+ tags: ["music", "playing-now"],
32
+ });
33
+ ```
34
+
35
+ Required fields are `providerId`, `available`, `lines`, and `updatedAt`. Optional fields such as `priority`, `tags`, `mode`, and `ttlMs` help the host choose between eligible providers. See [`protocol.md`](protocol.md) for the full registry shape and host selection notes.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pi-widget-host",
3
- "version": "0.3.4",
3
+ "version": "0.3.6",
4
4
  "description": "Host package for managing one shared Pi widget slot across multiple providers with preset policies and a built-in demo provider.",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -46,7 +46,7 @@
46
46
  "access": "public"
47
47
  },
48
48
  "dependencies": {
49
- "pi-widget-core": "^0.1.0"
49
+ "pi-widget-core": "^0.1.3"
50
50
  },
51
51
  "peerDependencies": {
52
52
  "@earendil-works/pi-coding-agent": "*"
@@ -60,6 +60,6 @@
60
60
  "@earendil-works/pi-coding-agent": "latest",
61
61
  "@types/node": "^26.0.0",
62
62
  "tsx": "^4.20.6",
63
- "typescript": "^6.0.3"
63
+ "typescript": "^7.0.2"
64
64
  }
65
65
  }