@aron98/load-lock 0.1.1 → 0.1.2

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/dist/cli/install.js +32 -37
  2. package/package.json +1 -1
@@ -6,10 +6,10 @@
6
6
  * package) so uninstall removes exactly what install added.
7
7
  *
8
8
  * Harnesses:
9
- * - opencode : plugin dir ~/.config/opencode/plugins/load-lock/ (stub that
10
- * re-exports the compiled plugin from this package, with a
11
- * local package.json so `@opencode/plugin` + `load-lock`
12
- * resolve), plus a `plugins` entry in opencode.json.
9
+ * - opencode : registers the published npm package in the `plugins`
10
+ * array of ~/.config/opencode/opencode.json (opencode
11
+ * resolves/installs/updates the package itself; legacy
12
+ * local-stub installs are migrated away automatically).
13
13
  * - claude-code : user-scope MCP server in ~/.claude.json, SessionStart /
14
14
  * Stop hooks + background await-offer watcher in
15
15
  * ~/.claude/settings.json, CLAUDE.md section, skill.
@@ -18,12 +18,12 @@
18
18
  * ~/.codex/AGENTS.md pointer. Trust must be granted via /hooks.
19
19
  * - generic : prints an MCP stdio config snippet (any MCP-capable harness).
20
20
  */
21
- import { spawnSync } from "node:child_process";
22
21
  import fs from "node:fs";
23
22
  import os from "node:os";
24
23
  import path from "node:path";
25
24
  import { POLICY_BRIEF } from "../policy/text.js";
26
25
  const HOME = os.homedir();
26
+ const PKG_NAME = "@aron98/load-lock";
27
27
  export function pkgRoot(binDir) {
28
28
  const d = binDir ?? path.join(import.meta.dirname ?? ".", ".."); // dist/cli -> dist
29
29
  return path.resolve(d, ".."); // dist -> package root
@@ -83,52 +83,44 @@ const LL_HOOK_TAG = "dist/cli/main.js hook"; // how we recognize our hook entrie
83
83
  function installOpenCode(opts, P) {
84
84
  const actions = [];
85
85
  const pluginDir = path.join(HOME, ".config", "opencode", "plugins", "load-lock");
86
- fs.mkdirSync(pluginDir, { recursive: true });
87
- // Stub that re-exports the compiled plugin from this package.
88
- fs.writeFileSync(path.join(pluginDir, "index.js"), `// installed by load-lock; re-exports the compiled plugin\n` +
89
- `export { default } from "@aron98/load-lock/dist/adapters/opencode/plugin.js";\n`);
90
- actions.push(`plugin stub: ${pluginDir}/index.js`);
91
- fs.writeFileSync(path.join(pluginDir, "package.json"), JSON.stringify({
92
- name: "load-lock-opencode-plugin",
93
- version: "0.1.0",
94
- type: "module",
95
- main: "index.js",
96
- dependencies: {
97
- "@opencode/plugin": "^2.0.29",
98
- "@aron98/load-lock": "file:" + P.root,
99
- },
100
- }, null, 2) + "\n");
101
- actions.push("plugin package.json (file: dep on this package)");
102
- const npmInstall = spawnSync("npm", ["install", "--no-audit", "--no-fund"], { cwd: pluginDir, encoding: "utf8" });
103
- if (npmInstall.status !== 0) {
104
- actions.push("WARNING: npm install inside plugin dir failed — see errors above");
105
- }
106
- else {
107
- actions.push("plugin dependencies installed");
86
+ // Migrate away from the legacy stub dir (pre-publish installs used a
87
+ // local stub with a file: symlink dep, which bun does not resolve).
88
+ if (fs.existsSync(pluginDir)) {
89
+ fs.rmSync(pluginDir, { recursive: true, force: true });
90
+ actions.push(`removed legacy plugin stub ${pluginDir}`);
108
91
  }
109
- // Register in ~/.config/opencode/opencode.json (merge, preserve).
92
+ // Register the published npm package; opencode resolves, installs and
93
+ // updates it itself (shows up in /plugins with the real version).
110
94
  const cfgFile = path.join(HOME, ".config", "opencode", "opencode.json");
111
95
  const cfg = readJson(cfgFile) ?? {};
112
96
  if (!Array.isArray(cfg.plugins))
113
97
  cfg.plugins = [];
114
- if (!cfg.plugins.includes(pluginDir))
115
- cfg.plugins.push(pluginDir);
98
+ const before = cfg.plugins.length;
99
+ cfg.plugins = cfg.plugins.filter((p) => p !== pluginDir && p !== PKG_NAME);
100
+ cfg.plugins.push(PKG_NAME);
116
101
  writeJson(cfgFile, cfg);
117
- actions.push(`plugins entry in ${cfgFile}`);
102
+ actions.push(`plugins entry "${PKG_NAME}" in ${cfgFile}`);
103
+ if (before !== cfg.plugins.length)
104
+ actions.push("(replaced legacy plugins entry)");
118
105
  actions.push("restart or reload your opencode service to load the plugin");
119
106
  return actions;
120
107
  }
121
108
  function uninstallOpenCode() {
122
109
  const actions = [];
123
110
  const pluginDir = path.join(HOME, ".config", "opencode", "plugins", "load-lock");
124
- fs.rmSync(pluginDir, { recursive: true, force: true });
125
- actions.push(`removed ${pluginDir}`);
111
+ if (fs.existsSync(pluginDir)) {
112
+ fs.rmSync(pluginDir, { recursive: true, force: true });
113
+ actions.push(`removed ${pluginDir}`);
114
+ }
126
115
  const cfgFile = path.join(HOME, ".config", "opencode", "opencode.json");
127
116
  const cfg = readJson(cfgFile);
128
117
  if (cfg && Array.isArray(cfg.plugins)) {
129
- cfg.plugins = cfg.plugins.filter((p) => p !== pluginDir);
130
- writeJson(cfgFile, cfg);
131
- actions.push(`removed plugins entry from ${cfgFile}`);
118
+ const before = cfg.plugins.length;
119
+ cfg.plugins = cfg.plugins.filter((p) => p !== pluginDir && p !== PKG_NAME);
120
+ if (cfg.plugins.length !== before) {
121
+ writeJson(cfgFile, cfg);
122
+ actions.push(`removed plugins entry from ${cfgFile}`);
123
+ }
132
124
  }
133
125
  return actions;
134
126
  }
@@ -262,7 +254,10 @@ function installCodex(opts, P) {
262
254
  const tomlFile = path.join(codexHome, "config.toml");
263
255
  fs.mkdirSync(codexHome, { recursive: true });
264
256
  const toml = fs.existsSync(tomlFile) ? fs.readFileSync(tomlFile, "utf8") : "";
265
- if (!toml.includes("[mcp_servers.load-lock]")) {
257
+ // 2. MCP server in config.toml (append block only if absent).
258
+ // Match only a real table header at line start - a comment or docs text
259
+ // mentioning the section must not be treated as "already installed".
260
+ if (!/^\[mcp_servers\.load-lock\]\s*$/m.test(toml)) {
266
261
  fs.writeFileSync(tomlFile, toml +
267
262
  (toml.endsWith("\n") ? "" : "\n") +
268
263
  `\n# load-lock (added by \`load-lock install\`)\n[mcp_servers.load-lock]\n` +
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aron98/load-lock",
3
- "version": "0.1.1",
3
+ "version": "0.1.2",
4
4
  "description": "Machine-wide counting semaphore coordinating resource-intensive work across parallel coding agents (OpenCode, Codex CLI, Claude Code, ...)",
5
5
  "type": "module",
6
6
  "license": "MIT",