Skip to content

Mirage 0.0.6

Latest

Choose a tag to compare

@zechengz zechengz released this 03 Sep 16:25
· 61 commits to main since this release
5678c94

We are excited to announce the release of Mirage 0.0.6 πŸŽ‰πŸŽ‰πŸŽ‰

Mirage 0.0.6 is a permissions release. 0.0.5 gave an agent typed programs to act with; 0.0.6 decides what it may do with them. A permissions document replaces the old guard list: allow, ask and deny rules, one role per session, mounts that narrow rather than gate, hidden subtrees that stay hidden through a mutation, an approval door where an asked line reaches a person, and a decision ledger you can query and explain. A policy can now be a program, written in Python or JavaScript and judged at the command, op and session doors. Credentials move behind a secrets plane instead of sitting in a config block. Underneath, a long deduplication pass collapses the backends onto shared HTTP, object-store, hierarchy and render kits, the integration fakes become one TypeScript and Prisma kit that runs off a laptop, bash grows most of tiers 2 and 3, guests see one filesystem through a single stat struct, and Hugging Face Hub arrives as both a mount and a CLI. Python and TypeScript stay mirrored throughout.

pip install mirage-ai==0.0.6 Β· npm install @struktoai/mirage-core@0.0.6 (and -node, -browser, -server, -cli, -agents)

@struktoai/mirage-dsh joins the shared version line at 0.0.6. It was published once as 0.0.1; the versions between were never released.

Highlights

  • Permissions are a document, not a guard list. A permissions document with profiles replaces the guards (#857), carrying allow, ask and deny rules with an approval door where an asked line reaches a person (#865). A session holds one role, and a mount narrows what that role may reach instead of gating it (#876). The path axis gained show entries, per-subtree modes and hide reasons (#896), and a mutation below a hidden path resolves without revealing it (#901). Every decision lands in a ledger with explain and whole-line judging (#880), reachable through an asks door and workspace-level list-asks, allow and deny (#899). Documented, with (approval <id>) renamed (ask <id>) (#900).
  • A profile's policy can be a program. A profile takes a script rather than only coded rules (#884), and the policy block's program defines which gate hooks exist: pre_command, pre_ops and pre_session, probed once per program text, with a hook left out meaning silence and none at all failing closed (#997). The op-door boundary is stated and pinned (#908), coded pre_ops binds on the command tier (#909), and dsh routes allow, ask and deny through its own approval channel (#890).
  • Credentials live on a secrets plane. Env-plane managed credentials arrive first (#960), then a config plane and a 1Password source (#973), and finally a mount or CLI credential that reads from that plane rather than holding the value (#978). Alongside it, every TypeScript mount config now validates through one door, with the two languages' field sets gated against each other (#994).
  • The backends collapse onto shared kits. One HTTP client kit with notion and discord as exemplars (#835), then every hand-rolled client onto it (#841). One JSON render kit for .json and .jsonl bodies (#823). An object-store kit and a hierarchy kit (#848), taking hf and opfs (#858), postgres, mongodb and the google trio (#868), trello, linear, notion and gcal (#870), discord, slack, gmail and email (#874), and lancedb and qdrant with per-mount routes (#875). The 42 S3-alias resources collapse onto a shared base (#866), and a TypeScript backend is assembled from one CommandIO table (#883).
  • The integration fakes are one TypeScript and Prisma kit. The mock servers unify (#916) and the services follow: dropbox, box and onedrive (#919), slack, notion and mem0 (#925), the hf buckets (#927), databricks, dify and http (#928), and github (#935). They can run somewhere other than a developer's laptop (#905), a run axis rides the URL so two hosts stop sharing one world (#945, #946, #947), and one launcher hosts them all behind pooled sessions (#965).
  • Hugging Face Hub is a mount and a CLI. A Hub repo mounts, with the hf CLI beside it (#931), exercised against a fake in CI (#934), read-only by default (#937), and serving Hub metadata and search (#939). The fake answers hf_fs errors the way the live server does (#974), advertises the discovery scopes it claims (#982), serves hf://README.md because the tool document tells the model to read it (#976) and /raw/ (#979).
  • bash tiers 2 and 3. The export attribute and identifier validation (#816); associative arrays, declare attributes, readonly -f and the jobs flags (#824); then let, umask, shopt, alias, mapfile, the read flags, declare -g/-n, disown/wait and exec (#833).
  • Guests see one filesystem. Every path-taking os verb routes through the workspace (#877), symlink, readlink and setattr are served (#879), a readdir row carries the link mark (#881), and one stat struct sits at the runtime door with each surface projecting it (#882). Engines and sandbox SDKs are upgraded with the monty Python and TypeScript guest-behavior gaps closed (#904), and the history view and root anchor are withheld from runtimes (#932). Two new providers: a smolvm microVM and a confined sandlock Python runtime (#834), and ssh (#852).
  • Errors say what the kernel would say. A prefix holding no keys is ENOENT rather than an empty directory (#809, #815), a path under a file is ENOTDIR rather than ENOENT (#813), a directory read carries GNU's errno and exit code (#895), rmdir refuses a non-empty directory at the op rather than only in the builder (#854), and every refusal now speaks bash's Permission denied instead of each command's own wording (#993).
  • Redis reaches the browser through Upstash's REST API, so a browser workspace can use the same cache and store as node (#992).

Breaking Changes

  • Guards are gone. The permissions document and its profiles replace them (#857); a session holds one role and a mount narrows rather than gates (#876).
  • build_resource is synchronous again (#820), reversing the 0.0.5 change; github hydrates lazily instead. Code written against 0.0.5's await build_resource(...) drops the await.
  • FileType is the node kind, and content type is its own axis (#878).
  • core is imported by module path. index.ts drops from 1589 lines to 102, so a deep import replaces the barrel (#805), and the dead exports around it are swept (#814).
  • Builtin commands are per-command packages behind a BUILTINS table with tiers (#853).
  • ls -l reports the workspace user as owner and the session profile as group (#985).
  • A Hub mount is read-only (#937).
  • /dev/null and /dev/zero are character devices, not regular files (#910).
  • getState/loadState sit on the TypeScript Resource contract, mirroring Python's base (#800).
  • Routing is renamed and execution passes through an ExecContext seam (#944).
  • @struktoai/mirage-dsh moves from its own version line onto the shared one, from 0.0.1 to 0.0.6 (#998).

Features

  • permissions: the document and profiles (#857); allow, ask and deny with an approval door (#865); one role per session (#876); the path axis, per-subtree modes and hide reasons (#896); the asks door and workspace list-asks/allow/deny (#899).
  • policy: decision ledger, explain and whole-line judging (#880); profiles written by a script (#884); a policy block whose program defines the gate's hooks (#997).
  • secrets: env-plane managed credentials (#960); config plane and 1Password source (#973); mount and CLI credentials read from the plane (#978).
  • cli: virtual gh workflows (#915); builtin command catalogs (#929); custom authoring made first-class (#950) with an example (#940) and specs validated at construction (#933); the hf CLI (#931).
  • shell: bash tier 2 stage 1 (#816); associative arrays, declare attributes, readonly -f, jobs flags (#824); let, umask, shopt, alias, mapfile, read flags, declare -g/-n, disown/wait, exec (#833).
  • runtime: smolvm microVM and confined sandlock Python (#834); the ssh sandbox provider (#852); every engine and sandbox SDK upgraded (#904).
  • resource: a Hugging Face Hub mount (#931, #937, #939); Redis in the browser over Upstash (#992); mount parents, kit backend ops and a resource class reference (#887).
  • core: optional byte-range reads across backends (#810).
  • watch: delta_hook for ten more backends (#811); push event mapping and subtree invalidation (#817).
  • integ: a restricted-token GitHub fake, gh api --jq and notion retrieve-block (#819); branch history recorded when a ref moves (#969); the kit migration (#916, #919, #925, #927, #928, #935) and the run axis (#945, #946, #947, #965).

Bugfixes

  • cache: a rename evicts the destination's own listing, across thirteen backends, with disk Windows separators and databricks copy invalidation (#802); a recursive delete or directory rename evicts its subtree (#864, #863); the cache manager walks the ancestor chain (#838); the Redis file cache add is atomic (#830).
  • errors: a prefix with no keys is ENOENT (#809, #815); a path under a file is ENOTDIR (#813); a directory read uses GNU's errno and exit code (#895); rmdir refuses at the op (#854).
  • ls: a cross-mount listing is relayed so GNU headers and the global sort survive (#844); a nested mount's root is listed in its parent's -R listing (#847).
  • rename: directories move whole, on every backend that fakes them (#808).
  • search: the grep and rg push-downs are gated on operand count (#851), and the remaining find push-downs with them (#856).
  • shell: an orphaned $var expands in a redirect target, and record is forwarded through the daemon (#926); the tree-sitter engine boots once (#912).
  • naming: every <label>__<id> name is budgeted in bytes, not characters (#885); the gmail excerpt and daemon description budgets are measured in code points (#871).
  • backends: box rename and copy refuse a destination they were destroying (#898); the dropbox emptiness probe bounds its walk (#860) and stat and du stop laundering a listing 5xx into a false ENOENT (#963); postgres refuses a readdir on a schema that does not exist (#894); sharepoint scopes the site and drive id cache to the accessor (#988); the browser presigned S3 client refuses a version-pinned read (#840); discord fixes dirname-parsed scope, tombstoned attachments and date-less grep paths (#797); a glob narrows a windowed listing instead of filtering it (#902).
  • fuse: a driverless machine is told which driver to install (#862), and an OSError is caught when mfusepy cannot find libfuse (#829).
  • runtime: /dev/stderr stays alive so a python timeout cannot kill the host (#922).
  • namespace: every namespace-table write is gated on its session's grant (#943).
  • parity: github ref default, NAME_MAX byte budget, the browser registry on node's config shape (#873); trello write guards, fenced revisions, browser ambient fallback (#938); the two hosts' extension surfaces aligned (#986).
  • corpus: ten agent-corpus defects across sed, awk, date, find and the fakes (#822); tar and unzip member selectors, relay extraction, grep file filters and direct path execution (#821).
  • security: fast-uri, fastify and qs advisories (#991), deepmerge-ts raised to 8 (#845), and the deepagents floor raised to what the API backend needs (#826).

Changes

  • layout: module homes and workspace/config placement (#837); constants in constants and shapes in types (#936); helpers split by concern with the Python and TypeScript symbols converged (#942); find strict numerics, tar and git constants, and the parse_flags convention (#948).
  • cleanup: the 37-item plan closed with the printf engine split (#843), then execute_node split, candidates() deleted and the integ facets landed (#849); the nested-function rule, layout parity, ts-audit and ls facets (#831); dead code removed behind an optional deadcode dependency (#980); survivor renames across github, gcal, msgraph, sharepoint and mem0 (#827); duplicated config, sanitizer, render and drive-op bodies collapsed (#869); the browser resource layer inherits BaseResource (#872).
  • ci: TypeScript is bootstrapped once and its dist reused (#889); pytest runs under xdist (#892) without coverage on every invocation (#913); mypy is cached (#917); example checks run concurrently (#918); Ruff replaces flake8 and autoflake (#924); pre-commit hook environments are cached (#954); three fixed costs leave the integ workflow (#941); the two integ CLI hosts run concurrently (#842); examples/typescript is typechecked (#812); a script refuses to run against a stale node_modules (#832).
  • integ: the truth txt files are retired for JSON (#839).
  • observe: op timing is owned in the record path (#968).
  • docs: the navigation is restructured (#903); the architecture figure is redrawn and the READMEs rewritten (#975, #964, #977); sandbox runtime documentation is organized (#850); upstream CLI projects and licenses are credited (#966); a Haystack integration page (#828); how a view reaches a handler, with the opt-in helper deleted (#930); the permissions system (#900); CLI page icons, frontmatter and the removed filetype renderers (#801, #803, #804, #806, #807).

Contributors

@zechengz, @bytecii, @sonhmai, @Beverly621, @Jackpkn

New Contributors

Full Changelog: v0.0.5...v0.0.6