apac is the Aussom Package Manager. It installs, removes, lists, searches,
packages, and publishes Aussom packages. It ships alongside the aussom CLI
in the same OS installer (deb, dmg, msi) and runs as its own binary. apac and
the aussom interpreter are sibling programs; they only meet on disk through
the shared .aussom/modules/ layout that apac populates.
This guide starts with the everyday commands (search, install, list, uninstall) and progresses to the more advanced flows (publishing your own packages, building each of the three package types). The first half covers what most users need; the second half is reference material for package authors.
| Concept | Meaning |
|---|---|
| Project deps | Packages installed under <project>/.aussom/modules/. Pinned in <project>/aussom.lock. The default install target. |
| System-globals | Packages installed once per machine in an OS-specific shared directory. Selected with -g. |
aussom.lock |
YAML lockfile pinning every transitive dependency to one exact version. Checked into source control. |
package.yaml |
Manifest at the root of a package source tree. Names, describes, and lists the package's own dependencies. |
apac.yaml |
apac's config file. Holds the registry URL and your publish key. Lives next to the system-globals modules directory. |
| Package type | One of pure, jvm, or native. Describes what file kinds the package is allowed to ship. |
| Registry | The HTTPS server apac talks to for search, list, download, and publish. Default: https://apac.aussom-lang.com. |
After installing Aussom from the OS package, the apac command is on your
path. Run apac -h for the built-in help, or apac -v to print the version.
Most apac commands operate on a target directory:
-g, the target is the current working directory. The first
install in a directory creates <cwd>/.aussom/modules/ and
<cwd>/aussom.lock.-g, the target is the system-globals directory for your platform.
Writing there requires elevation (sudo on Linux and macOS, UAC on Windows).apac -l, apac -s, apac -p, and apac -pub do not use a target;
they read from or write to the registry, or to a path you hand in.
apac -s socket
This calls the registry's search endpoint and prints a flat table with one package per row. Columns are name, latest version, type, and description. The output is plain text, so you can pipe it through other tools:
apac -s socket | grep tls
If the registry returns more than 200 hits, apac appends a trailing line
telling you the result was clipped and suggesting a more specific query.
If nothing matches, apac prints No packages match "<query>". and exits 0.
apac -l queries the registry. It takes two shapes:
apac -l socket
Prints one row per published version of socket, with each version's status
(normal, deprecated, or vulnerable) and a latest marker on the
highest semver normal release.
apac -l socket@1.0.5
Prints the full manifest for that exact version: description, license, author, author email, type, repository, homepage, keywords, dependencies, published-at, published-by, status, and status reason. Empty registry fields are omitted from the output.
-l always talks to the registry, so -g is not allowed with it.
The most common command. Without -f, the argument is a registry name:
apac -i socket
apac fetches the latest version of socket from the registry, resolves its
transitive dependencies against the existing aussom.lock, downloads each
package, extracts them into <cwd>/.aussom/modules/, and updates
aussom.lock with the chosen versions.
To pin a specific version, append @<version>:
apac -i socket@1.0.5
apac -i is "ensure installed," not "upgrade." When you pin an explicit
version, apac will not re-download files that are already on disk at that
version. The rules:
| Scenario | Behavior |
|---|---|
| Package not installed | Fetch, install, pin in lockfile. |
apac -i <name>@<version>, same version installed |
Resolver runs against the existing lockfile, no files are fetched or extracted, lockfile is rewritten with the same pin. |
apac -i <name>@<version>, different version installed |
Replace: delete the existing package directory, extract the new version into a fresh directory, update the pin. |
The version-swap path does not invoke the formal uninstall flow, so the
dependent-warning scan that apac -u performs does not fire on a swap.
To bump a package, give the explicit version: apac -i socket@1.0.6.
If you already have a zip on disk (one you built with apac -p or one a
coworker handed you), install it with -f:
apac -f -i socket-1.0.5.zip
apac extracts the zip into <target>/.aussom/modules/<name>/. Transitive
dependencies still resolve through the registry. Local directory installs
(passing a folder instead of a zip) are not supported; package first with
apac -p, then install the resulting zip.
If you know a version the resolver rejects actually works for your project,
-fc bypasses the compatibility check:
apac -fc -i socket@2.0.0
apac prints a loud warning naming the conflicting constraint, installs the
version anyway, and records forced: true on the lockfile entry. Subsequent
apac -i runs respect the existing pin without repeating the warning. The
flag only applies to -i. To revert, uninstall and reinstall without -fc.
Once apac -i socket finishes, your project tree looks like this:
<project>/
aussom.lock
.aussom/
modules/
socket/
package.yaml
aussom-socket.jar
socket.aus
...
The aussom CLI registers <cwd>/.aussom/modules/ as an include path
automatically at startup, so the package is reachable from a script run
from the project root:
include socket;
s = new socket();
No path configuration is needed. If you run a script from a different
working directory, the project-tier path will not be active for that run;
the script will fall through to system-globals instead. The rule of thumb
is to run your scripts from the project directory that holds
aussom.lock.
Multi-file packages keep additional source files in the same directory and
expose them through normal Aussom paths (include socket.util.parse;
resolves to socket/util/parse.aus).
apac -lf
Prints the contents of the current target's aussom.lock as a flat table
(name, version, plus a [forced] suffix on entries with forced: true).
With -g, the system-globals lockfile is read instead. An empty or missing
lockfile prints nothing and exits 0.
apac -u socket
Removes <target>/.aussom/modules/socket/ and the matching lockfile entry.
Before deleting, apac scans every other installed package's package.yaml
for a dependency on socket. If anything else declared a range against the
package you are removing, apac prints a warning naming each dependent and
the range it declared, then proceeds with the uninstall. The dependents stay
installed in their now-broken state. The user is responsible for either
reinstalling the dep or removing the dependents afterward.
Transitive deps that were pulled in alongside socket stay pinned in the
lockfile. apac does not auto-prune them.
The -g modifier targets the system-globals directory instead of the
current project. Use it for packages every project on the machine should
share, such as a UI framework or a workplace-wide utility library.
sudo apac -g -i ui_framework
The per-platform path:
| Platform | System-globals directory |
|---|---|
| Linux | /var/lib/aussom/modules/ |
| macOS | /Library/Application Support/Aussom/modules/ |
| Windows | %PROGRAMDATA%\Aussom\modules\ (typically C:\ProgramData\Aussom\modules\) |
These directories are the OS-conventional shared-data locations. They
survive Aussom upgrades and uninstalls. On Linux, dpkg -r aussom leaves
/var/lib/aussom/ untouched; only dpkg --purge aussom removes it.
On macOS and Windows, the standard uninstaller never touches its respective
path.
Inside the system-globals tree the layout is flatter than the project tier:
the platform directory is itself the modules directory, and aussom.lock
sits next to the installed packages:
/var/lib/aussom/modules/
aussom.lock
ui_framework/
package.yaml
aussom-ui_framework.jar
ui_framework.aus
...
Resolution at script run time still respects "more-specific wins": a
project-tier copy of the same name overrides the global. Pinning a different
version of ui_framework in a project's aussom.lock is the supported way
to deviate from the global on a per-project basis.
apac -g -u ui_framework removes the package from the global tree, and
apac -g -lf lists the global lockfile.
apac uses ANSI styling for log markers, a spinner, and a single status line pinned at the bottom of the terminal while work is in flight. The TUI is auto-detected from whether stdout is a TTY. Pipes and redirects automatically fall back to plain text so output is safe to capture in CI logs.
apac -vb -i socket
-vb (--verbose) adds extra log detail such as resolver decisions and
per-file extraction events.
Two other flags override TUI detection:
-ntui (--no-tui) forces plain output even on a TTY.-ftui (--force-tui) forces ANSI output even when stdout is not a TTY.-ntui and -ftui are mutually exclusive.
If you have edited files inside <project>/.aussom/modules/<name>/ and want
the original contents back, use the two-step pattern:
apac -u socket
apac -i socket@1.0.5
The uninstall clears the directory and lockfile entry; the install pulls a fresh copy.
Most users only ever consume packages. The remaining sections cover what you need to write and publish your own.
A package is a directory tree with a package.yaml manifest, a LICENSE.txt
license file, one or more .aus source files, and optionally JARs or native
libraries depending on the package type.
The manifest's type field is one of:
| Type | What It May Contain |
|---|---|
pure |
Aussom source files only. No JARs, no native libraries. |
jvm |
Aussom source plus optional JARs loaded with app.loadJar(...). No native libraries. |
native |
Aussom source plus optional JARs plus optional native libraries loaded through Panama. |
The type is descriptive, not enforcing. The Aussom CLI and Aussom-Server do not consult it at runtime; the security manager gates capabilities. The registry uses the type at publish time to verify the zip's contents fit the declared shape, and at browse time to let users filter results.
| Field | Notes |
|---|---|
name |
Lowercase ASCII letters, digits, underscores. Must start with a letter. 1-64 characters. No hyphens. |
version |
Three-part semver (MAJOR.MINOR.PATCH). No pre-release or build-metadata segments. |
description |
10-200 characters. One-line blurb shown in search results. |
license |
Free-form license name (MIT, Apache-2.0, etc.). Full text must ship as LICENSE.txt. |
author |
1-128 characters. Free-form name or organization. |
authorEmail |
local@domain shape. Used for outreach (security advisories, takedowns). |
type |
pure, jvm, or native. |
dependencies |
Map of name to version range. May be empty ({}), but the key must be present. |
| Field | Notes |
|---|---|
repository |
URL to the source repository. |
homepage |
URL to a project website or doc site. |
keywords |
List of short tag strings. Lowercase, hyphenated. 0-10 tags, each 2-32 characters. |
1.4.3 matches only 1.4.3.1.4.* matches any patch in 1.4. 1.* matches any minor in 1.x.
* matches any version. Wildcards must appear only as trailing
components; 1.*.0 is not valid.>=, <, <=, >) combine with whitespace as
AND: >=1.1.0 <2.0.0.apac does not use npm's ^ or ~ operators.
A publishable zip must contain package.yaml and a non-empty
LICENSE.txt at its root. apac also recommends:
README.md — written by you. apac -p bundles it verbatim. The registry
extracts it at publish time so a future web layer can serve it as the
package's landing page.CHANGELOG.md — version history. The registry surfaces it on the version
detail page when present.A docs/ directory is generated automatically; see the next section.
apac -ag generates a package skeleton in the current directory. Two modes:
apac -ag -sm hello_world
Simple mode produces an Aussom-only flat layout. The package directory is
the package name (no aussom- prefix). The tree:
<cwd>/
.gitignore
hello_world/
package.yaml # type: pure
LICENSE.txt # Apache-2.0 license text
README.md
hello_world.aus
You fill in hello_world.aus, then run apac -p hello_world to package it.
apac -ag com.example hello_world
Default mode produces a Java + Maven skeleton with an extern wrapper class and a JUnit driver:
<cwd>/
pom.xml
LICENSE.txt
README.md
package.yaml # type: jvm
.gitignore
src/
main/
aus/hello_world/hello_world.aus
java/com/example/aussom/HelloWorld.java
test/
aus/
java/Tests.java
lib/ # drop native libs here if you upgrade to type: native
package-files/ # extra files copied into the package directory at build time
The default mode is the Maven build path: run mvn clean package, then
apac -p hello_world. The Maven package phase rebuilds the
hello_world/ directory from scratch, copies package.yaml, LICENSE.txt,
README.md, the built aussom-hello_world.jar, every .aus under
src/main/aus/hello_world/, and the contents of lib/ and package-files/.
After Maven finishes, apac -p hello_world reads that directory and
produces the zip.
Validation rules apply: invalid package names (uppercase, hyphen, leading digit) are rejected before any files are written. In default mode, the groupId must be a valid dotted identifier.
apac -ag does not overwrite files. If a target file already exists, the
generator prints a warning and continues with the rest of the tree.
apac -p ./hello_world/
apac -p reads <path>/package.yaml, validates the package layout, and
writes <name>-<version>.zip into the current working directory. The zip's
top-level entries are the source directory's files and subdirectories
flattened in place — no extra wrapping folder — so
apac -f -i <name>-<version>.zip extracts directly into
<target>/.aussom/modules/<name>/.
The packager:
.aussom/ and
aussom.lock (those belong to the package author's own consumer
workflow, not to the package's content).docs/ directory inside the zip from the Aussom-Doc comments
in your .aus source files. One Markdown file per .aus file, mirroring
the source tree. A local docs/ directory at the source root is ignored
with a warning — apac always regenerates docs from source.pure
package with a JAR in it fails the pre-flight check.apac -p always writes to the cwd, never inside the source tree.
apac -ag -sm string_utils
cd string_utils
# edit string_utils.aus to add your code
apac -p .
The result is string_utils-1.0.0.zip containing package.yaml,
LICENSE.txt, README.md, string_utils.aus, and the generated docs/
tree. package.yaml declares type: pure.
apac -ag com.example net_tools
cd net_tools
# implement NetTools.java and net_tools.aus
mvn clean package
apac -p ./net_tools/
The Maven build compiles the Java sources into aussom-net_tools.jar and
rebuilds the net_tools/ directory with the manifest, license, README,
JAR, and .aus sources. apac -p zips that directory. package.yaml
declares type: jvm. The package's .aus wrapper loads the JAR with
app.loadJar("aussom-net_tools.jar") (the path-qualified form the
archetype emits).
The arcgen default mode is the starting point for native packages too,
because the same Maven layout produces the JAR and copies the lib/
directory into the package tree:
apac -ag com.example codec
cd codec
# drop your shared library files into lib/ (flat, no subdirectories):
# lib/libcodec.so Linux build
# lib/libcodec.dylib macOS build
# lib/codec.dll Windows build
# implement Codec.java and codec.aus (loading libs through Panama)
# edit package.yaml: change type: jvm to type: native
mvn clean package
apac -p ./codec/
apac -p's pre-flight check verifies the file contents match type: native
before producing the zip. Without the manifest edit the packager fails with
a type-vs-contents mismatch.
You can ship a single zip carrying the native libraries for every platform you support, or split per-platform builds into separate publishes — that is up to you as the package author. The Panama resolver picks the right file at load time based on the running host, so a multi-platform zip works without any additional metadata.
Inside the package, native libraries sit flat at the package root
(.aussom/modules/codec/libcodec.so). The wrapper loads them by prefixing
the package name to the library base name:
this.lib = panama.openLibrary("codec/codec");
The Panama resolver expands the base name to the right platform extension
(libcodec.so, libcodec.dylib, codec.dll) and finds the file inside
the package directory. The same path-prefix convention applies to the
package's JAR (app.loadJar("codec/aussom-codec.jar")).
apac publishes packages over HTTPS to the configured registry. Before you
can publish you need two things in apac.yaml: the registry URL (default
https://apac.aussom-lang.com) and a bearer publish key. The config file
lives in the system-globals modules directory:
| Platform | apac.yaml path |
|---|---|
| Linux | /var/lib/aussom/modules/apac.yaml |
| macOS | /Library/Application Support/Aussom/modules/apac.yaml |
| Windows | %PROGRAMDATA%\Aussom\modules\apac.yaml |
The Aussom installer writes the file on first install with the default registry URL and an empty publish key. The installer leaves an existing file alone, so your edits survive upgrades.
Example apac.yaml:
registry: "https://apac.aussom-lang.com"
publish:
key: "<your-key-here>"
At the moment there is no self-serve signup. To request a publish key, email cupofcode@yahoo.com. Self-serve signup will land in a later release.
Once you have a key, paste it into publish.key in apac.yaml. The key
is sensitive; apac never logs or echoes it back, including in verbose
mode.
apac -pub ./hello_world-1.0.0.zip
apac uploads the zip to the registry's publish endpoint as a multipart form
authenticated with the bearer key. The registry runs the same validation
the design documents (manifest fields, LICENSE.txt presence, zip safety,
type matches contents, dependencies resolvable). Failures print the
registry's error code and message and exit non-zero. On success, apac
prints Published <name>@<version>.
apac refuses to publish when:
publish.key is empty or missing (publish_key_missing).https://.Versions are immutable once published. The publish call is idempotent on failure (no half-state on the server) but not on success.
| Short | Long | Argument | Description |
|---|---|---|---|
-i |
--install |
<name[@ver]> or zip path |
Install a package. Default source is the registry; with -f, a local zip. |
-u |
--uninstall |
<name> |
Remove an installed package and its lockfile entry. |
-l |
--list |
<name[@ver]> |
List a package's published versions, or print a single version's manifest. |
-lf |
--lockfile |
List packages recorded in the current target's lockfile. | |
-p |
--package |
<path> |
Zip a package source into <name>-<version>.zip in cwd. |
-s |
--search |
<query> |
Search the registry. Prints a flat table to stdout. |
-pub |
--publish |
<zip-path> |
Upload a package zip to the registry. |
-ag |
--arcgen |
<group> <name> or <name> |
Generate an apac package skeleton. |
-f |
--file |
Modifier on -i. Treat the install argument as a local zip path. |
|
-fc |
--force |
Modifier on -i. Bypass the resolver's compatibility check. |
|
-g |
--global |
Modifier on -i, -u, or -lf. Target system-globals. |
|
-sm |
--simple |
Modifier on -ag. Produce the Aussom-only flat layout. |
|
-vb |
--verbose |
Verbose output. | |
-ntui |
--no-tui |
Force plain-text output even on a TTY. | |
-ftui |
--force-tui |
Force ANSI output even when stdout is not a TTY. | |
-h |
--help |
Print usage and exit. | |
-v |
--version |
Print apac version and exit. |
The action flags (-i, -u, -l, -lf, -p, -s, -pub, -ag) are
mutually exclusive. Modifiers apply only to their parent actions: -f and
-fc only with -i; -g only with -i, -u, or -lf; -sm only with
-ag. -h and -v short-circuit any action.