Skip to content

BOOTSTRAP — set up this folder, then build a tile ​

This runbook works with Codex and Claude Code, either from the downloaded starter folder or from a prompt that links to https://poe-tiles-docs.pages.dev/starter/BOOTSTRAP.md. Follow the creator's request; the workspace is not permission to publish an unfinished app. Read linked skill files explicitly when your agent does not automatically include them.

0. Pick the working folder ​

If this folder holds BOOTSTRAP.md, it is the starter; work here. Otherwise you arrived from a pasted prompt. Work in the current folder if it is empty or holds only this creator's tiles; if it contains an unrelated project, ask the creator where to create the tile before writing files. The scaffold in step 2 creates the app's own instructions and skills, so no starter files are needed.

1. Check Node and Bun, then install the CLI ​

bash
command -v bun
bun --version
command -v node
node --version

Use Node.js 22.22 or newer. If Node is missing or older, ask the creator to install it from the Node.js download page, then restart the agent.

Any Bun 1.x works; Bun 1.4.2 is the tested baseline. Keep an installed 1.x even if poe-tiles doctor later warns that it is untested, and suggest Bun 1.4.2 only if an install, build, or preview fails. If Bun is missing or not 1.x, offer to install the tested version with curl -fsSL https://bun.com/install | bash -s "bun-v1.4.2" and run it only after the creator approves. The starter folder's Claude Code permissions deny direct curl and bash; there, ask the creator to run that command in their terminal instead. After installing, use ~/.bun/bin/bun until the agent is restarted.

If a GUI shell cannot find Bun, use ~/.bun/bin/bun and ~/.bun/bin/poe-tiles; do not silently edit shell profiles. If you repair PATH, pass the verified Bun and Node directories in each command's environment. An earlier tool call's exports may not persist, and using Bun by absolute path alone does not make Node available to its child processes.

bash
bun remove -g @ai-app/poe-tiles-cli 2>/dev/null; bun install -g https://misc-dev-uploads.quora-913.workers.dev/ea0af63557ba70a14f0c2bb714a8895f9f6dd59255855b62a4ad3e77b284523b
command -v poe-tiles
poe-tiles auth whoami

Check that command -v poe-tiles printed the copy you just installed: a path under $BUN_INSTALL/bin, or ~/.bun/bin when BUN_INSTALL is unset. If it printed anything else, an older poe-tiles launcher comes first on PATH. Call the installed copy by its absolute path, for example ~/.bun/bin/poe-tiles, in every later command, and tell the creator about the older launcher instead of deleting it.

If not signed in, run poe-tiles login. The creator approves it in their browser; website login alone does not authenticate the CLI. Never request an API key in chat. For a remote terminal use poe-tiles login --remote.

login keeps running until the creator approves, so start it as a background command or in a separate terminal; a foreground tool call shows no output until it exits. Read its output as soon as it prints the approval URL and the Enter code: line, then post both to the creator in chat: the URL as a clickable Markdown link, and the code as text. Do this even when the CLI says it is opening the browser, because a browser launched from the agent's shell may not appear. Then wait for Logged in successfully. before uploading. Local setup, building, and previewing can continue while approval is pending. Before uploading, confirm the session with poe-tiles auth whoami; report a blocked login instead of attempting to bypass it.

2. Scaffold and install ​

Choose a lowercase hyphenated name from the idea and append a short random suffix, such as word-duel-k4x7. The name becomes the tile's handle, which is unique per creator; a bare name like word-duel can collide with, and overwrite, an earlier tile built from a similar idea. Players see the display name instead. Use React unless the creator requests another framework. Replace word-duel-k4x7 below with your name.

bash
poe-tiles tiles init word-duel-k4x7 --template react
cd word-duel-k4x7
bun install
poe-tiles doctor

Start these commands in the working folder from step 0. After cd word-duel-k4x7, run later commands in that app directory. Set the working directory for every tool call; do not assume an earlier cd persists. Explicitly read its AGENTS.md (Codex) or CLAUDE.md (Claude Code) before app work. In Codex desktop, ask the creator to make the app directory the project's primary folder for their next chat. It contains SDK skills for both agents. Load tile-creator and, for shared state, synced-store. If using an older CLI, run poe-tiles skills install --dir .agents/skills there and read the generated CLAUDE.md explicitly in Codex. If discovery fails, read .agents/skills/tile-creator/SKILL.md and .agents/skills/synced-store/SKILL.md directly (or the .claude/skills copies in Claude Code). Use the CLI's generated instructions and skill installer; no separate Codex adapter or TypeScript dependency rewrite is needed.

3. Build, preview, and verify ​

Implement the idea and use the generated test harnesses for behavior tests. The dev preview is required, not optional: tests and a built dist do not show what the creator will see. Start the dev server in a background tool session or a separate terminal:

bash
bun run dev

Wait for its URL: line and open that URL. Keep the process running while previewing. Wait for a successful build, then edit the app and confirm the browser shows the change. If the build fails or the browser disconnects, report that state instead of treating the previous preview as the new code. Give the creator the URL: link so they can try it too. If you cannot start or open the preview, say so in your report; do not skip it silently. Stop the dev server when done.

bash
bun run verify

For multiplayer, run a two-client browser test and perform a shared-state change. Then assert the authoritative server state with the test server's server.debugSnapshot({ storeTypeId, instanceId }). It returns seats, one per current member, and each seat's tables hold exactly the public and private rows that member's client can read. Check the shared rows, and check that private data such as a hand of cards appears only in its owner's seat:

ts
const snapshot = await server.debugSnapshot({ storeTypeId, instanceId });
const seat = (userId: string) => snapshot.seats.find((s) => s.userId === userId)!;
expect(JSON.stringify(seat("bob").tables)).not.toContain("alice-card");

Matching text in both browsers is not enough, because each client can show its own optimistic state. Finally, close and reopen a client and check that the saved change remains. Adapt tests to the creator's app. Do not count skipped tests or a screenshot as proof of multiplayer or persistence. Installing these skills does not provide managed Creator tools such as generate_image or music generation. Use available local tools or supplied assets, and report any tool-dependent work that remains blocked.

4. Explain publication, then publish when requested ​

Keep temporary verification output, logs, caches, and browser downloads out of the source bundle. The CLI applies built-in exclusions and the app's .gitignore; add any project-specific scratch paths before uploading.

The source default is public, consistently with the CLI scaffold. Explain that signed-in users can download and remix it. If the creator wants owner-only source, set sourceBundle.visibility to "owner_only" before uploading. Browser-delivered HTML, JavaScript, and CSS remain readable by players either way. Removing sourceBundle does not retract an earlier source upload.

Uploading normally makes the new version live because Auto-Advance Live is on by default. For an existing tile, inspect its channels first; disable auto-advance before a test-only upload. Discovery is separate: a new tile is unlisted, and uploads preserve its discovery setting. Unlisted means accessible by link, not private. Listing publicly is a separate explicit choice.

bash
bun run build
poe-tiles tiles publish

publish is the compatible alias for tiles upload. Inspect the receipt for the uploaded version, live status, discovery, and source visibility. Open the resulting link and test the published app. Return the link and the checks actually performed; do not say publishing was tested if it was not.