pushary 1.9.62 → 1.9.64

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.
Files changed (130) hide show
  1. package/CHANGELOG.md +20 -0
  2. package/README.md +2 -2
  3. package/dist/{api-7HLZRIUV.js → api-HDLTZTVR.js} +10 -11
  4. package/dist/bin/pushary-bell-hook.js +27 -30
  5. package/dist/bin/pushary-bell.js +10 -11
  6. package/dist/bin/pushary-claude.js +29 -32
  7. package/dist/bin/pushary-clean.js +63 -42
  8. package/dist/bin/pushary-codex-bridge.js +22 -24
  9. package/dist/bin/pushary-codex-hook.js +33 -36
  10. package/dist/bin/pushary-codex-session.js +8 -8
  11. package/dist/bin/pushary-codex.js +13 -15
  12. package/dist/bin/pushary-connect.js +26 -29
  13. package/dist/bin/pushary-cowork.js +5 -5
  14. package/dist/bin/pushary-daemon.js +39 -41
  15. package/dist/bin/pushary-disconnect.js +60 -40
  16. package/dist/bin/pushary-doctor.js +89 -46
  17. package/dist/bin/pushary-elicitation-hook.js +28 -31
  18. package/dist/bin/pushary-gemini-bridge.js +16 -18
  19. package/dist/bin/pushary-gemini-hook.js +30 -33
  20. package/dist/bin/pushary-hook.js +31 -34
  21. package/dist/bin/pushary-login.js +27 -16
  22. package/dist/bin/pushary-logout.js +26 -29
  23. package/dist/bin/pushary-mcp.js +11 -12
  24. package/dist/bin/pushary-mode.js +14 -15
  25. package/dist/bin/pushary-notification-hook.js +26 -29
  26. package/dist/bin/pushary-opencode-hook.js +29 -32
  27. package/dist/bin/pushary-permission-denied-hook.js +31 -34
  28. package/dist/bin/pushary-permission-hook.js +30 -33
  29. package/dist/bin/pushary-post-hook.js +26 -29
  30. package/dist/bin/pushary-prompt-hook.js +26 -29
  31. package/dist/bin/pushary-session-end-hook.js +28 -31
  32. package/dist/bin/pushary-session-start-hook.js +35 -37
  33. package/dist/bin/pushary-setup.js +361 -4412
  34. package/dist/bin/pushary-stats.js +5 -5
  35. package/dist/bin/pushary-status.js +32 -35
  36. package/dist/bin/pushary-stop-hook.js +26 -29
  37. package/dist/bin/pushary-stopfailure-hook.js +26 -29
  38. package/dist/bin/pushary-suggestions.js +14 -15
  39. package/dist/bin/pushary-transcript-register.js +18 -21
  40. package/dist/bin/pushary-transcripts.js +63 -11
  41. package/dist/bin/pushary-upgrade.js +41 -43
  42. package/dist/bin/pushary-wait.js +14 -15
  43. package/dist/bin/pushary.js +7 -8
  44. package/dist/{chunk-SJCPIYWJ.js → chunk-2CEVEMJE.js} +3 -3
  45. package/dist/{chunk-3YGUWPNZ.js → chunk-2EY4HGLG.js} +3 -3
  46. package/dist/{chunk-ESXGCZDA.js → chunk-2KID4FK4.js} +4 -4
  47. package/dist/{chunk-EO6CL4PD.js → chunk-2PKHGHMA.js} +2 -2
  48. package/dist/{chunk-PSCXEH42.js → chunk-2VADJ6JH.js} +2 -2
  49. package/dist/{chunk-GV43RXR2.js → chunk-2YXBCZ3Z.js} +1 -1
  50. package/dist/{chunk-7GU4PXE5.js → chunk-2Z7I7DHT.js} +1 -1
  51. package/dist/{chunk-4K6YZPZ3.js → chunk-3KXBRSL3.js} +1 -1
  52. package/dist/{chunk-YQK72JGV.js → chunk-42PD2MQH.js} +5 -5
  53. package/dist/{chunk-EUNSJKJJ.js → chunk-57PU5OBL.js} +21 -14
  54. package/dist/{chunk-5R23J52J.js → chunk-5NP3OJ5P.js} +7 -9
  55. package/dist/{chunk-UWCPY4RY.js → chunk-5TNGBDIE.js} +2 -2
  56. package/dist/{chunk-ZEDGKCCM.js → chunk-5TUDGSDC.js} +1 -1
  57. package/dist/{chunk-M7MEVILL.js → chunk-66FRMK7V.js} +4 -4
  58. package/dist/{chunk-3LBB7GVF.js → chunk-6HPLEGUP.js} +4 -4
  59. package/dist/{chunk-LCNN7UOE.js → chunk-6QPDBD7Q.js} +3 -57
  60. package/dist/{chunk-AFV3FQNG.js → chunk-7UBDBJTG.js} +4 -4
  61. package/dist/{chunk-RFCEVROB.js → chunk-A5KQXZR7.js} +3 -3
  62. package/dist/{chunk-G3ZDCYMU.js → chunk-ADRPW7KU.js} +2 -2
  63. package/dist/{chunk-OZRT64BB.js → chunk-AN7C3CHH.js} +1 -1
  64. package/dist/{chunk-6JAWNRDR.js → chunk-AQAPPSDV.js} +3 -3
  65. package/dist/{chunk-FG5HMJ7C.js → chunk-BAGBCSXA.js} +4 -2
  66. package/dist/{chunk-W3CBFLIX.js → chunk-BLAIETMP.js} +18 -4
  67. package/dist/{chunk-CFIQ3252.js → chunk-BSZIPIFA.js} +128 -26
  68. package/dist/{chunk-7EHZXZB2.js → chunk-CCNH4PJ2.js} +12 -12
  69. package/dist/{chunk-NZLQ6GMX.js → chunk-CJADXAJU.js} +9 -9
  70. package/dist/{chunk-TMHE5CVX.js → chunk-DCMRNIDM.js} +4 -4
  71. package/dist/{chunk-QW3FRUFB.js → chunk-DVYVGBPB.js} +1 -1
  72. package/dist/{chunk-RSNN2TPE.js → chunk-E23RKH3T.js} +9 -9
  73. package/dist/{chunk-ZJFJUAHS.js → chunk-E2LB6JNV.js} +6 -6
  74. package/dist/{chunk-HSRNWCXJ.js → chunk-EEM65CGJ.js} +3 -3
  75. package/dist/chunk-H4BKC2GN.js +1201 -0
  76. package/dist/{chunk-7NXB7OVX.js → chunk-HVOQUPSO.js} +1 -1
  77. package/dist/{chunk-R3CLBNST.js → chunk-IZTDX2MX.js} +3 -3
  78. package/dist/{chunk-RU37NSZH.js → chunk-JTOBQUIL.js} +3 -3
  79. package/dist/{chunk-W6MYFAOK.js → chunk-JX3DHGZX.js} +44 -32
  80. package/dist/{chunk-7NJ4TDUH.js → chunk-KA7JIMTG.js} +6 -6
  81. package/dist/chunk-KEPESIIR.js +4117 -0
  82. package/dist/{chunk-EA6574W2.js → chunk-KX3RMF6T.js} +12 -6
  83. package/dist/{chunk-BIUSODLS.js → chunk-LA7CKRZN.js} +2 -2
  84. package/dist/{chunk-A4CZPUQ6.js → chunk-LMC5UPL7.js} +1 -1
  85. package/dist/{chunk-EVZDYG7L.js → chunk-LV6DX4P6.js} +2 -2
  86. package/dist/{chunk-LWR5VKNC.js → chunk-MIPJ2VXP.js} +12 -14
  87. package/dist/{chunk-557ZE5EX.js → chunk-ML2Q6WWE.js} +37 -214
  88. package/dist/{chunk-FXECTHAG.js → chunk-MNKIR2ZB.js} +37 -4
  89. package/dist/{chunk-LILS32LF.js → chunk-MPPTIZ2G.js} +212 -254
  90. package/dist/{chunk-VUFHYMSP.js → chunk-MXPOLQZH.js} +1 -1
  91. package/dist/{chunk-MYEALNW6.js → chunk-NOH3EJFH.js} +1 -1
  92. package/dist/{chunk-GFAG72LR.js → chunk-NUEPJ5W6.js} +7 -3
  93. package/dist/chunk-NYV45Q25.js +111 -0
  94. package/dist/{chunk-NAZRRXZM.js → chunk-O7PCNYEY.js} +2 -2
  95. package/dist/{chunk-7E2ZN7XA.js → chunk-OQKSF5ST.js} +3 -5
  96. package/dist/{chunk-VF3IL56Q.js → chunk-PLMX3IHG.js} +3 -3
  97. package/dist/{chunk-F35YILEN.js → chunk-PMLQRB3D.js} +1 -1
  98. package/dist/{chunk-SJJYXMJP.js → chunk-Q6ID23SU.js} +6 -6
  99. package/dist/{chunk-SDOWT67G.js → chunk-QECRQWLV.js} +5 -5
  100. package/dist/{chunk-Q4WTIKM6.js → chunk-QNATBOUH.js} +3 -3
  101. package/dist/{chunk-QIPW7OVB.js → chunk-QPPBH5NY.js} +5 -5
  102. package/dist/{chunk-7ETELRQX.js → chunk-QSW3HAKI.js} +16 -5
  103. package/dist/{chunk-FVERRWDP.js → chunk-RY4EPMZX.js} +2 -2
  104. package/dist/{chunk-MURJ4WAL.js → chunk-SROWUG5W.js} +1 -1
  105. package/dist/{chunk-UUAVYIWJ.js → chunk-TJUJAK5L.js} +4 -2
  106. package/dist/{chunk-3IFCXMC6.js → chunk-TR3GP5MH.js} +1 -1
  107. package/dist/{chunk-FX7KDF47.js → chunk-VHKK3US3.js} +3 -3
  108. package/dist/{chunk-6HIYOY6I.js → chunk-VNRWQCGU.js} +6 -6
  109. package/dist/{chunk-67Q3Q5IO.js → chunk-XF3AWNMO.js} +6 -6
  110. package/dist/{chunk-44FNEAXK.js → chunk-XJIIU36L.js} +1 -1
  111. package/dist/{chunk-DFKEJARZ.js → chunk-Y64JGYTB.js} +1 -1
  112. package/dist/{chunk-FYS27SUS.js → chunk-YUDZCJYC.js} +10 -10
  113. package/dist/{codex-app-cards-switch-IIL7IPP6.js → codex-app-cards-switch-JQ6356VX.js} +11 -12
  114. package/dist/{codex-desktop-launch-XCLMYVBD.js → codex-desktop-launch-YUB2LOAG.js} +1 -1
  115. package/dist/{codex-session-launch-UMVALJ3A.js → codex-session-launch-UKMAORXS.js} +19 -21
  116. package/dist/{config-5N3GUJD5.js → config-YY54G3CC.js} +3 -3
  117. package/dist/{global-upgrade-5F4CSXED.js → global-upgrade-Y4USGPS2.js} +10 -12
  118. package/dist/{identity-7ULYW4RL.js → identity-W5CYL5RC.js} +4 -5
  119. package/dist/{live-capabilities-QTSFXA6T.js → live-capabilities-JRNNA5EP.js} +5 -7
  120. package/dist/{paths-HEMK2ALW.js → paths-4MEBINV3.js} +7 -3
  121. package/dist/reapply-ZN7C3CB3.js +63 -0
  122. package/dist/src/index.js +20 -23
  123. package/dist/{upgrade-lock-IAZC5644.js → upgrade-lock-QAWUV2DO.js} +4 -5
  124. package/dist/{usage-NEFDYSRT.js → usage-43C2DHDU.js} +3 -3
  125. package/package.json +1 -1
  126. package/dist/chunk-6ICPEJY5.js +0 -20
  127. package/dist/chunk-6YSEOXP5.js +0 -615
  128. package/dist/chunk-LL2KHEJH.js +0 -41
  129. package/dist/chunk-QENTGE75.js +0 -86
  130. package/dist/reapply-AMFKVYZV.js +0 -63
@@ -1,22 +1,23 @@
1
1
  import {
2
2
  openCodeConfigDirFrom
3
- } from "./chunk-6HIYOY6I.js";
3
+ } from "./chunk-VNRWQCGU.js";
4
4
  import {
5
5
  nativeClaudeInstallPath
6
- } from "./chunk-VUFHYMSP.js";
6
+ } from "./chunk-MXPOLQZH.js";
7
7
  import {
8
8
  grokHome
9
- } from "./chunk-557ZE5EX.js";
9
+ } from "./chunk-ML2Q6WWE.js";
10
10
  import {
11
11
  claudeConfigDir,
12
+ clineDataDirectory,
12
13
  codexHomeFrom
13
- } from "./chunk-6YSEOXP5.js";
14
+ } from "./chunk-H4BKC2GN.js";
14
15
  import {
15
16
  resolvePathBinary
16
- } from "./chunk-CFIQ3252.js";
17
+ } from "./chunk-BSZIPIFA.js";
17
18
  import {
18
19
  HOOK_COMPATIBLE_PROFILES
19
- } from "./chunk-FXECTHAG.js";
20
+ } from "./chunk-MNKIR2ZB.js";
20
21
 
21
22
  // src/hermes-config.ts
22
23
  import { execFileSync } from "child_process";
@@ -558,6 +559,11 @@ var agentProbes = (home = homedir3(), platform = process.platform) => ({
558
559
  paths: [join3(home, ".fx", "settings.json"), join3(home, ".fx", "sessions"), join3(home, ".fx", "history.jsonl")],
559
560
  configMarkers: []
560
561
  },
562
+ cline: {
563
+ binary: "cline",
564
+ paths: [clineDataDirectory({ home, environment: process.env })],
565
+ configMarkers: []
566
+ },
561
567
  ...compatibleProbes(),
562
568
  grok: { binary: "grok", paths: [join3(home, ".local", "bin", "grok")], configMarkers: [grokHome(home)] },
563
569
  // "Other" is a set of printed instructions for any MCP or HTTP client. There is
@@ -1,9 +1,9 @@
1
1
  import {
2
2
  CODEX_HOOK_STATUS
3
- } from "./chunk-EVZDYG7L.js";
3
+ } from "./chunk-LV6DX4P6.js";
4
4
  import {
5
5
  NPX_LATEST_COMMAND
6
- } from "./chunk-FG5HMJ7C.js";
6
+ } from "./chunk-BAGBCSXA.js";
7
7
 
8
8
  // src/setup/codex-trust.ts
9
9
  var CODEX_TRUST_TELEMETRY = {
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  HOOK_HOLD_BUDGET_ENV,
3
3
  hookHoldBudgetProof
4
- } from "./chunk-FXECTHAG.js";
4
+ } from "./chunk-MNKIR2ZB.js";
5
5
 
6
6
  // src/hold-budget.ts
7
7
  var takeHookHoldBudget = (args = process.argv.slice(2), env = process.env) => {
@@ -7,10 +7,10 @@ import {
7
7
  codexHome,
8
8
  codexHooksJsonIn,
9
9
  isPusharyCodexCommand
10
- } from "./chunk-6YSEOXP5.js";
10
+ } from "./chunk-H4BKC2GN.js";
11
11
  import {
12
12
  resolvePathBinary
13
- } from "./chunk-CFIQ3252.js";
13
+ } from "./chunk-BSZIPIFA.js";
14
14
  import {
15
15
  getPackageVersion
16
16
  } from "./chunk-QTOLNRET.js";
@@ -1,11 +1,6 @@
1
- import {
2
- IDLE_PROMPT_NOTIFICATION,
3
- NOTIFICATION_PUSH_TYPES,
4
- POSTTOOLUSE_MIRROR_ONLY_TOOLS
5
- } from "./chunk-LL2KHEJH.js";
6
1
  import {
7
2
  repoKeyFor
8
- } from "./chunk-4K6YZPZ3.js";
3
+ } from "./chunk-3KXBRSL3.js";
9
4
  import {
10
5
  cancelQuestion,
11
6
  clientErrorKindOf,
@@ -13,26 +8,29 @@ import {
13
8
  reportClientError,
14
9
  sendNotification,
15
10
  waitForAnswer
16
- } from "./chunk-RSNN2TPE.js";
11
+ } from "./chunk-E23RKH3T.js";
17
12
  import {
18
13
  withRetry
19
- } from "./chunk-ESXGCZDA.js";
14
+ } from "./chunk-2KID4FK4.js";
20
15
  import {
21
16
  getMachineId
22
- } from "./chunk-G3ZDCYMU.js";
17
+ } from "./chunk-ADRPW7KU.js";
23
18
  import {
24
19
  reportedInstallSource
25
- } from "./chunk-PSCXEH42.js";
20
+ } from "./chunk-2VADJ6JH.js";
26
21
  import {
22
+ IDLE_PROMPT_NOTIFICATION,
23
+ NOTIFICATION_PUSH_TYPES,
24
+ POSTTOOLUSE_MIRROR_ONLY_TOOLS,
27
25
  canonicalJson
28
- } from "./chunk-6YSEOXP5.js";
26
+ } from "./chunk-H4BKC2GN.js";
29
27
  import {
30
28
  writeFileAtomic
31
- } from "./chunk-QENTGE75.js";
29
+ } from "./chunk-BSZIPIFA.js";
32
30
  import {
33
31
  getApiKey,
34
32
  getBaseUrl
35
- } from "./chunk-DFKEJARZ.js";
33
+ } from "./chunk-Y64JGYTB.js";
36
34
  import {
37
35
  ACTION_BODY_MAX,
38
36
  AGENTS,
@@ -67,7 +65,7 @@ import {
67
65
  toToolLookup,
68
66
  truncateLine,
69
67
  unansweredRefusalReason
70
- } from "./chunk-FXECTHAG.js";
68
+ } from "./chunk-MNKIR2ZB.js";
71
69
 
72
70
  // ../hook-mapping/src/describe.ts
73
71
  import { isAbsolute, relative, resolve } from "path";
@@ -1,23 +1,25 @@
1
1
  import {
2
- CLAUDE_HOOK_EVENTS,
3
2
  addGeminiMcpServer,
4
- removeGeminiMcpServer,
5
- supportedClaudeEvents
6
- } from "./chunk-LCNN7UOE.js";
3
+ removeGeminiMcpServer
4
+ } from "./chunk-6QPDBD7Q.js";
7
5
  import {
8
6
  CLAUDE_CODE_AGENT,
9
7
  compatibleToolLookup
10
- } from "./chunk-LWR5VKNC.js";
8
+ } from "./chunk-MIPJ2VXP.js";
11
9
  import {
10
+ CLAUDE_HOOK_EVENTS,
11
+ PUSHARY_MCP_URL,
12
+ addClaudeMcpServer,
13
+ addPusharyToolPermissions,
12
14
  guardBinary,
13
15
  guardBinaryRefusing,
14
16
  holdBudgetOf,
15
- isProtectedByScope,
16
- registerHookEntry
17
- } from "./chunk-6YSEOXP5.js";
17
+ isPusharyHook,
18
+ registerHookEntry,
19
+ removeClaudeMcpServers
20
+ } from "./chunk-H4BKC2GN.js";
18
21
  import {
19
22
  HOOK_COMPATIBLE_PROFILES,
20
- HOOK_LOCATOR_BINARY,
21
23
  PHONE_ANSWERED_TOOLS,
22
24
  compatibleTargetFiles,
23
25
  hookCompatibleProfile,
@@ -26,176 +28,7 @@ import {
26
28
  pusharyMissingReason,
27
29
  refusalOutput,
28
30
  withHookHoldBudget
29
- } from "./chunk-FXECTHAG.js";
30
-
31
- // src/claude-config.ts
32
- import { join } from "path";
33
- import { isDeepStrictEqual } from "util";
34
- var PUSHARY_MCP_URL = "https://pushary.com/api/mcp/mcp";
35
- var PUSHARY_PERMISSION_RULE = "mcp__pushary__*";
36
- var asRecord = (value) => value && typeof value === "object" && !Array.isArray(value) ? value : void 0;
37
- var ensureRecord = (target, key) => {
38
- const existing = asRecord(target[key]);
39
- if (existing) return existing;
40
- const created = {};
41
- target[key] = created;
42
- return created;
43
- };
44
- var isPusharyPermission = (rule) => typeof rule === "string" && (rule.includes("pushary") || rule.includes("MCP(pushary"));
45
- var HOOK_BINARIES = /* @__PURE__ */ new Set([
46
- ...CLAUDE_HOOK_EVENTS.map((hook) => hook.binary),
47
- HOOK_LOCATOR_BINARY
48
- ]);
49
- var namesPusharyBinary = (command) => command.split(/[\s/\\"']+/).some((segment) => HOOK_BINARIES.has(segment.replace(/\.(cmd|exe)$/i, "")));
50
- var isPusharyHook = (entry2, scope) => {
51
- const hooks = asRecord(entry2)?.hooks;
52
- if (!Array.isArray(hooks)) return false;
53
- return hooks.some((hook) => {
54
- const command = String(asRecord(hook)?.command ?? "");
55
- if (isProtectedByScope(command, scope)) return false;
56
- return namesPusharyBinary(command);
57
- });
58
- };
59
- var pusharyMcpServer = (apiKey) => ({
60
- type: "http",
61
- url: PUSHARY_MCP_URL,
62
- headers: { Authorization: `Bearer ${apiKey}` }
63
- });
64
- var addClaudeMcpServer = (config, apiKey) => {
65
- const mcpServers = ensureRecord(config, "mcpServers");
66
- mcpServers.pushary = pusharyMcpServer(apiKey);
67
- };
68
- var isClaudeMcpSnapshot = (value) => {
69
- if (!value || typeof value !== "object" || Array.isArray(value)) return false;
70
- const snapshot = value;
71
- return typeof snapshot.hadMcpServers === "boolean" && typeof snapshot.mcpServersWasRecord === "boolean" && (!snapshot.hadMcpServers || snapshot.mcpServersWasRecord || Object.hasOwn(snapshot, "mcpServers")) && typeof snapshot.hadPushary === "boolean" && (!snapshot.hadPushary || Object.hasOwn(snapshot, "pushary")) && (!Object.hasOwn(snapshot, "installedPushary") || asRecord(snapshot.installedPushary)?.type === "http" && asRecord(snapshot.installedPushary)?.url === PUSHARY_MCP_URL);
72
- };
73
- var captureClaudeMcpServer = (config, apiKey) => {
74
- const mcpServers = asRecord(config.mcpServers);
75
- const hadMcpServers = Object.hasOwn(config, "mcpServers");
76
- return {
77
- hadMcpServers,
78
- mcpServersWasRecord: Boolean(mcpServers),
79
- ...hadMcpServers && !mcpServers ? { mcpServers: structuredClone(config.mcpServers) } : {},
80
- hadPushary: Boolean(mcpServers && Object.hasOwn(mcpServers, "pushary")),
81
- ...mcpServers && Object.hasOwn(mcpServers, "pushary") ? { pushary: structuredClone(mcpServers.pushary) } : {},
82
- ...apiKey ? { installedPushary: pusharyMcpServer(apiKey) } : {}
83
- };
84
- };
85
- var updateClaudeMcpSnapshot = (snapshot, apiKey) => ({
86
- ...snapshot,
87
- installedPushary: pusharyMcpServer(apiKey)
88
- });
89
- var restoreClaudeMcpServer = (config, snapshot) => {
90
- const mcpServers = asRecord(config.mcpServers);
91
- const current = asRecord(mcpServers?.pushary);
92
- if (Object.hasOwn(snapshot, "installedPushary")) {
93
- if (!isDeepStrictEqual(mcpServers?.pushary, snapshot.installedPushary)) return false;
94
- } else if (current?.type !== "http" || current.url !== PUSHARY_MCP_URL) {
95
- return false;
96
- }
97
- if (!snapshot.mcpServersWasRecord) {
98
- if (Object.keys(mcpServers).length === 1) {
99
- if (snapshot.hadMcpServers) config.mcpServers = structuredClone(snapshot.mcpServers);
100
- else delete config.mcpServers;
101
- } else {
102
- delete mcpServers.pushary;
103
- }
104
- } else if (snapshot.hadPushary) {
105
- mcpServers.pushary = structuredClone(snapshot.pushary);
106
- } else {
107
- delete mcpServers.pushary;
108
- if (!snapshot.hadMcpServers && Object.keys(mcpServers).length === 0) delete config.mcpServers;
109
- }
110
- return true;
111
- };
112
- var removeClaudeMcpServers = (config) => {
113
- let changed = false;
114
- const removeFrom = (target) => {
115
- const mcpServers = asRecord(target.mcpServers);
116
- if (!mcpServers?.pushary) return;
117
- delete mcpServers.pushary;
118
- if (Object.keys(mcpServers).length === 0) delete target.mcpServers;
119
- changed = true;
120
- };
121
- removeFrom(config);
122
- const projects = asRecord(config.projects);
123
- if (projects) {
124
- for (const project of Object.values(projects)) {
125
- const projectConfig = asRecord(project);
126
- if (projectConfig) removeFrom(projectConfig);
127
- }
128
- }
129
- return changed;
130
- };
131
- var removePusharyToolPermissions = (settings) => {
132
- const permissions = asRecord(settings.permissions);
133
- if (!permissions || !Array.isArray(permissions.allow)) return false;
134
- const filtered = permissions.allow.filter((rule) => !isPusharyPermission(rule));
135
- if (filtered.length === permissions.allow.length) return false;
136
- if (filtered.length === 0) delete permissions.allow;
137
- else permissions.allow = filtered;
138
- if (Object.keys(permissions).length === 0) delete settings.permissions;
139
- return true;
140
- };
141
- var addPusharyToolPermissions = (settings) => {
142
- const permissions = ensureRecord(settings, "permissions");
143
- const allow = Array.isArray(permissions.allow) ? permissions.allow : [];
144
- const filtered = allow.filter((rule) => !isPusharyPermission(rule));
145
- if (!filtered.includes(PUSHARY_PERMISSION_RULE)) {
146
- filtered.push(PUSHARY_PERMISSION_RULE);
147
- }
148
- permissions.allow = filtered;
149
- };
150
- var addPusharyHooks = (settings, binDir, version = null) => {
151
- const resolve = (name) => guardBinary(binDir ? join(binDir, name) : name);
152
- const hooks = ensureRecord(settings, "hooks");
153
- const supported = new Map(supportedClaudeEvents(version).map((hook) => [hook.event, hook]));
154
- for (const known of CLAUDE_HOOK_EVENTS) {
155
- const current = Array.isArray(hooks[known.event]) ? hooks[known.event] : [];
156
- const definition = supported.get(known.event);
157
- if (definition) {
158
- hooks[known.event] = registerHookEntry(current, isPusharyHook, entry(definition, resolve));
159
- continue;
160
- }
161
- const others = current.filter((item) => !isPusharyHook(item));
162
- if (others.length > 0) {
163
- hooks[known.event] = others;
164
- } else {
165
- delete hooks[known.event];
166
- }
167
- }
168
- };
169
- var entry = (definition, resolve) => ({
170
- ...definition.matcher ? { matcher: definition.matcher } : {},
171
- hooks: [{
172
- type: "command",
173
- command: withHookHoldBudget(resolve(definition.binary), holdBudgetOf(definition)),
174
- timeout: definition.timeout
175
- }]
176
- });
177
- var removePusharySettings = (settings, scope) => {
178
- let changed = scope?.keepMcpServer === true ? false : removeClaudeMcpServers(settings);
179
- if (scope?.keepMcpServer !== true && removePusharyToolPermissions(settings)) changed = true;
180
- const hooks = asRecord(settings.hooks);
181
- if (hooks) {
182
- for (const { event: key } of CLAUDE_HOOK_EVENTS) {
183
- const entries = hooks[key];
184
- if (!Array.isArray(entries)) continue;
185
- const filtered = entries.filter((entry2) => !isPusharyHook(entry2, scope));
186
- if (filtered.length !== entries.length) {
187
- if (filtered.length === 0) {
188
- delete hooks[key];
189
- } else {
190
- hooks[key] = filtered;
191
- }
192
- changed = true;
193
- }
194
- }
195
- if (Object.keys(hooks).length === 0) delete settings.hooks;
196
- }
197
- return changed;
198
- };
31
+ } from "./chunk-MNKIR2ZB.js";
199
32
 
200
33
  // src/config-document.ts
201
34
  import { parse, stringify } from "smol-toml";
@@ -220,7 +53,7 @@ var serializeConfigDocument = (value, format) => format === "toml" ? stringify(v
220
53
 
221
54
  // src/compatible-config.ts
222
55
  import { homedir } from "os";
223
- import { join as join2 } from "path";
56
+ import { join } from "path";
224
57
  var hasCompatibleMcpServer = (profile, contents) => {
225
58
  if (!profile.mcp) return false;
226
59
  const document = parseConfigDocument(contents, profile.mcp.file.format);
@@ -272,8 +105,8 @@ function normalizeToolCall(profile, input) {
272
105
  const lookup = compatibleToolLookup(profile, input.tool_name, input.tool_input ?? {}, input.cwd);
273
106
  return { ...input, tool_name: lookup.tool, tool_input: lookup.input };
274
107
  }
275
- var grokHome = (home = homedir(), environment = process.env) => environment.GROK_HOME?.trim() || join2(home, ".grok");
276
- var compatibleFilePath = (file, home = homedir()) => join2(file.root === "grok_home" ? grokHome(home) : home, ...file.path);
108
+ var grokHome = (home = homedir(), environment = process.env) => environment.GROK_HOME?.trim() || join(home, ".grok");
109
+ var compatibleFilePath = (file, home = homedir()) => join(file.root === "grok_home" ? grokHome(home) : home, ...file.path);
277
110
  var compatibleDocuments = (profile, home) => {
278
111
  const documents = /* @__PURE__ */ new Map();
279
112
  for (const file of [profile.configFile, profile.mcp?.file, profile.permissionRuleFile]) {
@@ -292,21 +125,21 @@ var compatibleInstructionsFile = (profile, home) => profile.instructions ? compa
292
125
  var PUSHARY_OWNED_FILE_STEM = "pushary";
293
126
  var isPusharyOwnedFile = (file) => file.path.at(-1)?.split(".")[0] === PUSHARY_OWNED_FILE_STEM;
294
127
  var isEmptiedPusharyOwnedDocument = (file, document) => isPusharyOwnedFile(file) && Object.keys(document).length === 0;
295
- var asRecord2 = (value) => value && typeof value === "object" && !Array.isArray(value) ? value : void 0;
296
- var ensureRecord2 = (target, key) => {
297
- const existing = asRecord2(target[key]);
128
+ var asRecord = (value) => value && typeof value === "object" && !Array.isArray(value) ? value : void 0;
129
+ var ensureRecord = (target, key) => {
130
+ const existing = asRecord(target[key]);
298
131
  if (existing) return existing;
299
132
  const created = {};
300
133
  target[key] = created;
301
134
  return created;
302
135
  };
303
- var descend = (config, keyPath) => keyPath.reduce(ensureRecord2, config);
304
- var findMap = (config, keyPath) => keyPath.reduce((node, key) => node && asRecord2(node[key]), config);
136
+ var descend = (config, keyPath) => keyPath.reduce(ensureRecord, config);
137
+ var findMap = (config, keyPath) => keyPath.reduce((node, key) => node && asRecord(node[key]), config);
305
138
  var pruneEmptyMap = (config, keyPath) => {
306
139
  if (keyPath.length === 0) return false;
307
140
  const parent = findMap(config, keyPath.slice(0, -1));
308
141
  const key = keyPath[keyPath.length - 1];
309
- const map = asRecord2(parent?.[key]);
142
+ const map = asRecord(parent?.[key]);
310
143
  if (!parent || !map || Object.keys(map).length > 0) return false;
311
144
  delete parent[key];
312
145
  return true;
@@ -320,11 +153,11 @@ var translateMatcher = (profile, definition, matcher) => {
320
153
  return [.../* @__PURE__ */ new Set([...spellings, ...soleGateCoverage(profile, definition), ...profile.extraMatchers])].join("|");
321
154
  };
322
155
  var TOOL_MATCHED_EVENTS = /* @__PURE__ */ new Set(["PreToolUse", "PostToolUse", "PostToolUseFailure"]);
323
- var isPusharyHandler = (entry2, scope) => {
324
- const record = asRecord2(entry2);
156
+ var isPusharyHandler = (entry, scope) => {
157
+ const record = asRecord(entry);
325
158
  return record !== void 0 && !Array.isArray(record.hooks) && isPusharyHook({ hooks: [record] }, scope);
326
159
  };
327
- var isPusharyCompatibleEntry = (entry2, scope) => isPusharyHook(entry2, scope) || isPusharyHandler(entry2, scope);
160
+ var isPusharyCompatibleEntry = (entry, scope) => isPusharyHook(entry, scope) || isPusharyHandler(entry, scope);
328
161
  var withoutMatcher = ({ matcher, ...hook }) => hook;
329
162
  var compatibleDefinitions = (profile) => {
330
163
  if (profile.source !== "grok") return CLAUDE_HOOK_EVENTS;
@@ -343,12 +176,12 @@ var WRITTEN = { ok: true };
343
176
  var ROOT_KEY = "(root)";
344
177
  var dotted = (segments) => segments.join(".") || ROOT_KEY;
345
178
  var hooksShapeConflict = (config, profile) => {
346
- if (!asRecord2(config)) return ROOT_KEY;
179
+ if (!asRecord(config)) return ROOT_KEY;
347
180
  const walked = [];
348
181
  let node = config;
349
182
  for (const key of profile.hooksKeyPath) {
350
183
  if (node[key] === void 0) return void 0;
351
- const nested = asRecord2(node[key]);
184
+ const nested = asRecord(node[key]);
352
185
  if (!nested) return dotted([...walked, key]);
353
186
  walked.push(key);
354
187
  node = nested;
@@ -357,9 +190,9 @@ var hooksShapeConflict = (config, profile) => {
357
190
  return clash ? dotted([...walked, clash.event]) : void 0;
358
191
  };
359
192
  var permissionsShapeConflict = (config) => {
360
- if (!asRecord2(config)) return ROOT_KEY;
193
+ if (!asRecord(config)) return ROOT_KEY;
361
194
  if (config.permissions === void 0) return void 0;
362
- const permissions = asRecord2(config.permissions);
195
+ const permissions = asRecord(config.permissions);
363
196
  if (!permissions) return "permissions";
364
197
  return permissions.allow !== void 0 && !Array.isArray(permissions.allow) ? "permissions.allow" : void 0;
365
198
  };
@@ -393,7 +226,7 @@ var addCompatibleHooks = (config, profile, binDir) => {
393
226
  const current = Array.isArray(hooks[known.event]) ? hooks[known.event] : [];
394
227
  const definition = supported.get(known.event);
395
228
  if (definition) {
396
- const resolve = (name) => guardFor(profile, definition, binDir ? join2(binDir, name) : name);
229
+ const resolve = (name) => guardFor(profile, definition, binDir ? join(binDir, name) : name);
397
230
  hooks[known.event] = registerHookEntry(current, isPusharyCompatibleEntry, entryFor(profile, definition, resolve));
398
231
  continue;
399
232
  }
@@ -410,7 +243,7 @@ var removeCompatibleHooks = (config, profile, scope) => {
410
243
  for (const { event } of compatibleDefinitions(profile)) {
411
244
  const entries = hooks[event];
412
245
  if (!Array.isArray(entries)) continue;
413
- const kept = entries.filter((entry2) => !isPusharyCompatibleEntry(entry2, scope));
246
+ const kept = entries.filter((entry) => !isPusharyCompatibleEntry(entry, scope));
414
247
  if (kept.length === entries.length) continue;
415
248
  if (kept.length === 0) delete hooks[event];
416
249
  else hooks[event] = kept;
@@ -424,14 +257,14 @@ var hasCompatibleHooks = (config, profile) => {
424
257
  if (!hooks) return false;
425
258
  return compatibleHookEvents(profile).some(({ event }) => {
426
259
  const entries = hooks[event];
427
- return Array.isArray(entries) && entries.some((entry2) => isPusharyCompatibleEntry(entry2));
260
+ return Array.isArray(entries) && entries.some((entry) => isPusharyCompatibleEntry(entry));
428
261
  });
429
262
  };
430
263
  var missingCompatibleHookEvents = (config, profile) => {
431
264
  const hooks = findMap(config, profile.hooksKeyPath);
432
265
  return compatibleHookEvents(profile).filter(({ event }) => {
433
266
  const entries = hooks?.[event];
434
- return !Array.isArray(entries) || !entries.some((entry2) => isPusharyCompatibleEntry(entry2));
267
+ return !Array.isArray(entries) || !entries.some((entry) => isPusharyCompatibleEntry(entry));
435
268
  }).map(({ event }) => event);
436
269
  };
437
270
  var compatiblePermissionRuleFile = (profile, home) => profile.permissionRuleFile ? compatibleFilePath(profile.permissionRuleFile, home) : null;
@@ -439,8 +272,8 @@ var addCompatibleMcpServer = (config, profile, apiKey) => {
439
272
  if (!profile.mcp) return;
440
273
  if (profile.mcp.shape === "grok_http") {
441
274
  const container = profile.mcp.container;
442
- if (config[container] !== void 0 && !asRecord2(config[container])) throw new Error(`${profile.label} ${container} is not a table; configuration was left unchanged.`);
443
- ensureRecord2(config, container).pushary = { url: PUSHARY_MCP_URL, headers: { Authorization: `Bearer ${apiKey}` } };
275
+ if (config[container] !== void 0 && !asRecord(config[container])) throw new Error(`${profile.label} ${container} is not a table; configuration was left unchanged.`);
276
+ ensureRecord(config, container).pushary = { url: PUSHARY_MCP_URL, headers: { Authorization: `Bearer ${apiKey}` } };
444
277
  return;
445
278
  }
446
279
  if (profile.mcp.shape === "gemini_http") {
@@ -448,7 +281,7 @@ var addCompatibleMcpServer = (config, profile, apiKey) => {
448
281
  return;
449
282
  }
450
283
  if (profile.mcp.shape === "antigravity_http") {
451
- ensureRecord2(config, "mcpServers").pushary = {
284
+ ensureRecord(config, "mcpServers").pushary = {
452
285
  serverUrl: PUSHARY_MCP_URL,
453
286
  headers: { Authorization: `Bearer ${apiKey}` }
454
287
  };
@@ -456,14 +289,14 @@ var addCompatibleMcpServer = (config, profile, apiKey) => {
456
289
  }
457
290
  addClaudeMcpServer(config, apiKey);
458
291
  if (!profile.mcp.trusted) return;
459
- const server = asRecord2(asRecord2(config.mcpServers)?.pushary);
292
+ const server = asRecord(asRecord(config.mcpServers)?.pushary);
460
293
  if (server) server.trust = true;
461
294
  };
462
295
  var removeCompatibleMcpServer = (config, profile) => {
463
296
  if (!profile.mcp) return false;
464
297
  if (profile.mcp.shape === "grok_http") {
465
298
  const container = profile.mcp.container;
466
- const servers = asRecord2(config[container]);
299
+ const servers = asRecord(config[container]);
467
300
  if (!servers || servers.pushary === void 0) return false;
468
301
  delete servers.pushary;
469
302
  if (Object.keys(servers).length === 0) delete config[container];
@@ -475,16 +308,6 @@ var removeCompatibleMcpServer = (config, profile) => {
475
308
  export {
476
309
  readConfigDocument,
477
310
  serializeConfigDocument,
478
- addClaudeMcpServer,
479
- isClaudeMcpSnapshot,
480
- captureClaudeMcpServer,
481
- updateClaudeMcpSnapshot,
482
- restoreClaudeMcpServer,
483
- removeClaudeMcpServers,
484
- removePusharyToolPermissions,
485
- addPusharyToolPermissions,
486
- addPusharyHooks,
487
- removePusharySettings,
488
311
  hasCompatibleMcpServer,
489
312
  profileFromArgv,
490
313
  activeIdentity,
@@ -168,7 +168,8 @@ var defaults = {
168
168
  activationGuide: null,
169
169
  enforcementDetail: "Cooperative. The agent chooses when to ask; no native permission interception.",
170
170
  capabilityNote: "",
171
- documented: true
171
+ documented: true,
172
+ keepsSessionHistory: false
172
173
  };
173
174
  var AGENTS = {
174
175
  claude_code: {
@@ -184,7 +185,8 @@ var AGENTS = {
184
185
  enforcement: "enforced",
185
186
  connectVia: "Native hooks + MCP",
186
187
  setupCommand: PUSHARY_SETUP_COMMAND,
187
- enforcementDetail: "Shell, writes and edits, subject to Claude Code permission mode and explicit policy."
188
+ enforcementDetail: "Shell, writes and edits, subject to Claude Code permission mode and explicit policy.",
189
+ keepsSessionHistory: true
188
190
  },
189
191
  claude_chat: {
190
192
  ...defaults,
@@ -211,7 +213,8 @@ var AGENTS = {
211
213
  enforcement: "enforced",
212
214
  connectVia: "Native hooks + MCP",
213
215
  setupCommand: PUSHARY_SETUP_COMMAND,
214
- enforcementDetail: "Shell and apply_patch edits through native permission hooks; requires a compatible Codex runtime."
216
+ enforcementDetail: "Shell and apply_patch edits through native permission hooks; requires a compatible Codex runtime.",
217
+ keepsSessionHistory: true
215
218
  },
216
219
  chatgpt: {
217
220
  ...defaults,
@@ -231,7 +234,8 @@ var AGENTS = {
231
234
  enforcement: "enforced",
232
235
  connectVia: "Native hooks + MCP",
233
236
  setupCommand: PUSHARY_SETUP_COMMAND,
234
- enforcementDetail: "Shell, writes, edits and MCP calls through native BeforeTool hooks."
237
+ enforcementDetail: "Shell, writes, edits and MCP calls through native BeforeTool hooks.",
238
+ keepsSessionHistory: true
235
239
  },
236
240
  hermes: {
237
241
  ...defaults,
@@ -288,6 +292,14 @@ var AGENTS = {
288
292
  setupCommand: PUSHARY_SETUP_COMMAND,
289
293
  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."
290
294
  },
295
+ cline: {
296
+ ...defaults,
297
+ label: "Cline",
298
+ disconnectable: true,
299
+ connectVia: "MCP with your key + global rule",
300
+ setupCommand: PUSHARY_SETUP_COMMAND,
301
+ capabilityNote: "Setup writes the Pushary server, with your key, into Cline's shared MCP settings and a global rule that tells Cline to ask and notify through Pushary. Cline's own approval prompts stay in VS Code. Auto-approving MCP servers in Cline lets Pushary calls run without a click there, and it applies to every MCP server Cline has, not only Pushary."
302
+ },
291
303
  qwen_code: {
292
304
  ...defaults,
293
305
  label: "Qwen Code",
@@ -427,6 +439,9 @@ var POLICY_AGENTS = [...Object.values(AGENTS).flatMap((agent) => agent.policyAge
427
439
  var AGENT_LABELS_BY_TYPE = Object.fromEntries(
428
440
  Object.entries(AGENTS).flatMap(([id, agent]) => agent.hasStoredIdentity ? [[id, agent.label]] : [])
429
441
  );
442
+ var SESSION_HISTORY_AGENT_TYPES = Object.freeze(
443
+ Object.entries(AGENTS).flatMap(([id, agent]) => agent.keepsSessionHistory ? [id] : [])
444
+ );
430
445
  var DISCONNECTABLE_AGENTS = Object.freeze(Object.values(AGENTS).flatMap((agent) => agent.disconnectable && agent.hookSource !== null ? [agent.hookSource] : []));
431
446
  var REPO_AWARE_AGENTS = Object.freeze(Object.values(AGENTS).flatMap((agent) => agent.repoAware ? [agent.policyAgent] : []));
432
447
  var MANAGED_PROVIDERS = Object.freeze(Object.values(AGENTS).flatMap((agent) => agent.managedProvider ? [agent.hookSource] : []));
@@ -2637,6 +2652,7 @@ var AGENT_SITE_REJECTION_REASONS = [
2637
2652
  "no_current_site"
2638
2653
  ];
2639
2654
  var AUTH_REJECTION_REASONS = [
2655
+ "sign_in_required",
2640
2656
  "malformed_key",
2641
2657
  "unknown_key",
2642
2658
  "expired_key",
@@ -2707,6 +2723,7 @@ var SETUP_AGENT_CHOICES = [
2707
2723
  "vscode",
2708
2724
  "opencode",
2709
2725
  "fx",
2726
+ "cline",
2710
2727
  ...COMPATIBLE_AGENT_TYPES,
2711
2728
  "custom"
2712
2729
  ];
@@ -2718,6 +2735,7 @@ var NO_PAIRING_COMPUTER = { computerName: null, os: null, agents: null };
2718
2735
  var SETUP_AGENT_FAILURE_KINDS = [
2719
2736
  "config-unparseable",
2720
2737
  "config-unreadable",
2738
+ "config-conflict",
2721
2739
  "installer-error",
2722
2740
  "not-wired",
2723
2741
  "app-account-mismatch"
@@ -3039,6 +3057,20 @@ var codexNativeApprovalResponse = (approval, answer) => {
3039
3057
  return { decision: accepted ? "accept" : approval.negativeDecision };
3040
3058
  };
3041
3059
 
3060
+ // ../contracts/src/transcript-record.ts
3061
+ var COMPRESSED_TRANSCRIPT_RECORD_MARKER = 1;
3062
+ var TRANSCRIPT_RECORD_MAX_INFLATED_BYTES = 1024 * 1024;
3063
+ var compressionShrinks = (raw, deflated) => deflated.length + 1 < raw.length;
3064
+ var compressTranscriptRecord = (raw, deflateRaw) => {
3065
+ if (raw.length > TRANSCRIPT_RECORD_MAX_INFLATED_BYTES) return raw;
3066
+ const deflated = deflateRaw(raw);
3067
+ if (!compressionShrinks(raw, deflated)) return raw;
3068
+ const record3 = new Uint8Array(deflated.length + 1);
3069
+ record3[0] = COMPRESSED_TRANSCRIPT_RECORD_MARKER;
3070
+ record3.set(deflated, 1);
3071
+ return record3;
3072
+ };
3073
+
3042
3074
  // ../contracts/src/index.ts
3043
3075
  var KEY_SCOPES = ["full_access", "agent", "connector", "bound"];
3044
3076
  var normalizeKeyScope = (value) => typeof value === "string" && KEY_SCOPES.includes(value) ? value : null;
@@ -6338,6 +6370,7 @@ export {
6338
6370
  CODEX_NATIVE_APPROVAL_REPLIES,
6339
6371
  parseCodexNativeApproval,
6340
6372
  codexNativeApprovalResponse,
6373
+ compressTranscriptRecord,
6341
6374
  normalizeKeyScope,
6342
6375
  isApprovalMode,
6343
6376
  approvalModeWithoutLocalPrompt,