Command reference
Every read/admin command supports --json. The shape is always { success: true, data } or { success: false, error: { code, message, nextAction? } }.
install
Section titled “install”Register the five Claude Code hooks in ~/.claude/settings.json and create ~/.codika-os/events.db. The SessionStart hook is what later triggers background syncs when last-sync is stale — no system cron is written.
codika-os installIdempotent. Re-run after upgrading the CLI to refresh hook entries.
Parse local SQLite + JSONL transcripts, classify projects, compute rollups, upload to /api/sync.
codika-os sync # default: PROD onlycodika-os sync --include-dev # PROD + mirror to DEV (best-effort)codika-os sync --mode dev # single-target DEV (for local testing)codika-os sync --since 7dcodika-os sync --since 2025-04-01 # ISO date is also acceptedcodika-os sync --dry-runcodika-os sync --if-stale # skip if last sync was less than 20h ago (used by the SessionStart hook)codika-os sync --full # re-process every session (bypass skip)codika-os sync --catalog-file ./catalog.yaml # use a YAML catalog instead of /api/projectsFull flag set: --if-stale, --dry-run, --since <window>, --mode <dev|prod>, --include-dev, --catalog-file <path>, --api-url <url>, --worker-email <email>, --full, --json.
The sync command runs only the deterministic path classifier. Sessions it can’t attribute are left with project_id = NULL and surfaced via the classifications pending command (and the /codika-os:classify-sessions plugin skill) for agent-inline classification. The previous --no-llm, --llm-dry-run, and --llm-concurrency flags are gone.
Sync targets
Section titled “Sync targets”PROD is the source of truth. By default sync writes only to /api/sync?mode=prod and exits non-zero on failure. Pass --include-dev to additionally mirror to DEV — DEV is best-effort, a failure logs a warning but PROD still counts as success. --mode dev restricts to single-target DEV (intended for local testing against a dev branch).
Chunked upload
Section titled “Chunked upload”Large syncs (more than 250 sessions, e.g. a first-time 90-day backfill) are automatically split into multiple requests grouped by conversation. Each request is self-contained and idempotent on the server. If a chunk fails, the next sync resumes safely — no data is dropped or duplicated.
First-sync 90-day cap
Section titled “First-sync 90-day cap”If no ~/.codika-os/last-sync timestamp exists (fresh install), the aggregation window is automatically bounded to the last 90 days. Subsequent syncs are uncapped. Pass --since <window> to override; pass --since 0 to disable the implicit cap.
Incremental by default
Section titled “Incremental by default”sync is incremental. Each session has a fingerprint — its user_prompt count plus the size and mtime of its JSONL transcript — persisted in session_sync_state after every successful upload. The next run computes the same fingerprint and skips any session whose values match: no transcript parse, no LLM classification, no upload.
This means a sync after a week of laptop downtime processes every accumulated session exactly once, and subsequent syncs only touch sessions that gained new prompts or whose transcripts grew. No data is lost and no data is re-uploaded just because a new Claude Code session triggered the SessionStart hook.
Pass --full to bypass the skip and re-process everything. Use it after upgrading the aggregator (better classifier, improved human-time math) or to recover from a state-file corruption — the state is cleared and rebuilt as part of the run.
Output (default):
✓ Sync complete sessions 47 processed · 612 skipped · 659 local conversations 38 events 1284 …--dry-run does everything except the upload (and does not advance state). Useful for previewing classification before pushing.
classifications
Section titled “classifications”Operate on sessions the path classifier couldn’t attribute. Two subcommands.
classifications pending
Section titled “classifications pending”Fetch unattributed sessions and the project catalog for a calendar month. The output is the input contract for the /codika-os:classify-sessions skill.
codika-os classifications pending --month 2026-05 --jsoncodika-os classifications pending --month 2026-03 # human-readable countResponse shape (JSON):
{ "success": true, "data": { "month": "2026-05", "sessions": [ { "id": "…", "started_at": "2026-05-03T14:21:08Z", "cwd": "/Users/…", "first_prompts": [{ "ts": "…", "text": "…" }], "paths_touched": ["/Users/…"] } ], "catalog": [ { "slug": "codika-os", "category": "tool", "subcategory": null, "display_name": "Codika OS", "alias": "Codika OS", "prompt_only": false, "path_prefixes": ["/Users/…/agency/tools/codika-os"] } ], "catalog_by_category": { "client": [{ "slug": "creafid", "subcategory": null, "display_name": "Creafid", "prompt_only": false }], "platform": [{ "slug": "codika-app", "subcategory": "app", "display_name": "Codika App", "prompt_only": false }], "growth": [{ "slug": "outreach", "subcategory": "outreach", "display_name": "Outreach", "prompt_only": true }], "knowledge": [{ "slug": "company-os", "subcategory": "company-os", "display_name": "Company OS", "prompt_only": false }] } }}Up to 500 sessions per request. Worker scope: the bearer’s worker_email (admin/shared-secret callers may pass --worker-email).
classifications submit
Section titled “classifications submit”Submit a JSON file of classification verdicts produced by the agent.
codika-os classifications submit ./classifications.json --json --model-hint claude-opus-4-7Accepted file shape (either form):
[ { "sessionId": "…", "projectSlug": "codika-os", "subcategory": null, "confidence": 0.92, "reasoning": "First prompt mentions hooks." }]or
{ "classifications": [ { "sessionId": "…", "projectSlug": null, "suggestedSlug": "billing-ops", "suggestedCategory": "tool", "suggestedSubcategory": null, "confidence": 0.7, "reasoning": "Stripe webhook work." } ]}Each entry must set either projectSlug (a real catalog slug, optionally with a subcategory) or the suggested* fields (suggestedSlug + suggestedCategory + optional suggestedSubcategory). Server response:
{ "success": true, "data": { "applied": 87, "suggested_new": 4, "skipped": 0, "invalid_slug_demoted": 0 }}Notes:
- Append-only: every entry produces one
project_attribution_attemptsrow withmethod = 'agent-inline'. - Idempotent: re-running with the same file won’t re-write the session’s
project_idonce it’s set (the server only updates sessions still NULL). - Sessions owned by another worker are silently skipped (counted in
skipped). invalid_slug_demotedcounts entries whoseprojectSlugwasn’t in the catalog (active or inactive). They’re recorded as suggestions instead.
status
Section titled “status”Health check.
codika-os statusOutput:
Last sync 4h ago Events 268 (12 unsynced) Tool calls 1333 (47 unsynced) events.db 1.2 MB ~/.codika-os/events.db
Hooks ✓ SessionStart ✓ UserPromptSubmit ✓ Stop ✓ SessionEnd ✓ PostToolUse
Sync runs on SessionStart when last-sync >20h ago.whoami
Section titled “whoami”Print active profile and (masked) key.
codika-os whoamiOutput:
Profile: you (active)Email: you@codika.ioAPI key: cos_xxxx... (last 4: 9a2f)Base URL: https://os.codika.ioverify
Section titled “verify”Round-trip the active key against /api/auth/cli/verify.
codika-os verifyReturns ✓ valid or an error code from the auth table in auth.
List or switch profiles.
codika-os use # listcodika-os use dev-local # switch active profilelogout
Section titled “logout”Remove a profile from local config. The backend key remains valid until you revoke it from the dashboard.
codika-os logout # logout active profilecodika-os logout dev-local # logout named profileconfig
Section titled “config”Inspect or mutate the on-disk config.
codika-os config showcodika-os config set apiBaseUrl https://os.codika.iocodika-os config set apiKey cos_xxxx... --profile dev-localcodika-os config clear --profile dev-localThe plugin’s codika-os-config skill wraps this for in-conversation use.
auth …
Section titled “auth …”See the dedicated auth page — signup-request, signup-complete, login-request, login-complete.
Hook subcommands
Section titled “Hook subcommands”codika-os hooks <name> # invoked by Claude Code, not by youInternal — invoked by Claude Code with the event payload piped to stdin. You should never run these by hand. See codika-os-cli/src/cli/commands/hooks/index.ts for the implementation.
Global flags
Section titled “Global flags”| Flag | Effect |
|---|---|
--json | Machine-readable output |
--profile <name> | Override active profile for this command |
--verbose | Print debug logs to stderr |
--no-color | Disable ANSI colors |
--help | Help for any command |
JSON output examples
Section titled “JSON output examples”// codika-os whoami --json{ "success": true, "data": { "profile": "codika", "email": "you@codika.io", "organization": "Codika", "apiKeyLast4": "9a2f", "apiBaseUrl": "https://os.codika.io" }}// codika-os sync --json{ "success": true, "data": { "sessionsUpserted": 47, "unattributed": 4, "costUsdCents": 123, "durationMs": 4200 }}