Packages
A package is how something is added to Mod: an app, a record type, a tool or a piece of the window. It is an ordinary npm package with a mod field in its package.json that says what it adds and what it may touch.
How it works
A package declares what it reads and writes, and gets only that. Access is denied by default: an app that calls into tasks without listing tasks in reads is refused at the first call, rather than quietly reading something it should not. Reading and writing are separate, because looking at a task list should not mean being able to close one. The lists are also the package's dependencies: declaring one is what installs it into the project.
A package is installed in one project or in the whole World. Installed in the World, it is available in every project.
Records belong to the project, not the package. Removing a package never deletes the records it made, and installing it again picks them up by their type. An update keeps the app's id and may not change its data type, so every record it owns keeps drawing.
An app is the common case. It owns a data type, draws its records with a view, and carries a skill that tells an agent how to use it. Once pushed, an app's source lives in the project as documents, so it can be changed in Mod like anything else. A package can instead edit a kind of document without owning a type, which is what an editor is. It can fill a part of the window, such as the sidebar, header or composer. It can give agents tools that change its records from any surface, with no view open.
Published packages live in a shared registry. Publishing copies the app's view and skill as they are now. Records never travel. Publishing again adds a new version of the same package, and installed copies can update to it.
Using it as you build
The mod field names what the package adds and what it may touch:
"mod": {
"name": "Launch plan",
"dataType": "launchplan",
"reads": ["tasks"],
"writes": ["tasks"],
"entry": "dist/index.html"
}
Other fields you can set: description; handles, the document types an editor edits; fields, a description of each field on its records; immutable, fields set once and never changed; build, the command that produces entry (by default npm run build); source, the files published as source (by default src); icon; worker, its package tools, the tools it gives agents (see tools); and category, about and screenshots for its registry page. A package needs a dataType or handles. The built entry must be self-contained: one that loads code from the network is refused.
Scaffold, build and install from the command line:
mod-next app init "Launch plan" --dataType launchplan
mod-next app push <projectId>
mod-next app push <projectId> --world
app pull writes the project's copy of the source back to disk to work on, and app push refuses a file whose document changed in Mod since you pulled. Publish to the registry, or start from someone else's published source:
mod-next app publish <projectId> --version 1.1.0 --include-source
mod-next app fork <lineageId> --dir ./my-launch-plan
Agents use list_packages to see what is installed, or with available and a query to search the registry. install_package installs from the registry with release, into the World by default or one project with scope: "project". uninstall_package removes a package and takes it out of any layout that names it. publish_package publishes an installed app. Publishing is public, so an agent asks you first.
You decide what your package adds, where to install it, and whether to publish it for others. See apps for drawing a type and shared data types for the records it works with.
Limits
- Harness packages, which change how Mod's own agent is prompted, routed and compacted, are designed but not shipped (RFC 0352). soon
- A shared list of record types for every package to build on is still forming. soon
- A package's tools run only on a host that can run them, such as the desktop app. Publishing needs a host that can reach the registry.