opencode-dashboard-server 0.1.0__tar.gz → 0.2.0__tar.gz
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.
- opencode_dashboard_server-0.2.0/PKG-INFO +65 -0
- opencode_dashboard_server-0.2.0/README.md +53 -0
- {opencode_dashboard_server-0.1.0 → opencode_dashboard_server-0.2.0}/app.py +17 -5
- {opencode_dashboard_server-0.1.0 → opencode_dashboard_server-0.2.0}/db.py +6 -2
- opencode_dashboard_server-0.2.0/opencode_dashboard_server.egg-info/PKG-INFO +65 -0
- {opencode_dashboard_server-0.1.0 → opencode_dashboard_server-0.2.0}/opencode_dashboard_server.egg-info/SOURCES.txt +1 -0
- {opencode_dashboard_server-0.1.0 → opencode_dashboard_server-0.2.0}/pyproject.toml +4 -1
- opencode_dashboard_server-0.1.0/PKG-INFO +0 -8
- opencode_dashboard_server-0.1.0/opencode_dashboard_server.egg-info/PKG-INFO +0 -8
- {opencode_dashboard_server-0.1.0 → opencode_dashboard_server-0.2.0}/aggregate.py +0 -0
- {opencode_dashboard_server-0.1.0 → opencode_dashboard_server-0.2.0}/opencode_dashboard_server.egg-info/dependency_links.txt +0 -0
- {opencode_dashboard_server-0.1.0 → opencode_dashboard_server-0.2.0}/opencode_dashboard_server.egg-info/requires.txt +0 -0
- {opencode_dashboard_server-0.1.0 → opencode_dashboard_server-0.2.0}/opencode_dashboard_server.egg-info/top_level.txt +0 -0
- {opencode_dashboard_server-0.1.0 → opencode_dashboard_server-0.2.0}/setup.cfg +0 -0
- {opencode_dashboard_server-0.1.0 → opencode_dashboard_server-0.2.0}/tests/test_aggregate.py +0 -0
- {opencode_dashboard_server-0.1.0 → opencode_dashboard_server-0.2.0}/tests/test_app.py +0 -0
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: opencode-dashboard-server
|
|
3
|
+
Version: 0.2.0
|
|
4
|
+
Summary: FastAPI aggregator over opencode's SQLite storage
|
|
5
|
+
Project-URL: Homepage, https://github.com/GCS-ZHN/opencode-dashboard
|
|
6
|
+
Project-URL: Repository, https://github.com/GCS-ZHN/opencode-dashboard
|
|
7
|
+
Project-URL: Issues, https://github.com/GCS-ZHN/opencode-dashboard/issues
|
|
8
|
+
Requires-Python: >=3.10
|
|
9
|
+
Description-Content-Type: text/markdown
|
|
10
|
+
Requires-Dist: fastapi<1,>=0.115
|
|
11
|
+
Requires-Dist: uvicorn<1,>=0.30
|
|
12
|
+
|
|
13
|
+
# opencode-dashboard-server
|
|
14
|
+
|
|
15
|
+
FastAPI aggregation backend for the [opencode-dashboard](https://github.com/GCS-ZHN/opencode-dashboard)
|
|
16
|
+
project. Reads opencode's local SQLite storage via the `opencode db` CLI and exposes a JSON + SSE
|
|
17
|
+
API for the dashboard front end.
|
|
18
|
+
|
|
19
|
+
## Install (PyPI)
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
pip install opencode-dashboard-server
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
Requires:
|
|
26
|
+
|
|
27
|
+
- **Python ≥ 3.10**
|
|
28
|
+
- **`opencode` CLI** on the same host — the server shells out to `opencode db "<SQL>"` and never
|
|
29
|
+
opens the SQLite file directly (it's WAL-mode and actively written while opencode runs).
|
|
30
|
+
|
|
31
|
+
## Quick start
|
|
32
|
+
|
|
33
|
+
Run one aggregator per opencode host:
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
uvicorn app:app --port 8791
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
Run on more hosts with different ports (`8792`, `8793`, …) and list each in the front end's
|
|
40
|
+
`dashboard.yaml`. Environment switches:
|
|
41
|
+
|
|
42
|
+
- `DASHBOARD_CORS_ORIGINS` — comma-separated CORS allow-list (defaults to the loopback dev origins `localhost/127.0.0.1:5173` and `:4173`; tighten or widen for your deployment).
|
|
43
|
+
- `DASHBOARD_POLL_SECONDS` — SSE poll interval in seconds (default `5`).
|
|
44
|
+
- `OPENCODE_BIN` — path to the `opencode` binary if it's not on `PATH`.
|
|
45
|
+
|
|
46
|
+
## API
|
|
47
|
+
|
|
48
|
+
- `GET /health` — liveness
|
|
49
|
+
- `GET /overview` — whole-host aggregate (tokens by type + cost, session counts, `updatedAt`)
|
|
50
|
+
- `GET /projects` — per-project rollups
|
|
51
|
+
- `GET /projects/{id}` — one project's sessions (parent/child tree)
|
|
52
|
+
- `GET /sessions/{id}` — per-model breakdown for one session (handles mid-conversation model switches)
|
|
53
|
+
- `GET /stream` — SSE: `updated` events when the DB changes (polled ~5s)
|
|
54
|
+
|
|
55
|
+
JSON is camelCase, timestamps are epoch-ms. Full contract in the repo's `API.md`.
|
|
56
|
+
|
|
57
|
+
## From source (development)
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
git clone https://github.com/GCS-ZHN/opencode-dashboard
|
|
61
|
+
cd opencode-dashboard/server
|
|
62
|
+
uv sync # install deps (fastapi, uvicorn) + dev (pytest, httpx)
|
|
63
|
+
uv run pytest # run tests
|
|
64
|
+
uvx ruff check . # lint
|
|
65
|
+
```
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
# opencode-dashboard-server
|
|
2
|
+
|
|
3
|
+
FastAPI aggregation backend for the [opencode-dashboard](https://github.com/GCS-ZHN/opencode-dashboard)
|
|
4
|
+
project. Reads opencode's local SQLite storage via the `opencode db` CLI and exposes a JSON + SSE
|
|
5
|
+
API for the dashboard front end.
|
|
6
|
+
|
|
7
|
+
## Install (PyPI)
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
pip install opencode-dashboard-server
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
Requires:
|
|
14
|
+
|
|
15
|
+
- **Python ≥ 3.10**
|
|
16
|
+
- **`opencode` CLI** on the same host — the server shells out to `opencode db "<SQL>"` and never
|
|
17
|
+
opens the SQLite file directly (it's WAL-mode and actively written while opencode runs).
|
|
18
|
+
|
|
19
|
+
## Quick start
|
|
20
|
+
|
|
21
|
+
Run one aggregator per opencode host:
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
uvicorn app:app --port 8791
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
Run on more hosts with different ports (`8792`, `8793`, …) and list each in the front end's
|
|
28
|
+
`dashboard.yaml`. Environment switches:
|
|
29
|
+
|
|
30
|
+
- `DASHBOARD_CORS_ORIGINS` — comma-separated CORS allow-list (defaults to the loopback dev origins `localhost/127.0.0.1:5173` and `:4173`; tighten or widen for your deployment).
|
|
31
|
+
- `DASHBOARD_POLL_SECONDS` — SSE poll interval in seconds (default `5`).
|
|
32
|
+
- `OPENCODE_BIN` — path to the `opencode` binary if it's not on `PATH`.
|
|
33
|
+
|
|
34
|
+
## API
|
|
35
|
+
|
|
36
|
+
- `GET /health` — liveness
|
|
37
|
+
- `GET /overview` — whole-host aggregate (tokens by type + cost, session counts, `updatedAt`)
|
|
38
|
+
- `GET /projects` — per-project rollups
|
|
39
|
+
- `GET /projects/{id}` — one project's sessions (parent/child tree)
|
|
40
|
+
- `GET /sessions/{id}` — per-model breakdown for one session (handles mid-conversation model switches)
|
|
41
|
+
- `GET /stream` — SSE: `updated` events when the DB changes (polled ~5s)
|
|
42
|
+
|
|
43
|
+
JSON is camelCase, timestamps are epoch-ms. Full contract in the repo's `API.md`.
|
|
44
|
+
|
|
45
|
+
## From source (development)
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
git clone https://github.com/GCS-ZHN/opencode-dashboard
|
|
49
|
+
cd opencode-dashboard/server
|
|
50
|
+
uv sync # install deps (fastapi, uvicorn) + dev (pytest, httpx)
|
|
51
|
+
uv run pytest # run tests
|
|
52
|
+
uvx ruff check . # lint
|
|
53
|
+
```
|
|
@@ -6,6 +6,7 @@ Run: uv run uvicorn app:app --reload
|
|
|
6
6
|
import asyncio
|
|
7
7
|
import json
|
|
8
8
|
import logging
|
|
9
|
+
import os
|
|
9
10
|
import socket
|
|
10
11
|
import subprocess
|
|
11
12
|
from functools import lru_cache
|
|
@@ -19,6 +20,20 @@ from db import CliRunner
|
|
|
19
20
|
|
|
20
21
|
logger = logging.getLogger("dashboard")
|
|
21
22
|
|
|
23
|
+
# Comma-separated CORS allow-list; defaults to the loopback dev origins. Tight
|
|
24
|
+
# by default so a random webpage can't exfiltrate local project/session data.
|
|
25
|
+
def cors_origins() -> list[str]:
|
|
26
|
+
env = os.environ.get("DASHBOARD_CORS_ORIGINS", "").strip()
|
|
27
|
+
if env:
|
|
28
|
+
return [o.strip() for o in env.split(",") if o.strip()]
|
|
29
|
+
return [
|
|
30
|
+
"http://localhost:5173", "http://127.0.0.1:5173",
|
|
31
|
+
"http://localhost:4173", "http://127.0.0.1:4173",
|
|
32
|
+
]
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
POLL_SECONDS = float(os.environ.get("DASHBOARD_POLL_SECONDS", "5"))
|
|
36
|
+
|
|
22
37
|
|
|
23
38
|
@lru_cache(maxsize=1)
|
|
24
39
|
def opencode_version() -> str:
|
|
@@ -37,10 +52,7 @@ def create_app(runner=None) -> FastAPI:
|
|
|
37
52
|
# local project/session data from the browser (the client runs from Vite).
|
|
38
53
|
app.add_middleware(
|
|
39
54
|
CORSMiddleware,
|
|
40
|
-
allow_origins=
|
|
41
|
-
"http://localhost:5173", "http://127.0.0.1:5173",
|
|
42
|
-
"http://localhost:4173", "http://127.0.0.1:4173",
|
|
43
|
-
],
|
|
55
|
+
allow_origins=cors_origins(),
|
|
44
56
|
allow_methods=["*"],
|
|
45
57
|
allow_headers=["*"],
|
|
46
58
|
)
|
|
@@ -116,7 +128,7 @@ def create_app(runner=None) -> FastAPI:
|
|
|
116
128
|
except Exception:
|
|
117
129
|
logger.exception("stream poll failed")
|
|
118
130
|
try:
|
|
119
|
-
await asyncio.wait_for(stop.wait(),
|
|
131
|
+
await asyncio.wait_for(stop.wait(), POLL_SECONDS)
|
|
120
132
|
except asyncio.TimeoutError:
|
|
121
133
|
pass
|
|
122
134
|
|
|
@@ -11,8 +11,12 @@ Two interchangeable runners over the same SQL surface:
|
|
|
11
11
|
"""
|
|
12
12
|
|
|
13
13
|
import json
|
|
14
|
+
import os
|
|
14
15
|
import subprocess
|
|
15
16
|
|
|
17
|
+
# opencode CLI binary; override for a non-PATH install (e.g. a brew cellar path).
|
|
18
|
+
OPENCODE_BIN = os.environ.get("OPENCODE_BIN", "opencode")
|
|
19
|
+
|
|
16
20
|
|
|
17
21
|
def _inline(sql: str, params: tuple) -> str:
|
|
18
22
|
"""Inline bound params into SQL as safely-quoted literals (CliRunner has no
|
|
@@ -29,8 +33,8 @@ def _inline(sql: str, params: tuple) -> str:
|
|
|
29
33
|
|
|
30
34
|
|
|
31
35
|
class CliRunner:
|
|
32
|
-
def __init__(self, executable: str =
|
|
33
|
-
self._cmd = [executable, "db"]
|
|
36
|
+
def __init__(self, executable: str | None = None):
|
|
37
|
+
self._cmd = [executable or OPENCODE_BIN, "db"]
|
|
34
38
|
|
|
35
39
|
def query(self, sql: str, params: tuple = ()) -> list[dict]:
|
|
36
40
|
raw = subprocess.run(
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: opencode-dashboard-server
|
|
3
|
+
Version: 0.2.0
|
|
4
|
+
Summary: FastAPI aggregator over opencode's SQLite storage
|
|
5
|
+
Project-URL: Homepage, https://github.com/GCS-ZHN/opencode-dashboard
|
|
6
|
+
Project-URL: Repository, https://github.com/GCS-ZHN/opencode-dashboard
|
|
7
|
+
Project-URL: Issues, https://github.com/GCS-ZHN/opencode-dashboard/issues
|
|
8
|
+
Requires-Python: >=3.10
|
|
9
|
+
Description-Content-Type: text/markdown
|
|
10
|
+
Requires-Dist: fastapi<1,>=0.115
|
|
11
|
+
Requires-Dist: uvicorn<1,>=0.30
|
|
12
|
+
|
|
13
|
+
# opencode-dashboard-server
|
|
14
|
+
|
|
15
|
+
FastAPI aggregation backend for the [opencode-dashboard](https://github.com/GCS-ZHN/opencode-dashboard)
|
|
16
|
+
project. Reads opencode's local SQLite storage via the `opencode db` CLI and exposes a JSON + SSE
|
|
17
|
+
API for the dashboard front end.
|
|
18
|
+
|
|
19
|
+
## Install (PyPI)
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
pip install opencode-dashboard-server
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
Requires:
|
|
26
|
+
|
|
27
|
+
- **Python ≥ 3.10**
|
|
28
|
+
- **`opencode` CLI** on the same host — the server shells out to `opencode db "<SQL>"` and never
|
|
29
|
+
opens the SQLite file directly (it's WAL-mode and actively written while opencode runs).
|
|
30
|
+
|
|
31
|
+
## Quick start
|
|
32
|
+
|
|
33
|
+
Run one aggregator per opencode host:
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
uvicorn app:app --port 8791
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
Run on more hosts with different ports (`8792`, `8793`, …) and list each in the front end's
|
|
40
|
+
`dashboard.yaml`. Environment switches:
|
|
41
|
+
|
|
42
|
+
- `DASHBOARD_CORS_ORIGINS` — comma-separated CORS allow-list (defaults to the loopback dev origins `localhost/127.0.0.1:5173` and `:4173`; tighten or widen for your deployment).
|
|
43
|
+
- `DASHBOARD_POLL_SECONDS` — SSE poll interval in seconds (default `5`).
|
|
44
|
+
- `OPENCODE_BIN` — path to the `opencode` binary if it's not on `PATH`.
|
|
45
|
+
|
|
46
|
+
## API
|
|
47
|
+
|
|
48
|
+
- `GET /health` — liveness
|
|
49
|
+
- `GET /overview` — whole-host aggregate (tokens by type + cost, session counts, `updatedAt`)
|
|
50
|
+
- `GET /projects` — per-project rollups
|
|
51
|
+
- `GET /projects/{id}` — one project's sessions (parent/child tree)
|
|
52
|
+
- `GET /sessions/{id}` — per-model breakdown for one session (handles mid-conversation model switches)
|
|
53
|
+
- `GET /stream` — SSE: `updated` events when the DB changes (polled ~5s)
|
|
54
|
+
|
|
55
|
+
JSON is camelCase, timestamps are epoch-ms. Full contract in the repo's `API.md`.
|
|
56
|
+
|
|
57
|
+
## From source (development)
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
git clone https://github.com/GCS-ZHN/opencode-dashboard
|
|
61
|
+
cd opencode-dashboard/server
|
|
62
|
+
uv sync # install deps (fastapi, uvicorn) + dev (pytest, httpx)
|
|
63
|
+
uv run pytest # run tests
|
|
64
|
+
uvx ruff check . # lint
|
|
65
|
+
```
|
|
@@ -4,8 +4,9 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "opencode-dashboard-server"
|
|
7
|
-
version = "0.
|
|
7
|
+
version = "0.2.0"
|
|
8
8
|
description = "FastAPI aggregator over opencode's SQLite storage"
|
|
9
|
+
readme = "README.md"
|
|
9
10
|
requires-python = ">=3.10"
|
|
10
11
|
dependencies = [
|
|
11
12
|
"fastapi>=0.115,<1",
|
|
@@ -14,6 +15,8 @@ dependencies = [
|
|
|
14
15
|
|
|
15
16
|
[project.urls]
|
|
16
17
|
Homepage = "https://github.com/GCS-ZHN/opencode-dashboard"
|
|
18
|
+
Repository = "https://github.com/GCS-ZHN/opencode-dashboard"
|
|
19
|
+
Issues = "https://github.com/GCS-ZHN/opencode-dashboard/issues"
|
|
17
20
|
|
|
18
21
|
[tool.setuptools]
|
|
19
22
|
py-modules = ["app", "aggregate", "db"]
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
Metadata-Version: 2.4
|
|
2
|
-
Name: opencode-dashboard-server
|
|
3
|
-
Version: 0.1.0
|
|
4
|
-
Summary: FastAPI aggregator over opencode's SQLite storage
|
|
5
|
-
Project-URL: Homepage, https://github.com/GCS-ZHN/opencode-dashboard
|
|
6
|
-
Requires-Python: >=3.10
|
|
7
|
-
Requires-Dist: fastapi<1,>=0.115
|
|
8
|
-
Requires-Dist: uvicorn<1,>=0.30
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
Metadata-Version: 2.4
|
|
2
|
-
Name: opencode-dashboard-server
|
|
3
|
-
Version: 0.1.0
|
|
4
|
-
Summary: FastAPI aggregator over opencode's SQLite storage
|
|
5
|
-
Project-URL: Homepage, https://github.com/GCS-ZHN/opencode-dashboard
|
|
6
|
-
Requires-Python: >=3.10
|
|
7
|
-
Requires-Dist: fastapi<1,>=0.115
|
|
8
|
-
Requires-Dist: uvicorn<1,>=0.30
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|