golem-cc 1.0.2 → 2.1.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/README.md CHANGED
@@ -5,21 +5,33 @@ Personal agentic workflow manager. Integrates Freshservice tickets, Gitea issues
5
5
  ## Installation
6
6
 
7
7
  ```bash
8
- # Install globally via npm
9
- npm install -g golem-cc
10
-
11
- # Or run directly with pnpm
8
+ # Bootstrap (one command)
12
9
  pnpm dlx golem-cc
13
10
  ```
14
11
 
15
- After installing, run the setup:
12
+ This copies everything to `~/.golem/`, links binaries to `~/.local/bin/`, and wires up Claude slash-commands.
13
+
14
+ After installing, restart your shell and configure:
16
15
 
17
16
  ```bash
18
- # Check your installation
17
+ # Verify setup
19
18
  golem doctor
20
19
 
21
- # Configure credentials
20
+ # Edit credentials
22
21
  vim ~/.golem/.env
22
+
23
+ # Initialize a project
24
+ cd your-project && golem init
25
+ ```
26
+
27
+ ### Updating
28
+
29
+ ```bash
30
+ # From a running install
31
+ golem install
32
+
33
+ # Or from a local checkout (dev workflow)
34
+ golem install --from /path/to/golem-cc
23
35
  ```
24
36
 
25
37
  ## Architecture
package/bin/golem CHANGED
@@ -8,7 +8,7 @@
8
8
 
9
9
  set -euo pipefail
10
10
 
11
- VERSION="0.1.0"
11
+ VERSION="2.0.0"
12
12
  GOLEM_HOME="${GOLEM_HOME:-$HOME/.golem}"
13
13
  GOLEM_API="golem-api"
14
14
 
@@ -124,6 +124,7 @@ SYNC COMMANDS:
124
124
 
125
125
  OTHER:
126
126
  install Install/update golem globally
127
+ uninstall Remove golem completely
127
128
  config Show current configuration
128
129
  doctor Diagnose setup issues
129
130
  init Initialize golem in current project
@@ -131,9 +132,11 @@ OTHER:
131
132
  help Show this help
132
133
 
133
134
  CLAUDE COMMANDS (inside Claude Code):
134
- /golem:spec Define specs interactively
135
- /golem:plan Create implementation plan
136
- /golem:build Run build loop (one task at a time)
135
+ /golem:spec Define specs (agent team: UX, Architect, Devil's Advocate)
136
+ /golem:plan Create implementation plan (agent team per layer)
137
+ /golem:build Build lead + builders (observable, interruptible)
138
+ /golem:security Run security scans (gitleaks, semgrep, pnpm audit, trivy)
139
+ /golem:review Security + code review (runs security first, then agent team)
137
140
  /golem:simplify Run code simplifier
138
141
  /golem:status Show current status
139
142
  /golem:help Show help
@@ -148,7 +151,15 @@ cmd_version() {
148
151
 
149
152
  cmd_init() {
150
153
  print_banner
151
- info "Initializing golem..."
154
+
155
+ # Validate global installation
156
+ if [[ ! -d "$GOLEM_HOME/lib" ]]; then
157
+ warn "Golem is not installed globally."
158
+ echo " Run: pnpm dlx golem-cc"
159
+ echo ""
160
+ fi
161
+
162
+ info "Initializing golem in current project..."
152
163
 
153
164
  mkdir -p .golem/{specs,tickets,worktrees}
154
165
 
@@ -184,6 +195,8 @@ EOF
184
195
  if [[ -d "$GOLEM_HOME/commands/golem" ]]; then
185
196
  ln -sf "$GOLEM_HOME/commands/golem" .claude/commands/golem 2>/dev/null || true
186
197
  success "Linked Claude commands"
198
+ else
199
+ warn "Claude commands not found (install golem globally first)"
187
200
  fi
188
201
 
189
202
  # Add .golem to .gitignore
@@ -413,19 +426,30 @@ Files to simplify: $files"
413
426
  }
414
427
 
415
428
  cmd_squash() {
416
- local ticket_id
429
+ local ticket_id message=""
417
430
  ticket_id=$(get_current_ticket)
418
431
  [[ -z "$ticket_id" ]] && die "Not in a ticket worktree"
419
432
 
433
+ # Parse arguments for -m flag
434
+ while [[ $# -gt 0 ]]; do
435
+ case "$1" in
436
+ -m|--message)
437
+ message="$2"
438
+ shift 2
439
+ ;;
440
+ *)
441
+ shift
442
+ ;;
443
+ esac
444
+ done
445
+
420
446
  check_api
421
447
  load_env
422
448
 
423
- # Find current stage commit message from plan
424
449
  if [[ ! -f .golem/IMPLEMENTATION_PLAN.md ]]; then
425
450
  die "No implementation plan found"
426
451
  fi
427
452
 
428
- # Get the commit message for current stage (simplified - just prompt user)
429
453
  echo -e "${BOLD}Squashing commits for $ticket_id${NC}"
430
454
  echo ""
431
455
 
@@ -438,9 +462,12 @@ cmd_squash() {
438
462
  return 0
439
463
  fi
440
464
 
441
- echo ""
442
- read -p "Commit message: " message
443
- [[ -z "$message" ]] && die "Commit message required"
465
+ # If message not provided via flag, prompt interactively
466
+ if [[ -z "$message" ]]; then
467
+ echo ""
468
+ read -p "Commit message: " message
469
+ [[ -z "$message" ]] && die "Commit message required"
470
+ fi
444
471
 
445
472
  info "Squashing..."
446
473
  $GOLEM_API git:squash "$ticket_id" -m "$message"
@@ -507,68 +534,175 @@ Branch: $branch" \
507
534
  success "PR created"
508
535
  }
509
536
 
510
- cmd_install() {
511
- print_banner
512
- info "Installing/updating golem..."
513
-
514
- local src_dir="$GOLEM_HOME/src"
537
+ # Resolve the package root from this script's location.
538
+ # When run via pnpm dlx, $0 lives inside a temp store.
539
+ # When run from ~/.golem/lib, $0 is there.
540
+ _resolve_pkg_root() {
541
+ local script_path
542
+ script_path="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
543
+ # bin/ is one level under package root
544
+ echo "$(cd "$script_path/.." && pwd)"
545
+ }
515
546
 
516
- # Clone or update
517
- if [[ -d "$src_dir/.git" ]]; then
518
- info "Updating existing installation..."
519
- git -C "$src_dir" pull --ff-only || die "Failed to update. Try: rm -rf $src_dir"
520
- else
521
- info "Cloning golem..."
522
- mkdir -p "$GOLEM_HOME"
523
- git clone https://github.com/daresTheDevil/golem.git "$src_dir" || die "Failed to clone"
524
- fi
547
+ # Bootstrap: copy package contents into ~/.golem/lib and wire everything up.
548
+ cmd_bootstrap() {
549
+ local pkg_root
550
+ pkg_root="$(_resolve_pkg_root)"
525
551
 
526
- # Build
527
- info "Building..."
528
- cd "$src_dir"
529
- pnpm install --silent || die "pnpm install failed"
530
- pnpm build || die "Build failed"
552
+ print_banner
553
+ info "Installing golem to $GOLEM_HOME..."
554
+
555
+ # ---- runtime ----
556
+ mkdir -p "$GOLEM_HOME/lib"
557
+ # Copy the package runtime (bin, dist, node_modules, package.json)
558
+ for item in bin dist node_modules package.json; do
559
+ if [[ -e "$pkg_root/$item" ]]; then
560
+ rm -rf "$GOLEM_HOME/lib/$item"
561
+ cp -R "$pkg_root/$item" "$GOLEM_HOME/lib/$item"
562
+ fi
563
+ done
564
+ success "Installed runtime to $GOLEM_HOME/lib"
531
565
 
532
- # Copy assets
533
- info "Installing assets..."
566
+ # ---- assets ----
534
567
  mkdir -p "$GOLEM_HOME"/{commands,agents,prompts}
535
- cp -r "$src_dir/commands/golem" "$GOLEM_HOME/commands/"
536
- cp "$src_dir/golem/agents/"*.md "$GOLEM_HOME/agents/"
537
- cp "$src_dir/golem/prompts/"*.md "$GOLEM_HOME/prompts/"
568
+ if [[ -d "$pkg_root/commands/golem" ]]; then
569
+ rm -rf "$GOLEM_HOME/commands/golem"
570
+ cp -R "$pkg_root/commands/golem" "$GOLEM_HOME/commands/golem"
571
+ fi
572
+ if compgen -G "$pkg_root/golem/agents/"*.md &>/dev/null; then
573
+ cp "$pkg_root/golem/agents/"*.md "$GOLEM_HOME/agents/"
574
+ fi
575
+ if compgen -G "$pkg_root/golem/prompts/"*.md &>/dev/null; then
576
+ cp "$pkg_root/golem/prompts/"*.md "$GOLEM_HOME/prompts/"
577
+ fi
578
+ success "Installed assets (commands, agents, prompts)"
538
579
 
539
- # Link binaries
580
+ # ---- symlinks in ~/.local/bin ----
540
581
  mkdir -p "$HOME/.local/bin"
541
- ln -sf "$src_dir/bin/golem" "$HOME/.local/bin/golem"
542
- ln -sf "$src_dir/dist/cli/index.js" "$HOME/.local/bin/golem-api"
543
- chmod +x "$src_dir/dist/cli/index.js"
582
+ ln -sf "$GOLEM_HOME/lib/bin/golem" "$HOME/.local/bin/golem"
583
+ ln -sf "$GOLEM_HOME/lib/dist/cli/index.js" "$HOME/.local/bin/golem-api"
584
+ chmod +x "$GOLEM_HOME/lib/bin/golem"
585
+ chmod +x "$GOLEM_HOME/lib/dist/cli/index.js" 2>/dev/null || true
586
+ success "Linked binaries to ~/.local/bin"
544
587
 
545
- # Link Claude commands
588
+ # ---- Claude slash-commands ----
546
589
  mkdir -p "$HOME/.claude/commands"
547
590
  ln -sf "$GOLEM_HOME/commands/golem" "$HOME/.claude/commands/golem" 2>/dev/null || true
591
+ success "Linked Claude commands"
548
592
 
549
- # Create env template if needed
593
+ # ---- .env template ----
594
+ if [[ -f "$pkg_root/.env.example" ]]; then
595
+ cp "$pkg_root/.env.example" "$GOLEM_HOME/.env.example"
596
+ fi
550
597
  if [[ ! -f "$GOLEM_HOME/.env" ]]; then
551
- cat > "$GOLEM_HOME/.env" << 'ENVEOF'
552
- # Freshservice
598
+ if [[ -f "$GOLEM_HOME/.env.example" ]]; then
599
+ cp "$GOLEM_HOME/.env.example" "$GOLEM_HOME/.env"
600
+ else
601
+ cat > "$GOLEM_HOME/.env" << 'ENVEOF'
602
+ # Freshworks/Freshservice
553
603
  FRESH_DOMAIN=yourcompany.freshservice.com
554
- FRESH_API_KEY=your_api_key
604
+ FRESH_API_KEY=your_api_key_here
605
+
606
+ # Gitea (on-prem)
607
+ GITEA_URL=https://dev.pearlriverresort.com
608
+ GITEA_TOKEN=your_token_here
609
+ GITEA_ORG=CRDE
555
610
 
556
- # Gitea
557
- GITEA_URL=https://gitea.example.com
558
- GITEA_TOKEN=your_token
559
- GITEA_ORG=your-org
560
- GITEA_REPO=default-repo
611
+ # Default repo for issues (can be overridden per-project)
612
+ GITEA_REPO=
561
613
  ENVEOF
562
- warn "Created $GOLEM_HOME/.env - edit with your credentials"
614
+ fi
615
+ warn "Created $GOLEM_HOME/.env — edit with your credentials"
616
+ fi
617
+
618
+ # ---- PATH setup (idempotent) ----
619
+ local shell_rc="$HOME/.zshrc"
620
+ [[ -f "$HOME/.bashrc" && ! -f "$HOME/.zshrc" ]] && shell_rc="$HOME/.bashrc"
621
+
622
+ if [[ -f "$shell_rc" ]]; then
623
+ if ! grep -q '$HOME/.local/bin' "$shell_rc" 2>/dev/null; then
624
+ echo '' >> "$shell_rc"
625
+ echo '# golem: add ~/.local/bin to PATH' >> "$shell_rc"
626
+ echo 'export PATH="$HOME/.local/bin:$PATH"' >> "$shell_rc"
627
+ success "Added ~/.local/bin to PATH in $(basename "$shell_rc")"
628
+ fi
563
629
  fi
564
630
 
565
631
  echo ""
566
632
  success "Installation complete!"
567
633
  echo ""
568
- echo "Make sure ~/.local/bin is in your PATH:"
569
- echo ' export PATH="$HOME/.local/bin:$PATH"'
634
+ echo "Restart your shell (or run: source $shell_rc), then:"
635
+ echo " golem doctor # verify setup"
636
+ echo " golem config # show configuration"
637
+ echo " cd <project> && golem init # set up a project"
638
+ }
639
+
640
+ cmd_uninstall() {
641
+ print_banner
642
+ echo -e "${BOLD}This will remove:${NC}"
643
+ echo " $GOLEM_HOME (runtime, assets, config)"
644
+ echo " ~/.local/bin/golem (symlink)"
645
+ echo " ~/.local/bin/golem-api (symlink)"
646
+ echo " ~/.claude/commands/golem (symlink)"
570
647
  echo ""
571
- echo "Then run: golem doctor"
648
+
649
+ # Check for .env with real credentials and warn
650
+ if [[ -f "$GOLEM_HOME/.env" ]]; then
651
+ warn "Your credentials in $GOLEM_HOME/.env will be deleted."
652
+ echo " Back up now if needed: cp $GOLEM_HOME/.env ~/golem-env-backup"
653
+ echo ""
654
+ fi
655
+
656
+ read -p "Are you sure? [y/N] " confirm
657
+ [[ "$confirm" != "y" && "$confirm" != "Y" ]] && { echo "Aborted."; exit 0; }
658
+
659
+ # Remove symlinks in ~/.local/bin
660
+ for bin in golem golem-api; do
661
+ local target="$HOME/.local/bin/$bin"
662
+ if [[ -L "$target" || -f "$target" ]]; then
663
+ rm -f "$target"
664
+ success "Removed $target"
665
+ fi
666
+ done
667
+
668
+ # Remove Claude commands symlink
669
+ if [[ -L "$HOME/.claude/commands/golem" || -d "$HOME/.claude/commands/golem" ]]; then
670
+ rm -rf "$HOME/.claude/commands/golem"
671
+ success "Removed ~/.claude/commands/golem"
672
+ fi
673
+
674
+ # Remove ~/.golem entirely
675
+ if [[ -d "$GOLEM_HOME" ]]; then
676
+ rm -rf "$GOLEM_HOME"
677
+ success "Removed $GOLEM_HOME"
678
+ fi
679
+
680
+ echo ""
681
+ success "Golem uninstalled."
682
+ echo ""
683
+ dim "The PATH entry in your shell rc was left in place (it's harmless)."
684
+ dim "To reinstall later: pnpm dlx golem-cc"
685
+ }
686
+
687
+ cmd_install() {
688
+ # If --from <path> given, bootstrap from a local checkout (dev workflow)
689
+ if [[ "${1:-}" == "--from" ]]; then
690
+ local local_path="${2:-}"
691
+ [[ -z "$local_path" ]] && die "Usage: golem install --from <path>"
692
+ [[ ! -d "$local_path/bin" ]] && die "Not a golem package directory: $local_path"
693
+
694
+ # Temporarily override _resolve_pkg_root
695
+ _resolve_pkg_root() { echo "$local_path"; }
696
+ cmd_bootstrap
697
+ return
698
+ fi
699
+
700
+ print_banner
701
+ info "Updating golem via pnpm dlx..."
702
+ echo ""
703
+
704
+ # Re-run pnpm dlx golem-cc which will hit the bootstrap path
705
+ pnpm dlx golem-cc || die "Update failed"
572
706
  }
573
707
 
574
708
  cmd_config() {
@@ -715,7 +849,7 @@ cmd_doctor() {
715
849
  if command -v golem-api &>/dev/null; then
716
850
  check_pass "golem-api accessible"
717
851
  else
718
- check_fail "golem-api not found" "Run: ./bin/install.sh in golem directory"
852
+ check_fail "golem-api not found" "Run: pnpm dlx golem-cc"
719
853
  fi
720
854
 
721
855
  echo ""
@@ -723,24 +857,30 @@ cmd_doctor() {
723
857
  # Installation checks
724
858
  echo -e "${BOLD}Installation${NC}"
725
859
 
860
+ if [[ -d "$GOLEM_HOME/lib" ]]; then
861
+ check_pass "Runtime installed ($GOLEM_HOME/lib)"
862
+ else
863
+ check_fail "Runtime not installed" "Run: pnpm dlx golem-cc"
864
+ fi
865
+
726
866
  local prompt_count=$(ls "$GOLEM_HOME/prompts/"*.md 2>/dev/null | wc -l | tr -d ' ')
727
867
  if [[ "$prompt_count" -gt 0 ]]; then
728
868
  check_pass "Prompts installed ($prompt_count files)"
729
869
  else
730
- check_fail "No prompts installed" "Run: ./bin/install.sh"
870
+ check_fail "No prompts installed" "Run: pnpm dlx golem-cc"
731
871
  fi
732
872
 
733
873
  local agent_count=$(ls "$GOLEM_HOME/agents/"*.md 2>/dev/null | wc -l | tr -d ' ')
734
874
  if [[ "$agent_count" -gt 0 ]]; then
735
875
  check_pass "Agents installed ($agent_count files)"
736
876
  else
737
- check_fail "No agents installed" "Run: ./bin/install.sh"
877
+ check_fail "No agents installed" "Run: pnpm dlx golem-cc"
738
878
  fi
739
879
 
740
880
  if [[ -d "$GOLEM_HOME/commands/golem" ]]; then
741
881
  check_pass "Commands installed"
742
882
  else
743
- check_fail "Commands not installed" "Run: ./bin/install.sh"
883
+ check_fail "Commands not installed" "Run: pnpm dlx golem-cc"
744
884
  fi
745
885
 
746
886
  if [[ -L "$HOME/.claude/commands/golem" ]] && [[ -d "$HOME/.claude/commands/golem" ]]; then
@@ -786,9 +926,19 @@ cmd_doctor() {
786
926
  # ============================================================================
787
927
 
788
928
  main() {
789
- local cmd="${1:-help}"
929
+ local cmd="${1:-}"
790
930
  shift || true
791
931
 
932
+ # No args: bootstrap if not installed, otherwise show help
933
+ if [[ -z "$cmd" ]]; then
934
+ if [[ -d "$GOLEM_HOME/lib" ]]; then
935
+ cmd_help
936
+ else
937
+ cmd_bootstrap
938
+ fi
939
+ return
940
+ fi
941
+
792
942
  case "$cmd" in
793
943
  help|--help|-h)
794
944
  cmd_help
@@ -844,6 +994,9 @@ main() {
844
994
  install)
845
995
  cmd_install "$@"
846
996
  ;;
997
+ uninstall)
998
+ cmd_uninstall "$@"
999
+ ;;
847
1000
  *)
848
1001
  die "Unknown command: $cmd. Run 'golem help' for usage."
849
1002
  ;;