Browse the documentation

Preview documentation for AEL Beta 0.0.1 — launching soon

Manifest reference

pack.ael will be the manifest of AEL, the Agent Engineering Language: the one file that says which packages a project, or one folder of it, uses. It will be a declarative record, never code. It will have no expressions, no includes and no scripts, and nothing in it will run. # comments will be allowed. Using packages explains how manifests and folder scopes will work together.

Status

Planned for AEL Beta 0.0.1. AEL is not available yet.

Package names on this page are preview naming and may change before launch.

Top-level fields

Preview syntax — may change before launch
pack {
    schema = 1;
    dependencies = [
        { name = "server/http"; version = "^1.2.0"; kind = "runtime";
          source = { kind = "registry"; };
          features = []; targets = []; capabilities = ["net.listen"];
          publisher = "openeng"; }
    ];
}
FieldRequiredMeaning
schemaYesThe format version: 1.
dependenciesYesThe packages this scope uses. [] for none.
toolchainNoThe AEL toolchain versions the project accepts, written like a version requirement. It will be checked before anything is resolved.
registriesNoPackage registries and their publishers. The official registry will be the default and will need no entry.

Unknown and repeated fields will be refused. The project's name, description and settings will belong in metadata.ael, never in pack.ael.

Dependency fields

Every dependency will name each of these fields, even when a list is empty:

FieldMeaning
nameThe package name, such as "server/http". See Names and aliases.
versionA version requirement, such as "^1.2.0".
kind"runtime", "build" or "development". See Kinds.
sourceWhere the package file comes from. See Sources.
featuresThe package features you ask for, by name. [] for none.
targetsThe targets this dependency applies to. [] for all of the package's targets.
capabilitiesThe permissions the package asks for, such as "net.listen". [] for none.
publisher"openeng" for official packages; your own publisher name for private ones.
aliasOptional: a local name for the package in your source.

Version requirements

RequirementAcceptsExample
=M.m.pExactly that version."=1.2.3"
^M.m.pCompatible versions: the same major version from 1 up; the same minor version while the major is 0; only that version for 0.0.p."^1.2.3" accepts 1.2.3 up to, not including, 2.0.0
~M.m.pPatch updates within the same minor version."~1.2.3" accepts 1.2.3 up to, not including, 1.3.0
>=A <BA range with both bounds.">=1.2.0 <2.0.0"
  • There will be no wildcards, no "or" and no requirement without an operator. Numbers will have no leading zeros, and each will be at most 2,147,483,647. Versions will compare number by number, never as text.
  • A pre-release, such as 1.3.0-rc.1, will be chosen only when you name it exactly with =. Build metadata after a + will be refused.
  • Adding, updating and locking will choose the highest version that fits. Installing and building will never choose again: they will use the lock file.
  • One scope will use one version of each package.

Sources

kindFieldsFor
"registry"origin, optional; it defaults to https://pack.ael.openeng.aiOfficial packages from the official registry.
"https"url and digestA private package file at an https address that never changes.
"local"path and digestA private package file kept inside the project.

digest will be the file's fingerprint: sha256: followed by 64 lower-case hex digits. There will be no source that points at code to be built: every source will be a built package file. Private packages gives the rules for addresses and paths.

Kinds

  • "runtime": part of your program.
  • "build": an explicit input for your builds that never becomes part of your program. It will never run inside the compiler, as an install script or by itself during a build, which runs no package code. What a build dependency will provide, and how you will use one, will be described when the manifest format is final.
  • "development": used for tests and development only. It will never reach your program unless it is also declared as a runtime dependency.

Features and targets

  • A package will have no default features: you will get exactly the features you list. An unknown feature will be refused.
  • When two packages in one scope ask for different features of a shared package, it will get the features that were explicitly requested, combined. Adding or updating will show any dependencies and capabilities that this brings.
  • targets will list exact target names; see Planned targets. A dependency limited to other targets will stay in the lock file but be left out of builds for your target.

Capabilities and publishers

  • capabilities will be a request, never a grant. Your deployment will decide what a program may actually do, and a package will still receive only what your code passes to it. See Effects and capabilities.
  • publisher will have to match the publisher the package itself records. Only official packages from the official registry will carry "openeng".

Names and aliases

  • Package names will be lower case and slash-separated, such as server/http or acme/billing. Each part will start with a letter and continue with letters, digits, _ or -. A name will be at most 128 characters.
  • AEL will never guess at a misspelled name or substitute a similar-looking one: an unknown name will be an error.
  • alias will be an AEL identifier. It will not be allowed to be a keyword, _ or print, and two aliases in one scope will not be allowed to differ only in letter case.

Limits

  • Every pack.ael will stay within the limits of every source file: at most 5,000 bytes and at most 5,000 lines. Split a long list of dependencies into folder scopes. See Limits.
  • The planned resolution limits for one scope are 1,024 packages and 8,192 dependency links, with no chain of dependencies more than 64 links long. Going over will be an error, never a partial result.
  • A dependency cycle will be refused, and the error will name the whole cycle.

The lock file

pack.lock will be generated beside each pack.ael by ael pack add, ael pack update and ael pack lock (command names may change before launch), and read by ael pack install --locked. It will record:

  • the exact version, origin, publisher and fingerprint of every package in the scope, direct or not;
  • how the packages depend on each other;
  • the features and targets chosen;
  • which manifest it belongs to.

With it, builds will repeat, even offline, and nothing will download when an app starts. Never edit it by hand: if it no longer matches its manifest, ael pack install --locked will stop instead of changing it. It will never hold secrets, access tokens or absolute paths.

The data of a manifest and of a lock file each have a published JSON Schema, still a draft: Package manifest and Package lock file. The manifest schema describes the parsed data; pack.ael itself will always be written as shown above.