@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 +18 -0
- package/README.md +28 -11
- package/dist/cli.js +53 -8
- package/dist/cli.js.map +1 -1
- package/package.json +1 -1
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/
|
|
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>
|
|
6
|
-
<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
|
[](https://www.npmjs.com/package/@braingrid/cli)
|
|
9
10
|
[](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
|
|
246
|
-
braingrid task update
|
|
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.
|
|
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
|
-
|
|
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(
|
|
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) {
|