

Also from Kynth Studios


Also from Kynth Studios


Also from Kynth Studios
1# CLAUDE.md23This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.45## What This Project Is67`continues` is a CLI tool that lets users resume AI coding sessions across Claude Code, GitHub Copilot CLI, Gemini CLI, Codex CLI, OpenCode, Factory Droid, and Cursor AI. It reads each tool's native session storage (read-only), extracts context (messages, file changes, tool activity, AI reasoning), and injects it into a different tool as a structured markdown handoff document.89## Build & Development Commands1011```bash12pnpm install # Install dependencies13pnpm run build # TypeScript compile (tsc) → dist/14pnpm run dev # Run with tsx (no build step)15pnpm test # Run unit tests (vitest)16pnpm run test:watch # Watch mode17pnpm run link # Build + pnpm link --global (local testing as `continues` / `cont`)18```1920Run a single test file:21```bash22npx vitest run src/__tests__/unit-conversions.test.ts23```2425Requires **Node.js 22+** (uses built-in `node:sqlite` for OpenCode parsing).2627## Architecture2829### Core Flow3031```32CLI (src/cli.ts) → Registry (src/parsers/registry.ts) → Index (src/utils/index.ts) → Parsers (src/parsers/*.ts) → Markdown (src/utils/markdown.ts) → Resume (src/utils/resume.ts)33```34351. **Adapter Registry** (`src/parsers/registry.ts`): Central `ToolAdapter` interface and `adapters` record. Every supported CLI tool is registered here with its parser functions, resume commands, color, label, and storage path. All other modules derive their behavior from the registry — no manual switch statements or hardcoded tool lists.36372. **CLI** (`src/cli.ts`): Commander-based CLI with interactive TUI (@clack/prompts). Handles `list`, `resume`, `scan`, `rebuild`, `pick`, and per-tool quick-resume subcommands. Quick-resume commands and source colors are generated from the registry automatically.38393. **Session Index** (`src/utils/index.ts`): Builds and caches a unified JSONL index at `~/.continues/sessions.jsonl` (5-min TTL). Calls all parsers in parallel via `Promise.allSettled` (one broken parser won't crash the CLI), merges and sorts by `updatedAt`.40414. **Parsers** (`src/parsers/*.ts`): One file per tool. Each exports `parse<Tool>Sessions()` (discovery + metadata) and `extract<Tool>Context()` (full conversation + tool activity extraction). Formats vary:42 - `claude.ts` — JSONL files under `~/.claude/projects/`, streamed with `readline`43 - `codex.ts` — JSONL files under `~/.codex/sessions/`, streamed with `readline`44 - `copilot.ts` — YAML workspace + JSONL events under `~/.copilot/session-state/`45 - `gemini.ts` — JSON files under `~/.gemini/tmp/*/chats/`46 - `opencode.ts` — SQLite DB at `~/.local/share/opencode/opencode.db` (via `node:sqlite`), with JSON file fallback47 - `droid.ts` — JSONL + companion `.settings.json` under `~/.factory/sessions/<workspace-slug>/`48 - `cursor.ts` — JSONL agent transcripts under `~/.cursor/projects/*/agent-transcripts/`49505. **Shared Utilities** (`src/utils/parser-helpers.ts`): Common functions shared by parsers — `cleanSummary()`, `extractRepoFromCwd()`, `homeDir()`.51526. **Tool Summarizer** (`src/utils/tool-summarizer.ts`): `SummaryCollector` class + formatting helpers (`shellSummary`, `fileSummary`, `grepSummary`, etc.) shared by all parsers to produce consistent one-line tool activity summaries.53547. **Markdown Generator** (`src/utils/markdown.ts`): `generateHandoffMarkdown()` takes parsed session data and produces the structured handoff document with overview table, tool activity, key decisions, recent conversation, files modified, and pending tasks.55568. **Resume** (`src/utils/resume.ts`): Handles both native resume (same tool) and cross-tool handoff. Uses the adapter registry for CLI binary names and argument patterns. For cross-tool: extracts context, saves `.continues-handoff.md` to project dir, then spawns the target CLI with the inline or reference prompt.5758### Types5960`src/types/index.ts` defines: `SessionSource` (union of 7 tool names), `UnifiedSession`, `ConversationMessage`, `ToolCall`, `ToolUsageSummary`, `SessionNotes`, `SessionContext`, `HandoffOptions`.6162### Adding a New Platform6364Adding support for a new AI coding CLI (e.g. "newtool") requires changes in **3 files**. Use `codex.ts` as the simplest reference parser.6566#### 1. Add to the `SessionSource` type — `src/types/index.ts`6768Add the new tool name to the union type:69```ts70export type SessionSource = 'codex' | 'claude' | 'copilot' | 'gemini' | 'opencode' | 'droid' | 'cursor' | 'newtool';71```7273#### 2. Create the parser — `src/parsers/newtool.ts`7475Export two functions following the established pattern:7677- `parseNewtoolSessions(): Promise<UnifiedSession[]>` — Discovers session files from the tool's storage directory, reads metadata (id, cwd, repo, branch, timestamps, summary), and returns `UnifiedSession[]` sorted by `updatedAt` descending.78- `extractNewtoolContext(session: UnifiedSession): Promise<SessionContext>` — Reads the full session, extracts `ConversationMessage[]`, uses `SummaryCollector` from `tool-summarizer.ts` to collect tool activity, and calls `generateHandoffMarkdown()` from `utils/markdown.ts` to produce the final markdown. Returns a `SessionContext`.7980Key patterns from existing parsers:81- Import shared utilities: `import { cleanSummary, extractRepoFromCwd, homeDir } from '../utils/parser-helpers.js';`82- Session discovery: walk the tool's storage directory, filter by file extension/naming pattern.83- For JSONL formats: stream with `readline.createInterface` to avoid loading entire files into memory.84- Use `SummaryCollector.add(category, summary, filePath?, isWrite?)` to accumulate tool usage and track modified files.85- Keep only the last ~10 messages in `recentMessages` for the handoff, but ensure at least one user message is included.86- Silently skip files/sessions that fail to parse (`catch {}` blocks).8788#### 3. Register in the adapter registry — `src/parsers/registry.ts`8990Add an entry to the registry with all metadata, parser functions, and resume commands:91```ts92import { parseNewtoolSessions, extractNewtoolContext } from './newtool.js';9394register({95 name: 'newtool',96 label: 'NewTool',97 color: chalk.hex('#FF6600'),98 storagePath: '~/.newtool/sessions/',99 binaryName: 'newtool',100 parseSessions: parseNewtoolSessions,101 extractContext: extractNewtoolContext,102 nativeResumeArgs: (s) => ['--resume', s.id],103 crossToolArgs: (prompt) => [prompt],104 resumeCommandDisplay: (s) => `newtool --resume ${s.id}`,105});106```107108That's it — the registry automatically wires the new tool into the CLI (quick-resume commands, source colors, help text, session index, resume logic). No switch statements or hardcoded arrays to update.109110#### 4. Add test fixtures — `src/__tests__/fixtures/index.ts`111112Create a `createNewtoolFixture(): FixtureDir` function that:113- Creates a temp directory matching the tool's storage layout.114- Writes minimal but realistic session data (at least 2 user messages + 2 assistant messages).115- Returns `{ root, cleanup }`.116117Then add conversion test cases in `src/__tests__/unit-conversions.test.ts` covering the new tool as both source and target (N-1 new conversion paths for each direction).118119## Testing120121Tests live in `src/__tests__/`. The vitest config (`vitest.config.ts`) **excludes** several test files by pattern: `e2e*`, `real-e2e*`, `stress*`, `injection*`, `parsers.test*`, `conversions.test*` (legacy file; the active suite is `unit-conversions.test.ts`). The primary test suite is `unit-conversions.test.ts`, which uses fixture data from `src/__tests__/fixtures/index.ts` to test all 42 cross-tool conversion paths (7 tools × 6 targets each) without requiring real session files on the machine.122123## Test-Driven Development124125Every code change should follow TDD discipline:1261271. **Write the test first** — parser changes, new features, and bug fixes all start with a failing test.1282. **Ground fixtures in real schemas** — before creating fixture data, read a real session file to verify field names and data structure. Use the Read tool or MCP to inspect the actual storage paths (`~/.claude/projects/`, `~/.codex/sessions/`, `~/.copilot/session-state/`, `~/.gemini/tmp/*/chats/`, `~/.local/share/opencode/`, `~/.factory/sessions/`, `~/.cursor/projects/*/agent-transcripts/`).1293. **If real session data isn't available** — ask the user to provide a sample or point to the storage directory. Don't invent schemas from imagination.130131### Test file conventions132133- **Parser/conversion tests**: `src/__tests__/unit-conversions.test.ts` — the primary test suite (fixture-based, all conversion paths)134- **Utility tests**: dedicated files (e.g. `src/__tests__/cwd-matching.test.ts`)135- **Fixtures**: `src/__tests__/fixtures/index.ts` — one `createXxxFixture()` factory per tool136137### Minimum test coverage for PRs138139- **New parser**: fixture factory + low-level parsing tests + all N-1 conversion paths in each direction140- **New utility function**: dedicated test file with edge cases141- **Bug fix**: regression test that reproduces the bug before the fix is applied142143## Key Conventions144145- ESM-only (`"type": "module"` in package.json). All local imports use `.js` extensions.146- `process.exitCode` is set instead of calling `process.exit()` directly.147- The tool suppresses `ExperimentalWarning` from `node:sqlite` at the top of `cli.ts`.148- Session data is **read-only** — the tool never modifies source session files.149- The index cache and handoff contexts are stored under `~/.continues/`.150
One repository carrying more than one format is the comparison this product exists for: does anyone actually write different content in each file, or is one a copy of the other?
| Repository | Format | Stack | Covers | Score | Changed |
|---|---|---|---|---|---|
| yigitkonur/cli-continues.github/copilot-instructions.md · 1.4k | Copilot instructions | lint-formatstylegitperformance+1 | 59/100 | 14 days ago | |
| yigitkonur/cli-continues.github/instructions/ci.instructions.md · 1.4k | Copilot instructions | setupbuildteststyle+4 | 82/100 | 14 days ago | |
| yigitkonur/cli-continues.github/instructions/parsers.instructions.md · 1.4k | Copilot instructions | testing-strategygitdo-not | 57/100 | 14 days ago | |
| yigitkonur/cli-continues.github/instructions/security.instructions.md · 1.4k | Copilot instructions | stylegitsecurity | 54/100 | 14 days ago | |
| yigitkonur/cli-continuesAGENTS.md · 1.4k | AGENTS.md | testlint-formatstyletesting-strategy+3 | 87/100 | 14 days ago | |
| yigitkonur/cli-continues.github/instructions/testing.instructions.md · 1.4k | Copilot instructions | testtesting-strategygitperformance | 56/100 | 14 days ago | |
| yigitkonur/cli-continues.github/instructions/typescript.instructions.md · 1.4k | Copilot instructions | styletypesgitdo-not | 61/100 | 14 days ago |
Same format, overlapping stack, ranked by quality.
| Repository | Format | Stack | Covers | Score | Changed |
|---|---|---|---|---|---|
| bagisto/bagistoCLAUDE.md · 28k | CLAUDE.md | setupbuildteststyle+5 | 100/100 | 7 days ago | |
| Adit-Jain-srm/NightmareNetCLAUDE.md · 46 | CLAUDE.md | buildtestlint-formatstyle+6 | 100/100 | 14 days ago | |
| tyrchen/geektime-bootcamp-aiw7/genslides/backend/CLAUDE.md · 230 | CLAUDE.md | testlint-formatstylearch+6 | 100/100 | 9 days ago | |
| nimbalyst/nimbalystpackages/android/CLAUDE.md · 1.5k | CLAUDE.md | setupbuildstylearch+2 | 100/100 | 14 days ago | |
| dotCMS/corecore-web/CLAUDE.md · 949 | CLAUDE.md | teststylearchtesting-strategy+3 | 100/100 | 14 days ago | |
| microsoft/playwrightCLAUDE.md · 95k | CLAUDE.md | buildtestlint-formatstyle+7 | 100/100 | 7 days ago | |
| tphakala/birdnet-goCLAUDE.md · 1.6k | CLAUDE.md | buildtestlint-formatstyle+8 | 100/100 | today | |
| livewire/livewireCLAUDE.md · 24k | CLAUDE.md | setupbuildteststyle+4 | 100/100 | 14 days ago |
A badge carrying the measured quality of the strongest agent config file in this repository, out of 100. It reads from this index every time somebody loads your page, so it changes when the measurement changes and there is nothing to keep up to date. Free, no account, and the value is not something you or we can set by hand.
[](https://rulestack.kynth.studio/configs/yigitkonur-cli-continues-claude)Would rather not hotlink us? Every badge is also served in shields.io’s endpoint schema, so shields renders the image and your readers never talk to our domain:
Published by Toolproof, the masthead over this index and eight others. The method behind the number is at toolproof.kynth.studio/methodology, and the whole thing is readable as JSON with no key at /api.