SPB Git

spb/khaelor Public

KHAELOR — a terminal-native autonomous engineering agent powered by Anthropic.

TypeScript 82.9% HTML 14.9% CSS 1.1% JavaScript 0.7%
2.7 KB · 72 lines typescript
Raw Blame History
1/**2 * KHAELOR3 * File: src/cli/subtasks.ts4 * Description: Subtask wiring — SubtaskManager factory whose child runner assembles a full headless engine per worktree (v2 design §6).5 *6 * Author: Simon-Pierre Boucher7 * Contact: contact@spboucher.ai8 */910import type { ResolvedConfig } from "../config/index.js";11import type { DurableEventInput } from "../session/index.js";12import { SubtaskManager } from "../tasks/index.js";13import type { ExecFn } from "../tasks/index.js";14import type { Workspace } from "../workspace/index.js";15import { runHeadlessTurn } from "./headless.js";16import type { FileLogger } from "./logger.js";1718const CHILD_PROMPT_SUFFIX =19  "\n\nYou are running as an isolated KHAELOR subtask inside a dedicated git worktree. " +20  "Work only inside this worktree. Do not push, merge, or touch branches — the orchestrator " +21  "supervises the merge. Design first, verify before finishing.";2223/** Adapt Workspace.exec to the tasks module's minimal exec seam. */24export function workspaceExec(workspace: Workspace): ExecFn {25  return async (cmd, cwd) => {26    const result = await workspace.exec({ cmd, timeoutMs: 120_000, ...(cwd !== undefined ? { cwd } : {}) });27    return { exitCode: result.exitCode, stdout: result.stdout, stderr: result.stderr };28  };29}3031export interface CreateSubtaskManagerOptions {32  config: ResolvedConfig;33  workspace: Workspace;34  projectRoot: string;35  logger: FileLogger;36  publish: (event: DurableEventInput) => void;37  /** Orchestrator session id — recorded as the child's meta.parent. */38  parentSessionId: string;39}4041/**42 * Build the SubtaskManager with a child runner that assembles a complete43 * headless engine over the worktree: own JSONL (meta.parent → orchestrator),44 * non-interactive permissions (capability attenuation: asks resolve deny),45 * phase gates in the configured mode, native verify active (v2 §6).46 */47export function createSubtaskManager(options: CreateSubtaskManagerOptions): SubtaskManager {48  return new SubtaskManager({49    publish: options.publish,50    exec: workspaceExec(options.workspace),51    projectRoot: options.projectRoot,52    runChild: async (args) => {53      const result = await runHeadlessTurn({54        config: options.config,55        cwd: args.worktreePath,56        prompt: args.description + CHILD_PROMPT_SUFFIX,57        logger: options.logger,58        meta: { parent: options.parentSessionId },59      });60      return {61        status:62          result.outcome === "done" ? "done" : result.outcome === "interrupted" ? "interrupted" : "failed",63        verifyOk: result.verifyOk,64        detail:65          result.outcome === "done"66            ? result.finalText.slice(0, 2000)67            : result.detail || result.finalText.slice(0, 2000),68      };69    },70  });71}72