synabun 2026.4.26-beta.10 → 2026.4.26-beta.11

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.
@@ -5094,15 +5094,51 @@
5094
5094
  }
5095
5095
  .update-backup-btn:hover { background: rgba(52,199,89,0.16); }
5096
5096
  .update-backup-btn:disabled { opacity: 0.5; pointer-events: none; }
5097
- .update-backup-status {
5098
- display: flex;
5099
- align-items: center;
5100
- gap: 8px;
5097
+ .update-backup-status {
5098
+ display: flex;
5099
+ align-items: center;
5100
+ gap: 8px;
5101
5101
  font-size: 11px;
5102
5102
  color: var(--t-muted);
5103
- padding: 4px 0;
5104
- }
5105
- .update-backup-icon { font-size: 14px; font-weight: 700; }
5103
+ padding: 4px 0;
5104
+ }
5105
+ .update-run-status {
5106
+ align-items: flex-start;
5107
+ gap: 10px;
5108
+ padding: 10px 12px;
5109
+ border-radius: var(--r-card);
5110
+ border: 1px solid rgba(255,255,255,0.08);
5111
+ background: rgba(255,255,255,0.045);
5112
+ color: var(--t-secondary);
5113
+ font-size: 12px;
5114
+ line-height: 1.4;
5115
+ }
5116
+ .update-run-status .update-backup-icon {
5117
+ flex: 0 0 auto;
5118
+ margin-top: 1px;
5119
+ }
5120
+ .update-run-status strong {
5121
+ display: block;
5122
+ color: var(--t-primary);
5123
+ font-size: 12px;
5124
+ font-weight: 600;
5125
+ margin-bottom: 2px;
5126
+ }
5127
+ .update-run-detail,
5128
+ .update-run-hint {
5129
+ display: block;
5130
+ color: var(--t-muted);
5131
+ }
5132
+ .update-run-hint {
5133
+ margin-top: 5px;
5134
+ opacity: .82;
5135
+ }
5136
+ .update-run-status code {
5137
+ font-family: var(--ff-mono);
5138
+ font-size: 11px;
5139
+ color: var(--t-secondary);
5140
+ }
5141
+ .update-backup-icon { font-size: 14px; font-weight: 700; }
5106
5142
  .update-backup-icon.spin { animation: updateSpin 1s linear infinite; }
5107
5143
  @keyframes updateSpin {
5108
5144
  from { transform: rotate(0deg); }
@@ -7,6 +7,7 @@
7
7
  import { showUpdateToast } from './ui-tool-updates.js';
8
8
 
9
9
  const $ = (id) => document.getElementById(id);
10
+ const SYNABUN_GITHUB_URL = 'https://github.com/danilokhury/Synabun';
10
11
 
11
12
  let _versionData = null;
12
13
  let _btnWired = false;
@@ -187,27 +188,37 @@ function openUpdateModal() {
187
188
 
188
189
  function renderStep3() {
189
190
  const installPlan = _versionData.installPlan || {};
190
- const canAutoUpdate = installPlan.canAutoUpdate !== false;
191
- const installCmd = installPlan.displayCommand || 'npm i -g synabun@latest';
191
+ const canAutoUpdate = installPlan.canAutoUpdate === true;
192
+ const repoUrl = installPlan.openUrl || SYNABUN_GITHUB_URL;
193
+ const installCmd = canAutoUpdate
194
+ ? (installPlan.displayCommand || 'npm i -g synabun@latest')
195
+ : repoUrl;
192
196
  const installIntro = canAutoUpdate
193
197
  ? 'SynaBun will close and run this command in a new terminal window:'
194
- : 'GitHub clone detected. Run this command from your cloned SynaBun repository:';
198
+ : 'This SynaBun install was not detected as an npm install. Open the GitHub repository to update from your checkout or installer:';
199
+ const title = canAutoUpdate ? 'Run the Update' : 'Update from GitHub';
195
200
  const installSource = canAutoUpdate
196
201
  ? 'Installing from npm.'
197
- : (installPlan.manualHint || 'Restart SynaBun after the GitHub clone update finishes.');
202
+ : (installPlan.manualHint || 'Open the SynaBun repository for the correct update path.');
198
203
  const autoRestartControl = canAutoUpdate ? `
199
204
  <label class="update-skip-label" style="margin:14px 0 8px;display:flex;align-items:center;gap:8px;cursor:pointer">
200
205
  <input type="checkbox" id="update-auto-restart" checked>
201
206
  <span>Relaunch SynaBun after update</span>
202
207
  </label>` : '';
208
+ const manualButton = canAutoUpdate ? `
209
+ <button class="action-btn action-btn--ghost" id="update-manual" title="Run the command yourself in your own terminal">Manual</button>` : '';
203
210
  const updateNowButton = canAutoUpdate ? `
204
211
  <button class="action-btn action-btn--primary" id="update-run-now">
205
212
  <svg viewBox="0 0 24 24" width="13" height="13" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" style="vertical-align:-2px;margin-right:6px"><polyline points="8 17 12 21 16 17"/><line x1="12" y1="12" x2="12" y2="21"/><path d="M20.88 18.09A5 5 0 0 0 18 9h-1.26A8 8 0 1 0 3 16.29"/></svg>
206
213
  Update Now
207
- </button>` : '';
214
+ </button>` : `
215
+ <button class="action-btn action-btn--primary" id="update-run-now" data-url="${esc(repoUrl)}">
216
+ <svg viewBox="0 0 24 24" width="13" height="13" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" style="vertical-align:-2px;margin-right:6px"><path d="M15 3h6v6"/><path d="M10 14 21 3"/><path d="M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6"/></svg>
217
+ Open GitHub
218
+ </button>`;
208
219
 
209
220
  return `
210
- <h3 class="update-modal-title">Run the Update</h3>
221
+ <h3 class="update-modal-title">${title}</h3>
211
222
  <p style="font-size:12px;color:var(--t-muted);margin:4px 0 12px">
212
223
  ${esc(installIntro)}
213
224
  </p>
@@ -227,12 +238,12 @@ function openUpdateModal() {
227
238
 
228
239
  <div class="tag-delete-modal-actions" style="margin-top:14px;flex-wrap:wrap;gap:8px">
229
240
  <button class="action-btn action-btn--ghost" id="update-back">Back</button>
230
- <button class="action-btn action-btn--ghost" id="update-manual" title="Run the command yourself in your own terminal">Manual</button>
241
+ ${manualButton}
231
242
  ${updateNowButton}
232
243
  </div>
233
244
 
234
245
  <p id="update-manual-note" style="display:none;font-size:11px;color:var(--t-muted);opacity:.75;margin:10px 0 0">
235
- After running the command, restart SynaBun: <code>synabun</code>
246
+ After running the command, restart SynaBun with <code>synabun</code>.
236
247
  </p>`;
237
248
  }
238
249
 
@@ -298,7 +309,9 @@ function openUpdateModal() {
298
309
  }
299
310
 
300
311
  async function handleRunUpdate() {
301
- if (_versionData?.installPlan?.canAutoUpdate === false) return;
312
+ const installPlan = _versionData?.installPlan || {};
313
+ const canAutoUpdate = installPlan.canAutoUpdate === true;
314
+ const repoUrl = installPlan.openUrl || SYNABUN_GITHUB_URL;
302
315
 
303
316
  const autoRestartCb = overlay.querySelector('#update-auto-restart');
304
317
  const autoRestart = !!autoRestartCb?.checked;
@@ -310,16 +323,27 @@ function openUpdateModal() {
310
323
  const icon = overlay.querySelector('#update-run-icon');
311
324
  const text = overlay.querySelector('#update-run-text');
312
325
 
313
- if (!runBtn || !backBtn || !manualBtn || !status || !icon || !text) return;
326
+ if (!runBtn || !backBtn || !status || !icon || !text) return;
327
+
328
+ if (!canAutoUpdate) {
329
+ window.open(repoUrl, '_blank', 'noopener,noreferrer');
330
+ status.style.display = 'flex';
331
+ icon.className = 'update-backup-icon';
332
+ icon.textContent = '↗';
333
+ icon.style.color = '#4fc3f7';
334
+ text.innerHTML = `<strong>GitHub repository opened</strong><span class="update-run-detail">Use the repository instructions to update this non-npm installation.</span>`;
335
+ return;
336
+ }
314
337
 
315
338
  runBtn.disabled = true;
316
339
  backBtn.disabled = true;
317
- manualBtn.disabled = true;
340
+ if (manualBtn) manualBtn.disabled = true;
318
341
  runBtn.innerHTML = '<span class="update-spinner"></span> Launching updater...';
319
342
  status.style.display = 'flex';
320
343
  icon.className = 'update-backup-icon spin';
321
344
  icon.textContent = '⟳';
322
- text.textContent = 'Opening updater terminal and shutting down server...';
345
+ icon.style.color = '';
346
+ text.innerHTML = '<strong>Launching updater</strong><span class="update-run-detail">Opening a terminal window for the npm update.</span>';
323
347
 
324
348
  try {
325
349
  const res = await fetch('/api/system/run-update', {
@@ -332,12 +356,12 @@ function openUpdateModal() {
332
356
  try { const b = await res.json(); msg = b.error || msg; } catch {}
333
357
  throw new Error(msg);
334
358
  }
335
- const body = await res.json();
359
+ await res.json();
336
360
 
337
361
  icon.className = 'update-backup-icon';
338
362
  icon.textContent = '✓';
339
363
  icon.style.color = '#34c759';
340
- text.innerHTML = `Updater terminal launched. <strong>This window will go offline.</strong> Watch the new terminal for install progress${autoRestart ? ' — SynaBun relaunches when done.' : '. Run <code>synabun</code> after install completes.'}`;
364
+ text.innerHTML = `<strong>Updater terminal launched</strong><span class="update-run-detail">SynaBun is shutting down so npm can replace the package. Watch the terminal for install progress${autoRestart ? '; SynaBun will relaunch when it finishes.' : '; run <code>synabun</code> when it finishes.'}</span><span class="update-run-hint">If no terminal window appears, run <code>${esc(installPlan.displayCommand || 'npm i -g synabun@latest')}</code> manually.</span>`;
341
365
  runBtn.innerHTML = 'Updater running…';
342
366
 
343
367
  // Server is shutting down. Optionally redirect to a friendly offline
@@ -351,7 +375,7 @@ function openUpdateModal() {
351
375
  text.textContent = 'Failed to launch updater: ' + err.message;
352
376
  runBtn.disabled = false;
353
377
  backBtn.disabled = false;
354
- manualBtn.disabled = false;
378
+ if (manualBtn) manualBtn.disabled = false;
355
379
  runBtn.innerHTML = `<svg viewBox="0 0 24 24" width="13" height="13" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" style="vertical-align:-2px;margin-right:6px"><polyline points="8 17 12 21 16 17"/><line x1="12" y1="12" x2="12" y2="21"/><path d="M20.88 18.09A5 5 0 0 0 18 9h-1.26A8 8 0 1 0 3 16.29"/></svg> Retry`;
356
380
  }
357
381
  }
@@ -1750,8 +1750,9 @@ app.post('/api/system/run-update', async (req, res) => {
1750
1750
  }
1751
1751
  if (installPlan.canAutoUpdate === false) {
1752
1752
  return res.status(409).json({
1753
- error: installPlan.manualHint || `This installation cannot be auto-updated. Run manually: ${installPlan.displayCommand}`,
1753
+ error: installPlan.manualHint || `This installation cannot be auto-updated. Open ${installPlan.openUrl || SYNABUN_GITHUB_REPO_URL}`,
1754
1754
  installPlan,
1755
+ openUrl: installPlan.openUrl || SYNABUN_GITHUB_REPO_URL,
1755
1756
  });
1756
1757
  }
1757
1758
  if (!installPlan.installSpec) {
@@ -1765,14 +1766,14 @@ app.post('/api/system/run-update', async (req, res) => {
1765
1766
  let spawned = null;
1766
1767
  let launchError = null;
1767
1768
 
1768
- if (plat === 'win32') {
1769
- try {
1770
- spawned = spawn('powershell.exe', [
1771
- '-NoProfile',
1772
- '-ExecutionPolicy', 'Bypass',
1773
- '-Command',
1774
- '$p=$env:SYNABUN_UPDATER_RUNNER; $w=$env:SYNABUN_UPDATER_CWD; Start-Process -FilePath $p -WorkingDirectory $w -WindowStyle Normal',
1775
- ], {
1769
+ if (plat === 'win32') {
1770
+ try {
1771
+ spawned = spawn('powershell.exe', [
1772
+ '-NoProfile',
1773
+ '-ExecutionPolicy', 'Bypass',
1774
+ '-Command',
1775
+ '$p=$env:SYNABUN_UPDATER_RUNNER; $w=$env:SYNABUN_UPDATER_CWD; $cmd=$env:ComSpec; if (-not $cmd) { $cmd="cmd.exe" }; Start-Process -FilePath $cmd -ArgumentList @("/k", "`"$p`"") -WorkingDirectory $w -WindowStyle Normal',
1776
+ ], {
1776
1777
  cwd: staged.stageDir,
1777
1778
  shell: false,
1778
1779
  detached: true,
@@ -10433,7 +10434,7 @@ app.post('/api/search/memories', async (req, res) => {
10433
10434
  // when EITHER source is newer than the installed version (catches one-sided
10434
10435
  // publishes — e.g. release tagged on GitHub before npm publish completes).
10435
10436
 
10436
- let _synabunUpdateCache = {
10437
+ let _synabunUpdateCache = {
10437
10438
  current: null,
10438
10439
  installedChannel: 'stable', // 'stable' | 'prerelease'
10439
10440
  npmLatestStable: null, // dist-tags.latest
@@ -10447,12 +10448,14 @@ let _synabunUpdateCache = {
10447
10448
  gitUpdateAvailable: false,
10448
10449
  updateAvailable: false, // npmUpdateAvailable || gitUpdateAvailable
10449
10450
  source: null, // 'npm' | 'github' | 'both' | null
10450
- installPlan: null, // server-owned npm install target for click-to-update
10451
+ installPlan: null, // server-owned npm/GitHub action target for click-to-update
10451
10452
  checkedAt: null,
10452
10453
  npmError: null,
10453
- gitError: null,
10454
- };
10455
-
10454
+ gitError: null,
10455
+ };
10456
+
10457
+ const SYNABUN_GITHUB_REPO_URL = 'https://github.com/danilokhury/Synabun';
10458
+
10456
10459
  function isSynabunGitHubRemote(remoteText) {
10457
10460
  return /github\.com[:/]danilokhury\/Synabun(?:\.git)?(?:[\s)]|$)/i.test(String(remoteText || ''));
10458
10461
  }
@@ -10504,17 +10507,21 @@ function buildSynabunInstallPlan({ current, installedChannel, latest, updateAvai
10504
10507
  if (!updateAvailable) return null;
10505
10508
 
10506
10509
  const installSource = detectSynabunInstallSource();
10507
- if (installSource.kind === 'github-clone') {
10510
+ if (installSource.kind !== 'npm-global') {
10511
+ const clonedHint = installSource.kind === 'github-clone'
10512
+ ? 'This SynaBun install is a GitHub checkout. Open the repository to pull or reinstall from the correct source.'
10513
+ : 'This SynaBun install was not detected as npm. Open the repository for the correct update path.';
10508
10514
  return {
10509
- source: 'github-clone',
10515
+ source: 'github',
10510
10516
  installSource: installSource.kind,
10511
10517
  canAutoUpdate: false,
10512
10518
  current,
10513
10519
  target: latest,
10514
10520
  channel: installedChannel,
10515
- displayCommand: 'git pull --ff-only',
10516
- manualCommand: 'git pull --ff-only',
10517
- manualHint: 'GitHub clone detected. Run this from your cloned SynaBun repository, then restart SynaBun.',
10521
+ displayCommand: SYNABUN_GITHUB_REPO_URL,
10522
+ openUrl: SYNABUN_GITHUB_REPO_URL,
10523
+ manualCommand: installSource.kind === 'github-clone' ? 'git pull --ff-only' : null,
10524
+ manualHint: clonedHint,
10518
10525
  remote: installSource.remote,
10519
10526
  };
10520
10527
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "synabun",
3
- "version": "2026.4.26-beta.10",
3
+ "version": "2026.4.26-beta.11",
4
4
  "description": "Persistent vector memory for AI assistants",
5
5
  "license": "Apache-2.0",
6
6
  "author": "The SynaBun Authors",