SPB Git

Repository Public MIT Selected

SPBGIT-2-PROGRESS.md 12.5 KB 216 lines markdown

1<!--2  ─────────────────────────────────────────────3   SPB Git — Personal Git Platform4  ─────────────────────────────────────────────5   Author  : Simon-Pierre Boucher6   Contact : contact@spboucher.ai7   File    : docs/SPBGIT-2-PROGRESS.md8   Purpose : SPB Git 2.0 — per-phase progress log (files, trade-offs, tests, screenshots, open issues)9   License : MIT © Simon-Pierre Boucher10  ─────────────────────────────────────────────11-->12# SPB Git 2.0 — Progress log1314## Phase 0 — Reconnaissance (2026-11-01) ✅1516**Files added**: `docs/SPBGIT-2-PLAN.md`, `docs/SPBGIT-2-PROGRESS.md`,17`docs/screenshots/baseline/*.png` (home, repo, blob, commits, commit, search ×18375/1440 × dark/light).1920**Method**: read every source/template/CSS/test file, the deploy manifest on21M1M32, PM2 state and logs; measured production with Playwright (Chromium) and22WebKit; ran the existing test suite on a laptop mirror with 9 bare repos cloned23from production plus a copy of `meta.json`/`activity.jsonl`/`clones.json`24(`dev/`, git-ignored).2526**Baseline**: tests 59/59, eslint clean, headers clean. Web vitals and server27timings in the plan (§3). Production restarts: 2 861 (memory). Stale overview28caches: 8 repos (`countryatlas`, `hilmacorp-ca`, `ka-apify-actors`, `llm-api`,29`maclustr-agentd`, `wp19_uqo`, `wp20_uqo`, `wp21_uqo`).3031**Trade-offs**: work happens on a laptop mirror (`~/Desktop/Cluster/projets/spbgit`,32origin = spbgit on M1M32) because the production checkout is the live app; the33node is updated only by `git pull` + `pm2 restart` after approval.3435**Open issues carried into Phase 1**: risks 1–8 of the plan.3637## Phase 1 — Design system + reliability P0 (2026-11-01) ✅3839**Files changed**: `src/web/assets/css/tokens.css` (rewritten: semantic tokens,40three themes, type/spacing/motion scales), `src/web/assets/css/app.css`41(rewritten, mobile-first, 13 sections), `src/web/assets/js/theme-boot.js`42(auto/light/dark/midnight before first paint), `src/web/assets/js/app.js`43(rewritten: dialogs/sheets, theme, palette, toast, confirm, clipboard, file44tree, code/diff helpers, TOC), `src/web/views/layout.njk` (AppShell),45`src/web/views/components/ui.njk` (new: icon, chip, statStrip, tabs,46breadcrumbs, refSelect, emptyState, errorState, skeleton, copyButton),47`src/lib/semaphore.mjs` (new), `src/git/repo.mjs` (git semaphore, `blobInfo`,48`blobStream`, `blob({maxBytes})`, `refStamp`, `allPaths`, `grepCommits`),49`src/lib/overview.mjs` (stamp-validated cache `overview-v5.json`, clones read50once, research detection), `src/stats/activity.mjs` (stamp-validated calendar51with `allTime`), `src/server.mjs` (compact completion-only logging via52`LogController`, memoized `/healthz` with memory/git/feature fields),53`src/config.mjs` (AI flags, off by default).5455**Trade-offs**: `Instrument Serif` dropped (one font less, 1 preload less);56the constellation canvas and typewriter are gone (static terminal card on57desktop only) — decorative motion is now limited to a slow mesh drift on58≥768 px without `prefers-reduced-motion`. `git` subprocesses are capped at 1259concurrent (`SPBGIT_GIT_CONCURRENCY`); crawlers now queue instead of growing60RSS. Native `<dialog>` is used for the palette, menu, clone panel and file61tree (bottom sheets on phones, modals on desktop) — requires Safari ≥ 15.4.6263**Tests**: `test/unit/semaphore.test.mjs` (2), `test/unit/routes-helpers.test.mjs`64(8: split rows, day grouping, research signals, sparkline, query terms,65stamps), e2e extended (+6: scoped search API, tree API + traversal, 3 MB66binary streamed from `/raw` with exact bytes + metadata-only blob view,67missed-hook detection with coherent totals, split/history/blame, healthz68flags). **74/74 green**, eslint + headers clean.6970## Phase 2 — Core screens (2026-11-01) ✅7172**Files changed**: `src/web/views/{home,repo,tree,blob,commits,commit,blame,branches,tags,search,error}.njk`73(all rewritten on the component library), `partials/{repo-header,repo-card,file-table}.njk`74(rewritten), `partials/{clone-panel,tree-sheet}.njk` (new), `views/metrics.njk`75(new `/about/metrics`), `src/web/routes.mjs` (rewritten: streamed `/raw`,76metadata-only blob probe, cached highlighted blobs/markdown/blame, cached77prepared diff per sha `commit-v2.json`, split view, large diffs not loaded78by default, `/about/metrics`, scoped search page), `src/api/v1.mjs`79(`/api/v1/search`, `/api/v1/repos/:name/tree`, richer `/api/v1/stats`,80`research` flag on PATCH), `src/lib/search.mjs` (rewritten: files, refs,81commits, stamp-validated index `search-index-v2.json`).8283**Responsive QA** (`scripts/qa/screens.py`, Playwright Chromium, 13 pages ×84320/360/375/390/430/768/1024/1440/1920, light/dark/midnight): **0 horizontal85overflow, 0 essential control under 44×44 px on touch viewports** (was: every86page overflowing at 375 px). Screenshots: `docs/screenshots/v2/` (375 + 1440,87midnight + light; full run archived outside the repo).8889**Open issues carried**: commit pages ship every file's rows in one document90(3 MB uncompressed for the 60-file v4 commit; ~120 KB over the gzip edge) —91per-file lazy loading is listed as remaining work; WebKit run and 200 % zoom92are done in Phase 7.9394## Phase 3 — Developer workflows (2026-11-01) ✅9596**Files changed**: `src/web/assets/js/app.js` (⌘K: scoped server search with97debounce, recent queries, keyboard/touch navigation, repo-context commands),98`src/lib/search.mjs` + `src/api/v1.mjs` (files/commits/branches, index status),99`src/web/views/commit.njk` + `src/web/routes.mjs` (unified/split, wrap, page100line budget with deferred files, cached prepared diff), `src/insights/insights.mjs`101+ `src/web/views/insights.njk` (per-repository analytics: 52-week calendar,102contributors, hottest paths, declared dependencies from manifests —103"dependency graph where data supports it" is delivered as a dependency list104with registry links; a true graph needs lockfile resolution and is listed as105remaining work), `src/web/views/metrics.njk` (`/about/metrics`).106107**Metric coherence**: `test/e2e/roundtrip.test.mjs` disables the hook, pushes108a commit and asserts `stats.commits` and `stats.commitsLast52Weeks` both move109by exactly one and that all-time ≥ 52-week. Root cause and definitions are110documented on `/about/metrics` and in the plan (§4.2).111112**Tests**: unit `routes-helpers`, `research-insights`; e2e search/tree/split.113114## Phase 4 — Research Mode (2026-11-01) ✅115116**Files**: `src/research/profile.mjs` (pure classifier + LaTeX metadata117parser, no compilation), `src/web/views/research.njk`, route118`/:repo/research`, `research` flag on `PATCH /api/v1/repos/:name`,119auto-detection in `lib/overview.mjs` (`researchDetected`) with a banner on the120repository page. The page reads at most 256 KB of each LaTeX candidate and121never executes anything; PDFs are rendered by the browser from `/raw`.122Verified on `wp20_uqo` (31 PDFs, 2 main documents, 127 figures).123124## Phase 5 — AI groundwork (2026-11-01) ✅ (opt-in, disabled by default)125126**Files**: `src/ai/index.mjs` (chunking, per-blob cache, BM25), `src/ai/ask.mjs`127(service, budget, concurrency, prompt-injection wrapping, citation128verification), `src/ai/providers/{anthropic,openai-compatible,fake}.mjs`,129`src/config.mjs` (`SPBGIT_AI_*`), API routes (`/api/v1/ai/status`,130`POST /api/v1/repos/:name/ask`, `POST /api/v1/repos/:name/commits/:sha/summary`,13112 req/min/IP), ask card on the repository page and "Summarize" on commits132(rendered only when enabled). Anthropic provider uses the official SDK133(`claude-opus-5-5` default, server-side refusal fallbacks, `refusal` stop134reason surfaced as an error). **No provider is simulated**: without135configuration the routes 404 and the UI shows nothing; the `fake` provider is136refused outside `SPBGIT_ENV=test` (unit-tested).137138**Not done (needs credentials/infra)**: embeddings — retrieval is lexical139(BM25) by design so that nothing leaves the server until a question is asked.140141## Phase 6 — Agent Workspace (2026-11-01) ✅ design only142143`docs/AGENT-WORKSPACE-DESIGN.md`: scoped job tokens + pre-receive hook,144sandboxed runner on a separate node, approval gates, audit log, acceptance145criteria. No code shipped — the preconditions (token scopes, runner) do not146exist yet.147148## Phase 7 — Hardening & release (2026-11-01) ✅ (deployment pending approval)149150- **Cross-engine QA**: `scripts/qa/screens.py` — Chromium 13 pages ×151  320/360/375/390/430/768/1024/1440/1920 × light/dark/midnight: 0 overflow,152  0 small target; WebKit 375/1440: 0; 200 % zoom: 0; landscape 812×375: 0.153- **Accessibility**: `scripts/qa/axe.py` (WCAG 2.x A/AA + best-practice) —154  from 142 violation groups on the first 2.0 build to **0 on home, repo,155  commits, branches, search, metrics, 404** after fixes (list semantics for156  the stat strip, keyboard-focusable scroll regions, contrast tokens,157  underlined inline links, `role="img"` on the pin). Code pages: shiki themes158  switched to `github-light-high-contrast` / `github-dark-default` so every159  syntax token meets AA, and gutters on changed lines use the full foreground.160  **Final run (`docs/screenshots/v2/axe-report.json`): 0 violations on 9 pages ×161  3 themes × 375/1440.**162- **Performance**: `docs/BENCHMARKS.md` (in-process brotli/gzip added; commit163  page 3.0 MB → 55 KB wire, 679 ms → 44 ms server).164- **Security regression tests**: CSP + frame + nosniff headers, no inline165  scripts, repo HTML served as text from `/raw` with a sandbox CSP, hostile166  README (onerror/script/javascript:) neutralized while badges survive,167  loopback-only hook with repo validation, traversal on blob/raw/tree/search.168- **Docs**: `CHANGELOG.md`, `docs/DEPLOY.md` (deploy + rollback), `README.md`169  and `CLAUDE.md` updated for 2.0.170171### Manual Safari / iPhone checklist (to run on production after deploy)172173| Check | Expected |174|---|---|175| Open https://git.spboucher.ai on iPhone Safari, portrait | header 52 px, no horizontal scroll, stat strip swipes, theme follows iOS appearance |176| Switch Light/Dark/Midnight from the menu sheet, reload | choice persists; status bar colour matches |177| Repository → Clone | bottom sheet; URL selectable; Copy shows a toast; ZIP downloads |178| Repository → Files | tree sheet; folders expand lazily; current file highlighted |179| Blob | wrap on by default; line-number tap sets `#L` hash; Permalink copies a sha URL |180| Commit | deferred files load with "Load diff"; wrap toggle; split hidden on phone |181| ⌘K (search icon) | keyboard opens without zoom (16 px input), scopes scroll, results open on tap |182| Rotate to landscape | no overflow, header stays reachable |183| Dynamic Type at the largest accessibility size | no clipped controls |184| VoiceOver | skip link, landmarks, dialog labels, list semantics of the stat strip |185186## Remaining work (not done, in priority order)1871881. **Deploy to M1M32** (`docs/DEPLOY.md`) and re-run the production189   measurements (LCP/INP on real iPhone, restart count after 24 h).1902. Per-file lazy loading of diffs over the API (today: page budget + `?all=1`).1913. True dependency graph (lockfile resolution, cross-repository edges).1924. Embedding-based retrieval behind the same provider abstraction (requires a193   credentialed embeddings endpoint; BM25 stays the default).1945. Agent Workspace preconditions (scoped tokens + pre-receive hook).1956. Playwright tests in the Node test runner (today Python Playwright scripts196   are the browser QA; vitest covers server/API).1977. `deploy/ecosystem.config.cjs` / `deploy/setup-m3u96a.sh` still describe198   the pre-mld (ngrok) deployment; production is driven by the `mld`199   manifest. Documentation debt only.200201## Deployment — 2026-11-01 03:10 ✅202203Pushed `2b8daed` to spbgit and deployed on M1M32 (`git pull --ff-only`,204`npm ci --omit=dev`, fonts, `pm2 restart spbgit-server`). First home request205rebuilt 160 overviews in 15.6 s, then 28 ms. Public checks through the tunnel:206`/healthz` 2.0.0 (RSS 358 MB, git 0/12), home 121 ms / 33 KB br, repo 275 ms,207blob 535 ms, commit 1.4 s first hit then cached, `/api/v1/search` 71 ms,208`/api/v1/stats` commits 3 379 = last-52-weeks 3 379 (coherent), raw file keeps209`Content-Length`, Smart HTTP advertisement OK, responsive QA on production210375/1440 × light/midnight: 0 failures. Mobile vitals (throttled): home LCP2111 592 ms, repo 184 ms, blob 320 ms, commit 192 ms, commits 376 ms, CLS 0.212Also installed `pm2-logrotate` (50 MB × 7, compressed), flushed the 599 MB213log, removed 163 obsolete 1.1.0 cache files. AI remains disabled214(`features.ai: false`). Restart counter baseline after deploy: 1 108 — check215again after 24 h.216
Files main
Menu

Theme