{"id":49841257,"url":"https://github.com/slankdev/codexweb","last_synced_at":"2026-05-14T06:14:05.318Z","repository":{"id":357238041,"uuid":"1236024840","full_name":"slankdev/codexweb","owner":"slankdev","description":null,"archived":false,"fork":false,"pushed_at":"2026-05-11T23:23:26.000Z","size":45,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-05-12T00:30:03.501Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/slankdev.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-05-11T22:04:28.000Z","updated_at":"2026-05-11T23:09:58.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/slankdev/codexweb","commit_stats":null,"previous_names":["slankdev/codexweb"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/slankdev/codexweb","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/slankdev%2Fcodexweb","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/slankdev%2Fcodexweb/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/slankdev%2Fcodexweb/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/slankdev%2Fcodexweb/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/slankdev","download_url":"https://codeload.github.com/slankdev/codexweb/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/slankdev%2Fcodexweb/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33012815,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-13T13:14:54.681Z","status":"online","status_checked_at":"2026-05-14T02:00:06.663Z","response_time":57,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-05-14T06:14:01.263Z","updated_at":"2026-05-14T06:14:05.309Z","avatar_url":"https://github.com/slankdev.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# codexweb (test)\n\nOpenAI Codex CLI ([`openai/codex`](https://github.com/openai/codex)) を Web UI から\n触れるようにする、Next.js ベースの薄いラッパーです。Codex Web や Claude Code\nCloud のような **チャット形式の Web UI** で Codex エージェントにタスクを投げ、\nストリーミング結果を眺めたり、追加の指示を送ったりできます。\n\n## 仕組み\n\n```\n┌──────────┐    SSE     ┌────────────────┐  spawn   ┌──────────────┐\n│  Browser │ ◀────────  │ Next.js server │ ──────▶  │  codex exec  │\n│  (chat)  │    HTTP    │  (API routes)  │   pipe   │ (vendor/codex│\n└──────────┘            └────────────────┘          └──────────────┘\n```\n\n- Next.js App Router の API ルートで `codex exec --json` を `child_process.spawn`\n- 各行を JSON としてパースし、`assistant_message` / `tool_call` / `tool_result`\n  などの内部イベント型に変換\n- ブラウザは `EventSource` で per-task の SSE エンドポイントを購読し、チャット\n  風に描画\n\n## セットアップ\n\n依存ツール: Node.js 18.18+ と git。\n\n```bash\n# 1. 依存パッケージ\nnpm install\n\n# 2. openai/codex を vendor/codex にサブモジュールとして追加\nnpm run setup:codex\n# (or: bash scripts/setup-codex.sh)\n\n# 3. codex CLI のビルド/インストール\n#    openai/codex の README に従ってください。例:\n#      cd vendor/codex/codex-cli \u0026\u0026 npm install \u0026\u0026 npm run build\n#    あるいはグローバルインストール:\n#      npm i -g @openai/codex\n#    どこにバイナリがあるかに応じて CODEX_BIN を設定 (下記)。\n\n# 4. 環境変数\ncp .env.example .env.local\n# OPENAI_API_KEY と必要なら CODEX_BIN を設定\n\n# 5. 起動\nnpm run dev\n# → http://localhost:3000\n```\n\n### 環境変数\n\n| 変数 | 説明 |\n| --- | --- |\n| `CODEX_BIN` | spawn する codex バイナリへの絶対パス。未指定なら `vendor/codex/codex-cli/bin/codex.js` → `codex` (PATH) の順で解決。 |\n| `CODEX_DEFAULT_CWD` | 「新しいタスク」ダイアログでデフォルトに入れる作業ディレクトリ。 |\n| `OPENAI_API_KEY` | Codex CLI が呼び出すモデルの認証用 (詳細は upstream の README 参照)。 |\n| `AUTH_SECRET` | **必須**。セッション/state Cookie の HMAC 署名鍵 (16 文字以上)。`openssl rand -base64 32` で生成。 |\n| `OAUTH_CLIENT_ID` | **必須**。OAuth 2.0 クライアント ID。 |\n| `OAUTH_CLIENT_SECRET` | confidential クライアント (Google \"Web application\" 型など) のみ必要。public クライアントなら省略可。 |\n| `OAUTH_AUTHORIZE_URL` / `OAUTH_TOKEN_URL` / `OAUTH_USERINFO_URL` | IdP のエンドポイント。デフォルトは Google。 |\n| `OAUTH_SCOPES` | 要求スコープ (デフォルト `openid email profile`)。 |\n| `ALLOWED_EMAILS` | ログイン許可リスト。`alice@example.com,@your-company.com` のようにメール or `@` ドメインを並べる。未設定だと **誰でもログイン可能**。 |\n| `AUTH_BASE_URL` | OAuth リダイレクト URL を組み立てるベース URL。未設定ならリクエストヘッダから自動推測 (Cloud Run など proxy 経由なら明示推奨)。 |\n| `CODEXWEB_AUTH_PROXY_URL` | (preview デプロイ用) Preview の `/login` ボタンがリダイレクトする canonical (= prod) の URL。これがセットされていると preview は自分で OAuth せず prod に丸投げする。 |\n| `CODEXWEB_PREVIEW_ORIGIN_PATTERN` | (prod デプロイ用) Prod が `?preview=…` 付き login を受け付けて handoff token を bounce してよい origin の正規表現。未設定だと preview への bounce を全部拒否する (= preview auth が動かない)。 |\n\n### 認証 (OAuth 2.0 + PKCE)\n\nWeb UI と API ルートは Next.js Middleware で保護されており、未ログインだと\nブラウザは `/login` にリダイレクト、API は `401 Unauthorized` を返します。\nフローは **OAuth 2.0 Authorization Code + PKCE (S256)** で常時。\n`OAUTH_CLIENT_SECRET` は設定されていれば token endpoint に併送されるので、\npublic / confidential どちらのクライアントにも対応します。\n\n#### IdP の選び方\n\n| IdP | クライアント種別 | `OAUTH_CLIENT_SECRET` | メモ |\n| --- | --- | --- | --- |\n| Google \"Web application\" | confidential | 必須 | Cloud Run など HTTPS ホスティング向け。 |\n| Google \"Desktop app\" | public | 不要 | ローカル限定 (redirect URI が loopback)。 |\n| Auth0 / Keycloak / Okta / Cognito (Native/SPA) | public | 不要 | 任意 HTTPS redirect 可。 |\n| Auth0 / Keycloak (Regular Web App) | confidential | 必須 | 同上。 |\n\n#### Google \"Web application\" でのセットアップ\n\n1. [Google Cloud Console](https://console.cloud.google.com/) で OAuth 2.0\n   クライアント ID を作成 (Application type: **Web application**)。\n2. Authorized redirect URIs に下記を追加:\n   - `http://localhost:3000/api/auth/callback` (開発用)\n   - `https://\u003ccloud-run-host\u003e/api/auth/callback` (本番用)\n3. `.env.local` または Secret Manager / GitHub Variables 経由で設定:\n   ```env\n   OAUTH_CLIENT_ID=\u003cclient id\u003e\n   OAUTH_CLIENT_SECRET=\u003cclient secret\u003e\n   AUTH_SECRET=$(openssl rand -base64 32)\n   ALLOWED_EMAILS=you@example.com\n   ```\n\n#### 他の IdP の例 (Keycloak public client)\n\n```env\nOAUTH_CLIENT_ID=codexweb\n# OAUTH_CLIENT_SECRET は省略 (Keycloak で public client にする)\nOAUTH_AUTHORIZE_URL=https://kc.example.com/realms/main/protocol/openid-connect/auth\nOAUTH_TOKEN_URL=https://kc.example.com/realms/main/protocol/openid-connect/token\nOAUTH_USERINFO_URL=https://kc.example.com/realms/main/protocol/openid-connect/userinfo\n```\n\n#### 提供エンドポイント\n\n| Method | Path | 説明 |\n| --- | --- | --- |\n| GET | `/api/auth/login` | IdP の同意画面へリダイレクト (`?redirect=/path` 対応) |\n| GET | `/api/auth/callback` | IdP からのコールバック (内部用) |\n| GET/POST | `/api/auth/logout` | セッション Cookie を破棄 |\n| GET | `/api/auth/me` | 現在ログイン中のユーザ情報 (未ログインなら `{ user: null }`) |\n\n## 使い方\n\n1. 右上の **+ New** から新しいタスクを作成\n2. プロンプトと作業ディレクトリ (絶対パス) を入力して **実行**\n3. 左サイドバーにタスクが追加され、メイン領域に Codex の出力がチャット形式で\n   ストリーミング表示される\n4. 完了後、下部のフォームから追加の指示を送れます\n\n## API (内部)\n\n| Method | Path | 説明 |\n| --- | --- | --- |\n| GET | `/api/tasks` | タスク一覧 |\n| POST | `/api/tasks` | 新規タスク作成 (`prompt`, `cwd`, `model?`) |\n| GET | `/api/tasks/:id` | タスク詳細 (これまでのイベント全部) |\n| GET | `/api/tasks/:id/events` | SSE ストリーム |\n| POST | `/api/tasks/:id/messages` | 追加メッセージ (アイドル時のみ) |\n| POST | `/api/tasks/:id/stop` | 実行中のタスクを停止 |\n\n## デプロイ\n\n### ローカル Docker (任意)\n\n公式のレジストリ push は行っていないので、ローカルで動作確認したい場合は\nリポジトリ直下でイメージをビルドしてから起動してください。\n\n```bash\ndocker build -t codexweb:local .\n\ncat \u003e .env \u003c\u003c'EOF'\nOPENAI_API_KEY=sk-...\n# 任意: CODEX_EXTRA_ARGS=\nEOF\n\ndocker run --rm -p 3000:3000 \\\n  --env-file .env \\\n  -v \"$PWD\":/workspace \\\n  -e CODEX_DEFAULT_CWD=/workspace \\\n  codexweb:local\n```\n\n→ ブラウザで http://localhost:3000\n\n### Cloud Run\n\n`main` への push で `.github/workflows/cloudrun.yml` が起動し、Artifact\nRegistry にイメージを push したあと Cloud Run にデプロイします。\n**シングルインスタンス前提** で動作するよう設定済み (`min-instances=1`,\n`max-instances=1`, `--timeout=3600`) で、これはタスクストアが\nインメモリ実装である現状の制約に合わせたものです。\n\n#### 前提セットアップ (Google Cloud 側、一度だけ)\n\n```bash\n# 変数\nPROJECT_ID=your-project\nREGION=asia-northeast1\nREPO=codexweb            # Artifact Registry repo 名\nSERVICE=codexweb         # Cloud Run service 名\n\n# API 有効化\ngcloud services enable run.googleapis.com artifactregistry.googleapis.com \\\n  secretmanager.googleapis.com iamcredentials.googleapis.com \\\n  --project=\"$PROJECT_ID\"\n\n# Artifact Registry リポジトリ\ngcloud artifacts repositories create \"$REPO\" \\\n  --repository-format=docker --location=\"$REGION\" --project=\"$PROJECT_ID\"\n\n# デプロイ用 Service Account\nSA=codexweb-deployer\ngcloud iam service-accounts create \"$SA\" --project=\"$PROJECT_ID\"\nSA_EMAIL=\"$SA@$PROJECT_ID.iam.gserviceaccount.com\"\nfor role in roles/run.admin roles/artifactregistry.writer \\\n            roles/iam.serviceAccountUser roles/secretmanager.secretAccessor; do\n  gcloud projects add-iam-policy-binding \"$PROJECT_ID\" \\\n    --member=\"serviceAccount:$SA_EMAIL\" --role=\"$role\"\ndone\n\n# Workload Identity Federation (GitHub → GCP の keyless 認証)\ngcloud iam workload-identity-pools create github \\\n  --location=global --project=\"$PROJECT_ID\"\ngcloud iam workload-identity-pools providers create-oidc github \\\n  --location=global --workload-identity-pool=github \\\n  --issuer-uri=https://token.actions.githubusercontent.com \\\n  --attribute-mapping='google.subject=assertion.sub,attribute.repository=assertion.repository' \\\n  --attribute-condition='assertion.repository==\"\u003cOWNER\u003e/codexweb\"' \\\n  --project=\"$PROJECT_ID\"\nPROJECT_NUM=$(gcloud projects describe \"$PROJECT_ID\" --format='value(projectNumber)')\ngcloud iam service-accounts add-iam-policy-binding \"$SA_EMAIL\" \\\n  --role=roles/iam.workloadIdentityUser \\\n  --member=\"principalSet://iam.googleapis.com/projects/$PROJECT_NUM/locations/global/workloadIdentityPools/github/attribute.repository/\u003cOWNER\u003e/codexweb\"\n\n# Secret Manager にシークレット投入 (Google Web app 型を使う想定)\nprintf \"%s\" \"$(openssl rand -base64 32)\" | gcloud secrets create AUTH_SECRET --data-file=- --project=\"$PROJECT_ID\"\nprintf \"%s\" \"\u003cyour-oauth-client-id\u003e\"     | gcloud secrets create OAUTH_CLIENT_ID --data-file=- --project=\"$PROJECT_ID\"\nprintf \"%s\" \"\u003cyour-oauth-client-secret\u003e\" | gcloud secrets create OAUTH_CLIENT_SECRET --data-file=- --project=\"$PROJECT_ID\"\nprintf \"%s\" \"sk-...\"                     | gcloud secrets create OPENAI_API_KEY --data-file=- --project=\"$PROJECT_ID\"\n```\n\n\u003e **public client を使う場合**: `OAUTH_CLIENT_SECRET` シークレットを作らず、\n\u003e リポジトリ Variables で `OAUTH_USE_CLIENT_SECRET=false` をセットすると\n\u003e workflow が secret 取得をスキップします。\n\n#### GitHub 側の設定\n\nリポジトリ Settings → Secrets and variables → Actions → **Variables** タブで:\n\n| Variable | 例 |\n| --- | --- |\n| `GCP_PROJECT_ID` | `your-project` |\n| `GCP_REGION` | `asia-northeast1` |\n| `ARTIFACT_REGISTRY_REPO` | `codexweb` |\n| `CLOUD_RUN_SERVICE` | `codexweb` |\n| `WIF_PROVIDER` | `projects/\u003cNUM\u003e/locations/global/workloadIdentityPools/github/providers/github` |\n| `WIF_SERVICE_ACCOUNT` | `codexweb-deployer@\u003cPROJECT_ID\u003e.iam.gserviceaccount.com` |\n| `ALLOWED_EMAILS` | (推奨) 許可メール/ドメイン |\n| `AUTH_BASE_URL` | (推奨) `https://\u003cservice\u003e-\u003chash\u003e-\u003cregion\u003e.a.run.app` |\n| `CODEXWEB_AUTH_PROXY_URL` | (PR Preview を使うなら必須) 本番の URL。例 `https://\u003cservice\u003e-\u003chash\u003e-\u003cregion\u003e.a.run.app` |\n| `CODEXWEB_PREVIEW_ORIGIN_PATTERN` | (PR Preview を使うなら必須) `^https://codexweb-pr-\\d+-[a-z0-9-]+\\.[a-z0-9-]+\\.run\\.app$` のような preview URL の正規表現 |\n| `CODEX_DEFAULT_CWD` | (任意) 例 `/tmp` |\n\n初回デプロイで URL が確定するので、その URL を Google Cloud Console の\nOAuth クライアントの \"Authorized redirect URIs\" にも追加してください\n(`\u003cURL\u003e/api/auth/callback`)。あわせて `AUTH_BASE_URL` を変数にセットして\n2 回目以降のデプロイで使うのが確実です。\n\n### PR Preview\n\n`pull_request` イベントで `.github/workflows/pr-preview.yml` が起動し、\n**PR ごとに専用 Cloud Run サービス** (`codexweb-pr-\u003cNUMBER\u003e`) を立てます。\n本番と同じ Artifact Registry / WIF / Secret を使い回しますが、`min-instances=0`\nで idle 中は無料です。タスクストアは **インメモリ** (Cloud SQL アタッチなし)\nなので、preview の chat 履歴はデプロイのたびに失われます。\n\nライフサイクル:\n\n- PR open / push: 自動デプロイ → URL を bot コメントで通知\n- PR close (merge / 不採用問わず): Cloud Run サービスを自動削除\n\n#### Auth (本番経由プロキシ)\n\nGoogle OAuth は redirect URI のワイルドカード非対応なので、PR ごとに変わる\npreview URL を都度登録するのは現実的でない。代わりに **preview は本番経由で\n認証を完結させる** 仕組みになっている:\n\n```\npreview /login\n   └─ \"Sign in\" を押すと →  prod /api/auth/login?preview=\u003cpreview-origin\u003e\u0026redirect=...\n                              │  state Cookie を prod ドメインに置いて Google へ\n                              ▼\n                          Google → prod /api/auth/callback\n                              │  token 交換 → userinfo → email allowlist\n                              │  state.previewOrigin が pattern にマッチすれば\n                              ▼\n                          handoff token (90s 有効) を URL に乗せて\n                              preview /api/auth/preview-callback?token=...\u0026redirect=...\n                                       │  AUTH_SECRET で検証\n                                       ▼\n                                  Session Cookie をセットして redirect 先へ\n```\n\n- Google OAuth client に登録する redirect URI は **本番の 1 つだけ** で OK。\n- 2 回目以降の preview ログインは prod 側のセッションがあれば Google を経由\n  せずに即 handoff される (= 1 クリックでログイン)。\n- `AUTH_SECRET` は本番と preview で共有 (Secret Manager の 1 つを両方が参照)。\n- preview は **`OAUTH_CLIENT_ID/SECRET` を持たない** (OAuth dance は prod 側だけ\n  が行うため)。\n- 必須の Variable: `CODEXWEB_AUTH_PROXY_URL` (preview に渡る、prod の URL)、\n  `CODEXWEB_PREVIEW_ORIGIN_PATTERN` (prod に渡る、preview origin を許可する\n  正規表現)。詳細は下記。\n\n#### 制約メモ\n\n- タスクは **インメモリ** 保持なので、リビジョン入れ替え (新規デプロイ)\n  で進行中タスクは失われます。本番運用するなら Firestore 等への永続化が\n  必要 (現状未対応)。\n- `--timeout=3600` を指定しているので Cloud Run としては 60 分まで SSE が\n  維持されます。それ以上のタスクは途中で切れるので、ローカル/専用 VM での\n  運用を推奨。\n\n## トラブルシュート\n\n### `Codex process error: spawn codex EACCES`\n\n`spawn \u003cbin\u003e EACCES` は Node が **`spawn` 失敗の汎用報告フォーマット** なので、\nファイル自体ではなく `cwd` への chdir 失敗でも同じメッセージが出ます。最も\nよくある原因は **bind-mount したホストディレクトリにコンテナ内ユーザーが\ntraverse できない** ケース。\n\n```bash\n# 直る組み合わせ (rootless Podman / Docker)\ndocker run --rm -p 3000:3000 --user 0 \\\n  --env-file .env \\\n  -v \"$PWD\":/workspace -e CODEX_DEFAULT_CWD=/workspace \\\n  codexweb:local\n```\n\n最新イメージは既定で root 起動なので `--user 0` は不要 (古いタグを使って\nいる場合のみ必要)。\n\n切り分け:\n\n```bash\n# コンテナ内で codex の実体と権限を確認\ndocker run --rm --entrypoint sh codexweb:local -c '\n  set -x;\n  command -v codex;\n  ls -la \"$(command -v codex)\";\n  readlink -f \"$(command -v codex)\";\n  ls -la \"$(readlink -f \"$(command -v codex)\")\";\n'\n```\n\n対処:\n\n1. **Apple Silicon (M1/M2/M3) の Mac で動かしている場合**\n   ローカルビルドはホストのアーキを使うので通常そのままで動きます。\n   どうしてもアーキを切り替えたいときは:\n   ```bash\n   docker buildx build --platform linux/arm64 -t codexweb:local --load .\n   # or\n   docker run --platform linux/arm64 ...\n   ```\n\n2. **手元の codex バイナリをマウントして使う**\n   ```bash\n   docker run --rm -p 3000:3000 \\\n     -e OPENAI_API_KEY=sk-... \\\n     -e CODEX_BIN=/opt/codex/codex \\\n     -v /usr/local/bin/codex:/opt/codex/codex:ro \\\n     codexweb:local\n   ```\n\n3. **イメージ内 codex の同梱をやめて自前で用意**\n   ```bash\n   docker build --build-arg INSTALL_CODEX=false -t codexweb .\n   # 起動時に CODEX_BIN を指定\n   ```\n\n### `codex_api::endpoint::responses_websocket: ... 401 Unauthorized`\n\nCodex CLI が `wss://api.openai.com/v1/responses` への接続で 401 を返すのは、\n`OPENAI_API_KEY` 環境変数だけだと WebSocket 側の認証経路が成立しないため。\n`codex login --with-api-key` で `~/.codex/auth.json` に key を焼き込んでおけば\n通ります。\n\n最新イメージは entrypoint がこれを自動で行うので、`OPENAI_API_KEY` を\n`.env` 経由で渡せば追加操作は不要です。手動でやる場合:\n\n```bash\ndocker exec -it \u003ccontainer\u003e sh -c '\n  printf \"%s\\n\" \"$OPENAI_API_KEY\" | codex login --with-api-key\n'\n```\n\nそれでも 401 が続く場合は、key が project-scoped で Responses API への\nアクセスが許可されていない / アカウントの tier が足りない可能性。OpenAI\nダッシュボードで該当 project の Model permissions を確認してください。\n\n### `spawn codex ENOENT`\n\nPATH に `codex` がない。`CODEX_BIN` に絶対パスを指定するか、`npm i -g @openai/codex`\n等でインストールしてください。\n\n## 既知の制約 (MVP)\n\n- タスクの永続化は **メモリのみ**。プロセス再起動で消えます。\n- マルチターン対話は、各ターンで `codex exec` を新規プロセスとして起動する\n  シンプル実装です (Codex 側の会話履歴は CLI の挙動に依存)。\n- 認証は Google OAuth のみサポート (`ALLOWED_EMAILS` でアカウント制限可)。\n- Codex CLI の `--json` 出力スキーマはバージョンにより差異があり、未知の\n  イベントは `stdout` として表示されます (`lib/codex-runner.ts` の\n  `mapCodexEvent` で必要に応じて拡張可能)。\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fslankdev%2Fcodexweb","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fslankdev%2Fcodexweb","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fslankdev%2Fcodexweb/lists"}