@appport/appboundry

中文文档
1.11.0发布于 2026/11/06Apache-2.0TypeScriptES Module近 30 天下载 1784

Build and verify repository applications for AppBoundry, with explicit canonical product tooling.

原始使用文档
文档目录3 节
  1. Upgrade note for 1.11.0: artifacts that declare accounts or…
  2. Self-contained artifacts ( appboundry.app/1 )
  3. WASM providers

@appport/appboundry

Build and verify an AppPort application for AppBoundry. The default commands operate on the current repository's authoritative contract, implementation, and WASM artifact.

The canonical AppBoundry product tooling is available under the explicit product subcommand, so it cannot be confused with a customer application build:

# Wrap the customer application in the current directory
npx appport add
npx @appport/appboundry test
npx @appport/appboundry build
npx @appport/appboundry verify

# Build the canonical AppBoundry product
npx @appport/appboundry product build
npx @appport/appboundry product certify

The package ships templates/appboundry.gitignore for generated or copied AppBoundry workspaces. Installers copy it to .gitignore; it excludes macOS metadata (.DS_Store and .DS_changes) and node_modules/.

npx @appport/appboundry product build --out AppBoundry.app
npx @appport/appboundry product certify # defaults to AppBoundry.app

test opens AppPort Studio against the current repository's running application so its capability boundary can be exercised before deployment. build emits a repository-named immutable AppPort/application-bundle/1 .app directory plus its browser-uploadable .appbundle. verify checks that application and its declared capabilities. product build and product certify are reserved for the canonical AppBoundry platform artifact.

Upgrade note for 1.11.0: artifacts that declare accounts or tenancy are refused

From 1.11.0, appboundry run refuses an artifact whose manifest declares identity.accounts or identity.tenancy (FeltKit writes these for auth.accounts and auth.tenant), with ARTIFACT_IDENTITY_UNSUPPORTED. This host does not serve FeltKit's sign-up, sign-in, invitation or tenant routes (/api/auth/*, /api/tenants/*), so such an artifact would run with operator-issued sessions only, and its tenant-scoped collections closed. 1.10.0 and earlier ran it that way without saying so.

To keep running it with operator-issued sessions, accept that explicitly:

appboundry run my-app.app --state ./state --accounts operator-sessions
# or: APPBOUNDRY_ACCOUNTS=operator-sessions appboundry run my-app.app --state ./state

The acceptance is recorded as a runtime warning. Artifacts built before FeltKit declared these fields, and artifacts that don't use accounts or tenancy, are unaffected. Deployments that start the runtime themselves (containers, the Hetzner runner) must pass the flag or the variable before moving to 1.11.0. The proposed identity host interface is in docs/identity-host-interface.md (FK-GAP-013).

Self-contained artifacts (appboundry.app/1)

From 1.2.0, appboundry run serves a self-contained artifact: a manifest.json plus a module.wasm that imports nothing. FeltKit's feltkit build --target appboundry produces one.

npx @appport/appboundry@^1.5.0 run my-app.app --state ./state
appboundry --version --json   # format, guest ABI, host interfaces (migrations@1 from 1.4.0, transactions@1 from 1.5.0), services, stateContract: "enforced"

What the host provides to application code:

  • storage, with FeltDB state on the --state directory;
  • identity and sessions;
  • files, notifications, configuration, jobs (run as the enqueuer) and webhooks (emit is recorded; no delivery, since the artifact has no network).

The artifact's data guarantees (1.3.0). The manifest's state.contract, a FeltDB state contract, is enforced by FeltDB, as it is on the producer's own runtime:

  • required fields and types;
  • unique constraints (a duplicate is CONFLICT);
  • references with restrict on delete (FAILED_PRECONDITION);
  • no undeclared collections.

How a contract is installed. It is validated, composed with the AppPort Services collections the artifact uses, and installed before anything is served:

  • A new artifact version is accepted only when every stored record satisfies its contract.
  • Otherwise, and when it drops a populated collection, the host refuses to start with SCHEMA_INCOMPATIBLE, naming what changed and the failing record. The previous version keeps running on unchanged data.
  • An artifact built before contracts runs as before, with a warning.

The artifact's data migrations (1.4.0). A manifest may list migrations (state.migrations: { format: "appboundry.migrations/1", order: [...] }, host interface migrations@1). They are the application's own functions, bundled into module.wasm like every other function (FeltKit: app.migration()); the host never receives code as data. Before serving, the host:

  • runs each pending migration once, in the listed order, in the guest (invocation { migration: name }). A migration may only read application records (migration.records); it returns the writes it staged, and a later migration reads what an earlier one wrote;
  • commits those writes, the new contract and a history record in one FeltDB evolution; FeltDB re-validates every record against the new contract. A collection the new contract drops is emptied first, in an intermediate contract version, recorded once;
  • records in _appboundry_contract what it actually applied: the migrations, how many records were put and deleted, the contract versions, the artifact and who authorized the start (authorizedBy; appboundry run records "appboundry run").

A migration that fails, or leaves a record the new contract refuses, refuses the start with SCHEMA_INCOMPATIBLE (the migration, its error code, or FeltDB's violation) and changes nothing: the previous artifact keeps running on unchanged data. An applied migration never runs again. A format other than appboundry.migrations/1 is refused when the artifact loads (MIGRATIONS_UNSUPPORTED). appboundry run --no-migrate refuses to start an artifact that would change the schema or run a migration, so a deployment can keep authorizing changes separately from starting a runtime.

Sequences and after-commit effects (1.5.0). An artifact that requires the host interface transactions@1 (FeltKit: ctx.db.sequence, ctx.afterCommit) gets two guest operations:

  • db.sequence { name }: the next number of a stream, drawn in the mutation's transaction and written with it, guarded on the version read. Within a stream, numbers are strictly increasing and gapless in commit order; a failed mutation consumes none. Different streams never contend. Concurrent writers to one stream serialize (CONFLICT). A manifest function with retry: { sequenceConflicts: n } is re-run instead, when it used no service.
  • outbox.stage { effects }: after-commit notifications, webhook events and jobs, validated and committed with the mutation's writes (_appboundry_outbox), or not at all. After the commit, the host performs them as the caller and records done or failed. Its worker recovers records a stopped runtime left behind. A failed one waits for an operator: appboundry admin outbox list [--status failed] and appboundry admin outbox retry <id>. From 1.6.0 a job or webhook delivery is created in the same FeltDB transaction that records the effect done (AppPort Services' transaction context, @appport/services 0.13.1). So it exists once per committed effect, across a stop and a recovery; a refused creation leaves neither the job nor a done mark. Notifications carry the record id as their idempotency key. Creation, not execution: a job's run and a webhook's delivery to its endpoint are retried by the services.

A host without the interface refuses such an artifact when it loads, and refuses an unsupported interface version. The contract is FeltKit's docs/TRANSACTIONS.md; FeltKit's tests/e2e/transactions-parity.test.mjs requires the same results here and on FeltKit's runtime.

MCP (1.11.0). A running artifact also serves its published AppPort capabilities as MCP tools at POST /mcp (Streamable HTTP, stateless, JSON responses; @appport/mcp). It uses the same host sessions (Authorization: Bearer abs_…), roles and guest decisions as /appport: a token that does not verify gets 401, and anonymous callers reach only public capabilities.

Both artifact formats (1.11.0). appboundry run, appboundry artifact verify|inspect and appboundry app install|inspect recognize the artifact by its manifest. An appboundry.app/1 artifact runs on the artifact host as before. An AppPort application bundle (AppPort/application-bundle/1, from appport app package) is verified and then started with appport app start. The managed deploy path still accepts appboundry.app/1 only (docs/artifact-formats.md).

How the release is checked. pnpm release:appboundry:verify packs this package, installs it into an empty directory, and runs a FeltKit application built from npm against it.

One AppPort runtime (1.7.0). The package depends on the published @appport/core, @appport/sdk and appport at exact versions instead of shipping private copies of them, so an installation runs one AppPort runtime, shared with the application's own @appport/sdk. It follows AppPort's current semantics: an application contract carries each capability's explicit effect and authorizationContract, so rebuilding an application yields a new package identity, while a package built by an earlier release still verifies at its original identity; and a capability that declares permissions is refused (UNAUTHORIZED) unless the host supplies an authorizer.

The Boundry design foundation (1.7.1). The artifact portal served at /portal (portal/app.js, portal/portal.css, inlined into AppBoundry.wasm) uses the same foundation as the cloud portal: StackUI states for deployments, connections and credentials, failed host reads shown as unknown instead of missing, and the shared theme switch. The package depends on appport 1.3.0, whose bundled Studio carries the AppBoundry host console on the same foundation.

WASM providers

AppBoundry reuses the same .app package for a verified Synapse WASM capability. Synapse owns module discovery, validation, the capability contract, and WASM execution semantics; AppBoundry owns packaging, provider composition, binding, authorization, and invocation routing:

.app
 └── WASM provider
       ↓
  Synapse capability
       ↓
 AppBoundry discovery → bind → invoke

For example, a packaged change-context-resolver continues to advertise [email protected]. A consumer requires that capability through the normal AppBoundry composition API and does not need to know the artifact path, module filename, or runtime. Inspecting or installing the package reports runtime: wasm while preserving the Synapse capability identity.

To share a private HTTP application through an AppBoundry edge, keep the application bound to localhost and run:

npx @appport/appboundry connect 3000 --edge https://edge.example

Or set APPBOUNDRY_EDGE_URL and optionally APPBOUNDRY_CREDENTIAL.

The connectivity path is provider-neutral and does not require an AppPort application runtime. The client makes an authenticated outbound connection to the configured edge, receives an edge-issued share and endpoint, and proxies a bounded HTTP subset to the local port.

The package also exposes an in-memory capability composition runtime plus snapshot-backed inspection commands so provider/consumer/binding state stays observable without requiring direct application-to-application integration:

# publish a local capability provider into a runtime snapshot
npx @appport/appboundry capabilities publish llm.generate@1 \
  --provider local-llm \
  --application example.local-llm

# register a consumer requirement
npx @appport/appboundry capabilities require llm.generate@1 \
  --consumer my-app \
  --application example.consumer

# inspect currently reachable providers
npx @appport/appboundry providers llm.generate@1

# create a logical binding
npx @appport/appboundry bind llm.generate@1 \
  --consumer-application example.consumer \
  --provider-application example.local-llm

# inspect the application view
npx @appport/appboundry capabilities --application example.consumer

By default these commands read and write .appboundry/runtime.json in the current working directory. Pass --runtime <path> to target a different snapshot file, and --json for machine-readable output.

Current connectivity surface:

  • shared AppBoundry/connect protocol with hello, ready, request, response, heartbeat, close, and error messages
  • edge-owned connection_id, share_id, endpoint_id, and authenticated application_id
  • explicit bounded buffering with:
    • max request body: 524288 bytes
    • max response body: 524288 bytes
    • max frame size: 2097152 bytes
  • supported methods: GET, POST, PUT, PATCH, DELETE, HEAD, OPTIONS
  • hop-by-hop header filtering in both directions
  • heartbeat/liveness, disconnect, reconnect, revoke, and expire handling

Current limitations:

  • buffering is bounded rather than streamed
  • the development edge is single-node and keeps share/endpoint state in memory
  • status / revoke CLI commands are not yet exposed; revocation and expiry are edge capabilities

版本与发布记录

@appport/appboundry 共发布 22 个版本,首次发布于 2026/09/08;过去 12 个月发布了 22 个版本。

版本发布日期距今
1.11.0latest2026/11/062 天前
1.10.02026/11/062 天前
1.9.02026/11/052 天前
1.8.02026/11/053 天前
1.7.32026/11/053 天前
1.7.22026/11/043 天前

关于 @appport/appboundry 的常见问题

@appport/appboundry 是什么?

Build and verify repository applications for AppBoundry, with explicit canonical product tooling.

如何安装 @appport/appboundry?

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

@appport/appboundry 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@appport/appboundry 支持 ESM 还是 CommonJS?

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

@appport/appboundry 需要什么版本的 Node.js?

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

@appport/appboundry 可以商用吗?

@appport/appboundry 使用 Apache-2.0 许可。宽松许可:允许商业使用、修改和再分发,并附带明确的专利授权;分发时需保留许可与 NOTICE 文件,修改过的文件要注明改动。以上为概括,不构成法律意见,请以许可原文为准。

@appport/appboundry 的下载量有多少?

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

@appport/appboundry 还在维护吗?

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