@cydm/magic-shell-agent-node 0.1.4 → 0.1.6

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/node.d.ts CHANGED
@@ -84,6 +84,7 @@ export declare class AgentNode {
84
84
  private sendControlResult;
85
85
  private buildRuntimeSnapshot;
86
86
  private buildPrimaryAgentStatus;
87
+ private getAvailableWorkerPluginNames;
87
88
  private isProtectedPrimarySession;
88
89
  private runSessionTurn;
89
90
  private runClaudeWorkerTurn;
package/dist/node.js CHANGED
@@ -973,6 +973,7 @@ export class AgentNode {
973
973
  return {
974
974
  pluginName: this.primaryAgent.pluginName,
975
975
  preferredWorkerPluginName: this.preferredWorkerPluginName,
976
+ availableWorkerPlugins: this.getAvailableWorkerPluginNames(),
976
977
  sessionId: this.primaryAgent.sessionId,
977
978
  status: this.primaryAgent.status,
978
979
  activityState: this.primaryAgent.activityState,
@@ -980,6 +981,12 @@ export class AgentNode {
980
981
  capabilities: this.primaryAgent.capabilities || [],
981
982
  };
982
983
  }
984
+ getAvailableWorkerPluginNames() {
985
+ return Array.from(this.plugins.values())
986
+ .map((plugin) => plugin.name)
987
+ .filter((name) => name !== this.primaryAgent.pluginName)
988
+ .sort((a, b) => a.localeCompare(b));
989
+ }
983
990
  isProtectedPrimarySession(sessionId) {
984
991
  return !!sessionId && sessionId === this.primaryAgent.sessionId;
985
992
  }
@@ -0,0 +1,7 @@
1
+ {
2
+ "name": "claude-code",
3
+ "type": "pty",
4
+ "command": "claude",
5
+ "args": ["--dangerously-skip-permissions"],
6
+ "capabilities": ["terminal", "bash", "file-edit", "vim", "tmux", "ansi256", "mouse"]
7
+ }
@@ -0,0 +1,7 @@
1
+ {
2
+ "name": "codex",
3
+ "type": "pty",
4
+ "command": "codex",
5
+ "args": ["--yolo", "--no-alt-screen"],
6
+ "capabilities": ["terminal", "bash", "file-edit", "ansi256", "mouse"]
7
+ }
@@ -0,0 +1,7 @@
1
+ {
2
+ "name": "echo",
3
+ "type": "stdio",
4
+ "command": "node",
5
+ "args": ["test/mocks/echo-agent.js"],
6
+ "capabilities": ["terminal", "test"]
7
+ }
@@ -0,0 +1,8 @@
1
+ {
2
+ "name": "pie-unity",
3
+ "type": "stdio",
4
+ "command": "pie-unity",
5
+ "args": ["--interactive"],
6
+ "capabilities": ["terminal", "file-edit", "web-search"],
7
+ "env": { "PIE_UNITY_MODE": "terminal" }
8
+ }
@@ -2429,18 +2429,45 @@
2429
2429
  document.cookie = `${name}=${encodeURIComponent(value)}; path=/; max-age=${60 * 60 * 24 * 365}`;
2430
2430
  }
2431
2431
 
2432
+ function getAvailableSpawnPlugins() {
2433
+ const plugins = Array.isArray(primaryAgent?.availableWorkerPlugins) && primaryAgent.availableWorkerPlugins.length
2434
+ ? primaryAgent.availableWorkerPlugins
2435
+ : ['pie'];
2436
+ return Array.from(new Set(plugins.filter((item) => typeof item === 'string' && item.length > 0)));
2437
+ }
2438
+
2439
+ function normalizeSpawnPlugin(pluginName) {
2440
+ const available = getAvailableSpawnPlugins();
2441
+ if (pluginName && available.includes(pluginName)) return pluginName;
2442
+ if (available.includes('pie')) return 'pie';
2443
+ return available[0] || 'pie';
2444
+ }
2445
+
2432
2446
  function readStoredSpawnPlugin() {
2433
2447
  const cookieValue = readCookie('spawnPlugin');
2434
2448
  const saved = cookieValue || localStorage.getItem('spawnPlugin') || 'pie';
2435
- return saved === 'claude-code' || saved === 'codex' ? saved : 'pie';
2449
+ return normalizeSpawnPlugin(saved);
2436
2450
  }
2437
2451
 
2438
2452
  function persistSpawnPlugin(pluginName) {
2439
- selectedSpawnPlugin = pluginName === 'claude-code' || pluginName === 'codex' ? pluginName : 'pie';
2453
+ selectedSpawnPlugin = normalizeSpawnPlugin(pluginName);
2440
2454
  localStorage.setItem('spawnPlugin', selectedSpawnPlugin);
2441
2455
  writeCookie('spawnPlugin', selectedSpawnPlugin);
2442
2456
  }
2443
2457
 
2458
+ function renderSpawnPluginOptions() {
2459
+ const select = document.getElementById('spawnPlugin');
2460
+ if (!select) return;
2461
+ const available = getAvailableSpawnPlugins();
2462
+ const current = normalizeSpawnPlugin(selectedSpawnPlugin);
2463
+ select.innerHTML = available.map((pluginName) => (
2464
+ `<option value="${escapeHtml(pluginName)}">${escapeHtml(getSpawnPluginLabel(pluginName))}</option>`
2465
+ )).join('');
2466
+ selectedSpawnPlugin = current;
2467
+ select.value = current;
2468
+ resetSpawnButton();
2469
+ }
2470
+
2444
2471
  function loadRecentCwds() {
2445
2472
  try {
2446
2473
  const stored = readCookie('recentCwds') || localStorage.getItem('recentCwds') || '[]';
@@ -2550,7 +2577,7 @@
2550
2577
  document.getElementById('nodeId').value = localStorage.getItem('nodeId') || '';
2551
2578
  document.getElementById('password').value = localStorage.getItem('password') || '';
2552
2579
  document.getElementById('spawnCwd').value = defaultSpawnCwd;
2553
- document.getElementById('spawnPlugin').value = selectedSpawnPlugin;
2580
+ renderSpawnPluginOptions();
2554
2581
  document.getElementById('spawnPlugin').addEventListener('change', (event) => {
2555
2582
  persistSpawnPlugin(event.target.value || 'pie');
2556
2583
  resetSpawnButton();
@@ -2591,6 +2618,17 @@
2591
2618
  }
2592
2619
  }
2593
2620
 
2621
+ function setSpawnCwd(cwd, { remember = false } = {}) {
2622
+ const next = (cwd || '').trim();
2623
+ const input = document.getElementById('spawnCwd');
2624
+ input.value = next;
2625
+ defaultSpawnCwd = next;
2626
+ localStorage.setItem('spawnCwd', defaultSpawnCwd);
2627
+ if (remember && next) {
2628
+ rememberCwd(next);
2629
+ }
2630
+ }
2631
+
2594
2632
  const searchParams = new URLSearchParams(window.location.search);
2595
2633
  const inferredRelayUrl = inferDefaultRelayUrl();
2596
2634
  document.getElementById('relayUrl').value = inferredRelayUrl;
@@ -3075,6 +3113,8 @@
3075
3113
  function getSpawnPluginLabel(pluginName) {
3076
3114
  if (pluginName === 'claude-code') return 'CLAUDE';
3077
3115
  if (pluginName === 'codex') return 'CODEX';
3116
+ if (pluginName === 'pie-unity') return 'PIE UNITY';
3117
+ if (pluginName === 'echo') return 'ECHO';
3078
3118
  return 'PIE';
3079
3119
  }
3080
3120
 
@@ -3658,6 +3698,11 @@
3658
3698
  pushNodeTranscript,
3659
3699
  renderWorkers,
3660
3700
  syncWorkerPluginPreference,
3701
+ renderSpawnPluginOptions,
3702
+ getSpawnCwd() {
3703
+ return (document.getElementById('spawnCwd').value || '').trim();
3704
+ },
3705
+ setSpawnCwd,
3661
3706
  setSessionDisplay(value) {
3662
3707
  document.getElementById('session-display').textContent = value;
3663
3708
  },
@@ -19,6 +19,7 @@
19
19
  ctx.runtimeSummary = snapshot.runtime || null;
20
20
  ctx.runtimeFocus = snapshot.focus || [];
21
21
  ctx.primaryAgent = snapshot.primary || null;
22
+ ctx.renderSpawnPluginOptions?.();
22
23
  ctx.syncNodeTranscriptFromServer(snapshot.nodeHistory);
23
24
 
24
25
  const liveSessionIds = new Set(ctx.workers.map((worker) => worker.sessionId));
@@ -105,8 +106,21 @@
105
106
  }
106
107
 
107
108
  function handleControlMessage(msg, ctx) {
109
+ if (msg.controlKind === "result" && msg.controlName === "spawn_worker") {
110
+ if (msg.ok === false) {
111
+ ctx.pendingSpawnSessionId = null;
112
+ ctx.pendingSpawnAutoAttach = true;
113
+ ctx.resetSpawnButton();
114
+ ctx.writeSystemNotice(`SPAWN FAILED: ${msg.payload?.error || msg.error || "Unknown error"}`);
115
+ ctx.renderWorkers();
116
+ return true;
117
+ }
118
+ return false;
119
+ }
120
+
108
121
  if (msg.controlKind === "result" && msg.controlName === "get_primary_agent" && msg.payload && msg.payload.primary) {
109
122
  ctx.primaryAgent = msg.payload.primary || null;
123
+ ctx.renderSpawnPluginOptions?.();
110
124
  ctx.renderNodeHome();
111
125
  return true;
112
126
  }
@@ -145,6 +159,9 @@
145
159
  ctx.dirBrowserParentPath = msg.payload.parentPath || null;
146
160
  ctx.dirBrowserRepoRoot = msg.payload.repoRoot || null;
147
161
  ctx.dirBrowserEntries = msg.payload.entries || [];
162
+ if (!ctx.getSpawnCwd?.() && msg.payload.path) {
163
+ ctx.setSpawnCwd?.(msg.payload.path);
164
+ }
148
165
  ctx.renderDirBrowser();
149
166
  return true;
150
167
  }
@@ -165,6 +182,9 @@
165
182
  ctx.dirBrowserParentPath = msg.payload.parentPath || null;
166
183
  ctx.dirBrowserRepoRoot = msg.payload.repoRoot || null;
167
184
  ctx.dirBrowserEntries = msg.payload.entries || [];
185
+ if (!ctx.getSpawnCwd?.() && msg.payload.path) {
186
+ ctx.setSpawnCwd?.(msg.payload.path);
187
+ }
168
188
  ctx.renderDirBrowser();
169
189
  return true;
170
190
  }
@@ -6,6 +6,9 @@
6
6
  ctx.sessionId = null;
7
7
  ctx.setSessionDisplay("----");
8
8
  ctx.syncWorkerPluginPreference?.();
9
+ if (!ctx.getSpawnCwd?.()) {
10
+ ctx.requestDirBrowse?.();
11
+ }
9
12
  ctx.requestWorkerList();
10
13
  return true;
11
14
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cydm/magic-shell-agent-node",
3
- "version": "0.1.4",
3
+ "version": "0.1.6",
4
4
  "description": "Magic Shell Agent Node - Local agent connector",
5
5
  "homepage": "https://magicshell.ai",
6
6
  "keywords": [
@@ -27,7 +27,7 @@
27
27
  "start": "node dist/node.js"
28
28
  },
29
29
  "dependencies": {
30
- "@cydm/magic-shell-protocol": "0.1.1",
30
+ "@cydm/magic-shell-protocol": "0.1.2",
31
31
  "node-pty": "^1.1.0",
32
32
  "ws": "^8.18.0"
33
33
  },