You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
fix(scan,ui): restore files-rail stale-clock icon via sidecar status
The corpus/render split rebuilt the files rail from the lightweight
GET /api/folders payload instead of the sidecar-carrying branch nodes.
It threaded errorCount / warnCount for the error/warn badges but dropped
the sidecar drift status, so the rail's per-row stale-clock icon went
dark in both demo and sm serve mode.
Thread a sidecarStatus field end to end: the kernel lite-node loader
selects scan_nodes.sidecar_status, the BFF emits it on /api/folders, and
the UI projects it onto node.sidecar so the rail flags staleness
corpus-wide without hydrating the branch payload. The demo static data
source mirrors the same lite shape. spec/cli-contract.md documents the
additive field and spec/index.json is regenerated.
The e2e sidecar smoke test was stale: folders now render collapsed by
default, so it expands the tree (files-expand-all) before asserting the
stale icon on the nested leaf row.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NF5XoRisDA9Z3fNK2KMoy9
Restores the files rail's per-row stale-clock icon, dropped when the rail switched to building from the lightweight `GET /api/folders` payload (which carried the error / warn counts but not the sidecar drift status). The endpoint now emits a `sidecarStatus` field (the persisted `scan_nodes.sidecar_status`, `null` when there is no parseable sidecar), threaded from the kernel loader through the BFF into the rail so staleness flags corpus-wide in demo and `sm serve` mode.
7
+
8
+
## User-facing
9
+
10
+
The files rail again flags out-of-date nodes with the clock icon, so you can see at a glance which files have drifted since their last review.
Copy file name to clipboardExpand all lines: spec/cli-contract.md
+1-1Lines changed: 1 addition & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -602,7 +602,7 @@ The reference implementation ships a Hono BFF rooted at `src/server/`. One Node
602
602
|`GET /api/nodes/:pathB64[?include=body]`| implemented | Single-node detail envelope: `{ schemaVersion, kind: 'node', item: Node, links: { incoming: Link[], outgoing: Link[] }, issues: Issue[] }`. `:pathB64` is base64url (RFC 4648 §5, no padding) of `node.path`. Missing node or malformed `pathB64` → 404 `not-found`. **`?include=body`** (Step 14.5.a), opt-in flag adding `item.body: string \| null` to the response. The body is read from disk on demand at request time (the kernel persists `bodyHash` only). `null` means the source file was missing / unreadable when the request landed (the watcher re-emits `scan.completed` on catch-up). Without the flag, `item.body` is `undefined` and the handler does not touch the filesystem. |
603
603
|`GET /api/links?kind=&from=&to=`| implemented |`RestEnvelope` (`kind: 'links'`), list of links. Filters: `kind` (CSV whitelist of `link.kind`), `from` (exact match on `link.source`), `to` (exact match on `link.target`). No pagination at v14.2. |
604
604
|`GET /api/issues?severity=&analyzerId=&node=`| implemented |`RestEnvelope` (`kind: 'issues'`), list of issues. Filters: `severity` (CSV from `error\|warn\|info`), `analyzerId` (CSV; qualified or short suffix per `sm check --analyzers`), `node` (filter to issues whose `nodeIds` includes the path). No pagination at v14.2. |
605
-
|`GET /api/folders`| implemented |`RestEnvelope` (`kind: 'folders'`), lightweight full-corpus projection: one entry per scanned node `{ path, kind, linksInCount, linksOutCount, tokensTotal, modifiedAtMs, errorCount, warnCount }`. Only cheap scalar columns of `scan_nodes` (no frontmatter, body, links, signals, or contributions), so the SPA folders tree renders the whole corpus (up to `scan.maxScan`) with per-node data columns + per-folder issue badges without hydrating the full `ScanResult`. `tokensTotal` / `modifiedAtMs` are nullable (tokenization disabled / unknown mtime). `errorCount` / `warnCount` are the count of error / warn issues whose `nodeIds` include that path (the same incidence the tree rolls up across descendants). No pagination (the complete tree is the point; the corpus is already bounded by `scan.maxScan`). DB absent → zero items. |
605
+
| `GET /api/folders` | implemented | `RestEnvelope` (`kind: 'folders'`), lightweight full-corpus projection: one entry per scanned node `{ path, kind, linksInCount, linksOutCount, tokensTotal, modifiedAtMs, errorCount, warnCount, sidecarStatus }`. Only cheap scalar columns of `scan_nodes` (no frontmatter, body, links, signals, or contributions), so the SPA folders tree renders the whole corpus (up to `scan.maxScan`) with per-node data columns + per-folder issue badges without hydrating the full `ScanResult`. `tokensTotal` / `modifiedAtMs` are nullable (tokenization disabled / unknown mtime). `errorCount` / `warnCount` are the count of error / warn issues whose `nodeIds` include that path (the same incidence the tree rolls up across descendants). `sidecarStatus` is the node's sidecar drift status (`scan_nodes.sidecar_status`), `null` when there is no parseable sidecar, so the folders tree can flag per-row staleness without hydrating the branch payload. No pagination (the complete tree is the point; the corpus is already bounded by `scan.maxScan`). DB absent → zero items. |
606
606
| `GET /api/branch?path=<prefix>&path=<prefix>&limit=<n>` | implemented | Branch projection for the map. `path` is **repeatable**: the response is the UNION of the subtrees under every given prefix (forward-slash; a node matches a prefix when its path equals it or starts with `<prefix>/`). No `path` (or a single empty one) = the whole corpus. The union is capped at `limit` nodes (default and effective max = the scan's `maxRenderNodes`), so the response stays bounded regardless of how many prefixes are sent. Direct shape (no envelope wrap, like `/api/scan`): `{ schemaVersion, kind: 'branch', branch: { paths, total, rendered, truncated, cap }, nodes: Node[], links: Link[], issues: Issue[] }`, where `paths` echoes the requested prefixes. `nodes` is the first `rendered` nodes of the union in stable path order; `links` carries only edges whose source AND target are in `nodes`; `issues` carries those touching `nodes`. `truncated` is `total > cap`. Lets the SPA render a multi-folder selection without hydrating the full `ScanResult`. DB absent → empty branch (zero nodes). Validation: `limit` integer ≥ 1 else 400 `bad-query`. |
0 commit comments