pushary 1.9.0 → 1.9.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.
Files changed (98) hide show
  1. package/CHANGELOG.md +7 -0
  2. package/dist/bin/pushary-bell-hook.js +23 -23
  3. package/dist/bin/pushary-bell.js +9 -9
  4. package/dist/bin/pushary-claude.js +26 -26
  5. package/dist/bin/pushary-clean.js +28 -28
  6. package/dist/bin/pushary-codex-bridge.js +18 -18
  7. package/dist/bin/pushary-codex-hook.js +31 -31
  8. package/dist/bin/pushary-codex.js +13 -13
  9. package/dist/bin/pushary-connect.js +13 -13
  10. package/dist/bin/pushary-cowork.js +5 -5
  11. package/dist/bin/pushary-daemon.js +26 -26
  12. package/dist/bin/pushary-disconnect.js +18 -18
  13. package/dist/bin/pushary-doctor.js +30 -30
  14. package/dist/bin/pushary-elicitation-hook.js +25 -25
  15. package/dist/bin/pushary-gemini-bridge.js +13 -13
  16. package/dist/bin/pushary-gemini-hook.js +28 -28
  17. package/dist/bin/pushary-hook.js +32 -32
  18. package/dist/bin/pushary-login.js +12 -12
  19. package/dist/bin/pushary-logout.js +7 -7
  20. package/dist/bin/pushary-mcp.js +9 -9
  21. package/dist/bin/pushary-mode.js +9 -9
  22. package/dist/bin/pushary-notification-hook.js +28 -28
  23. package/dist/bin/pushary-opencode-hook.js +27 -27
  24. package/dist/bin/pushary-permission-denied-hook.js +32 -32
  25. package/dist/bin/pushary-permission-hook.js +31 -31
  26. package/dist/bin/pushary-post-hook.js +28 -28
  27. package/dist/bin/pushary-prompt-hook.js +28 -28
  28. package/dist/bin/pushary-session-end-hook.js +28 -28
  29. package/dist/bin/pushary-session-start-hook.js +31 -31
  30. package/dist/bin/pushary-setup.js +36 -36
  31. package/dist/bin/pushary-stats.js +5 -5
  32. package/dist/bin/pushary-status.js +15 -15
  33. package/dist/bin/pushary-stop-hook.js +28 -28
  34. package/dist/bin/pushary-stopfailure-hook.js +28 -28
  35. package/dist/bin/pushary-suggestions.js +4 -4
  36. package/dist/bin/pushary-transcript-register.js +19 -19
  37. package/dist/bin/pushary-transcripts.js +7 -7
  38. package/dist/bin/pushary-upgrade.js +42 -394
  39. package/dist/bin/pushary-wait.js +9 -9
  40. package/dist/bin/pushary.js +6 -6
  41. package/dist/{chunk-EG46RJRF.js → chunk-4SB46XLF.js} +1 -1
  42. package/dist/{chunk-KETBIX7I.js → chunk-4XT4JXMG.js} +1 -1
  43. package/dist/{chunk-NAJ3UV4E.js → chunk-5K43TBK4.js} +3 -3
  44. package/dist/{chunk-OLG6FJV2.js → chunk-65TOHCXT.js} +4 -4
  45. package/dist/{chunk-P6VDRQF3.js → chunk-6JTTJIKJ.js} +3 -3
  46. package/dist/{chunk-3OFHFVPX.js → chunk-6L7TNZ43.js} +1 -1
  47. package/dist/{chunk-MQJWO3AA.js → chunk-6Q4NM2LW.js} +3 -3
  48. package/dist/{chunk-US3RDXK7.js → chunk-6QSDNXGM.js} +2 -2
  49. package/dist/{chunk-MBVV3RX3.js → chunk-7ER66HZH.js} +1 -1
  50. package/dist/{chunk-7TQQSQZ7.js → chunk-AKCJ5SNO.js} +6 -6
  51. package/dist/{chunk-HQWPMVR4.js → chunk-C6PPDKVI.js} +3 -3
  52. package/dist/{chunk-P25O4K3J.js → chunk-CE4UH4AP.js} +2 -2
  53. package/dist/{chunk-HHNFGWR5.js → chunk-CGRPHFOV.js} +1 -1
  54. package/dist/{chunk-RZXQFAWR.js → chunk-COSADFEH.js} +1 -1
  55. package/dist/{chunk-YFS4HYCI.js → chunk-D3RS57MN.js} +3 -3
  56. package/dist/{chunk-75CEJ4WP.js → chunk-DMA3QUOB.js} +3 -3
  57. package/dist/{chunk-MGXXQHCM.js → chunk-FJPC35OW.js} +1 -1
  58. package/dist/{chunk-SDSKTRIV.js → chunk-FVOCQSBG.js} +1 -1
  59. package/dist/{chunk-YJZDIFON.js → chunk-GHKNUQYU.js} +2 -2
  60. package/dist/{chunk-ET6QSY3H.js → chunk-HU2LWGEE.js} +1 -1
  61. package/dist/{chunk-CFAD2LTH.js → chunk-IITCMJ4G.js} +2 -2
  62. package/dist/{chunk-HNMMKFYN.js → chunk-IJXJW2VH.js} +10 -10
  63. package/dist/{chunk-VV4SBPCQ.js → chunk-J7JXA2LX.js} +1 -1
  64. package/dist/{chunk-42E4DE6C.js → chunk-JCER3Q6P.js} +9 -9
  65. package/dist/{chunk-K75TP4JY.js → chunk-JGQ2ANHQ.js} +2 -2
  66. package/dist/{chunk-ZMVLKPT7.js → chunk-JHZAZAI3.js} +5 -5
  67. package/dist/{chunk-JW7DKTT6.js → chunk-KR5JASA4.js} +2 -2
  68. package/dist/{chunk-MBNMO5IR.js → chunk-LJI7U6PM.js} +2 -2
  69. package/dist/{chunk-4ZXYWEEH.js → chunk-LKKYRNJT.js} +1 -1
  70. package/dist/{chunk-TUZ7WKOF.js → chunk-LXWUYG7D.js} +1 -1
  71. package/dist/{chunk-2V64X5RE.js → chunk-LZMH4EGE.js} +1 -1
  72. package/dist/{chunk-CKPDSFY3.js → chunk-NVLXK2I6.js} +5 -5
  73. package/dist/{chunk-IJJ3HHFT.js → chunk-P7YDVWLL.js} +1 -1
  74. package/dist/{chunk-LQESQPIT.js → chunk-PEGKBNGN.js} +5 -5
  75. package/dist/{chunk-HSM5FIA3.js → chunk-PMS3EBD2.js} +1 -1
  76. package/dist/chunk-QQJCDRD3.js +242 -0
  77. package/dist/chunk-QXL27RY6.js +175 -0
  78. package/dist/{chunk-ZRHA4PGN.js → chunk-RJ7ECJSZ.js} +2 -2
  79. package/dist/{chunk-VYNTRHB6.js → chunk-RNDFGHSQ.js} +1 -1
  80. package/dist/{chunk-4GMZOGH4.js → chunk-RS4ZOFSF.js} +4 -4
  81. package/dist/{chunk-JOQEPWDH.js → chunk-SKEP3M6M.js} +2 -2
  82. package/dist/{chunk-BG4QCOHQ.js → chunk-SPB3QRE7.js} +4 -4
  83. package/dist/{chunk-XXVMUMKT.js → chunk-SWGY5WNX.js} +5 -5
  84. package/dist/{chunk-OXQKXZJ3.js → chunk-UPTEPARD.js} +2 -2
  85. package/dist/{chunk-IQUBCAEK.js → chunk-UYHLMBPQ.js} +1 -1
  86. package/dist/{chunk-K7DY2DQN.js → chunk-V4H33GBM.js} +6 -6
  87. package/dist/{chunk-CPBRXBLG.js → chunk-VH6763OR.js} +3 -3
  88. package/dist/{chunk-7LLNRCOK.js → chunk-VQLWYKX7.js} +1 -1
  89. package/dist/{chunk-WFVNXGZ6.js → chunk-WWDPULS3.js} +8 -8
  90. package/dist/{chunk-4PCF34AB.js → chunk-XEIV5QOT.js} +75 -23
  91. package/dist/{chunk-XGS2DHGF.js → chunk-XW2B4QV2.js} +2 -2
  92. package/dist/{chunk-R76C43H7.js → chunk-ZMKEKWNR.js} +70 -49
  93. package/dist/global-upgrade-ML2RHV4W.js +24 -0
  94. package/dist/paths-LG3IEDDM.js +71 -0
  95. package/dist/{reapply-FYCVOWCW.js → reapply-7PFOITE4.js} +8 -8
  96. package/dist/src/index.js +20 -20
  97. package/dist/upgrade-lock-2A2YUUEU.js +17 -0
  98. package/package.json +1 -1
@@ -1186,6 +1186,7 @@ var isSafeSimpleCommand = (segment) => {
1186
1186
  if (/^[A-Za-z_][A-Za-z0-9_]*=/.test(first) || first.includes("$")) return false;
1187
1187
  if (!isTrustedExecutable(first)) return false;
1188
1188
  const exe = basenameOf(first);
1189
+ if (INSPECTED_ARGUMENT_COMMANDS.has(exe) && argumentsMayExpand(segment)) return false;
1189
1190
  if (exe === "git") {
1190
1191
  const sub = tokens[1];
1191
1192
  if (!sub || sub.startsWith("-")) return false;
@@ -1200,25 +1201,73 @@ var isSafeSimpleCommand = (segment) => {
1200
1201
  }
1201
1202
  return true;
1202
1203
  }
1204
+ if (exe === "sed") return isPrintOnlySed(tokens.slice(1));
1205
+ if (exe === "date") return isReadOnlyDate(tokens.slice(1));
1203
1206
  return SAFE_SHELL_COMMANDS.has(exe);
1204
1207
  };
1208
+ var SED_PRINT_ONLY_SCRIPT = /^(?:\d+|\$)(?:,(?:\d+|\$))?p$/;
1209
+ var SED_QUIET_FLAG = "-n";
1210
+ var DATE_FORMAT_PREFIX = "+";
1211
+ var DATE_UTC_FLAG = "-u";
1212
+ var isFlagToken = (token) => token.startsWith("-");
1213
+ var isPrintOnlySed = (args) => args[0] === SED_QUIET_FLAG && SED_PRINT_ONLY_SCRIPT.test(args[1] ?? "") && !args.slice(2).some(isFlagToken);
1214
+ var isReadOnlyDate = (args) => args.every((arg) => arg.startsWith(DATE_FORMAT_PREFIX) || arg === DATE_UTC_FLAG);
1215
+ var SINGLE_QUOTE = "'";
1216
+ var QUOTED_LITERAL = "_";
1217
+ var LITERAL_IN_DOUBLE_QUOTES = /* @__PURE__ */ new Set([";", "|", "&", "<", ">", "*", "?", "[", SHELL_ESCAPE]);
1218
+ var READ_ONLY_SEGMENT_SEPARATOR = /&&|\|\||[;|]/g;
1219
+ var PIPELINE_CHAIN_SEPARATOR = /&&|\|\||;/g;
1220
+ var shellVisibleText = (command) => {
1221
+ let visible = "";
1222
+ let quote = null;
1223
+ for (let index = 0; index < command.length; index += 1) {
1224
+ const char = command[index];
1225
+ if (quote === SINGLE_QUOTE) {
1226
+ quote = char === SINGLE_QUOTE ? null : quote;
1227
+ visible += quote === null ? char : QUOTED_LITERAL;
1228
+ continue;
1229
+ }
1230
+ if (quote === SHELL_DOUBLE_QUOTE) {
1231
+ if (char === SHELL_ESCAPE && DOUBLE_QUOTE_ESCAPABLE.has(command[index + 1] ?? "")) return null;
1232
+ quote = char === SHELL_DOUBLE_QUOTE ? null : quote;
1233
+ visible += quote !== null && LITERAL_IN_DOUBLE_QUOTES.has(char) ? QUOTED_LITERAL : char;
1234
+ continue;
1235
+ }
1236
+ if (SHELL_QUOTES.has(char)) quote = char;
1237
+ visible += char;
1238
+ }
1239
+ return quote === null ? visible : null;
1240
+ };
1241
+ var EXPANSION_THAT_CAN_BECOME_A_FLAG = /\$|(?:^|\s)[*?[]/;
1242
+ var SHELL_QUOTE_CHARACTERS = /['"]/g;
1243
+ var INSPECTED_ARGUMENT_COMMANDS = /* @__PURE__ */ new Set(["git", "find", "sed", "date"]);
1244
+ var argumentsMayExpand = (segment) => {
1245
+ const visible = shellVisibleText(segment);
1246
+ return visible === null || EXPANSION_THAT_CAN_BECOME_A_FLAG.test(visible.replace(SHELL_QUOTE_CHARACTERS, ""));
1247
+ };
1248
+ var blankedSafeRedirections = (text) => text.replace(SAFE_REDIRECTION, (redirection) => " ".repeat(redirection.length));
1249
+ var segmentsSplitWhereVisible = (command, visible, separators) => {
1250
+ const segments = [];
1251
+ let start = 0;
1252
+ for (const separator of visible.matchAll(separators)) {
1253
+ segments.push(command.slice(start, separator.index));
1254
+ start = separator.index + separator[0].length;
1255
+ }
1256
+ segments.push(command.slice(start));
1257
+ return segments;
1258
+ };
1205
1259
  var isSafeReadOnlyCommand = (command) => {
1206
1260
  const trimmed = command.trim();
1207
1261
  if (!trimmed || trimmed.length > 2e3) return false;
1208
- if (/[`\n\r{}]/.test(trimmed)) return false;
1209
- if (/;|\|\|/.test(trimmed)) return false;
1210
- if (/\\(?![()!])/.test(trimmed)) return false;
1211
- if (/(?<!\\)[()]/.test(trimmed)) return false;
1212
- const noRedir = trimmed.replace(SAFE_REDIRECTION, " ");
1213
- if (/[<>]/.test(noRedir)) return false;
1214
- if (noRedir.replace(/&&/g, " ").includes("&")) return false;
1215
- for (const andPart of noRedir.split("&&")) {
1216
- if (!andPart.trim()) return false;
1217
- for (const segment of andPart.split("|")) {
1218
- if (!isSafeSimpleCommand(segment)) return false;
1219
- }
1220
- }
1221
- return true;
1262
+ if (/[\n\r]/.test(trimmed)) return false;
1263
+ const visible = shellVisibleText(trimmed);
1264
+ if (visible === null || /[`{}]|\$'/.test(visible)) return false;
1265
+ if (/\\(?![()!])/.test(visible)) return false;
1266
+ if (/(?<!\\)[()]/.test(visible)) return false;
1267
+ const visibleWithoutRedirection = blankedSafeRedirections(visible);
1268
+ if (/[<>]/.test(visibleWithoutRedirection)) return false;
1269
+ if (visibleWithoutRedirection.replace(/&&/g, " ").includes("&")) return false;
1270
+ return segmentsSplitWhereVisible(blankedSafeRedirections(trimmed), visibleWithoutRedirection, READ_ONLY_SEGMENT_SEPARATOR).every((segment) => segment.trim().length > 0 && isSafeSimpleCommand(segment));
1222
1271
  };
1223
1272
  var isAutoApprove = (policy) => policy.timeoutSeconds === 0 && policy.timeoutAction === "approve";
1224
1273
  var isAutoDeny = (policy) => policy.timeoutSeconds === 0 && policy.timeoutAction === "deny";
@@ -1542,6 +1591,7 @@ var segmentNeedsAPerson = (toolName, segment) => {
1542
1591
  return invocationHidesItsEffect(invocation) || subcommandDestroys(invocation) || classifyDecisionRisk(toolName, normalized) !== "standard" || isCoveredByPolicy(CAPABILITY_PATTERNS.destructive, toolName, normalized) || isCoveredByPolicy(CAPABILITY_PATTERNS.network, toolName, normalized) || isCoveredByPolicy(DATA_LOSS_COMMAND_PATTERNS, toolName, normalized);
1543
1592
  };
1544
1593
  var commandNeedsAPerson = (toolName, command) => {
1594
+ if (toolName === "Bash" && isSafeReadOnlyCommand(command)) return false;
1545
1595
  const segments = readableCommandSegments(command);
1546
1596
  return segments === null || classifyDecisionRisk(toolName, command) !== "standard" || segments.some((segment) => segmentNeedsAPerson(toolName, segment));
1547
1597
  };
@@ -1619,11 +1669,7 @@ ${body}`;
1619
1669
  const highConsequence = HIGH_CONSEQUENCE_PATTERNS.some((re) => re.test(scanText));
1620
1670
  return { isCommand: command, commandText, path, highConsequence };
1621
1671
  };
1622
- var isDestructive = (toolName, commandText) => {
1623
- const haystack = `${toolName ?? ""}
1624
- ${commandText}`;
1625
- return APPROVAL_FATIGUE_FLAG_PATTERNS.some((re) => re.test(haystack));
1626
- };
1672
+ var isDestructive = (toolName, commandText) => namesADestructiveAction(toolName ?? "", commandText);
1627
1673
  var addAlnumTokens = (source, set) => {
1628
1674
  for (const raw of source.toLowerCase().split(/[^a-z0-9]+/)) {
1629
1675
  if (raw) set.add(raw);
@@ -1776,11 +1822,17 @@ var SETTLED_OUTCOME = {
1776
1822
  deny: "deny"
1777
1823
  };
1778
1824
  var isSettledOutcome = (value) => typeof value === "string" && SETTLED_OUTCOMES.includes(value);
1825
+ var commandTextThatCanAct = (command) => {
1826
+ const visible = shellVisibleText(command);
1827
+ return visible === null ? command : segmentsSplitWhereVisible(command, visible, PIPELINE_CHAIN_SEPARATOR).filter((pipeline) => !isSafeReadOnlyCommand(pipeline)).join("\n");
1828
+ };
1829
+ var destructiveKeywordTarget = (toolName, toolTarget) => toolName === "Bash" ? commandTextThatCanAct(toolTarget) : toolTarget;
1830
+ var matchesAnyPattern = (patterns, parts) => parts.some((part) => patterns.some((re) => re.test(part)));
1831
+ var namesADestructiveAction = (toolName, toolTarget) => matchesAnyPattern(APPROVAL_FATIGUE_FLAG_PATTERNS, [toolName, destructiveKeywordTarget(toolName, toolTarget)]);
1779
1832
  var classifyDecisionRisk = (toolName, toolTarget) => {
1780
- const parts = [toolName, toolTarget ?? ""];
1781
- const matchesAny = (patterns) => parts.some((part) => patterns.some((re) => re.test(part)));
1782
- if (matchesAny(APPROVAL_FATIGUE_FLAG_PATTERNS)) return "destructive";
1783
- if (matchesAny(HIGH_CONSEQUENCE_PATTERNS)) return "elevated";
1833
+ const target = toolTarget ?? "";
1834
+ if (namesADestructiveAction(toolName, target)) return "destructive";
1835
+ if (matchesAnyPattern(HIGH_CONSEQUENCE_PATTERNS, [toolName, target])) return "elevated";
1784
1836
  return "standard";
1785
1837
  };
1786
1838
  var POLICY_CAPABILITIES = ["read", "edit", "shell", "network", "destructive"];
@@ -1,10 +1,10 @@
1
1
  import {
2
2
  pusharyHookExecutable
3
- } from "./chunk-NAJ3UV4E.js";
3
+ } from "./chunk-5K43TBK4.js";
4
4
  import {
5
5
  isProtectedByScope,
6
6
  registerHookEntry
7
- } from "./chunk-R76C43H7.js";
7
+ } from "./chunk-ZMKEKWNR.js";
8
8
 
9
9
  // src/skills-cli.ts
10
10
  import { execSync } from "child_process";
@@ -13,7 +13,45 @@ import {
13
13
  isReleaseVersion,
14
14
  ownPackageName,
15
15
  withHookHoldBudget
16
- } from "./chunk-4PCF34AB.js";
16
+ } from "./chunk-XEIV5QOT.js";
17
+
18
+ // src/setup/paths.ts
19
+ import { homedir as homedir2 } from "os";
20
+ import { join as join3 } from "path";
21
+
22
+ // src/codex-config.ts
23
+ import { createHash } from "crypto";
24
+ import { homedir } from "os";
25
+ import { join as join2 } from "path";
26
+
27
+ // src/registration-holder.ts
28
+ var asRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value) ? value : null;
29
+ var registeredCommands = (document) => {
30
+ const hooks = asRecord(document?.hooks);
31
+ if (!hooks) return [];
32
+ const found = [];
33
+ for (const [event, value] of Object.entries(hooks)) {
34
+ if (!Array.isArray(value)) continue;
35
+ for (const item of value) {
36
+ const inner = asRecord(item)?.hooks;
37
+ if (!Array.isArray(inner)) continue;
38
+ for (const hook of inner) {
39
+ const command = asRecord(hook)?.command;
40
+ if (typeof command === "string") found.push({ event, command });
41
+ }
42
+ }
43
+ }
44
+ return found;
45
+ };
46
+ var wholeSegments = (command) => command.split(/[\s/\\"']+/).map((segment) => segment.replace(/\.(cmd|exe)$/i, ""));
47
+ var namesLocator = (command) => wholeSegments(command).includes(HOOK_LOCATOR_BINARY);
48
+ var namesCliBinary = (command, cliBinaries) => wholeSegments(command).some((segment) => cliBinaries.has(segment));
49
+ var namesOurBinary = (command, cliBinaries) => namesLocator(command) || namesCliBinary(command, cliBinaries);
50
+ var registrationHolderOf = (document, cliBinaries) => {
51
+ const commands = registeredCommands(document);
52
+ if (commands.some(({ command }) => namesLocator(command))) return "app";
53
+ return commands.some(({ command }) => namesCliBinary(command, cliBinaries)) ? "cli" : "none";
54
+ };
17
55
 
18
56
  // src/npm.ts
19
57
  import { promisify } from "util";
@@ -327,19 +365,32 @@ var installGlobally = (options) => {
327
365
  }
328
366
  const started = (async () => {
329
367
  if (!npmIsOnPath()) throw new NpmMissingError();
330
- const platform = process.platform;
331
- const { prefix, packageName } = planGlobalInstall(platform);
332
- const pinned = process.env.PUSHARY_PIN_GLOBAL_VERSION !== "0";
333
- if (pinned && prefix !== void 0 && !needsGlobalInstall(
334
- options.version,
335
- installedVersionOf(prefix, packageName, platform),
336
- globalPackageBinsPresent(packageName, prefix, platform)
337
- )) {
338
- return "skipped";
368
+ const { withUpgradeLock } = await import("./global-upgrade-ML2RHV4W.js");
369
+ const { installWithUpgradeLock, ownsUpgradeLock } = await import("./upgrade-lock-2A2YUUEU.js");
370
+ const { autoUpdateLock: autoUpdateLock2 } = await import("./paths-LG3IEDDM.js");
371
+ let result = "skipped";
372
+ const install = async () => {
373
+ const platform = process.platform;
374
+ const { prefix, packageName } = planGlobalInstall(platform);
375
+ const pinned = process.env.PUSHARY_PIN_GLOBAL_VERSION !== "0";
376
+ if (pinned && prefix !== void 0 && !needsGlobalInstall(
377
+ options.version,
378
+ installedVersionOf(prefix, packageName, platform),
379
+ globalPackageBinsPresent(packageName, prefix, platform)
380
+ )) {
381
+ return;
382
+ }
383
+ const version = pinned && options.version && options.version !== "0.0.0" ? options.version : LATEST_TAG;
384
+ installWithUpgradeLock({ packageName, version, timeoutMs: options.timeoutMs ?? 12e4 }, options.lockPath);
385
+ result = "installed";
386
+ };
387
+ if (ownsUpgradeLock(options.lockPath ?? autoUpdateLock2())) {
388
+ await install();
389
+ } else {
390
+ const lock = await withUpgradeLock(install, options);
391
+ if (lock.kind === "refused") throw new Error(lock.message);
339
392
  }
340
- const version = pinned && options.version && options.version !== "0.0.0" ? options.version : LATEST_TAG;
341
- installPackageGlobally({ packageName, version, timeoutMs: options.timeoutMs ?? 12e4 });
342
- return "installed";
393
+ return result;
343
394
  })();
344
395
  installState = started;
345
396
  started.catch(() => {
@@ -397,40 +448,6 @@ var guardedArgv = (target, args = [], platform = process.platform) => {
397
448
  return [shell, ...shellArgs, HOOK_GUARD_SCRIPTS[guardKindOf(target)], path, ...args];
398
449
  };
399
450
 
400
- // src/codex-config.ts
401
- import { createHash } from "crypto";
402
- import { homedir } from "os";
403
- import { join as join2 } from "path";
404
-
405
- // src/registration-holder.ts
406
- var asRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value) ? value : null;
407
- var registeredCommands = (document) => {
408
- const hooks = asRecord(document?.hooks);
409
- if (!hooks) return [];
410
- const found = [];
411
- for (const [event, value] of Object.entries(hooks)) {
412
- if (!Array.isArray(value)) continue;
413
- for (const item of value) {
414
- const inner = asRecord(item)?.hooks;
415
- if (!Array.isArray(inner)) continue;
416
- for (const hook of inner) {
417
- const command = asRecord(hook)?.command;
418
- if (typeof command === "string") found.push({ event, command });
419
- }
420
- }
421
- }
422
- return found;
423
- };
424
- var wholeSegments = (command) => command.split(/[\s/\\"']+/).map((segment) => segment.replace(/\.(cmd|exe)$/i, ""));
425
- var namesLocator = (command) => wholeSegments(command).includes(HOOK_LOCATOR_BINARY);
426
- var namesCliBinary = (command, cliBinaries) => wholeSegments(command).some((segment) => cliBinaries.has(segment));
427
- var namesOurBinary = (command, cliBinaries) => namesLocator(command) || namesCliBinary(command, cliBinaries);
428
- var registrationHolderOf = (document, cliBinaries) => {
429
- const commands = registeredCommands(document);
430
- if (commands.some(({ command }) => namesLocator(command))) return "app";
431
- return commands.some(({ command }) => namesCliBinary(command, cliBinaries)) ? "cli" : "none";
432
- };
433
-
434
451
  // src/hook-entries.ts
435
452
  var registerHookEntry = (existing, isOurs, entry) => {
436
453
  const rewritten = [];
@@ -759,13 +776,14 @@ var staleTrustKeys = (state, hooksJsonPath, event, currentKey, ourHash) => {
759
776
  };
760
777
 
761
778
  // src/setup/paths.ts
762
- import { homedir as homedir2 } from "os";
763
- import { join as join3 } from "path";
764
779
  var claudeSettings = () => join3(homedir2(), ".claude", "settings.json");
765
780
  var claudeJson = () => join3(homedir2(), ".claude.json");
766
781
  var claudeSkillDir = () => join3(homedir2(), ".claude", "skills", "pushary");
767
782
  var cursorPluginDir = () => join3(homedir2(), ".cursor", "plugins", "local", "pushary");
768
783
  var cursorUserHooks = () => join3(homedir2(), ".cursor", "hooks.json");
784
+ var cursorPluginMcp = () => join3(cursorPluginDir(), "mcp.json");
785
+ var cursorPluginManifest = () => join3(cursorPluginDir(), ".cursor-plugin", "plugin.json");
786
+ var cursorPluginRule = () => join3(cursorPluginDir(), "rules", "pushary.mdc");
769
787
  var cursorUserMcp = () => join3(homedir2(), ".cursor", "mcp.json");
770
788
  var vscodePluginDir = () => join3(homedir2(), ".pushary", "plugins", "vscode");
771
789
  var vscodePluginMcp = () => join3(vscodePluginDir(), ".mcp.json");
@@ -859,6 +877,9 @@ export {
859
877
  claudeSkillDir,
860
878
  cursorPluginDir,
861
879
  cursorUserHooks,
880
+ cursorPluginMcp,
881
+ cursorPluginManifest,
882
+ cursorPluginRule,
862
883
  cursorUserMcp,
863
884
  vscodePluginDir,
864
885
  vscodePluginMcp,
@@ -0,0 +1,24 @@
1
+ import {
2
+ finishGlobalUpgrade,
3
+ finishUpgradeWithLock,
4
+ globalUpgradeSubject,
5
+ readGlobalUpgradeSubject,
6
+ upgradeInstalledPackage,
7
+ withUpgradeLock
8
+ } from "./chunk-QQJCDRD3.js";
9
+ import "./chunk-QXL27RY6.js";
10
+ import "./chunk-CE4UH4AP.js";
11
+ import "./chunk-POFBE6ZY.js";
12
+ import "./chunk-KZERVKTD.js";
13
+ import "./chunk-ZMKEKWNR.js";
14
+ import "./chunk-T7E75EKA.js";
15
+ import "./chunk-FVOCQSBG.js";
16
+ import "./chunk-XEIV5QOT.js";
17
+ export {
18
+ finishGlobalUpgrade,
19
+ finishUpgradeWithLock,
20
+ globalUpgradeSubject,
21
+ readGlobalUpgradeSubject,
22
+ upgradeInstalledPackage,
23
+ withUpgradeLock
24
+ };
@@ -0,0 +1,71 @@
1
+ import {
2
+ autoUpdateLock,
3
+ autoUpdateLog,
4
+ autoUpdateState,
5
+ bridgeAgentKey,
6
+ claudeJson,
7
+ claudeMcpReceipt,
8
+ claudeRegistrationReceipt,
9
+ claudeSettings,
10
+ claudeSettingsLocal,
11
+ claudeSkillDir,
12
+ clientReportClaims,
13
+ codexAgentsMd2 as codexAgentsMd,
14
+ codexSkillDir2 as codexSkillDir,
15
+ cursorPluginDir,
16
+ cursorPluginManifest,
17
+ cursorPluginMcp,
18
+ cursorPluginRule,
19
+ cursorUserHooks,
20
+ cursorUserMcp,
21
+ fxAgentsMd,
22
+ fxConfigDir,
23
+ fxMcpProfile,
24
+ fxQuestionRuleReceipt,
25
+ fxSettings,
26
+ geminiMd,
27
+ geminiSettings,
28
+ hermesConfig,
29
+ hermesConfigReceipt,
30
+ hookTakeoverReceipt,
31
+ pusharyConfigFile,
32
+ pusharyDir,
33
+ vscodePluginDir,
34
+ vscodePluginMcp
35
+ } from "./chunk-ZMKEKWNR.js";
36
+ import "./chunk-XEIV5QOT.js";
37
+ export {
38
+ autoUpdateLock,
39
+ autoUpdateLog,
40
+ autoUpdateState,
41
+ bridgeAgentKey,
42
+ claudeJson,
43
+ claudeMcpReceipt,
44
+ claudeRegistrationReceipt,
45
+ claudeSettings,
46
+ claudeSettingsLocal,
47
+ claudeSkillDir,
48
+ clientReportClaims,
49
+ codexAgentsMd,
50
+ codexSkillDir,
51
+ cursorPluginDir,
52
+ cursorPluginManifest,
53
+ cursorPluginMcp,
54
+ cursorPluginRule,
55
+ cursorUserHooks,
56
+ cursorUserMcp,
57
+ fxAgentsMd,
58
+ fxConfigDir,
59
+ fxMcpProfile,
60
+ fxQuestionRuleReceipt,
61
+ fxSettings,
62
+ geminiMd,
63
+ geminiSettings,
64
+ hermesConfig,
65
+ hermesConfigReceipt,
66
+ hookTakeoverReceipt,
67
+ pusharyConfigFile,
68
+ pusharyDir,
69
+ vscodePluginDir,
70
+ vscodePluginMcp
71
+ };
@@ -9,18 +9,18 @@ import {
9
9
  reapplyGeminiSettings,
10
10
  reapplyVsCodePlugin,
11
11
  repairCodexHolds
12
- } from "./chunk-XXVMUMKT.js";
13
- import "./chunk-JW7DKTT6.js";
14
- import "./chunk-MQJWO3AA.js";
12
+ } from "./chunk-SWGY5WNX.js";
13
+ import "./chunk-KR5JASA4.js";
14
+ import "./chunk-6Q4NM2LW.js";
15
15
  import "./chunk-RIVNNBEK.js";
16
- import "./chunk-NAJ3UV4E.js";
17
- import "./chunk-YFS4HYCI.js";
16
+ import "./chunk-5K43TBK4.js";
17
+ import "./chunk-D3RS57MN.js";
18
18
  import "./chunk-XHKBHWLX.js";
19
19
  import "./chunk-6ICPEJY5.js";
20
- import "./chunk-VYNTRHB6.js";
21
- import "./chunk-R76C43H7.js";
20
+ import "./chunk-RNDFGHSQ.js";
21
+ import "./chunk-ZMKEKWNR.js";
22
22
  import "./chunk-T7E75EKA.js";
23
- import "./chunk-4PCF34AB.js";
23
+ import "./chunk-XEIV5QOT.js";
24
24
  export {
25
25
  ensureCodexTrustAfterReapply,
26
26
  inspectConfiguredManagedProviders,
package/dist/src/index.js CHANGED
@@ -1,15 +1,15 @@
1
1
  import {
2
2
  handlePreToolUse
3
- } from "../chunk-HNMMKFYN.js";
4
- import "../chunk-CKPDSFY3.js";
5
- import "../chunk-MQJWO3AA.js";
6
- import "../chunk-YJZDIFON.js";
7
- import "../chunk-IJJ3HHFT.js";
3
+ } from "../chunk-IJXJW2VH.js";
4
+ import "../chunk-NVLXK2I6.js";
5
+ import "../chunk-6Q4NM2LW.js";
6
+ import "../chunk-GHKNUQYU.js";
7
+ import "../chunk-P7YDVWLL.js";
8
8
  import "../chunk-5OP5MQI7.js";
9
- import "../chunk-YFS4HYCI.js";
9
+ import "../chunk-D3RS57MN.js";
10
10
  import {
11
11
  fetchAccountPublicKey
12
- } from "../chunk-HSM5FIA3.js";
12
+ } from "../chunk-PMS3EBD2.js";
13
13
  import "../chunk-6ICPEJY5.js";
14
14
  import {
15
15
  fetchModeOverride,
@@ -19,33 +19,33 @@ import {
19
19
  handlePostToolUse,
20
20
  handleStop,
21
21
  reportEvent
22
- } from "../chunk-42E4DE6C.js";
22
+ } from "../chunk-JCER3Q6P.js";
23
23
  import "../chunk-N6IOSZOE.js";
24
- import "../chunk-VYNTRHB6.js";
24
+ import "../chunk-RNDFGHSQ.js";
25
25
  import {
26
26
  askUser,
27
27
  cancelQuestion,
28
28
  waitForAnswer
29
- } from "../chunk-ZMVLKPT7.js";
30
- import "../chunk-BG4QCOHQ.js";
29
+ } from "../chunk-JHZAZAI3.js";
30
+ import "../chunk-SPB3QRE7.js";
31
31
  import "../chunk-POFBE6ZY.js";
32
- import "../chunk-CPBRXBLG.js";
33
- import "../chunk-75CEJ4WP.js";
34
- import "../chunk-P6VDRQF3.js";
35
- import "../chunk-VV4SBPCQ.js";
32
+ import "../chunk-VH6763OR.js";
33
+ import "../chunk-DMA3QUOB.js";
34
+ import "../chunk-6JTTJIKJ.js";
35
+ import "../chunk-J7JXA2LX.js";
36
36
  import "../chunk-7QLSKOSU.js";
37
37
  import "../chunk-KZERVKTD.js";
38
- import "../chunk-US3RDXK7.js";
39
- import "../chunk-R76C43H7.js";
38
+ import "../chunk-6QSDNXGM.js";
39
+ import "../chunk-ZMKEKWNR.js";
40
40
  import "../chunk-T7E75EKA.js";
41
41
  import {
42
42
  getApiKey,
43
43
  getBaseUrl
44
- } from "../chunk-EG46RJRF.js";
45
- import "../chunk-SDSKTRIV.js";
44
+ } from "../chunk-4SB46XLF.js";
45
+ import "../chunk-FVOCQSBG.js";
46
46
  import {
47
47
  resolvePolicy
48
- } from "../chunk-4PCF34AB.js";
48
+ } from "../chunk-XEIV5QOT.js";
49
49
  export {
50
50
  askUser,
51
51
  cancelQuestion,
@@ -0,0 +1,17 @@
1
+ import {
2
+ claimUpgradeLock,
3
+ finishWithUpgradeLock,
4
+ installWithUpgradeLock,
5
+ ownsUpgradeLock,
6
+ releaseAutoUpdateLock
7
+ } from "./chunk-QXL27RY6.js";
8
+ import "./chunk-ZMKEKWNR.js";
9
+ import "./chunk-T7E75EKA.js";
10
+ import "./chunk-XEIV5QOT.js";
11
+ export {
12
+ claimUpgradeLock,
13
+ finishWithUpgradeLock,
14
+ installWithUpgradeLock,
15
+ ownsUpgradeLock,
16
+ releaseAutoUpdateLock
17
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pushary",
3
- "version": "1.9.0",
3
+ "version": "1.9.1",
4
4
  "description": "Permission hooks for AI coding agents: route tool approvals through Pushary push notifications",
5
5
  "keywords": [
6
6
  "pushary",