import { parseArgs } from "@std/cli/parse-args"; import { basename, dirname, isAbsolute, join, relative, resolve, } from "@std/path"; import { isAbsolute as isAbsoluteSandboxPath, normalize as normalizeSandboxPath, } from "@std/path/posix"; import type { JSONSchema } from "@commonfabric/api"; import { type CfcEnforcementMode } from "@commonfabric/runner/cfc"; import { DEFAULT_GATEWAY_BASE_URL, type HarnessGatewayAuthMode, parseCfcEnforcementMode, parseHarnessGatewayAuthMode, } from "./config.ts"; import { createHarnessImageAttachment, parseImageAttachmentPaths, } from "./image-attachments.ts"; import type { HarnessImageAttachment } from "./contracts/image.ts"; import { HARNESS_BROWSER_ACCESS_ACCOUNT_ACCESS, HARNESS_BROWSER_ACCESS_LEASE_TYPE, HARNESS_BROWSER_ACCESS_PROFILE_MODES, type HarnessBrowserAccessLease, parseBrowserAccessExpiresAt, } from "./contracts/browser-access.ts"; import { readHarnessRunArtifacts, resolveHarnessRunPaths, } from "./artifacts.ts"; import { createCliPromptSlotBinding, type PromptSlotRole, } from "./contracts/prompt-slot.ts"; import { type HarnessRunManifest, parseLoomRunManifestJson, } from "./contracts/run-manifest.ts"; import { DEFAULT_SUBAGENT_PROFILE, getHarnessSubagentProfileConfig, HARNESS_SUBAGENT_PROFILES, type HarnessSubagentProfile, } from "./contracts/subagent.ts"; import { type BuiltinToolId } from "./contracts/tool-descriptor.ts"; import type { HarnessTranscriptEvent, HarnessTranscriptMessage, } from "./contracts/transcript.ts"; import { CfHarnessEngine } from "./engine.ts"; import { CFC_INVOCATION_CONTEXT_DIR_ENV, CFC_RESULT_DIR_ENV, DEFAULT_DOCKER_RUNSC_IMAGE, DEFAULT_FABRIC_MOUNT_PATH, } from "./sandbox/docker-runsc.ts"; import type { DockerRunscAdditionalMountConfig } from "./sandbox/types.ts"; import { CfHarnessPromptLoop, type CreateHarnessPromptLoopOptions, type HarnessPromptLoopResult, } from "./prompt-loop.ts"; import { discoverHarnessSkills, loadHarnessSkillContext, } from "./skills/registry.ts"; import { parseAllowedSkillScriptSpec, uniqueAllowedSkillScripts, } from "./skills/scripts.ts"; import type { HarnessAllowedSkillScript, HarnessSkillScriptExecutionTarget, } from "./contracts/skill.ts"; import { digestJsonValue, parseStructuredResultJson, parseStructuredResultSchema, validateStructuredResultValue, } from "./structured-result.ts"; import { BUILTIN_TOOLS } from "./tools/registry.ts"; import { normalizeCdpOrigin } from "./tools/browser-host-command-policy.ts"; const DEFAULT_MODEL = "gpt-5.5"; const DEFAULT_MAX_MODEL_TURNS = 8; const DEFAULT_ARTIFACT_DIRNAME = ".cf-harness-artifacts"; const CLI_OUTPUT_MODES = ["operator", "batch"] as const; const CLI_STRING_FLAGS = [ "workspace", "cwd", "focus-root", "allow-tool", "allow-skill-script", "allow-subagent-profile", "output-mode", "prompt-slot-role", "prompt", "prompt-file", "image", "system-prompt", "resume-run", "model", "skills-root", "skill", "skill-script-execution-target", "gateway-base-url", "gateway-auth-mode", "artifact-root", "result-json-path", "structured-result-path", "structured-result-schema", "structured-result-schema-file", "run-manifest", "cfc-enforcement-mode", "cfc-result-dir", "cfc-invocation-context-dir", "sandbox-image", "sandbox-docker-runtime", "max-model-turns", "fabric-mount", "host-mount", "browser-access-lease-id", "browser-access-cdp-url", "browser-access-owner", "browser-access-expires-at", "browser-access-profile-mode", "browser-access-account-access", ] as const; const CLI_BOOLEAN_FLAGS = [ "help", "describe-capabilities", "print-transcript", "stream-events", "no-skill-catalog", ] as const; const CLI_COLLECT_FLAGS = [ "allow-tool", "allow-skill-script", "allow-subagent-profile", "skill", "image", "host-mount", ] as const; export type CfHarnessCliOutputMode = (typeof CLI_OUTPUT_MODES)[number]; export interface CfHarnessCliConfig { workspace: string; cwd?: string; focusRoot?: string; allowedToolIds?: readonly BuiltinToolId[]; allowedSubagentProfiles: readonly HarnessSubagentProfile[]; outputMode: CfHarnessCliOutputMode; streamEvents: boolean; promptSlotRole: PromptSlotRole; prompt?: string; imageAttachments: readonly HarnessImageAttachment[]; resumeRun?: string; systemPrompt?: string; skillsRoot?: string; skillsRootSandboxPath?: string; skillNames: readonly string[]; allowedSkillScripts: readonly HarnessAllowedSkillScript[]; skillScriptExecutionTarget: HarnessSkillScriptExecutionTarget; skillCatalogEnabled: boolean; model?: string; gatewayBaseUrl: string; gatewayAuthMode: HarnessGatewayAuthMode; artifactRoot: string; resultJsonPath?: string; structuredResult?: CfHarnessStructuredResultConfig; runManifestPath?: string; cfcEnforcementModeOverride?: CfcEnforcementMode; cfcResultDir?: string; cfcInvocationContextDir?: string; browserAccess?: HarnessBrowserAccessLease; maxModelTurns: number; printTranscript: boolean; apiKey?: string; apiKeySource?: "CF_HARNESS_API_KEY" | "OPENAI_API_KEY"; sandboxImage?: string; sandboxDockerRuntime?: string; fabricMount?: string; hostMounts: readonly CfHarnessHostMountConfig[]; } export type CfHarnessHostMountMode = "readonly" | "writable"; export interface CfHarnessHostMountConfig { name: string; hostPath: string; sandboxPath: string; mode: CfHarnessHostMountMode; } export interface CfHarnessStructuredResultConfig { path: string; sandboxPath: string; schema: JSONSchema; } export interface CfHarnessCliCapabilities { type: "cf-harness.capabilities"; version: 1; cliFlags: readonly string[]; repeatableCliFlags: readonly string[]; parentToolIds: readonly BuiltinToolId[]; builtinToolIds: readonly BuiltinToolId[]; subagentProfiles: readonly HarnessSubagentProfile[]; nativeModelToolIds: readonly string[]; features: { images: true; structuredResults: true; skills: true; skillScripts: true; runManifest: true; fabricMount: true; hostMounts: true; resumeRun: true; }; } export interface CfHarnessCliIO { stdout(text: string): void; stderr(text: string): void; } export type CfHarnessCliSignal = "SIGINT" | "SIGTERM"; export type CfHarnessCliSignalHandler = ( signal: CfHarnessCliSignal, ) => void | Promise; export interface RunCfHarnessCliDependencies { cwd?: string; env?: Record; io?: CfHarnessCliIO; readTextFile?: (path: string) => Promise; writeTextFile?: (path: string, text: string) => Promise; readRunArtifacts?: typeof readHarnessRunArtifacts; createPromptLoop?: ( options: CreateHarnessPromptLoopOptions, ) => Pick; registerSignalHandler?: ( signals: readonly CfHarnessCliSignal[], handler: CfHarnessCliSignalHandler, ) => () => void; exit?: (code: number) => never | void; } const defaultCliIo = (): CfHarnessCliIO => ({ stdout: (text) => Deno.stdout.writeSync(new TextEncoder().encode(text)), stderr: (text) => Deno.stderr.writeSync(new TextEncoder().encode(text)), }); const signalExitCode = (signal: CfHarnessCliSignal): number => signal === "SIGINT" ? 130 : 143; const defaultRegisterSignalHandler = ( signals: readonly CfHarnessCliSignal[], handler: CfHarnessCliSignalHandler, ): () => void => { const listeners = signals.map((signal) => { const listener = () => { void handler(signal); }; Deno.addSignalListener(signal, listener); return { signal, listener }; }); let disposed = false; return () => { if (disposed) { return; } disposed = true; for (const { signal, listener } of listeners) { Deno.removeSignalListener(signal, listener); } }; }; export const installCfHarnessSignalHandlers = ( getEngine: () => CfHarnessEngine | undefined, deps: Pick< RunCfHarnessCliDependencies, "registerSignalHandler" | "exit" > = {}, ): () => void => { const registerSignalHandler = deps.registerSignalHandler ?? defaultRegisterSignalHandler; const exit = deps.exit ?? ((code: number): never => Deno.exit(code)); let handlingSignal = false; let cleanup = () => {}; let disposed = false; cleanup = registerSignalHandler(["SIGINT", "SIGTERM"], async (signal) => { if (handlingSignal) { return; } handlingSignal = true; cleanup(); try { await getEngine()?.terminalizeInterruptedRun(signal); } finally { exit(signalExitCode(signal)); } }); return () => { if (disposed) { return; } disposed = true; cleanup(); }; }; const usage = `Usage: deno run -A src/main.ts [options] [prompt text] Options: --workspace Workspace host path (defaults to current directory) --cwd Initial working directory inside the workspace --focus-root Narrow exploration to a workspace subpath when possible --allow-tool Restrict available tools (repeatable: bash | read_file | view_image | web_fetch | read_skill_resource | run_skill_script | edit_file | write_file | delegate_task) --allow-skill-script Allow exact skill script execution (repeatable: skill:scripts/path) --allow-subagent-profile

Authorize delegate_task to spawn a profile (repeatable: default | browser | web_fetch | web_search) --output-mode operator | batch (default: operator) --stream-events Print transcript events as they happen --prompt-slot-role direct-command | context | quote (default: direct-command) --prompt Prompt text to run --prompt-file Read prompt text from a file --image Attach an image file to the initial prompt (repeatable; png/jpeg/gif/webp) --resume-run Resume from a run root or run-state.json path --system-prompt Optional system prompt --skills-root Skill root containing /SKILL.md --skill Preload a skill for this run (repeatable) --skill-script-execution-target Execute skill scripts in sandbox or host (default: sandbox) --no-skill-catalog Disable automatic skill catalog disclosure --model Model name (default: ${DEFAULT_MODEL}) --gateway-base-url OpenAI-compatible gateway URL --gateway-auth-mode bearer | none (default: bearer) --artifact-root Host-side artifact directory --result-json-path Optional batch metadata JSON output path --structured-result-path

JSON file the run must write and validate --structured-result-schema JSON Schema for --structured-result-path --structured-result-schema-file

JSON Schema file for --structured-result-path --run-manifest Optional Loom run manifest JSON path --browser-access-lease-id Browser Access lease id for browser subagents --browser-access-cdp-url Local CDP origin for the Browser Access lease --browser-access-owner Optional owner label for the Browser Access lease --browser-access-expires-at Optional lease expiry timestamp --browser-access-profile-mode persistent | transient --browser-access-account-access available | none --cfc-enforcement-mode disabled | observe | enforce-explicit | enforce-strict --cfc-result-dir Host dir where runsc writes the CFC result sidecar (required for enforce-* modes) --cfc-invocation-context-dir Host dir where the harness writes the CFC invocation-context sidecar (required for enforce-* modes) --sandbox-image Docker image for the runsc-cfc sandbox (default: ${DEFAULT_DOCKER_RUNSC_IMAGE}) --sandbox-docker-runtime Docker runtime for the sandbox (default: runsc-cfc) --fabric-mount Host path for a Fabric FUSE mount (mounted at /fabric in the sandbox) --host-mount Extra host bind mount (repeatable: name=,source=,target=,mode=readonly|writable) --max-model-turns Maximum model turns before aborting --print-transcript Print the final transcript JSON after the response --describe-capabilities Print machine-readable capability JSON and exit --help Show this help text Environment: CF_HARNESS_API_KEY Preferred API key for the OpenAI-compatible gateway OPENAI_API_KEY Fallback API key if CF_HARNESS_API_KEY is unset CF_HARNESS_GATEWAY_BASE_URL Default value for --gateway-base-url CF_HARNESS_GATEWAY_AUTH_MODE Default value for --gateway-auth-mode CF_HARNESS_MODEL Default value for --model (ignored on --resume-run) CF_HARNESS_DOCKER_NETWORK_MODE none | bridge | host (default: bridge) CF_HARNESS_SANDBOX_IMAGE Default value for --sandbox-image CF_HARNESS_SANDBOX_DOCKER_RUNTIME Default value for --sandbox-docker-runtime ${CFC_RESULT_DIR_ENV} Fallback for --cfc-result-dir ${CFC_INVOCATION_CONTEXT_DIR_ENV} Fallback for --cfc-invocation-context-dir `; // CFC sidecar transport dirs may be supplied by flag (resolved against cwd so // relative paths work) or env-var fallback (already an absolute host path by // convention). The docker-runsc layer re-validates that the result is absolute. const resolveOptionalCfcDir = ( flagValue: unknown, envValue: string | undefined, cwd: string, flagName: string, ): string | undefined => { if (typeof flagValue === "string") { const trimmed = flagValue.trim(); if (trimmed === "") { throw new Error(`${flagName} requires a non-empty path`); } return resolve(cwd, trimmed); } return envValue; }; const parsePositiveInteger = ( input: string | undefined, flagName: string, ): number => { if (input === undefined) { return DEFAULT_MAX_MODEL_TURNS; } if (!/^\d+$/.test(input)) { throw new Error(`${flagName} must be a positive integer`); } const parsed = Number(input); if (!Number.isSafeInteger(parsed) || parsed <= 0) { throw new Error(`${flagName} must be a positive integer`); } return parsed; }; const PROMPT_SLOT_ROLES = ["direct-command", "context", "quote"] as const; const CLI_PARENT_TOOL_IDS = [ "bash", "read_file", "view_image", "web_fetch", "read_skill_resource", "run_skill_script", "edit_file", "write_file", "delegate_task", ] as const satisfies readonly BuiltinToolId[]; const uniqueStrings = ( values: readonly T[], ): readonly T[] => [...new Set(values)]; export const createCfHarnessCliCapabilities = (): CfHarnessCliCapabilities => ({ type: "cf-harness.capabilities", version: 1, cliFlags: [ ...CLI_STRING_FLAGS.map((flag) => `--${flag}`), ...CLI_BOOLEAN_FLAGS.map((flag) => `--${flag}`), ], repeatableCliFlags: CLI_COLLECT_FLAGS.map((flag) => `--${flag}`), parentToolIds: [...CLI_PARENT_TOOL_IDS], builtinToolIds: BUILTIN_TOOLS.map((tool) => tool.descriptor.toolId), subagentProfiles: [...HARNESS_SUBAGENT_PROFILES], nativeModelToolIds: uniqueStrings( HARNESS_SUBAGENT_PROFILES.flatMap((profile) => getHarnessSubagentProfileConfig(profile).nativeModelToolIds ?? [] ), ), features: { images: true, structuredResults: true, skills: true, skillScripts: true, runManifest: true, fabricMount: true, hostMounts: true, resumeRun: true, }, }); const parsePromptSlotRole = ( input: string | undefined, ): PromptSlotRole | undefined => input !== undefined && (PROMPT_SLOT_ROLES as readonly string[]).includes(input) ? input as PromptSlotRole : undefined; const parseCliOutputMode = ( input: string | undefined, ): CfHarnessCliOutputMode | undefined => input !== undefined && (CLI_OUTPUT_MODES as readonly string[]).includes(input) ? input as CfHarnessCliOutputMode : undefined; const parseBuiltinToolId = ( input: string, ): BuiltinToolId | undefined => (CLI_PARENT_TOOL_IDS as readonly string[]).includes(input) ? input as BuiltinToolId : undefined; const parseBuiltinToolIds = ( input: string | readonly string[] | undefined, ): readonly BuiltinToolId[] | undefined => { if (input === undefined) { return undefined; } const values = Array.isArray(input) ? input : [input]; if (values.length === 0) { return undefined; } const parsed = values.map((value) => parseBuiltinToolId(value)); if (parsed.some((value) => value === undefined)) { throw new Error( `allowed tools must be one or more of ${CLI_PARENT_TOOL_IDS.join(", ")}`, ); } return [...new Set(parsed)] as readonly BuiltinToolId[]; }; const parseAllowedSkillScripts = ( input: string | readonly string[] | undefined, ): readonly HarnessAllowedSkillScript[] => { if (input === undefined) { return []; } const values = Array.isArray(input) ? input : [input]; if (values.length === 0) { return []; } try { return uniqueAllowedSkillScripts( values.map((value) => parseAllowedSkillScriptSpec(value)), ); } catch (error) { throw new Error( `invalid --allow-skill-script: ${ error instanceof Error ? error.message : String(error) }`, ); } }; const parseSkillScriptExecutionTarget = ( input: string | undefined, ): HarnessSkillScriptExecutionTarget => { if (input === undefined || input === "") { return "sandbox"; } if (input === "sandbox" || input === "host") { return input; } throw new Error( "skill script execution target must be one of sandbox, host", ); }; const parseSubagentProfile = ( input: string, ): HarnessSubagentProfile | undefined => (HARNESS_SUBAGENT_PROFILES as readonly string[]).includes(input) ? input as HarnessSubagentProfile : undefined; const parseSubagentProfiles = ( input: string | readonly string[] | undefined, ): readonly HarnessSubagentProfile[] | undefined => { if (input === undefined) { return undefined; } const values = Array.isArray(input) ? input : [input]; if (values.length === 0) { return undefined; } const parsed = values.map((value) => parseSubagentProfile(value)); if (parsed.some((value) => value === undefined)) { throw new Error( `allowed subagent profiles must be one or more of ${ HARNESS_SUBAGENT_PROFILES.join(", ") }`, ); } return [...new Set(parsed)] as readonly HarnessSubagentProfile[]; }; const resolveAllowedSubagentProfiles = ( allowedToolIds: readonly BuiltinToolId[] | undefined, allowedSubagentProfiles: readonly HarnessSubagentProfile[] | undefined, ): readonly HarnessSubagentProfile[] => allowedSubagentProfiles ?? (allowedToolIds === undefined ? [DEFAULT_SUBAGENT_PROFILE] : []); const nonEmptyEnvValue = (input: string | undefined): string | undefined => { const trimmed = input?.trim(); return trimmed === undefined || trimmed === "" ? undefined : trimmed; }; const optionalStringArg = ( args: ReturnType, name: string, ): string | undefined => { const raw = args[name]; return typeof raw === "string" ? raw.trim() : undefined; }; const optionalStringValue = ( value: string | undefined, allowed: readonly T[], flagName: string, ): T | undefined => { if (value === undefined) { return undefined; } if ((allowed as readonly string[]).includes(value)) { return value as T; } throw new Error(`${flagName} must be one of: ${allowed.join(", ")}`); }; const parseBrowserAccessLease = ( args: ReturnType, ): HarnessBrowserAccessLease | undefined => { const leaseId = optionalStringArg(args, "browser-access-lease-id"); const cdpUrl = optionalStringArg(args, "browser-access-cdp-url"); const owner = optionalStringArg(args, "browser-access-owner"); const expiresAt = optionalStringArg(args, "browser-access-expires-at"); const profileMode = optionalStringValue( optionalStringArg(args, "browser-access-profile-mode"), HARNESS_BROWSER_ACCESS_PROFILE_MODES, "--browser-access-profile-mode", ); const accountAccess = optionalStringValue( optionalStringArg(args, "browser-access-account-access"), HARNESS_BROWSER_ACCESS_ACCOUNT_ACCESS, "--browser-access-account-access", ); const anyProvided = leaseId !== undefined || cdpUrl !== undefined || owner !== undefined || expiresAt !== undefined || profileMode !== undefined || accountAccess !== undefined; if (!anyProvided) { return undefined; } if (leaseId === undefined || leaseId.length === 0) { throw new Error( "--browser-access-lease-id requires a non-empty value when browser access is configured", ); } if (cdpUrl === undefined || cdpUrl.length === 0) { throw new Error( "--browser-access-cdp-url is required when browser access is configured", ); } const normalizedCdpUrl = normalizeCdpOrigin(cdpUrl); if (normalizedCdpUrl === undefined) { throw new Error( "--browser-access-cdp-url must be an http:// local origin with an explicit port", ); } if ( expiresAt !== undefined && expiresAt.length > 0 && parseBrowserAccessExpiresAt(expiresAt) === undefined ) { throw new Error( "--browser-access-expires-at must be a valid timestamp", ); } return { type: HARNESS_BROWSER_ACCESS_LEASE_TYPE, leaseId, cdpUrl: normalizedCdpUrl, ...(owner !== undefined && owner.length > 0 ? { owner } : {}), ...(expiresAt !== undefined && expiresAt.length > 0 ? { expiresAt } : {}), ...(profileMode !== undefined ? { profileMode } : {}), ...(accountAccess !== undefined ? { accountAccess } : {}), }; }; const parseSkillNames = ( input: string | readonly string[] | undefined, ): readonly string[] => { if (input === undefined) { return []; } const values = Array.isArray(input) ? input : [input]; return [ ...new Set( values.map((value) => value.trim()).filter((value) => value.length > 0), ), ]; }; interface CfHarnessAllowedHostRoot { hostPath: string; sandboxPath: string; readOnly: boolean; name?: string; } const HOST_MOUNT_NAME_PATTERN = /^[A-Za-z0-9][A-Za-z0-9._-]*$/; const normalizeSandboxMountPath = (path: string, label: string): string => { const normalized = normalizeSandboxPath(path); if (!isAbsoluteSandboxPath(normalized) || normalized === "/") { throw new Error(`${label} must be an absolute non-root sandbox path`); } return normalized.length > 1 && normalized.endsWith("/") ? normalized.slice(0, -1) : normalized; }; const parseHostMountSpecParts = ( spec: string, ): Record => { const parts: Record = {}; for (const segment of spec.split(",")) { const trimmed = segment.trim(); if (trimmed.length === 0) { continue; } const index = trimmed.indexOf("="); if (index <= 0) { throw new Error( "--host-mount entries must use key=value comma-separated fields", ); } const key = trimmed.slice(0, index).trim(); const value = trimmed.slice(index + 1).trim(); if (key.length === 0 || value.length === 0) { throw new Error("--host-mount fields require non-empty keys and values"); } if (parts[key] !== undefined) { throw new Error(`--host-mount field repeated: ${key}`); } parts[key] = value; } return parts; }; const realPathIfDirectory = async ( path: string, label: string, ): Promise => { let realPath: string; try { realPath = await Deno.realPath(path); } catch (error) { if (error instanceof Deno.errors.NotFound) { throw new Error(`${label} must exist: ${path}`); } throw error; } const stat = await Deno.stat(realPath); if (!stat.isDirectory) { throw new Error(`${label} must be a directory: ${path}`); } if (realPath === dirname(realPath)) { throw new Error(`${label} must not be the filesystem root`); } return realPath; }; const parseHostMountSpec = async ( spec: string, cwd: string, ): Promise => { if (spec.trim().length === 0) { throw new Error("--host-mount requires a non-empty spec"); } const parts = parseHostMountSpecParts(spec); const name = parts.name; const source = parts.source; const target = parts.target; const mode = parts.mode ?? "readonly"; if (name === undefined || source === undefined || target === undefined) { throw new Error( "--host-mount requires name, source, and target fields", ); } if (!HOST_MOUNT_NAME_PATTERN.test(name)) { throw new Error( "--host-mount name must start with an alphanumeric character and contain only alphanumerics, dot, underscore, or dash", ); } if (mode !== "readonly" && mode !== "writable") { throw new Error("--host-mount mode must be readonly or writable"); } return { name, hostPath: await realPathIfDirectory( isAbsolute(source) ? resolve(source) : resolve(cwd, source), "--host-mount source", ), sandboxPath: normalizeSandboxMountPath(target, "--host-mount target"), mode, }; }; const parseHostMountSpecs = async ( input: string | readonly string[] | undefined, cwd: string, ): Promise => { const specs = input === undefined ? [] : Array.isArray(input) ? input : [input]; const mounts = await Promise.all( specs.map((spec) => parseHostMountSpec(spec, cwd)), ); const names = new Set(); for (const mount of mounts) { if (names.has(mount.name)) { throw new Error(`--host-mount name repeated: ${mount.name}`); } names.add(mount.name); } return mounts; }; const resolveHostPathThroughNearestRealParent = (hostPath: string): string => { const suffix: string[] = []; let candidate = hostPath; while (true) { try { const realCandidate = Deno.realPathSync(candidate); return suffix.length === 0 ? realCandidate : join(realCandidate, ...suffix); } catch (error) { if (!(error instanceof Deno.errors.NotFound)) { throw error; } } const parent = dirname(candidate); if (parent === candidate) { return hostPath; } suffix.unshift(basename(candidate)); candidate = parent; } }; const createAllowedHostRoots = ( workspace: string, hostMounts: readonly CfHarnessHostMountConfig[], ): readonly CfHarnessAllowedHostRoot[] => [ { hostPath: resolveHostPathThroughNearestRealParent(workspace), sandboxPath: "/workspace", readOnly: false, }, ...hostMounts.map((mount) => ({ hostPath: mount.hostPath, sandboxPath: mount.sandboxPath, readOnly: mount.mode === "readonly", name: mount.name, })), ]; const isHostPathWithinRoot = (root: string, path: string): boolean => { const relativePath = relative(root, path); return relativePath === "" || (!relativePath.startsWith("..") && !isAbsolute(relativePath)); }; const findAllowedHostRoot = ( roots: readonly CfHarnessAllowedHostRoot[], hostPath: string, ): CfHarnessAllowedHostRoot | undefined => roots .filter((root) => isHostPathWithinRoot(root.hostPath, hostPath)) .sort((left, right) => right.hostPath.length - left.hostPath.length)[0]; const resolveCliHostPath = ( workspace: string, input: string, ): string => isAbsolute(input) ? resolve(input) : resolve(workspace, input); const toSandboxPathForAllowedHostPath = ( root: CfHarnessAllowedHostRoot, hostPath: string, ): string => { const relativePath = relative(root.hostPath, hostPath); if (relativePath === "") { return root.sandboxPath; } return normalizeSandboxPath( `${root.sandboxPath}/${relativePath.replaceAll("\\", "/")}`, ); }; const resolvePathWithinAllowedHostRoots = ( roots: readonly CfHarnessAllowedHostRoot[], workspace: string, input: string, flagName: string, options: { requireWritable?: boolean } = {}, ): { hostPath: string; sandboxPath: string; root: CfHarnessAllowedHostRoot; } => { const requestedHostPath = resolveCliHostPath(workspace, input); const realHostPath = resolveHostPathThroughNearestRealParent( requestedHostPath, ); const hostPath = realHostPath; const root = findAllowedHostRoot(roots, realHostPath); if (root === undefined) { throw new Error( `${flagName} must stay within the workspace or a host mount`, ); } if (options.requireWritable && root.readOnly) { throw new Error(`${flagName} must be inside a writable host mount`); } return { hostPath, sandboxPath: toSandboxPathForAllowedHostPath(root, hostPath), root, }; }; const assertSkillsRootRealPathWithinAllowedHostRoots = async ( roots: readonly CfHarnessAllowedHostRoot[], skillsRoot: string, ): Promise => { let skillsRootRealPath: string; try { skillsRootRealPath = await Deno.realPath(skillsRoot); } catch (error) { if (error instanceof Deno.errors.NotFound) { throw new Error(`--skills-root must exist: ${skillsRoot}`); } throw error; } if (findAllowedHostRoot(roots, skillsRootRealPath) === undefined) { throw new Error( "--skills-root must stay within the workspace or a host mount", ); } }; const resolvePrompt = async ( args: ReturnType, cwd: string, readTextFile: (path: string) => Promise, ): Promise => { const promptFlag = typeof args.prompt === "string" ? args.prompt : undefined; const promptFile = typeof args["prompt-file"] === "string" ? resolve(cwd, args["prompt-file"]) : undefined; const resumeRun = typeof args["resume-run"] === "string" ? resolve(cwd, args["resume-run"]) : undefined; const positionalPrompt = args._.length > 0 ? args._.map(String).join(" ").trim() : undefined; const promptSources = [ resumeRun !== undefined ? "resume-run" : undefined, promptFlag !== undefined ? "prompt" : undefined, promptFile !== undefined ? "prompt-file" : undefined, positionalPrompt !== undefined && positionalPrompt.length > 0 ? "positional" : undefined, ].filter((value): value is string => value !== undefined); if (promptSources.length === 0) { throw new Error( "a prompt is required via --prompt, --prompt-file, positional text, or --resume-run", ); } if (promptSources.length > 1) { throw new Error( "provide input using only one of --prompt, --prompt-file, positional text, or --resume-run", ); } if (resumeRun !== undefined) { return undefined; } if (promptFlag !== undefined) { return promptFlag; } if (promptFile !== undefined) { return await readTextFile(promptFile); } return positionalPrompt!; }; const parseStructuredResultConfig = async ( args: ReturnType, options: { cwd: string; workspace: string; allowedHostRoots: readonly CfHarnessAllowedHostRoot[]; readTextFile: (path: string) => Promise; }, ): Promise => { const structuredResultPathResolution = typeof args["structured-result-path"] === "string" ? resolvePathWithinAllowedHostRoots( options.allowedHostRoots, options.workspace, args["structured-result-path"], "--structured-result-path", { requireWritable: true }, ) : undefined; const structuredResultPath = structuredResultPathResolution?.hostPath; const inlineSchema = typeof args["structured-result-schema"] === "string" ? args["structured-result-schema"] : undefined; const schemaFile = typeof args["structured-result-schema-file"] === "string" ? resolve(options.cwd, args["structured-result-schema-file"]) : undefined; if (structuredResultPath === undefined) { if (inlineSchema !== undefined || schemaFile !== undefined) { throw new Error( "--structured-result-schema requires --structured-result-path", ); } return undefined; } if (inlineSchema !== undefined && schemaFile !== undefined) { throw new Error( "provide only one of --structured-result-schema or --structured-result-schema-file", ); } const rawSchema = inlineSchema ?? (schemaFile !== undefined ? await options.readTextFile(schemaFile) : undefined); if (rawSchema === undefined) { throw new Error( "--structured-result-path requires --structured-result-schema or --structured-result-schema-file", ); } const parsed = parseStructuredResultSchema(rawSchema, { label: "--structured-result-schema", }); if (parsed === undefined) { throw new Error( "--structured-result-path requires --structured-result-schema or --structured-result-schema-file", ); } return { path: structuredResultPath, sandboxPath: structuredResultPathResolution!.sandboxPath, schema: parsed.schema, }; }; export const parseCfHarnessCliArgs = async ( argv: readonly string[], deps: Pick = {}, ): Promise => { const normalizedArgv = argv[0] === "--" ? argv.slice(1) : argv; const args = parseArgs([...normalizedArgv], { string: [...CLI_STRING_FLAGS], boolean: [...CLI_BOOLEAN_FLAGS], collect: [...CLI_COLLECT_FLAGS], alias: { h: "help", }, default: { "print-transcript": false, }, }); if (args.help) { return { help: true }; } const cwd = resolve(deps.cwd ?? Deno.cwd()); const workspace = resolve( typeof args.workspace === "string" ? args.workspace : cwd, ); const hostMounts = await parseHostMountSpecs( args["host-mount"] as string | readonly string[] | undefined, cwd, ); const allowedHostRoots = createAllowedHostRoots(workspace, hostMounts); const initialCwd = typeof args.cwd === "string" ? resolvePathWithinAllowedHostRoots( allowedHostRoots, workspace, args.cwd, "--cwd", ).sandboxPath : undefined; const focusRoot = typeof args["focus-root"] === "string" ? resolve(workspace, args["focus-root"]) : undefined; const skillsRoot = typeof args["skills-root"] === "string" ? resolvePathWithinAllowedHostRoots( allowedHostRoots, workspace, args["skills-root"], "--skills-root", ).hostPath : undefined; const skillsRootSandboxPath = skillsRoot !== undefined ? resolvePathWithinAllowedHostRoots( allowedHostRoots, workspace, skillsRoot, "--skills-root", ).sandboxPath : undefined; const skillNames = parseSkillNames( args.skill as string | readonly string[] | undefined, ); if (skillNames.length > 0 && skillsRoot === undefined) { throw new Error("--skill requires --skills-root"); } const allowedSkillScripts = parseAllowedSkillScripts( args["allow-skill-script"] as string | readonly string[] | undefined, ); if (allowedSkillScripts.length > 0 && skillsRoot === undefined) { throw new Error("--allow-skill-script requires --skills-root"); } const skillScriptExecutionTarget = parseSkillScriptExecutionTarget( typeof args["skill-script-execution-target"] === "string" ? args["skill-script-execution-target"] : undefined, ); const allowedToolIds = parseBuiltinToolIds( args["allow-tool"] as string | readonly string[] | undefined, ); const allowedSubagentProfiles = resolveAllowedSubagentProfiles( allowedToolIds, parseSubagentProfiles( args["allow-subagent-profile"] as | string | readonly string[] | undefined, ), ); const browserAccess = parseBrowserAccessLease(args); const outputMode = parseCliOutputMode( typeof args["output-mode"] === "string" ? args["output-mode"] : undefined, ); if ( args["output-mode"] !== undefined && outputMode === undefined ) { throw new Error("output mode must be one of operator, batch"); } const promptSlotRole = parsePromptSlotRole( typeof args["prompt-slot-role"] === "string" ? args["prompt-slot-role"] : undefined, ); if ( args["prompt-slot-role"] !== undefined && promptSlotRole === undefined ) { throw new Error( "prompt slot role must be one of direct-command, context, quote", ); } const resumeRun = typeof args["resume-run"] === "string" ? resolve(cwd, args["resume-run"]) : undefined; if (resumeRun !== undefined && skillNames.length > 0) { throw new Error("--skill preloading is not supported with --resume-run"); } const imagePaths = parseImageAttachmentPaths( args.image as string | readonly string[] | undefined, ); if (resumeRun !== undefined && imagePaths.length > 0) { throw new Error("--image is not supported with --resume-run"); } if (skillsRoot !== undefined) { await assertSkillsRootRealPathWithinAllowedHostRoots( allowedHostRoots, skillsRoot, ); } const artifactRoot = resolve( typeof args["artifact-root"] === "string" ? args["artifact-root"] : resumeRun !== undefined ? dirname(resolveHarnessRunPaths(resumeRun).runRoot) : join(workspace, DEFAULT_ARTIFACT_DIRNAME), ); const resultJsonPath = typeof args["result-json-path"] === "string" ? resolve(cwd, args["result-json-path"]) : undefined; const runManifestPath = typeof args["run-manifest"] === "string" ? resolve(cwd, args["run-manifest"]) : undefined; const env = deps.env ?? { CF_HARNESS_API_KEY: Deno.env.get("CF_HARNESS_API_KEY"), OPENAI_API_KEY: Deno.env.get("OPENAI_API_KEY"), CF_HARNESS_GATEWAY_BASE_URL: Deno.env.get("CF_HARNESS_GATEWAY_BASE_URL"), CF_HARNESS_GATEWAY_AUTH_MODE: Deno.env.get( "CF_HARNESS_GATEWAY_AUTH_MODE", ), CF_HARNESS_MODEL: Deno.env.get("CF_HARNESS_MODEL"), CF_HARNESS_CFC_ENFORCEMENT_MODE: Deno.env.get( "CF_HARNESS_CFC_ENFORCEMENT_MODE", ), CF_CFC_MODE: Deno.env.get("CF_CFC_MODE"), CF_HARNESS_SANDBOX_IMAGE: Deno.env.get("CF_HARNESS_SANDBOX_IMAGE"), CF_HARNESS_SANDBOX_DOCKER_RUNTIME: Deno.env.get( "CF_HARNESS_SANDBOX_DOCKER_RUNTIME", ), [CFC_RESULT_DIR_ENV]: Deno.env.get(CFC_RESULT_DIR_ENV), [CFC_INVOCATION_CONTEXT_DIR_ENV]: Deno.env.get( CFC_INVOCATION_CONTEXT_DIR_ENV, ), }; const gatewayBaseUrl = typeof args["gateway-base-url"] === "string" ? args["gateway-base-url"] : nonEmptyEnvValue(env.CF_HARNESS_GATEWAY_BASE_URL) ?? DEFAULT_GATEWAY_BASE_URL; const rawGatewayAuthMode = typeof args["gateway-auth-mode"] === "string" ? args["gateway-auth-mode"] : nonEmptyEnvValue(env.CF_HARNESS_GATEWAY_AUTH_MODE); const parsedGatewayAuthMode = parseHarnessGatewayAuthMode( rawGatewayAuthMode, ); if (rawGatewayAuthMode !== undefined && parsedGatewayAuthMode === undefined) { throw new Error("gateway auth mode must be one of bearer, none"); } const gatewayAuthMode = parsedGatewayAuthMode ?? "bearer"; const readTextFile = deps.readTextFile ?? Deno.readTextFile; const structuredResult = await parseStructuredResultConfig(args, { cwd, workspace, allowedHostRoots, readTextFile, }); const prompt = await resolvePrompt(args, cwd, readTextFile); const imageAttachments = await Promise.all( imagePaths.map((path) => { const resolved = resolvePathWithinAllowedHostRoots( allowedHostRoots, workspace, path, "--image", ); return createHarnessImageAttachment({ workspaceHostPath: resolved.root.hostPath, cwd: resolved.root.hostPath, path: resolved.hostPath, }); }), ); const rawSandboxImage = typeof args["sandbox-image"] === "string" ? args["sandbox-image"].trim() : undefined; if (rawSandboxImage !== undefined && rawSandboxImage === "") { throw new Error("--sandbox-image requires a non-empty image reference"); } const sandboxImage = rawSandboxImage ?? nonEmptyEnvValue(env.CF_HARNESS_SANDBOX_IMAGE); const rawSandboxDockerRuntime = typeof args["sandbox-docker-runtime"] === "string" ? args["sandbox-docker-runtime"].trim() : undefined; if (rawSandboxDockerRuntime !== undefined && rawSandboxDockerRuntime === "") { throw new Error( "--sandbox-docker-runtime requires a non-empty runtime name", ); } const sandboxDockerRuntime = rawSandboxDockerRuntime ?? nonEmptyEnvValue(env.CF_HARNESS_SANDBOX_DOCKER_RUNTIME); const explicitCfcMode = typeof args["cfc-enforcement-mode"] === "string" ? args["cfc-enforcement-mode"] : undefined; const envCfcMode = nonEmptyEnvValue(env.CF_HARNESS_CFC_ENFORCEMENT_MODE) ?? nonEmptyEnvValue(env.CF_CFC_MODE); const cfcEnforcementModeOverride = parseCfcEnforcementMode( explicitCfcMode ?? envCfcMode, ); if ( (explicitCfcMode !== undefined || envCfcMode !== undefined) && cfcEnforcementModeOverride === undefined ) { throw new Error( "cfc enforcement mode must be one of disabled, observe, enforce-explicit, enforce-strict", ); } const cfcResultDir = resolveOptionalCfcDir( args["cfc-result-dir"], nonEmptyEnvValue(env[CFC_RESULT_DIR_ENV]), cwd, "--cfc-result-dir", ); const cfcInvocationContextDir = resolveOptionalCfcDir( args["cfc-invocation-context-dir"], nonEmptyEnvValue(env[CFC_INVOCATION_CONTEXT_DIR_ENV]), cwd, "--cfc-invocation-context-dir", ); const rawFabricMount = typeof args["fabric-mount"] === "string" ? args["fabric-mount"].trim() : undefined; if (rawFabricMount !== undefined && rawFabricMount === "") { throw new Error("--fabric-mount requires a non-empty path"); } const fabricMount = rawFabricMount !== undefined ? resolve(cwd, rawFabricMount) : undefined; const apiKey = env.CF_HARNESS_API_KEY ?? env.OPENAI_API_KEY; const apiKeySource = env.CF_HARNESS_API_KEY !== undefined ? "CF_HARNESS_API_KEY" : env.OPENAI_API_KEY !== undefined ? "OPENAI_API_KEY" : undefined; return { workspace, ...(initialCwd !== undefined ? { cwd: initialCwd } : {}), ...(focusRoot !== undefined ? { focusRoot } : {}), ...(allowedToolIds !== undefined ? { allowedToolIds } : {}), allowedSubagentProfiles, outputMode: outputMode ?? "operator", streamEvents: Boolean(args["stream-events"]), promptSlotRole: promptSlotRole ?? "direct-command", ...(prompt !== undefined ? { prompt } : {}), imageAttachments, ...(resumeRun !== undefined ? { resumeRun } : {}), ...(typeof args["system-prompt"] === "string" ? { systemPrompt: args["system-prompt"] } : {}), ...(skillsRoot !== undefined ? { skillsRoot } : {}), ...(skillsRootSandboxPath !== undefined ? { skillsRootSandboxPath } : {}), skillNames, allowedSkillScripts, skillScriptExecutionTarget, skillCatalogEnabled: args["no-skill-catalog"] !== true, ...(typeof args.model === "string" ? { model: args.model } : resumeRun === undefined ? { model: nonEmptyEnvValue(env.CF_HARNESS_MODEL) ?? DEFAULT_MODEL } : {}), gatewayBaseUrl, gatewayAuthMode, artifactRoot, ...(resultJsonPath !== undefined ? { resultJsonPath } : {}), ...(structuredResult !== undefined ? { structuredResult } : {}), ...(runManifestPath !== undefined ? { runManifestPath } : {}), ...(cfcEnforcementModeOverride !== undefined ? { cfcEnforcementModeOverride } : {}), ...(cfcResultDir !== undefined ? { cfcResultDir } : {}), ...(cfcInvocationContextDir !== undefined ? { cfcInvocationContextDir } : {}), ...(browserAccess !== undefined ? { browserAccess } : {}), maxModelTurns: parsePositiveInteger( typeof args["max-model-turns"] === "string" ? args["max-model-turns"] : undefined, "--max-model-turns", ), printTranscript: Boolean(args["print-transcript"]), ...(apiKey !== undefined ? { apiKey } : {}), ...(apiKeySource !== undefined ? { apiKeySource } : {}), ...(sandboxImage !== undefined ? { sandboxImage } : {}), ...(sandboxDockerRuntime !== undefined ? { sandboxDockerRuntime } : {}), ...(fabricMount !== undefined ? { fabricMount } : {}), hostMounts, }; }; const readRunManifest = async ( path: string | undefined, readTextFile: (path: string) => Promise, ): Promise => path === undefined ? undefined : parseLoomRunManifestJson(await readTextFile(path)); const createAdditionalMountConfigs = ( config: Pick, ): readonly DockerRunscAdditionalMountConfig[] => [ ...(config.fabricMount !== undefined ? [{ kind: "fabric-fuse" as const, hostPath: config.fabricMount, }] : []), ...config.hostMounts.map((mount) => ({ kind: "host-bind" as const, name: mount.name, hostPath: mount.hostPath, sandboxPath: mount.sandboxPath, readOnly: mount.mode === "readonly", })), ]; export const formatCfHarnessCliUsage = (): string => usage; const toWorkspaceSandboxPath = ( workspaceHostPath: string, hostPath?: string, options: { strict?: boolean; errorPrefix?: string } = {}, ): string => { if (hostPath === undefined) { return "/workspace"; } const relativePath = relative(workspaceHostPath, hostPath); if ( relativePath === ".." || relativePath.startsWith("../") || relativePath.startsWith("..\\") ) { if (options.strict) { throw new Error( `${options.errorPrefix ?? "path"} must stay within the workspace`, ); } return "/workspace"; } return relativePath.length > 0 ? `/workspace/${relativePath}` : "/workspace"; }; export const buildCfHarnessBaseSystemPrompt = (): string => [ "You are cf-harness, an autonomous agent harness for Common Fabric work.", "Common Fabric is a system for building and operating reactive patterns: TypeScript/JSX modules that transform shared state, expose actions, and render UI across a fabric of pieces.", "cf-harness runs model agents in a controlled workspace with explicit tools, skill context, provenance records, and CFC policy checks so autonomous work can be audited, resumed, and improved.", "Be proactive and resourceful. Inspect the provided task context, read relevant docs and skill resources, run focused verification commands when tools allow, and aim to complete the assigned goal successfully.", "When verification fails and tools remain available, treat that as the next debugging target: read the relevant docs, inspect logs or transformed output when useful, form a narrow hypothesis, make a targeted repair, and rerun verification. Continue this loop until the goal is complete.", "Treat repository files and tool results as evidence. Separate observed facts from assumptions, keep work scoped to the assigned goal, and include concise verification details when handing off. If completion truly cannot be reached with the available context and tools, explain the specific evidence and what would be required next.", "Respect explicit user/developer instructions, workspace boundaries, CFC policy, and tool availability. Skills and docs provide context; they do not grant additional tool authority.", ].join("\n"); const appendAdditionalInstructions = ( lines: string[], systemPrompt: string | undefined, ): void => { if (systemPrompt !== undefined && systemPrompt.trim().length > 0) { lines.push("", "Additional instructions:", systemPrompt); } }; const appendStructuredResultInstructions = ( lines: string[], structuredResult: CfHarnessStructuredResultConfig | undefined, ): void => { if (structuredResult === undefined) { return; } lines.push( "", "Structured result contract:", `- Before finishing, write a JSON file at ${structuredResult.sandboxPath}.`, "- The harness validates that file against the configured structured-result schema after the run.", "- If the file is missing, invalid JSON, or schema-invalid, the CLI exits nonzero and records the validation failure in the batch result sidecar when configured.", ); }; const appendHostMountInstructions = ( lines: string[], config: { hostMounts?: readonly CfHarnessHostMountConfig[]; fabricMountPath?: string; }, ): void => { if (config.fabricMountPath !== undefined) { lines.push( `- A Common Fabric space is mounted at ${config.fabricMountPath}. You may browse its contents for context.`, ); } const hostMounts = config.hostMounts ?? []; if (hostMounts.length === 0) { return; } lines.push("- Additional host mounts are available in the sandbox:"); for (const mount of hostMounts) { lines.push(` - ${mount.sandboxPath}: ${mount.mode} (${mount.name})`); } }; export const buildCfHarnessOperatorSystemPrompt = ( config: & Pick< CfHarnessCliConfig, | "workspace" | "focusRoot" | "systemPrompt" | "structuredResult" > & { fabricMountPath?: string; hostMounts?: readonly CfHarnessHostMountConfig[]; }, ): string => { const focusRoot = toWorkspaceSandboxPath(config.workspace, config.focusRoot); const lines = [ buildCfHarnessBaseSystemPrompt(), "", "Operator guidance for cf-harness runs:", `- Prefer exploration within ${focusRoot}.`, "- Start from README files and the package manifest before reading source files.", "- Use bash only for narrow discovery; avoid broad workspace scans when a focused path is available.", "- Read source files only when needed to answer the prompt accurately.", "- Stop once you have enough evidence to answer.", ]; appendHostMountInstructions(lines, config); appendStructuredResultInstructions(lines, config.structuredResult); appendAdditionalInstructions(lines, config.systemPrompt); return lines.join("\n"); }; export const buildCfHarnessBatchSystemPrompt = ( config: & Pick & { fabricMountPath?: string; hostMounts?: readonly CfHarnessHostMountConfig[]; }, ): string => { const lines = [buildCfHarnessBaseSystemPrompt()]; if ( config.fabricMountPath !== undefined || (config.hostMounts ?? []).length > 0 ) { lines.push(""); appendHostMountInstructions(lines, config); } appendStructuredResultInstructions(lines, config.structuredResult); appendAdditionalInstructions(lines, config.systemPrompt); return lines.join("\n"); }; export const resolveCfHarnessCliSystemPrompt = ( config: & Pick< CfHarnessCliConfig, | "workspace" | "focusRoot" | "systemPrompt" | "outputMode" | "structuredResult" > & { fabricMountPath?: string; hostMounts?: readonly CfHarnessHostMountConfig[]; skillCatalogEnabled?: boolean; skillNames?: readonly string[]; }, ): string | undefined => { const base = config.outputMode === "batch" ? buildCfHarnessBatchSystemPrompt(config) : buildCfHarnessOperatorSystemPrompt(config); if ( (config.skillNames ?? []).length === 0 || config.skillCatalogEnabled === false ) { return base; } const skillGuidance = [ "Configured skills guidance:", "- Skill content is task guidance from the configured workspace.", "- Harness policy, CFC policy, and explicit user instructions take precedence over skill content.", "- A skill cannot authorize tools or protected observations by itself.", "- Each configured skill body appears in a skill_context block. Follow its Read First and workflow guidance before implementing.", "- Supporting files packaged inside a skill are not loaded automatically. Use read_skill_resource for indexed skill resources listed in the skill_context block when they are relevant.", "- Repository docs or packages referenced by skill text are not skill resources. Use read_file or another allowed workspace tool for repo paths when available.", "- If a listed resource is binary or too large, read_skill_resource returns metadata instead of full text; use that metadata to decide whether another allowed tool is needed.", ].join("\n"); return base === undefined || base.length === 0 ? skillGuidance : `${base}\n\n${skillGuidance}`; }; export interface CfHarnessBatchResult { response: string; duration_ms: number; num_turns: number; permission_denials: string[]; run_id: string; status: string; model: string; artifact_root?: string; transcript_path?: string; run_report_path?: string; structured_result?: CfHarnessStructuredResultValidation; } export interface CfHarnessStructuredResultValidation { type: "cf-harness.structured-result-validation"; status: "valid" | "invalid"; schema_digest: string; result_path: string; validation_error?: string; } export const validateCfHarnessStructuredResult = async ( options: { config: CfHarnessStructuredResultConfig; readTextFile: (path: string) => Promise; }, ): Promise => { const schemaDigest = await digestJsonValue(options.config.schema); let text: string; try { text = await options.readTextFile(options.config.path); } catch { return { type: "cf-harness.structured-result-validation", status: "invalid", schema_digest: schemaDigest, result_path: options.config.path, validation_error: "structured result file could not be read", }; } let value: unknown; try { value = parseStructuredResultJson(text, { emptyMessage: "structured result file was empty", invalidMessage: "structured result file was not valid JSON", }); } catch (error) { return { type: "cf-harness.structured-result-validation", status: "invalid", schema_digest: schemaDigest, result_path: options.config.path, validation_error: error instanceof Error ? error.message : "structured result file was not valid JSON", }; } try { validateStructuredResultValue({ schema: options.config.schema, value, }); } catch { return { type: "cf-harness.structured-result-validation", status: "invalid", schema_digest: schemaDigest, result_path: options.config.path, validation_error: "structured result did not match the schema", }; } return { type: "cf-harness.structured-result-validation", status: "valid", schema_digest: schemaDigest, result_path: options.config.path, }; }; export const createCfHarnessBatchResult = ( result: HarnessPromptLoopResult, durationMs: number, structuredResult?: CfHarnessStructuredResultValidation, ): CfHarnessBatchResult => ({ response: result.finalAssistantText, duration_ms: durationMs, num_turns: result.modelTurns, permission_denials: result.runState.policyEvents .filter((event) => event.severity === "denied") .map((event) => event.detail), run_id: result.runState.runId, status: result.runState.status, model: result.model, ...(result.runState.artifactRoot !== undefined ? { artifact_root: result.runState.artifactRoot } : {}), ...(result.runState.transcriptPath !== undefined ? { transcript_path: result.runState.transcriptPath } : {}), ...(result.runState.runReportPath !== undefined ? { run_report_path: result.runState.runReportPath } : {}), ...(structuredResult !== undefined ? { structured_result: structuredResult } : {}), }); const summarizeToolResult = (content: string): string => { try { const parsed = JSON.parse(content) as Record; if (typeof parsed.detail === "string") { return parsed.detail; } if (typeof parsed.outputId === "string") { return `outputId=${parsed.outputId}`; } } catch { // fall through } const singleLine = content.replace(/\s+/g, " ").trim(); return singleLine.length > 180 ? `${singleLine.slice(0, 177)}...` : singleLine; }; const summarizeToolCallArguments = ( toolName: string, rawArguments: string, ): string | undefined => { try { const parsed = JSON.parse(rawArguments) as Record; switch (toolName) { case "bash": case "bash-no-sandbox": return typeof parsed.command === "string" ? `command=${JSON.stringify(parsed.command)}` : undefined; case "read_file": return typeof parsed.path === "string" ? `path=${JSON.stringify(parsed.path)}` : undefined; case "web_fetch": return typeof parsed.url === "string" ? `url=${JSON.stringify(parsed.url)}` : undefined; case "edit_file": { const path = typeof parsed.path === "string" ? `path=${JSON.stringify(parsed.path)}` : undefined; const editCount = Array.isArray(parsed.edits) ? `edits=${parsed.edits.length}` : undefined; return [path, editCount].filter((value): value is string => value !== undefined ) .join(" "); } case "read_skill_resource": { const skill = typeof parsed.skill === "string" ? `skill=${JSON.stringify(parsed.skill)}` : undefined; const path = typeof parsed.path === "string" ? `path=${JSON.stringify(parsed.path)}` : undefined; return [skill, path].filter((value): value is string => value !== undefined ) .join(" "); } case "run_skill_script": { const skill = typeof parsed.skill === "string" ? `skill=${JSON.stringify(parsed.skill)}` : undefined; const path = typeof parsed.path === "string" ? `path=${JSON.stringify(parsed.path)}` : undefined; const args = Array.isArray(parsed.args) ? `args=${parsed.args.length}` : undefined; return [skill, path, args].filter((value): value is string => value !== undefined ) .join(" "); } case "write_file": { const path = typeof parsed.path === "string" ? `path=${JSON.stringify(parsed.path)}` : undefined; const mode = typeof parsed.mode === "string" ? `mode=${JSON.stringify(parsed.mode)}` : undefined; return [path, mode].filter((value): value is string => value !== undefined ) .join(" "); } case "delegate_task": return "subagent"; default: return undefined; } } catch { return undefined; } }; export const formatCfHarnessTranscriptEvent = ( event: HarnessTranscriptEvent, ): string | undefined => { const message: HarnessTranscriptMessage = event.message; switch (message.role) { case "system": return undefined; case "user": { const imageCount = message.imageAttachments?.length ?? 0; return imageCount > 0 ? `user: ${message.content}\nuser images: ${imageCount}\n` : `user: ${message.content}\n`; } case "assistant": if (message.toolCalls !== undefined && message.toolCalls.length > 0) { const tools = message.toolCalls.map((toolCall) => { const detail = summarizeToolCallArguments( toolCall.function.name, toolCall.function.arguments, ); return detail !== undefined && detail.length > 0 ? `${toolCall.function.name}(${detail})` : toolCall.function.name; }) .join(", "); const prefix = `assistant -> tools: ${tools}`; return message.content.trim().length > 0 ? `${prefix}\nassistant: ${message.content}\n` : `${prefix}\n`; } return message.content.trim().length > 0 ? `assistant: ${message.content}\n` : undefined; case "tool": return `tool ${message.toolName}: ${ summarizeToolResult(message.content) }\n`; } }; export const formatCfHarnessCliResult = ( result: HarnessPromptLoopResult, outputMode: CfHarnessCliOutputMode = "operator", ): string => { if (outputMode === "batch") { return `${result.finalAssistantText}\n`; } const lines = [ result.finalAssistantText, "", `runId: ${result.runState.runId}`, `status: ${result.runState.status}`, `modelTurns: ${result.modelTurns}`, ]; if (result.runState.artifactRoot !== undefined) { lines.push(`artifactRoot: ${result.runState.artifactRoot}`); } if (result.runState.transcriptPath !== undefined) { lines.push(`transcriptPath: ${result.runState.transcriptPath}`); } if (result.runState.runReportPath !== undefined) { lines.push(`runReportPath: ${result.runState.runReportPath}`); } if (result.runState.policyEvents.length > 0) { lines.push(`policyEvents: ${result.runState.policyEvents.length}`); for (const event of result.runState.policyEvents) { lines.push( `- ${event.severity} ${event.toolId}: ${event.detail}`, ); } } return `${lines.join("\n")}\n`; }; const parseCfHarnessCliControlArgs = ( argv: readonly string[], ): ReturnType => { const normalizedArgv = argv[0] === "--" ? argv.slice(1) : argv; return parseArgs([...normalizedArgv], { boolean: ["help", "describe-capabilities"], alias: { h: "help", }, }); }; export const runCfHarnessCli = async ( argv: readonly string[], deps: RunCfHarnessCliDependencies = {}, ): Promise => { const io = deps.io ?? defaultCliIo(); let activeEngine: CfHarnessEngine | undefined; let signalCleanup: (() => void) | undefined; const activateEngine = (engine: CfHarnessEngine) => { activeEngine = engine; signalCleanup ??= installCfHarnessSignalHandlers( () => activeEngine, deps, ); }; try { const controlArgs = parseCfHarnessCliControlArgs(argv); if (controlArgs.help) { io.stdout(formatCfHarnessCliUsage()); return 0; } if (controlArgs["describe-capabilities"]) { io.stdout( `${JSON.stringify(createCfHarnessCliCapabilities(), null, 2)}\n`, ); return 0; } const parsed = await parseCfHarnessCliArgs(argv, deps); if ("help" in parsed) { io.stdout(formatCfHarnessCliUsage()); return 0; } const createPromptLoop = deps.createPromptLoop ?? ((options: CreateHarnessPromptLoopOptions) => new CfHarnessPromptLoop(options)); const writeTextFile = deps.writeTextFile ?? Deno.writeTextFile; const readTextFile = deps.readTextFile ?? Deno.readTextFile; if (parsed.gatewayAuthMode === "bearer" && parsed.apiKey === undefined) { throw new Error( "no API key configured; set CF_HARNESS_API_KEY or OPENAI_API_KEY", ); } const startedAt = Date.now(); let result: HarnessPromptLoopResult; const runManifest = await readRunManifest( parsed.runManifestPath, readTextFile, ); const promptSlotBinding = runManifest?.promptSlot ?? createCliPromptSlotBinding({ kernelName: "cf-harness", ...(parsed.runManifestPath !== undefined ? { source: { type: "cf-harness.loom-run-manifest-ref", path: parsed.runManifestPath, }, } : {}), role: parsed.promptSlotRole, subject: parsed.resumeRun ?? parsed.workspace, }); const onTranscriptEvent = parsed.streamEvents ? (event: HarnessTranscriptEvent) => { const formatted = formatCfHarnessTranscriptEvent(event); if (formatted !== undefined) { io.stdout(formatted); } } : undefined; const additionalMounts = createAdditionalMountConfigs(parsed); const prepareSkillContextMessages = async ( engine: CfHarnessEngine, ): Promise => { if (parsed.skillsRoot === undefined) { return []; } const registry = await discoverHarnessSkills({ skillsRoot: parsed.skillsRoot, sandboxSkillsRoot: parsed.skillsRootSandboxPath, }); await engine.persistSkillRegistry(registry); if (parsed.skillNames.length === 0) { return []; } const context = await loadHarnessSkillContext({ registry, skillNames: parsed.skillNames, source: "cli-preload", runId: engine.getRunState().runId, activatedAt: engine.getRunState().updatedAt, }); await engine.persistSkillActivations(context.activations); return [context.contextText]; }; if (parsed.resumeRun !== undefined) { const readRunArtifacts = deps.readRunArtifacts ?? readHarnessRunArtifacts; const artifacts = await readRunArtifacts(parsed.resumeRun); const engine = new CfHarnessEngine({ runState: artifacts.runState, artifactRoot: parsed.artifactRoot, workspaceHostPath: parsed.workspace, ...(parsed.sandboxImage !== undefined ? { sandboxImage: parsed.sandboxImage } : {}), ...(parsed.sandboxDockerRuntime !== undefined ? { sandboxDockerRuntime: parsed.sandboxDockerRuntime } : {}), ...(parsed.cfcResultDir !== undefined ? { cfcResultDir: parsed.cfcResultDir } : {}), ...(parsed.cfcInvocationContextDir !== undefined ? { cfcInvocationContextDir: parsed.cfcInvocationContextDir } : {}), model: parsed.model ?? artifacts.runState.model, gatewayBaseUrl: parsed.gatewayBaseUrl, gatewayAuthMode: parsed.gatewayAuthMode, ...(parsed.cwd !== undefined ? { cwd: parsed.cwd } : {}), ...(parsed.skillsRoot !== undefined ? { skillsRoot: parsed.skillsRoot } : {}), ...(parsed.allowedSkillScripts.length > 0 ? { allowedSkillScripts: parsed.allowedSkillScripts } : {}), skillScriptExecutionTarget: parsed.skillScriptExecutionTarget, ...(parsed.browserAccess !== undefined ? { browserAccess: parsed.browserAccess } : {}), cfcEnforcementModeOverride: parsed.cfcEnforcementModeOverride, ...(runManifest !== undefined ? { runManifest } : {}), ...(parsed.runManifestPath !== undefined ? { runManifestPath: parsed.runManifestPath } : {}), ...(additionalMounts.length > 0 ? { additionalMounts } : {}), }); activateEngine(engine); const loop = createPromptLoop({ engine, workspaceHostPath: parsed.workspace, artifactRoot: parsed.artifactRoot, model: parsed.model ?? artifacts.runState.model, gatewayBaseUrl: parsed.gatewayBaseUrl, gatewayAuthMode: parsed.gatewayAuthMode, ...(parsed.cwd !== undefined ? { cwd: parsed.cwd } : {}), ...(parsed.skillsRoot !== undefined ? { skillsRoot: parsed.skillsRoot } : {}), ...(parsed.allowedSkillScripts.length > 0 ? { allowedSkillScripts: parsed.allowedSkillScripts } : {}), skillScriptExecutionTarget: parsed.skillScriptExecutionTarget, ...(parsed.browserAccess !== undefined ? { browserAccess: parsed.browserAccess } : {}), cfcEnforcementModeOverride: parsed.cfcEnforcementModeOverride, ...(runManifest !== undefined ? { runManifest } : {}), ...(parsed.runManifestPath !== undefined ? { runManifestPath: parsed.runManifestPath } : {}), apiKey: parsed.apiKey, apiKeySource: parsed.apiKeySource, maxModelTurns: parsed.maxModelTurns, allowedSubagentProfiles: parsed.allowedSubagentProfiles, ...(parsed.allowedToolIds !== undefined ? { allowedToolIds: parsed.allowedToolIds } : {}), }); if (artifacts.transcript === undefined) { throw new Error( `resume run is missing transcript data: ${parsed.resumeRun}`, ); } result = await loop.runTranscript({ transcript: artifacts.transcript, model: parsed.model ?? artifacts.runState.model, maxModelTurns: parsed.maxModelTurns, promptSlotBinding: artifacts.runState.promptSlotBinding ?? promptSlotBinding, onTranscriptEvent, }); } else { const engine = new CfHarnessEngine({ workspaceHostPath: parsed.workspace, artifactRoot: parsed.artifactRoot, ...(parsed.sandboxImage !== undefined ? { sandboxImage: parsed.sandboxImage } : {}), ...(parsed.sandboxDockerRuntime !== undefined ? { sandboxDockerRuntime: parsed.sandboxDockerRuntime } : {}), ...(parsed.cfcResultDir !== undefined ? { cfcResultDir: parsed.cfcResultDir } : {}), ...(parsed.cfcInvocationContextDir !== undefined ? { cfcInvocationContextDir: parsed.cfcInvocationContextDir } : {}), model: parsed.model, gatewayBaseUrl: parsed.gatewayBaseUrl, gatewayAuthMode: parsed.gatewayAuthMode, ...(parsed.cwd !== undefined ? { cwd: parsed.cwd } : {}), ...(parsed.skillsRoot !== undefined ? { skillsRoot: parsed.skillsRoot } : {}), ...(parsed.allowedSkillScripts.length > 0 ? { allowedSkillScripts: parsed.allowedSkillScripts } : {}), skillScriptExecutionTarget: parsed.skillScriptExecutionTarget, ...(parsed.browserAccess !== undefined ? { browserAccess: parsed.browserAccess } : {}), cfcEnforcementModeOverride: parsed.cfcEnforcementModeOverride, ...(runManifest !== undefined ? { runManifest } : {}), ...(parsed.runManifestPath !== undefined ? { runManifestPath: parsed.runManifestPath } : {}), ...(additionalMounts.length > 0 ? { additionalMounts } : {}), }); activateEngine(engine); const loop = createPromptLoop({ engine, workspaceHostPath: parsed.workspace, artifactRoot: parsed.artifactRoot, model: parsed.model, gatewayBaseUrl: parsed.gatewayBaseUrl, gatewayAuthMode: parsed.gatewayAuthMode, ...(parsed.cwd !== undefined ? { cwd: parsed.cwd } : {}), ...(parsed.skillsRoot !== undefined ? { skillsRoot: parsed.skillsRoot } : {}), ...(parsed.allowedSkillScripts.length > 0 ? { allowedSkillScripts: parsed.allowedSkillScripts } : {}), skillScriptExecutionTarget: parsed.skillScriptExecutionTarget, apiKey: parsed.apiKey, apiKeySource: parsed.apiKeySource, cfcEnforcementModeOverride: parsed.cfcEnforcementModeOverride, ...(runManifest !== undefined ? { runManifest } : {}), ...(parsed.runManifestPath !== undefined ? { runManifestPath: parsed.runManifestPath } : {}), maxModelTurns: parsed.maxModelTurns, allowedSubagentProfiles: parsed.allowedSubagentProfiles, ...(parsed.browserAccess !== undefined ? { browserAccess: parsed.browserAccess } : {}), ...(parsed.allowedToolIds !== undefined ? { allowedToolIds: parsed.allowedToolIds } : {}), }); const contextMessages = await prepareSkillContextMessages(engine); result = await loop.runPrompt({ prompt: parsed.prompt!, imageAttachments: parsed.imageAttachments, systemPrompt: resolveCfHarnessCliSystemPrompt({ ...parsed, fabricMountPath: parsed.fabricMount !== undefined ? DEFAULT_FABRIC_MOUNT_PATH : undefined, }), contextMessages, model: parsed.model, maxModelTurns: parsed.maxModelTurns, promptSlotBinding, onTranscriptEvent, }); } const durationMs = Date.now() - startedAt; const structuredResultValidation = parsed.structuredResult === undefined ? undefined : await validateCfHarnessStructuredResult({ config: parsed.structuredResult, readTextFile, }); if (parsed.resultJsonPath !== undefined) { await writeTextFile( parsed.resultJsonPath, `${ JSON.stringify( createCfHarnessBatchResult( result, durationMs, structuredResultValidation, ), null, 2, ) }\n`, ); } io.stdout(formatCfHarnessCliResult(result, parsed.outputMode)); if (parsed.printTranscript) { io.stdout(`${JSON.stringify(result.transcript, null, 2)}\n`); } if (structuredResultValidation?.status === "invalid") { io.stderr( `structured result validation failed: ${structuredResultValidation.validation_error}\n`, ); return 1; } return 0; } catch (error) { io.stderr(`${error instanceof Error ? error.message : String(error)}\n`); return 1; } finally { signalCleanup?.(); } };