@chief-clancy/brief 0.1.0 → 0.1.2

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 ADDED
@@ -0,0 +1,83 @@
1
+ # @chief-clancy/brief
2
+
3
+ **Strategic brief generator for Claude Code.**
4
+
5
+ [![npm](https://img.shields.io/npm/v/@chief-clancy/brief?style=for-the-badge&color=cb3837)](https://www.npmjs.com/package/@chief-clancy/brief) [![License: MIT](https://img.shields.io/badge/License-MIT-blue?style=for-the-badge)](../../LICENSE)
6
+
7
+ ```bash
8
+ npx @chief-clancy/brief
9
+ ```
10
+
11
+ Turn feature ideas into structured strategic briefs with vertical-slice ticket decomposition. Works standalone — no board credentials, no pipeline, no config required.
12
+
13
+ ## What it does
14
+
15
+ The `/clancy:brief` slash command researches your codebase, grills you (or itself) on requirements, and produces a brief document with:
16
+
17
+ - Problem statement and goals
18
+ - Discovery Q&A from the grill phase
19
+ - User stories
20
+ - Technical considerations
21
+ - Ticket decomposition table (vertical slices, sized, with dependencies)
22
+ - Open questions and risks
23
+
24
+ ## How it works
25
+
26
+ 1. **Install:** `npx @chief-clancy/brief` — choose global or local
27
+ 2. **Run:** `/clancy:brief "Add dark mode support"` — inline text
28
+ 3. **Or from a file:** `/clancy:brief --from docs/rfc.md`
29
+
30
+ Briefs are saved to `.clancy/briefs/` in your project.
31
+
32
+ ## Input modes
33
+
34
+ | Mode | Example | Board needed? |
35
+ | ------------ | --------------------------------------------- | --------------------------- |
36
+ | Inline text | `/clancy:brief "Add dark mode"` | No |
37
+ | From file | `/clancy:brief --from docs/rfc.md` | No |
38
+ | Board ticket | `/clancy:brief #42`, `/clancy:brief PROJ-123` | Yes (`/clancy:board-setup`) |
39
+ | Batch | `/clancy:brief 3` | Yes (`/clancy:board-setup`) |
40
+ | Interactive | `/clancy:brief` | No |
41
+
42
+ ## Flags
43
+
44
+ | Flag | Description |
45
+ | --------------- | ------------------------------------- |
46
+ | `--afk` | AI-grill instead of human interview |
47
+ | `--fresh` | Discard existing brief and start over |
48
+ | `--research` | Include web research in analysis |
49
+ | `--from <path>` | Brief from a local file |
50
+ | `--epic <KEY>` | Set parent for ticket creation |
51
+ | `--list` | Show inventory of existing briefs |
52
+
53
+ ## Board ticket mode (optional)
54
+
55
+ To brief from board tickets without installing the full pipeline:
56
+
57
+ 1. Run `/clancy:board-setup` in Claude Code
58
+ 2. Follow the prompts to configure your board credentials
59
+ 3. Run `/clancy:brief #42` (or your board's ticket format)
60
+
61
+ Credentials are stored in `.clancy/.env` and are per-project (not global).
62
+
63
+ ## Full pipeline
64
+
65
+ For ticket creation, planning, and the full development pipeline, install the complete Clancy package:
66
+
67
+ ```bash
68
+ npx chief-clancy
69
+ ```
70
+
71
+ ## Part of the Clancy monorepo
72
+
73
+ - [`chief-clancy`](https://www.npmjs.com/package/chief-clancy) — full pipeline (install, configure, implement, autopilot)
74
+ - [`@chief-clancy/terminal`](https://www.npmjs.com/package/@chief-clancy/terminal) — installer, slash commands, hooks, runners
75
+ - [`@chief-clancy/core`](https://www.npmjs.com/package/@chief-clancy/core) — board integrations, pipeline phases, schemas
76
+
77
+ ## Credits
78
+
79
+ Built on the [Ralph technique](https://ghuntley.com/ralph/) by Geoffrey Huntley. See [CREDITS.md](https://github.com/Pushedskydiver/chief-clancy/blob/main/CREDITS.md).
80
+
81
+ ## License
82
+
83
+ MIT — see [LICENSE](https://github.com/Pushedskydiver/chief-clancy/blob/main/LICENSE).
package/bin/brief.js CHANGED
@@ -80,6 +80,14 @@ const rl = createInterface({ input: process.stdin, output: process.stdout });
80
80
  /** @param {string} label */
81
81
  const ask = (label) => new Promise((resolve) => rl.question(label, resolve));
82
82
 
83
+ // ---------------------------------------------------------------------------
84
+ // File lists (keep in sync with install.ts)
85
+ // ---------------------------------------------------------------------------
86
+
87
+ const COMMAND_FILES = ['board-setup.md', 'brief.md'];
88
+ const WORKFLOW_FILES = ['board-setup.md', 'brief.md'];
89
+ const AGENT_FILES = ['devils-advocate.md'];
90
+
83
91
  // ---------------------------------------------------------------------------
84
92
  // Installer
85
93
  // ---------------------------------------------------------------------------
@@ -102,20 +110,23 @@ function copyChecked(src, dest) {
102
110
  }
103
111
 
104
112
  /** Inline workflow @-references into command files (global mode only). */
105
- function inlineWorkflow(commandsDest, workflowsDest) {
113
+ function inlineWorkflows(commandsDest, workflowsDest) {
106
114
  const WORKFLOW_REF = /^@\.claude\/clancy\/workflows\/([^/\\]+\.md)\r?$/gm;
107
- const cmdPath = join(commandsDest, 'brief.md');
108
- const content = readFileSync(cmdPath, 'utf8');
109
- const resolved = content.replace(WORKFLOW_REF, (match, fileName) => {
110
- const wfPath = join(workflowsDest, fileName);
111
- if (!existsSync(wfPath)) return match;
112
- return readFileSync(wfPath, 'utf8');
113
- });
114
115
 
115
- if (resolved !== content) {
116
- rejectSymlink(cmdPath);
117
- writeFileSync(cmdPath, resolved);
118
- }
116
+ COMMAND_FILES.forEach((file) => {
117
+ const cmdPath = join(commandsDest, file);
118
+ const content = readFileSync(cmdPath, 'utf8');
119
+ const resolved = content.replace(WORKFLOW_REF, (match, fileName) => {
120
+ const wfPath = join(workflowsDest, fileName);
121
+ if (!existsSync(wfPath)) return match;
122
+ return readFileSync(wfPath, 'utf8');
123
+ });
124
+
125
+ if (resolved !== content) {
126
+ rejectSymlink(cmdPath);
127
+ writeFileSync(cmdPath, resolved);
128
+ }
129
+ });
119
130
  }
120
131
 
121
132
  // ---------------------------------------------------------------------------
@@ -178,22 +189,19 @@ async function main() {
178
189
  mkdirSync(agentsDest, { recursive: true });
179
190
 
180
191
  // Copy files
181
- copyChecked(
182
- join(sources.commandsDir, 'brief.md'),
183
- join(commandsDest, 'brief.md'),
192
+ COMMAND_FILES.forEach((f) =>
193
+ copyChecked(join(sources.commandsDir, f), join(commandsDest, f)),
184
194
  );
185
- copyChecked(
186
- join(sources.workflowsDir, 'brief.md'),
187
- join(workflowsDest, 'brief.md'),
195
+ WORKFLOW_FILES.forEach((f) =>
196
+ copyChecked(join(sources.workflowsDir, f), join(workflowsDest, f)),
188
197
  );
189
- copyChecked(
190
- join(sources.agentsDir, 'devils-advocate.md'),
191
- join(agentsDest, 'devils-advocate.md'),
198
+ AGENT_FILES.forEach((f) =>
199
+ copyChecked(join(sources.agentsDir, f), join(agentsDest, f)),
192
200
  );
193
201
 
194
202
  // Inline workflows for global mode
195
203
  if (mode === 'global') {
196
- inlineWorkflow(commandsDest, workflowsDest);
204
+ inlineWorkflows(commandsDest, workflowsDest);
197
205
  }
198
206
 
199
207
  // Write version marker
@@ -205,15 +213,21 @@ async function main() {
205
213
  console.log('');
206
214
  console.log(green(' ✓ Clancy Brief installed successfully.'));
207
215
  console.log('');
208
- console.log(' Command available:');
216
+ console.log(' Commands available:');
209
217
  console.log(
210
- ` ${cyan('/clancy:brief')} ${dim('Generate a strategic brief for a feature')}`,
218
+ ` ${cyan('/clancy:brief')} ${dim('Generate a strategic brief')}`,
219
+ );
220
+ console.log(
221
+ ` ${cyan('/clancy:board-setup')} ${dim('Configure board credentials (optional)')}`,
211
222
  );
212
223
  console.log('');
213
224
  console.log(' Next steps:');
214
225
  console.log(` 1. Open a project in Claude Code`);
215
226
  console.log(` 2. Run: ${cyan('/clancy:brief "Your feature idea"')}`);
216
227
  console.log('');
228
+ console.log(dim(' Want to brief from board tickets?'));
229
+ console.log(dim(` Run: ${cyan('/clancy:board-setup')}`));
230
+ console.log('');
217
231
  console.log(
218
232
  dim(' For the full pipeline (tickets, planning, implementation):'),
219
233
  );
@@ -10,9 +10,9 @@ import { join } from 'node:path';
10
10
  // Constants
11
11
  // ---------------------------------------------------------------------------
12
12
  /** Command files shipped with the brief package. */
13
- const COMMAND_FILES = ['brief.md'];
13
+ const COMMAND_FILES = ['board-setup.md', 'brief.md'];
14
14
  /** Workflow files shipped with the brief package. */
15
- const WORKFLOW_FILES = ['brief.md'];
15
+ const WORKFLOW_FILES = ['board-setup.md', 'brief.md'];
16
16
  /** Agent files shipped with the brief package. */
17
17
  const AGENT_FILES = ['devils-advocate.md'];
18
18
  /** Matches `@.claude/clancy/workflows/<filename>.md` on its own line. */
@@ -1 +1 @@
1
- {"version":3,"file":"install.js","sourceRoot":"","sources":["../../src/installer/install.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"install.js","sourceRoot":"","sources":["../../src/installer/install.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@chief-clancy/brief",
3
- "version": "0.1.0",
3
+ "version": "0.1.2",
4
4
  "description": "Strategic brief generator for Claude Code — grill, decompose, and document feature ideas",
5
5
  "author": "Alex Clapperton",
6
6
  "license": "MIT",
@@ -0,0 +1,11 @@
1
+ # /clancy:board-setup
2
+
3
+ Configure board credentials for standalone brief usage. Connects your project to a Kanban board so you can brief from board tickets.
4
+
5
+ Not needed if you have the full Clancy pipeline installed (`npx chief-clancy`) — use `/clancy:settings` instead.
6
+
7
+ Supported boards: Jira, GitHub Issues, Linear, Shortcut, Notion, Azure DevOps.
8
+
9
+ @.claude/clancy/workflows/board-setup.md
10
+
11
+ Follow the board setup workflow above. Collect credentials, verify the connection, and write them to `.clancy/.env`.
@@ -4,7 +4,7 @@ Generate a strategic brief for a feature idea. Researches the codebase, grills y
4
4
 
5
5
  Accepts optional arguments:
6
6
 
7
- - **Board ticket:** `/clancy:brief PROJ-123`, `/clancy:brief #42`, `/clancy:brief ENG-42` — brief from a board ticket
7
+ - **Board ticket:** `/clancy:brief PROJ-123`, `/clancy:brief #42`, `/clancy:brief ENG-42` — brief from a board ticket (requires credentials — run `/clancy:board-setup` or install the full pipeline with `npx chief-clancy`)
8
8
  - **Inline text:** `/clancy:brief "Add dark mode"` — brief from a description
9
9
  - **From file:** `/clancy:brief --from docs/rfc.md` — brief from a local file
10
10
  - **Batch mode:** `/clancy:brief 3` — brief up to 3 tickets from the queue
@@ -11,7 +11,7 @@ import { describe, expect, it } from 'vitest';
11
11
 
12
12
  const COMMANDS_DIR = fileURLToPath(new URL('.', import.meta.url));
13
13
 
14
- const EXPECTED_COMMANDS = ['brief.md'];
14
+ const EXPECTED_COMMANDS = ['board-setup.md', 'brief.md'];
15
15
 
16
16
  describe('commands directory structure', () => {
17
17
  it('contains exactly the expected command files', () => {
@@ -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
+ ```
@@ -2,47 +2,55 @@
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 — that is `/clancy:approve-brief`.
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
 
9
9
  ## Step 1 — Preflight checks
10
10
 
11
- 1. Check `.clancy/` exists and `.clancy/.env` is present. If not:
11
+ ### 1. Detect installation context
12
12
 
13
- ```
14
- .clancy/ not found. Run /clancy:init to set up Clancy first.
15
- ```
13
+ Check for `.clancy/.env`:
16
14
 
17
- Stop.
15
+ - **Absent** → **standalone mode**. No board credentials. Board ticket and batch modes are blocked.
16
+ - **Present** → continue to `.clancy/clancy-implement.js` check below.
18
17
 
19
- 2. Source `.clancy/.env` and check board credentials are present.
18
+ If `.clancy/.env` is present, check for `.clancy/clancy-implement.js`:
20
19
 
21
- 3. Check `CLANCY_ROLES` includes `strategist` (or env var is unset, which indicates a global install where all roles are available). If `CLANCY_ROLES` is set but does not include `strategist`:
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
22
 
23
- ```
24
- The Strategist role is not enabled. Add "strategist" to CLANCY_ROLES in .clancy/.env or run /clancy:settings.
25
- ```
23
+ ### 2. Terminal-mode preflight (skip in standalone mode and standalone+board mode)
26
24
 
27
- Stop.
25
+ If in **terminal mode** (`.clancy/.env` present AND `.clancy/clancy-implement.js` present):
28
26
 
29
- 4. Branch freshness check — run `git fetch origin` and compare the current HEAD with `origin/$CLANCY_BASE_BRANCH` (defaults to `main`). If the local branch is behind:
27
+ a. Source `.clancy/.env` and check board credentials are present.
30
28
 
31
- **AFK mode** (`--afk` flag or `CLANCY_MODE=afk`): auto-pull without prompting. Run `git pull origin $CLANCY_BASE_BRANCH` and continue.
29
+ b. Check `CLANCY_ROLES` includes `strategist` (or env var is unset, which indicates a global install where all roles are available). If `CLANCY_ROLES` is set but does not include `strategist`:
32
30
 
33
- **Interactive mode:**
31
+ ```
32
+ The Strategist role is not enabled. Add "strategist" to CLANCY_ROLES in .clancy/.env or run /clancy:settings.
33
+ ```
34
+
35
+ Stop.
36
+
37
+ ### 3. Branch freshness check — run `git fetch origin` and compare the current HEAD with `origin/$CLANCY_BASE_BRANCH` (defaults to `main`). If the local branch is behind:
34
38
 
35
- ```
36
- ⚠️ Your local branch is behind origin/{CLANCY_BASE_BRANCH} by {N} commit(s).
39
+ **AFK mode** (`--afk` flag or `CLANCY_MODE=afk`): auto-pull without prompting. Run `git pull origin $CLANCY_BASE_BRANCH` and continue.
37
40
 
38
- [1] Pull latest
39
- [2] Continue anyway
40
- [3] Abort
41
- ```
41
+ **Interactive mode:**
42
42
 
43
- - [1] runs `git pull origin $CLANCY_BASE_BRANCH` and continues
44
- - [2] continues without pulling
45
- - [3] stops
43
+ ```
44
+ ⚠️ Your local branch is behind origin/{CLANCY_BASE_BRANCH} by {N} commit(s).
45
+
46
+ [1] Pull latest
47
+ [2] Continue anyway
48
+ [3] Abort
49
+ ```
50
+
51
+ - [1] runs `git pull origin $CLANCY_BASE_BRANCH` and continues
52
+ - [2] continues without pulling
53
+ - [3] stops
46
54
 
47
55
  ---
48
56
 
@@ -56,7 +64,7 @@ Parse the arguments passed to the command. Arguments can appear in any order.
56
64
  - **`--fresh`** — discard any existing brief and start over from scratch
57
65
  - **`--research`** — force web research agent (adds 1 web agent to the research phase)
58
66
  - **`--afk`** — use AI-grill instead of human grill (no interactive questions)
59
- - **`--epic {KEY}`** — hint for `/clancy:approve-brief` later. Stored in the brief's metadata. Ignored if the input is a board ticket (the source ticket is the parent).
67
+ - **`--epic {KEY}`** — hint for the approve step later (terminal mode: `/clancy:approve-brief`). Stored in the brief's metadata. Ignored if the input is a board ticket (the source ticket is the parent).
60
68
 
61
69
  ### Input modes
62
70
 
@@ -82,6 +90,24 @@ If N > 10: `Maximum batch size is 10. Briefing 10 tickets.`
82
90
 
83
91
  If `--list` is present (with or without other arguments), jump to Step 11 (Brief Inventory) and stop.
84
92
 
93
+ ### Standalone board-ticket guard
94
+
95
+ If running in **standalone mode** (Step 1 detected no `.clancy/.env`) and the resolved input mode is **board ticket** or **batch mode**:
96
+
97
+ ```
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
101
+
102
+ For now, use:
103
+ /clancy:brief "Add dark mode" — inline text
104
+ /clancy:brief --from docs/rfc.md — from a file
105
+ ```
106
+
107
+ Stop.
108
+
109
+ In **standalone+board mode**, board ticket and batch modes proceed normally — credentials are available.
110
+
85
111
  ---
86
112
 
87
113
  ## Step 3 — Gather idea (mode-specific)
@@ -553,7 +579,7 @@ Same relentless energy as the human grill, but directed at the strategist itself
553
579
  2. Spawn the devil's advocate agent via the Agent tool, passing:
554
580
  - The idea text (ticket title + description, or inline text, or file content)
555
581
  - The 10-15 generated questions
556
- - The path to the agent prompt: `src/agents/devils-advocate.md`
582
+ - The path to the agent prompt: `.claude/clancy/agents/devils-advocate.md`
557
583
 
558
584
  3. The devil's advocate agent answers each question by INTERROGATING ITS SOURCES:
559
585
  - **Codebase:** explore affected areas, read `.clancy/docs/`, check existing patterns. Don't assume — look.
@@ -774,7 +800,7 @@ Using all gathered context (idea, grill output, research findings), generate the
774
800
 
775
801
  ---
776
802
 
777
- _Generated by [Clancy](https://github.com/Pushedskydiver/chief-clancy). To answer open questions or request changes: comment on the source ticket or add a ## Feedback section to the brief file, then re-run `/clancy:brief` to revise. To approve: `/clancy:approve-brief`. To start over: `/clancy:brief --fresh`._
803
+ _Generated by [Clancy](https://github.com/Pushedskydiver/chief-clancy). To answer open questions or request changes: comment on the source ticket or add a ## Feedback section to the brief file, then re-run `/clancy:brief` to revise. To create tickets: `/clancy:approve-brief` (requires full pipeline — `npx chief-clancy`). To start over: `/clancy:brief --fresh`._
778
804
  ```
779
805
 
780
806
  ### Source field format
@@ -837,7 +863,9 @@ Write to `.clancy/briefs/{YYYY-MM-DD}-{slug}.md`.
837
863
 
838
864
  ## Step 10 — Post to board
839
865
 
840
- Only for board-sourced briefs (ticket key was provided). Inline text and file briefs are local only.
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.
867
+
868
+ Inline text and file briefs are also local only — skip this step regardless of mode.
841
869
 
842
870
  ### GitHub — POST comment
843
871
 
@@ -951,7 +979,7 @@ Continue — do not stop. The local file is the source of truth.
951
979
 
952
980
  ## Step 10a — Apply pipeline label (board-sourced only)
953
981
 
954
- Only for board-sourced briefs (ticket key was provided). Inline text and file briefs skip this step.
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.
955
983
 
956
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.
957
985
 
@@ -1219,7 +1247,8 @@ Clancy — Briefs
1219
1247
 
1220
1248
  3 unapproved drafts. 1 stale (>7 days).
1221
1249
 
1222
- To approve: /clancy:approve-brief <slug or index>
1250
+ To approve (terminal mode): /clancy:approve-brief <slug or index>
1251
+ To approve (standalone/standalone+board): npx chief-clancy, then /clancy:approve-brief
1223
1252
  To review stale briefs: open the file and add ## Feedback, or delete it.
1224
1253
  ```
1225
1254
 
@@ -1253,7 +1282,8 @@ Next Steps
1253
1282
  • Or add a ## Feedback section to the brief file
1254
1283
  Then re-run: /clancy:brief {KEY}
1255
1284
 
1256
- Approve: /clancy:approve-brief {KEY}
1285
+ Approve: /clancy:approve-brief {KEY} (terminal mode)
1286
+ Full pipeline: npx chief-clancy (if not terminal mode)
1257
1287
  Start over: /clancy:brief --fresh {KEY}
1258
1288
  ```
1259
1289
 
@@ -1271,8 +1301,9 @@ Next Steps
1271
1301
  .clancy/briefs/{date}-{slug}.feedback.md
1272
1302
  Then re-run: /clancy:brief
1273
1303
 
1274
- Approve: /clancy:approve-brief {slug}
1304
+ Approve: /clancy:approve-brief {slug} (terminal mode)
1275
1305
  With parent: /clancy:approve-brief {slug} --epic {KEY}
1306
+ Full pipeline: npx chief-clancy (if not terminal mode)
1276
1307
  Start over: /clancy:brief --fresh
1277
1308
  ```
1278
1309
 
@@ -1307,14 +1338,14 @@ Briefed {M} of {N} tickets. {K} skipped.
1307
1338
  ⏭️ [{KEY3}] {Title} — already briefed
1308
1339
  ⏭️ [{KEY4}] {Title} — not relevant
1309
1340
 
1310
- Briefs saved to .clancy/briefs/. Run /clancy:approve-brief to create tickets.
1341
+ Briefs saved to .clancy/briefs/. To create tickets: /clancy:approve-brief (requires full pipeline — npx chief-clancy).
1311
1342
  ```
1312
1343
 
1313
1344
  ---
1314
1345
 
1315
1346
  ## Notes
1316
1347
 
1317
- - This command does NOT create tickets — it generates briefs only. Ticket creation is `/clancy:approve-brief`.
1348
+ - This command does NOT create tickets — it generates briefs only. Ticket creation requires the full pipeline (`npx chief-clancy`) and `/clancy:approve-brief`.
1318
1349
  - Briefs are saved locally in `.clancy/briefs/` and optionally posted as comments on the source ticket.
1319
1350
  - The grill phase is the most important part — do not skip or rush it. Zero ambiguity is the goal.
1320
1351
  - Re-running without `--fresh` auto-detects feedback: if feedback exists, revises; if no feedback, stops with guidance.
@@ -1322,7 +1353,7 @@ Briefs saved to .clancy/briefs/. Run /clancy:approve-brief to create tickets.
1322
1353
  - The `--list` flag is an inventory display only — no brief generated, no API calls beyond the local filesystem.
1323
1354
  - Batch mode (`/clancy:brief 3`) implies AI-grill — each ticket is briefed autonomously.
1324
1355
  - All board API calls are best-effort — if a comment fails to post, print the brief and warn. The local file is the source of truth.
1325
- - The `Clancy Strategic Brief` text in comments is the marker used by both `/clancy:brief` (to detect existing briefs and feedback) and `/clancy:approve-brief` (to find the brief). Search case-insensitively and match regardless of heading level (`#`, `##`, or plain text).
1356
+ - The `Clancy Strategic Brief` text in comments is the marker used by `/clancy:brief` (to detect existing briefs and feedback) and by `/clancy:approve-brief` in terminal mode (to find the brief for ticket creation). Search case-insensitively and match regardless of heading level (`#`, `##`, or plain text).
1326
1357
  - Jira uses ADF for comments (with `codeBlock` fallback). GitHub, Linear, and Shortcut accept Markdown directly.
1327
1358
  - Linear personal API keys do NOT use `Bearer` prefix.
1328
1359
  - Shortcut uses `Shortcut-Token` header (not `Authorization: Bearer`). API base: `https://api.app.shortcut.com/api/v3`. Stories use `name` (not `title`), `description` is markdown, dependencies use `story_links` with `blocks` verb, and workflow state transitions use `workflow_state_id`.
@@ -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 = ['board-setup.md', 'brief.md'];
15
15
 
16
16
  describe('workflows directory structure', () => {
17
17
  it('contains exactly the expected workflow files', () => {
@@ -44,3 +44,131 @@ describe('workflows directory structure', () => {
44
44
  expect(content).toContain('.clancy/briefs/');
45
45
  });
46
46
  });
47
+
48
+ // ---------------------------------------------------------------------------
49
+ // board-setup.md content assertions
50
+ // ---------------------------------------------------------------------------
51
+
52
+ describe('board-setup workflow', () => {
53
+ const content = readFileSync(
54
+ new URL('board-setup.md', import.meta.url),
55
+ 'utf8',
56
+ );
57
+
58
+ it('checks for full pipeline before proceeding', () => {
59
+ expect(content).toContain('clancy-implement.js');
60
+ expect(content).toContain('/clancy:settings');
61
+ });
62
+
63
+ it('checks for existing board credentials', () => {
64
+ expect(content).toContain('Existing board credentials found');
65
+ expect(content).toContain('Reconfigure');
66
+ });
67
+
68
+ it('offers all 6 supported boards', () => {
69
+ expect(content).toContain('Jira');
70
+ expect(content).toContain('GitHub Issues');
71
+ expect(content).toContain('Linear');
72
+ expect(content).toContain('Shortcut');
73
+ expect(content).toContain('Notion');
74
+ expect(content).toContain('Azure DevOps');
75
+ });
76
+
77
+ it('includes credential prompts for each board', () => {
78
+ expect(content).toContain('JIRA_BASE_URL');
79
+ expect(content).toContain('GITHUB_TOKEN');
80
+ expect(content).toContain('LINEAR_API_KEY');
81
+ expect(content).toContain('SHORTCUT_API_TOKEN');
82
+ expect(content).toContain('NOTION_TOKEN');
83
+ expect(content).toContain('AZDO_PAT');
84
+ });
85
+
86
+ it('includes credential verification for each board', () => {
87
+ expect(content).toContain('Jira connected');
88
+ expect(content).toContain('GitHub connected');
89
+ expect(content).toContain('Linear connected');
90
+ expect(content).toContain('Shortcut connected');
91
+ expect(content).toContain('Notion connected');
92
+ expect(content).toContain('Azure DevOps connected');
93
+ });
94
+
95
+ it('offers re-enter, skip, and cancel on verification failure', () => {
96
+ expect(content).toContain('Re-enter credentials');
97
+ expect(content).toContain('Skip verification');
98
+ expect(content).toContain('Cancel');
99
+ });
100
+
101
+ it('warns about .gitignore', () => {
102
+ expect(content).toContain('.gitignore');
103
+ expect(content).toContain('.clancy/.env');
104
+ });
105
+
106
+ it('notes credentials are per-project', () => {
107
+ expect(content).toContain('this project only');
108
+ });
109
+
110
+ it('includes brief header comment in env file', () => {
111
+ expect(content).toContain('Configured by @chief-clancy/brief');
112
+ });
113
+ });
114
+
115
+ // ---------------------------------------------------------------------------
116
+ // brief.md content assertions
117
+ // ---------------------------------------------------------------------------
118
+
119
+ describe('three-state mode detection', () => {
120
+ const content = readFileSync(new URL('brief.md', import.meta.url), 'utf8');
121
+
122
+ it('Step 1 detects three installation states', () => {
123
+ expect(content).toContain('standalone mode');
124
+ expect(content).toContain('standalone+board mode');
125
+ expect(content).toContain('terminal mode');
126
+ });
127
+
128
+ it('Step 1 checks .clancy/.env for credentials', () => {
129
+ expect(content).toContain('.clancy/.env');
130
+ });
131
+
132
+ it('Step 1 checks clancy-implement.js for terminal detection', () => {
133
+ expect(content).toContain('clancy-implement.js');
134
+ });
135
+
136
+ it('Step 1 does not hard-stop on missing .clancy/.env', () => {
137
+ expect(content).not.toContain(
138
+ '.clancy/ not found. Run /clancy:init to set up Clancy first.',
139
+ );
140
+ });
141
+
142
+ it('CLANCY_ROLES check only runs in terminal mode', () => {
143
+ expect(content).toContain('Terminal-mode preflight');
144
+ expect(content).toContain(
145
+ 'skip in standalone mode and standalone+board mode',
146
+ );
147
+ });
148
+
149
+ it('standalone guard mentions /clancy:board-setup', () => {
150
+ expect(content).toContain('Standalone board-ticket guard');
151
+ expect(content).toContain('Board credentials not found');
152
+ expect(content).toContain('/clancy:board-setup');
153
+ });
154
+
155
+ it('Step 10 runs when board credentials are available', () => {
156
+ expect(content).toContain(
157
+ 'when board credentials are available (terminal mode or standalone+board mode)',
158
+ );
159
+ });
160
+
161
+ it('Step 10a runs when board credentials are available', () => {
162
+ expect(content).toContain('see Step 10 guard');
163
+ });
164
+
165
+ it('agent reference uses .claude/clancy/agents/ path', () => {
166
+ expect(content).toContain('.claude/clancy/agents/devils-advocate.md');
167
+ expect(content).not.toContain('src/agents/devils-advocate.md');
168
+ });
169
+
170
+ it('approve-brief references include standalone guidance', () => {
171
+ expect(content).not.toMatch(/that is `\/clancy:approve-brief`\./);
172
+ expect(content).toContain('npx chief-clancy');
173
+ });
174
+ });