mcpField
C
caffeine-app

caffeine-app

github.com/dfinity开发39117 次安装今天更新
代码仓库

关于 caffeine-app

caffeine-app 是一项指导 Agent 从零搭建 Caffeine 全栈应用的技能,涵盖项目结构、清单文件和 CLI 构建流程。它面向使用 Motoko 后端与 React/Vite 前端的 Caffeine 项目;Motoko 语言细节则交由 `writing-motoko` 技能处理。

主要功能

  1. 01搭建 Caffeine 项目目录结构
  2. 02配置工作区与 canister 清单
  3. 03说明 Motoko 后端和前端绑定流程
  4. 04指导 caffeine CLI 构建循环
  5. 05涵盖稳定状态检查与迁移配置

适用场景

  1. 01从零创建 Caffeine 应用
  2. 02修复 `caffeine.toml` 或 `mops.toml`
  3. 03运行 `caffeine` 检查与预览构建

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/dfinity/icskills --skill caffeine-app

安装后在 Claude Code 中输入/caffeine-app确认已加载。

附带文件references/frontend-template.md

详细介绍

Caffeine App(从零开始构建)

Caffeine(caffeine.ai)在 Internet Computer 上构建并托管全栈应用:一个单独的 Motoko 后端 canister,以及一个作为 assets canister 提供服务的 React/Vite 前端。本技能将介绍准确的项目结构和 CLI 构建流程,帮助你从零构建一个可编译的 Caffeine App。

本技能负责项目结构和构建工作流,不负责 Motoko 语言。 编写或修改任何后端代码前,请获取并遵循 writing-motoko 技能:https://skills.internetcomputer.org/skills/writing-motoko/SKILL.md。该技能是有关 actor 语法、稳定状态、mo:core 和编译器错误的权威指南。本技能只展示最精简的空 actor 以及它所在的位置。

何时使用本技能

  • 从零创建或搭建新的 Caffeine App 或 caffeine.ai 项目。
  • 编写或修复 caffeine.toml(工作区或 canister 清单)或 mops.toml。
  • 运行 caffeine CLI 流程:auth login、doctor、install、check、preview。

不要将本技能用于 Motoko 语言细节(请使用 writing-motoko),也不要用于原始 IC/dfx/icp 部署(请使用 icp-cli)。Caffeine App 通过 caffeine CLI 和 caffeine.ai Web 应用构建和部署,而不是通过 dfx。

重要事实

  • 没有 caffeine init / caffeine new。“从零开始”是指你手动创建本技能中所述的文件,然后运行构建流程。(caffeine projects clone <id> 只会下载现有云项目,并不是从零搭建项目的脚手架。)
  • 后端 canister 必须且只能有一个,并且必须命名为 backend。 mops.toml 声明一个 [canisters.backend]。
  • 前端与后端的绑定文件由工具生成,绝不能手写。 src/frontend/src/backend.ts 和 src/frontend/src/declarations/ 由 caffeine-bindgen 在构建过程中生成。编辑这些文件毫无意义,因为它们会被覆盖。
  • 将应用部署到线上 URL 需要在 caffeine.ai Web 应用中进行,而不是通过 CLI。 CLI 最多会帮你生成一个已构建的草稿(caffeine preview --build,需要云端的 project.id,详见构建流程)。没有 caffeine deploy / publish 命令。

先决条件(运行一次)

# Install the CLI (public npm package). The binary is `caffeine`.
npm install -g @caffeineai/cli

# Authenticate against caffeine.ai (opens a browser; use --device on headless hosts).
caffeine auth login
caffeine auth status

# Check the environment: Node, pnpm, mops, caffeine-bindgen, that you are logged in,
# and that the Caffeine API is reachable (installs/repairs what it can).
caffeine doctor --fix

如果不希望全局安装,或者全局安装失败,请在每个 caffeine 命令前加上 npx -y @caffeineai/cli@latest 前缀运行,例如:npx -y @caffeineai/cli@latest auth status。

caffeine doctor --fix 会检查 Node.js、pnpm、mops 和 caffeine-bindgen,确认你已登录,并验证 Caffeine API 是否可访问;它会安装或修复能够处理的项目。它不会安装 Motoko 编译器(moc)或代码检查器(lintoko):mops 会在首次运行 mops install / 构建时,根据 mops.toml 中的 [toolchain] 固定版本自动获取这些工具。Caffeine 构建不需要 dfx。

项目结构

Caffeine App 是一个包含根清单和两个 canister 的 pnpm 工作区。请创建以下准确的目录树(文件内容见下文):

my-app/
├── .old/src/backend/dist/
│   └── backend.most           # stable-signature baseline — seed with an empty actor (see below)
├── caffeine.toml              # root workspace manifest — MUST contain [workspace]
├── mops.toml                  # Motoko build config — ONE per project, at the root
├── package.json               # pnpm workspace root + the `bindgen` script
├── pnpm-workspace.yaml         # declares src/**/* as workspace packages
├── tsconfig.json               # root TS config
└── src/
    ├── backend/                # the single Motoko canister, named "backend"
    │   ├── caffeine.toml        #   canister manifest: type = "motoko"
    │   ├── main.mo              #   actor entry point (write with the `writing-motoko` skill)
    │   └── migrations/          #   enhanced-migration chain (see the `mops.toml` notes)
    │       └── 00000000.mo      #   the no-op first migration
    └── frontend/               # the assets canister (React + Vite)
        ├── caffeine.toml        #   canister manifest: type = "assets"
        ├── package.json         #   frontend deps + scripts (see references/frontend-template.md)
        ├── vite.config.js       #   (see references/frontend-template.md)
        ├── tsconfig.json        #   (see references/frontend-template.md)
        ├── biome.json           #   (see references/frontend-template.md)
        ├── tailwind.config.js   #   (see references/frontend-template.md)
        ├── postcss.config.js    #   (see references/frontend-template.md)
        ├── index.html
        ├── env.json             #   runtime config — copied into dist/ on build
        └── src/
            ├── main.tsx          #   React entry (providers)
            ├── App.tsx
            ├── index.css
            ├── backend.ts        #   GENERATED by caffeine-bindgen — do NOT edit
            └── declarations/     #   GENERATED by caffeine-bindgen — do NOT edit

下文仅以内联形式展示根清单、两个 canister 清单、mops.toml、main.mo 和少量根配置文件。完整的前端样板代码(package.json、vite.config.js、Tailwind/PostCSS/Biome 配置、index.html、env.json、main.tsx、入门版 App.tsx)位于 references/frontend-template.md 中——创建前端时请阅读该文件。

清单

根目录中的 caffeine.toml — 工作区

根清单必须包含 [workspace] 部分。该部分用于标记工作区根目录;若缺少该部分,CLI 会将此文件视为普通 canister 清单,导致无法发现工作区。

manifest_version = "0.1.0"

[project]
name = "My App"
# id is assigned by the cloud after your first `caffeine preview`/create — omit it for
# a brand-new local project; the CLI fills it in.

[workspace]
include = [ "src/**" ]

# Build the backend before the frontend, because the frontend imports generated
# bindings produced from the backend's Candid interface.
[canisters.frontend]
depends_on = [ "backend" ]

[workspace].include 是一个 glob 列表,CLI 会据此扫描嵌套的 canister 清单。src/** 会找到 src/backend/caffeine.toml 和 src/frontend/caffeine.toml。

src/backend/caffeine.toml — Motoko 容器
manifest_version = "0.1.0"

[project]
name = "backend"
type = "motoko"
main = "main.mo"

[build]
commands = ["mops build", "pnpm bindgen"]
out = "dist"

[check]
commands = ["mops check"]

[check.fix]
commands = ["mops check --fix"]

[build].commands 按顺序运行:mops build 将 main.mo 编译为 Wasm + Candid,然后 pnpm bindgen(在根目录的 package.json 中定义)将 Candid 转换为前端的 TypeScript 客户端。caffeine check --fix 会运行 [check.fix].commands。

src/frontend/caffeine.toml — 资产容器
manifest_version = "0.1.0"

[project]
name = "frontend"
type = "assets"

[build]
commands = ["pnpm build"]
out = "dist"

[check]
commands = ["pnpm typecheck", "pnpm check"]

[check.fix]
commands = ["pnpm typecheck", "pnpm fix"]
mops.toml — Motoko 构建配置(每个项目在根目录下有一个)

只能有一个 [canisters.backend]。caffeine preview 只检查结构性部分,这些部分保持不变:单个 [canisters.backend]、 带有所示路径且没有 skipIfMissing 的 [canisters.backend.check-stable],以及 [build] outputDir = "src/backend/dist"。其他所有内容——工具链版本、[moc] 标志和 -E/-W/-A 诊断代码,以及依赖项列表——都是当前快照,Caffeine 模板会随时间更新;参见下文“版本和依赖项变更”。

[package]
name = "backend"
version = "0.1.0"

[build]
outputDir = "src/backend/dist"
args = ["--release"]
check-wasm = true

[canisters.backend]
main = "src/backend/main.mo"

[canisters.backend.check-stable]
path = ".old/src/backend/dist/backend.most"

[toolchain]
moc = "2.0.0"
lintoko = "0.12.0"

[lint]
extends = true

[moc]
args = [
  "--implicit-package=core",
  "-no-check-ir",
  "-E=M0254",
  "-W=M0235,M0223,M0236,M0237",
  "-A=M0241"
]

[dependencies]
core = "2.6.1"
ic = "4.2.0"
caffeineai-lints = "0.1.0"
caffeineai-oql = "0.8.0"

[canisters.backend.migrations]
chain = "src/backend/migrations"
check-limit = 1

说明:

  • 新项目使用 moc 2。 在 moc 2 中,裸 actor 是持久化的,而 persistent 关键字只会触发警告 M0217。旧指南会在 [moc] args 中添加 --default-persistent-actors 或 --generate-view-queries:这些是 moc 1.x 标志,已在 moc 2.0 中移除,传入后每次编译都会因 unknown option 而失败。从切换之前克隆的项目可能仍固定使用 moc 1.x 并保留 --default-persistent-actors;此类项目应继续使用其固定版本。

  • check-stable 指向 .old/src/backend/dist/backend.most,这是上次部署的后端稳定签名快照。caffeine check 会将你的稳定状态与之比较,而 caffeine projects clone 会从云端恢复它。不要删除 .old/。从零开始创建的项目必须用空 actor 为其初始化,就像 Caffeine 模板所做的那样,否则 caffeine check 会因以下错误而失败: Deployed file not found: .old/src/backend/dist/backend.most:

    // Version: 1.0.0
    actor {};
    

    不要改为设置 skipIfMissing = true:mops 已弃用此选项,而且 caffeine preview 会拒绝它,因为跳过检查只会在之后部署时才失败。

  • [canisters.backend.migrations] 会启用增强迁移:src/backend/migrations/ 中的每个 .mo 文件都按名称排序,作为一个步骤,将上一个稳定状态映射到下一个状态。新项目从无操作的 00000000.mo 开始,它的排序位置早于 writing-motoko 技能所创建的 YYYYMMDD_HHMMSS.mo 文件:

    module {
      public type OldActor = {};
      public type NewActor = {};
    
      public func migration(_ : OldActor) : NewActor {
        {};
      };
    };
    

    部署迁移后,绝不要编辑或删除它。

  • core 是 mo:core 标准库。请使用 mo:core,切勿使用已弃用的 mo:base——参见 writing-motoko 技能。caffeineai-oql 提供起始 main.mo 所包含的 Expose 混入(见下文)。

  • ic 提供 IC 管理容器的类型和调用(mo:ic/Types、 mo:ic/Call)。请用它替代 import ... "ic:aaaaa-aa",后者只有在存在 .did 文件的 --actor-idl 目录时才能解析,而 Caffeine 项目已不再包含该目录。

版本和依赖项变更。 [toolchain] 版本、[moc] 中的 -E/-W/-A 代码以及前端依赖项集合由模板管理,并会随时间变化(例如,从 @dfinity/* 迁移到 @icp-sdk/*、moc/core 版本升级)。请将此处的具体值视为快照——如需获取当前值,请使用 caffeine projects clone 克隆一个近期项目,并复制其 mops.toml 和 src/frontend/package.json。 不随版本变化的内容:文件布局、单个 backend 容器、带初始化基线的 check-stable、 [build] outputDir、mo:core,以及 useActor(createActor)。

package.json(根目录)— pnpm 工作区 + bindgen 脚本

bindgen 脚本负责将后端 Candid 转换为前端 TS 客户端。后端容器的 [build] 步骤会调用它(pnpm bindgen)。

{
  "name": "@caffeine/template-app",
  "type": "module",
  "engines": {
    "node": ">=18.17.0",
    "pnpm": ">=7.0.0",
    "npm": "please use pnpm"
  },
  "scripts": {
    "build": "pnpm -r --if-present run build",
    "typecheck": "pnpm -r --if-present run typecheck",
    "check": "pnpm -r --if-present run check",
    "fix": "pnpm -r --if-present run fix",
    "bindgen": "caffeine-bindgen --did-file ./src/backend/dist/backend.did --out-dir ./src/frontend/src --actor-interface-file --force"
  },
  "devDependencies": {
    "sharp": "^0.34.4"
  }
}
pnpm-workspace.yaml
packages:
  - src/**/*
onlyBuiltDependencies:
  - esbuild
tsconfig.json(根目录)
{
  "compilerOptions": {
    "strict": true,
    "target": "ES2020",
    "experimentalDecorators": true,
    "strictPropertyInitialization": false,
    "moduleResolution": "node",
    "allowJs": true,
    "outDir": "HACK_BECAUSE_OF_ALLOW_JS"
  }
}
src/backend/main.mo — 起始后端

规范模板的起始 main.mo 包含来自 caffeineai-oql 的 Expose 混入,用于发布后端的查询接口。Actor 目前没有稳定 状态,因此首次迁移会将 {} 映射为 {}。请按照 writing-motoko 技能在 Actor 内添加自己的函数。

import Expose "mo:caffeineai-oql/Expose";

actor {
  include Expose({ entities = [] });
};

在加载 writing-motoko 技能之前,不要编写更多 Motoko 代码——该技能涵盖持久化 Actor、稳定类型、mo:core,以及 Agent 否则可能凭空编造的编译器错误陷阱。

前端

获取此技能的配套参考文件 — references/frontend-template.md,它与此 SKILL.md 位于同一目录(即 …/skills/caffeine-app/references/frontend-template.md)——并根据该文件创建前端文件;其中包含经过验证的 package.json、Vite/Tailwind/Biome 配置、main.tsx,以及 useActor(createActor) 后端调用示例。要点如下:

  • 入口文件 src/frontend/src/main.tsx 使用 InternetIdentityProvider(来自 @caffeineai/core-infrastructure)和 TanStack QueryClientProvider 包装应用。
  • 前端通过生成的模块 src/frontend/src/backend.ts(以及 src/frontend/src/declarations/)与后端通信;该模块导出一个 createActor(...) 工厂,其类型根据后端的 Candid 定义生成。这些文件无需手动编写——首次构建后会自动生成。将该 createActor 传给 @caffeineai/core-infrastructure 中的 useActor(createActor),即可调用后端(同一软件包还提供 main.tsx 中使用的身份验证提供程序);你无需手动编写 Actor/配置/存储胶合代码。请参阅 references/frontend-template.md 中的示例。
  • env.json 存放运行时配置占位符(backend_host、backend_canister_id、 project_id、ii_derivation_origin、storage_gateway_url),本地值均为 "undefined";前端的 build 脚本会将其复制到 dist/(cp env.json dist/)。Caffeine 提供应用时会注入真实值。请保留 env.json 和 copy:env 步骤。

构建循环

从项目根目录运行。顺序很重要。

# 1. Install dependencies. On a brand-new project, generate the pnpm lockfile FIRST
#    (first run only — see Common Pitfalls), then install the rest (pnpm + mops).
pnpm install
caffeine install

# 2. Write your backend in src/backend/main.mo using the `writing-motoko` skill, and your
#    frontend in src/frontend/src/.

# 3. Build: compiles the backend, then `pnpm bindgen` regenerates the frontend client
#    (src/frontend/src/backend.ts + declarations/), then the frontend `pnpm build` runs.
#    Run this BEFORE check, so the frontend has the generated ./backend to typecheck
#    against. Artifacts land in src/backend/dist + src/frontend/dist (no cloud / no id).
caffeine build

# 4. Lint + typecheck + auto-fix (runs each canister's [check.fix] commands:
#    backend `mops check --fix`, frontend `pnpm typecheck` + `pnpm fix`).
caffeine check --fix

# 5. Upload a built draft (needs a cloud project id). For a brand-new app, create the
#    cloud project once to obtain an id, then preview:
caffeine projects create                 # reports a new project id
#    put that id in caffeine.toml [project] id = "...", OR pass --project-id:
caffeine preview --build --project-id <id>

设置 CAFFEINE_VERBOSE=1 可流式输出 caffeine install、caffeine build 和 caffeine check 的完整子进程输出。这相当于对每条命令传入 --verbose。--json 仍会禁止流式输出。

生成顺序。 只有在构建过程中运行 pnpm bindgen 后,src/frontend/src/backend.ts 才会生成。因此,如果前端从 ./backend 导入内容,就必须至少运行一次 caffeine build,之后 caffeine check 才能对前端进行类型检查。全新应用的 App.tsx 尚未导入 ./backend 时,即使在首次构建前也能通过类型检查。

上线。 caffeine preview --build(需要 project.id)会生成一个草稿并返回其 URL。在 caffeine.ai 网页应用中将草稿提升为正式 URL(通过 caffeine chat open 打开,或访问 caffeine.ai)。CLI 没有部署命令。使用 caffeine projects show <id> 查看草稿和正式 URL;如果已分配自定义域名,其中也会显示可用的自定义域名。

替代方案:让 Caffeine 自带的 AI 来构建

如果无法在本地运行 CLI(没有 shell 或工具链),可以改用 Caffeine 托管的 AI:通过 caffeine chat send "<prompt>"(或 caffeine.ai 网页聊天)用自然语言描述应用。随后,Caffeine 托管的 AI 会在服务器端搭建、构建并部署应用——chat send 只会提交提示词,因此这与 CLI 没有部署命令并不矛盾。本技能适用于在本地手动编写的流程。

常见陷阱

  1. 根目录的 caffeine.toml 中缺少 [workspace]。 如果没有该配置,根目录文件会被解析为 canister 清单,CLI 也就无法找到你的 canister。根清单由是否存在 [workspace] 定义,而不是由它是否位于顶层决定。
  2. 重命名后端 canister。 它必须命名为 backend——mops.toml 声明了 [canisters.backend],根目录的 bindgen 脚本会读取 ./src/backend/dist/backend.did。重命名会导致构建失败,并破坏生成的客户端。
  3. 手动编写或编辑 src/frontend/src/backend.ts 或 declarations/。 这些文件由 caffeine-bindgen 生成,并会在每次构建时被覆盖。请在 main.mo 中添加后端方法,然后重新构建,客户端就会重新生成。生成的文件头写着“请勿对本文件做任何更改”;此外,该文件也被 Biome 排除在外。
  4. 首次构建前导入 ./backend。 绑定模块由构建中的 pnpm bindgen 步骤创建。在依赖 import { createActor } from "./backend" 之前,先运行一次 caffeine preview --build(或 caffeine build)。
  5. 尝试运行 dfx deploy 或期待有 caffeine deploy。 Caffeine 应用通过 caffeine CLI 构建,并通过 Web 应用上线。工作流中没有 dfx,也没有 CLI 部署/发布命令。
  6. 删除必需的 mops.toml 设置。 请保留单个 [canisters.backend]、[canisters.backend.check-stable]、[build] outputDir,以及固定版本的 [toolchain] moc(没有该设置,mops 就无法编译)。
  7. 删除 .old/ 或 env.json,或跳过 copy:env。 .old/ 保存 check-stable 用于比较的稳定签名快照;必须将 env.json 复制到 dist/,以便提供服务的前端读取其运行时配置。
  8. 不使用 writing-motoko 技能就编写 Motoko。 现代 Caffeine Motoko 使用 mo:core、持久化 Actor 和特定模式。靠猜会导致编译器报错。请先加载 https://skills.internetcomputer.org/skills/writing-motoko/SKILL.md。
  9. 使用 npm/yarn 而非 pnpm。 该工作区基于 pnpm(pnpm-workspace.yaml、pnpm -r 脚本)。caffeine install 使用 pnpm + mops。
  10. 全新项目中,caffeine install/build 因 ERR_PNPM_NO_LOCKFILE 失败。 在非交互式 shell(Agent、CI 或任何没有 TTY 的运行环境)中,这些命令会运行 pnpm install --frozen-lockfile,而这要求存在全新项目尚未创建的 pnpm-lock.yaml。先运行一次 pnpm install 生成锁文件,然后整个流程就能正常运行。(在交互式终端中,系统会自动为你创建锁文件。)
  11. 首次运行 caffeine check 时,因 Deployed file not found: …/backend.most 失败。 稳定签名检查需要上次部署的快照,而从未部署过的项目没有该快照。请用一个空 Actor 创建 .old/src/backend/dist/backend.most(见上文的 mops.toml)。caffeine build 不会创建该文件。
  12. caffeine preview --build 因 No project.id in caffeine.toml 失败。 上传草稿需要云端项目。运行 caffeine projects create 获取 ID,在 [project] id 中设置(或传入 --project-id <id>),然后再预览。单独运行 caffeine build 无需 ID,足以验证应用能否编译。

相关技能

  • writing-motoko — 必须搭配使用的技能。所有后端 Motoko 代码的权威参考: https://skills.internetcomputer.org/skills/writing-motoko/SKILL.md。编辑 src/backend/main.mo 前,务必先加载。
  • icp-cli — 用于原生 Internet Computer / dfx / icp 项目。Caffeine 不会用到它;只有在用户没有构建 Caffeine 应用时才使用。

补充参考资料

  • references/frontend-template.md — 完整且未经修改的前端样板代码(package.json、vite.config.js、Tailwind/PostCSS/Biome 配置、tsconfig.json、index.html、env.json、main.tsx、起始版 App.tsx 以及后端 Actor 接线模式)。创建 src/frontend/ 时请阅读。

评论

支持 Markdown