pi-spotify-widget 0.1.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 ADDED
@@ -0,0 +1,19 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project will be documented in this file.
4
+
5
+ This project follows semantic versioning.
6
+
7
+ ## [0.1.0] - 2026-06-03
8
+
9
+ ### Added
10
+
11
+ - Now Playing widget in Pi prompt editor (track, artist, playing/paused, progress seek bar).
12
+ - OAuth 2.0 + PKCE login via `/spotify:login` with localhost callback on port 8888.
13
+ - Interactive Client ID setup (Dashboard opens in browser; optional `PI_SPOTIFY_CLIENT_ID` env override).
14
+ - Secret-safe `/spotify:status`, `/spotify:logout`, and `/spotify:refresh`.
15
+ - Playback controls (`/spotify:prev`, `/spotify:next`, `/spotify:pause`, `/spotify:play`) and `/spotify:play-uri`.
16
+ - `/spotify:share` for X compose (intent URL; optional API credentials via env).
17
+ - `spotify-playback` Agent Skill for playback and share workflows.
18
+ - Token refresh lifecycle and adaptive polling with stale snapshot fallback.
19
+ - CI workflow and npm Trusted Publishing setup.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 YOUR_NAME
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,160 @@
1
+ # pi-spotify-widget
2
+
3
+ [![CI](https://github.com/eiei114/pi-spotify-widget/actions/workflows/ci.yml/badge.svg)](https://github.com/eiei114/pi-spotify-widget/actions/workflows/ci.yml)
4
+ [![Publish](https://github.com/eiei114/pi-spotify-widget/actions/workflows/publish.yml/badge.svg)](https://github.com/eiei114/pi-spotify-widget/actions/workflows/publish.yml)
5
+ [![npm version](https://img.shields.io/npm/v/pi-spotify-widget.svg)](https://www.npmjs.com/package/pi-spotify-widget)
6
+ [![npm downloads](https://img.shields.io/npm/dm/pi-spotify-widget.svg)](https://www.npmjs.com/package/pi-spotify-widget)
7
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
8
+ [![Pi package](https://img.shields.io/badge/pi-package-purple.svg)](https://pi.dev/packages)
9
+ [![Trusted Publishing](https://img.shields.io/badge/npm-Trusted%20Publishing-blue.svg)](docs/release.md)
10
+
11
+ > Show Spotify playback status in Pi's prompt editor widget.
12
+
13
+ ## What this is
14
+
15
+ TypeScript-first Pi package that displays **Now Playing** (track, artist, playing/paused) in the prompt editor widget. Auth uses **OAuth 2.0 + PKCE** against Spotify Web API — not a static API key.
16
+
17
+ ## Features
18
+
19
+ - **Now Playing widget** — track, artist, playback state, compact progress seek bar
20
+ - **OAuth login** — `/spotify:login` opens Dashboard + browser, stores tokens locally
21
+ - **Secret-safe status** — `/spotify:status` without exposing token values
22
+ - **Playback controls** — `/spotify:prev`, `/spotify:next`, `/spotify:pause`, `/spotify:play`
23
+ - **Share to X** — `/spotify:share` opens compose with Now Playing text (soccer-widget style)
24
+ - **Manual refresh** — `/spotify:refresh`
25
+ - **Token refresh** — access token lifecycle before API calls
26
+
27
+ ## Install
28
+
29
+ ```bash
30
+ pi install npm:pi-spotify-widget
31
+ ```
32
+
33
+ Or install from GitHub:
34
+
35
+ ```bash
36
+ pi install git:github.com/eiei114/pi-spotify-widget
37
+ ```
38
+
39
+ ## Spotify Developer setup (required)
40
+
41
+ Each user creates their own Spotify app (v1 **BYO Client ID** policy). Client Secret is not needed for PKCE.
42
+
43
+ ### Option A — Interactive setup (recommended)
44
+
45
+ 1. Install the package (see [Install](#install)) and start Pi.
46
+ 2. Run `/spotify:login` — the [Spotify Developer Dashboard](https://developer.spotify.com/dashboard) opens automatically.
47
+ 3. Create an app and add redirect URI: `http://127.0.0.1:8888/callback`
48
+ 4. Paste your **Client ID** into the Pi prompt when asked.
49
+ 5. Complete browser OAuth authorization.
50
+
51
+ The Client ID is saved locally at `~/.pi/agent/pi-spotify-widget-config.json` (not sent to the model). OAuth tokens are stored separately at `~/.pi/agent/pi-spotify-widget-auth.json`.
52
+
53
+ ### Option B — Environment variable
54
+
55
+ Set `PI_SPOTIFY_CLIENT_ID` before starting Pi to skip the Client ID prompt:
56
+
57
+ ```powershell
58
+ # PowerShell
59
+ $env:PI_SPOTIFY_CLIENT_ID="your_client_id_here"
60
+ ```
61
+
62
+ ```bash
63
+ # bash
64
+ export PI_SPOTIFY_CLIENT_ID="your_client_id_here"
65
+ ```
66
+
67
+ Bundled Client ID and Extended Quota are planned for a future release. v1 does not ship a shared maintainer app.
68
+
69
+ ## Quick start
70
+
71
+ ```bash
72
+ pi install npm:pi-spotify-widget
73
+ ```
74
+
75
+ Try locally from a git checkout:
76
+
77
+ ```bash
78
+ pi -e .
79
+ ```
80
+
81
+ Then run:
82
+
83
+ ```txt
84
+ /spotify:login
85
+ /spotify:status
86
+ /spotify:refresh
87
+ ```
88
+
89
+ ## Commands
90
+
91
+ | Command | Description |
92
+ |---|---|
93
+ | `/spotify:login` | Open Dashboard, enter Client ID (if needed), OAuth PKCE login |
94
+ | `/spotify:status` | Secret-safe auth status (no token values) |
95
+ | `/spotify:logout` | Remove stored tokens |
96
+ | `/spotify:refresh` | Force Now Playing snapshot fetch |
97
+ | `/spotify:prev` | Skip to previous track |
98
+ | `/spotify:next` | Skip to next track |
99
+ | `/spotify:pause` | Pause playback |
100
+ | `/spotify:play` | Resume playback |
101
+ | `/spotify:help` | Playback command list for AI/user |
102
+ | `/spotify:share` | Open X compose with Now Playing (optional prefix text) |
103
+ | `/spotify:play-uri` | Play a Spotify track URL or URI |
104
+
105
+ ## Package contents
106
+
107
+ | Path | Purpose |
108
+ |---|---|
109
+ | `extensions/` | Pi TypeScript extension entrypoints |
110
+ | `lib/` | Spotify auth, API client, widget render |
111
+ | `docs/` | Release and setup docs |
112
+
113
+ ## Development
114
+
115
+ ```bash
116
+ npm install
117
+ npm run ci
118
+ ```
119
+
120
+ ## Release
121
+
122
+ This package is set up for npm Trusted Publishing, so no `NPM_TOKEN` is required.
123
+
124
+ ```bash
125
+ npm version patch
126
+ git push --follow-tags
127
+ ```
128
+
129
+ See [`docs/release.md`](docs/release.md) for setup details.
130
+
131
+ ## Template checklist
132
+
133
+ After creating a repository from this template, follow [`docs/template-checklist.md`](docs/template-checklist.md).
134
+
135
+ More docs:
136
+
137
+ - [`docs/typescript.md`](docs/typescript.md)
138
+ - [`docs/examples.md`](docs/examples.md)
139
+ - [`docs/github-template.md`](docs/github-template.md)
140
+ - [`docs/repository-settings.md`](docs/repository-settings.md)
141
+
142
+ ## Security
143
+
144
+ Pi packages can execute code with your local permissions. This package:
145
+
146
+ - sends network requests to Spotify Web API
147
+ - stores OAuth tokens under `~/.pi/agent/` (local only)
148
+ - opens your system browser for login
149
+
150
+ Review extensions before installing third-party packages. For vulnerability reporting, see [`SECURITY.md`](SECURITY.md).
151
+
152
+ ## Links
153
+
154
+ - npm: https://www.npmjs.com/package/pi-spotify-widget
155
+ - GitHub: https://github.com/eiei114/pi-spotify-widget
156
+ - Issues: https://github.com/eiei114/pi-spotify-widget/issues
157
+
158
+ ## License
159
+
160
+ MIT
@@ -0,0 +1,49 @@
1
+ # Examples
2
+
3
+ This template ships one minimal example for each Pi package resource type.
4
+
5
+ ## Extension
6
+
7
+ `extensions/hello.ts` registers:
8
+
9
+ - `/template-hello`
10
+ - a small session status indicator
11
+
12
+ Try it with:
13
+
14
+ ```bash
15
+ pi -e .
16
+ ```
17
+
18
+ Then run:
19
+
20
+ ```txt
21
+ /template-hello YourName
22
+ ```
23
+
24
+ ## Agent Skill
25
+
26
+ `skills/example-skill/SKILL.md` demonstrates a minimal Agent Skill.
27
+
28
+ Replace it with your real workflow instructions.
29
+
30
+ ## Prompt template
31
+
32
+ `prompts/example.md` demonstrates a tiny prompt template with one variable.
33
+
34
+ ## Theme
35
+
36
+ `themes/example-theme.json` is a placeholder theme. Replace it or remove `themes/` if your package does not ship themes.
37
+
38
+ ## Typed custom tool
39
+
40
+ `extensions/index.ts` registers:
41
+
42
+ - `/template-info`
43
+ - `template_greet` custom tool
44
+
45
+ The tool demonstrates:
46
+
47
+ - TypeBox object parameters
48
+ - a string enum schema via `StringEnum`
49
+ - shared logic imported from `lib/greeting.ts`
@@ -0,0 +1,43 @@
1
+ # GitHub Template Repository
2
+
3
+ Enable template mode on the source repository:
4
+
5
+ ```txt
6
+ GitHub repo → Settings → General → Template repository
7
+ ```
8
+
9
+ Create a public repository from the template:
10
+
11
+ ```bash
12
+ gh repo create OWNER/new-pi-extension \
13
+ --public \
14
+ --template OWNER/pi-extension-template \
15
+ --clone
16
+ ```
17
+
18
+ Create a private repository from the template:
19
+
20
+ ```bash
21
+ gh repo create OWNER/new-pi-extension \
22
+ --private \
23
+ --template OWNER/pi-extension-template \
24
+ --clone
25
+ ```
26
+
27
+ Include all branches if needed:
28
+
29
+ ```bash
30
+ gh repo create OWNER/new-pi-extension \
31
+ --public \
32
+ --template OWNER/pi-extension-template \
33
+ --include-all-branches \
34
+ --clone
35
+ ```
36
+
37
+ After creation:
38
+
39
+ ```bash
40
+ cd new-pi-extension
41
+ npm install
42
+ npm run ci
43
+ ```
@@ -0,0 +1,38 @@
1
+ # Release
2
+
3
+ This package uses npm Trusted Publishing with GitHub Actions OIDC.
4
+
5
+ Do not add `NPM_TOKEN` or long-lived npm tokens to GitHub Secrets.
6
+
7
+ ## One-time npm setup
8
+
9
+ On npmjs.com, configure Trusted Publishing for this package:
10
+
11
+ - Publisher: GitHub Actions
12
+ - Repository: this GitHub repository
13
+ - Workflow filename: `publish.yml`
14
+
15
+ ## Publish
16
+
17
+ ```bash
18
+ npm version patch
19
+ git push --follow-tags
20
+ ```
21
+
22
+ The `v*` tag triggers `.github/workflows/publish.yml`, which runs CI and publishes to npm.
23
+
24
+ ## GitHub Actions requirements
25
+
26
+ - `permissions: id-token: write`
27
+ - GitHub-hosted runner
28
+ - No `NPM_TOKEN`
29
+ - `npm publish` from the configured workflow file
30
+
31
+ ## First release checklist
32
+
33
+ - [ ] `package.json` name is final
34
+ - [ ] `repository.url` points to the real GitHub repository
35
+ - [ ] npm Trusted Publisher is configured
36
+ - [ ] `npm run ci` passes
37
+ - [ ] `npm pack --dry-run` contains only intended files
38
+ - [ ] `CHANGELOG.md` has the release date
@@ -0,0 +1,41 @@
1
+ # Repository Settings
2
+
3
+ Use this file after creating a real repository from the template.
4
+
5
+ ## GitHub About
6
+
7
+ Suggested fields:
8
+
9
+ - Description: one-line pitch for the Pi package
10
+ - Website: npm package URL or project docs URL
11
+ - Topics:
12
+ - `pi`
13
+ - `pi-package`
14
+ - `agent-skill`
15
+ - `typescript`
16
+
17
+ ## Template mode
18
+
19
+ If this repository itself should be reusable as a template:
20
+
21
+ ```txt
22
+ Settings → General → Template repository
23
+ ```
24
+
25
+ ## Branch protection
26
+
27
+ Recommended for public packages:
28
+
29
+ - Require pull request before merging
30
+ - Require status checks to pass
31
+ - Require `CI` workflow
32
+ - Block force pushes on the default branch
33
+
34
+ ## npm package page
35
+
36
+ After first publish:
37
+
38
+ - Confirm README renders correctly
39
+ - Confirm package provenance appears
40
+ - Confirm package contents are intentional
41
+ - Add npm URL to GitHub About and README
@@ -0,0 +1,85 @@
1
+ # Template Setup Checklist
2
+
3
+ このテンプレートから新しい Pi 拡張OSSを作った後に埋めること。
4
+
5
+ ## Repository
6
+
7
+ - [ ] GitHub repository name を決める
8
+ - [ ] GitHub About 欄を書く
9
+ - [ ] GitHub topics を設定する
10
+ - [ ] `pi`
11
+ - [ ] `pi-package`
12
+ - [ ] `agent-skill`
13
+ - [ ] `typescript`
14
+ - [ ] GitHub Settingsで `Template repository` をONにする
15
+ - [ ] Repository URL を `package.json` に反映する
16
+ - [ ] README の `OWNER/REPO` を実リポジトリに置き換える
17
+
18
+ ## Package metadata
19
+
20
+ - [ ] `package.json` の `name` を変更する
21
+ - [ ] `description` を書く
22
+ - [ ] `author` を入れる
23
+ - [ ] `repository.url` を埋める
24
+ - [ ] `bugs.url` を埋める
25
+ - [ ] `homepage` を埋める
26
+ - [ ] `keywords` を見直す
27
+ - [ ] `LICENSE` の年・名前を更新する
28
+
29
+ ## README placeholders
30
+
31
+ - [ ] `PACKAGE_DISPLAY_NAME` を置き換える
32
+ - [ ] `PACKAGE_NAME` を置き換える
33
+ - [ ] `OWNER/REPO` を置き換える
34
+ - [ ] one-line pitch を書く
35
+ - [ ] feature list を書く
36
+ - [ ] quick start command を実コマンドにする
37
+ - [ ] npm URL を確認する
38
+ - [ ] GitHub URL を確認する
39
+
40
+ ## Pi package manifest
41
+
42
+ - [ ] `pi.extensions` に公開する拡張だけを残す
43
+ - [ ] `pi.skills` に公開する skill だけを残す
44
+ - [ ] 不要なら `prompts/` を消す
45
+ - [ ] 不要なら `themes/` を消す
46
+ - [ ] サンプル名を実名に変える
47
+
48
+ ## TypeScript
49
+
50
+ - [ ] `extensions/index.ts` を実装に合わせて更新する
51
+ - [ ] `extensions/hello.ts` が不要なら削除する
52
+ - [ ] 共通ロジックを `lib/` に切り出す
53
+ - [ ] `strict: true` を維持する
54
+ - [ ] custom tool parameters は TypeBox schema で定義する
55
+ - [ ] string choices は `StringEnum` helper を使う
56
+ - [ ] runtime dependency は `dependencies`、Pi提供packageは `peerDependencies` に置く
57
+ - [ ] `package.json.files` に公開対象だけを入れる
58
+
59
+ ## GitHub Template repo
60
+
61
+ - [ ] `gh repo create --template OWNER/pi-extension-template` で作成できることを確認する
62
+ - [ ] public/privateどちらの作成例もdocsに載せる
63
+
64
+ ## CI / Release
65
+
66
+ - [ ] `npm run ci` が通る
67
+ - [ ] `npm pack --dry-run` が通る
68
+ - [ ] npm Trusted Publishing を設定する
69
+ - [ ] `NPM_TOKEN` を使っていないことを確認する
70
+ - [ ] tag publish が動くことを初回リリースで確認する
71
+
72
+ ## npm page
73
+
74
+ - [ ] npm package URL を README に追加する
75
+ - [ ] npm description が適切に表示されるか確認する
76
+ - [ ] provenance が付いているか確認する
77
+ - [ ] 不要なファイルが package に含まれていないか確認する
78
+
79
+ ## Before first release
80
+
81
+ - [ ] サンプルコードを実機 Pi でロードする
82
+ - [ ] `pi install git:github.com/OWNER/REPO` を試す
83
+ - [ ] `pi -e .` を試す
84
+ - [ ] README のコマンドがコピペで動くか確認する
85
+ - [ ] CHANGELOG に `0.1.0` を書く
@@ -0,0 +1,75 @@
1
+ # TypeScript Guide
2
+
3
+ This is a TypeScript-first Pi package template.
4
+
5
+ ## Layout
6
+
7
+ ```txt
8
+ extensions/*.ts Pi extension entrypoints
9
+ lib/*.ts Shared TypeScript helpers
10
+ skills/*/SKILL.md Agent Skills
11
+ prompts/*.md Prompt templates
12
+ themes/*.json Themes
13
+ tests/*.test.mjs Smoke tests
14
+ tests/*.test.ts Optional TypeScript tests if you add a TS test runner
15
+ ```
16
+
17
+ Pi loads TypeScript extensions directly, so no build step is required for normal use.
18
+
19
+ ## Strict mode
20
+
21
+ `tsconfig.json` keeps `strict: true`. Prefer fixing types over loosening compiler options.
22
+
23
+ ## Extension entrypoints
24
+
25
+ Two entrypoint styles are shown:
26
+
27
+ - `extensions/hello.ts`: single-file extension
28
+ - `extensions/index.ts`: index-style extension that imports shared code from `lib/`
29
+
30
+ For larger packages, keep entrypoints thin and put reusable logic in `lib/`.
31
+
32
+ ## TypeBox schemas
33
+
34
+ Use TypeBox schemas for custom tool parameters.
35
+
36
+ ```ts
37
+ import { Type } from "typebox";
38
+
39
+ const parameters = Type.Object({
40
+ name: Type.String({ description: "Name to greet" }),
41
+ });
42
+ ```
43
+
44
+ ## String enums
45
+
46
+ For string choices, use the local `StringEnum` helper from `lib/schema.ts`.
47
+
48
+ ```ts
49
+ import { StringEnum } from "../lib/schema.ts";
50
+
51
+ const mode = StringEnum(["short", "friendly"], {
52
+ description: "Greeting style",
53
+ });
54
+ ```
55
+
56
+ This emits a JSON Schema `enum`, which is friendlier to model providers than a union of string literals.
57
+
58
+ ## Runtime dependencies vs peer dependencies
59
+
60
+ Pi bundles core packages for extension authors. Keep Pi-provided packages as `peerDependencies` and also install them as `devDependencies` for local typechecking.
61
+
62
+ Use `peerDependencies` for:
63
+
64
+ - `@earendil-works/pi-coding-agent`
65
+ - `@earendil-works/pi-ai`
66
+ - `@earendil-works/pi-tui`
67
+ - `typebox`
68
+
69
+ Use `dependencies` for runtime packages your extension imports that Pi does not provide.
70
+
71
+ Use `devDependencies` for local-only tools such as TypeScript, test runners, and linters.
72
+
73
+ ## Package contents
74
+
75
+ Control npm package contents with `package.json` `files`. Prefer this over `.npmignore` so the published package stays explicit.