opencode-hub 1.0.13 → 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.
Files changed (2) hide show
  1. package/oc-tui.js +64 -27
  2. package/package.json +1 -1
package/oc-tui.js CHANGED
@@ -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,9 +376,35 @@ function showCur() { process.stderr.write(E + "?25h"); }
376
376
  // ---------------------------------------------------------------------------
377
377
 
378
378
  var items = buildList();
379
- var pluginItems = buildPluginList();
380
-
381
- var npmPluginItems = loadNpmPlugins();
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();
382
408
  var cursor = 0;
383
409
  var pcursor = 0; // plugin page cursor
384
410
  var mode = "list"; // "list" | "actions" | "input" | "pactions"
@@ -663,6 +689,17 @@ function buildPluginItem(pushBody, i, pitem, nameW, cols, isSelected) {
663
689
  var bg = sel ? BG_SEL : "";
664
690
  var nameStyle = sel ? (BOLD + WHITE) : DIM;
665
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
+
666
703
  var statusParts = [];
667
704
  if (!pitem.enabled) {
668
705
  statusParts.push(RED + "disabled" + RST);
@@ -746,34 +783,33 @@ function buildPlugins(pushBody, pushFoot, cols, barW) {
746
783
 
747
784
  var autoCount = 0, manualCount = 0, updateCount = 0, disabledCount = 0;
748
785
  for (var p of pluginItems) {
786
+ if (p.type === "npm") continue;
749
787
  if (!p.enabled) disabledCount++;
750
788
  else if (p.autoUpdate) autoCount++; else manualCount++;
751
789
  if (p.updateAvail) updateCount++;
752
790
  }
753
791
 
792
+ var npmCount = pluginItems.filter(function(p) { return p.type === "npm"; }).length;
754
793
  pushBody(" " + MAGENTA + "#" + GRAY + " Plugins " +
755
794
  DIM + "(" + autoCount + " auto, " + manualCount + " manual" +
756
795
  (disabledCount > 0 ? ", " + RED + disabledCount + " disabled" + DIM : "") +
757
796
  (updateCount > 0 ? ", " + CYAN + updateCount + " updates" + DIM : "") +
758
- (npmPluginItems.length > 0 ? ", " + GRAY + npmPluginItems.length + " npm" + DIM : "") +
797
+ (npmCount > 0 ? ", " + GRAY + npmCount + " npm" + DIM : "") +
759
798
  ")" + RST, false);
760
799
 
761
800
  if (!pluginFetched) {
762
801
  pushBody(" " + GRAY + " Press " + RST + "F" + GRAY + " to check for updates" + RST, false);
763
802
  }
764
803
 
804
+ var lastWasGit = false;
765
805
  for (var i = 0; i < pluginItems.length; i++) {
766
- buildPluginItem(pushBody, i, pluginItems[i], nameW, cols, i === pcursor);
767
- }
768
-
769
- if (npmPluginItems.length > 0) {
770
- pushBody("", false);
771
- pushBody(" " + MAGENTA + "#" + GRAY + " npm plugins" + RST, false);
772
- for (var ni = 0; ni < npmPluginItems.length; ni++) {
773
- var np = npmPluginItems[ni];
774
- var nvstr = np.version ? (GRAY + "v" + np.version + RST) : (GRAY + "not installed" + RST);
775
- 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);
776
811
  }
812
+ buildPluginItem(pushBody, i, pitem, nameW, cols, i === pcursor);
777
813
  }
778
814
 
779
815
  pushBody("", false);
@@ -824,7 +860,7 @@ function render() {
824
860
  pushHead("");
825
861
  pushHead(" " + BOLD + CYAN + " OpenCode" + RST + GRAY + " Launcher" + RST);
826
862
  pushHead(" " + GRAY + "-".repeat(barW) + RST);
827
- var showPluginsTab = pluginItems.length > 0 || npmPluginItems.length > 0;
863
+ var showPluginsTab = pluginItems.length > 0;
828
864
  var projTab = page === "projects" ? (BOLD + WHITE + BG_SEL + " Projects " + RST) : (GRAY + " Projects " + RST);
829
865
  var plugTab = showPluginsTab ? (page === "plugins" ? (BOLD + WHITE + BG_SEL + " Plugins " + RST) : (GRAY + " Plugins " + RST)) : "";
830
866
  pushHead(" " + projTab + (showPluginsTab ? " " + plugTab + " " + DIM + "<- ->" + RST : ""));
@@ -949,7 +985,8 @@ function handlePluginKey(key) {
949
985
  if (key === "up" || key === "w") { pcursor = Math.max(0, pcursor - 1); }
950
986
  else if (key === "down" || key === "s") { pcursor = Math.min(pluginItems.length - 1, pcursor + 1); }
951
987
  else if (key === "enter" || key === "space") {
952
- 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"); }
953
990
  }
954
991
  else if (key === "f") {
955
992
  flash("Fetching remotes...");
@@ -961,7 +998,7 @@ function handlePluginKey(key) {
961
998
  flash(updateCount > 0 ? updateCount + " update(s) available" : "All plugins up to date");
962
999
  }
963
1000
  else if (key === "a") {
964
- 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); });
965
1002
  if (toUpdate.length === 0) {
966
1003
  flash("All plugins are already up to date.");
967
1004
  } else {
@@ -972,31 +1009,31 @@ function handlePluginKey(key) {
972
1009
  var e = runPluginUpdate(pi);
973
1010
  if (e) errors.push(pi.name + ": " + e);
974
1011
  }
975
- pluginItems = buildPluginList();
1012
+ pluginItems = buildCombinedPluginList();
976
1013
  if (pcursor >= pluginItems.length) pcursor = Math.max(0, pluginItems.length - 1);
977
1014
  flash(errors.length > 0 ? errors.join("; ") : toUpdate.length + " plugin(s) updated. Restart OpenCode to apply.");
978
1015
  }
979
1016
  }
980
1017
  else if (key === "u") {
981
- if (pluginItems.length > 0) {
1018
+ if (pluginItems.length > 0 && pluginItems[pcursor].type !== "npm") {
982
1019
  var p = pluginItems[pcursor];
983
1020
  flash("Updating " + p.name + "...");
984
1021
  render();
985
1022
  var err = runPluginUpdate(p);
986
- pluginItems = buildPluginList();
1023
+ pluginItems = buildCombinedPluginList();
987
1024
  if (pcursor >= pluginItems.length) pcursor = Math.max(0, pluginItems.length - 1);
988
1025
  flash(err ? p.name + ": " + err : p.name + " updated. Restart OpenCode to apply.");
989
1026
  }
990
1027
  }
991
1028
  else if (key === "d") {
992
- if (pluginItems.length > 0) {
1029
+ if (pluginItems.length > 0 && pluginItems[pcursor].type !== "npm") {
993
1030
  var p = pluginItems[pcursor];
994
1031
  var plugins = loadPlugins();
995
1032
  var match = plugins.find(function(r) { return r.name === p.name; });
996
1033
  if (match) { match.enabled = false; savePlugins(plugins); }
997
1034
  var deployedPath = join(PLUGINS_DIR, p.pluginFile);
998
1035
  if (existsSync(deployedPath)) { try { unlinkSync(deployedPath); } catch {} }
999
- pluginItems = buildPluginList();
1036
+ pluginItems = buildCombinedPluginList();
1000
1037
  if (pcursor >= pluginItems.length) pcursor = Math.max(0, pluginItems.length - 1);
1001
1038
  flash(p.name + " disabled. Restart OpenCode to unload.");
1002
1039
  }
@@ -1013,7 +1050,7 @@ function handlePluginKey(key) {
1013
1050
  flash("Updating " + pitem.name + "...");
1014
1051
  render();
1015
1052
  var err = runPluginUpdate(pitem);
1016
- pluginItems = buildPluginList();
1053
+ pluginItems = buildCombinedPluginList();
1017
1054
  if (pcursor >= pluginItems.length) pcursor = Math.max(0, pluginItems.length - 1);
1018
1055
  flash(err ? pitem.name + ": " + err : pitem.name + " updated. Restart OpenCode to apply.");
1019
1056
  mode = "list";
@@ -1033,7 +1070,7 @@ function handlePluginKey(key) {
1033
1070
  if (match) { match.enabled = false; savePlugins(plugins); }
1034
1071
  var deployedPath = join(PLUGINS_DIR, pitem.pluginFile);
1035
1072
  if (existsSync(deployedPath)) { try { unlinkSync(deployedPath); } catch {} }
1036
- pluginItems = buildPluginList();
1073
+ pluginItems = buildCombinedPluginList();
1037
1074
  if (pcursor >= pluginItems.length) pcursor = Math.max(0, pluginItems.length - 1);
1038
1075
  flash(pitem.name + " disabled. Restart OpenCode to unload.");
1039
1076
  mode = "list";
@@ -1042,7 +1079,7 @@ function handlePluginKey(key) {
1042
1079
  var plugins = loadPlugins();
1043
1080
  var match = plugins.find(function(r) { return r.name === pitem.name; });
1044
1081
  if (match) { delete match.enabled; savePlugins(plugins); }
1045
- pluginItems = buildPluginList();
1082
+ pluginItems = buildCombinedPluginList();
1046
1083
  if (pcursor >= pluginItems.length) pcursor = Math.max(0, pluginItems.length - 1);
1047
1084
  flash(pitem.name + " enabled. Use Update to deploy.");
1048
1085
  mode = "list";
@@ -1112,7 +1149,7 @@ function handlePluginKey(key) {
1112
1149
  err = "Build output not found";
1113
1150
  }
1114
1151
  }
1115
- pluginItems = buildPluginList();
1152
+ pluginItems = buildCombinedPluginList();
1116
1153
  if (err) flash("Error: " + err);
1117
1154
  else flash("Downgraded to " + citem.hash.substring(0,7));
1118
1155
  mode = "list";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "opencode-hub",
3
- "version": "1.0.13",
3
+ "version": "1.0.14",
4
4
  "description": "TUI launcher for OpenCode - project switcher and plugin manager with oc command",
5
5
  "main": "plugin.js",
6
6
  "type": "module",