@vercel/factory 0.0.0 → 0.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/eve/index.ts"],"sourcesContent":["import { defineTool } from \"eve/tools\";\nimport { z } from \"zod\";\nimport { changeIdSchema, repositoryIdSchema, signalIdSchema, taskIdSchema } from \"../schema/id\";\nimport { levelSchema } from \"../schema/change\";\nimport { vocabularySchema } from \"../schema/common\";\nimport { taskQuestionSchema } from \"../schema/task\";\nimport type { FactoryStores } from \"../store/engine\";\n\nconst decidedOutcomeSchema = z.enum([\n \"accepted\",\n \"duplicate\",\n \"unactionable\",\n \"low_confidence\",\n \"ignored\",\n]);\n\n/**\n * The factory's store operations wrapped as eve tools. Expose a tool to an\n * agent by re-exporting it from a file under agent/tools/, e.g.\n * `export default factoryTools(stores).get_task;`. Every write goes through\n * the engine, so agents inherit transition legality and receipts.\n */\nexport function factoryTools(stores: FactoryStores) {\n return {\n get_task: defineTool({\n description:\n \"Read one factory task by id: its kind, state, repositories, origin, and results.\",\n inputSchema: z.object({ taskId: taskIdSchema }),\n async execute({ taskId }) {\n const task = await stores.tasks.get(taskId);\n return task ?? { found: false as const, taskId };\n },\n }),\n\n decide_signal: defineTool({\n description:\n \"Record the triage decision for a pending signal. A signal is decided exactly once.\",\n inputSchema: z.object({\n signalId: signalIdSchema,\n outcome: decidedOutcomeSchema,\n reason: z.string().min(1).describe(\"Why this outcome was chosen.\"),\n detail: z\n .string()\n .min(1)\n .optional()\n .describe(\"Severity if accepted, or the duplicate-of signal id.\"),\n }),\n execute({ signalId, outcome, reason, detail }) {\n return stores.signals.decide(signalId, outcome, { reason, detail });\n },\n }),\n\n record_change: defineTool({\n description:\n \"Record the pull request produced for a code_change task. Creates the change, links it to the task, and moves the task to verifying.\",\n inputSchema: z.object({\n taskId: taskIdSchema,\n repositoryId: repositoryIdSchema,\n prNumber: z.number().int().min(1),\n prUrl: z.url(),\n risk: levelSchema.describe(\"Blast radius of the change if it is wrong.\"),\n confidence: levelSchema.describe(\"How certain you are the change is correct.\"),\n summary: z.string().min(1).describe(\"One-sentence description of the change.\"),\n }),\n async execute({ taskId, repositoryId, prNumber, prUrl, risk, confidence, summary }) {\n const change = await stores.changes.create({\n repositoryId,\n taskId,\n prNumber,\n prUrl,\n author: \"factory\",\n risk,\n confidence,\n evidence: {\n reproVerified: false,\n testsAdded: 0,\n checksGreen: false,\n attackPassed: false,\n scopeMatches: false,\n },\n });\n const task = await stores.tasks.transition(taskId, \"verifying\", {\n patch: { changeId: change.id },\n reason: summary,\n });\n return { change, task };\n },\n }),\n\n report_blocked: defineTool({\n description:\n \"Mark a running task as needing a human because the work cannot continue without help.\",\n inputSchema: z.object({\n taskId: taskIdSchema,\n reason: z.string().min(1).describe(\"What is blocking, written for the human.\"),\n }),\n execute({ taskId, reason }) {\n return stores.tasks.transition(taskId, \"needs_human\", { reason });\n },\n }),\n\n ask_question: defineTool({\n description:\n \"Raise a question a human operator must answer. Creates a question task that waits for the answer.\",\n inputSchema: z.object({\n repositoryIds: z.array(repositoryIdSchema).min(1),\n parentTaskId: taskIdSchema\n .optional()\n .describe(\"Task the answer unblocks, when there is one.\"),\n channel: z.string().min(1).describe(\"Reply connector, e.g. github.\"),\n address: z.string().min(1).describe(\"Reply address, e.g. acme/web#41.\"),\n question: taskQuestionSchema.omit({ answer: true, answeredBy: true }),\n }),\n async execute({ repositoryIds, parentTaskId, channel, address, question }) {\n const task = await stores.tasks.create({\n repositoryIds,\n kind: \"question\",\n origin: parentTaskId === undefined ? { operator: \"factory\" } : { parentTaskId },\n replyTo: { channel, address },\n question,\n });\n return stores.tasks.transition(task.id, \"needs_human\");\n },\n }),\n\n append_receipt: defineTool({\n description:\n \"Append one immutable audit receipt for an event worth remembering. Receipts can never be edited or deleted.\",\n inputSchema: z.object({\n repositoryIds: z.array(repositoryIdSchema).min(1),\n taskId: taskIdSchema.optional(),\n changeId: changeIdSchema.optional(),\n kind: vocabularySchema.describe(\"What the receipt is about, e.g. investigation.\"),\n state: vocabularySchema.describe(\"What happened, e.g. flag_ramped.\"),\n reason: z.string().min(1).max(2000).optional(),\n dedupeKey: z\n .string()\n .min(1)\n .optional()\n .describe(\"Same key twice records one receipt instead of two.\"),\n }),\n execute(input) {\n return stores.receipts.append(input);\n },\n }),\n };\n}\n\nexport type FactoryTools = ReturnType<typeof factoryTools>;\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../src/eve/index.ts","../../src/eve/deepsec.ts","../../src/eve/finding.ts","../../src/eve/fetch.ts","../../src/eve/invoke.ts","../../src/eve/verification.ts"],"sourcesContent":["import { defineHook } from \"eve/hooks\";\nimport { defineTool } from \"eve/tools\";\nimport { z } from \"zod\";\nimport { changeIdSchema, repositoryIdSchema, signalIdSchema, taskIdSchema } from \"../schema/id\";\nimport { levelSchema } from \"../schema/change\";\nimport { vocabularySchema } from \"../schema/common\";\nimport { taskQuestionSchema } from \"../schema/task\";\nimport type { FactoryStores } from \"../store/engine\";\n\nconst decidedOutcomeSchema = z.enum([\n \"accepted\",\n \"duplicate\",\n \"unactionable\",\n \"low_confidence\",\n \"ignored\",\n]);\n\nconst recordChangeInputSchema = z.object({\n taskId: taskIdSchema,\n repositoryId: repositoryIdSchema,\n prNumber: z.number().int().min(1),\n prUrl: z.url(),\n risk: levelSchema.describe(\"Blast radius of the change if it is wrong.\"),\n confidence: levelSchema.describe(\"How certain you are the change is correct.\"),\n summary: z.string().min(1).describe(\"One-sentence description of the change.\"),\n});\n\nexport type RecordChangeInput = z.infer<typeof recordChangeInputSchema>;\n\nexport type GateVerdict = { ok: true } | { ok: false; reason: string };\n\nexport interface FactoryToolsOptions {\n /**\n * Pre-action gate for record_change, run as an eve approval policy before\n * the tool executes. Refusals reach the model as a denial with the reason.\n * Gates must fail closed: when they cannot verify, they refuse.\n */\n recordChangeGate?: (input: RecordChangeInput) => Promise<GateVerdict>;\n}\n\n/**\n * The factory's store operations wrapped as eve tools. Expose a tool to an\n * agent by re-exporting it from a file under agent/tools/, e.g.\n * `export default factoryTools(stores).get_task;`. Every write goes through\n * the engine, so agents inherit transition legality and receipts.\n */\nexport function factoryTools(stores: FactoryStores, options: FactoryToolsOptions = {}) {\n const recordChangeGate = options.recordChangeGate;\n return {\n get_task: defineTool({\n description:\n \"Read one factory task by id: its kind, state, repositories, origin, and results.\",\n inputSchema: z.object({ taskId: taskIdSchema }),\n async execute({ taskId }) {\n const task = await stores.tasks.get(taskId);\n return task ?? { found: false as const, taskId };\n },\n }),\n\n decide_signal: defineTool({\n description:\n \"Record the triage decision for a pending signal. A signal is decided exactly once.\",\n inputSchema: z.object({\n signalId: signalIdSchema,\n outcome: decidedOutcomeSchema,\n reason: z.string().min(1).describe(\"Why this outcome was chosen.\"),\n detail: z\n .string()\n .min(1)\n .optional()\n .describe(\"Severity if accepted, or the duplicate-of signal id.\"),\n }),\n execute({ signalId, outcome, reason, detail }) {\n return stores.signals.decide(signalId, outcome, { reason, detail });\n },\n }),\n\n record_change: defineTool({\n description:\n \"Record the pull request produced for a code_change task. Creates the change, links it to the task, and moves the task to verifying.\",\n inputSchema: recordChangeInputSchema,\n ...(recordChangeGate === undefined\n ? {}\n : {\n approval: async ({ toolInput }: { toolInput?: unknown }) => {\n const parsed = recordChangeInputSchema.safeParse(toolInput);\n if (!parsed.success) {\n return {\n type: \"denied\" as const,\n reason: \"record_change input is malformed; fix the arguments and retry\",\n };\n }\n const verdict = await recordChangeGate(parsed.data);\n return verdict.ok\n ? (\"not-applicable\" as const)\n : { type: \"denied\" as const, reason: verdict.reason };\n },\n }),\n async execute({ taskId, repositoryId, prNumber, prUrl, risk, confidence, summary }) {\n const change = await stores.changes.create({\n repositoryId,\n taskId,\n prNumber,\n prUrl,\n author: \"factory\",\n risk,\n confidence,\n evidence: {\n reproVerified: false,\n testsAdded: 0,\n checksGreen: false,\n attackPassed: false,\n scopeMatches: false,\n },\n });\n const task = await stores.tasks.transition(taskId, \"verifying\", {\n patch: { changeId: change.id },\n reason: summary,\n });\n return { change, task };\n },\n }),\n\n finish_task: defineTool({\n description:\n \"Mark your task finished with a summary, for task kinds that have no other outcome tool (for example a security_scan). Not for code_change or verification tasks: those end with record_change and record_verification.\",\n inputSchema: z.object({\n taskId: taskIdSchema,\n summary: z.string().min(1).max(4000).describe(\"What you did and found, for the ledger.\"),\n }),\n async execute({ taskId, summary }) {\n const task = await stores.tasks.get(taskId);\n if (task === null) {\n return { finished: false as const, reason: `${taskId} does not exist` };\n }\n if (task.kind === \"code_change\" || task.kind === \"verification\") {\n return { finished: false as const, reason: `${task.kind} tasks end with their own outcome tool` };\n }\n if (task.state !== \"running\") {\n return { finished: false as const, reason: `task is ${task.state}, not running` };\n }\n // The task machine has no running -> succeeded edge; walk through verifying.\n await stores.tasks.transition(taskId, \"verifying\", { reason: summary });\n const finished = await stores.tasks.transition(taskId, \"succeeded\", { reason: summary });\n return { finished: true as const, taskState: finished.state };\n },\n }),\n\n report_blocked: defineTool({\n description:\n \"Mark a running task as needing a human because the work cannot continue without help.\",\n inputSchema: z.object({\n taskId: taskIdSchema,\n reason: z.string().min(1).describe(\"What is blocking, written for the human.\"),\n }),\n execute({ taskId, reason }) {\n return stores.tasks.transition(taskId, \"needs_human\", { reason });\n },\n }),\n\n ask_question: defineTool({\n description:\n \"Raise a question a human operator must answer. Creates a question task that waits for the answer.\",\n inputSchema: z.object({\n repositoryIds: z.array(repositoryIdSchema).min(1),\n parentTaskId: taskIdSchema\n .optional()\n .describe(\"Task the answer unblocks, when there is one.\"),\n channel: z.string().min(1).describe(\"Reply connector, e.g. github.\"),\n address: z.string().min(1).describe(\"Reply address, e.g. acme/web#41.\"),\n question: taskQuestionSchema.omit({ answer: true, answeredBy: true }),\n }),\n async execute({ repositoryIds, parentTaskId, channel, address, question }) {\n const task = await stores.tasks.create({\n repositoryIds,\n kind: \"question\",\n origin: parentTaskId === undefined ? { operator: \"factory\" } : { parentTaskId },\n replyTo: { channel, address },\n question,\n });\n return stores.tasks.transition(task.id, \"needs_human\");\n },\n }),\n\n append_receipt: defineTool({\n description:\n \"Append one immutable audit receipt for an event worth remembering. Receipts can never be edited or deleted.\",\n inputSchema: z.object({\n repositoryIds: z.array(repositoryIdSchema).min(1),\n taskId: taskIdSchema.optional(),\n changeId: changeIdSchema.optional(),\n kind: vocabularySchema.describe(\"What the receipt is about, e.g. investigation.\"),\n state: vocabularySchema.describe(\"What happened, e.g. flag_ramped.\"),\n reason: z.string().min(1).max(2000).optional(),\n dedupeKey: z\n .string()\n .min(1)\n .optional()\n .describe(\"Same key twice records one receipt instead of two.\"),\n }),\n execute(input) {\n return stores.receipts.append(input);\n },\n }),\n };\n}\n\nexport type FactoryTools = ReturnType<typeof factoryTools>;\n\n/**\n * Observe-only eve hooks that keep the ledger honest about session outcomes.\n * Mount by re-exporting from agent/hooks/, e.g.\n * `export default factoryHooks(stores).factory;`.\n *\n * turn.completed: a turn that ends while its task is still running means the\n * agent finished talking without recording an outcome; the task moves to\n * needs_human instead of rotting. The task is found by the session's\n * channel address, which dispatch set from the task's replyTo.\n */\nexport function factoryHooks(stores: FactoryStores) {\n return {\n factory: defineHook({\n events: {\n async \"turn.completed\"(_event, ctx) {\n const address = ctx.channel.continuationToken;\n if (address === undefined) {\n return;\n }\n const tasks = await stores.tasks.list();\n const abandoned = tasks.filter(\n (task) => task.state === \"running\" && task.replyTo.address === address,\n );\n for (const task of abandoned) {\n // A hook throw fails the turn, so a lost race here is swallowed;\n // the task either moved legally elsewhere or the sweep catches it.\n await stores.tasks\n .transition(task.id, \"needs_human\", {\n reason: \"agent turn ended without recording an outcome\",\n })\n .catch(() => undefined);\n }\n },\n },\n }),\n };\n}\n\nexport type FactoryHooks = ReturnType<typeof factoryHooks>;\n\nexport { deepsecScanTool, findingFromDeepsec, type DeepsecScanOptions } from \"./deepsec\";\nexport { recordFinding, recordFindingTool, type RecordFindingOptions, type RecordFindingResult } from \"./finding\";\nexport {\n fetchPullRequestTool,\n type CommandSandbox,\n type FetchPullRequestOptions,\n type FetchPullRequestResult,\n} from \"./fetch\";\nexport { invokeAgentTool, type InvokeAgentOptions } from \"./invoke\";\nexport { recordVerificationTool } from \"./verification\";\n","import { defineTool } from \"eve/tools\";\nimport { z } from \"zod\";\nimport { findingSchema, type Finding, type FindingPriority } from \"../schema/finding\";\nimport { repositoryIdSchema } from \"../schema/id\";\nimport type { FactoryStores } from \"../store/engine\";\nimport type { CommandSandbox } from \"./fetch\";\nimport { recordFinding, type RecordFindingOptions, type RecordFindingResult } from \"./finding\";\n\nexport interface DeepsecScanOptions<S extends CommandSandbox = CommandSandbox> extends RecordFindingOptions {\n /**\n * Runs one shell command with the model credential deepsec's gateway route\n * expects, and removes it again before resolving. Supplied by the app, which\n * owns where the credential comes from: on Vercel it is the deployment's own\n * OIDC identity (VERCEL_OIDC_TOKEN), so nothing has to be configured.\n */\n withModelCredential: (sandbox: S, command: string) => Promise<{ stdout: string; stderr?: string; exitCode?: number }>;\n /** deepsec agent backend: claude, codex, or pi. */\n agent?: \"claude\" | \"codex\" | \"pi\";\n /** Model deepsec's investigation agent uses, through the AI Gateway (e.g. claude-sonnet-4-6). */\n model?: string;\n /** Reasoning effort for the investigation: minimal, low, medium, high, or xhigh. */\n thinkingLevel?: \"minimal\" | \"low\" | \"medium\" | \"high\" | \"xhigh\";\n /** Parallel investigation batches. */\n concurrency?: number;\n /** deepsec version to install. */\n version?: string;\n /** Repository checkout inside the sandbox. Defaults to `repo`. */\n repoPath?: string;\n /** deepsec workspace inside the sandbox. Defaults to `deepsec`. */\n workspacePath?: string;\n /** Shell run before every deepsec command, e.g. to put a Node 24 on PATH. */\n commandPrefix?: string;\n /**\n * Candidate files investigated per run. deepsec keeps state, so successive\n * scans continue where the last one stopped; the cap keeps one run inside\n * the deployment's time limit on large repositories. Defaults to 40.\n */\n filesPerRun?: number;\n}\n\n/** deepsec's exported finding shape, as far as we depend on it. */\nconst deepsecFindingSchema = z.looseObject({\n title: z.string().min(1),\n description: z.string().min(1),\n severity: z.string().min(1),\n metadata: z\n .looseObject({\n filePath: z.string().min(1).optional(),\n lineNumbers: z.array(z.number().int().min(1)).optional(),\n vulnSlug: z.string().min(1).optional(),\n confidence: z.string().optional(),\n runId: z.string().optional(),\n })\n .optional(),\n});\n\nconst deepsecExportSchema = z.union([\n z.array(deepsecFindingSchema),\n z.looseObject({ findings: z.array(deepsecFindingSchema) }).transform((value) => value.findings),\n]);\n\nconst priorityBySeverity: Record<string, FindingPriority> = {\n CRITICAL: \"P0\",\n HIGH: \"P1\",\n MEDIUM: \"P2\",\n HIGH_BUG: \"P2\",\n BUG: \"P3\",\n LOW: \"P3\",\n};\n\n/** Convert one deepsec finding into the factory's Finding. Pure; exported for tests. */\nexport function findingFromDeepsec(raw: z.infer<typeof deepsecFindingSchema>): Finding {\n const meta = raw.metadata ?? {};\n const confidence = (meta.confidence ?? \"\").toLowerCase();\n const line = meta.lineNumbers?.[0];\n const endLine = meta.lineNumbers === undefined ? undefined : Math.max(...meta.lineNumbers);\n return findingSchema.parse({\n title: raw.title.replace(/^\\[[A-Z_]+\\]\\s*/u, \"\").slice(0, 200),\n body: raw.description.slice(0, 8000),\n ...(meta.filePath === undefined ? {} : { path: meta.filePath.slice(0, 500) }),\n ...(line === undefined ? {} : { line }),\n ...(endLine === undefined || endLine === line ? {} : { endLine }),\n priority: priorityBySeverity[raw.severity.toUpperCase()] ?? \"P3\",\n category: \"security\",\n verification: {\n // deepsec's agent reads the code; it does not run it. Say so.\n level: confidence === \"high\" ? \"supported\" : \"unverified\",\n method: \"static_analysis\",\n summary: `deepsec ${meta.vulnSlug ?? \"finding\"} with ${confidence || \"unknown\"} confidence${meta.runId === undefined ? \"\" : ` (run ${meta.runId})`}.`,\n limitations: \"AI-assisted static analysis of the checkout; not reproduced at runtime.\",\n },\n tool: \"deepsec\",\n ...(meta.vulnSlug === undefined ? {} : { ruleId: meta.vulnSlug }),\n });\n}\n\nconst findingsPath = \"/tmp/deepsec-findings.json\";\n\n/** Parse \"N file(s) with candidates\" out of deepsec scan output; null when absent. */\nfunction candidateCount(output: string): number | null {\n const match = /(\\d+)\\s+file\\(s\\) with candidates/u.exec(output);\n return match?.[1] === undefined ? null : Number(match[1]);\n}\n\n/** The last few meaningful lines of a command's output, ANSI stripped, for a receipt. */\nfunction tail(output: string, lines = 4): string {\n // eslint-disable-next-line no-control-regex -- stripping terminal colour codes\n const ansi = /\\u001b\\[[0-9;]*m/gu;\n return output\n .replaceAll(ansi, \"\")\n .split(\"\\n\")\n .map((line) => line.trim())\n .filter((line) => line !== \"\")\n .slice(-lines)\n .join(\" | \")\n .slice(0, 600);\n}\n\n/**\n * Runs deepsec (vercel-labs/deepsec) against the sandbox checkout and records\n * what it finds through the same path as record_finding, so every deepsec\n * finding becomes a fix task subject to the approval policy. Trusted code\n * owns the command sequence and the credential; the agent chooses when to\n * scan and reports the outcome.\n */\nexport function deepsecScanTool<S extends CommandSandbox>(stores: FactoryStores, options: DeepsecScanOptions<S>) {\n const repoPath = options.repoPath ?? \"repo\";\n const workspace = options.workspacePath ?? \"deepsec\";\n const version = options.version ?? \"2.3.8\";\n const agent = options.agent ?? \"claude\";\n const model = options.model ?? \"claude-sonnet-4-6\";\n const thinkingLevel = options.thinkingLevel ?? \"medium\";\n const concurrency = options.concurrency ?? 4;\n const prefix = options.commandPrefix === undefined ? [] : [options.commandPrefix];\n const filesPerRun = options.filesPerRun ?? 40;\n\n return defineTool({\n description:\n \"Run deepsec, the AI-powered vulnerability scanner, over the repository checkout and record every finding it reports as a fix task. Takes minutes. Call once per scan; then summarize the result.\",\n inputSchema: z.object({\n repositoryId: repositoryIdSchema,\n limit: z\n .number()\n .int()\n .min(1)\n .max(500)\n .optional()\n .describe(\"Candidate files to investigate this run (default 40; deepsec resumes where it left off next time).\"),\n }),\n async execute({ repositoryId, limit }, ctx) {\n const repository = await stores.repositories.get(repositoryId);\n if (repository === null) {\n return { scanned: false as const, reason: `repository ${repositoryId} does not exist` };\n }\n const sandbox = (await ctx.getSandbox()) as unknown as S;\n const projectId = repository.slug.replace(/[^a-z0-9]+/gu, \"-\");\n const startedAt = Date.now();\n\n // One receipt per phase, so the ledger answers \"where is the scan\" while\n // deepsec runs and shows what each phase cost afterwards.\n const phase = async (state: string, reason: string): Promise<void> => {\n await stores.receipts.append({\n repositoryIds: [repositoryId],\n kind: \"deepsec\",\n state,\n phase: \"security_scan\",\n reason: `${reason} (${Math.round((Date.now() - startedAt) / 1000)}s in)`,\n });\n };\n await phase(\"started\", `deepsec ${version} on ${repository.slug}, ${agent}/${model}`);\n\n // Workspace: scaffolded once per sandbox, installed from npm. deepsec\n // needs Node 24; the sandbox bootstrap is expected to provide it.\n const prepare = await sandbox.run({\n command: [\n ...prefix,\n \"set -e\",\n `if [ ! -f ${workspace}/deepsec.config.ts ]; then`,\n ` npx -y deepsec@${version} init ./${workspace} ./${repoPath} --id ${projectId} --scaffold-only --headless --yes --skip-install`,\n ` (cd ${workspace} && npm install --no-audit --no-fund --loglevel=error)`,\n \"fi\",\n // deepsec resolves deepsec.config.ts from the current directory, so\n // every deepsec command runs inside the workspace. No --root: it is a\n // one-off override that skips the project's file records, leaving\n // `process` with nothing to investigate.\n `cd ${workspace}`,\n `./node_modules/.bin/deepsec scan --project-id ${projectId}`,\n ].join(\"\\n\"),\n });\n if (typeof prepare.exitCode === \"number\" && prepare.exitCode !== 0) {\n const detail = (prepare.stderr ?? prepare.stdout).trim().slice(-1500);\n await phase(\"failed\", `scan phase failed: ${detail.slice(-300)}`);\n return { scanned: false as const, reason: `deepsec scan failed: ${detail}` };\n }\n const candidates = candidateCount(prepare.stdout);\n await phase(\n \"scanned\",\n `${candidates === null ? \"scan output\" : `${candidates} files with candidates`}: ${tail(`${prepare.stdout}\\n${prepare.stderr ?? \"\"}`)}`,\n );\n\n // Investigation talks to the model through the AI Gateway (deepsec's\n // default route); this is the only step that needs a credential.\n const investigate = await options.withModelCredential(\n sandbox,\n [\n ...prefix,\n \"set -e\",\n `cd ${workspace}`,\n `./node_modules/.bin/deepsec process --project-id ${projectId} --agent ${agent} --model ${model} --thinking-level ${thinkingLevel} --concurrency ${concurrency} --limit ${limit ?? filesPerRun}`,\n `./node_modules/.bin/deepsec export --project-id ${projectId} --format json --out ${findingsPath}`,\n ].join(\"\\n\"),\n );\n if (typeof investigate.exitCode === \"number\" && investigate.exitCode !== 0) {\n const detail = (investigate.stderr ?? investigate.stdout).trim().slice(-1500);\n await phase(\"failed\", `process phase failed: ${detail.slice(-300)}`);\n return { scanned: false as const, reason: `deepsec process failed: ${detail}` };\n }\n\n const exported = await sandbox.run({ command: `cat ${findingsPath}` });\n let parsed: unknown;\n try {\n parsed = JSON.parse(exported.stdout);\n } catch {\n return { scanned: false as const, reason: \"deepsec export was not valid JSON\" };\n }\n const raw = deepsecExportSchema.safeParse(parsed);\n if (!raw.success) {\n return { scanned: false as const, reason: `deepsec export had an unexpected shape: ${raw.error.issues[0]?.message ?? \"unknown\"}` };\n }\n\n const results: { finding: Finding; result: RecordFindingResult }[] = [];\n for (const entry of raw.data) {\n const finding = findingFromDeepsec(entry);\n results.push({ finding, result: await recordFinding(stores, repositoryId, finding, options) });\n }\n const recorded = results.filter(({ result }) => result.recorded);\n await phase(\n \"completed\",\n `${results.length} findings, ${recorded.length} new. process output: ${tail(`${investigate.stdout}\\n${investigate.stderr ?? \"\"}`, 6)}`,\n );\n return {\n scanned: true as const,\n tool: \"deepsec\",\n found: results.length,\n recorded: recorded.length,\n duplicates: results.length - recorded.length,\n awaitingApproval: recorded.filter(({ result }) => result.recorded && result.approval === \"required\").length,\n findings: results.map(({ finding, result }) => ({\n title: finding.title,\n priority: finding.priority,\n path: finding.path,\n line: finding.line,\n ...(result.recorded ? { taskId: result.taskId, approval: result.approval } : { duplicate: true }),\n })),\n };\n },\n });\n}\n","import { defineTool } from \"eve/tools\";\nimport { z } from \"zod\";\nimport { defaultApprovalPolicy, requiresApproval, type ApprovalPolicy } from \"../approval\";\nimport { findingFingerprint, findingSchema, type Finding } from \"../schema/finding\";\nimport { repositoryIdSchema } from \"../schema/id\";\nimport type { FactoryStores } from \"../store/engine\";\n\nexport interface RecordFindingOptions {\n /** Signal source the findings are recorded under. Defaults to security_scan. */\n source?: string;\n /** Which resulting tasks wait for a human. Defaults to the standard policy. */\n approval?: ApprovalPolicy;\n}\n\nexport type RecordFindingResult =\n | { recorded: false; reason: string; duplicate?: true; signalId?: string }\n | { recorded: true; signalId: string; taskId: string; approval: \"required\" | \"not_required\" };\n\n/**\n * Turn one finding into a signal and a fix task. The fingerprint is the\n * signal's delivery id, so the same problem reported twice is a no-op. The\n * signal is accepted on the reporter's own verification (a human gate follows\n * when the approval policy says so), and the task carries the approval\n * decision from the moment it exists. Shared by record_finding and scanner\n * tools that record on the agent's behalf.\n */\nexport async function recordFinding(\n stores: FactoryStores,\n repositoryId: string,\n finding: Finding,\n options: RecordFindingOptions = {},\n): Promise<RecordFindingResult> {\n const source = options.source ?? \"security_scan\";\n const policy = options.approval ?? defaultApprovalPolicy;\n const repository = await stores.repositories.get(repositoryId);\n if (repository === null) {\n return { recorded: false, reason: `repository ${repositoryId} does not exist` };\n }\n\n const fingerprint = findingFingerprint(repositoryId, finding);\n const signal = await stores.signals.create({\n repositoryId,\n source,\n deliveryId: fingerprint,\n replyTo: { channel: \"finding\", address: fingerprint },\n payload: finding,\n });\n if (signal.outcome !== \"pending\") {\n return { recorded: false, duplicate: true, signalId: signal.id, reason: `already recorded as ${signal.id}` };\n }\n\n await stores.signals.decide(signal.id, \"accepted\", {\n detail: finding.priority,\n reason: `${finding.tool ?? \"scanner\"} reported it, ${finding.verification.level} by ${finding.verification.method}`,\n });\n\n const approval = requiresApproval(policy, { source, kind: \"code_change\", priority: finding.priority });\n const task = await stores.tasks.create({\n repositoryIds: [repositoryId],\n kind: \"code_change\",\n origin: { signalId: signal.id },\n replyTo: signal.replyTo,\n ...(approval ? { approval: \"required\" as const } : {}),\n });\n\n return { recorded: true, signalId: signal.id, taskId: task.id, approval: approval ? \"required\" : \"not_required\" };\n}\n\n/**\n * The scanner's outcome tool: turns one finding into a signal and a fix task\n * in a single deterministic step. The finding's fingerprint is the signal's\n * delivery id, so reporting the same problem twice is a no-op. The signal is\n * accepted on the reporter's own verification (a human gate follows when the\n * approval policy says so), and the task carries the approval decision from\n * the moment it exists.\n */\nexport function recordFindingTool(stores: FactoryStores, options: RecordFindingOptions = {}) {\n return defineTool({\n description:\n \"Record one problem you found in the repository. Creates a fix task (which may wait for human approval) unless the same finding was already recorded. Report every finding separately; never batch.\",\n inputSchema: z.object({\n repositoryId: repositoryIdSchema,\n finding: findingSchema,\n }),\n execute({ repositoryId, finding }) {\n return recordFinding(stores, repositoryId, finding, options);\n },\n });\n}\n","import { defineTool } from \"eve/tools\";\nimport { z } from \"zod\";\nimport { changeIdSchema } from \"../schema/id\";\nimport type { FactoryStores } from \"../store/engine\";\n\n/** The subset of the eve sandbox handle a credentialed git operation needs. */\nexport interface CommandSandbox {\n run(options: { command: string }): PromiseLike<{\n stdout: string;\n stderr?: string;\n exitCode?: number;\n }>;\n}\n\nexport interface FetchPullRequestOptions<S extends CommandSandbox = CommandSandbox> {\n /**\n * Runs one git command against `slug` with a credential the sandbox does not\n * otherwise have, and removes it again before resolving. Supplied by the\n * app, which owns how credentials are minted and where they are injected;\n * the library only decides what is fetched.\n */\n withCredential: (\n sandbox: S,\n slug: string,\n command: string,\n ) => Promise<{ stdout: string; stderr?: string; exitCode?: number }>;\n /** Path of the checkout inside the sandbox. Defaults to `repo`. */\n repoPath?: string;\n /** Fetch depth for the pull request head. Defaults to 50. */\n depth?: number;\n}\n\nexport type FetchPullRequestResult =\n | { fetched: false; reason: string }\n | { fetched: true; prNumber: number; prUrl: string; branch: string; headSha: string };\n\n/**\n * The verifier's way in to the change under review. The sandbox has no\n * GitHub credential while the agent runs, so trusted code does the one fetch\n * the agent cannot: the pull request number and repository come from the\n * change record, never from the agent, and the credential is gone again\n * before control returns. Mirrors how publication reads commits out of the\n * sandbox instead of letting the agent push.\n */\nexport function fetchPullRequestTool<S extends CommandSandbox>(\n stores: FactoryStores,\n options: FetchPullRequestOptions<S>,\n) {\n const repoPath = options.repoPath ?? \"repo\";\n const depth = options.depth ?? 50;\n return defineTool({\n description:\n \"Fetch the pull request under review into the checkout and check it out as the local branch `pr`. Call this after get_task, before inspecting or testing the change. Returns the PR number, URL, and the commit you are now on.\",\n inputSchema: z.object({\n changeId: changeIdSchema.describe(\"The change under review, from your starting message.\"),\n }),\n async execute({ changeId }, ctx): Promise<FetchPullRequestResult> {\n const change = await stores.changes.get(changeId);\n if (change === null) {\n return { fetched: false, reason: `change ${changeId} does not exist` };\n }\n if (change.state !== \"verifying\") {\n return { fetched: false, reason: `change is ${change.state}, not verifying; nothing to fetch` };\n }\n const repository = await stores.repositories.get(change.repositoryId);\n if (repository === null) {\n return { fetched: false, reason: `repository ${change.repositoryId} does not exist` };\n }\n\n // Fetch into a remote-tracking ref (never the checked-out branch, which\n // git refuses to update), then move the local `pr` branch onto it so a\n // repeated call picks up a force-pushed head.\n const sandbox = (await ctx.getSandbox()) as unknown as S;\n const tracking = `refs/remotes/origin/pr-${change.prNumber}`;\n const git = `git -C ${repoPath}`;\n const result = await options.withCredential(\n sandbox,\n repository.slug,\n `${git} fetch --depth ${depth} origin +refs/pull/${change.prNumber}/head:${tracking} && ${git} checkout -B pr ${tracking}`,\n );\n if (typeof result.exitCode === \"number\" && result.exitCode !== 0) {\n return {\n fetched: false,\n reason: `git fetch of pull request ${change.prNumber} failed: ${(result.stderr ?? \"\").trim()}`,\n };\n }\n\n const head = await sandbox.run({ command: `${git} rev-parse HEAD` });\n return {\n fetched: true,\n prNumber: change.prNumber,\n prUrl: change.prUrl,\n branch: \"pr\",\n headSha: head.stdout.trim(),\n };\n },\n });\n}\n","import { defineTool } from \"eve/tools\";\nimport { z } from \"zod\";\nimport { dispatchTask } from \"../dispatch\";\nimport { changeIdSchema, repositoryIdSchema, taskIdSchema } from \"../schema/id\";\nimport type { FactoryStores } from \"../store/engine\";\n\nexport interface InvokeAgentOptions {\n /** The factory task kind the handoff creates, e.g. \"verification\". */\n kind: string;\n /** Model-facing description of what the target agent does and when to invoke it. */\n description: string;\n /**\n * Base URL of the target agent's eve transport, e.g.\n * `https://factory.example.com/eve/agents/verifier`. Resolved at call time so\n * a deployment can derive it from its own origin.\n */\n targetUrl: () => string;\n /** Bearer token for the target agent's eve channel, when it requires auth. */\n token?: () => Promise<string | undefined>;\n /** Extra headers for the session request, e.g. a deployment protection bypass. */\n headers?: () => Record<string, string> | Promise<Record<string, string>>;\n fetch?: typeof fetch;\n}\n\n/**\n * A tool that lets one agent hand work to another, NMA-style: the caller\n * decides to invoke; trusted code owns the how. The handoff is recorded as a\n * factory task (single-winner dispatch, receipts), then a fresh session is\n * started on the target agent carrying only the task id — never the caller's\n * context. The session start is create-once on the task id, so a retried\n * tool call cannot start a second session.\n */\nexport function invokeAgentTool(stores: FactoryStores, options: InvokeAgentOptions) {\n const doFetch = options.fetch ?? fetch;\n return defineTool({\n description: `${options.description} Hands the work to a separate agent in a fresh session; you will not see its reasoning. Returns the handoff task id.`,\n inputSchema: z.object({\n repositoryIds: z.array(repositoryIdSchema).min(1),\n parentTaskId: taskIdSchema.optional().describe(\"Your own task, when this work continues it.\"),\n changeId: changeIdSchema.optional().describe(\"The change the target agent should work on.\"),\n channel: z.string().min(1).describe(\"Reply connector, e.g. github.\"),\n address: z.string().min(1).describe(\"Reply address, e.g. acme/web#41.\"),\n brief: z\n .string()\n .min(1)\n .max(4000)\n .describe(\"What the target agent needs to know. Facts and references only, not your reasoning.\"),\n }),\n async execute(input) {\n const task = await stores.tasks.create({\n repositoryIds: input.repositoryIds,\n kind: options.kind,\n origin:\n input.parentTaskId === undefined ? { operator: \"factory\" } : { parentTaskId: input.parentTaskId },\n replyTo: { channel: input.channel, address: input.address },\n });\n\n const running = await dispatchTask(stores, task.id, {\n launch: async (dispatched) => {\n const headers: Record<string, string> = {\n \"content-type\": \"application/json\",\n ...(await options.headers?.()),\n };\n const token = await options.token?.();\n if (token !== undefined) {\n headers.authorization = `Bearer ${token}`;\n }\n const message = [\n `You are assigned factory task ${dispatched.id}.`,\n input.changeId === undefined ? null : `Change under review: ${input.changeId}.`,\n `Reply address: ${input.channel} ${input.address}.`,\n \"\",\n input.brief,\n \"\",\n \"Read the task with get_task first, do the work, and record the outcome with your factory tools.\",\n ]\n .filter((line) => line !== null)\n .join(\"\\n\");\n const response = await doFetch(`${options.targetUrl()}/eve/v1/session`, {\n method: \"POST\",\n headers,\n body: JSON.stringify({ message, operationId: `factory-task:${dispatched.id}` }),\n });\n if (!response.ok) {\n throw new Error(`target agent refused the session: ${response.status}`);\n }\n },\n });\n\n return { taskId: running.id, kind: running.kind, state: running.state };\n },\n });\n}\n","import { defineTool } from \"eve/tools\";\nimport { z } from \"zod\";\nimport { changeEvidenceSchema, levelSchema } from \"../schema/change\";\nimport { changeIdSchema, taskIdSchema } from \"../schema/id\";\nimport type { FactoryStores } from \"../store/engine\";\n\n/**\n * The verifier's outcome tool. Writes evidence onto the change and moves it\n * to ready only when the verdict is pass; a failed verdict leaves the change\n * verifying with the evidence recorded, and the verification task itself\n * ends with a receipt either way. The change's own code_change task follows\n * the verdict too: succeeded on pass, failed on fail with the verifier's\n * summary as the reason, so the ledger never shows a verified-and-rejected fix\n * as still in progress. Fail closed: the agent cannot mark a change ready\n * without supplying every evidence field.\n */\nexport function recordVerificationTool(stores: FactoryStores) {\n return defineTool({\n description:\n \"Record the outcome of a verification task: the evidence you gathered and whether the change passed. Pass moves the change to ready for human review; fail keeps it out of review.\",\n inputSchema: z.object({\n taskId: taskIdSchema.describe(\"Your verification task.\"),\n changeId: changeIdSchema.describe(\"The change you verified.\"),\n verdict: z.enum([\"pass\", \"fail\"]),\n evidence: changeEvidenceSchema,\n confidence: levelSchema.describe(\"How certain you are in the verdict.\"),\n summary: z.string().min(1).max(2000).describe(\"What you checked and what you found.\"),\n }),\n async execute({ taskId, changeId, verdict, evidence, confidence, summary }) {\n const change = await stores.changes.get(changeId);\n if (change === null) {\n return { recorded: false as const, reason: `change ${changeId} does not exist` };\n }\n if (change.state !== \"verifying\") {\n return {\n recorded: false as const,\n reason: `change is ${change.state}, not verifying; nothing to record`,\n };\n }\n\n const task = await stores.tasks.get(taskId);\n if (task === null || task.kind !== \"verification\") {\n return { recorded: false as const, reason: `${taskId} is not a verification task` };\n }\n\n let updatedChange = change;\n if (verdict === \"pass\") {\n updatedChange = await stores.changes.transition(changeId, \"ready\", {\n patch: { evidence, confidence },\n reason: summary,\n });\n }\n\n // The task machine has no running -> succeeded edge; a passing\n // verification walks running -> verifying -> succeeded, a failing one\n // ends directly at failed.\n let finished;\n if (verdict === \"pass\") {\n await stores.tasks.transition(taskId, \"verifying\", { reason: summary });\n finished = await stores.tasks.transition(taskId, \"succeeded\");\n } else {\n finished = await stores.tasks.transition(taskId, \"failed\", { reason: summary });\n }\n\n // The fix task that produced the change. It sat in verifying while the\n // verifier worked; settle it the same way. A missing or already-settled\n // parent is not the verifier's problem, so tolerate it.\n if (change.taskId !== undefined) {\n const parent = await stores.tasks.get(change.taskId);\n if (parent?.state === \"verifying\") {\n await stores.tasks\n .transition(\n change.taskId,\n verdict === \"pass\" ? \"succeeded\" : \"failed\",\n verdict === \"pass\" ? {} : { reason: `verification failed: ${summary}` },\n )\n .catch(() => undefined);\n }\n }\n\n return {\n recorded: true as const,\n verdict,\n changeState: updatedChange.state,\n taskState: finished.state,\n };\n },\n });\n}\n"],"mappings":"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","names":["defineTool","z","defineTool","z","z","defineTool","defineTool","z","defineTool","z","defineTool","z","defineTool","z","defineTool","z","defineTool","z","z","defineTool"]}
package/dist/index.d.ts CHANGED
@@ -1,10 +1,60 @@
1
- import { T as Task, a as TaskId, F as FactoryStores, C as ChangeState, S as SignalOutcome, b as TaskState } from './engine-BXVTLiXU.js';
2
- export { A as AppendReceiptInput, c as Change, d as ChangeEvidence, e as ChangeId, f as ChangePatch, g as ChangeTransitionOptions, h as Cost, i as CreateChangeInput, j as CreateSignalInput, k as CreateStoresOptions, l as CreateTaskInput, D as DecideSignalOptions, m as FactoryId, L as Level, R as Receipt, n as ReceiptId, o as ReceiptKind, p as ReceiptPhase, q as ReceiptState, r as Repository, s as RepositoryId, t as RepositorySlug, u as Signal, v as SignalId, w as SignalSource, x as TaskKind, y as TaskPatch, z as TaskTransitionOptions, B as changeEvidenceSchema, E as changeIdSchema, G as changeSchema, H as changeStateSchema, I as costSchema, J as createStores, K as factoryIdSchema, M as harnessSchema, N as levelSchema, O as receiptIdSchema, P as receiptKindSchema, Q as receiptPhaseSchema, U as receiptSchema, V as receiptStateSchema, W as repositoryIdSchema, X as repositoryIdsSchema, Y as repositorySchema, Z as repositorySlugSchema, _ as signalIdSchema, $ as signalOutcomeSchema, a0 as signalSchema, a1 as signalSourceSchema, a2 as standardReceiptKinds, a3 as standardReceiptPhases, a4 as standardReceiptStates, a5 as standardSignalSources, a6 as standardTaskKinds, a7 as taskDevboxSchema, a8 as taskIdSchema, a9 as taskKindSchema, aa as taskOriginSchema, ab as taskQuestionSchema, ac as taskSchema, ad as taskStateSchema } from './engine-BXVTLiXU.js';
1
+ import { F as FactoryStores, T as Task, a as Finding, R as Repository, b as TaskId, C as ChangeState, S as SignalOutcome, c as TaskState, d as CreateSignalInput, e as Signal } from './approval-Z7iaWibT.js';
2
+ export { f as AppendReceiptInput, g as ApprovalDecision, h as ApprovalError, A as ApprovalPolicy, i as ApprovalRule, j as ApprovalSubject, k as Change, l as ChangeEvidence, m as ChangeId, n as ChangePatch, o as ChangeTransitionOptions, p as Cost, q as CreateChangeInput, r as CreateStoresOptions, s as CreateTaskInput, D as DecideSignalOptions, t as FactoryId, u as FindingCategory, v as FindingPriority, w as FindingVerification, L as Level, x as Receipt, y as ReceiptId, z as ReceiptKind, B as ReceiptPhase, E as ReceiptState, G as RepositoryId, H as RepositorySlug, I as SignalId, J as SignalSource, K as TaskApproval, M as TaskKind, N as TaskPatch, O as TaskTransitionOptions, P as approvalPolicySchema, Q as approvalRuleSchema, U as changeEvidenceSchema, V as changeIdSchema, W as changeSchema, X as changeStateSchema, Y as costSchema, Z as createStores, _ as defaultApprovalPolicy, $ as factoryIdSchema, a0 as findingCategorySchema, a1 as findingFingerprint, a2 as findingPrioritySchema, a3 as findingSchema, a4 as findingVerificationLevelSchema, a5 as findingVerificationMethodSchema, a6 as findingVerificationSchema, a7 as harnessSchema, a8 as levelSchema, a9 as receiptIdSchema, aa as receiptKindSchema, ab as receiptPhaseSchema, ac as receiptSchema, ad as receiptStateSchema, ae as repositoryIdSchema, af as repositoryIdsSchema, ag as repositorySchema, ah as repositorySlugSchema, ai as requiresApproval, aj as signalIdSchema, ak as signalOutcomeSchema, al as signalSchema, am as signalSourceSchema, an as standardReceiptKinds, ao as standardReceiptPhases, ap as standardReceiptStates, aq as standardSignalSources, ar as standardTaskKinds, as as taskApprovalSchema, at as taskDevboxSchema, au as taskIdSchema, av as taskKindSchema, aw as taskOriginSchema, ax as taskQuestionSchema, ay as taskSchema, az as taskStateSchema } from './approval-Z7iaWibT.js';
3
+ import { EveNextConfig, EveNextConfigInput, EveNextConfigFunction } from 'eve/next';
3
4
  import { z } from 'zod';
4
5
  export { R as ReplyTo, S as SCHEMA_VERSION, i as isoDateTimeSchema, r as replyToSchema, s as schemaVersionSchema, u as usdSchema, v as vocabularySchema } from './common-CaHaEOAS.js';
5
6
  import { S as StoreDriver } from './driver-tRNggCCJ.js';
6
7
  export { C as CollectionName, R as RecordExistsError, a as RecordNotFoundError, b as StoredEntry, c as StoredRecord, V as VersionConflictError } from './driver-tRNggCCJ.js';
7
8
 
9
+ /** The finding behind a task, when its signal carries one. */
10
+ declare function findingForTask(stores: FactoryStores, task: Task): Promise<Finding | null>;
11
+ /**
12
+ * The foreman's starting message for a fix task: facts only, never the
13
+ * reporter's reasoning. The finding text is untrusted data and is labelled so.
14
+ */
15
+ declare function fixBrief(task: Task, repository: Repository, finding: Finding | null): string;
16
+ /** The scanner's starting message for a scan task. */
17
+ declare function scanBrief(task: Task, repository: Repository): string;
18
+
19
+ declare const factoryConfigRepositorySchema: z.ZodObject<{
20
+ slug: z.ZodString;
21
+ dependsOn: z.ZodDefault<z.ZodArray<z.ZodString>>;
22
+ }, z.core.$strict>;
23
+ declare const factoryConfigSchema: z.ZodObject<{
24
+ connectors: z.ZodDefault<z.ZodObject<{
25
+ github: z.ZodArray<z.ZodObject<{
26
+ owner: z.ZodString;
27
+ connector: z.ZodString;
28
+ }, z.core.$strict>>;
29
+ }, z.core.$strict>>;
30
+ repositories: z.ZodArray<z.ZodObject<{
31
+ slug: z.ZodString;
32
+ dependsOn: z.ZodDefault<z.ZodArray<z.ZodString>>;
33
+ }, z.core.$strict>>;
34
+ operators: z.ZodArray<z.ZodString>;
35
+ approval: z.ZodDefault<z.ZodArray<z.ZodObject<{
36
+ source: z.ZodOptional<z.ZodString>;
37
+ kind: z.ZodOptional<z.ZodString>;
38
+ priority: z.ZodOptional<z.ZodArray<z.ZodEnum<{
39
+ P0: "P0";
40
+ P1: "P1";
41
+ P2: "P2";
42
+ P3: "P3";
43
+ }>>>;
44
+ require: z.ZodBoolean;
45
+ }, z.core.$strict>>>;
46
+ }, z.core.$strict>;
47
+ type FactoryConfig = z.infer<typeof factoryConfigSchema>;
48
+ type FactoryConfigInput = z.input<typeof factoryConfigSchema>;
49
+ declare function defineFactory(config: FactoryConfigInput): FactoryConfig;
50
+
51
+ interface FactoryArgs<TConfig extends EveNextConfig = EveNextConfig> {
52
+ factoryConfig: FactoryConfigInput;
53
+ nextConfig: EveNextConfigInput<TConfig>;
54
+ root?: string;
55
+ }
56
+ declare function buildFactory<TConfig extends EveNextConfig>({ factoryConfig, nextConfig, root, }: FactoryArgs<TConfig>): EveNextConfigFunction<TConfig>;
57
+
8
58
  declare class DispatchRefusedError extends Error {
9
59
  readonly taskId: TaskId;
10
60
  readonly reason: string;
@@ -70,6 +120,45 @@ declare class InvalidTransitionError<State extends string> extends Error {
70
120
  declare function assertTransition<State extends string>(transitions: readonly Transition<State>[], from: State, to: State): void;
71
121
  declare function terminalStates<State extends string>(transitions: readonly Transition<State>[]): readonly State[];
72
122
 
123
+ interface SignalCreator {
124
+ create(input: CreateSignalInput): Promise<Signal>;
125
+ }
126
+ /**
127
+ * Bind normalized intake to signal creation alone. Connectors and API routes
128
+ * own authentication and normalization; configured workflows own what happens
129
+ * next.
130
+ */
131
+ declare function createSignalCreator(stores: Pick<FactoryStores, "signals">): SignalCreator;
132
+
73
133
  declare function createInMemoryDriver(): StoreDriver;
74
134
 
75
- export { type Budget, ChangeState, type DispatchOptions, DispatchRefusedError, FactoryStores, InvalidTransitionError, SignalOutcome, StoreDriver, Task, TaskId, TaskState, type Transition, type TransitionActor, assertTransition, budgetMonthSchema, budgetSchema, changeInitialState, changeTransitions, createInMemoryDriver, dispatchTask, isTransitionAllowed, legalNextStates, signalInitialOutcome, signalOutcomeTransitions, taskInitialState, taskTransitions, terminalStates };
135
+ /** Starts the agent for one task kind. Supplied by the app, which knows its agents' addresses. */
136
+ type TaskLauncher = (task: Task, repository: Repository) => Promise<void>;
137
+ interface SweepOptions {
138
+ /** Launcher per task kind, e.g. code_change -> foreman, security_scan -> security-scanner. */
139
+ launchers: Readonly<Record<string, TaskLauncher>>;
140
+ }
141
+ interface SweepResult {
142
+ dispatched: string[];
143
+ /** Tasks left in the queue and why: awaiting approval, no launcher, missing repository. */
144
+ skipped: {
145
+ taskId: string;
146
+ reason: string;
147
+ }[];
148
+ /** Tasks whose launch threw; dispatchTask has already recorded them as failed. */
149
+ failed: {
150
+ taskId: string;
151
+ reason: string;
152
+ }[];
153
+ }
154
+ /**
155
+ * One pass of the factory's dispatcher, meant to run on a schedule inside the
156
+ * deployment: every queued task that is allowed to run is started, in
157
+ * creation order. Nothing outside the factory ever starts an agent; the CLI
158
+ * and the dashboard only write tasks and approvals, and this picks them up.
159
+ * Idempotent by construction: dispatchTask's single-winner transition means
160
+ * two overlapping sweeps cannot start the same task twice.
161
+ */
162
+ declare function sweepQueued(stores: FactoryStores, options: SweepOptions): Promise<SweepResult>;
163
+
164
+ export { type Budget, ChangeState, CreateSignalInput, type DispatchOptions, DispatchRefusedError, type FactoryArgs, type FactoryConfig, type FactoryConfigInput, FactoryStores, Finding, InvalidTransitionError, Repository, Signal, type SignalCreator, SignalOutcome, StoreDriver, type SweepOptions, type SweepResult, Task, TaskId, type TaskLauncher, TaskState, type Transition, type TransitionActor, assertTransition, budgetMonthSchema, budgetSchema, buildFactory, changeInitialState, changeTransitions, createInMemoryDriver, createSignalCreator, defineFactory, dispatchTask, factoryConfigRepositorySchema, factoryConfigSchema, findingForTask, fixBrief, isTransitionAllowed, legalNextStates, scanBrief, signalInitialOutcome, signalOutcomeTransitions, sweepQueued, taskInitialState, taskTransitions, terminalStates };