Version: 0.1.0-draft Date: 2026-02-05
- Vision & Goals
- Core Concepts
- Package Format
- Artifact Definitions
- CLI Design
- Registry Design
- Dependency Resolution
- Platform Adapters
- Configuration
- File Layout
- Architecture
- Example Walkthrough
- Roadmap
AAM (Agent Artifact Manager) is a package manager for AI agent artifacts. It manages the lifecycle of prompts, agents, instructions, and skills β packaging them into distributable units with dependency resolution and multi-platform deployment.
Think of it as pip/npm for AI agent configurations, but simpler and purpose-built.
AI practitioners create reusable artifacts (skills, prompts, agent configurations, instructions) for platforms like Cursor, GitHub Copilot, Claude, and OpenAI Codex. Currently:
- No standard way to package these artifacts for distribution
- No dependency management between artifacts (e.g., an agent that requires a skill)
- No cross-platform deployment β each platform has its own directory structure and format
- No registry for discovering and sharing agent artifacts
| Priority | Goal |
|---|---|
| P0 | Simple CLI: aam install <package> installs artifacts + dependencies |
| P0 | Multi-platform deployment (Cursor, Copilot, Claude, Codex) |
| P0 | Dependency resolution between packages |
| P1 | Git-based registry for package discovery and distribution |
| P1 | aam pkg init / aam pkg publish workflow for package authors |
| P1 | Namespace/scope support (@author/package-name) |
| P2 | Version pinning and lock files |
- GUI or web interface
- Binary artifact support (images, models)
- Runtime execution of agents (AAM is purely a packaging/deployment tool)
- Paid registry or access control (use private git repos instead)
AAM manages four artifact types:
| Type | Description | Example |
|---|---|---|
| skill | A workflow/capability package β SKILL.md with optional scripts, references, assets | asvc-report β generates ASVC audit reports |
| agent | An AI agent definition β system prompt, personality, tool config, skill references | asvc-audit β an agent configured for ASVC auditing |
| prompt | A reusable prompt template with optional variables | audit-finding-prompt β structured prompt for audit findings |
| instruction | Platform-specific rules, conventions, or guidelines | python-standards β coding rules for Python projects |
A package is a distributable unit that bundles one or more artifacts together. Every package has:
- A manifest (
aam.yaml) describing contents, metadata, and dependencies - Artifact files organized by type
- An optional lock file (
aam-lock.yaml) for reproducible installs
A registry is a storage backend where packages are published and discovered. AAM supports:
- Git registry β a Git repository with a defined directory structure (simple, no server needed)
- Local registry β a local directory for offline/private use
- HTTP registry β a REST API-based registry (see HTTP_REGISTRY_SPEC.md)
The default registry (aam-central) uses the git backend. Organizations can run their own HTTP registry (aam-central or custom) for advanced features like user authentication, package signing verification, and download statistics.
A platform is a target AI tool where artifacts get deployed. Each platform has a specific directory structure and file format. AAM uses platform adapters to translate abstract artifacts into platform-specific configurations.
A workspace is a project directory where AAM operates. It contains:
.aam/β local AAM state (installed packages, config)aam.yamlβ project-level manifest (optional, for projects that are themselves packages)
AAM follows a local-first architecture. The CLI is fully functional without any server-side infrastructure. All core operations β create, validate, pack, publish, search, install, deploy β work against local file-based registries. The HTTP registry (aam-backend) adds collaboration features (auth, signing verification, download stats, governance approvals) but is never required for the core packaging workflow.
This means:
- A single developer can try AAM in under 5 minutes with zero infrastructure
- Teams can share packages via a shared filesystem, NFS, or a git-synced directory
- The HTTP registry is an optional upgrade, not a prerequisite
- The CLI has zero required network dependencies;
httpxis only imported when an HTTP registry is configured
The manifest is the heart of every package. It uses YAML for readability.
# aam.yaml β Package Manifest
name: "@author/asvc-auditor" # Scoped package name (@scope/name format)
version: 1.0.0
description: "ASVC audit agent with reporting skill and prompts"
author: author
license: Apache-2.0
repository: https://github.com/spazy/asvc-auditor
# Artifact declarations β what this package provides
artifacts:
agents:
- name: asvc-audit
path: agents/asvc-audit/
description: "Agent configured for ASVC compliance auditing"
skills:
- name: asvc-report
path: skills/asvc-report/
description: "Skill for generating ASVC audit reports"
prompts:
- name: audit-finding
path: prompts/audit-finding.md
description: "Structured prompt for documenting audit findings"
- name: audit-summary
path: prompts/audit-summary.md
description: "Prompt for generating executive audit summaries"
instructions:
- name: asvc-coding-standards
path: instructions/asvc-coding-standards.md
description: "Coding standards for ASVC-compliant projects"
# Dependencies β other AAM packages this package requires
# Both scoped (@scope/name) and unscoped (name) dependencies are supported
dependencies:
"@author/generic-auditor": ">=1.0.0"
report-templates: "^2.0.0"
# Platform-specific deployment configuration
platforms:
cursor:
skill_scope: project # "project" (.cursor/skills/) or "user" (~/.cursor/skills/)
deploy_instructions_as: rules # deploy instructions as .mdc rules
copilot:
merge_instructions: true # merge all instructions into copilot-instructions.md
claude:
merge_instructions: true # merge into CLAUDE.md
codex:
skill_scope: user # deploy to ~/.codex/skills/
# Optional: keywords for registry search
keywords:
- audit
- asvc
- compliance
- reporting# Required fields
name: string # ^(@[a-z0-9][a-z0-9_-]{0,63}/)?[a-z0-9][a-z0-9-]{0,63}$
# Unscoped: "my-package" or scoped: "@author/my-package"
version: string # semver: MAJOR.MINOR.PATCH
description: string # max 256 chars
# Optional metadata
author: string
license: string # SPDX identifier
repository: string # URL (source code)
homepage: string # URL (project homepage, docs, etc.)
keywords: list[string]
# Artifact declarations (at least one artifact required)
artifacts:
agents: list[ArtifactRef]
skills: list[ArtifactRef]
prompts: list[ArtifactRef]
instructions: list[ArtifactRef]
# ArtifactRef schema:
# name: string β artifact identifier (required)
# path: string β relative path within the package (required)
# description: string β what this artifact does (required)
# Dependencies (optional)
dependencies:
<package-name>: <version-constraint>
# Version constraints:
# "1.0.0" β exact version
# ">=1.0.0" β minimum version
# "^1.0.0" β compatible (>=1.0.0 <2.0.0)
# "~1.0.0" β approximate (>=1.0.0 <1.1.0)
# "*" β any version
# Platform configuration (optional β defaults applied if omitted)
platforms:
cursor: CursorConfig
copilot: CopilotConfig
claude: ClaudeConfig
codex: CodexConfig
# Quality: tests and evals (optional)
quality:
tests:
- name: string # test name (e.g., "unit-tests")
command: string # shell command to run (e.g., "pytest tests/")
description: string # what this test verifies
evals:
- name: string # eval name (e.g., "accuracy-eval")
path: string # path to eval definition file
description: string # what this eval measures
metrics:
- name: string # metric name (e.g., "accuracy")
type: string # percentage, score, duration_ms, booleanasvc-auditor/
βββ aam.yaml # Package manifest
βββ agents/
β βββ asvc-audit/
β βββ agent.yaml # Agent definition
β βββ system-prompt.md # Agent system prompt
βββ skills/
β βββ asvc-report/
β βββ SKILL.md # Skill definition
β βββ scripts/
β β βββ generate_report.py
β βββ references/
β βββ asvc-framework.md
βββ prompts/
β βββ audit-finding.md
β βββ audit-summary.md
βββ instructions/
βββ asvc-coding-standards.md
Packages are distributed as .aam files (gzipped tar archives):
asvc-auditor-1.0.0.aam
The archive contains the full package directory. This mirrors the .skill format from Codex but is generalized for all artifact types.
Archive constraints:
- Maximum size: 50 MB (enforced by
aam pkg packand registry upload) - Must contain
aam.yamlat root - No symlinks outside package directory
- No absolute paths
Dist-tags are named aliases for package versions, enabling aam install @org/agent@stable or org-specific gates like bank-approved.
| Tag | Behavior |
|---|---|
latest |
Automatically set to the newest published version on each aam pkg publish |
stable |
Opt-in; set manually via aam dist-tag add or aam pkg publish --tag stable |
Organizations can define arbitrary tags (e.g., staging, bank-approved, qa-passed).
Tag rules:
- Lowercase alphanumeric + hyphens only
- Max 32 characters
- Cannot be a valid semver string (prevents ambiguity with version specifiers)
# Publish and tag in one step
aam pkg publish --tag beta
# Manage tags after publish
aam dist-tag add @org/agent@1.2.0 stable
aam dist-tag rm @org/agent stable
aam dist-tag ls @org/agent
# Install using a tag
aam install @org/agent@stableWhen aam install @org/agent@stable is invoked:
- Look up the
stabletag in the package metadata (eithermetadata.yamlfor local registries or the API for HTTP registries) - Resolve the tag to a concrete version (e.g.,
1.2.0) - Proceed with normal version resolution and install
Dist-tags are stored in metadata.yaml per-package (see Section 6.2). The aam dist-tag commands update metadata.yaml directly for local registries, or call the API for HTTP registries. This means aam install @org/agent@stable works fully offline.
A portable bundle is a self-contained, pre-compiled archive for a specific target platform. It contains all artifacts already transformed and ready to deploy, with no dependency resolution needed.
Why bundles exist: Not everyone will use the registry from day one. Portable bundles enable manual sharing (Slack, email, git) of pre-compiled artifacts β a critical on-ramp for adoption.
Building bundles:
aam pkg build --target cursor
# Produces: dist/my-package-1.0.0-cursor.bundle.aam
aam pkg build --target copilot
# Produces: dist/my-package-1.0.0-copilot.bundle.aam
aam pkg build --target all
# Produces one bundle per configured platformBundle structure (tar.gz internally):
my-package-1.0.0-cursor.bundle.aam
βββ bundle.json # Bundle manifest (target, platform version, checksums)
βββ .cursor/
β βββ skills/... # Pre-compiled platform-specific artifacts
β βββ rules/...
β βββ prompts/...
βββ aam.yaml # Original manifest for reference
bundle.json schema:
{
"format": "aam-bundle",
"version": "1.0",
"package": "@author/my-agent",
"package_version": "1.2.0",
"target": "cursor",
"built_at": "2026-02-07T14:30:00Z",
"checksum": "sha256:...",
"artifacts": [
{"type": "skill", "name": "my-skill", "path": ".cursor/skills/author--my-skill/"},
{"type": "agent", "name": "my-agent", "path": ".cursor/rules/agent-author--my-agent.mdc"}
]
}Installing from a bundle:
# Install directly from a bundle file β deploys immediately, no resolution needed
aam install ./dist/my-package-1.0.0-cursor.bundle.aamSkills follow the established SKILL.md convention used by Cursor and Codex.
Directory structure:
skills/<skill-name>/
βββ SKILL.md # Required β frontmatter + instructions
βββ scripts/ # Optional β executable scripts
βββ templates/ # Optional β output templates (Jinja2 .j2 files)
βββ references/ # Optional β documentation loaded on demand
βββ assets/ # Optional β files used in output (images, CSS, etc.)
SKILL.md format (unchanged from existing conventions):
---
name: asvc-report
description: Generate ASVC compliance audit reports with structured findings...
---
# ASVC Report Generator
## Instructions
...AAM preserves SKILL.md as-is during deployment. No transformation needed.
An agent is a new artifact type that defines an AI agent's configuration. It ties together a system prompt, skills, tools, and behavioral instructions.
Directory structure:
agents/<agent-name>/
βββ agent.yaml # Required β agent definition
βββ system-prompt.md # Required β the agent's system prompt
agent.yaml schema:
name: asvc-audit
description: "Agent specialized in ASVC compliance auditing"
version: 1.0.0
# The system prompt file for this agent
system_prompt: system-prompt.md
# Skills this agent uses (resolved from package artifacts or dependencies)
skills:
- asvc-report # from this package
- generic-auditor # from dependency
# Prompts this agent uses
prompts:
- audit-finding # from this package
- audit-summary # from this package
# Tool access configuration (platform-dependent)
tools:
- file_read
- file_write
- shell
- web_search
# Behavioral parameters
parameters:
temperature: 0.3
style: professional
output_format: markdownsystem-prompt.md:
You are an ASVC compliance auditor. Your role is to analyze codebases,
configurations, and documentation against ASVC framework requirements.
## Core Responsibilities
- Identify compliance gaps against ASVC standards
- Generate structured audit findings
- Produce executive summaries with risk ratings
## Audit Process
1. Analyze the target artifacts
2. Map findings to ASVC control objectives
3. Rate severity (Critical / High / Medium / Low)
4. Generate actionable remediation guidanceA prompt is a reusable prompt template with optional variable interpolation.
File format: Markdown with YAML frontmatter.
---
name: audit-finding
description: "Structured prompt for documenting a single audit finding"
variables:
- name: control_id
description: "ASVC control identifier"
required: true
- name: severity
description: "Finding severity level"
required: true
enum: [critical, high, medium, low]
default: medium # Optional default value
- name: evidence
description: "Evidence supporting the finding"
required: false
default: "No evidence provided"
---
# Audit Finding: {{control_id}}
## Severity: {{severity}}
Analyze the following evidence and produce a structured audit finding:
{{evidence}}
## Required Output Structure
1. **Finding Title**: Concise description
2. **Control Reference**: {{control_id}}
3. **Severity**: {{severity}}
4. **Description**: Detailed finding description
5. **Evidence**: Supporting evidence
6. **Impact**: Business/security impact
7. **Recommendation**: Actionable remediation stepsAn instruction defines rules, conventions, or guidelines. These get translated into platform-specific formats during deployment.
File format: Markdown with YAML frontmatter.
Frontmatter fields:
name(required): Instruction identifierdescription(required): What this instruction doesscope(optional):project(default) orglobalβ determines deployment locationglobs(optional): File patterns this instruction applies to (e.g.,**/*.py)
---
name: asvc-coding-standards
description: "Coding standards for ASVC-compliant projects"
scope: project # "project" (deploy to .cursor/rules/) or "global" (~/.cursor/rules/)
globs: "**/*.py" # Optional file pattern (used by Cursor rules)
---
# ASVC Coding Standards
## Security Requirements
- All API endpoints must validate authentication tokens
- Input validation required on all user-supplied data
- Secrets must never be committed β use environment variables
## Logging Requirements
- All security events must be logged with structured format
- Log entries must include: timestamp, user_id, action, resource, resultAn eval is a definition for evaluating an agent or skill's quality. Evals are declared in aam.yaml under quality.evals and reference eval definition files.
Eval definition file format (evals/accuracy.yaml):
name: accuracy-eval
description: "Evaluate agent accuracy on benchmark tasks"
dataset: evals/benchmark-dataset.jsonl
model: gpt-4
judge: evals/judge-prompt.md # LLM-as-judge prompt
metrics:
- name: accuracy
aggregation: mean
- name: latency_p95
aggregation: percentile_95Usage in aam.yaml:
quality:
tests:
- name: "unit-tests"
command: "pytest tests/"
description: "Unit tests for agent skills"
- name: "lint-check"
command: "ruff check ."
description: "Code quality check"
evals:
- name: "accuracy-eval"
path: "evals/accuracy.yaml"
description: "Measures accuracy against benchmark dataset"
metrics:
- name: "accuracy"
type: "percentage"
- name: "latency_p95"
type: "duration_ms"CLI commands:
# Run all declared tests
aam test
# Run all declared evals
aam eval
# Run evals and publish results to the registry
aam eval --publishEval results are stored in the registry (HTTP only) and shown during aam search and aam info to help consumers judge package quality.
Commands are organized by persona/workflow and displayed in categorized sections
via aam --help.
aam <command> [options] [arguments]
Getting Started:
init Set up AAM (platform, default sources)
Package Management:
install <package> Install a package and its dependencies
uninstall <package> Remove an installed package
upgrade [package] Upgrade outdated source-installed packages
outdated Check for outdated packages
search <query> Search registries and sources
list List installed packages (--available for sources)
info <package> Show package details
Package Integrity:
verify [package|--all] Verify installed file checksums
diff <package> Show unified diffs for modified files
Package Authoring (aam pkg):
pkg init <name> Scaffold a new package from scratch
pkg create [path] Create package from existing project (autodetect)
pkg validate Validate current package manifest and artifacts
pkg pack Build distributable .aam archive
pkg publish Publish package to registry
pkg build --target <platform> Build a portable bundle for a target platform
Source Management:
source add <url> Add a remote git repository as artifact source
source scan <name> Scan a source for artifacts
source update [name|--all] Fetch upstream changes and detect new artifacts
source list List configured remote git sources
source remove <name> Remove a configured source
source candidates List unpackaged artifact candidates
source enable-defaults Enable all default community skill sources
Configuration:
config set <key> <value> Set configuration value
config get <key> Get configuration value
registry add <url> Add a registry source
registry list List configured registries
registry remove <name> Remove a registry source
Utilities:
mcp serve Start MCP stdio server for IDE integration
doctor Check environment and diagnose issues
convert Convert configs between platforms
Installs a package and all transitive dependencies, then deploys artifacts to the active platform.
# Install from registry (unscoped)
aam install asvc-auditor
# Install scoped package from registry
aam install @author/asvc-auditor
# Install specific version (scoped)
aam install @author/asvc-auditor@1.2.0
# Install specific version (unscoped)
aam install asvc-auditor@1.2.0
# Install from git URL
aam install git+https://github.com/author/asvc-auditor.git
# Install from local path
aam install ./my-package/
# Install from .aam file
aam install asvc-auditor-1.0.0.aam
# Install and deploy to specific platform only
aam install @author/asvc-auditor --platform cursor
# Install without deploying (download + resolve only)
aam install @author/asvc-auditor --no-deployInstall flow:
1. Resolve package from registry/source
2. Download package archive
3. Parse aam.yaml manifest
4. Resolve dependencies (recursive)
5. Download missing dependencies
6. Extract all packages to .aam/packages/
7. Write lock file (.aam/aam-lock.yaml)
8. Deploy artifacts to active platform(s)
9. Print summary
Example output:
$ aam install @author/asvc-auditor
Resolving @author/asvc-auditor@1.0.0...
+ @author/asvc-auditor@1.0.0
+ @author/generic-auditor@1.2.3 (dependency)
+ report-templates@2.1.0 (dependency)
Downloading 3 packages...
β @author/asvc-auditor@1.0.0
β @author/generic-auditor@1.2.3
β report-templates@2.1.0
Deploying to cursor...
β skill: asvc-report β .cursor/skills/author--asvc-report/
β skill: generic-auditor β .cursor/skills/author--generic-auditor/
β agent: asvc-audit β .cursor/rules/agent-author--asvc-audit.mdc
β prompt: audit-finding β .cursor/prompts/audit-finding.md
β instruction: asvc-standards β .cursor/rules/asvc-standards.mdc
Installed 3 packages (2 skills, 1 agent, 2 prompts, 1 instruction)
Creates a new AAM package from an existing working project that already contains skills, agents, prompts, or instructions that are not yet managed by AAM. This is the reverse of aam pkg init β instead of scaffolding an empty package, it discovers existing artifacts in a project and packages them.
Use case: You have been working in a project and created skills (e.g., .cursor/skills/my-skill/SKILL.md) or agents (e.g., .cursor/rules/my-agent.mdc) or instructions organically β outside of any AAM package. Now you want to bundle them into a distributable AAM package.
# Auto-detect artifacts in current directory
$ aam pkg create
# Auto-detect artifacts in a specific directory
$ aam pkg create ./my-project/
# Skip interactive selection β include everything detected
$ aam pkg create --all
# Only detect specific artifact types
$ aam pkg create --type skills --type agents
# Output manifest to stdout without creating files (preview mode)
$ aam pkg create --dry-runAutodetection flow:
The command scans the project directory for files that match known artifact patterns but are NOT already declared in any existing aam.yaml manifest.
Detection patterns:
Skills:
β **/SKILL.md (any SKILL.md file β parent dir is a skill)
β .cursor/skills/*/SKILL.md (Cursor skill convention)
β .codex/skills/*/SKILL.md (Codex skill convention)
β skills/*/SKILL.md (AAM convention)
Agents:
β **/agent.yaml (agent definition files)
β agents/*/agent.yaml (AAM convention)
β .cursor/rules/agent-*.mdc (Cursor agent rules)
Prompts:
β prompts/*.md (AAM convention)
β .cursor/prompts/*.md (Cursor prompts)
β .github/prompts/*.md (Copilot prompts)
Instructions:
β instructions/*.md (AAM convention)
β .cursor/rules/*.mdc (Cursor rules, excluding agent-* rules)
β CLAUDE.md (Claude instructions)
β .github/copilot-instructions.md (Copilot legacy instructions)
β .github/instructions/*.instructions.md (Copilot instructions)
β AGENTS.md (Codex instructions)
Exclusion rules (NOT detected):
Files inside the following directories are ignored:
.aam/packages/β already-installed AAM packagesnode_modules/,.venv/,__pycache__/β dependency/build directories.git/β version control
Files already declared in an existing aam.yaml are excluded from detection results.
Interactive selection flow:
$ aam pkg create
Scanning for artifacts not managed by AAM...
Found 6 artifacts:
Skills:
[x] 1. my-reviewer .cursor/skills/my-reviewer/SKILL.md
[x] 2. deploy-helper .cursor/skills/deploy-helper/SKILL.md
[ ] 3. experiment-wip .cursor/skills/experiment-wip/SKILL.md
Agents:
[x] 4. code-auditor agents/code-auditor/agent.yaml
[ ] 5. chat-assistant .cursor/rules/agent-chat-assistant.mdc
Instructions:
[x] 6. python-rules .cursor/rules/python-rules.mdc
Toggle selection with space, confirm with enter.
Select/deselect all: [a]
Invert selection: [i]
βββββββββββββββββββββββββββββββββββββββ
Selected 4 artifacts. Continue? [Y/n] y
Package name [my-project]: my-toolkit
Version [1.0.0]:
Description: Custom toolkit with code review and deployment skills
Author [spazy]:
License [MIT]:
How should files be organized?
(c) Copy into AAM package structure (agents/, skills/, prompts/, instructions/)
(r) Reference in-place (keep files where they are, aam.yaml points to current paths)
[default: c]
Creating package...
β Created aam.yaml
β Copied .cursor/skills/my-reviewer/ β skills/my-reviewer/
β Copied .cursor/skills/deploy-helper/ β skills/deploy-helper/
β Copied agents/code-auditor/ β agents/code-auditor/ (already in place)
β Copied .cursor/rules/python-rules.mdc β instructions/python-rules.md
β Package created: my-toolkit@1.0.0
4 artifacts (2 skills, 1 agent, 1 instruction)
Next steps:
aam pkg validate β check that everything is correct
aam pkg pack β build distributable archive
aam pkg publish β publish to registryFile organization modes:
| Mode | Flag | Behavior |
|---|---|---|
| Copy (default) | --organize copy |
Copies files into standard AAM directory structure (skills/, agents/, etc.). Original files are left untouched. |
| Reference | --organize reference |
Does NOT copy files. The aam.yaml manifest points to files at their current locations (e.g., .cursor/skills/my-reviewer/). Useful for packages that will only be used locally or published from the same project layout. |
| Move | --organize move |
Moves files into AAM structure and removes originals. Use with caution. |
Platform-specific artifact conversion:
When artifacts are found in platform-specific locations, they may need conversion:
| Source Format | Target Format | Conversion |
|---|---|---|
.cursor/rules/*.mdc (instruction) |
instructions/*.md |
Strip .mdc frontmatter, convert to instruction markdown with YAML frontmatter |
.cursor/rules/agent-*.mdc (agent) |
agents/*/ |
Extract system prompt from rule body, generate agent.yaml |
CLAUDE.md sections |
instructions/*.md |
Split CLAUDE.md into individual instruction files |
.github/instructions/*.instructions.md |
instructions/*.md |
Copy instruction files |
Manual include:
In addition to autodetection, you can manually specify files to include:
# Include specific files that autodetection missed
$ aam pkg create --include docs/my-guide.md --include-as instruction
# Include a directory as a skill
$ aam pkg create --include ./my-tools/analyzer/ --include-as skillCommand options:
aam pkg create [PATH]
Arguments:
PATH Project directory to scan (default: current directory)
Options:
--all Include all detected artifacts without interactive selection
--type TYPE Filter detection to specific types (repeatable: skills, agents, prompts, instructions)
--organize MODE File organization: copy (default), reference, move
--include PATH Manually include a file/directory (repeatable)
--include-as TYPE Artifact type for --include (skill, agent, prompt, instruction)
--name NAME Package name (skip interactive prompt)
--version VERSION Package version (skip interactive prompt)
--description DESC Package description (skip interactive prompt)
--author AUTHOR Package author (skip interactive prompt)
--dry-run Show what would be created without writing files
--output-dir DIR Output directory for package (default: current directory)
-y, --yes Skip confirmation prompts
Client setup command. Guides new users through platform detection and default
source configuration. If called with a [name] argument, delegates to
aam pkg init for backward compatibility (with a deprecation warning).
# Interactive client setup
$ aam init
Detected platform: cursor
Choose platform [cursor]:
Register community artifact sources? [Y/n] y
β AAM initialized successfully.
Platform: cursor
Config: ~/.aam/config.yaml
Sources: 2 community source(s) added
Next steps:
aam search <query> β Find packages to install
aam install <pkg> β Install a package
aam list --available β Browse source artifacts
aam pkg init β Create a new package
# Non-interactive (use defaults)
$ aam init --yesInteractive package scaffolding. Creates artifact directories and aam.yaml.
$ aam pkg init asvc-auditor
Package name: asvc-auditor
Version (1.0.0):
Description: ASVC audit agent with reporting capabilities
Author: spazy
License (MIT):
Created asvc-auditor/
βββ aam.yaml
βββ agents/
βββ skills/
βββ prompts/Deploys installed artifacts to the target platform without re-downloading.
# Deploy to configured default platform
aam deploy
# Deploy to a specific platform
aam deploy --platform cursor
aam deploy --platform claude
aam deploy --platform copilot
# Deploy a specific package only
aam deploy asvc-auditor --platform cursor
# Dry run β show what would be deployed
aam deploy --dry-runBuilds a portable, pre-compiled bundle for one or more target platforms.
# Build for a specific platform
aam pkg build --target cursor
# Produces: dist/my-package-1.0.0-cursor.bundle.aam
# Build for all configured platforms
aam pkg build --target all
# Build with custom output directory
aam pkg build --target cursor --output ./releases/Build flow:
1. Parse aam.yaml manifest
2. Resolve all dependencies (from registries)
3. For the target platform, run the platform adapter to compile all artifacts
4. Package compiled artifacts + bundle.json into a .bundle.aam archive
5. Write to dist/ (or --output directory)
Creates a new local registry at the specified path. This is a one-time setup command.
# Create a new local registry in a specific directory
aam registry init ~/my-aam-registry
# Creates registry.yaml + empty index.yaml + packages/ directory
# Initialize in current directory
aam registry init .
# Initialize and immediately set as the default registry
aam registry init ~/my-packages --default$ aam list
Installed packages:
asvc-auditor 1.0.0 3 artifacts (1 agent, 1 skill, 2 prompts)
generic-auditor 1.2.3 1 artifact (1 skill)
report-templates 2.1.0 2 artifacts (1 skill, 1 instruction)
$ aam list --tree
asvc-auditor@1.0.0
βββ generic-auditor@1.2.3
βββ report-templates@2.1.0$ aam info asvc-auditor
asvc-auditor@1.0.0
Description: ASVC audit agent with reporting capabilities
Author: spazy
License: MIT
Repository: https://github.com/spazy/asvc-auditor
Artifacts:
agent: asvc-audit β Agent configured for ASVC compliance auditing
skill: asvc-report β Skill for generating ASVC audit reports
prompt: audit-finding β Structured prompt for documenting audit findings
prompt: audit-summary β Prompt for generating executive audit summaries
Dependencies:
generic-auditor >=1.0.0 (installed: 1.2.3)
report-templates ^2.0.0 (installed: 2.1.0)Converts AI agent configurations between platforms (Cursor, Copilot, Claude, Codex). Reads artifacts from one platform's format and writes them in another's format, with warnings about metadata that cannot be directly converted.
# Convert all Cursor configs to Copilot format
aam convert -s cursor -t copilot
# Convert only instructions, dry-run
aam convert -s copilot -t claude --type instruction --dry-run
# Force overwrite existing target files (with .bak backup)
aam convert -s codex -t cursor --forceOptions:
--source-platform/-s(required): Source platform--target-platform/-t(required): Target platform--type: Filter by artifact type (instruction,agent,prompt,skill)--dry-run: Preview conversions without writing files--force: Overwrite existing targets (creates.bakbackup)--verbose: Show detailed workaround instructions for lossy conversions
Conversion behavior:
- Skills: Direct copy (universal
SKILL.mdformat) - Instructions: Field mapping (e.g. Cursor
globsβ CopilotapplyTo) - Agents: Metadata filtering (platform-specific fields dropped with warnings)
- Prompts: Frontmatter stripping or addition as needed
See docs/specs/SPEC-convert-command.md for the full conversion matrix.
AAM exposes its CLI capabilities as an MCP (Model Context Protocol) server, allowing AI agents inside IDEs (Cursor, VS Code, Windsurf, etc.) to invoke AAM operations programmatically. The server communicates over stdio (JSON-RPC 2.0) β the standard transport for locally-embedded MCP servers.
The MCP server is built with FastMCP 2.0+, a high-level Python framework for MCP servers.
Why FastMCP over the low-level mcp SDK:
| Concern | FastMCP | Raw mcp SDK |
|---|---|---|
| Tool registration | @mcp.tool decorator |
Manual handler classes |
| Resource registration | @mcp.resource decorator |
Manual handler classes |
| Input validation | Auto-generated JSON Schema from type hints / Pydantic | Manual schema definition |
| Safety filtering | Built-in include_tags / exclude_tags |
Custom implementation |
| Transport | Built-in stdio + HTTP + SSE | Manual transport setup |
| Testing | fastmcp.Client in-memory testing |
Manual test harness |
aam mcp serve [options]
| Flag | Default | Description |
|---|---|---|
--transport |
stdio |
Transport protocol: stdio (default) or http |
--port |
8000 |
HTTP port (only used with --transport http) |
--allow-write |
false |
Enable mutating tools (install, publish, config set, etc.) |
--log-file <path> |
None |
Redirect application logs to a file (recommended for stdio mode) |
--log-level |
INFO |
Log level: DEBUG, INFO, WARNING, ERROR |
Note: In stdio mode,
stdoutis reserved for JSON-RPC messages. All application logging must go to a file (--log-file) orstderr. FastMCP handles the stdio protocol framing automatically.
from fastmcp import FastMCP
mcp = FastMCP(
name="aam",
instructions=(
"AAM (Agent Artifact Manager) β package manager for AI agent artifacts. "
"Search, install, publish, and manage skills, agents, prompts, and instructions "
"across platforms like Cursor, Claude, GitHub Copilot, and Codex."
),
version="0.1.0",
)When --allow-write is not passed (default), the server is created with:
mcp = FastMCP(
name="aam",
...,
exclude_tags={"write"}, # Only read-tagged tools are exposed
)| Transport | Invocation | Use Case |
|---|---|---|
| stdio (default) | aam mcp serve |
IDE integration β client spawns process, communicates via stdin/stdout |
| http | aam mcp serve --transport http --port 8000 |
Remote access, multi-client β accessible at http://localhost:8000/mcp |
CLI commands are exposed as MCP tools via @mcp.tool decorators. Each tool is tagged as read or write to support the safety model.
Read-only tools (always available):
| Tool | Maps to CLI | Description |
|---|---|---|
aam_search |
aam search |
Search registry for packages |
aam_list |
aam list |
List installed packages |
aam_info |
aam info <package> |
Show detailed package metadata |
aam_validate |
aam pkg validate |
Validate current package manifest and artifacts |
aam_config_get |
aam config get |
Get configuration value(s) |
aam_registry_list |
aam registry list |
List configured registries |
aam_doctor |
aam doctor |
Check environment and diagnose issues |
aam_source_list |
aam source list |
List configured artifact sources |
aam_source_scan |
aam source scan |
Scan a source for available artifacts |
aam_source_candidates |
aam source candidates |
List unpackaged candidates from a source |
aam_source_diff |
aam source diff |
Show diff between source and installed version |
aam_verify |
aam verify |
Verify installed package integrity |
aam_diff |
aam diff |
Show diff between installed and source versions |
aam_outdated |
aam outdated |
Check for outdated source-installed packages |
aam_available |
aam available |
List all available artifacts from configured sources |
aam_recommend_skills |
aam recommend-skills |
Recommend skills based on repository analysis |
aam_init_info |
aam init --info |
Get client initialization status and detected platform |
Write tools (require --allow-write):
| Tool | Maps to CLI | Description |
|---|---|---|
aam_install |
aam install |
Install one or more packages and their dependencies |
aam_uninstall |
aam uninstall |
Remove an installed package |
aam_publish |
aam pkg publish |
Publish package to registry |
aam_create_package |
aam pkg create |
Create AAM package from existing project |
aam_config_set |
aam config set |
Set a configuration value |
aam_registry_add |
aam registry add |
Add a new registry source |
aam_init_package |
aam pkg init |
Scaffold a new package with directories and manifest |
aam_source_add |
aam source add |
Add a remote git repository as an artifact source |
aam_source_remove |
aam source remove |
Remove a configured source |
aam_source_update |
aam source update |
Fetch upstream changes for one or all sources |
aam_upgrade |
aam upgrade |
Upgrade outdated source-installed packages |
aam_init |
aam init |
Initialize the AAM client for a specific AI platform |
Tool naming: All tools are prefixed with
aam_to avoid collisions when multiple MCP servers are active in an IDE.
FastMCP auto-generates JSON Schema for tool inputs from Python type hints. Tool handlers wrap the existing CLI core logic (services/functions), not Click commands directly β keeping the MCP layer thin and testable.
Read tool examples:
@mcp.tool(tags={"read"})
def aam_search(
query: str,
limit: int = 10,
package_type: str | None = None,
) -> list[dict]:
"""Search the AAM registry for packages matching a query.
Args:
query: Search terms to match against package names and descriptions.
limit: Maximum number of results to return (default: 10).
package_type: Filter by artifact type (skill, agent, prompt, instruction).
Returns:
List of matching packages with name, version, description, and author.
"""
...
@mcp.tool(tags={"read"})
def aam_info(package_name: str, version: str | None = None) -> dict:
"""Show detailed metadata for a specific package.
Args:
package_name: Full package name (e.g. 'asvc-auditor' or '@author/asvc-auditor').
version: Specific version to inspect (default: latest).
Returns:
Package metadata including artifacts, dependencies, platforms, and author.
"""
...
@mcp.tool(tags={"read"})
def aam_list() -> list[dict]:
"""List all installed AAM packages in the current project.
Returns:
List of installed packages with name, version, and deployment status.
"""
...
@mcp.tool(tags={"read"})
def aam_validate(path: str = ".") -> dict:
"""Validate an AAM package manifest and its artifacts.
Args:
path: Path to the package directory (default: current directory).
Returns:
Validation result with status, errors, and warnings.
"""
...
@mcp.tool(tags={"read"})
def aam_config_get(key: str | None = None) -> dict:
"""Get AAM configuration value(s).
Args:
key: Dot-notation config key (e.g. 'default_platform'). If None, returns all config.
Returns:
Configuration key-value pair(s).
"""
...
@mcp.tool(tags={"read"})
def aam_registry_list() -> list[dict]:
"""List all configured AAM registries.
Returns:
List of registries with name, URL, and default status.
"""
...
@mcp.tool(tags={"read"})
def aam_doctor() -> dict:
"""Check the AAM environment and diagnose issues.
Returns:
Diagnostic report with checks for Python version, dependencies, config, and connectivity.
"""
...Write tool examples:
@mcp.tool(tags={"write"})
def aam_install(
packages: list[str],
platform: str | None = None,
force: bool = False,
no_deploy: bool = False,
) -> dict:
"""Install AAM packages from registries or local sources.
Args:
packages: List of package specs (e.g. ['my-pkg', 'other@1.0']).
platform: Target platform override (default: from config).
force: Reinstall even if already present.
no_deploy: Download only, skip deployment.
Returns:
Install result with lists of installed, already_installed, and failed packages.
"""
...
@mcp.tool(tags={"write"})
def aam_publish(
access: str = "public",
tag: str = "latest",
sign: bool = False,
) -> dict:
"""Publish the current package to the registry.
Args:
access: Access level β 'public' or 'private'.
tag: Distribution tag (default: 'latest').
sign: Sign the package with Sigstore.
Returns:
Publish result with package name, version, and registry URL.
"""
...
@mcp.tool(tags={"write"})
def aam_create_package(
path: str = ".",
name: str | None = None,
version: str | None = None,
description: str | None = None,
artifact_types: list[str] | None = None,
include_all: bool = False,
) -> dict:
"""Create an AAM package from an existing project by detecting artifacts.
Args:
path: Project directory path to scan (default: current directory).
name: Package name (auto-detected if not provided).
version: Package version (default: '0.1.0').
description: Package description.
artifact_types: Filter to specific types (skill, agent, prompt, instruction).
include_all: Include all detected artifacts without interactive selection.
Returns:
Created package summary with manifest path and included artifacts.
"""
...
@mcp.tool(tags={"write"})
def aam_config_set(key: str, value: str) -> dict:
"""Set an AAM configuration value.
Args:
key: Dot-notation config key (e.g. 'default_platform', 'security.require_signature').
value: Value to set.
Returns:
Updated configuration entry.
"""
...
@mcp.tool(tags={"write"})
def aam_uninstall(package_name: str) -> dict:
"""Remove an installed AAM package.
Args:
package_name: Full package name to uninstall.
Returns:
Uninstall result with removed files and cleaned dependencies.
"""
...
@mcp.tool(tags={"write"})
def aam_registry_add(name: str, url: str, set_default: bool = False) -> dict:
"""Add a new AAM registry source.
Args:
name: Registry name (e.g. 'my-registry').
url: Registry URL.
set_default: Set this registry as the default.
Returns:
Registry entry with name, URL, and default status.
"""
...Resources expose read-only data that IDE agents can pull without invoking a tool. Resources are registered via @mcp.resource decorators.
| Resource URI | Description |
|---|---|
aam://config |
Current AAM configuration (global + project) |
aam://packages/installed |
List of installed packages with versions and platforms |
aam://packages/{name} |
Detailed metadata for a specific installed package (resource template) |
aam://registries |
All configured registries with URLs and auth status |
aam://manifest |
Current project's aam.yaml manifest contents (if present) |
Resource definition examples:
@mcp.resource("aam://config")
def get_config() -> dict:
"""Current AAM configuration (global merged with project-level)."""
...
@mcp.resource("aam://packages/installed")
def get_installed_packages() -> list[dict]:
"""List all installed AAM packages with version and platform info."""
...
@mcp.resource("aam://packages/{name}")
def get_package_details(name: str) -> dict:
"""Detailed metadata for a specific installed package."""
...
@mcp.resource("aam://registries")
def get_registries() -> list[dict]:
"""All configured AAM registries."""
...
@mcp.resource("aam://manifest")
def get_manifest() -> dict | None:
"""Current project's aam.yaml manifest contents, or null if not present."""
...The MCP server uses a read-only-by-default safety model built on FastMCP's tag-based filtering:
| Mode | Behavior | Flag |
|---|---|---|
| Read-only (default) | Only tools tagged read are exposed. Write tools are hidden from the IDE agent. Resources are always available. |
(none) |
| Full access | All tools (read + write) are exposed. The IDE agent can install, publish, and modify configuration. | --allow-write |
Implementation:
def create_mcp_server(allow_write: bool = False) -> FastMCP:
"""Create the AAM MCP server with appropriate safety settings."""
kwargs = {
"name": "aam",
"instructions": "...",
"version": "0.1.0",
}
if not allow_write:
kwargs["exclude_tags"] = {"write"}
return FastMCP(**kwargs)sequenceDiagram
participant IDE as IDE Agent
participant Stdio as stdio transport
participant FastMCP as FastMCP Server
participant Core as CLI Core Logic
participant Registry as Registry / Filesystem
IDE->>Stdio: JSON-RPC request (tools/call)
Stdio->>FastMCP: Parsed MCP message
FastMCP->>FastMCP: Validate input (Pydantic)
FastMCP->>FastMCP: Check tag permissions
FastMCP->>Core: Call tool handler
Core->>Registry: Execute operation
Registry-->>Core: Result
Core-->>FastMCP: Return value
FastMCP-->>Stdio: JSON-RPC response
Stdio-->>IDE: Result displayed to user
Cursor β project-level .cursor/mcp.json:
{
"mcpServers": {
"aam": {
"command": "aam",
"args": ["mcp", "serve"],
"env": {}
}
}
}Cursor β full access mode:
{
"mcpServers": {
"aam": {
"command": "aam",
"args": ["mcp", "serve", "--allow-write"],
"env": {}
}
}
}Alternative β using fastmcp run (does not require aam CLI on PATH):
{
"mcpServers": {
"aam": {
"command": "fastmcp",
"args": ["run", "aam_cli.mcp.server:mcp"],
"env": {}
}
}
}VS Code β .vscode/settings.json:
{
"mcp.servers": {
"aam": {
"command": "aam",
"args": ["mcp", "serve", "--allow-write"]
}
}
}FastMCP provides an in-memory Client for testing tools and resources without spawning a process:
import pytest
from fastmcp import Client
from aam_cli.mcp.server import mcp
@pytest.mark.asyncio
async def test_unit_aam_search():
"""Verify aam_search tool returns results for a valid query."""
async with Client(mcp) as client:
result = await client.call_tool("aam_search", {"query": "python"})
assert isinstance(result, list)
@pytest.mark.asyncio
async def test_unit_installed_packages_resource():
"""Verify the installed packages resource returns a list."""
async with Client(mcp) as client:
data = await client.read_resource("aam://packages/installed")
assert isinstance(data, list)The default registry is a Git repository with a defined layout. This follows the same philosophy as Homebrew taps or Go modules.
Registry repository structure:
aam-registry/
βββ registry.yaml # Registry metadata
βββ packages/
β βββ @author/ # Scoped packages nested under @scope/
β β βββ asvc-auditor/
β β β βββ metadata.yaml # Package metadata + version index
β β β βββ versions/
β β β βββ 1.0.0.aam # Archived package
β β β βββ 1.1.0.aam
β β βββ generic-auditor/
β β βββ metadata.yaml
β β βββ versions/
β β βββ 1.0.0.aam
β β βββ 1.1.0.aam
β β βββ 1.2.3.aam
β βββ report-templates/ # Unscoped packages at top level
β βββ metadata.yaml
β βββ versions/
β βββ 2.1.0.aam
βββ index.yaml # Flat package index for fast search
registry.yaml:
name: aam-central
description: "Community registry for AAM packages"
url: https://github.com/aam-packages/registry
api_version: 1packages/@author/asvc-auditor/metadata.yaml:
name: "@author/asvc-auditor"
description: "ASVC audit agent with reporting capabilities"
author: author
license: Apache-2.0
repository: https://github.com/author/asvc-auditor
keywords: [audit, asvc, compliance]
versions:
- version: 1.1.0
published: 2026-02-10
checksum: sha256:abc123...
dependencies:
"@author/generic-auditor": ">=1.0.0"
report-templates: "^2.0.0"
- version: 1.0.0
published: 2026-02-05
checksum: sha256:def456...
dependencies:
"@author/generic-auditor": ">=1.0.0"
latest: 1.1.0index.yaml (flat search index):
packages:
- name: "@author/asvc-auditor"
description: "ASVC audit agent with reporting capabilities"
latest: 1.1.0
keywords: [audit, asvc, compliance]
artifacts: [agent, skill, prompt]
- name: "@author/generic-auditor"
description: "General-purpose code auditing skill"
latest: 1.2.3
keywords: [audit, code-review]
artifacts: [skill]
- name: report-templates
description: "Reusable report generation templates"
latest: 2.1.0
keywords: [reporting, templates]
artifacts: [skill, instruction]A local directory that mirrors the git registry structure. Useful for offline development, private packages, or team sharing via a shared filesystem. This is the primary registry type for Phase 1 (MVP) and the recommended starting point.
Creating a local registry:
# Create a new local registry (one-time setup)
aam registry init ~/my-aam-registry
# Add it as a named registry source
aam registry add local file:///home/spazy/my-aam-registry --default
# Publish to local registry
aam pkg publish --registry localLocal registry directory structure:
~/my-aam-registry/
βββ registry.yaml # Registry metadata
βββ index.yaml # Flat search index (rebuilt on publish)
βββ packages/
βββ @myorg/ # Scoped packages nested under @scope/
β βββ my-agent/
β βββ metadata.yaml # Version index + checksums + dist-tags
β βββ versions/
β βββ 1.0.0.aam
β βββ 1.1.0.aam
βββ shared-skills/ # Unscoped packages at top level
βββ metadata.yaml
βββ versions/
βββ 2.0.0.aam
registry.yaml schema:
name: my-local-registry
type: local
description: "Local AAM package registry"
api_version: 1
created_at: "2026-02-07T10:00:00Z"index.yaml schema (flat search index, rebuilt on each publish):
packages:
- name: "@myorg/my-agent"
description: "ASVC compliance auditor agent"
latest: "1.1.0"
keywords: [audit, compliance]
artifact_types: [agent, skill, prompt]
updated_at: "2026-02-07T14:00:00Z"
- name: shared-skills
description: "Reusable utility skills"
latest: "2.0.0"
keywords: [utility]
artifact_types: [skill]
updated_at: "2026-02-06T10:00:00Z"metadata.yaml per-package schema:
name: "@myorg/my-agent"
description: "ASVC compliance auditor agent"
author: spazy
license: Apache-2.0
repository: https://github.com/myorg/my-agent
keywords: [audit, compliance]
dist_tags:
latest: "1.1.0"
stable: "1.0.0"
versions:
- version: "1.1.0"
published: "2026-02-07T14:00:00Z"
checksum: "sha256:abc123..."
size: 12847
dependencies:
"@myorg/generic-auditor": ">=1.0.0"
- version: "1.0.0"
published: "2026-02-05T10:00:00Z"
checksum: "sha256:def456..."
size: 11200
dependencies:
"@myorg/generic-auditor": ">=1.0.0"Local registry operations (all pure file I/O β no server, no database):
| Operation | Implementation |
|---|---|
search(query) |
Read index.yaml, fuzzy-match on name/description/keywords |
get_metadata(name) |
Read packages/@scope/name/metadata.yaml |
get_versions(name) |
Parse metadata.yaml versions list |
download(name, ver) |
Copy .aam file from versions/ to destination |
publish(archive) |
Extract manifest from archive, create dirs, copy .aam, update metadata.yaml + index.yaml |
Sharing a local registry across a team:
The entire registry is just a directory. Sync it however works for your team:
- Shared filesystem / NFS: Mount the same directory on all machines
- Git repository: Commit the registry directory to a git repo and clone it
- Cloud storage: Sync via Dropbox, Google Drive, or S3
- USB drive: For air-gapped environments
When resolving a package, AAM searches registries in order:
- Local install cache (
.aam/packages/) - User-configured registries (in
~/.aam/config.yamlorder) - Default community registry
$ cd asvc-auditor/
$ aam pkg validate
β aam.yaml is valid
β All artifact paths exist
β All artifact definitions are well-formed
β Dependencies reference valid packages
$ aam pkg pack
β Built asvc-auditor-1.0.0.aam (12.4 KB)
$ aam pkg publish
Publishing asvc-auditor@1.0.0 to aam-central...
β Published successfully
https://github.com/aam-packages/registry/packages/asvc-auditor/
# Publish with signature (HTTP registry)
$ aam pkg publish --sign
Publishing asvc-auditor@1.0.0 to aam-central...
Signing with Sigstore (OIDC identity)...
β Published with signature
Signature: sigstore bundle attached
# Publish with GPG signature
$ aam pkg publish --sign --sign-type gpg
Publishing asvc-auditor@1.0.0 to aam-central...
Signing with GPG key: ABC123DEF...
β Published with GPG signatureUnder the hood, aam pkg publish either:
- Creates a PR to the git registry (for community registry), or
- Uploads via HTTP API with optional signature (for HTTP registry), or
- Copies the
.aamfile to the local/private registry
AAM uses a simplified dependency resolution inspired by pip and npm but tailored for the smaller scale of agent artifacts.
Resolution strategy: Greedy with backtracking
RESOLVE(root_package):
queue = [root_package]
resolved = {}
while queue is not empty:
pkg = queue.pop()
for dep_name, constraint in pkg.dependencies:
if dep_name in resolved:
if resolved[dep_name].version satisfies constraint:
continue # already resolved, compatible
else:
ERROR: version conflict
version = find_best_version(dep_name, constraint)
resolved[dep_name] = version
queue.append(version) # resolve transitive deps
return resolved
find_best_version selects the highest version that satisfies the constraint from all configured registries.
| Syntax | Meaning | Example |
|---|---|---|
1.0.0 |
Exact version | Only 1.0.0 |
>=1.0.0 |
Minimum version | 1.0.0 or higher |
^1.0.0 |
Compatible release | >=1.0.0, <2.0.0 |
~1.0.0 |
Approximate | >=1.0.0, <1.1.0 |
* |
Any version | Latest available |
>=1.0.0,<2.0.0 |
Range constraint | Explicit range with multiple conditions |
Generated after resolution to ensure reproducible installs.
# aam-lock.yaml β DO NOT EDIT MANUALLY
lockfile_version: 1
resolved_at: "2026-02-05T14:30:00Z"
packages:
asvc-auditor:
version: 1.0.0
source: aam-central
checksum: sha256:abc123...
dependencies:
generic-auditor: 1.2.3
report-templates: 2.1.0
generic-auditor:
version: 1.2.3
source: aam-central
checksum: sha256:def456...
dependencies: {}
report-templates:
version: 2.1.0
source: aam-central
checksum: sha256:789ghi...
dependencies: {}When two packages require incompatible versions of the same dependency:
asvc-auditor requires generic-auditor >=2.0.0
other-tool requires generic-auditor <2.0.0
AAM reports the conflict clearly:
ERROR: Dependency conflict
asvc-auditor@1.0.0 requires generic-auditor >=2.0.0
other-tool@1.0.0 requires generic-auditor <2.0.0
No version of generic-auditor satisfies both constraints.
Suggestions:
1. Check if a newer version of other-tool relaxes the constraint
2. Install the packages in separate projects
Unlike npm, AAM does not support multiple versions of the same dependency (no node_modules-style nesting). Agent artifacts must converge on a single version to avoid conflicting instructions.
AAM supports multiple levels of package integrity and authenticity verification.
| Method | Description | When to Use |
|---|---|---|
| Checksum | SHA-256 hash of archive | Always (automatic) |
| Sigstore | Keyless, identity-based via OIDC | Recommended for public packages |
| GPG | Traditional key-based signing | For teams with existing GPG infrastructure |
| Registry Attestation | Server-side signatures | Automated trust for registry-verified packages |
Author Registry User
β β β
β aam pkg publish --sign β β
ββββββββββββββββββββββββββββββββΊβ β
β 1. Calculate SHA-256 β β
β 2. Sign with Sigstore/GPG β β
β 3. Upload archive+signature β β
β β Verify signature β
β β Store attestation β
β β β
β β aam install pkg β
β βββββββββββββββββββββββββββββββββ€
β β 1. Download archive β
β β 2. Download signature β
β ββββββββββββββββββββββββββββββββΊβ
β β β
β β 3. Verify checksum β
β β 4. Verify signature β
β β 5. Check trust policy β
β β 6. Install if valid β
Users configure their trust requirements in ~/.aam/config.yaml:
security:
require_checksum: true # Always enforced
require_signature: false # Optional by default
trusted_identities: # For Sigstore verification
- "*@example.org" # Trust all from domain
- "user@specific.com" # Trust specific user
trusted_keys: # For GPG verification
- "ABCD1234..." # GPG key fingerprint
on_signature_failure: warn # warn, error, or ignore# Verify package signature before install
$ aam install asvc-auditor --verify
β Checksum verified: sha256:abc123...
β Sigstore signature valid
Identity: author@example.org
Transparency log: https://rekor.sigstore.dev/...
# Show signature info
$ aam info asvc-auditor --signatures
asvc-auditor@1.0.0
Checksum: sha256:abc123def456...
Signatures:
- Type: sigstore
Identity: author@example.org
Timestamp: 2026-02-05T14:30:00ZFor full signing implementation details, see HTTP_REGISTRY_SPEC.md section 5.
Governance controls who can publish, what can be installed, and provides a tamper-evident record of all actions. AAM splits governance into client-side (works locally) and server-side (requires HTTP registry) features.
Policy gates are configurable rules in config.yaml that the CLI enforces before install or publish operations. They run entirely on the client and require no server.
# ~/.aam/config.yaml or .aam/config.yaml
governance:
install_policy:
allowed_scopes: ["@myorg", "@trusted-vendor"] # only allow these scopes
require_signature: true # require signed packages
require_tag: "stable" # only install tagged versions
blocked_packages: ["@sketchy/*"] # block specific packages
publish_policy:
require_approval: true # require approval before publish
approvers: ["admin@myorg.com"]
require_signature: true # must sign before publishingHow policy gates work:
| Gate | Trigger | Effect |
|---|---|---|
allowed_scopes |
aam install |
Block install of packages outside listed scopes |
require_signature |
aam install |
Block install of unsigned packages |
require_tag |
aam install |
Only install versions tagged with the specified tag |
blocked_packages |
aam install |
Block specific packages (supports glob patterns) |
require_approval |
aam pkg publish |
Require at least one approver to sign off |
require_signature |
aam pkg publish |
Require package signing before publish is allowed |
When require_approval: true is configured and publishing to an HTTP registry, the publish flow becomes:
aam pkg publishβ uploads package withapproval_status: pending- Approvers receive notification (webhook/email)
- Approvers review and run:
aam approve @org/agent@1.2.0or via API - Once approved, package becomes visible for install
- Rejected packages are hidden from search/install
Every mutation on the HTTP registry is logged immutably in the audit_log table:
{
"event": "package.publish",
"actor": "user@myorg.com",
"package": "@myorg/agent@1.2.0",
"timestamp": "2026-02-07T14:30:00Z",
"metadata": {"tag": "latest", "checksum": "sha256:abc..."}
}Audited events:
| Event | Description |
|---|---|
package.publish |
New version published |
version.yank |
Version marked as yanked |
tag.set |
Dist-tag added or updated |
tag.remove |
Dist-tag removed |
version.approve |
Version approved by an approver |
version.reject |
Version rejected by an approver |
ownership.transfer |
Package ownership transferred |
Each platform adapter implements the PlatformAdapter protocol (see section 11.4 for the full interface definition):
class PlatformAdapter(Protocol):
"""Deploys abstract artifacts to a specific AI platform."""
name: str
def deploy_skill(self, skill_path: Path, skill_ref: ArtifactRef, config: dict) -> Path
def deploy_agent(self, agent_path: Path, agent_ref: ArtifactRef, config: dict) -> Path
def deploy_prompt(self, prompt_path: Path, prompt_ref: ArtifactRef, config: dict) -> Path
def deploy_instruction(self, instr_path: Path, instr_ref: ArtifactRef, config: dict) -> Path
def undeploy(self, artifact_name: str, artifact_type: str) -> None
def list_deployed(self) -> list[tuple[str, str, Path]] # (name, type, path)When deploying scoped package artifacts to any platform, the @scope/name format must be converted to a filesystem-safe directory/file name. AAM uses the double-hyphen convention:
| Package Name | Filesystem Name | Rationale |
|---|---|---|
asvc-report (unscoped) |
asvc-report |
No change needed |
@author/asvc-report (scoped) |
author--asvc-report |
-- separates scope from name |
The -- separator is chosen because:
- Single hyphens are valid within both scope and name segments
- Double-hyphens cannot appear at positions 0-1 in a valid name (names must start with
[a-z0-9]) - The mapping is reversible: split on
--to recover(scope, name)
This convention applies to all platforms (Cursor, Copilot, Claude, Codex) and all artifact types.
Deployment mapping:
| Artifact Type | Cursor Location | Format |
|---|---|---|
| skill | .cursor/skills/<fs-name>/ or ~/.cursor/skills/<fs-name>/ |
SKILL.md (as-is) |
| agent | .cursor/rules/agent-<fs-name>.mdc |
Converted to rule with alwaysApply: true |
| prompt | .cursor/prompts/<fs-name>.md |
Stored as markdown (referenced by skills/agents) |
| instruction | .cursor/rules/<fs-name>.mdc |
Converted to .mdc rule with appropriate globs |
Note:
<fs-name>is the filesystem-safe name. For scoped packages,@author/asvc-reportbecomesauthor--asvc-report. See Section 8.0 for the mapping convention.
Agent β Cursor Rule conversion:
The agent's system prompt and configuration get wrapped in a Cursor rule:
---
description: "ASVC compliance auditor agent β activated for audit-related tasks"
alwaysApply: true
---
# Agent: asvc-audit
{{contents of system-prompt.md}}
## Available Skills
- asvc-report: Generate ASVC audit reports
- generic-auditor: General-purpose code auditing
## Available Prompts
- audit-finding: Use for documenting individual findings
- audit-summary: Use for executive summariesInstruction β Cursor Rule conversion:
---
description: "{{instruction.description}}"
globs: {{instruction.globs if defined}}
alwaysApply: {{true if no globs, false otherwise}}
---
{{instruction body}}Deployment mapping:
| Artifact Type | Copilot Location | Format |
|---|---|---|
| skill | .github/skills/<name>/SKILL.md |
SKILL.md (as-is, Copilot supports this) |
| agent | .github/agents/<name>.agent.md |
Discrete markdown file |
| prompt | .github/prompts/<name>.md |
Stored as markdown |
| instruction | .github/instructions/<name>.instructions.md |
Discrete markdown file |
Agent deployment:
Each agent is deployed as a discrete .agent.md file in .github/agents/, following Copilot's custom agents convention:
.github/agents/
βββ asvc-audit.agent.md
βββ code-reviewer.agent.md
Instruction deployment:
Each instruction is deployed as a discrete .instructions.md file in .github/instructions/, supporting conditional application via glob patterns:
.github/instructions/
βββ python-standards.instructions.md
βββ typescript-standards.instructions.md
Deployment mapping:
| Artifact Type | Claude Location | Format |
|---|---|---|
| skill | .claude/skills/<name>/SKILL.md |
SKILL.md (as-is) |
| agent | .claude/agents/<name>.md |
Discrete markdown file |
| prompt | .claude/prompts/<name>.md |
Stored as markdown |
| instruction | CLAUDE.md (appended section) |
Markdown section |
Agent deployment:
Each agent is deployed as a discrete .md file in .claude/agents/, following Claude Code's subagents convention:
.claude/agents/
βββ asvc-audit.md
βββ code-reviewer.md
Instruction deployment:
Instructions are merged into CLAUDE.md using marker-based sections:
<!-- BEGIN AAM: python-standards instruction -->
# Python Coding Standards
{{instruction contents}}
<!-- END AAM: python-standards instruction -->AAM uses the <!-- BEGIN AAM --> / <!-- END AAM --> markers to manage its own sections without disturbing user-written content in CLAUDE.md.
Deployment mapping:
| Artifact Type | Codex Location | Format |
|---|---|---|
| skill | ~/.codex/skills/<name>/ |
SKILL.md (as-is, native format) |
| agent | AGENTS.md (appended section) |
Markdown section |
| prompt | ~/.codex/prompts/<name>.md |
Stored as markdown |
| instruction | AGENTS.md (appended section) |
Markdown section |
flowchart TB
Package["AAM Package<br/>(abstract artifacts)"]
Package --> CursorAdapter["Cursor Adapter"]
Package --> CopilotAdapter["Copilot Adapter"]
Package --> ClaudeAdapter["Claude Adapter"]
Package --> CodexAdapter["Codex Adapter"]
CursorAdapter --> CursorFiles[".cursor/<br/>rules/, skills/, prompts/"]
CopilotAdapter --> CopilotFiles[".github/<br/>agents/, instructions/<br/>skills/, prompts/"]
ClaudeAdapter --> ClaudeFiles["CLAUDE.md<br/>.claude/agents/, skills/, prompts/"]
CodexAdapter --> CodexFiles["AGENTS.md<br/>~/.codex/skills/"]
style Package fill:#e1f5fe
style CursorAdapter fill:#fff3e0
style CopilotAdapter fill:#fff3e0
style ClaudeAdapter fill:#fff3e0
style CodexAdapter fill:#fff3e0
# ~/.aam/config.yaml β User-level AAM configuration
# Default platform for deployment
default_platform: cursor
# Active platforms (deploy to all listed platforms)
active_platforms:
- cursor
- claude
# Registry sources (searched in order)
registries:
- name: aam-central
url: https://github.com/aam-packages/registry
type: git
- name: local
url: file:///home/spazy/my-aam-packages
type: local
# Cache settings
cache:
directory: ~/.aam/cache
max_size_mb: 500
# Security and verification policy
security:
require_checksum: true # Always enforced (non-configurable)
require_signature: false # Require signed packages
trusted_identities: # Sigstore OIDC identities to trust
- "*@myorg.com"
trusted_keys: # GPG key fingerprints to trust
- "ABCD1234..."
on_signature_failure: warn # warn, error, or ignore
# Author defaults (used by aam init)
author:
name: author
email: author@example.com
# Publishing defaults
publish:
default_scope: "" # Default scope for aam pkg init / aam pkg publish
# Set to your username or org, e.g. "myorg"
# When set, aam init will default to @scope/name format# .aam/config.yaml β Project-level overrides
# Override default platform for this project
default_platform: cursor
# Override platform config for this project
platforms:
cursor:
skill_scope: projectProject (.aam/config.yaml) > Global (~/.aam/config.yaml) > Defaults
~/.aam/
βββ config.yaml # Global configuration
βββ credentials.yaml # API tokens (chmod 600, never commit)
βββ cache/ # Downloaded package cache
β βββ asvc-auditor-1.0.0.aam
β βββ generic-auditor-1.2.3.aam
βββ registries/ # Cached registry indexes
βββ aam-central/
βββ index.yaml
credentials.yaml format (sensitive β chmod 600):
# ~/.aam/credentials.yaml β DO NOT COMMIT
registries:
aam-central:
token: "aam_tok_abc123..."
expires: "2026-08-05T14:30:00Z"
private-registry:
token: "aam_tok_xyz789..."my-project/
βββ .aam/
β βββ config.yaml # Project configuration
β βββ aam-lock.yaml # Lock file (committed to git)
β βββ packages/ # Installed packages (local state)
β βββ @author/ # Scoped packages nested under @scope/
β β βββ asvc-auditor/
β β β βββ aam.yaml
β β β βββ agents/
β β β βββ skills/
β β β βββ prompts/
β β βββ generic-auditor/
β β βββ aam.yaml
β β βββ skills/
β βββ report-templates/ # Unscoped packages at top level
β βββ aam.yaml
β βββ skills/
β βββ instructions/
βββ .cursor/ # Deployed Cursor artifacts
β βββ skills/
β β βββ author--asvc-report/ # Scoped: scope--name format
β β βββ author--generic-auditor/
β βββ rules/
β β βββ agent-author--asvc-audit.mdc
β β βββ asvc-coding-standards.mdc
β βββ prompts/
β βββ audit-finding.md
β βββ audit-summary.md
βββ CLAUDE.md # Deployed Claude instructions (sections)
βββ .claude/
β βββ agents/ # Deployed Claude agents
βββ .github/
βββ agents/ # Deployed Copilot agents
βββ instructions/ # Deployed Copilot instructions
| Path | Commit? | Reason |
|---|---|---|
.aam/config.yaml |
Yes | Project settings shared with team |
.aam/aam-lock.yaml |
Yes | Reproducible installs |
.aam/packages/ |
No (.gitignore) | Re-downloaded on aam install |
.cursor/skills/ |
Yes | Deployed artifacts should be in repo |
.cursor/rules/ |
Yes | Deployed artifacts should be in repo |
CLAUDE.md |
Yes | Deployed artifacts should be in repo |
AAM auto-generates appropriate .gitignore entries.
aam/
βββ __init__.py
βββ __main__.py # Entry point: python -m aam
βββ cli/
β βββ __init__.py
β βββ main.py # Click/Typer CLI app
β βββ pkg/ # aam pkg command group (create, validate, pack, publish, build)
β βββ install.py # aam install command
β βββ init.py # aam init command
β βββ deploy.py # aam deploy command
β βββ publish.py # aam pkg publish command
β βββ search.py # aam search command
β βββ config.py # aam config command
β βββ register.py # aam register command (HTTP registry)
β βββ login.py # aam login / logout commands
β βββ yank.py # aam yank command
βββ core/
β βββ __init__.py
β βββ manifest.py # aam.yaml parsing and validation
β βββ package.py # Package model
β βββ artifact.py # Artifact models (Skill, Agent, Prompt, Instruction)
β βββ resolver.py # Dependency resolution
β βββ installer.py # Download + extract + deploy orchestration
β βββ version.py # Semver parsing and constraint matching
β βββ auth.py # Token management and credentials
βββ signing/
β βββ __init__.py
β βββ checksum.py # SHA-256 calculation and verification
β βββ sigstore.py # Sigstore signing/verification
β βββ gpg.py # GPG signing/verification
βββ registry/
β βββ __init__.py
β βββ base.py # Registry interface
β βββ git.py # Git-based registry
β βββ http.py # HTTP registry client
β βββ local.py # Local filesystem registry
βββ mcp/
β βββ __init__.py
β βββ server.py # FastMCP server instance and entry point
β βββ tools.py # @mcp.tool definitions (wrapping CLI core logic)
β βββ resources.py # @mcp.resource definitions (read-only data providers)
βββ adapters/
β βββ __init__.py
β βββ base.py # Platform adapter interface
β βββ cursor.py # Cursor deployment
β βββ copilot.py # GitHub Copilot deployment
β βββ claude.py # Claude deployment
β βββ codex.py # OpenAI Codex deployment
βββ utils/
βββ __init__.py
βββ archive.py # .aam archive creation/extraction
βββ yaml_utils.py # YAML helpers
βββ paths.py # Path resolution utilities
| Component | Choice | Rationale |
|---|---|---|
| Language | Python 3.11+ | Matches target audience, easy to install via pip |
| CLI framework | Typer | Modern, type-annotated CLI with auto-generated help |
| YAML parsing | PyYAML + pydantic | Schema validation with pydantic models |
| Archive format | tar.gz (renamed .aam) | Simple, universal, transparent |
| Version parsing | packaging library | Standard Python semver implementation |
| Git operations | subprocess (git CLI) | No heavy dependencies, git is ubiquitous |
| HTTP | httpx (optional) | Lazily imported only when an HTTP registry is configured |
| Rich output | rich | Beautiful terminal output, progress bars, trees |
| Signing | sigstore | Keyless signing via OIDC (Sigstore ecosystem) |
| GPG | python-gnupg | GPG key-based signing for traditional workflows |
| MCP server | FastMCP 2.0+ (fastmcp) |
High-level MCP framework with decorator API, built-in stdio/HTTP transports, Pydantic validation, tag-based filtering, and testing utilities |
flowchart TD
User["User: aam install asvc-auditor"]
CLI["CLI (install)<br/>Parse args, load config"]
Registry["Registry (resolve)<br/>Search registries for package<br/>Download metadata.yaml"]
Resolver["Resolver (dependencies)<br/>Build dependency graph<br/>Resolve version constraints"]
Download["Installer (download)<br/>Download .aam archives<br/>Download signatures"]
Verify["Signing (verify)<br/>Verify SHA-256 checksum<br/>Verify signatures per policy"]
Extract["Installer (extract)<br/>Extract to .aam/packages/<br/>Write lock file"]
Deploy["Adapter (deploy)<br/>For each active platform:<br/>Transform & copy artifacts"]
Summary["Summary (report)<br/>Print installed packages<br/>Show deployed locations"]
User --> CLI
CLI --> Registry
Registry --> Resolver
Resolver --> Download
Download --> Verify
Verify --> Extract
Extract --> Deploy
Deploy --> Summary
style User fill:#e8f5e9
style Summary fill:#e8f5e9
# --- Manifest Model ---
@dataclass
class ArtifactRef:
name: str
path: str
description: str
@dataclass
class PackageManifest:
name: str # Full name: "pkg" or "@scope/pkg"
scope: str # Scope part: "" for unscoped, "author" for @author/pkg
version: str
description: str
author: str | None
license: str | None
repository: str | None
keywords: list[str]
artifacts: dict[str, list[ArtifactRef]] # type -> refs
dependencies: dict[str, str] # name -> constraint (keys may be scoped)
platforms: dict[str, dict] # platform -> config
# --- Resolver ---
@dataclass
class ResolvedPackage:
name: str
version: str
source: str
checksum: str
manifest: PackageManifest
class Resolver:
def resolve(self, root: PackageManifest) -> list[ResolvedPackage]: ...
# --- Platform Adapter ---
class PlatformAdapter(Protocol):
name: str
def deploy_skill(self, skill_path: Path, skill_ref: ArtifactRef, config: dict) -> Path: ...
def deploy_agent(self, agent_path: Path, agent_ref: ArtifactRef, config: dict) -> Path: ...
def deploy_prompt(self, prompt_path: Path, prompt_ref: ArtifactRef, config: dict) -> Path: ...
def deploy_instruction(self, instr_path: Path, instr_ref: ArtifactRef, config: dict) -> Path: ...
def undeploy(self, artifact_name: str, artifact_type: str) -> None: ...
def list_deployed(self) -> list[tuple[str, str, Path]]: ...
# --- Registry ---
class Registry(Protocol):
name: str
def search(self, query: str) -> list[PackageMetadata]: ...
def get_metadata(self, name: str) -> PackageMetadata: ...
def get_versions(self, name: str) -> list[str]: ...
def download(self, name: str, version: str, dest: Path) -> Path: ...
def publish(self, archive_path: Path) -> None: ...The CLI contains a registry abstraction layer that decouples commands from any specific registry backend. This enables the local-first architecture: commands like aam search, aam install, and aam pkg publish work identically against local, git, or HTTP registries.
aam_cli/
βββ registry/
β βββ __init__.py
β βββ base.py # Registry Protocol/ABC β defines the interface
β βββ local.py # LocalRegistry β pure file I/O, no network
β βββ git.py # GitRegistry β git clone + local structure
β βββ http.py # HTTPRegistry β calls aam-backend REST API
β βββ factory.py # Instantiate registry from config type string
β βββ resolver.py # Search registries in configured order
Registry Protocol (base.py):
class Registry(Protocol):
"""Abstract registry interface β implemented by local, git, and HTTP backends."""
name: str
def search(self, query: str) -> list[PackageMetadata]: ...
def get_metadata(self, name: str) -> PackageMetadata: ...
def get_versions(self, name: str) -> list[str]: ...
def download(self, name: str, version: str, dest: Path) -> Path: ...
def publish(self, archive_path: Path) -> None: ...Factory (factory.py):
Instantiates the correct registry class from the type field in config.yaml:
| Config Type | Class | Dependencies |
|---|---|---|
local |
LocalRegistry |
None (stdlib only) |
git |
GitRegistry |
git CLI |
http |
HTTPRegistry |
httpx (imported lazily) |
This scenario demonstrates the full AAM workflow using only local registries β no Docker, no Postgres, no server.
# 1. Create a local registry (one-time setup)
aam registry init ~/my-packages
aam registry add local file:///home/user/my-packages --default
# 2. Author creates a package
cd my-project/
aam pkg create
aam pkg validate
aam pkg pack # produces my-agent-1.0.0.aam
# 3. Publish to local registry (no server needed)
aam pkg publish --registry local # copies .aam, updates metadata.yaml + index.yaml
# 4. Another developer installs it (same machine or shared filesystem)
cd other-project/
aam search "audit" # searches index.yaml locally
aam install @myorg/my-agent # copies from local registry, deploys to .cursor/
# 5. Works across a team via shared drive / NFS / git
# The entire registry is just a directory β sync it however you wantThis entire workflow requires only Python and the aam CLI. No Docker, no database, no Redis, no server process.
$ mkdir asvc-auditor && cd asvc-auditor
$ aam init
# ... interactive prompts ...
$ tree
asvc-auditor/
βββ aam.yaml
βββ agents/
βββ skills/
βββ prompts/
βββ instructions/$ mkdir -p skills/asvc-report/scripts skills/asvc-report/referencesWrite skills/asvc-report/SKILL.md:
---
name: asvc-report
description: Generate ASVC compliance audit reports with structured findings, risk ratings, and remediation guidance. Use when performing ASVC audits or generating compliance documentation.
---
# ASVC Report Generator
## Workflow
1. Analyze target artifacts against ASVC controls
2. Document findings using the audit-finding prompt
3. Run report generation script
4. Review and finalize
## Scripts
- `scripts/generate_report.py` β generates formatted report from findings JSON
## References
- See [references/asvc-framework.md](references/asvc-framework.md) for ASVC control details$ mkdir -p agents/asvc-auditWrite agents/asvc-audit/agent.yaml:
name: asvc-audit
description: "Agent specialized in ASVC compliance auditing"
system_prompt: system-prompt.md
skills:
- asvc-report
- generic-auditor
prompts:
- audit-finding
- audit-summary
tools:
- file_read
- file_write
- shellWrite agents/asvc-audit/system-prompt.md:
You are an ASVC compliance auditor...Write prompts/audit-finding.md and prompts/audit-summary.md.
In aam.yaml, add:
dependencies:
"@author/generic-auditor": ">=1.0.0"$ aam pkg validate
β Package is valid
$ aam pkg pack
β Built asvc-auditor-1.0.0.aam
$ aam pkg publish
β Published asvc-auditor@1.0.0$ cd my-project/
$ aam install @author/asvc-auditor
Resolving @author/asvc-auditor@1.0.0...
+ @author/asvc-auditor@1.0.0
+ @author/generic-auditor@1.2.3 (dependency)
Deploying to cursor...
β skill: asvc-report β .cursor/skills/author--asvc-report/
β skill: generic-auditor β .cursor/skills/author--generic-auditor/
β agent: asvc-audit β .cursor/rules/agent-author--asvc-audit.mdc
β prompt: audit-finding β .cursor/prompts/audit-finding.md
β prompt: audit-summary β .cursor/prompts/audit-summary.md
Installed 2 packages, deployed 5 artifactsNow the user opens Cursor, and the ASVC auditor agent is fully configured with its skills, prompts, and instructions ready to use.
Phase 1 ships a fully working tool with zero infrastructure requirements. All features work against local file-based registries.
- Core manifest parsing (
aam.yamlwith pydantic validation) - Namespace/scope support (
@author/package-name) in manifest, CLI, and registry -
aam pkg createβ create package from existing project (autodetect + interactive selection) -
aam initβ interactive package scaffolding (with optional--scope) -
aam pkg validateβ manifest and artifact validation -
aam pkg packβ build.aamarchive -
aam registry initβ create local registry -
aam pkg publish --registry localβ publish to local registry -
aam searchβ search local registry -
aam installβ install from local registry,.aamfile, or directory - Cursor adapter β deploy skills, agents (as rules), prompts, instructions
- Dependency resolution (local registries only)
- Lock file generation
- Git-based registry (read-only: search, download)
- HTTP registry client (
aam/registry/http.py) -
aam registerβ create registry account -
aam login/aam logoutβ authentication -
aam pkg publishβ publish to registry -
aam pkg publish --signβ publish with Sigstore/GPG signature -
aam searchβ search registry index - Package signing and verification (checksum always, Sigstore/GPG optional)
- Claude adapter
- GitHub Copilot adapter
- Lock file generation
-
aam listandaam infocommands
- Codex adapter
-
aam updateβ update packages -
aam uninstallβ clean removal -
aam deploy/aam undeployβ separate deploy lifecycle - Shell completion (bash/zsh/fish)
-
aam doctorβ environment diagnostics - FastMCP dependency and
mcp/module scaffold - MCP stdio server mode (
aam mcp serve) - MCP tool definitions for core CLI commands (read-only tools first)
- MCP tool definitions for write operations (install, publish, config set)
- MCP resource providers for config, packages, registries, manifest
- Tag-based safety model (read-only default,
--allow-writeopt-in) - IDE integration documentation and example configs (Cursor, VS Code)
- MCP server tests using FastMCP's
Clienttesting utilities
-
aam yankβ mark version as yanked (HTTP registry only) - Registry attestations (automated trust)
-
aam-lock.yamlintegrity verification - Plugin system for community-contributed adapters
- Multi-version dependency support (if needed)
- Prompt variable interpolation at deploy time
| Feature | AAM | pip | npm | Codex skill-installer |
|---|---|---|---|---|
| Artifact types | 4 (skill, agent, prompt, instruction) | 1 (Python package) | 1 (JS package) | 1 (skill) |
| Multi-platform deploy | Yes (Cursor, Copilot, Claude, Codex) | No | No | No |
| Dependency resolution | Yes (semver) | Yes | Yes | No |
| Registry | Git-based + local | PyPI | npm registry | GitHub repo |
| Package format | .aam (tar.gz) | .whl/.tar.gz | .tgz | .skill (zip) |
| Lock file | Yes | Yes (pip-tools) | Yes | No |
| Complexity | Simple | Medium | Complex | Minimal |
| Entity | Convention | Example |
|---|---|---|
| Package name (unscoped) | lowercase, hyphens, max 64 chars | asvc-auditor |
| Package name (scoped) | @scope/name, max 130 chars total |
@author/asvc-auditor |
| Scope name | lowercase, hyphens, underscores, max 64 chars | author, my_org |
| Artifact name | lowercase, hyphens, max 64 chars | asvc-report |
| Version | Semantic versioning | 1.0.0 |
| Archive file | {name}-{version}.aam |
asvc-auditor-1.0.0.aam |
| Cursor rule file | {type}-{fs-name}.mdc |
agent-author--asvc-audit.mdc |
| Filesystem name (scoped) | scope--name (double-hyphen) |
author--asvc-report |
| Registry package dir (unscoped) | packages/{name}/ |
packages/asvc-auditor/ |
| Registry package dir (scoped) | packages/@{scope}/{name}/ |
packages/@author/asvc-auditor/ |
| Variable | Description | Default |
|---|---|---|
AAM_HOME |
AAM home directory | ~/.aam |
AAM_DEFAULT_PLATFORM |
Default deployment platform | cursor |
AAM_REGISTRY |
Override default registry URL | community registry |
AAM_CACHE_DIR |
Package cache directory | ~/.aam/cache |
AAM_NO_COLOR |
Disable colored output | (unset) |
GITHUB_TOKEN / GH_TOKEN |
Auth for private git registries | (unset) |