@serkanalgur/opencode-nexus 2.4.1 → 2.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/dist/index.js +696 -110
  2. package/dist/tui.js +89 -60
  3. package/package.json +1 -1
package/dist/tui.js CHANGED
@@ -94,7 +94,7 @@ function describeFile(file) {
94
94
  }
95
95
  function formatConfigLoadLog(info) {
96
96
  const models = Object.entries(info.models).map(([role, model]) => `${role}=${model}`).join(" ");
97
- const override = info.sessionOverride ? " (+session override: storage; disk edits to models are IGNORED while a preset is set \u2014 clear the preset in the TUI to hand control back to disk)" : "";
97
+ const override = info.sessionOverride ? ' (+session override: storage; disk edits to models are IGNORED while a preset is set \u2014 call the preset tool with mode "clear", or reset in the TUI, to hand control back to disk)' : "";
98
98
  return `[nexus] config loaded (#${info.loadCount} trigger=${info.trigger} at=${info.loadedAt}) ` + `project=${info.project.path} [${describeFile(info.project)}] ` + `global=${info.global.path} [${describeFile(info.global)}] ` + `models:${override} ${models}`;
99
99
  }
100
100
  var DEFAULT_CONFIG = {
@@ -311,7 +311,9 @@ class NexusConfigManager {
311
311
  return result;
312
312
  }
313
313
  resetToDefaults() {
314
+ const hadOverride = this.storageConfig !== null;
314
315
  this.storageConfig = null;
316
+ return hadOverride;
315
317
  }
316
318
  applyPreset(name) {
317
319
  const preset = PRESETS[name];
@@ -454,6 +456,78 @@ var PRESETS = {
454
456
 
455
457
  // src/tui.tsx
456
458
  import { jsxDEV, Fragment } from "@opentui/solid/jsx-dev-runtime";
459
+ var NEXUS_AGENT_PREFIX = "nexus-";
460
+ function metadataString(metadata, key) {
461
+ const value = metadata?.[key];
462
+ return typeof value === "string" && value.length > 0 ? value : undefined;
463
+ }
464
+ function roleFromAgent(agent) {
465
+ if (!agent)
466
+ return;
467
+ const role = agent.startsWith(NEXUS_AGENT_PREFIX) ? agent.slice(NEXUS_AGENT_PREFIX.length) : agent;
468
+ return role.length > 0 ? role : undefined;
469
+ }
470
+ function modelLabel(model) {
471
+ if (!model?.providerID || !model.id)
472
+ return;
473
+ return `${model.providerID}/${model.id}`;
474
+ }
475
+ function titleCase(value) {
476
+ return value.charAt(0).toUpperCase() + value.slice(1);
477
+ }
478
+ function sidebarAgentFor(session, status, now) {
479
+ const role = metadataString(session.metadata, "nexusRole") ?? roleFromAgent(session.agent);
480
+ return {
481
+ id: session.id,
482
+ name: role ? titleCase(role) : session.title || session.id.slice(0, 12),
483
+ role: role ?? "agent",
484
+ status,
485
+ model: metadataString(session.metadata, "nexusModel") ?? modelLabel(session.model) ?? "",
486
+ sessionID: session.id,
487
+ spawnedAt: now,
488
+ tasksCompleted: 0,
489
+ tasksFailed: 0
490
+ };
491
+ }
492
+ function sidebarChildSessionIDs(family, currentSessionID) {
493
+ if (!Array.isArray(family))
494
+ return [];
495
+ return family.filter((id) => id !== currentSessionID);
496
+ }
497
+ function collectSidebarAgents(source, currentSessionID, statusOf, now) {
498
+ const childIDs = sidebarChildSessionIDs(source.family(currentSessionID), currentSessionID);
499
+ if (childIDs.length === 0)
500
+ return [];
501
+ const agents = [];
502
+ for (const id of childIDs) {
503
+ try {
504
+ const session = source.get(id);
505
+ if (!session)
506
+ continue;
507
+ let status = "completed";
508
+ try {
509
+ status = statusOf(id);
510
+ } catch {}
511
+ agents.push(sidebarAgentFor(session, status, now));
512
+ } catch {}
513
+ }
514
+ return agents;
515
+ }
516
+ function mergeSidebarAgents(agents, polled, childIDs) {
517
+ const next = agents.map((agent) => ({ ...agent }));
518
+ for (const agent of polled) {
519
+ const existing = next.find((a) => a.sessionID === agent.sessionID);
520
+ if (existing) {
521
+ existing.status = agent.status;
522
+ existing.name = agent.name;
523
+ existing.role = agent.role;
524
+ existing.model = agent.model;
525
+ } else {
526
+ next.push(agent);
527
+ }
528
+ }
529
+ return next.filter((a) => a.sessionID && childIDs.includes(a.sessionID) || a.status === "completed" || a.status === "failed");
530
+ }
457
531
  var tui_default = define({
458
532
  id: "nexus.cli",
459
533
  setup(context) {
@@ -848,69 +922,20 @@ var tui_default = define({
848
922
  const currentSessionID = currentRoute.sessionID;
849
923
  if (!currentSessionID)
850
924
  return;
851
- const family = context.data.session.family(currentSessionID);
852
- if (!family || !Array.isArray(family))
853
- return;
854
- const childIDs = family.filter((id) => id !== currentSessionID);
855
- try {
856
- const allSessions = context.data.session.list();
857
- if (allSessions && Array.isArray(allSessions)) {
858
- for (const s of allSessions) {
859
- if (!s || !s.id)
860
- continue;
861
- const meta = s.metadata;
862
- if (meta?.nexusRole && !childIDs.includes(s.id) && s.id !== currentSessionID) {
863
- childIDs.push(s.id);
864
- }
865
- }
866
- }
867
- } catch {}
925
+ const source = context.data.session;
926
+ const childIDs = sidebarChildSessionIDs(source.family(currentSessionID), currentSessionID);
868
927
  if (childIDs.length === 0) {
869
928
  setSidebarState((draft) => {
870
- draft.agents = draft.agents.filter((a) => a.status === "completed" || a.status === "failed");
929
+ draft.agents = mergeSidebarAgents(draft.agents, [], []);
871
930
  });
872
931
  return;
873
932
  }
874
- const newAgents = childIDs.map((id) => {
875
- try {
876
- const session = context.data.session.get(id);
877
- if (!session)
878
- return null;
879
- const meta = session.metadata || {};
880
- let status = "completed";
881
- try {
882
- status = context.data.session.status(id) === "running" ? "working" : "completed";
883
- } catch {}
884
- return {
885
- id,
886
- name: meta.nexusRole ? `${meta.nexusRole.charAt(0).toUpperCase() + meta.nexusRole.slice(1)}` : session?.title || id.slice(0, 12),
887
- role: meta.nexusRole || "agent",
888
- status,
889
- model: meta.nexusModel || "",
890
- sessionID: id,
891
- spawnedAt: new Date().toISOString(),
892
- tasksCompleted: 0,
893
- tasksFailed: 0
894
- };
895
- } catch {
896
- return null;
897
- }
898
- }).filter(Boolean);
899
- if (newAgents.length > 0) {
900
- setSidebarState((draft) => {
901
- for (const agent of newAgents) {
902
- const existing = draft.agents.find((a) => a.sessionID === agent.sessionID);
903
- if (existing) {
904
- existing.status = agent.status;
905
- existing.name = agent.name;
906
- existing.model = agent.model;
907
- } else {
908
- draft.agents.push(agent);
909
- }
910
- }
911
- draft.agents = draft.agents.filter((a) => a.sessionID && childIDs.includes(a.sessionID) || a.status === "completed" || a.status === "failed");
912
- });
913
- }
933
+ const newAgents = collectSidebarAgents(source, currentSessionID, (id) => context.data.session.status(id) === "running" ? "working" : "completed", new Date().toISOString());
934
+ if (newAgents.length === 0)
935
+ return;
936
+ setSidebarState((draft) => {
937
+ draft.agents = mergeSidebarAgents(draft.agents, newAgents, childIDs);
938
+ });
914
939
  } catch {}
915
940
  };
916
941
  const unsubSessionSucceeded = context.data.on("session.execution.succeeded", (event) => {
@@ -1039,5 +1064,9 @@ var tui_default = define({
1039
1064
  }
1040
1065
  });
1041
1066
  export {
1042
- tui_default as default
1067
+ collectSidebarAgents,
1068
+ tui_default as default,
1069
+ mergeSidebarAgents,
1070
+ sidebarAgentFor,
1071
+ sidebarChildSessionIDs
1043
1072
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@serkanalgur/opencode-nexus",
3
- "version": "2.4.1",
3
+ "version": "2.6.0",
4
4
  "description": "Adaptive Multi-Agent Orchestration with Cost Intelligence for OpenCode V2",
5
5
  "keywords": [
6
6
  "opencode",