@rivet-dev/agentos-toolchain 0.0.0-main.ab2ce7c

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli.d.ts ADDED
@@ -0,0 +1 @@
1
+ #!/usr/bin/env node
package/dist/cli.js ADDED
@@ -0,0 +1,182 @@
1
+ #!/usr/bin/env node
2
+ import {
3
+ build,
4
+ pack,
5
+ packAospkgFromTar,
6
+ publish,
7
+ stage
8
+ } from "./chunk-YTYFSDXW.js";
9
+
10
+ // src/cli.ts
11
+ import { existsSync, statSync } from "fs";
12
+ import { basename, resolve } from "path";
13
+ var USAGE = `agentos-toolchain \u2014 build, stage, and publish agentOS packages
14
+
15
+ Usage:
16
+ agentos-toolchain pack <npm-pkg | ./local-dir> [options]
17
+ Pack an npm package or local script dir into a self-contained agentOS
18
+ package tar (JS agents / node closures).
19
+ --agent <command> mark a bin command as the package's ACP entrypoint
20
+ --out <tar> output tar (default: ./<input-name>-package.tar)
21
+ --prune-native delete unreachable native .node addons
22
+
23
+ agentos-toolchain stage [<packageDir>] --commands-dir <dir> [--if-missing skip|error]
24
+ Populate <packageDir>/bin/ from a compiled commands directory, per the
25
+ commands/aliases/stubs lists in agentos-package.json. --if-missing skip
26
+ leaves a valid empty placeholder when binaries are absent (default: error).
27
+
28
+ agentos-toolchain build [<packageDir>]
29
+ Assemble the clean runtime tar dist/package.tar (bin/ + share/ +
30
+ agentos-package.json) from <packageDir> (default: cwd).
31
+
32
+ agentos-toolchain publish [<packageDir>] [--tag <t> | --latest] [--dry-run] [--set-version <v>]
33
+ Publish the built package to npm. Default dist-tag is "dev"; the latest
34
+ pointer only moves with an explicit --latest.
35
+
36
+ -h, --help show this help
37
+ `;
38
+ function defaultOutName(source) {
39
+ if (existsSync(source) && statSync(source).isDirectory()) {
40
+ return `./${basename(resolve(source))}-package.tar`;
41
+ }
42
+ const at = source.lastIndexOf("@");
43
+ const name = at > 0 ? source.slice(0, at) : source;
44
+ return `./${name.replace(/^@[^/]+\//, "")}-package.tar`;
45
+ }
46
+ var VALUE_FLAGS = /* @__PURE__ */ new Set([
47
+ "--agent",
48
+ "--out",
49
+ "--commands-dir",
50
+ "--if-missing",
51
+ "--tag",
52
+ "--set-version"
53
+ ]);
54
+ function parseArgs(argv) {
55
+ const positional = [];
56
+ const flags = /* @__PURE__ */ new Map();
57
+ for (let i = 0; i < argv.length; i++) {
58
+ const a = argv[i];
59
+ if (a === "-h" || a === "--help") {
60
+ process.stdout.write(USAGE);
61
+ process.exit(0);
62
+ } else if (VALUE_FLAGS.has(a)) {
63
+ const value = argv[++i];
64
+ if (value === void 0) throw new Error(`${a} requires a value`);
65
+ flags.set(a, value);
66
+ } else if (a.startsWith("-")) {
67
+ flags.set(a, true);
68
+ } else {
69
+ positional.push(a);
70
+ }
71
+ }
72
+ return { positional, flags };
73
+ }
74
+ function requireKnownFlags(args, known) {
75
+ for (const flag of args.flags.keys()) {
76
+ if (!known.includes(flag)) throw new Error(`unexpected argument: ${flag}`);
77
+ }
78
+ }
79
+ function main() {
80
+ const [cmd, ...rest] = process.argv.slice(2);
81
+ if (cmd === void 0) {
82
+ process.stdout.write(USAGE);
83
+ process.exit(1);
84
+ }
85
+ if (cmd === "-h" || cmd === "--help") {
86
+ process.stdout.write(USAGE);
87
+ process.exit(0);
88
+ }
89
+ const args = parseArgs(rest);
90
+ switch (cmd) {
91
+ case "pack-aospkg": {
92
+ requireKnownFlags(args, []);
93
+ const sourceTar = args.positional[0];
94
+ const dest = args.positional[1];
95
+ if (!sourceTar || !dest) {
96
+ throw new Error("pack-aospkg requires <source-tar> <dest-aospkg> arguments");
97
+ }
98
+ const summary = packAospkgFromTar(resolve(sourceTar), resolve(dest));
99
+ process.stdout.write(
100
+ `packed ${summary.name}@${summary.version} \u2192 ${dest}
101
+ `
102
+ );
103
+ return;
104
+ }
105
+ case "pack": {
106
+ requireKnownFlags(args, ["--agent", "--out", "--prune-native"]);
107
+ const source = args.positional[0];
108
+ if (!source) {
109
+ throw new Error("pack requires a <npm-pkg | ./local-dir> argument");
110
+ }
111
+ const result = pack({
112
+ source,
113
+ out: resolve(
114
+ args.flags.get("--out") ?? defaultOutName(source)
115
+ ),
116
+ agent: args.flags.get("--agent"),
117
+ pruneNative: args.flags.get("--prune-native") === true
118
+ });
119
+ process.stdout.write(
120
+ `packed ${result.name}@${result.version} \u2192 ${result.packageTar}
121
+ commands: ${result.commands.join(", ")}
122
+ `
123
+ );
124
+ return;
125
+ }
126
+ case "stage": {
127
+ requireKnownFlags(args, ["--commands-dir", "--if-missing"]);
128
+ const commandsDir = args.flags.get("--commands-dir");
129
+ if (!commandsDir) throw new Error("stage requires --commands-dir <dir>");
130
+ const ifMissing = args.flags.get("--if-missing") ?? "error";
131
+ if (ifMissing !== "error" && ifMissing !== "skip") {
132
+ throw new Error(
133
+ `--if-missing must be "skip" or "error", got "${ifMissing}"`
134
+ );
135
+ }
136
+ stage({
137
+ packageDir: args.positional[0] ?? process.cwd(),
138
+ commandsDir,
139
+ ifMissing
140
+ });
141
+ return;
142
+ }
143
+ case "build": {
144
+ requireKnownFlags(args, []);
145
+ build(args.positional[0]);
146
+ return;
147
+ }
148
+ case "publish": {
149
+ requireKnownFlags(args, [
150
+ "--tag",
151
+ "--latest",
152
+ "--dry-run",
153
+ "--set-version"
154
+ ]);
155
+ const result = publish({
156
+ packageDir: args.positional[0] ?? process.cwd(),
157
+ tag: args.flags.get("--tag"),
158
+ latest: args.flags.get("--latest") === true,
159
+ dryRun: args.flags.get("--dry-run") === true,
160
+ setVersion: args.flags.get("--set-version")
161
+ });
162
+ process.stdout.write(
163
+ `published ${result.name}@${result.version} (dist-tag: ${result.tag})
164
+ `
165
+ );
166
+ return;
167
+ }
168
+ default:
169
+ throw new Error(
170
+ `unknown command "${cmd}" (expected pack, stage, build, or publish)`
171
+ );
172
+ }
173
+ }
174
+ try {
175
+ main();
176
+ } catch (error) {
177
+ process.stderr.write(
178
+ `error: ${error instanceof Error ? error.message : String(error)}
179
+ `
180
+ );
181
+ process.exit(1);
182
+ }
@@ -0,0 +1,202 @@
1
+ interface PackOptions {
2
+ /** npm package spec (`name`, `name@version`) or a local directory path. */
3
+ source: string;
4
+ /**
5
+ * Output tar for the package itself. The tar contains
6
+ * `{bin/, node_modules/, agentos-package.json}` at its root. The versioned
7
+ * `/opt/agentos/<name>/<version>` + `current` layout is the sidecar
8
+ * projection's job (name/version from `agentos-package.json`).
9
+ */
10
+ out: string;
11
+ /** Mark a bin command as the package's ACP entrypoint (validated against bin/). */
12
+ agent?: string;
13
+ /**
14
+ * Delete native `.node` addons from the flat closure instead of failing.
15
+ * Use when a package's dependency tree contains optional/platform native
16
+ * addons (e.g. `koffi`, `clipboard-*`) that are never loaded on the code path
17
+ * that runs in V8. The JS closure (including dynamically-required modules) is
18
+ * kept; only the V8-incompatible `.node` files are removed. If a pruned addon
19
+ * IS reached at runtime it fails then — so this is opt-in.
20
+ */
21
+ pruneNative?: boolean;
22
+ }
23
+ interface PackResult {
24
+ name: string;
25
+ version: string;
26
+ packageTar: string;
27
+ /** The packed `.aospkg` runtime artifact (empty when `out` was a directory). */
28
+ packageAospkg?: string;
29
+ commands: string[];
30
+ }
31
+ /**
32
+ * Verify a finished package directory satisfies the agentOS package format:
33
+ * every `bin/` entry has a recognized, non-native header, and the tree has no
34
+ * native `.node` addons. Throws with a clear message on the first violation.
35
+ */
36
+ declare function verifyPackageDir(packageDir: string): void;
37
+ declare function pack(options: PackOptions): PackResult;
38
+
39
+ /**
40
+ * Executable header detection — the same binfmt rules the runtime uses.
41
+ *
42
+ * Runtime is decided by the file's leading bytes, never its name or extension:
43
+ * a `#!` shebang, the `\0asm` WebAssembly magic, or a native object-file magic
44
+ * (ELF / Mach-O / PE) which agentOS cannot execute (no native-arch handler).
45
+ */
46
+ type ExecutableKind = "shebang" | "wasm" | "native-elf" | "native-macho" | "native-pe" | "unknown";
47
+ declare function detectExecutableKind(head: Buffer): ExecutableKind;
48
+ declare function isNativeKind(kind: ExecutableKind): boolean;
49
+ /** The interpreter named on a shebang line, taken literally (no PATH search). */
50
+ declare function parseShebangInterpreter(head: Buffer): string | null;
51
+
52
+ interface StageOptions {
53
+ /** Package root holding `agentos-package.json`; `bin/` is (re)created here. */
54
+ packageDir: string;
55
+ /** Directory of compiled command binaries (e.g. the native wasm build output). */
56
+ commandsDir: string;
57
+ /**
58
+ * What to do when the commands dir or a declared binary is absent.
59
+ * `"error"` (default) fails the stage; `"skip"` warns and leaves the package
60
+ * a valid empty placeholder — used by in-repo builds so `pnpm build` works
61
+ * on checkouts that have not run the native build.
62
+ */
63
+ ifMissing?: "error" | "skip";
64
+ }
65
+ interface StageResult {
66
+ staged: string[];
67
+ missing: string[];
68
+ }
69
+ /**
70
+ * Populate a package's `bin/` from a commands directory, per the `commands` /
71
+ * `aliases` / `stubs` lists declared in its `agentos-package.json`.
72
+ *
73
+ * `bin/` is wiped and rebuilt on every run. Sources are copied dereferenced
74
+ * (`copyFileSync` follows symlinks), so alias/stub symlink farms in the
75
+ * commands dir land as real files that survive npm packing.
76
+ */
77
+ declare function stage(options: StageOptions): StageResult;
78
+
79
+ interface BuildResult {
80
+ name: string;
81
+ version: string;
82
+ commands: string[];
83
+ outDir: string;
84
+ outTar: string;
85
+ /** The packed `.aospkg` (header + vbare manifest + mount index + mount tar). */
86
+ outAospkg: string;
87
+ }
88
+ /**
89
+ * Assemble a clean `dist/package/` for a WASM / command registry package.
90
+ *
91
+ * Why this exists: a package's `src/index.ts` sets the descriptor `dir` that the
92
+ * sidecar projects read-only under `/opt/agentos/<name>/<version>`. The sidecar
93
+ * copies that WHOLE directory verbatim. If `dir` pointed at the package source
94
+ * root it would drag `src/`, dev `node_modules/`, `tsconfig.json`, `.turbo/`
95
+ * into every VM. The descriptor must instead point at a CLEAN runtime dir that
96
+ * holds ONLY what the package ships at runtime:
97
+ *
98
+ * dist/package/
99
+ * agentos-package.json pack-time manifest input (name, version, agent,
100
+ * provides) — consumed by the `.aospkg` packer and
101
+ * STRIPPED from the packed mount tar; the vbare
102
+ * chunk1 manifest is the single runtime manifest
103
+ * bin/<cmd> the compiled command binaries (copied verbatim)
104
+ * share/... (optional) man pages, if the source package ships them
105
+ *
106
+ * The runtime artifact is `dist/package.aospkg` (see aospkg.ts); the plain
107
+ * `dist/package.tar` is kept as the pack intermediate.
108
+ *
109
+ * Commands are derived from the source `bin/` directory's files (populate it
110
+ * with `stage`); `name`/`version` come from the source `package.json`. A package
111
+ * with NO (or an empty) `bin/` ships a valid, empty placeholder — it picks up
112
+ * its commands automatically once `stage` can populate `bin/`.
113
+ *
114
+ * This handles the COMMON case (compiled command packages). JS agent packages
115
+ * whose `dist/package` is a self-contained node runtime closure use `pack`
116
+ * instead; meta packages that default-export an ARRAY of descriptors have no
117
+ * `dir`/`bin` and never run this.
118
+ *
119
+ * Idempotent: `dist/package/` is removed and rebuilt on every run.
120
+ */
121
+ declare function build(packageDirInput?: string): BuildResult;
122
+
123
+ interface PublishOptions {
124
+ packageDir: string;
125
+ /** npm dist-tag. Defaults to `dev` so a publish NEVER moves `latest`. */
126
+ tag?: string;
127
+ /** Explicit opt-in to the `latest` dist-tag. */
128
+ latest?: boolean;
129
+ dryRun?: boolean;
130
+ /** Rewrite package.json `version` before publishing. */
131
+ setVersion?: string;
132
+ }
133
+ interface PublishResult {
134
+ name: string;
135
+ version: string;
136
+ tag: string;
137
+ }
138
+ /**
139
+ * `latest` is opt-in only: consumers installing `@agentos-software/<x>` with no
140
+ * tag must keep resolving a deliberate release, never whatever was published
141
+ * last from a dev machine or CI branch.
142
+ */
143
+ declare function resolveTag(options: Pick<PublishOptions, "tag" | "latest">): string;
144
+ /**
145
+ * Publish a built agentOS package to npm.
146
+ *
147
+ * Uses `pnpm publish` when the package lives in a pnpm workspace (so any
148
+ * `workspace:*` deps are rewritten to real versions), plain `npm publish`
149
+ * otherwise — 3rd-party repos need no pnpm.
150
+ */
151
+ declare function publish(options: PublishOptions): PublishResult;
152
+
153
+ /**
154
+ * The agentOS package manifest (`agentos-package.json`) at a package root.
155
+ *
156
+ * `name` / `agent` / `provides` describe the package to the runtime (they are
157
+ * copied into `dist/package/agentos-package.json` by `build`). `commands` /
158
+ * `aliases` / `stubs` describe how `stage` populates `bin/` from a compiled
159
+ * commands directory.
160
+ */
161
+ interface AgentosPackageManifest {
162
+ name?: string;
163
+ agent?: unknown;
164
+ provides?: unknown;
165
+ /** Command binaries copied from the commands dir into `bin/<name>`. */
166
+ commands?: string[];
167
+ /** alias -> command: staged as a copy of an already-staged `bin/<command>`. */
168
+ aliases?: Record<string, string>;
169
+ /** Commands staged as copies of the commands dir's `_stubs` binary. */
170
+ stubs?: string[];
171
+ }
172
+ declare function readManifest(packageDir: string): AgentosPackageManifest | undefined;
173
+
174
+ /**
175
+ * `.aospkg` packer — the toolchain half of the canonical packer in
176
+ * `crates/vfs/src/package_format/pack.rs` (both encode the schema in
177
+ * `crates/vfs/package-format/v1.bare`; the TS codecs are generated from it by
178
+ * `pnpm --dir packages/build-tools build:package-format`).
179
+ *
180
+ * Container layout: `16-byte header + vbare PackageManifest + vbare MountIndex
181
+ * + mount.tar` where each vbare chunk is `[u16 LE schema version] ++ BARE`.
182
+ *
183
+ * `agentos-package.json` is a pack-time INPUT only: it is parsed to build the
184
+ * chunk1 vbare manifest and stripped from the packed mount tar. The vbare
185
+ * manifest is the single runtime manifest; nothing re-materializes JSON into
186
+ * the guest. A root `package.json` stays in the mount tar (Node module
187
+ * resolution may need it) and its `bin` map is consulted for command targets.
188
+ */
189
+ interface AospkgSummary {
190
+ name: string;
191
+ version: string;
192
+ commands: string[];
193
+ }
194
+ /** Pack `sourceTar` into a `.aospkg` at `dest`. The source
195
+ * `agentos-package.json` must carry `name` and `version`. */
196
+ declare function packAospkgFromTar(sourceTar: string, dest: string): AospkgSummary;
197
+ declare function packAospkgFromTarBytes(source: Buffer): {
198
+ bytes: Buffer;
199
+ summary: AospkgSummary;
200
+ };
201
+
202
+ export { type AgentosPackageManifest, type AospkgSummary, type BuildResult, type ExecutableKind, type PackOptions, type PackResult, type PublishOptions, type PublishResult, type StageOptions, type StageResult, build, detectExecutableKind, isNativeKind, pack, packAospkgFromTar, packAospkgFromTarBytes, parseShebangInterpreter, publish, readManifest, resolveTag, stage, verifyPackageDir };
package/dist/index.js ADDED
@@ -0,0 +1,28 @@
1
+ import {
2
+ build,
3
+ detectExecutableKind,
4
+ isNativeKind,
5
+ pack,
6
+ packAospkgFromTar,
7
+ packAospkgFromTarBytes,
8
+ parseShebangInterpreter,
9
+ publish,
10
+ readManifest,
11
+ resolveTag,
12
+ stage,
13
+ verifyPackageDir
14
+ } from "./chunk-YTYFSDXW.js";
15
+ export {
16
+ build,
17
+ detectExecutableKind,
18
+ isNativeKind,
19
+ pack,
20
+ packAospkgFromTar,
21
+ packAospkgFromTarBytes,
22
+ parseShebangInterpreter,
23
+ publish,
24
+ readManifest,
25
+ resolveTag,
26
+ stage,
27
+ verifyPackageDir
28
+ };
package/package.json ADDED
@@ -0,0 +1,38 @@
1
+ {
2
+ "name": "@rivet-dev/agentos-toolchain",
3
+ "version": "0.0.0-main.ab2ce7c",
4
+ "description": "Build toolchain for agentOS packages (pack npm packages/scripts into self-contained agentOS packages).",
5
+ "type": "module",
6
+ "license": "Apache-2.0",
7
+ "bin": {
8
+ "agentos-toolchain": "./bin/agentos-toolchain.mjs"
9
+ },
10
+ "exports": {
11
+ ".": {
12
+ "import": {
13
+ "types": "./dist/index.d.ts",
14
+ "default": "./dist/index.js"
15
+ }
16
+ }
17
+ },
18
+ "files": [
19
+ "bin",
20
+ "dist",
21
+ "package.json",
22
+ "README.md"
23
+ ],
24
+ "scripts": {
25
+ "build": "tsup src/index.ts src/cli.ts --format esm --dts",
26
+ "check-types": "tsc --noEmit",
27
+ "test": "vitest run"
28
+ },
29
+ "devDependencies": {
30
+ "@types/node": "^22.10.2",
31
+ "tsup": "^8.3.5",
32
+ "typescript": "^5.7.2",
33
+ "vitest": "^2.1.9"
34
+ },
35
+ "dependencies": {
36
+ "@rivetkit/bare-ts": "^0.6.2"
37
+ }
38
+ }