create-hq 5.1.0 → 5.2.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/dist/deps.d.ts +2 -2
- package/dist/deps.d.ts.map +1 -1
- package/dist/deps.js +138 -29
- package/dist/deps.js.map +1 -1
- package/dist/index.js +1 -1
- package/dist/scaffold.d.ts.map +1 -1
- package/dist/scaffold.js +16 -26
- package/dist/scaffold.js.map +1 -1
- package/dist/ui.js +1 -1
- package/package.json +3 -6
- package/template/.claude/CLAUDE.md +0 -202
- package/template/.claude/commands/checkpoint.md +0 -127
- package/template/.claude/commands/cleanup.md +0 -307
- package/template/.claude/commands/execute-task.md +0 -440
- package/template/.claude/commands/exit-plan.md +0 -41
- package/template/.claude/commands/handoff.md +0 -97
- package/template/.claude/commands/learn.md +0 -218
- package/template/.claude/commands/metrics.md +0 -118
- package/template/.claude/commands/newworker.md +0 -162
- package/template/.claude/commands/nexttask.md +0 -67
- package/template/.claude/commands/prd.md +0 -238
- package/template/.claude/commands/reanchor.md +0 -51
- package/template/.claude/commands/remember.md +0 -126
- package/template/.claude/commands/run-project.md +0 -348
- package/template/.claude/commands/run.md +0 -110
- package/template/.claude/commands/search-reindex.md +0 -62
- package/template/.claude/commands/search.md +0 -100
- package/template/.claude/commands/setup.md +0 -381
- package/template/.claude/scripts/pure-ralph-loop.ps1 +0 -312
- package/template/.claude/scripts/pure-ralph-loop.sh +0 -859
- package/template/CHANGELOG.md +0 -220
- package/template/LICENSE +0 -21
- package/template/MIGRATION.md +0 -259
- package/template/README.md +0 -368
- package/template/data/journal/.gitkeep +0 -0
- package/template/docs/images/ascii-banner-options.md +0 -122
- package/template/docs/images/hq-banner.svg +0 -105
- package/template/knowledge/Ralph/01-overview.md +0 -71
- package/template/knowledge/Ralph/02-core-concepts.md +0 -114
- package/template/knowledge/Ralph/03-how-ralph-works.md +0 -184
- package/template/knowledge/Ralph/04-back-pressure.md +0 -222
- package/template/knowledge/Ralph/05-specifications.md +0 -210
- package/template/knowledge/Ralph/06-agents-md.md +0 -222
- package/template/knowledge/Ralph/07-implementation.md +0 -316
- package/template/knowledge/Ralph/08-economics.md +0 -182
- package/template/knowledge/Ralph/09-resources.md +0 -145
- package/template/knowledge/Ralph/10-claude-code-workflow.md +0 -212
- package/template/knowledge/Ralph/11-team-training-guide.md +0 -383
- package/template/knowledge/Ralph/README.md +0 -40
- package/template/knowledge/ai-security-framework/CONTRIBUTING.md +0 -139
- package/template/knowledge/ai-security-framework/GLOSSARY.md +0 -176
- package/template/knowledge/ai-security-framework/LICENSE +0 -21
- package/template/knowledge/ai-security-framework/QUICK-START.md +0 -172
- package/template/knowledge/ai-security-framework/README.md +0 -232
- package/template/knowledge/ai-security-framework/checklists/browser-security.md +0 -301
- package/template/knowledge/ai-security-framework/checklists/credential-isolation.md +0 -322
- package/template/knowledge/ai-security-framework/checklists/incident-response.md +0 -288
- package/template/knowledge/ai-security-framework/checklists/pre-flight.md +0 -249
- package/template/knowledge/ai-security-framework/checklists/weekly-audit.md +0 -159
- package/template/knowledge/ai-security-framework/configs/audit-logging.md +0 -372
- package/template/knowledge/ai-security-framework/configs/kill-switches.md +0 -354
- package/template/knowledge/ai-security-framework/docs/01-core-principles.md +0 -256
- package/template/knowledge/ai-security-framework/docs/02-threat-landscape.md +0 -326
- package/template/knowledge/ai-security-framework/docs/03-security-posture.md +0 -250
- package/template/knowledge/ai-security-framework/templates/agents-security.md +0 -233
- package/template/knowledge/design-styles/README.md +0 -42
- package/template/knowledge/design-styles/american-industrial.md +0 -136
- package/template/knowledge/design-styles/ethereal-abstract.md +0 -133
- package/template/knowledge/design-styles/liminal-portal.md +0 -111
- package/template/knowledge/design-styles/swipes/american-industrial/G-3m4YPW0AADdu2.jpeg +0 -0
- package/template/knowledge/design-styles/swipes/american-industrial/G-JJlt5WwAABK3K.png +0 -0
- package/template/knowledge/design-styles/swipes/american-industrial/G-JJmj5W0AEbJ-7.png +0 -0
- package/template/knowledge/design-styles/swipes/american-industrial/G59fgNuXkAAKLJQ (1).jpeg +0 -0
- package/template/knowledge/design-styles/swipes/american-industrial/G59fgNuXkAAKLJQ.jpeg +0 -0
- package/template/knowledge/design-styles/swipes/american-industrial/G7fVkn3WEAAM-ST.jpeg +0 -0
- package/template/knowledge/design-styles/swipes/american-industrial/G8ECO5JWEAIksyn.png +0 -0
- package/template/knowledge/design-styles/swipes/american-industrial/G9-3GQSWoAA8eqZ.png +0 -0
- package/template/knowledge/design-styles/swipes/american-industrial/G9xEOqrXkAEZRcs.png +0 -0
- package/template/knowledge/design-styles/swipes/american-industrial/G_MVeJrXQAA8sx4.jpeg +0 -0
- package/template/knowledge/design-styles/swipes/american-industrial/G_RSkmGXkAAgAVZ.png +0 -0
- package/template/knowledge/design-styles/swipes/american-industrial/README.md +0 -31
- package/template/knowledge/design-styles/swipes/american-industrial/qyqtg7Dq.png +0 -0
- package/template/knowledge/dev-team/README.md +0 -35
- package/template/knowledge/dev-team/patterns/README.md +0 -34
- package/template/knowledge/dev-team/patterns/frontend/react-best-practices.md +0 -178
- package/template/knowledge/dev-team/troubleshooting/README.md +0 -31
- package/template/knowledge/dev-team/workflows/README.md +0 -49
- package/template/knowledge/hq/checkpoint-schema.json +0 -51
- package/template/knowledge/hq/index-md-spec.md +0 -74
- package/template/knowledge/hq/thread-schema.md +0 -153
- package/template/knowledge/hq-core/checkpoint-schema.json +0 -51
- package/template/knowledge/hq-core/index-md-spec.md +0 -74
- package/template/knowledge/hq-core/thread-schema.md +0 -153
- package/template/knowledge/loom/README.md +0 -51
- package/template/knowledge/loom/architecture.md +0 -125
- package/template/knowledge/loom/code-style.md +0 -169
- package/template/knowledge/loom/llm-proxy.md +0 -132
- package/template/knowledge/loom/state-machine.md +0 -131
- package/template/knowledge/loom/thread-system.md +0 -117
- package/template/knowledge/loom/tools.md +0 -94
- package/template/knowledge/loom/weaver.md +0 -96
- package/template/knowledge/loom/web-frontend.md +0 -131
- package/template/knowledge/projects/README.md +0 -72
- package/template/knowledge/projects/templates/README.template.md +0 -28
- package/template/knowledge/workers/README.md +0 -195
- package/template/knowledge/workers/ralph-loop-pattern.md +0 -157
- package/template/knowledge/workers/skill-schema.md +0 -182
- package/template/knowledge/workers/state-machine.md +0 -102
- package/template/knowledge/workers/templates/base-worker.yaml +0 -73
- package/template/knowledge/workers/templates/code-worker.yaml +0 -85
- package/template/knowledge/workers/templates/skill.yaml +0 -49
- package/template/knowledge/workers/templates/social-worker.yaml +0 -70
- package/template/modules/examples/full-manifest.yaml +0 -92
- package/template/modules/examples/minimal.yaml +0 -14
- package/template/modules/modules.yaml +0 -59
- package/template/projects/.gitkeep +0 -0
- package/template/projects/incorporate-workers-into-pure-ralph/prd.json +0 -88
- package/template/projects/pure-ralph-branch-isolation/README.md +0 -114
- package/template/projects/pure-ralph-branch-isolation/prd.json +0 -123
- package/template/projects/purist-ralph-loop/README.md +0 -148
- package/template/projects/purist-ralph-loop/prd.json +0 -135
- package/template/projects/ralph-test/prd.json +0 -50
- package/template/prompts/pure-ralph-base.md +0 -551
- package/template/settings/.gitkeep +0 -0
- package/template/settings/pure-ralph.json +0 -42
- package/template/social-content/drafts/INDEX.md +0 -21
- package/template/social-content/drafts/linkedin/.gitkeep +0 -1
- package/template/social-content/drafts/x/.gitkeep +0 -1
- package/template/social-content/images/.gitkeep +0 -1
- package/template/starter-projects/code-worker/README.md +0 -97
- package/template/starter-projects/code-worker/prd.json +0 -45
- package/template/starter-projects/personal-assistant/README.md +0 -42
- package/template/starter-projects/personal-assistant/prd.json +0 -43
- package/template/starter-projects/social-media/README.md +0 -60
- package/template/starter-projects/social-media/prd.json +0 -43
- package/template/workers/content-brand/README.md +0 -59
- package/template/workers/content-brand/skills/messaging-alignment.md +0 -91
- package/template/workers/content-brand/skills/tone-check.md +0 -76
- package/template/workers/content-brand/skills/voice-analysis.md +0 -68
- package/template/workers/content-brand/worker.yaml +0 -81
- package/template/workers/content-legal/README.md +0 -80
- package/template/workers/content-legal/skills/claim-substantiation.md +0 -150
- package/template/workers/content-legal/skills/compliance-scan.md +0 -123
- package/template/workers/content-legal/skills/disclaimer-check.md +0 -146
- package/template/workers/content-legal/worker.yaml +0 -118
- package/template/workers/content-product/README.md +0 -77
- package/template/workers/content-product/skills/claim-verification.md +0 -96
- package/template/workers/content-product/skills/feature-accuracy.md +0 -117
- package/template/workers/content-product/skills/stats-check.md +0 -128
- package/template/workers/content-product/worker.yaml +0 -97
- package/template/workers/content-sales/README.md +0 -70
- package/template/workers/content-sales/skills/conversion-analysis.md +0 -96
- package/template/workers/content-sales/skills/cta-audit.md +0 -107
- package/template/workers/content-sales/skills/value-prop-check.md +0 -114
- package/template/workers/content-sales/worker.yaml +0 -93
- package/template/workers/content-shared/cli.ts +0 -242
- package/template/workers/content-shared/index.ts +0 -234
- package/template/workers/content-shared/lib/accuracy-analyzer.ts +0 -661
- package/template/workers/content-shared/lib/analyze.ts +0 -370
- package/template/workers/content-shared/lib/brand-analyzer.ts +0 -526
- package/template/workers/content-shared/lib/cms-integration.ts +0 -446
- package/template/workers/content-shared/lib/compliance-analyzer.ts +0 -655
- package/template/workers/content-shared/lib/conversion-analyzer.ts +0 -555
- package/template/workers/content-shared/lib/github-integration.ts +0 -582
- package/template/workers/content-shared/lib/output.ts +0 -373
- package/template/workers/content-shared/lib/parser.ts +0 -771
- package/template/workers/content-shared/lib/priority.ts +0 -439
- package/template/workers/content-shared/lib/recommendations.ts +0 -512
- package/template/workers/content-shared/lib/reporter.ts +0 -749
- package/template/workers/content-shared/lib/restructure.ts +0 -664
- package/template/workers/content-shared/lib/scorer.ts +0 -140
- package/template/workers/content-shared/lib/types.ts +0 -227
- package/template/workers/content-shared/lib/variants.ts +0 -595
- package/template/workers/content-shared/package.json +0 -51
- package/template/workers/content-shared/pnpm-lock.yaml +0 -39
- package/template/workers/content-shared/test/sample-page.json +0 -115
- package/template/workers/content-shared/tsconfig.json +0 -20
- package/template/workers/dev-team/README.md +0 -166
- package/template/workers/dev-team/_template.yaml +0 -70
- package/template/workers/dev-team/architect/package.json +0 -27
- package/template/workers/dev-team/architect/skills/api-design.md +0 -89
- package/template/workers/dev-team/architect/skills/refactor-plan.md +0 -96
- package/template/workers/dev-team/architect/skills/system-design.md +0 -100
- package/template/workers/dev-team/architect/src/index.ts +0 -49
- package/template/workers/dev-team/architect/src/mcp-server.ts +0 -122
- package/template/workers/dev-team/architect/src/skills/api-design.ts +0 -316
- package/template/workers/dev-team/architect/src/skills/refactor-plan.ts +0 -264
- package/template/workers/dev-team/architect/src/skills/system-design.ts +0 -212
- package/template/workers/dev-team/architect/tsconfig.json +0 -19
- package/template/workers/dev-team/architect/worker.yaml +0 -128
- package/template/workers/dev-team/backend-dev/package-lock.json +0 -1252
- package/template/workers/dev-team/backend-dev/package.json +0 -27
- package/template/workers/dev-team/backend-dev/skills/implement-endpoint.md +0 -70
- package/template/workers/dev-team/backend-dev/skills/implement-service.md +0 -62
- package/template/workers/dev-team/backend-dev/src/index.ts +0 -51
- package/template/workers/dev-team/backend-dev/src/mcp-server.ts +0 -109
- package/template/workers/dev-team/backend-dev/src/skills/implement-endpoint.ts +0 -122
- package/template/workers/dev-team/backend-dev/src/skills/implement-service.ts +0 -126
- package/template/workers/dev-team/backend-dev/tsconfig.json +0 -19
- package/template/workers/dev-team/backend-dev/worker.yaml +0 -128
- package/template/workers/dev-team/code-reviewer/package-lock.json +0 -1080
- package/template/workers/dev-team/code-reviewer/package.json +0 -24
- package/template/workers/dev-team/code-reviewer/skills/merge-to-production.md +0 -61
- package/template/workers/dev-team/code-reviewer/skills/merge-to-staging.md +0 -54
- package/template/workers/dev-team/code-reviewer/skills/request-changes.md +0 -63
- package/template/workers/dev-team/code-reviewer/skills/review-pr.md +0 -77
- package/template/workers/dev-team/code-reviewer/src/index.ts +0 -56
- package/template/workers/dev-team/code-reviewer/src/mcp-server.ts +0 -101
- package/template/workers/dev-team/code-reviewer/tsconfig.json +0 -19
- package/template/workers/dev-team/code-reviewer/worker.yaml +0 -90
- package/template/workers/dev-team/database-dev/package.json +0 -22
- package/template/workers/dev-team/database-dev/skills/create-schema.md +0 -48
- package/template/workers/dev-team/database-dev/src/index.ts +0 -50
- package/template/workers/dev-team/database-dev/src/mcp-server.ts +0 -76
- package/template/workers/dev-team/database-dev/tsconfig.json +0 -18
- package/template/workers/dev-team/database-dev/worker.yaml +0 -90
- package/template/workers/dev-team/frontend-dev/package.json +0 -22
- package/template/workers/dev-team/frontend-dev/skills/create-component.md +0 -26
- package/template/workers/dev-team/frontend-dev/src/index.ts +0 -50
- package/template/workers/dev-team/frontend-dev/src/mcp-server.ts +0 -77
- package/template/workers/dev-team/frontend-dev/tsconfig.json +0 -18
- package/template/workers/dev-team/frontend-dev/worker.yaml +0 -132
- package/template/workers/dev-team/infra-dev/package.json +0 -24
- package/template/workers/dev-team/infra-dev/skills/add-monitoring.md +0 -73
- package/template/workers/dev-team/infra-dev/skills/configure-deployment.md +0 -80
- package/template/workers/dev-team/infra-dev/skills/create-dockerfile.md +0 -62
- package/template/workers/dev-team/infra-dev/skills/setup-cicd.md +0 -63
- package/template/workers/dev-team/infra-dev/src/index.ts +0 -55
- package/template/workers/dev-team/infra-dev/src/mcp-server.ts +0 -82
- package/template/workers/dev-team/infra-dev/tsconfig.json +0 -19
- package/template/workers/dev-team/infra-dev/worker.yaml +0 -92
- package/template/workers/dev-team/knowledge-curator/package.json +0 -24
- package/template/workers/dev-team/knowledge-curator/skills/curate-troubleshooting.md +0 -63
- package/template/workers/dev-team/knowledge-curator/skills/process-learnings.md +0 -61
- package/template/workers/dev-team/knowledge-curator/skills/sync-documentation.md +0 -76
- package/template/workers/dev-team/knowledge-curator/skills/update-patterns.md +0 -63
- package/template/workers/dev-team/knowledge-curator/src/index.ts +0 -53
- package/template/workers/dev-team/knowledge-curator/src/mcp-server.ts +0 -92
- package/template/workers/dev-team/knowledge-curator/tsconfig.json +0 -19
- package/template/workers/dev-team/knowledge-curator/worker.yaml +0 -80
- package/template/workers/dev-team/motion-designer/package.json +0 -22
- package/template/workers/dev-team/motion-designer/skills/add-animation.md +0 -25
- package/template/workers/dev-team/motion-designer/skills/generate-image.md +0 -36
- package/template/workers/dev-team/motion-designer/src/index.ts +0 -63
- package/template/workers/dev-team/motion-designer/src/mcp-server.ts +0 -79
- package/template/workers/dev-team/motion-designer/tsconfig.json +0 -18
- package/template/workers/dev-team/motion-designer/worker.yaml +0 -84
- package/template/workers/dev-team/product-planner/queue.json +0 -4
- package/template/workers/dev-team/product-planner/worker.yaml +0 -220
- package/template/workers/dev-team/project-manager/package-lock.json +0 -1252
- package/template/workers/dev-team/project-manager/package.json +0 -27
- package/template/workers/dev-team/project-manager/skills/create-prd.md +0 -66
- package/template/workers/dev-team/project-manager/skills/next-issue.md +0 -51
- package/template/workers/dev-team/project-manager/skills/project-status.md +0 -59
- package/template/workers/dev-team/project-manager/skills/update-learnings.md +0 -65
- package/template/workers/dev-team/project-manager/src/index.ts +0 -54
- package/template/workers/dev-team/project-manager/src/mcp-server.ts +0 -207
- package/template/workers/dev-team/project-manager/src/skills/create-prd.ts +0 -86
- package/template/workers/dev-team/project-manager/src/skills/next-issue.ts +0 -137
- package/template/workers/dev-team/project-manager/src/skills/project-status.ts +0 -131
- package/template/workers/dev-team/project-manager/src/skills/update-learnings.ts +0 -94
- package/template/workers/dev-team/project-manager/tsconfig.json +0 -19
- package/template/workers/dev-team/project-manager/worker.yaml +0 -96
- package/template/workers/dev-team/qa-tester/package.json +0 -24
- package/template/workers/dev-team/qa-tester/skills/create-demo-account.md +0 -36
- package/template/workers/dev-team/qa-tester/skills/run-tests.md +0 -36
- package/template/workers/dev-team/qa-tester/skills/write-test.md +0 -27
- package/template/workers/dev-team/qa-tester/src/index.ts +0 -61
- package/template/workers/dev-team/qa-tester/src/mcp-server.ts +0 -88
- package/template/workers/dev-team/qa-tester/tsconfig.json +0 -18
- package/template/workers/dev-team/qa-tester/worker.yaml +0 -116
- package/template/workers/dev-team/task-executor/package-lock.json +0 -1252
- package/template/workers/dev-team/task-executor/package.json +0 -27
- package/template/workers/dev-team/task-executor/skills/analyze-issue.md +0 -101
- package/template/workers/dev-team/task-executor/skills/execute.md +0 -133
- package/template/workers/dev-team/task-executor/skills/report-learnings.md +0 -106
- package/template/workers/dev-team/task-executor/skills/validate-completion.md +0 -121
- package/template/workers/dev-team/task-executor/src/index.ts +0 -54
- package/template/workers/dev-team/task-executor/src/mcp-server.ts +0 -139
- package/template/workers/dev-team/task-executor/src/skills/analyze-issue.ts +0 -219
- package/template/workers/dev-team/task-executor/src/skills/execute.ts +0 -132
- package/template/workers/dev-team/task-executor/src/skills/report-learnings.ts +0 -119
- package/template/workers/dev-team/task-executor/src/skills/validate-completion.ts +0 -142
- package/template/workers/dev-team/task-executor/tsconfig.json +0 -19
- package/template/workers/dev-team/task-executor/worker.yaml +0 -110
- package/template/workers/registry.yaml +0 -171
- package/template/workers/security-scanner/README.md +0 -73
- package/template/workers/security-scanner/skills/pre-deploy-check.md +0 -205
- package/template/workers/security-scanner/worker.yaml +0 -26
- package/template/workspace/checkpoints/.gitkeep +0 -0
- package/template/workspace/content-ideas/inbox.jsonl +0 -0
- package/template/workspace/drafts/.gitkeep +0 -0
- package/template/workspace/learnings/.gitkeep +0 -3
- package/template/workspace/orchestrator/.gitkeep +0 -0
- package/template/workspace/ralph-test/COMPLETE.md +0 -18
- package/template/workspace/ralph-test/hello.txt +0 -2
- package/template/workspace/reports/.gitkeep +0 -0
- package/template/workspace/scratch/.gitkeep +0 -0
- package/template/workspace/threads/.gitkeep +0 -3
|
@@ -1,859 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env bash
|
|
2
|
-
#
|
|
3
|
-
# Pure Ralph Loop - External terminal orchestrator for autonomous PRD execution
|
|
4
|
-
#
|
|
5
|
-
# SYNOPSIS
|
|
6
|
-
# ./pure-ralph-loop.sh --prd-path <path> --target-repo <path> [--hq-path <path>] [--manual]
|
|
7
|
-
#
|
|
8
|
-
# DESCRIPTION
|
|
9
|
-
# Runs the canonical Ralph loop: one task per fresh Claude session,
|
|
10
|
-
# updates PRD on completion, commits each task atomically.
|
|
11
|
-
#
|
|
12
|
-
# ARGUMENTS
|
|
13
|
-
# --prd-path Full path to the PRD JSON file (required)
|
|
14
|
-
# --target-repo Full path to the target repository (required)
|
|
15
|
-
# --hq-path Path to HQ directory (defaults to ~/my-hq or C:/my-hq)
|
|
16
|
-
# --manual, -m Run in manual mode (interactive TUI, close windows manually)
|
|
17
|
-
# Default is auto mode (uses -p flag, auto-exits)
|
|
18
|
-
#
|
|
19
|
-
# EXAMPLE
|
|
20
|
-
# # Auto mode (default) - fully autonomous
|
|
21
|
-
# ./pure-ralph-loop.sh --prd-path ~/my-hq/projects/my-project/prd.json --target-repo ~/my-project
|
|
22
|
-
#
|
|
23
|
-
# # Manual mode - see chain of thought, close windows manually
|
|
24
|
-
# ./pure-ralph-loop.sh --prd-path ~/my-hq/projects/my-project/prd.json --target-repo ~/my-project --manual
|
|
25
|
-
#
|
|
26
|
-
|
|
27
|
-
set -euo pipefail
|
|
28
|
-
|
|
29
|
-
# ============================================================================
|
|
30
|
-
# Argument Parsing
|
|
31
|
-
# ============================================================================
|
|
32
|
-
|
|
33
|
-
PRD_PATH=""
|
|
34
|
-
TARGET_REPO=""
|
|
35
|
-
HQ_PATH=""
|
|
36
|
-
MANUAL_MODE=false
|
|
37
|
-
|
|
38
|
-
# Detect default HQ path based on OS
|
|
39
|
-
if [[ -d "$HOME/my-hq" ]]; then
|
|
40
|
-
HQ_PATH="$HOME/my-hq"
|
|
41
|
-
elif [[ -d "/c/my-hq" ]]; then
|
|
42
|
-
HQ_PATH="/c/my-hq"
|
|
43
|
-
elif [[ -d "C:/my-hq" ]]; then
|
|
44
|
-
HQ_PATH="C:/my-hq"
|
|
45
|
-
else
|
|
46
|
-
HQ_PATH="$HOME/my-hq"
|
|
47
|
-
fi
|
|
48
|
-
|
|
49
|
-
while [[ $# -gt 0 ]]; do
|
|
50
|
-
case $1 in
|
|
51
|
-
--prd-path)
|
|
52
|
-
PRD_PATH="$2"
|
|
53
|
-
shift 2
|
|
54
|
-
;;
|
|
55
|
-
--target-repo)
|
|
56
|
-
TARGET_REPO="$2"
|
|
57
|
-
shift 2
|
|
58
|
-
;;
|
|
59
|
-
--hq-path)
|
|
60
|
-
HQ_PATH="$2"
|
|
61
|
-
shift 2
|
|
62
|
-
;;
|
|
63
|
-
--manual|-m)
|
|
64
|
-
MANUAL_MODE=true
|
|
65
|
-
shift
|
|
66
|
-
;;
|
|
67
|
-
-h|--help)
|
|
68
|
-
echo "Usage: $0 --prd-path <path> --target-repo <path> [--hq-path <path>] [--manual]"
|
|
69
|
-
echo ""
|
|
70
|
-
echo "Arguments:"
|
|
71
|
-
echo " --prd-path Full path to the PRD JSON file (required)"
|
|
72
|
-
echo " --target-repo Full path to the target repository (required)"
|
|
73
|
-
echo " --hq-path Path to HQ directory (default: ~/my-hq)"
|
|
74
|
-
echo " --manual, -m Interactive mode (see chain of thought, close windows manually)"
|
|
75
|
-
echo ""
|
|
76
|
-
echo "Modes:"
|
|
77
|
-
echo " Auto (default) - Uses -p flag, auto-exits, fully autonomous"
|
|
78
|
-
echo " Manual (-m) - Interactive TUI, close windows manually"
|
|
79
|
-
exit 0
|
|
80
|
-
;;
|
|
81
|
-
*)
|
|
82
|
-
echo "Unknown option: $1"
|
|
83
|
-
exit 1
|
|
84
|
-
;;
|
|
85
|
-
esac
|
|
86
|
-
done
|
|
87
|
-
|
|
88
|
-
# Validate required arguments
|
|
89
|
-
if [[ -z "$PRD_PATH" ]]; then
|
|
90
|
-
echo "Error: --prd-path is required"
|
|
91
|
-
exit 1
|
|
92
|
-
fi
|
|
93
|
-
|
|
94
|
-
if [[ -z "$TARGET_REPO" ]]; then
|
|
95
|
-
echo "Error: --target-repo is required"
|
|
96
|
-
exit 1
|
|
97
|
-
fi
|
|
98
|
-
|
|
99
|
-
# Set Claude flags based on mode
|
|
100
|
-
if [[ "$MANUAL_MODE" == "true" ]]; then
|
|
101
|
-
CLAUDE_FLAGS="--permission-mode bypassPermissions"
|
|
102
|
-
MODE_LABEL="MANUAL (interactive)"
|
|
103
|
-
else
|
|
104
|
-
CLAUDE_FLAGS="-p --permission-mode bypassPermissions"
|
|
105
|
-
MODE_LABEL="AUTO (autonomous)"
|
|
106
|
-
fi
|
|
107
|
-
|
|
108
|
-
# ============================================================================
|
|
109
|
-
# Configuration
|
|
110
|
-
# ============================================================================
|
|
111
|
-
|
|
112
|
-
BASE_PROMPT_PATH="$HQ_PATH/prompts/pure-ralph-base.md"
|
|
113
|
-
PROJECT_NAME=$(basename "$(dirname "$PRD_PATH")")
|
|
114
|
-
LOG_DIR="$HQ_PATH/workspace/orchestrator/$PROJECT_NAME"
|
|
115
|
-
LOG_FILE="$LOG_DIR/pure-ralph.log"
|
|
116
|
-
LOCK_FILE="$TARGET_REPO/.pure-ralph.lock"
|
|
117
|
-
|
|
118
|
-
# ============================================================================
|
|
119
|
-
# Color Output
|
|
120
|
-
# ============================================================================
|
|
121
|
-
|
|
122
|
-
RED='\033[0;31m'
|
|
123
|
-
YELLOW='\033[0;33m'
|
|
124
|
-
GREEN='\033[0;32m'
|
|
125
|
-
CYAN='\033[0;36m'
|
|
126
|
-
GRAY='\033[0;90m'
|
|
127
|
-
NC='\033[0m' # No Color
|
|
128
|
-
|
|
129
|
-
# ============================================================================
|
|
130
|
-
# Logging Functions
|
|
131
|
-
# ============================================================================
|
|
132
|
-
|
|
133
|
-
initialize_logging() {
|
|
134
|
-
mkdir -p "$LOG_DIR"
|
|
135
|
-
|
|
136
|
-
local timestamp
|
|
137
|
-
timestamp=$(date '+%Y-%m-%d %H:%M:%S')
|
|
138
|
-
|
|
139
|
-
{
|
|
140
|
-
echo ""
|
|
141
|
-
echo "=========================================="
|
|
142
|
-
echo "Pure Ralph Loop Started: $timestamp"
|
|
143
|
-
echo "PRD: $PRD_PATH"
|
|
144
|
-
echo "Target: $TARGET_REPO"
|
|
145
|
-
echo "=========================================="
|
|
146
|
-
echo ""
|
|
147
|
-
} >> "$LOG_FILE"
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
# ============================================================================
|
|
151
|
-
# Lock File Functions
|
|
152
|
-
# ============================================================================
|
|
153
|
-
|
|
154
|
-
create_lock_file() {
|
|
155
|
-
local timestamp
|
|
156
|
-
timestamp=$(date -Iseconds)
|
|
157
|
-
cat > "$LOCK_FILE" <<EOF
|
|
158
|
-
{
|
|
159
|
-
"project": "$PROJECT_NAME",
|
|
160
|
-
"pid": $$,
|
|
161
|
-
"started_at": "$timestamp"
|
|
162
|
-
}
|
|
163
|
-
EOF
|
|
164
|
-
write_log "Lock file created: $LOCK_FILE"
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
remove_lock_file() {
|
|
168
|
-
if [[ -f "$LOCK_FILE" ]]; then
|
|
169
|
-
rm -f "$LOCK_FILE"
|
|
170
|
-
write_log "Lock file removed: $LOCK_FILE"
|
|
171
|
-
fi
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
check_existing_lock() {
|
|
175
|
-
if [[ -f "$LOCK_FILE" ]]; then
|
|
176
|
-
# Read lock file contents
|
|
177
|
-
local lock_project
|
|
178
|
-
local lock_pid
|
|
179
|
-
local lock_started
|
|
180
|
-
lock_project=$(jq -r '.project' "$LOCK_FILE" 2>/dev/null || echo "unknown")
|
|
181
|
-
lock_pid=$(jq -r '.pid' "$LOCK_FILE" 2>/dev/null || echo "unknown")
|
|
182
|
-
lock_started=$(jq -r '.started_at' "$LOCK_FILE" 2>/dev/null || echo "unknown")
|
|
183
|
-
|
|
184
|
-
# Calculate duration if we can parse the timestamp
|
|
185
|
-
local duration_str="unknown"
|
|
186
|
-
if [[ "$lock_started" != "unknown" ]]; then
|
|
187
|
-
local start_epoch
|
|
188
|
-
local now_epoch
|
|
189
|
-
local diff_seconds
|
|
190
|
-
# Try to parse ISO timestamp
|
|
191
|
-
if command -v gdate &> /dev/null; then
|
|
192
|
-
start_epoch=$(gdate -d "$lock_started" +%s 2>/dev/null || echo "0")
|
|
193
|
-
else
|
|
194
|
-
start_epoch=$(date -d "$lock_started" +%s 2>/dev/null || echo "0")
|
|
195
|
-
fi
|
|
196
|
-
now_epoch=$(date +%s)
|
|
197
|
-
if [[ "$start_epoch" != "0" ]]; then
|
|
198
|
-
diff_seconds=$((now_epoch - start_epoch))
|
|
199
|
-
local hours=$((diff_seconds / 3600))
|
|
200
|
-
local minutes=$(((diff_seconds % 3600) / 60))
|
|
201
|
-
local seconds=$((diff_seconds % 60))
|
|
202
|
-
duration_str=$(printf "%02d:%02d:%02d" $hours $minutes $seconds)
|
|
203
|
-
fi
|
|
204
|
-
fi
|
|
205
|
-
|
|
206
|
-
echo ""
|
|
207
|
-
echo -e "${YELLOW}=== WARNING: Lock File Detected ===${NC}"
|
|
208
|
-
echo -e "${YELLOW}Another pure-ralph loop may be running on this repo.${NC}"
|
|
209
|
-
echo ""
|
|
210
|
-
echo -e "${GRAY} Project: $lock_project${NC}"
|
|
211
|
-
echo -e "${GRAY} PID: $lock_pid${NC}"
|
|
212
|
-
echo -e "${GRAY} Started: $lock_started${NC}"
|
|
213
|
-
echo -e "${GRAY} Duration: $duration_str${NC}"
|
|
214
|
-
echo ""
|
|
215
|
-
|
|
216
|
-
# Check if process is still running
|
|
217
|
-
local process_running=false
|
|
218
|
-
if [[ "$lock_pid" != "unknown" ]] && kill -0 "$lock_pid" 2>/dev/null; then
|
|
219
|
-
process_running=true
|
|
220
|
-
echo -e " Process Status: ${RED}RUNNING${NC}"
|
|
221
|
-
else
|
|
222
|
-
echo -e " Process Status: ${YELLOW}NOT RUNNING (stale lock)${NC}"
|
|
223
|
-
fi
|
|
224
|
-
echo ""
|
|
225
|
-
|
|
226
|
-
write_log "Existing lock file found for project '$lock_project' (PID: $lock_pid, Duration: $duration_str)" "WARN"
|
|
227
|
-
|
|
228
|
-
# Prompt user
|
|
229
|
-
read -r -p "Another pure-ralph is running. Continue anyway? (y/N) " response
|
|
230
|
-
case "$response" in
|
|
231
|
-
[Yy])
|
|
232
|
-
write_log "User chose to continue despite existing lock" "WARN"
|
|
233
|
-
echo -e "${YELLOW}Continuing... (existing lock will be overwritten)${NC}"
|
|
234
|
-
return 0
|
|
235
|
-
;;
|
|
236
|
-
*)
|
|
237
|
-
write_log "User chose to abort due to existing lock" "INFO"
|
|
238
|
-
echo -e "${RED}Aborting.${NC}"
|
|
239
|
-
return 1
|
|
240
|
-
;;
|
|
241
|
-
esac
|
|
242
|
-
fi
|
|
243
|
-
return 0
|
|
244
|
-
}
|
|
245
|
-
|
|
246
|
-
# Trap to ensure lock file is removed on exit (success or failure)
|
|
247
|
-
cleanup_on_exit() {
|
|
248
|
-
remove_lock_file
|
|
249
|
-
}
|
|
250
|
-
trap cleanup_on_exit EXIT
|
|
251
|
-
|
|
252
|
-
write_log() {
|
|
253
|
-
local message="$1"
|
|
254
|
-
local level="${2:-INFO}"
|
|
255
|
-
local timestamp
|
|
256
|
-
timestamp=$(date '+%Y-%m-%d %H:%M:%S')
|
|
257
|
-
local log_entry="[$timestamp] [$level] $message"
|
|
258
|
-
|
|
259
|
-
echo "$log_entry" >> "$LOG_FILE"
|
|
260
|
-
|
|
261
|
-
# Also output to console with color
|
|
262
|
-
case $level in
|
|
263
|
-
ERROR)
|
|
264
|
-
echo -e "${RED}${log_entry}${NC}"
|
|
265
|
-
;;
|
|
266
|
-
WARN)
|
|
267
|
-
echo -e "${YELLOW}${log_entry}${NC}"
|
|
268
|
-
;;
|
|
269
|
-
SUCCESS)
|
|
270
|
-
echo -e "${GREEN}${log_entry}${NC}"
|
|
271
|
-
;;
|
|
272
|
-
*)
|
|
273
|
-
echo "$log_entry"
|
|
274
|
-
;;
|
|
275
|
-
esac
|
|
276
|
-
}
|
|
277
|
-
|
|
278
|
-
# ============================================================================
|
|
279
|
-
# PRD Functions (using jq for JSON parsing)
|
|
280
|
-
# ============================================================================
|
|
281
|
-
|
|
282
|
-
check_jq() {
|
|
283
|
-
if ! command -v jq &> /dev/null; then
|
|
284
|
-
echo -e "${RED}Error: jq is required but not installed.${NC}"
|
|
285
|
-
echo "Install with:"
|
|
286
|
-
echo " macOS: brew install jq"
|
|
287
|
-
echo " Ubuntu: sudo apt-get install jq"
|
|
288
|
-
echo " MSYS2: pacman -S jq"
|
|
289
|
-
exit 1
|
|
290
|
-
fi
|
|
291
|
-
}
|
|
292
|
-
|
|
293
|
-
get_prd() {
|
|
294
|
-
if [[ ! -f "$PRD_PATH" ]]; then
|
|
295
|
-
write_log "PRD not found: $PRD_PATH" "ERROR"
|
|
296
|
-
exit 1
|
|
297
|
-
fi
|
|
298
|
-
cat "$PRD_PATH"
|
|
299
|
-
}
|
|
300
|
-
|
|
301
|
-
get_task_count() {
|
|
302
|
-
local prd="$1"
|
|
303
|
-
echo "$prd" | jq '.features | length'
|
|
304
|
-
}
|
|
305
|
-
|
|
306
|
-
get_completed_count() {
|
|
307
|
-
local prd="$1"
|
|
308
|
-
echo "$prd" | jq '[.features[] | select(.passes == true)] | length'
|
|
309
|
-
}
|
|
310
|
-
|
|
311
|
-
get_next_task() {
|
|
312
|
-
local prd="$1"
|
|
313
|
-
|
|
314
|
-
# Find first task where:
|
|
315
|
-
# 1. passes != true
|
|
316
|
-
# 2. all dependencies (if any) have passes == true
|
|
317
|
-
echo "$prd" | jq -c '
|
|
318
|
-
.features as $all |
|
|
319
|
-
[.features[] | select(.passes != true)] |
|
|
320
|
-
map(select(
|
|
321
|
-
if .dependsOn then
|
|
322
|
-
[.dependsOn[] as $dep | $all[] | select(.id == $dep) | .passes == true] | all
|
|
323
|
-
else
|
|
324
|
-
true
|
|
325
|
-
end
|
|
326
|
-
)) |
|
|
327
|
-
first // empty
|
|
328
|
-
'
|
|
329
|
-
}
|
|
330
|
-
|
|
331
|
-
get_prior_context() {
|
|
332
|
-
local prd="$1"
|
|
333
|
-
echo "$prd" | jq -r '
|
|
334
|
-
[.features[] | select(.passes == true and .notes != null and .notes != "") | "- \(.id): \(.notes)"] | join("\n")
|
|
335
|
-
'
|
|
336
|
-
}
|
|
337
|
-
|
|
338
|
-
# ============================================================================
|
|
339
|
-
# Prompt Building
|
|
340
|
-
# ============================================================================
|
|
341
|
-
|
|
342
|
-
build_task_prompt() {
|
|
343
|
-
local task="$1"
|
|
344
|
-
local prd="$2"
|
|
345
|
-
|
|
346
|
-
# Read base prompt
|
|
347
|
-
if [[ ! -f "$BASE_PROMPT_PATH" ]]; then
|
|
348
|
-
write_log "Base prompt not found: $BASE_PROMPT_PATH" "ERROR"
|
|
349
|
-
exit 1
|
|
350
|
-
fi
|
|
351
|
-
|
|
352
|
-
local base_prompt
|
|
353
|
-
base_prompt=$(cat "$BASE_PROMPT_PATH")
|
|
354
|
-
|
|
355
|
-
# Extract task details
|
|
356
|
-
local task_id
|
|
357
|
-
local task_title
|
|
358
|
-
task_id=$(echo "$task" | jq -r '.id')
|
|
359
|
-
task_title=$(echo "$task" | jq -r '.title')
|
|
360
|
-
|
|
361
|
-
# Replace placeholders
|
|
362
|
-
local prompt="$base_prompt"
|
|
363
|
-
prompt="${prompt//\{\{TARGET_REPO\}\}/$TARGET_REPO}"
|
|
364
|
-
prompt="${prompt//\{\{PRD_PATH\}\}/$PRD_PATH}"
|
|
365
|
-
prompt="${prompt//\{\{TASK_ID\}\}/$task_id}"
|
|
366
|
-
prompt="${prompt//\{\{TASK_TITLE\}\}/$task_title}"
|
|
367
|
-
|
|
368
|
-
# Get context from prior completed tasks
|
|
369
|
-
local prior_context
|
|
370
|
-
prior_context=$(get_prior_context "$prd")
|
|
371
|
-
|
|
372
|
-
# Build full prompt with task details
|
|
373
|
-
cat <<EOF
|
|
374
|
-
$prompt
|
|
375
|
-
|
|
376
|
-
Execute task $task_id from $PRD_PATH.
|
|
377
|
-
|
|
378
|
-
Context from prior tasks:
|
|
379
|
-
$prior_context
|
|
380
|
-
|
|
381
|
-
Read the PRD, implement $task_id ($task_title), then update the PRD.
|
|
382
|
-
|
|
383
|
-
Return JSON: {success: boolean, summary: string, files_modified: array, notes: string}
|
|
384
|
-
EOF
|
|
385
|
-
}
|
|
386
|
-
|
|
387
|
-
# ============================================================================
|
|
388
|
-
# Task Execution
|
|
389
|
-
# ============================================================================
|
|
390
|
-
|
|
391
|
-
detect_os() {
|
|
392
|
-
case "$(uname -s)" in
|
|
393
|
-
Darwin*) echo "macos" ;;
|
|
394
|
-
Linux*) echo "linux" ;;
|
|
395
|
-
MINGW*|MSYS*|CYGWIN*) echo "windows" ;;
|
|
396
|
-
*) echo "unknown" ;;
|
|
397
|
-
esac
|
|
398
|
-
}
|
|
399
|
-
|
|
400
|
-
detect_terminal_app() {
|
|
401
|
-
local os="$1"
|
|
402
|
-
|
|
403
|
-
if [[ "$os" == "macos" ]]; then
|
|
404
|
-
# Check if iTerm is installed
|
|
405
|
-
if [[ -d "/Applications/iTerm.app" ]]; then
|
|
406
|
-
echo "iterm"
|
|
407
|
-
else
|
|
408
|
-
echo "terminal"
|
|
409
|
-
fi
|
|
410
|
-
elif [[ "$os" == "linux" ]]; then
|
|
411
|
-
# Check for common terminal emulators
|
|
412
|
-
if command -v gnome-terminal &> /dev/null; then
|
|
413
|
-
echo "gnome-terminal"
|
|
414
|
-
elif command -v xterm &> /dev/null; then
|
|
415
|
-
echo "xterm"
|
|
416
|
-
elif command -v konsole &> /dev/null; then
|
|
417
|
-
echo "konsole"
|
|
418
|
-
else
|
|
419
|
-
echo "xterm" # fallback
|
|
420
|
-
fi
|
|
421
|
-
else
|
|
422
|
-
echo "unknown"
|
|
423
|
-
fi
|
|
424
|
-
}
|
|
425
|
-
|
|
426
|
-
invoke_task() {
|
|
427
|
-
local task="$1"
|
|
428
|
-
local prd="$2"
|
|
429
|
-
|
|
430
|
-
local task_id
|
|
431
|
-
local task_title
|
|
432
|
-
task_id=$(echo "$task" | jq -r '.id')
|
|
433
|
-
task_title=$(echo "$task" | jq -r '.title')
|
|
434
|
-
|
|
435
|
-
write_log "Starting task: $task_id - $task_title"
|
|
436
|
-
write_log "Acceptance criteria:"
|
|
437
|
-
|
|
438
|
-
# Log each acceptance criterion
|
|
439
|
-
echo "$task" | jq -r '.acceptance_criteria[]' | while read -r ac; do
|
|
440
|
-
write_log " - $ac"
|
|
441
|
-
done
|
|
442
|
-
|
|
443
|
-
# Build the prompt
|
|
444
|
-
local prompt
|
|
445
|
-
prompt=$(build_task_prompt "$task" "$prd")
|
|
446
|
-
|
|
447
|
-
# Save prompt to persistent file so new terminal can read it
|
|
448
|
-
local prompt_file="$LOG_DIR/task-${task_id}-prompt.md"
|
|
449
|
-
echo "$prompt" > "$prompt_file"
|
|
450
|
-
|
|
451
|
-
write_log "Spawning fresh Claude session (interactive mode)..."
|
|
452
|
-
|
|
453
|
-
echo ""
|
|
454
|
-
echo -e "${CYAN}========================================"
|
|
455
|
-
echo -e " LAUNCHING CLAUDE FOR: $task_id"
|
|
456
|
-
echo -e " A new terminal window will open - watch Claude work there!"
|
|
457
|
-
echo -e "========================================${NC}"
|
|
458
|
-
echo ""
|
|
459
|
-
|
|
460
|
-
local os
|
|
461
|
-
local terminal_app
|
|
462
|
-
os=$(detect_os)
|
|
463
|
-
terminal_app=$(detect_terminal_app "$os")
|
|
464
|
-
|
|
465
|
-
write_log "Detected OS: $os, Terminal: $terminal_app"
|
|
466
|
-
|
|
467
|
-
# Build the command to run in the new terminal
|
|
468
|
-
local claude_cmd="cd '$TARGET_REPO' && claude $CLAUDE_FLAGS \"\$(cat '$prompt_file')\""
|
|
469
|
-
|
|
470
|
-
case "$os" in
|
|
471
|
-
macos)
|
|
472
|
-
if [[ "$terminal_app" == "iterm" ]]; then
|
|
473
|
-
# iTerm2
|
|
474
|
-
osascript <<EOF
|
|
475
|
-
tell application "iTerm"
|
|
476
|
-
create window with default profile
|
|
477
|
-
tell current session of current window
|
|
478
|
-
write text "cd '$TARGET_REPO' && claude $CLAUDE_FLAGS \"\$(cat '$prompt_file')\""
|
|
479
|
-
end tell
|
|
480
|
-
end tell
|
|
481
|
-
EOF
|
|
482
|
-
# Wait for iTerm window to close (poll for process)
|
|
483
|
-
write_log "Waiting for Claude session to complete in iTerm..."
|
|
484
|
-
echo -e "${YELLOW}>>> SWITCH TO THE iTerm WINDOW TO WATCH CLAUDE WORK <<<${NC}"
|
|
485
|
-
# Poll until the prompt file is removed or PRD is updated
|
|
486
|
-
while [[ -f "$prompt_file" ]]; do
|
|
487
|
-
sleep 5
|
|
488
|
-
# Check if PRD was updated for this task
|
|
489
|
-
local task_passes
|
|
490
|
-
task_passes=$(cat "$PRD_PATH" | jq -r ".features[] | select(.id == \"$task_id\") | .passes")
|
|
491
|
-
if [[ "$task_passes" == "true" ]]; then
|
|
492
|
-
break
|
|
493
|
-
fi
|
|
494
|
-
done
|
|
495
|
-
else
|
|
496
|
-
# Terminal.app
|
|
497
|
-
osascript <<EOF
|
|
498
|
-
tell application "Terminal"
|
|
499
|
-
do script "cd '$TARGET_REPO' && claude $CLAUDE_FLAGS \"\$(cat '$prompt_file')\""
|
|
500
|
-
activate
|
|
501
|
-
end tell
|
|
502
|
-
EOF
|
|
503
|
-
write_log "Waiting for Claude session to complete in Terminal..."
|
|
504
|
-
echo -e "${YELLOW}>>> SWITCH TO THE Terminal WINDOW TO WATCH CLAUDE WORK <<<${NC}"
|
|
505
|
-
# Poll until PRD is updated
|
|
506
|
-
while true; do
|
|
507
|
-
sleep 5
|
|
508
|
-
local task_passes
|
|
509
|
-
task_passes=$(cat "$PRD_PATH" | jq -r ".features[] | select(.id == \"$task_id\") | .passes")
|
|
510
|
-
if [[ "$task_passes" == "true" ]]; then
|
|
511
|
-
break
|
|
512
|
-
fi
|
|
513
|
-
done
|
|
514
|
-
fi
|
|
515
|
-
;;
|
|
516
|
-
linux)
|
|
517
|
-
case "$terminal_app" in
|
|
518
|
-
gnome-terminal)
|
|
519
|
-
gnome-terminal -- bash -c "$claude_cmd; exec bash" &
|
|
520
|
-
local term_pid=$!
|
|
521
|
-
;;
|
|
522
|
-
konsole)
|
|
523
|
-
konsole -e bash -c "$claude_cmd; exec bash" &
|
|
524
|
-
local term_pid=$!
|
|
525
|
-
;;
|
|
526
|
-
*)
|
|
527
|
-
xterm -e bash -c "$claude_cmd; exec bash" &
|
|
528
|
-
local term_pid=$!
|
|
529
|
-
;;
|
|
530
|
-
esac
|
|
531
|
-
write_log "Waiting for Claude session to complete (Terminal PID: $term_pid)..."
|
|
532
|
-
echo -e "${YELLOW}>>> SWITCH TO THE NEW TERMINAL WINDOW TO WATCH CLAUDE WORK <<<${NC}"
|
|
533
|
-
wait $term_pid 2>/dev/null || true
|
|
534
|
-
;;
|
|
535
|
-
*)
|
|
536
|
-
# Fallback - run inline (not ideal but works)
|
|
537
|
-
write_log "Unknown OS - running inline"
|
|
538
|
-
cd "$TARGET_REPO"
|
|
539
|
-
claude $CLAUDE_FLAGS "$(cat "$prompt_file")"
|
|
540
|
-
cd -
|
|
541
|
-
;;
|
|
542
|
-
esac
|
|
543
|
-
|
|
544
|
-
echo ""
|
|
545
|
-
echo -e "${CYAN}========================================"
|
|
546
|
-
echo -e " CLAUDE SESSION END: $task_id"
|
|
547
|
-
echo -e "========================================${NC}"
|
|
548
|
-
echo ""
|
|
549
|
-
|
|
550
|
-
# Log completion
|
|
551
|
-
write_log "Claude session completed"
|
|
552
|
-
|
|
553
|
-
# Clean up prompt file
|
|
554
|
-
rm -f "$prompt_file"
|
|
555
|
-
|
|
556
|
-
echo "SUCCESS"
|
|
557
|
-
}
|
|
558
|
-
|
|
559
|
-
# ============================================================================
|
|
560
|
-
# Beads Integration
|
|
561
|
-
# ============================================================================
|
|
562
|
-
|
|
563
|
-
BEADS_AVAILABLE=false
|
|
564
|
-
|
|
565
|
-
check_beads_cli() {
|
|
566
|
-
# Check if beads CLI (bd) is available
|
|
567
|
-
if command -v bd &> /dev/null; then
|
|
568
|
-
BEADS_AVAILABLE=true
|
|
569
|
-
return 0
|
|
570
|
-
else
|
|
571
|
-
BEADS_AVAILABLE=false
|
|
572
|
-
return 1
|
|
573
|
-
fi
|
|
574
|
-
}
|
|
575
|
-
|
|
576
|
-
initialize_beads() {
|
|
577
|
-
local prd="$1"
|
|
578
|
-
|
|
579
|
-
if [[ "$BEADS_AVAILABLE" != "true" ]]; then
|
|
580
|
-
return
|
|
581
|
-
fi
|
|
582
|
-
|
|
583
|
-
write_log "Syncing PRD tasks to beads..."
|
|
584
|
-
|
|
585
|
-
# Iterate through all tasks and sync to beads
|
|
586
|
-
local task_count
|
|
587
|
-
task_count=$(echo "$prd" | jq '.features | length')
|
|
588
|
-
|
|
589
|
-
for ((i=0; i<task_count; i++)); do
|
|
590
|
-
local task
|
|
591
|
-
task=$(echo "$prd" | jq -c ".features[$i]")
|
|
592
|
-
|
|
593
|
-
local task_id
|
|
594
|
-
local task_title
|
|
595
|
-
local passes
|
|
596
|
-
task_id=$(echo "$task" | jq -r '.id')
|
|
597
|
-
task_title=$(echo "$task" | jq -r '.title')
|
|
598
|
-
passes=$(echo "$task" | jq -r '.passes')
|
|
599
|
-
|
|
600
|
-
local bead_id="${PROJECT_NAME}-${task_id}"
|
|
601
|
-
local status
|
|
602
|
-
if [[ "$passes" == "true" ]]; then
|
|
603
|
-
status="done"
|
|
604
|
-
else
|
|
605
|
-
status="todo"
|
|
606
|
-
fi
|
|
607
|
-
|
|
608
|
-
# Create or update bead for this task
|
|
609
|
-
if bd add --id "$bead_id" --title "$task_id: $task_title" --status "$status" 2>/dev/null; then
|
|
610
|
-
write_log " Synced bead: $bead_id ($status)"
|
|
611
|
-
else
|
|
612
|
-
write_log " Failed to sync bead: $bead_id" "WARN"
|
|
613
|
-
fi
|
|
614
|
-
done
|
|
615
|
-
|
|
616
|
-
write_log "Beads sync complete" "SUCCESS"
|
|
617
|
-
}
|
|
618
|
-
|
|
619
|
-
update_bead_status() {
|
|
620
|
-
local task_id="$1"
|
|
621
|
-
local status="$2" # "in-progress", "done", "blocked"
|
|
622
|
-
|
|
623
|
-
if [[ "$BEADS_AVAILABLE" != "true" ]]; then
|
|
624
|
-
return
|
|
625
|
-
fi
|
|
626
|
-
|
|
627
|
-
local bead_id="${PROJECT_NAME}-${task_id}"
|
|
628
|
-
|
|
629
|
-
if bd update "$bead_id" --status "$status" 2>/dev/null; then
|
|
630
|
-
write_log "Updated bead $bead_id to $status"
|
|
631
|
-
else
|
|
632
|
-
write_log "Failed to update bead: $bead_id" "WARN"
|
|
633
|
-
fi
|
|
634
|
-
}
|
|
635
|
-
|
|
636
|
-
# ============================================================================
|
|
637
|
-
# Learnings Aggregation
|
|
638
|
-
# ============================================================================
|
|
639
|
-
|
|
640
|
-
LEARNINGS_PATH="$HQ_PATH/knowledge/pure-ralph/learnings.md"
|
|
641
|
-
|
|
642
|
-
aggregate_learnings() {
|
|
643
|
-
local prd="$1"
|
|
644
|
-
|
|
645
|
-
write_log "Aggregating learnings from completed project..."
|
|
646
|
-
|
|
647
|
-
# Count learnings by category based on keywords in notes
|
|
648
|
-
local workflow_count=0
|
|
649
|
-
local technical_count=0
|
|
650
|
-
local gotchas_count=0
|
|
651
|
-
|
|
652
|
-
# Extract notes and categorize
|
|
653
|
-
local notes
|
|
654
|
-
notes=$(echo "$prd" | jq -r '.features[] | select(.passes == true and .notes != null and .notes != "") | .notes')
|
|
655
|
-
|
|
656
|
-
while IFS= read -r note; do
|
|
657
|
-
[[ -z "$note" ]] && continue
|
|
658
|
-
|
|
659
|
-
# Check for workflow patterns
|
|
660
|
-
if echo "$note" | grep -qiE "workflow|process|method|approach|pattern"; then
|
|
661
|
-
((workflow_count++))
|
|
662
|
-
fi
|
|
663
|
-
|
|
664
|
-
# Check for technical patterns
|
|
665
|
-
if echo "$note" | grep -qiE "implement|code|script|function|api|json|file"; then
|
|
666
|
-
((technical_count++))
|
|
667
|
-
fi
|
|
668
|
-
|
|
669
|
-
# Check for gotchas
|
|
670
|
-
if echo "$note" | grep -qiE "error|issue|gotcha|pitfall|careful|avoid|warning"; then
|
|
671
|
-
((gotchas_count++))
|
|
672
|
-
fi
|
|
673
|
-
done <<< "$notes"
|
|
674
|
-
|
|
675
|
-
local total_learnings=$((workflow_count + technical_count + gotchas_count))
|
|
676
|
-
|
|
677
|
-
# Update learnings file if it exists
|
|
678
|
-
if [[ -f "$LEARNINGS_PATH" ]]; then
|
|
679
|
-
local date
|
|
680
|
-
date=$(date '+%Y-%m-%d')
|
|
681
|
-
local task_count
|
|
682
|
-
task_count=$(echo "$prd" | jq '.features | length')
|
|
683
|
-
|
|
684
|
-
# Append to aggregation log table
|
|
685
|
-
local log_entry="| $date | $PROJECT_NAME | $task_count | $total_learnings patterns extracted |"
|
|
686
|
-
|
|
687
|
-
# Check if file has the marker and append
|
|
688
|
-
if grep -q "<!-- Automatically updated when projects complete -->" "$LEARNINGS_PATH"; then
|
|
689
|
-
# Append after the last table row
|
|
690
|
-
# Find the table and add new row
|
|
691
|
-
sed -i "/^| [0-9]\{4\}-[0-9]\{2\}-[0-9]\{2\} |/a\\
|
|
692
|
-
$log_entry" "$LEARNINGS_PATH" 2>/dev/null || \
|
|
693
|
-
# If sed fails (macOS), use different approach
|
|
694
|
-
echo "$log_entry" >> "$LEARNINGS_PATH"
|
|
695
|
-
fi
|
|
696
|
-
|
|
697
|
-
write_log "Updated learnings aggregation log" "SUCCESS"
|
|
698
|
-
else
|
|
699
|
-
write_log "Learnings file not found at $LEARNINGS_PATH - skipping aggregation" "WARN"
|
|
700
|
-
fi
|
|
701
|
-
|
|
702
|
-
# Log summary
|
|
703
|
-
write_log "Learnings extracted - Workflow: $workflow_count, Technical: $technical_count, Gotchas: $gotchas_count"
|
|
704
|
-
}
|
|
705
|
-
|
|
706
|
-
# ============================================================================
|
|
707
|
-
# Main Loop
|
|
708
|
-
# ============================================================================
|
|
709
|
-
|
|
710
|
-
start_ralph_loop() {
|
|
711
|
-
initialize_logging
|
|
712
|
-
|
|
713
|
-
# Check for existing lock file (conflict detection)
|
|
714
|
-
if ! check_existing_lock; then
|
|
715
|
-
exit 1
|
|
716
|
-
fi
|
|
717
|
-
|
|
718
|
-
# Create lock file to prevent concurrent execution
|
|
719
|
-
create_lock_file
|
|
720
|
-
|
|
721
|
-
echo ""
|
|
722
|
-
echo -e "${CYAN}=== Pure Ralph Loop ===${NC}"
|
|
723
|
-
echo -e "${GRAY}PRD: $PRD_PATH${NC}"
|
|
724
|
-
echo -e "${GRAY}Target: $TARGET_REPO${NC}"
|
|
725
|
-
echo -e "${GRAY}Log: $LOG_FILE${NC}"
|
|
726
|
-
|
|
727
|
-
# Check for beads CLI availability
|
|
728
|
-
if check_beads_cli; then
|
|
729
|
-
echo -e "${GRAY}Beads CLI: ${GREEN}available${NC}"
|
|
730
|
-
write_log "Beads CLI (bd) detected - task tracking enabled"
|
|
731
|
-
|
|
732
|
-
# Initial sync of PRD tasks to beads
|
|
733
|
-
local prd
|
|
734
|
-
prd=$(get_prd)
|
|
735
|
-
initialize_beads "$prd"
|
|
736
|
-
else
|
|
737
|
-
echo -e "${GRAY}Beads CLI: ${YELLOW}not installed (optional)${NC}"
|
|
738
|
-
write_log "Beads CLI (bd) not found - continuing without task tracking"
|
|
739
|
-
fi
|
|
740
|
-
|
|
741
|
-
echo ""
|
|
742
|
-
|
|
743
|
-
local loop_count=0
|
|
744
|
-
local max_loops=50 # Safety limit
|
|
745
|
-
|
|
746
|
-
while [[ $loop_count -lt $max_loops ]]; do
|
|
747
|
-
((loop_count++))
|
|
748
|
-
|
|
749
|
-
# Reload PRD each iteration (it gets updated by claude)
|
|
750
|
-
local prd
|
|
751
|
-
prd=$(get_prd)
|
|
752
|
-
|
|
753
|
-
local total
|
|
754
|
-
local completed
|
|
755
|
-
local remaining
|
|
756
|
-
total=$(get_task_count "$prd")
|
|
757
|
-
completed=$(get_completed_count "$prd")
|
|
758
|
-
remaining=$((total - completed))
|
|
759
|
-
|
|
760
|
-
echo ""
|
|
761
|
-
echo -e "${CYAN}--- Iteration $loop_count ---${NC}"
|
|
762
|
-
write_log "Iteration $loop_count - Progress: $completed/$total tasks complete"
|
|
763
|
-
|
|
764
|
-
# Check if all done
|
|
765
|
-
if [[ $remaining -eq 0 ]]; then
|
|
766
|
-
write_log "All tasks completed!" "SUCCESS"
|
|
767
|
-
echo ""
|
|
768
|
-
echo -e "${GREEN}=== Project Complete ===${NC}"
|
|
769
|
-
echo -e "${GREEN}All $total tasks completed successfully.${NC}"
|
|
770
|
-
|
|
771
|
-
# Aggregate learnings on project completion
|
|
772
|
-
aggregate_learnings "$prd"
|
|
773
|
-
|
|
774
|
-
break
|
|
775
|
-
fi
|
|
776
|
-
|
|
777
|
-
# Get next task
|
|
778
|
-
local task
|
|
779
|
-
task=$(get_next_task "$prd")
|
|
780
|
-
|
|
781
|
-
if [[ -z "$task" ]]; then
|
|
782
|
-
write_log "No eligible tasks found. Some tasks may be blocked by dependencies." "WARN"
|
|
783
|
-
echo ""
|
|
784
|
-
echo -e "${YELLOW}Blocked: No tasks have all dependencies met.${NC}"
|
|
785
|
-
echo -e "${YELLOW}Check PRD for dependency issues.${NC}"
|
|
786
|
-
break
|
|
787
|
-
fi
|
|
788
|
-
|
|
789
|
-
local task_id
|
|
790
|
-
local task_title
|
|
791
|
-
task_id=$(echo "$task" | jq -r '.id')
|
|
792
|
-
task_title=$(echo "$task" | jq -r '.title')
|
|
793
|
-
|
|
794
|
-
echo ""
|
|
795
|
-
echo -e "${YELLOW}Executing: $task_id - $task_title${NC}"
|
|
796
|
-
|
|
797
|
-
# Update bead to in-progress
|
|
798
|
-
update_bead_status "$task_id" "in-progress"
|
|
799
|
-
|
|
800
|
-
# Execute the task
|
|
801
|
-
local result
|
|
802
|
-
result=$(invoke_task "$task" "$prd")
|
|
803
|
-
|
|
804
|
-
if [[ "$result" == "SUCCESS" ]]; then
|
|
805
|
-
write_log "Task $task_id execution completed" "SUCCESS"
|
|
806
|
-
# Update bead to done (PRD update happens in Claude session)
|
|
807
|
-
update_bead_status "$task_id" "done"
|
|
808
|
-
else
|
|
809
|
-
write_log "Task $task_id execution had issues" "WARN"
|
|
810
|
-
# Update bead to blocked
|
|
811
|
-
update_bead_status "$task_id" "blocked"
|
|
812
|
-
fi
|
|
813
|
-
|
|
814
|
-
# Brief pause between tasks
|
|
815
|
-
sleep 2
|
|
816
|
-
done
|
|
817
|
-
|
|
818
|
-
if [[ $loop_count -ge $max_loops ]]; then
|
|
819
|
-
write_log "Safety limit reached ($max_loops iterations)" "WARN"
|
|
820
|
-
fi
|
|
821
|
-
|
|
822
|
-
# Final summary
|
|
823
|
-
prd=$(get_prd)
|
|
824
|
-
total=$(get_task_count "$prd")
|
|
825
|
-
completed=$(get_completed_count "$prd")
|
|
826
|
-
remaining=$((total - completed))
|
|
827
|
-
|
|
828
|
-
echo ""
|
|
829
|
-
echo -e "${CYAN}=== Final Summary ===${NC}"
|
|
830
|
-
if [[ $remaining -eq 0 ]]; then
|
|
831
|
-
echo -e "${GREEN}Completed: $completed/$total tasks${NC}"
|
|
832
|
-
else
|
|
833
|
-
echo -e "${YELLOW}Completed: $completed/$total tasks${NC}"
|
|
834
|
-
fi
|
|
835
|
-
echo -e "${GRAY}Log file: $LOG_FILE${NC}"
|
|
836
|
-
|
|
837
|
-
write_log "Loop ended. Final state: $completed/$total tasks complete"
|
|
838
|
-
}
|
|
839
|
-
|
|
840
|
-
# ============================================================================
|
|
841
|
-
# Entry Point
|
|
842
|
-
# ============================================================================
|
|
843
|
-
|
|
844
|
-
# Check for jq dependency
|
|
845
|
-
check_jq
|
|
846
|
-
|
|
847
|
-
# Validate inputs
|
|
848
|
-
if [[ ! -f "$PRD_PATH" ]]; then
|
|
849
|
-
echo -e "${RED}Error: PRD not found at $PRD_PATH${NC}"
|
|
850
|
-
exit 1
|
|
851
|
-
fi
|
|
852
|
-
|
|
853
|
-
if [[ ! -d "$TARGET_REPO" ]]; then
|
|
854
|
-
echo -e "${RED}Error: Target repo not found at $TARGET_REPO${NC}"
|
|
855
|
-
exit 1
|
|
856
|
-
fi
|
|
857
|
-
|
|
858
|
-
# Run the loop
|
|
859
|
-
start_ralph_loop
|