pmx-canvas 0.4.2 → 0.4.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.
Files changed (37) hide show
  1. package/.github/extensions/pmx-canvas/extension.mjs +5 -2
  2. package/CHANGELOG.md +60 -0
  3. package/Readme.md +35 -12
  4. package/dist/canvas/global.css +92 -28
  5. package/dist/canvas/index.js +62 -62
  6. package/dist/canvas/surface-theme.css +52 -20
  7. package/dist/types/cli/agent.d.ts +1 -0
  8. package/dist/types/cli/commands/skills.d.ts +41 -0
  9. package/dist/types/client/state/sse-bridge.d.ts +1 -0
  10. package/dist/types/client/state/theme-override.d.ts +27 -0
  11. package/dist/types/shared/themes.d.ts +1 -1
  12. package/docs/RELEASE.md +14 -6
  13. package/docs/bun-webview-integration.md +2 -2
  14. package/docs/cli.md +24 -1
  15. package/docs/environment.md +2 -2
  16. package/docs/http-api.md +14 -3
  17. package/docs/plans/plan-009-tech-debt-backlog.md +5 -2
  18. package/docs/screenshot.png +0 -0
  19. package/package.json +3 -3
  20. package/skills/pmx-canvas/SKILL.md +18 -4
  21. package/skills/pmx-canvas/references/full-reference.md +1 -1
  22. package/skills/pmx-canvas-testing/SKILL.md +4 -0
  23. package/src/cli/agent.ts +1 -0
  24. package/src/cli/commands/skills.ts +183 -0
  25. package/src/cli/index.ts +3 -1
  26. package/src/cli/shared.ts +1 -0
  27. package/src/client/App.tsx +85 -78
  28. package/src/client/canvas/CommandPalette.tsx +4 -0
  29. package/src/client/nodes/ExtAppFrame.tsx +15 -4
  30. package/src/client/nodes/McpAppNode.tsx +6 -1
  31. package/src/client/state/sse-bridge.ts +22 -5
  32. package/src/client/state/theme-override.ts +83 -0
  33. package/src/client/theme/global.css +92 -28
  34. package/src/client/theme/surface-theme.css +52 -20
  35. package/src/server/operations/ops/canvas-wire.ts +10 -2
  36. package/src/server/server.ts +13 -2
  37. package/src/shared/themes.ts +3 -1
@@ -218,32 +218,32 @@
218
218
  }
219
219
 
220
220
  :root[data-theme="ember"] {
221
- /* ── Core palette (ember · charcoal + vivid warm orange) ─── */
222
- --c-bg: #0E0E11;
223
- --c-panel: #17181D;
224
- --c-panel-soft: #121317;
225
- --c-line: #2A2C34;
226
- --c-text: #ECEDF0;
227
- --c-text-soft: #C9CCD4;
228
- --c-muted: #8E939F;
229
- --c-dim: #5F646E;
230
- --c-accent: #FF5C2E;
221
+ /* ── Core palette (ember · neutral charcoal + vivid orange-red) ─── */
222
+ --c-bg: #0B0B0C;
223
+ --c-panel: #161618;
224
+ --c-panel-soft: #101012;
225
+ --c-line: #29292C;
226
+ --c-text: #EDEBE6;
227
+ --c-text-soft: #CBC9C2;
228
+ --c-muted: #96948D;
229
+ --c-dim: #66655F;
230
+ --c-accent: #F34E1C;
231
231
  --c-ok: #4CC38A;
232
232
  --c-warn: #F5B944;
233
233
  --c-warn-alt: #FFB300;
234
234
  --c-danger: #F0566A;
235
235
  --c-purple: #A78BFA;
236
236
 
237
- --color-bg: #0E0E11;
238
- --color-panel: #17181D;
239
- --color-surface: #121317;
240
- --color-border: #2A2C34;
241
- --color-text: #ECEDF0;
242
- --color-text-primary: #ECEDF0;
243
- --color-text-secondary: #C9CCD4;
244
- --color-text-muted: #8E939F;
245
- --color-text-dim: #5F646E;
246
- --color-accent: #FF5C2E;
237
+ --color-bg: #0B0B0C;
238
+ --color-panel: #161618;
239
+ --color-surface: #101012;
240
+ --color-border: #29292C;
241
+ --color-text: #EDEBE6;
242
+ --color-text-primary: #EDEBE6;
243
+ --color-text-secondary: #CBC9C2;
244
+ --color-text-muted: #96948D;
245
+ --color-text-dim: #66655F;
246
+ --color-accent: #F34E1C;
247
247
  --color-success: #4CC38A;
248
248
  --color-warning: #F5B944;
249
249
  --color-danger: #F0566A;
@@ -281,6 +281,38 @@
281
281
  --color-danger: #E57373;
282
282
  }
283
283
 
284
+ :root[data-theme="volt"] {
285
+ /* ── Core palette (volt · green-tinted charcoal + coral) ── */
286
+ --c-bg: #0B0D0B;
287
+ --c-panel: #171A17;
288
+ --c-panel-soft: #111311;
289
+ --c-line: #272A27;
290
+ --c-text: #F6FFF5;
291
+ --c-text-soft: #CBD3CA;
292
+ --c-muted: #9CA49C;
293
+ --c-dim: #626962;
294
+ --c-accent: #F34E3F;
295
+ --c-ok: #52C880;
296
+ --c-warn: #E4C465;
297
+ --c-warn-alt: #FFB300;
298
+ --c-danger: #D67670;
299
+ --c-purple: #BC8FB4;
300
+
301
+ --color-bg: #0B0D0B;
302
+ --color-panel: #171A17;
303
+ --color-surface: #111311;
304
+ --color-border: #272A27;
305
+ --color-text: #F6FFF5;
306
+ --color-text-primary: #F6FFF5;
307
+ --color-text-secondary: #CBD3CA;
308
+ --color-text-muted: #9CA49C;
309
+ --color-text-dim: #626962;
310
+ --color-accent: #F34E3F;
311
+ --color-success: #52C880;
312
+ --color-warning: #E4C465;
313
+ --color-danger: #D67670;
314
+ }
315
+
284
316
  html,
285
317
  body {
286
318
  margin: 0;
@@ -10,7 +10,8 @@ import { z } from 'zod';
10
10
  import { normalizeCanvasTheme } from '../../canvas-db.js';
11
11
  import { applyCanvasNodeUpdates } from '../../canvas-operations.js';
12
12
  import { canvasState } from '../../canvas-state.js';
13
- import { defineOperation, type Operation } from '../types.js';
13
+ import { CANVAS_THEMES, isCanvasTheme } from '../../../shared/themes.js';
14
+ import { defineOperation, OperationError, type Operation } from '../types.js';
14
15
 
15
16
  const emptyShape = {};
16
17
  const emptySchema = z.looseObject(emptyShape);
@@ -32,7 +33,7 @@ const themeSetShape = {
32
33
  .unknown()
33
34
  .optional()
34
35
  .describe(
35
- 'Theme name from the canvas theme registry (e.g. dark, light, high-contrast, midnight, sepia, arctic, ember, forest)',
36
+ 'Theme name from the canvas theme registry (e.g. dark, light, high-contrast, midnight, sepia, arctic, ember, forest, volt)',
36
37
  ),
37
38
  };
38
39
  const themeSetSchema = z.looseObject(themeSetShape);
@@ -47,6 +48,13 @@ const themeSetOperation = defineOperation<z.infer<typeof themeSetSchema>, Record
47
48
  path: '/api/canvas/theme',
48
49
  },
49
50
  handler: (input, ctx) => {
51
+ // Reject unknown names instead of silently keeping the prior theme
52
+ // (0.4.2 report: the soft-accept made typos look like successes).
53
+ if (input.theme !== undefined && !isCanvasTheme(input.theme)) {
54
+ throw new OperationError(
55
+ `Unknown theme ${JSON.stringify(input.theme)}. Valid themes: ${CANVAS_THEMES.join(', ')}.`,
56
+ );
57
+ }
50
58
  const theme = normalizeCanvasTheme(input.theme, canvasState.theme);
51
59
  const next = canvasState.setTheme(theme);
52
60
  ctx.emit('theme-changed', { theme: next });
@@ -977,12 +977,23 @@ function canvasSpaHtml(): string {
977
977
  : 'PMX Canvas hit a browser error while loading.';
978
978
  actions.hidden = false;
979
979
  });
980
- setTimeout(function () {
980
+ var showNotBooted = function () {
981
981
  if (!bootstrap || !copy || !actions) return;
982
982
  if (bootstrap.classList.contains('ready')) return;
983
983
  copy.textContent = 'PMX Canvas did not finish booting. Reload the canvas or restart the server.';
984
984
  actions.hidden = false;
985
- }, 4000);
985
+ };
986
+ var bootDeadline = setTimeout(showNotBooted, 4000);
987
+ // The client dispatches this when the SSE watchdog falls back to the
988
+ // polling transport mid-boot (buffering proxies): restart the deadline
989
+ // instead of alarming while the fallback is already recovering.
990
+ window.addEventListener('pmx-canvas-boot-extend', function () {
991
+ if (!bootstrap || bootstrap.classList.contains('ready')) return;
992
+ clearTimeout(bootDeadline);
993
+ if (copy) copy.textContent = 'Live stream blocked by a proxy — switching to polling...';
994
+ if (actions) actions.hidden = true;
995
+ bootDeadline = setTimeout(showNotBooted, 8000);
996
+ });
986
997
  })();
987
998
  </script>
988
999
  ${
@@ -19,6 +19,7 @@ export const CANVAS_THEMES = [
19
19
  'arctic',
20
20
  'ember',
21
21
  'forest',
22
+ 'volt',
22
23
  ] as const;
23
24
 
24
25
  export type CanvasThemeName = (typeof CANVAS_THEMES)[number];
@@ -48,8 +49,9 @@ export const CANVAS_THEME_META: Record<CanvasThemeName, CanvasThemeMeta> = {
48
49
  midnight: { label: 'Midnight', scheme: 'dark', swatchBg: '#0A0D1C', swatchAccent: '#8B96FF' },
49
50
  sepia: { label: 'Sepia', scheme: 'light', swatchBg: '#F2E7D5', swatchAccent: '#B4632C' },
50
51
  arctic: { label: 'Arctic', scheme: 'dark', swatchBg: '#20242E', swatchAccent: '#7FC8DE' },
51
- ember: { label: 'Ember', scheme: 'dark', swatchBg: '#0E0E11', swatchAccent: '#FF5C2E' },
52
+ ember: { label: 'Ember', scheme: 'dark', swatchBg: '#0B0B0C', swatchAccent: '#F34E1C' },
52
53
  forest: { label: 'Forest', scheme: 'dark', swatchBg: '#0C1712', swatchAccent: '#5CCF8F' },
54
+ volt: { label: 'Volt', scheme: 'dark', swatchBg: '#0B0D0B', swatchAccent: '#F34E3F' },
53
55
  };
54
56
 
55
57
  /** Collapse a theme to the dark/light scheme embedded dark|light-only viewers understand. */