Communityコーディング&開発github.com

WebXR-JP/xrift-skills

XRift ワールド制作のための Agent Skills。AI コーディングエージェント(Claude Code, Cursor, Copilot, Codex 等)で XRift ワールドを作成する際に必要な情報を提供します。

xrift-skills とは?

このスキルは、AI コーディングエージェントが XRift プラットフォーム向けのワールドやアイテムをプログラムから操作するための公式 TypeScript SDK `@xrift/sdk` の使用方法を提供します。主に Claude Code や Cursor、Copilot などのエージェントがワールドのアップロードやアイテム管理を自動化する際に役立ちます。SDK は Node.js とブラウザの両方で動作し、依存関係ゼロで `fetch` API と SHA-256 ハッシュを利用した統合アップロードフローを実装しています。スキルには API リファレンス、コードテンプレート、型定義へのリンクが含まれており、エージェントが正確に API を呼び出せるよう、トークン管理、ファイルデータの型、エラーハンドリングなどの重要なルールも明示されています。

対応✓Claude Code✓Codex CLI✓Cursor
npx skills add WebXR-JP/xrift-skills

Installed? Explore more コーディング&開発 skills: steipete/bluebubbles, steipete/eightctl, steipete/blucli · View all 6 →

お気に入りのAIに質問する

このエージェントスキルを事前に読み込んだ状態で新しいチャットを開きます。

ドキュメント

XRift SDK ガイド

@xrift/sdk を使用して XRift プラットフォームの API とプログラム的にやり取りするためのガイドです。

リファレンス

  • API リファレンス - XriftClient, WorldsApi, ItemsApi, エラークラス、ユーティリティ関数の完全な仕様
  • コードテンプレート - Node.js およびブラウザ環境向けのすぐに使えるコード例
  • 型定義 - すべての SDK インターフェースの完全な TypeScript 型定義

重要なルール

  1. API トークンは常に必要です — XriftClient は有効な token で初期化する必要があります。トークンをハードコードせず、環境変数またはセキュアな設定を使用してください。
  2. ファイルデータは FileData 型である必要があります — SDK は ArrayBuffer | Uint8Array を受け付け、ファイルパスや文字列は受け付けません。呼び出し元は SDK に渡す前にファイルをバイナリデータとして読み込む必要があります。
  3. remotePath は相対パスである必要があります — 絶対パスや / で始まるパスは使用しないでください。scene.glb や assets/texture.png のようなパスを使用してください。
  4. 常にエラーを処理してください — API 呼び出しを try/catch でラップし、XriftAuthError、XriftApiError、XriftNetworkError を個別に処理してください。

プロジェクト概要

@xrift/sdk とは?

@xrift/sdk は XRift プラットフォーム向けの汎用 TypeScript SDK です。ワールドとアイテムの API へのプログラム的なアクセスを提供し、ファイルアップロード機能が統合されています。

主な特徴

  • ユニバーサル: Node.js(>=18)とブラウザ環境の両方で動作
  • 依存関係ゼロ: ネイティブの fetch API 上に構築
  • TypeScript ファースト: 完全な型定義を含む
  • デュアルビルド: ESM + CJS 対応
  • 統合アップロード: ハッシュ計算 → 署名付き URL の取得 → アップロード → 完了を一度の呼び出しで実行

技術スタック

  • TypeScript(strict モード)
  • fetch API(axios 不使用)
  • SHA-256 ハッシュ(node:crypto / Web Crypto API)
  • ESM + CJS デュアルビルド

インストール

npm install @xrift/sdk

クイックスタート

import { XriftClient, getMimeType } from '@xrift/sdk';

const client = new XriftClient({
  token: process.env.XRIFT_TOKEN!,
});

// ワールドをアップロード
const result = await client.worlds.upload(
  [
    {
      remotePath: 'scene.glb',
      data: fileData, // Uint8Array または ArrayBuffer
      size: fileData.byteLength,
      contentType: getMimeType('scene.glb'),
    },
  ],
  {
    name: 'My World',
  },
);

console.log(`アップロード完了: ${result.worldId} v${result.versionNumber}`);

アップロードフロー

upload() メソッド(WorldsApi と ItemsApi の両方)は内部で以下の手順を実行します:

  1. ID を決定 — 提供された worldId/itemId を使用するか、create() で新しいリソースを作成
  2. コンテンツハッシュを計算 — すべてのファイルデータ + 設定値の SHA-256 ハッシュ(先頭 12 桁の 16 進数)
  3. 合計ファイルサイズを計算 — すべての file.size 値の合計
  4. 署名付きアップロード URL を取得 — メタデータとファイルリストを含む POST リクエストを /upload-urls エンドポイントに送信
  5. ファイルをアップロード — 各ファイルを正しい Content-Type ヘッダーとともに署名付き URL に PUT
  6. アップロードを完了 — バージョン ID を含む POST リクエストを /complete エンドポイントに送信

これらの手順はすべて upload() によって内部的に処理され、個別に呼び出すことはできません。

エラーハンドリング

import { XriftAuthError, XriftApiError, XriftNetworkError } from '@xrift/sdk';

try {
  await client.worlds.upload(files, options);
} catch (error) {
  if (error instanceof XriftAuthError) {
    // 401 - 無効または期限切れのトークン
  } else if (error instanceof XriftApiError) {
    // その他の API エラー (400, 403, 404, 500 など)
    console.error(`ステータス: ${error.statusCode}, ボディ:`, error.responseBody);
  } else if (error instanceof XriftNetworkError) {
    // ネットワーク接続の問題
    console.error('原因:', error.cause);
  }
}

エラー階層

XriftSdkError (基本)
├── XriftApiError (HTTP エラー、statusCode と responseBody を持つ)
│   └── XriftAuthError (HTTP 401)
└── XriftNetworkError (接続エラー、cause を持つ)

Node.js とブラウザの比較

項目Node.jsブラウザ
ファイル読み込みfs.readFile() → Uint8ArrayFile.arrayBuffer() → Uint8Array
ハッシュアルゴリズムnode:crypto (createHash)crypto.subtle.digest (Web Crypto API)
トークン保存環境変数セキュアなストレージ(localStorage は不可)
最小バージョンNode.js 18+fetch + Web Crypto 対応のモダンブラウザ

関連リソース

関連スキル