-
-
Notifications
You must be signed in to change notification settings - Fork 388
docs(skills): teach CLI agent orchestration #168
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,167 +1,108 @@ | ||
| --- | ||
| name: dynamic-workflows | ||
| description: Orchestrate multi-agent coding workflows via DevSpace Dynamic Workflows (CLI or MCP). | ||
| description: Run programmable multi-agent workflows through the DevSpace CLI. | ||
| --- | ||
|
|
||
| # Dynamic Workflows | ||
| # DevSpace Dynamic Workflows | ||
|
|
||
| Use this skill when the user wants multi-step, multi-agent orchestration — fan-out | ||
| review, migrate-and-verify, research panels — **not** a single subagent turn. | ||
| Use a workflow when the work benefits from a repeatable program: parallel | ||
| reviews, fan-out research, staged implementation, per-file pipelines, or a | ||
| review-and-fix loop. Use a direct subagent for one focused delegation. | ||
|
|
||
| ## Entry points | ||
| This skill is CLI-only. A coding harness should create or select a workflow | ||
| script and invoke it with `devspace workflow`. | ||
|
|
||
| | Host | Surface | | ||
| |---|---| | ||
| | Coding agent (Claude Code, Codex, pi, …) | CLI + this skill | | ||
| | ChatGPT / MCP client | MCP tools `run_workflow` / `workflow_status` / `workflow_cancel` | | ||
| ## CLI | ||
|
|
||
| ```bash | ||
| devspace workflow run --file path/to/script.js [--arg k=v]... [--follow] | ||
| devspace workflow run --script-path path/to/script.js [--resume <runId>] [--follow] | ||
| devspace workflow run --name review-auth [--follow] | ||
| devspace workflow run --resume <runId> | ||
| devspace workflow status <runId> [--follow] | ||
| devspace workflow cancel <runId> | ||
| devspace workflow run --file path/to/workflow.js [--arg key=value]... [--follow] | ||
| devspace workflow run --script-path path/to/workflow.js [--resume <run-id>] [--follow] | ||
| devspace workflow run --name <name> [--arg key=value]... [--follow] | ||
| devspace workflow status <run-id> [--follow] | ||
| devspace workflow cancel <run-id> | ||
| devspace workflow ls | ||
| devspace workflow calls <runId> | ||
| devspace workflow call <runId> <callIndex> | ||
| devspace workflow tui [runId] | ||
| devspace workflow calls <run-id> | ||
| devspace workflow call <run-id> <call-index> | ||
| ``` | ||
|
|
||
| Project named scripts live under `.devspace/workflows/<name>.js`. | ||
| Named scripts are stored in the project’s `.devspace/workflows/` directory. | ||
| Workflow commands are scoped to the current Git checkout (or the current | ||
| directory when it is not a Git project). Use `--follow` for a live terminal | ||
| handoff; otherwise poll with `status`. | ||
|
|
||
| ## Script shape | ||
| `--arg key=value` passes JSON values when the value is valid JSON and otherwise | ||
| passes a string. A failed or cancelled run can be started again with | ||
| `workflow run --resume <run-id>` after reviewing its status and call results. | ||
|
|
||
| ```js | ||
| export const meta = { | ||
| name: 'review-auth', | ||
| description: 'Fan-out review of auth changes', | ||
| phases: [{ title: 'Review' }, { title: 'Synthesize' }], | ||
| // optional DevSpace: | ||
| // defaultProvider: 'codex', | ||
| // concurrency: 4, | ||
| } | ||
| ## Script capabilities | ||
|
|
||
| phase('Review') | ||
| const findings = await parallel([ | ||
| () => agent('Review for correctness…', { label: 'correctness' }), | ||
| () => agent('Review for security…', { label: 'security' }), | ||
| ]) | ||
| phase('Synthesize') | ||
| const summary = await agent(`Synthesize: ${JSON.stringify(findings)}`) | ||
| return { summary, findings } | ||
| ``` | ||
|
|
||
| ### Primitives | ||
| Workflow scripts are JavaScript modules with a metadata export and an async | ||
| body. The orchestration API includes: | ||
|
|
||
| | API | Notes | | ||
| |---|---| | ||
| | `agent(prompt, opts?)` | Throws on failure. `opts`: `label`, `phase`, `schema`, `model`, `effort`, `profile` or `provider`, `isolation: 'worktree'` | | ||
| | `parallel(thunks)` | Barrier; throw → `null` slot | | ||
| | `pipeline(items, ...stages)` | Per-item chains; no cross-item barrier | | ||
| | `phase(title)` / `log(msg)` | Progress; journaled | | ||
| | `args` | Run input (object preferred) | | ||
| | `workflow(name\|{scriptPath}, args?)` | Nested, depth 1, shared call index | | ||
| | Capability | Use | | ||
| | --- | --- | | ||
| | `agent(prompt, options?)` | Ask one configured profile or provider to perform a unit of work. | | ||
| | `parallel(thunks)` | Run independent units together and collect their results. | | ||
| | `pipeline(items, ...stages)` | Apply the same sequence of agent stages to each item. | | ||
| | `phase(title)` | Group later work under a named stage. | | ||
| | `log(message)` | Emit progress text for the supervising harness. | | ||
| | `args` | Read values passed with `--arg`. | | ||
| | `workflow(nameOrPath, args?)` | Compose a named or project workflow as a step. | | ||
|
|
||
| **No `writeMode`.** Teach read-only vs write in the prompt. Use `isolation: 'worktree'` when parallel mutators would conflict (git required). | ||
| An `agent` can select `profile` or `provider`, and can set `label`, `phase`, | ||
| `schema`, `model`, `effort`, or `isolation: 'worktree'`. Use a profile when one | ||
| is configured; use `provider` only when the target is intentional. `profile` | ||
| and `provider` are alternatives, not a combination. | ||
|
|
||
| ### Determinism bans | ||
| The optional `schema` describes a JSON result, which is useful when later | ||
| stages consume structured findings. Prompts should say whether a child may | ||
| change files and what it should return. | ||
|
|
||
| `Date.now()`, `Math.random()`, and `new Date()` without args throw. Pass timestamps via `args` if needed. | ||
|
|
||
| ### Schema | ||
| ## Basic script | ||
|
|
||
| ```js | ||
| const out = await agent('Return JSON findings', { | ||
| schema: { | ||
| type: 'object', | ||
| properties: { bugs: { type: 'array', items: { type: 'string' } } }, | ||
| required: ['bugs'], | ||
| }, | ||
| }) | ||
| // out is validated object; engine retries ≤2 on invalid JSON | ||
| // codex/claude: native structured output first, then prompt repair; others: prompt+Ajv | ||
| ``` | ||
|
|
||
| ### Providers | ||
|
|
||
| Profiles exposed by `open_workspace` may be selected with `opts.profile`. The | ||
| profile supplies instructions, provider, model, and effort defaults; per-call | ||
| `model` and `effort` override those defaults. `profile` and `provider` are | ||
| mutually exclusive. | ||
|
|
||
| Without a profile, default provider resolution is `opts.provider` → | ||
| `meta.defaultProvider` → first currently available provider. | ||
|
|
||
| ### Resume | ||
|
|
||
| Failed and cancelled runs are terminal. Recovery creates a **new** run: | ||
|
|
||
| 1. Inspect the prior run with `workflow status`, `workflow calls`, and | ||
| `workflow call`. | ||
| 2. Edit the persisted `scriptPath` reported by the run, or pass a different | ||
| `--script-path`. | ||
| 3. Keep prompts and agent options stable for completed calls whose return values | ||
| should be reused. | ||
| 4. Run `devspace workflow run --resume <runId>` (optionally with | ||
| `--script-path <path>`). | ||
|
|
||
| Replay walks the prior run in call-index order and reuses the longest unchanged | ||
| prefix. The first failed, interrupted, changed, missing, corrupt, or unavailable | ||
| result executes live and closes replay for every later call, even when a later | ||
| cache key happens to match. Exact return values are stored separately from | ||
| bounded UI previews. | ||
|
|
||
| Replay restores an agent's **return value**, not its execution. Shared-checkout | ||
| calls assume their existing filesystem effects are still present. Worktree calls | ||
| are never reused unless their exact worktree can be restored, so they currently | ||
| end the reusable prefix and run live. | ||
|
|
||
| Return values must fit the replay budget (~1 MiB JSON). Oversized returns fail | ||
| the `agent()` call with `result_too_large` — prefer summaries or paths to large | ||
| artifacts on disk. | ||
|
|
||
| ### Cancel | ||
|
|
||
| `workflow cancel` sets a cooperative flag; worker aborts then hard-kills if needed. | ||
|
|
||
| ## When to use CLI vs MCP | ||
| export const meta = { | ||
| name: 'review-changes', | ||
| description: 'Independent correctness and security review', | ||
| } | ||
|
|
||
| - **CLI**: host agent can shell; prefer for long runs + `--follow`. | ||
| - **TUI**: `devspace workflow tui` opens a read-only live view for workflows associated with the current working directory. | ||
| - **MCP**: ChatGPT plans; call `run_workflow`, then `workflow_status` until terminal. With full widgets enabled, workflow tool cards and the `open_workspace` dashboard show read-only live activity, including workflows launched through the CLI. Disconnecting MCP does **not** kill the worker. | ||
| phase('Review') | ||
| const [correctness, security] = await parallel([ | ||
| () => agent('Review the diff for correctness bugs. Return file paths and concrete findings.', { label: 'correctness' }), | ||
| () => agent('Review the diff for security issues. Return file paths, severity, and evidence.', { label: 'security' }), | ||
| ]) | ||
|
|
||
| ## Worked mini-examples | ||
| return { correctness, security } | ||
| ``` | ||
|
|
||
| **1. Parallel review** | ||
| Run it with: | ||
|
|
||
| ```js | ||
| export const meta = { name: 'p-review', description: 'Two reviewers' } | ||
| const [a, b] = await parallel([ | ||
| () => agent('Correctness review of the diff', { label: 'corr' }), | ||
| () => agent('Security review of the diff', { label: 'sec' }), | ||
| ]) | ||
| return { a, b } | ||
| ```bash | ||
| devspace workflow run --file .devspace/workflows/review-changes.js --follow | ||
| ``` | ||
|
|
||
| **2. Pipeline with schema** | ||
| ## Structured pipeline | ||
|
|
||
| ```js | ||
| export const meta = { name: 'pipe', description: 'Find then fix plan' } | ||
| export const meta = { name: 'test-plan', description: 'Find and prioritize test gaps' } | ||
|
|
||
| return await pipeline( | ||
| args.files, | ||
| (file) => agent(`List bugs in ${file}`, { schema: { type: 'object', properties: { bugs: { type: 'array', items: { type: 'string' } } }, required: ['bugs'] } }), | ||
| (findings, file) => agent(`Plan fixes for ${file}: ${JSON.stringify(findings)}`), | ||
| (file) => agent(`Find test gaps in ${file}`, { | ||
| schema: { | ||
| type: 'object', | ||
| properties: { gaps: { type: 'array', items: { type: 'string' } } }, | ||
| required: ['gaps'], | ||
| }, | ||
| }), | ||
| (findings, file) => agent(`Prioritize these gaps for ${file}: ${JSON.stringify(findings)}`), | ||
| ) | ||
| ``` | ||
|
|
||
| **3. Isolation for parallel writers** | ||
|
|
||
| ```js | ||
| export const meta = { name: 'iso', description: 'Parallel mutators' } | ||
| await parallel([ | ||
| () => agent('Implement feature A in isolation', { isolation: 'worktree', label: 'a' }), | ||
| () => agent('Implement feature B in isolation', { isolation: 'worktree', label: 'b' }), | ||
| ]) | ||
| // dirty worktrees preserved; compose via return text / shared follow-up | ||
| ```bash | ||
| devspace workflow run --name test-plan --arg files='["src/parser.ts","src/parser.test.ts"]' --follow | ||
| ``` | ||
|
|
||
| For parallel writers, request `isolation: 'worktree'` and make the prompt | ||
| describe how the result should be handed back. For sequential edits that must | ||
| see one another’s files, keep the stages in a pipeline or ordinary sequence. | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,58 +1,87 @@ | ||
| --- | ||
| name: subagents | ||
| description: Delegate focused work to isolated DevSpace coding agents. | ||
| description: Delegate focused coding work to DevSpace subagents from a shell. | ||
| --- | ||
|
|
||
| Each subagent is headless, has its own context window, cannot see the parent conversation, cannot ask the user, and cannot spawn subagents or workflows. Give every child a self-contained prompt with paths, constraints, and the expected report. | ||
| # DevSpace subagents | ||
|
|
||
| ## Choose a target | ||
| Use a subagent for one focused piece of work: a second opinion, a narrow | ||
| investigation, a test plan, or an isolated implementation. Use a dynamic | ||
| workflow when the task needs several stages or programmable fan-out. | ||
|
|
||
| Prefer a configured profile that matches the task. Use a raw provider when the | ||
| user explicitly names that harness or no profile fits. Use target information | ||
| already available in the current host. When the choices are not known, run: | ||
| This skill uses the DevSpace CLI from any coding harness that can run shell | ||
| commands. | ||
|
|
||
| ## Discover available targets | ||
|
|
||
| Run this before choosing a profile or provider when the available targets are | ||
| not already known: | ||
|
|
||
| ```bash | ||
| devspace agents targets | ||
| devspace agents targets --json | ||
| ``` | ||
|
|
||
| Do not guess profile names or provider identifiers. | ||
| Configured profiles are preferred because they provide a reusable description | ||
| and defaults. A raw provider is useful when the user names a specific harness | ||
| or no matching profile exists. Do not guess a profile name. | ||
|
|
||
| ## Write the brief | ||
| ## Start and inspect work | ||
|
|
||
| ```bash | ||
| devspace agents run <profile-or-provider> "<self-contained brief>" | ||
| devspace agents show <agent-id> | ||
| devspace agents ls | ||
| ``` | ||
|
|
||
| Describe the task directly. Include decisions and constraints that exist only | ||
| in the parent conversation. Mention relevant paths or scope when useful. Do not | ||
| repeat project instructions that the child can discover from the repository. | ||
| The `run` command returns an agent id immediately. Use `show` to wait for the | ||
| final response or to read a later update. `ls` lists sessions for the current | ||
| project scope. Running the command from a subdirectory uses the enclosing Git | ||
| checkout; a non-Git directory uses the current directory. | ||
|
|
||
| ## Run and continue | ||
| To continue the same session, use its id as the target: | ||
|
|
||
| ```bash | ||
| devspace agents targets [--json] | ||
| devspace agents run <profile-or-provider> "<brief>" | ||
| devspace agents show <id> | ||
| devspace agents run <id> "<follow-up>" | ||
| devspace agents ls | ||
| devspace agents run <agent-id> "Follow up by checking the failing test and report the cause." | ||
| ``` | ||
|
|
||
| `targets` lists currently usable profiles and providers. `run` with a profile | ||
| or provider starts a child and returns its id. `show` reads its latest status | ||
| and response. `run` with an existing id continues the same child session. `ls` | ||
| lists sessions for the current project. | ||
| ## Write a useful brief | ||
|
|
||
| Give the child everything it needs without relying on the parent conversation: | ||
|
|
||
| Do not invoke provider CLIs directly; use `devspace agents` so DevSpace keeps | ||
| session and provider handling consistent. | ||
| - the exact goal and expected output; | ||
| - relevant files, commands, or boundaries; | ||
| - whether it may modify files; | ||
| - the checks it should run before reporting back. | ||
|
|
||
| ## Model and effort overrides | ||
| The child’s final response is the handoff. Ask for concise findings, paths, or | ||
| patch-ready changes rather than a broad narrative. | ||
|
|
||
| Normally omit `--model` and `--effort`. When an exact override is needed, read | ||
| `references/<provider>.md` first. Do not guess values or transfer an effort | ||
| name between providers merely because both use the same word. | ||
| ## Optional model controls | ||
|
|
||
| Profiles normally supply model and effort defaults. When an exact override is | ||
| needed, pass: | ||
|
|
||
| ```bash | ||
| devspace agents run <target> --model <model> --effort <effort> "<brief>" | ||
| devspace agents run <target> --model <model> --effort <level> "<brief>" | ||
| ``` | ||
|
|
||
| ## Direct subagent or workflow | ||
| Only use values supplied by the user, a configured profile, or the target | ||
| catalog. Omit overrides when the provider’s accepted values are unknown. | ||
|
|
||
| ## Common uses | ||
|
|
||
| ```bash | ||
| # Ask for an independent security review. | ||
| devspace agents run reviewer "Review the authentication changes for vulnerabilities. Return findings with file paths and severity." | ||
|
|
||
| # Delegate a small implementation and ask for verification. | ||
| devspace agents run implementer "Add a regression test for the parser bug. Run the focused test and report the result." | ||
|
|
||
| # Continue after the parent has inspected the first response. | ||
| devspace agents run agt_1234abcd "The test still fails on Windows. Investigate only the path handling and report a fix." | ||
| ``` | ||
|
Comment on lines
+74
to
+83
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win 🧩 Analysis chain🏁 Script executed: #!/usr/bin/env bash
set -euo pipefail
rg -n -C 3 \
'reviewer|implementer|default.*profile|profiles' \
--glob '*.json' --glob '*.yaml' --glob '*.yml' --glob '*.md' .Repository: Waishnav/devspace Length of output: 22297 🏁 Script executed: #!/usr/bin/env bash
set -euo pipefail
printf '--- focused search for reviewer/implementer in src ---\n'
rg -n '\'?reviewer\'?|\'?implementer\'?|DEVSPACE_AGENT|agent profile|agents run|targets' src docs tools bin scripts --glob '*.ts' --glob '*.js' --glob '*.mjs' --glob '*.cjs' --glob '*.json' || true
printf '\n--- package scripts/package manager files ---\n'
cat package.json | sed -n '1,80p'
git ls-files | sed -n '1,120p'
printf '\n--- subagent skill relevant lines ---\n'
cat -n skills/subagents/SKILL.md | sed -n '1,110p'Repository: Waishnav/devspace Length of output: 246 🏁 Script executed: #!/usr/bin/env bash
set -euo pipefail
printf '%s\n' '--- focused search for reviewer/implementer in src ---'
rg -- \
'\'?reviewer\'?|\'?implementer\'?|DEVSPACE_AGEN|agent profile|agents run|targets' \
src docs tools bin scripts --glob '*.ts' --glob '*.js' --glob '*.mjs' --glob '*.cjs' --glob '*.json' || true
printf '%s\n' ''
printf '%s\n' '--- package scripts/package manager files ---'
sed -n '1,80p' package.json
git ls-files | sed -n '1,160p'
printf '%s\n' ''
printf '%s\n' '--- subagent skill relevant lines ---'
cat -n skills/subagents/SKILL.md | sed -n '1,110p'Repository: Waishnav/devspace Length of output: 271 🏁 Script executed: #!/usr/bin/env bash
set -euo pipefail
printf '%s\n' '--- focused search for reviewer/implementer in src ---'
rg -n -S -- \
"reviewer|implementer|DEVSPACE_AGEN|agent profile|agents run|targets" \
src docs tools bin scripts --glob '*.ts' --glob '*.js' --glob '*.mjs' --glob '*.cjs' --glob '*.json' || true
printf '%s\n' ''
printf '%s\n' '--- package scripts/package manager files ---'
sed -n '1,80p' package.json
git ls-files | sed -n '1,160p'
printf '%s\n' ''
printf '%s\n' '--- subagent skill relevant lines ---'
cat -n skills/subagents/SKILL.md | sed -n '1,110p'Repository: Waishnav/devspace Length of output: 27538 🏁 Script executed: #!/usr/bin/env bash
set -euo pipefail
printf '%s\n' '--- example agent profiles ---'
for f in examples/agents/*.md; do
echo "--- $f"
sed -n '1,8p' "$f"
done
printf '%s\n' ''
printf '%s\n' '--- subagent skill reference files names only ---'
git ls-files 'skills/subagents/references/*.md'
printf '%s\n' ''
printf '%s\n' '--- source resolution for unknown subagent ---'
sed -n '55,85p' src/local-agent-resolution.tsRepository: Waishnav/devspace Length of output: 3746 Use configured profile names in copy-paste examples.
🤖 Prompt for AI Agents |
||
|
|
||
| Use a direct subagent for one focused delegation or a follow-up with the same | ||
| child. Use a dynamic workflow when the task needs programmed fan-out, stages, | ||
| branching, nesting, or replay. | ||
| Keep direct delegation to one focused child at a time. For independent | ||
| reviewers, staged implementation, or repeatable fan-out, use the | ||
| `dynamic-workflows` skill. | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,20 +1,9 @@ | ||
| # Claude overrides | ||
| # Claude target options | ||
|
|
||
| DevSpace passes `--model` to the Claude Agent SDK. When `--effort` is present, | ||
| DevSpace passes the SDK effort value with adaptive thinking enabled. | ||
|
|
||
| The SDK effort vocabulary is: | ||
|
|
||
| - `low` | ||
| - `medium` | ||
| - `high` | ||
| - `xhigh` | ||
| - `max` | ||
|
|
||
| Support is model-dependent. Some Claude models expose only part of this set or | ||
| do not support the effort option. Prefer configured defaults and omit an | ||
| override when the selected model's capability is unknown. | ||
| Use the configured profile defaults whenever possible. Model and effort values | ||
| are installation- and model-dependent; pass an override only when the user or | ||
| the target catalog provides the exact value. | ||
|
|
||
| ```bash | ||
| devspace agents run claude --model <model> --effort <supported-level> "<brief>" | ||
| devspace agents run claude --model <known-model> --effort <known-effort> "<brief>" | ||
| ``` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
Repository: Waishnav/devspace
Length of output: 50374
🏁 Script executed:
Repository: Waishnav/devspace
Length of output: 47212
Document how dirty worktrees exit the workflow.
isolation: 'worktree'creates a detached worktree, and DevSpace only returns the worktree path without merging changes into the parent checkout. Tell workflows to return the worktree path and handle checkout merging/error handling at the call site.🤖 Prompt for AI Agents
Source: Coding guidelines