@braingrid/cli 0.2.34 → 0.2.35
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 +17 -0
- package/dist/cli.js +72 -9
- package/dist/cli.js.map +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,23 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [0.2.35] - 2026-02-14
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
|
|
14
|
+
- **Acceptance criteria extraction in `/build` skill**
|
|
15
|
+
- `/build` now parses the `## Acceptance Criteria` section from requirement content
|
|
16
|
+
- Extracts all criteria into a flat `[]` checklist at `.braingrid/temp/REQ-{id}-acceptance-criteria.md`
|
|
17
|
+
- Handles both flat and sub-sectioned (`###` headings) criteria formats
|
|
18
|
+
- Strips markdown bold formatting and collapses multi-line criteria
|
|
19
|
+
- Added `Write` to allowed tools in build command
|
|
20
|
+
|
|
21
|
+
### Fixed
|
|
22
|
+
|
|
23
|
+
- **Add `create-braingrid-task.sh` to Claude Code sync script**
|
|
24
|
+
- The setup handler was fetching this hook from GitHub but the sync script never pushed it
|
|
25
|
+
- Without this fix, `braingrid setup claude-code` would fail to install the TaskCreate hook
|
|
26
|
+
|
|
10
27
|
## [0.2.34] - 2026-02-05
|
|
11
28
|
|
|
12
29
|
### 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.
|
|
225
|
+
var CLI_VERSION = true ? "0.2.35" : "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,7 @@ 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") {
|
|
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") {
|
|
2683
2683
|
try {
|
|
2684
2684
|
let settings = {};
|
|
2685
2685
|
try {
|
|
@@ -2716,8 +2716,58 @@ async function updateClaudeSettings(settingsPath = ".claude/settings.json", scri
|
|
|
2716
2716
|
} else {
|
|
2717
2717
|
mergedPostToolUse = [...existingPostToolUse, ourHookEntry];
|
|
2718
2718
|
}
|
|
2719
|
+
const ourCreateHookEntry = {
|
|
2720
|
+
matcher: "TaskCreate",
|
|
2721
|
+
hooks: [
|
|
2722
|
+
{
|
|
2723
|
+
type: "command",
|
|
2724
|
+
command: createHookScriptPath,
|
|
2725
|
+
timeout: 1e4
|
|
2726
|
+
}
|
|
2727
|
+
]
|
|
2728
|
+
};
|
|
2729
|
+
const taskCreatePostIdx = mergedPostToolUse.findIndex((e) => e.matcher === "TaskCreate");
|
|
2730
|
+
if (taskCreatePostIdx >= 0) {
|
|
2731
|
+
mergedPostToolUse[taskCreatePostIdx] = ourCreateHookEntry;
|
|
2732
|
+
} else {
|
|
2733
|
+
mergedPostToolUse = [...mergedPostToolUse, ourCreateHookEntry];
|
|
2734
|
+
}
|
|
2735
|
+
const ourPreToolUseEntry = {
|
|
2736
|
+
matcher: "TaskCreate",
|
|
2737
|
+
hooks: [
|
|
2738
|
+
{
|
|
2739
|
+
type: "prompt",
|
|
2740
|
+
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"
|
|
2741
|
+
}
|
|
2742
|
+
]
|
|
2743
|
+
};
|
|
2744
|
+
const existingPreToolUse = Array.isArray(existingHooks.PreToolUse) ? existingHooks.PreToolUse : [];
|
|
2745
|
+
const taskCreateIdx = existingPreToolUse.findIndex((e) => e.matcher === "TaskCreate");
|
|
2746
|
+
let mergedPreToolUse;
|
|
2747
|
+
if (taskCreateIdx >= 0) {
|
|
2748
|
+
mergedPreToolUse = [...existingPreToolUse];
|
|
2749
|
+
mergedPreToolUse[taskCreateIdx] = ourPreToolUseEntry;
|
|
2750
|
+
} else {
|
|
2751
|
+
mergedPreToolUse = [...existingPreToolUse, ourPreToolUseEntry];
|
|
2752
|
+
}
|
|
2753
|
+
const ourPreToolUseTaskUpdateEntry = {
|
|
2754
|
+
matcher: "TaskUpdate",
|
|
2755
|
+
hooks: [
|
|
2756
|
+
{
|
|
2757
|
+
type: "prompt",
|
|
2758
|
+
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"
|
|
2759
|
+
}
|
|
2760
|
+
]
|
|
2761
|
+
};
|
|
2762
|
+
const taskUpdatePreIdx = mergedPreToolUse.findIndex((e) => e.matcher === "TaskUpdate");
|
|
2763
|
+
if (taskUpdatePreIdx >= 0) {
|
|
2764
|
+
mergedPreToolUse[taskUpdatePreIdx] = ourPreToolUseTaskUpdateEntry;
|
|
2765
|
+
} else {
|
|
2766
|
+
mergedPreToolUse = [...mergedPreToolUse, ourPreToolUseTaskUpdateEntry];
|
|
2767
|
+
}
|
|
2719
2768
|
settings.hooks = {
|
|
2720
2769
|
...existingHooks,
|
|
2770
|
+
PreToolUse: mergedPreToolUse,
|
|
2721
2771
|
PostToolUse: mergedPostToolUse
|
|
2722
2772
|
};
|
|
2723
2773
|
const parentDir = path2.dirname(settingsPath);
|
|
@@ -3416,28 +3466,41 @@ async function _handleSetup(config2, opts) {
|
|
|
3416
3466
|
);
|
|
3417
3467
|
}
|
|
3418
3468
|
}
|
|
3419
|
-
let
|
|
3469
|
+
let syncHookInstalled = false;
|
|
3470
|
+
let createHookInstalled = false;
|
|
3420
3471
|
if (config2.name === "Claude Code") {
|
|
3421
3472
|
try {
|
|
3422
|
-
const
|
|
3423
|
-
await installHookScript(
|
|
3424
|
-
|
|
3473
|
+
const syncContent = await fetchFileFromGitHub("claude-code/hooks/sync-braingrid-task.sh");
|
|
3474
|
+
await installHookScript(syncContent);
|
|
3475
|
+
syncHookInstalled = true;
|
|
3476
|
+
} catch (error) {
|
|
3477
|
+
console.error(
|
|
3478
|
+
chalk8.yellow("\u26A0\uFE0F Failed to install sync hook:"),
|
|
3479
|
+
error instanceof Error ? error.message : String(error)
|
|
3480
|
+
);
|
|
3481
|
+
}
|
|
3482
|
+
try {
|
|
3483
|
+
const createContent = await fetchFileFromGitHub(
|
|
3484
|
+
"claude-code/hooks/create-braingrid-task.sh"
|
|
3485
|
+
);
|
|
3486
|
+
await installHookScript(createContent, ".claude/hooks/create-braingrid-task.sh");
|
|
3487
|
+
createHookInstalled = true;
|
|
3425
3488
|
} catch (error) {
|
|
3426
3489
|
console.error(
|
|
3427
|
-
chalk8.yellow("\u26A0\uFE0F Failed to install hook
|
|
3490
|
+
chalk8.yellow("\u26A0\uFE0F Failed to install create hook:"),
|
|
3428
3491
|
error instanceof Error ? error.message : String(error)
|
|
3429
3492
|
);
|
|
3430
3493
|
}
|
|
3431
3494
|
}
|
|
3432
3495
|
await copyBraingridReadme();
|
|
3433
3496
|
const statusLineMessage = statusLineInstalled ? chalk8.dim(" Status line: .claude/statusline.sh\n") : "";
|
|
3434
|
-
const
|
|
3497
|
+
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") : "");
|
|
3435
3498
|
return {
|
|
3436
3499
|
success: true,
|
|
3437
3500
|
message: chalk8.green(`\u2705 ${config2.name} integration installed successfully!
|
|
3438
3501
|
|
|
3439
3502
|
`) + chalk8.dim("Files installed:\n") + chalk8.dim(` Commands: ${result.installed} files
|
|
3440
|
-
`) + statusLineMessage +
|
|
3503
|
+
`) + statusLineMessage + hooksMessage + chalk8.dim(` Content injected into: ${config2.injection.targetFile}
|
|
3441
3504
|
|
|
3442
3505
|
`) + chalk8.dim("Next steps:\n") + chalk8.dim(" 1. Review the integration files\n") + chalk8.dim(` 2. Open ${config2.name}
|
|
3443
3506
|
`) + chalk8.dim(" 3. Try the /specify or /breakdown commands\n") + chalk8.dim(" 4. Learn more: ") + chalk8.cyan(config2.docsUrl)
|