import type { FileContribution } from "@intentic/extension-manifest"; import type { StateFile } from "./state-portability.js"; export interface WorkspaceStateFile extends StateFile { readonly invalidates: readonly string[]; readonly why?: string; readonly versioned?: true; readonly authored?: true; readonly backup?: false; readonly outsideWriter?: string; } declare const STATE_FILES: readonly [{ readonly path: ".intentic/config/capabilities.json"; readonly invalidates: readonly ["capabilities", "extensions", "environment", "panels", "manifests"]; readonly portability: "carry"; readonly versioned: true; }, { readonly path: ".intentic/config/capability-dismissals.json"; readonly invalidates: readonly ["capabilities"]; readonly portability: "carry"; readonly versioned: true; }, { readonly path: ".intentic/records/secret-uses.json"; readonly invalidates: readonly ["secrets"]; readonly portability: "carry"; }, { readonly path: ".intentic/records/wallet-ledger.json"; readonly invalidates: readonly []; readonly why: "Rendered through the wallet CLI and the capability card's live status probe, not from a browser query key."; readonly portability: "carry"; }, { readonly path: ".intentic/config/personas.json"; readonly invalidates: readonly ["personas", "capabilities", "manifests"]; readonly portability: "carry"; readonly versioned: true; }, { readonly path: ".intentic/config/areas.json"; readonly invalidates: readonly ["areas", "manifests"]; readonly portability: "carry"; readonly versioned: true; }, { readonly path: ".intentic/config/environment.custom.Dockerfile"; readonly invalidates: readonly ["environment"]; readonly portability: "carry"; readonly versioned: true; }, { readonly path: ".intentic/config/environment.Dockerfile"; readonly invalidates: readonly ["environment"]; readonly portability: "carry"; readonly versioned: true; }, { readonly path: ".intentic/config/environment.d/"; readonly invalidates: readonly ["environment"]; readonly portability: "carry"; readonly versioned: true; }, { readonly path: ".intentic/local/environment.approved.Dockerfile"; readonly invalidates: readonly ["environment"]; readonly portability: "derived"; readonly note: "The target composes its own overlay on first boot; rebuild it there to install the tools it names."; }, { readonly path: ".intentic/config/settings.json"; readonly invalidates: readonly ["settings", "manifests"]; readonly portability: "carry"; readonly versioned: true; }, { readonly path: ".intentic/config/safety.md"; readonly invalidates: readonly ["safety-policy"]; readonly portability: "carry"; readonly versioned: true; }, { readonly path: ".intentic/config/home.md"; readonly invalidates: readonly []; readonly portability: "carry"; readonly versioned: true; readonly why: "Read per home turn; no view shows it."; }, { readonly path: ".intentic/local/safety-log.json"; readonly invalidates: readonly ["safety-log"]; readonly portability: "derived"; readonly note: "The target starts its own record of what it decided."; }, { readonly path: ".intentic/local/privacy-log.json"; readonly invalidates: readonly ["privacy-log"]; readonly portability: "derived"; readonly note: "The target starts its own record of what its shield did."; }, { readonly path: ".intentic/config/autostart.json"; readonly invalidates: readonly []; readonly why: "The browser reads what is running off /panels; this file only tells the daemon what to start at boot."; readonly portability: "carry"; readonly versioned: true; }, { readonly path: ".intentic/config/heavy-commands.json"; readonly invalidates: readonly ["settings"]; readonly portability: "carry"; readonly versioned: true; }, { readonly path: ".intentic/config/field-notes.toon"; readonly invalidates: readonly ["settings"]; readonly portability: "carry"; readonly versioned: true; readonly outsideWriter: "the field-notes automation's agent turn (the daemon only reads it, through FIELD_NOTES_FILE)"; }, { readonly path: ".intentic/local/rule-firings.json"; readonly invalidates: readonly ["rule-firings"]; readonly portability: "derived"; readonly note: "Stamps of when each rule last did something; the new sandbox starts its own record."; }, { readonly path: ".intentic/records/runtime-installs.json"; readonly invalidates: readonly ["environment"]; readonly portability: "carry"; }, { readonly path: ".intentic/records/needs.json"; readonly invalidates: readonly ["needs"]; readonly portability: "carry"; }, { readonly path: ".intentic/config/engines.json"; readonly invalidates: readonly ["engines"]; readonly portability: "carry"; readonly versioned: true; }, { readonly path: ".intentic/config/approvals/"; readonly invalidates: readonly ["approvals"]; readonly portability: "carry"; readonly versioned: true; readonly authored: true; }, { readonly path: ".intentic/config/automations.json"; readonly invalidates: readonly []; readonly why: "Declared by the intentic.automations extension's contributes.files, `automations` is its query key, not core's."; readonly portability: "carry"; readonly versioned: true; }, { readonly path: ".intentic/records/automation-runs.json"; readonly invalidates: readonly []; readonly why: "Declared by the intentic.automations extension's contributes.files, `automations` is its query key, not core's."; readonly portability: "carry"; }, { readonly path: ".intentic/records/automation-schedule.json"; readonly invalidates: readonly []; readonly why: "Scheduler bookkeeping nothing in the browser renders: what a catch-up fire produces reaches the run ledger, which carries the automations key."; readonly portability: "carry"; }, { readonly path: ".intentic/records/automation-watch.json"; readonly invalidates: readonly []; readonly why: "Declared by the intentic.automations extension's contributes.files, `automations` is its query key, not core's."; readonly portability: "carry"; }, { readonly path: ".intentic/records/automation-state/"; readonly invalidates: readonly []; readonly why: "A guard's own scratch file; the daemon never reads it and nothing in the browser renders it."; readonly portability: "carry"; }, { readonly path: ".intentic/records/approvals/"; readonly invalidates: readonly []; readonly why: "Where releases before 2026-10-12 kept the wakes automations held for a person; they now sit on the history volume, and nothing reads this copy. The intentic.approvals extension's contributes.files still binds it, with `automation-approvals` as its query key, not core's."; readonly portability: "carry"; }, { readonly path: ".intentic/records/issues/"; readonly invalidates: readonly []; readonly why: "Declared by the intentic.issues extension's contributes.files, `issues` is its query key, not core's."; readonly portability: "carry"; }, { readonly path: ".intentic/records/chores/"; readonly invalidates: readonly []; readonly why: "Declared by the intentic.maintenance extension's contributes.files, `maintenance-report`/`maintenance-runs` are its query keys, not core's."; readonly portability: "carry"; }, { readonly path: ".intentic/config/docs/"; readonly invalidates: readonly []; readonly why: "Declared by the intentic.documentation extension's contributes.files, `documentation`/`documentation-runs` are its query keys, not core's."; readonly portability: "carry"; readonly authored: true; readonly outsideWriter: "the intentic.documentation extension's staging writes (its paths.ts)"; }, { readonly path: ".intentic/config/workflows.json"; readonly invalidates: readonly ["workflows"]; readonly portability: "carry"; readonly versioned: true; }, { readonly path: ".intentic/records/workflow-runs.json"; readonly invalidates: readonly ["workflows", "workflow-runs"]; readonly portability: "carry"; }, { readonly path: ".intentic/config/loop-designs.json"; readonly invalidates: readonly ["loop-designs"]; readonly portability: "carry"; readonly versioned: true; }, { readonly path: ".intentic/records/loops.json"; readonly invalidates: readonly []; readonly why: "Ralph loops and their iteration history. Nothing observes it: where a RUNNING loop stands rides on the fleet roster (AgentSummary.loop), which the /events stream already pushes about once a second, and a second source invalidating on this file could only ever disagree with the card beside it. The iteration list of an ENDED loop is an on-demand read, nothing renders it until someone opens it (web's useLoops, which holds no query for exactly this reason)."; readonly portability: "carry"; }, { readonly path: ".intentic/records/webchat-installs.json"; readonly invalidates: readonly []; readonly why: "Which origins have loaded a Visitor chat's widget, written on a 30s flush timer while a customer's site serves page views. The install panel that renders it fetches on open and polls itself while it is on screen, which is the whole window in which the answer changes for anyone. Pushing instead would bill every connected browser a refetch per flush, for a panel almost nobody has open."; readonly portability: "carry"; }, { readonly path: ".intentic/records/issue-installs.json"; readonly invalidates: readonly []; readonly why: "The same probe for the bug reporter's script, on the same flush timer and read by the same kind of panel, so it is outside the push path for the same reason the Visitor chat's is."; readonly portability: "carry"; }, { readonly path: ".intentic/records/webchat-outbox.json"; readonly invalidates: readonly []; readonly why: "Visitor chat replies a visitor has not collected yet, written when an approved wake answers or a human writes as the agent. The only reader is a stranger's browser polling the public /webchat door, which no query key in this app addresses; the owner's own view of the same words is the conversation's transcript, which the agent registry already pushes."; readonly portability: "carry"; }, { readonly path: ".intentic/records/thread-sessions.json"; readonly invalidates: readonly []; readonly why: "Thread bookkeeping (an inbound thread, a Visitor chat visitor, a Discord or Slack channel, → sandbox conversation + provider session), written on EVERY inbound message. Nothing in the browser reads it: what a thread produces is a conversation, and the fleet board already learns about that from the agent registry's own push. Naming a key here would bill every connected browser a refetch per inbound message, the request storm this table's own note warns about, to refresh nothing it can see."; readonly portability: "carry"; }, { readonly path: ".intentic/records/senders.json"; readonly invalidates: readonly []; readonly why: "Who has written to each listener source, written on every inbound message that reached an automation. Read only while the automation editor's sender picker is open, which fetches it on open; a live key here would refetch every connected browser per Discord message to refresh a list nobody has on screen."; readonly portability: "carry"; }, { readonly path: ".intentic/config/extension-settings.json"; readonly invalidates: readonly []; readonly why: "Held in a module-level shallowRef store per extension (web's extensionSettingsStore) with no query observer, and deliberately so: api.settings.get must answer SYNCHRONOUSLY from an extension's first activate() line, and the store outlives every component scope. A module-level QueryObserver is the one shape that would make invalidation refetch, and this app already ruled it out, it detaches on the queryClient.clear() at logout (see useSandbox's sandbox-list mirror). So a remote member's setting edit reaches this browser on its next load, not live."; readonly portability: "carry"; readonly versioned: true; }, { readonly path: ".intentic/config/extension-enablement.json"; readonly invalidates: readonly ["extensions"]; readonly portability: "carry"; readonly versioned: true; }, { readonly path: ".intentic/config/workspace-extensions/"; readonly invalidates: readonly ["extensions"]; readonly portability: "carry"; readonly versioned: true; readonly authored: true; }, { readonly path: ".intentic/records/extension-updates.json"; readonly invalidates: readonly ["extensions"]; readonly portability: "carry"; }, { readonly path: ".intentic/records/conversions.json"; readonly invalidates: readonly []; readonly why: "Written once per update that converted something, at boot before any browser is connected; the update card reads the plan from the new image instead."; readonly portability: "carry"; }, { readonly path: ".intentic/config/extension-update-policy.json"; readonly invalidates: readonly ["extensions"]; readonly portability: "carry"; readonly versioned: true; }, { readonly path: ".intentic/local/extension-dev.json"; readonly invalidates: readonly ["extensions"]; readonly portability: "derived"; readonly note: "Extensions run their pinned versions on the target; point one at its source checkout again there if you were working on it."; }, { readonly path: ".intentic/records/extension-usage.json"; readonly invalidates: readonly []; readonly why: "Which of the routes each extension DECLARED it has actually called, the evidence behind the permissions list on its row. The one entry here whose empty set is a RATE decision rather than an architectural one: every browser with the app open reports its batch on a timer, so wiring this to the `extensions` query would refetch the whole list every few seconds for a figure nobody is watching change. The tab reads it when it loads, which is when anyone is reading it."; readonly portability: "carry"; }, { readonly path: ".intentic/identity/members.json"; readonly invalidates: readonly []; readonly why: "Where releases before 2026-10-06 kept the daemon's enforced roster; it now lives on the history volume (`identity/members.json`), off the workspace every turn writes, and nothing reads this copy. Kept declared, locked and never exported, since it may still hold a pre-move roster a rollback reads."; readonly portability: "identity"; readonly note: "Re-invite collaborators from the Access tab, a grant is the platform's record, and the target enforces its own copy."; }, { readonly path: ".intentic/secrets/auth/"; readonly invalidates: readonly []; readonly why: "AI-provider credentials and runtime homes, plus the capability and extension-settings secret vaults; each account is rendered through owner-gated provider routes."; readonly portability: "secret"; readonly note: "Sign the agent's AI accounts in again on the Agent tab, then re-enter each connection's credential on Capabilities and each extension's secret settings on Extensions, both arrived listed but unauthenticated."; }, { readonly path: ".intentic/records/sessions/claude/"; readonly invalidates: readonly []; readonly why: "Agent session transcripts; nothing derives from watching them, and descending into them would cost a fifth of the watcher."; readonly portability: "carry"; }, { readonly path: ".intentic/records/artifacts/"; readonly invalidates: readonly []; readonly why: "Durable outputs owned by conversations and extension runs: attachments, browser captures, generated images, acceptance reports, workflow step reports, voice transcripts, and loop ledgers."; readonly portability: "carry"; }, { readonly path: ".intentic/records/artifacts/browser/"; readonly invalidates: readonly []; readonly why: "Page snapshots, screenshots and console logs a turn's browser wrote while looking at a site; read back by that turn and by nothing after it."; readonly portability: "carry"; readonly backup: false; }, { readonly path: ".intentic/local/cache/"; readonly invalidates: readonly []; readonly why: "Rebuildable indexes and caches, the iq index and its vector sidecar, the speech models an image does not bake, fileq's derived/ markdown shadows of binary files; ignored by the watcher and recreated from carried workspace content."; readonly portability: "derived"; }, { readonly path: ".intentic/local/runtime/"; readonly invalidates: readonly []; readonly why: "Extension runtime scratch (watermarks, cached short-lived tokens); nothing renders it and gateways re-derive it."; readonly portability: "derived"; readonly outsideWriter: "extensions, through extensionStateDir below"; }, { readonly path: ".intentic/local/tmp/"; readonly invalidates: readonly []; readonly why: "Scratch that agents and tools leave behind (build logs, demo checkouts); nothing reads it after the turn that wrote it. The state janitor empties it at boot."; readonly portability: "derived"; }, { readonly path: ".intentic/local/trash/"; readonly invalidates: readonly []; readonly why: "Entries deleted from the file view, held for a day so Undo can restore them; nothing renders it, and the janitor expires it."; readonly portability: "derived"; }, { readonly path: ".intentic/local/.pnpm-store/"; readonly invalidates: readonly []; readonly why: "pnpm's content-addressable store, auto-created by installs run from under .intentic; the next install rebuilds it."; readonly portability: "derived"; readonly outsideWriter: "pnpm itself, when an install runs from under .intentic"; }, { readonly path: ".intentic/local/newest-run.json"; readonly invalidates: readonly []; readonly why: "The newest daemon version that ever ran this workspace (store/newest-run.ts), a downgrade tripwire, about THIS sandbox the way rule-firings is."; readonly portability: "derived"; readonly note: "The target stamps its own daemon version on first boot."; }, { readonly path: ".intentic/secrets/converting/"; readonly invalidates: readonly []; readonly why: "Pre-images of the files an update's conversions changed; only the boot step reads them, to put a rolled-back version's files back."; readonly portability: "secret"; readonly note: "An export does not carry an update's undo record; the target converts its own files."; }, { readonly path: ".intentic/secrets/ci.json"; readonly invalidates: readonly []; readonly why: "Webhook secret + conclusion memory; the Pipelines view reads it through /ci/runs, not off disk."; readonly portability: "secret"; readonly note: "Re-add the CI webhook on the Pipelines view, its secret is per-sandbox."; }, { readonly path: ".intentic/secrets/doors.json"; readonly invalidates: readonly []; readonly why: "The credentials behind the event webhooks, release gates and bug intakes; each surface reads its own through /automations and /workflows, never off disk."; readonly portability: "secret"; readonly note: "Webhook, gate and intake URLs are minted fresh on the first read here: re-copy each into its caller's secret store."; }, { readonly path: ".intentic/identity/control-tokens.json"; readonly invalidates: readonly []; readonly why: "Where releases before 2026-10-06 kept the hashed control tokens; they now live on the history volume (`identity/control-tokens.json`), and nothing reads this copy."; readonly portability: "identity"; readonly backup: false; readonly note: "Mint fresh control tokens, the old ones authenticate against the source sandbox."; }, { readonly path: ".intentic/identity/owner.json"; readonly invalidates: readonly []; readonly why: "Where releases before 2026-10-06 kept the bound owner; it now lives on the history volume (`identity/owner.json`), and nothing reads this copy."; readonly portability: "identity"; }, { readonly path: ".intentic/identity/workspace.json"; readonly invalidates: readonly []; readonly why: "The workspace identity, read from the /events hello frame rather than as a file."; readonly portability: "identity"; }, { readonly path: ".intentic/identity/passkeys.json"; readonly invalidates: readonly []; readonly why: "Where earlier releases kept the passkeys registered with this sandbox, whether one is required to open it, and the hashes of the owner's recovery codes; they now live on the history volume (`identity/passkeys.json`), off the workspace every turn writes, and nothing reads this copy."; readonly portability: "identity"; readonly note: "Passkeys are bound to the sandbox they were registered with: add them again on the new one from its Access tab."; }, { readonly path: ".intentic/config/templates.json"; readonly invalidates: readonly []; readonly why: "Scaffold templates, read when the scaffold dialog opens."; readonly portability: "carry"; readonly versioned: true; }, { readonly path: ".intentic/local/browser/"; readonly invalidates: readonly []; readonly why: "Browser-login profiles: Chromium rewrites these constantly. Descent-ignored by the watcher outright."; readonly portability: "derived"; readonly note: "Log the agent's browser back into any site it needs, profiles do not travel."; }, { readonly path: ".intentic/local/extensions/"; readonly invalidates: readonly []; readonly why: "Extension checkouts, whole git clones. The `extensions` query is driven by the capability manifest above, not by their contents."; readonly portability: "derived"; readonly note: "Extensions re-clone from the capability manifest on the target's next reconcile."; }, { readonly path: ".intentic/records/plugins/"; readonly invalidates: readonly []; readonly why: "Agent plugin dirs, read by the SDK's loader each turn."; readonly portability: "carry"; }, { readonly path: ".intentic/config/skills/"; readonly invalidates: readonly ["skills"]; readonly portability: "carry"; readonly versioned: true; }, { readonly path: ".intentic/config/personas/"; readonly invalidates: readonly ["personas"]; readonly portability: "carry"; readonly versioned: true; }]; export declare const WORKSPACE_STATE_FILES: readonly WorkspaceStateFile[]; export declare const VERSIONED_STATE_PATHS: readonly string[]; export declare const SEARCHABLE_STATE_PATHS: readonly string[]; export type StateGroup = "config" | "records" | "local" | "identity" | "secrets"; export declare const STATE_GROUP_DIR: Readonly>; export declare const STATE_GROUPS: readonly StateGroup[]; export declare const stateGroupOf: (file: WorkspaceStateFile) => StateGroup; export declare const stateGroupPaths: (group: StateGroup) => readonly string[]; export declare const SHARED_STATE_PATHS: readonly string[]; export declare const BACKED_UP_STATE_PATHS: readonly string[]; export declare const UNBACKED_STATE_PATHS: readonly string[]; export declare const extensionStateDir: (identity: string) => string; export declare const extensionCacheDir: (identity: string) => string; export declare const legacyExtensionStateDir: (name: string) => string; export declare const extensionGatewayUrlFile: (provider: string) => string; export declare const REPORTED_MANIFEST_PATHS: readonly string[]; export declare const REPORTED_VOLUME_FILES: readonly string[]; export declare const isReportedManifest: (relPath: string) => boolean; export declare const LOCKED_STATE_ENTRIES: ReadonlySet; export declare const PLAN_DOCUMENTS_DIR = ".intentic/records/sessions/claude/plans"; export declare const ATTACHMENTS_DIR = ".intentic/records/artifacts/attachments"; export declare const isAttachmentPath: (relPath: string) => boolean; export declare const lockedWorkspaceEntry: (relPath: string) => string | undefined; export declare const isLockedWorkspacePath: (relPath: string) => boolean; export declare const isReviewableLockedPath: (relPath: string) => boolean; export declare const isUnversionedStatePath: (relPath: string) => boolean; export type WorkspaceStatePath = (typeof STATE_FILES)[number]["path"]; export declare const staleQueryKeys: (paths: readonly string[], contributed: readonly FileContribution[]) => readonly string[]; export declare const fileBoundQueryKeys: (contributed: readonly FileContribution[]) => readonly string[]; export {}; //# sourceMappingURL=workspace-state.d.ts.map