@webship.co/workspace 1.0.0-beta1 → 1.0.0-rc1
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} +9 -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/{plugins-page.js → core/workspace-app/plugins-page.js} +28 -2
- package/{server.js → core/workspace-app/server.js} +18 -0
- 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 +40 -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 +41 -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 +157 -0
- package/core/workspace-app/tests/step-definitions/clone-project.steps.js +47 -0
- package/core/workspace-app/tests/step-definitions/preconditions.steps.js +168 -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 +223 -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 +179 -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/preconditions.test.js +21 -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 +93 -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 +220 -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 +436 -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/package.json +38 -36
- /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-loader.js → core/workspace-app/plugin-loader.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/{row-layout.js → core/workspace-app/row-layout.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
- /package/{workspace-types.js → core/workspace-app/workspace-types.js} +0 -0
- /package/{workspaces.js → core/workspace-app/workspaces.js} +0 -0
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
Feature: The actions rail
|
|
2
|
+
The rail on the right of every page collapses to its icons and remembers the choice.
|
|
3
|
+
|
|
4
|
+
# This exists because the feature was broken by having TWO of it. A delegated handler near the
|
|
5
|
+
# top of ui.js toggled the class and wrote `actions-collapsed`; a second implementation at
|
|
6
|
+
# the bottom, from another line of work, bound its own listener to the same button, read the
|
|
7
|
+
# already-toggled class and toggled it straight back. Every click undid itself a millisecond
|
|
8
|
+
# later, so the rail simply did not move. Nothing in the suite noticed, because nothing asserted
|
|
9
|
+
# what a click DOES — only that the button was on the page.
|
|
10
|
+
#
|
|
11
|
+
# So these assert the state after the click, in both directions, and that it is remembered.
|
|
12
|
+
|
|
13
|
+
Scenario: The rail starts collapsed, because the page wants the width more than the labels do
|
|
14
|
+
Given I am on "/dev"
|
|
15
|
+
Then the element "#actions-rail" should be displayed
|
|
16
|
+
And the element ".actions-toggle" should be displayed
|
|
17
|
+
And the element "html" with the attribute "class" and the value containing "actions-collapsed" should exist
|
|
18
|
+
And the element ".actions-toggle" with the attribute "aria-expanded" and the value "false" should exist
|
|
19
|
+
|
|
20
|
+
Scenario: Clicking the toggle expands it
|
|
21
|
+
Given I am on "/dev"
|
|
22
|
+
When I click on the element ".actions-toggle"
|
|
23
|
+
Then the element "html" with the attribute "class" and the value containing "actions-collapsed" should not exist
|
|
24
|
+
And the element ".actions-toggle" with the attribute "aria-expanded" and the value "true" should exist
|
|
25
|
+
And I should see "All workspaces"
|
|
26
|
+
|
|
27
|
+
Scenario: Clicking it again collapses it — the click is not undone by a second handler
|
|
28
|
+
Given I am on "/dev"
|
|
29
|
+
When I click on the element ".actions-toggle"
|
|
30
|
+
And I click on the element ".actions-toggle"
|
|
31
|
+
Then the element "html" with the attribute "class" and the value containing "actions-collapsed" should exist
|
|
32
|
+
And the element ".actions-toggle" with the attribute "aria-expanded" and the value "false" should exist
|
|
33
|
+
|
|
34
|
+
# A layout preference that resets on every navigation is one you set on every page.
|
|
35
|
+
Scenario: The choice survives a navigation
|
|
36
|
+
Given I am on "/dev"
|
|
37
|
+
When I click on the element ".actions-toggle"
|
|
38
|
+
And I am on "/settings"
|
|
39
|
+
Then the element "html" with the attribute "class" and the value containing "actions-collapsed" should not exist
|
|
40
|
+
|
|
41
|
+
Scenario: The rail is on the settings page too, not only on a workspace page
|
|
42
|
+
Given I am on "/settings"
|
|
43
|
+
Then the element "#actions-rail" should be displayed
|
|
44
|
+
And the element ".actions-toggle" should be displayed
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
Feature: Installing agents, skills and prompts
|
|
2
|
+
|
|
3
|
+
Scenario: An item can be installed into the global Claude Code, or into one project
|
|
4
|
+
Given I am on "/ai-agents"
|
|
5
|
+
Then "select[name='toWorkspace']" should be attached
|
|
6
|
+
And "select[name='toProject']" should be attached
|
|
7
|
+
And "[hx-post='/actions/install-item']" should be attached
|
|
8
|
+
|
|
9
|
+
# htmx 4 fires after:swap on the element that MADE the request, not on the one
|
|
10
|
+
# swapped — so a listener reading e.target saw the button and never opened the
|
|
11
|
+
# modal. The content had loaded; nothing appeared.
|
|
12
|
+
Scenario: Editing a prompt opens the editor with its text in it
|
|
13
|
+
Given I am on "/ai-prompts"
|
|
14
|
+
When I click on the element "[hx-get^='/fragments/ai-prompts/edit/'] >> nth=0"
|
|
15
|
+
Then "#editor-modal.uk-open" should be visible
|
|
16
|
+
And "#editor-modal .ace_editor" should be visible
|
|
17
|
+
And "#editor-modal form[hx-post='/actions/save-item']" should be attached
|
|
18
|
+
|
|
19
|
+
Scenario: The same Edit works on the agents workspace
|
|
20
|
+
Given I am on "/ai-agents"
|
|
21
|
+
When I click on the element "[hx-get^='/fragments/ai-agents/edit/'] >> nth=0"
|
|
22
|
+
Then "#editor-modal.uk-open" should be visible
|
|
23
|
+
And "#editor-modal .ace_editor" should be visible
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
Feature: Talking to the assistant
|
|
2
|
+
The panel takes dictation and reads its answer back. Both are the browser's own — no key, no
|
|
3
|
+
service, nothing leaves the machine — so what is asserted here is that the component was actually
|
|
4
|
+
handed a working configuration, not that a remote service replied.
|
|
5
|
+
|
|
6
|
+
# Asserting the button EXISTS, not that speech works: a scenario cannot speak, and a browser will
|
|
7
|
+
# not grant a microphone to an automated run. What can go wrong without anyone noticing is the
|
|
8
|
+
# button being absent, or present with a config deep-chat silently ignored — so that is the target.
|
|
9
|
+
Scenario: The assistant offers a microphone
|
|
10
|
+
Given I am on "/"
|
|
11
|
+
Then "deep-chat" should be attached
|
|
12
|
+
And the assistant should offer voice input
|
|
13
|
+
And the assistant should read its replies aloud
|
|
14
|
+
|
|
15
|
+
# The microphone is what says voice is available. It used to be said in the placeholder as well
|
|
16
|
+
# ("Ask about dev… (or use voice)"), but the composer ships with no placeholder at all now: an
|
|
17
|
+
# empty field with a cursor in it already says "type here", and a prompt that suggests what to ask
|
|
18
|
+
# narrows what gets asked. So the button has to be there AND have a name — an icon-only control
|
|
19
|
+
# with no accessible name is a button a screen reader announces as nothing.
|
|
20
|
+
Scenario: The microphone is there, and it is named
|
|
21
|
+
Given I am on "/"
|
|
22
|
+
Then the assistant should show a named microphone button
|
|
23
|
+
|
|
24
|
+
# Nothing drawn in the box, and the box still has a name. These are one scenario because they are
|
|
25
|
+
# in tension: deep-chat resolves the placeholder as `text || "Ask me anything!"`, so an empty
|
|
26
|
+
# string does not remove its placeholder, it restores deep-chat's — and the text it is given also
|
|
27
|
+
# becomes the composer's aria-label. Removing what is drawn without removing the name is the whole
|
|
28
|
+
# trick, and either half alone is a bug.
|
|
29
|
+
Scenario: The composer shows no placeholder, and is still named
|
|
30
|
+
Given I am on "/"
|
|
31
|
+
Then the assistant composer should draw no placeholder
|
|
32
|
+
And the assistant composer should have an accessible name
|
|
33
|
+
|
|
34
|
+
# The recogniser's language is the setting that decides whether dictation works in a second
|
|
35
|
+
# language at all: left on the wrong one it does not fail, it returns confident nonsense. So a
|
|
36
|
+
# language is always pinned rather than inherited — en-US ships, and the dropdown offers the rest.
|
|
37
|
+
Scenario: A dictation language is always pinned, never left to chance
|
|
38
|
+
Given I am on "/"
|
|
39
|
+
Then the assistant speech language should be pinned
|
|
40
|
+
|
|
41
|
+
# An empty phrase is not a disabled command. If `commands` were built from blank strings, a
|
|
42
|
+
# command could fire on almost anything dictated — so with none configured the key must be absent.
|
|
43
|
+
Scenario: No voice commands are armed unless one is configured
|
|
44
|
+
Given I am on "/"
|
|
45
|
+
Then the assistant should have no voice commands
|
|
46
|
+
|
|
47
|
+
Scenario: Voice styling follows the theme rather than deep-chat's stock colours
|
|
48
|
+
Given I am on "/"
|
|
49
|
+
Then the assistant speech colours should be design tokens
|
|
50
|
+
|
|
51
|
+
# The panel is on every workspace page, not only the home page, and its context travels with it.
|
|
52
|
+
Scenario: A workspace page gets the same microphone
|
|
53
|
+
Given I am on "/dev"
|
|
54
|
+
Then "deep-chat" should be attached
|
|
55
|
+
And the assistant should offer voice input
|
|
56
|
+
|
|
57
|
+
# A browser with no synthesis voices accepts speak(), fires error: synthesis-failed, and is silent.
|
|
58
|
+
# Nothing reported it, so "read replies aloud" looked switched on and did nothing at all — the worst
|
|
59
|
+
# state a setting can be in.
|
|
60
|
+
Scenario: The settings file editor says which voices this browser actually has
|
|
61
|
+
Given I am on "/settings/settings.yml"
|
|
62
|
+
Then "[data-voice-name]" should be attached
|
|
63
|
+
And the voice list should report what this browser has
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
Feature: The checks a project already declares
|
|
2
|
+
Every package here carries its own quality scripts. The dashboard offers them without inventing any.
|
|
3
|
+
|
|
4
|
+
# One quality menu, not two. On a packages workspace there is no browser suite at all, and on a
|
|
5
|
+
# site there was no checks control — a separate button would have been the only one present in
|
|
6
|
+
# each case. They live together under Tests, with the checks nested inside it.
|
|
7
|
+
Scenario: A package row offers its checks inside the Tests menu
|
|
8
|
+
Given I am on "/products"
|
|
9
|
+
Then the element ".project-row .act-menu-tests" should be displayed
|
|
10
|
+
And ".act-menu-tests .act-menu-checks" should be attached
|
|
11
|
+
And I should see "Tests"
|
|
12
|
+
|
|
13
|
+
Scenario: The button says what the package covers without running anything
|
|
14
|
+
Given I am on "/products"
|
|
15
|
+
Then the element ".act-menu-tests + .act-status" should be displayed
|
|
16
|
+
And "[hx-post='/actions/checks-plan']" should be attached
|
|
17
|
+
|
|
18
|
+
# The pair is the point: the canonical name is what you type (--only js), the code beside it is
|
|
19
|
+
# the script the package itself declared. Listing them together is how the mapping is checkable.
|
|
20
|
+
Scenario: The nested menu lists each alias against the script it runs
|
|
21
|
+
Given I am on "/products"
|
|
22
|
+
Then ".checks-sub" should be attached
|
|
23
|
+
And ".checks-sub .checks-alias" should be attached
|
|
24
|
+
And ".checks-sub .checks-script" should be attached
|
|
25
|
+
|
|
26
|
+
@needs-check-aliases
|
|
27
|
+
Scenario: Each alias can be run on its own, and so can all of them
|
|
28
|
+
Given I am on "/products"
|
|
29
|
+
Then "[hx-post='/actions/checks']" should be attached
|
|
30
|
+
And "[hx-vals*='only']" should be attached
|
|
31
|
+
|
|
32
|
+
# A site gets the same nested list: its package.json declares the same vocabulary, and its
|
|
33
|
+
# ddev-dev-tools add-on adds the PHP and Twig checks on top.
|
|
34
|
+
@needs-testing-stack
|
|
35
|
+
Scenario: A site keeps its testing verbs and gains the checks beside them
|
|
36
|
+
Given I am on "/dev"
|
|
37
|
+
Then the element ".project-row .act-menu-tests" should be displayed
|
|
38
|
+
And "[hx-post='/actions/testing-configure']" should be attached
|
|
39
|
+
And "[hx-post='/actions/testing-run']" should be attached
|
|
40
|
+
And ".act-menu-tests .act-menu-checks" should be attached
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
Feature: Cloning a project
|
|
2
|
+
The clone modal validates before anything runs, and never clones over an
|
|
3
|
+
existing project or a name DDEV already tracks.
|
|
4
|
+
|
|
5
|
+
Scenario: The DDEV menu offers the clone
|
|
6
|
+
Given I am on "/dev"
|
|
7
|
+
Then "[hx-get^='/fragments/projects/clone-form/dev/']" should be attached
|
|
8
|
+
|
|
9
|
+
Scenario: The form arrives prefilled, with the live check wired
|
|
10
|
+
When I open the clone form of the first project in "dev"
|
|
11
|
+
Then the clone form proposes a copy of that project
|
|
12
|
+
And "select[name='toWorkspace']" should be attached
|
|
13
|
+
And "[hx-get='/fragments/projects/clone-check']" should be attached
|
|
14
|
+
And "textarea[name='prompt']" should be attached
|
|
15
|
+
|
|
16
|
+
Scenario: The live check refuses an existing project
|
|
17
|
+
When I ask the live check about the name of the first project in "dev"
|
|
18
|
+
Then I should see "already exists"
|
|
19
|
+
|
|
20
|
+
Scenario: The live check blesses a free name
|
|
21
|
+
Given I am on "/fragments/projects/clone-check?to=surely-free-name-zz&toWorkspace=dev"
|
|
22
|
+
Then I should see "is free"
|
|
23
|
+
|
|
24
|
+
Scenario: Cloning over an existing project is refused server-side too
|
|
25
|
+
When I post a clone of the first project in "dev" over itself
|
|
26
|
+
Then the action response should contain "already exists"
|
|
27
|
+
|
|
28
|
+
Scenario: A source that does not exist is refused
|
|
29
|
+
When I post "/actions/clone-project" with '{"workspace":"dev","projectName":"no-such-src","to":"whatever-zz","toWorkspace":"dev"}'
|
|
30
|
+
Then the action response should contain "Project not found"
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
Feature: Writing and changing the workspace commands
|
|
2
|
+
A cmd-*.sh is executed by the dashboard and by a terminal, so nothing changes one unreviewed.
|
|
3
|
+
|
|
4
|
+
Scenario: A new command can be given a purpose, not just a name
|
|
5
|
+
Given I am on "/settings/commands"
|
|
6
|
+
Then I should see "New command"
|
|
7
|
+
|
|
8
|
+
# The scaffold alone is a correct command that does nothing. Saying what it is FOR is what makes it
|
|
9
|
+
# a command for that thing — the assistant reads the workspace's own conventions and writes it.
|
|
10
|
+
Scenario: The new-command form asks what the command should do
|
|
11
|
+
Given I am on "/fragments/commands/new"
|
|
12
|
+
Then "textarea[name='purpose']" should be attached
|
|
13
|
+
And "input[name='newName']" should be attached
|
|
14
|
+
And "select[name='target']" should be attached
|
|
15
|
+
|
|
16
|
+
Scenario: The editor offers the assistant a change to make
|
|
17
|
+
Given I am on "/fragments/commands/edit/dev/cmd-tools-checks.sh"
|
|
18
|
+
Then "textarea[name='instruction']" should be attached
|
|
19
|
+
And ".cmd-ai-row .field-mic" should be attached
|
|
20
|
+
And "[hx-post='/actions/command-ai']" should be attached
|
|
21
|
+
And I should see "Ask"
|
|
22
|
+
|
|
23
|
+
# The command is still what gets saved by hand: the assistant is an extra way in, not the only one.
|
|
24
|
+
Scenario: The editor still edits the command directly
|
|
25
|
+
Given I am on "/fragments/commands/edit/dev/cmd-tools-checks.sh"
|
|
26
|
+
Then "textarea[name='content']" should be attached
|
|
27
|
+
And "[hx-post='/actions/command-save']" should be attached
|
|
28
|
+
And I should see "bash -n"
|
|
29
|
+
|
|
30
|
+
# 239 commands is too many to scroll. Searching matches the file name, the human name AND the
|
|
31
|
+
# description, because "reclaim" and "back up" are what somebody types and neither is a file name.
|
|
32
|
+
# A file name is a string you are about to type. In the body font it reads as prose and loses its
|
|
33
|
+
# word boundaries, and cmd-tool-backup-product.sh has a lot of boundaries.
|
|
34
|
+
Scenario: File names are shown as code wherever they appear
|
|
35
|
+
Given I am on "/fragments/commands/edit/dev/cmd-tools-checks.sh"
|
|
36
|
+
Then "h3 code.fname" should be attached
|
|
37
|
+
And "p code.fname" should be attached
|
|
38
|
+
|
|
39
|
+
Scenario: Commands can be searched and narrowed to one workspace folder
|
|
40
|
+
Given I am on "/commands"
|
|
41
|
+
Then "input[name='q']" should be attached
|
|
42
|
+
And "select[name='source']" should be attached
|
|
43
|
+
And ".cmd-title" should be attached
|
|
44
|
+
And ".cmd-file" should be attached
|
|
45
|
+
|
|
46
|
+
# Every list in the app 500d the moment `auto` reached the query, which is the first click of the
|
|
47
|
+
# auto-search checkbox: lists.js called hubDomain() without importing it.
|
|
48
|
+
Scenario: A list survives the auto-search preference being sent
|
|
49
|
+
Given I am on "/fragments/commands/list?q=backup&ws=all&auto=0&page=1"
|
|
50
|
+
Then ".cmd-title" should be attached
|
|
51
|
+
|
|
52
|
+
# Six action buttons and a full sentence on the same line squeezed each other into two-word
|
|
53
|
+
# columns. What a command is reads first; what you can do to it follows underneath.
|
|
54
|
+
Scenario: A command row reads top to bottom, with its actions on their own line
|
|
55
|
+
Given I am on "/settings/commands"
|
|
56
|
+
Then ".cmd-row-stack" should be attached
|
|
57
|
+
And ".cmd-row-stack .cmd-id" should be attached
|
|
58
|
+
And ".cmd-row-stack .project-actions" should be attached
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
Feature: The workspace dashboard
|
|
2
|
+
The pages a person opens every day, asserted against the running site.
|
|
3
|
+
|
|
4
|
+
Scenario: The hub lists the workspaces
|
|
5
|
+
Given I am on "/"
|
|
6
|
+
Then the element "#workspace-cards" should be displayed
|
|
7
|
+
And the element ".ws-card-wrap" should be displayed
|
|
8
|
+
And I should see "Products"
|
|
9
|
+
And I should see "Dev"
|
|
10
|
+
And I should see "RAG"
|
|
11
|
+
|
|
12
|
+
Scenario: A card carries the handle that reorders it
|
|
13
|
+
Given I am on "/"
|
|
14
|
+
Then the element ".ws-card-handle" should be displayed
|
|
15
|
+
And the element "#workspace-cards" with the attribute "data-sortable" and the value containing "ws-card-wrap" should exist
|
|
16
|
+
|
|
17
|
+
Scenario: A workspace page offers its builder and its projects
|
|
18
|
+
Given I am on "/dev"
|
|
19
|
+
Then I should see "Build a new project"
|
|
20
|
+
And the element ".project-row" should be displayed
|
|
21
|
+
And the element "select" should be displayed
|
|
22
|
+
|
|
23
|
+
Scenario: The settings file editor is reachable and shows the style block
|
|
24
|
+
Given I am on "/settings/settings.yml"
|
|
25
|
+
Then I should see "Workspace name"
|
|
26
|
+
And I should see "theme"
|
|
27
|
+
|
|
28
|
+
Scenario: The assistant panel is on the page it belongs to
|
|
29
|
+
Given I am on "/"
|
|
30
|
+
Then I should see "AI Assistant"
|
|
31
|
+
|
|
32
|
+
# It is ONE assistant, whose conversation follows you between workspaces — the thread id is a
|
|
33
|
+
# cookie on the hub domain for exactly that reason. The panel used to prefix the workspace it was
|
|
34
|
+
# scoped to ("Dev AI Assistant"), which read as a different assistant on every page. The scope is
|
|
35
|
+
# still shown, where it belongs: in the command picker, which carries that workspace's commands.
|
|
36
|
+
Scenario: The assistant is called the same thing on a workspace page
|
|
37
|
+
Given I am on "/dev"
|
|
38
|
+
Then I should see "AI Assistant"
|
|
39
|
+
And I should not see "Dev AI Assistant"
|
|
40
|
+
And I should see "the agent decides (Dev)"
|
|
41
|
+
|
|
42
|
+
# What it is called is configuration: `assistant: name:` in settings.yml for the dashboard, and in
|
|
43
|
+
# a workspace's own file for that workspace's page. Shipped, both say AI Assistant.
|
|
44
|
+
Scenario: Its name comes from the settings file, where anyone can change it
|
|
45
|
+
Given I am on "/settings/settings.yml"
|
|
46
|
+
Then I should see "What the assistant is called"
|
|
47
|
+
And I should see "What the box says when it is empty"
|
|
48
|
+
|
|
49
|
+
Scenario: A workspace with no projects still renders its page
|
|
50
|
+
Given I am on "/projects"
|
|
51
|
+
Then I should see "Projects"
|
|
52
|
+
And "#webship-workspace-projects" should be attached
|
|
53
|
+
|
|
54
|
+
Scenario: The assistant is a deep-chat component with its own input
|
|
55
|
+
Given I am on "/"
|
|
56
|
+
Then "#ws-deep-chat" should be attached
|
|
57
|
+
And "deep-chat" should be attached
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
Feature: The menus on a project row
|
|
2
|
+
Every project row carries its state above the name and its verbs in menus.
|
|
3
|
+
|
|
4
|
+
Scenario: State is a line above the folder name, not a word after it
|
|
5
|
+
Given I am on "/dev"
|
|
6
|
+
Then ".project-row .pcard-state-line" should be attached
|
|
7
|
+
And ".project-row .pcard-head" should be attached
|
|
8
|
+
|
|
9
|
+
# The Graph menu is the graph plugin's, asserted by its own feature.
|
|
10
|
+
Scenario: The row offers the DDEV and Tests menus
|
|
11
|
+
Given I am on "/dev"
|
|
12
|
+
Then ".project-row .act-menu-ddev" should be attached
|
|
13
|
+
And ".project-row .act-menu-tests" should be attached
|
|
14
|
+
And ".project-row .act-menu-more" should be attached
|
|
15
|
+
|
|
16
|
+
Scenario: A menu that carries a state word captions it under the button
|
|
17
|
+
Given I am on "/dev"
|
|
18
|
+
Then the element ".act-with-status" should be displayed
|
|
19
|
+
And the element ".act-with-status .act-status" should be displayed
|
|
20
|
+
|
|
21
|
+
# Opened on /rag rather than /dev: the rag workspace holds exactly one instance, so a click by
|
|
22
|
+
# selector is unambiguous. On a page of twelve rows every selector matches twelve buttons, and a
|
|
23
|
+
# test that has to say "the third one" is a test that breaks when a project is built.
|
|
24
|
+
Scenario: The DDEV menu opens and holds the verbs that moved into it
|
|
25
|
+
Given I am on "/dev"
|
|
26
|
+
And I click on the element ".project-row >> nth=0 >> .act-menu-ddev button"
|
|
27
|
+
Then ".uk-dropdown.uk-open" should be visible
|
|
28
|
+
And I should see "Restart"
|
|
29
|
+
And I should see "Describe (URLs, services)"
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
Feature: The Jira plugin on the project rows
|
|
2
|
+
A sites workspace project row offers its Jira surface, and the actions hold
|
|
3
|
+
their guards without ever needing Jira to answer.
|
|
4
|
+
|
|
5
|
+
# The menu is gated on twg + settings; in this environment both hold, so the
|
|
6
|
+
# rows carry the menu and the modal link.
|
|
7
|
+
Scenario: The JIRA menu is on the project rows
|
|
8
|
+
Given I am on "/dev"
|
|
9
|
+
Then "[hx-get^='/fragments/p/jira/list/dev/']" should be attached
|
|
10
|
+
|
|
11
|
+
# The guards answer without Jira: a malformed key never reaches twg.
|
|
12
|
+
Scenario: A malformed key is refused at the door
|
|
13
|
+
When I post "/actions/p/jira/task" with '{"workspace":"dev","projectName":"v11x00b1i18n","key":"not-a-key","mode":"view"}'
|
|
14
|
+
Then the action response should contain "Not a Jira key"
|
|
15
|
+
|
|
16
|
+
@needs-jira-writes-off
|
|
17
|
+
Scenario: Write modes are refused while Jira writes are off
|
|
18
|
+
When I post "/actions/p/jira/task" with '{"workspace":"dev","projectName":"v11x00b1i18n","key":"WEBSHIP-1","mode":"comment"}'
|
|
19
|
+
Then the action response should contain "Writing to Jira is off"
|
|
20
|
+
|
|
21
|
+
Scenario: An unknown project cannot host an agent
|
|
22
|
+
When I post "/actions/p/jira/task" with '{"workspace":"dev","projectName":"no-such-project","key":"WEBSHIP-1","mode":"view"}'
|
|
23
|
+
Then the action response should contain "Project not found"
|
|
24
|
+
|
|
25
|
+
Scenario: Watching a task nobody worked on says so
|
|
26
|
+
When I post "/actions/p/jira/task" with '{"workspace":"dev","projectName":"v11x00b1i18n","key":"WEBSHIP-424242","mode":"watch"}'
|
|
27
|
+
Then the action response should contain "No agent log"
|
|
28
|
+
|
|
29
|
+
Scenario: The Screens modal lists sessions or says there are none
|
|
30
|
+
Given I am on "/fragments/screens"
|
|
31
|
+
Then I should see "Screen sessions"
|
|
32
|
+
|
|
33
|
+
Scenario: Stopping a screen needs confirmation
|
|
34
|
+
When I post "/actions/screen-stop" with '{"session":"whatever-zz"}'
|
|
35
|
+
Then the action response should contain "requires confirmation"
|
|
36
|
+
|
|
37
|
+
Scenario: A hostile session name is refused
|
|
38
|
+
When I post "/actions/screen-stop" with '{"session":"x; rm -rf /","confirm":"yes"}'
|
|
39
|
+
Then the action response should contain "Not a screen session name"
|
|
40
|
+
|
|
41
|
+
Scenario: Remembering a Jira project refuses a bad key
|
|
42
|
+
When I post "/actions/jira-set-project" with '{"workspace":"dev","projectName":"v11x00b1i18n","key":"bad-key-1"}'
|
|
43
|
+
Then the action response should contain "Not a Jira project key"
|
|
44
|
+
|
|
45
|
+
Scenario: Remembering needs a real project
|
|
46
|
+
When I post "/actions/jira-set-project" with '{"workspace":"dev","projectName":"no-such","key":"WEBSHIP"}'
|
|
47
|
+
Then the action response should contain "Project not found"
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
Feature: Settings → Plugins
|
|
2
|
+
Optional features are packages, turned on in four steps; the page shows every package the
|
|
3
|
+
dashboard can see and the step each is at.
|
|
4
|
+
|
|
5
|
+
Scenario: The Plugins page lists the packages with their steps
|
|
6
|
+
Given I am on "/settings/plugins"
|
|
7
|
+
Then I should see "Plugins"
|
|
8
|
+
And the element ".plugin-card" should be displayed
|
|
9
|
+
And the element ".plugin-steps" should be displayed
|
|
10
|
+
And I should see "required"
|
|
11
|
+
And I should see "configured"
|
|
12
|
+
|
|
13
|
+
Scenario: A package can be required from the page
|
|
14
|
+
Given I am on "/settings/plugins"
|
|
15
|
+
Then the element ".plugin-require input[name=spec]" should be displayed
|
|
16
|
+
And I should see "Require"
|
|
17
|
+
|
|
18
|
+
Scenario: Settings offers Plugins among the dashboard's own sections
|
|
19
|
+
Given I am on "/settings"
|
|
20
|
+
Then I should see "Plugins"
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
Feature: What a project row can actually do
|
|
2
|
+
The verbs on a row, asserted where they are rather than by opening every menu.
|
|
3
|
+
|
|
4
|
+
# Each menu carries the name of the verb it opens (act-menu-ddev, act-menu-tests, …). A page of
|
|
5
|
+
# thirteen projects has thirteen of each, so these assert that the control and its items EXIST
|
|
6
|
+
# rather than clicking one — a test that has to say "the third one" breaks the moment a project
|
|
7
|
+
# is built. The one click test lives on /rag, which holds exactly one row.
|
|
8
|
+
|
|
9
|
+
Scenario: A row carries a menu for each thing it can do
|
|
10
|
+
Given I am on "/dev"
|
|
11
|
+
Then the element ".project-row .act-menu-ddev" should be displayed
|
|
12
|
+
And the element ".project-row .act-menu-tests" should be displayed
|
|
13
|
+
And the element ".project-row .act-menu-graph" should be displayed
|
|
14
|
+
And the element ".project-row .act-menu-more" should be displayed
|
|
15
|
+
|
|
16
|
+
# These two are the whole testing feature as far as the interface is concerned: one sets the
|
|
17
|
+
# environment up, the other runs the suite. Both post to their own action.
|
|
18
|
+
@needs-testing-stack
|
|
19
|
+
Scenario: The Tests menu offers setting the environment up and running the suite
|
|
20
|
+
Given I am on "/dev"
|
|
21
|
+
Then "[hx-post='/actions/testing-configure']" should be attached
|
|
22
|
+
And "[hx-post='/actions/testing-run']" should be attached
|
|
23
|
+
|
|
24
|
+
# The state under the button is the answer to "is there anything to look at yet" — it says
|
|
25
|
+
# webship, webship-js or none, and it is a caption under the control rather than a word inside it.
|
|
26
|
+
Scenario: A menu that carries a state word captions it under the button
|
|
27
|
+
Given I am on "/dev"
|
|
28
|
+
Then the element ".act-with-status .act-status" should be displayed
|
|
29
|
+
|
|
30
|
+
Scenario: The DDEV menu opens and holds the verbs that moved into it
|
|
31
|
+
Given I am on "/rag"
|
|
32
|
+
When I click on the element ".project-row .act-menu-ddev button"
|
|
33
|
+
Then ".uk-dropdown.uk-open" should be visible
|
|
34
|
+
And I should see "Restart"
|
|
35
|
+
And I should see "Describe (URLs, services)"
|
|
36
|
+
|
|
37
|
+
# Launch belongs with the hostname it opens, not in the row of things you DO to a project.
|
|
38
|
+
@needs-running-project
|
|
39
|
+
Scenario: A running project shows its own host on its card
|
|
40
|
+
Given I am on "/dev"
|
|
41
|
+
Then ".project-row .pcard-host-name" should be attached
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
Feature: The Screens manager
|
|
2
|
+
Screen sessions are where long work lives — Jira agents, builds, anything
|
|
3
|
+
started with cmd-tools-screen.sh. The page must list them, refuse what would
|
|
4
|
+
reach a shell, and never let another site drive it.
|
|
5
|
+
|
|
6
|
+
Scenario: Screens is its own page, not a settings tab
|
|
7
|
+
Given I am on "/screens"
|
|
8
|
+
Then I should see "New screen"
|
|
9
|
+
And I should see "Remove ended sessions"
|
|
10
|
+
|
|
11
|
+
Scenario: The old settings URL still lands on the manager
|
|
12
|
+
Given I am on "/settings/screens"
|
|
13
|
+
Then I should see "New screen"
|
|
14
|
+
|
|
15
|
+
Scenario: A new session needs a place that the server offered
|
|
16
|
+
When I post "/actions/screen-new" with '{"session":"zz-nope","target":"/etc"}'
|
|
17
|
+
Then the action response should contain "Unknown place"
|
|
18
|
+
|
|
19
|
+
Scenario: A session name that screen would read as an option is refused
|
|
20
|
+
When I post "/actions/screen-new" with '{"session":"-S","target":"root"}'
|
|
21
|
+
Then the action response should contain "session name"
|
|
22
|
+
|
|
23
|
+
Scenario: Killing a session is refused without confirmation
|
|
24
|
+
When I post "/actions/screen-stop" with '{"session":"whatever-zz"}'
|
|
25
|
+
Then the action response should contain "requires confirmation"
|
|
26
|
+
|
|
27
|
+
Scenario: A hostile session name never reaches screen
|
|
28
|
+
When I post "/actions/screen-interrupt" with '{"session":"x; rm -rf /"}'
|
|
29
|
+
Then the action response should contain "Not a screen session name"
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
Feature: The settings editor
|
|
2
|
+
The one page that holds real credentials, so what it does NOT show matters as much as what it does.
|
|
3
|
+
|
|
4
|
+
Scenario: The editor lists the settings files and edits one at a time
|
|
5
|
+
Given I am on "/settings/settings.yml"
|
|
6
|
+
Then the element ".settings-tabs" should be displayed
|
|
7
|
+
And I should see "settings.yml"
|
|
8
|
+
And I should see "Workspace name"
|
|
9
|
+
|
|
10
|
+
# A secret's value never reaches the browser: the field renders empty with a note saying a blank
|
|
11
|
+
# submission keeps what is on disk. This asserts the mechanism rather than the absence of one
|
|
12
|
+
# particular string, which would pass on a page that simply failed to render.
|
|
13
|
+
# The note lives in the field's placeholder, not in the page text: it belongs to the box you are
|
|
14
|
+
# about to type in, and as body copy it would repeat itself once per secret on the page.
|
|
15
|
+
Scenario: A secret is offered as a field to replace, never as a value to read
|
|
16
|
+
Given I am on "/settings/settings.yml"
|
|
17
|
+
Then the element "input[type='password']" should be displayed
|
|
18
|
+
And the element "input[type='password']" with the attribute "placeholder" and the value containing "leave blank to keep" should exist
|
|
19
|
+
And the element "input[type='password']" with the attribute "value" and the value containing "-" should not exist
|
|
20
|
+
|
|
21
|
+
# account.pass is deliberately NOT a secret: it is the admin password a fresh local install is
|
|
22
|
+
# given, and masking it made the field useless for the one thing it is for.
|
|
23
|
+
Scenario: The local admin password stays readable, because that is what it is for
|
|
24
|
+
Given I am on "/settings/settings.yml"
|
|
25
|
+
Then I should see "pass"
|
|
26
|
+
And I should see "That admin password"
|
|
27
|
+
|
|
28
|
+
Scenario: A workspace has its own settings file with its card presentation in it
|
|
29
|
+
Given I am on "/settings/workspace.rag.settings.yml"
|
|
30
|
+
Then I should see "presentation"
|
|
31
|
+
And the element "#ws-presentation" should be displayed
|
|
32
|
+
|
|
33
|
+
# The icon chooser writes only the two fields it owns. The rest of the block — label, noun, kind,
|
|
34
|
+
# also_files — has to still be there afterwards, which is what the unit tests assert; here we
|
|
35
|
+
# assert the chooser is what the page offers rather than a free-text field.
|
|
36
|
+
Scenario: The icon is chosen from the icons that will actually render
|
|
37
|
+
Given I am on "/settings/workspace.rag.settings.yml"
|
|
38
|
+
Then the element ".icon-filter" should be displayed
|
|
39
|
+
And the element ".icon-grid" should be displayed
|
|
40
|
+
|
|
41
|
+
Scenario: The settings hub groups what can be configured and leads to the files
|
|
42
|
+
Given I am on "/settings"
|
|
43
|
+
Then I should see "The dashboard"
|
|
44
|
+
And I should see "Workspace settings"
|
|
45
|
+
And I should see "Styles"
|
|
46
|
+
And "a[href='/settings/settings.yml']" should be attached
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
Feature: The report a test run leaves behind
|
|
2
|
+
A finished run is readable in the dashboard and downloadable as a document.
|
|
3
|
+
|
|
4
|
+
# The report opens in a modal from the Tests menu, so the row links to the FRAGMENT that renders
|
|
5
|
+
# it. Asserted on the fragment itself rather than by opening thirteen menus to find one.
|
|
6
|
+
@needs-test-report
|
|
7
|
+
Scenario: The Tests menu links to the report of a project that has been tested
|
|
8
|
+
Given I am on "/dev"
|
|
9
|
+
Then "[hx-get^='/fragments/dev/test-report/']" should be attached
|
|
10
|
+
|
|
11
|
+
@needs-test-report
|
|
12
|
+
Scenario: The report offers itself as a PDF, for people who were not at the run
|
|
13
|
+
Given I am on "/fragments/dev/test-report/amd-website_starter-1-0-x-site-template-manager"
|
|
14
|
+
Then I should see "Download as PDF"
|
|
15
|
+
And "[href^='/report-pdf/dev/']" should be attached
|
|
16
|
+
|
|
17
|
+
# Not navigated to: the route answers with Content-Disposition: attachment, which a browser
|
|
18
|
+
# downloads rather than renders — so the PDF itself is asserted by the unit tests, which check
|
|
19
|
+
# the document it builds. This checks the interface offers it.
|
|
20
|
+
@needs-test-report
|
|
21
|
+
Scenario: The report leads with the counts, not with a list to scroll
|
|
22
|
+
Given I am on "/fragments/dev/test-report/amd-website_starter-1-0-x-site-template-manager"
|
|
23
|
+
Then I should see "passed"
|
|
24
|
+
And I should see "failed"
|
|
25
|
+
And I should see "scenarios"
|
|
26
|
+
And the element ".uk-label-success" should be displayed
|
|
27
|
+
And the element ".uk-label-danger" should be displayed
|
|
28
|
+
|
|
29
|
+
@needs-test-report
|
|
30
|
+
Scenario: The HTML report is reachable from it as well
|
|
31
|
+
Given I am on "/fragments/dev/test-report/amd-website_starter-1-0-x-site-template-manager"
|
|
32
|
+
Then I should see "Open the HTML report"
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
Feature: The theme system
|
|
2
|
+
One stylesheet is assembled from a base, the components, and the palette last.
|
|
3
|
+
|
|
4
|
+
Scenario: The page asks for the assembled stylesheet, not a file on disk
|
|
5
|
+
Given I am on "/"
|
|
6
|
+
Then "link[href*='/style.css?v=']" should be attached
|
|
7
|
+
|
|
8
|
+
# Which style is last is a per-machine setting, so naming one here asserted the machine rather
|
|
9
|
+
# than the code: the scenario failed on any machine not wearing `default`, which since the Styles
|
|
10
|
+
# page is most of them. What the assembly guarantees is the ORDER — base, components, then a
|
|
11
|
+
# style — so that is what is asserted.
|
|
12
|
+
Scenario: The assembled sheet carries the base, the components and a style
|
|
13
|
+
Given I am on "/style.css"
|
|
14
|
+
Then I should see "/* base */"
|
|
15
|
+
And I should see "/* component: workspace-cards */"
|
|
16
|
+
And I should see "/* component: project-rows */"
|
|
17
|
+
And I should see "/* theme:"
|
|
18
|
+
|
|
19
|
+
# Every style names itself and declares the palette tokens, whichever one is worn.
|
|
20
|
+
Scenario: The style in use names itself and declares its palette
|
|
21
|
+
Given I am on "/style.css"
|
|
22
|
+
Then I should see "@name"
|
|
23
|
+
And I should see "--brand-primary:"
|
|
24
|
+
|
|
25
|
+
# Not a button: the only primary button on the home page used to be the assistant's Send, and
|
|
26
|
+
# deep-chat renders its own inside a shadow root where a selector cannot reach it. The card chips
|
|
27
|
+
# carry the brand colour on every page, which is what this scenario is actually about.
|
|
28
|
+
Scenario: The dashboard still renders with its own brand colour
|
|
29
|
+
Given I am on "/"
|
|
30
|
+
Then the element "#workspace-cards" should be displayed
|
|
31
|
+
And the element ".ws-card-wrap .uk-label" should be displayed
|
|
32
|
+
|
|
33
|
+
# The favicon is the artwork from the brand tokens (node 5743:11748): a square with the emblem
|
|
34
|
+
# SUBTRACTED out of it, one boolean path. Its fill flips with the viewer's colour scheme, because a
|
|
35
|
+
# knocked-out mark has no colour of its own — asserted on the file in tests/unit/favicon.test.js,
|
|
36
|
+
# since a browser handed an SVG renders it as an image and there is nothing here to select.
|
|
37
|
+
Scenario: The tab carries the Webship favicon, not a bare emblem
|
|
38
|
+
Given I am on "/"
|
|
39
|
+
Then "link[rel='alternate icon'][href$='.png']" should be attached
|
|
40
|
+
And "link[rel='apple-touch-icon'][href$='.png']" should be attached
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Steps that exercise an action's GUARDS over the wire, without a browser round
|
|
3
|
+
* trip: post the form, read the fragment that comes back. Used for actions whose
|
|
4
|
+
* happy path needs an external system (Jira through twg) — the guards answer
|
|
5
|
+
* locally and deterministically either way, and they are what must not regress.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
'use strict';
|
|
9
|
+
|
|
10
|
+
const { When, Then } = require('@cucumber/cucumber');
|
|
11
|
+
const assert = require('assert');
|
|
12
|
+
|
|
13
|
+
When('I post {string} with {string}', async function (path, json) {
|
|
14
|
+
const form = JSON.parse(json);
|
|
15
|
+
const base = process.env.LAUNCH_URL || 'https://workspace.ddev.site';
|
|
16
|
+
const response = await this.page.request.post(`${base}${path}`, { form });
|
|
17
|
+
this.lastActionResponse = await response.text();
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
Then('the action response should contain {string}', function (needle) {
|
|
21
|
+
assert.ok(
|
|
22
|
+
(this.lastActionResponse || '').includes(needle),
|
|
23
|
+
`expected the response to contain ${JSON.stringify(needle)} — got: ${(this.lastActionResponse || '').slice(0, 300)}`,
|
|
24
|
+
);
|
|
25
|
+
});
|