sync: update from private repo (dfadcd5f)
CI / build-and-test (push) Has been cancelled

This commit is contained in:
oss-sync
2026-06-23 06:38:48 +00:00
parent 6a2f2cc736
commit 29ccaf1e92
377 changed files with 31028 additions and 8994 deletions
+141
View File
@@ -0,0 +1,141 @@
# ワークスペース・アプリ ブリッジ仕様(アプリ作者=エージェント向け)
ワークスペース・アプリは、ワークスペースの `apps/{name}/index.html` に置く HTML 製の小さな
GUI です。ワークスペースの **「アプリ」タブ**に一覧表示され、「開く」を押すと `AppRunner`
サンドボックス iframe で実行します(ファイルタブの「アプリとして実行」からも起動できます)。
アプリはワークスペースのファイルを **postMessage ブリッジ経由でのみ** 読み書きできます。
このドキュメントは、生成する HTML(アプリ)が従うべきブリッジ API を定めます。
> **エージェントへ**: ユーザーから「ワークスペース・アプリを作って」と頼まれたら、この仕様に
> 従った**自己完結 HTML** を `apps/{name}/index.html` に Write してください(外部リソース禁止・
> インライン JS/CSS のみ)。動くひな型は `docs/examples/workspace-apps/file-note/``index.html`
> `app.json`)。この仕様自体は `ReadToolDoc({ name: "workspace-apps" })` でいつでも読めます。
## 実行環境(重要な制約)
- アプリは `<iframe sandbox="allow-scripts">` で動きます。**`allow-same-origin` は付きません。**
そのため不透明オリジン(opaque origin)で動作し、親ウィンドウの DOM・Cookie・セッション・
localStorage には一切アクセスできません。
- **資格情報は渡されません。** ファイル I/O は親が代理します。代理は実行中ユーザーのセッションで
行われるため、アプリはそのユーザーの権限を超えられません(メンバーシップ・編集権限・パス
ガードはサーバ側でそのまま効きます)。
- **外部ネットワークは使えません。** `fetch` / `XMLHttpRequest` による外部通信は想定外です
(配信はサンドボックス + CSP で絞られます)。データの入出力は必ずブリッジ経由で行ってください。
- V1 の主対象は **単一の自己完結 `index.html`**(JS/CSS をインライン化したもの)。複数ファイル
構成(`apps/{name}/` 配下の相対参照)はベストエフォートで、相対 `src`/`href` は親が raw URL に
書き換えます。確実に動かしたいなら 1 ファイルにまとめてください。
## マニフェスト `app.json`(任意)
アプリフォルダに `apps/{name}/app.json` を置くと、「アプリ」タブの表示情報を指定できます。
**任意**で、無ければフォルダ名と `index.html` がそのまま使われます。形式が壊れていても無視され、
フォールバックされます(アプリ一覧は壊れません)。
```json
{
"title": "ファイル・ノート",
"description": "output/ のファイルを閲覧してメモを保存するアプリ",
"entry": "index.html"
}
```
| キー | 必須 | 説明 |
|---|---|---|
| `title` | 任意 | 一覧に出す表示名(無ければフォルダ名) |
| `description` | 任意 | 一覧に出す短い説明 |
| `entry` | 任意 | アプリフォルダ基準の HTML エントリ(既定 `index.html`)。**必ず `apps/{name}/` 配下**に収めること(`..` や絶対パスは拒否され、`index.html` にフォールバックされる) |
## ブリッジ・プロトコル
要求は `window.parent.postMessage(req, '*')` で送り、応答は `window``message` イベントで
受け取ります。各要求には一意の `id` を付け、応答の `id` と突き合わせてください。
### 要求
```js
// 読み取り
window.parent.postMessage({ id, type: 'readFile', path: 'output/data.json' }, '*');
// 一覧(dir 省略でワークスペース直下)
window.parent.postMessage({ id, type: 'listFiles', dir: 'output' }, '*');
// 書き込み(content は文字列)
window.parent.postMessage({ id, type: 'writeFile', path: 'output/請求書.html', content: '<html>…' }, '*');
// 削除(常に確認ダイアログが出る)
window.parent.postMessage({ id, type: 'deleteFile', path: 'output/old.txt' }, '*');
```
### 応答
```js
window.addEventListener('message', (e) => {
const r = e.data; // { id, ok, data } または { id, ok:false, error }
if (r.id !== myRequestId) return;
if (r.ok) { /* r.data を使う */ } else { /* r.error を表示 */ }
});
```
応答ペイロード:
| type | 成功時 `data` |
|-------------|-------------------------------------------------|
| `readFile` | `{ path, content }`content は UTF-8 テキスト)|
| `listFiles` | `{ dir, entries }`(entries はファイル/フォルダ)|
| `writeFile` | `{ path, bytes }` |
| `deleteFile`| `{ deleted, skipped }` |
失敗時は `{ id, ok:false, error }`
## パスの規則
- パスは必ず **ワークスペース files 直下からの相対パス**。先頭 `/``..`・ドライブ文字
(`C:`)・バックスラッシュは拒否されます(クライアントとサーバの二重ガード)。
- アプリは自分のワークスペースの外には出られません。
## 書き込みの確認ポリシー
- **確認なしで書ける場所**: `output/` 配下、および自分のアプリの `apps/{name}/data/` 配下。
- それ以外のパスへの `writeFile` は、親が確認ダイアログ(「アプリ『{name}』が {path} に書き込もう
としています。許可しますか?」)を出し、ユーザーが許可したときだけ書き込みます。
- `deleteFile` は場所に関わらず常に確認ダイアログが出ます。
データを残すアプリは、原則として `output/`(ユーザーに見せる成果物)か
`apps/{name}/data/`(アプリ内部の状態)に書いてください。そうすればユーザーを確認で煩わせません。
## 最小サンプル(自己完結 index.html
```html
<!doctype html><meta charset="utf-8">
<button id="save">保存</button>
<script>
let seq = 0;
const pending = new Map();
function call(req) {
return new Promise((resolve, reject) => {
const id = ++seq;
pending.set(id, { resolve, reject });
window.parent.postMessage({ ...req, id }, '*');
});
}
window.addEventListener('message', (e) => {
const r = e.data;
const p = pending.get(r && r.id);
if (!p) return;
pending.delete(r.id);
r.ok ? p.resolve(r.data) : p.reject(new Error(r.error));
});
document.getElementById('save').onclick = async () => {
await call({ type: 'writeFile', path: 'output/note.txt', content: 'hello' });
alert('保存しました');
};
</script>
```
## ネットワーク制約(重要)
アプリ HTML には `default-src 'none'; connect-src 'none'; ...` の CSP が自動注入され、
**外部ネットワーク(fetch/XHR/WebSocket/sendBeacon/フォーム外部 POST)はすべて遮断**される。
アプリのファイル I/O は postMessage ブリッジ(親が代理)だけが経路。これは、ユーザーから
渡されたワークスペースのファイル内容を外部へ持ち出されないための exfil 対策。
V1 のアプリは **自己完結 HTML**(インライン JS/CSS、`data:` 画像)で書くこと。
外部 CDN・外部 API・別ファイルの `<script src>` は CSP で読み込めない。