Skip to content

Share one API contract across Go server and all clients (Phase 0+)#7

Open
dporkka wants to merge 4 commits into
mainfrom
phase0-contract-stabilization
Open

Share one API contract across Go server and all clients (Phase 0+)#7
dporkka wants to merge 4 commits into
mainfrom
phase0-contract-stabilization

Conversation

@dporkka

@dporkka dporkka commented Jun 18, 2026

Copy link
Copy Markdown
Owner

Phase 0+ consolidates the HTTP API contract into a single source on both sides of the boundary so the Go server, the Wails desktop bridge, and the web/extension/mobile/desktop TypeScript clients never drift. Also lands the related Phase 1 completeness fixes that were sitting broken in the working tree.

Shared contract

  • core/internal/contract — canonical Go types (SearchResult, NoteDetail, IndexResult, IndexError, Answer, Source, VaultStatus, GitStatus, GitModifiedFile) with the camelCase JSON tags the API emits. Imported by api, search, indexer, rag, and the desktop Go bridge.
  • packages/contract — zero-dependency TypeScript twin: types, a typed route table, and a portable createClient HTTP client with pluggable token storage. Consumed by web-local, browser-extension, mobile-expo, and the desktop frontend via tsconfig path mappings (+ Metro watchFolders for mobile, + vite resolve.alias for the web apps).
  • Removed apps/web-local/src/api/types.ts and the per-client hand-written duplicates; clients now re-export from @agentvault/contract.
  • make contract-check CI gate + scripts/contract-snake-list.sh guard against future drift (snake_case keys, hard-coded base URLs, non-shared types).

Completeness fixes (the in-progress tree had failing tests + a broken gate)

  • Folder resolution consolidated into templates.FolderRelForType / FolderPathForType as the single source. CLI, HTTP API, MCP, and desktop all route through it, removing three divergent folderForType copies. Rule: only meetings file under 20-projects/<project>; for every other type the project is metadata, not a file location. Fixes the MCP create_note / create_decision tests that expected notes in 10-notes and decisions in 30-decisions regardless of project. New templates/folders_test.go.
  • agentvault.ask registered as the 12th MCP tool (wired but uncounted); updated the tools/list test, README, and codebase analysis.
  • Fixed the contract-check snake_case gate — the old grep | head -20 && exit 1 always failed because head exits 0; it now only fails on actual matches.
  • Dropped a stray duplicate of contract.go and a broken Go snake-list helper from scripts/; gitignored the contract package's tsbuildinfo.

Verification (all green)

  • go vet + go test ./... (core) — pass, including the 4 previously-failing MCP tests
  • Desktop Go build with webkit2_41 tag — pass
  • make contract-check — pass
  • npm run build for web-local, browser-extension, desktop frontend — pass (desktop's >500 kB chunk warning is the known P2 item)
  • tsc --noEmit for mobile — pass

🤖 Generated with Claude Code

dporkka and others added 4 commits June 10, 2026 07:18
Finish the contract-stabilization work so the local HTTP API matches what
the web, extension, and mobile clients actually consume.

- GET /projects now returns a bare JSON string[] (was {projects:[...]}),
  matching all three clients and the other list endpoints (/search,
  /recent, /stale). Empty result serializes to [] not null.
- GET /git/status now reports real vault state via internal/git.Status
  (branch, clean, ahead/behind, modified and untracked files) and
  truthfully returns isGitRepo:false for non-versioned vaults, replacing
  the hard-coded clean-main payload.
- Wire source navigation: add ID to rag.Source (from the search result),
  surface it in the web Source type, and navigate AskPanel sources by
  /note/{id} instead of /note/{path}, which 404'd now that /ask returns
  real sources.

Tests assert the bare /projects array, both repo and non-repo /git/status
paths, and that /ask sources carry id + path. Docs updated to mark Phase 0
complete.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…tecture, quality

P0 Security fixes:
- Fix YAML injection in capture handler (quote user-supplied fields)
- Fix path traversal in note-by-path handler (validate with filepath.Clean)
- Fix race condition in capture file numbering (atomic O_CREATE|O_EXCL)
- Fix ~10 silently ignored errors across api, mcp, and search packages
- Replace predictable auth token fallback with panic on crypto/rand failure

P1 Architecture improvements:
- Consolidate ~500 lines of duplicated AI provider HTTP logic into shared httpClient
- Reuse http.Client in HealthCheck instead of creating new client each call
- Add embedClient field to Searcher instead of hardcoding Ollama defaults
- Rename rebuildFTS to clearFTS (accurate name for delete-only behavior)
- Eliminate CWD-dependent migration paths (use inline schema as primary)
- Add authentication to MCP HTTP endpoint
- Cache AI provider on Server struct with lazy initialization
- Consolidate duplicated parseAnswer into exported rag.ParseAnswer()
- Consolidate folderForType/noteTypeToFolder into templates package
- Add connection pool config and slow query logging to DB wrapper
- Use context.WithCancel in MCP ServeStdio
- Log partial failures in HybridSearch

P2 Quality improvements:
- Add recover() panic handler to writeJSON
- Improve token count heuristic (bytes vs runes)
- Handle HTML entities in stripHTMLTags
- Add token bucket rate limiter to API
- Preserve Unicode in sanitizeFilename
- Return empty slice instead of nil in git.Log
- Add cleanupDeletedFiles to remove orphaned DB entries
- Add AIStreamProvider interface for streaming support
- Use shared config.Load in indexer buildEmbedConfig
- Fix defer resp.Body.Close placement in embeddings
- Add TODO for Ollama batch endpoint
- Return relative paths in ParseFilesInDir
Phase 0+ — consolidate the HTTP API contract into a single source on both
sides of the boundary so the Go server, the Wails desktop bridge, and the
web/extension/mobile/desktop TypeScript clients never drift.

Shared contract:
- core/internal/contract: canonical Go types (SearchResult, NoteDetail,
  IndexResult, IndexError, Answer, Source, VaultStatus, GitStatus,
  GitModifiedFile) with the camelCase JSON tags the API emits. Imported by
  api, search, indexer, rag, and the desktop Go bridge.
- packages/contract: zero-dependency TypeScript twin — types, a typed route
  table, and a portable createClient HTTP client with pluggable token
  storage. Consumed by web-local, browser-extension, mobile-expo, and the
  desktop frontend via tsconfig path mappings (+ Metro watchFolders for
  mobile, + vite resolve.alias for the web apps).
- Remove apps/web-local/src/api/types.ts and the per-client hand-written
  duplicates; clients now re-export from @agentvault/contract.
- make contract-check CI gate + scripts/contract-snake-list.sh guard against
  future drift (snake_case keys, hard-coded base URLs, non-shared types).

Completeness fixes (the in-progress tree had failing tests and a broken gate):
- Consolidate note→folder resolution into templates.FolderRelForType /
  FolderPathForType as the single source. CLI, HTTP API, MCP, and desktop
  all route through it, removing three divergent folderForType copies. Rule:
  only meetings file under 20-projects/<project>; for every other type the
  project is metadata, not a file location. Fixes the MCP create_note /
  create_decision tests that expected notes in 10-notes and decisions in
  30-decisions regardless of project.
- Register agentvault.ask as the 12th MCP tool (wired but uncounted); update
  the tools/list test, README, and codebase analysis.
- Fix the contract-check snake_case gate: the old `grep | head -20 && exit 1`
  always failed because head exits 0; it now only fails on actual matches.
- Drop a stray duplicate of contract.go and a broken Go snake-list helper
  from scripts/; gitignore the contract package's tsbuildinfo.

Verified: go vet/test/build green (core + desktop webkit2_41), make
contract-check passes, and all four clients build/type-check.

Co-Authored-By: Claude <noreply@anthropic.com>
The shared RAG service (CLI/API/desktop/MCP all route through
internal/rag.Pipeline), auto-index after writes (API + MCP), and the
folder-resolution consolidation are all done in the tree, so reflect
that in the improvement plan and codebase analysis instead of listing
them as pending with stale evidence. Bump the review dates.

Co-Authored-By: Claude <noreply@anthropic.com>
@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant