opencode-dashboard-server 0.1.1__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.
@@ -1,8 +1,10 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: opencode-dashboard-server
3
- Version: 0.1.1
3
+ Version: 0.2.0
4
4
  Summary: FastAPI aggregator over opencode's SQLite storage
5
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
6
8
  Requires-Python: >=3.10
7
9
  Description-Content-Type: text/markdown
8
10
  Requires-Dist: fastapi<1,>=0.115
@@ -14,25 +16,32 @@ FastAPI aggregation backend for the [opencode-dashboard](https://github.com/GCS-
14
16
  project. Reads opencode's local SQLite storage via the `opencode db` CLI and exposes a JSON + SSE
15
17
  API for the dashboard front end.
16
18
 
17
- ## Install
19
+ ## Install (PyPI)
18
20
 
19
21
  ```bash
20
22
  pip install opencode-dashboard-server
21
23
  ```
22
24
 
23
- Requires Python ≥ 3.10 and the `opencode` CLI on the same host (the server shells out to
24
- `opencode db "<SQL>"` — it never opens the SQLite file directly, which is WAL-mode and actively
25
- written while opencode runs).
25
+ Requires:
26
26
 
27
- ## Usage
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).
28
30
 
29
- On each host that runs opencode:
31
+ ## Quick start
32
+
33
+ Run one aggregator per opencode host:
30
34
 
31
35
  ```bash
32
36
  uvicorn app:app --port 8791
33
37
  ```
34
38
 
35
- Run on more hosts with different ports (`8792`, `8793`, …) and point the front end at each.
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`.
36
45
 
37
46
  ## API
38
47
 
@@ -45,9 +54,11 @@ Run on more hosts with different ports (`8792`, `8793`, …) and point the front
45
54
 
46
55
  JSON is camelCase, timestamps are epoch-ms. Full contract in the repo's `API.md`.
47
56
 
48
- ## Development
57
+ ## From source (development)
49
58
 
50
59
  ```bash
60
+ git clone https://github.com/GCS-ZHN/opencode-dashboard
61
+ cd opencode-dashboard/server
51
62
  uv sync # install deps (fastapi, uvicorn) + dev (pytest, httpx)
52
63
  uv run pytest # run tests
53
64
  uvx ruff check . # lint
@@ -4,25 +4,32 @@ FastAPI aggregation backend for the [opencode-dashboard](https://github.com/GCS-
4
4
  project. Reads opencode's local SQLite storage via the `opencode db` CLI and exposes a JSON + SSE
5
5
  API for the dashboard front end.
6
6
 
7
- ## Install
7
+ ## Install (PyPI)
8
8
 
9
9
  ```bash
10
10
  pip install opencode-dashboard-server
11
11
  ```
12
12
 
13
- Requires Python ≥ 3.10 and the `opencode` CLI on the same host (the server shells out to
14
- `opencode db "<SQL>"` — it never opens the SQLite file directly, which is WAL-mode and actively
15
- written while opencode runs).
13
+ Requires:
16
14
 
17
- ## Usage
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
18
 
19
- On each host that runs opencode:
19
+ ## Quick start
20
+
21
+ Run one aggregator per opencode host:
20
22
 
21
23
  ```bash
22
24
  uvicorn app:app --port 8791
23
25
  ```
24
26
 
25
- Run on more hosts with different ports (`8792`, `8793`, …) and point the front end at each.
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`.
26
33
 
27
34
  ## API
28
35
 
@@ -35,9 +42,11 @@ Run on more hosts with different ports (`8792`, `8793`, …) and point the front
35
42
 
36
43
  JSON is camelCase, timestamps are epoch-ms. Full contract in the repo's `API.md`.
37
44
 
38
- ## Development
45
+ ## From source (development)
39
46
 
40
47
  ```bash
48
+ git clone https://github.com/GCS-ZHN/opencode-dashboard
49
+ cd opencode-dashboard/server
41
50
  uv sync # install deps (fastapi, uvicorn) + dev (pytest, httpx)
42
51
  uv run pytest # run tests
43
52
  uvx ruff check . # lint
@@ -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(), 5)
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 = "opencode"):
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(
@@ -1,8 +1,10 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: opencode-dashboard-server
3
- Version: 0.1.1
3
+ Version: 0.2.0
4
4
  Summary: FastAPI aggregator over opencode's SQLite storage
5
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
6
8
  Requires-Python: >=3.10
7
9
  Description-Content-Type: text/markdown
8
10
  Requires-Dist: fastapi<1,>=0.115
@@ -14,25 +16,32 @@ FastAPI aggregation backend for the [opencode-dashboard](https://github.com/GCS-
14
16
  project. Reads opencode's local SQLite storage via the `opencode db` CLI and exposes a JSON + SSE
15
17
  API for the dashboard front end.
16
18
 
17
- ## Install
19
+ ## Install (PyPI)
18
20
 
19
21
  ```bash
20
22
  pip install opencode-dashboard-server
21
23
  ```
22
24
 
23
- Requires Python ≥ 3.10 and the `opencode` CLI on the same host (the server shells out to
24
- `opencode db "<SQL>"` — it never opens the SQLite file directly, which is WAL-mode and actively
25
- written while opencode runs).
25
+ Requires:
26
26
 
27
- ## Usage
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).
28
30
 
29
- On each host that runs opencode:
31
+ ## Quick start
32
+
33
+ Run one aggregator per opencode host:
30
34
 
31
35
  ```bash
32
36
  uvicorn app:app --port 8791
33
37
  ```
34
38
 
35
- Run on more hosts with different ports (`8792`, `8793`, …) and point the front end at each.
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`.
36
45
 
37
46
  ## API
38
47
 
@@ -45,9 +54,11 @@ Run on more hosts with different ports (`8792`, `8793`, …) and point the front
45
54
 
46
55
  JSON is camelCase, timestamps are epoch-ms. Full contract in the repo's `API.md`.
47
56
 
48
- ## Development
57
+ ## From source (development)
49
58
 
50
59
  ```bash
60
+ git clone https://github.com/GCS-ZHN/opencode-dashboard
61
+ cd opencode-dashboard/server
51
62
  uv sync # install deps (fastapi, uvicorn) + dev (pytest, httpx)
52
63
  uv run pytest # run tests
53
64
  uvx ruff check . # lint
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "opencode-dashboard-server"
7
- version = "0.1.1"
7
+ version = "0.2.0"
8
8
  description = "FastAPI aggregator over opencode's SQLite storage"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.10"
@@ -15,6 +15,8 @@ dependencies = [
15
15
 
16
16
  [project.urls]
17
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"
18
20
 
19
21
  [tool.setuptools]
20
22
  py-modules = ["app", "aggregate", "db"]