Skip to content

feat(cli): Slice 2 — memoria init + ~/.claude.json writer#2

Merged
warting merged 2 commits into
mainfrom
slice/2-init
May 28, 2026
Merged

feat(cli): Slice 2 — memoria init + ~/.claude.json writer#2
warting merged 2 commits into
mainfrom
slice/2-init

Conversation

@warting

@warting warting commented May 28, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Adds memoria init <token> command that validates a token, stores it, writes ~/.claude.json, and records state
  • New internal/api package with a minimal HTTP client (WhoamiGET /v1/whoami)
  • New internal/config/claude_json.go with merge-safe ~/.claude.json editing

New commands

memoria init <token> [--api-url <url>]

Flow:

  1. Calls GET /v1/whoami to validate the token (server PR: premex-ab/memoria#220)
  2. Prints Bound to tenant=<id> brain=<id> scopes=<...> to stdout
  3. Stores token via auth.Store (keychain / env-var / file)
  4. Writes mcpServers.memoria entry into ~/.claude.json (merge-safe, 0600 perms)
  5. Updates ~/.config/memoria/state.json with bound_tenant, bound_brain, token_source
  6. Prints success message

Test plan

  • go vet ./... — clean
  • go test ./... — 8 new tests across 3 packages all pass
    • internal/api: 200 parse, 401 → *AuthError + ErrInvalidToken, 500 generic error, correct header
    • internal/config: missing file created, other keys preserved, sibling servers preserved, existing entry overwritten, malformed JSON → error, 0600 perms
    • cmd/memoria: success path (stdout contains "Bound to tenant=t", ~/.claude.json written, state.json has correct fields), 401 path (non-zero exit, stderr message, no ~/.claude.json)
  • go build -o /tmp/memoria ./cmd/memoria — binary builds and --help output is correct
  • CI status check will run on this PR

warting and others added 2 commits May 28, 2026 21:18
Adds `memoria init <token>` which validates a Memoria API token,
stores it securely (keychain / env-var mode / file), writes the MCP
entry into ~/.claude.json, and records the bound tenant + brain in
~/.config/memoria/state.json.

New packages:
- internal/api: thin HTTP client; Whoami() calls GET /v1/whoami and
  returns a typed *AuthError (wrapping ErrInvalidToken) on 401.
- internal/config/claude_json.go: merge-safe ~/.claude.json writer
  that preserves all existing top-level keys and sibling MCP servers.
  Atomic write (tempfile + rename), 0600 perms, error on malformed JSON.
- cmd/memoria/init.go: cobra command; uses httptest servers in tests.

New tests (8):
- internal/api: 200 parse, 401 AuthError, 500 generic, header shape
- internal/config: missing file, other keys preserved, sibling servers,
  overwrite, malformed JSON error, 0600 perms
- cmd/memoria: success path (stdout, ~/.claude.json, state.json),
  401 path (non-zero exit, stderr, no ~/.claude.json written)
- Drop duplicate config_pkg alias import in init.go
- Use errors.Is(err, os.ErrNotExist) instead of deprecated os.IsNotExist
- Set User-Agent: memoria-cli/<version> on whoami requests
- Bound whoami response body read to 64KB
- Tell the user the token was stored when claude.json write fails
- Assert Authorization header in init_test fake server
- Use 0o700 for parent-dir create to match Slice 1 convention

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@warting warting merged commit d446dbe into main May 28, 2026
1 check passed
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