@arbidocs/tui 0.3.8 → 0.3.10

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.js CHANGED
@@ -2,11 +2,11 @@
2
2
  'use strict';
3
3
 
4
4
  var commander = require('commander');
5
- var core = require('@arbidocs/core');
5
+ var sdk = require('@arbidocs/sdk');
6
6
  var piTui = require('@mariozechner/pi-tui');
7
7
  var chalk = require('chalk');
8
8
  require('fake-indexeddb/auto');
9
- var sdk = require('@arbidocs/sdk');
9
+ var client = require('@arbidocs/client');
10
10
  var prompts = require('@inquirer/prompts');
11
11
 
12
12
  function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
@@ -371,7 +371,7 @@ async function interactiveLogin(store) {
371
371
  const config = store.requireConfig();
372
372
  const email = await promptInput("Email");
373
373
  const pw = await promptPassword("Password");
374
- const authContext = await core.performPasswordLogin(config, email, pw, store);
374
+ const authContext = await sdk.performPasswordLogin(config, email, pw, store);
375
375
  console.info(`Logged in as ${email}`);
376
376
  const result = await selectOrCreateWorkspace(authContext, store);
377
377
  return { authContext, ...result };
@@ -379,7 +379,7 @@ async function interactiveLogin(store) {
379
379
  async function interactiveRegister(store) {
380
380
  const config = store.requireConfig();
381
381
  const email = await promptInput("Email");
382
- const arbi = sdk.createArbiClient({
382
+ const arbi = client.createArbiClient({
383
383
  baseUrl: config.baseUrl,
384
384
  deploymentDomain: config.deploymentDomain,
385
385
  credentials: "omit"
@@ -394,7 +394,7 @@ async function interactiveRegister(store) {
394
394
  verificationCode = await promptInput("Invitation code");
395
395
  } else {
396
396
  console.info("Sending verification email...");
397
- const verifyResponse = await arbi.fetch.POST("/api/user/verify-email", {
397
+ const verifyResponse = await arbi.fetch.POST("/v1/user/verify-email", {
398
398
  body: { email }
399
399
  });
400
400
  if (verifyResponse.error) {
@@ -420,20 +420,20 @@ async function interactiveRegister(store) {
420
420
  console.info(`
421
421
  Registered successfully as ${email}`);
422
422
  console.info("Logging in...");
423
- const authContext = await core.performPasswordLogin(config, email, pw, store);
423
+ const authContext = await sdk.performPasswordLogin(config, email, pw, store);
424
424
  console.info(`Logged in as ${email}`);
425
425
  const result = await selectOrCreateWorkspace(authContext, store);
426
426
  return { authContext, ...result };
427
427
  }
428
428
  async function selectOrCreateWorkspace(authContext, store) {
429
- const wsList = await core.workspaces.listWorkspaces(authContext.arbi);
429
+ const wsList = await sdk.workspaces.listWorkspaces(authContext.arbi);
430
430
  if (wsList.length === 1) {
431
431
  store.updateConfig({ selectedWorkspaceId: wsList[0].external_id });
432
432
  console.info(`Workspace: ${wsList[0].name}`);
433
433
  return { selectedWorkspaceId: wsList[0].external_id, selectedWorkspaceName: wsList[0].name };
434
434
  }
435
435
  if (wsList.length > 1) {
436
- const choices = core.formatWorkspaceChoices(wsList);
436
+ const choices = sdk.formatWorkspaceChoices(wsList);
437
437
  const selectedWorkspaceId = await promptSelect("Select workspace", choices);
438
438
  const ws = wsList.find((w) => w.external_id === selectedWorkspaceId);
439
439
  store.updateConfig({ selectedWorkspaceId });
@@ -444,7 +444,7 @@ async function selectOrCreateWorkspace(authContext, store) {
444
444
  const shouldCreate = await promptConfirm("Create a new workspace?");
445
445
  if (shouldCreate) {
446
446
  const name = await promptInput("Workspace name");
447
- const ws = await core.workspaces.createWorkspace(authContext.arbi, name.trim());
447
+ const ws = await sdk.workspaces.createWorkspace(authContext.arbi, name.trim());
448
448
  store.updateConfig({ selectedWorkspaceId: ws.external_id });
449
449
  console.info(`Created workspace: ${ws.name}`);
450
450
  return { selectedWorkspaceId: ws.external_id, selectedWorkspaceName: ws.name };
@@ -453,7 +453,7 @@ async function selectOrCreateWorkspace(authContext, store) {
453
453
  }
454
454
  async function ensureAuthenticated(store) {
455
455
  try {
456
- const authContext = await core.resolveAuth(store);
456
+ const authContext = await sdk.resolveAuth(store);
457
457
  const config = store.requireConfig();
458
458
  return {
459
459
  authContext,
@@ -478,7 +478,7 @@ async function ensureAuthenticated(store) {
478
478
  return await interactiveLogin(store);
479
479
  } catch (err) {
480
480
  console.error(`
481
- ${core.getErrorMessage(err)}
481
+ ${sdk.getErrorMessage(err)}
482
482
  `);
483
483
  }
484
484
  }
@@ -495,7 +495,7 @@ function showMessage(tui, message, level) {
495
495
  async function switchWorkspace(tui, workspaceId) {
496
496
  if (!tui.authContext) return null;
497
497
  try {
498
- const ws = await core.selectWorkspaceById(
498
+ const ws = await sdk.selectWorkspaceById(
499
499
  tui.authContext.arbi,
500
500
  workspaceId,
501
501
  tui.authContext.loginResult.serverSessionKey,
@@ -509,13 +509,13 @@ async function switchWorkspace(tui, workspaceId) {
509
509
  await tui.refreshWorkspaceContext();
510
510
  return ws;
511
511
  } catch (err) {
512
- showMessage(tui, `Failed to switch workspace: ${core.getErrorMessage(err)}`, "error");
512
+ showMessage(tui, `Failed to switch workspace: ${sdk.getErrorMessage(err)}`, "error");
513
513
  return null;
514
514
  }
515
515
  }
516
516
  async function applyWorkspaceSelection(tui, workspaceId, workspaceName) {
517
517
  if (!workspaceId) return;
518
- const wsCtx = await core.resolveWorkspace(tui.store, workspaceId);
518
+ const wsCtx = await sdk.resolveWorkspace(tui.store, workspaceId);
519
519
  tui.setWorkspaceContext(wsCtx);
520
520
  tui.state.workspaceName = workspaceName ?? null;
521
521
  }
@@ -528,7 +528,7 @@ async function runInteractiveFlow(tui, pauseMessage, action, errorPrefix) {
528
528
  return result;
529
529
  } catch (err) {
530
530
  tui.restartTui();
531
- showMessage(tui, `${errorPrefix}: ${core.getErrorMessage(err)}`, "error");
531
+ showMessage(tui, `${errorPrefix}: ${sdk.getErrorMessage(err)}`, "error");
532
532
  return null;
533
533
  }
534
534
  }
@@ -635,13 +635,13 @@ async function handleCreateWorkspace(tui, name) {
635
635
  }
636
636
  try {
637
637
  showMessage(tui, `Creating workspace "${name}"...`);
638
- const ws = await core.workspaces.createWorkspace(tui.authContext.arbi, name.trim());
638
+ const ws = await sdk.workspaces.createWorkspace(tui.authContext.arbi, name.trim());
639
639
  const selected = await switchWorkspace(tui, ws.external_id);
640
640
  if (selected) {
641
641
  showMessage(tui, `Created and switched to workspace: ${colors.accentBold(selected.name)}`);
642
642
  }
643
643
  } catch (err) {
644
- showMessage(tui, `Failed to create workspace: ${core.getErrorMessage(err)}`, "error");
644
+ showMessage(tui, `Failed to create workspace: ${sdk.getErrorMessage(err)}`, "error");
645
645
  }
646
646
  }
647
647
  async function handleWorkspaceSwitch(tui, workspaceId) {
@@ -660,23 +660,23 @@ async function handleWorkspaceSwitch(tui, workspaceId) {
660
660
  async function handleListWorkspaces(tui) {
661
661
  if (!requireAuth(tui, "Not authenticated.")) return;
662
662
  try {
663
- const wsList = await core.workspaces.listWorkspaces(tui.authContext.arbi);
663
+ const wsList = await sdk.workspaces.listWorkspaces(tui.authContext.arbi);
664
664
  const lines = wsList.map((ws) => {
665
665
  const current = ws.external_id === tui.state.workspaceId ? colors.accent(" (current)") : "";
666
666
  return ` ${ws.external_id} ${ws.name}${current}`;
667
667
  });
668
668
  showMessage(tui, ["Workspaces:", "", ...lines].join("\n"));
669
669
  } catch (err) {
670
- showMessage(tui, `Failed to list workspaces: ${core.getErrorMessage(err)}`, "error");
670
+ showMessage(tui, `Failed to list workspaces: ${sdk.getErrorMessage(err)}`, "error");
671
671
  }
672
672
  }
673
673
  async function handleListDocs(tui) {
674
- if (!tui.authContext || !tui.state.workspaceId) {
674
+ if (!tui.wsContext) {
675
675
  showMessage(tui, "No workspace selected. Use /workspace <id> first.", "warning");
676
676
  return;
677
677
  }
678
678
  try {
679
- const docs = await core.documents.listDocuments(tui.authContext.arbi, tui.state.workspaceId);
679
+ const docs = await sdk.documents.listDocuments(tui.wsContext.arbi);
680
680
  if (docs.length === 0) {
681
681
  showMessage(tui, "No documents in this workspace.");
682
682
  } else {
@@ -684,14 +684,14 @@ async function handleListDocs(tui) {
684
684
  showMessage(tui, [`Documents (${docs.length}):`, "", ...lines].join("\n"));
685
685
  }
686
686
  } catch (err) {
687
- showMessage(tui, `Failed to list documents: ${core.getErrorMessage(err)}`, "error");
687
+ showMessage(tui, `Failed to list documents: ${sdk.getErrorMessage(err)}`, "error");
688
688
  }
689
689
  }
690
690
  async function handleListContacts(tui) {
691
691
  if (!requireAuth(tui)) return;
692
692
  try {
693
- const contactList = await core.contacts.listContacts(tui.authContext.arbi);
694
- const { registered, pending } = core.contacts.groupContactsByStatus(contactList);
693
+ const contactList = await sdk.contacts.listContacts(tui.authContext.arbi);
694
+ const { registered, pending } = sdk.contacts.groupContactsByStatus(contactList);
695
695
  if (registered.length === 0 && pending.length === 0) {
696
696
  showMessage(tui, "No contacts. Use the web app to add contacts.");
697
697
  } else {
@@ -699,7 +699,7 @@ async function handleListContacts(tui) {
699
699
  if (registered.length > 0) {
700
700
  lines.push(`Contacts (${registered.length}):`, "");
701
701
  for (const c of registered) {
702
- const name = core.formatUserName(c.user);
702
+ const name = sdk.formatUserName(c.user);
703
703
  const nameStr = name ? colors.muted(` (${name})`) : "";
704
704
  lines.push(` ${c.email}${nameStr}`);
705
705
  }
@@ -715,7 +715,7 @@ async function handleListContacts(tui) {
715
715
  showMessage(tui, lines.join("\n"));
716
716
  }
717
717
  } catch (err) {
718
- showMessage(tui, `Failed to list contacts: ${core.getErrorMessage(err)}`, "error");
718
+ showMessage(tui, `Failed to list contacts: ${sdk.getErrorMessage(err)}`, "error");
719
719
  }
720
720
  }
721
721
  async function handleInviteContact(tui, email) {
@@ -726,7 +726,7 @@ async function handleInviteContact(tui, email) {
726
726
  }
727
727
  try {
728
728
  showMessage(tui, `Inviting ${email}...`);
729
- const result = await core.contacts.addContacts(tui.authContext.arbi, [email.trim()]);
729
+ const result = await sdk.contacts.addContacts(tui.authContext.arbi, [email.trim()]);
730
730
  const contact = result[0];
731
731
  if (contact?.status === "registered") {
732
732
  showMessage(
@@ -740,16 +740,16 @@ async function handleInviteContact(tui, email) {
740
740
  );
741
741
  }
742
742
  } catch (err) {
743
- showMessage(tui, `Failed to invite contact: ${core.getErrorMessage(err)}`, "error");
743
+ showMessage(tui, `Failed to invite contact: ${sdk.getErrorMessage(err)}`, "error");
744
744
  }
745
745
  }
746
746
  async function handleListConversations(tui) {
747
- if (!tui.authContext || !tui.state.workspaceId) {
747
+ if (!tui.wsContext) {
748
748
  showMessage(tui, "No workspace selected. Use /workspace <id> first.", "warning");
749
749
  return;
750
750
  }
751
751
  try {
752
- const convs = await core.conversations.listConversations(tui.authContext.arbi, tui.state.workspaceId);
752
+ const convs = await sdk.conversations.listConversations(tui.wsContext.arbi);
753
753
  if (convs.length === 0) {
754
754
  showMessage(tui, "No conversations in this workspace.");
755
755
  } else {
@@ -757,7 +757,7 @@ async function handleListConversations(tui) {
757
757
  showMessage(tui, [`Conversations (${convs.length}):`, "", ...lines].join("\n"));
758
758
  }
759
759
  } catch (err) {
760
- showMessage(tui, `Failed to list conversations: ${core.getErrorMessage(err)}`, "error");
760
+ showMessage(tui, `Failed to list conversations: ${sdk.getErrorMessage(err)}`, "error");
761
761
  }
762
762
  }
763
763
  function handleNewConversation(tui) {
@@ -789,7 +789,7 @@ async function handleUpload(tui, filePath) {
789
789
  }
790
790
  try {
791
791
  showMessage(tui, `Uploading ${filePath.trim()}...`);
792
- const result = await core.documents.uploadLocalFile(
792
+ const result = await sdk.documents.uploadLocalFile(
793
793
  {
794
794
  baseUrl: wsCtx.config.baseUrl,
795
795
  accessToken: wsCtx.accessToken,
@@ -804,21 +804,24 @@ async function handleUpload(tui, filePath) {
804
804
  showMessage(tui, `Duplicates detected: ${result.duplicates.join(", ")}`, "warning");
805
805
  }
806
806
  } catch (err) {
807
- showMessage(tui, `Failed to upload: ${core.getErrorMessage(err)}`, "error");
807
+ showMessage(tui, `Failed to upload: ${sdk.getErrorMessage(err)}`, "error");
808
808
  }
809
809
  }
810
810
  async function handleDelete(tui, docId) {
811
- if (!requireAuth(tui)) return;
811
+ if (!tui.wsContext) {
812
+ showMessage(tui, "No workspace selected. Use /workspace <id> first.", "warning");
813
+ return;
814
+ }
812
815
  if (!docId?.trim()) {
813
816
  showMessage(tui, "Usage: /delete <doc-id> (use /docs to list document IDs)", "warning");
814
817
  return;
815
818
  }
816
819
  try {
817
820
  showMessage(tui, `Deleting document ${docId}...`);
818
- await core.documents.deleteDocuments(tui.authContext.arbi, [docId.trim()]);
821
+ await sdk.documents.deleteDocuments(tui.wsContext.arbi, [docId.trim()]);
819
822
  showMessage(tui, `${colors.success("Deleted")} document ${docId}`);
820
823
  } catch (err) {
821
- showMessage(tui, `Failed to delete document: ${core.getErrorMessage(err)}`, "error");
824
+ showMessage(tui, `Failed to delete document: ${sdk.getErrorMessage(err)}`, "error");
822
825
  }
823
826
  }
824
827
  function handleLogout(tui) {
@@ -835,7 +838,7 @@ function handleLogout(tui) {
835
838
  async function handleHealth(tui) {
836
839
  if (!requireAuth(tui)) return;
837
840
  try {
838
- const data = await core.health.getHealth(tui.authContext.arbi);
841
+ const data = await sdk.health.getHealth(tui.authContext.arbi);
839
842
  const lines = ["System Health:", ""];
840
843
  const status = data.status;
841
844
  if (status) {
@@ -854,13 +857,13 @@ async function handleHealth(tui) {
854
857
  }
855
858
  showMessage(tui, lines.join("\n"));
856
859
  } catch (err) {
857
- showMessage(tui, `Failed to fetch health status: ${core.getErrorMessage(err)}`, "error");
860
+ showMessage(tui, `Failed to fetch health status: ${sdk.getErrorMessage(err)}`, "error");
858
861
  }
859
862
  }
860
863
  async function handleModels(tui) {
861
864
  if (!requireAuth(tui)) return;
862
865
  try {
863
- const data = await core.health.getHealthModels(tui.authContext.arbi);
866
+ const data = await sdk.health.getHealthModels(tui.authContext.arbi);
864
867
  const models = Array.isArray(data) ? data : data.data ?? [];
865
868
  if (models.length === 0) {
866
869
  showMessage(tui, "No models available.");
@@ -879,7 +882,7 @@ async function handleModels(tui) {
879
882
  }
880
883
  showMessage(tui, lines.join("\n"));
881
884
  } catch (err) {
882
- showMessage(tui, `Failed to fetch models: ${core.getErrorMessage(err)}`, "error");
885
+ showMessage(tui, `Failed to fetch models: ${sdk.getErrorMessage(err)}`, "error");
883
886
  }
884
887
  }
885
888
  async function streamResponse(tui, response) {
@@ -899,7 +902,7 @@ async function streamResponse(tui, response) {
899
902
  tui.requestRender();
900
903
  },
901
904
  onAgentStep: (data) => {
902
- const focus = data.focus || data.status || "";
905
+ const focus = data.focus || data.step || "";
903
906
  if (focus) {
904
907
  tui.chatLog.addAgentStep(focus);
905
908
  tui.requestRender();
@@ -911,7 +914,7 @@ async function streamResponse(tui, response) {
911
914
  }
912
915
  };
913
916
  try {
914
- const result = await core.streamSSE(response, callbacks);
917
+ const result = await sdk.streamSSE(response, callbacks);
915
918
  tui.chatLog.finalizeAssistant();
916
919
  tui.state.activityStatus = "idle";
917
920
  tui.requestRender();
@@ -919,15 +922,15 @@ async function streamResponse(tui, response) {
919
922
  } catch (err) {
920
923
  tui.chatLog.finalizeAssistant();
921
924
  tui.state.activityStatus = "error";
922
- tui.chatLog.addSystem(`Streaming failed: ${core.getErrorMessage(err)}`, "error");
925
+ tui.chatLog.addSystem(`Streaming failed: ${sdk.getErrorMessage(err)}`, "error");
923
926
  tui.requestRender();
924
927
  throw err;
925
928
  }
926
929
  }
927
930
  function deriveEncryptionKeypair(signingPrivateKeyBase64) {
928
- const signingPrivateKey = sdk.base64ToBytes(signingPrivateKeyBase64);
931
+ const signingPrivateKey = client.base64ToBytes(signingPrivateKeyBase64);
929
932
  const ed25519PublicKey = signingPrivateKey.slice(32, 64);
930
- return sdk.deriveEncryptionKeypairFromSigning({
933
+ return client.deriveEncryptionKeypairFromSigning({
931
934
  publicKey: ed25519PublicKey,
932
935
  secretKey: signingPrivateKey
933
936
  });
@@ -939,7 +942,7 @@ async function resolveRecipient(tui, query) {
939
942
  }
940
943
  const queryLower = query.toLowerCase();
941
944
  try {
942
- const contactList = await core.contacts.listContacts(tui.authContext.arbi);
945
+ const contactList = await sdk.contacts.listContacts(tui.authContext.arbi);
943
946
  const registered = contactList.filter(
944
947
  (c) => c.status === "registered" && c.user?.encryption_public_key
945
948
  );
@@ -972,7 +975,7 @@ ${names}`, "warning");
972
975
  family_name: user.family_name
973
976
  };
974
977
  } catch (err) {
975
- showMessage(tui, `Failed to resolve contact: ${core.getErrorMessage(err)}`, "error");
978
+ showMessage(tui, `Failed to resolve contact: ${sdk.getErrorMessage(err)}`, "error");
976
979
  return null;
977
980
  }
978
981
  }
@@ -1015,14 +1018,14 @@ async function loadDmHistory(tui, user) {
1015
1018
  if (!tui.authContext || !tui.encryptionKeys) return;
1016
1019
  const myExtId = tui.authContext.loginResult.userExtId;
1017
1020
  try {
1018
- const allDms = await core.dm.listDMs(tui.authContext.arbi);
1021
+ const allDms = await sdk.dm.listDMs(tui.authContext.arbi);
1019
1022
  const conversation = allDms.filter(
1020
1023
  (msg) => msg.type === "user_message" && (msg.sender.external_id === user.external_id && msg.recipient.external_id === myExtId || msg.sender.external_id === myExtId && msg.recipient.external_id === user.external_id)
1021
1024
  );
1022
1025
  conversation.sort((a, b) => new Date(a.created_at).getTime() - new Date(b.created_at).getTime());
1023
1026
  const unreadIds = conversation.filter((msg) => !msg.read && msg.sender.external_id === user.external_id).map((msg) => msg.external_id);
1024
1027
  if (unreadIds.length > 0) {
1025
- core.dm.markRead(tui.authContext.arbi, unreadIds).catch(() => {
1028
+ sdk.dm.markRead(tui.authContext.arbi, unreadIds).catch(() => {
1026
1029
  });
1027
1030
  }
1028
1031
  for (const msg of conversation) {
@@ -1034,7 +1037,7 @@ async function loadDmHistory(tui, user) {
1034
1037
  }
1035
1038
  tui.requestRender();
1036
1039
  } catch (err) {
1037
- showMessage(tui, `Failed to load DM history: ${core.getErrorMessage(err)}`, "error");
1040
+ showMessage(tui, `Failed to load DM history: ${sdk.getErrorMessage(err)}`, "error");
1038
1041
  }
1039
1042
  }
1040
1043
  async function sendEncryptedDm(tui, plaintext) {
@@ -1044,18 +1047,18 @@ async function sendEncryptedDm(tui, plaintext) {
1044
1047
  }
1045
1048
  const recipient = tui.currentDmChannel.user;
1046
1049
  try {
1047
- const encrypted = await sdk.encryptMessage(
1050
+ const encrypted = await client.encryptMessage(
1048
1051
  plaintext,
1049
1052
  recipient.encryption_public_key,
1050
1053
  tui.encryptionKeys.secretKey
1051
1054
  );
1052
- await core.dm.sendDM(tui.authContext.arbi, [
1055
+ await sdk.dm.sendDM(tui.authContext.arbi, [
1053
1056
  { recipient_ext_id: recipient.external_id, content: encrypted }
1054
1057
  ]);
1055
1058
  displayDmMessage(tui, plaintext, true, recipient.email);
1056
1059
  tui.requestRender();
1057
1060
  } catch (err) {
1058
- showMessage(tui, `Failed to send DM: ${core.getErrorMessage(err)}`, "error");
1061
+ showMessage(tui, `Failed to send DM: ${sdk.getErrorMessage(err)}`, "error");
1059
1062
  }
1060
1063
  }
1061
1064
  async function handleIncomingDm(tui, msg) {
@@ -1076,7 +1079,7 @@ async function handleIncomingDm(tui, msg) {
1076
1079
  if (plaintext) {
1077
1080
  displayDmMessage(tui, plaintext, false, msg.sender.email);
1078
1081
  tui.requestRender();
1079
- core.dm.markRead(tui.authContext.arbi, [msg.external_id]).catch(() => {
1082
+ sdk.dm.markRead(tui.authContext.arbi, [msg.external_id]).catch(() => {
1080
1083
  });
1081
1084
  }
1082
1085
  return true;
@@ -1084,7 +1087,7 @@ async function handleIncomingDm(tui, msg) {
1084
1087
  async function decryptNotification(notification, _myExtId, encryptionKeyPair, otherUser) {
1085
1088
  if (!notification.content) return null;
1086
1089
  try {
1087
- return await sdk.decryptMessage(
1090
+ return await client.decryptMessage(
1088
1091
  notification.content,
1089
1092
  otherUser.encryption_public_key,
1090
1093
  encryptionKeyPair.secretKey
@@ -1119,14 +1122,14 @@ async function handleMessage(msg, toasts, tui) {
1119
1122
  const handled = await handleIncomingDm(tui, msg);
1120
1123
  if (handled) return;
1121
1124
  }
1122
- const { text, level } = core.formatWsMessage(msg);
1125
+ const { text, level } = sdk.formatWsMessage(msg);
1123
1126
  const duration = DURATION_BY_LEVEL[level] ?? DURATION_DEFAULT;
1124
1127
  toasts.show(text, level, duration);
1125
1128
  }
1126
1129
  async function connectTuiWebSocket(options) {
1127
1130
  const { baseUrl, accessToken, toasts, tui } = options;
1128
1131
  try {
1129
- const connection = await core.connectWithReconnect({
1132
+ const connection = await sdk.connectWithReconnect({
1130
1133
  baseUrl,
1131
1134
  accessToken,
1132
1135
  onMessage: (msg) => handleMessage(msg, toasts, tui ?? null),
@@ -1162,7 +1165,7 @@ var ArbiTui = class {
1162
1165
  editor;
1163
1166
  /** Application state — public so handlers can read/write it. */
1164
1167
  state;
1165
- /** Auth context from @arbidocs/core — set during init. */
1168
+ /** Auth context from @arbidocs/sdk — set during init. */
1166
1169
  authContext = null;
1167
1170
  /** Workspace context with tokens/headers — set when workspace is selected. */
1168
1171
  workspaceContext = null;
@@ -1272,7 +1275,7 @@ var ArbiTui = class {
1272
1275
  /** Refresh workspace context (after switching workspaces). */
1273
1276
  async refreshWorkspaceContext() {
1274
1277
  if (!this.state.workspaceId || !this.authContext) return;
1275
- const { resolveWorkspace: resolveWorkspace3 } = await import('@arbidocs/core');
1278
+ const { resolveWorkspace: resolveWorkspace3 } = await import('@arbidocs/sdk');
1276
1279
  const ctx = await resolveWorkspace3(this.store, this.state.workspaceId);
1277
1280
  this.workspaceContext = ctx;
1278
1281
  this.updateHeader();
@@ -1339,21 +1342,18 @@ var ArbiTui = class {
1339
1342
  this.updateHeader();
1340
1343
  this.requestRender();
1341
1344
  try {
1342
- const docs = await core.documents.listDocuments(
1343
- this.workspaceContext.arbi,
1344
- this.workspaceContext.workspaceId
1345
- );
1345
+ const docs = await sdk.documents.listDocuments(this.workspaceContext.arbi);
1346
1346
  const docIds = docs.map((d) => d.external_id);
1347
1347
  const session = this.store.getChatSession();
1348
- const parentMessageExtId = this.state.conversationMessageId ?? session.lastMessageExtId;
1349
- const response = await core.assistant.queryAssistant({
1348
+ const previousResponseId = this.state.conversationMessageId ?? session.lastMessageExtId;
1349
+ const response = await sdk.assistant.queryAssistant({
1350
1350
  baseUrl: this.workspaceContext.config.baseUrl,
1351
1351
  accessToken: this.workspaceContext.accessToken,
1352
1352
  workspaceKeyHeader: this.workspaceContext.workspaceKeyHeader,
1353
1353
  workspaceId: this.workspaceContext.workspaceId,
1354
1354
  question,
1355
1355
  docIds,
1356
- parentMessageExtId
1356
+ previousResponseId
1357
1357
  });
1358
1358
  const result = await streamResponse(this, response);
1359
1359
  if (result.assistantMessageExtId) {
@@ -1369,7 +1369,7 @@ var ArbiTui = class {
1369
1369
  }
1370
1370
  } catch (err) {
1371
1371
  this.state.activityStatus = "error";
1372
- this.chatLog.addSystem(`Error: ${core.getErrorMessage(err)}`, "error");
1372
+ this.chatLog.addSystem(`Error: ${sdk.getErrorMessage(err)}`, "error");
1373
1373
  }
1374
1374
  this.state.activityStatus = "idle";
1375
1375
  this.updateHeader();
@@ -1409,7 +1409,7 @@ console.info = (...args) => {
1409
1409
  };
1410
1410
  var program = new commander.Command();
1411
1411
  program.name("arbi-tui").description("Interactive terminal UI for ARBI \u2014 chat with the RAG assistant").version("0.1.0").option("-w, --workspace <id>", "Workspace ID to use").action(async (opts) => {
1412
- const store = new core.FileConfigStore();
1412
+ const store = new sdk.FileConfigStore();
1413
1413
  try {
1414
1414
  store.requireConfig();
1415
1415
  } catch {
@@ -1422,19 +1422,19 @@ program.name("arbi-tui").description("Interactive terminal UI for ARBI \u2014 ch
1422
1422
  tui.setAuthContext(authContext);
1423
1423
  if (workspaceId) {
1424
1424
  try {
1425
- const wsCtx = await core.resolveWorkspace(store, workspaceId);
1425
+ const wsCtx = await sdk.resolveWorkspace(store, workspaceId);
1426
1426
  tui.setWorkspaceContext(wsCtx);
1427
1427
  if (selectedWorkspaceName && workspaceId === selectedWorkspaceId) {
1428
1428
  tui.state.workspaceName = selectedWorkspaceName;
1429
1429
  } else {
1430
- const wsList = await core.workspaces.listWorkspaces(authContext.arbi);
1430
+ const wsList = await sdk.workspaces.listWorkspaces(authContext.arbi);
1431
1431
  const ws = wsList.find((w) => w.external_id === workspaceId);
1432
1432
  if (ws) {
1433
1433
  tui.state.workspaceName = ws.name;
1434
1434
  }
1435
1435
  }
1436
1436
  } catch (err) {
1437
- tui.chatLog.addSystem(`Failed to load workspace: ${core.getErrorMessage(err)}`, "warning");
1437
+ tui.chatLog.addSystem(`Failed to load workspace: ${sdk.getErrorMessage(err)}`, "warning");
1438
1438
  tui.chatLog.addSystem("Use /workspaces to list and /workspace <id> to select.");
1439
1439
  }
1440
1440
  } else {
@@ -1448,7 +1448,7 @@ program.name("arbi-tui").description("Interactive terminal UI for ARBI \u2014 ch
1448
1448
  }
1449
1449
  if (session.conversationExtId && session.lastMessageExtId && tui.authContext) {
1450
1450
  try {
1451
- const threads = await core.conversations.getConversationThreads(
1451
+ const threads = await sdk.conversations.getConversationThreads(
1452
1452
  tui.authContext.arbi,
1453
1453
  session.conversationExtId
1454
1454
  );
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/theme/theme.ts","../src/theme/syntax-theme.ts","../src/components/assistant-message.ts","../src/components/user-message.ts","../src/components/system-message.ts","../src/components/agent-step.ts","../src/components/chat-log.ts","../src/components/arbi-editor.ts","../src/components/toast-container.ts","../src/commands.ts","../src/prompts.ts","../src/auth.ts","../src/tui-helpers.ts","../src/command-handlers.ts","../src/event-handlers.ts","../src/dm-handler.ts","../src/ws-handler.ts","../src/tui.ts","../src/index.ts"],"names":["chalk","Container","Text","Markdown","Spacer","Editor","matchesKey","Key","select","input","password","confirm","performPasswordLogin","createArbiClient","workspaces","formatWorkspaceChoices","resolveAuth","getErrorMessage","selectWorkspaceById","resolveWorkspace","documents","contacts","formatUserName","conversations","health","streamSSE","base64ToBytes","deriveEncryptionKeypairFromSigning","dm","encryptMessage","decryptMessage","formatWsMessage","connectWithReconnect","TUI","ProcessTerminal","CombinedAutocompleteProvider","assistant","Command","FileConfigStore"],"mappings":";;;;;;;;;;;;;;;AAYO,IAAM,MAAA,GAAS;AAAA;AAAA,EAEpB,QAAQA,sBAAA,CAAM,IAAA;AAAA,EACd,UAAA,EAAYA,uBAAM,IAAA,CAAK,IAAA;AAAA;AAAA,EAGvB,WAAWA,sBAAA,CAAM,IAAA;AAAA;AAAA,EAGjB,OAAOA,sBAAA,CAAM,IAAA;AAAA,EACb,QAAA,EAAUA,uBAAM,GAAA,CAAI,IAAA;AAAA;AAAA,EAGpB,SAASA,sBAAA,CAAM,KAAA;AAAA;AAAA,EAGf,SAASA,sBAAA,CAAM,MAAA;AAAA;AAAA,EAGf,OAAOA,sBAAA,CAAM,GAAA;AAAA,EACb,SAAA,EAAWA,uBAAM,IAAA,CAAK,GAAA;AAAA;AAAA,EAGtB,MAAMA,sBAAA,CAAM,KAAA;AAAA,EACZ,QAAA,EAAUA,uBAAM,IAAA,CAAK,KAAA;AAAA;AAAA,EAGrB,SAAA,EAAWA,uBAAM,IAAA,CAAK,KAAA;AAAA,EACtB,UAAUA,sBAAA,CAAM,KAAA;AAAA;AAAA,EAGhB,cAAA,EAAgBA,uBAAM,IAAA,CAAK,IAAA;AAAA;AAAA,EAG3B,YAAYA,sBAAA,CAAM,GAAA;AAAA,EAClB,UAAA,EAAYA,uBAAM,GAAA,CAAI,IAAA;AAAA,EACtB,WAAA,EAAaA,uBAAM,GAAA,CAAI,GAAA;AAAA,EACvB,aAAA,EAAeA,uBAAM,GAAA,CAAI,MAAA;AAAA;AAAA,EAGzB,WAAA,EAAaA,uBAAM,GAAA,CAAI,MAAA;AAAA,EACvB,YAAA,EAAcA,uBAAM,GAAA,CAAI;AAC1B,CAAA;AAcO,IAAM,eAAA,GAAmC;AAAA,EAC9C,cAAA,EAAgB,CAAC,CAAA,KAAc,MAAA,CAAO,OAAO,CAAC,CAAA;AAAA,EAC9C,YAAA,EAAc,CAAC,CAAA,KAAc,MAAA,CAAO,KAAK,CAAC,CAAA;AAAA,EAC1C,WAAA,EAAa,CAAC,CAAA,KAAc,MAAA,CAAO,MAAM,CAAC,CAAA;AAAA,EAC1C,UAAA,EAAY,CAAC,CAAA,KAAc,MAAA,CAAO,MAAM,CAAC,CAAA;AAAA,EACzC,OAAA,EAAS,CAAC,CAAA,KAAc,MAAA,CAAO,MAAM,CAAC;AACxC,CAAA;AAEO,IAAM,WAAA,GAA2B;AAAA,EACtC,WAAA,EAAa,CAAC,CAAA,KAAc,MAAA,CAAO,OAAO,CAAC,CAAA;AAAA,EAC3C,UAAA,EAAY;AACd,CAAA;AAEO,IAAM,aAAA,GAA+B;AAAA,EAC1C,OAAA,EAAS,CAAC,CAAA,KAAc,MAAA,CAAO,WAAW,CAAC,CAAA;AAAA,EAC3C,MAAM,CAAC,CAAA,KAAcA,sBAAA,CAAM,SAAA,CAAU,KAAK,CAAC,CAAA;AAAA,EAC3C,OAAA,EAAS,CAAC,CAAA,KAAc,MAAA,CAAO,MAAM,CAAC,CAAA;AAAA,EACtC,IAAA,EAAM,CAAC,CAAA,KAAc,MAAA,CAAO,QAAQ,CAAC,CAAA;AAAA,EACrC,SAAA,EAAW,CAAC,CAAA,KAAc,MAAA,CAAO,KAAK,CAAC,CAAA;AAAA,EACvC,eAAA,EAAiB,CAAC,CAAA,KAAc,MAAA,CAAO,MAAM,CAAC,CAAA;AAAA,EAC9C,OAAO,CAAC,CAAA,KAAcA,sBAAA,CAAM,MAAA,CAAO,KAAK,CAAC,CAAA;AAAA,EACzC,WAAA,EAAa,CAAC,CAAA,KAAc,MAAA,CAAO,MAAM,CAAC,CAAA;AAAA,EAC1C,EAAA,EAAI,CAAC,CAAA,KAAc,MAAA,CAAO,MAAM,CAAC,CAAA;AAAA,EACjC,UAAA,EAAY,CAAC,CAAA,KAAc,MAAA,CAAO,OAAO,CAAC,CAAA;AAAA,EAC1C,IAAA,EAAM,CAAC,CAAA,KAAcA,sBAAA,CAAM,KAAK,CAAC,CAAA;AAAA,EACjC,MAAA,EAAQ,CAAC,CAAA,KAAcA,sBAAA,CAAM,OAAO,CAAC,CAAA;AAAA,EACrC,aAAA,EAAe,CAAC,CAAA,KAAcA,sBAAA,CAAM,cAAc,CAAC,CAAA;AAAA,EACnD,SAAA,EAAW,CAAC,CAAA,KAAcA,sBAAA,CAAM,UAAU,CAAC;AAC7C,CAAA;AAIO,SAAS,YAAA,CAAa,eAA8B,MAAA,EAAwB;AACjF,EAAA,MAAM,GAAA,GAAM,MAAA,CAAO,UAAA,CAAW,MAAM,CAAA;AACpC,EAAA,MAAM,KAAK,aAAA,GAAgB,MAAA,CAAO,MAAM,CAAA,GAAA,EAAM,aAAa,EAAE,CAAA,GAAI,EAAA;AACjE,EAAA,MAAM,EAAA,GAAK,MAAA,CAAO,KAAA,CAAM,CAAA,GAAA,EAAM,MAAM,CAAA,CAAE,CAAA;AACtC,EAAA,OAAO,CAAA,EAAG,GAAG,CAAA,EAAG,EAAE,GAAG,EAAE,CAAA,CAAA;AACzB;ACxFO,SAAS,aAAA,CAAc,MAAc,IAAA,EAAyB;AACnE,EAAA,MAAM,KAAA,GAAQ,IAAA,CAAK,KAAA,CAAM,IAAI,CAAA;AAE7B,EAAA,OAAO,KAAA,CAAM,GAAA,CAAI,CAAC,IAAA,KAAS;AAEzB,IAAA,IAAI,MAAA,GAAS,IAAA,CAEV,OAAA,CAAQ,6BAAA,EAA+B,CAAC,CAAA,KAAMA,sBAAAA,CAAM,KAAA,CAAM,CAAC,CAAC,CAAA,CAE5D,OAAA,CAAQ,kBAAA,EAAoB,CAAC,CAAA,KAAMA,sBAAAA,CAAM,MAAA,CAAO,CAAC,CAAC,CAAA,CAElD,OAAA,CAAQ,gBAAA,EAAkB,CAAC,CAAA,KAAMA,sBAAAA,CAAM,IAAA,CAAK,CAAC,CAAC,CAAA;AAGjD,IAAA,MAAM,QAAA,GACJ,4KAAA;AACF,IAAA,MAAA,GAAS,MAAA,CAAO,QAAQ,QAAA,EAAU,CAAC,MAAMA,sBAAAA,CAAM,IAAA,CAAK,CAAC,CAAC,CAAA;AAEtD,IAAA,OAAO,MAAA;AAAA,EACT,CAAC,CAAA;AACH;;;AC1BA,IAAM,sBAAA,GAAyB;AAAA,EAC7B,GAAG,aAAA;AAAA,EACH;AACF,CAAA;AAEO,IAAM,gBAAA,GAAN,cAA+BC,eAAA,CAAU;AAAA,EACtC,QAAA;AAAA,EACA,KAAA;AAAA,EAER,WAAA,GAAc;AACZ,IAAA,KAAA,EAAM;AACN,IAAA,IAAA,CAAK,KAAA,GAAQ,IAAIC,UAAA,CAAK,MAAA,CAAO,eAAe,WAAW,CAAA,EAAG,GAAG,CAAC,CAAA;AAC9D,IAAA,IAAA,CAAK,WAAW,IAAIC,cAAA,CAAS,EAAA,EAAI,CAAA,EAAG,GAAG,sBAAsB,CAAA;AAC7D,IAAA,IAAA,CAAK,QAAA,CAAS,KAAK,KAAK,CAAA;AACxB,IAAA,IAAA,CAAK,QAAA,CAAS,KAAK,QAAQ,CAAA;AAAA,EAC7B;AAAA;AAAA,EAGA,QAAQ,IAAA,EAAoB;AAC1B,IAAA,IAAA,CAAK,QAAA,CAAS,QAAQ,IAAI,CAAA;AAAA,EAC5B;AACF,CAAA;ACvBO,IAAM,WAAA,GAAN,cAA0BF,eAAAA,CAAU;AAAA,EACzC,YAAY,IAAA,EAAc;AACxB,IAAA,KAAA,EAAM;AACN,IAAA,MAAM,KAAA,GAAQ,IAAIC,UAAAA,CAAK,MAAA,CAAO,UAAU,KAAK,CAAA,EAAG,GAAG,CAAC,CAAA;AACpD,IAAA,MAAM,UAAU,IAAIC,cAAAA,CAAS,IAAA,EAAM,CAAA,EAAG,GAAG,aAAa,CAAA;AACtD,IAAA,IAAA,CAAK,SAAS,KAAK,CAAA;AACnB,IAAA,IAAA,CAAK,SAAS,OAAO,CAAA;AAAA,EACvB;AACF,CAAA;ACNO,IAAM,aAAA,GAAN,cAA4BD,UAAAA,CAAK;AAAA,EACtC,WAAA,CAAY,OAAA,EAAiB,KAAA,GAA4B,MAAA,EAAQ;AAC/D,IAAA,MAAM,OAAA,GACJ,UAAU,OAAA,GACN,MAAA,CAAO,cACP,KAAA,KAAU,SAAA,GACR,MAAA,CAAO,aAAA,GACP,MAAA,CAAO,UAAA;AACf,IAAA,KAAA,CAAM,OAAA,CAAQ,OAAO,CAAA,EAAG,CAAA,EAAG,CAAC,CAAA;AAAA,EAC9B;AACF,CAAA;ACXO,IAAM,SAAA,GAAN,cAAwBA,UAAAA,CAAK;AAAA,EAC1B,SAAA,GAAY,KAAA;AAAA,EAEpB,YAAY,KAAA,EAAe;AACzB,IAAA,MAAM,MAAA,GAAS,CAAA,EAAG,MAAA,CAAO,WAAA,CAAY,GAAG,CAAC,CAAA,CAAA,EAAI,MAAA,CAAO,KAAA,CAAM,KAAK,CAAC,CAAA,CAAA;AAChE,IAAA,KAAA,CAAM,MAAA,EAAQ,GAAG,CAAC,CAAA;AAAA,EACpB;AAAA;AAAA,EAGA,QAAA,GAAiB;AACf,IAAA,IAAI,KAAK,SAAA,EAAW;AACpB,IAAA,IAAA,CAAK,SAAA,GAAY,IAAA;AAAA,EAGnB;AACF,CAAA;;;ACXO,IAAM,OAAA,GAAN,cAAsBD,eAAAA,CAAU;AAAA;AAAA,EAE7B,eAAA,GAA2C,IAAA;AAAA;AAAA,EAG3C,cAA2B,EAAC;AAAA;AAAA,EAGpC,QAAQ,IAAA,EAAoB;AAC1B,IAAA,IAAA,CAAK,QAAA,CAAS,IAAI,WAAA,CAAY,IAAI,CAAC,CAAA;AACnC,IAAA,IAAA,CAAK,QAAA,CAAS,IAAIG,YAAA,CAAO,CAAC,CAAC,CAAA;AAAA,EAC7B;AAAA;AAAA,EAGA,aAAa,IAAA,EAAoB;AAC/B,IAAA,MAAM,GAAA,GAAM,IAAI,gBAAA,EAAiB;AACjC,IAAA,GAAA,CAAI,QAAQ,IAAI,CAAA;AAChB,IAAA,IAAA,CAAK,SAAS,GAAG,CAAA;AACjB,IAAA,IAAA,CAAK,QAAA,CAAS,IAAIA,YAAA,CAAO,CAAC,CAAC,CAAA;AAAA,EAC7B;AAAA;AAAA,EAGA,SAAA,CAAU,OAAA,EAAiB,KAAA,GAA4B,MAAA,EAAc;AACnE,IAAA,IAAA,CAAK,QAAA,CAAS,IAAI,aAAA,CAAc,OAAA,EAAS,KAAK,CAAC,CAAA;AAC/C,IAAA,IAAA,CAAK,QAAA,CAAS,IAAIA,YAAA,CAAO,CAAC,CAAC,CAAA;AAAA,EAC7B;AAAA;AAAA,EAGA,KAAA,CAAM,aAAqB,IAAA,EAAoB;AAC7C,IAAA,MAAM,SAAA,GAAY,IAAIH,eAAAA,EAAU;AAChC,IAAA,MAAM,KAAA,GAAQ,IAAIC,UAAAA,CAAK,MAAA,CAAO,OAAO,WAAW,CAAA,EAAG,GAAG,CAAC,CAAA;AACvD,IAAA,MAAM,OAAA,GAAU,IAAIA,UAAAA,CAAK,MAAA,CAAO,KAAK,IAAI,CAAA,EAAG,GAAG,CAAC,CAAA;AAChD,IAAA,SAAA,CAAU,SAAS,KAAK,CAAA;AACxB,IAAA,SAAA,CAAU,SAAS,OAAO,CAAA;AAC1B,IAAA,IAAA,CAAK,SAAS,SAAS,CAAA;AACvB,IAAA,IAAA,CAAK,QAAA,CAAS,IAAIE,YAAA,CAAO,CAAC,CAAC,CAAA;AAAA,EAC7B;AAAA;AAAA,EAGA,aAAA,GAAsB;AACpB,IAAA,IAAA,CAAK,eAAA,GAAkB,IAAA;AACvB,IAAA,IAAA,CAAK,cAAc,EAAC;AAEpB,IAAA,OAAO,IAAA,CAAK,QAAA,CAAS,MAAA,GAAS,CAAA,EAAG;AAC/B,MAAA,IAAA,CAAK,YAAY,IAAA,CAAK,QAAA,CAAS,KAAK,QAAA,CAAS,MAAA,GAAS,CAAC,CAAC,CAAA;AAAA,IAC1D;AAAA,EACF;AAAA;AAAA,EAGA,cAAA,GAAuB;AACrB,IAAA,IAAA,CAAK,eAAA,GAAkB,IAAI,gBAAA,EAAiB;AAC5C,IAAA,IAAA,CAAK,cAAc,EAAC;AACpB,IAAA,IAAA,CAAK,QAAA,CAAS,KAAK,eAAe,CAAA;AAAA,EACpC;AAAA;AAAA,EAGA,gBAAgB,IAAA,EAAoB;AAClC,IAAA,IAAA,CAAK,eAAA,EAAiB,QAAQ,IAAI,CAAA;AAAA,EACpC;AAAA;AAAA,EAGA,aAAa,KAAA,EAAqB;AAChC,IAAA,IAAI,CAAC,KAAK,eAAA,EAAiB;AAC3B,IAAA,MAAM,IAAA,GAAO,IAAI,SAAA,CAAU,KAAK,CAAA;AAChC,IAAA,IAAA,CAAK,WAAA,CAAY,KAAK,IAAI,CAAA;AAE1B,IAAA,IAAA,CAAK,SAAS,IAAI,CAAA;AAAA,EACpB;AAAA;AAAA,EAGA,iBAAA,GAA0B;AACxB,IAAA,KAAA,MAAW,IAAA,IAAQ,KAAK,WAAA,EAAa;AACnC,MAAA,IAAA,CAAK,QAAA,EAAS;AAAA,IAChB;AACA,IAAA,IAAA,CAAK,eAAA,GAAkB,IAAA;AACvB,IAAA,IAAA,CAAK,cAAc,EAAC;AACpB,IAAA,IAAA,CAAK,QAAA,CAAS,IAAIA,YAAA,CAAO,CAAC,CAAC,CAAA;AAAA,EAC7B;AACF,CAAA;AC9EO,IAAM,UAAA,GAAN,cAAyBC,YAAA,CAAO;AAAA;AAAA,EAErC,QAAA;AAAA;AAAA,EAGA,OAAA;AAAA;AAAA,EAGA,OAAA;AAAA;AAAA,EAGA,OAAA;AAAA;AAAA,EAGA,OAAA;AAAA;AAAA,EAGQ,aAAA,GAAgB,CAAA;AAAA,EAExB,YAAY,GAAA,EAAU;AACpB,IAAA,KAAA,CAAM,GAAA,EAAK,WAAA,EAAa,EAAE,QAAA,EAAU,GAAG,CAAA;AAAA,EACzC;AAAA,EAES,YAAY,IAAA,EAAoB;AACvC,IAAA,IAAIC,gBAAA,CAAW,IAAA,EAAMC,SAAA,CAAI,MAAM,CAAA,EAAG;AAChC,MAAA,IAAA,CAAK,QAAA,IAAW;AAChB,MAAA;AAAA,IACF;AAEA,IAAA,IAAID,iBAAW,IAAA,EAAMC,SAAA,CAAI,IAAA,CAAK,GAAG,CAAC,CAAA,EAAG;AACnC,MAAA,MAAM,GAAA,GAAM,KAAK,GAAA,EAAI;AACrB,MAAA,IAAI,IAAA,CAAK,OAAA,EAAQ,CAAE,IAAA,EAAK,EAAG;AAEzB,QAAA,IAAA,CAAK,QAAQ,EAAE,CAAA;AACf,QAAA,IAAA,CAAK,aAAA,GAAgB,GAAA;AAAA,MACvB,CAAA,MAAA,IAAW,GAAA,GAAM,IAAA,CAAK,aAAA,GAAgB,GAAA,EAAM;AAE1C,QAAA,IAAA,CAAK,OAAA,IAAU;AAAA,MACjB,CAAA,MAAO;AACL,QAAA,IAAA,CAAK,aAAA,GAAgB,GAAA;AACrB,QAAA,IAAA,CAAK,OAAA,IAAU;AAAA,MACjB;AACA,MAAA;AAAA,IACF;AAEA,IAAA,IAAID,iBAAW,IAAA,EAAMC,SAAA,CAAI,IAAA,CAAK,GAAG,CAAC,CAAA,EAAG;AACnC,MAAA,IAAA,CAAK,OAAA,IAAU;AACf,MAAA;AAAA,IACF;AAEA,IAAA,IAAID,iBAAW,IAAA,EAAMC,SAAA,CAAI,IAAA,CAAK,GAAG,CAAC,CAAA,EAAG;AACnC,MAAA,IAAA,CAAK,OAAA,IAAU;AACf,MAAA;AAAA,IACF;AAEA,IAAA,IAAID,iBAAW,IAAA,EAAMC,SAAA,CAAI,IAAA,CAAK,GAAG,CAAC,CAAA,EAAG;AACnC,MAAA,IAAA,CAAK,OAAA,IAAU;AACf,MAAA;AAAA,IACF;AAGA,IAAA,KAAA,CAAM,YAAY,IAAI,CAAA;AAAA,EACxB;AACF,CAAA;ACjEA,IAAM,WAAA,GAAyD;AAAA,EAC7D,IAAA,EAAMP,uBAAM,GAAA,CAAI,IAAA;AAAA,EAChB,OAAA,EAASA,uBAAM,GAAA,CAAI,KAAA;AAAA,EACnB,OAAA,EAASA,uBAAM,GAAA,CAAI,MAAA;AAAA,EACnB,KAAA,EAAOA,uBAAM,GAAA,CAAI;AACnB,CAAA;AAEA,SAAS,eAAA,GAA0B;AACjC,EAAA,MAAM,GAAA,uBAAU,IAAA,EAAK;AACrB,EAAA,MAAM,EAAA,GAAK,OAAO,GAAA,CAAI,QAAA,EAAU,CAAA,CAAE,QAAA,CAAS,GAAG,GAAG,CAAA;AACjD,EAAA,MAAM,EAAA,GAAK,OAAO,GAAA,CAAI,UAAA,EAAY,CAAA,CAAE,QAAA,CAAS,GAAG,GAAG,CAAA;AACnD,EAAA,MAAM,EAAA,GAAK,OAAO,GAAA,CAAI,UAAA,EAAY,CAAA,CAAE,QAAA,CAAS,GAAG,GAAG,CAAA;AACnD,EAAA,OAAO,CAAA,EAAG,EAAE,CAAA,CAAA,EAAI,EAAE,IAAI,EAAE,CAAA,CAAA;AAC1B;AAOO,IAAM,cAAA,GAAN,cAA6BC,eAAAA,CAAU;AAAA,EACpC,eAA8B,EAAC;AAAA,EAC/B,cAAA,GAAsC,IAAA;AAAA;AAAA,EAG9C,kBAAkB,EAAA,EAAsB;AACtC,IAAA,IAAA,CAAK,cAAA,GAAiB,EAAA;AAAA,EACxB;AAAA;AAAA,EAGA,IAAA,CAAK,OAAA,EAAiB,KAAA,GAAoB,MAAA,EAAQ,aAAa,GAAA,EAAY;AACzE,IAAA,MAAM,OAAA,GAAU,YAAY,KAAK,CAAA;AACjC,IAAA,MAAM,YAAY,OAAA,CAAQ,CAAA,CAAA,EAAI,iBAAiB,CAAA,EAAA,EAAK,OAAO,CAAA,CAAE,CAAA;AAC7D,IAAA,MAAM,IAAA,GAAO,IAAIC,UAAAA,CAAK,SAAA,EAAW,GAAG,CAAC,CAAA;AAErC,IAAA,MAAM,KAAA,GAAQ,WAAW,MAAM;AAC7B,MAAA,IAAA,CAAK,QAAQ,IAAI,CAAA;AAAA,IACnB,GAAG,UAAU,CAAA;AAEb,IAAA,IAAA,CAAK,YAAA,CAAa,IAAA,CAAK,EAAE,IAAA,EAAM,OAAO,CAAA;AACtC,IAAA,IAAA,CAAK,SAAS,IAAI,CAAA;AAClB,IAAA,IAAA,CAAK,cAAA,IAAiB;AAAA,EACxB;AAAA;AAAA,EAGA,KAAA,GAAc;AACZ,IAAA,KAAA,MAAW,KAAA,IAAS,KAAK,YAAA,EAAc;AACrC,MAAA,YAAA,CAAa,MAAM,KAAK,CAAA;AACxB,MAAA,IAAA,CAAK,WAAA,CAAY,MAAM,IAAI,CAAA;AAAA,IAC7B;AACA,IAAA,IAAA,CAAK,eAAe,EAAC;AACrB,IAAA,IAAA,CAAK,cAAA,IAAiB;AAAA,EACxB;AAAA,EAEQ,QAAQ,IAAA,EAAkB;AAChC,IAAA,MAAM,GAAA,GAAM,KAAK,YAAA,CAAa,SAAA,CAAU,CAAC,CAAA,KAAM,CAAA,CAAE,SAAS,IAAI,CAAA;AAC9D,IAAA,IAAI,QAAQ,EAAA,EAAI;AACd,MAAA,YAAA,CAAa,IAAA,CAAK,YAAA,CAAa,GAAG,CAAA,CAAE,KAAK,CAAA;AACzC,MAAA,IAAA,CAAK,YAAA,CAAa,MAAA,CAAO,GAAA,EAAK,CAAC,CAAA;AAC/B,MAAA,IAAA,CAAK,YAAY,IAAI,CAAA;AACrB,MAAA,IAAA,CAAK,cAAA,IAAiB;AAAA,IACxB;AAAA,EACF;AACF,CAAA;;;AC7DO,IAAM,QAAA,GAAyB;AAAA,EACpC,EAAE,IAAA,EAAM,MAAA,EAAQ,WAAA,EAAa,yBAAA,EAA0B;AAAA,EACvD,EAAE,IAAA,EAAM,OAAA,EAAS,WAAA,EAAa,0BAAA,EAA2B;AAAA,EACzD,EAAE,IAAA,EAAM,UAAA,EAAY,WAAA,EAAa,wBAAA,EAAyB;AAAA,EAC1D,EAAE,IAAA,EAAM,QAAA,EAAU,WAAA,EAAa,wCAAA,EAAyC;AAAA,EACxE,EAAE,IAAA,EAAM,WAAA,EAAa,WAAA,EAAa,mCAAA,EAAoC;AAAA,EACtE,EAAE,IAAA,EAAM,YAAA,EAAc,WAAA,EAAa,qBAAA,EAAsB;AAAA,EACzD,EAAE,IAAA,EAAM,UAAA,EAAY,WAAA,EAAa,kCAAA,EAAmC;AAAA,EACpE,EAAE,IAAA,EAAM,QAAA,EAAU,WAAA,EAAa,4CAAA,EAA6C;AAAA,EAC5E,EAAE,IAAA,EAAM,MAAA,EAAQ,WAAA,EAAa,qCAAA,EAAsC;AAAA,EACnE,EAAE,IAAA,EAAM,QAAA,EAAU,WAAA,EAAa,+BAAA,EAAgC;AAAA,EAC/D,EAAE,IAAA,EAAM,QAAA,EAAU,WAAA,EAAa,qCAAA,EAAsC;AAAA,EACrE,EAAE,IAAA,EAAM,eAAA,EAAiB,WAAA,EAAa,oBAAA,EAAqB;AAAA,EAC3D,EAAE,IAAA,EAAM,KAAA,EAAO,WAAA,EAAa,4CAAA,EAA6C;AAAA,EACzE,EAAE,IAAA,EAAM,QAAA,EAAU,WAAA,EAAa,0BAAA,EAA2B;AAAA,EAC1D,EAAE,IAAA,EAAM,QAAA,EAAU,WAAA,EAAa,2BAAA,EAA4B;AAAA,EAC3D,EAAE,IAAA,EAAM,QAAA,EAAU,WAAA,EAAa,uCAAA,EAAwC;AAAA,EACvE,EAAE,IAAA,EAAM,QAAA,EAAU,WAAA,EAAa,+BAAA,EAAgC;AAAA,EAC/D,EAAE,IAAA,EAAM,MAAA,EAAQ,WAAA,EAAa,UAAA,EAAW;AAAA,EACxC,EAAE,IAAA,EAAM,MAAA,EAAQ,WAAA,EAAa,UAAA;AAC/B,CAAA;AAGO,SAAS,cAAA,GAAyB;AACvC,EAAA,MAAM,QAAQ,QAAA,CACX,MAAA,CAAO,CAAC,CAAA,KAAM,CAAA,CAAE,SAAS,MAAM,CAAA,CAC/B,GAAA,CAAI,CAAC,MAAM,CAAA,GAAA,EAAM,CAAA,CAAE,IAAI,CAAA,QAAA,EAAM,CAAA,CAAE,WAAW,CAAA,CAAE,CAAA;AAC/C,EAAA,OAAO;AAAA,IACL,qBAAA;AAAA,IACA,EAAA;AAAA,IACA,GAAG,KAAA;AAAA,IACH,EAAA;AAAA,IACA,kBAAA;AAAA,IACA,qDAAA;AAAA,IACA,wCAAA;AAAA,IACA,EAAA;AAAA,IACA,qBAAA;AAAA,IACA,kCAAA;AAAA,IACA,kCAAA;AAAA,IACA,sBAAA;AAAA,IACA;AAAA,GACF,CAAE,KAAK,IAAI,CAAA;AACb;ACxCA,eAAsB,YAAA,CACpB,SACA,OAAA,EACY;AACZ,EAAA,OAAOM,cAAA,CAAO,EAAE,OAAA,EAAS,OAAA,EAAS,CAAA;AACpC;AAkCA,eAAsB,WAAA,CAAY,OAAA,EAAiB,QAAA,GAAW,IAAA,EAAuB;AACnF,EAAA,OAAOC,aAAA,CAAM;AAAA,IACX,OAAA;AAAA,IACA,QAAA,EAAU,WAAW,CAAC,CAAA,KAAO,EAAE,IAAA,EAAK,GAAI,OAAO,UAAA,GAAc;AAAA,GAC9D,CAAA;AACH;AAKA,eAAsB,eAAe,OAAA,EAAkC;AACrE,EAAA,OAAOC,gBAAA,CAAS;AAAA,IACd,OAAA;AAAA,IACA,IAAA,EAAM,GAAA;AAAA,IACN,QAAA,EAAU,CAAC,CAAA,KAAO,CAAA,GAAI,IAAA,GAAO;AAAA,GAC9B,CAAA;AACH;AAKA,eAAsB,aAAA,CAAc,OAAA,EAAiB,YAAA,GAAe,IAAA,EAAwB;AAC1F,EAAA,OAAOC,eAAA,CAAQ,EAAE,OAAA,EAAS,OAAA,EAAS,cAAc,CAAA;AACnD;;;AC5CA,eAAsB,iBAAiB,KAAA,EAA0C;AAC/E,EAAA,MAAM,MAAA,GAAS,MAAM,aAAA,EAAc;AAEnC,EAAA,MAAM,KAAA,GAAQ,MAAM,WAAA,CAAY,OAAO,CAAA;AACvC,EAAA,MAAM,EAAA,GAAK,MAAM,cAAA,CAAe,UAAU,CAAA;AAE1C,EAAA,MAAM,cAAc,MAAMC,yBAAA,CAAqB,MAAA,EAAQ,KAAA,EAAO,IAAI,KAAK,CAAA;AAEvE,EAAA,OAAA,CAAQ,IAAA,CAAK,CAAA,aAAA,EAAgB,KAAK,CAAA,CAAE,CAAA;AAGpC,EAAA,MAAM,MAAA,GAAS,MAAM,uBAAA,CAAwB,WAAA,EAAa,KAAK,CAAA;AAE/D,EAAA,OAAO,EAAE,WAAA,EAAa,GAAG,MAAA,EAAO;AAClC;AAUA,eAAsB,oBAAoB,KAAA,EAA0C;AAClF,EAAA,MAAM,MAAA,GAAS,MAAM,aAAA,EAAc;AAEnC,EAAA,MAAM,KAAA,GAAQ,MAAM,WAAA,CAAY,OAAO,CAAA;AAEvC,EAAA,MAAM,OAAOC,oBAAA,CAAiB;AAAA,IAC5B,SAAS,MAAA,CAAO,OAAA;AAAA,IAChB,kBAAkB,MAAA,CAAO,gBAAA;AAAA,IACzB,WAAA,EAAa;AAAA,GACd,CAAA;AACD,EAAA,MAAM,IAAA,CAAK,OAAO,UAAA,EAAW;AAG7B,EAAA,MAAM,UAAA,GAAa,MAAM,YAAA,CAAa,qBAAA,EAAuB;AAAA,IAC3D,EAAE,IAAA,EAAM,2BAAA,EAA6B,KAAA,EAAO,MAAA,EAAgB;AAAA,IAC5D,EAAE,IAAA,EAAM,8BAAA,EAAgC,KAAA,EAAO,OAAA;AAAiB,GACjE,CAAA;AAED,EAAA,IAAI,gBAAA;AACJ,EAAA,IAAI,eAAe,MAAA,EAAQ;AACzB,IAAA,gBAAA,GAAmB,MAAM,YAAY,iBAAiB,CAAA;AAAA,EACxD,CAAA,MAAO;AACL,IAAA,OAAA,CAAQ,KAAK,+BAA+B,CAAA;AAC5C,IAAA,MAAM,cAAA,GAAiB,MAAM,IAAA,CAAK,KAAA,CAAM,KAAK,wBAAA,EAA0B;AAAA,MACrE,IAAA,EAAM,EAAE,KAAA;AAAM,KACf,CAAA;AACD,IAAA,IAAI,eAAe,KAAA,EAAO;AACxB,MAAA,MAAM,IAAI,MAAM,CAAA,mCAAA,EAAsC,IAAA,CAAK,UAAU,cAAA,CAAe,KAAK,CAAC,CAAA,CAAE,CAAA;AAAA,IAC9F;AACA,IAAA,OAAA,CAAQ,KAAK,4CAA4C,CAAA;AACzD,IAAA,gBAAA,GAAmB,MAAM,YAAY,mBAAmB,CAAA;AAAA,EAC1D;AAGA,EAAA,MAAM,EAAA,GAAK,MAAM,cAAA,CAAe,UAAU,CAAA;AAC1C,EAAA,MAAM,SAAA,GAAY,MAAM,cAAA,CAAe,kBAAkB,CAAA;AACzD,EAAA,IAAI,OAAO,SAAA,EAAW;AACpB,IAAA,MAAM,IAAI,MAAM,yBAAyB,CAAA;AAAA,EAC3C;AAGA,EAAA,MAAM,SAAA,GAAa,MAAM,WAAA,CAAY,uBAAA,EAAyB,KAAK,CAAA,IAAM,MAAA;AACzE,EAAA,MAAM,QAAA,GAAY,MAAM,WAAA,CAAY,sBAAA,EAAwB,KAAK,CAAA,IAAM,EAAA;AAGvE,EAAA,MAAM,IAAA,CAAK,KAAK,QAAA,CAAS;AAAA,IACvB,KAAA;AAAA,IACA,QAAA,EAAU,EAAA;AAAA,IACV,gBAAA;AAAA,IACA,SAAA;AAAA,IACA;AAAA,GACD,CAAA;AAED,EAAA,OAAA,CAAQ,IAAA,CAAK;AAAA,2BAAA,EAAgC,KAAK,CAAA,CAAE,CAAA;AAGpD,EAAA,OAAA,CAAQ,KAAK,eAAe,CAAA;AAC5B,EAAA,MAAM,cAAc,MAAMD,yBAAA,CAAqB,MAAA,EAAQ,KAAA,EAAO,IAAI,KAAK,CAAA;AAEvE,EAAA,OAAA,CAAQ,IAAA,CAAK,CAAA,aAAA,EAAgB,KAAK,CAAA,CAAE,CAAA;AACpC,EAAA,MAAM,MAAA,GAAS,MAAM,uBAAA,CAAwB,WAAA,EAAa,KAAK,CAAA;AAE/D,EAAA,OAAO,EAAE,WAAA,EAAa,GAAG,MAAA,EAAO;AAClC;AAQA,eAAe,uBAAA,CACb,aACA,KAAA,EAC2E;AAC3E,EAAA,MAAM,MAAA,GAAS,MAAME,eAAA,CAAW,cAAA,CAAe,YAAY,IAAI,CAAA;AAE/D,EAAA,IAAI,MAAA,CAAO,WAAW,CAAA,EAAG;AACvB,IAAA,KAAA,CAAM,aAAa,EAAE,mBAAA,EAAqB,OAAO,CAAC,CAAA,CAAE,aAAa,CAAA;AACjE,IAAA,OAAA,CAAQ,KAAK,CAAA,WAAA,EAAc,MAAA,CAAO,CAAC,CAAA,CAAE,IAAI,CAAA,CAAE,CAAA;AAC3C,IAAA,OAAO,EAAE,mBAAA,EAAqB,MAAA,CAAO,CAAC,CAAA,CAAE,aAAa,qBAAA,EAAuB,MAAA,CAAO,CAAC,CAAA,CAAE,IAAA,EAAK;AAAA,EAC7F;AAEA,EAAA,IAAI,MAAA,CAAO,SAAS,CAAA,EAAG;AACrB,IAAA,MAAM,OAAA,GAAUC,4BAAuB,MAAM,CAAA;AAE7C,IAAA,MAAM,mBAAA,GAAsB,MAAM,YAAA,CAAa,kBAAA,EAAoB,OAAO,CAAA;AAC1E,IAAA,MAAM,KAAK,MAAA,CAAO,IAAA,CAAK,CAAC,CAAA,KAAM,CAAA,CAAE,gBAAgB,mBAAmB,CAAA;AACnE,IAAA,KAAA,CAAM,YAAA,CAAa,EAAE,mBAAA,EAAqB,CAAA;AAC1C,IAAA,OAAA,CAAQ,IAAA,CAAK,CAAA,WAAA,EAAc,EAAA,EAAI,IAAI,CAAA,CAAE,CAAA;AACrC,IAAA,OAAO,EAAE,mBAAA,EAAqB,qBAAA,EAAuB,EAAA,EAAI,IAAA,EAAK;AAAA,EAChE;AAGA,EAAA,OAAA,CAAQ,KAAK,sBAAsB,CAAA;AACnC,EAAA,MAAM,YAAA,GAAe,MAAM,aAAA,CAAc,yBAAyB,CAAA;AAElE,EAAA,IAAI,YAAA,EAAc;AAChB,IAAA,MAAM,IAAA,GAAO,MAAM,WAAA,CAAY,gBAAgB,CAAA;AAE/C,IAAA,MAAM,EAAA,GAAK,MAAMD,eAAA,CAAW,eAAA,CAAgB,YAAY,IAAA,EAAM,IAAA,CAAK,MAAM,CAAA;AACzE,IAAA,KAAA,CAAM,YAAA,CAAa,EAAE,mBAAA,EAAqB,EAAA,CAAG,aAAa,CAAA;AAC1D,IAAA,OAAA,CAAQ,IAAA,CAAK,CAAA,mBAAA,EAAsB,EAAA,CAAG,IAAI,CAAA,CAAE,CAAA;AAC5C,IAAA,OAAO,EAAE,mBAAA,EAAqB,EAAA,CAAG,WAAA,EAAa,qBAAA,EAAuB,GAAG,IAAA,EAAK;AAAA,EAC/E;AAEA,EAAA,OAAO,EAAC;AACV;AAUA,eAAsB,oBAAoB,KAAA,EAA0C;AAElF,EAAA,IAAI;AACF,IAAA,MAAM,WAAA,GAAc,MAAME,gBAAA,CAAY,KAAK,CAAA;AAC3C,IAAA,MAAM,MAAA,GAAS,MAAM,aAAA,EAAc;AACnC,IAAA,OAAO;AAAA,MACL,WAAA;AAAA,MACA,qBAAqB,MAAA,CAAO;AAAA,KAC9B;AAAA,EACF,CAAA,CAAA,MAAQ;AAEN,IAAA,OAAA,CAAQ,KAAK,sBAAsB,CAAA;AAAA,EACrC;AAGA,EAAA,OAAO,IAAA,EAAM;AACX,IAAA,MAAM,MAAA,GAAS,MAAM,YAAA,CAAa,4BAAA,EAA8B;AAAA,MAC9D,EAAE,IAAA,EAAM,QAAA,EAAU,KAAA,EAAO,OAAA,EAAiB;AAAA,MAC1C,EAAE,IAAA,EAAM,wBAAA,EAA0B,KAAA,EAAO,UAAA,EAAoB;AAAA,MAC7D,EAAE,IAAA,EAAM,MAAA,EAAQ,KAAA,EAAO,MAAA;AAAgB,KACxC,CAAA;AAED,IAAA,IAAI,WAAW,MAAA,EAAQ;AACrB,MAAA,OAAA,CAAQ,KAAK,CAAC,CAAA;AAAA,IAChB;AAEA,IAAA,IAAI;AACF,MAAA,IAAI,WAAW,UAAA,EAAY;AACzB,QAAA,OAAO,MAAM,oBAAoB,KAAK,CAAA;AAAA,MACxC;AACA,MAAA,OAAO,MAAM,iBAAiB,KAAK,CAAA;AAAA,IACrC,SAAS,GAAA,EAAK;AACZ,MAAA,OAAA,CAAQ,KAAA,CAAM;AAAA,EAAKC,oBAAA,CAAgB,GAAG,CAAC;AAAA,CAAI,CAAA;AAAA,IAC7C;AAAA,EACF;AACF;ACjMO,SAAS,WAAA,CACd,GAAA,EACA,OAAA,GAAU,sCAAA,EACD;AACT,EAAA,IAAI,GAAA,CAAI,aAAa,OAAO,IAAA;AAC5B,EAAA,WAAA,CAAY,GAAA,EAAK,SAAS,OAAO,CAAA;AACjC,EAAA,OAAO,KAAA;AACT;AAKO,SAAS,WAAA,CAAY,GAAA,EAAc,OAAA,EAAiB,KAAA,EAAkC;AAC3F,EAAA,GAAA,CAAI,OAAA,CAAQ,SAAA,CAAU,OAAA,EAAS,KAAK,CAAA;AACpC,EAAA,GAAA,CAAI,aAAA,EAAc;AACpB;AAMA,eAAsB,eAAA,CACpB,KACA,WAAA,EACuD;AACvD,EAAA,IAAI,CAAC,GAAA,CAAI,WAAA,EAAa,OAAO,IAAA;AAE7B,EAAA,IAAI;AACF,IAAA,MAAM,KAAK,MAAMC,wBAAA;AAAA,MACf,IAAI,WAAA,CAAY,IAAA;AAAA,MAChB,WAAA;AAAA,MACA,GAAA,CAAI,YAAY,WAAA,CAAY,gBAAA;AAAA,MAC5B,GAAA,CAAI,KAAA,CAAM,kBAAA,EAAmB,CAAE;AAAA,KACjC;AAEA,IAAA,GAAA,CAAI,KAAA,CAAM,cAAc,EAAA,CAAG,WAAA;AAC3B,IAAA,GAAA,CAAI,KAAA,CAAM,gBAAgB,EAAA,CAAG,IAAA;AAC7B,IAAA,GAAA,CAAI,MAAM,qBAAA,GAAwB,IAAA;AAClC,IAAA,GAAA,CAAI,MAAM,gBAAA,EAAiB;AAC3B,IAAA,GAAA,CAAI,MAAM,YAAA,CAAa,EAAE,mBAAA,EAAqB,EAAA,CAAG,aAAa,CAAA;AAC9D,IAAA,MAAM,IAAI,uBAAA,EAAwB;AAElC,IAAA,OAAO,EAAA;AAAA,EACT,SAAS,GAAA,EAAK;AACZ,IAAA,WAAA,CAAY,KAAK,CAAA,4BAAA,EAA+BD,oBAAAA,CAAgB,GAAG,CAAC,IAAI,OAAO,CAAA;AAC/E,IAAA,OAAO,IAAA;AAAA,EACT;AACF;AAKA,eAAsB,uBAAA,CACpB,GAAA,EACA,WAAA,EACA,aAAA,EACe;AACf,EAAA,IAAI,CAAC,WAAA,EAAa;AAClB,EAAA,MAAM,KAAA,GAAQ,MAAME,qBAAA,CAAiB,GAAA,CAAI,OAAO,WAAW,CAAA;AAC3D,EAAA,GAAA,CAAI,oBAAoB,KAAK,CAAA;AAC7B,EAAA,GAAA,CAAI,KAAA,CAAM,gBAAgB,aAAA,IAAiB,IAAA;AAC7C;AAOA,eAAsB,kBAAA,CACpB,GAAA,EACA,YAAA,EACA,MAAA,EACA,WAAA,EACmB;AACnB,EAAA,WAAA,CAAY,KAAK,YAAY,CAAA;AAC7B,EAAA,GAAA,CAAI,OAAA,EAAQ;AAEZ,EAAA,IAAI;AACF,IAAA,MAAM,MAAA,GAAS,MAAM,MAAA,EAAO;AAC5B,IAAA,GAAA,CAAI,UAAA,EAAW;AACf,IAAA,OAAO,MAAA;AAAA,EACT,SAAS,GAAA,EAAK;AACZ,IAAA,GAAA,CAAI,UAAA,EAAW;AACf,IAAA,WAAA,CAAY,GAAA,EAAK,GAAG,WAAW,CAAA,EAAA,EAAKF,qBAAgB,GAAG,CAAC,IAAI,OAAO,CAAA;AACnE,IAAA,OAAO,IAAA;AAAA,EACT;AACF;;;AC1EA,eAAsB,aAAA,CAAc,KAAcR,MAAAA,EAAiC;AACjF,EAAA,MAAM,OAAA,GAAUA,OAAM,IAAA,EAAK;AAC3B,EAAA,IAAI,CAAC,OAAA,CAAQ,UAAA,CAAW,GAAG,GAAG,OAAO,KAAA;AAErC,EAAA,MAAM,QAAQ,OAAA,CAAQ,KAAA,CAAM,CAAC,CAAA,CAAE,MAAM,KAAK,CAAA;AAC1C,EAAA,MAAM,GAAA,GAAM,KAAA,CAAM,CAAC,CAAA,EAAG,WAAA,EAAY;AAClC,EAAA,MAAM,IAAA,GAAO,KAAA,CAAM,KAAA,CAAM,CAAC,CAAA;AAE1B,EAAA,QAAQ,GAAA;AAAK,IACX,KAAK,MAAA;AACH,MAAA,WAAA,CAAY,GAAA,EAAK,gBAAgB,CAAA;AACjC,MAAA,OAAO,IAAA;AAAA,IAET,KAAK,OAAA;AACH,MAAA,MAAM,YAAY,GAAG,CAAA;AACrB,MAAA,OAAO,IAAA;AAAA,IAET,KAAK,UAAA;AACH,MAAA,MAAM,eAAe,GAAG,CAAA;AACxB,MAAA,OAAO,IAAA;AAAA,IAET,KAAK,QAAA;AACH,MAAA,MAAM,qBAAA,CAAsB,GAAA,EAAK,IAAA,CAAK,IAAA,CAAK,GAAG,CAAC,CAAA;AAC/C,MAAA,OAAO,IAAA;AAAA,IAET,KAAK,WAAA;AACH,MAAA,MAAM,qBAAA,CAAsB,GAAA,EAAK,IAAA,CAAK,CAAC,CAAC,CAAA;AACxC,MAAA,OAAO,IAAA;AAAA,IAET,KAAK,YAAA;AACH,MAAA,MAAM,qBAAqB,GAAG,CAAA;AAC9B,MAAA,OAAO,IAAA;AAAA,IAET,KAAK,UAAA;AACH,MAAA,MAAM,mBAAmB,GAAG,CAAA;AAC5B,MAAA,OAAO,IAAA;AAAA,IAET,KAAK,QAAA;AACH,MAAA,MAAM,mBAAA,CAAoB,GAAA,EAAK,IAAA,CAAK,CAAC,CAAC,CAAA;AACtC,MAAA,OAAO,IAAA;AAAA,IAET,KAAK,MAAA;AACH,MAAA,MAAM,eAAe,GAAG,CAAA;AACxB,MAAA,OAAO,IAAA;AAAA,IAET,KAAK,QAAA;AACH,MAAA,MAAM,YAAA,CAAa,GAAA,EAAK,IAAA,CAAK,IAAA,CAAK,GAAG,CAAC,CAAA;AACtC,MAAA,OAAO,IAAA;AAAA,IAET,KAAK,QAAA;AACH,MAAA,MAAM,YAAA,CAAa,GAAA,EAAK,IAAA,CAAK,CAAC,CAAC,CAAA;AAC/B,MAAA,OAAO,IAAA;AAAA,IAET,KAAK,eAAA;AACH,MAAA,MAAM,wBAAwB,GAAG,CAAA;AACjC,MAAA,OAAO,IAAA;AAAA,IAET,KAAK,KAAA;AACH,MAAA,qBAAA,CAAsB,GAAG,CAAA;AACzB,MAAA,OAAO,IAAA;AAAA,IAET,KAAK,QAAA;AACH,MAAA,MAAM,aAAa,GAAG,CAAA;AACtB,MAAA,OAAO,IAAA;AAAA,IAET,KAAK,QAAA;AACH,MAAA,MAAM,aAAa,GAAG,CAAA;AACtB,MAAA,OAAO,IAAA;AAAA,IAET,KAAK,QAAA;AACH,MAAA,YAAA,CAAa,GAAG,CAAA;AAChB,MAAA,OAAO,IAAA;AAAA,IAET,KAAK,QAAA;AACH,MAAA,YAAA,CAAa,GAAG,CAAA;AAChB,MAAA,OAAO,IAAA;AAAA,IAET,KAAK,MAAA;AAAA,IACL,KAAK,MAAA;AACH,MAAA,GAAA,CAAI,QAAA,EAAS;AACb,MAAA,OAAO,IAAA;AAAA,IAET;AACE,MAAA,WAAA,CAAY,GAAA,EAAK,CAAA,kBAAA,EAAqB,GAAG,CAAA,oCAAA,CAAA,EAAwC,SAAS,CAAA;AAC1F,MAAA,OAAO,IAAA;AAAA;AAEb;AAEA,eAAe,YAAY,GAAA,EAA6B;AACtD,EAAA,MAAM,SAAS,MAAM,kBAAA;AAAA,IACnB,GAAA;AAAA,IACA,0BAAA;AAAA,IACA,MAAM,gBAAA,CAAiB,GAAA,CAAI,KAAK,CAAA;AAAA,IAChC;AAAA,GACF;AAEA,EAAA,IAAI,MAAA,EAAQ;AACV,IAAA,GAAA,CAAI,cAAA,CAAe,OAAO,WAAW,CAAA;AACrC,IAAA,MAAM,uBAAA,CAAwB,GAAA,EAAK,MAAA,CAAO,mBAAA,EAAqB,OAAO,qBAAqB,CAAA;AAC3F,IAAA,WAAA,CAAY,KAAK,yBAAyB,CAAA;AAAA,EAC5C;AACF;AAEA,eAAe,eAAe,GAAA,EAA6B;AACzD,EAAA,MAAM,SAAS,MAAM,kBAAA;AAAA,IACnB,GAAA;AAAA,IACA,iCAAA;AAAA,IACA,MAAM,mBAAA,CAAoB,GAAA,CAAI,KAAK,CAAA;AAAA,IACnC;AAAA,GACF;AAEA,EAAA,IAAI,MAAA,EAAQ;AACV,IAAA,GAAA,CAAI,cAAA,CAAe,OAAO,WAAW,CAAA;AACrC,IAAA,MAAM,uBAAA,CAAwB,GAAA,EAAK,MAAA,CAAO,mBAAA,EAAqB,OAAO,qBAAqB,CAAA;AAC3F,IAAA,WAAA,CAAY,KAAK,2BAA2B,CAAA;AAAA,EAC9C;AACF;AAEA,eAAe,qBAAA,CAAsB,KAAc,IAAA,EAA6B;AAC9E,EAAA,IAAI,CAAC,WAAA,CAAY,GAAG,CAAA,EAAG;AAEvB,EAAA,IAAI,CAAC,IAAA,CAAK,IAAA,EAAK,EAAG;AAChB,IAAA,WAAA,CAAY,GAAA,EAAK,mCAAmC,SAAS,CAAA;AAC7D,IAAA;AAAA,EACF;AAEA,EAAA,IAAI;AACF,IAAA,WAAA,CAAY,GAAA,EAAK,CAAA,oBAAA,EAAuB,IAAI,CAAA,IAAA,CAAM,CAAA;AAClD,IAAA,MAAM,EAAA,GAAK,MAAMK,eAAAA,CAAW,eAAA,CAAgB,IAAI,WAAA,CAAa,IAAA,EAAM,IAAA,CAAK,IAAA,EAAM,CAAA;AAC9E,IAAA,MAAM,QAAA,GAAW,MAAM,eAAA,CAAgB,GAAA,EAAK,GAAG,WAAW,CAAA;AAE1D,IAAA,IAAI,QAAA,EAAU;AACZ,MAAA,WAAA,CAAY,KAAK,CAAA,mCAAA,EAAsC,MAAA,CAAO,WAAW,QAAA,CAAS,IAAI,CAAC,CAAA,CAAE,CAAA;AAAA,IAC3F;AAAA,EACF,SAAS,GAAA,EAAK;AACZ,IAAA,WAAA,CAAY,KAAK,CAAA,4BAAA,EAA+BG,oBAAAA,CAAgB,GAAG,CAAC,IAAI,OAAO,CAAA;AAAA,EACjF;AACF;AAEA,eAAe,qBAAA,CAAsB,KAAc,WAAA,EAAqC;AACtF,EAAA,IAAI,CAAC,WAAA,CAAY,GAAA,EAAK,+CAA+C,CAAA,EAAG;AAExE,EAAA,IAAI,CAAC,WAAA,EAAa;AAChB,IAAA,MAAM,qBAAqB,GAAG,CAAA;AAC9B,IAAA,WAAA,CAAY,KAAK,gCAAgC,CAAA;AACjD,IAAA;AAAA,EACF;AAEA,EAAA,WAAA,CAAY,GAAA,EAAK,CAAA,uBAAA,EAA0B,WAAW,CAAA,GAAA,CAAK,CAAA;AAC3D,EAAA,MAAM,EAAA,GAAK,MAAM,eAAA,CAAgB,GAAA,EAAK,WAAW,CAAA;AACjD,EAAA,IAAI,EAAA,EAAI;AACN,IAAA,WAAA,CAAY,KAAK,CAAA,uBAAA,EAA0B,MAAA,CAAO,WAAW,EAAA,CAAG,IAAI,CAAC,CAAA,CAAE,CAAA;AAAA,EACzE;AACF;AAEA,eAAe,qBAAqB,GAAA,EAA6B;AAC/D,EAAA,IAAI,CAAC,WAAA,CAAY,GAAA,EAAK,oBAAoB,CAAA,EAAG;AAE7C,EAAA,IAAI;AACF,IAAA,MAAM,SAAS,MAAMH,eAAAA,CAAW,cAAA,CAAe,GAAA,CAAI,YAAa,IAAI,CAAA;AACpE,IAAA,MAAM,KAAA,GAAQ,MAAA,CAAO,GAAA,CAAI,CAAC,EAAA,KAAO;AAC/B,MAAA,MAAM,OAAA,GAAU,GAAG,WAAA,KAAgB,GAAA,CAAI,MAAM,WAAA,GAAc,MAAA,CAAO,MAAA,CAAO,YAAY,CAAA,GAAI,EAAA;AACzF,MAAA,OAAO,KAAK,EAAA,CAAG,WAAW,KAAK,EAAA,CAAG,IAAI,GAAG,OAAO,CAAA,CAAA;AAAA,IAClD,CAAC,CAAA;AACD,IAAA,WAAA,CAAY,GAAA,EAAK,CAAC,aAAA,EAAe,EAAA,EAAI,GAAG,KAAK,CAAA,CAAE,IAAA,CAAK,IAAI,CAAC,CAAA;AAAA,EAC3D,SAAS,GAAA,EAAK;AACZ,IAAA,WAAA,CAAY,KAAK,CAAA,2BAAA,EAA8BG,oBAAAA,CAAgB,GAAG,CAAC,IAAI,OAAO,CAAA;AAAA,EAChF;AACF;AAEA,eAAe,eAAe,GAAA,EAA6B;AACzD,EAAA,IAAI,CAAC,GAAA,CAAI,WAAA,IAAe,CAAC,GAAA,CAAI,MAAM,WAAA,EAAa;AAC9C,IAAA,WAAA,CAAY,GAAA,EAAK,qDAAqD,SAAS,CAAA;AAC/E,IAAA;AAAA,EACF;AAEA,EAAA,IAAI;AACF,IAAA,MAAM,IAAA,GAAO,MAAMG,cAAA,CAAU,aAAA,CAAc,IAAI,WAAA,CAAY,IAAA,EAAM,GAAA,CAAI,KAAA,CAAM,WAAW,CAAA;AACtF,IAAA,IAAI,IAAA,CAAK,WAAW,CAAA,EAAG;AACrB,MAAA,WAAA,CAAY,KAAK,iCAAiC,CAAA;AAAA,IACpD,CAAA,MAAO;AACL,MAAA,MAAM,KAAA,GAAQ,IAAA,CAAK,GAAA,CAAI,CAAC,CAAA,KAAM,CAAA,EAAA,EAAK,CAAA,CAAE,WAAW,CAAA,EAAA,EAAK,CAAA,CAAE,SAAA,IAAa,WAAW,CAAA,CAAE,CAAA;AACjF,MAAA,WAAA,CAAY,GAAA,EAAK,CAAC,CAAA,WAAA,EAAc,IAAA,CAAK,MAAM,CAAA,EAAA,CAAA,EAAM,EAAA,EAAI,GAAG,KAAK,CAAA,CAAE,IAAA,CAAK,IAAI,CAAC,CAAA;AAAA,IAC3E;AAAA,EACF,SAAS,GAAA,EAAK;AACZ,IAAA,WAAA,CAAY,KAAK,CAAA,0BAAA,EAA6BH,oBAAAA,CAAgB,GAAG,CAAC,IAAI,OAAO,CAAA;AAAA,EAC/E;AACF;AAEA,eAAe,mBAAmB,GAAA,EAA6B;AAC7D,EAAA,IAAI,CAAC,WAAA,CAAY,GAAG,CAAA,EAAG;AAEvB,EAAA,IAAI;AACF,IAAA,MAAM,cAAc,MAAMI,aAAA,CAAS,YAAA,CAAa,GAAA,CAAI,YAAa,IAAI,CAAA;AACrE,IAAA,MAAM,EAAE,UAAA,EAAY,OAAA,EAAQ,GAAIA,aAAA,CAAS,sBAAsB,WAAW,CAAA;AAE1E,IAAA,IAAI,UAAA,CAAW,MAAA,KAAW,CAAA,IAAK,OAAA,CAAQ,WAAW,CAAA,EAAG;AACnD,MAAA,WAAA,CAAY,KAAK,+CAA+C,CAAA;AAAA,IAClE,CAAA,MAAO;AACL,MAAA,MAAM,QAAkB,EAAC;AAEzB,MAAA,IAAI,UAAA,CAAW,SAAS,CAAA,EAAG;AACzB,QAAA,KAAA,CAAM,IAAA,CAAK,CAAA,UAAA,EAAa,UAAA,CAAW,MAAM,MAAM,EAAE,CAAA;AACjD,QAAA,KAAA,MAAW,KAAK,UAAA,EAAY;AAC1B,UAAA,MAAM,IAAA,GAAOC,mBAAA,CAAe,CAAA,CAAE,IAAI,CAAA;AAClC,UAAA,MAAM,UAAU,IAAA,GAAO,MAAA,CAAO,MAAM,CAAA,EAAA,EAAK,IAAI,GAAG,CAAA,GAAI,EAAA;AACpD,UAAA,KAAA,CAAM,KAAK,CAAA,EAAA,EAAK,CAAA,CAAE,KAAK,CAAA,EAAG,OAAO,CAAA,CAAE,CAAA;AAAA,QACrC;AAAA,MACF;AAEA,MAAA,IAAI,OAAA,CAAQ,SAAS,CAAA,EAAG;AACtB,QAAA,IAAI,KAAA,CAAM,MAAA,GAAS,CAAA,EAAG,KAAA,CAAM,KAAK,EAAE,CAAA;AACnC,QAAA,KAAA,CAAM,IAAA,CAAK,CAAA,qBAAA,EAAwB,OAAA,CAAQ,MAAM,CAAA,EAAA,CAAI,CAAA;AACrD,QAAA,KAAA,MAAW,KAAK,OAAA,EAAS;AACvB,UAAA,KAAA,CAAM,IAAA,CAAK,CAAA,EAAA,EAAK,CAAA,CAAE,KAAK,CAAA,QAAA,EAAM,OAAO,KAAA,CAAM,CAAA,CAAE,MAAM,CAAC,CAAA,CAAE,CAAA;AAAA,QACvD;AAAA,MACF;AAEA,MAAA,KAAA,CAAM,IAAA,CAAK,EAAA,EAAI,MAAA,CAAO,KAAA,CAAM,qDAAqD,CAAC,CAAA;AAClF,MAAA,WAAA,CAAY,GAAA,EAAK,KAAA,CAAM,IAAA,CAAK,IAAI,CAAC,CAAA;AAAA,IACnC;AAAA,EACF,SAAS,GAAA,EAAK;AACZ,IAAA,WAAA,CAAY,KAAK,CAAA,yBAAA,EAA4BL,oBAAAA,CAAgB,GAAG,CAAC,IAAI,OAAO,CAAA;AAAA,EAC9E;AACF;AAEA,eAAe,mBAAA,CAAoB,KAAc,KAAA,EAA+B;AAC9E,EAAA,IAAI,CAAC,WAAA,CAAY,GAAG,CAAA,EAAG;AAEvB,EAAA,IAAI,CAAC,KAAA,EAAO,IAAA,EAAK,EAAG;AAClB,IAAA,WAAA,CAAY,GAAA,EAAK,mCAAmC,SAAS,CAAA;AAC7D,IAAA;AAAA,EACF;AAEA,EAAA,IAAI;AACF,IAAA,WAAA,CAAY,GAAA,EAAK,CAAA,SAAA,EAAY,KAAK,CAAA,GAAA,CAAK,CAAA;AAEvC,IAAA,MAAM,MAAA,GAAS,MAAMI,aAAA,CAAS,WAAA,CAAY,GAAA,CAAI,WAAA,CAAa,IAAA,EAAM,CAAC,KAAA,CAAM,IAAA,EAAM,CAAC,CAAA;AAC/E,IAAA,MAAM,OAAA,GAAU,OAAO,CAAC,CAAA;AAExB,IAAA,IAAI,OAAA,EAAS,WAAW,YAAA,EAAc;AACpC,MAAA,WAAA;AAAA,QACE,GAAA;AAAA,QACA,CAAA,EAAG,MAAA,CAAO,OAAA,CAAQ,OAAO,CAAC,CAAA,CAAA,EAAI,KAAK,CAAA,kDAAA,EAAgD,KAAA,CAAM,KAAA,CAAM,GAAG,CAAA,CAAE,CAAC,CAAC,CAAA;AAAA,OACxG;AAAA,IACF,CAAA,MAAO;AACL,MAAA,WAAA;AAAA,QACE,GAAA;AAAA,QACA,GAAG,MAAA,CAAO,OAAA,CAAQ,SAAS,CAAC,IAAI,KAAK,CAAA,wEAAA;AAAA,OACvC;AAAA,IACF;AAAA,EACF,SAAS,GAAA,EAAK;AACZ,IAAA,WAAA,CAAY,KAAK,CAAA,0BAAA,EAA6BJ,oBAAAA,CAAgB,GAAG,CAAC,IAAI,OAAO,CAAA;AAAA,EAC/E;AACF;AAEA,eAAe,wBAAwB,GAAA,EAA6B;AAClE,EAAA,IAAI,CAAC,GAAA,CAAI,WAAA,IAAe,CAAC,GAAA,CAAI,MAAM,WAAA,EAAa;AAC9C,IAAA,WAAA,CAAY,GAAA,EAAK,qDAAqD,SAAS,CAAA;AAC/E,IAAA;AAAA,EACF;AAEA,EAAA,IAAI;AACF,IAAA,MAAM,KAAA,GAAQ,MAAMM,kBAAA,CAAc,iBAAA,CAAkB,IAAI,WAAA,CAAY,IAAA,EAAM,GAAA,CAAI,KAAA,CAAM,WAAW,CAAA;AAC/F,IAAA,IAAI,KAAA,CAAM,WAAW,CAAA,EAAG;AACtB,MAAA,WAAA,CAAY,KAAK,qCAAqC,CAAA;AAAA,IACxD,CAAA,MAAO;AACL,MAAA,MAAM,KAAA,GAAQ,KAAA,CAAM,GAAA,CAAI,CAAC,CAAA,KAAM,CAAA,EAAA,EAAK,CAAA,CAAE,WAAW,CAAA,EAAA,EAAK,CAAA,CAAE,KAAA,IAAS,YAAY,CAAA,CAAE,CAAA;AAC/E,MAAA,WAAA,CAAY,GAAA,EAAK,CAAC,CAAA,eAAA,EAAkB,KAAA,CAAM,MAAM,CAAA,EAAA,CAAA,EAAM,EAAA,EAAI,GAAG,KAAK,CAAA,CAAE,IAAA,CAAK,IAAI,CAAC,CAAA;AAAA,IAChF;AAAA,EACF,SAAS,GAAA,EAAK;AACZ,IAAA,WAAA,CAAY,KAAK,CAAA,8BAAA,EAAiCN,oBAAAA,CAAgB,GAAG,CAAC,IAAI,OAAO,CAAA;AAAA,EACnF;AACF;AAEA,SAAS,sBAAsB,GAAA,EAAoB;AACjD,EAAA,GAAA,CAAI,MAAM,qBAAA,GAAwB,IAAA;AAClC,EAAA,GAAA,CAAI,MAAM,gBAAA,EAAiB;AAC3B,EAAA,WAAA,CAAY,KAAK,2BAA2B,CAAA;AAC9C;AAEA,SAAS,aAAa,GAAA,EAAoB;AACxC,EAAA,MAAM,EAAE,OAAM,GAAI,GAAA;AAClB,EAAA,MAAM,KAAA,GAAQ;AAAA,IACZ,CAAA,eAAA,EAAkB,KAAA,CAAM,eAAA,GAAkB,MAAA,CAAO,OAAA,CAAQ,KAAK,CAAA,GAAI,MAAA,CAAO,KAAA,CAAM,IAAI,CAAC,CAAA,CAAA;AAAA,IACpF,CAAA,WAAA,EAAc,KAAA,CAAM,aAAA,GAAgB,MAAA,CAAO,MAAA,CAAO,KAAA,CAAM,aAAa,CAAA,GAAI,MAAA,CAAO,KAAA,CAAM,MAAM,CAAC,CAAA,CAAA;AAAA,IAC7F,iBAAiB,KAAA,CAAM,WAAA,IAAe,MAAA,CAAO,KAAA,CAAM,MAAM,CAAC,CAAA,CAAA;AAAA,IAC1D,CAAA,cAAA,EAAiB,KAAA,CAAM,qBAAA,GAAwB,MAAA,CAAO,KAAA,CAAM,KAAA,CAAM,qBAAqB,CAAA,GAAI,MAAA,CAAO,KAAA,CAAM,KAAK,CAAC,CAAA,CAAA;AAAA,IAC9G,CAAA,QAAA,EAAW,MAAM,cAAc,CAAA,CAAA;AAAA,IAC/B,CAAA,WAAA,EAAc,GAAA,CAAI,WAAA,GAAc,MAAA,CAAO,OAAA,CAAQ,WAAW,CAAA,GAAI,MAAA,CAAO,KAAA,CAAM,cAAc,CAAC,CAAA;AAAA,GAC5F;AACA,EAAA,WAAA,CAAY,GAAA,EAAK,KAAA,CAAM,IAAA,CAAK,IAAI,CAAC,CAAA;AACnC;AAEA,eAAe,YAAA,CAAa,KAAc,QAAA,EAAiC;AACzE,EAAA,MAAM,QAAQ,GAAA,CAAI,SAAA;AAClB,EAAA,IAAI,CAAC,KAAA,EAAO;AACV,IAAA,WAAA,CAAY,GAAA,EAAK,qDAAqD,SAAS,CAAA;AAC/E,IAAA;AAAA,EACF;AAEA,EAAA,IAAI,CAAC,QAAA,CAAS,IAAA,EAAK,EAAG;AACpB,IAAA,WAAA,CAAY,GAAA,EAAK,8BAA8B,SAAS,CAAA;AACxD,IAAA;AAAA,EACF;AAEA,EAAA,IAAI;AACF,IAAA,WAAA,CAAY,GAAA,EAAK,CAAA,UAAA,EAAa,QAAA,CAAS,IAAA,EAAM,CAAA,GAAA,CAAK,CAAA;AAElD,IAAA,MAAM,MAAA,GAAS,MAAMG,cAAA,CAAU,eAAA;AAAA,MAC7B;AAAA,QACE,OAAA,EAAS,MAAM,MAAA,CAAO,OAAA;AAAA,QACtB,aAAa,KAAA,CAAM,WAAA;AAAA,QACnB,oBAAoB,KAAA,CAAM;AAAA,OAC5B;AAAA,MACA,KAAA,CAAM,WAAA;AAAA,MACN,SAAS,IAAA;AAAK,KAChB;AAEA,IAAA,MAAM,GAAA,GAAM,MAAA,CAAO,WAAA,CAAY,IAAA,CAAK,IAAI,CAAA;AACxC,IAAA,WAAA,CAAY,GAAA,EAAK,CAAA,EAAG,MAAA,CAAO,OAAA,CAAQ,UAAU,CAAC,CAAA,CAAA,EAAI,MAAA,CAAO,QAAQ,CAAA,mBAAA,EAAiB,GAAG,CAAA,CAAE,CAAA;AAEvF,IAAA,IAAI,MAAA,CAAO,UAAA,IAAc,MAAA,CAAO,UAAA,CAAW,SAAS,CAAA,EAAG;AACrD,MAAA,WAAA,CAAY,GAAA,EAAK,wBAAwB,MAAA,CAAO,UAAA,CAAW,KAAK,IAAI,CAAC,IAAI,SAAS,CAAA;AAAA,IACpF;AAAA,EACF,SAAS,GAAA,EAAK;AACZ,IAAA,WAAA,CAAY,KAAK,CAAA,kBAAA,EAAqBH,oBAAAA,CAAgB,GAAG,CAAC,IAAI,OAAO,CAAA;AAAA,EACvE;AACF;AAEA,eAAe,YAAA,CAAa,KAAc,KAAA,EAA+B;AACvE,EAAA,IAAI,CAAC,WAAA,CAAY,GAAG,CAAA,EAAG;AAEvB,EAAA,IAAI,CAAC,KAAA,EAAO,IAAA,EAAK,EAAG;AAClB,IAAA,WAAA,CAAY,GAAA,EAAK,6DAA6D,SAAS,CAAA;AACvF,IAAA;AAAA,EACF;AAEA,EAAA,IAAI;AACF,IAAA,WAAA,CAAY,GAAA,EAAK,CAAA,kBAAA,EAAqB,KAAK,CAAA,GAAA,CAAK,CAAA;AAChD,IAAA,MAAMG,cAAA,CAAU,gBAAgB,GAAA,CAAI,WAAA,CAAa,MAAM,CAAC,KAAA,CAAM,IAAA,EAAM,CAAC,CAAA;AACrE,IAAA,WAAA,CAAY,GAAA,EAAK,GAAG,MAAA,CAAO,OAAA,CAAQ,SAAS,CAAC,CAAA,UAAA,EAAa,KAAK,CAAA,CAAE,CAAA;AAAA,EACnE,SAAS,GAAA,EAAK;AACZ,IAAA,WAAA,CAAY,KAAK,CAAA,2BAAA,EAA8BH,oBAAAA,CAAgB,GAAG,CAAC,IAAI,OAAO,CAAA;AAAA,EAChF;AACF;AAEA,SAAS,aAAa,GAAA,EAAoB;AACxC,EAAA,GAAA,CAAI,MAAM,iBAAA,EAAkB;AAC5B,EAAA,GAAA,CAAI,KAAA,CAAM,YAAA,CAAa,EAAE,mBAAA,EAAqB,QAAW,CAAA;AACzD,EAAA,GAAA,CAAI,MAAM,gBAAA,EAAiB;AAE3B,EAAA,GAAA,CAAI,WAAA,GAAc,IAAA;AAClB,EAAA,GAAA,CAAI,MAAM,eAAA,GAAkB,KAAA;AAC5B,EAAA,GAAA,CAAI,MAAM,WAAA,GAAc,IAAA;AACxB,EAAA,GAAA,CAAI,MAAM,aAAA,GAAgB,IAAA;AAC1B,EAAA,GAAA,CAAI,MAAM,qBAAA,GAAwB,IAAA;AAElC,EAAA,WAAA,CAAY,KAAK,+CAA+C,CAAA;AAClE;AAEA,eAAe,aAAa,GAAA,EAA6B;AACvD,EAAA,IAAI,CAAC,WAAA,CAAY,GAAG,CAAA,EAAG;AAEvB,EAAA,IAAI;AACF,IAAA,MAAM,OAAO,MAAMO,WAAA,CAAO,SAAA,CAAU,GAAA,CAAI,YAAa,IAAI,CAAA;AACzD,IAAA,MAAM,KAAA,GAAkB,CAAC,gBAAA,EAAkB,EAAE,CAAA;AAG7C,IAAA,MAAM,SAAU,IAAA,CAAiC,MAAA;AACjD,IAAA,IAAI,MAAA,EAAQ;AACV,MAAA,MAAM,WAAA,GAAc,WAAW,SAAA,GAAY,MAAA,CAAO,QAAQ,MAAM,CAAA,GAAI,MAAA,CAAO,OAAA,CAAQ,MAAM,CAAA;AACzF,MAAA,KAAA,CAAM,IAAA,CAAK,CAAA,UAAA,EAAa,WAAW,CAAA,CAAE,CAAA;AAAA,IACvC;AAGA,IAAA,MAAM,WAAY,IAAA,CAAiC,QAAA;AAGnD,IAAA,IAAI,QAAA,EAAU;AACZ,MAAA,KAAA,CAAM,IAAA,CAAK,IAAI,aAAa,CAAA;AAC5B,MAAA,KAAA,MAAW,CAAC,IAAA,EAAM,IAAI,KAAK,MAAA,CAAO,OAAA,CAAQ,QAAQ,CAAA,EAAG;AACnD,QAAA,MAAM,GAAA,GAAM,IAAA;AACZ,QAAA,MAAM,YAAY,GAAA,CAAI,MAAA;AACtB,QAAA,MAAM,SAAA,GAAY,SAAA,GACd,SAAA,KAAc,SAAA,GACZ,OAAO,OAAA,CAAQ,SAAS,CAAA,GACxB,MAAA,CAAO,KAAA,CAAM,SAAS,CAAA,GACxB,MAAA,CAAO,MAAM,SAAS,CAAA;AAC1B,QAAA,KAAA,CAAM,IAAA,CAAK,CAAA,IAAA,EAAO,IAAI,CAAA,EAAA,EAAK,SAAS,CAAA,CAAE,CAAA;AAAA,MACxC;AAAA,IACF;AAEA,IAAA,WAAA,CAAY,GAAA,EAAK,KAAA,CAAM,IAAA,CAAK,IAAI,CAAC,CAAA;AAAA,EACnC,SAAS,GAAA,EAAK;AACZ,IAAA,WAAA,CAAY,KAAK,CAAA,+BAAA,EAAkCP,oBAAAA,CAAgB,GAAG,CAAC,IAAI,OAAO,CAAA;AAAA,EACpF;AACF;AAEA,eAAe,aAAa,GAAA,EAA6B;AACvD,EAAA,IAAI,CAAC,WAAA,CAAY,GAAG,CAAA,EAAG;AAEvB,EAAA,IAAI;AACF,IAAA,MAAM,OAAO,MAAMO,WAAA,CAAO,eAAA,CAAgB,GAAA,CAAI,YAAa,IAAI,CAAA;AAC/D,IAAA,MAAM,MAAA,GAAS,MAAM,OAAA,CAAQ,IAAI,IAC7B,IAAA,GACG,IAAA,CAAiC,QAAsB,EAAC;AAE/D,IAAA,IAAI,MAAA,CAAO,WAAW,CAAA,EAAG;AACvB,MAAA,WAAA,CAAY,KAAK,sBAAsB,CAAA;AACvC,MAAA;AAAA,IACF;AAEA,IAAA,MAAM,QAAkB,CAAC,CAAA,QAAA,EAAW,MAAA,CAAO,MAAM,MAAM,EAAE,CAAA;AACzD,IAAA,KAAA,MAAW,KAAK,MAAA,EAAQ;AACtB,MAAA,MAAM,KAAA,GAAQ,CAAA;AACd,MAAA,MAAM,IAAA,GAAQ,KAAA,CAAM,UAAA,IAAc,KAAA,CAAM,IAAA,IAAQ,SAAA;AAChD,MAAA,MAAM,QAAA,GAAY,MAAM,QAAA,IAAY,EAAA;AACpC,MAAA,MAAM,OAAA,GAAW,MAAM,QAAA,IAAY,EAAA;AACnC,MAAA,MAAM,KAAA,GAAQ,CAAC,MAAA,CAAO,MAAA,CAAO,IAAI,CAAC,CAAA;AAClC,MAAA,IAAI,QAAA,EAAU,KAAA,CAAM,IAAA,CAAK,CAAA,UAAA,EAAa,QAAQ,CAAA,CAAE,CAAA;AAChD,MAAA,IAAI,OAAA,EAAS,KAAA,CAAM,IAAA,CAAK,CAAA,KAAA,EAAQ,OAAO,CAAA,CAAE,CAAA;AACzC,MAAA,KAAA,CAAM,KAAK,CAAA,EAAA,EAAK,KAAA,CAAM,IAAA,CAAK,IAAI,CAAC,CAAA,CAAE,CAAA;AAAA,IACpC;AAEA,IAAA,WAAA,CAAY,GAAA,EAAK,KAAA,CAAM,IAAA,CAAK,IAAI,CAAC,CAAA;AAAA,EACnC,SAAS,GAAA,EAAK;AACZ,IAAA,WAAA,CAAY,KAAK,CAAA,wBAAA,EAA2BP,oBAAAA,CAAgB,GAAG,CAAC,IAAI,OAAO,CAAA;AAAA,EAC7E;AACF;ACnbA,eAAsB,cAAA,CAAe,KAAc,QAAA,EAA8C;AAC/F,EAAA,GAAA,CAAI,QAAQ,cAAA,EAAe;AAC3B,EAAA,GAAA,CAAI,MAAM,cAAA,GAAiB,WAAA;AAC3B,EAAA,GAAA,CAAI,aAAA,EAAc;AAElB,EAAA,IAAI,WAAA,GAAc,EAAA;AAElB,EAAA,MAAM,SAAA,GAAgC;AAAA,IACpC,aAAA,EAAe,CAAC,IAAA,KAAS;AACvB,MAAA,IAAI,KAAK,wBAAA,EAA0B;AACjC,QAAA,GAAA,CAAI,KAAA,CAAM,wBAAwB,IAAA,CAAK,wBAAA;AAAA,MACzC;AAAA,IACF,CAAA;AAAA,IAEA,OAAA,EAAS,CAAC,OAAA,KAAY;AACpB,MAAA,WAAA,IAAe,OAAA;AACf,MAAA,GAAA,CAAI,OAAA,CAAQ,gBAAgB,WAAW,CAAA;AACvC,MAAA,GAAA,CAAI,aAAA,EAAc;AAAA,IACpB,CAAA;AAAA,IAEA,WAAA,EAAa,CAAC,IAAA,KAAS;AACrB,MAAA,MAAM,KAAA,GAAQ,IAAA,CAAK,KAAA,IAAS,IAAA,CAAK,MAAA,IAAU,EAAA;AAC3C,MAAA,IAAI,KAAA,EAAO;AACT,QAAA,GAAA,CAAI,OAAA,CAAQ,aAAa,KAAK,CAAA;AAC9B,QAAA,GAAA,CAAI,aAAA,EAAc;AAAA,MACpB;AAAA,IACF,CAAA;AAAA,IAEA,OAAA,EAAS,CAAC,OAAA,KAAY;AACpB,MAAA,GAAA,CAAI,OAAA,CAAQ,SAAA,CAAU,CAAA,cAAA,EAAiB,OAAO,IAAI,OAAO,CAAA;AACzD,MAAA,GAAA,CAAI,aAAA,EAAc;AAAA,IACpB;AAAA,GACF;AAEA,EAAA,IAAI;AACF,IAAA,MAAM,MAAA,GAAS,MAAMQ,cAAA,CAAU,QAAA,EAAU,SAAS,CAAA;AAClD,IAAA,GAAA,CAAI,QAAQ,iBAAA,EAAkB;AAC9B,IAAA,GAAA,CAAI,MAAM,cAAA,GAAiB,MAAA;AAC3B,IAAA,GAAA,CAAI,aAAA,EAAc;AAClB,IAAA,OAAO,MAAA;AAAA,EACT,SAAS,GAAA,EAAK;AACZ,IAAA,GAAA,CAAI,QAAQ,iBAAA,EAAkB;AAC9B,IAAA,GAAA,CAAI,MAAM,cAAA,GAAiB,OAAA;AAC3B,IAAA,GAAA,CAAI,QAAQ,SAAA,CAAU,CAAA,kBAAA,EAAqBR,qBAAgB,GAAG,CAAC,IAAI,OAAO,CAAA;AAC1E,IAAA,GAAA,CAAI,aAAA,EAAc;AAClB,IAAA,MAAM,GAAA;AAAA,EACR;AACF;AC9BO,SAAS,wBAAwB,uBAAA,EAA0C;AAChF,EAAA,MAAM,iBAAA,GAAoBS,kBAAc,uBAAuB,CAAA;AAE/D,EAAA,MAAM,gBAAA,GAAmB,iBAAA,CAAkB,KAAA,CAAM,EAAA,EAAI,EAAE,CAAA;AACvD,EAAA,OAAOC,sCAAA,CAAmC;AAAA,IACxC,SAAA,EAAW,gBAAA;AAAA,IACX,SAAA,EAAW;AAAA,GACZ,CAAA;AACH;AASA,eAAsB,gBAAA,CAAiB,KAAc,KAAA,EAA0C;AAC7F,EAAA,IAAI,CAAC,IAAI,WAAA,EAAa;AACpB,IAAA,WAAA,CAAY,GAAA,EAAK,wCAAwC,OAAO,CAAA;AAChE,IAAA,OAAO,IAAA;AAAA,EACT;AAEA,EAAA,MAAM,UAAA,GAAa,MAAM,WAAA,EAAY;AAErC,EAAA,IAAI;AACF,IAAA,MAAM,cAAc,MAAMN,aAAAA,CAAS,YAAA,CAAa,GAAA,CAAI,YAAY,IAAI,CAAA;AAGpE,IAAA,MAAM,aAAa,WAAA,CAAY,MAAA;AAAA,MAC7B,CAAC,CAAA,KAAM,CAAA,CAAE,MAAA,KAAW,YAAA,IAAgB,EAAE,IAAA,EAAM;AAAA,KAC9C;AAGA,IAAA,MAAM,OAAA,GAAU,UAAA,CAAW,MAAA,CAAO,CAAC,CAAA,KAAM;AACvC,MAAA,MAAM,WAAA,GAAc,EAAE,KAAA,CAAM,KAAA,CAAM,GAAG,CAAA,CAAE,CAAC,GAAG,WAAA,EAAY;AACvD,MAAA,MAAM,SAAA,GAAY,CAAA,CAAE,IAAA,EAAM,UAAA,EAAY,WAAA,EAAY;AAClD,MAAA,OAAO,WAAA,KAAgB,cAAc,SAAA,KAAc,UAAA;AAAA,IACrD,CAAC,CAAA;AAED,IAAA,IAAI,OAAA,CAAQ,WAAW,CAAA,EAAG;AACxB,MAAA,WAAA;AAAA,QACE,GAAA;AAAA,QACA,mCAAmC,KAAK,CAAA,2CAAA,CAAA;AAAA,QACxC;AAAA,OACF;AACA,MAAA,OAAO,IAAA;AAAA,IACT;AAEA,IAAA,IAAI,OAAA,CAAQ,SAAS,CAAA,EAAG;AACtB,MAAA,MAAM,KAAA,GAAQ,QACX,GAAA,CAAI,CAAC,MAAM,CAAA,EAAA,EAAK,CAAA,CAAE,KAAK,CAAA,EAAA,EAAK,CAAA,CAAE,MAAM,UAAA,IAAc,EAAE,IAAI,CAAA,CAAE,IAAA,EAAM,eAAe,EAAE,CAAA,CAAA,CAAG,CAAA,CACpF,IAAA,CAAK,IAAI,CAAA;AACZ,MAAA,WAAA,CAAY,GAAA,EAAK,wBAAwB,KAAK,CAAA;AAAA,EAAyB,KAAK,IAAI,SAAS,CAAA;AACzF,MAAA,OAAO,IAAA;AAAA,IACT;AAEA,IAAA,MAAM,OAAA,GAAU,QAAQ,CAAC,CAAA;AACzB,IAAA,MAAM,OAAO,OAAA,CAAQ,IAAA;AACrB,IAAA,OAAO;AAAA,MACL,aAAa,IAAA,CAAK,WAAA;AAAA,MAClB,OAAO,OAAA,CAAQ,KAAA;AAAA,MACf,uBAAuB,IAAA,CAAK,qBAAA;AAAA,MAC5B,YAAY,IAAA,CAAK,UAAA;AAAA,MACjB,aAAa,IAAA,CAAK;AAAA,KACpB;AAAA,EACF,SAAS,GAAA,EAAK;AACZ,IAAA,WAAA,CAAY,KAAK,CAAA,2BAAA,EAA8BJ,oBAAAA,CAAgB,GAAG,CAAC,IAAI,OAAO,CAAA;AAC9E,IAAA,OAAO,IAAA;AAAA,EACT;AACF;AAOA,eAAsB,mBAAA,CAAoB,KAAcR,MAAAA,EAA8B;AACpF,EAAA,MAAM,KAAA,GAAQA,MAAAA,CAAM,KAAA,CAAM,CAAC,EAAE,IAAA,EAAK;AAElC,EAAA,IAAI,CAAC,KAAA,EAAO;AACV,IAAA,WAAA,CAAY,GAAA,EAAK,2DAA2D,SAAS,CAAA;AACrF,IAAA;AAAA,EACF;AAGA,EAAA,IAAI,KAAA,CAAM,WAAA,EAAY,KAAM,MAAA,EAAQ;AAClC,IAAA,YAAA,CAAa,GAAG,CAAA;AAChB,IAAA;AAAA,EACF;AAGA,EAAA,MAAM,IAAA,GAAO,MAAM,gBAAA,CAAiB,GAAA,EAAK,KAAK,CAAA;AAC9C,EAAA,IAAI,CAAC,IAAA,EAAM;AAEX,EAAA,MAAM,iBAAA,CAAkB,KAAK,IAAI,CAAA;AACnC;AAMA,eAAsB,iBAAA,CAAkB,KAAc,IAAA,EAAgC;AACpF,EAAA,IAAI,CAAC,GAAA,CAAI,WAAA,IAAe,CAAC,IAAI,cAAA,EAAgB;AAC3C,IAAA,WAAA,CAAY,GAAA,EAAK,oDAAoD,OAAO,CAAA;AAC5E,IAAA;AAAA,EACF;AAGA,EAAA,GAAA,CAAI,gBAAA,GAAmB,EAAE,IAAA,EAAK;AAC9B,EAAA,GAAA,CAAI,YAAA,EAAa;AAGjB,EAAA,GAAA,CAAI,QAAQ,aAAA,EAAc;AAE1B,EAAA,WAAA,CAAY,KAAK,CAAA,oBAAA,EAAuB,MAAA,CAAO,OAAO,IAAA,CAAK,KAAK,CAAC,CAAA,4BAAA,CAA8B,CAAA;AAG/F,EAAA,MAAM,aAAA,CAAc,KAAK,IAAI,CAAA;AAC/B;AAKO,SAAS,aAAa,GAAA,EAAoB;AAC/C,EAAA,IAAI,CAAC,IAAI,gBAAA,EAAkB;AACzB,IAAA,WAAA,CAAY,GAAA,EAAK,4BAA4B,MAAM,CAAA;AACnD,IAAA;AAAA,EACF;AAEA,EAAA,GAAA,CAAI,gBAAA,GAAmB,IAAA;AACvB,EAAA,GAAA,CAAI,YAAA,EAAa;AAGjB,EAAA,GAAA,CAAI,QAAQ,aAAA,EAAc;AAC1B,EAAA,WAAA,CAAY,KAAK,2BAA2B,CAAA;AAC9C;AAOA,eAAe,aAAA,CAAc,KAAc,IAAA,EAAgC;AACzE,EAAA,IAAI,CAAC,GAAA,CAAI,WAAA,IAAe,CAAC,IAAI,cAAA,EAAgB;AAE7C,EAAA,MAAM,OAAA,GAAU,GAAA,CAAI,WAAA,CAAY,WAAA,CAAY,SAAA;AAE5C,EAAA,IAAI;AACF,IAAA,MAAM,SAAS,MAAMmB,OAAA,CAAG,OAAA,CAAQ,GAAA,CAAI,YAAY,IAAI,CAAA;AAGpD,IAAA,MAAM,eAAe,MAAA,CAAO,MAAA;AAAA,MAC1B,CAAC,QACC,GAAA,CAAI,IAAA,KAAS,mBACX,GAAA,CAAI,MAAA,CAAO,gBAAgB,IAAA,CAAK,WAAA,IAAe,IAAI,SAAA,CAAU,WAAA,KAAgB,WAC5E,GAAA,CAAI,MAAA,CAAO,gBAAgB,OAAA,IAAW,GAAA,CAAI,SAAA,CAAU,WAAA,KAAgB,IAAA,CAAK,WAAA;AAAA,KAChF;AAGA,IAAA,YAAA,CAAa,KAAK,CAAC,CAAA,EAAG,CAAA,KAAM,IAAI,KAAK,CAAA,CAAE,UAAU,CAAA,CAAE,OAAA,KAAY,IAAI,IAAA,CAAK,EAAE,UAAU,CAAA,CAAE,SAAS,CAAA;AAG/F,IAAA,MAAM,YAAY,YAAA,CACf,MAAA,CAAO,CAAC,GAAA,KAAQ,CAAC,IAAI,IAAA,IAAQ,GAAA,CAAI,MAAA,CAAO,WAAA,KAAgB,KAAK,WAAW,CAAA,CACxE,IAAI,CAAC,GAAA,KAAQ,IAAI,WAAW,CAAA;AAE/B,IAAA,IAAI,SAAA,CAAU,SAAS,CAAA,EAAG;AACxB,MAAAA,OAAA,CAAG,SAAS,GAAA,CAAI,WAAA,CAAY,MAAM,SAAS,CAAA,CAAE,MAAM,MAAM;AAAA,MAEzD,CAAC,CAAA;AAAA,IACH;AAGA,IAAA,KAAA,MAAW,OAAO,YAAA,EAAc;AAC9B,MAAA,MAAM,MAAA,GAAS,GAAA,CAAI,MAAA,CAAO,WAAA,KAAgB,OAAA;AAC1C,MAAA,MAAM,YAAY,MAAM,mBAAA,CAAoB,KAAK,OAAA,EAAU,GAAA,CAAI,gBAAgB,IAAI,CAAA;AACnF,MAAA,IAAI,SAAA,EAAW;AACb,QAAA,gBAAA,CAAiB,GAAA,EAAK,SAAA,EAAW,MAAA,EAAQ,IAAA,CAAK,KAAK,CAAA;AAAA,MACrD;AAAA,IACF;AAEA,IAAA,GAAA,CAAI,aAAA,EAAc;AAAA,EACpB,SAAS,GAAA,EAAK;AACZ,IAAA,WAAA,CAAY,KAAK,CAAA,2BAAA,EAA8BX,oBAAAA,CAAgB,GAAG,CAAC,IAAI,OAAO,CAAA;AAAA,EAChF;AACF;AAOA,eAAsB,eAAA,CAAgB,KAAc,SAAA,EAAkC;AACpF,EAAA,IAAI,CAAC,IAAI,WAAA,IAAe,CAAC,IAAI,cAAA,IAAkB,CAAC,IAAI,gBAAA,EAAkB;AACpE,IAAA,WAAA,CAAY,GAAA,EAAK,8CAAyC,OAAO,CAAA;AACjE,IAAA;AAAA,EACF;AAEA,EAAA,MAAM,SAAA,GAAY,IAAI,gBAAA,CAAiB,IAAA;AAEvC,EAAA,IAAI;AAEF,IAAA,MAAM,YAAY,MAAMY,kBAAA;AAAA,MACtB,SAAA;AAAA,MACA,SAAA,CAAU,qBAAA;AAAA,MACV,IAAI,cAAA,CAAe;AAAA,KACrB;AAGA,IAAA,MAAMD,OAAA,CAAG,MAAA,CAAO,GAAA,CAAI,WAAA,CAAY,IAAA,EAAM;AAAA,MACpC,EAAE,gBAAA,EAAkB,SAAA,CAAU,WAAA,EAAa,SAAS,SAAA;AAAU,KAC/D,CAAA;AAGD,IAAA,gBAAA,CAAiB,GAAA,EAAK,SAAA,EAAW,IAAA,EAAM,SAAA,CAAU,KAAK,CAAA;AACtD,IAAA,GAAA,CAAI,aAAA,EAAc;AAAA,EACpB,SAAS,GAAA,EAAK;AACZ,IAAA,WAAA,CAAY,KAAK,CAAA,mBAAA,EAAsBX,oBAAAA,CAAgB,GAAG,CAAC,IAAI,OAAO,CAAA;AAAA,EACxE;AACF;AASA,eAAsB,gBAAA,CACpB,KACA,GAAA,EACkB;AAClB,EAAA,IAAI,CAAC,IAAI,gBAAA,IAAoB,CAAC,IAAI,cAAA,IAAkB,CAAC,IAAI,WAAA,EAAa;AACpE,IAAA,OAAO,KAAA;AAAA,EACT;AAEA,EAAA,MAAM,OAAA,GAAU,GAAA,CAAI,WAAA,CAAY,WAAA,CAAY,SAAA;AAC5C,EAAA,MAAM,aAAA,GAAgB,GAAA,CAAI,gBAAA,CAAiB,IAAA,CAAK,WAAA;AAGhD,EAAA,IAAI,GAAA,CAAI,MAAA,CAAO,WAAA,KAAgB,aAAA,EAAe;AAC5C,IAAA,OAAO,KAAA;AAAA,EACT;AAGA,EAAA,MAAM,YAAY,MAAM,mBAAA;AAAA,IACtB,GAAA;AAAA,IACA,OAAA;AAAA,IACA,GAAA,CAAI,cAAA;AAAA,IACJ,IAAI,gBAAA,CAAiB;AAAA,GACvB;AAEA,EAAA,IAAI,SAAA,EAAW;AACb,IAAA,gBAAA,CAAiB,GAAA,EAAK,SAAA,EAAW,KAAA,EAAO,GAAA,CAAI,OAAO,KAAK,CAAA;AACxD,IAAA,GAAA,CAAI,aAAA,EAAc;AAGlB,IAAAW,OAAA,CAAG,QAAA,CAAS,GAAA,CAAI,WAAA,CAAY,IAAA,EAAM,CAAC,IAAI,WAAW,CAAC,CAAA,CAAE,KAAA,CAAM,MAAM;AAAA,IAEjE,CAAC,CAAA;AAAA,EACH;AAEA,EAAA,OAAO,IAAA;AACT;AAUA,eAAe,mBAAA,CACb,YAAA,EACA,QAAA,EACA,iBAAA,EACA,SAAA,EACwB;AACxB,EAAA,IAAI,CAAC,YAAA,CAAa,OAAA,EAAS,OAAO,IAAA;AAElC,EAAA,IAAI;AAEF,IAAA,OAAO,MAAME,kBAAA;AAAA,MACX,YAAA,CAAa,OAAA;AAAA,MACb,SAAA,CAAU,qBAAA;AAAA,MACV,iBAAA,CAAkB;AAAA,KACpB;AAAA,EACF,CAAA,CAAA,MAAQ;AACN,IAAA,OAAO,qBAAA;AAAA,EACT;AACF;AAQA,SAAS,gBAAA,CAAiB,GAAA,EAAc,IAAA,EAAc,MAAA,EAAiB,WAAA,EAA2B;AAChG,EAAA,IAAI,MAAA,EAAQ;AACV,IAAA,GAAA,CAAI,OAAA,CAAQ,QAAQ,IAAI,CAAA;AAAA,EAC1B,CAAA,MAAO;AACL,IAAA,GAAA,CAAI,OAAA,CAAQ,KAAA,CAAM,WAAA,EAAa,IAAI,CAAA;AAAA,EACrC;AACF;;;ACtUA,IAAM,cAAA,GAAiB,GAAA;AACvB,IAAM,gBAAA,GAAmB,GAAA;AACzB,IAAM,aAAA,GAAgB,GAAA;AAItB,IAAM,iBAAA,GAA4C;AAAA,EAChD,IAAA,EAAM,cAAA;AAAA,EACN,OAAA,EAAS,gBAAA;AAAA,EACT,KAAA,EAAO,aAAA;AAAA,EACP,OAAA,EAAS;AACX,CAAA;AAKA,SAAS,eAAe,GAAA,EAA4D;AAClF,EAAA,OAAO,QAAA,IAAY,OAAO,WAAA,IAAe,GAAA;AAC3C;AAIA,eAAe,aAAA,CACb,GAAA,EACA,MAAA,EACA,GAAA,EACe;AAEf,EAAA,IAAI,eAAe,GAAG,CAAA,IAAK,GAAA,CAAI,IAAA,KAAS,kBAAkB,GAAA,EAAK;AAC7D,IAAA,MAAM,OAAA,GAAU,MAAM,gBAAA,CAAiB,GAAA,EAAK,GAAG,CAAA;AAC/C,IAAA,IAAI,OAAA,EAAS;AAAA,EACf;AAGA,EAAA,MAAM,EAAE,IAAA,EAAM,KAAA,EAAM,GAAIC,qBAAgB,GAAG,CAAA;AAC3C,EAAA,MAAM,QAAA,GAAW,iBAAA,CAAkB,KAAK,CAAA,IAAK,gBAAA;AAC7C,EAAA,MAAA,CAAO,IAAA,CAAK,IAAA,EAAM,KAAA,EAAqB,QAAQ,CAAA;AACjD;AAeA,eAAsB,oBACpB,OAAA,EAC2C;AAC3C,EAAA,MAAM,EAAE,OAAA,EAAS,WAAA,EAAa,MAAA,EAAQ,KAAI,GAAI,OAAA;AAE9C,EAAA,IAAI;AACF,IAAA,MAAM,UAAA,GAAa,MAAMC,yBAAA,CAAqB;AAAA,MAC5C,OAAA;AAAA,MACA,WAAA;AAAA,MACA,WAAW,CAAC,GAAA,KAAQ,cAAc,GAAA,EAAK,MAAA,EAAQ,OAAO,IAAI,CAAA;AAAA,MAC1D,OAAA,EAAS,CAAC,KAAA,EAAO,OAAA,KAAY;AAC3B,QAAA,MAAA,CAAO,IAAA,CAAK,wBAAA,EAA0B,SAAA,EAAW,gBAAgB,CAAA;AAAA,MACnE,CAAA;AAAA,MACA,cAAA,EAAgB,CAAC,OAAA,EAAS,UAAA,KAAe;AACvC,QAAA,MAAA,CAAO,KAAK,CAAA,iBAAA,EAAoB,OAAO,IAAI,UAAU,CAAA,CAAA,CAAA,EAAK,WAAW,gBAAgB,CAAA;AAAA,MACvF,CAAA;AAAA,MACA,eAAe,MAAM;AACnB,QAAA,MAAA,CAAO,IAAA,CAAK,uBAAA,EAAyB,SAAA,EAAW,gBAAgB,CAAA;AAAA,MAClE,CAAA;AAAA,MACA,mBAAmB,MAAM;AACvB,QAAA,MAAA,CAAO,IAAA,CAAK,+BAAA,EAAiC,OAAA,EAAS,aAAa,CAAA;AAAA,MACrE;AAAA,KACD,CAAA;AACD,IAAA,OAAO,UAAA;AAAA,EACT,CAAA,CAAA,MAAQ;AAEN,IAAA,MAAA,CAAO,IAAA,CAAK,6BAAA,EAA+B,SAAA,EAAW,gBAAgB,CAAA;AACtE,IAAA,OAAO,IAAA;AAAA,EACT;AACF;;;AClDO,IAAM,UAAN,MAAc;AAAA,EACX,GAAA;AAAA,EACA,MAAA;AAAA;AAAA,EAGC,OAAA;AAAA;AAAA,EAGA,cAAA;AAAA;AAAA,EAGD,MAAA;AAAA;AAAA,EAGR,KAAA;AAAA;AAAA,EAGA,WAAA,GAAkC,IAAA;AAAA;AAAA,EAG1B,gBAAA,GAA4C,IAAA;AAAA;AAAA,EAG3C,KAAA;AAAA;AAAA,EAGD,YAAA,GAAiD,IAAA;AAAA;AAAA,EAGjD,iBAAA,GAAoC,IAAA;AAAA;AAAA,EAGpC,SAAA,GAA8B,IAAA;AAAA,EAEtC,YAAY,KAAA,EAAoB;AAC9B,IAAA,IAAA,CAAK,KAAA,GAAQ,KAAA;AAEb,IAAA,IAAA,CAAK,KAAA,GAAQ;AAAA,MACX,WAAA,EAAa,IAAA;AAAA,MACb,aAAA,EAAe,IAAA;AAAA,MACf,qBAAA,EAAuB,IAAA;AAAA,MACvB,cAAA,EAAgB,MAAA;AAAA,MAChB,eAAA,EAAiB;AAAA,KACnB;AAGA,IAAA,IAAA,CAAK,GAAA,GAAM,IAAIC,SAAA,CAAI,IAAIC,uBAAiB,CAAA;AAGxC,IAAA,IAAA,CAAK,MAAA,GAAS,IAAIhC,UAAAA,CAAK,YAAA,CAAa,MAAM,aAAa,CAAA,EAAG,GAAG,CAAC,CAAA;AAG9D,IAAA,IAAA,CAAK,OAAA,GAAU,IAAI,OAAA,EAAQ;AAG3B,IAAA,IAAA,CAAK,cAAA,GAAiB,IAAI,cAAA,EAAe;AACzC,IAAA,IAAA,CAAK,eAAe,iBAAA,CAAkB,MAAM,IAAA,CAAK,GAAA,CAAI,eAAe,CAAA;AAGpE,IAAA,IAAA,CAAK,MAAA,GAAS,KAAK,YAAA,EAAa;AAGhC,IAAA,IAAA,CAAK,GAAA,CAAI,QAAA,CAAS,IAAA,CAAK,MAAM,CAAA;AAC7B,IAAA,IAAA,CAAK,GAAA,CAAI,QAAA,CAAS,IAAIE,YAAAA,CAAO,CAAC,CAAC,CAAA;AAC/B,IAAA,IAAA,CAAK,GAAA,CAAI,QAAA,CAAS,IAAA,CAAK,cAAc,CAAA;AACrC,IAAA,IAAA,CAAK,GAAA,CAAI,QAAA,CAAS,IAAA,CAAK,OAAO,CAAA;AAC9B,IAAA,IAAA,CAAK,GAAA,CAAI,QAAA,CAAS,IAAA,CAAK,MAAM,CAAA;AAE7B,IAAA,IAAA,CAAK,GAAA,CAAI,QAAA,CAAS,IAAA,CAAK,MAAM,CAAA;AAAA,EAC/B;AAAA;AAAA;AAAA,EAKA,KAAA,GAAc;AACZ,IAAA,IAAA,CAAK,IAAI,KAAA,EAAM;AACf,IAAA,IAAA,CAAK,YAAA,EAAa;AAClB,IAAA,IAAA,CAAK,IAAI,aAAA,EAAc;AAAA,EACzB;AAAA;AAAA,EAGA,QAAA,GAAiB;AACf,IAAA,IAAA,CAAK,cAAc,KAAA,EAAM;AACzB,IAAA,IAAA,CAAK,YAAA,GAAe,IAAA;AACpB,IAAA,IAAA,CAAK,eAAe,KAAA,EAAM;AAC1B,IAAA,IAAA,CAAK,IAAI,IAAA,EAAK;AACd,IAAA,OAAA,CAAQ,KAAK,CAAC,CAAA;AAAA,EAChB;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,OAAA,GAAgB;AACd,IAAA,IAAA,CAAK,IAAI,IAAA,EAAK;AAAA,EAChB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,UAAA,GAAmB;AACjB,IAAA,IAAA,CAAK,GAAA,GAAM,IAAI6B,SAAA,CAAI,IAAIC,uBAAiB,CAAA;AAGxC,IAAA,IAAA,CAAK,GAAA,CAAI,QAAA,CAAS,IAAA,CAAK,MAAM,CAAA;AAC7B,IAAA,IAAA,CAAK,GAAA,CAAI,QAAA,CAAS,IAAI9B,YAAAA,CAAO,CAAC,CAAC,CAAA;AAC/B,IAAA,IAAA,CAAK,GAAA,CAAI,QAAA,CAAS,IAAA,CAAK,cAAc,CAAA;AACrC,IAAA,IAAA,CAAK,GAAA,CAAI,QAAA,CAAS,IAAA,CAAK,OAAO,CAAA;AAG9B,IAAA,IAAA,CAAK,MAAA,GAAS,KAAK,YAAA,EAAa;AAChC,IAAA,IAAA,CAAK,GAAA,CAAI,QAAA,CAAS,IAAA,CAAK,MAAM,CAAA;AAC7B,IAAA,IAAA,CAAK,GAAA,CAAI,QAAA,CAAS,IAAA,CAAK,MAAM,CAAA;AAE7B,IAAA,IAAA,CAAK,IAAI,KAAA,EAAM;AACf,IAAA,IAAA,CAAK,YAAA,EAAa;AAClB,IAAA,IAAA,CAAK,IAAI,aAAA,EAAc;AAAA,EACzB;AAAA;AAAA,EAGQ,YAAA,GAA2B;AACjC,IAAA,MAAM,MAAA,GAAS,IAAI,UAAA,CAAW,IAAA,CAAK,GAAG,CAAA;AACtC,IAAA,MAAA,CAAO,uBAAA,CAAwB,IAAI+B,kCAAA,CAA6B,QAAQ,CAAC,CAAA;AACzE,IAAA,MAAA,CAAO,QAAA,GAAW,CAAC,IAAA,KAAiB,IAAA,CAAK,aAAa,IAAI,CAAA;AAC1D,IAAA,MAAA,CAAO,QAAA,GAAW,MAAM,IAAA,CAAK,WAAA,EAAY;AACzC,IAAA,MAAA,CAAO,OAAA,GAAU,MAAM,IAAA,CAAK,QAAA,EAAS;AACrC,IAAA,MAAA,CAAO,OAAA,GAAU,MAAM,IAAA,CAAK,QAAA,EAAS;AACrC,IAAA,MAAA,CAAO,OAAA,GAAU,MAAM,IAAA,CAAK,YAAA,CAAa,aAAa,CAAA;AACtD,IAAA,MAAA,CAAO,OAAA,GAAU,MAAM,IAAA,CAAK,YAAA,CAAa,MAAM,CAAA;AAC/C,IAAA,OAAO,MAAA;AAAA,EACT;AAAA;AAAA,EAGA,aAAA,GAAsB;AACpB,IAAA,IAAA,CAAK,IAAI,aAAA,EAAc;AAAA,EACzB;AAAA;AAAA;AAAA,EAKA,eAAe,GAAA,EAAwB;AACrC,IAAA,IAAA,CAAK,WAAA,GAAc,GAAA;AACnB,IAAA,IAAA,CAAK,MAAM,eAAA,GAAkB,IAAA;AAC7B,IAAA,IAAA,CAAK,iBAAA,GAAoB,uBAAA;AAAA,MACvB,IAAA,CAAK,KAAA,CAAM,kBAAA,EAAmB,CAAE;AAAA,KAClC;AACA,IAAA,IAAA,CAAK,YAAA,EAAa;AAAA,EACpB;AAAA;AAAA,EAGA,oBAAoB,GAAA,EAA6B;AAC/C,IAAA,IAAA,CAAK,gBAAA,GAAmB,GAAA;AACxB,IAAA,IAAA,CAAK,KAAA,CAAM,cAAc,GAAA,CAAI,WAAA;AAE7B,IAAA,IAAA,CAAK,YAAA,EAAa;AAClB,IAAA,IAAA,CAAK,gBAAA,EAAiB;AAAA,EACxB;AAAA;AAAA,EAGA,MAAM,uBAAA,GAAyC;AAC7C,IAAA,IAAI,CAAC,IAAA,CAAK,KAAA,CAAM,WAAA,IAAe,CAAC,KAAK,WAAA,EAAa;AAElD,IAAA,MAAM,EAAE,gBAAA,EAAAhB,iBAAAA,EAAiB,GAAI,MAAM,OAAO,gBAAgB,CAAA;AAC1D,IAAA,MAAM,MAAM,MAAMA,iBAAAA,CAAiB,KAAK,KAAA,EAAO,IAAA,CAAK,MAAM,WAAW,CAAA;AACrE,IAAA,IAAA,CAAK,gBAAA,GAAmB,GAAA;AACxB,IAAA,IAAA,CAAK,YAAA,EAAa;AAAA,EACpB;AAAA;AAAA,EAGA,IAAI,SAAA,GAAqC;AACvC,IAAA,OAAO,IAAA,CAAK,gBAAA;AAAA,EACd;AAAA;AAAA,EAGA,IAAI,WAAA,GAAuB;AACzB,IAAA,OAAO,KAAK,YAAA,KAAiB,IAAA;AAAA,EAC/B;AAAA;AAAA,EAGQ,gBAAA,GAAyB;AAC/B,IAAA,IAAI,CAAC,KAAK,gBAAA,EAAkB;AAG5B,IAAA,IAAA,CAAK,cAAc,KAAA,EAAM;AACzB,IAAA,IAAA,CAAK,YAAA,GAAe,IAAA;AAEpB,IAAA,MAAM,EAAE,MAAA,EAAQ,WAAA,EAAY,GAAI,IAAA,CAAK,gBAAA;AAErC,IAAA,mBAAA,CAAoB;AAAA,MAClB,SAAS,MAAA,CAAO,OAAA;AAAA,MAChB,WAAA;AAAA,MACA,QAAQ,IAAA,CAAK,cAAA;AAAA,MACb,GAAA,EAAK;AAAA,KACN,CAAA,CAAE,IAAA,CAAK,CAAC,IAAA,KAAS;AAChB,MAAA,IAAA,CAAK,YAAA,GAAe,IAAA;AAAA,IACtB,CAAC,CAAA;AAAA,EACH;AAAA;AAAA,EAIA,MAAc,aAAa,IAAA,EAA6B;AACtD,IAAA,MAAM,OAAA,GAAU,KAAK,IAAA,EAAK;AAC1B,IAAA,IAAI,CAAC,OAAA,EAAS;AAGd,IAAA,IAAI,OAAA,CAAQ,UAAA,CAAW,GAAG,CAAA,EAAG;AAC3B,MAAA,MAAM,mBAAA,CAAoB,MAAM,OAAO,CAAA;AACvC,MAAA;AAAA,IACF;AAGA,IAAA,IAAI,OAAA,CAAQ,UAAA,CAAW,GAAG,CAAA,EAAG;AAC3B,MAAA,MAAM,OAAA,GAAU,MAAM,aAAA,CAAc,IAAA,EAAM,OAAO,CAAA;AACjD,MAAA,IAAI,OAAA,EAAS;AAAA,IACf;AAGA,IAAA,IAAI,KAAK,SAAA,EAAW;AAClB,MAAA,MAAM,eAAA,CAAgB,MAAM,OAAO,CAAA;AAAA,IACrC,CAAA,MAAO;AACL,MAAA,MAAM,IAAA,CAAK,YAAY,OAAO,CAAA;AAAA,IAChC;AAAA,EACF;AAAA,EAEQ,WAAA,GAAoB;AAC1B,IAAA,IAAI,IAAA,CAAK,KAAA,CAAM,cAAA,KAAmB,WAAA,EAAa;AAE7C,MAAA,IAAA,CAAK,OAAA,CAAQ,SAAA,CAAU,uDAAA,EAAyD,SAAS,CAAA;AACzF,MAAA,IAAA,CAAK,aAAA,EAAc;AAAA,IACrB;AAAA,EACF;AAAA;AAAA,EAIA,MAAc,YAAY,QAAA,EAAiC;AACzD,IAAA,IAAI,CAAC,KAAK,gBAAA,EAAkB;AAC1B,MAAA,IAAA,CAAK,OAAA,CAAQ,SAAA;AAAA,QACX,0EAAA;AAAA,QACA;AAAA,OACF;AACA,MAAA,IAAA,CAAK,aAAA,EAAc;AACnB,MAAA;AAAA,IACF;AAGA,IAAA,IAAA,CAAK,OAAA,CAAQ,QAAQ,QAAQ,CAAA;AAC7B,IAAA,IAAA,CAAK,MAAM,cAAA,GAAiB,SAAA;AAC5B,IAAA,IAAA,CAAK,YAAA,EAAa;AAClB,IAAA,IAAA,CAAK,aAAA,EAAc;AAEnB,IAAA,IAAI;AAEF,MAAA,MAAM,IAAA,GAAO,MAAMC,cAAAA,CAAU,aAAA;AAAA,QAC3B,KAAK,gBAAA,CAAiB,IAAA;AAAA,QACtB,KAAK,gBAAA,CAAiB;AAAA,OACxB;AACA,MAAA,MAAM,SAAS,IAAA,CAAK,GAAA,CAAI,CAAC,CAAA,KAAM,EAAE,WAAqB,CAAA;AAGtD,MAAA,MAAM,OAAA,GAAU,IAAA,CAAK,KAAA,CAAM,cAAA,EAAe;AAC1C,MAAA,MAAM,kBAAA,GAAqB,IAAA,CAAK,KAAA,CAAM,qBAAA,IAAyB,OAAA,CAAQ,gBAAA;AAGvE,MAAA,MAAM,QAAA,GAAW,MAAMgB,cAAA,CAAU,cAAA,CAAe;AAAA,QAC9C,OAAA,EAAS,IAAA,CAAK,gBAAA,CAAiB,MAAA,CAAO,OAAA;AAAA,QACtC,WAAA,EAAa,KAAK,gBAAA,CAAiB,WAAA;AAAA,QACnC,kBAAA,EAAoB,KAAK,gBAAA,CAAiB,kBAAA;AAAA,QAC1C,WAAA,EAAa,KAAK,gBAAA,CAAiB,WAAA;AAAA,QACnC,QAAA;AAAA,QACA,MAAA;AAAA,QACA;AAAA,OACD,CAAA;AAGD,MAAA,MAAM,MAAA,GAAS,MAAM,cAAA,CAAe,IAAA,EAAM,QAAQ,CAAA;AAGlD,MAAA,IAAI,OAAO,qBAAA,EAAuB;AAChC,QAAA,IAAA,CAAK,KAAA,CAAM,wBAAwB,MAAA,CAAO,qBAAA;AAC1C,QAAA,MAAM,aAAA,GAAwC;AAAA,UAC5C,kBAAkB,MAAA,CAAO;AAAA,SAC3B;AAEA,QAAA,MAAM,iBAAA,GACH,MAAA,CAAO,WAAA,EAAa,mBAAA,IACpB,OAAO,QAAA,EAAU,mBAAA;AACpB,QAAA,IAAI,iBAAA,EAAmB;AACrB,UAAA,aAAA,CAAc,iBAAA,GAAoB,iBAAA;AAAA,QACpC;AACA,QAAA,IAAA,CAAK,KAAA,CAAM,kBAAkB,aAAa,CAAA;AAAA,MAC5C;AAAA,IACF,SAAS,GAAA,EAAK;AACZ,MAAA,IAAA,CAAK,MAAM,cAAA,GAAiB,OAAA;AAC5B,MAAA,IAAA,CAAK,QAAQ,SAAA,CAAU,CAAA,OAAA,EAAUnB,qBAAgB,GAAG,CAAC,IAAI,OAAO,CAAA;AAAA,IAClE;AAEA,IAAA,IAAA,CAAK,MAAM,cAAA,GAAiB,MAAA;AAC5B,IAAA,IAAA,CAAK,YAAA,EAAa;AAClB,IAAA,IAAA,CAAK,aAAA,EAAc;AAAA,EACrB;AAAA;AAAA;AAAA,EAKA,YAAA,GAAqB;AACnB,IAAA,MAAM,UAAA,GACJ,IAAA,CAAK,KAAA,CAAM,cAAA,KAAmB,MAAA,GAC1B,MAAA,CAAO,OAAA,CAAQ,OAAO,CAAA,GACtB,IAAA,CAAK,KAAA,CAAM,cAAA,KAAmB,WAAA,GAC5B,MAAA,CAAO,OAAA,CAAQ,cAAc,CAAA,GAC7B,IAAA,CAAK,KAAA,CAAM,cAAA,KAAmB,SAAA,GAC5B,MAAA,CAAO,OAAA,CAAQ,YAAY,CAAA,GAC3B,MAAA,CAAO,KAAA,CAAM,OAAO,CAAA;AAE9B,IAAA,IAAI,KAAK,SAAA,EAAW;AAClB,MAAA,IAAA,CAAK,MAAA,CAAO,OAAA,CAAQ,YAAA,CAAa,CAAA,IAAA,EAAO,IAAA,CAAK,UAAU,IAAA,CAAK,KAAK,CAAA,CAAA,EAAI,UAAU,CAAC,CAAA;AAAA,IAClF,CAAA,MAAO;AACL,MAAA,IAAA,CAAK,OAAO,OAAA,CAAQ,YAAA,CAAa,KAAK,KAAA,CAAM,aAAA,EAAe,UAAU,CAAC,CAAA;AAAA,IACxE;AAAA,EACF;AAAA;AAAA;AAAA,EAKA,IAAI,gBAAA,GAAqC;AACvC,IAAA,OAAO,IAAA,CAAK,SAAA;AAAA,EACd;AAAA,EAEA,IAAI,iBAAiB,EAAA,EAAsB;AACzC,IAAA,IAAA,CAAK,SAAA,GAAY,EAAA;AAAA,EACnB;AAAA;AAAA,EAGA,IAAI,cAAA,GAAiC;AACnC,IAAA,OAAO,IAAA,CAAK,iBAAA;AAAA,EACd;AACF,CAAA;;;ACvXA,OAAA,CAAQ,QAAQ,MAAM;AAAC,CAAA;AACvB,IAAM,YAAY,OAAA,CAAQ,IAAA;AAC1B,OAAA,CAAQ,IAAA,GAAO,IAAI,IAAA,KAAoB;AACrC,EAAA,IAAI,OAAO,IAAA,CAAK,CAAC,CAAA,KAAM,QAAA,IAAY,KAAK,CAAC,CAAA,CAAE,UAAA,CAAW,OAAO,CAAA,EAAG;AAChE,EAAA,SAAA,CAAU,GAAG,IAAI,CAAA;AACnB,CAAA;AAaA,IAAM,OAAA,GAAU,IAAIoB,iBAAA,EAAQ;AAE5B,OAAA,CACG,IAAA,CAAK,UAAU,CAAA,CACf,WAAA,CAAY,qEAAgE,CAAA,CAC5E,OAAA,CAAQ,OAAO,CAAA,CACf,OAAO,sBAAA,EAAwB,qBAAqB,CAAA,CACpD,MAAA,CAAO,OAAO,IAAA,KAAiC;AAC9C,EAAA,MAAM,KAAA,GAAQ,IAAIC,oBAAA,EAAgB;AAGlC,EAAA,IAAI;AACF,IAAA,KAAA,CAAM,aAAA,EAAc;AAAA,EACtB,CAAA,CAAA,MAAQ;AACN,IAAA,OAAA,CAAQ,MAAM,wDAAwD,CAAA;AACtE,IAAA,OAAA,CAAQ,KAAK,CAAC,CAAA;AAAA,EAChB;AAGA,EAAA,MAAM,EAAE,WAAA,EAAa,mBAAA,EAAqB,uBAAsB,GAC9D,MAAM,oBAAoB,KAAK,CAAA;AAGjC,EAAA,MAAM,WAAA,GAAc,KAAK,SAAA,IAAa,mBAAA;AAGtC,EAAA,MAAM,GAAA,GAAM,IAAI,OAAA,CAAQ,KAAK,CAAA;AAC7B,EAAA,GAAA,CAAI,eAAe,WAAW,CAAA;AAE9B,EAAA,IAAI,WAAA,EAAa;AACf,IAAA,IAAI;AACF,MAAA,MAAM,KAAA,GAAQ,MAAMnB,qBAAAA,CAAiB,KAAA,EAAO,WAAW,CAAA;AACvD,MAAA,GAAA,CAAI,oBAAoB,KAAK,CAAA;AAG7B,MAAA,IAAI,qBAAA,IAAyB,gBAAgB,mBAAA,EAAqB;AAChE,QAAA,GAAA,CAAI,MAAM,aAAA,GAAgB,qBAAA;AAAA,MAC5B,CAAA,MAAO;AACL,QAAA,MAAM,MAAA,GAAS,MAAML,eAAAA,CAAW,cAAA,CAAe,YAAY,IAAI,CAAA;AAC/D,QAAA,MAAM,KAAK,MAAA,CAAO,IAAA,CAAK,CAAC,CAAA,KAAM,CAAA,CAAE,gBAAgB,WAAW,CAAA;AAC3D,QAAA,IAAI,EAAA,EAAI;AACN,UAAA,GAAA,CAAI,KAAA,CAAM,gBAAgB,EAAA,CAAG,IAAA;AAAA,QAC/B;AAAA,MACF;AAAA,IACF,SAAS,GAAA,EAAK;AACZ,MAAA,GAAA,CAAI,QAAQ,SAAA,CAAU,CAAA,0BAAA,EAA6BG,qBAAgB,GAAG,CAAC,IAAI,SAAS,CAAA;AACpF,MAAA,GAAA,CAAI,OAAA,CAAQ,UAAU,wDAAwD,CAAA;AAAA,IAChF;AAAA,EACF,CAAA,MAAO;AACL,IAAA,GAAA,CAAI,OAAA,CAAQ,SAAA;AAAA,MACV;AAAA,KACF;AAAA,EACF;AAGA,EAAA,MAAM,OAAA,GAAU,MAAM,cAAA,EAAe;AACrC,EAAA,IAAI,QAAQ,gBAAA,EAAkB;AAC5B,IAAA,GAAA,CAAI,KAAA,CAAM,wBAAwB,OAAA,CAAQ,gBAAA;AAAA,EAC5C;AAGA,EAAA,IAAI,OAAA,CAAQ,iBAAA,IAAqB,OAAA,CAAQ,gBAAA,IAAoB,IAAI,WAAA,EAAa;AAC5E,IAAA,IAAI;AACF,MAAA,MAAM,OAAA,GAAU,MAAMM,kBAAAA,CAAc,sBAAA;AAAA,QAClC,IAAI,WAAA,CAAY,IAAA;AAAA,QAChB,OAAA,CAAQ;AAAA,OACV;AACA,MAAA,MAAM,UAAA,GAAc,OAAA,CAAoC,OAAA,IAAW,EAAC;AACpE,MAAA,MAAM,SAAS,UAAA,CAAW,IAAA;AAAA,QACxB,CAAC,CAAA,KACE,CAAA,CAAuC,mBAAA,KAAwB,OAAA,CAAQ;AAAA,OAC5E;AAEA,MAAA,IAAI,MAAA,EAAQ,OAAA,IAAW,MAAA,CAAO,OAAA,CAAQ,SAAS,CAAA,EAAG;AAChD,QAAA,KAAA,MAAW,GAAA,IAAO,OAAO,OAAA,EAAS;AAChC,UAAA,IAAI,GAAA,CAAI,SAAS,MAAA,EAAQ;AACvB,YAAA,GAAA,CAAI,OAAA,CAAQ,OAAA,CAAQ,GAAA,CAAI,OAAO,CAAA;AAAA,UACjC,CAAA,MAAA,IAAW,GAAA,CAAI,IAAA,KAAS,WAAA,EAAa;AACnC,YAAA,GAAA,CAAI,OAAA,CAAQ,YAAA,CAAa,GAAA,CAAI,OAAO,CAAA;AAAA,UACtC;AAAA,QACF;AACA,QAAA,GAAA,CAAI,OAAA,CAAQ,UAAU,wCAAwC,CAAA;AAAA,MAChE;AAAA,IACF,CAAA,CAAA,MAAQ;AAAA,IAER;AAAA,EACF;AAEA,EAAA,GAAA,CAAI,OAAA,CAAQ,SAAA;AAAA,IACV;AAAA,GACF;AACA,EAAA,GAAA,CAAI,KAAA,EAAM;AACZ,CAAC,CAAA;AAEH,OAAA,CAAQ,KAAA,EAAM","file":"index.js","sourcesContent":["/**\n * ARBI TUI theme — color palette and component styling functions.\n *\n * Uses chalk for ANSI color output. All theme values are functions\n * that wrap text in the appropriate escape sequences.\n */\n\nimport chalk from 'chalk'\nimport type { MarkdownTheme, EditorTheme, SelectListTheme } from '@mariozechner/pi-tui'\n\n// ── Color palette ──────────────────────────────────────────────────────────\n\nexport const colors = {\n /** Primary accent — teal/cyan used for headings, prompts, highlights */\n accent: chalk.cyan,\n accentBold: chalk.bold.cyan,\n\n /** Secondary accent — blue for links and info */\n secondary: chalk.blue,\n\n /** Muted text — dim gray for borders, metadata */\n muted: chalk.gray,\n mutedDim: chalk.dim.gray,\n\n /** Success — green for completed states */\n success: chalk.green,\n\n /** Warning — yellow for pending states, code */\n warning: chalk.yellow,\n\n /** Error — red for error messages */\n error: chalk.red,\n errorBold: chalk.bold.red,\n\n /** Text — default and bold */\n text: chalk.white,\n textBold: chalk.bold.white,\n\n /** User message styling */\n userLabel: chalk.bold.green,\n userText: chalk.white,\n\n /** Assistant message styling */\n assistantLabel: chalk.bold.cyan,\n\n /** System message styling */\n systemText: chalk.dim,\n systemInfo: chalk.dim.cyan,\n systemError: chalk.dim.red,\n systemWarning: chalk.dim.yellow,\n\n /** Agent step styling */\n stepPending: chalk.dim.yellow,\n stepComplete: chalk.dim.green,\n} as const\n\n// ── Background functions ───────────────────────────────────────────────────\n\nexport const bgFn = {\n /** Subtle background for user messages */\n user: (text: string) => chalk.bgGray(text),\n\n /** Background for agent steps */\n agentStep: (text: string) => text,\n} as const\n\n// ── Component themes ───────────────────────────────────────────────────────\n\nexport const selectListTheme: SelectListTheme = {\n selectedPrefix: (s: string) => colors.accent(s),\n selectedText: (s: string) => colors.text(s),\n description: (s: string) => colors.muted(s),\n scrollInfo: (s: string) => colors.muted(s),\n noMatch: (s: string) => colors.muted(s),\n}\n\nexport const editorTheme: EditorTheme = {\n borderColor: (s: string) => colors.accent(s),\n selectList: selectListTheme,\n}\n\nexport const markdownTheme: MarkdownTheme = {\n heading: (s: string) => colors.accentBold(s),\n link: (s: string) => chalk.underline.blue(s),\n linkUrl: (s: string) => colors.muted(s),\n code: (s: string) => colors.warning(s),\n codeBlock: (s: string) => colors.text(s),\n codeBlockBorder: (s: string) => colors.muted(s),\n quote: (s: string) => chalk.italic.gray(s),\n quoteBorder: (s: string) => colors.muted(s),\n hr: (s: string) => colors.muted(s),\n listBullet: (s: string) => colors.accent(s),\n bold: (s: string) => chalk.bold(s),\n italic: (s: string) => chalk.italic(s),\n strikethrough: (s: string) => chalk.strikethrough(s),\n underline: (s: string) => chalk.underline(s),\n}\n\n// ── Header / Footer helpers ────────────────────────────────────────────────\n\nexport function formatHeader(workspaceName: string | null, status: string): string {\n const app = colors.accentBold('ARBI')\n const ws = workspaceName ? colors.muted(` | ${workspaceName}`) : ''\n const st = colors.muted(` | ${status}`)\n return `${app}${ws}${st}`\n}\n\nexport function formatPrompt(): string {\n return colors.accent('> ')\n}\n","/**\n * Syntax highlighting theme for code blocks in Markdown.\n *\n * Provides a highlightCode function compatible with pi-tui's\n * MarkdownTheme.highlightCode option.\n */\n\nimport chalk from 'chalk'\n\n/**\n * Simple keyword-based syntax highlighting for code blocks.\n * Returns an array of styled lines.\n *\n * For a first version, we apply basic keyword coloring. This can be\n * upgraded to use a proper highlighter (e.g., cli-highlight) later.\n */\n// eslint-disable-next-line @typescript-eslint/no-unused-vars\nexport function highlightCode(code: string, lang?: string): string[] {\n const lines = code.split('\\n')\n\n return lines.map((line) => {\n // Highlight common keywords\n let styled = line\n // String literals (double and single quoted)\n .replace(/([\"'])(?:(?=(\\\\?))\\2.)*?\\1/g, (m) => chalk.green(m))\n // Numbers\n .replace(/\\b(\\d+\\.?\\d*)\\b/g, (m) => chalk.yellow(m))\n // Comments (// and #)\n .replace(/(\\/\\/.*|#.*)$/g, (m) => chalk.gray(m))\n\n // Keywords (applied after strings/comments to avoid conflicts in simple cases)\n const keywords =\n /\\b(const|let|var|function|return|if|else|for|while|import|export|from|class|extends|new|async|await|try|catch|throw|type|interface|enum|def|self|None|True|False|print)\\b/g\n styled = styled.replace(keywords, (m) => chalk.cyan(m))\n\n return styled\n })\n}\n","/**\n * AssistantMessage — streaming markdown response from the RAG assistant.\n *\n * Wraps pi-tui's Markdown component. Call setText() as tokens arrive\n * to update the rendered content incrementally.\n */\n\nimport { Container, Markdown, Text } from '@mariozechner/pi-tui'\nimport { markdownTheme, colors } from '../theme/theme.js'\nimport { highlightCode } from '../theme/syntax-theme.js'\n\nconst assistantMarkdownTheme = {\n ...markdownTheme,\n highlightCode,\n}\n\nexport class AssistantMessage extends Container {\n private markdown: Markdown\n private label: Text\n\n constructor() {\n super()\n this.label = new Text(colors.assistantLabel('Assistant'), 1, 0)\n this.markdown = new Markdown('', 1, 0, assistantMarkdownTheme)\n this.addChild(this.label)\n this.addChild(this.markdown)\n }\n\n /** Update the response text (called as tokens stream in). */\n setText(text: string): void {\n this.markdown.setText(text)\n }\n}\n","/**\n * UserMessage — displays a user's submitted question.\n *\n * Wraps pi-tui's Markdown component with user-specific styling.\n */\n\nimport { Container, Markdown, Text } from '@mariozechner/pi-tui'\nimport { markdownTheme, colors } from '../theme/theme.js'\n\nexport class UserMessage extends Container {\n constructor(text: string) {\n super()\n const label = new Text(colors.userLabel('You'), 1, 0)\n const content = new Markdown(text, 1, 0, markdownTheme)\n this.addChild(label)\n this.addChild(content)\n }\n}\n","/**\n * SystemMessage — info, warning, and error messages.\n *\n * Wraps pi-tui's Text component with dim/accent styling.\n */\n\nimport { Text } from '@mariozechner/pi-tui'\nimport { colors } from '../theme/theme.js'\n\nexport type SystemMessageLevel = 'info' | 'warning' | 'error'\n\nexport class SystemMessage extends Text {\n constructor(message: string, level: SystemMessageLevel = 'info') {\n const styleFn =\n level === 'error'\n ? colors.systemError\n : level === 'warning'\n ? colors.systemWarning\n : colors.systemInfo\n super(styleFn(message), 1, 0)\n }\n}\n","/**\n * AgentStep — displays a single agent processing step.\n *\n * Shows the step focus/description with a status indicator.\n * Background changes from pending (yellow) to complete (green).\n */\n\nimport { Text } from '@mariozechner/pi-tui'\nimport { colors } from '../theme/theme.js'\n\nexport class AgentStep extends Text {\n private completed = false\n\n constructor(focus: string) {\n const styled = `${colors.stepPending('>')} ${colors.muted(focus)}`\n super(styled, 2, 0)\n }\n\n /** Mark this step as completed. */\n complete(): void {\n if (this.completed) return\n this.completed = true\n // Re-render would require knowing the original text — for now we leave styling as-is.\n // The step stays visible as context for the user.\n }\n}\n","/**\n * ChatLog — container managing the message list and streaming runs.\n *\n * Provides methods for adding user/system messages and managing\n * assistant streaming lifecycle (start → update → finalize).\n */\n\nimport { Container, Spacer, Text } from '@mariozechner/pi-tui'\nimport { AssistantMessage } from './assistant-message.js'\nimport { UserMessage } from './user-message.js'\nimport { SystemMessage, type SystemMessageLevel } from './system-message.js'\nimport { AgentStep } from './agent-step.js'\nimport { colors } from '../theme/theme.js'\n\nexport class ChatLog extends Container {\n /** Currently streaming assistant message (null when idle). */\n private activeAssistant: AssistantMessage | null = null\n\n /** Agent steps associated with the current streaming run. */\n private activeSteps: AgentStep[] = []\n\n /** Add a user message to the log. */\n addUser(text: string): void {\n this.addChild(new UserMessage(text))\n this.addChild(new Spacer(1))\n }\n\n /** Add a complete assistant message (non-streaming, e.g. for history restoration). */\n addAssistant(text: string): void {\n const msg = new AssistantMessage()\n msg.setText(text)\n this.addChild(msg)\n this.addChild(new Spacer(1))\n }\n\n /** Add a system/info/error message. */\n addSystem(message: string, level: SystemMessageLevel = 'info'): void {\n this.addChild(new SystemMessage(message, level))\n this.addChild(new Spacer(1))\n }\n\n /** Add a received DM message (cyan label with sender email). */\n addDm(senderEmail: string, text: string): void {\n const container = new Container()\n const label = new Text(colors.accent(senderEmail), 1, 0)\n const content = new Text(colors.text(text), 1, 0)\n container.addChild(label)\n container.addChild(content)\n this.addChild(container)\n this.addChild(new Spacer(1))\n }\n\n /** Remove all messages from the chat log. */\n clearMessages(): void {\n this.activeAssistant = null\n this.activeSteps = []\n // Remove all children by iterating backwards\n while (this.children.length > 0) {\n this.removeChild(this.children[this.children.length - 1])\n }\n }\n\n /** Start a new assistant streaming response. */\n startAssistant(): void {\n this.activeAssistant = new AssistantMessage()\n this.activeSteps = []\n this.addChild(this.activeAssistant)\n }\n\n /** Update the active assistant message with accumulated text. */\n updateAssistant(text: string): void {\n this.activeAssistant?.setText(text)\n }\n\n /** Add an agent step to the current streaming run. */\n addAgentStep(focus: string): void {\n if (!this.activeAssistant) return\n const step = new AgentStep(focus)\n this.activeSteps.push(step)\n // Insert step before the assistant message content\n this.addChild(step)\n }\n\n /** Finalize the current assistant response. */\n finalizeAssistant(): void {\n for (const step of this.activeSteps) {\n step.complete()\n }\n this.activeAssistant = null\n this.activeSteps = []\n this.addChild(new Spacer(1))\n }\n}\n","/**\n * ArbiEditor — custom Editor with ARBI-specific keybindings.\n *\n * Extends pi-tui's Editor to add:\n * - Escape → abort active stream\n * - Ctrl+C → clear input / double-tap to exit\n * - Ctrl+D → exit\n * - Ctrl+W → workspace selector\n * - Ctrl+N → new conversation\n */\n\nimport { Editor, matchesKey, Key, type TUI } from '@mariozechner/pi-tui'\nimport { editorTheme } from '../theme/theme.js'\n\nexport class ArbiEditor extends Editor {\n /** Callback when Escape is pressed (abort streaming). */\n onEscape?: () => void\n\n /** Callback when Ctrl+C is pressed (clear or exit). */\n onCtrlC?: () => void\n\n /** Callback when Ctrl+D is pressed (exit). */\n onCtrlD?: () => void\n\n /** Callback when Ctrl+W is pressed (workspace selector). */\n onCtrlW?: () => void\n\n /** Callback when Ctrl+N is pressed (new conversation). */\n onCtrlN?: () => void\n\n /** Track Ctrl+C presses for double-tap exit. */\n private lastCtrlCTime = 0\n\n constructor(tui: TUI) {\n super(tui, editorTheme, { paddingX: 1 })\n }\n\n override handleInput(data: string): void {\n if (matchesKey(data, Key.escape)) {\n this.onEscape?.()\n return\n }\n\n if (matchesKey(data, Key.ctrl('c'))) {\n const now = Date.now()\n if (this.getText().trim()) {\n // First Ctrl+C with content: clear input\n this.setText('')\n this.lastCtrlCTime = now\n } else if (now - this.lastCtrlCTime < 1000) {\n // Double Ctrl+C within 1s: exit\n this.onCtrlC?.()\n } else {\n this.lastCtrlCTime = now\n this.onCtrlC?.()\n }\n return\n }\n\n if (matchesKey(data, Key.ctrl('d'))) {\n this.onCtrlD?.()\n return\n }\n\n if (matchesKey(data, Key.ctrl('w'))) {\n this.onCtrlW?.()\n return\n }\n\n if (matchesKey(data, Key.ctrl('n'))) {\n this.onCtrlN?.()\n return\n }\n\n // Pass all other input to the base Editor\n super.handleInput(data)\n }\n}\n","/**\n * ToastContainer — auto-dismissing notification toasts.\n *\n * Manages a list of styled Text children that appear briefly then\n * auto-remove themselves. Used for WebSocket event notifications.\n */\n\nimport { Container, Text } from '@mariozechner/pi-tui'\nimport chalk from 'chalk'\n\nexport type ToastLevel = 'info' | 'success' | 'warning' | 'error'\n\nconst LEVEL_STYLE: Record<ToastLevel, (s: string) => string> = {\n info: chalk.dim.cyan,\n success: chalk.dim.green,\n warning: chalk.dim.yellow,\n error: chalk.dim.red,\n}\n\nfunction formatTimestamp(): string {\n const now = new Date()\n const hh = String(now.getHours()).padStart(2, '0')\n const mm = String(now.getMinutes()).padStart(2, '0')\n const ss = String(now.getSeconds()).padStart(2, '0')\n return `${hh}:${mm}:${ss}`\n}\n\ninterface ActiveToast {\n text: Text\n timer: ReturnType<typeof setTimeout>\n}\n\nexport class ToastContainer extends Container {\n private activeToasts: ActiveToast[] = []\n private renderCallback: (() => void) | null = null\n\n /** Set the callback used to trigger a TUI re-render after toast changes. */\n setRenderCallback(cb: () => void): void {\n this.renderCallback = cb\n }\n\n /** Show a toast notification that auto-dismisses after `durationMs`. */\n show(message: string, level: ToastLevel = 'info', durationMs = 5000): void {\n const styleFn = LEVEL_STYLE[level]\n const formatted = styleFn(`[${formatTimestamp()}] ${message}`)\n const text = new Text(formatted, 1, 0)\n\n const timer = setTimeout(() => {\n this.dismiss(text)\n }, durationMs)\n\n this.activeToasts.push({ text, timer })\n this.addChild(text)\n this.renderCallback?.()\n }\n\n /** Remove all active toasts immediately. */\n clear(): void {\n for (const toast of this.activeToasts) {\n clearTimeout(toast.timer)\n this.removeChild(toast.text)\n }\n this.activeToasts = []\n this.renderCallback?.()\n }\n\n private dismiss(text: Text): void {\n const idx = this.activeToasts.findIndex((t) => t.text === text)\n if (idx !== -1) {\n clearTimeout(this.activeToasts[idx].timer)\n this.activeToasts.splice(idx, 1)\n this.removeChild(text)\n this.renderCallback?.()\n }\n }\n}\n","/**\n * Command registry — slash commands available in the TUI.\n *\n * Each command has a name, description, and optional argument hint.\n * Used for autocomplete and help display.\n */\n\nimport type { SlashCommand } from '@mariozechner/pi-tui'\n\nexport interface TuiCommand extends SlashCommand {\n name: string\n description: string\n}\n\nexport const commands: TuiCommand[] = [\n { name: 'help', description: 'Show available commands' },\n { name: 'login', description: 'Log in (re-authenticate)' },\n { name: 'register', description: 'Register a new account' },\n { name: 'create', description: 'Create a new workspace: /create <name>' },\n { name: 'workspace', description: 'Switch workspace: /workspace <id>' },\n { name: 'workspaces', description: 'List all workspaces' },\n { name: 'contacts', description: 'List contacts (type @name to DM)' },\n { name: 'invite', description: 'Invite a contact: /invite user@example.com' },\n { name: 'docs', description: 'List documents in current workspace' },\n { name: 'upload', description: 'Upload a file: /upload <path>' },\n { name: 'delete', description: 'Delete a document: /delete <doc-id>' },\n { name: 'conversations', description: 'List conversations' },\n { name: 'new', description: 'Start fresh conversation (clear threading)' },\n { name: 'models', description: 'List available AI models' },\n { name: 'health', description: 'Show system health status' },\n { name: 'status', description: 'Show auth/workspace/connection status' },\n { name: 'logout', description: 'Log out and clear credentials' },\n { name: 'exit', description: 'Exit TUI' },\n { name: 'quit', description: 'Exit TUI' },\n]\n\n/** Format all commands as a help string for display. */\nexport function formatHelpText(): string {\n const lines = commands\n .filter((c) => c.name !== 'quit') // Don't show duplicate exit/quit\n .map((c) => ` /${c.name} — ${c.description}`)\n return [\n 'Available commands:',\n '',\n ...lines,\n '',\n 'Direct messages:',\n ' @name — Switch to DM channel with a contact',\n ' @arbi — Switch back to AI chat',\n '',\n 'Keyboard shortcuts:',\n ' Ctrl+N — New conversation',\n ' Ctrl+W — Switch workspace',\n ' Ctrl+D — Exit',\n ' Escape — Abort streaming',\n ].join('\\n')\n}\n","/**\n * Interactive prompt helpers using @inquirer/prompts.\n *\n * These are only used in interactive (TTY) flows — before the TUI starts\n * or after temporarily stopping it. Mirrors the CLI's prompt wrappers\n * for consistent validation and UX.\n */\n\nimport { select, input, password, confirm, checkbox, search } from '@inquirer/prompts'\n\nexport { select, input, password, confirm, checkbox, search }\n\n/**\n * Prompt user to pick from a list of items.\n * Returns the value of the selected choice.\n */\nexport async function promptSelect<T>(\n message: string,\n choices: Array<{ name: string; value: T; description?: string }>\n): Promise<T> {\n return select({ message, choices })\n}\n\n/**\n * Prompt user to pick multiple items from a list.\n * Returns array of selected values.\n */\nexport async function promptCheckbox<T>(\n message: string,\n choices: Array<{ name: string; value: T; checked?: boolean }>\n): Promise<T[]> {\n return checkbox({ message, choices })\n}\n\n/**\n * Prompt user to search and pick from a large list.\n * Type-ahead fuzzy filtering — best for docs (could be hundreds).\n */\nexport async function promptSearch<T>(\n message: string,\n choices: Array<{ name: string; value: T; description?: string }>\n): Promise<T> {\n return search({\n message,\n source: async (term) => {\n if (!term) return choices\n const lower = term.toLowerCase()\n return choices.filter((c) => c.name.toLowerCase().includes(lower))\n },\n })\n}\n\n/**\n * Prompt for text input. Returns trimmed string.\n */\nexport async function promptInput(message: string, required = true): Promise<string> {\n return input({\n message,\n validate: required ? (v) => (v.trim() ? true : 'Required') : undefined,\n })\n}\n\n/**\n * Prompt for a password (masked input).\n */\nexport async function promptPassword(message: string): Promise<string> {\n return password({\n message,\n mask: '*',\n validate: (v) => (v ? true : 'Required'),\n })\n}\n\n/**\n * Prompt for yes/no confirmation.\n */\nexport async function promptConfirm(message: string, defaultValue = true): Promise<boolean> {\n return confirm({ message, default: defaultValue })\n}\n","/**\n * Authentication flows for the TUI.\n *\n * Handles login and registration using @inquirer/prompts for interactive input.\n * These flows run BEFORE the TUI takes over the terminal (pi-tui raw mode),\n * or after temporarily stopping the TUI.\n */\n\nimport 'fake-indexeddb/auto'\nimport { createArbiClient } from '@arbidocs/sdk'\nimport type { ConfigStore, AuthContext } from '@arbidocs/core'\nimport {\n getErrorMessage,\n performPasswordLogin,\n formatWorkspaceChoices,\n resolveAuth,\n workspaces,\n} from '@arbidocs/core'\nimport { promptInput, promptPassword, promptSelect, promptConfirm } from './prompts.js'\n\n// ── Login ──────────────────────────────────────────────────────────────────\n\nexport interface LoginResult {\n authContext: AuthContext\n selectedWorkspaceId?: string\n selectedWorkspaceName?: string\n}\n\n/**\n * Interactive login flow. Prompts for email/password, authenticates,\n * and offers workspace selection.\n *\n * Must be called before the TUI starts (or after stopping it).\n */\nexport async function interactiveLogin(store: ConfigStore): Promise<LoginResult> {\n const config = store.requireConfig()\n\n const email = await promptInput('Email')\n const pw = await promptPassword('Password')\n\n const authContext = await performPasswordLogin(config, email, pw, store)\n\n console.info(`Logged in as ${email}`)\n\n // Workspace selection\n const result = await selectOrCreateWorkspace(authContext, store)\n\n return { authContext, ...result }\n}\n\n// ── Registration ───────────────────────────────────────────────────────────\n\n/**\n * Interactive registration flow. Prompts for email, verification code,\n * password, and name. Optionally logs in afterward.\n *\n * Must be called before the TUI starts (or after stopping it).\n */\nexport async function interactiveRegister(store: ConfigStore): Promise<LoginResult> {\n const config = store.requireConfig()\n\n const email = await promptInput('Email')\n\n const arbi = createArbiClient({\n baseUrl: config.baseUrl,\n deploymentDomain: config.deploymentDomain,\n credentials: 'omit',\n })\n await arbi.crypto.initSodium()\n\n // Verification\n const codeMethod = await promptSelect('Verification method', [\n { name: 'I have an invitation code', value: 'code' as const },\n { name: 'Send me a verification email', value: 'email' as const },\n ])\n\n let verificationCode: string\n if (codeMethod === 'code') {\n verificationCode = await promptInput('Invitation code')\n } else {\n console.info('Sending verification email...')\n const verifyResponse = await arbi.fetch.POST('/api/user/verify-email', {\n body: { email },\n })\n if (verifyResponse.error) {\n throw new Error(`Failed to send verification email: ${JSON.stringify(verifyResponse.error)}`)\n }\n console.info('Verification email sent. Check your inbox.')\n verificationCode = await promptInput('Verification code')\n }\n\n // Password\n const pw = await promptPassword('Password')\n const confirmPw = await promptPassword('Confirm password')\n if (pw !== confirmPw) {\n throw new Error('Passwords do not match.')\n }\n\n // Name\n const firstName = (await promptInput('First name (optional)', false)) || 'User'\n const lastName = (await promptInput('Last name (optional)', false)) || ''\n\n // Register\n await arbi.auth.register({\n email,\n password: pw,\n verificationCode,\n firstName,\n lastName,\n })\n\n console.info(`\\nRegistered successfully as ${email}`)\n\n // Auto-login with the credentials just provided\n console.info('Logging in...')\n const authContext = await performPasswordLogin(config, email, pw, store)\n\n console.info(`Logged in as ${email}`)\n const result = await selectOrCreateWorkspace(authContext, store)\n\n return { authContext, ...result }\n}\n\n// ── Workspace selection / creation ──────────────────────────────────────────\n\n/**\n * After login, select an existing workspace or prompt to create one.\n * Used by both login and register flows.\n */\nasync function selectOrCreateWorkspace(\n authContext: AuthContext,\n store: ConfigStore\n): Promise<{ selectedWorkspaceId?: string; selectedWorkspaceName?: string }> {\n const wsList = await workspaces.listWorkspaces(authContext.arbi)\n\n if (wsList.length === 1) {\n store.updateConfig({ selectedWorkspaceId: wsList[0].external_id })\n console.info(`Workspace: ${wsList[0].name}`)\n return { selectedWorkspaceId: wsList[0].external_id, selectedWorkspaceName: wsList[0].name }\n }\n\n if (wsList.length > 1) {\n const choices = formatWorkspaceChoices(wsList)\n\n const selectedWorkspaceId = await promptSelect('Select workspace', choices)\n const ws = wsList.find((w) => w.external_id === selectedWorkspaceId)\n store.updateConfig({ selectedWorkspaceId })\n console.info(`Workspace: ${ws?.name}`)\n return { selectedWorkspaceId, selectedWorkspaceName: ws?.name }\n }\n\n // No workspaces — offer to create one\n console.info('No workspaces found.')\n const shouldCreate = await promptConfirm('Create a new workspace?')\n\n if (shouldCreate) {\n const name = await promptInput('Workspace name')\n\n const ws = await workspaces.createWorkspace(authContext.arbi, name.trim())\n store.updateConfig({ selectedWorkspaceId: ws.external_id })\n console.info(`Created workspace: ${ws.name}`)\n return { selectedWorkspaceId: ws.external_id, selectedWorkspaceName: ws.name }\n }\n\n return {}\n}\n\n// ── Pre-flight auth check ──────────────────────────────────────────────────\n\n/**\n * Check if the user is authenticated. If not, offer to login or register.\n * Returns the auth context if successful, or exits the process.\n *\n * Called at startup before the TUI launches.\n */\nexport async function ensureAuthenticated(store: ConfigStore): Promise<LoginResult> {\n // Try existing credentials first\n try {\n const authContext = await resolveAuth(store)\n const config = store.requireConfig()\n return {\n authContext,\n selectedWorkspaceId: config.selectedWorkspaceId,\n }\n } catch {\n // Not authenticated — offer login/register with retry on errors\n console.info('Not authenticated.\\n')\n }\n\n // Retry loop — keeps prompting until successful login/register or user exits\n while (true) {\n const action = await promptSelect('What would you like to do?', [\n { name: 'Log in', value: 'login' as const },\n { name: 'Register a new account', value: 'register' as const },\n { name: 'Exit', value: 'exit' as const },\n ])\n\n if (action === 'exit') {\n process.exit(0)\n }\n\n try {\n if (action === 'register') {\n return await interactiveRegister(store)\n }\n return await interactiveLogin(store)\n } catch (err) {\n console.error(`\\n${getErrorMessage(err)}\\n`)\n }\n }\n}\n","/**\n * Shared TUI helpers — eliminates repeated boilerplate across command handlers.\n *\n * - requireAuth(): guard that checks authentication\n * - showMessage(): addSystem + requestRender in one call\n * - switchWorkspace(): workspace selection + state update\n * - runInteractiveFlow(): pause TUI → run action → restart TUI\n */\n\nimport { getErrorMessage, selectWorkspaceById, resolveWorkspace } from '@arbidocs/core'\nimport type { ArbiTui } from './tui.js'\nimport type { SystemMessageLevel } from './components/system-message.js'\n\n/**\n * Guard: check that the user is authenticated.\n * Returns true if auth context is present, otherwise shows an error and returns false.\n */\nexport function requireAuth(\n tui: ArbiTui,\n message = 'Not authenticated. Use /login first.'\n): boolean {\n if (tui.authContext) return true\n showMessage(tui, message, 'error')\n return false\n}\n\n/**\n * Display a system message and request a render in one call.\n */\nexport function showMessage(tui: ArbiTui, message: string, level?: SystemMessageLevel): void {\n tui.chatLog.addSystem(message, level)\n tui.requestRender()\n}\n\n/**\n * Switch to a workspace by ID — selects it, updates TUI state, persists config.\n * Returns the workspace info on success, or null on failure.\n */\nexport async function switchWorkspace(\n tui: ArbiTui,\n workspaceId: string\n): Promise<{ external_id: string; name: string } | null> {\n if (!tui.authContext) return null\n\n try {\n const ws = await selectWorkspaceById(\n tui.authContext.arbi,\n workspaceId,\n tui.authContext.loginResult.serverSessionKey,\n tui.store.requireCredentials().signingPrivateKeyBase64\n )\n\n tui.state.workspaceId = ws.external_id\n tui.state.workspaceName = ws.name\n tui.state.conversationMessageId = null\n tui.store.clearChatSession()\n tui.store.updateConfig({ selectedWorkspaceId: ws.external_id })\n await tui.refreshWorkspaceContext()\n\n return ws\n } catch (err) {\n showMessage(tui, `Failed to switch workspace: ${getErrorMessage(err)}`, 'error')\n return null\n }\n}\n\n/**\n * Set up workspace context after login/register when a workspace was auto-selected.\n */\nexport async function applyWorkspaceSelection(\n tui: ArbiTui,\n workspaceId?: string,\n workspaceName?: string | null\n): Promise<void> {\n if (!workspaceId) return\n const wsCtx = await resolveWorkspace(tui.store, workspaceId)\n tui.setWorkspaceContext(wsCtx)\n tui.state.workspaceName = workspaceName ?? null\n}\n\n/**\n * Run an interactive flow that requires stdin (login, register).\n * Stops the TUI, runs the action, restarts the TUI, and handles errors.\n * Returns the action result on success, or null on failure.\n */\nexport async function runInteractiveFlow<T>(\n tui: ArbiTui,\n pauseMessage: string,\n action: () => Promise<T>,\n errorPrefix: string\n): Promise<T | null> {\n showMessage(tui, pauseMessage)\n tui.stopTui()\n\n try {\n const result = await action()\n tui.restartTui()\n return result\n } catch (err) {\n tui.restartTui()\n showMessage(tui, `${errorPrefix}: ${getErrorMessage(err)}`, 'error')\n return null\n }\n}\n","/**\n * Command handlers — dispatch logic for slash commands.\n *\n * Each handler receives the TUI context and performs its action,\n * typically displaying results in the chat log.\n */\n\nimport {\n getErrorMessage,\n formatUserName,\n workspaces,\n documents,\n conversations,\n contacts,\n health,\n} from '@arbidocs/core'\nimport type { ArbiTui } from './tui.js'\nimport { formatHelpText } from './commands.js'\nimport { interactiveLogin, interactiveRegister } from './auth.js'\nimport { colors } from './theme/theme.js'\nimport {\n requireAuth,\n showMessage,\n switchWorkspace,\n applyWorkspaceSelection,\n runInteractiveFlow,\n} from './tui-helpers.js'\n\n/** Dispatch a slash command. Returns true if handled. */\nexport async function handleCommand(tui: ArbiTui, input: string): Promise<boolean> {\n const trimmed = input.trim()\n if (!trimmed.startsWith('/')) return false\n\n const parts = trimmed.slice(1).split(/\\s+/)\n const cmd = parts[0]?.toLowerCase()\n const args = parts.slice(1)\n\n switch (cmd) {\n case 'help':\n showMessage(tui, formatHelpText())\n return true\n\n case 'login':\n await handleLogin(tui)\n return true\n\n case 'register':\n await handleRegister(tui)\n return true\n\n case 'create':\n await handleCreateWorkspace(tui, args.join(' '))\n return true\n\n case 'workspace':\n await handleWorkspaceSwitch(tui, args[0])\n return true\n\n case 'workspaces':\n await handleListWorkspaces(tui)\n return true\n\n case 'contacts':\n await handleListContacts(tui)\n return true\n\n case 'invite':\n await handleInviteContact(tui, args[0])\n return true\n\n case 'docs':\n await handleListDocs(tui)\n return true\n\n case 'upload':\n await handleUpload(tui, args.join(' '))\n return true\n\n case 'delete':\n await handleDelete(tui, args[0])\n return true\n\n case 'conversations':\n await handleListConversations(tui)\n return true\n\n case 'new':\n handleNewConversation(tui)\n return true\n\n case 'models':\n await handleModels(tui)\n return true\n\n case 'health':\n await handleHealth(tui)\n return true\n\n case 'status':\n handleStatus(tui)\n return true\n\n case 'logout':\n handleLogout(tui)\n return true\n\n case 'exit':\n case 'quit':\n tui.shutdown()\n return true\n\n default:\n showMessage(tui, `Unknown command: /${cmd}. Type /help for available commands.`, 'warning')\n return true\n }\n}\n\nasync function handleLogin(tui: ArbiTui): Promise<void> {\n const result = await runInteractiveFlow(\n tui,\n 'Pausing TUI for login...',\n () => interactiveLogin(tui.store),\n 'Login failed'\n )\n\n if (result) {\n tui.setAuthContext(result.authContext)\n await applyWorkspaceSelection(tui, result.selectedWorkspaceId, result.selectedWorkspaceName)\n showMessage(tui, 'Logged in successfully.')\n }\n}\n\nasync function handleRegister(tui: ArbiTui): Promise<void> {\n const result = await runInteractiveFlow(\n tui,\n 'Pausing TUI for registration...',\n () => interactiveRegister(tui.store),\n 'Registration failed'\n )\n\n if (result) {\n tui.setAuthContext(result.authContext)\n await applyWorkspaceSelection(tui, result.selectedWorkspaceId, result.selectedWorkspaceName)\n showMessage(tui, 'Registered and logged in.')\n }\n}\n\nasync function handleCreateWorkspace(tui: ArbiTui, name: string): Promise<void> {\n if (!requireAuth(tui)) return\n\n if (!name.trim()) {\n showMessage(tui, 'Usage: /create <workspace name>', 'warning')\n return\n }\n\n try {\n showMessage(tui, `Creating workspace \"${name}\"...`)\n const ws = await workspaces.createWorkspace(tui.authContext!.arbi, name.trim())\n const selected = await switchWorkspace(tui, ws.external_id)\n\n if (selected) {\n showMessage(tui, `Created and switched to workspace: ${colors.accentBold(selected.name)}`)\n }\n } catch (err) {\n showMessage(tui, `Failed to create workspace: ${getErrorMessage(err)}`, 'error')\n }\n}\n\nasync function handleWorkspaceSwitch(tui: ArbiTui, workspaceId?: string): Promise<void> {\n if (!requireAuth(tui, 'Not authenticated. Please restart and log in.')) return\n\n if (!workspaceId) {\n await handleListWorkspaces(tui)\n showMessage(tui, 'Use /workspace <id> to switch.')\n return\n }\n\n showMessage(tui, `Switching to workspace ${workspaceId}...`)\n const ws = await switchWorkspace(tui, workspaceId)\n if (ws) {\n showMessage(tui, `Switched to workspace: ${colors.accentBold(ws.name)}`)\n }\n}\n\nasync function handleListWorkspaces(tui: ArbiTui): Promise<void> {\n if (!requireAuth(tui, 'Not authenticated.')) return\n\n try {\n const wsList = await workspaces.listWorkspaces(tui.authContext!.arbi)\n const lines = wsList.map((ws) => {\n const current = ws.external_id === tui.state.workspaceId ? colors.accent(' (current)') : ''\n return ` ${ws.external_id} ${ws.name}${current}`\n })\n showMessage(tui, ['Workspaces:', '', ...lines].join('\\n'))\n } catch (err) {\n showMessage(tui, `Failed to list workspaces: ${getErrorMessage(err)}`, 'error')\n }\n}\n\nasync function handleListDocs(tui: ArbiTui): Promise<void> {\n if (!tui.authContext || !tui.state.workspaceId) {\n showMessage(tui, 'No workspace selected. Use /workspace <id> first.', 'warning')\n return\n }\n\n try {\n const docs = await documents.listDocuments(tui.authContext.arbi, tui.state.workspaceId)\n if (docs.length === 0) {\n showMessage(tui, 'No documents in this workspace.')\n } else {\n const lines = docs.map((d) => ` ${d.external_id} ${d.file_name ?? '(unnamed)'}`)\n showMessage(tui, [`Documents (${docs.length}):`, '', ...lines].join('\\n'))\n }\n } catch (err) {\n showMessage(tui, `Failed to list documents: ${getErrorMessage(err)}`, 'error')\n }\n}\n\nasync function handleListContacts(tui: ArbiTui): Promise<void> {\n if (!requireAuth(tui)) return\n\n try {\n const contactList = await contacts.listContacts(tui.authContext!.arbi)\n const { registered, pending } = contacts.groupContactsByStatus(contactList)\n\n if (registered.length === 0 && pending.length === 0) {\n showMessage(tui, 'No contacts. Use the web app to add contacts.')\n } else {\n const lines: string[] = []\n\n if (registered.length > 0) {\n lines.push(`Contacts (${registered.length}):`, '')\n for (const c of registered) {\n const name = formatUserName(c.user)\n const nameStr = name ? colors.muted(` (${name})`) : ''\n lines.push(` ${c.email}${nameStr}`)\n }\n }\n\n if (pending.length > 0) {\n if (lines.length > 0) lines.push('')\n lines.push(`Pending invitations (${pending.length}):`)\n for (const c of pending) {\n lines.push(` ${c.email} — ${colors.muted(c.status)}`)\n }\n }\n\n lines.push('', colors.muted('Type @name to start a DM with a registered contact.'))\n showMessage(tui, lines.join('\\n'))\n }\n } catch (err) {\n showMessage(tui, `Failed to list contacts: ${getErrorMessage(err)}`, 'error')\n }\n}\n\nasync function handleInviteContact(tui: ArbiTui, email?: string): Promise<void> {\n if (!requireAuth(tui)) return\n\n if (!email?.trim()) {\n showMessage(tui, 'Usage: /invite user@example.com', 'warning')\n return\n }\n\n try {\n showMessage(tui, `Inviting ${email}...`)\n\n const result = await contacts.addContacts(tui.authContext!.arbi, [email.trim()])\n const contact = result[0]\n\n if (contact?.status === 'registered') {\n showMessage(\n tui,\n `${colors.success('Added')} ${email} — already registered. You can DM them with @${email.split('@')[0]}`\n )\n } else {\n showMessage(\n tui,\n `${colors.success('Invited')} ${email} — invitation sent. They'll appear in /contacts once they register.`\n )\n }\n } catch (err) {\n showMessage(tui, `Failed to invite contact: ${getErrorMessage(err)}`, 'error')\n }\n}\n\nasync function handleListConversations(tui: ArbiTui): Promise<void> {\n if (!tui.authContext || !tui.state.workspaceId) {\n showMessage(tui, 'No workspace selected. Use /workspace <id> first.', 'warning')\n return\n }\n\n try {\n const convs = await conversations.listConversations(tui.authContext.arbi, tui.state.workspaceId)\n if (convs.length === 0) {\n showMessage(tui, 'No conversations in this workspace.')\n } else {\n const lines = convs.map((c) => ` ${c.external_id} ${c.title ?? '(untitled)'}`)\n showMessage(tui, [`Conversations (${convs.length}):`, '', ...lines].join('\\n'))\n }\n } catch (err) {\n showMessage(tui, `Failed to list conversations: ${getErrorMessage(err)}`, 'error')\n }\n}\n\nfunction handleNewConversation(tui: ArbiTui): void {\n tui.state.conversationMessageId = null\n tui.store.clearChatSession()\n showMessage(tui, 'Started new conversation.')\n}\n\nfunction handleStatus(tui: ArbiTui): void {\n const { state } = tui\n const lines = [\n `Authenticated: ${state.isAuthenticated ? colors.success('yes') : colors.error('no')}`,\n `Workspace: ${state.workspaceName ? colors.accent(state.workspaceName) : colors.muted('none')}`,\n `Workspace ID: ${state.workspaceId ?? colors.muted('none')}`,\n `Conversation: ${state.conversationMessageId ? colors.muted(state.conversationMessageId) : colors.muted('new')}`,\n `Status: ${state.activityStatus}`,\n `WebSocket: ${tui.wsConnected ? colors.success('connected') : colors.muted('disconnected')}`,\n ]\n showMessage(tui, lines.join('\\n'))\n}\n\nasync function handleUpload(tui: ArbiTui, filePath: string): Promise<void> {\n const wsCtx = tui.wsContext\n if (!wsCtx) {\n showMessage(tui, 'No workspace selected. Use /workspace <id> first.', 'warning')\n return\n }\n\n if (!filePath.trim()) {\n showMessage(tui, 'Usage: /upload <file-path>', 'warning')\n return\n }\n\n try {\n showMessage(tui, `Uploading ${filePath.trim()}...`)\n\n const result = await documents.uploadLocalFile(\n {\n baseUrl: wsCtx.config.baseUrl,\n accessToken: wsCtx.accessToken,\n workspaceKeyHeader: wsCtx.workspaceKeyHeader,\n },\n wsCtx.workspaceId,\n filePath.trim()\n )\n\n const ids = result.doc_ext_ids.join(', ')\n showMessage(tui, `${colors.success('Uploaded')} ${result.fileName} — doc ID(s): ${ids}`)\n\n if (result.duplicates && result.duplicates.length > 0) {\n showMessage(tui, `Duplicates detected: ${result.duplicates.join(', ')}`, 'warning')\n }\n } catch (err) {\n showMessage(tui, `Failed to upload: ${getErrorMessage(err)}`, 'error')\n }\n}\n\nasync function handleDelete(tui: ArbiTui, docId?: string): Promise<void> {\n if (!requireAuth(tui)) return\n\n if (!docId?.trim()) {\n showMessage(tui, 'Usage: /delete <doc-id> (use /docs to list document IDs)', 'warning')\n return\n }\n\n try {\n showMessage(tui, `Deleting document ${docId}...`)\n await documents.deleteDocuments(tui.authContext!.arbi, [docId.trim()])\n showMessage(tui, `${colors.success('Deleted')} document ${docId}`)\n } catch (err) {\n showMessage(tui, `Failed to delete document: ${getErrorMessage(err)}`, 'error')\n }\n}\n\nfunction handleLogout(tui: ArbiTui): void {\n tui.store.deleteCredentials()\n tui.store.updateConfig({ selectedWorkspaceId: undefined })\n tui.store.clearChatSession()\n\n tui.authContext = null\n tui.state.isAuthenticated = false\n tui.state.workspaceId = null\n tui.state.workspaceName = null\n tui.state.conversationMessageId = null\n\n showMessage(tui, 'Logged out. Use /login to authenticate again.')\n}\n\nasync function handleHealth(tui: ArbiTui): Promise<void> {\n if (!requireAuth(tui)) return\n\n try {\n const data = await health.getHealth(tui.authContext!.arbi)\n const lines: string[] = ['System Health:', '']\n\n // Show overall status\n const status = (data as Record<string, unknown>).status as string | undefined\n if (status) {\n const statusColor = status === 'healthy' ? colors.success(status) : colors.warning(status)\n lines.push(` Status: ${statusColor}`)\n }\n\n // Show services if present\n const services = (data as Record<string, unknown>).services as\n | Record<string, unknown>\n | undefined\n if (services) {\n lines.push('', ' Services:')\n for (const [name, info] of Object.entries(services)) {\n const svc = info as Record<string, unknown>\n const svcStatus = svc.status as string | undefined\n const statusStr = svcStatus\n ? svcStatus === 'healthy'\n ? colors.success(svcStatus)\n : colors.error(svcStatus)\n : colors.muted('unknown')\n lines.push(` ${name}: ${statusStr}`)\n }\n }\n\n showMessage(tui, lines.join('\\n'))\n } catch (err) {\n showMessage(tui, `Failed to fetch health status: ${getErrorMessage(err)}`, 'error')\n }\n}\n\nasync function handleModels(tui: ArbiTui): Promise<void> {\n if (!requireAuth(tui)) return\n\n try {\n const data = await health.getHealthModels(tui.authContext!.arbi)\n const models = Array.isArray(data)\n ? data\n : (((data as Record<string, unknown>).data as unknown[]) ?? [])\n\n if (models.length === 0) {\n showMessage(tui, 'No models available.')\n return\n }\n\n const lines: string[] = [`Models (${models.length}):`, '']\n for (const m of models) {\n const model = m as Record<string, unknown>\n const name = (model.model_name ?? model.name ?? 'unknown') as string\n const provider = (model.provider ?? '') as string\n const apiType = (model.api_type ?? '') as string\n const parts = [colors.accent(name)]\n if (provider) parts.push(`provider: ${provider}`)\n if (apiType) parts.push(`api: ${apiType}`)\n lines.push(` ${parts.join(' ')}`)\n }\n\n showMessage(tui, lines.join('\\n'))\n } catch (err) {\n showMessage(tui, `Failed to fetch models: ${getErrorMessage(err)}`, 'error')\n }\n}\n","/**\n * SSE streaming event handler — wires @arbidocs/core streaming\n * into TUI component updates.\n */\n\nimport {\n getErrorMessage,\n streamSSE,\n type SSEStreamCallbacks,\n type SSEStreamResult,\n} from '@arbidocs/core'\nimport type { ArbiTui } from './tui.js'\n\n/**\n * Stream an assistant response from the API into the TUI.\n *\n * 1. Creates an assistant message in the chat log\n * 2. Streams tokens into it via SSE callbacks\n * 3. Displays agent steps as they arrive\n * 4. Finalizes when complete\n *\n * Returns the full SSE result for caller to extract metadata.\n */\nexport async function streamResponse(tui: ArbiTui, response: Response): Promise<SSEStreamResult> {\n tui.chatLog.startAssistant()\n tui.state.activityStatus = 'streaming'\n tui.requestRender()\n\n let accumulated = ''\n\n const callbacks: SSEStreamCallbacks = {\n onStreamStart: (data) => {\n if (data.assistant_message_ext_id) {\n tui.state.conversationMessageId = data.assistant_message_ext_id as string\n }\n },\n\n onToken: (content) => {\n accumulated += content\n tui.chatLog.updateAssistant(accumulated)\n tui.requestRender()\n },\n\n onAgentStep: (data) => {\n const focus = data.focus || data.status || ''\n if (focus) {\n tui.chatLog.addAgentStep(focus)\n tui.requestRender()\n }\n },\n\n onError: (message) => {\n tui.chatLog.addSystem(`Stream error: ${message}`, 'error')\n tui.requestRender()\n },\n }\n\n try {\n const result = await streamSSE(response, callbacks)\n tui.chatLog.finalizeAssistant()\n tui.state.activityStatus = 'idle'\n tui.requestRender()\n return result\n } catch (err) {\n tui.chatLog.finalizeAssistant()\n tui.state.activityStatus = 'error'\n tui.chatLog.addSystem(`Streaming failed: ${getErrorMessage(err)}`, 'error')\n tui.requestRender()\n throw err\n }\n}\n","/**\n * DM handler — encryption setup, send/receive, channel switching.\n *\n * Manages the DM channel state and E2E encrypted messaging.\n * Uses the same ECDH encryption pattern as the React frontend.\n */\n\nimport { getErrorMessage, dm, contacts } from '@arbidocs/core'\nimport {\n base64ToBytes,\n deriveEncryptionKeypairFromSigning,\n encryptMessage,\n decryptMessage,\n type KeyPair,\n type WsNotificationResponse,\n} from '@arbidocs/sdk'\nimport type { ArbiTui } from './tui.js'\nimport { colors } from './theme/theme.js'\nimport { showMessage } from './tui-helpers.js'\n\n// ── Types ────────────────────────────────────────────────────────────────────\n\nexport interface DmContact {\n external_id: string\n email: string\n encryption_public_key: string\n given_name: string\n family_name: string\n}\n\nexport interface DmChannel {\n user: DmContact\n}\n\n// ── Encryption keypair derivation ────────────────────────────────────────────\n\n/**\n * Derive X25519 encryption keypair from the stored Ed25519 signing key.\n * Called once after login.\n */\nexport function deriveEncryptionKeypair(signingPrivateKeyBase64: string): KeyPair {\n const signingPrivateKey = base64ToBytes(signingPrivateKeyBase64)\n // Ed25519 public key is the last 32 bytes of the 64-byte private key\n const ed25519PublicKey = signingPrivateKey.slice(32, 64)\n return deriveEncryptionKeypairFromSigning({\n publicKey: ed25519PublicKey,\n secretKey: signingPrivateKey,\n })\n}\n\n// ── Recipient resolution ─────────────────────────────────────────────────────\n\n/**\n * Resolve a @query to a contact user.\n * Matches by email prefix or given_name (case-insensitive).\n * Returns the matched contact user, or null if not found/ambiguous.\n */\nexport async function resolveRecipient(tui: ArbiTui, query: string): Promise<DmContact | null> {\n if (!tui.authContext) {\n showMessage(tui, 'Not authenticated. Use /login first.', 'error')\n return null\n }\n\n const queryLower = query.toLowerCase()\n\n try {\n const contactList = await contacts.listContacts(tui.authContext.arbi)\n\n // Filter for registered contacts with encryption keys\n const registered = contactList.filter(\n (c) => c.status === 'registered' && c.user?.encryption_public_key\n )\n\n // Match by email prefix (before @) or given_name\n const matches = registered.filter((c) => {\n const emailPrefix = c.email.split('@')[0]?.toLowerCase()\n const givenName = c.user?.given_name?.toLowerCase()\n return emailPrefix === queryLower || givenName === queryLower\n })\n\n if (matches.length === 0) {\n showMessage(\n tui,\n `No registered contact matching \"${query}\". Use /contacts to see available contacts.`,\n 'warning'\n )\n return null\n }\n\n if (matches.length > 1) {\n const names = matches\n .map((c) => ` ${c.email} (${c.user?.given_name ?? ''} ${c.user?.family_name ?? ''})`)\n .join('\\n')\n showMessage(tui, `Ambiguous match for \"${query}\". Be more specific:\\n${names}`, 'warning')\n return null\n }\n\n const contact = matches[0]\n const user = contact.user!\n return {\n external_id: user.external_id,\n email: contact.email,\n encryption_public_key: user.encryption_public_key,\n given_name: user.given_name,\n family_name: user.family_name,\n }\n } catch (err) {\n showMessage(tui, `Failed to resolve contact: ${getErrorMessage(err)}`, 'error')\n return null\n }\n}\n\n// ── Channel switching ────────────────────────────────────────────────────────\n\n/**\n * Handle @input — switch to DM channel or back to arbi.\n */\nexport async function handleChannelSwitch(tui: ArbiTui, input: string): Promise<void> {\n const query = input.slice(1).trim() // Remove leading @\n\n if (!query) {\n showMessage(tui, 'Usage: @username to switch to DM, @arbi to switch back.', 'warning')\n return\n }\n\n // @arbi — switch back to AI chat\n if (query.toLowerCase() === 'arbi') {\n switchToArbi(tui)\n return\n }\n\n // Resolve recipient\n const user = await resolveRecipient(tui, query)\n if (!user) return\n\n await switchToDmChannel(tui, user)\n}\n\n/**\n * Switch to a DM channel with a specific user.\n * Updates header, clears chat, loads DM history.\n */\nexport async function switchToDmChannel(tui: ArbiTui, user: DmContact): Promise<void> {\n if (!tui.authContext || !tui.encryptionKeys) {\n showMessage(tui, 'Not authenticated or encryption not initialized.', 'error')\n return\n }\n\n // Set channel state\n tui.currentDmChannel = { user }\n tui.updateHeader()\n\n // Clear chat log for DM view\n tui.chatLog.clearMessages()\n\n showMessage(tui, `Switched to DM with ${colors.accent(user.email)}. Type @arbi to switch back.`)\n\n // Fetch and display DM history\n await loadDmHistory(tui, user)\n}\n\n/**\n * Switch back to AI chat mode.\n */\nexport function switchToArbi(tui: ArbiTui): void {\n if (!tui.currentDmChannel) {\n showMessage(tui, 'Already in AI chat mode.', 'info')\n return\n }\n\n tui.currentDmChannel = null\n tui.updateHeader()\n\n // Clear chat log for fresh AI view\n tui.chatLog.clearMessages()\n showMessage(tui, 'Switched back to AI chat.')\n}\n\n// ── DM history ───────────────────────────────────────────────────────────────\n\n/**\n * Fetch all DMs and display the conversation with a specific user.\n */\nasync function loadDmHistory(tui: ArbiTui, user: DmContact): Promise<void> {\n if (!tui.authContext || !tui.encryptionKeys) return\n\n const myExtId = tui.authContext.loginResult.userExtId\n\n try {\n const allDms = await dm.listDMs(tui.authContext.arbi)\n\n // Filter for DMs between us and this user (type === 'user_message')\n const conversation = allDms.filter(\n (msg) =>\n msg.type === 'user_message' &&\n ((msg.sender.external_id === user.external_id && msg.recipient.external_id === myExtId) ||\n (msg.sender.external_id === myExtId && msg.recipient.external_id === user.external_id))\n )\n\n // Sort by created_at ascending\n conversation.sort((a, b) => new Date(a.created_at).getTime() - new Date(b.created_at).getTime())\n\n // Mark unread messages as read\n const unreadIds = conversation\n .filter((msg) => !msg.read && msg.sender.external_id === user.external_id)\n .map((msg) => msg.external_id)\n\n if (unreadIds.length > 0) {\n dm.markRead(tui.authContext.arbi, unreadIds).catch(() => {\n // Non-fatal — just log\n })\n }\n\n // Decrypt and display messages\n for (const msg of conversation) {\n const isSent = msg.sender.external_id === myExtId\n const plaintext = await decryptNotification(msg, myExtId!, tui.encryptionKeys, user)\n if (plaintext) {\n displayDmMessage(tui, plaintext, isSent, user.email)\n }\n }\n\n tui.requestRender()\n } catch (err) {\n showMessage(tui, `Failed to load DM history: ${getErrorMessage(err)}`, 'error')\n }\n}\n\n// ── Send encrypted DM ────────────────────────────────────────────────────────\n\n/**\n * Encrypt and send a DM to the current channel's recipient.\n */\nexport async function sendEncryptedDm(tui: ArbiTui, plaintext: string): Promise<void> {\n if (!tui.authContext || !tui.encryptionKeys || !tui.currentDmChannel) {\n showMessage(tui, 'Cannot send DM — not in a DM channel.', 'error')\n return\n }\n\n const recipient = tui.currentDmChannel.user\n\n try {\n // Encrypt the message\n const encrypted = await encryptMessage(\n plaintext,\n recipient.encryption_public_key,\n tui.encryptionKeys.secretKey\n )\n\n // Send via API\n await dm.sendDM(tui.authContext.arbi, [\n { recipient_ext_id: recipient.external_id, content: encrypted },\n ])\n\n // Display sent message in chat log\n displayDmMessage(tui, plaintext, true, recipient.email)\n tui.requestRender()\n } catch (err) {\n showMessage(tui, `Failed to send DM: ${getErrorMessage(err)}`, 'error')\n }\n}\n\n// ── Incoming DM handling (from WebSocket) ────────────────────────────────────\n\n/**\n * Handle an incoming WebSocket DM notification.\n * If we're in a DM channel with the sender, show it inline and return true.\n * Otherwise return false (caller shows toast).\n */\nexport async function handleIncomingDm(\n tui: ArbiTui,\n msg: WsNotificationResponse\n): Promise<boolean> {\n if (!tui.currentDmChannel || !tui.encryptionKeys || !tui.authContext) {\n return false\n }\n\n const myExtId = tui.authContext.loginResult.userExtId\n const channelUserId = tui.currentDmChannel.user.external_id\n\n // Check if this message is from the user we're chatting with\n if (msg.sender.external_id !== channelUserId) {\n return false\n }\n\n // Decrypt and display inline\n const plaintext = await decryptNotification(\n msg,\n myExtId!,\n tui.encryptionKeys,\n tui.currentDmChannel.user\n )\n\n if (plaintext) {\n displayDmMessage(tui, plaintext, false, msg.sender.email)\n tui.requestRender()\n\n // Mark as read\n dm.markRead(tui.authContext.arbi, [msg.external_id]).catch(() => {\n // Non-fatal\n })\n }\n\n return true\n}\n\n// ── Decryption helper ────────────────────────────────────────────────────────\n\n/**\n * Decrypt a notification's content field.\n *\n * For received messages: decrypt with sender's public key + our private key.\n * For sent messages: decrypt with recipient's public key + our private key.\n */\nasync function decryptNotification(\n notification: WsNotificationResponse,\n _myExtId: string,\n encryptionKeyPair: KeyPair,\n otherUser: DmContact\n): Promise<string | null> {\n if (!notification.content) return null\n\n try {\n // ECDH decryption uses the other party's public key in both cases\n return await decryptMessage(\n notification.content,\n otherUser.encryption_public_key,\n encryptionKeyPair.secretKey\n )\n } catch {\n return '[decryption failed]'\n }\n}\n\n// ── Display helper ───────────────────────────────────────────────────────────\n\n/**\n * Display a DM message in the chat log.\n * Sent messages show \"You:\", received show the sender's email.\n */\nfunction displayDmMessage(tui: ArbiTui, text: string, isSent: boolean, senderEmail: string): void {\n if (isSent) {\n tui.chatLog.addUser(text)\n } else {\n tui.chatLog.addDm(senderEmail, text)\n }\n}\n","/**\n * WebSocket handler — connects to backend WS and routes messages to toasts.\n *\n * Uses connectWithReconnect() from @arbidocs/core for connection/auth\n * with automatic reconnection, and formatWsMessage() from core for\n * shared message formatting.\n */\n\nimport {\n connectWithReconnect,\n formatWsMessage,\n type ReconnectableWsConnection,\n} from '@arbidocs/core'\nimport { type WebSocketServerMessage, type WsNotificationResponse } from '@arbidocs/sdk'\nimport type { ArbiTui } from './tui.js'\nimport type { ToastContainer, ToastLevel } from './components/toast-container.js'\nimport { handleIncomingDm } from './dm-handler.js'\n\n// ── Duration constants ────────────────────────────────────────────────────────\n\nconst DURATION_SHORT = 3000 // frequent in-progress updates\nconst DURATION_DEFAULT = 5000 // completed tasks, batch, notifications\nconst DURATION_LONG = 8000 // errors — longer so user notices\n\n// ── Duration mapping by level ────────────────────────────────────────────────\n\nconst DURATION_BY_LEVEL: Record<string, number> = {\n info: DURATION_SHORT,\n success: DURATION_DEFAULT,\n error: DURATION_LONG,\n warning: DURATION_DEFAULT,\n}\n\n// ── Helpers ──────────────────────────────────────────────────────────────────\n\n/** NotificationResponse uses NotificationType as its `type` field, not a single literal. */\nfunction isNotification(msg: WebSocketServerMessage): msg is WsNotificationResponse {\n return 'sender' in msg && 'recipient' in msg\n}\n\n// ── Message routing ───────────────────────────────────────────────────────────\n\nasync function handleMessage(\n msg: WebSocketServerMessage,\n toasts: ToastContainer,\n tui: ArbiTui | null\n): Promise<void> {\n // DM routing — TUI-specific: route user_message to the DM chat log\n if (isNotification(msg) && msg.type === 'user_message' && tui) {\n const handled = await handleIncomingDm(tui, msg)\n if (handled) return\n }\n\n // Use shared formatter for text + level\n const { text, level } = formatWsMessage(msg)\n const duration = DURATION_BY_LEVEL[level] ?? DURATION_DEFAULT\n toasts.show(text, level as ToastLevel, duration)\n}\n\n// ── Public API ────────────────────────────────────────────────────────────────\n\nexport interface TuiWsOptions {\n baseUrl: string\n accessToken: string\n toasts: ToastContainer\n tui?: ArbiTui\n}\n\n/**\n * Connect WebSocket with auto-reconnection and route messages to toast notifications.\n * Returns the connection handle for cleanup, or null on failure.\n */\nexport async function connectTuiWebSocket(\n options: TuiWsOptions\n): Promise<ReconnectableWsConnection | null> {\n const { baseUrl, accessToken, toasts, tui } = options\n\n try {\n const connection = await connectWithReconnect({\n baseUrl,\n accessToken,\n onMessage: (msg) => handleMessage(msg, toasts, tui ?? null),\n onClose: (_code, _reason) => {\n toasts.show('WebSocket disconnected', 'warning', DURATION_DEFAULT)\n },\n onReconnecting: (attempt, maxRetries) => {\n toasts.show(`Reconnecting... (${attempt}/${maxRetries})`, 'warning', DURATION_DEFAULT)\n },\n onReconnected: () => {\n toasts.show('WebSocket reconnected', 'success', DURATION_DEFAULT)\n },\n onReconnectFailed: () => {\n toasts.show('WebSocket reconnection failed', 'error', DURATION_LONG)\n },\n })\n return connection\n } catch {\n // Auth failure or connection error — not fatal, just skip WS\n toasts.show('WebSocket connection failed', 'warning', DURATION_DEFAULT)\n return null\n }\n}\n","/**\n * ArbiTui — main orchestrator for the ARBI terminal UI.\n *\n * Manages state, component wiring, and lifecycle. Coordinates between\n * the editor input, chat log display, command dispatch, and SSE streaming.\n */\n\nimport {\n TUI,\n ProcessTerminal,\n Text,\n Spacer,\n CombinedAutocompleteProvider,\n} from '@mariozechner/pi-tui'\nimport {\n type AuthContext,\n type WorkspaceContext,\n type ReconnectableWsConnection,\n type ConfigStore,\n getErrorMessage,\n assistant,\n documents,\n} from '@arbidocs/core'\nimport type { KeyPair } from '@arbidocs/sdk'\nimport { ChatLog } from './components/chat-log.js'\nimport { ArbiEditor } from './components/arbi-editor.js'\nimport { ToastContainer } from './components/toast-container.js'\nimport { handleCommand } from './command-handlers.js'\nimport { streamResponse } from './event-handlers.js'\nimport { connectTuiWebSocket } from './ws-handler.js'\nimport {\n type DmChannel,\n deriveEncryptionKeypair,\n handleChannelSwitch,\n sendEncryptedDm,\n} from './dm-handler.js'\nimport { commands } from './commands.js'\nimport { colors, formatHeader } from './theme/theme.js'\n\n// ── State ──────────────────────────────────────────────────────────────────\n\nexport interface TuiState {\n workspaceId: string | null\n workspaceName: string | null\n conversationMessageId: string | null\n activityStatus: 'idle' | 'sending' | 'streaming' | 'error'\n isAuthenticated: boolean\n}\n\n// ── Main TUI class ─────────────────────────────────────────────────────────\n\nexport class ArbiTui {\n private tui: TUI\n private header: Text\n\n /** The chat message log — public so command handlers can add messages. */\n readonly chatLog: ChatLog\n\n /** Toast notifications from WebSocket events. */\n readonly toastContainer: ToastContainer\n\n /** The input editor. */\n private editor: ArbiEditor\n\n /** Application state — public so handlers can read/write it. */\n state: TuiState\n\n /** Auth context from @arbidocs/core — set during init. */\n authContext: AuthContext | null = null\n\n /** Workspace context with tokens/headers — set when workspace is selected. */\n private workspaceContext: WorkspaceContext | null = null\n\n /** Config store for persistence. */\n readonly store: ConfigStore\n\n /** Active WebSocket connection (null when not connected). */\n private wsConnection: ReconnectableWsConnection | null = null\n\n /** X25519 encryption keypair derived from signing key (null until login). */\n private encryptionKeyPair: KeyPair | null = null\n\n /** Current DM channel (null = AI chat mode). */\n private dmChannel: DmChannel | null = null\n\n constructor(store: ConfigStore) {\n this.store = store\n\n this.state = {\n workspaceId: null,\n workspaceName: null,\n conversationMessageId: null,\n activityStatus: 'idle',\n isAuthenticated: false,\n }\n\n // Build TUI component tree\n this.tui = new TUI(new ProcessTerminal())\n\n // Header\n this.header = new Text(formatHeader(null, 'starting...'), 1, 0)\n\n // Chat log\n this.chatLog = new ChatLog()\n\n // Toast container for WebSocket notifications\n this.toastContainer = new ToastContainer()\n this.toastContainer.setRenderCallback(() => this.tui.requestRender())\n\n // Editor\n this.editor = this.createEditor()\n\n // Compose layout\n this.tui.addChild(this.header)\n this.tui.addChild(new Spacer(1))\n this.tui.addChild(this.toastContainer)\n this.tui.addChild(this.chatLog)\n this.tui.addChild(this.editor)\n\n this.tui.setFocus(this.editor)\n }\n\n // ── Lifecycle ──────────────────────────────────────────────────────────\n\n /** Start the TUI event loop. */\n start(): void {\n this.tui.start()\n this.updateHeader()\n this.tui.requestRender()\n }\n\n /** Gracefully shut down the TUI and exit. */\n shutdown(): void {\n this.wsConnection?.close()\n this.wsConnection = null\n this.toastContainer.clear()\n this.tui.stop()\n process.exit(0)\n }\n\n /**\n * Temporarily stop the TUI (releases terminal raw mode).\n * Used before interactive prompts that need stdin (login, register).\n */\n stopTui(): void {\n this.tui.stop()\n }\n\n /**\n * Restart the TUI after a stopTui() call.\n * Rebuilds the component tree with a fresh TUI instance since\n * pi-tui doesn't support stop/start cycling on the same instance.\n */\n restartTui(): void {\n this.tui = new TUI(new ProcessTerminal())\n\n // Re-compose layout\n this.tui.addChild(this.header)\n this.tui.addChild(new Spacer(1))\n this.tui.addChild(this.toastContainer)\n this.tui.addChild(this.chatLog)\n\n // Create new editor (needs fresh TUI reference)\n this.editor = this.createEditor()\n this.tui.addChild(this.editor)\n this.tui.setFocus(this.editor)\n\n this.tui.start()\n this.updateHeader()\n this.tui.requestRender()\n }\n\n /** Create and wire a new editor instance. */\n private createEditor(): ArbiEditor {\n const editor = new ArbiEditor(this.tui)\n editor.setAutocompleteProvider(new CombinedAutocompleteProvider(commands))\n editor.onSubmit = (text: string) => this.handleSubmit(text)\n editor.onEscape = () => this.handleAbort()\n editor.onCtrlC = () => this.shutdown()\n editor.onCtrlD = () => this.shutdown()\n editor.onCtrlW = () => this.handleSubmit('/workspaces')\n editor.onCtrlN = () => this.handleSubmit('/new')\n return editor\n }\n\n /** Request a render update. */\n requestRender(): void {\n this.tui.requestRender()\n }\n\n // ── Auth / Workspace ───────────────────────────────────────────────────\n\n /** Set authentication context after login. */\n setAuthContext(ctx: AuthContext): void {\n this.authContext = ctx\n this.state.isAuthenticated = true\n this.encryptionKeyPair = deriveEncryptionKeypair(\n this.store.requireCredentials().signingPrivateKeyBase64\n )\n this.updateHeader()\n }\n\n /** Set workspace context after workspace selection. */\n setWorkspaceContext(ctx: WorkspaceContext): void {\n this.workspaceContext = ctx\n this.state.workspaceId = ctx.workspaceId\n // Workspace name will be set separately since WorkspaceContext doesn't include it\n this.updateHeader()\n this.connectWebSocket()\n }\n\n /** Refresh workspace context (after switching workspaces). */\n async refreshWorkspaceContext(): Promise<void> {\n if (!this.state.workspaceId || !this.authContext) return\n\n const { resolveWorkspace } = await import('@arbidocs/core')\n const ctx = await resolveWorkspace(this.store, this.state.workspaceId)\n this.workspaceContext = ctx\n this.updateHeader()\n }\n\n /** Public accessor for workspace context (used by command handlers). */\n get wsContext(): WorkspaceContext | null {\n return this.workspaceContext\n }\n\n /** Whether the WebSocket is currently connected. */\n get wsConnected(): boolean {\n return this.wsConnection !== null\n }\n\n /** Connect (or reconnect) WebSocket for real-time notifications. */\n private connectWebSocket(): void {\n if (!this.workspaceContext) return\n\n // Close existing connection before reconnecting\n this.wsConnection?.close()\n this.wsConnection = null\n\n const { config, accessToken } = this.workspaceContext\n\n connectTuiWebSocket({\n baseUrl: config.baseUrl,\n accessToken,\n toasts: this.toastContainer,\n tui: this,\n }).then((conn) => {\n this.wsConnection = conn\n })\n }\n\n // ── Input handling ─────────────────────────────────────────────────────\n\n private async handleSubmit(text: string): Promise<void> {\n const trimmed = text.trim()\n if (!trimmed) return\n\n // Check for @channel switching\n if (trimmed.startsWith('@')) {\n await handleChannelSwitch(this, trimmed)\n return\n }\n\n // Check for slash commands\n if (trimmed.startsWith('/')) {\n const handled = await handleCommand(this, trimmed)\n if (handled) return\n }\n\n // Route to DM or AI based on channel\n if (this.dmChannel) {\n await sendEncryptedDm(this, trimmed)\n } else {\n await this.sendMessage(trimmed)\n }\n }\n\n private handleAbort(): void {\n if (this.state.activityStatus === 'streaming') {\n // TODO: implement AbortController for stream cancellation\n this.chatLog.addSystem('Abort requested (stream will complete current chunk).', 'warning')\n this.requestRender()\n }\n }\n\n // ── Messaging ──────────────────────────────────────────────────────────\n\n private async sendMessage(question: string): Promise<void> {\n if (!this.workspaceContext) {\n this.chatLog.addSystem(\n 'No workspace selected. Use /workspace <id> or /workspaces to choose one.',\n 'warning'\n )\n this.requestRender()\n return\n }\n\n // Display user message\n this.chatLog.addUser(question)\n this.state.activityStatus = 'sending'\n this.updateHeader()\n this.requestRender()\n\n try {\n // Get all docs in workspace for retrieval context\n const docs = await documents.listDocuments(\n this.workspaceContext.arbi,\n this.workspaceContext.workspaceId\n )\n const docIds = docs.map((d) => d.external_id as string)\n\n // Load chat session for conversation threading\n const session = this.store.getChatSession()\n const parentMessageExtId = this.state.conversationMessageId ?? session.lastMessageExtId\n\n // Query the assistant\n const response = await assistant.queryAssistant({\n baseUrl: this.workspaceContext.config.baseUrl,\n accessToken: this.workspaceContext.accessToken,\n workspaceKeyHeader: this.workspaceContext.workspaceKeyHeader,\n workspaceId: this.workspaceContext.workspaceId,\n question,\n docIds,\n parentMessageExtId,\n })\n\n // Stream the response into the chat log\n const result = await streamResponse(this, response)\n\n // Save conversation state for threading and history restoration\n if (result.assistantMessageExtId) {\n this.state.conversationMessageId = result.assistantMessageExtId\n const sessionUpdate: Record<string, string> = {\n lastMessageExtId: result.assistantMessageExtId,\n }\n // Extract conversation ID from user_message or metadata\n const conversationExtId =\n (result.userMessage?.conversation_ext_id as string) ??\n (result.metadata?.conversation_ext_id as string)\n if (conversationExtId) {\n sessionUpdate.conversationExtId = conversationExtId\n }\n this.store.updateChatSession(sessionUpdate)\n }\n } catch (err) {\n this.state.activityStatus = 'error'\n this.chatLog.addSystem(`Error: ${getErrorMessage(err)}`, 'error')\n }\n\n this.state.activityStatus = 'idle'\n this.updateHeader()\n this.requestRender()\n }\n\n // ── UI Updates ─────────────────────────────────────────────────────────\n\n /** Update the header bar — public so dm-handler can call it. */\n updateHeader(): void {\n const statusText =\n this.state.activityStatus === 'idle'\n ? colors.success('ready')\n : this.state.activityStatus === 'streaming'\n ? colors.warning('streaming...')\n : this.state.activityStatus === 'sending'\n ? colors.warning('sending...')\n : colors.error('error')\n\n if (this.dmChannel) {\n this.header.setText(formatHeader(`DM: ${this.dmChannel.user.email}`, statusText))\n } else {\n this.header.setText(formatHeader(this.state.workspaceName, statusText))\n }\n }\n\n // ── DM channel accessors (used by dm-handler) ────────────────────────────\n\n /** Current DM channel (null = AI chat mode). */\n get currentDmChannel(): DmChannel | null {\n return this.dmChannel\n }\n\n set currentDmChannel(ch: DmChannel | null) {\n this.dmChannel = ch\n }\n\n /** Encryption keypair for E2E DM encryption. */\n get encryptionKeys(): KeyPair | null {\n return this.encryptionKeyPair\n }\n}\n","/**\n * ARBI TUI — entry point\n *\n * Handles CLI argument parsing, authentication, and TUI launch.\n * Uses @arbidocs/core for auth and config, pi-tui for rendering.\n *\n * If not authenticated, offers interactive login/register before launching.\n *\n * Usage:\n * arbi-tui # Launch with default workspace\n * arbi-tui -w <workspace-id> # Launch with specific workspace\n */\n\n// Suppress SDK middleware logging\nconsole.debug = () => {}\nconst _origInfo = console.info\nconsole.info = (...args: unknown[]) => {\n if (typeof args[0] === 'string' && args[0].startsWith('[API]')) return\n _origInfo(...args)\n}\n\nimport { Command } from 'commander'\nimport {\n FileConfigStore,\n getErrorMessage,\n resolveWorkspace,\n workspaces,\n conversations,\n} from '@arbidocs/core'\nimport { ArbiTui } from './tui.js'\nimport { ensureAuthenticated } from './auth.js'\n\nconst program = new Command()\n\nprogram\n .name('arbi-tui')\n .description('Interactive terminal UI for ARBI — chat with the RAG assistant')\n .version('0.1.0')\n .option('-w, --workspace <id>', 'Workspace ID to use')\n .action(async (opts: { workspace?: string }) => {\n const store = new FileConfigStore()\n\n // Ensure config exists\n try {\n store.requireConfig()\n } catch {\n console.error('Not configured. Run `arbi config set-url <url>` first.')\n process.exit(1)\n }\n\n // Authenticate — offers login/register if not already authenticated\n const { authContext, selectedWorkspaceId, selectedWorkspaceName } =\n await ensureAuthenticated(store)\n\n // Resolve workspace\n const workspaceId = opts.workspace || selectedWorkspaceId\n\n // Create and start TUI\n const tui = new ArbiTui(store)\n tui.setAuthContext(authContext)\n\n if (workspaceId) {\n try {\n const wsCtx = await resolveWorkspace(store, workspaceId)\n tui.setWorkspaceContext(wsCtx)\n\n // Get workspace name\n if (selectedWorkspaceName && workspaceId === selectedWorkspaceId) {\n tui.state.workspaceName = selectedWorkspaceName\n } else {\n const wsList = await workspaces.listWorkspaces(authContext.arbi)\n const ws = wsList.find((w) => w.external_id === workspaceId)\n if (ws) {\n tui.state.workspaceName = ws.name\n }\n }\n } catch (err) {\n tui.chatLog.addSystem(`Failed to load workspace: ${getErrorMessage(err)}`, 'warning')\n tui.chatLog.addSystem('Use /workspaces to list and /workspace <id> to select.')\n }\n } else {\n tui.chatLog.addSystem(\n 'No workspace selected. Use /workspaces to list and /workspace <id> to select.'\n )\n }\n\n // Load chat session for conversation continuity\n const session = store.getChatSession()\n if (session.lastMessageExtId) {\n tui.state.conversationMessageId = session.lastMessageExtId\n }\n\n // Restore chat history from previous session\n if (session.conversationExtId && session.lastMessageExtId && tui.authContext) {\n try {\n const threads = await conversations.getConversationThreads(\n tui.authContext.arbi,\n session.conversationExtId\n )\n const threadList = (threads as { threads?: unknown[] }).threads ?? []\n const thread = threadList.find(\n (t) =>\n (t as { leaf_message_ext_id?: string }).leaf_message_ext_id === session.lastMessageExtId\n ) as { history?: { role: string; content: string }[] } | undefined\n\n if (thread?.history && thread.history.length > 0) {\n for (const msg of thread.history) {\n if (msg.role === 'user') {\n tui.chatLog.addUser(msg.content)\n } else if (msg.role === 'assistant') {\n tui.chatLog.addAssistant(msg.content)\n }\n }\n tui.chatLog.addSystem('--- restored from previous session ---')\n }\n } catch {\n // History restoration is best-effort — continue normally\n }\n }\n\n tui.chatLog.addSystem(\n 'Type a question to chat with the ARBI assistant. Use /help for commands.'\n )\n tui.start()\n })\n\nprogram.parse()\n"]}
1
+ {"version":3,"sources":["../src/theme/theme.ts","../src/theme/syntax-theme.ts","../src/components/assistant-message.ts","../src/components/user-message.ts","../src/components/system-message.ts","../src/components/agent-step.ts","../src/components/chat-log.ts","../src/components/arbi-editor.ts","../src/components/toast-container.ts","../src/commands.ts","../src/prompts.ts","../src/auth.ts","../src/tui-helpers.ts","../src/command-handlers.ts","../src/event-handlers.ts","../src/dm-handler.ts","../src/ws-handler.ts","../src/tui.ts","../src/index.ts"],"names":["chalk","Container","Text","Markdown","Spacer","Editor","matchesKey","Key","select","input","password","confirm","performPasswordLogin","createArbiClient","workspaces","formatWorkspaceChoices","resolveAuth","getErrorMessage","selectWorkspaceById","resolveWorkspace","documents","contacts","formatUserName","conversations","health","streamSSE","base64ToBytes","deriveEncryptionKeypairFromSigning","dm","encryptMessage","decryptMessage","formatWsMessage","connectWithReconnect","TUI","ProcessTerminal","CombinedAutocompleteProvider","assistant","Command","FileConfigStore"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * ARBI TUI theme — color palette and component styling functions.\n *\n * Uses chalk for ANSI color output. All theme values are functions\n * that wrap text in the appropriate escape sequences.\n */\n\nimport chalk from 'chalk'\nimport type { MarkdownTheme, EditorTheme, SelectListTheme } from '@mariozechner/pi-tui'\n\n// ── Color palette ──────────────────────────────────────────────────────────\n\nexport const colors = {\n /** Primary accent — teal/cyan used for headings, prompts, highlights */\n accent: chalk.cyan,\n accentBold: chalk.bold.cyan,\n\n /** Secondary accent — blue for links and info */\n secondary: chalk.blue,\n\n /** Muted text — dim gray for borders, metadata */\n muted: chalk.gray,\n mutedDim: chalk.dim.gray,\n\n /** Success — green for completed states */\n success: chalk.green,\n\n /** Warning — yellow for pending states, code */\n warning: chalk.yellow,\n\n /** Error — red for error messages */\n error: chalk.red,\n errorBold: chalk.bold.red,\n\n /** Text — default and bold */\n text: chalk.white,\n textBold: chalk.bold.white,\n\n /** User message styling */\n userLabel: chalk.bold.green,\n userText: chalk.white,\n\n /** Assistant message styling */\n assistantLabel: chalk.bold.cyan,\n\n /** System message styling */\n systemText: chalk.dim,\n systemInfo: chalk.dim.cyan,\n systemError: chalk.dim.red,\n systemWarning: chalk.dim.yellow,\n\n /** Agent step styling */\n stepPending: chalk.dim.yellow,\n stepComplete: chalk.dim.green,\n} as const\n\n// ── Background functions ───────────────────────────────────────────────────\n\nexport const bgFn = {\n /** Subtle background for user messages */\n user: (text: string) => chalk.bgGray(text),\n\n /** Background for agent steps */\n agentStep: (text: string) => text,\n} as const\n\n// ── Component themes ───────────────────────────────────────────────────────\n\nexport const selectListTheme: SelectListTheme = {\n selectedPrefix: (s: string) => colors.accent(s),\n selectedText: (s: string) => colors.text(s),\n description: (s: string) => colors.muted(s),\n scrollInfo: (s: string) => colors.muted(s),\n noMatch: (s: string) => colors.muted(s),\n}\n\nexport const editorTheme: EditorTheme = {\n borderColor: (s: string) => colors.accent(s),\n selectList: selectListTheme,\n}\n\nexport const markdownTheme: MarkdownTheme = {\n heading: (s: string) => colors.accentBold(s),\n link: (s: string) => chalk.underline.blue(s),\n linkUrl: (s: string) => colors.muted(s),\n code: (s: string) => colors.warning(s),\n codeBlock: (s: string) => colors.text(s),\n codeBlockBorder: (s: string) => colors.muted(s),\n quote: (s: string) => chalk.italic.gray(s),\n quoteBorder: (s: string) => colors.muted(s),\n hr: (s: string) => colors.muted(s),\n listBullet: (s: string) => colors.accent(s),\n bold: (s: string) => chalk.bold(s),\n italic: (s: string) => chalk.italic(s),\n strikethrough: (s: string) => chalk.strikethrough(s),\n underline: (s: string) => chalk.underline(s),\n}\n\n// ── Header / Footer helpers ────────────────────────────────────────────────\n\nexport function formatHeader(workspaceName: string | null, status: string): string {\n const app = colors.accentBold('ARBI')\n const ws = workspaceName ? colors.muted(` | ${workspaceName}`) : ''\n const st = colors.muted(` | ${status}`)\n return `${app}${ws}${st}`\n}\n\nexport function formatPrompt(): string {\n return colors.accent('> ')\n}\n","/**\n * Syntax highlighting theme for code blocks in Markdown.\n *\n * Provides a highlightCode function compatible with pi-tui's\n * MarkdownTheme.highlightCode option.\n */\n\nimport chalk from 'chalk'\n\n/**\n * Simple keyword-based syntax highlighting for code blocks.\n * Returns an array of styled lines.\n *\n * For a first version, we apply basic keyword coloring. This can be\n * upgraded to use a proper highlighter (e.g., cli-highlight) later.\n */\n// eslint-disable-next-line @typescript-eslint/no-unused-vars\nexport function highlightCode(code: string, lang?: string): string[] {\n const lines = code.split('\\n')\n\n return lines.map((line) => {\n // Highlight common keywords\n let styled = line\n // String literals (double and single quoted)\n .replace(/([\"'])(?:(?=(\\\\?))\\2.)*?\\1/g, (m) => chalk.green(m))\n // Numbers\n .replace(/\\b(\\d+\\.?\\d*)\\b/g, (m) => chalk.yellow(m))\n // Comments (// and #)\n .replace(/(\\/\\/.*|#.*)$/g, (m) => chalk.gray(m))\n\n // Keywords (applied after strings/comments to avoid conflicts in simple cases)\n const keywords =\n /\\b(const|let|var|function|return|if|else|for|while|import|export|from|class|extends|new|async|await|try|catch|throw|type|interface|enum|def|self|None|True|False|print)\\b/g\n styled = styled.replace(keywords, (m) => chalk.cyan(m))\n\n return styled\n })\n}\n","/**\n * AssistantMessage — streaming markdown response from the RAG assistant.\n *\n * Wraps pi-tui's Markdown component. Call setText() as tokens arrive\n * to update the rendered content incrementally.\n */\n\nimport { Container, Markdown, Text } from '@mariozechner/pi-tui'\nimport { markdownTheme, colors } from '../theme/theme.js'\nimport { highlightCode } from '../theme/syntax-theme.js'\n\nconst assistantMarkdownTheme = {\n ...markdownTheme,\n highlightCode,\n}\n\nexport class AssistantMessage extends Container {\n private markdown: Markdown\n private label: Text\n\n constructor() {\n super()\n this.label = new Text(colors.assistantLabel('Assistant'), 1, 0)\n this.markdown = new Markdown('', 1, 0, assistantMarkdownTheme)\n this.addChild(this.label)\n this.addChild(this.markdown)\n }\n\n /** Update the response text (called as tokens stream in). */\n setText(text: string): void {\n this.markdown.setText(text)\n }\n}\n","/**\n * UserMessage — displays a user's submitted question.\n *\n * Wraps pi-tui's Markdown component with user-specific styling.\n */\n\nimport { Container, Markdown, Text } from '@mariozechner/pi-tui'\nimport { markdownTheme, colors } from '../theme/theme.js'\n\nexport class UserMessage extends Container {\n constructor(text: string) {\n super()\n const label = new Text(colors.userLabel('You'), 1, 0)\n const content = new Markdown(text, 1, 0, markdownTheme)\n this.addChild(label)\n this.addChild(content)\n }\n}\n","/**\n * SystemMessage — info, warning, and error messages.\n *\n * Wraps pi-tui's Text component with dim/accent styling.\n */\n\nimport { Text } from '@mariozechner/pi-tui'\nimport { colors } from '../theme/theme.js'\n\nexport type SystemMessageLevel = 'info' | 'warning' | 'error'\n\nexport class SystemMessage extends Text {\n constructor(message: string, level: SystemMessageLevel = 'info') {\n const styleFn =\n level === 'error'\n ? colors.systemError\n : level === 'warning'\n ? colors.systemWarning\n : colors.systemInfo\n super(styleFn(message), 1, 0)\n }\n}\n","/**\n * AgentStep — displays a single agent processing step.\n *\n * Shows the step focus/description with a status indicator.\n * Background changes from pending (yellow) to complete (green).\n */\n\nimport { Text } from '@mariozechner/pi-tui'\nimport { colors } from '../theme/theme.js'\n\nexport class AgentStep extends Text {\n private completed = false\n\n constructor(focus: string) {\n const styled = `${colors.stepPending('>')} ${colors.muted(focus)}`\n super(styled, 2, 0)\n }\n\n /** Mark this step as completed. */\n complete(): void {\n if (this.completed) return\n this.completed = true\n // Re-render would require knowing the original text — for now we leave styling as-is.\n // The step stays visible as context for the user.\n }\n}\n","/**\n * ChatLog — container managing the message list and streaming runs.\n *\n * Provides methods for adding user/system messages and managing\n * assistant streaming lifecycle (start → update → finalize).\n */\n\nimport { Container, Spacer, Text } from '@mariozechner/pi-tui'\nimport { AssistantMessage } from './assistant-message.js'\nimport { UserMessage } from './user-message.js'\nimport { SystemMessage, type SystemMessageLevel } from './system-message.js'\nimport { AgentStep } from './agent-step.js'\nimport { colors } from '../theme/theme.js'\n\nexport class ChatLog extends Container {\n /** Currently streaming assistant message (null when idle). */\n private activeAssistant: AssistantMessage | null = null\n\n /** Agent steps associated with the current streaming run. */\n private activeSteps: AgentStep[] = []\n\n /** Add a user message to the log. */\n addUser(text: string): void {\n this.addChild(new UserMessage(text))\n this.addChild(new Spacer(1))\n }\n\n /** Add a complete assistant message (non-streaming, e.g. for history restoration). */\n addAssistant(text: string): void {\n const msg = new AssistantMessage()\n msg.setText(text)\n this.addChild(msg)\n this.addChild(new Spacer(1))\n }\n\n /** Add a system/info/error message. */\n addSystem(message: string, level: SystemMessageLevel = 'info'): void {\n this.addChild(new SystemMessage(message, level))\n this.addChild(new Spacer(1))\n }\n\n /** Add a received DM message (cyan label with sender email). */\n addDm(senderEmail: string, text: string): void {\n const container = new Container()\n const label = new Text(colors.accent(senderEmail), 1, 0)\n const content = new Text(colors.text(text), 1, 0)\n container.addChild(label)\n container.addChild(content)\n this.addChild(container)\n this.addChild(new Spacer(1))\n }\n\n /** Remove all messages from the chat log. */\n clearMessages(): void {\n this.activeAssistant = null\n this.activeSteps = []\n // Remove all children by iterating backwards\n while (this.children.length > 0) {\n this.removeChild(this.children[this.children.length - 1])\n }\n }\n\n /** Start a new assistant streaming response. */\n startAssistant(): void {\n this.activeAssistant = new AssistantMessage()\n this.activeSteps = []\n this.addChild(this.activeAssistant)\n }\n\n /** Update the active assistant message with accumulated text. */\n updateAssistant(text: string): void {\n this.activeAssistant?.setText(text)\n }\n\n /** Add an agent step to the current streaming run. */\n addAgentStep(focus: string): void {\n if (!this.activeAssistant) return\n const step = new AgentStep(focus)\n this.activeSteps.push(step)\n // Insert step before the assistant message content\n this.addChild(step)\n }\n\n /** Finalize the current assistant response. */\n finalizeAssistant(): void {\n for (const step of this.activeSteps) {\n step.complete()\n }\n this.activeAssistant = null\n this.activeSteps = []\n this.addChild(new Spacer(1))\n }\n}\n","/**\n * ArbiEditor — custom Editor with ARBI-specific keybindings.\n *\n * Extends pi-tui's Editor to add:\n * - Escape → abort active stream\n * - Ctrl+C → clear input / double-tap to exit\n * - Ctrl+D → exit\n * - Ctrl+W → workspace selector\n * - Ctrl+N → new conversation\n */\n\nimport { Editor, matchesKey, Key, type TUI } from '@mariozechner/pi-tui'\nimport { editorTheme } from '../theme/theme.js'\n\nexport class ArbiEditor extends Editor {\n /** Callback when Escape is pressed (abort streaming). */\n onEscape?: () => void\n\n /** Callback when Ctrl+C is pressed (clear or exit). */\n onCtrlC?: () => void\n\n /** Callback when Ctrl+D is pressed (exit). */\n onCtrlD?: () => void\n\n /** Callback when Ctrl+W is pressed (workspace selector). */\n onCtrlW?: () => void\n\n /** Callback when Ctrl+N is pressed (new conversation). */\n onCtrlN?: () => void\n\n /** Track Ctrl+C presses for double-tap exit. */\n private lastCtrlCTime = 0\n\n constructor(tui: TUI) {\n super(tui, editorTheme, { paddingX: 1 })\n }\n\n override handleInput(data: string): void {\n if (matchesKey(data, Key.escape)) {\n this.onEscape?.()\n return\n }\n\n if (matchesKey(data, Key.ctrl('c'))) {\n const now = Date.now()\n if (this.getText().trim()) {\n // First Ctrl+C with content: clear input\n this.setText('')\n this.lastCtrlCTime = now\n } else if (now - this.lastCtrlCTime < 1000) {\n // Double Ctrl+C within 1s: exit\n this.onCtrlC?.()\n } else {\n this.lastCtrlCTime = now\n this.onCtrlC?.()\n }\n return\n }\n\n if (matchesKey(data, Key.ctrl('d'))) {\n this.onCtrlD?.()\n return\n }\n\n if (matchesKey(data, Key.ctrl('w'))) {\n this.onCtrlW?.()\n return\n }\n\n if (matchesKey(data, Key.ctrl('n'))) {\n this.onCtrlN?.()\n return\n }\n\n // Pass all other input to the base Editor\n super.handleInput(data)\n }\n}\n","/**\n * ToastContainer — auto-dismissing notification toasts.\n *\n * Manages a list of styled Text children that appear briefly then\n * auto-remove themselves. Used for WebSocket event notifications.\n */\n\nimport { Container, Text } from '@mariozechner/pi-tui'\nimport chalk from 'chalk'\n\nexport type ToastLevel = 'info' | 'success' | 'warning' | 'error'\n\nconst LEVEL_STYLE: Record<ToastLevel, (s: string) => string> = {\n info: chalk.dim.cyan,\n success: chalk.dim.green,\n warning: chalk.dim.yellow,\n error: chalk.dim.red,\n}\n\nfunction formatTimestamp(): string {\n const now = new Date()\n const hh = String(now.getHours()).padStart(2, '0')\n const mm = String(now.getMinutes()).padStart(2, '0')\n const ss = String(now.getSeconds()).padStart(2, '0')\n return `${hh}:${mm}:${ss}`\n}\n\ninterface ActiveToast {\n text: Text\n timer: ReturnType<typeof setTimeout>\n}\n\nexport class ToastContainer extends Container {\n private activeToasts: ActiveToast[] = []\n private renderCallback: (() => void) | null = null\n\n /** Set the callback used to trigger a TUI re-render after toast changes. */\n setRenderCallback(cb: () => void): void {\n this.renderCallback = cb\n }\n\n /** Show a toast notification that auto-dismisses after `durationMs`. */\n show(message: string, level: ToastLevel = 'info', durationMs = 5000): void {\n const styleFn = LEVEL_STYLE[level]\n const formatted = styleFn(`[${formatTimestamp()}] ${message}`)\n const text = new Text(formatted, 1, 0)\n\n const timer = setTimeout(() => {\n this.dismiss(text)\n }, durationMs)\n\n this.activeToasts.push({ text, timer })\n this.addChild(text)\n this.renderCallback?.()\n }\n\n /** Remove all active toasts immediately. */\n clear(): void {\n for (const toast of this.activeToasts) {\n clearTimeout(toast.timer)\n this.removeChild(toast.text)\n }\n this.activeToasts = []\n this.renderCallback?.()\n }\n\n private dismiss(text: Text): void {\n const idx = this.activeToasts.findIndex((t) => t.text === text)\n if (idx !== -1) {\n clearTimeout(this.activeToasts[idx].timer)\n this.activeToasts.splice(idx, 1)\n this.removeChild(text)\n this.renderCallback?.()\n }\n }\n}\n","/**\n * Command registry — slash commands available in the TUI.\n *\n * Each command has a name, description, and optional argument hint.\n * Used for autocomplete and help display.\n */\n\nimport type { SlashCommand } from '@mariozechner/pi-tui'\n\nexport interface TuiCommand extends SlashCommand {\n name: string\n description: string\n}\n\nexport const commands: TuiCommand[] = [\n { name: 'help', description: 'Show available commands' },\n { name: 'login', description: 'Log in (re-authenticate)' },\n { name: 'register', description: 'Register a new account' },\n { name: 'create', description: 'Create a new workspace: /create <name>' },\n { name: 'workspace', description: 'Switch workspace: /workspace <id>' },\n { name: 'workspaces', description: 'List all workspaces' },\n { name: 'contacts', description: 'List contacts (type @name to DM)' },\n { name: 'invite', description: 'Invite a contact: /invite user@example.com' },\n { name: 'docs', description: 'List documents in current workspace' },\n { name: 'upload', description: 'Upload a file: /upload <path>' },\n { name: 'delete', description: 'Delete a document: /delete <doc-id>' },\n { name: 'conversations', description: 'List conversations' },\n { name: 'new', description: 'Start fresh conversation (clear threading)' },\n { name: 'models', description: 'List available AI models' },\n { name: 'health', description: 'Show system health status' },\n { name: 'status', description: 'Show auth/workspace/connection status' },\n { name: 'logout', description: 'Log out and clear credentials' },\n { name: 'exit', description: 'Exit TUI' },\n { name: 'quit', description: 'Exit TUI' },\n]\n\n/** Format all commands as a help string for display. */\nexport function formatHelpText(): string {\n const lines = commands\n .filter((c) => c.name !== 'quit') // Don't show duplicate exit/quit\n .map((c) => ` /${c.name} — ${c.description}`)\n return [\n 'Available commands:',\n '',\n ...lines,\n '',\n 'Direct messages:',\n ' @name — Switch to DM channel with a contact',\n ' @arbi — Switch back to AI chat',\n '',\n 'Keyboard shortcuts:',\n ' Ctrl+N — New conversation',\n ' Ctrl+W — Switch workspace',\n ' Ctrl+D — Exit',\n ' Escape — Abort streaming',\n ].join('\\n')\n}\n","/**\n * Interactive prompt helpers using @inquirer/prompts.\n *\n * These are only used in interactive (TTY) flows — before the TUI starts\n * or after temporarily stopping it. Mirrors the CLI's prompt wrappers\n * for consistent validation and UX.\n */\n\nimport { select, input, password, confirm, checkbox, search } from '@inquirer/prompts'\n\nexport { select, input, password, confirm, checkbox, search }\n\n/**\n * Prompt user to pick from a list of items.\n * Returns the value of the selected choice.\n */\nexport async function promptSelect<T>(\n message: string,\n choices: Array<{ name: string; value: T; description?: string }>\n): Promise<T> {\n return select({ message, choices })\n}\n\n/**\n * Prompt user to pick multiple items from a list.\n * Returns array of selected values.\n */\nexport async function promptCheckbox<T>(\n message: string,\n choices: Array<{ name: string; value: T; checked?: boolean }>\n): Promise<T[]> {\n return checkbox({ message, choices })\n}\n\n/**\n * Prompt user to search and pick from a large list.\n * Type-ahead fuzzy filtering — best for docs (could be hundreds).\n */\nexport async function promptSearch<T>(\n message: string,\n choices: Array<{ name: string; value: T; description?: string }>\n): Promise<T> {\n return search({\n message,\n source: async (term) => {\n if (!term) return choices\n const lower = term.toLowerCase()\n return choices.filter((c) => c.name.toLowerCase().includes(lower))\n },\n })\n}\n\n/**\n * Prompt for text input. Returns trimmed string.\n */\nexport async function promptInput(message: string, required = true): Promise<string> {\n return input({\n message,\n validate: required ? (v) => (v.trim() ? true : 'Required') : undefined,\n })\n}\n\n/**\n * Prompt for a password (masked input).\n */\nexport async function promptPassword(message: string): Promise<string> {\n return password({\n message,\n mask: '*',\n validate: (v) => (v ? true : 'Required'),\n })\n}\n\n/**\n * Prompt for yes/no confirmation.\n */\nexport async function promptConfirm(message: string, defaultValue = true): Promise<boolean> {\n return confirm({ message, default: defaultValue })\n}\n","/**\n * Authentication flows for the TUI.\n *\n * Handles login and registration using @inquirer/prompts for interactive input.\n * These flows run BEFORE the TUI takes over the terminal (pi-tui raw mode),\n * or after temporarily stopping the TUI.\n */\n\nimport 'fake-indexeddb/auto'\nimport { createArbiClient } from '@arbidocs/client'\nimport type { ConfigStore, AuthContext } from '@arbidocs/sdk'\nimport {\n getErrorMessage,\n performPasswordLogin,\n formatWorkspaceChoices,\n resolveAuth,\n workspaces,\n} from '@arbidocs/sdk'\nimport { promptInput, promptPassword, promptSelect, promptConfirm } from './prompts.js'\n\n// ── Login ──────────────────────────────────────────────────────────────────\n\nexport interface LoginResult {\n authContext: AuthContext\n selectedWorkspaceId?: string\n selectedWorkspaceName?: string\n}\n\n/**\n * Interactive login flow. Prompts for email/password, authenticates,\n * and offers workspace selection.\n *\n * Must be called before the TUI starts (or after stopping it).\n */\nexport async function interactiveLogin(store: ConfigStore): Promise<LoginResult> {\n const config = store.requireConfig()\n\n const email = await promptInput('Email')\n const pw = await promptPassword('Password')\n\n const authContext = await performPasswordLogin(config, email, pw, store)\n\n console.info(`Logged in as ${email}`)\n\n // Workspace selection\n const result = await selectOrCreateWorkspace(authContext, store)\n\n return { authContext, ...result }\n}\n\n// ── Registration ───────────────────────────────────────────────────────────\n\n/**\n * Interactive registration flow. Prompts for email, verification code,\n * password, and name. Optionally logs in afterward.\n *\n * Must be called before the TUI starts (or after stopping it).\n */\nexport async function interactiveRegister(store: ConfigStore): Promise<LoginResult> {\n const config = store.requireConfig()\n\n const email = await promptInput('Email')\n\n const arbi = createArbiClient({\n baseUrl: config.baseUrl,\n deploymentDomain: config.deploymentDomain,\n credentials: 'omit',\n })\n await arbi.crypto.initSodium()\n\n // Verification\n const codeMethod = await promptSelect('Verification method', [\n { name: 'I have an invitation code', value: 'code' as const },\n { name: 'Send me a verification email', value: 'email' as const },\n ])\n\n let verificationCode: string\n if (codeMethod === 'code') {\n verificationCode = await promptInput('Invitation code')\n } else {\n console.info('Sending verification email...')\n const verifyResponse = await arbi.fetch.POST('/v1/user/verify-email', {\n body: { email },\n })\n if (verifyResponse.error) {\n throw new Error(`Failed to send verification email: ${JSON.stringify(verifyResponse.error)}`)\n }\n console.info('Verification email sent. Check your inbox.')\n verificationCode = await promptInput('Verification code')\n }\n\n // Password\n const pw = await promptPassword('Password')\n const confirmPw = await promptPassword('Confirm password')\n if (pw !== confirmPw) {\n throw new Error('Passwords do not match.')\n }\n\n // Name\n const firstName = (await promptInput('First name (optional)', false)) || 'User'\n const lastName = (await promptInput('Last name (optional)', false)) || ''\n\n // Register\n await arbi.auth.register({\n email,\n password: pw,\n verificationCode,\n firstName,\n lastName,\n })\n\n console.info(`\\nRegistered successfully as ${email}`)\n\n // Auto-login with the credentials just provided\n console.info('Logging in...')\n const authContext = await performPasswordLogin(config, email, pw, store)\n\n console.info(`Logged in as ${email}`)\n const result = await selectOrCreateWorkspace(authContext, store)\n\n return { authContext, ...result }\n}\n\n// ── Workspace selection / creation ──────────────────────────────────────────\n\n/**\n * After login, select an existing workspace or prompt to create one.\n * Used by both login and register flows.\n */\nasync function selectOrCreateWorkspace(\n authContext: AuthContext,\n store: ConfigStore\n): Promise<{ selectedWorkspaceId?: string; selectedWorkspaceName?: string }> {\n const wsList = await workspaces.listWorkspaces(authContext.arbi)\n\n if (wsList.length === 1) {\n store.updateConfig({ selectedWorkspaceId: wsList[0].external_id })\n console.info(`Workspace: ${wsList[0].name}`)\n return { selectedWorkspaceId: wsList[0].external_id, selectedWorkspaceName: wsList[0].name }\n }\n\n if (wsList.length > 1) {\n const choices = formatWorkspaceChoices(wsList)\n\n const selectedWorkspaceId = await promptSelect('Select workspace', choices)\n const ws = wsList.find((w) => w.external_id === selectedWorkspaceId)\n store.updateConfig({ selectedWorkspaceId })\n console.info(`Workspace: ${ws?.name}`)\n return { selectedWorkspaceId, selectedWorkspaceName: ws?.name }\n }\n\n // No workspaces — offer to create one\n console.info('No workspaces found.')\n const shouldCreate = await promptConfirm('Create a new workspace?')\n\n if (shouldCreate) {\n const name = await promptInput('Workspace name')\n\n const ws = await workspaces.createWorkspace(authContext.arbi, name.trim())\n store.updateConfig({ selectedWorkspaceId: ws.external_id })\n console.info(`Created workspace: ${ws.name}`)\n return { selectedWorkspaceId: ws.external_id, selectedWorkspaceName: ws.name }\n }\n\n return {}\n}\n\n// ── Pre-flight auth check ──────────────────────────────────────────────────\n\n/**\n * Check if the user is authenticated. If not, offer to login or register.\n * Returns the auth context if successful, or exits the process.\n *\n * Called at startup before the TUI launches.\n */\nexport async function ensureAuthenticated(store: ConfigStore): Promise<LoginResult> {\n // Try existing credentials first\n try {\n const authContext = await resolveAuth(store)\n const config = store.requireConfig()\n return {\n authContext,\n selectedWorkspaceId: config.selectedWorkspaceId,\n }\n } catch {\n // Not authenticated — offer login/register with retry on errors\n console.info('Not authenticated.\\n')\n }\n\n // Retry loop — keeps prompting until successful login/register or user exits\n while (true) {\n const action = await promptSelect('What would you like to do?', [\n { name: 'Log in', value: 'login' as const },\n { name: 'Register a new account', value: 'register' as const },\n { name: 'Exit', value: 'exit' as const },\n ])\n\n if (action === 'exit') {\n process.exit(0)\n }\n\n try {\n if (action === 'register') {\n return await interactiveRegister(store)\n }\n return await interactiveLogin(store)\n } catch (err) {\n console.error(`\\n${getErrorMessage(err)}\\n`)\n }\n }\n}\n","/**\n * Shared TUI helpers — eliminates repeated boilerplate across command handlers.\n *\n * - requireAuth(): guard that checks authentication\n * - showMessage(): addSystem + requestRender in one call\n * - switchWorkspace(): workspace selection + state update\n * - runInteractiveFlow(): pause TUI → run action → restart TUI\n */\n\nimport { getErrorMessage, selectWorkspaceById, resolveWorkspace } from '@arbidocs/sdk'\nimport type { ArbiTui } from './tui.js'\nimport type { SystemMessageLevel } from './components/system-message.js'\n\n/**\n * Guard: check that the user is authenticated.\n * Returns true if auth context is present, otherwise shows an error and returns false.\n */\nexport function requireAuth(\n tui: ArbiTui,\n message = 'Not authenticated. Use /login first.'\n): boolean {\n if (tui.authContext) return true\n showMessage(tui, message, 'error')\n return false\n}\n\n/**\n * Display a system message and request a render in one call.\n */\nexport function showMessage(tui: ArbiTui, message: string, level?: SystemMessageLevel): void {\n tui.chatLog.addSystem(message, level)\n tui.requestRender()\n}\n\n/**\n * Switch to a workspace by ID — selects it, updates TUI state, persists config.\n * Returns the workspace info on success, or null on failure.\n */\nexport async function switchWorkspace(\n tui: ArbiTui,\n workspaceId: string\n): Promise<{ external_id: string; name: string } | null> {\n if (!tui.authContext) return null\n\n try {\n const ws = await selectWorkspaceById(\n tui.authContext.arbi,\n workspaceId,\n tui.authContext.loginResult.serverSessionKey,\n tui.store.requireCredentials().signingPrivateKeyBase64\n )\n\n tui.state.workspaceId = ws.external_id\n tui.state.workspaceName = ws.name\n tui.state.conversationMessageId = null\n tui.store.clearChatSession()\n tui.store.updateConfig({ selectedWorkspaceId: ws.external_id })\n await tui.refreshWorkspaceContext()\n\n return ws\n } catch (err) {\n showMessage(tui, `Failed to switch workspace: ${getErrorMessage(err)}`, 'error')\n return null\n }\n}\n\n/**\n * Set up workspace context after login/register when a workspace was auto-selected.\n */\nexport async function applyWorkspaceSelection(\n tui: ArbiTui,\n workspaceId?: string,\n workspaceName?: string | null\n): Promise<void> {\n if (!workspaceId) return\n const wsCtx = await resolveWorkspace(tui.store, workspaceId)\n tui.setWorkspaceContext(wsCtx)\n tui.state.workspaceName = workspaceName ?? null\n}\n\n/**\n * Run an interactive flow that requires stdin (login, register).\n * Stops the TUI, runs the action, restarts the TUI, and handles errors.\n * Returns the action result on success, or null on failure.\n */\nexport async function runInteractiveFlow<T>(\n tui: ArbiTui,\n pauseMessage: string,\n action: () => Promise<T>,\n errorPrefix: string\n): Promise<T | null> {\n showMessage(tui, pauseMessage)\n tui.stopTui()\n\n try {\n const result = await action()\n tui.restartTui()\n return result\n } catch (err) {\n tui.restartTui()\n showMessage(tui, `${errorPrefix}: ${getErrorMessage(err)}`, 'error')\n return null\n }\n}\n","/**\n * Command handlers — dispatch logic for slash commands.\n *\n * Each handler receives the TUI context and performs its action,\n * typically displaying results in the chat log.\n */\n\nimport {\n getErrorMessage,\n formatUserName,\n workspaces,\n documents,\n conversations,\n contacts,\n health,\n} from '@arbidocs/sdk'\nimport type { ArbiTui } from './tui.js'\nimport { formatHelpText } from './commands.js'\nimport { interactiveLogin, interactiveRegister } from './auth.js'\nimport { colors } from './theme/theme.js'\nimport {\n requireAuth,\n showMessage,\n switchWorkspace,\n applyWorkspaceSelection,\n runInteractiveFlow,\n} from './tui-helpers.js'\n\n/** Dispatch a slash command. Returns true if handled. */\nexport async function handleCommand(tui: ArbiTui, input: string): Promise<boolean> {\n const trimmed = input.trim()\n if (!trimmed.startsWith('/')) return false\n\n const parts = trimmed.slice(1).split(/\\s+/)\n const cmd = parts[0]?.toLowerCase()\n const args = parts.slice(1)\n\n switch (cmd) {\n case 'help':\n showMessage(tui, formatHelpText())\n return true\n\n case 'login':\n await handleLogin(tui)\n return true\n\n case 'register':\n await handleRegister(tui)\n return true\n\n case 'create':\n await handleCreateWorkspace(tui, args.join(' '))\n return true\n\n case 'workspace':\n await handleWorkspaceSwitch(tui, args[0])\n return true\n\n case 'workspaces':\n await handleListWorkspaces(tui)\n return true\n\n case 'contacts':\n await handleListContacts(tui)\n return true\n\n case 'invite':\n await handleInviteContact(tui, args[0])\n return true\n\n case 'docs':\n await handleListDocs(tui)\n return true\n\n case 'upload':\n await handleUpload(tui, args.join(' '))\n return true\n\n case 'delete':\n await handleDelete(tui, args[0])\n return true\n\n case 'conversations':\n await handleListConversations(tui)\n return true\n\n case 'new':\n handleNewConversation(tui)\n return true\n\n case 'models':\n await handleModels(tui)\n return true\n\n case 'health':\n await handleHealth(tui)\n return true\n\n case 'status':\n handleStatus(tui)\n return true\n\n case 'logout':\n handleLogout(tui)\n return true\n\n case 'exit':\n case 'quit':\n tui.shutdown()\n return true\n\n default:\n showMessage(tui, `Unknown command: /${cmd}. Type /help for available commands.`, 'warning')\n return true\n }\n}\n\nasync function handleLogin(tui: ArbiTui): Promise<void> {\n const result = await runInteractiveFlow(\n tui,\n 'Pausing TUI for login...',\n () => interactiveLogin(tui.store),\n 'Login failed'\n )\n\n if (result) {\n tui.setAuthContext(result.authContext)\n await applyWorkspaceSelection(tui, result.selectedWorkspaceId, result.selectedWorkspaceName)\n showMessage(tui, 'Logged in successfully.')\n }\n}\n\nasync function handleRegister(tui: ArbiTui): Promise<void> {\n const result = await runInteractiveFlow(\n tui,\n 'Pausing TUI for registration...',\n () => interactiveRegister(tui.store),\n 'Registration failed'\n )\n\n if (result) {\n tui.setAuthContext(result.authContext)\n await applyWorkspaceSelection(tui, result.selectedWorkspaceId, result.selectedWorkspaceName)\n showMessage(tui, 'Registered and logged in.')\n }\n}\n\nasync function handleCreateWorkspace(tui: ArbiTui, name: string): Promise<void> {\n if (!requireAuth(tui)) return\n\n if (!name.trim()) {\n showMessage(tui, 'Usage: /create <workspace name>', 'warning')\n return\n }\n\n try {\n showMessage(tui, `Creating workspace \"${name}\"...`)\n const ws = await workspaces.createWorkspace(tui.authContext!.arbi, name.trim())\n const selected = await switchWorkspace(tui, ws.external_id)\n\n if (selected) {\n showMessage(tui, `Created and switched to workspace: ${colors.accentBold(selected.name)}`)\n }\n } catch (err) {\n showMessage(tui, `Failed to create workspace: ${getErrorMessage(err)}`, 'error')\n }\n}\n\nasync function handleWorkspaceSwitch(tui: ArbiTui, workspaceId?: string): Promise<void> {\n if (!requireAuth(tui, 'Not authenticated. Please restart and log in.')) return\n\n if (!workspaceId) {\n await handleListWorkspaces(tui)\n showMessage(tui, 'Use /workspace <id> to switch.')\n return\n }\n\n showMessage(tui, `Switching to workspace ${workspaceId}...`)\n const ws = await switchWorkspace(tui, workspaceId)\n if (ws) {\n showMessage(tui, `Switched to workspace: ${colors.accentBold(ws.name)}`)\n }\n}\n\nasync function handleListWorkspaces(tui: ArbiTui): Promise<void> {\n if (!requireAuth(tui, 'Not authenticated.')) return\n\n try {\n const wsList = await workspaces.listWorkspaces(tui.authContext!.arbi)\n const lines = wsList.map((ws) => {\n const current = ws.external_id === tui.state.workspaceId ? colors.accent(' (current)') : ''\n return ` ${ws.external_id} ${ws.name}${current}`\n })\n showMessage(tui, ['Workspaces:', '', ...lines].join('\\n'))\n } catch (err) {\n showMessage(tui, `Failed to list workspaces: ${getErrorMessage(err)}`, 'error')\n }\n}\n\nasync function handleListDocs(tui: ArbiTui): Promise<void> {\n if (!tui.wsContext) {\n showMessage(tui, 'No workspace selected. Use /workspace <id> first.', 'warning')\n return\n }\n\n try {\n const docs = await documents.listDocuments(tui.wsContext!.arbi)\n if (docs.length === 0) {\n showMessage(tui, 'No documents in this workspace.')\n } else {\n const lines = docs.map((d) => ` ${d.external_id} ${d.file_name ?? '(unnamed)'}`)\n showMessage(tui, [`Documents (${docs.length}):`, '', ...lines].join('\\n'))\n }\n } catch (err) {\n showMessage(tui, `Failed to list documents: ${getErrorMessage(err)}`, 'error')\n }\n}\n\nasync function handleListContacts(tui: ArbiTui): Promise<void> {\n if (!requireAuth(tui)) return\n\n try {\n const contactList = await contacts.listContacts(tui.authContext!.arbi)\n const { registered, pending } = contacts.groupContactsByStatus(contactList)\n\n if (registered.length === 0 && pending.length === 0) {\n showMessage(tui, 'No contacts. Use the web app to add contacts.')\n } else {\n const lines: string[] = []\n\n if (registered.length > 0) {\n lines.push(`Contacts (${registered.length}):`, '')\n for (const c of registered) {\n const name = formatUserName(c.user)\n const nameStr = name ? colors.muted(` (${name})`) : ''\n lines.push(` ${c.email}${nameStr}`)\n }\n }\n\n if (pending.length > 0) {\n if (lines.length > 0) lines.push('')\n lines.push(`Pending invitations (${pending.length}):`)\n for (const c of pending) {\n lines.push(` ${c.email} — ${colors.muted(c.status)}`)\n }\n }\n\n lines.push('', colors.muted('Type @name to start a DM with a registered contact.'))\n showMessage(tui, lines.join('\\n'))\n }\n } catch (err) {\n showMessage(tui, `Failed to list contacts: ${getErrorMessage(err)}`, 'error')\n }\n}\n\nasync function handleInviteContact(tui: ArbiTui, email?: string): Promise<void> {\n if (!requireAuth(tui)) return\n\n if (!email?.trim()) {\n showMessage(tui, 'Usage: /invite user@example.com', 'warning')\n return\n }\n\n try {\n showMessage(tui, `Inviting ${email}...`)\n\n const result = await contacts.addContacts(tui.authContext!.arbi, [email.trim()])\n const contact = result[0]\n\n if (contact?.status === 'registered') {\n showMessage(\n tui,\n `${colors.success('Added')} ${email} — already registered. You can DM them with @${email.split('@')[0]}`\n )\n } else {\n showMessage(\n tui,\n `${colors.success('Invited')} ${email} — invitation sent. They'll appear in /contacts once they register.`\n )\n }\n } catch (err) {\n showMessage(tui, `Failed to invite contact: ${getErrorMessage(err)}`, 'error')\n }\n}\n\nasync function handleListConversations(tui: ArbiTui): Promise<void> {\n if (!tui.wsContext) {\n showMessage(tui, 'No workspace selected. Use /workspace <id> first.', 'warning')\n return\n }\n\n try {\n const convs = await conversations.listConversations(tui.wsContext!.arbi)\n if (convs.length === 0) {\n showMessage(tui, 'No conversations in this workspace.')\n } else {\n const lines = convs.map((c) => ` ${c.external_id} ${c.title ?? '(untitled)'}`)\n showMessage(tui, [`Conversations (${convs.length}):`, '', ...lines].join('\\n'))\n }\n } catch (err) {\n showMessage(tui, `Failed to list conversations: ${getErrorMessage(err)}`, 'error')\n }\n}\n\nfunction handleNewConversation(tui: ArbiTui): void {\n tui.state.conversationMessageId = null\n tui.store.clearChatSession()\n showMessage(tui, 'Started new conversation.')\n}\n\nfunction handleStatus(tui: ArbiTui): void {\n const { state } = tui\n const lines = [\n `Authenticated: ${state.isAuthenticated ? colors.success('yes') : colors.error('no')}`,\n `Workspace: ${state.workspaceName ? colors.accent(state.workspaceName) : colors.muted('none')}`,\n `Workspace ID: ${state.workspaceId ?? colors.muted('none')}`,\n `Conversation: ${state.conversationMessageId ? colors.muted(state.conversationMessageId) : colors.muted('new')}`,\n `Status: ${state.activityStatus}`,\n `WebSocket: ${tui.wsConnected ? colors.success('connected') : colors.muted('disconnected')}`,\n ]\n showMessage(tui, lines.join('\\n'))\n}\n\nasync function handleUpload(tui: ArbiTui, filePath: string): Promise<void> {\n const wsCtx = tui.wsContext\n if (!wsCtx) {\n showMessage(tui, 'No workspace selected. Use /workspace <id> first.', 'warning')\n return\n }\n\n if (!filePath.trim()) {\n showMessage(tui, 'Usage: /upload <file-path>', 'warning')\n return\n }\n\n try {\n showMessage(tui, `Uploading ${filePath.trim()}...`)\n\n const result = await documents.uploadLocalFile(\n {\n baseUrl: wsCtx.config.baseUrl,\n accessToken: wsCtx.accessToken,\n workspaceKeyHeader: wsCtx.workspaceKeyHeader,\n },\n wsCtx.workspaceId,\n filePath.trim()\n )\n\n const ids = result.doc_ext_ids.join(', ')\n showMessage(tui, `${colors.success('Uploaded')} ${result.fileName} — doc ID(s): ${ids}`)\n\n if (result.duplicates && result.duplicates.length > 0) {\n showMessage(tui, `Duplicates detected: ${result.duplicates.join(', ')}`, 'warning')\n }\n } catch (err) {\n showMessage(tui, `Failed to upload: ${getErrorMessage(err)}`, 'error')\n }\n}\n\nasync function handleDelete(tui: ArbiTui, docId?: string): Promise<void> {\n if (!tui.wsContext) {\n showMessage(tui, 'No workspace selected. Use /workspace <id> first.', 'warning')\n return\n }\n\n if (!docId?.trim()) {\n showMessage(tui, 'Usage: /delete <doc-id> (use /docs to list document IDs)', 'warning')\n return\n }\n\n try {\n showMessage(tui, `Deleting document ${docId}...`)\n await documents.deleteDocuments(tui.wsContext!.arbi, [docId.trim()])\n showMessage(tui, `${colors.success('Deleted')} document ${docId}`)\n } catch (err) {\n showMessage(tui, `Failed to delete document: ${getErrorMessage(err)}`, 'error')\n }\n}\n\nfunction handleLogout(tui: ArbiTui): void {\n tui.store.deleteCredentials()\n tui.store.updateConfig({ selectedWorkspaceId: undefined })\n tui.store.clearChatSession()\n\n tui.authContext = null\n tui.state.isAuthenticated = false\n tui.state.workspaceId = null\n tui.state.workspaceName = null\n tui.state.conversationMessageId = null\n\n showMessage(tui, 'Logged out. Use /login to authenticate again.')\n}\n\nasync function handleHealth(tui: ArbiTui): Promise<void> {\n if (!requireAuth(tui)) return\n\n try {\n const data = await health.getHealth(tui.authContext!.arbi)\n const lines: string[] = ['System Health:', '']\n\n // Show overall status\n const status = (data as Record<string, unknown>).status as string | undefined\n if (status) {\n const statusColor = status === 'healthy' ? colors.success(status) : colors.warning(status)\n lines.push(` Status: ${statusColor}`)\n }\n\n // Show services if present\n const services = (data as Record<string, unknown>).services as\n | Record<string, unknown>\n | undefined\n if (services) {\n lines.push('', ' Services:')\n for (const [name, info] of Object.entries(services)) {\n const svc = info as Record<string, unknown>\n const svcStatus = svc.status as string | undefined\n const statusStr = svcStatus\n ? svcStatus === 'healthy'\n ? colors.success(svcStatus)\n : colors.error(svcStatus)\n : colors.muted('unknown')\n lines.push(` ${name}: ${statusStr}`)\n }\n }\n\n showMessage(tui, lines.join('\\n'))\n } catch (err) {\n showMessage(tui, `Failed to fetch health status: ${getErrorMessage(err)}`, 'error')\n }\n}\n\nasync function handleModels(tui: ArbiTui): Promise<void> {\n if (!requireAuth(tui)) return\n\n try {\n const data = await health.getHealthModels(tui.authContext!.arbi)\n const models = Array.isArray(data)\n ? data\n : (((data as Record<string, unknown>).data as unknown[]) ?? [])\n\n if (models.length === 0) {\n showMessage(tui, 'No models available.')\n return\n }\n\n const lines: string[] = [`Models (${models.length}):`, '']\n for (const m of models) {\n const model = m as Record<string, unknown>\n const name = (model.model_name ?? model.name ?? 'unknown') as string\n const provider = (model.provider ?? '') as string\n const apiType = (model.api_type ?? '') as string\n const parts = [colors.accent(name)]\n if (provider) parts.push(`provider: ${provider}`)\n if (apiType) parts.push(`api: ${apiType}`)\n lines.push(` ${parts.join(' ')}`)\n }\n\n showMessage(tui, lines.join('\\n'))\n } catch (err) {\n showMessage(tui, `Failed to fetch models: ${getErrorMessage(err)}`, 'error')\n }\n}\n","/**\n * SSE streaming event handler — wires @arbidocs/sdk streaming\n * into TUI component updates.\n */\n\nimport {\n getErrorMessage,\n streamSSE,\n type SSEStreamCallbacks,\n type SSEStreamResult,\n} from '@arbidocs/sdk'\nimport type { ArbiTui } from './tui.js'\n\n/**\n * Stream an assistant response from the API into the TUI.\n *\n * 1. Creates an assistant message in the chat log\n * 2. Streams tokens into it via SSE callbacks\n * 3. Displays agent steps as they arrive\n * 4. Finalizes when complete\n *\n * Returns the full SSE result for caller to extract metadata.\n */\nexport async function streamResponse(tui: ArbiTui, response: Response): Promise<SSEStreamResult> {\n tui.chatLog.startAssistant()\n tui.state.activityStatus = 'streaming'\n tui.requestRender()\n\n let accumulated = ''\n\n const callbacks: SSEStreamCallbacks = {\n onStreamStart: (data) => {\n if (data.assistant_message_ext_id) {\n tui.state.conversationMessageId = data.assistant_message_ext_id\n }\n },\n\n onToken: (content) => {\n accumulated += content\n tui.chatLog.updateAssistant(accumulated)\n tui.requestRender()\n },\n\n onAgentStep: (data) => {\n const focus = data.focus || data.step || ''\n if (focus) {\n tui.chatLog.addAgentStep(focus)\n tui.requestRender()\n }\n },\n\n onError: (message) => {\n tui.chatLog.addSystem(`Stream error: ${message}`, 'error')\n tui.requestRender()\n },\n }\n\n try {\n const result = await streamSSE(response, callbacks)\n tui.chatLog.finalizeAssistant()\n tui.state.activityStatus = 'idle'\n tui.requestRender()\n return result\n } catch (err) {\n tui.chatLog.finalizeAssistant()\n tui.state.activityStatus = 'error'\n tui.chatLog.addSystem(`Streaming failed: ${getErrorMessage(err)}`, 'error')\n tui.requestRender()\n throw err\n }\n}\n","/**\n * DM handler — encryption setup, send/receive, channel switching.\n *\n * Manages the DM channel state and E2E encrypted messaging.\n * Uses the same ECDH encryption pattern as the React frontend.\n */\n\nimport { getErrorMessage, dm, contacts } from '@arbidocs/sdk'\nimport {\n base64ToBytes,\n deriveEncryptionKeypairFromSigning,\n encryptMessage,\n decryptMessage,\n type KeyPair,\n type WsNotificationResponse,\n} from '@arbidocs/client'\nimport type { ArbiTui } from './tui.js'\nimport { colors } from './theme/theme.js'\nimport { showMessage } from './tui-helpers.js'\n\n// ── Types ────────────────────────────────────────────────────────────────────\n\nexport interface DmContact {\n external_id: string\n email: string\n encryption_public_key: string\n given_name: string\n family_name: string\n}\n\nexport interface DmChannel {\n user: DmContact\n}\n\n// ── Encryption keypair derivation ────────────────────────────────────────────\n\n/**\n * Derive X25519 encryption keypair from the stored Ed25519 signing key.\n * Called once after login.\n */\nexport function deriveEncryptionKeypair(signingPrivateKeyBase64: string): KeyPair {\n const signingPrivateKey = base64ToBytes(signingPrivateKeyBase64)\n // Ed25519 public key is the last 32 bytes of the 64-byte private key\n const ed25519PublicKey = signingPrivateKey.slice(32, 64)\n return deriveEncryptionKeypairFromSigning({\n publicKey: ed25519PublicKey,\n secretKey: signingPrivateKey,\n })\n}\n\n// ── Recipient resolution ─────────────────────────────────────────────────────\n\n/**\n * Resolve a @query to a contact user.\n * Matches by email prefix or given_name (case-insensitive).\n * Returns the matched contact user, or null if not found/ambiguous.\n */\nexport async function resolveRecipient(tui: ArbiTui, query: string): Promise<DmContact | null> {\n if (!tui.authContext) {\n showMessage(tui, 'Not authenticated. Use /login first.', 'error')\n return null\n }\n\n const queryLower = query.toLowerCase()\n\n try {\n const contactList = await contacts.listContacts(tui.authContext.arbi)\n\n // Filter for registered contacts with encryption keys\n const registered = contactList.filter(\n (c) => c.status === 'registered' && c.user?.encryption_public_key\n )\n\n // Match by email prefix (before @) or given_name\n const matches = registered.filter((c) => {\n const emailPrefix = c.email.split('@')[0]?.toLowerCase()\n const givenName = c.user?.given_name?.toLowerCase()\n return emailPrefix === queryLower || givenName === queryLower\n })\n\n if (matches.length === 0) {\n showMessage(\n tui,\n `No registered contact matching \"${query}\". Use /contacts to see available contacts.`,\n 'warning'\n )\n return null\n }\n\n if (matches.length > 1) {\n const names = matches\n .map((c) => ` ${c.email} (${c.user?.given_name ?? ''} ${c.user?.family_name ?? ''})`)\n .join('\\n')\n showMessage(tui, `Ambiguous match for \"${query}\". Be more specific:\\n${names}`, 'warning')\n return null\n }\n\n const contact = matches[0]\n const user = contact.user!\n return {\n external_id: user.external_id,\n email: contact.email,\n encryption_public_key: user.encryption_public_key,\n given_name: user.given_name,\n family_name: user.family_name,\n }\n } catch (err) {\n showMessage(tui, `Failed to resolve contact: ${getErrorMessage(err)}`, 'error')\n return null\n }\n}\n\n// ── Channel switching ────────────────────────────────────────────────────────\n\n/**\n * Handle @input — switch to DM channel or back to arbi.\n */\nexport async function handleChannelSwitch(tui: ArbiTui, input: string): Promise<void> {\n const query = input.slice(1).trim() // Remove leading @\n\n if (!query) {\n showMessage(tui, 'Usage: @username to switch to DM, @arbi to switch back.', 'warning')\n return\n }\n\n // @arbi — switch back to AI chat\n if (query.toLowerCase() === 'arbi') {\n switchToArbi(tui)\n return\n }\n\n // Resolve recipient\n const user = await resolveRecipient(tui, query)\n if (!user) return\n\n await switchToDmChannel(tui, user)\n}\n\n/**\n * Switch to a DM channel with a specific user.\n * Updates header, clears chat, loads DM history.\n */\nexport async function switchToDmChannel(tui: ArbiTui, user: DmContact): Promise<void> {\n if (!tui.authContext || !tui.encryptionKeys) {\n showMessage(tui, 'Not authenticated or encryption not initialized.', 'error')\n return\n }\n\n // Set channel state\n tui.currentDmChannel = { user }\n tui.updateHeader()\n\n // Clear chat log for DM view\n tui.chatLog.clearMessages()\n\n showMessage(tui, `Switched to DM with ${colors.accent(user.email)}. Type @arbi to switch back.`)\n\n // Fetch and display DM history\n await loadDmHistory(tui, user)\n}\n\n/**\n * Switch back to AI chat mode.\n */\nexport function switchToArbi(tui: ArbiTui): void {\n if (!tui.currentDmChannel) {\n showMessage(tui, 'Already in AI chat mode.', 'info')\n return\n }\n\n tui.currentDmChannel = null\n tui.updateHeader()\n\n // Clear chat log for fresh AI view\n tui.chatLog.clearMessages()\n showMessage(tui, 'Switched back to AI chat.')\n}\n\n// ── DM history ───────────────────────────────────────────────────────────────\n\n/**\n * Fetch all DMs and display the conversation with a specific user.\n */\nasync function loadDmHistory(tui: ArbiTui, user: DmContact): Promise<void> {\n if (!tui.authContext || !tui.encryptionKeys) return\n\n const myExtId = tui.authContext.loginResult.userExtId\n\n try {\n const allDms = await dm.listDMs(tui.authContext.arbi)\n\n // Filter for DMs between us and this user (type === 'user_message')\n const conversation = allDms.filter(\n (msg) =>\n msg.type === 'user_message' &&\n ((msg.sender.external_id === user.external_id && msg.recipient.external_id === myExtId) ||\n (msg.sender.external_id === myExtId && msg.recipient.external_id === user.external_id))\n )\n\n // Sort by created_at ascending\n conversation.sort((a, b) => new Date(a.created_at).getTime() - new Date(b.created_at).getTime())\n\n // Mark unread messages as read\n const unreadIds = conversation\n .filter((msg) => !msg.read && msg.sender.external_id === user.external_id)\n .map((msg) => msg.external_id)\n\n if (unreadIds.length > 0) {\n dm.markRead(tui.authContext.arbi, unreadIds).catch(() => {\n // Non-fatal — just log\n })\n }\n\n // Decrypt and display messages\n for (const msg of conversation) {\n const isSent = msg.sender.external_id === myExtId\n const plaintext = await decryptNotification(msg, myExtId!, tui.encryptionKeys, user)\n if (plaintext) {\n displayDmMessage(tui, plaintext, isSent, user.email)\n }\n }\n\n tui.requestRender()\n } catch (err) {\n showMessage(tui, `Failed to load DM history: ${getErrorMessage(err)}`, 'error')\n }\n}\n\n// ── Send encrypted DM ────────────────────────────────────────────────────────\n\n/**\n * Encrypt and send a DM to the current channel's recipient.\n */\nexport async function sendEncryptedDm(tui: ArbiTui, plaintext: string): Promise<void> {\n if (!tui.authContext || !tui.encryptionKeys || !tui.currentDmChannel) {\n showMessage(tui, 'Cannot send DM — not in a DM channel.', 'error')\n return\n }\n\n const recipient = tui.currentDmChannel.user\n\n try {\n // Encrypt the message\n const encrypted = await encryptMessage(\n plaintext,\n recipient.encryption_public_key,\n tui.encryptionKeys.secretKey\n )\n\n // Send via API\n await dm.sendDM(tui.authContext.arbi, [\n { recipient_ext_id: recipient.external_id, content: encrypted },\n ])\n\n // Display sent message in chat log\n displayDmMessage(tui, plaintext, true, recipient.email)\n tui.requestRender()\n } catch (err) {\n showMessage(tui, `Failed to send DM: ${getErrorMessage(err)}`, 'error')\n }\n}\n\n// ── Incoming DM handling (from WebSocket) ────────────────────────────────────\n\n/**\n * Handle an incoming WebSocket DM notification.\n * If we're in a DM channel with the sender, show it inline and return true.\n * Otherwise return false (caller shows toast).\n */\nexport async function handleIncomingDm(\n tui: ArbiTui,\n msg: WsNotificationResponse\n): Promise<boolean> {\n if (!tui.currentDmChannel || !tui.encryptionKeys || !tui.authContext) {\n return false\n }\n\n const myExtId = tui.authContext.loginResult.userExtId\n const channelUserId = tui.currentDmChannel.user.external_id\n\n // Check if this message is from the user we're chatting with\n if (msg.sender.external_id !== channelUserId) {\n return false\n }\n\n // Decrypt and display inline\n const plaintext = await decryptNotification(\n msg,\n myExtId!,\n tui.encryptionKeys,\n tui.currentDmChannel.user\n )\n\n if (plaintext) {\n displayDmMessage(tui, plaintext, false, msg.sender.email)\n tui.requestRender()\n\n // Mark as read\n dm.markRead(tui.authContext.arbi, [msg.external_id]).catch(() => {\n // Non-fatal\n })\n }\n\n return true\n}\n\n// ── Decryption helper ────────────────────────────────────────────────────────\n\n/**\n * Decrypt a notification's content field.\n *\n * For received messages: decrypt with sender's public key + our private key.\n * For sent messages: decrypt with recipient's public key + our private key.\n */\nasync function decryptNotification(\n notification: WsNotificationResponse,\n _myExtId: string,\n encryptionKeyPair: KeyPair,\n otherUser: DmContact\n): Promise<string | null> {\n if (!notification.content) return null\n\n try {\n // ECDH decryption uses the other party's public key in both cases\n return await decryptMessage(\n notification.content,\n otherUser.encryption_public_key,\n encryptionKeyPair.secretKey\n )\n } catch {\n return '[decryption failed]'\n }\n}\n\n// ── Display helper ───────────────────────────────────────────────────────────\n\n/**\n * Display a DM message in the chat log.\n * Sent messages show \"You:\", received show the sender's email.\n */\nfunction displayDmMessage(tui: ArbiTui, text: string, isSent: boolean, senderEmail: string): void {\n if (isSent) {\n tui.chatLog.addUser(text)\n } else {\n tui.chatLog.addDm(senderEmail, text)\n }\n}\n","/**\n * WebSocket handler — connects to backend WS and routes messages to toasts.\n *\n * Uses connectWithReconnect() from @arbidocs/sdk for connection/auth\n * with automatic reconnection, and formatWsMessage() from core for\n * shared message formatting.\n */\n\nimport {\n connectWithReconnect,\n formatWsMessage,\n type ReconnectableWsConnection,\n} from '@arbidocs/sdk'\nimport { type WebSocketServerMessage, type WsNotificationResponse } from '@arbidocs/client'\nimport type { ArbiTui } from './tui.js'\nimport type { ToastContainer, ToastLevel } from './components/toast-container.js'\nimport { handleIncomingDm } from './dm-handler.js'\n\n// ── Duration constants ────────────────────────────────────────────────────────\n\nconst DURATION_SHORT = 3000 // frequent in-progress updates\nconst DURATION_DEFAULT = 5000 // completed tasks, batch, notifications\nconst DURATION_LONG = 8000 // errors — longer so user notices\n\n// ── Duration mapping by level ────────────────────────────────────────────────\n\nconst DURATION_BY_LEVEL: Record<string, number> = {\n info: DURATION_SHORT,\n success: DURATION_DEFAULT,\n error: DURATION_LONG,\n warning: DURATION_DEFAULT,\n}\n\n// ── Helpers ──────────────────────────────────────────────────────────────────\n\n/** NotificationResponse uses NotificationType as its `type` field, not a single literal. */\nfunction isNotification(msg: WebSocketServerMessage): msg is WsNotificationResponse {\n return 'sender' in msg && 'recipient' in msg\n}\n\n// ── Message routing ───────────────────────────────────────────────────────────\n\nasync function handleMessage(\n msg: WebSocketServerMessage,\n toasts: ToastContainer,\n tui: ArbiTui | null\n): Promise<void> {\n // DM routing — TUI-specific: route user_message to the DM chat log\n if (isNotification(msg) && msg.type === 'user_message' && tui) {\n const handled = await handleIncomingDm(tui, msg)\n if (handled) return\n }\n\n // Use shared formatter for text + level\n const { text, level } = formatWsMessage(msg)\n const duration = DURATION_BY_LEVEL[level] ?? DURATION_DEFAULT\n toasts.show(text, level as ToastLevel, duration)\n}\n\n// ── Public API ────────────────────────────────────────────────────────────────\n\nexport interface TuiWsOptions {\n baseUrl: string\n accessToken: string\n toasts: ToastContainer\n tui?: ArbiTui\n}\n\n/**\n * Connect WebSocket with auto-reconnection and route messages to toast notifications.\n * Returns the connection handle for cleanup, or null on failure.\n */\nexport async function connectTuiWebSocket(\n options: TuiWsOptions\n): Promise<ReconnectableWsConnection | null> {\n const { baseUrl, accessToken, toasts, tui } = options\n\n try {\n const connection = await connectWithReconnect({\n baseUrl,\n accessToken,\n onMessage: (msg) => handleMessage(msg, toasts, tui ?? null),\n onClose: (_code, _reason) => {\n toasts.show('WebSocket disconnected', 'warning', DURATION_DEFAULT)\n },\n onReconnecting: (attempt, maxRetries) => {\n toasts.show(`Reconnecting... (${attempt}/${maxRetries})`, 'warning', DURATION_DEFAULT)\n },\n onReconnected: () => {\n toasts.show('WebSocket reconnected', 'success', DURATION_DEFAULT)\n },\n onReconnectFailed: () => {\n toasts.show('WebSocket reconnection failed', 'error', DURATION_LONG)\n },\n })\n return connection\n } catch {\n // Auth failure or connection error — not fatal, just skip WS\n toasts.show('WebSocket connection failed', 'warning', DURATION_DEFAULT)\n return null\n }\n}\n","/**\n * ArbiTui — main orchestrator for the ARBI terminal UI.\n *\n * Manages state, component wiring, and lifecycle. Coordinates between\n * the editor input, chat log display, command dispatch, and SSE streaming.\n */\n\nimport {\n TUI,\n ProcessTerminal,\n Text,\n Spacer,\n CombinedAutocompleteProvider,\n} from '@mariozechner/pi-tui'\nimport {\n type AuthContext,\n type WorkspaceContext,\n type ReconnectableWsConnection,\n type ConfigStore,\n getErrorMessage,\n assistant,\n documents,\n} from '@arbidocs/sdk'\nimport type { KeyPair } from '@arbidocs/client'\nimport { ChatLog } from './components/chat-log.js'\nimport { ArbiEditor } from './components/arbi-editor.js'\nimport { ToastContainer } from './components/toast-container.js'\nimport { handleCommand } from './command-handlers.js'\nimport { streamResponse } from './event-handlers.js'\nimport { connectTuiWebSocket } from './ws-handler.js'\nimport {\n type DmChannel,\n deriveEncryptionKeypair,\n handleChannelSwitch,\n sendEncryptedDm,\n} from './dm-handler.js'\nimport { commands } from './commands.js'\nimport { colors, formatHeader } from './theme/theme.js'\n\n// ── State ──────────────────────────────────────────────────────────────────\n\nexport interface TuiState {\n workspaceId: string | null\n workspaceName: string | null\n conversationMessageId: string | null\n activityStatus: 'idle' | 'sending' | 'streaming' | 'error'\n isAuthenticated: boolean\n}\n\n// ── Main TUI class ─────────────────────────────────────────────────────────\n\nexport class ArbiTui {\n private tui: TUI\n private header: Text\n\n /** The chat message log — public so command handlers can add messages. */\n readonly chatLog: ChatLog\n\n /** Toast notifications from WebSocket events. */\n readonly toastContainer: ToastContainer\n\n /** The input editor. */\n private editor: ArbiEditor\n\n /** Application state — public so handlers can read/write it. */\n state: TuiState\n\n /** Auth context from @arbidocs/sdk — set during init. */\n authContext: AuthContext | null = null\n\n /** Workspace context with tokens/headers — set when workspace is selected. */\n private workspaceContext: WorkspaceContext | null = null\n\n /** Config store for persistence. */\n readonly store: ConfigStore\n\n /** Active WebSocket connection (null when not connected). */\n private wsConnection: ReconnectableWsConnection | null = null\n\n /** X25519 encryption keypair derived from signing key (null until login). */\n private encryptionKeyPair: KeyPair | null = null\n\n /** Current DM channel (null = AI chat mode). */\n private dmChannel: DmChannel | null = null\n\n constructor(store: ConfigStore) {\n this.store = store\n\n this.state = {\n workspaceId: null,\n workspaceName: null,\n conversationMessageId: null,\n activityStatus: 'idle',\n isAuthenticated: false,\n }\n\n // Build TUI component tree\n this.tui = new TUI(new ProcessTerminal())\n\n // Header\n this.header = new Text(formatHeader(null, 'starting...'), 1, 0)\n\n // Chat log\n this.chatLog = new ChatLog()\n\n // Toast container for WebSocket notifications\n this.toastContainer = new ToastContainer()\n this.toastContainer.setRenderCallback(() => this.tui.requestRender())\n\n // Editor\n this.editor = this.createEditor()\n\n // Compose layout\n this.tui.addChild(this.header)\n this.tui.addChild(new Spacer(1))\n this.tui.addChild(this.toastContainer)\n this.tui.addChild(this.chatLog)\n this.tui.addChild(this.editor)\n\n this.tui.setFocus(this.editor)\n }\n\n // ── Lifecycle ──────────────────────────────────────────────────────────\n\n /** Start the TUI event loop. */\n start(): void {\n this.tui.start()\n this.updateHeader()\n this.tui.requestRender()\n }\n\n /** Gracefully shut down the TUI and exit. */\n shutdown(): void {\n this.wsConnection?.close()\n this.wsConnection = null\n this.toastContainer.clear()\n this.tui.stop()\n process.exit(0)\n }\n\n /**\n * Temporarily stop the TUI (releases terminal raw mode).\n * Used before interactive prompts that need stdin (login, register).\n */\n stopTui(): void {\n this.tui.stop()\n }\n\n /**\n * Restart the TUI after a stopTui() call.\n * Rebuilds the component tree with a fresh TUI instance since\n * pi-tui doesn't support stop/start cycling on the same instance.\n */\n restartTui(): void {\n this.tui = new TUI(new ProcessTerminal())\n\n // Re-compose layout\n this.tui.addChild(this.header)\n this.tui.addChild(new Spacer(1))\n this.tui.addChild(this.toastContainer)\n this.tui.addChild(this.chatLog)\n\n // Create new editor (needs fresh TUI reference)\n this.editor = this.createEditor()\n this.tui.addChild(this.editor)\n this.tui.setFocus(this.editor)\n\n this.tui.start()\n this.updateHeader()\n this.tui.requestRender()\n }\n\n /** Create and wire a new editor instance. */\n private createEditor(): ArbiEditor {\n const editor = new ArbiEditor(this.tui)\n editor.setAutocompleteProvider(new CombinedAutocompleteProvider(commands))\n editor.onSubmit = (text: string) => this.handleSubmit(text)\n editor.onEscape = () => this.handleAbort()\n editor.onCtrlC = () => this.shutdown()\n editor.onCtrlD = () => this.shutdown()\n editor.onCtrlW = () => this.handleSubmit('/workspaces')\n editor.onCtrlN = () => this.handleSubmit('/new')\n return editor\n }\n\n /** Request a render update. */\n requestRender(): void {\n this.tui.requestRender()\n }\n\n // ── Auth / Workspace ───────────────────────────────────────────────────\n\n /** Set authentication context after login. */\n setAuthContext(ctx: AuthContext): void {\n this.authContext = ctx\n this.state.isAuthenticated = true\n this.encryptionKeyPair = deriveEncryptionKeypair(\n this.store.requireCredentials().signingPrivateKeyBase64\n )\n this.updateHeader()\n }\n\n /** Set workspace context after workspace selection. */\n setWorkspaceContext(ctx: WorkspaceContext): void {\n this.workspaceContext = ctx\n this.state.workspaceId = ctx.workspaceId\n // Workspace name will be set separately since WorkspaceContext doesn't include it\n this.updateHeader()\n this.connectWebSocket()\n }\n\n /** Refresh workspace context (after switching workspaces). */\n async refreshWorkspaceContext(): Promise<void> {\n if (!this.state.workspaceId || !this.authContext) return\n\n const { resolveWorkspace } = await import('@arbidocs/sdk')\n const ctx = await resolveWorkspace(this.store, this.state.workspaceId)\n this.workspaceContext = ctx\n this.updateHeader()\n }\n\n /** Public accessor for workspace context (used by command handlers). */\n get wsContext(): WorkspaceContext | null {\n return this.workspaceContext\n }\n\n /** Whether the WebSocket is currently connected. */\n get wsConnected(): boolean {\n return this.wsConnection !== null\n }\n\n /** Connect (or reconnect) WebSocket for real-time notifications. */\n private connectWebSocket(): void {\n if (!this.workspaceContext) return\n\n // Close existing connection before reconnecting\n this.wsConnection?.close()\n this.wsConnection = null\n\n const { config, accessToken } = this.workspaceContext\n\n connectTuiWebSocket({\n baseUrl: config.baseUrl,\n accessToken,\n toasts: this.toastContainer,\n tui: this,\n }).then((conn) => {\n this.wsConnection = conn\n })\n }\n\n // ── Input handling ─────────────────────────────────────────────────────\n\n private async handleSubmit(text: string): Promise<void> {\n const trimmed = text.trim()\n if (!trimmed) return\n\n // Check for @channel switching\n if (trimmed.startsWith('@')) {\n await handleChannelSwitch(this, trimmed)\n return\n }\n\n // Check for slash commands\n if (trimmed.startsWith('/')) {\n const handled = await handleCommand(this, trimmed)\n if (handled) return\n }\n\n // Route to DM or AI based on channel\n if (this.dmChannel) {\n await sendEncryptedDm(this, trimmed)\n } else {\n await this.sendMessage(trimmed)\n }\n }\n\n private handleAbort(): void {\n if (this.state.activityStatus === 'streaming') {\n // TODO: implement AbortController for stream cancellation\n this.chatLog.addSystem('Abort requested (stream will complete current chunk).', 'warning')\n this.requestRender()\n }\n }\n\n // ── Messaging ──────────────────────────────────────────────────────────\n\n private async sendMessage(question: string): Promise<void> {\n if (!this.workspaceContext) {\n this.chatLog.addSystem(\n 'No workspace selected. Use /workspace <id> or /workspaces to choose one.',\n 'warning'\n )\n this.requestRender()\n return\n }\n\n // Display user message\n this.chatLog.addUser(question)\n this.state.activityStatus = 'sending'\n this.updateHeader()\n this.requestRender()\n\n try {\n // Get all docs in workspace for retrieval context\n const docs = await documents.listDocuments(this.workspaceContext.arbi)\n const docIds = docs.map((d) => d.external_id as string)\n\n // Load chat session for conversation threading\n const session = this.store.getChatSession()\n const previousResponseId = this.state.conversationMessageId ?? session.lastMessageExtId\n\n // Query the assistant\n const response = await assistant.queryAssistant({\n baseUrl: this.workspaceContext.config.baseUrl,\n accessToken: this.workspaceContext.accessToken,\n workspaceKeyHeader: this.workspaceContext.workspaceKeyHeader,\n workspaceId: this.workspaceContext.workspaceId,\n question,\n docIds,\n previousResponseId,\n })\n\n // Stream the response into the chat log\n const result = await streamResponse(this, response)\n\n // Save conversation state for threading and history restoration\n if (result.assistantMessageExtId) {\n this.state.conversationMessageId = result.assistantMessageExtId\n const sessionUpdate: Record<string, string> = {\n lastMessageExtId: result.assistantMessageExtId,\n }\n // Extract conversation ID from user_message or metadata\n const conversationExtId =\n (result.userMessage?.conversation_ext_id as string) ??\n (result.metadata?.conversation_ext_id as string)\n if (conversationExtId) {\n sessionUpdate.conversationExtId = conversationExtId\n }\n this.store.updateChatSession(sessionUpdate)\n }\n } catch (err) {\n this.state.activityStatus = 'error'\n this.chatLog.addSystem(`Error: ${getErrorMessage(err)}`, 'error')\n }\n\n this.state.activityStatus = 'idle'\n this.updateHeader()\n this.requestRender()\n }\n\n // ── UI Updates ─────────────────────────────────────────────────────────\n\n /** Update the header bar — public so dm-handler can call it. */\n updateHeader(): void {\n const statusText =\n this.state.activityStatus === 'idle'\n ? colors.success('ready')\n : this.state.activityStatus === 'streaming'\n ? colors.warning('streaming...')\n : this.state.activityStatus === 'sending'\n ? colors.warning('sending...')\n : colors.error('error')\n\n if (this.dmChannel) {\n this.header.setText(formatHeader(`DM: ${this.dmChannel.user.email}`, statusText))\n } else {\n this.header.setText(formatHeader(this.state.workspaceName, statusText))\n }\n }\n\n // ── DM channel accessors (used by dm-handler) ────────────────────────────\n\n /** Current DM channel (null = AI chat mode). */\n get currentDmChannel(): DmChannel | null {\n return this.dmChannel\n }\n\n set currentDmChannel(ch: DmChannel | null) {\n this.dmChannel = ch\n }\n\n /** Encryption keypair for E2E DM encryption. */\n get encryptionKeys(): KeyPair | null {\n return this.encryptionKeyPair\n }\n}\n","/**\n * ARBI TUI — entry point\n *\n * Handles CLI argument parsing, authentication, and TUI launch.\n * Uses @arbidocs/sdk for auth and config, pi-tui for rendering.\n *\n * If not authenticated, offers interactive login/register before launching.\n *\n * Usage:\n * arbi-tui # Launch with default workspace\n * arbi-tui -w <workspace-id> # Launch with specific workspace\n */\n\n// Suppress SDK middleware logging\nconsole.debug = () => {}\nconst _origInfo = console.info\nconsole.info = (...args: unknown[]) => {\n if (typeof args[0] === 'string' && args[0].startsWith('[API]')) return\n _origInfo(...args)\n}\n\nimport { Command } from 'commander'\nimport {\n FileConfigStore,\n getErrorMessage,\n resolveWorkspace,\n workspaces,\n conversations,\n} from '@arbidocs/sdk'\nimport { ArbiTui } from './tui.js'\nimport { ensureAuthenticated } from './auth.js'\n\nconst program = new Command()\n\nprogram\n .name('arbi-tui')\n .description('Interactive terminal UI for ARBI — chat with the RAG assistant')\n .version('0.1.0')\n .option('-w, --workspace <id>', 'Workspace ID to use')\n .action(async (opts: { workspace?: string }) => {\n const store = new FileConfigStore()\n\n // Ensure config exists\n try {\n store.requireConfig()\n } catch {\n console.error('Not configured. Run `arbi config set-url <url>` first.')\n process.exit(1)\n }\n\n // Authenticate — offers login/register if not already authenticated\n const { authContext, selectedWorkspaceId, selectedWorkspaceName } =\n await ensureAuthenticated(store)\n\n // Resolve workspace\n const workspaceId = opts.workspace || selectedWorkspaceId\n\n // Create and start TUI\n const tui = new ArbiTui(store)\n tui.setAuthContext(authContext)\n\n if (workspaceId) {\n try {\n const wsCtx = await resolveWorkspace(store, workspaceId)\n tui.setWorkspaceContext(wsCtx)\n\n // Get workspace name\n if (selectedWorkspaceName && workspaceId === selectedWorkspaceId) {\n tui.state.workspaceName = selectedWorkspaceName\n } else {\n const wsList = await workspaces.listWorkspaces(authContext.arbi)\n const ws = wsList.find((w) => w.external_id === workspaceId)\n if (ws) {\n tui.state.workspaceName = ws.name\n }\n }\n } catch (err) {\n tui.chatLog.addSystem(`Failed to load workspace: ${getErrorMessage(err)}`, 'warning')\n tui.chatLog.addSystem('Use /workspaces to list and /workspace <id> to select.')\n }\n } else {\n tui.chatLog.addSystem(\n 'No workspace selected. Use /workspaces to list and /workspace <id> to select.'\n )\n }\n\n // Load chat session for conversation continuity\n const session = store.getChatSession()\n if (session.lastMessageExtId) {\n tui.state.conversationMessageId = session.lastMessageExtId\n }\n\n // Restore chat history from previous session\n if (session.conversationExtId && session.lastMessageExtId && tui.authContext) {\n try {\n const threads = await conversations.getConversationThreads(\n tui.authContext.arbi,\n session.conversationExtId\n )\n const threadList = (threads as { threads?: unknown[] }).threads ?? []\n const thread = threadList.find(\n (t) =>\n (t as { leaf_message_ext_id?: string }).leaf_message_ext_id === session.lastMessageExtId\n ) as { history?: { role: string; content: string }[] } | undefined\n\n if (thread?.history && thread.history.length > 0) {\n for (const msg of thread.history) {\n if (msg.role === 'user') {\n tui.chatLog.addUser(msg.content)\n } else if (msg.role === 'assistant') {\n tui.chatLog.addAssistant(msg.content)\n }\n }\n tui.chatLog.addSystem('--- restored from previous session ---')\n }\n } catch {\n // History restoration is best-effort — continue normally\n }\n }\n\n tui.chatLog.addSystem(\n 'Type a question to chat with the ARBI assistant. Use /help for commands.'\n )\n tui.start()\n })\n\nprogram.parse()\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@arbidocs/tui",
3
- "version": "0.3.8",
3
+ "version": "0.3.10",
4
4
  "description": "Interactive terminal UI for ARBI — chat-style RAG assistant with streaming responses",
5
5
  "main": "dist/index.js",
6
6
  "bin": {
@@ -14,8 +14,8 @@
14
14
  "typecheck": "tsc --noEmit"
15
15
  },
16
16
  "dependencies": {
17
- "@arbidocs/core": "0.3.8",
18
- "@arbidocs/sdk": "0.3.8",
17
+ "@arbidocs/sdk": "0.3.10",
18
+ "@arbidocs/client": "0.3.10",
19
19
  "@inquirer/prompts": "^8.2.0",
20
20
  "@mariozechner/pi-tui": "^0.52.6",
21
21
  "chalk": "^5.4.1",
@@ -33,7 +33,7 @@
33
33
  },
34
34
  "repository": {
35
35
  "type": "git",
36
- "url": "git+https://github.com/arbitrationcity/ARBI-frontend.git",
36
+ "url": "git+https://github.com/arbicity/ARBI-frontend.git",
37
37
  "directory": "packages/arbi-tui"
38
38
  },
39
39
  "keywords": [