@webship.co/workspace 1.0.0-beta1 → 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 (630) 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/core/workspace-app/README.md +380 -0
  160. package/{actions → core/workspace-app/actions}/ddev.js +0 -1
  161. package/{actions → core/workspace-app/actions}/rag.js +0 -1
  162. package/{actions → core/workspace-app/actions}/testing.js +0 -1
  163. package/{assistant.js → core/workspace-app/assistant.js} +1 -10
  164. package/{git-info.js → core/workspace-app/git-info.js} +17 -1
  165. package/core/workspace-app/package.json +29 -0
  166. package/core/workspace-app/plugin-catalog.js +50 -0
  167. package/{plugins-page.js → core/workspace-app/plugins-page.js} +28 -2
  168. package/{server.js → core/workspace-app/server.js} +18 -0
  169. package/core/workspace-app/tests/features/actions-rail.feature +44 -0
  170. package/core/workspace-app/tests/features/ai-items.feature +23 -0
  171. package/core/workspace-app/tests/features/assistant-speech.feature +63 -0
  172. package/core/workspace-app/tests/features/checks.feature +39 -0
  173. package/core/workspace-app/tests/features/clone-project.feature +30 -0
  174. package/core/workspace-app/tests/features/command-authoring.feature +58 -0
  175. package/core/workspace-app/tests/features/dashboard.feature +57 -0
  176. package/core/workspace-app/tests/features/menus.feature +29 -0
  177. package/core/workspace-app/tests/features/plugins/jira/jira.feature +47 -0
  178. package/core/workspace-app/tests/features/plugins.feature +20 -0
  179. package/core/workspace-app/tests/features/project-actions.feature +40 -0
  180. package/core/workspace-app/tests/features/screens.feature +29 -0
  181. package/core/workspace-app/tests/features/settings.feature +46 -0
  182. package/core/workspace-app/tests/features/test-reports.feature +32 -0
  183. package/core/workspace-app/tests/features/theme.feature +40 -0
  184. package/core/workspace-app/tests/step-definitions/actions-post.steps.js +25 -0
  185. package/core/workspace-app/tests/step-definitions/assistant-speech.steps.js +152 -0
  186. package/core/workspace-app/tests/step-definitions/preconditions.steps.js +100 -0
  187. package/core/workspace-app/tests/unit/_isolated-config.js +31 -0
  188. package/core/workspace-app/tests/unit/accessibility.test.js +124 -0
  189. package/core/workspace-app/tests/unit/actions-rail-ux.test.js +56 -0
  190. package/core/workspace-app/tests/unit/actions-rail.test.js +51 -0
  191. package/core/workspace-app/tests/unit/ai-inventory.test.js +64 -0
  192. package/core/workspace-app/tests/unit/app-docs.test.js +64 -0
  193. package/core/workspace-app/tests/unit/assistant-avatar.test.js +110 -0
  194. package/core/workspace-app/tests/unit/assistant-cast.test.js +105 -0
  195. package/core/workspace-app/tests/unit/assistant-send-animation.test.js +15 -0
  196. package/core/workspace-app/tests/unit/assistant-suggestions.test.js +112 -0
  197. package/core/workspace-app/tests/unit/assistant-switches.test.js +53 -0
  198. package/core/workspace-app/tests/unit/assistant-views.test.js +146 -0
  199. package/core/workspace-app/tests/unit/assistant-working-indicator.test.js +49 -0
  200. package/core/workspace-app/tests/unit/assistant.test.js +61 -0
  201. package/core/workspace-app/tests/unit/audio-player.test.js +147 -0
  202. package/core/workspace-app/tests/unit/audio-voice.test.js +634 -0
  203. package/core/workspace-app/tests/unit/auth-google.test.js +180 -0
  204. package/core/workspace-app/tests/unit/autostart-watch.test.js +76 -0
  205. package/core/workspace-app/tests/unit/browsers.test.js +76 -0
  206. package/core/workspace-app/tests/unit/build-distribution.test.js +125 -0
  207. package/core/workspace-app/tests/unit/build-order.test.js +153 -0
  208. package/core/workspace-app/tests/unit/builder-args.test.js +113 -0
  209. package/core/workspace-app/tests/unit/builders.test.js +158 -0
  210. package/core/workspace-app/tests/unit/card-state-toggle.test.js +29 -0
  211. package/core/workspace-app/tests/unit/changelog.test.js +177 -0
  212. package/core/workspace-app/tests/unit/chat-thread.test.js +92 -0
  213. package/core/workspace-app/tests/unit/checks-plan.test.js +205 -0
  214. package/core/workspace-app/tests/unit/claude-args.test.js +182 -0
  215. package/core/workspace-app/tests/unit/claude-code-here.test.js +15 -0
  216. package/core/workspace-app/tests/unit/claude-resume.test.js +147 -0
  217. package/core/workspace-app/tests/unit/claude-screen-options.test.js +84 -0
  218. package/core/workspace-app/tests/unit/claude-session.test.js +41 -0
  219. package/core/workspace-app/tests/unit/command-flags.test.js +45 -0
  220. package/core/workspace-app/tests/unit/command-palette.test.js +105 -0
  221. package/core/workspace-app/tests/unit/commands-center.test.js +338 -0
  222. package/core/workspace-app/tests/unit/composer-menu.test.js +187 -0
  223. package/core/workspace-app/tests/unit/config-yaml.test.js +116 -0
  224. package/core/workspace-app/tests/unit/confirm-dialog.test.js +69 -0
  225. package/core/workspace-app/tests/unit/create-card.test.js +85 -0
  226. package/core/workspace-app/tests/unit/ddev-addons.test.js +144 -0
  227. package/core/workspace-app/tests/unit/ddev-auth-ssh.test.js +40 -0
  228. package/core/workspace-app/tests/unit/ddev-custom-commands.test.js +56 -0
  229. package/core/workspace-app/tests/unit/ddev-diagnose.test.js +57 -0
  230. package/core/workspace-app/tests/unit/ddev-domains.test.js +153 -0
  231. package/core/workspace-app/tests/unit/ddev-hostnames.test.js +143 -0
  232. package/core/workspace-app/tests/unit/ddev-import.test.js +82 -0
  233. package/core/workspace-app/tests/unit/ddev-mail.test.js +135 -0
  234. package/core/workspace-app/tests/unit/ddev-menu-and-create.test.js +28 -0
  235. package/core/workspace-app/tests/unit/ddev-mutagen.test.js +37 -0
  236. package/core/workspace-app/tests/unit/ddev-options.test.js +51 -0
  237. package/core/workspace-app/tests/unit/ddev-share.test.js +40 -0
  238. package/core/workspace-app/tests/unit/ddev-shim.test.js +57 -0
  239. package/core/workspace-app/tests/unit/ddev-snapshots.test.js +142 -0
  240. package/core/workspace-app/tests/unit/ddev-start-daemons.test.js +62 -0
  241. package/core/workspace-app/tests/unit/ddev-xdebug.test.js +41 -0
  242. package/core/workspace-app/tests/unit/deep-chat-origin.test.js +38 -0
  243. package/core/workspace-app/tests/unit/density.test.js +52 -0
  244. package/core/workspace-app/tests/unit/elevenlabs.test.js +453 -0
  245. package/core/workspace-app/tests/unit/event-log.test.js +102 -0
  246. package/core/workspace-app/tests/unit/favicon.test.js +68 -0
  247. package/core/workspace-app/tests/unit/files-browser.test.js +224 -0
  248. package/core/workspace-app/tests/unit/git-info.test.js +26 -0
  249. package/core/workspace-app/tests/unit/grid-and-list.test.js +103 -0
  250. package/core/workspace-app/tests/unit/host-tool-wrapper.test.js +18 -0
  251. package/core/workspace-app/tests/unit/html-patterns.test.js +51 -0
  252. package/core/workspace-app/tests/unit/ide-infra.test.js +28 -0
  253. package/core/workspace-app/tests/unit/images-ai.test.js +201 -0
  254. package/core/workspace-app/tests/unit/images-create.test.js +59 -0
  255. package/core/workspace-app/tests/unit/images-providers.test.js +248 -0
  256. package/core/workspace-app/tests/unit/images-svg.test.js +213 -0
  257. package/core/workspace-app/tests/unit/images-workspace.test.js +144 -0
  258. package/core/workspace-app/tests/unit/jobs-fragment.test.js +66 -0
  259. package/core/workspace-app/tests/unit/media-ux.test.js +164 -0
  260. package/core/workspace-app/tests/unit/modal-fit.test.js +87 -0
  261. package/core/workspace-app/tests/unit/modules-load.test.js +23 -0
  262. package/core/workspace-app/tests/unit/narration.test.js +186 -0
  263. package/core/workspace-app/tests/unit/navigation-editor.test.js +260 -0
  264. package/core/workspace-app/tests/unit/navigation.test.js +254 -0
  265. package/core/workspace-app/tests/unit/new-folder.test.js +121 -0
  266. package/core/workspace-app/tests/unit/new-screen-form.test.js +149 -0
  267. package/core/workspace-app/tests/unit/node-menu.test.js +161 -0
  268. package/core/workspace-app/tests/unit/notes.test.js +128 -0
  269. package/core/workspace-app/tests/unit/page-structure.test.js +40 -0
  270. package/core/workspace-app/tests/unit/page-width.test.js +59 -0
  271. package/core/workspace-app/tests/unit/php-version.test.js +90 -0
  272. package/core/workspace-app/tests/unit/plan-card.test.js +44 -0
  273. package/core/workspace-app/tests/unit/plugin-catalog.test.js +31 -0
  274. package/core/workspace-app/tests/unit/plugin-system.test.js +251 -0
  275. package/core/workspace-app/tests/unit/plugins-page.test.js +28 -0
  276. package/core/workspace-app/tests/unit/plugins.test.js +58 -0
  277. package/core/workspace-app/tests/unit/project-activity-filter.test.js +180 -0
  278. package/core/workspace-app/tests/unit/project-make.test.js +143 -0
  279. package/core/workspace-app/tests/unit/project-name.test.js +202 -0
  280. package/core/workspace-app/tests/unit/reader.test.js +62 -0
  281. package/core/workspace-app/tests/unit/release.test.js +92 -0
  282. package/core/workspace-app/tests/unit/remove-confirm.test.js +37 -0
  283. package/core/workspace-app/tests/unit/report-pdf.test.js +171 -0
  284. package/core/workspace-app/tests/unit/round-11.test.js +31 -0
  285. package/core/workspace-app/tests/unit/round-12.test.js +37 -0
  286. package/core/workspace-app/tests/unit/row-layout.test.js +585 -0
  287. package/core/workspace-app/tests/unit/row-menus-fold.test.js +29 -0
  288. package/core/workspace-app/tests/unit/rows-add-modal.test.js +68 -0
  289. package/core/workspace-app/tests/unit/screen-runner-queue.test.js +41 -0
  290. package/core/workspace-app/tests/unit/screen-window.test.js +116 -0
  291. package/core/workspace-app/tests/unit/screens-beside-running.test.js +19 -0
  292. package/core/workspace-app/tests/unit/screens-columns.test.js +79 -0
  293. package/core/workspace-app/tests/unit/screens-menu.test.js +84 -0
  294. package/core/workspace-app/tests/unit/screens-modal-overlay.test.js +14 -0
  295. package/core/workspace-app/tests/unit/screens-waiting.test.js +129 -0
  296. package/core/workspace-app/tests/unit/screens.test.js +74 -0
  297. package/core/workspace-app/tests/unit/second-storage.test.js +218 -0
  298. package/core/workspace-app/tests/unit/session-name.test.js +64 -0
  299. package/core/workspace-app/tests/unit/settings-file.test.js +173 -0
  300. package/core/workspace-app/tests/unit/settings-nested-list.test.js +54 -0
  301. package/core/workspace-app/tests/unit/settings-raw.test.js +177 -0
  302. package/core/workspace-app/tests/unit/shared-prefs.test.js +49 -0
  303. package/core/workspace-app/tests/unit/speech.test.js +290 -0
  304. package/core/workspace-app/tests/unit/static-caching.test.js +39 -0
  305. package/core/workspace-app/tests/unit/status-language.test.js +47 -0
  306. package/core/workspace-app/tests/unit/tab-modal.test.js +69 -0
  307. package/core/workspace-app/tests/unit/tab-title.test.js +37 -0
  308. package/core/workspace-app/tests/unit/template-literals.test.js +52 -0
  309. package/core/workspace-app/tests/unit/terminal-scrollback.test.js +61 -0
  310. package/core/workspace-app/tests/unit/terminal-size.test.js +103 -0
  311. package/core/workspace-app/tests/unit/terminal-style.test.js +84 -0
  312. package/core/workspace-app/tests/unit/terminal-windows.test.js +154 -0
  313. package/core/workspace-app/tests/unit/themes.test.js +453 -0
  314. package/core/workspace-app/tests/unit/tool-labels.test.js +34 -0
  315. package/core/workspace-app/tests/unit/topbar-icons.test.js +47 -0
  316. package/core/workspace-app/tests/unit/update-docker-gid.test.js +51 -0
  317. package/core/workspace-app/tests/unit/user-guide.test.js +60 -0
  318. package/core/workspace-app/tests/unit/version-check.test.js +98 -0
  319. package/core/workspace-app/tests/unit/version-link.test.js +50 -0
  320. package/core/workspace-app/tests/unit/video-borrow.test.js +198 -0
  321. package/core/workspace-app/tests/unit/video-edit-ask.test.js +93 -0
  322. package/core/workspace-app/tests/unit/video-edit-short.test.js +42 -0
  323. package/core/workspace-app/tests/unit/video-edit.test.js +417 -0
  324. package/core/workspace-app/tests/unit/video-transcript.test.js +237 -0
  325. package/core/workspace-app/tests/unit/waiting.test.js +48 -0
  326. package/core/workspace-app/tests/unit/wordpress-odoo-builders.test.js +38 -0
  327. package/core/workspace-app/tests/unit/workspace-bin.test.js +48 -0
  328. package/core/workspace-app/tests/unit/workspace-card-tools.test.js +30 -0
  329. package/core/workspace-app/tests/unit/workspace-delete.test.js +77 -0
  330. package/core/workspace-app/tests/unit/workspace-types.test.js +68 -0
  331. package/core/workspace-app/tests/unit/worktree-clone.test.js +250 -0
  332. package/package.json +38 -36
  333. /package/{PLUGINS.md → core/workspace-app/PLUGINS.md} +0 -0
  334. /package/{WORKSPACES.md → core/workspace-app/WORKSPACES.md} +0 -0
  335. /package/{actions → core/workspace-app/actions}/ai-items.js +0 -0
  336. /package/{actions → core/workspace-app/actions}/audio.js +0 -0
  337. /package/{actions → core/workspace-app/actions}/build-order.js +0 -0
  338. /package/{actions → core/workspace-app/actions}/checks.js +0 -0
  339. /package/{actions → core/workspace-app/actions}/claude-session.js +0 -0
  340. /package/{actions → core/workspace-app/actions}/commands-center.js +0 -0
  341. /package/{actions → core/workspace-app/actions}/composer.js +0 -0
  342. /package/{actions → core/workspace-app/actions}/ddev-addons.js +0 -0
  343. /package/{actions → core/workspace-app/actions}/ddev-mail.js +0 -0
  344. /package/{actions → core/workspace-app/actions}/folders.js +0 -0
  345. /package/{actions → core/workspace-app/actions}/images-svg.js +0 -0
  346. /package/{actions → core/workspace-app/actions}/images.js +0 -0
  347. /package/{actions → core/workspace-app/actions}/navigation.js +0 -0
  348. /package/{actions → core/workspace-app/actions}/node.js +0 -0
  349. /package/{actions → core/workspace-app/actions}/notes.js +0 -0
  350. /package/{actions → core/workspace-app/actions}/plugins.js +0 -0
  351. /package/{actions → core/workspace-app/actions}/project-make.js +0 -0
  352. /package/{actions → core/workspace-app/actions}/row-actions.js +0 -0
  353. /package/{actions → core/workspace-app/actions}/screens.js +0 -0
  354. /package/{actions → core/workspace-app/actions}/video-edit.js +0 -0
  355. /package/{ai-inventory.js → core/workspace-app/ai-inventory.js} +0 -0
  356. /package/{ai-items.js → core/workspace-app/ai-items.js} +0 -0
  357. /package/{assistant-cast.js → core/workspace-app/assistant-cast.js} +0 -0
  358. /package/{assistant-suggestions.js → core/workspace-app/assistant-suggestions.js} +0 -0
  359. /package/{audio-voice.js → core/workspace-app/audio-voice.js} +0 -0
  360. /package/{auth-google.js → core/workspace-app/auth-google.js} +0 -0
  361. /package/{build-ai.js → core/workspace-app/build-ai.js} +0 -0
  362. /package/{build-order-page.js → core/workspace-app/build-order-page.js} +0 -0
  363. /package/{build-order.js → core/workspace-app/build-order.js} +0 -0
  364. /package/{builder-args.js → core/workspace-app/builder-args.js} +0 -0
  365. /package/{changelog.js → core/workspace-app/changelog.js} +0 -0
  366. /package/{chat-threads.js → core/workspace-app/chat-threads.js} +0 -0
  367. /package/{checks.js → core/workspace-app/checks.js} +0 -0
  368. /package/{claude-args.js → core/workspace-app/claude-args.js} +0 -0
  369. /package/{claude-sessions.js → core/workspace-app/claude-sessions.js} +0 -0
  370. /package/{command-author.js → core/workspace-app/command-author.js} +0 -0
  371. /package/{command-block.js → core/workspace-app/command-block.js} +0 -0
  372. /package/{commands → core/workspace-app/commands}/defaults.yml +0 -0
  373. /package/{commands-page.js → core/workspace-app/commands-page.js} +0 -0
  374. /package/{commands.js → core/workspace-app/commands.js} +0 -0
  375. /package/{cucumber.js → core/workspace-app/cucumber.js} +0 -0
  376. /package/{ddev-addons-page.js → core/workspace-app/ddev-addons-page.js} +0 -0
  377. /package/{ddev-addons.js → core/workspace-app/ddev-addons.js} +0 -0
  378. /package/{ddev-custom-commands.js → core/workspace-app/ddev-custom-commands.js} +0 -0
  379. /package/{ddev-domains.js → core/workspace-app/ddev-domains.js} +0 -0
  380. /package/{ddev-import.js → core/workspace-app/ddev-import.js} +0 -0
  381. /package/{ddev-mail-page.js → core/workspace-app/ddev-mail-page.js} +0 -0
  382. /package/{ddev-mail.js → core/workspace-app/ddev-mail.js} +0 -0
  383. /package/{ddev-options.js → core/workspace-app/ddev-options.js} +0 -0
  384. /package/{ddev-snapshots.js → core/workspace-app/ddev-snapshots.js} +0 -0
  385. /package/{ddev.js → core/workspace-app/ddev.js} +0 -0
  386. /package/{docs → core/workspace-app/docs}/DEVELOPER-GUIDE.md +0 -0
  387. /package/{docs → core/workspace-app/docs}/README.md +0 -0
  388. /package/{docs → core/workspace-app/docs}/REFERENCE.md +0 -0
  389. /package/{docs → core/workspace-app/docs}/USER-GUIDE.md +0 -0
  390. /package/{docs → core/workspace-app/docs}/screenshots/assistant/avatar-board.png +0 -0
  391. /package/{docs → core/workspace-app/docs}/screenshots/assistant/avatar-coffee.png +0 -0
  392. /package/{docs → core/workspace-app/docs}/screenshots/assistant/avatar-colours.png +0 -0
  393. /package/{docs → core/workspace-app/docs}/screenshots/assistant/avatar-icons.png +0 -0
  394. /package/{docs → core/workspace-app/docs}/screenshots/assistant/avatar-moves.png +0 -0
  395. /package/{docs → core/workspace-app/docs}/screenshots/assistant/avatar-pick-cookieman.png +0 -0
  396. /package/{docs → core/workspace-app/docs}/screenshots/assistant/avatar-settings-voices.png +0 -0
  397. /package/{docs → core/workspace-app/docs}/screenshots/assistant/avatar-status.png +0 -0
  398. /package/{docs → core/workspace-app/docs}/screenshots/create-card/create-card.png +0 -0
  399. /package/{docs → core/workspace-app/docs}/screenshots/create-card/start-ai.png +0 -0
  400. /package/{docs → core/workspace-app/docs}/screenshots/guide-clone-address.png +0 -0
  401. /package/{docs → core/workspace-app/docs}/screenshots/guide-clone-worktree-off.png +0 -0
  402. /package/{docs → core/workspace-app/docs}/screenshots/guide-clone-worktree-on.png +0 -0
  403. /package/{docs → core/workspace-app/docs}/screenshots/guide-ddev-menu.png +0 -0
  404. /package/{docs → core/workspace-app/docs}/screenshots/guide-domains.png +0 -0
  405. /package/{docs → core/workspace-app/docs}/screenshots/guide-home.png +0 -0
  406. /package/{docs → core/workspace-app/docs}/screenshots/guide-ide-menu.png +0 -0
  407. /package/{docs → core/workspace-app/docs}/screenshots/guide-remove-refusal.png +0 -0
  408. /package/{docs → core/workspace-app/docs}/screenshots/guide-rows-worktree.png +0 -0
  409. /package/{docs → core/workspace-app/docs}/screenshots/guide-screens.png +0 -0
  410. /package/{docs → core/workspace-app/docs}/screenshots/guide-settings.png +0 -0
  411. /package/{docs → core/workspace-app/docs}/screenshots/guide-workspace-page.png +0 -0
  412. /package/{docs → core/workspace-app/docs}/screenshots/home/card-settings.png +0 -0
  413. /package/{docs → core/workspace-app/docs}/screenshots/home/drag-reorder.png +0 -0
  414. /package/{docs → core/workspace-app/docs}/screenshots/home/edit-card.png +0 -0
  415. /package/{docs → core/workspace-app/docs}/screenshots/images/claude-code-image.png +0 -0
  416. /package/{docs → core/workspace-app/docs}/screenshots/images/edit-with-ai.png +0 -0
  417. /package/{docs → core/workspace-app/docs}/screenshots/images/gallery.png +0 -0
  418. /package/{docs → core/workspace-app/docs}/screenshots/images/generate-description.png +0 -0
  419. /package/{docs → core/workspace-app/docs}/screenshots/images/generate-plan.png +0 -0
  420. /package/{docs → core/workspace-app/docs}/screenshots/images/providers.png +0 -0
  421. /package/{docs → core/workspace-app/docs}/screenshots/images/svg-form.png +0 -0
  422. /package/{docs → core/workspace-app/docs}/screenshots/images/svg-result.png +0 -0
  423. /package/{docs → core/workspace-app/docs}/screenshots/images/upload.png +0 -0
  424. /package/{docs → core/workspace-app/docs}/screenshots/new-folder/2-form.png +0 -0
  425. /package/{docs → core/workspace-app/docs}/screenshots/new-folder/8-ddev-options.png +0 -0
  426. /package/{docs → core/workspace-app/docs}/screenshots/new-folder/files-folder.png +0 -0
  427. /package/{docs → core/workspace-app/docs}/screenshots/projects/ddev-custom-commands.png +0 -0
  428. /package/{docs → core/workspace-app/docs}/screenshots/projects/state-chip-stop.png +0 -0
  429. /package/{docs → core/workspace-app/docs}/screenshots/readme/dashboard-dark.png +0 -0
  430. /package/{docs → core/workspace-app/docs}/screenshots/readme/dashboard-light.png +0 -0
  431. /package/{docs → core/workspace-app/docs}/screenshots/readme/dev-dark.png +0 -0
  432. /package/{docs → core/workspace-app/docs}/screenshots/readme/dev-light.png +0 -0
  433. /package/{docs → core/workspace-app/docs}/screenshots/readme/docs-dark.png +0 -0
  434. /package/{docs → core/workspace-app/docs}/screenshots/readme/docs-light.png +0 -0
  435. /package/{docs → core/workspace-app/docs}/screenshots/readme/icons/ai.svg +0 -0
  436. /package/{docs → core/workspace-app/docs}/screenshots/readme/icons/code.svg +0 -0
  437. /package/{docs → core/workspace-app/docs}/screenshots/readme/icons/docs.svg +0 -0
  438. /package/{docs → core/workspace-app/docs}/screenshots/readme/icons/services.svg +0 -0
  439. /package/{docs → core/workspace-app/docs}/screenshots/readme/icons/sites.svg +0 -0
  440. /package/{docs → core/workspace-app/docs}/screenshots/readme/test-report-dark.png +0 -0
  441. /package/{docs → core/workspace-app/docs}/screenshots/readme/test-report-light.png +0 -0
  442. /package/{docs → core/workspace-app/docs}/screenshots/readme/test-scenarios.png +0 -0
  443. /package/{docs → core/workspace-app/docs}/screenshots/readme/test-steps.png +0 -0
  444. /package/{docs → core/workspace-app/docs}/screenshots/readme/videos-dark.png +0 -0
  445. /package/{docs → core/workspace-app/docs}/screenshots/readme/videos-light.png +0 -0
  446. /package/{docs → core/workspace-app/docs}/screenshots/screens-menu.png +0 -0
  447. /package/{docs → core/workspace-app/docs}/screenshots/screens-new.png +0 -0
  448. /package/{docs → core/workspace-app/docs}/screenshots/settings/auth-google-lists.png +0 -0
  449. /package/{docs → core/workspace-app/docs}/screenshots/settings/delete-1-row.png +0 -0
  450. /package/{docs → core/workspace-app/docs}/screenshots/settings/delete-2-confirm.png +0 -0
  451. /package/{docs → core/workspace-app/docs}/screenshots/settings/delete-3-type-name.png +0 -0
  452. /package/{docs → core/workspace-app/docs}/screenshots/settings/delete-4-type-yes.png +0 -0
  453. /package/{event-log.js → core/workspace-app/event-log.js} +0 -0
  454. /package/{files-browser.js → core/workspace-app/files-browser.js} +0 -0
  455. /package/{folders.js → core/workspace-app/folders.js} +0 -0
  456. /package/{format.js → core/workspace-app/format.js} +0 -0
  457. /package/{github-auth.js → core/workspace-app/github-auth.js} +0 -0
  458. /package/{html.js → core/workspace-app/html.js} +0 -0
  459. /package/{icons.js → core/workspace-app/icons.js} +0 -0
  460. /package/{images-ai.js → core/workspace-app/images-ai.js} +0 -0
  461. /package/{images-create.js → core/workspace-app/images-create.js} +0 -0
  462. /package/{images-page.js → core/workspace-app/images-page.js} +0 -0
  463. /package/{images-records.js → core/workspace-app/images-records.js} +0 -0
  464. /package/{images-render.js → core/workspace-app/images-render.js} +0 -0
  465. /package/{images-svg-core.js → core/workspace-app/images-svg-core.js} +0 -0
  466. /package/{images-svg-sanitize.js → core/workspace-app/images-svg-sanitize.js} +0 -0
  467. /package/{images-svg.js → core/workspace-app/images-svg.js} +0 -0
  468. /package/{images.js → core/workspace-app/images.js} +0 -0
  469. /package/{jobs.js → core/workspace-app/jobs.js} +0 -0
  470. /package/{linger.js → core/workspace-app/linger.js} +0 -0
  471. /package/{lists.js → core/workspace-app/lists.js} +0 -0
  472. /package/{media-info.js → core/workspace-app/media-info.js} +0 -0
  473. /package/{navigation-page.js → core/workspace-app/navigation-page.js} +0 -0
  474. /package/{navigation.js → core/workspace-app/navigation.js} +0 -0
  475. /package/{notes.js → core/workspace-app/notes.js} +0 -0
  476. /package/{palette-index.js → core/workspace-app/palette-index.js} +0 -0
  477. /package/{playwright.config.js → core/workspace-app/playwright.config.js} +0 -0
  478. /package/{plugin-install.js → core/workspace-app/plugin-install.js} +0 -0
  479. /package/{plugin-loader.js → core/workspace-app/plugin-loader.js} +0 -0
  480. /package/{plugin-manifest.js → core/workspace-app/plugin-manifest.js} +0 -0
  481. /package/{plugin-settings.js → core/workspace-app/plugin-settings.js} +0 -0
  482. /package/{plugins → core/workspace-app/plugins}/workspace-notes/index.js +0 -0
  483. /package/{project-make.js → core/workspace-app/project-make.js} +0 -0
  484. /package/{project-name.js → core/workspace-app/project-name.js} +0 -0
  485. /package/{public → core/workspace-app/public}/assistant-avatar-moves.js +0 -0
  486. /package/{public → core/workspace-app/public}/assistant-avatar-ui.js +0 -0
  487. /package/{public → core/workspace-app/public}/assistant-avatar.js +0 -0
  488. /package/{public → core/workspace-app/public}/avatar/druplicon.vrm +0 -0
  489. /package/{public → core/workspace-app/public}/css/base.css +0 -0
  490. /package/{public → core/workspace-app/public}/css/components/ai-assistant.css +0 -0
  491. /package/{public → core/workspace-app/public}/css/components/assistant-avatar.css +0 -0
  492. /package/{public → core/workspace-app/public}/css/components/assistant-views.css +0 -0
  493. /package/{public → core/workspace-app/public}/css/components/build-order.css +0 -0
  494. /package/{public → core/workspace-app/public}/css/components/clone-as-a-git-worktree.css +0 -0
  495. /package/{public → core/workspace-app/public}/css/components/command-palette.css +0 -0
  496. /package/{public → core/workspace-app/public}/css/components/commands-center.css +0 -0
  497. /package/{public → core/workspace-app/public}/css/components/confirm-dialog.css +0 -0
  498. /package/{public → core/workspace-app/public}/css/components/create-card.css +0 -0
  499. /package/{public → core/workspace-app/public}/css/components/ddev-menu.css +0 -0
  500. /package/{public → core/workspace-app/public}/css/components/deep-chat.css +0 -0
  501. /package/{public → core/workspace-app/public}/css/components/density.css +0 -0
  502. /package/{public → core/workspace-app/public}/css/components/floating-assistant-workspace-pages.css +0 -0
  503. /package/{public → core/workspace-app/public}/css/components/folders.css +0 -0
  504. /package/{public → core/workspace-app/public}/css/components/full-height-left-assistant-sidebar-all-pages.css +0 -0
  505. /package/{public → core/workspace-app/public}/css/components/full-height-right-actions-rail-pages-that-have-actions.css +0 -0
  506. /package/{public → core/workspace-app/public}/css/components/grid-and-list.css +0 -0
  507. /package/{public → core/workspace-app/public}/css/components/help-page.css +0 -0
  508. /package/{public → core/workspace-app/public}/css/components/hero.css +0 -0
  509. /package/{public → core/workspace-app/public}/css/components/images.css +0 -0
  510. /package/{public → core/workspace-app/public}/css/components/layout-rhythm-and-spacing-polish.css +0 -0
  511. /package/{public → core/workspace-app/public}/css/components/mic-on-any-field-that-wants-typing.css +0 -0
  512. /package/{public → core/workspace-app/public}/css/components/modal-fit.css +0 -0
  513. /package/{public → core/workspace-app/public}/css/components/page-width.css +0 -0
  514. /package/{public → core/workspace-app/public}/css/components/plugins-page.css +0 -0
  515. /package/{public → core/workspace-app/public}/css/components/project-cards.css +0 -0
  516. /package/{public → core/workspace-app/public}/css/components/project-rows.css +0 -0
  517. /package/{public → core/workspace-app/public}/css/components/reordering-the-workspace-cards.css +0 -0
  518. /package/{public → core/workspace-app/public}/css/components/responsive-home-and-the-workspace-pages.css +0 -0
  519. /package/{public → core/workspace-app/public}/css/components/running-commands-as-toasts.css +0 -0
  520. /package/{public → core/workspace-app/public}/css/components/settings-editor-core-config-yml.css +0 -0
  521. /package/{public → core/workspace-app/public}/css/components/short-results-as-a-toast-at-the-top.css +0 -0
  522. /package/{public → core/workspace-app/public}/css/components/sound-player.css +0 -0
  523. /package/{public → core/workspace-app/public}/css/components/suggest-agents-skills-commands.css +0 -0
  524. /package/{public → core/workspace-app/public}/css/components/tab-modal.css +0 -0
  525. /package/{public → core/workspace-app/public}/css/components/terminals.css +0 -0
  526. /package/{public → core/workspace-app/public}/css/components/test-report-media-one-file-per-row-paged.css +0 -0
  527. /package/{public → core/workspace-app/public}/css/components/top-toolbar-logo-breadcrumb.css +0 -0
  528. /package/{public → core/workspace-app/public}/css/components/video-edit.css +0 -0
  529. /package/{public → core/workspace-app/public}/css/components/web-ide-open-with.css +0 -0
  530. /package/{public → core/workspace-app/public}/css/components/working-indicators.css +0 -0
  531. /package/{public → core/workspace-app/public}/css/components/workspace-cards.css +0 -0
  532. /package/{public → core/workspace-app/public}/favicon.ico +0 -0
  533. /package/{public → core/workspace-app/public}/favicon.png +0 -0
  534. /package/{public → core/workspace-app/public}/htmx.min.js +0 -0
  535. /package/{public → core/workspace-app/public}/logo.png +0 -0
  536. /package/{public → core/workspace-app/public}/media-player.js +0 -0
  537. /package/{public → core/workspace-app/public}/mic.js +0 -0
  538. /package/{public → core/workspace-app/public}/narration.js +0 -0
  539. /package/{public → core/workspace-app/public}/palette.js +0 -0
  540. /package/{public → core/workspace-app/public}/sortable.js +0 -0
  541. /package/{public → core/workspace-app/public}/suggest.js +0 -0
  542. /package/{public → core/workspace-app/public}/terminal.js +0 -0
  543. /package/{public → core/workspace-app/public}/themes/default/theme.css +0 -0
  544. /package/{public → core/workspace-app/public}/themes/ember/theme.css +0 -0
  545. /package/{public → core/workspace-app/public}/themes/press/theme.css +0 -0
  546. /package/{public → core/workspace-app/public}/themes/slate/theme.css +0 -0
  547. /package/{public → core/workspace-app/public}/touch-icon.png +0 -0
  548. /package/{public → core/workspace-app/public}/ui.js +0 -0
  549. /package/{public → core/workspace-app/public}/vendor/ace/LICENSE.txt +0 -0
  550. /package/{public → core/workspace-app/public}/vendor/ace/ace.js +0 -0
  551. /package/{public → core/workspace-app/public}/vendor/ace/ext-language_tools.js +0 -0
  552. /package/{public → core/workspace-app/public}/vendor/ace/ext-searchbox.js +0 -0
  553. /package/{public → core/workspace-app/public}/vendor/ace/mode-css.js +0 -0
  554. /package/{public → core/workspace-app/public}/vendor/ace/mode-html.js +0 -0
  555. /package/{public → core/workspace-app/public}/vendor/ace/mode-javascript.js +0 -0
  556. /package/{public → core/workspace-app/public}/vendor/ace/mode-markdown.js +0 -0
  557. /package/{public → core/workspace-app/public}/vendor/ace/mode-sh.js +0 -0
  558. /package/{public → core/workspace-app/public}/vendor/ace/mode-yaml.js +0 -0
  559. /package/{public → core/workspace-app/public}/vendor/ace/theme-textmate.js +0 -0
  560. /package/{public → core/workspace-app/public}/vendor/ace/theme-tomorrow_night.js +0 -0
  561. /package/{public → core/workspace-app/public}/vendor/ace/worker-yaml.js +0 -0
  562. /package/{public → core/workspace-app/public}/vendor/deep-chat.LICENSE +0 -0
  563. /package/{public → core/workspace-app/public}/vendor/deep-chat.bundle.js +0 -0
  564. /package/{public → core/workspace-app/public}/vendor/fonts/dm-serif-text-LICENSE.txt +0 -0
  565. /package/{public → core/workspace-app/public}/vendor/fonts/dm-serif-text-latin-400-italic.woff2 +0 -0
  566. /package/{public → core/workspace-app/public}/vendor/fonts/dm-serif-text-latin-400-normal.woff2 +0 -0
  567. /package/{public → core/workspace-app/public}/vendor/fonts/figtree-LICENSE.txt +0 -0
  568. /package/{public → core/workspace-app/public}/vendor/fonts/figtree-latin-400-italic.woff2 +0 -0
  569. /package/{public → core/workspace-app/public}/vendor/fonts/figtree-latin-400-normal.woff2 +0 -0
  570. /package/{public → core/workspace-app/public}/vendor/fonts/figtree-latin-600-italic.woff2 +0 -0
  571. /package/{public → core/workspace-app/public}/vendor/fonts/figtree-latin-600-normal.woff2 +0 -0
  572. /package/{public → core/workspace-app/public}/vendor/fonts/jetbrains-mono-LICENSE.txt +0 -0
  573. /package/{public → core/workspace-app/public}/vendor/fonts/jetbrains-mono-latin-400-normal.woff2 +0 -0
  574. /package/{public → core/workspace-app/public}/vendor/fonts/ubuntu-mono-LICENSE.txt +0 -0
  575. /package/{public → core/workspace-app/public}/vendor/fonts/ubuntu-mono-latin-wght-normal.woff2 +0 -0
  576. /package/{public → core/workspace-app/public}/vendor/tabler-LICENSE.txt +0 -0
  577. /package/{public → core/workspace-app/public}/vendor/tabler-sprite.svg +0 -0
  578. /package/{public → core/workspace-app/public}/vendor/three/LICENSE +0 -0
  579. /package/{public → core/workspace-app/public}/vendor/three/addons/loaders/GLTFLoader.js +0 -0
  580. /package/{public → core/workspace-app/public}/vendor/three/addons/utils/BufferGeometryUtils.js +0 -0
  581. /package/{public → core/workspace-app/public}/vendor/three/addons/utils/SkeletonUtils.js +0 -0
  582. /package/{public → core/workspace-app/public}/vendor/three/three.core.min.js +0 -0
  583. /package/{public → core/workspace-app/public}/vendor/three/three.module.min.js +0 -0
  584. /package/{public → core/workspace-app/public}/vendor/three-vrm/LICENSE +0 -0
  585. /package/{public → core/workspace-app/public}/vendor/three-vrm/three-vrm.module.min.js +0 -0
  586. /package/{public → core/workspace-app/public}/vendor/uikit-icons.min.js +0 -0
  587. /package/{public → core/workspace-app/public}/vendor/uikit.min.css +0 -0
  588. /package/{public → core/workspace-app/public}/vendor/uikit.min.js +0 -0
  589. /package/{public → core/workspace-app/public}/vendor/webship-icons/ui/bookmark-outlined.svg +0 -0
  590. /package/{public → core/workspace-app/public}/vendor/webship-icons/ui/headset.svg +0 -0
  591. /package/{public → core/workspace-app/public}/vendor/webship-icons/ui/menu.svg +0 -0
  592. /package/{public → core/workspace-app/public}/vendor/webship-icons/ui/pause.svg +0 -0
  593. /package/{public → core/workspace-app/public}/vendor/webship-icons/ui/play.svg +0 -0
  594. /package/{public → core/workspace-app/public}/vendor/webship-icons/ui/share.svg +0 -0
  595. /package/{public → core/workspace-app/public}/vendor/webship-icons/ui/sound-off.svg +0 -0
  596. /package/{public → core/workspace-app/public}/vendor/webship-icons/ui/sound-on.svg +0 -0
  597. /package/{public → core/workspace-app/public}/vendor/webship-icons/ui/stop.svg +0 -0
  598. /package/{public → core/workspace-app/public}/vendor/xterm/addon-fit.js +0 -0
  599. /package/{public → core/workspace-app/public}/vendor/xterm/addon-unicode11.js +0 -0
  600. /package/{public → core/workspace-app/public}/vendor/xterm/addon-web-links.js +0 -0
  601. /package/{public → core/workspace-app/public}/vendor/xterm/xterm.css +0 -0
  602. /package/{public → core/workspace-app/public}/vendor/xterm/xterm.js +0 -0
  603. /package/{rag.js → core/workspace-app/rag.js} +0 -0
  604. /package/{reader.js → core/workspace-app/reader.js} +0 -0
  605. /package/{repo-blobs.js → core/workspace-app/repo-blobs.js} +0 -0
  606. /package/{report-pdf.js → core/workspace-app/report-pdf.js} +0 -0
  607. /package/{row-layout.js → core/workspace-app/row-layout.js} +0 -0
  608. /package/{screenrc → core/workspace-app/screenrc} +0 -0
  609. /package/{screens.js → core/workspace-app/screens.js} +0 -0
  610. /package/{scripts → core/workspace-app/scripts}/code-server-start.sh +0 -0
  611. /package/{scripts → core/workspace-app/scripts}/images-claude-finish.js +0 -0
  612. /package/{scripts → core/workspace-app/scripts}/screen-host.sh +0 -0
  613. /package/{scripts → core/workspace-app/scripts}/screen-runner.js +0 -0
  614. /package/{scripts → core/workspace-app/scripts}/screen-then.js +0 -0
  615. /package/{scripts → core/workspace-app/scripts}/update.sh +0 -0
  616. /package/{settings-file.js → core/workspace-app/settings-file.js} +0 -0
  617. /package/{speech.js → core/workspace-app/speech.js} +0 -0
  618. /package/{tab-modal.js → core/workspace-app/tab-modal.js} +0 -0
  619. /package/{test-reports.js → core/workspace-app/test-reports.js} +0 -0
  620. /package/{themes.js → core/workspace-app/themes.js} +0 -0
  621. /package/{transcripts.js → core/workspace-app/transcripts.js} +0 -0
  622. /package/{urls.js → core/workspace-app/urls.js} +0 -0
  623. /package/{validate.js → core/workspace-app/validate.js} +0 -0
  624. /package/{version-check.js → core/workspace-app/version-check.js} +0 -0
  625. /package/{video-edit.js → core/workspace-app/video-edit.js} +0 -0
  626. /package/{waiting.js → core/workspace-app/waiting.js} +0 -0
  627. /package/{workspace-card-tools.js → core/workspace-app/workspace-card-tools.js} +0 -0
  628. /package/{workspace-delete.js → core/workspace-app/workspace-delete.js} +0 -0
  629. /package/{workspace-types.js → core/workspace-app/workspace-types.js} +0 -0
  630. /package/{workspaces.js → core/workspace-app/workspaces.js} +0 -0
@@ -0,0 +1,304 @@
1
+ #!/usr/bin/env bash
2
+
3
+ # Upsun (https://upsun.com) is where workspace projects run in the cloud —
4
+ # client demos, sandboxes, the public Webship demo. A project links to Upsun
5
+ # through `upsun project:set-remote <id>`, which writes .upsun/local/project.yaml
6
+ # and adds an `upsun` git remote; deploys are `upsun push`.
7
+ #
8
+ # These functions are the local ⇄ cloud bridge for one project directory.
9
+ # Everything defaults to read-only; the mutating verbs (--link, --init, --push)
10
+ # each demand an explicit flag, and nothing here ever creates or deletes an
11
+ # Upsun project or environment.
12
+
13
+ # Make sure the upsun CLI is available. It is installed system-wide or per
14
+ # https://docs.upsun.com/administration/cli.html — not something to install
15
+ # silently, since it immediately carries the user's cloud credentials.
16
+ function ensure_upsun() {
17
+ if command -v upsun > /dev/null 2>&1 ; then
18
+ return 0 ;
19
+ fi
20
+ echo "The upsun CLI is not installed. Install it first:" ;
21
+ echo " curl -fsSL https://raw.githubusercontent.com/upsun/cli/main/installer.sh | bash" ;
22
+ echo " (or: brew install upsun/tap/upsun-cli)" ;
23
+ echo "then authenticate with: upsun auth:browser-login" ;
24
+ echo "For CI: set an API token and UPSUN_CLI_NO_INTERACTION=1 instead." ;
25
+ return 1 ;
26
+ }
27
+
28
+ # The Upsun project ID a directory is linked to, if any.
29
+ function upsun_linked_id() {
30
+ local link_file="$1/.upsun/local/project.yaml";
31
+ if [ -f "${link_file}" ]; then
32
+ grep '^id:' "${link_file}" | awk '{print $2}' ;
33
+ fi
34
+ }
35
+
36
+ # The environment (branch) a project's local tooling works against.
37
+ #
38
+ # Kept in .upsun/local/, which the CLI's own README calls its local-only directory and which
39
+ # `upsun project:set-remote` already excluded from git via .git/info/exclude — so remembering a
40
+ # branch dirties no repository, and a project that is cloned fresh simply has no selection yet.
41
+ UPSUN_ENV_FILE=".upsun/local/workspace-environment";
42
+
43
+ function upsun_selected_env() {
44
+ local file="$1/${UPSUN_ENV_FILE}";
45
+ [ -f "${file}" ] && head -1 "${file}" | tr -d '[:space:]' ;
46
+ }
47
+
48
+ function upsun_select_env() {
49
+ local project_path="$1" env="$2";
50
+ mkdir -p "${project_path}/.upsun/local" ;
51
+ printf '%s\n' "${env}" > "${project_path}/${UPSUN_ENV_FILE}" ;
52
+ }
53
+
54
+ # Which environment a run acts on: --environment for this run, else the remembered selection,
55
+ # else nothing (the caller decides whether that is fatal). Deliberately NOT defaulting to
56
+ # `main`: pulling production data because nobody said otherwise is exactly the accident worth
57
+ # preventing.
58
+ function upsun_target_env() {
59
+ local project_path="$1";
60
+ if [ ! "${ENVIRONMENT}" == '_none_' ] ; then printf '%s' "${ENVIRONMENT}"; return 0 ; fi
61
+ upsun_selected_env "${project_path}";
62
+ }
63
+
64
+ # Where this project serves from — Drupal's two conventions, plus the flat case.
65
+ function upsun_docroot() {
66
+ local project_path="$1";
67
+ for candidate in web docroot ; do
68
+ [ -d "${project_path}/${candidate}" ] && { printf '%s' "${candidate}"; return 0 ; }
69
+ done
70
+ printf '%s' "";
71
+ }
72
+
73
+ # Pull the database of one environment into the local DDEV project.
74
+ #
75
+ # Read-only in the cloud and destructive locally, which is the opposite way round from the rest of
76
+ # this file: the local database is REPLACED. So the local one is exported first, unconditionally,
77
+ # and the run says where that copy went before it starts.
78
+ function upsun_pull_db() {
79
+ local project_path="$1" linked_id="$2" env="$3";
80
+ local stamp out dump safety;
81
+
82
+ stamp="$(date +%Y-%m-%d-%H%M%S)";
83
+ out="${backups}/${doc_name}/${PROJECT_NAME}";
84
+ mkdir -p "${out}" ;
85
+ dump="${out}/${PROJECT_NAME}-upsun-${env}-${stamp}.sql.gz";
86
+ safety="${out}/${PROJECT_NAME}-before-upsun-pull-${stamp}.sql.gz";
87
+
88
+ echo "";
89
+ echo "Pulling the ${env} database of Upsun project ${linked_id}.";
90
+ echo " This is client data: it lands on this machine and in ${out}.";
91
+ echo " Sanitize it before sharing — see the drupal-thin-db-export skill.";
92
+ echo "";
93
+
94
+ # The local database is replaced, so it is exported first. A pull that ate an afternoon's work
95
+ # because nobody thought to dump it is a bad pull.
96
+ if [ "${NO_SAFETY_BACKUP:-no}" == 'yes' ] ; then
97
+ echo "Skipping the local database export, as asked. The current local data will be lost.";
98
+ else
99
+ echo "Exporting the current local database first.";
100
+ (cd "${project_path}" && ddev export-db --file="${safety}") \
101
+ || echo " (no local database to export yet — continuing)";
102
+ fi
103
+
104
+ echo "Dumping ${env} from Upsun.";
105
+ local upsun_app ;
106
+ upsun_app=$(cd "${project_path}" && upsun apps -p "${linked_id}" -e "${env}" --pipe 2>/dev/null | grep -v '^storybook$' | head -1) ;
107
+ upsun_app="${upsun_app:-drupal}" ;
108
+ (cd "${project_path}" && upsun db:dump -p "${linked_id}" -e "${env}" --app "${upsun_app}" --gzip -f "${dump}") || return 1 ;
109
+
110
+ echo "Importing it into DDEV.";
111
+ (cd "${project_path}" && ddev start -y > /dev/null && ddev import-db --file="${dump}") || return 1 ;
112
+
113
+ echo "";
114
+ echo " Imported ${env} into ${doc_name}/${PROJECT_NAME}.";
115
+ echo " pulled dump: ${dump}";
116
+ echo " local backup: ${safety}";
117
+ echo " Drupal sites usually need: ddev drush updb -y && ddev drush cr";
118
+ }
119
+
120
+ # Pull the files mount of one environment into the local site.
121
+ #
122
+ # Only the public files mount, and only into this project's own docroot: the private mount and the
123
+ # rest of the tree are not what "the images are missing locally" means, and downloading a client's
124
+ # private files onto a laptop is not something to do as a side effect.
125
+ function upsun_pull_files() {
126
+ local project_path="$1" linked_id="$2" env="$3";
127
+ local docroot mount target;
128
+
129
+ docroot="$(upsun_docroot "${project_path}")";
130
+ if [ -z "${docroot}" ] ; then
131
+ echo "No web/ or docroot/ in ${doc_name}/${PROJECT_NAME} — nothing to pull files into.";
132
+ return 1 ;
133
+ fi
134
+ mount="${docroot}/sites/default/files";
135
+ target="${project_path}/${mount}";
136
+
137
+ echo "";
138
+ echo "Pulling the ${env} files mount of Upsun project ${linked_id} into ${mount}.";
139
+ echo " This is client data. rsync-style: it adds and overwrites, and does not delete.";
140
+ echo "";
141
+ mkdir -p "${target}" ;
142
+ local upsun_app ;
143
+ upsun_app=$(cd "${project_path}" && upsun apps -p "${linked_id}" -e "${env}" --pipe 2>/dev/null | grep -v '^storybook$' | head -1) ;
144
+ upsun_app="${upsun_app:-drupal}" ;
145
+ (cd "${project_path}" && upsun mount:download -p "${linked_id}" -e "${env}" --app "${upsun_app}" \
146
+ --mount "${mount}" --target "${target}" -y) || return 1 ;
147
+
148
+ echo "";
149
+ echo " Files are in ${mount}.";
150
+ echo " If Drupal still shows broken images: ddev drush cr";
151
+ }
152
+
153
+ function upsun_project_tool() {
154
+ ensure_upsun || return 1 ;
155
+
156
+ local project_path="${WORKSPACE_ROOT}/${doc_name}/${PROJECT_NAME}";
157
+ local linked_id="";
158
+
159
+ if [ ! -d "${project_path}" ]; then
160
+ echo "No such project: ${project_path}";
161
+ return 1 ;
162
+ fi
163
+
164
+ cd "${project_path}" ;
165
+ linked_id=$(upsun_linked_id "${project_path}") ;
166
+
167
+ # --link <id>: formalize the hand-ritual. Refuses to silently relink a
168
+ # project that already points somewhere (the webship-com-site/website_starter
169
+ # duplicate-ID mixup is exactly what this guards against).
170
+ if [ ! "${LINK}" == '_none_' ] ; then
171
+ if [ -n "${linked_id}" ] && [ ! "${linked_id}" == "${LINK}" ] && [ ! "${FORCE}" == 'yes' ] ; then
172
+ echo "${doc_name}/${PROJECT_NAME} is already linked to Upsun project ${linked_id}." ;
173
+ echo "Re-run with --force to relink it to ${LINK}." ;
174
+ return 1 ;
175
+ fi
176
+ upsun project:set-remote "${LINK}" || return 1 ;
177
+ echo "Linked ${doc_name}/${PROJECT_NAME} → ${LINK}." ;
178
+ linked_id="${LINK}";
179
+ fi
180
+
181
+ # --init: scaffold .upsun/config.yaml for a project that has none. Upsun's
182
+ # own generator asks the stack questions interactively. For a Drupal project
183
+ # the official path is better than the generic generator, so point at it.
184
+ if [ "${INIT}" == 'yes' ] ; then
185
+ if [ -f ".upsun/config.yaml" ]; then
186
+ echo ".upsun/config.yaml already exists — edit it instead of re-initializing." ;
187
+ else
188
+ if grep -q '"drupal/core' composer.json 2>/dev/null ; then
189
+ echo "This is a Drupal project. The official Upsun paths for Drupal:" ;
190
+ echo " - upsun/drupal-scaffold — a composer plugin that places .upsun/config.yaml and" ;
191
+ echo " settings.upsun.php into an existing recommended-project structure:" ;
192
+ echo " composer config repositories.upsun-drupal-scaffold vcs https://github.com/upsun/drupal-scaffold" ;
193
+ echo " composer config --json --merge extra.drupal-scaffold.allowed-packages '[\"upsun/drupal-scaffold\"]'" ;
194
+ echo " ddev composer require upsun/drupal-scaffold" ;
195
+ echo " - the Drupal reference config in the upsun skill (references/config/drupal.md," ;
196
+ echo " from github.com/upsun/ai): build/deploy hooks with drush, mounts, redis, crons." ;
197
+ echo " Verify image versions against https://meta.upsun.com/images before committing." ;
198
+ echo "" ;
199
+ echo "Running the generic generator anyway:" ;
200
+ fi
201
+ upsun project:init || return 1 ;
202
+ fi
203
+ fi
204
+
205
+ # --push: deploy the current branch. Outward-facing, so say exactly what is
206
+ # about to happen and let upsun's own confirmation gate it.
207
+ if [ "${PUSH}" == 'yes' ] ; then
208
+ if [ -z "${linked_id}" ]; then
209
+ echo "Not linked to an Upsun project — run with --link <id> first." ;
210
+ return 1 ;
211
+ fi
212
+ echo "Pushing branch '$(git rev-parse --abbrev-ref HEAD 2>/dev/null)' of ${doc_name}/${PROJECT_NAME} to Upsun project ${linked_id}…" ;
213
+ if [ ! "${ENVIRONMENT}" == '_none_' ] ; then
214
+ upsun push --target "${ENVIRONMENT}" || return 1 ;
215
+ else
216
+ upsun push || return 1 ;
217
+ fi
218
+ fi
219
+
220
+ # --environments: the branch list, which is what you pick from.
221
+ if [ "${ENVIRONMENTS}" == 'yes' ] ; then
222
+ if [ -z "${linked_id}" ] ; then
223
+ echo "Not linked to an Upsun project — run with --link <id> first." ;
224
+ return 1 ;
225
+ fi
226
+ upsun environment:list -p "${linked_id}" || return 1 ;
227
+ echo "";
228
+ echo " Select one: bash cmd-tools-upsun.sh ${PROJECT_NAME} --select <environment>";
229
+ fi
230
+
231
+ # --select: remember which environment this project works against, so the pulls take no flag.
232
+ if [ ! "${SELECT}" == '_none_' ] ; then
233
+ if [ -z "${linked_id}" ] ; then
234
+ echo "Not linked to an Upsun project — run with --link <id> first." ;
235
+ return 1 ;
236
+ fi
237
+ # Checked against the real list rather than taken on trust: a typo would otherwise be
238
+ # discovered by a pull that dumps the wrong branch, or none.
239
+ if ! upsun environment:list -p "${linked_id}" --pipe 2>/dev/null | grep -qx "${SELECT}" ; then
240
+ echo "Upsun project ${linked_id} has no environment called '${SELECT}'." ;
241
+ echo " List them: bash cmd-tools-upsun.sh ${PROJECT_NAME} --environments" ;
242
+ return 1 ;
243
+ fi
244
+ upsun_select_env "${project_path}" "${SELECT}" ;
245
+ echo "${doc_name}/${PROJECT_NAME} now works against the ${SELECT} environment." ;
246
+ fi
247
+
248
+ # --pull-db / --pull-files: bring the cloud's data down. Read-only in the cloud, destructive
249
+ # locally, and client data either way — so each needs its own flag and an environment that was
250
+ # named or selected. There is no default environment on purpose.
251
+ if [ "${PULL_DB}" == 'yes' ] || [ "${PULL_FILES}" == 'yes' ] ; then
252
+ local target_env;
253
+ target_env="$(upsun_target_env "${project_path}")";
254
+ if [ -z "${linked_id}" ] ; then
255
+ echo "Not linked to an Upsun project — run with --link <id> first." ;
256
+ return 1 ;
257
+ fi
258
+ if [ -z "${target_env}" ] ; then
259
+ echo "No environment selected. Pick one first — a pull must never guess which branch it takes data from:" ;
260
+ echo " bash cmd-tools-upsun.sh ${PROJECT_NAME} --environments" ;
261
+ echo " bash cmd-tools-upsun.sh ${PROJECT_NAME} --select <environment>" ;
262
+ echo " (or name it for this run: --environment <environment>)" ;
263
+ return 1 ;
264
+ fi
265
+ [ "${PULL_DB}" == 'yes' ] && { upsun_pull_db "${project_path}" "${linked_id}" "${target_env}" || return 1 ; }
266
+ [ "${PULL_FILES}" == 'yes' ] && { upsun_pull_files "${project_path}" "${linked_id}" "${target_env}" || return 1 ; }
267
+ fi
268
+
269
+ # --logs / --activities: recent deploy output and activity trail.
270
+ if [ "${LOGS}" == 'yes' ] ; then
271
+ upsun activity:log --type environment.push 2>/dev/null || upsun activity:log || true ;
272
+ fi
273
+ if [ "${ACTIVITIES}" == 'yes' ] ; then
274
+ upsun activity:list --limit 10 || true ;
275
+ fi
276
+
277
+ # Default (and after any verb): status.
278
+ echo "";
279
+ echo "*---------------------------------------------------------------------*";
280
+ echo " ${doc_name}/${PROJECT_NAME} on Upsun";
281
+ if [ -z "${linked_id}" ]; then
282
+ echo " not linked. Link it with:";
283
+ echo " bash cmd-tools-upsun.sh ${PROJECT_NAME} --link <upsun-project-id>";
284
+ echo " (find the ID with: upsun projects)";
285
+ else
286
+ echo " project: ${linked_id}";
287
+ if [ -f ".upsun/config.yaml" ]; then
288
+ echo " config: .upsun/config.yaml present";
289
+ else
290
+ echo " config: MISSING — scaffold it with --init before a first push";
291
+ fi
292
+ local selected;
293
+ selected="$(upsun_selected_env "${project_path}")";
294
+ echo " branch: ${selected:-none selected — --environments then --select <name>}";
295
+ echo "";
296
+ upsun environment:list 2>/dev/null || echo " (could not list environments — check upsun auth:info)";
297
+ echo "";
298
+ echo " URLs: upsun url --primary | deploy: bash cmd-tools-upsun.sh ${PROJECT_NAME} --push";
299
+ echo " Data: --pull-db and --pull-files bring ${selected:-the selected environment} down into DDEV.";
300
+ fi
301
+ echo "*---------------------------------------------------------------------*";
302
+
303
+ cd "${WORKSPACE_ROOT}/${doc_name}";
304
+ }
@@ -0,0 +1,99 @@
1
+ #!/usr/bin/env bash
2
+ ## The host side of the Upsun plugin: the upsun CLI on this machine, the dashboard's API token,
3
+ ## and Upsun's agent toolkit. Run by core/scripts/plugins.sh --install upsun, and by
4
+ ## core/scripts/install.sh for every installed plugin that ships one. Idempotent: whatever is
5
+ ## already there is reported, not redone. Offered, never automatic: the CLI holds cloud
6
+ ## credentials for real environments, so putting it on a machine is a person's decision.
7
+ set -u
8
+ WORKSPACE_ROOT="${WORKSPACE_ROOT:-$(cd "$(dirname "${BASH_SOURCE[0]}")/../../../../.." && pwd)}";
9
+ HERE="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)";
10
+ confirm() { local a; read -r -p "$1 [y/N] " a < /dev/tty 2>/dev/null || return 1; [[ "${a}" =~ ^[Yy] ]]; }
11
+ PKG='';
12
+ command -v brew > /dev/null 2>&1 && PKG='brew';
13
+
14
+ # The upsun CLI: a per-person OAuth session, mounted into the dashboard from the host rather
15
+ # than installed in the image. ~/.local/bin is where the tarball route puts it and is not always
16
+ # on PATH, so `command -v` alone reports it missing on a machine that has it.
17
+ UPSUN_BIN='';
18
+ for candidate in "$(command -v upsun 2>/dev/null)" "${HOME}/.local/bin/upsun" "${HOME}/.upsun-cli/bin/upsun" ; do
19
+ [ -n "${candidate}" ] && [ -x "${candidate}" ] && { UPSUN_BIN="${candidate}"; break; }
20
+ done
21
+ if [ -n "${UPSUN_BIN}" ] ; then
22
+ printf ' ✓ %-16s %s\n' "upsun" "${UPSUN_BIN}" ;
23
+ else
24
+ printf ' ✗ %-16s %s\n' "upsun" "missing — deploys and the UPSUN menu need it (developer.upsun.com/cli)" ;
25
+ fi
26
+
27
+ # The DASHBOARD's Upsun access is separate from the host CLI's: `upsun login` writes a session
28
+ # into the host keyring, which the container cannot reach, so the container needs an API TOKEN in
29
+ # core/config/plugin.upsun.settings.yml. Checked by SHAPE, never printed: an Atlassian token in
30
+ # that field is refused by Upsun with a message that reads like an expiry.
31
+ TOKEN_STATE="$(python3 - "${WORKSPACE_ROOT}/core/config/plugin.upsun.settings.yml" <<'PYEOF' 2>/dev/null || echo unknown
32
+ import io, re, sys
33
+ try:
34
+ s = io.open(sys.argv[1], encoding='utf-8').read()
35
+ except Exception:
36
+ print('unset'); raise SystemExit
37
+ m = re.search(r'^cli_token:\s*(\S+)', s, re.M)
38
+ t = m.group(1) if m else ''
39
+ if not t or t in ('CHANGE_ME', "''", '""'):
40
+ print('unset')
41
+ elif t.startswith('ATATT'):
42
+ print('atlassian')
43
+ else:
44
+ print('set')
45
+ PYEOF
46
+ )";
47
+ case "${TOKEN_STATE}" in
48
+ set) printf ' ✓ %-16s %s\n' "upsun token" "set for the dashboard (plugin.upsun.settings.yml)" ;;
49
+ atlassian) printf ' ✗ %-16s %s\n' "upsun token" "cli_token holds an ATLASSIAN token — Upsun refuses it" ;;
50
+ unset) printf ' ✗ %-16s %s\n' "upsun token" "cli_token not set — every UPSUN action in the dashboard fails" ;;
51
+ *) ;;
52
+ esac
53
+
54
+ # Upsun's own AI toolkit for coding agents: developer.upsun.com/ai
55
+ if bash "${HERE}/upsun-ai.sh" --check --quiet > /dev/null 2>&1 ; then
56
+ printf ' ✓ %-16s %s\n' "upsun AI" "skill + read-only MCP installed" ;
57
+ else
58
+ printf ' ✗ %-16s %s\n' "upsun AI" "Upsun's agent skill/MCP not installed (developer.upsun.com/ai)" ;
59
+ fi
60
+
61
+ [ "${1:-}" == '--check' ] && exit 0 ;
62
+
63
+ if [ -z "${UPSUN_BIN}" ] && confirm "Install the Upsun CLI (deploys, environments — holds cloud credentials)?" ; then
64
+ case "${PKG}" in
65
+ brew) brew install upsun/tap/upsun-cli ;;
66
+ *)
67
+ # Upsun's own installer sets up an apt repository, so it needs root and an interactive
68
+ # password. The release tarball needs neither: one static binary into ~/.local/bin.
69
+ upsun_ver="$(wget -qO- https://api.github.com/repos/upsun/cli/releases/latest 2>/dev/null \
70
+ | sed -n 's/.*"tag_name": *"v\([^"]*\)".*/\1/p' | head -1)" ;
71
+ if [ -n "${upsun_ver}" ] ; then
72
+ upsun_tgz="upsun_${upsun_ver}_linux_amd64.tar.gz" ;
73
+ [ "$(uname -m)" == 'aarch64' ] && upsun_tgz="upsun_${upsun_ver}_linux_arm64.tar.gz" ;
74
+ upsun_tmp="$(mktemp -d)" ;
75
+ if wget -qO "${upsun_tmp}/upsun.tgz" "https://github.com/upsun/cli/releases/download/v${upsun_ver}/${upsun_tgz}" \
76
+ && tar -xzf "${upsun_tmp}/upsun.tgz" -C "${upsun_tmp}" upsun ; then
77
+ mkdir -p "${HOME}/.local/bin" ;
78
+ install -m 0755 "${upsun_tmp}/upsun" "${HOME}/.local/bin/upsun" ;
79
+ echo " Installed upsun ${upsun_ver} to ~/.local/bin/upsun (no root needed)." ;
80
+ else
81
+ echo " Could not fetch the release tarball — falling back to Upsun's installer (needs sudo)." ;
82
+ curl -fsSL https://raw.githubusercontent.com/upsun/cli/main/installer.sh | bash ;
83
+ fi
84
+ rm -rf "${upsun_tmp}" ;
85
+ else
86
+ curl -fsSL https://raw.githubusercontent.com/upsun/cli/main/installer.sh | bash ;
87
+ fi ;;
88
+ esac
89
+ echo " Sign in with: upsun login (it opens your browser, then writes SSH certificates)" ;
90
+ echo " The DASHBOARD needs its own credential: put an UPSUN API token in cli_token in" ;
91
+ echo " core/config/plugin.upsun.settings.yml (Upsun console -> My profile -> API tokens)." ;
92
+ fi
93
+
94
+ # Upsun's AI toolkit — the skill that teaches an agent the Upsun CLI and its config format, and
95
+ # the hosted MCP server, registered READ-ONLY (Upsun's own beta default; writes there are
96
+ # permanent on live environments).
97
+ if confirm "Install Upsun's agent skill and read-only MCP server (developer.upsun.com/ai)?" ; then
98
+ bash "${HERE}/upsun-ai.sh" || true ;
99
+ fi
@@ -0,0 +1 @@
1
+ ~/.upsun-cli
@@ -0,0 +1,133 @@
1
+ #!/usr/bin/env bash
2
+
3
+ ################################################################################
4
+ ## Webship Workspace — install Upsun's own AI toolkit for coding agents
5
+ ################################################################################
6
+ ## Upsun publishes a skill and an MCP server for coding agents:
7
+ ##
8
+ ## https://developer.upsun.com/ai
9
+ ## https://github.com/upsun/ai the toolkit: plugin + skill + MCP
10
+ ## https://github.com/upsun/skills the skill on its own
11
+ ##
12
+ ## The skill teaches an agent the Upsun CLI — 130+ commands across 30 namespaces,
13
+ ## plus per-framework config recipes including Drupal and PHP — so it writes a
14
+ ## working `.upsun/config.yaml` the first time instead of learning by failed
15
+ ## deploy. The MCP server answers the same questions over HTTP when no CLI is
16
+ ## available.
17
+ ##
18
+ ## bash core/scripts/upsun-ai.sh install the skill, register the MCP
19
+ ## bash core/scripts/upsun-ai.sh --check report, change nothing
20
+ ## bash core/scripts/upsun-ai.sh --quiet only speak when something is wrong
21
+ ##
22
+ ## Two deliberate choices:
23
+ ##
24
+ ## - **The MCP is registered read-only** (`enable-write: false`, which is Upsun's
25
+ ## own default). This is a CLI that manages live client environments; an agent
26
+ ## that can read them is useful, an agent that can change them is a decision for
27
+ ## a person, per environment, not a default of a setup script.
28
+ ## - **The skill is copied, not symlinked**, into ~/.claude/skills/upsun — the same
29
+ ## place cmd-tools-ai-items.sh installs Webship's own skills, so it is visible to
30
+ ## `--source claude` and cannot vanish when a temporary clone is cleaned up.
31
+ ##
32
+ ## Self-contained plain bash, like trust-https.sh and host-mounts.sh beside it.
33
+ ################################################################################
34
+
35
+ set -u
36
+
37
+ CHECK_ONLY='no'
38
+ QUIET='no'
39
+ while [ $# -gt 0 ]; do
40
+ case "$1" in
41
+ -c|--check) CHECK_ONLY='yes'; shift ;;
42
+ -q|--quiet) QUIET='yes'; shift ;;
43
+ -h|--help) sed -n '3,33p' "${BASH_SOURCE[0]}" | sed 's/^## \{0,1\}//'; exit 0 ;;
44
+ *) echo "Unknown option: $1 (see --help)"; exit 1 ;;
45
+ esac
46
+ done
47
+
48
+ REPO='https://github.com/upsun/ai.git'
49
+ SKILL_SRC='plugins/upsun/skills/upsun'
50
+ SKILL_DEST="${HOME}/.claude/skills/upsun"
51
+ MCP_URL='https://mcp.upsun.com/mcp'
52
+
53
+ function say() { [ "${QUIET}" == 'yes' ] || echo "$@" ; }
54
+ function warn() { echo "$@" ; }
55
+ function have() { command -v "$1" > /dev/null 2>&1 ; }
56
+
57
+ PROBLEMS=0
58
+
59
+ # ------------------------------------------------------------------- the skill ---
60
+
61
+ skill_installed='no'
62
+ [ -f "${SKILL_DEST}/SKILL.md" ] && skill_installed='yes'
63
+
64
+ if [ "${skill_installed}" == 'yes' ] ; then
65
+ say " ✓ upsun skill ~/.claude/skills/upsun ($(find "${SKILL_DEST}" -type f | wc -l) files)"
66
+ elif [ "${CHECK_ONLY}" == 'yes' ] ; then
67
+ warn " ✗ upsun skill not installed — an agent has to learn the Upsun CLI by failing"
68
+ PROBLEMS=$((PROBLEMS + 1))
69
+ else
70
+ if ! have git ; then
71
+ warn " ✗ git is needed to fetch the skill."
72
+ PROBLEMS=$((PROBLEMS + 1))
73
+ else
74
+ tmp="$(mktemp -d)"
75
+ # A shallow clone: this is 164KB of Markdown, and none of its history matters here.
76
+ if git clone --quiet --depth=1 "${REPO}" "${tmp}/ai" 2>/dev/null \
77
+ && [ -f "${tmp}/ai/${SKILL_SRC}/SKILL.md" ] ; then
78
+ mkdir -p "${HOME}/.claude/skills"
79
+ rm -rf "${SKILL_DEST}"
80
+ cp -r "${tmp}/ai/${SKILL_SRC}" "${SKILL_DEST}"
81
+ say " ✓ upsun skill installed to ~/.claude/skills/upsun ($(find "${SKILL_DEST}" -type f | wc -l) files)"
82
+ else
83
+ warn " ✗ could not fetch ${REPO} — check network access to GitHub."
84
+ PROBLEMS=$((PROBLEMS + 1))
85
+ fi
86
+ rm -rf "${tmp}"
87
+ fi
88
+ fi
89
+
90
+ # --------------------------------------------------------------------- the MCP ---
91
+
92
+ if ! have claude ; then
93
+ say " – upsun MCP skipped: the claude CLI is not installed"
94
+ else
95
+ if claude mcp get upsun > /dev/null 2>&1 ; then
96
+ say " ✓ upsun MCP registered (claude mcp get upsun)"
97
+ elif [ "${CHECK_ONLY}" == 'yes' ] ; then
98
+ warn " ✗ upsun MCP not registered"
99
+ PROBLEMS=$((PROBLEMS + 1))
100
+ else
101
+ # enable-write: false is Upsun's own default and it stays that way here: see the
102
+ # header. The token comes from the environment so no credential is written into
103
+ # ~/.claude.json — ${UPSUN_API_TOKEN} is expanded when the server is loaded.
104
+ if claude mcp add --transport http upsun "${MCP_URL}" -s user \
105
+ --header 'upsun-api-token: ${UPSUN_API_TOKEN:-}' \
106
+ --header 'enable-write: false' > /dev/null 2>&1 ; then
107
+ say " ✓ upsun MCP registered read-only at ${MCP_URL}"
108
+ else
109
+ warn " ✗ could not register the upsun MCP server with the claude CLI."
110
+ PROBLEMS=$((PROBLEMS + 1))
111
+ fi
112
+ fi
113
+ fi
114
+
115
+ # ------------------------------------------------------------------ what next ---
116
+
117
+ say ""
118
+ if [ "${CHECK_ONLY}" == 'yes' ] ; then
119
+ [ "${PROBLEMS}" -eq 0 ] && { say "Upsun's AI toolkit is installed."; exit 0; }
120
+ warn "Upsun's AI toolkit is incomplete — run without --check to install it."
121
+ exit 1
122
+ fi
123
+
124
+ if [ "${PROBLEMS}" -eq 0 ] ; then
125
+ say "Upsun's AI toolkit is installed. Two things it needs from you:"
126
+ say " • The skill reaches a session after a restart."
127
+ say " • The MCP authenticates with an UPSUN API token, not the browser session:"
128
+ say " export UPSUN_API_TOKEN=… (Upsun console → My profile → API tokens)"
129
+ say " It must be an Upsun token — an Atlassian token is refused with a message"
130
+ say " that reads like an expiry rather than the wrong kind of token."
131
+ exit 0
132
+ fi
133
+ exit 1