@serkanalgur/opencode-nexus 2.6.0 → 2.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +148 -40
- package/dist/index.js +4628 -218
- package/dist/tui.js +266 -52
- package/package.json +3 -4
package/dist/tui.js
CHANGED
|
@@ -116,6 +116,14 @@ var DEFAULT_CONFIG = {
|
|
|
116
116
|
enabled: true,
|
|
117
117
|
maxRetries: 3,
|
|
118
118
|
contextTransfer: true
|
|
119
|
+
},
|
|
120
|
+
dashboard: {
|
|
121
|
+
enabled: true,
|
|
122
|
+
port: 4747,
|
|
123
|
+
host: "127.0.0.1"
|
|
124
|
+
},
|
|
125
|
+
notifications: {
|
|
126
|
+
enabled: true
|
|
119
127
|
}
|
|
120
128
|
};
|
|
121
129
|
|
|
@@ -124,9 +132,13 @@ class NexusConfigManager {
|
|
|
124
132
|
globalConfig = null;
|
|
125
133
|
storageConfig = null;
|
|
126
134
|
loadInfo = null;
|
|
127
|
-
|
|
135
|
+
dashboardBase;
|
|
136
|
+
notificationsBase;
|
|
137
|
+
constructor(dashboardBase, notificationsBase) {
|
|
128
138
|
this.projectConfig = null;
|
|
129
139
|
this.globalConfig = null;
|
|
140
|
+
this.dashboardBase = { ...DEFAULT_CONFIG.dashboard, ...dashboardBase };
|
|
141
|
+
this.notificationsBase = { ...DEFAULT_CONFIG.notifications, ...notificationsBase };
|
|
130
142
|
}
|
|
131
143
|
loadConfigs(basePath) {
|
|
132
144
|
if (this.loadInfo === null)
|
|
@@ -188,6 +200,14 @@ class NexusConfigManager {
|
|
|
188
200
|
...this.globalConfig?.selfHealing,
|
|
189
201
|
...this.projectConfig?.selfHealing,
|
|
190
202
|
...this.storageConfig?.selfHealing
|
|
203
|
+
},
|
|
204
|
+
dashboard: {
|
|
205
|
+
enabled: this.storageConfig?.dashboard?.enabled ?? this.projectConfig?.dashboard?.enabled ?? this.globalConfig?.dashboard?.enabled ?? this.dashboardBase.enabled,
|
|
206
|
+
port: this.storageConfig?.dashboard?.port ?? this.projectConfig?.dashboard?.port ?? this.globalConfig?.dashboard?.port ?? this.dashboardBase.port,
|
|
207
|
+
host: this.storageConfig?.dashboard?.host ?? this.projectConfig?.dashboard?.host ?? this.globalConfig?.dashboard?.host ?? this.dashboardBase.host
|
|
208
|
+
},
|
|
209
|
+
notifications: {
|
|
210
|
+
enabled: this.storageConfig?.notifications?.enabled ?? this.projectConfig?.notifications?.enabled ?? this.globalConfig?.notifications?.enabled ?? this.notificationsBase.enabled
|
|
191
211
|
}
|
|
192
212
|
};
|
|
193
213
|
}
|
|
@@ -308,6 +328,8 @@ class NexusConfigManager {
|
|
|
308
328
|
result.models = { ...current.models };
|
|
309
329
|
result.budget = { ...current.budget };
|
|
310
330
|
result.selfHealing = { ...current.selfHealing };
|
|
331
|
+
result.dashboard = { ...current.dashboard };
|
|
332
|
+
result.notifications = { ...current.notifications };
|
|
311
333
|
return result;
|
|
312
334
|
}
|
|
313
335
|
resetToDefaults() {
|
|
@@ -528,6 +550,185 @@ function mergeSidebarAgents(agents, polled, childIDs) {
|
|
|
528
550
|
}
|
|
529
551
|
return next.filter((a) => a.sessionID && childIDs.includes(a.sessionID) || a.status === "completed" || a.status === "failed");
|
|
530
552
|
}
|
|
553
|
+
async function probeDashboard(host, port, fetchImpl = fetch) {
|
|
554
|
+
const url = `http://${host}:${port}/api/health`;
|
|
555
|
+
let response;
|
|
556
|
+
try {
|
|
557
|
+
response = await fetchImpl(url);
|
|
558
|
+
} catch (error) {
|
|
559
|
+
const detail = error instanceof Error ? error.message : String(error);
|
|
560
|
+
const refused = /ECONNREFUSED|fetch failed|Failed to fetch|NetworkError|ECONNRESET/i.test(detail);
|
|
561
|
+
return {
|
|
562
|
+
listening: false,
|
|
563
|
+
isNexusDashboard: false,
|
|
564
|
+
detail: refused ? `nothing is listening on ${host}:${port}` : `could not reach ${host}:${port} (${detail})`
|
|
565
|
+
};
|
|
566
|
+
}
|
|
567
|
+
let body;
|
|
568
|
+
try {
|
|
569
|
+
body = await response.json();
|
|
570
|
+
} catch {
|
|
571
|
+
return {
|
|
572
|
+
listening: true,
|
|
573
|
+
isNexusDashboard: false,
|
|
574
|
+
detail: `${host}:${port} answered ${response.status} but not with dashboard JSON`
|
|
575
|
+
};
|
|
576
|
+
}
|
|
577
|
+
if (body !== null && typeof body === "object" && !Array.isArray(body)) {
|
|
578
|
+
const record = body;
|
|
579
|
+
if (record.ok === true && typeof record.uptime === "number") {
|
|
580
|
+
return {
|
|
581
|
+
listening: true,
|
|
582
|
+
isNexusDashboard: true,
|
|
583
|
+
detail: `a nexus dashboard is serving ${host}:${port}`
|
|
584
|
+
};
|
|
585
|
+
}
|
|
586
|
+
}
|
|
587
|
+
return {
|
|
588
|
+
listening: true,
|
|
589
|
+
isNexusDashboard: false,
|
|
590
|
+
detail: `something else is listening on ${host}:${port} and it is not a nexus dashboard`
|
|
591
|
+
};
|
|
592
|
+
}
|
|
593
|
+
function parseWebDashboardTarget(input, fallback) {
|
|
594
|
+
const parts = (input ?? "").trim().split(/\s+/).filter(Boolean);
|
|
595
|
+
let port = fallback.port;
|
|
596
|
+
let host = fallback.host;
|
|
597
|
+
if (parts.length > 0) {
|
|
598
|
+
const parsed = Number(parts[0]);
|
|
599
|
+
if (!Number.isInteger(parsed) || parsed < 1 || parsed > 65535) {
|
|
600
|
+
return { error: `"${parts[0]}" is not a port number. Give a port between 1 and 65535.` };
|
|
601
|
+
}
|
|
602
|
+
port = parsed;
|
|
603
|
+
}
|
|
604
|
+
if (parts.length > 1) {
|
|
605
|
+
host = parts[1];
|
|
606
|
+
}
|
|
607
|
+
return { target: { port, host } };
|
|
608
|
+
}
|
|
609
|
+
var LISTEN_CONFIRM_ATTEMPTS = 15;
|
|
610
|
+
var LISTEN_CONFIRM_INTERVAL_MS = 200;
|
|
611
|
+
function defaultWait(ms) {
|
|
612
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
613
|
+
}
|
|
614
|
+
async function handleWebDashboard(input, deps) {
|
|
615
|
+
const parsed = parseWebDashboardTarget(input, {
|
|
616
|
+
port: deps.dashboard.port,
|
|
617
|
+
host: deps.dashboard.host
|
|
618
|
+
});
|
|
619
|
+
if ("error" in parsed) {
|
|
620
|
+
deps.showToast({ title: "Nexus Web Dashboard", message: parsed.error, variant: "error" });
|
|
621
|
+
return;
|
|
622
|
+
}
|
|
623
|
+
const { port, host } = parsed.target;
|
|
624
|
+
const url = `http://${host}:${port}`;
|
|
625
|
+
if (!deps.dashboard.enabled) {
|
|
626
|
+
deps.showToast({
|
|
627
|
+
title: "Nexus Web Dashboard \u2014 disabled",
|
|
628
|
+
message: [
|
|
629
|
+
`The dashboard is switched off: \`dashboard.enabled\` is false in your nexus.jsonc,`,
|
|
630
|
+
"so nothing will listen on any port and no browser was opened.",
|
|
631
|
+
"",
|
|
632
|
+
"Set it to true (or delete the `dashboard` block, which defaults to enabled),",
|
|
633
|
+
"then run /nexus web again."
|
|
634
|
+
].join(`
|
|
635
|
+
`),
|
|
636
|
+
variant: "error",
|
|
637
|
+
duration: 12000
|
|
638
|
+
});
|
|
639
|
+
return;
|
|
640
|
+
}
|
|
641
|
+
const probe = await probeDashboard(host, port, deps.fetchImpl);
|
|
642
|
+
if (probe.isNexusDashboard) {
|
|
643
|
+
await deps.openBrowser(url);
|
|
644
|
+
deps.showToast({
|
|
645
|
+
title: "\u26A1 Nexus Web Dashboard",
|
|
646
|
+
message: `Opened ${url} \u2014 a dashboard is already running there, so nothing was started.`,
|
|
647
|
+
variant: "success",
|
|
648
|
+
duration: 6000
|
|
649
|
+
});
|
|
650
|
+
return;
|
|
651
|
+
}
|
|
652
|
+
if (probe.listening) {
|
|
653
|
+
deps.showToast({
|
|
654
|
+
title: "Nexus Web Dashboard \u2014 port in use",
|
|
655
|
+
message: [
|
|
656
|
+
`${probe.detail}.`,
|
|
657
|
+
"",
|
|
658
|
+
"No browser was opened: that address is not the dashboard.",
|
|
659
|
+
"Run /nexus web with a different port, e.g. /nexus web 4748."
|
|
660
|
+
].join(`
|
|
661
|
+
`),
|
|
662
|
+
variant: "error",
|
|
663
|
+
duration: 12000
|
|
664
|
+
});
|
|
665
|
+
return;
|
|
666
|
+
}
|
|
667
|
+
let submitted;
|
|
668
|
+
try {
|
|
669
|
+
await deps.submitCommand(`/nexus dashboard ${port} ${host}`);
|
|
670
|
+
submitted = `/nexus dashboard ${port} ${host}`;
|
|
671
|
+
} catch (error) {
|
|
672
|
+
const detail = error instanceof Error ? error.message : String(error);
|
|
673
|
+
deps.showToast({
|
|
674
|
+
title: "Nexus Web Dashboard \u2014 could not start",
|
|
675
|
+
message: [
|
|
676
|
+
`The dashboard start command never reached the OpenCode server: ${detail}`,
|
|
677
|
+
"",
|
|
678
|
+
"No server is listening on that port and no browser was opened.",
|
|
679
|
+
"The dashboard runs in the server process, so this needs the server's",
|
|
680
|
+
"HTTP endpoint to be reachable from the TUI."
|
|
681
|
+
].join(`
|
|
682
|
+
`),
|
|
683
|
+
variant: "error",
|
|
684
|
+
duration: 15000
|
|
685
|
+
});
|
|
686
|
+
return;
|
|
687
|
+
}
|
|
688
|
+
const wait = deps.waitImpl ?? defaultWait;
|
|
689
|
+
const attempts = deps.confirmAttempts ?? LISTEN_CONFIRM_ATTEMPTS;
|
|
690
|
+
const intervalMs = deps.confirmIntervalMs ?? LISTEN_CONFIRM_INTERVAL_MS;
|
|
691
|
+
for (let attempt = 0;attempt < attempts; attempt++) {
|
|
692
|
+
if (attempt > 0)
|
|
693
|
+
await wait(intervalMs);
|
|
694
|
+
const check = await probeDashboard(host, port, deps.fetchImpl);
|
|
695
|
+
if (check.isNexusDashboard) {
|
|
696
|
+
await deps.openBrowser(url);
|
|
697
|
+
deps.showToast({
|
|
698
|
+
title: "\u26A1 Nexus Web Dashboard",
|
|
699
|
+
message: `Started and opened ${url} \u2014 a dashboard is serving there now.`,
|
|
700
|
+
variant: "success",
|
|
701
|
+
duration: 8000
|
|
702
|
+
});
|
|
703
|
+
return;
|
|
704
|
+
}
|
|
705
|
+
}
|
|
706
|
+
deps.showToast({
|
|
707
|
+
title: "Nexus Web Dashboard \u2014 not started",
|
|
708
|
+
message: [
|
|
709
|
+
`Ran \`${submitted}\`, but nothing is serving on ${host}:${port} after ${Math.round(attempts * intervalMs / 1000)}s,`,
|
|
710
|
+
"so no browser was opened and there is no URL to give you.",
|
|
711
|
+
"",
|
|
712
|
+
"The command runs in the OpenCode server process, which is the only place",
|
|
713
|
+
"the dashboard can start. If a Nexus plugin is active in that process, its",
|
|
714
|
+
`result is in this session as the reply to \`${submitted}\` \u2014 that text names`,
|
|
715
|
+
"the reason (a port already in use, or `dashboard.enabled: false`). If no",
|
|
716
|
+
"plugin is active there, the command was never handled at all. If the port",
|
|
717
|
+
"is held by another process, free it or pass a different one:",
|
|
718
|
+
"/nexus web 4748."
|
|
719
|
+
].join(`
|
|
720
|
+
`),
|
|
721
|
+
variant: "error",
|
|
722
|
+
duration: 20000
|
|
723
|
+
});
|
|
724
|
+
}
|
|
725
|
+
async function openInBrowser(url) {
|
|
726
|
+
try {
|
|
727
|
+
const { exec } = await import("child_process");
|
|
728
|
+
const command = process.platform === "darwin" ? "open" : process.platform === "win32" ? "start" : "xdg-open";
|
|
729
|
+
exec(`${command} ${url}`);
|
|
730
|
+
} catch {}
|
|
731
|
+
}
|
|
531
732
|
var tui_default = define({
|
|
532
733
|
id: "nexus.cli",
|
|
533
734
|
setup(context) {
|
|
@@ -619,10 +820,31 @@ var tui_default = define({
|
|
|
619
820
|
variant: "success"
|
|
620
821
|
});
|
|
621
822
|
};
|
|
622
|
-
const
|
|
823
|
+
const activeSessionID = () => {
|
|
824
|
+
const route = context.ui.router.current();
|
|
825
|
+
if (route.type === "session")
|
|
826
|
+
return route.sessionID;
|
|
827
|
+
return context.ui.tabs.list().find((tab) => tab.active)?.sessionID;
|
|
828
|
+
};
|
|
829
|
+
const submitServerCommand = async (text) => {
|
|
830
|
+
const sessionID = activeSessionID();
|
|
831
|
+
if (!sessionID) {
|
|
832
|
+
throw new Error("no session is open to run the command in");
|
|
833
|
+
}
|
|
834
|
+
await context.client.session.prompt({ sessionID, text });
|
|
835
|
+
};
|
|
836
|
+
const runWebDashboard = async (input) => {
|
|
837
|
+
await handleWebDashboard(input, {
|
|
838
|
+
dashboard: configManager.getConfig().dashboard,
|
|
839
|
+
showToast: (options) => context.ui.toast.show(options),
|
|
840
|
+
openBrowser: openInBrowser,
|
|
841
|
+
submitCommand: submitServerCommand
|
|
842
|
+
});
|
|
843
|
+
};
|
|
844
|
+
const handleOverview = async () => {
|
|
623
845
|
const config = configManager.getConfig();
|
|
624
846
|
const lines = [
|
|
625
|
-
"\u26A1 Nexus
|
|
847
|
+
"\u26A1 Nexus Overview",
|
|
626
848
|
"\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550",
|
|
627
849
|
"",
|
|
628
850
|
"\uD83E\uDD16 Agent Models:"
|
|
@@ -646,6 +868,9 @@ var tui_default = define({
|
|
|
646
868
|
lines.push(" /nexus status - Show config summary");
|
|
647
869
|
lines.push(" /nexus config - Configure models & budget");
|
|
648
870
|
lines.push(" /nexus model - Select model for role");
|
|
871
|
+
lines.push(" /nexus dashboard - Start the web dashboard and open it");
|
|
872
|
+
lines.push(" /nexus web - Same: start it if needed, then open it");
|
|
873
|
+
lines.push(" /nexus overview - Show this overview");
|
|
649
874
|
lines.push(" /nexus reset - Reset to defaults");
|
|
650
875
|
lines.push("");
|
|
651
876
|
lines.push("\uD83D\uDD27 Tools (use in agent prompt):");
|
|
@@ -653,8 +878,14 @@ var tui_default = define({
|
|
|
653
878
|
lines.push(" nexus.agents - List spawned agents");
|
|
654
879
|
lines.push(" nexus.costs - Cost report");
|
|
655
880
|
lines.push(" nexus.spawn - Spawn a sub-agent");
|
|
881
|
+
lines.push(" nexus.dashboard.start - Start the web dashboard server");
|
|
882
|
+
lines.push("");
|
|
883
|
+
lines.push("\uD83D\uDCCA Web Dashboard:");
|
|
884
|
+
lines.push(` Enabled: ${config.dashboard.enabled ? "\u2705" : "\u274C"}`);
|
|
885
|
+
lines.push(` Address: http://${config.dashboard.host}:${config.dashboard.port} (when running)`);
|
|
886
|
+
lines.push(" Not running? /nexus dashboard starts it and opens it.");
|
|
656
887
|
context.ui.toast.show({
|
|
657
|
-
title: "Nexus
|
|
888
|
+
title: "Nexus Overview",
|
|
658
889
|
message: lines.join(`
|
|
659
890
|
`),
|
|
660
891
|
variant: "info",
|
|
@@ -697,34 +928,14 @@ var tui_default = define({
|
|
|
697
928
|
break;
|
|
698
929
|
case "dashboard":
|
|
699
930
|
case "d":
|
|
700
|
-
await
|
|
931
|
+
await runWebDashboard(parts.slice(1).join(" "));
|
|
932
|
+
break;
|
|
933
|
+
case "overview":
|
|
934
|
+
await handleOverview();
|
|
701
935
|
break;
|
|
702
936
|
case "web":
|
|
703
937
|
case "w":
|
|
704
|
-
|
|
705
|
-
const port = parts[1] ? parseInt(parts[1]) : 4747;
|
|
706
|
-
const host = parts[2] || "127.0.0.1";
|
|
707
|
-
context.ui.toast.show({
|
|
708
|
-
title: "\u26A1 Nexus Web Dashboard",
|
|
709
|
-
message: [
|
|
710
|
-
`Starting dashboard on port ${port}...`,
|
|
711
|
-
"",
|
|
712
|
-
`Ask the agent to run: nexus.dashboard.start(port=${port})`,
|
|
713
|
-
"",
|
|
714
|
-
`Or type: nexus.dashboard.start with port=${port} in your next message`,
|
|
715
|
-
"",
|
|
716
|
-
`Then open: http://${host}:${port}`
|
|
717
|
-
].join(`
|
|
718
|
-
`),
|
|
719
|
-
variant: "success",
|
|
720
|
-
duration: 8000
|
|
721
|
-
});
|
|
722
|
-
try {
|
|
723
|
-
const { exec } = await import("child_process");
|
|
724
|
-
const cmd = process.platform === "darwin" ? "open" : process.platform === "win32" ? "start" : "xdg-open";
|
|
725
|
-
exec(`${cmd} http://${host}:${port}`);
|
|
726
|
-
} catch {}
|
|
727
|
-
}
|
|
938
|
+
await runWebDashboard(parts.slice(1).join(" "));
|
|
728
939
|
break;
|
|
729
940
|
case "model":
|
|
730
941
|
case "m":
|
|
@@ -762,7 +973,7 @@ var tui_default = define({
|
|
|
762
973
|
default:
|
|
763
974
|
context.ui.toast.show({
|
|
764
975
|
title: "Nexus",
|
|
765
|
-
message: "Commands: config, status, dashboard, web [port], model <role>, reset",
|
|
976
|
+
message: "Commands: config, status, dashboard [port], web [port], overview, model <role>, reset",
|
|
766
977
|
variant: "info"
|
|
767
978
|
});
|
|
768
979
|
}
|
|
@@ -783,45 +994,42 @@ var tui_default = define({
|
|
|
783
994
|
await handleFullConfig();
|
|
784
995
|
}
|
|
785
996
|
},
|
|
997
|
+
{
|
|
998
|
+
id: "nexus.overview",
|
|
999
|
+
title: "Nexus Overview (config, budget, dashboard status)",
|
|
1000
|
+
group: "Nexus",
|
|
1001
|
+
palette: true,
|
|
1002
|
+
slash: { name: "nexus-overview", aliases: ["no"], arguments: true },
|
|
1003
|
+
enabled: () => true,
|
|
1004
|
+
suggested: true,
|
|
1005
|
+
run: async () => {
|
|
1006
|
+
await handleOverview();
|
|
1007
|
+
}
|
|
1008
|
+
},
|
|
786
1009
|
{
|
|
787
1010
|
id: "nexus.dashboard",
|
|
788
|
-
title: "Nexus Dashboard",
|
|
1011
|
+
title: "Start the Nexus Web Dashboard",
|
|
1012
|
+
description: "Starts the dashboard server if it is not already running, then opens it in your browser",
|
|
789
1013
|
group: "Nexus",
|
|
790
1014
|
palette: true,
|
|
791
1015
|
slash: { name: "nexus-dashboard", aliases: ["nd"], arguments: true },
|
|
792
1016
|
enabled: () => true,
|
|
793
1017
|
suggested: true,
|
|
794
|
-
run: async () => {
|
|
795
|
-
await
|
|
1018
|
+
run: async (input) => {
|
|
1019
|
+
await runWebDashboard(input);
|
|
796
1020
|
}
|
|
797
1021
|
},
|
|
798
1022
|
{
|
|
799
1023
|
id: "nexus.web",
|
|
800
|
-
title: "
|
|
1024
|
+
title: "Open the Nexus Web Dashboard",
|
|
1025
|
+
description: "Alias of Nexus Dashboard: starts it if needed, then opens it in your browser",
|
|
801
1026
|
group: "Nexus",
|
|
802
1027
|
palette: true,
|
|
803
1028
|
slash: { name: "nexus-web", aliases: ["nw"], arguments: true },
|
|
804
1029
|
enabled: () => true,
|
|
805
1030
|
suggested: true,
|
|
806
1031
|
run: async (input) => {
|
|
807
|
-
|
|
808
|
-
const host = "127.0.0.1";
|
|
809
|
-
context.ui.toast.show({
|
|
810
|
-
title: "\u26A1 Nexus Web Dashboard",
|
|
811
|
-
message: [
|
|
812
|
-
`Port: ${port} Host: ${host}`,
|
|
813
|
-
"",
|
|
814
|
-
"To start the dashboard, ask the agent:",
|
|
815
|
-
` nexus.dashboard.start(port=${port}, host="${host}")`,
|
|
816
|
-
"",
|
|
817
|
-
`Then open: http://${host}:${port}`,
|
|
818
|
-
"",
|
|
819
|
-
"Tip: The dashboard shows live agent status, costs, and history."
|
|
820
|
-
].join(`
|
|
821
|
-
`),
|
|
822
|
-
variant: "info",
|
|
823
|
-
duration: 12000
|
|
824
|
-
});
|
|
1032
|
+
await runWebDashboard(input);
|
|
825
1033
|
}
|
|
826
1034
|
},
|
|
827
1035
|
{
|
|
@@ -1064,9 +1272,15 @@ var tui_default = define({
|
|
|
1064
1272
|
}
|
|
1065
1273
|
});
|
|
1066
1274
|
export {
|
|
1275
|
+
LISTEN_CONFIRM_ATTEMPTS,
|
|
1276
|
+
LISTEN_CONFIRM_INTERVAL_MS,
|
|
1067
1277
|
collectSidebarAgents,
|
|
1068
1278
|
tui_default as default,
|
|
1279
|
+
handleWebDashboard,
|
|
1069
1280
|
mergeSidebarAgents,
|
|
1281
|
+
openInBrowser,
|
|
1282
|
+
parseWebDashboardTarget,
|
|
1283
|
+
probeDashboard,
|
|
1070
1284
|
sidebarAgentFor,
|
|
1071
1285
|
sidebarChildSessionIDs
|
|
1072
1286
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@serkanalgur/opencode-nexus",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.8.0",
|
|
4
4
|
"description": "Adaptive Multi-Agent Orchestration with Cost Intelligence for OpenCode V2",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"opencode",
|
|
@@ -44,18 +44,17 @@
|
|
|
44
44
|
"dev": "bun run --watch src/index.ts",
|
|
45
45
|
"typecheck": "tsc --noEmit",
|
|
46
46
|
"test": "bun test",
|
|
47
|
-
"lint": "biome check src/",
|
|
48
|
-
"format": "biome format --write src/",
|
|
47
|
+
"lint": "biome check src/ test/ && tsc --noEmit && bun -e 'const page = \"dashboard/index.html\"; const html = await Bun.file(page).text(); const inline = [...html.matchAll(/<script(?![^>]*\\bsrc=)[^>]*>([\\s\\S]*?)<\\/script>/g)]; if (inline.length === 0) throw new Error(page + \" has no inline <script> to check\"); inline.forEach(m => { new Function(m[1]); }); console.log(\"lint: \" + page + \" - \" + inline.length + \" inline script(s) parse clean\");'",
|
|
49
48
|
"prepublishOnly": "bun run build"
|
|
50
49
|
},
|
|
51
50
|
"dependencies": {
|
|
52
51
|
"@opencode/plugin": "latest"
|
|
53
52
|
},
|
|
54
53
|
"devDependencies": {
|
|
54
|
+
"@biomejs/biome": "latest",
|
|
55
55
|
"@opentui/core": "^0.5.8",
|
|
56
56
|
"@opentui/solid": "^0.5.8",
|
|
57
57
|
"@types/bun": "latest",
|
|
58
|
-
"biome": "latest",
|
|
59
58
|
"bun-types": "^1.4.2",
|
|
60
59
|
"solid-js": "^1.9.0",
|
|
61
60
|
"typescript": "^5.5.0"
|