@craftware/crafty-cli

中文文档
0.7.0发布于 2026/11/01MITES Module

Crafty CLI — crea proyectos desde los starters (crafty create) y despliega tu frontend en Crafty Hosting

原始使用文档
文档目录14 节
  1. Install
  2. Start a new site
  3. Quick start
  4. Multiple tenants
  5. Commands
  6. Content types
  7. crafty.json
  8. How it resolves context
  9. Deploy from CI (GitHub Actions)
  10. Deployed URL & custom domains
  11. Agent skills
  12. Development
  13. Publishing
  14. Releasing a new version

@craftware/crafty-cli

Crafty Hosting CLI — deploy your frontend build to Crafty Hosting with a single command. The CLI talks to your Crafty CMS tenant; the underlying hosting provider is fully abstracted (you never deal with it directly).

Install

npm i -g @craftware/crafty-cli

Requires Node.js 20+.

Start a new site

npm create crafty@latest      # or: crafty create [dir]

Copies an official starter (today: Astro, "sitio de servicios"), logs you into your tenant in the browser (scopes deploy crafty:read crafty:write crafty:publish), creates the site with the starter's block types, collections, form and demo content (published; --draft keeps it as drafts), and writes .env, crafty.json and src/crafty.types.ts. Then npm install && npm run dev. Starters live in sdk/starters; npm run templates copies them into templates/ (done automatically by npm pack / npm publish).

Quick start

From your frontend project (the one that already consumes the Crafty API):

crafty login     # opens a browser to approve the CLI (OAuth device flow)
crafty init      # writes crafty.json (site + environment + build dir)
npm run build    # produce ./dist (framework-specific)
crafty deploy    # zips the build, uploads it, prints the live URL

The CLI reads CRAFTY_API_URL from your project's .env to know which tenant to talk to, so there is nothing else to configure. Hosting must be enabled for your tenant, site and environment (in the Crafty panel) before a deploy is allowed.

Multiple tenants

The CLI keeps one session per tenant host, so you stay logged into all of your tenants at once. Each project's CRAFTY_API_URL selects which stored session is used — switching directories never forces a re-login. Log into a tenant without entering its project with crafty login --host=<url>.

Commands

CommandDescription
crafty create [dir] [--url=<url> --template=<id> --name=<name> --site=<slug> --draft --yes]Create a project from a starter and its site in Crafty (same as npm create crafty). See Start a new site.
crafty login [--host=<url>]Authenticate via the OAuth 2.0 Device Authorization Grant. Without --host, the tenant comes from CRAFTY_API_URL. The token (scope deploy) is stored per host in ~/.crafty/credentials (mode 600).
crafty init [--site=<slug> --environment=<env> --build-dir=<dir>]Create crafty.json in the project.
crafty deploy [dir] [--force]Package and deploy a build directory (default: the buildDir from crafty.json, i.e. dist). The project root, your home directory and directories outside the project are refused unless --force is passed.
crafty statusShow the status of the project's last deployment.
crafty types [--api-key=<key> --url=<url> --out=<file>]Generate TypeScript types for the collections and block types of an environment (default output: crafty.types.ts). See Content types.
crafty skills list / crafty skills install [name…] [--global | --dir=<path>]List or install the Crafty agent skills (.claude/skills by default).
crafty logoutRevoke and remove the session for the current project's tenant.
crafty update (crafty --update / -u)Self-update the globally installed CLI to the latest version on npm.
crafty --version / crafty helpPrint version / usage.

Content types

crafty types writes TypeScript types for the content models (collections and block types) of one environment, so your code — and your coding agent — stops guessing field shapes:

crafty types                                  # uses CRAFTY_API_URL + CRAFTY_API_KEY from .env
crafty types --api-key=$STAGING_KEY --out=src/crafty.types.ts
  • The environment comes from the API key: types generated with the staging key describe staging. Regenerate after changing a collection or block type.
  • It uses the public environment API key (X-API-Key), not the crafty login session. --url / CRAFTY_API_URL selects the tenant; https is required except on localhost.
  • Output: <Slug>Entry per collection (entry metadata + fields, as returned by /collections/{slug}/entries), <Slug>BlockData and <Slug>Block per block type, the CraftyPageBlock union (discriminated by type), the CraftyCollectionTypes / CraftyBlockDataTypes slug maps, and the shared CraftyEntryReference / CraftyMediaSummary.
  • Field mapping: string/text/longText/url/datetime → string, number/decimal → number, boolean → boolean, select → union of its option values (an array of them with multiple), stringList → string[], repeater → array of item objects, media references → ids plus a <key>_media file summary, collection references → CraftyEntryReference on entries and the referenced entry type on blocks, json → unknown. Optional fields are | null.
import type { BlogEntry, CraftyPageBlock } from "./crafty.types";

const { data } = await crafty.entries.list("blog");
const posts = data as unknown as BlogEntry[];

const page = await crafty.pages.get("home");
for (const block of page.blocks as unknown as CraftyPageBlock[]) {
  if (block.type === "hero") {
    block.data.heading; // typed as HeroBlockData
  }
}

(Generic SDK methods such as crafty.entries.list<"blog">() are planned; until then, cast the SDK responses to the generated types.)

The schema comes from GET /api/v1/schema (JSON Schema, versioned by format_version); the CLI refuses a format it does not know — run crafty update.

crafty.json

{
  "site": "acme",
  "environment": "production",
  "buildDir": "dist"
}

Set buildDir to your framework's output: Vite/CRA/Astro dist, Next.js static export out, Nuxt .output/public, SvelteKit (static adapter) build.

How it resolves context

  1. CRAFTY_API_URL from the project .env (or the environment) → tenant base URL.
  2. crafty.json → site, environment, buildDir.
  3. CRAFTY_TOKEN from the process environment (CI) or, without it, ~/.crafty/credentials → the access token stored for that tenant host.

Deploy from CI (GitHub Actions)

In CI there is no crafty login. Create a personal access token with the deploy scope in the Crafty panel (Perfil → Tokens, as a tenant admin) and pass it as CRAFTY_TOKEN, together with CRAFTY_API_URL. CRAFTY_TOKEN is only read from the environment, never from .env.

To redeploy when content changes, add a content webhook in Site → Integraciones → Webhooks with the format GitHub Actions, the URL https://api.github.com/repos/{owner}/{repo}/dispatches and an Authorization: Bearer <token> header (a fine-grained GitHub token for that repository with Contents: read and write). Crafty then sends a repository_dispatch with event_type: crafty-content and the Crafty payload in client_payload; its test ping uses crafty-ping, which checks the token without starting a build.

# .github/workflows/crafty-deploy.yml
name: Deploy to Crafty Hosting

on:
  push:
    branches: [main]
  repository_dispatch:
    types: [crafty-content]
  workflow_dispatch:

# Publishing 20 entries in a row sends 20 events: each new run replaces the
# pending one and cancels the one in progress, so only the last one deploys.
concurrency:
  group: crafty-deploy
  cancel-in-progress: true

jobs:
  deploy:
    runs-on: ubuntu-latest
    timeout-minutes: 15
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: 22
          cache: npm
      - run: npm ci
      - run: npm run build
        env:
          CRAFTY_API_URL: ${{ vars.CRAFTY_API_URL }}
          CRAFTY_API_KEY: ${{ secrets.CRAFTY_API_KEY }}
      - run: npx --yes @craftware/crafty-cli@latest deploy
        env:
          CRAFTY_API_URL: ${{ vars.CRAFTY_API_URL }}
          CRAFTY_TOKEN: ${{ secrets.CRAFTY_TOKEN }}

github.event.client_payload carries the event (event, site, environment, data.type, data.slug, …) if the build needs to know what changed.

For safety, the token is only ever sent to the host it was issued for, https is required (except localhost), and .git, .env*, .envrc, .dev.vars, .npmrc, .netrc, .aws, .ssh, .crafty, id_rsa*-style keys, *.pem, *.key, node_modules and symlinks are excluded from the uploaded build (case-insensitive).

Deployed URL & custom domains

A successful deploy is served at a tenant-scoped subdomain {tenant}-{hash}.crafty.do, one per environment (DNS + TLS set up automatically). To use your own domain, add it in the Crafty panel under Site → Hosting; it returns a CNAME record to create at your DNS provider. Use a subdomain such as www, create only that record and leave the email records (MX, SPF, DKIM, DMARC) untouched. A root domain only connects when its DNS is on Cloudflare; never put a CNAME on the root, since it breaks the domain's email.

Agent skills

This package ships the Crafty agent skills: crafty-deploy (this CLI: when to run login/init/deploy, buildDir per framework, troubleshooting) and crafty-cms (the MCP server and the SDK). Install them where your agent reads skills:

crafty skills list
crafty skills install              # ./.claude/skills (this project)
crafty skills install --global     # ~/.claude/skills (every project)
crafty skills install --dir=<path> # another agent's skills folder
npx @craftware/crafty-cli skills install   # without installing the CLI

Running it again replaces the installed copies, so it also updates them to this CLI's version. For Claude.ai and Claude Desktop, download the zips from docs.crafty.do (/skills/crafty-cms.zip, /skills/crafty-deploy.zip) and upload them as skills.

Development

npm install
npm run build      # tsc → dist
npm test           # builds, then runs node:test
npm run typecheck

Publishing

Published as a public, scoped package under the @craftware org. publishConfig.access is already public and prepublishOnly rebuilds dist, so no extra flags are needed.

Prerequisites: an npm account that is a member of the craftware org with publish rights, and your 2FA device if enabled.

# 1. authenticate
npm login
npm whoami

# 2. from this package, install exact deps and validate
cd sdk/cli
npm ci
npm test
npm run typecheck

# 3. preview the exact tarball (no upload)
npm publish --dry-run
#    expect: dist/**, skills/**, templates/**, LICENSE, README.md, package.json
#    (never src/, tests/ or node_modules/)

# 4. publish
npm publish            # add --otp=123456 if 2FA is enabled

# 5. verify
npm view @craftware/crafty-cli
npm i -g @craftware/crafty-cli && crafty --version

Releasing a new version

cd sdk/cli
npm version patch      # or minor / major — creates a commit + git tag
git push --follow-tags
npm publish

Notes:

  • A given version can only be published once; bump the version for any change.
  • Publish from a clean tree at the intended commit.
  • The crafty bin is dist/bin/crafty.js (with a #!/usr/bin/env node shebang).
  • create-crafty (sdk/create-crafty, what npm create crafty runs) depends on this package's ./create export: publish the CLI first, then create-crafty.

版本与发布记录

@craftware/crafty-cli 共发布 14 个版本,首次发布于 2026/06/21;过去 12 个月发布了 14 个版本。

版本发布日期距今
0.7.0latest2026/11/012 天前
0.6.22026/11/012 天前
0.6.12026/10/313 天前
0.6.02026/10/313 天前
0.5.12026/10/286 天前
0.5.02026/10/2311 天前

关于 @craftware/crafty-cli 的常见问题

@craftware/crafty-cli 是什么?

巧手的CLI -创建项目指定的启动器(crafty create)被描述为前端在狡猾的托管

如何安装 @craftware/crafty-cli?

在项目目录运行 npm install @craftware/crafty-cli,或使用 pnpm add / yarn add / bun add。它还提供命令行工具 crafty,可以用 npx crafty 直接运行。

@craftware/crafty-cli 支持 TypeScript 吗?

该包的 package.json 没有声明类型入口。需要类型提示时,可以在 npm 上查找社区维护的 @types/craftware__crafty-cli 是否存在。

@craftware/crafty-cli 支持 ESM 还是 CommonJS?

以 ES Module 形式发布,推荐使用 import 引入。在 CommonJS 项目中,Node.js 20.19+ / 22.12+ 可以直接 require() 不含顶层 await 的 ES Module,更早的版本需要改用动态 import()。

@craftware/crafty-cli 需要什么版本的 Node.js?

package.json 的 engines 字段要求 Node.js >=20。版本不符时 npm 默认只给出警告,开启 engine-strict 后会拒绝安装。

@craftware/crafty-cli 可以商用吗?

@craftware/crafty-cli 使用 MIT 许可。宽松许可:允许商业使用、修改和再分发,通常只需在分发时保留原版权与许可声明。以上为概括,不构成法律意见,请以许可原文为准。

@craftware/crafty-cli 还在维护吗?

最新版本 0.7.0 发布于 2026/11/01(2 天前);至今共发布 14 个版本,其中过去 12 个月发布了 14 个;首次发布于 2026/06/21。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。