Agent Native docs v1.0.0Showcase
Uppercut Labs / Agent Native

Existing Astro site: experimental init

The @uppercut-labs/agent-native/init entrypoint is available in the 1.0.0 package. There is no agent-native init executable yet. Use the E01 fixture to try the current programmatic flow from a local package tarball:

npm ci
npm run example:e01

E01 copies an existing static Astro site into a temporary directory, installs a local tarball, applies a reviewed plan, and builds the site. It checks the original pages, routes, assets, data, and lockfile preservation after installation.

Plan before applying

The supported automatic edit is intentionally narrow: an Astro project with a single, literal defineConfig({ output: 'static' }) configuration. Detection reads project files as data; it does not import the site's config or business modules. A project with multiple apps, competing lockfiles, dynamic config, or an unsupported host receives an unresolved action instead of a guessed edit.

Detection also distinguishes pure static output from prerender = false on-demand routes. It records whether the Astro config has a server adapter, diagnoses server-adapter-missing, and rejects static files placed at known HTTP/MCP protocol paths. Existing on-demand projects are manual-integration cases: init does not rewrite their adapter or endpoint routes. Select a sidecar for a pure static site, or review same-origin endpoints and a supported adapter explicitly. Never rewrite an Astro 7 project to the removed historical output: 'hybrid' mode.

After installing this source package into a disposable Astro project, a caller can inspect the plan and then explicitly approve the same choices:

import { applyInitPlan, createInitPlan, restoreInit } from '@uppercut-labs/agent-native/init';

const projectRoot = '/absolute/path/to/existing-astro-site';
const choices = {
  hosting: 'cloudflare',
  routeMode: 'sidecar',
  sidecarOrigin: 'https://your-worker.example',
};
const plan = await createInitPlan(projectRoot, {}, choices);
console.log(plan);

// Review detection, unresolved actions, proposed files, and choices first.
const result = await applyInitPlan(projectRoot, plan, choices, { approved: true });
console.log(result);

// Later, if the generated files are unchanged:
// await restoreInit(projectRoot);

The plan digest binds detected evidence, overrides, and selected choices. Apply rechecks that evidence and refuses a stale plan. A second init is a no-op. Restore checks ownership and content digests before changing any file; it reports a conflict if a generated file was edited. Keep the ownership file at .agent-native/ownership.json with the project until restoration is no longer needed.

What this slice creates

The installer patches the recognized Astro config to inject .agent-native/browser-entry.mjs as a page script and writes .agent-native/init.json with the selected mode and sidecar origin. The browser entry emits an agent-native:ready event. It does not discover site functions, register a capability, create a server route, deploy a Worker, or edit the project's dependencies or lockfile. Bind only reviewed application operations using the capability guide, and use the static-site guide for the separate Worker example.

After init, these steps remain yours:

  1. Install what you import: @uppercut-labs/agent-native, zod@4.6.5 for the schema adapter, and @modelcontextprotocol/server@2.3.0 if you expose MCP (installation).
  2. Define capabilities and bind them to reviewed application operations.
  3. Pass an authorization port on every execution, including public reads.
  4. Add and deploy the server route or Worker sidecar if you expose HTTP or MCP.
  5. Test discovery, one successful call and one denied or invalid call before you publish.

E01's installed after-state explicitly executes its public album lookup through the shared registry and authorization port. Init does not generate this application code:

/** @param {unknown} input */
export function runAlbumLookup(input) {
  return executeCapability(registry, {
    identity: getAlbumCapability.identity,
    runtime: 'local',
    input,
    caller: { kind: 'anonymous' },
    authorization: publicReadAuthorization,
  });
}

View tested source

The npm run example:e01 export uses Node.js 22 or newer and a root npm ci. It builds the static site and checks found/missing results. A malformed album slug is rejected before the handler runs; correct the slug and retry. See the E01 project instructions.

The current init API is a tested foundation for a later interactive CLI. It is not a production deployment or a browser-agent host test.