refactor(claws): extract lifecycle state contracts

This commit is contained in:
Patrick Erichsen
2026-07-20 14:23:57 -07:00
parent d593dc82b9
commit 9f7b652eee
2 changed files with 107 additions and 87 deletions
+92
View File
@@ -0,0 +1,92 @@
import type { PersistedClawCronRef } from "./cron.js";
import type { ClawManagedFileStatus, RemovedWorkspaceFile } from "./lifecycle-delete-support.js";
import type { ClawPackageInspection, ClawPackageRemovalResult } from "./package-remove.js";
import type { PersistedClawInstall } from "./provenance.js";
import type { CLAW_OUTPUT_STABILITY } from "./types.js";
export const CLAW_STATUS_SCHEMA_VERSION = "openclaw.clawStatus.v1" as const;
export const CLAW_REMOVE_PLAN_SCHEMA_VERSION = "openclaw.clawRemovePlan.v1" as const;
export const CLAW_REMOVE_RESULT_SCHEMA_VERSION = "openclaw.clawRemoveResult.v1" as const;
export type ClawStatusRecord = {
install: PersistedClawInstall;
orphaned?: boolean;
agentState: "present" | "modified" | "missing";
workspaceFiles: ClawManagedFileStatus[];
packages: ClawPackageInspection[];
cronJobs: PersistedClawCronRef[];
};
export type ClawStatusResult = {
schemaVersion: typeof CLAW_STATUS_SCHEMA_VERSION;
stability: typeof CLAW_OUTPUT_STABILITY;
target?: string;
records: ClawStatusRecord[];
summary: {
claws: number;
partial: number;
missingAgents: number;
driftedFiles: number;
packageRefs: number;
missingPackages: number;
driftedPackages: number;
incompletePackages: number;
cronRefs: number;
unresolvedCronRefs: number;
};
};
export type ClawRemovePlanAction = {
kind:
| "agent"
| "configBinding"
| "agentAllow"
| "workspace"
| "agentState"
| "sessionIndex"
| "sessionTranscripts"
| "scheduledJob"
| "workspaceFile"
| "packageRef"
| "cronJob"
| "installRecord";
id: string;
action: "remove" | "delete" | "retain" | "release" | "uninstall" | "trash";
target: string;
blocked: boolean;
reason?: string;
details?: Record<string, unknown>;
};
export type ClawRemovePlan = {
schemaVersion: typeof CLAW_REMOVE_PLAN_SCHEMA_VERSION;
stability: typeof CLAW_OUTPUT_STABILITY;
dryRun: true;
mutationAllowed: false;
planIntegrity: string;
target: string;
agentId?: string;
actions: ClawRemovePlanAction[];
blockers: Array<{ code: string; message: string }>;
};
export type RemovedCronJob = {
manifestId: string;
schedulerJobId?: string;
action: "removed" | "error";
message?: string;
};
export type ClawRemoveResult = {
schemaVersion: typeof CLAW_REMOVE_RESULT_SCHEMA_VERSION;
stability: typeof CLAW_OUTPUT_STABILITY;
dryRun: false;
status: "complete" | "partial";
agentId: string;
agentRemoved: boolean;
workspaceFiles: RemovedWorkspaceFile[];
packages: ClawPackageRemovalResult[];
cronJobs: RemovedCronJob[];
packageRefsReleased: number;
error?: { code: string; message: string };
};
+15 -87
View File
@@ -1,4 +1,3 @@
/* oxlint-disable max-lines -- Resource-specific removal helpers split into owner modules in subsequent lifecycle slices. */
import { createHash } from "node:crypto";
import { stableStringify } from "../agents/stable-stringify.js";
import { getRuntimeConfig } from "../config/config.js";
@@ -14,7 +13,6 @@ import {
markClawCronRefRemoved,
readClawCronRefs,
type ClawCronGateway,
type PersistedClawCronRef,
} from "./cron.js";
import {
claimClawAgentConfigRemoval,
@@ -34,17 +32,25 @@ import {
removeClawWorkspaceFile,
synthesizeOrphanInstall,
workspaceContainsUntrackedEntries,
type ClawManagedFileStatus,
type ClawTrashPath,
type RemovedWorkspaceFile,
} from "./lifecycle-delete-support.js";
import {
CLAW_REMOVE_PLAN_SCHEMA_VERSION,
CLAW_REMOVE_RESULT_SCHEMA_VERSION,
CLAW_STATUS_SCHEMA_VERSION,
type ClawRemovePlan,
type ClawRemovePlanAction,
type ClawRemoveResult,
type ClawStatusRecord,
type ClawStatusResult,
type RemovedCronJob,
} from "./lifecycle-state-contract.js";
import { projectClawPackageRemovePlan } from "./package-remove-plan.js";
import {
applyClawPackageRemovals,
inspectClawPackage,
planClawPackageRemovals,
type ClawPackageInspection,
type ClawPackageRemovalResult,
type ClawReferencedCleanup,
type PackageRemovalDeps,
} from "./package-remove.js";
@@ -52,93 +58,15 @@ import {
readClawInstallRecords,
readClawPackageRefs,
updateClawInstallRecordStatus,
type PersistedClawInstall,
} from "./provenance.js";
import { CLAW_OUTPUT_STABILITY } from "./types.js";
import { readClawWorkspaceFiles } from "./workspace.js";
export { ClawRemoveError } from "./lifecycle-delete-support.js";
const CLAW_STATUS_SCHEMA_VERSION = "openclaw.clawStatus.v1" as const;
export const CLAW_REMOVE_PLAN_SCHEMA_VERSION = "openclaw.clawRemovePlan.v1" as const;
export const CLAW_REMOVE_RESULT_SCHEMA_VERSION = "openclaw.clawRemoveResult.v1" as const;
type ClawStatusRecord = {
install: PersistedClawInstall;
orphaned?: boolean;
agentState: "present" | "modified" | "missing";
workspaceFiles: ClawManagedFileStatus[];
packages: ClawPackageInspection[];
cronJobs: PersistedClawCronRef[];
};
type ClawStatusResult = {
schemaVersion: typeof CLAW_STATUS_SCHEMA_VERSION;
stability: typeof CLAW_OUTPUT_STABILITY;
target?: string;
records: ClawStatusRecord[];
summary: {
claws: number;
partial: number;
missingAgents: number;
driftedFiles: number;
packageRefs: number;
missingPackages: number;
driftedPackages: number;
incompletePackages: number;
cronRefs: number;
unresolvedCronRefs: number;
};
};
type ClawRemovePlanAction = {
kind:
| "agent"
| "configBinding"
| "agentAllow"
| "workspace"
| "agentState"
| "sessionIndex"
| "sessionTranscripts"
| "scheduledJob"
| "workspaceFile"
| "packageRef"
| "cronJob"
| "installRecord";
id: string;
action: "remove" | "delete" | "retain" | "release" | "uninstall" | "trash";
target: string;
blocked: boolean;
reason?: string;
details?: Record<string, unknown>;
};
type ClawRemovePlan = {
schemaVersion: typeof CLAW_REMOVE_PLAN_SCHEMA_VERSION;
stability: typeof CLAW_OUTPUT_STABILITY;
dryRun: true;
mutationAllowed: false;
planIntegrity: string;
target: string;
agentId?: string;
actions: ClawRemovePlanAction[];
blockers: Array<{ code: string; message: string }>;
};
type RemovedCronJob = {
manifestId: string;
schedulerJobId?: string;
action: "removed" | "error";
message?: string;
};
type ClawRemoveResult = {
schemaVersion: typeof CLAW_REMOVE_RESULT_SCHEMA_VERSION;
stability: typeof CLAW_OUTPUT_STABILITY;
dryRun: false;
status: "complete" | "partial";
agentId: string;
agentRemoved: boolean;
workspaceFiles: RemovedWorkspaceFile[];
packages: ClawPackageRemovalResult[];
cronJobs: RemovedCronJob[];
packageRefsReleased: number;
error?: { code: string; message: string };
};
export {
CLAW_REMOVE_PLAN_SCHEMA_VERSION,
CLAW_REMOVE_RESULT_SCHEMA_VERSION,
} from "./lifecycle-state-contract.js";
export async function readClawStatus(
target?: string,