add-mcp 0.1.1 → 0.2.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.
Files changed (3) hide show
  1. package/README.md +28 -13
  2. package/dist/index.js +175 -70
  3. package/package.json +3 -3
package/README.md CHANGED
@@ -1,13 +1,9 @@
1
1
  # add-mcp
2
2
 
3
- Install MCP servers onto coding agents with a single command.
4
-
5
- <!-- agent-list:start -->
3
+ Add MCP servers to your favorite coding agents with a single command.
6
4
 
7
5
  Supports **OpenCode**, **Claude Code**, **Codex**, **Cursor**, and [5 more](#supported-agents).
8
6
 
9
- <!-- agent-list:end -->
10
-
11
7
  ## Install an MCP Server
12
8
 
13
9
  ```bash
@@ -43,7 +39,7 @@ npx add-mcp "node /path/to/server.js --port 3000"
43
39
  | `--type <type>` | Alias for `--transport` |
44
40
  | `-n, --name <name>` | Server name (auto-inferred if not provided) |
45
41
  | `-y, --yes` | Skip all confirmation prompts |
46
- | `--all` | Install to all agents without prompts |
42
+ | `--all` | Install to all agents |
47
43
 
48
44
  ### Examples
49
45
 
@@ -60,8 +56,11 @@ npx add-mcp @modelcontextprotocol/server-postgres --name postgres
60
56
  # Non-interactive installation (CI/CD friendly)
61
57
  npx add-mcp https://mcp.example.com/mcp -g -a claude-code -y
62
58
 
63
- # Install to all agents without prompts
59
+ # Install to all agents
64
60
  npx add-mcp mcp-server-github --all
61
+
62
+ # Install to all agents, globally, without prompts
63
+ npx add-mcp mcp-server-github --all -g -y
65
64
  ```
66
65
 
67
66
  ### Installation Scope
@@ -71,6 +70,26 @@ npx add-mcp mcp-server-github --all
71
70
  | **Project** | (default) | `.cursor/mcp.json` etc. | Committed with your project, shared with team |
72
71
  | **Global** | `-g` | `~/.cursor/mcp.json` | Available across all projects |
73
72
 
73
+ ### Smart Detection
74
+
75
+ The CLI automatically detects agents based on your environment:
76
+
77
+ **Default (project mode):**
78
+
79
+ - Detects project-level config files (`.cursor/`, `.vscode/`, `.mcp.json`, etc.)
80
+ - Also detects globally-installed agents that only support global config (Claude Desktop, Codex, Zed)
81
+ - Agents are routed appropriately: project-capable agents use project config, global-only agents use global config
82
+
83
+ **With `-g` (global mode):**
84
+
85
+ - Detects all globally-installed agents
86
+ - All agents use global config
87
+
88
+ **No agents detected:**
89
+
90
+ - Interactive mode: Shows error with guidance to use `--global` or run in a project
91
+ - With `--yes`: Installs to all project-capable agents
92
+
74
93
  ## Transport Types
75
94
 
76
95
  MCP supports different transport mechanisms for remote servers:
@@ -86,8 +105,6 @@ Local servers (npm packages, commands) always use **stdio** transport.
86
105
 
87
106
  MCP servers can be installed to any of these agents:
88
107
 
89
- <!-- supported-agents:start -->
90
-
91
108
  | Agent | `--agent` | Project Path | Global Path |
92
109
  | -------------- | ---------------- | ----------------------- | ----------------------------------------------------------------- |
93
110
  | Claude Code | `claude-code` | `.mcp.json` | `~/.claude.json` |
@@ -95,16 +112,14 @@ MCP servers can be installed to any of these agents:
95
112
  | Codex | `codex` | - | `~/.codex/config.toml` |
96
113
  | Cursor | `cursor` | `.cursor/mcp.json` | `~/.cursor/mcp.json` |
97
114
  | Gemini CLI | `gemini-cli` | `.gemini/settings.json` | `~/.gemini/settings.json` |
98
- | Goose | `goose` | - | `~/.config/goose/config.yaml` |
115
+ | Goose | `goose` | `.goose/config.yaml` | `~/.config/goose/config.yaml` |
99
116
  | OpenCode | `opencode` | `.opencode.json` | `~/.config/opencode/opencode.json` |
100
117
  | VS Code | `vscode` | `.vscode/mcp.json` | `~/Library/Application Support/Code/User/mcp.json` |
101
118
  | Zed | `zed` | - | `~/.config/zed/settings.json` |
102
119
 
103
- <!-- supported-agents:end -->
104
-
105
120
  **Aliases:** `github-copilot` → `vscode`
106
121
 
107
- The CLI automatically detects which coding agents you have installed. If none are detected, you'll be prompted to select which agents to install to.
122
+ The CLI uses smart detection to find agents in your project directory and globally installed agents. See [Smart Detection](#smart-detection) for details.
108
123
 
109
124
  ### Transport Support
110
125
 
package/dist/index.js CHANGED
@@ -111,10 +111,11 @@ var agents = {
111
111
  displayName: "Claude Code",
112
112
  configPath: join(home, ".claude.json"),
113
113
  localConfigPath: ".mcp.json",
114
+ projectDetectPaths: [".mcp.json", ".claude"],
114
115
  configKey: "mcpServers",
115
116
  format: "json",
116
117
  supportedTransports: ["stdio", "http", "sse"],
117
- detectInstalled: async () => {
118
+ detectGlobalInstall: async () => {
118
119
  return existsSync(join(home, ".claude"));
119
120
  }
120
121
  },
@@ -122,10 +123,12 @@ var agents = {
122
123
  name: "claude-desktop",
123
124
  displayName: "Claude Desktop",
124
125
  configPath: join(appSupport, "Claude", "claude_desktop_config.json"),
126
+ projectDetectPaths: [],
127
+ // Global only - no project support
125
128
  configKey: "mcpServers",
126
129
  format: "json",
127
130
  supportedTransports: ["stdio", "http", "sse"],
128
- detectInstalled: async () => {
131
+ detectGlobalInstall: async () => {
129
132
  return existsSync(join(appSupport, "Claude"));
130
133
  }
131
134
  },
@@ -136,10 +139,12 @@ var agents = {
136
139
  process.env.CODEX_HOME || join(home, ".codex"),
137
140
  "config.toml"
138
141
  ),
142
+ projectDetectPaths: [],
143
+ // Global only - no project support
139
144
  configKey: "mcp_servers",
140
145
  format: "toml",
141
146
  supportedTransports: ["stdio", "http", "sse"],
142
- detectInstalled: async () => {
147
+ detectGlobalInstall: async () => {
143
148
  return existsSync(join(home, ".codex"));
144
149
  },
145
150
  transformConfig: transformCodexConfig
@@ -149,10 +154,11 @@ var agents = {
149
154
  displayName: "Cursor",
150
155
  configPath: join(home, ".cursor", "mcp.json"),
151
156
  localConfigPath: ".cursor/mcp.json",
157
+ projectDetectPaths: [".cursor"],
152
158
  configKey: "mcpServers",
153
159
  format: "json",
154
160
  supportedTransports: ["stdio", "http", "sse"],
155
- detectInstalled: async () => {
161
+ detectGlobalInstall: async () => {
156
162
  return existsSync(join(home, ".cursor"));
157
163
  }
158
164
  },
@@ -161,10 +167,11 @@ var agents = {
161
167
  displayName: "Gemini CLI",
162
168
  configPath: join(home, ".gemini", "settings.json"),
163
169
  localConfigPath: ".gemini/settings.json",
170
+ projectDetectPaths: [".gemini"],
164
171
  configKey: "mcpServers",
165
172
  format: "json",
166
173
  supportedTransports: ["stdio", "http", "sse"],
167
- detectInstalled: async () => {
174
+ detectGlobalInstall: async () => {
168
175
  return existsSync(join(home, ".gemini"));
169
176
  }
170
177
  },
@@ -172,11 +179,13 @@ var agents = {
172
179
  name: "goose",
173
180
  displayName: "Goose",
174
181
  configPath: join(home, ".config", "goose", "config.yaml"),
182
+ localConfigPath: ".goose/config.yaml",
183
+ projectDetectPaths: [".goose"],
175
184
  configKey: "extensions",
176
185
  format: "yaml",
177
186
  supportedTransports: ["stdio", "http"],
178
187
  // Goose does not support SSE
179
- detectInstalled: async () => {
188
+ detectGlobalInstall: async () => {
180
189
  return existsSync(join(home, ".config", "goose"));
181
190
  },
182
191
  transformConfig: transformGooseConfig
@@ -186,10 +195,11 @@ var agents = {
186
195
  displayName: "OpenCode",
187
196
  configPath: join(home, ".config", "opencode", "opencode.json"),
188
197
  localConfigPath: ".opencode.json",
198
+ projectDetectPaths: [".opencode.json", ".opencode"],
189
199
  configKey: "mcp",
190
200
  format: "json",
191
201
  supportedTransports: ["stdio", "http", "sse"],
192
- detectInstalled: async () => {
202
+ detectGlobalInstall: async () => {
193
203
  return existsSync(join(home, ".config", "opencode"));
194
204
  },
195
205
  transformConfig: transformOpenCodeConfig
@@ -199,10 +209,11 @@ var agents = {
199
209
  displayName: "VS Code",
200
210
  configPath: join(vscodePath, "mcp.json"),
201
211
  localConfigPath: ".vscode/mcp.json",
212
+ projectDetectPaths: [".vscode"],
202
213
  configKey: "mcpServers",
203
214
  format: "json",
204
215
  supportedTransports: ["stdio", "http", "sse"],
205
- detectInstalled: async () => {
216
+ detectGlobalInstall: async () => {
206
217
  return existsSync(vscodePath);
207
218
  }
208
219
  },
@@ -214,10 +225,12 @@ var agents = {
214
225
  "Zed",
215
226
  "settings.json"
216
227
  ) : join(home, ".config", "zed", "settings.json"),
228
+ projectDetectPaths: [],
229
+ // Global only - no project support
217
230
  configKey: "context_servers",
218
231
  format: "json",
219
232
  supportedTransports: ["stdio", "http", "sse"],
220
- detectInstalled: async () => {
233
+ detectGlobalInstall: async () => {
221
234
  return existsSync(join(home, ".config", "zed")) || existsSync(join(process.env.APPDATA || "", "Zed"));
222
235
  },
223
236
  transformConfig: transformZedConfig
@@ -226,14 +239,46 @@ var agents = {
226
239
  function getAgentTypes() {
227
240
  return Object.keys(agents);
228
241
  }
229
- async function detectInstalledAgents() {
230
- const installed = [];
242
+ function supportsProjectConfig(agentType) {
243
+ return agents[agentType].localConfigPath !== void 0;
244
+ }
245
+ function getProjectCapableAgents() {
246
+ return Object.keys(agents).filter(
247
+ (type) => supportsProjectConfig(type)
248
+ );
249
+ }
250
+ function detectProjectAgents(cwd) {
251
+ const dir = cwd || process.cwd();
252
+ const detected = [];
231
253
  for (const [type, config] of Object.entries(agents)) {
232
- if (await config.detectInstalled()) {
233
- installed.push(type);
254
+ if (!config.localConfigPath) continue;
255
+ for (const detectPath of config.projectDetectPaths) {
256
+ if (existsSync(join(dir, detectPath))) {
257
+ detected.push(type);
258
+ break;
259
+ }
234
260
  }
235
261
  }
236
- return installed;
262
+ return detected;
263
+ }
264
+ async function detectGlobalOnlyAgents() {
265
+ const detected = [];
266
+ for (const [type, config] of Object.entries(agents)) {
267
+ if (config.localConfigPath) continue;
268
+ if (await config.detectGlobalInstall()) {
269
+ detected.push(type);
270
+ }
271
+ }
272
+ return detected;
273
+ }
274
+ async function detectAllGlobalAgents() {
275
+ const detected = [];
276
+ for (const [type, config] of Object.entries(agents)) {
277
+ if (await config.detectGlobalInstall()) {
278
+ detected.push(type);
279
+ }
280
+ }
281
+ return detected;
237
282
  }
238
283
  function isTransportSupported(agentType, transport) {
239
284
  return agents[agentType].supportedTransports.includes(transport);
@@ -601,24 +646,26 @@ function installServerForAgent(serverName, serverConfig, agentType, options = {}
601
646
  function installServer(serverName, serverConfig, agentTypes, options = {}) {
602
647
  const results = /* @__PURE__ */ new Map();
603
648
  for (const agentType of agentTypes) {
649
+ const routing = options.routing?.get(agentType);
650
+ const installOptions = {
651
+ local: routing === "local",
652
+ cwd: options.cwd
653
+ };
604
654
  const result = installServerForAgent(
605
655
  serverName,
606
656
  serverConfig,
607
657
  agentType,
608
- options
658
+ installOptions
609
659
  );
610
660
  results.set(agentType, result);
611
661
  }
612
662
  return results;
613
663
  }
614
- function getAgentsWithLocalSupport() {
615
- return Object.entries(agents).filter(([_, config]) => config.localConfigPath !== void 0).map(([type, _]) => type);
616
- }
617
664
 
618
665
  // package.json
619
666
  var package_default = {
620
667
  name: "add-mcp",
621
- version: "0.1.1",
668
+ version: "0.2.0",
622
669
  description: "Install MCP servers onto coding agents (Claude Code, Cursor, VS Code, OpenCode, Codex)",
623
670
  author: "Andre Landgraf <andre@neon.tech>",
624
671
  license: "Apache-2.0",
@@ -634,8 +681,8 @@ var package_default = {
634
681
  fmt: "prettier --write .",
635
682
  build: "tsup src/index.ts --format esm --dts --clean",
636
683
  dev: "tsx src/index.ts",
637
- test: "tsx tests/source-parser.test.ts && tsx tests/installer.test.ts && tsx tests/e2e/install.test.ts",
638
- "test:unit": "tsx tests/source-parser.test.ts && tsx tests/installer.test.ts",
684
+ test: "tsx tests/source-parser.test.ts && tsx tests/agents.test.ts && tsx tests/installer.test.ts && tsx tests/e2e/install.test.ts",
685
+ "test:unit": "tsx tests/source-parser.test.ts && tsx tests/agents.test.ts && tsx tests/installer.test.ts",
639
686
  "test:e2e": "tsx tests/e2e/install.test.ts",
640
687
  typecheck: "tsc --noEmit",
641
688
  prepublishOnly: "npm run build"
@@ -717,15 +764,11 @@ program.name("add-mcp").description(
717
764
  ).option(
718
765
  "-t, --transport <type>",
719
766
  "Transport type for remote servers (http, sse)"
720
- ).option("--type <type>", "Alias for --transport").option("-y, --yes", "Skip confirmation prompts").option("--all", "Install to all agents without prompts (implies -y -g)").action(async (target, options) => {
767
+ ).option("--type <type>", "Alias for --transport").option("-y, --yes", "Skip confirmation prompts").option("--all", "Install to all agents").action(async (target, options) => {
721
768
  await main(target, options);
722
769
  });
723
770
  program.parse();
724
771
  async function main(target, options) {
725
- if (options.all) {
726
- options.yes = true;
727
- options.global = true;
728
- }
729
772
  console.log();
730
773
  p.intro(chalk.bgCyan.black(" add-mcp "));
731
774
  if (!target) {
@@ -774,6 +817,7 @@ async function main(target, options) {
774
817
  });
775
818
  let targetAgents;
776
819
  const allAgentTypes = getAgentTypes();
820
+ let agentRouting = /* @__PURE__ */ new Map();
777
821
  if (options.agent && options.agent.length > 0) {
778
822
  const resolved = [];
779
823
  const invalid = [];
@@ -795,16 +839,40 @@ async function main(target, options) {
795
839
  targetAgents = allAgentTypes;
796
840
  p.log.info(`Installing to all ${targetAgents.length} agents`);
797
841
  } else {
798
- spinner2.start("Detecting installed agents...");
799
- const installedAgents = await detectInstalledAgents();
842
+ spinner2.start("Detecting agents...");
843
+ let detectedAgents;
844
+ if (options.global) {
845
+ detectedAgents = await detectAllGlobalAgents();
846
+ } else {
847
+ const projectAgents = detectProjectAgents();
848
+ const globalOnlyAgents = await detectGlobalOnlyAgents();
849
+ detectedAgents = [...projectAgents, ...globalOnlyAgents];
850
+ for (const agent of projectAgents) {
851
+ agentRouting.set(agent, "local");
852
+ }
853
+ for (const agent of globalOnlyAgents) {
854
+ agentRouting.set(agent, "global");
855
+ }
856
+ }
800
857
  spinner2.stop(
801
- `Detected ${installedAgents.length} agent${installedAgents.length !== 1 ? "s" : ""}`
858
+ `Detected ${detectedAgents.length} agent${detectedAgents.length !== 1 ? "s" : ""}`
802
859
  );
803
- if (installedAgents.length === 0) {
860
+ if (detectedAgents.length === 0) {
804
861
  if (options.yes) {
805
- targetAgents = allAgentTypes;
806
- p.log.info("Installing to all agents (none detected)");
862
+ targetAgents = getProjectCapableAgents();
863
+ for (const agent of targetAgents) {
864
+ agentRouting.set(agent, "local");
865
+ }
866
+ p.log.info(
867
+ `Installing to ${targetAgents.length} project-capable agents (none detected)`
868
+ );
807
869
  } else {
870
+ if (!options.global) {
871
+ p.log.error(
872
+ "No agents detected in this project. Use --global to install globally, or run in a project with agent config files."
873
+ );
874
+ process.exit(1);
875
+ }
808
876
  p.log.warn(
809
877
  "No coding agents detected. You can still install MCP servers."
810
878
  );
@@ -823,21 +891,25 @@ async function main(target, options) {
823
891
  }
824
892
  targetAgents = selected;
825
893
  }
826
- } else if (installedAgents.length === 1 || options.yes) {
827
- targetAgents = installedAgents;
828
- const agentNames = installedAgents.map((a) => chalk.cyan(agents[a].displayName)).join(", ");
894
+ } else if (detectedAgents.length === 1 || options.yes) {
895
+ targetAgents = detectedAgents;
896
+ const agentNames = detectedAgents.map((a) => chalk.cyan(agents[a].displayName)).join(", ");
829
897
  p.log.info(`Installing to: ${agentNames}`);
830
898
  } else {
831
- const agentChoices = installedAgents.map((a) => ({
832
- value: a,
833
- label: agents[a].displayName,
834
- hint: shortenPath(agents[a].configPath)
835
- }));
899
+ const agentChoices = detectedAgents.map((a) => {
900
+ const routing = agentRouting.get(a);
901
+ const hint = routing === "local" ? "project" : routing === "global" ? "global" : shortenPath(agents[a].configPath);
902
+ return {
903
+ value: a,
904
+ label: agents[a].displayName,
905
+ hint
906
+ };
907
+ });
836
908
  const selected = await p.multiselect({
837
909
  message: "Select agents to install to",
838
910
  options: agentChoices,
839
911
  required: true,
840
- initialValues: installedAgents
912
+ initialValues: detectedAgents
841
913
  });
842
914
  if (p.isCancel(selected)) {
843
915
  p.cancel("Installation cancelled");
@@ -870,47 +942,80 @@ async function main(target, options) {
870
942
  process.exit(1);
871
943
  }
872
944
  }
873
- let installGlobally = options.global ?? false;
874
- if (options.global === void 0 && !options.yes) {
875
- const localSupported = getAgentsWithLocalSupport();
945
+ const hasSmartRouting = agentRouting.size > 0;
946
+ if (options.global) {
947
+ for (const agent of targetAgents) {
948
+ agentRouting.set(agent, "global");
949
+ }
950
+ } else if (!hasSmartRouting) {
876
951
  const selectedWithLocal = targetAgents.filter(
877
- (a) => localSupported.includes(a)
952
+ (a) => supportsProjectConfig(a)
953
+ );
954
+ const globalOnlySelected = targetAgents.filter(
955
+ (a) => !supportsProjectConfig(a)
878
956
  );
957
+ for (const agent of globalOnlySelected) {
958
+ agentRouting.set(agent, "global");
959
+ }
879
960
  if (selectedWithLocal.length > 0) {
880
- const scope = await p.select({
881
- message: "Installation scope",
882
- options: [
883
- {
884
- value: false,
885
- label: "Project",
886
- hint: "Install in current directory (committed with your project)"
887
- },
888
- {
889
- value: true,
890
- label: "Global",
891
- hint: "Install in home directory (available across all projects)"
892
- }
893
- ]
894
- });
895
- if (p.isCancel(scope)) {
896
- p.cancel("Installation cancelled");
897
- process.exit(0);
961
+ let installLocally = true;
962
+ if (!options.yes) {
963
+ const scope = await p.select({
964
+ message: "Installation scope",
965
+ options: [
966
+ {
967
+ value: true,
968
+ label: "Project",
969
+ hint: "Install in current directory (committed with your project)"
970
+ },
971
+ {
972
+ value: false,
973
+ label: "Global",
974
+ hint: "Install in home directory (available across all projects)"
975
+ }
976
+ ]
977
+ });
978
+ if (p.isCancel(scope)) {
979
+ p.cancel("Installation cancelled");
980
+ process.exit(0);
981
+ }
982
+ installLocally = scope;
983
+ }
984
+ for (const agent of selectedWithLocal) {
985
+ agentRouting.set(agent, installLocally ? "local" : "global");
898
986
  }
899
- installGlobally = scope;
900
987
  } else {
901
- installGlobally = true;
902
988
  p.log.info("Selected agents only support global installation");
903
989
  }
904
990
  }
905
991
  const summaryLines = [];
906
992
  summaryLines.push(`${chalk.cyan("Server:")} ${serverName}`);
907
993
  summaryLines.push(`${chalk.cyan("Type:")} ${sourceType}`);
908
- summaryLines.push(
909
- `${chalk.cyan("Scope:")} ${installGlobally ? "Global" : "Project"}`
994
+ const localAgents = targetAgents.filter(
995
+ (a) => agentRouting.get(a) === "local"
910
996
  );
911
- summaryLines.push(
912
- `${chalk.cyan("Agents:")} ${targetAgents.map((a) => agents[a].displayName).join(", ")}`
997
+ const globalAgents = targetAgents.filter(
998
+ (a) => agentRouting.get(a) === "global"
913
999
  );
1000
+ if (localAgents.length > 0 && globalAgents.length > 0) {
1001
+ summaryLines.push(`${chalk.cyan("Scope:")} Mixed (project + global)`);
1002
+ summaryLines.push(
1003
+ `${chalk.cyan(" Project:")} ${localAgents.map((a) => agents[a].displayName).join(", ")}`
1004
+ );
1005
+ summaryLines.push(
1006
+ `${chalk.cyan(" Global:")} ${globalAgents.map((a) => agents[a].displayName).join(", ")}`
1007
+ );
1008
+ } else if (localAgents.length > 0) {
1009
+ summaryLines.push(`${chalk.cyan("Scope:")} Project`);
1010
+ summaryLines.push(
1011
+ `${chalk.cyan("Agents:")} ${localAgents.map((a) => agents[a].displayName).join(", ")}`
1012
+ );
1013
+ } else {
1014
+ summaryLines.push(`${chalk.cyan("Scope:")} Global`);
1015
+ summaryLines.push(
1016
+ `${chalk.cyan("Agents:")} ${globalAgents.map((a) => agents[a].displayName).join(", ")}`
1017
+ );
1018
+ }
914
1019
  console.log();
915
1020
  p.note(summaryLines.join("\n"), "Installation Summary");
916
1021
  if (!options.yes) {
@@ -924,7 +1029,7 @@ async function main(target, options) {
924
1029
  }
925
1030
  spinner2.start("Installing MCP server...");
926
1031
  const results = installServer(serverName, serverConfig, targetAgents, {
927
- local: !installGlobally
1032
+ routing: agentRouting
928
1033
  });
929
1034
  spinner2.stop("Installation complete");
930
1035
  console.log();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "add-mcp",
3
- "version": "0.1.1",
3
+ "version": "0.2.0",
4
4
  "description": "Install MCP servers onto coding agents (Claude Code, Cursor, VS Code, OpenCode, Codex)",
5
5
  "author": "Andre Landgraf <andre@neon.tech>",
6
6
  "license": "Apache-2.0",
@@ -16,8 +16,8 @@
16
16
  "fmt": "prettier --write .",
17
17
  "build": "tsup src/index.ts --format esm --dts --clean",
18
18
  "dev": "tsx src/index.ts",
19
- "test": "tsx tests/source-parser.test.ts && tsx tests/installer.test.ts && tsx tests/e2e/install.test.ts",
20
- "test:unit": "tsx tests/source-parser.test.ts && tsx tests/installer.test.ts",
19
+ "test": "tsx tests/source-parser.test.ts && tsx tests/agents.test.ts && tsx tests/installer.test.ts && tsx tests/e2e/install.test.ts",
20
+ "test:unit": "tsx tests/source-parser.test.ts && tsx tests/agents.test.ts && tsx tests/installer.test.ts",
21
21
  "test:e2e": "tsx tests/e2e/install.test.ts",
22
22
  "typecheck": "tsc --noEmit",
23
23
  "prepublishOnly": "npm run build"