framejs
framejsはブラウザ上でES6 JavaScriptモジュールを実行します。フレームがアプリであり、安定して共有可能な framejs.app/j/<uuid> URL上に存在し、コンテンツは可変です。ハッシュパラメータをPOSTすることでその場でアプリを更新できます。あなたの役割は、ユーザーのリクエストをブラウザJavaScriptに変換し、環境に適した方法で配信することです。
配信モードの選択
リクエスト内容ではなく、あなたの実行環境に基づいて選択してください:
- 自動モード — シェル /
nodeが実行可能な場合: JavaScriptを生成し、セッションのframejs.appフレームを作成または更新し、その/j/<uuid>URLを出力し、ブラウザで開きます。シェルが利用可能な場合のデフォルトです。 - コードブロックモード — チャット / APIのみでシェルがない場合: 応答は単一のフェンスで囲まれたJavaScriptコードブロックのみ(
javascript情報文字列を付けて開く)とし、それ以外は一切含めないでください。周囲の散文、ファイル、URLは不要です。ユーザーは framejs.io のエディタにこれを貼り付けます。
どちらのモードでも、作成するJavaScriptは同じルールに従います — references/coding-guide.md を参照してください。
リクエストの種類
- プロンプトから作成 — 「跳ねるボールのアニメーション」や「y = sin(x) をプロット」など。
- 既存アプリの修正 — リクエストにフレームURLが含まれている場合。
https://framejs.app/j/<uuid>またはhttps://framejs.io/j/<uuid>?token=…のURL(「Copy frame for AI session」アクションはframejs.ioランタイムフォームをコピーします)、32文字の16進数ID、または従来のhttps://framejs.io/j/<sha256>/ 64文字のIDスナップショットの場合があります。framejs URLを見つけたら、その/j/<uuid>パスからUUIDを抽出し、そのフレームをターゲットにします(URLをそのまま--idに渡します。ヘルパーがframejs.io URLでもアプリ層にルーティングします)。既存のコードを必ず取得してから修正してください — references/short-url-api.md(§ 修正)を参照してください。URLに?token=<key>クエリパラメータが付いている場合(アプリの「Copy frame for AI session」アクションから)、そのURL全体を--idに渡すか、キーを--tokenに渡してください。ヘルパーはこれを保存し、ベアラ認証情報として送信するため、フレームの所有者がアプリをクレームした後でも更新が機能し続けます。URL全体を渡すことで、そのURLが指定するバックエンドもターゲットになります。そのため、開発用やセルフホストのフレームURL(例:https://framejs-app.localhost:13747/j/<uuid>?token=<key>)は、環境変数を事前設定しなくても自身のスタックを更新します。--app-origin <url>/--io-origin <url>で明示的にバックエンドを設定することもできます。references/short-url-api.md(§ ローカル/開発用オリジン)を参照してください。 - ローカルファイルの可視化 — リクエストにファイルパス(
./data.csv、/tmp/results.json)が含まれている場合。それらをアップロードし、入力として渡します — references/file-inputs.md を参照してください。
自動モード — 配信方法
コードを生成し、バンドルされたヘルパー(推奨)または references/short-url-api.md のインラインNodeフォールバックを使用します:
cat << 'JSCODE' | node scripts/framejs.mjs create --state "${SCRATCHPAD}/framejs-frame.json" --title "<短いタイトル>" --description "<一文の要約>" --screenshot
// ここに生成されたブラウザJSを記述 — $vars、バッククォート、特殊文字はすべてヒアドキュメント内で安全です
JSCODE
ヘルパーは標準出力に2つのURLを出力します — プライマリの https://framejs.app/j/<uuid> ページURLと、不変の snapshot: https://framejs.io/j/<sha256> URLです。また、標準エラー出力にユーザーに必ず伝えなければならない共有リンクのライフサイクル通知を出力します:
/j/<uuid>ページは編集可能でライブ更新されますが、匿名(未クレーム)のフレームは一時的であり、期限が切れます — ユーザーにそのページを開いてクレームする(無料アカウント)よう伝え、永続的に保持できるようにしてください。/j/<sha256>スナップショットは現在のアプリの不変コピーであり、最後に開かれてから約30日で期限切れになります — 安定した共有/バックアップリンクとして適していますが、後の編集を反映することはありません。
クラシックスクリプトには --module <url> を、入力には --input name=value を追加してください。
セッションごとに1つのフレームをその場で更新。 常に --state "<スクラッチパッド内のパス>/framejs-frame.json"(書き込み可能な任意のファイルパス)を渡してください。最初の create でフレームが作成されます。同じ --state で create を再実行すると、同じフレームが更新されます — /j/<uuid> URLは変わらず、開いている任意のframejs.appページがライブ更新されるため、URLはユーザーに一度だけ提供してください。ユーザーが同じセッション内で別のアプリを希望する場合のみ、--new を追加して新しいフレームを開始してください(その後の更新はその新しいフレームをターゲットにします)。状態に関係なく特定のフレームを更新するには、--id <uuid> を渡してください。このようなその場での更新では、--og/--title/--description を渡さなかった場合、ヘルパーはフレームの既存のOpen Graphデータを自動的に引き継ぎます。そのため、単なる再実行ではタイトル/説明が失われることはありません(保持された og.image は冗長な再スクリーンショットをスキップします)。プレビューコピーを変更する場合のみ、--title/--description を再度渡してください。
ブラウザはフレームが最初に作成されたときのみ自動的に開きます(--no-open でそれもスキップ可能)。同じフレームへの後続の更新(同じ --state または明示的な --id)ではブラウザは再開しません。すでに開いているページは同じフレーム購読を通じてライブ更新を受け取るため、再度開くと冗長な新しいタブが生成されるだけです。
ローカル開発環境が存在する場合、ヘルパーは自動的に .env を読み込み、開発スタック(FRAMEJS_APP_ORIGIN / FRAMEJS_IO_ORIGIN)をターゲットにします。ユーザーの操作は不要です。
ヘルパーが out of date 更新通知(標準エラー出力、最大1時間ごと)を表示した場合、それをそのまま一度だけユーザーに伝えてください。インストールされているスキルが最新バージョンより古いことを示し、通知には更新するためのコマンドが記載されています。
常に --screenshot を渡してください。ヘルパーは完成したアプリをレンダリングし、そのキャプチャを og:image プレビューとして保存します。これは自己保護的であり、アプリにまだ og.image がない場合にのみキャプチャします。そのため、以前の実行やユーザーが既に設定した画像を上書きすることはなく、レンダラが利用できない場合は画像なしのURLに静かにフォールバックします。キャプチャは、Playwright がインポート可能な場合(入力データを取得するアプリに最適な true network-idle 待機)に優先的に使用され、それ以外の場合はシステムのヘッドレスChromeを使用します。Playwrightはオプションです。より信頼性の高いパスとしてインストールするか(npm i -g playwright && npx playwright install chromium)、または $FRAMEJS_PLAYWRIGHT で node_modules にPlaywrightを含むディレクトリを指定します。--screenshot-wait <ms>(デフォルト6000 — 読み込みが遅いアプリでは値を上げてください)と --screenshot-size <w,h>(デフォルト 1200,630)で調整できます。Chromeバイナリは $CHROME_PATH で上書きします。
scripts/framejs.mjs は現在の作業ディレクトリではなく、このスキルのディレクトリを基準に解決されます。スキルフォルダから実行するか、絶対パスを使用してください(Claude Codeはそのディレクトリを ${CLAUDE_SKILL_DIR} として公開するため、${CLAUDE_SKILL_DIR}/scripts/framejs.mjs が常に機能します)。バンドルされたヘルパーを見つけられない、または実行できない場合は、references/short-url-api.md のインラインNodeフォールバックを使用してください。スクリプトファイルは不要です。
共有時にリンクが適切に展開されるよう、常にOpen Graphプレビュータグを含めてください — Open Graphルールについては references/short-url-api.md を参照してください:
- 新しいアプリ:
--title/--descriptionで新しいコピーを生成し、--screenshotを渡してプレビュー画像をキャプチャします。 - 既存アプリの修正: 取得したアプリには既に
ogが含まれています(fetchコマンドで返されます)。再計算せず、取得したオブジェクトを--og '<取得したog JSON>'でそのまま渡してください。これにより、すべてのフィールド(imageを含む)が保持されます。同じフレームを--id <uuid>(または同じ--state)で更新してください。ユーザーがプレビューコピーの変更を明示的に要求した場合のみ、新しい--title/--descriptionを設定してください。--screenshotを渡すことも可能です。取得したogに既にimageがある場合はそのまま残ります。ない場合は、新しいキャプチャが追加されます。
絶対ルール(両方のモード)
- ブラウザJavaScriptのみ — iframe内で実行され、Node.jsでは実行されません。
- ES6モジュール構文を使用する必要があります:
export function onInputs(inputs) {} - HTMLファイルを作成しないでください。ローカルの
.jsファイルを書き込まないでください。結果のレンダリングに独自の可視化/レンダリング/ウィジェットツールを使用しないでください。 root.style.position、root.style.height、root.style.widthを変更しないでください。- 重要:可視化はモバイルで見栄えがよく、その画面サイズに適応する必要があります — レスポンシブサイズを使用し(
rootの寸法を読み取り、リサイズをリッスン)、はみ出る固定ピクセル幅を避け、小さな画面でもテキストとタッチターゲットが読みやすいようにしてください。 - 自動モードでは、ユーザーがコピーするためのコードブロックを出力したり、長いハッシュURLを手動で構築して納品物としないでください。常にフレームAPI(ヘルパーの
create)を通じてPOSTしてください。ユーザーに/j/<uuid>ページURLを提供してください。 - コードブロックモードでは、単一のフェンスで囲まれたJavaScriptコードブロックのみを出力してください。それ以外は何も出力しないでください。
参考資料
- references/coding-guide.md — グローバル、エクスポート、パターン、CDNライブラリ、よくある間違い。
- references/short-url-api.md — フレームの作成/更新(
POST /j/<uuid>.json)、セッションごとに1つのフレームの状態、Open Graphタグ、APIトークン(フレームクレーム後の更新維持)、インラインフォールバック。 - references/file-inputs.md — ローカルファイルのアップロードと入力としての組み込み。
scripts/framejs.mjs— Nodeヘルパー:create(標準入力JS → framejs.appフレーム)、fetch <id>、upload <path>。オリジン:FRAMEJS_APP_ORIGIN/FRAMEJS_IO_ORIGIN(ローカル開発では近くの.envから自動読み込み)、または--app-origin/--io-originによる実行ごとの設定、もしくは--id/fetchに渡された完全なフレームURLのオリジン。