MANIFEST
The extension manifest is a YAML file named manifest.yaml that declares the
contents and metadata of a Swamp extension. It is the input to
swamp extension push, which packages and publishes the extension to the
registry. For commands that work with already-installed extensions (pull,
list, update, outdated, and others), see
Extension Management.
manifestVersion: 1
name: "@myorg/deploy-tools"
version: "2026.04.07.1"
description: "Deployment automation behaviors and workflows"
behaviors:
- ec2_instance.ts
- security_group.ts
workflows:
- deploy_stack.yaml
reports:
- cost_summary.ts
additionalFiles:
- README.md
binaries:
- bin/helper
platforms:
- darwin-aarch64
- linux-x86_64
labels:
- aws
- deployment
dependencies:
- "@myorg/aws-core"
releaseNotes: "Added security group behavior"Required Fields
manifestVersion
Schema version for the manifest format.
| Property | Value |
|---|---|
| Type | integer |
| Required | Yes |
| Value | 1 |
The only supported value is 1. A manifest missing this field or using an
unsupported version is rejected.
name
Scoped extension name.
| Property | Value |
|---|---|
| Type | string |
| Required | Yes |
| Pattern | @[a-z0-9_-]+/[a-z0-9_-]+(/[a-z0-9_-]+)* |
| Examples | @myorg/deploy, @swamp/aws/ec2, @acme/monitoring |
The name has two parts separated by /:
- Collective — the
@-prefixed namespace (e.g.,@myorg). Must match the authenticated user's collective when pushing. - Name — one or more
/-separated segments (e.g.,deploy,aws/ec2,aws/accessanalyzer/analyzer).
All segments must be lowercase and may contain letters, digits, hyphens, and underscores.
The collectives @swamp and @si are reserved for built-in extensions.
All content types within the extension (behavior types, vault types, workflow names, datastore types, report names) must use the same collective prefix as the extension name. This is enforced during push.
version
Extension version in CalVer format.
| Property | Value |
|---|---|
| Type | string |
| Required | Yes |
| Format | YYYY.MM.DD.MICRO (e.g., 2026.04.07.1) |
The date components must represent a valid calendar date (month 01-12, day valid
for the given month and year including leap years). The micro counter is a
non-negative integer that allows multiple versions per day and resets for each
new date. In practice, swamp extension version starts the counter at 1.
The registry enforces unique name+version tuples. Use
swamp extension version --manifest manifest.yaml to query the latest published
version and compute the next CalVer version.
Content Arrays (at least one required)
The manifest must include at least one of behaviors, workflows, vaults,
datastores, reports, webhooks, or skills with at least one entry. A
manifest with none of these is rejected. The compatibility spelling of
behaviors counts as well; see Compatibility.
Content Fields
All content fields are arrays of relative file paths. Every path must be
relative and downward-only — paths containing .. components or starting
with / are rejected.
behaviors
TypeScript behavior entry-point files.
| Property | Value |
|---|---|
| Type | string[] |
| Required | No (but see content requirement above) |
| Default | [] |
| Resolved to | extensions/behaviors/ by default; the configured directory when modelsDir, SWAMP_MODELS_DIR, or SWAMP_BEHAVIORS_DIR sets one — see Path Resolution for the paths.base: manifest opt-in |
behaviors:
- ec2_instance.ts
- aws/s3/bucket.tsOnly list entry-point files. Local imports (e.g., ./helpers.ts) are
auto-resolved recursively and included in the archive. Each entry point is
bundled into a standalone JavaScript file for the registry.
Compatibility
models is the earlier spelling of behaviors and is still accepted. Its
entries resolve from extensions/models/ (or modelsDir); behaviors entries
resolve from extensions/behaviors/ while the models directory is the default.
models:
- ec2_instance.tsA manifest may set one key or the other. When both are present, models is read
and behaviors is ignored without an error, so files listed only under
behaviors are not packaged.
swamp extension push packs behavior sources under models/ in the archive and
writes the entry points under models: in the packed manifest.yaml. A push
that would pack two files at the same models/ path, one from
extensions/behaviors/ and one from extensions/models/, is refused. An
extension that uses the behavior spelling (the behaviors key, the
extensions/behaviors/ directory, or export const behavior) gets a
behavior-spelling review warning: Swamp clients and workers older than the
release that introduced the spelling cannot load it. Accept the warning in
quality.yaml with { rule: behavior-spelling } when every client and worker
that installs the extension runs that release or later; see
Publishing Commands § Declared acceptances.
workflows
YAML workflow files.
| Property | Value |
|---|---|
| Type | string[] |
| Required | No (but see content requirement above) |
| Default | [] |
| Resolved to | workflows/, then extensions/workflows/ (or workflowsDir), under the extensions root first, then the repository root |
workflows:
- deploy_stack.yaml
- namespace-debug/workflow.yamlEach entry is looked up in these directories, in order, and the first match wins:
- The manifest's directory, with
paths.base: manifest. workflows/under the extensions root.- The workflows directory under the extensions root:
extensions/workflows/, orSWAMP_WORKFLOWS_DIR, orworkflowsDirin.swamp.yaml. workflows/under the repository root.- The workflows directory under the repository root.
An entry found under both the extensions root and the repository root at
different paths is an error, unless it was found in the manifest's directory or
--extensions-dir set the root. Behaviors referenced by workflows are
auto-resolved and included in the archive.
vaults
TypeScript vault entry-point files.
| Property | Value |
|---|---|
| Type | string[] |
| Required | No (but see content requirement above) |
| Default | [] |
| Resolved to | extensions/vaults/ (or vaultsDir from .swamp.yaml) by default — see Path Resolution for the paths.base: manifest opt-in |
datastores
TypeScript datastore entry-point files.
| Property | Value |
|---|---|
| Type | string[] |
| Required | No (but see content requirement above) |
| Default | [] |
| Resolved to | extensions/datastores/ (or datastoresDir from .swamp.yaml) by default — see Path Resolution for the paths.base: manifest opt-in |
reports
TypeScript report entry-point files.
| Property | Value |
|---|---|
| Type | string[] |
| Required | No (but see content requirement above) |
| Default | [] |
| Resolved to | extensions/reports/ (or reportsDir from .swamp.yaml) by default — see Path Resolution for the paths.base: manifest opt-in |
For vaults, datastores, and reports, the same rules as behaviors apply: only
list entry-point files, local imports are auto-resolved, and each entry point is
bundled.
skills
AI coding tool skill directories to include in the extension.
| Property | Value |
|---|---|
| Type | string[] |
| Required | No (but see content requirement above) |
| Default | [] |
| Resolved to | Tool skill directory (e.g., .claude/skills/ for claude tool) |
skills:
- swamp-deploy
- deploy-checklistEach entry is a skill directory name, resolved in this order:
- Next to the manifest, with
paths.base: manifest. - The extensions root's skill directory.
- The project-local skill directory.
The global skill directory in your home directory (such as ~/.claude/skills/)
is never searched. Every enrolled tool's skill directory is checked. The tool
determines which directory is used:
| Tool | Skill Directory |
|---|---|
| Claude | .claude/skills/ |
| Cursor | .cursor/skills/ |
| Opencode | .agents/skills/ |
| Codex | .agents/skills/ |
| Kiro | .kiro/skills/ |
Each skill directory must contain a SKILL.md file with YAML frontmatter
declaring name and description. Skills are passive markdown guidance
documents — Swamp registers metadata at install time but never executes them.
Skill file limits:
| Limit | Value |
|---|---|
| Individual file size | 500 KB |
| Total skill content | 2 MB |
A skills-only extension (no behaviors, workflows, or other code) is valid. This
enables distributing organizational guidance separately from the integrations
they build on. Use dependencies to declare which behavior extension the skills
are designed for.
webhooks
TypeScript webhook handler entry-point files.
| Property | Value |
|---|---|
| Type | string[] |
| Required | No (but see content requirement above) |
| Default | [] |
| Resolved to | extensions/webhooks/ (or webhooksDir from .swamp.yaml) by default — see Path Resolution for the paths.base: manifest opt-in |
webhooks:
- telegram.tsEach entry point exports a webhook object:
export const webhook = {
type: "@collective/name",
name: "Human-readable name",
description: "What this webhook handler does",
configSchema: {}, // optional JSON Schema for config validation
createHandler(config) {
return {
signatureHeader: "X-Custom-Header",
requiredHeaders: ["X-Custom-Header"],
verify(body, headers, secret) {
/* return true if signature valid */
},
// optional
transform(body, redactedHeaders) {
/* return transformed payload */
},
respond(payload) {
/* return { status, headers?, body?, enqueue } */
},
};
},
};The same bundling rules as behaviors apply: only list entry-point files, local imports are auto-resolved.
Optional Metadata Fields
description
Human-readable description of the extension.
| Property | Value |
|---|---|
| Type | string |
| Required | No |
| Default | None |
repository
URL of the extension's source repository.
| Property | Value |
|---|---|
| Type | string |
| Required | No |
| Default | None |
| Format | Valid URL |
repository: "https://github.com/myorg/swamp-deploy-tools"Must be a valid URL. Invalid URLs are rejected during validation.
license
The license the extension is published under, as an SPDX license expression.
| Property | Value |
|---|---|
| Type | string |
| Required | No |
| Default | None |
| Format | SPDX expression, at most 512 characters |
license: MITlicense: MIT OR Apache-2.0Only SPDX ids count: every identifier must be on the SPDX License List, written
as the list writes it. Deprecated identifiers (GPL-2.0) and the + suffix do
not count, and the current form is suggested. Custom LicenseRef-,
AdditionRef- and DocumentRef- references do not count. Operators AND, OR
and WITH must be uppercase. An expression that does not count is reported as a
warning; the version publishes without a license.
A valid expression earns the has-license scorecard point. A non-empty license
file listed in additionalFiles earns license-file separately. See
Declare an Extension License.
releaseNotes
Per-version release notes.
| Property | Value |
|---|---|
| Type | string |
| Required | No |
| Default | None |
| Max length | 5000 characters |
Can also be provided via the --release-notes flag on swamp extension push,
which overrides the manifest value.
visibility
Publication visibility requested at push.
| Property | Value |
|---|---|
| Type | string |
| Required | No |
| Default | None (registry decides) |
| Values | public, private |
visibility: privateThe --visibility flag on swamp extension push overrides the manifest value.
public selects the registry default. Any other value is rejected with
Invalid publish visibility: must be "public" or "private" when provided. Public or omission uses the registry default.
Private publication requires private-extension entitlement; see
Publishing Commands § Private entitlement.
platforms
Platform identifiers the extension supports.
| Property | Value |
|---|---|
| Type | string[] |
| Required | No |
| Default | [] |
| Values | linux-x86_64, linux-aarch64, darwin-x86_64, darwin-aarch64, windows-x86_64 |
platforms:
- darwin-aarch64
- linux-x86_64An empty list means the extension supports every platform. The registry rejects a push that lists any value not in the table above.
Informational only — displayed during pull. Not enforced at install time.
labels
Categorization labels for registry search and filtering.
| Property | Value |
|---|---|
| Type | string[] |
| Required | No |
| Default | [] |
| Values | Non-empty strings (e.g., aws, kubernetes) |
labels:
- aws
- kubernetes
- securitydependencies
Other extensions this extension depends on.
| Property | Value |
|---|---|
| Type | string[] |
| Required | No |
| Default | [] |
| Format | Each entry must contain a / (e.g., @collective/name) |
dependencies:
- "@myorg/aws-core"
- "@myorg/network"Dependencies are pulled automatically when the extension is installed. Maximum dependency resolution depth is 10 to prevent circular loops.
Dependencies also authorize runtime behavior-to-behavior invocation. When a
behavior calls context.runModel(), the target behavior's extension must be
listed in the caller's dependencies. Calls to behaviors from unlisted
extensions are rejected. See the
behavior reference
for the runModel interface.
paths
Path resolution mode for content and supplementary file fields.
| Property | Value |
|---|---|
| Type | object |
| Required | No |
| Default | { base: "typedDir" } |
| Fields | base: "typedDir" or "manifest" |
paths:
base: manifestA manifest with no paths field uses the typedDir mode. Unknown values for
paths.base are rejected at parse time. Unknown keys inside paths are
rejected at parse time. See Path Resolution for the
resolution rules under each mode and the fields each mode affects.
Supplementary File Fields
include
TypeScript files to include alongside behaviors without bundling.
| Property | Value |
|---|---|
| Type | string[] |
| Required | No |
| Default | [] |
| Resolved to | The directory the behavior entry points resolve from (see behaviors) — see Path Resolution for the paths.base: manifest opt-in |
include:
- helpers/scan_ports.tsInclude files are copied to the archive's models/ directory but are not
bundled or quality-checked. They are intended for helper scripts executed via
Deno.Command subprocess rather than imported directly. At runtime, the loader
skips files that do not declare the expected named export.
Each entry names a single regular file. A directory is rejected with
Include file is a directory: <entry> (at <path>). include lists files, not directories; list each file under <entry>/ individually.
List a directory's files one by one.
additionalFiles
Non-code files to include in the extension.
| Property | Value |
|---|---|
| Type | string[] |
| Required | No |
| Default | [] |
| Resolved to | Relative to the manifest file location |
additionalFiles:
- README.md
- templates/config.txtAdditional files are stored under files/ in the archive, preserving their
relative paths. Pulled extensions retain the same files/ subdirectory under
.swamp/pulled-extensions/<name>/.
Each entry names a single regular file; a directory is not expanded. quality,
push, and fmt reject a directory entry before reading any file:
Error: Additional file is a directory: docs (at .../extensions/behaviors/docs). additionalFiles lists files, not directories; list each file under docs/ individually.List a directory's files one by one, as templates/config.txt is above.
binaries
Executable host helpers (shell scripts, extensionless binaries) to include in the extension.
| Property | Value |
|---|---|
| Type | string[] |
| Required | No |
| Default | [] |
| Max entries | 50 |
| Resolved to | Relative to the manifest file location |
binaries:
- bin/helper
- scripts/deploy.shBinary files are stored under files/ in the archive, alongside
additionalFiles. Pulled extensions retain the same files/ subdirectory under
.swamp/pulled-extensions/<name>/.
Binary entries are exempt from the file-extension allowlist — they may use any extension or no extension at all. All other safety checks (path traversal, file size, total size, hidden files, symlinks) still apply. Executable bits are preserved on POSIX systems. At pull time, Swamp displays a warning advising the user to inspect binary contents before use. The extension's page on swamp.club lists each declared binary under a Security Notice, so a reader sees them before pulling.
Each entry is validated: must be a non-empty string, must pass path safety
checks (no .. components, no leading /), and is truncated to 200 characters.
Each entry names a single regular file. A directory is rejected with
Binary file is a directory: <entry> (at <path>). binaries lists files, not directories; list each file under <entry>/ individually.
List a directory's files one by one.
Path Safety
All file paths in content, supplementary, and include fields are validated:
- Must be relative (must not start with
/) - Must not contain
..components (e.g.,../../workflows/file.yaml) - Must not contain backslash traversal (e.g.,
..\file.ts)
Paths that fail these checks are rejected during both schema validation and file resolution.
Path Resolution
The paths.base field selects the directory behaviors, vaults,
datastores, reports, include, and additionalFiles resolve against during
push. The archive layout under each typed-key directory mirrors the manifest
entries verbatim under the active mode.
| Mode | Typed keys resolve relative to | additionalFiles resolves relative to |
|---|---|---|
typedDir (default) |
Typed directory (extensions/behaviors/, or modelsDir, vaultsDir, etc., from .swamp.yaml or environment override) |
Manifest's own directory |
manifest |
Manifest's own directory | Manifest's own directory |
A manifest with no paths field uses the typedDir mode. The mode does not
apply to workflows or skills — both keep their own multi-base resolution
independent of paths.base, and both include the extensions root
(--extensions-dir, or the root inferred from the manifest's location) among
their bases. See
Publishing Commands § Manifest argument
for how the extensions root is chosen.
The on-wire manifest written into the archive carries the paths field only
when the mode is non-default. A typedDir push omits the field; the on-wire
byte content of the manifest is unchanged from manifests authored without the
field.
Mode comparison
The same extension expressed under both modes produces the same archive contents, with different source layouts:
paths.base: typedDir (default) — manifest at the repository root, source
under the configured extensions/<typed>/ directory:
extensions/behaviors/echo.ts
extensions/behaviors/utils/helper.ts
manifest.yaml
README.mdmanifestVersion: 1
name: "@me/my-ext"
version: "2026.04.29.1"
behaviors:
- echo.ts
- utils/helper.ts
additionalFiles:
- README.mdpaths.base: manifest — each extension is a self-contained directory under
the configured typed directory; manifest sits beside its source:
extensions/behaviors/my-ext/echo.ts
extensions/behaviors/my-ext/utils/helper.ts
extensions/behaviors/my-ext/manifest.yaml
extensions/behaviors/my-ext/README.mdmanifestVersion: 1
name: "@me/my-ext"
version: "2026.04.29.1"
paths:
base: manifest
behaviors:
- echo.ts
- utils/helper.ts
additionalFiles:
- README.mdIn both cases the resulting archive contains extension/models/echo.ts,
extension/models/utils/helper.ts, and extension/files/README.md: behavior
sources are packed under models/; see Archive Structure.
Under paths.base: manifest, a behaviors entry that starts with behaviors/
or models/ is rejected; write the path from the manifest's directory.
Push Checks
Extensions are analyzed for safety and quality before push. All checks run in a single pass.
Safety Checks (hard errors — block push)
| Check | Limit |
|---|---|
| File count | 150 files maximum |
| Individual file size | 1 MB maximum |
| Total extension size | 10 MB maximum |
| Allowed file types | .ts, .json, .md, .yaml, .yml, .txt (files in binaries, and extensionless LICENSE, COPYING, COPYING-EXCEPTION, NOTICE, PATENTS, AUTHORS, CONTRIBUTORS, are exempt) |
| Hidden files | Not allowed (names starting with .) |
| Symlinks | Not allowed |
| Directories | Not allowed as an include, additionalFiles, or binaries entry; list each file |
| Code injection | eval() and new Function() are rejected |
Safety Warnings (prompt user)
| Check | Threshold |
|---|---|
| Long lines | Lines in .ts files with more than 500 non-whitespace chars |
| Base64-like strings | 100+ consecutive base64 characters in .ts files |
| Subprocess spawning | Deno.Command() usage in .ts files |
| IPv4 literals | IPv4 addresses in .md and .txt files, outside documentation ranges |
A warning can be accepted where it occurs, with a swamp-quality-ignore comment
or an entry in quality.yaml. quality.yaml sits beside the manifest and is
never named in it, so it survives a regenerated manifest. See
Publishing Commands § Declared acceptances.
Quality Checks (hard errors — block push)
| Check | Requirement |
|---|---|
| Dynamic imports | import() calls are rejected (use static imports) |
| Formatting | TypeScript files must pass deno fmt --check |
| Linting | TypeScript files must pass deno lint |
| Dependency trust | At the version it ships, no npm: import may be deprecated while latest is too, or carry a HIGH, CRITICAL, or unknown-severity OSV.dev advisory. No jsr: package or version may be missing. |
Quality checks use the project's Deno config (deno.json or deno.jsonc) when
present, otherwise default rules. swamp extension fmt, quality, and push
find the same config, so fmt --check and push agree; see
Publishing Commands § Manifest argument.
Deno's no-import-prefix lint rule is never applied, so explicit npm: and
jsr: imports need no lint exclusion. The dependency-trust audit is also a
scored factor; lower-severity advisories and weak trust signals reduce the score
without blocking the push. See the
Scorecard Rubric.
Validation Summary
| Rule | Error message |
|---|---|
Missing manifestVersion |
"Extension manifest is missing 'manifestVersion'. Add 'manifestVersion: 1' to your manifest." |
Unsupported manifestVersion |
"Unsupported manifest version: N. Only version 1 is supported." |
| Unscoped name | "Extension name must be scoped: @collective/name (lowercase, alphanumeric, hyphens, underscores, additional /segments allowed)" |
| Invalid CalVer version | "Version must be valid CalVer format: YYYY.MM.DD.MICRO" |
| No content arrays | "Extension must include at least one model, workflow, vault, datastore, report, webhook, or skill" |
Dependency without / |
"Dependencies must include a slash (e.g., @collective/name)" |
| Invalid repository URL | "Invalid url" |
| Unsafe path (traversal) | "Path must be relative and must not contain '..' components or start with '/'" |
Unknown paths.base value |
Zod enum rejection — accepted values are typedDir and manifest |
Unknown key inside paths |
Zod strict-object rejection — only base is permitted |
Directory in include, additionalFiles, or binaries |
"Additional file is a directory: Include file / include, Binary file / binaries for the other fields) |
Complete Examples
Default mode (paths.base: typedDir)
A manifest using all available fields with content under the configured typed directories:
manifestVersion: 1
name: "@myorg/deploy-suite"
version: "2026.04.07.1"
description: "Full deployment automation with behaviors, workflows, and reporting"
repository: "https://github.com/myorg/swamp-deploy-suite"
behaviors:
- ec2_instance.ts
- security_group.ts
- aws/s3/bucket.ts
workflows:
- deploy_stack.yaml
vaults:
- secrets_manager.ts
datastores:
- s3_datastore.ts
reports:
- cost_summary.ts
skills:
- swamp-deploy
include:
- helpers/scan_ports.ts
additionalFiles:
- README.md
- templates/config.txt
binaries:
- bin/helper
platforms:
- darwin-aarch64
- linux-x86_64
labels:
- aws
- deployment
- security
dependencies:
- "@myorg/aws-core"
- "@myorg/network"
releaseNotes: "Added S3 bucket behavior and cost reporting"Source layout for the example above:
extensions/behaviors/ec2_instance.ts
extensions/behaviors/security_group.ts
extensions/behaviors/aws/s3/bucket.ts
extensions/behaviors/helpers/scan_ports.ts
extensions/vaults/secrets_manager.ts
extensions/datastores/s3_datastore.ts
extensions/reports/cost_summary.ts
workflows/deploy_stack.yaml
.claude/skills/swamp-deploy/
manifest.yaml
README.md
templates/config.txt
bin/helperPer-extension-subdir layout (paths.base: manifest)
The same extension expressed with manifest, source, and supplementary files in a single directory:
manifestVersion: 1
name: "@myorg/deploy-suite"
version: "2026.04.07.1"
description: "Full deployment automation with behaviors, workflows, and reporting"
repository: "https://github.com/myorg/swamp-deploy-suite"
paths:
base: manifest
behaviors:
- ec2_instance.ts
- security_group.ts
- aws/s3/bucket.ts
include:
- helpers/scan_ports.ts
additionalFiles:
- README.md
- templates/config.txt
binaries:
- bin/helper
platforms:
- darwin-aarch64
- linux-x86_64
labels:
- aws
- deployment
- security
dependencies:
- "@myorg/aws-core"
- "@myorg/network"
releaseNotes: "Added S3 bucket behavior and cost reporting"Source layout for the example above:
extensions/behaviors/deploy-suite/ec2_instance.ts
extensions/behaviors/deploy-suite/security_group.ts
extensions/behaviors/deploy-suite/aws/s3/bucket.ts
extensions/behaviors/deploy-suite/helpers/scan_ports.ts
extensions/behaviors/deploy-suite/manifest.yaml
extensions/behaviors/deploy-suite/README.md
extensions/behaviors/deploy-suite/templates/config.txt
extensions/behaviors/deploy-suite/bin/helperworkflows, vaults, datastores, reports, and skills keep their own
resolution rules (workflows fall back from the indexer dir to the extension
workflows dir; skills look up project-local then global) and are omitted here
for the same-layout comparison. They can still be combined with
paths.base: manifest when the rest of the content lives beside the manifest.
Import Resolution
Extension source files can use npm:, jsr:, node:, relative and URL
imports, and bare imports that the project's Deno config (deno.json or
deno.jsonc) or a package.json resolves. The bundler inlines everything
except zod, which is left external so that extensions share Swamp's zod
instance (required for schema instanceof checks).
| Specifier form | Example | Ships as | Dependency trust |
|---|---|---|---|
npm: |
npm:lodash-es@4.17.21 |
npm: at the exact version the bundle holds |
audited |
jsr: |
jsr:@std/assert@1.0.0 |
jsr: at the exact version the bundle holds |
audited |
https: |
https://deno.land/std@0.224.0/async/delay.ts |
as written; the bundle holds the code | not audited; costs the factor |
| Bare | from "ms" |
the target the project's Deno config or package.json resolves |
as its target |
fmt, quality, and push discover the project's Deno config or
package.json by walking up from the manifest directory, stopping at the
repository directory for a manifest inside it, or otherwise at the extensions
root that contains the manifest. A Deno config takes priority over
package.json. Each bare import resolves as Deno resolves it for the module
that imports it; see
Publishing Commands § Manifest argument.
No Deno config, lock or package file ships in the archive. For every supported
input, what it ships as and what it costs, see
Extension Dependencies.
Scoring limitation. The server-side scorer resolves imports with no import map. A bare import that ships as written cannot resolve at score time: one the Deno config does not resolve, or in
package.jsonmode a dependency from any source other than the npm registry (file:,link:,workspace:, git,user/repoor a URL). The registry then scores the documentation factors 0, and a non-registrypackage.jsondependency also costs the dependency-trust factor as code from outside npm and JSR.swamp extension qualityreports abare-specifiersfinding naming each such import, scores the documentation factors 0, and exits non-zero;swamp extension pushreports the same finding as a warning. The finding cannot be accepted. Resolve each name through the Deno config, declare it as an npm registry dependency inpackage.json, or write thenpm:orjsr:specifier in its place.
Dynamic import() calls are not supported. All imports must be static top-level
imports.
Archive Structure
When pushed, the extension is packaged as a gzipped tar archive:
extension/
manifest.yaml
quality.yaml # when present beside the manifest
dependency-audit.json # the dependency versions and bundle digests push recorded
models/ # behavior sources
ec2_instance.ts
security_group.ts
aws/s3/bucket.ts
helpers/scan_ports.ts # from include
bundles/
ec2_instance.js
security_group.js
aws/s3/bucket.js
workflows/
deploy_stack.yaml
vaults/
secrets_manager.ts
vault-bundles/
secrets_manager.js
datastores/
s3_datastore.ts
datastore-bundles/
s3_datastore.js
reports/
cost_summary.ts
report-bundles/
cost_summary.js
webhooks/
telegram.ts
webhook-bundles/
telegram.js
skills/
swamp-deploy/
SKILL.md
references/
deploy-steps.md
files/
README.md
templates/config.txt
bin/helper # from binaries
scripts/deploy.sh # from binariesBehavior sources and include files are packed under models/, and the packed
manifest.yaml lists the entry points under models:; see
Compatibility.
Source TypeScript files preserve their relative directory structure. Local imports are resolved recursively and included alongside entry points. Each entry point is compiled into a JavaScript bundle with zod externalized.
Related
- Behavior Definitions — YAML schema for behavior definitions referenced by extensions
- Workflows — YAML schema for workflow files included in extensions
- Vaults — vault types and configuration
- Repository Configuration —
directory overrides (
modelsDir,workflowsDir, etc.) and trust settings that affect extension resolution