@webship.co/workspace 1.0.0-alpha1 → 1.0.0-beta2

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 (634) hide show
  1. package/LICENSE +339 -0
  2. package/README.md +28 -364
  3. package/core/bin/workspace.js +135 -0
  4. package/core/config/settings.labels.yml +514 -0
  5. package/core/config/settings.template.yml +292 -0
  6. package/core/config/style.yml +53 -0
  7. package/core/config/theme.default.yml +161 -0
  8. package/core/config/theme.dispatch.yml +166 -0
  9. package/core/config/theme.drupal.yml +175 -0
  10. package/core/config/theme.ember.yml +160 -0
  11. package/core/config/theme.github.yml +172 -0
  12. package/core/config/theme.gitlab.yml +168 -0
  13. package/core/config/theme.press.yml +161 -0
  14. package/core/config/theme.slate.yml +160 -0
  15. package/core/config/theme.upsun.yml +174 -0
  16. package/core/docs/architecture.svg +65 -0
  17. package/core/docs/getting-started.md +51 -0
  18. package/core/docs/plugins.md +27 -0
  19. package/core/docs/releases.md +23 -0
  20. package/core/docs/testing.md +15 -0
  21. package/core/docs/workspaces.md +25 -0
  22. package/core/scripts/args/arg-ai-items.sh +65 -0
  23. package/core/scripts/args/arg-autostart.sh +31 -0
  24. package/core/scripts/args/arg-avatar-agent.sh +28 -0
  25. package/core/scripts/args/arg-avatar-catalog.sh +12 -0
  26. package/core/scripts/args/arg-avatar-character.sh +68 -0
  27. package/core/scripts/args/arg-avatar-voice.sh +24 -0
  28. package/core/scripts/args/arg-avatar.sh +22 -0
  29. package/core/scripts/args/arg-checks.sh +36 -0
  30. package/core/scripts/args/arg-clone.sh +42 -0
  31. package/core/scripts/args/arg-commands.sh +51 -0
  32. package/core/scripts/args/arg-cucumber.sh +34 -0
  33. package/core/scripts/args/arg-distribution.sh +30 -0
  34. package/core/scripts/args/arg-drupal.sh +39 -0
  35. package/core/scripts/args/arg-drupal_cms.sh +18 -0
  36. package/core/scripts/args/arg-gitlab-ci-local.sh +25 -0
  37. package/core/scripts/args/arg-graphify.sh +36 -0
  38. package/core/scripts/args/arg-graphs.sh +12 -0
  39. package/core/scripts/args/arg-hostnames.sh +23 -0
  40. package/core/scripts/args/arg-milvus-backup.sh +8 -0
  41. package/core/scripts/args/arg-milvus-mcp.sh +12 -0
  42. package/core/scripts/args/arg-milvus.sh +32 -0
  43. package/core/scripts/args/arg-obsidian.sh +17 -0
  44. package/core/scripts/args/arg-odoo.sh +18 -0
  45. package/core/scripts/args/arg-penpot-backup.sh +8 -0
  46. package/core/scripts/args/arg-penpot-mcp.sh +15 -0
  47. package/core/scripts/args/arg-penpot-token.sh +17 -0
  48. package/core/scripts/args/arg-penpot.sh +44 -0
  49. package/core/scripts/args/arg-rag.sh +21 -0
  50. package/core/scripts/args/arg-ragify.sh +35 -0
  51. package/core/scripts/args/arg-reclaim.sh +18 -0
  52. package/core/scripts/args/arg-release.sh +21 -0
  53. package/core/scripts/args/arg-screen.sh +28 -0
  54. package/core/scripts/args/arg-site-template.sh +13 -0
  55. package/core/scripts/args/arg-spdd.sh +16 -0
  56. package/core/scripts/args/arg-specs.sh +22 -0
  57. package/core/scripts/args/arg-storage.sh +36 -0
  58. package/core/scripts/args/arg-testing.sh +36 -0
  59. package/core/scripts/args/arg-webship.sh +34 -0
  60. package/core/scripts/args/arg-webships-project.sh +22 -0
  61. package/core/scripts/args/arg-webships-site-template.sh +17 -0
  62. package/core/scripts/args/arg-webships.sh +34 -0
  63. package/core/scripts/args/arg-website-site-template.sh +17 -0
  64. package/core/scripts/args/arg-website.sh +25 -0
  65. package/core/scripts/args/arg-wordpress.sh +18 -0
  66. package/core/scripts/autostart-run.sh +162 -0
  67. package/core/scripts/autostart-stop.sh +30 -0
  68. package/core/scripts/autostart-watch.sh +43 -0
  69. package/core/scripts/autostart.sh +26 -0
  70. package/core/scripts/bootstrap-functions.sh +117 -0
  71. package/core/scripts/bootstrap-libraries.sh +10 -0
  72. package/core/scripts/bootstrap.sh +71 -0
  73. package/core/scripts/ddev-shim/ddev +122 -0
  74. package/core/scripts/docker-gid.sh +119 -0
  75. package/core/scripts/functions/arg-site-template.sh +28 -0
  76. package/core/scripts/functions/fun-ai-items-lock.sh +175 -0
  77. package/core/scripts/functions/fun-ai-items-sources.sh +298 -0
  78. package/core/scripts/functions/fun-ai-items.sh +621 -0
  79. package/core/scripts/functions/fun-ai-providers.sh +72 -0
  80. package/core/scripts/functions/fun-autostart.sh +429 -0
  81. package/core/scripts/functions/fun-avatar.sh +441 -0
  82. package/core/scripts/functions/fun-backup-item.sh +50 -0
  83. package/core/scripts/functions/fun-build-distribution.sh +226 -0
  84. package/core/scripts/functions/fun-build-site-template.sh +104 -0
  85. package/core/scripts/functions/fun-build-webships.sh +161 -0
  86. package/core/scripts/functions/fun-build-website.sh +199 -0
  87. package/core/scripts/functions/fun-checks.sh +243 -0
  88. package/core/scripts/functions/fun-clone-project.sh +289 -0
  89. package/core/scripts/functions/fun-commands.sh +521 -0
  90. package/core/scripts/functions/fun-database.sh +63 -0
  91. package/core/scripts/functions/fun-ddev-hostnames.sh +213 -0
  92. package/core/scripts/functions/fun-ddev-nodejs.sh +15 -0
  93. package/core/scripts/functions/fun-ddev-telemetry.sh +15 -0
  94. package/core/scripts/functions/fun-default-settings.sh +28 -0
  95. package/core/scripts/functions/fun-distribution-cucumber.sh +45 -0
  96. package/core/scripts/functions/fun-distribution-drupal.sh +25 -0
  97. package/core/scripts/functions/fun-distribution-drupal_cms.sh +35 -0
  98. package/core/scripts/functions/fun-distribution-webship.sh +28 -0
  99. package/core/scripts/functions/fun-distribution-webships.sh +33 -0
  100. package/core/scripts/functions/fun-distribution-website.sh +19 -0
  101. package/core/scripts/functions/fun-drush.sh +48 -0
  102. package/core/scripts/functions/fun-elevenlabs.sh +179 -0
  103. package/core/scripts/functions/fun-files.sh +19 -0
  104. package/core/scripts/functions/fun-git-worktrees.sh +142 -0
  105. package/core/scripts/functions/fun-gitlab-ci.sh +156 -0
  106. package/core/scripts/functions/fun-hostnames-cli.sh +88 -0
  107. package/core/scripts/functions/fun-milvus.sh +584 -0
  108. package/core/scripts/functions/fun-odoo.sh +121 -0
  109. package/core/scripts/functions/fun-penpot.sh +724 -0
  110. package/core/scripts/functions/fun-project-name.sh +20 -0
  111. package/core/scripts/functions/fun-rag.sh +253 -0
  112. package/core/scripts/functions/fun-ragify.sh +165 -0
  113. package/core/scripts/functions/fun-reclaim.sh +297 -0
  114. package/core/scripts/functions/fun-release.sh +159 -0
  115. package/core/scripts/functions/fun-remove-project.sh +319 -0
  116. package/core/scripts/functions/fun-screen.sh +96 -0
  117. package/core/scripts/functions/fun-spdd.sh +676 -0
  118. package/core/scripts/functions/fun-specs-share.sh +237 -0
  119. package/core/scripts/functions/fun-storage.sh +347 -0
  120. package/core/scripts/functions/fun-testing.sh +329 -0
  121. package/core/scripts/functions/fun-users.sh +87 -0
  122. package/core/scripts/functions/fun-version.sh +72 -0
  123. package/core/scripts/functions/fun-video-edit.sh +48 -0
  124. package/core/scripts/functions/fun-voice.sh +45 -0
  125. package/core/scripts/functions/fun-wordpress.sh +59 -0
  126. package/core/scripts/host-mounts.sh +161 -0
  127. package/core/scripts/install.sh +602 -0
  128. package/core/scripts/libs/__pycache__/video_edit.cpython-312.pyc +0 -0
  129. package/core/scripts/libs/argparse.sh +93 -0
  130. package/core/scripts/libs/bash-yaml.sh +52 -0
  131. package/core/scripts/libs/checks_plan.js +312 -0
  132. package/core/scripts/libs/elevenlabs.py +627 -0
  133. package/core/scripts/libs/progress-bar.sh +19 -0
  134. package/core/scripts/libs/rag_index.py +446 -0
  135. package/core/scripts/libs/video_edit.py +636 -0
  136. package/core/scripts/libs/voice.py +430 -0
  137. package/core/scripts/plugins/jira/host-install.sh +119 -0
  138. package/core/scripts/plugins/jira/host-mounts.txt +2 -0
  139. package/core/scripts/plugins/upsun/args/arg-upsun.sh +51 -0
  140. package/core/scripts/plugins/upsun/functions/fun-upsun.sh +304 -0
  141. package/core/scripts/plugins/upsun/host-install.sh +99 -0
  142. package/core/scripts/plugins/upsun/host-mounts.txt +1 -0
  143. package/core/scripts/plugins/upsun/upsun-ai.sh +133 -0
  144. package/core/scripts/plugins.sh +152 -0
  145. package/core/scripts/release.sh +69 -0
  146. package/core/scripts/storage.sh +39 -0
  147. package/core/scripts/sync-tooling.sh +246 -0
  148. package/core/scripts/tests/cmd-smoke-test.sh +109 -0
  149. package/core/scripts/trust-https.sh +257 -0
  150. package/core/workspace-app/.ddev/commands/web/test-dashboard +49 -0
  151. package/core/workspace-app/.ddev/config.yaml +400 -0
  152. package/core/workspace-app/.ddev/docker-compose.dood.yaml +45 -0
  153. package/core/workspace-app/.ddev/docker-compose.plugin-jira-twg.yaml +26 -0
  154. package/core/workspace-app/.ddev/docker-compose.plugin-upsun-upsun-cli.yaml +8 -0
  155. package/core/workspace-app/.ddev/docker-compose.screens.yaml +15 -0
  156. package/core/workspace-app/.ddev/nginx_full/nginx-site.conf +114 -0
  157. package/core/workspace-app/.ddev/web-build/Dockerfile.workspace-app +203 -0
  158. package/core/workspace-app/.ddev/web-build/ddev-shim-ddev +122 -0
  159. package/{PLUGINS.md → core/workspace-app/PLUGINS.md} +1 -1
  160. package/core/workspace-app/README.md +380 -0
  161. package/{actions → core/workspace-app/actions}/ddev.js +0 -1
  162. package/{actions → core/workspace-app/actions}/rag.js +0 -1
  163. package/{actions → core/workspace-app/actions}/testing.js +0 -1
  164. package/{assistant.js → core/workspace-app/assistant.js} +1 -10
  165. package/{git-info.js → core/workspace-app/git-info.js} +17 -1
  166. package/core/workspace-app/package.json +29 -0
  167. package/core/workspace-app/plugin-catalog.js +50 -0
  168. package/{plugin-loader.js → core/workspace-app/plugin-loader.js} +19 -1
  169. package/{plugins-page.js → core/workspace-app/plugins-page.js} +28 -2
  170. package/{row-layout.js → core/workspace-app/row-layout.js} +0 -1
  171. package/{server.js → core/workspace-app/server.js} +26 -225
  172. package/core/workspace-app/tests/features/actions-rail.feature +44 -0
  173. package/core/workspace-app/tests/features/ai-items.feature +23 -0
  174. package/core/workspace-app/tests/features/assistant-speech.feature +63 -0
  175. package/core/workspace-app/tests/features/checks.feature +39 -0
  176. package/core/workspace-app/tests/features/clone-project.feature +30 -0
  177. package/core/workspace-app/tests/features/command-authoring.feature +58 -0
  178. package/core/workspace-app/tests/features/dashboard.feature +57 -0
  179. package/core/workspace-app/tests/features/menus.feature +29 -0
  180. package/core/workspace-app/tests/features/plugins/jira/jira.feature +47 -0
  181. package/core/workspace-app/tests/features/plugins.feature +20 -0
  182. package/core/workspace-app/tests/features/project-actions.feature +40 -0
  183. package/core/workspace-app/tests/features/screens.feature +29 -0
  184. package/core/workspace-app/tests/features/settings.feature +46 -0
  185. package/core/workspace-app/tests/features/test-reports.feature +32 -0
  186. package/core/workspace-app/tests/features/theme.feature +40 -0
  187. package/core/workspace-app/tests/step-definitions/actions-post.steps.js +25 -0
  188. package/core/workspace-app/tests/step-definitions/assistant-speech.steps.js +152 -0
  189. package/core/workspace-app/tests/step-definitions/preconditions.steps.js +100 -0
  190. package/core/workspace-app/tests/unit/_isolated-config.js +31 -0
  191. package/core/workspace-app/tests/unit/accessibility.test.js +124 -0
  192. package/core/workspace-app/tests/unit/actions-rail-ux.test.js +56 -0
  193. package/core/workspace-app/tests/unit/actions-rail.test.js +51 -0
  194. package/core/workspace-app/tests/unit/ai-inventory.test.js +64 -0
  195. package/core/workspace-app/tests/unit/app-docs.test.js +64 -0
  196. package/core/workspace-app/tests/unit/assistant-avatar.test.js +110 -0
  197. package/core/workspace-app/tests/unit/assistant-cast.test.js +105 -0
  198. package/core/workspace-app/tests/unit/assistant-send-animation.test.js +15 -0
  199. package/core/workspace-app/tests/unit/assistant-suggestions.test.js +112 -0
  200. package/core/workspace-app/tests/unit/assistant-switches.test.js +53 -0
  201. package/core/workspace-app/tests/unit/assistant-views.test.js +146 -0
  202. package/core/workspace-app/tests/unit/assistant-working-indicator.test.js +49 -0
  203. package/core/workspace-app/tests/unit/assistant.test.js +61 -0
  204. package/core/workspace-app/tests/unit/audio-player.test.js +147 -0
  205. package/core/workspace-app/tests/unit/audio-voice.test.js +634 -0
  206. package/core/workspace-app/tests/unit/auth-google.test.js +180 -0
  207. package/core/workspace-app/tests/unit/autostart-watch.test.js +76 -0
  208. package/core/workspace-app/tests/unit/browsers.test.js +76 -0
  209. package/core/workspace-app/tests/unit/build-distribution.test.js +125 -0
  210. package/core/workspace-app/tests/unit/build-order.test.js +153 -0
  211. package/core/workspace-app/tests/unit/builder-args.test.js +113 -0
  212. package/core/workspace-app/tests/unit/builders.test.js +158 -0
  213. package/core/workspace-app/tests/unit/card-state-toggle.test.js +29 -0
  214. package/core/workspace-app/tests/unit/changelog.test.js +177 -0
  215. package/core/workspace-app/tests/unit/chat-thread.test.js +92 -0
  216. package/core/workspace-app/tests/unit/checks-plan.test.js +205 -0
  217. package/core/workspace-app/tests/unit/claude-args.test.js +182 -0
  218. package/core/workspace-app/tests/unit/claude-code-here.test.js +15 -0
  219. package/core/workspace-app/tests/unit/claude-resume.test.js +147 -0
  220. package/core/workspace-app/tests/unit/claude-screen-options.test.js +84 -0
  221. package/core/workspace-app/tests/unit/claude-session.test.js +41 -0
  222. package/core/workspace-app/tests/unit/command-flags.test.js +45 -0
  223. package/core/workspace-app/tests/unit/command-palette.test.js +105 -0
  224. package/core/workspace-app/tests/unit/commands-center.test.js +338 -0
  225. package/core/workspace-app/tests/unit/composer-menu.test.js +187 -0
  226. package/core/workspace-app/tests/unit/config-yaml.test.js +116 -0
  227. package/core/workspace-app/tests/unit/confirm-dialog.test.js +69 -0
  228. package/core/workspace-app/tests/unit/create-card.test.js +85 -0
  229. package/core/workspace-app/tests/unit/ddev-addons.test.js +144 -0
  230. package/core/workspace-app/tests/unit/ddev-auth-ssh.test.js +40 -0
  231. package/core/workspace-app/tests/unit/ddev-custom-commands.test.js +56 -0
  232. package/core/workspace-app/tests/unit/ddev-diagnose.test.js +57 -0
  233. package/core/workspace-app/tests/unit/ddev-domains.test.js +153 -0
  234. package/core/workspace-app/tests/unit/ddev-hostnames.test.js +143 -0
  235. package/core/workspace-app/tests/unit/ddev-import.test.js +82 -0
  236. package/core/workspace-app/tests/unit/ddev-mail.test.js +135 -0
  237. package/core/workspace-app/tests/unit/ddev-menu-and-create.test.js +28 -0
  238. package/core/workspace-app/tests/unit/ddev-mutagen.test.js +37 -0
  239. package/core/workspace-app/tests/unit/ddev-options.test.js +51 -0
  240. package/core/workspace-app/tests/unit/ddev-share.test.js +40 -0
  241. package/core/workspace-app/tests/unit/ddev-shim.test.js +57 -0
  242. package/core/workspace-app/tests/unit/ddev-snapshots.test.js +142 -0
  243. package/core/workspace-app/tests/unit/ddev-start-daemons.test.js +62 -0
  244. package/core/workspace-app/tests/unit/ddev-xdebug.test.js +41 -0
  245. package/core/workspace-app/tests/unit/deep-chat-origin.test.js +38 -0
  246. package/core/workspace-app/tests/unit/density.test.js +52 -0
  247. package/core/workspace-app/tests/unit/elevenlabs.test.js +453 -0
  248. package/core/workspace-app/tests/unit/event-log.test.js +102 -0
  249. package/core/workspace-app/tests/unit/favicon.test.js +68 -0
  250. package/core/workspace-app/tests/unit/files-browser.test.js +224 -0
  251. package/core/workspace-app/tests/unit/git-info.test.js +26 -0
  252. package/core/workspace-app/tests/unit/grid-and-list.test.js +103 -0
  253. package/core/workspace-app/tests/unit/host-tool-wrapper.test.js +18 -0
  254. package/core/workspace-app/tests/unit/html-patterns.test.js +51 -0
  255. package/core/workspace-app/tests/unit/ide-infra.test.js +28 -0
  256. package/core/workspace-app/tests/unit/images-ai.test.js +201 -0
  257. package/core/workspace-app/tests/unit/images-create.test.js +59 -0
  258. package/core/workspace-app/tests/unit/images-providers.test.js +248 -0
  259. package/core/workspace-app/tests/unit/images-svg.test.js +213 -0
  260. package/core/workspace-app/tests/unit/images-workspace.test.js +144 -0
  261. package/core/workspace-app/tests/unit/jobs-fragment.test.js +66 -0
  262. package/core/workspace-app/tests/unit/media-ux.test.js +164 -0
  263. package/core/workspace-app/tests/unit/modal-fit.test.js +87 -0
  264. package/core/workspace-app/tests/unit/modules-load.test.js +23 -0
  265. package/core/workspace-app/tests/unit/narration.test.js +186 -0
  266. package/core/workspace-app/tests/unit/navigation-editor.test.js +260 -0
  267. package/core/workspace-app/tests/unit/navigation.test.js +254 -0
  268. package/core/workspace-app/tests/unit/new-folder.test.js +121 -0
  269. package/core/workspace-app/tests/unit/new-screen-form.test.js +149 -0
  270. package/core/workspace-app/tests/unit/node-menu.test.js +161 -0
  271. package/core/workspace-app/tests/unit/notes.test.js +128 -0
  272. package/core/workspace-app/tests/unit/page-structure.test.js +40 -0
  273. package/core/workspace-app/tests/unit/page-width.test.js +59 -0
  274. package/core/workspace-app/tests/unit/php-version.test.js +90 -0
  275. package/core/workspace-app/tests/unit/plan-card.test.js +44 -0
  276. package/core/workspace-app/tests/unit/plugin-catalog.test.js +31 -0
  277. package/core/workspace-app/tests/unit/plugin-system.test.js +251 -0
  278. package/core/workspace-app/tests/unit/plugins-page.test.js +28 -0
  279. package/core/workspace-app/tests/unit/plugins.test.js +58 -0
  280. package/core/workspace-app/tests/unit/project-activity-filter.test.js +180 -0
  281. package/core/workspace-app/tests/unit/project-make.test.js +143 -0
  282. package/core/workspace-app/tests/unit/project-name.test.js +202 -0
  283. package/core/workspace-app/tests/unit/reader.test.js +62 -0
  284. package/core/workspace-app/tests/unit/release.test.js +92 -0
  285. package/core/workspace-app/tests/unit/remove-confirm.test.js +37 -0
  286. package/core/workspace-app/tests/unit/report-pdf.test.js +171 -0
  287. package/core/workspace-app/tests/unit/round-11.test.js +31 -0
  288. package/core/workspace-app/tests/unit/round-12.test.js +37 -0
  289. package/core/workspace-app/tests/unit/row-layout.test.js +585 -0
  290. package/core/workspace-app/tests/unit/row-menus-fold.test.js +29 -0
  291. package/core/workspace-app/tests/unit/rows-add-modal.test.js +68 -0
  292. package/core/workspace-app/tests/unit/screen-runner-queue.test.js +41 -0
  293. package/core/workspace-app/tests/unit/screen-window.test.js +116 -0
  294. package/core/workspace-app/tests/unit/screens-beside-running.test.js +19 -0
  295. package/core/workspace-app/tests/unit/screens-columns.test.js +79 -0
  296. package/core/workspace-app/tests/unit/screens-menu.test.js +84 -0
  297. package/core/workspace-app/tests/unit/screens-modal-overlay.test.js +14 -0
  298. package/core/workspace-app/tests/unit/screens-waiting.test.js +129 -0
  299. package/core/workspace-app/tests/unit/screens.test.js +74 -0
  300. package/core/workspace-app/tests/unit/second-storage.test.js +218 -0
  301. package/core/workspace-app/tests/unit/session-name.test.js +64 -0
  302. package/core/workspace-app/tests/unit/settings-file.test.js +173 -0
  303. package/core/workspace-app/tests/unit/settings-nested-list.test.js +54 -0
  304. package/core/workspace-app/tests/unit/settings-raw.test.js +177 -0
  305. package/core/workspace-app/tests/unit/shared-prefs.test.js +49 -0
  306. package/core/workspace-app/tests/unit/speech.test.js +290 -0
  307. package/core/workspace-app/tests/unit/static-caching.test.js +39 -0
  308. package/core/workspace-app/tests/unit/status-language.test.js +47 -0
  309. package/core/workspace-app/tests/unit/tab-modal.test.js +69 -0
  310. package/core/workspace-app/tests/unit/tab-title.test.js +37 -0
  311. package/core/workspace-app/tests/unit/template-literals.test.js +52 -0
  312. package/core/workspace-app/tests/unit/terminal-scrollback.test.js +61 -0
  313. package/core/workspace-app/tests/unit/terminal-size.test.js +103 -0
  314. package/core/workspace-app/tests/unit/terminal-style.test.js +84 -0
  315. package/core/workspace-app/tests/unit/terminal-windows.test.js +154 -0
  316. package/core/workspace-app/tests/unit/themes.test.js +453 -0
  317. package/core/workspace-app/tests/unit/tool-labels.test.js +34 -0
  318. package/core/workspace-app/tests/unit/topbar-icons.test.js +47 -0
  319. package/core/workspace-app/tests/unit/update-docker-gid.test.js +51 -0
  320. package/core/workspace-app/tests/unit/user-guide.test.js +60 -0
  321. package/core/workspace-app/tests/unit/version-check.test.js +98 -0
  322. package/core/workspace-app/tests/unit/version-link.test.js +50 -0
  323. package/core/workspace-app/tests/unit/video-borrow.test.js +198 -0
  324. package/core/workspace-app/tests/unit/video-edit-ask.test.js +93 -0
  325. package/core/workspace-app/tests/unit/video-edit-short.test.js +42 -0
  326. package/core/workspace-app/tests/unit/video-edit.test.js +417 -0
  327. package/core/workspace-app/tests/unit/video-transcript.test.js +237 -0
  328. package/core/workspace-app/tests/unit/waiting.test.js +48 -0
  329. package/core/workspace-app/tests/unit/wordpress-odoo-builders.test.js +38 -0
  330. package/core/workspace-app/tests/unit/workspace-bin.test.js +48 -0
  331. package/core/workspace-app/tests/unit/workspace-card-tools.test.js +30 -0
  332. package/core/workspace-app/tests/unit/workspace-delete.test.js +77 -0
  333. package/core/workspace-app/tests/unit/workspace-types.test.js +68 -0
  334. package/core/workspace-app/tests/unit/worktree-clone.test.js +250 -0
  335. package/{workspace-types.js → core/workspace-app/workspace-types.js} +2 -2
  336. package/{workspaces.js → core/workspace-app/workspaces.js} +1 -5
  337. package/package.json +38 -36
  338. package/actions/graphs.js +0 -107
  339. package/actions/obsidian.js +0 -59
  340. package/graphs.js +0 -104
  341. package/obsidian.js +0 -405
  342. /package/{WORKSPACES.md → core/workspace-app/WORKSPACES.md} +0 -0
  343. /package/{actions → core/workspace-app/actions}/ai-items.js +0 -0
  344. /package/{actions → core/workspace-app/actions}/audio.js +0 -0
  345. /package/{actions → core/workspace-app/actions}/build-order.js +0 -0
  346. /package/{actions → core/workspace-app/actions}/checks.js +0 -0
  347. /package/{actions → core/workspace-app/actions}/claude-session.js +0 -0
  348. /package/{actions → core/workspace-app/actions}/commands-center.js +0 -0
  349. /package/{actions → core/workspace-app/actions}/composer.js +0 -0
  350. /package/{actions → core/workspace-app/actions}/ddev-addons.js +0 -0
  351. /package/{actions → core/workspace-app/actions}/ddev-mail.js +0 -0
  352. /package/{actions → core/workspace-app/actions}/folders.js +0 -0
  353. /package/{actions → core/workspace-app/actions}/images-svg.js +0 -0
  354. /package/{actions → core/workspace-app/actions}/images.js +0 -0
  355. /package/{actions → core/workspace-app/actions}/navigation.js +0 -0
  356. /package/{actions → core/workspace-app/actions}/node.js +0 -0
  357. /package/{actions → core/workspace-app/actions}/notes.js +0 -0
  358. /package/{actions → core/workspace-app/actions}/plugins.js +0 -0
  359. /package/{actions → core/workspace-app/actions}/project-make.js +0 -0
  360. /package/{actions → core/workspace-app/actions}/row-actions.js +0 -0
  361. /package/{actions → core/workspace-app/actions}/screens.js +0 -0
  362. /package/{actions → core/workspace-app/actions}/video-edit.js +0 -0
  363. /package/{ai-inventory.js → core/workspace-app/ai-inventory.js} +0 -0
  364. /package/{ai-items.js → core/workspace-app/ai-items.js} +0 -0
  365. /package/{assistant-cast.js → core/workspace-app/assistant-cast.js} +0 -0
  366. /package/{assistant-suggestions.js → core/workspace-app/assistant-suggestions.js} +0 -0
  367. /package/{audio-voice.js → core/workspace-app/audio-voice.js} +0 -0
  368. /package/{auth-google.js → core/workspace-app/auth-google.js} +0 -0
  369. /package/{build-ai.js → core/workspace-app/build-ai.js} +0 -0
  370. /package/{build-order-page.js → core/workspace-app/build-order-page.js} +0 -0
  371. /package/{build-order.js → core/workspace-app/build-order.js} +0 -0
  372. /package/{builder-args.js → core/workspace-app/builder-args.js} +0 -0
  373. /package/{changelog.js → core/workspace-app/changelog.js} +0 -0
  374. /package/{chat-threads.js → core/workspace-app/chat-threads.js} +0 -0
  375. /package/{checks.js → core/workspace-app/checks.js} +0 -0
  376. /package/{claude-args.js → core/workspace-app/claude-args.js} +0 -0
  377. /package/{claude-sessions.js → core/workspace-app/claude-sessions.js} +0 -0
  378. /package/{command-author.js → core/workspace-app/command-author.js} +0 -0
  379. /package/{command-block.js → core/workspace-app/command-block.js} +0 -0
  380. /package/{commands → core/workspace-app/commands}/defaults.yml +0 -0
  381. /package/{commands-page.js → core/workspace-app/commands-page.js} +0 -0
  382. /package/{commands.js → core/workspace-app/commands.js} +0 -0
  383. /package/{cucumber.js → core/workspace-app/cucumber.js} +0 -0
  384. /package/{ddev-addons-page.js → core/workspace-app/ddev-addons-page.js} +0 -0
  385. /package/{ddev-addons.js → core/workspace-app/ddev-addons.js} +0 -0
  386. /package/{ddev-custom-commands.js → core/workspace-app/ddev-custom-commands.js} +0 -0
  387. /package/{ddev-domains.js → core/workspace-app/ddev-domains.js} +0 -0
  388. /package/{ddev-import.js → core/workspace-app/ddev-import.js} +0 -0
  389. /package/{ddev-mail-page.js → core/workspace-app/ddev-mail-page.js} +0 -0
  390. /package/{ddev-mail.js → core/workspace-app/ddev-mail.js} +0 -0
  391. /package/{ddev-options.js → core/workspace-app/ddev-options.js} +0 -0
  392. /package/{ddev-snapshots.js → core/workspace-app/ddev-snapshots.js} +0 -0
  393. /package/{ddev.js → core/workspace-app/ddev.js} +0 -0
  394. /package/{docs → core/workspace-app/docs}/DEVELOPER-GUIDE.md +0 -0
  395. /package/{docs → core/workspace-app/docs}/README.md +0 -0
  396. /package/{docs → core/workspace-app/docs}/REFERENCE.md +0 -0
  397. /package/{docs → core/workspace-app/docs}/USER-GUIDE.md +0 -0
  398. /package/{docs → core/workspace-app/docs}/screenshots/assistant/avatar-board.png +0 -0
  399. /package/{docs → core/workspace-app/docs}/screenshots/assistant/avatar-coffee.png +0 -0
  400. /package/{docs → core/workspace-app/docs}/screenshots/assistant/avatar-colours.png +0 -0
  401. /package/{docs → core/workspace-app/docs}/screenshots/assistant/avatar-icons.png +0 -0
  402. /package/{docs → core/workspace-app/docs}/screenshots/assistant/avatar-moves.png +0 -0
  403. /package/{docs → core/workspace-app/docs}/screenshots/assistant/avatar-pick-cookieman.png +0 -0
  404. /package/{docs → core/workspace-app/docs}/screenshots/assistant/avatar-settings-voices.png +0 -0
  405. /package/{docs → core/workspace-app/docs}/screenshots/assistant/avatar-status.png +0 -0
  406. /package/{docs → core/workspace-app/docs}/screenshots/create-card/create-card.png +0 -0
  407. /package/{docs → core/workspace-app/docs}/screenshots/create-card/start-ai.png +0 -0
  408. /package/{docs → core/workspace-app/docs}/screenshots/guide-clone-address.png +0 -0
  409. /package/{docs → core/workspace-app/docs}/screenshots/guide-clone-worktree-off.png +0 -0
  410. /package/{docs → core/workspace-app/docs}/screenshots/guide-clone-worktree-on.png +0 -0
  411. /package/{docs → core/workspace-app/docs}/screenshots/guide-ddev-menu.png +0 -0
  412. /package/{docs → core/workspace-app/docs}/screenshots/guide-domains.png +0 -0
  413. /package/{docs → core/workspace-app/docs}/screenshots/guide-home.png +0 -0
  414. /package/{docs → core/workspace-app/docs}/screenshots/guide-ide-menu.png +0 -0
  415. /package/{docs → core/workspace-app/docs}/screenshots/guide-remove-refusal.png +0 -0
  416. /package/{docs → core/workspace-app/docs}/screenshots/guide-rows-worktree.png +0 -0
  417. /package/{docs → core/workspace-app/docs}/screenshots/guide-screens.png +0 -0
  418. /package/{docs → core/workspace-app/docs}/screenshots/guide-settings.png +0 -0
  419. /package/{docs → core/workspace-app/docs}/screenshots/guide-workspace-page.png +0 -0
  420. /package/{docs → core/workspace-app/docs}/screenshots/home/card-settings.png +0 -0
  421. /package/{docs → core/workspace-app/docs}/screenshots/home/drag-reorder.png +0 -0
  422. /package/{docs → core/workspace-app/docs}/screenshots/home/edit-card.png +0 -0
  423. /package/{docs → core/workspace-app/docs}/screenshots/images/claude-code-image.png +0 -0
  424. /package/{docs → core/workspace-app/docs}/screenshots/images/edit-with-ai.png +0 -0
  425. /package/{docs → core/workspace-app/docs}/screenshots/images/gallery.png +0 -0
  426. /package/{docs → core/workspace-app/docs}/screenshots/images/generate-description.png +0 -0
  427. /package/{docs → core/workspace-app/docs}/screenshots/images/generate-plan.png +0 -0
  428. /package/{docs → core/workspace-app/docs}/screenshots/images/providers.png +0 -0
  429. /package/{docs → core/workspace-app/docs}/screenshots/images/svg-form.png +0 -0
  430. /package/{docs → core/workspace-app/docs}/screenshots/images/svg-result.png +0 -0
  431. /package/{docs → core/workspace-app/docs}/screenshots/images/upload.png +0 -0
  432. /package/{docs → core/workspace-app/docs}/screenshots/new-folder/2-form.png +0 -0
  433. /package/{docs → core/workspace-app/docs}/screenshots/new-folder/8-ddev-options.png +0 -0
  434. /package/{docs → core/workspace-app/docs}/screenshots/new-folder/files-folder.png +0 -0
  435. /package/{docs → core/workspace-app/docs}/screenshots/projects/ddev-custom-commands.png +0 -0
  436. /package/{docs → core/workspace-app/docs}/screenshots/projects/state-chip-stop.png +0 -0
  437. /package/{docs → core/workspace-app/docs}/screenshots/readme/dashboard-dark.png +0 -0
  438. /package/{docs → core/workspace-app/docs}/screenshots/readme/dashboard-light.png +0 -0
  439. /package/{docs → core/workspace-app/docs}/screenshots/readme/dev-dark.png +0 -0
  440. /package/{docs → core/workspace-app/docs}/screenshots/readme/dev-light.png +0 -0
  441. /package/{docs → core/workspace-app/docs}/screenshots/readme/docs-dark.png +0 -0
  442. /package/{docs → core/workspace-app/docs}/screenshots/readme/docs-light.png +0 -0
  443. /package/{docs → core/workspace-app/docs}/screenshots/readme/icons/ai.svg +0 -0
  444. /package/{docs → core/workspace-app/docs}/screenshots/readme/icons/code.svg +0 -0
  445. /package/{docs → core/workspace-app/docs}/screenshots/readme/icons/docs.svg +0 -0
  446. /package/{docs → core/workspace-app/docs}/screenshots/readme/icons/services.svg +0 -0
  447. /package/{docs → core/workspace-app/docs}/screenshots/readme/icons/sites.svg +0 -0
  448. /package/{docs → core/workspace-app/docs}/screenshots/readme/test-report-dark.png +0 -0
  449. /package/{docs → core/workspace-app/docs}/screenshots/readme/test-report-light.png +0 -0
  450. /package/{docs → core/workspace-app/docs}/screenshots/readme/test-scenarios.png +0 -0
  451. /package/{docs → core/workspace-app/docs}/screenshots/readme/test-steps.png +0 -0
  452. /package/{docs → core/workspace-app/docs}/screenshots/readme/videos-dark.png +0 -0
  453. /package/{docs → core/workspace-app/docs}/screenshots/readme/videos-light.png +0 -0
  454. /package/{docs → core/workspace-app/docs}/screenshots/screens-menu.png +0 -0
  455. /package/{docs → core/workspace-app/docs}/screenshots/screens-new.png +0 -0
  456. /package/{docs → core/workspace-app/docs}/screenshots/settings/auth-google-lists.png +0 -0
  457. /package/{docs → core/workspace-app/docs}/screenshots/settings/delete-1-row.png +0 -0
  458. /package/{docs → core/workspace-app/docs}/screenshots/settings/delete-2-confirm.png +0 -0
  459. /package/{docs → core/workspace-app/docs}/screenshots/settings/delete-3-type-name.png +0 -0
  460. /package/{docs → core/workspace-app/docs}/screenshots/settings/delete-4-type-yes.png +0 -0
  461. /package/{event-log.js → core/workspace-app/event-log.js} +0 -0
  462. /package/{files-browser.js → core/workspace-app/files-browser.js} +0 -0
  463. /package/{folders.js → core/workspace-app/folders.js} +0 -0
  464. /package/{format.js → core/workspace-app/format.js} +0 -0
  465. /package/{github-auth.js → core/workspace-app/github-auth.js} +0 -0
  466. /package/{html.js → core/workspace-app/html.js} +0 -0
  467. /package/{icons.js → core/workspace-app/icons.js} +0 -0
  468. /package/{images-ai.js → core/workspace-app/images-ai.js} +0 -0
  469. /package/{images-create.js → core/workspace-app/images-create.js} +0 -0
  470. /package/{images-page.js → core/workspace-app/images-page.js} +0 -0
  471. /package/{images-records.js → core/workspace-app/images-records.js} +0 -0
  472. /package/{images-render.js → core/workspace-app/images-render.js} +0 -0
  473. /package/{images-svg-core.js → core/workspace-app/images-svg-core.js} +0 -0
  474. /package/{images-svg-sanitize.js → core/workspace-app/images-svg-sanitize.js} +0 -0
  475. /package/{images-svg.js → core/workspace-app/images-svg.js} +0 -0
  476. /package/{images.js → core/workspace-app/images.js} +0 -0
  477. /package/{jobs.js → core/workspace-app/jobs.js} +0 -0
  478. /package/{linger.js → core/workspace-app/linger.js} +0 -0
  479. /package/{lists.js → core/workspace-app/lists.js} +0 -0
  480. /package/{media-info.js → core/workspace-app/media-info.js} +0 -0
  481. /package/{navigation-page.js → core/workspace-app/navigation-page.js} +0 -0
  482. /package/{navigation.js → core/workspace-app/navigation.js} +0 -0
  483. /package/{notes.js → core/workspace-app/notes.js} +0 -0
  484. /package/{palette-index.js → core/workspace-app/palette-index.js} +0 -0
  485. /package/{playwright.config.js → core/workspace-app/playwright.config.js} +0 -0
  486. /package/{plugin-install.js → core/workspace-app/plugin-install.js} +0 -0
  487. /package/{plugin-manifest.js → core/workspace-app/plugin-manifest.js} +0 -0
  488. /package/{plugin-settings.js → core/workspace-app/plugin-settings.js} +0 -0
  489. /package/{plugins → core/workspace-app/plugins}/workspace-notes/index.js +0 -0
  490. /package/{project-make.js → core/workspace-app/project-make.js} +0 -0
  491. /package/{project-name.js → core/workspace-app/project-name.js} +0 -0
  492. /package/{public → core/workspace-app/public}/assistant-avatar-moves.js +0 -0
  493. /package/{public → core/workspace-app/public}/assistant-avatar-ui.js +0 -0
  494. /package/{public → core/workspace-app/public}/assistant-avatar.js +0 -0
  495. /package/{public → core/workspace-app/public}/avatar/druplicon.vrm +0 -0
  496. /package/{public → core/workspace-app/public}/css/base.css +0 -0
  497. /package/{public → core/workspace-app/public}/css/components/ai-assistant.css +0 -0
  498. /package/{public → core/workspace-app/public}/css/components/assistant-avatar.css +0 -0
  499. /package/{public → core/workspace-app/public}/css/components/assistant-views.css +0 -0
  500. /package/{public → core/workspace-app/public}/css/components/build-order.css +0 -0
  501. /package/{public → core/workspace-app/public}/css/components/clone-as-a-git-worktree.css +0 -0
  502. /package/{public → core/workspace-app/public}/css/components/command-palette.css +0 -0
  503. /package/{public → core/workspace-app/public}/css/components/commands-center.css +0 -0
  504. /package/{public → core/workspace-app/public}/css/components/confirm-dialog.css +0 -0
  505. /package/{public → core/workspace-app/public}/css/components/create-card.css +0 -0
  506. /package/{public → core/workspace-app/public}/css/components/ddev-menu.css +0 -0
  507. /package/{public → core/workspace-app/public}/css/components/deep-chat.css +0 -0
  508. /package/{public → core/workspace-app/public}/css/components/density.css +0 -0
  509. /package/{public → core/workspace-app/public}/css/components/floating-assistant-workspace-pages.css +0 -0
  510. /package/{public → core/workspace-app/public}/css/components/folders.css +0 -0
  511. /package/{public → core/workspace-app/public}/css/components/full-height-left-assistant-sidebar-all-pages.css +0 -0
  512. /package/{public → core/workspace-app/public}/css/components/full-height-right-actions-rail-pages-that-have-actions.css +0 -0
  513. /package/{public → core/workspace-app/public}/css/components/grid-and-list.css +0 -0
  514. /package/{public → core/workspace-app/public}/css/components/help-page.css +0 -0
  515. /package/{public → core/workspace-app/public}/css/components/hero.css +0 -0
  516. /package/{public → core/workspace-app/public}/css/components/images.css +0 -0
  517. /package/{public → core/workspace-app/public}/css/components/layout-rhythm-and-spacing-polish.css +0 -0
  518. /package/{public → core/workspace-app/public}/css/components/mic-on-any-field-that-wants-typing.css +0 -0
  519. /package/{public → core/workspace-app/public}/css/components/modal-fit.css +0 -0
  520. /package/{public → core/workspace-app/public}/css/components/page-width.css +0 -0
  521. /package/{public → core/workspace-app/public}/css/components/plugins-page.css +0 -0
  522. /package/{public → core/workspace-app/public}/css/components/project-cards.css +0 -0
  523. /package/{public → core/workspace-app/public}/css/components/project-rows.css +0 -0
  524. /package/{public → core/workspace-app/public}/css/components/reordering-the-workspace-cards.css +0 -0
  525. /package/{public → core/workspace-app/public}/css/components/responsive-home-and-the-workspace-pages.css +0 -0
  526. /package/{public → core/workspace-app/public}/css/components/running-commands-as-toasts.css +0 -0
  527. /package/{public → core/workspace-app/public}/css/components/settings-editor-core-config-yml.css +0 -0
  528. /package/{public → core/workspace-app/public}/css/components/short-results-as-a-toast-at-the-top.css +0 -0
  529. /package/{public → core/workspace-app/public}/css/components/sound-player.css +0 -0
  530. /package/{public → core/workspace-app/public}/css/components/suggest-agents-skills-commands.css +0 -0
  531. /package/{public → core/workspace-app/public}/css/components/tab-modal.css +0 -0
  532. /package/{public → core/workspace-app/public}/css/components/terminals.css +0 -0
  533. /package/{public → core/workspace-app/public}/css/components/test-report-media-one-file-per-row-paged.css +0 -0
  534. /package/{public → core/workspace-app/public}/css/components/top-toolbar-logo-breadcrumb.css +0 -0
  535. /package/{public → core/workspace-app/public}/css/components/video-edit.css +0 -0
  536. /package/{public → core/workspace-app/public}/css/components/web-ide-open-with.css +0 -0
  537. /package/{public → core/workspace-app/public}/css/components/working-indicators.css +0 -0
  538. /package/{public → core/workspace-app/public}/css/components/workspace-cards.css +0 -0
  539. /package/{public → core/workspace-app/public}/favicon.ico +0 -0
  540. /package/{public → core/workspace-app/public}/favicon.png +0 -0
  541. /package/{public → core/workspace-app/public}/htmx.min.js +0 -0
  542. /package/{public → core/workspace-app/public}/logo.png +0 -0
  543. /package/{public → core/workspace-app/public}/media-player.js +0 -0
  544. /package/{public → core/workspace-app/public}/mic.js +0 -0
  545. /package/{public → core/workspace-app/public}/narration.js +0 -0
  546. /package/{public → core/workspace-app/public}/palette.js +0 -0
  547. /package/{public → core/workspace-app/public}/sortable.js +0 -0
  548. /package/{public → core/workspace-app/public}/suggest.js +0 -0
  549. /package/{public → core/workspace-app/public}/terminal.js +0 -0
  550. /package/{public → core/workspace-app/public}/themes/default/theme.css +0 -0
  551. /package/{public → core/workspace-app/public}/themes/ember/theme.css +0 -0
  552. /package/{public → core/workspace-app/public}/themes/press/theme.css +0 -0
  553. /package/{public → core/workspace-app/public}/themes/slate/theme.css +0 -0
  554. /package/{public → core/workspace-app/public}/touch-icon.png +0 -0
  555. /package/{public → core/workspace-app/public}/ui.js +0 -0
  556. /package/{public → core/workspace-app/public}/vendor/ace/LICENSE.txt +0 -0
  557. /package/{public → core/workspace-app/public}/vendor/ace/ace.js +0 -0
  558. /package/{public → core/workspace-app/public}/vendor/ace/ext-language_tools.js +0 -0
  559. /package/{public → core/workspace-app/public}/vendor/ace/ext-searchbox.js +0 -0
  560. /package/{public → core/workspace-app/public}/vendor/ace/mode-css.js +0 -0
  561. /package/{public → core/workspace-app/public}/vendor/ace/mode-html.js +0 -0
  562. /package/{public → core/workspace-app/public}/vendor/ace/mode-javascript.js +0 -0
  563. /package/{public → core/workspace-app/public}/vendor/ace/mode-markdown.js +0 -0
  564. /package/{public → core/workspace-app/public}/vendor/ace/mode-sh.js +0 -0
  565. /package/{public → core/workspace-app/public}/vendor/ace/mode-yaml.js +0 -0
  566. /package/{public → core/workspace-app/public}/vendor/ace/theme-textmate.js +0 -0
  567. /package/{public → core/workspace-app/public}/vendor/ace/theme-tomorrow_night.js +0 -0
  568. /package/{public → core/workspace-app/public}/vendor/ace/worker-yaml.js +0 -0
  569. /package/{public → core/workspace-app/public}/vendor/deep-chat.LICENSE +0 -0
  570. /package/{public → core/workspace-app/public}/vendor/deep-chat.bundle.js +0 -0
  571. /package/{public → core/workspace-app/public}/vendor/fonts/dm-serif-text-LICENSE.txt +0 -0
  572. /package/{public → core/workspace-app/public}/vendor/fonts/dm-serif-text-latin-400-italic.woff2 +0 -0
  573. /package/{public → core/workspace-app/public}/vendor/fonts/dm-serif-text-latin-400-normal.woff2 +0 -0
  574. /package/{public → core/workspace-app/public}/vendor/fonts/figtree-LICENSE.txt +0 -0
  575. /package/{public → core/workspace-app/public}/vendor/fonts/figtree-latin-400-italic.woff2 +0 -0
  576. /package/{public → core/workspace-app/public}/vendor/fonts/figtree-latin-400-normal.woff2 +0 -0
  577. /package/{public → core/workspace-app/public}/vendor/fonts/figtree-latin-600-italic.woff2 +0 -0
  578. /package/{public → core/workspace-app/public}/vendor/fonts/figtree-latin-600-normal.woff2 +0 -0
  579. /package/{public → core/workspace-app/public}/vendor/fonts/jetbrains-mono-LICENSE.txt +0 -0
  580. /package/{public → core/workspace-app/public}/vendor/fonts/jetbrains-mono-latin-400-normal.woff2 +0 -0
  581. /package/{public → core/workspace-app/public}/vendor/fonts/ubuntu-mono-LICENSE.txt +0 -0
  582. /package/{public → core/workspace-app/public}/vendor/fonts/ubuntu-mono-latin-wght-normal.woff2 +0 -0
  583. /package/{public → core/workspace-app/public}/vendor/tabler-LICENSE.txt +0 -0
  584. /package/{public → core/workspace-app/public}/vendor/tabler-sprite.svg +0 -0
  585. /package/{public → core/workspace-app/public}/vendor/three/LICENSE +0 -0
  586. /package/{public → core/workspace-app/public}/vendor/three/addons/loaders/GLTFLoader.js +0 -0
  587. /package/{public → core/workspace-app/public}/vendor/three/addons/utils/BufferGeometryUtils.js +0 -0
  588. /package/{public → core/workspace-app/public}/vendor/three/addons/utils/SkeletonUtils.js +0 -0
  589. /package/{public → core/workspace-app/public}/vendor/three/three.core.min.js +0 -0
  590. /package/{public → core/workspace-app/public}/vendor/three/three.module.min.js +0 -0
  591. /package/{public → core/workspace-app/public}/vendor/three-vrm/LICENSE +0 -0
  592. /package/{public → core/workspace-app/public}/vendor/three-vrm/three-vrm.module.min.js +0 -0
  593. /package/{public → core/workspace-app/public}/vendor/uikit-icons.min.js +0 -0
  594. /package/{public → core/workspace-app/public}/vendor/uikit.min.css +0 -0
  595. /package/{public → core/workspace-app/public}/vendor/uikit.min.js +0 -0
  596. /package/{public → core/workspace-app/public}/vendor/webship-icons/ui/bookmark-outlined.svg +0 -0
  597. /package/{public → core/workspace-app/public}/vendor/webship-icons/ui/headset.svg +0 -0
  598. /package/{public → core/workspace-app/public}/vendor/webship-icons/ui/menu.svg +0 -0
  599. /package/{public → core/workspace-app/public}/vendor/webship-icons/ui/pause.svg +0 -0
  600. /package/{public → core/workspace-app/public}/vendor/webship-icons/ui/play.svg +0 -0
  601. /package/{public → core/workspace-app/public}/vendor/webship-icons/ui/share.svg +0 -0
  602. /package/{public → core/workspace-app/public}/vendor/webship-icons/ui/sound-off.svg +0 -0
  603. /package/{public → core/workspace-app/public}/vendor/webship-icons/ui/sound-on.svg +0 -0
  604. /package/{public → core/workspace-app/public}/vendor/webship-icons/ui/stop.svg +0 -0
  605. /package/{public → core/workspace-app/public}/vendor/xterm/addon-fit.js +0 -0
  606. /package/{public → core/workspace-app/public}/vendor/xterm/addon-unicode11.js +0 -0
  607. /package/{public → core/workspace-app/public}/vendor/xterm/addon-web-links.js +0 -0
  608. /package/{public → core/workspace-app/public}/vendor/xterm/xterm.css +0 -0
  609. /package/{public → core/workspace-app/public}/vendor/xterm/xterm.js +0 -0
  610. /package/{rag.js → core/workspace-app/rag.js} +0 -0
  611. /package/{reader.js → core/workspace-app/reader.js} +0 -0
  612. /package/{repo-blobs.js → core/workspace-app/repo-blobs.js} +0 -0
  613. /package/{report-pdf.js → core/workspace-app/report-pdf.js} +0 -0
  614. /package/{screenrc → core/workspace-app/screenrc} +0 -0
  615. /package/{screens.js → core/workspace-app/screens.js} +0 -0
  616. /package/{scripts → core/workspace-app/scripts}/code-server-start.sh +0 -0
  617. /package/{scripts → core/workspace-app/scripts}/images-claude-finish.js +0 -0
  618. /package/{scripts → core/workspace-app/scripts}/screen-host.sh +0 -0
  619. /package/{scripts → core/workspace-app/scripts}/screen-runner.js +0 -0
  620. /package/{scripts → core/workspace-app/scripts}/screen-then.js +0 -0
  621. /package/{scripts → core/workspace-app/scripts}/update.sh +0 -0
  622. /package/{settings-file.js → core/workspace-app/settings-file.js} +0 -0
  623. /package/{speech.js → core/workspace-app/speech.js} +0 -0
  624. /package/{tab-modal.js → core/workspace-app/tab-modal.js} +0 -0
  625. /package/{test-reports.js → core/workspace-app/test-reports.js} +0 -0
  626. /package/{themes.js → core/workspace-app/themes.js} +0 -0
  627. /package/{transcripts.js → core/workspace-app/transcripts.js} +0 -0
  628. /package/{urls.js → core/workspace-app/urls.js} +0 -0
  629. /package/{validate.js → core/workspace-app/validate.js} +0 -0
  630. /package/{version-check.js → core/workspace-app/version-check.js} +0 -0
  631. /package/{video-edit.js → core/workspace-app/video-edit.js} +0 -0
  632. /package/{waiting.js → core/workspace-app/waiting.js} +0 -0
  633. /package/{workspace-card-tools.js → core/workspace-app/workspace-card-tools.js} +0 -0
  634. /package/{workspace-delete.js → core/workspace-app/workspace-delete.js} +0 -0
@@ -0,0 +1,602 @@
1
+ #!/usr/bin/env bash
2
+
3
+ ################################################################################
4
+ ## Webship Workspace — tool installer
5
+ ################################################################################
6
+ ## Installs (or verifies) everything the Webship Workspace needs on a fresh
7
+ ## machine: git, gh, curl, wget, jq, rsync, unzip, zip, sed, vim, links, lynx,
8
+ ## diffutils, htop, p7zip-full, gcc, g++, make, python3, gawk, screen, Node.js
9
+ ## (npm + npx, which also powers the skills.sh CLI), Docker, DDEV and
10
+ ## gitlab-ci-local, Claude Code, mkcert, and what each installed plugin asks for. Idempotent: whatever is already
11
+ ## is left alone.
12
+ ##
13
+ ## It also trusts the local https certificates, because every workspace URL is
14
+ ## https and a fresh machine has no CA to verify them with.
15
+ ##
16
+ ## bash core/scripts/install.sh
17
+ ##
18
+ ## --check report what is present and what is missing, install nothing
19
+ ## -y install everything missing without asking per group
20
+ ##
21
+ ## Linux: Debian/Ubuntu (apt) and Fedora (dnf). macOS: Homebrew. Windows: run
22
+ ## it inside WSL2 (it tells you how when it detects native Windows).
23
+ ################################################################################
24
+
25
+ set -u ;
26
+
27
+ # The version helpers, sourced explicitly. This installer is deliberately self-contained
28
+ # plain bash — it runs before anything is set up, so it never sources bootstrap.sh — but
29
+ # "what version is this tree" must have ONE answer, and duplicating it here is how the two
30
+ # would drift. fun-version.sh has no dependencies of its own for exactly this reason, and a
31
+ # missing file is not fatal: the stamp is skipped and everything else still installs.
32
+ # shellcheck source=functions/fun-version.sh
33
+ [ -f "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/functions/fun-version.sh" ] \
34
+ && source "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/functions/fun-version.sh"
35
+
36
+ CHECK_ONLY='no';
37
+ ASSUME_YES='no';
38
+ for arg in "$@"; do
39
+ case "${arg}" in
40
+ --check) CHECK_ONLY='yes' ;;
41
+ -y|--yes) ASSUME_YES='yes' ;;
42
+ -h|--help)
43
+ sed -n '3,19p' "$0" 2>/dev/null || true ;
44
+ echo "Usage: install.sh [--check] [-y]" ;
45
+ exit 0 ;;
46
+ esac
47
+ done
48
+
49
+ # ---------------------------------------------------------------- platform ---
50
+ OS='';
51
+ PKG='';
52
+ case "$(uname -s)" in
53
+ Linux)
54
+ if grep -qi microsoft /proc/version 2>/dev/null ; then
55
+ echo "WSL detected — treating it as Linux. Docker Desktop's WSL2 backend also works.";
56
+ fi
57
+ if command -v apt-get > /dev/null 2>&1 ; then PKG='apt';
58
+ elif command -v dnf > /dev/null 2>&1 ; then PKG='dnf';
59
+ else
60
+ echo "No apt or dnf here. Install the tools below with your package manager, then re-run --check.";
61
+ fi
62
+ OS='linux' ;;
63
+ Darwin)
64
+ OS='mac';
65
+ PKG='brew';
66
+ if ! command -v brew > /dev/null 2>&1 ; then
67
+ echo "Homebrew is how everything installs on macOS and it is missing.";
68
+ echo " Install it first: https://brew.sh";
69
+ echo " Then re-run this script.";
70
+ [ "${CHECK_ONLY}" == 'yes' ] || exit 1 ;
71
+ fi ;;
72
+ MINGW*|MSYS*|CYGWIN*)
73
+ echo "Native Windows shell detected. The workspace runs in WSL2:";
74
+ echo " 1. In an admin PowerShell: wsl --install -d Ubuntu";
75
+ echo " 2. Reboot, open Ubuntu, and re-run this command there.";
76
+ echo " 3. Install Docker Desktop for Windows and enable its WSL2 backend.";
77
+ exit 1 ;;
78
+ *)
79
+ echo "Unrecognised platform '$(uname -s)' — install the tools manually, then re-run --check.";
80
+ exit 1 ;;
81
+ esac
82
+
83
+ SUDO='';
84
+ if [ "${OS}" == 'linux' ] && [ "$(id -u)" != '0' ] ; then SUDO='sudo'; fi
85
+
86
+ # ------------------------------------------------------------------ helpers --
87
+ MISSING=();
88
+
89
+ function have() { command -v "$1" > /dev/null 2>&1 ; }
90
+
91
+ function report() {
92
+ local tool="$1" how="$2";
93
+ if have "${tool}" ; then
94
+ printf ' ✓ %-16s %s\n' "${tool}" "$(command -v "${tool}")" ;
95
+ else
96
+ printf ' ✗ %-16s missing (%s)\n' "${tool}" "${how}" ;
97
+ MISSING+=("${tool}") ;
98
+ fi
99
+ }
100
+
101
+ function confirm() {
102
+ [ "${ASSUME_YES}" == 'yes' ] && return 0 ;
103
+ local answer;
104
+ read -r -p "$1 [y/N] " answer ;
105
+ [ "${answer}" == 'y' ] || [ "${answer}" == 'Y' ] ;
106
+ }
107
+
108
+ function pkg_install() {
109
+ case "${PKG}" in
110
+ apt) ${SUDO} apt-get update -qq && ${SUDO} apt-get install -y "$@" ;;
111
+ dnf) ${SUDO} dnf install -y "$@" ;;
112
+ brew) brew install "$@" ;;
113
+ *) echo " install manually: $*" ; return 1 ;;
114
+ esac
115
+ }
116
+
117
+ function trust_local_https() {
118
+ # One implementation, shared with the dashboard's own `ddev start` hook, so the
119
+ # two can never disagree about which trust stores a browser reads.
120
+ local script="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/trust-https.sh";
121
+ if [ ! -f "${script}" ] ; then
122
+ echo " trust-https.sh is missing beside this script — skipping.";
123
+ return 0 ;
124
+ fi
125
+
126
+ # certutil is what writes a browser trust store, and it is a separate package.
127
+ if [ "${OS}" == 'linux' ] && ! have certutil ; then
128
+ case "${PKG}" in
129
+ apt) confirm "Install libnss3-tools (lets mkcert trust the certificate in Chrome, Brave and Firefox)?" && pkg_install libnss3-tools || true ;;
130
+ dnf) confirm "Install nss-tools (lets mkcert trust the certificate in Chrome, Brave and Firefox)?" && pkg_install nss-tools || true ;;
131
+ esac
132
+ fi
133
+
134
+ bash "${script}" || true ;
135
+ }
136
+
137
+ # Is the local CA there, and do the browsers know it? Reported in the survey so
138
+ # --check answers "will https work on this machine" without changing anything.
139
+ function https_trust_state() {
140
+ local script="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/trust-https.sh";
141
+ have mkcert || { echo "no mkcert"; return; }
142
+ [ -f "${script}" ] || { echo "trust-https.sh missing"; return; }
143
+ if bash "${script}" --check > /dev/null 2>&1 ; then echo "trusted"; return; fi
144
+ local caroot; caroot="$(mkcert -CAROOT 2>/dev/null)";
145
+ if [ -z "${caroot}" ] || [ ! -f "${caroot}/rootCA.pem" ] ; then echo "no local CA"; return; fi
146
+ echo "a browser here does not trust the CA";
147
+ }
148
+
149
+ # Record which release this tree is. Nothing else did: update.sh wrote .app-version and
150
+ # install.sh and sync-tooling.sh wrote nothing, so a freshly installed machine reported
151
+ # "Installed: (untracked)" and offered an update to the version it was already on — for
152
+ # ever, on every machine that had not been updated by the updater. Across a team that is
153
+ # the support question nobody can answer.
154
+ #
155
+ # The tag comes from the repository, not from a guess: when it cannot be read (no network,
156
+ # no gh) the stamp is skipped and the state stays honestly unknown rather than wrong.
157
+ if [ "${CHECK_ONLY}" != 'yes' ] ; then
158
+ ws_tag=""
159
+ command -v workspace_latest_tag > /dev/null 2>&1 && ws_tag="$(workspace_latest_tag 2>/dev/null)"
160
+ if [ -n "${ws_tag}" ] ; then
161
+ command -v workspace_version_stamp > /dev/null 2>&1 && workspace_version_stamp "${ws_tag}" && echo "Recorded this tree as ${ws_tag} (core/workspace-app/.app-version)."
162
+ else
163
+ echo "Could not reach GitHub for the release tag, so the version is not recorded." ;
164
+ echo " It will be set the first time you run core/workspace-app/scripts/update.sh." ;
165
+ fi
166
+ fi
167
+
168
+ function next_steps() {
169
+ local DOCKER_READY step
170
+ # ------------------------------------------------------- does docker actually work --
171
+
172
+ # Installing Docker is not the same as being able to use it. On a fresh Ubuntu the
173
+ # installer above adds you to the docker group, and a group is applied at LOGIN — so
174
+ # this shell, and anything started from it, still cannot reach the daemon. Every
175
+ # ddev command then fails with:
176
+ #
177
+ # Docker error: permission denied while trying to connect to the docker API
178
+ #
179
+ # which is the single most likely way a first install goes wrong, and it looks like a
180
+ # broken tool rather than a session that predates a group. So it is checked, by trying,
181
+ # rather than assumed from a successful install.
182
+ DOCKER_READY='no';
183
+ if have docker && docker info > /dev/null 2>&1 ; then
184
+ DOCKER_READY='yes';
185
+ fi
186
+
187
+ echo "Next steps:";
188
+ step=1;
189
+ if [ "${DOCKER_READY}" == 'no' ] && have docker ; then
190
+ if id -nG 2>/dev/null | tr ' ' '\n' | grep -qx docker ; then
191
+ echo " ${step}. Docker is installed but this shell cannot reach it — start it:";
192
+ echo " sudo systemctl start docker";
193
+ elif getent group docker 2>/dev/null | grep -q "\b$(id -un)\b" ; then
194
+ echo " ${step}. LOG OUT AND BACK IN. You are in the docker group, but a group only";
195
+ echo " applies at login, so this shell still cannot reach Docker — and every";
196
+ echo " ddev command would fail with a permission error that looks like a bug.";
197
+ else
198
+ echo " ${step}. Add yourself to the docker group, then log out and back in:";
199
+ echo " sudo usermod -aG docker $(id -un)";
200
+ fi
201
+ step=$((step+1));
202
+ fi
203
+ echo " ${step}. gh auth login";
204
+ step=$((step+1));
205
+ echo " ${step}. cd core/workspace-app && ddev start";
206
+ step=$((step+1));
207
+ echo " ${step}. Open https://workspace.ddev.site";
208
+ if [ "${DOCKER_READY}" == 'yes' ] ; then
209
+ echo "";
210
+ echo "Docker answers in this shell, so step $((step-1)) will work now.";
211
+ fi
212
+ }
213
+
214
+ # ------------------------------------------------------------------- survey --
215
+ echo "";
216
+ echo "Webship Workspace tools on this ${OS} machine:";
217
+ echo "";
218
+ report git "package manager";
219
+ report curl "package manager";
220
+ report wget "package manager";
221
+ report jq "package manager";
222
+ report rsync "package manager";
223
+ report unzip "package manager";
224
+ report python3 "package manager";
225
+ report screen "package manager";
226
+ report awk "gawk via package manager";
227
+ report vim "package manager";
228
+ report links "package manager";
229
+ report lynx "package manager";
230
+ report diff "diffutils via package manager";
231
+ report htop "package manager";
232
+ report 7z "p7zip-full via package manager";
233
+ report zip "package manager";
234
+ report sed "package manager";
235
+ report gcc "package manager";
236
+ report g++ "package manager";
237
+ report make "package manager";
238
+ report python "python-is-python3 via package manager";
239
+ report gh "GitHub CLI — cli.github.com";
240
+ report node "Node.js 24 — nodejs.org";
241
+ report npm "ships with Node.js";
242
+ report npx "ships with Node.js";
243
+ report docker "get.docker.com / Docker Desktop";
244
+ report ddev "ddev.com/install.sh";
245
+ report mkcert "package manager — signs the https certificates DDEV serves";
246
+ report gitlab-ci-local "npm -g gitlab-ci-local";
247
+ report claude "npm -g @anthropic-ai/claude-code";
248
+ echo "";
249
+ if have npx ; then
250
+ echo " ✓ skills.sh CLI runs through npx (npx skills …), nothing to install";
251
+ else
252
+ echo " ✗ skills.sh CLI needs npx (comes with Node.js)";
253
+ fi
254
+ echo "";
255
+ # The hub domain, for the URLs this survey prints. Read from settings.yml when it is
256
+ # there, so a machine with a custom hub_domain is told its own address rather than the
257
+ # default one.
258
+ function hub_domain_or_default() {
259
+ local cfg="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)/config/settings.yml"
260
+ local d=''
261
+ # One sed: take the value, drop surrounding quotes and any trailing spaces. Nesting
262
+ # quote-stripping inside a command substitution is how the first version of this line
263
+ # became unparseable — keep it in the sed script, not in the shell.
264
+ [ -f "${cfg}" ] && d="$(sed -n 's/^hub_domain:[[:space:]]*//; t v; b; :v s/^["\x27]//; s/["\x27][[:space:]]*$//; s/[[:space:]]*$//; p' "${cfg}" | head -1)"
265
+ echo "${d:-workspace.ddev.site}"
266
+ }
267
+
268
+ # EXPOSURE. The single most consequential line in this survey, and the reason it is here at
269
+ # all: this workspace has NO AUTHENTICATION. It serves a dashboard that runs shell commands,
270
+ # a browser terminal at /terminal/<session>, and a Web IDE with write access to the whole
271
+ # tree and a terminal of its own — in a container holding the Docker socket and the DDEV
272
+ # registry.
273
+ #
274
+ # That is defensible, and only because everything binds to LOOPBACK: DDEV's router is
275
+ # 127.0.0.1 by default and the machine answers nothing on its LAN address. It stops being
276
+ # defensible the moment either of two settings changes, and both are things a person changes
277
+ # for a good-looking reason:
278
+ #
279
+ # router_bind_all_interfaces: true DDEV documents it for Let's Encrypt and for reaching
280
+ # a project from a phone on the same network.
281
+ # hub_domain: <a public domain> the README says the same system runs as a remote hub.
282
+ #
283
+ # Neither warns you today. So this does, loudly, because the failure mode is not an error
284
+ # message — it is a shell on someone's machine, available to whoever can reach the port.
285
+ ws_bind_all="$(sed -n 's/^router_bind_all_interfaces:[[:space:]]*//p' "${HOME}/.ddev/global_config.yaml" 2>/dev/null | head -1 | tr -d '[:space:]')"
286
+ ws_hub="$(hub_domain_or_default)"
287
+ ws_exposed='no'
288
+ case "${ws_bind_all}" in true|yes) ws_exposed='bind' ;; esac
289
+ case "${ws_hub}" in *.ddev.site|localhost|127.0.0.1) ;; *) ws_exposed="${ws_exposed}+domain" ;; esac
290
+
291
+ if [ "${ws_exposed}" == 'no' ] ; then
292
+ printf ' ✓ %-16s %s\n' "exposure" "loopback only (router binds 127.0.0.1, hub is ${ws_hub})"
293
+ else
294
+ printf ' ✗ %-16s %s\n' "exposure" "THIS MACHINE MAY BE REACHABLE FROM THE NETWORK"
295
+ case "${ws_exposed}" in
296
+ *bind*) printf ' %-18s %s\n' "" "router_bind_all_interfaces is ${ws_bind_all} — the router listens on every interface." ;;
297
+ esac
298
+ case "${ws_exposed}" in
299
+ *domain*) printf ' %-18s %s\n' "" "hub_domain is ${ws_hub}, which is not a local address." ;;
300
+ esac
301
+ printf ' %-18s %s\n' "" "There is NO login on the dashboard, and it offers a terminal, a Web IDE with"
302
+ printf ' %-18s %s\n' "" "write access to ${WORKSPACE_ROOT_GUESS:-~/workspace}, and the Docker socket. Anyone who can reach"
303
+ printf ' %-18s %s\n' "" "the port has all of it. Put real authentication in front of it, or bind it back:"
304
+ printf ' %-18s %s\n' "" " ddev config global --router-bind-all-interfaces=false"
305
+ fi
306
+
307
+ # The ddev router-lock shim. The dashboard's container gets it from its image; on the
308
+ # HOST it is a root-owned file, so it is reported here and offered below rather than
309
+ # installed silently — a wrapper in front of ddev is not something to appear unannounced.
310
+ SHIM_SRC="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/ddev-shim/ddev"
311
+ SHIM_DEST='/usr/local/sbin/ddev'
312
+ if [ ! -x "$(command -v ddev 2>/dev/null)" ] ; then
313
+ printf ' – %-16s %s\n' "ddev lock" "skipped: ddev is not installed on this host"
314
+ elif [ "$(command -v ddev)" == "${SHIM_DEST}" ] ; then
315
+ if cmp -s "${SHIM_SRC}" "${SHIM_DEST}" 2>/dev/null ; then
316
+ printf ' ✓ %-16s %s\n' "ddev lock" "the router-lock wrapper is first on PATH"
317
+ else
318
+ printf ' ✗ %-16s %s\n' "ddev lock" "${SHIM_DEST} is an OLD copy of the wrapper — re-run this installer"
319
+ fi
320
+ else
321
+ printf ' ✗ %-16s %s\n' "ddev lock" "not installed on this host — concurrent ddev start/stop can destroy"
322
+ printf ' %-18s %s\n' "" "the shared ddev-router and take every workspace URL down. The dashboard"
323
+ printf ' %-18s %s\n' "" "is protected; a terminal or a cmd-*.sh script on this host is not."
324
+ fi
325
+
326
+ # inotify watches, which the Web IDE needs and Drupal exhausts. ONE built Drupal project
327
+ # is ~21,000 directories; the kernel default is 65,536 watches SHARED ACROSS THE WHOLE
328
+ # MACHINE, so two open projects and the editor stops noticing file changes — silently,
329
+ # except for one toast. The IDE's own settings already exclude vendor/, web/core/ and
330
+ # node_modules/ (55% of them), and this is the other half. Reported, never applied: it is
331
+ # a sysctl, it needs root, and a setup script changing kernel limits unasked is not on.
332
+ IN_WATCHES="$(cat /proc/sys/fs/inotify/max_user_watches 2>/dev/null || echo 0)"
333
+ if [ "${IN_WATCHES}" -ge 262144 ] ; then
334
+ printf ' ✓ %-16s %s\n' "inotify watches" "${IN_WATCHES}"
335
+ else
336
+ printf ' ✗ %-16s %s\n' "inotify watches" "${IN_WATCHES} — too low for the Web IDE on Drupal projects"
337
+ printf ' %-18s %s\n' "" "The editor will report \"Unable to watch for file changes\" and stop noticing"
338
+ printf ' %-18s %s\n' "" "edits made outside it. Raise it (needs root, survives reboot):"
339
+ printf ' %-18s %s\n' "" " echo 'fs.inotify.max_user_watches=524288' | sudo tee /etc/sysctl.d/60-inotify.conf"
340
+ printf ' %-18s %s\n' "" " sudo sysctl --system"
341
+ fi
342
+
343
+ # The Web IDE (code-server) — VS Code in the browser, which the dashboard's project rows
344
+ # and document folders link to. It is NOT installed on the host: it lives in the
345
+ # dashboard's own image and runs as one of its web_extra_daemons, so what there is to
346
+ # check here is whether that image carries it and whether the daemon is up. Both are
347
+ # answered from the container, which is also the honest place to answer them from.
348
+ IDE_STATE='unknown'
349
+ if docker ps --format '{{.Names}}' 2>/dev/null | grep -q '^ddev-workspace-web$' ; then
350
+ if docker exec ddev-workspace-web bash -lc 'command -v code-server >/dev/null' 2>/dev/null ; then
351
+ ide_ver="$(docker exec ddev-workspace-web bash -lc 'code-server --version 2>/dev/null | head -1' 2>/dev/null | awk '{print $1}')"
352
+ if docker exec ddev-workspace-web bash -lc 'curl -sf -o /dev/null --max-time 5 http://127.0.0.1:8443/' 2>/dev/null ; then
353
+ printf ' ✓ %-16s %s\n' "web IDE" "code-server ${ide_ver} — https://ide.$(hub_domain_or_default)/"
354
+ IDE_STATE='up'
355
+ else
356
+ printf ' ✗ %-16s %s\n' "web IDE" "code-server ${ide_ver} is in the image but not answering — ddev restart"
357
+ IDE_STATE='down'
358
+ fi
359
+ else
360
+ printf ' ✗ %-16s %s\n' "web IDE" "not in the dashboard image — rebuild it: ddev restart (it is baked in by .ddev/web-build)"
361
+ IDE_STATE='missing'
362
+ fi
363
+ else
364
+ printf ' – %-16s %s\n' "web IDE" "skipped: the dashboard container is not running"
365
+ fi
366
+
367
+ # Docker CREATES a missing bind-mount source, as a root-owned directory. Every optional
368
+ # tool the dashboard shares from the host is such a source, so this is checked before
369
+ # anything installs into one of them.
370
+ if bash "$(dirname "${BASH_SOURCE[0]}")/host-mounts.sh" --check --quiet > /dev/null 2>&1 ; then
371
+ printf ' ✓ %-16s %s\n' "mounted paths" "the host paths the dashboard shares are yours" ;
372
+ else
373
+ printf ' ✗ %-16s %s\n' "mounted paths" "a path Docker created is root-owned — see below" ;
374
+ fi
375
+
376
+ # The dashboard runs ddev inside its own container against the host's docker.sock, so
377
+ # a mismatched docker GID is as much a prerequisite as the tools above — and its symptom
378
+ # (every project reads as Stopped) looks like anything but a permissions problem.
379
+ DOCKER_GID_STATE='aligned';
380
+ if [ -f "$(dirname "${BASH_SOURCE[0]}")/docker-gid.sh" ] ; then
381
+ bash "$(dirname "${BASH_SOURCE[0]}")/docker-gid.sh" --check --quiet > /dev/null 2>&1 || DOCKER_GID_STATE='mismatched';
382
+ fi
383
+ if [ "${DOCKER_GID_STATE}" == 'aligned' ] ; then
384
+ printf ' ✓ %-16s %s\n' "dashboard docker" "shares this host's docker group" ;
385
+ else
386
+ printf ' ✗ %-16s %s\n' "dashboard docker" "wrong docker GID — every project would read as Stopped" ;
387
+ fi
388
+
389
+ # Every workspace URL is https, so this is as much a prerequisite as the tools above.
390
+ HTTPS_STATE="$(https_trust_state)";
391
+ if [ "${HTTPS_STATE}" == 'trusted' ] ; then
392
+ printf ' ✓ %-16s %s\n' "https trust" "${HTTPS_STATE}" ;
393
+ else
394
+ printf ' ✗ %-16s %s\n' "https trust" "${HTTPS_STATE} — every workspace URL would be refused by the browser" ;
395
+ fi
396
+ echo "";
397
+
398
+ if [ "${#MISSING[@]}" -eq 0 ] ; then
399
+ echo "Every tool is here.";
400
+ # The tools being present says nothing about the certificates: this machine is the
401
+ # common case — a complete toolchain and no local CA, so https is refused.
402
+ if [ "${HTTPS_STATE}" == 'trusted' ] && [ "${DOCKER_GID_STATE}" == 'aligned' ] ; then
403
+ echo "";
404
+ next_steps ;
405
+ exit 0 ;
406
+ fi
407
+ if [ "${CHECK_ONLY}" == 'yes' ] ; then
408
+ echo "Re-run without --check to fix what is marked ✗ above.";
409
+ exit 1 ;
410
+ fi
411
+ echo "";
412
+ echo "Trusted https for the workspace URLs:";
413
+ trust_local_https ;
414
+ echo "";
415
+ echo "The dashboard's Docker access:";
416
+ bash "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/docker-gid.sh" || true ;
417
+ echo "";
418
+ next_steps ;
419
+ exit 0 ;
420
+ fi
421
+ if [ "${CHECK_ONLY}" == 'yes' ] ; then
422
+ echo "Missing: ${MISSING[*]} (re-run without --check to install)";
423
+ exit 1 ;
424
+ fi
425
+
426
+ # ------------------------------------------------------------------ install --
427
+ function missing() {
428
+ local tool;
429
+ for tool in "${MISSING[@]}"; do [ "${tool}" == "$1" ] && return 0 ; done
430
+ return 1 ;
431
+ }
432
+
433
+ base_pkgs=();
434
+ for tool in git curl wget jq rsync unzip zip sed vim links lynx htop gcc g++ make python3 screen ; do
435
+ missing "${tool}" && base_pkgs+=("${tool}") ;
436
+ done
437
+ # These carry a package name that is not the command name.
438
+ missing awk && base_pkgs+=(gawk) ;
439
+ missing diff && base_pkgs+=(diffutils) ;
440
+ missing 7z && base_pkgs+=(p7zip-full) ;
441
+ missing python && base_pkgs+=(python-is-python3) ;
442
+ if [ "${#base_pkgs[@]}" -gt 0 ] && confirm "Install base tools (${base_pkgs[*]})?" ; then
443
+ pkg_install "${base_pkgs[@]}" ;
444
+ fi
445
+
446
+ if missing gh && confirm "Install the GitHub CLI (gh)?" ; then
447
+ case "${PKG}" in
448
+ apt)
449
+ # Debian/Ubuntu ship no gh package — this is the official keyring + repo.
450
+ ${SUDO} mkdir -p /etc/apt/keyrings ;
451
+ wget -qO- https://cli.github.com/packages/githubcli-archive-keyring.gpg \
452
+ | ${SUDO} tee /etc/apt/keyrings/githubcli-archive-keyring.gpg > /dev/null ;
453
+ echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/githubcli-archive-keyring.gpg] https://cli.github.com/packages stable main" \
454
+ | ${SUDO} tee /etc/apt/sources.list.d/github-cli.list > /dev/null ;
455
+ ${SUDO} apt-get update -qq && ${SUDO} apt-get install -y gh ;;
456
+ dnf) ${SUDO} dnf install -y gh ;;
457
+ brew) brew install gh ;;
458
+ esac
459
+ fi
460
+
461
+ if missing node && confirm "Install Node.js 24 (brings npm, npx and the skills.sh CLI)?" ; then
462
+ case "${PKG}" in
463
+ apt)
464
+ wget -qO- https://deb.nodesource.com/setup_24.x | ${SUDO} bash - ;
465
+ ${SUDO} apt-get install -y nodejs ;;
466
+ dnf) ${SUDO} dnf install -y nodejs npm ;;
467
+ brew) brew install node ;;
468
+ esac
469
+ fi
470
+
471
+ if missing docker && confirm "Install Docker?" ; then
472
+ if [ "${OS}" == 'mac' ] ; then
473
+ echo " On macOS install Docker Desktop (or OrbStack):";
474
+ echo " brew install --cask docker # or: brew install --cask orbstack";
475
+ echo " Start it once so the docker CLI works, then re-run --check.";
476
+ else
477
+ # Docker's official convenience script; adds the current user to the docker group after.
478
+ wget -qO- https://get.docker.com | ${SUDO} sh ;
479
+ if [ -n "${SUDO}" ] ; then
480
+ ${SUDO} usermod -aG docker "$(id -un)" \
481
+ && echo " Added $(id -un) to the docker group — log out and back in for it to apply." ;
482
+ fi
483
+ fi
484
+ fi
485
+
486
+ if missing ddev && confirm "Install DDEV?" ; then
487
+ # DDEV's official package repos — unlike ddev.com/install.sh these also work as root
488
+ # (containers, CI) and get updated by the package manager afterwards.
489
+ case "${PKG}" in
490
+ apt)
491
+ have gpg || ${SUDO} apt-get install -y gnupg ;
492
+ ${SUDO} mkdir -p /etc/apt/keyrings ;
493
+ wget -qO- https://pkg.ddev.com/apt/gpg.key | gpg --dearmor \
494
+ | ${SUDO} tee /etc/apt/keyrings/ddev.gpg > /dev/null ;
495
+ echo "deb [signed-by=/etc/apt/keyrings/ddev.gpg] https://pkg.ddev.com/apt/ * *" \
496
+ | ${SUDO} tee /etc/apt/sources.list.d/ddev.list > /dev/null ;
497
+ ${SUDO} apt-get update -qq && ${SUDO} apt-get install -y ddev ;;
498
+ dnf)
499
+ echo '[ddev]
500
+ name=ddev
501
+ baseurl=https://pkg.ddev.com/yum/
502
+ enabled=1
503
+ gpgcheck=0' | ${SUDO} tee /etc/yum.repos.d/ddev.repo > /dev/null ;
504
+ ${SUDO} dnf install -y ddev ;;
505
+ brew) brew install ddev/ddev/ddev ;;
506
+ esac
507
+ fi
508
+
509
+ if missing gitlab-ci-local && have npm && confirm "Install gitlab-ci-local (runs .gitlab-ci.yml pipelines locally)?" ; then
510
+ npm install -g gitlab-ci-local ;
511
+ fi
512
+
513
+ # mkcert signs the certificate every workspace URL is served with. DDEV installs it
514
+ # on some platforms and not others, so ask for it by name.
515
+ if missing mkcert && confirm "Install mkcert (trusted https for every workspace URL)?" ; then
516
+ pkg_install mkcert || true ;
517
+ fi
518
+
519
+ # Before installing anything into ~/.local/bin: if Docker created it as root for a bind
520
+ # mount, the twg installer below cannot write there. This makes those paths yours first.
521
+ echo "";
522
+ echo "The host paths the dashboard shares:";
523
+ bash "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/host-mounts.sh" --sudo || true ;
524
+
525
+ # The ddev router-lock wrapper on this host. Offered, because it puts a script in front of
526
+ # a binary people rely on: that is a thing to say out loud, not to do quietly. Needs root
527
+ # for /usr/local/sbin, which precedes /usr/local/bin and /usr/bin on a default PATH.
528
+ if [ -n "$(command -v ddev 2>/dev/null)" ] && [ "$(command -v ddev)" != "${SHIM_DEST}" ] \
529
+ && confirm "Serialise ddev start/stop on this host (a wrapper that holds a lock — stops concurrent starts destroying the router)?" ; then
530
+ if sudo install -m 0755 "${SHIM_SRC}" "${SHIM_DEST}" ; then
531
+ # Prove it before claiming it: the wrapper has to find the real binary and pass a
532
+ # read-only verb straight through, or every ddev call on this machine is now broken.
533
+ if "${SHIM_DEST}" --version > /dev/null 2>&1 ; then
534
+ echo " ✓ installed at ${SHIM_DEST} — ddev --version still answers through it" ;
535
+ echo " Router verbs (start, stop, restart, poweroff, delete) now queue instead of racing." ;
536
+ echo " Everything else — drush, composer, list, describe — passes straight through." ;
537
+ echo " Remove it any time with: sudo rm ${SHIM_DEST}" ;
538
+ else
539
+ echo " ✗ the wrapper does not run — REMOVING it so ddev keeps working:" ;
540
+ sudo rm -f "${SHIM_DEST}" ;
541
+ echo " sudo rm ${SHIM_DEST} (done)" ;
542
+ fi
543
+ else
544
+ echo " ✗ could not write ${SHIM_DEST} — ddev is unchanged." ;
545
+ fi
546
+ fi
547
+
548
+ # The host side of every installed plugin (core/scripts/plugins/<name>/host-install.sh): the
549
+ # tools a plugin needs on this machine, offered the same way as everything above.
550
+ for plugin_host_install in "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"/plugins/*/host-install.sh ; do
551
+ [ -f "${plugin_host_install}" ] || continue ;
552
+ echo "" ; echo "Plugin $(basename "$(dirname "${plugin_host_install}")"):" ;
553
+ bash "${plugin_host_install}" || true ;
554
+ done
555
+
556
+ # Claude Code — the CLI the dashboard's agents, the Screens page and the Jira
557
+ # actions all run (code.claude.com/docs/en/quickstart). The same package the
558
+ # workspace's own container installs, so host and container agree.
559
+ if missing claude && have npm && confirm "Install Claude Code (the AI CLI the workspace agents run)?" ; then
560
+ npm install -g @anthropic-ai/claude-code ;
561
+ echo " Run 'claude' once to sign in." ;
562
+ fi
563
+
564
+ # -------------------------------------------------------------- trusted https --
565
+ # Every workspace URL is https, and DDEV signs those certificates with mkcert's local
566
+ # CA. A fresh machine has no CA at all, so the browser refuses every page with
567
+ # ERR_CERT_AUTHORITY_INVALID — which reads as "the dashboard is broken" rather than
568
+ # "one command was never run". So it belongs in the install.
569
+ #
570
+ # Two trust stores, and they are separate:
571
+ # system /usr/local/share/ca-certificates — curl and the CLI tools. Needs root.
572
+ # browser ~/.pki/nssdb (NSS) — Chrome and Firefox. No root needed.
573
+ #
574
+ # mkcert skips the browser store SILENTLY when that database does not exist, which is
575
+ # the failure worth preventing here: the CA gets created, the system store gets it, and
576
+ # the browser still refuses the page. So the database is created first.
577
+
578
+ echo "";
579
+ echo "Trusted https for the workspace URLs:";
580
+ trust_local_https ;
581
+
582
+ # The dashboard runs ddev inside its own container against the host's docker.sock,
583
+ # which only works if it shares the host's docker GID. Wrong, and every project
584
+ # reads as Stopped forever while running perfectly well.
585
+ echo "";
586
+ echo "The dashboard's Docker access:";
587
+ bash "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/docker-gid.sh" || true ;
588
+
589
+ # ------------------------------------------------------------------- recheck --
590
+ echo "";
591
+ echo "Done. Re-checking:";
592
+ MISSING=();
593
+ for tool in git curl wget jq rsync unzip zip sed vim links lynx diff htop 7z gcc g++ make python3 python awk screen gh node npm npx docker ddev mkcert gitlab-ci-local claude ; do
594
+ report "${tool}" "see above" ;
595
+ done
596
+ echo "";
597
+ if [ "${#MISSING[@]}" -gt 0 ] ; then
598
+ echo "Still missing: ${MISSING[*]} — see the notes above.";
599
+ echo "";
600
+ fi
601
+
602
+ next_steps ;