# Build and publish a Plugin

Create a frontend-only, full-stack, or backend-only Plugin, keep its package,
protocol, deployment, and manifest boundaries explicit, upload a managed
immutable package, run publication checks, and send every target for review.
The scaffold uses the same public CLI and Registry path as first-party Plugins.

## Outcome

At the end you will have:

- a published Plugin release with a SHA-512-addressed managed artifact;
- one published backend deployment revision for every declared component;
- an approved independent human review of every frozen target;
- the exact artifact installed in an independent consumer Environment;
- proven frontend activation and, when declared, backend action by an
  independent consumer principal.

Submission is not automatic approval. The public catalog exposes the release
only after the Registry's normal review and publication transitions.

## Supported variants

| Variant       | Scaffold command                                                | Contract shape                                                 |
| ------------- | --------------------------------------------------------------- | -------------------------------------------------------------- |
| Frontend-only | `alamr create plugin <name>`                                    | At least one frontend adapter; no backend component            |
| Full-stack    | `alamr create plugin <name> --kind full-stack --with-backend`   | At least one frontend adapter and one backend component        |
| Backend-only  | `alamr create plugin <name> --kind backend-only --with-backend` | Backend components only; no frontend adapter or browser export |

`--kind full-stack` and `--with-backend` are an explicit pair; the CLI rejects
either one without the other, and the default remains `frontend-only`. The
default artifact path uploads a managed `.tgz`, so an npm publishing account is
not required; `--provider npm` is available when the package is already on a
public npm registry.

## Build and publication prerequisites

Every copyable command below uses the complete pinned
`npx @al-amr/cli@0.1.0-alpha.7` invocation. This version is available for the
human/CLI journey; the official Agent Context Pack still requires promotion.

- the exact public CLI version and integrity advertised on the [Start page](/start). The generated
  `package.json` records the selected package manager; use that exact manager
  for subsequent project commands;
- an Al-Amr developer account and access to the target Registry;
- an exact package SemVer and a redistributable license;
- public HTTPS hosting for every declared backend component (full-stack and
  backend-only variants).

## Exact steps

### 1. Scaffold a frontend-only Plugin

```sh
npx @al-amr/cli@0.1.0-alpha.7 create plugin my-plugin
cd my-plugin
npm install
npx @al-amr/cli@0.1.0-alpha.7 validate --json
```

The generated `src/index.ts` is a real vanilla adapter:

```ts
export interface ActivateOptions {
  host: HTMLElement;
}

export function activate({ host }: ActivateOptions): () => void {
  const element = document.createElement("div");
  element.textContent = "Hello from an Al-Amr Plugin";
  host.append(element);
  return () => element.remove();
}
```

The cleanup function is part of the contract with the host. Replace the text
and DOM behavior with your capability, but keep resource cleanup explicit for
listeners, timers, sockets, media, or device access that you add.

### 2. Keep the manifest, package, and exports aligned

Edit `name`, `shortDescription`, `category`, and documentation in
`al-amr.plugin.json` for the real capability, and keep these invariants:

| Boundary    | Required relationship                                                                |
| ----------- | ------------------------------------------------------------------------------------ |
| Version     | `package.json.version` equals `al-amr.plugin.json.version`                           |
| License     | `package.json.license` equals `documentation.license`                                |
| Export      | Every frontend adapter `exportPath` exists in `package.json.exports`                 |
| Types       | Every named adapter export exists in the built TypeScript declaration                |
| Composition | Every provided/contributed semantic surface names a declared adapter export          |
| Identity    | Registry Plugin ID, Publisher, and slug are assigned or synchronized by `alamr link` |
| Backend     | Live deployment URLs stay outside the Plugin manifest                                |

Use only the permissions the Plugin needs. Separate enforceable
`platformPermissions` from browser requirements, data and network disclosures,
and backend `grantScopes`. If the adapter provides a mount point or contributes
UI to a host surface, declare it under `frontendAdapters[].composition` and use
semantic surface IDs such as `avatar.overhead`; never import another Plugin to
inject the UI.

### 3. Link the Registry Project

```sh
npx @al-amr/cli@0.1.0-alpha.7 login
npx @al-amr/cli@0.1.0-alpha.7 link
npm install
npx @al-amr/cli@0.1.0-alpha.7 validate --json
```

With no Project ID, `link` creates a Plugin Project through the public
Management API and synchronizes `pluginId`, Publisher ID and handle, and slug
into the manifest. For the managed artifact path it also changes the generated
placeholder package name to `@al-amr-community/{publisher-handle}--{plugin-slug}`.
To link an existing owned Project, pass its `proj_*` ID. After linking, update
`documentation.canonicalUrl` to the stable public Plugin page. The second
`npm install` synchronizes local package-manager metadata after `link` changes
the managed package name.

### 4. Build and inspect the package

```sh
npm run typecheck
npm run build
npm run test:pack
npx @al-amr/cli@0.1.0-alpha.7 inspect --json
npx @al-amr/cli@0.1.0-alpha.7 validate --json
```

`build` produces `dist/index.js` and `dist/index.d.ts`. `test:pack` runs an
npm pack dry run and `publint`. Validation checks manifest schemas, package
identity, license, lifecycle scripts, dependency specifications, deployment
files, and adapter exports. Do not continue until all commands return process
code `0`.

### 5. Create the immutable release and run checks

```sh
npx @al-amr/cli@0.1.0-alpha.7 test --json --visibility unlisted --channel preview
```

For a frontend Plugin, the default managed path packs the local package,
creates or reuses the exact Plugin release version, uploads the package through
the managed artifact boundary, verifies the returned size and SHA-512
integrity, creates or reuses the publication submission, and runs publication
checks. Repeating `test` reuses an existing version only when manifest and
package content still match; otherwise bump SemVer in both
`al-amr.plugin.json` and `package.json`. The CLI rejects replacing immutable
content under an existing Plugin version.

### 6. Submit for review

```sh
npx @al-amr/cli@0.1.0-alpha.7 publish --json --yes
npx @al-amr/cli@0.1.0-alpha.7 status --json
```

A ready frontend-only submission reports
`Publication submission sent for review.` Checks, human review, and
publication remain distinct transitions. After publication, an Environment can
inspect and install the exact release:

```sh
npx @al-amr/cli@0.1.0-alpha.7 inspect publisher-handle/plugin-slug --json
npx @al-amr/cli@0.1.0-alpha.7 add publisher-handle/plugin-slug --adapter default --yes
```

### 7. Scaffold full-stack or backend-only variants

Use the official full-stack starter when the Plugin needs both browser code and
a publisher-hosted service:

```sh
npx @al-amr/cli@0.1.0-alpha.7 create plugin my-service --kind full-stack --with-backend
cd my-service
npm install
npm run validate -- --json
npm run typecheck
npm run build
npm run test:pack
```

For a service-only capability with no browser export, use the official
backend-only starter:

```sh
npx @al-amr/cli@0.1.0-alpha.7 create plugin my-service --kind backend-only --with-backend
cd my-service
npm install
npm run validate -- --json
npm run typecheck
npm run build
npm run test:pack
```

The generated standalone project contains no `workspace:*`, local-file, or Git
dependency. Every new release with a backend component must give that component
a `protocolArtifactId`; the official HTTPS starter generates
`protocol/service.openapi.json` and pins its SHA-256 digest. Registry validates
the actual packaged bytes during checks and again before publication; metadata
alone is not proof of the protocol.

### 8. Host the backend and submit the target set

After `alamr link`, host `packages/backend` over HTTPS. Set
`AL_AMR_PLUGIN_DEPLOYMENT_ID` in the hosting platform to the Registry-issued
`dep_*` value; this is public identity, not a secret. Update the endpoint and
health URL in `al-amr.deployments.json`, then run:

```sh
npx @al-amr/cli@0.1.0-alpha.7 validate --json
npx @al-amr/cli@0.1.0-alpha.7 test --json --visibility unlisted --channel preview
npx @al-amr/cli@0.1.0-alpha.7 publish --json --yes
npx @al-amr/cli@0.1.0-alpha.7 status --json
```

The Plugin release and every backend deployment revision are immutable,
separately checked submissions. `alamr publish` preflights the complete local
set and submits ready items resumably; an interrupted set is continued by
rerunning `alamr publish` after `alamr status --json`, which submits only the
remaining `ready_for_review` targets. Live endpoint configuration belongs only
in `al-amr.deployments.json`, never in the Plugin release, and public
deployment `config` is reviewed metadata, not secret storage.

### 9. Prove consumer installation

After publication, install the exact release in a separate consumer Environment
that you do not publish from the same owner account, choosing exactly one
integration mode:

```sh
# Import and run the reviewed browser adapter. A full-stack release also makes
# that same release's backend components eligible for Plugin Grants.
npx @al-amr/cli@0.1.0-alpha.7 add publisher-handle/plugin-slug@1.2.3 \
  --integration frontend-adapter --adapter default --yes

# Authorize the reviewed backend-component set without adding a browser package.
npx @al-amr/cli@0.1.0-alpha.7 add publisher-handle/plugin-slug@1.2.3 \
  --integration backend-components --yes
```

The authoring Journey then verifies the consumer proof: the installation lock
(`ALAMR_PLUGIN_CONSUMER_INSTALL_MISSING`), frontend activation
(`ALAMR_PLUGIN_FRONTEND_ACTIVATION_MISSING`), backend action when declared
(`ALAMR_PLUGIN_BACKEND_ACTION_MISSING`), a published consumer Environment
(`ALAMR_PLUGIN_CONSUMER_ENVIRONMENT_PUBLICATION_MISSING`), and a consumer
principal independent of the publisher owner
(`ALAMR_PLUGIN_CONSUMER_PRINCIPAL_NOT_INDEPENDENT`).

## Files and public contracts

- `al-amr.plugin.json` — the Plugin manifest; schema in the
  [manifest reference](/reference/manifests);
- `package.json` — version, license, and exports kept aligned with the
  manifest;
- `dist/index.js` and `dist/index.d.ts` — the built adapter entry and its type
  declaration;
- `al-amr.deployments.json` — live endpoint and health URLs, one entry per
  declared backend component;
- `protocol/service.openapi.json` — the immutable protocol bytes referenced by
  `protocolArtifactId`;
- `manifest.json`, `integration.md`, and `types.d.ts` — immutable review
  surfaces projected from the manifest at publication;
- `al-amr.lock.json` v3 — the Environment-side installation record: frontend
  entries retain the package artifact and SHA-512 integrity, backend-component
  entries contain no adapter, package, or integrity.

## Human gates

| Gate                                    | Actor                                    | What is approved                                                           |
| --------------------------------------- | ---------------------------------------- | -------------------------------------------------------------------------- |
| `alamr login` browser or device handoff | The human account owner                  | The exact displayed device code and URL                                    |
| `alamr link`                            | The Project owner                        | Binding this directory to the exact Registry Project                       |
| `alamr publish --yes`                   | The Project owner                        | Submission of the exact release and deployment digests as one ready set    |
| Review decision                         | An independent human reviewer            | The frozen evidence of each target; owner and submitter cannot self-review |
| Publication transition                  | An independent publication administrator | The exact approved digests per target; the reviewer cannot publish         |
| Consumer installation                   | The consumer Environment owner           | Trust approval (`--yes`) of the exact reviewed artifact and disclosures    |

## Expected structured outputs

| Command                       | Success evidence                                                                                   |
| ----------------------------- | -------------------------------------------------------------------------------------------------- |
| `alamr validate --json`       | Process code `0`, `ok: true`, and a valid manifest message                                         |
| `alamr test --json`           | `Publication checks completed.` with the release, artifact provider, submission, and check outcome |
| `alamr publish --json --yes`  | `Publication submission sent for review.` for every ready target in the set                        |
| `alamr status --json`         | The Project, linked immutable targets, and current publication records                             |
| `alamr inspect <spec> --json` | The published card, exact manifest, versions, artifacts, and integration guide URL                 |

## Stable errors and remediation

| Code                                        | Meaning                                               | Retryable | Remediation                                                                               |
| ------------------------------------------- | ----------------------------------------------------- | --------- | ----------------------------------------------------------------------------------------- |
| `ALAMR_USAGE`                               | Invalid arguments or options                          | No        | Run `alamr --help` and correct the invocation                                             |
| `ALAMR_AUTH_REQUIRED`                       | Missing or expired credential                         | No        | Run `alamr login` or supply a scoped Project token                                        |
| `ALAMR_NETWORK_ERROR`                       | Registry unreachable                                  | Yes       | Check DNS/TLS/proxy and Registry health, then retry                                       |
| `ALAMR_CONFLICT`                            | Version exists with different content, or state moved | No        | Bump the Plugin SemVer for changed content; otherwise read `alamr status --json` first    |
| `submission_not_ready`                      | One target in the set is not `ready_for_review`       | No        | Fix and rerun `alamr test` for every target; submit only the consistent ready set         |
| `artifact_snapshot_changed`                 | Frozen artifact evidence no longer matches            | No        | Stop; never rewrite a digest — create a new immutable release                             |
| `backend_protocol_reference_missing`        | A backend component lacks a `protocolArtifactId`      | No        | Bind every component to a declared OpenAPI/AsyncAPI artifact of the matching kind         |
| `backend_protocol_artifact_bytes_missing`   | Referenced protocol bytes are absent from the package | No        | Package the exact protocol path; a manifest declaration alone is not publishable evidence |
| `backend_protocol_artifact_digest_mismatch` | Packaged bytes differ from the declared SHA-256       | No        | Regenerate the digest from the exact packaged bytes, bump SemVer, and test a new release  |

The full index of stable codes is in [Troubleshooting](/docs/errors/troubleshooting).

## Definition of done

- The exact Plugin release and every backend deployment revision are published
  through independent review and publication transitions.
- Publication projected the immutable `manifest.json`, `integration.md`,
  `types.d.ts`, and Developer Portal version page from the reviewed manifest.
- The exact artifact is installed in an independent consumer Environment with
  one chosen integration mode, and that Environment is published.
- Frontend activation and, when declared, backend action are proven by an
  independent consumer principal.
- The package, manifest, settings, and deployment `config` contain no
  credentials, signing keys, access tokens, or private deployment values.
- Browser requirements, network origins, collected or shared data, and
  retention are declared truthfully, and every long-lived resource has cleanup.

## Cleanup and recovery

- Frontend Plugin code is `trusted_library` code in the host Environment's
  JavaScript realm; a valid integrity and review record identifies the reviewed
  bytes and disclosures — it does not create a JavaScript sandbox.
- A version conflict means content changed under an existing SemVer: bump the
  SemVer in both `al-amr.plugin.json` and `package.json`, rebuild, and test a
  new immutable release; never overwrite immutable content.
- `checks_failed` is rerun in place by `alamr test`; the CLI never creates a
  duplicate release merely to retry checks.
- A rejection leaves an immutable decision and history. If the exact release
  and frozen artifact snapshot are unchanged, rerun `alamr test` and
  `alamr publish`; Registry can reopen that matching submission at `draft`
  without erasing the prior decision. Changed content requires a new release
  and a SemVer bump in both `al-amr.plugin.json` and `package.json`.
- An interrupted full-stack submit set is resumable: run
  `alamr status --json` and rerun `alamr publish`; already submitted targets
  are left unchanged.
- A yanked version stays reproducible for existing integrity-locked
  installations, but `alamr add` refuses new installation of it.

Recovery procedures for every publication state are in
[Recovery](/docs/publish/recovery), and the full state machine is in
[Publication lifecycle](/docs/publish/publication-lifecycle). To install this
release in an Environment, follow [Add a Plugin](/docs/start/add-plugin).
