@node9/proxy 1.35.2 → 1.36.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/cli.js +67 -19
  2. package/dist/cli.mjs +67 -19
  3. package/package.json +1 -1
package/dist/cli.js CHANGED
@@ -19968,6 +19968,7 @@ var import_fs38 = __toESM(require("fs"));
19968
19968
  var import_path39 = __toESM(require("path"));
19969
19969
  var import_os34 = __toESM(require("os"));
19970
19970
  var yaml2 = __toESM(require("yaml"));
19971
+ var import_smol_toml2 = require("smol-toml");
19971
19972
  init_setup();
19972
19973
  function readJson2(filePath) {
19973
19974
  if (!import_fs38.default.existsSync(filePath)) return null;
@@ -20003,15 +20004,26 @@ function eventWired(root, ev, format) {
20003
20004
  if (format === "matcher") return matchersHaveNode9Hook(arr);
20004
20005
  return flatHaveNode9Hook(arr);
20005
20006
  }
20006
- function readMcp(filePath) {
20007
- const parsed = readJson2(filePath);
20008
- if (parsed === null || parsed === "invalid") return { wrapped: [], present: false };
20009
- const servers = parsed.mcpServers ?? {};
20010
- const entries = Object.entries(servers);
20007
+ function detectMcp(servers) {
20008
+ const entries = Object.entries(servers ?? {});
20011
20009
  const present = entries.some(([, s]) => s?.command === "node9");
20012
20010
  const wrapped = entries.filter(([, s]) => s?.command === "node9" && Array.isArray(s.args) && s.args.length > 0).map(([name, s]) => `${name} \u2192 ${s.args.join(" ")}`);
20013
20011
  return { wrapped, present };
20014
20012
  }
20013
+ function readMcp(filePath, format) {
20014
+ if (!import_fs38.default.existsSync(filePath)) return { wrapped: [], present: false };
20015
+ try {
20016
+ if (format === "toml") {
20017
+ const parsed2 = (0, import_smol_toml2.parse)(import_fs38.default.readFileSync(filePath, "utf-8"));
20018
+ return detectMcp(parsed2?.mcp_servers);
20019
+ }
20020
+ const parsed = readJson2(filePath);
20021
+ if (parsed === null || parsed === "invalid") return { wrapped: [], present: false };
20022
+ return detectMcp(parsed.mcpServers);
20023
+ } catch {
20024
+ return { wrapped: [], present: false };
20025
+ }
20026
+ }
20015
20027
  var exists = (p) => {
20016
20028
  try {
20017
20029
  return import_fs38.default.existsSync(p);
@@ -20051,6 +20063,8 @@ var AGENT_SPECS = [
20051
20063
  hookFile: (h) => import_path39.default.join(h, ".codex", "hooks.json"),
20052
20064
  hookFormat: "matcher",
20053
20065
  hookEvents: [ck("PreToolUse"), ck("UserPromptSubmit")],
20066
+ mcpFile: (h) => import_path39.default.join(h, ".codex", "config.toml"),
20067
+ mcpFormat: "toml",
20054
20068
  present: (h) => exists(import_path39.default.join(h, ".codex"))
20055
20069
  },
20056
20070
  {
@@ -20093,35 +20107,69 @@ var AGENT_SPECS = [
20093
20107
  labelPad: 14,
20094
20108
  // 'post_tool_call' is wider than the default
20095
20109
  present: (h) => exists(hermesConfigPath(h))
20110
+ },
20111
+ {
20112
+ // Plugin-shim agents — protected by a node9-authored plugin/extension file
20113
+ // (no hooks, no MCP). hookFormat is unused for these (shimFile drives it).
20114
+ id: "opencode",
20115
+ label: "OpenCode",
20116
+ setupCommand: "node9 setup opencode",
20117
+ hookFormat: "flat",
20118
+ hookEvents: [],
20119
+ shimFile: (h) => import_path39.default.join(h, ".config", "opencode", "plugins", "node9.js"),
20120
+ present: (h) => exists(import_path39.default.join(h, ".config", "opencode")) || exists(import_path39.default.join(h, ".config", "opencode", "plugins", "node9.js"))
20121
+ },
20122
+ {
20123
+ id: "pi",
20124
+ label: "Pi",
20125
+ setupCommand: "node9 setup pi",
20126
+ hookFormat: "flat",
20127
+ hookEvents: [],
20128
+ shimFile: (h) => import_path39.default.join(h, ".pi", "agent", "extensions", "node9.js"),
20129
+ present: (h) => exists(import_path39.default.join(h, ".pi", "agent")) || exists(import_path39.default.join(h, ".pi", "agent", "extensions", "node9.js"))
20096
20130
  }
20097
20131
  ];
20098
20132
  function getAgentWiring(home = import_os34.default.homedir()) {
20099
20133
  const detected = detectAgents(home);
20100
20134
  return AGENT_SPECS.map((spec) => {
20101
- const root = spec.hookFile ? readHookRoot(spec.hookFile(home), spec.hookFormat) : "absent";
20102
- const primary = spec.hookEvents[0];
20103
- const rootPresent = root !== "absent" && root !== "invalid";
20135
+ const present = spec.present(home);
20104
20136
  const pad = spec.labelPad ?? DEFAULT_LABEL_PAD;
20105
- const hooks = spec.hookEvents.map((ev) => ({
20106
- label: hookLabelOf(ev, pad),
20107
- wired: rootPresent && eventWired(root, ev, spec.hookFormat)
20108
- }));
20137
+ let hooks;
20109
20138
  let wireState;
20110
- if (root === "absent") wireState = "absent";
20111
- else if (root === "invalid") wireState = "invalid";
20112
- else wireState = primary && eventWired(root, primary, spec.hookFormat) ? "wired" : "unwired";
20113
- const mcp = spec.mcpFile ? readMcp(spec.mcpFile(home)) : null;
20139
+ let hookLabel;
20140
+ let settingsPath;
20141
+ if (spec.shimFile) {
20142
+ const shimWired = exists(spec.shimFile(home));
20143
+ hooks = [{ label: "node9 plugin (node9 check)", wired: shimWired }];
20144
+ wireState = shimWired ? "wired" : present ? "unwired" : "absent";
20145
+ hookLabel = "node9 plugin";
20146
+ settingsPath = spec.shimFile(home);
20147
+ } else {
20148
+ const root = spec.hookFile ? readHookRoot(spec.hookFile(home), spec.hookFormat) : "absent";
20149
+ const primary = spec.hookEvents[0];
20150
+ const rootPresent = root !== "absent" && root !== "invalid";
20151
+ hooks = spec.hookEvents.map((ev) => ({
20152
+ label: hookLabelOf(ev, pad),
20153
+ wired: rootPresent && eventWired(root, ev, spec.hookFormat)
20154
+ }));
20155
+ if (root === "absent") wireState = "absent";
20156
+ else if (root === "invalid") wireState = "invalid";
20157
+ else wireState = primary && eventWired(root, primary, spec.hookFormat) ? "wired" : "unwired";
20158
+ hookLabel = primary ? `${primary.key} hook` : "MCP proxy";
20159
+ settingsPath = spec.hookFile ? spec.hookFile(home) : spec.mcpFile ? spec.mcpFile(home) : "";
20160
+ }
20161
+ const mcp = spec.mcpFile ? readMcp(spec.mcpFile(home), spec.mcpFormat ?? "json") : null;
20114
20162
  const anyHookWired = hooks.some((h) => h.wired);
20115
20163
  return {
20116
20164
  id: spec.id,
20117
20165
  label: spec.label,
20118
20166
  setupCommand: spec.setupCommand,
20119
20167
  installed: detected[spec.id],
20120
- present: spec.present(home),
20168
+ present,
20121
20169
  hooks,
20122
20170
  wireState,
20123
- hookLabel: primary ? `${primary.key} hook` : "MCP proxy",
20124
- settingsPath: spec.hookFile ? spec.hookFile(home) : spec.mcpFile ? spec.mcpFile(home) : "",
20171
+ hookLabel,
20172
+ settingsPath,
20125
20173
  configFormat: spec.hookFormat === "yaml" ? "YAML" : "JSON",
20126
20174
  mcpServers: mcp ? mcp.wrapped : null,
20127
20175
  mcpProtected: mcp ? mcp.present : false,
package/dist/cli.mjs CHANGED
@@ -19941,6 +19941,7 @@ import fs38 from "fs";
19941
19941
  import path39 from "path";
19942
19942
  import os34 from "os";
19943
19943
  import * as yaml2 from "yaml";
19944
+ import { parse as parseToml2 } from "smol-toml";
19944
19945
  function readJson2(filePath) {
19945
19946
  if (!fs38.existsSync(filePath)) return null;
19946
19947
  try {
@@ -19975,15 +19976,26 @@ function eventWired(root, ev, format) {
19975
19976
  if (format === "matcher") return matchersHaveNode9Hook(arr);
19976
19977
  return flatHaveNode9Hook(arr);
19977
19978
  }
19978
- function readMcp(filePath) {
19979
- const parsed = readJson2(filePath);
19980
- if (parsed === null || parsed === "invalid") return { wrapped: [], present: false };
19981
- const servers = parsed.mcpServers ?? {};
19982
- const entries = Object.entries(servers);
19979
+ function detectMcp(servers) {
19980
+ const entries = Object.entries(servers ?? {});
19983
19981
  const present = entries.some(([, s]) => s?.command === "node9");
19984
19982
  const wrapped = entries.filter(([, s]) => s?.command === "node9" && Array.isArray(s.args) && s.args.length > 0).map(([name, s]) => `${name} \u2192 ${s.args.join(" ")}`);
19985
19983
  return { wrapped, present };
19986
19984
  }
19985
+ function readMcp(filePath, format) {
19986
+ if (!fs38.existsSync(filePath)) return { wrapped: [], present: false };
19987
+ try {
19988
+ if (format === "toml") {
19989
+ const parsed2 = parseToml2(fs38.readFileSync(filePath, "utf-8"));
19990
+ return detectMcp(parsed2?.mcp_servers);
19991
+ }
19992
+ const parsed = readJson2(filePath);
19993
+ if (parsed === null || parsed === "invalid") return { wrapped: [], present: false };
19994
+ return detectMcp(parsed.mcpServers);
19995
+ } catch {
19996
+ return { wrapped: [], present: false };
19997
+ }
19998
+ }
19987
19999
  var exists = (p) => {
19988
20000
  try {
19989
20001
  return fs38.existsSync(p);
@@ -20023,6 +20035,8 @@ var AGENT_SPECS = [
20023
20035
  hookFile: (h) => path39.join(h, ".codex", "hooks.json"),
20024
20036
  hookFormat: "matcher",
20025
20037
  hookEvents: [ck("PreToolUse"), ck("UserPromptSubmit")],
20038
+ mcpFile: (h) => path39.join(h, ".codex", "config.toml"),
20039
+ mcpFormat: "toml",
20026
20040
  present: (h) => exists(path39.join(h, ".codex"))
20027
20041
  },
20028
20042
  {
@@ -20065,35 +20079,69 @@ var AGENT_SPECS = [
20065
20079
  labelPad: 14,
20066
20080
  // 'post_tool_call' is wider than the default
20067
20081
  present: (h) => exists(hermesConfigPath(h))
20082
+ },
20083
+ {
20084
+ // Plugin-shim agents — protected by a node9-authored plugin/extension file
20085
+ // (no hooks, no MCP). hookFormat is unused for these (shimFile drives it).
20086
+ id: "opencode",
20087
+ label: "OpenCode",
20088
+ setupCommand: "node9 setup opencode",
20089
+ hookFormat: "flat",
20090
+ hookEvents: [],
20091
+ shimFile: (h) => path39.join(h, ".config", "opencode", "plugins", "node9.js"),
20092
+ present: (h) => exists(path39.join(h, ".config", "opencode")) || exists(path39.join(h, ".config", "opencode", "plugins", "node9.js"))
20093
+ },
20094
+ {
20095
+ id: "pi",
20096
+ label: "Pi",
20097
+ setupCommand: "node9 setup pi",
20098
+ hookFormat: "flat",
20099
+ hookEvents: [],
20100
+ shimFile: (h) => path39.join(h, ".pi", "agent", "extensions", "node9.js"),
20101
+ present: (h) => exists(path39.join(h, ".pi", "agent")) || exists(path39.join(h, ".pi", "agent", "extensions", "node9.js"))
20068
20102
  }
20069
20103
  ];
20070
20104
  function getAgentWiring(home = os34.homedir()) {
20071
20105
  const detected = detectAgents(home);
20072
20106
  return AGENT_SPECS.map((spec) => {
20073
- const root = spec.hookFile ? readHookRoot(spec.hookFile(home), spec.hookFormat) : "absent";
20074
- const primary = spec.hookEvents[0];
20075
- const rootPresent = root !== "absent" && root !== "invalid";
20107
+ const present = spec.present(home);
20076
20108
  const pad = spec.labelPad ?? DEFAULT_LABEL_PAD;
20077
- const hooks = spec.hookEvents.map((ev) => ({
20078
- label: hookLabelOf(ev, pad),
20079
- wired: rootPresent && eventWired(root, ev, spec.hookFormat)
20080
- }));
20109
+ let hooks;
20081
20110
  let wireState;
20082
- if (root === "absent") wireState = "absent";
20083
- else if (root === "invalid") wireState = "invalid";
20084
- else wireState = primary && eventWired(root, primary, spec.hookFormat) ? "wired" : "unwired";
20085
- const mcp = spec.mcpFile ? readMcp(spec.mcpFile(home)) : null;
20111
+ let hookLabel;
20112
+ let settingsPath;
20113
+ if (spec.shimFile) {
20114
+ const shimWired = exists(spec.shimFile(home));
20115
+ hooks = [{ label: "node9 plugin (node9 check)", wired: shimWired }];
20116
+ wireState = shimWired ? "wired" : present ? "unwired" : "absent";
20117
+ hookLabel = "node9 plugin";
20118
+ settingsPath = spec.shimFile(home);
20119
+ } else {
20120
+ const root = spec.hookFile ? readHookRoot(spec.hookFile(home), spec.hookFormat) : "absent";
20121
+ const primary = spec.hookEvents[0];
20122
+ const rootPresent = root !== "absent" && root !== "invalid";
20123
+ hooks = spec.hookEvents.map((ev) => ({
20124
+ label: hookLabelOf(ev, pad),
20125
+ wired: rootPresent && eventWired(root, ev, spec.hookFormat)
20126
+ }));
20127
+ if (root === "absent") wireState = "absent";
20128
+ else if (root === "invalid") wireState = "invalid";
20129
+ else wireState = primary && eventWired(root, primary, spec.hookFormat) ? "wired" : "unwired";
20130
+ hookLabel = primary ? `${primary.key} hook` : "MCP proxy";
20131
+ settingsPath = spec.hookFile ? spec.hookFile(home) : spec.mcpFile ? spec.mcpFile(home) : "";
20132
+ }
20133
+ const mcp = spec.mcpFile ? readMcp(spec.mcpFile(home), spec.mcpFormat ?? "json") : null;
20086
20134
  const anyHookWired = hooks.some((h) => h.wired);
20087
20135
  return {
20088
20136
  id: spec.id,
20089
20137
  label: spec.label,
20090
20138
  setupCommand: spec.setupCommand,
20091
20139
  installed: detected[spec.id],
20092
- present: spec.present(home),
20140
+ present,
20093
20141
  hooks,
20094
20142
  wireState,
20095
- hookLabel: primary ? `${primary.key} hook` : "MCP proxy",
20096
- settingsPath: spec.hookFile ? spec.hookFile(home) : spec.mcpFile ? spec.mcpFile(home) : "",
20143
+ hookLabel,
20144
+ settingsPath,
20097
20145
  configFormat: spec.hookFormat === "yaml" ? "YAML" : "JSON",
20098
20146
  mcpServers: mcp ? mcp.wrapped : null,
20099
20147
  mcpProtected: mcp ? mcp.present : false,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@node9/proxy",
3
- "version": "1.35.2",
3
+ "version": "1.36.0",
4
4
  "description": "The Sudo Command for AI Agents. Execution Security for Claude Code, Codex, Gemini, Cursor, Opencode, Pi, and any MCP server.",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.mjs",