pi-deck 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/README.md ADDED
@@ -0,0 +1,122 @@
1
+ # Pi-Deck
2
+
3
+ A web interface for [Pi](https://github.com/badlogic/pi-mono), the terminal coding agent. This is a personal project I built for my own workflow — it lets me use Pi from a browser instead of the terminal, with multi-workspace support so I can manage several projects at once.
4
+
5
+ > **Note:** This is personal tooling, not a general-purpose product. It works for my setup and I make no guarantees about stability, compatibility, or support. Feel free to fork or take ideas from it.
6
+
7
+ ## Features
8
+
9
+ - **Multi-workspace tabs** — open multiple project directories side by side
10
+ - **Real-time streaming** — chat with Pi via WebSocket, see responses as they arrive
11
+ - **Tool visualization** — watch tool calls execute with live output
12
+ - **Thinking blocks** — collapsible display for reasoning model internals
13
+ - **Session management** — switch between sessions, pick models per workspace
14
+ - **Image support** — paste or drag images into prompts
15
+ - **Persistent state** — open workspaces, theme, and drafts sync across devices via SQLite
16
+ - **Directory allowlist** — control which directories are accessible from the UI
17
+
18
+ ## Stack
19
+
20
+ - **Frontend:** React 19, Vite, TailwindCSS
21
+ - **Backend:** Express, WebSocket, Pi SDK
22
+ - **Storage:** SQLite for UI state
23
+
24
+ ## Install from npm
25
+
26
+ ```bash
27
+ npm install -g pi-deck
28
+ pi-deck
29
+ ```
30
+
31
+ Or run without installing:
32
+
33
+ ```bash
34
+ npx pi-deck
35
+ ```
36
+
37
+ Requires Node.js 20+ and an API key configured (e.g. `ANTHROPIC_API_KEY`).
38
+
39
+ Open `http://localhost:9741` in your browser.
40
+
41
+ ### CLI options
42
+
43
+ ```
44
+ pi-deck # start the server on port 9741
45
+ pi-deck --port 8080 # use a custom port
46
+ pi-deck --build # rebuild before starting (for local dev)
47
+ pi-deck --help # show all options
48
+ ```
49
+
50
+ ## Development setup
51
+
52
+ Clone the repo and install dependencies:
53
+
54
+ ```bash
55
+ git clone https://github.com/user/pi-deck.git
56
+ cd pi-deck
57
+ npm install
58
+ ```
59
+
60
+ ### Dev mode (hot-reload)
61
+
62
+ ```bash
63
+ npm run dev # frontend on :9740, backend on :9741
64
+ ```
65
+
66
+ ### Production mode (no hot-reload)
67
+
68
+ ```bash
69
+ npm run build # build everything
70
+ npm start # start the server on :9741
71
+ ```
72
+
73
+ ### Local CLI
74
+
75
+ To use the `pi-deck` command from your local checkout:
76
+
77
+ ```bash
78
+ npm run build
79
+ npm link # creates a global 'pi-deck' symlink
80
+ pi-deck # works from any directory
81
+ ```
82
+
83
+ To remove: `npm unlink -g pi-deck`
84
+
85
+ ## Publishing to npm
86
+
87
+ ```bash
88
+ npm run build # builds shared → server → client → bundles server with esbuild
89
+ npm pack # creates a .tgz to inspect before publishing
90
+ npm publish # publish to the npm registry
91
+ ```
92
+
93
+ The published package includes a bundled server (`dist/server.js`) and the pre-built client SPA (`packages/client/dist/`). Workspace dependencies are inlined by esbuild; only runtime dependencies (`express`, `better-sqlite3`, etc.) are installed by npm.
94
+
95
+ ## Configuration
96
+
97
+ Create a config file at `~/.config/pi-deck/config.json`:
98
+
99
+ ```json
100
+ {
101
+ "port": 9741,
102
+ "host": "0.0.0.0",
103
+ "allowedDirectories": ["~/projects", "~/code"]
104
+ }
105
+ ```
106
+
107
+ Or use environment variables: `PORT`, `HOST`, `PI_ALLOWED_DIRS` (colon-separated).
108
+
109
+ ## Running as a service
110
+
111
+ I run this on a Mac mini with Tailscale for always-on access from any device.
112
+
113
+ ```bash
114
+ npm run service:install # install as launchd service (starts on login)
115
+ npm run service:uninstall # remove it
116
+ ```
117
+
118
+ Logs go to `~/Library/Logs/pi-deck/`.
119
+
120
+ ## License
121
+
122
+ MIT
package/bin/pi-deck.js ADDED
@@ -0,0 +1,86 @@
1
+ #!/usr/bin/env node
2
+
3
+ import { fileURLToPath } from 'url';
4
+ import { dirname, join, resolve } from 'path';
5
+ import { existsSync } from 'fs';
6
+ import { execSync, fork } from 'child_process';
7
+
8
+ const __filename = fileURLToPath(import.meta.url);
9
+ const __dirname = dirname(__filename);
10
+ const ROOT = resolve(__dirname, '..');
11
+
12
+ const bundledServer = join(ROOT, 'dist/server.js');
13
+ const clientDist = join(ROOT, 'packages/client/dist');
14
+
15
+ // Parse CLI flags
16
+ const args = process.argv.slice(2);
17
+ const helpFlag = args.includes('--help') || args.includes('-h');
18
+ const buildFlag = args.includes('--build');
19
+ const portFlag = args.indexOf('--port');
20
+ const portValue = portFlag !== -1 ? args[portFlag + 1] : undefined;
21
+
22
+ if (helpFlag) {
23
+ console.log(`
24
+ pi-deck - Start the Pi-Deck server
25
+
26
+ Usage:
27
+ pi-deck [options]
28
+
29
+ Options:
30
+ --build Build before starting (if not already built)
31
+ --port <n> Override server port (default: 9741)
32
+ -h, --help Show this help message
33
+
34
+ The server will serve the built client UI and expose the WebSocket API.
35
+ Run 'npm run build' in the project root first, or use --build.
36
+ `);
37
+ process.exit(0);
38
+ }
39
+
40
+ // Check if build exists, offer to build if not
41
+ const serverBuilt = existsSync(bundledServer);
42
+ const clientBuilt = existsSync(clientDist);
43
+
44
+ if (!serverBuilt || !clientBuilt) {
45
+ if (buildFlag) {
46
+ console.log('[pi-deck] Building project...');
47
+ try {
48
+ execSync('npm run build', { cwd: ROOT, stdio: 'inherit' });
49
+ } catch {
50
+ console.error('[pi-deck] Build failed. Fix errors and retry.');
51
+ process.exit(1);
52
+ }
53
+ } else {
54
+ if (!serverBuilt) console.error(`[pi-deck] Server not built. Missing: ${bundledServer}`);
55
+ if (!clientBuilt) console.error(`[pi-deck] Client not built. Missing: ${clientDist}`);
56
+ console.error('[pi-deck] Run "npm run build" first, or use "pi-deck --build".');
57
+ process.exit(1);
58
+ }
59
+ }
60
+
61
+ // Set port via env if provided
62
+ if (portValue) {
63
+ process.env.PORT = portValue;
64
+ }
65
+
66
+ // Tell the bundled server where the client dist lives
67
+ process.env.PI_DECK_CLIENT_DIST = clientDist;
68
+
69
+ // Start the server
70
+ console.log('[pi-deck] Starting Pi-Deck server...');
71
+ const child = fork(bundledServer, [], {
72
+ cwd: ROOT,
73
+ stdio: 'inherit',
74
+ env: { ...process.env },
75
+ });
76
+
77
+ child.on('exit', (code) => {
78
+ process.exit(code ?? 0);
79
+ });
80
+
81
+ // Forward signals for clean shutdown
82
+ for (const sig of ['SIGINT', 'SIGTERM']) {
83
+ process.on(sig, () => {
84
+ child.kill(sig);
85
+ });
86
+ }