claude-flow-novice 2.14.13 → 2.14.15

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 (74) hide show
  1. package/.claude/commands/CFN_LOOP_TASK_MODE.md +7 -51
  2. package/.claude/commands/cfn-loop-cli.md +50 -125
  3. package/.claude/skills/cfn-agent-selector/SKILL.md +2 -2
  4. package/.claude/skills/cfn-agent-selector/select-agents.sh +0 -45
  5. package/.claude/skills/cfn-loop-orchestration/helpers/context-injection.sh +6 -69
  6. package/.claude/skills/cfn-loop-orchestration/orchestrate.sh +0 -17
  7. package/README.md +2 -2
  8. package/claude-assets/agents/cfn-dev-team/CLAUDE.md +3 -3
  9. package/claude-assets/agents/cfn-dev-team/README.md +1 -1
  10. package/claude-assets/agents/cfn-dev-team/coordinators/cfn-v3-coordinator.md +2 -2
  11. package/claude-assets/agents/cfn-dev-team/developers/README.md +3 -3
  12. package/claude-assets/agents/cfn-dev-team/documentation/agent-type-guidelines.md +1 -1
  13. package/claude-assets/agents/cfn-dev-team/test-agent.md +2 -2
  14. package/claude-assets/commands/CFN_LOOP_TASK_MODE.md +7 -51
  15. package/claude-assets/commands/cfn-loop-cli.md +50 -125
  16. package/claude-assets/skills/cfn-agent-selector/SKILL.md +2 -2
  17. package/claude-assets/skills/cfn-agent-selector/select-agents.sh +0 -45
  18. package/claude-assets/skills/cfn-loop-orchestration/helpers/context-injection.sh +6 -69
  19. package/claude-assets/skills/cfn-loop-orchestration/orchestrate.sh +0 -17
  20. package/claude-assets/skills/cfn-multi-coordinator-planning/README.md +256 -0
  21. package/claude-assets/skills/cfn-multi-coordinator-planning/SKILL.md +62 -0
  22. package/claude-assets/skills/cfn-multi-coordinator-planning/map-dependencies-conflicts.sh +376 -0
  23. package/claude-assets/skills/cfn-multi-coordinator-planning/plan-coordinator-resources.sh +258 -0
  24. package/claude-assets/skills/cfn-multi-coordinator-planning/plan-multi-coordinator-work.sh +267 -0
  25. package/claude-assets/skills/cfn-multi-coordinator-planning/plan-risk-rollout.sh +350 -0
  26. package/claude-assets/skills/cfn-multi-coordinator-planning/test-multi-coordinator-planning.sh +338 -0
  27. package/claude-assets/skills/cfn-multi-coordinator-planning/validate-task-planning.sh +189 -0
  28. package/dist/agents/agent-loader.js +165 -146
  29. package/dist/agents/agent-loader.js.map +1 -1
  30. package/package.json +1 -1
  31. package/.claude/skills/cfn-agent-selector/SKILL.md.backup_before_replace +0 -91
  32. package/.claude/skills/cfn-loop-orchestration/helpers/validate-task-context.sh +0 -241
  33. package/.claude/skills/pre-edit-backup/backup.sh +0 -130
  34. package/.claude/skills/pre-edit-backup/cleanup.sh +0 -155
  35. package/.claude/skills/pre-edit-backup/restore.sh +0 -128
  36. package/.claude/skills/pre-edit-backup/revert-file.sh +0 -168
  37. package/claude-assets/agents/cfn-dev-team/CLAUDE.md.backup_before_replace +0 -1086
  38. package/claude-assets/agents/cfn-dev-team/README.md.backup_before_replace +0 -116
  39. package/claude-assets/agents/cfn-dev-team/coordinators/cfn-v3-coordinator.md.backup_before_replace +0 -451
  40. package/claude-assets/agents/cfn-dev-team/developers/README.md.backup_before_replace +0 -69
  41. package/claude-assets/agents/cfn-dev-team/documentation/agent-type-guidelines.md.backup_before_replace +0 -465
  42. package/claude-assets/agents/cfn-dev-team/test-agent.md.backup_before_replace +0 -141
  43. package/claude-assets/skills/CFN-LOOP-VALIDATION.md +0 -202
  44. package/claude-assets/skills/REDIS-COORDINATION.md +0 -187
  45. package/claude-assets/skills/SKILL.md +0 -229
  46. package/claude-assets/skills/agent-discovery/agents-registry.json +0 -484
  47. package/claude-assets/skills/agent-name-validation/README.md +0 -28
  48. package/claude-assets/skills/agent-name-validation/SKILL.md +0 -168
  49. package/claude-assets/skills/agent-name-validation/validate-agent-names.sh +0 -47
  50. package/claude-assets/skills/cfn-agent-selector/SKILL.md.backup_before_replace +0 -91
  51. package/claude-assets/skills/cfn-loop-orchestration/helpers/validate-task-context.sh +0 -241
  52. package/claude-assets/skills/consensus-calculator.js +0 -45
  53. package/claude-assets/skills/evidence-chain.sql +0 -66
  54. package/claude-assets/skills/hook-pipeline/bash-dependency-checker.sh +0 -89
  55. package/claude-assets/skills/hook-pipeline/bash-pipe-safety.sh +0 -69
  56. package/claude-assets/skills/hook-pipeline/enforce-lf.sh +0 -36
  57. package/claude-assets/skills/hook-pipeline/js-promise-safety.sh +0 -110
  58. package/claude-assets/skills/hook-pipeline/python-async-safety.py +0 -124
  59. package/claude-assets/skills/hook-pipeline/python-import-checker.py +0 -114
  60. package/claude-assets/skills/hook-pipeline/python-subprocess-safety.py +0 -77
  61. package/claude-assets/skills/hook-pipeline/rust-command-safety.sh +0 -38
  62. package/claude-assets/skills/hook-pipeline/rust-dependency-checker.sh +0 -50
  63. package/claude-assets/skills/hook-pipeline/rust-future-safety.sh +0 -50
  64. package/claude-assets/skills/pre-edit-backup/backup.sh +0 -130
  65. package/claude-assets/skills/pre-edit-backup/cleanup.sh +0 -155
  66. package/claude-assets/skills/pre-edit-backup/restore.sh +0 -128
  67. package/claude-assets/skills/pre-edit-backup/revert-file.sh +0 -168
  68. package/claude-assets/skills/run-all-skill-tests.sh +0 -124
  69. package/claude-assets/skills/seo-orchestration/SKILL.md +0 -292
  70. package/claude-assets/skills/seo-orchestration/orchestrate-seo.sh +0 -566
  71. package/claude-assets/skills/seo-orchestration/orchestrate-seo.sh.backup +0 -755
  72. package/claude-assets/skills/seo-orchestration/validate-consensus.sh +0 -270
  73. package/claude-assets/skills/team-provider-routing/execute-agent.sh +0 -76
  74. package/claude-assets/skills/test-execution-coordinator-pattern.md +0 -228
@@ -1,755 +0,0 @@
1
- #!/usr/bin/env bash
2
-
3
- ##############################################################################
4
- # SEO Pipeline Orchestration - 8-Step Content Creation
5
- # Version: 1.0.0
6
- #
7
- # Orchestrates the SEO content pipeline using modular steps, Redis coordination,
8
- # and validation loops.
9
- #
10
- # Usage:
11
- # ./orchestrate-seo.sh --task-id <id> \
12
- # --target-keyword <keyword> \
13
- # --content-type <type> \
14
- # --brand <brand> \
15
- # --audience <audience> \
16
- # [--mode <mvp|standard|enterprise>] \
17
- # [--max-iterations <n>] \
18
- # [--iteration <n>]
19
- ##############################################################################
20
-
21
- set -euo pipefail
22
-
23
- # Determine script directory
24
- SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
25
- PROJECT_ROOT="$(cd "$SCRIPT_DIR/../../.." && pwd)"
26
- REDIS_COORD_SKILL="$PROJECT_ROOT/.claude/skills/cfn-redis-coordination"
27
-
28
- # Configuration
29
- TASK_ID=""
30
- TARGET_KEYWORD=""
31
- CONTENT_TYPE=""
32
- BRAND=""
33
- AUDIENCE=""
34
- MODE="standard"
35
- MAX_ITERATIONS=3
36
- ITERATION=1
37
- TARGET_LOCATION=""
38
- WORD_COUNT_TARGET=""
39
-
40
- # Mode-specific thresholds
41
- declare -A VALIDATOR_GATE=(
42
- [mvp]=0.70
43
- [standard]=0.75
44
- [enterprise]=0.80
45
- )
46
-
47
- declare -A CONSENSUS_THRESHOLD=(
48
- [mvp]=0.90
49
- [standard]=0.95
50
- [enterprise]=0.98
51
- )
52
-
53
- # Execution tracking
54
- START_TIME=$(date +%s)
55
- CURRENT_STEP=0
56
- VALIDATION_CONSENSUS=0.0
57
- FINAL_ARTICLE_PATH=""
58
- ITERATIONS_COMPLETED=0
59
-
60
- ##############################################################################
61
- # Argument Parsing
62
- ##############################################################################
63
- while [[ $# -gt 0 ]]; do
64
- case $1 in
65
- --task-id)
66
- TASK_ID="$2"
67
- shift 2
68
- ;;
69
- --target-keyword)
70
- TARGET_KEYWORD="$2"
71
- shift 2
72
- ;;
73
- --content-type)
74
- CONTENT_TYPE="$2"
75
- if [[ ! "$CONTENT_TYPE" =~ ^(blog|landing|product|local)$ ]]; then
76
- echo "Invalid content type. Must be: blog, landing, product, or local"
77
- exit 1
78
- fi
79
- shift 2
80
- ;;
81
- --brand)
82
- BRAND="$2"
83
- shift 2
84
- ;;
85
- --audience)
86
- AUDIENCE="$2"
87
- shift 2
88
- ;;
89
- --mode)
90
- MODE="$2"
91
- if [[ ! "$MODE" =~ ^(mvp|standard|enterprise)$ ]]; then
92
- echo "Invalid mode. Must be: mvp, standard, or enterprise"
93
- exit 1
94
- fi
95
- shift 2
96
- ;;
97
- --max-iterations)
98
- MAX_ITERATIONS="$2"
99
- if [[ ! "$MAX_ITERATIONS" =~ ^[1-9][0-9]*$ ]]; then
100
- echo "Max iterations must be a positive integer"
101
- exit 1
102
- fi
103
- shift 2
104
- ;;
105
- --iteration)
106
- ITERATION="$2"
107
- shift 2
108
- ;;
109
- --target-location)
110
- TARGET_LOCATION="$2"
111
- shift 2
112
- ;;
113
- --word-count)
114
- WORD_COUNT_TARGET="$2"
115
- shift 2
116
- ;;
117
- *)
118
- echo "Error: Unknown option: '$1'"
119
- echo ""
120
- echo "Usage: $0 [OPTIONS]"
121
- echo ""
122
- echo "Required options:"
123
- echo " --task-id <id> Unique task identifier"
124
- echo " --target-keyword <keyword> Primary SEO keyword"
125
- echo " --content-type <type> Content type: blog, landing, product, local"
126
- echo " --brand <brand> Brand name"
127
- echo " --audience <audience> Target audience"
128
- echo ""
129
- echo "Optional options:"
130
- echo " --mode <mode> SEO mode: mvp, standard, enterprise (default: standard)"
131
- echo " --max-iterations <n> Maximum validation iterations (default: 3)"
132
- echo " --iteration <n> Current iteration (default: 1)"
133
- echo " --target-location <loc> Target location (for local SEO)"
134
- echo " --word-count <n> Target word count (default: auto)"
135
- exit 1
136
- ;;
137
- esac
138
- done
139
-
140
- # Validation
141
- if [ -z "$TASK_ID" ] || [ -z "$TARGET_KEYWORD" ] || [ -z "$CONTENT_TYPE" ] || [ -z "$BRAND" ] || [ -z "$AUDIENCE" ]; then
142
- echo "Error: Required parameters missing"
143
- echo "Usage: $0 --task-id <id> --target-keyword <keyword> --content-type <type> --brand <brand> --audience <audience>"
144
- exit 1
145
- fi
146
-
147
- # Get thresholds for mode
148
- VALIDATOR_THRESHOLD=${VALIDATOR_GATE[$MODE]}
149
- CONSENSUS=${CONSENSUS_THRESHOLD[$MODE]}
150
-
151
- # Set word count target based on content type if not provided
152
- if [ -z "$WORD_COUNT_TARGET" ]; then
153
- case "$CONTENT_TYPE" in
154
- blog)
155
- WORD_COUNT_TARGET="1500-2000"
156
- ;;
157
- landing)
158
- WORD_COUNT_TARGET="800-1200"
159
- ;;
160
- product)
161
- WORD_COUNT_TARGET="400-800"
162
- ;;
163
- local)
164
- WORD_COUNT_TARGET="600-1000"
165
- ;;
166
- esac
167
- fi
168
-
169
- echo "=============================================="
170
- echo "SEO Pipeline Orchestration v1.0.0"
171
- echo "=============================================="
172
- echo "Task ID: $TASK_ID"
173
- echo "Content Type: $CONTENT_TYPE"
174
- echo "Target Keyword: $TARGET_KEYWORD"
175
- echo "Brand: $BRAND"
176
- echo "Audience: $AUDIENCE"
177
- echo "Mode: $MODE"
178
- echo "Word Count Target: $WORD_COUNT_TARGET"
179
- echo "Validator Threshold: $VALIDATOR_THRESHOLD"
180
- echo "Consensus Threshold: $CONSENSUS"
181
- echo "Max Iterations: $MAX_ITERATIONS"
182
- echo "=============================================="
183
- echo ""
184
-
185
- ##############################################################################
186
- # Helper Functions
187
- ##############################################################################
188
-
189
- function log_step() {
190
- local step_num="$1"
191
- local step_name="$2"
192
- local message="$3"
193
-
194
- echo "[$step_name] $message"
195
- redis-cli RPUSH "seo:task:${TASK_ID}:logs" "[$(date -Iseconds)] [Step $step_num] $message" >/dev/null
196
- }
197
-
198
- function store_context() {
199
- local task_id="$1"
200
-
201
- log_step 0 "Init" "Storing SEO task context in Redis"
202
-
203
- # Store task context using Redis HSET
204
- redis-cli HSET "seo:task:${task_id}:context" \
205
- target_keyword "$TARGET_KEYWORD" \
206
- content_type "$CONTENT_TYPE" \
207
- brand "$BRAND" \
208
- audience "$AUDIENCE" \
209
- mode "$MODE" \
210
- word_count_target "$WORD_COUNT_TARGET" \
211
- target_location "$TARGET_LOCATION" \
212
- max_iterations "$MAX_ITERATIONS" >/dev/null
213
-
214
- # Store status
215
- redis-cli HSET "seo:task:${task_id}:status" \
216
- current_step "0" \
217
- iteration "$ITERATION" \
218
- status "initializing" >/dev/null
219
-
220
- log_step 0 "Init" "Context stored in Redis"
221
- }
222
-
223
- function update_status() {
224
- local step_num="$1"
225
- local status="$2"
226
-
227
- redis-cli HSET "seo:task:${TASK_ID}:status" \
228
- current_step "$step_num" \
229
- status "$status" \
230
- last_updated "$(date -Iseconds)" >/dev/null
231
- }
232
-
233
- function spawn_agent() {
234
- local agent_type="$1"
235
- local step_num="$2"
236
- local context="$3"
237
- local timeout="${4:-300}" # Default 5 minute timeout
238
-
239
- local agent_id="${agent_type}-step${step_num}-iter${ITERATION}"
240
-
241
- log_step "$step_num" "$(get_step_name $step_num)" "Spawning agent: $agent_type (ID: $agent_id)"
242
-
243
- # Spawn agent via CLI
244
- npx claude-flow-novice agent "$agent_type" \
245
- --task-id "$TASK_ID" \
246
- --agent-id "$agent_id" \
247
- --iteration "$ITERATION" \
248
- --context "$context" &
249
-
250
- local agent_pid=$!
251
-
252
- # Store agent PID
253
- redis-cli HSET "seo:task:${TASK_ID}:agents" "$agent_id" "$agent_pid" >/dev/null
254
-
255
- log_step "$step_num" "$(get_step_name $step_num)" "Agent spawned (PID: $agent_pid)"
256
-
257
- # Wait for agent completion
258
- if redis-cli blpop "swarm:${TASK_ID}:${agent_id}:done" "$timeout" >/dev/null 2>&1; then
259
- log_step "$step_num" "$(get_step_name $step_num)" "Agent completed: $agent_id"
260
- return 0
261
- else
262
- log_step "$step_num" "$(get_step_name $step_num)" "Warning: Agent timeout: $agent_id"
263
- return 1
264
- fi
265
- }
266
-
267
- function get_step_name() {
268
- local step="$1"
269
- case "$step" in
270
- 1) echo "Keyword Research" ;;
271
- 2) echo "Competitor Analysis" ;;
272
- 3) echo "Content Outline" ;;
273
- 4) echo "Research" ;;
274
- 5) echo "Content Writing" ;;
275
- 6) echo "SEO Optimization" ;;
276
- 7) echo "Validation" ;;
277
- 8) echo "Publishing" ;;
278
- *) echo "Unknown" ;;
279
- esac
280
- }
281
-
282
- function should_run_step() {
283
- local step="$1"
284
-
285
- # All content types run certain core steps
286
- case "$CONTENT_TYPE" in
287
- blog)
288
- # Blog runs all 8 steps
289
- return 0
290
- ;;
291
- landing)
292
- # Landing page skips competitor analysis (step 2), minimal research (step 4)
293
- if [[ "$step" == "2" || "$step" == "4" ]]; then
294
- return 1
295
- fi
296
- return 0
297
- ;;
298
- product)
299
- # Product page skips competitor analysis (2), outline (3), research (4)
300
- if [[ "$step" == "2" || "$step" == "3" || "$step" == "4" ]]; then
301
- return 1
302
- fi
303
- return 0
304
- ;;
305
- local)
306
- # Local content skips competitor analysis (2)
307
- if [[ "$step" == "2" ]]; then
308
- return 1
309
- fi
310
- return 0
311
- ;;
312
- esac
313
-
314
- return 0
315
- }
316
-
317
- function store_step_output() {
318
- local step_num="$1"
319
- local output="$2"
320
-
321
- redis-cli HSET "seo:task:${TASK_ID}:step:${step_num}:output" \
322
- iteration "$ITERATION" \
323
- timestamp "$(date -Iseconds)" \
324
- output "$output" >/dev/null
325
- }
326
-
327
- ##############################################################################
328
- # Pipeline Steps
329
- ##############################################################################
330
-
331
- function step1_keyword_research() {
332
- if ! should_run_step "1"; then
333
- log_step 1 "Keyword Research" "Skipped for content type: $CONTENT_TYPE"
334
- return 0
335
- fi
336
-
337
- update_status 1 "running"
338
- CURRENT_STEP=1
339
-
340
- local context="Task: Keyword research for '$TARGET_KEYWORD' | Content Type: $CONTENT_TYPE | Brand: $BRAND | Audience: $AUDIENCE | Output: content/seo-data/keyword-research-${TASK_ID}.json"
341
-
342
- if spawn_agent "seo-analytics-specialist" 1 "$context" 600; then
343
- # Retrieve output from agent
344
- local keyword_data=$(redis-cli HGET "seo:task:${TASK_ID}:agents:seo-analytics-specialist-step1-iter${ITERATION}" "output" 2>/dev/null || echo "")
345
- store_step_output 1 "$keyword_data"
346
- log_step 1 "Keyword Research" "Completed successfully"
347
- return 0
348
- else
349
- log_step 1 "Keyword Research" "Failed or timed out"
350
- return 1
351
- fi
352
- }
353
-
354
- function step2_competitor_analysis() {
355
- if ! should_run_step "2"; then
356
- log_step 2 "Competitor Analysis" "Skipped for content type: $CONTENT_TYPE"
357
- return 0
358
- fi
359
-
360
- update_status 2 "running"
361
- CURRENT_STEP=2
362
-
363
- local context="Task: Analyze top 3 competitors for keyword '$TARGET_KEYWORD' | Keyword Data: content/seo-data/keyword-research-${TASK_ID}.json | Output: content/seo-data/competitor-analysis-${TASK_ID}.md"
364
-
365
- if spawn_agent "competitive-seo-analyst" 2 "$context" 600; then
366
- local competitor_data=$(redis-cli HGET "seo:task:${TASK_ID}:agents:competitive-seo-analyst-step2-iter${ITERATION}" "output" 2>/dev/null || echo "")
367
- store_step_output 2 "$competitor_data"
368
- log_step 2 "Competitor Analysis" "Completed successfully"
369
- return 0
370
- else
371
- log_step 2 "Competitor Analysis" "Failed or timed out"
372
- return 1
373
- fi
374
- }
375
-
376
- function step3_content_outline() {
377
- if ! should_run_step "3"; then
378
- log_step 3 "Content Outline" "Skipped for content type: $CONTENT_TYPE"
379
- return 0
380
- fi
381
-
382
- update_status 3 "running"
383
- CURRENT_STEP=3
384
-
385
- local context="Task: Create SEO-optimized outline for '$TARGET_KEYWORD' | Keyword Data: content/seo-data/keyword-research-${TASK_ID}.json | Competitor Data: content/seo-data/competitor-analysis-${TASK_ID}.md | Brand: $BRAND | Word Count: $WORD_COUNT_TARGET | Output: content/outlines/outline-${TASK_ID}.md"
386
-
387
- if spawn_agent "content-seo-strategist" 3 "$context" 600; then
388
- local outline_data=$(redis-cli HGET "seo:task:${TASK_ID}:agents:content-seo-strategist-step3-iter${ITERATION}" "output" 2>/dev/null || echo "")
389
- store_step_output 3 "$outline_data"
390
- log_step 3 "Content Outline" "Completed successfully"
391
- return 0
392
- else
393
- log_step 3 "Content Outline" "Failed or timed out"
394
- return 1
395
- fi
396
- }
397
-
398
- function step4_research() {
399
- if ! should_run_step "4"; then
400
- log_step 4 "Research" "Skipped for content type: $CONTENT_TYPE"
401
- return 0
402
- fi
403
-
404
- update_status 4 "running"
405
- CURRENT_STEP=4
406
-
407
- log_step 4 "Research" "Performing research via Perplexity API"
408
-
409
- # Check OpenRouter API key
410
- if [ -z "${OPENROUTER_API_KEY:-}" ]; then
411
- log_step 4 "Research" "Warning: OPENROUTER_API_KEY not set, skipping research"
412
- return 0
413
- fi
414
-
415
- # Extract research questions from outline
416
- local outline_path="content/outlines/outline-${TASK_ID}.md"
417
- local research_query="Research comprehensive information about: $TARGET_KEYWORD. Focus on: latest statistics, expert quotes, credible sources, and supporting data."
418
-
419
- # Call Perplexity API via OpenRouter
420
- local research_response=$(curl -s https://openrouter.ai/api/v1/chat/completions \
421
- -H "Authorization: Bearer ${OPENROUTER_API_KEY}" \
422
- -H "Content-Type: application/json" \
423
- -d "{
424
- \"model\": \"perplexity/pplx-70b-online\",
425
- \"messages\": [{\"role\": \"user\", \"content\": \"$research_query\"}]
426
- }" 2>/dev/null || echo '{"error": "API call failed"}')
427
-
428
- # Store research output
429
- store_step_output 4 "$research_response"
430
-
431
- # Save research to file
432
- echo "$research_response" > "content/research/research-${TASK_ID}.json"
433
-
434
- log_step 4 "Research" "Completed successfully"
435
- return 0
436
- }
437
-
438
- function step5_content_writing() {
439
- if ! should_run_step "5"; then
440
- log_step 5 "Content Writing" "Skipped for content type: $CONTENT_TYPE"
441
- return 0
442
- fi
443
-
444
- update_status 5 "running"
445
- CURRENT_STEP=5
446
-
447
- # Build context with feedback if this is an iteration
448
- local feedback=""
449
- if [ "$ITERATION" -gt 1 ]; then
450
- feedback=$(redis-cli HGET "seo:task:${TASK_ID}:validation:feedback" "iteration$((ITERATION - 1))" 2>/dev/null || echo "")
451
- fi
452
-
453
- local context="Task: Write $CONTENT_TYPE content for '$TARGET_KEYWORD' | Outline: content/outlines/outline-${TASK_ID}.md | Research: content/research/research-${TASK_ID}.json | Brand: $BRAND | Audience: $AUDIENCE | Word Count: $WORD_COUNT_TARGET | Tone: Conversational, human, natural | Output: content/drafts/draft-${TASK_ID}.md"
454
-
455
- if [ -n "$feedback" ]; then
456
- context="$context | Feedback from iteration $((ITERATION - 1)): $feedback"
457
- fi
458
-
459
- if spawn_agent "content-seo-strategist" 5 "$context" 900; then
460
- local draft_data=$(redis-cli HGET "seo:task:${TASK_ID}:agents:content-seo-strategist-step5-iter${ITERATION}" "output" 2>/dev/null || echo "")
461
- store_step_output 5 "$draft_data"
462
- log_step 5 "Content Writing" "Completed successfully"
463
- return 0
464
- else
465
- log_step 5 "Content Writing" "Failed or timed out"
466
- return 1
467
- fi
468
- }
469
-
470
- function step6_seo_optimization() {
471
- if ! should_run_step "6"; then
472
- log_step 6 "SEO Optimization" "Skipped for content type: $CONTENT_TYPE"
473
- return 0
474
- fi
475
-
476
- update_status 6 "running"
477
- CURRENT_STEP=6
478
-
479
- local context="Task: SEO optimize content | Draft: content/drafts/draft-${TASK_ID}.md | Primary Keyword: $TARGET_KEYWORD | Content Type: $CONTENT_TYPE | Target URL: /blog/$TARGET_KEYWORD | Tasks: Meta title (50-60 chars), Meta description (150-160 chars), Header optimization, Internal linking (3-5 links), Image alt text, Schema preparation | Output: content/optimized/optimized-${TASK_ID}.md"
480
-
481
- # Use technical-seo-specialist as primary agent
482
- if spawn_agent "technical-seo-specialist" 6 "$context" 600; then
483
- local optimized_data=$(redis-cli HGET "seo:task:${TASK_ID}:agents:technical-seo-specialist-step6-iter${ITERATION}" "output" 2>/dev/null || echo "")
484
- store_step_output 6 "$optimized_data"
485
- log_step 6 "SEO Optimization" "Completed successfully"
486
- return 0
487
- else
488
- log_step 6 "SEO Optimization" "Failed or timed out"
489
- return 1
490
- fi
491
- }
492
-
493
- function step7_validation() {
494
- if ! should_run_step "7"; then
495
- log_step 7 "Validation" "Skipped for content type: $CONTENT_TYPE"
496
- return 0
497
- fi
498
-
499
- update_status 7 "running"
500
- CURRENT_STEP=7
501
-
502
- log_step 7 "Validation" "Spawning 3 validators in parallel"
503
-
504
- local article_path="content/optimized/optimized-${TASK_ID}.md"
505
-
506
- # Spawn validators in parallel
507
- local validator_context_humanizer="Task: Validate article for natural, human-like writing | Article: $article_path | Iteration: $ITERATION | Check for: AI language patterns, conversational tone, personal examples, varied sentence structure | Output: Confidence score (0.0-1.0), Issues found, Recommended rewrites"
508
-
509
- local validator_context_branding="Task: Validate article alignment with $BRAND brand | Article: $article_path | Brand: $BRAND | Iteration: $ITERATION | Check for: Brand voice consistency, value proposition, tone alignment, messaging | Output: Confidence score (0.0-1.0), Brand issues, Recommended adjustments"
510
-
511
- local validator_context_audience="Task: Validate article fit for target audience | Article: $article_path | Audience: $AUDIENCE | Iteration: $ITERATION | Check for: Audience resonance, complexity level, relatable examples, clear value | Output: Confidence score (0.0-1.0), Audience fit issues, Suggested improvements"
512
-
513
- # Spawn all validators in background
514
- (spawn_agent "humanizer-validator" 7 "$validator_context_humanizer" 300) &
515
- local pid_humanizer=$!
516
-
517
- (spawn_agent "branding-validator" 7 "$validator_context_branding" 300) &
518
- local pid_branding=$!
519
-
520
- (spawn_agent "audience-validator" 7 "$validator_context_audience" 300) &
521
- local pid_audience=$!
522
-
523
- # Wait for all validators
524
- wait "$pid_humanizer" "$pid_branding" "$pid_audience" 2>/dev/null || true
525
-
526
- log_step 7 "Validation" "All validators completed"
527
-
528
- # Collect confidence scores
529
- local humanizer_score=$(redis-cli HGET "swarm:${TASK_ID}:humanizer-validator-step7-iter${ITERATION}:confidence" "score" 2>/dev/null || echo "0.0")
530
- local branding_score=$(redis-cli HGET "swarm:${TASK_ID}:branding-validator-step7-iter${ITERATION}:confidence" "score" 2>/dev/null || echo "0.0")
531
- local audience_score=$(redis-cli HGET "swarm:${TASK_ID}:audience-validator-step7-iter${ITERATION}:confidence" "score" 2>/dev/null || echo "0.0")
532
-
533
- # Store validator scores
534
- redis-cli HSET "seo:task:${TASK_ID}:validation:scores" \
535
- "iteration${ITERATION}_humanizer" "$humanizer_score" \
536
- "iteration${ITERATION}_branding" "$branding_score" \
537
- "iteration${ITERATION}_audience" "$audience_score" >/dev/null
538
-
539
- # Calculate consensus (average)
540
- VALIDATION_CONSENSUS=$(echo "scale=2; ($humanizer_score + $branding_score + $audience_score) / 3" | bc)
541
-
542
- log_step 7 "Validation" "Humanizer: $humanizer_score | Branding: $branding_score | Audience: $audience_score | Consensus: $VALIDATION_CONSENSUS"
543
-
544
- # Check individual gate thresholds
545
- local gate_pass=true
546
- if (( $(echo "$humanizer_score < $VALIDATOR_THRESHOLD" | bc -l) )); then
547
- log_step 7 "Validation" "Humanizer validator failed gate ($humanizer_score < $VALIDATOR_THRESHOLD)"
548
- gate_pass=false
549
- fi
550
- if (( $(echo "$branding_score < $VALIDATOR_THRESHOLD" | bc -l) )); then
551
- log_step 7 "Validation" "Branding validator failed gate ($branding_score < $VALIDATOR_THRESHOLD)"
552
- gate_pass=false
553
- fi
554
- if (( $(echo "$audience_score < $VALIDATOR_THRESHOLD" | bc -l) )); then
555
- log_step 7 "Validation" "Audience validator failed gate ($audience_score < $VALIDATOR_THRESHOLD)"
556
- gate_pass=false
557
- fi
558
-
559
- # Check consensus threshold
560
- if [[ "$gate_pass" == "true" ]] && (( $(echo "$VALIDATION_CONSENSUS >= $CONSENSUS" | bc -l) )); then
561
- log_step 7 "Validation" "Consensus passed ($VALIDATION_CONSENSUS >= $CONSENSUS)"
562
- return 0
563
- else
564
- log_step 7 "Validation" "Consensus failed ($VALIDATION_CONSENSUS < $CONSENSUS) or gate failed"
565
-
566
- # Collect feedback from validators
567
- local feedback=$(redis-cli HGET "seo:task:${TASK_ID}:validation:feedback" "iteration${ITERATION}" 2>/dev/null || echo "See validator outputs for specific feedback")
568
-
569
- # Store feedback for next iteration
570
- redis-cli HSET "seo:task:${TASK_ID}:validation:feedback" \
571
- "iteration${ITERATION}" "$feedback" >/dev/null
572
-
573
- return 1
574
- fi
575
- }
576
-
577
- function step8_publishing() {
578
- if ! should_run_step "8"; then
579
- log_step 8 "Publishing" "Skipped for content type: $CONTENT_TYPE"
580
- return 0
581
- fi
582
-
583
- update_status 8 "running"
584
- CURRENT_STEP=8
585
-
586
- local context="Task: Add schema markup and prepare for publishing | Article: content/optimized/optimized-${TASK_ID}.md | URL: https://${BRAND}.com/blog/${TARGET_KEYWORD} | Author: ${BRAND} Team | Published: $(date +%Y-%m-%d) | Tasks: Add Article schema (JSON-LD), Add BreadcrumbList schema, Add Organization schema, Validate with Google Rich Results Test, Final formatting | Output: content/published/published-${TASK_ID}.md"
587
-
588
- if spawn_agent "schema-markup-engineer" 8 "$context" 600; then
589
- local published_data=$(redis-cli HGET "seo:task:${TASK_ID}:agents:schema-markup-engineer-step8-iter${ITERATION}" "output" 2>/dev/null || echo "")
590
- store_step_output 8 "$published_data"
591
-
592
- # Set final article path
593
- FINAL_ARTICLE_PATH="content/published/published-${TASK_ID}.md"
594
-
595
- log_step 8 "Publishing" "Completed successfully - Article ready at $FINAL_ARTICLE_PATH"
596
- return 0
597
- else
598
- log_step 8 "Publishing" "Failed or timed out"
599
- return 1
600
- fi
601
- }
602
-
603
- ##############################################################################
604
- # Main Pipeline Execution
605
- ##############################################################################
606
-
607
- function run_pipeline() {
608
- log_step 0 "Pipeline" "Starting SEO pipeline for iteration $ITERATION"
609
-
610
- # Step 1: Keyword Research
611
- if ! step1_keyword_research; then
612
- log_step 0 "Pipeline" "Step 1 failed, retrying once"
613
- sleep 2
614
- if ! step1_keyword_research; then
615
- log_step 0 "Pipeline" "Step 1 failed after retry, aborting"
616
- return 1
617
- fi
618
- fi
619
-
620
- # Step 2: Competitor Analysis
621
- if ! step2_competitor_analysis; then
622
- log_step 0 "Pipeline" "Step 2 failed, retrying once"
623
- sleep 2
624
- if ! step2_competitor_analysis; then
625
- log_step 0 "Pipeline" "Step 2 failed after retry, continuing with degraded data"
626
- # Non-critical step, continue
627
- fi
628
- fi
629
-
630
- # Step 3: Content Outline
631
- if ! step3_content_outline; then
632
- log_step 0 "Pipeline" "Step 3 failed, retrying once"
633
- sleep 2
634
- if ! step3_content_outline; then
635
- log_step 0 "Pipeline" "Step 3 failed after retry, aborting"
636
- return 1
637
- fi
638
- fi
639
-
640
- # Step 4: Research
641
- if ! step4_research; then
642
- log_step 0 "Pipeline" "Step 4 failed, continuing without external research"
643
- # Non-critical step, continue
644
- fi
645
-
646
- # Step 5: Content Writing
647
- if ! step5_content_writing; then
648
- log_step 0 "Pipeline" "Step 5 failed, retrying once"
649
- sleep 2
650
- if ! step5_content_writing; then
651
- log_step 0 "Pipeline" "Step 5 failed after retry, aborting"
652
- return 1
653
- fi
654
- fi
655
-
656
- # Step 6: SEO Optimization
657
- if ! step6_seo_optimization; then
658
- log_step 0 "Pipeline" "Step 6 failed, retrying once"
659
- sleep 2
660
- if ! step6_seo_optimization; then
661
- log_step 0 "Pipeline" "Step 6 failed after retry, aborting"
662
- return 1
663
- fi
664
- fi
665
-
666
- # Step 7: Validation (with iteration loop)
667
- if ! step7_validation; then
668
- ITERATIONS_COMPLETED=$ITERATION
669
-
670
- if [ "$ITERATION" -ge "$MAX_ITERATIONS" ]; then
671
- log_step 7 "Validation" "Max iterations ($MAX_ITERATIONS) reached, proceeding to publishing"
672
- # Proceed to step 8 even if validation consensus not met
673
- else
674
- log_step 7 "Validation" "Validation failed, starting iteration $((ITERATION + 1))"
675
-
676
- # Recursive call with incremented iteration
677
- ITERATION=$((ITERATION + 1))
678
- run_pipeline
679
- return $?
680
- fi
681
- fi
682
-
683
- # Step 8: Publishing
684
- if ! step8_publishing; then
685
- log_step 0 "Pipeline" "Step 8 failed, retrying once"
686
- sleep 2
687
- if ! step8_publishing; then
688
- log_step 0 "Pipeline" "Step 8 failed after retry, aborting"
689
- return 1
690
- fi
691
- fi
692
-
693
- log_step 0 "Pipeline" "SEO pipeline completed successfully"
694
- return 0
695
- }
696
-
697
- function output_result() {
698
- local status="$1"
699
- local end_time=$(date +%s)
700
- local execution_time=$((end_time - START_TIME))
701
-
702
- echo ""
703
- echo "=============================================="
704
- echo "SEO Pipeline Execution Complete"
705
- echo "=============================================="
706
- echo "Status: $status"
707
- echo "Content Type: $CONTENT_TYPE"
708
- echo "Target Keyword: $TARGET_KEYWORD"
709
- echo "Iterations: $ITERATIONS_COMPLETED"
710
- echo "Final Validation Consensus: $VALIDATION_CONSENSUS"
711
- echo "Final Article Path: $FINAL_ARTICLE_PATH"
712
- echo "Execution Time: ${execution_time}s"
713
- echo "=============================================="
714
-
715
- # Output structured JSON result
716
- cat <<EOF
717
- {
718
- "status": "$status",
719
- "content_type": "$CONTENT_TYPE",
720
- "target_keyword": "$TARGET_KEYWORD",
721
- "brand": "$BRAND",
722
- "iterations_completed": $ITERATIONS_COMPLETED,
723
- "validation_consensus": $VALIDATION_CONSENSUS,
724
- "final_article_path": "$FINAL_ARTICLE_PATH",
725
- "execution_time_seconds": $execution_time,
726
- "task_id": "$TASK_ID"
727
- }
728
- EOF
729
-
730
- # Store final result in Redis
731
- redis-cli HSET "seo:task:${TASK_ID}:result" \
732
- status "$status" \
733
- iterations "$ITERATIONS_COMPLETED" \
734
- consensus "$VALIDATION_CONSENSUS" \
735
- article_path "$FINAL_ARTICLE_PATH" \
736
- execution_time "$execution_time" >/dev/null
737
- }
738
-
739
- ##############################################################################
740
- # Main Execution
741
- ##############################################################################
742
-
743
- # Store context in Redis
744
- store_context "$TASK_ID"
745
-
746
- # Run pipeline
747
- if run_pipeline; then
748
- ITERATIONS_COMPLETED=$ITERATION
749
- output_result "success"
750
- exit 0
751
- else
752
- ITERATIONS_COMPLETED=$ITERATION
753
- output_result "failed"
754
- exit 1
755
- fi