@ai-matrx/canvas 0.8.4 → 0.9.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.
package/dist/index.d.cts CHANGED
@@ -1,5 +1,5 @@
1
- import { C as CanvasItemId, a as CanvasWindowId, b as CanvasJson, c as CanvasLayoutNode, d as CanvasPaneId, e as CanvasStoreBinding, f as CanvasState, g as CanvasAction, h as CanvasController, i as CanvasItem, j as CanvasExtraWindow, k as CanvasHistoryEntry, l as CanvasPane, m as canvasWindowOfItem } from './toggleKind-BoFnqhzq.cjs';
2
- export { n as CANVAS_DEFAULT_KEY, o as CANVAS_DEFAULT_WIDTH, p as CANVAS_DESKTOP_LAYOUT_RULES, q as CANVAS_HISTORY_LIMIT, r as CANVAS_KEEP_ALIVE_DEPTH, s as CANVAS_LAUNCHER_KIND, t as CANVAS_MAIN_WINDOW, u as CANVAS_MIN_SPLIT_FRACTION, v as CANVAS_MIN_WIDTH, w as CANVAS_NARROW_WIDTH, x as CANVAS_PANE_MIN_WIDTH, y as CANVAS_PHONE_MAX_WIDTH, z as CANVAS_STORAGE_KEY, A as CANVAS_WEB_LAYOUT_RULES, B as CanvasControllerOptions, D as CanvasErrorReport, E as CanvasErrorSink, F as CanvasKeyValueStore, G as CanvasKindVisibility, H as CanvasLayoutRules, I as CanvasNavigateInput, J as CanvasOpenInput, K as CanvasOpenTarget, L as CanvasOrientation, M as CanvasPersistencePort, N as CanvasPreferredTarget, O as CanvasPresentation, P as CanvasPresentationOrientation, Q as CanvasRect, R as CanvasSessionAttachReason, S as CanvasSessionDetachReason, T as CanvasSessionEvent, U as CanvasSessionHooks, V as CanvasSplitId, W as CanvasWindowCloseMode, X as CanvasWindowFrame, Y as CanvasWindowPorts, Z as ReduxStoreLike, _ as ToggleKindInput, $ as bindCanvasToReduxStore, a0 as canvasActions, a1 as canvasOrientation, a2 as canvasPresentation, a3 as canvasReducer, a4 as canvasWindowFrame, a5 as canvasWindowOfPane, a6 as clampDraggedCanvasWidth, a7 as consoleCanvasErrorSink, a8 as createCanvasController, a9 as createCanvasStore, aa as createInitialCanvasState, ab as createKeyValueCanvasPersistence, ac as createLocalStorageCanvasPersistence, ad as defaultCanvasWidth, ae as fitCanvasWidth, af as foldCanvasWindows, ag as isCanvasAction, ah as listCanvasWindowIds, ai as preferredFlowDirection, aj as resolveCanvasLayoutRules, ak as sanitizeCanvasSnapshot, al as selectCanvasKindVisibility, am as shouldStackSplit, an as toPersistableSnapshot, ao as toggleKind } from './toggleKind-BoFnqhzq.cjs';
1
+ import { C as CanvasItemId, a as CanvasWindowId, b as CanvasJson, c as CanvasLayoutNode, d as CanvasPaneId, e as CanvasStoreBinding, f as CanvasState, g as CanvasAction, h as CanvasController, i as CanvasItem, j as CanvasExtraWindow, k as CanvasHistoryEntry, l as CanvasPane, m as canvasWindowOfItem } from './toggleKind-CI2nBjum.cjs';
2
+ export { n as CANVAS_DEFAULT_KEY, o as CANVAS_DEFAULT_WIDTH, p as CANVAS_DESKTOP_LAYOUT_RULES, q as CANVAS_HISTORY_LIMIT, r as CANVAS_KEEP_ALIVE_DEPTH, s as CANVAS_LAUNCHER_KIND, t as CANVAS_MAIN_WINDOW, u as CANVAS_MIN_SPLIT_FRACTION, v as CANVAS_MIN_WIDTH, w as CANVAS_NARROW_WIDTH, x as CANVAS_PANE_MIN_HEIGHT, y as CANVAS_PANE_MIN_WIDTH, z as CANVAS_PHONE_MAX_WIDTH, A as CANVAS_STORAGE_KEY, B as CANVAS_WEB_LAYOUT_RULES, D as CanvasControllerOptions, E as CanvasErrorReport, F as CanvasErrorSink, G as CanvasKeyValueStore, H as CanvasKindVisibility, I as CanvasLayoutRules, J as CanvasNavigateInput, K as CanvasOpenInput, L as CanvasOpenTarget, M as CanvasOrientation, N as CanvasPaneMeasure, O as CanvasPersistencePort, P as CanvasPreferredTarget, Q as CanvasPresentation, R as CanvasPresentationOrientation, S as CanvasRect, T as CanvasSessionAttachReason, U as CanvasSessionDetachReason, V as CanvasSessionEvent, W as CanvasSessionHooks, X as CanvasSplitId, Y as CanvasWindowCloseMode, Z as CanvasWindowFrame, _ as CanvasWindowPorts, $ as ReduxStoreLike, a0 as ToggleKindInput, a1 as bindCanvasToReduxStore, a2 as canvasActions, a3 as canvasOrientation, a4 as canvasPresentation, a5 as canvasReducer, a6 as canvasWindowFrame, a7 as canvasWindowOfPane, a8 as clampDraggedCanvasWidth, a9 as consoleCanvasErrorSink, aa as createCanvasController, ab as createCanvasStore, ac as createInitialCanvasState, ad as createKeyValueCanvasPersistence, ae as createLocalStorageCanvasPersistence, af as defaultCanvasWidth, ag as fitCanvasSplit, ah as fitCanvasSplitSizes, ai as fitCanvasWidth, aj as foldCanvasWindows, ak as isCanvasAction, al as listCanvasWindowIds, am as preferredFlowDirection, an as resolveCanvasLayoutRules, ao as sanitizeCanvasSnapshot, ap as selectCanvasKindVisibility, aq as shouldStackSplit, ar as toPersistableSnapshot, as as toggleKind } from './toggleKind-CI2nBjum.cjs';
3
3
 
4
4
  declare function canvasItemId(kind: string, key: string): CanvasItemId;
5
5
  declare function parseCanvasItemId(id: CanvasItemId): {
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { C as CanvasItemId, a as CanvasWindowId, b as CanvasJson, c as CanvasLayoutNode, d as CanvasPaneId, e as CanvasStoreBinding, f as CanvasState, g as CanvasAction, h as CanvasController, i as CanvasItem, j as CanvasExtraWindow, k as CanvasHistoryEntry, l as CanvasPane, m as canvasWindowOfItem } from './toggleKind-BoFnqhzq.js';
2
- export { n as CANVAS_DEFAULT_KEY, o as CANVAS_DEFAULT_WIDTH, p as CANVAS_DESKTOP_LAYOUT_RULES, q as CANVAS_HISTORY_LIMIT, r as CANVAS_KEEP_ALIVE_DEPTH, s as CANVAS_LAUNCHER_KIND, t as CANVAS_MAIN_WINDOW, u as CANVAS_MIN_SPLIT_FRACTION, v as CANVAS_MIN_WIDTH, w as CANVAS_NARROW_WIDTH, x as CANVAS_PANE_MIN_WIDTH, y as CANVAS_PHONE_MAX_WIDTH, z as CANVAS_STORAGE_KEY, A as CANVAS_WEB_LAYOUT_RULES, B as CanvasControllerOptions, D as CanvasErrorReport, E as CanvasErrorSink, F as CanvasKeyValueStore, G as CanvasKindVisibility, H as CanvasLayoutRules, I as CanvasNavigateInput, J as CanvasOpenInput, K as CanvasOpenTarget, L as CanvasOrientation, M as CanvasPersistencePort, N as CanvasPreferredTarget, O as CanvasPresentation, P as CanvasPresentationOrientation, Q as CanvasRect, R as CanvasSessionAttachReason, S as CanvasSessionDetachReason, T as CanvasSessionEvent, U as CanvasSessionHooks, V as CanvasSplitId, W as CanvasWindowCloseMode, X as CanvasWindowFrame, Y as CanvasWindowPorts, Z as ReduxStoreLike, _ as ToggleKindInput, $ as bindCanvasToReduxStore, a0 as canvasActions, a1 as canvasOrientation, a2 as canvasPresentation, a3 as canvasReducer, a4 as canvasWindowFrame, a5 as canvasWindowOfPane, a6 as clampDraggedCanvasWidth, a7 as consoleCanvasErrorSink, a8 as createCanvasController, a9 as createCanvasStore, aa as createInitialCanvasState, ab as createKeyValueCanvasPersistence, ac as createLocalStorageCanvasPersistence, ad as defaultCanvasWidth, ae as fitCanvasWidth, af as foldCanvasWindows, ag as isCanvasAction, ah as listCanvasWindowIds, ai as preferredFlowDirection, aj as resolveCanvasLayoutRules, ak as sanitizeCanvasSnapshot, al as selectCanvasKindVisibility, am as shouldStackSplit, an as toPersistableSnapshot, ao as toggleKind } from './toggleKind-BoFnqhzq.js';
1
+ import { C as CanvasItemId, a as CanvasWindowId, b as CanvasJson, c as CanvasLayoutNode, d as CanvasPaneId, e as CanvasStoreBinding, f as CanvasState, g as CanvasAction, h as CanvasController, i as CanvasItem, j as CanvasExtraWindow, k as CanvasHistoryEntry, l as CanvasPane, m as canvasWindowOfItem } from './toggleKind-CI2nBjum.js';
2
+ export { n as CANVAS_DEFAULT_KEY, o as CANVAS_DEFAULT_WIDTH, p as CANVAS_DESKTOP_LAYOUT_RULES, q as CANVAS_HISTORY_LIMIT, r as CANVAS_KEEP_ALIVE_DEPTH, s as CANVAS_LAUNCHER_KIND, t as CANVAS_MAIN_WINDOW, u as CANVAS_MIN_SPLIT_FRACTION, v as CANVAS_MIN_WIDTH, w as CANVAS_NARROW_WIDTH, x as CANVAS_PANE_MIN_HEIGHT, y as CANVAS_PANE_MIN_WIDTH, z as CANVAS_PHONE_MAX_WIDTH, A as CANVAS_STORAGE_KEY, B as CANVAS_WEB_LAYOUT_RULES, D as CanvasControllerOptions, E as CanvasErrorReport, F as CanvasErrorSink, G as CanvasKeyValueStore, H as CanvasKindVisibility, I as CanvasLayoutRules, J as CanvasNavigateInput, K as CanvasOpenInput, L as CanvasOpenTarget, M as CanvasOrientation, N as CanvasPaneMeasure, O as CanvasPersistencePort, P as CanvasPreferredTarget, Q as CanvasPresentation, R as CanvasPresentationOrientation, S as CanvasRect, T as CanvasSessionAttachReason, U as CanvasSessionDetachReason, V as CanvasSessionEvent, W as CanvasSessionHooks, X as CanvasSplitId, Y as CanvasWindowCloseMode, Z as CanvasWindowFrame, _ as CanvasWindowPorts, $ as ReduxStoreLike, a0 as ToggleKindInput, a1 as bindCanvasToReduxStore, a2 as canvasActions, a3 as canvasOrientation, a4 as canvasPresentation, a5 as canvasReducer, a6 as canvasWindowFrame, a7 as canvasWindowOfPane, a8 as clampDraggedCanvasWidth, a9 as consoleCanvasErrorSink, aa as createCanvasController, ab as createCanvasStore, ac as createInitialCanvasState, ad as createKeyValueCanvasPersistence, ae as createLocalStorageCanvasPersistence, af as defaultCanvasWidth, ag as fitCanvasSplit, ah as fitCanvasSplitSizes, ai as fitCanvasWidth, aj as foldCanvasWindows, ak as isCanvasAction, al as listCanvasWindowIds, am as preferredFlowDirection, an as resolveCanvasLayoutRules, ao as sanitizeCanvasSnapshot, ap as selectCanvasKindVisibility, aq as shouldStackSplit, ar as toPersistableSnapshot, as as toggleKind } from './toggleKind-CI2nBjum.js';
3
3
 
4
4
  declare function canvasItemId(kind: string, key: string): CanvasItemId;
5
5
  declare function parseCanvasItemId(id: CanvasItemId): {
package/dist/index.js CHANGED
@@ -1018,6 +1018,7 @@ function toPersistableSnapshot(state, isRestorable) {
1018
1018
 
1019
1019
  // src/core/rules.ts
1020
1020
  var CANVAS_PANE_MIN_WIDTH = 280;
1021
+ var CANVAS_PANE_MIN_HEIGHT = 200;
1021
1022
  var CANVAS_WEB_LAYOUT_RULES = {
1022
1023
  defaultWidth: CANVAS_DEFAULT_WIDTH,
1023
1024
  minWidth: CANVAS_MIN_WIDTH,
@@ -1031,7 +1032,10 @@ var CANVAS_WEB_LAYOUT_RULES = {
1031
1032
  sideSplit: 0.5,
1032
1033
  // A pane narrower than this cannot show a header (Back, a readable tab, "+", the menu, close) and a
1033
1034
  // body side by side with another: a split right that would go under it stacks instead.
1034
- paneMinWidth: CANVAS_PANE_MIN_WIDTH
1035
+ paneMinWidth: CANVAS_PANE_MIN_WIDTH,
1036
+ // 2026-10-07 live: Quick Notes / Notifications / Quick Chat stacked in an 800px window left
1037
+ // Notifications its header and one row.
1038
+ paneMinHeight: CANVAS_PANE_MIN_HEIGHT
1035
1039
  };
1036
1040
  var CANVAS_DESKTOP_LAYOUT_RULES = {
1037
1041
  defaultWidth: { fraction: 0.36 },
@@ -1039,7 +1043,8 @@ var CANVAS_DESKTOP_LAYOUT_RULES = {
1039
1043
  centreMinWidth: 520,
1040
1044
  stackSplit: 0.7,
1041
1045
  sideSplit: 0.5,
1042
- paneMinWidth: 360
1046
+ paneMinWidth: 360,
1047
+ paneMinHeight: CANVAS_PANE_MIN_HEIGHT
1043
1048
  };
1044
1049
  var clampFraction = (value, fallback) => Number.isFinite(value) ? Math.min(0.88, Math.max(0.12, value)) : fallback;
1045
1050
  function resolveCanvasLayoutRules(rules) {
@@ -1051,7 +1056,8 @@ function resolveCanvasLayoutRules(rules) {
1051
1056
  centreMinWidth: positive(merged.centreMinWidth, CANVAS_WEB_LAYOUT_RULES.centreMinWidth),
1052
1057
  stackSplit: clampFraction(merged.stackSplit, 0.5),
1053
1058
  sideSplit: clampFraction(merged.sideSplit, 0.5),
1054
- paneMinWidth: positive(merged.paneMinWidth, 0)
1059
+ paneMinWidth: positive(merged.paneMinWidth, 0),
1060
+ paneMinHeight: positive(merged.paneMinHeight, 0)
1055
1061
  };
1056
1062
  }
1057
1063
  function defaultCanvasWidth(rules, region) {
@@ -1070,6 +1076,30 @@ function clampDraggedCanvasWidth(next, region, rules) {
1070
1076
  function shouldStackSplit(width, children, rules) {
1071
1077
  return rules.paneMinWidth > 0 && width > 0 && width < rules.paneMinWidth * children;
1072
1078
  }
1079
+ function fitCanvasSplit(size, orientation, rules) {
1080
+ if (!size || size.width <= 0 || size.height <= 0) return orientation;
1081
+ const sideFits = rules.paneMinWidth <= 0 || size.width >= 2 * rules.paneMinWidth;
1082
+ const stackFits = rules.paneMinHeight <= 0 || size.height >= 2 * rules.paneMinHeight;
1083
+ if (orientation === "horizontal") return sideFits || stackFits ? "horizontal" : null;
1084
+ return stackFits ? "vertical" : sideFits ? "horizontal" : null;
1085
+ }
1086
+ function fitCanvasSplitSizes(sizes, total, mins) {
1087
+ if (!(total > 0) || sizes.length === 0) return [...sizes];
1088
+ const sum = sizes.reduce((a, b) => a + b, 0) || 1;
1089
+ const px = sizes.map((s) => s / sum * total);
1090
+ const floor = mins.map((m) => Number.isFinite(m) && m > 0 ? m : 0);
1091
+ const needed = floor.reduce((a, b) => a + b, 0);
1092
+ if (needed >= total) return needed > 0 ? floor.map((m) => m / needed) : px.map((p) => p / total);
1093
+ const short = px.reduce((acc, p, i) => acc + Math.max(0, (floor[i] ?? 0) - p), 0);
1094
+ if (short <= 0) return px.map((p) => p / total);
1095
+ const spare = px.map((p, i) => Math.max(0, p - (floor[i] ?? 0)));
1096
+ const spareSum = spare.reduce((a, b) => a + b, 0);
1097
+ return px.map((p, i) => {
1098
+ const min = floor[i] ?? 0;
1099
+ if (p <= min) return min / total;
1100
+ return (p - short * (spare[i] ?? 0) / spareSum) / total;
1101
+ });
1102
+ }
1073
1103
 
1074
1104
  // src/core/commands.ts
1075
1105
  var CANVAS_SHORTCUTS = [
@@ -1167,6 +1197,7 @@ function createCanvasController(options) {
1167
1197
  options,
1168
1198
  onError: options.onError ?? consoleCanvasErrorSink,
1169
1199
  rules: resolveCanvasLayoutRules(options.layoutRules),
1200
+ measures: /* @__PURE__ */ new Set(),
1170
1201
  presentations: /* @__PURE__ */ new Map(),
1171
1202
  presentationListeners: /* @__PURE__ */ new Set(),
1172
1203
  views: /* @__PURE__ */ new Map(),
@@ -1187,6 +1218,14 @@ function view(shared, windowId) {
1187
1218
  for (const listener of [...shared.presentationListeners]) listener();
1188
1219
  };
1189
1220
  const shareFor = (orientation) => orientation === "vertical" ? rules.stackSplit : rules.sideSplit;
1221
+ const measurePane = (paneId) => {
1222
+ for (const measure of shared.measures) {
1223
+ const size = measure(paneId);
1224
+ if (size) return size;
1225
+ }
1226
+ return null;
1227
+ };
1228
+ const fitSplit = (paneId, orientation) => fitCanvasSplit(measurePane(paneId), orientation, rules);
1190
1229
  const acceptable = (input) => {
1191
1230
  if (input.kind !== CANVAS_LAUNCHER_KIND && options.isKnownKind && !options.isKnownKind(input.kind)) {
1192
1231
  onError({ code: "unknown-kind", message: `No canvas kind "${input.kind}" is registered.`, detail: input });
@@ -1217,6 +1256,13 @@ function view(shared, windowId) {
1217
1256
  if (holding) return { paneId: holding };
1218
1257
  return state.panes[frame2.focusedPaneId]?.activeItemId ? preferred : "focused";
1219
1258
  };
1259
+ const splitTargetFor = (asked, forWindow) => {
1260
+ const state = store.getState();
1261
+ const frame2 = canvasWindowFrame(state, forWindow ? canvasWindowId(forWindow) : windowId);
1262
+ if (!frame2) return asked;
1263
+ const fitted = fitSplit(frame2.focusedPaneId, asked === "split-down" ? "vertical" : "horizontal");
1264
+ return fitted === null ? "focused" : fitted === "vertical" ? "split-down" : "split-right";
1265
+ };
1220
1266
  const controller = {
1221
1267
  store,
1222
1268
  windowId,
@@ -1225,7 +1271,8 @@ function view(shared, windowId) {
1225
1271
  getState: () => store.getState(),
1226
1272
  open(input) {
1227
1273
  if (!acceptable(input)) return null;
1228
- const target = input.target ?? preferredTargetFor(input);
1274
+ const asked = input.target ?? preferredTargetFor(input);
1275
+ const target = asked === "split-down" || asked === "split-right" ? splitTargetFor(asked, input.windowId) : asked;
1229
1276
  const splitShare = target === "split-down" ? rules.stackSplit : target === "split-right" ? rules.sideSplit : void 0;
1230
1277
  const withTarget = input.target === target ? input : { ...input, target };
1231
1278
  const resolved = withTarget.windowId || windowId === CANVAS_MAIN_WINDOW ? withTarget : { ...withTarget, windowId };
@@ -1290,7 +1337,15 @@ function view(shared, windowId) {
1290
1337
  activate: (itemId) => dispatch(canvasActions.activate(itemId)),
1291
1338
  focusPane: (paneId) => dispatch(canvasActions.focusPane(paneId)),
1292
1339
  moveItem: (itemId, toPaneId, index) => dispatch(canvasActions.moveItem(itemId, toPaneId, index)),
1293
- splitPane: (paneId, orientation, moveItemId) => dispatch(canvasActions.splitPane(paneId, orientation, moveItemId, shareFor(orientation))),
1340
+ splitPane(paneId, orientation, moveItemId) {
1341
+ const fitted = fitSplit(paneId, orientation);
1342
+ if (fitted) dispatch(canvasActions.splitPane(paneId, fitted, moveItemId, shareFor(fitted)));
1343
+ },
1344
+ fitSplit,
1345
+ registerPaneMeasure(measure) {
1346
+ shared.measures.add(measure);
1347
+ return () => void shared.measures.delete(measure);
1348
+ },
1294
1349
  closePane: (paneId) => dispatch(canvasActions.closePane(paneId)),
1295
1350
  resizeSplit: (splitId, sizes) => dispatch(canvasActions.resizeSplit(splitId, sizes)),
1296
1351
  show: (w = windowId) => dispatch(canvasActions.setOpen(true, w)),
@@ -1639,6 +1694,7 @@ export {
1639
1694
  CANVAS_MIN_SPLIT_FRACTION,
1640
1695
  CANVAS_MIN_WIDTH,
1641
1696
  CANVAS_NARROW_WIDTH,
1697
+ CANVAS_PANE_MIN_HEIGHT,
1642
1698
  CANVAS_PANE_MIN_WIDTH,
1643
1699
  CANVAS_PHONE_MAX_WIDTH,
1644
1700
  CANVAS_SHORTCUTS,
@@ -1665,6 +1721,8 @@ export {
1665
1721
  createRemoteCanvasStore,
1666
1722
  defaultCanvasWidth,
1667
1723
  findNonJson,
1724
+ fitCanvasSplit,
1725
+ fitCanvasSplitSizes,
1668
1726
  fitCanvasWidth,
1669
1727
  foldCanvasWindows,
1670
1728
  isCanvasAction,