Skip to main content

PUBLISHING COMMANDS

swamp provides three commands for releasing an extension: fmt formats and lints the source, quality scores it against the rubric, and push validates and uploads it. All three take a manifest path and resolve the files it references. For the consumer-side commands (pull, install, list, search, update, outdated, rm, version), see Management.

All three commands accept the global flags --json, --log, --quiet, --verbose, --no-color, --no-telemetry, and --log-level <level>. The command-specific flags are listed below.

fmt

Formats and lints the TypeScript files referenced by the manifest. Resolves each model, vault, driver, datastore, and report entry point plus its local imports, then runs deno fmt and deno lint --fix over them.

Flags

Flag Description
--check Check only; do not auto-fix. Exits non-zero on issues.
--repo-dir <dir> Repository directory (env: SWAMP_REPO_DIR).
--extensions-dir <dir> Extensions source directory (env: SWAMP_EXTENSIONS_DIR).

Output

info    extension·fmt        Formatted 1 TypeScript files.
info    extension·fmt        Checked 1 file

In --check mode, with nothing to fix:

info    extension·fmt        All quality checks passed.

Unfixable lint issues are reported and the command exits non-zero. push runs the equivalent of --check before uploading and is blocked if it fails.

quality

Packages the extension, scores it against the quality rubric, and writes the packaged tarball to .swamp/cache/packages/<hash>/ for reuse by push. Scoring does not gate publishing — the score is informational — but the packaging step runs the safety and dependency-trust checks, so an extension with a hard error fails here before producing a score.

Flags

Flag Description
--repo-dir <dir> Repository directory (env: SWAMP_REPO_DIR).

Output

info    extension·quality    Packaging extension for quality scoring...
info    extension·quality    Scoring extension against Swamp Club quality rubric...
info    extension·quality    Rubric v3 — 14/14 points (100%, "all factors earned")
info    extension·quality      "✓" "has-readme" ["2/2"] — "Has README or module doc"
info    extension·quality      "✓" "readme-example" ["1/1"] — "README has a code example"
info    extension·quality      "✓" "rich-readme" ["1/1"] — "README is substantive"
info    extension·quality      "✓" "symbols-docs" ["1/1"] — "Most symbols documented"
info    extension·quality      "✓" "fast-check" ["1/1"] — "No slow types"
info    extension·quality      "✓" "description" ["1/1"] — "Has description"
info    extension·quality      "✓" "platforms" ["2/2"] — "Platform support declared (or universal)"
info    extension·quality      "✓" "has-license" ["1/1"] — "License declared"
info    extension·quality      "✓" "repository-verified" ["2/2"] — "Verified public repository (server confirms on publish)"
info    extension·quality      "✓" "dependency-trust" ["2/2"] — "Dependencies pass trust gates"
info    extension·quality          No npm/jsr dependencies to audit
info    extension·quality    Packaged archive: 3563 bytes

repository-verified is earned locally when the URL is well-formed and on an allowlisted host. The registry performs the final public-reachability check at publish time. See the Scorecard Rubric for every factor and its points.

push

Validates and uploads the extension to the registry. Without --dry-run, the upload is a three-phase exchange: initiate, upload archive, confirm.

Flags

Flag Description
--dry-run Build and validate the archive locally; do not upload.
-y, --yes Skip confirmation prompts.
--release-notes <text> Per-version release notes (max 5000 chars).
--repo-dir <dir> Repository directory (env: SWAMP_REPO_DIR).
--extensions-dir <dir> Extensions source directory (env: SWAMP_EXTENSIONS_DIR).

Stages

  1. Parse the manifest and validate required fields.
  2. Validate the collective against the authenticated account.
  3. Resolve model entry points and their local imports.
  4. Detect the project's deno.json (or package.json) for bundling.
  5. Resolve include helper files.
  6. Run the safety analysis over all files.
  7. Run the formatting and dependency-trust checks.
  8. Bundle each entry point to standalone JavaScript.
  9. Verify the version does not already exist.
  10. Build the tar.gz archive.
  11. Upload (initiate, upload, confirm) — skipped under --dry-run.

Output (dry run)

info    extension·push       Extension: "@stack72/text-entropy"@"2026.05.31.1"
info    extension·push       Description: "Measure the Shannon entropy of a piece of text"
info    extension·push       Repository: "https://github.com/stack72/text-entropy"
info    extension·push       Models (1):
info    extension·push         "@stack72/text-entropy" ("extensions/models/text_entropy.ts")
info    extension·push       Additional files (2):
info    extension·push         "extensions/models/README.md"
info    extension·push         "extensions/models/LICENSE.md"
info    extension·push       Labels: "text, analysis"
info    extension·push       Dry run complete for "@stack72/text-entropy"@"2026.05.31.1"
info    extension·push       Archive size: "3.5KB"
info    extension·push       No API calls were made.

Blocking errors

The push is refused when any of the following is found. The safety and dependency-trust checks also run during quality.

Safety errors (see Manifest § Push Checks for the full table): eval() or new Function(), symlinks, hidden files, disallowed file extensions, files over 1 MB, total size over 10 MB, more than 150 files.

A file with no extension is rejected — only .ts, .json, .md, .yaml, .yml, and .txt are allowed (the binaries field is exempt). A license file must therefore be named LICENSE.md or LICENSE.txt, not bare LICENSE:

ERR extension·push Safety errors (push blocked):
ERR extension·push   ".../LICENSE": 'File extension "" is not allowed. Allowed: .ts, .json, .md, .yaml, .yml, .txt'

Dependency-trust errors: any npm: import that is deprecated, or carries a HIGH, CRITICAL, or unknown-severity OSV.dev advisory, blocks the push:

ERR extension·push Dependency trust errors (push blocked):
ERR extension·push   "lodash": "vulnerability GHSA-jf85-cpcp-j695 (CRITICAL)"
ERR extension·push   "lodash": "vulnerability GHSA-35jh-r3h4-6jhm (HIGH)"

Lower-severity advisories, unusual licenses, and low download counts reduce the dependency-trust score but do not block the push. jsr: imports are not audited. See the Scorecard Rubric § Dependency trust audit.

Safety warnings

Subprocess spawning (Deno.Command()), lines with 500+ non-whitespace characters, and base64-looking blobs are warnings, not errors: the push prompts for confirmation. Pass -y to accept them non-interactively.