@profoundlogic/coderflow-server 0.6.9 → 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 +68 -1
  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(_0x559bae){if(_0x559bae==='connected')return'onConnected';if(_0x559bae==='error')return'onError';return'on'+_0x559bae['split']('-')['map'](_0x75fbe1=>_0x75fbe1['charAt'](0x0)['toUpperCase']()+_0x75fbe1['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'](_0x432616,_0x14f81f){return!this['listeners']['has'](_0x432616)&&this['listeners']['set'](_0x432616,new Set()),this['listeners']['get'](_0x432616)['add'](_0x14f81f),this;}['off'](_0x1bb89b,_0x50e2fa){return this['listeners']['has'](_0x1bb89b)&&this['listeners']['get'](_0x1bb89b)['delete'](_0x50e2fa),this;}['_emit'](_0x15a92a,_0x1f85ae){this['listeners']['has'](_0x15a92a)&&this['listeners']['get'](_0x15a92a)['forEach'](_0x956ba6=>{try{_0x956ba6(_0x1f85ae);}catch(_0x2f9b3a){console['error']('[SSE\x20Client]\x20Error\x20in\x20'+_0x15a92a+'\x20listener:',_0x2f9b3a);}});}['connect'](_0x47bca9='me'){this['userId']=_0x47bca9,this['useSharedWorker']?this['_connectViaWorker'](_0x47bca9):this['_connectDirect'](_0x47bca9);}['_connectViaWorker'](_0x2129c8){try{this['_ensureWorker'](),this['port']['postMessage']({'action':'connect','userId':_0x2129c8});}catch(_0x4d1bf1){console['error']('[SSE\x20Client]\x20SharedWorker\x20failed,\x20falling\x20back\x20to\x20direct\x20SSE:',_0x4d1bf1),this['useSharedWorker']=![],this['_connectDirect'](_0x2129c8);}}['_ensureWorker'](){!this['worker']&&(this['worker']=new SharedWorker('/sse-shared-worker.js'),this['port']=this['worker']['port'],this['port']['onmessage']=this['_handleWorkerMessage'],this['port']['onmessageerror']=_0x5bdb1d=>{console['error']('[SSE\x20Client]\x20Worker\x20message\x20error:',_0x5bdb1d),this['_emit']('error',{'error':'Worker\x20message\x20error'});},this['port']['start']());}['_handleWorkerMessage'](_0x1651dd){const _0x3f4a1d=_0x1651dd['data'];if(_0x3f4a1d['type']&&_0x3f4a1d['type']['startsWith']('task:')){this['_handleTaskStreamMessage'](_0x3f4a1d);return;}switch(_0x3f4a1d['type']){case'connected':this['connected']=!![],this['_emit']('connected',{});break;case'snapshot':case'activity':case'status':case'new-task':case'queue-position':try{const _0x3ad405=JSON['parse'](_0x3f4a1d['data']);this['_emit'](_0x3f4a1d['type'],_0x3ad405);}catch(_0x1f6d2b){console['error']('[SSE\x20Client]\x20Failed\x20to\x20parse\x20'+_0x3f4a1d['type']+'\x20data:',_0x1f6d2b);}break;case'error':this['connected']=![],this['_emit']('error',_0x3f4a1d);break;default:console['warn']('[SSE\x20Client]\x20Unknown\x20message\x20type:',_0x3f4a1d['type']);}}['_handleTaskStreamMessage'](_0x34a3f6){const {taskId:_0x3279cd,type:_0x316a0c,data:_0x3cba50}=_0x34a3f6,_0x11af45=this['_taskSubscriptions']['get'](_0x3279cd);if(!_0x11af45||_0x11af45['size']===0x0)return;const _0x4eea14=_0x316a0c['replace']('task:',''),_0x451061=eventTypeToHandler(_0x4eea14);_0x11af45['forEach'](_0xc6fcca=>{if(_0xc6fcca['handlers'][_0x451061])try{const _0x278674=typeof _0x3cba50==='string'?JSON['parse'](_0x3cba50):_0x3cba50;_0xc6fcca['handlers'][_0x451061](_0x278674);}catch(_0x390239){console['error']('[SSE\x20Client]\x20Error\x20in\x20task\x20'+_0x4eea14+'\x20handler:',_0x390239);}});}['_connectDirect'](_0x5d491c){this['eventSource']&&(this['eventSource']['close'](),this['eventSource']=null);const _0x506cdb=_0x5d491c&&_0x5d491c!=='me'?'?userId='+_0x5d491c:'';try{this['eventSource']=new EventSource('/tasks/updates'+_0x506cdb),this['eventSource']['addEventListener']('open',()=>{this['connected']=!![],this['reconnectAttempts']=0x0,this['_emit']('connected',{});}),this['eventSource']['addEventListener']('snapshot',_0x35ca59=>{this['_handleDirectSSE']('snapshot',_0x35ca59),this['reconnectAttempts']=0x0;}),this['eventSource']['addEventListener']('activity',_0x3b553e=>{this['_handleDirectSSE']('activity',_0x3b553e);}),this['eventSource']['addEventListener']('status',_0x3c1252=>{this['_handleDirectSSE']('status',_0x3c1252);}),this['eventSource']['addEventListener']('new-task',_0x181ff3=>{this['_handleDirectSSE']('new-task',_0x181ff3);}),this['eventSource']['addEventListener']('queue-position',_0x5316b1=>{this['_handleDirectSSE']('queue-position',_0x5316b1);}),this['eventSource']['addEventListener']('error',_0x31be9c=>{console['error']('[SSE\x20Client]\x20Direct\x20SSE\x20error:',_0x31be9c),this['connected']=![],this['_emit']('error',{'error':'Connection\x20error'}),this['eventSource']&&(this['eventSource']['close'](),this['eventSource']=null),this['_scheduleReconnect']();});}catch(_0x3dc161){console['error']('[SSE\x20Client]\x20Failed\x20to\x20create\x20EventSource:',_0x3dc161),this['_emit']('error',{'error':_0x3dc161['message']}),this['_scheduleReconnect']();}}['_handleDirectSSE'](_0x44e9f0,_0x1e8630){try{const _0x3984f1=JSON['parse'](_0x1e8630['data']);this['_emit'](_0x44e9f0,_0x3984f1);}catch(_0x489dec){console['error']('[SSE\x20Client]\x20Failed\x20to\x20parse\x20'+_0x44e9f0+'\x20data:',_0x489dec);}}['_scheduleReconnect'](){this['reconnectTimeout']&&clearTimeout(this['reconnectTimeout']);const _0x20e4c7=Math['min'](0x3e8*Math['pow'](0x2,this['reconnectAttempts']),0x7530);this['reconnectAttempts']++,console['log']('[SSE\x20Client]\x20Scheduling\x20reconnect\x20in\x20'+_0x20e4c7+'ms'),this['reconnectTimeout']=setTimeout(()=>{this['_connectDirect'](this['userId']);},_0x20e4c7);}['changeFilter'](_0x4e41c4){if(_0x4e41c4===this['userId'])return;this['userId']=_0x4e41c4;if(this['useSharedWorker']&&this['port'])this['port']['postMessage']({'action':'changeFilter','userId':_0x4e41c4});else this['eventSource']&&this['_connectDirect'](_0x4e41c4);}['subscribeTask'](_0x33773b,_0x8b55f6){return this['useSharedWorker']?this['_subscribeTaskViaWorker'](_0x33773b,_0x8b55f6):this['_subscribeTaskDirect'](_0x33773b,_0x8b55f6);}['unsubscribeTask'](_0x26690a){if(!_0x26690a)return;_0x26690a['type']==='worker'?this['_unsubscribeTaskWorker'](_0x26690a):this['_unsubscribeTaskDirect'](_0x26690a);}['_subscribeTaskViaWorker'](_0x3fafd9,_0x2ad98f){try{this['_ensureWorker']();}catch(_0x386555){return console['error']('[SSE\x20Client]\x20SharedWorker\x20failed\x20for\x20task\x20sub,\x20falling\x20back:',_0x386555),this['useSharedWorker']=![],this['_subscribeTaskDirect'](_0x3fafd9,_0x2ad98f);}const _0x4eca89=++this['_taskSubIdCounter'],_0x526281={'type':'worker','taskId':_0x3fafd9,'handlers':_0x2ad98f,'id':_0x4eca89};return!this['_taskSubscriptions']['has'](_0x3fafd9)&&(this['_taskSubscriptions']['set'](_0x3fafd9,new Set()),this['port']['postMessage']({'action':'subscribeTask','taskId':_0x3fafd9})),this['_taskSubscriptions']['get'](_0x3fafd9)['add'](_0x526281),_0x526281;}['_unsubscribeTaskWorker'](_0x13b26c){const {taskId:_0x34043d}=_0x13b26c,_0x373d50=this['_taskSubscriptions']['get'](_0x34043d);if(_0x373d50){_0x373d50['delete'](_0x13b26c);if(_0x373d50['size']===0x0){this['_taskSubscriptions']['delete'](_0x34043d);try{this['port']&&this['port']['postMessage']({'action':'unsubscribeTask','taskId':_0x34043d});}catch(_0x50581b){}}}}['_subscribeTaskDirect'](_0x528dbc,_0x43d1c4){const _0x37eb11=++this['_taskSubIdCounter'],_0x1daff7=new EventSource('/tasks/'+_0x528dbc+'/stream'),_0x35a63e={'type':'direct','taskId':_0x528dbc,'handlers':_0x43d1c4,'id':_0x37eb11,'eventSource':_0x1daff7};!this['_taskSubscriptions']['has'](_0x528dbc)&&this['_taskSubscriptions']['set'](_0x528dbc,new Set());this['_taskSubscriptions']['get'](_0x528dbc)['add'](_0x35a63e);for(const _0x4fb0d2 of TASK_STREAM_EVENTS){const _0x329695=eventTypeToHandler(_0x4fb0d2);_0x1daff7['addEventListener'](_0x4fb0d2,_0x439226=>{if(_0x43d1c4[_0x329695])try{const _0x3ba5f9=JSON['parse'](_0x439226['data']);_0x43d1c4[_0x329695](_0x3ba5f9);}catch(_0x3898c4){console['error']('[SSE\x20Client]\x20Error\x20parsing\x20task\x20'+_0x4fb0d2+':',_0x3898c4);}});}return _0x1daff7['addEventListener']('open',()=>{if(_0x43d1c4['onConnected'])_0x43d1c4['onConnected']();}),_0x1daff7['addEventListener']('error',()=>{if(_0x43d1c4['onError'])_0x43d1c4['onError']({'error':'Connection\x20error'});}),_0x35a63e;}['_unsubscribeTaskDirect'](_0x1e2d58){_0x1e2d58['eventSource']&&(_0x1e2d58['eventSource']['close'](),_0x1e2d58['eventSource']=null);const _0x1cf258=this['_taskSubscriptions']['get'](_0x1e2d58['taskId']);_0x1cf258&&(_0x1cf258['delete'](_0x1e2d58),_0x1cf258['size']===0x0&&this['_taskSubscriptions']['delete'](_0x1e2d58['taskId']));}['disconnect'](){this['reconnectTimeout']&&(clearTimeout(this['reconnectTimeout']),this['reconnectTimeout']=null);this['_taskSubscriptions']['forEach']((_0x320246,_0x2119e2)=>{_0x320246['forEach'](_0x29bea0=>{_0x29bea0['type']==='direct'&&_0x29bea0['eventSource']&&_0x29bea0['eventSource']['close']();});}),this['_taskSubscriptions']['clear']();if(this['useSharedWorker']&&this['port'])try{this['port']['postMessage']({'action':'disconnect'});}catch(_0x51c50b){}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(_0x3d70f3){eventSource&&currentUserId!==_0x3d70f3&&(eventSource['close'](),eventSource=null);if(eventSource&&eventSource['readyState']!==EventSource['CLOSED'])return;currentUserId=_0x3d70f3;const _0x5cb5a0=_0x3d70f3&&_0x3d70f3!=='me'?'?userId='+_0x3d70f3:'';try{eventSource=new EventSource('/tasks/updates'+_0x5cb5a0),eventSource['addEventListener']('snapshot',_0x5bc730=>{broadcast({'type':'snapshot','data':_0x5bc730['data']}),reconnectAttempts=0x0;}),eventSource['addEventListener']('activity',_0x2b0e6c=>{broadcast({'type':'activity','data':_0x2b0e6c['data']});}),eventSource['addEventListener']('status',_0xd1e92f=>{broadcast({'type':'status','data':_0xd1e92f['data']});}),eventSource['addEventListener']('new-task',_0x2fa9a9=>{broadcast({'type':'new-task','data':_0x2fa9a9['data']});}),eventSource['addEventListener']('queue-position',_0x38544e=>{broadcast({'type':'queue-position','data':_0x38544e['data']});}),eventSource['addEventListener']('open',()=>{broadcast({'type':'connected'}),reconnectAttempts=0x0;}),eventSource['addEventListener']('error',_0x23e348=>{console['error']('[SSE\x20Worker]\x20Connection\x20error:',_0x23e348),broadcast({'type':'error','error':'Connection\x20error'}),eventSource&&(eventSource['close'](),eventSource=null),scheduleReconnect();});}catch(_0x431f28){console['error']('[SSE\x20Worker]\x20Failed\x20to\x20create\x20EventSource:',_0x431f28),broadcast({'type':'error','error':_0x431f28['message']}),scheduleReconnect();}}function scheduleReconnect(){reconnectTimeout&&clearTimeout(reconnectTimeout);if(ports['size']===0x0)return;const _0x40a24f=Math['min'](0x3e8*Math['pow'](0x2,reconnectAttempts),MAX_RECONNECT_DELAY);reconnectAttempts++,console['log']('[SSE\x20Worker]\x20Scheduling\x20reconnect\x20in\x20'+_0x40a24f+'ms\x20(attempt\x20'+reconnectAttempts+')'),reconnectTimeout=setTimeout(()=>{ports['size']>0x0&&connect(currentUserId);},_0x40a24f);}function broadcast(_0x106cca){const _0x49292a=[];ports['forEach'](_0x55c7eb=>{try{_0x55c7eb['postMessage'](_0x106cca);}catch(_0x1bc7e7){console['warn']('[SSE\x20Worker]\x20Failed\x20to\x20send\x20to\x20port,\x20removing:',_0x1bc7e7),_0x49292a['push'](_0x55c7eb);}}),_0x49292a['length']>0x0&&cleanUpDeadPorts(_0x49292a),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(_0x411131,_0x4dd9e0){let _0x354f76=taskStreams['get'](_0x4dd9e0);!_0x354f76&&(_0x354f76={'eventSource':null,'reconnectTimeout':null,'reconnectAttempts':0x0,'subscribedPorts':new Set()},taskStreams['set'](_0x4dd9e0,_0x354f76));_0x354f76['subscribedPorts']['add'](_0x411131);if(!_0x354f76['eventSource']||_0x354f76['eventSource']['readyState']===EventSource['CLOSED'])connectTaskStream(_0x4dd9e0);else{if(_0x354f76['eventSource']['readyState']===EventSource['OPEN'])try{_0x411131['postMessage']({'type':'task:connected','taskId':_0x4dd9e0});}catch(_0x4da280){}}}function unsubscribeTask(_0x518dad,_0x4f5bf2){const _0x28787e=taskStreams['get'](_0x4f5bf2);if(!_0x28787e)return;_0x28787e['subscribedPorts']['delete'](_0x518dad),_0x28787e['subscribedPorts']['size']===0x0&&deferredCloseTaskStream(_0x4f5bf2);}function connectTaskStream(_0x12ab67){const _0x46ce2c=taskStreams['get'](_0x12ab67);if(!_0x46ce2c)return;_0x46ce2c['eventSource']&&(_0x46ce2c['eventSource']['close'](),_0x46ce2c['eventSource']=null);try{_0x46ce2c['eventSource']=new EventSource('/tasks/'+_0x12ab67+'/stream');for(const _0x57c951 of TASK_STREAM_EVENTS){_0x46ce2c['eventSource']['addEventListener'](_0x57c951,_0x3c890b=>{broadcastToTask(_0x12ab67,'task:'+_0x57c951,_0x3c890b['data']),_0x46ce2c['reconnectAttempts']=0x0;});}_0x46ce2c['eventSource']['addEventListener']('open',()=>{broadcastToTask(_0x12ab67,'task:connected','{}'),_0x46ce2c['reconnectAttempts']=0x0;}),_0x46ce2c['eventSource']['addEventListener']('error',()=>{broadcastToTask(_0x12ab67,'task:error',JSON['stringify']({'error':'Connection\x20error'})),_0x46ce2c['eventSource']&&(_0x46ce2c['eventSource']['close'](),_0x46ce2c['eventSource']=null),scheduleTaskReconnect(_0x12ab67);});}catch(_0x1a919b){console['error']('[SSE\x20Worker]\x20Failed\x20to\x20create\x20task\x20EventSource\x20for\x20'+_0x12ab67+':',_0x1a919b),broadcastToTask(_0x12ab67,'task:error',JSON['stringify']({'error':_0x1a919b['message']})),scheduleTaskReconnect(_0x12ab67);}}function broadcastToTask(_0x37b0f8,_0x3028e1,_0x10156a){const _0x576514=taskStreams['get'](_0x37b0f8);if(!_0x576514)return;const _0x5ac452=[];_0x576514['subscribedPorts']['forEach'](_0x542b2c=>{try{_0x542b2c['postMessage']({'type':_0x3028e1,'taskId':_0x37b0f8,'data':_0x10156a});}catch(_0x5dead5){_0x5ac452['push'](_0x542b2c);}}),_0x5ac452['length']>0x0&&(_0x5ac452['forEach'](_0x1837c3=>_0x576514['subscribedPorts']['delete'](_0x1837c3)),cleanUpDeadPorts(_0x5ac452),_0x576514['subscribedPorts']['size']===0x0&&closeTaskStream(_0x37b0f8));}function closeTaskStream(_0x1a10b7){const _0x46f77e=taskStreams['get'](_0x1a10b7);if(!_0x46f77e)return;_0x46f77e['eventSource']&&_0x46f77e['eventSource']['close'](),_0x46f77e['reconnectTimeout']&&clearTimeout(_0x46f77e['reconnectTimeout']),taskStreams['delete'](_0x1a10b7);}function deferredCloseTaskStream(_0x37892f){setTimeout(()=>{const _0x343acb=taskStreams['get'](_0x37892f);_0x343acb&&_0x343acb['subscribedPorts']['size']===0x0&&closeTaskStream(_0x37892f);},0x0);}function scheduleTaskReconnect(_0xc41c3f){const _0x29bd24=taskStreams['get'](_0xc41c3f);if(!_0x29bd24||_0x29bd24['subscribedPorts']['size']===0x0)return;_0x29bd24['reconnectTimeout']&&clearTimeout(_0x29bd24['reconnectTimeout']);const _0x4bb7ed=Math['min'](0x3e8*Math['pow'](0x2,_0x29bd24['reconnectAttempts']),MAX_RECONNECT_DELAY);_0x29bd24['reconnectAttempts']++,console['log']('[SSE\x20Worker]\x20Scheduling\x20task\x20stream\x20reconnect\x20for\x20'+_0xc41c3f+'\x20in\x20'+_0x4bb7ed+'ms'),_0x29bd24['reconnectTimeout']=setTimeout(()=>{_0x29bd24['subscribedPorts']['size']>0x0&&connectTaskStream(_0xc41c3f);},_0x4bb7ed);}function cleanUpDeadPorts(_0x37bb34){for(const _0xde352b of _0x37bb34){ports['delete'](_0xde352b),taskStreams['forEach']((_0x33f676,_0x173cc1)=>{_0x33f676['subscribedPorts']['delete'](_0xde352b),_0x33f676['subscribedPorts']['size']===0x0&&closeTaskStream(_0x173cc1);});}}function removePortFromAllTasks(_0x3e1abc){taskStreams['forEach']((_0x24b9bf,_0x487c75)=>{_0x24b9bf['subscribedPorts']['has'](_0x3e1abc)&&(_0x24b9bf['subscribedPorts']['delete'](_0x3e1abc),_0x24b9bf['subscribedPorts']['size']===0x0&&closeTaskStream(_0x487c75));});}self['onconnect']=function(_0x322419){const _0x3d2a05=_0x322419['ports'][0x0];ports['add'](_0x3d2a05),console['log']('[SSE\x20Worker]\x20New\x20port\x20connected.\x20Total\x20ports:\x20'+ports['size']),_0x3d2a05['onmessage']=function(_0x5ad885){const {action:_0x2b92fe,userId:_0x3fe1cd,taskId:_0x119fa4}=_0x5ad885['data'];switch(_0x2b92fe){case'connect':connect(_0x3fe1cd);eventSource&&eventSource['readyState']===EventSource['OPEN']&&_0x3d2a05['postMessage']({'type':'connected'});break;case'disconnect':ports['delete'](_0x3d2a05),removePortFromAllTasks(_0x3d2a05),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':_0x3fe1cd!==currentUserId&&connect(_0x3fe1cd);break;case'subscribeTask':subscribeTask(_0x3d2a05,_0x119fa4);break;case'unsubscribeTask':unsubscribeTask(_0x3d2a05,_0x119fa4);break;default:console['warn']('[SSE\x20Worker]\x20Unknown\x20action:',_0x2b92fe);}},_0x3d2a05['onmessageerror']=function(_0x5cf358){console['error']('[SSE\x20Worker]\x20Port\x20message\x20error:',_0x5cf358),ports['delete'](_0x3d2a05),removePortFromAllTasks(_0x3d2a05);},_0x3d2a05['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(_0x5efb02,{fallback:fallback='Unknown'}={}){const _0x234ab4=String(_0x5efb02||'')['trim']()['toLowerCase']();if(!_0x234ab4)return fallback;return _0x234ab4['charAt'](0x0)['toUpperCase']()+_0x234ab4['slice'](0x1);}export function escapeRegExp(_0x7c06fe){return String(_0x7c06fe)['replace'](/[.*+?^${}()|[\]\\]/g,'\x5c$&');}export function compareJudgmentsForAliasOrder(_0x5987ab,_0x59f985){const _0x1790f2=String(_0x5987ab?.['createdAt']||''),_0x5f209e=String(_0x59f985?.['createdAt']||'');if(_0x1790f2!==_0x5f209e)return _0x1790f2['localeCompare'](_0x5f209e);return String(_0x5987ab?.['taskId']||'')['localeCompare'](String(_0x59f985?.['taskId']||''));}export function parseJudgeAliasNumber(_0x17017d,_0x22a62e){const _0x36ee12=typeof _0x17017d==='string'?_0x17017d['trim']():'',_0x470b2f=toDisplayAgentName(_0x22a62e,{'fallback':''});if(!_0x36ee12||!_0x470b2f)return null;const _0xea2412=_0x36ee12['toLowerCase'](),_0x3bf046=_0x470b2f['toLowerCase']();if(_0xea2412===_0x3bf046||_0xea2412===_0x3bf046+'\x20judge')return 0x1;const _0x597627=[new RegExp('^'+escapeRegExp(_0x470b2f)+'\x5cs+(\x5cd+)$','i'),new RegExp('^'+escapeRegExp(_0x470b2f)+'\x5cs+Judge\x5cs+(\x5cd+)$','i')];for(const _0xadc2f7 of _0x597627){const _0x59abba=_0x36ee12['match'](_0xadc2f7);if(_0x59abba){const _0x1ae7e0=Number(_0x59abba[0x1]);if(Number['isInteger'](_0x1ae7e0)&&_0x1ae7e0>0x0)return _0x1ae7e0;}}return null;}export function formatJudgeDisplayName({alias:_0x54f4df,agent:_0x389840,number:number=null,hasDuplicates:hasDuplicates=![]}={}){const _0x3a4e45=toDisplayAgentName(_0x389840,{'fallback':'Judge'}),_0x2ac9f6=typeof _0x54f4df==='string'?_0x54f4df['trim']():'';if(Number['isInteger'](number)&&number>0x0)return _0x3a4e45+'\x20Judge\x20'+number;if(_0x2ac9f6)return/\bjudge\b/i['test'](_0x2ac9f6)?_0x2ac9f6:_0x2ac9f6+'\x20Judge';if(hasDuplicates)return _0x3a4e45+'\x20Judge';return _0x3a4e45==='Judge'?_0x3a4e45:_0x3a4e45+'\x20Judge';}export function buildJudgmentDisplayNameMap(_0x30ef55=[]){const _0x2ec9d8=Array['isArray'](_0x30ef55)?_0x30ef55['filter'](Boolean):[],_0x1709e8=new Map();_0x2ec9d8['forEach'](_0x58606a=>{const _0x5bc84a=_0x58606a?.['judgeAgent']||_0x58606a?.['envVars']?.['CODER_AGENT']||'unknown',_0x28853d=String(_0x5bc84a||'')['trim']()['toLowerCase']()||'unknown';!_0x1709e8['has'](_0x28853d)&&_0x1709e8['set'](_0x28853d,[]),_0x1709e8['get'](_0x28853d)['push'](_0x58606a);});const _0xbf62c3=new Map();return _0x1709e8['forEach'](_0x5a2d27=>{const _0x162496=[..._0x5a2d27]['sort'](compareJudgmentsForAliasOrder),_0x36c279=_0x162496['length']>0x1,_0x12ee30=new Set(),_0x44c1bf=new Map();_0x36c279&&_0x162496['forEach'](_0x53ae8b=>{const _0xc0a97b=parseJudgeAliasNumber(_0x53ae8b?.['judgeAlias'],_0x53ae8b?.['judgeAgent']);if(!Number['isInteger'](_0xc0a97b)||_0xc0a97b<=0x0||_0x12ee30['has'](_0xc0a97b))return;_0x44c1bf['set'](_0x53ae8b['taskId'],_0xc0a97b),_0x12ee30['add'](_0xc0a97b);});let _0x1427a7=0x1;const _0x1d4cc2=()=>{while(_0x12ee30['has'](_0x1427a7)){_0x1427a7+=0x1;}return _0x12ee30['add'](_0x1427a7),_0x1427a7;};_0x162496['forEach'](_0x306b73=>{let _0x4757cf=_0x44c1bf['get'](_0x306b73['taskId'])||null;_0x36c279&&_0x4757cf===null&&!String(_0x306b73?.['judgeAlias']||'')['trim']()&&(_0x4757cf=_0x1d4cc2()),_0xbf62c3['set'](_0x306b73['taskId'],formatJudgeDisplayName({'alias':_0x306b73?.['judgeAlias']||null,'agent':_0x306b73?.['judgeAgent']||_0x306b73?.['envVars']?.['CODER_AGENT']||'unknown','number':_0x4757cf,'hasDuplicates':_0x36c279}));});}),_0xbf62c3;}export function buildTaskNavigationHref(_0x77cafb,{currentUrl:_0x5cb14a,groupedTaskIds:groupedTaskIds=[],groupId:groupId=null}={}){const _0x4e788f=new URL(_0x5cb14a),_0x1d2a0a=String(_0x77cafb||'')['trim'](),_0x3fc991=String(groupId||'')['trim'](),_0x4e506f=Array['isArray'](groupedTaskIds)?groupedTaskIds['map'](_0x362383=>String(_0x362383||'')['trim']())['filter'](Boolean):[],_0x2f6437=Boolean(_0x3fc991)||_0x4e506f['length']>0x1;if(!_0x2f6437)return _0x1d2a0a&&_0x4e788f['searchParams']['set']('id',_0x1d2a0a),_0x4e788f['searchParams']['delete']('groupId'),_0x4e788f['toString']();const _0x35fcee=_0x4e506f['includes'](_0x1d2a0a)?_0x4e506f:[..._0x4e506f,_0x1d2a0a]['filter'](Boolean);if(_0x35fcee['length']>0x0)_0x4e788f['searchParams']['set']('id',_0x35fcee['join'](','));else _0x1d2a0a&&_0x4e788f['searchParams']['set']('id',_0x1d2a0a);return _0x3fc991?_0x4e788f['searchParams']['set']('groupId',_0x3fc991):_0x4e788f['searchParams']['delete']('groupId'),_0x4e788f['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">