@pushary/agent-hooks 1.7.3 → 1.8.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 +14 -0
- package/README.md +39 -19
- package/data/SKILL.md +8 -8
- package/data/cowork/SKILL.md +2 -2
- package/data/cursor-plugin/README.md +2 -2
- package/data/cursor-plugin/scripts/pushary-gate.mjs +2 -21
- package/data/cursor-plugin/scripts/redaction.mjs +53 -0
- package/data/cursor-plugin/skills/pushary/SKILL.md +7 -7
- package/data/vscode-plugin/README.md +4 -4
- package/data/vscode-plugin/scripts/pushary-gate.mjs +3 -23
- package/data/vscode-plugin/scripts/redaction.mjs +53 -0
- package/data/vscode-plugin/skills/pushary/SKILL.md +7 -7
- package/dist/bin/pushary-bell-hook.js +23 -23
- package/dist/bin/pushary-bell.js +9 -9
- package/dist/bin/pushary-claude.js +26 -26
- package/dist/bin/pushary-clean.js +97 -111
- package/dist/bin/pushary-codex-bridge.js +18 -18
- package/dist/bin/pushary-codex-hook.js +42 -43
- package/dist/bin/pushary-codex.js +13 -13
- package/dist/bin/pushary-connect.js +13 -13
- package/dist/bin/pushary-cowork.js +5 -5
- package/dist/bin/pushary-daemon.js +27 -27
- package/dist/bin/pushary-disconnect.js +18 -18
- package/dist/bin/pushary-doctor.js +92 -86
- package/dist/bin/pushary-elicitation-hook.js +25 -25
- package/dist/bin/pushary-gemini-bridge.js +12 -12
- package/dist/bin/pushary-gemini-hook.js +29 -30
- package/dist/bin/pushary-hook.js +32 -32
- package/dist/bin/pushary-login.js +12 -12
- package/dist/bin/pushary-logout.js +7 -7
- package/dist/bin/pushary-mcp.js +85 -28
- package/dist/bin/pushary-mode.js +9 -9
- package/dist/bin/pushary-notification-hook.js +28 -28
- package/dist/bin/pushary-opencode-hook.js +28 -29
- package/dist/bin/pushary-permission-denied-hook.js +32 -32
- package/dist/bin/pushary-permission-hook.js +31 -31
- package/dist/bin/pushary-post-hook.js +28 -28
- package/dist/bin/pushary-prompt-hook.js +28 -28
- package/dist/bin/pushary-session-end-hook.js +28 -28
- package/dist/bin/pushary-session-start-hook.js +32 -32
- package/dist/bin/pushary-setup.js +62 -129
- package/dist/bin/pushary-stats.js +5 -5
- package/dist/bin/pushary-status.js +15 -15
- package/dist/bin/pushary-stop-hook.js +28 -28
- package/dist/bin/pushary-stopfailure-hook.js +28 -28
- package/dist/bin/pushary-suggestions.js +4 -4
- package/dist/bin/pushary-transcript-register.js +19 -19
- package/dist/bin/pushary-transcripts.js +7 -7
- package/dist/bin/pushary-upgrade.js +236 -110
- package/dist/bin/pushary-wait.js +9 -9
- package/dist/bin/pushary.js +6 -6
- package/dist/{chunk-DUQO4C4I.js → chunk-2SLCHCVN.js} +3 -3
- package/dist/{chunk-YYCTF4Q5.js → chunk-35X5UDML.js} +7 -7
- package/dist/{chunk-OVC5QXN5.js → chunk-4A3UQERT.js} +1 -1
- package/dist/chunk-5DGNEUXK.js +73 -0
- package/dist/{chunk-62CVUUNU.js → chunk-5Y2DY6X4.js} +2 -2
- package/dist/{chunk-G4GLCLKK.js → chunk-5YY3IJT4.js} +159 -36
- package/dist/{chunk-KJXUIPS4.js → chunk-64H5IZZD.js} +28 -16
- package/dist/{chunk-OTNOANMX.js → chunk-6TK4IY3A.js} +8 -8
- package/dist/{chunk-LPNJLKBQ.js → chunk-72WOCX22.js} +1 -1
- package/dist/{chunk-IRZG3HEU.js → chunk-7ITOAMCD.js} +1 -1
- package/dist/{chunk-G62JL2NT.js → chunk-7U7ZWUTR.js} +1 -1
- package/dist/{chunk-IPSRMLCJ.js → chunk-ASWRMBOM.js} +1 -1
- package/dist/{chunk-5S2VBSJI.js → chunk-CB23AO4D.js} +2 -2
- package/dist/{chunk-VKVSRCBO.js → chunk-CHMOVJ2M.js} +1 -1
- package/dist/{chunk-BGBLLHZ4.js → chunk-DLEKCAQL.js} +1 -1
- package/dist/{chunk-EEEJ2JIL.js → chunk-DVW2MYCM.js} +3 -3
- package/dist/{chunk-AWVNAYGD.js → chunk-DXBS2EL7.js} +1 -1
- package/dist/{chunk-ZKJ34T2F.js → chunk-EIGJYCOE.js} +31 -17
- package/dist/{chunk-U6RVDUJ5.js → chunk-F6NTWZZC.js} +283 -41
- package/dist/{chunk-7RUJKCR4.js → chunk-FLQPM2GQ.js} +2 -2
- package/dist/{chunk-TCVMK6GI.js → chunk-GBNQXYN4.js} +4 -4
- package/dist/{chunk-G6RRVJOG.js → chunk-GH6KGWMC.js} +6 -6
- package/dist/chunk-GU3EJCVV.js +43 -0
- package/dist/{chunk-6JQFIHZC.js → chunk-HBWC3JVZ.js} +3 -3
- package/dist/{chunk-IWJKSIB4.js → chunk-HMNR7B2F.js} +1 -1
- package/dist/{chunk-NOI3XTCY.js → chunk-HOEB6AKG.js} +1 -1
- package/dist/{chunk-62VT3BPH.js → chunk-HQRCVEI2.js} +32 -17
- package/dist/{chunk-MIXWMA73.js → chunk-HTEGMMT3.js} +3 -3
- package/dist/{chunk-BIH2Y2HP.js → chunk-HVDMGDYV.js} +2 -2
- package/dist/{chunk-VE7TXLR4.js → chunk-I4HKMUZQ.js} +3 -3
- package/dist/{chunk-YPUBA2FL.js → chunk-INSMZNS7.js} +5 -5
- package/dist/{chunk-G3OMOTJ4.js → chunk-JRQRNNGA.js} +3 -3
- package/dist/{chunk-N5MZH5A6.js → chunk-KB2FTO4O.js} +4 -4
- package/dist/{chunk-O3JDWNLU.js → chunk-LK2S5XIV.js} +183 -28
- package/dist/{chunk-YC27PROF.js → chunk-MMVCI6DT.js} +20 -5
- package/dist/{chunk-3EUBQARL.js → chunk-MYHG7PX2.js} +1 -1
- package/dist/{chunk-EADXTSHE.js → chunk-N6JJJTPH.js} +6 -3
- package/dist/{chunk-PRNFSORD.js → chunk-NHCUXTEM.js} +1 -1
- package/dist/{chunk-KEL5MXRL.js → chunk-NOLPURUI.js} +1 -1
- package/dist/{chunk-WTJM7PSL.js → chunk-OCVVSRDA.js} +3 -3
- package/dist/{chunk-R6OYCUNK.js → chunk-ON5JW2HP.js} +1 -1
- package/dist/{chunk-UOQRM7JQ.js → chunk-QB6QYZ6B.js} +5 -5
- package/dist/{chunk-7OA34PNW.js → chunk-T55H6YEP.js} +40 -10
- package/dist/{chunk-D6OODZCM.js → chunk-TJMAXQ5Q.js} +2 -2
- package/dist/{chunk-WGMW7OXW.js → chunk-TKQ6LZQZ.js} +6 -6
- package/dist/{chunk-WPX67AKT.js → chunk-UMMCHS6P.js} +1 -1
- package/dist/{chunk-MZBRL5H5.js → chunk-UPLV5AJF.js} +108 -25
- package/dist/{chunk-P2VIBGXA.js → chunk-URNXU3FO.js} +1 -1
- package/dist/{chunk-EUGNVLMG.js → chunk-VFFHQC7W.js} +3 -1
- package/dist/{chunk-Y4ZH64UK.js → chunk-VZMIHERK.js} +2 -2
- package/dist/{chunk-RLW3JWDY.js → chunk-W2LJ4O3A.js} +2 -2
- package/dist/{chunk-LHC45YUC.js → chunk-ZJYJAD52.js} +1 -1
- package/dist/{reapply-PH5T4BGR.js → reapply-ICGTBHVE.js} +9 -9
- package/dist/src/index.js +20 -20
- package/package.json +1 -1
- package/dist/chunk-5GB22QYL.js +0 -255
- package/dist/chunk-VYPJHGG6.js +0 -92
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
import {
|
|
2
2
|
readExistingMachineId
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-4A3UQERT.js";
|
|
4
4
|
import {
|
|
5
5
|
NetworkError
|
|
6
6
|
} from "./chunk-7QLSKOSU.js";
|
|
7
7
|
import {
|
|
8
8
|
getBaseUrl
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-ON5JW2HP.js";
|
|
10
10
|
import {
|
|
11
11
|
clientContextHeaders,
|
|
12
12
|
getPackageVersion
|
|
13
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-5YY3IJT4.js";
|
|
14
14
|
|
|
15
15
|
// src/cli/net.ts
|
|
16
16
|
import { createRequire } from "module";
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import {
|
|
2
2
|
SETUP_AGENT_CHOICES
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-5YY3IJT4.js";
|
|
4
4
|
|
|
5
5
|
// src/cli/commands.ts
|
|
6
|
-
var NPX_LATEST_COMMAND = "npx
|
|
6
|
+
var NPX_LATEST_COMMAND = "npx pushary@latest";
|
|
7
7
|
var COMMAND_LIST = [
|
|
8
8
|
{
|
|
9
9
|
name: "cowork",
|
|
@@ -181,11 +181,11 @@ var SETUP_OPTIONS = [
|
|
|
181
181
|
];
|
|
182
182
|
var AGENT_IDS = SETUP_AGENT_CHOICES.join(", ");
|
|
183
183
|
var USAGE_EXAMPLES = [
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
184
|
+
`${NPX_LATEST_COMMAND} setup`,
|
|
185
|
+
`${NPX_LATEST_COMMAND} setup --agents auto --yes --skip-phone`,
|
|
186
|
+
`${NPX_LATEST_COMMAND} setup --key-stdin --agents claude_code --yes < key.txt`,
|
|
187
|
+
`${NPX_LATEST_COMMAND} doctor`,
|
|
188
|
+
`${NPX_LATEST_COMMAND} mode push_only --for 30m`,
|
|
189
189
|
"pushary claude # native terminal, reachable from your phone",
|
|
190
190
|
'pushary claude --remote -p "start the refactor" # start headless, drive from your phone',
|
|
191
191
|
"pushary daemon # keep this machine ready to spawn a session"
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import {
|
|
2
|
+
AUTO_DECISION_WINDOW_MS,
|
|
3
|
+
claimThrottle,
|
|
4
|
+
deriveToolTarget,
|
|
5
|
+
permissionDeniedAction,
|
|
6
|
+
releaseThrottle,
|
|
7
|
+
reportEvent
|
|
8
|
+
} from "./chunk-F6NTWZZC.js";
|
|
9
|
+
import {
|
|
10
|
+
DEFAULT_SESSION
|
|
11
|
+
} from "./chunk-N6IOSZOE.js";
|
|
12
|
+
import {
|
|
13
|
+
machineDecisionFor,
|
|
14
|
+
shouldDeferToNativeMode,
|
|
15
|
+
wireVerdictFor
|
|
16
|
+
} from "./chunk-5YY3IJT4.js";
|
|
17
|
+
|
|
18
|
+
// src/machine-decision-audit.ts
|
|
19
|
+
import { basename } from "path";
|
|
20
|
+
var reportMachineDenial = async (input, verdict, agent) => {
|
|
21
|
+
const decision = machineDecisionFor(wireVerdictFor(verdict, 0));
|
|
22
|
+
if (!decision) return;
|
|
23
|
+
const sessionKey = input.session_id || DEFAULT_SESSION;
|
|
24
|
+
const toolTarget = deriveToolTarget(input.tool_name, input.tool_input);
|
|
25
|
+
const throttleKey = `machinedecision:${agent.type}:${sessionKey}:${input.tool_name}:${decision.origin}:${toolTarget ?? ""}`;
|
|
26
|
+
const throttle = claimThrottle(throttleKey, AUTO_DECISION_WINDOW_MS);
|
|
27
|
+
if (throttle === "throttled") return;
|
|
28
|
+
if (throttle === "unavailable") {
|
|
29
|
+
console.error("[Pushary] Could not access the audit throttle; reporting this denial without deduplication.");
|
|
30
|
+
}
|
|
31
|
+
try {
|
|
32
|
+
const response = await reportEvent({
|
|
33
|
+
event: "permission_denied",
|
|
34
|
+
occurredAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
35
|
+
toolUseId: input.tool_use_id,
|
|
36
|
+
agentType: agent.type,
|
|
37
|
+
agentName: `${agent.label} - ${basename(input.cwd ?? process.cwd())}`,
|
|
38
|
+
action: permissionDeniedAction(input.tool_name),
|
|
39
|
+
sessionId: input.session_id,
|
|
40
|
+
decisionSource: "policy_auto",
|
|
41
|
+
decisionOrigin: decision.origin,
|
|
42
|
+
decisionOutcome: decision.outcome,
|
|
43
|
+
toolName: input.tool_name,
|
|
44
|
+
toolTarget
|
|
45
|
+
}, { maxAttempts: 1, timeoutMs: 800, requireOk: true, skipDrain: true });
|
|
46
|
+
if (response?.ok !== true) throw new Error("Audit delivery was not acknowledged");
|
|
47
|
+
} catch {
|
|
48
|
+
console.error("[Pushary] Could not record the machine denial. The action remains blocked; its audit delivery will be retried on the next matching denial.");
|
|
49
|
+
if (throttle === "passed") {
|
|
50
|
+
try {
|
|
51
|
+
releaseThrottle(throttleKey);
|
|
52
|
+
} catch {
|
|
53
|
+
console.error("[Pushary] Could not reset the failed audit throttle.");
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
// src/native-defer.ts
|
|
60
|
+
var nativeDeferOptions = () => {
|
|
61
|
+
const respect = process.env.PUSHARY_RESPECT_PERMISSION_MODE;
|
|
62
|
+
const bypass = process.env.PUSHARY_DEFER_BYPASS;
|
|
63
|
+
return {
|
|
64
|
+
respectPermissionMode: !(respect === "0" || respect === "false"),
|
|
65
|
+
deferBypass: bypass === "1" || bypass === "true"
|
|
66
|
+
};
|
|
67
|
+
};
|
|
68
|
+
var defersToNativeMode = (permissionMode, toolName) => shouldDeferToNativeMode(permissionMode, toolName, nativeDeferOptions());
|
|
69
|
+
|
|
70
|
+
export {
|
|
71
|
+
reportMachineDenial,
|
|
72
|
+
defersToNativeMode
|
|
73
|
+
};
|
|
@@ -22,7 +22,7 @@ var COWORK_STANDING_INSTRUCTIONS = `Pushary is connected as a custom connector.
|
|
|
22
22
|
- If Pushary tools are missing or disabled, report that once and continue within my authorization. Do not claim a notification or approval was delivered.`;
|
|
23
23
|
|
|
24
24
|
// ../contracts/src/agent-manifest.ts
|
|
25
|
-
var
|
|
25
|
+
var PUSHARY_SETUP_COMMAND = "npx pushary@latest setup";
|
|
26
26
|
var defaults = {
|
|
27
27
|
hasStoredIdentity: true,
|
|
28
28
|
hookSource: null,
|
|
@@ -54,7 +54,7 @@ var AGENTS = {
|
|
|
54
54
|
managedProvider: true,
|
|
55
55
|
enforcement: "enforced",
|
|
56
56
|
connectVia: "Native hooks + MCP",
|
|
57
|
-
setupCommand:
|
|
57
|
+
setupCommand: PUSHARY_SETUP_COMMAND,
|
|
58
58
|
enforcementDetail: "Shell, writes and edits, subject to Claude Code permission mode and explicit policy."
|
|
59
59
|
},
|
|
60
60
|
claude_chat: {
|
|
@@ -81,7 +81,7 @@ var AGENTS = {
|
|
|
81
81
|
managedProvider: true,
|
|
82
82
|
enforcement: "enforced",
|
|
83
83
|
connectVia: "Native hooks + MCP",
|
|
84
|
-
setupCommand:
|
|
84
|
+
setupCommand: PUSHARY_SETUP_COMMAND,
|
|
85
85
|
enforcementDetail: "Shell and apply_patch edits through native permission hooks; requires a compatible Codex runtime."
|
|
86
86
|
},
|
|
87
87
|
chatgpt: {
|
|
@@ -101,7 +101,7 @@ var AGENTS = {
|
|
|
101
101
|
managedProvider: true,
|
|
102
102
|
enforcement: "enforced",
|
|
103
103
|
connectVia: "Native hooks + MCP",
|
|
104
|
-
setupCommand:
|
|
104
|
+
setupCommand: PUSHARY_SETUP_COMMAND,
|
|
105
105
|
enforcementDetail: "Shell, writes and edits through native BeforeTool hooks."
|
|
106
106
|
},
|
|
107
107
|
hermes: {
|
|
@@ -110,7 +110,7 @@ var AGENTS = {
|
|
|
110
110
|
policyAgent: "hermes",
|
|
111
111
|
enforcement: "enforced",
|
|
112
112
|
connectVia: "Native Python plugin + approval transport",
|
|
113
|
-
setupCommand:
|
|
113
|
+
setupCommand: PUSHARY_SETUP_COMMAND,
|
|
114
114
|
enforcementDetail: "Hermes dangerous-command approvals when the Pushary transport is selected; optional PUSHARY_GATE_TOOLS gates named tools.",
|
|
115
115
|
capabilityNote: "Uses the Python plugin, not a macOS bridge HookSource. CLI disconnect and managed-provider controls are not implemented for Hermes."
|
|
116
116
|
},
|
|
@@ -123,7 +123,7 @@ var AGENTS = {
|
|
|
123
123
|
disconnectable: true,
|
|
124
124
|
enforcement: "enforced",
|
|
125
125
|
connectVia: "Editor plugin hooks + MCP",
|
|
126
|
-
setupCommand:
|
|
126
|
+
setupCommand: PUSHARY_SETUP_COMMAND,
|
|
127
127
|
enforcementDetail: "With installed hooks: shell, MCP execution and Write/Delete/Edit tool calls. Plain MCP remains cooperative."
|
|
128
128
|
},
|
|
129
129
|
vscode: {
|
|
@@ -134,7 +134,7 @@ var AGENTS = {
|
|
|
134
134
|
policyAgent: "vscode",
|
|
135
135
|
enforcement: "enforced",
|
|
136
136
|
connectVia: "Agent plugin hooks + MCP",
|
|
137
|
-
setupCommand:
|
|
137
|
+
setupCommand: PUSHARY_SETUP_COMMAND,
|
|
138
138
|
enforcementDetail: "PreToolUse approval hooks from the installed agent plugin; the host decides which events it exposes.",
|
|
139
139
|
capabilityNote: "Has both a bridge HookSource and a per-agent policy profile. CLI disconnect and managed-provider controls are not implemented for VS Code."
|
|
140
140
|
},
|
|
@@ -148,14 +148,14 @@ var AGENTS = {
|
|
|
148
148
|
disconnectable: true,
|
|
149
149
|
enforcement: "enforced",
|
|
150
150
|
connectVia: "Generated plugin + MCP",
|
|
151
|
-
setupCommand:
|
|
151
|
+
setupCommand: PUSHARY_SETUP_COMMAND,
|
|
152
152
|
enforcementDetail: "Shell, writes, edits and web fetches when OpenCode itself asks for permission."
|
|
153
153
|
},
|
|
154
154
|
fx: {
|
|
155
155
|
...defaults,
|
|
156
156
|
label: "fx",
|
|
157
157
|
connectVia: "Local MCP bridge",
|
|
158
|
-
setupCommand:
|
|
158
|
+
setupCommand: PUSHARY_SETUP_COMMAND,
|
|
159
159
|
capabilityNote: "fx has no hooks that other tools can register, so Pushary cannot answer fx's own approval prompts. Setup turns off fx's terminal question tool so fx's agent asks through Pushary. fx's full-access mode ignores that setting; there the agent is only instructed to ask through Pushary."
|
|
160
160
|
},
|
|
161
161
|
qwen_code: {
|
|
@@ -168,7 +168,7 @@ var AGENTS = {
|
|
|
168
168
|
disconnectable: true,
|
|
169
169
|
enforcement: "enforced",
|
|
170
170
|
connectVia: "Native hooks + MCP",
|
|
171
|
-
setupCommand:
|
|
171
|
+
setupCommand: PUSHARY_SETUP_COMMAND,
|
|
172
172
|
enforcementDetail: "Shell, writes and edits through native PreToolUse hooks, matched on Qwen's own tool names and their Claude-shaped aliases."
|
|
173
173
|
},
|
|
174
174
|
codebuddy: {
|
|
@@ -181,7 +181,7 @@ var AGENTS = {
|
|
|
181
181
|
disconnectable: true,
|
|
182
182
|
enforcement: "enforced",
|
|
183
183
|
connectVia: "Native hooks + MCP",
|
|
184
|
-
setupCommand:
|
|
184
|
+
setupCommand: PUSHARY_SETUP_COMMAND,
|
|
185
185
|
enforcementDetail: "Shell, writes and edits through native PreToolUse hooks, plus PermissionRequest. CodeBuddy implements the Claude Code hook specification."
|
|
186
186
|
},
|
|
187
187
|
qoder: {
|
|
@@ -194,7 +194,7 @@ var AGENTS = {
|
|
|
194
194
|
disconnectable: true,
|
|
195
195
|
enforcement: "enforced",
|
|
196
196
|
connectVia: "Native hooks + MCP",
|
|
197
|
-
setupCommand:
|
|
197
|
+
setupCommand: PUSHARY_SETUP_COMMAND,
|
|
198
198
|
enforcementDetail: "Shell, writes and edits through native PreToolUse hooks, plus PermissionRequest, over Qoder's superset of the Claude Code event list.",
|
|
199
199
|
capabilityNote: "Qoder documents no user-level instructions file, so the proactive-ask block is not installed. Hooks and MCP are unaffected. Like every agent in this family, the CLI wires it; the macOS app does not yet."
|
|
200
200
|
},
|
|
@@ -208,7 +208,7 @@ var AGENTS = {
|
|
|
208
208
|
disconnectable: true,
|
|
209
209
|
enforcement: "enforced",
|
|
210
210
|
connectVia: "Native hooks",
|
|
211
|
-
setupCommand:
|
|
211
|
+
setupCommand: PUSHARY_SETUP_COMMAND,
|
|
212
212
|
enforcementDetail: "Execute, Create, Edit and ApplyPatch through native PreToolUse hooks in ~/.factory/hooks.json.",
|
|
213
213
|
capabilityNote: "Droid registers MCP servers through `droid mcp add` rather than a documented remote-server config shape, so setup writes hooks only. Add Pushary's MCP server yourself to let Droid send notifications and ask questions."
|
|
214
214
|
},
|
|
@@ -222,14 +222,14 @@ var AGENTS = {
|
|
|
222
222
|
disconnectable: true,
|
|
223
223
|
enforcement: "enforced",
|
|
224
224
|
connectVia: "Native hooks",
|
|
225
|
-
setupCommand:
|
|
225
|
+
setupCommand: PUSHARY_SETUP_COMMAND,
|
|
226
226
|
enforcementDetail: "exec, write and edit through native PreToolUse hooks, answered in Devin's own approve/block schema.",
|
|
227
227
|
capabilityNote: "Devin CLI answers PreToolUse with `{decision}` rather than a permission decision. Pushary blocks an unanswered approval because this adapter cannot request a native prompt reliably. Question and plan dialogs remain with Devin; this adapter does not render their answers. It also fires no Notification event."
|
|
228
228
|
},
|
|
229
229
|
windsurf: {
|
|
230
230
|
...defaults,
|
|
231
231
|
label: "Windsurf",
|
|
232
|
-
setupCommand:
|
|
232
|
+
setupCommand: PUSHARY_SETUP_COMMAND,
|
|
233
233
|
setupChoice: "Other"
|
|
234
234
|
},
|
|
235
235
|
unknown: {
|
|
@@ -246,7 +246,7 @@ var AGENTS = {
|
|
|
246
246
|
...defaults,
|
|
247
247
|
hasStoredIdentity: false,
|
|
248
248
|
label: "Any MCP client",
|
|
249
|
-
setupCommand:
|
|
249
|
+
setupCommand: PUSHARY_SETUP_COMMAND,
|
|
250
250
|
setupChoice: "Other"
|
|
251
251
|
},
|
|
252
252
|
http: {
|
|
@@ -455,7 +455,7 @@ var compatibleTargetFiles = (profile) => {
|
|
|
455
455
|
};
|
|
456
456
|
|
|
457
457
|
// ../contracts/src/redaction.ts
|
|
458
|
-
var CREDENTIAL_NAME = String.raw`(?:secret|token|password|passwd|api[_-]?key|access[_-]?key|client[_-]?secret|private[_-]?key)["']?`;
|
|
458
|
+
var CREDENTIAL_NAME = String.raw`(?:authorization|secret|token|password|passwd|api[_-]?key|access[_-]?key|client[_-]?secret|private[_-]?key)["']?`;
|
|
459
459
|
var CREDENTIAL_KEY = String.raw`${CREDENTIAL_NAME}\s*[=:]\s*`;
|
|
460
460
|
var DISPLAYED_CREDENTIAL_KEY = String.raw`${CREDENTIAL_NAME}(?:[ \t]*:[ \t]*|[ \t]+=[ \t]*|=)`;
|
|
461
461
|
var SHELL_INERT_UNIT = String.raw`(?:[A-Za-z0-9_\-./+=:@%^!#]|\\[^\s'"])`;
|
|
@@ -467,6 +467,7 @@ var credentialAssignmentRule = (key, doubleQuoted, singleQuoted, bare) => ({
|
|
|
467
467
|
replacement: "$1$2$3$4[redacted]$2$3"
|
|
468
468
|
});
|
|
469
469
|
var DISPLAYED_SECRET_SHAPES = {
|
|
470
|
+
separator: String.raw`[ \t]`,
|
|
470
471
|
privateKeyBody: String.raw`${PEM_LINE_BREAK}?(?:(?:Proc-Type|DEK-Info): [A-Za-z0-9,-]+${PEM_LINE_BREAK})*(?:[A-Za-z0-9+/=\r\n]|\\[rn])*?`,
|
|
471
472
|
urlPassword: `${SHELL_INERT_URL_PASSWORD_UNIT}+`,
|
|
472
473
|
authorizationValue: `${SHELL_INERT_UNIT}+`,
|
|
@@ -478,6 +479,7 @@ var DISPLAYED_SECRET_SHAPES = {
|
|
|
478
479
|
)
|
|
479
480
|
};
|
|
480
481
|
var CUT_OFF_SECRET_SHAPES = {
|
|
482
|
+
separator: String.raw`\s`,
|
|
481
483
|
privateKeyBody: String.raw`[\s\S]*?`,
|
|
482
484
|
urlPassword: String.raw`[^\s@/]+`,
|
|
483
485
|
authorizationValue: String.raw`\S+`,
|
|
@@ -504,8 +506,8 @@ var secretRedactionRules = (shapes) => [
|
|
|
504
506
|
{ pattern: /\bxai-[A-Za-z0-9]{16,}\b/g, replacement: "[redacted]" },
|
|
505
507
|
{ pattern: /\beyJ[A-Za-z0-9_-]{8,}\.[A-Za-z0-9_-]{8,}\.[A-Za-z0-9_-]{8,}\b/g, replacement: "[redacted]" },
|
|
506
508
|
{ pattern: new RegExp(String.raw`\b([a-z][a-z0-9+.-]*:\/\/[^\s:/@]+:)${shapes.urlPassword}@`, "gi"), replacement: "$1[redacted]@" },
|
|
507
|
-
{ pattern:
|
|
508
|
-
{ pattern: new RegExp(String.raw`\bauthorization
|
|
509
|
+
{ pattern: new RegExp(String.raw`\bbearer${shapes.separator}+[A-Za-z0-9._~+/=-]+`, "gi"), replacement: "bearer [redacted]" },
|
|
510
|
+
{ pattern: new RegExp(String.raw`\bauthorization:${shapes.separator}*${shapes.authorizationValue}`, "gi"), replacement: "authorization: [redacted]" },
|
|
509
511
|
shapes.credentialAssignment
|
|
510
512
|
];
|
|
511
513
|
var SECRET_REDACTION_RULES = secretRedactionRules(DISPLAYED_SECRET_SHAPES);
|
|
@@ -643,7 +645,7 @@ var parseAgentQuestionAnswers = (questions, value) => {
|
|
|
643
645
|
return answers;
|
|
644
646
|
};
|
|
645
647
|
var INSTALL_SOURCES = [
|
|
646
|
-
/** `npx
|
|
648
|
+
/** `npx pushary@latest ...`, the documented one-liner. */
|
|
647
649
|
"npx",
|
|
648
650
|
/** A global or project npm install, invoked as `pushary`. */
|
|
649
651
|
"npm",
|
|
@@ -659,9 +661,13 @@ var INSTALL_SOURCES = [
|
|
|
659
661
|
"framework_adapter",
|
|
660
662
|
/** The browser onboarding wizard. */
|
|
661
663
|
"dashboard",
|
|
662
|
-
/** Reported nothing, or reported something we do not recognise. */
|
|
663
664
|
/** The macOS app pairing a phone from its own onboarding. */
|
|
664
665
|
"mac_app",
|
|
666
|
+
/** The phone app's own sign-up, which provisions the agent site before any web step. */
|
|
667
|
+
"mobile_app",
|
|
668
|
+
/** The CLI's device-code sign-in page (`/cli/authorize`), which provisions a site before any web step. */
|
|
669
|
+
"cli_login",
|
|
670
|
+
/** Reported nothing, or reported something we do not recognise. */
|
|
665
671
|
"unknown"
|
|
666
672
|
];
|
|
667
673
|
var isInstallSource = (value) => typeof value === "string" && INSTALL_SOURCES.includes(value);
|
|
@@ -1535,6 +1541,16 @@ var API_KEY_PATTERN = /^pk_[a-f0-9]+\.[a-f0-9]+$/;
|
|
|
1535
1541
|
var isValidApiKey = (value) => API_KEY_PATTERN.test(value);
|
|
1536
1542
|
var ACTION_BODY_MAX = 4e3;
|
|
1537
1543
|
var DECISION_LINE_MAX = 500;
|
|
1544
|
+
var ASK_QUESTION_MAX = 500;
|
|
1545
|
+
var ASK_AGENT_NAME_MAX = 100;
|
|
1546
|
+
var TRUNCATION_MARK = "\u2026";
|
|
1547
|
+
var isHighSurrogate = (code) => code >= 55296 && code <= 56319;
|
|
1548
|
+
var truncateLine = (text, max, mark = TRUNCATION_MARK) => {
|
|
1549
|
+
if (text.length <= max) return text;
|
|
1550
|
+
const end = max - mark.length;
|
|
1551
|
+
const keep = isHighSurrogate(text.charCodeAt(end - 1)) ? end - 1 : end;
|
|
1552
|
+
return `${text.slice(0, keep)}${mark}`;
|
|
1553
|
+
};
|
|
1538
1554
|
var APPROVAL_FATIGUE_FLAG_PATTERNS = [
|
|
1539
1555
|
/\brm\s+-[a-z]*r/i,
|
|
1540
1556
|
/\brmdir\b/i,
|
|
@@ -2539,40 +2555,126 @@ var hookActivationResult = (report) => {
|
|
|
2539
2555
|
return report && !report.truncated && report.evidence.length === 1 ? report.evidence[0].result : "unverified";
|
|
2540
2556
|
};
|
|
2541
2557
|
|
|
2558
|
+
// src/cli-package-name.ts
|
|
2559
|
+
var CANONICAL_PACKAGE = "pushary";
|
|
2560
|
+
var LEGACY_PACKAGE = "@pushary/agent-hooks";
|
|
2561
|
+
var CLI_PACKAGE_NAMES = [CANONICAL_PACKAGE, LEGACY_PACKAGE];
|
|
2562
|
+
var isCliPackageName = (value) => typeof value === "string" && CLI_PACKAGE_NAMES.some((name) => name === value);
|
|
2563
|
+
var cliPackagePathSegments = (name) => name.split("/");
|
|
2564
|
+
|
|
2565
|
+
// src/global-package.ts
|
|
2566
|
+
import { posix, win32 } from "path";
|
|
2567
|
+
var OWNERSHIP_PROBE_COMMAND = "pushary-hook";
|
|
2568
|
+
var pathApiFor = (platform) => platform === "win32" ? win32 : posix;
|
|
2569
|
+
var POSIX_GLOBAL_ROOT_SEGMENTS = ["lib", "node_modules"];
|
|
2570
|
+
var UPGRADE_ENTRY_SEGMENTS = ["dist", "bin", "pushary-upgrade.js"];
|
|
2571
|
+
var globalRootFor = (prefix, platform) => platform === "win32" ? win32.join(prefix, "node_modules") : posix.join(prefix, ...POSIX_GLOBAL_ROOT_SEGMENTS);
|
|
2572
|
+
var globalPackageFolder = (root, name, platform) => pathApiFor(platform).join(root, ...cliPackagePathSegments(name));
|
|
2573
|
+
var globalUpgradeEntry = (prefix, name, platform) => pathApiFor(platform).join(globalPackageFolder(globalRootFor(prefix, platform), name, platform), ...UPGRADE_ENTRY_SEGMENTS);
|
|
2574
|
+
var isInsideFolder = (target, folder, platform) => {
|
|
2575
|
+
const pathApi = pathApiFor(platform);
|
|
2576
|
+
const relativePath = pathApi.relative(folder, target);
|
|
2577
|
+
return relativePath !== "" && !relativePath.startsWith("..") && !pathApi.isAbsolute(relativePath);
|
|
2578
|
+
};
|
|
2579
|
+
var linkPointsInto = (evidence, targets, name) => evidence.globalRoots.some((root) => {
|
|
2580
|
+
const folder = globalPackageFolder(root, name, evidence.platform);
|
|
2581
|
+
return targets.some((target) => isInsideFolder(target, folder, evidence.platform));
|
|
2582
|
+
});
|
|
2583
|
+
var ownerFromInstalled = (installed, whenNone) => {
|
|
2584
|
+
const [only, ...others] = installed;
|
|
2585
|
+
if (only === void 0) return whenNone;
|
|
2586
|
+
if (others.length > 0) return { kind: "unknown", reason: "both_installed" };
|
|
2587
|
+
return { kind: "owned", name: only };
|
|
2588
|
+
};
|
|
2589
|
+
var decideCommandOwner = (evidence) => {
|
|
2590
|
+
const { link } = evidence;
|
|
2591
|
+
if (link.kind === "resolved") {
|
|
2592
|
+
const name = CLI_PACKAGE_NAMES.find((candidate) => linkPointsInto(evidence, link.targets, candidate));
|
|
2593
|
+
return name === void 0 ? { kind: "unknown", reason: "foreign_command" } : { kind: "owned", name };
|
|
2594
|
+
}
|
|
2595
|
+
const whenNone = link.kind === "absent" ? { kind: "none" } : { kind: "unknown", reason: "unreadable_command" };
|
|
2596
|
+
return ownerFromInstalled(evidence.installed, whenNone);
|
|
2597
|
+
};
|
|
2598
|
+
var CMD_SHIM_TARGET = /"%(?:~dp0|dp0%)\\([^"]+?)"\s+%[*]/;
|
|
2599
|
+
var cmdShimTarget = (shimDir, contents) => {
|
|
2600
|
+
const relativeTarget = CMD_SHIM_TARGET.exec(contents)?.[1];
|
|
2601
|
+
return relativeTarget === void 0 ? void 0 : win32.resolve(shimDir, relativeTarget);
|
|
2602
|
+
};
|
|
2603
|
+
var launchedPackage = (ownName) => ownName ?? LEGACY_PACKAGE;
|
|
2604
|
+
var globalInstallTarget = (owner, ownName) => {
|
|
2605
|
+
switch (owner.kind) {
|
|
2606
|
+
case "owned":
|
|
2607
|
+
return owner.name;
|
|
2608
|
+
case "none":
|
|
2609
|
+
return launchedPackage(ownName);
|
|
2610
|
+
case "unknown":
|
|
2611
|
+
return LEGACY_PACKAGE;
|
|
2612
|
+
}
|
|
2613
|
+
};
|
|
2614
|
+
var isRecord2 = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
|
|
2615
|
+
var declaresOwnershipProbe = (bin) => isRecord2(bin) && typeof bin[OWNERSHIP_PROBE_COMMAND] === "string";
|
|
2616
|
+
var cliManifestName = (manifest) => {
|
|
2617
|
+
if (!isRecord2(manifest) || !isCliPackageName(manifest.name) || !declaresOwnershipProbe(manifest.bin)) return void 0;
|
|
2618
|
+
return manifest.name;
|
|
2619
|
+
};
|
|
2620
|
+
var classifyGlobalFolder = (name, read) => {
|
|
2621
|
+
if (read.kind === "unreadable") return { kind: "unseen" };
|
|
2622
|
+
const { manifest } = read;
|
|
2623
|
+
if (!isRecord2(manifest) || cliManifestName(manifest) !== name) return { kind: "foreign" };
|
|
2624
|
+
return { kind: "ours", installed: { name, version: typeof manifest.version === "string" ? manifest.version : void 0 } };
|
|
2625
|
+
};
|
|
2626
|
+
var classifyGlobalInstall = (installed, owner) => {
|
|
2627
|
+
const [only, ...others] = installed;
|
|
2628
|
+
if (only === void 0) return { kind: "absent" };
|
|
2629
|
+
if (others.length === 0) return { kind: "single", installed: only };
|
|
2630
|
+
return { kind: "both", installed, owner };
|
|
2631
|
+
};
|
|
2632
|
+
var isUninstallable = (evidence) => evidence.listing !== "absent" && evidence.folder !== "foreign";
|
|
2633
|
+
var globalPackagesToUninstall = (evidence) => evidence.filter(isUninstallable).map((entry) => entry.name);
|
|
2634
|
+
var commandsPackage = (install) => {
|
|
2635
|
+
if (install.kind === "single") return install.installed;
|
|
2636
|
+
if (install.kind !== "both" || install.owner.kind !== "owned") return void 0;
|
|
2637
|
+
const ownerName = install.owner.name;
|
|
2638
|
+
return install.installed.find((installed) => installed.name === ownerName);
|
|
2639
|
+
};
|
|
2640
|
+
|
|
2542
2641
|
// src/cli/version.ts
|
|
2543
2642
|
import { readFileSync } from "fs";
|
|
2544
2643
|
import { dirname, join, parse } from "path";
|
|
2545
2644
|
import { fileURLToPath } from "url";
|
|
2546
|
-
var PACKAGE_NAME = "@pushary/agent-hooks";
|
|
2547
2645
|
var UNKNOWN_VERSION = "0.0.0";
|
|
2548
|
-
var
|
|
2646
|
+
var cliManifestNameAt = (manifestPath) => {
|
|
2647
|
+
try {
|
|
2648
|
+
return cliManifestName(JSON.parse(readFileSync(manifestPath, "utf-8")));
|
|
2649
|
+
} catch {
|
|
2650
|
+
return void 0;
|
|
2651
|
+
}
|
|
2652
|
+
};
|
|
2653
|
+
var findOwnPackage = (start) => {
|
|
2549
2654
|
const { root } = parse(start);
|
|
2550
2655
|
let dir = start;
|
|
2551
2656
|
while (true) {
|
|
2552
|
-
const
|
|
2553
|
-
|
|
2554
|
-
const pkg = JSON.parse(readFileSync(candidate, "utf-8"));
|
|
2555
|
-
if (pkg.name === PACKAGE_NAME) return candidate;
|
|
2556
|
-
} catch {
|
|
2557
|
-
}
|
|
2657
|
+
const name = cliManifestNameAt(join(dir, "package.json"));
|
|
2658
|
+
if (name !== void 0) return { root: dir, name };
|
|
2558
2659
|
if (dir === root) return void 0;
|
|
2559
2660
|
const parent = dirname(dir);
|
|
2560
2661
|
if (parent === dir) return void 0;
|
|
2561
2662
|
dir = parent;
|
|
2562
2663
|
}
|
|
2563
2664
|
};
|
|
2564
|
-
var
|
|
2565
|
-
const root = ownPackageRoot();
|
|
2566
|
-
return (root === void 0 ? void 0 : packageVersionAt(root)) ?? UNKNOWN_VERSION;
|
|
2567
|
-
};
|
|
2568
|
-
var ownPackageRoot = () => {
|
|
2665
|
+
var runningPackage = () => {
|
|
2569
2666
|
try {
|
|
2570
|
-
|
|
2571
|
-
return found ? dirname(found) : void 0;
|
|
2667
|
+
return findOwnPackage(dirname(fileURLToPath(import.meta.url)));
|
|
2572
2668
|
} catch {
|
|
2573
2669
|
return void 0;
|
|
2574
2670
|
}
|
|
2575
2671
|
};
|
|
2672
|
+
var getPackageVersion = () => {
|
|
2673
|
+
const root = ownPackageRoot();
|
|
2674
|
+
return (root === void 0 ? void 0 : packageVersionAt(root)) ?? UNKNOWN_VERSION;
|
|
2675
|
+
};
|
|
2676
|
+
var ownPackageRoot = () => runningPackage()?.root;
|
|
2677
|
+
var ownPackageName = () => runningPackage()?.name;
|
|
2576
2678
|
var packageVersionAt = (packageRoot) => {
|
|
2577
2679
|
try {
|
|
2578
2680
|
const manifest = JSON.parse(readFileSync(join(packageRoot, "package.json"), "utf-8"));
|
|
@@ -2657,6 +2759,9 @@ export {
|
|
|
2657
2759
|
isValidApiKey,
|
|
2658
2760
|
ACTION_BODY_MAX,
|
|
2659
2761
|
DECISION_LINE_MAX,
|
|
2762
|
+
ASK_QUESTION_MAX,
|
|
2763
|
+
ASK_AGENT_NAME_MAX,
|
|
2764
|
+
truncateLine,
|
|
2660
2765
|
isAnswerSource,
|
|
2661
2766
|
buildDecisionEpisodeFeatures,
|
|
2662
2767
|
resolveAutoResolveOrigin,
|
|
@@ -2700,8 +2805,26 @@ export {
|
|
|
2700
2805
|
planElicitationAsk,
|
|
2701
2806
|
elicitationContent,
|
|
2702
2807
|
elicitationContentFromAnswers,
|
|
2808
|
+
CANONICAL_PACKAGE,
|
|
2809
|
+
LEGACY_PACKAGE,
|
|
2810
|
+
CLI_PACKAGE_NAMES,
|
|
2811
|
+
cliPackagePathSegments,
|
|
2812
|
+
OWNERSHIP_PROBE_COMMAND,
|
|
2813
|
+
POSIX_GLOBAL_ROOT_SEGMENTS,
|
|
2814
|
+
globalRootFor,
|
|
2815
|
+
globalPackageFolder,
|
|
2816
|
+
globalUpgradeEntry,
|
|
2817
|
+
decideCommandOwner,
|
|
2818
|
+
cmdShimTarget,
|
|
2819
|
+
launchedPackage,
|
|
2820
|
+
globalInstallTarget,
|
|
2821
|
+
classifyGlobalFolder,
|
|
2822
|
+
classifyGlobalInstall,
|
|
2823
|
+
globalPackagesToUninstall,
|
|
2824
|
+
commandsPackage,
|
|
2703
2825
|
getPackageVersion,
|
|
2704
2826
|
ownPackageRoot,
|
|
2827
|
+
ownPackageName,
|
|
2705
2828
|
packageVersionAt,
|
|
2706
2829
|
isNewerVersion,
|
|
2707
2830
|
isReleaseVersion,
|
|
@@ -3,23 +3,25 @@ import {
|
|
|
3
3
|
} from "./chunk-POFBE6ZY.js";
|
|
4
4
|
import {
|
|
5
5
|
autoUpdateState
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-UPLV5AJF.js";
|
|
7
7
|
import {
|
|
8
8
|
readJsonSafe,
|
|
9
9
|
writeJsonAtomic
|
|
10
10
|
} from "./chunk-T7E75EKA.js";
|
|
11
11
|
import {
|
|
12
|
+
CLI_PACKAGE_NAMES,
|
|
13
|
+
POSIX_GLOBAL_ROOT_SEGMENTS,
|
|
14
|
+
cliPackagePathSegments,
|
|
15
|
+
globalUpgradeEntry,
|
|
12
16
|
ownPackageRoot
|
|
13
|
-
} from "./chunk-
|
|
17
|
+
} from "./chunk-5YY3IJT4.js";
|
|
14
18
|
|
|
15
19
|
// src/auto-update.ts
|
|
16
20
|
import { spawn } from "child_process";
|
|
17
|
-
import { dirname
|
|
21
|
+
import { dirname } from "path";
|
|
18
22
|
var AUTO_UPDATE_DISABLE_ENV = "PUSHARY_DISABLE_AUTOUPDATE";
|
|
19
23
|
var AUTO_UPDATE_INTERVAL_MS = 24 * 60 * 60 * 1e3;
|
|
20
24
|
var AUTO_UPDATE_FLAG = "--auto";
|
|
21
|
-
var GLOBAL_PACKAGE_SUBPATH = "/lib/node_modules/@pushary/agent-hooks";
|
|
22
|
-
var UPGRADE_ENTRY_SUBPATH = ["dist", "bin", "pushary-upgrade.js"];
|
|
23
25
|
var NON_GLOBAL_INSTALL_SEGMENTS = ["/_npx/", "/.volta/"];
|
|
24
26
|
var AUTO_UPDATE_RESULTS = ["updated", "current", "needs_manual", "failed", "finish_pending"];
|
|
25
27
|
var isRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
|
|
@@ -55,14 +57,24 @@ var autoUpdateOffReason = (input) => {
|
|
|
55
57
|
if (input.platform === "linux") return "linux";
|
|
56
58
|
return null;
|
|
57
59
|
};
|
|
58
|
-
var
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
if (
|
|
62
|
-
const prefix = root.slice(0, -
|
|
60
|
+
var globalPackageSubpath = (name) => `/${[...POSIX_GLOBAL_ROOT_SEGMENTS, ...cliPackagePathSegments(name)].join("/")}`;
|
|
61
|
+
var prefixOfGlobalPackage = (root, name) => {
|
|
62
|
+
const subpath = globalPackageSubpath(name);
|
|
63
|
+
if (!root.endsWith(subpath)) return null;
|
|
64
|
+
const prefix = root.slice(0, -subpath.length);
|
|
63
65
|
return prefix.startsWith("/") ? prefix : null;
|
|
64
66
|
};
|
|
65
|
-
var
|
|
67
|
+
var isNonGlobalInstall = (root) => NON_GLOBAL_INSTALL_SEGMENTS.some((segment) => root.includes(segment));
|
|
68
|
+
var globalInstallLocation = (packageRoot) => {
|
|
69
|
+
const root = packageRoot.replace(/\/+$/, "");
|
|
70
|
+
if (isNonGlobalInstall(root)) return null;
|
|
71
|
+
for (const packageName of CLI_PACKAGE_NAMES) {
|
|
72
|
+
const prefix = prefixOfGlobalPackage(root, packageName);
|
|
73
|
+
if (prefix !== null) return { prefix, packageName };
|
|
74
|
+
}
|
|
75
|
+
return null;
|
|
76
|
+
};
|
|
77
|
+
var upgradeEntryFor = (location, platform = process.platform) => globalUpgradeEntry(location.prefix, location.packageName, platform);
|
|
66
78
|
var checkedWithinInterval = (lastCheckAt, now) => {
|
|
67
79
|
const last = lastCheckAt === void 0 ? Number.NaN : Date.parse(lastCheckAt);
|
|
68
80
|
if (Number.isNaN(last)) return false;
|
|
@@ -73,10 +85,10 @@ var autoUpdateDecision = (input) => {
|
|
|
73
85
|
if (input.isSubagentStart) return { kind: "skip", reason: "subagent_start" };
|
|
74
86
|
const offReason = autoUpdateOffReason(input);
|
|
75
87
|
if (offReason !== null) return { kind: "skip", reason: offReason };
|
|
76
|
-
const
|
|
77
|
-
if (
|
|
88
|
+
const location = input.packageRoot === void 0 ? null : globalInstallLocation(input.packageRoot);
|
|
89
|
+
if (location === null) return { kind: "skip", reason: "not_global_install" };
|
|
78
90
|
if (checkedWithinInterval(input.state.lastCheckAt, input.now)) return { kind: "skip", reason: "checked_recently" };
|
|
79
|
-
return { kind: "check",
|
|
91
|
+
return { kind: "check", ...location };
|
|
80
92
|
};
|
|
81
93
|
var parseAutoUpdateFlag = (args) => {
|
|
82
94
|
const token = args.find((arg) => arg === AUTO_UPDATE_FLAG || arg.startsWith(`${AUTO_UPDATE_FLAG}=`));
|
|
@@ -141,7 +153,7 @@ var triggerAutoUpdate = (trigger) => {
|
|
|
141
153
|
if (decision.kind === "skip") return decision;
|
|
142
154
|
updateAutoUpdateState(statePath, { lastCheckAt: new Date(now).toISOString() });
|
|
143
155
|
const spawnUpgrade = trigger.spawn ?? spawnDetached;
|
|
144
|
-
spawnUpgrade(trigger.execPath ?? process.execPath, [upgradeEntryFor(decision
|
|
156
|
+
spawnUpgrade(trigger.execPath ?? process.execPath, [upgradeEntryFor(decision), AUTO_UPDATE_FLAG], dirname(statePath));
|
|
145
157
|
return decision;
|
|
146
158
|
} catch {
|
|
147
159
|
return null;
|
|
@@ -152,7 +164,7 @@ export {
|
|
|
152
164
|
AUTO_UPDATE_DISABLE_ENV,
|
|
153
165
|
isAutoUpdateDisabledByEnv,
|
|
154
166
|
autoUpdateOffReason,
|
|
155
|
-
|
|
167
|
+
globalInstallLocation,
|
|
156
168
|
upgradeEntryFor,
|
|
157
169
|
parseAutoUpdateFlag,
|
|
158
170
|
describeAutoUpdateCheck,
|