brn-toolkit 1.0.0

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 (48) hide show
  1. package/GEMINI.md +92 -0
  2. package/README.md +145 -0
  3. package/cli/brn.ts +301 -0
  4. package/dist/cli/brn.js +274 -0
  5. package/dist/lib/utils.js +167 -0
  6. package/dist/skills/github/scripts/create_pr.js +24 -0
  7. package/dist/skills/github/scripts/get_repo_info.js +23 -0
  8. package/dist/skills/github/scripts/list_prs.js +27 -0
  9. package/dist/skills/github/scripts/list_repos.js +39 -0
  10. package/dist/skills/jira/scripts/add_comment.js +36 -0
  11. package/dist/skills/jira/scripts/get_ticket.js +45 -0
  12. package/dist/skills/jira/scripts/list_tickets.js +42 -0
  13. package/dist/skills/jira/scripts/update_ticket.js +30 -0
  14. package/dist/skills/workflow/scripts/start.js +75 -0
  15. package/dist/skills/workspace-manager/scripts/configure_workspace.js +59 -0
  16. package/dist/skills/workspace-manager/scripts/create_workspace.js +60 -0
  17. package/lib/utils.ts +236 -0
  18. package/package.json +46 -0
  19. package/skills/git-worktree/SKILL.md +49 -0
  20. package/skills/git-worktree/scripts/clone_repo.sh +53 -0
  21. package/skills/git-worktree/scripts/create_worktree.sh +66 -0
  22. package/skills/git-worktree/scripts/list_worktrees.sh +39 -0
  23. package/skills/git-worktree/scripts/remove_worktree.sh +47 -0
  24. package/skills/github/SKILL.md +51 -0
  25. package/skills/github/references/api_patterns.md +36 -0
  26. package/skills/github/scripts/create_pr.ts +38 -0
  27. package/skills/github/scripts/get_repo_info.ts +39 -0
  28. package/skills/github/scripts/list_prs.ts +45 -0
  29. package/skills/github/scripts/list_repos.ts +54 -0
  30. package/skills/jira/SKILL.md +50 -0
  31. package/skills/jira/references/api_patterns.md +59 -0
  32. package/skills/jira/scripts/add_comment.ts +41 -0
  33. package/skills/jira/scripts/get_ticket.ts +71 -0
  34. package/skills/jira/scripts/list_tickets.ts +64 -0
  35. package/skills/jira/scripts/update_ticket.ts +50 -0
  36. package/skills/workflow/SKILL.md +94 -0
  37. package/skills/workflow/references/coding_workflow.md +88 -0
  38. package/skills/workflow/references/planning_workflow.md +96 -0
  39. package/skills/workflow/references/review_workflow.md +104 -0
  40. package/skills/workflow/scripts/start.ts +93 -0
  41. package/skills/workspace-manager/SKILL.md +49 -0
  42. package/skills/workspace-manager/scripts/configure_workspace.sh +87 -0
  43. package/skills/workspace-manager/scripts/configure_workspace.ts +70 -0
  44. package/skills/workspace-manager/scripts/create_workspace.sh +66 -0
  45. package/skills/workspace-manager/scripts/create_workspace.ts +74 -0
  46. package/skills/workspace-manager/scripts/get_active_workspace.sh +24 -0
  47. package/skills/workspace-manager/scripts/list_workspaces.sh +31 -0
  48. package/skills/workspace-manager/scripts/switch_workspace.sh +38 -0
@@ -0,0 +1,94 @@
1
+ ---
2
+ name: brn:workflow
3
+ description: |
4
+ Orchestrate the complete development workflow from ticket to PR.
5
+ Use when: (1) Starting work on a JIRA ticket, (2) Following the planning-coding-review cycle.
6
+ ---
7
+
8
+ # Development Workflow Orchestrator
9
+
10
+ ## Description
11
+ The Workflow skill orchestrates high-level development tasks that involve multiple other skills (JIRA, Git, GitHub). It is designed to reduce the cognitive load of starting and managing tasks.
12
+
13
+ ## Available Scripts
14
+
15
+ ### `start`
16
+ Initiates work on a specific ticket. This script:
17
+ 1. Fetches ticket details from JIRA.
18
+ 2. Determines the correct repository (based on convention or config).
19
+ 3. Creates a new git worktree for the feature branch.
20
+ 4. Updates the JIRA ticket status to "In Progress".
21
+
22
+ * **Usage**: `brn start <ticket_id>` (Shortcut) or `brn workflow start <ticket_id>`
23
+ * **Arguments**:
24
+ * `ticket_id`: The JIRA issue key (e.g., `PROJ-123`).
25
+ * **Example**: `brn start PROJ-123`
26
+
27
+ ## Workflow Overview
28
+
29
+ ```
30
+ ┌─────────────────────────────────────────────────────────────┐
31
+ │ DEVELOPMENT WORKFLOW │
32
+ ├─────────────────────────────────────────────────────────────┤
33
+ │ 1. INITIATE │
34
+ │ └── brn start <ticket> │
35
+ ├─────────────────────────────────────────────────────────────┤
36
+ │ 2. PLAN │
37
+ │ └── Understand requirements → Create implementation plan │
38
+ ├─────────────────────────────────────────────────────────────┤
39
+ │ 3. CODE │
40
+ │ └── Implement → Test → Iterate │
41
+ ├─────────────────────────────────────────────────────────────┤
42
+ │ 4. REVIEW │
43
+ │ └── Self-review → Fix issues → Validate │
44
+ ├─────────────────────────────────────────────────────────────┤
45
+ │ 5. SHIP │
46
+ │ └── Create PR → Update ticket → Clean up worktree │
47
+ └─────────────────────────────────────────────────────────────┘
48
+ ```
49
+
50
+ ## Detailed Phases
51
+
52
+ ### Phase 1: Initiate
53
+ Start work on a JIRA ticket using the deterministic command:
54
+ ```bash
55
+ brn start PROJ-123
56
+ ```
57
+
58
+ ### Phase 2: Plan
59
+ Create an implementation plan before coding. Read the ticket thoroughly and create a `PLAN.md` in the worktree.
60
+
61
+ ### Phase 3: Code
62
+ Implement the solution following the plan. Commit frequently with the ticket ID in the message.
63
+
64
+ ### Phase 4: Review
65
+ Self-review before creating PR. Use linter, tests, and type checking.
66
+
67
+ ### Phase 5: Ship
68
+
69
+ Should always check ~/.brn/config.yaml to confirm automation is enabled.
70
+ Should not commit the PLAN.md file.
71
+ Should keep commit message clean. Dont append co-authored-by
72
+
73
+ ```bash
74
+ # Push branch
75
+ git push origin <branch-name>
76
+
77
+ # Create PR
78
+ brn github create_pr <owner/repo> <head> <base> <title>
79
+
80
+ # Add PR link to ticket
81
+ brn jira add_comment <ticket_key> "PR: <url>"
82
+
83
+ # Update ticket status
84
+ brn jira update_ticket <ticket_key> "Code Review"
85
+ ```
86
+
87
+ ### Phase 6: Clean-up
88
+
89
+ It should clean-up git worktrees if code change was pushed upstream.
90
+
91
+ ## Detailed Guides
92
+ - [Planning Workflow](references/planning_workflow.md)
93
+ - [Coding Workflow](references/coding_workflow.md)
94
+ - [Review Workflow](references/review_workflow.md)
@@ -0,0 +1,88 @@
1
+ # Coding Workflow
2
+
3
+ Best practices for the implementation phase.
4
+
5
+ ## Principles
6
+
7
+ 1. **Follow the plan** - Resist scope creep
8
+ 2. **Work incrementally** - Small, verifiable steps
9
+ 3. **Commit often** - Atomic, reversible changes
10
+ 4. **Test as you go** - Don't save testing for the end
11
+
12
+ ## Process
13
+
14
+ ### 1. Set Up Environment
15
+
16
+ ```bash
17
+ # Navigate to worktree
18
+ cd ~/dev/<workspace>/repo-worktrees/TICKET-branch
19
+
20
+ # Install dependencies
21
+ npm install
22
+
23
+ # Start dev server if needed
24
+ npm run dev
25
+ ```
26
+
27
+ ### 2. Work Through Plan
28
+
29
+ For each step in your plan:
30
+ 1. Write the code
31
+ 2. Write/update tests
32
+ 3. Run tests locally
33
+ 4. Commit
34
+
35
+ ### 3. Commit Practices
36
+
37
+ #### Commit Message Format
38
+ ```
39
+ <type>(<scope>): <description> [TICKET-KEY]
40
+
41
+ [optional body]
42
+ ```
43
+
44
+ Types:
45
+ - `feat`: New feature
46
+ - `fix`: Bug fix
47
+ - `refactor`: Code change that neither fixes nor adds
48
+ - `test`: Adding tests
49
+ - `docs`: Documentation
50
+ - `chore`: Maintenance
51
+
52
+ #### Good Commits
53
+ ```bash
54
+ git commit -m "feat(auth): add password reset endpoint [PROJ-123]"
55
+ git commit -m "test(auth): add tests for password reset [PROJ-123]"
56
+ git commit -m "fix(auth): handle expired tokens gracefully [PROJ-123]"
57
+ ```
58
+
59
+ ### 4. Handle Blockers
60
+
61
+ When stuck:
62
+ 1. Time-box the problem (15-30 min)
63
+ 2. Document what you've tried
64
+ 3. Ask for help with context
65
+ 4. Update plan if approach changes
66
+
67
+ ### 5. Keep Plan Updated
68
+
69
+ As you work:
70
+ - Check off completed steps
71
+ - Add discovered steps
72
+ - Note any deviations
73
+ - Update "Files Changed" section
74
+
75
+ ## Code Quality
76
+
77
+ ### Before Committing
78
+ - [ ] Code compiles/runs
79
+ - [ ] Tests pass
80
+ - [ ] Linter is happy
81
+ - [ ] No debug code left
82
+ - [ ] No hardcoded secrets
83
+
84
+ ### Code Style
85
+ - Follow project conventions
86
+ - Match surrounding code style
87
+ - Add comments for non-obvious logic
88
+ - Use meaningful names
@@ -0,0 +1,96 @@
1
+ # Planning Workflow
2
+
3
+ Detailed guide for the planning phase of development.
4
+
5
+ ## Purpose
6
+
7
+ A good plan:
8
+ - Reduces wasted effort from misdirection
9
+ - Surfaces blockers early
10
+ - Creates shared understanding
11
+ - Provides a roadmap for implementation
12
+
13
+ ## Process
14
+
15
+ ### 1. Understand the Ticket
16
+
17
+ Read the ticket completely. Answer:
18
+ - What is the user problem being solved?
19
+ - What are the acceptance criteria?
20
+ - Are there any constraints or requirements?
21
+ - Who are the stakeholders?
22
+
23
+ ### 2. Research the Codebase
24
+
25
+ Before planning changes:
26
+ - Find related existing code
27
+ - Understand current patterns
28
+ - Identify dependencies
29
+ - Note any technical debt to address
30
+
31
+ ### 3. Design the Solution
32
+
33
+ Consider:
34
+ - What's the minimal change to solve the problem?
35
+ - Are there multiple approaches? Which is best?
36
+ - What are the risks of each approach?
37
+ - How will this be tested?
38
+
39
+ ### 4. Write the Plan
40
+
41
+ Create `PLAN.md` in your worktree:
42
+
43
+ ```markdown
44
+ # [TICKET-KEY]: [Title]
45
+
46
+ ## Problem Statement
47
+ [What problem are we solving?]
48
+
49
+ ## Requirements
50
+ - [ ] Requirement from ticket
51
+ - [ ] Inferred requirement
52
+
53
+ ## Approach
54
+ [High-level description of solution]
55
+
56
+ ### Option A: [Name]
57
+ - Pros: ...
58
+ - Cons: ...
59
+
60
+ ### Option B: [Name]
61
+ - Pros: ...
62
+ - Cons: ...
63
+
64
+ **Chosen: Option A because...**
65
+
66
+ ## Implementation Steps
67
+ 1. [ ] Step one
68
+ 2. [ ] Step two
69
+ 3. [ ] Step three
70
+
71
+ ## Files to Change
72
+ | File | Change |
73
+ |------|--------|
74
+ | `path/to/file.ts` | Add X |
75
+ | `path/to/test.ts` | Add tests for X |
76
+
77
+ ## Testing Strategy
78
+ - Unit tests for...
79
+ - Integration test for...
80
+ - Manual test: ...
81
+
82
+ ## Open Questions
83
+ - [ ] Q1: Who to ask?
84
+ - [ ] Q2: Research needed?
85
+
86
+ ## Risks
87
+ - Risk 1: Mitigation...
88
+ ```
89
+
90
+ ### 5. Review & Refine
91
+
92
+ Before coding:
93
+ - Does the plan address all requirements?
94
+ - Are the steps clear enough to follow?
95
+ - Are open questions resolved?
96
+ - Get approval if needed
@@ -0,0 +1,104 @@
1
+ # Review Workflow
2
+
3
+ Self-review process before creating a PR.
4
+
5
+ ## Purpose
6
+
7
+ Self-review catches:
8
+ - Obvious bugs before reviewers see them
9
+ - Style issues that slow down review
10
+ - Missing tests or documentation
11
+ - Opportunities for improvement
12
+
13
+ ## Pre-Review Checks
14
+
15
+ ### 1. Automated Checks
16
+
17
+ ```bash
18
+ # Run all checks
19
+ npm run lint
20
+ npm run typecheck
21
+ npm test
22
+ npm run build
23
+ ```
24
+
25
+ All must pass before proceeding.
26
+
27
+ ### 2. Diff Review
28
+
29
+ Review your own diff as if reviewing someone else's code:
30
+
31
+ ```bash
32
+ # See what you're about to submit
33
+ git diff main...HEAD
34
+ ```
35
+
36
+ For each file, ask:
37
+ - Does this change make sense?
38
+ - Is there unnecessary code?
39
+ - Are there any obvious bugs?
40
+ - Does the logic flow clearly?
41
+
42
+ ### 3. Code Quality Checklist
43
+
44
+ #### Functionality
45
+ - [ ] Meets all acceptance criteria
46
+ - [ ] Handles edge cases
47
+ - [ ] Error states handled gracefully
48
+ - [ ] No regressions in existing behavior
49
+
50
+ #### Testing
51
+ - [ ] New code has tests
52
+ - [ ] Tests are meaningful (not just coverage)
53
+ - [ ] Edge cases tested
54
+ - [ ] Error paths tested
55
+
56
+ #### Security
57
+ - [ ] No secrets in code
58
+ - [ ] Input validation present
59
+ - [ ] No SQL injection / XSS vectors
60
+ - [ ] Auth/authz properly enforced
61
+
62
+ #### Performance
63
+ - [ ] No N+1 queries
64
+ - [ ] No unnecessary loops
65
+ - [ ] Large data handled appropriately
66
+ - [ ] No memory leaks
67
+
68
+ #### Maintainability
69
+ - [ ] Code is readable
70
+ - [ ] Complex logic documented
71
+ - [ ] No magic numbers
72
+ - [ ] DRY principles followed
73
+
74
+ ### 4. Documentation
75
+
76
+ - [ ] README updated if needed
77
+ - [ ] API docs updated
78
+ - [ ] Inline comments for complex code
79
+ - [ ] CHANGELOG updated if needed
80
+
81
+ ### 5. Final Verification
82
+
83
+ - [ ] Feature works end-to-end manually
84
+ - [ ] Works in all required environments
85
+ - [ ] No console errors/warnings
86
+ - [ ] Performance is acceptable
87
+
88
+ ## Common Issues to Check
89
+
90
+ | Issue | How to Check |
91
+ |-------|--------------|
92
+ | Unused imports | Linter should catch |
93
+ | Console.log left in | `grep -r "console.log" src/` |
94
+ | TODO comments | `grep -r "TODO" src/` |
95
+ | Debugging code | Search for `debugger`, test data |
96
+ | Hardcoded values | Search for magic strings/numbers |
97
+
98
+ ## After Review
99
+
100
+ Once checks pass:
101
+ 1. Push to remote
102
+ 2. Create PR with good description
103
+ 3. Link to ticket
104
+ 4. Request reviewers
@@ -0,0 +1,93 @@
1
+ #!/usr/bin/env npx tsx
2
+ /**
3
+ * Initiate a new development workflow for a JIRA ticket
4
+ * Usage: npx tsx start.ts <ticket_id>
5
+ */
6
+ import { $ } from "zx";
7
+ import { getActiveWorkspace, jiraRequest } from "../../../lib/utils.js";
8
+ import { join } from "path";
9
+ import { existsSync } from "fs";
10
+ import { homedir } from "os";
11
+
12
+ $.verbose = false;
13
+
14
+ const ticketId = process.argv[2];
15
+
16
+ if (!ticketId) {
17
+ console.log("Usage: npx tsx start.ts <ticket_id>");
18
+ console.log("Example: npx tsx start.ts PROJ-123");
19
+ process.exit(1);
20
+ }
21
+
22
+ async function run() {
23
+ console.log(`🚀 Initiating workflow for ${ticketId}...`);
24
+
25
+ // 1. Fetch ticket details
26
+ console.log(`📋 Fetching ticket ${ticketId}...`);
27
+ const ticket: any = await jiraRequest(`/rest/api/3/issue/${ticketId}`);
28
+ const summary = ticket.fields.summary;
29
+ const projectKey = ticket.fields.project.key;
30
+
31
+ console.log(`✅ Ticket found: ${summary}`);
32
+
33
+ // 2. Identify repo (simple heuristic or prompt)
34
+ // For now, let's look for repos in the workspace
35
+ const workspace = getActiveWorkspace();
36
+ let workDir = workspace.path;
37
+ if (workDir.startsWith("~")) {
38
+ workDir = join(homedir(), workDir.slice(1));
39
+ }
40
+
41
+ // In a real scenario, we might have a mapping or ask the user
42
+ // For this automation, we'll try to find a repo that matches the project key or ask
43
+ console.log(`📂 Searching for repositories in ${workDir}...`);
44
+
45
+ // List directories in workDir
46
+ const repos = (await $`ls -d ${workDir}/*/ 2>/dev/null`.quiet()).stdout
47
+ .split("\n")
48
+ .map(p => p.trim())
49
+ .filter(p => p && !p.endsWith("-worktrees/"))
50
+ .map(p => p.split("/").filter(Boolean).pop());
51
+
52
+ if (repos.length === 0) {
53
+ console.error("❌ No repositories found in workspace. Please clone a repo first using git-worktree:clone.");
54
+ process.exit(1);
55
+ }
56
+
57
+ let selectedRepo = repos[0];
58
+ if (repos.length > 1) {
59
+ console.log("Multiple repositories found:");
60
+ repos.forEach((r, i) => console.log(` ${i + 1}. ${r}`));
61
+ console.log(`Using ${selectedRepo} (default). To use another, clone it or configure mapping.`);
62
+ }
63
+
64
+ // 3. Create branch name
65
+ const branchName = `${ticketId}-${summary.toLowerCase().replace(/[^a-z0-9]/g, "-").slice(0, 30)}`;
66
+
67
+ // 4. Create worktree
68
+ console.log(`🌿 Creating worktree for branch ${branchName}...`);
69
+ const createWorktreeScript = join(process.cwd(), "skills/git-worktree/scripts/create_worktree.sh");
70
+ await $`${createWorktreeScript} ${selectedRepo} ${branchName}`;
71
+
72
+ // 5. Update ticket status
73
+ console.log(`🔄 Updating ticket status to 'In Progress'...`);
74
+ const updateTicketScript = join(process.cwd(), "skills/jira/scripts/update_ticket.ts");
75
+ await $`npx tsx ${updateTicketScript} ${ticketId} "In Progress"`.quiet();
76
+
77
+ const worktreePath = join(workDir, `${selectedRepo}-worktrees`, branchName);
78
+
79
+ console.log("\n" + "=".repeat(50));
80
+ console.log(`✅ Workflow initiated successfully!`);
81
+ console.log(`📍 Worktree: ${worktreePath}`);
82
+ console.log(`🔗 Ticket: ${workspace.jira_url}/browse/${ticketId}`);
83
+ console.log("=".repeat(50));
84
+ console.log(`
85
+ Next steps:
86
+ cd ${worktreePath}
87
+ # Start planning and coding!`);
88
+ }
89
+
90
+ run().catch(err => {
91
+ console.error("❌ Error initiating workflow:", err.message);
92
+ process.exit(1);
93
+ });
@@ -0,0 +1,49 @@
1
+ ---
2
+ name: brn:workspace-manager
3
+ description: |
4
+ Manage isolated configurations (tokens, paths) for different contexts.
5
+ ---
6
+
7
+ # Workspace Manager
8
+
9
+ ## Description
10
+ The Workspace Manager skill handles the configuration for the BRN toolkit. It allows you to maintain separate environments (e.g., "personal" vs "work") with their own API tokens, directories, and preferences.
11
+
12
+ ## Available Scripts
13
+
14
+ ### `create_workspace`
15
+ Creates a new workspace configuration.
16
+
17
+ * **Usage**: `brn workspace-manager create_workspace <name> <dir>`
18
+ * **Arguments**:
19
+ * `name`: The unique name for the workspace (e.g., "work", "personal").
20
+ * `dir`: The root directory where repositories and worktrees will be stored.
21
+ * **Example**: `brn workspace-manager create_workspace personal ~/dev/personal/auto`
22
+
23
+ ### `configure_workspace`
24
+ Updates a specific configuration key for a workspace.
25
+
26
+ * **Usage**: `brn workspace-manager configure_workspace <workspace_name> <key> <value>`
27
+ * **Arguments**:
28
+ * `workspace_name`: The name of the workspace to configure.
29
+ * `key`: The configuration key (e.g., `github_token`, `jira_url`).
30
+ * `value`: The value to set.
31
+ * **Example**: `brn workspace-manager configure_workspace personal github_token ghp_123456789`
32
+
33
+ ### `list_workspaces`
34
+ Lists all configured workspaces.
35
+
36
+ * **Usage**: `brn workspace-manager list_workspaces`
37
+ * **Alternative**: `brn workspace list` (CLI shortcut)
38
+
39
+ ### `switch_workspace`
40
+ Switches the active workspace.
41
+
42
+ * **Usage**: `brn workspace-manager switch_workspace <name>`
43
+ * **Alternative**: `brn workspace switch <name>` (CLI shortcut)
44
+ * **Arguments**:
45
+ * `name`: The name of the workspace to activate.
46
+ * **Example**: `brn workspace switch work`
47
+
48
+ ## Workspace Config
49
+ Configuration is stored in `~/.brn/config.yaml`. It is recommended to use `brn setup` for an interactive wizard when initializing the tool for the first time.
@@ -0,0 +1,87 @@
1
+ #!/bin/bash
2
+ # Configure a workspace setting
3
+ # Usage: configure_workspace.sh <workspace_name> <key> <value>
4
+ # Keys: github_token, jira_token, jira_url, jira_email, path
5
+ # Automation keys: automation.github_auto_push, automation.github_auto_pr,
6
+ # automation.jira_auto_transition, automation.jira_auto_comment
7
+
8
+ set -e
9
+
10
+ WORKSPACE_NAME="$1"
11
+ KEY="$2"
12
+ VALUE="$3"
13
+
14
+ if [ -z "$WORKSPACE_NAME" ] || [ -z "$KEY" ] || [ -z "$VALUE" ]; then
15
+ echo "Usage: configure_workspace.sh <workspace_name> <key> <value>"
16
+ echo ""
17
+ echo "Standard keys: github_token, jira_token, jira_url, jira_email, path"
18
+ echo ""
19
+ echo "Automation keys (default: false):"
20
+ echo " automation.github_auto_push - Auto-push commits"
21
+ echo " automation.github_auto_pr - Auto-create PRs"
22
+ echo " automation.jira_auto_transition - Auto-update ticket status"
23
+ echo " automation.jira_auto_comment - Auto-add comments"
24
+ echo ""
25
+ echo "Examples:"
26
+ echo " configure_workspace.sh personal github_token ghp_xxxxx"
27
+ echo " configure_workspace.sh work automation.jira_auto_transition true"
28
+ exit 1
29
+ fi
30
+
31
+ CONFIG_FILE="$HOME/.brn/config.yaml"
32
+
33
+ if [ ! -f "$CONFIG_FILE" ]; then
34
+ echo "Error: No config found. Create a workspace first."
35
+ exit 1
36
+ fi
37
+
38
+ # Validate key
39
+ VALID_KEYS="github_token jira_token jira_url jira_email path"
40
+ VALID_AUTOMATION_KEYS="automation.github_auto_push automation.github_auto_pr automation.jira_auto_transition automation.jira_auto_comment"
41
+
42
+ IS_VALID=false
43
+ if [[ " $VALID_KEYS " =~ " $KEY " ]]; then
44
+ IS_VALID=true
45
+ fi
46
+ if [[ " $VALID_AUTOMATION_KEYS " =~ " $KEY " ]]; then
47
+ IS_VALID=true
48
+ fi
49
+
50
+ if [ "$IS_VALID" = false ]; then
51
+ echo "Error: Invalid key '$KEY'"
52
+ echo "Valid keys: $VALID_KEYS"
53
+ echo "Automation keys: $VALID_AUTOMATION_KEYS"
54
+ exit 1
55
+ fi
56
+
57
+ if command -v yq &> /dev/null; then
58
+ # Check if workspace exists
59
+ if ! yq -e ".workspaces.$WORKSPACE_NAME" "$CONFIG_FILE" &> /dev/null; then
60
+ echo "Error: Workspace '$WORKSPACE_NAME' not found"
61
+ exit 1
62
+ fi
63
+
64
+ # Handle automation keys (nested)
65
+ if [[ "$KEY" == automation.* ]]; then
66
+ AUTOMATION_KEY="${KEY#automation.}"
67
+
68
+ # Convert string to boolean if needed
69
+ if [ "$VALUE" = "true" ]; then
70
+ yq -i ".workspaces.$WORKSPACE_NAME.automation.$AUTOMATION_KEY = true" "$CONFIG_FILE"
71
+ elif [ "$VALUE" = "false" ]; then
72
+ yq -i ".workspaces.$WORKSPACE_NAME.automation.$AUTOMATION_KEY = false" "$CONFIG_FILE"
73
+ else
74
+ echo "Error: Automation values must be 'true' or 'false'"
75
+ exit 1
76
+ fi
77
+ else
78
+ # Update standard setting
79
+ yq -i ".workspaces.$WORKSPACE_NAME.$KEY = \"$VALUE\"" "$CONFIG_FILE"
80
+ fi
81
+
82
+ echo "✓ Set $KEY for workspace '$WORKSPACE_NAME'"
83
+ else
84
+ echo "Error: yq required for this operation"
85
+ exit 1
86
+ fi
87
+
@@ -0,0 +1,70 @@
1
+ #!/usr/bin/env npx tsx
2
+ /**
3
+ * Configure a workspace setting
4
+ * Usage: npx tsx configure_workspace.ts <workspace_name> <key> <value>
5
+ */
6
+ import { getBrnConfig, saveBrnConfig } from "../../../lib/utils.js";
7
+
8
+ const workspaceName = process.argv[2];
9
+ const key = process.argv[3];
10
+ const value = process.argv[4];
11
+
12
+ if (!workspaceName || !key || !value) {
13
+ console.log("Usage: configure_workspace.ts <workspace_name> <key> <value>");
14
+ console.log("");
15
+ console.log("Standard keys: github_token, jira_token, jira_url, jira_email, path");
16
+ console.log("");
17
+ console.log("Automation keys (default: false):");
18
+ console.log(" automation.github_auto_push - Auto-push commits");
19
+ console.log(" automation.github_auto_pr - Auto-create PRs");
20
+ console.log(" automation.jira_auto_transition - Auto-update ticket status");
21
+ console.log(" automation.jira_auto_comment - Auto-add comments");
22
+ process.exit(1);
23
+ }
24
+
25
+ const config = getBrnConfig();
26
+
27
+ if (!config.workspaces[workspaceName]) {
28
+ console.error(`Error: Workspace '${workspaceName}' not found`);
29
+ process.exit(1);
30
+ }
31
+
32
+ // Validate key
33
+ const validKeys = ["github_token", "github_org", "jira_token", "jira_url", "jira_email", "path"];
34
+ const validAutomationKeys = [
35
+ "automation.github_auto_push",
36
+ "automation.github_auto_pr",
37
+ "automation.jira_auto_transition",
38
+ "automation.jira_auto_comment"
39
+ ];
40
+
41
+ let isValid = validKeys.includes(key) || validAutomationKeys.includes(key);
42
+
43
+ if (!isValid) {
44
+ console.error(`Error: Invalid key '${key}'`);
45
+ console.log(`Valid keys: ${validKeys.join(", ")}`);
46
+ console.log(`Automation keys: ${validAutomationKeys.join(", ")}`);
47
+ process.exit(1);
48
+ }
49
+
50
+ // Handle automation keys (nested)
51
+ if (key.startsWith("automation.")) {
52
+ const automationKey = key.replace("automation.", "");
53
+ const boolValue = value === "true";
54
+
55
+ if (value !== "true" && value !== "false") {
56
+ console.error("Error: Automation values must be 'true' or 'false'");
57
+ process.exit(1);
58
+ }
59
+
60
+ if (!config.workspaces[workspaceName].automation) {
61
+ config.workspaces[workspaceName].automation = {};
62
+ }
63
+
64
+ (config.workspaces[workspaceName].automation as any)[automationKey] = boolValue;
65
+ } else {
66
+ (config.workspaces[workspaceName] as any)[key] = value;
67
+ }
68
+
69
+ saveBrnConfig(config);
70
+ console.log(`✓ Set ${key} for workspace '${workspaceName}'`);