46 lines
2.8 KiB
Markdown
46 lines
2.8 KiB
Markdown
# ワークスペース・アプリの作り方(エージェント向け)
|
||
|
||
ユーザーから「ワークスペース・アプリを作って」「○○用の GUI を作って」などと頼まれたときの
|
||
手順です。専用ツールは不要 — `edit: true` の movement で **Write/Edit を使って HTML を書く**
|
||
だけで成立します。
|
||
|
||
## 何を作るか
|
||
|
||
ワークスペースの `apps/{name}/index.html` に置く、**自己完結した 1 枚の HTML**(インライン
|
||
JS/CSS、`data:` 画像のみ)。ユーザーはワークスペースの「アプリ」タブから「開く」で起動します。
|
||
アプリはサンドボックス iframe(opaque origin、`allow-same-origin` 無し)で動き、ファイル I/O は
|
||
親への **postMessage ブリッジ経由のみ**です。
|
||
|
||
## 守るべき制約(重要)
|
||
|
||
- **外部ネットワーク禁止**: `default-src 'none'; connect-src 'none'` の CSP が自動注入される。
|
||
外部 CDN・外部 API・別ファイルの `<script src>`・Web フォントは読み込めない。すべてインライン化する。
|
||
- **資格情報は渡らない**: I/O は親がユーザーのセッションで代理する。ユーザーの権限を超えられない。
|
||
- **パスはワークスペース相対**: `output/...`・`apps/{name}/data/...` への書き込みは確認不要。
|
||
それ以外への書き込み・削除はユーザー確認が出る。`..`・絶対パスは拒否される。
|
||
|
||
## ブリッジ API(要点)
|
||
|
||
```js
|
||
// 一意 id を付けて postMessage、message イベントで応答を id 突き合わせ。
|
||
const { entries } = await call({ type: 'listFiles', dir: 'output' }); // 一覧
|
||
const { content } = await call({ type: 'readFile', path: 'output/x.md' }); // 読み取り
|
||
await call({ type: 'writeFile', path: 'output/note.md', content: '...' }); // 書き込み
|
||
await call({ type: 'deleteFile', path: 'output/old.txt' }); // 削除(常に確認)
|
||
```
|
||
|
||
完全なプロトコル・最小ヘルパー実装・応答形式は **`docs/workspace-apps-bridge.md`** を参照。
|
||
|
||
## ひな型をコピーする
|
||
|
||
動くサンプルが `docs/examples/workspace-apps/file-note/` にある(`index.html` + `app.json`)。
|
||
`output/` を一覧・閲覧し、メモを `output/note.md` に保存する自己完結アプリ。これを土台に、
|
||
依頼に合わせて改変して `apps/{name}/index.html` に Write するのが最短。
|
||
|
||
`apps/{name}/app.json`(任意)で一覧の表示名・説明・エントリを指定できる(無ければフォルダ名)。
|
||
|
||
## 仕上げ
|
||
|
||
- 書き込んだら、ユーザーに「アプリ」タブの「開く」で起動できることを一言伝える。
|
||
- アプリ名(フォルダ名)は内容が分かる短い英小文字+ハイフンにする(例: `invoice-gen`)。
|