概要
Cloudflare Computer は、Durable Object 内で SQLite ベースの仮想ファイルシステムを提供し、コンテナ、Shell 分離、JavaScript 分離などのプラガブルな実行バックエンドをサポートします。統一されたエントリーポイント workspace.runtime.exec を通じてコードを実行し、FUSE マウント、RPC 同期、永続的な相対インポートをサポートします。
README プレビュー
# Cloudflare Computer\n\nCloudflare Computer is a virtual filesystem that lives inside a\nDurable Object. The Durable Object holds the authoritative state in\nSQLite and exposes one pluggable execution surface through\n`workspace.runtime`. Three backends ship today:\n\n- **Container** projects the SQLite state into a sandbox container as\n a real FUSE mount. A sandbox-side daemon (`computerd`) mounts the state\n as a filesystem and syncs changes back over a capnweb RPC channel.\n Full Linux userland, real binaries, real network.\n- **Isolate shell** runs [just-bash](https://github.com/vercel-labs/just-bash)\n in a Dynamic Worker. It reaches the authoritative Workspace over\n Workers RPC, so there is no second store or sync round trip.\n- **Isolate JavaScript** runs an ECMAScript module in a fresh Dynamic\n Worker with structured input/results, durable relative imports,\n configured libraries, Workspace-backed `node:fs/promises`, and trusted `ws:git` and\n `ws:artifacts` modules.\n\nA Workspace may register multiple backends under stable IDs.\n`workspace.runtime.exec(source, { backend })` is the single execution\nentry point; the selected backend defines whether `source` is a shell\ncommand or an ECMAScript module. Backends connect lazily on first use.\n\nWorkspace can also be constructed without a backend at all, giving\ncallers the filesystem on its own.\n\n> [!IMPORTANT]\n> **PREVIEW ONLY** This package is provided as a preview for feedback only.\n> APIs are unstable and the design is subject to change.\n>\n> Suitable for experiments, exploration and prototypes. It is NOT suitable\n> for production use at this time.\n>\n> The specification under [`docs/`](docs/) is forward-looking — read it for\n> intent, not as description of the code today.\n\n## Using it\n\nIf you want to build on Cloudflare Computer, install\n[`@cloudflare/computer`](packages/computer/README.md) and follow that\npackage's README — it has the installation steps, the entrypoint map,\nandFAQ (5)
トラブル対応Cloudflare Computer で worker-shell exec を実行した際に発生する「Cannot read properties of undefined (reading 'WorkspaceServiceProxy')」エラーを修正するにはどうすればよいですか?
このエラーにはセットアップに起因する2つの原因が考えられます。両方を修正してください:
1. 必要な互換性フラグ enable_ctx_exports を wrangler.toml に追加します:
compatibility_flags = ["nodejs_compat", "experimental", "enable_ctx_exports"]
wrangler.json を使用している場合:
{
"compatibility_flags": ["nodejs_compat", "experimental", "enable_ctx_exports"]
}
2. Worker のエントリーポイントから WorkspaceServiceProxy を再エクスポートします:
export { WorkspaceServiceProxy } from "@cloudflare/computer";
Wrangler を再起動または再デプロイしてから、再試行します:
curl -X POST localhost:8787/exec \
-H 'content-type: application/json' \
-d '{"cmd":"echo hi"}'
enable_ctx_exports がない場合、ctx.exports は undefined になります。再エクスポートがない場合は、WorkspaceServiceProxy 自体が存在しません。どちらのミスも、同じ紛らわしいエラーを引き起こします。これは @cloudflare/computer@0.2.0、wrangler@4.123.0、workerd@1.20260811.1 で確認されました。
トラブル対応@cloudflare/computer の `edit` ツールが `oldText` と完全一致しない場合にファイル全体を書き換え、スマートクォート、ダッシュ、末尾の空白を削除してしまう問題を修正するにはどうすればよいですか?
根本原因: 完全一致でのマッチングに失敗した場合、packages/computer/src/tools/fs/edit-diff.ts 内の applyEditsToNormalizedContent はファジー正規化されたコピーに対してマッチングを行いますが、その正規化されたコピーを書き込みと差分の両方の baseContent として誤って使用しています。その結果、無関係な Unicode 句読点や行末の空白が平坦化されてしまいます。
暫定的な回避策: oldText をバイト単位で完全一致させてください。誤って入った行末のスペースを削除し、スマートクォート(U+201C/U+201D)、em ダッシュ(U+2014)、およびファイルの Unicode 正規化を保持してください。再現例では、次のように変更します:
oldText: "let target = 1; "
を次のように変更:
oldText: "let target = 1;"
不可視文字は sed -n l path/to/file または od -c path/to/file で確認できます。
恒久対応: 正規化されたコンテンツはマッチングのためだけに保持し、正規化された文字から元のファイルへのソースオフセットマップを維持し、置換を元のコンテンツに挿入し、元のコンテンツと編集後のコンテンツから差分を生成します。Unicode 正規化による文字の統合や、展開された合字の一部のみにマッチが及ぶ場合など、曖昧なマッピングは拒否してください。これは PR fix: preserve files during fuzzy edits (#51) で実装されています。
影響を受けるバージョン: コミット 76d9e75 における @cloudflare/computer 0.1.0-alpha.1。次のコマンドで検証してください:
npm test --workspace @cloudflare/computer -- src/tools/fs/repro.test.tsトラブル対応なぜ Worker JavaScript capability のサイズエラーで、設定されたバイト制限値ではなく、リテラルの ${maxCapabilityBytes} が表示されるのですか?
上限値はサイズ比較では補間されますが、エラーメッセージは単純なダブルクォート文字列として生成されるため、${maxCapabilityBytes} は置き換えられません。モジュール生成時に設定値を挿入するように、packages/computer/src/backends/worker-javascript/module-graph.ts 内の capabilitiesModule() を修正してください。例: throw new Error(${JSON.stringify(Workspace capability request exceeds ${maxCapabilityBytes} bytes.)});。maxCapabilityBytes: 256 の場合、生成されるランタイムコードは次のようになる必要があります: throw new Error("Workspace capability request exceeds 256 bytes.");。Worker モジュールをリビルドまたは再生成し、再デプロイしてください。可能であれば、手動でパッチを適用する代わりに、PR #99 を含むリリースに更新してください。
トラブル対応なぜ computerd 0.3.0 で Cap'n Web の WebSocket エンドポイントは /ws から /api に変更されたのですか?
computerd 0.3.0では、Cap'n Webエンドポイントが統合されました。WebSocket接続には/wsではなく/apiを使用してください。サーバーは、Upgradeヘッダーを持つGETリクエストによって、WebSocketリクエストとHTTPリクエストを区別します。旧/wsパスは削除されました。なお、HTTPバッチサポートも0.3.0で削除されました。これは、ストリーム移行後にRPC呼び出しから返されるストリームに接続できなかったためです。
トラブル対応ドキュメントではシンボリックリンクは内部的なものだと説明されているのに、なぜ Workspace.fs は symlink()、readlink()、lstat()、chmod() を公開しているのですか?
ドキュメントは古くなっています。リリース済みのAPIでは、これらのメソッドは WorkspaceFilesystem 上で意図的にpublicとなっており、WorkspaceFilesystemStub によってWorkers RPC境界を越えてミラーリングされています。
これらをPromiseベースのファイルシステムAPIとして使用してください:
await workspace.fs.symlink(targetPath, linkPath);
const target = await workspace.fs.readlink(linkPath);
const linkStats = await workspace.fs.lstat(linkPath);
await workspace.fs.chmod(filePath, 0o644);
stat() は末尾のシンボリックリンクをたどってターゲットを報告しますが、lstat() はリンク自体を報告します。関連するエラーとしては、パスが存在しない場合の ENOENT、無効な引数または操作の場合の EINVAL、シンボリックリンクが多すぎる場合の ELOOP があります。
修正内容は、docs/04_filesystem_interface.md を更新して symlink、readlink、lstat、chmod を文書化し、シンボリックリンクが内部専用であるという記述を削除することです。これらのメソッドを削除すると、破壊的なAPI変更となります。