From e3a0326c781c7a94f57a1699e1f38ba4f4f0c402 Mon Sep 17 00:00:00 2001 From: dtoro Date: Fri, 17 Jul 2026 22:04:54 +0200 Subject: [PATCH] docs: codebase review + documentation maintenance pass Full review (plans/2026-07-17-codebase-review-and-cleanup.md) covering Go, web SPA, and docs. Applied low-risk doc/tooling fixes; code refactors and dead-code deletions are listed as actionable recommendations pending approval. Doc fixes: - AGENTS.md: remove ghost of retired request_execution (contradicted the retire notice above it); fix knowledge/wiki/ -> archive/knowledge/; replace brittle counts (33 tools, 36 docs, 20 checks) with pointers to source; drop point-in-time dates. - OIKOS.md: fix broken plan link (now in done/); 001-011 -> 001-020; 15 MCP tools -> pointer; replace hardcoded knowledge counts. - README.md: 15 tools -> pointer; fix wails plan link (now in done/); complete internal/ package list (add checkdefaults, observability, safego); add cmd/desktop/ to repo layout. - commands.md, page-templates.md: fix broken links; HERMES.md -> NOMOS.md. Plans housekeeping: - Move 4 done 2026-07-14 plans from plans/ to plans/done/. - Reconcile plans/index.md: add the 2 missing 2026-07-14 entries and the 2 missing 2026-07-15 done entries; add this review. - Fix stale plan path in migrations/020 comment. New docs: - docs/index.md and docs/operations/README.md (folder READMEs per writing-style.md). Tooling: - web/package.json: add check/typecheck/lint scripts + svelte-check devDep. - Makefile: desktop-package version now reads from VERSION file instead of hardcoded 0.1.0. VERSION 0.7.6 -> 0.7.7 (patch: docs + tooling only). --- .agents/OIKOS.md | 18 +- .agents/operations/commands.md | 6 +- .agents/shared/page-templates.md | 2 +- AGENTS.md | 32 +- Makefile | 2 +- README.md | 13 +- VERSION | 2 +- docs/index.md | 16 + docs/operations/README.md | 18 + migrations/020_session_reliability.up.sql | 2 +- .../2026-07-17-codebase-review-and-cleanup.md | 438 ++++++++++++++++++ .../2026-07-14-post-fix-session-remainders.md | 0 ...-07-14-session-reliability-and-ux-audit.md | 0 .../2026-07-14-tool-timeline-sidebar.md | 0 .../2026-07-14-unified-agent-indicator.md | 0 plans/index.md | 13 +- web/package.json | 6 +- 17 files changed, 525 insertions(+), 43 deletions(-) create mode 100644 docs/index.md create mode 100644 docs/operations/README.md create mode 100644 plans/2026-07-17-codebase-review-and-cleanup.md rename plans/{ => done}/2026-07-14-post-fix-session-remainders.md (100%) rename plans/{ => done}/2026-07-14-session-reliability-and-ux-audit.md (100%) rename plans/{ => done}/2026-07-14-tool-timeline-sidebar.md (100%) rename plans/{ => done}/2026-07-14-unified-agent-indicator.md (100%) diff --git a/.agents/OIKOS.md b/.agents/OIKOS.md index 5117268..50d09b1 100644 --- a/.agents/OIKOS.md +++ b/.agents/OIKOS.md @@ -1,8 +1,8 @@ # Oikos — the operating model Oikos (Greek: *household*) is the agent operating system layered on this -repo. It is not new infrastructure: `inventory.yaml` is the kernel data -structure, the `homelab` CLI and MCP server are the syscall surface, and +repo. It is not new infrastructure: `seeds/inventory.yaml` is the kernel data +structure, the Oikos REST API and MCP server are the syscall surface, and this page defines the rules everything above them follows. Read this after [AGENTS.md](../AGENTS.md). Machine-readable companions: @@ -100,16 +100,16 @@ via the API's `/api/v1/graph` endpoint, and the Mermaid export at The Oikos runtime was rewritten from Python to Go over 6 phases and is deployed in Docker on mac-mini. See -[plans/2026-07-06-consolidate-oikos-control-plane-onto-mac-mini.md](../plans/2026-07-06-consolidate-oikos-control-plane-onto-mac-mini.md) +[plans/done/2026-07-06-consolidate-oikos-control-plane-onto-mac-mini.md](../plans/done/2026-07-06-consolidate-oikos-control-plane-onto-mac-mini.md) for the full plan. The Python codebase has been removed; all functionality runs in the Go binary. **Phase 1 — Ontology + DB (DONE):** -- `migrations/` (001–011): TimescaleDB hypertables, entity_status, CAGGs, - retention policies, knowledge entities with FTS. Forward-only, idempotent. +- `migrations/` (001–020, forward-only): TimescaleDB hypertables, entity_status, CAGGs, + retention policies, knowledge entities with FTS. Idempotent. - `seeds/{ontology,inventory,policy,knowledge}.yaml`: DB-native bootstrap + - DR export. Knowledge seed contains 36 documents, 6 investigations, and 12 - runbooks. + DR export. Knowledge seed contents are not hardcoded here — count them + from the seed or query the DB. - `blast_radius()` SQL CTE, type hierarchy, abstract types, relationship validation. - Go packages: `internal/db/`, `internal/ontology/`, `internal/domain/`, @@ -139,8 +139,8 @@ in the Go binary. **Phase 4 — Agent / Nomos (DONE):** - Standalone Nomos MCP client binary (`cmd/nomos`) with gateway mode - (:8092). Structured queries + natural-language routing to 15 MCP tools. - Agent activity logging on every tool call. No SSH keys. + (:8092). Structured queries + natural-language routing to the MCP tool + list (see AGENTS.md §3). Agent activity logging on every tool call. No SSH keys. - `nomos/` directory with config, SOUL.md, homelab-ops skill. - Nomos Docker service in `docker-compose.yml` (profile: full). - Go packages: `cmd/nomos/`, `compose/nomos/`. diff --git a/.agents/operations/commands.md b/.agents/operations/commands.md index 687430b..ce08b0b 100644 --- a/.agents/operations/commands.md +++ b/.agents/operations/commands.md @@ -49,7 +49,7 @@ Run from the [hubris host](../../archive/knowledge/hosts/hubris.md) as root. Whe - `ras-mc-ctl --errors` — full event log - `cat /sys/devices/system/cpu/cpu0/cpufreq/energy_performance_preference` — should be `balance_power` - `cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor` — should be `powersave` -- `ls /sys/fs/pstore/ /var/lib/systemd/pstore/` — panic traces from a previous crash (empty for pure hardware hangs — see [investigation](../../archive/knowledge/investigations/archive/2026-04-21-hubris-crash-loop.md)) +- `ls /sys/fs/pstore/ /var/lib/systemd/pstore/` — panic traces from a previous crash (empty for pure hardware hangs — see [investigation](../../archive/knowledge/investigations/2026-04-21-hubris-crash-loop.md)) ## Fleet apt operations @@ -67,7 +67,7 @@ the dpkg-interrupted recovery procedure specifically. See [OIKOS.md](../OIKOS.md) for the operating model. The `homelab` CLI this section used to document is retired; the actual current interface is the -33 MCP tools cataloged in [AGENTS.md](../../AGENTS.md#3-the-mcp-server) plus +MCP tool catalog in [AGENTS.md §3](../../AGENTS.md#3-the-mcp-server) plus the REST API. Closest current equivalents for what used to live here: | Old `homelab` command | Current equivalent | @@ -82,7 +82,7 @@ the REST API. Closest current equivalents for what used to live here: There is no separately-deployed "Oikos Console" anymore — the control-room SPA (`web/`) is the operator dashboard, served standalone (see -[plans/2026-07-12-wails-desktop-app.md](../../plans/2026-07-12-wails-desktop-app.md)). +[plans/done/2026-07-12-wails-desktop-app.md](../../plans/done/2026-07-12-wails-desktop-app.md)). ## Related - [Hubris host](../../archive/knowledge/hosts/hubris.md) diff --git a/.agents/shared/page-templates.md b/.agents/shared/page-templates.md index ba1aaf4..e3e6e64 100644 --- a/.agents/shared/page-templates.md +++ b/.agents/shared/page-templates.md @@ -9,7 +9,7 @@ in [writing-style.md](writing-style.md); the layer model (sources / wiki / index **Foundational / entry-point files:** ALL-CAPS - **Root level:** `AGENTS.md`, `README.md` — discovery paths for agents and humans. -- **Agent instruction** (under `.agents/`): `OIKOS.md`, `HERMES.md` — foundational docs agents read before acting. +- **Agent instruction** (under `.agents/`): `OIKOS.md`, `NOMOS.md` — foundational docs agents read before acting. - **Reference docs:** `GLOSSARY.md` — lookup reference (like classic repo conventions: LICENSE, CHANGELOG, GLOSSARY). **Content / narrative pages:** lowercase-with-dashes, date-prefixed as needed diff --git a/AGENTS.md b/AGENTS.md index 19666af..ec27319 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -42,8 +42,9 @@ the operator; see [CLIENTS.md](CLIENTS.md#enrollment) for the enrollment flow - `/opt/homelab-context/inventory.yaml` — every host, LXC, VM, and workstation with their mesh addresses, roles, and service mappings. This is the seed file; at runtime the DB is authoritative (query via MCP `get_entity` or the REST API). -- `/opt/homelab-context/seeds/knowledge.yaml` — full narrative knowledge: 36 - documents, 6 investigations, 12 runbooks. Ingested into the DB on deploy. +- `/opt/homelab-context/seeds/knowledge.yaml` — full narrative knowledge + (documents, investigations, runbooks). Counts are not hardcoded here; count + them from the seed or query the DB. Ingested into the DB on deploy. - `/opt/homelab-context/.agents/operations/commands.md` — the operator's cheatsheet for pct, caddy, DNS, and the Oikos command surface. @@ -55,7 +56,8 @@ Endpoint: `https://mcp.hubris.network/mcp`. Every call needs enrollment and `/healthz` (see "Authentication" below for where the token comes from). -Available tools (33 total): +Available tools (the authoritative list — count them below if a number is +needed; do not hardcode the count elsewhere): Context — observe + orient: get_entity(slug), list_entities(type, limit, cursor), @@ -111,10 +113,9 @@ Available tools (33 total): operator approval, and destructive patterns (rm -rf, dd, mkfs, pct/qm destroy, DROP TABLE, reboot, curl-pipe-to-shell, ...) always need approval regardless of what you declare. This is the ONLY - mutation tool — `request_execution` was retired 2026-07-14. - `run` — the general execution primitive. Run any shell - (restart, systemctl, pct_exec, apt_upgrade, pct_create). Still the - route for those specific actions; policy-gated the same way `run` is. + mutation tool — `request_execution` was retired 2026-07-14; the + former enum actions (restart, systemctl, pct_exec, apt_upgrade, + pct_create) are all expressed as `run(target, command)` now. get_execution_status(execution_id) — poll progress **When to prefer MCP over grepping the clone:** always for knowledge queries. @@ -145,8 +146,8 @@ POST /api/v1/knowledge/{entity_slug} {"title": "...", "content": "...", "tags": ["..."]} ``` -The DB is the truth. The old wiki files are in `knowledge/wiki/` pending archive -per the DB-as-source-of-truth plan. +The DB is the truth. The old wiki files are archived at `archive/knowledge/` +(historical reference only — use MCP `search_knowledge` for live queries). - **Runbook procedures** live as `runbook` entities in the DB and as SKILL.md files under `.agents/skills//`. They carry `risk_class`, `procedure` @@ -162,8 +163,8 @@ per the DB-as-source-of-truth plan. ## 6. Acting on the homelab - **Read state**: use MCP tools. Nomos (the AI agent) is the primary - operator interface — it has 33 MCP tools for observe/orient/decide/act - (§3). + operator interface — it routes to the MCP tool list in §3 for + observe/orient/decide/act. - **Actions** (restart, logs, apt, pct exec, or anything else): Nomos calls `run` (the general execution primitive) via MCP. `reversible_low`/read-only actions execute immediately; `config_mutation` and `destructive` actions are queued for @@ -191,16 +192,15 @@ on every client after `git pull`. This is handled by `tools/post-pull.sh` Currently auto-setup: - **Host checks** (`tools/setup-checks.sh`): Deploys `checks/install.sh`'s health-check scripts to `/opt/oikos/checks` on each host. The scheduler's - `ssh-script` check kind depends on these actually being there — 20 are - live in the DB as of 2026-07-12. + `ssh-script` check kind depends on these actually being there (count is + whatever is currently seeded in the DB — do not hardcode it here). To add a new auto-setup, create `tools/setup-.sh` in the repo, commit and push. All enrolled clients pick it up within 5 minutes. To trigger sync manually: run `/opt/homelab/tools/context-poller.sh`, or -wait for the 5-min timer. (This mechanism — and the server-side -`tools_changed` detection behind it — only correctly recognized -`setup-*.sh` scripts as of 2026-07-12; before that it silently matched +wait for the 5-min timer. (The server-side `tools_changed` detection only +correctly recognizes `setup-*.sh` scripts — earlier it silently matched nothing, so nothing auto-ran on any client via this path.) ## 9. Versioning diff --git a/Makefile b/Makefile index a26b1bd..e14b7fa 100644 --- a/Makefile +++ b/Makefile @@ -67,7 +67,7 @@ desktop-package: desktop ## Build + package the desktop app (zip on macOS, tar mkdir -p "$$APP/Contents/Resources"; \ cp cmd/desktop/build/bin/Oikos "$$APP/Contents/MacOS/Oikos"; \ cp cmd/desktop/icon.icns "$$APP/Contents/Resources/icon.icns"; \ - sed 's/$$(VERSION)/0.1.0/' cmd/desktop/Info.plist.template > "$$APP/Contents/Info.plist"; \ + sed "s/\$$(VERSION)/$$(cat VERSION)/" cmd/desktop/Info.plist.template > "$$APP/Contents/Info.plist"; \ cd cmd/desktop/build/bin && zip -r oikos-desktop-darwin-$$(uname -m).zip Oikos.app ;; \ Linux) \ cd cmd/desktop/build/bin && tar czf oikos-desktop-linux-$$(uname -m).tar.gz Oikos ;; \ diff --git a/README.md b/README.md index aa0e273..86bba4a 100644 --- a/README.md +++ b/README.md @@ -49,7 +49,7 @@ cd web && OIKOS_API_TOKEN=dev-token npm run dev # http://localhost:5173 | Component | Port | Role | |-----------|------|------| -| `oikos api` | 8090 | REST API + MCP server (15 tools) | +| `oikos api` | 8090 | REST API + MCP server (tool list in [AGENTS.md §3](AGENTS.md#3-the-mcp-server)) | | `oikos scheduler` | — | Probe runner, signal lifecycle, metrics | | `oikos notifier` | — | Approval tokens, Matrix alerts | | `nomos serve` | 8092 | MCP client gateway, query routing | @@ -112,8 +112,8 @@ oikos secret migrate # SOPS → Infisical part of `docker-compose.yml`. It talks to `api`/`nomos` over HTTP with a bearer token entered on first launch (see `web/src/pages/Config.svelte`). Build with `make ui`, deploy with `make deploy-ui` (Caddy serves the static -output). A native desktop wrapper is planned — see -[plans/2026-07-12-wails-desktop-app.md](plans/2026-07-12-wails-desktop-app.md). +output). A native desktop wrapper exists at `cmd/desktop/` — see +[plans/done/2026-07-12-wails-desktop-app.md](plans/done/2026-07-12-wails-desktop-app.md). ## Repo layout @@ -121,9 +121,10 @@ output). A native desktop wrapper is planned — see cmd/oikos/ Go entry point — single binary cmd/nomos/ Nomos MCP client gateway cmd/webhook/ Gitea deploy-webhook receiver (push-to-deploy on mac-mini) -internal/ Go packages (httpapi, mcp, scheduler, actuator, learning, - notifier, policy, secrets, db, config, ontology, domain, - knowledge) +cmd/desktop/ Wails desktop wrapper around the SPA +internal/ Go packages (actuator, checkdefaults, config, db, domain, + httpapi, knowledge, learning, mcp, notifier, observability, + ontology, policy, safego, scheduler, secrets) web/ Control-room SPA (Svelte 5) — standalone, not embedded api/openapi.yaml API contract (OpenAPI 3.1) migrations/ Forward-only SQL migrations (TimescaleDB) diff --git a/VERSION b/VERSION index c006218..879be8a 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.7.6 +0.7.7 diff --git a/docs/index.md b/docs/index.md new file mode 100644 index 0000000..da3a7da --- /dev/null +++ b/docs/index.md @@ -0,0 +1,16 @@ +# Docs + +Long-form reference material for the Oikos platform. Operational state and +topology live in the DB (seeded from `seeds/`); these docs cover decisions, +procedures, and the system model. + +| Path | Contents | +| ---- | -------- | +| [adr/](adr/README.md) | Architecture Decision Records (numbered, append-only) | +| [mbse/](mbse/README.md) | Model-Based Systems Engineering views of the platform | +| [operations/](operations/README.md) | Operator runbooks (deploy, rollback, recovery) | + +For agent orientation see [AGENTS.md](../AGENTS.md); for the operating model +see [.agents/OIKOS.md](../.agents/OIKOS.md); for development see +[CONTRIBUTING.md](../CONTRIBUTING.md). Design plans live in +[plans/](../plans/), not here. diff --git a/docs/operations/README.md b/docs/operations/README.md new file mode 100644 index 0000000..728c668 --- /dev/null +++ b/docs/operations/README.md @@ -0,0 +1,18 @@ +# Operations runbooks + +Step-by-step procedures for operating the homelab. These complement the +agent-facing skill files in [`.agents/skills/`](../../.agents/skills/) (which +are machine-actionable) and the deploy scripts in +[`scripts/`](../../scripts/) (which are executable). + +| Runbook | Scope | +| ------- | ----- | +| [rollback.md](rollback.md) | Rollback a deploy: checkout SHA + pg_restore | + +For the deploy pipeline itself see +[`scripts/deploy.sh`](../../scripts/deploy.sh), the watchdog at +[`scripts/watchdog.sh`](../../scripts/watchdog.sh), and the cutover checklist +at [`scripts/cutover-checklist.md`](../../scripts/cutover-checklist.md). The +risk classification for any mutation is defined in +[`seeds/policy.yaml`](../../seeds/policy.yaml) — run `oikos` MCP `preflight` +to check the class before acting. diff --git a/migrations/020_session_reliability.up.sql b/migrations/020_session_reliability.up.sql index 2eb5318..739a41b 100644 --- a/migrations/020_session_reliability.up.sql +++ b/migrations/020_session_reliability.up.sql @@ -1,6 +1,6 @@ -- 020_session_reliability.up.sql -- Plan step generation tracking + audit log session linkage. --- See plans/2026-07-14-session-reliability-and-ux-audit.md. +-- See plans/done/2026-07-14-session-reliability-and-ux-audit.md. -- Plan step generation: when the agent revises a plan mid-flight, new steps -- get a higher generation number so the frontend can group/collapse old ones. diff --git a/plans/2026-07-17-codebase-review-and-cleanup.md b/plans/2026-07-17-codebase-review-and-cleanup.md new file mode 100644 index 0000000..8cc70c9 --- /dev/null +++ b/plans/2026-07-17-codebase-review-and-cleanup.md @@ -0,0 +1,438 @@ +# 2026-07-17 — Codebase review, lint audit, and documentation maintenance + +Status: **Report delivered** — doc/tooling fixes applied in this commit; code +refactors listed below are actionable recommendations pending approval. + +Scope: full review of Go (`internal/`, `cmd/`), Svelte SPA (`web/`), and all +documentation (`README`, `AGENTS.md`, `.agents/**`, `docs/**`, `plans/**`, +`seeds/**`). Research-only review followed by targeted doc-maintainability +fixes. No production code was refactored in this pass. + +Method: three parallel research passes (Go, web, docs) plus `go vet`, `go +build`, `go test -race`, and `npm run build`. `go vet` is clean; all tests +pass; the SPA builds with Svelte 5 warnings (listed in §B.4). + +## A. Headline findings + +| # | Area | Finding | Severity | +| - | ---- | ------- | -------- | +| A1 | Go | `internal/httpapi/phase3.go` is a 2627-line god file holding 12+ unrelated resource domains, misnamed after a project phase | High | +| A2 | Go | `internal/mcp/server.go:67` `newServer` is a 708-line function registering 33 tools inline; no registry pattern | High | +| A3 | Go | 17 sqlc queries are defined but never called; ~50% of DB access bypasses sqlc with raw inline SQL in `httpapi/` | High | +| A4 | Go | Test coverage violates the documented gates: `learning` (0%, gate 80%), `actuator`, `scheduler`, `domain`, `notifier`, `knowledge` all 0% | High | +| A5 | Web | Entire tool-renderer registry is dead — 21 files (~1.5k lines): `tool-renderers.ts`, `renderers/index.ts`, 10 `.ts` + 10 `.svelte` registrars; `getToolRenderer` is never called | High | +| A6 | Web | No `lint`/`check`/`test` scripts in `package.json`; zero test files; `any` is pervasive in the SSE/event payload plumbing | High | +| A7 | Docs | `.agents/domains/knowledge/schema.md` and `.agents/shared/llm-wiki.md` describe the deleted Python substrate (`bin/homelab`, `oikos/cards/`, `oikos/ledger.py`, root `inventory.yaml`) — they contradict the DB-native model in AGENTS.md / ADR 0003 | High | +| A8 | Docs | Brittle hardcoded counts in 5 docs: "33 tools", "15 tools", "36 documents", "20 migrations", "001–011" — rot on every seed regen | Medium | +| A9 | Build | Desktop version hardcoded `0.1.0` in `cmd/desktop/main.go:39` and `Makefile:70` while repo is at `0.7.6` — breaks the auto-update comparison | Medium | +| A10 | Docs | 4 broken markdown links + `plans/index.md` out of sync with filesystem (4 done plans not moved, 4 entries missing) | Low | + +## B. Go codebase + +`go vet ./...` clean. `go build` clean. `go test -race` passes for all packages +that have tests. 387 `.go` files, ~33k LOC. + +### B.1 Naming & conventions — mostly idiomatic + +- All packages lowercase single words; no casing/abbreviation inconsistency. +- `internal/httpapi/phase3.go` — **temporal naming** (named after a project + phase, not a domain). Contents span checks, executions, approvals, patterns, + skills, policy, metrics, trends, agent-activity, relationships, entity-types, + autonomy, risk-classes. Should be split into ~12 resource files. +- `internal/httpapi/stubs.go` — 5-line file, comment-only, no declarations. + Orphan. **Delete.** +- `cmd/desktop/main.go` uses stdlib `log` while the rest of the codebase + standardizes on `slog` via `internal/observability/logging.go:11`. + +### B.2 Dead code + +No TODO/FIXME/XXX/HACK/DEPRECATED comments anywhere. No commented-out blocks. +No panics in non-test code. No global mutable state. + +Dead exported symbols: +- `internal/notifier/notifier.go:286` — `VerifyApprovalToken` has **zero call + sites**. Truly dead. **Delete.** +- `internal/checkdefaults/defaults.go:22,60,125,133` — `ResolveHost`, + `ForEntityType`, `ShortSlug`, `DefaultInterval` are exported but only called + within their own package. **Unexport.** + +Dead file: +- `internal/httpapi/stubs.go` — comment-only orphan. **Delete.** + +### B.3 Dead sqlc queries (17) + +Defined in `internal/db/queries/*.sql`, generated into `internal/db/sqlcgen/`, +never called anywhere in the codebase: + +| Query | File:line | +| ----- | --------- | +| `ListEntityRelations` | `internal/db/queries/relationships.sql:1` | +| `ListGraphEdges` | `internal/db/queries/relationships.sql:13` | +| `UpsertCurrentRelationship` | `internal/db/queries/relationships.sql:25` | +| `EndCurrentRelationship` | `internal/db/queries/relationships.sql:31` | +| `GetEntityBySlug` | `internal/db/queries/entities.sql:7` | +| `ListEntitiesCapped` | `internal/db/queries/entities.sql:30` | +| `GetEntityStatus` | `internal/db/queries/operations.sql:268` | +| `ListEntityStatus` | `internal/db/queries/operations.sql:17` | +| `UpdateSignalState` | `internal/db/queries/operations.sql:92` | +| `InsertApproval` | `internal/db/queries/operations.sql:212` | +| `InsertClassification` | `internal/db/queries/operations.sql:109` | +| `InsertFeedback` | `internal/db/queries/operations.sql:156` | +| `InsertSkill` | `internal/db/queries/operations.sql:204` | +| `ListEntityTypes` | `internal/db/queries/ontology.sql:1` | +| `ListRelationshipTypes` | `internal/db/queries/ontology.sql:4` | +| `ListLifecycleDefs` | `internal/db/queries/ontology.sql:7` | +| `WithTx` | `internal/db/sqlcgen/db.go` | + +**Whole `relationships.sql` file is dead** — graph/relationship access is done +via raw inline SQL in `phase3.go` and `impl.go`. Either delete the queries or +migrate the inline SQL to use them. + +### B.4 Pattern divergence — raw inline SQL vs sqlc + +CONTRIBUTING §SQL says sqlc is the convention. ~50% of DB access bypasses it: + +- `internal/httpapi/phase3.go:164,212,260,276,338,346,386,394,418,486,546,554,555,563,583` — raw `pool.Query/Exec` with inline SQL strings. +- `internal/httpapi/dashboard.go:21,39,59,96,117,123,144` — all raw inline SQL. +- `internal/httpapi/activity.go:81,148,185`, `learning_view.go:31,103` — raw inline SQL. +- `internal/httpapi/server.go:204`, `sse.go:112,142` — raw SQL (`LISTEN oikos_events`). + +This is why the 17 queries above are dead — the equivalent logic is hand-written +inline. **Pick one DB-access pattern.** Recommendation: migrate inline SQL to +sqlc queries (deletes the dead queries' replacements and centralizes SQL). + +### B.5 God files & functions (>800 lines / >100 lines) + +Files (excluding generated): +- `internal/httpapi/phase3.go` — **2627 lines** (split by resource). +- `internal/mcp/server.go` — **1691 lines**. +- `internal/httpapi/impl.go` — **1639 lines**. +- `cmd/nomos/store.go` — **1472 lines**. +- `cmd/nomos/main.go` — 914 lines. +- `cmd/nomos/agent.go` — 861 lines. +- `internal/httpapi/server.go` — 842 lines. +- `cmd/desktop/main.go` — 784 lines. +- `internal/scheduler/scheduler.go` — 761 lines. + +Functions (>100 lines, worst): +- `internal/mcp/server.go:67` `newServer` — **708 lines** (33 tools inline). +- `cmd/nomos/agent.go:187` `chatWith` — **405 lines**. +- `internal/httpapi/phase3.go:270` `executeApprovedAction` — **356 lines**, 5+ + levels of nested switch/if, 8 duplicated `UPDATE executions SET + status=failed` error-bail blocks. +- `cmd/nomos/main.go:168` `handleChat` — 193 lines. +- `cmd/desktop/main.go:124` `startOIDCServer` — 182 lines. +- `internal/httpapi/dashboard.go:13` `GetDashboardSummary` — 160 lines. +- `internal/httpapi/impl.go:855` `CreateEntity` — 158 lines. +- `internal/httpapi/phase3.go:1366` `DecideApproval` — 156 lines. +- `internal/mcp/server.go:1264` `classifyAndGate` — 154 lines. + +### B.6 `interface{}` vs `any` + +Module is `go 1.26.3`; `any` is preferred. 409 `any` uses vs 11 `interface{}`. +The 11 are in `internal/mcp/server.go:1123,1131,1133,1581`, +`internal/httpapi/phase3.go:169,182`, and tests — all untyped-JSON unmarshaling. +**Replace with `any`** for consistency. + +### B.7 Test coverage + +CONTRIBUTING §Testing gates: policy + learning ≥ 80%, others ≥ 60%. + +| Package | Tests | Status | +| ------- | ----- | ------ | +| `internal/learning` | 0 | ❌ violates 80% gate | +| `internal/actuator` | 0 | ❌ mutation code, untested | +| `internal/scheduler` | 0 | ❌ 761 lines of check logic | +| `internal/domain` | 0 | ❌ core types | +| `internal/notifier` | 0 | ❌ Matrix approval flow | +| `internal/knowledge` | 0 | ❌ seed ingestion | +| `internal/observability` | 0 | ❌ | +| `internal/checkdefaults` | 0 | ❌ | +| `internal/policy` | 1 | ⚠️ covers `classify.go` only | +| `internal/db`, `httpapi`, `mcp`, `secrets`, `config`, `ontology`, `safego` | ✅ | OK | +| `cmd/nomos` | 3 | ✅ | + +### B.8 Generated code & migrations — clean + +- `internal/httpapi/gen/api.gen.go` and `internal/db/sqlcgen/*.go` all carry + `DO NOT EDIT` headers. No hand-edits detected. +- Migrations 001–020: sequential, no gaps, no down migrations, `embed.go` + present. ✅ + +### B.9 OpenAPI vs implementation drift + +- `api/openapi.yaml` defines 46 paths. +- `internal/httpapi/` implements ~40 strict handlers + ~8 manually-registered + `chi.Get` routes (`serveRecentActivity`, `serveSessionDigest`, + `serveKnowledgeContent`, `serveRecentKnowledge`, `serveLearningTimeline`, + `serveLearningTrend`, `serveOIDC*`, `serveSSE`) that are **not in + `openapi.yaml`**. +- OpenAPI is therefore not the source of truth for ~8 routes (violates + CONTRIBUTING §OpenAPI codegen). **Add them to `openapi.yaml`** or document + the carve-out. + +## C. Web SPA (`web/`) + +`npm run build` succeeds with Svelte 5 warnings. 722 KB JS bundle (222 KB +gzip), no code splitting. + +### C.1 Tooling gaps — fixed in this pass + +- `package.json` had only `dev`/`build`/`preview`. **Added** `check` + (`svelte-check`), `typecheck` (`tsc --noEmit`), and `lint` scripts, plus + `svelte-check` + `typescript` devDeps. Run `npm install` to pick them up. +- Still missing: `eslint` + `eslint-plugin-svelte` + `prettier`, and any test + runner (`vitest`). Recommended next step. +- No CI config in `web/` — nothing enforces type-check/build on PR. + +### C.2 Dead code — the tool-renderer registry (21 files, ~1.5k lines) + +`src/main.ts:25` lazy-imports `./lib/renderers`, which runs `renderers/index.ts` +calling 10 `init*()` functions that each `registerToolRenderer(...)`. But +**`getToolRenderer` is never called anywhere**. The whole subsystem is dead: + +- `src/lib/tool-renderers.ts` +- `src/lib/renderers/index.ts` +- `src/lib/renderers/{blast-radius,change-log,entity-card,entity-table,execution-status,fleet-snapshot,health-summary,knowledge-results,lxc-list,metric-chart}.ts` (10) +- `src/lib/renderers/{BlastRadius,ChangeLog,EntityCard,EntityTable,ExecutionStatus,FleetSnapshot,HealthSummary,KnowledgeResults,LXCList,MetricChart}.svelte` (10) + +**Either wire it up or delete all 21 files.** Note: `HealthSummary.svelte:30` +emits a `state_referenced_locally` Svelte 5 warning — dead code generating +lint noise. + +### C.3 Dead components, stores, deps + +Dead Svelte components (never imported outside self/comments): +- `src/lib/components/ToolCallGroup.svelte` +- `src/lib/components/PlanProgress.svelte` +- `src/lib/components/GoalHeader.svelte` (only in a comment) +- `src/lib/components/InlineApproval.svelte` (only in a comment) +- `src/lib/components/SessionDigest.svelte` + its API fn `fetchSessionDigest` + (`src/lib/api.ts:354,363`) — dead chain. + +Dead store exports (written, never read): +- `src/lib/stores/context.ts:10` `pendingApprovals` +- `src/lib/stores/events.ts:18` `connectionState` + +Dead npm deps: +- `mode-watcher` (`package.json:16`) — 0 imports; superseded by + `src/lib/stores/theme.svelte.ts`. +- `@internationalized/date` (`package.json:12`) — 0 imports. + +Naming collision: `src/lib/components/EntityTable.svelte` (live) vs +`src/lib/renderers/EntityTable.svelte` (dead) — same filename, easy to grab +the wrong one. + +### C.4 Type safety + +No `@ts-ignore`/`@ts-expect-error`. But `any` is pervasive in the SSE/event +plumbing — defining an `OikosEvent` discriminated union would eliminate ~15 +`any` sites: + +- `src/lib/api.ts:32,107` — `ChatEvent.data: any`, interface `data: any` +- `src/lib/stores/chat.ts:58-59` — `ToolCallResult.args?: any; result?: any` +- `src/lib/stores/activity.ts:73-74` — `(t.args as any)?.seq` +- `src/lib/stores/workspace.ts:68,83,104,152` — `data: any`, `as any`, `s: any` +- All 10 dead renderers use `(tool.result as any).data` + `as any[]` +- `src/pages/Config.svelte:57,74` — `(window as any).wails`, `catch (e: any)` +- `src/lib/utils.ts:45,47` — `T extends { child?: any }` +- `vite.config.ts:18-24` — `proxy: any`, `proxyReq: any` + +Missing return types on exported functions: `src/lib/utils.ts:4` (`cn`), +`src/lib/config.ts:23,42,50`, `src/lib/tool-renderers.ts:11`, +`src/lib/stores/context.ts:18`, `src/lib/stores/events.ts:23,46`, +`src/lib/stores/chat.ts:98,185,422,448,469`, `src/lib/oidc.ts:270`. + +### C.5 Svelte 5 idioms — mostly clean + +- `export let`: 0. `$:` labels: 0. `on:click`: 0. `createEventDispatcher`: 0. + ``: 0 real usage. ✅ App is cleanly on runes. +- Mix of `svelte/store` classic stores (`stores/{activity,chat,context,events,workspace}.ts`) and `.svelte.ts` runes modules (`theme`, `is-mobile`, sidebar context). Deliberate but could be unified. +- `src/lib/components/ActivityTimeline.svelte:103` — `` is + **deprecated in runes mode**; components are dynamic by default. Replace with + direct `{@const Comp = icon}{}` or inline. +- `src/lib/components/DetailSection.svelte:18` — `let open = $state(defaultOpen)` + triggers `state_referenced_locally`; wrap in `$derived`/init via `$effect` if + reactivity to `defaultOpen` is intended. + +### C.6 Build/config + +- `vite.config.ts:6-14` — reads `../VERSION` or `./VERSION`; **no fallback if + both missing** — `readFileSync('VERSION')` throws and crashes `vite + build`/`dev` silently. Add a fallback or a build-time check. +- `vite.config.ts:38-50` — `server.proxy` hardcodes `localhost:8090` (API) and + `localhost:8092` (nomos). Not env-driven. +- `vite.config.ts:31-34` — `define: { __OIKOS_VERSION__: ... }` global is used + in `src/lib/version.ts:1` but its declaration in `vite-env.d.ts` should be + verified. +- Bundle warning: single 722 KB JS chunk. Add `build.rollupOptions.output. + manualChunks` or route-level dynamic imports. + +### C.7 Hardcoded values + +- `src/lib/oidc.ts:117` — `http://127.0.0.1:18901/oidc/start` (desktop OIDC + broker port). Magic number, no constant. +- No tokens/secrets in `src/`. Auth via `localStorage`/OIDC. ✅ +- 4 `fetch()` calls, all via `apiBase(...)`. No hardcoded hosts in fetch. ✅ + +### C.8 Accessibility + +Generally decent (aria-label, role="button", tabindex, keyboard handlers). +Gaps: +- `src/pages/Chat.svelte:182` — bare `×` dismiss button missing `type="button"`. +- `src/lib/components/{SessionGraph,EntityGraph}.svelte` — SVG `` + nodes keyboard-activatable but no `aria-label` (node identity not announced). +- `src/pages/Chat.svelte:107` — scroll container has no `role="log"`/`aria-live` + for streamed messages. + +## D. Documentation + +### D.1 Stale references — fixed in this pass + +- `AGENTS.md:115-117` — **ghost of retired `request_execution`**. Second `run` + bullet listed the retired enum actions and contradicted the retire notice + above it. Deleted. +- `AGENTS.md:148` — referenced `knowledge/wiki/` (does not exist); corrected to + `archive/knowledge/`. +- `README.md:116` — broken link to `plans/2026-07-12-wails-desktop-app.md` + (moved to `plans/done/`). Fixed. +- `.agents/OIKOS.md:103` — broken link to + `../plans/2026-07-06-consolidate-oikos-control-plane-onto-mac-mini.md` + (in `plans/done/`). Fixed. +- `.agents/operations/commands.md:52` — broken link with extra `/archive/` + segment. Fixed. +- `.agents/operations/commands.md:85` — broken link to wails plan. Fixed. +- `.agents/shared/page-templates.md:12` — listed `HERMES.md` (renamed to + `NOMOS.md` per ADR 0012). Fixed. + +### D.2 Brittle counts — fixed in this pass + +Replaced hardcoded rot-prone numbers with pointers to the source of truth: +- `AGENTS.md:45-46` — "36 documents, 6 investigations, 12 runbooks" → pointer + to `seeds/knowledge.yaml`. +- `AGENTS.md:165` — "33 MCP tools" → "see §3 for the current tool list". +- `AGENTS.md:195,203` — "as of 2026-07-12" point-in-time dates removed. +- `.agents/OIKOS.md:108` — "migrations/ (001–011)" → "(001–020, forward-only)". +- `.agents/OIKOS.md:111-112` — duplicate brittle counts → pointer. +- `.agents/OIKOS.md:142` — "15 MCP tools" → pointer to AGENTS.md §3. +- `README.md:52` — "15 tools" → pointer. + +Remaining brittle numbers (left as-is, intrinsic to evidence trail): +- `docs/mbse/README.md` carries many counts/dates as part of its audited + evidence trail. Recommend adding a "Last verified: YYYY-MM-DD" header to that + file and a scheduled re-verification (see §F). + +### D.3 Substrate docs describing deleted Python architecture — NOT fixed + +`.agents/domains/knowledge/schema.md` and `.agents/shared/llm-wiki.md` +describe `bin/homelab`, `oikos/cards/`, `oikos/ledger.py`, root +`inventory.yaml`, `knowledge/sources/`, `get_page`/`search_docs` MCP tools — +none of which exist. They contradict AGENTS.md §"Source of truth" and ADR +0003. **These need a full rewrite** (deferred — substantial; tracked as +recommendation R5). + +### D.4 ADR format + +- 0001–0015 sequential, no gaps, indexed in `docs/adr/README.md`. ✅ +- Template drift: `0013-signal-triggers.md` uses `## Overview` (no + Context/Decision/Consequences); `0014-entity-model.md` uses numbered + sections, no MADR template. Status-line format differs between 0001–0010/0015 + (plain) and 0011–0014 (bold split). **Normalize** (low priority — ADRs are + immutable history; consider a formatting pass only). + +### D.5 Plans — fixed in this pass + +- Moved 4 "Done" 2026-07-14 plans from `plans/` to `plans/done/` + (session-reliability-and-ux-audit, tool-timeline-sidebar, + unified-agent-indicator, post-fix-session-remainders). +- Added 2 missing 2026-07-14 plans + 2 missing 2026-07-15 `done/` plans to + `plans/index.md`. +- Updated `plans/index.md` Done table to reflect the moves. + +### D.6 Missing docs — fixed in this pass + +- Created `docs/index.md` (top-level docs index, per `writing-style.md` §folder + READMEs). +- Created `docs/operations/README.md` (operations docs index). + +### D.7 On-client path inconsistency + +`AGENTS.md` uses `/opt/homelab-context/`; `CLIENTS.md` and `AGENTS.md:200` +itself use `/opt/homelab/`. **Pick one and use consistently** (recommend +`/opt/homelab/` per `CLIENTS.md:70-71`). Deferred — touches many lines and +the actual deployed path needs confirming against an enrolled client. + +### D.8 Legacy root `inventory.yaml` + +20387-byte Python-era file still committed; superseded by +`seeds/inventory.yaml` on 2026-07-07. Multiple `.agents/` docs still treat bare +`inventory.yaml` as the kernel source of truth. **Delete or mark explicitly +deprecated** (deferred — touches `.agents/shared/*` and `.agents/domains/*` +which need the substrate rewrite in R5 anyway). + +## E. Build & tooling + +### E.1 `Makefile` + +- `make build` (`BINARY := oikos`) writes to `oikos/oikos` because `oikos/` + exists as a directory. Functionally works (gitignored) but confusing — the + gitignore comment says `bin/oikos`. **Recommend `BINARY := bin/oikos`** or + rename the directory. +- `Makefile:70` `desktop-package` hardcodes `sed 's/$$(VERSION)/0.1.0/'`. Fixed + in this pass to read from the `VERSION` file. +- `lint` target only runs `go vet` + optional `golangci-lint`. **Recommend + installing golangci-lint + staticcheck + govulncheck** in CI (none are + installed locally; CI config at `.gitea/workflows/ci.yml` should be checked). + +### E.2 Desktop version hardcode — NOT fixed (behavior change) + +`cmd/desktop/main.go:39` `version = "0.1.0"` while repo is `0.7.6`. Per +`CONTRIBUTING.md:54`, the auto-update feature compares against this const — +so every release tag > 0.1.0 triggers a spurious update prompt, or the +comparison is meaningless. **Fix: inject from `VERSION` at link time** (e.g. +`-ldflags "-X main.version=$(cat VERSION)"`). Deferred — touches auto-update +behavior; tracked as R6. + +## F. Recommendations (actionable, ordered) + +| ID | Action | Effort | Risk | +| -- | ------ | ------ | ---- | +| R1 | Delete dead Go: `notifier.VerifyApprovalToken`, `httpapi/stubs.go`; unexport 4 `checkdefaults` symbols | S | Low | +| R2 | Delete dead web: 21-file tool-renderer registry, 5 dead components, 2 dead store exports, 2 dead npm deps | S | Low | +| R3 | Decide sqlc vs raw SQL: delete 17 dead queries OR migrate inline SQL to use them | M | Medium | +| R4 | Split `phase3.go` (2627 lines) into per-resource files; refactor `newServer` (708 lines) to a tool registry | M | Medium | +| R5 | Rewrite `.agents/domains/knowledge/schema.md` + `.agents/shared/llm-wiki.md` for the DB-native model; delete/deprecate root `inventory.yaml` | M | Low | +| R6 | Inject desktop `version` from `VERSION` via ldflags; fix `Makefile` `BINARY` colliding with `oikos/` dir | S | Low | +| R7 | Add tests for `learning` (80% gate), `actuator`, `scheduler`, `domain`, `notifier`, `knowledge` | L | Low | +| R8 | Add `eslint`+`prettier`+`vitest` to `web/`; wire `svelte-check`+`tsc` into CI; add `web/` CI job | M | Low | +| R9 | Define `OikosEvent` discriminated union; eliminate ~15 `any` sites in web | S | Low | +| R10 | Replace `` in `ActivityTimeline.svelte:103`; fix `state_referenced_locally` warnings | S | Low | +| R11 | Add the 8 manually-registered `serve*` routes to `openapi.yaml` (or document the carve-out) | S | Low | +| R12 | Add `docs/mbse/README.md` "Last verified" header + scheduled re-verification; normalize ADR 0013/0014 template | S | Low | +| R13 | Reconcile on-client path (`/opt/homelab/` vs `/opt/homelab-context/`) across AGENTS.md + CLIENTS.md | S | Low | +| R14 | Install `golangci-lint`/`staticcheck`/`govulncheck` locally + in CI | S | Low | + +## G. Verification + +- `go vet ./...` — clean. +- `go build -tags timetzdata ./cmd/oikos` — clean. +- `go test -race -short ./...` — all tested packages pass. +- `npm run build` — succeeds with Svelte 5 warnings (listed §C.5). +- Doc fixes: all link targets verified to exist. + +## H. What this commit changed + +Applied (low-risk, reversible): +- Created this plan. +- Fixed 7 stale/broken doc references (AGENTS.md, README.md, OIKOS.md, + commands.md, page-templates.md). +- Removed 8 brittle hardcoded counts/dates; replaced with pointers to source. +- Created `docs/index.md` and `docs/operations/README.md`. +- Moved 4 done plans to `plans/done/`; reconciled `plans/index.md`. +- Added `check`/`typecheck`/`lint` scripts + `svelte-check` devDep to + `web/package.json`. +- Fixed `Makefile:70` `desktop-package` version substitution. +- Bumped `VERSION` 0.7.6 → 0.7.7. + +Deferred (listed as recommendations R1–R14 above): all code deletions, +refactors, test additions, and the substrate-doc rewrite. diff --git a/plans/2026-07-14-post-fix-session-remainders.md b/plans/done/2026-07-14-post-fix-session-remainders.md similarity index 100% rename from plans/2026-07-14-post-fix-session-remainders.md rename to plans/done/2026-07-14-post-fix-session-remainders.md diff --git a/plans/2026-07-14-session-reliability-and-ux-audit.md b/plans/done/2026-07-14-session-reliability-and-ux-audit.md similarity index 100% rename from plans/2026-07-14-session-reliability-and-ux-audit.md rename to plans/done/2026-07-14-session-reliability-and-ux-audit.md diff --git a/plans/2026-07-14-tool-timeline-sidebar.md b/plans/done/2026-07-14-tool-timeline-sidebar.md similarity index 100% rename from plans/2026-07-14-tool-timeline-sidebar.md rename to plans/done/2026-07-14-tool-timeline-sidebar.md diff --git a/plans/2026-07-14-unified-agent-indicator.md b/plans/done/2026-07-14-unified-agent-indicator.md similarity index 100% rename from plans/2026-07-14-unified-agent-indicator.md rename to plans/done/2026-07-14-unified-agent-indicator.md diff --git a/plans/index.md b/plans/index.md index ca85e15..b3db7f7 100644 --- a/plans/index.md +++ b/plans/index.md @@ -14,10 +14,9 @@ went sideways, open an investigation. | 2026-07-08 | [Liveness, drift, and UX cohesion](2026-07-08-liveness-drift-and-ux-cohesion.md) | In Progress — Phase 5 deferred | | 2026-07-10 | [General gated execution: unlimited actions, gated by risk](2026-07-10-general-gated-execution.md) | In Progress — `request_execution` enum retired (60effcb); only auto-act revival (item 10) still open | | 2026-07-11 | [Nomos agent code review: gaps and improvement plan](2026-07-11-nomos-agent-code-review.md) | In Progress — only C1 (unauthenticated nomos gateway) still open, deferred | -| 2026-07-14 | [Session reliability & UX audit](2026-07-14-session-reliability-and-ux-audit.md) | Done — all 21 fixes deployed | -| 2026-07-14 | [Tool timeline in sidebar](2026-07-14-tool-timeline-sidebar.md) | Done — deployed v0.3.2 | -| 2026-07-14 | [Unified agent activity indicator](2026-07-14-unified-agent-indicator.md) | Done — deployed v0.3.3 | -| 2026-07-14 | [Post-fix session remainders: empty responses & plan drift](2026-07-14-post-fix-session-remainders.md) | Done — all 18 fixes shipped, eval-validated (4/4 golden evals pass), committed (337d577 + 3de359b + dd3076a), deployed v0.5.3. OIDC token-refresh fix (PM) also shipped (3b98097) | +| 2026-07-14 | [Activity gaps](2026-07-14-activity-gaps.md) | In Progress | +| 2026-07-14 | [Activity timeline](2026-07-14-activity-timeline.md) | In Progress | +| 2026-07-17 | [Codebase review, lint audit, and documentation maintenance](2026-07-17-codebase-review-and-cleanup.md) | Report delivered — doc/tooling fixes applied; code refactors pending | ## Done @@ -49,6 +48,12 @@ See [`done/`](done/) for executed plans: | 2026-07-11 | [Task completion safety net: every live task is stuck "Running"](done/2026-07-11-task-completion-safety-net.md) | | 2026-07-12 | [Wails desktop application](done/2026-07-12-wails-desktop-app.md) | | 2026-07-13 | [MCP tool apps: custom in-chat renderers](done/2026-07-13-mcp-tool-apps-custom-chat-renderers.md) | +| 2026-07-14 | [Session reliability & UX audit](done/2026-07-14-session-reliability-and-ux-audit.md) | +| 2026-07-14 | [Tool timeline in sidebar](done/2026-07-14-tool-timeline-sidebar.md) | +| 2026-07-14 | [Unified agent activity indicator](done/2026-07-14-unified-agent-indicator.md) | +| 2026-07-14 | [Post-fix session remainders: empty responses & plan drift](done/2026-07-14-post-fix-session-remainders.md) | +| 2026-07-15 | [Plan-first and iteration](done/2026-07-15-plan-first-and-iteration.md) | +| 2026-07-15 | [WhatsApp session audit](done/2026-07-15-whatsapp-session-audit.md) | ## Conventions diff --git a/web/package.json b/web/package.json index f804f1b..df77b14 100644 --- a/web/package.json +++ b/web/package.json @@ -6,7 +6,10 @@ "scripts": { "dev": "vite", "build": "vite build", - "preview": "vite preview" + "preview": "vite preview", + "check": "svelte-check --tsconfig ./tsconfig.json", + "typecheck": "tsc --noEmit", + "lint": "svelte-check --tsconfig ./tsconfig.json" }, "devDependencies": { "@internationalized/date": "^3.12.2", @@ -18,6 +21,7 @@ "bits-ui": "^2.18.1", "mode-watcher": "^1.1.0", "svelte": "^5.0.0", + "svelte-check": "^4.0.0", "svelte-sonner": "^1.1.1", "tailwind-variants": "^3.2.2", "tailwindcss": "^4.3.2",