owflow 0.3.0 → 0.4.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +24 -2
- package/dist/agents/information-gatherer.md +11 -11
- package/dist/agents/research-planner.md +15 -12
- package/dist/agents/research-synthesizer.md +7 -5
- package/dist/agents/solution-brainstormer.md +4 -4
- package/dist/agents/solution-designer.md +6 -6
- package/dist/commands/work.md +9 -9
- package/dist/configuration/commands-config.js +57 -0
- package/dist/configuration/skills-config.js +1 -1
- package/dist/index.js +5 -2
- package/dist/skills/diagrams-mermaid/SKILL.md +1 -0
- package/dist/skills/flow-init/SKILL.md +1 -1
- package/dist/skills/goal-research/SKILL.md +118 -0
- package/dist/skills/html-renderer/SKILL.md +1 -0
- package/dist/skills/migration/SKILL.md +1 -0
- package/dist/skills/orchestrator-framework/references/command-namespacing.md +1 -1
- package/dist/skills/orchestrator-framework/references/dispatcher-handoff.md +8 -1
- package/dist/skills/orchestrator-framework/references/gate-contract.md +17 -9
- package/dist/skills/performance/SKILL.md +1 -0
- package/dist/skills/research/SKILL.md +130 -376
- package/dist/skills/research-brainstorm/SKILL.md +120 -0
- package/dist/skills/{research → research-brainstorm}/references/brainstorming-techniques.md +1 -1
- package/dist/skills/research-converge/SKILL.md +130 -0
- package/dist/skills/research-design/SKILL.md +146 -0
- package/dist/skills/{research → research-design}/references/design-techniques.md +1 -1
- package/dist/skills/research-finalize/SKILL.md +125 -0
- package/dist/skills/research-fork/SKILL.md +190 -0
- package/dist/skills/research-gather/SKILL.md +133 -0
- package/dist/skills/research-plan/SKILL.md +141 -0
- package/dist/skills/research-quick/SKILL.md +139 -0
- package/dist/skills/research-synthesize/SKILL.md +127 -0
- package/dist/skills/rule-reviewer/SKILL.md +1 -1
- package/dist/skills/standards-discover/SKILL.md +1 -0
- package/dist/templates/orchestrator-state-research.yml +19 -13
- package/dist/tools/fork_task.js +36 -0
- package/dist/tools/verify_template.js +10 -31
- package/dist/utils/file-util.js +1 -1
- package/dist/utils/fork-task.js +74 -0
- package/dist/utils/plugin-info.js +20 -0
- package/dist/utils/yaml-structure.js +32 -0
- package/package.json +1 -1
- package/dist/commands/agents-md-generator.md +0 -36
- package/dist/commands/dev-analyze.md +0 -33
- package/dist/commands/dev-bugfix.md +0 -37
- package/dist/commands/dev-finalize.md +0 -33
- package/dist/commands/dev-implement.md +0 -34
- package/dist/commands/dev-plan.md +0 -37
- package/dist/commands/dev-spec.md +0 -37
- package/dist/commands/dev-tdd-red.md +0 -33
- package/dist/commands/dev-verify.md +0 -33
- package/dist/commands/development.md +0 -36
- package/dist/commands/diagrams-mermaid.md +0 -36
- package/dist/commands/flow-init.md +0 -36
- package/dist/commands/goal-development.md +0 -32
- package/dist/commands/html-renderer.md +0 -36
- package/dist/commands/migration.md +0 -36
- package/dist/commands/performance.md +0 -36
- package/dist/commands/research.md +0 -36
- package/dist/commands/rule-reviewer.md +0 -38
- package/dist/commands/standards-discover.md +0 -36
- package/dist/commands/standards-update.md +0 -36
- package/dist/constants.js +0 -4
- /package/dist/skills/{research → research-plan}/references/research-methodologies.md +0 -0
package/README.md
CHANGED
|
@@ -27,7 +27,7 @@ owflow/
|
|
|
27
27
|
└── src/ # Source code
|
|
28
28
|
├── __tests__/ # Test suites
|
|
29
29
|
├── agents/ # Agent definitions and prompts (.md)
|
|
30
|
-
├── commands/ #
|
|
30
|
+
├── commands/ # Maintained content commands (.md); the rest are generated from skill frontmatter
|
|
31
31
|
├── configuration/ # Handlers for agent, command, and skill configurations
|
|
32
32
|
├── hooks/ # OpenCode lifecycle hooks (tool execution, compaction)
|
|
33
33
|
├── skills/ # Workflows, orchestrators, and reusable skills
|
|
@@ -137,7 +137,14 @@ You can always be explicit when you prefer - arguments and flags simply override
|
|
|
137
137
|
| `/owflow:performance` | Optimizing speed or resource usage |
|
|
138
138
|
| `/owflow:migration` | Changing technologies or patterns |
|
|
139
139
|
|
|
140
|
-
|
|
140
|
+
Use `/owflow:work` as a single entry point — it classifies the task with the `task-classifier` subagent and routes to the right workflow.
|
|
141
|
+
|
|
142
|
+
### Research Utility
|
|
143
|
+
|
|
144
|
+
| Command | Use When |
|
|
145
|
+
| ----------------------------- | -------------------------------------------------------------------------------- |
|
|
146
|
+
| `/owflow:research-quick "<description>"` | Condensed research: brief → plan → gather → synthesis in one pass |
|
|
147
|
+
| `/owflow:research-fork <task-path> ["<what this fork should explore>"]` | Branch a research task and re-run from the fork point with different choices |
|
|
141
148
|
|
|
142
149
|
### Quick Commands
|
|
143
150
|
|
|
@@ -221,6 +228,21 @@ You can also append additional instructions to narrow scope or guide the workflo
|
|
|
221
228
|
/owflow:development .owflow/tasks/research/2026-01-12-oauth-research Implement only phase 1
|
|
222
229
|
```
|
|
223
230
|
|
|
231
|
+
**Fork a research task to diverge from it.** If you want to re-run part of a completed research with different choices while keeping the original intact, fork it. Passing the task path is enough — the skill reads that research, then asks what the fork should explore, where it should diverge, and what to call it, with suggestions drawn from the research itself:
|
|
232
|
+
|
|
233
|
+
```bash
|
|
234
|
+
/owflow:research-fork .owflow/tasks/research/2026-01-12-oauth-research
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
Answer the three questions (or supply the answers up front — each one then gets skipped):
|
|
238
|
+
|
|
239
|
+
```bash
|
|
240
|
+
/owflow:research-fork .owflow/tasks/research/2026-01-12-oauth-research "compare scoping alternatives" \
|
|
241
|
+
--from=synthesis-complete --name="compare-scoping-alternatives"
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
The copy is verbatim (all artifacts, including those from after the fork point) and only the fork's `completed_phases` is trimmed at the fork point, so the fork resumes at the step after it. The source task is never modified.
|
|
245
|
+
|
|
224
246
|
## Known Issues
|
|
225
247
|
|
|
226
248
|
**Orchestrator may stall after long phases.** After context compaction (which typically happens after lengthy phases like implementation), the main agent may stop progressing automatically. If you notice it's idle, just type something like "continue" or "proceed" — it will pick up where it left off. You can also re-invoke the workflow in resume mode to reload the orchestrator state:
|
|
@@ -47,14 +47,14 @@ hidden: true
|
|
|
47
47
|
**Custom Categories**: The `source_category` parameter also accepts custom category IDs defined by the research-planner's gathering strategy (e.g., `external-apis`, `project-a-codebase`, `legacy-system`). When a custom category is provided:
|
|
48
48
|
|
|
49
49
|
- Read the Gathering Strategy section from `planning/research-plan.md` to understand the focus area
|
|
50
|
-
- Name output files using the category ID as
|
|
50
|
+
- Name output files using the category ID as the leading slug: `analysis/findings/[category-id]-*.md` — the category ID IS the required prefix; the `*` tail may add fresh, specific keywords but MUST NOT repeat words already in the category ID (no stacked slugs like `v2-opencode-v2-direction.md` for category `v2`; the duplicated words add nothing — keep the tail distinct)
|
|
51
51
|
- Apply the most appropriate tools based on the focus area (codebase-focused → Glob/Grep/Read, external-focused → WebSearch/WebFetch, docs-focused → Read/Grep)
|
|
52
52
|
|
|
53
53
|
**When source_category is NOT `all`**:
|
|
54
54
|
|
|
55
55
|
- Filter `planning/sources.md` to only include matching category (or use gathering strategy focus area for custom categories)
|
|
56
|
-
- Skip summary generation (Phase 7) - handled by
|
|
57
|
-
- Skip verification generation - handled by
|
|
56
|
+
- Skip summary generation (Phase 7) - handled by the research-gather merge step
|
|
57
|
+
- Skip verification generation - handled by the research-gather merge step
|
|
58
58
|
- Write only category-specific findings files
|
|
59
59
|
|
|
60
60
|
---
|
|
@@ -104,7 +104,7 @@ You are an information gathering specialist that executes systematic data collec
|
|
|
104
104
|
- Read the "Gathering Strategy" section from `planning/research-plan.md`
|
|
105
105
|
- Find the row matching this category ID to understand the specific focus area and recommended tools
|
|
106
106
|
- Use the focus area description to guide what sources to investigate
|
|
107
|
-
- Use the
|
|
107
|
+
- Use the category ID from the strategy for file naming (`analysis/findings/[category-id]-*.md`)
|
|
108
108
|
|
|
109
109
|
**Output**: Clear understanding of what to gather and how (filtered by category if specified)
|
|
110
110
|
|
|
@@ -451,7 +451,7 @@ Follow the research plan phases systematically. Typical progression:
|
|
|
451
451
|
|
|
452
452
|
### Phase 7: Create Findings Summary
|
|
453
453
|
|
|
454
|
-
**SKIP this phase if `source_category` is NOT `all`** - summary will be created by
|
|
454
|
+
**SKIP this phase if `source_category` is NOT `all`** - summary will be created by the research-gather merge step when running in parallel mode.
|
|
455
455
|
|
|
456
456
|
**Execute this phase only when `source_category` is `all` or not specified.**
|
|
457
457
|
|
|
@@ -675,17 +675,17 @@ analysis/findings/
|
|
|
675
675
|
|
|
676
676
|
---
|
|
677
677
|
|
|
678
|
-
## Integration with Research
|
|
678
|
+
## Integration with the Research Workflow
|
|
679
679
|
|
|
680
|
-
**
|
|
680
|
+
**Invoked by**: the `owflow:research-gather` subskill (Task tool), one call per planned category, all calls in ONE message
|
|
681
681
|
|
|
682
|
+
**Input**:
|
|
682
683
|
- `planning/research-plan.md` (methodology + gathering strategy)
|
|
683
684
|
- `planning/sources.md` (data sources)
|
|
684
685
|
|
|
685
|
-
**Output
|
|
686
|
-
|
|
686
|
+
**Output** (merged by the calling subskill):
|
|
687
687
|
- `analysis/findings/*.md` (detailed findings by source category)
|
|
688
688
|
|
|
689
|
-
**State Update**:
|
|
689
|
+
**State Update**: The calling subskill records `findings-gathered`
|
|
690
690
|
|
|
691
|
-
**Next Step**:
|
|
691
|
+
**Next Step**: `owflow:research-synthesize` merges the findings and invokes research-synthesizer
|
|
@@ -239,11 +239,11 @@ You are a research planning specialist that creates structured, methodical resea
|
|
|
239
239
|
|
|
240
240
|
### Instances: [N] (max 8)
|
|
241
241
|
|
|
242
|
-
| # | Category ID | Focus Area | Tools |
|
|
243
|
-
| --- | ------------- | -------------------------- | ------------------- |
|
|
244
|
-
| 1 | codebase | Source code analysis | Glob, Grep, Read |
|
|
245
|
-
| 2 | documentation | Project docs & code docs | Read, Grep |
|
|
246
|
-
| 3 | external-apis | External API documentation | WebSearch, WebFetch |
|
|
242
|
+
| # | Category ID | Focus Area | Tools |
|
|
243
|
+
| --- | ------------- | -------------------------- | ------------------- |
|
|
244
|
+
| 1 | codebase | Source code analysis | Glob, Grep, Read |
|
|
245
|
+
| 2 | documentation | Project docs & code docs | Read, Grep |
|
|
246
|
+
| 3 | external-apis | External API documentation | WebSearch, WebFetch |
|
|
247
247
|
|
|
248
248
|
### Rationale
|
|
249
249
|
|
|
@@ -255,8 +255,9 @@ You are a research planning specialist that creates structured, methodical resea
|
|
|
255
255
|
- Minimum: 1 gatherer (simple questions that only need one source type)
|
|
256
256
|
- Maximum: 8 gatherers (prevent token waste and diminishing returns)
|
|
257
257
|
- Each gatherer must have a distinct focus area (no overlapping categories)
|
|
258
|
-
- The category ID becomes the `source_category` parameter for the information-gatherer agent
|
|
259
|
-
-
|
|
258
|
+
- The category ID becomes the `source_category` parameter for the information-gatherer agent AND the findings file prefix: files are `analysis/findings/[category-id]-*.md` — the Category ID is the ONLY filename slug source (an optional short Output Prefix column previously duplicated this and caused stacked slugs like `dynamic-dynamic-approaches.md`; removed)
|
|
259
|
+
- Category IDs SHOULD be short and descriptive (e.g. `codebase`, `docs`, `external`) — they lead every findings filename, and reuse of their words in the descriptive tail is duplication
|
|
260
|
+
- **Heading label is fixed**: the section heading MUST be exactly `## Gathering Strategy` (no numeric prefix like `## 6. Gathering Strategy` — downstream `research-gather` parses for the exact string)
|
|
260
261
|
|
|
261
262
|
**Default Fallback** (if not specified):
|
|
262
263
|
When the planner does not include a Gathering Strategy section, the orchestrator falls back to 4 instances:
|
|
@@ -437,11 +438,13 @@ When the planner does not include a Gathering Strategy section, the orchestrator
|
|
|
437
438
|
|
|
438
439
|
---
|
|
439
440
|
|
|
440
|
-
## Integration with Research
|
|
441
|
+
## Integration with the Research Workflow
|
|
441
442
|
|
|
442
|
-
**
|
|
443
|
-
**Output to Phase 1, Step 3**: `planning/research-plan.md`, `planning/sources.md`
|
|
443
|
+
**Invoked by**: the `owflow:research-plan` subskill (Task tool)
|
|
444
444
|
|
|
445
|
-
**
|
|
445
|
+
**Input**: `planning/research-brief.md`
|
|
446
|
+
**Output**: `planning/research-plan.md`, `planning/sources.md`
|
|
446
447
|
|
|
447
|
-
**
|
|
448
|
+
**State Update**: The calling subskill records `plan-created`
|
|
449
|
+
|
|
450
|
+
**Next Step**: `owflow:research-gather` reads the gathering strategy and launches the information-gatherer fan
|
|
@@ -387,15 +387,17 @@ Combine relevant elements from above frameworks based on research objectives.
|
|
|
387
387
|
|
|
388
388
|
---
|
|
389
389
|
|
|
390
|
-
## Integration with Research
|
|
390
|
+
## Integration with the Research Workflow
|
|
391
391
|
|
|
392
|
-
**
|
|
392
|
+
**Invoked by**: the `owflow:research-synthesize` subskill (Task tool)
|
|
393
|
+
|
|
394
|
+
**Input** (information gathering):
|
|
393
395
|
- `analysis/findings/*.md` (all finding files)
|
|
394
396
|
|
|
395
|
-
**Output
|
|
397
|
+
**Output**:
|
|
396
398
|
- `analysis/synthesis.md` (patterns and insights)
|
|
397
399
|
- `outputs/research-report.md` (comprehensive report)
|
|
398
400
|
|
|
399
|
-
**State Update**:
|
|
401
|
+
**State Update**: The calling subskill records `synthesis-complete`
|
|
400
402
|
|
|
401
|
-
**Next Step**:
|
|
403
|
+
**Next Step**: the user chooses the optional chain (brainstorm / design) or `owflow:research-finalize` completes the task
|
|
@@ -228,18 +228,18 @@ warnings: ["any non-critical observations"]
|
|
|
228
228
|
|
|
229
229
|
## Integration
|
|
230
230
|
|
|
231
|
-
**Invoked by**: research
|
|
231
|
+
**Invoked by**: the `owflow:research-brainstorm` subskill (Task tool)
|
|
232
232
|
|
|
233
233
|
**Prerequisites**:
|
|
234
234
|
- Task directory exists with `analysis/` and `outputs/` subdirectories
|
|
235
|
-
- `analysis/synthesis.md` exists (
|
|
236
|
-
- `outputs/research-report.md` exists (
|
|
235
|
+
- `analysis/synthesis.md` exists (research-synthesize output)
|
|
236
|
+
- `outputs/research-report.md` exists (research-synthesize output)
|
|
237
237
|
|
|
238
238
|
**Input**: Task path, research artifacts, accumulated context (no user preferences — alternatives are generated purely from evidence)
|
|
239
239
|
|
|
240
240
|
**Output**: `outputs/solution-exploration.md` + structured result
|
|
241
241
|
|
|
242
|
-
**Next
|
|
242
|
+
**Next**: `owflow:research-converge` presents the alternatives to the user for per-area convergence, then `owflow:research-design` consumes the chosen approach.
|
|
243
243
|
|
|
244
244
|
---
|
|
245
245
|
|
|
@@ -336,24 +336,24 @@ warnings: ["any non-critical observations"]
|
|
|
336
336
|
|
|
337
337
|
## Integration
|
|
338
338
|
|
|
339
|
-
**Invoked by**: research
|
|
339
|
+
**Invoked by**: the `owflow:research-design` subskill (Task tool)
|
|
340
340
|
|
|
341
341
|
**Prerequisites**:
|
|
342
342
|
- Task directory exists with `analysis/` and `outputs/` subdirectories
|
|
343
|
-
- `
|
|
344
|
-
- `
|
|
345
|
-
- `outputs/
|
|
343
|
+
- `analysis/synthesis.md` exists (research-synthesize output)
|
|
344
|
+
- `outputs/research-report.md` exists (research-synthesize output)
|
|
345
|
+
- `outputs/solution-exploration.md` exists — only when brainstorming ran; on the design-only branch `selected_approach` comes from the research report instead
|
|
346
346
|
|
|
347
347
|
**Input**: Task path, solution exploration, research artifacts, selected approach, design preferences, accumulated context
|
|
348
348
|
|
|
349
349
|
**Output**: `outputs/high-level-design.md` + `outputs/decision-log.md` + structured result
|
|
350
350
|
|
|
351
|
-
**Next
|
|
351
|
+
**Next**: `owflow:research-finalize` inventories the outputs and completes the task; the design documents are later consumed by development's specification phase.
|
|
352
352
|
|
|
353
353
|
**Downstream consumption**:
|
|
354
354
|
- `specification-creator` reads `high-level-design.md` as primary architectural input
|
|
355
355
|
- `specification-creator` references `decision-log.md` to avoid re-deciding settled questions
|
|
356
|
-
- Development
|
|
356
|
+
- Development's specification phase incorporates architecture decisions, which can be lighter when comprehensive ADRs exist
|
|
357
357
|
|
|
358
358
|
---
|
|
359
359
|
|
package/dist/commands/work.md
CHANGED
|
@@ -53,12 +53,12 @@ Auto-classifies tasks and routes to the appropriate workflow orchestrator. Suppo
|
|
|
53
53
|
|
|
54
54
|
## Workflow Type Routing
|
|
55
55
|
|
|
56
|
-
| Classification | Routes To (Skill)
|
|
57
|
-
| -------------- |
|
|
58
|
-
| development | `development`
|
|
59
|
-
| performance | `performance`
|
|
60
|
-
| migration | `migration`
|
|
61
|
-
| research | `research`
|
|
56
|
+
| Classification | Routes To (Skill) |
|
|
57
|
+
| -------------- | --------------------- |
|
|
58
|
+
| development | `owflow:development` |
|
|
59
|
+
| performance | `owflow:performance` |
|
|
60
|
+
| migration | `owflow:migration` |
|
|
61
|
+
| research | `owflow:research` |
|
|
62
62
|
|
|
63
63
|
---
|
|
64
64
|
|
|
@@ -146,7 +146,7 @@ Use Skill tool:
|
|
|
146
146
|
Examples:
|
|
147
147
|
|
|
148
148
|
- Resume development: `skill: "owflow:development"` with `args: "--resume .owflow/tasks/development/2025-10-23-fix"`
|
|
149
|
-
- Restart from step: `skill: "owflow:development"` with `args: "--resume .owflow/tasks/development/2025-10-26-auth --from=verification-done"` (dev tasks use descriptive step slugs in `completed_phases`;
|
|
149
|
+
- Restart from step: `skill: "owflow:development"` with `args: "--resume .owflow/tasks/development/2025-10-26-auth --from=verification-done"` (dev tasks use descriptive step slugs in `completed_phases`; performance and migration are the remaining `phase-N` holdouts — research uses the descriptive slugs in `templates/orchestrator-state-research.yml`)
|
|
150
150
|
- Fresh attempts: `skill: "owflow:migration"` with `args: "--resume .owflow/tasks/migrations/2025-10-20-redux --reset-attempts"`
|
|
151
151
|
|
|
152
152
|
### Step 3: Classify & Route New Task
|
|
@@ -235,10 +235,10 @@ Display:
|
|
|
235
235
|
|
|
236
236
|
| Workflow Type | Skill | Args |
|
|
237
237
|
| ------------- | ------------- | --------------------------------------------------- |
|
|
238
|
-
| development | `development` | `--resume [path] [--from
|
|
238
|
+
| development | `development` | `--resume [path] [--from=<slug>] [--reset-attempts]` |
|
|
239
239
|
| performance | `performance` | `--resume [path] [--from=PHASE]` |
|
|
240
240
|
| migration | `migration` | `--resume [path] [--from=PHASE]` |
|
|
241
|
-
| research | `research` | `--resume [path] [--from
|
|
241
|
+
| research | `research` | `--resume [path] [--from=<slug>]` |
|
|
242
242
|
|
|
243
243
|
---
|
|
244
244
|
|
|
@@ -1,4 +1,44 @@
|
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import matter from "gray-matter";
|
|
1
4
|
import { loadMarkdownDir } from "../utils/file-util.js";
|
|
5
|
+
import { PLUGIN_ROOT } from "../utils/plugin-info.js";
|
|
6
|
+
// Keeps the rendered body independent of the line endings of this file's storage.
|
|
7
|
+
const CRLF = "\r\n";
|
|
8
|
+
const REQUIRED_COMMAND_KEYS = ["name", "description"];
|
|
9
|
+
/**
|
|
10
|
+
* Renders the command body for one skill from its frontmatter.
|
|
11
|
+
* Pure: one frontmatter object in, one string out.
|
|
12
|
+
*/
|
|
13
|
+
export const renderCommandTemplate = (data) => [
|
|
14
|
+
`CRITICAL INSTRUCTION: You MUST invoke the ${data.name} skill immediately as your FIRST action.`,
|
|
15
|
+
"",
|
|
16
|
+
"Use the Skill tool with these exact parameters:",
|
|
17
|
+
`name: "${data.name}"`,
|
|
18
|
+
`prompt: "$ARGUMENTS"`,
|
|
19
|
+
].join(CRLF);
|
|
20
|
+
/**
|
|
21
|
+
* Reads the frontmatter of every `skills/<slug>/SKILL.md`, one level deep.
|
|
22
|
+
* I/O and parsing only — the invocable gate and the key contract live in the
|
|
23
|
+
* registration loop. Failures are never swallowed: our own source data must not
|
|
24
|
+
* register silently incomplete.
|
|
25
|
+
*/
|
|
26
|
+
export const readSkillFrontmatter = () => {
|
|
27
|
+
const skillsDir = path.join(PLUGIN_ROOT, "skills");
|
|
28
|
+
const skills = [];
|
|
29
|
+
for (const entry of fs.readdirSync(skillsDir, { withFileTypes: true })) {
|
|
30
|
+
if (!entry.isDirectory())
|
|
31
|
+
continue;
|
|
32
|
+
const skillFile = path.join(skillsDir, entry.name, "SKILL.md");
|
|
33
|
+
if (!fs.existsSync(skillFile))
|
|
34
|
+
continue;
|
|
35
|
+
skills.push({
|
|
36
|
+
slug: entry.name,
|
|
37
|
+
data: matter(fs.readFileSync(skillFile, "utf8")).data,
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
return skills;
|
|
41
|
+
};
|
|
2
42
|
export const configureCommands = (config) => {
|
|
3
43
|
config.command = config.command || {};
|
|
4
44
|
for (const { data, content } of loadMarkdownDir("commands")) {
|
|
@@ -18,4 +58,21 @@ export const configureCommands = (config) => {
|
|
|
18
58
|
}),
|
|
19
59
|
};
|
|
20
60
|
}
|
|
61
|
+
for (const { slug, data } of readSkillFrontmatter()) {
|
|
62
|
+
if (data["user-invocable"] !== true)
|
|
63
|
+
continue;
|
|
64
|
+
const missing = REQUIRED_COMMAND_KEYS.filter((key) => typeof data[key] !== "string" || data[key] === "");
|
|
65
|
+
if (missing.length > 0) {
|
|
66
|
+
throw new Error(`[owflow] Skill '${slug}' is user-invocable but is missing required frontmatter: ${missing.join(", ")}`);
|
|
67
|
+
}
|
|
68
|
+
const name = data.name;
|
|
69
|
+
// Don't overwrite commands the user has explicitly configured
|
|
70
|
+
if (config.command[name])
|
|
71
|
+
continue;
|
|
72
|
+
config.command[name] = {
|
|
73
|
+
template: renderCommandTemplate(data),
|
|
74
|
+
// A folded YAML description scalar parses with a trailing newline
|
|
75
|
+
description: data.description.trimEnd(),
|
|
76
|
+
};
|
|
77
|
+
}
|
|
21
78
|
};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import path from "node:path";
|
|
2
|
-
import { PLUGIN_ROOT } from "../
|
|
2
|
+
import { PLUGIN_ROOT } from "../utils/plugin-info.js";
|
|
3
3
|
export const configureSkills = (config) => {
|
|
4
4
|
config.skills = config.skills || {};
|
|
5
5
|
config.skills.paths = config.skills.paths || [];
|
package/dist/index.js
CHANGED
|
@@ -4,7 +4,9 @@
|
|
|
4
4
|
*/
|
|
5
5
|
import path from "node:path";
|
|
6
6
|
import fs from "node:fs";
|
|
7
|
+
import { PLUGIN_VERSION } from "./utils/plugin-info.js";
|
|
7
8
|
import { verify_template } from "./tools/verify_template.js";
|
|
9
|
+
import { fork_task } from "./tools/fork_task.js";
|
|
8
10
|
import { rereadOrchestratorState } from "./hooks/session-compaction.js";
|
|
9
11
|
import { guardAgainstDestructiveActions } from "./hooks/before-tool.js";
|
|
10
12
|
import { configureSkills } from "./configuration/skills-config.js";
|
|
@@ -16,13 +18,14 @@ const OwflowPlugin = async ({ $, directory }) => {
|
|
|
16
18
|
return {
|
|
17
19
|
tool: {
|
|
18
20
|
verify_template,
|
|
21
|
+
fork_task,
|
|
19
22
|
},
|
|
20
23
|
/**
|
|
21
24
|
* Register owflow's skills, commands, and agents so OpenCode discovers
|
|
22
25
|
* them without requiring manual config file edits.
|
|
23
26
|
*/
|
|
24
27
|
config: async (config) => {
|
|
25
|
-
console.log(
|
|
28
|
+
console.log(`[owflow] Starting plugin installation (v${PLUGIN_VERSION})...`);
|
|
26
29
|
let typedConfig = config;
|
|
27
30
|
// Get small_model config for alias resolution
|
|
28
31
|
// Try from config parameter first, fallback to reading opencode.json
|
|
@@ -45,7 +48,7 @@ const OwflowPlugin = async ({ $, directory }) => {
|
|
|
45
48
|
configureCommands(typedConfig);
|
|
46
49
|
configureAgents(typedConfig, smallModel);
|
|
47
50
|
config = typedConfig;
|
|
48
|
-
console.log(
|
|
51
|
+
console.log(`[owflow] Plugin installation completed successfully (v${PLUGIN_VERSION}).`);
|
|
49
52
|
},
|
|
50
53
|
"experimental.session.compacting": async (input, output) => {
|
|
51
54
|
await rereadOrchestratorState(directory, output);
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: owflow:diagrams-mermaid
|
|
3
3
|
description: Creates Mermaid diagrams for planning flows, component communication, and architecture views with adaptive detail selection (including C4 levels). This skill should be used when the user asks for a workflow, interaction, or architecture visualization from provided task context.
|
|
4
|
+
argument-hint: "[diagram description]"
|
|
4
5
|
user-invocable: true
|
|
5
6
|
---
|
|
6
7
|
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: owflow:goal-research
|
|
3
|
+
description: Full orchestrated research wrapper — runs ALL research steps in one session by invoking every research-* subskill in sequence with question gates between them (equivalent to the classic unified orchestrator for research). Use /owflow:research for the same lifecycle in assisted mode — tasks can mix both modes freely.
|
|
4
|
+
argument-hint: "[task description | task-path] [--from=<slug>] [--type=<type>]"
|
|
5
|
+
user-invocable: true
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Orchestrated Research Wrapper
|
|
9
|
+
|
|
10
|
+
Autonomous mode for research tasks. Initializes (or resumes) the task, then invokes every required `research-*` subskill back-to-back via the Skill tool, pausing at gates between subskills. Shares `orchestrator-state.yml` with assisted mode (`/owflow:research`) — tasks can mix both modes freely.
|
|
11
|
+
|
|
12
|
+
Gates follow the shared contract in [Gate Contract](../orchestrator-framework/references/gate-contract.md) — orchestrated mode exception: each subskill's own Exit Gate acceptance question IS the loop gate (Accept = continue to the next subskill).
|
|
13
|
+
|
|
14
|
+
## Input / Output Artifacts
|
|
15
|
+
|
|
16
|
+
| Artifact | Normal mode (this wrapper) | Quick mode (`research-quick`) |
|
|
17
|
+
| ----------------------------------- | ---------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------- |
|
|
18
|
+
| Consumed: argument (question / path)| research question (new task) or task path/identifier (resume) | n/a — this wrapper never starts a quick run; a completed quick pass just skips rows 2-3 |
|
|
19
|
+
| Consumed/produced: all task artifacts| owned entirely by the invoked subskills (none here — delegate, never inline) | same — the subskills run at full fidelity after a quick pass |
|
|
20
|
+
| State write | `orchestrator.task_ids` (task items) + `orchestrator.updated` only | none additional — state was already written by the quick pass |
|
|
21
|
+
|
|
22
|
+
## Entry Gate
|
|
23
|
+
|
|
24
|
+
Identical to the research dispatcher — complete ALL of its entry-gate steps first (see `../research/SKILL.md` Entry Gate):
|
|
25
|
+
|
|
26
|
+
1. Read the framework reference files NOW, exactly as the research dispatcher's Step 1: the [Dispatcher & Handoff Pattern](../orchestrator-framework/references/dispatcher-handoff.md), the [Delegation Rules](../orchestrator-framework/references/delegation-rules.md), and the [Orchestrator Patterns](../orchestrator-framework/references/orchestrator-patterns.md).
|
|
27
|
+
2. Resolve the argument the same way the research dispatcher does: task path or identifier (a directory, or a directory name under `.owflow/tasks/research/`) → **resume mode** (read `orchestrator-state.yml`, validate expected artifacts for `completed_phases`; find the first step slug NOT in `completed_phases`, with `--from=<slug>` overriding); a research question (free text) → new task; nothing provided → ask via `question` — "What is your research question?" — then WAIT. Missing state file → print `No research task found at <path>. Run /owflow:research <question> to start from scratch.` and STOP.
|
|
28
|
+
3. Initialize (new task) exactly as the dispatcher: create `.owflow/tasks/research/YYYY-MM-DD-task-name/` + `orchestrator-state.yml` from the research template — `task.title` / `task.description` from the question, `task.status: in_progress`, `orchestrator.task_path`, `orchestrator.entry_point: "research"`. **CRITICAL**: use the `verify_template` tool immediately after creation to check YAML validity against `orchestrator-state-research.yml`. No project-docs discovery at this layer — the `research-plan` brief step owns it.
|
|
29
|
+
4. Command flags: `--type=TYPE` → `research_context.research_type`. Subskills read it from there. This wrapper never forwards quick runs. The optional brainstorm/design chain has no flags — the chain decision is asked at the gate after synthesis (row 4 below) or made by manually invoking the optional subskills.
|
|
30
|
+
5. Create ONE task item via `TaskCreate` per subskill in the upcoming loop (subject: `"<step name>: <subskill>"`, e.g. `"Brief + plan: research-plan"`), then set the execution order with `TaskUpdate addBlockedBy` (plan → gather → synthesize → optional chain (gate question) → finalize). On resume, refresh the already-evidenced items instead of re-creating them. Update statuses as the loop progresses.
|
|
31
|
+
|
|
32
|
+
**Output**:
|
|
33
|
+
|
|
34
|
+
```
|
|
35
|
+
🚀 Orchestrated Research
|
|
36
|
+
|
|
37
|
+
Task: [research question]
|
|
38
|
+
Directory: [task-path]
|
|
39
|
+
Loop: research-plan → research-gather → research-synthesize → [research-brainstorm] → [research-converge] → [research-design] → research-finalize (chain asked at the gate)
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
---
|
|
43
|
+
|
|
44
|
+
## The Loop
|
|
45
|
+
|
|
46
|
+
For each subskill in sequence, execute — skipping any row whose condition is not met (a row whose slug is already in `completed_phases` counts as done):
|
|
47
|
+
|
|
48
|
+
1. **Announce**: 1-line step banner.
|
|
49
|
+
2. **Invoke**: Skill tool with `name: "<subskill>"` and `prompt: "<task-path> [flags relevant to that subskill]"`. The subskill owns its Entry Gate, delegation, and state updates.
|
|
50
|
+
3. **Verify handback**: after the skill returns, re-read `orchestrator-state.yml` — confirm the expected step slugs were appended to `completed_phases` (per the Sequence and Conditionals table). A user-chosen skip of `research-brainstorm` or `research-design` appends no slug — the gate answer itself settles the decision, and the loop continues to the next selected row (or to finalize). Do not treat a skipped optional subskill as an early stop. If a subskill stopped early (entry check failed), STOP the loop and relay its routing message to the user.
|
|
51
|
+
4. **Gate (subskill's Exit Gate is the loop gate)**: each subskill presents its results box and fires its own results-acceptance `question` before its handoff hint (Orchestrated-mode exception, [Gate Contract](../orchestrator-framework/references/gate-contract.md)). [Rule 5 of the Dispatcher & Handoff Pattern](../orchestrator-framework/references/dispatcher-handoff.md) — "subskills only SUGGEST the next command" — is superseded for Accept: when the user answers **Accept** to the subskill's Exit Gate question pointing at the next subskill in this loop, treat that as "continue to the next subskill" and invoke it. Any other answer (Adjust / Discuss / Stop / other options picked) ends the loop the same way a rejected gate would.
|
|
52
|
+
- **Exception**: the per-area convergence `question`s `research-converge` fires (one area, one question) are part of that subskill's own decision flow — they are NOT the loop gate and are NEVER auto-accepted or answered by this wrapper. There is exactly ONE gate definition per subskill hop; the wrapper adds NO second consecutive `question`.
|
|
53
|
+
- **Condensed lane**: this wrapper never starts a quick run. A task already started with `/owflow:research-quick` enters the loop with `brief-written` … `synthesis-complete` already recorded, so those rows are skipped like any other completed slug. An interrupted quick pass (those slugs missing) is not finished condensed here — the user runs `/owflow:research-quick <task-path>` for that.
|
|
54
|
+
|
|
55
|
+
### Sequence and Conditionals
|
|
56
|
+
|
|
57
|
+
| Order | Subskill | Run when (from state) |
|
|
58
|
+
| ----- | ------------------ | ------------------------------------------------------------------------------------------------------------------- |
|
|
59
|
+
| 1 | research-plan | Always (new task or partial foundation) |
|
|
60
|
+
| 2 | research-gather | `plan-created` completed (parses `## Gathering Strategy`, or falls back to 4 default categories; existing findings count as done) |
|
|
61
|
+
| 3 | research-synthesize| `findings-gathered` completed |
|
|
62
|
+
| 4 | chain decision | `synthesis-complete` completed — the wrapper asks via `question`: brainstorm → converge → design, design-only, or straight to finalize |
|
|
63
|
+
| 5 | research-brainstorm| User chose brainstorming at the gate (invoking/sequencing the skill IS the decision) |
|
|
64
|
+
| 6 | research-converge | `alternatives-generated` completed (brainstorm ran) |
|
|
65
|
+
| 7 | research-design | User chose design — after `approaches-chosen`, or the design-only branch (seeded from the research report) |
|
|
66
|
+
| 8 | research-finalize | Foundation complete + optional chain settled (every step the user chose to run is recorded) |
|
|
67
|
+
|
|
68
|
+
A completed quick pass already recorded `brief-written` … `synthesis-complete`, so rows 2-3 are skipped as already done and the loop continues at row 4 (the chain decision). This wrapper never starts a quick run.
|
|
69
|
+
|
|
70
|
+
The optional chain is the user's choice — asked at the gate (row 4) or made by manually invoking the optional subskills. There is no enablement flag in state:
|
|
71
|
+
|
|
72
|
+
- Brainstorm chosen → `research-brainstorm` → `research-converge` → design (if chosen) → finalize.
|
|
73
|
+
- Design-only chosen → skip the brainstorm + converge rows → `research-design` → finalize.
|
|
74
|
+
- Neither chosen → all conditional rows are skipped → `research-finalize`.
|
|
75
|
+
|
|
76
|
+
`research-completed` already in `completed_phases` → the task is TERMINAL: skip the Loop and present the wrapper Exit Gate.
|
|
77
|
+
|
|
78
|
+
**Interruptible**: at any gate the user may answer "stop" — print the standard handoff block (next command + `/owflow:research <task-path>` resume hint) and end the session. The task resumes later in either mode.
|
|
79
|
+
|
|
80
|
+
---
|
|
81
|
+
|
|
82
|
+
## Exit Gate
|
|
83
|
+
|
|
84
|
+
When research-finalize completes (`task.status: completed`):
|
|
85
|
+
|
|
86
|
+
1. Mark the final task item completed via `TaskUpdate`.
|
|
87
|
+
2. Present the workflow results box:
|
|
88
|
+
|
|
89
|
+
```markdown
|
|
90
|
+
## ✅ RESEARCH WORKFLOW COMPLETE — <research question>
|
|
91
|
+
|
|
92
|
+
**Steps** — [executed step slugs, e.g. brief-written → plan-created → findings-gathered → synthesis-complete → alternatives-generated → approaches-chosen → design-generated → research-completed]
|
|
93
|
+
**Confidence** — [research_context.confidence_level]
|
|
94
|
+
**Decisions** — [count of ADRs in the decision log, if design ran]
|
|
95
|
+
**Artifacts** — [artifact inventory: outputs/research-report.md always; outputs/solution-exploration.md / outputs/high-level-design.md / outputs/decision-log.md conditionally]
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
3. Use `question` — "Are these results correct?" with options: **Accept** (print follow-up suggestions: clear context, then `/owflow:development <task-path>` to build on this research, `/owflow:standards-update "<lesson>"` if a standard surfaced, then end) / **Adjust** (re-open the relevant `/owflow:research-*` skill with the corrections) / **Discuss** (walk through the research summary) / **Stop here** (print the resume command `/owflow:research <task-path>` and end).
|
|
99
|
+
|
|
100
|
+
Then end. No further owflow phase commands are required.
|
|
101
|
+
|
|
102
|
+
---
|
|
103
|
+
|
|
104
|
+
## Loop Rules
|
|
105
|
+
|
|
106
|
+
- **Delegate, never inline**: the wrapper only sequences — all step work happens inside subskills. If you catch yourself researching/authoring outside a subskill, STOP and invoke the subskill instead.
|
|
107
|
+
- **State is the truth**: gates and routing read `orchestrator-state.yml`, not memory. Re-read after every subskill returns.
|
|
108
|
+
- **Same state schema as assisted mode**: `completed_phases` step slugs (`brief-written` … `research-completed`) are identical; resume works across modes.
|
|
109
|
+
- **Wrapper writes almost nothing**: step slugs, summaries, and outputs belong to the subskills — this wrapper writes ONLY `orchestrator.task_ids` (task items) and `orchestrator.updated` (timestamps).
|
|
110
|
+
|
|
111
|
+
## Command Integration
|
|
112
|
+
|
|
113
|
+
Invoked via:
|
|
114
|
+
|
|
115
|
+
- `/owflow:goal-research [question] [--type=TYPE]` (new)
|
|
116
|
+
- `/owflow:goal-research [task-path] [--from=<slug>]` (resume)
|
|
117
|
+
|
|
118
|
+
Alternative: `/owflow:research` — same task in assisted mode (one subskill per invocation, fresh context each step).
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: owflow:html-renderer
|
|
3
3
|
description: Render a markdown plan, idea, RFC, or design note into a self-contained, share-ready HTML file using the warm editorial visual system bundled under `references/`. Use this skill whenever the user asks to "render", "convert", "turn into HTML", "make a nice HTML version", "share this as a page", or "make this look good" for a markdown file containing a plan, proposal, idea, brief, RFC, design note, or pitch — even if they don't explicitly say "HTML". The output is a single .html file with all CSS inlined, written next to the source .md, that visually matches the reference layout in `references/index.html` and uses tokens from `references/tokens.json`.
|
|
4
|
+
argument-hint: "[path to markdown file]"
|
|
4
5
|
disable-model-invocation: true
|
|
5
6
|
user-invocable: true
|
|
6
7
|
---
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: owflow:migration
|
|
3
3
|
description: Orchestrates the complete migration workflow from current state analysis through implementation to compatibility verification. Handles technology migrations, platform changes, and architecture pattern transitions with adaptive risk assessment, incremental execution, and rollback planning. Use when migrating technologies, platforms, or architecture patterns.
|
|
4
|
+
argument-hint: "[task description]"
|
|
4
5
|
user-invocable: true
|
|
5
6
|
---
|
|
6
7
|
|
|
@@ -2,6 +2,6 @@
|
|
|
2
2
|
|
|
3
3
|
How commands and skills are named and referenced. Extracted from `orchestrator-patterns.md` (Section 8) so skills can link to it directly.
|
|
4
4
|
|
|
5
|
-
- Slash commands registered from `src/commands/*.md` use `name: owflow:<command>` in frontmatter; users invoke `/owflow:<command>`.
|
|
5
|
+
- Slash commands registered from `src/skills/*/SKILL.md` and from the maintained `src/commands/*.md` use `name: owflow:<command>` in frontmatter; users invoke `/owflow:<command>`.
|
|
6
6
|
- **Skill `name:` fields are prefixed too.** Skill-tool invocations (`skill: "owflow:development"`, `skills:` frontmatter preloads, work.md routing) always reference `owflow:`-prefixed skill names.
|
|
7
7
|
- Handoff messages, docs, and cross-references always display the prefixed slash command — never the bare skill name — in user-facing text.
|
|
@@ -12,7 +12,14 @@ Orchestrators MAY delegate phase bodies to user-invocable **subskills** instead
|
|
|
12
12
|
## Rules
|
|
13
13
|
|
|
14
14
|
1. **State file is canonical.** `orchestrator-state.yml` remains the single source of truth. Subskills read it on entry and write step results on exit. `completed_phases` values MUST stay stable so both modes intermix freely on the same task.
|
|
15
|
-
- **Value convention**: `completed_phases` / `failed_phases` / `auto_fix_attempts` keys are **descriptive step slugs**, not `phase-N` numbers.
|
|
15
|
+
- **Value convention**: `completed_phases` / `failed_phases` / `auto_fix_attempts` keys are **descriptive step slugs**, not `phase-N` numbers. Canonical slugs per workflow:
|
|
16
|
+
|
|
17
|
+
| Workflow | Slugs | Routing table | Template |
|
|
18
|
+
| ------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------- | ---------------------------------------------- |
|
|
19
|
+
| development | `codebase-analysed`, `gap-analysed`, `tdd-red-proven`, `spec-written`, `spec-audited`, `plan-created`, `implementation-done`, `tdd-green-proven`, `options-chosen`, `verification-done`, `e2e-run`, `docs-generated`, `task-completed` | `skills/development/SKILL.md` | `templates/orchestrator-state-development.yml` |
|
|
20
|
+
| research | `brief-written`, `plan-created`, `findings-gathered`, `synthesis-complete`, `alternatives-generated`, `approaches-chosen`, `design-generated`, `research-completed` | `skills/research/SKILL.md` | `templates/orchestrator-state-research.yml` |
|
|
21
|
+
| performance | `phase-N` (legacy holdout — kept internally consistent) | `skills/performance/SKILL.md` | `templates/orchestrator-state-performance.yml` |
|
|
22
|
+
| migration | `phase-N` (legacy holdout — kept internally consistent) | `skills/migration/SKILL.md` | `templates/orchestrator-state-migration.yml` |
|
|
16
23
|
2. **Subskills are self-contained.** Each has: an entry check (validate state + prerequisite artifacts), an execute section (delegation via Skill/Task tools per the [Delegation Rules](delegation-rules.md)), and an exit (state update + closing ritual). **State updates are per-step**: a subskill writes `orchestrator-state.yml` immediately after each of its steps completes — appending only the step slug actually performed, bumping `orchestrator.updated`, recording failures in `failed_phases`/`auto_fix_attempts`, and validating with `verify_template` — never as a single end-of-skill write.
|
|
17
24
|
3. **Closing ritual (handoff) → Exit Gate.** Every subskill ends with the **Exit Gate** contract, see [Gate Contract](gate-contract.md) (results box → results-acceptance question → next-step hint on accept → STOP).
|
|
18
25
|
4. **Entry checks replace phase gates in assisted mode.** A subskill invoked directly must validate the same prerequisites a phase gate would (e.g., spec exists before audit) and route to the prerequisite's command if missing — via its **Entry Gate** ([Gate Contract](gate-contract.md)).
|