tide-commander 1.133.0 → 1.133.2

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 (42) hide show
  1. package/dist/assets/{BossLogsModal-DrdxKTb-.js → BossLogsModal-DwuIK9m6.js} +1 -1
  2. package/dist/assets/{BossSpawnModal-B2w4kFpi.js → BossSpawnModal-Dj3RAYvK.js} +1 -1
  3. package/dist/assets/{ControlsModal-BWYKL25r.js → ControlsModal-2RYmmfrr.js} +1 -1
  4. package/dist/assets/{DockerLogsModal-0fJudEU2.js → DockerLogsModal-CtK69VXz.js} +1 -1
  5. package/dist/assets/{EmbeddedEditor-BDzAm2JK.js → EmbeddedEditor-D4dyGPWp.js} +1 -1
  6. package/dist/assets/{GmailOAuthSetup-CR0SPH0J.js → GmailOAuthSetup-D4WIJQPh.js} +1 -1
  7. package/dist/assets/{GoogleOAuthSetup-BTDncXU3.js → GoogleOAuthSetup-CeOoPjBn.js} +1 -1
  8. package/dist/assets/{IframeModal-Csor52D5.js → IframeModal-Czpk8nNY.js} +1 -1
  9. package/dist/assets/{IntegrationsPanel-qTRjzZ-I.js → IntegrationsPanel-BTWvtUqh.js} +2 -2
  10. package/dist/assets/{LogViewerModal-BiPg_NL7.js → LogViewerModal-BoFD-vk1.js} +1 -1
  11. package/dist/assets/{MonitoringModal-BKjwjSqZ.js → MonitoringModal-ChR0ELIz.js} +1 -1
  12. package/dist/assets/{PM2LogsModal-BAEeg_iW.js → PM2LogsModal-CoCnLncV.js} +1 -1
  13. package/dist/assets/{RestoreArchivedAreaModal-Hm9Osmc4.js → RestoreArchivedAreaModal-DPTPKLHh.js} +1 -1
  14. package/dist/assets/{Scene2DCanvas-T-7D8dQ_.js → Scene2DCanvas-BH-47TIq.js} +1 -1
  15. package/dist/assets/{SceneManager-C2rng0PA.js → SceneManager-IluWBEFk.js} +1 -1
  16. package/dist/assets/{SkillsPanel-BD9RO30O.js → SkillsPanel-XcUykivP.js} +1 -1
  17. package/dist/assets/{SlackMultiInstanceSetup-CiK0r5fz.js → SlackMultiInstanceSetup-DeLiUle3.js} +1 -1
  18. package/dist/assets/{SpawnModal-Di4xD6Ue.js → SpawnModal-BZfIZTdq.js} +1 -1
  19. package/dist/assets/{StatisticsModal-Dnl8segJ.js → StatisticsModal-C0Ets4vl.js} +1 -1
  20. package/dist/assets/{SubordinateAssignmentModal-CBIMPvXj.js → SubordinateAssignmentModal-BMT6EK_E.js} +1 -1
  21. package/dist/assets/{TriggerManagerPanel-Bt5jFa9e.js → TriggerManagerPanel-Bnwo6pTt.js} +1 -1
  22. package/dist/assets/{WorkflowEditorPanel-Dr7w30kC.js → WorkflowEditorPanel-D0G14Ebq.js} +1 -1
  23. package/dist/assets/{area-logos-CbqAEc5x.js → area-logos-C5XZBFfj.js} +1 -1
  24. package/dist/assets/{index-B_EnZVF3.js → index-AlXP8uuc.js} +3 -3
  25. package/dist/assets/{index-Cah-uKuh.js → index-B3k628ul.js} +1 -1
  26. package/dist/assets/{index-BajNxeMu.js → index-BV42oiJT.js} +1 -1
  27. package/dist/assets/{index-D-b-ReZX.js → index-Bd5JKG69.js} +1 -1
  28. package/dist/assets/{index-Cs3R3S9l.js → index-D-ETqZcB.js} +2 -2
  29. package/dist/assets/{index-DAjLIFPG.js → index-D5ufwk7t.js} +1 -1
  30. package/dist/assets/{index-D5ncPXgD.js → index-D_shYCrx.js} +1 -1
  31. package/dist/assets/{index-DHPrZrMN.js → index-GtO7k8QG.js} +1 -1
  32. package/dist/assets/{index-C7vxRa_S.js → index-bY0k_5jo.js} +1 -1
  33. package/dist/assets/{main-D5m1NJ8q.js → main-DZgTocNE.js} +7 -7
  34. package/dist/assets/main-rrlO1Py8.css +1 -0
  35. package/dist/assets/{web-CbFuYEMc.js → web-CwRGXDj6.js} +1 -1
  36. package/dist/assets/{web-Dh2cBvOj.js → web-i9NDpV0L.js} +1 -1
  37. package/dist/assets/{web-C--hoJ1w.js → web-zQ3wpRl0.js} +1 -1
  38. package/dist/index.html +2 -2
  39. package/dist/src/packages/server/services/subagent-jsonl-watcher.js +33 -7
  40. package/dist/src/packages/server/websocket/listeners/runtime-listeners.js +20 -0
  41. package/package.json +1 -1
  42. package/dist/assets/main-BUUWICEe.css +0 -1
@@ -1 +1 @@
1
- import{cO as s}from"./main-D5m1NJ8q.js";import"./vendor-react--Eh9ivFN.js";import"./vendor-three-Chj50gSY.js";class l extends s{constructor(){super(...arguments),this.pending=[],this.deliveredNotifications=[],this.hasNotificationSupport=()=>{if(!("Notification"in window)||!Notification.requestPermission)return!1;if(Notification.permission!=="granted")try{new Notification("")}catch(i){if(i instanceof Error&&i.name==="TypeError")return!1}return!0}}async getDeliveredNotifications(){const i=[];for(const t of this.deliveredNotifications){const e={title:t.title,id:parseInt(t.tag),body:t.body};i.push(e)}return{notifications:i}}async removeDeliveredNotifications(i){for(const t of i.notifications){const e=this.deliveredNotifications.find(n=>n.tag===String(t.id));e==null||e.close(),this.deliveredNotifications=this.deliveredNotifications.filter(()=>!e)}}async removeAllDeliveredNotifications(){for(const i of this.deliveredNotifications)i.close();this.deliveredNotifications=[]}async createChannel(){throw this.unimplemented("Not implemented on web.")}async deleteChannel(){throw this.unimplemented("Not implemented on web.")}async listChannels(){throw this.unimplemented("Not implemented on web.")}async schedule(i){if(!this.hasNotificationSupport())throw this.unavailable("Notifications not supported in this browser.");for(const t of i.notifications)this.sendNotification(t);return{notifications:i.notifications.map(t=>({id:t.id}))}}async getPending(){return{notifications:this.pending}}async registerActionTypes(){throw this.unimplemented("Not implemented on web.")}async cancel(i){this.pending=this.pending.filter(t=>!i.notifications.find(e=>e.id===t.id))}async areEnabled(){const{display:i}=await this.checkPermissions();return{value:i==="granted"}}async changeExactNotificationSetting(){throw this.unimplemented("Not implemented on web.")}async checkExactNotificationSetting(){throw this.unimplemented("Not implemented on web.")}async requestPermissions(){if(!this.hasNotificationSupport())throw this.unavailable("Notifications not supported in this browser.");return{display:this.transformNotificationPermission(await Notification.requestPermission())}}async checkPermissions(){if(!this.hasNotificationSupport())throw this.unavailable("Notifications not supported in this browser.");return{display:this.transformNotificationPermission(Notification.permission)}}transformNotificationPermission(i){switch(i){case"granted":return"granted";case"denied":return"denied";default:return"prompt"}}sendPending(){var i;const t=[],e=new Date().getTime();for(const n of this.pending)!((i=n.schedule)===null||i===void 0)&&i.at&&n.schedule.at.getTime()<=e&&(this.buildNotification(n),t.push(n));this.pending=this.pending.filter(n=>!t.find(o=>o===n))}sendNotification(i){var t;if(!((t=i.schedule)===null||t===void 0)&&t.at){const e=i.schedule.at.getTime()-new Date().getTime();this.pending.push(i),setTimeout(()=>{this.sendPending()},e);return}this.buildNotification(i)}buildNotification(i){const t=new Notification(i.title,{body:i.body,tag:String(i.id)});return t.addEventListener("click",this.onClick.bind(this,i),!1),t.addEventListener("show",this.onShow.bind(this,i),!1),t.addEventListener("close",()=>{this.deliveredNotifications=this.deliveredNotifications.filter(()=>!this)},!1),this.deliveredNotifications.push(t),t}onClick(i){const t={actionId:"tap",notification:i};this.notifyListeners("localNotificationActionPerformed",t)}onShow(i){this.notifyListeners("localNotificationReceived",i)}}export{l as LocalNotificationsWeb};
1
+ import{cO as s}from"./main-DZgTocNE.js";import"./vendor-react--Eh9ivFN.js";import"./vendor-three-Chj50gSY.js";class l extends s{constructor(){super(...arguments),this.pending=[],this.deliveredNotifications=[],this.hasNotificationSupport=()=>{if(!("Notification"in window)||!Notification.requestPermission)return!1;if(Notification.permission!=="granted")try{new Notification("")}catch(i){if(i instanceof Error&&i.name==="TypeError")return!1}return!0}}async getDeliveredNotifications(){const i=[];for(const t of this.deliveredNotifications){const e={title:t.title,id:parseInt(t.tag),body:t.body};i.push(e)}return{notifications:i}}async removeDeliveredNotifications(i){for(const t of i.notifications){const e=this.deliveredNotifications.find(n=>n.tag===String(t.id));e==null||e.close(),this.deliveredNotifications=this.deliveredNotifications.filter(()=>!e)}}async removeAllDeliveredNotifications(){for(const i of this.deliveredNotifications)i.close();this.deliveredNotifications=[]}async createChannel(){throw this.unimplemented("Not implemented on web.")}async deleteChannel(){throw this.unimplemented("Not implemented on web.")}async listChannels(){throw this.unimplemented("Not implemented on web.")}async schedule(i){if(!this.hasNotificationSupport())throw this.unavailable("Notifications not supported in this browser.");for(const t of i.notifications)this.sendNotification(t);return{notifications:i.notifications.map(t=>({id:t.id}))}}async getPending(){return{notifications:this.pending}}async registerActionTypes(){throw this.unimplemented("Not implemented on web.")}async cancel(i){this.pending=this.pending.filter(t=>!i.notifications.find(e=>e.id===t.id))}async areEnabled(){const{display:i}=await this.checkPermissions();return{value:i==="granted"}}async changeExactNotificationSetting(){throw this.unimplemented("Not implemented on web.")}async checkExactNotificationSetting(){throw this.unimplemented("Not implemented on web.")}async requestPermissions(){if(!this.hasNotificationSupport())throw this.unavailable("Notifications not supported in this browser.");return{display:this.transformNotificationPermission(await Notification.requestPermission())}}async checkPermissions(){if(!this.hasNotificationSupport())throw this.unavailable("Notifications not supported in this browser.");return{display:this.transformNotificationPermission(Notification.permission)}}transformNotificationPermission(i){switch(i){case"granted":return"granted";case"denied":return"denied";default:return"prompt"}}sendPending(){var i;const t=[],e=new Date().getTime();for(const n of this.pending)!((i=n.schedule)===null||i===void 0)&&i.at&&n.schedule.at.getTime()<=e&&(this.buildNotification(n),t.push(n));this.pending=this.pending.filter(n=>!t.find(o=>o===n))}sendNotification(i){var t;if(!((t=i.schedule)===null||t===void 0)&&t.at){const e=i.schedule.at.getTime()-new Date().getTime();this.pending.push(i),setTimeout(()=>{this.sendPending()},e);return}this.buildNotification(i)}buildNotification(i){const t=new Notification(i.title,{body:i.body,tag:String(i.id)});return t.addEventListener("click",this.onClick.bind(this,i),!1),t.addEventListener("show",this.onShow.bind(this,i),!1),t.addEventListener("close",()=>{this.deliveredNotifications=this.deliveredNotifications.filter(()=>!this)},!1),this.deliveredNotifications.push(t),t}onClick(i){const t={actionId:"tap",notification:i};this.notifyListeners("localNotificationActionPerformed",t)}onShow(i){this.notifyListeners("localNotificationReceived",i)}}export{l as LocalNotificationsWeb};
@@ -1 +1 @@
1
- import{cO as a}from"./main-D5m1NJ8q.js";import{ImpactStyle as i,NotificationType as r}from"./index-Cs3R3S9l.js";import"./vendor-react--Eh9ivFN.js";import"./vendor-three-Chj50gSY.js";class h extends a{constructor(){super(...arguments),this.selectionStarted=!1}async impact(t){const e=this.patternForImpact(t==null?void 0:t.style);this.vibrateWithPattern(e)}async notification(t){const e=this.patternForNotification(t==null?void 0:t.type);this.vibrateWithPattern(e)}async vibrate(t){const e=(t==null?void 0:t.duration)||300;this.vibrateWithPattern([e])}async selectionStart(){this.selectionStarted=!0}async selectionChanged(){this.selectionStarted&&this.vibrateWithPattern([70])}async selectionEnd(){this.selectionStarted=!1}patternForImpact(t=i.Heavy){return t===i.Medium?[43]:t===i.Light?[20]:[61]}patternForNotification(t=r.Success){return t===r.Warning?[30,40,30,50,60]:t===r.Error?[27,45,50]:[35,65,21]}vibrateWithPattern(t){if(navigator.vibrate)navigator.vibrate(t);else throw this.unavailable("Browser does not support the vibrate API")}}export{h as HapticsWeb};
1
+ import{cO as a}from"./main-DZgTocNE.js";import{ImpactStyle as i,NotificationType as r}from"./index-D-ETqZcB.js";import"./vendor-react--Eh9ivFN.js";import"./vendor-three-Chj50gSY.js";class h extends a{constructor(){super(...arguments),this.selectionStarted=!1}async impact(t){const e=this.patternForImpact(t==null?void 0:t.style);this.vibrateWithPattern(e)}async notification(t){const e=this.patternForNotification(t==null?void 0:t.type);this.vibrateWithPattern(e)}async vibrate(t){const e=(t==null?void 0:t.duration)||300;this.vibrateWithPattern([e])}async selectionStart(){this.selectionStarted=!0}async selectionChanged(){this.selectionStarted&&this.vibrateWithPattern([70])}async selectionEnd(){this.selectionStarted=!1}patternForImpact(t=i.Heavy){return t===i.Medium?[43]:t===i.Light?[20]:[61]}patternForNotification(t=r.Success){return t===r.Warning?[30,40,30,50,60]:t===r.Error?[27,45,50]:[35,65,21]}vibrateWithPattern(t){if(navigator.vibrate)navigator.vibrate(t);else throw this.unavailable("Browser does not support the vibrate API")}}export{h as HapticsWeb};
@@ -1 +1 @@
1
- import{cO as t}from"./main-D5m1NJ8q.js";import"./vendor-react--Eh9ivFN.js";import"./vendor-three-Chj50gSY.js";class o extends t{constructor(){super(),this.handleVisibilityChange=()=>{const e={isActive:document.hidden!==!0};this.notifyListeners("appStateChange",e),document.hidden?this.notifyListeners("pause",null):this.notifyListeners("resume",null)},document.addEventListener("visibilitychange",this.handleVisibilityChange,!1)}exitApp(){throw this.unimplemented("Not implemented on web.")}async getInfo(){throw this.unimplemented("Not implemented on web.")}async getLaunchUrl(){return{url:""}}async getState(){return{isActive:document.hidden!==!0}}async minimizeApp(){throw this.unimplemented("Not implemented on web.")}async toggleBackButtonHandler(){throw this.unimplemented("Not implemented on web.")}async getAppLanguage(){return{value:navigator.language.split("-")[0].toLowerCase()}}}export{o as AppWeb};
1
+ import{cO as t}from"./main-DZgTocNE.js";import"./vendor-react--Eh9ivFN.js";import"./vendor-three-Chj50gSY.js";class o extends t{constructor(){super(),this.handleVisibilityChange=()=>{const e={isActive:document.hidden!==!0};this.notifyListeners("appStateChange",e),document.hidden?this.notifyListeners("pause",null):this.notifyListeners("resume",null)},document.addEventListener("visibilitychange",this.handleVisibilityChange,!1)}exitApp(){throw this.unimplemented("Not implemented on web.")}async getInfo(){throw this.unimplemented("Not implemented on web.")}async getLaunchUrl(){return{url:""}}async getState(){return{isActive:document.hidden!==!0}}async minimizeApp(){throw this.unimplemented("Not implemented on web.")}async toggleBackButtonHandler(){throw this.unimplemented("Not implemented on web.")}async getAppLanguage(){return{value:navigator.language.split("-")[0].toLowerCase()}}}export{o as AppWeb};
package/dist/index.html CHANGED
@@ -22,10 +22,10 @@
22
22
  <link rel="icon" type="image/png" sizes="16x16" href="/assets/icons/favicon-16x16.png" />
23
23
  <link rel="apple-touch-icon" sizes="180x180" href="/assets/icons/apple-touch-icon.png" />
24
24
  <title>Tide Commander</title>
25
- <script type="module" crossorigin src="/assets/main-D5m1NJ8q.js"></script>
25
+ <script type="module" crossorigin src="/assets/main-DZgTocNE.js"></script>
26
26
  <link rel="modulepreload" crossorigin href="/assets/vendor-react--Eh9ivFN.js">
27
27
  <link rel="modulepreload" crossorigin href="/assets/vendor-three-Chj50gSY.js">
28
- <link rel="stylesheet" crossorigin href="/assets/main-BUUWICEe.css">
28
+ <link rel="stylesheet" crossorigin href="/assets/main-rrlO1Py8.css">
29
29
  </head>
30
30
  <body>
31
31
  <div id="app"></div>
@@ -35,6 +35,8 @@ const TOOL_KEY_PARAMS = {
35
35
  Task: 'description',
36
36
  NotebookEdit: 'notebook_path',
37
37
  };
38
+ // Cap forwarded tool outputs — JSONL lines can embed very large results.
39
+ const MAX_TOOL_RESULT_OUTPUT_CHARS = 100_000;
38
40
  const activeWatchers = new Map();
39
41
  /**
40
42
  * Get the subagents directory for a given agent's session
@@ -46,7 +48,7 @@ export function getSubagentsDir(cwd, sessionId) {
46
48
  /**
47
49
  * Start watching for a subagent's JSONL file
48
50
  */
49
- export function startWatching(toolUseId, parentAgentId, subagentsDir, onBroadcast) {
51
+ export function startWatching(toolUseId, parentAgentId, subagentsDir, onBroadcast, onToolResult) {
50
52
  if (activeWatchers.has(toolUseId)) {
51
53
  log.warn(`[Watcher] Already watching for toolUseId=${toolUseId}`);
52
54
  return;
@@ -59,6 +61,8 @@ export function startWatching(toolUseId, parentAgentId, subagentsDir, onBroadcas
59
61
  lineBuffer: '',
60
62
  pendingEntries: [],
61
63
  onBroadcast,
64
+ onToolResult,
65
+ toolNames: new Map(),
62
66
  stopped: false,
63
67
  lastReadTime: Date.now(),
64
68
  };
@@ -298,10 +302,17 @@ function readNewLines(watcher) {
298
302
  const trimmed = line.trim();
299
303
  if (!trimmed)
300
304
  continue;
301
- const entries = parseLine(trimmed);
305
+ const { entries, toolResults } = parseLine(trimmed, watcher.toolNames);
302
306
  if (entries.length > 0) {
303
307
  watcher.pendingEntries.push(...entries);
304
308
  }
309
+ // Forward full tool results immediately (not debounced) — the terminal
310
+ // uses them to resolve a subagent tool card's "running" spinner.
311
+ if (watcher.onToolResult) {
312
+ for (const result of toolResults) {
313
+ watcher.onToolResult(watcher.toolUseId, watcher.parentAgentId, result);
314
+ }
315
+ }
305
316
  }
306
317
  // Debounce broadcast
307
318
  scheduleBroadcast(watcher);
@@ -341,15 +352,19 @@ function flushEntries(watcher) {
341
352
  watcher.onBroadcast(watcher.toolUseId, watcher.parentAgentId, entries);
342
353
  }
343
354
  /**
344
- * Parse a single JSONL line into SubagentStreamEntry items
355
+ * Parse a single JSONL line into SubagentStreamEntry items plus any full
356
+ * tool results (used to resolve subagent tool cards in the terminal).
357
+ * `toolNames` accumulates the subagent's tool_use id -> name mapping across
358
+ * lines so results can be attributed to their tool.
345
359
  */
346
- function parseLine(line) {
360
+ function parseLine(line, toolNames) {
347
361
  const entries = [];
362
+ const toolResults = [];
348
363
  try {
349
364
  const data = JSON.parse(line);
350
365
  const message = data.message;
351
366
  if (!message || !message.content)
352
- return entries;
367
+ return { entries, toolResults };
353
368
  const timestamp = data.timestamp || new Date().toISOString();
354
369
  const contentArray = Array.isArray(message.content) ? message.content : [];
355
370
  // Skip initial user prompts (the task delegation message)
@@ -370,10 +385,18 @@ function parseLine(line) {
370
385
  isError: block.is_error === true,
371
386
  toolUseId: block.tool_use_id,
372
387
  });
388
+ if (block.tool_use_id) {
389
+ toolResults.push({
390
+ toolUseId: block.tool_use_id,
391
+ toolName: toolNames.get(block.tool_use_id) || 'unknown',
392
+ output: resultText.slice(0, MAX_TOOL_RESULT_OUTPUT_CHARS),
393
+ isError: block.is_error === true,
394
+ });
395
+ }
373
396
  }
374
397
  }
375
398
  }
376
- return entries;
399
+ return { entries, toolResults };
377
400
  }
378
401
  // Parse assistant messages
379
402
  if (data.type === 'assistant' && message.role === 'assistant') {
@@ -395,6 +418,9 @@ function parseLine(line) {
395
418
  const keyParam = keyParamName && input[keyParamName]
396
419
  ? String(input[keyParamName]).slice(0, 120)
397
420
  : undefined;
421
+ if (block.id) {
422
+ toolNames.set(block.id, toolName);
423
+ }
398
424
  entries.push({
399
425
  type: 'tool_use',
400
426
  timestamp,
@@ -409,5 +435,5 @@ function parseLine(line) {
409
435
  catch {
410
436
  // Invalid JSON line - skip
411
437
  }
412
- return entries;
438
+ return { entries, toolResults };
413
439
  }
@@ -107,6 +107,26 @@ export function setupRuntimeListeners(ctx) {
107
107
  type: 'subagent_stream',
108
108
  payload: { toolUseId, parentAgentId, entries },
109
109
  });
110
+ }, (toolUseId, parentAgentId, result) => {
111
+ // The parent CLI stream never echoes subagent tool_result events
112
+ // (only tool_use), so without this bridge the subagent Bash
113
+ // cards in the terminal keep their "running" spinner forever.
114
+ // Mirror the parent-agent behavior: only Bash results get a card.
115
+ if (result.toolName !== 'Bash')
116
+ return;
117
+ ctx.broadcast({
118
+ type: 'event',
119
+ payload: {
120
+ agentId: parentAgentId,
121
+ type: 'tool_result',
122
+ toolName: 'Bash',
123
+ toolOutput: result.output,
124
+ parentToolUseId: toolUseId,
125
+ // Subagent-internal tool_use id — matches the uuid of the
126
+ // corresponding tool_start card so the client pairs exactly.
127
+ uuid: result.toolUseId,
128
+ },
129
+ });
110
130
  });
111
131
  }
112
132
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tide-commander",
3
- "version": "1.133.0",
3
+ "version": "1.133.2",
4
4
  "description": "Visual multi-agent orchestrator and manager for Claude Code with 3D/2D interface",
5
5
  "repository": {
6
6
  "type": "git",