@orchestrator-claude/definitions 3.12.1 → 3.12.2
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/hooks/dangling-workflow-guard.sh +57 -0
- package/hooks/gate-guardian.sh +79 -0
- package/hooks/orch-helpers.sh +133 -0
- package/hooks/ping-pong-enforcer.sh +58 -0
- package/hooks/post-phase-checkpoint.sh +159 -137
- package/hooks/prompt-orchestrator.sh +41 -0
- package/hooks/session-orchestrator.sh +54 -0
- package/hooks/track-agent-invocation.sh +108 -70
- package/hooks/workflow-guard.sh +79 -0
- package/manifest.json +35 -19
- package/package.json +1 -1
- package/hooks/post-agent-artifact-relay.sh +0 -11
- package/hooks/post-artifact-generate.sh +0 -39
- package/hooks/post-implement-validate.sh +0 -102
- package/hooks/pre-agent-invoke.sh +0 -34
- package/hooks/pre-phase-advance.sh +0 -40
|
@@ -1,180 +1,202 @@
|
|
|
1
1
|
#!/bin/bash
|
|
2
|
-
# Post-Phase Checkpoint Hook (
|
|
3
|
-
#
|
|
4
|
-
#
|
|
2
|
+
# Post-Phase Checkpoint Hook (RFC-012 compatible)
|
|
3
|
+
# Registers a checkpoint in PostgreSQL via the Orchestrator REST API.
|
|
4
|
+
# Replaces the deprecated orchestrator-index.json approach (TD-105 F-04).
|
|
5
5
|
#
|
|
6
6
|
# Triggered by: PostToolUse on Task tool (after agent completes)
|
|
7
|
-
#
|
|
8
|
-
#
|
|
7
|
+
# Behavior: Infers the just-completed phase from the active workflow state
|
|
8
|
+
# and registers a checkpoint via the REST API.
|
|
9
|
+
#
|
|
10
|
+
# Required env vars:
|
|
11
|
+
# ORCHESTRATOR_API_URL - Base URL (e.g. http://localhost:3000)
|
|
12
|
+
# ORCHESTRATOR_PROJECT_TOKEN - Bearer token for API authentication
|
|
13
|
+
#
|
|
14
|
+
# Optional env vars:
|
|
15
|
+
# ORCHESTRATOR_PROJECT_ID - Project ID for project-scoped workflow query
|
|
16
|
+
# ORCH_CHECKPOINT_DEBUG=1 - Enable verbose logging
|
|
17
|
+
#
|
|
18
|
+
# Always exits 0 (non-blocking).
|
|
9
19
|
|
|
10
|
-
set -
|
|
20
|
+
set -euo pipefail
|
|
11
21
|
|
|
12
|
-
# Configuration
|
|
13
22
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
# API Configuration
|
|
20
|
-
API_URL="${ORCHESTRATOR_API_URL:-http://localhost:3001}"
|
|
21
|
-
AUTH_EMAIL="${ORCHESTRATOR_AUTH_EMAIL:-admin@orchestrator.local}"
|
|
22
|
-
AUTH_PASSWORD="${ORCHESTRATOR_AUTH_PASSWORD:-admin123}"
|
|
23
|
-
PROJECT_ID="${ORCHESTRATOR_PROJECT_ID:-d001d65d-25f5-4d13-b1dc-d006873e949c}"
|
|
23
|
+
STATE_DIR="$SCRIPT_DIR/../../.orchestrator/.state"
|
|
24
|
+
LOG_FILE="${STATE_DIR}/checkpoint-hook.log"
|
|
25
|
+
LAST_PHASE_FILE="${STATE_DIR}/last-checkpointed-phase"
|
|
26
|
+
DEBUG="${ORCH_CHECKPOINT_DEBUG:-0}"
|
|
24
27
|
|
|
25
28
|
mkdir -p "$STATE_DIR"
|
|
26
29
|
|
|
27
|
-
|
|
30
|
+
log_info() { echo "[$(date -u +%Y-%m-%dT%H:%M:%SZ)] [INFO] $1" >> "$LOG_FILE"; }
|
|
31
|
+
log_warn() { echo "[$(date -u +%Y-%m-%dT%H:%M:%SZ)] [WARN] $1" >> "$LOG_FILE"; echo "[WARN] $1" >&2; }
|
|
32
|
+
log_debug() { [ "$DEBUG" = "1" ] && echo "[$(date -u +%Y-%m-%dT%H:%M:%SZ)] [DEBUG] $1" >> "$LOG_FILE" || true; }
|
|
28
33
|
|
|
29
|
-
|
|
30
|
-
if [ "$DEBUG" = "1" ]; then
|
|
31
|
-
echo "[$(date -u +%Y-%m-%dT%H:%M:%SZ)] [DEBUG] $1" >> "$LOG_FILE"
|
|
32
|
-
echo "[DEBUG] $1" >&2
|
|
33
|
-
fi
|
|
34
|
-
}
|
|
34
|
+
# ── prerequisites ─────────────────────────────────────────────────────────────
|
|
35
35
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
36
|
+
check_prerequisites() {
|
|
37
|
+
if ! command -v curl &>/dev/null; then
|
|
38
|
+
log_warn "curl not found. Checkpoints disabled."
|
|
39
|
+
return 1
|
|
40
|
+
fi
|
|
41
|
+
if ! command -v jq &>/dev/null; then
|
|
42
|
+
log_warn "jq not found. Checkpoints disabled."
|
|
43
|
+
return 1
|
|
40
44
|
fi
|
|
45
|
+
if [ -z "${ORCHESTRATOR_API_URL:-}" ]; then
|
|
46
|
+
log_debug "ORCHESTRATOR_API_URL not set. Checkpoints disabled."
|
|
47
|
+
return 1
|
|
48
|
+
fi
|
|
49
|
+
if [ -z "${ORCHESTRATOR_PROJECT_TOKEN:-}" ]; then
|
|
50
|
+
log_debug "ORCHESTRATOR_PROJECT_TOKEN not set. Checkpoints disabled."
|
|
51
|
+
return 1
|
|
52
|
+
fi
|
|
53
|
+
return 0
|
|
41
54
|
}
|
|
42
55
|
|
|
43
|
-
|
|
44
|
-
echo "[$(date -u +%Y-%m-%dT%H:%M:%SZ)] [ERROR] $1" >> "$LOG_FILE"
|
|
45
|
-
echo "[ERROR] $1" >&2
|
|
46
|
-
}
|
|
56
|
+
# ── API helpers ────────────────────────────────────────────────────────────────
|
|
47
57
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
local
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
resp=$(curl -s -f -X POST "${API_URL}/api/v1/auth/login" \
|
|
58
|
+
get_active_workflow() {
|
|
59
|
+
local project_id="${ORCHESTRATOR_PROJECT_ID:-}"
|
|
60
|
+
local url="${ORCHESTRATOR_API_URL}/api/v1/workflows?status=in_progress&limit=1"
|
|
61
|
+
[ -n "$project_id" ] && url="${url}&projectId=${project_id}"
|
|
62
|
+
|
|
63
|
+
local tmpfile
|
|
64
|
+
tmpfile=$(mktemp 2>/dev/null) || return 1
|
|
65
|
+
|
|
66
|
+
curl -sf \
|
|
67
|
+
-H "Authorization: Bearer ${ORCHESTRATOR_PROJECT_TOKEN}" \
|
|
59
68
|
-H "Content-Type: application/json" \
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
69
|
+
"${url}" \
|
|
70
|
+
-o "$tmpfile" 2>/dev/null || { rm -f "$tmpfile"; return 1; }
|
|
71
|
+
|
|
72
|
+
local result
|
|
73
|
+
result=$(node -e "
|
|
74
|
+
const fs=require('fs');
|
|
75
|
+
try {
|
|
76
|
+
const d=fs.readFileSync('${tmpfile}','utf8');
|
|
77
|
+
const j=JSON.parse(d);
|
|
78
|
+
const wf=Array.isArray(j)?j[0]:j;
|
|
79
|
+
if(wf&&wf.id){ process.stdout.write(JSON.stringify(wf)); process.exit(0); }
|
|
80
|
+
process.exit(1);
|
|
81
|
+
} catch { process.exit(1); }" 2>/dev/null)
|
|
82
|
+
local rc=$?
|
|
83
|
+
rm -f "$tmpfile"
|
|
84
|
+
[ $rc -eq 0 ] && echo "$result" || return 1
|
|
64
85
|
}
|
|
65
86
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
local
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
87
|
+
create_checkpoint() {
|
|
88
|
+
local workflow_id="$1"
|
|
89
|
+
local phase="$2"
|
|
90
|
+
local description="$3"
|
|
91
|
+
|
|
92
|
+
local body
|
|
93
|
+
body=$(jq -n \
|
|
94
|
+
--arg phase "$phase" \
|
|
95
|
+
--arg desc "$description" \
|
|
96
|
+
'{ phase: $phase, description: $desc }')
|
|
97
|
+
|
|
98
|
+
local http_code
|
|
99
|
+
http_code=$(curl -sf -o /dev/null -w "%{http_code}" \
|
|
100
|
+
-X POST \
|
|
101
|
+
-H "Authorization: Bearer ${ORCHESTRATOR_PROJECT_TOKEN}" \
|
|
102
|
+
-H "Content-Type: application/json" \
|
|
103
|
+
-d "$body" \
|
|
104
|
+
"${ORCHESTRATOR_API_URL}/api/v1/workflows/${workflow_id}/checkpoints" 2>/dev/null) || echo ""
|
|
74
105
|
|
|
75
|
-
|
|
76
|
-
# When currentPhase = PLAN, SPECIFY just completed; etc.
|
|
77
|
-
get_completed_phase() {
|
|
78
|
-
case "$1" in
|
|
79
|
-
plan|PLAN) echo "specify" ;;
|
|
80
|
-
tasks|TASKS) echo "plan" ;;
|
|
81
|
-
implement|IMPLEMENT) echo "tasks" ;;
|
|
82
|
-
completed) echo "implement" ;;
|
|
83
|
-
*) echo "" ;;
|
|
84
|
-
esac
|
|
106
|
+
echo "$http_code"
|
|
85
107
|
}
|
|
86
108
|
|
|
87
|
-
#
|
|
88
|
-
create_git_checkpoint() {
|
|
89
|
-
local phase="$1"
|
|
90
|
-
|
|
91
|
-
log_info "Creating git checkpoint for phase: $phase"
|
|
109
|
+
# ── dedup guard ────────────────────────────────────────────────────────────────
|
|
92
110
|
|
|
93
|
-
|
|
111
|
+
get_saved_last_phase() {
|
|
112
|
+
[ -f "$LAST_PHASE_FILE" ] && cat "$LAST_PHASE_FILE" || echo ""
|
|
113
|
+
}
|
|
94
114
|
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
echo ""
|
|
99
|
-
return 0
|
|
100
|
-
fi
|
|
115
|
+
save_last_phase() {
|
|
116
|
+
echo "$1" > "$LAST_PHASE_FILE"
|
|
117
|
+
}
|
|
101
118
|
|
|
102
|
-
|
|
119
|
+
# ── phase inference ────────────────────────────────────────────────────────────
|
|
103
120
|
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
121
|
+
# When workflow is at PLAN, it means SPECIFY just completed, etc.
|
|
122
|
+
get_completed_phase() {
|
|
123
|
+
local current="$1"
|
|
124
|
+
local status="$2"
|
|
125
|
+
case "$status" in
|
|
126
|
+
"completed") echo "implement"; return ;;
|
|
127
|
+
esac
|
|
128
|
+
case "${current,,}" in
|
|
129
|
+
"plan") echo "specify" ;;
|
|
130
|
+
"tasks") echo "plan" ;;
|
|
131
|
+
"implement") echo "tasks" ;;
|
|
132
|
+
*) echo "" ;;
|
|
133
|
+
esac
|
|
114
134
|
}
|
|
115
135
|
|
|
116
|
-
#
|
|
117
|
-
register_checkpoint() {
|
|
118
|
-
local wf_id="$1"
|
|
119
|
-
local phase="$2"
|
|
120
|
-
local commit_hash="$3"
|
|
121
|
-
local description="$4"
|
|
122
|
-
local token
|
|
123
|
-
token=$(get_token) || return 1
|
|
124
|
-
curl -s -f -X POST "${API_URL}/api/v1/checkpoints" \
|
|
125
|
-
-H "Content-Type: application/json" \
|
|
126
|
-
-H "Authorization: Bearer $token" \
|
|
127
|
-
-H "X-Project-ID: $PROJECT_ID" \
|
|
128
|
-
-d "{\"workflowId\":\"${wf_id}\",\"description\":\"${description}\",\"commitHash\":\"${commit_hash}\"}" >> "$LOG_FILE" 2>&1 || true
|
|
129
|
-
}
|
|
136
|
+
# ── main ───────────────────────────────────────────────────────────────────────
|
|
130
137
|
|
|
131
138
|
main() {
|
|
132
139
|
log_debug "Hook triggered"
|
|
133
140
|
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
# Get workflow from API
|
|
139
|
-
WORKFLOW_RESP=$(get_workflow_info) || { log_debug "No API access"; exit 0; }
|
|
140
|
-
|
|
141
|
-
WORKFLOW_DATA=$(echo "$WORKFLOW_RESP" | node -e "
|
|
142
|
-
let d='';process.stdin.on('data',c=>d+=c);process.stdin.on('end',()=>{
|
|
143
|
-
try{
|
|
144
|
-
const j=JSON.parse(d);
|
|
145
|
-
const wfs=j.data||j;
|
|
146
|
-
const wf=Array.isArray(wfs)?wfs[0]:wfs;
|
|
147
|
-
if(!wf){console.log('{}');return;}
|
|
148
|
-
console.log(JSON.stringify({id:wf.id||'',phase:wf.currentPhase||wf.phase||'',status:wf.status||''}));
|
|
149
|
-
}catch{console.log('{}')}
|
|
150
|
-
});
|
|
151
|
-
" 2>/dev/null)
|
|
141
|
+
if ! check_prerequisites; then
|
|
142
|
+
exit 0
|
|
143
|
+
fi
|
|
152
144
|
|
|
153
|
-
|
|
154
|
-
|
|
145
|
+
local workflow_json
|
|
146
|
+
workflow_json=$(get_active_workflow 2>/dev/null) || workflow_json=""
|
|
155
147
|
|
|
156
|
-
[ -z "$
|
|
148
|
+
if [ -z "$workflow_json" ]; then
|
|
149
|
+
log_debug "No active workflow found via API."
|
|
150
|
+
exit 0
|
|
151
|
+
fi
|
|
157
152
|
|
|
158
|
-
|
|
159
|
-
|
|
153
|
+
local workflow_id current_phase workflow_status
|
|
154
|
+
workflow_id=$(echo "$workflow_json" | jq -r '.id // empty' 2>/dev/null || echo "")
|
|
155
|
+
current_phase=$(echo "$workflow_json" | jq -r '.currentPhase // empty' 2>/dev/null || echo "")
|
|
156
|
+
workflow_status=$(echo "$workflow_json" | jq -r '.status // empty' 2>/dev/null || echo "")
|
|
160
157
|
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
158
|
+
if [ -z "$workflow_id" ] || [ -z "$current_phase" ]; then
|
|
159
|
+
log_debug "Could not parse workflow ID or phase."
|
|
160
|
+
exit 0
|
|
161
|
+
fi
|
|
164
162
|
|
|
165
|
-
|
|
163
|
+
local completed_phase
|
|
164
|
+
completed_phase=$(get_completed_phase "$current_phase" "$workflow_status")
|
|
166
165
|
|
|
167
|
-
|
|
168
|
-
|
|
166
|
+
if [ -z "$completed_phase" ]; then
|
|
167
|
+
log_debug "No completed phase inferred from current_phase=${current_phase}."
|
|
168
|
+
exit 0
|
|
169
|
+
fi
|
|
169
170
|
|
|
170
|
-
if
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
171
|
+
# Dedup guard — skip if we already checkpointed this phase
|
|
172
|
+
local saved_last
|
|
173
|
+
saved_last=$(get_saved_last_phase)
|
|
174
|
+
if [ "$completed_phase" = "$saved_last" ]; then
|
|
175
|
+
log_debug "Phase ${completed_phase} already checkpointed. Skipping."
|
|
176
|
+
exit 0
|
|
175
177
|
fi
|
|
176
178
|
|
|
177
|
-
|
|
179
|
+
local description="Auto-checkpoint after ${completed_phase} phase"
|
|
180
|
+
local http_code
|
|
181
|
+
http_code=$(create_checkpoint "$workflow_id" "$completed_phase" "$description")
|
|
182
|
+
|
|
183
|
+
case "$http_code" in
|
|
184
|
+
201|200)
|
|
185
|
+
save_last_phase "$completed_phase"
|
|
186
|
+
log_info "Checkpoint registered: workflow=${workflow_id}, phase=${completed_phase}"
|
|
187
|
+
;;
|
|
188
|
+
409)
|
|
189
|
+
save_last_phase "$completed_phase"
|
|
190
|
+
log_info "Checkpoint already exists (409): phase=${completed_phase}"
|
|
191
|
+
;;
|
|
192
|
+
"")
|
|
193
|
+
log_warn "API unreachable. Checkpoint skipped for phase=${completed_phase}."
|
|
194
|
+
;;
|
|
195
|
+
*)
|
|
196
|
+
log_warn "Unexpected HTTP ${http_code} creating checkpoint for phase=${completed_phase}."
|
|
197
|
+
;;
|
|
198
|
+
esac
|
|
199
|
+
|
|
178
200
|
exit 0
|
|
179
201
|
}
|
|
180
202
|
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# prompt-orchestrator.sh — ADR-013 Phase 5 Hook (JSON Structured Output)
|
|
3
|
+
# Trigger: UserPromptSubmit
|
|
4
|
+
# Purpose: On every user prompt, inject orchestrator context.
|
|
5
|
+
# If no workflow active, remind about workflow requirement.
|
|
6
|
+
# If workflow active, inject current state.
|
|
7
|
+
#
|
|
8
|
+
# Output: JSON with additionalContext (never blocks prompts)
|
|
9
|
+
|
|
10
|
+
set -euo pipefail
|
|
11
|
+
|
|
12
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
13
|
+
source "$SCRIPT_DIR/orch-helpers.sh"
|
|
14
|
+
|
|
15
|
+
orch_log "PROMPT-ORCH: UserPromptSubmit triggered"
|
|
16
|
+
|
|
17
|
+
# Find active workflow
|
|
18
|
+
WORKFLOW_ID=$(orch_get_active_workflow 2>/dev/null) || WORKFLOW_ID=""
|
|
19
|
+
|
|
20
|
+
if [ -z "$WORKFLOW_ID" ]; then
|
|
21
|
+
# No workflow — inject reminder (lightweight, no API calls)
|
|
22
|
+
orch_log "PROMPT-ORCH: No active workflow, injecting reminder"
|
|
23
|
+
echo '{"hookSpecificOutput":{"hookEventName":"UserPromptSubmit","additionalContext":"[ORCHESTRATOR] No active workflow. If this request involves creating, modifying, or fixing code, you must start a workflow first (detectWorkflow → startWorkflow). The workflow-guard hook will block writes to src/ without a workflow."}}'
|
|
24
|
+
exit 0
|
|
25
|
+
fi
|
|
26
|
+
|
|
27
|
+
# Active workflow — inject state
|
|
28
|
+
NEXT_ACTION=$(orch_get_next_action "$WORKFLOW_ID" 2>/dev/null) || NEXT_ACTION=""
|
|
29
|
+
HAS_ACTION=$(orch_json_field "$NEXT_ACTION" "hasAction")
|
|
30
|
+
AGENT=$(orch_json_field "$NEXT_ACTION" "pendingAction.agent")
|
|
31
|
+
PA_STATUS=$(orch_json_field "$NEXT_ACTION" "pendingAction.status")
|
|
32
|
+
|
|
33
|
+
if [ "$HAS_ACTION" = "true" ]; then
|
|
34
|
+
CONTEXT="[ORCHESTRATOR] Active workflow: ${WORKFLOW_ID}. Next: invoke '${AGENT}' (${PA_STATUS})."
|
|
35
|
+
else
|
|
36
|
+
CONTEXT="[ORCHESTRATOR] Active workflow: ${WORKFLOW_ID}. No pending actions."
|
|
37
|
+
fi
|
|
38
|
+
|
|
39
|
+
orch_log "PROMPT-ORCH: workflow=$WORKFLOW_ID hasAction=$HAS_ACTION"
|
|
40
|
+
echo "{\"hookSpecificOutput\":{\"hookEventName\":\"UserPromptSubmit\",\"additionalContext\":$(echo "$CONTEXT" | node -e "let d='';process.stdin.on('data',c=>d+=c);process.stdin.on('end',()=>console.log(JSON.stringify(d)))" 2>/dev/null)}}"
|
|
41
|
+
exit 0
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# session-orchestrator.sh — ADR-013 Phase 5 Hook (JSON Structured Output)
|
|
3
|
+
# Trigger: SessionStart
|
|
4
|
+
# Purpose: On session start, check for active workflow and inject context.
|
|
5
|
+
# Helps the LLM resume work from where it left off.
|
|
6
|
+
#
|
|
7
|
+
# Output: JSON with additionalContext containing workflow state
|
|
8
|
+
|
|
9
|
+
set -euo pipefail
|
|
10
|
+
|
|
11
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
12
|
+
source "$SCRIPT_DIR/orch-helpers.sh"
|
|
13
|
+
|
|
14
|
+
orch_log "SESSION-ORCH: SessionStart hook triggered"
|
|
15
|
+
|
|
16
|
+
# Find active workflow
|
|
17
|
+
WORKFLOW_ID=$(orch_get_active_workflow 2>/dev/null) || WORKFLOW_ID=""
|
|
18
|
+
|
|
19
|
+
if [ -z "$WORKFLOW_ID" ]; then
|
|
20
|
+
orch_log "SESSION-ORCH: No active workflow"
|
|
21
|
+
echo '{"hookSpecificOutput":{"hookEventName":"SessionStart","additionalContext":"[ORCHESTRATOR] No active workflow. For feature requests, bug fixes, or refactoring, start with:\n1. mcp__orchestrator-tools__detectWorkflow\n2. mcp__orchestrator-tools__startWorkflow\n3. Follow the nextStep returned\n\nDirect implementation is blocked by the workflow-guard hook."}}'
|
|
22
|
+
exit 0
|
|
23
|
+
fi
|
|
24
|
+
|
|
25
|
+
# Get workflow details
|
|
26
|
+
TOKEN=$(orch_get_token 2>/dev/null) || TOKEN=""
|
|
27
|
+
if [ -z "$TOKEN" ]; then
|
|
28
|
+
echo "{\"hookSpecificOutput\":{\"hookEventName\":\"SessionStart\",\"additionalContext\":\"[ORCHESTRATOR] Active workflow: ${WORKFLOW_ID} (could not fetch details — auth failed).\"}}"
|
|
29
|
+
exit 0
|
|
30
|
+
fi
|
|
31
|
+
|
|
32
|
+
STATUS_RESP=$(curl -sf --max-time 5 "${API_URL}/api/v1/workflows/${WORKFLOW_ID}/status" \
|
|
33
|
+
-H "Authorization: Bearer $TOKEN" \
|
|
34
|
+
-H "X-Project-ID: $PROJECT_ID" 2>/dev/null) || STATUS_RESP=""
|
|
35
|
+
|
|
36
|
+
PHASE=$(orch_json_field "$STATUS_RESP" "currentPhase")
|
|
37
|
+
STATUS=$(orch_json_field "$STATUS_RESP" "status")
|
|
38
|
+
WF_TYPE=$(orch_json_field "$STATUS_RESP" "type")
|
|
39
|
+
|
|
40
|
+
# Get next action
|
|
41
|
+
NEXT_ACTION=$(orch_get_next_action "$WORKFLOW_ID" 2>/dev/null) || NEXT_ACTION=""
|
|
42
|
+
HAS_ACTION=$(orch_json_field "$NEXT_ACTION" "hasAction")
|
|
43
|
+
AGENT=$(orch_json_field "$NEXT_ACTION" "pendingAction.agent")
|
|
44
|
+
PA_STATUS=$(orch_json_field "$NEXT_ACTION" "pendingAction.status")
|
|
45
|
+
|
|
46
|
+
CONTEXT="[ORCHESTRATOR] Active workflow: ${WORKFLOW_ID}\nType: ${WF_TYPE}\nPhase: ${PHASE}\nStatus: ${STATUS}"
|
|
47
|
+
|
|
48
|
+
if [ "$HAS_ACTION" = "true" ]; then
|
|
49
|
+
CONTEXT="${CONTEXT}\nNext action: invoke '${AGENT}' (${PA_STATUS})"
|
|
50
|
+
fi
|
|
51
|
+
|
|
52
|
+
orch_log "SESSION-ORCH: Injecting workflow context (wf=$WORKFLOW_ID phase=$PHASE)"
|
|
53
|
+
echo "{\"hookSpecificOutput\":{\"hookEventName\":\"SessionStart\",\"additionalContext\":$(echo "$CONTEXT" | node -e "let d='';process.stdin.on('data',c=>d+=c);process.stdin.on('end',()=>console.log(JSON.stringify(d)))" 2>/dev/null)}}"
|
|
54
|
+
exit 0
|