@profoundlogic/coderflow-server 0.6.8 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (182) hide show
  1. package/dist/base-image/Dockerfile +3 -0
  2. package/dist/base-image/entrypoint.sh +13 -0
  3. package/dist/base-image/standard-instructions/ibmi-database-sql.md +11 -0
  4. package/dist/base-image/standard-instructions/ibmi-exploratory-verification.md +38 -0
  5. package/dist/base-image/standard-instructions/ibmi-output-requirements.md +6 -0
  6. package/dist/base-image/standard-instructions/output-requirements.md +18 -0
  7. package/dist/base-image/standard-instructions/screenshot-guidelines.md +17 -0
  8. package/dist/coder-server.js +1 -1
  9. package/dist/config.js +1 -1
  10. package/dist/lib/agent-keepalive.js +1 -1
  11. package/dist/lib/agent-models.js +1 -1
  12. package/dist/lib/api-keys.js +1 -1
  13. package/dist/lib/apiKeys.js +1 -1
  14. package/dist/lib/app-server-ports.js +1 -1
  15. package/dist/lib/auto-judge.js +1 -1
  16. package/dist/lib/automation-service.js +1 -1
  17. package/dist/lib/basic-auth.js +1 -1
  18. package/dist/lib/bindings.js +1 -1
  19. package/dist/lib/build-history.js +1 -1
  20. package/dist/lib/build-output-service.js +1 -1
  21. package/dist/lib/build-scheduler.js +1 -1
  22. package/dist/lib/build-service.js +1 -1
  23. package/dist/lib/ca-certificates.js +1 -1
  24. package/dist/lib/claude-oauth-refresh.js +1 -1
  25. package/dist/lib/cli/build.js +1 -1
  26. package/dist/lib/cli/cleanup-users.js +1 -1
  27. package/dist/lib/cli/config-command.js +1 -1
  28. package/dist/lib/cli/config.js +1 -1
  29. package/dist/lib/cli/create-user.js +1 -1
  30. package/dist/lib/cli/grant-admin.js +1 -1
  31. package/dist/lib/cli/init.js +1 -1
  32. package/dist/lib/cli/jira.js +1 -1
  33. package/dist/lib/cli/license.js +1 -1
  34. package/dist/lib/cli/list-roles.js +1 -1
  35. package/dist/lib/cli/list-users.js +1 -1
  36. package/dist/lib/cli/server-manager.js +1 -1
  37. package/dist/lib/cli/set-password.js +1 -1
  38. package/dist/lib/config-migration.js +1 -1
  39. package/dist/lib/container-credential-sync.js +1 -1
  40. package/dist/lib/container-tokens.js +1 -1
  41. package/dist/lib/data-dir.js +1 -1
  42. package/dist/lib/deployment-history.js +1 -1
  43. package/dist/lib/deployment-service.js +1 -1
  44. package/dist/lib/docker-utils.js +1 -1
  45. package/dist/lib/email.js +1 -1
  46. package/dist/lib/emailTemplates.js +1 -1
  47. package/dist/lib/entitlement.js +1 -1
  48. package/dist/lib/external-connections.js +1 -1
  49. package/dist/lib/fetch-utils.js +1 -1
  50. package/dist/lib/git-commit-details-route.js +1 -1
  51. package/dist/lib/git-history-diff-guardrails.js +1 -1
  52. package/dist/lib/git-provider-service.js +1 -1
  53. package/dist/lib/git-provider-setup/github-setup-handler.js +1 -1
  54. package/dist/lib/git-provider-setup/index.js +1 -1
  55. package/dist/lib/git-provider-setup/setup-factory.js +1 -1
  56. package/dist/lib/git-provider-setup/setup-interface.js +1 -1
  57. package/dist/lib/git-providers/azure-devops-provider.js +1 -1
  58. package/dist/lib/git-providers/github-app-provider.js +1 -1
  59. package/dist/lib/git-providers/index.js +1 -1
  60. package/dist/lib/git-providers/provider-factory.js +1 -1
  61. package/dist/lib/git-providers/provider-interface.js +1 -1
  62. package/dist/lib/github-urls.js +1 -1
  63. package/dist/lib/group-objective-linking.js +1 -1
  64. package/dist/lib/ibmi-sync.js +1 -1
  65. package/dist/lib/jira-client.js +1 -1
  66. package/dist/lib/judge-blinding.js +1 -1
  67. package/dist/lib/logger.js +1 -1
  68. package/dist/lib/migration-to-scoped-rbac.js +1 -1
  69. package/dist/lib/model-fetcher.js +1 -1
  70. package/dist/lib/notifications.js +1 -1
  71. package/dist/lib/objective-context.js +1 -1
  72. package/dist/lib/oidc-auth.js +1 -1
  73. package/dist/lib/oidc-device-flow.js +1 -1
  74. package/dist/lib/passwordTokens.js +1 -1
  75. package/dist/lib/permission-resolver.js +1 -1
  76. package/dist/lib/pin-cascade.js +1 -1
  77. package/dist/lib/provider-accounts.js +1 -1
  78. package/dist/lib/provider-oauth.js +1 -1
  79. package/dist/lib/provider-profile.js +1 -1
  80. package/dist/lib/provider-token-refresh.js +1 -1
  81. package/dist/lib/rbac-user-state.js +1 -1
  82. package/dist/lib/request-url.js +1 -1
  83. package/dist/lib/rewind.js +1 -1
  84. package/dist/lib/role-definitions.js +1 -1
  85. package/dist/lib/roles.js +1 -1
  86. package/dist/lib/secrets.js +1 -1
  87. package/dist/lib/setup-repo-git-auth.js +1 -1
  88. package/dist/lib/state-capture.js +1 -1
  89. package/dist/lib/static-files.js +1 -1
  90. package/dist/lib/task-aliases.js +1 -1
  91. package/dist/lib/task-name-format.js +1 -1
  92. package/dist/lib/task-name-generator.js +1 -1
  93. package/dist/lib/task-source-metadata.js +1 -1
  94. package/dist/lib/teams.js +1 -1
  95. package/dist/lib/user-git-oauth.js +1 -1
  96. package/dist/lib/user-git-tokens.js +1 -1
  97. package/dist/lib/users.js +1 -1
  98. package/dist/middleware/requireAuth.js +1 -1
  99. package/dist/middleware/requireInit.js +1 -1
  100. package/dist/middleware/requirePermission.js +1 -1
  101. package/dist/package.json +1 -1
  102. package/dist/playwright.config.js +1 -1
  103. package/dist/playwright.task-terminal.config.js +1 -1
  104. package/dist/routes/apiKeys.js +1 -1
  105. package/dist/routes/auth-oidc.js +1 -1
  106. package/dist/routes/auth.js +1 -1
  107. package/dist/routes/automations.js +1 -1
  108. package/dist/routes/bindings.js +1 -1
  109. package/dist/routes/build.js +1 -1
  110. package/dist/routes/containers.js +1 -1
  111. package/dist/routes/deploy-task.js +1 -1
  112. package/dist/routes/environment-management.js +1 -1
  113. package/dist/routes/environments.js +1 -1
  114. package/dist/routes/external-skills.js +1 -1
  115. package/dist/routes/git-credentials.js +1 -1
  116. package/dist/routes/git-oauth.js +1 -1
  117. package/dist/routes/git-provider-setup.js +1 -1
  118. package/dist/routes/health.js +1 -1
  119. package/dist/routes/jira.js +1 -1
  120. package/dist/routes/objective-management.js +1 -1
  121. package/dist/routes/password.js +1 -1
  122. package/dist/routes/prompt.js +1 -1
  123. package/dist/routes/provider-auth.js +1 -1
  124. package/dist/routes/qa.js +1 -1
  125. package/dist/routes/roles.js +1 -1
  126. package/dist/routes/settings.js +1 -1
  127. package/dist/routes/skill-management.js +1 -1
  128. package/dist/routes/skills.js +1 -1
  129. package/dist/routes/tasks.js +1 -1
  130. package/dist/routes/teams.js +1 -1
  131. package/dist/routes/templates.js +1 -1
  132. package/dist/routes/test-task.js +1 -1
  133. package/dist/routes/test.js +1 -1
  134. package/dist/routes/users.js +1 -1
  135. package/dist/routes/visualizations.js +1 -1
  136. package/dist/scripts/create-user.js +1 -1
  137. package/dist/scripts/migrate-config-to-data-dir.js +1 -1
  138. package/dist/start.js +1 -1
  139. package/dist/web-ui/public/activity-detail-modal.js +1 -1
  140. package/dist/web-ui/public/activity-feed.js +1 -1
  141. package/dist/web-ui/public/activity-formatters.js +1 -1
  142. package/dist/web-ui/public/agent-event-parser.js +1 -1
  143. package/dist/web-ui/public/app.js +1 -1
  144. package/dist/web-ui/public/approve-dialog.js +1 -1
  145. package/dist/web-ui/public/automation-links.js +1 -1
  146. package/dist/web-ui/public/automation-schedule.js +1 -1
  147. package/dist/web-ui/public/comments-widget.js +1 -1
  148. package/dist/web-ui/public/diff-utils.js +1 -1
  149. package/dist/web-ui/public/environments.css +21 -0
  150. package/dist/web-ui/public/environments.html +79 -9
  151. package/dist/web-ui/public/environments.js +1 -1
  152. package/dist/web-ui/public/feedback-widget.js +1 -1
  153. package/dist/web-ui/public/file-selection-tree.js +1 -1
  154. package/dist/web-ui/public/git-history-lazy-utils.js +1 -1
  155. package/dist/web-ui/public/git-history.js +1 -1
  156. package/dist/web-ui/public/git-status.js +1 -1
  157. package/dist/web-ui/public/ibmi-file-filter.js +1 -1
  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.js +1 -1
  169. package/dist/web-ui/public/setup-password.js +1 -1
  170. package/dist/web-ui/public/skills.js +1 -1
  171. package/dist/web-ui/public/sse-client.js +1 -1
  172. package/dist/web-ui/public/sse-shared-worker.js +1 -1
  173. package/dist/web-ui/public/styles.css +52 -1
  174. package/dist/web-ui/public/task-judging-helpers.js +1 -1
  175. package/dist/web-ui/public/task.html +43 -5
  176. package/dist/web-ui/public/task.js +1 -1
  177. package/dist/web-ui/public/teams.js +1 -1
  178. package/dist/web-ui/public/terminal.js +1 -1
  179. package/dist/web-ui/public/theme.js +1 -1
  180. package/dist/web-ui/public/users.js +1 -1
  181. package/dist/web-ui/public/variant-grouping.js +1 -1
  182. package/package.json +1 -1
@@ -1 +1 @@
1
- function isSharedWorkerSupported(){return typeof SharedWorker!=='undefined';}function eventTypeToHandler(_0x22ae55){if(_0x22ae55==='connected')return'onConnected';if(_0x22ae55==='error')return'onError';return'on'+_0x22ae55['split']('-')['map'](_0x4f1511=>_0x4f1511['charAt'](0x0)['toUpperCase']()+_0x4f1511['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'](_0x182249,_0x52fa31){return!this['listeners']['has'](_0x182249)&&this['listeners']['set'](_0x182249,new Set()),this['listeners']['get'](_0x182249)['add'](_0x52fa31),this;}['off'](_0x39c2b5,_0x4841cd){return this['listeners']['has'](_0x39c2b5)&&this['listeners']['get'](_0x39c2b5)['delete'](_0x4841cd),this;}['_emit'](_0x55dbeb,_0x312f59){this['listeners']['has'](_0x55dbeb)&&this['listeners']['get'](_0x55dbeb)['forEach'](_0x33431b=>{try{_0x33431b(_0x312f59);}catch(_0x579a20){console['error']('[SSE\x20Client]\x20Error\x20in\x20'+_0x55dbeb+'\x20listener:',_0x579a20);}});}['connect'](_0xef248d='me'){this['userId']=_0xef248d,this['useSharedWorker']?this['_connectViaWorker'](_0xef248d):this['_connectDirect'](_0xef248d);}['_connectViaWorker'](_0x180318){try{this['_ensureWorker'](),this['port']['postMessage']({'action':'connect','userId':_0x180318});}catch(_0x48636c){console['error']('[SSE\x20Client]\x20SharedWorker\x20failed,\x20falling\x20back\x20to\x20direct\x20SSE:',_0x48636c),this['useSharedWorker']=![],this['_connectDirect'](_0x180318);}}['_ensureWorker'](){!this['worker']&&(this['worker']=new SharedWorker('/sse-shared-worker.js'),this['port']=this['worker']['port'],this['port']['onmessage']=this['_handleWorkerMessage'],this['port']['onmessageerror']=_0x11296f=>{console['error']('[SSE\x20Client]\x20Worker\x20message\x20error:',_0x11296f),this['_emit']('error',{'error':'Worker\x20message\x20error'});},this['port']['start']());}['_handleWorkerMessage'](_0x4e0894){const _0x1e418c=_0x4e0894['data'];if(_0x1e418c['type']&&_0x1e418c['type']['startsWith']('task:')){this['_handleTaskStreamMessage'](_0x1e418c);return;}switch(_0x1e418c['type']){case'connected':this['connected']=!![],this['_emit']('connected',{});break;case'snapshot':case'activity':case'status':case'new-task':case'queue-position':try{const _0xa99e93=JSON['parse'](_0x1e418c['data']);this['_emit'](_0x1e418c['type'],_0xa99e93);}catch(_0x20f94c){console['error']('[SSE\x20Client]\x20Failed\x20to\x20parse\x20'+_0x1e418c['type']+'\x20data:',_0x20f94c);}break;case'error':this['connected']=![],this['_emit']('error',_0x1e418c);break;default:console['warn']('[SSE\x20Client]\x20Unknown\x20message\x20type:',_0x1e418c['type']);}}['_handleTaskStreamMessage'](_0x377cb5){const {taskId:_0x1ab021,type:_0x2dd734,data:_0x1eb999}=_0x377cb5,_0x106a01=this['_taskSubscriptions']['get'](_0x1ab021);if(!_0x106a01||_0x106a01['size']===0x0)return;const _0x48aada=_0x2dd734['replace']('task:',''),_0x28813e=eventTypeToHandler(_0x48aada);_0x106a01['forEach'](_0x380cb6=>{if(_0x380cb6['handlers'][_0x28813e])try{const _0x4a0498=typeof _0x1eb999==='string'?JSON['parse'](_0x1eb999):_0x1eb999;_0x380cb6['handlers'][_0x28813e](_0x4a0498);}catch(_0x293a31){console['error']('[SSE\x20Client]\x20Error\x20in\x20task\x20'+_0x48aada+'\x20handler:',_0x293a31);}});}['_connectDirect'](_0x330a06){this['eventSource']&&(this['eventSource']['close'](),this['eventSource']=null);const _0x5c4121=_0x330a06&&_0x330a06!=='me'?'?userId='+_0x330a06:'';try{this['eventSource']=new EventSource('/tasks/updates'+_0x5c4121),this['eventSource']['addEventListener']('open',()=>{this['connected']=!![],this['reconnectAttempts']=0x0,this['_emit']('connected',{});}),this['eventSource']['addEventListener']('snapshot',_0x271cce=>{this['_handleDirectSSE']('snapshot',_0x271cce),this['reconnectAttempts']=0x0;}),this['eventSource']['addEventListener']('activity',_0x55f6cc=>{this['_handleDirectSSE']('activity',_0x55f6cc);}),this['eventSource']['addEventListener']('status',_0x26408d=>{this['_handleDirectSSE']('status',_0x26408d);}),this['eventSource']['addEventListener']('new-task',_0x335164=>{this['_handleDirectSSE']('new-task',_0x335164);}),this['eventSource']['addEventListener']('queue-position',_0x4030cf=>{this['_handleDirectSSE']('queue-position',_0x4030cf);}),this['eventSource']['addEventListener']('error',_0x5d5269=>{console['error']('[SSE\x20Client]\x20Direct\x20SSE\x20error:',_0x5d5269),this['connected']=![],this['_emit']('error',{'error':'Connection\x20error'}),this['eventSource']&&(this['eventSource']['close'](),this['eventSource']=null),this['_scheduleReconnect']();});}catch(_0x1e863d){console['error']('[SSE\x20Client]\x20Failed\x20to\x20create\x20EventSource:',_0x1e863d),this['_emit']('error',{'error':_0x1e863d['message']}),this['_scheduleReconnect']();}}['_handleDirectSSE'](_0xfe15a5,_0x2a6ccd){try{const _0x55479a=JSON['parse'](_0x2a6ccd['data']);this['_emit'](_0xfe15a5,_0x55479a);}catch(_0x6936c9){console['error']('[SSE\x20Client]\x20Failed\x20to\x20parse\x20'+_0xfe15a5+'\x20data:',_0x6936c9);}}['_scheduleReconnect'](){this['reconnectTimeout']&&clearTimeout(this['reconnectTimeout']);const _0x1bd1a2=Math['min'](0x3e8*Math['pow'](0x2,this['reconnectAttempts']),0x7530);this['reconnectAttempts']++,console['log']('[SSE\x20Client]\x20Scheduling\x20reconnect\x20in\x20'+_0x1bd1a2+'ms'),this['reconnectTimeout']=setTimeout(()=>{this['_connectDirect'](this['userId']);},_0x1bd1a2);}['changeFilter'](_0x3aaa61){if(_0x3aaa61===this['userId'])return;this['userId']=_0x3aaa61;if(this['useSharedWorker']&&this['port'])this['port']['postMessage']({'action':'changeFilter','userId':_0x3aaa61});else this['eventSource']&&this['_connectDirect'](_0x3aaa61);}['subscribeTask'](_0x1e0fbe,_0x33fd02){return this['useSharedWorker']?this['_subscribeTaskViaWorker'](_0x1e0fbe,_0x33fd02):this['_subscribeTaskDirect'](_0x1e0fbe,_0x33fd02);}['unsubscribeTask'](_0x1909da){if(!_0x1909da)return;_0x1909da['type']==='worker'?this['_unsubscribeTaskWorker'](_0x1909da):this['_unsubscribeTaskDirect'](_0x1909da);}['_subscribeTaskViaWorker'](_0x1cd41e,_0xfc875d){try{this['_ensureWorker']();}catch(_0x3f93d6){return console['error']('[SSE\x20Client]\x20SharedWorker\x20failed\x20for\x20task\x20sub,\x20falling\x20back:',_0x3f93d6),this['useSharedWorker']=![],this['_subscribeTaskDirect'](_0x1cd41e,_0xfc875d);}const _0x31159b=++this['_taskSubIdCounter'],_0x3afb7e={'type':'worker','taskId':_0x1cd41e,'handlers':_0xfc875d,'id':_0x31159b};return!this['_taskSubscriptions']['has'](_0x1cd41e)&&(this['_taskSubscriptions']['set'](_0x1cd41e,new Set()),this['port']['postMessage']({'action':'subscribeTask','taskId':_0x1cd41e})),this['_taskSubscriptions']['get'](_0x1cd41e)['add'](_0x3afb7e),_0x3afb7e;}['_unsubscribeTaskWorker'](_0x4ddbda){const {taskId:_0x20edd3}=_0x4ddbda,_0x40a101=this['_taskSubscriptions']['get'](_0x20edd3);if(_0x40a101){_0x40a101['delete'](_0x4ddbda);if(_0x40a101['size']===0x0){this['_taskSubscriptions']['delete'](_0x20edd3);try{this['port']&&this['port']['postMessage']({'action':'unsubscribeTask','taskId':_0x20edd3});}catch(_0x108e9f){}}}}['_subscribeTaskDirect'](_0x21dbe6,_0x5c32e7){const _0x1a2aa1=++this['_taskSubIdCounter'],_0x28770c=new EventSource('/tasks/'+_0x21dbe6+'/stream'),_0x5373bb={'type':'direct','taskId':_0x21dbe6,'handlers':_0x5c32e7,'id':_0x1a2aa1,'eventSource':_0x28770c};!this['_taskSubscriptions']['has'](_0x21dbe6)&&this['_taskSubscriptions']['set'](_0x21dbe6,new Set());this['_taskSubscriptions']['get'](_0x21dbe6)['add'](_0x5373bb);for(const _0x1224d8 of TASK_STREAM_EVENTS){const _0x23feb6=eventTypeToHandler(_0x1224d8);_0x28770c['addEventListener'](_0x1224d8,_0x20182c=>{if(_0x5c32e7[_0x23feb6])try{const _0x969535=JSON['parse'](_0x20182c['data']);_0x5c32e7[_0x23feb6](_0x969535);}catch(_0x309f0d){console['error']('[SSE\x20Client]\x20Error\x20parsing\x20task\x20'+_0x1224d8+':',_0x309f0d);}});}return _0x28770c['addEventListener']('open',()=>{if(_0x5c32e7['onConnected'])_0x5c32e7['onConnected']();}),_0x28770c['addEventListener']('error',()=>{if(_0x5c32e7['onError'])_0x5c32e7['onError']({'error':'Connection\x20error'});}),_0x5373bb;}['_unsubscribeTaskDirect'](_0xc4a812){_0xc4a812['eventSource']&&(_0xc4a812['eventSource']['close'](),_0xc4a812['eventSource']=null);const _0x58b65e=this['_taskSubscriptions']['get'](_0xc4a812['taskId']);_0x58b65e&&(_0x58b65e['delete'](_0xc4a812),_0x58b65e['size']===0x0&&this['_taskSubscriptions']['delete'](_0xc4a812['taskId']));}['disconnect'](){this['reconnectTimeout']&&(clearTimeout(this['reconnectTimeout']),this['reconnectTimeout']=null);this['_taskSubscriptions']['forEach']((_0x3ae96b,_0x6490c0)=>{_0x3ae96b['forEach'](_0x520c2c=>{_0x520c2c['type']==='direct'&&_0x520c2c['eventSource']&&_0x520c2c['eventSource']['close']();});}),this['_taskSubscriptions']['clear']();if(this['useSharedWorker']&&this['port'])try{this['port']['postMessage']({'action':'disconnect'});}catch(_0x35c37d){}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(_0x584336){if(_0x584336==='connected')return'onConnected';if(_0x584336==='error')return'onError';return'on'+_0x584336['split']('-')['map'](_0x4540f6=>_0x4540f6['charAt'](0x0)['toUpperCase']()+_0x4540f6['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'](_0x141555,_0x21e33e){return!this['listeners']['has'](_0x141555)&&this['listeners']['set'](_0x141555,new Set()),this['listeners']['get'](_0x141555)['add'](_0x21e33e),this;}['off'](_0x31a848,_0x229eac){return this['listeners']['has'](_0x31a848)&&this['listeners']['get'](_0x31a848)['delete'](_0x229eac),this;}['_emit'](_0x1d62e8,_0x1172d9){this['listeners']['has'](_0x1d62e8)&&this['listeners']['get'](_0x1d62e8)['forEach'](_0x4b8d94=>{try{_0x4b8d94(_0x1172d9);}catch(_0x2af304){console['error']('[SSE\x20Client]\x20Error\x20in\x20'+_0x1d62e8+'\x20listener:',_0x2af304);}});}['connect'](_0xd2d90e='me'){this['userId']=_0xd2d90e,this['useSharedWorker']?this['_connectViaWorker'](_0xd2d90e):this['_connectDirect'](_0xd2d90e);}['_connectViaWorker'](_0x2e6045){try{this['_ensureWorker'](),this['port']['postMessage']({'action':'connect','userId':_0x2e6045});}catch(_0x3519f5){console['error']('[SSE\x20Client]\x20SharedWorker\x20failed,\x20falling\x20back\x20to\x20direct\x20SSE:',_0x3519f5),this['useSharedWorker']=![],this['_connectDirect'](_0x2e6045);}}['_ensureWorker'](){!this['worker']&&(this['worker']=new SharedWorker('/sse-shared-worker.js'),this['port']=this['worker']['port'],this['port']['onmessage']=this['_handleWorkerMessage'],this['port']['onmessageerror']=_0x594540=>{console['error']('[SSE\x20Client]\x20Worker\x20message\x20error:',_0x594540),this['_emit']('error',{'error':'Worker\x20message\x20error'});},this['port']['start']());}['_handleWorkerMessage'](_0x408fb0){const _0x53905b=_0x408fb0['data'];if(_0x53905b['type']&&_0x53905b['type']['startsWith']('task:')){this['_handleTaskStreamMessage'](_0x53905b);return;}switch(_0x53905b['type']){case'connected':this['connected']=!![],this['_emit']('connected',{});break;case'snapshot':case'activity':case'status':case'new-task':case'queue-position':try{const _0x577dfa=JSON['parse'](_0x53905b['data']);this['_emit'](_0x53905b['type'],_0x577dfa);}catch(_0x2ce780){console['error']('[SSE\x20Client]\x20Failed\x20to\x20parse\x20'+_0x53905b['type']+'\x20data:',_0x2ce780);}break;case'error':this['connected']=![],this['_emit']('error',_0x53905b);break;default:console['warn']('[SSE\x20Client]\x20Unknown\x20message\x20type:',_0x53905b['type']);}}['_handleTaskStreamMessage'](_0x373362){const {taskId:_0x22381f,type:_0x5a9ac3,data:_0x5cccc2}=_0x373362,_0x58699f=this['_taskSubscriptions']['get'](_0x22381f);if(!_0x58699f||_0x58699f['size']===0x0)return;const _0x1d9f88=_0x5a9ac3['replace']('task:',''),_0x53ad22=eventTypeToHandler(_0x1d9f88);_0x58699f['forEach'](_0x527daf=>{if(_0x527daf['handlers'][_0x53ad22])try{const _0x1b7097=typeof _0x5cccc2==='string'?JSON['parse'](_0x5cccc2):_0x5cccc2;_0x527daf['handlers'][_0x53ad22](_0x1b7097);}catch(_0x3774a4){console['error']('[SSE\x20Client]\x20Error\x20in\x20task\x20'+_0x1d9f88+'\x20handler:',_0x3774a4);}});}['_connectDirect'](_0x1ae580){this['eventSource']&&(this['eventSource']['close'](),this['eventSource']=null);const _0x2c126d=_0x1ae580&&_0x1ae580!=='me'?'?userId='+_0x1ae580:'';try{this['eventSource']=new EventSource('/tasks/updates'+_0x2c126d),this['eventSource']['addEventListener']('open',()=>{this['connected']=!![],this['reconnectAttempts']=0x0,this['_emit']('connected',{});}),this['eventSource']['addEventListener']('snapshot',_0x17b386=>{this['_handleDirectSSE']('snapshot',_0x17b386),this['reconnectAttempts']=0x0;}),this['eventSource']['addEventListener']('activity',_0x1bd235=>{this['_handleDirectSSE']('activity',_0x1bd235);}),this['eventSource']['addEventListener']('status',_0x7d99fa=>{this['_handleDirectSSE']('status',_0x7d99fa);}),this['eventSource']['addEventListener']('new-task',_0x45e631=>{this['_handleDirectSSE']('new-task',_0x45e631);}),this['eventSource']['addEventListener']('queue-position',_0x4ba101=>{this['_handleDirectSSE']('queue-position',_0x4ba101);}),this['eventSource']['addEventListener']('error',_0x5d24ab=>{console['error']('[SSE\x20Client]\x20Direct\x20SSE\x20error:',_0x5d24ab),this['connected']=![],this['_emit']('error',{'error':'Connection\x20error'}),this['eventSource']&&(this['eventSource']['close'](),this['eventSource']=null),this['_scheduleReconnect']();});}catch(_0xff8b8b){console['error']('[SSE\x20Client]\x20Failed\x20to\x20create\x20EventSource:',_0xff8b8b),this['_emit']('error',{'error':_0xff8b8b['message']}),this['_scheduleReconnect']();}}['_handleDirectSSE'](_0x4462fc,_0x50b06b){try{const _0x4ca24c=JSON['parse'](_0x50b06b['data']);this['_emit'](_0x4462fc,_0x4ca24c);}catch(_0x4575d5){console['error']('[SSE\x20Client]\x20Failed\x20to\x20parse\x20'+_0x4462fc+'\x20data:',_0x4575d5);}}['_scheduleReconnect'](){this['reconnectTimeout']&&clearTimeout(this['reconnectTimeout']);const _0x4cce6a=Math['min'](0x3e8*Math['pow'](0x2,this['reconnectAttempts']),0x7530);this['reconnectAttempts']++,console['log']('[SSE\x20Client]\x20Scheduling\x20reconnect\x20in\x20'+_0x4cce6a+'ms'),this['reconnectTimeout']=setTimeout(()=>{this['_connectDirect'](this['userId']);},_0x4cce6a);}['changeFilter'](_0xcd22d2){if(_0xcd22d2===this['userId'])return;this['userId']=_0xcd22d2;if(this['useSharedWorker']&&this['port'])this['port']['postMessage']({'action':'changeFilter','userId':_0xcd22d2});else this['eventSource']&&this['_connectDirect'](_0xcd22d2);}['subscribeTask'](_0x22bc2f,_0x2aae4d){return this['useSharedWorker']?this['_subscribeTaskViaWorker'](_0x22bc2f,_0x2aae4d):this['_subscribeTaskDirect'](_0x22bc2f,_0x2aae4d);}['unsubscribeTask'](_0x338289){if(!_0x338289)return;_0x338289['type']==='worker'?this['_unsubscribeTaskWorker'](_0x338289):this['_unsubscribeTaskDirect'](_0x338289);}['_subscribeTaskViaWorker'](_0x502052,_0x18bc3e){try{this['_ensureWorker']();}catch(_0x1f296a){return console['error']('[SSE\x20Client]\x20SharedWorker\x20failed\x20for\x20task\x20sub,\x20falling\x20back:',_0x1f296a),this['useSharedWorker']=![],this['_subscribeTaskDirect'](_0x502052,_0x18bc3e);}const _0x5a4992=++this['_taskSubIdCounter'],_0x3dba4c={'type':'worker','taskId':_0x502052,'handlers':_0x18bc3e,'id':_0x5a4992};return!this['_taskSubscriptions']['has'](_0x502052)&&(this['_taskSubscriptions']['set'](_0x502052,new Set()),this['port']['postMessage']({'action':'subscribeTask','taskId':_0x502052})),this['_taskSubscriptions']['get'](_0x502052)['add'](_0x3dba4c),_0x3dba4c;}['_unsubscribeTaskWorker'](_0x46e0c9){const {taskId:_0x21f193}=_0x46e0c9,_0x556043=this['_taskSubscriptions']['get'](_0x21f193);if(_0x556043){_0x556043['delete'](_0x46e0c9);if(_0x556043['size']===0x0){this['_taskSubscriptions']['delete'](_0x21f193);try{this['port']&&this['port']['postMessage']({'action':'unsubscribeTask','taskId':_0x21f193});}catch(_0x2498cf){}}}}['_subscribeTaskDirect'](_0x310572,_0x2ef8a3){const _0x2add16=++this['_taskSubIdCounter'],_0x15b552=new EventSource('/tasks/'+_0x310572+'/stream'),_0x4041ea={'type':'direct','taskId':_0x310572,'handlers':_0x2ef8a3,'id':_0x2add16,'eventSource':_0x15b552};!this['_taskSubscriptions']['has'](_0x310572)&&this['_taskSubscriptions']['set'](_0x310572,new Set());this['_taskSubscriptions']['get'](_0x310572)['add'](_0x4041ea);for(const _0x45bec1 of TASK_STREAM_EVENTS){const _0x332be6=eventTypeToHandler(_0x45bec1);_0x15b552['addEventListener'](_0x45bec1,_0x5556c5=>{if(_0x2ef8a3[_0x332be6])try{const _0x4be075=JSON['parse'](_0x5556c5['data']);_0x2ef8a3[_0x332be6](_0x4be075);}catch(_0x3e231d){console['error']('[SSE\x20Client]\x20Error\x20parsing\x20task\x20'+_0x45bec1+':',_0x3e231d);}});}return _0x15b552['addEventListener']('open',()=>{if(_0x2ef8a3['onConnected'])_0x2ef8a3['onConnected']();}),_0x15b552['addEventListener']('error',()=>{if(_0x2ef8a3['onError'])_0x2ef8a3['onError']({'error':'Connection\x20error'});}),_0x4041ea;}['_unsubscribeTaskDirect'](_0x432fab){_0x432fab['eventSource']&&(_0x432fab['eventSource']['close'](),_0x432fab['eventSource']=null);const _0x99c1f7=this['_taskSubscriptions']['get'](_0x432fab['taskId']);_0x99c1f7&&(_0x99c1f7['delete'](_0x432fab),_0x99c1f7['size']===0x0&&this['_taskSubscriptions']['delete'](_0x432fab['taskId']));}['disconnect'](){this['reconnectTimeout']&&(clearTimeout(this['reconnectTimeout']),this['reconnectTimeout']=null);this['_taskSubscriptions']['forEach']((_0x232446,_0x2ce5c2)=>{_0x232446['forEach'](_0x2d39c4=>{_0x2d39c4['type']==='direct'&&_0x2d39c4['eventSource']&&_0x2d39c4['eventSource']['close']();});}),this['_taskSubscriptions']['clear']();if(this['useSharedWorker']&&this['port'])try{this['port']['postMessage']({'action':'disconnect'});}catch(_0x97d6f7){}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(_0x171e79){eventSource&&currentUserId!==_0x171e79&&(eventSource['close'](),eventSource=null);if(eventSource&&eventSource['readyState']!==EventSource['CLOSED'])return;currentUserId=_0x171e79;const _0x3c9e82=_0x171e79&&_0x171e79!=='me'?'?userId='+_0x171e79:'';try{eventSource=new EventSource('/tasks/updates'+_0x3c9e82),eventSource['addEventListener']('snapshot',_0x16b9e5=>{broadcast({'type':'snapshot','data':_0x16b9e5['data']}),reconnectAttempts=0x0;}),eventSource['addEventListener']('activity',_0x146267=>{broadcast({'type':'activity','data':_0x146267['data']});}),eventSource['addEventListener']('status',_0xeb11e4=>{broadcast({'type':'status','data':_0xeb11e4['data']});}),eventSource['addEventListener']('new-task',_0x3995af=>{broadcast({'type':'new-task','data':_0x3995af['data']});}),eventSource['addEventListener']('queue-position',_0x224051=>{broadcast({'type':'queue-position','data':_0x224051['data']});}),eventSource['addEventListener']('open',()=>{broadcast({'type':'connected'}),reconnectAttempts=0x0;}),eventSource['addEventListener']('error',_0x2bf13e=>{console['error']('[SSE\x20Worker]\x20Connection\x20error:',_0x2bf13e),broadcast({'type':'error','error':'Connection\x20error'}),eventSource&&(eventSource['close'](),eventSource=null),scheduleReconnect();});}catch(_0x252bdf){console['error']('[SSE\x20Worker]\x20Failed\x20to\x20create\x20EventSource:',_0x252bdf),broadcast({'type':'error','error':_0x252bdf['message']}),scheduleReconnect();}}function scheduleReconnect(){reconnectTimeout&&clearTimeout(reconnectTimeout);if(ports['size']===0x0)return;const _0x495468=Math['min'](0x3e8*Math['pow'](0x2,reconnectAttempts),MAX_RECONNECT_DELAY);reconnectAttempts++,console['log']('[SSE\x20Worker]\x20Scheduling\x20reconnect\x20in\x20'+_0x495468+'ms\x20(attempt\x20'+reconnectAttempts+')'),reconnectTimeout=setTimeout(()=>{ports['size']>0x0&&connect(currentUserId);},_0x495468);}function broadcast(_0x8261fb){const _0x4fc413=[];ports['forEach'](_0x4fc64a=>{try{_0x4fc64a['postMessage'](_0x8261fb);}catch(_0x415dbb){console['warn']('[SSE\x20Worker]\x20Failed\x20to\x20send\x20to\x20port,\x20removing:',_0x415dbb),_0x4fc413['push'](_0x4fc64a);}}),_0x4fc413['length']>0x0&&cleanUpDeadPorts(_0x4fc413),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(_0x578c2a,_0x196882){let _0x456626=taskStreams['get'](_0x196882);!_0x456626&&(_0x456626={'eventSource':null,'reconnectTimeout':null,'reconnectAttempts':0x0,'subscribedPorts':new Set()},taskStreams['set'](_0x196882,_0x456626));_0x456626['subscribedPorts']['add'](_0x578c2a);if(!_0x456626['eventSource']||_0x456626['eventSource']['readyState']===EventSource['CLOSED'])connectTaskStream(_0x196882);else{if(_0x456626['eventSource']['readyState']===EventSource['OPEN'])try{_0x578c2a['postMessage']({'type':'task:connected','taskId':_0x196882});}catch(_0xd3d648){}}}function unsubscribeTask(_0x29fff0,_0x5135c4){const _0x2a3522=taskStreams['get'](_0x5135c4);if(!_0x2a3522)return;_0x2a3522['subscribedPorts']['delete'](_0x29fff0),_0x2a3522['subscribedPorts']['size']===0x0&&deferredCloseTaskStream(_0x5135c4);}function connectTaskStream(_0x488eea){const _0x398f78=taskStreams['get'](_0x488eea);if(!_0x398f78)return;_0x398f78['eventSource']&&(_0x398f78['eventSource']['close'](),_0x398f78['eventSource']=null);try{_0x398f78['eventSource']=new EventSource('/tasks/'+_0x488eea+'/stream');for(const _0x42a225 of TASK_STREAM_EVENTS){_0x398f78['eventSource']['addEventListener'](_0x42a225,_0x4a1adc=>{broadcastToTask(_0x488eea,'task:'+_0x42a225,_0x4a1adc['data']),_0x398f78['reconnectAttempts']=0x0;});}_0x398f78['eventSource']['addEventListener']('open',()=>{broadcastToTask(_0x488eea,'task:connected','{}'),_0x398f78['reconnectAttempts']=0x0;}),_0x398f78['eventSource']['addEventListener']('error',()=>{broadcastToTask(_0x488eea,'task:error',JSON['stringify']({'error':'Connection\x20error'})),_0x398f78['eventSource']&&(_0x398f78['eventSource']['close'](),_0x398f78['eventSource']=null),scheduleTaskReconnect(_0x488eea);});}catch(_0x19b165){console['error']('[SSE\x20Worker]\x20Failed\x20to\x20create\x20task\x20EventSource\x20for\x20'+_0x488eea+':',_0x19b165),broadcastToTask(_0x488eea,'task:error',JSON['stringify']({'error':_0x19b165['message']})),scheduleTaskReconnect(_0x488eea);}}function broadcastToTask(_0x2f72f1,_0x1b95da,_0xc44143){const _0x100418=taskStreams['get'](_0x2f72f1);if(!_0x100418)return;const _0x197d3e=[];_0x100418['subscribedPorts']['forEach'](_0x500408=>{try{_0x500408['postMessage']({'type':_0x1b95da,'taskId':_0x2f72f1,'data':_0xc44143});}catch(_0x3a7004){_0x197d3e['push'](_0x500408);}}),_0x197d3e['length']>0x0&&(_0x197d3e['forEach'](_0x11dac3=>_0x100418['subscribedPorts']['delete'](_0x11dac3)),cleanUpDeadPorts(_0x197d3e),_0x100418['subscribedPorts']['size']===0x0&&closeTaskStream(_0x2f72f1));}function closeTaskStream(_0x5a2b28){const _0x64a9a6=taskStreams['get'](_0x5a2b28);if(!_0x64a9a6)return;_0x64a9a6['eventSource']&&_0x64a9a6['eventSource']['close'](),_0x64a9a6['reconnectTimeout']&&clearTimeout(_0x64a9a6['reconnectTimeout']),taskStreams['delete'](_0x5a2b28);}function deferredCloseTaskStream(_0x1e0b6b){setTimeout(()=>{const _0x5486a0=taskStreams['get'](_0x1e0b6b);_0x5486a0&&_0x5486a0['subscribedPorts']['size']===0x0&&closeTaskStream(_0x1e0b6b);},0x0);}function scheduleTaskReconnect(_0x1d013b){const _0x128bc9=taskStreams['get'](_0x1d013b);if(!_0x128bc9||_0x128bc9['subscribedPorts']['size']===0x0)return;_0x128bc9['reconnectTimeout']&&clearTimeout(_0x128bc9['reconnectTimeout']);const _0x47d2cb=Math['min'](0x3e8*Math['pow'](0x2,_0x128bc9['reconnectAttempts']),MAX_RECONNECT_DELAY);_0x128bc9['reconnectAttempts']++,console['log']('[SSE\x20Worker]\x20Scheduling\x20task\x20stream\x20reconnect\x20for\x20'+_0x1d013b+'\x20in\x20'+_0x47d2cb+'ms'),_0x128bc9['reconnectTimeout']=setTimeout(()=>{_0x128bc9['subscribedPorts']['size']>0x0&&connectTaskStream(_0x1d013b);},_0x47d2cb);}function cleanUpDeadPorts(_0x4f866d){for(const _0x201eea of _0x4f866d){ports['delete'](_0x201eea),taskStreams['forEach']((_0xd41e4f,_0x18d3e6)=>{_0xd41e4f['subscribedPorts']['delete'](_0x201eea),_0xd41e4f['subscribedPorts']['size']===0x0&&closeTaskStream(_0x18d3e6);});}}function removePortFromAllTasks(_0x5a85df){taskStreams['forEach']((_0x3c73ba,_0x25aac3)=>{_0x3c73ba['subscribedPorts']['has'](_0x5a85df)&&(_0x3c73ba['subscribedPorts']['delete'](_0x5a85df),_0x3c73ba['subscribedPorts']['size']===0x0&&closeTaskStream(_0x25aac3));});}self['onconnect']=function(_0x3bc674){const _0xc1a754=_0x3bc674['ports'][0x0];ports['add'](_0xc1a754),console['log']('[SSE\x20Worker]\x20New\x20port\x20connected.\x20Total\x20ports:\x20'+ports['size']),_0xc1a754['onmessage']=function(_0x2cdd22){const {action:_0x45581c,userId:_0x2bb268,taskId:_0x1812fb}=_0x2cdd22['data'];switch(_0x45581c){case'connect':connect(_0x2bb268);eventSource&&eventSource['readyState']===EventSource['OPEN']&&_0xc1a754['postMessage']({'type':'connected'});break;case'disconnect':ports['delete'](_0xc1a754),removePortFromAllTasks(_0xc1a754),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':_0x2bb268!==currentUserId&&connect(_0x2bb268);break;case'subscribeTask':subscribeTask(_0xc1a754,_0x1812fb);break;case'unsubscribeTask':unsubscribeTask(_0xc1a754,_0x1812fb);break;default:console['warn']('[SSE\x20Worker]\x20Unknown\x20action:',_0x45581c);}},_0xc1a754['onmessageerror']=function(_0x3ff9c6){console['error']('[SSE\x20Worker]\x20Port\x20message\x20error:',_0x3ff9c6),ports['delete'](_0xc1a754),removePortFromAllTasks(_0xc1a754);},_0xc1a754['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(_0x336562){eventSource&&currentUserId!==_0x336562&&(eventSource['close'](),eventSource=null);if(eventSource&&eventSource['readyState']!==EventSource['CLOSED'])return;currentUserId=_0x336562;const _0x380480=_0x336562&&_0x336562!=='me'?'?userId='+_0x336562:'';try{eventSource=new EventSource('/tasks/updates'+_0x380480),eventSource['addEventListener']('snapshot',_0x21a038=>{broadcast({'type':'snapshot','data':_0x21a038['data']}),reconnectAttempts=0x0;}),eventSource['addEventListener']('activity',_0xb9bc89=>{broadcast({'type':'activity','data':_0xb9bc89['data']});}),eventSource['addEventListener']('status',_0x118272=>{broadcast({'type':'status','data':_0x118272['data']});}),eventSource['addEventListener']('new-task',_0x4fb5e1=>{broadcast({'type':'new-task','data':_0x4fb5e1['data']});}),eventSource['addEventListener']('queue-position',_0x1ae028=>{broadcast({'type':'queue-position','data':_0x1ae028['data']});}),eventSource['addEventListener']('open',()=>{broadcast({'type':'connected'}),reconnectAttempts=0x0;}),eventSource['addEventListener']('error',_0x4be801=>{console['error']('[SSE\x20Worker]\x20Connection\x20error:',_0x4be801),broadcast({'type':'error','error':'Connection\x20error'}),eventSource&&(eventSource['close'](),eventSource=null),scheduleReconnect();});}catch(_0x3d2177){console['error']('[SSE\x20Worker]\x20Failed\x20to\x20create\x20EventSource:',_0x3d2177),broadcast({'type':'error','error':_0x3d2177['message']}),scheduleReconnect();}}function scheduleReconnect(){reconnectTimeout&&clearTimeout(reconnectTimeout);if(ports['size']===0x0)return;const _0xc63027=Math['min'](0x3e8*Math['pow'](0x2,reconnectAttempts),MAX_RECONNECT_DELAY);reconnectAttempts++,console['log']('[SSE\x20Worker]\x20Scheduling\x20reconnect\x20in\x20'+_0xc63027+'ms\x20(attempt\x20'+reconnectAttempts+')'),reconnectTimeout=setTimeout(()=>{ports['size']>0x0&&connect(currentUserId);},_0xc63027);}function broadcast(_0x436770){const _0x235fca=[];ports['forEach'](_0x2560f2=>{try{_0x2560f2['postMessage'](_0x436770);}catch(_0x338078){console['warn']('[SSE\x20Worker]\x20Failed\x20to\x20send\x20to\x20port,\x20removing:',_0x338078),_0x235fca['push'](_0x2560f2);}}),_0x235fca['length']>0x0&&cleanUpDeadPorts(_0x235fca),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(_0x74a86,_0x2275b4){let _0x36f6ea=taskStreams['get'](_0x2275b4);!_0x36f6ea&&(_0x36f6ea={'eventSource':null,'reconnectTimeout':null,'reconnectAttempts':0x0,'subscribedPorts':new Set()},taskStreams['set'](_0x2275b4,_0x36f6ea));_0x36f6ea['subscribedPorts']['add'](_0x74a86);if(!_0x36f6ea['eventSource']||_0x36f6ea['eventSource']['readyState']===EventSource['CLOSED'])connectTaskStream(_0x2275b4);else{if(_0x36f6ea['eventSource']['readyState']===EventSource['OPEN'])try{_0x74a86['postMessage']({'type':'task:connected','taskId':_0x2275b4});}catch(_0xa4e375){}}}function unsubscribeTask(_0x14def9,_0x2f2e79){const _0x3d2318=taskStreams['get'](_0x2f2e79);if(!_0x3d2318)return;_0x3d2318['subscribedPorts']['delete'](_0x14def9),_0x3d2318['subscribedPorts']['size']===0x0&&deferredCloseTaskStream(_0x2f2e79);}function connectTaskStream(_0x59a458){const _0x3cc620=taskStreams['get'](_0x59a458);if(!_0x3cc620)return;_0x3cc620['eventSource']&&(_0x3cc620['eventSource']['close'](),_0x3cc620['eventSource']=null);try{_0x3cc620['eventSource']=new EventSource('/tasks/'+_0x59a458+'/stream');for(const _0x34c1c9 of TASK_STREAM_EVENTS){_0x3cc620['eventSource']['addEventListener'](_0x34c1c9,_0x564eca=>{broadcastToTask(_0x59a458,'task:'+_0x34c1c9,_0x564eca['data']),_0x3cc620['reconnectAttempts']=0x0;});}_0x3cc620['eventSource']['addEventListener']('open',()=>{broadcastToTask(_0x59a458,'task:connected','{}'),_0x3cc620['reconnectAttempts']=0x0;}),_0x3cc620['eventSource']['addEventListener']('error',()=>{broadcastToTask(_0x59a458,'task:error',JSON['stringify']({'error':'Connection\x20error'})),_0x3cc620['eventSource']&&(_0x3cc620['eventSource']['close'](),_0x3cc620['eventSource']=null),scheduleTaskReconnect(_0x59a458);});}catch(_0x5f4a54){console['error']('[SSE\x20Worker]\x20Failed\x20to\x20create\x20task\x20EventSource\x20for\x20'+_0x59a458+':',_0x5f4a54),broadcastToTask(_0x59a458,'task:error',JSON['stringify']({'error':_0x5f4a54['message']})),scheduleTaskReconnect(_0x59a458);}}function broadcastToTask(_0x364a58,_0x80ed6,_0x4f4bf6){const _0x3d870c=taskStreams['get'](_0x364a58);if(!_0x3d870c)return;const _0x8b92a0=[];_0x3d870c['subscribedPorts']['forEach'](_0x53dcac=>{try{_0x53dcac['postMessage']({'type':_0x80ed6,'taskId':_0x364a58,'data':_0x4f4bf6});}catch(_0x2a6471){_0x8b92a0['push'](_0x53dcac);}}),_0x8b92a0['length']>0x0&&(_0x8b92a0['forEach'](_0x387b56=>_0x3d870c['subscribedPorts']['delete'](_0x387b56)),cleanUpDeadPorts(_0x8b92a0),_0x3d870c['subscribedPorts']['size']===0x0&&closeTaskStream(_0x364a58));}function closeTaskStream(_0x77f8c8){const _0x14095c=taskStreams['get'](_0x77f8c8);if(!_0x14095c)return;_0x14095c['eventSource']&&_0x14095c['eventSource']['close'](),_0x14095c['reconnectTimeout']&&clearTimeout(_0x14095c['reconnectTimeout']),taskStreams['delete'](_0x77f8c8);}function deferredCloseTaskStream(_0xba7000){setTimeout(()=>{const _0x2dc569=taskStreams['get'](_0xba7000);_0x2dc569&&_0x2dc569['subscribedPorts']['size']===0x0&&closeTaskStream(_0xba7000);},0x0);}function scheduleTaskReconnect(_0x344c08){const _0x412474=taskStreams['get'](_0x344c08);if(!_0x412474||_0x412474['subscribedPorts']['size']===0x0)return;_0x412474['reconnectTimeout']&&clearTimeout(_0x412474['reconnectTimeout']);const _0x243bc7=Math['min'](0x3e8*Math['pow'](0x2,_0x412474['reconnectAttempts']),MAX_RECONNECT_DELAY);_0x412474['reconnectAttempts']++,console['log']('[SSE\x20Worker]\x20Scheduling\x20task\x20stream\x20reconnect\x20for\x20'+_0x344c08+'\x20in\x20'+_0x243bc7+'ms'),_0x412474['reconnectTimeout']=setTimeout(()=>{_0x412474['subscribedPorts']['size']>0x0&&connectTaskStream(_0x344c08);},_0x243bc7);}function cleanUpDeadPorts(_0xaa0bd3){for(const _0x8e6088 of _0xaa0bd3){ports['delete'](_0x8e6088),taskStreams['forEach']((_0x10ee9b,_0xa6187e)=>{_0x10ee9b['subscribedPorts']['delete'](_0x8e6088),_0x10ee9b['subscribedPorts']['size']===0x0&&closeTaskStream(_0xa6187e);});}}function removePortFromAllTasks(_0x23cd7c){taskStreams['forEach']((_0x5b4213,_0x4185be)=>{_0x5b4213['subscribedPorts']['has'](_0x23cd7c)&&(_0x5b4213['subscribedPorts']['delete'](_0x23cd7c),_0x5b4213['subscribedPorts']['size']===0x0&&closeTaskStream(_0x4185be));});}self['onconnect']=function(_0x5089d0){const _0x535e85=_0x5089d0['ports'][0x0];ports['add'](_0x535e85),console['log']('[SSE\x20Worker]\x20New\x20port\x20connected.\x20Total\x20ports:\x20'+ports['size']),_0x535e85['onmessage']=function(_0x340dbe){const {action:_0x1973df,userId:_0x186f6e,taskId:_0x12eb6}=_0x340dbe['data'];switch(_0x1973df){case'connect':connect(_0x186f6e);eventSource&&eventSource['readyState']===EventSource['OPEN']&&_0x535e85['postMessage']({'type':'connected'});break;case'disconnect':ports['delete'](_0x535e85),removePortFromAllTasks(_0x535e85),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':_0x186f6e!==currentUserId&&connect(_0x186f6e);break;case'subscribeTask':subscribeTask(_0x535e85,_0x12eb6);break;case'unsubscribeTask':unsubscribeTask(_0x535e85,_0x12eb6);break;default:console['warn']('[SSE\x20Worker]\x20Unknown\x20action:',_0x1973df);}},_0x535e85['onmessageerror']=function(_0x1c5bb5){console['error']('[SSE\x20Worker]\x20Port\x20message\x20error:',_0x1c5bb5),ports['delete'](_0x535e85),removePortFromAllTasks(_0x535e85);},_0x535e85['start']();};
@@ -21263,6 +21263,14 @@ body.file-browser-open .file-browser-side-trigger {
21263
21263
  flex-shrink: 0;
21264
21264
  }
21265
21265
 
21266
+ .file-browser-new-folder-btn {
21267
+ flex-shrink: 0;
21268
+ }
21269
+
21270
+ .file-browser-header-icon-btn {
21271
+ flex-shrink: 0;
21272
+ }
21273
+
21266
21274
  .file-browser-breadcrumb {
21267
21275
  padding: 8px 16px;
21268
21276
  font-size: 12px;
@@ -21327,6 +21335,11 @@ body.file-browser-open .file-browser-side-trigger {
21327
21335
  font-size: 13px;
21328
21336
  }
21329
21337
 
21338
+ .file-browser-row {
21339
+ display: flex;
21340
+ align-items: center;
21341
+ }
21342
+
21330
21343
  .file-browser-entry {
21331
21344
  display: flex;
21332
21345
  align-items: center;
@@ -21337,10 +21350,11 @@ body.file-browser-open .file-browser-side-trigger {
21337
21350
  cursor: pointer;
21338
21351
  border: none;
21339
21352
  background: none;
21340
- width: 100%;
21353
+ flex: 1;
21341
21354
  text-align: left;
21342
21355
  font-family: inherit;
21343
21356
  transition: background 0.1s ease;
21357
+ min-width: 0;
21344
21358
  }
21345
21359
 
21346
21360
  .file-browser-entry:hover {
@@ -21376,6 +21390,34 @@ body.file-browser-open .file-browser-side-trigger {
21376
21390
  flex-shrink: 0;
21377
21391
  }
21378
21392
 
21393
+ .file-browser-entry-actions {
21394
+ display: flex;
21395
+ align-items: center;
21396
+ gap: 4px;
21397
+ padding-right: 10px;
21398
+ opacity: 0;
21399
+ pointer-events: none;
21400
+ transition: opacity 0.12s ease;
21401
+ }
21402
+
21403
+ .file-browser-row:hover .file-browser-entry-actions,
21404
+ .file-browser-entry-actions:focus-within {
21405
+ opacity: 1;
21406
+ pointer-events: auto;
21407
+ }
21408
+
21409
+ .file-browser-entry-action {
21410
+ color: var(--color-text-muted);
21411
+ }
21412
+
21413
+ .file-browser-entry-action:hover {
21414
+ color: var(--color-text);
21415
+ }
21416
+
21417
+ .file-browser-entry-action.file-browser-entry-delete:hover {
21418
+ color: var(--color-danger);
21419
+ }
21420
+
21379
21421
  /* File viewer pane */
21380
21422
  .file-browser-viewer-pane {
21381
21423
  border-top: 1px solid var(--color-border);
@@ -21660,9 +21702,18 @@ body.file-browser-open .file-browser-side-trigger {
21660
21702
 
21661
21703
  /* Mobile responsive */
21662
21704
  @media (max-width: 768px) {
21705
+ .file-browser-panel-header {
21706
+ flex-wrap: wrap;
21707
+ }
21708
+
21663
21709
  .file-browser-panel {
21664
21710
  width: 100vw;
21665
21711
  max-width: 100vw;
21666
21712
  }
21667
21713
 
21714
+ .file-browser-entry-actions {
21715
+ opacity: 1;
21716
+ pointer-events: auto;
21717
+ }
21718
+
21668
21719
  }
@@ -1 +1 @@
1
- export function toDisplayAgentName(_0x1b7ab7,{fallback:fallback='Unknown'}={}){const _0x27b7aa=String(_0x1b7ab7||'')['trim']()['toLowerCase']();if(!_0x27b7aa)return fallback;return _0x27b7aa['charAt'](0x0)['toUpperCase']()+_0x27b7aa['slice'](0x1);}export function escapeRegExp(_0x34ca03){return String(_0x34ca03)['replace'](/[.*+?^${}()|[\]\\]/g,'\x5c$&');}export function compareJudgmentsForAliasOrder(_0x351265,_0x499a96){const _0x1eff0b=String(_0x351265?.['createdAt']||''),_0x12f34d=String(_0x499a96?.['createdAt']||'');if(_0x1eff0b!==_0x12f34d)return _0x1eff0b['localeCompare'](_0x12f34d);return String(_0x351265?.['taskId']||'')['localeCompare'](String(_0x499a96?.['taskId']||''));}export function parseJudgeAliasNumber(_0x24b364,_0x325773){const _0x48fd17=typeof _0x24b364==='string'?_0x24b364['trim']():'',_0x5d14af=toDisplayAgentName(_0x325773,{'fallback':''});if(!_0x48fd17||!_0x5d14af)return null;const _0x44604d=_0x48fd17['toLowerCase'](),_0x3db408=_0x5d14af['toLowerCase']();if(_0x44604d===_0x3db408||_0x44604d===_0x3db408+'\x20judge')return 0x1;const _0x13bf69=[new RegExp('^'+escapeRegExp(_0x5d14af)+'\x5cs+(\x5cd+)$','i'),new RegExp('^'+escapeRegExp(_0x5d14af)+'\x5cs+Judge\x5cs+(\x5cd+)$','i')];for(const _0x199f76 of _0x13bf69){const _0x55f2e9=_0x48fd17['match'](_0x199f76);if(_0x55f2e9){const _0x5f1509=Number(_0x55f2e9[0x1]);if(Number['isInteger'](_0x5f1509)&&_0x5f1509>0x0)return _0x5f1509;}}return null;}export function formatJudgeDisplayName({alias:_0x2f8370,agent:_0x5368a8,number:number=null,hasDuplicates:hasDuplicates=![]}={}){const _0x1db9d2=toDisplayAgentName(_0x5368a8,{'fallback':'Judge'}),_0x39099b=typeof _0x2f8370==='string'?_0x2f8370['trim']():'';if(Number['isInteger'](number)&&number>0x0)return _0x1db9d2+'\x20Judge\x20'+number;if(_0x39099b)return/\bjudge\b/i['test'](_0x39099b)?_0x39099b:_0x39099b+'\x20Judge';if(hasDuplicates)return _0x1db9d2+'\x20Judge';return _0x1db9d2==='Judge'?_0x1db9d2:_0x1db9d2+'\x20Judge';}export function buildJudgmentDisplayNameMap(_0x2a0e34=[]){const _0x557fcc=Array['isArray'](_0x2a0e34)?_0x2a0e34['filter'](Boolean):[],_0x30a470=new Map();_0x557fcc['forEach'](_0x175be7=>{const _0xe08e05=_0x175be7?.['judgeAgent']||_0x175be7?.['envVars']?.['CODER_AGENT']||'unknown',_0x4f0c27=String(_0xe08e05||'')['trim']()['toLowerCase']()||'unknown';!_0x30a470['has'](_0x4f0c27)&&_0x30a470['set'](_0x4f0c27,[]),_0x30a470['get'](_0x4f0c27)['push'](_0x175be7);});const _0x14a6d7=new Map();return _0x30a470['forEach'](_0x5e8a71=>{const _0x4b5cbb=[..._0x5e8a71]['sort'](compareJudgmentsForAliasOrder),_0x34387e=_0x4b5cbb['length']>0x1,_0x3fb92f=new Set(),_0x308844=new Map();_0x34387e&&_0x4b5cbb['forEach'](_0x4d1b8e=>{const _0x153a89=parseJudgeAliasNumber(_0x4d1b8e?.['judgeAlias'],_0x4d1b8e?.['judgeAgent']);if(!Number['isInteger'](_0x153a89)||_0x153a89<=0x0||_0x3fb92f['has'](_0x153a89))return;_0x308844['set'](_0x4d1b8e['taskId'],_0x153a89),_0x3fb92f['add'](_0x153a89);});let _0xf6e9d4=0x1;const _0x3ebb8a=()=>{while(_0x3fb92f['has'](_0xf6e9d4)){_0xf6e9d4+=0x1;}return _0x3fb92f['add'](_0xf6e9d4),_0xf6e9d4;};_0x4b5cbb['forEach'](_0x36ce06=>{let _0x4bcabd=_0x308844['get'](_0x36ce06['taskId'])||null;_0x34387e&&_0x4bcabd===null&&!String(_0x36ce06?.['judgeAlias']||'')['trim']()&&(_0x4bcabd=_0x3ebb8a()),_0x14a6d7['set'](_0x36ce06['taskId'],formatJudgeDisplayName({'alias':_0x36ce06?.['judgeAlias']||null,'agent':_0x36ce06?.['judgeAgent']||_0x36ce06?.['envVars']?.['CODER_AGENT']||'unknown','number':_0x4bcabd,'hasDuplicates':_0x34387e}));});}),_0x14a6d7;}export function buildTaskNavigationHref(_0x4ca6a9,{currentUrl:_0x5eca01,groupedTaskIds:groupedTaskIds=[],groupId:groupId=null}={}){const _0x30e4c2=new URL(_0x5eca01),_0x2b96f0=String(_0x4ca6a9||'')['trim'](),_0x5436ab=String(groupId||'')['trim'](),_0x5f387b=Array['isArray'](groupedTaskIds)?groupedTaskIds['map'](_0x131c0d=>String(_0x131c0d||'')['trim']())['filter'](Boolean):[],_0x576933=Boolean(_0x5436ab)||_0x5f387b['length']>0x1;if(!_0x576933)return _0x2b96f0&&_0x30e4c2['searchParams']['set']('id',_0x2b96f0),_0x30e4c2['searchParams']['delete']('groupId'),_0x30e4c2['toString']();const _0x33bd26=_0x5f387b['includes'](_0x2b96f0)?_0x5f387b:[..._0x5f387b,_0x2b96f0]['filter'](Boolean);if(_0x33bd26['length']>0x0)_0x30e4c2['searchParams']['set']('id',_0x33bd26['join'](','));else _0x2b96f0&&_0x30e4c2['searchParams']['set']('id',_0x2b96f0);return _0x5436ab?_0x30e4c2['searchParams']['set']('groupId',_0x5436ab):_0x30e4c2['searchParams']['delete']('groupId'),_0x30e4c2['toString']();}
1
+ export function toDisplayAgentName(_0x3a01e3,{fallback:fallback='Unknown'}={}){const _0x40cc6c=String(_0x3a01e3||'')['trim']()['toLowerCase']();if(!_0x40cc6c)return fallback;return _0x40cc6c['charAt'](0x0)['toUpperCase']()+_0x40cc6c['slice'](0x1);}export function escapeRegExp(_0x33b1ea){return String(_0x33b1ea)['replace'](/[.*+?^${}()|[\]\\]/g,'\x5c$&');}export function compareJudgmentsForAliasOrder(_0x3c8654,_0x50822c){const _0x245a2c=String(_0x3c8654?.['createdAt']||''),_0x3a5662=String(_0x50822c?.['createdAt']||'');if(_0x245a2c!==_0x3a5662)return _0x245a2c['localeCompare'](_0x3a5662);return String(_0x3c8654?.['taskId']||'')['localeCompare'](String(_0x50822c?.['taskId']||''));}export function parseJudgeAliasNumber(_0x6a5845,_0x45b21e){const _0x256a0a=typeof _0x6a5845==='string'?_0x6a5845['trim']():'',_0xd2d558=toDisplayAgentName(_0x45b21e,{'fallback':''});if(!_0x256a0a||!_0xd2d558)return null;const _0x37cec8=_0x256a0a['toLowerCase'](),_0x146557=_0xd2d558['toLowerCase']();if(_0x37cec8===_0x146557||_0x37cec8===_0x146557+'\x20judge')return 0x1;const _0x799865=[new RegExp('^'+escapeRegExp(_0xd2d558)+'\x5cs+(\x5cd+)$','i'),new RegExp('^'+escapeRegExp(_0xd2d558)+'\x5cs+Judge\x5cs+(\x5cd+)$','i')];for(const _0x550e10 of _0x799865){const _0x497740=_0x256a0a['match'](_0x550e10);if(_0x497740){const _0x204ff6=Number(_0x497740[0x1]);if(Number['isInteger'](_0x204ff6)&&_0x204ff6>0x0)return _0x204ff6;}}return null;}export function formatJudgeDisplayName({alias:_0x33f4ef,agent:_0x1b0c22,number:number=null,hasDuplicates:hasDuplicates=![]}={}){const _0xf22110=toDisplayAgentName(_0x1b0c22,{'fallback':'Judge'}),_0x2e72d2=typeof _0x33f4ef==='string'?_0x33f4ef['trim']():'';if(Number['isInteger'](number)&&number>0x0)return _0xf22110+'\x20Judge\x20'+number;if(_0x2e72d2)return/\bjudge\b/i['test'](_0x2e72d2)?_0x2e72d2:_0x2e72d2+'\x20Judge';if(hasDuplicates)return _0xf22110+'\x20Judge';return _0xf22110==='Judge'?_0xf22110:_0xf22110+'\x20Judge';}export function buildJudgmentDisplayNameMap(_0x4cfc26=[]){const _0x23a737=Array['isArray'](_0x4cfc26)?_0x4cfc26['filter'](Boolean):[],_0x21cdac=new Map();_0x23a737['forEach'](_0x2dab3e=>{const _0x2f16e3=_0x2dab3e?.['judgeAgent']||_0x2dab3e?.['envVars']?.['CODER_AGENT']||'unknown',_0x1167d5=String(_0x2f16e3||'')['trim']()['toLowerCase']()||'unknown';!_0x21cdac['has'](_0x1167d5)&&_0x21cdac['set'](_0x1167d5,[]),_0x21cdac['get'](_0x1167d5)['push'](_0x2dab3e);});const _0xc3ed4=new Map();return _0x21cdac['forEach'](_0x1b1cc8=>{const _0x4fd60e=[..._0x1b1cc8]['sort'](compareJudgmentsForAliasOrder),_0x554751=_0x4fd60e['length']>0x1,_0x102b64=new Set(),_0x11ec00=new Map();_0x554751&&_0x4fd60e['forEach'](_0x3efe41=>{const _0x4775d5=parseJudgeAliasNumber(_0x3efe41?.['judgeAlias'],_0x3efe41?.['judgeAgent']);if(!Number['isInteger'](_0x4775d5)||_0x4775d5<=0x0||_0x102b64['has'](_0x4775d5))return;_0x11ec00['set'](_0x3efe41['taskId'],_0x4775d5),_0x102b64['add'](_0x4775d5);});let _0x485ce0=0x1;const _0x38f0ae=()=>{while(_0x102b64['has'](_0x485ce0)){_0x485ce0+=0x1;}return _0x102b64['add'](_0x485ce0),_0x485ce0;};_0x4fd60e['forEach'](_0x870189=>{let _0x55d5c9=_0x11ec00['get'](_0x870189['taskId'])||null;_0x554751&&_0x55d5c9===null&&!String(_0x870189?.['judgeAlias']||'')['trim']()&&(_0x55d5c9=_0x38f0ae()),_0xc3ed4['set'](_0x870189['taskId'],formatJudgeDisplayName({'alias':_0x870189?.['judgeAlias']||null,'agent':_0x870189?.['judgeAgent']||_0x870189?.['envVars']?.['CODER_AGENT']||'unknown','number':_0x55d5c9,'hasDuplicates':_0x554751}));});}),_0xc3ed4;}export function buildTaskNavigationHref(_0x49a728,{currentUrl:_0x13f8a7,groupedTaskIds:groupedTaskIds=[],groupId:groupId=null}={}){const _0x3ae1a2=new URL(_0x13f8a7),_0xe42e02=String(_0x49a728||'')['trim'](),_0x285222=String(groupId||'')['trim'](),_0x4786fa=Array['isArray'](groupedTaskIds)?groupedTaskIds['map'](_0x56c044=>String(_0x56c044||'')['trim']())['filter'](Boolean):[],_0x2345e3=Boolean(_0x285222)||_0x4786fa['length']>0x1;if(!_0x2345e3)return _0xe42e02&&_0x3ae1a2['searchParams']['set']('id',_0xe42e02),_0x3ae1a2['searchParams']['delete']('groupId'),_0x3ae1a2['toString']();const _0x28ab20=_0x4786fa['includes'](_0xe42e02)?_0x4786fa:[..._0x4786fa,_0xe42e02]['filter'](Boolean);if(_0x28ab20['length']>0x0)_0x3ae1a2['searchParams']['set']('id',_0x28ab20['join'](','));else _0xe42e02&&_0x3ae1a2['searchParams']['set']('id',_0xe42e02);return _0x285222?_0x3ae1a2['searchParams']['set']('groupId',_0x285222):_0x3ae1a2['searchParams']['delete']('groupId'),_0x3ae1a2['toString']();}
@@ -1054,8 +1054,17 @@
1054
1054
  </svg>
1055
1055
  <span class="file-browser-title">File Browser</span>
1056
1056
  <div style="flex: 1;"></div>
1057
- <button class="btn-ghost btn-small file-browser-upload-btn" id="file-browser-upload-btn" title="Attach files to the current folder">
1058
- Attach files
1057
+ <button class="btn-icon file-browser-header-icon-btn file-browser-new-folder-btn" id="file-browser-new-folder-btn" title="Create a folder in the current directory" aria-label="Create a folder in the current directory" type="button">
1058
+ <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
1059
+ <path d="M22 19a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h5l2 3h9a2 2 0 0 1 2 2z"></path>
1060
+ <path d="M12 11v6"></path>
1061
+ <path d="M9 14h6"></path>
1062
+ </svg>
1063
+ </button>
1064
+ <button class="btn-icon file-browser-header-icon-btn file-browser-upload-btn" id="file-browser-upload-btn" title="Attach files to the current folder" aria-label="Attach files to the current folder" type="button">
1065
+ <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
1066
+ <path d="M21.44 11.05l-9.19 9.19a6 6 0 0 1-8.49-8.49l9.19-9.19a4 4 0 0 1 5.66 5.66l-9.2 9.19a2 2 0 0 1-2.83-2.83l8.49-8.48"></path>
1067
+ </svg>
1059
1068
  </button>
1060
1069
  <input type="file" id="file-browser-upload-input" multiple accept="*/*" hidden aria-label="Attach files to the current folder">
1061
1070
  <button class="btn-icon file-browser-close" id="file-browser-close" title="Close">
@@ -1090,6 +1099,12 @@
1090
1099
  <path d="M18.5 2.5a2.121 2.121 0 0 1 3 3L12 15l-4 1 1-4 9.5-9.5z"></path>
1091
1100
  </svg>
1092
1101
  </button>
1102
+ <button class="btn-ghost btn-small file-browser-rename-btn" id="file-browser-rename-btn" title="Rename file" style="display: none;">
1103
+ <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
1104
+ <path d="M20.59 13.41 11 3H4v7l9.59 10.59a2 2 0 0 0 2.82 0l4.18-4.18a2 2 0 0 0 0-2.82z"></path>
1105
+ <path d="M7 7h.01"></path>
1106
+ </svg>
1107
+ </button>
1093
1108
  <button class="btn-ghost btn-small file-browser-delete-btn" id="file-browser-delete-btn" title="Delete file" style="display: none;">
1094
1109
  <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
1095
1110
  <polyline points="3 6 5 6 21 6"></polyline>
@@ -1625,13 +1640,13 @@
1625
1640
  <div class="modal-overlay"></div>
1626
1641
  <div class="modal-content">
1627
1642
  <div class="modal-header">
1628
- <h2>Delete File</h2>
1643
+ <h2 id="delete-file-modal-title">Delete File</h2>
1629
1644
  <button class="modal-close" id="close-delete-file-modal">&times;</button>
1630
1645
  </div>
1631
1646
  <div class="modal-body">
1632
1647
  <div class="modal-section">
1633
- <p>Are you sure you want to delete <strong id="delete-file-name"></strong>?</p>
1634
- <p class="field-hint" style="color: var(--color-danger); margin-top: 8px;">This will permanently remove the file from the container.</p>
1648
+ <p id="delete-file-message">Are you sure you want to delete <strong id="delete-file-name"></strong>?</p>
1649
+ <p class="field-hint" id="delete-file-hint" style="color: var(--color-danger); margin-top: 8px;">This will permanently remove the file from the container.</p>
1635
1650
  </div>
1636
1651
  </div>
1637
1652
  <div class="modal-footer">
@@ -1641,6 +1656,29 @@
1641
1656
  </div>
1642
1657
  </div>
1643
1658
 
1659
+ <div id="file-browser-name-modal" class="modal" hidden>
1660
+ <div class="modal-overlay"></div>
1661
+ <div class="modal-content">
1662
+ <div class="modal-header">
1663
+ <h2 id="file-browser-name-modal-title">Create Folder</h2>
1664
+ <button class="modal-close" id="close-file-browser-name-modal">&times;</button>
1665
+ </div>
1666
+ <div class="modal-body">
1667
+ <div class="modal-section">
1668
+ <p id="file-browser-name-modal-description">Enter a name.</p>
1669
+ <label for="file-browser-name-input" id="file-browser-name-modal-label">Name</label>
1670
+ <input type="text" id="file-browser-name-input" class="new-branch-input" autocomplete="off" spellcheck="false">
1671
+ <p class="field-hint" id="file-browser-name-modal-hint" style="margin-top: 8px;">Names cannot include "/" and must stay inside the current safe root.</p>
1672
+ <div class="modal-error" id="file-browser-name-modal-error" hidden></div>
1673
+ </div>
1674
+ </div>
1675
+ <div class="modal-footer">
1676
+ <button class="btn-ghost" id="cancel-file-browser-name-modal">Cancel</button>
1677
+ <button class="btn-primary" id="confirm-file-browser-name-modal">Create</button>
1678
+ </div>
1679
+ </div>
1680
+ </div>
1681
+
1644
1682
  <div id="discard-file-modal" class="modal" hidden>
1645
1683
  <div class="modal-overlay"></div>
1646
1684
  <div class="modal-content">