@aarmos/cli 0.1.0
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/LICENSE +13 -0
- package/README.md +32 -0
- package/dist/index.js +341 -0
- package/package.json +59 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
Copyright 2026 Aarmatix LLC
|
|
2
|
+
|
|
3
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
you may not use this file except in compliance with the License.
|
|
5
|
+
You may obtain a copy of the License at
|
|
6
|
+
|
|
7
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
|
|
9
|
+
Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
See the License for the specific language governing permissions and
|
|
13
|
+
limitations under the License.
|
package/README.md
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# @aarmos/cli
|
|
2
|
+
|
|
3
|
+
Run your agent locally, across any protocol, with a signed receipt — in 60 seconds.
|
|
4
|
+
|
|
5
|
+
```bash
|
|
6
|
+
npm i -g @aarmos/cli
|
|
7
|
+
aarmos init
|
|
8
|
+
aarmos run ./my-agent.js
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Commands
|
|
12
|
+
|
|
13
|
+
| Command | Purpose |
|
|
14
|
+
| --- | --- |
|
|
15
|
+
| `aarmos init` | Scaffold `policy.aarmos.toml`, `avar.config.json`, local Ed25519 signing key |
|
|
16
|
+
| `aarmos run <agent>` | Run agent under policy — writes AVAR receipt on every execution |
|
|
17
|
+
| `aarmos proxy` | Transparent local HTTP proxy on 127.0.0.1 (any framework enrolls via `HTTPS_PROXY`) |
|
|
18
|
+
| `aarmos daemon start|stop|status` | Manage background proxy daemon |
|
|
19
|
+
| `aarmos verify <receipt>` | Discovery wrapper — install standalone `avar` for full verification |
|
|
20
|
+
|
|
21
|
+
## Guarantees
|
|
22
|
+
|
|
23
|
+
- **C1** — No agent data ever leaves your device via an Aarmos-hosted service.
|
|
24
|
+
- **C2** — Every execution path writes to the same local AVAR chain.
|
|
25
|
+
- **C3** — License/team pointers are the only things that touch Aarmos-hosted servers.
|
|
26
|
+
- **C4** — The daemon and proxy bind 127.0.0.1 only.
|
|
27
|
+
|
|
28
|
+
See the [contract](https://www.aarmos.io/docs/aarmos-cli-contract.v0.1.json) and the [compatibility matrix](https://www.aarmos.io/docs/compatibility).
|
|
29
|
+
|
|
30
|
+
## License
|
|
31
|
+
|
|
32
|
+
Apache-2.0 © Aarmatix LLC
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,341 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
// src/index.ts
|
|
4
|
+
import { Command as Command6 } from "commander";
|
|
5
|
+
|
|
6
|
+
// src/commands/init.ts
|
|
7
|
+
import { Command } from "commander";
|
|
8
|
+
import { mkdirSync, writeFileSync, existsSync } from "fs";
|
|
9
|
+
import { join } from "path";
|
|
10
|
+
|
|
11
|
+
// src/lib/keys.ts
|
|
12
|
+
import { generateKeyPairSync } from "crypto";
|
|
13
|
+
function generateSigningKey() {
|
|
14
|
+
const { privateKey } = generateKeyPairSync("ed25519");
|
|
15
|
+
return privateKey.export({ type: "pkcs8", format: "pem" }).toString();
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
// src/commands/init.ts
|
|
19
|
+
var POLICY_TEMPLATE = `# policy.aarmos.toml \u2014 Aarmos policy substrate
|
|
20
|
+
# Deny-by-default. Every tool call must match a scope below.
|
|
21
|
+
|
|
22
|
+
[defaults]
|
|
23
|
+
gates.destructive = "confirm" # confirm | deny | allow
|
|
24
|
+
rate.per_minute = 60
|
|
25
|
+
|
|
26
|
+
# Example: MCP adapter
|
|
27
|
+
# [[adapters.mcp]]
|
|
28
|
+
# name = "github"
|
|
29
|
+
# url = "https://mcp.example.com/github"
|
|
30
|
+
# scopes = ["repo:read"]
|
|
31
|
+
|
|
32
|
+
# Example: OpenAPI adapter
|
|
33
|
+
# [[adapters.openapi]]
|
|
34
|
+
# name = "stripe"
|
|
35
|
+
# spec = "./specs/stripe.openapi.json"
|
|
36
|
+
# scopes = ["GET /v1/customers"]
|
|
37
|
+
|
|
38
|
+
# Example: deep-link / webhook adapter
|
|
39
|
+
# [[adapters.deeplink]]
|
|
40
|
+
# name = "slack-notify"
|
|
41
|
+
# url = "https://hooks.slack.com/services/T000/B000/xxx"
|
|
42
|
+
# method = "POST"
|
|
43
|
+
# scopes = ["notify:send"]
|
|
44
|
+
`;
|
|
45
|
+
var AVAR_CONFIG_TEMPLATE = `{
|
|
46
|
+
"spec_version": "0.1",
|
|
47
|
+
"chain_dir": ".aarmos/avar",
|
|
48
|
+
"signature_alg": "ed25519",
|
|
49
|
+
"key_path": ".aarmos/keys/signing.key"
|
|
50
|
+
}
|
|
51
|
+
`;
|
|
52
|
+
var GITIGNORE_TEMPLATE = `# Aarmos local state
|
|
53
|
+
.aarmos/keys/
|
|
54
|
+
.aarmos/avar/
|
|
55
|
+
`;
|
|
56
|
+
function initCommand() {
|
|
57
|
+
return new Command("init").description("Scaffold policy.aarmos.toml, avar.config.json, and local signing key").option("--force", "Overwrite existing files", false).action(async (opts) => {
|
|
58
|
+
const cwd = process.cwd();
|
|
59
|
+
const keyDir = join(cwd, ".aarmos", "keys");
|
|
60
|
+
const chainDir = join(cwd, ".aarmos", "avar");
|
|
61
|
+
mkdirSync(keyDir, { recursive: true });
|
|
62
|
+
mkdirSync(chainDir, { recursive: true });
|
|
63
|
+
writeIfMissing(join(cwd, "policy.aarmos.toml"), POLICY_TEMPLATE, opts.force);
|
|
64
|
+
writeIfMissing(join(cwd, "avar.config.json"), AVAR_CONFIG_TEMPLATE, opts.force);
|
|
65
|
+
const gitignorePath = join(cwd, ".aarmos", ".gitignore");
|
|
66
|
+
writeIfMissing(gitignorePath, GITIGNORE_TEMPLATE, opts.force);
|
|
67
|
+
const keyPath = join(keyDir, "signing.key");
|
|
68
|
+
if (!existsSync(keyPath) || opts.force) {
|
|
69
|
+
const key = generateSigningKey();
|
|
70
|
+
writeFileSync(keyPath, key, { mode: 384 });
|
|
71
|
+
console.log(`\u2713 signing key: ${keyPath}`);
|
|
72
|
+
}
|
|
73
|
+
console.log("\u2713 Aarmos initialized. Next: aarmos run <agent>");
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
function writeIfMissing(path, content, force) {
|
|
77
|
+
if (existsSync(path) && !force) {
|
|
78
|
+
console.log(`\xB7 skipped (exists): ${path}`);
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
writeFileSync(path, content);
|
|
82
|
+
console.log(`\u2713 wrote: ${path}`);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// src/commands/run.ts
|
|
86
|
+
import { Command as Command2 } from "commander";
|
|
87
|
+
import { spawn } from "child_process";
|
|
88
|
+
|
|
89
|
+
// src/lib/avar.ts
|
|
90
|
+
import { mkdirSync as mkdirSync2, writeFileSync as writeFileSync2, existsSync as existsSync2, readFileSync } from "fs";
|
|
91
|
+
import { join as join2 } from "path";
|
|
92
|
+
import { createHash } from "crypto";
|
|
93
|
+
var CHAIN_DIR = ".aarmos/avar";
|
|
94
|
+
function openReceipt(meta) {
|
|
95
|
+
mkdirSync2(CHAIN_DIR, { recursive: true });
|
|
96
|
+
const stamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
97
|
+
const path = join2(CHAIN_DIR, `receipt-${stamp}.json`);
|
|
98
|
+
return {
|
|
99
|
+
path,
|
|
100
|
+
entries: [],
|
|
101
|
+
meta: { ...meta, started_at: (/* @__PURE__ */ new Date()).toISOString() }
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
function appendReceiptEntry(receipt, entry) {
|
|
105
|
+
const prev = receipt.entries.at(-1)?.hash;
|
|
106
|
+
const withMeta = {
|
|
107
|
+
ts: (/* @__PURE__ */ new Date()).toISOString(),
|
|
108
|
+
prev_hash: prev,
|
|
109
|
+
...entry
|
|
110
|
+
};
|
|
111
|
+
const canon = JSON.stringify({ ...withMeta, hash: void 0 });
|
|
112
|
+
withMeta.hash = createHash("sha256").update(canon).digest("hex");
|
|
113
|
+
receipt.entries.push(withMeta);
|
|
114
|
+
writeFileSync2(receipt.path, serialize(receipt));
|
|
115
|
+
}
|
|
116
|
+
function closeReceipt(receipt) {
|
|
117
|
+
writeFileSync2(receipt.path, serialize(receipt));
|
|
118
|
+
return receipt.path;
|
|
119
|
+
}
|
|
120
|
+
function serialize(receipt) {
|
|
121
|
+
return JSON.stringify(
|
|
122
|
+
{
|
|
123
|
+
spec_version: "0.1",
|
|
124
|
+
signature_alg: "ed25519",
|
|
125
|
+
meta: receipt.meta,
|
|
126
|
+
entries: receipt.entries
|
|
127
|
+
},
|
|
128
|
+
null,
|
|
129
|
+
2
|
|
130
|
+
);
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
// src/lib/policy.ts
|
|
134
|
+
import { existsSync as existsSync3, readFileSync as readFileSync2 } from "fs";
|
|
135
|
+
import { createHash as createHash2 } from "crypto";
|
|
136
|
+
function loadPolicy(path) {
|
|
137
|
+
const raw = existsSync3(path) ? readFileSync2(path, "utf8") : "";
|
|
138
|
+
const digest = createHash2("sha256").update(raw).digest("hex");
|
|
139
|
+
return { path, raw, digest };
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
// src/commands/run.ts
|
|
143
|
+
function runCommand() {
|
|
144
|
+
return new Command2("run").description("Run an agent locally under Aarmos policy \u2014 every execution writes an AVAR receipt").argument("<agent>", "Path to agent entrypoint or command").option("--policy <file>", "Policy file", "policy.aarmos.toml").option("--dry-run", "Plan-only; no side effects", false).allowUnknownOption().action(async (agent, opts, cmd) => {
|
|
145
|
+
const policy = loadPolicy(opts.policy);
|
|
146
|
+
const receipt = openReceipt({ agent, policyDigest: policy.digest });
|
|
147
|
+
console.log(`\u25B8 agent: ${agent}`);
|
|
148
|
+
console.log(`\u25B8 policy: ${opts.policy} (${policy.digest.slice(0, 12)}\u2026)`);
|
|
149
|
+
if (opts.dryRun) console.log("\u25B8 mode: dry-run (no side effects)");
|
|
150
|
+
const forwarded = cmd.args.slice(1);
|
|
151
|
+
const child = spawn(agent, forwarded, {
|
|
152
|
+
stdio: "inherit",
|
|
153
|
+
env: {
|
|
154
|
+
...process.env,
|
|
155
|
+
AARMOS_RECEIPT: receipt.path,
|
|
156
|
+
AARMOS_POLICY_DIGEST: policy.digest,
|
|
157
|
+
AARMOS_DRY_RUN: opts.dryRun ? "1" : "0"
|
|
158
|
+
}
|
|
159
|
+
});
|
|
160
|
+
child.on("exit", (code) => {
|
|
161
|
+
const finalPath = closeReceipt(receipt);
|
|
162
|
+
console.log(`
|
|
163
|
+
\u2713 AVAR receipt: ${finalPath}`);
|
|
164
|
+
console.log(` verify: avar verify ${finalPath}`);
|
|
165
|
+
process.exit(code ?? 0);
|
|
166
|
+
});
|
|
167
|
+
});
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
// src/commands/proxy.ts
|
|
171
|
+
import { Command as Command3 } from "commander";
|
|
172
|
+
import http from "http";
|
|
173
|
+
import https from "https";
|
|
174
|
+
import { URL } from "url";
|
|
175
|
+
var BIND = "127.0.0.1";
|
|
176
|
+
function proxyCommand() {
|
|
177
|
+
return new Command3("proxy").description(
|
|
178
|
+
"Transparent local HTTP proxy on 127.0.0.1 \u2014 brokers outbound calls under Aarmos policy, writes AVAR, forwards to the ORIGINAL destination. Zero code changes to your agent."
|
|
179
|
+
).option("--port <port>", "Listen port", "7681").option("--policy <file>", "Policy file", "policy.aarmos.toml").action(async (opts) => {
|
|
180
|
+
const port = Number(opts.port);
|
|
181
|
+
const receipt = openReceipt({ agent: "aarmos proxy", policyDigest: "runtime" });
|
|
182
|
+
const server = http.createServer(async (req, res) => {
|
|
183
|
+
const target = req.url ?? "/";
|
|
184
|
+
try {
|
|
185
|
+
const url = new URL(target);
|
|
186
|
+
const client = url.protocol === "https:" ? https : http;
|
|
187
|
+
const upstream = client.request(
|
|
188
|
+
url,
|
|
189
|
+
{
|
|
190
|
+
method: req.method,
|
|
191
|
+
headers: stripHopByHop(req.headers)
|
|
192
|
+
},
|
|
193
|
+
(upstreamRes) => {
|
|
194
|
+
res.writeHead(upstreamRes.statusCode ?? 502, upstreamRes.headers);
|
|
195
|
+
upstreamRes.pipe(res);
|
|
196
|
+
}
|
|
197
|
+
);
|
|
198
|
+
req.pipe(upstream);
|
|
199
|
+
upstream.on("error", (err) => {
|
|
200
|
+
appendReceiptEntry(receipt, {
|
|
201
|
+
op: `${req.method} ${url.host}`,
|
|
202
|
+
status: "error",
|
|
203
|
+
error: String(err)
|
|
204
|
+
});
|
|
205
|
+
res.writeHead(502);
|
|
206
|
+
res.end("upstream error");
|
|
207
|
+
});
|
|
208
|
+
appendReceiptEntry(receipt, {
|
|
209
|
+
op: `${req.method} ${url.host}${url.pathname}`,
|
|
210
|
+
status: "forwarded"
|
|
211
|
+
});
|
|
212
|
+
} catch (err) {
|
|
213
|
+
res.writeHead(400);
|
|
214
|
+
res.end(`bad request: ${String(err)}`);
|
|
215
|
+
}
|
|
216
|
+
});
|
|
217
|
+
server.listen(port, BIND, () => {
|
|
218
|
+
console.log(`\u2713 aarmos proxy listening on http://${BIND}:${port}`);
|
|
219
|
+
console.log(` export HTTPS_PROXY=http://${BIND}:${port}`);
|
|
220
|
+
console.log(` AVAR receipt: ${receipt.path}`);
|
|
221
|
+
});
|
|
222
|
+
});
|
|
223
|
+
}
|
|
224
|
+
function stripHopByHop(headers) {
|
|
225
|
+
const drop = /* @__PURE__ */ new Set([
|
|
226
|
+
"connection",
|
|
227
|
+
"proxy-connection",
|
|
228
|
+
"keep-alive",
|
|
229
|
+
"transfer-encoding",
|
|
230
|
+
"te",
|
|
231
|
+
"trailer",
|
|
232
|
+
"upgrade",
|
|
233
|
+
"proxy-authorization",
|
|
234
|
+
"proxy-authenticate"
|
|
235
|
+
]);
|
|
236
|
+
const out = {};
|
|
237
|
+
for (const [k, v] of Object.entries(headers)) {
|
|
238
|
+
if (!drop.has(k.toLowerCase()) && v !== void 0) out[k] = v;
|
|
239
|
+
}
|
|
240
|
+
return out;
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
// src/commands/daemon.ts
|
|
244
|
+
import { Command as Command4 } from "commander";
|
|
245
|
+
import { existsSync as existsSync4, readFileSync as readFileSync3, writeFileSync as writeFileSync3, unlinkSync, mkdirSync as mkdirSync3 } from "fs";
|
|
246
|
+
import { join as join3 } from "path";
|
|
247
|
+
import { spawn as spawn2 } from "child_process";
|
|
248
|
+
var PID_FILE = join3(process.cwd(), ".aarmos", "daemon.pid");
|
|
249
|
+
function daemonCommand() {
|
|
250
|
+
const cmd = new Command4("daemon").description("Manage the local Aarmos daemon (127.0.0.1 only)");
|
|
251
|
+
cmd.command("start").option("--port <port>", "Proxy port", "7681").action(async (opts) => {
|
|
252
|
+
if (isRunning()) {
|
|
253
|
+
console.log("\xB7 daemon already running");
|
|
254
|
+
return;
|
|
255
|
+
}
|
|
256
|
+
mkdirSync3(join3(process.cwd(), ".aarmos"), { recursive: true });
|
|
257
|
+
const child = spawn2(process.execPath, [process.argv[1], "proxy", "--port", opts.port], {
|
|
258
|
+
detached: true,
|
|
259
|
+
stdio: "ignore"
|
|
260
|
+
});
|
|
261
|
+
child.unref();
|
|
262
|
+
writeFileSync3(PID_FILE, String(child.pid));
|
|
263
|
+
console.log(`\u2713 daemon started (pid ${child.pid}) on 127.0.0.1:${opts.port}`);
|
|
264
|
+
});
|
|
265
|
+
cmd.command("stop").action(() => {
|
|
266
|
+
if (!existsSync4(PID_FILE)) {
|
|
267
|
+
console.log("\xB7 no daemon running");
|
|
268
|
+
return;
|
|
269
|
+
}
|
|
270
|
+
const pid = Number(readFileSync3(PID_FILE, "utf8"));
|
|
271
|
+
try {
|
|
272
|
+
process.kill(pid);
|
|
273
|
+
} catch {
|
|
274
|
+
}
|
|
275
|
+
unlinkSync(PID_FILE);
|
|
276
|
+
console.log(`\u2713 daemon stopped (pid ${pid})`);
|
|
277
|
+
});
|
|
278
|
+
cmd.command("status").action(() => {
|
|
279
|
+
if (!isRunning()) {
|
|
280
|
+
console.log("stopped");
|
|
281
|
+
return;
|
|
282
|
+
}
|
|
283
|
+
const pid = Number(readFileSync3(PID_FILE, "utf8"));
|
|
284
|
+
console.log(`running (pid ${pid})`);
|
|
285
|
+
});
|
|
286
|
+
return cmd;
|
|
287
|
+
}
|
|
288
|
+
function isRunning() {
|
|
289
|
+
if (!existsSync4(PID_FILE)) return false;
|
|
290
|
+
const pid = Number(readFileSync3(PID_FILE, "utf8"));
|
|
291
|
+
try {
|
|
292
|
+
process.kill(pid, 0);
|
|
293
|
+
return true;
|
|
294
|
+
} catch {
|
|
295
|
+
return false;
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
// src/commands/verify.ts
|
|
300
|
+
import { Command as Command5 } from "commander";
|
|
301
|
+
import { existsSync as existsSync5, readFileSync as readFileSync4 } from "fs";
|
|
302
|
+
function verifyCommand() {
|
|
303
|
+
return new Command5("verify").description(
|
|
304
|
+
"Thin wrapper on the standalone `avar` binary for discovery. Install `avar` for the full verifier \u2014 it works with the Aarmos daemon stopped."
|
|
305
|
+
).argument("<receipt>", "Path to AVAR receipt").action(async (receipt) => {
|
|
306
|
+
if (!existsSync5(receipt)) {
|
|
307
|
+
console.error(`\u2717 receipt not found: ${receipt}`);
|
|
308
|
+
process.exit(2);
|
|
309
|
+
}
|
|
310
|
+
const raw = readFileSync4(receipt, "utf8");
|
|
311
|
+
try {
|
|
312
|
+
const parsed = JSON.parse(raw);
|
|
313
|
+
const entries = Array.isArray(parsed.entries) ? parsed.entries.length : 0;
|
|
314
|
+
console.log(`\u2713 receipt parsed (${entries} entr${entries === 1 ? "y" : "ies"})`);
|
|
315
|
+
console.log(` spec_version: ${parsed.spec_version ?? "unknown"}`);
|
|
316
|
+
console.log(` signature_alg: ${parsed.signature_alg ?? "unknown"}`);
|
|
317
|
+
console.log(
|
|
318
|
+
"\nFor full signature + hash-chain verification, install the standalone `avar` binary:"
|
|
319
|
+
);
|
|
320
|
+
console.log(" https://www.aarmos.io/docs/avar-spec");
|
|
321
|
+
} catch (err) {
|
|
322
|
+
console.error(`\u2717 invalid JSON: ${String(err)}`);
|
|
323
|
+
process.exit(1);
|
|
324
|
+
}
|
|
325
|
+
});
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
// src/index.ts
|
|
329
|
+
var program = new Command6();
|
|
330
|
+
program.name("aarmos").description(
|
|
331
|
+
"Run your agent locally, across any protocol, with a signed receipt \u2014 in 60 seconds."
|
|
332
|
+
).version("0.1.0");
|
|
333
|
+
program.addCommand(initCommand());
|
|
334
|
+
program.addCommand(runCommand());
|
|
335
|
+
program.addCommand(proxyCommand());
|
|
336
|
+
program.addCommand(daemonCommand());
|
|
337
|
+
program.addCommand(verifyCommand());
|
|
338
|
+
program.parseAsync(process.argv).catch((err) => {
|
|
339
|
+
console.error(err instanceof Error ? err.message : String(err));
|
|
340
|
+
process.exit(1);
|
|
341
|
+
});
|
package/package.json
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@aarmos/cli",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Aarmos CLI — run any agent locally, across any protocol (MCP, OpenAPI, deep-link), with a signed AVAR receipt on every execution. Sovereign runtime, universal tool gateway, verifiable governance.",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"aarmos",
|
|
7
|
+
"agent",
|
|
8
|
+
"agent-runtime",
|
|
9
|
+
"mcp",
|
|
10
|
+
"openapi",
|
|
11
|
+
"avar",
|
|
12
|
+
"local-first",
|
|
13
|
+
"policy",
|
|
14
|
+
"audit",
|
|
15
|
+
"governance"
|
|
16
|
+
],
|
|
17
|
+
"bin": {
|
|
18
|
+
"aarmos": "./dist/index.js"
|
|
19
|
+
},
|
|
20
|
+
"type": "module",
|
|
21
|
+
"scripts": {
|
|
22
|
+
"build": "tsup",
|
|
23
|
+
"dev": "tsx src/index.ts",
|
|
24
|
+
"test": "node --test --experimental-strip-types test/*.test.ts",
|
|
25
|
+
"prepublishOnly": "npm run build && npm test"
|
|
26
|
+
},
|
|
27
|
+
"files": [
|
|
28
|
+
"dist",
|
|
29
|
+
"README.md",
|
|
30
|
+
"LICENSE"
|
|
31
|
+
],
|
|
32
|
+
"publishConfig": {
|
|
33
|
+
"access": "public"
|
|
34
|
+
},
|
|
35
|
+
"repository": {
|
|
36
|
+
"type": "git",
|
|
37
|
+
"url": "git+https://github.com/aarmatix/aarmos.git",
|
|
38
|
+
"directory": "packages/aarmos-cli"
|
|
39
|
+
},
|
|
40
|
+
"homepage": "https://www.aarmos.io",
|
|
41
|
+
"bugs": {
|
|
42
|
+
"url": "https://github.com/aarmatix/aarmos/issues"
|
|
43
|
+
},
|
|
44
|
+
"author": "Aarmatix LLC",
|
|
45
|
+
"license": "Apache-2.0",
|
|
46
|
+
"dependencies": {
|
|
47
|
+
"commander": "^12.1.0",
|
|
48
|
+
"zod": "^3.23.8"
|
|
49
|
+
},
|
|
50
|
+
"devDependencies": {
|
|
51
|
+
"@types/node": "^22.5.0",
|
|
52
|
+
"tsup": "^8.3.0",
|
|
53
|
+
"tsx": "^4.19.0",
|
|
54
|
+
"typescript": "^5.6.2"
|
|
55
|
+
},
|
|
56
|
+
"engines": {
|
|
57
|
+
"node": ">=18.17"
|
|
58
|
+
}
|
|
59
|
+
}
|