diff --git a/landing/index.html.bak b/landing/index.html.bak new file mode 100644 index 00000000..493265b8 --- /dev/null +++ b/landing/index.html.bak @@ -0,0 +1,312 @@ + + + + + + Antfarm — Build your agent team with one command + + + + + + + + + + + + + + + + + + + +
+
+ + Antfarm + + +
+
+ +
+ +
+
+ +

Build your agent team in OpenClaw with one command

+
+

You don't need to hire a dev team. You need to define one. Antfarm gives you a team of specialized AI agents — planner, developer, verifier, tester, reviewer — that work together in reliable, repeatable workflows. One install. Zero infrastructure.

+
+ +
+

Antfarm gives you a team of agents that specialize, verify each other, and run the same playbook every time.

+
+
+
+ $ curl -fsSL https://raw.githubusercontent.com/snarktank/antfarm/v0.5.1/scripts/install.sh | bash +
+ + v0.5.1 +
+

Paste in your terminal, or just ask your OpenClaw to run it.

+
+
+ + +
+

What you get: Agent team workflows

+
+
+
+

feature-dev

+ 6 agents +
+

Drop in a feature request. Get back a tested PR. The planner decomposes your task into stories. Each story gets implemented, verified, and tested in isolation. Failures retry automatically. Nothing ships without a code review.

+
+ plan + setup + implement + verify + test + PR + review +
+
+
+
+

security-audit

+ 7 agents +
+

Point it at a repo. Get back a security fix PR with regression tests. Scans for vulnerabilities, ranks by severity, patches each one, re-audits after all fixes are applied.

+
+ scan + prioritize + setup + fix + verify + test + PR +
+
+
+
+

bug-fix

+ 6 agents +
+

Paste a bug report. Get back a fix with a regression test. Triager reproduces it, investigator finds root cause, fixer patches, verifier confirms. Zero babysitting.

+
+ triage + investigate + setup + fix + verify + PR +
+
+
+
+ + +
+

Why it works

+
+
+

Deterministic workflows

+

Same workflow, same steps, same order. Not "hopefully the agent remembers to test."

+
+
+

Agents verify each other

+

The developer doesn't mark their own homework. A separate verifier checks every story against acceptance criteria.

+
+
+

Fresh context, every step

+

Each agent gets a clean session. No context window bloat. No hallucinated state from 50 messages ago.

+
+
+

Automatic retries

+

Failed steps retry automatically with configurable limits per step. The medic watches for stuck agents and cleans up abandoned work.

+
+
+
+ + +
+

How it works

+
+
+
1
+

Define

+

Agents and steps in YAML. Each agent gets a persona, workspace, and strict acceptance criteria. No ambiguity about who does what.

+
+
+
2
+

Install

+

One command provisions everything: agent workspaces, cron polling, subagent permissions. No Docker, no queues, no external services.

+
+
+
3
+

Run

+

Agents poll for work independently. Claim a step, do the work, pass context to the next agent. SQLite tracks state. Cron keeps it moving.

+
+
+
+ + +
+

Minimal by design

+

YAML + SQLite + cron. That's it. No Redis, no Kafka, no container orchestrator. Antfarm is a TypeScript CLI with zero external dependencies. It runs wherever OpenClaw runs.

+
+ + +
+
+ Ralph +
+

Built on the Ralph loop

+

Each agent runs in a fresh session with clean context. Memory persists through git history and progress files — the same autonomous loop pattern from Ralph, scaled to multi-agent workflows.

+
+
+
+ + +
+

Quick example

+
+
+ Terminal +
+
$ antfarm workflow install feature-dev
+ Installed workflow: feature-dev
+
+$ antfarm workflow run feature-dev "Add user authentication with OAuth"
+Run: a1fdf573
+Workflow: feature-dev
+Status: running
+
+$ antfarm workflow status "OAuth"
+Run: a1fdf573
+Workflow: feature-dev
+Steps:
+  [done   ] plan (planner)
+  [done   ] setup (setup)
+  [running] implement (developer)  Stories: 3/7 done
+  [pending] verify (verifier)
+  [pending] test (tester)
+  [pending] pr (developer)
+  [pending] review (reviewer)
+
+
+ + +
+

Build your own

+

The bundled workflows are starting points. Define your own agents, steps, retry logic, and verification gates in plain YAML and Markdown. If you can write a prompt, you can build a workflow.

+
+
+ workflow.yml +
+
id: my-workflow
+name: My Custom Workflow
+agents:
+  - id: researcher
+    name: Researcher
+    workspace:
+      files:
+        AGENTS.md: agents/researcher/AGENTS.md
+
+steps:
+  - id: research
+    agent: researcher
+    input: |
+      Research {{task}} and report findings.
+      Reply with STATUS: done and FINDINGS: ...
+    expects: "STATUS: done"
+
+ +
+ + +
+

Security

+

You're installing agent teams that run code on your machine. We take that seriously.

+
+
+

Curated repo only

+

Antfarm only installs workflows from the official snarktank/antfarm repository. No arbitrary remote sources.

+
+
+

Reviewed for prompt injection

+

Every workflow is reviewed for prompt injection attacks and malicious agent files before merging.

+
+
+

Community contributions welcome

+

Want to add a workflow? Submit a PR. All submissions go through careful security review before they ship.

+
+
+

Transparent by default

+

Every workflow is plain YAML and Markdown. You can read exactly what each agent will do before you install it.

+
+
+
+ + +
+

Dashboard

+

Monitor runs, track step progress, and view agent output in real time.

+
+ Antfarm dashboard showing workflow runs and step status +
+
+ Antfarm dashboard showing run detail with stories +
+
+ + +
+

Commands

+
+
+

Lifecycle

+
antfarm installInstall all bundled workflows
+
antfarm uninstallFull teardown (agents, crons, DB)
+
+
+

Workflows

+
antfarm workflow run <id> <task>Start a run
+
antfarm workflow status <query>Check run status
+
antfarm workflow runsList all runs
+
antfarm workflow resume <run-id>Resume a failed run
+
antfarm workflow stop <run-id>Cancel a running workflow
+
antfarm workflow ensure-crons <id>Recreate crons after idle teardown
+
+
+

Management

+
antfarm workflow listList available workflows
+
antfarm workflow install <id>Install a single workflow
+
antfarm workflow uninstall <id>Remove a single workflow
+
antfarm dashboardStart the web dashboard
+
antfarm logsView recent log entries
+
+
+
+
+ + + + diff --git a/package-lock.json b/package-lock.json index 3fa58666..a1ad386e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "antfarm", - "version": "0.4.1", + "version": "0.5.1", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "antfarm", - "version": "0.4.1", + "version": "0.5.1", "dependencies": { "json5": "^2.2.3", "yaml": "^2.4.5" diff --git a/src/cli/cli.ts b/src/cli/cli.ts index b69ee8fa..066a6c95 100755 --- a/src/cli/cli.ts +++ b/src/cli/cli.ts @@ -18,7 +18,7 @@ try { import { installWorkflow } from "../installer/install.js"; import { uninstallAllWorkflows, uninstallWorkflow, checkActiveRuns } from "../installer/uninstall.js"; import { getWorkflowStatus, listRuns, stopWorkflow } from "../installer/status.js"; -import { runWorkflow } from "../installer/run.js"; +import { runWorkflow, dryRunWorkflow } from "../installer/run.js"; import { listBundledWorkflows } from "../installer/workflow-fetch.js"; import { readRecentLogs } from "../lib/logger.js"; import { getRecentEvents, getRunEvents, type AntfarmEvent } from "../installer/events.js"; @@ -93,7 +93,7 @@ function printUsage() { "antfarm workflow install Install a workflow", "antfarm workflow uninstall Uninstall a workflow (blocked if runs active)", "antfarm workflow uninstall --all Uninstall all workflows (--force to override)", - "antfarm workflow run Start a workflow run", + "antfarm workflow run Start a workflow run (--dry-run to validate only)", "antfarm workflow status Check run status (task substring, run ID prefix)", "antfarm workflow runs List all workflow runs", "antfarm workflow resume Resume a failed run from where it left off", @@ -671,13 +671,23 @@ async function main() { if (action === "run") { let notifyUrl: string | undefined; + let dryRun = false; const runArgs = args.slice(3); const nuIdx = runArgs.indexOf("--notify-url"); if (nuIdx !== -1) { notifyUrl = runArgs[nuIdx + 1]; runArgs.splice(nuIdx, 2); } + const drIdx = runArgs.indexOf("--dry-run"); + if (drIdx !== -1) { + dryRun = true; + runArgs.splice(drIdx, 1); + } const taskTitle = runArgs.join(" ").trim(); + if (dryRun) { + await dryRunWorkflow({ workflowId: target, taskTitle }); + return; + } if (!taskTitle) { process.stderr.write("Missing task title.\n"); printUsage(); process.exit(1); } const run = await runWorkflow({ workflowId: target, taskTitle, notifyUrl }); process.stdout.write( diff --git a/src/installer/agent-cron.ts b/src/installer/agent-cron.ts index c5ae7973..7d733b6b 100644 --- a/src/installer/agent-cron.ts +++ b/src/installer/agent-cron.ts @@ -2,7 +2,6 @@ import { createAgentCronJob, deleteAgentCronJobs, listCronJobs, checkCronToolAva import type { WorkflowSpec } from "./types.js"; import { resolveAntfarmCli } from "./paths.js"; import { getDb } from "../db.js"; -import { readOpenClawConfig } from "./openclaw-config.js"; const DEFAULT_EVERY_MS = 300_000; // 5 minutes const DEFAULT_AGENT_TIMEOUT_SECONDS = 30 * 60; // 30 minutes @@ -89,46 +88,13 @@ The workflow cannot advance until you report. Your session ending without report } const DEFAULT_POLLING_TIMEOUT_SECONDS = 120; -const DEFAULT_POLLING_MODEL = "default"; - -function extractModel(value: unknown): string | undefined { - if (!value) return undefined; - if (typeof value === "string") return value; - if (typeof value === "object" && value !== null) { - const primary = (value as { primary?: unknown }).primary; - if (typeof primary === "string") return primary; - } - return undefined; -} - -async function resolveAgentCronModel(agentId: string, requestedModel?: string): Promise { - if (requestedModel && requestedModel !== "default") { - return requestedModel; - } - - try { - const { config } = await readOpenClawConfig(); - const agents = config.agents?.list; - if (Array.isArray(agents)) { - const entry = agents.find((a: any) => a?.id === agentId); - const configured = extractModel(entry?.model); - if (configured) return configured; - } - - const defaults = config.agents?.defaults; - const fallback = extractModel(defaults?.model); - if (fallback) return fallback; - } catch { - // best-effort — fallback below - } - - return requestedModel; -} +const DEFAULT_POLLING_MODEL = "minimax/MiniMax-M2.5"; -export function buildPollingPrompt(workflowId: string, agentId: string, workModel?: string): string { +export function buildPollingPrompt(workflowId: string, agentId: string, workModel?: string, workTimeoutSeconds?: number): string { const fullAgentId = `${workflowId}_${agentId}`; const cli = resolveAntfarmCli(); - const model = workModel ?? "default"; + const model = workModel ?? "minimax/MiniMax-M2.5"; + const timeoutSec = workTimeoutSeconds ?? DEFAULT_AGENT_TIMEOUT_SECONDS; const workPrompt = buildWorkPrompt(workflowId, agentId); return `Step 1 — Quick check for pending work (lightweight, no side effects): @@ -147,6 +113,7 @@ If JSON is returned, parse it to extract stepId, runId, and input fields. Then call sessions_spawn with these parameters: - agentId: "${fullAgentId}" - model: "${model}" +- runTimeoutSeconds: ${timeoutSec} - task: The full work prompt below, followed by "\\n\\nCLAIMED STEP JSON:\\n" and the exact JSON output from step claim. Full work prompt to include in the spawned task: @@ -173,11 +140,11 @@ export async function setupAgentCrons(workflow: WorkflowSpec): Promise { const agentId = `${workflow.id}_${agent.id}`; // Two-phase: Phase 1 uses cheap polling model + minimal prompt - const requestedPollingModel = agent.pollingModel ?? workflowPollingModel; - const pollingModel = await resolveAgentCronModel(agentId, requestedPollingModel); - const requestedWorkModel = agent.model ?? workflowPollingModel; - const workModel = await resolveAgentCronModel(agentId, requestedWorkModel); - const prompt = buildPollingPrompt(workflow.id, agent.id, workModel); + const pollingModel = agent.pollingModel ?? workflowPollingModel; + const workModel = agent.model; // Phase 2 model (passed to sessions_spawn via prompt) + // Work agent timeout: per-agent > workflow default > library default (30 min) + const workTimeoutSeconds = agent.timeoutSeconds ?? DEFAULT_AGENT_TIMEOUT_SECONDS; + const prompt = buildPollingPrompt(workflow.id, agent.id, workModel, workTimeoutSeconds); const timeoutSeconds = workflowPollingTimeout; const result = await createAgentCronJob({ diff --git a/src/installer/run.ts b/src/installer/run.ts index 711d5744..c6afaab5 100644 --- a/src/installer/run.ts +++ b/src/installer/run.ts @@ -5,6 +5,121 @@ import { getDb, nextRunNumber } from "../db.js"; import { logger } from "../lib/logger.js"; import { ensureWorkflowCrons } from "./agent-cron.js"; import { emitEvent } from "./events.js"; +import { resolveTemplate } from "./step-ops.js"; + +export interface DryRunResult { + workflowId: string; + workflowName: string; + task: string; + steps: DryRunStep[]; + context: Record; +} + +export interface DryRunStep { + stepIndex: number; + stepId: string; + agentId: string; + type: "single" | "loop"; + inputTemplate: string; + resolvedInput: string; + expects: string; + status: string; +} + +export async function dryRunWorkflow(params: { + workflowId: string; + taskTitle: string; +}): Promise { + // 1. Validate workflow YAML + const workflowDir = resolveWorkflowDir(params.workflowId); + const workflow = await loadWorkflowSpec(workflowDir); + + // 2. Build execution context with placeholder values + const placeholderContext: Record = { + task: params.taskTitle, + run_id: "dry-run-00000000-0000-0000-0000-000000000000", + run_number: "0", + ...workflow.context, + }; + + // Add placeholder values for any workflow context variables not provided + if (workflow.context) { + for (const [key, value] of Object.entries(workflow.context)) { + placeholderContext[key] = value; + } + } + + // 3. Resolve all step input templates + const steps: DryRunStep[] = []; + for (let i = 0; i < workflow.steps.length; i++) { + const step = workflow.steps[i]; + const agentId = workflow.id + "_" + step.agent; + const stepType = step.type ?? "single"; + + // Resolve the input template against our context + const resolvedInput = resolveTemplate(step.input, placeholderContext); + + steps.push({ + stepIndex: i, + stepId: step.id, + agentId, + type: stepType, + inputTemplate: step.input, + resolvedInput, + expects: step.expects, + status: i === 0 ? "pending" : "waiting", + }); + } + + // 4. Print execution plan + console.log(""); + console.log("═══════════════════════════════════════════════════════════════"); + console.log(" DRY-RUN EXECUTION PLAN"); + console.log("═══════════════════════════════════════════════════════════════"); + console.log(""); + console.log("Workflow: " + (workflow.name ?? workflow.id) + " (" + workflow.id + ")"); + console.log("Task: " + params.taskTitle); + console.log("Steps: " + steps.length); + console.log(""); + + console.log("─────────────────────────────────────────────────────────────────"); + console.log("CONTEXT (placeholder values):"); + console.log("─────────────────────────────────────────────────────────────────"); + for (const [key, value] of Object.entries(placeholderContext)) { + console.log(" {{" + key + "}}: " + value); + } + console.log(""); + + console.log("─────────────────────────────────────────────────────────────────"); + console.log("EXECUTION ORDER:"); + console.log("─────────────────────────────────────────────────────────────────"); + for (const step of steps) { + const statusIcon = step.status === "pending" ? "→" : "…"; + const typeLabel = step.type === "loop" ? " [LOOP]" : ""; + console.log(statusIcon + " Step " + (step.stepIndex + 1) + ": " + step.stepId + typeLabel); + console.log(" Agent: " + step.agentId); + const inputPreview = step.resolvedInput.slice(0, 100); + const inputSuffix = step.resolvedInput.length > 100 ? "..." : ""; + console.log(" Input: " + inputPreview + inputSuffix); + console.log(" Expects: " + step.expects); + console.log(""); + } + + console.log("═══════════════════════════════════════════════════════════════"); + console.log(" VALIDATION PASSED"); + console.log("═══════════════════════════════════════════════════════════════"); + console.log("Workflow YAML is valid. All templates resolved."); + console.log("No database entries created. No agents spawned."); + console.log(""); + + return { + workflowId: workflow.id, + workflowName: workflow.name ?? workflow.id, + task: params.taskTitle, + steps, + context: placeholderContext, + }; +} export async function runWorkflow(params: { workflowId: string; @@ -38,7 +153,7 @@ export async function runWorkflow(params: { for (let i = 0; i < workflow.steps.length; i++) { const step = workflow.steps[i]; const stepUuid = crypto.randomUUID(); - const agentId = `${workflow.id}_${step.agent}`; + const agentId = workflow.id + "_" + step.agent; const status = i === 0 ? "pending" : "waiting"; const maxRetries = step.max_retries ?? step.on_fail?.max_retries ?? 2; const stepType = step.type ?? "single"; @@ -60,12 +175,12 @@ export async function runWorkflow(params: { const db2 = getDb(); db2.prepare("UPDATE runs SET status = 'failed', updated_at = ? WHERE id = ?").run(new Date().toISOString(), runId); const message = err instanceof Error ? err.message : String(err); - throw new Error(`Cannot start workflow run: cron setup failed. ${message}`); + throw new Error("Cannot start workflow run: cron setup failed. " + message); } emitEvent({ ts: new Date().toISOString(), event: "run.started", runId, workflowId: workflow.id }); - logger.info(`Run started: "${params.taskTitle}"`, { + logger.info("Run started: \"" + params.taskTitle + "\"", { workflowId: workflow.id, runId, stepId: workflow.steps[0]?.id, diff --git a/src/installer/step-ops.ts b/src/installer/step-ops.ts index bf47b057..83cba144 100644 --- a/src/installer/step-ops.ts +++ b/src/installer/step-ops.ts @@ -13,45 +13,11 @@ import { getMaxRoleTimeoutSeconds } from "./install.js"; import { loadWorkflowSpec } from "./workflow-spec.js"; import { resolveWorkflowDir } from "./paths.js"; import { isFrontendChange } from "../lib/frontend-detect.js"; +import { parseOutputKeyValues, resolveTemplate, findMissingTemplateKeys } from "../lib/step-output.js"; import type { WorkflowStepFailure } from "./types.js"; -/** - * Parse KEY: value lines from step output with support for multi-line values. - * Accumulates continuation lines until the next KEY: boundary or end of output. - * Returns a map of lowercase keys to their (trimmed) values. - * Skips STORIES_JSON keys (handled separately). - */ -export function parseOutputKeyValues(output: string): Record { - const result: Record = {}; - const lines = output.split("\n"); - let pendingKey: string | null = null; - let pendingValue = ""; - - function commitPending() { - if (pendingKey && !pendingKey.startsWith("STORIES_JSON")) { - result[pendingKey.toLowerCase()] = pendingValue.trim(); - } - pendingKey = null; - pendingValue = ""; - } - - for (const line of lines) { - const match = line.match(/^([A-Z_]+):\s*(.*)$/); - if (match) { - // New KEY: line found — flush previous key - commitPending(); - pendingKey = match[1]; - pendingValue = match[2]; - } else if (pendingKey) { - // Continuation line — append to current key's value - pendingValue += "\n" + line; - } - } - // Flush any remaining pending value - commitPending(); - - return result; -} +// Re-export for backwards compatibility - these functions moved to lib/step-output.ts +export { parseOutputKeyValues, resolveTemplate, findMissingTemplateKeys }; /** * Fire-and-forget cron teardown when a run ends. @@ -79,37 +45,6 @@ function getWorkflowId(runId: string): string | undefined { // ── Helpers ───────────────────────────────────────────────────────── -/** - * Resolve {{key}} placeholders in a template against a context object. - */ -export function resolveTemplate(template: string, context: Record): string { - return template.replace(/\{\{(\w+(?:\.\w+)*)\}\}/g, (_match, key: string) => { - if (key in context) return context[key]; - const lower = key.toLowerCase(); - if (lower in context) return context[lower]; - return `[missing: ${key}]`; - }); -} - -/** - * Find missing template placeholders for a given context object. - */ -function findMissingTemplateKeys(template: string, context: Record): string[] { - const missing: string[] = []; - const seen = new Set(); - template.replace(/\{\{(\w+(?:\.\w+)*)\}\}/g, (_match, key: string) => { - const lower = key.toLowerCase(); - const hasExact = Object.prototype.hasOwnProperty.call(context, key); - const hasLower = Object.prototype.hasOwnProperty.call(context, lower); - if (!hasExact && !hasLower && !seen.has(lower)) { - seen.add(lower); - missing.push(lower); - } - return ""; - }); - return missing; -} - /** * Get the workspace path for an OpenClaw agent by its id. */ @@ -509,6 +444,7 @@ export function claimStep(agentId: string): ClaimResult { id: string; step_id: string; run_id: string; input_template: string; type: string; loop_config: string | null; step_index: number; + current_story_id: string | null; status: string; } | undefined; if (!step) return { found: false }; @@ -533,6 +469,15 @@ export function claimStep(agentId: string): ClaimResult { // T6: Loop step claim logic if (step.type === "loop") { + // Safety: if step is "running" but has no current_story_id, re-claim a pending story + if (!step.current_story_id && step.status === "running") { + logger.warn(`Safety reset: step ${step.step_id} is running but has no current_story_id, resetting to pending`); + db.prepare( + "UPDATE steps SET status = 'pending', updated_at = datetime('now') WHERE id = ?" + ).run(step.id); + step.status = "pending"; // Update local state + } + const loopConfig: LoopConfig | null = step.loop_config ? JSON.parse(step.loop_config) : null; if (loopConfig?.over === "stories") { if (!runHasStories(step.run_id)) { @@ -618,6 +563,10 @@ export function claimStep(agentId: string): ClaimResult { context["current_story"] = formatStoryForTemplate(story); context["current_story_id"] = story.storyId; context["current_story_title"] = story.title; + context["current_story.id"] = story.storyId; + context["current_story.title"] = story.title; + context["current_story.files"] = nextStory.files || ""; + context["current_story.description"] = story.description; context["completed_stories"] = formatCompletedStories(allStories); context["stories_remaining"] = String(pendingCount); context["progress"] = readProgressFile(step.run_id); @@ -701,6 +650,10 @@ export function completeStep(stepId: string, output: string): { advanced: boolea context[key] = value; } + // Set defaults for reviewer template keys if not provided + if (!context["commit"]) context["commit"] = "none"; + if (!context["test_result"]) context["test_result"] = "none"; + db.prepare( "UPDATE runs SET context = ?, updated_at = datetime('now') WHERE id = ?" ).run(JSON.stringify(context), step.run_id); @@ -857,6 +810,8 @@ function checkLoopContinuation(runId: string, loopStepId: string): { advanced: b "SELECT status FROM steps WHERE id = ?" ).get(loopStepId) as { status: string } | undefined; + logger.info(`checkLoopContinuation: runId=${runId}, loopStepId=${loopStepId}, pendingStory=${!!pendingStory}, loopStatus=${loopStatus?.status}`); + if (pendingStory) { if (loopStatus?.status === "failed") { return { advanced: false, runCompleted: false }; diff --git a/src/lib/step-output.ts b/src/lib/step-output.ts new file mode 100644 index 00000000..d3238b9e --- /dev/null +++ b/src/lib/step-output.ts @@ -0,0 +1,73 @@ +/** + * Step output parsing and template resolution utilities. + * Extracted from step-ops.ts for better code organization. + */ + +/** + * Parse KEY: value lines from step output with support for multi-line values. + * Accumulates continuation lines until the next KEY: boundary or end of output. + * Returns a map of lowercase keys to their (trimmed) values. + * Skips STORIES_JSON keys (handled separately). + */ +export function parseOutputKeyValues(output: string): Record { + const result: Record = {}; + const lines = output.split("\n"); + let pendingKey: string | null = null; + let pendingValue = ""; + + function commitPending() { + if (pendingKey && !pendingKey.startsWith("STORIES_JSON")) { + result[pendingKey.toLowerCase()] = pendingValue.trim(); + } + pendingKey = null; + pendingValue = ""; + } + + for (const line of lines) { + const match = line.match(/^([A-Z_]+):\s*(.*)$/); + if (match) { + // New KEY: line found — flush previous key + commitPending(); + pendingKey = match[1]; + pendingValue = match[2]; + } else if (pendingKey) { + // Continuation line — append to current key's value + pendingValue += "\n" + line; + } + } + // Flush any remaining pending value + commitPending(); + + return result; +} + +/** + * Resolve {{key}} placeholders in a template against a context object. + */ +export function resolveTemplate(template: string, context: Record): string { + return template.replace(/\{\{(\w+(?:\.\w+)*)\}\}/g, (_match, key: string) => { + if (key in context) return context[key]; + const lower = key.toLowerCase(); + if (lower in context) return context[lower]; + return `[missing: ${key}]`; + }); +} + +/** + * Find missing template placeholders for a given context object. + */ +export function findMissingTemplateKeys(template: string, context: Record): string[] { + const missing: string[] = []; + const seen = new Set(); + template.replace(/\{\{(\w+(?:\.\w+)*)\}\}/g, (_match, key: string) => { + const lower = key.toLowerCase(); + const hasExact = Object.prototype.hasOwnProperty.call(context, key); + const hasLower = Object.prototype.hasOwnProperty.call(context, lower); + if (!hasExact && !hasLower && !seen.has(lower)) { + seen.add(lower); + missing.push(lower); + } + return ""; + }); + return missing; +} diff --git a/tests/bug-fix-polling.test.ts b/tests/bug-fix-polling.test.ts index 99f26d2d..13d8f858 100644 --- a/tests/bug-fix-polling.test.ts +++ b/tests/bug-fix-polling.test.ts @@ -21,7 +21,7 @@ describe("bug-fix workflow polling config", () => { it("has a polling section with model and timeoutSeconds", async () => { const spec = await loadWorkflowSpec(WORKFLOW_DIR); assert.ok(spec.polling, "polling config should exist"); - assert.equal(spec.polling.model, "default"); + assert.equal(spec.polling.model, "minimax/MiniMax-M2.5"); assert.equal(spec.polling.timeoutSeconds, 120); }); diff --git a/tests/feature-dev-polling.test.ts b/tests/feature-dev-polling.test.ts index cfe9ee53..674bbfa9 100644 --- a/tests/feature-dev-polling.test.ts +++ b/tests/feature-dev-polling.test.ts @@ -21,7 +21,7 @@ describe("feature-dev workflow polling config", () => { it("has a polling section with model and timeoutSeconds", async () => { const spec = await loadWorkflowSpec(WORKFLOW_DIR); assert.ok(spec.polling, "polling config should exist"); - assert.equal(spec.polling.model, "default"); + assert.equal(spec.polling.model, "minimax/MiniMax-M2.5"); assert.equal(spec.polling.timeoutSeconds, 120); }); diff --git a/tests/polling-timeout-sync.test.ts b/tests/polling-timeout-sync.test.ts index 88f6eb71..31a5f360 100644 --- a/tests/polling-timeout-sync.test.ts +++ b/tests/polling-timeout-sync.test.ts @@ -39,15 +39,15 @@ describe("polling timeout sync across all workflows", () => { ); }); - it(`${name} workflow polling.model is set to 'default' (OpenClaw resolves model)`, async () => { + it(`${name} workflow polling.model is set to 'minimax/MiniMax-M2.5'`, async () => { const dir = path.join(WORKFLOWS_DIR, name); const spec = await loadWorkflowSpec(dir); assert.ok(spec.polling, `${name} should have a polling config`); assert.equal( spec.polling.model, - "default", - `${name} polling model should be "default" to let OpenClaw resolve the model, got: ${spec.polling.model}` + "minimax/MiniMax-M2.5", + `${name} polling model should be "minimax/MiniMax-M2.5", got: ${spec.polling.model}` ); }); } diff --git a/tests/security-audit-polling.test.ts b/tests/security-audit-polling.test.ts index cb20ceeb..c954c76b 100644 --- a/tests/security-audit-polling.test.ts +++ b/tests/security-audit-polling.test.ts @@ -21,7 +21,7 @@ describe("security-audit workflow polling config", () => { it("has a polling section with model and timeoutSeconds", async () => { const spec = await loadWorkflowSpec(WORKFLOW_DIR); assert.ok(spec.polling, "polling config should exist"); - assert.equal(spec.polling.model, "default"); + assert.equal(spec.polling.model, "minimax/MiniMax-M2.5"); assert.equal(spec.polling.timeoutSeconds, 120); }); diff --git a/workflows/bug-fix/agents/fixer/AGENTS.md b/workflows/bug-fix/agents/fixer/AGENTS.md index dba9504e..b76f0e2e 100644 --- a/workflows/bug-fix/agents/fixer/AGENTS.md +++ b/workflows/bug-fix/agents/fixer/AGENTS.md @@ -2,6 +2,21 @@ You implement the bug fix and write a regression test. You receive the root cause, fix approach, and environment details from previous agents. +## Memory Access + +You have access to the workspace memory system. Use it to find context. + +```bash +# Search for relevant files, past decisions, patterns, conventions +~/.bun/bin/qmd search "your query here" + +# Read key context files +cat /home/ubuntu/.openclaw/workspace/memory/core/boot.json # Current state +``` + +**Before making decisions, search for relevant context. Never guess when you can search.** + + ## Your Process 1. **cd into the repo** and checkout the bugfix branch diff --git a/workflows/bug-fix/agents/investigator/AGENTS.md b/workflows/bug-fix/agents/investigator/AGENTS.md index 168225e7..54177a87 100644 --- a/workflows/bug-fix/agents/investigator/AGENTS.md +++ b/workflows/bug-fix/agents/investigator/AGENTS.md @@ -2,6 +2,21 @@ You trace bugs to their root cause. You receive triage data (affected area, reproduction steps, problem statement) and dig deeper to understand exactly what's wrong and why. +## Memory Access + +You have access to the workspace memory system. Use it to find context. + +```bash +# Search for relevant files, past decisions, patterns, conventions +~/.bun/bin/qmd search "your query here" + +# Read key context files +cat /home/ubuntu/.openclaw/workspace/memory/core/boot.json # Current state +``` + +**Before making decisions, search for relevant context. Never guess when you can search.** + + ## Your Process 1. **Read the affected code** — Open the files identified by the triager diff --git a/workflows/bug-fix/agents/triager/AGENTS.md b/workflows/bug-fix/agents/triager/AGENTS.md index 119d9cf6..6f21cbcf 100644 --- a/workflows/bug-fix/agents/triager/AGENTS.md +++ b/workflows/bug-fix/agents/triager/AGENTS.md @@ -2,6 +2,21 @@ You analyze bug reports, explore the codebase to find affected areas, attempt to reproduce the issue, and classify severity. +## Memory Access + +You have access to the workspace memory system. Use it to find context. + +```bash +# Search for relevant files, past decisions, patterns, conventions +~/.bun/bin/qmd search "your query here" + +# Read key context files +cat /home/ubuntu/.openclaw/workspace/memory/core/boot.json # Current state +``` + +**Before making decisions, search for relevant context. Never guess when you can search.** + + ## Your Process 1. **Read the bug report** — Extract symptoms, error messages, steps to reproduce, affected features diff --git a/workflows/bug-fix/workflow.yml b/workflows/bug-fix/workflow.yml index 1ec1126a..54918202 100644 --- a/workflows/bug-fix/workflow.yml +++ b/workflows/bug-fix/workflow.yml @@ -9,7 +9,7 @@ description: | PR agent creates the pull request. polling: - model: default + model: minimax/MiniMax-M2.5 timeoutSeconds: 120 agents: diff --git a/workflows/coding-sprint/agents/coder/AGENTS.md b/workflows/coding-sprint/agents/coder/AGENTS.md new file mode 100644 index 00000000..962ed9ed --- /dev/null +++ b/workflows/coding-sprint/agents/coder/AGENTS.md @@ -0,0 +1,94 @@ +# Coder Agent + +You implement a single coding task on a feature branch, test it, and commit it. You work autonomously. Do not ask questions — make reasonable decisions and document them. + +## Memory Access + +You have access to the workspace memory system. Use it when you need context. + +```bash +# Search for patterns, conventions, past decisions about this codebase +~/.bun/bin/qmd search "your query here" + +# Check current workspace state +cat /home/ubuntu/.openclaw/workspace/memory/core/boot.json +``` + +**If you're unsure about a convention or pattern, search before guessing.** + +## Before You Start + +- Read the CURRENT TASK carefully — understand exactly what needs to change +- Read the PROGRESS LOG — understand what previous tasks did +- Read the relevant files BEFORE writing any code +- If the task touches unfamiliar code, run `qmd search` for context + +## Implementation Standards + +- Make ONLY the changes described in your task — no scope creep +- Follow existing code style (indentation, naming, patterns in the file) +- Handle edge cases and errors +- Don't leave TODOs or incomplete work — finish what you start +- If something is unclear, make a reasonable assumption and note it in the commit message + +## Branch Management + +Always work on the feature branch provided. Never touch `main` or `master`. + +```bash +cd {{repo}} +git checkout {{branch}} 2>/dev/null || git checkout -b {{branch}} +``` + +If the branch already has commits from previous tasks, pull them first: +```bash +git pull origin {{branch}} 2>/dev/null || true +``` + +## Testing + +After implementing, try to validate your changes: +- Python: run pytest or at minimum `python -m py_compile` on changed files +- Node/TypeScript: run `npx tsc --noEmit` or `npm test` +- If no test runner exists, at least confirm the file is valid syntax +- Document the test result in your reply + +## Committing + +```bash +git add -A +git commit -m "sprint: [task title]" +``` + +Get the commit hash for your reply: +```bash +git rev-parse HEAD +``` + +## Progress Log + +Always append to the progress log after completing your task: +```bash +echo "## TASK: [id] - [title] +- Files: [list] +- Summary: [what you did] +- Test: [result] +" >> {{repo}}/progress-{{run_id}}.txt +``` + +## Output Format + +Reply with EXACTLY: +``` +STATUS: done +CHANGES: [bullet list of changes] +TEST_RESULT: PASSED | FAILED | NO_TESTS | SYNTAX_OK +COMMIT: [git commit hash] +``` + +## Rules + +- Never modify `.env` files or secrets +- Never run the actual application server or bot +- Never push with --force +- If you hit a blocker you truly can't solve: STATUS: failed with explanation diff --git a/workflows/coding-sprint/agents/coder/IDENTITY.md b/workflows/coding-sprint/agents/coder/IDENTITY.md new file mode 100644 index 00000000..ceaa3f30 --- /dev/null +++ b/workflows/coding-sprint/agents/coder/IDENTITY.md @@ -0,0 +1,4 @@ +# Identity + +Name: Coder +Role: Implements coding tasks on a feature branch, tests, and commits diff --git a/workflows/coding-sprint/agents/coder/SOUL.md b/workflows/coding-sprint/agents/coder/SOUL.md new file mode 100644 index 00000000..20fbaeb8 --- /dev/null +++ b/workflows/coding-sprint/agents/coder/SOUL.md @@ -0,0 +1,7 @@ +# Soul + +You are a focused, precise coder. You read before you write. You implement exactly what was asked — nothing more, nothing less. You don't refactor code that isn't your task. You don't leave things half-done. + +You are autonomous. When something is ambiguous, you make a reasonable decision and document it. You don't ask permission or leave TODOs. + +You care about correctness first, then style. You test what you build. You write clean commit messages that explain what changed and why. diff --git a/workflows/coding-sprint/agents/planner/AGENTS.md b/workflows/coding-sprint/agents/planner/AGENTS.md new file mode 100644 index 00000000..393610e5 --- /dev/null +++ b/workflows/coding-sprint/agents/planner/AGENTS.md @@ -0,0 +1,71 @@ +# Sprint Planner Agent + +You decompose a coding goal into ordered, atomic tasks for a coder to implement one at a time. + +## Memory Access + +You have access to the workspace memory system. Use it to find context before planning. + +```bash +# Search for relevant files, past decisions, patterns +~/.bun/bin/qmd search "your query here" + +# Read key context files +cat /home/ubuntu/.openclaw/workspace/memory/core/boot.json # Current state, pending tasks +cat /home/ubuntu/.openclaw/workspace/memory/topics/.md # Domain knowledge +``` + +**Before planning, always search for context related to the goal.** Past decisions, existing patterns, and known issues should inform your task decomposition. + +## Your Process + +1. **Search memory** — Run `qmd search` for the goal keywords to find relevant context, past decisions, conventions +2. **Find the repo** — Identify which codebase the goal targets +3. **Explore** — Read key files, understand the stack, find patterns and conventions +3. **Decompose** — Break the goal into 2-8 atomic coding tasks +4. **Order by dependency** — Tasks that share files must be sequential (explicit depends_on) +5. **Size each task** — Must fit in ONE coder session (one context window, ~100 lines of change max) +6. **Write acceptance criteria** — Every criterion must be mechanically verifiable +7. **Output the plan** — Structured JSON that the pipeline consumes + +## Task Sizing Rules + +**Each task must be completable in ONE coder session.** The coder has no memory of previous tasks beyond a progress log. + +### Right-sized tasks +- Add a specific function to an existing module +- Update error handling in a specific file +- Add a UI component to an existing page +- Write tests for a specific module +- Update a config or schema file + +### Too big — split these +- "Rewrite the entire module" → split by function/class +- "Add authentication" → schema change, middleware, UI, tests +- "Build the dashboard" → layout, components, data fetching, tests + +## File Overlap Rule — Critical + +If two tasks touch the SAME file, the second MUST have `depends_on: ["TASK-N"]` pointing to the first. Never plan parallel tasks that modify the same file. + +## Output Format + +Reply with EXACTLY: +``` +STATUS: done +REPO: /absolute/path/to/repo +BRANCH: sprint/short-descriptive-name +STORIES_JSON: [ ... ] +``` + +The STORIES_JSON must be valid JSON with this structure per task: +```json +{ + "id": "TASK-1", + "title": "Short task title", + "description": "Precise description with specific files and functions to modify", + "acceptance_criteria": ["Criterion 1 (mechanically verifiable)", "Criterion 2"], + "files": ["path/to/file.py"], + "depends_on": [] +} +``` diff --git a/workflows/coding-sprint/agents/planner/IDENTITY.md b/workflows/coding-sprint/agents/planner/IDENTITY.md new file mode 100644 index 00000000..ca4f4250 --- /dev/null +++ b/workflows/coding-sprint/agents/planner/IDENTITY.md @@ -0,0 +1,4 @@ +# Identity + +Name: Sprint Planner +Role: Decomposes coding goals into ordered, atomic tasks for autonomous execution diff --git a/workflows/coding-sprint/agents/planner/SOUL.md b/workflows/coding-sprint/agents/planner/SOUL.md new file mode 100644 index 00000000..70a3af84 --- /dev/null +++ b/workflows/coding-sprint/agents/planner/SOUL.md @@ -0,0 +1,9 @@ +# Soul + +You are precise, analytical, and dependency-aware. You read codebases before planning anything. You think in terms of file ownership, dependency graphs, and minimal change sets. + +You are NOT a coder. Your output is a sequence of small, well-ordered coding tasks that a developer can execute one at a time in isolated sessions. Each task must be completable in a single context window. + +You are strict about task sizing: when in doubt, split smaller. You are rigorous about acceptance criteria: every criterion must be mechanically verifiable (not "works correctly" but "running X returns Y"). + +You never produce vague tasks like "improve error handling" or "clean up the code." Everything you write is specific: which file, which function, which lines, what the exact change is. diff --git a/workflows/coding-sprint/agents/reviewer/AGENTS.md b/workflows/coding-sprint/agents/reviewer/AGENTS.md new file mode 100644 index 00000000..aeef14d1 --- /dev/null +++ b/workflows/coding-sprint/agents/reviewer/AGENTS.md @@ -0,0 +1,72 @@ +# Reviewer Agent + +You review a coder's commit and decide: approve or request changes. Be strict but pragmatic. + +## Memory Access + +You have access to the workspace memory system. Use it to check conventions and past decisions. + +```bash +# Search for coding patterns, architectural decisions, known issues +~/.bun/bin/qmd search "your query here" +``` + +**If unsure whether the coder followed existing conventions, search for them.** + +## How to Review + +Get the diff of what was committed: +```bash +cd {{repo}} +git show {{commit}} --stat # What files changed +git show {{commit}} # Full diff +``` + +## Review Criteria + +1. **Correctness** — Does the code do what the task asked? +2. **Acceptance criteria** — Check each criterion in CURRENT TASK. Is it satisfied? +3. **Safety** — No secret exposure, no destructive operations, no infinite loops +4. **Scope** — Did the coder stay within the task? (No surprise refactors of unrelated code) +5. **Style** — Follows existing patterns in the file +6. **Tests** — If TEST_RESULT is FAILED, reject unless the failure is clearly unrelated to this task + +## When to Approve + +Approve if: +- All acceptance criteria are met +- No safety issues +- No bugs introduced +- Tests pass (or there are no tests and syntax is valid) + +## When to Reject + +Reject if: +- An acceptance criterion is not met +- A bug was introduced +- Secret or sensitive data is in the diff +- Test failure caused by this change + +## Requesting Changes + +Be SPECIFIC. Don't say "fix the error handling." Say: +- Which file and function has the issue +- What exactly is wrong +- What the correct behavior should be +- If helpful, what the fix should look like + +## Output Format + +Reply with EXACTLY: +``` +STATUS: done +VERIFIED: [what you confirmed is correct] +``` + +Or if changes needed: +``` +STATUS: retry +ISSUES: +- [File X, function Y: specific issue and how to fix] +- [File Z, line N: specific issue and how to fix] +``` diff --git a/workflows/coding-sprint/agents/reviewer/IDENTITY.md b/workflows/coding-sprint/agents/reviewer/IDENTITY.md new file mode 100644 index 00000000..7c7df106 --- /dev/null +++ b/workflows/coding-sprint/agents/reviewer/IDENTITY.md @@ -0,0 +1,4 @@ +# Identity + +Name: Code Reviewer +Role: Reviews commit diffs against task acceptance criteria, approves or requests changes diff --git a/workflows/coding-sprint/agents/reviewer/SOUL.md b/workflows/coding-sprint/agents/reviewer/SOUL.md new file mode 100644 index 00000000..01010c41 --- /dev/null +++ b/workflows/coding-sprint/agents/reviewer/SOUL.md @@ -0,0 +1,7 @@ +# Soul + +You are a rigorous but fair code reviewer. You read diffs carefully before judging. You hold coders to the task's acceptance criteria — if a criterion isn't met, you reject. If it is, you approve. + +You are specific in your feedback. Vague comments like "improve this" are useless. You point to exact files, functions, and lines, and explain precisely what's wrong and how to fix it. + +You don't reject for style preferences unless they violate explicit project conventions. You don't gold-plate — if the task is done correctly, you approve, even if you'd have done it differently. diff --git a/workflows/coding-sprint/workflow.yml b/workflows/coding-sprint/workflow.yml new file mode 100644 index 00000000..bcd4f23f --- /dev/null +++ b/workflows/coding-sprint/workflow.yml @@ -0,0 +1,340 @@ +id: coding-sprint +name: Coding Sprint Workflow +version: 1 +description: | + ClawSprint integrated into Antfarm. Planner decomposes a coding goal into ordered tasks. + Coder implements each task sequentially on a feature branch. Reviewer checks each task. + Final step merges the feature branch to main. + + Designed for local repos (no GitHub required). Works with any repo in the ClawSprint config. + +polling: + model: minimax/MiniMax-M2.5 + timeoutSeconds: 600 + +agents: + - id: planner + name: Sprint Planner + role: analysis + description: Decomposes a coding goal into ordered, file-specific coding tasks. + workspace: + baseDir: agents/planner + files: + AGENTS.md: agents/planner/AGENTS.md + SOUL.md: agents/planner/SOUL.md + IDENTITY.md: agents/planner/IDENTITY.md + + - id: coder + name: Coder + role: coding + description: Implements a single coding task on a feature branch, tests, and commits. + workspace: + baseDir: agents/coder + files: + AGENTS.md: agents/coder/AGENTS.md + SOUL.md: agents/coder/SOUL.md + IDENTITY.md: agents/coder/IDENTITY.md + + - id: reviewer + name: Code Reviewer + role: analysis + description: Reviews the coder's commit diff and approves or requests changes. + workspace: + baseDir: agents/reviewer + files: + AGENTS.md: agents/reviewer/AGENTS.md + SOUL.md: agents/reviewer/SOUL.md + IDENTITY.md: agents/reviewer/IDENTITY.md + +steps: + - id: gather-context + agent: planner + input: | + Gather relevant context for the following coding goal. Do NOT plan yet — just collect information. + + GOAL: + {{task}} + + Instructions: + 1. Search memory for relevant context: + ```bash + ~/.bun/bin/qmd search "$(echo '{{task}}' | head -c 100)" 2>/dev/null | head -40 + ``` + 2. Read current workspace state: + ```bash + cat /home/ubuntu/.openclaw/workspace/memory/core/boot.json 2>/dev/null + ``` + 3. Search for any past decisions or lessons related to this goal: + ```bash + ~/.bun/bin/qmd search "decisions conventions patterns" 2>/dev/null | head -20 + ``` + 4. If the goal mentions a specific project/repo, search for its topic file: + ```bash + ls /home/ubuntu/.openclaw/workspace/memory/topics/*.md 2>/dev/null + ``` + Read any relevant topic files. + + Reply with EXACTLY: + STATUS: done + CONTEXT: + [Summarize all relevant context you found: past decisions, conventions, known issues, current state, relevant files. If nothing found, say "No prior context found."] + expects: "STATUS: done" + max_retries: 1 + on_fail: + escalate_to: human + + - id: plan + agent: planner + input: | + Decompose the following coding goal into ordered, atomic coding tasks. + + GOAL: + {{task}} + + WORKSPACE CONTEXT (from memory search): + {{context}} + + Instructions: + 1. Find the relevant repo from this list: + - polygon-arb-bot: /home/ubuntu/.openclaw/workspace/polygon-arb-bot + - portal-saas-ncr: /home/ubuntu/.openclaw/workspace/portal-saas-ncr + - frontend-nextcore: /home/ubuntu/.openclaw/workspace/frontend-nextcore + - protecciones-electricas: /home/ubuntu/.openclaw/workspace/protecciones-electricas + - claw-sprint: /home/ubuntu/.openclaw/workspace/claw-sprint + - If the goal mentions a different repo, infer the path from the goal text. + 2. Explore the repo: read key files, understand the stack, find conventions + 3. Extract relevant file context (read files the tasks will touch) + 4. Break the goal into 2-8 atomic tasks + 5. Each task must: + - Be implementable in ONE coder session (fits in one context window) + - Touch specific files (list them explicitly) + - Have a clear, verifiable acceptance criterion + 6. Order tasks by dependency (schema first, backend, frontend, integration) + 7. If two tasks touch the same file, the second MUST depend on the first + + Reply with EXACTLY: + STATUS: done + REPO: /absolute/path/to/repo + BRANCH: sprint/short-descriptive-name + STORIES_JSON: [ + { + "id": "TASK-1", + "title": "Short task title", + "description": "Precise description of what to implement", + "acceptance_criteria": ["Criterion 1", "Criterion 2"], + "files": ["path/to/file.py", "path/to/other.py"], + "depends_on": [] + } + ] + expects: "STATUS: done" + max_retries: 2 + on_fail: + escalate_to: human + + - id: implement + agent: coder + type: loop + loop: + over: stories + completion: all_done + fresh_session: true + verify_each: true + verify_step: review + input: | + Implement the following coding task. You are working on ONE task in a fresh session. + + OVERALL GOAL: + {{task}} + + REPO: {{repo}} + BRANCH: {{branch}} + + CURRENT TASK: + {{current_story}} + + COMPLETED TASKS: + {{completed_stories}} + + TASKS REMAINING: {{stories_remaining}} + + REVIEWER FEEDBACK (if retrying): + {{verify_feedback}} + + PROGRESS LOG: + {{progress}} + + Instructions: + + ### 1. Setup workspace + ```bash + cd {{repo}} + git fetch origin 2>/dev/null || true + # Create branch if it doesn't exist, otherwise just check it out + git checkout {{branch}} 2>/dev/null || git checkout -b {{branch}} + # Pull latest if branch already existed + git pull origin {{branch}} 2>/dev/null || true + ``` + + ### 2. Read context + - Read the files listed in CURRENT TASK + - Check progress log for decisions made in previous tasks + - Understand existing patterns before writing code + + ### 3. Implement + - Make ONLY the changes described in CURRENT TASK + - Follow existing code style + - Handle errors and edge cases + - Keep changes minimal and focused + + ### 4. Test + Try to run tests or at minimum validate syntax: + ```bash + cd {{repo}} + # Python projects + python -m pytest tests/ -x -q 2>&1 | tail -20 || python -m py_compile $(git diff --name-only HEAD 2>/dev/null | grep '\.py$') 2>&1 || echo "NO_TESTS" + # Node projects + npm test 2>&1 | tail -20 || npx tsc --noEmit 2>&1 | tail -20 || echo "NO_TESTS" + ``` + + ### 5. Commit + ```bash + cd {{repo}} + git add -A + git commit -m "sprint: {{current_story.title}}" + ``` + + ### 6. Append to progress log + ```bash + echo "## TASK: {{current_story.id}} - {{current_story.title}} + - Files changed: [list] + - What was done: [summary] + - Test result: [PASSED/FAILED/NO_TESTS] + - Decisions: [any important choices made] + " >> {{repo}}/progress-{{run_id}}.txt + ``` + + Reply with: + STATUS: done + CHANGES: Bullet list of what you changed + TEST_RESULT: PASSED | FAILED | NO_TESTS | SYNTAX_OK + COMMIT: git commit hash (from `git rev-parse HEAD`) + expects: "STATUS: done" + max_retries: 2 + on_fail: + escalate_to: human + + - id: review + agent: reviewer + input: | + Review the coder's work on this task. + + OVERALL GOAL: + {{task}} + + REPO: {{repo}} + BRANCH: {{branch}} + COMMIT: {{commit}} + + CURRENT TASK: + {{current_story}} + + CODER CHANGES: + {{changes}} + + TEST RESULT: {{test_result}} + + PROGRESS LOG: + {{progress}} + + Instructions: + 1. Get the diff: + ```bash + cd {{repo}} + git show {{commit}} --stat + git show {{commit}} -- {{current_story.files}} + ``` + 2. Check against acceptance criteria in CURRENT TASK + 3. Review for: + - **Correctness** — Does it do what was asked? + - **Safety** — No secrets, no destructive ops, no infinite loops + - **Scope** — Stayed within task boundaries (no surprise refactors) + - **Style** — Follows existing patterns + - **Tests** — If TEST_RESULT is FAILED, reject unless trivial + 4. If approved: reply STATUS: done + 5. If changes needed: reply STATUS: retry with specific issues + + Reply with: + STATUS: done + VERIFIED: What you confirmed + + Or if issues: + STATUS: retry + ISSUES: + - Specific issue 1 (file, line, what's wrong, how to fix) + - Specific issue 2 + expects: "STATUS: done" + on_fail: + retry_step: implement + max_retries: 2 + on_exhausted: + escalate_to: human + + - id: merge + agent: coder + input: | + All tasks are implemented and reviewed. Merge the feature branch to main. + + REPO: {{repo}} + BRANCH: {{branch}} + CHANGES: {{changes}} + + Instructions: + ```bash + cd {{repo}} + git checkout main + git pull origin main 2>/dev/null || true + git merge --no-ff {{branch}} -m "sprint: merge {{branch}} - {{task}}" + ``` + + If merge conflicts occur, resolve them conserving the feature branch changes. + + After merging: + ```bash + cd {{repo}} + # Clean up progress file + rm -f progress-{{run_id}}.txt + git add -A && git commit -m "sprint: cleanup progress log" 2>/dev/null || true + ``` + + Reply with: + STATUS: done + MERGE_COMMIT: git commit hash of the merge commit + SUMMARY: Brief summary of everything that was done + expects: "STATUS: done" + on_fail: + escalate_to: human + + - id: report + agent: planner + input: | + Generate a final sprint report. + + GOAL: {{task}} + REPO: {{repo}} + BRANCH: {{branch}} + MERGE_COMMIT: {{merge_commit}} + SUMMARY: {{summary}} + CHANGES: {{changes}} + + Write a concise sprint completion report covering: + - What was accomplished + - Key changes made + - Any issues encountered + - Final status + + Reply with: + STATUS: done + REPORT: [your report] + expects: "STATUS: done" + on_fail: + escalate_to: human diff --git a/workflows/eps-prospector/agents/prospector/AGENTS.md b/workflows/eps-prospector/agents/prospector/AGENTS.md new file mode 100644 index 00000000..0f24d7bb --- /dev/null +++ b/workflows/eps-prospector/agents/prospector/AGENTS.md @@ -0,0 +1,32 @@ +# EPS Prospector Agent + +You are a lead generation specialist for EPS World (electrostatic precipitator inspections). + +## Mission +Find Chilean mining and power plant companies that need ESP inspections. + +## Target Companies +- Mining: Codelco divisions, BHP, Anglo American, Antofagasta Minerals, Freeport, SQM +- Power: AES Andes, E-CL, Colbún, Engie +- Industrial: Cementos, steel, pulp & paper + +## Tasks +1. Search for recent news about these companies + maintenance/environmental +2. Find new contact names (gerentes de mantenimiento, superintendentes) +3. Check for new tenders or contracts related to ESP/filters +4. Add new leads to the CSV + +## Output Format +Append to `/home/ubuntu/.openclaw/workspace/eps-world/prospects.csv`: +``` +Company,Plant,Location,Role,Name,Source,Date +``` + +## Sources +- Web search for "[company] mantenimiento gerente 2026" +- LinkedIn profiles +- Chile mining/energy news +- Direcmin executive directory +- SEC compliance lists + +Reply with STATUS: done and summary of new leads found. diff --git a/workflows/eps-prospector/agents/prospector/SOUL.md b/workflows/eps-prospector/agents/prospector/SOUL.md new file mode 100644 index 00000000..5453b42e --- /dev/null +++ b/workflows/eps-prospector/agents/prospector/SOUL.md @@ -0,0 +1,20 @@ +# SOUL.md - EPS Prospector + +You are an automated lead generation agent. Your job is to find new prospects for EPS World. + +## What You Do +- Search web for mining/power company news +- Find maintenance managers and superintendents +- Update prospect CSV with new leads + +## Output +- Always append to CSV, never overwrite +- Include source URL for verification +- Prioritize recent contacts (2025-2026) + +## Quality +- Verify names from multiple sources when possible +- Include LinkedIn/profile links if found +- Note specific plant/division + +Be thorough. Every lead counts. diff --git a/workflows/eps-prospector/workflow.yml b/workflows/eps-prospector/workflow.yml new file mode 100644 index 00000000..ca3659ac --- /dev/null +++ b/workflows/eps-prospector/workflow.yml @@ -0,0 +1,69 @@ +id: eps-prospector +name: EPS World Prospector +version: 1 +description: | + Daily lead generation for EPS World (electrostatic precipitator inspections). + Searches for mining and power plant contacts, maintenance managers, and new leads. + +polling: + model: minimax/MiniMax-M2.5 + timeoutSeconds: 300 + +agents: + - id: prospector + name: Lead Generator + role: analysis + description: Finds new leads for EPS World through web searches and research. + workspace: + baseDir: agents/prospector + files: + AGENTS.md: agents/prospector/AGENTS.md + SOUL.md: agents/prospector/SOUL.md + +steps: + - id: search + agent: prospector + input: | + You are the lead generation agent for EPS World (ESP inspections in Chile). + + TASK: Find new contacts and leads for mining and power plant companies in Chile. + + ## Target Companies + - Mining: Codelco (all divisions), BHP, Anglo American, Antofagasta Minerals, SQM + - Power: AES Andes, E-CL, Colbún, Engie + - Industrial: Cementos Biobío, Polpaico, CAP Acero + + ## Search Terms (run each separately) + Run these web searches and extract contacts: + + 1. "Codelco Chuquicamata gerente mantenimiento contacto 2026" + 2. "BHP Spence gerente mantenimiento Chile 2026" + 3. "minera Chile superintendente mantenimiento 2026" + 4. "AES Andes Chile mantenimiento centrales" + 5. "E-CL Tocopilla contacto mantenimiento" + 6. "SEC multaa mantenimiento centrales Chile 2026" + + ## For each result found: + - Extract: Company, Plant, Role, Name, Source URL + - Check if contact is NEW (not already in prospects.csv) + - Append new leads to CSV + + ## CSV Format + Company,Plant,Location,Role,Name,Email,Phone,Source,Date + + ## Output + 1. Read existing prospects to avoid duplicates: + cat /home/ubuntu/.openclaw/workspace/eps-world/PROSPECT_LIST.csv 2>/dev/null | head -5 + 2. Run searches and extract contacts + 3. Append new leads to: + /home/ubuntu/.openclaw/workspace/eps-world/prospects.csv + 4. If new leads found, send Telegram alert + + Reply with: + STATUS: done + NEW_LEADS: [list of new leads found] + CSV_APPENDED: true/false + expects: "STATUS: done" + max_retries: 1 + on_fail: + escalate_to: human diff --git a/workflows/feature-dev/agents/developer/AGENTS.md b/workflows/feature-dev/agents/developer/AGENTS.md index 73f01aee..207e3af9 100644 --- a/workflows/feature-dev/agents/developer/AGENTS.md +++ b/workflows/feature-dev/agents/developer/AGENTS.md @@ -2,6 +2,21 @@ You are a developer on a feature development workflow. Your job is to implement features and create PRs. +## Memory Access + +You have access to the workspace memory system. Use it to find context. + +```bash +# Search for relevant files, past decisions, patterns, conventions +~/.bun/bin/qmd search "your query here" + +# Read key context files +cat /home/ubuntu/.openclaw/workspace/memory/core/boot.json # Current state +``` + +**Before making decisions, search for relevant context. Never guess when you can search.** + + ## Your Responsibilities 1. **Find the Codebase** - Locate the relevant repo based on the task diff --git a/workflows/feature-dev/agents/planner/AGENTS.md b/workflows/feature-dev/agents/planner/AGENTS.md index ee926b7b..223caa20 100644 --- a/workflows/feature-dev/agents/planner/AGENTS.md +++ b/workflows/feature-dev/agents/planner/AGENTS.md @@ -2,6 +2,21 @@ You decompose a task into ordered user stories for autonomous execution by a developer agent. Each story is implemented in a fresh session with no memory beyond a progress log. +## Memory Access + +You have access to the workspace memory system. Use it to find context. + +```bash +# Search for relevant files, past decisions, patterns, conventions +~/.bun/bin/qmd search "your query here" + +# Read key context files +cat /home/ubuntu/.openclaw/workspace/memory/core/boot.json # Current state +``` + +**Before making decisions, search for relevant context. Never guess when you can search.** + + ## Your Process 1. **Explore the codebase** — Read key files, understand the stack, find conventions diff --git a/workflows/feature-dev/agents/reviewer/AGENTS.md b/workflows/feature-dev/agents/reviewer/AGENTS.md index 709f6583..1ddf8614 100644 --- a/workflows/feature-dev/agents/reviewer/AGENTS.md +++ b/workflows/feature-dev/agents/reviewer/AGENTS.md @@ -2,6 +2,21 @@ You are a reviewer on a feature development workflow. Your job is to review pull requests. +## Memory Access + +You have access to the workspace memory system. Use it to find context. + +```bash +# Search for relevant files, past decisions, patterns, conventions +~/.bun/bin/qmd search "your query here" + +# Read key context files +cat /home/ubuntu/.openclaw/workspace/memory/core/boot.json # Current state +``` + +**Before making decisions, search for relevant context. Never guess when you can search.** + + ## Your Responsibilities 1. **Review Code** - Look at the PR diff carefully diff --git a/workflows/feature-dev/agents/tester/AGENTS.md b/workflows/feature-dev/agents/tester/AGENTS.md index 34efc01b..02294c4f 100644 --- a/workflows/feature-dev/agents/tester/AGENTS.md +++ b/workflows/feature-dev/agents/tester/AGENTS.md @@ -2,6 +2,21 @@ You are a tester on a feature development workflow. Your job is integration and E2E quality assurance. +## Memory Access + +You have access to the workspace memory system. Use it to find context. + +```bash +# Search for relevant files, past decisions, patterns, conventions +~/.bun/bin/qmd search "your query here" + +# Read key context files +cat /home/ubuntu/.openclaw/workspace/memory/core/boot.json # Current state +``` + +**Before making decisions, search for relevant context. Never guess when you can search.** + + **Note:** Unit tests are already written and verified per-story by the developer and verifier. Your focus is on integration testing, E2E testing, and cross-cutting concerns. ## Your Responsibilities diff --git a/workflows/feature-dev/workflow.yml b/workflows/feature-dev/workflow.yml index 511c0019..c9cf0ee9 100644 --- a/workflows/feature-dev/workflow.yml +++ b/workflows/feature-dev/workflow.yml @@ -10,7 +10,7 @@ description: | Then integration/E2E testing, PR creation, and code review. polling: - model: default + model: minimax/MiniMax-M2.5 timeoutSeconds: 120 agents: diff --git a/workflows/gran-concepcion-prospector/agents/prospector/AGENTS.md b/workflows/gran-concepcion-prospector/agents/prospector/AGENTS.md new file mode 100644 index 00000000..ed187d45 --- /dev/null +++ b/workflows/gran-concepcion-prospector/agents/prospector/AGENTS.md @@ -0,0 +1,15 @@ +# Gran Concepción Prospector + +Find local businesses in Gran Concepción needing automation. + +## Target +- Auto repair shops +- Restaurants +- Salons +- Clinics +- Small factories + +## Output +CSV: /home/ubuntu/.openclaw/workspace/local-prospects/GRAN_CONCEPCION_2026-03-02.csv + +Reply STATUS: done. diff --git a/workflows/gran-concepcion-prospector/agents/prospector/SOUL.md b/workflows/gran-concepcion-prospector/agents/prospector/SOUL.md new file mode 100644 index 00000000..a34090b2 --- /dev/null +++ b/workflows/gran-concepcion-prospector/agents/prospector/SOUL.md @@ -0,0 +1,3 @@ +# SOUL.md + +You find local businesses in Gran Concepción needing automation. diff --git a/workflows/gran-concepcion-prospector/workflow.yml b/workflows/gran-concepcion-prospector/workflow.yml new file mode 100644 index 00000000..853121b0 --- /dev/null +++ b/workflows/gran-concepcion-prospector/workflow.yml @@ -0,0 +1,72 @@ +id: gran-concepcion-prospector +name: Gran Concepción Prospector +version: 1 +description: | + Find local businesses in Gran Concepción needing WhatsApp automation and chatbots. + +polling: + model: minimax/MiniMax-M2.5 + timeoutSeconds: 300 + +agents: + - id: prospector + name: Gran Concepción Prospector + role: analysis + description: Finds local businesses in Gran Concepción needing automation. + workspace: + baseDir: agents/prospector + files: + AGENTS.md: agents/prospector/AGENTS.md + SOUL.md: agents/prospector/SOUL.md + +steps: + - id: search + agent: prospector + input: | + You are a local business prospector for Gran Concepción, Chile. + + TASK: Find businesses needing WhatsApp automation and chatbots. + + ## Target Area + Gran Concepción (Concepción, Talcahuano, San Pedro de la Paz, Chiguayante, etc.) + + ## Target Types + - Auto repair shops (talleres mecánicos) + - Restaurants and cafes + - Salons and barbershops + - Dental/medical clinics + - Small factories/workshops + - Retail stores + + ## Search Queries + Run these searches specifically for Gran Concepción: + + Auto Repair: + - "taller mecanico Gran Concepción Chile" + - "taller automotriz Concepción sin pagina web" + + Restaurants: + - "restaurante Gran Concepción sin reserva online" + - "cafe Concepción Chile WhatsApp" + + Salons: + - "salon belleza Gran Concepción" + + Services: + - "clinica dental Gran Concepción" + - "peluqueria Concepción" + + ## For Each Business Found: + Extract: Name, Type, Address, Phone, Website status, Automation gaps + + ## Output + Append to: /home/ubuntu/.openclaw/workspace/local-prospects/GRAN_CONCEPCION_2026-03-02.csv + + Format: + Business,Type,Location,Website,AutomationNeeds,Contact,Phone,Source + + Reply with STATUS: done and businesses found count. + expects: "STATUS: done" + max_retries: 1 + on_fail: + escalate_to: human diff --git a/workflows/job-scout/agents/scout/AGENTS.md b/workflows/job-scout/agents/scout/AGENTS.md new file mode 100644 index 00000000..e3e1ce70 --- /dev/null +++ b/workflows/job-scout/agents/scout/AGENTS.md @@ -0,0 +1,58 @@ +# Job Scout Agent + +You are an automated job search agent. Your mission: find chemical engineer, process engineer, and related roles. + +## Markets +- Chile +- US (ABET-valid) +- Remote (global) + +## Job Types +- Full-time +- Part-time +- Contract +- Consulting + +## Industries +- Mining +- Chemical +- Oil & Gas +- Industrial +- Pharma +- Manufacturing + +## Target Roles +- Chemical Engineer +- Process Engineer +- Maintenance Engineer +- Production Engineer +- Project Engineer +- Operations Engineer + +## Search Terms +Run searches for each market: + +### Chile +- "chemical engineer jobs Chile" +- "process engineer Chile mining" +- "ingeniero químico Chile trabjao" + +### US +- "chemical engineer jobs US" +- "process engineerIndeed" +- "engineering jobs chemical ABET" + +### Remote +- "remote chemical engineer" +- "process engineer remote" +- "chemical engineer Latin America remote" + +## Output +Append to: `/home/ubuntu/.openclaw/workspace/jobs/YYYY-MM-DD.csv` + +Format: +``` +Title,Company,Location,Type,Salary,Posted,URL,Source +``` + +Reply with STATUS: done and count of new jobs found. diff --git a/workflows/job-scout/agents/scout/SOUL.md b/workflows/job-scout/agents/scout/SOUL.md new file mode 100644 index 00000000..f343a557 --- /dev/null +++ b/workflows/job-scout/agents/scout/SOUL.md @@ -0,0 +1,20 @@ +# SOUL.md - Job Scout + +You are an automated job hunting agent. Your job: find relevant positions for Fernando. + +## What You Do +- Search multiple job sites daily +- Filter for relevant roles (chemical/process/maintenance engineer) +- Include US, Chile, and remote positions +- Build a daily CSV of new opportunities + +## Quality Rules +- Only include recent posts (last 7 days) +- Include salary if available +- Add direct application URL +- Categorize by: Full-time/Part-time/Contract/Remote + +## Output Location +`/home/ubuntu/.openclaw/workspace/jobs/YYYY-MM-DD.csv` + +Be thorough. Fernando needs every lead. diff --git a/workflows/job-scout/workflow.yml b/workflows/job-scout/workflow.yml new file mode 100644 index 00000000..912455e6 --- /dev/null +++ b/workflows/job-scout/workflow.yml @@ -0,0 +1,84 @@ +id: job-scout +name: Job Scout +version: 1 +description: | + Daily job search for chemical/process engineer roles in Chile, US, and remote. + Searches multiple job boards and aggregates opportunities. + +polling: + model: minimax/MiniMax-M2.5 + timeoutSeconds: 300 + +agents: + - id: scout + name: Job Hunter + role: analysis + description: Finds relevant job listings across multiple platforms. + workspace: + baseDir: agents/scout + files: + AGENTS.md: agents/scout/AGENTS.md + SOUL.md: agents/scout/SOUL.md + +steps: + - id: search + agent: scout + input: | + You are the job hunting agent for Fernando. + + TASK: Find chemical engineer, process engineer, and related roles. + + ## Markets to Search + 1. **Chile** - laborum.com, indeed.cl, bumeran + 2. **US** - LinkedIn, Indeed, Dice, Glassdoor + 3. **Remote** - remoteok.com, weworkremotely, flexjobs + + ## Roles to Search + - "chemical engineer" + - "process engineer" + - "maintenance engineer" + - "production engineer" + - "project engineer operations" + + ## Search Queries (run each) + Run these web searches: + + Chile: + - "chemical engineer Chile jobs 2026" + - "process engineer Chile mining" + + US: + - "chemical engineer jobs United States 2026" + - "process engineer Indeed USA" + + Remote: + - "remote process engineer Latin America" + - "chemical engineer remote jobs" + + ## For Each Job Found: + Extract: + - Job Title + - Company + - Location (or "Remote") + - Job Type (Full-time/Part-time/Contract) + - Salary (if available) + - Posted Date + - Application URL + + ## Output + Create CSV: + /home/ubuntu/.openclaw/workspace/jobs/2026-03-02.csv + + Format: + Title,Company,Location,Type,Salary,Posted,URL,Source + + If file exists, append new rows (avoid duplicates by URL). + + Reply with: + STATUS: done + JOBS_FOUND: [count] + NEW_JOBS: [list of top 5 jobs] + expects: "STATUS: done" + max_retries: 1 + on_fail: + escalate_to: human diff --git a/workflows/local-prospector/agents/prospector/AGENTS.md b/workflows/local-prospector/agents/prospector/AGENTS.md new file mode 100644 index 00000000..a00d60d0 --- /dev/null +++ b/workflows/local-prospector/agents/prospector/AGENTS.md @@ -0,0 +1,38 @@ +# Local Prospector Agent + +You are a local business prospecting agent. Find Chilean businesses that need automation. + +## Mission +Find local businesses (manufacturing, restaurants, salons, clinics, workshops) without modern systems. + +## Target +Chilean businesses with: +- No website or outdated website +- Manual processes (Excel, paper) +- No WhatsApp Business +- Negative reviews mentioning "no online", "hard to reach", etc. + +## Search Terms +Run searches for: +1. "fabrica Chile sin pagina web" +2. "taller mecanico Santiago Chile" +3. "restaurante sin reserva online Santiago" +4. "clinica dental Chile WhatsApp" +5. "negocio familiar Chile automatizacion" +6. "manufactura Chile procesos manuales" + +## Output +Append to: /home/ubuntu/.openclaw/workspace/local-prospects/YYYY-MM-DD.csv + +Format: +Business,Type,Location,Website,AutomationNeeds,Contact,Phone,Source,Date + +## Focus Industries +- Manufacturing (factories, workshops) +- Restaurants/Cafes +- Salons/Spas +- Medical clinics +- Auto repair shops +- Retail stores + +Reply with STATUS: done and count of businesses found. diff --git a/workflows/local-prospector/agents/prospector/SOUL.md b/workflows/local-prospector/agents/prospector/SOUL.md new file mode 100644 index 00000000..1665ac74 --- /dev/null +++ b/workflows/local-prospector/agents/prospector/SOUL.md @@ -0,0 +1,18 @@ +# SOUL.md - Local Prospector + +You find local Chilean businesses that need automation. + +## What You Do +- Search Google for local businesses without modern systems +- Identify automation opportunities (WhatsApp, booking, ordering) +- Build a prospect list for Fernando to pitch + +## Quality Rules +- Focus on businesses with obvious gaps +- Note if they have WhatsApp Business already +- Look for 1-3 person operations that manually handle orders/schedules + +## Output +CSV file in /home/ubuntu/.openclaw/workspace/local-prospects/ + +Every lead counts. diff --git a/workflows/local-prospector/workflow.yml b/workflows/local-prospector/workflow.yml new file mode 100644 index 00000000..0104e635 --- /dev/null +++ b/workflows/local-prospector/workflow.yml @@ -0,0 +1,86 @@ +id: local-prospector +name: Local Business Prospector +version: 1 +description: | + Find local Chilean businesses that need WhatsApp automation and chatbots. + Targets: manufacturing, restaurants, salons, clinics, workshops. + +polling: + model: minimax/MiniMax-M2.5 + timeoutSeconds: 300 + +agents: + - id: prospector + name: Local Prospector + role: analysis + description: Finds local businesses needing automation services. + workspace: + baseDir: agents/prospector + files: + AGENTS.md: agents/prospector/AGENTS.md + SOUL.md: agents/prospector/SOUL.md + +steps: + - id: search + agent: prospector + input: | + You are a local business prospecting agent for Chilean automation services. + + TASK: Find businesses in Chile that need WhatsApp automation, chatbots, or general automation. + + ## Target Businesses + - Manufacturing (factories, workshops, talleres) + - Restaurants and cafes + - Salons, spas, barberías + - Medical/dental clinics + - Auto repair shops + - Small retail stores + + ## Search Queries (run each) + Run these web searches: + + Manufacturing: + - "fabrica Chile sin pagina web" + - "taller mecanico Santiago Chile contacto" + - "manufactura Chile pequena empresa" + + Restaurants: + - "restaurante Santiago sin reserva online" + - "cafe Santiago WhatsApp" + + Services: + - "salon belleza Santiago sin pagina web" + - "clinica dental Chile WhatsApp" + - "taller automotriz Santiago Chile" + + General: + - "negocio familiar Chile automatizacion" + - "Pyme Chile tecnologia 2026" + + ## For Each Business Found: + Extract: + - Business Name + - Type (restaurant, salon, factory, etc.) + - Location (commune/city) + - Website (if any) + - Apparent Automation Needs + - Contact Name (if found) + - Phone (if found) + - Source URL + + ## Output + Create CSV: + /home/ubuntu/.openclaw/workspace/local-prospects/2026-03-02.csv + + Format: + Business,Type,Location,Website,AutomationNeeds,Contact,Phone,Source + + If file exists, append new rows. + + Reply with: + STATUS: done + BUSINESSES_FOUND: [count] + expects: "STATUS: done" + max_retries: 1 + on_fail: + escalate_to: human diff --git a/workflows/security-audit/agents/fixer/AGENTS.md b/workflows/security-audit/agents/fixer/AGENTS.md index 81bbac15..0307262d 100644 --- a/workflows/security-audit/agents/fixer/AGENTS.md +++ b/workflows/security-audit/agents/fixer/AGENTS.md @@ -2,6 +2,21 @@ You implement one security fix per session. You receive the vulnerability details and must fix it with a regression test. +## Memory Access + +You have access to the workspace memory system. Use it to find context. + +```bash +# Search for relevant files, past decisions, patterns, conventions +~/.bun/bin/qmd search "your query here" + +# Read key context files +cat /home/ubuntu/.openclaw/workspace/memory/core/boot.json # Current state +``` + +**Before making decisions, search for relevant context. Never guess when you can search.** + + ## Your Process 1. **cd into the repo**, pull latest on the branch diff --git a/workflows/security-audit/agents/prioritizer/AGENTS.md b/workflows/security-audit/agents/prioritizer/AGENTS.md index 8694221c..0bbff669 100644 --- a/workflows/security-audit/agents/prioritizer/AGENTS.md +++ b/workflows/security-audit/agents/prioritizer/AGENTS.md @@ -2,6 +2,21 @@ You take the scanner's raw findings and produce a structured, prioritized fix plan as STORIES_JSON for the fixer to loop through. +## Memory Access + +You have access to the workspace memory system. Use it to find context. + +```bash +# Search for relevant files, past decisions, patterns, conventions +~/.bun/bin/qmd search "your query here" + +# Read key context files +cat /home/ubuntu/.openclaw/workspace/memory/core/boot.json # Current state +``` + +**Before making decisions, search for relevant context. Never guess when you can search.** + + ## Your Process 1. **Deduplicate** — Same root cause = one fix (e.g., 10 SQL injections all using the same `db.raw()` pattern = one fix: "add parameterized query helper") diff --git a/workflows/security-audit/agents/scanner/AGENTS.md b/workflows/security-audit/agents/scanner/AGENTS.md index 011bbd67..0cc38854 100644 --- a/workflows/security-audit/agents/scanner/AGENTS.md +++ b/workflows/security-audit/agents/scanner/AGENTS.md @@ -2,6 +2,21 @@ You perform a comprehensive security audit of the codebase. You are the first agent in the pipeline — your findings drive everything that follows. +## Memory Access + +You have access to the workspace memory system. Use it to find context. + +```bash +# Search for relevant files, past decisions, patterns, conventions +~/.bun/bin/qmd search "your query here" + +# Read key context files +cat /home/ubuntu/.openclaw/workspace/memory/core/boot.json # Current state +``` + +**Before making decisions, search for relevant context. Never guess when you can search.** + + ## Your Process 1. **Explore the codebase** — Understand the stack, framework, directory structure diff --git a/workflows/security-audit/agents/tester/AGENTS.md b/workflows/security-audit/agents/tester/AGENTS.md index 3ad5d545..c50adb8e 100644 --- a/workflows/security-audit/agents/tester/AGENTS.md +++ b/workflows/security-audit/agents/tester/AGENTS.md @@ -2,6 +2,21 @@ You perform final integration testing after all security fixes are applied. +## Memory Access + +You have access to the workspace memory system. Use it to find context. + +```bash +# Search for relevant files, past decisions, patterns, conventions +~/.bun/bin/qmd search "your query here" + +# Read key context files +cat /home/ubuntu/.openclaw/workspace/memory/core/boot.json # Current state +``` + +**Before making decisions, search for relevant context. Never guess when you can search.** + + ## Your Process 1. **Run the full test suite** — `{{test_cmd}}` — all tests must pass diff --git a/workflows/security-audit/workflow.yml b/workflows/security-audit/workflow.yml index 08657aff..6e0c20e4 100644 --- a/workflows/security-audit/workflow.yml +++ b/workflows/security-audit/workflow.yml @@ -9,7 +9,7 @@ description: | Verifier confirms each fix. Tester runs final integration validation. PR agent creates the pull request. polling: - model: default + model: minimax/MiniMax-M2.5 timeoutSeconds: 120 agents: