diff --git a/internal/serve/store/cost_store.go b/internal/serve/store/cost_store.go
index 8056fd7..d5b6daa 100644
--- a/internal/serve/store/cost_store.go
+++ b/internal/serve/store/cost_store.go
@@ -34,6 +34,8 @@ import (
"errors"
"fmt"
"net/url"
+ "os"
+ "path/filepath"
"sync"
"time"
@@ -92,6 +94,18 @@ type sqliteCostStore struct {
// keeps the handler-side Writer from erroring under light contention
// with the quota-subscriber goroutine.
func OpenCostStore(path string) (CostStore, error) {
+ // Ensure the parent directory exists. Production opens the DB at
+ // ~/.config/ctm/ctm.db; on a fresh install (or in CI runners
+ // without a pre-existing config dir) the parent might not exist
+ // yet, and mattn/go-sqlite3 surfaces that as
+ // "unable to open database file". Cheap and idempotent — no-op
+ // for ":memory:" (filepath.Dir returns "."). Errors here are
+ // non-fatal: if mkdir fails we let sql.Open surface the real
+ // problem.
+ if path != ":memory:" {
+ _ = os.MkdirAll(filepath.Dir(path), 0o700)
+ }
+
// DSN tuning: ?_busy_timeout=5000 waits out brief writer locks;
// ?_journal=WAL enables concurrent readers; ?_sync=NORMAL pairs
// with WAL for an acceptable durability-vs-speed trade.
diff --git a/ui/src/App.tsx b/ui/src/App.tsx
index 1d38e53..06cdb86 100644
--- a/ui/src/App.tsx
+++ b/ui/src/App.tsx
@@ -26,6 +26,7 @@ import { AuthGate } from "@/routes/AuthGate";
const router = createBrowserRouter([
{ path: "/", element: },
{ path: "/s/:name", element: },
+ { path: "/s/:name/feed", element: },
{ path: "/s/:name/checkpoints", element: },
{ path: "/s/:name/pane", element: },
{ path: "/s/:name/subagents", element: },
diff --git a/ui/src/routes/SessionDetail.tsx b/ui/src/routes/SessionDetail.tsx
index 339fe92..2356d62 100644
--- a/ui/src/routes/SessionDetail.tsx
+++ b/ui/src/routes/SessionDetail.tsx
@@ -41,6 +41,7 @@ type TabKey =
| "meta";
function tabFromPath(pathname: string): TabKey {
+ if (pathname.endsWith("/feed")) return "feed";
if (pathname.endsWith("/checkpoints")) return "checkpoints";
if (pathname.endsWith("/pane")) return "pane";
if (pathname.endsWith("/subagents")) return "subagents";