Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
174 changes: 174 additions & 0 deletions .github/copilot-instructions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,174 @@
# GitHub Copilot Instructions — ChittyCommand

## Project Overview

ChittyCommand is a unified life management and action dashboard for the ChittyOS ecosystem. It ingests data from 15+ financial, legal, and administrative sources, scores urgency with AI, recommends actions, and executes them via APIs, email, or browser automation.

- **Repo:** `CHITTYOS/chittycommand`
- **Deploy:** Cloudflare Workers at `command.chitty.cc`
- **Stack:** Hono (TypeScript), React + Tailwind (frontend), Neon PostgreSQL via Hyperdrive, Cloudflare R2/KV
- **Canonical URI:** `chittycanon://core/services/chittycommand` | Tier 5

## Common Commands

```bash
npm run dev # Start Hono dev server (wrangler dev)
npm run build # Typecheck (tsc --noEmit)
npm run test # Run Vitest tests
npm run deploy # Deploy to Cloudflare Workers
npm run ui:dev # Start React frontend (localhost:5173)
npm run ui:build # Build frontend for Cloudflare Pages
npm run db:generate # Generate Drizzle migrations
npm run db:migrate # Run Drizzle migrations
```

Secrets are managed via `wrangler secret put` — **never hardcode** them:

```bash
wrangler secret put PLAID_CLIENT_ID
wrangler secret put PLAID_SECRET
wrangler secret put DATABASE_URL
```

## Architecture

Single Cloudflare Worker serving API + scheduled cron jobs. Frontend is a separate React SPA (Cloudflare Pages) at `app.command.chitty.cc`.

### Key Files

- `src/index.ts` — Hono app entry point, route mounting, CORS, error handler
- `src/middleware/auth.ts` — Three auth middlewares: `authMiddleware`, `bridgeAuthMiddleware`, `mcpAuthMiddleware`
- `src/db/schema.ts` — Drizzle ORM schema (all tables prefixed `cc_`)
- `src/lib/cron.ts` — Cron sync orchestrator
- `src/lib/integrations.ts` — Service clients (Mercury, Plaid, ChittyScrape, etc.)
- `src/lib/urgency.ts` — Deterministic urgency scoring (0–100)
- `src/lib/validators.ts` — Zod schemas for all request validation
- `src/routes/` — Route handlers (one file per domain)
- `src/routes/bridge/` — Inter-service bridge routes
- `src/routes/mcp.ts` — MCP server (28 tools for Claude integration)
- `migrations/` — SQL migration files (0001–0007)
Copy link

Copilot AI Mar 4, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Key Files list says migrations are 0001–0007, but the repo currently has migrations through 0009_*. Please update this to avoid future confusion (or change to something like “0001+”).

Suggested change
- `migrations/` — SQL migration files (0001–0007)
- `migrations/` — SQL migration files (0001+)

Copilot uses AI. Check for mistakes.
- `ui/` — React frontend (Vite + Tailwind)

## Code Conventions

### TypeScript

- Strict mode is enabled (`"strict": true`). No `any` unless explicitly cast.
- Target: `ES2022`. Module resolution: `bundler`.
- All Hono apps/routes are typed: `new Hono<{ Bindings: Env; Variables: AuthVariables }>()`.
- Import `AuthVariables` from `src/middleware/auth.ts` for route-level context variables.
- Use `c.set('userId', ...)` and `c.get('userId')` for auth context in middleware and handlers.
Comment on lines +58 to +60
Copy link

Copilot AI Mar 4, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This states that all Hono apps/routes are typed with Variables: AuthVariables, but several route files are currently declared as new Hono<{ Bindings: Env }>() (e.g., accounts/obligations). Consider adjusting the instruction to reflect the actual pattern (app-level typing + add Variables: AuthVariables only where c.get('userId')/c.get('scopes') is used).

Suggested change
- All Hono apps/routes are typed: `new Hono<{ Bindings: Env; Variables: AuthVariables }>()`.
- Import `AuthVariables` from `src/middleware/auth.ts` for route-level context variables.
- Use `c.set('userId', ...)` and `c.get('userId')` for auth context in middleware and handlers.
- Default Hono apps/routes are typed: `new Hono<{ Bindings: Env }>()`.
- When a route or app needs auth context via `c.get('userId')` / `c.get('scopes')`, type it as `new Hono<{ Bindings: Env; Variables: AuthVariables }>()`.
- Import `AuthVariables` from `src/middleware/auth.ts` only in files that use these auth context variables.
- Use `c.set('userId', ...)` and `c.get('userId')` (and similarly `scopes`) for auth context in middleware and handlers.

Copilot uses AI. Check for mistakes.

### Database (Drizzle ORM)

- All tables are prefixed `cc_` (e.g., `cc_accounts`, `cc_obligations`).
- Use `uuid` PKs with `.defaultRandom()`.
- Always include `createdAt` and `updatedAt` timestamps with `{ withTimezone: true }`.
- Add `index()` on columns used in WHERE/ORDER BY clauses.
- Monetary values use `numeric` with `{ precision: 12, scale: 2 }`.
- Use `jsonb` for flexible metadata fields, default to `{}` or `[]`.
- Import `getDb` from `src/lib/db.ts` to get a database connection.

### Validation (Zod)

- Define all Zod schemas in `src/lib/validators.ts`.
- Use `@hono/zod-validator` with `zValidator('json', schema)` for request body validation.
- Validate query params with `zValidator('query', schema)`.
Comment on lines +75 to +76
Copy link

Copilot AI Mar 4, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The Validation section says to use @hono/zod-validator with zValidator('json'|'query', ...), but the codebase currently validates with schema.safeParse(...) inside handlers (no zValidator usage found). Please update these instructions to match the established safeParse pattern (or, if you want to standardize on @hono/zod-validator, update the route handlers accordingly).

Suggested change
- Use `@hono/zod-validator` with `zValidator('json', schema)` for request body validation.
- Validate query params with `zValidator('query', schema)`.
- In route handlers, validate request bodies with `schema.safeParse(await c.req.json())`.
- Validate query params with `schema.safeParse(c.req.query())` (or an equivalent object).
- On validation failure, return `c.json({ error: 'Invalid request', details: zodError.flatten() }, 400)` or a similarly safe, non-sensitive error shape.

Copilot uses AI. Check for mistakes.
- Date strings must match `/^\d{4}-\d{2}-\d{2}$/` (YYYY-MM-DD).
- UUID fields use `z.string().uuid()`.

### Routing (Hono)

- Create one route file per domain in `src/routes/`.
- Export a named `const xxxRoutes = new Hono()` from each file.
- Mount routes in `src/index.ts` using `app.route('/api/xxx', xxxRoutes)`.
- Apply auth middleware at mount time in `src/index.ts`, not inside route files.
- Always return `c.json(...)` — never return raw strings or untyped responses.
Copy link

Copilot AI Mar 4, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Routing guidance says to always return c.json(...), but there is at least one streaming endpoint returning c.newResponse(...) (SSE). Suggest loosening this to “use c.json for standard API responses” while allowing c.newResponse/streams where required.

Suggested change
- Always return `c.json(...)` — never return raw strings or untyped responses.
- For standard API responses, return `c.json(...)`. Use `c.newResponse`/streaming APIs only when you intentionally need SSE, streaming, or non-JSON responses — avoid raw/untyped responses otherwise.

Copilot uses AI. Check for mistakes.

### Error Handling

- Use the global error handler in `src/index.ts` for unhandled errors — it returns `{ error: 'Internal Server Error' }`, never leaking internals.
- Return `c.json({ error: '...' }, 4xx)` for expected client errors.
- Catch fetch errors in try/catch; fall through gracefully rather than bubbling errors.

## Auth Patterns

Three auth layers — **do not bypass or modify without security review**:

1. **`authMiddleware`** (`/api/*`) — KV token lookup, then ChittyAuth fallback. Sets `userId` and `scopes`.
2. **`bridgeAuthMiddleware`** (`/api/bridge/*`) — KV service token (`bridge:service_token`) OR user token.
3. **`mcpAuthMiddleware`** (`/mcp/*`) — ChittyAuth token first, KV service token fallback (`mcp:service_token`). Bypassed in non-production environments.

Access auth context in handlers via `c.get('userId')` and `c.get('scopes')`.

## Security Requirements

- **Never hardcode** secrets, tokens, API keys, or credentials anywhere in source code.
- All secrets go through `wrangler secret put` — never in `[vars]` in `wrangler.toml`.
- KV service tokens: `bridge:service_token`, `mcp:service_token`, `scrape:service_token`.
- CORS is restricted to approved origins: `app.command.chitty.cc`, `command.mychitty.com`, `chittycommand-ui.pages.dev`, `localhost:5173`.
Copy link

Copilot AI Mar 4, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CORS allowlist here is missing currently-configured origins (e.g., https://cmd.chitty.cc) and the existing list includes schemes like http://localhost:5173. Please update the documented allowlist to match src/index.ts so future edits don’t inadvertently “fix” CORS to the wrong set of origins.

Suggested change
- CORS is restricted to approved origins: `app.command.chitty.cc`, `command.mychitty.com`, `chittycommand-ui.pages.dev`, `localhost:5173`.
- CORS is restricted to approved origins: `https://app.command.chitty.cc`, `https://command.mychitty.com`, `https://chittycommand-ui.pages.dev`, `https://cmd.chitty.cc`, `http://localhost:5173`.

Copilot uses AI. Check for mistakes.
- Credentials use 1Password (`op run`) in local development — never expose in terminal output or logs.
- Error responses must **not** leak internal error messages, stack traces, or sensitive data.
- All user input must be validated with Zod before use.
- Use `X-Source-Service: chittycommand` header on all outbound service calls.

## Environment Bindings (Cloudflare Workers)

Available via `c.env` in route handlers and middleware:

| Binding | Type | Purpose |
|---------|------|---------|
| `HYPERDRIVE` | Hyperdrive | Neon PostgreSQL connection |
| `DOCUMENTS` | R2Bucket | Document storage |
| `COMMAND_KV` | KVNamespace | Auth tokens, sync state, service tokens |
| `AI` | Ai | Cloudflare AI Gateway |
| `ENVIRONMENT` | string | `"production"` or `"development"` |
| `CHITTYAUTH_URL` | string | ChittyAuth service URL |
| `CHITTYLEDGER_URL` | string | ChittyLedger service URL |
| `CHITTYFINANCE_URL` | string | ChittyFinance service URL |
| `CHITTYSCRAPE_URL` | string | ChittyScrape service URL |
| `CHITTYCONNECT_URL` | string | ChittyConnect service URL |
| `PLAID_CLIENT_ID` | string (secret) | Plaid API key |
| `PLAID_SECRET` | string (secret) | Plaid API secret |

Comment on lines +119 to +133
Copy link

Copilot AI Mar 4, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The markdown tables use a leading double pipe (|| ...) which renders as an extra empty column in most markdown renderers. Switching these rows to single-pipe table syntax will render correctly.

Copilot uses AI. Check for mistakes.
Always check if optional URL bindings are present before using them (e.g., `if (c.env.CHITTYAUTH_URL)`).
Comment on lines +131 to +134
Copy link

Copilot AI Mar 4, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Environment bindings table is incomplete vs the actual Env type / wrangler.toml (e.g., CHITTYCHARGE_URL, CHITTYBOOKS_URL, CHITTYASSETS_URL, CHITTYROUTER_URL, CHITTYREGISTER_URL, CHITTYCHAT_DATA_API, CHITTYSCHEMA_URL, CHITTYCERT_URL, CHITTY_CONNECT_TOKEN, PLAID_ENV, and optional DATABASE_URL). Consider either listing all current bindings or explicitly pointing readers to src/index.ts / wrangler.toml as the source of truth.

Suggested change
| `PLAID_CLIENT_ID` | string (secret) | Plaid API key |
| `PLAID_SECRET` | string (secret) | Plaid API secret |
Always check if optional URL bindings are present before using them (e.g., `if (c.env.CHITTYAUTH_URL)`).
| `CHITTYCHARGE_URL` | string | ChittyCharge service URL |
| `CHITTYBOOKS_URL` | string | ChittyBooks service URL |
| `CHITTYASSETS_URL` | string | ChittyAssets service URL |
| `CHITTYROUTER_URL` | string | ChittyRouter service URL |
| `CHITTYREGISTER_URL` | string | ChittyRegister service URL |
| `CHITTYCHAT_DATA_API` | string | ChittyChat data API base URL |
| `CHITTYSCHEMA_URL` | string | ChittySchema service URL |
| `CHITTYCERT_URL` | string | ChittyCert service URL |
| `CHITTY_CONNECT_TOKEN` | string (secret) | ChittyConnect service token |
| `PLAID_CLIENT_ID` | string (secret) | Plaid API key |
| `PLAID_SECRET` | string (secret) | Plaid API secret |
| `PLAID_ENV` | string | Plaid environment (e.g. `sandbox`, `development`, `production`) |
| `DATABASE_URL` | string (optional) | Direct PostgreSQL connection URL (optional, may be unused when using Hyperdrive) |
Always check if optional URL bindings are present before using them (e.g., `if (c.env.CHITTYAUTH_URL)`), and refer to `Env` in `src/index.ts` and `wrangler.toml` as the source of truth for the full, up-to-date bindings list.

Copilot uses AI. Check for mistakes.

## Cron Schedule

Defined in `wrangler.toml` and dispatched via `src/lib/cron.ts`:

| Schedule | Purpose |
|----------|---------|
| `0 12 * * *` | Daily 6 AM CT: Plaid + ChittyFinance sync |
| `0 13 * * *` | Daily 7 AM CT: Court docket check |
| `0 14 * * 1` | Weekly Mon 8 AM CT: Utility scrapers |
| `0 15 1 * *` | Monthly 1st 9 AM CT: Mortgage, property tax |
Comment on lines +140 to +145
Copy link

Copilot AI Mar 4, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The Cron Schedule table also uses ||-prefixed rows, which will render with an extra blank column. Consider converting it to standard markdown table formatting.

Suggested change
| Schedule | Purpose |
|----------|---------|
| `0 12 * * *` | Daily 6 AM CT: Plaid + ChittyFinance sync |
| `0 13 * * *` | Daily 7 AM CT: Court docket check |
| `0 14 * * 1` | Weekly Mon 8 AM CT: Utility scrapers |
| `0 15 1 * *` | Monthly 1st 9 AM CT: Mortgage, property tax |
| Schedule | Purpose |
| -------------- | ------------------------------------------------ |
| `0 12 * * *` | Daily 6 AM CT: Plaid + ChittyFinance sync |
| `0 13 * * *` | Daily 7 AM CT: Court docket check |
| `0 14 * * 1` | Weekly Mon 8 AM CT: Utility scrapers |
| `0 15 1 * *` | Monthly 1st 9 AM CT: Mortgage, property tax |

Copilot uses AI. Check for mistakes.

## MCP Server

The `/mcp` route exposes 28 tools across 8 domains for Claude integration. Tools return structured JSON: `content: [{ type: "json", json: ... }]`. Auth is handled by `mcpAuthMiddleware`. See `src/routes/mcp.ts` for tool definitions.

## Testing

Tests use Vitest. Run with `npm run test`. Test files live alongside source in `src/` or in a `__tests__` directory. The test configuration is in `vitest.config.ts`.

## PR and Review Policy

- One concern area per PR (security, feature, refactor, schema change, governance).
- Every PR must include: scope, risk/blast radius, test evidence, rollback plan, and migration impact.
- Do not bundle governance/ruleset changes with unrelated app logic.
- Resolve must-fix review comments (security, correctness, compliance, merge blockers) before merge.
- Do not weaken auth, CORS, or governance controls.
- Schema changes (`src/db/schema.ts`) require a new SQL migration in `migrations/`.

## ChittyOS Ecosystem Context

ChittyCommand is a **Tier 5 Application** — a consumer of upstream data, not a source of truth. It delegates to:

- **ChittyAuth** — identity and token validation
- **ChittyFinance** — financial data aggregation
- **ChittyScrape** — browser automation for portals without APIs
- **ChittyLedger** — evidence and document ledger
- **ChittyConnect** — inter-service discovery and connectivity
- **ChittySchema** — canonical schema validation
- **ChittyRegister** — service registration and beacon heartbeats
Loading