@1agh/maude 0.54.0 → 0.56.0

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 (53) hide show
  1. package/apps/studio/annotations-layer.tsx +11 -1
  2. package/apps/studio/bin/_smart-frames.mjs +187 -20
  3. package/apps/studio/bin/_smart-frames.test.mjs +59 -4
  4. package/apps/studio/bin/_transcribe.mjs +40 -3
  5. package/apps/studio/bin/smoke.sh +7 -1
  6. package/apps/studio/canvas-build-sandbox.ts +101 -9
  7. package/apps/studio/canvas-build-worker.ts +7 -1
  8. package/apps/studio/canvas-build.ts +9 -1
  9. package/apps/studio/client/app.jsx +49 -3
  10. package/apps/studio/client/github.js +7 -0
  11. package/apps/studio/client/panels/CloudBar.jsx +505 -45
  12. package/apps/studio/client/panels/GitPanel.jsx +38 -25
  13. package/apps/studio/client/panels/SettingsPanel.jsx +239 -27
  14. package/apps/studio/client/styles/3-shell-maude.css +30 -0
  15. package/apps/studio/client/styles/4-components.css +72 -0
  16. package/apps/studio/cloud/endpoints.ts +104 -9
  17. package/apps/studio/collab/persistence.ts +29 -2
  18. package/apps/studio/config.schema.json +3 -3
  19. package/apps/studio/context.ts +41 -0
  20. package/apps/studio/dist/client.bundle.js +1545 -1545
  21. package/apps/studio/dist/comment-mount.js +2 -2
  22. package/apps/studio/dist/styles.css +1 -1
  23. package/apps/studio/generation/gemma-models.ts +312 -14
  24. package/apps/studio/generation/prefs.ts +7 -2
  25. package/apps/studio/generation/runtime-probe.ts +50 -0
  26. package/apps/studio/generation/whisper-models.ts +124 -0
  27. package/apps/studio/hmr-broadcast.ts +67 -0
  28. package/apps/studio/http.ts +210 -110
  29. package/apps/studio/input-router.tsx +55 -2
  30. package/apps/studio/server.ts +11 -9
  31. package/apps/studio/sync/autocommit.ts +61 -2
  32. package/apps/studio/sync/cell-pairing.ts +174 -0
  33. package/apps/studio/sync/codec.ts +11 -5
  34. package/apps/studio/sync/index.ts +239 -26
  35. package/apps/studio/sync/limits.ts +49 -0
  36. package/apps/studio/sync/loopback.ts +21 -0
  37. package/apps/studio/sync/projection.ts +47 -12
  38. package/apps/studio/sync/supervisor.ts +178 -0
  39. package/apps/studio/test/cloud-endpoints.test.ts +326 -4
  40. package/apps/studio/test/csrf-write-guard.test.ts +19 -2
  41. package/apps/studio/test/gemma-models.test.ts +245 -0
  42. package/apps/studio/test/hmr-broadcast.test.ts +57 -1
  43. package/apps/studio/test/input-router.test.ts +95 -0
  44. package/apps/studio/test/shared-doc-cell-pairing.test.ts +639 -0
  45. package/apps/studio/test/sync-autocommit.test.ts +47 -0
  46. package/apps/studio/test/sync-supervisor.test.ts +212 -0
  47. package/apps/studio/test/trusted-request-host.test.ts +66 -0
  48. package/apps/studio/test/whisper-setup.test.ts +97 -0
  49. package/apps/studio/whats-new.json +45 -0
  50. package/apps/studio/ws.ts +9 -1
  51. package/cli/commands/kg.mjs +9 -2
  52. package/package.json +8 -8
  53. package/plugins/design/dependencies.json +21 -3
@@ -79,7 +79,13 @@ main().catch((err) => {
79
79
  // the one who has to act on it. Bun collapses plugin throws into the build
80
80
  // log, so the allowlist's own wording survives in `err.message`.
81
81
  process.stdout.write(
82
- JSON.stringify({ ok: false, error: String(err?.message ?? err).slice(0, 4000) })
82
+ JSON.stringify({
83
+ ok: false,
84
+ error: String(err?.message ?? err).slice(0, 4000),
85
+ // A NUMBER, never the specifiers. The host counts these; the strings
86
+ // stay between the canvas and the person who wrote it.
87
+ rejectedImports: Number(err?.rejectedImports ?? 0) || 0,
88
+ })
83
89
  );
84
90
  process.exit(1);
85
91
  });
@@ -187,7 +187,15 @@ export async function buildCanvasModule(
187
187
  // "Bundle failed" log, so the allowlist records its own reasons and they
188
188
  // win here — the person who wrote the canvas has to be able to act on it,
189
189
  // and "Bundle failed" tells them nothing.
190
- if (denials.length > 0) throw new Error(denials.map((d) => d.reason).join('\n'));
190
+ if (denials.length > 0) {
191
+ // The COUNT of denials travels with the error, so the cost lane can
192
+ // record that imports were refused without ever seeing the specifier —
193
+ // that string is tenant-authored content (Cloud Phase 26 Stage 4). The
194
+ // reasons still go to the person who wrote the canvas, unchanged.
195
+ const err = new Error(denials.map((d) => d.reason).join('\n'));
196
+ (err as Error & { rejectedImports?: number }).rejectedImports = denials.length;
197
+ throw err;
198
+ }
191
199
  const msg = built.logs.map((l) => l.message).join('\n');
192
200
  throw new Error(`Bun.build failed on ${canvasAbsPath}:\n${msg}`);
193
201
  }
@@ -156,7 +156,7 @@ const LAYERS_MODE_STORE = 'mdcc-layers-mode';
156
156
  // resizable width + a tab strip over the panels assigned to the slot; renders
157
157
  // the active panel (passed as children). Collapses to 0 width when nothing is
158
158
  // visibly open (it may still host an always-mounted hidden ChatPanel).
159
- function DockSlot({ side, width, open, ids, activeId, onPick, children }) {
159
+ function DockSlot({ side, width, open, ids, activeId, onPick, children, labels = null }) {
160
160
  return (
161
161
  <div
162
162
  className={'st-dockslot st-dockslot--' + side + (open ? '' : ' is-collapsed')}
@@ -173,7 +173,7 @@ function DockSlot({ side, width, open, ids, activeId, onPick, children }) {
173
173
  className={'st-docktab' + (activeId === id ? ' is-active' : '')}
174
174
  onClick={() => onPick(id)}
175
175
  >
176
- {(DOCK_PANELS.find((p) => p.id === id) || {}).label || id}
176
+ {labels?.[id] || (DOCK_PANELS.find((p) => p.id === id) || {}).label || id}
177
177
  </button>
178
178
  ))}
179
179
  </div>
@@ -628,6 +628,14 @@ const STICONS = {
628
628
  <path d="M4.3 9.5v2.3a1.2 1.2 0 0 0 2.4 0v-1.7" />
629
629
  </>
630
630
  ),
631
+ bug: (
632
+ <>
633
+ <circle cx="8" cy="9" r="3.6" />
634
+ <circle cx="8" cy="4.4" r="1.3" />
635
+ <path d="M6.2 3.4 5.2 2M9.8 3.4l1-1.4" />
636
+ <path d="M4.6 7.6H2.2M4.6 9H2.2M4.6 10.6H2.5M11.4 7.6h2.4M11.4 9h2.4M11.4 10.6h2.3" />
637
+ </>
638
+ ),
631
639
  'panel-left': (
632
640
  <>
633
641
  <rect x="2.5" y="3" width="11" height="10" rx="1.5" />
@@ -3725,7 +3733,14 @@ function Menubar({
3725
3733
  { id: 'tree', label: 'Project Tree', shortcut: 'T', checked: sidebarOpen, disabled: false },
3726
3734
  {
3727
3735
  id: 'changes',
3728
- label: changesCount > 0 ? `Changes · ${changesCount} unsaved` : 'Changes',
3736
+ // In a cell this panel is History (the hub already committed the work),
3737
+ // so the menu names what it opens rather than an unsaved count there is
3738
+ // no way — and no reason — to act on.
3739
+ label: cloud
3740
+ ? 'History'
3741
+ : changesCount > 0
3742
+ ? `Changes · ${changesCount} unsaved`
3743
+ : 'Changes',
3729
3744
  shortcut: '⌘ ⇧ G',
3730
3745
  checked: changesOpen,
3731
3746
  disabled: false,
@@ -4115,6 +4130,16 @@ function Menubar({
4115
4130
  </button>
4116
4131
  )}
4117
4132
  {exportCenter && <ExportBadge center={exportCenter} />}
4133
+ <button
4134
+ type="button"
4135
+ className="st-reportbug"
4136
+ data-testid="report-bug-toggle"
4137
+ aria-label="Report a bug"
4138
+ data-tip="Report a bug"
4139
+ onClick={onReportBug}
4140
+ >
4141
+ <StIcon name="bug" size={15} />
4142
+ </button>
4118
4143
  <button
4119
4144
  type="button"
4120
4145
  className="st-whatsnew"
@@ -14001,6 +14026,11 @@ function App() {
14001
14026
  changes: changesOpen,
14002
14027
  assistant: assistantOpen,
14003
14028
  };
14029
+ // Per-shell overrides for the dock tab strip. In a cell the `changes` panel
14030
+ // IS the history (the hub commits server-side), so its tab must say so —
14031
+ // otherwise the one visible word still promises a working-tree surface that
14032
+ // panel no longer has.
14033
+ const dockLabels = cfg.cloud ? { changes: 'History' } : null;
14004
14034
  const leftIds = idsForSide('left');
14005
14035
  const rightIds = idsForSide('right');
14006
14036
  const leftActive = leftIds.find((id) => panelIsOpen[id]) || null;
@@ -14065,6 +14095,20 @@ function App() {
14065
14095
  status={gitStatus && remoteSync ? { ...gitStatus, ...remoteSync } : gitStatus}
14066
14096
  project={project}
14067
14097
  readOnly={!isNativeApp() || viewerMode}
14098
+ // A cloud cell commits every edit server-side as it lands, so the
14099
+ // working-tree half of this panel describes work that is already
14100
+ // saved. `cfg.cloud` is present exactly when the hub runs the
14101
+ // workspace agent that owns this project's history, which is the
14102
+ // same condition.
14103
+ //
14104
+ // PRESENTATION, NOT A CONTROL — nothing may come to depend on this.
14105
+ // `/_api/git/commit` and `/_api/git/discard` are classified `edit` in
14106
+ // the cell's route manifest and stay reachable by any member with a
14107
+ // session; withdrawing the buttons removes an offer that would
14108
+ // mislead, it does not remove a capability. The real gates are
14109
+ // server-side (`projectReadOnly`, the manifest's role matrix), and
14110
+ // they are unchanged by this flag.
14111
+ historyOnly={!!cfg.cloud}
14068
14112
  resizing={resizingFor('changes')}
14069
14113
  onClose={() => setChangesOpen(false)}
14070
14114
  onCommit={gitCommit}
@@ -14312,6 +14356,7 @@ function App() {
14312
14356
  ids={leftIds}
14313
14357
  activeId={leftActive}
14314
14358
  onPick={togglePanel}
14359
+ labels={dockLabels}
14315
14360
  >
14316
14361
  {leftHostsAssistant && (
14317
14362
  <ChatPanel
@@ -14384,6 +14429,7 @@ function App() {
14384
14429
  ids={rightIds}
14385
14430
  activeId={rightActive}
14386
14431
  onPick={togglePanel}
14432
+ labels={dockLabels}
14387
14433
  >
14388
14434
  {rightHostsAssistant && (
14389
14435
  <ChatPanel
@@ -39,6 +39,13 @@ export const openVerification = () =>
39
39
  * Rust side host-locks it to github.com. Throws on an older desktop build without
40
40
  * the command — callers fall back to copy-to-clipboard. */
41
41
  export const openGitHubUrl = (url) => invoke('open_github_url', { url });
42
+ /** Open a Maude Cloud URL (device activation, share view, dashboard) in the OS
43
+ * browser. Native only — `window.open` is a silent no-op in WKWebView, which is
44
+ * what stranded people mid-sign-in. The Rust side zone-locks it against the
45
+ * address it resolves per call, so this argument can't widen where it goes.
46
+ * Throws on an older desktop build without the command — every caller must keep
47
+ * a visible link the person can use by hand. */
48
+ export const openCloudUrl = (url) => invoke('open_cloud_url', { url });
42
49
  /** Show the device code as soon as the shell has it. Returns an unlisten promise. */
43
50
  export const onDeviceCode = (cb) => listen('github://device-code', cb);
44
51
  /** Fire when sign-in completes (any surface) so other surfaces can flip live. cb(login). */