@pushary/agent-hooks 0.88.1 → 0.89.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/CHANGELOG.md CHANGED
@@ -1,5 +1,29 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.89.0
4
+
5
+ ### Hermes approvals go to the phone, and setup wires it
6
+
7
+ `setup --agents hermes` now selects Pushary as the Hermes approval transport,
8
+ with `transport_fallback: builtin`. Hermes owns the timeout (300s) and the
9
+ once/session/always/deny choices, and persists the last two, so a repeated
10
+ approval can become a standing rule instead of being asked forever. The
11
+ fallback is what makes selecting it safe: a missing key, an unreachable
12
+ Pushary, or no connected device falls back to the terminal prompt rather than
13
+ blocking work.
14
+
15
+ The note explaining why setup writes `~/.hermes/config.yaml` directly rather
16
+ than running `hermes plugins enable` was half wrong. Current Hermes does
17
+ resolve pip-installed plugins in both `list` and `enable`; the reason to write
18
+ the file is the rule against executing an agent's binary, and nothing else.
19
+
20
+ ### `pushary upgrade` named a package that does not exist
21
+
22
+ It printed `pip install --upgrade pushary-hermes`. That package is not on PyPI.
23
+ The real one is `hermes-plugin-pushary`, and the upgrade path for it is setup,
24
+ which installs into the interpreter Hermes actually runs in. Now points there,
25
+ like every other agent in that list.
26
+
3
27
  ## 0.88.1
4
28
 
5
29
  ### One install, whichever surface writes it
@@ -807,7 +807,7 @@ var ensurePip = (python) => {
807
807
  }
808
808
  };
809
809
  var enablePusharyPlugin = (python) => {
810
- const snippet = 'from hermes_cli.config import load_config, save_config; c = load_config(); p = c.get("plugins") if isinstance(c.get("plugins"), dict) else {}; e = p.get("enabled") if isinstance(p.get("enabled"), list) else []; p["enabled"] = (e + ["pushary"]) if "pushary" not in e else e; c["plugins"] = p; a = c.get("agent") if isinstance(c.get("agent"), dict) else {}; d = a.get("disabled_toolsets") if isinstance(a.get("disabled_toolsets"), list) else []; a["disabled_toolsets"] = (d + ["clarify"]) if "clarify" not in d else d; c["agent"] = a; save_config(c)';
810
+ const snippet = 'from hermes_cli.config import load_config, save_config; c = load_config(); s = c.get("security") if isinstance(c.get("security"), dict) else {}; ap = s.get("approval") if isinstance(s.get("approval"), dict) else {}; ap["transport"] = "pushary"; ap["transport_fallback"] = "builtin"; s["approval"] = ap; c["security"] = s; p = c.get("plugins") if isinstance(c.get("plugins"), dict) else {}; e = p.get("enabled") if isinstance(p.get("enabled"), list) else []; p["enabled"] = (e + ["pushary"]) if "pushary" not in e else e; c["plugins"] = p; a = c.get("agent") if isinstance(c.get("agent"), dict) else {}; d = a.get("disabled_toolsets") if isinstance(a.get("disabled_toolsets"), list) else []; a["disabled_toolsets"] = (d + ["clarify"]) if "clarify" not in d else d; c["agent"] = a; save_config(c)';
811
811
  const scriptPath = join3(tmpdir(), `pushary-hermes-${process.pid}.py`);
812
812
  try {
813
813
  writeFileSync(scriptPath, snippet.split("; ").join("\n"), "utf-8");
@@ -847,15 +847,17 @@ var setupHermes = async (_apiKey) => {
847
847
  });
848
848
  if (!pluginEnabled) {
849
849
  console.log(` ${yellow("!")} Installed the plugin, but could not edit Hermes' config.`);
850
- noteManual('Add "pushary" to plugins.enabled in ~/.hermes/config.yaml, and "clarify" to agent.disabled_toolsets');
850
+ noteManual('Add "pushary" to plugins.enabled and set security.approval.transport to "pushary" (with transport_fallback "builtin") in ~/.hermes/config.yaml, plus "clarify" in agent.disabled_toolsets');
851
851
  }
852
852
  console.log();
853
853
  console.log(` ${dim("What this configured:")}`);
854
- console.log(` ${dim("\u2022")} Native tools: pushary_notify, pushary_ask, pushary_wait, pushary_cancel`);
854
+ console.log(` ${dim("\u2022")} Native tools: pushary_notify, pushary_ask, pushary_wait, pushary_cancel, pushary_propose_scope`);
855
+ console.log(` ${dim("\u2022")} Approvals: Hermes' dangerous-command prompts go to your phone with allow once / this session / always / deny`);
856
+ console.log(` ${dim("\u2022")} Falls back to the terminal prompt when no device is connected, so work never blocks on us`);
855
857
  console.log(` ${dim("\u2022")} Questions go to your phone: Hermes' terminal ${bold("clarify")} tool is disabled, so pushary_ask handles every question`);
856
858
  console.log(` ${dim("\u2022")} Auto-notifications: push alert when tools return errors`);
857
- console.log(` ${dim("\u2022")} Permission gating: set ${bold("PUSHARY_GATE_TOOLS")} to require lock-screen approval for risky tools`);
858
- console.log(` ${dim("To re-enable terminal prompts:")} remove ${bold("clarify")} from ${dim("agent.disabled_toolsets")} in ~/.hermes/config.yaml`);
859
+ console.log(` ${dim("To send approvals back to the terminal:")} remove ${bold("security.approval.transport")} from ~/.hermes/config.yaml`);
860
+ console.log(` ${dim("To re-enable terminal questions:")} remove ${bold("clarify")} from ${dim("agent.disabled_toolsets")}`);
859
861
  };
860
862
  var CODEX_HOOKS_JSON = join3(CODEX_HOME, "hooks.json");
861
863
  var CODEX_HOOKS_MIN_VERSION = [0, 122, 0];
@@ -238,7 +238,7 @@ var detectInstallModes = () => {
238
238
  },
239
239
  {
240
240
  label: "Hermes plugin (pip)",
241
- upgrade: "pip install --upgrade pushary-hermes",
241
+ upgrade: "npx @pushary/agent-hooks@latest setup --agents hermes",
242
242
  present: existsSync2(join2(homedir2(), ".hermes"))
243
243
  }
244
244
  ];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pushary/agent-hooks",
3
- "version": "0.88.1",
3
+ "version": "0.89.0",
4
4
  "description": "Permission hooks for AI coding agents: route tool approvals through Pushary push notifications",
5
5
  "keywords": [
6
6
  "pushary",