@profoundlogic/coderflow-server 0.7.4 → 0.7.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (179) hide show
  1. package/dist/coder-server.js +1 -1
  2. package/dist/config.js +1 -1
  3. package/dist/lib/agent-keepalive.js +1 -1
  4. package/dist/lib/agent-models.js +1 -1
  5. package/dist/lib/api-keys.js +1 -1
  6. package/dist/lib/apiKeys.js +1 -1
  7. package/dist/lib/app-server-ports.js +1 -1
  8. package/dist/lib/auto-judge.js +1 -1
  9. package/dist/lib/automation-service.js +1 -1
  10. package/dist/lib/basic-auth.js +1 -1
  11. package/dist/lib/bindings.js +1 -1
  12. package/dist/lib/build-history.js +1 -1
  13. package/dist/lib/build-output-service.js +1 -1
  14. package/dist/lib/build-scheduler.js +1 -1
  15. package/dist/lib/build-service.js +1 -1
  16. package/dist/lib/ca-certificates.js +1 -1
  17. package/dist/lib/claude-oauth-refresh.js +1 -1
  18. package/dist/lib/cli/build.js +1 -1
  19. package/dist/lib/cli/cleanup-users.js +1 -1
  20. package/dist/lib/cli/config-command.js +1 -1
  21. package/dist/lib/cli/config.js +1 -1
  22. package/dist/lib/cli/create-user.js +1 -1
  23. package/dist/lib/cli/grant-admin.js +1 -1
  24. package/dist/lib/cli/init.js +1 -1
  25. package/dist/lib/cli/jira.js +1 -1
  26. package/dist/lib/cli/license.js +1 -1
  27. package/dist/lib/cli/list-roles.js +1 -1
  28. package/dist/lib/cli/list-users.js +1 -1
  29. package/dist/lib/cli/server-manager.js +1 -1
  30. package/dist/lib/cli/set-password.js +1 -1
  31. package/dist/lib/config-migration.js +1 -1
  32. package/dist/lib/container-credential-sync.js +1 -1
  33. package/dist/lib/container-tokens.js +1 -1
  34. package/dist/lib/data-dir.js +1 -1
  35. package/dist/lib/deployment-history.js +1 -1
  36. package/dist/lib/deployment-service.js +1 -1
  37. package/dist/lib/docker-utils.js +1 -1
  38. package/dist/lib/email.js +1 -1
  39. package/dist/lib/emailTemplates.js +1 -1
  40. package/dist/lib/entitlement.js +1 -1
  41. package/dist/lib/external-connections.js +1 -1
  42. package/dist/lib/fetch-utils.js +1 -1
  43. package/dist/lib/git-commit-details-route.js +1 -1
  44. package/dist/lib/git-history-diff-guardrails.js +1 -1
  45. package/dist/lib/git-provider-service.js +1 -1
  46. package/dist/lib/git-provider-setup/github-setup-handler.js +1 -1
  47. package/dist/lib/git-provider-setup/index.js +1 -1
  48. package/dist/lib/git-provider-setup/setup-factory.js +1 -1
  49. package/dist/lib/git-provider-setup/setup-interface.js +1 -1
  50. package/dist/lib/git-providers/azure-devops-provider.js +1 -1
  51. package/dist/lib/git-providers/github-app-provider.js +1 -1
  52. package/dist/lib/git-providers/index.js +1 -1
  53. package/dist/lib/git-providers/provider-factory.js +1 -1
  54. package/dist/lib/git-providers/provider-interface.js +1 -1
  55. package/dist/lib/github-urls.js +1 -1
  56. package/dist/lib/group-objective-linking.js +1 -1
  57. package/dist/lib/ibmi-sync.js +1 -1
  58. package/dist/lib/jira-client.js +1 -1
  59. package/dist/lib/judge-blinding.js +1 -1
  60. package/dist/lib/logger.js +1 -1
  61. package/dist/lib/memory-utils.js +1 -1
  62. package/dist/lib/migration-to-scoped-rbac.js +1 -1
  63. package/dist/lib/model-fetcher.js +1 -1
  64. package/dist/lib/notifications.js +1 -1
  65. package/dist/lib/objective-context.js +1 -1
  66. package/dist/lib/oidc-auth.js +1 -1
  67. package/dist/lib/oidc-device-flow.js +1 -1
  68. package/dist/lib/passwordTokens.js +1 -1
  69. package/dist/lib/permission-resolver.js +1 -1
  70. package/dist/lib/pin-cascade.js +1 -1
  71. package/dist/lib/provider-accounts.js +1 -1
  72. package/dist/lib/provider-oauth.js +1 -1
  73. package/dist/lib/provider-profile.js +1 -1
  74. package/dist/lib/provider-token-refresh.js +1 -1
  75. package/dist/lib/rbac-user-state.js +1 -1
  76. package/dist/lib/request-url.js +1 -1
  77. package/dist/lib/rewind.js +1 -1
  78. package/dist/lib/role-definitions.js +1 -1
  79. package/dist/lib/roles.js +1 -1
  80. package/dist/lib/secrets.js +1 -1
  81. package/dist/lib/setup-repo-git-auth.js +1 -1
  82. package/dist/lib/state-capture.js +1 -1
  83. package/dist/lib/static-files.js +1 -1
  84. package/dist/lib/task-aliases.js +1 -1
  85. package/dist/lib/task-name-format.js +1 -1
  86. package/dist/lib/task-name-generator.js +1 -1
  87. package/dist/lib/task-source-metadata.js +1 -1
  88. package/dist/lib/teams.js +1 -1
  89. package/dist/lib/user-git-oauth.js +1 -1
  90. package/dist/lib/user-git-tokens.js +1 -1
  91. package/dist/lib/users.js +1 -1
  92. package/dist/middleware/requireAuth.js +1 -1
  93. package/dist/middleware/requireInit.js +1 -1
  94. package/dist/middleware/requirePermission.js +1 -1
  95. package/dist/package.json +1 -1
  96. package/dist/playwright.config.js +1 -1
  97. package/dist/playwright.task-terminal.config.js +1 -1
  98. package/dist/routes/apiKeys.js +1 -1
  99. package/dist/routes/auth-oidc.js +1 -1
  100. package/dist/routes/auth.js +1 -1
  101. package/dist/routes/automations.js +1 -1
  102. package/dist/routes/bindings.js +1 -1
  103. package/dist/routes/build.js +1 -1
  104. package/dist/routes/containers.js +1 -1
  105. package/dist/routes/deploy-task.js +1 -1
  106. package/dist/routes/environment-management.js +1 -1
  107. package/dist/routes/environments.js +1 -1
  108. package/dist/routes/external-skills.js +1 -1
  109. package/dist/routes/git-credentials.js +1 -1
  110. package/dist/routes/git-oauth.js +1 -1
  111. package/dist/routes/git-provider-setup.js +1 -1
  112. package/dist/routes/health.js +1 -1
  113. package/dist/routes/jira.js +1 -1
  114. package/dist/routes/objective-management.js +1 -1
  115. package/dist/routes/password.js +1 -1
  116. package/dist/routes/prompt.js +1 -1
  117. package/dist/routes/provider-auth.js +1 -1
  118. package/dist/routes/qa.js +1 -1
  119. package/dist/routes/roles.js +1 -1
  120. package/dist/routes/settings.js +1 -1
  121. package/dist/routes/skill-management.js +1 -1
  122. package/dist/routes/skills.js +1 -1
  123. package/dist/routes/tasks.js +1 -1
  124. package/dist/routes/teams.js +1 -1
  125. package/dist/routes/templates.js +1 -1
  126. package/dist/routes/test-task.js +1 -1
  127. package/dist/routes/test.js +1 -1
  128. package/dist/routes/users.js +1 -1
  129. package/dist/routes/visualizations.js +1 -1
  130. package/dist/scripts/create-user.js +1 -1
  131. package/dist/scripts/migrate-config-to-data-dir.js +1 -1
  132. package/dist/shipped-skills/environment-templates/SKILL.md +152 -17
  133. package/dist/start.js +1 -1
  134. package/dist/web-ui/public/activity-detail-modal.js +1 -1
  135. package/dist/web-ui/public/activity-feed.js +1 -1
  136. package/dist/web-ui/public/activity-formatters.js +1 -1
  137. package/dist/web-ui/public/agent-event-parser.js +1 -1
  138. package/dist/web-ui/public/app.js +1 -1
  139. package/dist/web-ui/public/approve-dialog.js +1 -1
  140. package/dist/web-ui/public/automation-links.js +1 -1
  141. package/dist/web-ui/public/automation-schedule.js +1 -1
  142. package/dist/web-ui/public/comments-widget.js +1 -1
  143. package/dist/web-ui/public/diff-utils.js +1 -1
  144. package/dist/web-ui/public/docs/admin/ai-providers.md +5 -5
  145. package/dist/web-ui/public/environments.js +1 -1
  146. package/dist/web-ui/public/feedback-widget.css +21 -5
  147. package/dist/web-ui/public/feedback-widget.js +1 -1
  148. package/dist/web-ui/public/file-selection-tree.js +1 -1
  149. package/dist/web-ui/public/git-history-lazy-utils.js +1 -1
  150. package/dist/web-ui/public/git-history.js +1 -1
  151. package/dist/web-ui/public/git-status.js +1 -1
  152. package/dist/web-ui/public/ibmi-file-filter.js +1 -1
  153. package/dist/web-ui/public/index.html +20 -0
  154. package/dist/web-ui/public/index.js +1 -1
  155. package/dist/web-ui/public/login.js +1 -1
  156. package/dist/web-ui/public/markdown-editor.js +1 -1
  157. package/dist/web-ui/public/markdown-file-editor.js +1 -1
  158. package/dist/web-ui/public/modal-maximize.js +1 -1
  159. package/dist/web-ui/public/notifications.js +1 -1
  160. package/dist/web-ui/public/permissions.js +1 -1
  161. package/dist/web-ui/public/pr-dialog.js +1 -1
  162. package/dist/web-ui/public/roles.js +1 -1
  163. package/dist/web-ui/public/server-health.js +1 -1
  164. package/dist/web-ui/public/settings.html +1 -1
  165. package/dist/web-ui/public/settings.js +1 -1
  166. package/dist/web-ui/public/setup-password.js +1 -1
  167. package/dist/web-ui/public/skills.js +1 -1
  168. package/dist/web-ui/public/sse-client.js +1 -1
  169. package/dist/web-ui/public/sse-shared-worker.js +1 -1
  170. package/dist/web-ui/public/styles.css +25 -0
  171. package/dist/web-ui/public/task-judging-helpers.js +1 -1
  172. package/dist/web-ui/public/task.html +15 -1
  173. package/dist/web-ui/public/task.js +1 -1
  174. package/dist/web-ui/public/teams.js +1 -1
  175. package/dist/web-ui/public/terminal.js +1 -1
  176. package/dist/web-ui/public/theme.js +1 -1
  177. package/dist/web-ui/public/users.js +1 -1
  178. package/dist/web-ui/public/variant-grouping.js +1 -1
  179. package/package.json +1 -1
@@ -1 +1 @@
1
- function isSharedWorkerSupported(){return typeof SharedWorker!=='undefined';}function eventTypeToHandler(_0x4b7f81){if(_0x4b7f81==='connected')return'onConnected';if(_0x4b7f81==='error')return'onError';return'on'+_0x4b7f81['split']('-')['map'](_0x15d767=>_0x15d767['charAt'](0x0)['toUpperCase']()+_0x15d767['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'](_0x4920f7,_0x4df677){return!this['listeners']['has'](_0x4920f7)&&this['listeners']['set'](_0x4920f7,new Set()),this['listeners']['get'](_0x4920f7)['add'](_0x4df677),this;}['off'](_0x12bc1f,_0x52de97){return this['listeners']['has'](_0x12bc1f)&&this['listeners']['get'](_0x12bc1f)['delete'](_0x52de97),this;}['_emit'](_0x4c7bac,_0x153f69){this['listeners']['has'](_0x4c7bac)&&this['listeners']['get'](_0x4c7bac)['forEach'](_0x122262=>{try{_0x122262(_0x153f69);}catch(_0x5686c0){console['error']('[SSE\x20Client]\x20Error\x20in\x20'+_0x4c7bac+'\x20listener:',_0x5686c0);}});}['connect'](_0xefeb85='me'){this['userId']=_0xefeb85,this['useSharedWorker']?this['_connectViaWorker'](_0xefeb85):this['_connectDirect'](_0xefeb85);}['_connectViaWorker'](_0x23a694){try{this['_ensureWorker'](),this['port']['postMessage']({'action':'connect','userId':_0x23a694});}catch(_0x29ad6e){console['error']('[SSE\x20Client]\x20SharedWorker\x20failed,\x20falling\x20back\x20to\x20direct\x20SSE:',_0x29ad6e),this['useSharedWorker']=![],this['_connectDirect'](_0x23a694);}}['_ensureWorker'](){!this['worker']&&(this['worker']=new SharedWorker('/sse-shared-worker.js'),this['port']=this['worker']['port'],this['port']['onmessage']=this['_handleWorkerMessage'],this['port']['onmessageerror']=_0x4d2012=>{console['error']('[SSE\x20Client]\x20Worker\x20message\x20error:',_0x4d2012),this['_emit']('error',{'error':'Worker\x20message\x20error'});},this['port']['start']());}['_handleWorkerMessage'](_0x2e4e82){const _0xb9cc9c=_0x2e4e82['data'];if(_0xb9cc9c['type']&&_0xb9cc9c['type']['startsWith']('task:')){this['_handleTaskStreamMessage'](_0xb9cc9c);return;}switch(_0xb9cc9c['type']){case'connected':this['connected']=!![],this['_emit']('connected',{});break;case'snapshot':case'activity':case'status':case'new-task':case'queue-position':try{const _0x349540=JSON['parse'](_0xb9cc9c['data']);this['_emit'](_0xb9cc9c['type'],_0x349540);}catch(_0x3324e0){console['error']('[SSE\x20Client]\x20Failed\x20to\x20parse\x20'+_0xb9cc9c['type']+'\x20data:',_0x3324e0);}break;case'error':this['connected']=![],this['_emit']('error',_0xb9cc9c);break;default:console['warn']('[SSE\x20Client]\x20Unknown\x20message\x20type:',_0xb9cc9c['type']);}}['_handleTaskStreamMessage'](_0x5771c7){const {taskId:_0x212bf5,type:_0x5a68a3,data:_0x52eea5}=_0x5771c7,_0x1ec552=this['_taskSubscriptions']['get'](_0x212bf5);if(!_0x1ec552||_0x1ec552['size']===0x0)return;const _0x36cd74=_0x5a68a3['replace']('task:',''),_0x30be23=eventTypeToHandler(_0x36cd74);_0x1ec552['forEach'](_0x2674e9=>{if(_0x2674e9['handlers'][_0x30be23])try{const _0x5c944e=typeof _0x52eea5==='string'?JSON['parse'](_0x52eea5):_0x52eea5;_0x2674e9['handlers'][_0x30be23](_0x5c944e);}catch(_0x4f7c99){console['error']('[SSE\x20Client]\x20Error\x20in\x20task\x20'+_0x36cd74+'\x20handler:',_0x4f7c99);}});}['_connectDirect'](_0x57a616){this['eventSource']&&(this['eventSource']['close'](),this['eventSource']=null);const _0x32d627=_0x57a616&&_0x57a616!=='me'?'?userId='+_0x57a616:'';try{this['eventSource']=new EventSource('/tasks/updates'+_0x32d627),this['eventSource']['addEventListener']('open',()=>{this['connected']=!![],this['reconnectAttempts']=0x0,this['_emit']('connected',{});}),this['eventSource']['addEventListener']('snapshot',_0x18f79e=>{this['_handleDirectSSE']('snapshot',_0x18f79e),this['reconnectAttempts']=0x0;}),this['eventSource']['addEventListener']('activity',_0x272adc=>{this['_handleDirectSSE']('activity',_0x272adc);}),this['eventSource']['addEventListener']('status',_0x59e9ca=>{this['_handleDirectSSE']('status',_0x59e9ca);}),this['eventSource']['addEventListener']('new-task',_0x4806fe=>{this['_handleDirectSSE']('new-task',_0x4806fe);}),this['eventSource']['addEventListener']('queue-position',_0x1d9cc3=>{this['_handleDirectSSE']('queue-position',_0x1d9cc3);}),this['eventSource']['addEventListener']('error',_0x3a1fcd=>{console['error']('[SSE\x20Client]\x20Direct\x20SSE\x20error:',_0x3a1fcd),this['connected']=![],this['_emit']('error',{'error':'Connection\x20error'}),this['eventSource']&&(this['eventSource']['close'](),this['eventSource']=null),this['_scheduleReconnect']();});}catch(_0x448902){console['error']('[SSE\x20Client]\x20Failed\x20to\x20create\x20EventSource:',_0x448902),this['_emit']('error',{'error':_0x448902['message']}),this['_scheduleReconnect']();}}['_handleDirectSSE'](_0x288c34,_0x3084a7){try{const _0x57bc7e=JSON['parse'](_0x3084a7['data']);this['_emit'](_0x288c34,_0x57bc7e);}catch(_0x1ccacb){console['error']('[SSE\x20Client]\x20Failed\x20to\x20parse\x20'+_0x288c34+'\x20data:',_0x1ccacb);}}['_scheduleReconnect'](){this['reconnectTimeout']&&clearTimeout(this['reconnectTimeout']);const _0x3a2d03=Math['min'](0x3e8*Math['pow'](0x2,this['reconnectAttempts']),0x7530);this['reconnectAttempts']++,console['log']('[SSE\x20Client]\x20Scheduling\x20reconnect\x20in\x20'+_0x3a2d03+'ms'),this['reconnectTimeout']=setTimeout(()=>{this['_connectDirect'](this['userId']);},_0x3a2d03);}['changeFilter'](_0x40207b){if(_0x40207b===this['userId'])return;this['userId']=_0x40207b;if(this['useSharedWorker']&&this['port'])this['port']['postMessage']({'action':'changeFilter','userId':_0x40207b});else this['eventSource']&&this['_connectDirect'](_0x40207b);}['subscribeTask'](_0x5191f9,_0x45bc2e){return this['useSharedWorker']?this['_subscribeTaskViaWorker'](_0x5191f9,_0x45bc2e):this['_subscribeTaskDirect'](_0x5191f9,_0x45bc2e);}['unsubscribeTask'](_0x16092c){if(!_0x16092c)return;_0x16092c['type']==='worker'?this['_unsubscribeTaskWorker'](_0x16092c):this['_unsubscribeTaskDirect'](_0x16092c);}['_subscribeTaskViaWorker'](_0x3296f7,_0x2503e6){try{this['_ensureWorker']();}catch(_0x1573f7){return console['error']('[SSE\x20Client]\x20SharedWorker\x20failed\x20for\x20task\x20sub,\x20falling\x20back:',_0x1573f7),this['useSharedWorker']=![],this['_subscribeTaskDirect'](_0x3296f7,_0x2503e6);}const _0x16d3a3=++this['_taskSubIdCounter'],_0x346b7a={'type':'worker','taskId':_0x3296f7,'handlers':_0x2503e6,'id':_0x16d3a3};return!this['_taskSubscriptions']['has'](_0x3296f7)&&(this['_taskSubscriptions']['set'](_0x3296f7,new Set()),this['port']['postMessage']({'action':'subscribeTask','taskId':_0x3296f7})),this['_taskSubscriptions']['get'](_0x3296f7)['add'](_0x346b7a),_0x346b7a;}['_unsubscribeTaskWorker'](_0x4f4822){const {taskId:_0x215a21}=_0x4f4822,_0x380c63=this['_taskSubscriptions']['get'](_0x215a21);if(_0x380c63){_0x380c63['delete'](_0x4f4822);if(_0x380c63['size']===0x0){this['_taskSubscriptions']['delete'](_0x215a21);try{this['port']&&this['port']['postMessage']({'action':'unsubscribeTask','taskId':_0x215a21});}catch(_0x493819){}}}}['_subscribeTaskDirect'](_0x532335,_0x274343){const _0x1c21e6=++this['_taskSubIdCounter'],_0x9a27b0=new EventSource('/tasks/'+_0x532335+'/stream'),_0x517bbc={'type':'direct','taskId':_0x532335,'handlers':_0x274343,'id':_0x1c21e6,'eventSource':_0x9a27b0};!this['_taskSubscriptions']['has'](_0x532335)&&this['_taskSubscriptions']['set'](_0x532335,new Set());this['_taskSubscriptions']['get'](_0x532335)['add'](_0x517bbc);for(const _0x567e5c of TASK_STREAM_EVENTS){const _0x3ee30c=eventTypeToHandler(_0x567e5c);_0x9a27b0['addEventListener'](_0x567e5c,_0x1fc4a7=>{if(_0x274343[_0x3ee30c])try{const _0x1aa64f=JSON['parse'](_0x1fc4a7['data']);_0x274343[_0x3ee30c](_0x1aa64f);}catch(_0x5a6671){console['error']('[SSE\x20Client]\x20Error\x20parsing\x20task\x20'+_0x567e5c+':',_0x5a6671);}});}return _0x9a27b0['addEventListener']('open',()=>{if(_0x274343['onConnected'])_0x274343['onConnected']();}),_0x9a27b0['addEventListener']('error',()=>{if(_0x274343['onError'])_0x274343['onError']({'error':'Connection\x20error'});}),_0x517bbc;}['_unsubscribeTaskDirect'](_0x186d7a){_0x186d7a['eventSource']&&(_0x186d7a['eventSource']['close'](),_0x186d7a['eventSource']=null);const _0xc2b94a=this['_taskSubscriptions']['get'](_0x186d7a['taskId']);_0xc2b94a&&(_0xc2b94a['delete'](_0x186d7a),_0xc2b94a['size']===0x0&&this['_taskSubscriptions']['delete'](_0x186d7a['taskId']));}['disconnect'](){this['reconnectTimeout']&&(clearTimeout(this['reconnectTimeout']),this['reconnectTimeout']=null);this['_taskSubscriptions']['forEach']((_0x542503,_0x48c0cb)=>{_0x542503['forEach'](_0x401030=>{_0x401030['type']==='direct'&&_0x401030['eventSource']&&_0x401030['eventSource']['close']();});}),this['_taskSubscriptions']['clear']();if(this['useSharedWorker']&&this['port'])try{this['port']['postMessage']({'action':'disconnect'});}catch(_0x22db91){}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(_0xf3ad15){if(_0xf3ad15==='connected')return'onConnected';if(_0xf3ad15==='error')return'onError';return'on'+_0xf3ad15['split']('-')['map'](_0x532c9e=>_0x532c9e['charAt'](0x0)['toUpperCase']()+_0x532c9e['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'](_0x378320,_0x54d943){return!this['listeners']['has'](_0x378320)&&this['listeners']['set'](_0x378320,new Set()),this['listeners']['get'](_0x378320)['add'](_0x54d943),this;}['off'](_0x3c29fc,_0xf34252){return this['listeners']['has'](_0x3c29fc)&&this['listeners']['get'](_0x3c29fc)['delete'](_0xf34252),this;}['_emit'](_0xaf30ed,_0x4c4d6e){this['listeners']['has'](_0xaf30ed)&&this['listeners']['get'](_0xaf30ed)['forEach'](_0x46c342=>{try{_0x46c342(_0x4c4d6e);}catch(_0x43a9a4){console['error']('[SSE\x20Client]\x20Error\x20in\x20'+_0xaf30ed+'\x20listener:',_0x43a9a4);}});}['connect'](_0x38a1c0='me'){this['userId']=_0x38a1c0,this['useSharedWorker']?this['_connectViaWorker'](_0x38a1c0):this['_connectDirect'](_0x38a1c0);}['_connectViaWorker'](_0x326d5c){try{this['_ensureWorker'](),this['port']['postMessage']({'action':'connect','userId':_0x326d5c});}catch(_0x3cb459){console['error']('[SSE\x20Client]\x20SharedWorker\x20failed,\x20falling\x20back\x20to\x20direct\x20SSE:',_0x3cb459),this['useSharedWorker']=![],this['_connectDirect'](_0x326d5c);}}['_ensureWorker'](){!this['worker']&&(this['worker']=new SharedWorker('/sse-shared-worker.js'),this['port']=this['worker']['port'],this['port']['onmessage']=this['_handleWorkerMessage'],this['port']['onmessageerror']=_0x418ee5=>{console['error']('[SSE\x20Client]\x20Worker\x20message\x20error:',_0x418ee5),this['_emit']('error',{'error':'Worker\x20message\x20error'});},this['port']['start']());}['_handleWorkerMessage'](_0x417c05){const _0x8202ff=_0x417c05['data'];if(_0x8202ff['type']&&_0x8202ff['type']['startsWith']('task:')){this['_handleTaskStreamMessage'](_0x8202ff);return;}switch(_0x8202ff['type']){case'connected':this['connected']=!![],this['_emit']('connected',{});break;case'snapshot':case'activity':case'status':case'new-task':case'queue-position':try{const _0x57f727=JSON['parse'](_0x8202ff['data']);this['_emit'](_0x8202ff['type'],_0x57f727);}catch(_0x2ff7c1){console['error']('[SSE\x20Client]\x20Failed\x20to\x20parse\x20'+_0x8202ff['type']+'\x20data:',_0x2ff7c1);}break;case'error':this['connected']=![],this['_emit']('error',_0x8202ff);break;default:console['warn']('[SSE\x20Client]\x20Unknown\x20message\x20type:',_0x8202ff['type']);}}['_handleTaskStreamMessage'](_0x557132){const {taskId:_0x8476dd,type:_0x1175c0,data:_0x5b6920}=_0x557132,_0x6d59a=this['_taskSubscriptions']['get'](_0x8476dd);if(!_0x6d59a||_0x6d59a['size']===0x0)return;const _0x31ee04=_0x1175c0['replace']('task:',''),_0x259654=eventTypeToHandler(_0x31ee04);_0x6d59a['forEach'](_0x13ae28=>{if(_0x13ae28['handlers'][_0x259654])try{const _0x1764f9=typeof _0x5b6920==='string'?JSON['parse'](_0x5b6920):_0x5b6920;_0x13ae28['handlers'][_0x259654](_0x1764f9);}catch(_0x22b8b5){console['error']('[SSE\x20Client]\x20Error\x20in\x20task\x20'+_0x31ee04+'\x20handler:',_0x22b8b5);}});}['_connectDirect'](_0x2581d1){this['eventSource']&&(this['eventSource']['close'](),this['eventSource']=null);const _0x2fdd99=_0x2581d1&&_0x2581d1!=='me'?'?userId='+_0x2581d1:'';try{this['eventSource']=new EventSource('/tasks/updates'+_0x2fdd99),this['eventSource']['addEventListener']('open',()=>{this['connected']=!![],this['reconnectAttempts']=0x0,this['_emit']('connected',{});}),this['eventSource']['addEventListener']('snapshot',_0xe55db6=>{this['_handleDirectSSE']('snapshot',_0xe55db6),this['reconnectAttempts']=0x0;}),this['eventSource']['addEventListener']('activity',_0x73e0de=>{this['_handleDirectSSE']('activity',_0x73e0de);}),this['eventSource']['addEventListener']('status',_0x2dc5e0=>{this['_handleDirectSSE']('status',_0x2dc5e0);}),this['eventSource']['addEventListener']('new-task',_0x23b010=>{this['_handleDirectSSE']('new-task',_0x23b010);}),this['eventSource']['addEventListener']('queue-position',_0x198dea=>{this['_handleDirectSSE']('queue-position',_0x198dea);}),this['eventSource']['addEventListener']('error',_0x5984a5=>{console['error']('[SSE\x20Client]\x20Direct\x20SSE\x20error:',_0x5984a5),this['connected']=![],this['_emit']('error',{'error':'Connection\x20error'}),this['eventSource']&&(this['eventSource']['close'](),this['eventSource']=null),this['_scheduleReconnect']();});}catch(_0x27ebb1){console['error']('[SSE\x20Client]\x20Failed\x20to\x20create\x20EventSource:',_0x27ebb1),this['_emit']('error',{'error':_0x27ebb1['message']}),this['_scheduleReconnect']();}}['_handleDirectSSE'](_0x1d8a20,_0xfc8529){try{const _0x473792=JSON['parse'](_0xfc8529['data']);this['_emit'](_0x1d8a20,_0x473792);}catch(_0x45f9f5){console['error']('[SSE\x20Client]\x20Failed\x20to\x20parse\x20'+_0x1d8a20+'\x20data:',_0x45f9f5);}}['_scheduleReconnect'](){this['reconnectTimeout']&&clearTimeout(this['reconnectTimeout']);const _0x3c7ed3=Math['min'](0x3e8*Math['pow'](0x2,this['reconnectAttempts']),0x7530);this['reconnectAttempts']++,console['log']('[SSE\x20Client]\x20Scheduling\x20reconnect\x20in\x20'+_0x3c7ed3+'ms'),this['reconnectTimeout']=setTimeout(()=>{this['_connectDirect'](this['userId']);},_0x3c7ed3);}['changeFilter'](_0x38b250){if(_0x38b250===this['userId'])return;this['userId']=_0x38b250;if(this['useSharedWorker']&&this['port'])this['port']['postMessage']({'action':'changeFilter','userId':_0x38b250});else this['eventSource']&&this['_connectDirect'](_0x38b250);}['subscribeTask'](_0x6cd3bc,_0x5dec0d){return this['useSharedWorker']?this['_subscribeTaskViaWorker'](_0x6cd3bc,_0x5dec0d):this['_subscribeTaskDirect'](_0x6cd3bc,_0x5dec0d);}['unsubscribeTask'](_0x66a766){if(!_0x66a766)return;_0x66a766['type']==='worker'?this['_unsubscribeTaskWorker'](_0x66a766):this['_unsubscribeTaskDirect'](_0x66a766);}['_subscribeTaskViaWorker'](_0x4ffc6d,_0x3db7f3){try{this['_ensureWorker']();}catch(_0x5768b0){return console['error']('[SSE\x20Client]\x20SharedWorker\x20failed\x20for\x20task\x20sub,\x20falling\x20back:',_0x5768b0),this['useSharedWorker']=![],this['_subscribeTaskDirect'](_0x4ffc6d,_0x3db7f3);}const _0x5d824b=++this['_taskSubIdCounter'],_0xd19dd0={'type':'worker','taskId':_0x4ffc6d,'handlers':_0x3db7f3,'id':_0x5d824b};return!this['_taskSubscriptions']['has'](_0x4ffc6d)&&(this['_taskSubscriptions']['set'](_0x4ffc6d,new Set()),this['port']['postMessage']({'action':'subscribeTask','taskId':_0x4ffc6d})),this['_taskSubscriptions']['get'](_0x4ffc6d)['add'](_0xd19dd0),_0xd19dd0;}['_unsubscribeTaskWorker'](_0x595dcd){const {taskId:_0xf1668c}=_0x595dcd,_0x2a3156=this['_taskSubscriptions']['get'](_0xf1668c);if(_0x2a3156){_0x2a3156['delete'](_0x595dcd);if(_0x2a3156['size']===0x0){this['_taskSubscriptions']['delete'](_0xf1668c);try{this['port']&&this['port']['postMessage']({'action':'unsubscribeTask','taskId':_0xf1668c});}catch(_0x11d348){}}}}['_subscribeTaskDirect'](_0xb204af,_0x61e3d9){const _0x57e26d=++this['_taskSubIdCounter'],_0x5b0f2e=new EventSource('/tasks/'+_0xb204af+'/stream'),_0x153018={'type':'direct','taskId':_0xb204af,'handlers':_0x61e3d9,'id':_0x57e26d,'eventSource':_0x5b0f2e};!this['_taskSubscriptions']['has'](_0xb204af)&&this['_taskSubscriptions']['set'](_0xb204af,new Set());this['_taskSubscriptions']['get'](_0xb204af)['add'](_0x153018);for(const _0x103bed of TASK_STREAM_EVENTS){const _0x36d823=eventTypeToHandler(_0x103bed);_0x5b0f2e['addEventListener'](_0x103bed,_0x4c9cd5=>{if(_0x61e3d9[_0x36d823])try{const _0x567347=JSON['parse'](_0x4c9cd5['data']);_0x61e3d9[_0x36d823](_0x567347);}catch(_0x3a0960){console['error']('[SSE\x20Client]\x20Error\x20parsing\x20task\x20'+_0x103bed+':',_0x3a0960);}});}return _0x5b0f2e['addEventListener']('open',()=>{if(_0x61e3d9['onConnected'])_0x61e3d9['onConnected']();}),_0x5b0f2e['addEventListener']('error',()=>{if(_0x61e3d9['onError'])_0x61e3d9['onError']({'error':'Connection\x20error'});}),_0x153018;}['_unsubscribeTaskDirect'](_0x3521de){_0x3521de['eventSource']&&(_0x3521de['eventSource']['close'](),_0x3521de['eventSource']=null);const _0x3c41ac=this['_taskSubscriptions']['get'](_0x3521de['taskId']);_0x3c41ac&&(_0x3c41ac['delete'](_0x3521de),_0x3c41ac['size']===0x0&&this['_taskSubscriptions']['delete'](_0x3521de['taskId']));}['disconnect'](){this['reconnectTimeout']&&(clearTimeout(this['reconnectTimeout']),this['reconnectTimeout']=null);this['_taskSubscriptions']['forEach']((_0x35226b,_0x1d046e)=>{_0x35226b['forEach'](_0x266439=>{_0x266439['type']==='direct'&&_0x266439['eventSource']&&_0x266439['eventSource']['close']();});}),this['_taskSubscriptions']['clear']();if(this['useSharedWorker']&&this['port'])try{this['port']['postMessage']({'action':'disconnect'});}catch(_0x4dfa6f){}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(_0x29ed90){eventSource&&currentUserId!==_0x29ed90&&(eventSource['close'](),eventSource=null);if(eventSource&&eventSource['readyState']!==EventSource['CLOSED'])return;currentUserId=_0x29ed90;const _0x261727=_0x29ed90&&_0x29ed90!=='me'?'?userId='+_0x29ed90:'';try{eventSource=new EventSource('/tasks/updates'+_0x261727),eventSource['addEventListener']('snapshot',_0x2d0d91=>{broadcast({'type':'snapshot','data':_0x2d0d91['data']}),reconnectAttempts=0x0;}),eventSource['addEventListener']('activity',_0x397bd5=>{broadcast({'type':'activity','data':_0x397bd5['data']});}),eventSource['addEventListener']('status',_0x239b7d=>{broadcast({'type':'status','data':_0x239b7d['data']});}),eventSource['addEventListener']('new-task',_0x1f6b08=>{broadcast({'type':'new-task','data':_0x1f6b08['data']});}),eventSource['addEventListener']('queue-position',_0x2cf21a=>{broadcast({'type':'queue-position','data':_0x2cf21a['data']});}),eventSource['addEventListener']('open',()=>{broadcast({'type':'connected'}),reconnectAttempts=0x0;}),eventSource['addEventListener']('error',_0x45cc3a=>{console['error']('[SSE\x20Worker]\x20Connection\x20error:',_0x45cc3a),broadcast({'type':'error','error':'Connection\x20error'}),eventSource&&(eventSource['close'](),eventSource=null),scheduleReconnect();});}catch(_0x1b197d){console['error']('[SSE\x20Worker]\x20Failed\x20to\x20create\x20EventSource:',_0x1b197d),broadcast({'type':'error','error':_0x1b197d['message']}),scheduleReconnect();}}function scheduleReconnect(){reconnectTimeout&&clearTimeout(reconnectTimeout);if(ports['size']===0x0)return;const _0xced58d=Math['min'](0x3e8*Math['pow'](0x2,reconnectAttempts),MAX_RECONNECT_DELAY);reconnectAttempts++,console['log']('[SSE\x20Worker]\x20Scheduling\x20reconnect\x20in\x20'+_0xced58d+'ms\x20(attempt\x20'+reconnectAttempts+')'),reconnectTimeout=setTimeout(()=>{ports['size']>0x0&&connect(currentUserId);},_0xced58d);}function broadcast(_0x3152eb){const _0x3165f7=[];ports['forEach'](_0x229e0c=>{try{_0x229e0c['postMessage'](_0x3152eb);}catch(_0x497ce9){console['warn']('[SSE\x20Worker]\x20Failed\x20to\x20send\x20to\x20port,\x20removing:',_0x497ce9),_0x3165f7['push'](_0x229e0c);}}),_0x3165f7['length']>0x0&&cleanUpDeadPorts(_0x3165f7),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(_0x8a4cce,_0x2dbb8f){let _0x12fcfb=taskStreams['get'](_0x2dbb8f);!_0x12fcfb&&(_0x12fcfb={'eventSource':null,'reconnectTimeout':null,'reconnectAttempts':0x0,'subscribedPorts':new Set()},taskStreams['set'](_0x2dbb8f,_0x12fcfb));_0x12fcfb['subscribedPorts']['add'](_0x8a4cce);if(!_0x12fcfb['eventSource']||_0x12fcfb['eventSource']['readyState']===EventSource['CLOSED'])connectTaskStream(_0x2dbb8f);else{if(_0x12fcfb['eventSource']['readyState']===EventSource['OPEN'])try{_0x8a4cce['postMessage']({'type':'task:connected','taskId':_0x2dbb8f});}catch(_0x277f5a){}}}function unsubscribeTask(_0x3083a0,_0x579cb0){const _0x2792ce=taskStreams['get'](_0x579cb0);if(!_0x2792ce)return;_0x2792ce['subscribedPorts']['delete'](_0x3083a0),_0x2792ce['subscribedPorts']['size']===0x0&&deferredCloseTaskStream(_0x579cb0);}function connectTaskStream(_0x474e85){const _0x2315d7=taskStreams['get'](_0x474e85);if(!_0x2315d7)return;_0x2315d7['eventSource']&&(_0x2315d7['eventSource']['close'](),_0x2315d7['eventSource']=null);try{_0x2315d7['eventSource']=new EventSource('/tasks/'+_0x474e85+'/stream');for(const _0x180bd1 of TASK_STREAM_EVENTS){_0x2315d7['eventSource']['addEventListener'](_0x180bd1,_0x3f0ebc=>{broadcastToTask(_0x474e85,'task:'+_0x180bd1,_0x3f0ebc['data']),_0x2315d7['reconnectAttempts']=0x0;});}_0x2315d7['eventSource']['addEventListener']('open',()=>{broadcastToTask(_0x474e85,'task:connected','{}'),_0x2315d7['reconnectAttempts']=0x0;}),_0x2315d7['eventSource']['addEventListener']('error',()=>{broadcastToTask(_0x474e85,'task:error',JSON['stringify']({'error':'Connection\x20error'})),_0x2315d7['eventSource']&&(_0x2315d7['eventSource']['close'](),_0x2315d7['eventSource']=null),scheduleTaskReconnect(_0x474e85);});}catch(_0x4eee2c){console['error']('[SSE\x20Worker]\x20Failed\x20to\x20create\x20task\x20EventSource\x20for\x20'+_0x474e85+':',_0x4eee2c),broadcastToTask(_0x474e85,'task:error',JSON['stringify']({'error':_0x4eee2c['message']})),scheduleTaskReconnect(_0x474e85);}}function broadcastToTask(_0x1df3a4,_0x40bb38,_0x365689){const _0x20b281=taskStreams['get'](_0x1df3a4);if(!_0x20b281)return;const _0x3c1db3=[];_0x20b281['subscribedPorts']['forEach'](_0x301914=>{try{_0x301914['postMessage']({'type':_0x40bb38,'taskId':_0x1df3a4,'data':_0x365689});}catch(_0x30057a){_0x3c1db3['push'](_0x301914);}}),_0x3c1db3['length']>0x0&&(_0x3c1db3['forEach'](_0x538049=>_0x20b281['subscribedPorts']['delete'](_0x538049)),cleanUpDeadPorts(_0x3c1db3),_0x20b281['subscribedPorts']['size']===0x0&&closeTaskStream(_0x1df3a4));}function closeTaskStream(_0x11bd84){const _0x45baf4=taskStreams['get'](_0x11bd84);if(!_0x45baf4)return;_0x45baf4['eventSource']&&_0x45baf4['eventSource']['close'](),_0x45baf4['reconnectTimeout']&&clearTimeout(_0x45baf4['reconnectTimeout']),taskStreams['delete'](_0x11bd84);}function deferredCloseTaskStream(_0x51d555){setTimeout(()=>{const _0x4e08fe=taskStreams['get'](_0x51d555);_0x4e08fe&&_0x4e08fe['subscribedPorts']['size']===0x0&&closeTaskStream(_0x51d555);},0x0);}function scheduleTaskReconnect(_0x551126){const _0x5defc5=taskStreams['get'](_0x551126);if(!_0x5defc5||_0x5defc5['subscribedPorts']['size']===0x0)return;_0x5defc5['reconnectTimeout']&&clearTimeout(_0x5defc5['reconnectTimeout']);const _0x515c6b=Math['min'](0x3e8*Math['pow'](0x2,_0x5defc5['reconnectAttempts']),MAX_RECONNECT_DELAY);_0x5defc5['reconnectAttempts']++,console['log']('[SSE\x20Worker]\x20Scheduling\x20task\x20stream\x20reconnect\x20for\x20'+_0x551126+'\x20in\x20'+_0x515c6b+'ms'),_0x5defc5['reconnectTimeout']=setTimeout(()=>{_0x5defc5['subscribedPorts']['size']>0x0&&connectTaskStream(_0x551126);},_0x515c6b);}function cleanUpDeadPorts(_0x3c9ff3){for(const _0x1a613f of _0x3c9ff3){ports['delete'](_0x1a613f),taskStreams['forEach']((_0x1052fb,_0x1da79b)=>{_0x1052fb['subscribedPorts']['delete'](_0x1a613f),_0x1052fb['subscribedPorts']['size']===0x0&&closeTaskStream(_0x1da79b);});}}function removePortFromAllTasks(_0x274321){taskStreams['forEach']((_0x37c66b,_0x57347d)=>{_0x37c66b['subscribedPorts']['has'](_0x274321)&&(_0x37c66b['subscribedPorts']['delete'](_0x274321),_0x37c66b['subscribedPorts']['size']===0x0&&closeTaskStream(_0x57347d));});}self['onconnect']=function(_0x1c4d24){const _0x34309d=_0x1c4d24['ports'][0x0];ports['add'](_0x34309d),console['log']('[SSE\x20Worker]\x20New\x20port\x20connected.\x20Total\x20ports:\x20'+ports['size']),_0x34309d['onmessage']=function(_0x425eea){const {action:_0x27b98a,userId:_0x46aa18,taskId:_0x2d6155}=_0x425eea['data'];switch(_0x27b98a){case'connect':connect(_0x46aa18);eventSource&&eventSource['readyState']===EventSource['OPEN']&&_0x34309d['postMessage']({'type':'connected'});break;case'disconnect':ports['delete'](_0x34309d),removePortFromAllTasks(_0x34309d),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':_0x46aa18!==currentUserId&&connect(_0x46aa18);break;case'subscribeTask':subscribeTask(_0x34309d,_0x2d6155);break;case'unsubscribeTask':unsubscribeTask(_0x34309d,_0x2d6155);break;default:console['warn']('[SSE\x20Worker]\x20Unknown\x20action:',_0x27b98a);}},_0x34309d['onmessageerror']=function(_0x201b74){console['error']('[SSE\x20Worker]\x20Port\x20message\x20error:',_0x201b74),ports['delete'](_0x34309d),removePortFromAllTasks(_0x34309d);},_0x34309d['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(_0x2f011d){eventSource&&currentUserId!==_0x2f011d&&(eventSource['close'](),eventSource=null);if(eventSource&&eventSource['readyState']!==EventSource['CLOSED'])return;currentUserId=_0x2f011d;const _0x367d57=_0x2f011d&&_0x2f011d!=='me'?'?userId='+_0x2f011d:'';try{eventSource=new EventSource('/tasks/updates'+_0x367d57),eventSource['addEventListener']('snapshot',_0x3900b2=>{broadcast({'type':'snapshot','data':_0x3900b2['data']}),reconnectAttempts=0x0;}),eventSource['addEventListener']('activity',_0x2f0210=>{broadcast({'type':'activity','data':_0x2f0210['data']});}),eventSource['addEventListener']('status',_0x2fd26c=>{broadcast({'type':'status','data':_0x2fd26c['data']});}),eventSource['addEventListener']('new-task',_0x3c705d=>{broadcast({'type':'new-task','data':_0x3c705d['data']});}),eventSource['addEventListener']('queue-position',_0x50c24b=>{broadcast({'type':'queue-position','data':_0x50c24b['data']});}),eventSource['addEventListener']('open',()=>{broadcast({'type':'connected'}),reconnectAttempts=0x0;}),eventSource['addEventListener']('error',_0x5c73b9=>{console['error']('[SSE\x20Worker]\x20Connection\x20error:',_0x5c73b9),broadcast({'type':'error','error':'Connection\x20error'}),eventSource&&(eventSource['close'](),eventSource=null),scheduleReconnect();});}catch(_0x4f71af){console['error']('[SSE\x20Worker]\x20Failed\x20to\x20create\x20EventSource:',_0x4f71af),broadcast({'type':'error','error':_0x4f71af['message']}),scheduleReconnect();}}function scheduleReconnect(){reconnectTimeout&&clearTimeout(reconnectTimeout);if(ports['size']===0x0)return;const _0x388bfb=Math['min'](0x3e8*Math['pow'](0x2,reconnectAttempts),MAX_RECONNECT_DELAY);reconnectAttempts++,console['log']('[SSE\x20Worker]\x20Scheduling\x20reconnect\x20in\x20'+_0x388bfb+'ms\x20(attempt\x20'+reconnectAttempts+')'),reconnectTimeout=setTimeout(()=>{ports['size']>0x0&&connect(currentUserId);},_0x388bfb);}function broadcast(_0x141c44){const _0x2a7a30=[];ports['forEach'](_0x14124e=>{try{_0x14124e['postMessage'](_0x141c44);}catch(_0xeee4f8){console['warn']('[SSE\x20Worker]\x20Failed\x20to\x20send\x20to\x20port,\x20removing:',_0xeee4f8),_0x2a7a30['push'](_0x14124e);}}),_0x2a7a30['length']>0x0&&cleanUpDeadPorts(_0x2a7a30),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(_0xa191c3,_0x4f267e){let _0x2f3630=taskStreams['get'](_0x4f267e);!_0x2f3630&&(_0x2f3630={'eventSource':null,'reconnectTimeout':null,'reconnectAttempts':0x0,'subscribedPorts':new Set()},taskStreams['set'](_0x4f267e,_0x2f3630));_0x2f3630['subscribedPorts']['add'](_0xa191c3);if(!_0x2f3630['eventSource']||_0x2f3630['eventSource']['readyState']===EventSource['CLOSED'])connectTaskStream(_0x4f267e);else{if(_0x2f3630['eventSource']['readyState']===EventSource['OPEN'])try{_0xa191c3['postMessage']({'type':'task:connected','taskId':_0x4f267e});}catch(_0x21404d){}}}function unsubscribeTask(_0x1d35b2,_0x570a71){const _0x4309bc=taskStreams['get'](_0x570a71);if(!_0x4309bc)return;_0x4309bc['subscribedPorts']['delete'](_0x1d35b2),_0x4309bc['subscribedPorts']['size']===0x0&&deferredCloseTaskStream(_0x570a71);}function connectTaskStream(_0x56639d){const _0x45f25f=taskStreams['get'](_0x56639d);if(!_0x45f25f)return;_0x45f25f['eventSource']&&(_0x45f25f['eventSource']['close'](),_0x45f25f['eventSource']=null);try{_0x45f25f['eventSource']=new EventSource('/tasks/'+_0x56639d+'/stream');for(const _0x1ee46e of TASK_STREAM_EVENTS){_0x45f25f['eventSource']['addEventListener'](_0x1ee46e,_0x4e12ef=>{broadcastToTask(_0x56639d,'task:'+_0x1ee46e,_0x4e12ef['data']),_0x45f25f['reconnectAttempts']=0x0;});}_0x45f25f['eventSource']['addEventListener']('open',()=>{broadcastToTask(_0x56639d,'task:connected','{}'),_0x45f25f['reconnectAttempts']=0x0;}),_0x45f25f['eventSource']['addEventListener']('error',()=>{broadcastToTask(_0x56639d,'task:error',JSON['stringify']({'error':'Connection\x20error'})),_0x45f25f['eventSource']&&(_0x45f25f['eventSource']['close'](),_0x45f25f['eventSource']=null),scheduleTaskReconnect(_0x56639d);});}catch(_0x10c9ab){console['error']('[SSE\x20Worker]\x20Failed\x20to\x20create\x20task\x20EventSource\x20for\x20'+_0x56639d+':',_0x10c9ab),broadcastToTask(_0x56639d,'task:error',JSON['stringify']({'error':_0x10c9ab['message']})),scheduleTaskReconnect(_0x56639d);}}function broadcastToTask(_0x4179a4,_0x17c617,_0x3f710f){const _0x41b41c=taskStreams['get'](_0x4179a4);if(!_0x41b41c)return;const _0x2f0252=[];_0x41b41c['subscribedPorts']['forEach'](_0x2a0149=>{try{_0x2a0149['postMessage']({'type':_0x17c617,'taskId':_0x4179a4,'data':_0x3f710f});}catch(_0x1b4469){_0x2f0252['push'](_0x2a0149);}}),_0x2f0252['length']>0x0&&(_0x2f0252['forEach'](_0x2c487d=>_0x41b41c['subscribedPorts']['delete'](_0x2c487d)),cleanUpDeadPorts(_0x2f0252),_0x41b41c['subscribedPorts']['size']===0x0&&closeTaskStream(_0x4179a4));}function closeTaskStream(_0x123909){const _0x18b7b1=taskStreams['get'](_0x123909);if(!_0x18b7b1)return;_0x18b7b1['eventSource']&&_0x18b7b1['eventSource']['close'](),_0x18b7b1['reconnectTimeout']&&clearTimeout(_0x18b7b1['reconnectTimeout']),taskStreams['delete'](_0x123909);}function deferredCloseTaskStream(_0x4a82bb){setTimeout(()=>{const _0x2d8c3a=taskStreams['get'](_0x4a82bb);_0x2d8c3a&&_0x2d8c3a['subscribedPorts']['size']===0x0&&closeTaskStream(_0x4a82bb);},0x0);}function scheduleTaskReconnect(_0xbc4146){const _0x1131b6=taskStreams['get'](_0xbc4146);if(!_0x1131b6||_0x1131b6['subscribedPorts']['size']===0x0)return;_0x1131b6['reconnectTimeout']&&clearTimeout(_0x1131b6['reconnectTimeout']);const _0x3d4588=Math['min'](0x3e8*Math['pow'](0x2,_0x1131b6['reconnectAttempts']),MAX_RECONNECT_DELAY);_0x1131b6['reconnectAttempts']++,console['log']('[SSE\x20Worker]\x20Scheduling\x20task\x20stream\x20reconnect\x20for\x20'+_0xbc4146+'\x20in\x20'+_0x3d4588+'ms'),_0x1131b6['reconnectTimeout']=setTimeout(()=>{_0x1131b6['subscribedPorts']['size']>0x0&&connectTaskStream(_0xbc4146);},_0x3d4588);}function cleanUpDeadPorts(_0x461adf){for(const _0x2b820a of _0x461adf){ports['delete'](_0x2b820a),taskStreams['forEach']((_0x33812c,_0x2828dd)=>{_0x33812c['subscribedPorts']['delete'](_0x2b820a),_0x33812c['subscribedPorts']['size']===0x0&&closeTaskStream(_0x2828dd);});}}function removePortFromAllTasks(_0x246208){taskStreams['forEach']((_0x5c2e40,_0x3d5053)=>{_0x5c2e40['subscribedPorts']['has'](_0x246208)&&(_0x5c2e40['subscribedPorts']['delete'](_0x246208),_0x5c2e40['subscribedPorts']['size']===0x0&&closeTaskStream(_0x3d5053));});}self['onconnect']=function(_0xa1beef){const _0x4d5696=_0xa1beef['ports'][0x0];ports['add'](_0x4d5696),console['log']('[SSE\x20Worker]\x20New\x20port\x20connected.\x20Total\x20ports:\x20'+ports['size']),_0x4d5696['onmessage']=function(_0x3a391d){const {action:_0x475188,userId:_0x4619d2,taskId:_0x5565fc}=_0x3a391d['data'];switch(_0x475188){case'connect':connect(_0x4619d2);eventSource&&eventSource['readyState']===EventSource['OPEN']&&_0x4d5696['postMessage']({'type':'connected'});break;case'disconnect':ports['delete'](_0x4d5696),removePortFromAllTasks(_0x4d5696),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':_0x4619d2!==currentUserId&&connect(_0x4619d2);break;case'subscribeTask':subscribeTask(_0x4d5696,_0x5565fc);break;case'unsubscribeTask':unsubscribeTask(_0x4d5696,_0x5565fc);break;default:console['warn']('[SSE\x20Worker]\x20Unknown\x20action:',_0x475188);}},_0x4d5696['onmessageerror']=function(_0xb56201){console['error']('[SSE\x20Worker]\x20Port\x20message\x20error:',_0xb56201),ports['delete'](_0x4d5696),removePortFromAllTasks(_0x4d5696);},_0x4d5696['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(_0x139b4c,{fallback:fallback='Unknown'}={}){const _0x2955d1=String(_0x139b4c||'')['trim']()['toLowerCase']();if(!_0x2955d1)return fallback;return _0x2955d1['charAt'](0x0)['toUpperCase']()+_0x2955d1['slice'](0x1);}export function escapeRegExp(_0x4f59d1){return String(_0x4f59d1)['replace'](/[.*+?^${}()|[\]\\]/g,'\x5c$&');}export function compareJudgmentsForAliasOrder(_0x5d4ee9,_0x35e043){const _0x432e25=String(_0x5d4ee9?.['createdAt']||''),_0x2d7e5c=String(_0x35e043?.['createdAt']||'');if(_0x432e25!==_0x2d7e5c)return _0x432e25['localeCompare'](_0x2d7e5c);return String(_0x5d4ee9?.['taskId']||'')['localeCompare'](String(_0x35e043?.['taskId']||''));}export function parseJudgeAliasNumber(_0x557a2c,_0x549b6f){const _0x2db604=typeof _0x557a2c==='string'?_0x557a2c['trim']():'',_0x1ce60e=toDisplayAgentName(_0x549b6f,{'fallback':''});if(!_0x2db604||!_0x1ce60e)return null;const _0x53a991=_0x2db604['toLowerCase'](),_0x4e168f=_0x1ce60e['toLowerCase']();if(_0x53a991===_0x4e168f||_0x53a991===_0x4e168f+'\x20judge')return 0x1;const _0x2cdbf0=[new RegExp('^'+escapeRegExp(_0x1ce60e)+'\x5cs+(\x5cd+)$','i'),new RegExp('^'+escapeRegExp(_0x1ce60e)+'\x5cs+Judge\x5cs+(\x5cd+)$','i')];for(const _0x443afa of _0x2cdbf0){const _0x237008=_0x2db604['match'](_0x443afa);if(_0x237008){const _0x420cd4=Number(_0x237008[0x1]);if(Number['isInteger'](_0x420cd4)&&_0x420cd4>0x0)return _0x420cd4;}}return null;}export function formatJudgeDisplayName({alias:_0x38cfcd,agent:_0x69859c,number:number=null,hasDuplicates:hasDuplicates=![]}={}){const _0x55a191=toDisplayAgentName(_0x69859c,{'fallback':'Judge'}),_0xfde225=typeof _0x38cfcd==='string'?_0x38cfcd['trim']():'';if(Number['isInteger'](number)&&number>0x0)return _0x55a191+'\x20Judge\x20'+number;if(_0xfde225)return/\bjudge\b/i['test'](_0xfde225)?_0xfde225:_0xfde225+'\x20Judge';if(hasDuplicates)return _0x55a191+'\x20Judge';return _0x55a191==='Judge'?_0x55a191:_0x55a191+'\x20Judge';}export function buildJudgmentDisplayNameMap(_0x2c7b46=[]){const _0x6a8974=Array['isArray'](_0x2c7b46)?_0x2c7b46['filter'](Boolean):[],_0x49a769=new Map();_0x6a8974['forEach'](_0x305cb4=>{const _0x51c533=_0x305cb4?.['judgeAgent']||_0x305cb4?.['envVars']?.['CODER_AGENT']||'unknown',_0xac68dc=String(_0x51c533||'')['trim']()['toLowerCase']()||'unknown';!_0x49a769['has'](_0xac68dc)&&_0x49a769['set'](_0xac68dc,[]),_0x49a769['get'](_0xac68dc)['push'](_0x305cb4);});const _0x42ab5a=new Map();return _0x49a769['forEach'](_0x599ffe=>{const _0x5dcdb2=[..._0x599ffe]['sort'](compareJudgmentsForAliasOrder),_0x5673a6=_0x5dcdb2['length']>0x1,_0x5b6b51=new Set(),_0x17f028=new Map();_0x5673a6&&_0x5dcdb2['forEach'](_0xa82bb4=>{const _0x1b572a=parseJudgeAliasNumber(_0xa82bb4?.['judgeAlias'],_0xa82bb4?.['judgeAgent']);if(!Number['isInteger'](_0x1b572a)||_0x1b572a<=0x0||_0x5b6b51['has'](_0x1b572a))return;_0x17f028['set'](_0xa82bb4['taskId'],_0x1b572a),_0x5b6b51['add'](_0x1b572a);});let _0x41db66=0x1;const _0x224655=()=>{while(_0x5b6b51['has'](_0x41db66)){_0x41db66+=0x1;}return _0x5b6b51['add'](_0x41db66),_0x41db66;};_0x5dcdb2['forEach'](_0x1a5554=>{let _0x3a3d15=_0x17f028['get'](_0x1a5554['taskId'])||null;_0x5673a6&&_0x3a3d15===null&&!String(_0x1a5554?.['judgeAlias']||'')['trim']()&&(_0x3a3d15=_0x224655()),_0x42ab5a['set'](_0x1a5554['taskId'],formatJudgeDisplayName({'alias':_0x1a5554?.['judgeAlias']||null,'agent':_0x1a5554?.['judgeAgent']||_0x1a5554?.['envVars']?.['CODER_AGENT']||'unknown','number':_0x3a3d15,'hasDuplicates':_0x5673a6}));});}),_0x42ab5a;}export function buildTaskNavigationHref(_0x51d77d,{currentUrl:_0x19b80c,groupedTaskIds:groupedTaskIds=[],groupId:groupId=null}={}){const _0x24192d=new URL(_0x19b80c),_0x27ed0e=String(_0x51d77d||'')['trim'](),_0x4c3e2e=String(groupId||'')['trim'](),_0x139b64=Array['isArray'](groupedTaskIds)?groupedTaskIds['map'](_0x547456=>String(_0x547456||'')['trim']())['filter'](Boolean):[],_0x381767=Boolean(_0x4c3e2e)||_0x139b64['length']>0x1;if(!_0x381767)return _0x27ed0e&&_0x24192d['searchParams']['set']('id',_0x27ed0e),_0x24192d['searchParams']['delete']('groupId'),_0x24192d['toString']();const _0xd1bf50=_0x139b64['includes'](_0x27ed0e)?_0x139b64:[..._0x139b64,_0x27ed0e]['filter'](Boolean);if(_0xd1bf50['length']>0x0)_0x24192d['searchParams']['set']('id',_0xd1bf50['join'](','));else _0x27ed0e&&_0x24192d['searchParams']['set']('id',_0x27ed0e);return _0x4c3e2e?_0x24192d['searchParams']['set']('groupId',_0x4c3e2e):_0x24192d['searchParams']['delete']('groupId'),_0x24192d['toString']();}
1
+ export function toDisplayAgentName(_0x154e3e,{fallback:fallback='Unknown'}={}){const _0xea7a5=String(_0x154e3e||'')['trim']()['toLowerCase']();if(!_0xea7a5)return fallback;return _0xea7a5['charAt'](0x0)['toUpperCase']()+_0xea7a5['slice'](0x1);}export function escapeRegExp(_0x3bdd82){return String(_0x3bdd82)['replace'](/[.*+?^${}()|[\]\\]/g,'\x5c$&');}export function compareJudgmentsForAliasOrder(_0x501089,_0x49466d){const _0x50c403=String(_0x501089?.['createdAt']||''),_0x1152a4=String(_0x49466d?.['createdAt']||'');if(_0x50c403!==_0x1152a4)return _0x50c403['localeCompare'](_0x1152a4);return String(_0x501089?.['taskId']||'')['localeCompare'](String(_0x49466d?.['taskId']||''));}export function parseJudgeAliasNumber(_0x1a2ce5,_0x9b3b48){const _0x3969bd=typeof _0x1a2ce5==='string'?_0x1a2ce5['trim']():'',_0x236789=toDisplayAgentName(_0x9b3b48,{'fallback':''});if(!_0x3969bd||!_0x236789)return null;const _0x104856=_0x3969bd['toLowerCase'](),_0x497839=_0x236789['toLowerCase']();if(_0x104856===_0x497839||_0x104856===_0x497839+'\x20judge')return 0x1;const _0x1cd7ea=[new RegExp('^'+escapeRegExp(_0x236789)+'\x5cs+(\x5cd+)$','i'),new RegExp('^'+escapeRegExp(_0x236789)+'\x5cs+Judge\x5cs+(\x5cd+)$','i')];for(const _0x3da1e1 of _0x1cd7ea){const _0x3ef0eb=_0x3969bd['match'](_0x3da1e1);if(_0x3ef0eb){const _0x44f914=Number(_0x3ef0eb[0x1]);if(Number['isInteger'](_0x44f914)&&_0x44f914>0x0)return _0x44f914;}}return null;}export function formatJudgeDisplayName({alias:_0xcbd3a4,agent:_0x3516ae,number:number=null,hasDuplicates:hasDuplicates=![]}={}){const _0x53a39b=toDisplayAgentName(_0x3516ae,{'fallback':'Judge'}),_0x49d509=typeof _0xcbd3a4==='string'?_0xcbd3a4['trim']():'';if(Number['isInteger'](number)&&number>0x0)return _0x53a39b+'\x20Judge\x20'+number;if(_0x49d509)return/\bjudge\b/i['test'](_0x49d509)?_0x49d509:_0x49d509+'\x20Judge';if(hasDuplicates)return _0x53a39b+'\x20Judge';return _0x53a39b==='Judge'?_0x53a39b:_0x53a39b+'\x20Judge';}export function buildJudgmentDisplayNameMap(_0x1a931b=[]){const _0x5c40f9=Array['isArray'](_0x1a931b)?_0x1a931b['filter'](Boolean):[],_0x1c4fc4=new Map();_0x5c40f9['forEach'](_0x36fef1=>{const _0x1b2460=_0x36fef1?.['judgeAgent']||_0x36fef1?.['envVars']?.['CODER_AGENT']||'unknown',_0x439a97=String(_0x1b2460||'')['trim']()['toLowerCase']()||'unknown';!_0x1c4fc4['has'](_0x439a97)&&_0x1c4fc4['set'](_0x439a97,[]),_0x1c4fc4['get'](_0x439a97)['push'](_0x36fef1);});const _0x143587=new Map();return _0x1c4fc4['forEach'](_0x330f90=>{const _0x3b3b17=[..._0x330f90]['sort'](compareJudgmentsForAliasOrder),_0x37e6e6=_0x3b3b17['length']>0x1,_0x358029=new Set(),_0x42f116=new Map();_0x37e6e6&&_0x3b3b17['forEach'](_0x17c3d1=>{const _0x4fd9c7=parseJudgeAliasNumber(_0x17c3d1?.['judgeAlias'],_0x17c3d1?.['judgeAgent']);if(!Number['isInteger'](_0x4fd9c7)||_0x4fd9c7<=0x0||_0x358029['has'](_0x4fd9c7))return;_0x42f116['set'](_0x17c3d1['taskId'],_0x4fd9c7),_0x358029['add'](_0x4fd9c7);});let _0x33a3d4=0x1;const _0x59f7ca=()=>{while(_0x358029['has'](_0x33a3d4)){_0x33a3d4+=0x1;}return _0x358029['add'](_0x33a3d4),_0x33a3d4;};_0x3b3b17['forEach'](_0x475680=>{let _0x528550=_0x42f116['get'](_0x475680['taskId'])||null;_0x37e6e6&&_0x528550===null&&!String(_0x475680?.['judgeAlias']||'')['trim']()&&(_0x528550=_0x59f7ca()),_0x143587['set'](_0x475680['taskId'],formatJudgeDisplayName({'alias':_0x475680?.['judgeAlias']||null,'agent':_0x475680?.['judgeAgent']||_0x475680?.['envVars']?.['CODER_AGENT']||'unknown','number':_0x528550,'hasDuplicates':_0x37e6e6}));});}),_0x143587;}export function buildTaskNavigationHref(_0x19d5a3,{currentUrl:_0x123f80,groupedTaskIds:groupedTaskIds=[],groupId:groupId=null}={}){const _0x17bd7b=new URL(_0x123f80),_0x1ef0da=String(_0x19d5a3||'')['trim'](),_0x14c0ec=String(groupId||'')['trim'](),_0x44a218=Array['isArray'](groupedTaskIds)?groupedTaskIds['map'](_0x27a436=>String(_0x27a436||'')['trim']())['filter'](Boolean):[],_0x3bfd60=Boolean(_0x14c0ec)||_0x44a218['length']>0x1;if(!_0x3bfd60)return _0x1ef0da&&_0x17bd7b['searchParams']['set']('id',_0x1ef0da),_0x17bd7b['searchParams']['delete']('groupId'),_0x17bd7b['toString']();const _0xe4b317=_0x44a218['includes'](_0x1ef0da)?_0x44a218:[..._0x44a218,_0x1ef0da]['filter'](Boolean);if(_0xe4b317['length']>0x0)_0x17bd7b['searchParams']['set']('id',_0xe4b317['join'](','));else _0x1ef0da&&_0x17bd7b['searchParams']['set']('id',_0x1ef0da);return _0x14c0ec?_0x17bd7b['searchParams']['set']('groupId',_0x14c0ec):_0x17bd7b['searchParams']['delete']('groupId'),_0x17bd7b['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>