{"id":48946554,"url":"https://github.com/tigrisdata/agent-shell","last_synced_at":"2026-04-21T21:01:04.868Z","repository":{"id":351594083,"uuid":"1211398569","full_name":"tigrisdata/agent-shell","owner":"tigrisdata","description":"A virtual bash environment for AI agents, backed by Tigris object storage","archived":false,"fork":false,"pushed_at":"2026-04-20T13:24:41.000Z","size":306,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-04-20T20:02:57.749Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/tigrisdata.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-04-15T11:00:00.000Z","updated_at":"2026-04-20T13:24:46.000Z","dependencies_parsed_at":"2026-04-20T20:00:51.733Z","dependency_job_id":null,"html_url":"https://github.com/tigrisdata/agent-shell","commit_stats":null,"previous_names":["tigrisdata/agent-shell"],"tags_count":5,"template":false,"template_full_name":null,"purl":"pkg:github/tigrisdata/agent-shell","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tigrisdata%2Fagent-shell","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tigrisdata%2Fagent-shell/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tigrisdata%2Fagent-shell/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tigrisdata%2Fagent-shell/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/tigrisdata","download_url":"https://codeload.github.com/tigrisdata/agent-shell/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tigrisdata%2Fagent-shell/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32110137,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-21T11:25:29.218Z","status":"ssl_error","status_checked_at":"2026-04-21T11:25:28.499Z","response_time":128,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-04-17T17:01:14.444Z","updated_at":"2026-04-21T21:01:04.810Z","avatar_url":"https://github.com/tigrisdata.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# @tigrisdata/agent-shell\n\nPersistent sandboxed storage for AI agents — a bash filesystem backed by [Tigris](https://www.tigrisdata.com/) object storage.\n\nAI agents produce artifacts — reports, data, configs, logs. These need to go somewhere durable, shareable, and globally accessible. `@tigrisdata/agent-shell` gives agents a familiar bash interface (`cat`, `grep`, `sed`, `jq`, `awk`, pipes, redirects) where every file operation is backed by a Tigris bucket.\n\n**What makes it a storage sandbox:**\n\n- **Isolated** — writes stay in-memory until you explicitly flush. No partial state leaks to storage.\n- **Durable** — flush persists files to Tigris, globally distributed.\n- **Checkpointable** — take snapshots of your storage at any point. Roll back if needed.\n- **Forkable** — create copy-on-write forks of a bucket for safe experimentation.\n- **Shareable** — generate presigned URLs for any stored file.\n\nBuilt on [just-bash](https://github.com/vercel-labs/just-bash) for the shell engine and [@tigrisdata/storage](https://www.npmjs.com/package/@tigrisdata/storage) for the storage layer.\n\n## Quick Start\n\n```bash\nnpm install @tigrisdata/agent-shell\n```\n\n```typescript\nimport { TigrisShell } from \"@tigrisdata/agent-shell\";\n\nconst shell = new TigrisShell({\n  bucket: process.env.TIGRIS_STORAGE_BUCKET,\n  accessKeyId: process.env.TIGRIS_STORAGE_ACCESS_KEY_ID,\n  secretAccessKey: process.env.TIGRIS_STORAGE_SECRET_ACCESS_KEY,\n});\n\nawait shell.exec('echo \"Hello world\" \u003e greeting.txt');\nawait shell.exec(\"cat greeting.txt\"); // stdout: \"Hello world\\n\"\nawait shell.exec(\"mkdir -p reports/2026\");\nawait shell.exec('echo \"Q1 done\" \u003e reports/2026/q1.txt');\nawait shell.exec(\"ls reports/2026\"); // stdout: \"q1.txt\\n\"\nawait shell.exec(\"cat greeting.txt | tr a-z A-Z\"); // stdout: \"HELLO WORLD\\n\"\n\n// Persist to Tigris when you're ready\nawait shell.flush();\n```\n\n## Authentication\n\nAll three fields are required — bucket, access key, and secret key:\n\n```typescript\nconst shell = new TigrisShell({\n  bucket: process.env.TIGRIS_STORAGE_BUCKET,\n  accessKeyId: process.env.TIGRIS_STORAGE_ACCESS_KEY_ID,\n  secretAccessKey: process.env.TIGRIS_STORAGE_SECRET_ACCESS_KEY,\n});\n```\n\n## Storage Sandbox Model\n\nThe shell uses an in-memory write-back cache that acts as a storage sandbox:\n\n```\nAgent writes file  →  cached locally (isolated)\nAgent reads file   →  cache hit or fetch from Tigris\nAgent calls flush  →  all changes persisted atomically\n```\n\nThis gives you:\n\n- **Isolation** — nothing touches storage until you say so\n- **Atomic commits** — if your agent fails midway, no partial state is written\n- **Fast execution** — most operations never hit the network\n\n```typescript\nconst shell = new TigrisShell({\n  bucket: process.env.TIGRIS_STORAGE_BUCKET,\n  accessKeyId: process.env.TIGRIS_STORAGE_ACCESS_KEY_ID,\n  secretAccessKey: process.env.TIGRIS_STORAGE_SECRET_ACCESS_KEY,\n});\n\ntry {\n  await shell.exec('echo \"processing...\" \u003e status.txt');\n  await shell.exec(\"echo '{\\\"score\\\": 0.95}' \u003e results.json\");\n  await shell.exec(\"cat results.json | jq .score\"); // \"0.95\\n\"\n\n  // Only persist on success\n  await shell.flush();\n} catch (e) {\n  // Nothing was written to Tigris — storage is clean\n}\n```\n\n## Shell Options\n\nThe second argument configures shell behavior:\n\n```typescript\nconst shell = new TigrisShell(\n  {\n    bucket: process.env.TIGRIS_STORAGE_BUCKET,\n    accessKeyId: process.env.TIGRIS_STORAGE_ACCESS_KEY_ID,\n    secretAccessKey: process.env.TIGRIS_STORAGE_SECRET_ACCESS_KEY,\n  },\n  {\n    cwd: \"/workspace\", // Starting directory (default: /workspace)\n    env: { DEBUG: \"true\" }, // Initial environment variables\n  }\n);\n```\n\n## Built-in Tigris Commands\n\nIn addition to all standard bash commands from [just-bash](https://github.com/vercel-labs/just-bash), the shell includes Tigris-specific commands:\n\n### presign\n\nGenerate presigned URLs for sharing or uploading.\n\n```bash\npresign /path/to/file.txt                    # GET URL, 1 hour expiry\npresign /path/to/file.txt --expires 7200     # GET URL, 2 hour expiry\npresign /path/to/file.txt --put              # PUT URL for uploads\n```\n\n### snapshot\n\nCheckpoint your dataset. Create or list point-in-time bucket snapshots.\n\n```bash\nsnapshot my-bucket                           # Create a snapshot\nsnapshot my-bucket --name \"checkpoint-1\"     # Create a named snapshot\nsnapshot my-bucket --list                    # List all snapshots\n```\n\n### fork\n\nBranch your dataset. Create a copy-on-write fork for safe experimentation.\n\n```bash\nfork source-bucket my-fork                   # Fork a bucket\nfork source-bucket my-fork --snapshot 1713200000   # Fork from a specific snapshot\n```\n\n### forks\n\nList forks of a bucket.\n\n```bash\nforks my-bucket\n```\n\n### bundle\n\nBatch-download multiple files as a tar archive.\n\n```bash\nbundle file1.txt file2.txt                   # Download as tar\nbundle file1.txt file2.txt --gzip           # Download as gzip tar\nbundle file1.txt file2.txt --zstd           # Download as zstd tar\n```\n\n## Advanced: Compose with just-bash\n\nFor more control, import `TigrisAdapter` and the commands separately to build your own storage layout. This is useful when you need multiple buckets mounted at different paths.\n\n```typescript\nimport { Bash, MountableFs, InMemoryFs } from \"just-bash\";\nimport { TigrisAdapter } from \"@tigrisdata/agent-shell/fs\";\nimport { createTigrisCommands } from \"@tigrisdata/agent-shell/commands\";\n\nconst auth = {\n  accessKeyId: process.env.TIGRIS_STORAGE_ACCESS_KEY_ID,\n  secretAccessKey: process.env.TIGRIS_STORAGE_SECRET_ACCESS_KEY,\n};\n\nconst workspaceConfig = { bucket: \"agent-workspace\", ...auth };\nconst datasetsConfig = { bucket: \"shared-datasets\", ...auth };\n\n// Build your own storage layout\nconst fs = new MountableFs({ base: new InMemoryFs() });\nfs.mount(\"/workspace\", new TigrisAdapter(workspaceConfig));\nfs.mount(\"/datasets\", new TigrisAdapter(datasetsConfig));\n\nconst bash = new Bash({\n  fs,\n  cwd: \"/workspace\",\n  customCommands: [\n    ...createTigrisCommands(workspaceConfig),\n    // your own custom commands\n  ],\n});\n\nawait bash.exec(\"cat /datasets/training/labels.csv | head -10\");\nawait bash.exec(\"cp /datasets/training/labels.csv ./local-copy.csv\");\nawait bash.exec('echo \"processed\" \u003e results.txt');\n\n// Flush a specific mount\nconst workspaceFs = fs.getMount(\"/workspace\") as TigrisAdapter;\nawait workspaceFs.flush();\n```\n\n## API Reference\n\n### `@tigrisdata/agent-shell`\n\n| Export         | Description                                                        |\n| -------------- | ------------------------------------------------------------------ |\n| `TigrisShell`  | Main class — sandboxed storage shell backed by a Tigris bucket     |\n| `TigrisConfig` | Config type: `{ bucket, accessKeyId, secretAccessKey, endpoint? }` |\n| `ShellOptions` | Shell options type: `{ cwd?, env? }`                               |\n\n#### `TigrisShell`\n\n```typescript\nnew TigrisShell(config: TigrisConfig, shellOptions?: ShellOptions)\n```\n\n| Method          | Returns                   | Description                     |\n| --------------- | ------------------------- | ------------------------------- |\n| `exec(command)` | `Promise\u003cBashExecResult\u003e` | Execute a bash command          |\n| `flush()`       | `Promise\u003cvoid\u003e`           | Persist cached writes to Tigris |\n| `engine`        | `Bash`                    | Underlying just-bash instance   |\n| `fs`            | `TigrisAdapter`           | Underlying filesystem instance  |\n\n### `@tigrisdata/agent-shell/fs`\n\n| Export          | Description                                               |\n| --------------- | --------------------------------------------------------- |\n| `TigrisAdapter` | Filesystem adapter implementing just-bash's `IFileSystem` |\n| `TigrisConfig`  | Same config type as main export                           |\n\n### `@tigrisdata/agent-shell/commands`\n\n| Export                           | Description                  |\n| -------------------------------- | ---------------------------- |\n| `createTigrisCommands(config)`   | Create all Tigris commands   |\n| `createPresignCommand(config)`   | Create presign command only  |\n| `createSnapshotCommand(config)`  | Create snapshot command only |\n| `createForkCommand(config)`      | Create fork command only     |\n| `createForksListCommand(config)` | Create forks command only    |\n| `createBundleCommand(config)`    | Create bundle command only   |\n\n## Examples\n\nAll examples require `TIGRIS_STORAGE_ACCESS_KEY_ID`, `TIGRIS_STORAGE_SECRET_ACCESS_KEY`, and `TIGRIS_STORAGE_BUCKET` env vars. Run with `npx tsx examples/\u003cname\u003e.ts`.\n\n| Example                                                 | Description                                            |\n| ------------------------------------------------------- | ------------------------------------------------------ |\n| [`basic.ts`](examples/basic.ts)                         | Write files, pipe/process, flush to Tigris             |\n| [`presign.ts`](examples/presign.ts)                     | Generate shareable and upload URLs for stored files    |\n| [`snapshot-and-fork.ts`](examples/snapshot-and-fork.ts) | Checkpoint and branch storage — Tigris-unique features |\n| [`multi-bucket.ts`](examples/multi-bucket.ts)           | Mount multiple buckets, copy across them (advanced)    |\n\n## Development\n\n```bash\n# Install dependencies\nnpm install\n\n# Type check\nnpm run typecheck\n\n# Lint and format\nnpm run lint\nnpm run lint:fix\n\n# Run tests\nnpm test\n\n# Build\nnpm run build\n```\n\n## License\n\nMIT\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftigrisdata%2Fagent-shell","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftigrisdata%2Fagent-shell","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftigrisdata%2Fagent-shell/lists"}