CommunityCoding & Developmentgithub.com

diifan/app-website

Build or migrate an app marketing website from a supplied prototype using Bun, following the AceCut static website convention, and prepare or complete Vercel hosting and an app subdomain. Use for app official websites; not native app development.

What is app-website?

app-website is a Claude Code agent skill that build or migrate an app marketing website from a supplied prototype using Bun, following the AceCut static website convention, and prepare or complete Vercel hosting and an app subdomain. Use for app official websites; not native app development.

Works with~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/diifan/golfcut-website/tree/main/skills/app-website

Installed? Explore more Coding & Development skills: steipete/bluebubbles, steipete/eightctl, steipete/blucli · View all 6 →

Ask in your favorite AI

Open a new chat with this agent skill pre-loaded.

Documentation

App website

Deliver the user's supplied design as a standalone static site, with reproducible Bun development/build commands and explicit deployment status. Preserve the requested hosting provider. This workflow comes from AceCut (/data/swi-algo/Swi-App-Factory/Acecut/website) and GolfCut; those projects are examples, not required dependencies.

Establish inputs

Read applicable AGENTS.md and inspect the prototype, existing website and deployment documentation. Identify the app name, destination directory, canonical domain, real App Store URL and requested visual changes. Reuse existing branding and content. Check filesystem write access and hosting/DNS authentication early; continue local preparation if deployment access is unavailable. Do not treat unavailable authentication as deployment success.

Prepare a Bun project

For a new static website, initialize an empty directory:

python3 <skill-directory>/scripts/init_site.py <app-directory>/website --slug <app-slug>
cd <app-directory>/website
bun install

The bundled starter contains the verified build/preview scripts and Vercel configuration. Keep an existing project's tooling when appropriate. public/ contains source; scripts/build.mjs copies it to dist/; production requires no Bun server. No dependency is needed for plain HTML/CSS/JS. If Bun is absent from PATH, check ~/.bun/bin/bun before installing anything. Do not copy .git, .vercel, credentials or identity from another app.

Transfer the prototype

Prefer an authorized source export or repository. If only a public static prototype is available, retrieve HTML and recursively inspect same-origin HTML src/href and CSS url() dependencies, including feature pages, icons, SVGs and scripts. Fetch with curl if the host rejects the Python HTTP client. Fail visibly on missing resources; do not save error bodies as images. Map directory routes to public/<route>/index.html.

Keep assets local. Remove hosting-injected Cloudflare challenge scripts and preview-only metadata from fetched HTML, preserving application JS. Do not copy service credentials or add analytics without a requirement. Review external dependencies such as Google Fonts. Preserve the prototype's app links; never invent an App Store ID or silently substitute another app's legal terms.

Replace prototype origins in canonical URLs, Open Graph, JSON-LD, robots and sitemap with the intended production origin. Preserve page paths consistently. For button color requests, inspect the rendered asset as well as CSS: a filled SVG can conceal a CSS background. Change only the intended SVG background paths and preserve logo/text paths, accessible names and link targets.

Company footer and legal pages

For SWINK app websites that should align with AceCut, use © <year> SWINK AI INC., a visible mailto:[email protected] contact link, and working /terms and /privacy links on every page, including feature pages and the legal pages themselves. Keep the current app's brand and visual style. Use root-relative assets and navigation so nested routes work; make legal links reachable without JavaScript. Let footer links wrap on tablets and use a compact mobile layout without horizontal overflow.

When the user requests alignment, use the referenced app's Terms/Privacy structure and confirmed company/contact details, then adapt app names, actual features, dates, canonical URLs and cross-links. Do not blindly transfer another app's analytics provider, upload behavior, storage/retention promises or settings. Inspect available product evidence for such claims; omit unconfirmed specifics rather than invent them. Keep Terms and Privacy as readable standalone pages, add both to sitemap, and verify clean URLs in local tooling and Vercel.

For footer/legal changes, check all affected pages at desktop, tablet and narrow mobile widths; verify company text, mailto target, both legal links, readable text, no overflow, and mobile navigation. Preserve requested download-button colors. After pushing, verify the new production deployment and fetch the real /terms and /privacy over HTTPS before reporting them live.

Build and verify

bun run build
bun run preview

The local server supports directory index routes and .html clean URLs, GET and HEAD, and returns 404 for missing files. Validate every page and local asset over HTTP; confirm sitemap and canonical URLs. Check desktop and narrow mobile widths (for example 1440, 768, 390 and 320), overflow, loaded images, browser errors, menus, tabs/keyboard controls, FAQ, filters and download targets as applicable. Capture review screenshots outside public/. When color is represented by an SVG, inspect its paths or screenshot pixels as well as computed CSS.

GitHub publication and machine access

On the SWI machine, AceCut was pushed using the existing GitHub CLI login under Linux user ubuntu (GitHub identity CC-AIMI). Confirm the current identity and repository write permission with gh repo view <owner>/<repo> --json viewerPermission,defaultBranchRef,isEmpty before relying on this precedent. A network/proxy error is not proof of an invalid login. If Git asks for a username despite a working gh login, use a per-command credential helper in that same authenticated Linux account: git -c credential.helper='!gh auth git-credential' push origin <branch>. This reuses the existing login without exposing its token or changing global Git configuration. Do not copy credentials between accounts or put passwords/tokens in this skill, shell arguments, source files or logs.

When a user authorizes an administrator account to resolve a Unix permission issue, inspect id and getfacl, and grant only the needed project access (for example setfacl -m u:<executor>:rwx,d:u:<executor>:rwx <project>). Preserve owner/group and unrelated permissions. An administrator login does not authenticate Vercel or GoDaddy.

If an explicitly requested repository already exists, clone it first and preserve its history; do not force-push an unrelated initial commit. Place the website files at repository root, not in another website/ layer. Exclude .git, .vercel, dist, node_modules, validation screenshots and secrets when transferring prepared source. If publishing through another authorized Linux account, use a temporary checkout owned by that account and grant only required read access to source. Configure the repository's intended author locally, inspect staged files, commit, push to the intended branch, and verify the remote SHA. Keep the main working checkout synchronized afterward.

For a standalone repo such as diifan/golfcut-website, Vercel must import that repo with Root Directory ./. A GitHub push alone does not create a Vercel project.

Vercel and DNS

The starter uses framework null (dashboard: Other), bun install, bun run build, output dist, cleanUrls: true, trailingSlash: false. In a standalone website repository, set Vercel Root Directory to ./; in an app monorepo, use website/. GitHub integration is optional if an authenticated Vercel CLI/API can deploy directly. Follow the user's authorized publication scope without adding another approval gate.

Inspect the authenticated account/team and existing project before creating or linking. If CLI login is needed, run bun x vercel login and send the current device authorization URL to the user; keep the process alive while completing independent work. bun x works even when the bunx shim is missing. Never claim login until the CLI confirms it. After login, inspect available teams and AceCut's project, select the same intended scope, create/link the new app project, connect its exact GitHub repository, then deploy. Prefer a connected Vercel plugin if it supplies these capabilities. Do not reuse expired device codes or assume a suggested plugin is connected. Never reuse another app's project ID. Deploy the built website and verify its returned deployment URL. For a requested app.goswie.com, add that exact domain to its Vercel project, then obtain the project's current DNS recommendation. On the authoritative DNS provider (AceCut documents GoDaddy), create/update only the requested app record, usually CNAME host app. Use the target returned by Vercel, not a guessed or copied AceCut target. Preserve unrelated records, especially @, www, MX and nameservers. Resolve an ownership/conflict before replacing an existing unrelated record. Add only a requested verification TXT record when Vercel requires it.

Verify public DNS, Vercel domain status, HTTPS and the deployed pages. If credentials are missing, finish the build and document the exact remaining account action; distinguish prepared configuration, completed deployment and verified domain. Never label a planned domain as live.

Current official references (consult when doing deployment work):

Verified CLI sequence

GolfCut was deployed with Vercel CLI 65.4.0. After an authenticated login, use current --help if flags differ. Substitute the verified scope, project and repo; the actual SWI scope used for AceCut and GolfCut is diifans-projects.

bun x vercel teams list
bun x vercel project list --scope <scope>
bun x vercel project create <project> --scope <scope>
bun x vercel link --yes --project <project> --scope <scope>
bun x vercel git connect --yes --scope <scope>
bun x vercel project update <project> --framework other --build-command 'bun run build' --install-command 'bun install' --output-directory dist --yes --scope <scope>
bun x vercel --prod --yes --scope <scope>
bun x vercel domains add <app-domain> <project> --scope <scope>
bun x vercel domains verify <app-domain> --scope <scope>

Run these from the website checkout with the correct Git remote. Skip creation when the matching project exists. git connect --yes uses that remote; without --yes, agent-mode CLI can exit at a confirmation prompt without actually connecting. link may create .env.local with an OIDC token and .vercel/; keep both ignored. Never print or commit them.

Send a newly generated device-login URL immediately, retain the login process, and wait for its explicit success. If a user reports an invalid/expired code, stop the old login, issue a fresh one and keep the turn active for authorization; do not keep returning the stale URL.

A READY deployment and a custom-domain alias do not prove public DNS works. Test the public <project>.vercel.app URL without authentication as well as the requested domain. domains verify returns the exact recommended CNAME; record that value for the user if they manage DNS. Keep the public preview available while DNS is pending. When Git is connected, later pushes should trigger deployment; verify the deployment status if claiming a particular new commit is live.

Handoff

Record source origin, commands, build output, validation evidence and remaining limitations in the website README. Keep generated output, local validation artifacts, environment files and provider credentials out of Git. Report the actual live URL only after successful deployment; otherwise provide the ready project and precise blocker.

Related Skills