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