@braingrid/cli 0.2.0 → 0.2.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.
Files changed (219) hide show
  1. package/CHANGELOG.md +60 -0
  2. package/README.md +55 -39
  3. package/dist/chunk-KNVWIF3L.js +401 -0
  4. package/dist/chunk-KNVWIF3L.js.map +1 -0
  5. package/dist/cli.js +6236 -245
  6. package/dist/cli.js.map +1 -1
  7. package/dist/gh-installer-B65ZOOC4.js +13 -0
  8. package/dist/gh-installer-B65ZOOC4.js.map +1 -0
  9. package/package.json +19 -11
  10. package/dist/build-config.d.ts +0 -26
  11. package/dist/build-config.d.ts.map +0 -1
  12. package/dist/build-config.js +0 -45
  13. package/dist/build-config.js.map +0 -1
  14. package/dist/cli.d.ts +0 -3
  15. package/dist/cli.d.ts.map +0 -1
  16. package/dist/handlers/auth.handlers.d.ts +0 -13
  17. package/dist/handlers/auth.handlers.d.ts.map +0 -1
  18. package/dist/handlers/auth.handlers.js +0 -111
  19. package/dist/handlers/auth.handlers.js.map +0 -1
  20. package/dist/handlers/index.d.ts +0 -13
  21. package/dist/handlers/index.d.ts.map +0 -1
  22. package/dist/handlers/index.js +0 -13
  23. package/dist/handlers/index.js.map +0 -1
  24. package/dist/handlers/init.handlers.d.ts +0 -10
  25. package/dist/handlers/init.handlers.d.ts.map +0 -1
  26. package/dist/handlers/init.handlers.js +0 -638
  27. package/dist/handlers/init.handlers.js.map +0 -1
  28. package/dist/handlers/project.handlers.d.ts +0 -36
  29. package/dist/handlers/project.handlers.d.ts.map +0 -1
  30. package/dist/handlers/project.handlers.js +0 -309
  31. package/dist/handlers/project.handlers.js.map +0 -1
  32. package/dist/handlers/requirement.handlers.d.ts +0 -32
  33. package/dist/handlers/requirement.handlers.d.ts.map +0 -1
  34. package/dist/handlers/requirement.handlers.js +0 -264
  35. package/dist/handlers/requirement.handlers.js.map +0 -1
  36. package/dist/handlers/status.handlers.d.ts +0 -12
  37. package/dist/handlers/status.handlers.d.ts.map +0 -1
  38. package/dist/handlers/status.handlers.js +0 -212
  39. package/dist/handlers/status.handlers.js.map +0 -1
  40. package/dist/handlers/task.handlers.d.ts +0 -29
  41. package/dist/handlers/task.handlers.d.ts.map +0 -1
  42. package/dist/handlers/task.handlers.js +0 -326
  43. package/dist/handlers/task.handlers.js.map +0 -1
  44. package/dist/handlers/types.d.ts +0 -10
  45. package/dist/handlers/types.d.ts.map +0 -1
  46. package/dist/handlers/types.js +0 -5
  47. package/dist/handlers/types.js.map +0 -1
  48. package/dist/handlers/update.handlers.d.ts +0 -16
  49. package/dist/handlers/update.handlers.d.ts.map +0 -1
  50. package/dist/handlers/update.handlers.js +0 -119
  51. package/dist/handlers/update.handlers.js.map +0 -1
  52. package/dist/services/auth.d.ts +0 -59
  53. package/dist/services/auth.d.ts.map +0 -1
  54. package/dist/services/auth.js +0 -549
  55. package/dist/services/auth.js.map +0 -1
  56. package/dist/services/claude.d.ts +0 -18
  57. package/dist/services/claude.d.ts.map +0 -1
  58. package/dist/services/claude.js +0 -164
  59. package/dist/services/claude.js.map +0 -1
  60. package/dist/services/credential-store.d.ts +0 -47
  61. package/dist/services/credential-store.d.ts.map +0 -1
  62. package/dist/services/credential-store.js +0 -89
  63. package/dist/services/credential-store.js.map +0 -1
  64. package/dist/services/internal/github-service.d.ts +0 -67
  65. package/dist/services/internal/github-service.d.ts.map +0 -1
  66. package/dist/services/internal/github-service.js +0 -81
  67. package/dist/services/internal/github-service.js.map +0 -1
  68. package/dist/services/internal/repository-service.d.ts +0 -79
  69. package/dist/services/internal/repository-service.d.ts.map +0 -1
  70. package/dist/services/internal/repository-service.js +0 -88
  71. package/dist/services/internal/repository-service.js.map +0 -1
  72. package/dist/services/oauth2-auth.d.ts +0 -76
  73. package/dist/services/oauth2-auth.d.ts.map +0 -1
  74. package/dist/services/oauth2-auth.js +0 -451
  75. package/dist/services/oauth2-auth.js.map +0 -1
  76. package/dist/services/project-service.d.ts +0 -24
  77. package/dist/services/project-service.d.ts.map +0 -1
  78. package/dist/services/project-service.js +0 -60
  79. package/dist/services/project-service.js.map +0 -1
  80. package/dist/services/requirement-service.d.ts +0 -32
  81. package/dist/services/requirement-service.d.ts.map +0 -1
  82. package/dist/services/requirement-service.js +0 -91
  83. package/dist/services/requirement-service.js.map +0 -1
  84. package/dist/services/task-service.d.ts +0 -22
  85. package/dist/services/task-service.d.ts.map +0 -1
  86. package/dist/services/task-service.js +0 -52
  87. package/dist/services/task-service.js.map +0 -1
  88. package/dist/types/api.d.ts +0 -16
  89. package/dist/types/api.d.ts.map +0 -1
  90. package/dist/types/api.js +0 -5
  91. package/dist/types/api.js.map +0 -1
  92. package/dist/types/auth.d.ts +0 -73
  93. package/dist/types/auth.d.ts.map +0 -1
  94. package/dist/types/auth.js +0 -2
  95. package/dist/types/auth.js.map +0 -1
  96. package/dist/types/claude.d.ts +0 -22
  97. package/dist/types/claude.d.ts.map +0 -1
  98. package/dist/types/claude.js +0 -2
  99. package/dist/types/claude.js.map +0 -1
  100. package/dist/types/github.d.ts +0 -105
  101. package/dist/types/github.d.ts.map +0 -1
  102. package/dist/types/github.js +0 -6
  103. package/dist/types/github.js.map +0 -1
  104. package/dist/types/local-project.d.ts +0 -30
  105. package/dist/types/local-project.d.ts.map +0 -1
  106. package/dist/types/local-project.js +0 -24
  107. package/dist/types/local-project.js.map +0 -1
  108. package/dist/types/project.d.ts +0 -56
  109. package/dist/types/project.d.ts.map +0 -1
  110. package/dist/types/project.js +0 -5
  111. package/dist/types/project.js.map +0 -1
  112. package/dist/types/requirement.d.ts +0 -69
  113. package/dist/types/requirement.d.ts.map +0 -1
  114. package/dist/types/requirement.js +0 -5
  115. package/dist/types/requirement.js.map +0 -1
  116. package/dist/types/task.d.ts +0 -44
  117. package/dist/types/task.d.ts.map +0 -1
  118. package/dist/types/task.js +0 -5
  119. package/dist/types/task.js.map +0 -1
  120. package/dist/utils/axios-retry.d.ts +0 -25
  121. package/dist/utils/axios-retry.d.ts.map +0 -1
  122. package/dist/utils/axios-retry.js +0 -174
  123. package/dist/utils/axios-retry.js.map +0 -1
  124. package/dist/utils/axios-with-auth.d.ts +0 -10
  125. package/dist/utils/axios-with-auth.d.ts.map +0 -1
  126. package/dist/utils/axios-with-auth.js +0 -118
  127. package/dist/utils/axios-with-auth.js.map +0 -1
  128. package/dist/utils/cli-tools.d.ts +0 -30
  129. package/dist/utils/cli-tools.d.ts.map +0 -1
  130. package/dist/utils/cli-tools.js +0 -199
  131. package/dist/utils/cli-tools.js.map +0 -1
  132. package/dist/utils/command-execution.d.ts +0 -30
  133. package/dist/utils/command-execution.d.ts.map +0 -1
  134. package/dist/utils/command-execution.js +0 -264
  135. package/dist/utils/command-execution.js.map +0 -1
  136. package/dist/utils/command-parser.d.ts +0 -85
  137. package/dist/utils/command-parser.d.ts.map +0 -1
  138. package/dist/utils/command-parser.js +0 -287
  139. package/dist/utils/command-parser.js.map +0 -1
  140. package/dist/utils/config.d.ts +0 -10
  141. package/dist/utils/config.d.ts.map +0 -1
  142. package/dist/utils/config.js +0 -77
  143. package/dist/utils/config.js.map +0 -1
  144. package/dist/utils/error-formatter.d.ts +0 -17
  145. package/dist/utils/error-formatter.d.ts.map +0 -1
  146. package/dist/utils/error-formatter.js +0 -115
  147. package/dist/utils/error-formatter.js.map +0 -1
  148. package/dist/utils/formatting.d.ts +0 -10
  149. package/dist/utils/formatting.d.ts.map +0 -1
  150. package/dist/utils/formatting.js +0 -122
  151. package/dist/utils/formatting.js.map +0 -1
  152. package/dist/utils/gh-installer.d.ts +0 -31
  153. package/dist/utils/gh-installer.d.ts.map +0 -1
  154. package/dist/utils/gh-installer.js +0 -296
  155. package/dist/utils/gh-installer.js.map +0 -1
  156. package/dist/utils/git-installer.d.ts +0 -31
  157. package/dist/utils/git-installer.d.ts.map +0 -1
  158. package/dist/utils/git-installer.js +0 -290
  159. package/dist/utils/git-installer.js.map +0 -1
  160. package/dist/utils/git.d.ts +0 -60
  161. package/dist/utils/git.d.ts.map +0 -1
  162. package/dist/utils/git.js +0 -144
  163. package/dist/utils/git.js.map +0 -1
  164. package/dist/utils/github-repo.d.ts +0 -43
  165. package/dist/utils/github-repo.d.ts.map +0 -1
  166. package/dist/utils/github-repo.js +0 -113
  167. package/dist/utils/github-repo.js.map +0 -1
  168. package/dist/utils/id-normalization.d.ts +0 -26
  169. package/dist/utils/id-normalization.d.ts.map +0 -1
  170. package/dist/utils/id-normalization.js +0 -45
  171. package/dist/utils/id-normalization.js.map +0 -1
  172. package/dist/utils/jwt.d.ts +0 -45
  173. package/dist/utils/jwt.d.ts.map +0 -1
  174. package/dist/utils/jwt.js +0 -64
  175. package/dist/utils/jwt.js.map +0 -1
  176. package/dist/utils/local-store.d.ts +0 -36
  177. package/dist/utils/local-store.d.ts.map +0 -1
  178. package/dist/utils/local-store.js +0 -94
  179. package/dist/utils/local-store.js.map +0 -1
  180. package/dist/utils/logger.d.ts +0 -36
  181. package/dist/utils/logger.d.ts.map +0 -1
  182. package/dist/utils/logger.js +0 -176
  183. package/dist/utils/logger.js.map +0 -1
  184. package/dist/utils/package-manager-installer.d.ts +0 -36
  185. package/dist/utils/package-manager-installer.d.ts.map +0 -1
  186. package/dist/utils/package-manager-installer.js +0 -106
  187. package/dist/utils/package-manager-installer.js.map +0 -1
  188. package/dist/utils/package-manager.d.ts +0 -31
  189. package/dist/utils/package-manager.d.ts.map +0 -1
  190. package/dist/utils/package-manager.js +0 -133
  191. package/dist/utils/package-manager.js.map +0 -1
  192. package/dist/utils/projects.d.ts +0 -23
  193. package/dist/utils/projects.d.ts.map +0 -1
  194. package/dist/utils/projects.js +0 -36
  195. package/dist/utils/projects.js.map +0 -1
  196. package/dist/utils/repository-access.d.ts +0 -89
  197. package/dist/utils/repository-access.d.ts.map +0 -1
  198. package/dist/utils/repository-access.js +0 -132
  199. package/dist/utils/repository-access.js.map +0 -1
  200. package/dist/utils/requirements.d.ts +0 -43
  201. package/dist/utils/requirements.d.ts.map +0 -1
  202. package/dist/utils/requirements.js +0 -79
  203. package/dist/utils/requirements.js.map +0 -1
  204. package/dist/utils/spinner.d.ts +0 -47
  205. package/dist/utils/spinner.d.ts.map +0 -1
  206. package/dist/utils/spinner.js +0 -101
  207. package/dist/utils/spinner.js.map +0 -1
  208. package/dist/utils/status-parser.d.ts +0 -95
  209. package/dist/utils/status-parser.d.ts.map +0 -1
  210. package/dist/utils/status-parser.js +0 -205
  211. package/dist/utils/status-parser.js.map +0 -1
  212. package/dist/utils/tasks.d.ts +0 -21
  213. package/dist/utils/tasks.d.ts.map +0 -1
  214. package/dist/utils/tasks.js +0 -63
  215. package/dist/utils/tasks.js.map +0 -1
  216. package/dist/utils/workspace-manager.d.ts +0 -65
  217. package/dist/utils/workspace-manager.d.ts.map +0 -1
  218. package/dist/utils/workspace-manager.js +0 -98
  219. package/dist/utils/workspace-manager.js.map +0 -1
package/CHANGELOG.md CHANGED
@@ -5,6 +5,66 @@ All notable changes to this project will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [0.2.2] - 2025-11-10
9
+
10
+ ### Added
11
+
12
+ - Concise BrainGrid documentation for project injection (`.claude/CLAUDE.md`)
13
+ - 42-line section explaining BrainGrid workflow for Claude Code
14
+ - Slash commands reference and typical workflow
15
+ - Key features (auto-detection, reactive errors, status flows, output formats)
16
+ - BrainGrid CLI slash commands for Claude Code
17
+ - `/specify [prompt]` - Create AI-refined requirement from vague idea
18
+ - `/save-requirement [title]` - Save detailed plan as requirement
19
+ - `/breakdown [req-id]` - Break requirement into AI-prompted tasks
20
+ - `/build [req-id]` - Get complete implementation plan in markdown
21
+ - `/cut-release [patch|minor|major]` - Automate NPM release workflow
22
+ - BrainGrid CLI skill for Claude Code with comprehensive workflow guidance
23
+ - Installation instructions in braingrid-cli skill
24
+ - BrainGrid project configuration files
25
+
26
+ ### Changed
27
+
28
+ - Updated README tagline capitalization
29
+
30
+ ### Fixed
31
+
32
+ - Removed unsupported `--status` field from `/save-requirement` slash command
33
+ - API does not accept status field during requirement creation
34
+ - Status is set automatically by the backend
35
+
36
+ ## [0.2.1] - 2025-01-07
37
+
38
+ ### Added
39
+
40
+ - Repository linking support for `project create` command
41
+ - New `--repository-id <uuid>` option to link project by repository UUID
42
+ - New `--repository <owner/name>` option to link project by repository name (e.g., `microsoft/vscode`)
43
+ - Automatic repository UUID lookup when using owner/name format
44
+ - Repository ID takes precedence when both options provided
45
+ - Requirement ID auto-detection from git branch names
46
+ - CLI automatically detects requirement ID from branch patterns like `feature/REQ-123-description` or `REQ-123-fix-bug`
47
+ - Eliminates need to manually specify `-r` parameter in most cases
48
+ - Branch field in requirement list output
49
+ - Shows which git branch is assigned to each requirement
50
+
51
+ ### Changed
52
+
53
+ - Enhanced requirement output with URL and consistent field display
54
+ - Improved README documentation wording and fixed numbered list in quickstart section
55
+
56
+ ### Fixed
57
+
58
+ - All error messages now consistently display with red color and single ❌ emoji
59
+ - Task command documentation and parameter formats
60
+
61
+ ### Removed
62
+
63
+ - Complexity and readiness fields from requirements and tasks
64
+ - Removed from TypeScript type definitions
65
+ - Removed from all test mock data
66
+ - CLI no longer displays or accepts these fields (API still returns them but they are ignored)
67
+
8
68
  ## [0.2.0] - 2025-11-04
9
69
 
10
70
  ### Changed
package/README.md CHANGED
@@ -2,8 +2,8 @@
2
2
  <img src="https://www.braingrid.ai/logos/braingrid-symbol-800.png" width="100"/>
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.</h3>
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>
7
7
 
8
8
  [![npm version](https://img.shields.io/npm/v/@braingrid/cli.svg?color=blue&logo=npm)](https://www.npmjs.com/package/@braingrid/cli)
9
9
  [![Downloads](https://img.shields.io/npm/dm/@braingrid/cli.svg?color=green)](https://www.npmjs.com/package/@braingrid/cli)
@@ -15,19 +15,17 @@
15
15
 
16
16
  ## Overview
17
17
 
18
- **BrainGrid** helps you turn half-baked thoughts into build-ready specs and perfectly-prompted tasks that AI coding agents like Cursor, or Claude Code, can build fast without breaking things.
18
+ **BrainGrid** helps you turn half-baked thoughts into build-ready specs and perfectly-prompted tasks that AI coding agents like Cursor, or Claude Code, build fast without breaking things.
19
19
 
20
20
  ## Features
21
21
 
22
22
  **BrainGrid CLI** is the command-line interface for managing your requirements, and tasks on the BrainGrid platform.
23
23
 
24
- - 📋 **Add Requirements to Your Backlog** - Create requirements from prompts and link to repositories
25
- - ✨ **Refine Requirements** - Update and manage requirements to get them build-ready
24
+ - **Specify Requirements** - Create build-ready requirement documents from messy ideas
26
25
  - 🎯 **Break Down into Tasks** - Create perfectly-prompted tasks from requirements
27
- - 🤖 **Fetch Tasks for AI Agents** - Get task prompts to feed to Cursor, Claude Code, and other AI coding tools
26
+ - 🤖 **Build with AI Agents** - Get an implementation plan with prompts for each task to feed to Cursor, Claude Code, and other AI coding tools
28
27
  - 📊 **Track Progress** - Manage and update task statuses
29
- - 💾 **Multiple Output Formats** - View data as formatted tables or JSON for scripting
30
- - 🔍 **Environment Detection** - Automatically detect git repository info and installed AI coding tools
28
+ - 💾 **Multiple Output Formats** - View task prompts as formatted tables, JSON, Markdown, or XML for scripting
31
29
 
32
30
  ---
33
31
 
@@ -37,12 +35,6 @@
37
35
  npm install -g @braingrid/cli
38
36
  ```
39
37
 
40
- > **Requirements:** Node.js 20+ and Git
41
- >
42
- > **Note:** If Git is not installed, the CLI will offer to install it automatically when you run `braingrid init`.
43
- >
44
- > **Recommended:** GitHub CLI (`gh`) is highly recommended for seamless GitHub integration. The CLI will offer to install it during initialization.
45
-
46
38
  ---
47
39
 
48
40
  ## QuickStart: One-Minute Flow
@@ -51,17 +43,14 @@ npm install -g @braingrid/cli
51
43
  # 1. Initialize your project
52
44
  braingrid init
53
45
 
54
- # 3. Create a requirement
55
- braingrid requirement create --prompt "Add user authentication"
56
-
57
- # 4. List requirements
58
- braingrid requirement list
46
+ # 2. Create a requirement with AI refinement
47
+ braingrid specify --prompt "Add user authentication"
59
48
 
60
- # 5. Create tasks for a requirement
61
- braingrid task create -r REQ-1 --title "Implement login endpoint"
49
+ # 3. Break down requirement into tasks with AI
50
+ braingrid requirement breakdown REQ-1
62
51
 
63
- # 6. View tasks for a requirement
64
- braingrid task list -r REQ-1
52
+ # 4. Build requirement with all tasks (markdown with full content)
53
+ braingrid requirement build REQ-1
65
54
  ```
66
55
 
67
56
  ---
@@ -83,7 +72,7 @@ braingrid logout
83
72
  Initialize your repository with a BrainGrid project. The command will show you the detected project and ask for confirmation before proceeding:
84
73
 
85
74
  ```bash
86
- # Step-by-step wirzard to initialize your project
75
+ # Step-by-step wizard to initialize your project
87
76
  braingrid init
88
77
 
89
78
  # Manually specify project by ID (short ID or UUID)
@@ -104,46 +93,73 @@ The `init` command creates a `.braingrid/project.json` file in the `.braingrid/`
104
93
  braingrid project list [--format json] [--page 1] [--limit 20]
105
94
  braingrid project show
106
95
  braingrid project show [<id>] [--repository "owner/repo"]
107
- braingrid project create --name "Project Name" [--description "Description"] [--repository "owner/repo"]
96
+ braingrid project create --name "Project Name" [--description "Description"] [--repository-id <uuid>] [--repository "owner/name"]
108
97
  braingrid project update <id> [--name "New Name"] [--description "New Description"]
109
98
  braingrid project delete <id> [--force]
110
99
  ```
111
100
 
112
101
  > **Note:** `project show` displays the initialized project from your workspace when called without arguments. Use `--repository "owner/repo"` to list all projects for a specific repository, or provide a project ID directly to view a specific project.
102
+ >
103
+ > **Note:** When creating a project, you can optionally link it to a repository using `--repository-id <uuid>` to link by repository UUID, or `--repository "owner/name"` (e.g., `--repository "microsoft/vscode"`) to link by repository name. If `--repository-id` is provided, it takes precedence.
113
104
 
114
105
  ### Requirement Commands
115
106
 
116
107
  ```bash
117
- # After running braingrid init (project auto-detected):
118
- braingrid requirement list [--status PLANNED|IN_PROGRESS|COMPLETED|CANCELLED] [--format json]
119
- braingrid requirement create --prompt "Requirement description" [--repository "owner/repo"]
120
- braingrid requirement show <id>
121
- braingrid requirement update <id> [--status STATUS] [--name "New Name"]
122
- braingrid requirement delete <id> [--force]
108
+ # Create requirement with AI refinement (specify command)
109
+ # With auto-detected project from workspace:
110
+ braingrid specify --prompt "Add user authentication with OAuth2"
111
+
112
+ # Specify project explicitly:
113
+ braingrid specify -p PROJ-123 --prompt "Implement real-time notifications"
114
+
115
+ # Output in different formats:
116
+ braingrid specify --prompt "Add dark mode support" --format json
117
+ braingrid specify --prompt "Add export feature" --format markdown
118
+
119
+ # Working with the initialized project
120
+ braingrid requirement list [--status IDEA|PLANNED|IN_PROGRESS|REVIEW|COMPLETED|CANCELLED] [--format json]
121
+ braingrid requirement create --name "Name" [--content "Description"] [--assigned-to <uuid>]
122
+ braingrid requirement show [id]
123
+ braingrid requirement update [id] [--status IDEA|PLANNED|IN_PROGRESS|REVIEW|COMPLETED|CANCELLED] [--name "New Name"]
124
+ braingrid requirement delete [id] [--force]
125
+ braingrid requirement breakdown [id] [--verbose]
126
+ braingrid requirement build [id] [--format markdown|json|xml]
123
127
 
124
128
  # Working with a different project:
125
129
  braingrid requirement list -p PROJ-456 [--status PLANNED]
126
- braingrid requirement create -p PROJ-456 --prompt "Description"
130
+ braingrid requirement create -p PROJ-456 --name "Description"
127
131
  ```
128
132
 
129
133
  > **Note:** The `-p`/`--project` parameter is optional when working in an initialized repository. Use it to work with a different project.
134
+ >
135
+ > **Note:** For the `specify` command, the prompt must be between 10-5000 characters. The AI will refine your prompt into a detailed requirement document.
136
+ >
137
+ > **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.
138
+ >
139
+ > **Note:** The `requirement list` command displays requirements with their status, name, branch (if assigned), and progress percentage.
130
140
 
131
141
  ### Task Commands
132
142
 
133
143
  ```bash
134
- # After running braingrid init (project auto-detected):
135
- braingrid task list -r REQ-456 [--format json]
144
+ # Working with the initialized project
145
+ braingrid task list -r REQ-456 [--format table|json|xml|markdown] [--verbose]
136
146
  braingrid task create -r REQ-456 --title "Task Title" [--content "Description"]
137
147
  braingrid task show <id>
138
- braingrid task update <id> [--status STATUS] [--title "New Title"]
148
+ braingrid task update <id> [--status PLANNED|IN_PROGRESS|COMPLETED|CANCELLED] [--title "New Title"]
139
149
  braingrid task delete <id> [--force]
140
150
 
141
- # Working with a different project (full format):
142
- braingrid task list -r PROJ-123/REQ-456
143
- braingrid task create -r PROJ-123/REQ-456 --title "Task Title"
151
+ # Working with a different project:
152
+ braingrid task list -p PROJ-123 -r REQ-456
153
+ braingrid task create -p PROJ-123 -r REQ-456 --title "Task Title"
144
154
  ```
145
155
 
146
- > **Note:** The `-r`/`--requirement` parameter accepts either `REQ-456` (auto-detects project from `.braingrid/project.json`) or full format `PROJ-123/REQ-456` for working with other projects.
156
+ > **Note:** The `-p`/`--project` parameter is optional when working in an initialized repository. Use it to work with a different project.
157
+ >
158
+ > **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.
159
+ >
160
+ > **Note:** Use `--verbose` with `task list` to show full task content in addition to task metadata.
161
+ >
162
+ > **Note:** Task status values are: `PLANNED`, `IN_PROGRESS`, `COMPLETED`, `CANCELLED` (tasks do not have `IDEA` or `REVIEW` status).
147
163
 
148
164
  ### Informational Commands
149
165
 
@@ -0,0 +1,401 @@
1
+ // src/utils/gh-installer.ts
2
+ import { exec as exec3 } from "child_process";
3
+ import { promisify as promisify3 } from "util";
4
+ import chalk from "chalk";
5
+
6
+ // src/utils/cli-tools.ts
7
+ import { exec } from "child_process";
8
+ import { promisify } from "util";
9
+ import { access, constants } from "fs/promises";
10
+ import { homedir } from "os";
11
+ import { join } from "path";
12
+ var execAsync = promisify(exec);
13
+ var CLAUDE_LOCAL_PATH = join(homedir(), ".claude", "local", "claude");
14
+ async function checkClaudeInstalled() {
15
+ try {
16
+ await access(CLAUDE_LOCAL_PATH, constants.X_OK);
17
+ return true;
18
+ } catch {
19
+ }
20
+ try {
21
+ await execAsync("claude --version 2>&1", { timeout: 2e3 });
22
+ return true;
23
+ } catch {
24
+ }
25
+ return isCliInstalled("claude");
26
+ }
27
+ async function getClaudeVersion() {
28
+ try {
29
+ await access(CLAUDE_LOCAL_PATH, constants.X_OK);
30
+ const result = await execAsync(`"${CLAUDE_LOCAL_PATH}" --version 2>&1`, {
31
+ timeout: 2e3
32
+ });
33
+ const output = result.stdout || result.stderr;
34
+ const match = output.match(/([\d.]+)/);
35
+ return match ? match[1] : null;
36
+ } catch {
37
+ }
38
+ return getCliVersion("claude", "--version", (output) => {
39
+ const match = output.match(/([\d.]+)/);
40
+ return match ? match[1] : null;
41
+ });
42
+ }
43
+ var CLI_TOOLS = [
44
+ {
45
+ name: "Git",
46
+ command: "git",
47
+ versionFlag: "--version",
48
+ versionParser: (output) => {
49
+ const match = output.match(/git version ([\d.]+)/);
50
+ return match ? match[1] : null;
51
+ }
52
+ },
53
+ {
54
+ name: "GitHub CLI",
55
+ command: "gh",
56
+ versionFlag: "--version",
57
+ versionParser: (output) => {
58
+ const match = output.match(/gh version ([\d.]+)/);
59
+ return match ? match[1] : null;
60
+ }
61
+ },
62
+ {
63
+ name: "Claude Code",
64
+ command: "claude",
65
+ specialCheck: checkClaudeInstalled,
66
+ specialVersionCheck: getClaudeVersion,
67
+ versionFlag: "--version",
68
+ versionParser: (output) => {
69
+ const match = output.match(/([\d.]+)/);
70
+ return match ? match[1] : null;
71
+ }
72
+ }
73
+ ];
74
+ async function isCliInstalled(command) {
75
+ try {
76
+ if (process.platform === "win32") {
77
+ await execAsync(`where ${command}`, { timeout: 2e3 });
78
+ } else {
79
+ await execAsync(`which ${command} 2>/dev/null`, { timeout: 2e3 });
80
+ }
81
+ return true;
82
+ } catch {
83
+ return false;
84
+ }
85
+ }
86
+ async function getCliVersion(command, versionFlag = "--version", parser) {
87
+ try {
88
+ const result = await execAsync(`${command} ${versionFlag} 2>&1`, {
89
+ timeout: 2e3
90
+ });
91
+ const output = result.stdout || result.stderr;
92
+ if (parser) {
93
+ return parser(output);
94
+ }
95
+ return output.trim().split("\n")[0] || null;
96
+ } catch {
97
+ return null;
98
+ }
99
+ }
100
+ async function checkCliTool(config) {
101
+ const installed = config.specialCheck ? await config.specialCheck() : await isCliInstalled(config.command);
102
+ if (!installed) {
103
+ return {
104
+ name: config.name,
105
+ command: config.command,
106
+ installed: false
107
+ };
108
+ }
109
+ let version;
110
+ if (config.specialVersionCheck) {
111
+ const versionStr = await config.specialVersionCheck();
112
+ if (versionStr) {
113
+ version = versionStr;
114
+ }
115
+ } else if (config.versionFlag) {
116
+ const versionStr = await getCliVersion(
117
+ config.command,
118
+ config.versionFlag,
119
+ config.versionParser
120
+ );
121
+ if (versionStr) {
122
+ version = versionStr;
123
+ }
124
+ }
125
+ return {
126
+ name: config.name,
127
+ command: config.command,
128
+ installed: true,
129
+ version
130
+ };
131
+ }
132
+ async function checkInstalledCliTools() {
133
+ try {
134
+ const results = await Promise.all(CLI_TOOLS.map((config) => checkCliTool(config)));
135
+ return results;
136
+ } catch {
137
+ return CLI_TOOLS.map((config) => ({
138
+ name: config.name,
139
+ command: config.command,
140
+ installed: false
141
+ }));
142
+ }
143
+ }
144
+
145
+ // src/utils/package-manager-installer.ts
146
+ import { exec as exec2 } from "child_process";
147
+ import { promisify as promisify2 } from "util";
148
+ var execAsync2 = promisify2(exec2);
149
+ async function isHomebrewInstalled() {
150
+ if (process.platform !== "darwin") {
151
+ return false;
152
+ }
153
+ try {
154
+ await execAsync2("which brew", { timeout: 2e3 });
155
+ return true;
156
+ } catch {
157
+ return false;
158
+ }
159
+ }
160
+ async function isWingetAvailable() {
161
+ if (process.platform !== "win32") {
162
+ return false;
163
+ }
164
+ try {
165
+ await execAsync2("winget --version", { timeout: 2e3 });
166
+ return true;
167
+ } catch {
168
+ return false;
169
+ }
170
+ }
171
+ async function detectLinuxPackageManager() {
172
+ if (process.platform !== "linux") {
173
+ return null;
174
+ }
175
+ const packageManagers = [
176
+ { name: "apt", command: "apt-get", available: false },
177
+ { name: "dnf", command: "dnf", available: false },
178
+ { name: "yum", command: "yum", available: false },
179
+ { name: "pacman", command: "pacman", available: false }
180
+ ];
181
+ for (const pm of packageManagers) {
182
+ try {
183
+ await execAsync2(`which ${pm.command}`, { timeout: 2e3 });
184
+ return { ...pm, available: true };
185
+ } catch {
186
+ }
187
+ }
188
+ return null;
189
+ }
190
+
191
+ // src/utils/gh-installer.ts
192
+ var execAsync3 = promisify3(exec3);
193
+ async function isGhInstalled() {
194
+ return isCliInstalled("gh");
195
+ }
196
+ async function getGhVersion() {
197
+ return getCliVersion("gh", "--version", (output) => {
198
+ const match = output.match(/gh version ([\d.]+)/);
199
+ return match ? match[1] : null;
200
+ });
201
+ }
202
+ async function installViaHomebrew() {
203
+ console.log(chalk.blue("\u{1F4E6} Installing GitHub CLI via Homebrew..."));
204
+ try {
205
+ await execAsync3("brew install gh", {
206
+ timeout: 3e5
207
+ // 5 minutes
208
+ });
209
+ const version = await getGhVersion();
210
+ if (!version) {
211
+ return {
212
+ success: false,
213
+ message: chalk.red("\u274C GitHub CLI installation completed but gh command not found")
214
+ };
215
+ }
216
+ return {
217
+ success: true,
218
+ message: chalk.green(`\u2705 GitHub CLI installed successfully (version ${version})!`),
219
+ version
220
+ };
221
+ } catch (error) {
222
+ const errorMsg = error instanceof Error ? error.message : String(error);
223
+ return {
224
+ success: false,
225
+ message: chalk.red("\u274C Failed to install GitHub CLI via Homebrew\n\n") + chalk.dim("Error: ") + errorMsg + "\n\n" + chalk.dim("Please install GitHub CLI manually from: ") + chalk.cyan("https://cli.github.com/")
226
+ };
227
+ }
228
+ }
229
+ async function installViaWebi() {
230
+ console.log(chalk.blue("\u{1F4E6} Installing GitHub CLI via Webi..."));
231
+ console.log(chalk.dim("This will install gh to ~/.local/bin/\n"));
232
+ try {
233
+ await execAsync3("curl -sS https://webi.sh/gh | sh", {
234
+ timeout: 3e5
235
+ // 5 minutes
236
+ });
237
+ const version = await getGhVersion();
238
+ if (!version) {
239
+ return {
240
+ success: true,
241
+ message: chalk.green("\u2705 GitHub CLI installed successfully!\n") + chalk.dim(
242
+ "Note: You may need to restart your terminal for the gh command to be available."
243
+ )
244
+ };
245
+ }
246
+ return {
247
+ success: true,
248
+ message: chalk.green(`\u2705 GitHub CLI installed successfully (version ${version})!`),
249
+ version
250
+ };
251
+ } catch (error) {
252
+ const errorMsg = error instanceof Error ? error.message : String(error);
253
+ return {
254
+ success: false,
255
+ message: chalk.red("\u274C Failed to install GitHub CLI via Webi\n\n") + chalk.dim("Error: ") + errorMsg + "\n\n" + chalk.dim("Please install GitHub CLI manually from: ") + chalk.cyan("https://cli.github.com/")
256
+ };
257
+ }
258
+ }
259
+ async function installGhMacOS() {
260
+ const hasHomebrew = await isHomebrewInstalled();
261
+ if (hasHomebrew) {
262
+ return installViaHomebrew();
263
+ }
264
+ return installViaWebi();
265
+ }
266
+ async function installGhWindows() {
267
+ const hasWinget = await isWingetAvailable();
268
+ if (!hasWinget) {
269
+ return {
270
+ success: false,
271
+ message: chalk.red("\u274C winget is not available on this system\n\n") + chalk.dim("winget is included in Windows 10 (version 1809+) and Windows 11.\n") + chalk.dim("Please install GitHub CLI manually from: ") + chalk.cyan("https://cli.github.com/")
272
+ };
273
+ }
274
+ console.log(chalk.blue("\u{1F4E6} Installing GitHub CLI via winget..."));
275
+ try {
276
+ await execAsync3("winget install --id GitHub.cli --silent", {
277
+ timeout: 3e5
278
+ // 5 minutes
279
+ });
280
+ const version = await getGhVersion();
281
+ if (!version) {
282
+ return {
283
+ success: false,
284
+ message: chalk.red("\u274C GitHub CLI installation completed but gh command not found")
285
+ };
286
+ }
287
+ return {
288
+ success: true,
289
+ message: chalk.green(`\u2705 GitHub CLI installed successfully (version ${version})!`),
290
+ version
291
+ };
292
+ } catch (error) {
293
+ const errorMsg = error instanceof Error ? error.message : String(error);
294
+ return {
295
+ success: false,
296
+ message: chalk.red("\u274C Failed to install GitHub CLI via winget\n\n") + chalk.dim("Error: ") + errorMsg + "\n\n" + chalk.dim("Please install GitHub CLI manually from: ") + chalk.cyan("https://cli.github.com/")
297
+ };
298
+ }
299
+ }
300
+ async function installGhLinux() {
301
+ const packageManager = await detectLinuxPackageManager();
302
+ if (!packageManager) {
303
+ return {
304
+ success: false,
305
+ message: chalk.red("\u274C Could not detect a supported package manager\n\n") + chalk.dim("Supported package managers: apt, dnf, yum, pacman\n") + chalk.dim("Please install GitHub CLI manually from: ") + chalk.cyan("https://cli.github.com/")
306
+ };
307
+ }
308
+ console.log(chalk.blue(`\u{1F4E6} Installing GitHub CLI via ${packageManager.name}...`));
309
+ console.log(chalk.dim("This may prompt for your sudo password.\n"));
310
+ try {
311
+ let installCommand;
312
+ switch (packageManager.name) {
313
+ case "apt":
314
+ installCommand = 'curl -fsSL https://cli.github.com/packages/githubcli-archive-keyring.gpg | sudo dd of=/usr/share/keyrings/githubcli-archive-keyring.gpg && sudo chmod go+r /usr/share/keyrings/githubcli-archive-keyring.gpg && echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/githubcli-archive-keyring.gpg] https://cli.github.com/packages stable main" | sudo tee /etc/apt/sources.list.d/github-cli.list > /dev/null && sudo apt update && sudo apt install gh -y';
315
+ break;
316
+ case "dnf":
317
+ installCommand = "sudo dnf install gh -y";
318
+ break;
319
+ case "yum":
320
+ installCommand = "sudo yum install gh -y";
321
+ break;
322
+ case "pacman":
323
+ installCommand = "sudo pacman -S --noconfirm github-cli";
324
+ break;
325
+ default:
326
+ return {
327
+ success: false,
328
+ message: chalk.red(`\u274C Unsupported package manager: ${packageManager.name}`)
329
+ };
330
+ }
331
+ await execAsync3(installCommand, {
332
+ timeout: 3e5
333
+ // 5 minutes
334
+ });
335
+ const version = await getGhVersion();
336
+ if (!version) {
337
+ return {
338
+ success: false,
339
+ message: chalk.red("\u274C GitHub CLI installation completed but gh command not found")
340
+ };
341
+ }
342
+ return {
343
+ success: true,
344
+ message: chalk.green(`\u2705 GitHub CLI installed successfully (version ${version})!`),
345
+ version
346
+ };
347
+ } catch (error) {
348
+ const errorMsg = error instanceof Error ? error.message : String(error);
349
+ return {
350
+ success: false,
351
+ message: chalk.red("\u274C Failed to install GitHub CLI\n\n") + chalk.dim("Error: ") + errorMsg + "\n\n" + chalk.dim("Please install GitHub CLI manually from: ") + chalk.cyan("https://cli.github.com/")
352
+ };
353
+ }
354
+ }
355
+ async function installGh() {
356
+ const platform = process.platform;
357
+ switch (platform) {
358
+ case "darwin":
359
+ return installGhMacOS();
360
+ case "win32":
361
+ return installGhWindows();
362
+ case "linux":
363
+ return installGhLinux();
364
+ default:
365
+ return {
366
+ success: false,
367
+ message: chalk.red(`\u274C Unsupported platform: ${platform}
368
+
369
+ `) + chalk.dim("Please install GitHub CLI manually from: ") + chalk.cyan("https://cli.github.com/")
370
+ };
371
+ }
372
+ }
373
+ function getGhManualInstallInstructions() {
374
+ const platform = process.platform;
375
+ switch (platform) {
376
+ case "darwin":
377
+ return chalk.yellow("\u{1F4D6} Manual GitHub CLI Installation (macOS)\n\n") + chalk.dim("Option 1 - Webi (recommended, no Homebrew needed):\n") + chalk.cyan(" curl -sS https://webi.sh/gh | sh\n\n") + chalk.dim("Option 2 - Homebrew:\n") + chalk.cyan(" brew install gh\n\n") + chalk.dim("Option 3 - Direct download:\n") + chalk.cyan(" Download from: https://cli.github.com/");
378
+ case "win32":
379
+ return chalk.yellow("\u{1F4D6} Manual GitHub CLI Installation (Windows)\n\n") + chalk.dim("Option 1 - winget (Windows 10+):\n") + chalk.cyan(" winget install --id GitHub.cli\n\n") + chalk.dim("Option 2 - Direct download:\n") + chalk.cyan(" Download from: https://cli.github.com/");
380
+ case "linux":
381
+ return chalk.yellow("\u{1F4D6} Manual GitHub CLI Installation (Linux)\n\n") + chalk.dim("Debian/Ubuntu:\n") + chalk.cyan(
382
+ " See instructions at: https://github.com/cli/cli/blob/trunk/docs/install_linux.md#debian-ubuntu-linux-raspberry-pi-os-apt\n\n"
383
+ ) + chalk.dim("Fedora/RHEL:\n") + chalk.cyan(" sudo dnf install gh\n\n") + chalk.dim("Arch Linux:\n") + chalk.cyan(" sudo pacman -S github-cli\n\n") + chalk.dim("Or download from: ") + chalk.cyan("https://cli.github.com/");
384
+ default:
385
+ return chalk.yellow("\u{1F4D6} Manual GitHub CLI Installation\n\n") + chalk.dim("Download from: ") + chalk.cyan("https://cli.github.com/");
386
+ }
387
+ }
388
+
389
+ export {
390
+ isCliInstalled,
391
+ getCliVersion,
392
+ checkInstalledCliTools,
393
+ isHomebrewInstalled,
394
+ isWingetAvailable,
395
+ detectLinuxPackageManager,
396
+ isGhInstalled,
397
+ getGhVersion,
398
+ installGh,
399
+ getGhManualInstallInstructions
400
+ };
401
+ //# sourceMappingURL=chunk-KNVWIF3L.js.map