@pulsemcp/air-cli 0.0.1

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/README.md ADDED
@@ -0,0 +1,47 @@
1
+ # @pulsemcp/air-cli
2
+
3
+ CLI for the [AIR](https://github.com/pulsemcp/air) framework. Validates configs, lists artifacts, initializes new setups, and starts agent sessions.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install -g @pulsemcp/air-cli
9
+ ```
10
+
11
+ ## Commands
12
+
13
+ ```bash
14
+ # Initialize a new AIR configuration at ~/.air/
15
+ air init
16
+
17
+ # Validate a JSON file against its AIR schema
18
+ air validate ~/.air/air.json
19
+ air validate ~/.air/mcp/mcp.json
20
+
21
+ # List available artifacts
22
+ air list skills
23
+ air list mcp
24
+ air list roots
25
+
26
+ # Start an agent session
27
+ air start claude
28
+ air start claude --root web-app
29
+ air start claude --root web-app --dry-run
30
+ ```
31
+
32
+ ## Agent Adapters
33
+
34
+ `air start <agent>` discovers adapters dynamically. Install the adapter package for your agent:
35
+
36
+ ```bash
37
+ # Claude Code (officially maintained)
38
+ npm install -g @pulsemcp/air-adapter-claude
39
+ ```
40
+
41
+ The CLI looks for `@pulsemcp/air-adapter-<agent>` packages. If the package is installed, the agent is available.
42
+
43
+ ## Environment Variables
44
+
45
+ | Variable | Description |
46
+ |----------|-------------|
47
+ | `AIR_CONFIG` | Override the path to `air.json` (default: `~/.air/air.json`) |
@@ -0,0 +1,11 @@
1
+ import type { AgentAdapter } from "@pulsemcp/air-core";
2
+ /**
3
+ * Find an adapter by agent name.
4
+ * Returns null if the adapter package isn't installed.
5
+ */
6
+ export declare function findAdapter(name: string): Promise<AgentAdapter | null>;
7
+ /**
8
+ * List all available adapter names (installed packages only).
9
+ */
10
+ export declare function listAvailableAdapters(): Promise<string[]>;
11
+ //# sourceMappingURL=adapter-registry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"adapter-registry.d.ts","sourceRoot":"","sources":["../src/adapter-registry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAgB,MAAM,oBAAoB,CAAC;AAUrE;;;GAGG;AACH,wBAAsB,WAAW,CAC/B,IAAI,EAAE,MAAM,GACX,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC,CAsB9B;AAED;;GAEG;AACH,wBAAsB,qBAAqB,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC,CAW/D"}
@@ -0,0 +1,52 @@
1
+ /**
2
+ * Known adapter packages. The CLI tries to dynamically import each one.
3
+ * If the package is installed, its adapter is available. If not, it's skipped.
4
+ */
5
+ const KNOWN_ADAPTERS = [
6
+ { name: "claude", packageName: "@pulsemcp/air-adapter-claude" },
7
+ ];
8
+ /**
9
+ * Find an adapter by agent name.
10
+ * Returns null if the adapter package isn't installed.
11
+ */
12
+ export async function findAdapter(name) {
13
+ // Check known adapters first
14
+ for (const known of KNOWN_ADAPTERS) {
15
+ if (known.name === name) {
16
+ try {
17
+ const mod = await import(known.packageName);
18
+ const ext = mod.default;
19
+ return ext?.adapter ?? null;
20
+ }
21
+ catch {
22
+ return null;
23
+ }
24
+ }
25
+ }
26
+ // Try convention-based package name: @pulsemcp/air-adapter-{name}
27
+ try {
28
+ const mod = await import(`@pulsemcp/air-adapter-${name}`);
29
+ const ext = mod.default;
30
+ return ext?.adapter ?? null;
31
+ }
32
+ catch {
33
+ return null;
34
+ }
35
+ }
36
+ /**
37
+ * List all available adapter names (installed packages only).
38
+ */
39
+ export async function listAvailableAdapters() {
40
+ const available = [];
41
+ for (const known of KNOWN_ADAPTERS) {
42
+ try {
43
+ await import(known.packageName);
44
+ available.push(known.name);
45
+ }
46
+ catch {
47
+ // Not installed
48
+ }
49
+ }
50
+ return available;
51
+ }
52
+ //# sourceMappingURL=adapter-registry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"adapter-registry.js","sourceRoot":"","sources":["../src/adapter-registry.ts"],"names":[],"mappings":"AAEA;;;GAGG;AACH,MAAM,cAAc,GAA4C;IAC9D,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,8BAA8B,EAAE;CAChE,CAAC;AAEF;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,WAAW,CAC/B,IAAY;IAEZ,6BAA6B;IAC7B,KAAK,MAAM,KAAK,IAAI,cAAc,EAAE,CAAC;QACnC,IAAI,KAAK,CAAC,IAAI,KAAK,IAAI,EAAE,CAAC;YACxB,IAAI,CAAC;gBACH,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;gBAC5C,MAAM,GAAG,GAAG,GAAG,CAAC,OAAmC,CAAC;gBACpD,OAAO,GAAG,EAAE,OAAO,IAAI,IAAI,CAAC;YAC9B,CAAC;YAAC,MAAM,CAAC;gBACP,OAAO,IAAI,CAAC;YACd,CAAC;QACH,CAAC;IACH,CAAC;IAED,kEAAkE;IAClE,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC,yBAAyB,IAAI,EAAE,CAAC,CAAC;QAC1D,MAAM,GAAG,GAAG,GAAG,CAAC,OAAmC,CAAC;QACpD,OAAO,GAAG,EAAE,OAAO,IAAI,IAAI,CAAC;IAC9B,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,qBAAqB;IACzC,MAAM,SAAS,GAAa,EAAE,CAAC;IAC/B,KAAK,MAAM,KAAK,IAAI,cAAc,EAAE,CAAC;QACnC,IAAI,CAAC;YACH,MAAM,MAAM,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;YAChC,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAC7B,CAAC;QAAC,MAAM,CAAC;YACP,gBAAgB;QAClB,CAAC;IACH,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC"}
@@ -0,0 +1,3 @@
1
+ import { Command } from "commander";
2
+ export declare function initCommand(): Command;
3
+ //# sourceMappingURL=init.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAKpC,wBAAgB,WAAW,IAAI,OAAO,CA4DrC"}
@@ -0,0 +1,52 @@
1
+ import { Command } from "commander";
2
+ import { writeFileSync, existsSync, mkdirSync } from "fs";
3
+ import { resolve, dirname } from "path";
4
+ import { getDefaultAirJsonPath } from "@pulsemcp/air-core";
5
+ export function initCommand() {
6
+ const cmd = new Command("init")
7
+ .description("Initialize a new AIR configuration at ~/.air/")
8
+ .action(() => {
9
+ const airJsonPath = getDefaultAirJsonPath();
10
+ const airDir = dirname(airJsonPath);
11
+ if (existsSync(airJsonPath)) {
12
+ console.error(`Error: ${airJsonPath} already exists.`);
13
+ process.exit(1);
14
+ }
15
+ mkdirSync(airDir, { recursive: true });
16
+ const airJson = {
17
+ name: "my-config",
18
+ description: "",
19
+ skills: ["./skills/skills.json"],
20
+ references: ["./references/references.json"],
21
+ mcp: ["./mcp/mcp.json"],
22
+ plugins: ["./plugins/plugins.json"],
23
+ roots: ["./roots/roots.json"],
24
+ hooks: ["./hooks/hooks.json"],
25
+ };
26
+ const emptyIndex = () => "{}\n";
27
+ writeFileSync(airJsonPath, JSON.stringify(airJson, null, 2) + "\n");
28
+ const files = [
29
+ ["skills/skills.json", emptyIndex()],
30
+ ["references/references.json", emptyIndex()],
31
+ ["mcp/mcp.json", emptyIndex()],
32
+ ["plugins/plugins.json", emptyIndex()],
33
+ ["roots/roots.json", emptyIndex()],
34
+ ["hooks/hooks.json", emptyIndex()],
35
+ ];
36
+ for (const [filename, content] of files) {
37
+ const filePath = resolve(airDir, filename);
38
+ mkdirSync(dirname(filePath), { recursive: true });
39
+ if (!existsSync(filePath)) {
40
+ writeFileSync(filePath, content);
41
+ }
42
+ }
43
+ console.log(`Initialized AIR configuration at ${airDir}/:`);
44
+ console.log(" air.json");
45
+ for (const [filename] of files) {
46
+ console.log(` ${filename}`);
47
+ }
48
+ console.log("\nEdit air.json to configure your setup. Run 'air validate ~/.air/air.json' to check.");
49
+ });
50
+ return cmd;
51
+ }
52
+ //# sourceMappingURL=init.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"init.js","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,IAAI,CAAC;AAC1D,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AACxC,OAAO,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AAE3D,MAAM,UAAU,WAAW;IACzB,MAAM,GAAG,GAAG,IAAI,OAAO,CAAC,MAAM,CAAC;SAC5B,WAAW,CAAC,+CAA+C,CAAC;SAC5D,MAAM,CAAC,GAAG,EAAE;QACX,MAAM,WAAW,GAAG,qBAAqB,EAAE,CAAC;QAC5C,MAAM,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC;QAEpC,IAAI,UAAU,CAAC,WAAW,CAAC,EAAE,CAAC;YAC5B,OAAO,CAAC,KAAK,CAAC,UAAU,WAAW,kBAAkB,CAAC,CAAC;YACvD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;QAED,SAAS,CAAC,MAAM,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAEvC,MAAM,OAAO,GAAG;YACd,IAAI,EAAE,WAAW;YACjB,WAAW,EAAE,EAAE;YACf,MAAM,EAAE,CAAC,sBAAsB,CAAC;YAChC,UAAU,EAAE,CAAC,8BAA8B,CAAC;YAC5C,GAAG,EAAE,CAAC,gBAAgB,CAAC;YACvB,OAAO,EAAE,CAAC,wBAAwB,CAAC;YACnC,KAAK,EAAE,CAAC,oBAAoB,CAAC;YAC7B,KAAK,EAAE,CAAC,oBAAoB,CAAC;SAC9B,CAAC;QAEF,MAAM,UAAU,GAAG,GAAG,EAAE,CAAC,MAAM,CAAC;QAEhC,aAAa,CACX,WAAW,EACX,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,CACxC,CAAC;QAEF,MAAM,KAAK,GAAuB;YAChC,CAAC,oBAAoB,EAAE,UAAU,EAAE,CAAC;YACpC,CAAC,4BAA4B,EAAE,UAAU,EAAE,CAAC;YAC5C,CAAC,cAAc,EAAE,UAAU,EAAE,CAAC;YAC9B,CAAC,sBAAsB,EAAE,UAAU,EAAE,CAAC;YACtC,CAAC,kBAAkB,EAAE,UAAU,EAAE,CAAC;YAClC,CAAC,kBAAkB,EAAE,UAAU,EAAE,CAAC;SACnC,CAAC;QAEF,KAAK,MAAM,CAAC,QAAQ,EAAE,OAAO,CAAC,IAAI,KAAK,EAAE,CAAC;YACxC,MAAM,QAAQ,GAAG,OAAO,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;YAC3C,SAAS,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;YAClD,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;gBAC1B,aAAa,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;YACnC,CAAC;QACH,CAAC;QAED,OAAO,CAAC,GAAG,CAAC,oCAAoC,MAAM,IAAI,CAAC,CAAC;QAC5D,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;QAC1B,KAAK,MAAM,CAAC,QAAQ,CAAC,IAAI,KAAK,EAAE,CAAC;YAC/B,OAAO,CAAC,GAAG,CAAC,KAAK,QAAQ,EAAE,CAAC,CAAC;QAC/B,CAAC;QACD,OAAO,CAAC,GAAG,CACT,uFAAuF,CACxF,CAAC;IACJ,CAAC,CAAC,CAAC;IAEL,OAAO,GAAG,CAAC;AACb,CAAC"}
@@ -0,0 +1,3 @@
1
+ import { Command } from "commander";
2
+ export declare function listCommand(): Command;
3
+ //# sourceMappingURL=list.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"list.d.ts","sourceRoot":"","sources":["../../src/commands/list.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAwBpC,wBAAgB,WAAW,IAAI,OAAO,CAsJrC"}
@@ -0,0 +1,138 @@
1
+ import { Command } from "commander";
2
+ import { getAirJsonPath, resolveArtifacts, emptyArtifacts, } from "@pulsemcp/air-core";
3
+ const VALID_TYPES = [
4
+ "skills",
5
+ "mcp",
6
+ "plugins",
7
+ "roots",
8
+ "hooks",
9
+ "references",
10
+ ];
11
+ export function listCommand() {
12
+ const cmd = new Command("list")
13
+ .description("List available artifacts (skills, mcp, plugins, roots, hooks, references)")
14
+ .argument("<type>", "Artifact type to list: skills, mcp, plugins, roots, hooks, references")
15
+ .action(async (type) => {
16
+ if (!VALID_TYPES.includes(type)) {
17
+ console.error(`Error: Unknown artifact type "${type}". Valid types: ${VALID_TYPES.join(", ")}`);
18
+ process.exit(1);
19
+ }
20
+ const airJsonPath = getAirJsonPath();
21
+ const artifacts = airJsonPath
22
+ ? await resolveArtifacts(airJsonPath)
23
+ : emptyArtifacts();
24
+ const listType = type;
25
+ switch (listType) {
26
+ case "skills": {
27
+ const entries = Object.entries(artifacts.skills);
28
+ if (entries.length === 0) {
29
+ console.log("No skills found.");
30
+ return;
31
+ }
32
+ console.log(`Skills (${entries.length}):\n`);
33
+ for (const [id, skill] of entries) {
34
+ const title = skill.title ? ` (${skill.title})` : "";
35
+ console.log(` ${id}${title}`);
36
+ console.log(` ${skill.description}`);
37
+ if (skill.references && skill.references.length > 0) {
38
+ console.log(` References: ${skill.references.join(", ")}`);
39
+ }
40
+ console.log();
41
+ }
42
+ break;
43
+ }
44
+ case "mcp": {
45
+ const entries = Object.entries(artifacts.mcp);
46
+ if (entries.length === 0) {
47
+ console.log("No MCP servers found.");
48
+ return;
49
+ }
50
+ console.log(`MCP Servers (${entries.length}):\n`);
51
+ for (const [id, server] of entries) {
52
+ const title = server.title ? ` (${server.title})` : "";
53
+ console.log(` ${id}${title}`);
54
+ if (server.description) {
55
+ console.log(` ${server.description}`);
56
+ }
57
+ console.log(` Type: ${server.type}`);
58
+ console.log();
59
+ }
60
+ break;
61
+ }
62
+ case "plugins": {
63
+ const entries = Object.entries(artifacts.plugins);
64
+ if (entries.length === 0) {
65
+ console.log("No plugins found.");
66
+ return;
67
+ }
68
+ console.log(`Plugins (${entries.length}):\n`);
69
+ for (const [id, plugin] of entries) {
70
+ const title = plugin.title ? ` (${plugin.title})` : "";
71
+ console.log(` ${id}${title}`);
72
+ console.log(` ${plugin.description}`);
73
+ console.log(` Command: ${plugin.command} ${(plugin.args || []).join(" ")}`);
74
+ console.log();
75
+ }
76
+ break;
77
+ }
78
+ case "roots": {
79
+ const entries = Object.entries(artifacts.roots);
80
+ if (entries.length === 0) {
81
+ console.log("No roots found.");
82
+ return;
83
+ }
84
+ console.log(`Roots (${entries.length}):\n`);
85
+ for (const [id, root] of entries) {
86
+ const displayName = root.display_name || id;
87
+ console.log(` ${id} (${displayName})`);
88
+ console.log(` ${root.description}`);
89
+ if (root.url) {
90
+ console.log(` URL: ${root.url}`);
91
+ }
92
+ if (root.default_mcp_servers?.length) {
93
+ console.log(` MCP Servers: ${root.default_mcp_servers.join(", ")}`);
94
+ }
95
+ if (root.default_skills?.length) {
96
+ console.log(` Skills: ${root.default_skills.join(", ")}`);
97
+ }
98
+ console.log();
99
+ }
100
+ break;
101
+ }
102
+ case "hooks": {
103
+ const entries = Object.entries(artifacts.hooks);
104
+ if (entries.length === 0) {
105
+ console.log("No hooks found.");
106
+ return;
107
+ }
108
+ console.log(`Hooks (${entries.length}):\n`);
109
+ for (const [id, hook] of entries) {
110
+ const title = hook.title ? ` (${hook.title})` : "";
111
+ console.log(` ${id}${title}`);
112
+ console.log(` ${hook.description}`);
113
+ console.log(` Event: ${hook.event}`);
114
+ console.log();
115
+ }
116
+ break;
117
+ }
118
+ case "references": {
119
+ const entries = Object.entries(artifacts.references);
120
+ if (entries.length === 0) {
121
+ console.log("No references found.");
122
+ return;
123
+ }
124
+ console.log(`References (${entries.length}):\n`);
125
+ for (const [id, ref] of entries) {
126
+ const title = ref.title ? ` (${ref.title})` : "";
127
+ console.log(` ${id}${title}`);
128
+ console.log(` ${ref.description}`);
129
+ console.log(` File: ${ref.file}`);
130
+ console.log();
131
+ }
132
+ break;
133
+ }
134
+ }
135
+ });
136
+ return cmd;
137
+ }
138
+ //# sourceMappingURL=list.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"list.js","sourceRoot":"","sources":["../../src/commands/list.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import { Command } from "commander";
2
+ export declare function startCommand(): Command;
3
+ //# sourceMappingURL=start.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"start.d.ts","sourceRoot":"","sources":["../../src/commands/start.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAUpC,wBAAgB,YAAY,IAAI,OAAO,CAkFtC"}
@@ -0,0 +1,112 @@
1
+ import { Command } from "commander";
2
+ import { getAirJsonPath, resolveArtifacts, emptyArtifacts, } from "@pulsemcp/air-core";
3
+ import { findAdapter, listAvailableAdapters } from "../adapter-registry.js";
4
+ export function startCommand() {
5
+ const cmd = new Command("start")
6
+ .description("Start an agent session with AIR configs loaded")
7
+ .argument("<agent>", "Agent to start (e.g., claude)")
8
+ .option("--root <name>", "Root to start the session in")
9
+ .option("--dry-run", "Show what would be activated without starting")
10
+ .option("--skip-confirmation", "Don't prompt for confirmation before starting")
11
+ .action(async (agent, options) => {
12
+ // Try to find the adapter
13
+ const adapter = await findAdapter(agent);
14
+ if (!adapter) {
15
+ const available = await listAvailableAdapters();
16
+ const availableMsg = available.length > 0
17
+ ? `Available: ${available.join(", ")}`
18
+ : "No adapters installed";
19
+ console.error(`Error: No adapter found for "${agent}". ${availableMsg}.\n` +
20
+ `Install an adapter: npm install @pulsemcp/air-adapter-${agent}`);
21
+ process.exit(1);
22
+ }
23
+ // Load air.json
24
+ const airJsonPath = getAirJsonPath();
25
+ const artifacts = airJsonPath
26
+ ? await resolveArtifacts(airJsonPath)
27
+ : emptyArtifacts();
28
+ // Resolve root if specified
29
+ let root;
30
+ if (options.root) {
31
+ root = artifacts.roots[options.root];
32
+ if (!root) {
33
+ console.error(`Error: Root "${options.root}" not found. Available roots: ${Object.keys(artifacts.roots).join(", ") || "(none)"}`);
34
+ process.exit(1);
35
+ }
36
+ }
37
+ // Generate config
38
+ const sessionConfig = adapter.generateConfig(artifacts, root);
39
+ // Dry run
40
+ if (options.dryRun) {
41
+ printDryRun(agent, artifacts, root);
42
+ process.exit(0);
43
+ }
44
+ // Check if agent is available
45
+ const available = await adapter.isAvailable();
46
+ if (!available) {
47
+ console.error(`Error: ${adapter.displayName} is not installed or not in PATH.`);
48
+ process.exit(1);
49
+ }
50
+ printDryRun(agent, artifacts, root);
51
+ const startCmd = adapter.buildStartCommand(sessionConfig);
52
+ console.log(`\nStarting ${adapter.displayName}...`);
53
+ console.log(`Command: ${startCmd.command} ${startCmd.args.join(" ")}`);
54
+ });
55
+ return cmd;
56
+ }
57
+ function printDryRun(agent, artifacts, root) {
58
+ console.log(`\n=== AIR Session Configuration ===`);
59
+ console.log(`Agent: ${agent}`);
60
+ if (root) {
61
+ console.log(`Root: ${root.name} \u2014 ${root.description}`);
62
+ }
63
+ const mcpIds = root?.default_mcp_servers || Object.keys(artifacts.mcp);
64
+ const skillIds = root?.default_skills || Object.keys(artifacts.skills);
65
+ const pluginIds = root?.default_plugins || Object.keys(artifacts.plugins);
66
+ const hookIds = root?.default_hooks || Object.keys(artifacts.hooks);
67
+ console.log(`\nMCP Servers (${mcpIds.length}):`);
68
+ for (const id of mcpIds) {
69
+ const server = artifacts.mcp[id];
70
+ if (server) {
71
+ console.log(` \u2022 ${id} \u2014 ${server.description || server.title || "(no description)"}`);
72
+ }
73
+ else {
74
+ console.log(` \u2022 ${id} \u2014 (not found)`);
75
+ }
76
+ }
77
+ console.log(`\nSkills (${skillIds.length}):`);
78
+ for (const id of skillIds) {
79
+ const skill = artifacts.skills[id];
80
+ if (skill) {
81
+ console.log(` \u2022 ${id} \u2014 ${skill.description}`);
82
+ }
83
+ else {
84
+ console.log(` \u2022 ${id} \u2014 (not found)`);
85
+ }
86
+ }
87
+ if (pluginIds.length > 0) {
88
+ console.log(`\nPlugins (${pluginIds.length}):`);
89
+ for (const id of pluginIds) {
90
+ const plugin = artifacts.plugins[id];
91
+ if (plugin) {
92
+ console.log(` \u2022 ${id} \u2014 ${plugin.description}`);
93
+ }
94
+ else {
95
+ console.log(` \u2022 ${id} \u2014 (not found)`);
96
+ }
97
+ }
98
+ }
99
+ if (hookIds.length > 0) {
100
+ console.log(`\nHooks (${hookIds.length}):`);
101
+ for (const id of hookIds) {
102
+ const hook = artifacts.hooks[id];
103
+ if (hook) {
104
+ console.log(` \u2022 ${id} \u2014 ${hook.description}`);
105
+ }
106
+ else {
107
+ console.log(` \u2022 ${id} \u2014 (not found)`);
108
+ }
109
+ }
110
+ }
111
+ }
112
+ //# sourceMappingURL=start.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"start.js","sourceRoot":"","sources":["../../src/commands/start.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import { Command } from "commander";
2
+ export declare function validateCommand(): Command;
3
+ //# sourceMappingURL=validate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validate.d.ts","sourceRoot":"","sources":["../../src/commands/validate.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAWpC,wBAAgB,eAAe,IAAI,OAAO,CA2EzC"}
@@ -0,0 +1,62 @@
1
+ import { Command } from "commander";
2
+ import { readFileSync } from "fs";
3
+ import { resolve } from "path";
4
+ import { detectSchemaType, detectSchemaFromValue, isValidSchemaType, validateJson, } from "@pulsemcp/air-core";
5
+ export function validateCommand() {
6
+ const cmd = new Command("validate")
7
+ .description("Validate a JSON file against its AIR schema")
8
+ .argument("<file>", "Path to the JSON file to validate")
9
+ .option("--schema <type>", "Override schema detection (air, skills, references, mcp, plugins, roots, hooks)")
10
+ .action((file, options) => {
11
+ const filePath = resolve(process.cwd(), file);
12
+ let data;
13
+ try {
14
+ const content = readFileSync(filePath, "utf-8");
15
+ data = JSON.parse(content);
16
+ }
17
+ catch (err) {
18
+ const message = err instanceof Error ? err.message : "Unknown error";
19
+ console.error(`Error: Could not read or parse "${file}": ${message}`);
20
+ process.exit(1);
21
+ }
22
+ // Determine schema type: --schema flag > $schema in JSON > filename substring
23
+ let schemaType = null;
24
+ if (options.schema) {
25
+ if (!isValidSchemaType(options.schema)) {
26
+ console.error(`Error: Unknown schema type "${options.schema}". Valid types: air, skills, references, mcp, plugins, roots, hooks`);
27
+ process.exit(1);
28
+ }
29
+ schemaType = options.schema;
30
+ }
31
+ if (!schemaType &&
32
+ data &&
33
+ typeof data === "object" &&
34
+ !Array.isArray(data)) {
35
+ const schemaValue = data.$schema;
36
+ if (typeof schemaValue === "string") {
37
+ schemaType = detectSchemaFromValue(schemaValue);
38
+ }
39
+ }
40
+ if (!schemaType) {
41
+ schemaType = detectSchemaType(file);
42
+ }
43
+ if (!schemaType) {
44
+ console.error(`Error: Could not detect schema type for "${file}". Use --schema to specify.`);
45
+ process.exit(1);
46
+ }
47
+ const result = validateJson(data, schemaType);
48
+ if (result.valid) {
49
+ console.log(`\u2713 ${file} is valid (schema: ${schemaType})`);
50
+ process.exit(0);
51
+ }
52
+ else {
53
+ console.error(`\u2717 ${file} has validation errors (schema: ${schemaType}):`);
54
+ for (const error of result.errors) {
55
+ console.error(` ${error.path}: ${error.message}`);
56
+ }
57
+ process.exit(1);
58
+ }
59
+ });
60
+ return cmd;
61
+ }
62
+ //# sourceMappingURL=validate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validate.js","sourceRoot":"","sources":["../../src/commands/validate.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
package/dist/index.js ADDED
@@ -0,0 +1,17 @@
1
+ #!/usr/bin/env node
2
+ import { Command } from "commander";
3
+ import { validateCommand } from "./commands/validate.js";
4
+ import { startCommand } from "./commands/start.js";
5
+ import { listCommand } from "./commands/list.js";
6
+ import { initCommand } from "./commands/init.js";
7
+ const program = new Command();
8
+ program
9
+ .name("air")
10
+ .description("AIR \u2014 Agent Infrastructure Repository CLI")
11
+ .version("0.0.1");
12
+ program.addCommand(validateCommand());
13
+ program.addCommand(startCommand());
14
+ program.addCommand(listCommand());
15
+ program.addCommand(initCommand());
16
+ program.parseAsync();
17
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAEjD,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;AAE9B,OAAO;KACJ,IAAI,CAAC,KAAK,CAAC;KACX,WAAW,CAAC,gDAAgD,CAAC;KAC7D,OAAO,CAAC,OAAO,CAAC,CAAC;AAEpB,OAAO,CAAC,UAAU,CAAC,eAAe,EAAE,CAAC,CAAC;AACtC,OAAO,CAAC,UAAU,CAAC,YAAY,EAAE,CAAC,CAAC;AACnC,OAAO,CAAC,UAAU,CAAC,WAAW,EAAE,CAAC,CAAC;AAClC,OAAO,CAAC,UAAU,CAAC,WAAW,EAAE,CAAC,CAAC;AAElC,OAAO,CAAC,UAAU,EAAE,CAAC"}
package/package.json ADDED
@@ -0,0 +1,43 @@
1
+ {
2
+ "name": "@pulsemcp/air-cli",
3
+ "version": "0.0.1",
4
+ "publishConfig": {
5
+ "access": "public"
6
+ },
7
+ "repository": {
8
+ "type": "git",
9
+ "url": "https://github.com/pulsemcp/air.git",
10
+ "directory": "packages/cli"
11
+ },
12
+ "description": "CLI for the AIR (Agent Infrastructure Repository) framework",
13
+ "type": "module",
14
+ "bin": {
15
+ "air": "./dist/index.js"
16
+ },
17
+ "main": "./dist/index.js",
18
+ "files": [
19
+ "dist/"
20
+ ],
21
+ "scripts": {
22
+ "build": "tsc",
23
+ "dev": "tsx src/index.ts",
24
+ "test": "vitest run",
25
+ "test:watch": "vitest",
26
+ "lint": "tsc --noEmit"
27
+ },
28
+ "dependencies": {
29
+ "@pulsemcp/air-core": "0.0.1",
30
+ "@pulsemcp/air-adapter-claude": "0.0.1",
31
+ "commander": "^12.1.0",
32
+ "chalk": "^5.3.0"
33
+ },
34
+ "devDependencies": {
35
+ "@types/node": "^22.10.0",
36
+ "tsx": "^4.19.0",
37
+ "typescript": "^5.7.0",
38
+ "vitest": "^2.1.0"
39
+ },
40
+ "engines": {
41
+ "node": ">=18"
42
+ }
43
+ }