@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,521 @@
1
+ #!/usr/bin/env bash
2
+
3
+ # The commands workspace: one place to see and manage every cmd-*.sh in the tree.
4
+ #
5
+ # The scripts themselves live in the workspace folder they belong to — a builder
6
+ # for dev sits in dev/ because that is where it is run from, and moving them here
7
+ # would break every path in the harness. So this workspace holds no scripts of
8
+ # its own; it is a view over the others, plus the operations that are awkward
9
+ # when the commands are scattered across nineteen folders:
10
+ #
11
+ # list what exists, everywhere, with what each one builds
12
+ # new scaffold a command into a workspace, bootstrap chain already right
13
+ # clone copy one, retargeted at another workspace if asked
14
+ # pull bring a command (or a new one) down from the tooling repository
15
+ # diff what this machine has against what the repo has
16
+ # propose hand a local command to the AI agent to file the issue and open
17
+ # the PR — never silently: it prints the plan and waits for --confirm
18
+ #
19
+ # Nothing here writes to the repository directly. Publishing goes through the
20
+ # agent, which follows the workspace's issue/PR rules (issue first,
21
+ # Checkpoints, never tick the human-review boxes).
22
+
23
+ # WORKSPACE_REPO / WORKSPACE_REPO_REF are resolved in bootstrap.sh from settings.yml
24
+ # `sources.tooling`, because this file is sourced before settings.yml is parsed.
25
+
26
+ # Let git borrow the gh CLI's login for github.com, so cloning the tooling repository works
27
+ # without a token in the environment and without one written into a remote URL.
28
+ #
29
+ # Defined here rather than imported: it is four lines, and this is the only thing in this
30
+ # workspace that clones from GitHub over https.
31
+ function ensure_git_github_auth() {
32
+ command -v gh > /dev/null 2>&1 || return 0 ;
33
+ export GIT_CONFIG_COUNT=1 ;
34
+ export GIT_CONFIG_KEY_0="credential.https://github.com.helper" ;
35
+ export GIT_CONFIG_VALUE_0="!gh auth git-credential" ;
36
+ }
37
+
38
+ # Where the local mirror of the tooling repository is kept. Gitignored, and
39
+ # hidden from the command listing.
40
+ function commands_repo_checkout() {
41
+ echo "${WORKSPACE_ROOT}/${doc_name}/workspace-repo";
42
+ }
43
+
44
+ # Every workspace folder, in the order settings.yml lists them.
45
+ #
46
+ # bootstrap.sh has already evaluated settings.yml, so `workspaces` is a bash
47
+ # array here. Do NOT re-evaluate it: parse_yaml emits `workspaces+=("…")`, so a
48
+ # second eval appends the whole list again and every workspace is visited twice.
49
+ # Deduplicated anyway, cheaply, so a caller that did re-evaluate cannot produce
50
+ # doubled output.
51
+ function commands_workspaces() {
52
+ local seen=" " name;
53
+ for name in "${workspaces[@]}" ; do
54
+ [ -z "${name}" ] && continue ;
55
+ case "${seen}" in *" ${name} "*) continue ;; esac
56
+ seen="${seen}${name} " ;
57
+ echo "${name}" ;
58
+ done
59
+ }
60
+
61
+ # The human name a builder declares for itself, used by the dashboard's Build
62
+ # dropdown and enforced by the smoke test.
63
+ function command_workspace_name() {
64
+ local file="$1";
65
+ sed -n 's/^# workspace-name:[[:space:]]*//p' "${file}" 2>/dev/null | head -1 ;
66
+ }
67
+
68
+ # List every cmd-*.sh, or those of one workspace.
69
+ function commands_list() {
70
+ local only="${1:-}";
71
+ local total=0 ws dir count label;
72
+
73
+ echo "*---------------------------------------------------------------------*";
74
+ echo " cmd-*.sh across the workspace";
75
+ echo "*---------------------------------------------------------------------*";
76
+
77
+ for ws in $(commands_workspaces) ; do
78
+ if [ -n "${only}" ] && [ ! "${only}" == '_all_' ] && [ ! "${ws}" == "${only}" ] ; then continue ; fi
79
+ dir="${WORKSPACE_ROOT}/${ws}";
80
+ [ -d "${dir}" ] || continue ;
81
+ count=$(find "${dir}" -maxdepth 1 -name 'cmd-*.sh' 2>/dev/null | wc -l) ;
82
+ [ "${count}" -eq 0 ] && continue ;
83
+ printf "\n %s (%s)\n" "${ws}" "${count}" ;
84
+ local f;
85
+ for f in $(find "${dir}" -maxdepth 1 -name 'cmd-*.sh' -printf '%f\n' 2>/dev/null | sort) ; do
86
+ label=$(command_workspace_name "${dir}/${f}") ;
87
+ if [ -n "${label}" ]; then
88
+ printf " %-52s %s\n" "${f}" "${label}" ;
89
+ else
90
+ printf " %s\n" "${f}" ;
91
+ fi
92
+ total=$((total+1)) ;
93
+ done
94
+ done
95
+ printf "\n %s command(s).\n" "${total}" ;
96
+ }
97
+
98
+ # Find which workspace folder holds a command, by file name.
99
+ function commands_locate() {
100
+ local file="$1" ws;
101
+ for ws in $(commands_workspaces) ; do
102
+ if [ -f "${WORKSPACE_ROOT}/${ws}/${file}" ]; then echo "${ws}"; return 0 ; fi
103
+ done
104
+ return 1 ;
105
+ }
106
+
107
+ # Refresh the local mirror of the tooling repository.
108
+ #
109
+ # Reads files out of the FETCHED REMOTE BRANCH with git archive, never the
110
+ # checkout's working tree, so a mirror someone has been poking at is left alone.
111
+ function commands_repo_sync() {
112
+ local checkout;
113
+ checkout=$(commands_repo_checkout) ;
114
+
115
+ # A real authenticated call, not `gh auth status`: that exits non-zero when ANY configured
116
+ # account fails, and the dashboard container carries a stale one beside a working GH_TOKEN.
117
+ # `--active` would fix that but does not exist in the gh Ubuntu ships (2.45).
118
+ if command -v gh > /dev/null 2>&1 && gh api user --jq .login > /dev/null 2>&1 ; then
119
+ ensure_git_github_auth ;
120
+ fi
121
+
122
+ if [ -d "${checkout}/.git" ]; then
123
+ echo "Fetching ${WORKSPACE_REPO}…" ;
124
+ git -C "${checkout}" fetch --quiet origin || return 1 ;
125
+ else
126
+ echo "Cloning ${WORKSPACE_REPO}…" ;
127
+ git clone --quiet "https://github.com/${WORKSPACE_REPO}.git" "${checkout}" || {
128
+ echo "Could not clone ${WORKSPACE_REPO}." ;
129
+ echo " If it is private, this needs a GitHub login:" ;
130
+ echo " on this machine: gh auth login" ;
131
+ echo " in the dashboard container: set GH_TOKEN in its DDEV web_environment" ;
132
+ return 1 ;
133
+ }
134
+ fi
135
+ }
136
+
137
+ # Echo a temp directory holding the repository's cmd-*.sh tree at the target ref.
138
+ function commands_repo_tree() {
139
+ local checkout tmp;
140
+ checkout=$(commands_repo_checkout) ;
141
+ tmp=$(mktemp -d) ;
142
+ if ! git -C "${checkout}" archive "origin/${WORKSPACE_REPO_REF}" 2>/dev/null | tar -x -C "${tmp}" ; then
143
+ echo "Nothing at origin/${WORKSPACE_REPO_REF} in the mirror." >&2 ;
144
+ rm -rf "${tmp}" ; return 1 ;
145
+ fi
146
+ echo "${tmp}" ;
147
+ }
148
+
149
+ # What the repository has, and whether this machine has it too.
150
+ function commands_list_remote() {
151
+ commands_repo_sync || return 1 ;
152
+ local tmp;
153
+ tmp=$(commands_repo_tree) || return 1 ;
154
+
155
+ echo "";
156
+ echo "*---------------------------------------------------------------------*";
157
+ echo " ${WORKSPACE_REPO}@${WORKSPACE_REPO_REF}";
158
+ echo "*---------------------------------------------------------------------*";
159
+ local ws f local_file state missing=0 differs=0 same=0;
160
+ for ws in $(commands_workspaces) ; do
161
+ [ -d "${tmp}/${ws}" ] || continue ;
162
+ for f in $(find "${tmp}/${ws}" -maxdepth 1 -name 'cmd-*.sh' -printf '%f\n' 2>/dev/null | sort) ; do
163
+ local_file="${WORKSPACE_ROOT}/${ws}/${f}";
164
+ if [ ! -f "${local_file}" ]; then
165
+ state="not here"; missing=$((missing+1)) ;
166
+ elif cmp -s "${local_file}" "${tmp}/${ws}/${f}" ; then
167
+ state="same"; same=$((same+1)) ;
168
+ else
169
+ state="differs"; differs=$((differs+1)) ;
170
+ fi
171
+ printf " %-11s %-14s %s\n" "${ws}" "${state}" "${f}" ;
172
+ done
173
+ done
174
+ rm -rf "${tmp}" ;
175
+ printf "\n %s same · %s differ · %s not on this machine\n" "${same}" "${differs}" "${missing}" ;
176
+ echo " Bring one down: bash cmd-tools-commands.sh --pull <cmd-file.sh>" ;
177
+ }
178
+
179
+ # Diff one command against the repository's copy.
180
+ function commands_diff() {
181
+ local file="$1";
182
+ commands_repo_sync || return 1 ;
183
+ local tmp found=0;
184
+ tmp=$(commands_repo_tree) || return 1 ;
185
+
186
+ local ws;
187
+ for ws in $(commands_workspaces) ; do
188
+ [ -f "${tmp}/${ws}/${file}" ] || continue ;
189
+ found=1 ;
190
+ if [ ! -f "${WORKSPACE_ROOT}/${ws}/${file}" ]; then
191
+ echo "${ws}/${file}: only in ${WORKSPACE_REPO} — --pull to bring it down." ;
192
+ elif cmp -s "${WORKSPACE_ROOT}/${ws}/${file}" "${tmp}/${ws}/${file}" ; then
193
+ echo "${ws}/${file}: identical to ${WORKSPACE_REPO}@${WORKSPACE_REPO_REF}." ;
194
+ else
195
+ echo "${ws}/${file}: differs (< repo, > this machine)" ;
196
+ diff "${tmp}/${ws}/${file}" "${WORKSPACE_ROOT}/${ws}/${file}" ;
197
+ fi
198
+ done
199
+ rm -rf "${tmp}" ;
200
+ [ "${found}" -eq 1 ] || { echo "No '${file}' in ${WORKSPACE_REPO}@${WORKSPACE_REPO_REF}." ; return 1 ; }
201
+ }
202
+
203
+ # Bring a command down from the repository into the workspace folder it belongs
204
+ # to — including one this machine does not have yet.
205
+ function commands_pull() {
206
+ local file="$1";
207
+ commands_repo_sync || return 1 ;
208
+ local tmp pulled=0;
209
+ tmp=$(commands_repo_tree) || return 1 ;
210
+
211
+ local ws dest keep;
212
+ for ws in $(commands_workspaces) ; do
213
+ [ -f "${tmp}/${ws}/${file}" ] || continue ;
214
+ dest="${WORKSPACE_ROOT}/${ws}";
215
+ mkdir -p "${dest}" ;
216
+
217
+ # A pull overwrites, and the ref can easily be BEHIND this machine — the
218
+ # default branch does not carry work that is still in review, so pulling can
219
+ # silently undo a local fix. Keep the version being replaced, under
220
+ # backups/, and say where it went.
221
+ if [ -f "${dest}/${file}" ] && ! cmp -s "${dest}/${file}" "${tmp}/${ws}/${file}" ; then
222
+ keep="${backups}/${doc_name}/${ws}---${file}--$(date '+%Y-%m-%d_%H-%M-%S').bak";
223
+ mkdir -p "${backups}/${doc_name}" ;
224
+ cp -a "${dest}/${file}" "${keep}" ;
225
+ echo " the copy here differed — kept it at ${keep}" ;
226
+ fi
227
+
228
+ cp "${tmp}/${ws}/${file}" "${dest}/${file}" ;
229
+ chmod +x "${dest}/${file}" ;
230
+ echo "Pulled ${ws}/${file} from ${WORKSPACE_REPO}@${WORKSPACE_REPO_REF}." ;
231
+ pulled=$((pulled+1)) ;
232
+ done
233
+ rm -rf "${tmp}" ;
234
+ [ "${pulled}" -gt 0 ] || { echo "No '${file}' in ${WORKSPACE_REPO}@${WORKSPACE_REPO_REF}." ; return 1 ; }
235
+ }
236
+
237
+ # Bring the repository's commands down in bulk.
238
+ #
239
+ # Two categories, treated differently on purpose:
240
+ #
241
+ # missing this machine does not have it. Safe to take: nothing is lost.
242
+ # differs both have it and they are not the same. NOT safe to take blindly — the difference
243
+ # may be a local fix that has not been proposed yet, which is exactly what the first
244
+ # comparison of this workspace found.
245
+ #
246
+ # So a plain --sync reports and changes nothing, --confirm takes the missing ones, and only
247
+ # --overwrite replaces the ones that differ. Each replaced file is kept under backups/ first,
248
+ # the same as a single --pull.
249
+ function commands_sync() {
250
+ local confirmed="$1" overwrite="$2";
251
+ commands_repo_sync || return 1 ;
252
+ local tmp;
253
+ tmp=$(commands_repo_tree) || return 1 ;
254
+
255
+ local ws file dest missing=() differs=() same=0;
256
+ for ws in $(commands_workspaces) ; do
257
+ [ -d "${tmp}/${ws}" ] || continue ;
258
+ for file in $(cd "${tmp}/${ws}" && ls cmd-*.sh 2>/dev/null) ; do
259
+ dest="${WORKSPACE_ROOT}/${ws}/${file}";
260
+ if [ ! -f "${dest}" ] ; then
261
+ missing+=("${ws}/${file}") ;
262
+ elif cmp -s "${dest}" "${tmp}/${ws}/${file}" ; then
263
+ same=$((same+1)) ;
264
+ else
265
+ differs+=("${ws}/${file}") ;
266
+ fi
267
+ done
268
+ done
269
+
270
+ echo "*---------------------------------------------------------------------*";
271
+ echo " Sync from ${WORKSPACE_REPO}@${WORKSPACE_REPO_REF}";
272
+ echo "*---------------------------------------------------------------------*";
273
+ echo " ${same} identical · ${#missing[@]} missing here · ${#differs[@]} differ";
274
+ echo "";
275
+ local entry;
276
+ for entry in "${missing[@]}" ; do echo " missing ${entry}" ; done
277
+ for entry in "${differs[@]}" ; do echo " differs ${entry}" ; done
278
+
279
+ if [ "${#missing[@]}" -eq 0 ] && [ "${#differs[@]}" -eq 0 ] ; then
280
+ echo "" ; echo " Nothing to bring down — this machine matches the repository." ;
281
+ rm -rf "${tmp}" ; return 0 ;
282
+ fi
283
+
284
+ if [ ! "${confirmed}" == 'yes' ] ; then
285
+ echo "";
286
+ echo " Nothing has been written. To take the missing ones:";
287
+ echo " bash cmd-tools-commands.sh --sync --confirm";
288
+ if [ "${#differs[@]}" -gt 0 ] ; then
289
+ echo " To replace the ones that differ as well (each is kept under backups/ first):";
290
+ echo " bash cmd-tools-commands.sh --sync --confirm --overwrite";
291
+ echo " Look at one first: bash cmd-tools-commands.sh --diff <cmd-file.sh>";
292
+ fi
293
+ rm -rf "${tmp}" ; return 0 ;
294
+ fi
295
+
296
+ local took=0 replaced=0 keep;
297
+ for entry in "${missing[@]}" ; do
298
+ ws="${entry%%/*}" ; file="${entry##*/}" ;
299
+ mkdir -p "${WORKSPACE_ROOT}/${ws}" ;
300
+ cp "${tmp}/${ws}/${file}" "${WORKSPACE_ROOT}/${ws}/${file}" ;
301
+ chmod +x "${WORKSPACE_ROOT}/${ws}/${file}" ;
302
+ echo " took ${entry}" ;
303
+ took=$((took+1)) ;
304
+ done
305
+
306
+ if [ "${overwrite}" == 'yes' ] ; then
307
+ for entry in "${differs[@]}" ; do
308
+ ws="${entry%%/*}" ; file="${entry##*/}" ;
309
+ keep="${backups}/${doc_name}/${ws}---${file}--$(date '+%Y-%m-%d_%H-%M-%S').bak";
310
+ mkdir -p "${backups}/${doc_name}" ;
311
+ cp -a "${WORKSPACE_ROOT}/${ws}/${file}" "${keep}" ;
312
+ cp "${tmp}/${ws}/${file}" "${WORKSPACE_ROOT}/${ws}/${file}" ;
313
+ chmod +x "${WORKSPACE_ROOT}/${ws}/${file}" ;
314
+ echo " replaced ${entry} (yours kept at ${keep})" ;
315
+ replaced=$((replaced+1)) ;
316
+ done
317
+ fi
318
+
319
+ rm -rf "${tmp}" ;
320
+ echo "";
321
+ echo " ${took} taken · ${replaced} replaced";
322
+ if [ "${overwrite}" != 'yes' ] && [ "${#differs[@]}" -gt 0 ] ; then
323
+ echo " ${#differs[@]} left alone because they differ — add --overwrite to replace them too.";
324
+ fi
325
+ }
326
+
327
+ # Retarget a command at a workspace: the settings file it reads and the folder
328
+ # name in its comments. A builder copied from dev to demos that still reads
329
+ # workspace.dev.settings.yml would build into the wrong folder, which is the one
330
+ # mistake a clone must not make.
331
+ function command_retarget_workspace() {
332
+ local file="$1" from="$2" to="$3";
333
+ [ "${from}" == "${to}" ] && return 0 ;
334
+ python3 - "${file}" "${from}" "${to}" <<'PYEOF'
335
+ import re, sys
336
+ path, old, new = sys.argv[1], sys.argv[2], sys.argv[3]
337
+ s = open(path).read()
338
+ s = s.replace(f'workspace.{old}.settings.yml', f'workspace.{new}.settings.yml')
339
+ # Folder mentions in comments and echoed paths, bounded so a longer name that
340
+ # merely starts with the old one is left alone.
341
+ s = re.sub(r'(?<![\w-])%s/' % re.escape(old), f'{new}/', s)
342
+ open(path, 'w').write(s)
343
+ PYEOF
344
+ }
345
+
346
+ # Copy a command under a new name, optionally into another workspace.
347
+ function commands_clone() {
348
+ local file="$1" new_name="$2" target="$3";
349
+
350
+ if [ -z "${file}" ] || [ "${file}" == '_none_' ] ; then
351
+ echo "Name the command to clone: --clone <cmd-file.sh> --to <new-cmd-file.sh>" ; return 1 ;
352
+ fi
353
+ if [ -z "${new_name}" ] || [ "${new_name}" == '_none_' ] ; then
354
+ echo "Give the copy a name: --to <new-cmd-file.sh>" ; return 1 ;
355
+ fi
356
+ if ! echo "${new_name}" | grep -qE '^cmd-[a-zA-Z0-9_.-]+\.sh$' ; then
357
+ echo "Invalid name '${new_name}': a command is cmd-<something>.sh." ; return 1 ;
358
+ fi
359
+
360
+ local source_ws;
361
+ source_ws=$(commands_locate "${file}") || { echo "No '${file}' in any workspace." ; return 1 ; }
362
+
363
+ # --workspace defaults to _all_ (it doubles as the --list filter), which for a
364
+ # clone means "leave it where it is", not a workspace called _all_.
365
+ local dest_ws="${source_ws}";
366
+ if [ -n "${target}" ] && [ ! "${target}" == '_none_' ] && [ ! "${target}" == '_all_' ] ; then
367
+ dest_ws="${target}" ;
368
+ [ -d "${WORKSPACE_ROOT}/${dest_ws}" ] || { echo "No such workspace: ${dest_ws}." ; return 1 ; }
369
+ [ -f "${WORKSPACE_CONFIG}/workspace.${dest_ws}.settings.yml" ] || {
370
+ echo "No workspace.${dest_ws}.settings.yml — ${dest_ws} is not a registered workspace." ; return 1 ; }
371
+ fi
372
+
373
+ local dest="${WORKSPACE_ROOT}/${dest_ws}/${new_name}";
374
+ [ -e "${dest}" ] && { echo "${dest_ws}/${new_name} already exists — pick another name." ; return 1 ; }
375
+
376
+ cp -a "${WORKSPACE_ROOT}/${source_ws}/${file}" "${dest}" ;
377
+ chmod +x "${dest}" ;
378
+ command_retarget_workspace "${dest}" "${source_ws}" "${dest_ws}" ;
379
+ echo "Cloned ${source_ws}/${file} to ${dest_ws}/${new_name}." ;
380
+ if [ ! "${source_ws}" == "${dest_ws}" ] ; then
381
+ echo " retargeted at workspace.${dest_ws}.settings.yml, and ${source_ws}/ paths repointed" ;
382
+ echo " Prose and echoed text naming '${source_ws}' are left alone — rewriting a bare" ;
383
+ echo " workspace name would corrupt ordinary words. Read the file before running it." ;
384
+ fi
385
+ echo " Set its '# workspace-name:' header to what it builds — the smoke test checks it." ;
386
+ CLONED_COMMAND="${dest}";
387
+ }
388
+
389
+ # Scaffold a new command with the bootstrap chain already correct.
390
+ function commands_new() {
391
+ local new_name="$1" target="$2" label="$3";
392
+
393
+ if ! echo "${new_name}" | grep -qE '^cmd-[a-zA-Z0-9_.-]+\.sh$' ; then
394
+ echo "Invalid name '${new_name}': a command is cmd-<something>.sh." ; return 1 ;
395
+ fi
396
+ if [ -z "${target}" ] || [ "${target}" == '_none_' ] ; then
397
+ echo "Say which workspace it belongs to: --workspace <name>" ; return 1 ;
398
+ fi
399
+ [ -f "${WORKSPACE_CONFIG}/workspace.${target}.settings.yml" ] || {
400
+ echo "No workspace.${target}.settings.yml — ${target} is not a registered workspace." ; return 1 ; }
401
+
402
+ local dest="${WORKSPACE_ROOT}/${target}/${new_name}";
403
+ [ -e "${dest}" ] && { echo "${target}/${new_name} already exists." ; return 1 ; }
404
+ mkdir -p "${WORKSPACE_ROOT}/${target}" ;
405
+
406
+ [ -z "${label}" ] || [ "${label}" == '_none_' ] && label="${new_name}";
407
+
408
+ cat > "${dest}" <<EOF
409
+ #!/usr/bin/env bash
410
+
411
+ # workspace-name: ${label}
412
+
413
+ # Bootstrap.
414
+ # Find the workspace tooling from this script, so a fresh clone needs no setup.
415
+ WORKSPACE_SCRIPTS="\${WORKSPACE_SCRIPTS:-\$(cd "\$(dirname "\${BASH_SOURCE[0]}")/../core/scripts" && pwd)}";
416
+ source \${WORKSPACE_SCRIPTS}/bootstrap.sh || exit 1 ;
417
+
418
+ # Load workspace settings and extra lists.
419
+ eval \$(parse_yaml \${WORKSPACE_CONFIG}/workspace.${target}.settings.yml);
420
+
421
+ ARGPARSE_DESCRIPTION="${label}"
422
+ argparse "\$@" <<ARGEOF || exit 1
423
+ parser.add_argument('PROJECT_NAME',
424
+ help='The name of the project.')
425
+ ARGEOF
426
+
427
+ shift \$#;
428
+
429
+ # What this command does goes here. DDEV only — ddev composer, ddev drush,
430
+ # ddev export-db — never raw composer/drush/mysql on the host.
431
+ echo "\${PROJECT_NAME} in ${target}: nothing implemented yet." ;
432
+ EOF
433
+ chmod +x "${dest}" ;
434
+ echo "Created ${target}/${new_name}." ;
435
+ echo " header: # workspace-name: ${label}" ;
436
+ echo " Edit it, then check it: bash core/scripts/tests/cmd-smoke-test.sh" ;
437
+ CREATED_COMMAND="${dest}";
438
+ }
439
+
440
+ # Hand a local command to the AI agent to file the issue and open the PR.
441
+ #
442
+ # Confirm-gated on purpose. Filing an issue and opening a pull request are
443
+ # public, and the house rule is that neither happens without being asked for
444
+ # explicitly — so this prints exactly what it would do and stops, and only
445
+ # --confirm lets it call the agent.
446
+ function commands_propose() {
447
+ local file="$1" summary="$2" confirmed="$3";
448
+
449
+ local ws;
450
+ ws=$(commands_locate "${file}") || { echo "No '${file}' in any workspace." ; return 1 ; }
451
+ local path="${WORKSPACE_ROOT}/${ws}/${file}";
452
+
453
+ # State whether this is new to the repository or a change to what is there —
454
+ # and say so honestly when the repository cannot be reached. Defaulting to
455
+ # "a change to" would assert something unverified, and in the dashboard
456
+ # container (no GH_TOKEN) that is the usual case.
457
+ local state="a change of unknown status against";
458
+ if commands_repo_sync > /dev/null 2>&1 ; then
459
+ local tmp;
460
+ if tmp=$(commands_repo_tree) ; then
461
+ if [ ! -f "${tmp}/${ws}/${file}" ]; then
462
+ state="new to";
463
+ elif cmp -s "${path}" "${tmp}/${ws}/${file}" ; then
464
+ echo "${ws}/${file} is identical to ${WORKSPACE_REPO}@${WORKSPACE_REPO_REF} — nothing to propose." ;
465
+ rm -rf "${tmp}" ; return 0 ;
466
+ else
467
+ state="a change to";
468
+ fi
469
+ rm -rf "${tmp}" ;
470
+ fi
471
+ fi
472
+ if [ "${state}" == 'a change of unknown status against' ] ; then
473
+ echo " (could not read ${WORKSPACE_REPO} to compare — the agent will work it out)" ;
474
+ fi
475
+
476
+ echo "*---------------------------------------------------------------------*";
477
+ echo " Propose ${ws}/${file} to ${WORKSPACE_REPO}";
478
+ echo "*---------------------------------------------------------------------*";
479
+ echo " file ${path}";
480
+ echo " status ${state} ${WORKSPACE_REPO}@${WORKSPACE_REPO_REF}";
481
+ echo " summary ${summary}";
482
+ echo "";
483
+ echo " The AI agent would: file an issue, push a branch to a fork, open a PR";
484
+ echo " against ${WORKSPACE_REPO_REF}, and leave the human-review boxes unticked.";
485
+ echo " It never merges, and it never pushes to ${WORKSPACE_REPO_REF} directly.";
486
+
487
+ if [ ! "${confirmed}" == 'yes' ] ; then
488
+ echo "";
489
+ echo " Nothing has been created. To go ahead, add --confirm:";
490
+ echo " bash cmd-tools-commands.sh --propose ${file} --summary \"…\" --confirm";
491
+ return 0 ;
492
+ fi
493
+
494
+ if ! command -v claude > /dev/null 2>&1 ; then
495
+ echo "" ;
496
+ echo " Claude Code CLI not found — cannot hand this over." ;
497
+ echo " install: https://claude.com/claude-code" ;
498
+ return 1 ;
499
+ fi
500
+
501
+ echo "";
502
+ echo " Handing it to the AI agent…";
503
+ local prompt;
504
+ prompt="Publish one workspace command to the ${WORKSPACE_REPO} repository, following the workspace's issue/PR rules.
505
+
506
+ File: ${path}
507
+ Belongs in: the ${ws}/ folder of the repository
508
+ Status: it is ${state} ${WORKSPACE_REPO}@${WORKSPACE_REPO_REF}
509
+ What it is for: ${summary}
510
+
511
+ Do this:
512
+ 1. Read the file, and read the repository's CLAUDE.md so the command matches how this tooling is written.
513
+ 2. File one issue on ${WORKSPACE_REPO} describing the command and why it is needed.
514
+ 3. Push a branch and open ONE pull request against ${WORKSPACE_REPO_REF} containing only this file, referencing the issue, ending with the Checkpoints checklist.
515
+ 4. Leave 'Reviewed by a human' and 'Code review by maintainers' unticked. Never merge. Never push to ${WORKSPACE_REPO_REF} directly.
516
+ 5. Report the issue URL and the pull request URL.
517
+
518
+ Only this one file. Do not include unrelated local changes.";
519
+
520
+ claude -p "${prompt}" --allowedTools Read Glob Grep Bash --disallowedTools Write Edit --no-session-persistence ;
521
+ }
@@ -0,0 +1,63 @@
1
+ #!/usr/bin/env bash
2
+
3
+ # Each DDEV project gets its own isolated database container, so there is no
4
+ # shared host database to drop between rebuilds -- deleting the DDEV project
5
+ # (containers + volumes) gives the same clean-slate guarantee.
6
+ #
7
+ # `ddev delete` only knows about projects DDEV still has in its registry. A project
8
+ # whose directory was removed by hand is gone from the registry while its docker
9
+ # volumes are still there, and `2>/dev/null || true` hid that. The next build then
10
+ # started against a volume provisioned by a DIFFERENT MariaDB version and DDEV
11
+ # refused to start at all:
12
+ #
13
+ # project website_starter10001 is configured for database mariadb:10.11, but its
14
+ # database volume holds mariadb:11.8
15
+ #
16
+ # So the volumes are removed by name as well. DDEV names them `<project>-mariadb`
17
+ # and `ddev-<project>-snapshots`.
18
+ function drop_database() {
19
+ echo "Removing any existing DDEV project for a clean rebuild";
20
+ ddev delete "${PROJECT_NAME}" -y -O 2>/dev/null || true ;
21
+
22
+ local volume ;
23
+ for volume in "${PROJECT_NAME}-mariadb" "${PROJECT_NAME}-postgres" "ddev-${PROJECT_NAME}-snapshots" ; do
24
+ if docker volume inspect "${volume}" > /dev/null 2>&1 ; then
25
+ docker volume rm -f "${volume}" > /dev/null 2>&1 \
26
+ && echo " removed the leftover ${volume} volume" \
27
+ || echo " could not remove ${volume} — a container may still hold it" ;
28
+ fi
29
+ done
30
+ }
31
+
32
+ # `ddev start` / `ddev restart`, with the one recovery a build actually needs.
33
+ #
34
+ # DDEV refuses to start when the project's configured database version does not
35
+ # match what its database volume already holds, and it is right to: migrating or
36
+ # discarding somebody's data is not a decision a tool should take on its own. In a
37
+ # BUILD that reasoning does not apply. drop_database has already deleted the
38
+ # project and its directory, so any surviving volume belongs to a build that no
39
+ # longer exists and there is nothing in it worth keeping.
40
+ #
41
+ # On that specific failure, and only that one, the volume is thrown away with
42
+ # `--reset-database --omit-snapshot`. Every other failure is passed straight
43
+ # through, because a build that cannot start for some other reason must fail loudly.
44
+ #
45
+ # Usage: ddev_up start -y / ddev_up restart
46
+ function ddev_up() {
47
+ local action="${1:-start}" ; shift || true ;
48
+ local output rc ;
49
+
50
+ output="$( ddev "${action}" "$@" 2>&1 )" ; rc=$? ;
51
+ printf '%s\n' "${output}" ;
52
+ [ ${rc} -eq 0 ] && return 0 ;
53
+
54
+ if printf '%s' "${output}" | grep -q 'database volume holds' ; then
55
+ echo "" ;
56
+ echo " The database volume was provisioned by a different MariaDB version." ;
57
+ echo " This is a fresh build, so the volume is discarded rather than migrated." ;
58
+ ddev start --reset-database --omit-snapshot ;
59
+ return $? ;
60
+ fi
61
+
62
+ return ${rc} ;
63
+ }