opencode-hub 1.0.12 → 1.0.14
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/oc-tui.js +65 -27
- package/package.json +27 -27
package/oc-tui.js
CHANGED
|
@@ -25,7 +25,7 @@ function loadNpmPlugins() {
|
|
|
25
25
|
if (!existsSync(ocPath)) return [];
|
|
26
26
|
try {
|
|
27
27
|
var raw = readFileSync(ocPath, "utf-8");
|
|
28
|
-
var stripped = raw.replace(
|
|
28
|
+
var stripped = raw.replace(/^\s*\/\/[^\n]*/gm, "");
|
|
29
29
|
var oc = JSON.parse(stripped);
|
|
30
30
|
var plugins = oc.plugin || [];
|
|
31
31
|
return plugins
|
|
@@ -276,7 +276,7 @@ function buildPluginList() {
|
|
|
276
276
|
|
|
277
277
|
function fetchPluginRemotes(pluginItems) {
|
|
278
278
|
for (var p of pluginItems) {
|
|
279
|
-
if (!p.installed) continue;
|
|
279
|
+
if (p.type === "npm" || !p.installed) continue;
|
|
280
280
|
var dir = join(REPOS_DIR, p.folderName);
|
|
281
281
|
gitText(["git", "fetch", "origin"], dir);
|
|
282
282
|
for (var ref of ["origin/HEAD", "origin/main", "origin/master"]) {
|
|
@@ -376,8 +376,35 @@ function showCur() { process.stderr.write(E + "?25h"); }
|
|
|
376
376
|
// ---------------------------------------------------------------------------
|
|
377
377
|
|
|
378
378
|
var items = buildList();
|
|
379
|
-
|
|
380
|
-
|
|
379
|
+
|
|
380
|
+
function buildCombinedPluginList() {
|
|
381
|
+
var git = buildPluginList();
|
|
382
|
+
var npm = loadNpmPlugins().map(function(np) {
|
|
383
|
+
return {
|
|
384
|
+
type: "npm",
|
|
385
|
+
name: np.name,
|
|
386
|
+
version: np.version,
|
|
387
|
+
raw: np.raw,
|
|
388
|
+
// filler fields so shared code doesn't crash
|
|
389
|
+
enabled: true,
|
|
390
|
+
autoUpdate: false,
|
|
391
|
+
installed: !!np.version,
|
|
392
|
+
deployed: !!np.version,
|
|
393
|
+
updateAvail: false,
|
|
394
|
+
localHead: "",
|
|
395
|
+
remoteHead: "",
|
|
396
|
+
latestTag: np.version || "",
|
|
397
|
+
subject: "npm plugin",
|
|
398
|
+
folderName: "",
|
|
399
|
+
url: "",
|
|
400
|
+
hasBuild: false,
|
|
401
|
+
pluginFile: ""
|
|
402
|
+
};
|
|
403
|
+
});
|
|
404
|
+
return git.concat(npm);
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
var pluginItems = buildCombinedPluginList();
|
|
381
408
|
var cursor = 0;
|
|
382
409
|
var pcursor = 0; // plugin page cursor
|
|
383
410
|
var mode = "list"; // "list" | "actions" | "input" | "pactions"
|
|
@@ -662,6 +689,17 @@ function buildPluginItem(pushBody, i, pitem, nameW, cols, isSelected) {
|
|
|
662
689
|
var bg = sel ? BG_SEL : "";
|
|
663
690
|
var nameStyle = sel ? (BOLD + WHITE) : DIM;
|
|
664
691
|
|
|
692
|
+
// NPM plugins: simpler read-only row
|
|
693
|
+
if (pitem.type === "npm") {
|
|
694
|
+
var nvstr = pitem.version ? (GRAY + "v" + pitem.version + RST) : (GRAY + "not installed" + RST);
|
|
695
|
+
pushBody(" " + bg + arrow + nameStyle + pad(trunc(pitem.name, nameW), nameW) + RST + bg + " " + CYAN + "npm" + RST + " " + nvstr + RST, isSelected);
|
|
696
|
+
if (sel) {
|
|
697
|
+
var subInfo = GRAY + " managed via npm (opencode.json)" + RST;
|
|
698
|
+
pushBody(" " + subInfo, isSelected);
|
|
699
|
+
}
|
|
700
|
+
return;
|
|
701
|
+
}
|
|
702
|
+
|
|
665
703
|
var statusParts = [];
|
|
666
704
|
if (!pitem.enabled) {
|
|
667
705
|
statusParts.push(RED + "disabled" + RST);
|
|
@@ -745,34 +783,33 @@ function buildPlugins(pushBody, pushFoot, cols, barW) {
|
|
|
745
783
|
|
|
746
784
|
var autoCount = 0, manualCount = 0, updateCount = 0, disabledCount = 0;
|
|
747
785
|
for (var p of pluginItems) {
|
|
786
|
+
if (p.type === "npm") continue;
|
|
748
787
|
if (!p.enabled) disabledCount++;
|
|
749
788
|
else if (p.autoUpdate) autoCount++; else manualCount++;
|
|
750
789
|
if (p.updateAvail) updateCount++;
|
|
751
790
|
}
|
|
752
791
|
|
|
792
|
+
var npmCount = pluginItems.filter(function(p) { return p.type === "npm"; }).length;
|
|
753
793
|
pushBody(" " + MAGENTA + "#" + GRAY + " Plugins " +
|
|
754
794
|
DIM + "(" + autoCount + " auto, " + manualCount + " manual" +
|
|
755
795
|
(disabledCount > 0 ? ", " + RED + disabledCount + " disabled" + DIM : "") +
|
|
756
796
|
(updateCount > 0 ? ", " + CYAN + updateCount + " updates" + DIM : "") +
|
|
757
|
-
(
|
|
797
|
+
(npmCount > 0 ? ", " + GRAY + npmCount + " npm" + DIM : "") +
|
|
758
798
|
")" + RST, false);
|
|
759
799
|
|
|
760
800
|
if (!pluginFetched) {
|
|
761
801
|
pushBody(" " + GRAY + " Press " + RST + "F" + GRAY + " to check for updates" + RST, false);
|
|
762
802
|
}
|
|
763
803
|
|
|
804
|
+
var lastWasGit = false;
|
|
764
805
|
for (var i = 0; i < pluginItems.length; i++) {
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
pushBody(" " + MAGENTA + "#" + GRAY + " npm plugins" + RST, false);
|
|
771
|
-
for (var ni = 0; ni < npmPluginItems.length; ni++) {
|
|
772
|
-
var np = npmPluginItems[ni];
|
|
773
|
-
var nvstr = np.version ? (GRAY + "v" + np.version + RST) : (GRAY + "not installed" + RST);
|
|
774
|
-
pushBody(" " + DIM + np.name + RST + " " + nvstr, false);
|
|
806
|
+
var pitem = pluginItems[i];
|
|
807
|
+
// Insert a section header when transitioning to npm plugins
|
|
808
|
+
if (pitem.type === "npm" && (i === 0 || pluginItems[i - 1].type !== "npm")) {
|
|
809
|
+
pushBody("", false);
|
|
810
|
+
pushBody(" " + MAGENTA + "#" + GRAY + " npm plugins" + RST, false);
|
|
775
811
|
}
|
|
812
|
+
buildPluginItem(pushBody, i, pitem, nameW, cols, i === pcursor);
|
|
776
813
|
}
|
|
777
814
|
|
|
778
815
|
pushBody("", false);
|
|
@@ -823,7 +860,7 @@ function render() {
|
|
|
823
860
|
pushHead("");
|
|
824
861
|
pushHead(" " + BOLD + CYAN + " OpenCode" + RST + GRAY + " Launcher" + RST);
|
|
825
862
|
pushHead(" " + GRAY + "-".repeat(barW) + RST);
|
|
826
|
-
var showPluginsTab = pluginItems.length > 0
|
|
863
|
+
var showPluginsTab = pluginItems.length > 0;
|
|
827
864
|
var projTab = page === "projects" ? (BOLD + WHITE + BG_SEL + " Projects " + RST) : (GRAY + " Projects " + RST);
|
|
828
865
|
var plugTab = showPluginsTab ? (page === "plugins" ? (BOLD + WHITE + BG_SEL + " Plugins " + RST) : (GRAY + " Plugins " + RST)) : "";
|
|
829
866
|
pushHead(" " + projTab + (showPluginsTab ? " " + plugTab + " " + DIM + "<- ->" + RST : ""));
|
|
@@ -948,7 +985,8 @@ function handlePluginKey(key) {
|
|
|
948
985
|
if (key === "up" || key === "w") { pcursor = Math.max(0, pcursor - 1); }
|
|
949
986
|
else if (key === "down" || key === "s") { pcursor = Math.min(pluginItems.length - 1, pcursor + 1); }
|
|
950
987
|
else if (key === "enter" || key === "space") {
|
|
951
|
-
if (pluginItems.length > 0) { mode = "pactions"; pacursor = 0; }
|
|
988
|
+
if (pluginItems.length > 0 && pluginItems[pcursor].type !== "npm") { mode = "pactions"; pacursor = 0; }
|
|
989
|
+
else if (pluginItems.length > 0 && pluginItems[pcursor].type === "npm") { flash(pluginItems[pcursor].name + " is managed via npm"); }
|
|
952
990
|
}
|
|
953
991
|
else if (key === "f") {
|
|
954
992
|
flash("Fetching remotes...");
|
|
@@ -960,7 +998,7 @@ function handlePluginKey(key) {
|
|
|
960
998
|
flash(updateCount > 0 ? updateCount + " update(s) available" : "All plugins up to date");
|
|
961
999
|
}
|
|
962
1000
|
else if (key === "a") {
|
|
963
|
-
var toUpdate = pluginItems.filter(function(p) { return p.updateAvail || !p.deployed; });
|
|
1001
|
+
var toUpdate = pluginItems.filter(function(p) { return p.type !== "npm" && (p.updateAvail || !p.deployed); });
|
|
964
1002
|
if (toUpdate.length === 0) {
|
|
965
1003
|
flash("All plugins are already up to date.");
|
|
966
1004
|
} else {
|
|
@@ -971,31 +1009,31 @@ function handlePluginKey(key) {
|
|
|
971
1009
|
var e = runPluginUpdate(pi);
|
|
972
1010
|
if (e) errors.push(pi.name + ": " + e);
|
|
973
1011
|
}
|
|
974
|
-
pluginItems =
|
|
1012
|
+
pluginItems = buildCombinedPluginList();
|
|
975
1013
|
if (pcursor >= pluginItems.length) pcursor = Math.max(0, pluginItems.length - 1);
|
|
976
1014
|
flash(errors.length > 0 ? errors.join("; ") : toUpdate.length + " plugin(s) updated. Restart OpenCode to apply.");
|
|
977
1015
|
}
|
|
978
1016
|
}
|
|
979
1017
|
else if (key === "u") {
|
|
980
|
-
if (pluginItems.length > 0) {
|
|
1018
|
+
if (pluginItems.length > 0 && pluginItems[pcursor].type !== "npm") {
|
|
981
1019
|
var p = pluginItems[pcursor];
|
|
982
1020
|
flash("Updating " + p.name + "...");
|
|
983
1021
|
render();
|
|
984
1022
|
var err = runPluginUpdate(p);
|
|
985
|
-
pluginItems =
|
|
1023
|
+
pluginItems = buildCombinedPluginList();
|
|
986
1024
|
if (pcursor >= pluginItems.length) pcursor = Math.max(0, pluginItems.length - 1);
|
|
987
1025
|
flash(err ? p.name + ": " + err : p.name + " updated. Restart OpenCode to apply.");
|
|
988
1026
|
}
|
|
989
1027
|
}
|
|
990
1028
|
else if (key === "d") {
|
|
991
|
-
if (pluginItems.length > 0) {
|
|
1029
|
+
if (pluginItems.length > 0 && pluginItems[pcursor].type !== "npm") {
|
|
992
1030
|
var p = pluginItems[pcursor];
|
|
993
1031
|
var plugins = loadPlugins();
|
|
994
1032
|
var match = plugins.find(function(r) { return r.name === p.name; });
|
|
995
1033
|
if (match) { match.enabled = false; savePlugins(plugins); }
|
|
996
1034
|
var deployedPath = join(PLUGINS_DIR, p.pluginFile);
|
|
997
1035
|
if (existsSync(deployedPath)) { try { unlinkSync(deployedPath); } catch {} }
|
|
998
|
-
pluginItems =
|
|
1036
|
+
pluginItems = buildCombinedPluginList();
|
|
999
1037
|
if (pcursor >= pluginItems.length) pcursor = Math.max(0, pluginItems.length - 1);
|
|
1000
1038
|
flash(p.name + " disabled. Restart OpenCode to unload.");
|
|
1001
1039
|
}
|
|
@@ -1012,7 +1050,7 @@ function handlePluginKey(key) {
|
|
|
1012
1050
|
flash("Updating " + pitem.name + "...");
|
|
1013
1051
|
render();
|
|
1014
1052
|
var err = runPluginUpdate(pitem);
|
|
1015
|
-
pluginItems =
|
|
1053
|
+
pluginItems = buildCombinedPluginList();
|
|
1016
1054
|
if (pcursor >= pluginItems.length) pcursor = Math.max(0, pluginItems.length - 1);
|
|
1017
1055
|
flash(err ? pitem.name + ": " + err : pitem.name + " updated. Restart OpenCode to apply.");
|
|
1018
1056
|
mode = "list";
|
|
@@ -1032,7 +1070,7 @@ function handlePluginKey(key) {
|
|
|
1032
1070
|
if (match) { match.enabled = false; savePlugins(plugins); }
|
|
1033
1071
|
var deployedPath = join(PLUGINS_DIR, pitem.pluginFile);
|
|
1034
1072
|
if (existsSync(deployedPath)) { try { unlinkSync(deployedPath); } catch {} }
|
|
1035
|
-
pluginItems =
|
|
1073
|
+
pluginItems = buildCombinedPluginList();
|
|
1036
1074
|
if (pcursor >= pluginItems.length) pcursor = Math.max(0, pluginItems.length - 1);
|
|
1037
1075
|
flash(pitem.name + " disabled. Restart OpenCode to unload.");
|
|
1038
1076
|
mode = "list";
|
|
@@ -1041,7 +1079,7 @@ function handlePluginKey(key) {
|
|
|
1041
1079
|
var plugins = loadPlugins();
|
|
1042
1080
|
var match = plugins.find(function(r) { return r.name === pitem.name; });
|
|
1043
1081
|
if (match) { delete match.enabled; savePlugins(plugins); }
|
|
1044
|
-
pluginItems =
|
|
1082
|
+
pluginItems = buildCombinedPluginList();
|
|
1045
1083
|
if (pcursor >= pluginItems.length) pcursor = Math.max(0, pluginItems.length - 1);
|
|
1046
1084
|
flash(pitem.name + " enabled. Use Update to deploy.");
|
|
1047
1085
|
mode = "list";
|
|
@@ -1111,7 +1149,7 @@ function handlePluginKey(key) {
|
|
|
1111
1149
|
err = "Build output not found";
|
|
1112
1150
|
}
|
|
1113
1151
|
}
|
|
1114
|
-
pluginItems =
|
|
1152
|
+
pluginItems = buildCombinedPluginList();
|
|
1115
1153
|
if (err) flash("Error: " + err);
|
|
1116
1154
|
else flash("Downgraded to " + citem.hash.substring(0,7));
|
|
1117
1155
|
mode = "list";
|
package/package.json
CHANGED
|
@@ -1,29 +1,29 @@
|
|
|
1
1
|
{
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
2
|
+
"name": "opencode-hub",
|
|
3
|
+
"version": "1.0.14",
|
|
4
|
+
"description": "TUI launcher for OpenCode - project switcher and plugin manager with oc command",
|
|
5
|
+
"main": "plugin.js",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"license": "MIT",
|
|
8
|
+
"author": "intisy",
|
|
9
|
+
"repository": {
|
|
10
|
+
"type": "git",
|
|
11
|
+
"url": "git+https://github.com/intisy/opencode-hub.git"
|
|
12
|
+
},
|
|
13
|
+
"homepage": "https://github.com/intisy/opencode-hub#readme",
|
|
14
|
+
"keywords": [
|
|
15
|
+
"opencode",
|
|
16
|
+
"launcher",
|
|
17
|
+
"tui",
|
|
18
|
+
"project-switcher",
|
|
19
|
+
"plugin"
|
|
20
|
+
],
|
|
21
|
+
"engines": {
|
|
22
|
+
"node": ">=20.0.0"
|
|
23
|
+
},
|
|
24
|
+
"files": [
|
|
25
|
+
"plugin.js",
|
|
26
|
+
"oc-tui.js",
|
|
27
|
+
"README.md"
|
|
28
|
+
]
|
|
29
29
|
}
|