|
1 | 1 | # AGENTS.md |
2 | 2 |
|
3 | | -This repository is a Node.js/Bun TypeScript CLI for managing AI agent configurations. |
4 | | -It provides an adapter-based architecture to sync configs for Claude Code, Cursor, |
5 | | -Windsurf, OpenCode, and VSCode across machines using git and symlinks/copies. |
6 | | - |
7 | | -## Quick facts |
8 | | -- Runtime: Node.js ≥20 or Bun |
9 | | -- Language: TypeScript (ES modules) |
10 | | -- Entry point: src/index.ts (shebang: `#!/usr/bin/env node`) |
11 | | -- Build: tsup (outputs to dist/) |
12 | | -- OS targets: macOS + Linux (Windows planned) |
13 | | -- Package manager: npm or bun |
14 | | -- Package name: @donnes/syncode |
15 | | - |
16 | | -## Commands (build / lint / test) |
17 | | -- Install dependencies: `bun install` or `npm install` |
18 | | -- Run CLI in dev mode: `bun run dev` (uses tsx) |
19 | | -- Build for production: `bun run build` (uses tsup) |
20 | | -- Type check: `bun run typecheck` |
21 | | -- Link the CLI globally: `bun link` or `npm link` |
22 | | -- CLI usage help: `syncode help` |
23 | | - |
24 | | -Notes |
25 | | -- There is no lint script defined in `package.json`. |
26 | | -- There is no test runner configured in this repo. |
27 | | -- Build outputs to `dist/` directory via tsup. |
28 | | - |
29 | | -## Single-test guidance |
30 | | -- No test framework is configured, so there is no "single test" command. |
31 | | -- If you add tests, also add a `package.json` script and document the single-test |
32 | | - usage here. |
33 | | - |
34 | | -## Repository structure |
35 | | -- `src/index.ts` is the CLI entry and interactive menu. |
36 | | -- `src/commands/` contains 3 user-facing commands: new, sync, status |
37 | | -- `src/adapters/` contains agent adapters implementing AgentAdapter interface |
38 | | -- `src/config/` contains configuration management (manager.ts, types.ts) |
39 | | -- `src/utils/` contains shared helpers (fs/git/paths/shell/platform). |
40 | | -- `configs/` (in user's repo) stores tracked agent configs |
41 | | - |
42 | | -## Architecture |
43 | | - |
44 | | -### Adapter System |
45 | | -The project uses an adapter-based architecture where each AI agent has its own adapter: |
46 | | -- **AgentAdapter interface** (`src/adapters/types.ts`) - defines the contract |
47 | | -- **Built-in adapters** - claude, cursor, windsurf, opencode, vscode |
48 | | -- **AdapterRegistry** (`src/adapters/registry.ts`) - central registry for all adapters |
49 | | -- Each adapter handles platform-specific paths, import/export, and sync strategies |
50 | | - |
51 | | -### Sync Strategies |
52 | | -- **Symlink** (default): Live sync, changes reflected immediately |
53 | | -- **Copy**: One-way copy (used for Claude to preserve cache/history) |
54 | | -- Configured per adapter in `syncStrategy.import` and `syncStrategy.export` |
55 | | - |
56 | | -### Configuration |
57 | | -- Global config stored at `~/.syncode/config.json` |
58 | | -- User's agent configs stored in their chosen repo (e.g., `~/agent-configs`) |
59 | | -- Each adapter determines its own system paths per platform |
60 | | - |
61 | | -## Code style guidelines |
62 | | - |
63 | | -### Formatting |
64 | | -- Use double quotes for strings. |
65 | | -- Use semicolons. |
66 | | -- Use trailing commas in object/array literals. |
67 | | -- One statement per line; avoid clever one-liners. |
68 | | -- Keep functions small and single-purpose. |
69 | | -- Favor explicit spacing for readability. |
70 | | - |
71 | | -### Imports |
72 | | -- Use ES module syntax (import/export, not require). |
73 | | -- Order: external packages first, then relative imports. |
74 | | -- Use `import type` for types when possible. |
75 | | -- Prefer named imports; use `import * as p` for @clack/prompts. |
76 | | - |
77 | | -### Types and interfaces |
78 | | -- Prefer interfaces for shared shapes (see `src/adapters/types.ts`). |
79 | | -- Keep union types narrow and explicit (e.g. Platform: "macos" | "linux" | "windows"). |
80 | | -- Use `Record<string, T>` for indexed dictionaries. |
81 | | -- Avoid `any`; if unavoidable, keep it local and explain with context. |
82 | | -- Keep result types consistent (`success`, `message`, optional fields). |
83 | | - |
84 | | -### Naming conventions |
85 | | -- File names are lowercase with dashes only when needed. |
86 | | -- Functions are `camelCase`. |
87 | | -- Classes/Interfaces are `PascalCase` (e.g. `AgentAdapter`, `AdapterRegistry`). |
88 | | -- Constants are `SCREAMING_SNAKE_CASE` only for true constants (e.g. `SUPPORTED_AGENTS`). |
89 | | -- Adapter IDs are lowercase (e.g. "claude", "cursor", "opencode"). |
90 | | - |
91 | | -### Error handling |
92 | | -- Use `try/catch` around filesystem and shell operations. |
93 | | -- Return structured results (success + message) rather than throwing. |
94 | | -- When catching, surface a clear message for the CLI user. |
95 | | -- In CLI flows, cancel early on prompt cancellations. |
96 | | - |
97 | | -### Async / sync usage |
98 | | -- Use async/await for shell calls and long-running operations. |
99 | | -- Synchronous fs calls are acceptable for small, controlled operations. |
100 | | -- Keep CLI output responsive; use spinners for long operations. |
101 | | - |
102 | | -### CLI UX |
103 | | -- Use @clack/prompts for interactive flows. |
104 | | -- Always handle cancellations with `p.isCancel`. |
105 | | -- Use `p.intro` / `p.outro` for command boundaries. |
106 | | -- Keep status output short and scannable. |
107 | | - |
108 | | -### Filesystem operations |
109 | | -- Use helpers from `src/utils/fs.ts` when available. |
110 | | -- Always ensure parent directories exist before writing. |
111 | | -- Respect symlink behavior: avoid overwriting without backups. |
112 | | -- For config exports, back up existing paths when not symlinked. |
113 | | - |
114 | | -### Git operations |
115 | | -- Use helpers from `src/utils/git.ts`. |
116 | | -- Prefer `git -C` with `REPO_ROOT`. |
117 | | -- Keep git output minimal and user-friendly. |
118 | | - |
119 | | -### Paths |
120 | | -- Use `systemPaths` and `repoPaths` from `src/utils/paths.ts`. |
121 | | -- Prefer `contractHome` for user-facing paths. |
122 | | -- Avoid hardcoding OS-specific locations. |
123 | | - |
124 | | -## Adding new commands |
125 | | -- Place new command files in `src/commands/`. |
126 | | -- Export a single `*Command` function (async, no parameters). |
127 | | -- Import and register in `src/index.ts` in the `commands` object. |
128 | | -- Add to the interactive menu options in the `p.select` call. |
129 | | -- Add to `showHelp()` function for CLI help output. |
130 | | - |
131 | | -## Adding new agent adapters |
132 | | -- Implement `AgentAdapter` interface from `src/adapters/types.ts`. |
133 | | -- Create new file in `src/adapters/` (e.g., `newagentagent.ts`). |
134 | | -- Export adapter instance (e.g., `export const newAgentAdapter: AgentAdapter`). |
135 | | -- Import and register in `src/adapters/registry.ts` in `registerBuiltinAdapters()`. |
136 | | -- Add agent ID to `SUPPORTED_AGENTS` in `src/config/types.ts`. |
137 | | -- Define sync strategy (symlink or copy) in adapter definition. |
138 | | -- Implement platform-specific path resolution in `getConfigPath()`. |
139 | | -- Keep import/export logic symmetric and idempotent. |
140 | | - |
141 | | -## Agent adapter behavior |
142 | | -- **Import**: Copy files from system to repo (preserves originals). |
143 | | -- **Export**: Create symlink from system to repo OR copy from repo to system. |
144 | | -- **Backup**: Always backup existing system configs before export. |
145 | | -- Avoid destructive operations without user confirmation. |
146 | | - |
147 | | -## CLI Commands |
148 | | - |
149 | | -### `syncode new` |
150 | | -- Initialize a new agent config repository |
151 | | -- Auto-detects installed AI agents |
152 | | -- Prompts for repo path, GitHub remote, agent selection |
153 | | -- Creates directory structure and initial git commit |
154 | | -- Imports existing configs from system |
155 | | -- Creates global config at `~/.syncode/config.json` |
156 | | - |
157 | | -### `syncode sync` |
158 | | -- Sync agent configs between system and repo |
159 | | -- Prompts for direction: import (system → repo) or export (repo → system) |
160 | | -- Import: copies configs from system to repo |
161 | | -- Export: creates symlinks (or copies for Claude) from system to repo |
162 | | -- Automatic backups before destructive operations |
163 | | - |
164 | | -### `syncode status` |
165 | | -- Show status of synced agents |
166 | | -- Lists enabled/detected agents |
167 | | -- Shows sync method (symlink vs copy) |
168 | | -- Shows git status of repo |
169 | | - |
170 | | -## Common pitfalls |
171 | | -- Do not use `require()` - this is an ES module project, use `import` instead. |
172 | | -- Do not assume a test runner exists. |
173 | | -- Do not add new scripts without updating this doc. |
174 | | -- Do not add emoji output unless already used in command output. |
175 | | -- Remember that adapters are registered at module load time (see registry.ts). |
176 | | -- Always use platform detection for path resolution (don't hardcode paths). |
177 | | - |
178 | | -## When editing AGENTS.md |
179 | | -- Keep it under 200 lines to stay readable. |
180 | | -- Update command sections as scripts or commands change. |
181 | | -- Document any new adapters immediately. |
182 | | -- Document any new lint/test tools immediately. |
| 3 | +Syncode is a Node.js/Bun TypeScript CLI that syncs AI agent configurations via adapter-based git + symlink/copy workflows. |
| 4 | + |
| 5 | +## Essentials |
| 6 | +- Runtime: Node.js >=20 |
| 7 | +- Package manager: npm (bun supported) |
| 8 | +- Non-standard commands: |
| 9 | + - `bun run dev` |
| 10 | + - `bun run build` |
| 11 | + - `bun run typecheck` |
| 12 | + |
| 13 | +## More details |
| 14 | +- `docs/agents/commands.md` |
| 15 | +- `docs/agents/project-structure.md` |
| 16 | +- `docs/agents/architecture.md` |
| 17 | +- `docs/agents/code-style.md` |
| 18 | +- `docs/agents/feature-development.md` |
| 19 | +- `docs/agents/troubleshooting.md` |
| 20 | +- `docs/agents/roadmap.md` |
0 commit comments