@aventara/cli

中文文档
1.0.0-rc.12发布于 2026/11/01SEE LICENSE IN LICENSEES Module零依赖近 30 天下载 2382

Scaffolds an Aventara server: aventara new for a new NestJS project, aventara init for an existing one.

原始使用文档
文档目录11 节
  1. aventara new <name>
  2. aventara new <name> --host next
  3. aventara init
  4. Questions and flags
  5. What it writes (no ORM yet, SQLite, npm)
  6. What it writes in a Next.js app
  7. Next steps it prints
  8. Calling it by hand
  9. aventara skill
  10. Supported
  11. License

@aventara/cli

The aventara command: it scaffolds an Aventara server on NestJS 12 or Next.js 16.

npm i -g @aventara/cli@rc  # or run it once: npx @aventara/cli@rc <command>
aventara new my-api           # a new NestJS project with Aventara
aventara new my-app --host next   # a new Next.js app with Aventara (create-next-app, then init)
aventara init                 # Aventara added to the NestJS 12 or Next.js 16 project in this directory
aventara skill                # refresh the agent skill for the installed @aventara/core

It is run once, globally or through npx; it is not a dependency of the projects it writes. The frontend's side (framework.client.ts and the generated client) belongs to @aventara/client (npx @aventara/client@rc init).

aventara new <name>

Runs the pinned nest new (npx -y @nestjs/[email protected] new …, or pnpm dlx … under pnpm), checks that its src/app.module.ts is what that version writes, then runs exactly aventara init's pipeline over the new project and installs it. A directory that exists and is not empty is refused before anything runs.

Once installed, the project gets its first git commit, Initial Aventara Scaffold, with the lockfile in it and without .env (it is in .gitignore). No commit is made, and one line says why, when git is not installed, when git has no user.name/user.email, or when the directory is already inside a git repository (a monorepo: commit it there). --skip-git makes no repository and no commit.

aventara new <name> --host next

Runs create-next-app@latest <name> --ts --app --src-dir --import-alias "@/*" --use-<npm|pnpm> --skip-install, then aventara init's pipeline over the new app, then the install. create-next-app asks its own questions on your terminal; with --yes it takes its defaults instead (and is given --yes too), which is also what a run with no terminal needs. Its own flags go after --, as they are: aventara new my-app --host next --yes -- --tailwind --eslint. --skip-git becomes its --disable-git. --host defaults to nest.

aventara init

Runs inside an existing NestJS 12 or Next.js 16 project, telling them apart by package.json: @nestjs/core is NestJS, next is Next.js, and a project depending on both or neither is refused in one sentence. A Next.js app must use the App Router under src/app/ and map @/* to ./src/* in tsconfig.json (as create-next-app writes it), and have no ORM yet. The rest of this section is NestJS's; a Next.js app gets its own files.

In a NestJS project, it refuses another Nest major, TypeScript 7, a yarn-only lockfile, or a project already initialized.

In a project with no ORM yet, the ORM and the database are asked (or taken from the flags), and everything below is written.

In a project that already uses Prisma, the installed Prisma must be one an Aventara adapter supports, or the run is refused in one sentence with nothing written. Today that is Prisma 7 (^7.10.1) on SQLite or PostgreSQL, with a driver adapter and the prisma-client generator. Your schema, Prisma config and service are reused and never written, and your .env only gains a CORS_ORIGINS line at its end when it has none. Init finds the class extending PrismaClient and the module exporting it, or asks.

Questions and flags

Every question has a flag. On a terminal, unanswered questions are asked; anywhere else (CI, a script) pass the flags or --yes, or the run stops in one sentence naming what is missing, before writing anything. A question with one possible answer is shown, not asked.

FlagQuestionDefault
<name> (new only)The project directory.required
--host <nest|next> (new only)The framework to build on; init reads it from package.json. Not asked.nest
--orm <alias>The ORM, as an adapter's alias: prisma7 (Prisma 7, @aventara/prisma7-adapter). --help lists the aliases that exist.the only one there is
--db <provider>The database: the adapter's providers (sqlite, postgresql).sqlite
--package-manager <npm|pnpm>The package manager.the lockfile's, else the one that launched the CLI, else npm
--prisma-service <path#Export> (init)Your Prisma service, when more than one, or none, is found.the one found; none → write src/prisma.service.ts
--prisma-module <path#Export> (init)The Nest module that provides and exports it.the one found
--skip-installWrite the files; print the install instead of running it.
--skip-git (new)Passed to nest new.
-y, --yesAccept every unanswered default, and replace existing content that differs.
--verboseShow the output of nest new and the install as they run.
-- <args> (new --host next)Passed to create-next-app as they are, after its own.

While it works, each step is shown on stderr, such as [3/4] Installing dependencies (npm install). On a terminal it has a spinner and the seconds so far; in a pipe, in CI (CI) or with NO_COLOR it is one plain line per step (… done (12.4s)). The output of nest new and the install is shown only if it fails, or with --verbose.

Existing content that differs from what would be written (a .env key, a script, a file) is listed, and replaced only when you confirm, or with --yes; where nobody can be asked, the run stops and touches nothing.

What it writes (no ORM yet, SQLite, npm)

PathOwner afterwards
prisma/schema.prisma: prisma-client generating into src/generated/prisma, a User modelyou
prisma.config.ts: loads .env itself (Prisma does not)you
src/prisma.service.ts: PrismaService extending the client with the driver adapter, refusing a missing DATABASE_URL before the server listens; PrismaModuleyou
src/aventara.config.ts: aventaraConfig(prisma): the api mount path (/api), a diagnostics sink that logs the raw error of a server failure, with its stack, through Nest's Logger, and the exposed/exemptions, pipelines and resources you addyou
src/app.module.ts: one edit that adds the imports, PrismaModule and AventaraModule.forRootAsync({ … }); printed instead when the file is not the shape expectedyou
test/app.e2e-spec.ts: one edit that adds a GET /api/_contract → 200 test after Nest's GET / test; left alone when the file is not Nest'syou
src/main.ts: one edit after NestFactory.create: app.enableCors(…) for the comma-separated origins in CORS_ORIGINS, and CORS off when it is unset or empty, then a commented-out platform-level rate limiter (express-rate-limit; Nest's @nestjs/throttler is a guard, which does not run on Aventara's routes); left alone when the file already configures CORS, printed when it has no such lineyou
.env (DATABASE_URL, and CORS_ORIGINS="http://localhost:5173,http://localhost:3001" appended unless a line sets it), .gitignore (/src/generated/, /dev.db*, .env)you
package.json: @aventara/* at this CLI's version, prisma, @prisma/client and the driver at the adapter's declared range, so the first install takes the newest Prisma 7; aventara:prepare, run by postinstall and by prebuild, prestart, prestart:dev and prestart:debug, and the .env on the start scripts and test:e2e (--env-file, --env-file-if-exists)you
pnpm-workspace.yaml (pnpm only): allowBuilds for Prisma's and SQLite's install scriptsyou
src/generated/prisma/**, src/generated/aventara/discovery.artifact.tsgenerated by aventara:prepare (run on every install, build and start, so a schema change needs only a restart); never edit
.claude/skills/aventara/ (SKILL.md, reference/*.md, .aventara-skill.json): the agent skill your AI coding agent readsAventara's: aventara skill refreshes it, and keeps a file you changed unless --force
AGENTS.md: an Aventara section between <!-- aventara:start --> and <!-- aventara:end -->, appended to an existing fileyou, except the marked section

What it writes in a Next.js app

Everything Aventara is in one folder, src/aventara/, at the paths @aventara/next declares and aventara-build reads.

PathOwner afterwards
prisma/schema.prisma, prisma.config.tsyou (as in a NestJS project)
src/prisma.ts: prisma(), the app's one Prisma client with the driver adapter, made on first use and kept across next dev reloadsyou
src/aventara/config.ts: aventaraConfig, as in a NestJS project, logging through console.erroryou
src/aventara/adapter.ts: the adapter's descriptionyou
src/aventara/server.ts: Aventara({ ...aventaraConfig, adapter, prebuilt, state }) exporting handlers, avClient, avApp and ready; @/aventara/serveryou
src/app/api/[...aventara]/route.ts: every method of handlersyou
src/instrumentation.ts: awaits ready() on the Node.js runtime, so a bad configuration stops next start. An instrumentation file of yours is never replaced, even with --yes: the lines to add are printedyou
next.config.ts: serverExternalPackages: ["@aventara/core", "@aventara/prisma7-adapter"] added to its configuration object, so Node.js loads them once per server process (one core and one Prisma client for every route and page). Added to create-next-app's config, or to any whose const nextConfig = { object has no serverExternalPackages; written as a new next.config.ts when the app has none. A config that already names serverExternalPackages, or is written another way, is never changed, even with --yes: the line to add is printedyou
package.json: @aventara/core, @aventara/next, the adapter and @aventara/build at this CLI's version, server-only, Prisma and its driver at the adapter's declared range (the newest Prisma 7 on the first install); aventara:prepare (ending in aventara-build --client), run by postinstall and prebuildyou
.env (DATABASE_URL), .gitignore (/src/generated/, /dev.db*, /src/aventara/generated/, /src/aventara/client.ts, /src/aventara/universal.ts, .env)you
src/aventara/client.ts, src/aventara/universal.ts, src/aventara/generated/generated by aventara:prepare; never edit

No CORS (the browser calls the same origin), no Pages Router, no proxy, and no MCP route: an mcp endpoint you add on Next.js needs authorization. Next steps: npx prisma db push, then npm run dev.

Next steps it prints

npx prisma db push          # create the tables (init never touches a database); pnpm: pnpm exec prisma db push
npm run start:dev           # GET http://localhost:3000/api/_contract
npx @aventara/client@rc init   # in your frontend; pnpm: pnpm dlx @aventara/client@rc init

The frontend command is the package manager's own runner (npx, or pnpm dlx under pnpm) and, while the CLI is a prerelease, carries its dist-tag (@rc), so the client comes from the same release.

With PostgreSQL, set DATABASE_URL in .env first (init writes Prisma's placeholder, and never asks for a secret).

Calling it by hand

With the server running, the starter User model answers at /api:

# 1. The contract. Its protocol.hash is what every resource request sends as Aventara-Contract-Hash.
HASH=$(curl -s http://localhost:3000/api/_contract | node -p 'JSON.parse(require("fs").readFileSync(0, "utf8")).protocol.hash')

# 2. find.many on User, with both identity headers.
curl -s -X POST http://localhost:3000/api/_resources/User/find/many \
  -H 'Content-Type: application/json' \
  -H 'Aventara-Protocol-Version: 1' \
  -H "Aventara-Contract-Hash: $HASH" \
  -d '{}'
# {"data":[],"code":"A1000","cause":null}

Leave out an identity header and the answer is 400 A2000, naming the header that is missing. The hash changes whenever the schema or the configuration does: fetch it again, and regenerate the client.

Resource keys are the model names, as written. model User is User everywhere: on the wire (/_resources/User/find/many) and in the generated client (avClient.User.find.many({})). Nothing is renamed, lower-cased or pluralized.

Results are read-only. A list result is a readonly array, so type it readonly User[]: const users: readonly User[] = await avClient.User.find.many({});.

aventara skill

Writes the agent skill for the @aventara/core installed in the project in this directory: its version, and its ERRORS.md as reference/errors.md. It reads those files and runs none of the project's packages. A skill file it wrote before is replaced; one you changed is kept, with a warning, unless you pass --force. In AGENTS.md only the text between the Aventara markers is replaced (or the section appended), and CLAUDE.md is never written. Run it with the CLI at your @aventara/core version: npx @aventara/cli@<version> skill.

Supported

  • NestJS 12.
  • Node ^22.23.4 || >=24.22.1. On any other Node the bin refuses in one sentence naming that range. On Node 22 use npm ≥ 11, because Node 22's bundled npm 10 cannot install Nest 12's own scaffold. A CommonJS project's jest e2e needs Node ≥ 24.9, which is Nest's and Jest's limit.
  • npm and pnpm. Yarn is not supported.
  • ESM and CommonJS projects.
  • Prisma 7 (^7.10.1) on SQLite and PostgreSQL.

The ORMs, majors, databases and drivers on offer are generated from the Aventara adapter packages that exist (src/catalog/adapter.catalog.generated.ts), never listed by hand, so a future @aventara/prisma8-adapter appears once it exists.

License

PolyForm Shield 1.0.0 with an additional permission. It is free to use, including in commercial applications, but you may not use it to build a product that competes with Aventara itself. See LICENSE and LICENSE-ADDITIONAL-PERMISSION.md.

版本与发布记录

@aventara/cli 共发布 16 个版本,首次发布于 2026/10/06;过去 12 个月发布了 16 个版本。

版本发布日期距今
1.0.0-rc.12latest2026/11/016 天前
1.0.0-rc.112026/10/317 天前
1.0.0-rc.102026/10/2711 天前
1.0.0-rc.92026/10/2315 天前
1.0.0-rc.82026/10/2216 天前
1.0.0-rc.42026/10/2117 天前

其他发布通道:pilot → 0.1.0-pilot.4。

关于 @aventara/cli 的常见问题

@aventara/cli 是什么?

Scaffolds an Aventara server: aventara new for a new NestJS project, aventara init for an existing one.

如何安装 @aventara/cli?

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

@aventara/cli 支持 TypeScript 吗?

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

@aventara/cli 支持 ESM 还是 CommonJS?

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

@aventara/cli 需要什么版本的 Node.js?

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

@aventara/cli 可以商用吗?

@aventara/cli 使用 SEE LICENSE IN LICENSE 许可。许可条款写在包内的独立文件中,请阅读该文件确认可否商用。以上为概括,不构成法律意见,请以许可原文为准。

@aventara/cli 的下载量有多少?

根据 npm 官方下载统计,@aventara/cli 在 2026/10/07 – 2026/11/05 这 30 天内被下载 2,382 次,日均约 79 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@aventara/cli 还在维护吗?

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