@braingrid/cli 0.2.37 → 0.2.38

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/CHANGELOG.md CHANGED
@@ -7,6 +7,24 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [0.2.38] - 2026-02-17
11
+
12
+ ### Added
13
+
14
+ - **`--content` option for `requirement update` command**
15
+ - Allows updating a requirement's content directly from the CLI with `--content`
16
+ - **Parallel mode with agent teams for `/build` command**
17
+ - `/build` now supports a parallel execution mode that spawns agent teams for concurrent task implementation
18
+ - **Verify acceptance criteria hook in Claude Code setup**
19
+ - `braingrid setup claude-code` now installs a hook that verifies acceptance criteria during builds
20
+ - **PostToolUse TaskUpdate prompt hook in Claude Code setup**
21
+ - Setup installs a prompt hook that updates task status on PostToolUse events
22
+
23
+ ### Changed
24
+
25
+ - **Synced README and Claude Code guide with CLI implementation**
26
+ - Documentation updated to reflect latest CLI features and usage
27
+
10
28
  ## [0.2.37] - 2026-02-14
11
29
 
12
30
  ### Added
package/README.md CHANGED
@@ -1,9 +1,10 @@
1
1
  <div align="center">
2
- <img src="https://www.braingrid.ai/logos/braingrid-symbol-800.png" width="100"/>
2
+ <img src="https://www.braingrid.ai/brand/symbol-lime-on-jungle.svg" width="80" height="80"/>
3
3
  <h1>BrainGrid</h1>
4
4
 
5
- <p>Prompt AI Coding Tools Like a Rockstar Developer</p>
6
- <h3>A CLI to turn messy thoughts into detailed specs and perfectly-prompted tasks to build well-structured, maintainable software with AI.</h3>
5
+ <p>The AI Product Planner</p>
6
+ <h3>BrainGrid is the AI Product Planner that helps you shape ideas, plan features,
7
+ and scope tasks that your AI coding tools can build right the first time.</h3>
7
8
 
8
9
  [![npm version](https://img.shields.io/npm/v/@braingrid/cli.svg?color=blue&logo=npm)](https://www.npmjs.com/package/@braingrid/cli)
9
10
  [![Downloads](https://img.shields.io/npm/dm/@braingrid/cli.svg?color=green)](https://www.npmjs.com/package/@braingrid/cli)
@@ -207,18 +208,24 @@ braingrid specify -p PROJ-123 --prompt "Implement real-time notifications"
207
208
  # Output in different formats:
208
209
  braingrid specify --prompt "Add dark mode support" --format json
209
210
  braingrid specify --prompt "Add export feature" --format markdown
211
+ braingrid specify --prompt "Add search" --tags "search,backend"
210
212
 
211
213
  # Working with the initialized project
212
- braingrid requirement list [--status IDEA|PLANNED|IN_PROGRESS|REVIEW|COMPLETED|CANCELLED] [--format json]
213
- braingrid requirement create --name "Name" [--content "Description"] [--assigned-to <uuid>]
214
+ braingrid requirement list [--status IDEA|PLANNED|IN_PROGRESS|REVIEW|COMPLETED|CANCELLED] [--tree] [--format json]
215
+ braingrid requirement create --name "Name" [--content "Description"] [--assigned-to <uuid>] [--tags "tag1,tag2"]
214
216
  braingrid requirement show [id]
215
- braingrid requirement update [id] [--status IDEA|PLANNED|IN_PROGRESS|REVIEW|COMPLETED|CANCELLED] [--name "New Name"]
217
+ braingrid requirement update [id] [--status IDEA|PLANNED|IN_PROGRESS|REVIEW|COMPLETED|CANCELLED] [--name "New Name"] [--content "markdown"]
216
218
  braingrid requirement delete [id] [--force]
217
- braingrid requirement breakdown [id]
219
+ braingrid requirement breakdown [id] [--format markdown|json|xml]
218
220
  braingrid requirement build [id] [--format markdown|json|xml]
219
221
  braingrid requirement create-branch [id] [--name <branch-name>] [--base <branch>]
220
222
  braingrid requirement review [id] [--pr <number>]
221
223
 
224
+ # Tag management
225
+ braingrid requirement tag list [id]
226
+ braingrid requirement tag add [id] --name "Tag" --color "#FF0000"
227
+ braingrid requirement tag remove [id] --name "Tag"
228
+
222
229
  # Working with a different project:
223
230
  braingrid requirement list -p PROJ-456 [--status PLANNED]
224
231
  braingrid requirement create -p PROJ-456 --name "Description"
@@ -241,9 +248,11 @@ braingrid requirement create -p PROJ-456 --name "Description"
241
248
  ```bash
242
249
  # Working with the initialized project
243
250
  braingrid task list -r REQ-456 [--format table|json|xml|markdown]
244
- braingrid task create -r REQ-456 --title "Task Title" [--content "Description"]
245
- braingrid task show <id>
246
- braingrid task update <id> [--status PLANNED|IN_PROGRESS|COMPLETED|CANCELLED] [--title "New Title"]
251
+ braingrid task create -r REQ-456 --title "Task Title" [--content "Description"] [--external-id <id>]
252
+ braingrid task show [id]
253
+ braingrid task update [id] [--status PLANNED|IN_PROGRESS|COMPLETED|CANCELLED] [--title "New Title"] [--external-id <id>]
254
+ braingrid task summary -r REQ-456
255
+ braingrid task specify -r REQ-456 --prompt "Task description"
247
256
  braingrid task delete <id> [--force]
248
257
 
249
258
  # Working with a different project:
@@ -256,6 +265,14 @@ braingrid task create -p PROJ-123 -r REQ-456 --title "Task Title"
256
265
  > **Note:** The `-r`/`--requirement` parameter is optional and accepts formats like `REQ-456`, `req-456`, or `456`. The CLI will automatically detect the requirement ID from your git branch name (e.g., `feature/REQ-123-description` or `REQ-123-fix-bug`) if it is not provided.
257
266
  >
258
267
  > **Note:** Task status values are: `PLANNED`, `IN_PROGRESS`, `COMPLETED`, `CANCELLED` (tasks do not have `IDEA` or `REVIEW` status).
268
+ >
269
+ > **Note:** `task summary` shows a compact overview table (number, status, title) without full content — useful for quick progress checks.
270
+ >
271
+ > **Note:** `task specify` creates a single AI-generated task from a prompt (10-5000 characters), similar to how `specify` creates requirements.
272
+ >
273
+ > **Note:** The `requirement tag` commands manage tags on requirements. Each requirement can have up to 5 tags. Tags require a name and hex color code (e.g., `#FF0000`).
274
+ >
275
+ > **Note:** `--external-id` links tasks to external systems (e.g., Claude Code task IDs) for status synchronization.
259
276
 
260
277
  ### Informational Commands
261
278
 
@@ -318,7 +335,7 @@ eval "$(braingrid completion zsh)"
318
335
  ### What Gets Completed
319
336
 
320
337
  - **Commands**: `login`, `logout`, `project`, `requirement`, `task`, etc.
321
- - **Subcommands**: `list`, `show`, `create`, `update`, `delete`, `breakdown`, `build`, `create-branch`, `review`
338
+ - **Subcommands**: `list`, `show`, `create`, `update`, `delete`, `breakdown`, `build`, `create-branch`, `review`, `summary`, `specify`, `tag`
322
339
  - **Options**: `--help`, `--format`, `--status`, `--project`, `--requirement`
323
340
  - **Values**: Status values (`IDEA`, `PLANNED`, `IN_PROGRESS`, etc.), format options (`table`, `json`, `xml`, `markdown`)
324
341
 
package/dist/cli.js CHANGED
@@ -222,7 +222,7 @@ async function axiosWithRetry(config2, options) {
222
222
 
223
223
  // src/build-config.ts
224
224
  var BUILD_ENV = true ? "production" : process.env.NODE_ENV === "test" ? "development" : "production";
225
- var CLI_VERSION = true ? "0.2.37" : "0.0.0-test";
225
+ var CLI_VERSION = true ? "0.2.38" : "0.0.0-test";
226
226
  var PRODUCTION_CONFIG = {
227
227
  apiUrl: "https://app.braingrid.ai",
228
228
  workosAuthUrl: "https://auth.braingrid.ai",
@@ -2679,7 +2679,18 @@ async function copyBraingridReadme(targetPath = ".braingrid/README.md") {
2679
2679
  return false;
2680
2680
  }
2681
2681
  }
2682
- async function updateClaudeSettings(settingsPath = ".claude/settings.json", scriptPath2 = ".claude/statusline.sh", hookScriptPath = ".claude/hooks/sync-braingrid-task.sh", createHookScriptPath = ".claude/hooks/create-braingrid-task.sh") {
2682
+ var TASK_UPDATE_CONTINUATION_PROMPT = `After every task status change, follow these rules:
2683
+
2684
+ 1. **On completion**: Verify you committed your changes and updated the task subject with the commit hash (e.g. 'TASK 2 (abc1234): feat: add login'). If you forgot to commit, do it now before moving on.
2685
+
2686
+ 2. **Continue immediately**: After completing a task, check TaskList for the next pending task. Mark it as in_progress and start implementing it right away. Do NOT stop to ask the user for permission.
2687
+
2688
+ 3. **Do not stop until done**: Keep iterating through tasks until ALL tasks are completed. The only valid reason to pause is a genuine blocking question that cannot be answered from the requirement, task descriptions, or codebase.
2689
+
2690
+ 4. **Never ask to continue**: Do NOT say 'Would you like me to continue?', 'Ready for the next task?', 'Shall I proceed?', or any variation. Just continue.
2691
+
2692
+ $ARGUMENTS`;
2693
+ async function updateClaudeSettings(settingsPath = ".claude/settings.json", scriptPath2 = ".claude/statusline.sh", hookScriptPath = ".claude/hooks/sync-braingrid-task.sh", createHookScriptPath = ".claude/hooks/create-braingrid-task.sh", verifyHookScriptPath = ".claude/hooks/verify-acceptance-criteria.sh") {
2683
2694
  try {
2684
2695
  let settings = {};
2685
2696
  try {
@@ -2703,6 +2714,10 @@ async function updateClaudeSettings(settingsPath = ".claude/settings.json", scri
2703
2714
  type: "command",
2704
2715
  command: hookScriptPath,
2705
2716
  timeout: 1e4
2717
+ },
2718
+ {
2719
+ type: "prompt",
2720
+ prompt: TASK_UPDATE_CONTINUATION_PROMPT
2706
2721
  }
2707
2722
  ]
2708
2723
  };
@@ -2765,10 +2780,24 @@ async function updateClaudeSettings(settingsPath = ".claude/settings.json", scri
2765
2780
  } else {
2766
2781
  mergedPreToolUse = [...mergedPreToolUse, ourPreToolUseTaskUpdateEntry];
2767
2782
  }
2783
+ const ourStopHookEntry = {
2784
+ hooks: [
2785
+ {
2786
+ type: "command",
2787
+ command: verifyHookScriptPath
2788
+ }
2789
+ ]
2790
+ };
2791
+ const existingStop = Array.isArray(existingHooks.Stop) ? existingHooks.Stop : [];
2792
+ const hasVerifyHook = existingStop.some(
2793
+ (entry) => entry.hooks?.some((h) => h.command?.includes("verify-acceptance-criteria"))
2794
+ );
2795
+ const mergedStop = hasVerifyHook ? existingStop : [...existingStop, ourStopHookEntry];
2768
2796
  settings.hooks = {
2769
2797
  ...existingHooks,
2770
2798
  PreToolUse: mergedPreToolUse,
2771
- PostToolUse: mergedPostToolUse
2799
+ PostToolUse: mergedPostToolUse,
2800
+ Stop: mergedStop
2772
2801
  };
2773
2802
  const parentDir = path2.dirname(settingsPath);
2774
2803
  await fs2.mkdir(parentDir, { recursive: true });
@@ -3572,8 +3601,21 @@ async function handleSetupClaudeCode(opts) {
3572
3601
  error instanceof Error ? error.message : String(error)
3573
3602
  );
3574
3603
  }
3604
+ let verifyHookInstalled = false;
3605
+ try {
3606
+ const verifyContent = await fetchFileFromGitHub(
3607
+ "claude-code/hooks/verify-acceptance-criteria.sh"
3608
+ );
3609
+ await installHookScript(verifyContent, ".claude/hooks/verify-acceptance-criteria.sh");
3610
+ verifyHookInstalled = true;
3611
+ } catch (error) {
3612
+ console.error(
3613
+ chalk8.yellow("\u26A0\uFE0F Failed to install verify hook:"),
3614
+ error instanceof Error ? error.message : String(error)
3615
+ );
3616
+ }
3575
3617
  const statusLineMessage = statusLineInstalled ? chalk8.dim(" Status line: .claude/statusline.sh\n") : "";
3576
- const hooksMessage = (syncHookInstalled ? chalk8.dim(" Hook script: .claude/hooks/sync-braingrid-task.sh\n") : "") + (createHookInstalled ? chalk8.dim(" Hook script: .claude/hooks/create-braingrid-task.sh\n") : "");
3618
+ const hooksMessage = (syncHookInstalled ? chalk8.dim(" Hook script: .claude/hooks/sync-braingrid-task.sh\n") : "") + (createHookInstalled ? chalk8.dim(" Hook script: .claude/hooks/create-braingrid-task.sh\n") : "") + (verifyHookInstalled ? chalk8.dim(" Hook script: .claude/hooks/verify-acceptance-criteria.sh\n") : "");
3577
3619
  return {
3578
3620
  success: true,
3579
3621
  message: buildSuccessMessage(config2, displayPerDir, statusLineMessage + hooksMessage)
@@ -6739,10 +6781,12 @@ async function handleRequirementUpdate(opts) {
6739
6781
  message: chalk14.red("\u274C Not authenticated. Please run `braingrid login` first.")
6740
6782
  };
6741
6783
  }
6742
- if (!opts.status && !opts.name) {
6784
+ if (!opts.status && !opts.name && !opts.content) {
6743
6785
  return {
6744
6786
  success: false,
6745
- message: chalk14.red("\u274C Please provide at least one field to update (--status or --name)")
6787
+ message: chalk14.red(
6788
+ "\u274C Please provide at least one field to update (--status, --name, or --content)"
6789
+ )
6746
6790
  };
6747
6791
  }
6748
6792
  const requirementResult = await workspaceManager.getRequirement(opts.id);
@@ -6765,7 +6809,8 @@ async function handleRequirementUpdate(opts) {
6765
6809
  stopSpinner = showSpinner("Updating requirement", chalk14.gray);
6766
6810
  const requirement2 = await requirementService.updateProjectRequirement(projectId, normalizedId, {
6767
6811
  status: opts.status,
6768
- name: opts.name
6812
+ name: opts.name,
6813
+ content: opts.content
6769
6814
  });
6770
6815
  stopSpinner();
6771
6816
  stopSpinner = null;
@@ -8488,7 +8533,7 @@ requirement.command("create").description("Create a new requirement").option(
8488
8533
  requirement.command("update [id]").description("Update requirement information (auto-detects ID from git branch if not provided)").option("-p, --project <id>", "project ID (auto-detects from workspace if not specified)").option(
8489
8534
  "--status <status>",
8490
8535
  "new status (IDEA, PLANNED, IN_PROGRESS, REVIEW, COMPLETED, CANCELLED)"
8491
- ).option("--name <name>", "new requirement name").action(async (id, opts) => {
8536
+ ).option("--name <name>", "new requirement name").option("-c, --content <content>", "new requirement content (markdown)").action(async (id, opts) => {
8492
8537
  const result = await handleRequirementUpdate({ ...opts, id });
8493
8538
  console.log(result.message);
8494
8539
  if (!result.success) {