@webship.co/workspace 1.0.2 → 1.0.4
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/core/docs/releases.md +1 -1
- package/core/scripts/functions/fun-build-distribution.sh +0 -9
- package/core/scripts/functions/fun-build-webships.sh +4 -0
- package/core/scripts/functions/fun-default-settings.sh +2 -1
- package/core/scripts/functions/fun-testing.sh +19 -9
- package/core/workspace-app/docs/README.md +4 -3
- package/core/workspace-app/docs/USER-GUIDE.md +2 -2
- package/core/workspace-app/docs/screenshots/assistant/avatar-board.png +0 -0
- package/core/workspace-app/docs/screenshots/assistant/avatar-colours.png +0 -0
- package/core/workspace-app/docs/screenshots/assistant/avatar-icons.png +0 -0
- package/core/workspace-app/docs/screenshots/assistant/avatar-moves.png +0 -0
- package/core/workspace-app/docs/screenshots/assistant/avatar-settings-voices.png +0 -0
- package/core/workspace-app/docs/screenshots/create-card/create-card.png +0 -0
- package/core/workspace-app/docs/screenshots/create-card/start-ai.png +0 -0
- package/core/workspace-app/docs/screenshots/guide-clone-address.png +0 -0
- package/core/workspace-app/docs/screenshots/guide-clone-worktree-off.png +0 -0
- package/core/workspace-app/docs/screenshots/guide-clone-worktree-on.png +0 -0
- package/core/workspace-app/docs/screenshots/guide-ddev-menu.png +0 -0
- package/core/workspace-app/docs/screenshots/guide-domains.png +0 -0
- package/core/workspace-app/docs/screenshots/guide-home.png +0 -0
- package/core/workspace-app/docs/screenshots/guide-ide-menu.png +0 -0
- package/core/workspace-app/docs/screenshots/guide-remove-refusal.png +0 -0
- package/core/workspace-app/docs/screenshots/guide-rows-worktree.png +0 -0
- package/core/workspace-app/docs/screenshots/guide-screens.png +0 -0
- package/core/workspace-app/docs/screenshots/guide-settings.png +0 -0
- package/core/workspace-app/docs/screenshots/guide-workspace-page.png +0 -0
- package/core/workspace-app/docs/screenshots/home/card-settings.png +0 -0
- package/core/workspace-app/docs/screenshots/home/drag-reorder.png +0 -0
- package/core/workspace-app/docs/screenshots/home/edit-card.png +0 -0
- package/core/workspace-app/docs/screenshots/images/claude-code-image.png +0 -0
- package/core/workspace-app/docs/screenshots/images/edit-with-ai.png +0 -0
- package/core/workspace-app/docs/screenshots/images/gallery.png +0 -0
- package/core/workspace-app/docs/screenshots/images/generate-description.png +0 -0
- package/core/workspace-app/docs/screenshots/images/generate-plan.png +0 -0
- package/core/workspace-app/docs/screenshots/images/providers.png +0 -0
- package/core/workspace-app/docs/screenshots/images/svg-form.png +0 -0
- package/core/workspace-app/docs/screenshots/images/svg-result.png +0 -0
- package/core/workspace-app/docs/screenshots/images/upload.png +0 -0
- package/core/workspace-app/docs/screenshots/new-folder/2-form.png +0 -0
- package/core/workspace-app/docs/screenshots/new-folder/8-ddev-options.png +0 -0
- package/core/workspace-app/docs/screenshots/new-folder/files-folder.png +0 -0
- package/core/workspace-app/docs/screenshots/projects/ddev-custom-commands.png +0 -0
- package/core/workspace-app/docs/screenshots/projects/state-chip-stop.png +0 -0
- package/core/workspace-app/docs/screenshots/readme/dashboard-dark.png +0 -0
- package/core/workspace-app/docs/screenshots/readme/dashboard-light.png +0 -0
- package/core/workspace-app/docs/screenshots/readme/dev-dark.png +0 -0
- package/core/workspace-app/docs/screenshots/readme/dev-light.png +0 -0
- package/core/workspace-app/docs/screenshots/readme/docs-dark.png +0 -0
- package/core/workspace-app/docs/screenshots/readme/docs-light.png +0 -0
- package/core/workspace-app/docs/screenshots/readme/videos-dark.png +0 -0
- package/core/workspace-app/docs/screenshots/readme/videos-light.png +0 -0
- package/core/workspace-app/docs/screenshots/screens-menu.png +0 -0
- package/core/workspace-app/docs/screenshots/screens-new.png +0 -0
- package/core/workspace-app/docs/screenshots/settings/auth-google-lists.png +0 -0
- package/core/workspace-app/docs/screenshots/settings/delete-1-row.png +0 -0
- package/core/workspace-app/docs/screenshots/settings/delete-2-confirm.png +0 -0
- package/core/workspace-app/docs/screenshots/settings/delete-3-type-name.png +0 -0
- package/core/workspace-app/docs/screenshots/settings/delete-4-type-yes.png +0 -0
- package/core/workspace-app/package.json +1 -1
- package/core/workspace-app/public/avatar/druplicon.vrm +0 -0
- package/core/workspace-app/server.js +1 -1
- package/core/workspace-app/tests/unit/files-route-stream.test.js +16 -0
- package/package.json +1 -1
- package/core/workspace-app/docs/screenshots/assistant/avatar-coffee.png +0 -0
- package/core/workspace-app/docs/screenshots/assistant/avatar-pick-cookieman.png +0 -0
- package/core/workspace-app/docs/screenshots/assistant/avatar-status.png +0 -0
- package/core/workspace-app/docs/screenshots/readme/test-report-dark.png +0 -0
- package/core/workspace-app/docs/screenshots/readme/test-report-light.png +0 -0
- package/core/workspace-app/docs/screenshots/readme/test-scenarios.png +0 -0
- package/core/workspace-app/docs/screenshots/readme/test-steps.png +0 -0
package/core/docs/releases.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Releases
|
|
2
2
|
|
|
3
|
-
Every package is versioned together: `@webship.co/workspace` (the core) and every `@webship.co/workspace-<name>`. Versions so far: 1.0.0-alpha1 (the first publish), 1.0.0-beta1, 1.0.0-beta2, 1.0.0-rc1, 1.0.0, 1.0.1 (the core and the git, ide and graph plugins only), 1.0.2.
|
|
3
|
+
Every package is versioned together: `@webship.co/workspace` (the core) and every `@webship.co/workspace-<name>`. Versions so far: 1.0.0-alpha1 (the first publish), 1.0.0-beta1, 1.0.0-beta2, 1.0.0-rc1, 1.0.0, 1.0.1 (the core and the git, ide and graph plugins only), 1.0.2, 1.0.3 and 1.0.4 (the core only).
|
|
4
4
|
|
|
5
5
|
## How a change lands
|
|
6
6
|
|
|
@@ -117,15 +117,6 @@ function build_distribution() {
|
|
|
117
117
|
fi
|
|
118
118
|
fi
|
|
119
119
|
|
|
120
|
-
# A failed create-project (an upstream patch that no longer applies, a yanked tag) has to stop
|
|
121
|
-
# the build here. Every step below assumes a real vendor/autoload.php, so carrying on used to
|
|
122
|
-
# mean "installing" nothing and then announcing success.
|
|
123
|
-
if ! ddev composer create-project ${distribution_project_template}:${site_version} . --no-interaction ; then
|
|
124
|
-
echo "composer create-project failed for ${distribution_project_template}:${site_version} — aborting, nothing was installed." ;
|
|
125
|
-
cd ${WORKSPACE_ROOT}/${doc_name};
|
|
126
|
-
return 1 ;
|
|
127
|
-
fi
|
|
128
|
-
|
|
129
120
|
# Some project templates ship their own .ddev config that
|
|
130
121
|
# changes the docroot/database/webimage packages after our initial ddev
|
|
131
122
|
# config. Re-align: keep the database type we already provisioned, drop
|
|
@@ -55,6 +55,10 @@ function webships_create_project() {
|
|
|
55
55
|
# Keep the API site templates as recipes, the way the project template does:
|
|
56
56
|
# the installer finds them in recipes/ without Composer unpacking them.
|
|
57
57
|
ddev composer config --json --merge extra.drupal-recipe-unpack.ignore '["drupal/webships_starter", "drupal/webapi_starter"]' ;
|
|
58
|
+
# The project template ships its own .ddev/config.yaml, which pins an older Node.js:
|
|
59
|
+
# re-align to the workspace's Node.js (24, like Drupal core) and restart on it.
|
|
60
|
+
ddev config --nodejs-version=$(ddev_nodejs_version) --webimage-extra-packages="" ;
|
|
61
|
+
ddev restart ;
|
|
58
62
|
}
|
|
59
63
|
|
|
60
64
|
# The shared steps after a successful install.
|
|
@@ -14,7 +14,8 @@ function set_default_settings() {
|
|
|
14
14
|
|
|
15
15
|
if [ -f "${settings_file}" ]; then
|
|
16
16
|
# Fixed, not a setting: it has to match the config/sync created above.
|
|
17
|
-
|
|
17
|
+
# An active assignment only: default.settings.php carries the same line commented out.
|
|
18
|
+
if ! grep -qE "^[[:space:]]*\\\$settings\['config_sync_directory'\]" "${settings_file}" ; then
|
|
18
19
|
# Defaulted here rather than asked for in the settings: ../config/sync is the Drupal
|
|
19
20
|
# convention and the folder created just above. Setting config_sync_directory in
|
|
20
21
|
# settings.yml still overrides it.
|
|
@@ -62,12 +62,16 @@ function testing_write_browser_libs_build() {
|
|
|
62
62
|
# they survive `ddev restart` — installed by the workspace testing tooling.
|
|
63
63
|
# Playwright resolves the package names for this Debian release itself; the apt
|
|
64
64
|
# list is the fallback for a build with no network access to npm.
|
|
65
|
-
|
|
65
|
+
# The third-party PHP repository of the web image is set aside while apt runs: an expired key
|
|
66
|
+
# there would fail the whole image build, and chromium's libraries are Debian's own.
|
|
67
|
+
RUN mkdir -p /tmp/apt-off && (mv /etc/apt/sources.list.d/php.list /tmp/apt-off/ 2>/dev/null || true) && \
|
|
68
|
+
(npx --yes playwright@1.56 install-deps chromium || \
|
|
66
69
|
(apt-get update && apt-get install -y --no-install-recommends \
|
|
67
70
|
libnspr4 libnss3 libdbus-1-3 libatk1.0-0t64 libatk-bridge2.0-0t64 libcups2t64 \
|
|
68
71
|
libdrm2 libatspi2.0-0t64 libxcomposite1 libxdamage1 libxfixes3 libxrandr2 \
|
|
69
|
-
libgbm1 libxkbcommon0 libasound2t64 libpango-1.0-0 libcairo2 fonts-liberation \
|
|
70
|
-
|
|
72
|
+
libgbm1 libxkbcommon0 libasound2t64 libpango-1.0-0 libcairo2 fonts-liberation)) ; \
|
|
73
|
+
status=$? ; (mv /tmp/apt-off/php.list /etc/apt/sources.list.d/ 2>/dev/null || true) ; \
|
|
74
|
+
rm -rf /var/lib/apt/lists/* ; exit $status
|
|
71
75
|
DOCKERFILE
|
|
72
76
|
}
|
|
73
77
|
|
|
@@ -179,7 +183,6 @@ function testing_configure() {
|
|
|
179
183
|
echo "";
|
|
180
184
|
echo "Installing the JS dependencies and the chromium browser.";
|
|
181
185
|
ddev ${runner} install || true ;
|
|
182
|
-
testing_write_browser_libs_build "${project_path}" ;
|
|
183
186
|
testing_ensure_browser_libs "${project_path}" || true ;
|
|
184
187
|
testing_install_browsers || true ;
|
|
185
188
|
fi
|
|
@@ -255,6 +258,7 @@ function testing_run() {
|
|
|
255
258
|
[ "${HEADED}" == 'yes' ] && env_prefix="${env_prefix} HEADLESS=false";
|
|
256
259
|
local cucumber="node ./node_modules/@cucumber/cucumber/bin/cucumber.js --config cucumber.js";
|
|
257
260
|
local filter="";
|
|
261
|
+
local run_log; run_log=$(mktemp);
|
|
258
262
|
# Narrowing to one feature is an ENV var here, not a positional argument: these projects'
|
|
259
263
|
# cucumber.js sets `paths: [process.env.FEATURES || 'tests/features/**/*.feature']`, and a config
|
|
260
264
|
# `paths` wins over the path you type — passing it positionally silently ran all 275 scenarios.
|
|
@@ -262,7 +266,7 @@ function testing_run() {
|
|
|
262
266
|
if [ ! "${TESTING_PATH}" == '_none_' ] ; then
|
|
263
267
|
local features="${TESTING_PATH}";
|
|
264
268
|
case "${features}" in
|
|
265
|
-
*.feature
|
|
269
|
+
*.feature|*.feature:[0-9]*|*'*'*) : ;;
|
|
266
270
|
*) features="${features%/}/**/*.feature" ;;
|
|
267
271
|
esac
|
|
268
272
|
env_prefix="${env_prefix} FEATURES=\"${features}\"";
|
|
@@ -277,8 +281,14 @@ function testing_run() {
|
|
|
277
281
|
|
|
278
282
|
if [ -n "${filter}" ] ; then
|
|
279
283
|
echo " ddev exec ${env_prefix} ${cucumber} ${filter}";
|
|
280
|
-
ddev exec "${env_prefix} ${cucumber} ${filter}" ;
|
|
281
|
-
status
|
|
284
|
+
ddev exec "${env_prefix} ${cucumber} ${filter}" 2>&1 | tee "${run_log}" ;
|
|
285
|
+
status=${PIPESTATUS[0]} ;
|
|
286
|
+
# A run that matched nothing exits 0 too: a wrong --path or tag expression must not read as green.
|
|
287
|
+
if grep -qE '^0 scenarios' "${run_log}" ; then
|
|
288
|
+
echo " No scenario ran: check the --path or --tags you gave." ;
|
|
289
|
+
status=3 ;
|
|
290
|
+
fi
|
|
291
|
+
rm -f "${run_log}" ;
|
|
282
292
|
else
|
|
283
293
|
script="test:${BROWSER}";
|
|
284
294
|
echo " ddev ${runner} run ${script}";
|
|
@@ -320,10 +330,10 @@ function testing_run() {
|
|
|
320
330
|
function testing_command() {
|
|
321
331
|
# --configure is the default, so it is only meaningful as a word — except together with --run,
|
|
322
332
|
# where "set it up and then run it" is a real thing to ask for and used to lose the setup half.
|
|
323
|
-
if [ "${CONFIGURE}" == 'yes' ] || [ ! "${RUN}" == 'yes' ] ; then
|
|
333
|
+
if [ "${CONFIGURE}" == 'yes' ] || { [ ! "${RUN}" == 'yes' ] && [ ! "${DRY_RUN}" == 'yes' ] ; } ; then
|
|
324
334
|
testing_configure || return 1 ;
|
|
325
335
|
fi
|
|
326
|
-
if [ "${RUN}" == 'yes' ] ; then
|
|
336
|
+
if [ "${RUN}" == 'yes' ] || [ "${DRY_RUN}" == 'yes' ] ; then
|
|
327
337
|
testing_run ;
|
|
328
338
|
fi
|
|
329
339
|
}
|
|
@@ -247,6 +247,7 @@ Some releases change the container image; the notes say so, and then
|
|
|
247
247
|
| the hard rules and the operational traps | `docs/workspace-tips-and-rules.md` |
|
|
248
248
|
| what changed, dated | `worklogs/` |
|
|
249
249
|
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
250
|
+
The pictures in `screenshots/` are used by these guides; `assistant/` and `readme/` hold spare ones of
|
|
251
|
+
the assistant's avatar and of the pages in light and dark. All of them were taken on 13 November 2026
|
|
252
|
+
on a Webship Workspace with demo content, at 1920×1080 (the home page is taller, to show every card),
|
|
253
|
+
in light mode unless the name says dark. A pull request carries its own pictures on its branch.
|
|
@@ -399,7 +399,7 @@ Claude ends the way it would if you typed it, and the conversation is kept. When
|
|
|
399
399
|
project or folder that has one, the same menu offers **Resume Claude Code**, which resumes the last conversation
|
|
400
400
|
with `claude --resume` in that folder.
|
|
401
401
|
|
|
402
|
-

|
|
403
403
|
|
|
404
404
|
### Watch something long
|
|
405
405
|
|
|
@@ -459,7 +459,7 @@ Pick the **Provider** first: OpenAI, Google Gemini, xAI, Stability AI or Claude
|
|
|
459
459
|
quality fields change with it. A provider with no key on this machine is listed but greyed out, with the key
|
|
460
460
|
to set (`ai_providers.<provider>.api_key` in `core/config/settings.yml`).
|
|
461
461
|
|
|
462
|
-

|
|
463
463
|
|
|
464
464
|
**Claude Code** needs no key: it uses your own Claude Code login, so there is no API charge. It cannot paint
|
|
465
465
|
a photo, so it draws a flat illustration as an SVG, and the dashboard turns it into a PNG as well; you keep
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "workspace-dashboard",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.4",
|
|
4
4
|
"description": "The Webship Workspace dashboard: a lean core (workspaces, builders, settings, the assistant shell, the plugin system) that every feature joins as a @webship.co/workspace-<name> plugin — required with npm, then activated, installed and configured.",
|
|
5
5
|
"license": "ISC",
|
|
6
6
|
"main": "server.js",
|
|
Binary file
|
|
@@ -7875,7 +7875,7 @@ Summarise what you changed and how to verify it`,
|
|
|
7875
7875
|
// An SVG is a document that can carry script; shown on its own it runs none.
|
|
7876
7876
|
...(type === 'image/svg+xml' ? { 'Content-Security-Policy': "default-src 'none'; style-src 'unsafe-inline'; sandbox" } : {}),
|
|
7877
7877
|
});
|
|
7878
|
-
return fs.createReadStream(
|
|
7878
|
+
return fs.createReadStream(real).pipe(res);
|
|
7879
7879
|
}
|
|
7880
7880
|
const argsMatch = pathname.match(/^\/fragments\/([a-z0-9_-]+)\/builder-args$/);
|
|
7881
7881
|
if (argsMatch && isValidWorkspace(argsMatch[1])) {
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
// The /files/<workspace>/<path> route resolves the file to `real` and must stream that. It streamed
|
|
2
|
+
// `file`, a name the route never defines, so every plain (non-range) request sent headers and no body.
|
|
3
|
+
const assert = require('node:assert');
|
|
4
|
+
const { test } = require('node:test');
|
|
5
|
+
const fs = require('fs');
|
|
6
|
+
const path = require('path');
|
|
7
|
+
|
|
8
|
+
test('the files route streams the file it resolved', () => {
|
|
9
|
+
const src = fs.readFileSync(path.join(__dirname, '..', '..', 'server.js'), 'utf8');
|
|
10
|
+
const start = src.indexOf('filesBrowser.realFileIn(workspaceDir(fileMatch[1]), name)');
|
|
11
|
+
assert.ok(start > 0, 'the files route was not found');
|
|
12
|
+
const route = src.slice(start, src.indexOf('builder-args', start));
|
|
13
|
+
const streams = [...route.matchAll(/fs\.createReadStream\((\w+)/g)].map((m) => m[1]);
|
|
14
|
+
assert.ok(streams.length >= 2, 'expected the range branch and the whole-file branch');
|
|
15
|
+
for (const name of streams) assert.strictEqual(name, 'real', `the route streams "${name}", which it does not define`);
|
|
16
|
+
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@webship.co/workspace",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.4",
|
|
4
4
|
"description": "Webship Workspace: a container-based development workspace with a web dashboard. The core ships empty; workspace folders, hosting providers, git forges, container runtimes and features are @webship.co/workspace-<name> plugins you add one at a time.",
|
|
5
5
|
"license": "GPL-2.0-or-later",
|
|
6
6
|
"repository": {
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|