@cloudflare/shell

中文文档
0.5.0发布于 2026/10/20MITTypeScriptESM + CJS构建来源已验证近 30 天下载 88.6万

Deprecated: use @cloudflare/computer. Experimental sandboxed JS execution and filesystem runtime for Cloudflare Workers agents

此软件包已被标记为弃用

Deprecated: use @cloudflare/computer. Migration guide: https://github.com/cloudflare/agents/blob/main/docs/shell/migrating-to-computer.md

原始使用文档
文档目录19 节
  1. What it is
  2. What it is not
  3. Example — in-memory state
  4. Example — durable Workspace
  5. Example — git operations
  6. Git commands
  7. Git ToolProvider for codemode
  8. Design goals
  9. state object API
  10. Primitive filesystem
  11. JSON helpers
  12. Search and replace
  13. Filesystem queries
  14. Archive and compression
  15. Structured edit planning
  16. Multi-file workflow
  17. Rough command translation
  18. Maybe later
  19. Relationship to other packages

@cloudflare/shell

Deprecated. Use @cloudflare/computer for new agent workspaces. To move existing files, see Migrating to @cloudflare/computer.

Sandboxed JavaScript execution and filesystem runtime for Cloudflare Workers agents.

The published package includes the Workspace guide at docs/index.md.

Instead of parsing shell syntax, @cloudflare/shell runs JavaScript inside an isolated Worker and exposes a typed state object for operating on a filesystem backend. It is designed for agent workflows that need structured state operations, predictable semantics, and coarse host-side filesystem primitives.

What it is

  • A runtime-neutral StateBackend interface for filesystem/state operations
  • A FileSystem interface with two implementations: InMemoryFs (ephemeral) and WorkspaceFileSystem (durable)
  • FileSystemStateBackend — a single adapter wrapping any FileSystem into a StateBackend
  • Workspace — durable file storage backed by SQLite + optional R2
  • stateTools(workspace) — a ToolProvider for @cloudflare/codemode that exposes state.* in sandboxed executions
  • createGit(filesystem) — pure-JS git operations via isomorphic-git, backed by the virtual filesystem
  • gitTools(workspace) — a ToolProvider for @cloudflare/codemode that exposes git.* in sandboxed executions with auto-injected auth
  • A prebuilt state stdlib with type declarations for LLM prompts

What it is not

This is not a bash interpreter. It does not parse shell syntax, expose pipes, or emulate POSIX shell behavior. It executes JavaScript.

Example — in-memory state

import { createMemoryStateBackend } from "@cloudflare/shell";
import { stateToolsFromBackend } from "@cloudflare/shell/workers";
import { DynamicWorkerExecutor, resolveProvider } from "@cloudflare/codemode";

const backend = createMemoryStateBackend({
  files: {
    "/src/app.ts": 'export const answer = "foo";\n'
  }
});

const executor = new DynamicWorkerExecutor({ loader: env.LOADER });

const result = await executor.execute(
  `async () => {
    const text = await state.readFile("/src/app.ts");
    await state.writeFile("/src/app.ts", text.replace("foo", "bar"));
    return await state.readFile("/src/app.ts");
  }`,
  [resolveProvider(stateToolsFromBackend(backend))]
);

Example — durable Workspace

import { Agent } from "agents";
import { Workspace } from "@cloudflare/shell";
import { stateTools } from "@cloudflare/shell/workers";
import { DynamicWorkerExecutor, resolveProvider } from "@cloudflare/codemode";

class MyAgent extends Agent<Env> {
  workspace = new Workspace({
    sql: this.ctx.storage.sql,
    r2: this.env.MY_BUCKET,
    name: () => this.name
  });

  async run(code: string) {
    const executor = new DynamicWorkerExecutor({ loader: this.env.LOADER });
    return executor.execute(code, [
      resolveProvider(stateTools(this.workspace))
    ]);
  }
}

Example — git operations

import { Agent } from "agents";
import { Workspace } from "@cloudflare/shell";
import { WorkspaceFileSystem } from "@cloudflare/shell";
import { createGit } from "@cloudflare/shell/git";

class MyAgent extends Agent<Env> {
  workspace = new Workspace({
    sql: this.ctx.storage.sql,
    name: () => this.name
  });

  async run() {
    const git = createGit(new WorkspaceFileSystem(this.workspace));

    await git.clone({ url: "https://github.com/org/repo", depth: 1 });
    await this.workspace.writeFile("/README.md", "# Updated");
    await git.add({ filepath: "." });
    await git.commit({
      message: "update readme",
      author: { name: "Agent", email: "[email protected]" }
    });
    await git.push({ token: this.env.GITHUB_TOKEN });
  }
}

Git commands

init, clone, status, add, rm, commit, log, branch, checkout, fetch, pull, push, diff, remote

Git ToolProvider for codemode

gitTools(workspace) exposes all git commands inside sandboxed executions. Default auth is auto-injected into clone/fetch/pull/push — the LLM never sees secrets.

import { stateTools } from "@cloudflare/shell/workers";
import { gitTools } from "@cloudflare/shell/git";

const providers = [
  resolveProvider(stateTools(this.workspace)),
  resolveProvider(gitTools(this.workspace, { token: this.env.GITHUB_TOKEN }))
];

For Git servers that require Basic auth, pass hidden default credentials:

const providers = [
  resolveProvider(stateTools(this.workspace)),
  resolveProvider(
    gitTools(this.workspace, {
      auth: {
        username: "git",
        password: this.env.GIT_PASSWORD
      }
    })
  )
];

If both auth and token are configured, auth is used. Direct tool-call auth, if supplied, takes precedence over either default.

Design goals

  • Structured state operations instead of shell parsing
  • Coarse host-side operations like glob() and diff() to avoid chatty RPC
  • Compatibility with both ephemeral in-memory state and durable Workspace
  • Secure execution with isolate-level timeouts and outbound network blocking by default

state object API

The state object is available inside every isolate and exposes:

Primitive filesystem

readFile, writeFile, appendFile, readFileBytes, writeFileBytes, mkdir, rm, cp, mv, symlink, readlink, realpath, readdir, glob, stat, lstat, exists, diff, diffContent

JSON helpers

readJson(path), writeJson(path, value, { spaces? }), queryJson(path, query), updateJson(path, operations)

Search and replace

searchText(path, query, options?), searchFiles(glob, query, options?), replaceInFile(path, search, replacement, options?), replaceInFiles(glob, search, replacement, { dryRun?, rollbackOnError?, ...options })

Filesystem queries

find(path, options?), walkTree(path, { maxDepth? }), summarizeTree(path, { maxDepth? })

Archive and compression

createArchive(path, sources), listArchive(path), extractArchive(path, destination), compressFile(path, destination?), decompressFile(path, destination?), hashFile(path, { algorithm? }), detectFile(path)

Structured edit planning

planEdits(instructions), applyEditPlan(plan, { dryRun?, rollbackOnError? }), applyEdits(edits, { dryRun?, rollbackOnError? })

Multi-file workflow

// Preview changes without applying
const preview = await state.replaceInFiles("src/**/*.ts", "foo", "bar", {
  dryRun: true
});

// Plan structured edits with intent
const plan = await state.planEdits([
  { kind: "replace", path: "/src/app.ts", search: "foo", replacement: "bar" },
  { kind: "writeJson", path: "/src/config.json", value: { enabled: true } }
]);
await state.applyEditPlan(plan);

// Apply raw edits transactionally
await state.applyEdits([
  { path: "/src/generated.ts", content: "export const generated = true;\n" }
]);

Batch writes roll back by default if any write fails. Set rollbackOnError: false to allow partial progress.

Rough command translation

Shell commandstate equivalent
catstate.readFile()
echo x > filestate.writeFile()
mkdirstate.mkdir()
ls / findstate.readdir() / state.glob()
find with filtersstate.find()
tree / dustate.walkTree() / state.summarizeTree()
cp / mv / rmstate.cp() / state.mv() / state.rm()
diffstate.diff() / state.diffContent()
grepstate.searchText() / state.searchFiles()
sedstate.replaceInFile() / state.replaceInFiles()
jqstate.readJson() / state.queryJson() / state.updateJson()
tarstate.createArchive() / state.listArchive() / state.extractArchive()
gzip / gunzipstate.compressFile() / state.decompressFile()
sha256sum / filestate.hashFile() / state.detectFile()
gitgit.* via @cloudflare/shell/git

Maybe later

  • Stream-oriented transforms inspired by sort, uniq, comm, cut, paste, tr
  • Full rg CLI parity — file types, ignore controls, multiple roots
  • Richer JSON query semantics closer to jq filters
  • Structured patch helpers covering more of diff / codemod workflows
  • A smaller "command" library built on top of state.*

Relationship to other packages

  • @cloudflare/codemode: executes sandboxed JavaScript that orchestrates tools
  • @cloudflare/shell: provides filesystem backends and stateTools() ToolProvider for codemode

版本与发布记录

@cloudflare/shell 共发布 20 个版本,首次发布于 2026/03/13;过去 12 个月发布了 20 个版本。最新版本附带 npm provenance 构建来源证明,可追溯到公开的 CI 构建记录。

版本发布日期距今
0.5.0latest2026/10/2020 天前
0.4.32026/07/233 个月前
0.4.22026/07/233 个月前
0.4.12026/06/264 个月前
0.4.02026/06/134 个月前
0.3.92026/06/075 个月前

关于 @cloudflare/shell 的常见问题

@cloudflare/shell 是什么?

Deprecated: use @cloudflare/computer. Experimental sandboxed JS execution and filesystem runtime for Cloudflare Workers agents注意:该包已被作者标记为弃用——Deprecated: use @cloudflare/computer. Migration guide: https://github.com/cloudflare/agents/blob/main/docs/shell/migrating-to-computer.md

如何安装 @cloudflare/shell?

在项目目录运行 npm install @cloudflare/shell,或使用 pnpm add / yarn add / bun add。

@cloudflare/shell 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@cloudflare/shell 支持 ESM 还是 CommonJS?

同时提供 ES Module 与 CommonJS 入口,import 和 require() 都可以使用,打包工具会自动选择合适的版本。

@cloudflare/shell 可以商用吗?

@cloudflare/shell 使用 MIT 许可。宽松许可:允许商业使用、修改和再分发,通常只需在分发时保留原版权与许可声明。以上为概括,不构成法律意见,请以许可原文为准。

@cloudflare/shell 的下载量有多少?

根据 npm 官方下载统计,@cloudflare/shell 在 2026/10/10 – 2026/11/08 这 30 天内被下载 885,652 次,日均约 29,522 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@cloudflare/shell 还在维护吗?

最新版本 0.5.0 发布于 2026/10/20(20 天前);至今共发布 20 个版本,其中过去 12 个月发布了 20 个;首次发布于 2026/03/13。作者已将其标记为弃用,新项目建议寻找替代方案。