docs(writing-agent-relay-workflows): rewrite + add GitHub primitive#23
docs(writing-agent-relay-workflows): rewrite + add GitHub primitive#23khaliqgant wants to merge 1 commit intomainfrom
Conversation
… + add GitHub primitive Trims the skill from 1024 to 485 lines while inlining the critical examples (test-fix-rerun, lead + workers, cross-repo with createGitHubStep, verify gates table, parallelism/waves). Prior version was bloated, had zero mention of the bundled GitHub primitive, and duplicated content that now lives on the public docs. Changes: - Add GitHub primitive section (bundled with SDK — `@agent-relay/sdk/github`) with a full end-to-end cross-repo workflow (worktree → edit → PR via createGitHubStep → cleanup). - Deep-link to `agentrelay.com/docs/markdown/*.md` endpoints for the long tail — agent-navigable via WebFetch, no HTML chrome. - Full verification types table (exit_code, file_exists, output_contains, custom) with the silent-fallthrough warning. - Pair with relay-80-100-workflow + choosing-swarm-patterns skills, with install instructions for both prpm and skills.sh. - Correct `--sync-code` semantics: git ls-files + working-tree contents; staging is enough, commit optional; no clone fallback. Bumps version to 2.0.0 (breaking in the sense that the structure is reorganized — existing references to section names will need updating). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
| .step('open-pr', createGitHubStep({ | ||
| action: 'createPR', | ||
| repo: 'org/other-repo', | ||
| params: { head: 'feat-x', base: 'main', title: 'feat: x', body: 'Linked PR.' }, | ||
| output: { mode: 'data', format: 'json' }, | ||
| })) |
There was a problem hiding this comment.
🔴 Cross-repo example: open-pr step missing dependsOn: ['push-branch'] causes DAG race
In the cross-repo workflow example, the open-pr step (line 315) has no dependsOn clause. In a DAG workflow, steps without dependsOn start immediately. This means open-pr will attempt to create a PR before push-branch has pushed the feat-x branch to the remote — the branch won't exist on GitHub yet, so the createPR call will fail.
Every other step in this example correctly chains via dependsOn (install-sibling → setup-worktree, edit-sibling → install-sibling, push-branch → edit-sibling, print-pr-url → open-pr), but open-pr itself is missing the link to push-branch. Since this is a reference example that agents copy, it will produce broken cross-repo workflows.
| .step('open-pr', createGitHubStep({ | |
| action: 'createPR', | |
| repo: 'org/other-repo', | |
| params: { head: 'feat-x', base: 'main', title: 'feat: x', body: 'Linked PR.' }, | |
| output: { mode: 'data', format: 'json' }, | |
| })) | |
| .step('open-pr', createGitHubStep({ | |
| action: 'createPR', | |
| repo: 'org/other-repo', | |
| dependsOn: ['push-branch'], | |
| params: { head: 'feat-x', base: 'main', title: 'feat: x', body: 'Linked PR.' }, | |
| output: { mode: 'data', format: 'json' }, | |
| })) |
Was this helpful? React with 👍 or 👎 to provide feedback.
| await workflow('ship-readme') | ||
| .agent('writer', { cli: 'claude' }) | ||
|
|
||
| .step('read-readme', createGitHubStep({ | ||
| action: 'readFile', | ||
| repo: 'AgentWorkforce/relay', | ||
| params: { path: 'README.md' }, | ||
| output: { mode: 'data', format: 'text' }, | ||
| })) | ||
|
|
||
| .step('edit', { | ||
| agent: 'writer', | ||
| dependsOn: ['read-readme'], | ||
| task: `Current README:\n{{steps.read-readme.output}}\nClean up the intro.`, | ||
| }) | ||
|
|
||
| 1. **Deterministic verification** — `exit_code`, `file_exists`, `output_contains` pass → immediate completion | ||
| 2. **Owner decision** — `OWNER_DECISION: COMPLETE|INCOMPLETE_RETRY|INCOMPLETE_FAIL` | ||
| 3. **Evidence-based** — channel signals, file artifacts, clean exit code | ||
| 4. **Marker fast-path** — `STEP_COMPLETE:<step-name>` (optional accelerator) | ||
| 5. **Process-exit fallback** — agent exits 0 with no signals → completes after grace period | ||
| .step('open-pr', createGitHubStep({ | ||
| action: 'createPR', | ||
| repo: 'AgentWorkforce/relay', | ||
| params: { head: 'docs/readme-cleanup', base: 'main', title: 'docs: cleanup', body: '...' }, | ||
| })) | ||
|
|
||
| **Key principle:** No single signal is mandatory. Describe the deliverable, not what to print. | ||
| .run({ cwd: process.cwd() }); |
There was a problem hiding this comment.
🔴 GitHub primitive example uses bare top-level await, contradicting the skill's own non-negotiable rule #1
Line 77 defines non-negotiable rule #1: "Wrap in async function main() — not raw top-level await. Executor-driven files sometimes run as CJS." However, the GitHub primitive example at line 223 uses bare await workflow('ship-readme')...run(...) at the top level with no main() wrapper and no .catch() handler. An agent following this example will produce workflow files that break in CJS executor environments — the exact failure this rule exists to prevent.
| await workflow('ship-readme') | |
| .agent('writer', { cli: 'claude' }) | |
| .step('read-readme', createGitHubStep({ | |
| action: 'readFile', | |
| repo: 'AgentWorkforce/relay', | |
| params: { path: 'README.md' }, | |
| output: { mode: 'data', format: 'text' }, | |
| })) | |
| .step('edit', { | |
| agent: 'writer', | |
| dependsOn: ['read-readme'], | |
| task: `Current README:\n{{steps.read-readme.output}}\nClean up the intro.`, | |
| }) | |
| 1. **Deterministic verification** — `exit_code`, `file_exists`, `output_contains` pass → immediate completion | |
| 2. **Owner decision** — `OWNER_DECISION: COMPLETE|INCOMPLETE_RETRY|INCOMPLETE_FAIL` | |
| 3. **Evidence-based** — channel signals, file artifacts, clean exit code | |
| 4. **Marker fast-path** — `STEP_COMPLETE:<step-name>` (optional accelerator) | |
| 5. **Process-exit fallback** — agent exits 0 with no signals → completes after grace period | |
| .step('open-pr', createGitHubStep({ | |
| action: 'createPR', | |
| repo: 'AgentWorkforce/relay', | |
| params: { head: 'docs/readme-cleanup', base: 'main', title: 'docs: cleanup', body: '...' }, | |
| })) | |
| **Key principle:** No single signal is mandatory. Describe the deliverable, not what to print. | |
| .run({ cwd: process.cwd() }); | |
| async function main() { | |
| await workflow('ship-readme') | |
| .agent('writer', { cli: 'claude' }) | |
| .step('read-readme', createGitHubStep({ | |
| action: 'readFile', | |
| repo: 'AgentWorkforce/relay', | |
| params: { path: 'README.md' }, | |
| output: { mode: 'data', format: 'text' }, | |
| })) | |
| .step('edit', { | |
| agent: 'writer', | |
| dependsOn: ['read-readme'], | |
| task: `Current README:\n{{steps.read-readme.output}}\nClean up the intro.`, | |
| }) | |
| .step('open-pr', createGitHubStep({ | |
| action: 'createPR', | |
| repo: 'AgentWorkforce/relay', | |
| params: { head: 'docs/readme-cleanup', base: 'main', title: 'docs: cleanup', body: '...' }, | |
| })) | |
| .run({ cwd: process.cwd() }); | |
| } | |
| main().catch((e) => { console.error(e); process.exit(1); }); |
Was this helpful? React with 👍 or 👎 to provide feedback.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: a4982dc79e
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| | Rule | Why | | ||
| |---|---| | ||
| | No `_` in YAML numbers (`1_200_000`) | YAML doesn't support them | | ||
| | `grep -Eq "a\|b\|c"` not `grep "a\|b\|c"` | Basic alternation misbehaves silently | |
There was a problem hiding this comment.
Remove escaped pipes from grep -E example
With grep -E, escaped pipes are treated as literal | characters, so grep -Eq "a\|b\|c" only matches the exact string a|b|c rather than any of a, b, or c. Workflows copied from this rule will produce false verification failures whenever they expect alternation matching in final gates. This should use unescaped alternation (for example, grep -Eq "a|b|c").
Useful? React with 👍 / 👎.
Summary
Rewrites the
writing-agent-relay-workflowsskill to pair with the public docs at agentrelay.com and surface the bundled GitHub primitive. Trims from 1024 → 485 lines while adding inline examples for the patterns agents actually use.What changed
@agent-relay/sdk—createGitHubStepfrom/githubsubpath). Prior version had zero mention of it.createGitHubStep→ PR URL echo → cleanup.dependsOn, within-workflow parallelism (BAD/GOOD), wave-based cross-workflow parallelism.exit_code/file_exists/output_contains/customexamples and the silent-fallthrough warning.agentrelay.com/docs/markdown/*.mdendpoints — agent-navigable via WebFetch with no HTML chrome.prpmandskills.sh, covering the three workflow-authoring skills (this one,relay-80-100-workflow,choosing-swarm-patterns).--sync-codesemantics: git ls-files + working-tree contents; staging is enough, commit optional; no clone fallback.Version bump
1.5.1→2.0.0inprpm.json. The structure is reorganized enough that any consumer referencing specific section anchors will need to update.Why now
The docs at agentrelay.com/docs are the canonical source of truth for the Builder API, full 24-pattern catalog, and every GitHub action. The skill's job is to tell an agent when to use what and what not to do — it shouldn't duplicate the reference. At the same time, an agent running in a sandbox without WebFetch needs the 80% case inline, which this version delivers.
Test plan
agentrelay.com/docs/markdown/*.mdlinks resolvecreateGitHubStepexample matches the signature in@agent-relay/sdk/githubnpx prpm install @agent-relay/writing-agent-relay-workflows@2.0.0 --as claudeand run a sample workflow-authoring prompt🤖 Generated with Claude Code