From e75b23d7e5626a6b7b647710a42237028b02d735 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 9 Oct 2026 14:03:57 +0000 Subject: [PATCH] =?UTF-8?q?Add=2010=20rig=20samples=20=E2=80=94=202026-10-?= =?UTF-8?q?09?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add rig sample programs demonstrating commit classification, tsconfig validation, repair/timeout/steering addons, sequential and parallel workflow composition, glob-based subagent fan-out, p.write side effects, and a pure-logic custom tool. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .../rig/samples/531-commit-type-classifier.md | 18 ++++++ .../samples/532-tsconfig-deep-validator.md | 22 +++++++ .../samples/533-repair-addon-strict-output.md | 21 +++++++ .../samples/534-healthcheck-timeout-status.md | 20 +++++++ .../samples/535-lint-test-gate-workflow.md | 60 +++++++++++++++++++ skills/rig/samples/536-glob-tagger-fanout.md | 28 +++++++++ .../samples/537-line-count-report-writer.md | 23 +++++++ .../rig/samples/538-semver-satisfies-tool.md | 48 +++++++++++++++ .../539-todo-fixme-parallel-workflow.md | 50 ++++++++++++++++ .../samples/540-steering-nullable-commit.md | 22 +++++++ 10 files changed, 312 insertions(+) create mode 100644 skills/rig/samples/531-commit-type-classifier.md create mode 100644 skills/rig/samples/532-tsconfig-deep-validator.md create mode 100644 skills/rig/samples/533-repair-addon-strict-output.md create mode 100644 skills/rig/samples/534-healthcheck-timeout-status.md create mode 100644 skills/rig/samples/535-lint-test-gate-workflow.md create mode 100644 skills/rig/samples/536-glob-tagger-fanout.md create mode 100644 skills/rig/samples/537-line-count-report-writer.md create mode 100644 skills/rig/samples/538-semver-satisfies-tool.md create mode 100644 skills/rig/samples/539-todo-fixme-parallel-workflow.md create mode 100644 skills/rig/samples/540-steering-nullable-commit.md diff --git a/skills/rig/samples/531-commit-type-classifier.md b/skills/rig/samples/531-commit-type-classifier.md new file mode 100644 index 0000000..d148359 --- /dev/null +++ b/skills/rig/samples/531-commit-type-classifier.md @@ -0,0 +1,18 @@ +# 531 - Commit Type Classifier + +```rig +import { agent, p, s } from "rig"; + +// Agent role: classify recent commit subjects into conventional-commit types. +const classifyCommits = agent({ + model: "small", + instructions: p`Classify each commit subject from ${p.bash("git log --oneline -n 30 --pretty=format:'%s'")} + into a conventional-commit type and group subjects by type.`, + output: s.record( + s.array(s.string), + "commit subjects grouped by conventional-commit type", + ), +}); + +export default classifyCommits; +``` diff --git a/skills/rig/samples/532-tsconfig-deep-validator.md b/skills/rig/samples/532-tsconfig-deep-validator.md new file mode 100644 index 0000000..939de77 --- /dev/null +++ b/skills/rig/samples/532-tsconfig-deep-validator.md @@ -0,0 +1,22 @@ +# 532 - Tsconfig Deep Validator + +```rig +import { agent, p, s } from "rig"; + +// Agent role: validate tsconfig.json compiler options and report issues. +const validateTsconfig = agent({ + model: "small", + instructions: p`Validate ${p.read("tsconfig.json")} and report whether strict mode + is enabled, the configured target, whether path mappings are configured, the + path mappings themselves if present, and any validation issues found.`, + output: s.object({ + hasStrict: s.boolean, + target: s.optional(s.string), + pathsConfigured: s.boolean, + pathMappings: s.optional(s.record(s.array(s.string))), + issues: s.array(s.string), + }), +}); + +export default validateTsconfig; +``` diff --git a/skills/rig/samples/533-repair-addon-strict-output.md b/skills/rig/samples/533-repair-addon-strict-output.md new file mode 100644 index 0000000..1230647 --- /dev/null +++ b/skills/rig/samples/533-repair-addon-strict-output.md @@ -0,0 +1,21 @@ +# 533 - Repair Addon Strict Output + +```rig +import { agent, p, repair, s } from "rig"; + +// Agent role: assess working tree status and return a risk verdict. +const assessStatus = agent({ + model: "small", + maxTurns: 6, + instructions: p`Review ${p.bash("git status --short")} and return a concise summary, + an overall risk level, and concrete action items.`, + output: s.object({ + summary: s.string, + riskLevel: s.enum("low", "medium", "high"), + actionItems: s.array(s.string), + }), + addons: repair(), +}); + +export default assessStatus; +``` diff --git a/skills/rig/samples/534-healthcheck-timeout-status.md b/skills/rig/samples/534-healthcheck-timeout-status.md new file mode 100644 index 0000000..20a6389 --- /dev/null +++ b/skills/rig/samples/534-healthcheck-timeout-status.md @@ -0,0 +1,20 @@ +# 534 - Healthcheck Timeout Status + +```rig +import { agent, p, s, timeout } from "rig"; + +// Agent role: run a health-check command and report its status within a time budget. +const healthCheck = agent({ + model: "small", + instructions: p`Run ${p.bash("node --version")} as a health-check probe. Report + "ok" if it succeeded, "error" if it failed, or "timeout" if it did not + complete, along with the approximate duration in milliseconds.`, + output: s.object({ + status: s.enum("ok", "timeout", "error"), + durationMs: s.number, + }), + addons: timeout({ timeout: 15_000 }), +}); + +export default healthCheck; +``` diff --git a/skills/rig/samples/535-lint-test-gate-workflow.md b/skills/rig/samples/535-lint-test-gate-workflow.md new file mode 100644 index 0000000..610f307 --- /dev/null +++ b/skills/rig/samples/535-lint-test-gate-workflow.md @@ -0,0 +1,60 @@ +# 535 - Lint Test Gate Workflow + +```rig +import { agent, p, s, workflow } from "rig"; + +const checkResult = s.object({ + passed: s.boolean, + issues: s.array(s.string), +}); + +// Agent role: run a typecheck-style lint pass and report issues. +const lintCheck = agent({ + model: "small", + instructions: p`Run ${p.bash("npx tsc --noEmit")} and report whether it passed + and list any issues found.`, + output: checkResult, +}); + +// Agent role: run the test suite and report issues. +const testCheck = agent({ + model: "small", + instructions: p`Run ${p.bash("npx vitest run")} and report whether it passed + and list any issues found.`, + output: checkResult, +}); + +// Agent role: combine lint and test results into an approval decision. +const gate = agent({ + model: "small", + input: s.object({ lint: checkResult, test: checkResult }), + instructions: + "Given input.lint and input.test, decide whether to approve or block, and explain why.", + output: s.object({ + decision: s.enum("approved", "blocked"), + reasons: s.array(s.string), + }), +}); + +// Workflow role: sequentially gate changes on lint and test results. +const releaseGate = workflow({ + meta: { + name: "release-gate", + description: "Chain lint-check and test-check results into a gate decision", + phases: ["Lint", "Test", "Gate"], + }, + body: async ({ call, phase }) => { + phase("Lint"); + const lint = await call(lintCheck, ""); + phase("Test"); + const test = await call(testCheck, ""); + phase("Gate"); + return call(gate, { + lint: lint ?? { passed: false, issues: ["lint check failed to run"] }, + test: test ?? { passed: false, issues: ["test check failed to run"] }, + }); + }, +}); + +export default releaseGate; +``` diff --git a/skills/rig/samples/536-glob-tagger-fanout.md b/skills/rig/samples/536-glob-tagger-fanout.md new file mode 100644 index 0000000..2581300 --- /dev/null +++ b/skills/rig/samples/536-glob-tagger-fanout.md @@ -0,0 +1,28 @@ +# 536 - Glob Tagger Fanout + +```rig +import { agent, p, s } from "rig"; + +// Agent role: assign a topical tag to a single source file. +const tagger = agent({ + model: "small", + input: s.object({ path: s.path }), + instructions: p`Read ${p.readInput("path")} and assign the single most fitting tag.`, + output: s.object({ + path: s.path, + tag: s.enum("test", "schema", "engine", "prompt", "utility", "other"), + }), +}); + +// Agent role: discover source files, delegate tagging, and aggregate by tag. +const coordinator = agent({ + model: "small", + agents: { tagger }, + instructions: p`Find source files with ${p.glob("src/**/*.ts")}. For each + discovered path, delegate to tagger, then return a record mapping each + tag to the list of file paths assigned that tag.`, + output: s.record(s.array(s.path), "file paths grouped by assigned tag"), +}); + +export default coordinator; +``` diff --git a/skills/rig/samples/537-line-count-report-writer.md b/skills/rig/samples/537-line-count-report-writer.md new file mode 100644 index 0000000..7f46799 --- /dev/null +++ b/skills/rig/samples/537-line-count-report-writer.md @@ -0,0 +1,23 @@ +# 537 - Line Count Report Writer + +```rig +import { agent, p, s } from "rig"; + +// Agent role: count lines per TypeScript source file and write a markdown report. +const lineCountReport = agent({ + model: "small", + instructions: p`Run ${p.bash("find src -name '*.ts' -exec wc -l {} +")} to get + per-file line counts. Compose a markdown report summarizing the counts per + file and the total, then ${p.writeOutput("report", "/tmp/gh-aw/agent/line-count-report.md")}. + Return the report path, the total line count across all files, and the + number of files counted.`, + output: s.object({ + report: s.string, + reportPath: s.path, + totalLines: s.int, + fileCount: s.int, + }), +}); + +export default lineCountReport; +``` diff --git a/skills/rig/samples/538-semver-satisfies-tool.md b/skills/rig/samples/538-semver-satisfies-tool.md new file mode 100644 index 0000000..43a279b --- /dev/null +++ b/skills/rig/samples/538-semver-satisfies-tool.md @@ -0,0 +1,48 @@ +# 538 - Semver Satisfies Tool + +```rig +import { agent, defineTool, p, s } from "rig"; + +// Tool: check whether a version satisfies a minimum-version range like ">=1.0.0". +const checkSemverSatisfies = defineTool("check_semver_satisfies", { + description: "Check whether a semantic version satisfies a minimum-version range.", + parameters: s.object({ + version: s.string, + range: s.string, + }), + handler: async ({ version, range }: { version: string; range: string }) => { + const parse = (v: string) => + v + .replace(/^[^0-9]*/, "") + .split(".") + .map((part: string) => Number.parseInt(part, 10) || 0); + const match = range.match(/^>=\s*([\d.]+)/); + if (!match) return { satisfies: false }; + const [vMajor, vMinor, vPatch] = parse(version); + const [rMajor, rMinor, rPatch] = parse(match[1]); + const satisfies = + vMajor > rMajor || + (vMajor === rMajor && vMinor > rMinor) || + (vMajor === rMajor && vMinor === rMinor && vPatch >= rPatch); + return { satisfies }; + }, +}); + +// Agent role: check each package.json dependency against a minimum-version range. +const dependencyRangeCheck = agent({ + model: "small", + instructions: p`Read ${p.read("package.json")} and list its dependencies. For + each dependency, call check_semver_satisfies with its declared version and + range ">=1.0.0", then return the combined results.`, + tools: [checkSemverSatisfies], + output: s.array( + s.object({ + name: s.string, + version: s.string, + satisfiesRange: s.boolean, + }), + ), +}); + +export default dependencyRangeCheck; +``` diff --git a/skills/rig/samples/539-todo-fixme-parallel-workflow.md b/skills/rig/samples/539-todo-fixme-parallel-workflow.md new file mode 100644 index 0000000..e1878ca --- /dev/null +++ b/skills/rig/samples/539-todo-fixme-parallel-workflow.md @@ -0,0 +1,50 @@ +# 539 - Todo Fixme Parallel Workflow + +```rig +import { agent, p, s, workflow } from "rig"; + +// Agent role: count TODO comments across the repository. +const countTodos = agent({ + model: "small", + instructions: p`Run ${p.bash("grep -ro 'TODO' src/ | wc -l")} and return the count.`, + output: s.object({ count: s.int }), +}); + +// Agent role: count FIXME comments across the repository. +const countFixmes = agent({ + model: "small", + instructions: p`Run ${p.bash("grep -ro 'FIXME' src/ | wc -l")} and return the count.`, + output: s.object({ count: s.int }), +}); + +// Agent role: combine TODO and FIXME counts into a total. +const aggregate = agent({ + model: "small", + input: s.object({ todoCount: s.int, fixmeCount: s.int }), + instructions: "Combine input.todoCount and input.fixmeCount into a total.", + output: s.object({ todoCount: s.int, fixmeCount: s.int, total: s.int }), +}); + +// Workflow role: count TODO and FIXME comments in parallel, then aggregate. +const commentAudit = workflow({ + meta: { + name: "comment-audit", + description: "Count TODO and FIXME comments in parallel and aggregate totals", + phases: ["Count", "Aggregate"], + }, + body: async ({ call, parallel, phase }) => { + phase("Count"); + const [todo, fixme] = await parallel([ + () => call(countTodos, ""), + () => call(countFixmes, ""), + ]); + phase("Aggregate"); + return call(aggregate, { + todoCount: todo?.count ?? 0, + fixmeCount: fixme?.count ?? 0, + }); + }, +}); + +export default commentAudit; +``` diff --git a/skills/rig/samples/540-steering-nullable-commit.md b/skills/rig/samples/540-steering-nullable-commit.md new file mode 100644 index 0000000..224bd27 --- /dev/null +++ b/skills/rig/samples/540-steering-nullable-commit.md @@ -0,0 +1,22 @@ +# 540 - Steering Nullable Commit + +```rig +import { agent, p, repair, s, steering } from "rig"; + +// Agent role: report the most recent commit message, or null if there is none. +const lastCommit = agent({ + model: "small", + maxTurns: 4, + instructions: p`Run ${p.bash("git log -n 1 --pretty=format:'%s'")}. If the + output is empty, return null for lastCommitMessage and 0 for commitCount. + Otherwise return the commit subject as lastCommitMessage and 1 for + commitCount.`, + output: s.object({ + lastCommitMessage: s.nullable(s.string), + commitCount: s.int, + }), + addons: [steering(), repair()], +}); + +export default lastCommit; +```