One profile: the whole permission document a session runs under.
A session is created from exactly one of these, and it is the only
place permissions are written. There is no workspace-wide block and
no mount-owned block above it, so reading this object is reading
everything the profile may do; what a profile does not say, it does not
restrict. Configuration, not enforcement: the resolver compiles it
onto the session's narrowing fields and the entry points keep enforcing.
Deliberately not named a View, which per the view convention is a
handle an agent holds on one entry point, while a profile is what the
embedder uses to define one. Frozen so two agents with the same
profile share one object and neither can bend the other's view.
Two rules decide a line against it, and they are the whole law.
A rule naming no path is read by verb (deny before ask before
allow), wherever it is written. A rule carrying paths, and every
hide, is read by anchor depth: the deeper entry wins, ties break by
verb.
A profile may also state a policy: for each pre_ method it
answers at (pre_execute, pre_command, pre_vfs,
pre_session), a list of programs, each with the runtime it runs
on (ProfilePolicy, the shape a clis entry has). A program's
function for the method takes its context and returns its answer:
None for no opinion, a deny, an ask, or at pre_execute a route.
They are asked in order and the first deny wins, so a policy expresses
the conditions a declarative rule cannot; like every policy, it can
only restrict, never grant past a deny. The document is optional
beside it: a profile stating only a policy hides nothing, and the
policy is its whole admission policy.
Args:
cwd (str | None): the session's working directory at creation.
env (dict[str, str | EnvVar] | None): the env entries seeded
into the session at creation, in the workspace env
grammar: a bare string is an exported literal, and a
from: entry a managed pointer, so a credential is
named here and fetched, never written as its value.
mounts (dict[str, ProfileMount] | None): per-mount settings,
keyed by prefix: a mode, ask and deny rules for lines
working inside the mount, and hides under it. A mount the
mapping omits keeps its own mode and gains no rules.
paths (PathsBlock | None): the profile's hides, absolute.
vars (VarsBlock | None): the profile's hidden variables.
commands (CommandsBlock | None): the profile's allow list and its
ask / deny rules, absolute paths.
policy (dict[ScriptMethod, list[ProfilePolicy]] | None): the
profile's policy: each pre_ method's programs, asked in
order.
network (bool | dict[str, list[str]] | None): where the
session's lines may connect, the workspace's network
grammar, held besides the workspace's own; None leaves the
workspace's alone.
paths: of a profile, or of one of its mount sections.
hide entries use the document's one grammar: an entry with
*, ? or [ is a pattern, anything else an exact path
and its subtree (utils/hidden.classify_paths); every entry
holds a token and is absolute or a name pattern, wherever the block
is written. A hide entry may also be a group
{patterns: [...], reason: ...}: the patterns join the flat list
like any other entry and the reason lands in reasons, the
operator-only side table (:class:HideReason).
show is the other half of the path axis: a mapping of path to
mode ({"/repo/docs": r}), or a plain list whose entries inherit
the mount's mode. Every entry is absolute, a subtree or an anchored
pattern, because a show anchors to a place and a name pattern names
none. An entry re-opens its subtree inside a hidden region when its
anchor is deeper than the hide's, and states the mode in force
below its anchor when it carries one; both on the one anchor-depth
rule.
Args:
hide (tuple[str, ...]): what the profile makes nonexistent.
show (tuple[ShowEntry, ...]): the profile's show entries, in
document order.
reasons (tuple[HideReason, ...]): why grouped hide entries
exist, for the operator's entry points only.
allow lists the command patterns the profile allows; a line no
pattern covers is refused, <cmd>: Permission denied at 126, like
any other rule's Deny. Shell builtins are subjects like everything
else: a list stating only cat refuses echo and cd. The agent's
own functions are the one exemption, safe because every line of a
body passes the gate itself. ask rules are admitted only with a
host approval; deny rules refuse with a reason. A bare string in
either is one command pattern with the default reason.
Args:
allow (tuple[str, ...] | None): the profile's allow patterns;
None (unstated) allows everything.
ask (tuple[CommandRule, ...]): what needs sign-off, in order.
deny (tuple[CommandRule, ...]): the profile's refusals, in order.
How far past its own session a profile reaches into processes.
A session always sees and stops its own processes. list widens
what ps and a handler's process view see; kill widens what
they may stop, and never past list. max caps the live
processes the session holds, its running line included, as
ulimit -u counts the shell. A bare scope sets both. The workspace
states one for every session and a profile's overrides it field by
field (layered).
Args:
list (ProcessScope): whose processes the session sees.
kill (ProcessScope): whose processes the session may stop.
max (int | None): most live processes, MAX_PROCESSES unless
stated, None for no cap.
{"docsConfig":{"theme":"mint","$schema":"https://mintlify.com/docs.json","name":"Mirage","description":"Mirage gives AI agents one virtual filesystem for S3, Google Drive, Slack, GitHub, Notion, Postgres, and SSH, so shell commands work across services.","colors":{"primary":"#0C0C0C","light":"#FAFAFA","dark":"#000000"},"logo":{"light":"https://mintcdn.com/struktoai/7G-pGKhPIqaKqOXr/logo/light.svg?fit=max\u0026auto=format\u0026n=7G-pGKhPIqaKqOXr\u0026q=85\u0026s=d7007be7b5588a72b2072d2c33791785","dark":"https://mintcdn.com/struktoai/7G-pGKhPIqaKqOXr/logo/dark.svg?fit=max\u0026auto=format\u0026n=7G-pGKhPIqaKqOXr\u0026q=85\u0026s=0a255f925beb7370a41145f3f9185e9d"},"favicon":"https://mintcdn.com/struktoai/F9Lv_nTaj6By6crk/favicon.svg?fit=max\u0026auto=format\u0026n=F9Lv_nTaj6By6crk\u0026q=85\u0026s=bbca6fb54e64d72bdda46fb667828f1f","api":{"playground":{"display":"none"}},"navbar":{"links":[{"icon":"globe","href":"https://www.strukto.ai/mirage","label":"mirage"},{"icon":"discord","href":"https://discord.gg/u8BPQ65KsS","label":""},{"icon":"x-twitter","href":"https://x.com/struktoai","label":""},{"icon":"github","href":"https://github.com/strukto-ai/mirage","label":"strukto-ai/mirage"}]},"footer":{"socials":{"github":"https://github.com/strukto-ai/mirage"}},"seo":{"metatags":{"keywords":"Mirage, filesystem for AI agents, virtual filesystem, AI agent tools, agent infrastructure, MCP alternative, bash for agents, S3 filesystem, Google Drive filesystem, Slack filesystem, GitHub filesystem, agent sandbox, Strukto","author":"Strukto","robots":"index, follow","googlebot":"index, follow","canonical":"https://docs.mirage.strukto.ai","theme-color":"#0C0C0C","color-scheme":"light dark","language":"en","category":"Technology","target":"developers","apple-mobile-web-app-capable":"yes","apple-mobile-web-app-status-bar-style":"black-translucent","og:type":"website","og:url":"https://docs.mirage.strukto.ai","og:image":"https://raw.githubusercontent.com/strukto-ai/mirage/main/assets/mirage-og-light@2x.png","og:image:alt":"Mirage: a virtual terminal for AI agents","og:site_name":"Mirage","og:locale":"en_US","twitter:card":"summary_large_image","twitter:site":"@struktoai","twitter:creator":"@struktoai","twitter:image":"https://raw.githubusercontent.com/strukto-ai/mirage/main/assets/mirage-og-light@2x.png","twitter:image:alt":"Mirage · A Virtual Terminal for AI Agents | Strukto"}},"contextual":{"options":["copy","view","chatgpt","claude","perplexity","mcp","cursor","vscode"],"display":"header"},"styling":{"latex":false},"navigation":{"pages":[]}},"deployment":{"deploymentMetadataValue":{"subdomain":"struktoai","hasAudioNarration":false,"actualSubdomain":"struktoai","customDomains":["docs.mirage.strukto.ai"],"gitSource":{"type":"github","owner":"strukto-ai","repo":"mirage","deployBranch":"main","contentDirectory":"docs","isPrivate":true,"mountPath":"","label":""},"chroma":{"liveDeploymentHistoryId":"6aecc113b20fc35bf671c161","collectionId":"c7fe3e69-889e-47b8-b169-a31692320da7","schemaVersion":"v3","latestBuiltDeploymentHistoryId":"6aecc113b20fc35bf671c161"},"entitlements":{},"buildId":"6aee565bda8ce456c16389fb","clientVersion":"0.0.4076","searchFilterCounts":[{"language":"default","tag":"VFS","count":198},{"language":"default","tag":"Home","count":134},{"language":"default","tag":"API","count":98},{"language":"default","tag":"Operations","count":96},{"language":"default","tag":"TS","count":95},{"language":"default","tag":"Python","count":91},{"language":"default","tag":"CLIs","count":79},{"language":"default","tag":"Object Storage","count":48},{"language":"default","tag":"Cloud \u0026 Productivity","count":35},{"language":"default","tag":"Data \u0026 AI","count":33}]},"assistantConfig":{"enableAskAiButton":false,"enableStarterQuestions":false,"enableContextualStarterQuestions":false,"enableAskAiSearchBar":true},"basePath":"","hasChatPermissions":false,"hasWebMcpPermissions":false,"toggles":[{"name":"kill-isr","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"agent-mintlify-slack","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"agent-integrations-settings","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"rbac-expansion","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automations-pr-grouping","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"custom-prefix","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"analytics-v7","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"user-flows-analytics","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"no-publish-flow","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-onboarding","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"llms-txt-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"snapshot-serving-live","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"stripTemperatureMiddleware","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"support-platform-pylon-zendesk","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"snapshot-serving","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"instant-rollback","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"granular-notifications-server","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"granular-notifications","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automations-fable","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"fixed-ai-action-pricing","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automation-resolve-merge-conflict","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"scoped-publishing","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"mintql","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"page-level-analytics","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"editor-version-history-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"billing-page-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"full-page-search","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workspace-projects","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"assistant-v5","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"fork-pr-previews","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"revalidation-jwt","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-sso-scim","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"hobby-abuse-scan","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"dashboard-inbox","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-signup","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"turbopuffer-dual-write","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-enabled","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"approve-review-flow","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"editor-metadata","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"sso-setup-deadline-banner","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"turbopuffer-serve","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"live-agents","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"comment-mode","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false}],"googleFontsInlined":false},"customCss":[],"page":{"pagePath":"api/operations/workspaces/set-a-profile","slug":"/api/operations/workspaces/set-a-profile","pageMetadata":{"title":"Set a profile","description":"Define a named profile on the live workspace, or replace it.\n\nOnly the live table changes: a session moves when it is updated\nonto the name, and the workspace's config is never rewritten.","deprecated":null,"version":null,"openapi":"/openapi.yaml put /v1/workspaces/{workspace_id}/profiles/{name}","href":"/api/operations/workspaces/set-a-profile","autogeneratedByOpenApi":true},"description":{"compiledSource":"\"use strict\";\nconst {Fragment: _Fragment, jsx: _jsx, jsxs: _jsxs} = arguments[0];\nconst {useMDXComponents: _provideComponents} = arguments[0];\nfunction _createMdxContent(props) {\n const _components = {\n p: \"p\",\n ..._provideComponents(),\n ...props.components\n };\n return _jsxs(_Fragment, {\n children: [_jsx(_components.p, {\n children: \"Define a named profile on the live workspace, or replace it.\"\n }), \"\\n\", _jsx(_components.p, {\n children: \"Only the live table changes: a session moves when it is updated\\nonto the name, and the workspace’s config is never rewritten.\"\n })]\n });\n}\nfunction MDXContent(props = {}) {\n const {wrapper: MDXLayout} = {\n ..._provideComponents(),\n ...props.components\n };\n return MDXLayout ? _jsx(MDXLayout, {\n ...props,\n children: _jsx(_createMdxContent, {\n ...props\n })\n }) : _createMdxContent(props);\n}\nreturn {\n default: MDXContent\n};\n","frontmatter":{},"scope":{}},"pageType":"default","mdx":{"mdxSource":{"compiledSource":"\"use strict\";const{Fragment:_Fragment,jsx:_jsx}=arguments[0];const{useMDXComponents:_provideComponents}=arguments[0];function _createMdxContent(props){return _jsx(_Fragment,{})}function MDXContent(props={}){const{wrapper:MDXLayout}={..._provideComponents(),...props.components};return MDXLayout?_jsx(MDXLayout,{...props,children:_jsx(_createMdxContent,{...props})}):_createMdxContent(props)}return{default:MDXContent}","frontmatter":{},"scope":{"config":{},"pageMetadata":{"title":"Set a profile","description":"Define a named profile on the live workspace, or replace it.\n\nOnly the live table changes: a session moves when it is updated\nonto the name, and the workspace's config is never rewritten.","deprecated":null,"version":null,"openapi":"/openapi.yaml put /v1/workspaces/{workspace_id}/profiles/{name}","href":"/api/operations/workspaces/set-a-profile","autogeneratedByOpenApi":true}}},"mdxSourceWithNoJs":null},"mdxExtracts":{"tableOfContents":[],"codeExamples":{}},"jsLinks":[],"openApiReferenceData":{"operation":{"summary":"Set a profile","operationId":"set_profile_v1_workspaces__workspace_id__profiles__name__put","parameters":["c2072c7e-d27a-466a-beba-286f2ff1cd83","e24c6c69-8f33-47e9-bd8a-f8b64546e137"],"requestBody":"c9ab5ddb-9218-4fd1-b3b5-1e8f391f813b","responses":{"200":"bfbe343b-969a-47ad-98ad-1066bb911220","401":"55e22732-920a-4890-8ae5-43d26da67616","404":"6d6cb91d-ce1b-45b4-a242-ce498f9bd5bf","422":"59aed612-c15b-4dae-9122-d7e0cb79efb5","429":"598e4251-8e69-44fc-8a89-9266d5838cb8"},"description":"Define a named profile on the live workspace, or replace it.\n\nOnly the live table changes: a session moves when it is updated\nonto the name, and the workspace's config is never rewritten.","tags":["Workspaces"],"x-hosts":["daemon"],"method":"put","type":"path","servers":["5b646690-c8a6-470b-9b36-ade1de13789b"],"security":["4159ccc1-3afa-4800-8ae3-f86840818ec3"],"path":"/v1/workspaces/{workspace_id}/profiles/{name}","baseUrlOptions":["http://127.0.0.1:8765"],"title":"Set a profile","codeSamples":[],"requiredOnlyExamples":false,"requestExampleType":"generated","responseExampleType":"generated"},"dependencies":{"parameters":{"c2072c7e-d27a-466a-beba-286f2ff1cd83":{"name":"workspace_id","in":"path","required":true,"description":"The workspace's id.","schema":{"type":"string","isRequired":true,"description":"The workspace's id.","uniqueKey":"","typeLabel":"string"}},"e24c6c69-8f33-47e9-bd8a-f8b64546e137":{"name":"name","in":"path","required":true,"schema":{"type":"string","isRequired":true,"uniqueKey":"","typeLabel":"string"}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"properties":{"cwd":{"oneOf":[{"type":"string","title":"Cwd","uniqueKey":"cwd.oneOf.0","typeLabel":"string"},{"type":"null","title":"Cwd","uniqueKey":"cwd.oneOf.1","typeLabel":"null"}],"uniqueKey":"cwd","typeLabel":"string | null"},"env":{"oneOf":[{"type":"object","title":"Env","additionalProperties":{"oneOf":[{"type":"string","uniqueKey":"env.oneOf.0.additionalProperties.oneOf.0","typeLabel":"string"},{"type":"object","title":"EnvVar","description":"One entry of the env map: a literal value or a managed pointer.\n\nThe env block is one map, name -> entry. A bare string in the map\nis the literal short form and never reaches this model; a dict is\nvalidated through it. `value` and `from` are mutually exclusive and\none is required: `export` belongs to a literal entry, `ref`/`key`/\n`fetch` to a managed one, and `readonly` to either.\n\nArgs:\n value (str | None): the literal text; set = a literal entry.\n readonly (bool): compiles to `VarAttr.READONLY`, so the agent\n cannot assign to the name or unset it. Legal on a managed\n entry too, and the point of one: the fetch writes the\n record itself rather than going through the shell's\n assignment gate, so mirage still fills a readonly\n credential while a line that tries to overwrite it is\n refused.\n export (bool): literal-only knob (default on); a managed entry\n is always exported.\n provider (str | None): registered source name; set = a managed\n entry. Spelled `from:` in YAML (python keyword), via alias.\n ref (str): the source's address for the secret.\n key (str | None): which secret field to read; default the\n variable's own name.\n fetch (Literal[\"lazy\", \"eager\"]): eager joins every line's\n fetch set instead of waiting for a reference.","properties":{"value":{"oneOf":[{"type":"string","title":"Value","uniqueKey":"env.oneOf.0.additionalProperties.oneOf.1.value.oneOf.0","typeLabel":"string"},{"type":"null","title":"Value","uniqueKey":"env.oneOf.0.additionalProperties.oneOf.1.value.oneOf.1","typeLabel":"null"}],"uniqueKey":"env.oneOf.0.additionalProperties.oneOf.1.value","typeLabel":"string | null"},"readonly":{"type":"boolean","title":"Readonly","default":false,"uniqueKey":"env.oneOf.0.additionalProperties.oneOf.1.readonly","typeLabel":"boolean"},"export":{"type":"boolean","title":"Export","default":true,"uniqueKey":"env.oneOf.0.additionalProperties.oneOf.1.export","typeLabel":"boolean"},"from":{"oneOf":[{"type":"string","title":"From","uniqueKey":"env.oneOf.0.additionalProperties.oneOf.1.from.oneOf.0","typeLabel":"string"},{"type":"null","title":"From","uniqueKey":"env.oneOf.0.additionalProperties.oneOf.1.from.oneOf.1","typeLabel":"null"}],"uniqueKey":"env.oneOf.0.additionalProperties.oneOf.1.from","typeLabel":"string | null"},"ref":{"type":"string","title":"Ref","default":"","uniqueKey":"env.oneOf.0.additionalProperties.oneOf.1.ref","typeLabel":"string"},"key":{"oneOf":[{"type":"string","title":"Key","uniqueKey":"env.oneOf.0.additionalProperties.oneOf.1.key.oneOf.0","typeLabel":"string"},{"type":"null","title":"Key","uniqueKey":"env.oneOf.0.additionalProperties.oneOf.1.key.oneOf.1","typeLabel":"null"}],"uniqueKey":"env.oneOf.0.additionalProperties.oneOf.1.key","typeLabel":"string | null"},"fetch":{"type":"string","enum":["lazy","eager"],"title":"Fetch","default":"lazy","uniqueKey":"env.oneOf.0.additionalProperties.oneOf.1.fetch","typeLabel":"enum\u003cstring>"}},"additionalProperties":false,"uniqueKey":"env.oneOf.0.additionalProperties.oneOf.1","typeLabel":"EnvVar · object"}],"uniqueKey":"env.oneOf.0.additionalProperties","typeLabel":"string | EnvVar · object"},"uniqueKey":"env.oneOf.0","typeLabel":"Env · object"},{"type":"null","title":"Env","uniqueKey":"env.oneOf.1","typeLabel":"null"}],"uniqueKey":"env","typeLabel":"Env · object | null"},"mounts":{"oneOf":[{"type":"object","title":"Mounts","additionalProperties":{"properties":{"mode":{"oneOf":[{"type":"string","title":"MountMode","description":"What a mount lets commands do, a cumulative ladder.\n\nREAD lists and reads. WRITE also creates, changes and deletes. EXEC\nalso lets the interpreter commands (python3, js) run code: a script\nfile named as their operand must sit on an EXEC mount, while inline\ncode and -m need one somewhere in the workspace (imports are not\nchecked by path). Shell scripts need no EXEC, since the shell checks\neach of their commands like a typed one; a ./script whose shebang\nnames python3 reaches python3, which does check.","enum":["read","write","exec"],"uniqueKey":"mounts.oneOf.0.additionalProperties.mode.oneOf.0","typeLabel":"enum\u003cstring>"},{"type":"null","uniqueKey":"mounts.oneOf.0.additionalProperties.mode.oneOf.1","typeLabel":"null"}],"uniqueKey":"mounts.oneOf.0.additionalProperties.mode","typeLabel":"enum\u003cstring> | null"},"commands":{"oneOf":[{"type":"object","title":"MountCommandsBlock","description":"``commands:`` of one mount section: ``ask`` and ``deny`` only.\n\nA mount rule applies to a line that works inside the mount (its cwd\nor one of its paths lies under the root); its ``paths`` are\nabsolute, like every other path in the document, and must name\nsomething under that root. There is no ``allow`` here: what a\nsession can see is a property of the session, and an operand cannot\nmake a command \"not found\".\n\nArgs:\n ask (tuple[CommandRule, ...]): what needs sign-off here.\n deny (tuple[CommandRule, ...]): what is refused here.","properties":{"ask":{"items":{"properties":{"reason":{"type":"string","title":"Reason","isRequired":true,"uniqueKey":"mounts.oneOf.0.additionalProperties.commands.oneOf.0.ask.items.[INDEX].reason","typeLabel":"string"},"commands":{"items":{"type":"string","uniqueKey":"mounts.oneOf.0.additionalProperties.commands.oneOf.0.ask.items.[INDEX].commands.items.[INDEX]","typeLabel":"string"},"type":"array","title":"Commands","default":[],"uniqueKey":"mounts.oneOf.0.additionalProperties.commands.oneOf.0.ask.items.[INDEX].commands","typeLabel":"string[]"},"paths":{"items":{"type":"string","uniqueKey":"mounts.oneOf.0.additionalProperties.commands.oneOf.0.ask.items.[INDEX].paths.items.[INDEX]","typeLabel":"string"},"type":"array","title":"Paths","default":[],"uniqueKey":"mounts.oneOf.0.additionalProperties.commands.oneOf.0.ask.items.[INDEX].paths","typeLabel":"string[]"},"mount":{"type":"string","title":"Mount","default":"","uniqueKey":"mounts.oneOf.0.additionalProperties.commands.oneOf.0.ask.items.[INDEX].mount","typeLabel":"string"}},"additionalProperties":false,"type":"object","required":["reason"],"title":"CommandRule","description":"One admission rule of the permissions document: refuse (or ask\nabout) matching commands, on matching paths when it names any.\n\nIt is the compiled element of ``commands.deny`` and ``commands.ask``\nwherever the profile writes one, and reaches the workspace only inside\nthat document; ``PermissionsPolicy`` is what evaluates it. The\ndocument writes a rule in one of three shapes, and each compiles to\nrules of this class: a list of command patterns (a whole-line rule\non each, no paths), a mapping of command pattern to its paths (one\ncommand to many paths, one rule per command, so a path is never\nstated beside a command it was not meant for), or paths alone (a\nrule on every command, at the dispatcher too). A command entry is a\ntoken-prefix pattern over the line as the entry point normalizes it (``rm``\nis every rm line, ``git push`` every ``git push ...``, a ``*`` token\nany one token). Path entries use the document's one grammar: an\nentry with ``*``, ``?`` or ``[`` is a pattern (repo fnmatch dialect,\n``*`` crossing ``/``, a slashless pattern matching any name\ncomponent), anything else is an exact path and its subtree. Every\nentry is absolute or a name pattern, holds a token (a blank one\nwould be the root), and inside a mount section must name something\nunder that mount root.\n\nArgs:\n reason (str): why the command is refused, carried on the\n result's refusal record.\n commands (tuple[str, ...]): command patterns the rule applies\n to; empty means every command. A path-scoped rule carries\n exactly one.\n paths (tuple[str, ...]): path entries; empty refuses the\n command regardless of its operands.\n mount (str): set by the compiler for a rule written under a\n ``mounts.\u003cprefix>`` section, the mount root it is scoped to:\n it applies only to a line whose cwd or paths lie under it.\n Empty for a rule written at the top level; never typed in\n the document.","uniqueKey":"mounts.oneOf.0.additionalProperties.commands.oneOf.0.ask.items.[INDEX]","typeLabel":"CommandRule · object"},"type":"array","title":"Ask","default":[],"uniqueKey":"mounts.oneOf.0.additionalProperties.commands.oneOf.0.ask","typeLabel":"CommandRule · object[]"},"deny":{"items":{"properties":{"reason":{"type":"string","title":"Reason","isRequired":true,"uniqueKey":"mounts.oneOf.0.additionalProperties.commands.oneOf.0.deny.items.[INDEX].reason","typeLabel":"string"},"commands":{"items":{"type":"string","uniqueKey":"mounts.oneOf.0.additionalProperties.commands.oneOf.0.deny.items.[INDEX].commands.items.[INDEX]","typeLabel":"string"},"type":"array","title":"Commands","default":[],"uniqueKey":"mounts.oneOf.0.additionalProperties.commands.oneOf.0.deny.items.[INDEX].commands","typeLabel":"string[]"},"paths":{"items":{"type":"string","uniqueKey":"mounts.oneOf.0.additionalProperties.commands.oneOf.0.deny.items.[INDEX].paths.items.[INDEX]","typeLabel":"string"},"type":"array","title":"Paths","default":[],"uniqueKey":"mounts.oneOf.0.additionalProperties.commands.oneOf.0.deny.items.[INDEX].paths","typeLabel":"string[]"},"mount":{"type":"string","title":"Mount","default":"","uniqueKey":"mounts.oneOf.0.additionalProperties.commands.oneOf.0.deny.items.[INDEX].mount","typeLabel":"string"}},"additionalProperties":false,"type":"object","required":["reason"],"title":"CommandRule","description":"One admission rule of the permissions document: refuse (or ask\nabout) matching commands, on matching paths when it names any.\n\nIt is the compiled element of ``commands.deny`` and ``commands.ask``\nwherever the profile writes one, and reaches the workspace only inside\nthat document; ``PermissionsPolicy`` is what evaluates it. The\ndocument writes a rule in one of three shapes, and each compiles to\nrules of this class: a list of command patterns (a whole-line rule\non each, no paths), a mapping of command pattern to its paths (one\ncommand to many paths, one rule per command, so a path is never\nstated beside a command it was not meant for), or paths alone (a\nrule on every command, at the dispatcher too). A command entry is a\ntoken-prefix pattern over the line as the entry point normalizes it (``rm``\nis every rm line, ``git push`` every ``git push ...``, a ``*`` token\nany one token). Path entries use the document's one grammar: an\nentry with ``*``, ``?`` or ``[`` is a pattern (repo fnmatch dialect,\n``*`` crossing ``/``, a slashless pattern matching any name\ncomponent), anything else is an exact path and its subtree. Every\nentry is absolute or a name pattern, holds a token (a blank one\nwould be the root), and inside a mount section must name something\nunder that mount root.\n\nArgs:\n reason (str): why the command is refused, carried on the\n result's refusal record.\n commands (tuple[str, ...]): command patterns the rule applies\n to; empty means every command. A path-scoped rule carries\n exactly one.\n paths (tuple[str, ...]): path entries; empty refuses the\n command regardless of its operands.\n mount (str): set by the compiler for a rule written under a\n ``mounts.\u003cprefix>`` section, the mount root it is scoped to:\n it applies only to a line whose cwd or paths lie under it.\n Empty for a rule written at the top level; never typed in\n the document.","uniqueKey":"mounts.oneOf.0.additionalProperties.commands.oneOf.0.deny.items.[INDEX]","typeLabel":"CommandRule · object"},"type":"array","title":"Deny","default":[],"uniqueKey":"mounts.oneOf.0.additionalProperties.commands.oneOf.0.deny","typeLabel":"CommandRule · object[]"}},"additionalProperties":false,"uniqueKey":"mounts.oneOf.0.additionalProperties.commands.oneOf.0","typeLabel":"MountCommandsBlock · object"},{"type":"null","uniqueKey":"mounts.oneOf.0.additionalProperties.commands.oneOf.1","typeLabel":"null"}],"uniqueKey":"mounts.oneOf.0.additionalProperties.commands","typeLabel":"MountCommandsBlock · object | null"},"paths":{"oneOf":[{"type":"object","title":"PathsBlock","description":"``paths:`` of a profile, or of one of its mount sections.\n\n``hide`` entries use the document's one grammar: an entry with\n``*``, ``?`` or ``[`` is a pattern, anything else an exact path\nand its subtree (``utils/hidden.classify_paths``); every entry\nholds a token and is absolute or a name pattern, wherever the block\nis written. A hide entry may also be a group\n``{patterns: [...], reason: ...}``: the patterns join the flat list\nlike any other entry and the reason lands in ``reasons``, the\noperator-only side table (:class:`HideReason`).\n\n``show`` is the other half of the path axis: a mapping of path to\nmode (``{\"/repo/docs\": r}``), or a plain list whose entries inherit\nthe mount's mode. Every entry is absolute, a subtree or an anchored\npattern, because a show anchors to a place and a name pattern names\nnone. An entry re-opens its subtree inside a hidden region when its\nanchor is deeper than the hide's, and states the mode in force\nbelow its anchor when it carries one; both on the one anchor-depth\nrule.\n\nArgs:\n hide (tuple[str, ...]): what the profile makes nonexistent.\n show (tuple[ShowEntry, ...]): the profile's show entries, in\n document order.\n reasons (tuple[HideReason, ...]): why grouped hide entries\n exist, for the operator's entry points only.","properties":{"hide":{"items":{"type":"string","uniqueKey":"mounts.oneOf.0.additionalProperties.paths.oneOf.0.hide.items.[INDEX]","typeLabel":"string"},"type":"array","title":"Hide","default":[],"uniqueKey":"mounts.oneOf.0.additionalProperties.paths.oneOf.0.hide","typeLabel":"string[]"},"show":{"items":{"properties":{"path":{"type":"string","title":"Path","isRequired":true,"uniqueKey":"mounts.oneOf.0.additionalProperties.paths.oneOf.0.show.items.[INDEX].path","typeLabel":"string"},"mode":{"oneOf":[{"type":"string","title":"MountMode","description":"What a mount lets commands do, a cumulative ladder.\n\nREAD lists and reads. WRITE also creates, changes and deletes. EXEC\nalso lets the interpreter commands (python3, js) run code: a script\nfile named as their operand must sit on an EXEC mount, while inline\ncode and -m need one somewhere in the workspace (imports are not\nchecked by path). Shell scripts need no EXEC, since the shell checks\neach of their commands like a typed one; a ./script whose shebang\nnames python3 reaches python3, which does check.","enum":["read","write","exec"],"uniqueKey":"mounts.oneOf.0.additionalProperties.paths.oneOf.0.show.items.[INDEX].mode.oneOf.0","typeLabel":"enum\u003cstring>"},{"type":"null","uniqueKey":"mounts.oneOf.0.additionalProperties.paths.oneOf.0.show.items.[INDEX].mode.oneOf.1","typeLabel":"null"}],"uniqueKey":"mounts.oneOf.0.additionalProperties.paths.oneOf.0.show.items.[INDEX].mode","typeLabel":"enum\u003cstring> | null"}},"additionalProperties":false,"type":"object","required":["path"],"title":"ShowEntry","description":"One ``show`` entry of a profile's path axis, compiled.\n\nArgs:\n path (str): the entry as written: an exact subtree or an\n anchored pattern, always absolute. A slashless name pattern\n is refused at validation, because a show anchors to a place\n and a name pattern names none.\n mode (MountMode | None): the mode the entry states for its\n subtree; None for a list-form entry, which inherits the\n mount's.","uniqueKey":"mounts.oneOf.0.additionalProperties.paths.oneOf.0.show.items.[INDEX]","typeLabel":"ShowEntry · object"},"type":"array","title":"Show","default":[],"uniqueKey":"mounts.oneOf.0.additionalProperties.paths.oneOf.0.show","typeLabel":"ShowEntry · object[]"},"reasons":{"items":{"properties":{"patterns":{"items":{"type":"string","uniqueKey":"mounts.oneOf.0.additionalProperties.paths.oneOf.0.reasons.items.[INDEX].patterns.items.[INDEX]","typeLabel":"string"},"type":"array","title":"Patterns","isRequired":true,"uniqueKey":"mounts.oneOf.0.additionalProperties.paths.oneOf.0.reasons.items.[INDEX].patterns","typeLabel":"string[]"},"reason":{"type":"string","title":"Reason","isRequired":true,"uniqueKey":"mounts.oneOf.0.additionalProperties.paths.oneOf.0.reasons.items.[INDEX].reason","typeLabel":"string"}},"additionalProperties":false,"type":"object","required":["patterns","reason"],"title":"HideReason","description":"Why one group of hide entries exists, for the operator only.\n\nThe document may state a hide as ``{patterns: [...], reason: ...}``;\nthe patterns compile into the flat hide spec like any other entry,\nand this side table keeps the reason beside them for the host's\nentry points (audit, read-back). It is never rendered to the agent: a hide\nanswers ENOENT, and a reason on a nonexistent path would confirm\nthe path exists.\n\nArgs:\n patterns (tuple[str, ...]): the group's entries, as compiled\n (a mount section's entries anchored to its root).\n reason (str): why the operator hid them.","uniqueKey":"mounts.oneOf.0.additionalProperties.paths.oneOf.0.reasons.items.[INDEX]","typeLabel":"HideReason · object"},"type":"array","title":"Reasons","default":[],"uniqueKey":"mounts.oneOf.0.additionalProperties.paths.oneOf.0.reasons","typeLabel":"HideReason · object[]"}},"additionalProperties":false,"uniqueKey":"mounts.oneOf.0.additionalProperties.paths.oneOf.0","typeLabel":"PathsBlock · object"},{"type":"null","uniqueKey":"mounts.oneOf.0.additionalProperties.paths.oneOf.1","typeLabel":"null"}],"uniqueKey":"mounts.oneOf.0.additionalProperties.paths","typeLabel":"PathsBlock · object | null"}},"additionalProperties":false,"type":"object","title":"ProfileMount","description":"One mount's entry in a profile: what this profile may do there.\n\nEvery field is optional, and an omitted mount is not a refusal: the\nmount is reachable at the mode it declares in the workspace's\n``mounts:``, which a profile can only weaken (``weaker_mode``), never\nraise. A profile that must not touch a mount hides it, so the mount\nreads as nonexistent rather than as a permission error naming\nsomething the profile cannot see.\n\n``commands`` here carries ask and deny only: an allow list installs\na command for the whole session, and visibility is answered before\nany operand exists, so it cannot be per mount. Rules written here\napply to a line that works inside this mount, by cwd or by operand,\nwhich is what a path-scoped rule cannot express (``cd /repo \u0026\u0026 git\ncommit`` names no path).\n\nArgs:\n mode (MountMode | None): this profile's mode for the mount; None\n keeps the mount's own.\n commands (MountCommandsBlock | None): ask and deny rules for\n lines working inside it.\n paths (PathsBlock | None): hides under it.","uniqueKey":"mounts.oneOf.0.additionalProperties","typeLabel":"ProfileMount · object"},"uniqueKey":"mounts.oneOf.0","typeLabel":"Mounts · object"},{"type":"null","title":"Mounts","uniqueKey":"mounts.oneOf.1","typeLabel":"null"}],"uniqueKey":"mounts","typeLabel":"Mounts · object | null"},"paths":{"oneOf":[{"type":"object","title":"PathsBlock","description":"``paths:`` of a profile, or of one of its mount sections.\n\n``hide`` entries use the document's one grammar: an entry with\n``*``, ``?`` or ``[`` is a pattern, anything else an exact path\nand its subtree (``utils/hidden.classify_paths``); every entry\nholds a token and is absolute or a name pattern, wherever the block\nis written. A hide entry may also be a group\n``{patterns: [...], reason: ...}``: the patterns join the flat list\nlike any other entry and the reason lands in ``reasons``, the\noperator-only side table (:class:`HideReason`).\n\n``show`` is the other half of the path axis: a mapping of path to\nmode (``{\"/repo/docs\": r}``), or a plain list whose entries inherit\nthe mount's mode. Every entry is absolute, a subtree or an anchored\npattern, because a show anchors to a place and a name pattern names\nnone. An entry re-opens its subtree inside a hidden region when its\nanchor is deeper than the hide's, and states the mode in force\nbelow its anchor when it carries one; both on the one anchor-depth\nrule.\n\nArgs:\n hide (tuple[str, ...]): what the profile makes nonexistent.\n show (tuple[ShowEntry, ...]): the profile's show entries, in\n document order.\n reasons (tuple[HideReason, ...]): why grouped hide entries\n exist, for the operator's entry points only.","properties":{"hide":{"items":{"type":"string","uniqueKey":"paths.oneOf.0.hide.items.[INDEX]","typeLabel":"string"},"type":"array","title":"Hide","default":[],"uniqueKey":"paths.oneOf.0.hide","typeLabel":"string[]"},"show":{"items":{"properties":{"path":{"type":"string","title":"Path","isRequired":true,"uniqueKey":"paths.oneOf.0.show.items.[INDEX].path","typeLabel":"string"},"mode":{"oneOf":[{"type":"string","title":"MountMode","description":"What a mount lets commands do, a cumulative ladder.\n\nREAD lists and reads. WRITE also creates, changes and deletes. EXEC\nalso lets the interpreter commands (python3, js) run code: a script\nfile named as their operand must sit on an EXEC mount, while inline\ncode and -m need one somewhere in the workspace (imports are not\nchecked by path). Shell scripts need no EXEC, since the shell checks\neach of their commands like a typed one; a ./script whose shebang\nnames python3 reaches python3, which does check.","enum":["read","write","exec"],"uniqueKey":"paths.oneOf.0.show.items.[INDEX].mode.oneOf.0","typeLabel":"enum\u003cstring>"},{"type":"null","uniqueKey":"paths.oneOf.0.show.items.[INDEX].mode.oneOf.1","typeLabel":"null"}],"uniqueKey":"paths.oneOf.0.show.items.[INDEX].mode","typeLabel":"enum\u003cstring> | null"}},"additionalProperties":false,"type":"object","required":["path"],"title":"ShowEntry","description":"One ``show`` entry of a profile's path axis, compiled.\n\nArgs:\n path (str): the entry as written: an exact subtree or an\n anchored pattern, always absolute. A slashless name pattern\n is refused at validation, because a show anchors to a place\n and a name pattern names none.\n mode (MountMode | None): the mode the entry states for its\n subtree; None for a list-form entry, which inherits the\n mount's.","uniqueKey":"paths.oneOf.0.show.items.[INDEX]","typeLabel":"ShowEntry · object"},"type":"array","title":"Show","default":[],"uniqueKey":"paths.oneOf.0.show","typeLabel":"ShowEntry · object[]"},"reasons":{"items":{"properties":{"patterns":{"items":{"type":"string","uniqueKey":"paths.oneOf.0.reasons.items.[INDEX].patterns.items.[INDEX]","typeLabel":"string"},"type":"array","title":"Patterns","isRequired":true,"uniqueKey":"paths.oneOf.0.reasons.items.[INDEX].patterns","typeLabel":"string[]"},"reason":{"type":"string","title":"Reason","isRequired":true,"uniqueKey":"paths.oneOf.0.reasons.items.[INDEX].reason","typeLabel":"string"}},"additionalProperties":false,"type":"object","required":["patterns","reason"],"title":"HideReason","description":"Why one group of hide entries exists, for the operator only.\n\nThe document may state a hide as ``{patterns: [...], reason: ...}``;\nthe patterns compile into the flat hide spec like any other entry,\nand this side table keeps the reason beside them for the host's\nentry points (audit, read-back). It is never rendered to the agent: a hide\nanswers ENOENT, and a reason on a nonexistent path would confirm\nthe path exists.\n\nArgs:\n patterns (tuple[str, ...]): the group's entries, as compiled\n (a mount section's entries anchored to its root).\n reason (str): why the operator hid them.","uniqueKey":"paths.oneOf.0.reasons.items.[INDEX]","typeLabel":"HideReason · object"},"type":"array","title":"Reasons","default":[],"uniqueKey":"paths.oneOf.0.reasons","typeLabel":"HideReason · object[]"}},"additionalProperties":false,"uniqueKey":"paths.oneOf.0","typeLabel":"PathsBlock · object"},{"type":"null","uniqueKey":"paths.oneOf.1","typeLabel":"null"}],"uniqueKey":"paths","typeLabel":"PathsBlock · object | null"},"vars":{"oneOf":[{"type":"object","title":"VarsBlock","description":"``vars:`` of a profile.\n\nArgs:\n hide (tuple[str, ...]): variable names or globs over names the\n session reads as unset.","properties":{"hide":{"items":{"type":"string","uniqueKey":"vars.oneOf.0.hide.items.[INDEX]","typeLabel":"string"},"type":"array","title":"Hide","default":[],"uniqueKey":"vars.oneOf.0.hide","typeLabel":"string[]"}},"additionalProperties":false,"uniqueKey":"vars.oneOf.0","typeLabel":"VarsBlock · object"},{"type":"null","uniqueKey":"vars.oneOf.1","typeLabel":"null"}],"uniqueKey":"vars","typeLabel":"VarsBlock · object | null"},"commands":{"oneOf":[{"type":"object","title":"CommandsBlock","description":"``commands:`` at the top level of a profile.\n\n``allow`` lists the command patterns the profile allows; a line no\npattern covers is refused, ``\u003ccmd>: Permission denied`` at 126, like\nany other rule's Deny. Shell builtins are subjects like everything\nelse: a list stating only ``cat`` refuses ``echo`` and ``cd``. The agent's\nown functions are the one exemption, safe because every line of a\nbody passes the gate itself. ``ask`` rules are admitted only with a\nhost approval; ``deny`` rules refuse with a reason. A bare string in\neither is one command pattern with the default reason.\n\nArgs:\n allow (tuple[str, ...] | None): the profile's allow patterns;\n None (unstated) allows everything.\n ask (tuple[CommandRule, ...]): what needs sign-off, in order.\n deny (tuple[CommandRule, ...]): the profile's refusals, in order.","properties":{"allow":{"oneOf":[{"type":"array","items":{"type":"string","uniqueKey":"commands.oneOf.0.allow.oneOf.0.items.[INDEX]","typeLabel":"string"},"title":"Allow","uniqueKey":"commands.oneOf.0.allow.oneOf.0","typeLabel":"string[]"},{"type":"null","title":"Allow","uniqueKey":"commands.oneOf.0.allow.oneOf.1","typeLabel":"null"}],"uniqueKey":"commands.oneOf.0.allow","typeLabel":"string[] | null"},"ask":{"items":{"properties":{"reason":{"type":"string","title":"Reason","isRequired":true,"uniqueKey":"commands.oneOf.0.ask.items.[INDEX].reason","typeLabel":"string"},"commands":{"items":{"type":"string","uniqueKey":"commands.oneOf.0.ask.items.[INDEX].commands.items.[INDEX]","typeLabel":"string"},"type":"array","title":"Commands","default":[],"uniqueKey":"commands.oneOf.0.ask.items.[INDEX].commands","typeLabel":"string[]"},"paths":{"items":{"type":"string","uniqueKey":"commands.oneOf.0.ask.items.[INDEX].paths.items.[INDEX]","typeLabel":"string"},"type":"array","title":"Paths","default":[],"uniqueKey":"commands.oneOf.0.ask.items.[INDEX].paths","typeLabel":"string[]"},"mount":{"type":"string","title":"Mount","default":"","uniqueKey":"commands.oneOf.0.ask.items.[INDEX].mount","typeLabel":"string"}},"additionalProperties":false,"type":"object","required":["reason"],"title":"CommandRule","description":"One admission rule of the permissions document: refuse (or ask\nabout) matching commands, on matching paths when it names any.\n\nIt is the compiled element of ``commands.deny`` and ``commands.ask``\nwherever the profile writes one, and reaches the workspace only inside\nthat document; ``PermissionsPolicy`` is what evaluates it. The\ndocument writes a rule in one of three shapes, and each compiles to\nrules of this class: a list of command patterns (a whole-line rule\non each, no paths), a mapping of command pattern to its paths (one\ncommand to many paths, one rule per command, so a path is never\nstated beside a command it was not meant for), or paths alone (a\nrule on every command, at the dispatcher too). A command entry is a\ntoken-prefix pattern over the line as the entry point normalizes it (``rm``\nis every rm line, ``git push`` every ``git push ...``, a ``*`` token\nany one token). Path entries use the document's one grammar: an\nentry with ``*``, ``?`` or ``[`` is a pattern (repo fnmatch dialect,\n``*`` crossing ``/``, a slashless pattern matching any name\ncomponent), anything else is an exact path and its subtree. Every\nentry is absolute or a name pattern, holds a token (a blank one\nwould be the root), and inside a mount section must name something\nunder that mount root.\n\nArgs:\n reason (str): why the command is refused, carried on the\n result's refusal record.\n commands (tuple[str, ...]): command patterns the rule applies\n to; empty means every command. A path-scoped rule carries\n exactly one.\n paths (tuple[str, ...]): path entries; empty refuses the\n command regardless of its operands.\n mount (str): set by the compiler for a rule written under a\n ``mounts.\u003cprefix>`` section, the mount root it is scoped to:\n it applies only to a line whose cwd or paths lie under it.\n Empty for a rule written at the top level; never typed in\n the document.","uniqueKey":"commands.oneOf.0.ask.items.[INDEX]","typeLabel":"CommandRule · object"},"type":"array","title":"Ask","default":[],"uniqueKey":"commands.oneOf.0.ask","typeLabel":"CommandRule · object[]"},"deny":{"items":{"properties":{"reason":{"type":"string","title":"Reason","isRequired":true,"uniqueKey":"commands.oneOf.0.deny.items.[INDEX].reason","typeLabel":"string"},"commands":{"items":{"type":"string","uniqueKey":"commands.oneOf.0.deny.items.[INDEX].commands.items.[INDEX]","typeLabel":"string"},"type":"array","title":"Commands","default":[],"uniqueKey":"commands.oneOf.0.deny.items.[INDEX].commands","typeLabel":"string[]"},"paths":{"items":{"type":"string","uniqueKey":"commands.oneOf.0.deny.items.[INDEX].paths.items.[INDEX]","typeLabel":"string"},"type":"array","title":"Paths","default":[],"uniqueKey":"commands.oneOf.0.deny.items.[INDEX].paths","typeLabel":"string[]"},"mount":{"type":"string","title":"Mount","default":"","uniqueKey":"commands.oneOf.0.deny.items.[INDEX].mount","typeLabel":"string"}},"additionalProperties":false,"type":"object","required":["reason"],"title":"CommandRule","description":"One admission rule of the permissions document: refuse (or ask\nabout) matching commands, on matching paths when it names any.\n\nIt is the compiled element of ``commands.deny`` and ``commands.ask``\nwherever the profile writes one, and reaches the workspace only inside\nthat document; ``PermissionsPolicy`` is what evaluates it. The\ndocument writes a rule in one of three shapes, and each compiles to\nrules of this class: a list of command patterns (a whole-line rule\non each, no paths), a mapping of command pattern to its paths (one\ncommand to many paths, one rule per command, so a path is never\nstated beside a command it was not meant for), or paths alone (a\nrule on every command, at the dispatcher too). A command entry is a\ntoken-prefix pattern over the line as the entry point normalizes it (``rm``\nis every rm line, ``git push`` every ``git push ...``, a ``*`` token\nany one token). Path entries use the document's one grammar: an\nentry with ``*``, ``?`` or ``[`` is a pattern (repo fnmatch dialect,\n``*`` crossing ``/``, a slashless pattern matching any name\ncomponent), anything else is an exact path and its subtree. Every\nentry is absolute or a name pattern, holds a token (a blank one\nwould be the root), and inside a mount section must name something\nunder that mount root.\n\nArgs:\n reason (str): why the command is refused, carried on the\n result's refusal record.\n commands (tuple[str, ...]): command patterns the rule applies\n to; empty means every command. A path-scoped rule carries\n exactly one.\n paths (tuple[str, ...]): path entries; empty refuses the\n command regardless of its operands.\n mount (str): set by the compiler for a rule written under a\n ``mounts.\u003cprefix>`` section, the mount root it is scoped to:\n it applies only to a line whose cwd or paths lie under it.\n Empty for a rule written at the top level; never typed in\n the document.","uniqueKey":"commands.oneOf.0.deny.items.[INDEX]","typeLabel":"CommandRule · object"},"type":"array","title":"Deny","default":[],"uniqueKey":"commands.oneOf.0.deny","typeLabel":"CommandRule · object[]"}},"additionalProperties":false,"uniqueKey":"commands.oneOf.0","typeLabel":"CommandsBlock · object"},{"type":"null","uniqueKey":"commands.oneOf.1","typeLabel":"null"}],"uniqueKey":"commands","typeLabel":"CommandsBlock · object | null"},"policy":{"oneOf":[{"type":"object","title":"Policy","additionalProperties":{"items":{"properties":{"script":{"oneOf":[{"type":"object","title":"ScriptSource","description":"A program's source: a policy program or a script CLI.\n\nA yaml ``script:`` value references a ``.py`` or ``.js``/``.mjs``\nfile whose content is embedded here at load; code passes the text.\nIt runs as a program on the runtime its config names, never edited.\n\nArgs:\n source (str): the script program.\n language (Language): the script's language (\"python\" or \"js\"),\n stamped from the file extension at config load; the\n programmatic default is \"python\".\n module (bool): the source is an ES module (a ``.mjs`` file), so\n a js engine must run it in module mode or ``import`` and\n top-level ``await`` fail. Stamped from the extension at\n load beside ``language``, since the path is gone once the\n source is embedded.","required":["source"],"properties":{"source":{"type":"string","title":"Source","isRequired":true,"uniqueKey":"policy.oneOf.0.additionalProperties.items.[INDEX].script.oneOf.0.source","typeLabel":"string"},"language":{"type":"string","enum":["python","js"],"title":"Language","default":"python","uniqueKey":"policy.oneOf.0.additionalProperties.items.[INDEX].script.oneOf.0.language","typeLabel":"enum\u003cstring>"},"module":{"type":"boolean","title":"Module","default":false,"uniqueKey":"policy.oneOf.0.additionalProperties.items.[INDEX].script.oneOf.0.module","typeLabel":"boolean"}},"additionalProperties":false,"isRequired":true,"uniqueKey":"policy.oneOf.0.additionalProperties.items.[INDEX].script.oneOf.0","typeLabel":"ScriptSource · object"},{"type":"string","title":"Script","isRequired":true,"uniqueKey":"policy.oneOf.0.additionalProperties.items.[INDEX].script.oneOf.1","typeLabel":"string"}],"isRequired":true,"uniqueKey":"policy.oneOf.0.additionalProperties.items.[INDEX].script","typeLabel":"ScriptSource · object | string"},"runtime":{"oneOf":[{"type":"string","title":"Runtime","default":"monty","uniqueKey":"policy.oneOf.0.additionalProperties.items.[INDEX].runtime.oneOf.0","typeLabel":"string"},{"type":"object","title":"Runtime","default":"monty","additionalProperties":true,"uniqueKey":"policy.oneOf.0.additionalProperties.items.[INDEX].runtime.oneOf.1","typeLabel":"Runtime · object"}],"uniqueKey":"policy.oneOf.0.additionalProperties.items.[INDEX].runtime","typeLabel":"string | Runtime · object"},"env":{"additionalProperties":{"oneOf":[{"type":"string","uniqueKey":"policy.oneOf.0.additionalProperties.items.[INDEX].env.additionalProperties.oneOf.0","typeLabel":"string"},{"type":"object","title":"SecretRef","description":"A configured value read from a source instead of written down.\n\nThe plane's one declarative pointer, spelled with the same three\nkeys the env plane's managed entry uses, so one grammar covers\nevery place a deployment points at a secret: a source's own config,\na mount's credential, a CLI's.\n\nWhere it may point is the *context's* rule, not this model's.\n`SecretSource` narrows its own config to `BOOTSTRAP_SOURCES`,\nbecause that is what stops the source table from needing a\ndependency graph; a mount has no such limit, since every source is\nalready built by the time one is read.\n\nArgs:\n provider (str): the bootstrap source, `env` or `dotenv`.\n Spelled `from:` in YAML (python keyword), via alias.\n ref (str): the source's address, a file path for `dotenv`.\n key (str): which of the secret's fields holds the value.","required":["from","key"],"properties":{"from":{"type":"string","title":"From","isRequired":true,"uniqueKey":"policy.oneOf.0.additionalProperties.items.[INDEX].env.additionalProperties.oneOf.1.from","typeLabel":"string"},"key":{"type":"string","title":"Key","isRequired":true,"uniqueKey":"policy.oneOf.0.additionalProperties.items.[INDEX].env.additionalProperties.oneOf.1.key","typeLabel":"string"},"ref":{"type":"string","title":"Ref","default":"","uniqueKey":"policy.oneOf.0.additionalProperties.items.[INDEX].env.additionalProperties.oneOf.1.ref","typeLabel":"string"}},"additionalProperties":false,"uniqueKey":"policy.oneOf.0.additionalProperties.items.[INDEX].env.additionalProperties.oneOf.1","typeLabel":"SecretRef · object"}],"uniqueKey":"policy.oneOf.0.additionalProperties.items.[INDEX].env.additionalProperties","typeLabel":"string | SecretRef · object"},"type":"object","title":"Env","default":{},"uniqueKey":"policy.oneOf.0.additionalProperties.items.[INDEX].env","typeLabel":"Env · object"}},"additionalProperties":false,"type":"object","required":["script"],"title":"ProfilePolicy","description":"One program of a profile's policy, as the document states it: the\nprogram, and the runtime that runs it.\n\nArgs:\n script (ScriptSource | str): the policy program. A ``str`` is\n the path form the config loader accepts and loads; code\n passes the loaded ``ScriptSource``, so a path still spelled\n as a string when the workspace reads it means the config\n layer never saw it, and is refused there.\n runtime (str | dict[str, Any]): the runtime the program runs on:\n a name, or ``{name, config}`` for one that needs settings,\n the shape a ``runtimes`` entry has. Monty when the program\n names none; without the ``monty`` extra installed, such a\n program fails closed with the extra's install hint.\n env (dict[str, str | SecretRef]): variables the program runs\n with beside ``MIRAGE_POLICY_CTX``, on any runtime: a literal,\n or a pointer read from its source when the program first\n runs. None of the session's reach it.","uniqueKey":"policy.oneOf.0.additionalProperties.items.[INDEX]","typeLabel":"ProfilePolicy · object"},"type":"array","uniqueKey":"policy.oneOf.0.additionalProperties","typeLabel":"ProfilePolicy · object[]"},"uniqueKey":"policy.oneOf.0","typeLabel":"Policy · object"},{"type":"null","title":"Policy","uniqueKey":"policy.oneOf.1","typeLabel":"null"}],"uniqueKey":"policy","typeLabel":"Policy · object | null"},"command_limits":{"oneOf":[{"type":"object","title":"Command Limits","additionalProperties":{"properties":{"max_bytes":{"oneOf":[{"type":"integer","title":"Max Bytes","minimum":0,"uniqueKey":"command_limits.oneOf.0.additionalProperties.max_bytes.oneOf.0","typeLabel":"integer"},{"type":"null","title":"Max Bytes","uniqueKey":"command_limits.oneOf.0.additionalProperties.max_bytes.oneOf.1","typeLabel":"null"}],"uniqueKey":"command_limits.oneOf.0.additionalProperties.max_bytes","typeLabel":"integer | null"},"max_lines":{"oneOf":[{"type":"integer","title":"Max Lines","minimum":0,"uniqueKey":"command_limits.oneOf.0.additionalProperties.max_lines.oneOf.0","typeLabel":"integer"},{"type":"null","title":"Max Lines","uniqueKey":"command_limits.oneOf.0.additionalProperties.max_lines.oneOf.1","typeLabel":"null"}],"uniqueKey":"command_limits.oneOf.0.additionalProperties.max_lines","typeLabel":"integer | null"},"timeout_seconds":{"oneOf":[{"type":"number","title":"Timeout Seconds","minimum":0,"uniqueKey":"command_limits.oneOf.0.additionalProperties.timeout_seconds.oneOf.0","typeLabel":"number"},{"type":"null","title":"Timeout Seconds","uniqueKey":"command_limits.oneOf.0.additionalProperties.timeout_seconds.oneOf.1","typeLabel":"null"}],"uniqueKey":"command_limits.oneOf.0.additionalProperties.timeout_seconds","typeLabel":"number | null"},"walk_limit":{"oneOf":[{"type":"integer","title":"Walk Limit","minimum":-1,"uniqueKey":"command_limits.oneOf.0.additionalProperties.walk_limit.oneOf.0","typeLabel":"integer"},{"type":"null","title":"Walk Limit","uniqueKey":"command_limits.oneOf.0.additionalProperties.walk_limit.oneOf.1","typeLabel":"null"}],"uniqueKey":"command_limits.oneOf.0.additionalProperties.walk_limit","typeLabel":"integer | null"},"on_exceed":{"type":"string","enum":["error","truncate"],"title":"OnExceed","default":"truncate","uniqueKey":"command_limits.oneOf.0.additionalProperties.on_exceed","typeLabel":"enum\u003cstring>"}},"additionalProperties":false,"type":"object","title":"Limit","description":"A bound on a result: the policy layer's limit arm and the shape\nevery cap config parses into.\n\nCarries its fields inline (the Deny precedent: an action is its\npayload). ``kind`` is the wire discriminant; ``aggr`` is the\ncomposition law (AND to the tightest per bound, ANY on error mode)\nand ``layered`` the resolution law (each field from the most\nspecific layer that sets it). ``walk_limit`` caps the entries one\nwalk lists on a mount, -1 for no cap.","uniqueKey":"command_limits.oneOf.0.additionalProperties","typeLabel":"Limit · object"},"uniqueKey":"command_limits.oneOf.0","typeLabel":"Command Limits · object"},{"type":"null","title":"Command Limits","uniqueKey":"command_limits.oneOf.1","typeLabel":"null"}],"uniqueKey":"command_limits","typeLabel":"Command Limits · object | null"},"processes":{"oneOf":[{"type":"object","title":"ProcessPermissions","description":"How far past its own session a profile reaches into processes.\n\nA session always sees and stops its own processes. ``list`` widens\nwhat ``ps`` and a handler's process view see; ``kill`` widens what\nthey may stop, and never past ``list``. ``max`` caps the live\nprocesses the session holds, its running line included, as\n``ulimit -u`` counts the shell. A bare scope sets both. The workspace\nstates one for every session and a profile's overrides it field by\nfield (``layered``).\n\nArgs:\n list (ProcessScope): whose processes the session sees.\n kill (ProcessScope): whose processes the session may stop.\n max (int | None): most live processes, ``MAX_PROCESSES`` unless\n stated, None for no cap.","properties":{"list":{"type":"string","enum":["session","workspace"],"title":"List","default":"session","uniqueKey":"processes.oneOf.0.list","typeLabel":"enum\u003cstring>"},"kill":{"type":"string","enum":["session","workspace"],"title":"Kill","default":"session","uniqueKey":"processes.oneOf.0.kill","typeLabel":"enum\u003cstring>"},"max":{"oneOf":[{"type":"integer","title":"Max","default":128,"minimum":1,"uniqueKey":"processes.oneOf.0.max.oneOf.0","typeLabel":"integer"},{"type":"null","title":"Max","default":128,"uniqueKey":"processes.oneOf.0.max.oneOf.1","typeLabel":"null"}],"uniqueKey":"processes.oneOf.0.max","typeLabel":"integer | null"}},"additionalProperties":false,"uniqueKey":"processes.oneOf.0","typeLabel":"ProcessPermissions · object"},{"type":"null","uniqueKey":"processes.oneOf.1","typeLabel":"null"}],"uniqueKey":"processes","typeLabel":"ProcessPermissions · object | null"},"network":{"oneOf":[{"type":"boolean","title":"Network","uniqueKey":"network.oneOf.0","typeLabel":"boolean"},{"type":"object","title":"Network","additionalProperties":{"oneOf":[{"type":"array","items":{"type":"string","uniqueKey":"network.oneOf.1.additionalProperties.oneOf.0.items.[INDEX]","typeLabel":"string"},"uniqueKey":"network.oneOf.1.additionalProperties.oneOf.0","typeLabel":"string[]"},{"type":"object","additionalProperties":{"type":"string","uniqueKey":"network.oneOf.1.additionalProperties.oneOf.1.additionalProperties","typeLabel":"string"},"uniqueKey":"network.oneOf.1.additionalProperties.oneOf.1","typeLabel":"object"}],"uniqueKey":"network.oneOf.1.additionalProperties","typeLabel":"string[] | object"},"uniqueKey":"network.oneOf.1","typeLabel":"Network · object"},{"type":"null","title":"Network","uniqueKey":"network.oneOf.2","typeLabel":"null"}],"uniqueKey":"network","typeLabel":"boolean | Network · object | null"}},"additionalProperties":false,"type":"object","title":"SessionProfile","description":"One profile: the whole permission document a session runs under.\n\nA session is created from exactly one of these, and it is the only\nplace permissions are written. There is no workspace-wide block and\nno mount-owned block above it, so reading this object is reading\neverything the profile may do; what a profile does not say, it does not\nrestrict. Configuration, not enforcement: the resolver compiles it\nonto the session's narrowing fields and the entry points keep enforcing.\nDeliberately not named a View, which per the view convention is a\nhandle an agent holds on one entry point, while a profile is what the\nembedder uses to *define* one. Frozen so two agents with the same\nprofile share one object and neither can bend the other's view.\n\nTwo rules decide a line against it, and they are the whole law.\nA rule naming no path is read by verb (deny before ask before\nallow), wherever it is written. A rule carrying paths, and every\nhide, is read by anchor depth: the deeper entry wins, ties break by\nverb.\n\nA profile may also state a ``policy``: for each ``pre_`` method it\nanswers at (``pre_execute``, ``pre_command``, ``pre_vfs``,\n``pre_session``), a list of programs, each with the runtime it runs\non (``ProfilePolicy``, the shape a ``clis`` entry has). A program's\nfunction for the method takes its context and returns its answer:\nNone for no opinion, a deny, an ask, or at ``pre_execute`` a route.\nThey are asked in order and the first deny wins, so a policy expresses\nthe conditions a declarative rule cannot; like every policy, it can\nonly restrict, never grant past a deny. The document is optional\nbeside it: a profile stating only a policy hides nothing, and the\npolicy is its whole admission policy.\n\nArgs:\n cwd (str | None): the session's working directory at creation.\n env (dict[str, str | EnvVar] | None): the env entries seeded\n into the session at creation, in the workspace ``env``\n grammar: a bare string is an exported literal, and a\n ``from:`` entry a managed pointer, so a credential is\n named here and fetched, never written as its value.\n mounts (dict[str, ProfileMount] | None): per-mount settings,\n keyed by prefix: a mode, ask and deny rules for lines\n working inside the mount, and hides under it. A mount the\n mapping omits keeps its own mode and gains no rules.\n paths (PathsBlock | None): the profile's hides, absolute.\n vars (VarsBlock | None): the profile's hidden variables.\n commands (CommandsBlock | None): the profile's allow list and its\n ask / deny rules, absolute paths.\n policy (dict[ScriptMethod, list[ProfilePolicy]] | None): the\n profile's policy: each ``pre_`` method's programs, asked in\n order.\n network (bool | dict[str, list[str]] | None): where the\n session's lines may connect, the workspace's ``network``\n grammar, held besides the workspace's own; None leaves the\n workspace's alone.","uniqueKey":"","typeLabel":"SessionProfile · object"},"examples":{"Example":{"title":"Example","value":{"cwd":"\u003cstring>","env":{},"mounts":{},"paths":{"hide":[],"show":[],"reasons":[]},"vars":{"hide":[]},"commands":{"allow":["\u003cstring>"],"ask":[],"deny":[]},"policy":{},"command_limits":{},"processes":{"list":"session","kill":"session","max":128},"network":true}}},"exampleType":"generated"}},"exampleType":"generated"},"responses":{"bfbe343b-969a-47ad-98ad-1066bb911220":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":{"type":"string","uniqueKey":"additionalProperties","typeLabel":"string"},"title":"Response Set Profile V1 Workspaces Workspace Id Profiles Name Put","uniqueKey":"","typeLabel":"Response Set Profile V1 Workspaces Workspace Id Profiles Name Put · object"},"examples":{"Example":{"title":"Example","value":{}}},"exampleType":"generated"}},"exampleType":"generated"},"55e22732-920a-4890-8ae5-43d26da67616":{"description":"The token is missing or wrong","content":{"application/json":{"schema":{"type":"object","properties":{"detail":{"description":"What went wrong, as text or a structured record.","isRequired":true,"uniqueKey":"detail","typeLabel":"any"},"errno":{"type":"string","description":"The errno of a failed file call, such as ENOENT.","uniqueKey":"errno","typeLabel":"string"},"refusal":{"type":"object","description":"The policy refusal, when a policy refused the call.","uniqueKey":"refusal","typeLabel":"object"}},"required":["detail"],"uniqueKey":"","typeLabel":"object"},"examples":{"Example":{"title":"Example","value":{"detail":"\u003cunknown>","errno":"\u003cstring>","refusal":{}}}},"exampleType":"generated"},"text/plain":{"schema":{"type":"string","description":"The Python daemon answers Unauthorized as plain text.","uniqueKey":"","typeLabel":"string"},"examples":{"Example":{"title":"Example","value":"\u003cstring>"}},"exampleType":"generated"}},"exampleType":"generated"},"6d6cb91d-ce1b-45b4-a242-ce498f9bd5bf":{"description":"The workspace, session, job or file does not exist","content":{"application/json":{"schema":{"type":"object","properties":{"detail":{"description":"What went wrong, as text or a structured record.","isRequired":true,"uniqueKey":"detail","typeLabel":"any"},"errno":{"type":"string","description":"The errno of a failed file call, such as ENOENT.","uniqueKey":"errno","typeLabel":"string"},"refusal":{"type":"object","description":"The policy refusal, when a policy refused the call.","uniqueKey":"refusal","typeLabel":"object"}},"required":["detail"],"uniqueKey":"","typeLabel":"object"},"examples":{"Example":{"title":"Example","value":{"detail":"\u003cunknown>","errno":"\u003cstring>","refusal":{}}}},"exampleType":"generated"}},"exampleType":"generated"},"59aed612-c15b-4dae-9122-d7e0cb79efb5":{"content":{"application/json":{"schema":{"properties":{"detail":{"items":{"properties":{"loc":{"items":{"oneOf":[{"type":"string","uniqueKey":"detail.items.[INDEX].loc.items.[INDEX].oneOf.0","typeLabel":"string"},{"type":"integer","uniqueKey":"detail.items.[INDEX].loc.items.[INDEX].oneOf.1","typeLabel":"integer"}],"uniqueKey":"detail.items.[INDEX].loc.items.[INDEX]","typeLabel":"string | integer"},"type":"array","title":"Location","isRequired":true,"uniqueKey":"detail.items.[INDEX].loc","typeLabel":"(string | integer)[]"},"msg":{"type":"string","title":"Message","isRequired":true,"uniqueKey":"detail.items.[INDEX].msg","typeLabel":"string"},"type":{"type":"string","title":"Error Type","isRequired":true,"uniqueKey":"detail.items.[INDEX].type","typeLabel":"string"},"input":{"oneOf":[{"title":"Input"}],"uniqueKey":"detail.items.[INDEX].input","typeLabel":"any"},"ctx":{"type":"object","title":"Context","uniqueKey":"detail.items.[INDEX].ctx","typeLabel":"Context · object"}},"type":"object","required":["loc","msg","type"],"title":"ValidationError","uniqueKey":"detail.items.[INDEX]","typeLabel":"ValidationError · object"},"type":"array","title":"Detail","uniqueKey":"detail","typeLabel":"ValidationError · object[]"}},"type":"object","title":"HTTPValidationError","uniqueKey":"","typeLabel":"HTTPValidationError · object"},"examples":{"Example":{"title":"Example","value":{"detail":[{"loc":["\u003cstring>"],"msg":"\u003cstring>","type":"\u003cstring>","input":"\u003cunknown>","ctx":{}}]}}},"exampleType":"generated"}},"description":"Validation Error","exampleType":"generated"},"598e4251-8e69-44fc-8a89-9266d5838cb8":{"description":"Past a rate limit, or a new session past max_sessions","content":{"application/json":{"schema":{"type":"object","properties":{"detail":{"description":"What went wrong, as text or a structured record.","isRequired":true,"uniqueKey":"detail","typeLabel":"any"},"errno":{"type":"string","description":"The errno of a failed file call, such as ENOENT.","uniqueKey":"errno","typeLabel":"string"},"refusal":{"type":"object","description":"The policy refusal, when a policy refused the call.","uniqueKey":"refusal","typeLabel":"object"}},"required":["detail"],"uniqueKey":"","typeLabel":"object"},"examples":{"Example":{"title":"Example","value":{"detail":"\u003cunknown>","errno":"\u003cstring>","refusal":{}}}},"exampleType":"generated"}},"headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer","minimum":0}}},"exampleType":"generated"}},"security":{"4159ccc1-3afa-4800-8ae3-f86840818ec3":{"bearerAuth":{"type":"http","scheme":"bearer","description":"The server's token (MIRAGE_AUTH_TOKEN) or a JWT. A daemon in the default local mode with no token accepts requests without one.","scopes":[],"schemeName":"bearerAuth"}}},"servers":{"5b646690-c8a6-470b-9b36-ade1de13789b":{"url":"http://127.0.0.1:8765","description":"A local daemon on its default port"}},"processedSecurityOptions":[{"schemes":[{"scheme":{"type":"http","scheme":"bearer","description":"The server's token (MIRAGE_AUTH_TOKEN) or a JWT. A daemon in the default local mode with no token accepts requests without one.","scopes":[],"schemeName":"bearerAuth"},"schema":{"title":"Bearer Auth","type":"string","isRequired":true,"description":"The server's token (MIRAGE_AUTH_TOKEN) or a JWT. A daemon in the default local mode with no token accepts requests without one.","format":"bearer","typeLabel":"string\u003cbearer>","deprecated":false},"schemeName":"bearerAuth","name":"Authorization"}],"title":"bearerAuth"}]},"originalFileLocation":"openapi.yaml"},"subdomain":"struktoai","siteName":"Mirage","title":"Set a profile - Mirage","navMaps":{"firstHrefInVersion":{},"firstHrefInLanguage":{}},"lastModified":"2026-11-06T19:53:32.208Z","originalFileLocation":"api/operations/workspaces/set-a-profile.mdx"},"headHtml":"\u003cscript data-mint-head>(function(){var d=document.documentElement,p=null;if(!p){try{p=localStorage.getItem(\"isDarkMode\")}catch(e){}if(p==='true')p='dark';else if(p==='false')p='light';if(p!=='light'\u0026\u0026p!=='dark'\u0026\u0026p!=='system')p=\"system\"}var r=p==='system'?(matchMedia(\"(prefers-color-scheme: dark)\").matches?'dark':'light'):p;d.classList.remove(r==='dark'?'light':'dark');d.classList.add(r);d.setAttribute(\"data-theme-preference\",p)})();\u003c/script>\u003cmeta data-mint-head name=\"description\" content=\"Define a named profile on the live workspace, or replace it. Only the live table changes: a session moves when it is updated onto the name, and the workspace\u0026#x27;s config is never rewritten.\">\u003cmeta data-mint-head name=\"keywords\" content=\"Mirage, filesystem for AI agents, virtual filesystem, AI agent tools, agent infrastructure, MCP alternative, bash for agents, S3 filesystem, Google Drive filesystem, Slack filesystem, GitHub filesystem, agent sandbox, Strukto\">\u003cmeta data-mint-head name=\"application-name\" content=\"Mirage\">\u003cmeta data-mint-head name=\"generator\" content=\"Mintlify\">\u003cmeta data-mint-head name=\"robots\" content=\"index, follow\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"192x192\" href=\"/mintlify-assets/_mintlify/favicons/struktoai/3lv99snhL-Tr_A0L/_generated/favicon/android-chrome-192x192.png\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"apple-touch-icon\" type=\"image/png\" sizes=\"180x180\" href=\"/mintlify-assets/_mintlify/favicons/struktoai/3lv99snhL-Tr_A0L/_generated/favicon/apple-touch-icon.png\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"16x16\" href=\"/mintlify-assets/_mintlify/favicons/struktoai/3lv99snhL-Tr_A0L/_generated/favicon/favicon-16x16.png\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"32x32\" href=\"/mintlify-assets/_mintlify/favicons/struktoai/3lv99snhL-Tr_A0L/_generated/favicon/favicon-32x32.png\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"shortcut icon\" type=\"image/x-icon\" href=\"/mintlify-assets/_mintlify/favicons/struktoai/3lv99snhL-Tr_A0L/_generated/favicon/favicon.ico\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"192x192\" href=\"/mintlify-assets/_mintlify/favicons/struktoai/3lv99snhL-Tr_A0L/_generated/favicon-dark/android-chrome-192x192.png\" media=\"(prefers-color-scheme: dark)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"16x16\" href=\"/mintlify-assets/_mintlify/favicons/struktoai/3lv99snhL-Tr_A0L/_generated/favicon-dark/favicon-16x16.png\" media=\"(prefers-color-scheme: dark)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"32x32\" href=\"/mintlify-assets/_mintlify/favicons/struktoai/3lv99snhL-Tr_A0L/_generated/favicon-dark/favicon-32x32.png\" media=\"(prefers-color-scheme: dark)\">\u003clink data-mint-head rel=\"shortcut icon\" type=\"image/x-icon\" href=\"/mintlify-assets/_mintlify/favicons/struktoai/3lv99snhL-Tr_A0L/_generated/favicon-dark/favicon.ico\" media=\"(prefers-color-scheme: dark)\">\u003cmeta data-mint-head property=\"og:title\" content=\"Set a profile - Mirage\">\u003cmeta data-mint-head property=\"og:description\" content=\"Define a named profile on the live workspace, or replace it. Only the live table changes: a session moves when it is updated onto the name, and the workspace\u0026#x27;s config is never rewritten.\">\u003cmeta data-mint-head property=\"og:site_name\" content=\"Mirage\">\u003cmeta data-mint-head property=\"og:url\" content=\"https://docs.mirage.strukto.ai/api/operations/workspaces/set-a-profile\">\u003cmeta data-mint-head property=\"og:type\" content=\"website\">\u003cmeta data-mint-head property=\"og:image\" content=\"https://raw.githubusercontent.com/strukto-ai/mirage/main/assets/mirage-og-light@2x.png\">\u003cmeta data-mint-head property=\"og:image:width\" content=\"1200\">\u003cmeta data-mint-head property=\"og:image:height\" content=\"630\">\u003cmeta data-mint-head name=\"twitter:card\" content=\"summary_large_image\">\u003cmeta data-mint-head name=\"twitter:title\" content=\"Set a profile - Mirage\">\u003cmeta data-mint-head name=\"twitter:description\" content=\"Define a named profile on the live workspace, or replace it. Only the live table changes: a session moves when it is updated onto the name, and the workspace\u0026#x27;s config is never rewritten.\">\u003cmeta data-mint-head name=\"twitter:image\" content=\"https://raw.githubusercontent.com/strukto-ai/mirage/main/assets/mirage-og-light@2x.png\">\u003cmeta data-mint-head name=\"twitter:image:width\" content=\"1200\">\u003cmeta data-mint-head name=\"twitter:image:height\" content=\"630\">\u003cmeta data-mint-head name=\"msapplication-config\" content=\"/mintlify-assets/_mintlify/favicons/struktoai/3lv99snhL-Tr_A0L/_generated/favicon/browserconfig.xml\">\u003cmeta data-mint-head name=\"apple-mobile-web-app-title\" content=\"Mirage\">\u003cmeta data-mint-head name=\"msapplication-TileColor\" content=\"#0C0C0C\">\u003cmeta data-mint-head name=\"og:locale\" content=\"en_US\">\u003cmeta data-mint-head name=\"author\" content=\"Strukto\">\u003cmeta data-mint-head name=\"googlebot\" content=\"index, follow\">\u003cmeta data-mint-head name=\"theme-color\" content=\"#0C0C0C\">\u003cmeta data-mint-head name=\"color-scheme\" content=\"light dark\">\u003cmeta data-mint-head name=\"language\" content=\"en\">\u003cmeta data-mint-head name=\"category\" content=\"Technology\">\u003cmeta data-mint-head name=\"target\" content=\"developers\">\u003cmeta data-mint-head name=\"apple-mobile-web-app-capable\" content=\"yes\">\u003cmeta data-mint-head name=\"apple-mobile-web-app-status-bar-style\" content=\"black-translucent\">\u003cmeta data-mint-head name=\"og:image:alt\" content=\"Mirage: a virtual terminal for AI agents\">\u003cmeta data-mint-head name=\"twitter:creator\" content=\"@struktoai\">\u003cmeta data-mint-head name=\"twitter:image:alt\" content=\"Mirage · A Virtual Terminal for AI Agents | Strukto\">\u003clink data-mint-head rel=\"canonical\" href=\"https://docs.mirage.strukto.ai/api/operations/workspaces/set-a-profile\">\u003clink data-mint-head rel=\"alternate\" type=\"application/xml\" href=\"/sitemap.xml\">\u003clink data-mint-head rel=\"alternate\" type=\"text/markdown\" href=\"/api/operations/workspaces/set-a-profile.md\">\u003cscript data-mint-head type=\"application/ld+json\">{\"@context\":\"https://schema.org\",\"@graph\":[{\"@type\":\"Organization\",\"@id\":\"https://docs.mirage.strukto.ai/#organization\",\"name\":\"Mirage\",\"url\":\"https://docs.mirage.strukto.ai\",\"logo\":{\"@type\":\"ImageObject\",\"url\":\"https://mintcdn.com/struktoai/7G-pGKhPIqaKqOXr/logo/light.svg?fit=max\u0026auto=format\u0026n=7G-pGKhPIqaKqOXr\u0026q=85\u0026s=d7007be7b5588a72b2072d2c33791785\"}},{\"@type\":\"WebSite\",\"@id\":\"https://docs.mirage.strukto.ai#website\",\"name\":\"Mirage\",\"url\":\"https://docs.mirage.strukto.ai\",\"publisher\":{\"@id\":\"https://docs.mirage.strukto.ai/#organization\"}},{\"@type\":\"WebPage\",\"@id\":\"https://docs.mirage.strukto.ai/api/operations/workspaces/set-a-profile#webpage\",\"url\":\"https://docs.mirage.strukto.ai/api/operations/workspaces/set-a-profile\",\"name\":\"Set a profile\",\"description\":\"Define a named profile on the live workspace, or replace it. Only the live table changes: a session moves when it is updated onto the name, and the workspace's config is never rewritten.\",\"dateModified\":\"2026-11-06T19:53:32.208Z\",\"isPartOf\":{\"@id\":\"https://docs.mirage.strukto.ai#website\"},\"breadcrumb\":{\"@id\":\"https://docs.mirage.strukto.ai/api/operations/workspaces/set-a-profile#breadcrumb\"}},{\"@type\":\"BreadcrumbList\",\"@id\":\"https://docs.mirage.strukto.ai/api/operations/workspaces/set-a-profile#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Operations\",\"item\":\"https://docs.mirage.strukto.ai/api/operations/workspaces/list-workspaces\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Workspaces\",\"item\":\"https://docs.mirage.strukto.ai/api/operations/workspaces/list-workspaces\"},{\"@type\":\"ListItem\",\"position\":3,\"name\":\"Set a profile\",\"item\":\"https://docs.mirage.strukto.ai/api/operations/workspaces/set-a-profile\"}]},{\"@type\":[\"TechArticle\",\"APIReference\"],\"@id\":\"https://docs.mirage.strukto.ai/api/operations/workspaces/set-a-profile#apireference\",\"headline\":\"Set a profile\",\"name\":\"Set a profile\",\"description\":\"Define a named profile on the live workspace, or replace it. Only the live table changes: a session moves when it is updated onto the name, and the workspace's config is never rewritten.\",\"url\":\"https://docs.mirage.strukto.ai/api/operations/workspaces/set-a-profile\",\"mainEntityOfPage\":{\"@id\":\"https://docs.mirage.strukto.ai/api/operations/workspaces/set-a-profile#webpage\"},\"image\":\"https://raw.githubusercontent.com/strukto-ai/mirage/main/assets/mirage-og-light@2x.png\",\"dateModified\":\"2026-11-06T19:53:32.208Z\",\"publisher\":{\"@id\":\"https://docs.mirage.strukto.ai/#organization\"},\"isPartOf\":{\"@id\":\"https://docs.mirage.strukto.ai#website\"}}]}\u003c/script>\u003cscript data-mint-head type=\"application/ld+json\">{\"@context\":\"https://schema.org\",\"@type\":\"WebSite\",\"name\":\"Mirage\",\"creator\":{\"@type\":\"Organization\",\"name\":\"Mintlify\",\"url\":\"https://mintlify.com\"}}\u003c/script>","siteName":"Mirage","nav":{"global":null,"tabs":[{"tab":"Home","icon":"https://mintlify.s3.us-west-1.amazonaws.com/struktoai/images/mirage-icon-light.svg","pages":[{"title":"Home","href":"/home/introduction"}]},{"tab":"Python","icon":"https://mintlify.s3.us-west-1.amazonaws.com/struktoai/images/python-logo.svg","pages":[{"title":"Python","href":"/python/install"}]},{"tab":"TS","icon":"https://mintlify.s3.us-west-1.amazonaws.com/struktoai/images/typescript-logo.svg","pages":[{"title":"TS","href":"/typescript/install"}]},{"tab":"API","icon":"code","groups":[{"group":"HTTP API","pages":[{"title":"Overview","icon":"book-open","href":"/api/overview"},{"title":"API reference","description":"Every route of the Mirage HTTP API, generated from openapi.yaml.","icon":"list","href":"/api/reference"}]},{"group":"Operations","hidden":true,"searchable":true,"pages":[{"group":"Workspaces","pages":[{"title":"List workspaces","description":null,"deprecated":null,"version":null,"openapi":"/openapi.yaml get /v1/workspaces","href":"/api/operations/workspaces/list-workspaces"},{"title":"Create a workspace","description":"Create a workspace, or answer the live one created from this config.\n\nCreating is idempotent for one config: an id already held by a\nworkspace created from an identical config answers that workspace\nwith 200, so a client that names its workspace can run again and\nreach it; an id held by anything else is refused with 409. The\nserver's policies judge the config as written (`pre_workspace`)\nbefore any of it is built: a refusal is 403 with its reason, and\n`explain` answers what they say without creating anything.","deprecated":null,"version":null,"openapi":"/openapi.yaml post /v1/workspaces","href":"/api/operations/workspaces/create-a-workspace"},{"title":"Get a workspace","description":null,"deprecated":null,"version":null,"openapi":"/openapi.yaml get /v1/workspaces/{workspace_id}","href":"/api/operations/workspaces/get-a-workspace"},{"title":"Delete a workspace","description":null,"deprecated":null,"version":null,"openapi":"/openapi.yaml delete /v1/workspaces/{workspace_id}","href":"/api/operations/workspaces/delete-a-workspace"},{"title":"Read a workspace's history","description":"The workspace's recorded history, oldest first: a `command`\nentry for every line its sessions ran, and with `vfs` a `vfs`\nentry for every call a line made to a mount. Read on the workspace's\nown loop.","deprecated":null,"version":null,"openapi":"/openapi.yaml get /v1/workspaces/{workspace_id}/history","href":"/api/operations/workspaces/read-a-workspaces-history"},{"title":"Close a workspace","description":"Close the workspace and keep its state for the owner to reopen.","deprecated":null,"version":null,"openapi":"/openapi.yaml post /v1/workspaces/{workspace_id}/close","href":"/api/operations/workspaces/close-a-workspace"},{"title":"Cancel a workspace's lines","description":"Cancel every session's running and queued lines; all stay open.","deprecated":null,"version":null,"openapi":"/openapi.yaml post /v1/workspaces/{workspace_id}/cancel","href":"/api/operations/workspaces/cancel-a-workspaces-lines"},{"title":"Kill a workspace's jobs","description":"Kill every session's background jobs and runners.","deprecated":null,"version":null,"openapi":"/openapi.yaml post /v1/workspaces/{workspace_id}/kill","href":"/api/operations/workspaces/kill-a-workspaces-jobs"},{"title":"Set a profile","deprecated":null,"version":null,"openapi":"/openapi.yaml put /v1/workspaces/{workspace_id}/profiles/{name}","href":"/api/operations/workspaces/set-a-profile"},{"title":"Install an MCP CLI","description":"Install an MCP server as a CLI on the live workspace.\n\nThe body is one `clis:` entry, `cli: mcp` with its config, as a\nconfig file states it. Its pointers resolve and its tools are listed\nunder the workspace's network. A name already installed answers 409.","deprecated":null,"version":null,"openapi":"/openapi.yaml put /v1/workspaces/{workspace_id}/clis/{name}","href":"/api/operations/workspaces/install-an-mcp-cli"},{"title":"Remove an MCP CLI","description":"Remove an MCP CLI from the live workspace.","deprecated":null,"version":null,"openapi":"/openapi.yaml delete /v1/workspaces/{workspace_id}/clis/{name}","href":"/api/operations/workspaces/remove-an-mcp-cli"}]},{"group":"Snapshots","pages":[{"title":"Clone a workspace","description":null,"deprecated":null,"version":null,"openapi":"/openapi.yaml post /v1/workspaces/{workspace_id}/clone","href":"/api/operations/snapshots/clone-a-workspace"},{"title":"Download a snapshot","description":null,"deprecated":null,"version":null,"openapi":"/openapi.yaml get /v1/workspaces/{workspace_id}/snapshot","href":"/api/operations/snapshots/download-a-snapshot"},{"title":"Snapshot a workspace","description":null,"deprecated":null,"version":null,"openapi":"/openapi.yaml post /v1/workspaces/{workspace_id}/snapshot","href":"/api/operations/snapshots/snapshot-a-workspace"},{"title":"Load a snapshot","description":null,"deprecated":null,"version":null,"openapi":"/openapi.yaml post /v1/workspaces/load","href":"/api/operations/snapshots/load-a-snapshot"}]},{"group":"Templates","pages":[{"title":"List templates","description":"The saved templates, by name.","deprecated":null,"version":null,"openapi":"/openapi.yaml get /v1/templates","href":"/api/operations/templates/list-templates"},{"title":"Create a template","description":"Save a template: a whole workspace config, checked as a create\nchecks one, and kept as written. A name already saved is a 409.","deprecated":null,"version":null,"openapi":"/openapi.yaml post /v1/templates","href":"/api/operations/templates/create-a-template"},{"title":"Get a template","description":null,"deprecated":null,"version":null,"openapi":"/openapi.yaml get /v1/templates/{ref}","href":"/api/operations/templates/get-a-template"},{"title":"Delete a template","description":"Delete a template; `restore` brings it back.","deprecated":null,"version":null,"openapi":"/openapi.yaml delete /v1/templates/{ref}","href":"/api/operations/templates/delete-a-template"},{"title":"Restore a template","description":null,"deprecated":null,"version":null,"openapi":"/openapi.yaml post /v1/templates/{ref}/restore","href":"/api/operations/templates/restore-a-template"}]},{"group":"Documents","pages":[{"title":"Read the workspace's VFS.md","description":null,"deprecated":null,"version":null,"openapi":"/openapi.yaml get /v1/workspaces/{workspace_id}/vfs-md","href":"/api/operations/documents/read-the-workspaces-vfsmd"},{"title":"Write the workspace's VFS.md","description":null,"deprecated":null,"version":null,"openapi":"/openapi.yaml put /v1/workspaces/{workspace_id}/vfs-md","href":"/api/operations/documents/write-the-workspaces-vfsmd"},{"title":"Read a session's VFS.md","description":null,"deprecated":null,"version":null,"openapi":"/openapi.yaml get /v1/workspaces/{workspace_id}/sessions/{session_id}/vfs-md","href":"/api/operations/documents/read-a-sessions-vfsmd"},{"title":"Write a session's VFS.md","description":null,"deprecated":null,"version":null,"openapi":"/openapi.yaml put /v1/workspaces/{workspace_id}/sessions/{session_id}/vfs-md","href":"/api/operations/documents/write-a-sessions-vfsmd"},{"title":"Read the workspace's SKILL.md","description":null,"deprecated":null,"version":null,"openapi":"/openapi.yaml get /v1/workspaces/{workspace_id}/skill-md","href":"/api/operations/documents/read-the-workspaces-skillmd"},{"title":"Write the workspace's SKILL.md","description":null,"deprecated":null,"version":null,"openapi":"/openapi.yaml put /v1/workspaces/{workspace_id}/skill-md","href":"/api/operations/documents/write-the-workspaces-skillmd"},{"title":"Read a session's SKILL.md","description":null,"deprecated":null,"version":null,"openapi":"/openapi.yaml get /v1/workspaces/{workspace_id}/sessions/{session_id}/skill-md","href":"/api/operations/documents/read-a-sessions-skillmd"},{"title":"Write a session's SKILL.md","description":null,"deprecated":null,"version":null,"openapi":"/openapi.yaml put /v1/workspaces/{workspace_id}/sessions/{session_id}/skill-md","href":"/api/operations/documents/write-a-sessions-skillmd"}]},{"group":"Sessions","pages":[{"title":"List sessions","description":null,"deprecated":null,"version":null,"openapi":"/openapi.yaml get /v1/workspaces/{workspace_id}/sessions","href":"/api/operations/sessions/list-sessions"},{"title":"Create a session","description":null,"deprecated":null,"version":null,"openapi":"/openapi.yaml post /v1/workspaces/{workspace_id}/sessions","href":"/api/operations/sessions/create-a-session"},{"title":"Delete a session","description":null,"deprecated":null,"version":null,"openapi":"/openapi.yaml delete /v1/workspaces/{workspace_id}/sessions/{session_id}","href":"/api/operations/sessions/delete-a-session"},{"title":"Change a session's profile","description":"Replace the session's profile; its cwd, env and history stay.","deprecated":null,"version":null,"openapi":"/openapi.yaml patch /v1/workspaces/{workspace_id}/sessions/{session_id}","href":"/api/operations/sessions/change-a-sessions-profile"},{"title":"Cancel a session's lines","description":"Cancel the session's running and queued lines, from every entry point.\n\nThe session stays open; returns once those lines have ended.","deprecated":null,"version":null,"openapi":"/openapi.yaml post /v1/workspaces/{workspace_id}/sessions/{session_id}/cancel","href":"/api/operations/sessions/cancel-a-sessions-lines"},{"title":"Kill a session's jobs","description":"Kill the session's background jobs and runners; it stays open.","deprecated":null,"version":null,"openapi":"/openapi.yaml post /v1/workspaces/{workspace_id}/sessions/{session_id}/kill","href":"/api/operations/sessions/kill-a-sessions-jobs"}]},{"group":"Asks","pages":[{"title":"List asks","description":"The workspace's asks: pending by default, every decision under\n`all=true`. The ledger already serves both views from one store,\nso the entry point only picks which query to run.","deprecated":null,"version":null,"openapi":"/openapi.yaml get /v1/workspaces/{workspace_id}/asks","href":"/api/operations/asks/list-asks"},{"title":"Answer an ask","description":"Answer one waiting ask, allow or deny, and return the settled\nrecord. A known id with nothing waiting is 409 rather than 404, so\nan operator retrying a click reads \"already answered\", not \"not\nfound\".","deprecated":null,"version":null,"openapi":"/openapi.yaml post /v1/workspaces/{workspace_id}/asks/{ask_id}","href":"/api/operations/asks/answer-an-ask"}]},{"group":"Shell","pages":[{"title":"Run a shell line","description":null,"deprecated":null,"version":null,"openapi":"/openapi.yaml post /v1/workspaces/{workspace_id}/shell","href":"/api/operations/shell/run-a-shell-line"},{"title":"Match paths","description":"`session.glob`: every path a pattern matches, as the session\nsees them.","deprecated":null,"version":null,"openapi":"/openapi.yaml post /v1/workspaces/{workspace_id}/glob","href":"/api/operations/shell/match-paths"}]},{"group":"Tools","pages":[{"title":"Shell tool","description":null,"deprecated":null,"version":null,"openapi":"/openapi.yaml post /v1/workspaces/{workspace_id}/tools/shell","href":"/api/operations/tools/shell-tool"},{"title":"Read tool","description":null,"deprecated":null,"version":null,"openapi":"/openapi.yaml post /v1/workspaces/{workspace_id}/tools/read","href":"/api/operations/tools/read-tool"},{"title":"Write tool","description":null,"deprecated":null,"version":null,"openapi":"/openapi.yaml post /v1/workspaces/{workspace_id}/tools/write","href":"/api/operations/tools/write-tool"},{"title":"Edit tool","description":null,"deprecated":null,"version":null,"openapi":"/openapi.yaml post /v1/workspaces/{workspace_id}/tools/edit","href":"/api/operations/tools/edit-tool"},{"title":"Ls tool","description":null,"deprecated":null,"version":null,"openapi":"/openapi.yaml post /v1/workspaces/{workspace_id}/tools/ls","href":"/api/operations/tools/ls-tool"},{"title":"Grep tool","description":null,"deprecated":null,"version":null,"openapi":"/openapi.yaml post /v1/workspaces/{workspace_id}/tools/grep","href":"/api/operations/tools/grep-tool"},{"title":"Glob tool","description":null,"deprecated":null,"version":null,"openapi":"/openapi.yaml post /v1/workspaces/{workspace_id}/tools/glob","href":"/api/operations/tools/glob-tool"}]},{"group":"VFS","pages":[{"title":"VFS read","description":"Read a file's bytes, from an offset.","deprecated":null,"version":null,"openapi":"/openapi.yaml post /v1/workspaces/{workspace_id}/vfs/read","href":"/api/operations/vfs/vfs-read"},{"title":"VFS write","description":"Write a file's bytes, replacing what it held.","deprecated":null,"version":null,"openapi":"/openapi.yaml post /v1/workspaces/{workspace_id}/vfs/write","href":"/api/operations/vfs/vfs-write"},{"title":"VFS append","description":"Append bytes to a file.","deprecated":null,"version":null,"openapi":"/openapi.yaml post /v1/workspaces/{workspace_id}/vfs/append","href":"/api/operations/vfs/vfs-append"},{"title":"VFS pwrite","description":"Write bytes into a file at an offset.","deprecated":null,"version":null,"openapi":"/openapi.yaml post /v1/workspaces/{workspace_id}/vfs/pwrite","href":"/api/operations/vfs/vfs-pwrite"},{"title":"VFS stat","description":"A path's metadata.","deprecated":null,"version":null,"openapi":"/openapi.yaml post /v1/workspaces/{workspace_id}/vfs/stat","href":"/api/operations/vfs/vfs-stat"},{"title":"VFS readdir","description":"A directory's entries.","deprecated":null,"version":null,"openapi":"/openapi.yaml post /v1/workspaces/{workspace_id}/vfs/readdir","href":"/api/operations/vfs/vfs-readdir"},{"title":"VFS exists","description":"Whether a path exists.","deprecated":null,"version":null,"openapi":"/openapi.yaml post /v1/workspaces/{workspace_id}/vfs/exists","href":"/api/operations/vfs/vfs-exists"},{"title":"VFS is_dir","description":"Whether a path is a directory.","deprecated":null,"version":null,"openapi":"/openapi.yaml post /v1/workspaces/{workspace_id}/vfs/is_dir","href":"/api/operations/vfs/vfs-is_dir"},{"title":"VFS is_file","description":"Whether a path is a file.","deprecated":null,"version":null,"openapi":"/openapi.yaml post /v1/workspaces/{workspace_id}/vfs/is_file","href":"/api/operations/vfs/vfs-is_file"},{"title":"VFS list_files","description":"The names of a directory's files.","deprecated":null,"version":null,"openapi":"/openapi.yaml post /v1/workspaces/{workspace_id}/vfs/list_files","href":"/api/operations/vfs/vfs-list_files"},{"title":"VFS mkdir","description":"Make a directory.","deprecated":null,"version":null,"openapi":"/openapi.yaml post /v1/workspaces/{workspace_id}/vfs/mkdir","href":"/api/operations/vfs/vfs-mkdir"},{"title":"VFS rmdir","description":"Remove an empty directory.","deprecated":null,"version":null,"openapi":"/openapi.yaml post /v1/workspaces/{workspace_id}/vfs/rmdir","href":"/api/operations/vfs/vfs-rmdir"},{"title":"VFS unlink","description":"Remove a file.","deprecated":null,"version":null,"openapi":"/openapi.yaml post /v1/workspaces/{workspace_id}/vfs/unlink","href":"/api/operations/vfs/vfs-unlink"},{"title":"VFS create","description":"Create an empty file.","deprecated":null,"version":null,"openapi":"/openapi.yaml post /v1/workspaces/{workspace_id}/vfs/create","href":"/api/operations/vfs/vfs-create"},{"title":"VFS rename","description":"Rename a path within its mount.","deprecated":null,"version":null,"openapi":"/openapi.yaml post /v1/workspaces/{workspace_id}/vfs/rename","href":"/api/operations/vfs/vfs-rename"},{"title":"VFS symlink","description":"Make a symbolic link at a path.","deprecated":null,"version":null,"openapi":"/openapi.yaml post /v1/workspaces/{workspace_id}/vfs/symlink","href":"/api/operations/vfs/vfs-symlink"},{"title":"VFS readlink","description":"Where a symbolic link points.","deprecated":null,"version":null,"openapi":"/openapi.yaml post /v1/workspaces/{workspace_id}/vfs/readlink","href":"/api/operations/vfs/vfs-readlink"},{"title":"VFS setattr","description":"Change a path's mode, owner or times.","deprecated":null,"version":null,"openapi":"/openapi.yaml post /v1/workspaces/{workspace_id}/vfs/setattr","href":"/api/operations/vfs/vfs-setattr"},{"title":"VFS getxattr","description":"One extended attribute's value.","deprecated":null,"version":null,"openapi":"/openapi.yaml post /v1/workspaces/{workspace_id}/vfs/getxattr","href":"/api/operations/vfs/vfs-getxattr"},{"title":"VFS listxattr","description":"A path's extended attribute names.","deprecated":null,"version":null,"openapi":"/openapi.yaml post /v1/workspaces/{workspace_id}/vfs/listxattr","href":"/api/operations/vfs/vfs-listxattr"},{"title":"VFS setxattr","description":"Set an extended attribute.","deprecated":null,"version":null,"openapi":"/openapi.yaml post /v1/workspaces/{workspace_id}/vfs/setxattr","href":"/api/operations/vfs/vfs-setxattr"},{"title":"VFS removexattr","description":"Remove an extended attribute.","deprecated":null,"version":null,"openapi":"/openapi.yaml post /v1/workspaces/{workspace_id}/vfs/removexattr","href":"/api/operations/vfs/vfs-removexattr"},{"title":"VFS truncate","description":"Cut or extend a file to a length.","deprecated":null,"version":null,"openapi":"/openapi.yaml post /v1/workspaces/{workspace_id}/vfs/truncate","href":"/api/operations/vfs/vfs-truncate"},{"title":"Call any VFS function","description":"Call a declared VFS function using the ordinary session and policy gate.","deprecated":null,"version":null,"openapi":"/openapi.yaml post /v1/workspaces/{workspace_id}/vfs/{name}","href":"/api/operations/vfs/call-any-vfs-function"}]},{"group":"Server","pages":[{"title":"Check health","description":null,"deprecated":null,"version":null,"openapi":"/openapi.yaml get /v1/health","href":"/api/operations/server/check-health"},{"title":"Check readiness","description":"Whether the server takes new workspaces: 503 while it drains for\nshutdown or holds `max_workspaces`, so a load balancer sends new\nwork elsewhere. `/v1/health` only says the process is up.","deprecated":null,"version":null,"openapi":"/openapi.yaml get /v1/ready","href":"/api/operations/server/check-readiness"},{"title":"Shut down the server","description":"Trip the exit event, which the app's `on_idle_exit` acts on.\n\nThe daemon's hook sends SIGTERM to its own process, so uvicorn runs\nits graceful shutdown (close connections, run the lifespan's finally\nblock). An app run without a hook keeps serving. The server serves\nevery account, so an account may not stop it.","deprecated":null,"version":null,"openapi":"/openapi.yaml post /v1/shutdown","href":"/api/operations/server/shut-down-the-server"}]},{"group":"Auth","pages":[{"title":"Read OAuth protected-resource metadata","description":"Say where to log in, for `mirage login`.\n\nRFC 9728's protected resource metadata names the issuer, and\n`client_id` the OAuth client the CLI signs in as. A server that\npublishes no login answers 404, so the CLI knows it needs none.","deprecated":null,"version":null,"openapi":"/openapi.yaml get /.well-known/oauth-protected-resource","href":"/api/operations/auth/read-oauth-protected-resource-metadata"}]},{"group":"Saved VFS","pages":[{"title":"List VFS configs","description":"The saved VFS configs: a mount's type and fields, kept by name for templates to use.","deprecated":null,"version":null,"openapi":"/openapi.yaml get /v1/vfs","href":"/api/operations/saved-vfs/list-vfs-configs"},{"title":"Create a VFS config","description":"Save a VFS config. Its fields are checked against the type's; secret fields are sealed, and a string field may point at a saved store's secret instead. A name already saved is a 409.","deprecated":null,"version":null,"openapi":"/openapi.yaml post /v1/vfs","href":"/api/operations/saved-vfs/create-a-vfs-config"},{"title":"List VFS config types","description":"Every type a VFS config can be, with the fields its config takes.","deprecated":null,"version":null,"openapi":"/openapi.yaml get /v1/vfs/types","href":"/api/operations/saved-vfs/list-vfs-config-types"},{"title":"Get a VFS config","description":"One saved VFS config, with its sealed fields named but not answered.","deprecated":null,"version":null,"openapi":"/openapi.yaml get /v1/vfs/{ref}","href":"/api/operations/saved-vfs/get-a-vfs-config"},{"title":"Update a VFS config","description":"Change a VFS config's fields. Its name and type stay; a sealed field left out keeps its value.","deprecated":null,"version":null,"openapi":"/openapi.yaml put /v1/vfs/{ref}","href":"/api/operations/saved-vfs/update-a-vfs-config"},{"title":"Delete a VFS config","description":"Delete a saved VFS config.","deprecated":null,"version":null,"openapi":"/openapi.yaml delete /v1/vfs/{ref}","href":"/api/operations/saved-vfs/delete-a-vfs-config"}]},{"group":"Saved CLIs","pages":[{"title":"List CLI configs","description":"The saved CLI configs: a CLI install's type and fields, kept by name for templates to use.","deprecated":null,"version":null,"openapi":"/openapi.yaml get /v1/clis","href":"/api/operations/saved-clis/list-cli-configs"},{"title":"Create a CLI config","description":"Save a CLI config. Its fields are checked against the type's; secret fields are sealed, and a string field may point at a saved store's secret instead. A name already saved is a 409.","deprecated":null,"version":null,"openapi":"/openapi.yaml post /v1/clis","href":"/api/operations/saved-clis/create-a-cli-config"},{"title":"List CLI config types","description":"Every type a CLI config can be, with the fields its config takes.","deprecated":null,"version":null,"openapi":"/openapi.yaml get /v1/clis/types","href":"/api/operations/saved-clis/list-cli-config-types"},{"title":"Get a CLI config","description":"One saved CLI config, with its sealed fields named but not answered.","deprecated":null,"version":null,"openapi":"/openapi.yaml get /v1/clis/{ref}","href":"/api/operations/saved-clis/get-a-cli-config"},{"title":"Update a CLI config","description":"Change a CLI config's fields. Its name and type stay; a sealed field left out keeps its value.","deprecated":null,"version":null,"openapi":"/openapi.yaml put /v1/clis/{ref}","href":"/api/operations/saved-clis/update-a-cli-config"},{"title":"Delete a CLI config","description":"Delete a saved CLI config.","deprecated":null,"version":null,"openapi":"/openapi.yaml delete /v1/clis/{ref}","href":"/api/operations/saved-clis/delete-a-cli-config"}]},{"group":"Saved runtimes","pages":[{"title":"List runtime configs","description":"The saved runtime configs: a runtime's type and fields, kept by name for templates to use.","deprecated":null,"version":null,"openapi":"/openapi.yaml get /v1/runtimes","href":"/api/operations/saved-runtimes/list-runtime-configs"},{"title":"Create a runtime config","description":"Save a runtime config. Its fields are checked against the type's; secret fields are sealed, and a string field may point at a saved store's secret instead. A name already saved is a 409.","deprecated":null,"version":null,"openapi":"/openapi.yaml post /v1/runtimes","href":"/api/operations/saved-runtimes/create-a-runtime-config"},{"title":"List runtime config types","description":"Every type a runtime config can be, with the fields its config takes.","deprecated":null,"version":null,"openapi":"/openapi.yaml get /v1/runtimes/types","href":"/api/operations/saved-runtimes/list-runtime-config-types"},{"title":"Get a runtime config","description":"One saved runtime config, with its sealed fields named but not answered.","deprecated":null,"version":null,"openapi":"/openapi.yaml get /v1/runtimes/{ref}","href":"/api/operations/saved-runtimes/get-a-runtime-config"},{"title":"Update a runtime config","description":"Change a runtime config's fields. Its name and type stay; a sealed field left out keeps its value.","deprecated":null,"version":null,"openapi":"/openapi.yaml put /v1/runtimes/{ref}","href":"/api/operations/saved-runtimes/update-a-runtime-config"},{"title":"Delete a runtime config","description":"Delete a saved runtime config.","deprecated":null,"version":null,"openapi":"/openapi.yaml delete /v1/runtimes/{ref}","href":"/api/operations/saved-runtimes/delete-a-runtime-config"}]},{"group":"Policies","pages":[{"title":"List policies","description":"The saved policies' names, sorted. Get one for its source.","deprecated":null,"version":null,"openapi":"/openapi.yaml get /v1/policies","href":"/api/operations/policies/list-policies"},{"title":"Create a policy","description":"Save a policy program, by name. A name already saved is a 409.","deprecated":null,"version":null,"openapi":"/openapi.yaml post /v1/policies","href":"/api/operations/policies/create-a-policy"},{"title":"Get a policy","description":"One saved policy, with its source.","deprecated":null,"version":null,"openapi":"/openapi.yaml get /v1/policies/{ref}","href":"/api/operations/policies/get-a-policy"},{"title":"Update a policy","description":"Replace a saved policy's source.","deprecated":null,"version":null,"openapi":"/openapi.yaml put /v1/policies/{ref}","href":"/api/operations/policies/update-a-policy"},{"title":"Delete a policy","description":"Delete a saved policy.","deprecated":null,"version":null,"openapi":"/openapi.yaml delete /v1/policies/{ref}","href":"/api/operations/policies/delete-a-policy"}]}]}]}]},"basePath":"","title":"Set a profile - Mirage","buildId":"dpl_8LJbrAiZvr1K98WQNZXCyY5AvT34","deploymentId":"dpl_8LJbrAiZvr1K98WQNZXCyY5AvT34","dynamics":["c2aa737661","2b790eda92","b0f84f53ff","a9bb46feb3"],"chunks":["OpenApiReferenceProvider-i2a3QZ8E.js","utils-ChLwp8m0.js","cloneDeep-izs3Hzxb.js","_Uint8Array-BVIqJ90l.js","isObjectLike-C8vmzPEN.js","isArray-Dcu1dQ5t.js","utils-DRktVTDc.js","toString-BX-iyh8G.js","isSymbol-CSH9U2Gm.js","addUniqueKeysToSchema-CA2pEs4T.js","snippetPresets-ClQ6XrKD.js","style-to-object-BY3JEAdk.js","v4-DIgz8zy6.js","ApiExamples-Ct_Lv36y.js","isEqual-BfaiBbcl.js","usePlaygroundInputsStore-Cn2PYw9e.js","shallow-rkyymjXQ.js","getApiPlaygroundDisplay-BB9vkXtE.js","CodeSnippet-Bm5RU7m1.js","CodeSnippets-BgU9Deuz.js","Page-BUDYNlhG.js","getPastedJson-BD-6NNum.js","icon-8Z6tud2e.js","MethodPill-Tuzr4g3V.js","DuplicateIcon-0ceWFYhN.js","createIcon-FBXow_ST.js","DynamicMarkdown-CD8713Yy.js","SectionHeading-7zgzQbH-.js","axios-vUo_bRtp.js","Markdown-D7Ofw1oz.js","clsx-eKJ4rcii.js","lib-DuNMoZ05.js","lib-B8HbPgcC.js","html-void-elements-mCSPHezU.js","dist-CwjSCXIK.js","katex-YMM-FMeD.js","marked.esm-CZWythHk.js","AssistantPageLink-9EK5IAXV.js"]}