tide-commander 1.47.0 → 1.49.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 (57) hide show
  1. package/dist/assets/{BossLogsModal-BEZSJWBV.js → BossLogsModal-buht3LyW.js} +1 -1
  2. package/dist/assets/BossSpawnModal-D7M1JocE.js +1 -0
  3. package/dist/assets/{ControlsModal-BZKmtLz7.js → ControlsModal-C3-j1E6y.js} +1 -1
  4. package/dist/assets/{DockerLogsModal-DD8gRVu6.js → DockerLogsModal-CA2j24QX.js} +1 -1
  5. package/dist/assets/{EmbeddedEditor-DMcKiZ5q.js → EmbeddedEditor-CrLtAaIO.js} +1 -1
  6. package/dist/assets/GmailOAuthSetup-CG2BmCyg.js +303 -0
  7. package/dist/assets/GoogleOAuthSetup-DlaXAoyq.js +236 -0
  8. package/dist/assets/{IframeModal-DJn-dNqr.js → IframeModal-CvJ6LEIu.js} +1 -1
  9. package/dist/assets/IntegrationsPanel-iTByepHj.js +2 -0
  10. package/dist/assets/{LogViewerModal-BgIfdR-l.js → LogViewerModal-C75Yyse9.js} +1 -1
  11. package/dist/assets/{MonitoringModal-Dm8wbcHY.js → MonitoringModal-C3NapNrP.js} +1 -1
  12. package/dist/assets/{PM2LogsModal-CDULU4yk.js → PM2LogsModal-CaacRI13.js} +1 -1
  13. package/dist/assets/{RestoreArchivedAreaModal-DLuiZj6S.js → RestoreArchivedAreaModal-mwQqJ4qp.js} +1 -1
  14. package/dist/assets/{SaveSnapshotModal-CbfjHVJz.js → SaveSnapshotModal-Didvj3hf.js} +1 -1
  15. package/dist/assets/{Scene2DCanvas-Dw9o4Fk8.js → Scene2DCanvas-chSGLBlj.js} +1 -1
  16. package/dist/assets/{SceneManager-KAhHYpUf.js → SceneManager-G0H-cWU4.js} +1 -1
  17. package/dist/assets/{SkillsPanel-BYy3W8hd.js → SkillsPanel-nKzb0E59.js} +1 -1
  18. package/dist/assets/{SnapshotManager-LxlHIjaa.js → SnapshotManager-DoQRZCNb.js} +1 -1
  19. package/dist/assets/SpawnModal-CPTZGYNR.js +1 -0
  20. package/dist/assets/{SubordinateAssignmentModal-zuSTZAqj.js → SubordinateAssignmentModal-B2XP8wZU.js} +1 -1
  21. package/dist/assets/{SupervisorPanel-tTfMa-0x.js → SupervisorPanel-LlgMdGCQ.js} +1 -1
  22. package/dist/assets/{TriggerManagerPanel-BoHdbpqk.js → TriggerManagerPanel-DMiK0_y5.js} +1 -1
  23. package/dist/assets/{WorkflowEditorPanel-Cusd-51G.js → WorkflowEditorPanel-DPwmjV2f.js} +1 -1
  24. package/dist/assets/{index-BoFICHSl.js → index-BCuYxI5F.js} +2 -2
  25. package/dist/assets/{index-BPn1NjZ5.js → index-BIt0Cgpm.js} +1 -1
  26. package/dist/assets/{index-CeMGJMtZ.js → index-BM1s5vTS.js} +3 -3
  27. package/dist/assets/{index-ChZ1qMl3.js → index-CG-I_YeN.js} +1 -1
  28. package/dist/assets/{index-ifiZ65Cu.js → index-CxEHgPe3.js} +1 -1
  29. package/dist/assets/{index-C_3LXJYS.js → index-D33VRpYX.js} +1 -1
  30. package/dist/assets/{index-D3KwWKEv.js → index-DYwDeYnm.js} +1 -1
  31. package/dist/assets/{index-Cxx3kFoj.js → index-XXW1ctrV.js} +1 -1
  32. package/dist/assets/{main-BsOvZp5M.js → main-D-o_EGqJ.js} +35 -35
  33. package/dist/assets/{web-B5moyGVG.js → web-Blb26Kj7.js} +1 -1
  34. package/dist/assets/{web-BYzo_b4X.js → web-hHpxvpTK.js} +1 -1
  35. package/dist/index.html +1 -1
  36. package/dist/src/packages/server/codex/backend.js +5 -1
  37. package/dist/src/packages/server/data/builtin-skills/report-task-to-boss.js +1 -1
  38. package/dist/src/packages/server/data/event-queries.js +15 -0
  39. package/dist/src/packages/server/data/migrations/005_drive_actions.sql +19 -0
  40. package/dist/src/packages/server/index.js +1 -0
  41. package/dist/src/packages/server/integrations/gmail/index.js +8 -6
  42. package/dist/src/packages/server/integrations/google-drive/drive-client.js +605 -0
  43. package/dist/src/packages/server/integrations/google-drive/drive-config.js +127 -0
  44. package/dist/src/packages/server/integrations/google-drive/drive-routes.js +365 -0
  45. package/dist/src/packages/server/integrations/google-drive/drive-skill.js +248 -0
  46. package/dist/src/packages/server/integrations/google-drive/index.js +60 -0
  47. package/dist/src/packages/server/integrations/integration-registry.js +2 -0
  48. package/dist/src/packages/server/routes/agents.js +45 -17
  49. package/dist/src/packages/server/services/agent-service.js +7 -1
  50. package/dist/src/packages/server/services/llm-matcher-service.js +3 -1
  51. package/dist/src/packages/shared/agent-types.js +9 -1
  52. package/package.json +1 -1
  53. package/dist/assets/BossSpawnModal-BknVJp2f.js +0 -1
  54. package/dist/assets/GmailOAuthSetup-CO2LqLvU.js +0 -270
  55. package/dist/assets/GoogleOAuthSetup-OVzavssB.js +0 -203
  56. package/dist/assets/IntegrationsPanel-C0JSiDOw.js +0 -2
  57. package/dist/assets/SpawnModal-Ch7yKsdS.js +0 -1
@@ -1 +1 @@
1
- import{bz as s}from"./main-BsOvZp5M.js";import"./modulepreload-polyfill-B5Qt9EMX.js";import"./vendor-react--Eh9ivFN.js";import"./vendor-three-Chj50gSY.js";class f 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{f as LocalNotificationsWeb};
1
+ import{bz as s}from"./main-D-o_EGqJ.js";import"./modulepreload-polyfill-B5Qt9EMX.js";import"./vendor-react--Eh9ivFN.js";import"./vendor-three-Chj50gSY.js";class f 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{f as LocalNotificationsWeb};
@@ -1 +1 @@
1
- import{bz as a}from"./main-BsOvZp5M.js";import{ImpactStyle as i,NotificationType as r}from"./index-BoFICHSl.js";import"./modulepreload-polyfill-B5Qt9EMX.js";import"./vendor-react--Eh9ivFN.js";import"./vendor-three-Chj50gSY.js";class u 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{u as HapticsWeb};
1
+ import{bz as a}from"./main-D-o_EGqJ.js";import{ImpactStyle as i,NotificationType as r}from"./index-BCuYxI5F.js";import"./modulepreload-polyfill-B5Qt9EMX.js";import"./vendor-react--Eh9ivFN.js";import"./vendor-three-Chj50gSY.js";class u 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{u as HapticsWeb};
package/dist/index.html CHANGED
@@ -22,7 +22,7 @@
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-BsOvZp5M.js"></script>
25
+ <script type="module" crossorigin src="/assets/main-D-o_EGqJ.js"></script>
26
26
  <link rel="modulepreload" crossorigin href="/assets/modulepreload-polyfill-B5Qt9EMX.js">
27
27
  <link rel="modulepreload" crossorigin href="/assets/vendor-react--Eh9ivFN.js">
28
28
  <link rel="modulepreload" crossorigin href="/assets/vendor-three-Chj50gSY.js">
@@ -8,7 +8,11 @@ import { loadAreas } from '../data/index.js';
8
8
  function shouldPassCodexModel(model) {
9
9
  if (!model)
10
10
  return false;
11
- if (model === 'codex' || model === 'sonnet' || model === 'opus' || model === 'haiku') {
11
+ if (model === 'codex' ||
12
+ model === 'sonnet' ||
13
+ model === 'opus' ||
14
+ model === 'haiku' ||
15
+ model.startsWith('claude-')) {
12
16
  return false;
13
17
  }
14
18
  return true;
@@ -61,7 +61,7 @@ EOF
61
61
  - Replace \`YOUR_AGENT_ID\` with your actual agent ID from the system prompt
62
62
  - Keep the summary concise but informative (what was done, key outcomes)
63
63
  - Use \`"failed"\` status only when the task truly cannot be completed
64
- - This only works when you have an active delegation from a boss agent
64
+ - Safe to call even if the active delegation window has expired — the server will still accept the report and forward it to your recorded boss when possible
65
65
  - Call this AFTER you have finished all work (not before)
66
66
  - You should still send your regular task completion notification separately`,
67
67
  };
@@ -215,6 +215,21 @@ export function logCalendarAction(log) {
215
215
  recorded_at: log.recordedAt,
216
216
  });
217
217
  }
218
+ // ═══════════════════════════════════════════════════════════════
219
+ // DRIVE ACTION LOGS
220
+ // ═══════════════════════════════════════════════════════════════
221
+ export function logDriveAction(log) {
222
+ return insertOne('drive_action_logs', {
223
+ file_id: log.fileId,
224
+ action: log.action,
225
+ file_name: log.fileName,
226
+ mime_type: log.mimeType,
227
+ folder_id: log.folderId ?? null,
228
+ agent_id: log.agentId ?? null,
229
+ workflow_instance_id: log.workflowInstanceId ?? null,
230
+ recorded_at: log.recordedAt,
231
+ });
232
+ }
218
233
  function jiraRowToEvent(row) {
219
234
  return {
220
235
  id: row.id,
@@ -0,0 +1,19 @@
1
+ -- ═══════════════════════════════════════════════════════════════
2
+ -- DRIVE ACTION LOGS
3
+ -- ═══════════════════════════════════════════════════════════════
4
+
5
+ CREATE TABLE IF NOT EXISTS drive_action_logs (
6
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
7
+ file_id TEXT NOT NULL,
8
+ action TEXT NOT NULL,
9
+ file_name TEXT NOT NULL,
10
+ mime_type TEXT NOT NULL,
11
+ folder_id TEXT,
12
+ agent_id TEXT,
13
+ workflow_instance_id TEXT,
14
+ recorded_at INTEGER NOT NULL
15
+ );
16
+
17
+ CREATE INDEX idx_drive_logs_file ON drive_action_logs(file_id);
18
+ CREATE INDEX idx_drive_logs_workflow ON drive_action_logs(workflow_instance_id);
19
+ CREATE INDEX idx_drive_logs_recorded ON drive_action_logs(recorded_at);
@@ -77,6 +77,7 @@ async function main() {
77
77
  logApprovalEvent: eventQueries.logApprovalEvent,
78
78
  logDocumentGeneration: eventQueries.logDocumentGeneration,
79
79
  logCalendarAction: eventQueries.logCalendarAction,
80
+ logDriveAction: eventQueries.logDriveAction,
80
81
  logJiraTicketAction: eventQueries.logJiraTicketAction,
81
82
  logAudit: eventQueries.logAudit,
82
83
  },
@@ -50,9 +50,11 @@ export const gmailPlugin = {
50
50
  }
51
51
  return {
52
52
  authMethod: gmailClient.getConfig().authMethod || 'oauth2',
53
- clientId: integrationCtx.secrets.get('GOOGLE_CLIENT_ID') || '',
54
- clientSecret: integrationCtx.secrets.get('GOOGLE_CLIENT_SECRET') || '',
55
- serviceAccountJson: integrationCtx.secrets.get('GOOGLE_SERVICE_ACCOUNT_JSON') || '',
53
+ // Mask shared OAuth credentials with '********' placeholder (consistent with
54
+ // Calendar and Drive integrations, which share these same secrets).
55
+ clientId: integrationCtx.secrets.get('GOOGLE_CLIENT_ID') ? '********' : '',
56
+ clientSecret: integrationCtx.secrets.get('GOOGLE_CLIENT_SECRET') ? '********' : '',
57
+ serviceAccountJson: integrationCtx.secrets.get('GOOGLE_SERVICE_ACCOUNT_JSON') ? '********' : '',
56
58
  impersonateEmail: integrationCtx.secrets.get('GOOGLE_IMPERSONATE_EMAIL') || '',
57
59
  pollingIntervalMs: gmailClient.getConfig().pollingIntervalMs,
58
60
  defaultApprovalKeywords: gmailClient.getConfig().defaultApprovalKeywords.join(','),
@@ -65,15 +67,15 @@ export const gmailPlugin = {
65
67
  if (config.authMethod !== undefined) {
66
68
  updates.authMethod = config.authMethod;
67
69
  }
68
- if (config.clientId) {
70
+ if (config.clientId && config.clientId !== '********') {
69
71
  updates.clientId = config.clientId;
70
72
  integrationCtx.secrets.set('GOOGLE_CLIENT_ID', config.clientId);
71
73
  }
72
- if (config.clientSecret) {
74
+ if (config.clientSecret && config.clientSecret !== '********') {
73
75
  updates.clientSecret = config.clientSecret;
74
76
  integrationCtx.secrets.set('GOOGLE_CLIENT_SECRET', config.clientSecret);
75
77
  }
76
- if (config.serviceAccountJson) {
78
+ if (config.serviceAccountJson && config.serviceAccountJson !== '********') {
77
79
  updates.serviceAccountJson = config.serviceAccountJson;
78
80
  integrationCtx.secrets.set('GOOGLE_SERVICE_ACCOUNT_JSON', config.serviceAccountJson);
79
81
  }