@chief-clancy/brief 0.1.1 → 0.2.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/README.md +20 -10
- package/bin/brief.js +41 -24
- package/dist/installer/install.d.ts.map +1 -1
- package/dist/installer/install.js +10 -2
- package/dist/installer/install.js.map +1 -1
- package/package.json +1 -1
- package/src/commands/approve-brief.md +23 -0
- package/src/commands/board-setup.md +11 -0
- package/src/commands/brief.md +1 -1
- package/src/commands/commands.test.ts +10 -1
- package/src/workflows/approve-brief.md +1540 -0
- package/src/workflows/board-setup.md +370 -0
- package/src/workflows/brief.md +21 -13
- package/src/workflows/workflows.test.ts +106 -10
|
@@ -0,0 +1,370 @@
|
|
|
1
|
+
# Board Setup Workflow
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
|
|
5
|
+
Configure board credentials so `/clancy:brief` can fetch tickets and post briefs as comments. This workflow collects the minimum credentials needed for board access — no pipeline configuration, no role settings, no iteration limits.
|
|
6
|
+
|
|
7
|
+
Credentials are stored in `.clancy/.env` in the current project directory. They are per-project, not global.
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
## Step 1 — Preflight checks
|
|
12
|
+
|
|
13
|
+
### 1. Check for full pipeline
|
|
14
|
+
|
|
15
|
+
Check if `.clancy/clancy-implement.js` exists in the project root.
|
|
16
|
+
|
|
17
|
+
If present, the full Clancy pipeline is installed. Show:
|
|
18
|
+
|
|
19
|
+
```
|
|
20
|
+
Full Clancy pipeline detected. Use /clancy:settings to manage board credentials.
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
Stop. Do not proceed with standalone board setup.
|
|
24
|
+
|
|
25
|
+
### 2. Check for existing credentials
|
|
26
|
+
|
|
27
|
+
Check if `.clancy/.env` exists and contains board credentials (any of: `JIRA_BASE_URL`, `GITHUB_TOKEN`, `LINEAR_API_KEY`, `SHORTCUT_API_TOKEN`, `NOTION_TOKEN`, `AZDO_ORG`, `AZDO_PAT`, `AZDO_PROJECT`).
|
|
28
|
+
|
|
29
|
+
If board credentials are found, show:
|
|
30
|
+
|
|
31
|
+
```
|
|
32
|
+
Existing board credentials found in .clancy/.env.
|
|
33
|
+
|
|
34
|
+
[1] Reconfigure (replace current board)
|
|
35
|
+
[2] Cancel
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
If [2]: stop.
|
|
39
|
+
If [1]: continue to Step 2. The existing `.clancy/.env` will be updated (board-specific vars replaced, other vars preserved).
|
|
40
|
+
|
|
41
|
+
If `.clancy/.env` does not exist, or exists but has no board credentials: continue to Step 2.
|
|
42
|
+
|
|
43
|
+
---
|
|
44
|
+
|
|
45
|
+
## Step 2 — Board selection
|
|
46
|
+
|
|
47
|
+
Output:
|
|
48
|
+
|
|
49
|
+
```
|
|
50
|
+
Which board are you using?
|
|
51
|
+
|
|
52
|
+
[1] Jira
|
|
53
|
+
[2] GitHub Issues
|
|
54
|
+
[3] Linear
|
|
55
|
+
[4] Shortcut
|
|
56
|
+
[5] Notion
|
|
57
|
+
[6] Azure DevOps
|
|
58
|
+
[7] My board isn't listed
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
If the user selects [7], show:
|
|
62
|
+
|
|
63
|
+
```
|
|
64
|
+
Clancy currently supports Jira, GitHub Issues, Linear, Shortcut, Notion, and Azure DevOps.
|
|
65
|
+
|
|
66
|
+
Your board isn't supported yet — open an issue:
|
|
67
|
+
github.com/Pushedskydiver/chief-clancy/issues
|
|
68
|
+
|
|
69
|
+
You can still use /clancy:brief with inline text or file input:
|
|
70
|
+
/clancy:brief "Add dark mode support"
|
|
71
|
+
/clancy:brief --from docs/rfc.md
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
Stop.
|
|
75
|
+
|
|
76
|
+
---
|
|
77
|
+
|
|
78
|
+
## Step 3 — Credential collection
|
|
79
|
+
|
|
80
|
+
Ask each question individually and wait for an answer before moving to the next.
|
|
81
|
+
|
|
82
|
+
### Jira
|
|
83
|
+
|
|
84
|
+
1. `What's your Jira base URL? (e.g. https://your-org.atlassian.net)`
|
|
85
|
+
2. `What's your Jira project key? (e.g. PROJ)`
|
|
86
|
+
3. `What email address do you use to log in to Atlassian?`
|
|
87
|
+
4. `Paste your Jira API token: (create one at id.atlassian.com/manage-profile/security/api-tokens)`
|
|
88
|
+
|
|
89
|
+
Store as `JIRA_BASE_URL`, `JIRA_PROJECT_KEY`, `JIRA_USER`, `JIRA_API_TOKEN`.
|
|
90
|
+
|
|
91
|
+
### GitHub Issues
|
|
92
|
+
|
|
93
|
+
1. `What's your GitHub repo? (owner/name, e.g. acme/my-app)`
|
|
94
|
+
2. `Paste your GitHub personal access token: (needs repo scope)`
|
|
95
|
+
|
|
96
|
+
Store as `GITHUB_REPO`, `GITHUB_TOKEN`.
|
|
97
|
+
|
|
98
|
+
After collecting credentials, show:
|
|
99
|
+
|
|
100
|
+
```
|
|
101
|
+
Note: Clancy only picks up GitHub Issues that have the "clancy" label applied.
|
|
102
|
+
Add this label to any issue you want Clancy to brief.
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
### Linear
|
|
106
|
+
|
|
107
|
+
1. `Paste your Linear API key: (create one at linear.app/settings/api)`
|
|
108
|
+
2. After verifying the API key (Step 4), auto-detect teams by querying `{ teams { nodes { id name } } }`.
|
|
109
|
+
- If exactly 1 team: use it automatically. Show `Using team: {name} ({id})`.
|
|
110
|
+
- If 2+ teams: show a numbered list and let the user pick.
|
|
111
|
+
- If the query fails or returns no teams: fall back to asking manually: `What's your Linear team ID? (find it at linear.app/settings/teams — click your team, copy the ID from the URL)`
|
|
112
|
+
|
|
113
|
+
Store as `LINEAR_API_KEY`, `LINEAR_TEAM_ID`.
|
|
114
|
+
|
|
115
|
+
### Shortcut
|
|
116
|
+
|
|
117
|
+
1. `Paste your Shortcut API token: (create one at app.shortcut.com/settings/account/api-tokens)`
|
|
118
|
+
|
|
119
|
+
Store as `SHORTCUT_API_TOKEN`.
|
|
120
|
+
|
|
121
|
+
### Notion
|
|
122
|
+
|
|
123
|
+
1. `Paste your Notion integration token: (create one at notion.so/my-integrations)`
|
|
124
|
+
2. `What's your Notion database ID? (the 32-character hex string in your database URL)`
|
|
125
|
+
|
|
126
|
+
Store as `NOTION_TOKEN`, `NOTION_DATABASE_ID`.
|
|
127
|
+
|
|
128
|
+
### Azure DevOps
|
|
129
|
+
|
|
130
|
+
1. `What's your Azure DevOps organisation name? (e.g. your-org)`
|
|
131
|
+
2. `What's your Azure DevOps project name?`
|
|
132
|
+
3. `Paste your Azure DevOps personal access token: (needs Work Items Read & Write scope)`
|
|
133
|
+
|
|
134
|
+
Store as `AZDO_ORG`, `AZDO_PROJECT`, `AZDO_PAT`.
|
|
135
|
+
|
|
136
|
+
---
|
|
137
|
+
|
|
138
|
+
## Step 4 — Credential verification
|
|
139
|
+
|
|
140
|
+
After collecting all credentials for the chosen board, verify the connection before writing them.
|
|
141
|
+
|
|
142
|
+
### Jira
|
|
143
|
+
|
|
144
|
+
Call `GET {JIRA_BASE_URL}/rest/api/3/project/{JIRA_PROJECT_KEY}` with basic auth (`{JIRA_USER}:{JIRA_API_TOKEN}` base64-encoded in the `Authorization: Basic` header).
|
|
145
|
+
|
|
146
|
+
On success (HTTP 200):
|
|
147
|
+
|
|
148
|
+
```
|
|
149
|
+
✅ Jira connected — project {JIRA_PROJECT_KEY} reachable.
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
### GitHub Issues
|
|
153
|
+
|
|
154
|
+
Call `GET https://api.github.com/repos/{GITHUB_REPO}` with `Authorization: Bearer {GITHUB_TOKEN}` and `X-GitHub-Api-Version: 2022-11-28`.
|
|
155
|
+
|
|
156
|
+
On success (HTTP 200):
|
|
157
|
+
|
|
158
|
+
```
|
|
159
|
+
✅ GitHub connected — {GITHUB_REPO} reachable.
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
### Linear
|
|
163
|
+
|
|
164
|
+
Call `POST https://api.linear.app/graphql` with `Authorization: {LINEAR_API_KEY}` (no Bearer prefix) and body `{"query": "{ viewer { id name } }"}`.
|
|
165
|
+
|
|
166
|
+
On success (HTTP 200 with `data.viewer`):
|
|
167
|
+
|
|
168
|
+
```
|
|
169
|
+
✅ Linear connected — {viewer.name}.
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
### Shortcut
|
|
173
|
+
|
|
174
|
+
Call `GET https://api.app.shortcut.com/api/v3/member-info` with `Shortcut-Token: {SHORTCUT_API_TOKEN}`.
|
|
175
|
+
|
|
176
|
+
On success (HTTP 200):
|
|
177
|
+
|
|
178
|
+
```
|
|
179
|
+
✅ Shortcut connected.
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
### Notion
|
|
183
|
+
|
|
184
|
+
Call `GET https://api.notion.com/v1/databases/{NOTION_DATABASE_ID}` with `Authorization: Bearer {NOTION_TOKEN}` and `Notion-Version: 2022-06-28`.
|
|
185
|
+
|
|
186
|
+
On success (HTTP 200):
|
|
187
|
+
|
|
188
|
+
```
|
|
189
|
+
✅ Notion connected — database reachable.
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
### Azure DevOps
|
|
193
|
+
|
|
194
|
+
Call `GET https://dev.azure.com/{AZDO_ORG}/{AZDO_PROJECT}/_apis/wit/workitemtypes?api-version=7.1` with basic auth (empty user, `AZDO_PAT` as password).
|
|
195
|
+
|
|
196
|
+
On success (HTTP 200):
|
|
197
|
+
|
|
198
|
+
```
|
|
199
|
+
✅ Azure DevOps connected — {AZDO_PROJECT} reachable.
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
### On failure (any board)
|
|
203
|
+
|
|
204
|
+
```
|
|
205
|
+
❌ Couldn't connect to {board} (HTTP {status}).
|
|
206
|
+
Check your credentials.
|
|
207
|
+
|
|
208
|
+
[1] Re-enter credentials
|
|
209
|
+
[2] Skip verification (save anyway)
|
|
210
|
+
[3] Cancel
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
If [1]: go back to Step 3 for that board.
|
|
214
|
+
If [2]: save the unverified credentials and continue to Step 5.
|
|
215
|
+
If [3]: stop without saving.
|
|
216
|
+
|
|
217
|
+
Never silently continue with unverified credentials — the user must explicitly choose.
|
|
218
|
+
|
|
219
|
+
---
|
|
220
|
+
|
|
221
|
+
## Step 5 — Detect base branch
|
|
222
|
+
|
|
223
|
+
Auto-detect the default branch:
|
|
224
|
+
|
|
225
|
+
```bash
|
|
226
|
+
BASE_BRANCH_REF="$(git symbolic-ref refs/remotes/origin/HEAD 2>/dev/null)"
|
|
227
|
+
echo "${BASE_BRANCH_REF#refs/remotes/origin/}"
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
If detection succeeds and the branch is `main` or `master`: use it silently. Store as `CLANCY_BASE_BRANCH`.
|
|
231
|
+
|
|
232
|
+
If detection fails or returns an unexpected branch name, ask:
|
|
233
|
+
|
|
234
|
+
```
|
|
235
|
+
What's your base branch? [main]
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
---
|
|
239
|
+
|
|
240
|
+
## Step 6 — Write credentials
|
|
241
|
+
|
|
242
|
+
### Create directory
|
|
243
|
+
|
|
244
|
+
Create `.clancy/` directory if it does not exist.
|
|
245
|
+
|
|
246
|
+
### Write `.clancy/.env`
|
|
247
|
+
|
|
248
|
+
If `.clancy/.env` already exists (reconfigure path from Step 1, or exists with no board credentials):
|
|
249
|
+
|
|
250
|
+
- Preserve all existing lines (comments, blank lines, non-board vars)
|
|
251
|
+
- Remove any existing board-specific env vars for ALL boards (not just the new one). Board vars to remove:
|
|
252
|
+
- Jira: `JIRA_BASE_URL`, `JIRA_PROJECT_KEY`, `JIRA_USER`, `JIRA_API_TOKEN`, `CLANCY_JQL_STATUS`, `CLANCY_JQL_SPRINT`
|
|
253
|
+
- GitHub: `GITHUB_REPO`, `GITHUB_TOKEN`
|
|
254
|
+
- Linear: `LINEAR_API_KEY`, `LINEAR_TEAM_ID`
|
|
255
|
+
- Shortcut: `SHORTCUT_API_TOKEN`, `SHORTCUT_WORKFLOW`
|
|
256
|
+
- Notion: `NOTION_TOKEN`, `NOTION_DATABASE_ID`, `CLANCY_NOTION_STATUS`, `CLANCY_NOTION_ASSIGNEE`, `CLANCY_NOTION_LABELS`, `CLANCY_NOTION_PARENT`, `CLANCY_NOTION_TODO`
|
|
257
|
+
- Azure DevOps: `AZDO_ORG`, `AZDO_PROJECT`, `AZDO_PAT`, `CLANCY_AZDO_WIT`, `CLANCY_AZDO_STATUS`
|
|
258
|
+
- Preserve all other lines (comments, blank lines, non-board vars like `CLANCY_BASE_BRANCH`)
|
|
259
|
+
- Append the new board's credentials at the end
|
|
260
|
+
- Update `CLANCY_BASE_BRANCH` if it exists, or append it
|
|
261
|
+
|
|
262
|
+
If `.clancy/.env` does not exist, write a new file:
|
|
263
|
+
|
|
264
|
+
```
|
|
265
|
+
# Clancy — Board credentials
|
|
266
|
+
# Configured by @chief-clancy/brief
|
|
267
|
+
# Do not commit this file to version control.
|
|
268
|
+
|
|
269
|
+
{BOARD_CREDENTIALS}
|
|
270
|
+
|
|
271
|
+
CLANCY_BASE_BRANCH={branch}
|
|
272
|
+
```
|
|
273
|
+
|
|
274
|
+
Where `{BOARD_CREDENTIALS}` is the board-specific key=value pairs collected in Step 3. Wrap values containing spaces in double quotes.
|
|
275
|
+
|
|
276
|
+
### Check .gitignore
|
|
277
|
+
|
|
278
|
+
Check if `.gitignore` exists and contains `.clancy/.env` (or a pattern that covers it, like `.clancy/` or `*.env`).
|
|
279
|
+
|
|
280
|
+
If not covered, show:
|
|
281
|
+
|
|
282
|
+
```
|
|
283
|
+
⚠️ Add .clancy/.env to your .gitignore to keep credentials out of version control:
|
|
284
|
+
|
|
285
|
+
echo '.clancy/.env' >> .gitignore
|
|
286
|
+
```
|
|
287
|
+
|
|
288
|
+
---
|
|
289
|
+
|
|
290
|
+
## Step 7 — Completion
|
|
291
|
+
|
|
292
|
+
Show the board-specific success message:
|
|
293
|
+
|
|
294
|
+
### Jira
|
|
295
|
+
|
|
296
|
+
```
|
|
297
|
+
Board credentials configured for Jira ({JIRA_PROJECT_KEY}).
|
|
298
|
+
|
|
299
|
+
You can now brief from Jira tickets:
|
|
300
|
+
/clancy:brief PROJ-123
|
|
301
|
+
|
|
302
|
+
Credentials are stored in .clancy/.env (this project only).
|
|
303
|
+
To reconfigure: /clancy:board-setup
|
|
304
|
+
For the full pipeline: npx chief-clancy
|
|
305
|
+
```
|
|
306
|
+
|
|
307
|
+
### GitHub Issues
|
|
308
|
+
|
|
309
|
+
```
|
|
310
|
+
Board credentials configured for GitHub Issues ({GITHUB_REPO}).
|
|
311
|
+
|
|
312
|
+
You can now brief from GitHub issues:
|
|
313
|
+
/clancy:brief #42
|
|
314
|
+
|
|
315
|
+
Credentials are stored in .clancy/.env (this project only).
|
|
316
|
+
To reconfigure: /clancy:board-setup
|
|
317
|
+
For the full pipeline: npx chief-clancy
|
|
318
|
+
```
|
|
319
|
+
|
|
320
|
+
### Linear
|
|
321
|
+
|
|
322
|
+
```
|
|
323
|
+
Board credentials configured for Linear.
|
|
324
|
+
|
|
325
|
+
You can now brief from Linear issues:
|
|
326
|
+
/clancy:brief ENG-42
|
|
327
|
+
|
|
328
|
+
Credentials are stored in .clancy/.env (this project only).
|
|
329
|
+
To reconfigure: /clancy:board-setup
|
|
330
|
+
For the full pipeline: npx chief-clancy
|
|
331
|
+
```
|
|
332
|
+
|
|
333
|
+
### Shortcut
|
|
334
|
+
|
|
335
|
+
```
|
|
336
|
+
Board credentials configured for Shortcut.
|
|
337
|
+
|
|
338
|
+
You can now brief from Shortcut stories:
|
|
339
|
+
/clancy:brief SC-123
|
|
340
|
+
|
|
341
|
+
Credentials are stored in .clancy/.env (this project only).
|
|
342
|
+
To reconfigure: /clancy:board-setup
|
|
343
|
+
For the full pipeline: npx chief-clancy
|
|
344
|
+
```
|
|
345
|
+
|
|
346
|
+
### Notion
|
|
347
|
+
|
|
348
|
+
```
|
|
349
|
+
Board credentials configured for Notion.
|
|
350
|
+
|
|
351
|
+
You can now brief from Notion pages:
|
|
352
|
+
/clancy:brief notion-XXXXXXXX
|
|
353
|
+
|
|
354
|
+
Credentials are stored in .clancy/.env (this project only).
|
|
355
|
+
To reconfigure: /clancy:board-setup
|
|
356
|
+
For the full pipeline: npx chief-clancy
|
|
357
|
+
```
|
|
358
|
+
|
|
359
|
+
### Azure DevOps
|
|
360
|
+
|
|
361
|
+
```
|
|
362
|
+
Board credentials configured for Azure DevOps ({AZDO_PROJECT}).
|
|
363
|
+
|
|
364
|
+
You can now brief from Azure DevOps work items:
|
|
365
|
+
/clancy:brief 42
|
|
366
|
+
|
|
367
|
+
Credentials are stored in .clancy/.env (this project only).
|
|
368
|
+
To reconfigure: /clancy:board-setup
|
|
369
|
+
For the full pipeline: npx chief-clancy
|
|
370
|
+
```
|
package/src/workflows/brief.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
## Overview
|
|
4
4
|
|
|
5
|
-
Research an idea, interrogate it thoroughly, and generate a structured strategic brief with vertical-slice ticket decomposition. Briefs are saved locally and optionally posted as comments on the source ticket. Does not create tickets — in **terminal mode**, use `/clancy:approve-brief` for that. In **standalone mode**, install the full pipeline (`npx chief-clancy`) to create tickets from briefs.
|
|
5
|
+
Research an idea, interrogate it thoroughly, and generate a structured strategic brief with vertical-slice ticket decomposition. Briefs are saved locally and optionally posted as comments on the source ticket. Does not create tickets — in **terminal mode**, use `/clancy:approve-brief` for that. In **standalone mode** or **standalone+board mode**, install the full pipeline (`npx chief-clancy`) to create tickets from briefs.
|
|
6
6
|
|
|
7
7
|
---
|
|
8
8
|
|
|
@@ -12,12 +12,17 @@ Research an idea, interrogate it thoroughly, and generate a structured strategic
|
|
|
12
12
|
|
|
13
13
|
Check for `.clancy/.env`:
|
|
14
14
|
|
|
15
|
-
- **
|
|
16
|
-
- **
|
|
15
|
+
- **Absent** → **standalone mode**. No board credentials. Board ticket and batch modes are blocked.
|
|
16
|
+
- **Present** → continue to `.clancy/clancy-implement.js` check below.
|
|
17
17
|
|
|
18
|
-
|
|
18
|
+
If `.clancy/.env` is present, check for `.clancy/clancy-implement.js`:
|
|
19
19
|
|
|
20
|
-
|
|
20
|
+
- **Present** → **terminal mode**. Full Clancy pipeline installed.
|
|
21
|
+
- **Absent** → **standalone+board mode**. Board credentials available via `/clancy:board-setup`. Board ticket mode works. Steps 10/10a work. But `/clancy:approve-brief` is not available (requires full pipeline).
|
|
22
|
+
|
|
23
|
+
### 2. Terminal-mode preflight (skip in standalone mode and standalone+board mode)
|
|
24
|
+
|
|
25
|
+
If in **terminal mode** (`.clancy/.env` present AND `.clancy/clancy-implement.js` present):
|
|
21
26
|
|
|
22
27
|
a. Source `.clancy/.env` and check board credentials are present.
|
|
23
28
|
|
|
@@ -90,8 +95,9 @@ If `--list` is present (with or without other arguments), jump to Step 11 (Brief
|
|
|
90
95
|
If running in **standalone mode** (Step 1 detected no `.clancy/.env`) and the resolved input mode is **board ticket** or **batch mode**:
|
|
91
96
|
|
|
92
97
|
```
|
|
93
|
-
Board credentials not found. To brief from a board ticket
|
|
94
|
-
|
|
98
|
+
Board credentials not found. To brief from a board ticket:
|
|
99
|
+
/clancy:board-setup — configure board credentials (standalone)
|
|
100
|
+
npx chief-clancy — install the full pipeline
|
|
95
101
|
|
|
96
102
|
For now, use:
|
|
97
103
|
/clancy:brief "Add dark mode" — inline text
|
|
@@ -100,6 +106,8 @@ For now, use:
|
|
|
100
106
|
|
|
101
107
|
Stop.
|
|
102
108
|
|
|
109
|
+
In **standalone+board mode**, board ticket and batch modes proceed normally — credentials are available.
|
|
110
|
+
|
|
103
111
|
---
|
|
104
112
|
|
|
105
113
|
## Step 3 — Gather idea (mode-specific)
|
|
@@ -855,7 +863,7 @@ Write to `.clancy/briefs/{YYYY-MM-DD}-{slug}.md`.
|
|
|
855
863
|
|
|
856
864
|
## Step 10 — Post to board
|
|
857
865
|
|
|
858
|
-
Only for board-sourced briefs
|
|
866
|
+
Only for board-sourced briefs when board credentials are available (terminal mode or standalone+board mode). In **standalone mode** (no `.clancy/.env`), skip this step and Step 10a entirely — the local file in `.clancy/briefs/` is the source of truth.
|
|
859
867
|
|
|
860
868
|
Inline text and file briefs are also local only — skip this step regardless of mode.
|
|
861
869
|
|
|
@@ -971,7 +979,7 @@ Continue — do not stop. The local file is the source of truth.
|
|
|
971
979
|
|
|
972
980
|
## Step 10a — Apply pipeline label (board-sourced only)
|
|
973
981
|
|
|
974
|
-
Only for board-sourced briefs
|
|
982
|
+
Only for board-sourced briefs when board credentials are available (terminal mode or standalone+board mode). In **standalone mode** (no `.clancy/.env`), skip this step entirely (see Step 10 guard). Inline text and file briefs also skip this step. Note: in standalone+board mode, this step creates a `clancy:brief` label on the board — this is expected behaviour when credentials are configured.
|
|
975
983
|
|
|
976
984
|
**This step is mandatory for board-sourced briefs — always apply the label.** Use `CLANCY_LABEL_BRIEF` from `.clancy/.env` if set. If not set, use `clancy:brief` as the default. Ensure the label exists on the board (create it if missing), then add it to the ticket. Also read `CLANCY_LABEL_PLAN` (default: `clancy:plan`) and `CLANCY_LABEL_BUILD` (default: `clancy:build`) for cleanup during re-briefs.
|
|
977
985
|
|
|
@@ -1240,7 +1248,7 @@ Clancy — Briefs
|
|
|
1240
1248
|
3 unapproved drafts. 1 stale (>7 days).
|
|
1241
1249
|
|
|
1242
1250
|
To approve (terminal mode): /clancy:approve-brief <slug or index>
|
|
1243
|
-
To approve (standalone):
|
|
1251
|
+
To approve (standalone/standalone+board): npx chief-clancy, then /clancy:approve-brief
|
|
1244
1252
|
To review stale briefs: open the file and add ## Feedback, or delete it.
|
|
1245
1253
|
```
|
|
1246
1254
|
|
|
@@ -1275,7 +1283,7 @@ Next Steps
|
|
|
1275
1283
|
Then re-run: /clancy:brief {KEY}
|
|
1276
1284
|
|
|
1277
1285
|
Approve: /clancy:approve-brief {KEY} (terminal mode)
|
|
1278
|
-
Full pipeline: npx chief-clancy (if
|
|
1286
|
+
Full pipeline: npx chief-clancy (if not terminal mode)
|
|
1279
1287
|
Start over: /clancy:brief --fresh {KEY}
|
|
1280
1288
|
```
|
|
1281
1289
|
|
|
@@ -1295,7 +1303,7 @@ Next Steps
|
|
|
1295
1303
|
|
|
1296
1304
|
Approve: /clancy:approve-brief {slug} (terminal mode)
|
|
1297
1305
|
With parent: /clancy:approve-brief {slug} --epic {KEY}
|
|
1298
|
-
Full pipeline: npx chief-clancy (if
|
|
1306
|
+
Full pipeline: npx chief-clancy (if not terminal mode)
|
|
1299
1307
|
Start over: /clancy:brief --fresh
|
|
1300
1308
|
```
|
|
1301
1309
|
|
|
@@ -1330,7 +1338,7 @@ Briefed {M} of {N} tickets. {K} skipped.
|
|
|
1330
1338
|
⏭️ [{KEY3}] {Title} — already briefed
|
|
1331
1339
|
⏭️ [{KEY4}] {Title} — not relevant
|
|
1332
1340
|
|
|
1333
|
-
Briefs saved to .clancy/briefs/. To create tickets: /clancy:approve-brief (
|
|
1341
|
+
Briefs saved to .clancy/briefs/. To create tickets: /clancy:approve-brief (requires full pipeline — npx chief-clancy).
|
|
1334
1342
|
```
|
|
1335
1343
|
|
|
1336
1344
|
---
|
|
@@ -11,7 +11,7 @@ import { describe, expect, it } from 'vitest';
|
|
|
11
11
|
|
|
12
12
|
const WORKFLOWS_DIR = fileURLToPath(new URL('.', import.meta.url));
|
|
13
13
|
|
|
14
|
-
const EXPECTED_WORKFLOWS = ['brief.md'];
|
|
14
|
+
const EXPECTED_WORKFLOWS = ['approve-brief.md', 'board-setup.md', 'brief.md'];
|
|
15
15
|
|
|
16
16
|
describe('workflows directory structure', () => {
|
|
17
17
|
it('contains exactly the expected workflow files', () => {
|
|
@@ -43,15 +43,104 @@ describe('workflows directory structure', () => {
|
|
|
43
43
|
expect(content).toContain('## Step 1');
|
|
44
44
|
expect(content).toContain('.clancy/briefs/');
|
|
45
45
|
});
|
|
46
|
+
|
|
47
|
+
it('approve-brief workflow has structural step markers', () => {
|
|
48
|
+
const content = readFileSync(
|
|
49
|
+
new URL('approve-brief.md', import.meta.url),
|
|
50
|
+
'utf8',
|
|
51
|
+
);
|
|
52
|
+
|
|
53
|
+
expect(content).toContain('## Step 1');
|
|
54
|
+
expect(content).toContain('.clancy/briefs/');
|
|
55
|
+
});
|
|
46
56
|
});
|
|
47
57
|
|
|
48
|
-
|
|
58
|
+
// ---------------------------------------------------------------------------
|
|
59
|
+
// board-setup.md content assertions
|
|
60
|
+
// ---------------------------------------------------------------------------
|
|
61
|
+
|
|
62
|
+
describe('board-setup workflow', () => {
|
|
63
|
+
const content = readFileSync(
|
|
64
|
+
new URL('board-setup.md', import.meta.url),
|
|
65
|
+
'utf8',
|
|
66
|
+
);
|
|
67
|
+
|
|
68
|
+
it('checks for full pipeline before proceeding', () => {
|
|
69
|
+
expect(content).toContain('clancy-implement.js');
|
|
70
|
+
expect(content).toContain('/clancy:settings');
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
it('checks for existing board credentials', () => {
|
|
74
|
+
expect(content).toContain('Existing board credentials found');
|
|
75
|
+
expect(content).toContain('Reconfigure');
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
it('offers all 6 supported boards', () => {
|
|
79
|
+
expect(content).toContain('Jira');
|
|
80
|
+
expect(content).toContain('GitHub Issues');
|
|
81
|
+
expect(content).toContain('Linear');
|
|
82
|
+
expect(content).toContain('Shortcut');
|
|
83
|
+
expect(content).toContain('Notion');
|
|
84
|
+
expect(content).toContain('Azure DevOps');
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
it('includes credential prompts for each board', () => {
|
|
88
|
+
expect(content).toContain('JIRA_BASE_URL');
|
|
89
|
+
expect(content).toContain('GITHUB_TOKEN');
|
|
90
|
+
expect(content).toContain('LINEAR_API_KEY');
|
|
91
|
+
expect(content).toContain('SHORTCUT_API_TOKEN');
|
|
92
|
+
expect(content).toContain('NOTION_TOKEN');
|
|
93
|
+
expect(content).toContain('AZDO_PAT');
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
it('includes credential verification for each board', () => {
|
|
97
|
+
expect(content).toContain('Jira connected');
|
|
98
|
+
expect(content).toContain('GitHub connected');
|
|
99
|
+
expect(content).toContain('Linear connected');
|
|
100
|
+
expect(content).toContain('Shortcut connected');
|
|
101
|
+
expect(content).toContain('Notion connected');
|
|
102
|
+
expect(content).toContain('Azure DevOps connected');
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
it('offers re-enter, skip, and cancel on verification failure', () => {
|
|
106
|
+
expect(content).toContain('Re-enter credentials');
|
|
107
|
+
expect(content).toContain('Skip verification');
|
|
108
|
+
expect(content).toContain('Cancel');
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
it('warns about .gitignore', () => {
|
|
112
|
+
expect(content).toContain('.gitignore');
|
|
113
|
+
expect(content).toContain('.clancy/.env');
|
|
114
|
+
});
|
|
115
|
+
|
|
116
|
+
it('notes credentials are per-project', () => {
|
|
117
|
+
expect(content).toContain('this project only');
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
it('includes brief header comment in env file', () => {
|
|
121
|
+
expect(content).toContain('Configured by @chief-clancy/brief');
|
|
122
|
+
});
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
// ---------------------------------------------------------------------------
|
|
126
|
+
// brief.md content assertions
|
|
127
|
+
// ---------------------------------------------------------------------------
|
|
128
|
+
|
|
129
|
+
describe('three-state mode detection', () => {
|
|
49
130
|
const content = readFileSync(new URL('brief.md', import.meta.url), 'utf8');
|
|
50
131
|
|
|
51
|
-
it('Step 1
|
|
132
|
+
it('Step 1 detects three installation states', () => {
|
|
52
133
|
expect(content).toContain('standalone mode');
|
|
134
|
+
expect(content).toContain('standalone+board mode');
|
|
53
135
|
expect(content).toContain('terminal mode');
|
|
54
|
-
|
|
136
|
+
});
|
|
137
|
+
|
|
138
|
+
it('Step 1 checks .clancy/.env for credentials', () => {
|
|
139
|
+
expect(content).toContain('.clancy/.env');
|
|
140
|
+
});
|
|
141
|
+
|
|
142
|
+
it('Step 1 checks clancy-implement.js for terminal detection', () => {
|
|
143
|
+
expect(content).toContain('clancy-implement.js');
|
|
55
144
|
});
|
|
56
145
|
|
|
57
146
|
it('Step 1 does not hard-stop on missing .clancy/.env', () => {
|
|
@@ -60,19 +149,26 @@ describe('standalone mode adaptations', () => {
|
|
|
60
149
|
);
|
|
61
150
|
});
|
|
62
151
|
|
|
63
|
-
it('
|
|
152
|
+
it('CLANCY_ROLES check only runs in terminal mode', () => {
|
|
153
|
+
expect(content).toContain('Terminal-mode preflight');
|
|
154
|
+
expect(content).toContain(
|
|
155
|
+
'skip in standalone mode and standalone+board mode',
|
|
156
|
+
);
|
|
157
|
+
});
|
|
158
|
+
|
|
159
|
+
it('standalone guard mentions /clancy:board-setup', () => {
|
|
64
160
|
expect(content).toContain('Standalone board-ticket guard');
|
|
65
161
|
expect(content).toContain('Board credentials not found');
|
|
66
|
-
expect(content).toContain('
|
|
162
|
+
expect(content).toContain('/clancy:board-setup');
|
|
67
163
|
});
|
|
68
164
|
|
|
69
|
-
it('Step 10
|
|
165
|
+
it('Step 10 runs when board credentials are available', () => {
|
|
70
166
|
expect(content).toContain(
|
|
71
|
-
'
|
|
167
|
+
'when board credentials are available (terminal mode or standalone+board mode)',
|
|
72
168
|
);
|
|
73
169
|
});
|
|
74
170
|
|
|
75
|
-
it('Step 10a
|
|
171
|
+
it('Step 10a runs when board credentials are available', () => {
|
|
76
172
|
expect(content).toContain('see Step 10 guard');
|
|
77
173
|
});
|
|
78
174
|
|
|
@@ -81,7 +177,7 @@ describe('standalone mode adaptations', () => {
|
|
|
81
177
|
expect(content).not.toContain('src/agents/devils-advocate.md');
|
|
82
178
|
});
|
|
83
179
|
|
|
84
|
-
it('approve-brief references include standalone
|
|
180
|
+
it('approve-brief references include standalone guidance', () => {
|
|
85
181
|
expect(content).not.toMatch(/that is `\/clancy:approve-brief`\./);
|
|
86
182
|
expect(content).toContain('npx chief-clancy');
|
|
87
183
|
});
|