@braingrid/cli 0.2.39 → 0.2.41

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,29 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [0.2.41] - 2026-02-17
11
+
12
+ ### Fixed
13
+
14
+ - **Tasks invisible to teammates in parallel build mode** — reordered `/build` command to discover tasks and select mode before calling `TaskCreate`; in parallel mode, `TeamCreate` now runs first so tasks land in the team's task list instead of the default session list
15
+ - **Acceptance criteria format** — checklist files now use `## Acceptance Criteria` heading with `- []` list items; updated `verify-acceptance-criteria.sh` grep patterns to match new format
16
+ - **Renamed teammate agents** — parallel build teammates renamed from `builder-{n}` to `braingrid-builder-{n}` for clarity
17
+
18
+ ### Changed
19
+
20
+ - **Update handler uses subprocess for IDE setup** — `braingrid update` now runs IDE setup via a spawned subprocess so the newly installed binary is used instead of the old code still loaded in memory
21
+
22
+ ## [0.2.40] - 2026-02-17
23
+
24
+ ### Fixed
25
+
26
+ - **Converted prompt-type hooks to command-type in setup service**
27
+ - `braingrid setup claude-code` now generates command-type hooks pointing to shell scripts instead of inline prompt-type hooks, matching the local `.claude/settings.json` configuration
28
+ - Affected hooks: PostToolUse TaskUpdate prompt, PreToolUse TaskCreate, PreToolUse TaskUpdate
29
+ - Setup now fetches and installs 3 additional hook scripts: `pre-task-create-naming.sh`, `pre-task-update-instructions.sh`, `post-task-update-prompt.sh`
30
+ - **Added missing hook scripts to docs sync**
31
+ - `verify-acceptance-criteria.sh`, `pre-task-create-naming.sh`, `pre-task-update-instructions.sh`, and `post-task-update-prompt.sh` are now synced to the remote repository
32
+
10
33
  ## [0.2.39] - 2026-02-17
11
34
 
12
35
  ### Fixed
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.39" : "0.0.0-test";
225
+ var CLI_VERSION = true ? "0.2.41" : "0.0.0-test";
226
226
  var PRODUCTION_CONFIG = {
227
227
  apiUrl: "https://app.braingrid.ai",
228
228
  workosAuthUrl: "https://auth.braingrid.ai",
@@ -2679,18 +2679,7 @@ async function copyBraingridReadme(targetPath = ".braingrid/README.md") {
2679
2679
  return false;
2680
2680
  }
2681
2681
  }
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") {
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", verifyHookScriptPath = ".claude/hooks/verify-acceptance-criteria.sh", postTaskUpdatePromptPath = ".claude/hooks/post-task-update-prompt.sh", preTaskCreatePath = ".claude/hooks/pre-task-create-naming.sh", preTaskUpdatePath = ".claude/hooks/pre-task-update-instructions.sh") {
2694
2683
  try {
2695
2684
  let settings = {};
2696
2685
  try {
@@ -2716,8 +2705,8 @@ async function updateClaudeSettings(settingsPath = ".claude/settings.json", scri
2716
2705
  timeout: 1e4
2717
2706
  },
2718
2707
  {
2719
- type: "prompt",
2720
- prompt: TASK_UPDATE_CONTINUATION_PROMPT
2708
+ type: "command",
2709
+ command: postTaskUpdatePromptPath
2721
2710
  }
2722
2711
  ]
2723
2712
  };
@@ -2751,8 +2740,8 @@ async function updateClaudeSettings(settingsPath = ".claude/settings.json", scri
2751
2740
  matcher: "TaskCreate",
2752
2741
  hooks: [
2753
2742
  {
2754
- type: "prompt",
2755
- prompt: "Use sequential task numbering with conventional commit naming for task subjects. The subject MUST follow the format 'TASK N: type: description' where N is the next sequential number (1, 2, 3, ...) based on existing tasks in the current session. Valid types: feat, fix, docs, style, refactor, perf, test, chore. Optional scope in parentheses after type is allowed. Examples: 'TASK 1: feat: add user login', 'TASK 2: fix: resolve null pointer', 'TASK 3: feat(auth): add OAuth support'. Reject if the subject does not follow this convention. $ARGUMENTS"
2743
+ type: "command",
2744
+ command: preTaskCreatePath
2756
2745
  }
2757
2746
  ]
2758
2747
  };
@@ -2769,8 +2758,8 @@ async function updateClaudeSettings(settingsPath = ".claude/settings.json", scri
2769
2758
  matcher: "TaskUpdate",
2770
2759
  hooks: [
2771
2760
  {
2772
- type: "prompt",
2773
- prompt: "Before completing a task, you MUST validate and commit. If status is being set to 'completed':\n\n1. Run the project's linter, test suite, and type checker (detect from project config \u2014 e.g. package.json, Makefile, pyproject.toml, Cargo.toml, etc.).\n2. If any check fails, DO NOT complete \u2014 fix first.\n3. Stage relevant files with git add (specific paths, not -A).\n4. Commit using the conventional commit part of the subject as the message (e.g. 'feat: add user login').\n5. Get the short hash: git rev-parse --short HEAD\n6. Update the task subject to: 'TASK N (HASH): type: description' (e.g. 'TASK 1 (abc1234): feat: add user login').\n7. Only then mark completed.\n\nFor other status changes, proceed normally.\n\n$ARGUMENTS"
2761
+ type: "command",
2762
+ command: preTaskUpdatePath
2774
2763
  }
2775
2764
  ]
2776
2765
  };
@@ -3614,8 +3603,50 @@ async function handleSetupClaudeCode(opts) {
3614
3603
  error instanceof Error ? error.message : String(error)
3615
3604
  );
3616
3605
  }
3606
+ let preTaskCreateInstalled = false;
3607
+ try {
3608
+ const preTaskCreateContent = await fetchFileFromGitHub(
3609
+ "claude-code/hooks/pre-task-create-naming.sh"
3610
+ );
3611
+ await installHookScript(preTaskCreateContent, ".claude/hooks/pre-task-create-naming.sh");
3612
+ preTaskCreateInstalled = true;
3613
+ } catch (error) {
3614
+ console.error(
3615
+ chalk8.yellow("\u26A0\uFE0F Failed to install pre-task-create hook:"),
3616
+ error instanceof Error ? error.message : String(error)
3617
+ );
3618
+ }
3619
+ let preTaskUpdateInstalled = false;
3620
+ try {
3621
+ const preTaskUpdateContent = await fetchFileFromGitHub(
3622
+ "claude-code/hooks/pre-task-update-instructions.sh"
3623
+ );
3624
+ await installHookScript(
3625
+ preTaskUpdateContent,
3626
+ ".claude/hooks/pre-task-update-instructions.sh"
3627
+ );
3628
+ preTaskUpdateInstalled = true;
3629
+ } catch (error) {
3630
+ console.error(
3631
+ chalk8.yellow("\u26A0\uFE0F Failed to install pre-task-update hook:"),
3632
+ error instanceof Error ? error.message : String(error)
3633
+ );
3634
+ }
3635
+ let postTaskUpdateInstalled = false;
3636
+ try {
3637
+ const postTaskUpdateContent = await fetchFileFromGitHub(
3638
+ "claude-code/hooks/post-task-update-prompt.sh"
3639
+ );
3640
+ await installHookScript(postTaskUpdateContent, ".claude/hooks/post-task-update-prompt.sh");
3641
+ postTaskUpdateInstalled = true;
3642
+ } catch (error) {
3643
+ console.error(
3644
+ chalk8.yellow("\u26A0\uFE0F Failed to install post-task-update hook:"),
3645
+ error instanceof Error ? error.message : String(error)
3646
+ );
3647
+ }
3617
3648
  const statusLineMessage = statusLineInstalled ? chalk8.dim(" Status line: .claude/statusline.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") : "");
3649
+ 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") : "") + (preTaskCreateInstalled ? chalk8.dim(" Hook script: .claude/hooks/pre-task-create-naming.sh\n") : "") + (preTaskUpdateInstalled ? chalk8.dim(" Hook script: .claude/hooks/pre-task-update-instructions.sh\n") : "") + (postTaskUpdateInstalled ? chalk8.dim(" Hook script: .claude/hooks/post-task-update-prompt.sh\n") : "");
3619
3650
  return {
3620
3651
  success: true,
3621
3652
  message: buildSuccessMessage(config2, displayPerDir, statusLineMessage + hooksMessage)
@@ -3663,6 +3694,7 @@ async function handleSetupCursor(opts) {
3663
3694
  }
3664
3695
 
3665
3696
  // src/handlers/update.handlers.ts
3697
+ import { execSync as execSync2 } from "child_process";
3666
3698
  import { confirm } from "@inquirer/prompts";
3667
3699
  import chalk9 from "chalk";
3668
3700
 
@@ -3771,6 +3803,18 @@ function executeUpdate(pm, packageName) {
3771
3803
  }
3772
3804
 
3773
3805
  // src/handlers/update.handlers.ts
3806
+ function runSetupSubprocess(subcommand) {
3807
+ try {
3808
+ const output = execSync2(`braingrid setup ${subcommand} --force`, {
3809
+ stdio: "pipe",
3810
+ timeout: 6e4
3811
+ });
3812
+ return output.toString();
3813
+ } catch (error) {
3814
+ const msg = error instanceof Error ? error.message : String(error);
3815
+ return chalk9.yellow(`\u26A0\uFE0F Setup ${subcommand} failed: ${msg}`);
3816
+ }
3817
+ }
3774
3818
  async function promptForIdeUpdates() {
3775
3819
  const cliTools = await checkInstalledCliTools();
3776
3820
  const claudeInstalled = cliTools.find((t) => t.command === "claude")?.installed;
@@ -3782,9 +3826,8 @@ async function promptForIdeUpdates() {
3782
3826
  default: true
3783
3827
  });
3784
3828
  if (shouldUpdate) {
3785
- const result = await handleSetupClaudeCode({ force: true });
3786
3829
  setupOutput += `
3787
- ${result.message}`;
3830
+ ${runSetupSubprocess("claude-code")}`;
3788
3831
  }
3789
3832
  }
3790
3833
  if (cursorInstalled) {
@@ -3793,9 +3836,8 @@ ${result.message}`;
3793
3836
  default: true
3794
3837
  });
3795
3838
  if (shouldUpdate) {
3796
- const result = await handleSetupCursor({ force: true });
3797
3839
  setupOutput += `
3798
- ${result.message}`;
3840
+ ${runSetupSubprocess("cursor")}`;
3799
3841
  }
3800
3842
  }
3801
3843
  return setupOutput;