diff --git a/.claude-plugin/marketplace.json b/.claude-plugin/marketplace.json index d89207d..1a56f40 100644 --- a/.claude-plugin/marketplace.json +++ b/.claude-plugin/marketplace.json @@ -9,7 +9,7 @@ "name": "edgeone-makers-tools", "source": "./", "description": "EdgeOne Makers platform development skills — AI Agents, Cloud Functions, Edge Functions, Storage, Middleware, and Deployment.", - "version": "1.0.0", + "version": "2.0.0", "author": { "name": "EdgeOne" }, diff --git a/.claude-plugin/plugin.json b/.claude-plugin/plugin.json index 67296b5..d98eb53 100644 --- a/.claude-plugin/plugin.json +++ b/.claude-plugin/plugin.json @@ -1,7 +1,7 @@ { "name": "edgeone-makers-tools", "description": "EdgeOne Makers platform development skills — AI Agents, Cloud Functions, Edge Functions, Storage, Middleware, and Deployment.", - "version": "1.0.0", + "version": "2.0.0", "author": { "name": "EdgeOne" } diff --git a/.codebuddy-plugin/manifest.json b/.codebuddy-plugin/manifest.json index 9e7ad70..6c93e1c 100644 --- a/.codebuddy-plugin/manifest.json +++ b/.codebuddy-plugin/manifest.json @@ -1,16 +1,9 @@ { "name": "edgeone-makers-tools", "description": "EdgeOne Makers platform development skills — AI Agents, Cloud Functions, Edge Functions, Storage, Middleware, and Deployment.", - "version": "1.0.0", + "version": "2.0.0", "author": "EdgeOne", "skills": [ - "skills/makers-agents", - "skills/makers-deploy", - "skills/makers-edge-functions", - "skills/makers-cloud-functions", - "skills/makers-storage", - "skills/makers-middleware", - "skills/makers-cli", - "skills/makers-recipes" + "skills/edgeone-makers-tools" ] } diff --git a/.codebuddy-plugin/marketplace.json b/.codebuddy-plugin/marketplace.json index b0d7768..5440d7f 100644 --- a/.codebuddy-plugin/marketplace.json +++ b/.codebuddy-plugin/marketplace.json @@ -9,20 +9,13 @@ "name": "edgeone-makers-tools", "source": "./", "description": "EdgeOne Makers platform development skills — AI Agents, Cloud Functions, Edge Functions, Storage, Middleware, and Deployment.", - "version": "1.0.0", + "version": "2.0.0", "author": { "name": "EdgeOne" }, "strict": false, "skills": [ - "./skills/makers-agents", - "./skills/makers-deploy", - "./skills/makers-edge-functions", - "./skills/makers-cloud-functions", - "./skills/makers-storage", - "./skills/makers-middleware", - "./skills/makers-cli", - "./skills/makers-recipes" + "./skills/edgeone-makers-tools" ], "hooks": "./hooks/hooks.json" } diff --git a/.cursor-plugin/plugin.json b/.cursor-plugin/plugin.json index 67296b5..d98eb53 100644 --- a/.cursor-plugin/plugin.json +++ b/.cursor-plugin/plugin.json @@ -1,7 +1,7 @@ { "name": "edgeone-makers-tools", "description": "EdgeOne Makers platform development skills — AI Agents, Cloud Functions, Edge Functions, Storage, Middleware, and Deployment.", - "version": "1.0.0", + "version": "2.0.0", "author": { "name": "EdgeOne" } diff --git a/AGENTS.md b/AGENTS.md index 971f5b4..4b42dae 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -4,14 +4,14 @@ When you need EdgeOne Makers platform development guidance, read the matching Sk | Task | Read | |------|------| -| AI Agent development (DeepAgents, LangGraph, Claude SDK, OpenAI Agents, CrewAI) | skills/makers-agents/SKILL.md | -| Migrate existing agent project to EdgeOne Makers format | skills/makers-migration/SKILL.md | -| Deploy project to EdgeOne | skills/makers-deploy/SKILL.md | -| Edge Functions (V8 lightweight functions) | skills/makers-edge-functions/SKILL.md | -| Cloud Functions (Node.js / Go / Python APIs) | skills/makers-cloud-functions/SKILL.md | -| KV + Blob Storage | skills/makers-storage/SKILL.md | -| Middleware (auth, rewrites, routing) | skills/makers-middleware/SKILL.md | -| CLI command reference | skills/makers-cli/SKILL.md | -| Project structure / scaffolding | skills/makers-recipes/SKILL.md | +| AI Agent development (DeepAgents, LangGraph, Claude SDK, OpenAI Agents, CrewAI) | skills/edgeone-makers-tools/references/makers-agents/SKILL.md | +| Migrate existing agent project to EdgeOne Makers format | skills/edgeone-makers-tools/references/makers-migration/SKILL.md | +| Deploy project to EdgeOne | skills/edgeone-makers-tools/references/makers-deploy/SKILL.md | +| Edge Functions (V8 lightweight functions) | skills/edgeone-makers-tools/references/makers-edge-functions/SKILL.md | +| Cloud Functions (Node.js / Go / Python APIs) | skills/edgeone-makers-tools/references/makers-cloud-functions/SKILL.md | +| KV + Blob Storage | skills/edgeone-makers-tools/references/makers-storage/SKILL.md | +| Middleware (auth, rewrites, routing) | skills/edgeone-makers-tools/references/makers-middleware/SKILL.md | +| CLI command reference | skills/edgeone-makers-tools/references/makers-cli/SKILL.md | +| Project structure / scaffolding | skills/edgeone-makers-tools/references/makers-recipes/SKILL.md | ⚠️ Only read the Skill relevant to the current task. Do not load all skills at once. diff --git a/CLAUDE.md b/CLAUDE.md index aa2e78a..b34fa99 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -4,15 +4,16 @@ When you need EdgeOne Makers platform development guidance, read the matching Sk | Task | Read | |------|------| -| AI Agent development (DeepAgents, LangGraph, Claude SDK, OpenAI Agents, CrewAI) | skills/makers-agents/SKILL.md | -| Migrate existing agent project to EdgeOne Makers format | skills/makers-migration/SKILL.md | -| Deploy project to EdgeOne | skills/makers-deploy/SKILL.md | -| Edge Functions (V8 lightweight functions) | skills/makers-edge-functions/SKILL.md | -| Cloud Functions (Node.js / Go / Python APIs) | skills/makers-cloud-functions/SKILL.md | -| KV + Blob Storage | skills/makers-storage/SKILL.md | -| Middleware (auth, rewrites, routing) | skills/makers-middleware/SKILL.md | -| CLI command reference | skills/makers-cli/SKILL.md | -| Project structure / scaffolding | skills/makers-recipes/SKILL.md | -| Environment adaptation (WorkBuddy / sandbox / CI) | skills/makers-env-adaption/SKILL.md | +| AI Agent development (DeepAgents, LangGraph, Claude SDK, OpenAI Agents, CrewAI) | skills/edgeone-makers-tools/references/makers-agents/SKILL.md | +| Migrate existing agent project to EdgeOne Makers format | skills/edgeone-makers-tools/references/makers-migration/SKILL.md | +| Deploy project to EdgeOne | skills/edgeone-makers-tools/references/makers-deploy/SKILL.md | +| Edge Functions (V8 lightweight functions) | skills/edgeone-makers-tools/references/makers-edge-functions/SKILL.md | +| Cloud Functions (Node.js / Go / Python APIs) | skills/edgeone-makers-tools/references/makers-cloud-functions/SKILL.md | +| KV + Blob Storage | skills/edgeone-makers-tools/references/makers-storage/SKILL.md | +| Persist dynamic data for a site (messages, uploads, votes, save-state) — **no database; use Blob** | skills/edgeone-makers-tools/references/makers-storage/SKILL.md | +| Middleware (auth, rewrites, routing) | skills/edgeone-makers-tools/references/makers-middleware/SKILL.md | +| CLI command reference | skills/edgeone-makers-tools/references/makers-cli/SKILL.md | +| Project structure / scaffolding | skills/edgeone-makers-tools/references/makers-recipes/SKILL.md | +| Environment adaptation (WorkBuddy / sandbox / CI) | skills/edgeone-makers-tools/references/makers-env-adaption/SKILL.md | ⚠️ Only read the Skill relevant to the current task. Do not load all skills at once. diff --git a/README.md b/README.md index 2808053..0fce020 100644 --- a/README.md +++ b/README.md @@ -10,26 +10,16 @@ Official AI Agent Skills for developing and deploying projects on [EdgeOne Maker npx skills add TencentEdgeOne/edgeone-makers-tools ``` -This installs **9 independent sub-skills** (one per capability) into your -agent's skills directory (`.codebuddy/skills//`, `.claude/skills//`, -`.cursor/skills//`, …). Your agent loads only the matching skill per -task — no router indirection. +This installs **one skill — `edgeone-makers-tools`** into your agent's skills +directory (`.codebuddy/skills/edgeone-makers-tools/`, `.claude/skills/edgeone-makers-tools/`, +`.cursor/skills/edgeone-makers-tools/`, …). Its `SKILL.md` is a router that loads the +matching capability under `references/` on demand — one skill in your list, full +coverage inside. ### Option B — CodeBuddy plugin marketplace / SkillHub Search and install `edgeone-makers-tools` from the CodeBuddy plugin marketplace or -SkillHub. These platforms install the skill from the -[`skillhub`](https://github.com/TencentEdgeOne/edgeone-makers-tools/tree/skillhub) -branch, which adds a frontmatter to the root `SKILL.md` so the platform can -register it as a single root skill (it then routes to the same 9 sub-skills -internally). - -> Why two branches? The two install ecosystems have **incompatible -> requirements** on the root `SKILL.md` (one wants no frontmatter, the other -> requires one). The `main` branch is optimized for `npx skills add`; the -> `skillhub` branch is optimized for CodeBuddy / SkillHub. See -> [`BRANCH.md`](https://github.com/TencentEdgeOne/edgeone-makers-tools/blob/skillhub/BRANCH.md) -> on the `skillhub` branch for the maintenance flow. +SkillHub. They register the same single `edgeone-makers-tools` skill. ### Option C — Claude Code plugin marketplace @@ -40,9 +30,11 @@ internally). After installation, your AI coding agent will automatically detect relevant tasks and load the right skill. -## Skills +## Capabilities -| Skill | Description | +The single `edgeone-makers-tools` skill routes to these capabilities (each lives under `skills/edgeone-makers-tools/references//`): + +| Capability | Description | |-------|-------------| | `makers-agents` | AI Agent development (DeepAgents, LangGraph, Claude SDK, OpenAI Agents, CrewAI) | | `makers-deploy` | Deploy projects to EdgeOne | @@ -52,6 +44,8 @@ After installation, your AI coding agent will automatically detect relevant task | `makers-middleware` | Middleware (auth, rewrites, routing) | | `makers-cli` | CLI command reference | | `makers-recipes` | Project structure templates & scaffolding | +| `makers-migration` | Migrate existing agent projects to EdgeOne Makers | +| `makers-env-adaption` | Environment adaptation (WorkBuddy / sandbox / CI) | ## Usage Examples @@ -99,34 +93,32 @@ Create a Claude Agent SDK endpoint with sandbox code execution ## Skill Structure +One skill, capabilities bundled as reference docs it routes to on demand: + ``` skills/ -├── makers-agents/ # AI Agent development -│ ├── SKILL.md # Decision tree, red lines, framework routing -│ └── references/ -│ ├── platform/ # Entry conventions, env, SSE protocol -│ ├── capabilities/ # Store, sandbox, tools -│ ├── node-frameworks/ # Claude SDK, LangGraph, OpenAI Agents, DeepAgents -│ └── python-frameworks/ # Claude SDK, LangGraph, OpenAI Agents, DeepAgents, CrewAI -├── makers-deploy/ # Deployment workflow -│ ├── SKILL.md -│ └── references/ -├── makers-edge-functions/ # V8 edge runtime -│ └── SKILL.md -├── makers-cloud-functions/ # Node.js / Go / Python -│ ├── SKILL.md -│ └── references/ -├── makers-storage/ # KV + Blob storage -│ └── SKILL.md -├── makers-middleware/ # Request interception -│ └── SKILL.md -├── makers-cli/ # CLI commands -│ └── SKILL.md -└── makers-recipes/ # Project templates - └── SKILL.md -``` - -Each skill follows the [skill-creator](https://github.com/anthropics/skills) standard: +└── edgeone-makers-tools/ + ├── SKILL.md # Router — matches the task, loads a capability below + └── references/ + ├── makers-agents/ # AI Agent development + │ ├── SKILL.md # Decision tree, red lines, framework routing + │ └── references/ + │ ├── platform/ # Entry conventions, env, SSE protocol + │ ├── capabilities/ # Store, sandbox, tools + │ ├── node-frameworks/ # Claude SDK, LangGraph, OpenAI Agents, DeepAgents + │ └── python-frameworks/ # Claude SDK, LangGraph, OpenAI Agents, DeepAgents, CrewAI + ├── makers-deploy/ # Deployment workflow + ├── makers-edge-functions/ # V8 edge runtime + ├── makers-cloud-functions/ # Node.js / Go / Python + ├── makers-storage/ # KV + Blob storage + ├── makers-middleware/ # Request interception + ├── makers-cli/ # CLI commands + ├── makers-recipes/ # Project templates + ├── makers-migration/ # Migrate existing agent projects + └── makers-env-adaption/ # Sandbox / WorkBuddy / CI adaptation +``` + +The skill follows the [skill-creator](https://github.com/anthropics/skills) standard: - `SKILL.md` — YAML frontmatter (name + description) + core instructions - `references/` — detailed docs loaded on demand, routed from `SKILL.md` diff --git a/SKILL.md b/SKILL.md deleted file mode 100644 index a4ca7f5..0000000 --- a/SKILL.md +++ /dev/null @@ -1,17 +0,0 @@ -# EdgeOne Makers Skills - -When you need EdgeOne Makers platform development guidance, read the matching Skill based on the task: - -| Task | Read | -|------|------| -| AI Agent development (DeepAgents, LangGraph, Claude SDK, OpenAI Agents, CrewAI) | skills/makers-agents/SKILL.md | -| Deploy project to EdgeOne | skills/makers-deploy/SKILL.md | -| Edge Functions (V8 lightweight functions) | skills/makers-edge-functions/SKILL.md | -| Cloud Functions (Node.js / Go / Python APIs) | skills/makers-cloud-functions/SKILL.md | -| KV + Blob Storage | skills/makers-storage/SKILL.md | -| Middleware (auth, rewrites, routing) | skills/makers-middleware/SKILL.md | -| CLI command reference | skills/makers-cli/SKILL.md | -| Project structure / scaffolding | skills/makers-recipes/SKILL.md | -| Environment adaptation (WorkBuddy / sandbox / CI) | skills/makers-env-adaption/SKILL.md | - -⚠️ Only read the Skill relevant to the current task. Do not load all skills at once. diff --git a/_meta.json b/_meta.json index 2bd2717..d28c7b0 100644 --- a/_meta.json +++ b/_meta.json @@ -2,45 +2,53 @@ "ownerId": "442102", "publishedAt": 1781766512723, "slug": "edgeone-makers-tools", - "version": "1.0.4", + "version": "2.0.0", "files": [ - "SKILL.md", "CLAUDE.md", - "skills/makers-agents/SKILL.md", - "skills/makers-agents/references/capabilities/sandbox.md", - "skills/makers-agents/references/capabilities/store.md", - "skills/makers-agents/references/capabilities/tools.md", - "skills/makers-agents/references/framework-native-patterns.md", - "skills/makers-agents/references/node-frameworks/claude-sdk.md", - "skills/makers-agents/references/node-frameworks/deepagents.md", - "skills/makers-agents/references/node-frameworks/langgraph.md", - "skills/makers-agents/references/node-frameworks/openai-agents.md", - "skills/makers-agents/references/platform/cloud-functions.md", - "skills/makers-agents/references/platform/conversation-id.md", - "skills/makers-agents/references/platform/env-and-model.md", - "skills/makers-agents/references/platform/node-entry.md", - "skills/makers-agents/references/platform/python-entry.md", - "skills/makers-agents/references/platform/sse-protocol.md", - "skills/makers-agents/references/python-frameworks/claude-sdk.md", - "skills/makers-agents/references/python-frameworks/crewai.md", - "skills/makers-agents/references/python-frameworks/deepagents.md", - "skills/makers-agents/references/python-frameworks/langgraph.md", - "skills/makers-agents/references/python-frameworks/openai-agents.md", - "skills/makers-agents/references/review-checklist.md", - "skills/makers-cli/SKILL.md", - "skills/makers-cloud-functions/SKILL.md", - "skills/makers-cloud-functions/references/go-functions.md", - "skills/makers-cloud-functions/references/node-functions.md", - "skills/makers-cloud-functions/references/python-functions.md", - "skills/makers-cloud-functions/references/troubleshooting.md", - "skills/makers-deploy/SKILL.md", - "skills/makers-deploy/references/command-reference.md", - "skills/makers-edge-functions/SKILL.md", - "skills/makers-env-adaption/SKILL.md", - "skills/makers-middleware/SKILL.md", - "skills/makers-recipes/SKILL.md", - "skills/makers-storage/SKILL.md", - "skills/makers-storage/references/blob.md", - "skills/makers-storage/references/kv.md" + "skills/edgeone-makers-tools/SKILL.md", + "skills/edgeone-makers-tools/references/makers-agents/SKILL.md", + "skills/edgeone-makers-tools/references/makers-agents/references/capabilities/sandbox.md", + "skills/edgeone-makers-tools/references/makers-agents/references/capabilities/store.md", + "skills/edgeone-makers-tools/references/makers-agents/references/capabilities/tools.md", + "skills/edgeone-makers-tools/references/makers-agents/references/framework-native-patterns.md", + "skills/edgeone-makers-tools/references/makers-agents/references/node-frameworks/claude-sdk.md", + "skills/edgeone-makers-tools/references/makers-agents/references/node-frameworks/deepagents.md", + "skills/edgeone-makers-tools/references/makers-agents/references/node-frameworks/langgraph.md", + "skills/edgeone-makers-tools/references/makers-agents/references/node-frameworks/openai-agents.md", + "skills/edgeone-makers-tools/references/makers-agents/references/platform/cloud-functions.md", + "skills/edgeone-makers-tools/references/makers-agents/references/platform/conversation-id.md", + "skills/edgeone-makers-tools/references/makers-agents/references/platform/env-and-model.md", + "skills/edgeone-makers-tools/references/makers-agents/references/platform/node-entry.md", + "skills/edgeone-makers-tools/references/makers-agents/references/platform/python-entry.md", + "skills/edgeone-makers-tools/references/makers-agents/references/platform/sse-protocol.md", + "skills/edgeone-makers-tools/references/makers-agents/references/python-frameworks/claude-sdk.md", + "skills/edgeone-makers-tools/references/makers-agents/references/python-frameworks/crewai.md", + "skills/edgeone-makers-tools/references/makers-agents/references/python-frameworks/deepagents.md", + "skills/edgeone-makers-tools/references/makers-agents/references/python-frameworks/langgraph.md", + "skills/edgeone-makers-tools/references/makers-agents/references/python-frameworks/openai-agents.md", + "skills/edgeone-makers-tools/references/makers-agents/references/review-checklist.md", + "skills/edgeone-makers-tools/references/makers-cli/SKILL.md", + "skills/edgeone-makers-tools/references/makers-cloud-functions/SKILL.md", + "skills/edgeone-makers-tools/references/makers-cloud-functions/references/go-functions.md", + "skills/edgeone-makers-tools/references/makers-cloud-functions/references/node-functions.md", + "skills/edgeone-makers-tools/references/makers-cloud-functions/references/python-functions.md", + "skills/edgeone-makers-tools/references/makers-cloud-functions/references/troubleshooting.md", + "skills/edgeone-makers-tools/references/makers-deploy/SKILL.md", + "skills/edgeone-makers-tools/references/makers-deploy/references/command-reference.md", + "skills/edgeone-makers-tools/references/makers-edge-functions/SKILL.md", + "skills/edgeone-makers-tools/references/makers-env-adaption/SKILL.md", + "skills/edgeone-makers-tools/references/makers-middleware/SKILL.md", + "skills/edgeone-makers-tools/references/makers-migration/SKILL.md", + "skills/edgeone-makers-tools/references/makers-migration/references/api-route-to-makers.md", + "skills/edgeone-makers-tools/references/makers-migration/references/claude-agent-sdk-to-makers.md", + "skills/edgeone-makers-tools/references/makers-migration/references/crewai-to-makers.md", + "skills/edgeone-makers-tools/references/makers-migration/references/deepagents-to-makers.md", + "skills/edgeone-makers-tools/references/makers-migration/references/langgraph-to-makers.md", + "skills/edgeone-makers-tools/references/makers-migration/references/openai-agents-to-makers.md", + "skills/edgeone-makers-tools/references/makers-recipes/SKILL.md", + "skills/edgeone-makers-tools/references/makers-recipes/references/youth-site-scenarios.md", + "skills/edgeone-makers-tools/references/makers-storage/SKILL.md", + "skills/edgeone-makers-tools/references/makers-storage/references/blob.md", + "skills/edgeone-makers-tools/references/makers-storage/references/kv.md" ] -} \ No newline at end of file +} diff --git a/codex/makers-agents.md b/codex/makers-agents.md index 0dc498c..474e539 100644 --- a/codex/makers-agents.md +++ b/codex/makers-agents.md @@ -38,7 +38,7 @@ This skill covers five supported frameworks (DeepAgents, LangGraph, CrewAI, Open - Calling sandbox or platform tools via `context.sandbox` / `context.tools` - Splitting AI inference (`agents/`) from data CRUD (`cloud-functions/`) -> Cross-reference: if your code uses `context.store` or KV APIs, also read `skills/makers-storage/SKILL.md`. +> Cross-reference: if your code uses `context.store` or KV APIs, also read `../makers-storage/SKILL.md`. **Do NOT use for:** - Plain Edge Functions / Cloud Functions / Middleware → use `edgeone-pages-dev` diff --git a/codex/makers-cli.md b/codex/makers-cli.md index ea6e420..90437ca 100644 --- a/codex/makers-cli.md +++ b/codex/makers-cli.md @@ -1,5 +1,5 @@ --- -name: makers-cli +name: edgeone-makers-cli description: >- EdgeOne Makers CLI command reference. Use when running edgeone CLI commands for dev, build, deploy, env management. diff --git a/codex/makers-cloud-functions.md b/codex/makers-cloud-functions.md index 26fac3d..7b8ce09 100644 --- a/codex/makers-cloud-functions.md +++ b/codex/makers-cloud-functions.md @@ -1,5 +1,5 @@ --- -name: makers-cloud-functions +name: edgeone-makers-cloud-functions description: >- EdgeOne Makers Cloud Functions — Node.js, Go, and Python runtimes. Use when building server-side APIs, Express/Koa patterns, or backend logic. diff --git a/codex/makers-deploy.md b/codex/makers-deploy.md index 2d0f3e3..dc2dff9 100644 --- a/codex/makers-deploy.md +++ b/codex/makers-deploy.md @@ -39,15 +39,18 @@ Deploy any project to **EdgeOne Makers**. **Self-check after writing your reply**: scan for every instance of the `.edgeone.cool` domain. Does each one include `?eo_token=`? If any doesn't, fix it NOW — the user will get a 401. 3a. **Prefer `--json` when running non-interactively** — in Agent/CI/headless contexts, always pass `--json` to `deploy` so the result is a single machine-readable line; no need to scrape colored/`\r`-animated stdout. See **Parse Deploy Output**. 3b. **Use `edgeone whoami` to check login status** — on CLI ≥ 1.6.0, `whoami` fails fast (exit 1) when not logged in instead of hanging. If it exits 0, the user is already logged in and `-t` is not needed. **Do NOT** check `cat .edgeone/.token` — CLI stores credentials in `~/.edgeone/` files, not a fixed `.token` path. -4. **⚠️ The deploy URL MUST be placed prominently at the very top of your reply** — once deployment finishes, the complete access URL is the core deliverable the user cares about most. You MUST: ① place it on the first line or in the first standalone block of your reply body; ② use a prominent format (e.g. a large heading + code block); ③ never bury the URL in the middle of a long paragraph where the user has to hunt for it. Example format: +4. **The deploy URL MUST be placed at the very top of the visible reply body (own line, code block, or heading — not inline, not mid-reply), AND ALSO pinned via `present_files` (or the IDE's preview tool) to the side panel.** Two UI failures to survive: thinking / reasoning / "深度思考" blocks hide content by default; long replies get auto-folded by IDE chat cards, burying anything placed mid-reply. `present_files` is unaffected by chat folding — that's the second, always-visible channel. Complete URL, no truncation (Rule 2). Example format: ``` 🌐 Live URL: https://my-project-abc123.edgeone.cool? ``` Then append any other notes (console URL, caveats, etc.). + + **Self-check before ending the turn (MANDATORY)** — read back what the user will actually SEE (NOT your thinking / reasoning content). Two questions: (a) Is the complete `.edgeone.cool` URL present at the top of the visible reply, in a code block or heading? (b) Was `present_files` called with that URL? If either answer is no, send an **additional short message** containing ONLY the `🌐 Live URL: ` block and call `present_files`. Do not end the turn until both channels carry the URL. "I already mentioned it in my reasoning" is NOT a substitute for placing it in the visible body. 5. **Ask the user to choose China or Global site** before browser login. Never assume. (Token login via `edgeone login --token` auto-detects site, no need to ask.) -6. **Auto-detect the login method** — browser login in desktop environments, token login in headless/remote/CI environments. Follow the decision table below. +6. **Prefer Browser Login; fall back to Token only after browser login is confirmed to fail** (see Login section for the ~60s fallback threshold and the Agent-in-IDE clarification — WorkBuddy is NOT headless). Token-first only when the user explicitly requests it. 7. **After token login, ask if the user wants to save the token locally** for future use. 8. **Before triggering any browser popup (login / registration), explain the reason and the benefits to the user first** — never silently launch a browser window. +9. **On any CLI failure, surface the actual error text to the user before retrying, switching commands, or proposing a workaround.** Do NOT paraphrase (e.g. don't rewrite `Makers project exceeds 40 limit` into "maybe a name conflict or permission"). Do NOT silently pivot from `makers dev` to `makers deploy` (or vice versa) hoping to bypass — a systemic failure (auth / quota / permission) hits both with the same cause. Quote the raw error, name the root cause, then propose the fix or ask the user. --- @@ -85,6 +88,13 @@ edgeone whoami # If exit 0 → logged in, no -t needed # If exit 1 → not logged in, need token or browser login +# NOTE: This auth gate is for `deploy` (account-bound upload to your EdgeOne +# account). For `edgeone makers dev` (local preview), login is ONLY required +# when the project uses Blob/credentialed backends — a pure-static dev needs +# no login. When Blob IS used, the chain is: Blob → must be linked → linking +# requires login, so login before linking/starting dev. See makers-storage / +# makers-env-adaption for the dev auth rule and the link chain. + # Check 3: Project already linked? cat edgeone.json 2>/dev/null ``` @@ -96,8 +106,8 @@ cat edgeone.json 2>/dev/null | Not installed or < 1.6.0 | — | → Go to **Install CLI** | | `≥ 1.6.0` ✓ | Logged in (or token present) | → Go to **Deploy** | | `≥ 1.6.0` ✓ | Not logged in, has saved token | → Go to **Deploy with Token** (use saved token) | -| `≥ 1.6.0` ✓ | Not logged in, no saved token, **interactive desktop** | → Go to **Login** (browser) | -| `≥ 1.6.0` ✓ | Not logged in, no saved token, **non-interactive (Agent/CI/headless)** | → Ask user for a **token**; browser login is unavailable and `deploy` will fail fast with a token hint | +| `≥ 1.6.0` ✓ | Not logged in, no saved token | → **Try Browser Login first** (see Login section). If the browser doesn't open or nothing happens within ~60 seconds, **fall back to Token Login**. Do NOT preemptively skip browser login by guessing "this looks like an Agent/CI environment" — that guess is often wrong. In particular, **WorkBuddy is a desktop IDE sandbox and fully supports browser login** (host browser + OAuth callback are bridged into the sandbox). | +| `≥ 1.6.0` ✓ | User explicitly provides a token or requests token login | → Go to **Deploy with Token** / **Token Login** | --- @@ -125,7 +135,7 @@ Tell the user: > - **What happens next**: I'll run `edgeone login`, and your default browser will open the Tencent Cloud login page. Please complete the login/registration and authorize access, then come back here. > - **If you get stuck**: If the browser doesn't open, or the CLI keeps waiting after you've logged in, let me know — I'll switch to Token login instead. -If the user does not respond for an extended period (e.g., more than 1–2 minutes), **proactively ask** about their status (whether the browser opened, any errors, or if they want to switch to Token login). Do not wait indefinitely. +If the user does not respond within ~60 seconds (no browser popup or no progress reported), **proactively ask** about their status (whether the browser opened, any errors, or if they want to switch to Token login). Do not wait indefinitely. ### 1. Ask the user to choose a site, then ALWAYS pass `--site` @@ -142,13 +152,14 @@ On CLI ≥ 1.6.0, a bare `login` in a non-interactive context fails fast asking `--site` (it no longer pops an interactive site-picker that would hang). The site choice is meant to happen here in the conversation, not inside the CLI. -### 2. Detect environment and choose login method +### 2. Login methods reference -| Condition | Method | -|-----------|--------| -| Local desktop IDE (VS Code, Cursor, WorkBuddy, etc.) | **Browser Login** | -| Remote / SSH / container / CI / cloud IDE / headless | **Token Login** | -| User explicitly requests token | **Token Login** | +Two login methods are available. **Per Rule 6, always try Browser Login first**; the table below is a reference for when each method applies, not a decision procedure — do not use it to guess the environment. + +| Method | When it applies | +|--------|-----------------| +| **Browser Login** | Default. Works in all local desktop IDEs (VS Code, Cursor, WorkBuddy) — the IDE bridges the OS browser + OAuth callback into the sandbox. | +| **Token Login** | Fallback after Browser Login is confirmed to fail (no browser popup / no progress within ~60s), OR when the user explicitly provides a token or requests token login. Also the only option in truly detached environments (SSH-only, CI runners, browserless containers). | #### Browser Login @@ -180,6 +191,8 @@ edgeone login --token Auto-detects china/global from the token — no `--site` flag needed. Persists login state for subsequent commands. +> 💡 **Reuse the token from a prior browser login — no console trip needed.** `edgeone login --site ` (browser) auto-generates an API Token and writes it to `~/.edgeone/` (JSON with `value.Token`). You can reuse that `Token` value directly as `EDGEONE_PAGES_API_TOKEN=""` or `-t ` for `makers dev`/`deploy` in headless/agent contexts, instead of creating a new token in the console. + **Method B: Pass `-t` directly in deploy (per-invocation)** Token is used for that single deploy only; no persistent login state is saved. @@ -324,7 +337,7 @@ https://console.cloud.tencent.com/edgeone/pages/project/pages-xxxxxxxx/deploymen | **Project ID** | Value after `EDGEONE_PROJECT_ID=` | — | | **Console URL** | Line after "You can view your deployment..." | — | -**Show the user — the deploy URL MUST be placed at the very top of your reply, in the most prominent position:** +**Show the user — the deploy URL MUST be at the very top of the visible reply AND pinned via `present_files` to the side panel (see Rule 4 for why both channels are required):** ⚠️ **URL Integrity Rules (read before composing your reply):** @@ -358,8 +371,12 @@ https://console.cloud.tencent.com/edgeone/pages/project/pages-xxxxxxxx/deploymen | Auth error with token | Token may be expired — regenerate at the console | | Login appears successful but `deploy` reports auth error | Browser reused a session from the wrong site, binding the wrong account. Click "Sign in with a different account" on the login page, or log out from all Tencent Cloud consoles first | | `edgeone whoami` shows an unexpected account | Browser session reuse. Click "Sign in with a different account" or log out from all consoles and re-login | +| `Failed to create pages project` (dev) / `Makers project exceeds 40 limit` (deploy) | Account hit the **40-project cap**. Both dev and deploy fail the same way. Present ONLY these two options to the user, verbatim — no "recommended" tag on either, no third option (do NOT suggest CloudStudio or any other platform, do NOT invent alternatives): ① user deletes an unused project in the EdgeOne Makers console; ② user names an existing linked project via `-n `. Agent MUST NOT delete projects itself (CLI has no delete command by design — do not route around via HTTP APIs or cached credentials). | | Project name conflict | Use a different name with `-n` | | Build failure | Check logs — usually missing deps or bad build script | +| `whoami` says "not authenticated" but `edgeone login` just succeeded | Expected in agent/headless: `whoami` and `makers dev`/`deploy` read API-Token auth, not the browser session. Reuse the auto-generated token from `~/.edgeone/` (`value.Token`) as `EDGEONE_PAGES_API_TOKEN` / `-t`. See Token Login note above. | +| `makers dev` hangs on an interactive "Link existing / Create and link" menu | Dev was started without `-n` and fell into the interactive picker. Kill it, then restart with `edgeone makers dev -n --skip-env-sync` — dev auto-creates the project if missing and links it internally. Always pass `-n` to dev whenever the project uses Blob/KV. | +| `curl` to the deploy URL returns 302 → DingTalk SSO login | Preview gateway requires browser-based `eo_token` validation (JS), which `curl` can't do. Open the full `?eo_token=...&eo_time=...` URL in a real browser — it validates the token and bypasses SSO. Not a code bug. | --- diff --git a/codex/makers-edge-functions.md b/codex/makers-edge-functions.md index 7345171..b7d0502 100644 --- a/codex/makers-edge-functions.md +++ b/codex/makers-edge-functions.md @@ -108,9 +108,9 @@ export function onRequest(context) { ## KV Storage (Edge Functions only) -> Cross-reference: if your code uses `context.store` or KV APIs, also read `skills/makers-storage/SKILL.md`. +> Cross-reference: if your code uses `context.store` or KV APIs, also read `../makers-storage/SKILL.md`. -⚠️ **Prerequisites**: You must enable KV Storage in the EdgeOne Makers console, create a namespace, and bind it to your project before using KV. See [kv-storage.md](kv-storage.md) for full setup instructions (same directory). +⚠️ **Prerequisites**: You must enable KV Storage in the EdgeOne Makers console, create a namespace, and bind it to your project before using KV. See [../makers-storage/references/kv.md](../makers-storage/references/kv.md) for full setup instructions. The KV namespace is a **global variable** (name is set when binding in the console) — it is **NOT** on `context.env`. @@ -134,7 +134,7 @@ export async function onRequest(context) { } ``` -For full KV Storage API reference and usage guide, see: [kv-storage.md](kv-storage.md) (same directory). +For full KV Storage API reference and usage guide, see: [../makers-storage/references/kv.md](../makers-storage/references/kv.md). ## Supported Runtime APIs diff --git a/codex/makers-env-adaption.md b/codex/makers-env-adaption.md index 4c6fcc3..495ae8a 100644 --- a/codex/makers-env-adaption.md +++ b/codex/makers-env-adaption.md @@ -3,14 +3,13 @@ name: edgeone-makers-env-adaption description: >- Environment-specific adaptation rules for EdgeOne Makers Skills running in sandboxed or restricted AI coding environments (e.g. WorkBuddy). - Trigger when: the user is working in WorkBuddy, a sandboxed IDE, or any - non-interactive/CI environment where CLI commands may hang or network is isolated. + Trigger when: the user is working in WorkBuddy or a sandboxed IDE where CLI prompts hang and network is proxy-isolated (but browser login still works). Covers: non-interactive CLI flags, network isolation workarounds, login in sandbox, proxy bypass, file preview constraints (MUST use http:// via dev server, NEVER file://, NEVER python -m http.server / npx serve), dev server requirements. metadata: author: edgeone - version: "1.1.0" + version: "1.1.1" --- # Runtime Environment Adaptation Guide @@ -38,7 +37,8 @@ preview │ ┌─ dev server running? ─ Yes ── | Preview local dev server | `present_files("http://127.0.0.1:8088/")` | ❌ Passing `/path/to/index.html` (IDE opens it via file://) | | Preview a deployed project | `present_files(deploy_url)` with `?eo_token=...` | ❌ Passing a local `dist/index.html` path | | Start dev server | `edgeone makers dev --name

--skip-env-sync` | ❌ `python -m http.server` / `npx serve` | -| Verify dev server is up | `present_files(http://...)` or the user's system terminal | ❌ Bash `curl localhost` (sandbox network isolation) | +| Verify dev server is up (agent-side API check) | `curl --noproxy '*' http://127.0.0.1:8088/api/...` ✅ works (same sandbox) | ❌ `curl localhost:8088` / plain `curl` (proxy + IPv6 → 404/000) | +| Verify dev server is up (user-facing) | `present_files(http://127.0.0.1:8088/)` (platform tunnel) | ❌ Telling user to open `127.0.0.1:8088` — their browser can't reach the sandbox | **Core iron rule**: inside a Makers project, **any HTML / URL preview MUST go through the HTTP protocol**. `file://` looks convenient, but fetch / SSE / Blob / KV all break under it. @@ -55,6 +55,12 @@ preview │ ┌─ dev server running? ─ Yes ── WorkBuddy is a sandboxed remote IDE environment. When running AI coding tasks, it has the following constraints that differ from local development. +> **⚠️ Common misread: WorkBuddy is a *desktop IDE sandbox*, NOT a headless environment.** +> - CLI **interactive prompts** (site picker, confirmations) hang inside the sandbox → use the non-interactive flags in this section. +> - **BUT browser login (`edgeone login --site `) works fully** — WorkBuddy launches the host OS browser AND routes the OAuth callback back into the sandbox. +> +> Deploy/link login should default to browser login and only fall back to `-t ` after browser login is confirmed to fail. Do NOT jump to token login just because the caller is an "Agent". + --- ### 1. Non-interactive mode (all CLI commands must avoid interactive prompts) @@ -100,21 +106,25 @@ edgeone login --site china --local edgeone whoami # exit 0 = logged in, exit 1 = not logged in (does not hang) ``` +**When is login actually required?** Login is only needed when the project uses **Blob** or other credentialed backends — and strictly because of the dependency chain: **Blob requires the project to be linked, and linking requires a logged-in account first.** So `edgeone makers dev` for a **pure-static** site runs fine without login — **do NOT force a login prompt for static-only previews**. Login (or `-t `) becomes mandatory the moment dev/deploy must touch Blob storage. (The trigger condition and the link chain live in makers-storage.) + **CLI version requirement**: >= 1.6.7 (older versions lack the non-interactive fixes; whoami will hang) --- -### 3. Network isolation +### 3. Network isolation (dev server reachability from Bash) -**The Bash tool's network is isolated from the host** — inside WorkBuddy's Bash, `curl localhost:` cannot reach the host's dev server. +The Bash tool and `edgeone makers dev` run **in the same sandbox (same machine)**, so the loopback dev server IS reachable from Bash. The earlier claim that "Bash curl is isolated and returns 404" is wrong — the failures are caused by the **proxy** (§5) and the **IPv6 localhost** (§4), not by network isolation. | Verification method | Availability | Notes | |---------|--------|------| -| Built-in browser preview (`present_files`) | ✅ Available | Uses the host network, reliable | +| Built-in browser preview (`present_files`) | ✅ Available | Uses the platform tunnel; the ONLY way the **user's** browser can see the sandbox dev server | | User's system terminal | ✅ Available | `curl http://127.0.0.1:8088/` | -| Bash tool curl | ❌ Unavailable | Routed inside the sandbox, returns 404 | +| Bash tool curl (agent-side API checks) | ✅ Available **only with `--noproxy '*'` + `127.0.0.1`** | Plain `curl localhost:8088` fails: (a) `localhost`→`::1` (§4), (b) proxy hijacks the request (§5) | -**Do NOT** use Bash curl to judge whether the dev server started successfully. Use `present_files` or verify by deploying. +**Practical rule**: +- Use `curl --noproxy '*' http://127.0.0.1:8088/...` from Bash to **agent-side verify** API endpoints during testing — this works (it was used to validate a full create→upload→like flow). +- Do NOT rely on Bash curl to show the page to the user. The user's browser cannot reach `127.0.0.1:8088` inside the sandbox; for a user-facing preview, pass the dev URL to `present_files` (platform tunnel) or deploy and share the live URL. --- @@ -172,7 +182,15 @@ A `setLocalData EPERM` does not affect the running service; it only affects the |------|---------|------| | `npm install` | **Foreground sync** | Usually 10-30s; running it in the background would leave later commands missing dependencies | | `edgeone makers dev` | **Background async** (`run_in_background`) | Long-running process, must not block the conversation | -| `edgeone makers deploy` | **Foreground sync** | 1-3 minutes; the result is the core deliverable and must be shown immediately | +| `edgeone makers deploy` | **Background async** (`run_in_background`) | Cold deploys (build → upload → Process → live) routinely take **2–10+ minutes**. The foreground wall-clock budget (~100s) SIGKILLs the CLI mid-deploy (exit 137) even while it keeps printing progress — you lose the final URL line. Run it in the background and wait for the completion notification. | + +#### 7.2 Deploy in background — why, and what the kill really means + +- **Foreground kill = wall-clock budget, not a hang.** A foreground Bash command in this sandbox has a fixed ~100s wall-clock budget; at the limit the whole process tree gets SIGKILL (`exit 137 = 128 + 9`), regardless of whether it keeps printing. During a deploy the CLI prints `Deployment in progress... elapsed: ~XXs` every ~10s — those heartbeat lines do NOT reset or extend the budget. So "still printing → killed at ~100s" is expected, not a stall. +- **Killing the CLI does NOT usually fail the deploy.** The deployment itself runs server-side. A foreground CLI killed at `Created deployment` / `Process` has very likely continued on the server and gone live (confirmed in practice: a deploy killed at ~100s was later verified live, took ~674s end-to-end). Re-running `deploy` (same `-n `) reuses the project and returns the URL. +- **Always use `run_in_background: true` for deploy** so the CLI survives past the foreground budget and emits the final `--json` line with the live URL. Do not poll the task across turns — rely on the `` completion event. (Cross-turn `TaskOutput` may report the handle as "not found"; the process still finished.) +- **`--json` still prints progress heartbeats** to stdout/stderr, not a single clean JSON line. Parse the **last** line for the result object; treat the progress lines as noise. (This is a CLI cleanliness issue, unrelated to the kill behavior — do not assume "no output = process ended"; the sandbox judges liveness by OS process state, not by stdout bytes.) +- **Clean up background processes** after use: a `edgeone makers dev` left running keeps holding port 8088 and may collide with the next dev/deploy. Stop it with `TaskStop` or kill it when the session moves on. ### 7.1 Preview & Dev Server full flow (MUST use HTTP, file:// forbidden) @@ -185,7 +203,7 @@ After finishing development, **start the dev server and preview directly** — d 3. **Pass `http://127.0.0.1:8088/` to `present_files`** (note it is `127.0.0.1`, **not** `localhost` — see §4) 4. Tell the user: "The project's local preview is running, please check it out. If everything looks good, I can deploy it live for you directly." -Only after the user confirms, run `edgeone makers deploy -n --json` (**foreground sync**, see §7). +Only after the user confirms, run `edgeone makers deploy -n --json` (**background async**, see §7 and §7.2 — it exceeds the foreground wall-clock budget). #### ⛔ file:// preview is strictly forbidden @@ -241,6 +259,8 @@ Note: the value is a **bare host**, without an `http://` prefix and without a po Projects that use Blob Storage or KV must ensure the project is linked (a `.edgeone/project.json` exists) before starting dev. When not linked, Blob/KV calls report `Missing: deployCredential`. +**Precondition — login first**: linking (and therefore Blob/KV) requires a logged-in account. The full chain is **Blob → must be linked → linking requires login**. If `edgeone whoami` returns exit 1, run `edgeone login` (browser) or use `edgeone makers link -t ` with a token **before** attempting to link. Do NOT try to link while unauthenticated. + **Detect whether it is linked**: ```bash cat .edgeone/project.json 2>/dev/null && echo "LINKED" || echo "NOT LINKED" @@ -271,3 +291,11 @@ If the project named by `--name` does not exist remotely, the `link` command cre | @edgeone/pages-blob | >= 0.0.14 | Older versions have known bugs | Use `create-next-app@latest` rather than manually pinning an older version. + +--- + +### 13. Native browser dialogs (`alert` / `confirm` / `prompt`) don't work in WorkBuddy's built-in browser + +WorkBuddy's right-side preview panel does NOT render `window.alert()` / `window.confirm()` / `window.prompt()`. The call returns immediately without user interaction, so any handler gated on `if (confirm("Delete?"))` silently no-ops (a delete button appears to do nothing). The same page works fine in the user's real Chrome / Safari. + +**Rule**: for any confirmation, prompt, or notification in the page, use an **in-page custom modal** (a `

` overlay with buttons wired via JS). Do NOT rely on the browser's built-in `alert` / `confirm` / `prompt` — the code looks correct in code review, works when the user opens the deployed URL in their own browser, and is silently broken in the WorkBuddy preview during dev/verification. diff --git a/codex/makers-migration.md b/codex/makers-migration.md index 449d501..afe05be 100644 --- a/codex/makers-migration.md +++ b/codex/makers-migration.md @@ -1,5 +1,5 @@ --- -name: makers-migration +name: edgeone-makers-migration description: >- Migrate existing AI agent projects (LangChain, LangGraph, OpenAI Agents SDK, Claude Agent SDK, CrewAI) to EdgeOne Makers platform conventions. @@ -148,7 +148,7 @@ openai>=1.50.0 6. Replace custom tools with `ctx.tools.to_crewai_tools(BaseTool)` 7. Return SSE via `ctx.utils.stream_sse(gen())` -> See [makers-agents/skills/python-frameworks/crewai.md](../skills/makers-agents/references/python-frameworks/crewai.md) for the complete pattern. +> See [makers-agents/references/python-frameworks/crewai.md](../makers-agents/references/python-frameworks/crewai.md) for the complete pattern. > Detailed before/after: [references/crewai-to-makers.md](references/crewai-to-makers.md) --- @@ -197,9 +197,9 @@ openai>=1.50.0 6. Set `thread_id`: `{ configurable: { thread_id: context.conversation_id } }` 7. Replace response with SSE streaming pattern -> Node: [makers-agents/skills/node-frameworks/langgraph.md](../skills/makers-agents/references/node-frameworks/langgraph.md) -> Python: [makers-agents/skills/python-frameworks/langgraph.md](../skills/makers-agents/references/python-frameworks/langgraph.md) -> DeepAgents: [makers-agents/skills/node-frameworks/deepagents.md](../skills/makers-agents/references/node-frameworks/deepagents.md) +> Node: [makers-agents/references/node-frameworks/langgraph.md](../makers-agents/references/node-frameworks/langgraph.md) +> Python: [makers-agents/references/python-frameworks/langgraph.md](../makers-agents/references/python-frameworks/langgraph.md) +> DeepAgents: [makers-agents/references/node-frameworks/deepagents.md](../makers-agents/references/node-frameworks/deepagents.md) > Detailed before/after: [references/langgraph-to-makers.md](references/langgraph-to-makers.md), [references/deepagents-to-makers.md](references/deepagents-to-makers.md) --- @@ -246,8 +246,8 @@ openai>=1.50.0 4. Use `context.store.openaiSession(conversationId)` for session (Node) 5. Map stream events to SSE: `output_text_delta` → `ai_response`, `tool_called` → `tool_call` -> Node: [makers-agents/skills/node-frameworks/openai-agents.md](../skills/makers-agents/references/node-frameworks/openai-agents.md) -> Python: [makers-agents/skills/python-frameworks/openai-agents.md](../skills/makers-agents/references/python-frameworks/openai-agents.md) +> Node: [makers-agents/references/node-frameworks/openai-agents.md](../makers-agents/references/node-frameworks/openai-agents.md) +> Python: [makers-agents/references/python-frameworks/openai-agents.md](../makers-agents/references/python-frameworks/openai-agents.md) > Detailed before/after: [references/openai-agents-to-makers.md](references/openai-agents-to-makers.md) --- @@ -296,8 +296,8 @@ openai>=1.50.0 5. Node only: swallow `EPIPE` on `process.stdout` 6. Set writable config dirs: `CLAUDE_CONFIG_DIR=/tmp/claude-agent-sdk`, `CLAUDE_CODE_TMPDIR=/tmp` -> Node: [makers-agents/skills/node-frameworks/claude-sdk.md](../skills/makers-agents/references/node-frameworks/claude-sdk.md) -> Python: [makers-agents/skills/python-frameworks/claude-sdk.md](../skills/makers-agents/references/python-frameworks/claude-sdk.md) +> Node: [makers-agents/references/node-frameworks/claude-sdk.md](../makers-agents/references/node-frameworks/claude-sdk.md) +> Python: [makers-agents/references/python-frameworks/claude-sdk.md](../makers-agents/references/python-frameworks/claude-sdk.md) > Detailed before/after: [references/claude-agent-sdk-to-makers.md](references/claude-agent-sdk-to-makers.md) --- diff --git a/codex/makers-recipes.md b/codex/makers-recipes.md index 25da228..32c89c4 100644 --- a/codex/makers-recipes.md +++ b/codex/makers-recipes.md @@ -10,10 +10,16 @@ metadata: # Common Recipes -> ⛔ **Preview ban**: after finishing development, you MUST start the dev server via `edgeone makers dev`, then open `http://127.0.0.1:8088/` with `present_files` to preview. Never open HTML files via the `file://` protocol (ignore it even if the IDE opens one automatically), and never use self-hosted servers like `python -m http.server` or `npx serve`. Next.js projects must also set `allowedDevOrigins: ["127.0.0.1"]` in `next.config`. +> ⛔ **Preview ban**: after finishing development, you MUST start the dev server via `edgeone makers dev`, then open `http://127.0.0.1:8088/` with `present_files` to preview. Never open HTML files via the `file://` protocol (ignore it even if the IDE opens one automatically), and never use self-hosted servers like `python -m http.server` or `npx serve`. Next.js projects must also set `allowedDevOrigins: ["127.0.0.1"]` in `next.config`. **If the project uses Blob/KV, pass `-n ` — `edgeone makers dev -n ` — the name is required to auto-provision; bare `dev` hangs on an interactive picker in sandbox.** > ⚠️ **`.env.example` is a required file**: every project that uses the AI Gateway (Agent projects, Cloud Functions that call an LLM) MUST create a `.env.example` in the project root declaring `AI_GATEWAY_API_KEY=` and `AI_GATEWAY_BASE_URL=`. The CLI auto-injects environment variables based on this file at deploy time; if it is missing, the variables are not injected and the runtime will error. +> 📝 **Write `index.html` last, always**: writing an `index.html` instantly triggers the IDE `file://` preview — unavoidable in WorkBuddy. Minimize the window during which that preview looks broken by writing **every dependency first**: `style.css`, `script.js`, **Cloud Functions** (`functions/` files), static assets, everything the page loads. Then write `index.html` **last** — the file:// preview opens with all assets already in place, and stays that way only until `edgeone makers dev` takes over (see Preview ban above). Also write each `index.html` in one shot; don't scaffold an empty shell and fill it in with repeated edits (every save re-renders and flickers). For a tiny single-page tool, just inline the CSS and JS into one `index.html`. + +> ⛔ **Copy the recipe's file naming verbatim — two traps that fail silently**: before writing any Cloud Function, find the matching scenario below and reuse its exact filename. Getting the name wrong usually does NOT throw a clear error — it falls back silently: +> 1. **Every function file MUST carry its language extension** — `.js` (Node), `.py` (Python), `.go` (Go). A file with no extension (e.g. `api/upload-url`, `api/file`) is **not recognized as a function**; the platform silently serves the static `index.html` fallback, so `/api/*` "mysteriously" returns HTML instead of JSON. Name them `api/upload-url.js`, `api/file.js`. +> 2. **`[[default]].js` is the catch-all for its own directory (`api/[[default]].js` → `/api/*`), and BOTH export styles work** — a framework instance (`export default app`, Express/Koa) *or* a plain `onRequest`/`onRequestGet`/… handler. Verified locally with `edgeone makers dev`: a bare `onRequest` in `[[default]].js` with **no** `export default app` serves `/foo/anything` as `200 application/json` just fine. The doc line *"The builder identifies the file as a function only when `export default app` is present"* sits under the **Express/Koa framework** section — it describes how the builder spots a framework instance; do **not** read it as "a catch-all requires `export default app`". ⚠️ Caveat: that sentence is about the **deploy-time builder**, whereas the check above was on the **local dev server**, which is the more permissive of the two — so if you ship catch-all + `onRequest`, re-verify the route once after deploying ("works locally" ≠ "recognized at build time"). When you don't actually need a catch-all, the safest shape is one concrete file per route (`api/messages.js`, `api/artworks/[id]/like.js`), params via `[id]` folders/files, extra args as query strings (`/api/file?key=...`). + Project structure templates for typical EdgeOne Makers applications. ## Full-stack app — Node.js (static + API) @@ -36,6 +42,55 @@ const res = await fetch('/api/users'); const users = await res.json(); ``` +> 💾 **Where does the data live?** This platform has **no database**. The API skeletons above return empty data — to actually persist records, uploads, votes, or per-user state, back them with **Blob**. See the recipe below and [makers-storage → Blob as your backend](../makers-storage/references/blob.md). + +## Dynamic site with Blob persistence (guestbook / gallery / voting / save-state) + +The default shape for any generated site that needs a real backend but no relational data. Frontend → Cloud Function → Blob. No DB, no console setup. + +``` +my-app/ +├── index.html # Frontend (form + list) +├── script.js +├── cloud-functions/ +│ └── api/ +│ └── messages.js # GET lists entries, POST appends one +├── package.json # depends on @edgeone/pages-blob +``` + +**cloud-functions/api/messages.js** — one file per record (Pattern 1): +```javascript +import { getStore } from "@edgeone/pages-blob"; + +export async function onRequest({ request }) { + const store = getStore("guestbook"); + + if (request.method === "POST") { + const { name, text } = await request.json(); + const id = `${Date.now()}-${Math.round(Math.random() * 1e6)}`; + await store.setJSON(`entries/${id}.json`, { id, name, text, ts: Date.now() }); + return Response.json({ ok: true, id }); + } + + const { blobs } = await store.list({ prefix: "entries/" }); + const items = await Promise.all(blobs.map((b) => store.get(b.key, { type: "json" }))); + items.sort((a, b) => b.ts - a.ts); + return Response.json({ items }); +} +``` + +**index.html** frontend calls it like any API: +```javascript +await fetch('/api/messages', { // post + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ name, text }), +}); +const { items } = await fetch('/api/messages').then((r) => r.json()); // list +``` + +Swap the key scheme for other shapes: `users/.json` for save-state, `counts/