@orchestrator-claude/definitions 3.12.0 → 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.
@@ -1,7 +1,6 @@
1
1
  #!/bin/bash
2
- # Track Agent Invocation Hook (v2 — REST API)
3
- # Defense-in-depth: agents self-report via MCP, this hook is a safety net.
4
- # Registers agent invocations via REST API (PostgreSQL).
2
+ # Track Agent Invocation Hook
3
+ # Registers agent invocations in orchestrator-index.json
5
4
  #
6
5
  # Usage (called by Claude Code hooks):
7
6
  # track-agent-invocation.sh start (reads stdin JSON)
@@ -14,67 +13,14 @@ set -e
14
13
 
15
14
  SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
16
15
  PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
16
+ INDEX_FILE="$PROJECT_ROOT/.orchestrator/orchestrator-index.json"
17
17
  STATE_DIR="$PROJECT_ROOT/.orchestrator/.state"
18
18
  INVOCATION_FILE="$STATE_DIR/current-invocation"
19
19
  DEBUG_LOG="$STATE_DIR/hook-debug.log"
20
20
 
21
- # API Configuration
22
- API_URL="${ORCHESTRATOR_API_URL:-http://localhost:3001}"
23
- AUTH_EMAIL="${ORCHESTRATOR_AUTH_EMAIL:-admin@orchestrator.local}"
24
- AUTH_PASSWORD="${ORCHESTRATOR_AUTH_PASSWORD:-admin123}"
25
- PROJECT_ID="${ORCHESTRATOR_PROJECT_ID:-d001d65d-25f5-4d13-b1dc-d006873e949c}"
26
-
27
21
  # Ensure state directory exists
28
22
  mkdir -p "$STATE_DIR"
29
23
 
30
- # Log rotation: max 1MB, keep 3 rotated copies
31
- MAX_LOG_SIZE=1048576 # 1MB in bytes
32
- if [ -f "$DEBUG_LOG" ]; then
33
- LOG_SIZE=$(stat -f%z "$DEBUG_LOG" 2>/dev/null || stat -c%s "$DEBUG_LOG" 2>/dev/null || echo 0)
34
- if [ "$LOG_SIZE" -gt "$MAX_LOG_SIZE" ]; then
35
- [ -f "${DEBUG_LOG}.2" ] && mv "${DEBUG_LOG}.2" "${DEBUG_LOG}.3"
36
- [ -f "${DEBUG_LOG}.1" ] && mv "${DEBUG_LOG}.1" "${DEBUG_LOG}.2"
37
- mv "$DEBUG_LOG" "${DEBUG_LOG}.1"
38
- fi
39
- fi
40
-
41
- log() {
42
- echo "[$(date -u +%Y-%m-%dT%H:%M:%SZ)] $*" >> "$DEBUG_LOG"
43
- }
44
-
45
- # Auth function: login and cache JWT
46
- get_token() {
47
- local cached="$STATE_DIR/jwt-token"
48
- if [ -f "$cached" ]; then
49
- local age=$(( $(date +%s) - $(stat -c%Y "$cached" 2>/dev/null || stat -f%m "$cached" 2>/dev/null || echo 0) ))
50
- if [ "$age" -lt 3500 ]; then # Refresh if > ~58 min
51
- cat "$cached"
52
- return
53
- fi
54
- fi
55
- local resp
56
- resp=$(curl -s -f -X POST "${API_URL}/api/v1/auth/login" \
57
- -H "Content-Type: application/json" \
58
- -d "{\"email\":\"${AUTH_EMAIL}\",\"password\":\"${AUTH_PASSWORD}\"}" 2>/dev/null) || return 1
59
- local token
60
- token=$(echo "$resp" | node -e "let d='';process.stdin.on('data',c=>d+=c);process.stdin.on('end',()=>{try{const j=JSON.parse(d);console.log(j.data?.accessToken||j.accessToken||j.token||'')}catch{console.log('')}})" 2>/dev/null)
61
- if [ -n "$token" ]; then
62
- echo "$token" > "$cached"
63
- echo "$token"
64
- fi
65
- }
66
-
67
- # Get active workflow ID from REST API
68
- get_workflow_id() {
69
- local token
70
- token=$(get_token) || return 1
71
- local resp
72
- resp=$(curl -s -f "${API_URL}/api/v1/workflows?status=in_progress" \
73
- -H "Authorization: Bearer $token" \
74
- -H "X-Project-ID: $PROJECT_ID" 2>/dev/null) || return 1
75
- echo "$resp" | node -e "let d='';process.stdin.on('data',c=>d+=c);process.stdin.on('end',()=>{try{const j=JSON.parse(d);const wfs=j.data||j;const wf=Array.isArray(wfs)?wfs[0]:wfs;console.log(wf?.id||'')}catch{console.log('')}})" 2>/dev/null
76
- }
77
-
78
24
  ACTION="${1:-}"
79
25
 
80
26
  # Read stdin into variable (Claude Code passes JSON via stdin)
@@ -88,6 +34,7 @@ case "$ACTION" in
88
34
  # Extract agent info from stdin JSON
89
35
  # Structure: { "tool_name": "Task", "tool_input": { "subagent_type": "...", ... } }
90
36
  if [ -n "$STDIN_DATA" ]; then
37
+ # Debug: log received data
91
38
  echo "[$(date -u +%Y-%m-%dT%H:%M:%SZ)] START stdin: $STDIN_DATA" >> "$DEBUG_LOG"
92
39
 
93
40
  AGENT_NAME=$(echo "$STDIN_DATA" | node -e "
@@ -96,6 +43,7 @@ case "$ACTION" in
96
43
  process.stdin.on('end', () => {
97
44
  try {
98
45
  const json = JSON.parse(data);
46
+ // Try different structures
99
47
  const type = json.tool_input?.subagent_type
100
48
  || json.subagent_type
101
49
  || json.tool_input?.type
@@ -128,6 +76,7 @@ case "$ACTION" in
128
76
  });
129
77
  ")
130
78
  elif [ -n "$CLAUDE_TOOL_INPUT" ]; then
79
+ # Fallback to environment variable
131
80
  echo "[$(date -u +%Y-%m-%dT%H:%M:%SZ)] START env: $CLAUDE_TOOL_INPUT" >> "$DEBUG_LOG"
132
81
 
133
82
  AGENT_NAME=$(echo "$CLAUDE_TOOL_INPUT" | node -e "
@@ -148,35 +97,124 @@ case "$ACTION" in
148
97
  PHASE="unknown"
149
98
  fi
150
99
 
151
- TOKEN=$(get_token) || { log "ERROR: Auth failed"; exit 0; }
152
- WORKFLOW_ID=$(get_workflow_id) || { log "SKIP: No active workflow"; exit 0; }
153
-
100
+ # Generate invocation ID
101
+ INVOCATION_ID="inv-$(date +%s)-$(head -c 4 /dev/urandom | xxd -p)"
154
102
  STARTED_AT=$(date -u +"%Y-%m-%dT%H:%M:%SZ")
155
- INVOCATION_ID=$(cat /proc/sys/kernel/random/uuid 2>/dev/null || uuidgen 2>/dev/null || python3 -c 'import uuid; print(uuid.uuid4())' 2>/dev/null || echo "inv-$(date +%s)-$(head -c 4 /dev/urandom | xxd -p)")
103
+
104
+ # Get workflow ID from index
105
+ WORKFLOW_ID=""
106
+ if [ -f "$INDEX_FILE" ]; then
107
+ WORKFLOW_ID=$(node -e "
108
+ const fs = require('fs');
109
+ try {
110
+ const idx = JSON.parse(fs.readFileSync('$INDEX_FILE', 'utf8'));
111
+ console.log(idx.activeWorkflow?.id || 'wf-standalone-' + Date.now());
112
+ } catch { console.log('wf-standalone-' + Date.now()); }
113
+ ")
114
+ fi
115
+
116
+ # Save invocation state
156
117
  echo "$INVOCATION_ID" > "$INVOCATION_FILE"
157
118
 
158
- # Register via REST API
159
- curl -s -f -X POST "${API_URL}/api/v1/invocations/start" \
160
- -H "Content-Type: application/json" \
161
- -H "Authorization: Bearer $TOKEN" \
162
- -H "X-Project-ID: $PROJECT_ID" \
163
- -d "{\"agentType\":\"${AGENT_NAME}\",\"workflowId\":\"${WORKFLOW_ID}\",\"phase\":\"${PHASE}\",\"startedAt\":\"${STARTED_AT}\"}" >> "$DEBUG_LOG" 2>&1 || true
119
+ # Update orchestrator-index.json
120
+ if [ -f "$INDEX_FILE" ]; then
121
+ node -e "
122
+ const fs = require('fs');
123
+ const indexPath = '$INDEX_FILE';
124
+ const idx = JSON.parse(fs.readFileSync(indexPath, 'utf8'));
125
+
126
+ if (!idx.agentInvocations) idx.agentInvocations = [];
127
+
128
+ idx.agentInvocations.push({
129
+ id: '$INVOCATION_ID',
130
+ agentName: '$AGENT_NAME',
131
+ phase: '$PHASE',
132
+ workflowId: '$WORKFLOW_ID',
133
+ startedAt: '$STARTED_AT',
134
+ completedAt: null,
135
+ status: 'running',
136
+ durationMs: 0
137
+ });
164
138
 
165
- log "START: agent=$AGENT_NAME phase=$PHASE workflow=$WORKFLOW_ID"
139
+ fs.writeFileSync(indexPath, JSON.stringify(idx, null, 2));
140
+ console.log(JSON.stringify({ invocationId: '$INVOCATION_ID', startedAt: '$STARTED_AT' }));
141
+ "
142
+ else
143
+ echo '{"invocationId": "'$INVOCATION_ID'", "startedAt": "'$STARTED_AT'", "warning": "No index file found"}'
144
+ fi
166
145
  ;;
167
146
 
168
147
  complete)
148
+ # Get invocation ID from state file
169
149
  INVOCATION_ID=""
170
150
  if [ -f "$INVOCATION_FILE" ]; then
171
151
  INVOCATION_ID=$(cat "$INVOCATION_FILE")
172
- rm -f "$INVOCATION_FILE"
173
152
  fi
174
153
 
154
+ if [ -z "$INVOCATION_ID" ]; then
155
+ echo '{"success": false, "error": "No invocation ID found"}'
156
+ exit 0 # Don't fail the hook
157
+ fi
158
+
159
+ # Debug log
175
160
  if [ -n "$STDIN_DATA" ]; then
176
161
  echo "[$(date -u +%Y-%m-%dT%H:%M:%SZ)] COMPLETE stdin: $STDIN_DATA" >> "$DEBUG_LOG"
177
162
  fi
178
163
 
179
- log "COMPLETE: invocation=$INVOCATION_ID (agent self-reports via MCP; hook is safety net)"
164
+ # Determine status - default to success
165
+ STATUS="success"
166
+ SUMMARY="Completed"
167
+
168
+ COMPLETED_AT=$(date -u +"%Y-%m-%dT%H:%M:%SZ")
169
+
170
+ # Update orchestrator-index.json
171
+ if [ -f "$INDEX_FILE" ]; then
172
+ node -e "
173
+ const fs = require('fs');
174
+ const indexPath = '$INDEX_FILE';
175
+ const idx = JSON.parse(fs.readFileSync(indexPath, 'utf8'));
176
+
177
+ const invocations = idx.agentInvocations || [];
178
+ const invIdx = invocations.findIndex(i => i.id === '$INVOCATION_ID');
179
+
180
+ if (invIdx === -1) {
181
+ console.log(JSON.stringify({ success: false, error: 'Invocation not found' }));
182
+ process.exit(0);
183
+ }
184
+
185
+ const inv = invocations[invIdx];
186
+ const startTime = new Date(inv.startedAt).getTime();
187
+ const endTime = new Date('$COMPLETED_AT').getTime();
188
+ const durationMs = endTime - startTime;
189
+
190
+ invocations[invIdx] = {
191
+ ...inv,
192
+ completedAt: '$COMPLETED_AT',
193
+ status: '$STATUS' === 'success' ? 'completed' : 'failed',
194
+ durationMs,
195
+ result: {
196
+ status: '$STATUS',
197
+ summary: '$SUMMARY'
198
+ }
199
+ };
200
+
201
+ idx.agentInvocations = invocations;
202
+
203
+ // Update statistics
204
+ if (idx.statistics) {
205
+ idx.statistics.totalInvocations = invocations.length;
206
+ idx.statistics.lastActivity = '$COMPLETED_AT';
207
+ }
208
+
209
+ fs.writeFileSync(indexPath, JSON.stringify(idx, null, 2));
210
+ console.log(JSON.stringify({ success: true, durationMs }));
211
+ "
212
+ else
213
+ echo '{"success": false, "error": "No index file found"}'
214
+ fi
215
+
216
+ # Clean up state file
217
+ rm -f "$INVOCATION_FILE"
180
218
  ;;
181
219
 
182
220
  *)
@@ -0,0 +1,79 @@
1
+ #!/bin/bash
2
+ # workflow-guard.sh — ADR-013 Phase 5 Hook (JSON Structured Output)
3
+ # Trigger: PreToolUse on Write|Edit
4
+ # Purpose: Block writes to src/ and tests/ when no active workflow exists.
5
+ #
6
+ # Output: JSON with permissionDecision (deny/allow) + additionalContext
7
+ # Exit 0 with JSON = structured decision
8
+
9
+ set -euo pipefail
10
+
11
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
12
+ source "$SCRIPT_DIR/orch-helpers.sh"
13
+
14
+ STDIN_DATA=$(orch_read_stdin)
15
+
16
+ # Extract file path (Claude Code wraps in tool_input)
17
+ FILE_PATH=$(orch_json_field "$STDIN_DATA" "tool_input.file_path")
18
+ [ -z "$FILE_PATH" ] && FILE_PATH=$(orch_json_field "$STDIN_DATA" "file_path")
19
+ [ -z "$FILE_PATH" ] && FILE_PATH=$(orch_json_field "$STDIN_DATA" "input.file_path")
20
+
21
+ orch_log "workflow-guard: file_path=$FILE_PATH"
22
+
23
+ # Explicit bypass via env var (for direct implementation without dogfooding)
24
+ if [ "${SKIP_WORKFLOW_GUARD:-}" = "true" ]; then
25
+ orch_log "workflow-guard: ALLOW (SKIP_WORKFLOW_GUARD=true)"
26
+ echo '{"hookSpecificOutput":{"hookEventName":"PreToolUse","permissionDecision":"allow","additionalContext":"Workflow guard bypassed via SKIP_WORKFLOW_GUARD=true."}}'
27
+ exit 0
28
+ fi
29
+
30
+ # Only guard src/ and tests/ paths (production code)
31
+ case "$FILE_PATH" in
32
+ */src/*|*/tests/*)
33
+ ;;
34
+ *)
35
+ orch_log "workflow-guard: ALLOW (non-guarded path)"
36
+ exit 0
37
+ ;;
38
+ esac
39
+
40
+ # Allow config and non-code files
41
+ case "$FILE_PATH" in
42
+ *.json|*.yml|*.yaml|*.md|*.env|*.env.*)
43
+ orch_log "workflow-guard: ALLOW (config/doc file)"
44
+ exit 0
45
+ ;;
46
+ esac
47
+
48
+ # Check for active workflow
49
+ WORKFLOW_ID=$(orch_get_active_workflow 2>/dev/null) || WORKFLOW_ID=""
50
+
51
+ if [ -n "$WORKFLOW_ID" ]; then
52
+ # Check if running inside a sub-agent (agent_id present) or main agent (absent)
53
+ AGENT_ID=$(orch_json_field "$STDIN_DATA" "agent_id")
54
+
55
+ if [ -n "$AGENT_ID" ]; then
56
+ # Sub-agent writing — ALLOW
57
+ AGENT_TYPE=$(orch_json_field "$STDIN_DATA" "agent_type")
58
+ orch_log "workflow-guard: ALLOW (sub-agent: ${AGENT_TYPE:-unknown}, workflow: $WORKFLOW_ID)"
59
+ echo "{\"hookSpecificOutput\":{\"hookEventName\":\"PreToolUse\",\"permissionDecision\":\"allow\",\"additionalContext\":\"Active workflow: ${WORKFLOW_ID}. Sub-agent ${AGENT_TYPE:-unknown} write allowed.\"}}"
60
+ exit 0
61
+ fi
62
+
63
+ # Main agent writing directly — check if SKIP_SUBAGENT_GUARD allows it
64
+ if [ "${SKIP_SUBAGENT_GUARD:-}" = "true" ]; then
65
+ orch_log "workflow-guard: ALLOW (SKIP_SUBAGENT_GUARD=true, workflow: $WORKFLOW_ID)"
66
+ echo "{\"hookSpecificOutput\":{\"hookEventName\":\"PreToolUse\",\"permissionDecision\":\"allow\",\"additionalContext\":\"Active workflow: ${WORKFLOW_ID}. Direct write allowed via SKIP_SUBAGENT_GUARD.\"}}"
67
+ exit 0
68
+ fi
69
+
70
+ # Main agent writing directly — DENY, must use sub-agent
71
+ orch_log "workflow-guard: DENY (main agent direct write, no sub-agent invocation)"
72
+ echo "{\"hookSpecificOutput\":{\"hookEventName\":\"PreToolUse\",\"permissionDecision\":\"deny\",\"permissionDecisionReason\":\"Workflow Guard: Direct code writes are blocked. You must invoke a sub-agent (e.g. implementer) to write code. The sub-agent will have write access.\",\"additionalContext\":\"Use the Agent tool to spawn an implementer sub-agent for code changes. The workflow-guard allows writes only from sub-agents (identified by agent_id in hook input).\"}}"
73
+ exit 0
74
+ fi
75
+
76
+ # No active workflow — DENY with structured instructions
77
+ orch_log "workflow-guard: DENY (no active workflow)"
78
+ echo '{"hookSpecificOutput":{"hookEventName":"PreToolUse","permissionDecision":"deny","permissionDecisionReason":"Workflow Guard: No active workflow. Direct implementation is not allowed.","additionalContext":"You MUST start a workflow before writing code:\n1. mcp__orchestrator-tools__detectWorkflow({ prompt: \"...\" })\n2. mcp__orchestrator-tools__startWorkflow({ workflowType: \"...\", prompt: \"...\" })\n3. Follow the nextStep returned by startWorkflow\n\nThe workflow-guard hook blocks all writes to src/ and tests/ without an active workflow."}}'
79
+ exit 0
package/manifest.json CHANGED
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "schema": "orchestrator-definitions/v1",
3
3
  "namespace": "orchestrator",
4
- "version": "3.12.0",
5
- "generatedAt": "2026-03-15T00:48:41.789Z",
4
+ "version": "3.12.2",
5
+ "generatedAt": "2026-03-15T23:15:56.132Z",
6
6
  "definitions": {
7
7
  "agents": [
8
8
  {
@@ -234,26 +234,34 @@
234
234
  ],
235
235
  "hooks": [
236
236
  {
237
- "slug": "post-agent-artifact-relay",
238
- "file": "hooks/post-agent-artifact-relay.sh",
237
+ "slug": "dangling-workflow-guard",
238
+ "file": "hooks/dangling-workflow-guard.sh",
239
239
  "version": "1.0.0",
240
- "checksum": "sha256:59988e41d1530dcc36e62f7fed0bac2a1857c126e09296b261df3589a7de7af1",
240
+ "checksum": "sha256:34b195e03357e1d264328d7345832845beae11d2846c8e22810e427b20c75a0c",
241
241
  "supersedes": null,
242
242
  "metadata": {}
243
243
  },
244
244
  {
245
- "slug": "post-artifact-generate",
246
- "file": "hooks/post-artifact-generate.sh",
245
+ "slug": "gate-guardian",
246
+ "file": "hooks/gate-guardian.sh",
247
247
  "version": "1.0.0",
248
- "checksum": "sha256:891d4be3bf636f482d93473de0e221215a76373f45d6c832f19128864045665b",
248
+ "checksum": "sha256:7a5add785c53b4040bfde3ba68af8d2f43f65ecc101b600793f6f47a3e411f15",
249
249
  "supersedes": null,
250
250
  "metadata": {}
251
251
  },
252
252
  {
253
- "slug": "post-implement-validate",
254
- "file": "hooks/post-implement-validate.sh",
253
+ "slug": "orch-helpers",
254
+ "file": "hooks/orch-helpers.sh",
255
255
  "version": "1.0.0",
256
- "checksum": "sha256:051012b51361c1e6954194273adfbf30d6d323e037468370b40962c7b654b389",
256
+ "checksum": "sha256:0038a622374b5c88b9c674a8fc49744a72752c390db3e45a00948e6676e42959",
257
+ "supersedes": null,
258
+ "metadata": {}
259
+ },
260
+ {
261
+ "slug": "ping-pong-enforcer",
262
+ "file": "hooks/ping-pong-enforcer.sh",
263
+ "version": "1.0.0",
264
+ "checksum": "sha256:d2a5a10ea253da2ead5e203d64690129a56f377ecabe7ea4d43cd9c99d4cad95",
257
265
  "supersedes": null,
258
266
  "metadata": {}
259
267
  },
@@ -261,23 +269,23 @@
261
269
  "slug": "post-phase-checkpoint",
262
270
  "file": "hooks/post-phase-checkpoint.sh",
263
271
  "version": "1.0.0",
264
- "checksum": "sha256:580da7b8c319cbc419d5002f59beca3b5f09163f1f84bb549ad0bbf7dac96821",
272
+ "checksum": "sha256:f75c815334e371bf508642b9591d94a548e1221c65ff7f34af9e430ec6e88722",
265
273
  "supersedes": null,
266
274
  "metadata": {}
267
275
  },
268
276
  {
269
- "slug": "pre-agent-invoke",
270
- "file": "hooks/pre-agent-invoke.sh",
277
+ "slug": "prompt-orchestrator",
278
+ "file": "hooks/prompt-orchestrator.sh",
271
279
  "version": "1.0.0",
272
- "checksum": "sha256:059c2fa044f9cd03fdc15aaee49281eadec4651415f00855ebe5782b44e114ed",
280
+ "checksum": "sha256:93835c7798185a9c8f8bf84a029c660b2bbe34801cd34c5be6b2b7a1f07a0b8b",
273
281
  "supersedes": null,
274
282
  "metadata": {}
275
283
  },
276
284
  {
277
- "slug": "pre-phase-advance",
278
- "file": "hooks/pre-phase-advance.sh",
285
+ "slug": "session-orchestrator",
286
+ "file": "hooks/session-orchestrator.sh",
279
287
  "version": "1.0.0",
280
- "checksum": "sha256:ac9d7e98111776f578c613619d875b9d853817448448c64eab3cfcb3f85ba321",
288
+ "checksum": "sha256:143024a68b8438a0724fd93dd9b6eb1688bcc89c1a846ae7f6c389361b469f65",
281
289
  "supersedes": null,
282
290
  "metadata": {}
283
291
  },
@@ -285,7 +293,15 @@
285
293
  "slug": "track-agent-invocation",
286
294
  "file": "hooks/track-agent-invocation.sh",
287
295
  "version": "1.0.0",
288
- "checksum": "sha256:c6e664831354b80b2eb1bae2dabfd13c6554fd8c258972e0b037bccb7dae3b0f",
296
+ "checksum": "sha256:6a9343b032dd72e391fc4c476af480ee3055a5a25ec60d3524b0b0d804a80c6d",
297
+ "supersedes": null,
298
+ "metadata": {}
299
+ },
300
+ {
301
+ "slug": "workflow-guard",
302
+ "file": "hooks/workflow-guard.sh",
303
+ "version": "1.0.0",
304
+ "checksum": "sha256:170a15396a61c537df4c8adc093d7ac36faab6e7de761ff8d283828c53e4a332",
289
305
  "supersedes": null,
290
306
  "metadata": {}
291
307
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@orchestrator-claude/definitions",
3
- "version": "3.12.0",
3
+ "version": "3.12.2",
4
4
  "description": "Built-in definitions (agents, skills, hooks, workflows, KB seeds) for the Orchestrator ecosystem",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -1,11 +0,0 @@
1
- #!/bin/bash
2
- # Post-Agent Artifact Relay Hook (DEPRECATED — ADR-012)
3
- #
4
- # With ADR-012 F1, agents store artifacts directly via MCP artifactStore.
5
- # This hook is no longer needed. Kept as documentation.
6
- #
7
- # Previous behavior: relayed artifacts from filesystem staging to MinIO.
8
- # Now: agents call mcp__orchestrator-extended__artifactStore directly.
9
-
10
- # No-op: agents handle artifact storage directly
11
- exit 0
@@ -1,39 +0,0 @@
1
- #!/bin/bash
2
- # Post-Artifact Generate Hook
3
- # Executado apos geracao de um artefato
4
- # Valida artefato, atualiza indice, cria checkpoint
5
-
6
- set -e
7
-
8
- SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
9
- PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
10
-
11
- # Recebe evento via stdin ou argumento
12
- if [ -n "$1" ]; then
13
- EVENT="$1"
14
- else
15
- EVENT=$(cat)
16
- fi
17
-
18
- # Verifica se temos o handler compilado
19
- HANDLER="$PROJECT_ROOT/dist/hook.js"
20
-
21
- if [ ! -f "$HANDLER" ]; then
22
- echo '{"success": false, "error": "Hook handler not compiled. Run npm run build first."}' >&2
23
- exit 1
24
- fi
25
-
26
- # Executa o handler TypeScript
27
- echo "$EVENT" | node "$HANDLER" post-artifact
28
-
29
- EXIT_CODE=$?
30
-
31
- # Log do resultado
32
- if [ $EXIT_CODE -eq 0 ]; then
33
- echo "[post-artifact-generate] Artifact processed successfully" >&2
34
- else
35
- echo "[post-artifact-generate] Warning: Artifact processing had issues" >&2
36
- fi
37
-
38
- # Este hook nao bloqueia, apenas avisa
39
- exit 0
@@ -1,102 +0,0 @@
1
- #!/bin/bash
2
- # Post-Implement Validation Hook (v2 — REST API)
3
- # Validates workflow consistency after IMPLEMENT phase.
4
- # Defense-in-depth: agents track progress via MCP, this validates externally.
5
- #
6
- # Exit codes:
7
- # 0 = Validation passed or skipped
8
- # 1 = Warning detected (TDD violation detected)
9
-
10
- set -e
11
-
12
- SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
13
- PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
14
- STATE_DIR="$PROJECT_ROOT/.orchestrator/.state"
15
-
16
- # API Configuration
17
- API_URL="${ORCHESTRATOR_API_URL:-http://localhost:3001}"
18
- AUTH_EMAIL="${ORCHESTRATOR_AUTH_EMAIL:-admin@orchestrator.local}"
19
- AUTH_PASSWORD="${ORCHESTRATOR_AUTH_PASSWORD:-admin123}"
20
- PROJECT_ID="${ORCHESTRATOR_PROJECT_ID:-d001d65d-25f5-4d13-b1dc-d006873e949c}"
21
-
22
- # Colors
23
- RED='\033[0;31m'
24
- YELLOW='\033[1;33m'
25
- GREEN='\033[0;32m'
26
- NC='\033[0m'
27
-
28
- log_info() { echo -e "${GREEN}[post-implement-validate]${NC} $1" >&2; }
29
- log_warn() { echo -e "${YELLOW}[post-implement-validate] WARNING:${NC} $1" >&2; }
30
-
31
- # Auth: get cached token
32
- get_token() {
33
- mkdir -p "$STATE_DIR"
34
- local cached="$STATE_DIR/jwt-token"
35
- if [ -f "$cached" ]; then
36
- local age=$(( $(date +%s) - $(stat -c%Y "$cached" 2>/dev/null || stat -f%m "$cached" 2>/dev/null || echo 0) ))
37
- if [ "$age" -lt 3500 ]; then
38
- cat "$cached"
39
- return
40
- fi
41
- fi
42
- local resp
43
- resp=$(curl -s -f -X POST "${API_URL}/api/v1/auth/login" \
44
- -H "Content-Type: application/json" \
45
- -d "{\"email\":\"${AUTH_EMAIL}\",\"password\":\"${AUTH_PASSWORD}\"}" 2>/dev/null) || return 1
46
- local token
47
- token=$(echo "$resp" | node -e "let d='';process.stdin.on('data',c=>d+=c);process.stdin.on('end',()=>{try{const j=JSON.parse(d);console.log(j.data?.accessToken||j.accessToken||j.token||'')}catch{console.log('')}})" 2>/dev/null)
48
- if [ -n "$token" ]; then
49
- echo "$token" > "$cached"
50
- echo "$token"
51
- fi
52
- }
53
-
54
- # Get workflow status from REST API
55
- TOKEN=$(get_token) || { exit 0; } # Can't auth → skip silently
56
-
57
- WORKFLOW_RESP=$(curl -s -f "${API_URL}/api/v1/workflows?status=in_progress" \
58
- -H "Authorization: Bearer $TOKEN" \
59
- -H "X-Project-ID: $PROJECT_ID" 2>/dev/null) || { exit 0; }
60
-
61
- # Extract workflow info
62
- WORKFLOW_INFO=$(echo "$WORKFLOW_RESP" | node -e "
63
- let d='';
64
- process.stdin.on('data',c=>d+=c);
65
- process.stdin.on('end',()=>{
66
- try {
67
- const j=JSON.parse(d);
68
- const wfs=j.data||j;
69
- const wf=Array.isArray(wfs)?wfs[0]:wfs;
70
- if(!wf){console.log('{}');return;}
71
- console.log(JSON.stringify({
72
- id:wf.id||'',
73
- phase:wf.currentPhase||wf.phase||'',
74
- status:wf.status||''
75
- }));
76
- }catch{console.log('{}')}
77
- });
78
- " 2>/dev/null)
79
-
80
- CURRENT_PHASE=$(echo "$WORKFLOW_INFO" | node -e "let d='';process.stdin.on('data',c=>d+=c);process.stdin.on('end',()=>{try{console.log(JSON.parse(d).phase||'unknown')}catch{console.log('unknown')}})" 2>/dev/null)
81
- STATUS=$(echo "$WORKFLOW_INFO" | node -e "let d='';process.stdin.on('data',c=>d+=c);process.stdin.on('end',()=>{try{console.log(JSON.parse(d).status||'unknown')}catch{console.log('unknown')}})" 2>/dev/null)
82
-
83
- # Count source and test files
84
- TS_FILES_COUNT=0
85
- if [ -d "$PROJECT_ROOT/src" ]; then
86
- TS_FILES_COUNT=$(find "$PROJECT_ROOT/src" -name "*.ts" 2>/dev/null | wc -l | tr -d ' ')
87
- fi
88
- TEST_FILES_COUNT=0
89
- if [ -d "$PROJECT_ROOT/tests" ]; then
90
- TEST_FILES_COUNT=$(find "$PROJECT_ROOT/tests" \( -name "*.test.ts" -o -name "*.spec.ts" \) 2>/dev/null | wc -l | tr -d ' ')
91
- fi
92
-
93
- log_info "Phase: $CURRENT_PHASE | Status: $STATUS | Src: $TS_FILES_COUNT | Tests: $TEST_FILES_COUNT"
94
-
95
- # TDD check: source files without tests
96
- if [ "$TS_FILES_COUNT" -gt 5 ] && [ "$TEST_FILES_COUNT" -eq 0 ]; then
97
- log_warn "Found $TS_FILES_COUNT source files but no test files. TDD may not have been followed."
98
- exit 1
99
- fi
100
-
101
- log_info "Validation passed."
102
- exit 0
@@ -1,34 +0,0 @@
1
- #!/bin/bash
2
- # Pre-Agent Invoke Hook
3
- # Executado antes de invocar um subagent
4
- # Valida contexto e injeta informacoes da KB
5
-
6
- set -e
7
-
8
- SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
9
- PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
10
-
11
- # Recebe evento via stdin ou argumento
12
- if [ -n "$1" ]; then
13
- EVENT="$1"
14
- else
15
- EVENT=$(cat)
16
- fi
17
-
18
- # Verifica se temos o handler compilado
19
- HANDLER="$PROJECT_ROOT/dist/hook.js"
20
-
21
- if [ ! -f "$HANDLER" ]; then
22
- echo '{"success": false, "error": "Hook handler not compiled. Run npm run build first."}' >&2
23
- exit 1
24
- fi
25
-
26
- # Executa o handler TypeScript
27
- echo "$EVENT" | node "$HANDLER" pre-agent-invoke
28
-
29
- EXIT_CODE=$?
30
-
31
- # Exit code determina se agente pode prosseguir
32
- # 0 = permitido
33
- # 1 = bloqueado
34
- exit $EXIT_CODE
@@ -1,40 +0,0 @@
1
- #!/bin/bash
2
- # Pre-Phase Advance Hook
3
- # Executado antes de avancar para proxima fase
4
- # Avalia gate e cria checkpoint
5
-
6
- set -e
7
-
8
- SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
9
- PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
10
-
11
- # Recebe evento via stdin ou argumento
12
- if [ -n "$1" ]; then
13
- EVENT="$1"
14
- else
15
- EVENT=$(cat)
16
- fi
17
-
18
- # Verifica se temos o handler compilado
19
- HANDLER="$PROJECT_ROOT/dist/hook.js"
20
-
21
- if [ ! -f "$HANDLER" ]; then
22
- echo '{"success": false, "error": "Hook handler not compiled. Run npm run build first."}' >&2
23
- exit 1
24
- fi
25
-
26
- # Executa o handler TypeScript
27
- echo "$EVENT" | node "$HANDLER" pre-phase-advance
28
-
29
- EXIT_CODE=$?
30
-
31
- # Exit code determina se fase pode avancar
32
- # 0 = gate passou, pode avancar
33
- # 1 = gate falhou, bloqueado
34
- if [ $EXIT_CODE -eq 0 ]; then
35
- echo "[pre-phase-advance] Gate passed, advancing phase" >&2
36
- else
37
- echo "[pre-phase-advance] Gate failed, phase advance blocked" >&2
38
- fi
39
-
40
- exit $EXIT_CODE