synabun 2026.4.21 → 2026.4.25-beta.2

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 (61) hide show
  1. package/CHANGELOG.md +175 -881
  2. package/README.md +1 -1
  3. package/hooks/claude-code/prompt-submit.mjs +39 -18
  4. package/hooks/claude-code/session-start.mjs +10 -3
  5. package/hooks/claude-code/shared.mjs +39 -2
  6. package/hooks/claude-code/stop.mjs +33 -6
  7. package/mcp-server/src/index.ts +9 -1
  8. package/mcp-server/src/services/neural-interface.ts +42 -14
  9. package/mcp-server/src/services/profiles.ts +8 -7
  10. package/mcp-server/src/tools/browser-advanced.ts +12 -10
  11. package/mcp-server/src/tools/browser-interact.ts +39 -38
  12. package/mcp-server/src/tools/browser-navigate.ts +12 -4
  13. package/mcp-server/src/tools/loop.ts +7 -3
  14. package/mcp-server/src/tools/profile.ts +19 -1
  15. package/neural-interface/lib/loop-logger.js +103 -0
  16. package/neural-interface/lib/mcp-installer.js +109 -0
  17. package/neural-interface/lib/plugin-installer.js +264 -0
  18. package/neural-interface/package.json +1 -1
  19. package/neural-interface/public/shared/api.js +66 -17
  20. package/neural-interface/public/shared/cdx/cdx-icons.js +5 -4
  21. package/neural-interface/public/shared/cdx/cdx-panel.js +117 -14
  22. package/neural-interface/public/shared/cdx/cdx-render.js +170 -43
  23. package/neural-interface/public/shared/cdx/cdx-styles.js +55 -10
  24. package/neural-interface/public/shared/cdx/cdx-tabs.js +394 -72
  25. package/neural-interface/public/shared/cli-status.js +157 -0
  26. package/neural-interface/public/shared/constants.js +3 -2
  27. package/neural-interface/public/shared/html-shell.js +32 -11
  28. package/neural-interface/public/shared/ocp/ocp-panel.js +127 -28
  29. package/neural-interface/public/shared/ocp/ocp-render.js +52 -44
  30. package/neural-interface/public/shared/ocp/ocp-styles.js +33 -0
  31. package/neural-interface/public/shared/ocp/ocp-tabs.js +693 -82
  32. package/neural-interface/public/shared/styles.css +635 -0
  33. package/neural-interface/public/shared/ui-automation-studio.js +38 -12
  34. package/neural-interface/public/shared/ui-claude-panel.js +322 -15
  35. package/neural-interface/public/shared/ui-file-explorer.js +38 -18
  36. package/neural-interface/public/shared/ui-menubar.js +34 -10
  37. package/neural-interface/public/shared/ui-navbar.js +8 -6
  38. package/neural-interface/public/shared/ui-schedules-studio.js +1464 -0
  39. package/neural-interface/public/shared/ui-settings.js +274 -50
  40. package/neural-interface/public/shared/ui-sidepanel-layout.js +18 -7
  41. package/neural-interface/public/shared/ui-sidepanel-tray.js +287 -0
  42. package/neural-interface/public/shared/ui-sync.js +9 -5
  43. package/neural-interface/public/shared/ui-terminal.js +76 -27
  44. package/neural-interface/public/shared/ui-tool-updates.js +49 -15
  45. package/neural-interface/public/shared/ui-tutorial-steps.js +4 -2
  46. package/neural-interface/public/shared/ui-tutorial.js +24 -18
  47. package/neural-interface/public/shared/ui-whiteboard.js +79 -31
  48. package/neural-interface/public/shared/vterm-buffer.js +9 -8
  49. package/neural-interface/public/variant/2d/main.js +9 -7
  50. package/neural-interface/public/variant/3d/main.js +10 -8
  51. package/neural-interface/server.js +1292 -255
  52. package/package.json +1 -1
  53. package/skills/leonardo/SKILL.md +5 -1
  54. package/skills/leonardo/modules/image-prompter.md +5 -1
  55. package/skills/leonardo/modules/video-prompter.md +5 -1
  56. package/skills/synabun/SKILL.md +44 -26
  57. package/skills/synabun/modules/audit.md +40 -36
  58. package/skills/synabun/modules/changelog.md +22 -18
  59. package/skills/synabun/modules/memorize.md +19 -15
  60. package/skills/synabun/modules/schedule.md +285 -0
  61. package/CLAUDE.md +0 -217
@@ -174,12 +174,14 @@ function _destroyWhiteboardLayers() {
174
174
  // UI HELPERS
175
175
  // ═══════════════════════════════════════════
176
176
 
177
- function _hideStaticBgLogo(hide) {
178
- const logo = document.querySelector('#static-bg .static-bg-logo');
179
- const breathe = document.querySelector('#static-bg .focus-breathe');
180
- if (logo) logo.classList.toggle('tutorial-hidden', hide);
181
- if (breathe) breathe.classList.toggle('tutorial-hidden', hide);
182
- }
177
+ function _hideStaticBgLogo(hide) {
178
+ const logo = document.querySelector('#static-bg .static-bg-logo');
179
+ const breathe = document.querySelector('#static-bg .focus-breathe');
180
+ const rulesetAlert = document.getElementById('wb-ruleset-alert');
181
+ if (logo) logo.classList.toggle('tutorial-hidden', hide);
182
+ if (breathe) breathe.classList.toggle('tutorial-hidden', hide);
183
+ if (rulesetAlert) rulesetAlert.classList.toggle('tutorial-hidden', hide);
184
+ }
183
185
 
184
186
  function _hideWhiteboardToolbar(hide) {
185
187
  const toolbar = document.getElementById('wb-toolbar');
@@ -311,8 +313,9 @@ async function _animateCompletion() {
311
313
  await new Promise(r => setTimeout(r, 400));
312
314
 
313
315
  // ── 2. Reveal logo with scale + fade entrance ──
314
- const logo = document.querySelector('#static-bg .static-bg-logo');
315
- const breathe = document.querySelector('#static-bg .focus-breathe');
316
+ const logo = document.querySelector('#static-bg .static-bg-logo');
317
+ const breathe = document.querySelector('#static-bg .focus-breathe');
318
+ const rulesetAlert = document.getElementById('wb-ruleset-alert');
316
319
 
317
320
  if (logo) {
318
321
  logo.style.transition = 'none';
@@ -324,16 +327,19 @@ async function _animateCompletion() {
324
327
  logo.style.opacity = ''; // back to CSS default (0.18)
325
328
  logo.style.transform = '';
326
329
  }
327
- if (breathe) {
328
- breathe.style.transition = 'none';
329
- breathe.style.opacity = '0';
330
- breathe.classList.remove('tutorial-hidden');
331
- breathe.offsetHeight;
332
- breathe.style.transition = 'opacity 1.2s ease 0.3s';
333
- breathe.style.opacity = '';
334
- }
335
-
336
- // ── 3. Slide toolbar in from left (staggered) ──
330
+ if (breathe) {
331
+ breathe.style.transition = 'none';
332
+ breathe.style.opacity = '0';
333
+ breathe.classList.remove('tutorial-hidden');
334
+ breathe.offsetHeight;
335
+ breathe.style.transition = 'opacity 1.2s ease 0.3s';
336
+ breathe.style.opacity = '';
337
+ }
338
+ if (rulesetAlert) {
339
+ rulesetAlert.classList.remove('tutorial-hidden');
340
+ }
341
+
342
+ // ── 3. Slide toolbar in from left (staggered) ──
337
343
  const toolbar = document.getElementById('wb-toolbar');
338
344
  if (toolbar) {
339
345
  toolbar.style.transition = 'none';
@@ -8,9 +8,10 @@
8
8
  // rounded borders, undo/redo, and full workspace persistence.
9
9
 
10
10
  import { state, emit, on } from './state.js';
11
- import { KEYS } from './constants.js';
12
- import { storage } from './storage.js';
13
- import { isGuest, hasPermission } from './ui-sync.js';
11
+ import { KEYS } from './constants.js';
12
+ import { storage } from './storage.js';
13
+ import { isGuest, hasPermission } from './ui-sync.js';
14
+ import { openSettingsModal } from './ui-settings.js';
14
15
 
15
16
  // ── Helpers ──
16
17
 
@@ -120,7 +121,9 @@ function _snap(v) {
120
121
  const IMAGE_QUALITY = 0.8;
121
122
 
122
123
  // DOM refs (set in init)
123
- let _root, _toolbar, _canvas, _arrowsSvg, _elementsDiv, _arrowPreview, _arrowHint;
124
+ let _root, _toolbar, _canvas, _arrowsSvg, _elementsDiv, _arrowPreview, _arrowHint;
125
+
126
+ const RULESET_SETUP_SECTIONS = ['setup-claude', 'setup-codex', 'setup-opencode'];
124
127
 
125
128
 
126
129
  // ═══════════════════════════════════════════
@@ -210,12 +213,50 @@ function redo() {
210
213
  updateUndoButtons();
211
214
  }
212
215
 
213
- function updateUndoButtons() {
214
- const undoBtn = $('wb-undo');
215
- const redoBtn = $('wb-redo');
216
- if (undoBtn) undoBtn.classList.toggle('disabled', !_undoStack.length);
217
- if (redoBtn) redoBtn.classList.toggle('disabled', !_redoStack.length);
218
- }
216
+ function updateUndoButtons() {
217
+ const undoBtn = $('wb-undo');
218
+ const redoBtn = $('wb-redo');
219
+ if (undoBtn) undoBtn.classList.toggle('disabled', !_undoStack.length);
220
+ if (redoBtn) redoBtn.classList.toggle('disabled', !_redoStack.length);
221
+ }
222
+
223
+ function isRulesetAlertDismissed() {
224
+ return storage.getItem(KEYS.WHITEBOARD_RULESET_ALERT_DISMISSED) === '1';
225
+ }
226
+
227
+ function syncRulesetAlertVisibility() {
228
+ const alert = $('wb-ruleset-alert');
229
+ if (!alert) return;
230
+ const logo = document.querySelector('#static-bg .static-bg-logo');
231
+ const logoHidden = logo?.style.display === 'none';
232
+ alert.classList.toggle('hidden', isRulesetAlertDismissed() || logoHidden);
233
+ }
234
+
235
+ function initRulesetAlert() {
236
+ const alert = $('wb-ruleset-alert');
237
+ if (!alert) return;
238
+
239
+ const setupBtn = $('wb-ruleset-settings');
240
+ const dismissBtn = $('wb-ruleset-dismiss');
241
+
242
+ setupBtn?.addEventListener('click', (e) => {
243
+ e.stopPropagation();
244
+ openSettingsModal({
245
+ tab: 'setup',
246
+ expand: RULESET_SETUP_SECTIONS,
247
+ highlight: RULESET_SETUP_SECTIONS,
248
+ scrollTo: 'setup-claude-ruleset-preview',
249
+ });
250
+ });
251
+
252
+ dismissBtn?.addEventListener('click', (e) => {
253
+ e.stopPropagation();
254
+ storage.setItem(KEYS.WHITEBOARD_RULESET_ALERT_DISMISSED, '1');
255
+ syncRulesetAlertVisibility();
256
+ });
257
+
258
+ syncRulesetAlertVisibility();
259
+ }
219
260
 
220
261
 
221
262
  // ═══════════════════════════════════════════
@@ -2754,13 +2795,14 @@ function onToolbarClick(e) {
2754
2795
  const logo = document.querySelector('#static-bg .static-bg-logo');
2755
2796
  const breathe = document.querySelector('#static-bg .focus-breathe');
2756
2797
  const hidden = logo?.style.display !== 'none';
2757
- if (logo) logo.style.display = hidden ? 'none' : '';
2758
- if (breathe) breathe.style.display = hidden ? 'none' : '';
2759
- btn.classList.toggle('active', hidden);
2760
- sessionStorage.setItem('wb-logo-hidden', hidden ? '1' : '');
2761
- return;
2762
- }
2763
- }
2798
+ if (logo) logo.style.display = hidden ? 'none' : '';
2799
+ if (breathe) breathe.style.display = hidden ? 'none' : '';
2800
+ btn.classList.toggle('active', hidden);
2801
+ sessionStorage.setItem('wb-logo-hidden', hidden ? '1' : '');
2802
+ syncRulesetAlertVisibility();
2803
+ return;
2804
+ }
2805
+ }
2764
2806
 
2765
2807
 
2766
2808
  // ═══════════════════════════════════════════
@@ -2910,14 +2952,17 @@ export function initWhiteboard() {
2910
2952
  // Toolbar
2911
2953
  if (_toolbar) _toolbar.addEventListener('click', onToolbarClick);
2912
2954
 
2913
- // Color picker
2914
- initColorPicker();
2915
-
2916
- // Shape picker
2917
- initShapePicker();
2918
-
2919
- // Section picker
2920
- initSectionPicker();
2955
+ // Color picker
2956
+ initColorPicker();
2957
+
2958
+ // Shape picker
2959
+ initShapePicker();
2960
+
2961
+ // Section picker
2962
+ initSectionPicker();
2963
+
2964
+ // Logo-adjacent ruleset reminder
2965
+ initRulesetAlert();
2921
2966
 
2922
2967
  // Prevent context menu on whiteboard
2923
2968
  _root.addEventListener('contextmenu', e => e.preventDefault());
@@ -2933,12 +2978,15 @@ export function initWhiteboard() {
2933
2978
  if (sessionStorage.getItem('wb-logo-hidden') === '1') {
2934
2979
  const logo = document.querySelector('#static-bg .static-bg-logo');
2935
2980
  const breathe = document.querySelector('#static-bg .focus-breathe');
2936
- if (logo) logo.style.display = 'none';
2937
- if (breathe) breathe.style.display = 'none';
2938
- const btn = document.getElementById('wb-toggle-logo');
2939
- if (btn) btn.classList.add('active');
2940
- }
2941
- });
2981
+ if (logo) logo.style.display = 'none';
2982
+ if (breathe) breathe.style.display = 'none';
2983
+ syncRulesetAlertVisibility();
2984
+ const btn = document.getElementById('wb-toggle-logo');
2985
+ if (btn) btn.classList.add('active');
2986
+ } else {
2987
+ syncRulesetAlertVisibility();
2988
+ }
2989
+ });
2942
2990
 
2943
2991
  // Connect to server for external commands (Claude MCP)
2944
2992
  _connectWhiteboardWS();
@@ -114,7 +114,7 @@ export class VTermBuffer {
114
114
  * @param {number} cols
115
115
  * @param {number} rows
116
116
  */
117
- constructor(cols, rows) {
117
+ constructor(cols, rows, maxScrollback = MAX_SCROLLBACK) {
118
118
  this.cols = cols;
119
119
  this.rows = rows;
120
120
 
@@ -130,7 +130,7 @@ export class VTermBuffer {
130
130
  this._buffer = this._mainBuffer;
131
131
 
132
132
  // Scrollback (main buffer only) — circular buffer for O(1) operations
133
- this._scrollback = new CircularBuffer(MAX_SCROLLBACK);
133
+ this._scrollback = new CircularBuffer(maxScrollback);
134
134
 
135
135
  // Cursor state
136
136
  this._cursorX = 0;
@@ -218,12 +218,13 @@ export class VTermBuffer {
218
218
  this._allDirty = false;
219
219
  }
220
220
 
221
- get cursorX() { return this._cursorX; }
222
- get cursorY() { return this._cursorY; }
223
- get cursorVisible() { return this._cursorVisible; }
224
- get title() { return this._title; }
225
- get bracketedPaste() { return this._bracketedPaste; }
226
- get appCursorKeys() { return this._appCursorKeys; }
221
+ get cursorX() { return this._cursorX; }
222
+ get cursorY() { return this._cursorY; }
223
+ get cursorVisible() { return this._cursorVisible; }
224
+ get useAltBuffer() { return this._useAlt; }
225
+ get title() { return this._title; }
226
+ get bracketedPaste() { return this._bracketedPaste; }
227
+ get appCursorKeys() { return this._appCursorKeys; }
227
228
 
228
229
  /** Resize the terminal */
229
230
  resize(cols, rows) {
@@ -51,9 +51,10 @@ import { initImageGallery } from '../../shared/ui-image-gallery.js';
51
51
 
52
52
  // ── 2D variant modules ──
53
53
  import { gfx, saveGfxConfig } from './gfx.js';
54
- import './settings-gfx.js'; // side-effect: self-registers Graphics tab
55
- import { initAutomationStudio } from '../../shared/ui-automation-studio.js';
56
- import { initCommandRunner } from '../../shared/ui-command-runner.js';
54
+ import './settings-gfx.js'; // side-effect: self-registers Graphics tab
55
+ import { initAutomationStudio } from '../../shared/ui-automation-studio.js';
56
+ import { initSchedulesStudio } from '../../shared/ui-schedules-studio.js';
57
+ import { initCommandRunner } from '../../shared/ui-command-runner.js';
57
58
  import { stopBackground } from './background.js';
58
59
  import { initMinimap, drawMinimap, toggleMinimap, isMinimapVisible, forceHideMinimap, restoreMinimap } from './minimap.js';
59
60
  import { initLasso, clearLasso } from './lasso.js';
@@ -419,10 +420,11 @@ initHelp();
419
420
  initMultiSelect();
420
421
  initStats();
421
422
  initExplorer();
422
- initFileExplorer();
423
- initSkillsStudio();
424
- initAutomationStudio();
425
- initImageGallery();
423
+ initFileExplorer();
424
+ initSkillsStudio();
425
+ initAutomationStudio();
426
+ initSchedulesStudio();
427
+ initImageGallery();
426
428
  initCommandRunner();
427
429
  initTerminal();
428
430
  initLink();
@@ -50,10 +50,11 @@ import { initTutorial } from '../../shared/ui-tutorial.js';
50
50
  import { initImageGallery } from '../../shared/ui-image-gallery.js';
51
51
 
52
52
  // ── 3D variant modules ──
53
- import { gfx } from './gfx.js';
54
- import { setGraphicsHooks } from './settings-gfx.js';
55
- import { initAutomationStudio } from '../../shared/ui-automation-studio.js';
56
- import { initCommandRunner } from '../../shared/ui-command-runner.js';
53
+ import { gfx } from './gfx.js';
54
+ import { setGraphicsHooks } from './settings-gfx.js';
55
+ import { initAutomationStudio } from '../../shared/ui-automation-studio.js';
56
+ import { initSchedulesStudio } from '../../shared/ui-schedules-studio.js';
57
+ import { initCommandRunner } from '../../shared/ui-command-runner.js';
57
58
  import { initCamera, updateCameraMovement, animateCameraToNode, frameCameraToExtent, saveCameraState, restoreCameraState, pauseCamera, resumeCamera } from './camera.js';
58
59
  import { applyFloorStyle, applyBgTheme, animateBackground } from './background.js';
59
60
  import {
@@ -405,10 +406,11 @@ initHelp();
405
406
  initMultiSelect();
406
407
  initStats();
407
408
  initExplorer();
408
- initFileExplorer();
409
- initSkillsStudio();
410
- initAutomationStudio();
411
- initImageGallery();
409
+ initFileExplorer();
410
+ initSkillsStudio();
411
+ initAutomationStudio();
412
+ initSchedulesStudio();
413
+ initImageGallery();
412
414
  initCommandRunner();
413
415
  initTerminal();
414
416
  initLink();