@pushary/agent-hooks 0.75.0 → 0.76.1

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,36 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.76.0
4
+
5
+ ### A phone-supplied field could switch your approval gate off
6
+
7
+ `pushary claude --remote` sessions started from the phone build their command
8
+ line from fields the request supplies. The wrapper then read that command line
9
+ back to learn what it had been asked to do, and it scanned every position without
10
+ knowing which ones were a flag's **value** rather than a flag.
11
+
12
+ So a prompt or a model of `--permission-mode=dontAsk` was read as a real
13
+ permission mode. `dontAsk`, `plan` and `auto` all defer to the agent's own prompt
14
+ unconditionally, which means the session stopped asking you for approvals
15
+ entirely, and the decision log recorded a session that was never gated. A clean
16
+ approval history that is not true is worse than a missing one.
17
+
18
+ Flag values are now consumed with the flag that owns them, so nothing a request
19
+ supplies can be mistaken for an instruction. A `--permission-mode` you passed
20
+ yourself still works, in both the `--permission-mode plan` and
21
+ `--permission-mode=plan` forms.
22
+
23
+ The server that queues these sessions now also refuses flag-shaped model and
24
+ working-directory values, so an out-of-date CLI is protected against those two.
25
+ It cannot do the same for the prompt, which is free text you are entitled to
26
+ start with a dash, so **updating is what closes this one properly.**
27
+
28
+ Reaching it needed an authenticated session on your own account, spawning to your
29
+ own machine, with the daemon running. It is not cross-tenant and not remote code
30
+ execution. It matters most where the person spawning is not the person governed:
31
+ Team approval routing, Partner, and any case where a phone session or API key has
32
+ been compromised.
33
+
3
34
  ## 0.75.0
4
35
 
5
36
  ### An agent can now run the install
@@ -1047,13 +1047,16 @@ var flagValue = (args2, index) => {
1047
1047
  const next = args2[index + 1];
1048
1048
  return next && !next.startsWith("-") ? next : void 0;
1049
1049
  };
1050
+ var PASS_THROUGH_VALUE_FLAGS = /* @__PURE__ */ new Set(["--model", "-m", "--cwd", "--add-dir", "--settings"]);
1050
1051
  var parseRemoteArgs = (args2) => {
1051
1052
  let initialPrompt;
1052
1053
  let resume;
1053
1054
  let permissionMode;
1054
1055
  for (let i = 0; i < args2.length; i++) {
1055
1056
  const arg = args2[i];
1056
- if (arg === "-p" || arg === "--print" || arg?.startsWith("--print=")) {
1057
+ if (PASS_THROUGH_VALUE_FLAGS.has(arg ?? "")) {
1058
+ i++;
1059
+ } else if (arg === "-p" || arg === "--print" || arg?.startsWith("--print=")) {
1057
1060
  initialPrompt = flagValue(args2, i);
1058
1061
  } else if (arg === "-r" || arg === "--resume" || arg?.startsWith("--resume=")) {
1059
1062
  resume = flagValue(args2, i);
@@ -51,7 +51,9 @@ var isAuthFailure = (err) => {
51
51
  return candidate.status === 401 || candidate.status === 403;
52
52
  };
53
53
  var NATIVE_AGENT_BINARIES = { codex: "codex", gemini: "gemini" };
54
+ var isFlagShapedPrompt = (prompt) => prompt.trimStart().startsWith("-");
54
55
  var buildSpawnLaunch = (req, opts) => {
56
+ if (isFlagShapedPrompt(req.prompt)) return null;
55
57
  const agent = req.agent === "codex" || req.agent === "gemini" ? req.agent : "claude";
56
58
  const model = typeof req.model === "string" && req.model.length > 0 ? ["--model", req.model] : [];
57
59
  if (agent === "claude") {
@@ -103,6 +105,10 @@ var runSpawnDaemon = async () => {
103
105
  pusharyBin,
104
106
  resolveNative: (name) => resolveGlobalBinary(name) ?? name
105
107
  });
108
+ if (!plan) {
109
+ stderr("[pushary] refused a phone-requested session: the prompt looks like a command-line flag\n");
110
+ return;
111
+ }
106
112
  try {
107
113
  const child = plan.direct ? spawn(plan.command, plan.args, { cwd, detached: true, stdio: "ignore", env }) : spawnClaude(plan.command, plan.args, { cwd, detached: true, stdio: "ignore", env });
108
114
  child.on("error", (err) => stderr(`[pushary] could not launch session: ${err.message}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pushary/agent-hooks",
3
- "version": "0.75.0",
3
+ "version": "0.76.1",
4
4
  "description": "Permission hooks for AI coding agents: route tool approvals through Pushary push notifications",
5
5
  "keywords": [
6
6
  "pushary",