synabun 2026.3.312 → 2026.3.314

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.
@@ -238,13 +238,13 @@
238
238
  </div>
239
239
 
240
240
  <script>
241
- // --- Build command with full path ---
241
+ // --- Build restart command ---
242
+ // Use the global `synabun` command (works from any directory)
243
+ // Fallback: cd + npm start with `;` separator (works in both PowerShell and bash)
242
244
  const projectDir = localStorage.getItem('synabun-project-dir');
243
- const cmd = projectDir ? `cd ${projectDir} && npm start` : 'npm start';
245
+ const cmd = 'synabun';
244
246
  const cmdText = document.getElementById('cmdText');
245
- if (projectDir) {
246
- cmdText.innerHTML = `<span>cd</span> ${projectDir} && <span>npm</span> start`;
247
- }
247
+ cmdText.innerHTML = `<span>synabun</span>`;
248
248
  const copyBtn = document.getElementById('copyBtn');
249
249
 
250
250
  copyBtn.addEventListener('click', async () => {
@@ -2194,6 +2194,7 @@ function handleClaudeSkinWebSocket(ws) {
2194
2194
  let inTurn = false; // true while CLI is processing a user message
2195
2195
  let lastEventTime = Date.now(); // shared with stall detector
2196
2196
  const approvedTools = new Set(); // tools the user has approved — persists across respawns
2197
+ let mcpAllowedTools = new Set(); // MCP tools in permissions.allow — refreshed each spawn
2197
2198
  let lastPermissionDenials = null; // cached for retry after approval
2198
2199
  let awaitingPermission = false; // true when permission card shown, suppresses 'done' from close handler
2199
2200
  const permCardToolNames = new Map(); // requestId → toolName, for proactive permission cards
@@ -2263,6 +2264,11 @@ function handleClaudeSkinWebSocket(ws) {
2263
2264
 
2264
2265
  function spawnProc(sessionId, model, cwd, effort, prompt) {
2265
2266
  killProc();
2267
+ // Read current MCP permissions so we can show proactive cards for non-allowed MCP tools
2268
+ const _globalSettings = readClaudeSettings(getGlobalClaudeSettingsPath()) || {};
2269
+ mcpAllowedTools = new Set(
2270
+ (_globalSettings.permissions?.allow || []).filter(t => t.startsWith('mcp__'))
2271
+ );
2266
2272
  const workDir = validateWorkDir(cwd) || PACKAGE_ROOT;
2267
2273
  const args = [
2268
2274
  '--print',
@@ -2526,6 +2532,21 @@ function handleClaudeSkinWebSocket(ws) {
2526
2532
  request: { tool_name: tool.name, subtype: 'can_use_tool', input },
2527
2533
  });
2528
2534
  }
2535
+ // MCP tools: proactive card when not session-approved and not in permissions.allow
2536
+ // --print mode silently denies MCP tools without emitting permission_denials,
2537
+ // so we must intercept tool_use blocks and prompt the user ourselves.
2538
+ if (tool.name.startsWith('mcp__') && !approvedTools.has(tool.name) && !mcpAllowedTools.has(tool.name)) {
2539
+ const requestId = `perm-${tool.id}`;
2540
+ const input = tool.input || {};
2541
+ permCardToolNames.set(requestId, tool.name);
2542
+ console.log(`[claude-skin] ▶ PROACTIVE MCP permission card for ${tool.name}`);
2543
+ sendToClient({
2544
+ type: 'control_request',
2545
+ request_id: requestId,
2546
+ request: { tool_name: tool.name, subtype: 'can_use_tool', input },
2547
+ });
2548
+ awaitingPermission = true;
2549
+ }
2529
2550
  }
2530
2551
  }
2531
2552
  // Forward all events to client
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "synabun",
3
- "version": "2026.3.312",
3
+ "version": "2026.3.314",
4
4
  "description": "Persistent vector memory for AI assistants",
5
5
  "license": "Apache-2.0",
6
6
  "author": "The SynaBun Authors",