{"version":3,"file":"run.mjs","names":[],"sources":["../src/run.ts"],"sourcesContent":["import { existsSync, mkdirSync, statSync, writeFileSync } from \"node:fs\"\nimport { dirname, join } from \"node:path\"\nimport { readPiTownMayorPrompt, resolvePiTownExtensionPath } from \"@schilderlabs/pitown-package\"\nimport {\n\tcreateRepoSlug,\n\tgetRepoIdentity,\n\tgetRepoRoot,\n\trunLoop,\n\ttype ControllerRunResult,\n\ttype LoopRunResult,\n} from \"../../core/src/index.js\"\nimport { isDirectExecution } from \"./entrypoint.js\"\nimport { resolveRunConfig } from \"./config.js\"\nimport {\n\tgetLatestRunPointerPath,\n\tgetRecommendedPlanDir,\n\tgetRepoArtifactsDir,\n\tgetRepoLatestRunPointerPath,\n\tgetTownHomeDir,\n} from \"./paths.js\"\n\ninterface LatestRunPointer {\n\trepoSlug: string\n\trepoRoot: string\n\trunId: string\n\trunDir: string\n\tlatestDir: string\n\tmanifestPath: string\n\tmetricsPath: string\n\tsummaryPath: string\n\tupdatedAt: string\n}\n\nfunction writeJson(path: string, value: unknown) {\n\tmkdirSync(dirname(path), { recursive: true })\n\twriteFileSync(path, `${JSON.stringify(value, null, 2)}\\n`, \"utf-8\")\n}\n\nfunction assertDirectory(path: string, label: string) {\n\tif (!existsSync(path)) throw new Error(`${label} does not exist: ${path}`)\n\tif (!statSync(path).isDirectory()) throw new Error(`${label} is not a directory: ${path}`)\n}\n\nfunction createLatestRunPointer(result: ControllerRunResult, repoSlug: string, repoRoot: string): LatestRunPointer {\n\treturn {\n\t\trepoSlug,\n\t\trepoRoot,\n\t\trunId: result.runId,\n\t\trunDir: result.runDir,\n\t\tlatestDir: result.latestDir,\n\t\tmanifestPath: join(result.latestDir, \"manifest.json\"),\n\t\tmetricsPath: join(result.latestDir, \"metrics.json\"),\n\t\tsummaryPath: join(result.latestDir, \"run-summary.json\"),\n\t\tupdatedAt: new Date().toISOString(),\n\t}\n}\n\nfunction getLatestControllerResult(result: LoopRunResult): ControllerRunResult {\n\tconst latestIteration = result.iterations[result.iterations.length - 1]\n\tif (!latestIteration) {\n\t\tthrow new Error(\"Autonomous run did not produce any mayor iterations.\")\n\t}\n\n\treturn latestIteration.controllerResult\n}\n\nexport function runTown(argv = process.argv.slice(2)): LoopRunResult {\n\tconst config = resolveRunConfig(argv)\n\tassertDirectory(config.repo, \"Target repo\")\n\tif (config.plan) assertDirectory(config.plan, \"Plan path\")\n\n\tconst townHome = getTownHomeDir()\n\tmkdirSync(townHome, { recursive: true })\n\n\tconst repoRoot = getRepoRoot(config.repo)\n\tconst repoId = getRepoIdentity(repoRoot)\n\tconst repoSlug = createRepoSlug(repoId, repoRoot)\n\tconst recommendedPlanDir = config.plan ? null : getRecommendedPlanDir(repoSlug)\n\tconst artifactsDir = getRepoArtifactsDir(repoSlug)\n\n\tconst result = runLoop({\n\t\trunOptions: {\n\t\t\tartifactsDir,\n\t\t\tcwd: repoRoot,\n\t\t\tgoal: config.goal,\n\t\t\tmode: \"single-pi\",\n\t\t\tplanPath: config.plan,\n\t\t\trecommendedPlanDir,\n\t\t\tappendedSystemPrompt: readPiTownMayorPrompt(),\n\t\t\textensionPath: resolvePiTownExtensionPath(),\n\t\t},\n\t\tstopOnMayorIdleNoWork: true,\n\t})\n\tconst latestControllerResult = getLatestControllerResult(result)\n\n\tconst latestPointer = createLatestRunPointer(latestControllerResult, repoSlug, repoRoot)\n\twriteJson(getLatestRunPointerPath(), latestPointer)\n\twriteJson(getRepoLatestRunPointerPath(repoSlug), latestPointer)\n\n\tconsole.log(\"[pitown] autonomous run written\")\n\tconsole.log(`- loop id: ${result.loopId}`)\n\tconsole.log(`- iterations: ${result.totalIterations}`)\n\tconsole.log(`- stop reason: ${result.stopReason}`)\n\tconsole.log(`- latest run id: ${latestControllerResult.runId}`)\n\tconsole.log(`- repo root: ${latestControllerResult.manifest.repoRoot}`)\n\tconsole.log(`- branch: ${latestControllerResult.manifest.branch}`)\n\tconsole.log(`- artifacts: ${latestControllerResult.runDir}`)\n\tconsole.log(`- latest metrics: ${latestPointer.metricsPath}`)\n\tconsole.log(`- aggregate interrupt rate: ${result.aggregateMetrics.interruptRate}`)\n\tconsole.log(`- aggregate autonomous completion: ${result.aggregateMetrics.autonomousCompletionRate}`)\n\tconsole.log(`- latest pi exit code: ${latestControllerResult.piInvocation.exitCode}`)\n\tif (!latestControllerResult.summary.success) console.log(`- note: ${latestControllerResult.summary.message}`)\n\tif (latestControllerResult.manifest.planPath) console.log(`- plan path: ${latestControllerResult.manifest.planPath}`)\n\tif (latestControllerResult.summary.recommendedPlanDir) {\n\t\tconsole.log(`- recommended plans: ${latestControllerResult.summary.recommendedPlanDir}`)\n\t}\n\n\treturn result\n}\n\nif (isDirectExecution(import.meta.url)) {\n\tconst result = runTown()\n\tconst latestIteration = result.iterations[result.iterations.length - 1]\n\tif (latestIteration && latestIteration.controllerResult.piInvocation.exitCode !== 0) {\n\t\tprocess.exitCode = latestIteration.controllerResult.piInvocation.exitCode\n\t}\n}\n"],"mappings":"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"}