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
package/bin/golem
DELETED
|
@@ -1,1040 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env bash
|
|
2
|
-
#
|
|
3
|
-
# golem - Personal agentic workflow manager
|
|
4
|
-
#
|
|
5
|
-
# Integrates Freshworks tickets, Gitea issues, and Claude Code
|
|
6
|
-
# for a unified development workflow.
|
|
7
|
-
#
|
|
8
|
-
|
|
9
|
-
set -euo pipefail
|
|
10
|
-
|
|
11
|
-
VERSION="2.1.2"
|
|
12
|
-
GOLEM_HOME="${GOLEM_HOME:-$HOME/.golem}"
|
|
13
|
-
GOLEM_API="golem-api"
|
|
14
|
-
|
|
15
|
-
# Colors
|
|
16
|
-
RED='\033[0;31m'
|
|
17
|
-
GREEN='\033[0;32m'
|
|
18
|
-
YELLOW='\033[0;33m'
|
|
19
|
-
BLUE='\033[0;34m'
|
|
20
|
-
CYAN='\033[0;36m'
|
|
21
|
-
DIM='\033[0;90m'
|
|
22
|
-
BOLD='\033[1m'
|
|
23
|
-
NC='\033[0m' # No Color
|
|
24
|
-
|
|
25
|
-
# ============================================================================
|
|
26
|
-
# Helpers
|
|
27
|
-
# ============================================================================
|
|
28
|
-
|
|
29
|
-
print_banner() {
|
|
30
|
-
echo -e "${CYAN}"
|
|
31
|
-
echo " ██████╗ ██████╗ ██╗ ███████╗███╗ ███╗"
|
|
32
|
-
echo " ██╔════╝ ██╔═══██╗██║ ██╔════╝████╗ ████║"
|
|
33
|
-
echo " ██║ ███╗██║ ██║██║ █████╗ ██╔████╔██║"
|
|
34
|
-
echo " ██║ ██║██║ ██║██║ ██╔══╝ ██║╚██╔╝██║"
|
|
35
|
-
echo " ╚██████╔╝╚██████╔╝███████╗███████╗██║ ╚═╝ ██║"
|
|
36
|
-
echo " ╚═════╝ ╚═════╝ ╚══════╝╚══════╝╚═╝ ╚═╝"
|
|
37
|
-
echo -e "${NC}"
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
die() {
|
|
41
|
-
echo -e "${RED}Error:${NC} $1" >&2
|
|
42
|
-
exit 1
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
info() {
|
|
46
|
-
echo -e "${BLUE}→${NC} $1"
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
success() {
|
|
50
|
-
echo -e "${GREEN}✓${NC} $1"
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
warn() {
|
|
54
|
-
echo -e "${YELLOW}!${NC} $1"
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
dim() {
|
|
58
|
-
echo -e "${DIM}$1${NC}"
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
# Load environment from multiple locations (safely handles special chars)
|
|
62
|
-
load_env() {
|
|
63
|
-
local env_file
|
|
64
|
-
for env_file in "$GOLEM_HOME/.env" ".env"; do
|
|
65
|
-
if [[ -f "$env_file" ]]; then
|
|
66
|
-
while IFS='=' read -r key value; do
|
|
67
|
-
# Skip comments and empty lines
|
|
68
|
-
[[ -z "$key" || "$key" =~ ^[[:space:]]*# ]] && continue
|
|
69
|
-
# Remove leading/trailing whitespace from key
|
|
70
|
-
key="${key#"${key%%[![:space:]]*}"}"
|
|
71
|
-
key="${key%"${key##*[![:space:]]}"}"
|
|
72
|
-
# Skip if not a valid variable name
|
|
73
|
-
[[ ! "$key" =~ ^[a-zA-Z_][a-zA-Z0-9_]*$ ]] && continue
|
|
74
|
-
# Export the variable (value keeps quotes if present)
|
|
75
|
-
export "$key=$value"
|
|
76
|
-
done < "$env_file"
|
|
77
|
-
fi
|
|
78
|
-
done
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
# Check if golem-api is available
|
|
82
|
-
check_api() {
|
|
83
|
-
if ! command -v "$GOLEM_API" &>/dev/null; then
|
|
84
|
-
die "golem-api not found. Run 'pnpm build' in golem directory first."
|
|
85
|
-
fi
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
# Get current ticket ID from worktree path
|
|
89
|
-
get_current_ticket() {
|
|
90
|
-
local branch
|
|
91
|
-
branch=$(git rev-parse --abbrev-ref HEAD 2>/dev/null || echo "")
|
|
92
|
-
echo "$branch" | grep -oE '(INC|SR)-[0-9]+' || echo ""
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
# ============================================================================
|
|
96
|
-
# Commands
|
|
97
|
-
# ============================================================================
|
|
98
|
-
|
|
99
|
-
cmd_help() {
|
|
100
|
-
print_banner
|
|
101
|
-
cat << 'EOF'
|
|
102
|
-
USAGE:
|
|
103
|
-
golem <command> [options]
|
|
104
|
-
|
|
105
|
-
TICKET COMMANDS:
|
|
106
|
-
new <subject> Create new ticket in Fresh + Gitea
|
|
107
|
-
import <INC-XXXX> Import existing Fresh ticket
|
|
108
|
-
list List all tracked tickets
|
|
109
|
-
status [ticket] Show ticket status
|
|
110
|
-
|
|
111
|
-
WORKTREE COMMANDS:
|
|
112
|
-
worktree [ticket] Create/switch to worktree for ticket
|
|
113
|
-
worktrees List all worktrees
|
|
114
|
-
|
|
115
|
-
BUILD COMMANDS:
|
|
116
|
-
build Run autonomous build loop (spawns Claude)
|
|
117
|
-
plan Generate implementation plan
|
|
118
|
-
simplify [files] Run code simplifier
|
|
119
|
-
squash Squash current stage commits
|
|
120
|
-
|
|
121
|
-
SYNC COMMANDS:
|
|
122
|
-
sync Sync ticket status to Fresh/Gitea
|
|
123
|
-
pr Create PR for current ticket
|
|
124
|
-
|
|
125
|
-
OTHER:
|
|
126
|
-
update [version] Update golem (default: latest)
|
|
127
|
-
install Install golem globally
|
|
128
|
-
uninstall Remove golem completely
|
|
129
|
-
config Show current configuration
|
|
130
|
-
doctor Diagnose setup issues
|
|
131
|
-
init Initialize golem in current project
|
|
132
|
-
version Show version
|
|
133
|
-
help Show this help
|
|
134
|
-
|
|
135
|
-
CLAUDE COMMANDS (inside Claude Code):
|
|
136
|
-
/golem:spec Define specs (agent team: UX, Architect, Devil's Advocate)
|
|
137
|
-
/golem:plan Create implementation plan (agent team per layer)
|
|
138
|
-
/golem:build Build lead + builders (observable, interruptible)
|
|
139
|
-
/golem:security Run security scans (gitleaks, semgrep, pnpm audit, trivy)
|
|
140
|
-
/golem:review Security + code review (runs security first, then agent team)
|
|
141
|
-
/golem:simplify Run code simplifier
|
|
142
|
-
/golem:status Show current status
|
|
143
|
-
/golem:help Show help
|
|
144
|
-
|
|
145
|
-
EOF
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
cmd_version() {
|
|
149
|
-
print_banner
|
|
150
|
-
echo " v$VERSION"
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
cmd_init() {
|
|
154
|
-
print_banner
|
|
155
|
-
|
|
156
|
-
# Validate global installation
|
|
157
|
-
if [[ ! -d "$GOLEM_HOME/lib" ]]; then
|
|
158
|
-
warn "Golem is not installed globally."
|
|
159
|
-
echo " Run: pnpm dlx golem-cc"
|
|
160
|
-
echo ""
|
|
161
|
-
fi
|
|
162
|
-
|
|
163
|
-
info "Initializing golem in current project..."
|
|
164
|
-
|
|
165
|
-
mkdir -p .golem/{specs,tickets,worktrees}
|
|
166
|
-
|
|
167
|
-
if [[ ! -f .golem/AGENTS.md ]]; then
|
|
168
|
-
cat > .golem/AGENTS.md << 'EOF'
|
|
169
|
-
# Operational Guide
|
|
170
|
-
|
|
171
|
-
## Commands
|
|
172
|
-
|
|
173
|
-
### Testing
|
|
174
|
-
```bash
|
|
175
|
-
pnpm test
|
|
176
|
-
```
|
|
177
|
-
|
|
178
|
-
### Type Checking
|
|
179
|
-
```bash
|
|
180
|
-
pnpm typecheck
|
|
181
|
-
```
|
|
182
|
-
|
|
183
|
-
### Linting
|
|
184
|
-
```bash
|
|
185
|
-
pnpm lint
|
|
186
|
-
```
|
|
187
|
-
|
|
188
|
-
## Learnings
|
|
189
|
-
<!-- Updated during build iterations -->
|
|
190
|
-
EOF
|
|
191
|
-
success "Created .golem/AGENTS.md"
|
|
192
|
-
fi
|
|
193
|
-
|
|
194
|
-
# Link commands to Claude
|
|
195
|
-
mkdir -p .claude/commands
|
|
196
|
-
if [[ -d "$GOLEM_HOME/commands/golem" ]]; then
|
|
197
|
-
ln -sf "$GOLEM_HOME/commands/golem" .claude/commands/golem 2>/dev/null || true
|
|
198
|
-
success "Linked Claude commands"
|
|
199
|
-
else
|
|
200
|
-
warn "Claude commands not found (install golem globally first)"
|
|
201
|
-
fi
|
|
202
|
-
|
|
203
|
-
# Add .golem to .gitignore
|
|
204
|
-
if [[ -f .gitignore ]]; then
|
|
205
|
-
if ! grep -q "^\.golem/worktrees" .gitignore 2>/dev/null; then
|
|
206
|
-
echo -e "\n# Golem worktrees\n.golem/worktrees/" >> .gitignore
|
|
207
|
-
success "Updated .gitignore"
|
|
208
|
-
fi
|
|
209
|
-
fi
|
|
210
|
-
|
|
211
|
-
success "Golem initialized"
|
|
212
|
-
}
|
|
213
|
-
|
|
214
|
-
cmd_new() {
|
|
215
|
-
local subject="${1:-}"
|
|
216
|
-
[[ -z "$subject" ]] && die "Usage: golem new <subject>"
|
|
217
|
-
|
|
218
|
-
print_banner
|
|
219
|
-
check_api
|
|
220
|
-
load_env
|
|
221
|
-
|
|
222
|
-
local repo="${GITEA_REPO:-}"
|
|
223
|
-
[[ -z "$repo" ]] && die "GITEA_REPO not set"
|
|
224
|
-
|
|
225
|
-
echo -e "${BOLD}Creating new ticket${NC}"
|
|
226
|
-
echo ""
|
|
227
|
-
|
|
228
|
-
read -p "Type (feat/fix/refactor/docs/test/chore) [fix]: " type
|
|
229
|
-
type="${type:-fix}"
|
|
230
|
-
|
|
231
|
-
read -p "Slug (for branch name): " slug
|
|
232
|
-
[[ -z "$slug" ]] && die "Slug required"
|
|
233
|
-
|
|
234
|
-
read -p "Description (optional): " description
|
|
235
|
-
description="${description:-$subject}"
|
|
236
|
-
|
|
237
|
-
read -p "Priority (1=Urgent, 2=High, 3=Medium, 4=Low) [3]: " priority
|
|
238
|
-
priority="${priority:-3}"
|
|
239
|
-
|
|
240
|
-
info "Creating ticket..."
|
|
241
|
-
$GOLEM_API ticket:new \
|
|
242
|
-
--subject "$subject" \
|
|
243
|
-
--description "$description" \
|
|
244
|
-
--type "$type" \
|
|
245
|
-
--slug "$slug" \
|
|
246
|
-
--priority "$priority" \
|
|
247
|
-
--repo "$repo"
|
|
248
|
-
}
|
|
249
|
-
|
|
250
|
-
cmd_import() {
|
|
251
|
-
local ticket_id="${1:-}"
|
|
252
|
-
[[ -z "$ticket_id" ]] && die "Usage: golem import <INC-XXXX>"
|
|
253
|
-
|
|
254
|
-
print_banner
|
|
255
|
-
check_api
|
|
256
|
-
load_env
|
|
257
|
-
|
|
258
|
-
local repo="${GITEA_REPO:-}"
|
|
259
|
-
[[ -z "$repo" ]] && die "GITEA_REPO not set"
|
|
260
|
-
|
|
261
|
-
echo -e "${BOLD}Importing ticket $ticket_id${NC}"
|
|
262
|
-
echo ""
|
|
263
|
-
|
|
264
|
-
read -p "Type (feat/fix/refactor/docs/test/chore) [fix]: " type
|
|
265
|
-
type="${type:-fix}"
|
|
266
|
-
|
|
267
|
-
read -p "Slug (for branch name): " slug
|
|
268
|
-
[[ -z "$slug" ]] && die "Slug required"
|
|
269
|
-
|
|
270
|
-
info "Importing..."
|
|
271
|
-
$GOLEM_API ticket:import "$ticket_id" \
|
|
272
|
-
--type "$type" \
|
|
273
|
-
--slug "$slug" \
|
|
274
|
-
--repo "$repo"
|
|
275
|
-
}
|
|
276
|
-
|
|
277
|
-
cmd_list() {
|
|
278
|
-
check_api
|
|
279
|
-
load_env
|
|
280
|
-
$GOLEM_API ticket:list
|
|
281
|
-
}
|
|
282
|
-
|
|
283
|
-
cmd_status() {
|
|
284
|
-
local ticket_id="${1:-$(get_current_ticket)}"
|
|
285
|
-
|
|
286
|
-
print_banner
|
|
287
|
-
|
|
288
|
-
if [[ -z "$ticket_id" ]]; then
|
|
289
|
-
# Show general status
|
|
290
|
-
echo -e "${BOLD}Status${NC}"
|
|
291
|
-
echo ""
|
|
292
|
-
|
|
293
|
-
if [[ -d .golem ]]; then
|
|
294
|
-
local spec_count=$(ls .golem/specs/*.md 2>/dev/null | wc -l | tr -d ' ')
|
|
295
|
-
echo "Specs: $spec_count"
|
|
296
|
-
|
|
297
|
-
if [[ -f .golem/IMPLEMENTATION_PLAN.md ]]; then
|
|
298
|
-
local total=$(grep -cE '^(###|-) \[' .golem/IMPLEMENTATION_PLAN.md 2>/dev/null || echo 0)
|
|
299
|
-
local done=$(grep -cE '^(###|-) \[x\]' .golem/IMPLEMENTATION_PLAN.md 2>/dev/null || echo 0)
|
|
300
|
-
echo "Tasks: $done / $total"
|
|
301
|
-
else
|
|
302
|
-
dim "No implementation plan"
|
|
303
|
-
fi
|
|
304
|
-
else
|
|
305
|
-
warn "Not a golem project. Run 'golem init'"
|
|
306
|
-
fi
|
|
307
|
-
else
|
|
308
|
-
check_api
|
|
309
|
-
load_env
|
|
310
|
-
$GOLEM_API ticket:get "$ticket_id"
|
|
311
|
-
fi
|
|
312
|
-
}
|
|
313
|
-
|
|
314
|
-
cmd_worktree() {
|
|
315
|
-
local ticket_id="${1:-$(get_current_ticket)}"
|
|
316
|
-
[[ -z "$ticket_id" ]] && die "Usage: golem worktree <INC-XXXX> or run from ticket branch"
|
|
317
|
-
|
|
318
|
-
check_api
|
|
319
|
-
load_env
|
|
320
|
-
|
|
321
|
-
info "Creating worktree for $ticket_id..."
|
|
322
|
-
local output
|
|
323
|
-
output=$($GOLEM_API worktree:create "$ticket_id" 2>&1) || {
|
|
324
|
-
echo "$output" >&2
|
|
325
|
-
die "Failed to create worktree"
|
|
326
|
-
}
|
|
327
|
-
|
|
328
|
-
local path
|
|
329
|
-
path=$(echo "$output" | tail -1)
|
|
330
|
-
|
|
331
|
-
success "Worktree created at $path"
|
|
332
|
-
echo ""
|
|
333
|
-
echo "To switch to it:"
|
|
334
|
-
echo " cd $path"
|
|
335
|
-
}
|
|
336
|
-
|
|
337
|
-
cmd_worktrees() {
|
|
338
|
-
check_api
|
|
339
|
-
$GOLEM_API worktree:list
|
|
340
|
-
}
|
|
341
|
-
|
|
342
|
-
cmd_build() {
|
|
343
|
-
local ticket_id
|
|
344
|
-
ticket_id=$(get_current_ticket)
|
|
345
|
-
|
|
346
|
-
print_banner
|
|
347
|
-
|
|
348
|
-
[[ -z "$ticket_id" ]] && warn "Not in a ticket worktree"
|
|
349
|
-
|
|
350
|
-
if [[ ! -f .golem/IMPLEMENTATION_PLAN.md ]]; then
|
|
351
|
-
die "No implementation plan. Run /golem:plan in Claude first."
|
|
352
|
-
fi
|
|
353
|
-
|
|
354
|
-
local remaining
|
|
355
|
-
remaining=$(grep -cE '^(###|-) \[ \]' .golem/IMPLEMENTATION_PLAN.md 2>/dev/null || echo 0)
|
|
356
|
-
|
|
357
|
-
if [[ "$remaining" -eq 0 ]]; then
|
|
358
|
-
success "All tasks complete!"
|
|
359
|
-
return 0
|
|
360
|
-
fi
|
|
361
|
-
|
|
362
|
-
info "Starting build loop ($remaining tasks remaining)"
|
|
363
|
-
echo ""
|
|
364
|
-
|
|
365
|
-
read -p "Continue? [y/N] " confirm
|
|
366
|
-
[[ "$confirm" != "y" && "$confirm" != "Y" ]] && exit 0
|
|
367
|
-
|
|
368
|
-
# Build the prompt from the build command file
|
|
369
|
-
local build_prompt
|
|
370
|
-
build_prompt=$(cat "$GOLEM_HOME/prompts/PROMPT_build.md")
|
|
371
|
-
|
|
372
|
-
# Loop until done
|
|
373
|
-
while true; do
|
|
374
|
-
remaining=$(grep -cE '^(###|-) \[ \]' .golem/IMPLEMENTATION_PLAN.md 2>/dev/null || echo 0)
|
|
375
|
-
|
|
376
|
-
if [[ "$remaining" -eq 0 ]]; then
|
|
377
|
-
success "All tasks complete!"
|
|
378
|
-
break
|
|
379
|
-
fi
|
|
380
|
-
|
|
381
|
-
info "Tasks remaining: $remaining"
|
|
382
|
-
info "Running Claude (print mode)..."
|
|
383
|
-
echo ""
|
|
384
|
-
|
|
385
|
-
# Run Claude in print mode with the build prompt
|
|
386
|
-
# --dangerously-skip-permissions allows tool use without confirmation
|
|
387
|
-
claude -p "$build_prompt" --dangerously-skip-permissions || true
|
|
388
|
-
|
|
389
|
-
echo ""
|
|
390
|
-
read -p "Continue to next task? [Y/n] " continue_choice
|
|
391
|
-
[[ "$continue_choice" == "n" || "$continue_choice" == "N" ]] && break
|
|
392
|
-
done
|
|
393
|
-
}
|
|
394
|
-
|
|
395
|
-
cmd_plan() {
|
|
396
|
-
print_banner
|
|
397
|
-
|
|
398
|
-
if [[ ! -d .golem/specs ]] || [[ -z "$(ls .golem/specs/*.md 2>/dev/null)" ]]; then
|
|
399
|
-
die "No specs found. Run /golem:spec in Claude first."
|
|
400
|
-
fi
|
|
401
|
-
|
|
402
|
-
info "Running Claude to generate plan..."
|
|
403
|
-
|
|
404
|
-
local plan_prompt
|
|
405
|
-
plan_prompt=$(cat "$GOLEM_HOME/prompts/PROMPT_plan.md")
|
|
406
|
-
|
|
407
|
-
claude -p "$plan_prompt" --dangerously-skip-permissions
|
|
408
|
-
}
|
|
409
|
-
|
|
410
|
-
cmd_simplify() {
|
|
411
|
-
print_banner
|
|
412
|
-
|
|
413
|
-
local files="${*:-}"
|
|
414
|
-
|
|
415
|
-
info "Running code simplifier..."
|
|
416
|
-
|
|
417
|
-
local simplify_prompt
|
|
418
|
-
simplify_prompt=$(cat "$GOLEM_HOME/agents/code-simplifier.md")
|
|
419
|
-
|
|
420
|
-
if [[ -n "$files" ]]; then
|
|
421
|
-
simplify_prompt="$simplify_prompt
|
|
422
|
-
|
|
423
|
-
Files to simplify: $files"
|
|
424
|
-
fi
|
|
425
|
-
|
|
426
|
-
claude -p "$simplify_prompt" --dangerously-skip-permissions
|
|
427
|
-
}
|
|
428
|
-
|
|
429
|
-
cmd_squash() {
|
|
430
|
-
local ticket_id message=""
|
|
431
|
-
ticket_id=$(get_current_ticket)
|
|
432
|
-
[[ -z "$ticket_id" ]] && die "Not in a ticket worktree"
|
|
433
|
-
|
|
434
|
-
# Parse arguments for -m flag
|
|
435
|
-
while [[ $# -gt 0 ]]; do
|
|
436
|
-
case "$1" in
|
|
437
|
-
-m|--message)
|
|
438
|
-
message="$2"
|
|
439
|
-
shift 2
|
|
440
|
-
;;
|
|
441
|
-
*)
|
|
442
|
-
shift
|
|
443
|
-
;;
|
|
444
|
-
esac
|
|
445
|
-
done
|
|
446
|
-
|
|
447
|
-
check_api
|
|
448
|
-
load_env
|
|
449
|
-
|
|
450
|
-
if [[ ! -f .golem/IMPLEMENTATION_PLAN.md ]]; then
|
|
451
|
-
die "No implementation plan found"
|
|
452
|
-
fi
|
|
453
|
-
|
|
454
|
-
echo -e "${BOLD}Squashing commits for $ticket_id${NC}"
|
|
455
|
-
echo ""
|
|
456
|
-
|
|
457
|
-
local commits
|
|
458
|
-
commits=$(git log --oneline origin/main..HEAD 2>/dev/null | wc -l | tr -d ' ')
|
|
459
|
-
echo "Commits to squash: $commits"
|
|
460
|
-
|
|
461
|
-
if [[ "$commits" -eq 0 ]]; then
|
|
462
|
-
warn "No commits to squash"
|
|
463
|
-
return 0
|
|
464
|
-
fi
|
|
465
|
-
|
|
466
|
-
# If message not provided via flag, prompt interactively
|
|
467
|
-
if [[ -z "$message" ]]; then
|
|
468
|
-
echo ""
|
|
469
|
-
read -p "Commit message: " message
|
|
470
|
-
[[ -z "$message" ]] && die "Commit message required"
|
|
471
|
-
fi
|
|
472
|
-
|
|
473
|
-
info "Squashing..."
|
|
474
|
-
$GOLEM_API git:squash "$ticket_id" -m "$message"
|
|
475
|
-
|
|
476
|
-
success "Squashed to single commit"
|
|
477
|
-
}
|
|
478
|
-
|
|
479
|
-
cmd_sync() {
|
|
480
|
-
local ticket_id
|
|
481
|
-
ticket_id=$(get_current_ticket)
|
|
482
|
-
[[ -z "$ticket_id" ]] && die "Not in a ticket worktree"
|
|
483
|
-
|
|
484
|
-
check_api
|
|
485
|
-
load_env
|
|
486
|
-
|
|
487
|
-
local repo="${GITEA_REPO:-}"
|
|
488
|
-
[[ -z "$repo" ]] && die "GITEA_REPO not set"
|
|
489
|
-
|
|
490
|
-
read -p "Status (new/spec/planning/in-progress/review/done/blocked): " status
|
|
491
|
-
read -p "Note (optional): " note
|
|
492
|
-
|
|
493
|
-
info "Syncing..."
|
|
494
|
-
$GOLEM_API ticket:status "$ticket_id" "$status" --repo "$repo" ${note:+--note "$note"}
|
|
495
|
-
}
|
|
496
|
-
|
|
497
|
-
cmd_pr() {
|
|
498
|
-
local ticket_id
|
|
499
|
-
ticket_id=$(get_current_ticket)
|
|
500
|
-
[[ -z "$ticket_id" ]] && die "Not in a ticket worktree"
|
|
501
|
-
|
|
502
|
-
check_api
|
|
503
|
-
load_env
|
|
504
|
-
|
|
505
|
-
# Push branch first
|
|
506
|
-
info "Pushing branch..."
|
|
507
|
-
$GOLEM_API git:push "$ticket_id"
|
|
508
|
-
|
|
509
|
-
# Get ticket info for PR title/body
|
|
510
|
-
local ticket_json
|
|
511
|
-
ticket_json=$($GOLEM_API ticket:get "$ticket_id" 2>/dev/null)
|
|
512
|
-
|
|
513
|
-
local subject
|
|
514
|
-
subject=$(echo "$ticket_json" | grep -o '"subject":"[^"]*"' | cut -d'"' -f4 || echo "$ticket_id")
|
|
515
|
-
|
|
516
|
-
local branch
|
|
517
|
-
branch=$(git rev-parse --abbrev-ref HEAD)
|
|
518
|
-
|
|
519
|
-
info "Creating PR..."
|
|
520
|
-
|
|
521
|
-
# Use gh CLI
|
|
522
|
-
gh pr create \
|
|
523
|
-
--title "[$ticket_id] $subject" \
|
|
524
|
-
--body "Closes Gitea issue.
|
|
525
|
-
|
|
526
|
-
---
|
|
527
|
-
Ticket: $ticket_id
|
|
528
|
-
Branch: $branch" \
|
|
529
|
-
--head "$branch"
|
|
530
|
-
|
|
531
|
-
# Update status
|
|
532
|
-
local repo="${GITEA_REPO:-}"
|
|
533
|
-
[[ -n "$repo" ]] && $GOLEM_API ticket:status "$ticket_id" "review" --repo "$repo" --note "PR created"
|
|
534
|
-
|
|
535
|
-
success "PR created"
|
|
536
|
-
}
|
|
537
|
-
|
|
538
|
-
# Resolve the package root from this script's location.
|
|
539
|
-
# When run via pnpm dlx, $0 lives inside a temp store.
|
|
540
|
-
# When run from ~/.golem/lib, $0 is there.
|
|
541
|
-
_resolve_pkg_root() {
|
|
542
|
-
local script_path
|
|
543
|
-
script_path="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
544
|
-
# bin/ is one level under package root
|
|
545
|
-
echo "$(cd "$script_path/.." && pwd)"
|
|
546
|
-
}
|
|
547
|
-
|
|
548
|
-
# Bootstrap: copy package contents into ~/.golem/lib and wire everything up.
|
|
549
|
-
cmd_bootstrap() {
|
|
550
|
-
local pkg_root
|
|
551
|
-
pkg_root="$(_resolve_pkg_root)"
|
|
552
|
-
|
|
553
|
-
print_banner
|
|
554
|
-
info "Installing golem to $GOLEM_HOME..."
|
|
555
|
-
|
|
556
|
-
# ---- runtime ----
|
|
557
|
-
mkdir -p "$GOLEM_HOME/lib"
|
|
558
|
-
# Copy the package runtime (bin, dist, node_modules, package.json)
|
|
559
|
-
for item in bin dist node_modules package.json; do
|
|
560
|
-
if [[ -e "$pkg_root/$item" ]]; then
|
|
561
|
-
rm -rf "$GOLEM_HOME/lib/$item"
|
|
562
|
-
cp -R "$pkg_root/$item" "$GOLEM_HOME/lib/$item"
|
|
563
|
-
fi
|
|
564
|
-
done
|
|
565
|
-
success "Installed runtime to $GOLEM_HOME/lib"
|
|
566
|
-
|
|
567
|
-
# ---- assets ----
|
|
568
|
-
mkdir -p "$GOLEM_HOME"/{commands,agents,prompts}
|
|
569
|
-
if [[ -d "$pkg_root/commands/golem" ]]; then
|
|
570
|
-
rm -rf "$GOLEM_HOME/commands/golem"
|
|
571
|
-
cp -R "$pkg_root/commands/golem" "$GOLEM_HOME/commands/golem"
|
|
572
|
-
fi
|
|
573
|
-
if compgen -G "$pkg_root/golem/agents/"*.md &>/dev/null; then
|
|
574
|
-
cp "$pkg_root/golem/agents/"*.md "$GOLEM_HOME/agents/"
|
|
575
|
-
fi
|
|
576
|
-
if compgen -G "$pkg_root/golem/prompts/"*.md &>/dev/null; then
|
|
577
|
-
cp "$pkg_root/golem/prompts/"*.md "$GOLEM_HOME/prompts/"
|
|
578
|
-
fi
|
|
579
|
-
success "Installed assets (commands, agents, prompts)"
|
|
580
|
-
|
|
581
|
-
# ---- symlinks in ~/.local/bin ----
|
|
582
|
-
mkdir -p "$HOME/.local/bin"
|
|
583
|
-
ln -sf "$GOLEM_HOME/lib/bin/golem" "$HOME/.local/bin/golem"
|
|
584
|
-
ln -sf "$GOLEM_HOME/lib/dist/cli/index.js" "$HOME/.local/bin/golem-api"
|
|
585
|
-
chmod +x "$GOLEM_HOME/lib/bin/golem"
|
|
586
|
-
chmod +x "$GOLEM_HOME/lib/dist/cli/index.js" 2>/dev/null || true
|
|
587
|
-
success "Linked binaries to ~/.local/bin"
|
|
588
|
-
|
|
589
|
-
# ---- Claude slash-commands ----
|
|
590
|
-
mkdir -p "$HOME/.claude/commands"
|
|
591
|
-
ln -sf "$GOLEM_HOME/commands/golem" "$HOME/.claude/commands/golem" 2>/dev/null || true
|
|
592
|
-
success "Linked Claude commands"
|
|
593
|
-
|
|
594
|
-
# ---- .env template ----
|
|
595
|
-
if [[ -f "$pkg_root/.env.example" ]]; then
|
|
596
|
-
cp "$pkg_root/.env.example" "$GOLEM_HOME/.env.example"
|
|
597
|
-
fi
|
|
598
|
-
if [[ ! -f "$GOLEM_HOME/.env" ]]; then
|
|
599
|
-
if [[ -f "$GOLEM_HOME/.env.example" ]]; then
|
|
600
|
-
cp "$GOLEM_HOME/.env.example" "$GOLEM_HOME/.env"
|
|
601
|
-
else
|
|
602
|
-
cat > "$GOLEM_HOME/.env" << 'ENVEOF'
|
|
603
|
-
# Freshworks/Freshservice
|
|
604
|
-
FRESH_DOMAIN=yourcompany.freshservice.com
|
|
605
|
-
FRESH_API_KEY=your_api_key_here
|
|
606
|
-
|
|
607
|
-
# Gitea (on-prem)
|
|
608
|
-
GITEA_URL=https://dev.pearlriverresort.com
|
|
609
|
-
GITEA_TOKEN=your_token_here
|
|
610
|
-
GITEA_ORG=CRDE
|
|
611
|
-
|
|
612
|
-
# Default repo for issues (can be overridden per-project)
|
|
613
|
-
GITEA_REPO=
|
|
614
|
-
ENVEOF
|
|
615
|
-
fi
|
|
616
|
-
warn "Created $GOLEM_HOME/.env — edit with your credentials"
|
|
617
|
-
fi
|
|
618
|
-
|
|
619
|
-
# ---- PATH setup (idempotent) ----
|
|
620
|
-
local shell_rc="$HOME/.zshrc"
|
|
621
|
-
[[ -f "$HOME/.bashrc" && ! -f "$HOME/.zshrc" ]] && shell_rc="$HOME/.bashrc"
|
|
622
|
-
|
|
623
|
-
if [[ -f "$shell_rc" ]]; then
|
|
624
|
-
if ! grep -q '$HOME/.local/bin' "$shell_rc" 2>/dev/null; then
|
|
625
|
-
echo '' >> "$shell_rc"
|
|
626
|
-
echo '# golem: add ~/.local/bin to PATH' >> "$shell_rc"
|
|
627
|
-
echo 'export PATH="$HOME/.local/bin:$PATH"' >> "$shell_rc"
|
|
628
|
-
success "Added ~/.local/bin to PATH in $(basename "$shell_rc")"
|
|
629
|
-
fi
|
|
630
|
-
fi
|
|
631
|
-
|
|
632
|
-
echo ""
|
|
633
|
-
success "Installation complete!"
|
|
634
|
-
echo ""
|
|
635
|
-
echo "Restart your shell (or run: source $shell_rc), then:"
|
|
636
|
-
echo " golem doctor # verify setup"
|
|
637
|
-
echo " golem config # show configuration"
|
|
638
|
-
echo " cd <project> && golem init # set up a project"
|
|
639
|
-
}
|
|
640
|
-
|
|
641
|
-
cmd_uninstall() {
|
|
642
|
-
print_banner
|
|
643
|
-
echo -e "${BOLD}This will remove:${NC}"
|
|
644
|
-
echo " $GOLEM_HOME (runtime, assets, config)"
|
|
645
|
-
echo " ~/.local/bin/golem (symlink)"
|
|
646
|
-
echo " ~/.local/bin/golem-api (symlink)"
|
|
647
|
-
echo " ~/.claude/commands/golem (symlink)"
|
|
648
|
-
echo ""
|
|
649
|
-
|
|
650
|
-
# Check for .env with real credentials and warn
|
|
651
|
-
if [[ -f "$GOLEM_HOME/.env" ]]; then
|
|
652
|
-
warn "Your credentials in $GOLEM_HOME/.env will be deleted."
|
|
653
|
-
echo " Back up now if needed: cp $GOLEM_HOME/.env ~/golem-env-backup"
|
|
654
|
-
echo ""
|
|
655
|
-
fi
|
|
656
|
-
|
|
657
|
-
read -p "Are you sure? [y/N] " confirm
|
|
658
|
-
[[ "$confirm" != "y" && "$confirm" != "Y" ]] && { echo "Aborted."; exit 0; }
|
|
659
|
-
|
|
660
|
-
# Remove symlinks in ~/.local/bin
|
|
661
|
-
for bin in golem golem-api; do
|
|
662
|
-
local target="$HOME/.local/bin/$bin"
|
|
663
|
-
if [[ -L "$target" || -f "$target" ]]; then
|
|
664
|
-
rm -f "$target"
|
|
665
|
-
success "Removed $target"
|
|
666
|
-
fi
|
|
667
|
-
done
|
|
668
|
-
|
|
669
|
-
# Remove Claude commands symlink
|
|
670
|
-
if [[ -L "$HOME/.claude/commands/golem" || -d "$HOME/.claude/commands/golem" ]]; then
|
|
671
|
-
rm -rf "$HOME/.claude/commands/golem"
|
|
672
|
-
success "Removed ~/.claude/commands/golem"
|
|
673
|
-
fi
|
|
674
|
-
|
|
675
|
-
# Remove ~/.golem entirely
|
|
676
|
-
if [[ -d "$GOLEM_HOME" ]]; then
|
|
677
|
-
rm -rf "$GOLEM_HOME"
|
|
678
|
-
success "Removed $GOLEM_HOME"
|
|
679
|
-
fi
|
|
680
|
-
|
|
681
|
-
echo ""
|
|
682
|
-
success "Golem uninstalled."
|
|
683
|
-
echo ""
|
|
684
|
-
dim "The PATH entry in your shell rc was left in place (it's harmless)."
|
|
685
|
-
dim "To reinstall later: pnpm dlx golem-cc"
|
|
686
|
-
}
|
|
687
|
-
|
|
688
|
-
cmd_install() {
|
|
689
|
-
# If --from <path> given, bootstrap from a local checkout (dev workflow)
|
|
690
|
-
if [[ "${1:-}" == "--from" ]]; then
|
|
691
|
-
local local_path="${2:-}"
|
|
692
|
-
[[ -z "$local_path" ]] && die "Usage: golem install --from <path>"
|
|
693
|
-
[[ ! -d "$local_path/bin" ]] && die "Not a golem package directory: $local_path"
|
|
694
|
-
|
|
695
|
-
# Temporarily override _resolve_pkg_root
|
|
696
|
-
_resolve_pkg_root() { echo "$local_path"; }
|
|
697
|
-
cmd_bootstrap
|
|
698
|
-
return
|
|
699
|
-
fi
|
|
700
|
-
|
|
701
|
-
# Default: install from npm
|
|
702
|
-
local version="${1:-latest}"
|
|
703
|
-
cmd_update "$version"
|
|
704
|
-
}
|
|
705
|
-
|
|
706
|
-
cmd_update() {
|
|
707
|
-
local version="${1:-latest}"
|
|
708
|
-
|
|
709
|
-
print_banner
|
|
710
|
-
info "Fetching golem-cc@$version from npm..."
|
|
711
|
-
|
|
712
|
-
# Download to temp directory
|
|
713
|
-
local tmp
|
|
714
|
-
tmp=$(mktemp -d)
|
|
715
|
-
trap "rm -rf '$tmp'" EXIT
|
|
716
|
-
|
|
717
|
-
if ! pnpm --prefix="$tmp" add "golem-cc@$version" --silent 2>/dev/null; then
|
|
718
|
-
die "Failed to fetch golem-cc@$version"
|
|
719
|
-
fi
|
|
720
|
-
|
|
721
|
-
local pkg_path="$tmp/node_modules/golem-cc"
|
|
722
|
-
[[ ! -d "$pkg_path/bin" ]] && die "Downloaded package is invalid"
|
|
723
|
-
|
|
724
|
-
# Bootstrap from downloaded package
|
|
725
|
-
_resolve_pkg_root() { echo "$pkg_path"; }
|
|
726
|
-
cmd_bootstrap
|
|
727
|
-
|
|
728
|
-
# Update current project if we're in one
|
|
729
|
-
if [[ -d ".golem" ]]; then
|
|
730
|
-
echo ""
|
|
731
|
-
info "Updating project..."
|
|
732
|
-
cmd_init
|
|
733
|
-
fi
|
|
734
|
-
|
|
735
|
-
trap - EXIT
|
|
736
|
-
rm -rf "$tmp"
|
|
737
|
-
}
|
|
738
|
-
|
|
739
|
-
cmd_config() {
|
|
740
|
-
print_banner
|
|
741
|
-
load_env
|
|
742
|
-
|
|
743
|
-
echo -e "${BOLD}Configuration${NC}"
|
|
744
|
-
echo ""
|
|
745
|
-
|
|
746
|
-
# Paths
|
|
747
|
-
echo -e "${BOLD}Paths${NC}"
|
|
748
|
-
echo " GOLEM_HOME: $GOLEM_HOME"
|
|
749
|
-
echo ""
|
|
750
|
-
|
|
751
|
-
# Env files
|
|
752
|
-
echo -e "${BOLD}Environment Files${NC}"
|
|
753
|
-
if [[ -f "$GOLEM_HOME/.env" ]]; then
|
|
754
|
-
success "$GOLEM_HOME/.env"
|
|
755
|
-
else
|
|
756
|
-
warn "$GOLEM_HOME/.env (not found)"
|
|
757
|
-
fi
|
|
758
|
-
if [[ -f ".env" ]]; then
|
|
759
|
-
success "./.env (local)"
|
|
760
|
-
else
|
|
761
|
-
dim " ./.env (not found)"
|
|
762
|
-
fi
|
|
763
|
-
echo ""
|
|
764
|
-
|
|
765
|
-
# Helper to print var status
|
|
766
|
-
print_var() {
|
|
767
|
-
local name="$1"
|
|
768
|
-
local value="$2"
|
|
769
|
-
local required="$3"
|
|
770
|
-
local secret="$4"
|
|
771
|
-
|
|
772
|
-
if [[ -n "$value" ]]; then
|
|
773
|
-
if [[ "$secret" == "true" ]]; then
|
|
774
|
-
echo -e " ${GREEN}$name${NC}: (set)"
|
|
775
|
-
else
|
|
776
|
-
echo -e " ${GREEN}$name${NC}: $value"
|
|
777
|
-
fi
|
|
778
|
-
elif [[ "$required" == "true" ]]; then
|
|
779
|
-
echo -e " ${RED}$name${NC}: (not set) - REQUIRED"
|
|
780
|
-
else
|
|
781
|
-
echo -e " ${YELLOW}$name${NC}: (not set)"
|
|
782
|
-
fi
|
|
783
|
-
}
|
|
784
|
-
|
|
785
|
-
# Freshservice vars
|
|
786
|
-
echo -e "${BOLD}Freshservice${NC}"
|
|
787
|
-
print_var "FRESH_DOMAIN" "${FRESH_DOMAIN:-}" "true" "false"
|
|
788
|
-
print_var "FRESH_API_KEY" "${FRESH_API_KEY:-}" "true" "true"
|
|
789
|
-
print_var "FRESH_DEFAULT_GROUP_ID" "${FRESH_DEFAULT_GROUP_ID:-}" "false" "false"
|
|
790
|
-
print_var "FRESH_DEFAULT_CATEGORY" "${FRESH_DEFAULT_CATEGORY:-}" "false" "false"
|
|
791
|
-
print_var "FRESH_SOURCE_ID" "${FRESH_SOURCE_ID:-}" "false" "false"
|
|
792
|
-
print_var "FRESH_DEFAULT_EMAIL" "${FRESH_DEFAULT_EMAIL:-}" "false" "false"
|
|
793
|
-
echo ""
|
|
794
|
-
|
|
795
|
-
# Gitea vars
|
|
796
|
-
echo -e "${BOLD}Gitea${NC}"
|
|
797
|
-
print_var "GITEA_URL" "${GITEA_URL:-}" "true" "false"
|
|
798
|
-
print_var "GITEA_TOKEN" "${GITEA_TOKEN:-}" "true" "true"
|
|
799
|
-
print_var "GITEA_ORG" "${GITEA_ORG:-}" "false" "false"
|
|
800
|
-
print_var "GITEA_REPO" "${GITEA_REPO:-}" "false" "false"
|
|
801
|
-
}
|
|
802
|
-
|
|
803
|
-
cmd_doctor() {
|
|
804
|
-
local check_apis=false
|
|
805
|
-
[[ "${1:-}" == "--check-apis" ]] && check_apis=true
|
|
806
|
-
|
|
807
|
-
print_banner
|
|
808
|
-
load_env
|
|
809
|
-
|
|
810
|
-
local passed=0
|
|
811
|
-
local failed=0
|
|
812
|
-
|
|
813
|
-
# Helper functions
|
|
814
|
-
check_pass() {
|
|
815
|
-
echo -e " ${GREEN}✓${NC} $1"
|
|
816
|
-
passed=$((passed + 1))
|
|
817
|
-
}
|
|
818
|
-
|
|
819
|
-
check_fail() {
|
|
820
|
-
echo -e " ${RED}✗${NC} $1"
|
|
821
|
-
if [[ -n "${2:-}" ]]; then
|
|
822
|
-
echo -e " ${DIM}→ $2${NC}"
|
|
823
|
-
fi
|
|
824
|
-
failed=$((failed + 1))
|
|
825
|
-
}
|
|
826
|
-
|
|
827
|
-
# Environment checks
|
|
828
|
-
echo -e "${BOLD}Environment${NC}"
|
|
829
|
-
|
|
830
|
-
if [[ -d "$GOLEM_HOME" ]]; then
|
|
831
|
-
check_pass "$GOLEM_HOME directory exists"
|
|
832
|
-
else
|
|
833
|
-
check_fail "$GOLEM_HOME directory missing" "Run: mkdir -p $GOLEM_HOME"
|
|
834
|
-
fi
|
|
835
|
-
|
|
836
|
-
if [[ -f "$GOLEM_HOME/.env" ]]; then
|
|
837
|
-
check_pass "$GOLEM_HOME/.env file exists"
|
|
838
|
-
else
|
|
839
|
-
check_fail "$GOLEM_HOME/.env file missing" "Run: cp $GOLEM_HOME/.env.example $GOLEM_HOME/.env"
|
|
840
|
-
fi
|
|
841
|
-
|
|
842
|
-
local missing_vars=()
|
|
843
|
-
[[ -z "${FRESH_DOMAIN:-}" ]] && missing_vars+=("FRESH_DOMAIN")
|
|
844
|
-
[[ -z "${FRESH_API_KEY:-}" ]] && missing_vars+=("FRESH_API_KEY")
|
|
845
|
-
[[ -z "${GITEA_URL:-}" ]] && missing_vars+=("GITEA_URL")
|
|
846
|
-
[[ -z "${GITEA_TOKEN:-}" ]] && missing_vars+=("GITEA_TOKEN")
|
|
847
|
-
|
|
848
|
-
if [[ ${#missing_vars[@]} -eq 0 ]]; then
|
|
849
|
-
check_pass "Required env vars set"
|
|
850
|
-
else
|
|
851
|
-
check_fail "Missing required env vars: ${missing_vars[*]}" "Edit $GOLEM_HOME/.env"
|
|
852
|
-
fi
|
|
853
|
-
|
|
854
|
-
echo ""
|
|
855
|
-
|
|
856
|
-
# Dependency checks
|
|
857
|
-
echo -e "${BOLD}Dependencies${NC}"
|
|
858
|
-
|
|
859
|
-
if command -v node &>/dev/null; then
|
|
860
|
-
local node_ver=$(node --version 2>/dev/null)
|
|
861
|
-
check_pass "node $node_ver"
|
|
862
|
-
else
|
|
863
|
-
check_fail "node not found" "Install Node.js"
|
|
864
|
-
fi
|
|
865
|
-
|
|
866
|
-
if command -v pnpm &>/dev/null; then
|
|
867
|
-
local pnpm_ver=$(pnpm --version 2>/dev/null)
|
|
868
|
-
check_pass "pnpm $pnpm_ver"
|
|
869
|
-
else
|
|
870
|
-
check_fail "pnpm not found" "Run: npm install -g pnpm"
|
|
871
|
-
fi
|
|
872
|
-
|
|
873
|
-
if command -v git &>/dev/null; then
|
|
874
|
-
local git_ver=$(git --version 2>/dev/null | cut -d' ' -f3)
|
|
875
|
-
check_pass "git $git_ver"
|
|
876
|
-
else
|
|
877
|
-
check_fail "git not found" "Install git"
|
|
878
|
-
fi
|
|
879
|
-
|
|
880
|
-
if command -v golem-api &>/dev/null; then
|
|
881
|
-
check_pass "golem-api accessible"
|
|
882
|
-
else
|
|
883
|
-
check_fail "golem-api not found" "Run: pnpm dlx golem-cc"
|
|
884
|
-
fi
|
|
885
|
-
|
|
886
|
-
echo ""
|
|
887
|
-
|
|
888
|
-
# Installation checks
|
|
889
|
-
echo -e "${BOLD}Installation${NC}"
|
|
890
|
-
|
|
891
|
-
if [[ -d "$GOLEM_HOME/lib" ]]; then
|
|
892
|
-
check_pass "Runtime installed ($GOLEM_HOME/lib)"
|
|
893
|
-
else
|
|
894
|
-
check_fail "Runtime not installed" "Run: pnpm dlx golem-cc"
|
|
895
|
-
fi
|
|
896
|
-
|
|
897
|
-
local prompt_count=$(ls "$GOLEM_HOME/prompts/"*.md 2>/dev/null | wc -l | tr -d ' ')
|
|
898
|
-
if [[ "$prompt_count" -gt 0 ]]; then
|
|
899
|
-
check_pass "Prompts installed ($prompt_count files)"
|
|
900
|
-
else
|
|
901
|
-
check_fail "No prompts installed" "Run: pnpm dlx golem-cc"
|
|
902
|
-
fi
|
|
903
|
-
|
|
904
|
-
local agent_count=$(ls "$GOLEM_HOME/agents/"*.md 2>/dev/null | wc -l | tr -d ' ')
|
|
905
|
-
if [[ "$agent_count" -gt 0 ]]; then
|
|
906
|
-
check_pass "Agents installed ($agent_count files)"
|
|
907
|
-
else
|
|
908
|
-
check_fail "No agents installed" "Run: pnpm dlx golem-cc"
|
|
909
|
-
fi
|
|
910
|
-
|
|
911
|
-
if [[ -d "$GOLEM_HOME/commands/golem" ]]; then
|
|
912
|
-
check_pass "Commands installed"
|
|
913
|
-
else
|
|
914
|
-
check_fail "Commands not installed" "Run: pnpm dlx golem-cc"
|
|
915
|
-
fi
|
|
916
|
-
|
|
917
|
-
if [[ -L "$HOME/.claude/commands/golem" ]] && [[ -d "$HOME/.claude/commands/golem" ]]; then
|
|
918
|
-
check_pass "Claude integration linked"
|
|
919
|
-
else
|
|
920
|
-
check_fail "Claude integration not linked" "Run: ln -sf $GOLEM_HOME/commands/golem ~/.claude/commands/golem"
|
|
921
|
-
fi
|
|
922
|
-
|
|
923
|
-
echo ""
|
|
924
|
-
|
|
925
|
-
# Optional API checks
|
|
926
|
-
if [[ "$check_apis" == "true" ]]; then
|
|
927
|
-
echo -e "${BOLD}API Connectivity${NC}"
|
|
928
|
-
|
|
929
|
-
if golem-api fresh:test &>/dev/null; then
|
|
930
|
-
check_pass "Freshservice API responds"
|
|
931
|
-
else
|
|
932
|
-
check_fail "Freshservice API not responding" "Check FRESH_DOMAIN and FRESH_API_KEY"
|
|
933
|
-
fi
|
|
934
|
-
|
|
935
|
-
if golem-api gitea:test &>/dev/null; then
|
|
936
|
-
check_pass "Gitea API responds"
|
|
937
|
-
else
|
|
938
|
-
check_fail "Gitea API not responding" "Check GITEA_URL and GITEA_TOKEN"
|
|
939
|
-
fi
|
|
940
|
-
|
|
941
|
-
echo ""
|
|
942
|
-
fi
|
|
943
|
-
|
|
944
|
-
# Summary
|
|
945
|
-
local total=$((passed + failed))
|
|
946
|
-
if [[ "$failed" -eq 0 ]]; then
|
|
947
|
-
echo -e "${GREEN}Summary: $passed/$total checks passed${NC}"
|
|
948
|
-
return 0
|
|
949
|
-
else
|
|
950
|
-
echo -e "${RED}Summary: $passed/$total checks passed ($failed failed)${NC}"
|
|
951
|
-
return 1
|
|
952
|
-
fi
|
|
953
|
-
}
|
|
954
|
-
|
|
955
|
-
# ============================================================================
|
|
956
|
-
# Main
|
|
957
|
-
# ============================================================================
|
|
958
|
-
|
|
959
|
-
main() {
|
|
960
|
-
local cmd="${1:-}"
|
|
961
|
-
shift || true
|
|
962
|
-
|
|
963
|
-
# No args: bootstrap if not installed, otherwise show help
|
|
964
|
-
if [[ -z "$cmd" ]]; then
|
|
965
|
-
if [[ -d "$GOLEM_HOME/lib" ]]; then
|
|
966
|
-
cmd_help
|
|
967
|
-
else
|
|
968
|
-
cmd_bootstrap
|
|
969
|
-
fi
|
|
970
|
-
return
|
|
971
|
-
fi
|
|
972
|
-
|
|
973
|
-
case "$cmd" in
|
|
974
|
-
help|--help|-h)
|
|
975
|
-
cmd_help
|
|
976
|
-
;;
|
|
977
|
-
version|--version|-v)
|
|
978
|
-
cmd_version
|
|
979
|
-
;;
|
|
980
|
-
init)
|
|
981
|
-
cmd_init "$@"
|
|
982
|
-
;;
|
|
983
|
-
new)
|
|
984
|
-
cmd_new "$@"
|
|
985
|
-
;;
|
|
986
|
-
import)
|
|
987
|
-
cmd_import "$@"
|
|
988
|
-
;;
|
|
989
|
-
list)
|
|
990
|
-
cmd_list "$@"
|
|
991
|
-
;;
|
|
992
|
-
status)
|
|
993
|
-
cmd_status "$@"
|
|
994
|
-
;;
|
|
995
|
-
worktree)
|
|
996
|
-
cmd_worktree "$@"
|
|
997
|
-
;;
|
|
998
|
-
worktrees)
|
|
999
|
-
cmd_worktrees "$@"
|
|
1000
|
-
;;
|
|
1001
|
-
build)
|
|
1002
|
-
cmd_build "$@"
|
|
1003
|
-
;;
|
|
1004
|
-
plan)
|
|
1005
|
-
cmd_plan "$@"
|
|
1006
|
-
;;
|
|
1007
|
-
simplify)
|
|
1008
|
-
cmd_simplify "$@"
|
|
1009
|
-
;;
|
|
1010
|
-
squash)
|
|
1011
|
-
cmd_squash "$@"
|
|
1012
|
-
;;
|
|
1013
|
-
sync)
|
|
1014
|
-
cmd_sync "$@"
|
|
1015
|
-
;;
|
|
1016
|
-
pr)
|
|
1017
|
-
cmd_pr "$@"
|
|
1018
|
-
;;
|
|
1019
|
-
config)
|
|
1020
|
-
cmd_config "$@"
|
|
1021
|
-
;;
|
|
1022
|
-
doctor)
|
|
1023
|
-
cmd_doctor "$@"
|
|
1024
|
-
;;
|
|
1025
|
-
update)
|
|
1026
|
-
cmd_update "$@"
|
|
1027
|
-
;;
|
|
1028
|
-
install)
|
|
1029
|
-
cmd_install "$@"
|
|
1030
|
-
;;
|
|
1031
|
-
uninstall)
|
|
1032
|
-
cmd_uninstall "$@"
|
|
1033
|
-
;;
|
|
1034
|
-
*)
|
|
1035
|
-
die "Unknown command: $cmd. Run 'golem help' for usage."
|
|
1036
|
-
;;
|
|
1037
|
-
esac
|
|
1038
|
-
}
|
|
1039
|
-
|
|
1040
|
-
main "$@"
|