export type MachinePlatform = "linux" | "macos" | "windows"; export type MachineConnection = "local" | "ssh" | "tailscale"; export interface ManifestPackageSpec { name: string; manager?: "bun" | "brew" | "apt" | "custom"; version?: string; /** Distribution appId (hasna.app.v1 join key), e.g. "open-todos". Defaults to a slug derived from the package name. */ appId?: string; /** CLI bin used to verify installs via ` --version`. Defaults to the unscoped package name. */ bin?: string; /** * Set false for library-only packages without a CLI: skips the * ` --version` verification so rollouts succeed on install exit code * alone (an mcpHealthUrl, when declared, is still checked). */ verify?: boolean; /** Optional MCP health endpoint checked after install/update (expects HTTP 200). */ mcpHealthUrl?: string; /** Optional target-local exact Bun registry delivery contract. */ exactBunRegistry?: ExactBunRegistryDeliveryV1; } export interface ExactBunRegistrySourceRef { provider: "files" | "task-attachment"; ref: string; sha256: string; sizeBytes: number; } export interface ExactBunRegistryDeliveryV1 { schema: "machines.exact_bun_registry.v1"; order: number; mode: "live-global"; source: ExactBunRegistrySourceRef; archiveSha256: string; registryIntegrity: string; secretRefs: ["hasna/npm/live/publish-token", "hasnaxyz/npm/live/publish-token"]; quarantine: { minimumReleaseAge: 604800; exactExclusions: ["@hasnaxyz/infinity", "@hasnaxyz/factory", "@hasna/secrets", "@hasna/events"]; }; probe: { sdkImport: string; cli: { bin: string; args: ["--help"]; }; }; rollback: "byte-preimage"; } export interface FreezeEntry { name: string; reason?: string; frozenAt?: string; until?: string; } export interface ManifestAppSpec { name: string; manager?: "brew" | "cask" | "apt" | "winget" | "custom"; /** Package or executable identity. For legacy custom entries, this is also the install command and command-v probe target. */ packageName?: string; /** Exact shell command executed for a custom app install. Requires probeCommand. */ installCommand?: string; /** Exact shell command used to probe a custom app. Requires installCommand and structured installed/version output. */ probeCommand?: string; /** Exact version required for a custom probe to report installed=true. */ expectedVersion?: string; } export interface ManifestFileSyncSpec { source: string; target: string; mode?: "copy" | "symlink"; } export interface MachineManifest { id: string; /** Legacy machine identities retained during a canonical stationNN re-key. */ aliases?: string[]; friendlyName?: string; updatedAt?: string; hostname?: string; sshAddress?: string; tailscaleName?: string; platform: MachinePlatform; connection?: MachineConnection; workspacePath: string; bunPath?: string; tags?: string[]; metadata?: Record; packages?: ManifestPackageSpec[]; apps?: ManifestAppSpec[]; files?: ManifestFileSyncSpec[]; } export interface FleetManifest { version: 1; generatedAt?: string; /** Fleet-wide desired-state packages applied to every machine; per-machine packages override by name. */ packages?: ManifestPackageSpec[]; /** Supply-chain freeze list; frozen packages are blocked from reconcile installs/updates. */ freeze?: FreezeEntry[]; machines: MachineManifest[]; } export type ManifestSourceKind = "file" | "private-ref"; export interface ManifestSourceRef { kind: ManifestSourceKind; ref: string; backend: string | null; private: boolean; publicSafe: true; } export interface ManifestLoadInfo { source: ManifestSourceRef; loadedFrom: ManifestSourceKind | "default" | "fallback"; fallbackSource?: ManifestSourceRef; warnings: string[]; } export interface AgentHeartbeat { machineId: string; pid: number; status: "online" | "offline"; updatedAt: string; } export interface SetupResult { machineId: string; mode: "plan" | "apply"; planDigest?: string; steps: SetupStep[]; executed: number; } export interface SetupStep { id: string; title: string; command: string; manager: "shell" | "bun" | "brew" | "apt" | "custom"; privileged?: boolean; /** Exact custom status probe bound into the reviewed mutation plan. */ probeCommand?: string; /** Expected custom probe version bound into the reviewed mutation plan. */ expectedVersion?: string; } export interface SyncResult { machineId: string; mode: "plan" | "apply"; planDigest?: string; actions: SyncAction[]; executed: number; } export interface SyncAction { id: string; title: string; command: string; status: "ok" | "missing" | "drifted"; kind: "package" | "file" | "summary"; } export interface MachineDiff { leftMachineId: string; rightMachineId: string; changedFields: string[]; missingPackages: { leftOnly: string[]; rightOnly: string[]; }; missingFiles: { leftOnly: string[]; rightOnly: string[]; }; } export interface FleetStatusMachine { machineId: string; friendlyName?: string | null; displayName?: string; platform?: string; manifestDeclared: boolean; heartbeatStatus: "online" | "offline" | "unknown"; lastHeartbeatAt?: string; updatedAt?: string | null; daemonVersion?: string | null; agentMode?: string | null; storageSyncStatus?: string | null; doctorSummary?: Record | null; privateMetadata?: boolean; } export interface FleetStatus { machineId: string; manifestPath: string; dbPath: string; notificationsPath: string; manifestMachineCount: number; heartbeatCount: number; machines: FleetStatusMachine[]; recentSetupRuns: number; recentSyncRuns: number; warnings?: string[]; } export type NotificationChannelType = "email" | "webhook" | "command"; export interface NotificationChannel { id: string; type: NotificationChannelType; target: string; commandArgs?: string[]; events: string[]; enabled: boolean; } export interface NotificationConfig { version: 1; updatedAt?: string; channels: NotificationChannel[]; } export interface NotificationTestResult { channelId: string; mode: "plan" | "apply"; delivered: boolean; preview: string; detail: string; } export interface InstalledAppStatus { name: string; packageName: string; manager: "bun" | "brew" | "cask" | "apt" | "winget" | "custom"; installed: boolean; version?: string; } export interface AppsStatusResult { machineId: string; source: "local" | "lan" | "tailscale" | "ssh"; apps: InstalledAppStatus[]; } export interface AppsDiffResult extends AppsStatusResult { missing: string[]; installed: string[]; } export interface ExactBunPackageProbe { schema: "machines.bun_package_probe.v1"; package: string; expectedVersion: string; observedVersion: string; installed: boolean; checks: { packageJson: { ok: boolean; version: string; }; registryProvenance: { ok: boolean; integrity: string; lockSource: "registry"; }; sdkImport: { ok: boolean; }; cliHelp: { ok: boolean; bin: string; exitCode: number; }; }; status: "pass" | "fail"; reasonCodes: string[]; } export interface ExactBunRegistryPlanStep { id: string; kind: "bun-registry-exact"; order: number; package: { name: string; version: string; selector: string; bin: string; archiveSha256: string; registryIntegrity: string; }; source: ExactBunRegistrySourceRef; policy: ExactBunRegistryDeliveryV1["quarantine"]; probe: { schema: "machines.bun_package_probe.v1"; sdkImport: string; cliBin: string; cliArgs: ["--help"]; }; rollback: { mode: "byte-preimage"; scope: "target-transaction"; }; } export interface ExactBunAppsPlan { schema: "machines.apps.plan.v2"; machineId: string; platform: "linux" | "macos"; mode: "plan" | "apply"; planDigest?: string; steps: ExactBunRegistryPlanStep[]; executed: number; collateral: { removals: 0; unrelatedUpdates: 0; serviceOperations: 0; configurationWrites: 0; privilegedSteps: 0; otherMachines: 0; }; probes?: ExactBunPackageProbe[]; state?: "COMMITTED" | "ROLLED_BACK" | "ROLLBACK_FAILED"; reasonCodes?: string[]; } export type AppsPlanResult = SetupResult | ExactBunAppsPlan; export interface AppsValidationResult { schema: "machines.apps.validation.v1"; valid: boolean; machineId: string; platform: MachinePlatform | null; packageCount: number; errors: string[]; warnings: string[]; } export interface ExactBunAppsStatusResult { schema: "machines.apps.status.v2"; machineId: string; platform: "linux" | "macos"; source: "local" | "lan" | "tailscale" | "ssh"; packages: ExactBunPackageProbe[]; status: "pass" | "unmanaged"; reasonCodes: string[]; } export interface CliToolStatus { tool: "claude" | "codex" | "gemini"; packageName: string; installed: boolean; version?: string; } export interface ClaudeCliStatusResult { machineId: string; source: "local" | "lan" | "tailscale" | "ssh"; tools: CliToolStatus[]; } export interface ClaudeCliDiffResult extends ClaudeCliStatusResult { missing: string[]; installed: string[]; } export interface NotificationDispatchResult { channelId: string; event: string; delivered: boolean; transport: NotificationChannelType; detail: string; } export interface NotificationDispatchSummary { event: string; message: string; deliveries: NotificationDispatchResult[]; } export interface DoctorCheck { id: string; status: "ok" | "warn" | "fail"; summary: string; detail: string; optional?: boolean; source?: string; data?: Record; remediation?: string[]; } export interface DoctorProbe { attempted: boolean; verified: boolean; source: "local" | "lan" | "tailscale" | "ssh"; exitCode: number; timedOut: boolean; reason: "completed" | "command_failed" | "timed_out" | "incomplete_output"; } export interface DoctorReport { machineId: string; source: "local" | "lan" | "tailscale" | "ssh"; schemaVersion?: 1; generatedAt?: string; probe?: DoctorProbe; manifestSource?: ManifestLoadInfo; manifestPath?: string; dbPath?: string; notificationsPath?: string; checks: DoctorCheck[]; } export interface SelfTestCheck { id: string; status: "ok" | "warn" | "fail"; summary: string; detail: string; } export interface SelfTestCounts { ok: number; warn: number; fail: number; } export interface SelfTestResult { machineId: string; overall: SelfTestCheck["status"]; counts: SelfTestCounts; checks: SelfTestCheck[]; } export interface ClipboardEntry { hash: string; content: string; contentType: "text" | "rich" | "url"; sourceMachine: string; timestamp: string; } export interface ClipboardConfig { version: 1; enabled: boolean; port: number; maxHistory: number; maxSizeBytes: number; skipPatterns: string[]; } export interface ClipboardStatus { running: boolean; pid?: number; port: number; lastSync?: string; historyCount: number; } export interface ClipboardSyncEvent { hash: string; content: string; contentType: "text" | "rich" | "url"; sourceMachine: string; timestamp: string; }