@pushary/agent-hooks 0.76.1 → 0.77.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.
@@ -7,7 +7,7 @@ import {
7
7
  KILL_REASON,
8
8
  isDeferAnswer,
9
9
  resolveGate
10
- } from "../chunk-UPPHYOIZ.js";
10
+ } from "../chunk-FWWBEB6L.js";
11
11
  import {
12
12
  askUser,
13
13
  cancelQuestion,
@@ -19,7 +19,7 @@ import {
19
19
  reportEvent,
20
20
  scopePathFor,
21
21
  waitForAnswer
22
- } from "../chunk-7L57N7WN.js";
22
+ } from "../chunk-HPDLDQC5.js";
23
23
  import "../chunk-BSZYIAZL.js";
24
24
  import "../chunk-SAF6HGAA.js";
25
25
  import "../chunk-7QLSKOSU.js";
@@ -4,7 +4,7 @@ import {
4
4
  denyReasonFrom,
5
5
  isDeferAnswer,
6
6
  resolveGate
7
- } from "../chunk-UPPHYOIZ.js";
7
+ } from "../chunk-FWWBEB6L.js";
8
8
  import {
9
9
  CODEX_AGENT,
10
10
  DEFAULT_SESSION,
@@ -35,7 +35,7 @@ import {
35
35
  toPolicyLookup,
36
36
  toPolicyLookups,
37
37
  waitForAnswer
38
- } from "../chunk-7L57N7WN.js";
38
+ } from "../chunk-HPDLDQC5.js";
39
39
  import {
40
40
  isGatingMoment,
41
41
  recordKeylessMoment
@@ -3,7 +3,7 @@ import {
3
3
  askUser,
4
4
  reportEvent,
5
5
  waitForAnswer
6
- } from "../chunk-7L57N7WN.js";
6
+ } from "../chunk-HPDLDQC5.js";
7
7
  import "../chunk-BSZYIAZL.js";
8
8
  import "../chunk-SAF6HGAA.js";
9
9
  import "../chunk-7QLSKOSU.js";
@@ -28,6 +28,27 @@ import {
28
28
  import { spawn } from "child_process";
29
29
  import { existsSync } from "fs";
30
30
  import { basename, dirname, join } from "path";
31
+
32
+ // src/stop-requests.ts
33
+ var STOP_CAPABILITY = "stop";
34
+ var isStopRequest = (value) => {
35
+ if (!value || typeof value !== "object") return false;
36
+ const candidate = value;
37
+ return typeof candidate.sessionId === "string" && candidate.sessionId.length > 0 && typeof candidate.pid === "number" && Number.isInteger(candidate.pid) && candidate.pid > 1;
38
+ };
39
+ var parseStopRequests = (value) => Array.isArray(value) ? value.filter(isStopRequest) : [];
40
+ var applyStop = (request, deps) => {
41
+ if (request.pid === deps.selfPid) return "skipped_self";
42
+ try {
43
+ deps.kill(request.pid, "SIGTERM");
44
+ return "stopped";
45
+ } catch (err) {
46
+ const code = err?.code;
47
+ return code === "ESRCH" ? "already_gone" : "refused";
48
+ }
49
+ };
50
+
51
+ // src/spawn-daemon.ts
31
52
  var DRAIN_PATH = "/api/agent/spawn/drain";
32
53
  var FAST_POLL_MS = 3e3;
33
54
  var SLOW_POLL_MS = 3e4;
@@ -121,6 +142,17 @@ var runSpawnDaemon = async () => {
121
142
  `);
122
143
  }
123
144
  };
145
+ const runStop = (stop) => {
146
+ const outcome = applyStop(stop, { kill: process.kill.bind(process), selfPid: process.pid });
147
+ const said = {
148
+ stopped: `stopped session ${stop.sessionId}`,
149
+ already_gone: `session ${stop.sessionId} had already exited`,
150
+ refused: `could not stop session ${stop.sessionId}, the system refused the signal`,
151
+ skipped_self: `refused to stop session ${stop.sessionId}: that pid is this daemon`
152
+ };
153
+ stderr(`[pushary] ${said[outcome]}
154
+ `);
155
+ };
124
156
  const drain = async (signal) => {
125
157
  const res = await fetch(`${baseUrl}${DRAIN_PATH}`, {
126
158
  method: "POST",
@@ -130,6 +162,7 @@ var runSpawnDaemon = async () => {
130
162
  });
131
163
  if (!res.ok) throw new DrainError(res.status);
132
164
  const data = await res.json();
165
+ for (const stop of parseStopRequests(data.stops)) runStop(stop);
133
166
  const spawn2 = data.spawn;
134
167
  return spawn2 && typeof spawn2.prompt === "string" && typeof spawn2.id === "string" ? spawn2 : null;
135
168
  };
@@ -182,7 +215,10 @@ var runSpawnDaemon = async () => {
182
215
  };
183
216
  const beat = async () => {
184
217
  if (stopped) return;
185
- const result = await sendHeartbeat(apiKey, { repoKey: basename(process.cwd()) });
218
+ const result = await sendHeartbeat(apiKey, {
219
+ repoKey: basename(process.cwd()),
220
+ capabilities: ["spawn", STOP_CAPABILITY]
221
+ });
186
222
  if (result.kind === "unauthorized" && !stopped) {
187
223
  fatalCode = EXIT.UNAUTHENTICATED;
188
224
  stderr("[pushary] daemon stopping: this machine's key was rejected. Run `pushary login` to sign in again.\n");
@@ -4,7 +4,7 @@ import {
4
4
  denyReasonFrom,
5
5
  isDeferAnswer,
6
6
  resolveGate
7
- } from "../chunk-UPPHYOIZ.js";
7
+ } from "../chunk-FWWBEB6L.js";
8
8
  import {
9
9
  DEFAULT_SESSION,
10
10
  askUser,
@@ -26,7 +26,7 @@ import {
26
26
  scopePathFor,
27
27
  sendNotification,
28
28
  waitForAnswer
29
- } from "../chunk-7L57N7WN.js";
29
+ } from "../chunk-HPDLDQC5.js";
30
30
  import {
31
31
  isGatingMoment,
32
32
  recordKeylessMoment
@@ -1,14 +1,14 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  handlePreToolUse
4
- } from "../chunk-DJHWBNM3.js";
4
+ } from "../chunk-MY4VJPWW.js";
5
5
  import "../chunk-3CBPY2G5.js";
6
6
  import {
7
7
  exitOnHelpFlag
8
8
  } from "../chunk-BBK3TTU2.js";
9
9
  import "../chunk-7OYGFJYZ.js";
10
- import "../chunk-UPPHYOIZ.js";
11
- import "../chunk-7L57N7WN.js";
10
+ import "../chunk-FWWBEB6L.js";
11
+ import "../chunk-HPDLDQC5.js";
12
12
  import "../chunk-IA5GBKNL.js";
13
13
  import "../chunk-BSZYIAZL.js";
14
14
  import "../chunk-SAF6HGAA.js";
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  handleNotification
4
- } from "../chunk-7L57N7WN.js";
4
+ } from "../chunk-HPDLDQC5.js";
5
5
  import "../chunk-BSZYIAZL.js";
6
6
  import "../chunk-SAF6HGAA.js";
7
7
  import "../chunk-7QLSKOSU.js";
@@ -1,10 +1,10 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  handlePermissionDenied
4
- } from "../chunk-DJHWBNM3.js";
4
+ } from "../chunk-MY4VJPWW.js";
5
5
  import "../chunk-3CBPY2G5.js";
6
- import "../chunk-UPPHYOIZ.js";
7
- import "../chunk-7L57N7WN.js";
6
+ import "../chunk-FWWBEB6L.js";
7
+ import "../chunk-HPDLDQC5.js";
8
8
  import "../chunk-IA5GBKNL.js";
9
9
  import "../chunk-BSZYIAZL.js";
10
10
  import "../chunk-SAF6HGAA.js";
@@ -1,10 +1,10 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  handlePermissionRequest
4
- } from "../chunk-DJHWBNM3.js";
4
+ } from "../chunk-MY4VJPWW.js";
5
5
  import "../chunk-3CBPY2G5.js";
6
- import "../chunk-UPPHYOIZ.js";
7
- import "../chunk-7L57N7WN.js";
6
+ import "../chunk-FWWBEB6L.js";
7
+ import "../chunk-HPDLDQC5.js";
8
8
  import "../chunk-IA5GBKNL.js";
9
9
  import "../chunk-BSZYIAZL.js";
10
10
  import "../chunk-SAF6HGAA.js";
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  handlePostToolUse
4
- } from "../chunk-7L57N7WN.js";
4
+ } from "../chunk-HPDLDQC5.js";
5
5
  import "../chunk-BSZYIAZL.js";
6
6
  import "../chunk-SAF6HGAA.js";
7
7
  import "../chunk-7QLSKOSU.js";
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  handleUserPrompt
4
- } from "../chunk-7L57N7WN.js";
4
+ } from "../chunk-HPDLDQC5.js";
5
5
  import "../chunk-BSZYIAZL.js";
6
6
  import "../chunk-SAF6HGAA.js";
7
7
  import "../chunk-7QLSKOSU.js";
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  handleSessionEnd
4
- } from "../chunk-7L57N7WN.js";
4
+ } from "../chunk-HPDLDQC5.js";
5
5
  import "../chunk-BSZYIAZL.js";
6
6
  import "../chunk-SAF6HGAA.js";
7
7
  import "../chunk-7QLSKOSU.js";
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  handleSessionStart
4
- } from "../chunk-7L57N7WN.js";
4
+ } from "../chunk-HPDLDQC5.js";
5
5
  import "../chunk-BSZYIAZL.js";
6
6
  import "../chunk-SAF6HGAA.js";
7
7
  import "../chunk-7QLSKOSU.js";
@@ -94,7 +94,7 @@ import {
94
94
  } from "../chunk-7OYGFJYZ.js";
95
95
  import {
96
96
  reportEvent
97
- } from "../chunk-7L57N7WN.js";
97
+ } from "../chunk-HPDLDQC5.js";
98
98
  import "../chunk-BSZYIAZL.js";
99
99
  import "../chunk-SAF6HGAA.js";
100
100
  import {
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  handleStop
4
- } from "../chunk-7L57N7WN.js";
4
+ } from "../chunk-HPDLDQC5.js";
5
5
  import "../chunk-BSZYIAZL.js";
6
6
  import "../chunk-SAF6HGAA.js";
7
7
  import "../chunk-7QLSKOSU.js";
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  handleStopFailure
4
- } from "../chunk-7L57N7WN.js";
4
+ } from "../chunk-HPDLDQC5.js";
5
5
  import "../chunk-BSZYIAZL.js";
6
6
  import "../chunk-SAF6HGAA.js";
7
7
  import "../chunk-7QLSKOSU.js";
@@ -4,7 +4,7 @@ import {
4
4
  isModeStateDegraded,
5
5
  resolveAutoResolveOrigin,
6
6
  resolvePolicyAcross
7
- } from "./chunk-7L57N7WN.js";
7
+ } from "./chunk-HPDLDQC5.js";
8
8
  import {
9
9
  evaluateScope,
10
10
  scopeChangeReason,
@@ -1028,6 +1028,9 @@ var reportEvent = async (event, options = {}) => {
1028
1028
  body: JSON.stringify({
1029
1029
  ...event,
1030
1030
  machineId: event.machineId ?? getMachineId(),
1031
+ // Lets the phone's Stop end this process instead of only denying its next
1032
+ // tool call. Ours alone: never another process, never a parent.
1033
+ pid: event.pid ?? process.pid,
1031
1034
  repoKey: event.repoKey ?? repoKeyFor(),
1032
1035
  installMode: detectInstallMode(),
1033
1036
  // Link-back for a phone-spawned session: forward the spawn id the daemon
@@ -5,7 +5,7 @@ import {
5
5
  denyReasonFrom,
6
6
  isDeferAnswer,
7
7
  resolveGate
8
- } from "./chunk-UPPHYOIZ.js";
8
+ } from "./chunk-FWWBEB6L.js";
9
9
  import {
10
10
  DEFAULT_SESSION,
11
11
  askUser,
@@ -25,7 +25,7 @@ import {
25
25
  sendNotification,
26
26
  throttlePass,
27
27
  waitForAnswer
28
- } from "./chunk-7L57N7WN.js";
28
+ } from "./chunk-HPDLDQC5.js";
29
29
  import {
30
30
  isGatingMoment,
31
31
  recordKeylessMoment
@@ -70,6 +70,7 @@ interface AgentEvent {
70
70
  agents?: readonly string[];
71
71
  meta?: ReceiptMeta;
72
72
  usage?: UsageReport;
73
+ pid?: number;
73
74
  }
74
75
  interface ReportEventOptions {
75
76
  maxAttempts?: number;
package/dist/src/index.js CHANGED
@@ -1,8 +1,8 @@
1
1
  import {
2
2
  handlePreToolUse
3
- } from "../chunk-DJHWBNM3.js";
3
+ } from "../chunk-MY4VJPWW.js";
4
4
  import "../chunk-3CBPY2G5.js";
5
- import "../chunk-UPPHYOIZ.js";
5
+ import "../chunk-FWWBEB6L.js";
6
6
  import {
7
7
  askUser,
8
8
  cancelQuestion,
@@ -15,7 +15,7 @@ import {
15
15
  reportEvent,
16
16
  resolvePolicy,
17
17
  waitForAnswer
18
- } from "../chunk-7L57N7WN.js";
18
+ } from "../chunk-HPDLDQC5.js";
19
19
  import "../chunk-IA5GBKNL.js";
20
20
  import "../chunk-BSZYIAZL.js";
21
21
  import "../chunk-SAF6HGAA.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pushary/agent-hooks",
3
- "version": "0.76.1",
3
+ "version": "0.77.0",
4
4
  "description": "Permission hooks for AI coding agents: route tool approvals through Pushary push notifications",
5
5
  "keywords": [
6
6
  "pushary",