/** * Workspace Directory Resolution Utilities * * Shared helpers for resolving workspace directories across commands and hooks. * * Hook resolution priority (PRI-259): PD canonical config → OpenClaw fallback. * PD canonical sources: PD_WORKSPACE_DIR env → OPENCLAW_WORKSPACE env → * principles-disciple.json → ~/.openclaw/workspace default. * OpenClaw fallback: ctx.workspaceDir → api.runtime.agent.resolveAgentWorkspaceDir(). * * WHY PD canonical wins over host runtime workspace (ADR-0023 §2.6.1, PRI-686): * the PD workspace is the single boundary of governance state (.pd/.state/ * .principles/memory/) — splitting it across two directories splits governance * itself. The host's workspace semantics (e.g. OpenClaw 2026.8/9 resolving an * unpinned main agent to /main) describe where a session * RUNS, not which state tree owns governance. */ import type { OpenClawPluginApi, PluginCommandContext } from '../openclaw-sdk.js'; import { type WorkspaceResolutionContext } from '../core/workspace-dir-validation.js'; /** * Resolve workspace directory for command execution. * * Chain (PRI-686, aligned with hook side PRI-259): PD explicit sources * (PD_WORKSPACE_DIR → OPENCLAW_WORKSPACE → principles-disciple.json) → * ctx.workspaceDir → resolveWorkspaceDirFromApi (official OpenClaw API). * * PD explicit sources are owner-declared and intentionally override the live * session context: on OpenClaw 2026.8/9 multi-agent layouts an unpinned agent * entry resolves ctx.workspaceDir to `/`, which * split hook writes (PD canonical) from command reads (agent sub-workspace) * and silently gated every pain candidate with needs_evidence. * * Divergence between PD explicit and ctx.workspaceDir is logged as a warning * — never silent (rc-9). * * CRITICAL: Throws if workspaceDir cannot be resolved. Silent failures are dangerous * because commands might operate on the wrong directory. */ /** Options shared by command-side resolvers (mirrors HookWorkspaceResolutionOptions). */ export interface CommandWorkspaceResolutionOptions { /** Override PD explicit-source resolution — for tests isolating from host config. */ explicitPdResolver?: () => CanonicalWorkspaceResult | null; } export declare function resolveCommandWorkspaceDir(api: OpenClawPluginApi, ctx: { workspaceDir?: string; }, options?: CommandWorkspaceResolutionOptions): string; /** * Resolve workspace directory for plugin command execution. * * Chain (PRI-686, aligned with hook side PRI-259): PD explicit sources * (PD_WORKSPACE_DIR → OPENCLAW_WORKSPACE → principles-disciple.json) → * ctx.workspaceDir (canonical) → ctx.config.workspaceDir (dispatcher fallback) * * Same priority as resolveCommandWorkspaceDir — see its doc comment for the * workspace-split rationale. Divergence is logged, never silent (rc-9). * * CRITICAL: Throws if workspaceDir cannot be resolved. Commands must NEVER silently * fall back to process.cwd() as this masks configuration errors and can corrupt * the wrong workspace. * * @param ctx - Plugin command context (has workspaceDir + config properties) * @param source - Source label for error messages (e.g. 'pain', 'pd-status') * @param logger - Optional logger for divergence warnings (the plugin API logger) */ export declare function resolvePluginCommandWorkspaceDir(ctx: PluginCommandContext, source: string, logger?: { warn?: (msg: string) => void; }, options?: CommandWorkspaceResolutionOptions): string; export type CanonicalWorkspaceSource = 'pd_env' | 'openclaw_env' | 'pd_config' | 'pd_default'; export interface CanonicalWorkspaceResult { workspaceDir: string; source: CanonicalWorkspaceSource; } export declare function resolveCanonicalWorkspaceDir(): CanonicalWorkspaceResult | null; export type HookWorkspaceSource = CanonicalWorkspaceSource | 'openclaw_context' | 'openclaw_api'; export interface HookWorkspaceResolutionSuccess { ok: true; workspaceDir: string; source: HookWorkspaceSource; consistencyWarning?: string; } export interface HookWorkspaceResolutionFailure { ok: false; reason: string; nextAction: string; message: string; } export type HookWorkspaceResolutionResult = HookWorkspaceResolutionSuccess | HookWorkspaceResolutionFailure; export interface HookWorkspaceResolutionOptions { canonicalResolver?: () => CanonicalWorkspaceResult | null; explicitPdResolver?: () => CanonicalWorkspaceResult | null; } export declare function resolveHookWorkspaceDir(ctx: WorkspaceResolutionContext, api: OpenClawPluginApi, source: string, options?: HookWorkspaceResolutionOptions): HookWorkspaceResolutionResult; /** * Resolve workspace directory for tool hook execution (safe version). * Returns undefined instead of throwing if resolution fails. * * PRI-259: Uses PD canonical config as primary source, OpenClaw as fallback. */ export declare function resolveToolHookWorkspaceDirSafe(ctx: WorkspaceResolutionContext, api: OpenClawPluginApi, source: string, options?: HookWorkspaceResolutionOptions): string | undefined; export declare class WorkspaceResolutionError extends Error { readonly reason: string; readonly nextAction: string; constructor(message: string, reason: string, nextAction: string); toJSON(): { ok: false; reason: string; message: string; nextAction: string; }; } export declare function resolveWorkspaceDirForRuntimeV2(ctx: { workspaceDir?: string; }, api: OpenClawPluginApi | undefined, source: string): string;