cairn-work 0.6.0 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,358 +1,161 @@
1
- # Cairn: Agent Skill
1
+ # Cairn Project Management
2
2
 
3
- You are working within Cairn, an AI-native project management platform. Cairn is the source of truth where you and your human coordinate on projects and tasks. Your work lives in markdown files at `{{WORKSPACE_PATH}}`.
3
+ Workspace: `{{WORKSPACE_PATH}}`
4
4
 
5
- Cairn is the platform, not an agent. You are the agent.
5
+ Read `.cairn/planning.md` before creating any projects.
6
6
 
7
- ## Your Identity
8
-
9
- Detect your agent name from your environment for task assignments:
10
- - **Clawdbot**: Read `IDENTITY.md` or `USER.md` in workspace, or use the configured user identity
11
- - **Other agents**: Use `$USER` environment variable, git config user.name, or ask your human
12
-
13
- Use this identity when:
14
- - Assigning yourself to tasks (`assignee: <your-name>`)
15
- - Logging work (`[<your-name>]` in log entries)
16
- - Creating new tasks with default assignee
17
-
18
- ## How Cairn Works
19
-
20
- - **Projects** = What you're trying to achieve (charter.md)
21
- - **Tasks** = Atomic work assigned to you or your human (task-name.md in tasks/ folder)
22
- - **Inbox** = Raw inputs to triage
23
-
24
- Files are the source of truth. You read and write markdown directly.
25
-
26
- ## Your Workflow
27
-
28
- ### Starting a Session
29
-
30
- 1. Check for tasks assigned to you:
31
- ```
32
- Find all task files where assignee = {your-name} AND status IN (pending, active)
33
- ```
34
-
35
- 2. Prioritize by:
36
- - Overdue first
37
- - Due today (by project priority 1→2→3)
38
- - Due this week (by project priority)
39
- - No due date (by project priority)
40
-
41
- 3. Check `{{WORKSPACE_PATH}}/inbox/` for unprocessed items
42
-
43
- ### Picking Up a Task
44
-
45
- 1. Read the task file
46
- 2. Read the parent project's `charter.md`
47
- 3. Check the `autonomy` field (or inherit from project → default `draft`)
48
-
49
- ### Autonomy Levels
50
-
51
- | Level | What to do |
52
- |-------|------------|
53
- | `propose` | Log your approach, set status to `review`, assign to human. Wait for approval. |
54
- | `draft` | Do the work, create artifacts, set status to `review`, assign to human. Don't take irreversible actions. |
55
- | `execute` | Do everything including final actions. Log completion, set status to `completed`. |
56
-
57
- ### Writing Log Entries
58
-
59
- Always append to the `## Work Log` section. Format:
60
-
61
- ```
62
- ### YYYY-MM-DD - Description
63
- [Your-name] What you did
64
- ```
65
-
66
- For handoffs to human, use arrow notation:
67
-
68
- ```
69
- ### YYYY-MM-DD - Blocked on {reason}
70
- [Your-name] → {human}: Context about what you need
71
- ```
72
-
73
- ### Status Transitions
74
-
75
- | From | To | When |
76
- |------|----|------|
77
- | `pending` | `active` | You start working |
78
- | `active` | `review` | Work complete, needs human approval |
79
- | `active` | `blocked` | You need human input to continue |
80
- | `active` | `completed` | Work complete (execute autonomy only) |
81
- | `review` | `active` | Human gives feedback, more work needed |
82
- | `review` | `completed` | Human approves |
83
- | `blocked` | `active` | Human provides input |
84
-
85
- ### Blocker Workflow (CRITICAL)
86
-
87
- **When you hit a blocker, update the file BEFORE asking questions.**
88
-
89
- This is not optional. Wrong status = miscommunication. The human monitors task status to know what needs attention. If a task shows `active` but you're actually blocked, they think you're making progress.
90
-
91
- **The sequence:**
92
-
93
- 1. **Hit a blocker** (need info, access, decision, etc.)
94
- 2. **IMMEDIATELY edit the task file:**
95
- - Change `status: active` → `status: blocked`
96
- - Add `blocker: [what you're blocked on]` to frontmatter
97
- 3. **Verify the edit worked** (`grep "status: blocked" file.md`)
98
- 4. **Log the blocker** in the Work Log section
99
- 5. **THEN ask your blocking question**
100
-
101
- **Example:**
102
-
103
- ```bash
104
- # 1. Hit blocker - need API credentials
105
-
106
- # 2. Edit file IMMEDIATELY
107
- edit(path="{{WORKSPACE_PATH}}/projects/launch-app/tasks/setup-api.md",
108
- oldText="status: active",
109
- newText="status: blocked\nblocker: Need Twitter API credentials")
110
-
111
- # 3. Verify
112
- grep "status: blocked" {{WORKSPACE_PATH}}/projects/launch-app/tasks/setup-api.md
113
-
114
- # 4. Log it (in same edit or separate)
115
- # Add to Work Log section:
116
- ### 2026-01-29 - Blocked on API credentials
117
- [pagoda] → Gregory: Need Twitter API credentials to continue setup
118
-
119
- # 5. NOW ask the question
120
- "I need Twitter API credentials to continue. Where can I find them?"
121
- ```
122
-
123
- ### Creating Artifacts
124
-
125
- When you complete significant work:
126
-
127
- 1. Save artifacts (code, docs, designs, etc.)
128
- 2. Add to frontmatter `artifacts:` array:
129
- ```yaml
130
- artifacts:
131
- - description: "API integration code"
132
- path: "./api-client.ts"
133
- created: "2026-01-29"
134
- ```
135
- 3. Log the artifact in Work Log
136
-
137
- ### Completing Tasks
138
-
139
- When task is done:
140
-
141
- 1. Set status to `completed`
142
- 2. Add completion log entry
143
- 3. Update `spend` if applicable
144
- 4. Move completed tasks to `tasks/completed/` (optional, system may do this)
145
-
146
- ## File Structure
7
+ ## Structure
147
8
 
148
9
  ```
149
10
  {{WORKSPACE_PATH}}/
150
- projects/
151
- {project-slug}/
152
- charter.md # Project overview
153
- tasks/
154
- {task-slug}.md # Individual task
155
- another-task.md
156
- completed/ # Archived completed tasks (optional)
157
- inbox/ # Unprocessed inputs
158
- _drafts/ # WIP documents
159
- _conflicts/ # Sync conflicts (multi-device)
160
- _abandoned/ # Abandoned work
11
+ projects/{slug}/charter.md # Project definition
12
+ projects/{slug}/tasks/{slug}.md # Individual tasks
13
+ inbox/ # Unprocessed inputs
14
+ _drafts/ # Work in progress
161
15
  ```
162
16
 
163
- ## Cairn CLI Helper
164
-
165
- **CRITICAL: ALWAYS use the Cairn CLI helper to create projects and tasks. NEVER create entity files manually.**
17
+ ## CLI Commands
166
18
 
167
- The CLI ensures proper structure, slugification, and frontmatter.
168
-
169
- ### Create Task
19
+ Always use the CLI to create entities (never create files manually):
170
20
 
171
21
  ```bash
172
- {{WORKSPACE_ROOT}}/cairn-cli/bin/cairn.js create task "Task Title" --project <project-slug> [options]
22
+ cairn create project "Name" --description "..." --objective "..." --criteria "..." --context "..." --due YYYY-MM-DD
23
+ cairn create task "Name" --project <slug> --description "..." --objective "..." --assignee <name> --due YYYY-MM-DD
24
+ cairn doctor # Check workspace health
25
+ cairn update-skill # Refresh this file
173
26
  ```
174
27
 
175
- Options:
176
- - `--project <slug>` - Project slug (REQUIRED)
177
- - `--assignee <name>` - Who's responsible (default: human)
178
- - `--description "text"` - Task description
179
- - `--objective "text"` - What needs to be accomplished
180
- - `--status <status>` - Initial status (default: pending)
181
- - `--due YYYY-MM-DD` - Due date
28
+ Tasks are created with `status: pending` by default. Do NOT pass `--status` unless the user explicitly asks you to begin work immediately (in which case use `--status next_up`).
182
29
 
183
- **IMPORTANT:** Always pass `--description` and `--objective` with real content. If you omit them, the file will have empty sections. Write specific, actionable text — never placeholder text like "[Describe what needs to be accomplished]".
30
+ Always pass `--description`, `--objective`, `--criteria`, and `--context` with real content. Never leave placeholders.
184
31
 
185
- Example:
186
- ```bash
187
- cairn create task "Set up CI pipeline" \\
188
- --project launch-app \\
189
- --assignee pagoda \\
190
- --description "Configure GitHub Actions for automated testing" \\
191
- --objective "Set up a CI pipeline that runs lint, typecheck, and tests on every PR. Use GitHub Actions with a Node.js matrix for v18 and v20. Cache node_modules for faster runs." \\
192
- --due 2026-02-01
193
- ```
32
+ ## File Format
194
33
 
195
- ### Create Project
196
-
197
- ```bash
198
- {{WORKSPACE_ROOT}}/cairn-cli/bin/cairn.js create project "Project Title" [options]
34
+ **Charter frontmatter:**
35
+ ```yaml
36
+ title, description, status (in_progress|paused|completed), priority (1-3),
37
+ created, due, owner, default_autonomy (propose|draft|execute), budget, spent
199
38
  ```
200
39
 
201
- Options:
202
- - `--description "text"` - Project description
203
- - `--objective "text"` - Why this matters
204
- - `--criteria "text"` - Success criteria
205
- - `--context "text"` - Background, constraints, or dependencies
206
- - `--due YYYY-MM-DD` - Project deadline
207
- - `--assignee <name>` - Project owner
208
-
209
- **IMPORTANT:** Always pass `--description`, `--objective`, `--criteria`, and `--context` with real content. Write thoughtful, specific text for each — these sections drive the entire project. After creating the project, read the charter and fill in anything that still needs detail.
210
-
211
- Example:
212
- ```bash
213
- cairn create project "Launch Mobile App" \\
214
- --description "Ship iOS and Android app by Q2" \\
215
- --objective "We need a mobile app to reach users who primarily use phones. The web app has 60% mobile traffic but poor mobile UX." \\
216
- --criteria "App published to App Store and Play Store. Supports login, dashboard, and notifications. 4+ star rating in first month." \\
217
- --context "Using React Native for cross-platform. Backend API already exists. Design mockups in Figma." \\
218
- --due 2026-06-30
40
+ **Task frontmatter:**
41
+ ```yaml
42
+ title, description, assignee, status (pending|next_up|in_progress|review|completed|blocked),
43
+ created, due, autonomy (propose|draft|execute), spend, artifacts, blocker
219
44
  ```
220
45
 
221
- ## Operating Principles
46
+ **Body sections:** `## Objective`, `## Why This Matters`, `## Success Criteria`, `## Context`, `## Work Log`
222
47
 
223
- 1. **Always check status before starting work** - Don't start tasks already in progress
224
- 2. **Update status when blocked IMMEDIATELY** - Don't let human think you're making progress when you're stuck
225
- 3. **Log all significant work** - Future-you (or another agent) will need context
226
- 4. **Never auto-create projects** - Always propose new projects to human first
227
- 5. **Use CLI for entity creation** - Don't hand-craft YAML
48
+ ## Valid Statuses
228
49
 
229
- ### When To Propose Projects
50
+ Tasks: `inbox`, `pending`, `next_up`, `in_progress`, `review`, `completed`, `blocked`
230
51
 
231
- - Notice something untracked "Should this be a project?"
232
- - Gap in coverage → "You have projects for X and Y, but nothing for Z"
233
- - Task complete → "What's next for this project?"
52
+ There is NO `active` status. Never use `active` use `in_progress` when working, `next_up` for queued work.
234
53
 
235
- Example:
236
- ```
237
- I noticed you've been working on API docs in several tasks.
238
- Should we create a project for "Documentation Infrastructure"?
239
- ```
54
+ - **pending** — Default. Task exists but is not ready to start yet.
55
+ - **next_up** — Queued and ready to be picked up.
56
+ - **in_progress** Currently being worked on.
57
+ - **review** Work complete, waiting for human approval.
58
+ - **blocked** — Cannot proceed, needs human input.
59
+ - **completed** — Done.
240
60
 
241
- ## Reading Task Files
61
+ ## Working on Tasks
242
62
 
243
- Use efficient tools:
63
+ Task files are a shared kanban board between you and the human. Status is how you communicate progress. The human sees the board and knows exactly where everything stands. You are accountable for keeping it accurate.
244
64
 
245
- ```bash
246
- # Find all tasks for a project
247
- ls -1 {{WORKSPACE_PATH}}/projects/launch-app/tasks/*.md
65
+ ### Picking up a task
248
66
 
249
- # Find your assigned tasks
250
- rg "^assignee: pagoda" {{WORKSPACE_PATH}}/projects/*/tasks/*.md
67
+ When the human asks you to work on a task (e.g. "work on task X", "start the API integration"):
251
68
 
252
- # Check task status
253
- grep "^status:" {{WORKSPACE_PATH}}/projects/launch-app/tasks/setup-api.md
69
+ 1. **Read the task file** — understand the objective
70
+ 2. **Read the parent charter** — understand the project context and autonomy level
71
+ 3. **Set status to `in_progress`** — do this BEFORE you start any work
72
+ 4. **Log it** — add a Work Log entry: `[name] Starting work on this task`
254
73
 
255
- # Read task frontmatter (first 20 lines usually enough)
256
- head -20 {{WORKSPACE_PATH}}/projects/launch-app/tasks/setup-api.md
74
+ ### While working
257
75
 
258
- # Search task descriptions
259
- rg "^description:" {{WORKSPACE_PATH}}/projects/*/tasks/*.md
76
+ As you work, keep the task file updated:
77
+ - **Log significant progress** in the Work Log section
78
+ - **Add artifacts** to the frontmatter as you create them (code files, docs, configs)
260
79
 
261
- # Find blocked tasks
262
- rg "^status: blocked" {{WORKSPACE_PATH}}/projects/*/tasks/*.md
263
- ```
80
+ ### Finishing a task
264
81
 
265
- ## Project Charters
82
+ When you're done working, your next status depends on **autonomy**:
266
83
 
267
- Charters define project goals, constraints, and success criteria.
84
+ - **`propose` or `draft` autonomy** set status to **`review`**. The human decides if it's complete.
85
+ - **`execute` autonomy** → set status to **`completed`**. You have full authority.
268
86
 
269
- **Frontmatter:**
270
- ```yaml
271
- ---
272
- title: Project Name
273
- description: Brief summary
274
- status: active | paused | completed
275
- priority: 1 | 2 | 3 (1 = highest)
276
- created: YYYY-MM-DD
277
- due: YYYY-MM-DD
278
- owner: name
279
- default_autonomy: draft | propose | execute
280
- budget: 100 (or "unlimited")
281
- spent: 0
282
- ---
283
- ```
87
+ Always add a completion log entry describing what you did and what the human should look at.
284
88
 
285
- **Budget check:** If project budget ≠ `unlimited` AND spent > 80% of budget, note this in your response to the human.
89
+ ### When you get stuck
286
90
 
287
- ## Task Files
91
+ If you hit a blocker (need info, access, a decision, clarification):
288
92
 
289
- Tasks are atomic units of work.
93
+ 1. **Set status to `blocked`** and add `blocker: [reason]` to frontmatter — do this FIRST
94
+ 2. **Log it** — `[name] → human: What you need`
95
+ 3. **Then ask your question**
290
96
 
291
- **Frontmatter:**
292
- ```yaml
293
- ---
294
- title: Task Name
295
- description: What this task accomplishes
296
- assignee: name
297
- status: pending | active | blocked | review | completed
298
- created: YYYY-MM-DD
299
- due: YYYY-MM-DD
300
- autonomy: draft | propose | execute
301
- spend: 0
302
- artifacts: []
303
- blocker: "Reason (only when status: blocked)"
304
- ---
305
- ```
97
+ Never leave a task as `in_progress` while you're actually waiting on the human. Wrong status = the human thinks you're making progress when you're not.
306
98
 
307
- **Body sections:**
308
- ```markdown
309
- ## Objective
99
+ ### Multiple tasks
310
100
 
311
- What needs to be accomplished and why.
101
+ If the human asks you to work through several tasks in sequence:
102
+ - Move each task to `in_progress` as you start it
103
+ - Move it to the correct finish status (`review` or `completed`) before starting the next one
104
+ - Don't leave multiple tasks as `in_progress` simultaneously unless you're genuinely working on them in parallel
312
105
 
313
- ## Work Log
106
+ ### Task you didn't create
314
107
 
315
- ### YYYY-MM-DD - Event
316
- [Agent/human] Description of work or update
108
+ The human may move tasks to `in_progress` or `next_up` from the kanban board and then ask you to pick them up. Always read the task file and charter before starting — don't assume you know what's needed.
317
109
 
318
- ### YYYY-MM-DD - Another event
319
- [Agent] More details
320
- ```
321
-
322
- ## Sync Conflicts
110
+ ## Status Transitions
323
111
 
324
- If using multi-device sync (Obsidian Sync, Dropbox, etc.), conflicts may appear in `_conflicts/`.
112
+ | From | To | When |
113
+ |------|----|------|
114
+ | pending | next_up | Task is ready to be worked on |
115
+ | next_up | in_progress | You start working |
116
+ | in_progress | review | Work done, needs human approval (draft/propose autonomy) |
117
+ | in_progress | blocked | You need human input |
118
+ | in_progress | completed | Done (execute autonomy ONLY) |
119
+ | review | in_progress | Human gives feedback, more work needed |
120
+ | review | completed | Human approves |
121
+ | blocked | in_progress | Human provides input |
325
122
 
326
- When you see a conflict:
327
- 1. Read both versions
328
- 2. Merge important changes
329
- 3. Write merged version back to original location
330
- 4. Delete conflict file
123
+ ## Autonomy Levels (CRITICAL — always respect these)
331
124
 
332
- ## Common Mistakes
125
+ Check the task's `autonomy` field (or inherit from parent project's `default_autonomy`). This controls what you may do and what status you set when finished:
333
126
 
334
- 1. Creating task files manually (missing proper frontmatter)
335
- ✅ Use `cairn create task`
127
+ | Level | What you do | Final status |
128
+ |-------|-------------|-------------|
129
+ | **propose** | Log your planned approach. Do NOT do the work. | → `review` |
130
+ | **draft** | Do the work and create artifacts. Do NOT take irreversible actions (deploy, publish, send, delete). | → `review` |
131
+ | **execute** | Do everything including irreversible actions. | → `completed` |
336
132
 
337
- 2. Asking blocking questions while status = active
338
- ✅ Edit status to blocked FIRST, then ask
133
+ **You MUST follow autonomy.** If autonomy is `draft`, you cannot set status to `completed` — you MUST set it to `review` and let the human approve. Only `execute` autonomy permits moving directly to `completed`.
339
134
 
340
- 3. Auto-creating projects without human approval
341
- ✅ Propose projects, wait for approval
135
+ ## Work Log Format
342
136
 
343
- 4. ❌ Forgetting to log work
344
- Add Work Log entry for all significant changes
137
+ ```markdown
138
+ ### YYYY-MM-DD - Description
139
+ [your-name] What you did
345
140
 
346
- 5. Not verifying file edits
347
- grep/cat to confirm changes applied
141
+ ### YYYY-MM-DD - Blocked on {reason}
142
+ [your-name] human: What you need
143
+ ```
348
144
 
349
- ## Integration Notes
145
+ ## Identity
350
146
 
351
- - **Clawdbot**: Full integration, skill auto-loads
352
- - **Claude Code**: Add as workspace context
353
- - **Cursor**: Reads from .cursor/ or workspace context
354
- - **Other agents**: Include as system context
147
+ Detect your name from environment (`$USER`, git config, or ask). Use it for:
148
+ - `assignee:` in task frontmatter
149
+ - `[name]` in work log entries
355
150
 
356
- ---
151
+ ## Operating Principles
357
152
 
358
- **Remember:** You're a team member, not a tool. Treat the workspace like shared docs between collaborators. Be proactive, communicate clearly, and always keep files updated.
153
+ 1. **Status is communication** the human reads the board to know what needs attention. Keep it accurate at all times.
154
+ 2. **Move to `in_progress` when you start** — never work on a task without claiming it first.
155
+ 3. **Move to `blocked` IMMEDIATELY when stuck** — never leave it as `in_progress` while waiting for the human.
156
+ 4. **Respect autonomy** — `draft`/`propose` → `review`, only `execute` → `completed`.
157
+ 5. **Log all significant work** with timestamps so there's a clear trail of what happened.
158
+ 6. **Never auto-create projects** — propose to human first.
159
+ 7. **Use CLI for entity creation** — don't hand-craft YAML.
160
+ 8. **After creating a project**, fill in ALL charter sections with real content.
161
+ 9. **Budget check** — if spent > 80% of budget, notify human.
@@ -1,107 +0,0 @@
1
- import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'fs';
2
- import { join, dirname } from 'path';
3
- import { fileURLToPath } from 'url';
4
- import chalk from 'chalk';
5
-
6
- const __filename = fileURLToPath(import.meta.url);
7
- const __dirname = dirname(__filename);
8
-
9
- /**
10
- * Set up Cairn for Claude Code
11
- * Adds agent-skill.md to workspace context
12
- */
13
- export async function setupClaudeCode(workspacePath) {
14
- const cwd = process.cwd();
15
- const contextDir = join(cwd, '.claude-code');
16
- const skillTemplate = join(__dirname, '../../skills/agent-skill.template.md');
17
- const skillDest = join(contextDir, 'cairn-skill.md');
18
-
19
- // Create context directory
20
- if (!existsSync(contextDir)) {
21
- mkdirSync(contextDir, { recursive: true });
22
- }
23
-
24
- // Read template and replace workspace placeholders
25
- let skillContent = readFileSync(skillTemplate, 'utf-8');
26
- const workspaceRoot = dirname(workspacePath);
27
-
28
- skillContent = skillContent
29
- .replace(/\{\{WORKSPACE_PATH\}\}/g, workspacePath)
30
- .replace(/\{\{WORKSPACE_ROOT\}\}/g, workspaceRoot);
31
-
32
- // Write skill to workspace
33
- writeFileSync(skillDest, skillContent);
34
- console.log(chalk.green('✓'), 'Cairn skill added to Claude Code workspace');
35
-
36
- // Read planning template and replace placeholders
37
- const planningTemplate = join(__dirname, '../../skills/agent-planning.template.md');
38
- let planningContent = readFileSync(planningTemplate, 'utf-8');
39
- planningContent = planningContent
40
- .replace(/\{\{WORKSPACE_PATH\}\}/g, workspacePath)
41
- .replace(/\{\{WORKSPACE_ROOT\}\}/g, workspaceRoot);
42
-
43
- const planningDest = join(contextDir, 'cairn-planning.md');
44
- writeFileSync(planningDest, planningContent);
45
- console.log(chalk.green('✓'), 'Cairn planning guide added to Claude Code workspace');
46
-
47
- // Create instructions file
48
- const instructionsPath = join(contextDir, 'cairn-instructions.md');
49
- const instructions = `# Cairn Project Management
50
-
51
- This workspace uses Cairn for project management.
52
-
53
- **Workspace:** ${workspacePath}
54
-
55
- ## Agent Documentation
56
-
57
- Read BOTH files in this directory:
58
- - **cairn-skill.md** — Operations: status transitions, autonomy levels, blocker workflow, file format
59
- - **cairn-planning.md** — Planning: how to create projects, break down tasks, write real content, examples
60
-
61
- **Key points:**
62
- - All project files are in markdown format at ${workspacePath}
63
- - Files are the source of truth (no database)
64
- - Follow the project → task hierarchy
65
- - Always update status before asking blocking questions
66
- - Log all work in the Work Log section
67
- - When creating projects, fill in ALL sections with real content (never leave placeholder text)
68
-
69
- Read both skill files before working with Cairn.
70
- `;
71
-
72
- writeFileSync(instructionsPath, instructions);
73
- console.log(chalk.green('✓'), 'Cairn instructions added');
74
-
75
- return true;
76
- }
77
-
78
- /**
79
- * Get setup instructions for Claude Code
80
- */
81
- export function getClaudeCodeInstructions(workspacePath) {
82
- return `
83
- ${chalk.bold('Claude Code Setup Complete!')}
84
-
85
- Your Cairn workspace: ${chalk.cyan(workspacePath)}
86
- Context added at: ${chalk.cyan('.claude-code/')}
87
-
88
- ${chalk.bold('Test it:')}
89
- Ask Claude Code:
90
- ${chalk.yellow('"Read .claude-code/cairn-skill.md and help me create a project"')}
91
-
92
- ${chalk.dim('Note: You may need to reload the workspace for changes to take effect.')}
93
- `;
94
- }
95
-
96
- /**
97
- * Verify Claude Code setup
98
- */
99
- export function verifyClaudeCode() {
100
- const contextPath = join(process.cwd(), '.claude-code', 'cairn-skill.md');
101
-
102
- if (!existsSync(contextPath)) {
103
- return { success: false, message: 'Cairn skill not found in workspace' };
104
- }
105
-
106
- return { success: true, message: 'Claude Code setup verified' };
107
- }
@@ -1,96 +0,0 @@
1
- import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'fs';
2
- import { homedir } from 'os';
3
- import { join, dirname } from 'path';
4
- import { fileURLToPath } from 'url';
5
- import chalk from 'chalk';
6
-
7
- const __filename = fileURLToPath(import.meta.url);
8
- const __dirname = dirname(__filename);
9
-
10
- /**
11
- * Set up Cairn for Clawdbot
12
- * Installs skill file from template (agent detects its own identity)
13
- */
14
- export async function setupClawdbot(workspacePath) {
15
- const clawdbotSkillsDir = join(homedir(), '.clawdbot', 'skills', 'cairn');
16
- const skillTemplate = join(__dirname, '../../skills/agent-skill.template.md');
17
- const skillDest = join(clawdbotSkillsDir, 'SKILL.md');
18
-
19
- // Create skills directory if it doesn't exist
20
- if (!existsSync(clawdbotSkillsDir)) {
21
- mkdirSync(clawdbotSkillsDir, { recursive: true });
22
- }
23
-
24
- // Read template and replace workspace placeholders only
25
- let skillContent = readFileSync(skillTemplate, 'utf-8');
26
-
27
- // Determine workspace root (parent of workspace path, e.g., /home/user from /home/user/cairn)
28
- const workspaceRoot = dirname(workspacePath);
29
-
30
- // Replace workspace placeholders (agent will detect its own name)
31
- skillContent = skillContent
32
- .replace(/\{\{WORKSPACE_PATH\}\}/g, workspacePath)
33
- .replace(/\{\{WORKSPACE_ROOT\}\}/g, workspaceRoot);
34
-
35
- // Write skill file
36
- writeFileSync(skillDest, skillContent);
37
- console.log(chalk.green('✓'), 'Cairn skill added to Clawdbot');
38
-
39
- // Read planning template and replace placeholders
40
- const planningTemplate = join(__dirname, '../../skills/agent-planning.template.md');
41
- let planningContent = readFileSync(planningTemplate, 'utf-8');
42
- planningContent = planningContent
43
- .replace(/\{\{WORKSPACE_PATH\}\}/g, workspacePath)
44
- .replace(/\{\{WORKSPACE_ROOT\}\}/g, workspaceRoot);
45
-
46
- const planningDest = join(clawdbotSkillsDir, 'PLANNING.md');
47
- writeFileSync(planningDest, planningContent);
48
- console.log(chalk.green('✓'), 'Cairn planning guide added to Clawdbot');
49
-
50
- // Create a config file with workspace path
51
- const configPath = join(clawdbotSkillsDir, 'config.json');
52
- const config = {
53
- workspacePath,
54
- version: '0.1.0',
55
- installedAt: new Date().toISOString()
56
- };
57
- writeFileSync(configPath, JSON.stringify(config, null, 2));
58
-
59
- return true;
60
- }
61
-
62
- /**
63
- * Get setup instructions for Clawdbot
64
- */
65
- export function getClawdbotInstructions(workspacePath) {
66
- return `
67
- ${chalk.bold('Clawdbot Setup Complete!')}
68
-
69
- Your Cairn workspace: ${chalk.cyan(workspacePath)}
70
- Skill installed at: ${chalk.cyan('~/.clawdbot/skills/cairn/')}
71
-
72
- ${chalk.bold('Test it:')}
73
- In your next Clawdbot session, try:
74
- ${chalk.yellow('"Help me create a project called Launch My App"')}
75
-
76
- The skill will be automatically available in new sessions.
77
- `;
78
- }
79
-
80
- /**
81
- * Verify Clawdbot setup
82
- */
83
- export function verifyClawdbot() {
84
- const clawdbotPath = join(homedir(), '.clawdbot');
85
- const skillPath = join(clawdbotPath, 'skills', 'cairn', 'SKILL.md');
86
-
87
- if (!existsSync(clawdbotPath)) {
88
- return { success: false, message: 'Clawdbot directory not found' };
89
- }
90
-
91
- if (!existsSync(skillPath)) {
92
- return { success: false, message: 'Cairn skill not installed' };
93
- }
94
-
95
- return { success: true, message: 'Clawdbot setup verified' };
96
- }