tucan studio

Docs / Developer documentation

Browse topics
On this page

registry-cli — browse and publish Tucan extensions

A console tool for publishing extensions and looking at what the extension registry (https://tucan.amlang.net) is actually serving while you develop extensions. Not used by am-ide — the IDE has its own in-process client — but it reuses the IDE's registry parsers from modules/extensions, so the two can't drift out of step. Same arrangement aminet-cli has with the aminet module.

Build

make            # macos-arm
make build-linux
make build-amigaos
make build-morphos

The binary lands in builds/bin/<platform>/app.

Use

registry-cli list                                  published extensions
registry-cli versions <id> [page]                  releases, newest first
registry-cli info <id> [version]                   one release in full
registry-cli download <id> <ver> <platform> [name] [dest]
registry-cli console                               browse without retyping ids

--json          one machine-readable document instead of text
--url <base>    registry to talk to (or set TUCAN_REGISTRY_URL)

info with no version shows the latest. download with no resource name fetches every registry-hosted resource for that platform — what installing the release would pull. aminet and url resources are listed but skipped with a note saying where they actually live, because /r/<name> serves only files the registry hosts.

A dest ending in / (or : on AmigaOS) is treated as a directory.

Console mode

> l                     list published extensions
> 3                     details of listed extension #3 (latest release)
> v 3                   its versions
> i 3 1.0.0             a specific release
> d 3 amigaos           download its resources for a platform
> q

Numbers refer to the last l listing; an id works anywhere a number does.

Create and publish extensions

The authoring commands use the same registry as the browser. All are native AmLang; only archive creation invokes an external zip or lha tool on PATH.

# Create/update the identity only, from extension.json.
registry-cli create ./my-extension --token "$TUCAN_ACCESS_TOKEN"

# Build archives locally without authentication or registry requests.
registry-cli build ./my-extension

# Create/update a version and upload its archives (identity must already exist).
registry-cli create-version ./my-extension --token "$TUCAN_ACCESS_TOKEN"

# Build, create/update identity, create/update version, and upload all archives.
registry-cli publish ./my-extension --username my-user --password "$TUCAN_PASSWORD"

# Obtain an access token explicitly; prints only the token (JSON with --json).
registry-cli login --username my-user --password "$TUCAN_PASSWORD"

The folder defaults to the current directory. TUCAN_ACCESS_TOKEN, TUCAN_USERNAME, and TUCAN_PASSWORD can supply authentication without command line flags. Flags override their matching environment variables. A supplied access token takes precedence over username/password except for login, which always requests a new token. Credentials are not saved locally. login prints its access token intentionally; other commands never print credentials. Use HTTPS; plain HTTP is supported only for a localhost test registry.

The input layout is:

my-extension/
  extension.json
  version.json
  shared/                   scripts, forms, data
  platforms/
    amigaos/                platform-specific files
    macos-arm/

Minimal extension.json:

{"localName":"my-extension","name":"My extension","description":"Example"}

Example version.json:

{
  "version": "1.0.0",
  "releaseNotes": "First release",
  "permissions": ["system.execute"],
  "path": ["bin"],
  "menuItems": [{"name":"Run", "command":"my-tool"}],
  "resources": [
    {"source":"registry", "platform":"amigaos", "name":"my-extension-amigaos.lha", "format":"lha"},
    {"source":"registry", "platform":"macos-arm", "name":"my-extension-macos-arm.zip", "format":"zip"}
  ]
}

version.json.resources selects the platforms, archive names, and formats. Declare one registry archive per platform with distinct names and an empty or omitted folder. Supported generated formats are zip and lha (LH5); the format can also be inferred from .zip or .lha. Existing aminet and url resources remain in the version metadata and do not cause local uploads. Names, platforms and version identifiers accept letters, digits, -, _, ., and +; path separators and traversal identifiers are rejected.

For each registry resource, the builder copies the contents of shared/, then overlays platforms/<platform>/. A missing platform folder uses shared files alone, allowing script-only extensions. At least one source folder must exist. Symlinks are rejected. It adds an extension.json combining the identity with release behavior; fields in version.json take precedence for menus, permissions, and other release metadata. Executable file permissions survive staging. Archives contain the installed files directly, without a wrapper folder. File/directory type conflicts fail the build.

Every build uses a fresh .registry-build-…-files/ directory inside the source folder. Its path is returned (output in JSON). It contains staging trees and archives and is retained for inspection; add .registry-build-* to your extension's .gitignore. Existing dist/ is not used. Old files cannot leak from one build into another.

All archives are built before any registry writes. Publishing stops at the first failure and returns exit status 1 (--json returns an error object). Uploads use raw archive bytes and application/octet-stream. If an upload fails, the version and any earlier uploads remain on the registry; rerun the same command to retry. Reposting a version replaces its resource declarations, so retain the complete resource list in version.json. Successful publishing stages the release; registry approval remains a separate administrator action.

API references: extension registry and login.

Integration tests

After building on macOS ARM:

python3 tests/publishing.py

The tests start a localhost mock registry and use temporary extension folders; no live account is needed. Set REGISTRY_CLI to test another host binary. The LHA test is skipped if lha is unavailable.

Studio integration can pass --account-file /path/to/config/account.json. This reads the saved access token and checks expiresAt (epoch milliseconds), overrides other token sources, and is restricted to https://tucan.amlang.net. It cannot be used with login. Extension DevTools obtains this command through studio.account.registryCommand(action, folder) and runs it in the task window; the command contains the file path, not the token.

From the Tucan Studio documentation: modules/registry-cli/README.md