Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 35 additions & 0 deletions skills/rig/samples/371-json-fixture-anonymizer.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# 371 - Json Fixture Anonymizer

```rig
import { agent, p, s, defineTool, repair } from "rig";

const anonymizeValue = defineTool("anonymizeValue", {
description: "Anonymize a field value based on the field name.",
parameters: s.object({ fieldName: s.string, value: s.string }),
handler({ fieldName, value }) {
const lower = fieldName.toLowerCase();
if (lower.includes("email")) return "redacted@example.com" as const;
if (lower.includes("name")) return "John Doe" as const;
if (lower.includes("phone")) return "XXX-XXXX" as const;
if (lower.includes("id")) return String(Math.abs(value.split("").reduce((a: number, c: string) => a + c.charCodeAt(0), 0)));
return "REDACTED" as const;
},
});

// Agent role: Read a JSON fixture file, anonymize specified fields, and write sanitized output.
const jsonFixtureAnonymizer = agent({
model: "small",
input: s.object({ inputFile: s.path, outputFile: s.path, fieldsToAnonymize: s.array(s.string) }),
instructions: p`Read ${p.readInput("inputFile")}, anonymize the fields listed in fieldsToAnonymize using the anonymizeValue tool, then write the sanitized JSON to ${p.writeInput("outputFile", "anonymizedContent")}.`,
output: s.object({
fieldsAnonymized: s.int,
totalRecords: s.int,
outputPath: s.path,
anonymizedFields: s.array(s.string),
}),
tools: [anonymizeValue],
addons: [repair()],
});

export default jsonFixtureAnonymizer;
```
30 changes: 30 additions & 0 deletions skills/rig/samples/372-csv-to-markdown-table.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# 372 - Csv To Markdown Table

```rig
import { agent, p, s, defineTool, repair } from "rig";

const parseCSVRow = defineTool("parseCSVRow", {
description: "Parse a single CSV row into an array of trimmed string values.",
parameters: s.object({ row: s.string }),
handler({ row }) {
return row.split(",").map((cell: string) => cell.trim());
},
});

// Agent role: Convert a CSV file to a Markdown table and write it to the output file.
const csvToMarkdownTable = agent({
model: "small",
input: s.object({ csvFile: s.path, outputFile: s.path, includeStats: s.boolean }),
instructions: p`Read ${p.readInput("csvFile")}, parse each row using parseCSVRow, format as a Markdown table, and write to ${p.writeInput("outputFile", "markdownContent")}. If includeStats is true, append row and column statistics.`,
output: s.object({
rowCount: s.int,
columnCount: s.int,
outputFile: s.path,
headers: s.array(s.string),
}),
tools: [parseCSVRow],
addons: [repair()],
});

export default csvToMarkdownTable;
```
29 changes: 29 additions & 0 deletions skills/rig/samples/373-toml-config-section-analyzer.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# 373 - Toml Config Section Analyzer

```rig
import { agent, p, s, defineTool, repair } from "rig";
import { readFile } from "node:fs/promises";

const analyzeTomlFile = defineTool("analyzeTomlFile", {
description: "Read a TOML file and extract its top-level section headers and key count.",
parameters: s.object({ filePath: s.path }),
async handler({ filePath }) {
const content = await readFile(filePath, "utf8");
const sections = [...content.matchAll(/^\[(\w+)\]/gm)].map((m: RegExpMatchArray) => m[1]);
const keyCount = content.split("\n").filter((l: string) => /^\w+\s*=/.test(l)).length;
const hasRequired = sections.includes("dependencies") || sections.includes("package");
return { sections, keyCount, hasRequired };
},
});

// Agent role: Discover all TOML files and analyze their section structure.
const tomlConfigAnalyzer = agent({
model: "small",
instructions: p`Analyze TOML files found at ${p.glob("**/*.toml")} using the analyzeTomlFile tool. Return results keyed by file path.`,
output: s.record(s.object({ sections: s.array(s.string), keyCount: s.int, hasRequired: s.boolean })),
tools: [analyzeTomlFile],
addons: [repair()],
});

export default tomlConfigAnalyzer;
```
35 changes: 35 additions & 0 deletions skills/rig/samples/374-git-checkpoint-summarizer.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# 374 - Git Checkpoint Summarizer

```rig
import { agent, p, s, defineTool, repair } from "rig";

const classifyCheckpoint = defineTool("classifyCheckpoint", {
description: "Classify a git checkpoint string as stash, commit, tag, or branch.",
parameters: s.object({ ref: s.string }),
handler({ ref }) {
if (ref.startsWith("stash@")) return "stash" as const;
if (/^v?\d+\.\d+/.test(ref)) return "tag" as const;
if (/^[0-9a-f]{7,40}/.test(ref.split(" ")[0])) return "commit" as const;
return "branch" as const;
},
});

// Agent role: Summarize git stash and commit checkpoints in the repository.
const gitCheckpointSummarizer = agent({
model: "small",
instructions: p`Review git checkpoints:
Stash list: ${p.bash("git stash list")}
Recent commits: ${p.bash("git log --oneline -10")}

Use classifyCheckpoint to classify each entry and return a summary.`,
output: s.object({
checkpoints: s.array(s.object({ ref: s.string, type: s.enum("stash", "commit", "tag", "branch"), message: s.string })),
latestCheckpoint: s.optional(s.string),
totalCount: s.int,
}),
tools: [classifyCheckpoint],
addons: [repair()],
});

export default gitCheckpointSummarizer;
```
33 changes: 33 additions & 0 deletions skills/rig/samples/375-ts-literal-union-extractor.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# 375 - Ts Literal Union Extractor

```rig
import { agent, p, s, defineTool, steering } from "rig";
import { readFile } from "node:fs/promises";

const extractLiteralUnions = defineTool("extractLiteralUnions", {
description: "Extract TypeScript string literal type unions from a source file.",
parameters: s.object({ filePath: s.path }),
async handler({ filePath }) {
const content = await readFile(filePath, "utf8");
const results: Record<string, { members: string[]; memberCount: number; isStringLiteral: boolean }> = {};
const regex = /type\s+(\w+)\s*=\s*((?:'[^']*'|"[^"]*")\s*(?:\|\s*(?:'[^']*'|"[^"]*")\s*)*)/g;
for (const match of content.matchAll(regex)) {
const name = match[1];
const members = [...match[2].matchAll(/['"]([^'"]+)['"]/g)].map((m: RegExpMatchArray) => m[1]);
results[name] = { members, memberCount: members.length, isStringLiteral: true };
}
return results;
},
});

// Agent role: Scan TypeScript files to find and catalog all string literal type union definitions.
const tsLiteralUnionExtractor = agent({
model: "small",
instructions: p`Find TypeScript files: ${p.bash("find . -name '*.ts' -not -path '*/node_modules/*' | head -30")}. Use extractLiteralUnions on each file to collect all string literal type unions.`,
output: s.record(s.object({ members: s.array(s.string), memberCount: s.int, isStringLiteral: s.boolean })),
tools: [extractLiteralUnions],
addons: [steering()],
});

export default tsLiteralUnionExtractor;
```
44 changes: 44 additions & 0 deletions skills/rig/samples/376-markdown-heading-validator.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# 376 - Markdown Heading Validator

```rig
import { agent, p, s, defineTool, repair } from "rig";
import { readFile } from "node:fs/promises";

const validateHeadings = defineTool("validateHeadings", {
description: "Validate Markdown heading structure in a file — check for skipped levels and multiple H1s.",
parameters: s.object({ filePath: s.path }),
async handler({ filePath }) {
const content = await readFile(filePath, "utf8");
const headings = [...content.matchAll(/^(#{1,6})\s+(.+)$/gm)].map((m: RegExpMatchArray) => ({
level: m[1].length,
text: m[2].trim(),
}));
const issues: string[] = [];
const h1Count = headings.filter((h: { level: number; text: string }) => h.level === 1).length;
if (h1Count > 1) issues.push(`Multiple H1 headings found (${h1Count})`);
for (let i = 1; i < headings.length; i++) {
if (headings[i].level > headings[i - 1].level + 1) {
issues.push(`Heading level skipped: H${headings[i - 1].level} → H${headings[i].level}`);
}
}
const maxDepth = headings.reduce((max: number, h: { level: number; text: string }) => Math.max(max, h.level), 0);
return { headings, maxDepth, isValid: issues.length === 0, issues };
},
});

// Agent role: Validate the heading structure of all Markdown files in the workspace.
const markdownHeadingValidator = agent({
model: "small",
instructions: p`Validate Markdown heading structure for files found at ${p.glob("**/*.md")}. Use validateHeadings on each file and return results keyed by file path.`,
output: s.record(s.object({
headings: s.array(s.object({ level: s.int, text: s.string })),
maxDepth: s.int,
isValid: s.boolean,
issues: s.array(s.string),
})),
tools: [validateHeadings],
addons: [repair()],
});

export default markdownHeadingValidator;
```
30 changes: 30 additions & 0 deletions skills/rig/samples/377-ts-barrel-module-writer.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# 377 - Ts Barrel Module Writer

```rig
import { agent, p, s, defineTool, repair } from "rig";

const validateExportName = defineTool("validateExportName", {
description: "Validate that a string is a valid JavaScript identifier for export.",
parameters: s.object({ name: s.string }),
handler({ name }) {
return /^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(name);
},
});

// Agent role: Generate a TypeScript barrel module that re-exports the given symbols and write it to the target file.
const tsBarrelModuleWriter = agent({
model: "small",
input: s.object({ targetFile: s.path, moduleName: s.string, exports: s.array(s.string) }),
instructions: p`Given the input targetFile, moduleName, and exports array, validate each export name using validateExportName, generate barrel export lines, and write the module to ${p.writeInput("targetFile", "moduleContent")}.`,
output: s.object({
outputFile: s.path,
exportsWritten: s.array(s.string),
moduleLines: s.int,
success: s.boolean,
}),
tools: [validateExportName],
addons: [repair()],
});

export default tsBarrelModuleWriter;
```
35 changes: 35 additions & 0 deletions skills/rig/samples/378-git-remote-metadata-inspector.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# 378 - Git Remote Metadata Inspector

```rig
import { agent, p, s, defineTool, steering } from "rig";

const classifyRemote = defineTool("classifyRemote", {
description: "Classify a git remote URL into its hosting provider.",
parameters: s.object({ url: s.string }),
handler({ url }) {
if (url.includes("github.com")) return "github" as const;
if (url.includes("gitlab.com")) return "gitlab" as const;
if (url.includes("bitbucket.org")) return "bitbucket" as const;
return "other" as const;
},
});

// Agent role: Inspect git remote metadata and classify each remote by provider.
const gitRemoteMetadataInspector = agent({
model: "small",
instructions: p`Inspect git remotes:
Remotes: ${p.bash("git remote -v")}
Branch count: ${p.bash("git ls-remote --heads origin 2>/dev/null | wc -l")}

Use classifyRemote for each remote URL and return results keyed by remote name.`,
output: s.record(s.object({
url: s.string,
type: s.enum("github", "gitlab", "bitbucket", "other"),
branchCount: s.int,
})),
tools: [classifyRemote],
addons: [steering()],
});

export default gitRemoteMetadataInspector;
```
34 changes: 34 additions & 0 deletions skills/rig/samples/379-os-env-variable-scanner.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# 379 - Os Env Variable Scanner

```rig
import { agent, p, s, defineTool, repair } from "rig";

const classifyEnvVar = defineTool("classifyEnvVar", {
description: "Classify an environment variable by its name and value into a category.",
parameters: s.object({ name: s.string, value: s.string }),
handler({ name }) {
if (name === "PATH" || name.endsWith("_PATH") || name.endsWith("_HOME")) return "path" as const;
if (name.startsWith("LANG") || name.startsWith("LC_")) return "locale" as const;
if (name === "HOME" || name === "USER" || name === "USERNAME" || name === "LOGNAME") return "home" as const;
if (name === "EDITOR" || name === "VISUAL" || name === "PAGER") return "editor" as const;
if (name === "CI" || name.startsWith("GITHUB_") || name.startsWith("RUNNER_") || name.startsWith("ACTIONS_")) return "ci" as const;
return "custom" as const;
},
});

// Agent role: Scan all OS environment variables and categorize them by type.
const osEnvVariableScanner = agent({
model: "small",
instructions: p`Scan environment variables: ${p.bash("env")}. Use classifyEnvVar on each variable and return a summary.`,
output: s.object({
vars: s.record(s.object({ value: s.string, category: s.enum("path", "locale", "home", "editor", "ci", "custom") })),
totalVars: s.int,
ciEnvCount: s.int,
customCount: s.int,
}),
tools: [classifyEnvVar],
addons: [repair()],
});

export default osEnvVariableScanner;
```
49 changes: 49 additions & 0 deletions skills/rig/samples/380-sequential-commit-classifier-workflow.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
# 380 - Sequential Commit Classifier Workflow

```rig
import { agent, workflow, p, s } from "rig";

// Agent role: Collect recent git commits from the repository.
const commitCollector = agent({
model: "small",
instructions: p`Collect recent commits: ${p.bash("git log --oneline -10")}. Return each as hash and message.`,
output: s.object({
commits: s.array(s.object({ hash: s.string, message: s.string })),
}),
});

// Agent role: Classify each commit message into a conventional commit category.
const commitClassifier = agent({
model: "small",
input: s.object({ commits: s.array(s.object({ hash: s.string, message: s.string })) }),
instructions: p`Classify each commit in the input. Return the hash and category for each.`,
output: s.array(s.object({ hash: s.string, category: s.enum("feat", "fix", "chore", "docs", "other") })),
});

// Agent role: Aggregate classified commits into a summary report.
const commitAggregator = agent({
model: "small",
input: s.array(s.object({ hash: s.string, category: s.enum("feat", "fix", "chore", "docs", "other") })),
instructions: p`Count how many commits fall into each category and identify the top category.`,
output: s.object({
summary: s.record(s.int),
totalCommits: s.int,
topCategory: s.string,
}),
});

// Workflow role: Pipeline three agents to collect, classify, and aggregate recent git commits.
export default workflow({
meta: { name: "sequential-commit-classifier", description: "Collect, classify, and aggregate recent git commits.", phases: ["Collect", "Classify", "Aggregate"] },
body: async ({ call, phase }) => {
phase("Collect");
const step1 = await call(commitCollector, "Collect recent commits.");
if (!step1) return null;
phase("Classify");
const step2 = await call(commitClassifier, { commits: step1.commits });
if (!step2) return null;
phase("Aggregate");
return call(commitAggregator, step2);
},
});
```