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.
- package/bin/cairn.js +5 -6
- package/lib/commands/create.js +1 -1
- package/lib/commands/doctor.js +24 -54
- package/lib/commands/onboard.js +17 -74
- package/lib/commands/update-skill.js +13 -51
- package/lib/setup/context.js +70 -0
- package/lib/setup/workspace.js +1 -1
- package/package.json +1 -1
- package/skills/agent-planning.template.md +8 -8
- package/skills/agent-skill.template.md +105 -302
- package/lib/agents/claude-code.js +0 -107
- package/lib/agents/clawdbot.js +0 -96
- package/lib/agents/cursor.js +0 -118
- package/lib/agents/detect.js +0 -60
- package/lib/agents/detect.test.js +0 -108
- package/lib/agents/generic.js +0 -62
|
@@ -1,358 +1,161 @@
|
|
|
1
|
-
# Cairn
|
|
1
|
+
# Cairn Project Management
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Workspace: `{{WORKSPACE_PATH}}`
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
Read `.cairn/planning.md` before creating any projects.
|
|
6
6
|
|
|
7
|
-
##
|
|
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
|
-
|
|
152
|
-
|
|
153
|
-
|
|
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
|
-
##
|
|
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
|
-
|
|
168
|
-
|
|
169
|
-
### Create Task
|
|
19
|
+
Always use the CLI to create entities (never create files manually):
|
|
170
20
|
|
|
171
21
|
```bash
|
|
172
|
-
|
|
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
|
-
|
|
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
|
-
|
|
30
|
+
Always pass `--description`, `--objective`, `--criteria`, and `--context` with real content. Never leave placeholders.
|
|
184
31
|
|
|
185
|
-
|
|
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
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
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
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
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
|
-
|
|
46
|
+
**Body sections:** `## Objective`, `## Why This Matters`, `## Success Criteria`, `## Context`, `## Work Log`
|
|
222
47
|
|
|
223
|
-
|
|
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
|
-
|
|
50
|
+
Tasks: `inbox`, `pending`, `next_up`, `in_progress`, `review`, `completed`, `blocked`
|
|
230
51
|
|
|
231
|
-
|
|
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
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
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
|
-
##
|
|
61
|
+
## Working on Tasks
|
|
242
62
|
|
|
243
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
253
|
-
|
|
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
|
-
|
|
256
|
-
head -20 {{WORKSPACE_PATH}}/projects/launch-app/tasks/setup-api.md
|
|
74
|
+
### While working
|
|
257
75
|
|
|
258
|
-
|
|
259
|
-
|
|
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
|
-
|
|
262
|
-
rg "^status: blocked" {{WORKSPACE_PATH}}/projects/*/tasks/*.md
|
|
263
|
-
```
|
|
80
|
+
### Finishing a task
|
|
264
81
|
|
|
265
|
-
|
|
82
|
+
When you're done working, your next status depends on **autonomy**:
|
|
266
83
|
|
|
267
|
-
|
|
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
|
-
|
|
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
|
-
|
|
89
|
+
### When you get stuck
|
|
286
90
|
|
|
287
|
-
|
|
91
|
+
If you hit a blocker (need info, access, a decision, clarification):
|
|
288
92
|
|
|
289
|
-
|
|
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
|
-
|
|
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
|
-
|
|
308
|
-
```markdown
|
|
309
|
-
## Objective
|
|
99
|
+
### Multiple tasks
|
|
310
100
|
|
|
311
|
-
|
|
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
|
-
|
|
106
|
+
### Task you didn't create
|
|
314
107
|
|
|
315
|
-
|
|
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
|
-
|
|
319
|
-
[Agent] More details
|
|
320
|
-
```
|
|
321
|
-
|
|
322
|
-
## Sync Conflicts
|
|
110
|
+
## Status Transitions
|
|
323
111
|
|
|
324
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
335
|
-
|
|
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
|
-
|
|
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
|
-
|
|
341
|
-
✅ Propose projects, wait for approval
|
|
135
|
+
## Work Log Format
|
|
342
136
|
|
|
343
|
-
|
|
344
|
-
|
|
137
|
+
```markdown
|
|
138
|
+
### YYYY-MM-DD - Description
|
|
139
|
+
[your-name] What you did
|
|
345
140
|
|
|
346
|
-
|
|
347
|
-
|
|
141
|
+
### YYYY-MM-DD - Blocked on {reason}
|
|
142
|
+
[your-name] → human: What you need
|
|
143
|
+
```
|
|
348
144
|
|
|
349
|
-
##
|
|
145
|
+
## Identity
|
|
350
146
|
|
|
351
|
-
|
|
352
|
-
-
|
|
353
|
-
-
|
|
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
|
-
**
|
|
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
|
-
}
|
package/lib/agents/clawdbot.js
DELETED
|
@@ -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
|
-
}
|