instar 0.7.41 → 0.7.42

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.js CHANGED
File without changes
@@ -27,6 +27,7 @@
27
27
  * Existing project adds .instar/ and appends to CLAUDE.md.
28
28
  */
29
29
  import fs from 'node:fs';
30
+ import os from 'node:os';
30
31
  import path from 'node:path';
31
32
  import pc from 'picocolors';
32
33
  import { randomUUID } from 'node:crypto';
@@ -2173,17 +2174,77 @@ function installClaudeSettings(projectDir) {
2173
2174
  hooks.Notification = filtered;
2174
2175
  }
2175
2176
  }
2176
- // MCP Servers: Playwright for browser automation (used by setup wizard, Telegram setup, etc.)
2177
- if (!settings.mcpServers) {
2178
- settings.mcpServers = {};
2179
- }
2180
- const mcpServers = settings.mcpServers;
2181
- if (!mcpServers.playwright) {
2182
- mcpServers.playwright = {
2183
- command: 'npx',
2184
- args: ['-y', '@playwright/mcp@latest'],
2185
- };
2177
+ // Remove stale mcpServers from settings.json MCP servers belong in
2178
+ // ~/.claude.json (local scope) or .mcp.json, NOT .claude/settings.json
2179
+ if (settings.mcpServers) {
2180
+ delete settings.mcpServers;
2186
2181
  }
2187
2182
  fs.writeFileSync(settingsPath, JSON.stringify(settings, null, 2));
2183
+ // MCP Servers: Register Playwright in the correct locations
2184
+ // Claude Code reads MCP servers from ~/.claude.json and .mcp.json, NOT .claude/settings.json
2185
+ registerPlaywrightMcp(projectDir);
2186
+ }
2187
+ /**
2188
+ * Register Playwright MCP server in the correct locations for Claude Code.
2189
+ *
2190
+ * Claude Code reads MCP servers from:
2191
+ * 1. ~/.claude.json — local scope (projects["/path"].mcpServers) — no trust dialog
2192
+ * 2. .mcp.json in project root — project scope — requires trust acceptance
2193
+ *
2194
+ * We register in both for robustness.
2195
+ */
2196
+ function registerPlaywrightMcp(projectDir) {
2197
+ const absDir = path.resolve(projectDir);
2198
+ // ── 1. Register in ~/.claude.json at local scope ──
2199
+ const claudeJsonPath = path.join(os.homedir(), '.claude.json');
2200
+ try {
2201
+ let claudeJson = {};
2202
+ if (fs.existsSync(claudeJsonPath)) {
2203
+ claudeJson = JSON.parse(fs.readFileSync(claudeJsonPath, 'utf-8'));
2204
+ }
2205
+ if (!claudeJson.projects || typeof claudeJson.projects !== 'object') {
2206
+ claudeJson.projects = {};
2207
+ }
2208
+ const projects = claudeJson.projects;
2209
+ if (!projects[absDir]) {
2210
+ projects[absDir] = {};
2211
+ }
2212
+ const projectEntry = projects[absDir];
2213
+ if (!projectEntry.mcpServers || typeof projectEntry.mcpServers !== 'object') {
2214
+ projectEntry.mcpServers = {};
2215
+ }
2216
+ const mcpServers = projectEntry.mcpServers;
2217
+ if (!mcpServers.playwright) {
2218
+ mcpServers.playwright = {
2219
+ command: 'npx',
2220
+ args: ['-y', '@playwright/mcp@latest'],
2221
+ };
2222
+ }
2223
+ projectEntry.hasTrustDialogAccepted = true;
2224
+ const tmpPath = `${claudeJsonPath}.${process.pid}.tmp`;
2225
+ fs.writeFileSync(tmpPath, JSON.stringify(claudeJson, null, 2));
2226
+ fs.renameSync(tmpPath, claudeJsonPath);
2227
+ }
2228
+ catch {
2229
+ // Non-fatal
2230
+ }
2231
+ // ── 2. Create .mcp.json in project root ──
2232
+ const mcpJsonPath = path.join(projectDir, '.mcp.json');
2233
+ if (!fs.existsSync(mcpJsonPath)) {
2234
+ try {
2235
+ const mcpConfig = {
2236
+ mcpServers: {
2237
+ playwright: {
2238
+ command: 'npx',
2239
+ args: ['-y', '@playwright/mcp@latest'],
2240
+ },
2241
+ },
2242
+ };
2243
+ fs.writeFileSync(mcpJsonPath, JSON.stringify(mcpConfig, null, 2));
2244
+ }
2245
+ catch {
2246
+ // Non-fatal
2247
+ }
2248
+ }
2188
2249
  }
2189
2250
  //# sourceMappingURL=init.js.map
@@ -144,35 +144,75 @@ export async function runSetup(opts) {
144
144
  });
145
145
  }
146
146
  /**
147
- * Ensure .claude/settings.json in the given directory has the Playwright MCP
148
- * server registered. This is critical for the setup wizard — Claude Code loads
149
- * MCP servers at startup, so the file must exist BEFORE spawning the session.
147
+ * Register the Playwright MCP server so Claude Code has browser automation
148
+ * available when spawned for the setup wizard.
150
149
  *
151
- * The .npmignore excludes .claude/settings*.json from the published package,
152
- * so this function creates it for fresh npx installations.
150
+ * Claude Code loads MCP servers from THREE places (NOT .claude/settings.json):
151
+ * 1. ~/.claude.json user scope (top-level mcpServers) or local scope
152
+ * (projects["/abs/path"].mcpServers) — NO trust dialog needed
153
+ * 2. .mcp.json in project root — project scope — requires trust acceptance
154
+ *
155
+ * We register in BOTH places for robustness:
156
+ * - ~/.claude.json local scope: guaranteed to work, no trust dialog
157
+ * - .mcp.json: works if trust is pre-accepted or enableAllProjectMcpServers
153
158
  */
154
159
  function ensurePlaywrightMcp(dir) {
155
- const claudeDir = path.join(dir, '.claude');
156
- fs.mkdirSync(claudeDir, { recursive: true });
157
- const settingsPath = path.join(claudeDir, 'settings.json');
158
- let settings = {};
159
- if (fs.existsSync(settingsPath)) {
160
- try {
161
- settings = JSON.parse(fs.readFileSync(settingsPath, 'utf-8'));
160
+ const absDir = path.resolve(dir);
161
+ // ── 1. Register in ~/.claude.json at local scope (most reliable) ──
162
+ const claudeJsonPath = path.join(os.homedir(), '.claude.json');
163
+ try {
164
+ let claudeJson = {};
165
+ if (fs.existsSync(claudeJsonPath)) {
166
+ claudeJson = JSON.parse(fs.readFileSync(claudeJsonPath, 'utf-8'));
167
+ }
168
+ // Ensure projects map exists
169
+ if (!claudeJson.projects || typeof claudeJson.projects !== 'object') {
170
+ claudeJson.projects = {};
171
+ }
172
+ const projects = claudeJson.projects;
173
+ // Ensure project entry exists
174
+ if (!projects[absDir]) {
175
+ projects[absDir] = {};
176
+ }
177
+ const projectEntry = projects[absDir];
178
+ // Register Playwright MCP at local scope
179
+ if (!projectEntry.mcpServers || typeof projectEntry.mcpServers !== 'object') {
180
+ projectEntry.mcpServers = {};
181
+ }
182
+ const mcpServers = projectEntry.mcpServers;
183
+ if (!mcpServers.playwright) {
184
+ mcpServers.playwright = {
185
+ command: 'npx',
186
+ args: ['-y', '@playwright/mcp@latest'],
187
+ };
162
188
  }
163
- catch { /* start fresh if corrupted */ }
189
+ // Pre-accept trust so .mcp.json servers also load without a dialog
190
+ projectEntry.hasTrustDialogAccepted = true;
191
+ // Write atomically
192
+ const tmpPath = `${claudeJsonPath}.${process.pid}.tmp`;
193
+ fs.writeFileSync(tmpPath, JSON.stringify(claudeJson, null, 2));
194
+ fs.renameSync(tmpPath, claudeJsonPath);
164
195
  }
165
- // Register Playwright MCP server if not already present
166
- if (!settings.mcpServers) {
167
- settings.mcpServers = {};
196
+ catch {
197
+ // Non-fatal — .mcp.json fallback below
168
198
  }
169
- const mcpServers = settings.mcpServers;
170
- if (!mcpServers.playwright) {
171
- mcpServers.playwright = {
172
- command: 'npx',
173
- args: ['-y', '@playwright/mcp@latest'],
174
- };
175
- fs.writeFileSync(settingsPath, JSON.stringify(settings, null, 2));
199
+ // ── 2. Also create .mcp.json in the project root (belt-and-suspenders) ──
200
+ const mcpJsonPath = path.join(dir, '.mcp.json');
201
+ if (!fs.existsSync(mcpJsonPath)) {
202
+ try {
203
+ const mcpConfig = {
204
+ mcpServers: {
205
+ playwright: {
206
+ command: 'npx',
207
+ args: ['-y', '@playwright/mcp@latest'],
208
+ },
209
+ },
210
+ };
211
+ fs.writeFileSync(mcpJsonPath, JSON.stringify(mcpConfig, null, 2));
212
+ }
213
+ catch {
214
+ // Non-fatal
215
+ }
176
216
  }
177
217
  }
178
218
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "instar",
3
- "version": "0.7.41",
3
+ "version": "0.7.42",
4
4
  "description": "Persistent autonomy infrastructure for AI agents",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",