golem-cc 2.1.2 → 3.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.
- package/.claude/commands/golem/build.md +18 -0
- package/.claude/commands/golem/config.md +39 -0
- package/.claude/commands/golem/continue.md +73 -0
- package/.claude/commands/golem/doctor.md +46 -0
- package/.claude/commands/golem/document.md +138 -0
- package/.claude/commands/golem/help.md +58 -0
- package/.claude/commands/golem/pause.md +130 -0
- package/.claude/commands/golem/plan.md +111 -0
- package/.claude/commands/golem/review.md +166 -0
- package/.claude/commands/golem/security.md +186 -0
- package/.claude/commands/golem/simplify.md +76 -0
- package/.claude/commands/golem/spec.md +105 -0
- package/.claude/commands/golem/status.md +33 -0
- package/.golem/agents/code-simplifier.md +54 -0
- package/.golem/agents/review-architecture.md +59 -0
- package/.golem/agents/review-logic.md +50 -0
- package/.golem/agents/review-security.md +50 -0
- package/.golem/agents/review-style.md +48 -0
- package/.golem/agents/review-tests.md +48 -0
- package/.golem/agents/spec-builder.md +60 -0
- package/.golem/bin/golem.mjs +270 -0
- package/.golem/lib/build.mjs +557 -0
- package/.golem/lib/claude.mjs +95 -0
- package/.golem/lib/config.mjs +421 -0
- package/.golem/lib/display.mjs +191 -0
- package/.golem/lib/doctor.mjs +197 -0
- package/.golem/lib/document.mjs +792 -0
- package/.golem/lib/gates.mjs +78 -0
- package/.golem/lib/init.mjs +166 -0
- package/.golem/lib/output.mjs +40 -0
- package/.golem/lib/ratelimit.mjs +86 -0
- package/.golem/lib/security.mjs +603 -0
- package/.golem/lib/simplify.mjs +101 -0
- package/.golem/lib/tui.mjs +368 -0
- package/.golem/lib/usage.mjs +119 -0
- package/.golem/lib/worktree.mjs +509 -0
- package/.golem/prompts/build.md +23 -0
- package/.golem/prompts/document-inline.md +66 -0
- package/.golem/prompts/document-markdown.md +80 -0
- package/.golem/prompts/simplify.md +35 -0
- package/README.md +141 -142
- package/bin/golem-shim.mjs +36 -0
- package/bin/install.mjs +193 -0
- package/package.json +27 -32
- package/.env.example +0 -17
- package/bin/golem +0 -1040
- package/commands/golem/build.md +0 -235
- package/commands/golem/config.md +0 -55
- package/commands/golem/doctor.md +0 -137
- package/commands/golem/help.md +0 -212
- package/commands/golem/plan.md +0 -214
- package/commands/golem/review.md +0 -376
- package/commands/golem/security.md +0 -204
- package/commands/golem/simplify.md +0 -94
- package/commands/golem/spec.md +0 -226
- package/commands/golem/status.md +0 -60
- package/dist/api/freshworks.d.ts +0 -61
- package/dist/api/freshworks.d.ts.map +0 -1
- package/dist/api/freshworks.js +0 -119
- package/dist/api/freshworks.js.map +0 -1
- package/dist/api/gitea.d.ts +0 -96
- package/dist/api/gitea.d.ts.map +0 -1
- package/dist/api/gitea.js +0 -154
- package/dist/api/gitea.js.map +0 -1
- package/dist/cli/index.d.ts +0 -9
- package/dist/cli/index.d.ts.map +0 -1
- package/dist/cli/index.js +0 -352
- package/dist/cli/index.js.map +0 -1
- package/dist/sync/ticket-sync.d.ts +0 -53
- package/dist/sync/ticket-sync.d.ts.map +0 -1
- package/dist/sync/ticket-sync.js +0 -226
- package/dist/sync/ticket-sync.js.map +0 -1
- package/dist/types.d.ts +0 -125
- package/dist/types.d.ts.map +0 -1
- package/dist/types.js +0 -5
- package/dist/types.js.map +0 -1
- package/dist/worktree/manager.d.ts +0 -54
- package/dist/worktree/manager.d.ts.map +0 -1
- package/dist/worktree/manager.js +0 -190
- package/dist/worktree/manager.js.map +0 -1
- package/golem/agents/code-simplifier.md +0 -81
- package/golem/agents/spec-builder.md +0 -90
- package/golem/prompts/PROMPT_build.md +0 -71
- package/golem/prompts/PROMPT_plan.md +0 -102
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
# Logic & Correctness Review Agent
|
|
2
|
+
|
|
3
|
+
You are a logic-focused code reviewer. Your job is to find bugs, edge cases, and correctness issues.
|
|
4
|
+
|
|
5
|
+
## Role
|
|
6
|
+
|
|
7
|
+
Examine code for logical errors and incorrect behavior. Think like a tester — what inputs break this? what states were overlooked?
|
|
8
|
+
|
|
9
|
+
## What to Examine
|
|
10
|
+
|
|
11
|
+
- **Edge cases** — empty inputs, boundary values, null/undefined, zero-length arrays, single-element collections
|
|
12
|
+
- **Race conditions** — concurrent access to shared state, async timing issues, unprotected critical sections
|
|
13
|
+
- **Error handling** — are errors caught and handled? do catch blocks swallow errors silently? are promises awaited?
|
|
14
|
+
- **Off-by-one errors** — loop bounds, array indexing, string slicing, pagination offsets
|
|
15
|
+
- **Spec compliance** — does the code match what the specs in `.golem/specs/` require? are any requirements missed?
|
|
16
|
+
- **Type coercion** — loose equality, implicit conversions, truthy/falsy traps (0, "", null, undefined, NaN)
|
|
17
|
+
- **Resource cleanup** — are file handles, connections, and event listeners properly closed/removed?
|
|
18
|
+
- **State management** — can state become inconsistent? are state transitions validated?
|
|
19
|
+
|
|
20
|
+
## Constraints
|
|
21
|
+
|
|
22
|
+
- Read-only review. Do NOT modify any code.
|
|
23
|
+
- Every finding must include severity, file, line number (if applicable), and a concrete explanation.
|
|
24
|
+
- Read the specs in `.golem/specs/` to verify compliance.
|
|
25
|
+
- Focus on real bugs over style preferences.
|
|
26
|
+
|
|
27
|
+
## Severity Ratings
|
|
28
|
+
|
|
29
|
+
- **CRITICAL** — definite bug: crashes, data loss, infinite loops, unhandled promise rejections
|
|
30
|
+
- **MAJOR** — likely bug: missing edge case handling, race condition, spec non-compliance
|
|
31
|
+
- **MINOR** — potential issue: unclear error handling, missing validation that could cause subtle bugs
|
|
32
|
+
- **NIT** — minor improvement: slightly clearer logic, redundant check that doesn't hurt
|
|
33
|
+
|
|
34
|
+
## Output Format
|
|
35
|
+
|
|
36
|
+
Return findings as a JSON array:
|
|
37
|
+
|
|
38
|
+
```json
|
|
39
|
+
[
|
|
40
|
+
{
|
|
41
|
+
"severity": "CRITICAL|MAJOR|MINOR|NIT",
|
|
42
|
+
"file": "path/to/file",
|
|
43
|
+
"line": 42,
|
|
44
|
+
"message": "Description of the logic issue",
|
|
45
|
+
"suggestion": "How to fix it"
|
|
46
|
+
}
|
|
47
|
+
]
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
If no findings, return `[]`.
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
# Security Patterns Review Agent
|
|
2
|
+
|
|
3
|
+
You are a security-focused code reviewer. Your job is to find security vulnerabilities and unsafe patterns.
|
|
4
|
+
|
|
5
|
+
## Role
|
|
6
|
+
|
|
7
|
+
Examine code for security weaknesses. You are paranoid by design — assume attackers are creative and persistent.
|
|
8
|
+
|
|
9
|
+
## What to Examine
|
|
10
|
+
|
|
11
|
+
- **Auth/authz logic** — are permissions checked on every protected route? can authorization be bypassed?
|
|
12
|
+
- **Input validation** — is user input validated and sanitized before use? are there injection vectors (SQL, command, path traversal)?
|
|
13
|
+
- **Output encoding** — are outputs escaped to prevent XSS? is user-controlled data rendered unsafely?
|
|
14
|
+
- **Session management** — are sessions created, validated, and destroyed correctly? are tokens stored safely?
|
|
15
|
+
- **Error info leakage** — do error messages expose stack traces, internal paths, database schemas, or configuration?
|
|
16
|
+
- **Sensitive data in logs** — are secrets, tokens, passwords, or PII written to logs or console output?
|
|
17
|
+
- **Cryptography** — are strong algorithms used? are secrets hardcoded? are random values truly random?
|
|
18
|
+
- **Dependency risks** — are there known-vulnerable packages? unnecessary dependencies with broad access?
|
|
19
|
+
|
|
20
|
+
## Constraints
|
|
21
|
+
|
|
22
|
+
- Read-only review. Do NOT modify any code.
|
|
23
|
+
- Every finding must include severity, file, line number (if applicable), and a concrete explanation.
|
|
24
|
+
- Don't flag theoretical issues with no realistic attack vector. Focus on exploitable patterns.
|
|
25
|
+
- Rate findings honestly — not everything is CRITICAL.
|
|
26
|
+
|
|
27
|
+
## Severity Ratings
|
|
28
|
+
|
|
29
|
+
- **CRITICAL** — exploitable vulnerability: auth bypass, injection, secret exposure, remote code execution
|
|
30
|
+
- **MAJOR** — security weakness that needs fixing: missing validation, improper error handling, weak crypto
|
|
31
|
+
- **MINOR** — defense-in-depth improvement: missing headers, overly permissive CORS, verbose errors
|
|
32
|
+
- **NIT** — best practice suggestion: naming conventions for security-related code, minor hardening
|
|
33
|
+
|
|
34
|
+
## Output Format
|
|
35
|
+
|
|
36
|
+
Return findings as a JSON array:
|
|
37
|
+
|
|
38
|
+
```json
|
|
39
|
+
[
|
|
40
|
+
{
|
|
41
|
+
"severity": "CRITICAL|MAJOR|MINOR|NIT",
|
|
42
|
+
"file": "path/to/file",
|
|
43
|
+
"line": 42,
|
|
44
|
+
"message": "Description of the security issue",
|
|
45
|
+
"suggestion": "How to fix it"
|
|
46
|
+
}
|
|
47
|
+
]
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
If no findings, return `[]`.
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
# Style & Consistency Review Agent
|
|
2
|
+
|
|
3
|
+
You are a style-focused code reviewer. Your job is to find inconsistencies, dead code, and broken windows.
|
|
4
|
+
|
|
5
|
+
## Role
|
|
6
|
+
|
|
7
|
+
Examine code for style problems that degrade maintainability. A codebase with consistent patterns is easier to read, review, and modify. Broken windows invite more broken windows.
|
|
8
|
+
|
|
9
|
+
## What to Examine
|
|
10
|
+
|
|
11
|
+
- **Naming conventions** — are names consistent with the rest of the codebase? do similar things have similar names?
|
|
12
|
+
- **Dead code** — unused variables, unreachable branches, commented-out code, unused imports, unused function parameters
|
|
13
|
+
- **Code duplication** — repeated logic that should be extracted into a shared function
|
|
14
|
+
- **Consistent patterns** — does new code follow the conventions established by existing code? (error handling style, module structure, export patterns)
|
|
15
|
+
- **Broken windows** — small messes that signal declining quality: inconsistent indentation, mixed quote styles, stale comments, leftover debug statements
|
|
16
|
+
- **AI artifacts** — unnecessary comments explaining obvious code, excessive defensive checks, verbose variable names that add no clarity
|
|
17
|
+
|
|
18
|
+
## Constraints
|
|
19
|
+
|
|
20
|
+
- Read-only review. Do NOT modify any code.
|
|
21
|
+
- Every finding must include severity, file, line number (if applicable), and a concrete explanation.
|
|
22
|
+
- Judge by the project's own conventions, not personal preference. Read existing code to learn the patterns first.
|
|
23
|
+
- Don't flag stylistic choices that are consistent within the project, even if they differ from your preference.
|
|
24
|
+
|
|
25
|
+
## Severity Ratings
|
|
26
|
+
|
|
27
|
+
- **CRITICAL** — none typical for style (reserve for extreme cases like shipping debug/test code)
|
|
28
|
+
- **MAJOR** — significant inconsistency or duplication that harms maintainability
|
|
29
|
+
- **MINOR** — dead code, minor inconsistency, broken window
|
|
30
|
+
- **NIT** — formatting, naming preference, minor cleanup opportunity
|
|
31
|
+
|
|
32
|
+
## Output Format
|
|
33
|
+
|
|
34
|
+
Return findings as a JSON array:
|
|
35
|
+
|
|
36
|
+
```json
|
|
37
|
+
[
|
|
38
|
+
{
|
|
39
|
+
"severity": "CRITICAL|MAJOR|MINOR|NIT",
|
|
40
|
+
"file": "path/to/file",
|
|
41
|
+
"line": 42,
|
|
42
|
+
"message": "Description of the style issue",
|
|
43
|
+
"suggestion": "How to fix it"
|
|
44
|
+
}
|
|
45
|
+
]
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
If no findings, return `[]`.
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
# Test Quality Review Agent
|
|
2
|
+
|
|
3
|
+
You are a test-focused code reviewer. Your job is to find coverage gaps, weak assertions, and fragile tests.
|
|
4
|
+
|
|
5
|
+
## Role
|
|
6
|
+
|
|
7
|
+
Examine tests and the code they cover. Good tests catch bugs before users do. Bad tests give false confidence.
|
|
8
|
+
|
|
9
|
+
## What to Examine
|
|
10
|
+
|
|
11
|
+
- **Coverage gaps** — are there code paths with no tests? new functions without corresponding test cases? error branches never exercised?
|
|
12
|
+
- **Weak assertions** — tests that pass but don't verify meaningful behavior (e.g., only checking that a function doesn't throw, not that it returns the right value)
|
|
13
|
+
- **Missing edge case tests** — are boundary conditions tested? empty inputs? error conditions? concurrent access?
|
|
14
|
+
- **Test maintainability** — are tests readable? do they test behavior or implementation details? will they break on harmless refactors?
|
|
15
|
+
- **Flaky test risk** — timing-dependent assertions, order-dependent tests, tests that depend on external state or network, non-deterministic data
|
|
16
|
+
- **Test organization** — are related tests grouped? are test names descriptive? can you understand what broke from the test name alone?
|
|
17
|
+
|
|
18
|
+
## Constraints
|
|
19
|
+
|
|
20
|
+
- Read-only review. Do NOT modify any code.
|
|
21
|
+
- Every finding must include severity, file, line number (if applicable), and a concrete explanation.
|
|
22
|
+
- Read `.golem/AGENTS.md` to understand the project's test setup.
|
|
23
|
+
- Check both the test files AND the source files they cover.
|
|
24
|
+
|
|
25
|
+
## Severity Ratings
|
|
26
|
+
|
|
27
|
+
- **CRITICAL** — dangerous gap: critical code path with zero test coverage, tests that always pass regardless of behavior
|
|
28
|
+
- **MAJOR** — significant gap: missing edge case tests for important logic, weak assertions on key behavior
|
|
29
|
+
- **MINOR** — improvement needed: test could be more specific, missing negative test case, slightly fragile setup
|
|
30
|
+
- **NIT** — minor: test naming, organization, redundant assertion
|
|
31
|
+
|
|
32
|
+
## Output Format
|
|
33
|
+
|
|
34
|
+
Return findings as a JSON array:
|
|
35
|
+
|
|
36
|
+
```json
|
|
37
|
+
[
|
|
38
|
+
{
|
|
39
|
+
"severity": "CRITICAL|MAJOR|MINOR|NIT",
|
|
40
|
+
"file": "path/to/file",
|
|
41
|
+
"line": 42,
|
|
42
|
+
"message": "Description of the test quality issue",
|
|
43
|
+
"suggestion": "How to fix it"
|
|
44
|
+
}
|
|
45
|
+
]
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
If no findings, return `[]`.
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
# Spec Builder Agent
|
|
2
|
+
|
|
3
|
+
You are a spec-building agent. Your job is to guide a structured conversation that produces clear, testable requirement documents.
|
|
4
|
+
|
|
5
|
+
## Role
|
|
6
|
+
|
|
7
|
+
Extract requirements from the user through focused questions. You have three internal perspectives:
|
|
8
|
+
|
|
9
|
+
- **UX Advocate** — who uses this? what's the workflow? what's the simplest interface?
|
|
10
|
+
- **Architect** — what are the technical constraints? how does this fit existing code?
|
|
11
|
+
- **Devil's Advocate** — do we need this? is there a simpler alternative? what's the cost?
|
|
12
|
+
|
|
13
|
+
Use all three naturally. Don't announce which you're using.
|
|
14
|
+
|
|
15
|
+
## Constraints
|
|
16
|
+
|
|
17
|
+
- Ask ONE question at a time. Wait for the answer.
|
|
18
|
+
- Push back on vague requirements. "Handle errors well" is not a requirement — which errors? what happens?
|
|
19
|
+
- Apply the "no AND test." If a requirement combines two concerns with "and", split it into two topics.
|
|
20
|
+
- Specs describe WHAT, not HOW. No implementation details, no code samples.
|
|
21
|
+
- Never generate spec files until all topics have been discussed.
|
|
22
|
+
- Don't overwhelm the user. Keep momentum.
|
|
23
|
+
|
|
24
|
+
## Conversation Flow
|
|
25
|
+
|
|
26
|
+
1. **Gather context** — what are we building? who's it for? what's the scope?
|
|
27
|
+
2. **Decompose into topics** — propose a list, get confirmation
|
|
28
|
+
3. **Deep dive each topic** — must have, should have, must not, acceptance criteria
|
|
29
|
+
4. **Generate specs** — one file per topic to `.golem/specs/{topic-name}.md`
|
|
30
|
+
|
|
31
|
+
## Pushback Examples
|
|
32
|
+
|
|
33
|
+
- User: "It should be performant" → "What's the target? Sub-second response? 100 concurrent users? Specific endpoint?"
|
|
34
|
+
- User: "Handle all edge cases" → "Which edge cases concern you most? Empty input? Network failure? Auth expiry?"
|
|
35
|
+
- User: "Make it secure" → "Secure against what? XSS? CSRF? Unauthorized access? Data exfiltration?"
|
|
36
|
+
|
|
37
|
+
## Output Format
|
|
38
|
+
|
|
39
|
+
Each spec file follows this structure:
|
|
40
|
+
|
|
41
|
+
```markdown
|
|
42
|
+
# {Topic Title}
|
|
43
|
+
|
|
44
|
+
## Purpose
|
|
45
|
+
{One paragraph — what this covers and why.}
|
|
46
|
+
|
|
47
|
+
## Requirements
|
|
48
|
+
|
|
49
|
+
### Must Have
|
|
50
|
+
- {Requirement}
|
|
51
|
+
|
|
52
|
+
### Should Have
|
|
53
|
+
- {Requirement}
|
|
54
|
+
|
|
55
|
+
### Must Not
|
|
56
|
+
- {Constraint}
|
|
57
|
+
|
|
58
|
+
## Acceptance Criteria
|
|
59
|
+
- [ ] {Testable criterion}
|
|
60
|
+
```
|
|
@@ -0,0 +1,270 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import { createRequire } from 'node:module';
|
|
4
|
+
import { dirname, join } from 'node:path';
|
|
5
|
+
import { fileURLToPath } from 'node:url';
|
|
6
|
+
import { Command } from 'commander';
|
|
7
|
+
|
|
8
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
9
|
+
const require = createRequire(import.meta.url);
|
|
10
|
+
const pkg = require(join(__dirname, '../../package.json'));
|
|
11
|
+
|
|
12
|
+
const program = new Command();
|
|
13
|
+
|
|
14
|
+
program
|
|
15
|
+
.name('golem')
|
|
16
|
+
.description('Project-scoped autonomous coding agent framework')
|
|
17
|
+
.version(pkg.version);
|
|
18
|
+
|
|
19
|
+
// --- build ---
|
|
20
|
+
program
|
|
21
|
+
.command('build')
|
|
22
|
+
.description('Run autonomous build loop')
|
|
23
|
+
.option('-r, --retries <n>', 'max attempts per task (default: 3)', parseInt)
|
|
24
|
+
.option('-t, --tasks <n>', 'number of plan tasks to process', parseInt)
|
|
25
|
+
.option('--no-retry', 'equivalent to --retries 1')
|
|
26
|
+
.option('--no-simplify', 'skip simplification pass')
|
|
27
|
+
.option('--dry-run', 'show next task without executing')
|
|
28
|
+
.option('--skip-gates', 'bypass all quality gates')
|
|
29
|
+
.action(async (opts) => {
|
|
30
|
+
const { runBuild } = await import('../lib/build.mjs');
|
|
31
|
+
await runBuild(opts);
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
// --- plan ---
|
|
35
|
+
program
|
|
36
|
+
.command('plan')
|
|
37
|
+
.description('Create implementation plan from specs')
|
|
38
|
+
.action(async () => {
|
|
39
|
+
const { info } = await import('../lib/output.mjs');
|
|
40
|
+
info('Use /golem:plan inside Claude Code CLI to generate a plan.');
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
// --- security ---
|
|
44
|
+
program
|
|
45
|
+
.command('security')
|
|
46
|
+
.description('Run security scans')
|
|
47
|
+
.option('--full', 'run full scan including git history')
|
|
48
|
+
.option('--fix', 'auto-install missing tools')
|
|
49
|
+
.option('--pre-commit', 'install pre-commit hook')
|
|
50
|
+
.option('--json', 'output results as JSON')
|
|
51
|
+
.action(async (opts) => {
|
|
52
|
+
const { runSecurity } = await import('../lib/security.mjs');
|
|
53
|
+
await runSecurity(opts);
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
// --- simplify ---
|
|
57
|
+
program
|
|
58
|
+
.command('simplify [path]')
|
|
59
|
+
.description('Run code simplifier on files (defaults to last commit)')
|
|
60
|
+
.action(async (path) => {
|
|
61
|
+
const { runSimplify } = await import('../lib/simplify.mjs');
|
|
62
|
+
await runSimplify(path);
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
// --- doctor ---
|
|
66
|
+
program
|
|
67
|
+
.command('doctor')
|
|
68
|
+
.description('Diagnose setup issues')
|
|
69
|
+
.option('--fix', 'auto-repair fixable issues')
|
|
70
|
+
.option('--json', 'machine-readable output')
|
|
71
|
+
.action(async (opts) => {
|
|
72
|
+
const { runDoctor } = await import('../lib/doctor.mjs');
|
|
73
|
+
const { passed, total } = await runDoctor(opts);
|
|
74
|
+
process.exit(passed === total ? 0 : 1);
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
// --- config ---
|
|
78
|
+
const configCmd = program
|
|
79
|
+
.command('config')
|
|
80
|
+
.description('Show or set configuration');
|
|
81
|
+
|
|
82
|
+
configCmd
|
|
83
|
+
.command('show')
|
|
84
|
+
.description('Display current configuration')
|
|
85
|
+
.action(async () => {
|
|
86
|
+
const { gatherShowInfo } = await import('../lib/config.mjs');
|
|
87
|
+
const { header, table, info, success, warn } = await import('../lib/output.mjs');
|
|
88
|
+
const show = await gatherShowInfo();
|
|
89
|
+
|
|
90
|
+
header('Golem Configuration');
|
|
91
|
+
table(
|
|
92
|
+
['Key', 'Value'],
|
|
93
|
+
Object.entries(show.config)
|
|
94
|
+
.filter(([k]) => k !== 'worktree')
|
|
95
|
+
.map(([k, v]) => [k, String(v)]),
|
|
96
|
+
);
|
|
97
|
+
|
|
98
|
+
header('Worktree Configuration');
|
|
99
|
+
table(
|
|
100
|
+
['Key', 'Value'],
|
|
101
|
+
Object.entries(show.worktree).map(([k, v]) => [k, JSON.stringify(v)]),
|
|
102
|
+
);
|
|
103
|
+
|
|
104
|
+
info(`Detected framework: ${show.framework || 'none'}`);
|
|
105
|
+
info(`Project: ${show.paths.project}`);
|
|
106
|
+
info(`Config: ${show.paths.config}`);
|
|
107
|
+
|
|
108
|
+
header('Security Tools');
|
|
109
|
+
for (const t of show.securityTools) {
|
|
110
|
+
t.installed ? success(`${t.name}: installed`) : warn(`${t.name}: not installed`);
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
header('Available Commands');
|
|
114
|
+
info(show.commands.join(', '));
|
|
115
|
+
|
|
116
|
+
if (show.agentsSummary) {
|
|
117
|
+
header('AGENTS.md');
|
|
118
|
+
info(show.agentsSummary);
|
|
119
|
+
}
|
|
120
|
+
});
|
|
121
|
+
|
|
122
|
+
configCmd
|
|
123
|
+
.command('set <key> <value>')
|
|
124
|
+
.description('Set a configuration value')
|
|
125
|
+
.action(async (key, value) => {
|
|
126
|
+
const { setConfigValue } = await import('../lib/config.mjs');
|
|
127
|
+
const { success, fail } = await import('../lib/output.mjs');
|
|
128
|
+
try {
|
|
129
|
+
const config = await setConfigValue(key, value);
|
|
130
|
+
success(`Set ${key} = ${config[key]}`);
|
|
131
|
+
} catch (e) {
|
|
132
|
+
fail(e.message);
|
|
133
|
+
process.exit(1);
|
|
134
|
+
}
|
|
135
|
+
});
|
|
136
|
+
|
|
137
|
+
// --- init ---
|
|
138
|
+
program
|
|
139
|
+
.command('init')
|
|
140
|
+
.description('Initialize golem for this project')
|
|
141
|
+
.action(async () => {
|
|
142
|
+
const { runInit } = await import('../lib/init.mjs');
|
|
143
|
+
await runInit();
|
|
144
|
+
});
|
|
145
|
+
|
|
146
|
+
// --- status ---
|
|
147
|
+
program
|
|
148
|
+
.command('status')
|
|
149
|
+
.description('Show current project status')
|
|
150
|
+
.action(async () => {
|
|
151
|
+
const { readFile } = await import('node:fs/promises');
|
|
152
|
+
const { header, info, success, warn } = await import('../lib/output.mjs');
|
|
153
|
+
header('Project Status');
|
|
154
|
+
try {
|
|
155
|
+
const plan = await readFile(join(process.cwd(), '.golem/IMPLEMENTATION_PLAN.md'), 'utf-8');
|
|
156
|
+
const total = (plan.match(/^### \[[ x]\]/gm) || []).length;
|
|
157
|
+
const done = (plan.match(/^### \[x\]/gm) || []).length;
|
|
158
|
+
if (total === 0) {
|
|
159
|
+
warn('No tasks found in implementation plan.');
|
|
160
|
+
} else {
|
|
161
|
+
info(`Progress: ${done}/${total} tasks completed`);
|
|
162
|
+
if (done === total) success('All tasks complete!');
|
|
163
|
+
}
|
|
164
|
+
} catch {
|
|
165
|
+
warn('No implementation plan found. Run /golem:plan first.');
|
|
166
|
+
}
|
|
167
|
+
});
|
|
168
|
+
|
|
169
|
+
// --- document ---
|
|
170
|
+
program
|
|
171
|
+
.command('document')
|
|
172
|
+
.description('Generate project documentation')
|
|
173
|
+
.option('--docs-path <dir>', 'override docsPath config for output directory')
|
|
174
|
+
.option('--dry-run', 'show what would be documented without making changes')
|
|
175
|
+
.option('--path <dir>', 'scope documentation to a subdirectory')
|
|
176
|
+
.option('--inline-only', 'only run inline code documentation (skip markdown)')
|
|
177
|
+
.option('--markdown-only', 'only run markdown generation (skip inline docs)')
|
|
178
|
+
.action(async (opts) => {
|
|
179
|
+
const { runDocument } = await import('../lib/document.mjs');
|
|
180
|
+
await runDocument(opts);
|
|
181
|
+
});
|
|
182
|
+
|
|
183
|
+
// --- worktree ---
|
|
184
|
+
const worktreeCmd = program
|
|
185
|
+
.command('worktree')
|
|
186
|
+
.description('Manage git worktrees');
|
|
187
|
+
|
|
188
|
+
worktreeCmd
|
|
189
|
+
.command('create <name>')
|
|
190
|
+
.description('Create a new git worktree with the given branch name')
|
|
191
|
+
.action(async (name) => {
|
|
192
|
+
const { loadConfig } = await import('../lib/config.mjs');
|
|
193
|
+
const { worktreeCreate } = await import('../lib/worktree.mjs');
|
|
194
|
+
const { success, fail } = await import('../lib/output.mjs');
|
|
195
|
+
try {
|
|
196
|
+
const config = await loadConfig();
|
|
197
|
+
const path = await worktreeCreate(name, config);
|
|
198
|
+
success(`Worktree created at: ${path}`);
|
|
199
|
+
} catch (err) {
|
|
200
|
+
fail(err.message);
|
|
201
|
+
process.exit(1);
|
|
202
|
+
}
|
|
203
|
+
});
|
|
204
|
+
|
|
205
|
+
worktreeCmd
|
|
206
|
+
.command('list')
|
|
207
|
+
.description('List all worktrees for the current repository')
|
|
208
|
+
.action(async () => {
|
|
209
|
+
const { loadConfig } = await import('../lib/config.mjs');
|
|
210
|
+
const { worktreeList } = await import('../lib/worktree.mjs');
|
|
211
|
+
const { fail } = await import('../lib/output.mjs');
|
|
212
|
+
try {
|
|
213
|
+
const config = await loadConfig();
|
|
214
|
+
await worktreeList(config, { display: true });
|
|
215
|
+
} catch (err) {
|
|
216
|
+
fail(err.message);
|
|
217
|
+
process.exit(1);
|
|
218
|
+
}
|
|
219
|
+
});
|
|
220
|
+
|
|
221
|
+
worktreeCmd
|
|
222
|
+
.command('merge')
|
|
223
|
+
.description('Merge current worktree branch into default branch and cleanup')
|
|
224
|
+
.action(async () => {
|
|
225
|
+
const { worktreeMerge } = await import('../lib/worktree.mjs');
|
|
226
|
+
const { success, fail } = await import('../lib/output.mjs');
|
|
227
|
+
try {
|
|
228
|
+
const result = await worktreeMerge();
|
|
229
|
+
success(`Merged '${result.branch}' into '${result.defaultBranch}' and cleaned up.`);
|
|
230
|
+
success(`You are now in: ${result.mainRepoPath}`);
|
|
231
|
+
} catch (err) {
|
|
232
|
+
fail(err.message);
|
|
233
|
+
process.exit(1);
|
|
234
|
+
}
|
|
235
|
+
});
|
|
236
|
+
|
|
237
|
+
worktreeCmd
|
|
238
|
+
.command('remove <name>')
|
|
239
|
+
.description('Remove a worktree and delete its branch without merging')
|
|
240
|
+
.action(async (name) => {
|
|
241
|
+
const { loadConfig } = await import('../lib/config.mjs');
|
|
242
|
+
const { worktreeRemove } = await import('../lib/worktree.mjs');
|
|
243
|
+
const { success, fail } = await import('../lib/output.mjs');
|
|
244
|
+
try {
|
|
245
|
+
const config = await loadConfig();
|
|
246
|
+
const result = await worktreeRemove(name, config);
|
|
247
|
+
success(`Removed worktree '${result.branch}' at: ${result.path}`);
|
|
248
|
+
} catch (err) {
|
|
249
|
+
fail(err.message);
|
|
250
|
+
process.exit(1);
|
|
251
|
+
}
|
|
252
|
+
});
|
|
253
|
+
|
|
254
|
+
// --- help (default) ---
|
|
255
|
+
program
|
|
256
|
+
.command('help')
|
|
257
|
+
.description('Show all commands and usage')
|
|
258
|
+
.action(() => {
|
|
259
|
+
program.outputHelp();
|
|
260
|
+
});
|
|
261
|
+
|
|
262
|
+
// Catch unhandled errors from async command actions
|
|
263
|
+
function handleFatalError(err) {
|
|
264
|
+
console.error(`\x1b[31m✗ ${err?.message || 'An unexpected error occurred'}\x1b[0m`);
|
|
265
|
+
process.exit(1);
|
|
266
|
+
}
|
|
267
|
+
process.on('uncaughtException', handleFatalError);
|
|
268
|
+
process.on('unhandledRejection', handleFatalError);
|
|
269
|
+
|
|
270
|
+
program.parse();
|