@tekmidian/pai 0.60.0 → 0.60.1
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.
- package/dist/{chain-DFlzAfDE.mjs → chain-CGyAIHo4.mjs} +4 -4
- package/dist/{chain-DFlzAfDE.mjs.map → chain-CGyAIHo4.mjs.map} +1 -1
- package/dist/cli/index.mjs +12 -12
- package/dist/cli/program.mjs +12 -12
- package/dist/{config-msER8xj_.mjs → config-CQCmH_gV.mjs} +2 -1
- package/dist/config-CQCmH_gV.mjs.map +1 -0
- package/dist/{config-GceCMUxa.mjs → config-DjXq_W42.mjs} +1 -1
- package/dist/{context-handover-cache-DF0xWVB0.mjs → context-handover-cache-BzM7Qudn.mjs} +4 -4
- package/dist/{context-handover-cache-DF0xWVB0.mjs.map → context-handover-cache-BzM7Qudn.mjs.map} +1 -1
- package/dist/daemon/index.mjs +11 -11
- package/dist/{daemon-DArRKBlk.mjs → daemon-B_TodsIS.mjs} +15 -15
- package/dist/{daemon-DArRKBlk.mjs.map → daemon-B_TodsIS.mjs.map} +1 -1
- package/dist/daemon-jviL3VVJ.mjs +19 -0
- package/dist/daemon-mcp/index.mjs +7 -7
- package/dist/{factory-D6I2jmjQ.mjs → factory-DW7BCJJT.mjs} +1 -1
- package/dist/{factory-ChfAvCzO.mjs → factory-EUUhSSoq.mjs} +5 -6
- package/dist/factory-EUUhSSoq.mjs.map +1 -0
- package/dist/{fallback-B7VEMMRn.mjs → fallback-CjdakQVu.mjs} +5 -5
- package/dist/{fallback-B7VEMMRn.mjs.map → fallback-CjdakQVu.mjs.map} +1 -1
- package/dist/hooks/block-sleep-poll.mjs.map +1 -1
- package/dist/hooks/context-compression-hook.mjs.map +1 -1
- package/dist/hooks/post-compact-inject.mjs.map +1 -1
- package/dist/hooks/route-agents-to-worker.mjs +2 -2
- package/dist/hooks/route-agents-to-worker.mjs.map +3 -3
- package/dist/hooks/security-validator.mjs +2 -2
- package/dist/hooks/security-validator.mjs.map +3 -3
- package/dist/hooks/whisper-rules.mjs +2 -2
- package/dist/hooks/whisper-rules.mjs.map +3 -3
- package/dist/hooks/worker-proxy.mjs +2 -2
- package/dist/hooks/worker-proxy.mjs.map +3 -3
- package/dist/hooks/worker-status-line.mjs +2 -2
- package/dist/hooks/worker-status-line.mjs.map +3 -3
- package/dist/hooks/worker-supervision.mjs +2 -2
- package/dist/hooks/worker-supervision.mjs.map +3 -3
- package/dist/{main-resolver-BqTjt-GL.mjs → main-resolver-BFQfU5xo.mjs} +4 -4
- package/dist/{main-resolver-BqTjt-GL.mjs.map → main-resolver-BFQfU5xo.mjs.map} +1 -1
- package/dist/main-resolver-VMBENifT.mjs +7 -0
- package/dist/{planner-DbpsMZqY.mjs → planner-DN967Lvm.mjs} +7 -7
- package/dist/{planner-DbpsMZqY.mjs.map → planner-DN967Lvm.mjs.map} +1 -1
- package/dist/{program-QSuci3RH.mjs → program-BnsjB57Q.mjs} +40 -40
- package/dist/{program-QSuci3RH.mjs.map → program-BnsjB57Q.mjs.map} +1 -1
- package/dist/{run-BFxuNnIJ.mjs → run-FeM1_UVa.mjs} +7 -6
- package/dist/run-FeM1_UVa.mjs.map +1 -0
- package/dist/{run-env-kbWVwUvU.mjs → run-env-CEHTeIUM.mjs} +2 -2
- package/dist/{run-env-kbWVwUvU.mjs.map → run-env-CEHTeIUM.mjs.map} +1 -1
- package/dist/{server-B0vBmfJt.mjs → server-CekGOJcp.mjs} +2 -2
- package/dist/{server-B0vBmfJt.mjs.map → server-CekGOJcp.mjs.map} +1 -1
- package/dist/{session-keepalive-CUcFa8ld.mjs → session-keepalive-Bc9aT678.mjs} +5 -5
- package/dist/{session-keepalive-CUcFa8ld.mjs.map → session-keepalive-Bc9aT678.mjs.map} +1 -1
- package/dist/{tools-CaTZnIau.mjs → tools-qXyHFwNj.mjs} +2 -2
- package/dist/{tools-CaTZnIau.mjs.map → tools-qXyHFwNj.mjs.map} +1 -1
- package/dist/{tools-_7MF8Ebb.mjs → tools-r-7ZG8B5.mjs} +3 -3
- package/dist/{wakeup-CTX3rlz-.mjs → wakeup-C48hcN6O.mjs} +2 -2
- package/dist/{wakeup-CTX3rlz-.mjs.map → wakeup-C48hcN6O.mjs.map} +1 -1
- package/dist/{work-queue-worker-B4eZGy5n.mjs → work-queue-worker-BL4dq5P7.mjs} +2 -2
- package/dist/{work-queue-worker-B4eZGy5n.mjs.map → work-queue-worker-BL4dq5P7.mjs.map} +1 -1
- package/dist/work-queue-worker-DVOVcEnO.mjs +11 -0
- package/package.json +1 -1
- package/dist/config-msER8xj_.mjs.map +0 -1
- package/dist/daemon-BppwJtrH.mjs +0 -19
- package/dist/factory-ChfAvCzO.mjs.map +0 -1
- package/dist/main-resolver-CCojcYr2.mjs +0 -7
- package/dist/run-BFxuNnIJ.mjs.map +0 -1
- package/dist/work-queue-worker-DuhZmfDB.mjs +0 -11
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import "./utils-C9HsYDpO.mjs";
|
|
2
|
+
import "./config-CQCmH_gV.mjs";
|
|
3
|
+
import "./run-env-CEHTeIUM.mjs";
|
|
4
|
+
import { i as resumeTargetFor, n as resolveSessionDir, r as resumeCandidateFor, t as cmdMain } from "./main-resolver-BFQfU5xo.mjs";
|
|
5
|
+
import "./aibroker-client-BK1h--W_.mjs";
|
|
6
|
+
|
|
7
|
+
export { cmdMain };
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import "./factory-
|
|
2
|
-
import "./config-
|
|
3
|
-
import { T as readWorkersSection } from "./run-env-
|
|
4
|
-
import { B as newWorkerId, E as mergeWorker, J as shortText, O as appendLedger, R as loadStatus, T as git, n as runWorker, q as parseRunnerArgs, t as printResult } from "./run-
|
|
5
|
-
import { h as ledgerPath, v as workersLogDir } from "./server-
|
|
6
|
-
import { n as swapPromptArg } from "./chain-
|
|
1
|
+
import "./factory-EUUhSSoq.mjs";
|
|
2
|
+
import "./config-CQCmH_gV.mjs";
|
|
3
|
+
import { T as readWorkersSection } from "./run-env-CEHTeIUM.mjs";
|
|
4
|
+
import { B as newWorkerId, E as mergeWorker, J as shortText, O as appendLedger, R as loadStatus, T as git, n as runWorker, q as parseRunnerArgs, t as printResult } from "./run-FeM1_UVa.mjs";
|
|
5
|
+
import { h as ledgerPath, v as workersLogDir } from "./server-CekGOJcp.mjs";
|
|
6
|
+
import { n as swapPromptArg } from "./chain-CGyAIHo4.mjs";
|
|
7
7
|
import { existsSync, mkdirSync, readFileSync } from "node:fs";
|
|
8
8
|
import { join } from "node:path";
|
|
9
9
|
|
|
@@ -297,4 +297,4 @@ function printPlannerSummary(logDir, plannerId, results, merged, conflicted, fmt
|
|
|
297
297
|
|
|
298
298
|
//#endregion
|
|
299
299
|
export { runPlanner };
|
|
300
|
-
//# sourceMappingURL=planner-
|
|
300
|
+
//# sourceMappingURL=planner-DN967Lvm.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"planner-DbpsMZqY.mjs","names":[],"sources":["../src/workers/planner.ts"],"sourcesContent":["/**\n * planner.ts — the plan class: plan, spawn, integrate.\n *\n * `pai worker run --class plan -p \"<goal>\"` does not run one worker but a\n * small orchestration:\n *\n * 1. a planner worker (the plan class's provider) reads the repository and\n * writes `<logDir>/plans/<planner id>.json` — 5–50 sub-tasks, fewer only\n * when the goal itself names a smaller count, each with title, brief,\n * class, files and acceptance;\n * 2. the runner validates the plan and spawns the sub-tasks as children of\n * the planner worker (`parent` = the planner id, so `ps` shows the\n * tree), at most `workers.tree.maxChildren` at a time;\n * 3. each child that finishes delivers its structured report to the\n * planner's inbox as a `kind: \"result\"` handoff (see handoff.ts);\n * 4. the run finishes with a summary report and the branches to merge.\n *\n * The planner's prompt carries the prompt rules from the self-driving\n * codebases write-up: domain-specific instructions only, constraints over\n * step lists, explicit quantity ranges, no checkbox style.\n */\n\nimport { existsSync, mkdirSync, readFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { readWorkersSection } from \"./config.js\";\nimport { appendLedger } from \"./ledger.js\";\nimport { ledgerPath, workersLogDir } from \"./paths.js\";\nimport { loadStatus, newWorkerId } from \"./status.js\";\nimport { parseRunnerArgs, shortText } from \"./args.js\";\nimport { swapPromptArg } from \"./chain.js\";\nimport { runWorker, printResult, type RunOptions, type StreamEvent } from \"./run.js\";\nimport { git, mergeWorker } from \"./worktree.js\";\nimport type { WorkerReport } from \"./report.js\";\n\n/** Where a planner run's plan file lives: <logDir>/plans/<planner id>.json. */\nexport function planPathFor(logDir: string, plannerId: string): string {\n return join(logDir, \"plans\", `${plannerId}.json`);\n}\n\nexport interface PlannerTask {\n title: string;\n brief: string;\n /** Task class of the child (implement, research, …); default implement. */\n class?: string;\n /** Files the sub-task likely touches. */\n files?: string[];\n /** How to tell the sub-task is done. */\n acceptance?: string[];\n}\n\nexport const MIN_TASKS = 5;\nexport const MAX_TASKS = 50;\n\n/**\n * Validate a raw plan file into its tasks. Accepts 1–MAX_TASKS tasks: the\n * prompt asks for MIN_TASKS–MAX_TASKS, but a goal may itself name a smaller\n * explicit count (\"one sub-task per file\" with three files), and that\n * explicit range wins. Everything else — missing file, damaged JSON, tasks\n * without a title or brief — throws with a message the operator can act on.\n */\nexport function validatePlan(raw: unknown): PlannerTask[] {\n if (typeof raw !== \"object\" || raw === null || Array.isArray(raw)) {\n throw new Error(\"plan file must be a JSON object\");\n }\n const tasksRaw = (raw as Record<string, unknown>).tasks;\n if (!Array.isArray(tasksRaw)) throw new Error('plan file needs a \"tasks\" array');\n if (tasksRaw.length < 1) throw new Error(\"plan file has no tasks\");\n if (tasksRaw.length > MAX_TASKS) {\n throw new Error(`plan file has ${tasksRaw.length} tasks; the maximum is ${MAX_TASKS}`);\n }\n const tasks: PlannerTask[] = [];\n for (let i = 0; i < tasksRaw.length; i++) {\n const t = tasksRaw[i];\n if (typeof t !== \"object\" || t === null || Array.isArray(t)) {\n throw new Error(`task ${i + 1} must be an object`);\n }\n const o = t as Record<string, unknown>;\n const title = typeof o.title === \"string\" ? o.title.trim() : \"\";\n const brief = typeof o.brief === \"string\" ? o.brief.trim() : \"\";\n if (!title) throw new Error(`task ${i + 1} needs a non-empty \"title\"`);\n if (!brief) throw new Error(`task ${i + 1} needs a non-empty \"brief\"`);\n const strArr = (v: unknown): string[] | undefined =>\n Array.isArray(v) && v.every((x) => typeof x === \"string\") ? (v as string[]) : undefined;\n const files = strArr(o.files);\n const acceptance = strArr(o.acceptance);\n tasks.push({\n title,\n brief,\n ...(typeof o.class === \"string\" && o.class.trim() ? { class: o.class.trim() } : {}),\n ...(files?.length ? { files } : {}),\n ...(acceptance?.length ? { acceptance } : {}),\n });\n }\n return tasks;\n}\n\n/** The planner worker's instructions, goal and prompt rules included. */\nexport function plannerPrompt(goal: string, planFile: string, maxChildren: number): string {\n return [\n \"You are a PLANNER worker. Turn the goal below into a plan file and stop —\",\n \"you do not implement anything, and you do not spawn workers yourself:\",\n \"the runner executes your plan on your behalf (the sub-tasks run as your\",\n \"children and report back to you).\",\n \"\",\n `Write the plan with the Write tool to ${planFile} as one JSON object:`,\n '{\"tasks\":[{\"title\":\"…\",\"brief\":\"…\",\"class\":\"implement\",\"files\":[\"…\"],\"acceptance\":[\"…\"]}]}',\n \"\",\n \"Prompt rules for the plan itself (they are yours too):\",\n \"- Domain-specific instructions only: name real files, commands and\",\n \" constraints of this repository, never generic advice.\",\n \"- Constraints over step lists: state what must hold (and what must not\",\n \" change), not a numbered procedure to follow.\",\n \"- Explicit quantity ranges: how many, how much, how long — never\",\n ' \"several\", \"some\", \"as needed\".',\n \"- No checkbox style: no `[ ]` items, no step numbering theatre.\",\n \"\",\n `Emit between ${MIN_TASKS} and ${MAX_TASKS} sub-tasks — unless the goal itself`,\n 'names a smaller explicit count (\"one sub-task per file\" with three files',\n \"means three); an explicit count in the goal always wins.\",\n `At most ${maxChildren} of them run at a time, so independent tasks are better`,\n \"than long chains. Each task's class picks its provider: implement, draft,\",\n \"review, research, spotcheck, simple, complex, image.\",\n \"\",\n \"Read the repository first (Glob/Grep/Read) so tasks name real files.\",\n \"Every sub-task runs in its own worktree of the same repository: name files\",\n \"relative to the repository root and never an absolute path or a worktree\",\n \"directory in a title, brief, files or acceptance entry.\",\n \"\",\n \"## Goal\",\n \"\",\n goal,\n ].join(\"\\n\");\n}\n\n/** The child's prompt for one planned sub-task. */\nexport function taskPrompt(goal: string, task: PlannerTask, index: number, of: number): string {\n return [\n `You are sub-task ${index + 1} of ${of} of a planned goal. Do exactly this sub-task;`,\n \"the other sub-tasks are other workers' business.\",\n \"\",\n `# ${task.title}`,\n \"\",\n task.brief,\n ...(task.files?.length ? [\"\", \"Files likely touched: \" + task.files.join(\", \")] : []),\n ...(task.acceptance?.length\n ? [\"\", \"Done means:\", ...task.acceptance.map((a) => `- ${a}`)]\n : []),\n \"\",\n \"## The overall goal (context only — your scope is the sub-task above)\",\n \"\",\n goal,\n ].join(\"\\n\");\n}\n\nexport interface PlannerDeps {\n /** Stage runner; tests inject a mock, production uses runWorker. */\n runStage?: (opts: RunOptions) => Promise<number>;\n /** logDir override for tests. */\n logDir?: string;\n /** maxChildren override for tests. */\n maxChildren?: number;\n}\n\n/**\n * The planner orchestration; returns the process exit code. The planner id is\n * minted here and preset on the phase-1 run, so the plan file's name is known\n * before the worker starts and the prompt can name its exact path.\n */\nexport async function runPlanner(opts: RunOptions, deps: PlannerDeps = {}): Promise<number> {\n const runStage = deps.runStage ?? runWorker;\n const { workers: config } = readWorkersSection();\n const logDir = deps.logDir ?? workersLogDir(config);\n const maxChildren = deps.maxChildren ?? config.tree.maxChildren;\n const parsed = parseRunnerArgs(opts.claudeArgs);\n const goal = parsed.prompt ?? \"\";\n const plannerId = newWorkerId();\n const planFile = planPathFor(logDir, plannerId);\n mkdirSync(join(logDir, \"plans\"), { recursive: true });\n\n // --- phase 1: the planner worker writes the plan file\n process.stderr.write(`planner ${plannerId}: writing plan (${planFile})\\n`);\n const rc1 = await runStage({\n ...opts,\n id: plannerId,\n claudeArgs: swapPromptArg(opts.claudeArgs, plannerPrompt(goal, planFile, maxChildren)),\n quiet: true,\n _planner: true,\n });\n if (rc1 !== 0) return rc1;\n if (!existsSync(planFile)) {\n process.stderr.write(\n `planner ${plannerId}: no plan file at ${planFile} — the planner worker did not write one. ` +\n `Re-run, or write the plan yourself and run the tasks with pai worker run.\\n`\n );\n appendLedger(ledgerPath(logDir), \"WORKER-PLAN-END\", { planner: plannerId, rc: 1, failed: \"plan\" });\n return 1;\n }\n let tasks: PlannerTask[];\n try {\n tasks = validatePlan(JSON.parse(readFileSync(planFile, \"utf8\")));\n } catch (e) {\n process.stderr.write(`planner ${plannerId}: invalid plan file ${planFile}: ${(e as Error).message}\\n`);\n appendLedger(ledgerPath(logDir), \"WORKER-PLAN-END\", { planner: plannerId, rc: 1, failed: \"plan\" });\n return 1;\n }\n appendLedger(ledgerPath(logDir), \"WORKER-PLAN\", {\n planner: plannerId,\n tasks: tasks.length,\n plan: planFile,\n });\n\n // --- phase 2: run the sub-tasks as children, maxChildren at a time. Each\n // child is spawned in the planner's own worktree (when it got one) rather\n // than the operator's cwd, so its branch is created off the planner's own\n // HEAD and can later be merged straight into it.\n const plannerStatus = loadStatus(logDir, plannerId);\n const plannerWorktreeDir = plannerStatus?.worktreeDir ?? null;\n const results: { task: PlannerTask; rc: number; id: string }[] = [];\n for (let i = 0; i < tasks.length; i += maxChildren) {\n const wave = tasks.slice(i, i + maxChildren);\n process.stderr.write(\n `planner ${plannerId}: sub-tasks ${i + 1}–${i + wave.length} of ${tasks.length}\\n`\n );\n const waveIds: string[] = new Array(wave.length).fill(\"\");\n const rcs = await Promise.all(\n wave.map((task, w) =>\n runStage({\n className: task.class ?? \"implement\",\n providerFlag: opts.providerFlag,\n modelFlag: opts.modelFlag,\n label: shortText(task.title, 40),\n noPane: opts.noPane,\n mcpFlag: opts.mcpFlag,\n claudeArgs: swapPromptArg(opts.claudeArgs, taskPrompt(goal, task, i + w, tasks.length)),\n cwd: plannerWorktreeDir ?? opts.cwd,\n worktreeFlag: opts.worktreeFlag,\n parent: plannerId,\n quiet: true,\n onWorkerStart: (wid) => {\n waveIds[w] = wid;\n },\n })\n )\n );\n for (let w = 0; w < wave.length; w++) results.push({ task: wave[w], rc: rcs[w], id: waveIds[w] });\n }\n\n // --- phase 3: the planner merges each finished child's branch into its\n // OWN worktree branch, in spawn order — never into the operator's checkout\n // — reusing `pai worker merge`'s own logic (mergeWorker). A conflicting\n // merge is aborted cleanly so the planner's branch stays clean and the\n // next child still gets a try; the child's branch is left intact either way.\n const merged: string[] = [];\n const conflicted: { id: string; branch: string; paths: string[] }[] = [];\n if (plannerWorktreeDir) {\n for (const r of results) {\n if (r.rc !== 0 || !r.id) continue;\n const st = loadStatus(logDir, r.id);\n if (!st?.branch) continue; // ran in place, or no worktree: nothing to merge\n try {\n mergeWorker(logDir, r.id);\n merged.push(r.id);\n } catch {\n let paths: string[] = [];\n try {\n git(plannerWorktreeDir, [\"rev-parse\", \"-q\", \"--verify\", \"MERGE_HEAD\"]);\n paths = git(plannerWorktreeDir, [\"diff\", \"--name-only\", \"--diff-filter=U\"])\n .split(\"\\n\")\n .filter(Boolean);\n git(plannerWorktreeDir, [\"merge\", \"--abort\"]);\n } catch {\n // no merge was left in progress: the failure was not a conflict\n }\n conflicted.push({ id: r.id, branch: st.branch, paths });\n }\n }\n }\n\n // --- phase 4: summary from the children's statuses and inbox handoffs\n const failed = results.filter((r) => r.rc !== 0).length;\n appendLedger(ledgerPath(logDir), \"WORKER-PLAN-END\", {\n planner: plannerId,\n rc: failed || conflicted.length ? 1 : 0,\n failed,\n merged: merged.length,\n conflicted: conflicted.length,\n });\n printPlannerSummary(logDir, plannerId, results, merged, conflicted, parsed.outputFormat, opts.quiet === true);\n return failed || conflicted.length ? 1 : 0;\n}\n\n/** Compose and print the planner's summary report (text or json). */\nfunction printPlannerSummary(\n logDir: string,\n plannerId: string,\n results: { task: PlannerTask; rc: number; id: string }[],\n merged: string[],\n conflicted: { id: string; branch: string; paths: string[] }[],\n fmt: \"text\" | \"json\" | \"stream-json\",\n quiet: boolean\n): void {\n const ok = results.filter((r) => r.rc === 0).length;\n const attempted = new Set([...merged, ...conflicted.map((c) => c.id)]);\n // a branch never attempted (no planner worktree to merge into) still needs\n // the old \"go merge me by hand\" hint\n const stillOpen: { id: string; branch: string }[] = [];\n for (const r of results) {\n if (r.rc !== 0 || !r.id || attempted.has(r.id)) continue;\n const st = loadStatus(logDir, r.id);\n if (st?.branch && !st.merged) stillOpen.push({ id: r.id, branch: st.branch });\n }\n const report: WorkerReport = {\n checks: results.map((r) => ({\n name: r.task.title,\n ok: r.rc === 0,\n detail: r.rc === 0 ? shortText(r.id ? loadStatus(logDir, r.id)?.last : \"\", 80) : `rc=${r.rc}`,\n })),\n ...(merged.length || conflicted.length || stillOpen.length\n ? {\n open: [\n ...merged.map((id) => `merged: ${id}`),\n ...conflicted.map(\n (c) =>\n `conflict: pai worker merge ${c.id} (${c.branch})` +\n (c.paths.length ? ` — ${c.paths.join(\", \")}` : \"\")\n ),\n ...stillOpen.map((c) => `branch to merge: pai worker merge ${c.id} (${c.branch})`),\n ],\n }\n : {}),\n notes:\n `${ok}/${results.length} sub-tasks ok` +\n (merged.length ? `; ${merged.length} merged` : \"\") +\n (conflicted.length ? `; ${conflicted.length} conflict(s)` : \"\") +\n (stillOpen.length ? `; ${stillOpen.length} branch(es) to merge` : \"\"),\n };\n if (quiet || fmt === \"stream-json\") return;\n const allOk = ok === results.length && conflicted.length === 0;\n const resultEvent: StreamEvent = {\n type: \"result\",\n result: [\n `planner ${plannerId}: ${report.notes}`,\n ...(conflicted.length ? [\"conflicts:\"] : []),\n ...conflicted.map(\n (c) =>\n ` pai worker merge ${c.id} # ${c.branch}, conflicting: ${c.paths.join(\", \") || \"unknown\"}`\n ),\n ...(stillOpen.length ? [\"branches to merge:\"] : []),\n ...stillOpen.map((c) => ` pai worker merge ${c.id} # ${c.branch}`),\n ].join(\"\\n\"),\n is_error: !allOk,\n };\n printResult(fmt, resultEvent, allOk ? 0 : 1, logDir, plannerId, report, {\n plan: results.length,\n ...(merged.length ? { mergedBranches: merged } : {}),\n ...(conflicted.length ? { conflictedBranches: conflicted.map((c) => c.branch) } : {}),\n ...(stillOpen.length ? { branches: stillOpen.map((c) => c.branch) } : {}),\n });\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"planner-DN967Lvm.mjs","names":[],"sources":["../src/workers/planner.ts"],"sourcesContent":["/**\n * planner.ts — the plan class: plan, spawn, integrate.\n *\n * `pai worker run --class plan -p \"<goal>\"` does not run one worker but a\n * small orchestration:\n *\n * 1. a planner worker (the plan class's provider) reads the repository and\n * writes `<logDir>/plans/<planner id>.json` — 5–50 sub-tasks, fewer only\n * when the goal itself names a smaller count, each with title, brief,\n * class, files and acceptance;\n * 2. the runner validates the plan and spawns the sub-tasks as children of\n * the planner worker (`parent` = the planner id, so `ps` shows the\n * tree), at most `workers.tree.maxChildren` at a time;\n * 3. each child that finishes delivers its structured report to the\n * planner's inbox as a `kind: \"result\"` handoff (see handoff.ts);\n * 4. the run finishes with a summary report and the branches to merge.\n *\n * The planner's prompt carries the prompt rules from the self-driving\n * codebases write-up: domain-specific instructions only, constraints over\n * step lists, explicit quantity ranges, no checkbox style.\n */\n\nimport { existsSync, mkdirSync, readFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { readWorkersSection } from \"./config.js\";\nimport { appendLedger } from \"./ledger.js\";\nimport { ledgerPath, workersLogDir } from \"./paths.js\";\nimport { loadStatus, newWorkerId } from \"./status.js\";\nimport { parseRunnerArgs, shortText } from \"./args.js\";\nimport { swapPromptArg } from \"./chain.js\";\nimport { runWorker, printResult, type RunOptions, type StreamEvent } from \"./run.js\";\nimport { git, mergeWorker } from \"./worktree.js\";\nimport type { WorkerReport } from \"./report.js\";\n\n/** Where a planner run's plan file lives: <logDir>/plans/<planner id>.json. */\nexport function planPathFor(logDir: string, plannerId: string): string {\n return join(logDir, \"plans\", `${plannerId}.json`);\n}\n\nexport interface PlannerTask {\n title: string;\n brief: string;\n /** Task class of the child (implement, research, …); default implement. */\n class?: string;\n /** Files the sub-task likely touches. */\n files?: string[];\n /** How to tell the sub-task is done. */\n acceptance?: string[];\n}\n\nexport const MIN_TASKS = 5;\nexport const MAX_TASKS = 50;\n\n/**\n * Validate a raw plan file into its tasks. Accepts 1–MAX_TASKS tasks: the\n * prompt asks for MIN_TASKS–MAX_TASKS, but a goal may itself name a smaller\n * explicit count (\"one sub-task per file\" with three files), and that\n * explicit range wins. Everything else — missing file, damaged JSON, tasks\n * without a title or brief — throws with a message the operator can act on.\n */\nexport function validatePlan(raw: unknown): PlannerTask[] {\n if (typeof raw !== \"object\" || raw === null || Array.isArray(raw)) {\n throw new Error(\"plan file must be a JSON object\");\n }\n const tasksRaw = (raw as Record<string, unknown>).tasks;\n if (!Array.isArray(tasksRaw)) throw new Error('plan file needs a \"tasks\" array');\n if (tasksRaw.length < 1) throw new Error(\"plan file has no tasks\");\n if (tasksRaw.length > MAX_TASKS) {\n throw new Error(`plan file has ${tasksRaw.length} tasks; the maximum is ${MAX_TASKS}`);\n }\n const tasks: PlannerTask[] = [];\n for (let i = 0; i < tasksRaw.length; i++) {\n const t = tasksRaw[i];\n if (typeof t !== \"object\" || t === null || Array.isArray(t)) {\n throw new Error(`task ${i + 1} must be an object`);\n }\n const o = t as Record<string, unknown>;\n const title = typeof o.title === \"string\" ? o.title.trim() : \"\";\n const brief = typeof o.brief === \"string\" ? o.brief.trim() : \"\";\n if (!title) throw new Error(`task ${i + 1} needs a non-empty \"title\"`);\n if (!brief) throw new Error(`task ${i + 1} needs a non-empty \"brief\"`);\n const strArr = (v: unknown): string[] | undefined =>\n Array.isArray(v) && v.every((x) => typeof x === \"string\") ? (v as string[]) : undefined;\n const files = strArr(o.files);\n const acceptance = strArr(o.acceptance);\n tasks.push({\n title,\n brief,\n ...(typeof o.class === \"string\" && o.class.trim() ? { class: o.class.trim() } : {}),\n ...(files?.length ? { files } : {}),\n ...(acceptance?.length ? { acceptance } : {}),\n });\n }\n return tasks;\n}\n\n/** The planner worker's instructions, goal and prompt rules included. */\nexport function plannerPrompt(goal: string, planFile: string, maxChildren: number): string {\n return [\n \"You are a PLANNER worker. Turn the goal below into a plan file and stop —\",\n \"you do not implement anything, and you do not spawn workers yourself:\",\n \"the runner executes your plan on your behalf (the sub-tasks run as your\",\n \"children and report back to you).\",\n \"\",\n `Write the plan with the Write tool to ${planFile} as one JSON object:`,\n '{\"tasks\":[{\"title\":\"…\",\"brief\":\"…\",\"class\":\"implement\",\"files\":[\"…\"],\"acceptance\":[\"…\"]}]}',\n \"\",\n \"Prompt rules for the plan itself (they are yours too):\",\n \"- Domain-specific instructions only: name real files, commands and\",\n \" constraints of this repository, never generic advice.\",\n \"- Constraints over step lists: state what must hold (and what must not\",\n \" change), not a numbered procedure to follow.\",\n \"- Explicit quantity ranges: how many, how much, how long — never\",\n ' \"several\", \"some\", \"as needed\".',\n \"- No checkbox style: no `[ ]` items, no step numbering theatre.\",\n \"\",\n `Emit between ${MIN_TASKS} and ${MAX_TASKS} sub-tasks — unless the goal itself`,\n 'names a smaller explicit count (\"one sub-task per file\" with three files',\n \"means three); an explicit count in the goal always wins.\",\n `At most ${maxChildren} of them run at a time, so independent tasks are better`,\n \"than long chains. Each task's class picks its provider: implement, draft,\",\n \"review, research, spotcheck, simple, complex, image.\",\n \"\",\n \"Read the repository first (Glob/Grep/Read) so tasks name real files.\",\n \"Every sub-task runs in its own worktree of the same repository: name files\",\n \"relative to the repository root and never an absolute path or a worktree\",\n \"directory in a title, brief, files or acceptance entry.\",\n \"\",\n \"## Goal\",\n \"\",\n goal,\n ].join(\"\\n\");\n}\n\n/** The child's prompt for one planned sub-task. */\nexport function taskPrompt(goal: string, task: PlannerTask, index: number, of: number): string {\n return [\n `You are sub-task ${index + 1} of ${of} of a planned goal. Do exactly this sub-task;`,\n \"the other sub-tasks are other workers' business.\",\n \"\",\n `# ${task.title}`,\n \"\",\n task.brief,\n ...(task.files?.length ? [\"\", \"Files likely touched: \" + task.files.join(\", \")] : []),\n ...(task.acceptance?.length\n ? [\"\", \"Done means:\", ...task.acceptance.map((a) => `- ${a}`)]\n : []),\n \"\",\n \"## The overall goal (context only — your scope is the sub-task above)\",\n \"\",\n goal,\n ].join(\"\\n\");\n}\n\nexport interface PlannerDeps {\n /** Stage runner; tests inject a mock, production uses runWorker. */\n runStage?: (opts: RunOptions) => Promise<number>;\n /** logDir override for tests. */\n logDir?: string;\n /** maxChildren override for tests. */\n maxChildren?: number;\n}\n\n/**\n * The planner orchestration; returns the process exit code. The planner id is\n * minted here and preset on the phase-1 run, so the plan file's name is known\n * before the worker starts and the prompt can name its exact path.\n */\nexport async function runPlanner(opts: RunOptions, deps: PlannerDeps = {}): Promise<number> {\n const runStage = deps.runStage ?? runWorker;\n const { workers: config } = readWorkersSection();\n const logDir = deps.logDir ?? workersLogDir(config);\n const maxChildren = deps.maxChildren ?? config.tree.maxChildren;\n const parsed = parseRunnerArgs(opts.claudeArgs);\n const goal = parsed.prompt ?? \"\";\n const plannerId = newWorkerId();\n const planFile = planPathFor(logDir, plannerId);\n mkdirSync(join(logDir, \"plans\"), { recursive: true });\n\n // --- phase 1: the planner worker writes the plan file\n process.stderr.write(`planner ${plannerId}: writing plan (${planFile})\\n`);\n const rc1 = await runStage({\n ...opts,\n id: plannerId,\n claudeArgs: swapPromptArg(opts.claudeArgs, plannerPrompt(goal, planFile, maxChildren)),\n quiet: true,\n _planner: true,\n });\n if (rc1 !== 0) return rc1;\n if (!existsSync(planFile)) {\n process.stderr.write(\n `planner ${plannerId}: no plan file at ${planFile} — the planner worker did not write one. ` +\n `Re-run, or write the plan yourself and run the tasks with pai worker run.\\n`\n );\n appendLedger(ledgerPath(logDir), \"WORKER-PLAN-END\", { planner: plannerId, rc: 1, failed: \"plan\" });\n return 1;\n }\n let tasks: PlannerTask[];\n try {\n tasks = validatePlan(JSON.parse(readFileSync(planFile, \"utf8\")));\n } catch (e) {\n process.stderr.write(`planner ${plannerId}: invalid plan file ${planFile}: ${(e as Error).message}\\n`);\n appendLedger(ledgerPath(logDir), \"WORKER-PLAN-END\", { planner: plannerId, rc: 1, failed: \"plan\" });\n return 1;\n }\n appendLedger(ledgerPath(logDir), \"WORKER-PLAN\", {\n planner: plannerId,\n tasks: tasks.length,\n plan: planFile,\n });\n\n // --- phase 2: run the sub-tasks as children, maxChildren at a time. Each\n // child is spawned in the planner's own worktree (when it got one) rather\n // than the operator's cwd, so its branch is created off the planner's own\n // HEAD and can later be merged straight into it.\n const plannerStatus = loadStatus(logDir, plannerId);\n const plannerWorktreeDir = plannerStatus?.worktreeDir ?? null;\n const results: { task: PlannerTask; rc: number; id: string }[] = [];\n for (let i = 0; i < tasks.length; i += maxChildren) {\n const wave = tasks.slice(i, i + maxChildren);\n process.stderr.write(\n `planner ${plannerId}: sub-tasks ${i + 1}–${i + wave.length} of ${tasks.length}\\n`\n );\n const waveIds: string[] = new Array(wave.length).fill(\"\");\n const rcs = await Promise.all(\n wave.map((task, w) =>\n runStage({\n className: task.class ?? \"implement\",\n providerFlag: opts.providerFlag,\n modelFlag: opts.modelFlag,\n label: shortText(task.title, 40),\n noPane: opts.noPane,\n mcpFlag: opts.mcpFlag,\n claudeArgs: swapPromptArg(opts.claudeArgs, taskPrompt(goal, task, i + w, tasks.length)),\n cwd: plannerWorktreeDir ?? opts.cwd,\n worktreeFlag: opts.worktreeFlag,\n parent: plannerId,\n quiet: true,\n onWorkerStart: (wid) => {\n waveIds[w] = wid;\n },\n })\n )\n );\n for (let w = 0; w < wave.length; w++) results.push({ task: wave[w], rc: rcs[w], id: waveIds[w] });\n }\n\n // --- phase 3: the planner merges each finished child's branch into its\n // OWN worktree branch, in spawn order — never into the operator's checkout\n // — reusing `pai worker merge`'s own logic (mergeWorker). A conflicting\n // merge is aborted cleanly so the planner's branch stays clean and the\n // next child still gets a try; the child's branch is left intact either way.\n const merged: string[] = [];\n const conflicted: { id: string; branch: string; paths: string[] }[] = [];\n if (plannerWorktreeDir) {\n for (const r of results) {\n if (r.rc !== 0 || !r.id) continue;\n const st = loadStatus(logDir, r.id);\n if (!st?.branch) continue; // ran in place, or no worktree: nothing to merge\n try {\n mergeWorker(logDir, r.id);\n merged.push(r.id);\n } catch {\n let paths: string[] = [];\n try {\n git(plannerWorktreeDir, [\"rev-parse\", \"-q\", \"--verify\", \"MERGE_HEAD\"]);\n paths = git(plannerWorktreeDir, [\"diff\", \"--name-only\", \"--diff-filter=U\"])\n .split(\"\\n\")\n .filter(Boolean);\n git(plannerWorktreeDir, [\"merge\", \"--abort\"]);\n } catch {\n // no merge was left in progress: the failure was not a conflict\n }\n conflicted.push({ id: r.id, branch: st.branch, paths });\n }\n }\n }\n\n // --- phase 4: summary from the children's statuses and inbox handoffs\n const failed = results.filter((r) => r.rc !== 0).length;\n appendLedger(ledgerPath(logDir), \"WORKER-PLAN-END\", {\n planner: plannerId,\n rc: failed || conflicted.length ? 1 : 0,\n failed,\n merged: merged.length,\n conflicted: conflicted.length,\n });\n printPlannerSummary(logDir, plannerId, results, merged, conflicted, parsed.outputFormat, opts.quiet === true);\n return failed || conflicted.length ? 1 : 0;\n}\n\n/** Compose and print the planner's summary report (text or json). */\nfunction printPlannerSummary(\n logDir: string,\n plannerId: string,\n results: { task: PlannerTask; rc: number; id: string }[],\n merged: string[],\n conflicted: { id: string; branch: string; paths: string[] }[],\n fmt: \"text\" | \"json\" | \"stream-json\",\n quiet: boolean\n): void {\n const ok = results.filter((r) => r.rc === 0).length;\n const attempted = new Set([...merged, ...conflicted.map((c) => c.id)]);\n // a branch never attempted (no planner worktree to merge into) still needs\n // the old \"go merge me by hand\" hint\n const stillOpen: { id: string; branch: string }[] = [];\n for (const r of results) {\n if (r.rc !== 0 || !r.id || attempted.has(r.id)) continue;\n const st = loadStatus(logDir, r.id);\n if (st?.branch && !st.merged) stillOpen.push({ id: r.id, branch: st.branch });\n }\n const report: WorkerReport = {\n checks: results.map((r) => ({\n name: r.task.title,\n ok: r.rc === 0,\n detail: r.rc === 0 ? shortText(r.id ? loadStatus(logDir, r.id)?.last : \"\", 80) : `rc=${r.rc}`,\n })),\n ...(merged.length || conflicted.length || stillOpen.length\n ? {\n open: [\n ...merged.map((id) => `merged: ${id}`),\n ...conflicted.map(\n (c) =>\n `conflict: pai worker merge ${c.id} (${c.branch})` +\n (c.paths.length ? ` — ${c.paths.join(\", \")}` : \"\")\n ),\n ...stillOpen.map((c) => `branch to merge: pai worker merge ${c.id} (${c.branch})`),\n ],\n }\n : {}),\n notes:\n `${ok}/${results.length} sub-tasks ok` +\n (merged.length ? `; ${merged.length} merged` : \"\") +\n (conflicted.length ? `; ${conflicted.length} conflict(s)` : \"\") +\n (stillOpen.length ? `; ${stillOpen.length} branch(es) to merge` : \"\"),\n };\n if (quiet || fmt === \"stream-json\") return;\n const allOk = ok === results.length && conflicted.length === 0;\n const resultEvent: StreamEvent = {\n type: \"result\",\n result: [\n `planner ${plannerId}: ${report.notes}`,\n ...(conflicted.length ? [\"conflicts:\"] : []),\n ...conflicted.map(\n (c) =>\n ` pai worker merge ${c.id} # ${c.branch}, conflicting: ${c.paths.join(\", \") || \"unknown\"}`\n ),\n ...(stillOpen.length ? [\"branches to merge:\"] : []),\n ...stillOpen.map((c) => ` pai worker merge ${c.id} # ${c.branch}`),\n ].join(\"\\n\"),\n is_error: !allOk,\n };\n printResult(fmt, resultEvent, allOk ? 0 : 1, logDir, plannerId, report, {\n plan: results.length,\n ...(merged.length ? { mergedBranches: merged } : {}),\n ...(conflicted.length ? { conflictedBranches: conflicted.map((c) => c.branch) } : {}),\n ...(stillOpen.length ? { branches: stillOpen.map((c) => c.branch) } : {}),\n });\n}\n"],"mappings":"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"}
|
|
@@ -3,26 +3,26 @@ import { a as slugify$1, i as parseSessionFilename } from "./migrate-BD7D8EEh.mj
|
|
|
3
3
|
import { n as ensurePaiMarker } from "./pai-marker-D1MMswkz.mjs";
|
|
4
4
|
import { t as STOP_WORDS } from "./stop-words-ClCwO8mZ.mjs";
|
|
5
5
|
import { t as applyRecencyBoost } from "./search-BaTbyWjK.mjs";
|
|
6
|
-
import { a as getStorageBackend, i as getRegistryBackend, r as createStorageBackend, s as humanDuration } from "./factory-
|
|
7
|
-
import { a as formatDetectionJson, i as formatDetection, n as migrateIdentityFile, r as detectProject } from "./wakeup-
|
|
8
|
-
import { B as claudeProjectsDir, C as findLatestNote, H as scanTranscriptFolders, I as resolveHome, L as saveScanConfig, M as cmdScan, N as loadScanConfig, P as migrateScanConfig, R as upsertProject, S as applyContinue, T as readBodyFile, U as transcriptFiles, V as findMovedProjects, d as migrateWorkQueue, g as migrateSummaryCooldowns, t as readContextHandoverCache, v as extractAndStoreTriples, w as findNotesDir$1, x as appendCheckpointToNote, z as upsertSession } from "./context-handover-cache-
|
|
6
|
+
import { a as getStorageBackend, i as getRegistryBackend, r as createStorageBackend, s as humanDuration } from "./factory-EUUhSSoq.mjs";
|
|
7
|
+
import { a as formatDetectionJson, i as formatDetection, n as migrateIdentityFile, r as detectProject } from "./wakeup-C48hcN6O.mjs";
|
|
8
|
+
import { B as claudeProjectsDir, C as findLatestNote, H as scanTranscriptFolders, I as resolveHome, L as saveScanConfig, M as cmdScan, N as loadScanConfig, P as migrateScanConfig, R as upsertProject, S as applyContinue, T as readBodyFile, U as transcriptFiles, V as findMovedProjects, d as migrateWorkQueue, g as migrateSummaryCooldowns, t as readContextHandoverCache, v as extractAndStoreTriples, w as findNotesDir$1, x as appendCheckpointToNote, z as upsertSession } from "./context-handover-cache-BzM7Qudn.mjs";
|
|
9
9
|
import { a as paiHomePath, i as paiHomeDir, n as migratePaiDir, o as resolvePaiFile, r as migratePaiFile, t as PaiFileMigrationError } from "./pai-home-CeOIYltV.mjs";
|
|
10
|
-
import { b as OWNER_LABEL_PREFIX, c as migrateConfigFile, d as readMainConfigRaw, f as writeMainConfigRaw, h as resolvedMainConfigPath, l as paiConfigFilePath, m as migrateMainConfigToYaml, n as CONFIG_FILE$2, o as expandHome, p as MainConfigError, s as loadConfig, t as CONFIG_DIR, u as paiConfigYamlFilePath, v as readJsonStrict, x as UNROUTED, y as writeJsonAtomic } from "./config-
|
|
10
|
+
import { b as OWNER_LABEL_PREFIX, c as migrateConfigFile, d as readMainConfigRaw, f as writeMainConfigRaw, h as resolvedMainConfigPath, l as paiConfigFilePath, m as migrateMainConfigToYaml, n as CONFIG_FILE$2, o as expandHome, p as MainConfigError, s as loadConfig, t as CONFIG_DIR, u as paiConfigYamlFilePath, v as readJsonStrict, x as UNROUTED, y as writeJsonAtomic } from "./config-CQCmH_gV.mjs";
|
|
11
11
|
import { a as schedulerLogPath, i as paiSocketPath, n as daemonLogPath, r as daemonPidPath } from "./runtime-paths-BRwDeBEg.mjs";
|
|
12
|
-
import { A as initWorkersYaml, B as stripModelVariant, F as relocateWorkersYaml, I as workersYamlLegacyNotice, L as workersYamlPath, M as migrateWorkersToYaml, N as needsWorkersYamlRelocation, P as parseWorkersYamlDocument, R as DEFAULT_CONTEXT_WINDOW, S as nativeAnthropicProvider, T as readWorkersSection, _ as expandHome$1, d as PROVIDER_TAGS, j as inlineWorkersYamlKeys, p as WorkersConfigError, r as ANTHROPIC_NATIVE, t as buildRunEnv, u as MODEL_CAPABILITIES, v as getProviderOrNative, x as maskKey, y as isModelCapability, z as contextWindowFromModelId } from "./run-env-
|
|
13
|
-
import { A as UNLABELED, E as mergeWorker, G as waitForTerminalStatus, H as ownsPid, I as isChatPane, K as longInlinePromptHint, L as isLive, O as appendLedger, R as loadStatus, U as saveStatus, W as setWorkerLabel, X as expandMcpNames, Y as describeMcp, a as projectLaunchConfig, c as handoffFromInside, f as checkPaneForWorker, g as markControlsHeld, h as clickrControlsArgv, i as usageContextTokens, m as openPaneForWorker, n as runWorker, o as parseWorkerReport, p as openFollowPane, q as parseRunnerArgs, r as testProvider, u as sayToWorker, w as discardWorker, z as loadStatuses } from "./run-
|
|
12
|
+
import { A as initWorkersYaml, B as stripModelVariant, F as relocateWorkersYaml, I as workersYamlLegacyNotice, L as workersYamlPath, M as migrateWorkersToYaml, N as needsWorkersYamlRelocation, P as parseWorkersYamlDocument, R as DEFAULT_CONTEXT_WINDOW, S as nativeAnthropicProvider, T as readWorkersSection, _ as expandHome$1, d as PROVIDER_TAGS, j as inlineWorkersYamlKeys, p as WorkersConfigError, r as ANTHROPIC_NATIVE, t as buildRunEnv, u as MODEL_CAPABILITIES, v as getProviderOrNative, x as maskKey, y as isModelCapability, z as contextWindowFromModelId } from "./run-env-CEHTeIUM.mjs";
|
|
13
|
+
import { A as UNLABELED, E as mergeWorker, G as waitForTerminalStatus, H as ownsPid, I as isChatPane, K as longInlinePromptHint, L as isLive, O as appendLedger, R as loadStatus, U as saveStatus, W as setWorkerLabel, X as expandMcpNames, Y as describeMcp, a as projectLaunchConfig, c as handoffFromInside, f as checkPaneForWorker, g as markControlsHeld, h as clickrControlsArgv, i as usageContextTokens, m as openPaneForWorker, n as runWorker, o as parseWorkerReport, p as openFollowPane, q as parseRunnerArgs, r as testProvider, u as sayToWorker, w as discardWorker, z as loadStatuses } from "./run-FeM1_UVa.mjs";
|
|
14
14
|
import { t as MergeError } from "./merge-xoyfZQ4W.mjs";
|
|
15
15
|
import { n as oldFederationPath, t as federationDbPath } from "./federation-db-w8e-sKjp.mjs";
|
|
16
16
|
import { r as registryDbPath, t as oldRegistryPath } from "./registry-db-Bkpbp7Gf.mjs";
|
|
17
17
|
import { i as indexProjectWithBackend } from "./async-CLvuY7b-.mjs";
|
|
18
18
|
import { t as PaiClient } from "./ipc-client-Dasm515c.mjs";
|
|
19
|
-
import { A as getConfigValueOp, C as psOutput, D as resolveSpecPath, E as readSpecPrompt, M as setConfigValueOp, N as unsetConfigValueOp, O as MainConfigOpsError, S as followWorkers, T as statusLineOutput, _ as setWorkersEnabled, a as addProvider, b as updateProvider, c as describeModels, d as removeProvider, f as resolveProviderName, g as setProviderModel, h as setProviderEnabled, i as fallbackStatusText, j as listConfigOp, k as formatConfigGetOutput, l as describeProviders, m as setClass, n as fallbackOn, o as classTargetText, p as setCapabilityPreference, r as fallbackStatus, s as describeCapabilities, t as fallbackOff, u as modelPrefsText, v as unsetCapabilityPreference, w as replayOutput, x as useProvider, y as unsetClass } from "./fallback-
|
|
20
|
-
import { _ as resolveSessionByNameOrId, a as buildDeduped, c as hasConversation, d as providerResumePlan, f as restoreTopLevel, g as migrateSessionScanCache, h as fmtAge, l as launchInDir, m as printExitDir, o as normalizeName$2, p as resumeArgvText, s as renderDedupedSessions, t as cmdMain, u as launchPrompt, v as scanCacheFilePath, y as scanSessions } from "./main-resolver-
|
|
19
|
+
import { A as getConfigValueOp, C as psOutput, D as resolveSpecPath, E as readSpecPrompt, M as setConfigValueOp, N as unsetConfigValueOp, O as MainConfigOpsError, S as followWorkers, T as statusLineOutput, _ as setWorkersEnabled, a as addProvider, b as updateProvider, c as describeModels, d as removeProvider, f as resolveProviderName, g as setProviderModel, h as setProviderEnabled, i as fallbackStatusText, j as listConfigOp, k as formatConfigGetOutput, l as describeProviders, m as setClass, n as fallbackOn, o as classTargetText, p as setCapabilityPreference, r as fallbackStatus, s as describeCapabilities, t as fallbackOff, u as modelPrefsText, v as unsetCapabilityPreference, w as replayOutput, x as useProvider, y as unsetClass } from "./fallback-CjdakQVu.mjs";
|
|
20
|
+
import { _ as resolveSessionByNameOrId, a as buildDeduped, c as hasConversation, d as providerResumePlan, f as restoreTopLevel, g as migrateSessionScanCache, h as fmtAge, l as launchInDir, m as printExitDir, o as normalizeName$2, p as resumeArgvText, s as renderDedupedSessions, t as cmdMain, u as launchPrompt, v as scanCacheFilePath, y as scanSessions } from "./main-resolver-BFQfU5xo.mjs";
|
|
21
21
|
import { n as queriesDirPath, t as migrateQueriesDir } from "./query-feedback-xz5axTj3.mjs";
|
|
22
|
-
import { h as ledgerPath, m as eventsPath, n as ensureProxyRunning, p as ensureNoMcpConfig, r as stopProxy, t as DEFAULT_PROXY_PORT, v as workersLogDir } from "./server-
|
|
22
|
+
import { h as ledgerPath, m as eventsPath, n as ensureProxyRunning, p as ensureNoMcpConfig, r as stopProxy, t as DEFAULT_PROXY_PORT, v as workersLogDir } from "./server-CekGOJcp.mjs";
|
|
23
23
|
import { i as sendToSession, n as fetchLiveSessions, r as revealItermSession, t as callAiBroker } from "./aibroker-client-BK1h--W_.mjs";
|
|
24
|
-
import { a as totalUsageTokens, i as parseSessionUsage, r as sessionKeepaliveLedgerSummary, t as loadSessionKeepaliveState } from "./session-keepalive-
|
|
25
|
-
import { t as runChain } from "./chain-
|
|
24
|
+
import { a as totalUsageTokens, i as parseSessionUsage, r as sessionKeepaliveLedgerSummary, t as loadSessionKeepaliveState } from "./session-keepalive-Bc9aT678.mjs";
|
|
25
|
+
import { t as runChain } from "./chain-CGyAIHo4.mjs";
|
|
26
26
|
import { appendFileSync, chmodSync, copyFileSync, cpSync, createReadStream, existsSync, lstatSync, mkdirSync, readFileSync, readdirSync, readlinkSync, realpathSync, renameSync, statSync, symlinkSync, unlinkSync, writeFileSync } from "node:fs";
|
|
27
27
|
import { homedir, platform, tmpdir, userInfo } from "node:os";
|
|
28
28
|
import { basename, dirname, join, relative, resolve, sep } from "node:path";
|
|
@@ -161,7 +161,7 @@ async function cmdPromote(opts) {
|
|
|
161
161
|
console.error(dim$1(` Pick a durable location for the new project.`));
|
|
162
162
|
process.exit(1);
|
|
163
163
|
}
|
|
164
|
-
const { getRegistryBackend } = await import("./factory-
|
|
164
|
+
const { getRegistryBackend } = await import("./factory-DW7BCJJT.mjs");
|
|
165
165
|
const registryBackend = await getRegistryBackend();
|
|
166
166
|
const encodedDir = encodeDir(targetPath);
|
|
167
167
|
if (await registryBackend.getProjectBySlug(slug) ?? await registryBackend.getProjectByRootPath(targetPath) ?? await registryBackend.getProjectByEncodedDir(encodedDir)) {
|
|
@@ -2035,7 +2035,7 @@ async function cmdUnregister(slug, opts = {}) {
|
|
|
2035
2035
|
//#region src/cli/commands/project/projects-index.ts
|
|
2036
2036
|
function registerProjectsCommands(projectsCmd) {
|
|
2037
2037
|
projectsCmd.command("list", { isDefault: true }).description("Show the unified deduped listing (same as `pai`).\nUse --all to include cold / zero-session / archived projects.").option("--all", "Show all entries including cold / zero-session / archived projects").option("-n, --n <count>", "Max rows to show", "20").action(async (opts) => {
|
|
2038
|
-
const { cmdMain } = await import("./main-resolver-
|
|
2038
|
+
const { cmdMain } = await import("./main-resolver-VMBENifT.mjs");
|
|
2039
2039
|
await cmdMain(void 0, void 0, opts);
|
|
2040
2040
|
});
|
|
2041
2041
|
projectsCmd.command("list-raw").description("Raw registry listing with slug, path, status, last_active columns").option("--all", "Include archived projects (default: active only)").option("--status <status>", "Filter by status: active | archived").option("--tag <tag>", "Filter by tag").option("--type <type>", "Filter by type").action(async (opts) => {
|
|
@@ -3247,8 +3247,8 @@ function registerStatsCommands(memoryCmd) {
|
|
|
3247
3247
|
//#region src/cli/commands/memory/sources-cmd.ts
|
|
3248
3248
|
function registerSourcesCommand(memoryCmd) {
|
|
3249
3249
|
memoryCmd.command("sources").description("Show what the indexer has taken in: composition by source, which roots\ncontent enters from, the heaviest single files, and how many chunks are\nrewritten per day (which distinguishes a finite backlog from a treadmill).").option("--limit <n>", "Rows per section (default 8)", "8").action(async (opts) => {
|
|
3250
|
-
const { createStorageBackend } = await import("./factory-
|
|
3251
|
-
const { loadConfig } = await import("./config-
|
|
3250
|
+
const { createStorageBackend } = await import("./factory-DW7BCJJT.mjs");
|
|
3251
|
+
const { loadConfig } = await import("./config-DjXq_W42.mjs");
|
|
3252
3252
|
const { cmdMemorySources } = await import("./sources-BBe3AZ-W.mjs");
|
|
3253
3253
|
let backend;
|
|
3254
3254
|
try {
|
|
@@ -3950,7 +3950,7 @@ async function escalate(task, headline, detail, state, now, opts) {
|
|
|
3950
3950
|
let delivered = false;
|
|
3951
3951
|
try {
|
|
3952
3952
|
const { routeNotification } = await import("./router-C5hPk9YP.mjs");
|
|
3953
|
-
const { loadConfig } = await import("./config-
|
|
3953
|
+
const { loadConfig } = await import("./config-DjXq_W42.mjs");
|
|
3954
3954
|
delivered = (await routeNotification({
|
|
3955
3955
|
event: "error",
|
|
3956
3956
|
title: `PAI: ${headline}`,
|
|
@@ -7050,8 +7050,8 @@ function cmdLogs(opts) {
|
|
|
7050
7050
|
}
|
|
7051
7051
|
function registerDaemonCommands(daemonCmd) {
|
|
7052
7052
|
daemonCmd.command("serve").description("Start the PAI daemon in the foreground").action(async () => {
|
|
7053
|
-
const { serve } = await import("./daemon-
|
|
7054
|
-
const { loadConfig: lc, ensureConfigDir } = await import("./config-
|
|
7053
|
+
const { serve } = await import("./daemon-jviL3VVJ.mjs");
|
|
7054
|
+
const { loadConfig: lc, ensureConfigDir } = await import("./config-DjXq_W42.mjs");
|
|
7055
7055
|
ensureConfigDir();
|
|
7056
7056
|
await serve(lc());
|
|
7057
7057
|
});
|
|
@@ -16613,7 +16613,7 @@ async function getSessionTags(registryBackend, sessionId) {
|
|
|
16613
16613
|
* Session CRUD commands: list, info, rename, slug, tag, route, active, auto-route.
|
|
16614
16614
|
*/
|
|
16615
16615
|
async function cmdList(projectSlug, opts) {
|
|
16616
|
-
const { getRegistryBackend } = await import("./factory-
|
|
16616
|
+
const { getRegistryBackend } = await import("./factory-DW7BCJJT.mjs");
|
|
16617
16617
|
const registryBackend = await getRegistryBackend();
|
|
16618
16618
|
const limit = parseInt(opts.limit ?? "20", 10);
|
|
16619
16619
|
let project;
|
|
@@ -16678,7 +16678,7 @@ async function cmdList(projectSlug, opts) {
|
|
|
16678
16678
|
console.log(dim$1(` ${rows.length} session(s) shown (limit: ${limit})`));
|
|
16679
16679
|
}
|
|
16680
16680
|
async function cmdInfo(projectSlug, sessionNumber) {
|
|
16681
|
-
const { getRegistryBackend } = await import("./factory-
|
|
16681
|
+
const { getRegistryBackend } = await import("./factory-DW7BCJJT.mjs");
|
|
16682
16682
|
const registryBackend = await getRegistryBackend();
|
|
16683
16683
|
const project = await getProject$1(registryBackend, projectSlug);
|
|
16684
16684
|
if (!project) {
|
|
@@ -16702,7 +16702,7 @@ async function cmdInfo(projectSlug, sessionNumber) {
|
|
|
16702
16702
|
console.log();
|
|
16703
16703
|
}
|
|
16704
16704
|
async function cmdRename(projectSlug, numberOrLatest, newSlug) {
|
|
16705
|
-
const { getRegistryBackend } = await import("./factory-
|
|
16705
|
+
const { getRegistryBackend } = await import("./factory-DW7BCJJT.mjs");
|
|
16706
16706
|
await cmdRenameWith(await getRegistryBackend(), projectSlug, numberOrLatest, newSlug);
|
|
16707
16707
|
}
|
|
16708
16708
|
async function cmdRenameWith(registryBackend, projectSlug, numberOrLatest, newSlug) {
|
|
@@ -16765,7 +16765,7 @@ async function cmdRenameWith(registryBackend, projectSlug, numberOrLatest, newSl
|
|
|
16765
16765
|
console.log();
|
|
16766
16766
|
}
|
|
16767
16767
|
async function cmdSlug(projectSlug, numberOrLatest, opts) {
|
|
16768
|
-
const { getRegistryBackend } = await import("./factory-
|
|
16768
|
+
const { getRegistryBackend } = await import("./factory-DW7BCJJT.mjs");
|
|
16769
16769
|
const registryBackend = await getRegistryBackend();
|
|
16770
16770
|
const project = await getProject$1(registryBackend, projectSlug);
|
|
16771
16771
|
if (!project) {
|
|
@@ -16795,7 +16795,7 @@ async function cmdSlug(projectSlug, numberOrLatest, opts) {
|
|
|
16795
16795
|
}
|
|
16796
16796
|
}
|
|
16797
16797
|
async function cmdTag(projectSlug, sessionNumber, rawTags) {
|
|
16798
|
-
const { getRegistryBackend } = await import("./factory-
|
|
16798
|
+
const { getRegistryBackend } = await import("./factory-DW7BCJJT.mjs");
|
|
16799
16799
|
const registryBackend = await getRegistryBackend();
|
|
16800
16800
|
const project = await getProject$1(registryBackend, projectSlug);
|
|
16801
16801
|
if (!project) {
|
|
@@ -16835,7 +16835,7 @@ async function cmdTag(projectSlug, sessionNumber, rawTags) {
|
|
|
16835
16835
|
console.log();
|
|
16836
16836
|
}
|
|
16837
16837
|
async function cmdRoute(projectSlug, sessionNumber, targetProjectSlug, opts) {
|
|
16838
|
-
const { getRegistryBackend } = await import("./factory-
|
|
16838
|
+
const { getRegistryBackend } = await import("./factory-DW7BCJJT.mjs");
|
|
16839
16839
|
const registryBackend = await getRegistryBackend();
|
|
16840
16840
|
const project = await getProject$1(registryBackend, projectSlug);
|
|
16841
16841
|
if (!project) {
|
|
@@ -16877,7 +16877,7 @@ async function cmdRoute(projectSlug, sessionNumber, targetProjectSlug, opts) {
|
|
|
16877
16877
|
console.log();
|
|
16878
16878
|
}
|
|
16879
16879
|
async function cmdActive(opts) {
|
|
16880
|
-
const { getRegistryBackend } = await import("./factory-
|
|
16880
|
+
const { getRegistryBackend } = await import("./factory-DW7BCJJT.mjs");
|
|
16881
16881
|
const registryBackend = await getRegistryBackend();
|
|
16882
16882
|
const minutes = parseInt(opts.minutes ?? "60", 10);
|
|
16883
16883
|
const cutoff = Date.now() - minutes * 60 * 1e3;
|
|
@@ -16965,8 +16965,8 @@ async function cmdActive(opts) {
|
|
|
16965
16965
|
}
|
|
16966
16966
|
async function cmdAutoRoute(opts) {
|
|
16967
16967
|
const { autoRoute, formatAutoRouteJson } = await import("./auto-route-CF8WNaoy.mjs");
|
|
16968
|
-
const { getRegistryBackend, createStorageBackend } = await import("./factory-
|
|
16969
|
-
const { loadConfig } = await import("./config-
|
|
16968
|
+
const { getRegistryBackend, createStorageBackend } = await import("./factory-DW7BCJJT.mjs");
|
|
16969
|
+
const { loadConfig } = await import("./config-DjXq_W42.mjs");
|
|
16970
16970
|
const config = loadConfig();
|
|
16971
16971
|
const registryBackend = await getRegistryBackend();
|
|
16972
16972
|
const federation = await createStorageBackend(config);
|
|
@@ -17202,7 +17202,7 @@ async function cmdPause(opts) {
|
|
|
17202
17202
|
process.exitCode = 1;
|
|
17203
17203
|
return;
|
|
17204
17204
|
}
|
|
17205
|
-
const { getRegistryBackend } = await import("./factory-
|
|
17205
|
+
const { getRegistryBackend } = await import("./factory-DW7BCJJT.mjs");
|
|
17206
17206
|
const registryBackend = await getRegistryBackend();
|
|
17207
17207
|
const cwd = process.cwd();
|
|
17208
17208
|
const project = await resolveProjectByCwd(registryBackend, cwd);
|
|
@@ -17597,7 +17597,7 @@ function buildStopBody(project, sessionId) {
|
|
|
17597
17597
|
}
|
|
17598
17598
|
}
|
|
17599
17599
|
async function cmdHandover(projectSlug, numberOrLatest, sessionId) {
|
|
17600
|
-
const { getRegistryBackend } = await import("./factory-
|
|
17600
|
+
const { getRegistryBackend } = await import("./factory-DW7BCJJT.mjs");
|
|
17601
17601
|
const registryBackend = await getRegistryBackend();
|
|
17602
17602
|
let project;
|
|
17603
17603
|
if (projectSlug) {
|
|
@@ -17893,7 +17893,7 @@ function touchSentinel(rootPath) {
|
|
|
17893
17893
|
async function cmdAutosave(opts) {
|
|
17894
17894
|
const minGap = parseInt(opts.minGap ?? String(DEFAULT_MIN_GAP), 10);
|
|
17895
17895
|
const cwd = process.cwd();
|
|
17896
|
-
const { getRegistryBackend } = await import("./factory-
|
|
17896
|
+
const { getRegistryBackend } = await import("./factory-DW7BCJJT.mjs");
|
|
17897
17897
|
const registryBackend = await getRegistryBackend();
|
|
17898
17898
|
const project = await resolveProjectByCwd(registryBackend, cwd);
|
|
17899
17899
|
if (!project) return;
|
|
@@ -20169,8 +20169,8 @@ async function analyzeProject(registryBackend, project) {
|
|
|
20169
20169
|
async function countVectorDbPaths(oldPaths) {
|
|
20170
20170
|
if (oldPaths.length === 0) return 0;
|
|
20171
20171
|
try {
|
|
20172
|
-
const { loadConfig } = await import("./config-
|
|
20173
|
-
const { createStorageBackend } = await import("./factory-
|
|
20172
|
+
const { loadConfig } = await import("./config-DjXq_W42.mjs");
|
|
20173
|
+
const { createStorageBackend } = await import("./factory-DW7BCJJT.mjs");
|
|
20174
20174
|
const config = loadConfig();
|
|
20175
20175
|
if (config.storageBackend !== "postgres") return 0;
|
|
20176
20176
|
const backend = await createStorageBackend(config);
|
|
@@ -20187,8 +20187,8 @@ async function countVectorDbPaths(oldPaths) {
|
|
|
20187
20187
|
async function updateVectorDbPaths(moves) {
|
|
20188
20188
|
if (moves.length === 0) return 0;
|
|
20189
20189
|
try {
|
|
20190
|
-
const { loadConfig } = await import("./config-
|
|
20191
|
-
const { createStorageBackend } = await import("./factory-
|
|
20190
|
+
const { loadConfig } = await import("./config-DjXq_W42.mjs");
|
|
20191
|
+
const { createStorageBackend } = await import("./factory-DW7BCJJT.mjs");
|
|
20192
20192
|
const config = loadConfig();
|
|
20193
20193
|
if (config.storageBackend !== "postgres") return 0;
|
|
20194
20194
|
const backend = await createStorageBackend(config);
|
|
@@ -20275,7 +20275,7 @@ async function displayDryRun(plans) {
|
|
|
20275
20275
|
console.log();
|
|
20276
20276
|
}
|
|
20277
20277
|
async function executeCleanup(plans, skipReindex) {
|
|
20278
|
-
const { getRegistryBackend } = await import("./factory-
|
|
20278
|
+
const { getRegistryBackend } = await import("./factory-DW7BCJJT.mjs");
|
|
20279
20279
|
const registryBackend = await getRegistryBackend();
|
|
20280
20280
|
let deleted = 0;
|
|
20281
20281
|
let renamed = 0;
|
|
@@ -20472,7 +20472,7 @@ async function executeCleanup(plans, skipReindex) {
|
|
|
20472
20472
|
//#region src/cli/commands/session-cleanup/index.ts
|
|
20473
20473
|
function registerSessionCleanupCommand(sessionCmd) {
|
|
20474
20474
|
sessionCmd.command("cleanup [project-slug]").description("Clean up session notes: delete empties, auto-name unnamed, move into YYYY/MM/ hierarchy, renumber").option("--execute", "Actually perform the cleanup (default is dry-run)").option("--no-renumber", "Skip renumbering sessions after deletions").option("--no-reindex", "Skip triggering memory re-index after moves").action(async (projectSlug, opts) => {
|
|
20475
|
-
const { getRegistryBackend } = await import("./factory-
|
|
20475
|
+
const { getRegistryBackend } = await import("./factory-DW7BCJJT.mjs");
|
|
20476
20476
|
const registryBackend = await getRegistryBackend();
|
|
20477
20477
|
const dryRun = !opts.execute;
|
|
20478
20478
|
const skipReindex = opts.reindex === false;
|
|
@@ -20542,7 +20542,7 @@ function finalizeNote(notePath) {
|
|
|
20542
20542
|
}
|
|
20543
20543
|
async function cmdEnd(opts) {
|
|
20544
20544
|
await cmdPause(opts);
|
|
20545
|
-
const { getRegistryBackend } = await import("./factory-
|
|
20545
|
+
const { getRegistryBackend } = await import("./factory-DW7BCJJT.mjs");
|
|
20546
20546
|
const registryBackend = await getRegistryBackend();
|
|
20547
20547
|
const cwd = process.cwd();
|
|
20548
20548
|
const project = await registryBackend.findProjectByCwdPrefix(cwd);
|
|
@@ -20990,7 +20990,7 @@ async function cmdFind(query, opts) {
|
|
|
20990
20990
|
*/
|
|
20991
20991
|
async function getProjects(includeArchived) {
|
|
20992
20992
|
try {
|
|
20993
|
-
const { getRegistryBackend } = await import("./factory-
|
|
20993
|
+
const { getRegistryBackend } = await import("./factory-DW7BCJJT.mjs");
|
|
20994
20994
|
const rows = await (await getRegistryBackend()).listProjectsWithSessionStats();
|
|
20995
20995
|
return includeArchived ? rows : rows.filter((p) => p.status === "active");
|
|
20996
20996
|
} catch {
|
|
@@ -21464,7 +21464,7 @@ async function cmdPick(opts = {}) {
|
|
|
21464
21464
|
const onRemove = async (rec) => {
|
|
21465
21465
|
if (!rec.slug) return false;
|
|
21466
21466
|
try {
|
|
21467
|
-
const { getRegistryBackend } = await import("./factory-
|
|
21467
|
+
const { getRegistryBackend } = await import("./factory-DW7BCJJT.mjs");
|
|
21468
21468
|
const registryBackend = await getRegistryBackend();
|
|
21469
21469
|
const project = await registryBackend.getProjectBySlug(rec.slug);
|
|
21470
21470
|
if (!project || project.status !== "active") return false;
|
|
@@ -21749,4 +21749,4 @@ claude() {
|
|
|
21749
21749
|
|
|
21750
21750
|
//#endregion
|
|
21751
21751
|
export { drainStdio as n, buildProgram as t };
|
|
21752
|
-
//# sourceMappingURL=program-
|
|
21752
|
+
//# sourceMappingURL=program-BnsjB57Q.mjs.map
|