@braingrid/cli 0.2.13 → 0.2.16
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 +29 -0
- package/dist/cli.js +129 -62
- package/dist/cli.js.map +1 -1
- package/package.json +116 -113
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,35 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [0.2.16] - 2025-12-17
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
|
|
14
|
+
- **--format option for show commands**
|
|
15
|
+
- Added `--format` option to `requirement show` command
|
|
16
|
+
- Added `--format` option to `task show` command
|
|
17
|
+
- Supports all standard formats: table (default), json, xml, markdown
|
|
18
|
+
- Consistent with other commands that already support `--format`
|
|
19
|
+
|
|
20
|
+
## [0.2.15] - 2025-12-15
|
|
21
|
+
|
|
22
|
+
### Changed
|
|
23
|
+
|
|
24
|
+
- **CI/CD: Switch to OIDC-based npm publishing**
|
|
25
|
+
- GitHub Actions workflow now uses OpenID Connect (Trusted Publishing) for npm authentication
|
|
26
|
+
- No longer requires NPM_TOKEN secret - authentication is handled via OIDC
|
|
27
|
+
- More secure and eliminates token expiration issues
|
|
28
|
+
|
|
29
|
+
## [0.2.14] - 2025-12-15
|
|
30
|
+
|
|
31
|
+
### Added
|
|
32
|
+
|
|
33
|
+
- **Requirement auto-detection for task commands**
|
|
34
|
+
- Task commands now auto-detect the requirement ID from git branch names (e.g., `feature/REQ-123-something` → `REQ-123`)
|
|
35
|
+
- Matches the existing behavior of requirement commands
|
|
36
|
+
- Applies to all task commands: `list`, `summary`, `show`, `create`, `update`, `delete`
|
|
37
|
+
- Explicit `-r/--requirement` flag still works and takes precedence over auto-detection
|
|
38
|
+
|
|
10
39
|
## [0.2.13] - 2025-12-08
|
|
11
40
|
|
|
12
41
|
### Added
|
package/dist/cli.js
CHANGED
|
@@ -422,7 +422,7 @@ import axios3, { AxiosError as AxiosError2 } from "axios";
|
|
|
422
422
|
|
|
423
423
|
// src/build-config.ts
|
|
424
424
|
var BUILD_ENV = true ? "production" : process.env.NODE_ENV === "test" ? "development" : "production";
|
|
425
|
-
var CLI_VERSION = true ? "0.2.
|
|
425
|
+
var CLI_VERSION = true ? "0.2.16" : "0.0.0-test";
|
|
426
426
|
var PRODUCTION_CONFIG = {
|
|
427
427
|
apiUrl: "https://app.braingrid.ai",
|
|
428
428
|
workosAuthUrl: "https://auth.braingrid.ai",
|
|
@@ -3940,6 +3940,15 @@ async function handleRequirementShow(opts) {
|
|
|
3940
3940
|
message: chalk7.red("\u274C Not authenticated. Please run `braingrid login` first.")
|
|
3941
3941
|
};
|
|
3942
3942
|
}
|
|
3943
|
+
const format = opts?.format || "table";
|
|
3944
|
+
if (!["table", "json", "xml", "markdown"].includes(format)) {
|
|
3945
|
+
return {
|
|
3946
|
+
success: false,
|
|
3947
|
+
message: chalk7.red(
|
|
3948
|
+
`\u274C Invalid format: ${format}. Supported formats: table, json, xml, markdown`
|
|
3949
|
+
)
|
|
3950
|
+
};
|
|
3951
|
+
}
|
|
3943
3952
|
const requirementResult = await workspaceManager.getRequirement(opts?.id);
|
|
3944
3953
|
if (!requirementResult.success) {
|
|
3945
3954
|
return {
|
|
@@ -3961,17 +3970,39 @@ async function handleRequirementShow(opts) {
|
|
|
3961
3970
|
const requirement2 = await requirementService.getProjectRequirement(projectId, normalizedId);
|
|
3962
3971
|
stopSpinner();
|
|
3963
3972
|
stopSpinner = null;
|
|
3964
|
-
|
|
3965
|
-
|
|
3966
|
-
|
|
3967
|
-
|
|
3968
|
-
|
|
3969
|
-
|
|
3970
|
-
|
|
3971
|
-
|
|
3973
|
+
let output;
|
|
3974
|
+
switch (format) {
|
|
3975
|
+
case "json": {
|
|
3976
|
+
output = JSON.stringify(requirement2, null, 2);
|
|
3977
|
+
break;
|
|
3978
|
+
}
|
|
3979
|
+
case "xml": {
|
|
3980
|
+
output = formatRequirementBuildXml(requirement2);
|
|
3981
|
+
break;
|
|
3982
|
+
}
|
|
3983
|
+
case "markdown": {
|
|
3984
|
+
output = formatRequirementBuildMarkdown(requirement2, {
|
|
3985
|
+
apiUrl: config.apiUrl,
|
|
3986
|
+
projectShortId: projectId
|
|
3987
|
+
});
|
|
3988
|
+
break;
|
|
3989
|
+
}
|
|
3990
|
+
case "table":
|
|
3991
|
+
default: {
|
|
3992
|
+
output = "\n" + formatRequirementOutput(requirement2, {
|
|
3993
|
+
showDescription: true,
|
|
3994
|
+
showContent: true,
|
|
3995
|
+
showTasks: true,
|
|
3996
|
+
showUpdated: true,
|
|
3997
|
+
apiUrl: config.apiUrl,
|
|
3998
|
+
projectShortId: projectId
|
|
3999
|
+
});
|
|
4000
|
+
break;
|
|
4001
|
+
}
|
|
4002
|
+
}
|
|
3972
4003
|
return {
|
|
3973
4004
|
success: true,
|
|
3974
|
-
message:
|
|
4005
|
+
message: output,
|
|
3975
4006
|
data: requirement2
|
|
3976
4007
|
};
|
|
3977
4008
|
} catch (error) {
|
|
@@ -4498,12 +4529,6 @@ async function handleTaskList(opts) {
|
|
|
4498
4529
|
message: chalk8.red("\u274C Not authenticated. Please run `braingrid login` first.")
|
|
4499
4530
|
};
|
|
4500
4531
|
}
|
|
4501
|
-
if (!opts.requirement) {
|
|
4502
|
-
return {
|
|
4503
|
-
success: false,
|
|
4504
|
-
message: chalk8.red("\u274C No requirement specified.\n\n") + chalk8.dim("Please provide a requirement ID:\n") + chalk8.cyan("braingrid task list -r REQ-456") + chalk8.dim(" (if initialized) or\n") + chalk8.cyan("braingrid task list -r REQ-456 -p PROJ-123")
|
|
4505
|
-
};
|
|
4506
|
-
}
|
|
4507
4532
|
const workspace = await workspaceManager.getProject(opts.project);
|
|
4508
4533
|
if (!workspace.success) {
|
|
4509
4534
|
return {
|
|
@@ -4512,7 +4537,14 @@ async function handleTaskList(opts) {
|
|
|
4512
4537
|
};
|
|
4513
4538
|
}
|
|
4514
4539
|
const projectId = workspace.projectId;
|
|
4515
|
-
const
|
|
4540
|
+
const requirementResult = await workspaceManager.getRequirement(opts.requirement);
|
|
4541
|
+
if (!requirementResult.success) {
|
|
4542
|
+
return {
|
|
4543
|
+
success: false,
|
|
4544
|
+
message: requirementResult.error
|
|
4545
|
+
};
|
|
4546
|
+
}
|
|
4547
|
+
const requirementId = requirementResult.requirementId;
|
|
4516
4548
|
stopSpinner = showSpinner("Loading tasks", chalk8.gray);
|
|
4517
4549
|
const response = await taskService.listTasks(projectId, requirementId);
|
|
4518
4550
|
stopSpinner();
|
|
@@ -4525,7 +4557,7 @@ async function handleTaskList(opts) {
|
|
|
4525
4557
|
};
|
|
4526
4558
|
}
|
|
4527
4559
|
const projectShortId = projectId;
|
|
4528
|
-
const requirementShortId = opts.requirement;
|
|
4560
|
+
const requirementShortId = opts.requirement || requirementId;
|
|
4529
4561
|
const format = opts.format || "markdown";
|
|
4530
4562
|
const config = getConfig();
|
|
4531
4563
|
const output = formatTasksListOutput(response.tasks, format, true, {
|
|
@@ -4560,12 +4592,6 @@ async function handleTaskSummary(opts) {
|
|
|
4560
4592
|
message: chalk8.red("\u274C Not authenticated. Please run `braingrid login` first.")
|
|
4561
4593
|
};
|
|
4562
4594
|
}
|
|
4563
|
-
if (!opts.requirement) {
|
|
4564
|
-
return {
|
|
4565
|
-
success: false,
|
|
4566
|
-
message: chalk8.red("\u274C No requirement specified.\n\n") + chalk8.dim("Please provide a requirement ID:\n") + chalk8.cyan("braingrid task summary -r REQ-456") + chalk8.dim(" (if initialized) or\n") + chalk8.cyan("braingrid task summary -r REQ-456 -p PROJ-123")
|
|
4567
|
-
};
|
|
4568
|
-
}
|
|
4569
4595
|
const workspace = await workspaceManager.getProject(opts.project);
|
|
4570
4596
|
if (!workspace.success) {
|
|
4571
4597
|
return {
|
|
@@ -4574,7 +4600,14 @@ async function handleTaskSummary(opts) {
|
|
|
4574
4600
|
};
|
|
4575
4601
|
}
|
|
4576
4602
|
const projectId = workspace.projectId;
|
|
4577
|
-
const
|
|
4603
|
+
const requirementResult = await workspaceManager.getRequirement(opts.requirement);
|
|
4604
|
+
if (!requirementResult.success) {
|
|
4605
|
+
return {
|
|
4606
|
+
success: false,
|
|
4607
|
+
message: requirementResult.error
|
|
4608
|
+
};
|
|
4609
|
+
}
|
|
4610
|
+
const requirementId = requirementResult.requirementId;
|
|
4578
4611
|
stopSpinner = showSpinner("Loading tasks", chalk8.gray);
|
|
4579
4612
|
const response = await taskService.listTasks(projectId, requirementId);
|
|
4580
4613
|
stopSpinner();
|
|
@@ -4587,7 +4620,7 @@ async function handleTaskSummary(opts) {
|
|
|
4587
4620
|
};
|
|
4588
4621
|
}
|
|
4589
4622
|
const projectShortId = projectId;
|
|
4590
|
-
const requirementShortId = opts.requirement;
|
|
4623
|
+
const requirementShortId = opts.requirement || requirementId;
|
|
4591
4624
|
const config = getConfig();
|
|
4592
4625
|
const output = formatTasksListOutput(response.tasks, "table", false, {
|
|
4593
4626
|
requirementId,
|
|
@@ -4621,13 +4654,16 @@ async function handleTaskShow(id, opts) {
|
|
|
4621
4654
|
message: chalk8.red("\u274C Not authenticated. Please run `braingrid login` first.")
|
|
4622
4655
|
};
|
|
4623
4656
|
}
|
|
4624
|
-
|
|
4657
|
+
const format = opts?.format || "table";
|
|
4658
|
+
if (!["table", "json", "xml", "markdown"].includes(format)) {
|
|
4625
4659
|
return {
|
|
4626
4660
|
success: false,
|
|
4627
|
-
message: chalk8.red(
|
|
4661
|
+
message: chalk8.red(
|
|
4662
|
+
`\u274C Invalid format: ${format}. Supported formats: table, json, xml, markdown`
|
|
4663
|
+
)
|
|
4628
4664
|
};
|
|
4629
4665
|
}
|
|
4630
|
-
const workspace = await workspaceManager.getProject(opts
|
|
4666
|
+
const workspace = await workspaceManager.getProject(opts?.project);
|
|
4631
4667
|
if (!workspace.success) {
|
|
4632
4668
|
return {
|
|
4633
4669
|
success: false,
|
|
@@ -4635,20 +4671,48 @@ async function handleTaskShow(id, opts) {
|
|
|
4635
4671
|
};
|
|
4636
4672
|
}
|
|
4637
4673
|
const projectId = workspace.projectId;
|
|
4638
|
-
const
|
|
4674
|
+
const requirementResult = await workspaceManager.getRequirement(opts?.requirement);
|
|
4675
|
+
if (!requirementResult.success) {
|
|
4676
|
+
return {
|
|
4677
|
+
success: false,
|
|
4678
|
+
message: requirementResult.error
|
|
4679
|
+
};
|
|
4680
|
+
}
|
|
4681
|
+
const requirementId = requirementResult.requirementId;
|
|
4639
4682
|
const taskId = normalizeTaskId(id);
|
|
4640
4683
|
const config = getConfig();
|
|
4641
4684
|
stopSpinner = showSpinner("Loading task", chalk8.gray);
|
|
4642
4685
|
const task2 = await taskService.getTask(projectId, requirementId, taskId);
|
|
4643
4686
|
stopSpinner();
|
|
4644
4687
|
stopSpinner = null;
|
|
4645
|
-
|
|
4646
|
-
|
|
4647
|
-
|
|
4648
|
-
|
|
4649
|
-
|
|
4650
|
-
|
|
4651
|
-
|
|
4688
|
+
let output;
|
|
4689
|
+
switch (format) {
|
|
4690
|
+
case "json": {
|
|
4691
|
+
output = JSON.stringify(task2, null, 2);
|
|
4692
|
+
break;
|
|
4693
|
+
}
|
|
4694
|
+
case "xml":
|
|
4695
|
+
case "markdown": {
|
|
4696
|
+
output = formatTasksListOutput([task2], format, true, {
|
|
4697
|
+
requirementId,
|
|
4698
|
+
projectShortId: projectId,
|
|
4699
|
+
requirementShortId: opts?.requirement || requirementId,
|
|
4700
|
+
apiUrl: config.apiUrl
|
|
4701
|
+
});
|
|
4702
|
+
break;
|
|
4703
|
+
}
|
|
4704
|
+
case "table":
|
|
4705
|
+
default: {
|
|
4706
|
+
output = formatTaskOutput(task2, {
|
|
4707
|
+
showContent: true,
|
|
4708
|
+
apiUrl: config.apiUrl,
|
|
4709
|
+
projectShortId: projectId,
|
|
4710
|
+
requirementShortId: opts?.requirement || requirementId,
|
|
4711
|
+
requirementId
|
|
4712
|
+
});
|
|
4713
|
+
break;
|
|
4714
|
+
}
|
|
4715
|
+
}
|
|
4652
4716
|
return {
|
|
4653
4717
|
success: true,
|
|
4654
4718
|
message: output,
|
|
@@ -4675,12 +4739,6 @@ async function handleTaskCreate(opts) {
|
|
|
4675
4739
|
message: chalk8.red("\u274C Not authenticated. Please run `braingrid login` first.")
|
|
4676
4740
|
};
|
|
4677
4741
|
}
|
|
4678
|
-
if (!opts.requirement) {
|
|
4679
|
-
return {
|
|
4680
|
-
success: false,
|
|
4681
|
-
message: chalk8.red("\u274C No requirement specified.\n\n") + chalk8.dim("Please provide a requirement ID:\n") + chalk8.cyan('braingrid task create -r REQ-456 --title "..."') + chalk8.dim(" (if initialized) or\n") + chalk8.cyan('braingrid task create -r REQ-456 -p PROJ-123 --title "..."')
|
|
4682
|
-
};
|
|
4683
|
-
}
|
|
4684
4742
|
const workspace = await workspaceManager.getProject(opts.project);
|
|
4685
4743
|
if (!workspace.success) {
|
|
4686
4744
|
return {
|
|
@@ -4689,9 +4747,16 @@ async function handleTaskCreate(opts) {
|
|
|
4689
4747
|
};
|
|
4690
4748
|
}
|
|
4691
4749
|
const projectId = workspace.projectId;
|
|
4692
|
-
const
|
|
4750
|
+
const requirementResult = await workspaceManager.getRequirement(opts.requirement);
|
|
4751
|
+
if (!requirementResult.success) {
|
|
4752
|
+
return {
|
|
4753
|
+
success: false,
|
|
4754
|
+
message: requirementResult.error
|
|
4755
|
+
};
|
|
4756
|
+
}
|
|
4757
|
+
const requirementId = requirementResult.requirementId;
|
|
4693
4758
|
const projectShortId = projectId;
|
|
4694
|
-
const requirementShortId = opts.requirement;
|
|
4759
|
+
const requirementShortId = opts.requirement || requirementId;
|
|
4695
4760
|
const config = getConfig();
|
|
4696
4761
|
stopSpinner = showSpinner("Creating task", chalk8.gray);
|
|
4697
4762
|
const task2 = await taskService.createTask(projectId, requirementId, {
|
|
@@ -4740,12 +4805,6 @@ async function handleTaskUpdate(id, opts) {
|
|
|
4740
4805
|
message: chalk8.red("\u274C Please provide at least one field to update (--status or --title)")
|
|
4741
4806
|
};
|
|
4742
4807
|
}
|
|
4743
|
-
if (!opts.requirement) {
|
|
4744
|
-
return {
|
|
4745
|
-
success: false,
|
|
4746
|
-
message: chalk8.red("\u274C No requirement specified.\n\n") + chalk8.dim("Please provide a requirement ID:\n") + chalk8.cyan("braingrid task update TASK-789 -r REQ-456 --status COMPLETED") + chalk8.dim(" (if initialized) or\n") + chalk8.cyan("braingrid task update TASK-789 -r REQ-456 -p PROJ-123 --status COMPLETED")
|
|
4747
|
-
};
|
|
4748
|
-
}
|
|
4749
4808
|
const workspace = await workspaceManager.getProject(opts.project);
|
|
4750
4809
|
if (!workspace.success) {
|
|
4751
4810
|
return {
|
|
@@ -4754,7 +4813,14 @@ async function handleTaskUpdate(id, opts) {
|
|
|
4754
4813
|
};
|
|
4755
4814
|
}
|
|
4756
4815
|
const projectId = workspace.projectId;
|
|
4757
|
-
const
|
|
4816
|
+
const requirementResult = await workspaceManager.getRequirement(opts.requirement);
|
|
4817
|
+
if (!requirementResult.success) {
|
|
4818
|
+
return {
|
|
4819
|
+
success: false,
|
|
4820
|
+
message: requirementResult.error
|
|
4821
|
+
};
|
|
4822
|
+
}
|
|
4823
|
+
const requirementId = requirementResult.requirementId;
|
|
4758
4824
|
const taskId = normalizeTaskId(id);
|
|
4759
4825
|
const config = getConfig();
|
|
4760
4826
|
stopSpinner = showSpinner("Updating task", chalk8.gray);
|
|
@@ -4769,7 +4835,7 @@ async function handleTaskUpdate(id, opts) {
|
|
|
4769
4835
|
successMessage: `Updated task ${task2.number}`,
|
|
4770
4836
|
apiUrl: config.apiUrl,
|
|
4771
4837
|
projectShortId: projectId,
|
|
4772
|
-
requirementShortId: opts.requirement,
|
|
4838
|
+
requirementShortId: opts.requirement || requirementId,
|
|
4773
4839
|
requirementId
|
|
4774
4840
|
});
|
|
4775
4841
|
return {
|
|
@@ -4804,12 +4870,6 @@ async function handleTaskDelete(id, opts) {
|
|
|
4804
4870
|
message: chalk8.yellow("\u26A0\uFE0F Deleting a task is permanent. Use --force to confirm deletion.")
|
|
4805
4871
|
};
|
|
4806
4872
|
}
|
|
4807
|
-
if (!opts.requirement) {
|
|
4808
|
-
return {
|
|
4809
|
-
success: false,
|
|
4810
|
-
message: chalk8.red("\u274C No requirement specified.\n\n") + chalk8.dim("Please provide a requirement ID:\n") + chalk8.cyan("braingrid task delete TASK-789 -r REQ-456 --force") + chalk8.dim(" (if initialized) or\n") + chalk8.cyan("braingrid task delete TASK-789 -r REQ-456 -p PROJ-123 --force")
|
|
4811
|
-
};
|
|
4812
|
-
}
|
|
4813
4873
|
const workspace = await workspaceManager.getProject(opts.project);
|
|
4814
4874
|
if (!workspace.success) {
|
|
4815
4875
|
return {
|
|
@@ -4818,7 +4878,14 @@ async function handleTaskDelete(id, opts) {
|
|
|
4818
4878
|
};
|
|
4819
4879
|
}
|
|
4820
4880
|
const projectId = workspace.projectId;
|
|
4821
|
-
const
|
|
4881
|
+
const requirementResult = await workspaceManager.getRequirement(opts.requirement);
|
|
4882
|
+
if (!requirementResult.success) {
|
|
4883
|
+
return {
|
|
4884
|
+
success: false,
|
|
4885
|
+
message: requirementResult.error
|
|
4886
|
+
};
|
|
4887
|
+
}
|
|
4888
|
+
const requirementId = requirementResult.requirementId;
|
|
4822
4889
|
const taskId = normalizeTaskId(id);
|
|
4823
4890
|
stopSpinner = showSpinner("Deleting task", chalk8.gray);
|
|
4824
4891
|
await taskService.deleteTask(projectId, requirementId, taskId);
|
|
@@ -6948,7 +7015,7 @@ requirement.command("list").description("List requirements for a project").optio
|
|
|
6948
7015
|
requirement.command("show [id]").description("Show requirement details (auto-detects ID from git branch if not provided)").option(
|
|
6949
7016
|
"-p, --project <id>",
|
|
6950
7017
|
"project ID (auto-detects from .braingrid/project.json if not provided)"
|
|
6951
|
-
).action(async (id, opts) => {
|
|
7018
|
+
).option("--format <format>", "output format (table, json, xml, markdown)", "table").action(async (id, opts) => {
|
|
6952
7019
|
const result = await handleRequirementShow({ ...opts, id });
|
|
6953
7020
|
console.log(result.message);
|
|
6954
7021
|
if (!result.success) {
|
|
@@ -7021,7 +7088,7 @@ task.command("summary").description("Show task summary table (quick overview wit
|
|
|
7021
7088
|
process.exit(1);
|
|
7022
7089
|
}
|
|
7023
7090
|
});
|
|
7024
|
-
task.command("show <id>").description("Show task details").option("-r, --requirement <id>", "requirement ID (REQ-456, auto-detects project if initialized)").option("-p, --project <id>", "project ID (PROJ-123, optional if project is initialized)").action(async (id, opts) => {
|
|
7091
|
+
task.command("show <id>").description("Show task details").option("-r, --requirement <id>", "requirement ID (REQ-456, auto-detects project if initialized)").option("-p, --project <id>", "project ID (PROJ-123, optional if project is initialized)").option("--format <format>", "output format (table, json, xml, markdown)", "table").action(async (id, opts) => {
|
|
7025
7092
|
const result = await handleTaskShow(id, opts);
|
|
7026
7093
|
console.log(result.message);
|
|
7027
7094
|
if (!result.success) {
|