docs: add llm/PLAN.md and llm/STATUS.md
This commit is contained in:
195
llm/PLAN.md
Normal file
195
llm/PLAN.md
Normal file
@@ -0,0 +1,195 @@
|
|||||||
|
# GoCalGoo — Implementation Plan
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
|
||||||
|
GoCalGoo is a single Go application with four surfaces sharing one service layer:
|
||||||
|
|
||||||
|
1. **CLI** — direct human use via cobra
|
||||||
|
2. **HTTP API** — programmatic access (REST/JSON)
|
||||||
|
3. **MCP server** — tool-style integration (stdio + HTTP)
|
||||||
|
4. **Shared service layer** — underneath all three
|
||||||
|
|
||||||
|
## Architecture
|
||||||
|
|
||||||
|
```
|
||||||
|
cmd/gocalgoo/ ← main entrypoint
|
||||||
|
internal/app/ ← app wiring, lifecycle
|
||||||
|
internal/config/ ← config loading, validation, profiles
|
||||||
|
internal/auth/ ← OAuth2, PKCE, token lifecycle, callback server
|
||||||
|
internal/google/ ← Google client init, raw API adapters
|
||||||
|
internal/calendar/ ← business logic: calendars, events
|
||||||
|
internal/contacts/ ← business logic: contacts
|
||||||
|
internal/httpapi/ ← REST/JSON API handlers
|
||||||
|
internal/mcp/ ← MCP server (stdio + HTTP)
|
||||||
|
internal/security/ ← API key auth, middleware, secret redaction
|
||||||
|
internal/store/ ← token store, API key store, local state
|
||||||
|
internal/output/ ← CLI tables/json/yaml rendering
|
||||||
|
internal/telemetry/ ← structured logging, tracing (optional)
|
||||||
|
```
|
||||||
|
|
||||||
|
## Key Design Decisions
|
||||||
|
|
||||||
|
- **No CLI→API calling**: HTTP API and MCP layer call shared services directly, not the CLI.
|
||||||
|
- **Google types at the edge**: Convert Google API types to internal types immediately.
|
||||||
|
- **Interfaces at the call site**: Interface definitions live in the package that uses them.
|
||||||
|
- **Config precedence**: CLI flags > env vars > profile config > base config file > defaults.
|
||||||
|
- **SQLite for local metadata**: API keys, audit log, local state.
|
||||||
|
- **Token file permissions**: 0600, never world-readable.
|
||||||
|
- **API keys**: Hashed at rest (bcrypt). Show raw key once on creation only.
|
||||||
|
|
||||||
|
## Core Interfaces
|
||||||
|
|
||||||
|
```go
|
||||||
|
type AuthManager interface {
|
||||||
|
LoginLoopback(ctx context.Context, port int) error
|
||||||
|
LoginManual(ctx context.Context, port int) error
|
||||||
|
Status(ctx context.Context) (AuthStatus, error)
|
||||||
|
Logout(ctx context.Context) error
|
||||||
|
}
|
||||||
|
|
||||||
|
type CalendarService interface {
|
||||||
|
ListCalendars(ctx context.Context) ([]Calendar, error)
|
||||||
|
ListEvents(ctx context.Context, req ListEventsRequest) ([]Event, error)
|
||||||
|
AddEvent(ctx context.Context, req AddEventRequest) (*Event, error)
|
||||||
|
UpdateEvent(ctx context.Context, req UpdateEventRequest) (*Event, error)
|
||||||
|
DeleteEvent(ctx context.Context, calendarID, eventID string) error
|
||||||
|
}
|
||||||
|
|
||||||
|
type ContactsService interface {
|
||||||
|
ListContacts(ctx context.Context, req ListContactsRequest) ([]Contact, error)
|
||||||
|
AddContact(ctx context.Context, req AddContactRequest) (*Contact, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
type APIKeyService interface {
|
||||||
|
CreateKey(ctx context.Context, req CreateAPIKeyRequest) (*IssuedAPIKey, error)
|
||||||
|
ValidateKey(ctx context.Context, raw string) (*Principal, error)
|
||||||
|
RevokeKey(ctx context.Context, id string) error
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## OAuth2 Plan
|
||||||
|
|
||||||
|
Google installed-app / desktop-style flow with Authorization Code + PKCE.
|
||||||
|
|
||||||
|
### Login modes
|
||||||
|
|
||||||
|
| Mode | Flag | Behavior |
|
||||||
|
|------|------|----------|
|
||||||
|
| Fixed-port loopback | `--port 53682` | Bind `127.0.0.1:<port>`, open browser, receive code |
|
||||||
|
| Random-port loopback | `--port 0` | OS picks port, prints actual port before browser launch |
|
||||||
|
| Manual fallback | `--manual` | Print URL, user pastes redirect or code, CLI exchanges |
|
||||||
|
|
||||||
|
### Scopes (v1)
|
||||||
|
- `https://www.googleapis.com/auth/calendar`
|
||||||
|
- `https://www.googleapis.com/auth/contacts`
|
||||||
|
|
||||||
|
## CLI Commands
|
||||||
|
|
||||||
|
```
|
||||||
|
gocalgoo auth login [--port 53682] [--manual]
|
||||||
|
gocalgoo auth status
|
||||||
|
gocalgoo auth logout
|
||||||
|
gocalgoo calendars list
|
||||||
|
gocalgoo events list --calendar primary [--from RFC3339] [--to RFC3339]
|
||||||
|
gocalgoo events add --calendar primary --title "..." --start RFC3339 --end RFC3339
|
||||||
|
gocalgoo events update --calendar primary --id ID --title "..."
|
||||||
|
gocalgoo events delete --calendar primary --id ID
|
||||||
|
gocalgoo contacts list
|
||||||
|
gocalgoo contacts add --given-name NAME --family-name NAME --email EMAIL
|
||||||
|
gocalgoo serve api
|
||||||
|
gocalgoo serve mcp
|
||||||
|
gocalgoo serve all
|
||||||
|
gocalgoo admin api-keys create --name NAME --perm events.read [--perm events.write]
|
||||||
|
gocalgoo admin api-keys list
|
||||||
|
gocalgoo admin api-keys revoke --id ID
|
||||||
|
gocalgoo config validate
|
||||||
|
```
|
||||||
|
|
||||||
|
## HTTP API
|
||||||
|
|
||||||
|
Base path: `/api/v1`
|
||||||
|
|
||||||
|
| Method | Path | Description |
|
||||||
|
|--------|------|-------------|
|
||||||
|
| POST | /api/v1/auth/login/start | Begin OAuth login |
|
||||||
|
| POST | /api/v1/auth/login/complete | Complete OAuth login |
|
||||||
|
| GET | /api/v1/auth/status | Auth status |
|
||||||
|
| POST | /api/v1/auth/logout | Logout |
|
||||||
|
| GET | /api/v1/calendars | List calendars |
|
||||||
|
| GET | /api/v1/calendars/{calendarId}/events | List events |
|
||||||
|
| POST | /api/v1/calendars/{calendarId}/events | Add event |
|
||||||
|
| PATCH | /api/v1/calendars/{calendarId}/events/{eventId} | Update event |
|
||||||
|
| DELETE | /api/v1/calendars/{calendarId}/events/{eventId} | Delete event |
|
||||||
|
| GET | /api/v1/contacts | List contacts |
|
||||||
|
| POST | /api/v1/contacts | Add contact |
|
||||||
|
| POST | /api/v1/admin/api-keys | Create API key |
|
||||||
|
| GET | /api/v1/admin/api-keys | List API keys |
|
||||||
|
| DELETE | /api/v1/admin/api-keys/{id} | Revoke API key |
|
||||||
|
| GET | /healthz | Liveness |
|
||||||
|
| GET | /readyz | Readiness |
|
||||||
|
|
||||||
|
## MCP
|
||||||
|
|
||||||
|
Transports: stdio + Streamable HTTP
|
||||||
|
|
||||||
|
### Tools
|
||||||
|
- `calendars_list`
|
||||||
|
- `events_list`
|
||||||
|
- `events_add`
|
||||||
|
- `events_update`
|
||||||
|
- `events_delete`
|
||||||
|
- `contacts_list`
|
||||||
|
- `contacts_add`
|
||||||
|
|
||||||
|
### Resources
|
||||||
|
- `gocalgoo://calendars`
|
||||||
|
- `gocalgoo://calendar/{id}/events`
|
||||||
|
- `gocalgoo://contacts`
|
||||||
|
|
||||||
|
### Auth
|
||||||
|
- stdio: rely on environment/config (no transport auth)
|
||||||
|
- HTTP MCP: require API key (`X-API-Key` header)
|
||||||
|
|
||||||
|
## API Key Design
|
||||||
|
|
||||||
|
- Header: `X-API-Key: <key>` or `Authorization: Bearer <service-key>`
|
||||||
|
- Storage: hashed secret (bcrypt), never raw after creation
|
||||||
|
- Fields: id, hashed_secret, name, scopes, created_at, last_used_at, disabled
|
||||||
|
- Permissions: `calendars.read`, `events.read`, `events.write`, `contacts.read`, `contacts.write`, `mcp.call`
|
||||||
|
|
||||||
|
## Security Requirements
|
||||||
|
|
||||||
|
- Bind OAuth callback loopback to `127.0.0.1` only
|
||||||
|
- Validate OAuth state parameter
|
||||||
|
- Use PKCE
|
||||||
|
- Redact secrets/codes from logs
|
||||||
|
- Token file permissions: 0600
|
||||||
|
- Hash API keys at rest
|
||||||
|
- Show raw API key once on creation only
|
||||||
|
- Admin endpoints disabled by default
|
||||||
|
- Require API key for HTTP API and MCP HTTP
|
||||||
|
|
||||||
|
## Delivery Phases
|
||||||
|
|
||||||
|
| Phase | Status | Description |
|
||||||
|
|-------|--------|-------------|
|
||||||
|
| 1 | ✅ In progress | Foundation: repo scaffold, config, logging, token store, OAuth2 CLI |
|
||||||
|
| 2 | ⏳ Pending | Core business logic: calendars, events, contacts |
|
||||||
|
| 3 | ⏳ Pending | CLI completion: output formats, validation, robust errors |
|
||||||
|
| 4 | ⏳ Pending | HTTP API: auth middleware, REST endpoints, API key management |
|
||||||
|
| 5 | ⏳ Pending | MCP: stdio transport, HTTP transport, tool/resource exposure |
|
||||||
|
| 6 | ⏳ Pending | Hardening: audit log, retry/backoff, quota-aware errors, tests, packaging |
|
||||||
|
|
||||||
|
## Go Stack
|
||||||
|
|
||||||
|
| Library | Purpose |
|
||||||
|
|---------|---------|
|
||||||
|
| `github.com/spf13/cobra` | CLI framework |
|
||||||
|
| `github.com/spf13/viper` | Config management |
|
||||||
|
| `go.uber.org/zap` | Structured logging |
|
||||||
|
| `github.com/go-chi/chi/v5` | HTTP routing |
|
||||||
|
| `golang.org/x/oauth2` | OAuth2 plumbing |
|
||||||
|
| `google.golang.org/api` | Google API clients |
|
||||||
|
| `github.com/stretchr/testify` | Test assertions |
|
||||||
|
| `golang.org/x/crypto/bcrypt` | API key hashing |
|
||||||
|
| SQLite | Local metadata (API keys, audit log) |
|
||||||
54
llm/STATUS.md
Normal file
54
llm/STATUS.md
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
# GoCalGoo — Implementation Status
|
||||||
|
|
||||||
|
## Current Phase: Phase 1 — Foundation
|
||||||
|
|
||||||
|
**Started:** 2026-04-01
|
||||||
|
**Agent:** Claude Code (via OpenClaw ACP)
|
||||||
|
**Go Skill:** Loaded from AMCS (`go-skill` — cobra, viper, zap, chi, testify)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Phase 1 Progress
|
||||||
|
|
||||||
|
| Task | Status | Notes |
|
||||||
|
|------|--------|-------|
|
||||||
|
| Repo scaffold (`go.mod`, `Makefile`, `.gitignore`) | 🔄 In progress | Agent running |
|
||||||
|
| `internal/config/` — layered config with viper | 🔄 In progress | |
|
||||||
|
| `internal/store/` — token store (JSON, 0600) | 🔄 In progress | |
|
||||||
|
| `internal/auth/` — OAuth2 + PKCE | 🔄 In progress | Fixed-port, random-port, manual modes |
|
||||||
|
| `cmd/gocalgoo/` — cobra root + auth commands | 🔄 In progress | |
|
||||||
|
| `gocalgoo config validate` command | 🔄 In progress | |
|
||||||
|
| `configs/config.yaml` example | 🔄 In progress | |
|
||||||
|
| `go build ./...` passes | ⏳ Pending | |
|
||||||
|
| Committed and pushed to Gitea | ⏳ Pending | |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Phase History
|
||||||
|
|
||||||
|
### Phase 1 — Foundation
|
||||||
|
- **Goal:** Repo scaffold, config system, logging, token store, OAuth2 CLI
|
||||||
|
- **Started:** 2026-04-01 ~20:55 SAST
|
||||||
|
- **Completed:** —
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Upcoming Phases
|
||||||
|
|
||||||
|
| Phase | Description |
|
||||||
|
|-------|-------------|
|
||||||
|
| 2 | Google API integrations: calendars list, events CRUD, contacts list/add |
|
||||||
|
| 3 | CLI polish: output formats (table/json/yaml), validation, error handling |
|
||||||
|
| 4 | HTTP API: chi router, auth middleware, REST endpoints, API key management |
|
||||||
|
| 5 | MCP server: stdio transport, HTTP transport, tools, resources, session handling |
|
||||||
|
| 6 | Hardening: audit log, retry/backoff, quota awareness, test matrix, release packaging |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Notes
|
||||||
|
|
||||||
|
- Module path: `git.warky.dev/wdevs/gocalgoo`
|
||||||
|
- Gitea remote: `http://10.23.89.1:3000/wdevs/GoCalGoo`
|
||||||
|
- AMCS Go skill used: `go-skill` (id: `ea7f18c8-639b-4166-9272-f98f4a2e53c7`)
|
||||||
|
- Config precedence: CLI flags > env vars > profile config > base config > defaults
|
||||||
|
- No CLI→API internal calling — all surfaces share the service layer directly
|
||||||
Reference in New Issue
Block a user