@the-agenticflow/openflows 0.1.2 → 0.1.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (85) hide show
  1. package/.env.example +60 -0
  2. package/README.md +217 -0
  3. package/bin/LICENSE +21 -0
  4. package/bin/README.md +535 -0
  5. package/bin/agentflow-bin +0 -0
  6. package/bin/agentflow-dashboard-bin +0 -0
  7. package/bin/agentflow-doctor-bin +0 -0
  8. package/bin/agentflow-setup-bin +0 -0
  9. package/bin/openflows.js +285 -3
  10. package/bin/orchestration/agent/agents/forge.agent.md +110 -0
  11. package/bin/orchestration/agent/agents/lore.agent.md +27 -0
  12. package/bin/orchestration/agent/agents/nexus.agent.md +201 -0
  13. package/bin/orchestration/agent/agents/sentinel.agent.md +96 -0
  14. package/bin/orchestration/agent/agents/vessel.agent.md +38 -0
  15. package/bin/orchestration/agent/registry.json +10 -0
  16. package/bin/orchestration/agent/standards/CODING.md +22 -0
  17. package/bin/orchestration/agent/standards/REVIEW.md +15 -0
  18. package/bin/orchestration/agent/standards/SECURITY.md +72 -0
  19. package/bin/orchestration/plugin/commands/assign.md +45 -0
  20. package/bin/orchestration/plugin/commands/check-ci.md +26 -0
  21. package/bin/orchestration/plugin/commands/document-pr.md +32 -0
  22. package/bin/orchestration/plugin/commands/gate-approve.md +39 -0
  23. package/bin/orchestration/plugin/commands/handoff.md +75 -0
  24. package/bin/orchestration/plugin/commands/merge.md +47 -0
  25. package/bin/orchestration/plugin/commands/plan.md +66 -0
  26. package/bin/orchestration/plugin/commands/segment-done.md +50 -0
  27. package/bin/orchestration/plugin/commands/status-check.md +28 -0
  28. package/bin/orchestration/plugin/commands/status.md +94 -0
  29. package/bin/orchestration/plugin/commands/update-changelog.md +37 -0
  30. package/bin/orchestration/plugin/hooks/forge/post_write_lint.sh +76 -0
  31. package/bin/orchestration/plugin/hooks/forge/pre_bash_guard.sh +81 -0
  32. package/bin/orchestration/plugin/hooks/forge/pre_compact_handoff.sh +28 -0
  33. package/bin/orchestration/plugin/hooks/forge/pre_write_check.sh +77 -0
  34. package/bin/orchestration/plugin/hooks/forge/session_start.sh +59 -0
  35. package/bin/orchestration/plugin/hooks/forge/stop_require_artifact.sh +75 -0
  36. package/bin/orchestration/plugin/hooks/lore/session-start.sh +13 -0
  37. package/bin/orchestration/plugin/hooks/nexus/init-session.sh +23 -0
  38. package/bin/orchestration/plugin/hooks/nexus/log-decision.sh +10 -0
  39. package/bin/orchestration/plugin/hooks/sentinel/post_write_validate.sh +59 -0
  40. package/bin/orchestration/plugin/hooks/sentinel/pre_bash_readonly_guard.sh +107 -0
  41. package/bin/orchestration/plugin/hooks/sentinel/session_start.sh +74 -0
  42. package/bin/orchestration/plugin/hooks/sentinel/stop_require_eval.sh +57 -0
  43. package/bin/orchestration/plugin/hooks/vessel/log-merge-status.sh +7 -0
  44. package/bin/orchestration/plugin/hooks/vessel/session-start.sh +14 -0
  45. package/bin/orchestration/plugin/mcp/mcp.json.template +26 -0
  46. package/bin/orchestration/plugin/plugin.json +66 -0
  47. package/bin/orchestration/plugin/skills/forge-algorithmic-art.md +24 -0
  48. package/bin/orchestration/plugin/skills/forge-canvas-design.md +25 -0
  49. package/bin/orchestration/plugin/skills/forge-coding.md +161 -0
  50. package/bin/orchestration/plugin/skills/forge-frontend-design.md +30 -0
  51. package/bin/orchestration/plugin/skills/forge-mcp-builder.md +37 -0
  52. package/bin/orchestration/plugin/skills/forge-planning.md +102 -0
  53. package/bin/orchestration/plugin/skills/forge-skill-creator.md +25 -0
  54. package/bin/orchestration/plugin/skills/forge-web-artifacts-builder.md +29 -0
  55. package/bin/orchestration/plugin/skills/lore-brand-guidelines.md +33 -0
  56. package/bin/orchestration/plugin/skills/lore-changelog.md +69 -0
  57. package/bin/orchestration/plugin/skills/lore-doc-coauthoring.md +33 -0
  58. package/bin/orchestration/plugin/skills/lore-documentation.md +57 -0
  59. package/bin/orchestration/plugin/skills/lore-docx.md +20 -0
  60. package/bin/orchestration/plugin/skills/lore-pdf.md +20 -0
  61. package/bin/orchestration/plugin/skills/lore-pptx.md +23 -0
  62. package/bin/orchestration/plugin/skills/lore-theme-factory.md +20 -0
  63. package/bin/orchestration/plugin/skills/lore-xlsx.md +20 -0
  64. package/bin/orchestration/plugin/skills/nexus-doc-coauthoring.md +21 -0
  65. package/bin/orchestration/plugin/skills/nexus-internal-comms.md +28 -0
  66. package/bin/orchestration/plugin/skills/nexus-orchestration.md +63 -0
  67. package/bin/orchestration/plugin/skills/nexus-skill-creator.md +15 -0
  68. package/bin/orchestration/plugin/skills/nexus-slack-gif-creator.md +21 -0
  69. package/bin/orchestration/plugin/skills/nexus-triage.md +56 -0
  70. package/bin/orchestration/plugin/skills/nexus-xlsx.md +20 -0
  71. package/bin/orchestration/plugin/skills/sentinel-algorithmic-art.md +20 -0
  72. package/bin/orchestration/plugin/skills/sentinel-criteria.md +115 -0
  73. package/bin/orchestration/plugin/skills/sentinel-frontend-design.md +20 -0
  74. package/bin/orchestration/plugin/skills/sentinel-review.md +124 -0
  75. package/bin/orchestration/plugin/skills/sentinel-web-artifacts-builder.md +20 -0
  76. package/bin/orchestration/plugin/skills/sentinel-webapp-testing.md +34 -0
  77. package/bin/orchestration/plugin/skills/shared-claude-api.md +25 -0
  78. package/bin/orchestration/plugin/skills/vessel-ci-gate.md +68 -0
  79. package/bin/orchestration/plugin/skills/vessel-internal-comms.md +20 -0
  80. package/bin/orchestration/plugin/skills/vessel-mcp-builder.md +21 -0
  81. package/bin/orchestration/plugin/skills/vessel-merge-protocol.md +113 -0
  82. package/bin/orchestration/plugin/skills/vessel-pdf.md +20 -0
  83. package/bin/orchestration/plugin/skills/vessel-webapp-testing.md +34 -0
  84. package/package.json +12 -2
  85. package/scripts/install.js +212 -23
@@ -0,0 +1,94 @@
1
+ ---
2
+ name: status
3
+ description: Signal terminal status to the harness
4
+ ---
5
+
6
+ # /status Command
7
+
8
+ Signal terminal status to the harness. Use when work is complete or blocked.
9
+
10
+ ## Usage
11
+
12
+ ```bash
13
+ /status <status> [reason]
14
+ ```
15
+
16
+ ## Status Values
17
+
18
+ ### Terminal statuses (ends the pair lifecycle)
19
+ - `PR_OPENED` - Work complete, PR created
20
+ - `COMPLETE` - All work done, PR creation deferred to harness
21
+ - `BLOCKED` - Cannot proceed, needs intervention
22
+ - `FUEL_EXHAUSTED` - Budget/tokens exhausted, need more allocation
23
+
24
+ ### Non-terminal statuses (continues the event loop)
25
+ - `PENDING_REVIEW` - Work paused, waiting for review
26
+ - `AWAITING_SENTINEL_REVIEW` - Segment done, waiting for SENTINEL evaluation
27
+ - `APPROVED_READY` - Changes requested by SENTINEL have been addressed
28
+ - `SEGMENT_N_DONE` - Segment N complete (e.g. `SEGMENT_1_DONE`)
29
+
30
+ ### IMPORTANT
31
+ Do NOT use any other status value. Values like `AWAITING_REVIEW`, `DONE`, `FINISHED`, `SUCCESS`, `IMPLEMENTATION_COMPLETE` will be treated as `BLOCKED` and your work will be wasted.
32
+
33
+ ## What it does
34
+
35
+ 1. Writes STATUS.json with current state
36
+ 2. Lists all files changed
37
+ 3. Provides reason/explanation
38
+ 4. Harness reads STATUS.json and takes appropriate action
39
+
40
+ ## STATUS.json Structure
41
+
42
+ ```json
43
+ {
44
+ "status": "PR_OPENED | COMPLETE | BLOCKED | FUEL_EXHAUSTED | PENDING_REVIEW | AWAITING_SENTINEL_REVIEW | APPROVED_READY | SEGMENT_N_DONE",
45
+ "pair": "pair-{N}",
46
+ "ticket_id": "T-{id}",
47
+ "branch": "forge-{N}/T-{id}",
48
+ "files_changed": [
49
+ "src/auth.rs",
50
+ "tests/auth_test.rs"
51
+ ],
52
+ "segments_completed": 3,
53
+ "pr_url": "https://github.com/owner/repo/pull/42",
54
+ "reason": "Optional reason for BLOCKED or FUEL_EXHAUSTED",
55
+ "timestamp": "2025-03-24T10:00:00Z"
56
+ }
57
+ ```
58
+
59
+ ## Examples
60
+
61
+ ### Work Complete
62
+
63
+ ```bash
64
+ /status PR_OPENED
65
+ ```
66
+
67
+ Then provide the PR URL when prompted.
68
+
69
+ ### Blocked
70
+
71
+ ```bash
72
+ /status BLOCKED Cannot proceed due to API rate limit
73
+ ```
74
+
75
+ ### Fuel Exhausted
76
+
77
+ ```bash
78
+ /status FUEL_EXHAUSTED Need 50k more tokens to complete
79
+ ```
80
+
81
+ ## After STATUS.json
82
+
83
+ The harness will:
84
+
85
+ - **PR_OPENED**: Notify VESSEL to check CI and merge
86
+ - **BLOCKED**: Alert NEXUS for human intervention
87
+ - **FUEL_EXHAUSTED**: Request more budget allocation
88
+
89
+ ## Important
90
+
91
+ - This is a terminal state - you cannot continue after writing STATUS.json
92
+ - For temporary pauses, use `/segment-done` instead
93
+ - For context reset, use `/handoff` instead
94
+ - Always list ALL files changed across all segments
@@ -0,0 +1,37 @@
1
+ ---
2
+ name: update-changelog
3
+ description: Add entry to CHANGELOG.md
4
+ ---
5
+
6
+ # /update-changelog Command
7
+
8
+ Adds an entry to CHANGELOG.md for a merged PR.
9
+
10
+ ## Steps
11
+
12
+ 1. **Read PR Description**
13
+ Get the PR description from the merge.
14
+
15
+ 2. **Categorize Change**
16
+ Determine category:
17
+ - Added: New features
18
+ - Changed: Modified behavior
19
+ - Fixed: Bug fixes
20
+ - Security: Security fixes
21
+
22
+ 3. **Write Entry**
23
+ Add to CHANGELOG.md under [Unreleased]:
24
+ ```markdown
25
+ ### Added
26
+ - New feature X (#42)
27
+ ```
28
+
29
+ 4. **Commit**
30
+ Commit with message:
31
+ ```
32
+ docs: update CHANGELOG for T-{id}
33
+ ```
34
+
35
+ ## Output
36
+
37
+ CHANGELOG.md updated with new entry.
@@ -0,0 +1,76 @@
1
+ #!/bin/bash
2
+ # Runs after every Write, Edit, MultiEdit tool call
3
+ # Validates atomic writes for shared/ artifacts and runs linter on source files
4
+ #
5
+ # Environment:
6
+ # CLAUDE_TOOL_INPUT_FILE_PATH - the file that was written
7
+ # SPRINTLESS_WORKTREE - the worktree directory
8
+
9
+ FILE="${CLAUDE_TOOL_INPUT_FILE_PATH}"
10
+ WORKTREE="${SPRINTLESS_WORKTREE}"
11
+
12
+ # For shared/ artifacts, ensure atomic write was used (.tmp + rename pattern)
13
+ case "$FILE" in
14
+ */orchestration/pairs/*/shared/*)
15
+ # Verify file was written atomically (should never see .tmp files at this point)
16
+ if [[ "$FILE" == *.tmp ]]; then
17
+ echo "ERROR: Temporary file leaked to filesystem: ${FILE}"
18
+ echo "All shared/ writes must be atomic (write to .tmp, then rename)."
19
+ exit 2
20
+ fi
21
+ # Validate JSON structure for specific artifact types
22
+ case "$FILE" in
23
+ */STATUS.json)
24
+ if command -v python3 &> /dev/null; then
25
+ python3 -c "import json, sys; json.load(open('$FILE'))" 2>&1
26
+ if [ $? -ne 0 ]; then
27
+ echo "INVALID: STATUS.json is not valid JSON"
28
+ exit 2
29
+ fi
30
+ fi
31
+ ;;
32
+ esac
33
+ exit 0
34
+ ;;
35
+ esac
36
+
37
+ # Only lint source files (not config, docs, etc.)
38
+ case "$FILE" in
39
+ *.ts|*.tsx)
40
+ if command -v npx &> /dev/null; then
41
+ OUTPUT=$(cd "$WORKTREE" && npx eslint "$FILE" --quiet 2>&1)
42
+ if [ $? -ne 0 ]; then
43
+ echo "Lint failed on ${FILE}:"
44
+ echo "$OUTPUT"
45
+ echo ""
46
+ echo "Fix these lint errors before continuing."
47
+ exit 2
48
+ fi
49
+ fi
50
+ ;;
51
+ *.rs)
52
+ if command -v cargo &> /dev/null; then
53
+ OUTPUT=$(cd "$WORKTREE" && cargo clippy --quiet --message-format=short 2>&1 | grep -A5 "$FILE" || true)
54
+ if [ -n "$OUTPUT" ]; then
55
+ echo "Clippy warnings for ${FILE}:"
56
+ echo "$OUTPUT"
57
+ echo ""
58
+ echo "Fix these warnings before continuing."
59
+ # Clippy warnings don't fail the build, but we want clean code
60
+ # exit 2 # Uncomment to enforce zero warnings
61
+ fi
62
+ fi
63
+ ;;
64
+ *.py)
65
+ if command -v ruff &> /dev/null; then
66
+ OUTPUT=$(cd "$WORKTREE" && ruff check "$FILE" 2>&1)
67
+ if [ $? -ne 0 ]; then
68
+ echo "Ruff failed on ${FILE}:"
69
+ echo "$OUTPUT"
70
+ exit 2
71
+ fi
72
+ fi
73
+ ;;
74
+ esac
75
+
76
+ exit 0
@@ -0,0 +1,81 @@
1
+ #!/bin/bash
2
+ # Runs before every Bash tool call
3
+ # Blocks dangerous commands and access to other pairs' worktrees
4
+ #
5
+ # Environment:
6
+ # CLAUDE_TOOL_INPUT_COMMAND - the command being executed
7
+ # SPRINTLESS_PAIR_ID - the current pair ID
8
+
9
+ CMD="${CLAUDE_TOOL_INPUT_COMMAND}"
10
+
11
+ # Block direct git push to non-forge branches - must use MCP tools for PR creation
12
+ if echo "$CMD" | grep -qE '^git push|^git push '; then
13
+ # Allow pushing to the pair's own branch
14
+ BRANCH_PATTERN="forge-${SPRINTLESS_PAIR_ID}"
15
+ if echo "$CMD" | grep -q "$BRANCH_PATTERN"; then
16
+ # Allow pushing own branch
17
+ exit 0
18
+ fi
19
+ echo "BLOCKED: Cannot push to branches other than your own."
20
+ echo ""
21
+ echo "Your branch: forge-${SPRINTLESS_PAIR_ID}/${SPRINTLESS_TICKET_ID}"
22
+ echo ""
23
+ echo "After pushing, create a PR using GitHub MCP tools:"
24
+ echo " 1. Use create_pull_request from github MCP server"
25
+ echo " 2. Write STATUS.json with PR_OPENED status and PR URL"
26
+ exit 2
27
+ fi
28
+
29
+ # Block writes to other pairs' worktrees
30
+ if echo "$CMD" | grep -qE 'worktrees/pair-[0-9]+/' ; then
31
+ REFERENCED=$(echo "$CMD" | grep -oE 'pair-[0-9]+' | head -1)
32
+ if [ "$REFERENCED" != "${SPRINTLESS_PAIR_ID}" ]; then
33
+ echo "BLOCKED: Cannot access ${REFERENCED}'s worktree."
34
+ echo "You are ${SPRINTLESS_PAIR_ID}."
35
+ echo ""
36
+ echo "Each pair works in isolation. You cannot read or write"
37
+ echo "to another pair's worktree."
38
+ exit 2
39
+ fi
40
+ fi
41
+
42
+ # Block writes to main branch
43
+ if echo "$CMD" | grep -qE 'checkout main|checkout origin/main'; then
44
+ echo "BLOCKED: Cannot checkout main. Work on your branch only."
45
+ echo ""
46
+ echo "Your branch: forge-${SPRINTLESS_PAIR_ID}/${SPRINTLESS_TICKET_ID}"
47
+ exit 2
48
+ fi
49
+
50
+ # Block dangerous commands
51
+ DANGEROUS_PATTERNS="rm -rf /|sudo rm|:(){ :|:& };:|mkfs|dd if="
52
+ if echo "$CMD" | grep -qE "$DANGEROUS_PATTERNS"; then
53
+ echo "BLOCKED: Dangerous command detected."
54
+ echo "This command is not allowed for safety reasons."
55
+ exit 2
56
+ fi
57
+
58
+ # Block network operations (MCP tools should be used instead)
59
+ NETWORK_PATTERNS="^curl |^wget |^nc |^ncat |^telnet |^ssh "
60
+ if echo "$CMD" | grep -qE "$NETWORK_PATTERNS"; then
61
+ echo "BLOCKED: Network commands are not allowed."
62
+ echo ""
63
+ echo "Use MCP tools instead:"
64
+ echo " - For GitHub API: use github MCP server"
65
+ echo " - For HTTP requests: use appropriate MCP tool"
66
+ exit 2
67
+ fi
68
+
69
+ # Block package installation (could introduce unreviewed dependencies)
70
+ INSTALL_PATTERNS="npm install |yarn add |pip install |cargo install |go get "
71
+ if echo "$CMD" | grep -qE "$INSTALL_PATTERNS"; then
72
+ echo "BLOCKED: Package installation is not allowed."
73
+ echo ""
74
+ echo "If a new dependency is needed:"
75
+ echo " 1. Document it in PLAN.md"
76
+ echo " 2. Get SENTINEL approval"
77
+ echo " 3. Have a human add it to package.json/Cargo.toml"
78
+ exit 2
79
+ fi
80
+
81
+ exit 0
@@ -0,0 +1,28 @@
1
+ #!/bin/bash
2
+ # Runs on PreCompact - converts compaction to clean context reset
3
+ # This hook fires when the context window is approaching its limit
4
+ #
5
+ # Environment:
6
+ # SPRINTLESS_SHARED - the shared directory
7
+
8
+ SHARED="${SPRINTLESS_SHARED}"
9
+
10
+ echo "=============================================="
11
+ echo " CONTEXT RESET REQUIRED"
12
+ echo "=============================================="
13
+ echo ""
14
+ echo "Your context window is approaching its limit."
15
+ echo "Before this session ends, you must write a handoff."
16
+ echo ""
17
+ echo "Use the /handoff command now. It will:"
18
+ echo " 1. Collect everything needed for the handoff"
19
+ echo " 2. Write ${SHARED}/HANDOFF.md"
20
+ echo " 3. Update WORKLOG.md with current state"
21
+ echo " 4. Exit cleanly"
22
+ echo ""
23
+ echo "A fresh FORGE session will read your handoff and continue."
24
+ echo ""
25
+ echo "DO NOT attempt to continue working - write the handoff now."
26
+ echo ""
27
+
28
+ exit 2
@@ -0,0 +1,77 @@
1
+ #!/bin/bash
2
+ # Runs before every Write, Edit, MultiEdit tool call
3
+ # Enforces dynamic file ownership locking via flock
4
+ #
5
+ # Environment:
6
+ # CLAUDE_TOOL_INPUT_FILE_PATH - the file being written
7
+ # SPRINTLESS_PAIR_ID - the current pair ID
8
+ # SPRINTLESS_SHARED - the shared directory
9
+
10
+ FILE="${CLAUDE_TOOL_INPUT_FILE_PATH}"
11
+ PAIR_ID="${SPRINTLESS_PAIR_ID}"
12
+ LOCKS_DIR="${SPRINTLESS_SHARED}/../locks"
13
+
14
+ # Skip lock check for shared/ artifacts - those are pair-scoped already
15
+ case "$FILE" in
16
+ */orchestration/pairs/*/shared/*)
17
+ exit 0
18
+ ;;
19
+ esac
20
+
21
+ # Also skip if FILE is relative and matches shared pattern
22
+ case "$FILE" in
23
+ shared/*|./shared/*)
24
+ exit 0
25
+ ;;
26
+ esac
27
+
28
+ # Create locks directory if needed
29
+ mkdir -p "$LOCKS_DIR" 2>/dev/null
30
+
31
+ # Generate lock filename (sha256 hash of filepath to avoid path issues)
32
+ LOCK_HASH=$(echo -n "$FILE" | sha256sum | cut -d' ' -f1)
33
+ LOCK_FILE="${LOCKS_DIR}/${LOCK_HASH}.lock"
34
+ LOCK_JSON="${LOCKS_DIR}/${LOCK_HASH}.json"
35
+
36
+ # Attempt atomic lock acquisition using flock
37
+ {
38
+ # Acquire exclusive lock on .lock file (non-blocking)
39
+ flock -x -n 200 || {
40
+ echo "BLOCKED: Another process is currently locking ${FILE}"
41
+ echo "Waiting for lock to be released..."
42
+ exit 2
43
+ }
44
+
45
+ # Check if lock JSON exists and who owns it
46
+ if [ -f "$LOCK_JSON" ]; then
47
+ OWNER=$(cat "$LOCK_JSON" | grep -o '"pair"[[:space:]]*:[[:space:]]*"[^"]*"' | head -1 | cut -d'"' -f4)
48
+ if [ "$OWNER" != "$PAIR_ID" ]; then
49
+ echo "BLOCKED: ${FILE} is currently locked by ${OWNER}."
50
+ echo ""
51
+ echo "This file is being modified by another pair."
52
+ echo ""
53
+ echo "Options:"
54
+ echo " 1. Find an alternative implementation that avoids this file"
55
+ echo " 2. Wait for ${OWNER} to complete and release the lock"
56
+ echo " 3. Set STATUS.json to BLOCKED with reason FILE_LOCK_CONFLICT"
57
+ echo ""
58
+ echo "Lock details in: ${LOCK_JSON}"
59
+
60
+ exit 2
61
+ fi
62
+ # Lock belongs to us - proceed
63
+ else
64
+ # No lock exists - acquire it
65
+ cat > "$LOCK_JSON" << EOF
66
+ {
67
+ "pair": "${PAIR_ID}",
68
+ "file": "${FILE}",
69
+ "acquired_at": "$(date -u +%Y-%m-%dT%H:%M:%SZ)"
70
+ }
71
+ EOF
72
+ fi
73
+
74
+ } 200>"$LOCK_FILE"
75
+
76
+ # Lock acquired or already owned by us - proceed with write
77
+ exit 0
@@ -0,0 +1,59 @@
1
+ #!/bin/bash
2
+ # Runs when FORGE starts a new session
3
+ # This hook runs at the beginning of every FORGE session
4
+
5
+ PAIR_ID="${SPRINTLESS_PAIR_ID}"
6
+ TICKET_ID="${SPRINTLESS_TICKET_ID}"
7
+ SHARED="${SPRINTLESS_SHARED}"
8
+ WORKTREE="${SPRINTLESS_WORKTREE}"
9
+
10
+ # Log session start to shared event log
11
+ echo "[$(date -u +%Y-%m-%dT%H:%M:%SZ)] forge-${PAIR_ID} session_start ticket=${TICKET_ID}" \
12
+ >> "${SHARED}/../events.log"
13
+
14
+ # Check if this is a resume (HANDOFF.md exists)
15
+ if [ -f "${SHARED}/HANDOFF.md" ]; then
16
+ echo "=========================================="
17
+ echo " RESUME MODE: HANDOFF.md found"
18
+ echo "=========================================="
19
+ echo ""
20
+ echo "Read ${SHARED}/HANDOFF.md before doing anything else."
21
+ echo "Continue from the exact next step described in the handoff."
22
+ echo ""
23
+ echo "Key things to check:"
24
+ echo " 1. Which segments are already complete"
25
+ echo " 2. Which segment is in progress"
26
+ echo " 3. Decisions already made (do not contradict)"
27
+ echo " 4. Files already written (do not rewrite)"
28
+ echo " 5. Exact next step to take"
29
+ echo ""
30
+ else
31
+ echo "=========================================="
32
+ echo " NEW SESSION: No handoff found"
33
+ echo "=========================================="
34
+ echo ""
35
+ echo "Starting fresh on ticket ${TICKET_ID}"
36
+ echo ""
37
+ echo "IMPORTANT - Directory Structure:"
38
+ echo " CURRENT DIR (worktree): ${WORKTREE}"
39
+ echo " -> Write ALL source code, tests, package.json here"
40
+ echo " SHARED DIR: ${SHARED}"
41
+ echo " -> Write PLAN.md, WORKLOG.md, STATUS.json here"
42
+ echo ""
43
+ echo "First steps:"
44
+ echo " 1. Read ${SHARED}/TICKET.md to understand the task"
45
+ echo " 2. Read ${SHARED}/TASK.md for specific instructions"
46
+ echo " 3. Use /plan command to create ${SHARED}/PLAN.md"
47
+ echo " 4. Wait for CONTRACT.md from SENTINEL"
48
+ echo ""
49
+ fi
50
+
51
+ # Show current state
52
+ echo "Environment:"
53
+ echo " PAIR_ID: ${PAIR_ID}"
54
+ echo " TICKET_ID: ${TICKET_ID}"
55
+ echo " WORKTREE: ${WORKTREE}"
56
+ echo " SHARED: ${SHARED}"
57
+ echo ""
58
+
59
+ exit 0
@@ -0,0 +1,75 @@
1
+ #!/bin/bash
2
+ # Runs on Stop - FORGE cannot exit without a terminal artifact
3
+ # This ensures FORGE always leaves a clear state for the harness
4
+ #
5
+ # Environment:
6
+ # SPRINTLESS_SHARED - the shared directory
7
+
8
+ SHARED="${SPRINTLESS_SHARED}"
9
+
10
+ # Accept: STATUS.json written (done or blocked)
11
+ if [ -f "${SHARED}/STATUS.json" ]; then
12
+ # Validate it has required fields
13
+ if command -v python3 &> /dev/null; then
14
+ VALID=$(python3 -c "
15
+ import json, sys
16
+ try:
17
+ s = json.load(open('${SHARED}/STATUS.json'))
18
+ required = ['status','pair','ticket_id','files_changed']
19
+ missing = [k for k in required if k not in s]
20
+ valid_statuses = ['PR_OPENED','BLOCKED','FUEL_EXHAUSTED','PENDING_REVIEW']
21
+ # Note: IMPLEMENTATION_COMPLETE and COMPLETED are NOT valid terminal statuses
22
+ # FORGE must push and create PR (PR_OPENED) or explicitly block
23
+ if missing:
24
+ print(f'missing: {missing}')
25
+ sys.exit(1)
26
+ if s['status'] not in valid_statuses:
27
+ print(f'invalid status: {s[\"status\"]}')
28
+ sys.exit(1)
29
+ except Exception as e:
30
+ print(str(e))
31
+ sys.exit(1)
32
+ " 2>&1)
33
+ if [ $? -ne 0 ]; then
34
+ echo "STATUS.json exists but is invalid: ${VALID}"
35
+ echo "Fix STATUS.json before exiting."
36
+ echo ""
37
+ echo "Required fields: status, pair, ticket_id, files_changed"
38
+ echo "Valid statuses: PR_OPENED, BLOCKED, FUEL_EXHAUSTED, PENDING_REVIEW"
39
+ exit 2
40
+ fi
41
+ fi
42
+ exit 0
43
+ fi
44
+
45
+ # Accept: HANDOFF.md written (context reset in progress)
46
+ if [ -f "${SHARED}/HANDOFF.md" ]; then
47
+ # Verify HANDOFF.md has required sections
48
+ if grep -q "## Exact next step" "${SHARED}/HANDOFF.md"; then
49
+ exit 0
50
+ else
51
+ echo "HANDOFF.md is incomplete. It must contain '## Exact next step'."
52
+ echo ""
53
+ echo "Required sections in HANDOFF.md:"
54
+ echo " - ## Completed Segments"
55
+ echo " - ## Decisions"
56
+ echo " - ## Files Changed"
57
+ echo " - ## Exact next step"
58
+ exit 2
59
+ fi
60
+ fi
61
+
62
+ # Neither exists - block exit
63
+ echo "=============================================="
64
+ echo " BLOCKED: Cannot exit without terminal artifact"
65
+ echo "=============================================="
66
+ echo ""
67
+ echo "You must write either:"
68
+ echo " - ${SHARED}/STATUS.json (if done or blocked)"
69
+ echo " - ${SHARED}/HANDOFF.md (if context reset needed)"
70
+ echo ""
71
+ echo "Use /status command if your work is complete."
72
+ echo "Use /handoff command if you need a context reset."
73
+ echo ""
74
+
75
+ exit 2
@@ -0,0 +1,13 @@
1
+ #!/bin/bash
2
+ # LORE Session Start Hook
3
+ # Initializes the documenter session
4
+
5
+ echo "=========================================="
6
+ echo "LORE Session Starting"
7
+ echo "=========================================="
8
+ echo ""
9
+ echo "Checking for recently merged PRs..."
10
+
11
+ # Lore monitors merged PRs and updates documentation
12
+
13
+ exit 0
@@ -0,0 +1,23 @@
1
+ #!/bin/bash
2
+ # NEXUS Session Start Hook
3
+ # Initializes the orchestrator session
4
+
5
+ echo "NEXUS session starting..."
6
+ echo "Reading registry from: ${AGENTFLOW_REGISTRY:-.agent/registry.json}"
7
+ echo "Store path: ${AGENTFLOW_STORE:-.agent/store.json}"
8
+
9
+ # Check if jq is installed
10
+ if ! command -v jq &> /dev/null; then
11
+ echo "ERROR: jq is not installed. Please install it to use NEXUS."
12
+ exit 1
13
+ fi
14
+
15
+ # Check for pending command gate items
16
+ if [ -n "${AGENTFLOW_STORE}" ] && [ -f "${AGENTFLOW_STORE}" ]; then
17
+ GATE_PENDING=$(jq -r '.command_gate | length // 0' "${AGENTFLOW_STORE}" 2>/dev/null || echo "0")
18
+ if [ "$GATE_PENDING" -gt 0 ]; then
19
+ echo "WARNING: ${GATE_PENDING} pending command(s) awaiting approval"
20
+ fi
21
+ fi
22
+
23
+ exit 0
@@ -0,0 +1,10 @@
1
+ #!/bin/bash
2
+ # NEXUS Stop Hook
3
+ # Logs the decision made this session
4
+
5
+ echo "NEXUS session ending. Decision logged."
6
+
7
+ # The actual decision is captured in the shared store
8
+ # This hook ensures we have a log entry
9
+
10
+ exit 0
@@ -0,0 +1,59 @@
1
+ #!/bin/bash
2
+ # SENTINEL Post-Write Validation Hook
3
+ # Validates that eval files have correct structure
4
+ #
5
+ # Environment:
6
+ # SPRINTLESS_SHARED - the shared directory
7
+ # CLAUDE_FILE - the file that was just written (injected by Claude Code)
8
+
9
+ SHARED="${SPRINTLESS_SHARED}"
10
+ FILE="${CLAUDE_FILE:-}"
11
+
12
+ # Only validate eval files
13
+ if [[ ! "$FILE" =~ -eval\.md$ ]] && [[ ! "$FILE" =~ final-review\.md$ ]]; then
14
+ exit 0
15
+ fi
16
+
17
+ echo "Validating evaluation file: ${FILE}"
18
+ echo ""
19
+
20
+ # Check required sections
21
+ MISSING=""
22
+
23
+ if ! grep -q "## Summary" "$FILE"; then
24
+ MISSING="${MISSING}Summary, "
25
+ fi
26
+
27
+ if ! grep -q "## Tests Run" "$FILE" && ! grep -q "## Test Results" "$FILE"; then
28
+ MISSING="${MISSING}Tests Run, "
29
+ fi
30
+
31
+ if ! grep -q "## Verdict" "$FILE"; then
32
+ MISSING="${MISSING}Verdict, "
33
+ fi
34
+
35
+ # Check verdict is valid
36
+ VERDICT=$(grep -oP '(?<=## Verdict\n)[A-Z_]+' "$FILE" 2>/dev/null || echo "")
37
+ if [ -n "$VERDICT" ]; then
38
+ if [ "$VERDICT" != "APPROVED" ] && [ "$VERDICT" != "NEEDS_WORK" ]; then
39
+ echo "ERROR: Invalid verdict '${VERDICT}'. Must be APPROVED or NEEDS_WORK."
40
+ exit 2
41
+ fi
42
+ fi
43
+
44
+ if [ -n "$MISSING" ]; then
45
+ echo "ERROR: Missing required sections: ${MISSING%,*}"
46
+ echo ""
47
+ echo "Required sections for eval files:"
48
+ echo " - ## Summary"
49
+ echo " - ## Tests Run (or ## Test Results)"
50
+ echo " - ## Verdict (APPROVED or NEEDS_WORK)"
51
+ echo ""
52
+ echo "If NEEDS_WORK, also include:"
53
+ echo " - ## Issues Found"
54
+ echo " - ## Required Fixes"
55
+ exit 2
56
+ fi
57
+
58
+ echo "Validation passed."
59
+ exit 0