@raingor/pi-web-switch 0.2.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.
Files changed (41) hide show
  1. package/README.ja.md +137 -0
  2. package/README.md +277 -0
  3. package/README.zh-CN.md +176 -0
  4. package/index.html +13 -0
  5. package/package.json +44 -0
  6. package/pi-package/index.ts +100 -0
  7. package/pi-package/skills/pi-web-switch/SKILL.md +60 -0
  8. package/public/pi.svg +4 -0
  9. package/server/pi-reader.ts +678 -0
  10. package/src/App.tsx +25 -0
  11. package/src/components/dashboard/DashboardPage.tsx +607 -0
  12. package/src/components/layout/AppShell.tsx +18 -0
  13. package/src/components/layout/Sidebar.tsx +116 -0
  14. package/src/components/models/ModelsPage.tsx +570 -0
  15. package/src/components/providers/ProvidersPage.tsx +466 -0
  16. package/src/components/sessions/MemoryPage.tsx +177 -0
  17. package/src/components/sessions/SessionsPage.tsx +347 -0
  18. package/src/components/settings/SettingsPage.tsx +351 -0
  19. package/src/components/ui/Badge.tsx +29 -0
  20. package/src/components/ui/EmptyState.tsx +20 -0
  21. package/src/components/ui/Modal.tsx +41 -0
  22. package/src/components/ui/StatCard.tsx +37 -0
  23. package/src/data/builtin-providers.ts +148 -0
  24. package/src/data/mock-config.ts +261 -0
  25. package/src/data/mock-usage.ts +153 -0
  26. package/src/index.css +217 -0
  27. package/src/lib/config.ts +56 -0
  28. package/src/lib/currency.ts +48 -0
  29. package/src/lib/i18n.tsx +98 -0
  30. package/src/lib/translations/en.ts +168 -0
  31. package/src/lib/translations/index.ts +14 -0
  32. package/src/lib/translations/ja.ts +158 -0
  33. package/src/lib/translations/zh-CN.ts +158 -0
  34. package/src/lib/translations/zh-TW.ts +158 -0
  35. package/src/lib/utils.ts +51 -0
  36. package/src/main.tsx +106 -0
  37. package/src/store/config-store.ts +459 -0
  38. package/src/types/index.ts +187 -0
  39. package/src/vite-env.d.ts +1 -0
  40. package/tsconfig.json +24 -0
  41. package/vite.config.ts +172 -0
@@ -0,0 +1,100 @@
1
+ import type { ExtensionAPI, ExtensionContext } from "@earendil-works/pi-coding-agent";
2
+ import { Box, Text } from "@earendil-works/pi-tui";
3
+ import { Type } from "typebox";
4
+ import { execSync, spawn } from "node:child_process";
5
+ import { existsSync, readFileSync } from "node:fs";
6
+ import { homedir } from "node:os";
7
+ import { join, resolve, dirname } from "node:path";
8
+ import { fileURLToPath } from "node:url";
9
+
10
+ const PI_SWITCH_DIR = resolve(dirname(fileURLToPath(import.meta.url)), "..");
11
+
12
+ let serverProcess: ReturnType<typeof spawn> | null = null;
13
+
14
+ function getPackageManager(): "npm" | "pnpm" | "yarn" {
15
+ if (existsSync(join(PI_SWITCH_DIR, "pnpm-lock.yaml"))) return "pnpm";
16
+ if (existsSync(join(PI_SWITCH_DIR, "yarn.lock"))) return "yarn";
17
+ return "npm";
18
+ }
19
+
20
+ export default function (api: ExtensionAPI, ctx: ExtensionContext) {
21
+ // Register a command to start/stop the web UI
22
+ api.registerCommand({
23
+ name: "pi-switch",
24
+ description: "Start or stop the pi-web-switch dashboard",
25
+ params: Type.Object({
26
+ action: Type.Enum({ start: "start", stop: "stop", status: "status" }),
27
+ port: Type.Optional(Type.Number({ default: 5173 })),
28
+ }),
29
+ execute: async (params) => {
30
+ const { action, port = 5173 } = params;
31
+
32
+ if (action === "status") {
33
+ if (serverProcess && !serverProcess.killed) {
34
+ return ctx.say(
35
+ <Box borderStyle="round" borderColor="green" paddingLeft={1} paddingRight={1}>
36
+ <Text>pi-web-switch is running at http://localhost:{port}</Text>
37
+ </Box>
38
+ );
39
+ } else {
40
+ serverProcess = null;
41
+ return ctx.say(
42
+ <Box borderStyle="round" borderColor="yellow" paddingLeft={1} paddingRight={1}>
43
+ <Text>pi-web-switch is not running.</Text>
44
+ <Text>Use `/pi-web-switch start` to launch the dashboard.</Text>
45
+ </Box>
46
+ );
47
+ }
48
+ }
49
+
50
+ if (action === "stop") {
51
+ if (serverProcess && !serverProcess.killed) {
52
+ serverProcess.kill();
53
+ serverProcess = null;
54
+ return ctx.say(
55
+ <Box borderStyle="round" borderColor="green" paddingLeft={1} paddingRight={1}>
56
+ <Text>pi-web-switch stopped.</Text>
57
+ </Box>
58
+ );
59
+ }
60
+ return ctx.say(
61
+ <Box borderStyle="round" borderColor="yellow" paddingLeft={1} paddingRight={1}>
62
+ <Text>pi-web-switch is not running.</Text>
63
+ </Box>
64
+ );
65
+ }
66
+
67
+ if (action === "start") {
68
+ if (serverProcess && !serverProcess.killed) {
69
+ return ctx.say(
70
+ <Box borderStyle="round" borderColor="yellow" paddingLeft={1} paddingRight={1}>
71
+ <Text>pi-web-switch is already running at http://localhost:{port}</Text>
72
+ </Box>
73
+ );
74
+ }
75
+
76
+ const pm = getPackageManager();
77
+ const cmd = pm === "npm" ? "npx" : pm;
78
+
79
+ serverProcess = spawn(cmd, ["vite", "--host", "--port", String(port)], {
80
+ cwd: PI_SWITCH_DIR,
81
+ stdio: "ignore",
82
+ detached: true,
83
+ });
84
+
85
+ serverProcess.unref();
86
+
87
+ // Wait a moment then check
88
+ await new Promise((r) => setTimeout(r, 2000));
89
+
90
+ return ctx.say(
91
+ <Box borderStyle="round" borderColor="green" paddingLeft={1} paddingRight={1}>
92
+ <Text>pi-web-switch started!</Text>
93
+ <Text>Dashboard: http://localhost:{port}</Text>
94
+ <Text>Use `/pi-web-switch stop` to stop the server.</Text>
95
+ </Box>
96
+ );
97
+ }
98
+ },
99
+ });
100
+ }
@@ -0,0 +1,60 @@
1
+ # pi-web-switch
2
+
3
+ A web-based dashboard for managing your pi coding agent's providers, models, token usage, sessions, and settings.
4
+
5
+ ## Features
6
+
7
+ - **Dashboard**: Real-time token usage, cost tracking, cache hit rate, request logs
8
+ - **Models**: Browse, enable/disable, add/edit/delete models
9
+ - **Providers**: Manage built-in and custom providers, API keys
10
+ - **Sessions**: Browse past sessions grouped by project, delete old sessions
11
+ - **Memory**: View pi-hermes-memory content (MEMORY.md, USER.md, failures.md)
12
+ - **Settings**: Defaults, theme (Light/Dark/System), packages, import/export
13
+ - **Multi-language**: English, 简体中文, 繁體中文, 日本語
14
+
15
+ ## Commands
16
+
17
+ ### Start the dashboard
18
+
19
+ ```
20
+ /pi-web-switch start
21
+ ```
22
+
23
+ Opens the web UI at `http://localhost:5173`. The dashboard reads data directly from `~/.pi/agent/` — no setup required.
24
+
25
+ ### Stop the dashboard
26
+
27
+ ```
28
+ /pi-web-switch stop
29
+ ```
30
+
31
+ ### Check status
32
+
33
+ ```
34
+ /pi-web-switch status
35
+ ```
36
+
37
+ ## Requirements
38
+
39
+ - pi coding agent installed and configured (`~/.pi/agent/` exists)
40
+ - Node.js 18+
41
+
42
+ ## Usage
43
+
44
+ 1. Run `/pi-web-switch start` in your pi session
45
+ 2. Open `http://localhost:5173` in your browser
46
+ 3. The dashboard automatically loads your pi configuration
47
+
48
+ ## Data Source
49
+
50
+ All data is read from `~/.pi/agent/`:
51
+
52
+ | File | Description |
53
+ |------|-------------|
54
+ | `settings.json` | Provider, model, theme, packages config |
55
+ | `auth.json` | API keys per provider |
56
+ | `models.json` | Custom provider definitions |
57
+ | `sessions/*.jsonl` | Session history with token usage |
58
+ | `pi-hermes-memory/*.md` | Memory content |
59
+
60
+ Changes made in the UI are written back to these files in real time.
package/public/pi.svg ADDED
@@ -0,0 +1,4 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32" fill="none">
2
+ <rect width="32" height="32" rx="6" fill="#2563eb"/>
3
+ <text x="16" y="22" text-anchor="middle" font-size="18" font-weight="bold" fill="white" font-family="system-ui">π</text>
4
+ </svg>