@pushary/agent-hooks 1.9.8 → 1.9.10
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/dist/bin/pushary-bell-hook.js +22 -23
- package/dist/bin/pushary-bell.js +13 -13
- package/dist/bin/pushary-claude.js +26 -27
- package/dist/bin/pushary-clean.js +124 -51
- package/dist/bin/pushary-codex-bridge.js +20 -20
- package/dist/bin/pushary-codex-hook.js +34 -35
- package/dist/bin/pushary-codex.js +13 -13
- package/dist/bin/pushary-connect.js +41 -18
- package/dist/bin/pushary-cowork.js +5 -5
- package/dist/bin/pushary-daemon.js +35 -37
- package/dist/bin/pushary-disconnect.js +29 -32
- package/dist/bin/pushary-doctor.js +101 -78
- package/dist/bin/pushary-elicitation-hook.js +25 -26
- package/dist/bin/pushary-gemini-bridge.js +13 -13
- package/dist/bin/pushary-gemini-hook.js +29 -30
- package/dist/bin/pushary-hook.js +36 -37
- package/dist/bin/pushary-login.js +12 -12
- package/dist/bin/pushary-logout.js +18 -78
- package/dist/bin/pushary-mcp.js +9 -9
- package/dist/bin/pushary-mode.js +12 -12
- package/dist/bin/pushary-notification-hook.js +29 -30
- package/dist/bin/pushary-opencode-hook.js +28 -29
- package/dist/bin/pushary-permission-denied-hook.js +30 -31
- package/dist/bin/pushary-permission-hook.js +33 -34
- package/dist/bin/pushary-post-hook.js +30 -31
- package/dist/bin/pushary-prompt-hook.js +29 -30
- package/dist/bin/pushary-session-end-hook.js +29 -30
- package/dist/bin/pushary-session-start-hook.js +33 -35
- package/dist/bin/pushary-setup.js +147 -116
- package/dist/bin/pushary-stats.js +5 -5
- package/dist/bin/pushary-status.js +48 -18
- package/dist/bin/pushary-stop-hook.js +29 -30
- package/dist/bin/pushary-stopfailure-hook.js +29 -30
- package/dist/bin/pushary-suggestions.js +12 -12
- package/dist/bin/pushary-transcript-register.js +18 -19
- package/dist/bin/pushary-transcripts.js +7 -7
- package/dist/bin/pushary-upgrade.js +38 -44
- package/dist/bin/pushary-wait.js +12 -12
- package/dist/bin/pushary.js +6 -6
- package/dist/{chunk-CKV3UPMU.js → chunk-2HFSKYLN.js} +2 -2
- package/dist/{chunk-ZN3C6GBG.js → chunk-2HXG2QDI.js} +4 -4
- package/dist/{chunk-5QUPKDI5.js → chunk-2M52CFVO.js} +1 -1
- package/dist/{chunk-KF3UZLYI.js → chunk-2S34OPHS.js} +1 -1
- package/dist/{chunk-2A53H4S6.js → chunk-5MQYA3YL.js} +22 -21
- package/dist/{chunk-I5IJRMNV.js → chunk-5RGA636G.js} +21 -9
- package/dist/{chunk-IAD2RT4L.js → chunk-6KNC6KLL.js} +4 -4
- package/dist/{chunk-KHNFLYJO.js → chunk-7HGR5GNY.js} +4 -4
- package/dist/{chunk-BEJRK4DF.js → chunk-AKPHYSEL.js} +5 -4
- package/dist/{chunk-ZBK6E2OR.js → chunk-APP43AW7.js} +1 -1
- package/dist/chunk-BOSXFI7L.js +52 -0
- package/dist/{chunk-WS4H76EP.js → chunk-BTFUSQFB.js} +2 -2
- package/dist/{chunk-B64KHETR.js → chunk-BVPPYR7B.js} +3 -3
- package/dist/{chunk-TCWKTUAE.js → chunk-BVSIM4EF.js} +2 -2
- package/dist/{chunk-BXET3ALR.js → chunk-C6QTMWJZ.js} +2 -2
- package/dist/{chunk-IHO3YQAN.js → chunk-CJYM4ZHV.js} +2 -2
- package/dist/{chunk-6TE27XZR.js → chunk-DAOQT4WK.js} +2 -2
- package/dist/{chunk-V5HPPF3E.js → chunk-DL6QHS7V.js} +1 -1
- package/dist/{chunk-DPGSLWOS.js → chunk-DWO4RLYK.js} +10 -10
- package/dist/{chunk-GU3EJCVV.js → chunk-EA5NWDK7.js} +4 -0
- package/dist/{chunk-I6MJXLMY.js → chunk-EVC765EO.js} +2 -2
- package/dist/{chunk-WG3K4TCH.js → chunk-GQYX24UC.js} +1 -1
- package/dist/{chunk-N4QSPI3B.js → chunk-GTZ4HIHU.js} +15 -13
- package/dist/{chunk-DUZVXBBU.js → chunk-H4F5O3RE.js} +1 -1
- package/dist/{chunk-MKTJEXZ3.js → chunk-I3W7GJ5R.js} +3 -3
- package/dist/{chunk-ZSTSEBG7.js → chunk-IIVZZMSO.js} +1 -1
- package/dist/{chunk-KRCR2CRQ.js → chunk-LDQGURCF.js} +11 -11
- package/dist/{chunk-2WXF3QJR.js → chunk-LXA236ZQ.js} +2 -2
- package/dist/{chunk-CD47ZFFZ.js → chunk-MD4SVNT6.js} +1 -1
- package/dist/{chunk-CLOSJ4ES.js → chunk-MISUKJGW.js} +1 -1
- package/dist/{chunk-DKMD6AWR.js → chunk-NQ67AF3V.js} +4 -4
- package/dist/{chunk-HRULIYDU.js → chunk-OL2Z7WI4.js} +2 -2
- package/dist/{chunk-MXHTGVFZ.js → chunk-PNC5ZQFS.js} +16 -20
- package/dist/{chunk-3I6IVOZV.js → chunk-PR2VDVCP.js} +3 -3
- package/dist/{chunk-FQ2GORVG.js → chunk-Q3UMWSE4.js} +2 -2
- package/dist/{chunk-MFF3ONG5.js → chunk-QAGWWDXQ.js} +78 -8
- package/dist/{chunk-M6BZZFVQ.js → chunk-QGRENWJL.js} +1 -1
- package/dist/{chunk-LKLVTG3V.js → chunk-RPQLZLKC.js} +5 -5
- package/dist/{chunk-KFF7G225.js → chunk-S2DAKKQQ.js} +3 -3
- package/dist/chunk-SB2GN6OP.js +71 -0
- package/dist/{chunk-2QGYMY7A.js → chunk-SIHYBIEN.js} +142 -4
- package/dist/{chunk-ZW3XZLJC.js → chunk-SJDMULE7.js} +5 -5
- package/dist/{chunk-IHFDPV7C.js → chunk-SMVMLWCD.js} +1 -1
- package/dist/{chunk-QOLITCIP.js → chunk-T6ZN4TEF.js} +1 -1
- package/dist/{chunk-7DVNSQWF.js → chunk-TCXL5FQQ.js} +2 -2
- package/dist/{chunk-7PT35RY2.js → chunk-U5FP5JIS.js} +2 -2
- package/dist/{chunk-ZBHUHJG6.js → chunk-UJZ7AGSC.js} +6 -4
- package/dist/{chunk-TCQ43LSG.js → chunk-UM5WXBKN.js} +3 -3
- package/dist/{chunk-2QTO5YIT.js → chunk-XKMGHVXW.js} +6 -6
- package/dist/{chunk-LWOO567I.js → chunk-XXLCYKVS.js} +3 -3
- package/dist/{chunk-MGRFDGWU.js → chunk-Y7JM47CI.js} +2 -2
- package/dist/{chunk-NWDG3MSW.js → chunk-YUQHUGTH.js} +1 -1
- package/dist/{chunk-WWOHTTVP.js → chunk-Z2Q2VH43.js} +2 -2
- package/dist/{chunk-DL7XWKYV.js → chunk-ZGADIZDS.js} +2 -2
- package/dist/{chunk-2VZAALEJ.js → chunk-ZSGJYSF2.js} +8 -8
- package/dist/{global-upgrade-I56HNM23.js → global-upgrade-PUM44JUH.js} +6 -6
- package/dist/{paths-AGY43CXS.js → paths-U2MJGNBT.js} +2 -2
- package/dist/{reapply-IA5XUKWW.js → reapply-PRKV4EO7.js} +22 -24
- package/dist/src/index.js +19 -19
- package/dist/{upgrade-lock-B34TAUKV.js → upgrade-lock-QZSVLEM7.js} +3 -3
- package/package.json +1 -1
- package/dist/chunk-3Z3A37WD.js +0 -77
- package/dist/chunk-OP7IHC2I.js +0 -24
- package/dist/chunk-YIG2R3BJ.js +0 -145
package/dist/chunk-3Z3A37WD.js
DELETED
|
@@ -1,77 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
openCodePluginArgv,
|
|
3
|
-
openCodePluginFile
|
|
4
|
-
} from "./chunk-MFF3ONG5.js";
|
|
5
|
-
import {
|
|
6
|
-
compatibleConfigFile
|
|
7
|
-
} from "./chunk-KHNFLYJO.js";
|
|
8
|
-
import {
|
|
9
|
-
hookOwnerOf,
|
|
10
|
-
hookOwnerOfCommands
|
|
11
|
-
} from "./chunk-YIG2R3BJ.js";
|
|
12
|
-
import {
|
|
13
|
-
liveBridgeProbe,
|
|
14
|
-
resolveBridgeStub
|
|
15
|
-
} from "./chunk-2QGYMY7A.js";
|
|
16
|
-
import {
|
|
17
|
-
claudeSettings,
|
|
18
|
-
codexHooksJson,
|
|
19
|
-
cursorUserHooks,
|
|
20
|
-
geminiSettings,
|
|
21
|
-
pusharyDir,
|
|
22
|
-
vscodePluginDir
|
|
23
|
-
} from "./chunk-ZBHUHJG6.js";
|
|
24
|
-
import {
|
|
25
|
-
readJsonSafe
|
|
26
|
-
} from "./chunk-T7E75EKA.js";
|
|
27
|
-
import {
|
|
28
|
-
HOOK_COMPATIBLE_PROFILES,
|
|
29
|
-
HOOK_LOCATOR_BINARY,
|
|
30
|
-
hookCompatibleProfile
|
|
31
|
-
} from "./chunk-I5IJRMNV.js";
|
|
32
|
-
|
|
33
|
-
// src/setup/agent-hook-owner.ts
|
|
34
|
-
import { readFileSync } from "fs";
|
|
35
|
-
import { join } from "path";
|
|
36
|
-
var COMPATIBLE_HOOK_FILES = Object.fromEntries(
|
|
37
|
-
HOOK_COMPATIBLE_PROFILES.map((profile) => [profile.agentType, () => compatibleConfigFile(profile)])
|
|
38
|
-
);
|
|
39
|
-
var HOOK_FILES = {
|
|
40
|
-
claude_code: claudeSettings,
|
|
41
|
-
codex: codexHooksJson,
|
|
42
|
-
gemini_cli: geminiSettings,
|
|
43
|
-
cursor: cursorUserHooks,
|
|
44
|
-
vscode: () => join(vscodePluginDir(), "hooks", "hooks.json"),
|
|
45
|
-
...COMPATIBLE_HOOK_FILES
|
|
46
|
-
};
|
|
47
|
-
var agentHookFile = (agent) => HOOK_FILES[agent]?.() ?? null;
|
|
48
|
-
var agentHookOwner = (agent, appAvailable) => {
|
|
49
|
-
const file = agentHookFile(agent);
|
|
50
|
-
if (!file) return "none";
|
|
51
|
-
const document = readJsonSafe(file);
|
|
52
|
-
const profile = hookCompatibleProfile(agent);
|
|
53
|
-
return hookOwnerOf(
|
|
54
|
-
document.kind === "ok" ? document.value : null,
|
|
55
|
-
appAvailable,
|
|
56
|
-
profile ? profile.hooksKeyPath : void 0
|
|
57
|
-
);
|
|
58
|
-
};
|
|
59
|
-
var readTextOrNull = (path) => {
|
|
60
|
-
try {
|
|
61
|
-
return readFileSync(path, "utf-8");
|
|
62
|
-
} catch {
|
|
63
|
-
return null;
|
|
64
|
-
}
|
|
65
|
-
};
|
|
66
|
-
var openCodePluginOwner = (appAvailable, pluginFile = openCodePluginFile()) => {
|
|
67
|
-
const contents = readTextOrNull(pluginFile);
|
|
68
|
-
return hookOwnerOfCommands(contents === null ? [] : openCodePluginArgv(contents) ?? [], appAvailable);
|
|
69
|
-
};
|
|
70
|
-
var macAppBridgeAvailable = () => resolveBridgeStub(join(pusharyDir(), "bin", HOOK_LOCATOR_BINARY), liveBridgeProbe()).kind === "bundle";
|
|
71
|
-
|
|
72
|
-
export {
|
|
73
|
-
agentHookFile,
|
|
74
|
-
agentHookOwner,
|
|
75
|
-
openCodePluginOwner,
|
|
76
|
-
macAppBridgeAvailable
|
|
77
|
-
};
|
package/dist/chunk-OP7IHC2I.js
DELETED
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
isValidApiKey
|
|
3
|
-
} from "./chunk-I5IJRMNV.js";
|
|
4
|
-
|
|
5
|
-
// src/shared-mcp-key.ts
|
|
6
|
-
var asRecord = (value) => value !== null && typeof value === "object" && !Array.isArray(value) ? value : void 0;
|
|
7
|
-
var pusharyKey = (value) => typeof value === "string" && isValidApiKey(value.trim()) ? value.trim() : null;
|
|
8
|
-
var bearerKey = (authorization) => typeof authorization === "string" && authorization.startsWith("Bearer ") ? pusharyKey(authorization.slice("Bearer ".length)) : null;
|
|
9
|
-
var mcpServerBearer = (mcpServers) => bearerKey(asRecord(asRecord(asRecord(mcpServers)?.pushary)?.headers)?.Authorization);
|
|
10
|
-
var appAgentKey = (bridgeAgentKey) => pusharyKey(asRecord(bridgeAgentKey)?.key);
|
|
11
|
-
var setupReceiptKey = (claudeMcpReceipt) => bearerKey(asRecord(asRecord(asRecord(claudeMcpReceipt)?.installedPushary)?.headers)?.Authorization);
|
|
12
|
-
var macAppKeepsMcpEntry = (entryKey, keys) => {
|
|
13
|
-
if (!entryKey) return true;
|
|
14
|
-
if (keys.appKey) return entryKey === keys.appKey;
|
|
15
|
-
return entryKey !== keys.setupKey;
|
|
16
|
-
};
|
|
17
|
-
|
|
18
|
-
export {
|
|
19
|
-
pusharyKey,
|
|
20
|
-
mcpServerBearer,
|
|
21
|
-
appAgentKey,
|
|
22
|
-
setupReceiptKey,
|
|
23
|
-
macAppKeepsMcpEntry
|
|
24
|
-
};
|
package/dist/chunk-YIG2R3BJ.js
DELETED
|
@@ -1,145 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
AGENT_CHOICES
|
|
3
|
-
} from "./chunk-DL7XWKYV.js";
|
|
4
|
-
import {
|
|
5
|
-
isBridgeLocator,
|
|
6
|
-
pusharyHookExecutable
|
|
7
|
-
} from "./chunk-2QGYMY7A.js";
|
|
8
|
-
import {
|
|
9
|
-
BELL_HOOK_BINARY
|
|
10
|
-
} from "./chunk-WG3K4TCH.js";
|
|
11
|
-
|
|
12
|
-
// src/setup/hook-ownership.ts
|
|
13
|
-
var commandsIn = (value) => {
|
|
14
|
-
if (Array.isArray(value)) return value.flatMap(commandsIn);
|
|
15
|
-
if (!value || typeof value !== "object") return [];
|
|
16
|
-
return Object.entries(value).flatMap(([key, item]) => key === "command" && typeof item === "string" ? [item] : commandsIn(item));
|
|
17
|
-
};
|
|
18
|
-
var isRecord = (value) => value !== null && typeof value === "object" && !Array.isArray(value);
|
|
19
|
-
var hasPaidPusharyCommand = (value) => commandsIn(value).some((command) => {
|
|
20
|
-
const executable = pusharyHookExecutable(command);
|
|
21
|
-
const name = executable?.split(/[/\\]/).pop()?.replace(/\.(cmd|exe|mjs)$/i, "");
|
|
22
|
-
return executable !== null && !isBridgeLocator(executable) && name !== BELL_HOOK_BINARY;
|
|
23
|
-
});
|
|
24
|
-
var hasAppCommand = (value) => commandsIn(value).some((command) => {
|
|
25
|
-
const executable = pusharyHookExecutable(command);
|
|
26
|
-
return executable !== null && isBridgeLocator(executable);
|
|
27
|
-
});
|
|
28
|
-
var mcpBearerKey = (document, containerKey, headersKey) => {
|
|
29
|
-
const servers = isRecord(document?.[containerKey]) ? document[containerKey] : null;
|
|
30
|
-
const pushary = isRecord(servers?.pushary) ? servers.pushary : null;
|
|
31
|
-
const headers = isRecord(pushary?.[headersKey]) ? pushary[headersKey] : null;
|
|
32
|
-
const authorization = headers?.Authorization;
|
|
33
|
-
const match = typeof authorization === "string" ? authorization.trim().match(/^Bearer\s+(\S+)$/) : null;
|
|
34
|
-
return match?.[1] ?? null;
|
|
35
|
-
};
|
|
36
|
-
var captureMcpServer = (document, containerKey) => {
|
|
37
|
-
const container = document[containerKey];
|
|
38
|
-
const servers = isRecord(container) ? container : null;
|
|
39
|
-
if (!servers && Object.hasOwn(document, containerKey)) {
|
|
40
|
-
return { present: false, containerValue: structuredClone(container) };
|
|
41
|
-
}
|
|
42
|
-
return servers && Object.hasOwn(servers, "pushary") ? { present: true, value: structuredClone(servers.pushary) } : { present: false };
|
|
43
|
-
};
|
|
44
|
-
var restoreMcpServer = (document, containerKey, snapshot) => {
|
|
45
|
-
const before = JSON.stringify(document);
|
|
46
|
-
const existing = isRecord(document[containerKey]) ? document[containerKey] : null;
|
|
47
|
-
if (snapshot.present) {
|
|
48
|
-
const servers = existing ?? {};
|
|
49
|
-
servers.pushary = structuredClone(snapshot.value);
|
|
50
|
-
document[containerKey] = servers;
|
|
51
|
-
} else if (Object.hasOwn(snapshot, "containerValue")) {
|
|
52
|
-
document[containerKey] = structuredClone(snapshot.containerValue);
|
|
53
|
-
} else if (existing && Object.hasOwn(existing, "pushary")) {
|
|
54
|
-
delete existing.pushary;
|
|
55
|
-
if (Object.keys(existing).length === 0) delete document[containerKey];
|
|
56
|
-
}
|
|
57
|
-
return JSON.stringify(document) !== before;
|
|
58
|
-
};
|
|
59
|
-
var captureHookTakeover = (agent, document) => {
|
|
60
|
-
const hooks = isRecord(document?.hooks) ? document.hooks : null;
|
|
61
|
-
if (!hooks) return null;
|
|
62
|
-
const captured = {};
|
|
63
|
-
for (const [event, entries] of Object.entries(hooks)) {
|
|
64
|
-
if (!Array.isArray(entries)) continue;
|
|
65
|
-
const appEntries = entries.flatMap((value, index) => isRecord(value) && hasAppCommand(value) ? [{ index, value: structuredClone(value) }] : []);
|
|
66
|
-
if (appEntries.length > 0) captured[event] = appEntries;
|
|
67
|
-
}
|
|
68
|
-
return Object.keys(captured).length > 0 ? { version: 1, agent, hooks: captured } : null;
|
|
69
|
-
};
|
|
70
|
-
var isHookTakeoverReceipt = (value) => {
|
|
71
|
-
if (!isRecord(value) || value.version !== 1 || typeof value.agent !== "string" || !AGENT_CHOICES.includes(value.agent) || !isRecord(value.hooks)) return false;
|
|
72
|
-
const expectsMcp = ["claude_code", "codex", "gemini_cli", "vscode"].includes(value.agent);
|
|
73
|
-
if (value.mcpServer !== void 0 !== expectsMcp) return false;
|
|
74
|
-
if (value.codexTrust !== void 0 !== (value.agent === "codex")) return false;
|
|
75
|
-
if (value.codexTrust !== void 0 && !isRecord(value.codexTrust)) return false;
|
|
76
|
-
if (value.mcpServer !== void 0 && (!isRecord(value.mcpServer) || typeof value.mcpServer.present !== "boolean" || value.mcpServer.present && !Object.hasOwn(value.mcpServer, "value"))) return false;
|
|
77
|
-
return Object.values(value.hooks).every((entries) => Array.isArray(entries) && entries.length > 0 && entries.every((item) => isRecord(item) && Number.isInteger(item.index) && item.index >= 0 && isRecord(item.value)));
|
|
78
|
-
};
|
|
79
|
-
var restoreHookTakeover = (document, receipt) => {
|
|
80
|
-
const before = JSON.stringify(document);
|
|
81
|
-
const appOwnsNow = hookOwnerOf(document) === "app";
|
|
82
|
-
const hooks = isRecord(document.hooks) ? document.hooks : {};
|
|
83
|
-
for (const [event, value] of Object.entries(hooks)) {
|
|
84
|
-
if (!Array.isArray(value)) continue;
|
|
85
|
-
const kept = value.filter((entry) => !hasPaidPusharyCommand(entry));
|
|
86
|
-
if (kept.length === 0) delete hooks[event];
|
|
87
|
-
else hooks[event] = kept;
|
|
88
|
-
}
|
|
89
|
-
if (!appOwnsNow) {
|
|
90
|
-
for (const [event, snapshots] of Object.entries(receipt.hooks)) {
|
|
91
|
-
const entries = Array.isArray(hooks[event]) ? [...hooks[event]] : [];
|
|
92
|
-
for (const snapshot of snapshots) {
|
|
93
|
-
entries.splice(Math.min(snapshot.index, entries.length), 0, structuredClone(snapshot.value));
|
|
94
|
-
}
|
|
95
|
-
hooks[event] = entries;
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
document.hooks = hooks;
|
|
99
|
-
return JSON.stringify(document) !== before;
|
|
100
|
-
};
|
|
101
|
-
var hookOwnerOf = (document, appAvailable = true, hooksKeyPath = ["hooks"]) => {
|
|
102
|
-
const hooks = hooksKeyPath.reduce(
|
|
103
|
-
(node, key) => node && typeof node === "object" ? node[key] : void 0,
|
|
104
|
-
document
|
|
105
|
-
);
|
|
106
|
-
return hookOwnerOfCommands(commandsIn(hooks), appAvailable);
|
|
107
|
-
};
|
|
108
|
-
var hookOwnerOfCommands = (commands, appAvailable = true) => {
|
|
109
|
-
const executables = commands.map(pusharyHookExecutable).filter((executable) => executable !== null);
|
|
110
|
-
if (appAvailable && executables.some(isBridgeLocator)) return "app";
|
|
111
|
-
if (executables.some((executable) => !isBridgeLocator(executable))) return "cli";
|
|
112
|
-
return "none";
|
|
113
|
-
};
|
|
114
|
-
var planHooks = (context) => {
|
|
115
|
-
if (context.owner !== "app") return "install";
|
|
116
|
-
if (context.takeOverHooks) return "install";
|
|
117
|
-
return "keep";
|
|
118
|
-
};
|
|
119
|
-
var describeAppOwnership = (agentName) => `The Pushary Mac app owns ${agentName}'s hooks.`;
|
|
120
|
-
var KEEP_HINT = "Kept with the app's account. Pass --take-over-hooks to have the CLI own them instead.";
|
|
121
|
-
var OWNER_LABELS = {
|
|
122
|
-
app: "the Pushary Mac app",
|
|
123
|
-
cli: "the CLI"
|
|
124
|
-
};
|
|
125
|
-
var describeHookOwnership = (entries, names) => {
|
|
126
|
-
const owned = entries.filter((entry) => entry.owner !== "none");
|
|
127
|
-
if (owned.length === 0) return null;
|
|
128
|
-
const parts = owned.map((entry) => `${names[entry.agent]} by ${OWNER_LABELS[entry.owner]}${entry.kept ? " (kept)" : ""}`);
|
|
129
|
-
return `Hooks: ${parts.join(", ")}.`;
|
|
130
|
-
};
|
|
131
|
-
|
|
132
|
-
export {
|
|
133
|
-
mcpBearerKey,
|
|
134
|
-
captureMcpServer,
|
|
135
|
-
restoreMcpServer,
|
|
136
|
-
captureHookTakeover,
|
|
137
|
-
isHookTakeoverReceipt,
|
|
138
|
-
restoreHookTakeover,
|
|
139
|
-
hookOwnerOf,
|
|
140
|
-
hookOwnerOfCommands,
|
|
141
|
-
planHooks,
|
|
142
|
-
describeAppOwnership,
|
|
143
|
-
KEEP_HINT,
|
|
144
|
-
describeHookOwnership
|
|
145
|
-
};
|