@pushary/agent-hooks 1.9.65 → 1.9.67
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 +18 -0
- package/data/SKILL.md +1 -1
- package/data/cursor-plugin/skills/pushary/SKILL.md +1 -1
- package/data/vscode-plugin/skills/pushary/SKILL.md +1 -1
- package/dist/{api-32B3XLJR.js → api-3WIPD5GC.js} +12 -10
- package/dist/bin/pushary-bell-hook.js +25 -27
- package/dist/bin/pushary-bell.js +10 -10
- package/dist/bin/pushary-claude.js +26 -28
- package/dist/bin/pushary-clean.js +74 -77
- package/dist/bin/pushary-codex-bridge.js +21 -22
- package/dist/bin/pushary-codex-hook.js +30 -32
- package/dist/bin/pushary-codex-session.js +8 -8
- package/dist/bin/pushary-codex.js +13 -13
- package/dist/bin/pushary-connect.js +28 -28
- package/dist/bin/pushary-cowork.js +5 -5
- package/dist/bin/pushary-daemon.js +40 -41
- package/dist/bin/pushary-disconnect.js +25 -26
- package/dist/bin/pushary-doctor.js +118 -76
- package/dist/bin/pushary-elicitation-hook.js +25 -27
- package/dist/bin/pushary-gemini-bridge.js +15 -16
- package/dist/bin/pushary-gemini-hook.js +27 -29
- package/dist/bin/pushary-hook.js +29 -31
- package/dist/bin/pushary-login.js +20 -19
- package/dist/bin/pushary-logout.js +26 -28
- package/dist/bin/pushary-mcp.js +11 -11
- package/dist/bin/pushary-mode.js +16 -15
- package/dist/bin/pushary-notification-hook.js +24 -26
- package/dist/bin/pushary-opencode-hook.js +26 -28
- package/dist/bin/pushary-permission-denied-hook.js +29 -31
- package/dist/bin/pushary-permission-hook.js +32 -31
- package/dist/bin/pushary-post-hook.js +24 -26
- package/dist/bin/pushary-prompt-hook.js +24 -26
- package/dist/bin/pushary-session-end-hook.js +26 -28
- package/dist/bin/pushary-session-start-hook.js +34 -35
- package/dist/bin/pushary-setup.js +111 -99
- package/dist/bin/pushary-stats.js +5 -5
- package/dist/bin/pushary-status.js +37 -36
- package/dist/bin/pushary-stop-hook.js +24 -26
- package/dist/bin/pushary-stopfailure-hook.js +24 -26
- package/dist/bin/pushary-suggestions.js +15 -14
- package/dist/bin/pushary-transcript-register.js +16 -18
- package/dist/bin/pushary-transcripts.js +18 -17
- package/dist/bin/pushary-upgrade.js +45 -39
- package/dist/bin/pushary-wait.js +26 -20
- package/dist/bin/pushary.js +7 -7
- package/dist/{chunk-Y64JGYTB.js → chunk-32OSSYGZ.js} +1 -1
- package/dist/{chunk-UHS5MMAI.js → chunk-3THDNNVL.js} +3 -3
- package/dist/{chunk-OA6EADFT.js → chunk-564IPPBL.js} +3 -3
- package/dist/chunk-5MOJCOCF.js +25 -0
- package/dist/{chunk-RRHHWYPX.js → chunk-6H4E5UBA.js} +6 -6
- package/dist/{chunk-UM2X7HL6.js → chunk-6LXXKMV6.js} +42 -16
- package/dist/chunk-76SWHCAR.js +299 -0
- package/dist/{chunk-AN7C3CHH.js → chunk-77L2TNJW.js} +1 -1
- package/dist/{chunk-XJIIU36L.js → chunk-7YJSDXLM.js} +1 -1
- package/dist/{chunk-XZCJC3QO.js → chunk-B3V2WOJX.js} +285 -50
- package/dist/{chunk-RABLE5R6.js → chunk-BBFGDYYI.js} +1 -1
- package/dist/{chunk-GTBWWCCM.js → chunk-BFF3ABFV.js} +115 -9
- package/dist/{chunk-NOH3EJFH.js → chunk-C4EDAHXI.js} +1 -1
- package/dist/{chunk-ITYKN2K3.js → chunk-CHYBOTQN.js} +2 -2
- package/dist/{chunk-FFSIYBBU.js → chunk-CJZLIAJF.js} +27 -10
- package/dist/{chunk-UMTMFDL2.js → chunk-CPLQ5OHX.js} +1 -1
- package/dist/{chunk-DTVHZDYM.js → chunk-D3U6CN7T.js} +26 -12
- package/dist/{chunk-ICFHMJTW.js → chunk-D7Z4USSB.js} +27 -8
- package/dist/{chunk-DXMUJTYF.js → chunk-DP6LU6BB.js} +2 -2
- package/dist/{chunk-GA257T2E.js → chunk-DXCHIKAN.js} +8 -8
- package/dist/{chunk-PP7FC3Y7.js → chunk-EQR6JSFE.js} +9 -7
- package/dist/{chunk-Z3M627TQ.js → chunk-FONWVVDD.js} +1 -1
- package/dist/{chunk-3KXBRSL3.js → chunk-GMHQYX3D.js} +1 -1
- package/dist/{chunk-WY6YAMZW.js → chunk-ICQCQAUO.js} +5 -4
- package/dist/{chunk-CZ65D6Q5.js → chunk-IPG3RS23.js} +2 -2
- package/dist/{chunk-JCWHOB36.js → chunk-IRV2MNMA.js} +53 -3
- package/dist/{chunk-HIYLAC3C.js → chunk-IVB5O6NY.js} +3 -3
- package/dist/{chunk-DM24VZOI.js → chunk-IXTVUINH.js} +3 -3
- package/dist/{chunk-BEQ3MEE3.js → chunk-JBRMIADM.js} +2 -2
- package/dist/{chunk-CU2PXLZ6.js → chunk-JHB5SR5B.js} +4 -4
- package/dist/{chunk-ED2SWTPC.js → chunk-JOBSKQ2Z.js} +4 -4
- package/dist/{chunk-W5L2ZLHE.js → chunk-JOD2325S.js} +3 -3
- package/dist/{chunk-CSKABVSH.js → chunk-JSPCGPSH.js} +3 -3
- package/dist/{chunk-R4FL5JHK.js → chunk-KE4TSJUD.js} +4 -4
- package/dist/{chunk-3LF7T3NW.js → chunk-KIXRHNCW.js} +6 -6
- package/dist/{chunk-BKCI53W6.js → chunk-KNUYUQBP.js} +4 -4
- package/dist/{chunk-4LUWNBGD.js → chunk-KTLE7NIK.js} +23 -8
- package/dist/{chunk-ADXHPGBZ.js → chunk-LJHDUKBB.js} +6 -6
- package/dist/{chunk-U2P2LQ5B.js → chunk-LS42NV6E.js} +15 -6
- package/dist/{chunk-QNZ6G3LY.js → chunk-LYTWK5TF.js} +5 -5
- package/dist/{chunk-2VADJ6JH.js → chunk-METUT7V4.js} +2 -2
- package/dist/{chunk-P5HZEGT7.js → chunk-NSS2AIGI.js} +6 -6
- package/dist/{chunk-QSW3HAKI.js → chunk-NWN6GGJL.js} +61 -2
- package/dist/{chunk-7ILQX47W.js → chunk-P4RXSZDT.js} +3 -3
- package/dist/{chunk-FWS2KLV2.js → chunk-PIBWX3EF.js} +2 -2
- package/dist/{chunk-F56GTJFG.js → chunk-PO2P3XDC.js} +5 -5
- package/dist/{chunk-EEVE7H5Z.js → chunk-R2BZH2NK.js} +4 -4
- package/dist/{chunk-I2UBF2SS.js → chunk-RO2B4YBF.js} +1 -1
- package/dist/{chunk-MNKIR2ZB.js → chunk-RQOT6QL3.js} +67 -6
- package/dist/{chunk-Q2BD4IBX.js → chunk-SB6TYV4M.js} +11 -13
- package/dist/{chunk-ATPJGHUP.js → chunk-TI4JYPGQ.js} +7 -3
- package/dist/{chunk-LMC5UPL7.js → chunk-UC2J5RR4.js} +1 -1
- package/dist/{chunk-IZVEBBDH.js → chunk-UQIPWXBL.js} +3 -3
- package/dist/{chunk-VHKK3US3.js → chunk-UXN73YAE.js} +3 -3
- package/dist/{chunk-WOHP7EL6.js → chunk-VEYFXRZ6.js} +7 -6
- package/dist/{chunk-2Z7I7DHT.js → chunk-VHMZPN3N.js} +1 -1
- package/dist/{chunk-HVOQUPSO.js → chunk-VKZ3RJ5U.js} +1 -1
- package/dist/chunk-VVIQWGS7.js +2298 -0
- package/dist/{chunk-SCMEVDAR.js → chunk-WJLHZ6E6.js} +3 -3
- package/dist/{chunk-BAGBCSXA.js → chunk-X2MTVD4W.js} +1 -1
- package/dist/{chunk-3UNAPXED.js → chunk-XFDWLDHG.js} +9 -9
- package/dist/{chunk-6CZX6YOE.js → chunk-XNUWKKGS.js} +3 -3
- package/dist/{chunk-NUEPJ5W6.js → chunk-XZKSUJ55.js} +3 -5
- package/dist/{chunk-HDGB6SQ4.js → chunk-Y4MRHAE5.js} +2 -2
- package/dist/{chunk-SZBMTOUZ.js → chunk-Y6ZN454E.js} +1 -1
- package/dist/{chunk-TK4JU2F7.js → chunk-YSD4SMHE.js} +1 -1
- package/dist/{chunk-SROWUG5W.js → chunk-ZK5WYAMI.js} +1 -1
- package/dist/{chunk-JFKMPLNF.js → chunk-ZPIYJLQ3.js} +2 -2
- package/dist/{codex-app-cards-switch-HK4RMOBI.js → codex-app-cards-switch-25TDTMUZ.js} +11 -11
- package/dist/{codex-desktop-launch-OCO6N7SA.js → codex-desktop-launch-JDKUCD2Y.js} +1 -1
- package/dist/{codex-session-launch-ETZQTVFS.js → codex-session-launch-6N35AAEO.js} +18 -19
- package/dist/{config-YY54G3CC.js → config-OBGYURFX.js} +3 -3
- package/dist/{global-upgrade-5DN5G3ZQ.js → global-upgrade-2QNQD5OM.js} +10 -10
- package/dist/{identity-EGL6HAWG.js → identity-CUPX2U7Q.js} +4 -4
- package/dist/{live-capabilities-WU3FYJJG.js → live-capabilities-CUEIWMSM.js} +5 -5
- package/dist/{paths-ZG6KDM6Y.js → paths-BHLBZ6FY.js} +7 -3
- package/dist/{reapply-AQLNCCTE.js → reapply-4GXLWZ5M.js} +27 -27
- package/dist/src/index.js +30 -20
- package/dist/{upgrade-lock-BIRXIKHJ.js → upgrade-lock-RDKTAHWR.js} +4 -4
- package/dist/{usage-43C2DHDU.js → usage-KX2HN47E.js} +3 -3
- package/package.json +1 -1
- package/dist/chunk-ANP3DIST.js +0 -118
- package/dist/chunk-ONBL2GCU.js +0 -615
- package/dist/chunk-TJUJAK5L.js +0 -62
|
@@ -1,25 +1,24 @@
|
|
|
1
|
-
import {
|
|
2
|
-
GEMINI_HOOK_EVENTS,
|
|
3
|
-
hasGeminiHooks
|
|
4
|
-
} from "./chunk-ANP3DIST.js";
|
|
5
1
|
import {
|
|
6
2
|
AGENT_CHOICES
|
|
7
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-ZK5WYAMI.js";
|
|
8
4
|
import {
|
|
9
5
|
BELL_HOOK_BINARY
|
|
10
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-FONWVVDD.js";
|
|
11
7
|
import {
|
|
12
8
|
CLAUDE_HOOK_EVENTS,
|
|
13
9
|
CODEX_HOOK_EVENTS,
|
|
14
10
|
HOOK_SHELL,
|
|
15
11
|
hasCodexHooks,
|
|
16
|
-
holdBudgetOf
|
|
17
|
-
|
|
12
|
+
holdBudgetOf,
|
|
13
|
+
isProtectedByScope,
|
|
14
|
+
registerHookEntry
|
|
15
|
+
} from "./chunk-TI4JYPGQ.js";
|
|
18
16
|
import {
|
|
19
17
|
CURSOR_GATE_EVENTS,
|
|
18
|
+
HOOK_BUDGETS,
|
|
20
19
|
HOOK_LOCATOR_BINARY,
|
|
21
20
|
hookCommandHoldBudget
|
|
22
|
-
} from "./chunk-
|
|
21
|
+
} from "./chunk-RQOT6QL3.js";
|
|
23
22
|
|
|
24
23
|
// src/diagnostics/bridge.ts
|
|
25
24
|
import { execFileSync } from "child_process";
|
|
@@ -97,6 +96,105 @@ var liveBridgeProbe = () => ({
|
|
|
97
96
|
home: homedir()
|
|
98
97
|
});
|
|
99
98
|
|
|
99
|
+
// src/gemini-config.ts
|
|
100
|
+
var GEMINI_HOOK_BINARY = "pushary-gemini-hook";
|
|
101
|
+
var GEMINI_MCP_URL = "https://pushary.com/api/mcp/mcp";
|
|
102
|
+
var GEMINI_HOOK_EVENTS = [
|
|
103
|
+
{ event: "BeforeTool", matcher: "run_shell_command|write_file|replace|mcp_.*", delivery: "approval", timeoutMs: HOOK_BUDGETS.gemini.budgetSeconds * 1e3 },
|
|
104
|
+
{ event: "AfterTool", matcher: "run_shell_command|write_file|replace|mcp_.*", delivery: "telemetry", timeoutMs: 1e4 },
|
|
105
|
+
{ event: "BeforeAgent", delivery: "telemetry", timeoutMs: 1e4 },
|
|
106
|
+
{ event: "AfterAgent", delivery: "telemetry", timeoutMs: 1e4 },
|
|
107
|
+
{ event: "SessionStart", delivery: "telemetry", timeoutMs: 1e4 },
|
|
108
|
+
{ event: "SessionEnd", delivery: "telemetry", timeoutMs: 1e4 }
|
|
109
|
+
];
|
|
110
|
+
var asRecord = (value) => value && typeof value === "object" && !Array.isArray(value) ? value : void 0;
|
|
111
|
+
var ensureRecord = (target, key) => {
|
|
112
|
+
const existing = asRecord(target[key]);
|
|
113
|
+
if (existing) return existing;
|
|
114
|
+
const created = {};
|
|
115
|
+
target[key] = created;
|
|
116
|
+
return created;
|
|
117
|
+
};
|
|
118
|
+
var isPusharyGeminiHook = (entry, scope) => {
|
|
119
|
+
const hooks = asRecord(entry)?.hooks;
|
|
120
|
+
if (!Array.isArray(hooks)) return false;
|
|
121
|
+
return hooks.some((hook) => {
|
|
122
|
+
const command = String(asRecord(hook)?.command ?? "");
|
|
123
|
+
if (isProtectedByScope(command, scope)) return false;
|
|
124
|
+
return command.includes(GEMINI_HOOK_BINARY) || command.includes(HOOK_LOCATOR_BINARY);
|
|
125
|
+
});
|
|
126
|
+
};
|
|
127
|
+
var addGeminiMcpServer = (settings, apiKey) => {
|
|
128
|
+
const mcpServers = ensureRecord(settings, "mcpServers");
|
|
129
|
+
mcpServers.pushary = {
|
|
130
|
+
httpUrl: GEMINI_MCP_URL,
|
|
131
|
+
headers: { Authorization: `Bearer ${apiKey}` },
|
|
132
|
+
trust: true
|
|
133
|
+
};
|
|
134
|
+
};
|
|
135
|
+
var addGeminiHooks = (settings, command) => {
|
|
136
|
+
const hooks = ensureRecord(settings, "hooks");
|
|
137
|
+
for (const definition of GEMINI_HOOK_EVENTS) {
|
|
138
|
+
const existing = Array.isArray(hooks[definition.event]) ? hooks[definition.event] : [];
|
|
139
|
+
hooks[definition.event] = registerHookEntry(existing, isPusharyGeminiHook, {
|
|
140
|
+
...definition.matcher ? { matcher: definition.matcher } : {},
|
|
141
|
+
hooks: [{
|
|
142
|
+
name: "pushary",
|
|
143
|
+
type: "command",
|
|
144
|
+
command,
|
|
145
|
+
timeout: definition.timeoutMs
|
|
146
|
+
}]
|
|
147
|
+
});
|
|
148
|
+
}
|
|
149
|
+
};
|
|
150
|
+
var removeGeminiHooks = (settings, scope) => {
|
|
151
|
+
const hooks = asRecord(settings.hooks);
|
|
152
|
+
if (!hooks) return false;
|
|
153
|
+
let changed = false;
|
|
154
|
+
for (const definition of GEMINI_HOOK_EVENTS) {
|
|
155
|
+
const entries = hooks[definition.event];
|
|
156
|
+
if (!Array.isArray(entries)) continue;
|
|
157
|
+
const filtered = entries.filter((entry) => !isPusharyGeminiHook(entry, scope));
|
|
158
|
+
if (filtered.length !== entries.length) {
|
|
159
|
+
if (filtered.length === 0) {
|
|
160
|
+
delete hooks[definition.event];
|
|
161
|
+
} else {
|
|
162
|
+
hooks[definition.event] = filtered;
|
|
163
|
+
}
|
|
164
|
+
changed = true;
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
if (Object.keys(hooks).length === 0) delete settings.hooks;
|
|
168
|
+
return changed;
|
|
169
|
+
};
|
|
170
|
+
var removeGeminiMcpServer = (settings) => {
|
|
171
|
+
const mcpServers = asRecord(settings.mcpServers);
|
|
172
|
+
if (!mcpServers?.pushary) return false;
|
|
173
|
+
delete mcpServers.pushary;
|
|
174
|
+
if (Object.keys(mcpServers).length === 0) delete settings.mcpServers;
|
|
175
|
+
return true;
|
|
176
|
+
};
|
|
177
|
+
var removeGeminiSettings = (settings, scope) => {
|
|
178
|
+
const mcpRemoved = scope?.keepMcpServer === true ? false : removeGeminiMcpServer(settings);
|
|
179
|
+
const hooksRemoved = removeGeminiHooks(settings, scope);
|
|
180
|
+
return mcpRemoved || hooksRemoved;
|
|
181
|
+
};
|
|
182
|
+
var hasGeminiHooks = (settings) => {
|
|
183
|
+
const hooks = asRecord(settings.hooks);
|
|
184
|
+
if (!hooks) return false;
|
|
185
|
+
return GEMINI_HOOK_EVENTS.some((definition) => {
|
|
186
|
+
const entries = hooks[definition.event];
|
|
187
|
+
return Array.isArray(entries) && entries.some((entry) => isPusharyGeminiHook(entry));
|
|
188
|
+
});
|
|
189
|
+
};
|
|
190
|
+
var missingGeminiHookEvents = (settings) => {
|
|
191
|
+
const hooks = asRecord(settings.hooks);
|
|
192
|
+
return GEMINI_HOOK_EVENTS.filter((definition) => {
|
|
193
|
+
const entries = hooks?.[definition.event];
|
|
194
|
+
return !Array.isArray(entries) || !entries.some((entry) => isPusharyGeminiHook(entry));
|
|
195
|
+
}).map((definition) => definition.event);
|
|
196
|
+
};
|
|
197
|
+
|
|
100
198
|
// src/diagnostics/wiring.ts
|
|
101
199
|
var record = (value) => value && typeof value === "object" && !Array.isArray(value) ? value : null;
|
|
102
200
|
var CLAUDE_HOOK_BINARY = /pushary-[a-z-]*hook/;
|
|
@@ -326,6 +424,14 @@ export {
|
|
|
326
424
|
describeBridgeResolution,
|
|
327
425
|
isBridgeLocator,
|
|
328
426
|
liveBridgeProbe,
|
|
427
|
+
GEMINI_HOOK_BINARY,
|
|
428
|
+
GEMINI_HOOK_EVENTS,
|
|
429
|
+
addGeminiMcpServer,
|
|
430
|
+
addGeminiHooks,
|
|
431
|
+
removeGeminiMcpServer,
|
|
432
|
+
removeGeminiSettings,
|
|
433
|
+
hasGeminiHooks,
|
|
434
|
+
missingGeminiHookEvents,
|
|
329
435
|
pusharyHookExecutable,
|
|
330
436
|
claudeWired,
|
|
331
437
|
codexWired,
|
|
@@ -4,10 +4,10 @@ import {
|
|
|
4
4
|
keyPrefix,
|
|
5
5
|
readConfigFileKey,
|
|
6
6
|
readMacAppKeyPrefix
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-JOBSKQ2Z.js";
|
|
8
8
|
import {
|
|
9
9
|
NPX_LATEST_COMMAND
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-X2MTVD4W.js";
|
|
11
11
|
|
|
12
12
|
// src/key-signed-out.ts
|
|
13
13
|
var VERDICT_BY_CHECK = {
|
|
@@ -2,25 +2,31 @@ import {
|
|
|
2
2
|
SIGNED_OUT_ON_MAC_MESSAGE,
|
|
3
3
|
describeSignedOutKey,
|
|
4
4
|
readSignedOutDiagnosis
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-CHYBOTQN.js";
|
|
6
|
+
import {
|
|
7
|
+
APPROVAL_RULES_PATH
|
|
8
|
+
} from "./chunk-5MOJCOCF.js";
|
|
6
9
|
import {
|
|
7
10
|
createIo
|
|
8
11
|
} from "./chunk-FO3MDD26.js";
|
|
9
12
|
import {
|
|
10
13
|
readKeySource
|
|
11
|
-
} from "./chunk-
|
|
14
|
+
} from "./chunk-JOBSKQ2Z.js";
|
|
12
15
|
import {
|
|
13
16
|
absoluteUrl,
|
|
14
17
|
checkApiKey,
|
|
15
18
|
describeKeyCheck,
|
|
16
19
|
keyCheckFromResponse
|
|
17
|
-
} from "./chunk-
|
|
20
|
+
} from "./chunk-3THDNNVL.js";
|
|
18
21
|
import {
|
|
19
22
|
EXIT
|
|
20
23
|
} from "./chunk-KZERVKTD.js";
|
|
21
24
|
import {
|
|
22
25
|
getBaseUrl
|
|
23
|
-
} from "./chunk-
|
|
26
|
+
} from "./chunk-32OSSYGZ.js";
|
|
27
|
+
import {
|
|
28
|
+
KEY_SCOPE
|
|
29
|
+
} from "./chunk-RQOT6QL3.js";
|
|
24
30
|
|
|
25
31
|
// src/cli/report-key.ts
|
|
26
32
|
var { dim, yellow } = createIo();
|
|
@@ -61,16 +67,28 @@ var exitOnFailedResponse = async (response, baseUrl) => {
|
|
|
61
67
|
};
|
|
62
68
|
var REFUSED_SETTINGS_ACTION = {
|
|
63
69
|
mode: "change the approval mode",
|
|
70
|
+
mode_clear: "end a temporary approval mode",
|
|
64
71
|
wait: "change how long approvals wait for you",
|
|
65
72
|
suggestions: "read or accept rule suggestions"
|
|
66
73
|
};
|
|
67
|
-
var
|
|
68
|
-
|
|
69
|
-
|
|
74
|
+
var settingsChangeStep = (request, baseUrl) => {
|
|
75
|
+
const approvalRules = absoluteUrl(baseUrl, APPROVAL_RULES_PATH);
|
|
76
|
+
switch (request) {
|
|
77
|
+
case "mode":
|
|
78
|
+
return `Change it in the Pushary app, or on the dashboard: ${approvalRules}`;
|
|
79
|
+
case "mode_clear":
|
|
80
|
+
return "A temporary mode ends on its own. To end it now, pick a mode in the Pushary app.";
|
|
81
|
+
case "wait":
|
|
82
|
+
return `Change it on the dashboard: ${approvalRules}`;
|
|
83
|
+
case "suggestions":
|
|
84
|
+
return `Review them on the dashboard: ${approvalRules}`;
|
|
85
|
+
}
|
|
86
|
+
};
|
|
87
|
+
var isAgentKeyRefusal = (status, check) => status === 401 && check.kind === "ok" && check.identity.keyScope === KEY_SCOPE.agent;
|
|
70
88
|
var describeAgentKeyRefusal = (request, baseUrl = getBaseUrl()) => ({
|
|
71
|
-
message: `This computer's key cannot ${REFUSED_SETTINGS_ACTION[request]}.
|
|
89
|
+
message: `This computer's key cannot ${REFUSED_SETTINGS_ACTION[request]}. It runs approvals and notifications, not account settings.`,
|
|
72
90
|
next: [
|
|
73
|
-
|
|
91
|
+
settingsChangeStep(request, baseUrl),
|
|
74
92
|
"The key itself is valid. Nothing on this computer needs fixing."
|
|
75
93
|
],
|
|
76
94
|
exitCode: EXIT.USAGE,
|
|
@@ -90,6 +108,5 @@ var exitOnFailedSettingsRequest = async (response, settings) => {
|
|
|
90
108
|
|
|
91
109
|
export {
|
|
92
110
|
printKeyCheck,
|
|
93
|
-
APPROVAL_SETTINGS_PATH,
|
|
94
111
|
exitOnFailedSettingsRequest
|
|
95
112
|
};
|
|
@@ -6,18 +6,18 @@ import {
|
|
|
6
6
|
McpToolError,
|
|
7
7
|
SubscriptionRequiredError,
|
|
8
8
|
callMcpTool
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-KNUYUQBP.js";
|
|
10
10
|
import {
|
|
11
11
|
installNetworkDefaults,
|
|
12
12
|
isNetworkFailure
|
|
13
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-P4RXSZDT.js";
|
|
14
14
|
import {
|
|
15
15
|
clientReportClaims
|
|
16
|
-
} from "./chunk-
|
|
16
|
+
} from "./chunk-TI4JYPGQ.js";
|
|
17
17
|
import {
|
|
18
18
|
getApiKey,
|
|
19
19
|
getBaseUrl
|
|
20
|
-
} from "./chunk-
|
|
20
|
+
} from "./chunk-32OSSYGZ.js";
|
|
21
21
|
import {
|
|
22
22
|
ASK_AGENT_NAME_MAX,
|
|
23
23
|
CLIENT_REPORT_PATH,
|
|
@@ -26,7 +26,7 @@ import {
|
|
|
26
26
|
TOOL_FAILURE_CODES,
|
|
27
27
|
degradedLine,
|
|
28
28
|
truncateLine
|
|
29
|
-
} from "./chunk-
|
|
29
|
+
} from "./chunk-RQOT6QL3.js";
|
|
30
30
|
|
|
31
31
|
// src/api.ts
|
|
32
32
|
import { randomUUID } from "crypto";
|
|
@@ -235,25 +235,38 @@ var nextLongPollMs = (deadlineMs, nowMs) => {
|
|
|
235
235
|
const hold = Math.min(deadlineMs - nowMs - WAIT_RESPONSE_GRACE_MS, MAX_LONG_POLL_MS);
|
|
236
236
|
return hold >= MIN_LONG_POLL_MS ? hold : null;
|
|
237
237
|
};
|
|
238
|
-
var
|
|
239
|
-
|
|
238
|
+
var ABANDONED_WAIT = { answered: false, status: "abandoned" };
|
|
239
|
+
var sleepUnlessAborted = (ms, signal) => new Promise((resolve) => {
|
|
240
|
+
const wake = () => {
|
|
241
|
+
clearTimeout(timer);
|
|
242
|
+
signal?.removeEventListener("abort", wake);
|
|
243
|
+
resolve();
|
|
244
|
+
};
|
|
245
|
+
const timer = setTimeout(wake, ms);
|
|
246
|
+
signal?.addEventListener("abort", wake, { once: true });
|
|
247
|
+
});
|
|
248
|
+
var boundedBy = (timeoutMs, signal) => signal ? AbortSignal.any([AbortSignal.timeout(timeoutMs), signal]) : AbortSignal.timeout(timeoutMs);
|
|
249
|
+
var pollForAnswer = async (apiKey, correlationId, deadlineMs, pollInterval = 2e3, signal) => {
|
|
240
250
|
while (Date.now() < deadlineMs) {
|
|
251
|
+
if (signal?.aborted) return ABANDONED_WAIT;
|
|
241
252
|
const hold = nextLongPollMs(deadlineMs, Date.now());
|
|
242
253
|
if (hold === null) {
|
|
243
|
-
await
|
|
254
|
+
await sleepUnlessAborted(Math.max(0, deadlineMs - Date.now()), signal);
|
|
244
255
|
continue;
|
|
245
256
|
}
|
|
246
257
|
let answer;
|
|
247
258
|
try {
|
|
248
|
-
answer = await waitForAnswer(apiKey, correlationId, hold,
|
|
259
|
+
answer = await waitForAnswer(apiKey, correlationId, hold, boundedBy(Math.max(1, deadlineMs - Date.now()), signal));
|
|
249
260
|
} catch {
|
|
261
|
+
if (signal?.aborted) return ABANDONED_WAIT;
|
|
250
262
|
const late = await withdrawQuestion(apiKey, correlationId);
|
|
251
263
|
return late.answered ? late : STOPPED;
|
|
252
264
|
}
|
|
253
265
|
if (isDecisionStopped(answer) || answer.answered) return answer;
|
|
254
266
|
if (answer.status === "expired") return STOPPED;
|
|
255
|
-
await
|
|
267
|
+
await sleepUnlessAborted(Math.min(pollInterval, Math.max(0, deadlineMs - Date.now())), signal);
|
|
256
268
|
}
|
|
269
|
+
if (signal?.aborted) return ABANDONED_WAIT;
|
|
257
270
|
return withdrawQuestion(apiKey, correlationId);
|
|
258
271
|
};
|
|
259
272
|
var cancelQuestion = async (apiKey, correlationId, signal, baseUrl) => {
|
|
@@ -271,10 +284,10 @@ var withdrawQuestion = async (apiKey, correlationId, transport = { cancelQuestio
|
|
|
271
284
|
return STOPPED;
|
|
272
285
|
}
|
|
273
286
|
};
|
|
274
|
-
var waitForQuestion = async (apiKey, question, deadlineMs, pollInterval = 2e3) => {
|
|
287
|
+
var waitForQuestion = async (apiKey, question, deadlineMs, pollInterval = 2e3, signal) => {
|
|
275
288
|
if (isDecisionStopped(question) || question.answered) return { ...question, answered: !!question.answered };
|
|
276
289
|
if (question.status === "expired") return STOPPED;
|
|
277
|
-
return isAwayPaused(question) || isLocalQuestionHandoff(question) ? withdrawQuestion(apiKey, question.correlationId) : pollForAnswer(apiKey, question.correlationId, deadlineMs, pollInterval);
|
|
290
|
+
return isAwayPaused(question) || isLocalQuestionHandoff(question) ? withdrawQuestion(apiKey, question.correlationId) : pollForAnswer(apiKey, question.correlationId, deadlineMs, pollInterval, signal);
|
|
278
291
|
};
|
|
279
292
|
var sendNotification = async (apiKey, params, timeoutMs = 15e3, signal) => {
|
|
280
293
|
await callMcpTool(apiKey, "send_notification", { ...params }, { maxRetries: signal ? 1 : 3, timeoutMs, signal });
|
|
@@ -328,6 +341,7 @@ export {
|
|
|
328
341
|
waitForAnswer,
|
|
329
342
|
WAIT_RESPONSE_GRACE_MS,
|
|
330
343
|
nextLongPollMs,
|
|
344
|
+
ABANDONED_WAIT,
|
|
331
345
|
pollForAnswer,
|
|
332
346
|
cancelQuestion,
|
|
333
347
|
withdrawQuestion,
|
|
@@ -1,13 +1,24 @@
|
|
|
1
|
+
import {
|
|
2
|
+
APPROVAL_RULES_PATH,
|
|
3
|
+
canChangeApprovalSettings
|
|
4
|
+
} from "./chunk-5MOJCOCF.js";
|
|
1
5
|
import {
|
|
2
6
|
callMcpTool
|
|
3
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-KNUYUQBP.js";
|
|
8
|
+
import {
|
|
9
|
+
absoluteUrl
|
|
10
|
+
} from "./chunk-3THDNNVL.js";
|
|
11
|
+
import {
|
|
12
|
+
getBaseUrl
|
|
13
|
+
} from "./chunk-32OSSYGZ.js";
|
|
4
14
|
import {
|
|
5
15
|
NPX_LATEST_COMMAND
|
|
6
|
-
} from "./chunk-
|
|
16
|
+
} from "./chunk-X2MTVD4W.js";
|
|
7
17
|
import {
|
|
18
|
+
APPROVAL_MODE_META,
|
|
8
19
|
classifyConfirmResponse,
|
|
9
20
|
isAnswerSource
|
|
10
|
-
} from "./chunk-
|
|
21
|
+
} from "./chunk-RQOT6QL3.js";
|
|
11
22
|
|
|
12
23
|
// src/reach.ts
|
|
13
24
|
var reachVerdict = (channels) => {
|
|
@@ -304,7 +315,15 @@ var unansweredNextStep = (appPlatforms) => {
|
|
|
304
315
|
const step = notificationAnswerStep(appPlatforms);
|
|
305
316
|
return step === null ? CHECK_THE_NOTIFICATION_OPENED : `To send another one, run pushary doctor --roundtrip. ${step}`;
|
|
306
317
|
};
|
|
307
|
-
var
|
|
318
|
+
var PHONE_APPROVAL_MODES = ["push_only", "push_first"];
|
|
319
|
+
var NOTIFY_ONLY_SENT = `Sent. This site is set to ${APPROVAL_MODE_META.notify_only.label}, so questions never wait for an answer.`;
|
|
320
|
+
var phoneApprovalModeLabels = PHONE_APPROVAL_MODES.map((mode) => APPROVAL_MODE_META[mode].label).join(" or ");
|
|
321
|
+
var phoneApprovalModeCommands = PHONE_APPROVAL_MODES.map((mode) => `pushary mode ${mode}`).join(" or ");
|
|
322
|
+
var answerFromYourPhoneSteps = (baseUrl, keyScope) => {
|
|
323
|
+
const inTheAppOrDashboard = `To answer approvals from your phone, choose ${phoneApprovalModeLabels} in the Pushary app, or on the dashboard: ${absoluteUrl(baseUrl, APPROVAL_RULES_PATH)}`;
|
|
324
|
+
return canChangeApprovalSettings(keyScope) ? [inTheAppOrDashboard, `With this key you can also run ${phoneApprovalModeCommands}.`] : [inTheAppOrDashboard];
|
|
325
|
+
};
|
|
326
|
+
var describeRoundTripOutcome = (outcome, { appPlatforms = [], baseUrl = getBaseUrl(), keyScope = null } = {}) => {
|
|
308
327
|
switch (outcome.kind) {
|
|
309
328
|
case "answered":
|
|
310
329
|
return {
|
|
@@ -324,8 +343,8 @@ var describeRoundTripOutcome = (outcome, appPlatforms = []) => {
|
|
|
324
343
|
case "notify-only":
|
|
325
344
|
return {
|
|
326
345
|
ok: true,
|
|
327
|
-
message:
|
|
328
|
-
next: [
|
|
346
|
+
message: NOTIFY_ONLY_SENT,
|
|
347
|
+
next: [...answerFromYourPhoneSteps(baseUrl, keyScope)]
|
|
329
348
|
};
|
|
330
349
|
case "no-recipients":
|
|
331
350
|
return {
|
|
@@ -344,8 +363,8 @@ var describeRoundTripOutcome = (outcome, appPlatforms = []) => {
|
|
|
344
363
|
};
|
|
345
364
|
}
|
|
346
365
|
};
|
|
347
|
-
var describeRoundTrip = (outcome,
|
|
348
|
-
const report = describeRoundTripOutcome(outcome,
|
|
366
|
+
var describeRoundTrip = (outcome, context = {}) => {
|
|
367
|
+
const report = describeRoundTripOutcome(outcome, context);
|
|
349
368
|
return { ...report, next: [...report.next, "Agent hook activation remains unverified. Restart your agent and check one real approval."] };
|
|
350
369
|
};
|
|
351
370
|
var roundTripEvidence = (outcome) => ({
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import {
|
|
2
2
|
autoUpdateLock
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-TI4JYPGQ.js";
|
|
4
4
|
import {
|
|
5
5
|
installPackageGlobally,
|
|
6
6
|
npmErrorMessage,
|
|
7
7
|
writeJsonAtomic
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-WJLHZ6E6.js";
|
|
9
9
|
|
|
10
10
|
// src/upgrade-lock.ts
|
|
11
11
|
import { fork } from "child_process";
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import {
|
|
2
|
-
APPROVAL_SETTINGS_PATH
|
|
3
|
-
} from "./chunk-FFSIYBBU.js";
|
|
4
1
|
import {
|
|
5
2
|
readMacAppAgentKey
|
|
6
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-LS42NV6E.js";
|
|
4
|
+
import {
|
|
5
|
+
API_KEYS_PATH
|
|
6
|
+
} from "./chunk-5MOJCOCF.js";
|
|
7
7
|
import {
|
|
8
8
|
findExportedKeyLines,
|
|
9
9
|
isAdoptedMacAppKey,
|
|
@@ -13,13 +13,13 @@ import {
|
|
|
13
13
|
readConfigFileKey,
|
|
14
14
|
readKeySource,
|
|
15
15
|
readMacAppKeyPrefix
|
|
16
|
-
} from "./chunk-
|
|
16
|
+
} from "./chunk-JOBSKQ2Z.js";
|
|
17
17
|
import {
|
|
18
18
|
absoluteUrl
|
|
19
|
-
} from "./chunk-
|
|
19
|
+
} from "./chunk-3THDNNVL.js";
|
|
20
20
|
import {
|
|
21
21
|
isValidApiKey
|
|
22
|
-
} from "./chunk-
|
|
22
|
+
} from "./chunk-RQOT6QL3.js";
|
|
23
23
|
|
|
24
24
|
// src/key-revocation.ts
|
|
25
25
|
var SELF_REVOKE_PATH = "/api/v1/server/keys/self/revoke";
|
|
@@ -128,7 +128,7 @@ var SPARED_KEY_WHY = {
|
|
|
128
128
|
no_creation_record: "This CLI has no record of creating it, so it may be in use by the Mac app or on another machine."
|
|
129
129
|
};
|
|
130
130
|
var localRemovalOf = (dryRun) => dryRun ? "would be removed here" : "removed here";
|
|
131
|
-
var settingsUrlOf = (baseUrl) => absoluteUrl(baseUrl,
|
|
131
|
+
var settingsUrlOf = (baseUrl) => absoluteUrl(baseUrl, API_KEYS_PATH);
|
|
132
132
|
var revokeYourselfHint = (reason, baseUrl) => reason === "no_creation_record" ? `Revoke it at ${settingsUrlOf(baseUrl)} if nothing else uses it.` : null;
|
|
133
133
|
var describeCliKeyRevocation = (outcome, run) => {
|
|
134
134
|
const label = `API key ${outcome.keyPrefix}`;
|
|
@@ -1,25 +1,25 @@
|
|
|
1
1
|
import {
|
|
2
2
|
registerTranscript
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-SB6TYV4M.js";
|
|
4
4
|
import {
|
|
5
5
|
namedEvent
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-ICQCQAUO.js";
|
|
7
7
|
import {
|
|
8
8
|
isBridgeLocator,
|
|
9
9
|
liveBridgeProbe,
|
|
10
10
|
pusharyHookExecutable,
|
|
11
11
|
resolveBridgeStub
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-BFF3ABFV.js";
|
|
13
13
|
import {
|
|
14
14
|
writeDegraded
|
|
15
|
-
} from "./chunk-
|
|
15
|
+
} from "./chunk-D3U6CN7T.js";
|
|
16
16
|
import {
|
|
17
17
|
cursorUserHooks
|
|
18
|
-
} from "./chunk-
|
|
18
|
+
} from "./chunk-TI4JYPGQ.js";
|
|
19
19
|
import {
|
|
20
20
|
atLeast,
|
|
21
21
|
parseVersion
|
|
22
|
-
} from "./chunk-
|
|
22
|
+
} from "./chunk-WJLHZ6E6.js";
|
|
23
23
|
import {
|
|
24
24
|
CURSOR_GATE_COVERAGE,
|
|
25
25
|
CURSOR_GATE_SCRIPT,
|
|
@@ -33,7 +33,7 @@ import {
|
|
|
33
33
|
isGrokSessionEndStop,
|
|
34
34
|
isRecord,
|
|
35
35
|
toolsCoveredByGateEntry
|
|
36
|
-
} from "./chunk-
|
|
36
|
+
} from "./chunk-RQOT6QL3.js";
|
|
37
37
|
|
|
38
38
|
// src/tool-hook-input.ts
|
|
39
39
|
var OPTIONAL_TEXT_FIELDS = ["hook_event_name", "session_id", "cwd", "transcript_path", "tool_use_id", "permission_mode", "cursor_version"];
|
|
@@ -210,6 +210,8 @@ function readToolHookCall(source, event, stdin = process.stdin, { readCursorGate
|
|
|
210
210
|
}
|
|
211
211
|
|
|
212
212
|
export {
|
|
213
|
+
readAdmissionRules,
|
|
214
|
+
isAdmitted,
|
|
213
215
|
readHookInput,
|
|
214
216
|
readToolHookInput,
|
|
215
217
|
readToolHookCall
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import {
|
|
2
2
|
addGeminiMcpServer,
|
|
3
3
|
removeGeminiMcpServer
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-BFF3ABFV.js";
|
|
5
5
|
import {
|
|
6
6
|
CLAUDE_CODE_AGENT,
|
|
7
7
|
compatibleToolLookup
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-XFDWLDHG.js";
|
|
9
9
|
import {
|
|
10
10
|
CLAUDE_HOOK_EVENTS,
|
|
11
11
|
PUSHARY_MCP_URL,
|
|
@@ -17,7 +17,7 @@ import {
|
|
|
17
17
|
isPusharyHook,
|
|
18
18
|
registerHookEntry,
|
|
19
19
|
removeClaudeMcpServers
|
|
20
|
-
} from "./chunk-
|
|
20
|
+
} from "./chunk-TI4JYPGQ.js";
|
|
21
21
|
import {
|
|
22
22
|
HOOK_COMPATIBLE_PROFILES,
|
|
23
23
|
PHONE_ANSWERED_TOOLS,
|
|
@@ -28,7 +28,7 @@ import {
|
|
|
28
28
|
pusharyMissingReason,
|
|
29
29
|
refusalOutput,
|
|
30
30
|
withHookHoldBudget
|
|
31
|
-
} from "./chunk-
|
|
31
|
+
} from "./chunk-RQOT6QL3.js";
|
|
32
32
|
|
|
33
33
|
// src/config-document.ts
|
|
34
34
|
import { parse, stringify } from "smol-toml";
|
|
@@ -312,6 +312,7 @@ export {
|
|
|
312
312
|
profileFromArgv,
|
|
313
313
|
activeIdentity,
|
|
314
314
|
namedEvent,
|
|
315
|
+
namedSource,
|
|
315
316
|
activeHookSource,
|
|
316
317
|
normalizeToolCall,
|
|
317
318
|
grokHome,
|
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
import {
|
|
2
2
|
CODEX_HOOK_STATUS
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-Y4MRHAE5.js";
|
|
4
|
+
import {
|
|
5
|
+
retryAgentCommand
|
|
6
|
+
} from "./chunk-JOD2325S.js";
|
|
4
7
|
import {
|
|
5
8
|
NPX_LATEST_COMMAND
|
|
6
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-X2MTVD4W.js";
|
|
7
10
|
|
|
8
11
|
// src/setup/codex-trust.ts
|
|
9
12
|
var CODEX_TRUST_TELEMETRY = {
|
|
@@ -61,9 +64,56 @@ var describeCodexTrustConfirmation = (confirmation) => {
|
|
|
61
64
|
}
|
|
62
65
|
};
|
|
63
66
|
|
|
67
|
+
// src/hermes/messages.ts
|
|
68
|
+
var HERMES_RESTART_COMMAND = "hermes gateway restart";
|
|
69
|
+
var HERMES_MAC_APP_REPAIR = "open Pushary on this Mac and connect Hermes again";
|
|
70
|
+
var describeHermesInstallFailure = (reason, pluginDirectory, receiptPath) => {
|
|
71
|
+
switch (reason) {
|
|
72
|
+
case "home_unknown":
|
|
73
|
+
return "Hermes did not say where its settings live. Check that `hermes config path` works, then run setup again.";
|
|
74
|
+
case "receipt_invalid":
|
|
75
|
+
return `${receiptPath} is unreadable, so setup cannot record what it changes. Move it aside, then run setup again.`;
|
|
76
|
+
case "settings_unreadable":
|
|
77
|
+
return "Hermes would not report its settings through `hermes config get`. Run `hermes update`, then run setup again.";
|
|
78
|
+
case "plugin_folder_not_ours":
|
|
79
|
+
return `${pluginDirectory} holds a pushary plugin that Pushary did not install. Remove that folder, then run setup again.`;
|
|
80
|
+
case "plugin_write_failed":
|
|
81
|
+
return `Could not write the Pushary plugin to ${pluginDirectory}.`;
|
|
82
|
+
case "settings_failed":
|
|
83
|
+
return "The plugin is in place, but Hermes refused a settings change. Run `hermes plugins enable pushary`, then run setup again.";
|
|
84
|
+
}
|
|
85
|
+
};
|
|
86
|
+
var PROBLEM_DESCRIPTIONS = {
|
|
87
|
+
plugin_missing: "the Pushary plugin folder is missing",
|
|
88
|
+
plugin_not_enabled: "pushary is not in plugins.enabled",
|
|
89
|
+
plugin_disabled: "pushary is in plugins.disabled"
|
|
90
|
+
};
|
|
91
|
+
var describeHermesProblems = (problems) => problems.map((problem) => PROBLEM_DESCRIPTIONS[problem]).join(", ");
|
|
92
|
+
var hermesRepairStep = (installer) => installer === "mac_app" ? HERMES_MAC_APP_REPAIR : `run ${retryAgentCommand("hermes")}`;
|
|
93
|
+
var describeHermesState = (state) => {
|
|
94
|
+
switch (state.kind) {
|
|
95
|
+
case "not_wired":
|
|
96
|
+
return "Pushary is not set up for Hermes";
|
|
97
|
+
case "needs_repair":
|
|
98
|
+
return `Hermes needs repair: ${describeHermesProblems(state.problems)}`;
|
|
99
|
+
case "restart_needed":
|
|
100
|
+
return `Restart Hermes to load Pushary ${state.installedVersion ?? ""}`.trim();
|
|
101
|
+
case "connected":
|
|
102
|
+
if (!state.live) {
|
|
103
|
+
return state.gatewayRunning ? "Hermes is running, and this plugin copy does not report whether it loaded" : "Hermes loads Pushary the next time it starts";
|
|
104
|
+
}
|
|
105
|
+
return state.runningVersion === state.version ? "Hermes loaded Pushary" : `Hermes runs Pushary ${state.runningVersion ?? "from an older copy"}; restart it to load ${state.version ?? "the new copy"}`;
|
|
106
|
+
}
|
|
107
|
+
};
|
|
108
|
+
|
|
64
109
|
export {
|
|
65
110
|
codexTrustOutcome,
|
|
66
111
|
CODEX_HOOK_REMEDY,
|
|
67
112
|
needsCodexTrustStep,
|
|
68
|
-
describeCodexTrustConfirmation
|
|
113
|
+
describeCodexTrustConfirmation,
|
|
114
|
+
HERMES_RESTART_COMMAND,
|
|
115
|
+
describeHermesInstallFailure,
|
|
116
|
+
describeHermesProblems,
|
|
117
|
+
hermesRepairStep,
|
|
118
|
+
describeHermesState
|
|
69
119
|
};
|