Skip to content
Back to skills

Ailang Packages

ASecurity

Create, validate, and publish AILANG packages with correct conventions. Use when user asks to create a new package, fix package errors, add dependencies, publish to registry, or import packages. Also use when encountering `IMP010`, `LDR001`, `MOD010`, or `export type` errors during package development.

  • 34 stars
  • 0 votes
  • 0 copies
  • 2 views
  • Added September 2, 2026
ai-agentsbashdockertestinggitapidocumentation

Works with

  • cli
  • api

Security analysis

A100/100

Pro scans all 4 files and shows the line behind each finding

Scanned October 3, 2026

npx -y skills add sunholo-data/ailang --skill ailang-packages --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Ailang Packages?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Ailang Packages
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/sunholo-data-ailang-packages-ailang/badge)](https://www.skillsdirectory.com/skills/sunholo-data-ailang-packages-ailang)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: ailang-packages
description: Create, validate, and publish AILANG packages with correct conventions. Use when user asks to create a new package, fix package errors, add dependencies, publish to registry, or import packages. Also use when encountering `IMP010`, `LDR001`, `MOD010`, or `export type` errors during package development.
---

# AILANG Package Development

Create, validate, and publish AILANG packages with correct conventions. Use when user asks to create a new package, fix package errors, add dependencies, publish to registry, or import packages. Also use when encountering `IMP010`, `LDR001`, `MOD010`, or `export type` errors during package development.

## When to Use This Skill

- User wants to create a new AILANG package
- User encounters package-related errors (IMP010, LDR001, MOD010, type unification across packages)
- User asks about `ailang.toml`, `ailang.lock`, package imports, or package publishing
- User wants to add dependencies between packages
- User asks "how do I import from another package" or "how do I export types"
- Code has `import pkg/` or `import ./` paths that aren't resolving

## Start with the installed binary

Read `ailang docs package-authoring` first. If unavailable on an older binary,
read the **whole** `ailang prompt`, including its contracts, testing and package
sections. Use `ailang docs --all-functions <term>` and `ailang pkg-docs --help`
before web search or guessing APIs. Verify historic limitations with a minimal
reproducer against the installed version.

## Native quality evidence

Separate pure logic from effectful adapters. Use ADTs for closed states/errors,
meaningful requires/ensures for pure functions, boundary/invalid examples in
native tests and properties for algebraic invariants. Declare minimal effect
ceilings and bounded effect counts with @limit where meaningful. Never add
vacuous contracts just to satisfy a count.

Run `ailang pkg quality --strict .` for the package quality report: compile,
contracts, interface, effects, docs, style, and attested *_test.ail tests and
smoke. It does **not** run inline test blocks in source modules, and it is not
coverage or proof. Older binaries lacking this command require a manual
evidence review; report that limitation explicitly.

`ailang test --package .` only discovers *_test.ail. Run source modules with
inline tests explicitly (`ailang test module.ail`) too. A plain function named
test_* is not a native test declaration. Report actual totals, failures and skips;
zero discovered tests does not validate behavior. Use `ailang verify --help` for
SMT verification and report proved/unknown/skipped outcomes separately.

## Quick Reference

### Create a Package

```bash
ailang init package --name vendor/name
ailang init package --name sunholo/mylib --module-prefix mylib --dep sunholo/config
```

### Install Dependencies

```bash
ailang install sunholo/auth           # Install latest version (resolves from registry)
ailang install sunholo/auth@latest    # Same as above
ailang install sunholo/auth@0.1.0     # Install exact version
```

`@latest` resolves once and writes the **exact version** to `ailang.toml`. Semver ranges (`^`, `~`, `>=`) are not supported — AILANG requires exact versions in manifests for determinism.

### Package Lifecycle

```bash
ailang lock                    # Resolve dependencies → ailang.lock
ailang check --package .       # Type-check all modules (cross-module resolution)
ailang test --package .        # Run *_test.ail files
ailang pkg quality --strict .  # Inventory missing authoring evidence
ailang publish --dry-run       # Packaging preview, not remote validation or proof
ailang publish                 # Publish to registry
```

## Critical Rules (learned from production)

### 1. Module names use underscores, never hyphens

Hyphens parse as subtraction. Directory names can have hyphens, but module paths must use underscores.

```
Directory:  packages/billing-store/
Module:     module sunholo/billing_store/customers_repo
Import:     import pkg/sunholo/billing_store/customers_repo (getCustomer)
```

### 2. Use `./` for intra-package sibling imports

Three-way import distinction — locality is explicit at the point of use:

```ailang
import ./plan (Plan, lookupPlan)              -- LOCAL: sibling in same package
import pkg/sunholo/firestore/client (getDoc)  -- EXTERNAL: different package
import std/result (Ok, Err)                   -- STDLIB: bundled
```

`./` resolves in **module namespace** (not filesystem): if current module is `sunholo/billing_entitlements/entitlement`, then `./plan` normalizes to `sunholo/billing_entitlements/plan`.

```ailang
import ./plan (Plan, lookupPlan, freePlan)    -- sibling
import ./sub/helpers (validate)               -- child directory
```

`pkg/` self-imports also work (backward compatible) but `./` is preferred.

### 3. Cross-package types MUST use `export type`

Types used by other packages need `export type`, not just `type`. Without it, consumers get `IMP010: symbol not exported`.

```ailang
-- WRONG: only visible within this module
type Customer = { name: string, email: string }

-- CORRECT: visible to importing packages
export type Customer = { name: string, email: string }
```

This applies to record types AND ADTs:
```ailang
export type ProposalStatus = PendingApproval | AwaitingPayment | Approved
export type RequestedBy = Human | Agent(string)
```

### 4. Always import `Ok` and `Err` explicitly

They are NOT in the auto-imported prelude:
```ailang
import std/result (Ok, Err)
```

### 5. Package name is vendor/name format (exactly 2 segments)

```toml
[package]
name = "sunholo/firestore"    # CORRECT
name = "firestore"            # WRONG — single segment
name = "sunholo/billing/store" # WRONG — 3 segments
```

### 6. Use `module_prefix` for existing apps adopting packages

If your project uses `module myapp/...` but you want to publish as `sunholo/myapp`:

```toml
[package]
name = "sunholo/myapp"
module_prefix = "myapp"

[exports]
modules = ["myapp/services/api", "myapp/handlers/parse"]
```

Zero source changes needed — existing `module myapp/...` declarations work as-is.

### 7. Publishing rewrites path deps automatically

`ailang publish` automatically rewrites path deps (`{ path = "../firestore" }`) to registry version strings (`"0.1.0"`) in the tarball. Your local `ailang.toml` is restored after. You don't need to change deps manually before publishing.

**Publish in dependency order**: packages with no deps first, then packages that depend on already-published packages.

## ailang.toml Reference

See [resources/manifest_reference.md](resources/manifest_reference.md) for full field documentation.

```toml
[package]
name = "sunholo/billing_store"
version = "0.2.0"
edition = "1"
ailang = ">=0.9.5"              # optional: minimum AILANG version
module_prefix = "myapp"         # optional: for existing apps
description = "Firestore CRUD for billing records"
license = "Apache-2.0"

[exports]
modules = [
  "sunholo/billing_store/customers_repo",
  "sunholo/billing_store/subscriptions_repo"
]

[dependencies]
# Path deps (local development):
"sunholo/firestore" = { path = "../firestore" }
# Git deps (version pinned):
# "sunholo/firestore" = { git = "https://github.com/sunholo-data/ailang-packages", subdir = "packages/firestore", tag = "main" }
# Registry deps (published packages — use exact versions only, no ranges):
# "sunholo/firestore" = "0.1.0"
# Install latest: ailang install sunholo/firestore

[effects]
max = ["Net", "FS", "Env"]     # effect ceiling — functions can't exceed this

[metadata]
tags = ["billing", "firestore"]
ai_summary = "Firestore CRUD for billing records"

[stability]
level = "experimental"          # experimental | stable | frozen

[bin]                           # optional: commands `ailang install` shims onto PATH (~/.ailang/bin)
billing = "cli"                 # module sunholo/billing_store/cli, entry main, caps auto
# billing = { module = "cli", entry = "main", caps = "IO,Env", run_flags = ["--process-timeout", "5m"] }
```

### Shipping a command (`[bin]`, v0.40.1)

Never write a `scripts/` or `bin/` launcher that `cd`s into a checkout and `ailang run`s a
file — that is exactly what `[bin]` replaces. Declare the module; `ailang install` writes the
package's lock beside its cached manifest and a shim that runs it from any cwd.

```bash
ailang install --path .          # developer loop: shim THIS checkout, no publish
ailang bin list                  # (= ailang pkg bin list) installed shims with package@version
ailang bin uninstall billing
```

The entry reads its arguments with `std/env` `getArgs()`; `ailang publish` refuses a bin
whose module is missing or whose entry is not exported.

### Lock File Portability

Registry and git lock entries resolve from the local cache (`~/.ailang/cache/`). Path dependencies are recorded relative to the depending `ailang.toml` (forward slashes), so a lock stays valid when the whole tree is cloned or moved — but only if the dependency is inside that tree (a sibling repo is not in a CI clone). `ailang lock --check` verifies the committed lock without writing; it flags a lock from an older ailang that still names an absolute path, and `ailang lock` rewrites it relative.

**Docker workflow:**
```dockerfile
COPY ailang.toml ailang.lock .
RUN ailang install sunholo/auth    # Populates cache from lock file versions
```

**Key facts:**
- Lock file stores: name, version, content hash, source type, git URL/rev
- Registry/git entries do not need absolute cache paths; local path entries are workspace-specific
- `ailang install` populates the cache; `ailang lock` resolves + downloads
- Old lock files with stored paths still work (backward compatible)

### Version Conflict Detection

The resolver enforces **flat dependencies** — one version per package name. If a transitive dependency requires a different version than the root manifest pins, `ailang lock` fails with a structured error:

```
version conflict: sunholo/firestore
  root requires: 0.2.0
  already resolved: 0.1.0
  transitive requires: 0.1.0 (via sunholo/billing_store)

resolution aborted

suggestion:
  - republish sunholo/billing_store against sunholo/firestore@0.2.0
  - or change root dependency to sunholo/firestore@0.1.0 explicitly
```

**Resolution rules:**
- Direct dependencies in the root `ailang.toml` are **authoritative**
- Transitive dependencies must match the direct pin exactly
- If they conflict, the resolver fails (never silently downgrades)
- Same version from multiple sources is fine (silently deduplicated)

**How to fix version conflicts:**
1. Republish the transitive package against the version you need
2. Or change your root `ailang.toml` to match the transitive version
3. The error message tells you exactly which package introduced the conflict

## Common Error Solutions

See [resources/error_solutions.md](resources/error_solutions.md) for full troubleshooting guide.

| Error | Cause | Fix |
|-------|-------|-----|
| `version conflict: pkg` | Direct and transitive deps disagree on version | Republish transitive dep or change root pin (see error message) |
| `IMP010: symbol not exported` | Type missing `export` keyword | Add `export type Foo = ...` |
| `LDR001: module not found` | Missing dependency or wrong import path | Add dep to ailang.toml + `ailang lock` |
| `cannot unify type constructor X with TRecord` | Type alias not exported across packages | Add `export type` to the defining module |
| `package not found in ailang.lock` | Dependencies not resolved | Run `ailang lock` |
| `PAR_HYPHEN_IN_MODULE` | Hyphen in module path | Use underscores: `billing_store` not `billing-store` |
| `Key has already been defined` | Duplicate dep entry in ailang.toml | Remove duplicate, keep one format |

## Publishing Checklist

1. All modules pass: `ailang check --package .`
2. Dependencies are listed in `[dependencies]` (path deps OK — publish rewrites them)
3. Exported types have `export type`
4. `[exports].modules` lists all public modules
5. `[effects].max` includes all effects used
6. `AGENT.md` exists with usage guide
7. Native tests/properties have been executed with totals and skips reviewed; source inline tests run explicitly
8. Meaningful contracts and effect budgets reviewed; proof outcomes recorded separately
9. `ailang pkg quality --strict .` reports no missing evidence, or gaps are explicitly documented (do not claim the strict gate passed)
10. Publish in dependency order (leaf packages first)

`publish --dry-run` returns before remote registry validation. It is packaging evidence, not a test or proof gate.

## Registry Validator

The registry validator (`/version` endpoint shows deployed version):
- Runs `ailang check --package .` on uploaded tarballs
- Rewrites any remaining path deps to registry versions (safety net for older clients)
- Runs `ailang lock` to download deps from registry before checking
- Validates compilation, effect ceilings, and contracts

## Workflow

1. **Read** [resources/manifest_reference.md](resources/manifest_reference.md) for ailang.toml details
2. **Read** [resources/error_solutions.md](resources/error_solutions.md) when encountering errors
3. **Run** `scripts/validate_package.sh` after creating a package
4. **Follow** the critical rules above — they prevent the most common failures

Files in this skill

  • SKILL.md9.8 KB
  • resources/error_solutions.md4.5 KB
  • resources/manifest_reference.md3.7 KB
  • scripts/validate_package.sh684 B

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.