vibora 2.7.0 → 2.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.html CHANGED
@@ -5,8 +5,8 @@
5
5
  <link rel="icon" type="image/jpeg" href="/logo-dark.jpg" />
6
6
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
7
7
  <title>Vibora</title>
8
- <script type="module" crossorigin src="/assets/index-BX0fUoBb.js"></script>
9
- <link rel="stylesheet" crossorigin href="/assets/index-CWnf8iCM.css">
8
+ <script type="module" crossorigin src="/assets/index-CD2MTwMA.js"></script>
9
+ <link rel="stylesheet" crossorigin href="/assets/index-CBg95boU.css">
10
10
  </head>
11
11
  <body>
12
12
  <div id="root"></div>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vibora",
3
- "version": "2.7.0",
3
+ "version": "2.9.0",
4
4
  "description": "The Vibe Engineer's Cockpit",
5
5
  "license": "PolyForm-Shield-1.0.0",
6
6
  "repository": {
package/server/index.js CHANGED
@@ -21701,7 +21701,7 @@ var terminalWebSocketHandlers = {
21701
21701
  const tabManager2 = getTabManager();
21702
21702
  switch (message.type) {
21703
21703
  case "terminal:create": {
21704
- const { name, cols, rows, cwd, tabId, positionInTab } = message.payload;
21704
+ const { name, cols, rows, cwd, tabId, positionInTab, requestId, tempId } = message.payload;
21705
21705
  let effectiveCwd = cwd;
21706
21706
  if (tabId && !cwd) {
21707
21707
  const tab = tabManager2.get(tabId);
@@ -21709,15 +21709,15 @@ var terminalWebSocketHandlers = {
21709
21709
  effectiveCwd = tab.directory;
21710
21710
  }
21711
21711
  }
21712
- log2.ws.debug("terminal:create request", { name, cwd: effectiveCwd, tabId, clientId: clientData.id });
21712
+ log2.ws.debug("terminal:create request", { name, cwd: effectiveCwd, tabId, clientId: clientData.id, requestId, tempId });
21713
21713
  if (effectiveCwd && !tabId) {
21714
21714
  const existing = ptyManager2.listTerminals().find((t) => t.cwd === effectiveCwd && !t.tabId);
21715
21715
  if (existing) {
21716
- log2.ws.debug("terminal:create returning existing", { terminalId: existing.id, isNew: false });
21716
+ log2.ws.debug("terminal:create returning existing", { terminalId: existing.id, isNew: false, requestId, tempId });
21717
21717
  clientData.attachedTerminals.add(existing.id);
21718
21718
  sendTo(ws, {
21719
21719
  type: "terminal:created",
21720
- payload: { terminal: existing, isNew: false }
21720
+ payload: { terminal: existing, isNew: false, requestId, tempId }
21721
21721
  });
21722
21722
  break;
21723
21723
  }
@@ -21727,7 +21727,9 @@ var terminalWebSocketHandlers = {
21727
21727
  terminalId: terminal.id,
21728
21728
  name,
21729
21729
  cwd,
21730
- clientId: clientData.id
21730
+ clientId: clientData.id,
21731
+ requestId,
21732
+ tempId
21731
21733
  });
21732
21734
  clientData.attachedTerminals.add(terminal.id);
21733
21735
  log2.ws.info("terminal:create added to attachedTerminals", {
@@ -21737,16 +21739,46 @@ var terminalWebSocketHandlers = {
21737
21739
  });
21738
21740
  broadcast({
21739
21741
  type: "terminal:created",
21740
- payload: { terminal, isNew: true }
21742
+ payload: { terminal, isNew: true, requestId, tempId }
21741
21743
  });
21742
21744
  break;
21743
21745
  }
21744
21746
  case "terminal:destroy": {
21745
- log2.ws.info("terminal:destroy received", {
21746
- terminalId: message.payload.terminalId,
21747
- clientId: clientData.id
21747
+ const { terminalId, force, reason } = message.payload;
21748
+ const terminalInfo = ptyManager2.getInfo(terminalId);
21749
+ if (terminalInfo?.tabId && !force) {
21750
+ log2.ws.warn("terminal:destroy BLOCKED - tab terminal requires force flag", {
21751
+ terminalId,
21752
+ tabId: terminalInfo.tabId,
21753
+ name: terminalInfo.name,
21754
+ clientId: clientData.id,
21755
+ reason
21756
+ });
21757
+ sendTo(ws, {
21758
+ type: "terminal:error",
21759
+ payload: {
21760
+ terminalId,
21761
+ error: "Tab terminals require explicit force flag to destroy"
21762
+ }
21763
+ });
21764
+ break;
21765
+ }
21766
+ log2.ws.info("terminal:destroy EXECUTING", {
21767
+ terminalId,
21768
+ name: terminalInfo?.name,
21769
+ cwd: terminalInfo?.cwd,
21770
+ tabId: terminalInfo?.tabId,
21771
+ clientId: clientData.id,
21772
+ reason: reason ?? "unspecified",
21773
+ force: force ?? false
21748
21774
  });
21749
- ptyManager2.destroy(message.payload.terminalId);
21775
+ const destroyed = ptyManager2.destroy(terminalId);
21776
+ if (destroyed) {
21777
+ broadcast({
21778
+ type: "terminal:destroyed",
21779
+ payload: { terminalId }
21780
+ });
21781
+ }
21750
21782
  break;
21751
21783
  }
21752
21784
  case "terminal:input": {
@@ -21788,13 +21820,21 @@ var terminalWebSocketHandlers = {
21788
21820
  break;
21789
21821
  }
21790
21822
  case "terminal:rename": {
21791
- const success = ptyManager2.rename(message.payload.terminalId, message.payload.name);
21823
+ const { terminalId, name } = message.payload;
21824
+ const success = ptyManager2.rename(terminalId, name);
21792
21825
  if (success) {
21793
21826
  broadcast({
21794
21827
  type: "terminal:renamed",
21828
+ payload: { terminalId, name }
21829
+ });
21830
+ } else {
21831
+ log2.ws.warn("terminal:rename failed - terminal not found", { terminalId, clientId: clientData.id });
21832
+ sendTo(ws, {
21833
+ type: "sync:stale",
21795
21834
  payload: {
21796
- terminalId: message.payload.terminalId,
21797
- name: message.payload.name
21835
+ entityType: "terminal",
21836
+ entityId: terminalId,
21837
+ error: `Terminal ${terminalId} not found`
21798
21838
  }
21799
21839
  });
21800
21840
  }
@@ -21813,6 +21853,16 @@ var terminalWebSocketHandlers = {
21813
21853
  positionInTab: info?.positionInTab ?? 0
21814
21854
  }
21815
21855
  });
21856
+ } else {
21857
+ log2.ws.warn("terminal:assignTab failed", { terminalId, tabId, clientId: clientData.id });
21858
+ sendTo(ws, {
21859
+ type: "sync:stale",
21860
+ payload: {
21861
+ entityType: "terminal",
21862
+ entityId: terminalId,
21863
+ error: `Terminal ${terminalId} or tab ${tabId} not found`
21864
+ }
21865
+ });
21816
21866
  }
21817
21867
  break;
21818
21868
  }
@@ -21828,13 +21878,13 @@ var terminalWebSocketHandlers = {
21828
21878
  break;
21829
21879
  }
21830
21880
  case "tab:create": {
21831
- const { name, position, directory } = message.payload;
21832
- log2.ws.debug("tab:create request", { name, position, directory, clientId: clientData.id });
21881
+ const { name, position, directory, requestId, tempId } = message.payload;
21882
+ log2.ws.debug("tab:create request", { name, position, directory, clientId: clientData.id, requestId, tempId });
21833
21883
  const tab = tabManager2.create({ name, position, directory });
21834
- log2.ws.info("tab:create created", { tabId: tab.id, name: tab.name, directory: tab.directory });
21884
+ log2.ws.info("tab:create created", { tabId: tab.id, name: tab.name, directory: tab.directory, requestId, tempId });
21835
21885
  broadcast({
21836
21886
  type: "tab:created",
21837
- payload: { tab }
21887
+ payload: { tab, requestId, tempId }
21838
21888
  });
21839
21889
  break;
21840
21890
  }
@@ -21846,13 +21896,51 @@ var terminalWebSocketHandlers = {
21846
21896
  type: "tab:updated",
21847
21897
  payload: { tabId, name, directory }
21848
21898
  });
21899
+ } else {
21900
+ log2.ws.warn("tab:update failed - tab not found", { tabId, clientId: clientData.id });
21901
+ sendTo(ws, {
21902
+ type: "sync:stale",
21903
+ payload: {
21904
+ entityType: "tab",
21905
+ entityId: tabId,
21906
+ error: `Tab ${tabId} not found`
21907
+ }
21908
+ });
21849
21909
  }
21850
21910
  break;
21851
21911
  }
21852
21912
  case "tab:delete": {
21853
21913
  const { tabId } = message.payload;
21914
+ const tabInfo = tabManager2.get(tabId);
21915
+ log2.ws.info("tab:delete received", {
21916
+ tabId,
21917
+ tabName: tabInfo?.name,
21918
+ clientId: clientData.id
21919
+ });
21920
+ const terminalsInTab = ptyManager2.listTerminals().filter((t) => t.tabId === tabId);
21921
+ for (const terminal of terminalsInTab) {
21922
+ log2.ws.info("tab:delete CASCADE destroying terminal", {
21923
+ terminalId: terminal.id,
21924
+ terminalName: terminal.name,
21925
+ tabId,
21926
+ clientId: clientData.id
21927
+ });
21928
+ const destroyed = ptyManager2.destroy(terminal.id);
21929
+ if (destroyed) {
21930
+ broadcast({
21931
+ type: "terminal:destroyed",
21932
+ payload: { terminalId: terminal.id }
21933
+ });
21934
+ }
21935
+ }
21854
21936
  const success = tabManager2.delete(tabId);
21855
21937
  if (success) {
21938
+ log2.ws.info("tab:delete SUCCESS", {
21939
+ tabId,
21940
+ tabName: tabInfo?.name,
21941
+ terminalsDestroyed: terminalsInTab.length,
21942
+ clientId: clientData.id
21943
+ });
21856
21944
  broadcast({
21857
21945
  type: "tab:deleted",
21858
21946
  payload: { tabId }
@@ -21868,6 +21956,16 @@ var terminalWebSocketHandlers = {
21868
21956
  type: "tab:reordered",
21869
21957
  payload: { tabId, position }
21870
21958
  });
21959
+ } else {
21960
+ log2.ws.warn("tab:reorder failed - tab not found", { tabId, position, clientId: clientData.id });
21961
+ sendTo(ws, {
21962
+ type: "sync:stale",
21963
+ payload: {
21964
+ entityType: "tab",
21965
+ entityId: tabId,
21966
+ error: `Tab ${tabId} not found`
21967
+ }
21968
+ });
21871
21969
  }
21872
21970
  break;
21873
21971
  }
@@ -146563,7 +146661,7 @@ app5.post("/restart", (c) => {
146563
146661
  return c.json({ error: "Restart only available in developer mode" }, 403);
146564
146662
  }
146565
146663
  setTimeout(() => {
146566
- spawn2("bash", ["-c", "cd ~/projects/vibora && mise run build && bun run drizzle-kit push && systemctl --user restart vibora-dev"], {
146664
+ spawn2("bash", ["-c", "cd ~/projects/vibora && mise run build && bun run drizzle-kit push && systemctl --user restart vibora"], {
146567
146665
  detached: true,
146568
146666
  stdio: "ignore"
146569
146667
  }).unref();