# Development lifecycle

Create, build, validate, package, migrate, and install plugins outside
Thortiq. Keep every scaffold and build directory outside all vaults. The app
never runs a package manager, project script, compiler, archive hook, or
developer build.

## Scaffold

The downloaded developer kit is the self-contained bootstrap path. From the
extracted `thortiq-plugin-kit` directory:

```sh
node bootstrap.mjs \
  --name my-plugin \
  --template vanilla \
  ./my-plugin
```

This runs the exact bundled scaffolder and vendors the required Thortiq
packages into the generated project. Use `--skip-install` when dependency
installation must happen later. If `create-thortiq-plugin@1.0.0` and
the matching `@thortiq/*` packages are available from your configured npm
registry, the equivalent registry command is:

```sh
npm create thortiq-plugin@1.0.0 -- \
  --name my-plugin \
  --template vanilla \
  ./my-plugin
```

Do not assume the registry route is available; the downloaded kit remains the
version-pinned fallback.

Settings → Plugins → Developer mode displays compatible API/tool versions,
the kit download, the bundled bootstrap command, and this manual. It is a
device-local, off-by-default diagnostics preference, not a development host.

## Validate and package

Run the generated project scripts, then use the external CLI on prebuilt
output:

```sh
npm run validate
npm test
npm run typecheck
npm run build
npx thortiq-plugin validate ./dist
npx thortiq-plugin test ./dist
npx thortiq-plugin package ./dist --out ../plugin.thortiq-plugin
npx thortiq-plugin signing-payload ../plugin.thortiq-plugin --metadata ./signing-draft.json --out ./signing-payload.json
npx thortiq-plugin verify-signature ../plugin.thortiq-plugin --metadata ./signed-package.json --trust-store ./publisher-keys.json
```

The CLI never executes the plugin or accepts a publisher private key.
Generated projects created by `bootstrap.mjs` use the exact CLI tarball carried
in the kit, so `npx` does not need to download `@thortiq/plugin-cli`.

## Install

Install into a canonical vault root containing `.thortiq`:

```sh
npx thortiq-plugin install ../plugin.thortiq-plugin --vault "/path/to/vault"
```

`--replace` is required when the validated manifest ID already exists. The CLI
validates before writing, derives the destination from that ID, rejects
symlinks and traversal, stages on the vault filesystem, commits
`manifest.json` last, and restores the previous package if replacement fails.

Manual installation may copy validated files to
`.thortiq/plugins/<plugin-id>/`; copy `manifest.json` last. `pages/` is not a
plugin discovery path.

Use this command to relocate an existing manifest-v2 or live package:

```sh
npx thortiq-plugin migrate plugin-id --vault "/path/to/vault"
```

Destination collisions are refused. Legacy unversioned plugins must be
upgraded externally before migration.

The archive commands above apply to packaged `native` and `sandboxed-page`
plugins. `live-sandboxed` is a managed source-bundle lifecycle; the external
live template is useful for source authoring and tests but is not installable
through the packaged-plugin archive command.

## Runtime approval and recovery

Install, trust, origin approval, enablement, and execution remain separate.
Changed bytes require fresh device-local approval. The app automatically keeps
and uses its internal last-known-good runtime generation, but does not expose
package update history or user-selected rollback.

Settings exposes installed-plugin settings and app-owned trust, recovery,
secret, data-removal, and uninstall controls. Developer mode adds only bounded,
redacted diagnostics, rescan/retry, compatible versions, this manual, and the
pinned scaffold command.

See [security.md](security.md) for runtime trust and
[packaging.md](packaging.md) for the closed installed payload.
