@profoundlogic/coderflow-server 0.7.2 → 0.7.5

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 (183) hide show
  1. package/dist/base-image/entrypoint.sh +7 -0
  2. package/dist/base-image/standard-instructions/memory-instructions.md +7 -0
  3. package/dist/coder-server.js +1 -1
  4. package/dist/config.js +1 -1
  5. package/dist/lib/agent-keepalive.js +1 -1
  6. package/dist/lib/agent-models.js +1 -1
  7. package/dist/lib/api-keys.js +1 -1
  8. package/dist/lib/apiKeys.js +1 -1
  9. package/dist/lib/app-server-ports.js +1 -1
  10. package/dist/lib/auto-judge.js +1 -1
  11. package/dist/lib/automation-service.js +1 -1
  12. package/dist/lib/basic-auth.js +1 -1
  13. package/dist/lib/bindings.js +1 -1
  14. package/dist/lib/build-history.js +1 -1
  15. package/dist/lib/build-output-service.js +1 -1
  16. package/dist/lib/build-scheduler.js +1 -1
  17. package/dist/lib/build-service.js +1 -1
  18. package/dist/lib/ca-certificates.js +1 -1
  19. package/dist/lib/claude-oauth-refresh.js +1 -1
  20. package/dist/lib/cli/build.js +1 -1
  21. package/dist/lib/cli/cleanup-users.js +1 -1
  22. package/dist/lib/cli/config-command.js +1 -1
  23. package/dist/lib/cli/config.js +1 -1
  24. package/dist/lib/cli/create-user.js +1 -1
  25. package/dist/lib/cli/grant-admin.js +1 -1
  26. package/dist/lib/cli/init.js +1 -1
  27. package/dist/lib/cli/jira.js +1 -1
  28. package/dist/lib/cli/license.js +1 -1
  29. package/dist/lib/cli/list-roles.js +1 -1
  30. package/dist/lib/cli/list-users.js +1 -1
  31. package/dist/lib/cli/server-manager.js +1 -1
  32. package/dist/lib/cli/set-password.js +1 -1
  33. package/dist/lib/config-migration.js +1 -1
  34. package/dist/lib/container-credential-sync.js +1 -1
  35. package/dist/lib/container-tokens.js +1 -1
  36. package/dist/lib/data-dir.js +1 -1
  37. package/dist/lib/deployment-history.js +1 -1
  38. package/dist/lib/deployment-service.js +1 -1
  39. package/dist/lib/docker-utils.js +1 -1
  40. package/dist/lib/email.js +1 -1
  41. package/dist/lib/emailTemplates.js +1 -1
  42. package/dist/lib/entitlement.js +1 -1
  43. package/dist/lib/external-connections.js +1 -1
  44. package/dist/lib/fetch-utils.js +1 -1
  45. package/dist/lib/git-commit-details-route.js +1 -1
  46. package/dist/lib/git-history-diff-guardrails.js +1 -1
  47. package/dist/lib/git-provider-service.js +1 -1
  48. package/dist/lib/git-provider-setup/github-setup-handler.js +1 -1
  49. package/dist/lib/git-provider-setup/index.js +1 -1
  50. package/dist/lib/git-provider-setup/setup-factory.js +1 -1
  51. package/dist/lib/git-provider-setup/setup-interface.js +1 -1
  52. package/dist/lib/git-providers/azure-devops-provider.js +1 -1
  53. package/dist/lib/git-providers/github-app-provider.js +1 -1
  54. package/dist/lib/git-providers/index.js +1 -1
  55. package/dist/lib/git-providers/provider-factory.js +1 -1
  56. package/dist/lib/git-providers/provider-interface.js +1 -1
  57. package/dist/lib/github-urls.js +1 -1
  58. package/dist/lib/group-objective-linking.js +1 -1
  59. package/dist/lib/ibmi-sync.js +1 -1
  60. package/dist/lib/jira-client.js +1 -1
  61. package/dist/lib/judge-blinding.js +1 -1
  62. package/dist/lib/logger.js +1 -1
  63. package/dist/lib/memory-utils.js +1 -0
  64. package/dist/lib/migration-to-scoped-rbac.js +1 -1
  65. package/dist/lib/model-fetcher.js +1 -1
  66. package/dist/lib/notifications.js +1 -1
  67. package/dist/lib/objective-context.js +1 -1
  68. package/dist/lib/oidc-auth.js +1 -1
  69. package/dist/lib/oidc-device-flow.js +1 -1
  70. package/dist/lib/passwordTokens.js +1 -1
  71. package/dist/lib/permission-resolver.js +1 -1
  72. package/dist/lib/pin-cascade.js +1 -1
  73. package/dist/lib/provider-accounts.js +1 -1
  74. package/dist/lib/provider-oauth.js +1 -1
  75. package/dist/lib/provider-profile.js +1 -1
  76. package/dist/lib/provider-token-refresh.js +1 -1
  77. package/dist/lib/rbac-user-state.js +1 -1
  78. package/dist/lib/request-url.js +1 -1
  79. package/dist/lib/rewind.js +1 -1
  80. package/dist/lib/role-definitions.js +1 -1
  81. package/dist/lib/roles.js +1 -1
  82. package/dist/lib/secrets.js +1 -1
  83. package/dist/lib/setup-repo-git-auth.js +1 -1
  84. package/dist/lib/state-capture.js +1 -1
  85. package/dist/lib/static-files.js +1 -1
  86. package/dist/lib/task-aliases.js +1 -1
  87. package/dist/lib/task-name-format.js +1 -1
  88. package/dist/lib/task-name-generator.js +1 -1
  89. package/dist/lib/task-source-metadata.js +1 -1
  90. package/dist/lib/teams.js +1 -1
  91. package/dist/lib/user-git-oauth.js +1 -1
  92. package/dist/lib/user-git-tokens.js +1 -1
  93. package/dist/lib/users.js +1 -1
  94. package/dist/middleware/requireAuth.js +1 -1
  95. package/dist/middleware/requireInit.js +1 -1
  96. package/dist/middleware/requirePermission.js +1 -1
  97. package/dist/package.json +1 -1
  98. package/dist/playwright.config.js +1 -1
  99. package/dist/playwright.task-terminal.config.js +1 -1
  100. package/dist/routes/apiKeys.js +1 -1
  101. package/dist/routes/auth-oidc.js +1 -1
  102. package/dist/routes/auth.js +1 -1
  103. package/dist/routes/automations.js +1 -1
  104. package/dist/routes/bindings.js +1 -1
  105. package/dist/routes/build.js +1 -1
  106. package/dist/routes/containers.js +1 -1
  107. package/dist/routes/deploy-task.js +1 -1
  108. package/dist/routes/environment-management.js +1 -1
  109. package/dist/routes/environments.js +1 -1
  110. package/dist/routes/external-skills.js +1 -1
  111. package/dist/routes/git-credentials.js +1 -1
  112. package/dist/routes/git-oauth.js +1 -1
  113. package/dist/routes/git-provider-setup.js +1 -1
  114. package/dist/routes/health.js +1 -1
  115. package/dist/routes/jira.js +1 -1
  116. package/dist/routes/objective-management.js +1 -1
  117. package/dist/routes/password.js +1 -1
  118. package/dist/routes/prompt.js +1 -1
  119. package/dist/routes/provider-auth.js +1 -1
  120. package/dist/routes/qa.js +1 -1
  121. package/dist/routes/roles.js +1 -1
  122. package/dist/routes/settings.js +1 -1
  123. package/dist/routes/skill-management.js +1 -1
  124. package/dist/routes/skills.js +1 -1
  125. package/dist/routes/tasks.js +1 -1
  126. package/dist/routes/teams.js +1 -1
  127. package/dist/routes/templates.js +1 -1
  128. package/dist/routes/test-task.js +1 -1
  129. package/dist/routes/test.js +1 -1
  130. package/dist/routes/users.js +1 -1
  131. package/dist/routes/visualizations.js +1 -1
  132. package/dist/scripts/create-user.js +1 -1
  133. package/dist/scripts/migrate-config-to-data-dir.js +1 -1
  134. package/dist/shipped-skills/memory-management/SKILL.md +103 -0
  135. package/dist/start.js +1 -1
  136. package/dist/web-ui/public/activity-detail-modal.js +1 -1
  137. package/dist/web-ui/public/activity-feed.js +1 -1
  138. package/dist/web-ui/public/activity-formatters.js +1 -1
  139. package/dist/web-ui/public/agent-event-parser.js +1 -1
  140. package/dist/web-ui/public/app.js +1 -1
  141. package/dist/web-ui/public/approve-dialog.js +1 -1
  142. package/dist/web-ui/public/automation-links.js +1 -1
  143. package/dist/web-ui/public/automation-schedule.js +1 -1
  144. package/dist/web-ui/public/comments-widget.js +1 -1
  145. package/dist/web-ui/public/diff-utils.js +1 -1
  146. package/dist/web-ui/public/docs/admin/ai-providers.md +5 -5
  147. package/dist/web-ui/public/environments.css +61 -0
  148. package/dist/web-ui/public/environments.html +114 -0
  149. package/dist/web-ui/public/environments.js +1 -1
  150. package/dist/web-ui/public/feedback-widget.css +15 -5
  151. package/dist/web-ui/public/feedback-widget.js +1 -1
  152. package/dist/web-ui/public/file-selection-tree.js +1 -1
  153. package/dist/web-ui/public/git-history-lazy-utils.js +1 -1
  154. package/dist/web-ui/public/git-history.js +1 -1
  155. package/dist/web-ui/public/git-status.js +1 -1
  156. package/dist/web-ui/public/ibmi-file-filter.js +1 -1
  157. package/dist/web-ui/public/index.html +20 -0
  158. package/dist/web-ui/public/index.js +1 -1
  159. package/dist/web-ui/public/login.js +1 -1
  160. package/dist/web-ui/public/markdown-editor.js +1 -1
  161. package/dist/web-ui/public/markdown-file-editor.js +1 -1
  162. package/dist/web-ui/public/modal-maximize.js +1 -1
  163. package/dist/web-ui/public/notifications.js +1 -1
  164. package/dist/web-ui/public/permissions.js +1 -1
  165. package/dist/web-ui/public/pr-dialog.js +1 -1
  166. package/dist/web-ui/public/roles.js +1 -1
  167. package/dist/web-ui/public/server-health.js +1 -1
  168. package/dist/web-ui/public/settings.html +1 -1
  169. package/dist/web-ui/public/settings.js +1 -1
  170. package/dist/web-ui/public/setup-password.js +1 -1
  171. package/dist/web-ui/public/skills.js +1 -1
  172. package/dist/web-ui/public/sse-client.js +1 -1
  173. package/dist/web-ui/public/sse-shared-worker.js +1 -1
  174. package/dist/web-ui/public/styles.css +25 -0
  175. package/dist/web-ui/public/task-judging-helpers.js +1 -1
  176. package/dist/web-ui/public/task.html +15 -1
  177. package/dist/web-ui/public/task.js +1 -1
  178. package/dist/web-ui/public/teams.js +1 -1
  179. package/dist/web-ui/public/terminal.js +1 -1
  180. package/dist/web-ui/public/theme.js +1 -1
  181. package/dist/web-ui/public/users.js +1 -1
  182. package/dist/web-ui/public/variant-grouping.js +1 -1
  183. package/package.json +2 -2
@@ -1 +1 @@
1
- function isSharedWorkerSupported(){return typeof SharedWorker!=='undefined';}function eventTypeToHandler(_0x576fdb){if(_0x576fdb==='connected')return'onConnected';if(_0x576fdb==='error')return'onError';return'on'+_0x576fdb['split']('-')['map'](_0xfab6c=>_0xfab6c['charAt'](0x0)['toUpperCase']()+_0xfab6c['slice'](0x1))['join']('');}const TASK_STREAM_EVENTS=['activity','logs','metadata','summary','changed-files','app-server-status','complete'];export class TaskUpdatesClient{constructor(){this['listeners']=new Map(),this['worker']=null,this['port']=null,this['eventSource']=null,this['userId']=null,this['reconnectTimeout']=null,this['reconnectAttempts']=0x0,this['useSharedWorker']=isSharedWorkerSupported(),this['connected']=![],this['_taskSubscriptions']=new Map(),this['_taskSubIdCounter']=0x0,this['_handleWorkerMessage']=this['_handleWorkerMessage']['bind'](this),this['_handleDirectSSE']=this['_handleDirectSSE']['bind'](this);}['on'](_0x4f0508,_0x3b1b10){return!this['listeners']['has'](_0x4f0508)&&this['listeners']['set'](_0x4f0508,new Set()),this['listeners']['get'](_0x4f0508)['add'](_0x3b1b10),this;}['off'](_0x2fe567,_0x94fc85){return this['listeners']['has'](_0x2fe567)&&this['listeners']['get'](_0x2fe567)['delete'](_0x94fc85),this;}['_emit'](_0x189852,_0x3ccc33){this['listeners']['has'](_0x189852)&&this['listeners']['get'](_0x189852)['forEach'](_0x4387bd=>{try{_0x4387bd(_0x3ccc33);}catch(_0x5045b1){console['error']('[SSE\x20Client]\x20Error\x20in\x20'+_0x189852+'\x20listener:',_0x5045b1);}});}['connect'](_0x1f52b1='me'){this['userId']=_0x1f52b1,this['useSharedWorker']?this['_connectViaWorker'](_0x1f52b1):this['_connectDirect'](_0x1f52b1);}['_connectViaWorker'](_0x50f38a){try{this['_ensureWorker'](),this['port']['postMessage']({'action':'connect','userId':_0x50f38a});}catch(_0x1679e6){console['error']('[SSE\x20Client]\x20SharedWorker\x20failed,\x20falling\x20back\x20to\x20direct\x20SSE:',_0x1679e6),this['useSharedWorker']=![],this['_connectDirect'](_0x50f38a);}}['_ensureWorker'](){!this['worker']&&(this['worker']=new SharedWorker('/sse-shared-worker.js'),this['port']=this['worker']['port'],this['port']['onmessage']=this['_handleWorkerMessage'],this['port']['onmessageerror']=_0x251aa0=>{console['error']('[SSE\x20Client]\x20Worker\x20message\x20error:',_0x251aa0),this['_emit']('error',{'error':'Worker\x20message\x20error'});},this['port']['start']());}['_handleWorkerMessage'](_0x168b6a){const _0x360371=_0x168b6a['data'];if(_0x360371['type']&&_0x360371['type']['startsWith']('task:')){this['_handleTaskStreamMessage'](_0x360371);return;}switch(_0x360371['type']){case'connected':this['connected']=!![],this['_emit']('connected',{});break;case'snapshot':case'activity':case'status':case'new-task':case'queue-position':try{const _0x44cfdd=JSON['parse'](_0x360371['data']);this['_emit'](_0x360371['type'],_0x44cfdd);}catch(_0x14be1c){console['error']('[SSE\x20Client]\x20Failed\x20to\x20parse\x20'+_0x360371['type']+'\x20data:',_0x14be1c);}break;case'error':this['connected']=![],this['_emit']('error',_0x360371);break;default:console['warn']('[SSE\x20Client]\x20Unknown\x20message\x20type:',_0x360371['type']);}}['_handleTaskStreamMessage'](_0x5cb1f0){const {taskId:_0x21efb1,type:_0x4a73ca,data:_0x4d5cc6}=_0x5cb1f0,_0x556ff5=this['_taskSubscriptions']['get'](_0x21efb1);if(!_0x556ff5||_0x556ff5['size']===0x0)return;const _0x1eeb26=_0x4a73ca['replace']('task:',''),_0x5884d1=eventTypeToHandler(_0x1eeb26);_0x556ff5['forEach'](_0x437fc2=>{if(_0x437fc2['handlers'][_0x5884d1])try{const _0x4c1ec1=typeof _0x4d5cc6==='string'?JSON['parse'](_0x4d5cc6):_0x4d5cc6;_0x437fc2['handlers'][_0x5884d1](_0x4c1ec1);}catch(_0x41ea19){console['error']('[SSE\x20Client]\x20Error\x20in\x20task\x20'+_0x1eeb26+'\x20handler:',_0x41ea19);}});}['_connectDirect'](_0x47a285){this['eventSource']&&(this['eventSource']['close'](),this['eventSource']=null);const _0x2c707e=_0x47a285&&_0x47a285!=='me'?'?userId='+_0x47a285:'';try{this['eventSource']=new EventSource('/tasks/updates'+_0x2c707e),this['eventSource']['addEventListener']('open',()=>{this['connected']=!![],this['reconnectAttempts']=0x0,this['_emit']('connected',{});}),this['eventSource']['addEventListener']('snapshot',_0x703d45=>{this['_handleDirectSSE']('snapshot',_0x703d45),this['reconnectAttempts']=0x0;}),this['eventSource']['addEventListener']('activity',_0x8d816b=>{this['_handleDirectSSE']('activity',_0x8d816b);}),this['eventSource']['addEventListener']('status',_0xfd5531=>{this['_handleDirectSSE']('status',_0xfd5531);}),this['eventSource']['addEventListener']('new-task',_0x1fbbd2=>{this['_handleDirectSSE']('new-task',_0x1fbbd2);}),this['eventSource']['addEventListener']('queue-position',_0x462e16=>{this['_handleDirectSSE']('queue-position',_0x462e16);}),this['eventSource']['addEventListener']('error',_0x11a56b=>{console['error']('[SSE\x20Client]\x20Direct\x20SSE\x20error:',_0x11a56b),this['connected']=![],this['_emit']('error',{'error':'Connection\x20error'}),this['eventSource']&&(this['eventSource']['close'](),this['eventSource']=null),this['_scheduleReconnect']();});}catch(_0x1b6a67){console['error']('[SSE\x20Client]\x20Failed\x20to\x20create\x20EventSource:',_0x1b6a67),this['_emit']('error',{'error':_0x1b6a67['message']}),this['_scheduleReconnect']();}}['_handleDirectSSE'](_0x2209cd,_0x528bbb){try{const _0xdc3478=JSON['parse'](_0x528bbb['data']);this['_emit'](_0x2209cd,_0xdc3478);}catch(_0x58489e){console['error']('[SSE\x20Client]\x20Failed\x20to\x20parse\x20'+_0x2209cd+'\x20data:',_0x58489e);}}['_scheduleReconnect'](){this['reconnectTimeout']&&clearTimeout(this['reconnectTimeout']);const _0x4e7b47=Math['min'](0x3e8*Math['pow'](0x2,this['reconnectAttempts']),0x7530);this['reconnectAttempts']++,console['log']('[SSE\x20Client]\x20Scheduling\x20reconnect\x20in\x20'+_0x4e7b47+'ms'),this['reconnectTimeout']=setTimeout(()=>{this['_connectDirect'](this['userId']);},_0x4e7b47);}['changeFilter'](_0x489acc){if(_0x489acc===this['userId'])return;this['userId']=_0x489acc;if(this['useSharedWorker']&&this['port'])this['port']['postMessage']({'action':'changeFilter','userId':_0x489acc});else this['eventSource']&&this['_connectDirect'](_0x489acc);}['subscribeTask'](_0x176313,_0x2ccd84){return this['useSharedWorker']?this['_subscribeTaskViaWorker'](_0x176313,_0x2ccd84):this['_subscribeTaskDirect'](_0x176313,_0x2ccd84);}['unsubscribeTask'](_0x1a8ae4){if(!_0x1a8ae4)return;_0x1a8ae4['type']==='worker'?this['_unsubscribeTaskWorker'](_0x1a8ae4):this['_unsubscribeTaskDirect'](_0x1a8ae4);}['_subscribeTaskViaWorker'](_0x2734b1,_0x1eaefa){try{this['_ensureWorker']();}catch(_0x456e24){return console['error']('[SSE\x20Client]\x20SharedWorker\x20failed\x20for\x20task\x20sub,\x20falling\x20back:',_0x456e24),this['useSharedWorker']=![],this['_subscribeTaskDirect'](_0x2734b1,_0x1eaefa);}const _0x2eb249=++this['_taskSubIdCounter'],_0x348025={'type':'worker','taskId':_0x2734b1,'handlers':_0x1eaefa,'id':_0x2eb249};return!this['_taskSubscriptions']['has'](_0x2734b1)&&(this['_taskSubscriptions']['set'](_0x2734b1,new Set()),this['port']['postMessage']({'action':'subscribeTask','taskId':_0x2734b1})),this['_taskSubscriptions']['get'](_0x2734b1)['add'](_0x348025),_0x348025;}['_unsubscribeTaskWorker'](_0x88b86e){const {taskId:_0x8fadba}=_0x88b86e,_0x5a0c3a=this['_taskSubscriptions']['get'](_0x8fadba);if(_0x5a0c3a){_0x5a0c3a['delete'](_0x88b86e);if(_0x5a0c3a['size']===0x0){this['_taskSubscriptions']['delete'](_0x8fadba);try{this['port']&&this['port']['postMessage']({'action':'unsubscribeTask','taskId':_0x8fadba});}catch(_0x24017d){}}}}['_subscribeTaskDirect'](_0x1eceea,_0x32e21f){const _0x45be64=++this['_taskSubIdCounter'],_0xeb3894=new EventSource('/tasks/'+_0x1eceea+'/stream'),_0x2d60b4={'type':'direct','taskId':_0x1eceea,'handlers':_0x32e21f,'id':_0x45be64,'eventSource':_0xeb3894};!this['_taskSubscriptions']['has'](_0x1eceea)&&this['_taskSubscriptions']['set'](_0x1eceea,new Set());this['_taskSubscriptions']['get'](_0x1eceea)['add'](_0x2d60b4);for(const _0x334b96 of TASK_STREAM_EVENTS){const _0x44dfd8=eventTypeToHandler(_0x334b96);_0xeb3894['addEventListener'](_0x334b96,_0x625b31=>{if(_0x32e21f[_0x44dfd8])try{const _0x18051a=JSON['parse'](_0x625b31['data']);_0x32e21f[_0x44dfd8](_0x18051a);}catch(_0x100a00){console['error']('[SSE\x20Client]\x20Error\x20parsing\x20task\x20'+_0x334b96+':',_0x100a00);}});}return _0xeb3894['addEventListener']('open',()=>{if(_0x32e21f['onConnected'])_0x32e21f['onConnected']();}),_0xeb3894['addEventListener']('error',()=>{if(_0x32e21f['onError'])_0x32e21f['onError']({'error':'Connection\x20error'});}),_0x2d60b4;}['_unsubscribeTaskDirect'](_0x3ad0d2){_0x3ad0d2['eventSource']&&(_0x3ad0d2['eventSource']['close'](),_0x3ad0d2['eventSource']=null);const _0x4c7750=this['_taskSubscriptions']['get'](_0x3ad0d2['taskId']);_0x4c7750&&(_0x4c7750['delete'](_0x3ad0d2),_0x4c7750['size']===0x0&&this['_taskSubscriptions']['delete'](_0x3ad0d2['taskId']));}['disconnect'](){this['reconnectTimeout']&&(clearTimeout(this['reconnectTimeout']),this['reconnectTimeout']=null);this['_taskSubscriptions']['forEach']((_0x1ab193,_0x406dce)=>{_0x1ab193['forEach'](_0x247c6d=>{_0x247c6d['type']==='direct'&&_0x247c6d['eventSource']&&_0x247c6d['eventSource']['close']();});}),this['_taskSubscriptions']['clear']();if(this['useSharedWorker']&&this['port'])try{this['port']['postMessage']({'action':'disconnect'});}catch(_0x3a32f5){}this['eventSource']&&(this['eventSource']['close'](),this['eventSource']=null),this['connected']=![];}['isConnected'](){return this['connected'];}['isUsingSharedWorker'](){return this['useSharedWorker'];}}let globalClient=null;export function getTaskUpdatesClient(){return!globalClient&&(globalClient=new TaskUpdatesClient()),globalClient;}
1
+ function isSharedWorkerSupported(){return typeof SharedWorker!=='undefined';}function eventTypeToHandler(_0x210281){if(_0x210281==='connected')return'onConnected';if(_0x210281==='error')return'onError';return'on'+_0x210281['split']('-')['map'](_0x19a45c=>_0x19a45c['charAt'](0x0)['toUpperCase']()+_0x19a45c['slice'](0x1))['join']('');}const TASK_STREAM_EVENTS=['activity','logs','metadata','summary','changed-files','app-server-status','complete'];export class TaskUpdatesClient{constructor(){this['listeners']=new Map(),this['worker']=null,this['port']=null,this['eventSource']=null,this['userId']=null,this['reconnectTimeout']=null,this['reconnectAttempts']=0x0,this['useSharedWorker']=isSharedWorkerSupported(),this['connected']=![],this['_taskSubscriptions']=new Map(),this['_taskSubIdCounter']=0x0,this['_handleWorkerMessage']=this['_handleWorkerMessage']['bind'](this),this['_handleDirectSSE']=this['_handleDirectSSE']['bind'](this);}['on'](_0x5034df,_0x107515){return!this['listeners']['has'](_0x5034df)&&this['listeners']['set'](_0x5034df,new Set()),this['listeners']['get'](_0x5034df)['add'](_0x107515),this;}['off'](_0x4c7acd,_0x3e4d4b){return this['listeners']['has'](_0x4c7acd)&&this['listeners']['get'](_0x4c7acd)['delete'](_0x3e4d4b),this;}['_emit'](_0x1c844f,_0x2e5c67){this['listeners']['has'](_0x1c844f)&&this['listeners']['get'](_0x1c844f)['forEach'](_0x12aba4=>{try{_0x12aba4(_0x2e5c67);}catch(_0x3a4ed3){console['error']('[SSE\x20Client]\x20Error\x20in\x20'+_0x1c844f+'\x20listener:',_0x3a4ed3);}});}['connect'](_0x53637c='me'){this['userId']=_0x53637c,this['useSharedWorker']?this['_connectViaWorker'](_0x53637c):this['_connectDirect'](_0x53637c);}['_connectViaWorker'](_0x536e0d){try{this['_ensureWorker'](),this['port']['postMessage']({'action':'connect','userId':_0x536e0d});}catch(_0x1092ea){console['error']('[SSE\x20Client]\x20SharedWorker\x20failed,\x20falling\x20back\x20to\x20direct\x20SSE:',_0x1092ea),this['useSharedWorker']=![],this['_connectDirect'](_0x536e0d);}}['_ensureWorker'](){!this['worker']&&(this['worker']=new SharedWorker('/sse-shared-worker.js'),this['port']=this['worker']['port'],this['port']['onmessage']=this['_handleWorkerMessage'],this['port']['onmessageerror']=_0x2f7f8a=>{console['error']('[SSE\x20Client]\x20Worker\x20message\x20error:',_0x2f7f8a),this['_emit']('error',{'error':'Worker\x20message\x20error'});},this['port']['start']());}['_handleWorkerMessage'](_0x2bdd3a){const _0x3729b7=_0x2bdd3a['data'];if(_0x3729b7['type']&&_0x3729b7['type']['startsWith']('task:')){this['_handleTaskStreamMessage'](_0x3729b7);return;}switch(_0x3729b7['type']){case'connected':this['connected']=!![],this['_emit']('connected',{});break;case'snapshot':case'activity':case'status':case'new-task':case'queue-position':try{const _0x1cff6f=JSON['parse'](_0x3729b7['data']);this['_emit'](_0x3729b7['type'],_0x1cff6f);}catch(_0x55d9d3){console['error']('[SSE\x20Client]\x20Failed\x20to\x20parse\x20'+_0x3729b7['type']+'\x20data:',_0x55d9d3);}break;case'error':this['connected']=![],this['_emit']('error',_0x3729b7);break;default:console['warn']('[SSE\x20Client]\x20Unknown\x20message\x20type:',_0x3729b7['type']);}}['_handleTaskStreamMessage'](_0x24a09c){const {taskId:_0x38cefd,type:_0x4c163b,data:_0x414aa3}=_0x24a09c,_0x4893c1=this['_taskSubscriptions']['get'](_0x38cefd);if(!_0x4893c1||_0x4893c1['size']===0x0)return;const _0x4434b7=_0x4c163b['replace']('task:',''),_0x51e002=eventTypeToHandler(_0x4434b7);_0x4893c1['forEach'](_0x2f1b92=>{if(_0x2f1b92['handlers'][_0x51e002])try{const _0x47a335=typeof _0x414aa3==='string'?JSON['parse'](_0x414aa3):_0x414aa3;_0x2f1b92['handlers'][_0x51e002](_0x47a335);}catch(_0x29aa00){console['error']('[SSE\x20Client]\x20Error\x20in\x20task\x20'+_0x4434b7+'\x20handler:',_0x29aa00);}});}['_connectDirect'](_0x41f78f){this['eventSource']&&(this['eventSource']['close'](),this['eventSource']=null);const _0x369b20=_0x41f78f&&_0x41f78f!=='me'?'?userId='+_0x41f78f:'';try{this['eventSource']=new EventSource('/tasks/updates'+_0x369b20),this['eventSource']['addEventListener']('open',()=>{this['connected']=!![],this['reconnectAttempts']=0x0,this['_emit']('connected',{});}),this['eventSource']['addEventListener']('snapshot',_0x33b176=>{this['_handleDirectSSE']('snapshot',_0x33b176),this['reconnectAttempts']=0x0;}),this['eventSource']['addEventListener']('activity',_0x388bde=>{this['_handleDirectSSE']('activity',_0x388bde);}),this['eventSource']['addEventListener']('status',_0x10d07d=>{this['_handleDirectSSE']('status',_0x10d07d);}),this['eventSource']['addEventListener']('new-task',_0x54ec3c=>{this['_handleDirectSSE']('new-task',_0x54ec3c);}),this['eventSource']['addEventListener']('queue-position',_0x3083f6=>{this['_handleDirectSSE']('queue-position',_0x3083f6);}),this['eventSource']['addEventListener']('error',_0x1bdecc=>{console['error']('[SSE\x20Client]\x20Direct\x20SSE\x20error:',_0x1bdecc),this['connected']=![],this['_emit']('error',{'error':'Connection\x20error'}),this['eventSource']&&(this['eventSource']['close'](),this['eventSource']=null),this['_scheduleReconnect']();});}catch(_0x148ac8){console['error']('[SSE\x20Client]\x20Failed\x20to\x20create\x20EventSource:',_0x148ac8),this['_emit']('error',{'error':_0x148ac8['message']}),this['_scheduleReconnect']();}}['_handleDirectSSE'](_0x31348f,_0x3f064a){try{const _0x2b0a41=JSON['parse'](_0x3f064a['data']);this['_emit'](_0x31348f,_0x2b0a41);}catch(_0x1f1472){console['error']('[SSE\x20Client]\x20Failed\x20to\x20parse\x20'+_0x31348f+'\x20data:',_0x1f1472);}}['_scheduleReconnect'](){this['reconnectTimeout']&&clearTimeout(this['reconnectTimeout']);const _0x48f6a2=Math['min'](0x3e8*Math['pow'](0x2,this['reconnectAttempts']),0x7530);this['reconnectAttempts']++,console['log']('[SSE\x20Client]\x20Scheduling\x20reconnect\x20in\x20'+_0x48f6a2+'ms'),this['reconnectTimeout']=setTimeout(()=>{this['_connectDirect'](this['userId']);},_0x48f6a2);}['changeFilter'](_0x2906e1){if(_0x2906e1===this['userId'])return;this['userId']=_0x2906e1;if(this['useSharedWorker']&&this['port'])this['port']['postMessage']({'action':'changeFilter','userId':_0x2906e1});else this['eventSource']&&this['_connectDirect'](_0x2906e1);}['subscribeTask'](_0x442072,_0x37c3fb){return this['useSharedWorker']?this['_subscribeTaskViaWorker'](_0x442072,_0x37c3fb):this['_subscribeTaskDirect'](_0x442072,_0x37c3fb);}['unsubscribeTask'](_0xed716){if(!_0xed716)return;_0xed716['type']==='worker'?this['_unsubscribeTaskWorker'](_0xed716):this['_unsubscribeTaskDirect'](_0xed716);}['_subscribeTaskViaWorker'](_0x225fa3,_0x216b74){try{this['_ensureWorker']();}catch(_0x4883b5){return console['error']('[SSE\x20Client]\x20SharedWorker\x20failed\x20for\x20task\x20sub,\x20falling\x20back:',_0x4883b5),this['useSharedWorker']=![],this['_subscribeTaskDirect'](_0x225fa3,_0x216b74);}const _0x169e84=++this['_taskSubIdCounter'],_0x7854b5={'type':'worker','taskId':_0x225fa3,'handlers':_0x216b74,'id':_0x169e84};return!this['_taskSubscriptions']['has'](_0x225fa3)&&(this['_taskSubscriptions']['set'](_0x225fa3,new Set()),this['port']['postMessage']({'action':'subscribeTask','taskId':_0x225fa3})),this['_taskSubscriptions']['get'](_0x225fa3)['add'](_0x7854b5),_0x7854b5;}['_unsubscribeTaskWorker'](_0x3d2d7d){const {taskId:_0x5509c8}=_0x3d2d7d,_0x2d3422=this['_taskSubscriptions']['get'](_0x5509c8);if(_0x2d3422){_0x2d3422['delete'](_0x3d2d7d);if(_0x2d3422['size']===0x0){this['_taskSubscriptions']['delete'](_0x5509c8);try{this['port']&&this['port']['postMessage']({'action':'unsubscribeTask','taskId':_0x5509c8});}catch(_0x4737c5){}}}}['_subscribeTaskDirect'](_0x51cf15,_0x2f2135){const _0x5d53d5=++this['_taskSubIdCounter'],_0x1c171d=new EventSource('/tasks/'+_0x51cf15+'/stream'),_0x1dcc19={'type':'direct','taskId':_0x51cf15,'handlers':_0x2f2135,'id':_0x5d53d5,'eventSource':_0x1c171d};!this['_taskSubscriptions']['has'](_0x51cf15)&&this['_taskSubscriptions']['set'](_0x51cf15,new Set());this['_taskSubscriptions']['get'](_0x51cf15)['add'](_0x1dcc19);for(const _0xeea261 of TASK_STREAM_EVENTS){const _0x37fccc=eventTypeToHandler(_0xeea261);_0x1c171d['addEventListener'](_0xeea261,_0x1e37a3=>{if(_0x2f2135[_0x37fccc])try{const _0x108743=JSON['parse'](_0x1e37a3['data']);_0x2f2135[_0x37fccc](_0x108743);}catch(_0xe4006c){console['error']('[SSE\x20Client]\x20Error\x20parsing\x20task\x20'+_0xeea261+':',_0xe4006c);}});}return _0x1c171d['addEventListener']('open',()=>{if(_0x2f2135['onConnected'])_0x2f2135['onConnected']();}),_0x1c171d['addEventListener']('error',()=>{if(_0x2f2135['onError'])_0x2f2135['onError']({'error':'Connection\x20error'});}),_0x1dcc19;}['_unsubscribeTaskDirect'](_0x2316d5){_0x2316d5['eventSource']&&(_0x2316d5['eventSource']['close'](),_0x2316d5['eventSource']=null);const _0x18bc69=this['_taskSubscriptions']['get'](_0x2316d5['taskId']);_0x18bc69&&(_0x18bc69['delete'](_0x2316d5),_0x18bc69['size']===0x0&&this['_taskSubscriptions']['delete'](_0x2316d5['taskId']));}['disconnect'](){this['reconnectTimeout']&&(clearTimeout(this['reconnectTimeout']),this['reconnectTimeout']=null);this['_taskSubscriptions']['forEach']((_0x137c3a,_0x13dbc1)=>{_0x137c3a['forEach'](_0x1bd8f4=>{_0x1bd8f4['type']==='direct'&&_0x1bd8f4['eventSource']&&_0x1bd8f4['eventSource']['close']();});}),this['_taskSubscriptions']['clear']();if(this['useSharedWorker']&&this['port'])try{this['port']['postMessage']({'action':'disconnect'});}catch(_0x3cdf1f){}this['eventSource']&&(this['eventSource']['close'](),this['eventSource']=null),this['connected']=![];}['isConnected'](){return this['connected'];}['isUsingSharedWorker'](){return this['useSharedWorker'];}}let globalClient=null;export function getTaskUpdatesClient(){return!globalClient&&(globalClient=new TaskUpdatesClient()),globalClient;}
@@ -1 +1 @@
1
- const ports=new Set();let eventSource=null,currentUserId=null,reconnectTimeout=null,reconnectAttempts=0x0;const MAX_RECONNECT_DELAY=0x7530,taskStreams=new Map(),TASK_STREAM_EVENTS=['activity','logs','metadata','summary','changed-files','app-server-status','complete'];function connect(_0x2cf3f3){eventSource&&currentUserId!==_0x2cf3f3&&(eventSource['close'](),eventSource=null);if(eventSource&&eventSource['readyState']!==EventSource['CLOSED'])return;currentUserId=_0x2cf3f3;const _0x594a57=_0x2cf3f3&&_0x2cf3f3!=='me'?'?userId='+_0x2cf3f3:'';try{eventSource=new EventSource('/tasks/updates'+_0x594a57),eventSource['addEventListener']('snapshot',_0x82acfd=>{broadcast({'type':'snapshot','data':_0x82acfd['data']}),reconnectAttempts=0x0;}),eventSource['addEventListener']('activity',_0x43f76c=>{broadcast({'type':'activity','data':_0x43f76c['data']});}),eventSource['addEventListener']('status',_0x1aa35d=>{broadcast({'type':'status','data':_0x1aa35d['data']});}),eventSource['addEventListener']('new-task',_0x3fd11a=>{broadcast({'type':'new-task','data':_0x3fd11a['data']});}),eventSource['addEventListener']('queue-position',_0x46e575=>{broadcast({'type':'queue-position','data':_0x46e575['data']});}),eventSource['addEventListener']('open',()=>{broadcast({'type':'connected'}),reconnectAttempts=0x0;}),eventSource['addEventListener']('error',_0x31d932=>{console['error']('[SSE\x20Worker]\x20Connection\x20error:',_0x31d932),broadcast({'type':'error','error':'Connection\x20error'}),eventSource&&(eventSource['close'](),eventSource=null),scheduleReconnect();});}catch(_0x470e9b){console['error']('[SSE\x20Worker]\x20Failed\x20to\x20create\x20EventSource:',_0x470e9b),broadcast({'type':'error','error':_0x470e9b['message']}),scheduleReconnect();}}function scheduleReconnect(){reconnectTimeout&&clearTimeout(reconnectTimeout);if(ports['size']===0x0)return;const _0x3c01d6=Math['min'](0x3e8*Math['pow'](0x2,reconnectAttempts),MAX_RECONNECT_DELAY);reconnectAttempts++,console['log']('[SSE\x20Worker]\x20Scheduling\x20reconnect\x20in\x20'+_0x3c01d6+'ms\x20(attempt\x20'+reconnectAttempts+')'),reconnectTimeout=setTimeout(()=>{ports['size']>0x0&&connect(currentUserId);},_0x3c01d6);}function broadcast(_0x531721){const _0x311b98=[];ports['forEach'](_0x1733be=>{try{_0x1733be['postMessage'](_0x531721);}catch(_0x559bb4){console['warn']('[SSE\x20Worker]\x20Failed\x20to\x20send\x20to\x20port,\x20removing:',_0x559bb4),_0x311b98['push'](_0x1733be);}}),_0x311b98['length']>0x0&&cleanUpDeadPorts(_0x311b98),ports['size']===0x0&&eventSource&&(console['log']('[SSE\x20Worker]\x20No\x20more\x20connected\x20ports,\x20closing\x20SSE'),eventSource['close'](),eventSource=null,reconnectTimeout&&(clearTimeout(reconnectTimeout),reconnectTimeout=null));}function subscribeTask(_0x58ed51,_0x4da809){let _0x334e3a=taskStreams['get'](_0x4da809);!_0x334e3a&&(_0x334e3a={'eventSource':null,'reconnectTimeout':null,'reconnectAttempts':0x0,'subscribedPorts':new Set()},taskStreams['set'](_0x4da809,_0x334e3a));_0x334e3a['subscribedPorts']['add'](_0x58ed51);if(!_0x334e3a['eventSource']||_0x334e3a['eventSource']['readyState']===EventSource['CLOSED'])connectTaskStream(_0x4da809);else{if(_0x334e3a['eventSource']['readyState']===EventSource['OPEN'])try{_0x58ed51['postMessage']({'type':'task:connected','taskId':_0x4da809});}catch(_0x5a4e67){}}}function unsubscribeTask(_0x33d1fe,_0xfdd797){const _0x44f42e=taskStreams['get'](_0xfdd797);if(!_0x44f42e)return;_0x44f42e['subscribedPorts']['delete'](_0x33d1fe),_0x44f42e['subscribedPorts']['size']===0x0&&deferredCloseTaskStream(_0xfdd797);}function connectTaskStream(_0x5ba3ef){const _0x4764fd=taskStreams['get'](_0x5ba3ef);if(!_0x4764fd)return;_0x4764fd['eventSource']&&(_0x4764fd['eventSource']['close'](),_0x4764fd['eventSource']=null);try{_0x4764fd['eventSource']=new EventSource('/tasks/'+_0x5ba3ef+'/stream');for(const _0x4b8580 of TASK_STREAM_EVENTS){_0x4764fd['eventSource']['addEventListener'](_0x4b8580,_0x2da268=>{broadcastToTask(_0x5ba3ef,'task:'+_0x4b8580,_0x2da268['data']),_0x4764fd['reconnectAttempts']=0x0;});}_0x4764fd['eventSource']['addEventListener']('open',()=>{broadcastToTask(_0x5ba3ef,'task:connected','{}'),_0x4764fd['reconnectAttempts']=0x0;}),_0x4764fd['eventSource']['addEventListener']('error',()=>{broadcastToTask(_0x5ba3ef,'task:error',JSON['stringify']({'error':'Connection\x20error'})),_0x4764fd['eventSource']&&(_0x4764fd['eventSource']['close'](),_0x4764fd['eventSource']=null),scheduleTaskReconnect(_0x5ba3ef);});}catch(_0x2acfb5){console['error']('[SSE\x20Worker]\x20Failed\x20to\x20create\x20task\x20EventSource\x20for\x20'+_0x5ba3ef+':',_0x2acfb5),broadcastToTask(_0x5ba3ef,'task:error',JSON['stringify']({'error':_0x2acfb5['message']})),scheduleTaskReconnect(_0x5ba3ef);}}function broadcastToTask(_0x5d7aab,_0x1b85d3,_0xbeb232){const _0x1ea676=taskStreams['get'](_0x5d7aab);if(!_0x1ea676)return;const _0xed4542=[];_0x1ea676['subscribedPorts']['forEach'](_0x583f18=>{try{_0x583f18['postMessage']({'type':_0x1b85d3,'taskId':_0x5d7aab,'data':_0xbeb232});}catch(_0x4e7e17){_0xed4542['push'](_0x583f18);}}),_0xed4542['length']>0x0&&(_0xed4542['forEach'](_0x4b31c0=>_0x1ea676['subscribedPorts']['delete'](_0x4b31c0)),cleanUpDeadPorts(_0xed4542),_0x1ea676['subscribedPorts']['size']===0x0&&closeTaskStream(_0x5d7aab));}function closeTaskStream(_0x6bb74a){const _0x8d82c7=taskStreams['get'](_0x6bb74a);if(!_0x8d82c7)return;_0x8d82c7['eventSource']&&_0x8d82c7['eventSource']['close'](),_0x8d82c7['reconnectTimeout']&&clearTimeout(_0x8d82c7['reconnectTimeout']),taskStreams['delete'](_0x6bb74a);}function deferredCloseTaskStream(_0x1c66ab){setTimeout(()=>{const _0x3fa38c=taskStreams['get'](_0x1c66ab);_0x3fa38c&&_0x3fa38c['subscribedPorts']['size']===0x0&&closeTaskStream(_0x1c66ab);},0x0);}function scheduleTaskReconnect(_0x4d0d7f){const _0x35ed83=taskStreams['get'](_0x4d0d7f);if(!_0x35ed83||_0x35ed83['subscribedPorts']['size']===0x0)return;_0x35ed83['reconnectTimeout']&&clearTimeout(_0x35ed83['reconnectTimeout']);const _0x1847ea=Math['min'](0x3e8*Math['pow'](0x2,_0x35ed83['reconnectAttempts']),MAX_RECONNECT_DELAY);_0x35ed83['reconnectAttempts']++,console['log']('[SSE\x20Worker]\x20Scheduling\x20task\x20stream\x20reconnect\x20for\x20'+_0x4d0d7f+'\x20in\x20'+_0x1847ea+'ms'),_0x35ed83['reconnectTimeout']=setTimeout(()=>{_0x35ed83['subscribedPorts']['size']>0x0&&connectTaskStream(_0x4d0d7f);},_0x1847ea);}function cleanUpDeadPorts(_0x26393b){for(const _0x18a02b of _0x26393b){ports['delete'](_0x18a02b),taskStreams['forEach']((_0x2bb808,_0x297daa)=>{_0x2bb808['subscribedPorts']['delete'](_0x18a02b),_0x2bb808['subscribedPorts']['size']===0x0&&closeTaskStream(_0x297daa);});}}function removePortFromAllTasks(_0x4d16d1){taskStreams['forEach']((_0x34a0d1,_0x5f01ee)=>{_0x34a0d1['subscribedPorts']['has'](_0x4d16d1)&&(_0x34a0d1['subscribedPorts']['delete'](_0x4d16d1),_0x34a0d1['subscribedPorts']['size']===0x0&&closeTaskStream(_0x5f01ee));});}self['onconnect']=function(_0x4c86fe){const _0x21c63a=_0x4c86fe['ports'][0x0];ports['add'](_0x21c63a),console['log']('[SSE\x20Worker]\x20New\x20port\x20connected.\x20Total\x20ports:\x20'+ports['size']),_0x21c63a['onmessage']=function(_0x5f0805){const {action:_0x5e8f33,userId:_0xd669d3,taskId:_0x26048e}=_0x5f0805['data'];switch(_0x5e8f33){case'connect':connect(_0xd669d3);eventSource&&eventSource['readyState']===EventSource['OPEN']&&_0x21c63a['postMessage']({'type':'connected'});break;case'disconnect':ports['delete'](_0x21c63a),removePortFromAllTasks(_0x21c63a),console['log']('[SSE\x20Worker]\x20Port\x20disconnected.\x20Total\x20ports:\x20'+ports['size']);ports['size']===0x0&&eventSource&&(eventSource['close'](),eventSource=null,reconnectTimeout&&(clearTimeout(reconnectTimeout),reconnectTimeout=null));break;case'changeFilter':_0xd669d3!==currentUserId&&connect(_0xd669d3);break;case'subscribeTask':subscribeTask(_0x21c63a,_0x26048e);break;case'unsubscribeTask':unsubscribeTask(_0x21c63a,_0x26048e);break;default:console['warn']('[SSE\x20Worker]\x20Unknown\x20action:',_0x5e8f33);}},_0x21c63a['onmessageerror']=function(_0xc0d028){console['error']('[SSE\x20Worker]\x20Port\x20message\x20error:',_0xc0d028),ports['delete'](_0x21c63a),removePortFromAllTasks(_0x21c63a);},_0x21c63a['start']();};
1
+ const ports=new Set();let eventSource=null,currentUserId=null,reconnectTimeout=null,reconnectAttempts=0x0;const MAX_RECONNECT_DELAY=0x7530,taskStreams=new Map(),TASK_STREAM_EVENTS=['activity','logs','metadata','summary','changed-files','app-server-status','complete'];function connect(_0x37b217){eventSource&&currentUserId!==_0x37b217&&(eventSource['close'](),eventSource=null);if(eventSource&&eventSource['readyState']!==EventSource['CLOSED'])return;currentUserId=_0x37b217;const _0xd524f5=_0x37b217&&_0x37b217!=='me'?'?userId='+_0x37b217:'';try{eventSource=new EventSource('/tasks/updates'+_0xd524f5),eventSource['addEventListener']('snapshot',_0x2077a9=>{broadcast({'type':'snapshot','data':_0x2077a9['data']}),reconnectAttempts=0x0;}),eventSource['addEventListener']('activity',_0x1565de=>{broadcast({'type':'activity','data':_0x1565de['data']});}),eventSource['addEventListener']('status',_0x5a5bf4=>{broadcast({'type':'status','data':_0x5a5bf4['data']});}),eventSource['addEventListener']('new-task',_0x55250d=>{broadcast({'type':'new-task','data':_0x55250d['data']});}),eventSource['addEventListener']('queue-position',_0x652393=>{broadcast({'type':'queue-position','data':_0x652393['data']});}),eventSource['addEventListener']('open',()=>{broadcast({'type':'connected'}),reconnectAttempts=0x0;}),eventSource['addEventListener']('error',_0x2cb5d5=>{console['error']('[SSE\x20Worker]\x20Connection\x20error:',_0x2cb5d5),broadcast({'type':'error','error':'Connection\x20error'}),eventSource&&(eventSource['close'](),eventSource=null),scheduleReconnect();});}catch(_0x1a6f21){console['error']('[SSE\x20Worker]\x20Failed\x20to\x20create\x20EventSource:',_0x1a6f21),broadcast({'type':'error','error':_0x1a6f21['message']}),scheduleReconnect();}}function scheduleReconnect(){reconnectTimeout&&clearTimeout(reconnectTimeout);if(ports['size']===0x0)return;const _0x1c03e2=Math['min'](0x3e8*Math['pow'](0x2,reconnectAttempts),MAX_RECONNECT_DELAY);reconnectAttempts++,console['log']('[SSE\x20Worker]\x20Scheduling\x20reconnect\x20in\x20'+_0x1c03e2+'ms\x20(attempt\x20'+reconnectAttempts+')'),reconnectTimeout=setTimeout(()=>{ports['size']>0x0&&connect(currentUserId);},_0x1c03e2);}function broadcast(_0x2421ae){const _0x39c7a0=[];ports['forEach'](_0xcba3b6=>{try{_0xcba3b6['postMessage'](_0x2421ae);}catch(_0x376447){console['warn']('[SSE\x20Worker]\x20Failed\x20to\x20send\x20to\x20port,\x20removing:',_0x376447),_0x39c7a0['push'](_0xcba3b6);}}),_0x39c7a0['length']>0x0&&cleanUpDeadPorts(_0x39c7a0),ports['size']===0x0&&eventSource&&(console['log']('[SSE\x20Worker]\x20No\x20more\x20connected\x20ports,\x20closing\x20SSE'),eventSource['close'](),eventSource=null,reconnectTimeout&&(clearTimeout(reconnectTimeout),reconnectTimeout=null));}function subscribeTask(_0x4869a6,_0x5f10c3){let _0x17d2a2=taskStreams['get'](_0x5f10c3);!_0x17d2a2&&(_0x17d2a2={'eventSource':null,'reconnectTimeout':null,'reconnectAttempts':0x0,'subscribedPorts':new Set()},taskStreams['set'](_0x5f10c3,_0x17d2a2));_0x17d2a2['subscribedPorts']['add'](_0x4869a6);if(!_0x17d2a2['eventSource']||_0x17d2a2['eventSource']['readyState']===EventSource['CLOSED'])connectTaskStream(_0x5f10c3);else{if(_0x17d2a2['eventSource']['readyState']===EventSource['OPEN'])try{_0x4869a6['postMessage']({'type':'task:connected','taskId':_0x5f10c3});}catch(_0x199639){}}}function unsubscribeTask(_0x513b43,_0x2445e3){const _0x1c52e=taskStreams['get'](_0x2445e3);if(!_0x1c52e)return;_0x1c52e['subscribedPorts']['delete'](_0x513b43),_0x1c52e['subscribedPorts']['size']===0x0&&deferredCloseTaskStream(_0x2445e3);}function connectTaskStream(_0x85aa28){const _0x3962af=taskStreams['get'](_0x85aa28);if(!_0x3962af)return;_0x3962af['eventSource']&&(_0x3962af['eventSource']['close'](),_0x3962af['eventSource']=null);try{_0x3962af['eventSource']=new EventSource('/tasks/'+_0x85aa28+'/stream');for(const _0x3ad138 of TASK_STREAM_EVENTS){_0x3962af['eventSource']['addEventListener'](_0x3ad138,_0x5d935b=>{broadcastToTask(_0x85aa28,'task:'+_0x3ad138,_0x5d935b['data']),_0x3962af['reconnectAttempts']=0x0;});}_0x3962af['eventSource']['addEventListener']('open',()=>{broadcastToTask(_0x85aa28,'task:connected','{}'),_0x3962af['reconnectAttempts']=0x0;}),_0x3962af['eventSource']['addEventListener']('error',()=>{broadcastToTask(_0x85aa28,'task:error',JSON['stringify']({'error':'Connection\x20error'})),_0x3962af['eventSource']&&(_0x3962af['eventSource']['close'](),_0x3962af['eventSource']=null),scheduleTaskReconnect(_0x85aa28);});}catch(_0x53ae53){console['error']('[SSE\x20Worker]\x20Failed\x20to\x20create\x20task\x20EventSource\x20for\x20'+_0x85aa28+':',_0x53ae53),broadcastToTask(_0x85aa28,'task:error',JSON['stringify']({'error':_0x53ae53['message']})),scheduleTaskReconnect(_0x85aa28);}}function broadcastToTask(_0x4ac2fc,_0x2f974f,_0x16a8fe){const _0x36b544=taskStreams['get'](_0x4ac2fc);if(!_0x36b544)return;const _0x3589b7=[];_0x36b544['subscribedPorts']['forEach'](_0xe65e=>{try{_0xe65e['postMessage']({'type':_0x2f974f,'taskId':_0x4ac2fc,'data':_0x16a8fe});}catch(_0x58f93c){_0x3589b7['push'](_0xe65e);}}),_0x3589b7['length']>0x0&&(_0x3589b7['forEach'](_0x47093b=>_0x36b544['subscribedPorts']['delete'](_0x47093b)),cleanUpDeadPorts(_0x3589b7),_0x36b544['subscribedPorts']['size']===0x0&&closeTaskStream(_0x4ac2fc));}function closeTaskStream(_0x28444f){const _0x1a727a=taskStreams['get'](_0x28444f);if(!_0x1a727a)return;_0x1a727a['eventSource']&&_0x1a727a['eventSource']['close'](),_0x1a727a['reconnectTimeout']&&clearTimeout(_0x1a727a['reconnectTimeout']),taskStreams['delete'](_0x28444f);}function deferredCloseTaskStream(_0x709df3){setTimeout(()=>{const _0x5448cd=taskStreams['get'](_0x709df3);_0x5448cd&&_0x5448cd['subscribedPorts']['size']===0x0&&closeTaskStream(_0x709df3);},0x0);}function scheduleTaskReconnect(_0x1e3659){const _0x4bf5b8=taskStreams['get'](_0x1e3659);if(!_0x4bf5b8||_0x4bf5b8['subscribedPorts']['size']===0x0)return;_0x4bf5b8['reconnectTimeout']&&clearTimeout(_0x4bf5b8['reconnectTimeout']);const _0x4db93c=Math['min'](0x3e8*Math['pow'](0x2,_0x4bf5b8['reconnectAttempts']),MAX_RECONNECT_DELAY);_0x4bf5b8['reconnectAttempts']++,console['log']('[SSE\x20Worker]\x20Scheduling\x20task\x20stream\x20reconnect\x20for\x20'+_0x1e3659+'\x20in\x20'+_0x4db93c+'ms'),_0x4bf5b8['reconnectTimeout']=setTimeout(()=>{_0x4bf5b8['subscribedPorts']['size']>0x0&&connectTaskStream(_0x1e3659);},_0x4db93c);}function cleanUpDeadPorts(_0x393d57){for(const _0x15b3b1 of _0x393d57){ports['delete'](_0x15b3b1),taskStreams['forEach']((_0x653911,_0x1f1a0f)=>{_0x653911['subscribedPorts']['delete'](_0x15b3b1),_0x653911['subscribedPorts']['size']===0x0&&closeTaskStream(_0x1f1a0f);});}}function removePortFromAllTasks(_0x3a0f66){taskStreams['forEach']((_0x29dcd9,_0x1e27e1)=>{_0x29dcd9['subscribedPorts']['has'](_0x3a0f66)&&(_0x29dcd9['subscribedPorts']['delete'](_0x3a0f66),_0x29dcd9['subscribedPorts']['size']===0x0&&closeTaskStream(_0x1e27e1));});}self['onconnect']=function(_0x42c311){const _0x1ca17f=_0x42c311['ports'][0x0];ports['add'](_0x1ca17f),console['log']('[SSE\x20Worker]\x20New\x20port\x20connected.\x20Total\x20ports:\x20'+ports['size']),_0x1ca17f['onmessage']=function(_0x5a60a9){const {action:_0x27942,userId:_0x101f8c,taskId:_0x290089}=_0x5a60a9['data'];switch(_0x27942){case'connect':connect(_0x101f8c);eventSource&&eventSource['readyState']===EventSource['OPEN']&&_0x1ca17f['postMessage']({'type':'connected'});break;case'disconnect':ports['delete'](_0x1ca17f),removePortFromAllTasks(_0x1ca17f),console['log']('[SSE\x20Worker]\x20Port\x20disconnected.\x20Total\x20ports:\x20'+ports['size']);ports['size']===0x0&&eventSource&&(eventSource['close'](),eventSource=null,reconnectTimeout&&(clearTimeout(reconnectTimeout),reconnectTimeout=null));break;case'changeFilter':_0x101f8c!==currentUserId&&connect(_0x101f8c);break;case'subscribeTask':subscribeTask(_0x1ca17f,_0x290089);break;case'unsubscribeTask':unsubscribeTask(_0x1ca17f,_0x290089);break;default:console['warn']('[SSE\x20Worker]\x20Unknown\x20action:',_0x27942);}},_0x1ca17f['onmessageerror']=function(_0x3e7398){console['error']('[SSE\x20Worker]\x20Port\x20message\x20error:',_0x3e7398),ports['delete'](_0x1ca17f),removePortFromAllTasks(_0x1ca17f);},_0x1ca17f['start']();};
@@ -13405,10 +13405,19 @@ input.toggle-switch:focus {
13405
13405
  stroke: #4285f4; /* Google Blue for Gemini */
13406
13406
  }
13407
13407
 
13408
+ .icon-bob {
13409
+ stroke: #6366f1; /* Indigo for Bob */
13410
+ }
13411
+
13408
13412
  .icon-terminal {
13409
13413
  stroke: #64748b; /* Gray for terminal */
13410
13414
  }
13411
13415
 
13416
+ .icon-vscode {
13417
+ color: #007acc; /* VS Code blue */
13418
+ stroke: none;
13419
+ }
13420
+
13412
13421
  .quick-action-item:hover .icon-branch {
13413
13422
  stroke: #7d3c98;
13414
13423
  }
@@ -13433,10 +13442,18 @@ input.toggle-switch:focus {
13433
13442
  stroke: #1a73e8;
13434
13443
  }
13435
13444
 
13445
+ .quick-action-item:hover .icon-bob {
13446
+ stroke: #4f46e5;
13447
+ }
13448
+
13436
13449
  .quick-action-item:hover .icon-terminal {
13437
13450
  stroke: #475569;
13438
13451
  }
13439
13452
 
13453
+ .quick-action-item:hover .icon-vscode {
13454
+ color: #005a9e;
13455
+ }
13456
+
13440
13457
  /* Task Page Menu Styles */
13441
13458
  #terminal-dropdown-menu {
13442
13459
  min-width: 240px;
@@ -13513,6 +13530,10 @@ input.toggle-switch:focus {
13513
13530
  stroke: #4285f4; /* Google Blue for Gemini */
13514
13531
  }
13515
13532
 
13533
+ .icon-bob-session {
13534
+ stroke: #6366f1; /* Indigo for Bob */
13535
+ }
13536
+
13516
13537
  /* Hover states for task menu icons */
13517
13538
  .task-menu-item:hover .icon-play {
13518
13539
  stroke: #248a5f;
@@ -13562,6 +13583,10 @@ input.toggle-switch:focus {
13562
13583
  stroke: #1a73e8;
13563
13584
  }
13564
13585
 
13586
+ .task-menu-item:hover .icon-bob-session {
13587
+ stroke: #4f46e5;
13588
+ }
13589
+
13565
13590
  /* Server Health Modal Styles */
13566
13591
  .health-metrics {
13567
13592
  display: grid;
@@ -1 +1 @@
1
- export function toDisplayAgentName(_0x19b876,{fallback:fallback='Unknown'}={}){const _0x30406f=String(_0x19b876||'')['trim']()['toLowerCase']();if(!_0x30406f)return fallback;return _0x30406f['charAt'](0x0)['toUpperCase']()+_0x30406f['slice'](0x1);}export function escapeRegExp(_0x44969c){return String(_0x44969c)['replace'](/[.*+?^${}()|[\]\\]/g,'\x5c$&');}export function compareJudgmentsForAliasOrder(_0x4a74b9,_0x538af2){const _0x19816a=String(_0x4a74b9?.['createdAt']||''),_0x289879=String(_0x538af2?.['createdAt']||'');if(_0x19816a!==_0x289879)return _0x19816a['localeCompare'](_0x289879);return String(_0x4a74b9?.['taskId']||'')['localeCompare'](String(_0x538af2?.['taskId']||''));}export function parseJudgeAliasNumber(_0x26475b,_0x461ccc){const _0x34026d=typeof _0x26475b==='string'?_0x26475b['trim']():'',_0xd2c0af=toDisplayAgentName(_0x461ccc,{'fallback':''});if(!_0x34026d||!_0xd2c0af)return null;const _0x90a0de=_0x34026d['toLowerCase'](),_0x1cbb50=_0xd2c0af['toLowerCase']();if(_0x90a0de===_0x1cbb50||_0x90a0de===_0x1cbb50+'\x20judge')return 0x1;const _0x37473f=[new RegExp('^'+escapeRegExp(_0xd2c0af)+'\x5cs+(\x5cd+)$','i'),new RegExp('^'+escapeRegExp(_0xd2c0af)+'\x5cs+Judge\x5cs+(\x5cd+)$','i')];for(const _0x315738 of _0x37473f){const _0x53ff32=_0x34026d['match'](_0x315738);if(_0x53ff32){const _0x14c868=Number(_0x53ff32[0x1]);if(Number['isInteger'](_0x14c868)&&_0x14c868>0x0)return _0x14c868;}}return null;}export function formatJudgeDisplayName({alias:_0x1c25c7,agent:_0x462478,number:number=null,hasDuplicates:hasDuplicates=![]}={}){const _0x2504e1=toDisplayAgentName(_0x462478,{'fallback':'Judge'}),_0x5d9648=typeof _0x1c25c7==='string'?_0x1c25c7['trim']():'';if(Number['isInteger'](number)&&number>0x0)return _0x2504e1+'\x20Judge\x20'+number;if(_0x5d9648)return/\bjudge\b/i['test'](_0x5d9648)?_0x5d9648:_0x5d9648+'\x20Judge';if(hasDuplicates)return _0x2504e1+'\x20Judge';return _0x2504e1==='Judge'?_0x2504e1:_0x2504e1+'\x20Judge';}export function buildJudgmentDisplayNameMap(_0x5cc408=[]){const _0x28c9fa=Array['isArray'](_0x5cc408)?_0x5cc408['filter'](Boolean):[],_0x1b6465=new Map();_0x28c9fa['forEach'](_0x1a2f4b=>{const _0x4175cb=_0x1a2f4b?.['judgeAgent']||_0x1a2f4b?.['envVars']?.['CODER_AGENT']||'unknown',_0x4f5a85=String(_0x4175cb||'')['trim']()['toLowerCase']()||'unknown';!_0x1b6465['has'](_0x4f5a85)&&_0x1b6465['set'](_0x4f5a85,[]),_0x1b6465['get'](_0x4f5a85)['push'](_0x1a2f4b);});const _0x38f0a7=new Map();return _0x1b6465['forEach'](_0x279a4f=>{const _0x15a3fb=[..._0x279a4f]['sort'](compareJudgmentsForAliasOrder),_0x10d000=_0x15a3fb['length']>0x1,_0x4ed0e7=new Set(),_0x134e94=new Map();_0x10d000&&_0x15a3fb['forEach'](_0x7f16f8=>{const _0x317f0e=parseJudgeAliasNumber(_0x7f16f8?.['judgeAlias'],_0x7f16f8?.['judgeAgent']);if(!Number['isInteger'](_0x317f0e)||_0x317f0e<=0x0||_0x4ed0e7['has'](_0x317f0e))return;_0x134e94['set'](_0x7f16f8['taskId'],_0x317f0e),_0x4ed0e7['add'](_0x317f0e);});let _0x4acc0a=0x1;const _0x45e178=()=>{while(_0x4ed0e7['has'](_0x4acc0a)){_0x4acc0a+=0x1;}return _0x4ed0e7['add'](_0x4acc0a),_0x4acc0a;};_0x15a3fb['forEach'](_0x3656dd=>{let _0x413394=_0x134e94['get'](_0x3656dd['taskId'])||null;_0x10d000&&_0x413394===null&&!String(_0x3656dd?.['judgeAlias']||'')['trim']()&&(_0x413394=_0x45e178()),_0x38f0a7['set'](_0x3656dd['taskId'],formatJudgeDisplayName({'alias':_0x3656dd?.['judgeAlias']||null,'agent':_0x3656dd?.['judgeAgent']||_0x3656dd?.['envVars']?.['CODER_AGENT']||'unknown','number':_0x413394,'hasDuplicates':_0x10d000}));});}),_0x38f0a7;}export function buildTaskNavigationHref(_0x3c6327,{currentUrl:_0x8801c0,groupedTaskIds:groupedTaskIds=[],groupId:groupId=null}={}){const _0x1a14ac=new URL(_0x8801c0),_0x16dcb3=String(_0x3c6327||'')['trim'](),_0x123686=String(groupId||'')['trim'](),_0xe061e9=Array['isArray'](groupedTaskIds)?groupedTaskIds['map'](_0x12aa04=>String(_0x12aa04||'')['trim']())['filter'](Boolean):[],_0x39f943=Boolean(_0x123686)||_0xe061e9['length']>0x1;if(!_0x39f943)return _0x16dcb3&&_0x1a14ac['searchParams']['set']('id',_0x16dcb3),_0x1a14ac['searchParams']['delete']('groupId'),_0x1a14ac['toString']();const _0x2ffe7e=_0xe061e9['includes'](_0x16dcb3)?_0xe061e9:[..._0xe061e9,_0x16dcb3]['filter'](Boolean);if(_0x2ffe7e['length']>0x0)_0x1a14ac['searchParams']['set']('id',_0x2ffe7e['join'](','));else _0x16dcb3&&_0x1a14ac['searchParams']['set']('id',_0x16dcb3);return _0x123686?_0x1a14ac['searchParams']['set']('groupId',_0x123686):_0x1a14ac['searchParams']['delete']('groupId'),_0x1a14ac['toString']();}
1
+ export function toDisplayAgentName(_0x5a8109,{fallback:fallback='Unknown'}={}){const _0x3411ea=String(_0x5a8109||'')['trim']()['toLowerCase']();if(!_0x3411ea)return fallback;return _0x3411ea['charAt'](0x0)['toUpperCase']()+_0x3411ea['slice'](0x1);}export function escapeRegExp(_0x55a411){return String(_0x55a411)['replace'](/[.*+?^${}()|[\]\\]/g,'\x5c$&');}export function compareJudgmentsForAliasOrder(_0x59e4ba,_0x317b1a){const _0x331772=String(_0x59e4ba?.['createdAt']||''),_0x50e8ea=String(_0x317b1a?.['createdAt']||'');if(_0x331772!==_0x50e8ea)return _0x331772['localeCompare'](_0x50e8ea);return String(_0x59e4ba?.['taskId']||'')['localeCompare'](String(_0x317b1a?.['taskId']||''));}export function parseJudgeAliasNumber(_0x2bddd2,_0x5e458e){const _0x199f57=typeof _0x2bddd2==='string'?_0x2bddd2['trim']():'',_0x4b27fb=toDisplayAgentName(_0x5e458e,{'fallback':''});if(!_0x199f57||!_0x4b27fb)return null;const _0x3a908f=_0x199f57['toLowerCase'](),_0x103398=_0x4b27fb['toLowerCase']();if(_0x3a908f===_0x103398||_0x3a908f===_0x103398+'\x20judge')return 0x1;const _0xdccb08=[new RegExp('^'+escapeRegExp(_0x4b27fb)+'\x5cs+(\x5cd+)$','i'),new RegExp('^'+escapeRegExp(_0x4b27fb)+'\x5cs+Judge\x5cs+(\x5cd+)$','i')];for(const _0x2f9f14 of _0xdccb08){const _0x4feb5a=_0x199f57['match'](_0x2f9f14);if(_0x4feb5a){const _0x44eca7=Number(_0x4feb5a[0x1]);if(Number['isInteger'](_0x44eca7)&&_0x44eca7>0x0)return _0x44eca7;}}return null;}export function formatJudgeDisplayName({alias:_0x693db5,agent:_0x5a9e87,number:number=null,hasDuplicates:hasDuplicates=![]}={}){const _0x5dce40=toDisplayAgentName(_0x5a9e87,{'fallback':'Judge'}),_0x537d83=typeof _0x693db5==='string'?_0x693db5['trim']():'';if(Number['isInteger'](number)&&number>0x0)return _0x5dce40+'\x20Judge\x20'+number;if(_0x537d83)return/\bjudge\b/i['test'](_0x537d83)?_0x537d83:_0x537d83+'\x20Judge';if(hasDuplicates)return _0x5dce40+'\x20Judge';return _0x5dce40==='Judge'?_0x5dce40:_0x5dce40+'\x20Judge';}export function buildJudgmentDisplayNameMap(_0x380e8d=[]){const _0x10eeaf=Array['isArray'](_0x380e8d)?_0x380e8d['filter'](Boolean):[],_0x428c7a=new Map();_0x10eeaf['forEach'](_0x15b958=>{const _0x25a8ca=_0x15b958?.['judgeAgent']||_0x15b958?.['envVars']?.['CODER_AGENT']||'unknown',_0x4a2447=String(_0x25a8ca||'')['trim']()['toLowerCase']()||'unknown';!_0x428c7a['has'](_0x4a2447)&&_0x428c7a['set'](_0x4a2447,[]),_0x428c7a['get'](_0x4a2447)['push'](_0x15b958);});const _0x574e89=new Map();return _0x428c7a['forEach'](_0x5ec02e=>{const _0x505783=[..._0x5ec02e]['sort'](compareJudgmentsForAliasOrder),_0x6c3c1b=_0x505783['length']>0x1,_0x3ea1e0=new Set(),_0x3de7cc=new Map();_0x6c3c1b&&_0x505783['forEach'](_0x504f57=>{const _0x245fc2=parseJudgeAliasNumber(_0x504f57?.['judgeAlias'],_0x504f57?.['judgeAgent']);if(!Number['isInteger'](_0x245fc2)||_0x245fc2<=0x0||_0x3ea1e0['has'](_0x245fc2))return;_0x3de7cc['set'](_0x504f57['taskId'],_0x245fc2),_0x3ea1e0['add'](_0x245fc2);});let _0x366dac=0x1;const _0x4fff51=()=>{while(_0x3ea1e0['has'](_0x366dac)){_0x366dac+=0x1;}return _0x3ea1e0['add'](_0x366dac),_0x366dac;};_0x505783['forEach'](_0x869217=>{let _0x1ae5a3=_0x3de7cc['get'](_0x869217['taskId'])||null;_0x6c3c1b&&_0x1ae5a3===null&&!String(_0x869217?.['judgeAlias']||'')['trim']()&&(_0x1ae5a3=_0x4fff51()),_0x574e89['set'](_0x869217['taskId'],formatJudgeDisplayName({'alias':_0x869217?.['judgeAlias']||null,'agent':_0x869217?.['judgeAgent']||_0x869217?.['envVars']?.['CODER_AGENT']||'unknown','number':_0x1ae5a3,'hasDuplicates':_0x6c3c1b}));});}),_0x574e89;}export function buildTaskNavigationHref(_0x2838e9,{currentUrl:_0x43fafd,groupedTaskIds:groupedTaskIds=[],groupId:groupId=null}={}){const _0x20246b=new URL(_0x43fafd),_0x2579d9=String(_0x2838e9||'')['trim'](),_0x5ece20=String(groupId||'')['trim'](),_0x127957=Array['isArray'](groupedTaskIds)?groupedTaskIds['map'](_0xe6c73e=>String(_0xe6c73e||'')['trim']())['filter'](Boolean):[],_0x32cea3=Boolean(_0x5ece20)||_0x127957['length']>0x1;if(!_0x32cea3)return _0x2579d9&&_0x20246b['searchParams']['set']('id',_0x2579d9),_0x20246b['searchParams']['delete']('groupId'),_0x20246b['toString']();const _0x146fe3=_0x127957['includes'](_0x2579d9)?_0x127957:[..._0x127957,_0x2579d9]['filter'](Boolean);if(_0x146fe3['length']>0x0)_0x20246b['searchParams']['set']('id',_0x146fe3['join'](','));else _0x2579d9&&_0x20246b['searchParams']['set']('id',_0x2579d9);return _0x5ece20?_0x20246b['searchParams']['set']('groupId',_0x5ece20):_0x20246b['searchParams']['delete']('groupId'),_0x20246b['toString']();}
@@ -39,7 +39,7 @@
39
39
  <script type="module" src="markdown-editor.js?v=2"></script>
40
40
  <script src="markdown-file-editor.js?v=2"></script>
41
41
  <script type="module" src="comments-widget.js?v=2"></script>
42
- <script type="module" src="task.js?v=79"></script>
42
+ <script type="module" src="task.js?v=80"></script>
43
43
  <!-- Dev QA shortcut: Ctrl+Shift+Q to launch current page in QA mode -->
44
44
  <style>
45
45
  .agent-card.agent-disabled {
@@ -455,6 +455,20 @@
455
455
  </svg>
456
456
  <span class="option-text">New Gemini Session</span>
457
457
  </button>
458
+ <button class="dropdown-item task-menu-item" data-action="new-bob">
459
+ <svg class="option-icon icon-bob-session" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round">
460
+ <rect x="3.5" y="10.5" width="17" height="12" rx="3"></rect>
461
+ <circle cx="9" cy="15.5" r="2" fill="currentColor" stroke="none"></circle>
462
+ <circle cx="15" cy="15.5" r="2" fill="currentColor" stroke="none"></circle>
463
+ <path d="M10 20q2 1.2 4 0"></path>
464
+ <path d="M3.5 14.5a1.5 1.5 0 0 0 0 3"></path>
465
+ <path d="M20.5 14.5a1.5 1.5 0 0 1 0 3"></path>
466
+ <path d="M2 10.5h20" stroke-width="2.5"></path>
467
+ <path d="M5 10.5V8c0-3 3.2-5.5 7-5.5s7 2.5 7 5.5v2.5"></path>
468
+ <path d="M5 7.5h14" stroke-width="1.2"></path>
469
+ </svg>
470
+ <span class="option-text">New Bob Shell Session</span>
471
+ </button>
458
472
  </div>
459
473
  </div>
460
474
  <button class="btn-warning btn-small" id="stop-task" disabled hidden>Interrupt</button>