--- title: TypeScript Quickstart icon: /images/typescript-logo.svg description: Create a Mirage TypeScript workspace, mount RAM as a virtual filesystem, and run shell commands with @struktoai/mirage-node. keywords: ["Mirage TypeScript quickstart", "@struktoai/mirage-node", "virtual filesystem", "AI agents", "shell commands"] --- ## Installation Install the Node runtime: ```bash pnpm add @struktoai/mirage-node pnpm add -D tsx typescript ``` `npm install @struktoai/mirage-node` and `yarn add @struktoai/mirage-node` work too. ## Create a Workspace Start with the RAM resource so you can try Mirage without credentials. ```ts import { MountMode, RAMResource, Workspace } from '@struktoai/mirage-node' async function main(): Promise { const ws = new Workspace({ '/data': new RAMResource() }, { mode: MountMode.WRITE }) await ws.execute('echo "hello mirage" | tee /data/hello.txt') const result = await ws.execute('cat /data/hello.txt') process.stdout.write(result.stdoutText) await ws.close() } main() ``` Run it: ```bash pnpm tsx quickstart.ts ``` ## Run Commands Once a resource is mounted, you can use Mirage like a shell over your virtual filesystem: ```ts import { MountMode, RAMResource, Workspace } from '@struktoai/mirage-node' async function main(): Promise { const ws = new Workspace({ '/data': new RAMResource() }, { mode: MountMode.WRITE }) await ws.execute(`echo '{"name": "alice"}' | tee /data/user.json`) const files = await ws.execute('ls /data/') process.stdout.write(files.stdoutText) const name = await ws.execute('jq ".name" /data/user.json') process.stdout.write(name.stdoutText) const match = await ws.execute('grep alice /data/user.json') process.stdout.write(match.stdoutText) await ws.close() } main() ``` ## Estimate Before You Run `execute(..., { provision: true })` returns a `ProvisionResult` instead of running the command: network/cache bytes, read ops, and a `precision` telling you how much to trust the numbers (`exact`, `range`, `unknown` -- totals under `unknown` are floors). Pipelines, `&&`/`||`, `if`/`case`, loops, and subshells aggregate automatically. ```ts const plan = await ws.execute('cat /data/user.json | wc -l', { provision: true }) console.log(plan.networkRead, plan.readOps, plan.precision) ``` Read commands are estimated out of the box on every backend. When you register your own command, pass `provision:` to `command({...})` (reuse a helper like `makeFileReadProvision(myStat)` or `defaultProvision(name, myStat)`, or wrap a bespoke command list with `withDefaultProvisions(commands, myStat)`), or omit it and the planner reports `unknown`. Full semantics live in the [CLI provision docs](/home/cli#5-dry-run-with-provision). ## Output Safeguards To keep huge reads from flooding an agent, `cat`, `grep`, `rg`, `head`, and `tail` cap their **final** output at 2000 lines by default. When a cap fires, the agent sees the truncated bytes plus a stderr notice (`output truncated at safeguard limit (2000 lines); ...`); the exit code stays 0. Caps fire only on the **terminal** command of a pipeline, so `cat big.txt | head -n 30` still shows 30 lines. ### Configure per mount Pass a `commandSafeguards` option keyed by mount prefix, then command. Each `CommandSafeguard` sets `maxLines` / `maxBytes` (output cap) and/or `timeoutSeconds` (deadline); `onExceed` is `TRUNCATE` (default, exit 0 plus notice) or `ERROR` (exit 1 plus notice): ```ts import { CommandSafeguard, MountMode, OnExceed, RAMResource, Workspace, } from '@struktoai/mirage-node' const ws = new Workspace( { '/data': new RAMResource() }, { mode: MountMode.WRITE, commandSafeguards: { '/data': { head: new CommandSafeguard({ maxLines: 100 }), // cap, keep going grep: new CommandSafeguard({ maxLines: 50, onExceed: OnExceed.ERROR }), rg: new CommandSafeguard({ timeoutSeconds: 30 }), // deadline }, }, }, ) ``` The same limits are available to the CLI as a `command_safeguards` block in the workspace YAML. ## Next Steps - See [TypeScript Installation](/typescript/install) for optional native peers (FUSE, Redis, Postgres, MongoDB, SSH, Email). - Browse [TypeScript Agents](/typescript/agents/index) to wire Mirage into OpenAI Agents SDK, Vercel AI SDK, LangChain, Mastra, and more. - Pick a real backend from the Resources section, such as [S3](/typescript/setup/s3), [Slack](/typescript/slack), or [Discord](/typescript/discord).