@profoundlogic/coderflow-server 0.8.6 → 0.8.8

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 (191) hide show
  1. package/dist/base-image/Dockerfile +3 -2
  2. package/dist/base-image/agent-wrapper.sh +7 -2
  3. package/dist/coder-server.js +1 -1
  4. package/dist/config.js +1 -1
  5. package/dist/lib/agent-keepalive.js +1 -1
  6. package/dist/lib/agent-models.js +1 -1
  7. package/dist/lib/api-keys.js +1 -1
  8. package/dist/lib/apiKeys.js +1 -1
  9. package/dist/lib/app-server-ports.js +1 -1
  10. package/dist/lib/auto-judge.js +1 -1
  11. package/dist/lib/automation-service.js +1 -1
  12. package/dist/lib/basic-auth.js +1 -1
  13. package/dist/lib/bindings.js +1 -1
  14. package/dist/lib/build-history.js +1 -1
  15. package/dist/lib/build-output-service.js +1 -1
  16. package/dist/lib/build-scheduler.js +1 -1
  17. package/dist/lib/build-service.js +1 -1
  18. package/dist/lib/ca-certificates.js +1 -1
  19. package/dist/lib/claude-oauth-refresh.js +1 -1
  20. package/dist/lib/cli/build.js +1 -1
  21. package/dist/lib/cli/cleanup-users.js +1 -1
  22. package/dist/lib/cli/config-command.js +1 -1
  23. package/dist/lib/cli/config.js +1 -1
  24. package/dist/lib/cli/create-user.js +1 -1
  25. package/dist/lib/cli/grant-admin.js +1 -1
  26. package/dist/lib/cli/init.js +1 -1
  27. package/dist/lib/cli/jira.js +1 -1
  28. package/dist/lib/cli/license.js +1 -1
  29. package/dist/lib/cli/list-roles.js +1 -1
  30. package/dist/lib/cli/list-users.js +1 -1
  31. package/dist/lib/cli/server-manager.js +1 -1
  32. package/dist/lib/cli/set-password.js +1 -1
  33. package/dist/lib/compression-filter.js +1 -1
  34. package/dist/lib/config-migration.js +1 -1
  35. package/dist/lib/container-credential-sync.js +1 -1
  36. package/dist/lib/container-tokens.js +1 -1
  37. package/dist/lib/data-dir.js +1 -1
  38. package/dist/lib/deployment-history.js +1 -1
  39. package/dist/lib/deployment-service.js +1 -1
  40. package/dist/lib/docker-utils.js +1 -1
  41. package/dist/lib/email.js +1 -1
  42. package/dist/lib/emailTemplates.js +1 -1
  43. package/dist/lib/entitlement.js +1 -1
  44. package/dist/lib/external-connections.js +1 -1
  45. package/dist/lib/fetch-utils.js +1 -1
  46. package/dist/lib/git-commit-details-route.js +1 -1
  47. package/dist/lib/git-history-diff-guardrails.js +1 -1
  48. package/dist/lib/git-provider-service.js +1 -1
  49. package/dist/lib/git-provider-setup/github-setup-handler.js +1 -1
  50. package/dist/lib/git-provider-setup/index.js +1 -1
  51. package/dist/lib/git-provider-setup/setup-factory.js +1 -1
  52. package/dist/lib/git-provider-setup/setup-interface.js +1 -1
  53. package/dist/lib/git-providers/azure-devops-provider.js +1 -1
  54. package/dist/lib/git-providers/github-app-provider.js +1 -1
  55. package/dist/lib/git-providers/index.js +1 -1
  56. package/dist/lib/git-providers/provider-factory.js +1 -1
  57. package/dist/lib/git-providers/provider-interface.js +1 -1
  58. package/dist/lib/github-urls.js +1 -1
  59. package/dist/lib/group-objective-linking.js +1 -1
  60. package/dist/lib/ibmi-sync.js +1 -1
  61. package/dist/lib/jira-client.js +1 -1
  62. package/dist/lib/judge-blinding.js +1 -1
  63. package/dist/lib/logger.js +1 -1
  64. package/dist/lib/memory-utils.js +1 -1
  65. package/dist/lib/migration-to-scoped-rbac.js +1 -1
  66. package/dist/lib/model-fetcher.js +1 -1
  67. package/dist/lib/notifications.js +1 -1
  68. package/dist/lib/objective-context.js +1 -1
  69. package/dist/lib/oidc-auth.js +1 -1
  70. package/dist/lib/oidc-device-flow.js +1 -1
  71. package/dist/lib/passwordTokens.js +1 -1
  72. package/dist/lib/permission-resolver.js +1 -1
  73. package/dist/lib/pin-cascade.js +1 -1
  74. package/dist/lib/provider-accounts.js +1 -1
  75. package/dist/lib/provider-oauth.js +1 -1
  76. package/dist/lib/provider-profile.js +1 -1
  77. package/dist/lib/provider-token-refresh.js +1 -1
  78. package/dist/lib/rbac-user-state.js +1 -1
  79. package/dist/lib/request-url.js +1 -1
  80. package/dist/lib/rewind.js +1 -1
  81. package/dist/lib/role-definitions.js +1 -1
  82. package/dist/lib/roles.js +1 -1
  83. package/dist/lib/secrets.js +1 -1
  84. package/dist/lib/setup-repo-git-auth.js +1 -1
  85. package/dist/lib/slack-service.js +1 -0
  86. package/dist/lib/state-capture.js +1 -1
  87. package/dist/lib/static-files.js +1 -1
  88. package/dist/lib/task-aliases.js +1 -1
  89. package/dist/lib/task-container-init.js +1 -1
  90. package/dist/lib/task-context-usage.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/logs.js +1 -1
  121. package/dist/routes/objective-management.js +1 -1
  122. package/dist/routes/password.js +1 -1
  123. package/dist/routes/prompt.js +1 -1
  124. package/dist/routes/provider-auth.js +1 -1
  125. package/dist/routes/qa.js +1 -1
  126. package/dist/routes/roles.js +1 -1
  127. package/dist/routes/settings.js +1 -1
  128. package/dist/routes/skill-management.js +1 -1
  129. package/dist/routes/skills.js +1 -1
  130. package/dist/routes/slack.js +1 -0
  131. package/dist/routes/stats.js +1 -1
  132. package/dist/routes/tasks.js +1 -1
  133. package/dist/routes/teams.js +1 -1
  134. package/dist/routes/templates.js +1 -1
  135. package/dist/routes/test-task.js +1 -1
  136. package/dist/routes/test.js +1 -1
  137. package/dist/routes/users.js +1 -1
  138. package/dist/routes/visualizations.js +1 -1
  139. package/dist/scripts/create-user.js +1 -1
  140. package/dist/scripts/migrate-config-to-data-dir.js +1 -1
  141. package/dist/start.js +1 -1
  142. package/dist/web-ui/public/activity-detail-modal.js +1 -1
  143. package/dist/web-ui/public/activity-feed.js +1 -1
  144. package/dist/web-ui/public/activity-formatters.js +1 -1
  145. package/dist/web-ui/public/admin.css +476 -0
  146. package/dist/web-ui/public/admin.html +96 -17
  147. package/dist/web-ui/public/admin.js +1 -1
  148. package/dist/web-ui/public/agent-event-parser.js +1 -1
  149. package/dist/web-ui/public/app.js +1 -1
  150. package/dist/web-ui/public/approve-dialog.js +1 -1
  151. package/dist/web-ui/public/automation-links.js +1 -1
  152. package/dist/web-ui/public/automation-schedule.js +1 -1
  153. package/dist/web-ui/public/comments-widget.js +1 -1
  154. package/dist/web-ui/public/diff-utils.js +1 -1
  155. package/dist/web-ui/public/docs/_sidebar.md +1 -0
  156. package/dist/web-ui/public/docs/admin/container-lifecycle.md +102 -0
  157. package/dist/web-ui/public/docs/admin/jira.md +20 -3
  158. package/dist/web-ui/public/docs/docsify-proxy-helper.js +1 -0
  159. package/dist/web-ui/public/docs/index.html +25 -18
  160. package/dist/web-ui/public/environments.html +1 -0
  161. package/dist/web-ui/public/environments.js +1 -1
  162. package/dist/web-ui/public/feedback-widget.js +1 -1
  163. package/dist/web-ui/public/file-selection-tree.js +1 -1
  164. package/dist/web-ui/public/git-history-lazy-utils.js +1 -1
  165. package/dist/web-ui/public/git-history.js +1 -1
  166. package/dist/web-ui/public/git-status.js +1 -1
  167. package/dist/web-ui/public/ibmi-file-filter.js +1 -1
  168. package/dist/web-ui/public/index.js +1 -1
  169. package/dist/web-ui/public/login.js +1 -1
  170. package/dist/web-ui/public/markdown-editor.js +1 -1
  171. package/dist/web-ui/public/markdown-file-editor.js +1 -1
  172. package/dist/web-ui/public/modal-maximize.js +1 -1
  173. package/dist/web-ui/public/notifications.js +1 -1
  174. package/dist/web-ui/public/permissions.js +1 -1
  175. package/dist/web-ui/public/pr-dialog.js +1 -1
  176. package/dist/web-ui/public/roles.js +1 -1
  177. package/dist/web-ui/public/settings.html +245 -0
  178. package/dist/web-ui/public/settings.js +1 -1
  179. package/dist/web-ui/public/setup-password.js +1 -1
  180. package/dist/web-ui/public/skills.js +1 -1
  181. package/dist/web-ui/public/sse-client.js +1 -1
  182. package/dist/web-ui/public/sse-client.transport-warning.js +1 -0
  183. package/dist/web-ui/public/sse-shared-worker.js +1 -1
  184. package/dist/web-ui/public/task-judging-helpers.js +1 -1
  185. package/dist/web-ui/public/task.js +1 -1
  186. package/dist/web-ui/public/teams.js +1 -1
  187. package/dist/web-ui/public/terminal.js +1 -1
  188. package/dist/web-ui/public/theme.js +1 -1
  189. package/dist/web-ui/public/users.js +1 -1
  190. package/dist/web-ui/public/variant-grouping.js +1 -1
  191. package/package.json +1 -1
@@ -0,0 +1,102 @@
1
+ # Container Lifecycle
2
+
3
+ CoderFlow automatically manages the lifecycle of task containers to balance resource usage with availability. Containers progress through several phases—from creation to eventual removal—based on activity, task status, and configuration.
4
+
5
+ ## Container States
6
+
7
+ A task container can be in one of these states:
8
+
9
+ | State | Description |
10
+ |-------|-------------|
11
+ | **Running** | Container is active. The agent may be executing, or the task may be completed but the container kept available for interaction (terminal access, file browsing, app server testing). |
12
+ | **Stopped** | Container has been stopped due to inactivity but still exists on disk. It can be restarted if needed. |
13
+ | **Removed** | Container has been permanently deleted. The task's data (logs, output, diffs) is preserved, but the container environment is gone. |
14
+
15
+ ## Automatic Sleep (Stopping Inactive Containers)
16
+
17
+ CoderFlow runs a cleanup job every **10 minutes** that checks for containers with no recent activity. When a container exceeds the inactivity threshold, it is gracefully stopped.
18
+
19
+ ### Inactivity Thresholds
20
+
21
+ | Container Type | Default Threshold |
22
+ |----------------|-------------------|
23
+ | Standard containers | **2 hours** |
24
+ | Pinned containers | **48 hours** |
25
+
26
+ The standard threshold can be configured by setting the `CONTAINER_CLEANUP_HOURS` environment variable on the CoderFlow server.
27
+
28
+ ### What Counts as Activity
29
+
30
+ The inactivity timer resets whenever a user or the system interacts with the task:
31
+
32
+ - **Viewing the task** in the Web UI
33
+ - **Opening a terminal** session to the container
34
+ - **Providing feedback** or starting a follow-up agent run
35
+ - **Approving** the task
36
+ - **Pinning or unpinning** the task
37
+ - **Changing winner/loser status** on a variant
38
+ - **Agent execution** finishing (timer starts from completion time)
39
+
40
+ If none of these interactions occur within the threshold period, the container is stopped.
41
+
42
+ ### Stopped Containers Are Not Lost
43
+
44
+ Stopping a container does **not** delete the task's work. All code changes, logs, and output remain intact. The container can be restarted for further interaction—such as reviewing files, running terminals, or providing additional feedback.
45
+
46
+ ## Automatic Removal (Deleting Containers)
47
+
48
+ Stopped containers are only removed when it is safe to do so—meaning no work will be lost. The same cleanup job that stops inactive containers also checks stopped containers for removal eligibility.
49
+
50
+ A stopped container is removed when **any** of these conditions are met:
51
+
52
+ | Condition | What It Means |
53
+ |-----------|---------------|
54
+ | **Approved and pushed** | The task was approved and its changes were successfully pushed to the remote repository. The code is safely stored in Git. |
55
+ | **Marked as loser** | The task variant was explicitly marked as a loser during winner selection. The user has decided this variant's changes should be discarded. |
56
+ | **Rejected** | The task was rejected via the CLI. Rejection immediately stops and removes the container. |
57
+
58
+ ### Containers That Are Never Auto-Removed
59
+
60
+ **Pinned containers** are never automatically stopped or removed, regardless of inactivity. They are preserved indefinitely for demos, reference, or ongoing work. To free resources from a pinned container, you must first unpin the task.
61
+
62
+ ## IBM i Task Libraries
63
+
64
+ When an environment has an IBM i connection with the Build feature enabled, CoderFlow creates a **temporary task library** (DB2 schema) on the IBM i system for each task. This library provides an isolated build environment so that tasks do not interfere with each other or with production libraries.
65
+
66
+ ### Lifecycle
67
+
68
+ Task libraries follow the same lifecycle as the container they belong to:
69
+
70
+ | Event | What Happens |
71
+ |-------|-------------|
72
+ | **Task starts** | A uniquely named library is created on the IBM i system (e.g., `AITSK_ABC123...`) and added to the job's library list. |
73
+ | **Container is stopped** | The library is automatically deleted (`DROP SCHEMA CASCADE`) as part of the container's shutdown cleanup. |
74
+
75
+ Because library cleanup runs when the container stops, **task libraries persist for as long as the container is running**—up to **2 hours** of inactivity for standard containers, or **48 hours** for pinned containers (see [Inactivity Thresholds](#inactivity-thresholds) above).
76
+
77
+ ### Orphaned Libraries
78
+
79
+ In some cases, a task library may not be cleaned up automatically:
80
+
81
+ - **Container crash** — if the container is terminated abruptly (e.g., the Docker host crashes) without running its shutdown handler, the cleanup script never executes.
82
+ - **Object locks** — if an IBM i job still holds a lock on an object in the library at shutdown time, the `DROP SCHEMA CASCADE` will fail. The error is logged but the container shutdown continues, leaving the library behind.
83
+
84
+ Orphaned libraries can be identified by their description text, which includes the CoderFlow task ID (e.g., `CoderFlow task 1711484523456-k7f2xm9`). They can be safely deleted manually using `DLTLIB` once any locks are released.
85
+
86
+ ## Orphaned Directory Cleanup
87
+
88
+ Task directories that have no associated `task.json` file (orphaned data from interrupted container creation or other edge cases) are automatically deleted after **24 hours**.
89
+
90
+ ## Summary
91
+
92
+ 1. **Running** — container is active; activity resets the inactivity timer
93
+ 2. **Stopped** — no activity for 2h (48h if pinned); container can be restarted
94
+ 3. **Removed** — approved+pushed or marked as loser; task data preserved, container gone
95
+
96
+ ## Configuration Reference
97
+
98
+ | Environment Variable | Default | Description |
99
+ |---------------------|---------|-------------|
100
+ | `CONTAINER_CLEANUP_HOURS` | `2` | Hours of inactivity before a standard (non-pinned) container is stopped |
101
+
102
+ Pinned container thresholds and the cleanup check interval are not currently configurable.
@@ -67,9 +67,24 @@ The API token authenticates as the associated account. The integration will have
67
67
 
68
68
  ## Setup
69
69
 
70
- Jira can be configured using the interactive CLI wizard or by editing the configuration file directly.
70
+ Jira can be configured from the **Settings** page in the Web UI, using the interactive CLI wizard, or by editing the configuration file directly.
71
71
 
72
- ### CLI Setup (Recommended)
72
+ ### Web UI Setup (Recommended)
73
+
74
+ The easiest way to configure Jira is from the Settings page:
75
+
76
+ 1. Go to **Settings → Jira**
77
+ 2. Toggle **Enabled** on
78
+ 3. Choose your **Account Type** (personal or service account)
79
+ 4. Enter your **Jira Site URL** (e.g., `https://your-company.atlassian.net`)
80
+ 5. For service accounts: click **Fetch** to auto-detect your **Cloud ID**, or enter it manually
81
+ 6. Enter the **Email** and **API Token** for the account
82
+ 7. Click **Test Connection** to verify the credentials
83
+ 8. Click **Save**
84
+
85
+ Changes take effect immediately — no server restart is needed. You can also use the **Disconnect** button to remove the configuration entirely.
86
+
87
+ ### CLI Setup
73
88
 
74
89
  The server CLI provides a guided setup that tests the connection before saving:
75
90
 
@@ -139,6 +154,8 @@ When `JIRA_CLOUD_ID` is set, API calls are routed through `api.atlassian.com`, e
139
154
 
140
155
  ## Managing the Integration
141
156
 
157
+ You can manage the Jira integration from the **Settings → Jira** page in the Web UI (configure, test, or disconnect), or use the CLI commands below.
158
+
142
159
  ### CLI Commands
143
160
 
144
161
  Use `coder-server jira <command>` to manage the integration:
@@ -187,7 +204,7 @@ If you're using a service account, these comments will appear under the service
187
204
 
188
205
  ### "Jira integration not enabled"
189
206
 
190
- This appears when users try to import issues but Jira is not configured. Run `coder-server jira connect` or create the `jira.json` configuration file.
207
+ This appears when users try to import issues but Jira is not configured. Go to **Settings &rarr; Jira** in the Web UI, or run `coder-server jira connect` from the CLI.
191
208
 
192
209
  ### Authentication Failed (Service Accounts)
193
210
 
@@ -0,0 +1 @@
1
+ (function(){const _0x41edf0={'docsMarker':'/docs/','lifecycleBound':![],'linkObserver':null,'ensureSubSidebarFrame':null,'ensureSubSidebarRetryTimer':null,'observing':![]};function _0x3619a0(){return _0x41edf0['docsMarker']||'/docs/';}function _0x389a49(_0x332e20){const _0x4ede28=_0x3619a0(),_0x2b64c5=_0x332e20['indexOf'](_0x4ede28);if(_0x2b64c5===-0x1)return _0x4ede28;return _0x332e20['slice'](0x0,_0x2b64c5+_0x4ede28['length']);}function _0x5485ed(){const _0x180ff0=window['location']['hash']||'#/',_0x163877=_0x180ff0['slice'](0x1)['split']('?')[0x0]||'/';return _0x163877['charAt'](0x0)==='/'?_0x163877:'/'+_0x163877;}function _0x39dd0a(){const _0x2c1556=_0x5485ed();return _0x2c1556['slice'](0x0,_0x2c1556['lastIndexOf']('/')+0x1)||'/';}function _0x285e65(){const _0x1fd3cd=window['location']['hash']||'#/',_0x29bf47=_0x1fd3cd['indexOf']('?');return new URLSearchParams(_0x29bf47===-0x1?'':_0x1fd3cd['slice'](_0x29bf47+0x1));}function _0x2d402b(){return _0x285e65()['get']('id');}function _0x15b389(_0x88e4a3){return typeof _0x88e4a3==='string'&&_0x88e4a3['indexOf']('#/')===0x0;}function _0x3998b3(_0x3e4917){return!_0x3e4917||_0x3e4917['charAt'](0x0)==='#'&&!_0x15b389(_0x3e4917)||_0x3e4917['startsWith']('javascript:')||_0x3e4917['startsWith']('mailto:')||_0x3e4917['startsWith']('tel:');}function _0x3d903d(_0x5e5de8){if(_0x3998b3(_0x5e5de8)||!/\.md(?:$|[?#])/i['test'](_0x5e5de8))return null;const _0x362c73=_0x389a49(window['location']['pathname']),_0x42f414=_0x39dd0a();let _0x4f4698='',_0x410386='',_0x812930='';if(/^(?:[a-z]+:)?\/\//i['test'](_0x5e5de8)){const _0x45df6a=new URL(_0x5e5de8,window['location']['href']);if(_0x45df6a['origin']!==window['location']['origin'])return null;_0x4f4698=_0x45df6a['pathname'],_0x410386=_0x45df6a['search'],_0x812930=_0x45df6a['hash'];}else{if(_0x5e5de8['charAt'](0x0)==='/'){const _0x54a779=new URL(_0x5e5de8,window['location']['origin']);_0x4f4698=_0x54a779['pathname'],_0x410386=_0x54a779['search'],_0x812930=_0x54a779['hash'];}else{const _0x21871f=_0x5e5de8['startsWith']('./')||_0x5e5de8['startsWith']('../')?'https://docsify.local'+_0x42f414:'https://docsify.local/',_0x5e0775=new URL(_0x5e5de8,_0x21871f);_0x4f4698=_0x5e0775['pathname'],_0x410386=_0x5e0775['search'],_0x812930=_0x5e0775['hash'];}}let _0x2813f5=null;if(_0x4f4698['startsWith'](_0x362c73))_0x2813f5=_0x4f4698['slice'](_0x362c73['length']-0x1);else{const _0x252c70=_0x4f4698['indexOf'](_0x3619a0());if(_0x252c70!==-0x1)_0x2813f5=_0x4f4698['slice'](_0x252c70+_0x3619a0()['slice'](0x0,-0x1)['length']);else _0x5e5de8['charAt'](0x0)!=='/'&&(_0x2813f5=_0x4f4698);}if(!_0x2813f5||!/\.md$/i['test'](_0x2813f5))return null;_0x2813f5=_0x2813f5['replace'](/\/README\.md$/i,'/'),_0x2813f5=_0x2813f5['replace'](/README\.md$/i,'/'),_0x2813f5=_0x2813f5['replace'](/\.md$/i,''),_0x2813f5=_0x2813f5||'/',_0x2813f5=_0x2813f5['charAt'](0x0)==='/'?_0x2813f5:'/'+_0x2813f5;const _0x16a173=new URLSearchParams(_0x410386);_0x812930&&_0x16a173['set']('id',decodeURIComponent(_0x812930['slice'](0x1)));const _0x3eb44c=_0x16a173['toString']();return'#'+_0x2813f5+(_0x3eb44c?'?'+_0x3eb44c:'');}function _0x395ba7(_0x2cadec){if(!_0x15b389(_0x2cadec))return null;const _0x25ef1d=_0x2cadec['slice'](0x1),_0xbec5cd=_0x25ef1d['indexOf']('?'),_0xa8f79b=_0xbec5cd===-0x1?_0x25ef1d:_0x25ef1d['slice'](0x0,_0xbec5cd),_0x4b6a13=_0xbec5cd===-0x1?'':_0x25ef1d['slice'](_0xbec5cd+0x1);if(!_0xa8f79b)return null;const _0x36b80e=new URL(_0xa8f79b,'https://docsify.local'+_0x39dd0a())['pathname'];return'#'+_0x36b80e+(_0x4b6a13?'?'+_0x4b6a13:'');}function _0x38a9d5(_0x137f00){if(_0x3998b3(_0x137f00))return null;if(_0x15b389(_0x137f00))return _0x395ba7(_0x137f00)||_0x137f00;return _0x3d903d(_0x137f00);}function _0x728e81(_0x368ce4){return String(_0x368ce4)['replace'](/&/g,'&amp;')['replace'](/</g,'&lt;')['replace'](/>/g,'&gt;')['replace'](/"/g,'&quot;')['replace'](/'/g,'&#39;');}function _0x13bfda(_0x5f01ea){const _0x44e1b7=_0x5f01ea['querySelector']('a.anchor');return _0x44e1b7?_0x44e1b7['textContent']['trim']():_0x5f01ea['textContent']['trim']();}function _0x3fe4ad(_0x4c9554){const _0x3143a7=String(_0x4c9554||'')['trim']();if(!_0x3143a7)return'section';if(window['Docsify']&&typeof window['Docsify']['slugify']==='function'){const _0x72ea02=window['Docsify']['slugify'](_0x3143a7);if(_0x72ea02)return _0x72ea02;}return _0x3143a7['toLowerCase']()['replace'](/[^\w\s-]/g,'')['replace'](/\s+/g,'-')['replace'](/-+/g,'-')['replace'](/^-|-$/g,'')||'section';}function _0x37d8fa(){const _0x47605f=Array['from'](document['querySelectorAll']('.markdown-section\x20h1,\x20.markdown-section\x20h2,\x20.markdown-section\x20h3,\x20.markdown-section\x20h4,\x20.markdown-section\x20h5,\x20.markdown-section\x20h6')),_0x3ac02a=new Set();return _0x47605f['forEach'](function(_0x139e3d){_0x139e3d['id']&&_0x3ac02a['add'](_0x139e3d['id']);}),_0x47605f['forEach'](function(_0x4079a9){if(_0x4079a9['id'])return;const _0x53ef24=_0x13bfda(_0x4079a9);if(!_0x53ef24)return;const _0x52d00f=_0x3fe4ad(_0x53ef24);let _0x576a07=_0x52d00f,_0x31ffb1=0x2;while(_0x3ac02a['has'](_0x576a07)){_0x576a07=_0x52d00f+'-'+_0x31ffb1,_0x31ffb1+=0x1;}_0x4079a9['id']=_0x576a07,_0x3ac02a['add'](_0x576a07);}),_0x47605f;}function _0x2a97f0(_0x2b668d){return Array['from'](_0x2b668d['children']||[])['find'](function(_0x2b3328){return _0x2b3328['classList']&&_0x2b3328['classList']['contains']('app-sub-sidebar');})||null;}function _0x5861e3(_0x56b11b){if(!_0x56b11b||_0x56b11b['nodeType']!==Node['ELEMENT_NODE'])return![];if(_0x56b11b['closest']&&_0x56b11b['closest']('.app-sub-sidebar[data-coderflow-managed=\x22true\x22]'))return![];return _0x56b11b['matches']&&_0x56b11b['matches']('.sidebar-nav,\x20.markdown-section')||_0x56b11b['closest']&&_0x56b11b['closest']('.sidebar-nav,\x20.markdown-section')||_0x56b11b['querySelector']&&_0x56b11b['querySelector']('.sidebar-nav,\x20.markdown-section');}function _0x1a36f9(){return _0x37d8fa()['filter'](function(_0x4c6047){return!!_0x4c6047['id'];});}function _0xc04305(_0x1b936d,_0x3757d9){const _0x11b5be=[],_0x3fc28a={};return _0x1b936d['forEach'](function(_0x2ebecd){const _0x50f6e6=_0x2ebecd['level']||0x1,_0x4dc966=_0x50f6e6-0x1;if(_0x50f6e6>_0x3757d9)return;_0x3fc28a[_0x4dc966]?_0x3fc28a[_0x4dc966]['children']=(_0x3fc28a[_0x4dc966]['children']||[])['concat'](_0x2ebecd):_0x11b5be['push'](_0x2ebecd),_0x3fc28a[_0x50f6e6]=_0x2ebecd;}),_0x11b5be;}function _0x2fa20c(_0x2222a7,_0x21a899,_0x5c78d3){if(!_0x2222a7['length'])return'';const _0x16d671=_0x5c78d3?'\x20class=\x22app-sub-sidebar\x22\x20data-coderflow-managed=\x22true\x22\x20data-coderflow-signature=\x22'+_0x728e81(_0x21a899)+'\x22':'\x20class=\x22app-sub-sidebar\x22';return'<ul'+_0x16d671+'>'+_0x2222a7['map'](function(_0x494011){const _0x51f952=_0x494011['children']?_0x2fa20c(_0x494011['children'],_0x21a899,![]):'';return'<li><a\x20class=\x22section-link\x22\x20href=\x22'+_0x728e81(_0x494011['slug'])+'\x22\x20title=\x22'+_0x728e81(_0x494011['title'])+'\x22>'+_0x728e81(_0x494011['title'])+'</a></li>'+_0x51f952;})['join']('')+'</ul>';}function _0x4aa8e1(){const _0x5dc2ee=Number(window['$docsify']&&window['$docsify']['subMaxLevel'])||0x0;if(!_0x5dc2ee)return{'html':'','signature':''};const _0x40d2b6=_0x1a36f9()['map'](function(_0x526822){const _0x236a56=_0x13bfda(_0x526822);if(!_0x236a56||!_0x526822['id'])return null;const _0x128371=_0x285e65();return _0x128371['set']('id',_0x526822['id']),{'level':Number['parseInt'](_0x526822['tagName']['slice'](0x1),0xa),'title':_0x236a56,'slug':'#'+_0x5485ed()+'?'+_0x128371['toString']()};})['filter'](Boolean);_0x40d2b6[0x0]&&_0x40d2b6[0x0]['level']===0x1&&_0x40d2b6['shift']();if(!_0x40d2b6['length'])return{'html':'','signature':''};const _0x4cfefd=_0x40d2b6['map'](function(_0x2c452d){return _0x2c452d['level']+'|'+_0x2c452d['slug']+'|'+_0x2c452d['title'];})['join']('||');return{'html':_0x2fa20c(_0xc04305(_0x40d2b6,_0x5dc2ee),_0x4cfefd,!![]),'signature':_0x4cfefd};}function _0x29224b(){const _0x125e95='#'+_0x5485ed();let _0x1c6604=null,_0x1a37eb=-0x1;return document['querySelectorAll']('.sidebar-nav\x20a[href]')['forEach'](function(_0x51c68c){if(_0x51c68c['closest']('.app-sub-sidebar'))return;const _0x8afd04=_0x38a9d5(_0x51c68c['getAttribute']('href'));if(!_0x8afd04)return;const _0xf8c311=_0x8afd04['split']('?')[0x0];if(_0xf8c311!==_0x125e95)return;_0xf8c311['length']>_0x1a37eb&&(_0x1c6604=_0x51c68c,_0x1a37eb=_0xf8c311['length']);}),_0x1c6604;}function _0x57fb00(_0x462162){const _0x414dd1=_0x462162&&_0x462162['parentElement'],_0x5d305c=_0x414dd1&&_0x2a97f0(_0x414dd1),_0x582e88='#'+_0x5485ed(),_0x34514f=_0x2d402b();if(!_0x5d305c)return;_0x5d305c['querySelectorAll']('li')['forEach'](function(_0x21c0b9){_0x21c0b9['classList']['remove']('active');});if(!_0x34514f)return;const _0x216391=Array['from'](_0x5d305c['querySelectorAll']('a.section-link[href]'))['find'](function(_0x42093d){const _0x1d0605=_0x42093d['getAttribute']('href')||'';if(_0x1d0605['charAt'](0x0)!=='#')return![];const _0x248203=_0x1d0605['indexOf']('?'),_0x5aeff8=_0x248203===-0x1?_0x1d0605:_0x1d0605['slice'](0x0,_0x248203);if(_0x5aeff8!==_0x582e88)return![];const _0x495e62=new URLSearchParams(_0x248203===-0x1?'':_0x1d0605['slice'](_0x248203+0x1));return _0x495e62['get']('id')===_0x34514f;});_0x216391&&_0x216391['parentElement']&&_0x216391['parentElement']['classList']['add']('active');}function _0x58d22f(){const _0x4f0f70=_0x29224b();if(!_0x4f0f70||!_0x4f0f70['parentElement'])return![];const _0x3d4af3=_0x4f0f70['parentElement'],_0x2aa4a2=_0x4aa8e1(),_0x5034ce=_0x2aa4a2['html'],_0x2904fe=_0x2aa4a2['signature'];document['querySelectorAll']('.sidebar-nav\x20li')['forEach'](function(_0x1c0df6){if(_0x1c0df6!==_0x3d4af3){const _0x4caff6=_0x2a97f0(_0x1c0df6);_0x4caff6&&_0x4caff6['remove']();}});const _0x3b08b3=_0x2a97f0(_0x3d4af3);if(!_0x5034ce)return _0x3b08b3&&_0x3b08b3['remove'](),!![];return _0x3b08b3?_0x3b08b3['getAttribute']('data-coderflow-signature')!==_0x2904fe&&(_0x3b08b3['outerHTML']=_0x5034ce):_0x4f0f70['insertAdjacentHTML']('afterend',_0x5034ce),_0x3d4af3['classList']['add']('active','open'),_0x3d4af3['classList']['remove']('collapse'),_0x57fb00(_0x4f0f70),!![];}function _0x395047(_0x5c40ca){const _0x9ade7f=Number['isInteger'](_0x5c40ca)?_0x5c40ca:0x8;_0x41edf0['ensureSubSidebarFrame']!==null&&window['cancelAnimationFrame'](_0x41edf0['ensureSubSidebarFrame']),_0x41edf0['ensureSubSidebarRetryTimer']!==null&&(window['clearTimeout'](_0x41edf0['ensureSubSidebarRetryTimer']),_0x41edf0['ensureSubSidebarRetryTimer']=null),_0x41edf0['ensureSubSidebarFrame']=window['requestAnimationFrame'](function(){_0x41edf0['ensureSubSidebarFrame']=null,_0x58d22f();if(_0x9ade7f<=0x0)return;const _0x21d80f=_0x29224b(),_0x21f3fa=_0x1a36f9(),_0x19ac69=_0x21d80f&&_0x21d80f['parentElement']&&_0x2a97f0(_0x21d80f['parentElement']);(!_0x21d80f||_0x21f3fa['length']>0x1&&!_0x19ac69)&&(_0x41edf0['ensureSubSidebarRetryTimer']=window['setTimeout'](function(){_0x395047(_0x9ade7f-0x1);},0x4b));});}function _0x477afd(_0x59125a){const _0x2aa503=_0x59125a||document,_0x351083=_0x2aa503['querySelectorAll']?_0x2aa503['querySelectorAll']('a[href]'):[];_0x351083['forEach'](function(_0x5b8f07){const _0x46a4cb=_0x38a9d5(_0x5b8f07['getAttribute']('href'));_0x46a4cb&&_0x46a4cb!==_0x5b8f07['getAttribute']('href')&&_0x5b8f07['setAttribute']('href',_0x46a4cb);});}function _0x378169(){return!_0x41edf0['linkObserver']&&(_0x41edf0['linkObserver']=new MutationObserver(function(_0x359cd3){let _0x14389b=![];_0x359cd3['forEach'](function(_0x1b9cd6){_0x1b9cd6['addedNodes']['forEach'](function(_0x2ccfc8){_0x2ccfc8['nodeType']===Node['ELEMENT_NODE']&&(_0x477afd(_0x2ccfc8),_0x5861e3(_0x2ccfc8)&&(_0x14389b=!![]));});}),_0x14389b&&_0x395047(0x2);})),_0x41edf0['linkObserver'];}function _0x5ca9fa(){_0x477afd(),_0x395047(),!_0x41edf0['observing']&&document['body']&&(_0x378169()['observe'](document['body'],{'childList':!![],'subtree':!![]}),_0x41edf0['observing']=!![]);}function _0x38dcbe(){if(_0x41edf0['lifecycleBound'])return;_0x41edf0['lifecycleBound']=!![],document['readyState']==='loading'?document['addEventListener']('DOMContentLoaded',_0x5ca9fa,{'once':!![]}):_0x5ca9fa(),window['addEventListener']('hashchange',function(){_0x395047();});}function _0x5a214b(){return function(_0x2ba27d){_0x2ba27d['doneEach'](function(){_0x477afd(),_0x395047();});};}function _0x248c70(_0x59736a){const _0x4f9a3c=_0x59736a&&typeof _0x59736a['docsMarker']==='string'?_0x59736a['docsMarker']:_0x41edf0['docsMarker'];_0x41edf0['docsMarker']=_0x4f9a3c;const _0x5d1dd5=_0x389a49(window['location']['pathname']);return window['__CODERFLOW_DOCS_BASE_PATH__']=_0x5d1dd5,window['__CODERFLOW_ENSURE_SUB_SIDEBAR__']=_0x58d22f,window['__CODERFLOW_SCHEDULE_SUB_SIDEBAR__']=_0x395047,window['__CODERFLOW_NORMALIZE_DOCS_LINKS__']=_0x477afd,_0x38dcbe(),_0x5d1dd5;}window['CoderflowDocsifyProxy']={'createDocsifyPlugin':_0x5a214b,'ensureSubSidebar':_0x58d22f,'getDocsBasePath':_0x389a49,'init':_0x248c70,'normalizeDocsLinks':_0x477afd,'scheduleEnsureSubSidebar':_0x395047};}());
@@ -8,15 +8,15 @@
8
8
 
9
9
  <!-- docsify-themeable: auto dark/light mode based on system preference -->
10
10
  <link rel="stylesheet" media="(prefers-color-scheme: dark)"
11
- href="/vendor/docsify-themeable/0.9.0/dist/css/theme-simple-dark.css">
11
+ href="../vendor/docsify-themeable/0.9.0/dist/css/theme-simple-dark.css">
12
12
  <link rel="stylesheet" media="(prefers-color-scheme: light)"
13
- href="/vendor/docsify-themeable/0.9.0/dist/css/theme-simple.css">
13
+ href="../vendor/docsify-themeable/0.9.0/dist/css/theme-simple.css">
14
14
 
15
15
  <!-- Sidebar collapse with arrow/chevron icons -->
16
- <link rel="stylesheet" href="/vendor/docsify-sidebar-collapse/1.3.5/dist/sidebar.min.css">
16
+ <link rel="stylesheet" href="../vendor/docsify-sidebar-collapse/1.3.5/dist/sidebar.min.css">
17
17
 
18
18
  <!-- Prism syntax highlighting -->
19
- <link rel="stylesheet" href="/vendor/prismjs/1.30.0/themes/prism-tomorrow.min.css">
19
+ <link rel="stylesheet" href="../vendor/prismjs/1.30.0/themes/prism-tomorrow.min.css">
20
20
 
21
21
  <style>
22
22
  :root {
@@ -69,10 +69,13 @@
69
69
  <body>
70
70
  <div id="app">Loading documentation...</div>
71
71
 
72
+ <script src="docsify-proxy-helper.js"></script>
72
73
  <script>
74
+ var docsBasePath = window.CoderflowDocsifyProxy.init({ docsMarker: '/docs/' });
75
+
73
76
  window.$docsify = {
74
77
  name: 'CoderFlow',
75
- nameLink: '/docs/',
78
+ nameLink: docsBasePath || '/docs/',
76
79
  repo: '',
77
80
  loadSidebar: true,
78
81
  alias: {
@@ -94,27 +97,31 @@
94
97
  copyCode: {
95
98
  buttonText: 'Copy',
96
99
  successText: 'Copied'
97
- }
100
+ },
101
+
102
+ plugins: [
103
+ window.CoderflowDocsifyProxy.createDocsifyPlugin()
104
+ ]
98
105
  };
99
106
  </script>
100
107
 
101
108
  <!-- Docsify core -->
102
- <script src="/vendor/docsify/4.13.1/lib/docsify.min.js"></script>
109
+ <script src="../vendor/docsify/4.13.1/lib/docsify.min.js"></script>
103
110
 
104
111
  <!-- docsify-themeable (must come after docsify) -->
105
- <script src="/vendor/docsify-themeable/0.9.0/dist/js/docsify-themeable.min.js"></script>
112
+ <script src="../vendor/docsify-themeable/0.9.0/dist/js/docsify-themeable.min.js"></script>
106
113
 
107
114
  <!-- Plugins -->
108
- <script src="/vendor/docsify-sidebar-collapse/1.3.5/dist/docsify-sidebar-collapse.min.js"></script>
109
- <script src="/vendor/docsify/4.13.1/lib/plugins/search.min.js"></script>
110
- <script src="/vendor/docsify-copy-code/2.1.1/dist/docsify-copy-code.min.js"></script>
111
- <script src="/vendor/docsify-plugin-flexible-alerts/1.2.0/dist/docsify-plugin-flexible-alerts.min.js"></script>
115
+ <script src="../vendor/docsify-sidebar-collapse/1.3.5/dist/docsify-sidebar-collapse.min.js"></script>
116
+ <script src="../vendor/docsify/4.13.1/lib/plugins/search.min.js"></script>
117
+ <script src="../vendor/docsify-copy-code/2.1.1/dist/docsify-copy-code.min.js"></script>
118
+ <script src="../vendor/docsify-plugin-flexible-alerts/1.2.0/dist/docsify-plugin-flexible-alerts.min.js"></script>
112
119
 
113
120
  <!-- Syntax highlighting -->
114
- <script src="/vendor/prismjs/1.30.0/components/prism-bash.min.js"></script>
115
- <script src="/vendor/prismjs/1.30.0/components/prism-javascript.min.js"></script>
116
- <script src="/vendor/prismjs/1.30.0/components/prism-json.min.js"></script>
117
- <script src="/vendor/prismjs/1.30.0/components/prism-yaml.min.js"></script>
121
+ <script src="../vendor/prismjs/1.30.0/components/prism-bash.min.js"></script>
122
+ <script src="../vendor/prismjs/1.30.0/components/prism-javascript.min.js"></script>
123
+ <script src="../vendor/prismjs/1.30.0/components/prism-json.min.js"></script>
124
+ <script src="../vendor/prismjs/1.30.0/components/prism-yaml.min.js"></script>
118
125
 
119
126
  <!-- About CoderFlow Modal (shared with main UI) -->
120
127
  <div id="about-coderflow-modal" class="modal" hidden>
@@ -131,8 +138,8 @@
131
138
  </div>
132
139
  <div class="modal-body about-modal-body">
133
140
  <div class="about-modal-hero">
134
- <img src="/coderflow-logo.svg" alt="CoderFlow" class="brand-logo brand-logo-light about-logo">
135
- <img src="/coderflow-logo-reversed.svg" alt="CoderFlow" class="brand-logo brand-logo-dark about-logo">
141
+ <img src="../coderflow-logo.svg" alt="CoderFlow" class="brand-logo brand-logo-light about-logo">
142
+ <img src="../coderflow-logo-reversed.svg" alt="CoderFlow" class="brand-logo brand-logo-dark about-logo">
136
143
  </div>
137
144
  <div class="about-version-card">
138
145
  <span class="about-version-label">Server version</span>
@@ -270,6 +270,7 @@
270
270
  <path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"></path>
271
271
  </svg>
272
272
  Connections
273
+ <span class="content-tab-badge" id="badge-connections" hidden></span>
273
274
  </button>
274
275
  <button class="content-tab" data-tab="env-vars" role="tab">
275
276
  <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" style="margin-right: 4px; vertical-align: text-bottom;">