@aksp/opencrew 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (87) hide show
  1. package/CHANGELOG.md +19 -0
  2. package/LICENSE +24 -0
  3. package/README.md +118 -0
  4. package/bin/opencrew.js +8 -0
  5. package/package.json +57 -0
  6. package/src/cli.js +70 -0
  7. package/src/commands/init.js +97 -0
  8. package/src/commands/update.js +58 -0
  9. package/src/lib/fsx.js +55 -0
  10. package/src/lib/ides.js +120 -0
  11. package/src/lib/paths.js +8 -0
  12. package/src/lib/prompts.js +35 -0
  13. package/src/lib/ui.js +20 -0
  14. package/templates/.env.example +23 -0
  15. package/templates/.mcp.json +8 -0
  16. package/templates/AGENTS.md +105 -0
  17. package/templates/_opencrew/.opencrew-version +1 -0
  18. package/templates/_opencrew/_investigations/.gitkeep +0 -0
  19. package/templates/_opencrew/_memory/company.md +4 -0
  20. package/templates/_opencrew/_memory/preferences.md +9 -0
  21. package/templates/_opencrew/config/playwright.config.json +11 -0
  22. package/templates/_opencrew/core/architect.agent.yaml +110 -0
  23. package/templates/_opencrew/core/best-practices/_catalog.yaml +116 -0
  24. package/templates/_opencrew/core/best-practices/blog-post.md +151 -0
  25. package/templates/_opencrew/core/best-practices/blog-seo.md +146 -0
  26. package/templates/_opencrew/core/best-practices/copywriting.md +446 -0
  27. package/templates/_opencrew/core/best-practices/data-analysis.md +420 -0
  28. package/templates/_opencrew/core/best-practices/email-newsletter.md +136 -0
  29. package/templates/_opencrew/core/best-practices/email-sales.md +127 -0
  30. package/templates/_opencrew/core/best-practices/image-design.md +365 -0
  31. package/templates/_opencrew/core/best-practices/instagram-feed.md +252 -0
  32. package/templates/_opencrew/core/best-practices/instagram-reels.md +128 -0
  33. package/templates/_opencrew/core/best-practices/instagram-stories.md +123 -0
  34. package/templates/_opencrew/core/best-practices/linkedin-article.md +133 -0
  35. package/templates/_opencrew/core/best-practices/linkedin-post.md +138 -0
  36. package/templates/_opencrew/core/best-practices/researching.md +366 -0
  37. package/templates/_opencrew/core/best-practices/review.md +286 -0
  38. package/templates/_opencrew/core/best-practices/social-networks-publishing.md +311 -0
  39. package/templates/_opencrew/core/best-practices/strategist.md +361 -0
  40. package/templates/_opencrew/core/best-practices/technical-writing.md +382 -0
  41. package/templates/_opencrew/core/best-practices/twitter-post.md +122 -0
  42. package/templates/_opencrew/core/best-practices/twitter-thread.md +139 -0
  43. package/templates/_opencrew/core/best-practices/whatsapp-broadcast.md +124 -0
  44. package/templates/_opencrew/core/best-practices/youtube-script.md +139 -0
  45. package/templates/_opencrew/core/best-practices/youtube-shorts.md +129 -0
  46. package/templates/_opencrew/core/prompts/build.prompt.md +547 -0
  47. package/templates/_opencrew/core/prompts/design.prompt.md +469 -0
  48. package/templates/_opencrew/core/prompts/discovery.prompt.md +269 -0
  49. package/templates/_opencrew/core/prompts/sherlock-instagram.md +123 -0
  50. package/templates/_opencrew/core/prompts/sherlock-linkedin.md +73 -0
  51. package/templates/_opencrew/core/prompts/sherlock-shared.md +684 -0
  52. package/templates/_opencrew/core/prompts/sherlock-twitter.md +78 -0
  53. package/templates/_opencrew/core/prompts/sherlock-youtube.md +85 -0
  54. package/templates/_opencrew/core/runner.pipeline.md +611 -0
  55. package/templates/_opencrew/core/skills.engine.md +388 -0
  56. package/templates/_opencrew/logs/.gitkeep +0 -0
  57. package/templates/crews/.gitkeep +0 -0
  58. package/templates/gitignore +8 -0
  59. package/templates/skills/apify/SKILL.md +55 -0
  60. package/templates/skills/blotato/SKILL.md +63 -0
  61. package/templates/skills/canva/SKILL.md +60 -0
  62. package/templates/skills/image-ai-generator/SKILL.md +124 -0
  63. package/templates/skills/image-ai-generator/scripts/generate.py +175 -0
  64. package/templates/skills/image-creator/SKILL.md +155 -0
  65. package/templates/skills/image-fetcher/SKILL.md +91 -0
  66. package/templates/skills/instagram-publisher/SKILL.md +119 -0
  67. package/templates/skills/instagram-publisher/scripts/publish.js +165 -0
  68. package/templates/skills/opencrew-best-practice-creator/SKILL.md +192 -0
  69. package/templates/skills/opencrew-skill-creator/SKILL.md +420 -0
  70. package/templates/skills/opencrew-skill-creator/agents/analyzer.md +274 -0
  71. package/templates/skills/opencrew-skill-creator/agents/comparator.md +202 -0
  72. package/templates/skills/opencrew-skill-creator/agents/grader.md +223 -0
  73. package/templates/skills/opencrew-skill-creator/assets/eval_review.html +146 -0
  74. package/templates/skills/opencrew-skill-creator/eval-viewer/generate_review.py +471 -0
  75. package/templates/skills/opencrew-skill-creator/eval-viewer/viewer.html +1325 -0
  76. package/templates/skills/opencrew-skill-creator/references/schemas.md +430 -0
  77. package/templates/skills/opencrew-skill-creator/references/skill-format.md +235 -0
  78. package/templates/skills/opencrew-skill-creator/scripts/__init__.py +0 -0
  79. package/templates/skills/opencrew-skill-creator/scripts/aggregate_benchmark.py +401 -0
  80. package/templates/skills/opencrew-skill-creator/scripts/quick_validate.py +103 -0
  81. package/templates/skills/opencrew-skill-creator/scripts/run_eval.py +310 -0
  82. package/templates/skills/opencrew-skill-creator/scripts/utils.py +47 -0
  83. package/templates/skills/resend/SKILL.md +80 -0
  84. package/templates/skills/template-designer/SKILL.md +208 -0
  85. package/templates/skills/template-designer/base-templates/model-a.html +27 -0
  86. package/templates/skills/template-designer/base-templates/model-b.html +31 -0
  87. package/templates/skills/template-designer/base-templates/model-c.html +42 -0
@@ -0,0 +1,611 @@
1
+ # opencrew Pipeline Runner
2
+
3
+ > **SHARED FILE** — applies to ALL IDEs. Do not add IDE-specific logic here.
4
+ > For IDE-specific behavior: `templates/ide-templates/{ide}/` only.
5
+
6
+ You are the Pipeline Runner. Your job is to execute a crew's pipeline step by step.
7
+
8
+ ## Initialization
9
+
10
+ Before starting execution:
11
+
12
+ 1. You have already loaded:
13
+ - The crew's `crew.yaml` (passed to you by the opencrew skill)
14
+ - The crew's `crew-party.csv` (all agent personas)
15
+ - Company context from `_opencrew/_memory/company.md`
16
+ - Crew memory from `crews/{name}/_memory/memories.md`
17
+
18
+ 1b. **Memory format migration** — After loading `memories.md`, check whether it uses the new format by scanning for the `## Estilo de Escrita` section header:
19
+ ```bash
20
+ [ -f crews/{name}/_memory/memories.md ] && grep -q "## Estilo de Escrita" crews/{name}/_memory/memories.md && echo "NEW_FORMAT" || echo "OLD_FORMAT"
21
+ ```
22
+ - If `NEW_FORMAT` → proceed normally.
23
+ - If `OLD_FORMAT` (or file is empty / does not exist) → silently migrate before proceeding:
24
+ a. Write `crews/{name}/_memory/memories.md` with the new empty-sections format (do NOT attempt to salvage content from the old file — reset unconditionally):
25
+ ```markdown
26
+ # Crew Memory: {crew-name}
27
+
28
+ ## Estilo de Escrita
29
+
30
+ ## Design Visual
31
+
32
+ ## Estrutura de Conteúdo
33
+
34
+ ## Proibições Explícitas
35
+
36
+ ## Técnico (específico do crew)
37
+ ```
38
+ (Use the crew's display name for `{crew-name}`, and the crew code for `{name}` in file paths — they refer to the same crew.)
39
+ b. Check if `crews/{name}/_memory/runs.md` exists:
40
+ ```bash
41
+ test -f crews/{name}/_memory/runs.md && echo "EXISTS" || echo "MISSING"
42
+ ```
43
+ If `MISSING`, create it with:
44
+ ```markdown
45
+ # Run History: {crew-name}
46
+
47
+ | Data | Run ID | Tema | Output | Resultado |
48
+ |------|--------|------|--------|-----------|
49
+ ```
50
+ - Do NOT inform the user or pause execution for this migration — it is transparent.
51
+
52
+ 2. Read `crews/{name}/pipeline/pipeline.yaml` for the pipeline definition
53
+ 3. **Resolve skills**: Read `crew.yaml` → `skills` section. For each non-native skill (anything other than web_search, web_fetch):
54
+ a. Verify `skills/{skill}/SKILL.md` exists
55
+ - If missing → ask user: "Skill '{skill}' is not installed. Install now? (y/n)"
56
+ - If yes → read `_opencrew/core/skills.engine.md`, follow Operation 2 (Install)
57
+ - If no → **ERROR**: stop pipeline
58
+ b. Read SKILL.md, parse frontmatter for type
59
+ c. If type: mcp, verify MCP is configured in `.claude/settings.local.json`
60
+ - If missing → **ERROR**: "Skill '{skill}' MCP not configured. Reinstall the skill."
61
+ All skills must resolve successfully before the pipeline starts (fail fast).
62
+ 4. **Model tiers**: Individual steps declare their own `model_tier` in their frontmatter (`fast` or `powerful`), set by the Architect at crew creation time.
63
+ - If the file exists: read and note the tier values for reference.
64
+ - If the file doesn't exist: ignore silently — all steps default to `powerful` at dispatch.
65
+ 5. Inform the user that the crew is starting:
66
+ ```
67
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
68
+ 🚀 Running crew: {crew name}
69
+ 📋 Pipeline: {number of steps} steps
70
+ 🤖 Agents: {list agent names with icons}
71
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
72
+ ```
73
+ 5b. **Initialize run folder**: Generate a unique run ID for this execution:
74
+ - Format: `YYYY-MM-DD-HHmmss` using the current timestamp (e.g. `2026-03-03-143022`)
75
+ - Check if `crews/{name}/output/{run_id}/` already exists
76
+ - If it does (sub-second collision), append `-2`, `-3`, etc. until the folder does not exist
77
+ - Create the folder using Bash: `mkdir -p crews/{name}/output/{run_id}`
78
+ - Store `run_id` in working memory for this run — it will be used for ALL output paths
79
+ 6. **Initialize state.json**: Create `crews/{name}/state.json` from scratch (see below). State writes are always mandatory.
80
+ - **IMPORTANT**: You MUST write to `crews/{name}/state.json` before every step and after every handoff. This is non-negotiable. Never skip these writes.
81
+ - Create `state.json` from scratch:
82
+ a. Read `crews/{name}/crew-party.csv` — for each agent row (skip header), extract:
83
+ - `id`: take the `path` column, strip `./agents/` prefix and `.agent.md` suffix
84
+ (e.g. `./agents/researcher.agent.md` → `researcher`)
85
+ - `name`: use the `displayName` column
86
+ - `icon`: use the `icon` column
87
+ b. Assign desk positions by agent order (0-based index):
88
+ - `col = (index % 3) + 1`
89
+ - `row = floor(index / 3) + 1`
90
+ (index 0 → col:1 row:1, index 1 → col:2 row:1, index 2 → col:3 row:1, index 3 → col:1 row:2, etc.)
91
+ c. Read `crews/{name}/crew.yaml` — count items in `pipeline.steps` for `total`
92
+ d. Write `crews/{name}/state.json` with the Write tool:
93
+ ```json
94
+ {
95
+ "crew": "{crew code from crew.yaml}",
96
+ "status": "idle",
97
+ "step": { "current": 0, "total": {step count from c}, "label": "" },
98
+ "agents": [
99
+ {
100
+ "id": "{agent id}",
101
+ "name": "{agent displayName}",
102
+ "icon": "{agent icon}",
103
+ "status": "idle",
104
+ "desk": { "col": {col from b}, "row": {row from b} }
105
+ }
106
+ ],
107
+ "handoff": null,
108
+ "startedAt": null,
109
+ "updatedAt": "{ISO timestamp now}"
110
+ }
111
+ ```
112
+ Include one entry per agent, in crew-party.csv order.
113
+
114
+ ## Execution Rules
115
+
116
+ ### Agent Loading (for inline and subagent steps)
117
+
118
+ Before executing any step that references an agent:
119
+ 1. Read the agent's row from crew-party.csv for quick persona reference
120
+ 2. Read the FULL agent file from the crew's agents/ directory (path comes from crew-party.csv)
121
+ - The file uses YAML frontmatter for metadata and markdown body for depth
122
+ - The markdown body contains: Operational Framework, Output Examples, Anti-Patterns, Voice Guidance
123
+ - All agents are complete `.agent.md` files with full definitions — no overlay resolution needed
124
+ 3. When executing the step, the agent's full definition informs behavior:
125
+ - Follow the Operational Framework's process steps
126
+ - Use Output Examples as quality reference
127
+ - Avoid Anti-Patterns listed in the agent definition
128
+ - Apply Voice Guidance (vocabulary always/never use, tone rules)
129
+ 4. **Inject format context**: Check if the current step's frontmatter contains a `format:` field.
130
+ If present:
131
+ a. Read `_opencrew/core/best-practices/{format}.md` (e.g., `_opencrew/core/best-practices/instagram-feed.md`)
132
+ - If the file does not exist → **WARNING**: "Format '{format}' not found in _opencrew/core/best-practices/. Skipping format injection." Continue without format.
133
+ b. Parse the YAML frontmatter to extract the `name` field
134
+ c. Extract the Markdown body (everything after the YAML frontmatter closing `---`)
135
+ d. Append to the agent's context, before skill instructions:
136
+ ```
137
+ --- FORMAT: {name from frontmatter} ---
138
+
139
+ {format file markdown body}
140
+ ```
141
+ If the step has no `format:` field, skip this step entirely (backward compatible).
142
+ 5. **Inject skill context (Two-Tier)**:
143
+ a. Build a Tier 1 skill index from each declared skill's frontmatter `name` and `description` (~30 tokens per skill)
144
+ b. Append the index after format injection:
145
+ ```
146
+ --- AVAILABLE SKILLS ---
147
+ - {skill-id}: {description} (type: {type})
148
+ ```
149
+ c. If the step's frontmatter contains `skills_needed: [...]`, load Tier 2 (full SKILL.md body) for those skills immediately
150
+ d. Otherwise, Tier 2 is loaded on-demand when the agent invokes a skill during execution
151
+ e. See `_opencrew/core/skills.engine.md` Operation 6 for full details
152
+
153
+ The final agent context composition order is:
154
+ ```
155
+ Agent (.agent.md) → Platform Best Practices → Skill Index (Tier 1) → Skill Instructions (Tier 2, on-demand)
156
+ ```
157
+
158
+ ### Context Compression (Summary-Based Handoff)
159
+
160
+ To prevent linear token growth across multi-agent pipelines, apply context compression
161
+ when passing prior agents' outputs as context:
162
+
163
+ 1. **TL;DR extraction**: After each agent completes, check if its output contains a `## TL;DR` section.
164
+ If present, extract and store it separately as the agent's summary.
165
+ ```bash
166
+ grep -q "^## TL;DR" "{outputFile}" && echo "HAS_TLDR" || echo "NO_TLDR"
167
+ ```
168
+
169
+ 2. **Compressed context assembly**: When preparing context for Agent N:
170
+ - Include **TL;DR summaries** from Agents 1 through N-2 (all agents except the direct predecessor)
171
+ - Include the **full output** from Agent N-1 (the direct predecessor) — this ensures
172
+ the current agent has complete detail from its immediate dependency
173
+ - Full outputs from all agents remain saved in `output/{run_id}/` for reference
174
+
175
+ 3. **Context format**:
176
+ ```
177
+ --- PRIOR CONTEXT (Summaries) ---
178
+
179
+ ### {Agent 1 Name} — Summary
180
+ {TL;DR content from Agent 1}
181
+
182
+ ### {Agent 2 Name} — Summary
183
+ {TL;DR content from Agent 2}
184
+
185
+ --- PREVIOUS STEP (Full Output) ---
186
+
187
+ {Complete output from Agent N-1}
188
+ ```
189
+
190
+ 4. **Fallback**: If an agent's output does NOT contain a `## TL;DR` section,
191
+ use the first 500 characters of the output as an auto-summary.
192
+ Going forward, the Architect should ensure all agent definitions include
193
+ a TL;DR requirement in their output instructions.
194
+
195
+ 5. **Single-agent crews**: If the pipeline has only 1 step, this rule does not apply.
196
+
197
+ 6. **Backward compatibility**: If the crew was created before this feature,
198
+ the runner falls back to passing full outputs (current behavior) when no
199
+ TL;DR sections are found in any prior output.
200
+
201
+ ### Task-Based Agent Execution
202
+
203
+ When an agent's `.agent.md` frontmatter contains a `tasks:` field:
204
+
205
+ 1. **Load task list**: Read the `tasks:` array from the agent's frontmatter
206
+ - Each entry is a relative path to a task file (e.g., `tasks/analyze-source.md`)
207
+ - Tasks execute in the order listed
208
+
209
+ 2. **For each task in sequence**:
210
+ a. Read the task file from the agent's directory (e.g., `crews/{crew-name}/agents/{agent}/tasks/{task}.md`)
211
+ b. Construct the execution prompt:
212
+ - Agent persona + principles (from agent.md — fixed across all tasks)
213
+ - Task description and process (from task file)
214
+ - Task output format (from task file)
215
+ - Task quality criteria and veto conditions (from task file)
216
+ - Input: For the first task, use the step's input. For subsequent tasks, use the previous task's output.
217
+ c. Execute the task (inline or subagent, matching the step's execution mode)
218
+ d. Collect the task output
219
+ e. Check task veto conditions (same enforcement as step veto conditions below)
220
+
221
+ 3. **Final output**: The output of the LAST task in the chain becomes the step's output
222
+ - Apply the Output Path Transformation (Steps 1 and 2: run_id injection + version folder) to the `outputFile` path before saving — this applies regardless of whether the step runs as `execution: inline` or `execution: subagent`
223
+ - Save to the **transformed** outputFile path
224
+ - This is what the next step (or checkpoint) receives
225
+
226
+ 4. **Progress reporting**: For inline execution, announce each task:
227
+ ```
228
+ {icon} {Agent Name} — Task {N}/{total}: {task name}...
229
+ ```
230
+
231
+ 5. **Backward compatibility**: If the agent's frontmatter does NOT contain a `tasks:` field,
232
+ execute the agent monolithically as before (current behavior unchanged).
233
+
234
+ ### Output Path Transformation
235
+
236
+ Before saving any output file in a step, apply these rules to determine the final path:
237
+
238
+ #### Step 1 — Insert run_id
239
+
240
+ - If the path starts with `crews/{name}/output/`, insert `{run_id}/` immediately after `output/`
241
+ - Example: `crews/carousel/output/slides/draft.md` → `crews/carousel/output/2026-03-03-143022/slides/draft.md`
242
+ - Example: `crews/carousel/output/angles-brief.yaml` → `crews/carousel/output/2026-03-03-143022/angles-brief.yaml`
243
+ - If the path does NOT start with `crews/{name}/output/`, leave it unchanged
244
+
245
+ #### Step 2 — Insert version folder
246
+
247
+ Apply to every path that was transformed in Step 1:
248
+
249
+ 1. Determine the **output group** = the parent directory of the file (after Step 1 transformation)
250
+ - Example: `crews/carousel/output/2026-03-03-143022/slides/draft.md` → group is `crews/carousel/output/2026-03-03-143022/slides/`
251
+ - Example: `crews/carousel/output/2026-03-03-143022/angles-brief.yaml` → group is `crews/carousel/output/2026-03-03-143022/`
252
+
253
+ 2. Detect existing versions for this group using Bash:
254
+ ```bash
255
+ ls -1 crews/{name}/output/{run_id}/{relative-group}/ 2>/dev/null | grep -E '^v[0-9]+$' | sort -V | tail -1
256
+ ```
257
+ - If the command returns a version (e.g. `v2`) → use `v3`
258
+ (Always increment the highest version found, even if lower versions have gaps — e.g. if `v1` and `v3` exist, use `v4`)
259
+ - If the command returns nothing (no versions yet) → use `v1`
260
+ (`{relative-group}` is the portion of the group path after `crews/{name}/output/{run_id}/`, e.g. `slides/` or empty string for root-level files)
261
+
262
+ 3. Insert the version folder immediately before the filename:
263
+ - `crews/carousel/output/2026-03-03-143022/slides/draft.md` → `crews/carousel/output/2026-03-03-143022/slides/v1/draft.md`
264
+ - `crews/carousel/output/2026-03-03-143022/angles-brief.yaml` → `crews/carousel/output/2026-03-03-143022/v1/angles-brief.yaml`
265
+
266
+ 4. **Cache per group**: within a single step execution, once a version is determined for a group, reuse it for all subsequent files in that same group. Do not re-run the `ls` per file.
267
+ If the same file path is written twice within a step, both writes go to the same versioned path (the second write overwrites the first within that version).
268
+
269
+ Apply this transformation consistently for every write in this step.
270
+
271
+ ### For each pipeline step:
272
+
273
+ 0. **Update dashboard** — MANDATORY. Write `crews/{name}/state.json` using the Write tool. Always write — it is never wrong to update the dashboard. Use this content:
274
+ ```json
275
+ {
276
+ "crew": "{crew code from crew.yaml}",
277
+ "status": "running",
278
+ "step": {
279
+ "current": {1-based index of this step},
280
+ "total": {total steps in pipeline},
281
+ "label": "{step id or label}"
282
+ },
283
+ "agents": [
284
+ {
285
+ "id": "{agent id}",
286
+ "name": "{agent displayName}",
287
+ "icon": "{agent icon}",
288
+ "status": "{working if this is the current step's agent, done if already completed, idle otherwise}",
289
+ "desk": {preserve existing desk positions from state.json — do not change col/row}
290
+ }
291
+ ],
292
+ "handoff": {preserve existing handoff object, or null if this is the first step},
293
+ "startedAt": "{ISO timestamp — set on the first step only, then preserve from existing state.json on subsequent steps}",
294
+ "updatedAt": "{ISO timestamp now}"
295
+ }
296
+ ```
297
+
298
+ 1. **Pre-Step Input Validation** — MANDATORY. If the step's frontmatter declares an `inputFile`, validate that the input exists before executing the step. Run via Bash tool:
299
+ ```bash
300
+ test -s "{transformed inputFile path}" && echo "VALIDATION:PASS" || echo "VALIDATION:FAIL"
301
+ ```
302
+ - Apply the Output Path Transformation (Step 1: run_id injection) to the `inputFile` path before running the check.
303
+ - If the Bash output contains `VALIDATION:PASS` → proceed to execute the step.
304
+ - If the Bash output contains `VALIDATION:FAIL` → do NOT execute the step. Present to user:
305
+ ```
306
+ ⚠️ Input for {Agent Name} not found: {path}
307
+ The previous step may have failed to produce output.
308
+
309
+ 1. Skip step and continue
310
+ 2. Abort pipeline
311
+ ```
312
+ Wait for user choice before proceeding. No retry — if the input doesn't exist, re-executing this step won't create it. The problem is upstream.
313
+ - If the step does not declare an `inputFile` → skip this validation entirely.
314
+ - Checkpoint steps (`type: checkpoint`) are exempt — they receive input from the user, not from files.
315
+
316
+ 2. **Read the step file** completely: `crews/{name}/pipeline/steps/{step-file}.md`
317
+ 3. **Check execution mode** from the step's frontmatter:
318
+
319
+ #### If `execution: subagent`
320
+ - Inform user: `🔍 {Agent Name} is working in the background...`
321
+ - Read the step's `model_tier` frontmatter field (if present).
322
+ Valid values: `fast` or `powerful`. If absent or any other value: default to `powerful`.
323
+ - **Before building the subagent prompt**: Apply the Output Path Transformation (Step 1: run_id injection + Step 2: version folder) to all output paths referenced in the step file. Store the transformed path(s) in working memory — they will be used both in the prompt and in post-completion verification. Never pass raw paths from the step file to the subagent.
324
+ - Use the Task tool to dispatch the step as a subagent:
325
+ - If `model_tier: fast`: use the fastest/lightest model available in your current IDE.
326
+ - If `model_tier: powerful` or absent/invalid: use the default model (no model override needed)
327
+ - In the Task prompt, include:
328
+ - The full agent persona from the party CSV
329
+ - The full agent `.agent.md` content (persona, principles, voice guidance, anti-patterns)
330
+ - If the agent has tasks: include ALL task files in order with instructions to execute sequentially, piping output from each task to the next
331
+ - If the agent has no tasks: include the step instructions and operational framework as before
332
+ - The veto conditions from the step file (agent should self-check before completing)
333
+ - The company context
334
+ - The crew memory
335
+ - The **transformed** path to save output (e.g., `crews/{name}/output/2026-03-20-140736/slides/v1/draft.md`)
336
+ - Wait for the subagent to complete
337
+ - Inform user: `✓ {Agent Name} completed`
338
+ - Proceed to Post-Step Output Validation (below) before advancing.
339
+
340
+ #### If `execution: inline`
341
+ - Switch to the agent's persona (read from party CSV)
342
+ - Announce: `{icon} {Agent Name} is working...`
343
+ - Follow the step instructions
344
+ - Present output directly in the conversation
345
+ - Save output to the specified output file — apply the Output Path Transformation (Steps 1 and 2) to the path before writing. Do not write to the raw path from the step file.
346
+ - Proceed to Post-Step Output Validation (below) before advancing.
347
+
348
+ #### If `type: checkpoint`
349
+ - Present the checkpoint message to the user
350
+ - If the checkpoint requires a choice (numbered list), present options as a numbered list
351
+ - **Always include the file path** of any generated content the user needs to review. Example: "Review the content at `crews/{name}/output/{run_id}/v1/content.md` and let me know if it looks good."
352
+ - Wait for user input before proceeding
353
+ - Save the user's choice/response for the next step
354
+ - **If the step frontmatter contains `outputFile`**: after collecting the user's full response,
355
+ apply the Output Path Transformation **Step 1 only** (run_id injection — skip Step 2, version folder) to the `outputFile` path, then write the response to the transformed path using the Write tool before moving to the next step. Checkpoint files are user input captures, not versioned output — Step 2 does not apply here, regardless of the general "every write" rule in the Output Path Transformation section above.
356
+ Use this format:
357
+ ```
358
+ # Research Focus
359
+
360
+ **Topic:** {user's typed topic}
361
+ **Time Range:** {selected time range label, e.g., "Últimos 7 dias"}
362
+ **Date:** {today's date in YYYY-MM-DD format}
363
+ ```
364
+ This file is the `inputFile` for the researcher step that follows.
365
+
366
+ ### Post-Step Output Validation
367
+
368
+ After a step produces output (subagent or inline) and BEFORE Veto Condition Enforcement, the runner MUST validate that the declared output files exist and are non-empty. This is a binary, non-negotiable gate — the runner does NOT proceed on memory or assumption, only on bash output.
369
+
370
+ **If the step declares an `outputFile`** (single or multiple), run via Bash tool for EACH output file:
371
+
372
+ ```bash
373
+ test -s "{transformed outputFile path}" && echo "VALIDATION:PASS" || echo "VALIDATION:FAIL"
374
+ ```
375
+
376
+ Use the **stored transformed path** (after Output Path Transformation Steps 1 and 2), not the raw path from the step file.
377
+
378
+ **Rules:**
379
+ - If ALL output files return `VALIDATION:PASS` → proceed to Veto Condition Enforcement.
380
+ - If ANY output file returns `VALIDATION:FAIL`:
381
+ 1. **Retry once**: re-execute the entire step with the same input and context.
382
+ 2. After re-execution, run the validation again for all output files.
383
+ 3. If second attempt returns `VALIDATION:PASS` for all files → proceed normally.
384
+ 4. If second attempt still has ANY `VALIDATION:FAIL` → present to user:
385
+ ```
386
+ ⚠️ {Agent Name}'s output was not generated: {path}
387
+
388
+ 1. Retry step
389
+ 2. Skip step and continue
390
+ 3. Abort pipeline
391
+ ```
392
+ Wait for user choice before proceeding.
393
+ - If the step does not declare an `outputFile` (e.g., steps that only produce inline console output) → skip output validation.
394
+ - Checkpoint steps (`type: checkpoint`) are exempt — their output is the user's response, not a file.
395
+
396
+ **IMPORTANT**: Do NOT rely on reading the file with the Read tool to "verify" output. The Read tool returns content that can be misinterpreted. Use ONLY the bash `test -s` command — its output is binary and cannot be hallucinated.
397
+
398
+ ### Output Contract Validation
399
+
400
+ If the step's frontmatter declares an `output_contract:` field, apply structured validation
401
+ AFTER the basic file existence check passes:
402
+
403
+ 1. **Required sections check**: If `output_contract.required_sections` is defined,
404
+ verify each required section exists in the output file:
405
+ ```bash
406
+ grep -c "^## " "{transformed outputFile path}" | xargs -I {} test {} -ge {min_sections} && echo "SECTIONS:PASS" || echo "SECTIONS:FAIL"
407
+ ```
408
+
409
+ 2. **TL;DR check**: If the output contract requires a TL;DR section:
410
+ ```bash
411
+ grep -q "^## TL;DR" "{transformed outputFile path}" && echo "TLDR:PASS" || echo "TLDR:FAIL"
412
+ ```
413
+
414
+ 3. **If any check fails**:
415
+ - Present to user: "⚠️ Output from {Agent Name} is incomplete: {which checks failed}"
416
+ - Options as numbered list:
417
+ 1. Accept anyway and continue
418
+ 2. Retry step (re-execute the agent)
419
+ 3. Abort pipeline
420
+
421
+ 4. **If no `output_contract` is defined**, skip this validation entirely (backward compatible).
422
+
423
+ Example `output_contract` in step frontmatter:
424
+ ```yaml
425
+ output_contract:
426
+ required_sections:
427
+ - "Fontes Pesquisadas"
428
+ - "Principais Descobertas"
429
+ - "TL;DR"
430
+ min_sections: 3
431
+ ```
432
+
433
+ ### Veto Condition Enforcement
434
+
435
+ After an agent completes a step (before moving to the next step):
436
+
437
+ 1. Check if the step file has a `## Veto Conditions` section
438
+ 2. If yes, evaluate each veto condition against the agent's output:
439
+ - Read the output that was just produced
440
+ - Check each condition (e.g., "slides exceed 30 words", "no CTA", "missing sources")
441
+ 3. If ANY veto condition is triggered:
442
+ - Inform user: "⚠️ {Agent Name}'s output triggered a veto: {condition}"
443
+ - Ask the agent to fix the specific issue (re-execute with targeted correction)
444
+ - Maximum 2 veto fix attempts per step
445
+ - After 2 failed attempts, present to user for manual decision
446
+ 4. If no veto conditions triggered: proceed to next step
447
+
448
+ This creates an internal quality loop BEFORE the reviewer sees the content,
449
+ catching obvious issues early and reducing review cycle waste.
450
+
451
+ ### Review Loops
452
+
453
+ When a step has `on_reject: {step-id}`:
454
+ - Track the review cycle count
455
+ - If reviewer rejects, go back to the referenced step
456
+ - Pass reviewer feedback to the writer agent
457
+ - If max_review_cycles reached, present to user for manual decision
458
+
459
+ ### Dashboard Handoff (between steps)
460
+
461
+ After a step completes output and there IS a next step (MANDATORY):
462
+
463
+ 1. **Write delivering state** — Write `crews/{name}/state.json` with:
464
+ - Current step's agent: `"status": "delivering"`
465
+ - Next step's agent: `"status": "idle"`
466
+ - All other agents unchanged
467
+ - Pipeline `"status": "running"`
468
+ - Add or update `"handoff"`:
469
+ ```json
470
+ "handoff": {
471
+ "from": "{current agent id}",
472
+ "to": "{next agent id}",
473
+ "message": "{one-sentence summary of what was produced, written in the user's language}",
474
+ "completedAt": "{ISO timestamp now}"
475
+ }
476
+ ```
477
+ - `"updatedAt"`: now
478
+
479
+ 2. _(No delay — proceed immediately to working state)_
480
+
481
+ 2. **Write working state** — Write `crews/{name}/state.json` again with:
482
+ - Current agent: `"status": "done"`
483
+ - Next agent: `"status": "working"`
484
+ - Keep the `"handoff"` object from step 1 unchanged
485
+ - `"updatedAt"`: now
486
+
487
+ ### Step Execution Order (Summary)
488
+
489
+ For reference, the complete execution order for each pipeline step is:
490
+
491
+ ```
492
+ 0. Dashboard update (state.json)
493
+ 1. Pre-Step Input Validation (bash gate)
494
+ 2. Read step file
495
+ 3. Check execution mode and execute (subagent / inline / checkpoint)
496
+ 4. Post-Step Output Validation (bash gate)
497
+ 5. Veto Condition Enforcement
498
+ 6. Dashboard Handoff (to next step)
499
+ ```
500
+
501
+ Steps 1 and 4 are binary bash gates. If either fails, the pipeline does NOT advance — the user is consulted.
502
+
503
+ ### After Pipeline Completion
504
+
505
+ 1. Save final output to `crews/{name}/output/{run_id}/{filename}.md`
506
+ (The run folder was created during initialization — no separate date subfolder needed)
507
+ 1b. **Update dashboard** — MANDATORY. Write `crews/{name}/state.json` with:
508
+ - `"status": "completed"`
509
+ - All agents: `"status": "done"`
510
+ - `"updatedAt"`: now
511
+ - `"completedAt"`: now
512
+ - `"startedAt"`: preserve from existing `state.json`
513
+ - Keep existing `"handoff"` object
514
+
515
+ ### Post-Completion Cleanup
516
+
517
+ After writing the final "completed" state to `crews/{name}/state.json`:
518
+
519
+ 1. Add the `completedAt` field (or `failedAt` if status is `failed`) with the current ISO timestamp
520
+ 2. Copy `state.json` to the run output folder for permanent history:
521
+ ```bash
522
+ cp crews/{name}/state.json crews/{name}/output/{run_id}/state.json
523
+ ```
524
+ 3. Wait 10 seconds (so the dashboard can display the completed state)
525
+ 4. Delete the working copy:
526
+ ```bash
527
+ rm crews/{name}/state.json
528
+ ```
529
+
530
+ This archives the run state for the `runs` command while keeping the crew root clean.
531
+
532
+ 2. **Update crew memory** — write to BOTH files (runs after Post-Completion Cleanup above):
533
+
534
+ ### 2a. Update `memories.md` (living preferences)
535
+
536
+ Read `crews/{name}/_memory/memories.md` in full. Then identify candidates from this run: **only explicit user feedback** — approvals with comments, rejections with reasons, direct requests ("prefiro X", "não quero Y"). Never infer preferences.
537
+
538
+ For each candidate:
539
+ - If an equivalent memory already exists and is compatible → skip (no duplicate)
540
+ - If an equivalent memory exists but contradicts the new item → replace with the newer version
541
+ - If no equivalent exists → add to the correct semantic section:
542
+ - Writing style choices → `## Estilo de Escrita`
543
+ - Visual/design preferences → `## Design Visual`
544
+ - Content structure choices → `## Estrutura de Conteúdo`
545
+ - Explicit rejections or prohibitions → `## Proibições Explícitas`
546
+ - Crew-specific technical patterns → `## Técnico (específico do crew)`
547
+
548
+ **Never write to `memories.md`:**
549
+ - Runner inferences ("usuário parece preferir X")
550
+ - Run scores, review grades, output file paths, topics from past runs
551
+
552
+ **Technical routing:** For any technical learning (bugs, workarounds, API behavior):
553
+ - If it affects any crew (Playwright bugs, OS rendering quirks, API limits) → write to the appropriate `_opencrew/core/best-practices/` file instead of `memories.md`
554
+ - If it is specific to this crew's output type or toolchain → add to `## Técnico (específico do crew)` following the dedup rules above
555
+
556
+ After applying all candidates, write the updated `memories.md`.
557
+
558
+ If no candidates are found (the run had no explicit user feedback), skip writing `memories.md` entirely — do not write an unmodified copy. Always proceed to step 2b regardless.
559
+
560
+ ### 2b. Prepend to `runs.md` (reverse-chronological log — newest run first)
561
+
562
+ If `crews/{name}/_memory/runs.md` does not exist, create it first with:
563
+ ```markdown
564
+ # Run History: {crew-name}
565
+
566
+ | Data | Run ID | Tema | Output | Resultado |
567
+ |------|--------|------|--------|-----------|
568
+ ```
569
+ Then proceed to prepend the new row.
570
+
571
+ Read `crews/{name}/_memory/runs.md`. Prepend one new row to the table (immediately after the header row), with:
572
+ - `Data`: today's date in YYYY-MM-DD format
573
+ - `Run ID`: the `run_id` for this execution
574
+ - `Tema`: the topic or user request from this run (1 sentence max)
575
+ - `Output`: brief description of what was generated (e.g., "Carrossel 9 slides", "Thread 7 posts")
576
+ - `Resultado`: one of — `Aprovado` / `Rejeitado` / `Publicado` / `Abortado`
577
+
578
+ No other data. Do not add preferences, scores, file paths, or technical notes to `runs.md`.
579
+
580
+ 3. Present completion summary:
581
+ ```
582
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
583
+ ✅ Pipeline complete!
584
+ 📁 Run folder: crews/{name}/output/{run_id}/
585
+ 📄 Output saved to: {output path}
586
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
587
+
588
+ What would you like to do?
589
+ ● Run again (new topic)
590
+ ○ Edit this content
591
+ ○ Back to menu
592
+ ```
593
+
594
+ ## Error Handling
595
+
596
+ - If a subagent fails, retry once. If it fails again, inform the user and offer to skip the step or abort.
597
+ - If a step file is missing, inform the user and suggest running `/opencrew edit {crew}` to fix.
598
+ - If company.md is empty, stop and redirect to onboarding.
599
+ - Never continue past a checkpoint without user input.
600
+
601
+ ## Pipeline State
602
+
603
+ Track pipeline state in memory during execution:
604
+ - Run ID (run_id) — the output subfolder name for this execution
605
+ - Current step index
606
+ - Outputs from each completed step (file paths)
607
+ - User choices at checkpoints
608
+ - Review cycle count
609
+ - Start time
610
+
611
+ This state does NOT persist to disk — it exists only during the current run.