@event4u/agent-config 14.17.0 → 14.18.0

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 (74) hide show
  1. package/.augment-plugin/marketplace.json +3 -3
  2. package/.augment-plugin/plugin.json +1 -1
  3. package/.claude-plugin/marketplace.json +1 -1
  4. package/CHANGELOG.md +170 -79
  5. package/README.md +1 -1
  6. package/dist/agent-src/commands/pr/merge.md +35 -44
  7. package/dist/agent-src/skills/accessibility-auditor/SKILL.md +2 -0
  8. package/dist/agent-src/skills/ai-code-blindspots/SKILL.md +27 -1
  9. package/dist/agent-src/skills/code-intelligence/SKILL.md +60 -12
  10. package/dist/agent-src/skills/complexity-first-planning/SKILL.md +27 -0
  11. package/dist/agent-src/skills/design-review/SKILL.md +2 -0
  12. package/dist/agent-src/skills/feature-planning/SKILL.md +34 -0
  13. package/dist/agent-src/skills/git-workflow/SKILL.md +37 -12
  14. package/dist/agent-src/skills/git-workflow/references/push-closes-its-loop.md +176 -0
  15. package/dist/agent-src/skills/laravel-mail/SKILL.md +44 -0
  16. package/dist/agent-src/skills/testing-anti-patterns/SKILL.md +40 -0
  17. package/dist/agent-src/skills/using-git-worktrees/SKILL.md +12 -0
  18. package/dist/agent-src/skills/verify-repair-loop/SKILL.md +53 -8
  19. package/dist/agent-src/skills/worktree-lifecycle/SKILL.md +3 -1
  20. package/dist/agent-src/templates/agents/agent-project-settings.example.yml +1 -1
  21. package/dist/cli-delegate/cmd_conformance.js +335 -659
  22. package/dist/discovery/deprecation-report.md +1 -1
  23. package/dist/discovery/discovery-manifest.json +15 -15
  24. package/dist/discovery/discovery-manifest.json.sha256 +1 -1
  25. package/dist/discovery/discovery-manifest.summary.md +1 -1
  26. package/dist/discovery/dormancy-report.md +1 -1
  27. package/dist/discovery/orphan-report.md +1 -1
  28. package/dist/discovery/packs.json +2 -2
  29. package/dist/discovery/trust-report.md +1 -1
  30. package/dist/discovery/workspaces.json +2 -2
  31. package/dist/hooks/dispatch.js +959 -1304
  32. package/dist/mcp/registry-manifest.json +2 -2
  33. package/dist/mcp/server.json +2 -2
  34. package/dist/mcp/server.mjs +671 -1002
  35. package/dist/shared/settingsConsent.js +1 -1
  36. package/package.json +1 -1
  37. package/src/config/conformance-claim-baseline.json +9 -0
  38. package/src/config/gate-violation-baselines.json +3 -3
  39. package/src/config/release-gate-locality.yml +129 -0
  40. package/src/scripts/_lib/release_highlights.ts +172 -1
  41. package/src/scripts/_lib/release_material.ts +66 -0
  42. package/src/scripts/_lib/repeated_run.ts +77 -0
  43. package/src/scripts/_lib/tamper_vocabulary.ts +242 -0
  44. package/src/scripts/_lib/unified_diff.ts +121 -0
  45. package/src/scripts/check_finding_dispositions.ts +179 -3
  46. package/src/scripts/check_installed_hooks_fresh.ts +381 -0
  47. package/src/scripts/check_release_highlights.ts +25 -13
  48. package/src/scripts/check_suppression_hygiene.ts +11 -0
  49. package/src/scripts/code_graph/build.ts +230 -33
  50. package/src/scripts/code_graph/extract.ts +168 -33
  51. package/src/scripts/code_graph/types.ts +37 -2
  52. package/src/scripts/code_graph/validate.ts +12 -1
  53. package/src/scripts/conformance_scan.ts +2 -2
  54. package/src/scripts/detect_silent_catch.ts +403 -0
  55. package/src/scripts/detect_verification_tampering.ts +538 -0
  56. package/src/scripts/git_authorization_hook.ts +153 -17
  57. package/src/scripts/hook_manifest.json +1 -1
  58. package/src/scripts/hook_manifest.yaml +33 -19
  59. package/src/scripts/hooks/block_no_verify.ts +3 -3
  60. package/src/scripts/hooks/concern_registry.ts +2 -2
  61. package/src/scripts/hooks/evidence_independence.ts +21 -2
  62. package/src/scripts/hooks/{block_unauthorized_git.ts → git_command_classifier.ts} +25 -369
  63. package/src/scripts/hooks/push_settle_hook.ts +250 -0
  64. package/src/scripts/hooks/ship_diff_volume_hook.ts +1 -1
  65. package/src/scripts/install-hooks.sh +134 -1
  66. package/src/scripts/language_mirror_hook.ts +27 -5
  67. package/src/scripts/release.ts +31 -143
  68. package/src/scripts/release_drill.ts +71 -1
  69. package/src/scripts/release_publication.ts +243 -3
  70. package/src/scripts/release_verify.ts +220 -0
  71. package/src/scripts/schemas/review-findings.schema.json +1 -1
  72. package/src/scripts/schemas/skill.schema.json +11 -1
  73. package/src/scripts/self_review_gate.ts +10 -1
  74. package/src/shared/settingsConsent.ts +1 -1
@@ -22673,11 +22673,137 @@ if (_isCliEntry18()) {
22673
22673
  process.exit(main22());
22674
22674
  }
22675
22675
 
22676
- // src/scripts/session_canary_hook.ts
22676
+ // src/scripts/hooks/push_settle_hook.ts
22677
22677
  import fs40 from "node:fs";
22678
22678
  import path40 from "node:path";
22679
+ import { execFileSync as execFileSync3 } from "node:child_process";
22679
22680
  import { fileURLToPath as fileURLToPath27, pathToFileURL as pathToFileURL20 } from "node:url";
22680
22681
  var EXIT_ALLOW4 = 0;
22682
+ var EXIT_WARN3 = 2;
22683
+ var COMMAND_TOOLS4 = /* @__PURE__ */ new Set([
22684
+ "launch-process",
22685
+ "launch_process",
22686
+ "Bash",
22687
+ "BashTool",
22688
+ "run-process",
22689
+ "runProcess",
22690
+ "shell",
22691
+ "execute_shell",
22692
+ "RunShellCommand"
22693
+ ]);
22694
+ var DRY_RUN = /(?:^|\s)(?:--dry-run|-n)(?:\s|$)/;
22695
+ var REF_ADVANCED = /(?:\[new branch\]|\[new tag\]|[0-9a-f]{7,}\.\.[0-9a-f]{7,})\s+(\S+)\s+->\s+(\S+)/;
22696
+ var REJECTED = /^\s*!\s*\[(?:rejected|remote rejected)\]/m;
22697
+ function isObject2(v) {
22698
+ return typeof v === "object" && v !== null && !Array.isArray(v);
22699
+ }
22700
+ function unwrap2(envelope) {
22701
+ const inner = envelope["payload"];
22702
+ return isObject2(inner) ? inner : envelope;
22703
+ }
22704
+ function extractCommand(payload) {
22705
+ const toolRaw = payload["tool_name"] ?? payload["toolName"] ?? payload["tool"];
22706
+ const tool = typeof toolRaw === "string" ? toolRaw : null;
22707
+ if (tool === null || !COMMAND_TOOLS4.has(tool)) return null;
22708
+ const ti = payload["tool_input"];
22709
+ if (isObject2(ti)) {
22710
+ for (const key of ["command", "cmd", "shell_command"]) {
22711
+ const v = ti[key];
22712
+ if (typeof v === "string" && v) return v;
22713
+ }
22714
+ }
22715
+ for (const key of ["command", "cmd"]) {
22716
+ const v = payload[key];
22717
+ if (typeof v === "string" && v) return v;
22718
+ }
22719
+ return null;
22720
+ }
22721
+ function toolOutput(payload) {
22722
+ for (const key of ["tool_response", "tool_result", "toolResponse", "output", "result", "stdout"]) {
22723
+ const v = payload[key];
22724
+ if (typeof v === "string") return v;
22725
+ if (isObject2(v) || Array.isArray(v)) return JSON.stringify(v);
22726
+ }
22727
+ return JSON.stringify(payload);
22728
+ }
22729
+ function pushedBranch(output) {
22730
+ if (REJECTED.test(output)) return null;
22731
+ const m = REF_ADVANCED.exec(output);
22732
+ if (m === null) return null;
22733
+ const remote = m[2];
22734
+ if (remote === void 0) return null;
22735
+ return remote.replace(/^refs\/heads\//, "") || null;
22736
+ }
22737
+ function resolvePr(branch, run12 = (cmd, args) => execFileSync3(cmd, args, { encoding: "utf8", stdio: ["ignore", "pipe", "ignore"], timeout: 15e3 })) {
22738
+ try {
22739
+ const out = run12("gh", ["pr", "view", branch, "--json", "number", "-q", ".number"]).trim();
22740
+ const n = Number.parseInt(out, 10);
22741
+ return Number.isInteger(n) && n > 0 ? n : null;
22742
+ } catch {
22743
+ return null;
22744
+ }
22745
+ }
22746
+ function buildReminder(branch, pr) {
22747
+ const settle = pr === null ? `gh pr view ${branch} --json number -q .number # then:
22748
+ ./scripts-run src/scripts/ci_settle <that number>` : `./scripts-run src/scripts/ci_settle ${pr}`;
22749
+ const subject = pr === null ? `branch ${branch}` : `PR #${pr} (${branch})`;
22750
+ const reason = `Pushed ${subject} \u2014 the turn is not finished until its CI has settled green (verify-before-complete). Run ci_settle before you report this as done.`;
22751
+ const additional_context = `You just advanced a remote ref: ${subject}.
22752
+
22753
+ A push is not a delivery. Per verify-before-complete, a completion claim needs fresh evidence, and the evidence for a push is the CI verdict \u2014 not the push's own exit code.
22754
+
22755
+ Before this turn ends:
22756
+ 1. Settle it:
22757
+ ${settle}
22758
+ Exit 0 = settled green \xB7 1 = settled, something failed \xB7 2 = NOT a verdict (timed out or unreadable \u2014 never report 2 as green).
22759
+ 2. Red? Read only the failing part:
22760
+ gh run view --job <id> --log-failed | grep -E '\xD7|FAIL|Error'
22761
+ then fix it and push again (fix-what-you-see: the author is irrelevant).
22762
+ 3. Still red after 3 attempts on the same target, or blocked on something only the user can decide \u2014 stop and say so, with the three attempts named (autonomous-execution N=3).
22763
+
22764
+ Handing the user a red PR with its cause named and unfixed is not a delivery either. If you are deliberately leaving this WIP, say that in the reply \u2014 silence is what this hook exists to stop.`;
22765
+ return { reason, additional_context };
22766
+ }
22767
+ function main23() {
22768
+ let envelope;
22769
+ try {
22770
+ const raw = readHookStdin();
22771
+ envelope = raw.trim() ? JSON.parse(raw) : {};
22772
+ } catch {
22773
+ return EXIT_ALLOW4;
22774
+ }
22775
+ if (!isObject2(envelope)) return EXIT_ALLOW4;
22776
+ const inner = unwrap2(envelope);
22777
+ const command = extractCommand(inner);
22778
+ if (command === null) return EXIT_ALLOW4;
22779
+ if (DRY_RUN.test(command)) return EXIT_ALLOW4;
22780
+ const branch = pushedBranch(toolOutput(inner));
22781
+ if (branch === null) return EXIT_ALLOW4;
22782
+ const { reason, additional_context } = buildReminder(branch, resolvePr(branch));
22783
+ process.stdout.write(`${JSON.stringify({ decision: "warn", reason, additional_context })}
22784
+ `);
22785
+ return EXIT_WARN3;
22786
+ }
22787
+ function isCliEntry9() {
22788
+ if (true) return false;
22789
+ if (process.argv[1] === void 0) return false;
22790
+ const argvUrl = pathToFileURL20(path40.resolve(process.argv[1])).href;
22791
+ if (import.meta.url === argvUrl) return true;
22792
+ try {
22793
+ return fs40.realpathSync(fileURLToPath27(import.meta.url)) === fs40.realpathSync(path40.resolve(process.argv[1]));
22794
+ } catch {
22795
+ return false;
22796
+ }
22797
+ }
22798
+ if (isCliEntry9()) {
22799
+ process.exit(main23());
22800
+ }
22801
+
22802
+ // src/scripts/session_canary_hook.ts
22803
+ import fs41 from "node:fs";
22804
+ import path41 from "node:path";
22805
+ import { fileURLToPath as fileURLToPath28, pathToFileURL as pathToFileURL21 } from "node:url";
22806
+ var EXIT_ALLOW5 = 0;
22681
22807
  var SETTINGS_FILE5 = ".agent-settings.yml";
22682
22808
  function _isObject6(v) {
22683
22809
  return typeof v === "object" && v !== null && !Array.isArray(v);
@@ -22685,10 +22811,10 @@ function _isObject6(v) {
22685
22811
  function read_canary_name(settings_path) {
22686
22812
  let text;
22687
22813
  try {
22688
- if (!fs40.statSync(settings_path).isFile()) {
22814
+ if (!fs41.statSync(settings_path).isFile()) {
22689
22815
  return null;
22690
22816
  }
22691
- text = fs40.readFileSync(settings_path, "utf-8");
22817
+ text = fs41.readFileSync(settings_path, "utf-8");
22692
22818
  } catch {
22693
22819
  return null;
22694
22820
  }
@@ -22713,10 +22839,10 @@ function read_canary_name(settings_path) {
22713
22839
  function read_identity_name(user_yml_path) {
22714
22840
  let text;
22715
22841
  try {
22716
- if (!fs40.statSync(user_yml_path).isFile()) {
22842
+ if (!fs41.statSync(user_yml_path).isFile()) {
22717
22843
  return null;
22718
22844
  }
22719
- text = fs40.readFileSync(user_yml_path, "utf-8");
22845
+ text = fs41.readFileSync(user_yml_path, "utf-8");
22720
22846
  } catch {
22721
22847
  return null;
22722
22848
  }
@@ -22740,13 +22866,13 @@ function read_identity_name(user_yml_path) {
22740
22866
  }
22741
22867
  function resolve_canary_name(workspace_root) {
22742
22868
  const project = sanitize_name(
22743
- read_canary_name(path40.join(workspace_root, SETTINGS_FILE5))
22869
+ read_canary_name(path41.join(workspace_root, SETTINGS_FILE5))
22744
22870
  );
22745
22871
  if (project) {
22746
22872
  return { name: project, layer: "project override" };
22747
22873
  }
22748
22874
  const global_settings = resolve_with_fallback(
22749
- path40.join("settings", ".agent-settings.yml")
22875
+ path41.join("settings", ".agent-settings.yml")
22750
22876
  );
22751
22877
  if (global_settings) {
22752
22878
  const name = sanitize_name(read_canary_name(global_settings));
@@ -22754,7 +22880,7 @@ function resolve_canary_name(workspace_root) {
22754
22880
  return { name, layer: "user-global settings" };
22755
22881
  }
22756
22882
  }
22757
- const global_user = resolve_with_fallback(path40.join("settings", ".agent-user.yml"));
22883
+ const global_user = resolve_with_fallback(path41.join("settings", ".agent-user.yml"));
22758
22884
  if (global_user) {
22759
22885
  const name = sanitize_name(read_identity_name(global_user));
22760
22886
  if (name) {
@@ -22794,7 +22920,7 @@ function _workspaceRoot2(envelope) {
22794
22920
  }
22795
22921
  return process.cwd();
22796
22922
  }
22797
- function main23() {
22923
+ function main24() {
22798
22924
  let envelope = {};
22799
22925
  try {
22800
22926
  const raw = _readStdin10();
@@ -22805,12 +22931,12 @@ function main23() {
22805
22931
  const event = env["event"];
22806
22932
  const slot = typeof event === "string" && event !== "" ? event : "session_start";
22807
22933
  if (slot !== "session_start" && slot !== "user_prompt_submit") {
22808
- return EXIT_ALLOW4;
22934
+ return EXIT_ALLOW5;
22809
22935
  }
22810
22936
  const root = _workspaceRoot2(env);
22811
22937
  const { name, layer } = resolve_canary_name(root);
22812
22938
  if (!name) {
22813
- return EXIT_ALLOW4;
22939
+ return EXIT_ALLOW5;
22814
22940
  }
22815
22941
  process.stdout.write(
22816
22942
  `${JSON.stringify({
@@ -22820,7 +22946,7 @@ function main23() {
22820
22946
  })}
22821
22947
  `
22822
22948
  );
22823
- return EXIT_ALLOW4;
22949
+ return EXIT_ALLOW5;
22824
22950
  }
22825
22951
  function _readStdin10() {
22826
22952
  return readHookStdin();
@@ -22832,27 +22958,27 @@ function _isCliEntry19() {
22832
22958
  if (process.argv[1] === void 0) {
22833
22959
  return false;
22834
22960
  }
22835
- const argvUrl = pathToFileURL20(path40.resolve(process.argv[1])).href;
22961
+ const argvUrl = pathToFileURL21(path41.resolve(process.argv[1])).href;
22836
22962
  if (import.meta.url === argvUrl) {
22837
22963
  return true;
22838
22964
  }
22839
22965
  try {
22840
- const here = fs40.realpathSync(fileURLToPath27(import.meta.url));
22841
- const argv = fs40.realpathSync(path40.resolve(process.argv[1]));
22966
+ const here = fs41.realpathSync(fileURLToPath28(import.meta.url));
22967
+ const argv = fs41.realpathSync(path41.resolve(process.argv[1]));
22842
22968
  return here === argv;
22843
22969
  } catch {
22844
22970
  return false;
22845
22971
  }
22846
22972
  }
22847
22973
  if (_isCliEntry19()) {
22848
- process.exit(main23());
22974
+ process.exit(main24());
22849
22975
  }
22850
22976
 
22851
22977
  // src/scripts/council_availability_hook.ts
22852
- import * as fs41 from "node:fs";
22853
- import * as path41 from "node:path";
22854
- import { fileURLToPath as fileURLToPath28, pathToFileURL as pathToFileURL21 } from "node:url";
22855
- var EXIT_ALLOW5 = 0;
22978
+ import * as fs42 from "node:fs";
22979
+ import * as path42 from "node:path";
22980
+ import { fileURLToPath as fileURLToPath29, pathToFileURL as pathToFileURL22 } from "node:url";
22981
+ var EXIT_ALLOW6 = 0;
22856
22982
  function resolveAvailability(cwd, env) {
22857
22983
  let p;
22858
22984
  try {
@@ -22860,7 +22986,7 @@ function resolveAvailability(cwd, env) {
22860
22986
  } catch {
22861
22987
  return null;
22862
22988
  }
22863
- const exists = fs41.existsSync(p);
22989
+ const exists = fs42.existsSync(p);
22864
22990
  const provenance2 = env[COUNCIL_CONFIG_ENV] ? "env-override" : "user-global";
22865
22991
  if (!exists) {
22866
22992
  return { configured: false, path: p, exists: false, provenance: provenance2, membersEnabled: 0, memberNames: [] };
@@ -22913,17 +23039,17 @@ function run7(stdin, options = {}) {
22913
23039
  envelope = parsed;
22914
23040
  }
22915
23041
  } catch {
22916
- return EXIT_ALLOW5;
23042
+ return EXIT_ALLOW6;
22917
23043
  }
22918
23044
  }
22919
23045
  const event = envelope["event"];
22920
23046
  const slot = typeof event === "string" && event !== "" ? event : "session_start";
22921
23047
  if (slot !== "session_start") {
22922
- return EXIT_ALLOW5;
23048
+ return EXIT_ALLOW6;
22923
23049
  }
22924
23050
  const a = resolveAvailability(_workspaceRoot3(envelope), options.env ?? process.env);
22925
23051
  if (a === null) {
22926
- return EXIT_ALLOW5;
23052
+ return EXIT_ALLOW6;
22927
23053
  }
22928
23054
  process.stdout.write(
22929
23055
  `${JSON.stringify({
@@ -22933,9 +23059,9 @@ function run7(stdin, options = {}) {
22933
23059
  })}
22934
23060
  `
22935
23061
  );
22936
- return EXIT_ALLOW5;
23062
+ return EXIT_ALLOW6;
22937
23063
  }
22938
- function main24(argv) {
23064
+ function main25(argv) {
22939
23065
  const args = argv ?? process.argv.slice(2);
22940
23066
  let env = process.env;
22941
23067
  void args;
@@ -22948,26 +23074,26 @@ function _isCliEntry20() {
22948
23074
  if (process.argv[1] === void 0) {
22949
23075
  return false;
22950
23076
  }
22951
- return import.meta.url === pathToFileURL21(path41.resolve(process.argv[1])).href;
23077
+ return import.meta.url === pathToFileURL22(path42.resolve(process.argv[1])).href;
22952
23078
  }
22953
23079
  if (_isCliEntry20()) {
22954
- process.exit(main24());
23080
+ process.exit(main25());
22955
23081
  }
22956
23082
 
22957
23083
  // src/scripts/telemetry_disclosure_hook.ts
22958
- import * as fs46 from "node:fs";
22959
- import * as path45 from "node:path";
22960
- import { pathToFileURL as pathToFileURL23 } from "node:url";
23084
+ import * as fs47 from "node:fs";
23085
+ import * as path46 from "node:path";
23086
+ import { pathToFileURL as pathToFileURL24 } from "node:url";
22961
23087
 
22962
23088
  // src/scripts/hooks/telemetry_usage_hook.ts
22963
23089
  import * as os7 from "node:os";
22964
- import * as path44 from "node:path";
22965
- import { fileURLToPath as fileURLToPath29, pathToFileURL as pathToFileURL22 } from "node:url";
22966
- import * as fs45 from "node:fs";
23090
+ import * as path45 from "node:path";
23091
+ import { fileURLToPath as fileURLToPath30, pathToFileURL as pathToFileURL23 } from "node:url";
23092
+ import * as fs46 from "node:fs";
22967
23093
 
22968
23094
  // src/agent-src/templates/scripts/telemetry/settings.ts
22969
23095
  import { createRequire as createRequire5 } from "node:module";
22970
- import * as fs42 from "node:fs";
23096
+ import * as fs43 from "node:fs";
22971
23097
  var YAML3 = createRequire5(import.meta.url)("yaml");
22972
23098
  function _isPlainObject7(v) {
22973
23099
  return typeof v === "object" && v !== null && !Array.isArray(v) && !(v instanceof Date);
@@ -23005,7 +23131,7 @@ function _coerce_path(value, def) {
23005
23131
  }
23006
23132
  function _isFile7(p) {
23007
23133
  try {
23008
- return fs42.statSync(p).isFile();
23134
+ return fs43.statSync(p).isFile();
23009
23135
  } catch {
23010
23136
  return false;
23011
23137
  }
@@ -23016,7 +23142,7 @@ function _read_telemetry_section(p, key) {
23016
23142
  }
23017
23143
  let raw = {};
23018
23144
  try {
23019
- raw = YAML3.parse(fs42.readFileSync(p, "utf-8"), { version: "1.1" });
23145
+ raw = YAML3.parse(fs43.readFileSync(p, "utf-8"), { version: "1.1" });
23020
23146
  if (raw === null || raw === void 0) {
23021
23147
  raw = {};
23022
23148
  }
@@ -23127,8 +23253,8 @@ function read_remote_settings(p) {
23127
23253
 
23128
23254
  // src/agent-src/templates/scripts/telemetry/remote.ts
23129
23255
  import * as crypto4 from "node:crypto";
23130
- import * as fs43 from "node:fs";
23131
- import * as path42 from "node:path";
23256
+ import * as fs44 from "node:fs";
23257
+ import * as path43 from "node:path";
23132
23258
 
23133
23259
  // src/agent-src/templates/scripts/telemetry/engagement.ts
23134
23260
  var MAX_ID_LEN = 200;
@@ -23426,13 +23552,13 @@ var RETENTION_HEAD_WINDOW_BYTES = 8192;
23426
23552
  function _oldest_datable_ms(log_path) {
23427
23553
  let fd;
23428
23554
  try {
23429
- fd = fs43.openSync(log_path, "r");
23555
+ fd = fs44.openSync(log_path, "r");
23430
23556
  } catch {
23431
23557
  return null;
23432
23558
  }
23433
23559
  try {
23434
23560
  const buf = Buffer.alloc(RETENTION_HEAD_WINDOW_BYTES);
23435
- const read = fs43.readSync(fd, buf, 0, buf.length, 0);
23561
+ const read = fs44.readSync(fd, buf, 0, buf.length, 0);
23436
23562
  if (read <= 0) {
23437
23563
  return null;
23438
23564
  }
@@ -23449,13 +23575,13 @@ function _oldest_datable_ms(log_path) {
23449
23575
  } catch {
23450
23576
  return null;
23451
23577
  } finally {
23452
- fs43.closeSync(fd);
23578
+ fs44.closeSync(fd);
23453
23579
  }
23454
23580
  }
23455
23581
  function retention_due(log_path, policy = DEFAULT_RETENTION_POLICY, now = /* @__PURE__ */ new Date()) {
23456
23582
  let size;
23457
23583
  try {
23458
- size = fs43.statSync(log_path).size;
23584
+ size = fs44.statSync(log_path).size;
23459
23585
  } catch {
23460
23586
  return false;
23461
23587
  }
@@ -23474,7 +23600,7 @@ function retention_due(log_path, policy = DEFAULT_RETENTION_POLICY, now = /* @__
23474
23600
  function enforce_retention(log_path, policy = DEFAULT_RETENTION_POLICY, now = /* @__PURE__ */ new Date()) {
23475
23601
  let raw;
23476
23602
  try {
23477
- raw = fs43.readFileSync(log_path, "utf-8");
23603
+ raw = fs44.readFileSync(log_path, "utf-8");
23478
23604
  } catch {
23479
23605
  return { kept: 0, dropped_by_age: 0, dropped_by_size: 0 };
23480
23606
  }
@@ -23506,13 +23632,13 @@ function enforce_retention(log_path, policy = DEFAULT_RETENTION_POLICY, now = /*
23506
23632
  const payload = kept_lines.length === 0 ? "" : `${kept_lines.join("\n")}
23507
23633
  `;
23508
23634
  const tmp = `${log_path}.retention.${process.pid}.tmp`;
23509
- fs43.writeFileSync(tmp, payload, { encoding: "utf-8" });
23510
- fs43.renameSync(tmp, log_path);
23635
+ fs44.writeFileSync(tmp, payload, { encoding: "utf-8" });
23636
+ fs44.renameSync(tmp, log_path);
23511
23637
  return { kept: kept_lines.length, dropped_by_age, dropped_by_size };
23512
23638
  }
23513
23639
  function _append_and_bound(target, payload, policy, now) {
23514
- fs43.mkdirSync(path42.dirname(target) || ".", { recursive: true });
23515
- fs43.appendFileSync(target, payload, { encoding: "utf-8" });
23640
+ fs44.mkdirSync(path43.dirname(target) || ".", { recursive: true });
23641
+ fs44.appendFileSync(target, payload, { encoding: "utf-8" });
23516
23642
  if (retention_due(target, policy, now)) {
23517
23643
  enforce_retention(target, policy, now);
23518
23644
  }
@@ -23528,14 +23654,14 @@ function append_class_a_record(log_path, record, policy = DEFAULT_RETENTION_POLI
23528
23654
 
23529
23655
  // src/agent-src/templates/scripts/telemetry/transport.ts
23530
23656
  import { spawn } from "node:child_process";
23531
- import * as fs44 from "node:fs";
23532
- import * as path43 from "node:path";
23657
+ import * as fs45 from "node:fs";
23658
+ import * as path44 from "node:path";
23533
23659
  var DEFAULT_FLUSH_TIMEOUT_MS = 1e3;
23534
23660
  var FLUSH_SESSION_END = "session-end";
23535
23661
  function spool_path_for(log_path) {
23536
- const dir = path43.dirname(log_path);
23537
- const base = path43.basename(log_path).replace(/\.jsonl$/u, "");
23538
- return path43.join(dir, `${base}.spool.jsonl`);
23662
+ const dir = path44.dirname(log_path);
23663
+ const base = path44.basename(log_path).replace(/\.jsonl$/u, "");
23664
+ return path44.join(dir, `${base}.spool.jsonl`);
23539
23665
  }
23540
23666
  function spawn_detached_sender(input) {
23541
23667
  try {
@@ -23560,22 +23686,22 @@ function spawn_detached_sender(input) {
23560
23686
  }
23561
23687
  function spool_has_work(spool_path) {
23562
23688
  try {
23563
- return fs44.statSync(spool_path).size > 0;
23689
+ return fs45.statSync(spool_path).size > 0;
23564
23690
  } catch {
23565
23691
  return false;
23566
23692
  }
23567
23693
  }
23568
23694
 
23569
23695
  // src/scripts/hooks/telemetry_usage_hook.ts
23570
- var EXIT_ALLOW6 = 0;
23696
+ var EXIT_ALLOW7 = 0;
23571
23697
  var SKILL_TOOL_NAME = "Skill";
23572
23698
  var SETTINGS_FILENAME = ".agent-settings.yml";
23573
- function isObject2(v) {
23699
+ function isObject3(v) {
23574
23700
  return typeof v === "object" && v !== null && !Array.isArray(v);
23575
23701
  }
23576
23702
  function unwrapPayload(envelope) {
23577
23703
  const inner = envelope["payload"];
23578
- return isObject2(inner) ? inner : envelope;
23704
+ return isObject3(inner) ? inner : envelope;
23579
23705
  }
23580
23706
  function extractToolName(payload) {
23581
23707
  const v = payload["tool_name"] ?? payload["toolName"] ?? payload["tool"];
@@ -23583,7 +23709,7 @@ function extractToolName(payload) {
23583
23709
  }
23584
23710
  function extractSkillName(payload) {
23585
23711
  const input = payload["tool_input"] ?? payload["toolInput"];
23586
- if (!isObject2(input)) return null;
23712
+ if (!isObject3(input)) return null;
23587
23713
  const v = input["skill"] ?? input["skill_name"] ?? input["name"];
23588
23714
  return typeof v === "string" && v ? v : null;
23589
23715
  }
@@ -23622,15 +23748,15 @@ function extractPackageVersion(env) {
23622
23748
  }
23623
23749
  var _settingsCache = /* @__PURE__ */ new Map();
23624
23750
  function resolveSettingsPath(start) {
23625
- let dir = path44.resolve(start);
23751
+ let dir = path45.resolve(start);
23626
23752
  for (; ; ) {
23627
- const candidate = path44.join(dir, SETTINGS_FILENAME);
23753
+ const candidate = path45.join(dir, SETTINGS_FILENAME);
23628
23754
  try {
23629
- if (fs45.statSync(candidate).isFile()) return candidate;
23755
+ if (fs46.statSync(candidate).isFile()) return candidate;
23630
23756
  } catch {
23631
23757
  }
23632
- const parent = path44.dirname(dir);
23633
- if (parent === dir) return path44.join(path44.resolve(start), SETTINGS_FILENAME);
23758
+ const parent = path45.dirname(dir);
23759
+ if (parent === dir) return path45.join(path45.resolve(start), SETTINGS_FILENAME);
23634
23760
  dir = parent;
23635
23761
  }
23636
23762
  }
@@ -23640,24 +23766,24 @@ function readSettingsFor(consumerRoot) {
23640
23766
  if (cached !== void 0) return cached;
23641
23767
  let text = "";
23642
23768
  try {
23643
- text = fs45.readFileSync(p, "utf-8");
23769
+ text = fs46.readFileSync(p, "utf-8");
23644
23770
  } catch {
23645
23771
  text = "";
23646
23772
  }
23647
- const read = { settings: read_remote_settings(p), text, root: path44.dirname(p) };
23773
+ const read = { settings: read_remote_settings(p), text, root: path45.dirname(p) };
23648
23774
  _settingsCache.set(p, read);
23649
23775
  return read;
23650
23776
  }
23651
23777
  function processEnvelope(envelope, consumer_root) {
23652
23778
  try {
23653
- if (!isObject2(envelope)) return EXIT_ALLOW6;
23779
+ if (!isObject3(envelope)) return EXIT_ALLOW7;
23654
23780
  const payload = unwrapPayload(envelope);
23655
- if (extractToolName(payload) !== SKILL_TOOL_NAME) return EXIT_ALLOW6;
23781
+ if (extractToolName(payload) !== SKILL_TOOL_NAME) return EXIT_ALLOW7;
23656
23782
  const { settings, text, root } = readSettingsFor(consumer_root);
23657
- if (!settings.active) return EXIT_ALLOW6;
23658
- if (is_replay_mode()) return EXIT_ALLOW6;
23783
+ if (!settings.active) return EXIT_ALLOW7;
23784
+ if (is_replay_mode()) return EXIT_ALLOW7;
23659
23785
  const skill = extractSkillName(payload);
23660
- if (skill === null) return EXIT_ALLOW6;
23786
+ if (skill === null) return EXIT_ALLOW7;
23661
23787
  const record = build_class_a_record({
23662
23788
  skill,
23663
23789
  host: extractHost(envelope),
@@ -23669,7 +23795,7 @@ function processEnvelope(envelope, consumer_root) {
23669
23795
  package_version: extractPackageVersion(process.env),
23670
23796
  discipline_profile: extractDisciplineProfile(text)
23671
23797
  });
23672
- const logPath = path44.isAbsolute(settings.log_path) ? settings.log_path : path44.join(root, settings.log_path);
23798
+ const logPath = path45.isAbsolute(settings.log_path) ? settings.log_path : path45.join(root, settings.log_path);
23673
23799
  const spool = settings.flush === FLUSH_SESSION_END ? spool_path_for(logPath) : null;
23674
23800
  append_class_a_record(
23675
23801
  logPath,
@@ -23682,12 +23808,12 @@ function processEnvelope(envelope, consumer_root) {
23682
23808
  spool
23683
23809
  );
23684
23810
  } catch {
23685
- return EXIT_ALLOW6;
23811
+ return EXIT_ALLOW7;
23686
23812
  }
23687
- return EXIT_ALLOW6;
23813
+ return EXIT_ALLOW7;
23688
23814
  }
23689
23815
  function _resolveRoot(envelope) {
23690
- if (isObject2(envelope)) {
23816
+ if (isObject3(envelope)) {
23691
23817
  const cwd = envelope["cwd"];
23692
23818
  if (typeof cwd === "string" && cwd) return cwd;
23693
23819
  const pr = envelope["workspace_root"] ?? envelope["project_root"];
@@ -23695,13 +23821,13 @@ function _resolveRoot(envelope) {
23695
23821
  }
23696
23822
  return process.cwd();
23697
23823
  }
23698
- function main25() {
23824
+ function main26() {
23699
23825
  const raw = readHookStdin();
23700
23826
  let envelope = {};
23701
23827
  try {
23702
23828
  envelope = raw.trim() ? JSON.parse(raw) : {};
23703
23829
  } catch {
23704
- return EXIT_ALLOW6;
23830
+ return EXIT_ALLOW7;
23705
23831
  }
23706
23832
  return processEnvelope(envelope, _resolveRoot(envelope));
23707
23833
  }
@@ -23710,18 +23836,18 @@ function _isCliEntry21() {
23710
23836
  return false;
23711
23837
  }
23712
23838
  if (process.argv[1] === void 0) return false;
23713
- const argvUrl = pathToFileURL22(path44.resolve(process.argv[1])).href;
23839
+ const argvUrl = pathToFileURL23(path45.resolve(process.argv[1])).href;
23714
23840
  if (import.meta.url === argvUrl) return true;
23715
23841
  try {
23716
- return fs45.realpathSync(fileURLToPath29(import.meta.url)) === fs45.realpathSync(path44.resolve(process.argv[1]));
23842
+ return fs46.realpathSync(fileURLToPath30(import.meta.url)) === fs46.realpathSync(path45.resolve(process.argv[1]));
23717
23843
  } catch {
23718
23844
  return false;
23719
23845
  }
23720
23846
  }
23721
- if (_isCliEntry21()) process.exit(main25());
23847
+ if (_isCliEntry21()) process.exit(main26());
23722
23848
 
23723
23849
  // src/scripts/telemetry_disclosure_hook.ts
23724
- var EXIT_ALLOW7 = 0;
23850
+ var EXIT_ALLOW8 = 0;
23725
23851
  var MAX_FIELD_CHARS3 = 120;
23726
23852
  function _clamp(value) {
23727
23853
  return value.length <= MAX_FIELD_CHARS3 ? value : `${value.slice(0, MAX_FIELD_CHARS3 - 1)}\u2026`;
@@ -23739,7 +23865,7 @@ function disclosureKey(facts) {
23739
23865
  }
23740
23866
  function alreadyDisclosed(root, facts) {
23741
23867
  try {
23742
- const raw = fs46.readFileSync(path45.join(root, DISCLOSURE_STATE_REL), "utf-8");
23868
+ const raw = fs47.readFileSync(path46.join(root, DISCLOSURE_STATE_REL), "utf-8");
23743
23869
  const parsed = JSON.parse(raw);
23744
23870
  if (parsed === null || typeof parsed !== "object") {
23745
23871
  return false;
@@ -23751,9 +23877,9 @@ function alreadyDisclosed(root, facts) {
23751
23877
  }
23752
23878
  function recordDisclosure(root, facts, at) {
23753
23879
  try {
23754
- const p = path45.join(root, DISCLOSURE_STATE_REL);
23755
- fs46.mkdirSync(path45.dirname(p), { recursive: true });
23756
- fs46.writeFileSync(
23880
+ const p = path46.join(root, DISCLOSURE_STATE_REL);
23881
+ fs47.mkdirSync(path46.dirname(p), { recursive: true });
23882
+ fs47.writeFileSync(
23757
23883
  p,
23758
23884
  `${JSON.stringify({ disclosed: disclosureKey(facts), at }, null, 2)}
23759
23885
  `,
@@ -23783,25 +23909,25 @@ function run8(stdin, options = {}) {
23783
23909
  envelope = parsed;
23784
23910
  }
23785
23911
  } catch {
23786
- return EXIT_ALLOW7;
23912
+ return EXIT_ALLOW8;
23787
23913
  }
23788
23914
  }
23789
23915
  if (envelope["event"] !== "session_start") {
23790
- return EXIT_ALLOW7;
23916
+ return EXIT_ALLOW8;
23791
23917
  }
23792
23918
  if (is_replay_mode()) {
23793
- return EXIT_ALLOW7;
23919
+ return EXIT_ALLOW8;
23794
23920
  }
23795
23921
  const settingsFile = options.settingsFile ?? resolveSettingsPath(_resolveRoot(envelope));
23796
- const root = path45.dirname(settingsFile);
23922
+ const root = path46.dirname(settingsFile);
23797
23923
  let settings;
23798
23924
  try {
23799
23925
  settings = read_remote_settings(settingsFile);
23800
23926
  } catch {
23801
- return EXIT_ALLOW7;
23927
+ return EXIT_ALLOW8;
23802
23928
  }
23803
23929
  if (!settings.active) {
23804
- return EXIT_ALLOW7;
23930
+ return EXIT_ALLOW8;
23805
23931
  }
23806
23932
  const facts = {
23807
23933
  org_id: settings.org_id,
@@ -23809,7 +23935,7 @@ function run8(stdin, options = {}) {
23809
23935
  log_path: settings.log_path
23810
23936
  };
23811
23937
  if (alreadyDisclosed(root, facts)) {
23812
- return EXIT_ALLOW7;
23938
+ return EXIT_ALLOW8;
23813
23939
  }
23814
23940
  process.stdout.write(
23815
23941
  `${JSON.stringify({
@@ -23820,9 +23946,9 @@ function run8(stdin, options = {}) {
23820
23946
  `
23821
23947
  );
23822
23948
  recordDisclosure(root, facts, options.now ?? (/* @__PURE__ */ new Date()).toISOString());
23823
- return EXIT_ALLOW7;
23949
+ return EXIT_ALLOW8;
23824
23950
  }
23825
- function main26(argv) {
23951
+ function main27(argv) {
23826
23952
  const args = argv ?? process.argv.slice(2);
23827
23953
  void args;
23828
23954
  return run8(readHookStdin());
@@ -23834,16 +23960,16 @@ function _isCliEntry22() {
23834
23960
  if (process.argv[1] === void 0) {
23835
23961
  return false;
23836
23962
  }
23837
- return import.meta.url === pathToFileURL23(path45.resolve(process.argv[1])).href;
23963
+ return import.meta.url === pathToFileURL24(path46.resolve(process.argv[1])).href;
23838
23964
  }
23839
23965
  if (_isCliEntry22()) {
23840
- process.exit(main26());
23966
+ process.exit(main27());
23841
23967
  }
23842
23968
 
23843
23969
  // src/scripts/self_repair_hook.ts
23844
- import * as fs48 from "node:fs";
23845
- import * as path48 from "node:path";
23846
- import { fileURLToPath as fileURLToPath30, pathToFileURL as pathToFileURL24 } from "node:url";
23970
+ import * as fs49 from "node:fs";
23971
+ import * as path49 from "node:path";
23972
+ import { fileURLToPath as fileURLToPath31, pathToFileURL as pathToFileURL25 } from "node:url";
23847
23973
 
23848
23974
  // src/scripts/_lib/self_repair.ts
23849
23975
  import { createHash as createHash8 } from "node:crypto";
@@ -24080,14 +24206,14 @@ function mergeRecord(existing, finding, now) {
24080
24206
  }
24081
24207
 
24082
24208
  // src/scripts/_lib/self_repair_store.ts
24083
- import * as fs47 from "node:fs";
24084
- import * as path46 from "node:path";
24085
- var STORE_REL = path46.join("agents", "runtime", "self-repair");
24209
+ import * as fs48 from "node:fs";
24210
+ import * as path47 from "node:path";
24211
+ var STORE_REL = path47.join("agents", "runtime", "self-repair");
24086
24212
  function storeDir(root) {
24087
- return path46.join(root, STORE_REL);
24213
+ return path47.join(root, STORE_REL);
24088
24214
  }
24089
24215
  function recordPath(root, fp) {
24090
- return path46.join(storeDir(root), `${fp}.json`);
24216
+ return path47.join(storeDir(root), `${fp}.json`);
24091
24217
  }
24092
24218
  function isRecord(v) {
24093
24219
  if (typeof v !== "object" || v === null) {
@@ -24098,7 +24224,7 @@ function isRecord(v) {
24098
24224
  }
24099
24225
  function readRecord(root, fp) {
24100
24226
  try {
24101
- const parsed = JSON.parse(fs47.readFileSync(recordPath(root, fp), "utf-8"));
24227
+ const parsed = JSON.parse(fs48.readFileSync(recordPath(root, fp), "utf-8"));
24102
24228
  return isRecord(parsed) ? parsed : null;
24103
24229
  } catch {
24104
24230
  return null;
@@ -24106,8 +24232,8 @@ function readRecord(root, fp) {
24106
24232
  }
24107
24233
  function writeRecord(root, record) {
24108
24234
  const dir = storeDir(root);
24109
- fs47.mkdirSync(dir, { recursive: true });
24110
- fs47.writeFileSync(
24235
+ fs48.mkdirSync(dir, { recursive: true });
24236
+ fs48.writeFileSync(
24111
24237
  recordPath(root, record.fingerprint),
24112
24238
  `${JSON.stringify(record, null, 2)}
24113
24239
  `,
@@ -24117,7 +24243,7 @@ function writeRecord(root, record) {
24117
24243
  function listRecords(root) {
24118
24244
  let names;
24119
24245
  try {
24120
- names = fs47.readdirSync(storeDir(root));
24246
+ names = fs48.readdirSync(storeDir(root));
24121
24247
  } catch {
24122
24248
  return [];
24123
24249
  }
@@ -24139,11 +24265,11 @@ function openRecords(root) {
24139
24265
  }
24140
24266
  var OVERFLOW_FILE = "_overflow.json";
24141
24267
  function overflowPath(root) {
24142
- return path46.join(storeDir(root), OVERFLOW_FILE);
24268
+ return path47.join(storeDir(root), OVERFLOW_FILE);
24143
24269
  }
24144
24270
  function readOverflow(root) {
24145
24271
  try {
24146
- const parsed = JSON.parse(fs47.readFileSync(overflowPath(root), "utf-8"));
24272
+ const parsed = JSON.parse(fs48.readFileSync(overflowPath(root), "utf-8"));
24147
24273
  return typeof parsed === "object" && parsed !== null ? parsed : {};
24148
24274
  } catch {
24149
24275
  return {};
@@ -24154,8 +24280,8 @@ function bumpOverflow(root, source, now) {
24154
24280
  const prev = counts[source]?.dropped ?? 0;
24155
24281
  counts[source] = { dropped: prev + 1, last_seen: now };
24156
24282
  const dir = storeDir(root);
24157
- fs47.mkdirSync(dir, { recursive: true });
24158
- fs47.writeFileSync(overflowPath(root), `${JSON.stringify(counts, null, 2)}
24283
+ fs48.mkdirSync(dir, { recursive: true });
24284
+ fs48.writeFileSync(overflowPath(root), `${JSON.stringify(counts, null, 2)}
24159
24285
  `, "utf-8");
24160
24286
  }
24161
24287
  function upsertFinding(root, finding, now) {
@@ -24172,7 +24298,7 @@ function upsertFinding(root, finding, now) {
24172
24298
 
24173
24299
  // src/scripts/hooks/telemetry_self_repair.ts
24174
24300
  import * as os8 from "node:os";
24175
- import * as path47 from "node:path";
24301
+ import * as path48 from "node:path";
24176
24302
  function str(v) {
24177
24303
  return typeof v === "string" ? v : "";
24178
24304
  }
@@ -24204,7 +24330,7 @@ function emitDefectShadow(root, rec, env) {
24204
24330
  package_version: extractPackageVersion(process.env),
24205
24331
  discipline_profile: extractDisciplineProfile(text)
24206
24332
  });
24207
- const logPath = path47.isAbsolute(settings.log_path) ? settings.log_path : path47.join(projectRoot, settings.log_path);
24333
+ const logPath = path48.isAbsolute(settings.log_path) ? settings.log_path : path48.join(projectRoot, settings.log_path);
24208
24334
  const spool = settings.flush === FLUSH_SESSION_END ? spool_path_for(logPath) : null;
24209
24335
  append_class_a_record(
24210
24336
  logPath,
@@ -24223,8 +24349,8 @@ function emitDefectShadow(root, rec, env) {
24223
24349
  }
24224
24350
 
24225
24351
  // src/scripts/self_repair_hook.ts
24226
- var EXIT_ALLOW8 = 0;
24227
- function isObject3(v) {
24352
+ var EXIT_ALLOW9 = 0;
24353
+ function isObject4(v) {
24228
24354
  return typeof v === "object" && v !== null && !Array.isArray(v);
24229
24355
  }
24230
24356
  function str2(v) {
@@ -24241,7 +24367,7 @@ function readTurn(transcriptPath, pinned) {
24241
24367
  }
24242
24368
  let lines;
24243
24369
  try {
24244
- lines = fs48.readFileSync(transcriptPath, "utf-8").split("\n");
24370
+ lines = fs49.readFileSync(transcriptPath, "utf-8").split("\n");
24245
24371
  } catch {
24246
24372
  return empty;
24247
24373
  }
@@ -24259,11 +24385,11 @@ function readTurn(transcriptPath, pinned) {
24259
24385
  } catch {
24260
24386
  continue;
24261
24387
  }
24262
- if (!isObject3(obj)) {
24388
+ if (!isObject4(obj)) {
24263
24389
  continue;
24264
24390
  }
24265
24391
  const msg = obj["message"];
24266
- if (!isObject3(msg)) {
24392
+ if (!isObject4(msg)) {
24267
24393
  continue;
24268
24394
  }
24269
24395
  const content = msg["content"];
@@ -24282,7 +24408,7 @@ function readTurn(transcriptPath, pinned) {
24282
24408
  }
24283
24409
  const parts = [];
24284
24410
  for (const blk of content) {
24285
- if (!isObject3(blk)) {
24411
+ if (!isObject4(blk)) {
24286
24412
  continue;
24287
24413
  }
24288
24414
  if (blk["type"] === "text" && typeof blk["text"] === "string") {
@@ -24291,7 +24417,7 @@ function readTurn(transcriptPath, pinned) {
24291
24417
  if (blk["type"] === "tool_use") {
24292
24418
  const input = blk["input"];
24293
24419
  const name = str2(blk["name"]);
24294
- const cmd = isObject3(input) ? str2(input["command"]) : "";
24420
+ const cmd = isObject4(input) ? str2(input["command"]) : "";
24295
24421
  toolCommands.push(`${name} ${cmd}`.trim());
24296
24422
  }
24297
24423
  }
@@ -24315,17 +24441,17 @@ function pinnedLanguage(env) {
24315
24441
  }
24316
24442
  return null;
24317
24443
  }
24318
- function main27() {
24444
+ function main28() {
24319
24445
  let env = {};
24320
24446
  try {
24321
24447
  const raw = readHookStdin();
24322
24448
  const parsed = raw.trim() ? JSON.parse(raw) : {};
24323
- env = isObject3(parsed) ? parsed : {};
24449
+ env = isObject4(parsed) ? parsed : {};
24324
24450
  } catch {
24325
24451
  }
24326
24452
  const slot = str2(env["event"]) || "session_start";
24327
24453
  if (slot !== "user_prompt_submit" && slot !== "stop") {
24328
- return EXIT_ALLOW8;
24454
+ return EXIT_ALLOW9;
24329
24455
  }
24330
24456
  const root = workspaceRoot(env);
24331
24457
  const now = (/* @__PURE__ */ new Date()).toISOString();
@@ -24350,16 +24476,16 @@ function main27() {
24350
24476
  }
24351
24477
  }
24352
24478
  if (slot !== "user_prompt_submit") {
24353
- return EXIT_ALLOW8;
24479
+ return EXIT_ALLOW9;
24354
24480
  }
24355
24481
  let open;
24356
24482
  try {
24357
24483
  open = openRecords(root);
24358
24484
  } catch {
24359
- return EXIT_ALLOW8;
24485
+ return EXIT_ALLOW9;
24360
24486
  }
24361
24487
  if (open.length === 0) {
24362
- return EXIT_ALLOW8;
24488
+ return EXIT_ALLOW9;
24363
24489
  }
24364
24490
  process.stdout.write(
24365
24491
  `${JSON.stringify({
@@ -24373,42 +24499,42 @@ function main27() {
24373
24499
  })}
24374
24500
  `
24375
24501
  );
24376
- return EXIT_ALLOW8;
24502
+ return EXIT_ALLOW9;
24377
24503
  }
24378
- function isCliEntry9() {
24504
+ function isCliEntry10() {
24379
24505
  if (true) {
24380
24506
  return false;
24381
24507
  }
24382
24508
  if (process.argv[1] === void 0) {
24383
24509
  return false;
24384
24510
  }
24385
- const argvUrl = pathToFileURL24(path48.resolve(process.argv[1])).href;
24511
+ const argvUrl = pathToFileURL25(path49.resolve(process.argv[1])).href;
24386
24512
  if (import.meta.url === argvUrl) {
24387
24513
  return true;
24388
24514
  }
24389
24515
  try {
24390
- return fs48.realpathSync(fileURLToPath30(import.meta.url)) === fs48.realpathSync(path48.resolve(process.argv[1]));
24516
+ return fs49.realpathSync(fileURLToPath31(import.meta.url)) === fs49.realpathSync(path49.resolve(process.argv[1]));
24391
24517
  } catch {
24392
24518
  return false;
24393
24519
  }
24394
24520
  }
24395
- if (isCliEntry9()) {
24396
- process.exit(main27());
24521
+ if (isCliEntry10()) {
24522
+ process.exit(main28());
24397
24523
  }
24398
24524
 
24399
24525
  // src/scripts/session_register_hook.ts
24400
- import * as fs53 from "node:fs";
24401
- import * as path53 from "node:path";
24526
+ import * as fs54 from "node:fs";
24527
+ import * as path54 from "node:path";
24402
24528
  import process10 from "node:process";
24403
- import { fileURLToPath as fileURLToPath31 } from "node:url";
24529
+ import { fileURLToPath as fileURLToPath32 } from "node:url";
24404
24530
 
24405
24531
  // src/scripts/_lib/session_register.ts
24406
- import fs50 from "node:fs";
24407
- import path50 from "node:path";
24532
+ import fs51 from "node:fs";
24533
+ import path51 from "node:path";
24408
24534
 
24409
24535
  // src/scripts/_lib/fs_atomic.ts
24410
- import fs49 from "node:fs";
24411
- import path49 from "node:path";
24536
+ import fs50 from "node:fs";
24537
+ import path50 from "node:path";
24412
24538
  import { randomBytes } from "node:crypto";
24413
24539
  function _normalize_encoding(encoding) {
24414
24540
  const compact = encoding.toLowerCase().replace(/[-_\s]/g, "");
@@ -24424,9 +24550,9 @@ function _normalize_encoding(encoding) {
24424
24550
  }
24425
24551
  function write_atomic(p, data, options = {}) {
24426
24552
  const encoding = options.encoding ?? "utf-8";
24427
- const target = path49.normalize(p);
24428
- const parent = path49.dirname(target);
24429
- fs49.mkdirSync(parent, { recursive: true });
24553
+ const target = path50.normalize(p);
24554
+ const parent = path50.dirname(target);
24555
+ fs50.mkdirSync(parent, { recursive: true });
24430
24556
  let payload;
24431
24557
  if (typeof data === "string") {
24432
24558
  payload = Buffer.from(data, _normalize_encoding(encoding));
@@ -24440,12 +24566,12 @@ function write_atomic(p, data, options = {}) {
24440
24566
  let fd = null;
24441
24567
  let tmp_path = "";
24442
24568
  for (let attempt = 0; attempt < 32; attempt += 1) {
24443
- tmp_path = path49.join(
24569
+ tmp_path = path50.join(
24444
24570
  parent,
24445
- `.${path49.basename(target)}.tmp.${randomBytes(6).toString("hex")}`
24571
+ `.${path50.basename(target)}.tmp.${randomBytes(6).toString("hex")}`
24446
24572
  );
24447
24573
  try {
24448
- fd = fs49.openSync(tmp_path, "wx", 384);
24574
+ fd = fs50.openSync(tmp_path, "wx", 384);
24449
24575
  break;
24450
24576
  } catch (err) {
24451
24577
  if (err.code === "EEXIST") continue;
@@ -24459,24 +24585,24 @@ function write_atomic(p, data, options = {}) {
24459
24585
  try {
24460
24586
  let offset = 0;
24461
24587
  while (offset < payload.length) {
24462
- offset += fs49.writeSync(fd, payload, offset, payload.length - offset);
24588
+ offset += fs50.writeSync(fd, payload, offset, payload.length - offset);
24463
24589
  }
24464
24590
  try {
24465
- fs49.fsyncSync(fd);
24591
+ fs50.fsyncSync(fd);
24466
24592
  } catch {
24467
24593
  }
24468
- fs49.closeSync(fd);
24594
+ fs50.closeSync(fd);
24469
24595
  closed = true;
24470
- fs49.renameSync(tmp_path, target);
24596
+ fs50.renameSync(tmp_path, target);
24471
24597
  } catch (err) {
24472
24598
  if (!closed) {
24473
24599
  try {
24474
- fs49.closeSync(fd);
24600
+ fs50.closeSync(fd);
24475
24601
  } catch {
24476
24602
  }
24477
24603
  }
24478
24604
  try {
24479
- fs49.unlinkSync(tmp_path);
24605
+ fs50.unlinkSync(tmp_path);
24480
24606
  } catch {
24481
24607
  }
24482
24608
  throw err;
@@ -24487,17 +24613,17 @@ function write_atomic(p, data, options = {}) {
24487
24613
  function _fsync_dir(directory) {
24488
24614
  let dir_fd;
24489
24615
  try {
24490
- dir_fd = fs49.openSync(directory, fs49.constants.O_RDONLY);
24616
+ dir_fd = fs50.openSync(directory, fs50.constants.O_RDONLY);
24491
24617
  } catch {
24492
24618
  return;
24493
24619
  }
24494
24620
  try {
24495
24621
  try {
24496
- fs49.fsyncSync(dir_fd);
24622
+ fs50.fsyncSync(dir_fd);
24497
24623
  } catch {
24498
24624
  }
24499
24625
  } finally {
24500
- fs49.closeSync(dir_fd);
24626
+ fs50.closeSync(dir_fd);
24501
24627
  }
24502
24628
  }
24503
24629
 
@@ -24535,7 +24661,7 @@ function safe_stem(session_id) {
24535
24661
  }
24536
24662
  function register_dir(workspace_root) {
24537
24663
  const common = git_common_dir(workspace_root);
24538
- return common === null ? null : path50.join(common, REGISTER_DIRNAME);
24664
+ return common === null ? null : path51.join(common, REGISTER_DIRNAME);
24539
24665
  }
24540
24666
  function iso_now(now = /* @__PURE__ */ new Date()) {
24541
24667
  return now.toISOString().replace(/\.\d{3}Z$/, "+00:00");
@@ -24558,7 +24684,7 @@ function is_record(v) {
24558
24684
  }
24559
24685
  function write_record(dir, rec) {
24560
24686
  try {
24561
- const target = path50.join(dir, `${safe_stem(rec.session_id)}.json`);
24687
+ const target = path51.join(dir, `${safe_stem(rec.session_id)}.json`);
24562
24688
  write_atomic(target, `${JSON.stringify(rec, null, 2)}
24563
24689
  `);
24564
24690
  return true;
@@ -24568,8 +24694,8 @@ function write_record(dir, rec) {
24568
24694
  }
24569
24695
  function read_own_record(dir, session_id) {
24570
24696
  try {
24571
- const target = path50.join(dir, `${safe_stem(session_id)}.json`);
24572
- const parsed = JSON.parse(fs50.readFileSync(target, "utf-8"));
24697
+ const target = path51.join(dir, `${safe_stem(session_id)}.json`);
24698
+ const parsed = JSON.parse(fs51.readFileSync(target, "utf-8"));
24573
24699
  return is_record(parsed) ? parsed : null;
24574
24700
  } catch {
24575
24701
  return null;
@@ -24577,7 +24703,7 @@ function read_own_record(dir, session_id) {
24577
24703
  }
24578
24704
  function delete_record(dir, session_id) {
24579
24705
  try {
24580
- fs50.unlinkSync(path50.join(dir, `${safe_stem(session_id)}.json`));
24706
+ fs51.unlinkSync(path51.join(dir, `${safe_stem(session_id)}.json`));
24581
24707
  return true;
24582
24708
  } catch {
24583
24709
  return false;
@@ -24590,16 +24716,16 @@ function read_live_records(dir, options = {}) {
24590
24716
  const grace = options.prune_grace_ms ?? PRUNE_GRACE_MS;
24591
24717
  let names;
24592
24718
  try {
24593
- names = fs50.readdirSync(dir).filter((n) => n.endsWith(".json"));
24719
+ names = fs51.readdirSync(dir).filter((n) => n.endsWith(".json"));
24594
24720
  } catch {
24595
24721
  return [];
24596
24722
  }
24597
24723
  const live = [];
24598
24724
  for (const name of names) {
24599
- const full = path50.join(dir, name);
24725
+ const full = path51.join(dir, name);
24600
24726
  let rec = null;
24601
24727
  try {
24602
- const parsed = JSON.parse(fs50.readFileSync(full, "utf-8"));
24728
+ const parsed = JSON.parse(fs51.readFileSync(full, "utf-8"));
24603
24729
  rec = is_record(parsed) ? parsed : null;
24604
24730
  } catch {
24605
24731
  rec = null;
@@ -24607,7 +24733,7 @@ function read_live_records(dir, options = {}) {
24607
24733
  if (rec === null || is_expired(rec, now)) {
24608
24734
  if (prune && (rec === null || is_expired(rec, new Date(now.getTime() - grace)))) {
24609
24735
  try {
24610
- fs50.unlinkSync(full);
24736
+ fs51.unlinkSync(full);
24611
24737
  } catch {
24612
24738
  }
24613
24739
  }
@@ -24647,13 +24773,13 @@ function classify_collisions(others, here) {
24647
24773
 
24648
24774
  // src/scripts/_lib/turn_end_refusals.ts
24649
24775
  import * as crypto5 from "node:crypto";
24650
- import * as fs52 from "node:fs";
24651
- import * as path52 from "node:path";
24776
+ import * as fs53 from "node:fs";
24777
+ import * as path53 from "node:path";
24652
24778
 
24653
24779
  // src/scripts/_lib/installed_lock.ts
24654
- import * as fs51 from "node:fs";
24780
+ import * as fs52 from "node:fs";
24655
24781
  import * as os9 from "node:os";
24656
- import * as path51 from "node:path";
24782
+ import * as path52 from "node:path";
24657
24783
  var LOCKFILE_ENV = "AGENT_CONFIG_INSTALLED_LOCK";
24658
24784
  function _default_lockfile() {
24659
24785
  return write_target("installed.lock");
@@ -24670,7 +24796,7 @@ function expanduser2(p) {
24670
24796
  return os9.homedir();
24671
24797
  }
24672
24798
  if (p.startsWith("~/") || process.platform === "win32" && p.startsWith("~\\")) {
24673
- return path51.join(os9.homedir(), p.slice(2));
24799
+ return path52.join(os9.homedir(), p.slice(2));
24674
24800
  }
24675
24801
  return p;
24676
24802
  }
@@ -24690,7 +24816,7 @@ function read_lockfile(path106) {
24690
24816
  const target = path106 ?? lockfile_path();
24691
24817
  let text;
24692
24818
  try {
24693
- text = fs51.readFileSync(target, { encoding: "utf-8" });
24819
+ text = fs52.readFileSync(target, { encoding: "utf-8" });
24694
24820
  } catch {
24695
24821
  return null;
24696
24822
  }
@@ -24757,19 +24883,19 @@ var DETECTOR_IDS = [
24757
24883
  "verification",
24758
24884
  "completion"
24759
24885
  ];
24760
- var REFUSAL_STATE_REL = path52.join("agents", "runtime", "state", "turn-end-gate");
24886
+ var REFUSAL_STATE_REL = path53.join("agents", "runtime", "state", "turn-end-gate");
24761
24887
  function refusalStateDir(workspaceRoot3) {
24762
- return path52.join(workspaceRoot3, REFUSAL_STATE_REL);
24888
+ return path53.join(workspaceRoot3, REFUSAL_STATE_REL);
24763
24889
  }
24764
24890
  function deriveSessionKey(sessionId2) {
24765
24891
  return crypto5.createHash("sha256").update(sessionId2).digest("hex").slice(0, 32);
24766
24892
  }
24767
24893
  function sessionRefusalFile(workspaceRoot3, sessionKey) {
24768
- return path52.join(refusalStateDir(workspaceRoot3), `${sessionKey}.json`);
24894
+ return path53.join(refusalStateDir(workspaceRoot3), `${sessionKey}.json`);
24769
24895
  }
24770
24896
  function readSessionCounts(workspaceRoot3, sessionId2) {
24771
24897
  try {
24772
- const raw = fs52.readFileSync(
24898
+ const raw = fs53.readFileSync(
24773
24899
  sessionRefusalFile(workspaceRoot3, deriveSessionKey(sessionId2)),
24774
24900
  "utf-8"
24775
24901
  );
@@ -24871,7 +24997,7 @@ function pruneAgedRefusalState(workspaceRoot3, opts = {}) {
24871
24997
  const result = { scanned: 0, pruned: 0, kept: 0 };
24872
24998
  let entries;
24873
24999
  try {
24874
- entries = fs52.readdirSync(dir);
25000
+ entries = fs53.readdirSync(dir);
24875
25001
  } catch {
24876
25002
  return result;
24877
25003
  }
@@ -24879,10 +25005,10 @@ function pruneAgedRefusalState(workspaceRoot3, opts = {}) {
24879
25005
  for (const name of entries) {
24880
25006
  if (!name.endsWith(".json")) continue;
24881
25007
  result.scanned += 1;
24882
- const file = path52.join(dir, name);
25008
+ const file = path53.join(dir, name);
24883
25009
  let rec = null;
24884
25010
  try {
24885
- rec = parseRecord(fs52.readFileSync(file, "utf-8"));
25011
+ rec = parseRecord(fs53.readFileSync(file, "utf-8"));
24886
25012
  } catch {
24887
25013
  rec = null;
24888
25014
  }
@@ -24896,7 +25022,7 @@ function pruneAgedRefusalState(workspaceRoot3, opts = {}) {
24896
25022
  continue;
24897
25023
  }
24898
25024
  try {
24899
- fs52.unlinkSync(file);
25025
+ fs53.unlinkSync(file);
24900
25026
  result.pruned += 1;
24901
25027
  } catch {
24902
25028
  result.kept += 1;
@@ -24907,16 +25033,16 @@ function pruneAgedRefusalState(workspaceRoot3, opts = {}) {
24907
25033
 
24908
25034
  // src/scripts/session_register_hook.ts
24909
25035
  var REPLAY_ENV_VAR6 = "AGENT_CONFIG_REPLAY";
24910
- var _STATE_REL = path53.join("agents", "runtime", "state");
24911
- var ROADMAP_CLAIM_REL = path53.join(_STATE_REL, "roadmap-claim.json");
25036
+ var _STATE_REL = path54.join("agents", "runtime", "state");
25037
+ var ROADMAP_CLAIM_REL = path54.join(_STATE_REL, "roadmap-claim.json");
24912
25038
  function roadmap_claim_rel(session_id) {
24913
25039
  const id = String(session_id ?? "").trim();
24914
25040
  if (id === "") {
24915
25041
  return ROADMAP_CLAIM_REL;
24916
25042
  }
24917
- const rel = path53.join(_STATE_REL, `roadmap-claim-${safe_stem(id)}.json`);
24918
- const norm = path53.normalize(rel);
24919
- if (!norm.startsWith(`${_STATE_REL}${path53.sep}`) || norm.includes("..")) {
25043
+ const rel = path54.join(_STATE_REL, `roadmap-claim-${safe_stem(id)}.json`);
25044
+ const norm = path54.normalize(rel);
25045
+ if (!norm.startsWith(`${_STATE_REL}${path54.sep}`) || norm.includes("..")) {
24920
25046
  return ROADMAP_CLAIM_REL;
24921
25047
  }
24922
25048
  return norm;
@@ -24924,21 +25050,21 @@ function roadmap_claim_rel(session_id) {
24924
25050
  var CLAIM_DIRNAME = "agent-claims";
24925
25051
  function claim_dir(workspace_root) {
24926
25052
  const common = git_common_dir(workspace_root);
24927
- return common === null ? null : path53.join(common, CLAIM_DIRNAME);
25053
+ return common === null ? null : path54.join(common, CLAIM_DIRNAME);
24928
25054
  }
24929
25055
  function claim_read_paths(workspace_root, session_id) {
24930
25056
  const rel = roadmap_claim_rel(session_id);
24931
25057
  const dir = claim_dir(workspace_root);
24932
25058
  const out = [];
24933
25059
  if (dir !== null) {
24934
- out.push(path53.join(dir, path53.basename(rel)));
25060
+ out.push(path54.join(dir, path54.basename(rel)));
24935
25061
  if (rel !== ROADMAP_CLAIM_REL) {
24936
- out.push(path53.join(dir, path53.basename(ROADMAP_CLAIM_REL)));
25062
+ out.push(path54.join(dir, path54.basename(ROADMAP_CLAIM_REL)));
24937
25063
  }
24938
25064
  }
24939
- out.push(path53.join(workspace_root, rel));
25065
+ out.push(path54.join(workspace_root, rel));
24940
25066
  if (rel !== ROADMAP_CLAIM_REL) {
24941
- out.push(path53.join(workspace_root, ROADMAP_CLAIM_REL));
25067
+ out.push(path54.join(workspace_root, ROADMAP_CLAIM_REL));
24942
25068
  }
24943
25069
  return out;
24944
25070
  }
@@ -24947,7 +25073,7 @@ function _is_replay_mode4() {
24947
25073
  }
24948
25074
  function _read_claim_file(file) {
24949
25075
  try {
24950
- const parsed = JSON.parse(fs53.readFileSync(file, "utf-8"));
25076
+ const parsed = JSON.parse(fs54.readFileSync(file, "utf-8"));
24951
25077
  if (parsed === null || typeof parsed !== "object" || Array.isArray(parsed)) {
24952
25078
  return null;
24953
25079
  }
@@ -24972,7 +25098,7 @@ function resolve_claim(workspace_root, session_id) {
24972
25098
  const own = roadmap_claim_rel(session_id);
24973
25099
  if (own !== ROADMAP_CLAIM_REL) {
24974
25100
  for (const p of claim_read_paths(workspace_root, session_id)) {
24975
- if (path53.basename(p) === path53.basename(ROADMAP_CLAIM_REL)) continue;
25101
+ if (path54.basename(p) === path54.basename(ROADMAP_CLAIM_REL)) continue;
24976
25102
  const mine = _read_claim_file(p);
24977
25103
  if (mine !== null) {
24978
25104
  return {
@@ -24986,7 +25112,7 @@ function resolve_claim(workspace_root, session_id) {
24986
25112
  let legacy = null;
24987
25113
  let legacy_path = "";
24988
25114
  for (const p of claim_read_paths(workspace_root, session_id)) {
24989
- if (path53.basename(p) !== path53.basename(ROADMAP_CLAIM_REL)) continue;
25115
+ if (path54.basename(p) !== path54.basename(ROADMAP_CLAIM_REL)) continue;
24990
25116
  legacy = _read_claim_file(p);
24991
25117
  if (legacy !== null) {
24992
25118
  legacy_path = p;
@@ -25014,9 +25140,9 @@ function claim_is_stale(workspace_root, slug, peer_worktree) {
25014
25140
  return false;
25015
25141
  }
25016
25142
  const base = slug.trim().replace(/\.md$/, "");
25017
- const rel = path53.normalize(path53.join("agents", "roadmaps", `${base}.md`));
25018
- const inside = path53.dirname(rel) === path53.join("agents", "roadmaps");
25019
- if (!inside || path53.isAbsolute(base)) {
25143
+ const rel = path54.normalize(path54.join("agents", "roadmaps", `${base}.md`));
25144
+ const inside = path54.dirname(rel) === path54.join("agents", "roadmaps");
25145
+ if (!inside || path54.isAbsolute(base)) {
25020
25146
  return true;
25021
25147
  }
25022
25148
  const roots = [peer_worktree, workspace_root].filter(
@@ -25024,7 +25150,7 @@ function claim_is_stale(workspace_root, slug, peer_worktree) {
25024
25150
  );
25025
25151
  for (const root of roots) {
25026
25152
  try {
25027
- if (fs53.existsSync(path53.join(root, rel))) {
25153
+ if (fs54.existsSync(path54.join(root, rel))) {
25028
25154
  return false;
25029
25155
  }
25030
25156
  } catch {
@@ -25039,8 +25165,8 @@ function session_checkout(workspace_root, payload_cwd) {
25039
25165
  if (cwd === "") return fallback;
25040
25166
  let start;
25041
25167
  try {
25042
- if (!fs53.statSync(cwd).isDirectory()) return fallback;
25043
- start = fs53.realpathSync(cwd);
25168
+ if (!fs54.statSync(cwd).isDirectory()) return fallback;
25169
+ start = fs54.realpathSync(cwd);
25044
25170
  } catch {
25045
25171
  return fallback;
25046
25172
  }
@@ -25052,9 +25178,9 @@ function session_checkout(workspace_root, payload_cwd) {
25052
25178
  return root;
25053
25179
  }
25054
25180
  function canonical(p) {
25055
- const abs = path53.resolve(p);
25181
+ const abs = path54.resolve(p);
25056
25182
  try {
25057
- return fs53.realpathSync(abs);
25183
+ return fs54.realpathSync(abs);
25058
25184
  } catch {
25059
25185
  return abs;
25060
25186
  }
@@ -25063,7 +25189,7 @@ function nearest_checkout_root(start) {
25063
25189
  let dir = start;
25064
25190
  for (let i = 0; i < 64; i++) {
25065
25191
  if (git_dir(dir) !== null) return dir;
25066
- const up = path53.dirname(dir);
25192
+ const up = path54.dirname(dir);
25067
25193
  if (up === dir) return null;
25068
25194
  dir = up;
25069
25195
  }
@@ -25200,7 +25326,7 @@ function foreign_sessions_block(workspace_root, session_id, now = /* @__PURE__ *
25200
25326
  );
25201
25327
  return parts.join("\n");
25202
25328
  }
25203
- function main28() {
25329
+ function main29() {
25204
25330
  let envelope = {};
25205
25331
  try {
25206
25332
  const raw = readHookStdin().trim();
@@ -25229,9 +25355,9 @@ function main28() {
25229
25355
  const dir = register_dir(root);
25230
25356
  if (dir !== null) delete_record(dir, session_id);
25231
25357
  for (const p of claim_read_paths(root, session_id)) {
25232
- if (path53.basename(p) !== path53.basename(roadmap_claim_rel(session_id))) continue;
25358
+ if (path54.basename(p) !== path54.basename(roadmap_claim_rel(session_id))) continue;
25233
25359
  try {
25234
- fs53.unlinkSync(p);
25360
+ fs54.unlinkSync(p);
25235
25361
  } catch {
25236
25362
  }
25237
25363
  }
@@ -25279,14 +25405,14 @@ function main28() {
25279
25405
  return 0;
25280
25406
  }
25281
25407
  var _bundled4 = true;
25282
- if (!_bundled4 && fileURLToPath31(import.meta.url) === path53.resolve(process10.argv[1] ?? "")) {
25283
- process10.exit(main28());
25408
+ if (!_bundled4 && fileURLToPath32(import.meta.url) === path54.resolve(process10.argv[1] ?? "")) {
25409
+ process10.exit(main29());
25284
25410
  }
25285
25411
 
25286
25412
  // src/scripts/language_mirror_hook.ts
25287
- import fs54 from "node:fs";
25288
- import path54 from "node:path";
25289
- import { fileURLToPath as fileURLToPath32, pathToFileURL as pathToFileURL25 } from "node:url";
25413
+ import fs55 from "node:fs";
25414
+ import path55 from "node:path";
25415
+ import { fileURLToPath as fileURLToPath33, pathToFileURL as pathToFileURL26 } from "node:url";
25290
25416
 
25291
25417
  // src/scripts/_lib/prompt_shape.ts
25292
25418
  function isSyntheticPrompt(prompt) {
@@ -25343,10 +25469,10 @@ function stripInjectedRegions(text) {
25343
25469
  }
25344
25470
 
25345
25471
  // src/scripts/language_mirror_hook.ts
25346
- var EXIT_ALLOW9 = 0;
25347
- var EXIT_WARN3 = 2;
25348
- var STATE_FILE6 = path54.join("agents", "state", "language-mirror.json");
25349
- var STATE_DIR4 = path54.join("agents", "state", "language-mirror");
25472
+ var EXIT_ALLOW10 = 0;
25473
+ var EXIT_WARN4 = 2;
25474
+ var STATE_FILE6 = path55.join("agents", "state", "language-mirror.json");
25475
+ var STATE_DIR4 = path55.join("agents", "state", "language-mirror");
25350
25476
  var STATE_RETENTION_DAYS2 = 7;
25351
25477
  function hasStableSessionId(session_id) {
25352
25478
  return has_stable_session_id(session_id);
@@ -25354,10 +25480,10 @@ function hasStableSessionId(session_id) {
25354
25480
  function statePathFor2(session_id) {
25355
25481
  return session_state_file(STATE_DIR4, session_id);
25356
25482
  }
25357
- var PIN_LOST_DIR = path54.join("agents", "state", "language-mirror.pin-lost");
25483
+ var PIN_LOST_DIR = path55.join("agents", "state", "language-mirror.pin-lost");
25358
25484
  function pinLostMarker(session_id) {
25359
25485
  const safe = (session_id || "unknown-session").replace(/[^A-Za-z0-9._-]/g, "_");
25360
- return path54.join(PIN_LOST_DIR, `${safe}.marker`);
25486
+ return path55.join(PIN_LOST_DIR, `${safe}.marker`);
25361
25487
  }
25362
25488
  function _isObject7(v) {
25363
25489
  return typeof v === "object" && v !== null && !Array.isArray(v);
@@ -25453,7 +25579,7 @@ This pin exists because the trigger is not observable from the transcript alone:
25453
25579
  }
25454
25580
  function _loadState(target) {
25455
25581
  try {
25456
- const raw = fs54.readFileSync(target, "utf8");
25582
+ const raw = fs55.readFileSync(target, "utf8");
25457
25583
  const decoded = JSON.parse(raw);
25458
25584
  return _isObject7(decoded) ? decoded : {};
25459
25585
  } catch {
@@ -25508,10 +25634,10 @@ function _sessionId(envelope) {
25508
25634
  return typeof v === "string" && v.trim() !== "" ? v : "unknown-session";
25509
25635
  }
25510
25636
  function _migrateLegacyMarker(consumer_root) {
25511
- const legacy = path54.join(consumer_root, PIN_LOST_DIR);
25637
+ const legacy = path55.join(consumer_root, PIN_LOST_DIR);
25512
25638
  try {
25513
- if (fs54.statSync(legacy).isFile()) {
25514
- fs54.rmSync(legacy, { force: true });
25639
+ if (fs55.statSync(legacy).isFile()) {
25640
+ fs55.rmSync(legacy, { force: true });
25515
25641
  }
25516
25642
  } catch {
25517
25643
  }
@@ -25520,13 +25646,17 @@ function _setPinLost(consumer_root, session_id) {
25520
25646
  if (is_replay_mode()) return;
25521
25647
  _migrateLegacyMarker(consumer_root);
25522
25648
  try {
25523
- atomic_write_text(path54.join(consumer_root, pinLostMarker(session_id)), (/* @__PURE__ */ new Date()).toISOString());
25524
- } catch {
25649
+ atomic_write_text(path55.join(consumer_root, pinLostMarker(session_id)), (/* @__PURE__ */ new Date()).toISOString());
25650
+ } catch (err) {
25651
+ process.stderr.write(
25652
+ `language-mirror: pin-lost marker write failed (${_errText(err)}) \u2014 the pin will NOT be re-emitted after this compaction. Turn outcome unchanged.
25653
+ `
25654
+ );
25525
25655
  }
25526
25656
  }
25527
25657
  function _pinLost(consumer_root, session_id) {
25528
25658
  try {
25529
- return fs54.existsSync(path54.join(consumer_root, pinLostMarker(session_id)));
25659
+ return fs55.existsSync(path55.join(consumer_root, pinLostMarker(session_id)));
25530
25660
  } catch {
25531
25661
  return false;
25532
25662
  }
@@ -25534,30 +25664,30 @@ function _pinLost(consumer_root, session_id) {
25534
25664
  function _clearPinLost(consumer_root, session_id) {
25535
25665
  if (is_replay_mode()) return;
25536
25666
  try {
25537
- fs54.rmSync(path54.join(consumer_root, pinLostMarker(session_id)), { force: true });
25667
+ fs55.rmSync(path55.join(consumer_root, pinLostMarker(session_id)), { force: true });
25538
25668
  } catch {
25539
25669
  }
25540
25670
  }
25541
25671
  function _reEmitAfterCompaction(consumer_root, session_id, write_json = atomic_write_json) {
25542
25672
  if (!hasStableSessionId(session_id)) {
25543
- return EXIT_ALLOW9;
25673
+ return EXIT_ALLOW10;
25544
25674
  }
25545
25675
  if (!_pinLost(consumer_root, session_id)) {
25546
- return EXIT_ALLOW9;
25676
+ return EXIT_ALLOW10;
25547
25677
  }
25548
- return _withToolWriteLock(consumer_root, session_id, EXIT_ALLOW9, () => {
25549
- const previous = _loadState(path54.join(consumer_root, statePathFor2(session_id)));
25678
+ return _withToolWriteLock(consumer_root, session_id, EXIT_ALLOW10, () => {
25679
+ const previous = _loadState(path55.join(consumer_root, statePathFor2(session_id)));
25550
25680
  const language = previous.language;
25551
25681
  const source = previous.source === "system-locale" ? "system-locale" : "prompt";
25552
25682
  _clearPinLost(consumer_root, session_id);
25553
25683
  if (language !== "de" && language !== "en") {
25554
- return EXIT_ALLOW9;
25684
+ return EXIT_ALLOW10;
25555
25685
  }
25556
25686
  if (!_ownsPin(previous, session_id)) {
25557
- return EXIT_ALLOW9;
25687
+ return EXIT_ALLOW10;
25558
25688
  }
25559
25689
  if (!_resetDistance(consumer_root, previous, session_id, write_json)) {
25560
- return EXIT_ALLOW9;
25690
+ return EXIT_ALLOW10;
25561
25691
  }
25562
25692
  process.stdout.write(
25563
25693
  `${JSON.stringify({
@@ -25567,15 +25697,15 @@ function _reEmitAfterCompaction(consumer_root, session_id, write_json = atomic_w
25567
25697
  })}
25568
25698
  `
25569
25699
  );
25570
- return EXIT_WARN3;
25700
+ return EXIT_WARN4;
25571
25701
  });
25572
25702
  }
25573
25703
  function _pruneLegacyState(consumer_root) {
25574
- prune_legacy_state_file(path54.join(consumer_root, STATE_FILE6));
25704
+ prune_legacy_state_file(path55.join(consumer_root, STATE_FILE6));
25575
25705
  }
25576
- function _pruneStaleSessions(consumer_root, now_ms, mtimeOf = (target) => fs54.statSync(target).mtimeMs) {
25706
+ function _pruneStaleSessions(consumer_root, now_ms, mtimeOf = (target) => fs55.statSync(target).mtimeMs) {
25577
25707
  return prune_stale_session_states(
25578
- path54.join(consumer_root, STATE_DIR4),
25708
+ path55.join(consumer_root, STATE_DIR4),
25579
25709
  now_ms,
25580
25710
  STATE_RETENTION_DAYS2,
25581
25711
  mtimeOf
@@ -25583,24 +25713,24 @@ function _pruneStaleSessions(consumer_root, now_ms, mtimeOf = (target) => fs54.s
25583
25713
  }
25584
25714
  var LOCK_STALE_MS2 = 3e4;
25585
25715
  function _withToolWriteLock(consumer_root, session_id, when_busy, body, now_ms = Date.now()) {
25586
- const lock = `${path54.join(consumer_root, statePathFor2(session_id))}.lock`;
25716
+ const lock = `${path55.join(consumer_root, statePathFor2(session_id))}.lock`;
25587
25717
  let fd;
25588
25718
  const acquire = () => {
25589
25719
  try {
25590
- fs54.mkdirSync(path54.dirname(lock), { recursive: true });
25591
- return fs54.openSync(lock, "wx");
25720
+ fs55.mkdirSync(path55.dirname(lock), { recursive: true });
25721
+ return fs55.openSync(lock, "wx");
25592
25722
  } catch (err) {
25593
25723
  if (err.code !== "EEXIST") return null;
25594
25724
  let age;
25595
25725
  try {
25596
- age = now_ms - fs54.statSync(lock).mtimeMs;
25726
+ age = now_ms - fs55.statSync(lock).mtimeMs;
25597
25727
  } catch {
25598
25728
  return null;
25599
25729
  }
25600
25730
  if (age < LOCK_STALE_MS2) return null;
25601
25731
  try {
25602
- fs54.rmSync(lock, { force: true });
25603
- return fs54.openSync(lock, "wx");
25732
+ fs55.rmSync(lock, { force: true });
25733
+ return fs55.openSync(lock, "wx");
25604
25734
  } catch {
25605
25735
  return null;
25606
25736
  }
@@ -25613,11 +25743,11 @@ function _withToolWriteLock(consumer_root, session_id, when_busy, body, now_ms =
25613
25743
  return body();
25614
25744
  } finally {
25615
25745
  try {
25616
- fs54.closeSync(fd);
25746
+ fs55.closeSync(fd);
25617
25747
  } catch {
25618
25748
  }
25619
25749
  try {
25620
- fs54.rmSync(lock, { force: true });
25750
+ fs55.rmSync(lock, { force: true });
25621
25751
  } catch {
25622
25752
  }
25623
25753
  }
@@ -25625,7 +25755,7 @@ function _withToolWriteLock(consumer_root, session_id, when_busy, body, now_ms =
25625
25755
  function _writeDistance(consumer_root, expected, session_id, value, write_json = atomic_write_json) {
25626
25756
  if (is_replay_mode()) return false;
25627
25757
  if (!hasStableSessionId(session_id)) return false;
25628
- const target = path54.join(consumer_root, statePathFor2(session_id));
25758
+ const target = path55.join(consumer_root, statePathFor2(session_id));
25629
25759
  const current = _loadState(target);
25630
25760
  if (!_ownsPin(current, session_id)) return false;
25631
25761
  if (current.detected_at !== expected.detected_at || current.language !== expected.language || current.source !== expected.source) {
@@ -25647,19 +25777,19 @@ function _resetDistance(consumer_root, expected, session_id, write_json = atomic
25647
25777
  }
25648
25778
  function _reEmitAfterDistance(consumer_root, session_id, write_json = atomic_write_json) {
25649
25779
  if (is_replay_mode()) {
25650
- return EXIT_ALLOW9;
25780
+ return EXIT_ALLOW10;
25651
25781
  }
25652
25782
  if (!hasStableSessionId(session_id)) {
25653
- return EXIT_ALLOW9;
25783
+ return EXIT_ALLOW10;
25654
25784
  }
25655
- return _withToolWriteLock(consumer_root, session_id, EXIT_ALLOW9, () => {
25656
- const previous = _loadState(path54.join(consumer_root, statePathFor2(session_id)));
25785
+ return _withToolWriteLock(consumer_root, session_id, EXIT_ALLOW10, () => {
25786
+ const previous = _loadState(path55.join(consumer_root, statePathFor2(session_id)));
25657
25787
  const language = previous.language;
25658
25788
  if (language !== "de" && language !== "en") {
25659
- return EXIT_ALLOW9;
25789
+ return EXIT_ALLOW10;
25660
25790
  }
25661
25791
  if (!_ownsPin(previous, session_id)) {
25662
- return EXIT_ALLOW9;
25792
+ return EXIT_ALLOW10;
25663
25793
  }
25664
25794
  const seen = typeof previous.tool_calls_since_pin === "number" && previous.tool_calls_since_pin >= 0 ? previous.tool_calls_since_pin : 0;
25665
25795
  const advanced = seen + 1;
@@ -25672,10 +25802,10 @@ function _reEmitAfterDistance(consumer_root, session_id, write_json = atomic_wri
25672
25802
  write_json
25673
25803
  );
25674
25804
  if (!due) {
25675
- return EXIT_ALLOW9;
25805
+ return EXIT_ALLOW10;
25676
25806
  }
25677
25807
  if (!written) {
25678
- return EXIT_ALLOW9;
25808
+ return EXIT_ALLOW10;
25679
25809
  }
25680
25810
  const source = previous.source === "system-locale" ? "system-locale" : "prompt";
25681
25811
  process.stdout.write(
@@ -25686,7 +25816,7 @@ function _reEmitAfterDistance(consumer_root, session_id, write_json = atomic_wri
25686
25816
  })}
25687
25817
  `
25688
25818
  );
25689
- return EXIT_WARN3;
25819
+ return EXIT_WARN4;
25690
25820
  });
25691
25821
  }
25692
25822
  function _onToolUse(consumer_root, session_id, write_json = atomic_write_json) {
@@ -25704,28 +25834,28 @@ function run9(stdin_text, options) {
25704
25834
  envelope = decoded;
25705
25835
  }
25706
25836
  } catch {
25707
- return EXIT_ALLOW9;
25837
+ return EXIT_ALLOW10;
25708
25838
  }
25709
25839
  }
25710
25840
  const payload = _isObject7(envelope["payload"]) ? envelope["payload"] : envelope;
25711
25841
  const event = typeof envelope["event"] === "string" ? envelope["event"] : "";
25712
25842
  if (event === "pre_compact") {
25713
25843
  _setPinLost(options.consumer_root, _sessionId(envelope));
25714
- return EXIT_ALLOW9;
25844
+ return EXIT_ALLOW10;
25715
25845
  }
25716
25846
  if (event === "post_tool_use") {
25717
25847
  return _onToolUse(options.consumer_root, _sessionId(envelope), options.write_json);
25718
25848
  }
25719
25849
  const prompt = _extractPrompt(payload);
25720
25850
  if (!prompt) {
25721
- return EXIT_ALLOW9;
25851
+ return EXIT_ALLOW10;
25722
25852
  }
25723
25853
  if (isSyntheticPrompt(prompt)) {
25724
- return EXIT_ALLOW9;
25854
+ return EXIT_ALLOW10;
25725
25855
  }
25726
25856
  const session_id = typeof envelope["session_id"] === "string" ? envelope["session_id"] : "";
25727
25857
  const stateful = hasStableSessionId(session_id);
25728
- const target = stateful ? path54.join(options.consumer_root, statePathFor2(session_id)) : "";
25858
+ const target = stateful ? path55.join(options.consumer_root, statePathFor2(session_id)) : "";
25729
25859
  const previous = stateful ? _loadState(target) : {};
25730
25860
  const classification = classify(prompt);
25731
25861
  const next = nextState(
@@ -25747,7 +25877,11 @@ function run9(stdin_text, options) {
25747
25877
  atomic_write_json(target, next);
25748
25878
  _pruneLegacyState(options.consumer_root);
25749
25879
  _pruneStaleSessions(options.consumer_root, Date.now());
25750
- } catch {
25880
+ } catch (err) {
25881
+ process.stderr.write(
25882
+ `language-mirror: pin-state write failed (${_errText(err)}) \u2014 the language pin did NOT persist and the next turn re-derives it. This turn's notice is unchanged.
25883
+ `
25884
+ );
25751
25885
  }
25752
25886
  }
25753
25887
  if (effective === "de" || effective === "en") {
@@ -25755,11 +25889,15 @@ function run9(stdin_text, options) {
25755
25889
  `${JSON.stringify({ decision: "warn", reason: noticeText(effective, effectiveSource), additional_context: pinText(effective, effectiveSource) })}
25756
25890
  `
25757
25891
  );
25758
- return EXIT_WARN3;
25892
+ return EXIT_WARN4;
25759
25893
  }
25760
- return EXIT_ALLOW9;
25894
+ return EXIT_ALLOW10;
25761
25895
  }
25762
- function main29(argv) {
25896
+ function _errText(err) {
25897
+ const t = err instanceof Error ? err.message : String(err);
25898
+ return t.replace(/\s+/g, " ").trim().slice(0, 200);
25899
+ }
25900
+ function main30(argv) {
25763
25901
  const args = argv ?? process.argv.slice(2);
25764
25902
  let consumer_root = process.cwd();
25765
25903
  for (let i = 0; i < args.length; i += 1) {
@@ -25780,26 +25918,26 @@ function _isCliEntry23() {
25780
25918
  if (process.argv[1] === void 0) {
25781
25919
  return false;
25782
25920
  }
25783
- const argvUrl = pathToFileURL25(path54.resolve(process.argv[1])).href;
25921
+ const argvUrl = pathToFileURL26(path55.resolve(process.argv[1])).href;
25784
25922
  if (import.meta.url === argvUrl) {
25785
25923
  return true;
25786
25924
  }
25787
25925
  try {
25788
- const here = fs54.realpathSync(fileURLToPath32(import.meta.url));
25789
- const argv = fs54.realpathSync(path54.resolve(process.argv[1]));
25926
+ const here = fs55.realpathSync(fileURLToPath33(import.meta.url));
25927
+ const argv = fs55.realpathSync(path55.resolve(process.argv[1]));
25790
25928
  return here === argv;
25791
25929
  } catch {
25792
25930
  return false;
25793
25931
  }
25794
25932
  }
25795
25933
  if (_isCliEntry23()) {
25796
- process.exit(main29());
25934
+ process.exit(main30());
25797
25935
  }
25798
25936
 
25799
25937
  // src/scripts/git_authorization_hook.ts
25800
- import fs55 from "node:fs";
25801
- import path55 from "node:path";
25802
- import { fileURLToPath as fileURLToPath33, pathToFileURL as pathToFileURL26 } from "node:url";
25938
+ import fs56 from "node:fs";
25939
+ import path56 from "node:path";
25940
+ import { fileURLToPath as fileURLToPath34, pathToFileURL as pathToFileURL27 } from "node:url";
25803
25941
 
25804
25942
  // src/scripts/_lib/machine_wake.ts
25805
25943
  var MACHINE_WAKE_PREFIXES = [
@@ -25817,10 +25955,10 @@ function humanTypedThisTurn(prompt) {
25817
25955
  }
25818
25956
 
25819
25957
  // src/scripts/git_authorization_hook.ts
25820
- var EXIT_ALLOW10 = 0;
25821
- var STATE_FILE7 = path55.join("agents", "state", "git-authorization.json");
25822
- var STATE_DIR5 = path55.join("agents", "state", "git-authorization");
25823
- var PENDING_DIR = path55.join("agents", "state", "git-authorization-pending");
25958
+ var EXIT_ALLOW11 = 0;
25959
+ var STATE_FILE7 = path56.join("agents", "state", "git-authorization.json");
25960
+ var STATE_DIR5 = path56.join("agents", "state", "git-authorization");
25961
+ var PENDING_DIR = path56.join("agents", "state", "git-authorization-pending");
25824
25962
  function sessionSlug(session_id) {
25825
25963
  return session_id.replace(/[^A-Za-z0-9._-]/gu, "_").slice(0, 80);
25826
25964
  }
@@ -25828,15 +25966,15 @@ function ledgerFileFor(session_id) {
25828
25966
  if (!session_id) {
25829
25967
  return STATE_FILE7;
25830
25968
  }
25831
- return path55.join(STATE_DIR5, `${sessionSlug(session_id)}.json`);
25969
+ return path56.join(STATE_DIR5, `${sessionSlug(session_id)}.json`);
25832
25970
  }
25833
25971
  function pendingFileFor(session_id) {
25834
25972
  if (!session_id) {
25835
25973
  return PENDING_FILE;
25836
25974
  }
25837
- return path55.join(PENDING_DIR, `${sessionSlug(session_id)}.json`);
25975
+ return path56.join(PENDING_DIR, `${sessionSlug(session_id)}.json`);
25838
25976
  }
25839
- var PENDING_FILE = path55.join("agents", "state", "git-authorization-pending.json");
25977
+ var PENDING_FILE = path56.join("agents", "state", "git-authorization-pending.json");
25840
25978
  var PENDING_MAX_AGE_MS = 10 * 60 * 1e3;
25841
25979
  function _isObject8(v) {
25842
25980
  return typeof v === "object" && v !== null && !Array.isArray(v);
@@ -26089,7 +26227,7 @@ function splitFences(prompt) {
26089
26227
  function _commandLines(fence) {
26090
26228
  return fence.split("\n").map((l) => l.trim()).filter((l) => l.length > 0).filter((l) => !/^(remote:|error:|hint:|fatal:|warning:|To |!\s|\s*\^)/i.test(l)).map((l) => l.replace(/^[$>#]\s*/, "")).filter((l) => /^(git|gh|npm|pnpm|yarn|task)\b/.test(l));
26091
26229
  }
26092
- function _errText(err) {
26230
+ function _errText2(err) {
26093
26231
  const t = err instanceof Error ? err.message : String(err);
26094
26232
  return t.replace(/\s+/g, " ").trim().slice(0, 200);
26095
26233
  }
@@ -26106,9 +26244,20 @@ function extractMergeTargets(prompt) {
26106
26244
  }
26107
26245
  return [...out].sort((a, b) => a - b);
26108
26246
  }
26109
- var REVOKE_RE = /\b(stop|stopp|halt|abbrechen|abbruch|cancel|revoke|widerruf(en)?|zur(ü|ue)ck(nehmen|ziehen)|hold\s+(everything|on|the\s+merge)|warte|wait)\b|(?:\b(nicht|kein(e|en)?|no|not|dont|don't|never|niemals|nie)\b[^.!?\n]{0,30}\b(merg(e|en|ing)|zusammenf(ü|ue)hren)\b)/iu;
26247
+ var REVOKE_STOP_WORD = /\b(stop|stopp|halt|abbrechen|abbruch|cancel|revoke|widerruf(en)?|zur(ü|ue)ck(nehmen|ziehen)|hold\s+(everything|on|the\s+merge)|warte|wait)\b/iu;
26248
+ var MERGE_VERB = /\b(merg(e|en|ing)|zusammenf(ü|ue)hren)\b/giu;
26110
26249
  function isRevocation(prompt) {
26111
- return REVOKE_RE.test(prompt);
26250
+ if (REVOKE_STOP_WORD.test(prompt) || isBareRefusal(prompt)) {
26251
+ return true;
26252
+ }
26253
+ MERGE_VERB.lastIndex = 0;
26254
+ let m;
26255
+ while ((m = MERGE_VERB.exec(prompt)) !== null) {
26256
+ if (negatedBefore(prompt, m.index, m[0])) {
26257
+ return true;
26258
+ }
26259
+ }
26260
+ return false;
26112
26261
  }
26113
26262
  function _grantId(session_id, at, targets) {
26114
26263
  return `${sessionSlug(session_id) || "nosession"}:${at}:${targets.join(",")}`;
@@ -26143,8 +26292,12 @@ function foldGrants(prior, prompt, authorized, session_id, now) {
26143
26292
  }
26144
26293
  ];
26145
26294
  }
26146
- var NEGATION_WORD = /\b(nicht|nichts|kein(e|en|em|er|es)?|niemals|nie|no|not|dont|don't|never|without|ohne)\b/i;
26147
- var CONTRAST_CUE = /\b(aber|sondern|jedoch|but|however|instead)\b/gi;
26295
+ var APOSTROPHE = "'\u2019\u2018\u02BC";
26296
+ var NEGATION_ALTERNATION = `nicht|nichts|kein(?:e|en|em|er|es)?|niemals|nie|no|not|don[${APOSTROPHE}]?t|never|without|ohne`;
26297
+ var NEGATION_WORD = new RegExp(`\\b(${NEGATION_ALTERNATION})\\b`, "i");
26298
+ var NEGATION_TOKEN = new RegExp(`^(?:${NEGATION_ALTERNATION})$`, "i");
26299
+ var CONTRAST_ALTERNATION = "aber|sondern|jedoch|but|however|instead";
26300
+ var CONTRAST_CUE = new RegExp(`\\b(${CONTRAST_ALTERNATION})\\b`, "gi");
26148
26301
  var ABBREVIATION_BEFORE_DOT = /(?:^|[\s("'\u2018\u201c])(?:[a-z]|z\.b|bzw|ca|usw|d\.h|u\.a|evtl|ggf|inkl|max|min|nr|abb|e\.g|i\.e|etc|vs|approx|fig|no|st|dr|prof)\.$/i;
26149
26302
  function isSentenceBoundary(text, at) {
26150
26303
  const mark = text[at];
@@ -26231,6 +26384,19 @@ function negatedBefore(text, index, matched = "") {
26231
26384
  const after = afterFrom < end ? text.slice(afterFrom, clauseEnd(text, afterFrom, end)) : "";
26232
26385
  return NEGATION_WORD.test(before) || NEGATION_WORD.test(matched) || NEGATION_WORD.test(after);
26233
26386
  }
26387
+ var WORD_TOKEN = new RegExp(`[\\p{L}\\p{N}${APOSTROPHE}]+`, "gu");
26388
+ var CLAUSE_SPLIT = new RegExp(`[,;:]|\\b(?:${CONTRAST_ALTERNATION})\\b`, "iu");
26389
+ function isBareRefusal(text) {
26390
+ for (const sentence of _sentences(text)) {
26391
+ for (const clause of sentence.split(CLAUSE_SPLIT)) {
26392
+ const tokens = (clause ?? "").match(WORD_TOKEN) ?? [];
26393
+ if (tokens.length > 0 && tokens.every((t) => NEGATION_TOKEN.test(t))) {
26394
+ return true;
26395
+ }
26396
+ }
26397
+ }
26398
+ return false;
26399
+ }
26234
26400
  function classifyAuthorization(prompt) {
26235
26401
  const { prose, fences } = splitFences(prompt);
26236
26402
  const authorized = /* @__PURE__ */ new Set();
@@ -26268,7 +26434,7 @@ function classifyAuthorization(prompt) {
26268
26434
  }
26269
26435
  function readGrants(consumer_root, session_id) {
26270
26436
  try {
26271
- const raw = fs55.readFileSync(path55.join(consumer_root, ledgerFileFor(session_id)), "utf8");
26437
+ const raw = fs56.readFileSync(path56.join(consumer_root, ledgerFileFor(session_id)), "utf8");
26272
26438
  const decoded = JSON.parse(raw);
26273
26439
  if (!_isObject8(decoded) || !Array.isArray(decoded["grants"])) {
26274
26440
  return [];
@@ -26298,50 +26464,16 @@ function readGrants(consumer_root, session_id) {
26298
26464
  return [];
26299
26465
  }
26300
26466
  }
26301
- function consumeGrantTarget(consumer_root, session_id, target) {
26302
- const file = path55.join(consumer_root, ledgerFileFor(session_id));
26303
- let decoded;
26304
- try {
26305
- decoded = JSON.parse(fs55.readFileSync(file, "utf8"));
26306
- } catch {
26307
- return;
26308
- }
26309
- if (!_isObject8(decoded) || !Array.isArray(decoded["grants"])) {
26310
- return;
26311
- }
26312
- let touched = false;
26313
- for (const g of decoded["grants"]) {
26314
- if (!_isObject8(g) || !Array.isArray(g["targets"]) || !Array.isArray(g["consumed"])) {
26315
- continue;
26316
- }
26317
- const targets = g["targets"];
26318
- const consumed = g["consumed"];
26319
- if (targets.includes(target) && !consumed.includes(target)) {
26320
- consumed.push(target);
26321
- touched = true;
26322
- }
26323
- }
26324
- if (touched) {
26325
- try {
26326
- atomic_write_json(file, decoded);
26327
- } catch (err) {
26328
- process.stderr.write(
26329
- `git-authorization: grant-consumption write failed (${_errText(err)}) \u2014 the target stays UNSPENT, so one further merge of a PR the user named will still be authorized. Authorization outcome unchanged.
26330
- `
26331
- );
26332
- }
26333
- }
26334
- }
26335
26467
  function takePending(consumer_root, session_id, now) {
26336
- const file = path55.join(consumer_root, pendingFileFor(session_id));
26468
+ const file = path56.join(consumer_root, pendingFileFor(session_id));
26337
26469
  let raw;
26338
26470
  try {
26339
- raw = fs55.readFileSync(file, "utf8");
26471
+ raw = fs56.readFileSync(file, "utf8");
26340
26472
  } catch {
26341
26473
  return null;
26342
26474
  }
26343
26475
  try {
26344
- fs55.rmSync(file, { force: true });
26476
+ fs56.rmSync(file, { force: true });
26345
26477
  } catch {
26346
26478
  }
26347
26479
  try {
@@ -26351,731 +26483,83 @@ function takePending(consumer_root, session_id, now) {
26351
26483
  }
26352
26484
  const op = decoded["op"];
26353
26485
  if (typeof op !== "string" || !ALL_OPS.includes(op)) {
26354
- return null;
26355
- }
26356
- const recorded = typeof decoded["session_id"] === "string" ? decoded["session_id"] : "";
26357
- if (session_id && recorded && recorded !== session_id) {
26358
- return null;
26359
- }
26360
- const at = Date.parse(String(decoded["refused_at"] ?? ""));
26361
- if (!Number.isFinite(at) || now - at > PENDING_MAX_AGE_MS) {
26362
- return null;
26363
- }
26364
- return { op, session_id: recorded, refused_at: String(decoded["refused_at"]) };
26365
- } catch {
26366
- return null;
26367
- }
26368
- }
26369
- function run10(stdin_text, options) {
26370
- let envelope = {};
26371
- if (stdin_text.trim()) {
26372
- try {
26373
- const decoded = JSON.parse(stdin_text);
26374
- if (_isObject8(decoded)) {
26375
- envelope = decoded;
26376
- }
26377
- } catch {
26378
- return EXIT_ALLOW10;
26379
- }
26380
- }
26381
- const payload = _isObject8(envelope["payload"]) ? envelope["payload"] : envelope;
26382
- let prompt = "";
26383
- for (const key of ["prompt", "userPrompt", "user_prompt", "message", "text"]) {
26384
- const v = payload[key];
26385
- if (typeof v === "string" && v.trim()) {
26386
- prompt = v;
26387
- break;
26388
- }
26389
- }
26390
- if (!prompt) {
26391
- return EXIT_ALLOW10;
26392
- }
26393
- const session = typeof envelope["session_id"] === "string" ? envelope["session_id"] : "";
26394
- if (!humanTypedThisTurn(prompt)) {
26395
- return EXIT_ALLOW10;
26396
- }
26397
- const { authorized, evidence } = classifyAuthorization(prompt);
26398
- const pending = takePending(options.consumer_root, session, Date.now());
26399
- if (pending && !authorized.includes(pending.op) && isAffirmative(prompt)) {
26400
- authorized.push(pending.op);
26401
- evidence[pending.op] = `confirmation of the refused \`${pending.op}\` (refused ${pending.refused_at}): "${prompt.trim().slice(0, 40)}"`;
26402
- }
26403
- const now = /* @__PURE__ */ new Date();
26404
- const ledger = {
26405
- session_id: typeof envelope["session_id"] === "string" ? envelope["session_id"] : "",
26406
- detected_at: now.toISOString(),
26407
- authorized,
26408
- evidence,
26409
- prompt_chars: prompt.length,
26410
- // Grants survive this write; `authorized` does not. That asymmetry IS the
26411
- // decision. A bare operation name stays one-shot exactly as `commit-policy`
26412
- // requires, and only an authorization that also froze its objects earns a
26413
- // life longer than the turn. See ADR-252.
26414
- grants: foldGrants(
26415
- readGrants(options.consumer_root, session),
26416
- prompt,
26417
- authorized,
26418
- session,
26419
- now
26420
- )
26421
- };
26422
- try {
26423
- atomic_write_json(path55.join(options.consumer_root, ledgerFileFor(session)), ledger);
26424
- } catch (err) {
26425
- process.stderr.write(
26426
- `git-authorization: session-ledger write failed (${_errText(err)}) \u2014 the gate degrades to "no ledger" for this session, which denies the irreversible subset and warns on the rest. Authorization outcome unchanged.
26427
- `
26428
- );
26429
- }
26430
- return EXIT_ALLOW10;
26431
- }
26432
- function main30(argv) {
26433
- const args = argv ?? process.argv.slice(2);
26434
- let consumer_root = process.cwd();
26435
- for (let i = 0; i < args.length; i += 1) {
26436
- const a = args[i];
26437
- if (a === "--project-dir" && args[i + 1] !== void 0) {
26438
- consumer_root = args[i + 1];
26439
- i += 1;
26440
- } else if (a !== void 0 && a.startsWith("--project-dir=")) {
26441
- consumer_root = a.slice("--project-dir=".length);
26442
- }
26443
- }
26444
- return run10(readHookStdin(), { consumer_root });
26445
- }
26446
- function _isCliEntry24() {
26447
- if (true) {
26448
- return false;
26449
- }
26450
- if (process.argv[1] === void 0) {
26451
- return false;
26452
- }
26453
- const argvUrl = pathToFileURL26(path55.resolve(process.argv[1])).href;
26454
- if (import.meta.url === argvUrl) {
26455
- return true;
26456
- }
26457
- try {
26458
- const here = fs55.realpathSync(fileURLToPath33(import.meta.url));
26459
- const argv = fs55.realpathSync(path55.resolve(process.argv[1]));
26460
- return here === argv;
26461
- } catch {
26462
- return false;
26463
- }
26464
- }
26465
- if (_isCliEntry24()) {
26466
- process.exit(main30());
26467
- }
26468
-
26469
- // src/scripts/hooks/block_unauthorized_git.ts
26470
- import fs56 from "node:fs";
26471
- import path56 from "node:path";
26472
- import { fileURLToPath as fileURLToPath34, pathToFileURL as pathToFileURL27 } from "node:url";
26473
-
26474
- // src/scripts/hooks/merge_impact.ts
26475
- import { execFileSync as execFileSync3 } from "node:child_process";
26476
- var DESTRUCTIVE_MARKERS = [
26477
- // Schema removal. Matched on ADDED lines only — a migration that *removes* a
26478
- // dropColumn call is the opposite of destructive, and matching the raw patch
26479
- // would score it the same way.
26480
- { label: "migration drops a column or table", re: /^\+.*\b(dropColumn|dropTable|dropIfExists|removeColumn|drop_column|drop_table)\b/im },
26481
- { label: "raw DROP or TRUNCATE in a migration", re: /^\+.*\b(DROP\s+(TABLE|COLUMN|INDEX|CONSTRAINT)|TRUNCATE\s+TABLE)\b/im },
26482
- // The author said so themselves. Conventional Commits marks a breaking change
26483
- // with a `!` before the colon or a body trailer.
26484
- { label: "author marked a BREAKING CHANGE", re: /^\+.*BREAKING[ -]CHANGE/m },
26485
- // A removed export is the shape most likely to break an importer.
26486
- { label: "an exported symbol was removed", re: /^-\s*export\s+(default\s+|const\s+|function\s+|class\s+|interface\s+|type\s+|async\s+)/m },
26487
- { label: "a public PHP or Python symbol was removed", re: /^-\s*(public\s+function|def\s+[a-z_]+\s*\()/m },
26488
- // Route removal breaks callers that never imported anything.
26489
- { label: "a route or endpoint was removed", re: /^-.*\b(Route::(get|post|put|patch|delete)|@(Get|Post|Put|Patch|Delete)Mapping|app\.(get|post|put|patch|delete)\s*\()/m },
26490
- { label: "a whole file was deleted", re: /^deleted file mode /m }
26491
- ];
26492
- var SCHEMA_REMOVAL_BODY = /\b(dropColumn|dropTable|dropIfExists|removeColumn|drop_column|drop_table|DROP\s+(TABLE|COLUMN|INDEX|CONSTRAINT)|TRUNCATE\s+TABLE)\b/i;
26493
- var RENAME_METADATA = /^rename (?:from|to) /m;
26494
- function fileBlocks(patch) {
26495
- return patch.split(/^(?=diff --git )/m).filter((b) => b.startsWith("diff --git "));
26496
- }
26497
- function renamedSchemaRemoval(patch) {
26498
- for (const block of fileBlocks(patch)) {
26499
- if (!RENAME_METADATA.test(block)) {
26500
- continue;
26501
- }
26502
- for (const line of block.split("\n")) {
26503
- if (line.startsWith("-") && !line.startsWith("---") && SCHEMA_REMOVAL_BODY.test(line)) {
26504
- return true;
26505
- }
26506
- }
26507
- }
26508
- return false;
26509
- }
26510
- var MAJOR_BUMP = /^-\s*"version"\s*:\s*"(\d+)\.[^"]*"[\s\S]{0,200}?^\+\s*"version"\s*:\s*"(\d+)\./m;
26511
- function classifyDiff(patch) {
26512
- if (patch.trim() === "") {
26513
- return { verdict: "undecidable", markers: [], reason: "empty diff" };
26514
- }
26515
- const markers = [];
26516
- for (const { label, re } of DESTRUCTIVE_MARKERS) {
26517
- if (re.test(patch)) {
26518
- markers.push(label);
26519
- }
26520
- }
26521
- if (renamedSchemaRemoval(patch)) {
26522
- markers.push("a renamed file drops a column or table");
26523
- }
26524
- const bump = MAJOR_BUMP.exec(patch);
26525
- if (bump && bump[1] !== bump[2]) {
26526
- markers.push(`major version bump ${bump[1]}.x to ${bump[2]}.x`);
26527
- }
26528
- const filesChanged = (patch.match(/^diff --git /gm) ?? []).length;
26529
- if (markers.length > 0) {
26530
- return { verdict: "destructive", markers, filesChanged };
26531
- }
26532
- return { verdict: "additive", markers: [], filesChanged };
26533
- }
26534
- function fetchPatch(pr, opts = {}) {
26535
- const run13 = opts.exec ?? execFileSync3;
26536
- const cwd = opts.cwd ?? process.cwd();
26537
- const capture = (file, args) => run13(file, args, { cwd, encoding: "utf-8", stdio: ["ignore", "pipe", "ignore"], timeout: 15e3 });
26538
- for (const ref of [`refs/pull/${pr}/head`, `pull/${pr}/head`]) {
26539
- try {
26540
- const base = capture("git", ["merge-base", "HEAD", ref]).trim();
26541
- if (base) {
26542
- const patch = capture("git", ["diff", `${base}...${ref}`]);
26543
- if (patch.trim() !== "") {
26544
- return { patch, source: "local" };
26545
- }
26546
- }
26547
- } catch {
26548
- }
26549
- }
26550
- if (opts.allowNetwork === false) {
26551
- return { patch: "", source: "none", reason: "no local ref and network reads disabled" };
26552
- }
26553
- try {
26554
- const patch = capture("gh", ["pr", "diff", String(pr), "--patch"]);
26555
- if (patch.trim() !== "") {
26556
- return { patch, source: "gh" };
26557
- }
26558
- return { patch: "", source: "none", reason: "gh returned an empty diff" };
26559
- } catch {
26560
- return { patch: "", source: "none", reason: "no local ref, and gh pr diff failed" };
26561
- }
26562
- }
26563
- function analyseMergeImpact(pr, opts = {}) {
26564
- const got = fetchPatch(pr, opts);
26565
- if (got.source === "none") {
26566
- return { verdict: "undecidable", markers: [], ...got.reason ? { reason: got.reason } : {} };
26567
- }
26568
- return classifyDiff(got.patch);
26569
- }
26570
- function describeImpact(pr, impact) {
26571
- const say = `Say "merge #${pr}" to authorize it.`;
26572
- switch (impact.verdict) {
26573
- case "additive":
26574
- return `Impact scan: PR #${pr} touches ${impact.filesChanged ?? 0} file(s) and trips no destructive marker \u2014 no schema drop, no removed export or route, no major bump, no BREAKING CHANGE. Additive as far as the diff can show, which is not the same as safe to merge: the base has moved since review and merging may trigger a deploy. ${say}`;
26575
- case "destructive":
26576
- return `Impact scan: PR #${pr} is NOT additive \u2014 ${impact.markers.join("; ")}. Read the diff before authorizing. ${say}`;
26577
- default:
26578
- return `Impact scan: could not read the diff for PR #${pr} (${impact.reason ?? "unknown"}), so nothing is known about what it changes. ${say}`;
26579
- }
26580
- }
26581
-
26582
- // src/scripts/hooks/block_unauthorized_git.ts
26583
- var EXIT_ALLOW11 = 0;
26584
- var EXIT_BLOCK = 1;
26585
- function _isObject9(v) {
26586
- return typeof v === "object" && v !== null && !Array.isArray(v);
26587
- }
26588
- var BLOCK_OPS = /* @__PURE__ */ new Set([
26589
- "publish",
26590
- "tag",
26591
- "release",
26592
- "pr-merge",
26593
- // Enabling auto-merge commits the outcome to a condition the agent does not
26594
- // control, so it is blocked on the same terms as the merge it schedules.
26595
- "pr-merge-auto",
26596
- // ── Added 2026-09-03. Every one is already never-autonomous in the
26597
- // `non-destructive-by-default` prose; the measurement that drove it is in the
26598
- // `GitOp` union's own note — 17 of 25 borderline operations classified as
26599
- // NOTHING, including three worse than anything the guard already caught.
26600
- /** The undo that is more destructive than the act: lockfiles break. */
26601
- "unpublish",
26602
- /** Metadata only, and every install on earth starts warning. */
26603
- "deprecate",
26604
- /** Replaces bytes consumers already hold a checksum for. */
26605
- "release-asset",
26606
- /** Deletes the guard rather than the data — everything after is unguarded. */
26607
- "protection",
26608
- /** No data lost; the gate that protects everything downstream is off. */
26609
- "workflow-toggle",
26610
- /** Reach outside the repository, and mostly one-way. */
26611
- "repo-lifecycle",
26612
- /** No code moves, and an armed auto-merge is released. */
26613
- "review-approve",
26614
- /** Discards commits that landed after the last fetch, on a shared ref. */
26615
- "force-push",
26616
- /** Destroys uncommitted work belonging to a session this one cannot see. */
26617
- "worktree-remove",
26618
- /** `-x` is the flag that takes `.env` and local certificates. */
26619
- "clean-ignored"
26620
- ]);
26621
- var WARN_OPS = /* @__PURE__ */ new Set([
26622
- "commit",
26623
- "push",
26624
- "pr-create",
26625
- "branch",
26626
- // ── Added 2026-09-03, deliberately at warn rather than block.
26627
- //
26628
- // Each is destructive in some reading, and each is also routine enough that
26629
- // blocking it would be the friction that gets the whole guard routed around —
26630
- // the failure mode this estate has already recorded twice. `reset-hard` is the
26631
- // sharpest case and stays here for a decidable reason: the Hard Floor's
26632
- // qualifier is "past unpushed work", and the command text cannot say whether
26633
- // the work was pushed.
26634
- "tag-force",
26635
- "rebase",
26636
- "reset-hard",
26637
- "clean",
26638
- "stash-drop",
26639
- "branch-delete",
26640
- "close"
26641
- ]);
26642
- var G = "(?:-[A-Za-z-]+(?:=\\S+)?(?:\\s+\\S+)?\\s+)*";
26643
- var P = "^(?:\\S*\\/)?";
26644
- function ghApiWrite(pathRe) {
26645
- return new RegExp(
26646
- `${P}gh\\s+api\\b(?=[^\\n]*${pathRe})(?=[^\\n]*(?:-X|--method)\\s+(?:POST|PATCH|PUT|DELETE)\\b)`,
26647
- "i"
26648
- );
26649
- }
26650
- var COMMAND_OPS = [
26651
- { op: "publish", re: new RegExp(`${P}(npm|pnpm|yarn)\\s+${G}publish\\b`, "i") },
26652
- {
26653
- op: "release",
26654
- re: new RegExp(`${P}gh\\s+release\\s+create\\b|${ghApiWrite("\\/releases\\b").source}`, "i")
26655
- },
26656
- {
26657
- op: "tag",
26658
- re: new RegExp(`${P}git\\s+${G}push\\b[^\\n;|&]*(--tags|--follow-tags|refs\\/tags\\/)`, "i")
26659
- },
26660
- // ORDER IS LOAD-BEARING, per this table's own rule that the most specific
26661
- // pattern wins: `gh pr merge 12 --auto` matches the plain merge pattern too.
26662
- //
26663
- // The GraphQL mutation needs its OWN pattern rather than a widening of
26664
- // `ghApiWrite()`. That helper requires BOTH a REST-shaped path and an
26665
- // explicit write method, and `gh api graphql -f query='mutation{...}'` has
26666
- // neither — widening it to reach this would loosen every other op that uses
26667
- // it, which is a bigger change than the defect.
26668
- {
26669
- op: "pr-merge-auto",
26670
- re: new RegExp(
26671
- `${P}gh\\s+pr\\s+merge\\b(?=[^\\n]*--auto\\b)|${P}gh\\s+api\\b(?=[^\\n]*enablePullRequestAutoMerge\\b)`,
26672
- "i"
26673
- )
26674
- },
26675
- {
26676
- op: "pr-merge",
26677
- re: new RegExp(
26678
- `${P}gh\\s+pr\\s+merge\\b(?![^\\n]*--(auto|disable-auto)\\b)|${ghApiWrite("\\/pulls\\/\\d+\\/merge\\b").source}`,
26679
- "i"
26680
- )
26681
- },
26682
- {
26683
- op: "pr-create",
26684
- re: new RegExp(`${P}gh\\s+pr\\s+create\\b|${ghApiWrite("\\/pulls\\b").source}`, "i")
26685
- },
26686
- // ── Added 2026-09-03. Placement inside this table is as load-bearing as the
26687
- // patterns: the loop takes the MOST SEVERE match per segment, but within one
26688
- // op the first pattern wins, so anything more specific than a plain `git push`
26689
- // has to sit above it.
26690
- // `npm unpublish` is NOT reached by the publish pattern — `\bpublish\b` needs
26691
- // a word boundary that `unpublish` does not provide between `n` and `p`. That
26692
- // is why it classified as nothing for as long as it did.
26693
- { op: "unpublish", re: new RegExp(`${P}(npm|pnpm|yarn)\\s+${G}unpublish\\b`, "i") },
26694
- { op: "deprecate", re: new RegExp(`${P}(npm|pnpm|yarn)\\s+${G}deprecate\\b`, "i") },
26695
- {
26696
- op: "release-asset",
26697
- re: new RegExp(`${P}gh\\s+release\\s+(upload|edit|delete)\\b`, "i")
26698
- },
26699
- {
26700
- op: "protection",
26701
- re: new RegExp(
26702
- `${P}gh\\s+api\\b(?=[^\\n]*(?:protection|rulesets?)\\b)(?=[^\\n]*(?:-X|--method)\\s+(?:DELETE|PUT|PATCH|POST)\\b)|${P}gh\\s+ruleset\\s+delete\\b`,
26703
- "i"
26704
- )
26705
- },
26706
- {
26707
- op: "workflow-toggle",
26708
- re: new RegExp(`${P}gh\\s+workflow\\s+(disable|enable)\\b`, "i")
26709
- },
26710
- {
26711
- op: "repo-lifecycle",
26712
- re: new RegExp(
26713
- `${P}gh\\s+repo\\s+(archive|delete|unarchive)\\b|${P}gh\\s+repo\\s+edit\\b(?=[^\\n]*--visibility\\b)`,
26714
- "i"
26715
- )
26716
- },
26717
- {
26718
- op: "review-approve",
26719
- re: new RegExp(`${P}gh\\s+pr\\s+review\\b(?=[^\\n]*--approve\\b)`, "i")
26720
- },
26721
- // Above `push`, and both spellings: `--force` and `--force-with-lease`. The
26722
- // "safe force" is in the same class here because what it is safe against is a
26723
- // stale local view, not a collaborator who pushed after your fetch.
26724
- {
26725
- op: "force-push",
26726
- re: new RegExp(`${P}git\\s+${G}push\\b[^\\n;|&]*(--force\\b|--force-with-lease\\b|\\s-f\\b)`, "i")
26727
- },
26728
- {
26729
- op: "worktree-remove",
26730
- re: new RegExp(`${P}git\\s+worktree\\s+remove\\b[^\\n;|&]*(--force\\b|\\s-f\\b)`, "i")
26731
- },
26732
- // `-x` (or `-X`) anywhere in the flag cluster is what reaches ignored files.
26733
- {
26734
- op: "clean-ignored",
26735
- re: new RegExp(`${P}git\\s+clean\\b[^\\n;|&]*-[A-Za-z]*x`, "i")
26736
- },
26737
- { op: "tag-force", re: new RegExp(`${P}git\\s+tag\\b[^\\n;|&]*(-f\\b|--force\\b)`, "i") },
26738
- { op: "rebase", re: new RegExp(`${P}git\\s+${G}rebase\\b`, "i") },
26739
- { op: "reset-hard", re: new RegExp(`${P}git\\s+${G}reset\\b[^\\n;|&]*--hard\\b`, "i") },
26740
- { op: "clean", re: new RegExp(`${P}git\\s+clean\\b`, "i") },
26741
- { op: "stash-drop", re: new RegExp(`${P}git\\s+stash\\s+(drop|clear)\\b`, "i") },
26742
- // Remote deletion and the local `-D` are one op: both remove a ref, and the
26743
- // remote form additionally closes any open PR pointing at it.
26744
- {
26745
- op: "branch-delete",
26746
- re: new RegExp(
26747
- `${P}git\\s+branch\\b[^\\n;|&]*(-D\\b|--delete\\b)|${P}git\\s+${G}push\\b[^\\n;|&]*(--delete\\b|\\s:\\S)`,
26748
- "i"
26749
- )
26750
- },
26751
- { op: "close", re: new RegExp(`${P}gh\\s+(pr|issue)\\s+close\\b`, "i") },
26752
- { op: "push", re: new RegExp(`${P}git\\s+${G}push\\b`, "i") },
26753
- { op: "commit", re: new RegExp(`${P}git\\s+${G}commit\\b`, "i") },
26754
- { op: "branch", re: new RegExp(`${P}git\\s+${G}(checkout\\s+-b|switch\\s+-c)\\b`, "i") }
26755
- ];
26756
- var COMMAND_TOOLS4 = /* @__PURE__ */ new Set([
26757
- "launch-process",
26758
- "launch_process",
26759
- "Bash",
26760
- "BashTool",
26761
- "run-process",
26762
- "runProcess",
26763
- "shell",
26764
- "execute_shell",
26765
- "RunShellCommand"
26766
- ]);
26767
- function extractCommand(envelope) {
26768
- const payload = _isObject9(envelope["payload"]) ? envelope["payload"] : envelope;
26769
- const toolRaw = payload["tool_name"] ?? payload["toolName"] ?? payload["tool"];
26770
- const tool = typeof toolRaw === "string" ? toolRaw : null;
26771
- if (tool !== null && !COMMAND_TOOLS4.has(tool)) {
26772
- return null;
26773
- }
26774
- const input = _isObject9(payload["tool_input"]) ? payload["tool_input"] : _isObject9(payload["toolInput"]) ? payload["toolInput"] : payload;
26775
- for (const key of ["command", "cmd", "script"]) {
26776
- const v = input[key];
26777
- if (typeof v === "string" && v.trim()) {
26778
- return v;
26779
- }
26780
- }
26781
- return null;
26782
- }
26783
- function splitOutsideQuotes(command) {
26784
- const parts = [];
26785
- let cur = "";
26786
- let quote = null;
26787
- for (let i = 0; i < command.length; i += 1) {
26788
- const ch = command[i];
26789
- if (quote !== null) {
26790
- if (quote === "$'" && ch === "\\" && i + 1 < command.length) {
26791
- cur += ch + command[i + 1];
26792
- i += 1;
26793
- continue;
26794
- }
26795
- cur += ch;
26796
- if (ch === (quote === "$'" ? "'" : quote)) {
26797
- quote = null;
26798
- } else if (ch === "\\" && quote === '"' && i + 1 < command.length) {
26799
- cur += command[i + 1];
26800
- i += 1;
26801
- }
26802
- continue;
26803
- }
26804
- if (ch === "$" && (command[i + 1] === "'" || command[i + 1] === '"')) {
26805
- quote = command[i + 1] === "'" ? "$'" : '"';
26806
- cur += ch + command[i + 1];
26807
- i += 1;
26808
- continue;
26809
- }
26810
- if (ch === '"' || ch === "'") {
26811
- quote = ch;
26812
- cur += ch;
26813
- continue;
26814
- }
26815
- if (ch === "\\" && i + 1 < command.length) {
26816
- cur += ch + command[i + 1];
26817
- i += 1;
26818
- continue;
26819
- }
26820
- if (ch === "\n" || ch === ";" || ch === "|" || ch === "&") {
26821
- if ((ch === "|" || ch === "&") && command[i + 1] === ch) {
26822
- i += 1;
26823
- }
26824
- parts.push(cur);
26825
- cur = "";
26826
- continue;
26827
- }
26828
- cur += ch;
26829
- }
26830
- if (quote !== null) {
26831
- parts.push(...splitIgnoringQuotes(cur));
26832
- return parts;
26833
- }
26834
- parts.push(cur);
26835
- return parts;
26836
- }
26837
- function splitIgnoringQuotes(fragment) {
26838
- const parts = [];
26839
- let cur = "";
26840
- for (let i = 0; i < fragment.length; i += 1) {
26841
- const ch = fragment[i];
26842
- if (ch === "\\" && i + 1 < fragment.length) {
26843
- cur += ch + fragment[i + 1];
26844
- i += 1;
26845
- continue;
26846
- }
26847
- if (ch === "\n" || ch === ";" || ch === "|" || ch === "&") {
26848
- if ((ch === "|" || ch === "&") && fragment[i + 1] === ch) {
26849
- i += 1;
26850
- }
26851
- parts.push(cur);
26852
- cur = "";
26853
- continue;
26854
- }
26855
- cur += ch;
26856
- }
26857
- parts.push(cur);
26858
- return parts;
26859
- }
26860
- function substitutionPayloads(segment) {
26861
- const out = [];
26862
- for (let i = 0; i < segment.length; i += 1) {
26863
- const ch = segment[i];
26864
- if (ch === "\\") {
26865
- i += 1;
26866
- continue;
26867
- }
26868
- if ((ch === "$" || ch === "<" || ch === ">") && segment[i + 1] === "(") {
26869
- let open = 1;
26870
- let j = i + 2;
26871
- const start = j;
26872
- for (; j < segment.length && open > 0; j += 1) {
26873
- const c = segment[j];
26874
- if (c === "\\") {
26875
- j += 1;
26876
- } else if (c === "(") {
26877
- open += 1;
26878
- } else if (c === ")") {
26879
- open -= 1;
26880
- }
26881
- }
26882
- out.push(segment.slice(start, open === 0 ? j - 1 : segment.length));
26883
- i = j - 1;
26884
- continue;
26885
- }
26886
- if (ch === "`") {
26887
- const end = segment.indexOf("`", i + 1);
26888
- out.push(segment.slice(i + 1, end === -1 ? segment.length : end));
26889
- i = end === -1 ? segment.length : end;
26890
- }
26891
- }
26892
- return out;
26893
- }
26894
- function invokedSegments(command, depth = 0) {
26895
- if (depth > 3) {
26896
- return [];
26897
- }
26898
- const out = [];
26899
- const withoutHeredocs = command.replace(
26900
- /<<-?\s*(['"]?)([A-Za-z_][A-Za-z0-9_]*)\1[\s\S]*?^\s*\2\s*$/gm,
26901
- "<<HEREDOC"
26902
- );
26903
- for (const raw of splitOutsideQuotes(withoutHeredocs)) {
26904
- let seg = raw.trim();
26905
- if (!seg) {
26906
- continue;
26907
- }
26908
- seg = seg.replace(/^(?:[A-Za-z_][A-Za-z0-9_]*=(?:"[^"]*"|'[^']*'|\S*)\s+)+/, "");
26909
- for (const payload of substitutionPayloads(seg)) {
26910
- out.push(...invokedSegments(payload, depth + 1));
26911
- }
26912
- const wrapped = /^(?:\S*\/)?(?:ba|z|k)?sh\s+-[a-z]*c\s+(?:"([^"]*)"|'([^']*)'|(\S+))/.exec(seg);
26913
- if (wrapped) {
26914
- out.push(...invokedSegments(wrapped[1] ?? wrapped[2] ?? wrapped[3] ?? "", depth + 1));
26915
- continue;
26916
- }
26917
- const evaled = /^eval\s+(?:"([^"]*)"|'([^']*)'|(.+))$/.exec(seg);
26918
- if (evaled) {
26919
- out.push(...invokedSegments(evaled[1] ?? evaled[2] ?? evaled[3] ?? "", depth + 1));
26920
- continue;
26921
- }
26922
- out.push(seg.replace(/^(\S+)/, (w) => w.replace(/['"]/g, "")));
26923
- }
26924
- return out;
26925
- }
26926
- function commandOp(command) {
26927
- let found = null;
26928
- for (const seg of invokedSegments(command)) {
26929
- if (!/^(?:\S*\/)?(git|gh|npm|pnpm|yarn)\b/.test(seg)) {
26930
- continue;
26931
- }
26932
- for (const { op, re } of COMMAND_OPS) {
26933
- if (re.test(seg)) {
26934
- if (BLOCK_OPS.has(op)) {
26935
- return op;
26936
- }
26937
- found ??= op;
26938
- break;
26939
- }
26940
- }
26941
- }
26942
- return found;
26943
- }
26944
- function mergeTargetOf(command) {
26945
- const gh = /\bgh\s+pr\s+merge\s+(?:-{1,2}\S+\s+)*?(\d{1,10})\b/i.exec(command);
26946
- if (gh) {
26947
- return _boundedTarget(gh[1]);
26948
- }
26949
- const api = /\/pulls\/(\d{1,10})\/merge\b/i.exec(command);
26950
- return api ? _boundedTarget(api[1]) : null;
26951
- }
26952
- function _boundedTarget(digits) {
26953
- const n = Number.parseInt(digits, 10);
26954
- return Number.isSafeInteger(n) && n > 0 && n <= PR_NUMBER_MAX ? n : null;
26955
- }
26956
- function grantCovers(grants, op, target) {
26957
- if (op !== "pr-merge" || target === null) {
26958
- return null;
26959
- }
26960
- return grants.find(
26961
- (g) => g.op === "pr-merge" && g.targets.includes(target) && !g.consumed.includes(target)
26962
- ) ?? null;
26963
- }
26964
- var LEDGER_MAX_AGE_MS = 30 * 60 * 1e3;
26965
- function _loadLedger(consumer_root, session_id, now) {
26966
- const grants = readGrants(consumer_root, session_id);
26967
- const candidates = [ledgerFileFor(session_id)];
26968
- if (!candidates.includes(STATE_FILE7)) {
26969
- candidates.push(STATE_FILE7);
26970
- }
26971
- for (const rel of candidates) {
26972
- const found = _readLedgerFile(path56.join(consumer_root, rel), session_id, now);
26973
- if (found !== null) {
26974
- return { ...found, grants };
26486
+ return null;
26975
26487
  }
26976
- }
26977
- return { authorized: /* @__PURE__ */ new Set(), present: false, grants };
26978
- }
26979
- function _readLedgerFile(file, session_id, now) {
26980
- try {
26981
- const raw = fs56.readFileSync(file, "utf8");
26982
- const decoded = JSON.parse(raw);
26983
- if (_isObject9(decoded) && Array.isArray(decoded["authorized"])) {
26984
- const ledgerSession = typeof decoded["session_id"] === "string" ? decoded["session_id"] : "";
26985
- if (session_id && ledgerSession && ledgerSession !== session_id) {
26986
- return null;
26987
- }
26988
- const at = Date.parse(String(decoded["detected_at"] ?? ""));
26989
- if (Number.isFinite(at) && now - at > LEDGER_MAX_AGE_MS) {
26990
- return null;
26991
- }
26992
- return {
26993
- authorized: new Set(decoded["authorized"].filter(Boolean)),
26994
- present: true
26995
- };
26488
+ const recorded = typeof decoded["session_id"] === "string" ? decoded["session_id"] : "";
26489
+ if (session_id && recorded && recorded !== session_id) {
26490
+ return null;
26491
+ }
26492
+ const at = Date.parse(String(decoded["refused_at"] ?? ""));
26493
+ if (!Number.isFinite(at) || now - at > PENDING_MAX_AGE_MS) {
26494
+ return null;
26996
26495
  }
26496
+ return { op, session_id: recorded, refused_at: String(decoded["refused_at"]) };
26997
26497
  } catch {
26498
+ return null;
26998
26499
  }
26999
- return null;
27000
- }
27001
- function decide(command, ledger, impact) {
27002
- if (command === null) {
27003
- return { exit: EXIT_ALLOW11, stdout: "", stderr: "" };
27004
- }
27005
- const op = commandOp(command);
27006
- if (op === null || ledger.authorized.has(op)) {
27007
- return { exit: EXIT_ALLOW11, stdout: "", stderr: "" };
27008
- }
27009
- const target = mergeTargetOf(command);
27010
- if (grantCovers(ledger.grants ?? [], op, target) && target !== null) {
27011
- return { exit: EXIT_ALLOW11, stdout: "", stderr: "", consumedTarget: target };
27012
- }
27013
- const shown = command.length > 120 ? `${command.slice(0, 117)}\u2026` : command;
27014
- if (BLOCK_OPS.has(op)) {
27015
- const scan = op === "pr-merge" && target !== null && impact ? ` ${impact}` : "";
27016
- const reason = `Blocked: \`${op}\` with no authorization in this turn's prompt. This operation is irreversible and non-destructive-by-default already declares it never-autonomous. Command: ${shown}.${scan} Ask the user, in one numbered-options block, and run it only after they answer this turn.`;
27017
- return { exit: EXIT_BLOCK, stdout: "", stderr: `${reason}
27018
- `, blockedOp: op };
27019
- }
27020
- if (WARN_OPS.has(op)) {
27021
- const reason = `No \`${op}\` authorization found in this turn's prompt (commit-policy: a one-shot authorization is spent on the operation it named). If the user did authorize it this turn, proceed; otherwise stop and ask. Command: ${shown}`;
27022
- return {
27023
- exit: EXIT_ALLOW11,
27024
- stdout: `${JSON.stringify({ decision: "warn", reason })}
27025
- `,
27026
- stderr: ""
27027
- };
27028
- }
27029
- return { exit: EXIT_ALLOW11, stdout: "", stderr: "" };
27030
26500
  }
27031
- function run11(stdin_text, options) {
26501
+ function run10(stdin_text, options) {
27032
26502
  let envelope = {};
27033
26503
  if (stdin_text.trim()) {
27034
26504
  try {
27035
26505
  const decoded = JSON.parse(stdin_text);
27036
- if (_isObject9(decoded)) {
26506
+ if (_isObject8(decoded)) {
27037
26507
  envelope = decoded;
27038
26508
  }
27039
26509
  } catch {
27040
26510
  return EXIT_ALLOW11;
27041
26511
  }
27042
26512
  }
27043
- const session_id = typeof envelope["session_id"] === "string" ? envelope["session_id"] : "";
27044
- const command = extractCommand(envelope);
27045
- const ledger = _loadLedger(options.consumer_root, session_id, Date.now());
27046
- let impact;
27047
- const stage1 = command === null ? null : commandOp(command);
27048
- const stage2Target = command === null ? null : mergeTargetOf(command);
27049
- if (stage1 === "pr-merge" && stage2Target !== null && !ledger.authorized.has("pr-merge") && !grantCovers(ledger.grants ?? [], "pr-merge", stage2Target)) {
27050
- try {
27051
- impact = describeImpact(
27052
- stage2Target,
27053
- analyseMergeImpact(stage2Target, { cwd: options.consumer_root })
27054
- );
27055
- } catch {
26513
+ const payload = _isObject8(envelope["payload"]) ? envelope["payload"] : envelope;
26514
+ let prompt = "";
26515
+ for (const key of ["prompt", "userPrompt", "user_prompt", "message", "text"]) {
26516
+ const v = payload[key];
26517
+ if (typeof v === "string" && v.trim()) {
26518
+ prompt = v;
26519
+ break;
27056
26520
  }
27057
26521
  }
27058
- const decision = decide(command, ledger, impact);
27059
- if (decision.consumedTarget !== void 0) {
27060
- consumeGrantTarget(options.consumer_root, session_id, decision.consumedTarget);
26522
+ if (!prompt) {
26523
+ return EXIT_ALLOW11;
27061
26524
  }
27062
- if (decision.blockedOp) {
27063
- try {
27064
- atomic_write_json(path56.join(options.consumer_root, pendingFileFor(session_id)), {
27065
- op: decision.blockedOp,
27066
- session_id,
27067
- refused_at: (/* @__PURE__ */ new Date()).toISOString()
27068
- });
27069
- } catch {
27070
- }
26525
+ const session = typeof envelope["session_id"] === "string" ? envelope["session_id"] : "";
26526
+ if (!humanTypedThisTurn(prompt)) {
26527
+ return EXIT_ALLOW11;
27071
26528
  }
27072
- if (decision.stdout) {
27073
- process.stdout.write(decision.stdout);
26529
+ const { authorized, evidence } = classifyAuthorization(prompt);
26530
+ const pending = takePending(options.consumer_root, session, Date.now());
26531
+ if (pending && !authorized.includes(pending.op) && isAffirmative(prompt)) {
26532
+ authorized.push(pending.op);
26533
+ evidence[pending.op] = `confirmation of the refused \`${pending.op}\` (refused ${pending.refused_at}): "${prompt.trim().slice(0, 40)}"`;
27074
26534
  }
27075
- if (decision.stderr) {
27076
- process.stderr.write(decision.stderr);
26535
+ const now = /* @__PURE__ */ new Date();
26536
+ const ledger = {
26537
+ session_id: typeof envelope["session_id"] === "string" ? envelope["session_id"] : "",
26538
+ detected_at: now.toISOString(),
26539
+ authorized,
26540
+ evidence,
26541
+ prompt_chars: prompt.length,
26542
+ // Grants survive this write; `authorized` does not. That asymmetry IS the
26543
+ // decision. A bare operation name stays one-shot exactly as `commit-policy`
26544
+ // requires, and only an authorization that also froze its objects earns a
26545
+ // life longer than the turn. See ADR-252.
26546
+ grants: foldGrants(
26547
+ readGrants(options.consumer_root, session),
26548
+ prompt,
26549
+ authorized,
26550
+ session,
26551
+ now
26552
+ )
26553
+ };
26554
+ try {
26555
+ atomic_write_json(path56.join(options.consumer_root, ledgerFileFor(session)), ledger);
26556
+ } catch (err) {
26557
+ process.stderr.write(
26558
+ `git-authorization: session-ledger write failed (${_errText2(err)}) \u2014 the gate degrades to "no ledger" for this session, which denies the irreversible subset and warns on the rest. Authorization outcome unchanged.
26559
+ `
26560
+ );
27077
26561
  }
27078
- return decision.exit;
26562
+ return EXIT_ALLOW11;
27079
26563
  }
27080
26564
  function main31(argv) {
27081
26565
  const args = argv ?? process.argv.slice(2);
@@ -27089,9 +26573,9 @@ function main31(argv) {
27089
26573
  consumer_root = a.slice("--project-dir=".length);
27090
26574
  }
27091
26575
  }
27092
- return run11(readHookStdin(), { consumer_root });
26576
+ return run10(readHookStdin(), { consumer_root });
27093
26577
  }
27094
- function _isCliEntry25() {
26578
+ function _isCliEntry24() {
27095
26579
  if (true) {
27096
26580
  return false;
27097
26581
  }
@@ -27110,7 +26594,7 @@ function _isCliEntry25() {
27110
26594
  return false;
27111
26595
  }
27112
26596
  }
27113
- if (_isCliEntry25()) {
26597
+ if (_isCliEntry24()) {
27114
26598
  process.exit(main31());
27115
26599
  }
27116
26600
 
@@ -27120,9 +26604,9 @@ import fs57 from "node:fs";
27120
26604
  import path57 from "node:path";
27121
26605
  import { fileURLToPath as fileURLToPath35, pathToFileURL as pathToFileURL28 } from "node:url";
27122
26606
  var EXIT_ALLOW12 = 0;
27123
- var EXIT_BLOCK2 = 1;
26607
+ var EXIT_BLOCK = 1;
27124
26608
  var STATE_FILE8 = path57.join("agents", "state", "evidence-dispatch.json");
27125
- function _isObject10(v) {
26609
+ function _isObject9(v) {
27126
26610
  return typeof v === "object" && v !== null && !Array.isArray(v);
27127
26611
  }
27128
26612
  var DISPATCH_TOOLS = /* @__PURE__ */ new Set([
@@ -27175,10 +26659,10 @@ function preloadedVerdict(prompt) {
27175
26659
  return null;
27176
26660
  }
27177
26661
  function extractDispatch(envelope) {
27178
- const payload = _isObject10(envelope["payload"]) ? envelope["payload"] : envelope;
26662
+ const payload = _isObject9(envelope["payload"]) ? envelope["payload"] : envelope;
27179
26663
  const toolRaw = payload["tool_name"] ?? payload["toolName"] ?? payload["tool"];
27180
26664
  const tool = typeof toolRaw === "string" ? toolRaw : null;
27181
- const input = _isObject10(payload["tool_input"]) ? payload["tool_input"] : _isObject10(payload["toolInput"]) ? payload["toolInput"] : payload;
26665
+ const input = _isObject9(payload["tool_input"]) ? payload["tool_input"] : _isObject9(payload["toolInput"]) ? payload["toolInput"] : payload;
27182
26666
  for (const key of ["prompt", "instructions", "task", "description"]) {
27183
26667
  const v = input[key];
27184
26668
  if (typeof v === "string" && v.trim()) {
@@ -27202,7 +26686,7 @@ function _ledgerStamp(consumer_root) {
27202
26686
  function _load(target) {
27203
26687
  try {
27204
26688
  const decoded = JSON.parse(fs57.readFileSync(target, "utf8"));
27205
- if (_isObject10(decoded) && Array.isArray(decoded["evaluations"])) {
26689
+ if (_isObject9(decoded) && Array.isArray(decoded["evaluations"])) {
27206
26690
  return decoded;
27207
26691
  }
27208
26692
  } catch {
@@ -27210,14 +26694,14 @@ function _load(target) {
27210
26694
  return { session_id: "", turn_started_at: "", evaluations: [] };
27211
26695
  }
27212
26696
  var WARN_TEXT = "First evaluation dispatch this turn. Two shapes fabricated a binding honest-null in the audited sessions \u2014 check your prompt for both before it goes out: (1) a verdict pre-loaded into the prompt, and (2) a scope narrowed to files you chose. A review you commissioned on your own work is admissible as gate evidence only when the prompt is recorded alongside the verdict.";
27213
- function decide2(tool, prompt, priorEvaluations) {
26697
+ function decide(tool, prompt, priorEvaluations) {
27214
26698
  if (!isDispatchTool(tool) || !isEvaluationPrompt(prompt)) {
27215
26699
  return { exit: EXIT_ALLOW12, stdout: "", stderr: "", evaluations: priorEvaluations };
27216
26700
  }
27217
26701
  const preloaded = preloadedVerdict(prompt);
27218
26702
  if (preloaded !== null) {
27219
26703
  return {
27220
- exit: EXIT_BLOCK2,
26704
+ exit: EXIT_BLOCK,
27221
26705
  stdout: "",
27222
26706
  stderr: `Blocked: this evaluation prompt pre-loads its verdict ("${preloaded}"). That is the construct that produced a fabricated NO-FINDINGS committed as binding gate evidence, over a delta an unsteered pass then found a live critical in. Remove the expectation from the prompt and let the evaluator reach its own verdict.
27223
26707
  `,
@@ -27247,12 +26731,12 @@ function decide2(tool, prompt, priorEvaluations) {
27247
26731
  evaluations: priorEvaluations + 1
27248
26732
  };
27249
26733
  }
27250
- function run12(stdin_text, options) {
26734
+ function run11(stdin_text, options) {
27251
26735
  let envelope = {};
27252
26736
  if (stdin_text.trim()) {
27253
26737
  try {
27254
26738
  const decoded = JSON.parse(stdin_text);
27255
- if (_isObject10(decoded)) {
26739
+ if (_isObject9(decoded)) {
27256
26740
  envelope = decoded;
27257
26741
  }
27258
26742
  } catch {
@@ -27269,7 +26753,7 @@ function run12(stdin_text, options) {
27269
26753
  state.evaluations = [];
27270
26754
  }
27271
26755
  const [tool, prompt] = extractDispatch(envelope);
27272
- const decision = decide2(tool, prompt, state.evaluations.length);
26756
+ const decision = decide(tool, prompt, state.evaluations.length);
27273
26757
  if (decision.evaluations > state.evaluations.length) {
27274
26758
  state.evaluations.push({
27275
26759
  at: (/* @__PURE__ */ new Date()).toISOString(),
@@ -27278,7 +26762,11 @@ function run12(stdin_text, options) {
27278
26762
  });
27279
26763
  try {
27280
26764
  atomic_write_json(target, state);
27281
- } catch {
26765
+ } catch (err) {
26766
+ process.stderr.write(
26767
+ `evidence-independence: evaluation-count write failed (${_errText3(err)}) \u2014 this turn's count did NOT advance, so a second self-scoped evaluation will not be warned about. The pre-loaded-verdict block is unaffected.
26768
+ `
26769
+ );
27282
26770
  }
27283
26771
  }
27284
26772
  if (decision.stdout) {
@@ -27289,6 +26777,10 @@ function run12(stdin_text, options) {
27289
26777
  }
27290
26778
  return decision.exit;
27291
26779
  }
26780
+ function _errText3(err) {
26781
+ const t = err instanceof Error ? err.message : String(err);
26782
+ return t.replace(/\s+/g, " ").trim().slice(0, 200);
26783
+ }
27292
26784
  function main32(argv) {
27293
26785
  const args = argv ?? process.argv.slice(2);
27294
26786
  let consumer_root = process.cwd();
@@ -27297,39 +26789,191 @@ function main32(argv) {
27297
26789
  if (a === "--project-dir" && args[i + 1] !== void 0) {
27298
26790
  consumer_root = args[i + 1];
27299
26791
  i += 1;
27300
- } else if (a !== void 0 && a.startsWith("--project-dir=")) {
27301
- consumer_root = a.slice("--project-dir=".length);
26792
+ } else if (a !== void 0 && a.startsWith("--project-dir=")) {
26793
+ consumer_root = a.slice("--project-dir=".length);
26794
+ }
26795
+ }
26796
+ return run11(readHookStdin(), { consumer_root });
26797
+ }
26798
+ function _isCliEntry25() {
26799
+ if (true) {
26800
+ return false;
26801
+ }
26802
+ if (process.argv[1] === void 0) {
26803
+ return false;
26804
+ }
26805
+ const argvUrl = pathToFileURL28(path57.resolve(process.argv[1])).href;
26806
+ if (import.meta.url === argvUrl) {
26807
+ return true;
26808
+ }
26809
+ try {
26810
+ const here = fs57.realpathSync(fileURLToPath35(import.meta.url));
26811
+ const argv = fs57.realpathSync(path57.resolve(process.argv[1]));
26812
+ return here === argv;
26813
+ } catch {
26814
+ return false;
26815
+ }
26816
+ }
26817
+ if (_isCliEntry25()) {
26818
+ process.exit(main32());
26819
+ }
26820
+
26821
+ // src/scripts/hooks/block_no_verify.ts
26822
+ import * as fs58 from "node:fs";
26823
+ import { fileURLToPath as fileURLToPath36, pathToFileURL as pathToFileURL29 } from "node:url";
26824
+ import * as path58 from "node:path";
26825
+
26826
+ // src/scripts/hooks/git_command_classifier.ts
26827
+ var G = "(?:-[A-Za-z-]+(?:=\\S+)?(?:\\s+\\S+)?\\s+)*";
26828
+ var P = "^(?:\\S*\\/)?";
26829
+ function ghApiWrite(pathRe) {
26830
+ return new RegExp(
26831
+ `${P}gh\\s+api\\b(?=[^\\n]*${pathRe})(?=[^\\n]*(?:-X|--method)\\s+(?:POST|PATCH|PUT|DELETE)\\b)`,
26832
+ "i"
26833
+ );
26834
+ }
26835
+ var COMMAND_OPS = [
26836
+ { op: "publish", re: new RegExp(`${P}(npm|pnpm|yarn)\\s+${G}publish\\b`, "i") },
26837
+ {
26838
+ op: "release",
26839
+ re: new RegExp(`${P}gh\\s+release\\s+create\\b|${ghApiWrite("\\/releases\\b").source}`, "i")
26840
+ },
26841
+ {
26842
+ op: "tag",
26843
+ re: new RegExp(`${P}git\\s+${G}push\\b[^\\n;|&]*(--tags|--follow-tags|refs\\/tags\\/)`, "i")
26844
+ },
26845
+ // ORDER IS LOAD-BEARING, per this table's own rule that the most specific
26846
+ // pattern wins: `gh pr merge 12 --auto` matches the plain merge pattern too.
26847
+ //
26848
+ // The GraphQL mutation needs its OWN pattern rather than a widening of
26849
+ // `ghApiWrite()`. That helper requires BOTH a REST-shaped path and an
26850
+ // explicit write method, and `gh api graphql -f query='mutation{...}'` has
26851
+ // neither — widening it to reach this would loosen every other op that uses
26852
+ // it, which is a bigger change than the defect.
26853
+ {
26854
+ op: "pr-merge-auto",
26855
+ re: new RegExp(
26856
+ `${P}gh\\s+pr\\s+merge\\b(?=[^\\n]*--auto\\b)|${P}gh\\s+api\\b(?=[^\\n]*enablePullRequestAutoMerge\\b)`,
26857
+ "i"
26858
+ )
26859
+ },
26860
+ {
26861
+ op: "pr-merge",
26862
+ re: new RegExp(
26863
+ `${P}gh\\s+pr\\s+merge\\b(?![^\\n]*--(auto|disable-auto)\\b)|${ghApiWrite("\\/pulls\\/\\d+\\/merge\\b").source}`,
26864
+ "i"
26865
+ )
26866
+ },
26867
+ {
26868
+ op: "pr-create",
26869
+ re: new RegExp(`${P}gh\\s+pr\\s+create\\b|${ghApiWrite("\\/pulls\\b").source}`, "i")
26870
+ },
26871
+ // ── Added 2026-09-03. Placement inside this table is as load-bearing as the
26872
+ // patterns: the loop takes the MOST SEVERE match per segment, but within one
26873
+ // op the first pattern wins, so anything more specific than a plain `git push`
26874
+ // has to sit above it.
26875
+ // `npm unpublish` is NOT reached by the publish pattern — `\bpublish\b` needs
26876
+ // a word boundary that `unpublish` does not provide between `n` and `p`. That
26877
+ // is why it classified as nothing for as long as it did.
26878
+ { op: "unpublish", re: new RegExp(`${P}(npm|pnpm|yarn)\\s+${G}unpublish\\b`, "i") },
26879
+ { op: "deprecate", re: new RegExp(`${P}(npm|pnpm|yarn)\\s+${G}deprecate\\b`, "i") },
26880
+ {
26881
+ op: "release-asset",
26882
+ re: new RegExp(`${P}gh\\s+release\\s+(upload|edit|delete)\\b`, "i")
26883
+ },
26884
+ {
26885
+ op: "protection",
26886
+ re: new RegExp(
26887
+ `${P}gh\\s+api\\b(?=[^\\n]*(?:protection|rulesets?)\\b)(?=[^\\n]*(?:-X|--method)\\s+(?:DELETE|PUT|PATCH|POST)\\b)|${P}gh\\s+ruleset\\s+delete\\b`,
26888
+ "i"
26889
+ )
26890
+ },
26891
+ {
26892
+ op: "workflow-toggle",
26893
+ re: new RegExp(`${P}gh\\s+workflow\\s+(disable|enable)\\b`, "i")
26894
+ },
26895
+ {
26896
+ op: "repo-lifecycle",
26897
+ re: new RegExp(
26898
+ `${P}gh\\s+repo\\s+(archive|delete|unarchive)\\b|${P}gh\\s+repo\\s+edit\\b(?=[^\\n]*--visibility\\b)`,
26899
+ "i"
26900
+ )
26901
+ },
26902
+ {
26903
+ op: "review-approve",
26904
+ re: new RegExp(`${P}gh\\s+pr\\s+review\\b(?=[^\\n]*--approve\\b)`, "i")
26905
+ },
26906
+ // Above `push`, and both spellings: `--force` and `--force-with-lease`. The
26907
+ // "safe force" is in the same class here because what it is safe against is a
26908
+ // stale local view, not a collaborator who pushed after your fetch.
26909
+ {
26910
+ op: "force-push",
26911
+ re: new RegExp(`${P}git\\s+${G}push\\b[^\\n;|&]*(--force\\b|--force-with-lease\\b|\\s-f\\b)`, "i")
26912
+ },
26913
+ {
26914
+ op: "worktree-remove",
26915
+ re: new RegExp(`${P}git\\s+worktree\\s+remove\\b[^\\n;|&]*(--force\\b|\\s-f\\b)`, "i")
26916
+ },
26917
+ // `-x` (or `-X`) anywhere in the flag cluster is what reaches ignored files.
26918
+ {
26919
+ op: "clean-ignored",
26920
+ re: new RegExp(`${P}git\\s+clean\\b[^\\n;|&]*-[A-Za-z]*x`, "i")
26921
+ },
26922
+ { op: "tag-force", re: new RegExp(`${P}git\\s+tag\\b[^\\n;|&]*(-f\\b|--force\\b)`, "i") },
26923
+ { op: "rebase", re: new RegExp(`${P}git\\s+${G}rebase\\b`, "i") },
26924
+ { op: "reset-hard", re: new RegExp(`${P}git\\s+${G}reset\\b[^\\n;|&]*--hard\\b`, "i") },
26925
+ { op: "clean", re: new RegExp(`${P}git\\s+clean\\b`, "i") },
26926
+ { op: "stash-drop", re: new RegExp(`${P}git\\s+stash\\s+(drop|clear)\\b`, "i") },
26927
+ // Remote deletion and the local `-D` are one op: both remove a ref, and the
26928
+ // remote form additionally closes any open PR pointing at it.
26929
+ {
26930
+ op: "branch-delete",
26931
+ re: new RegExp(
26932
+ `${P}git\\s+branch\\b[^\\n;|&]*(-D\\b|--delete\\b)|${P}git\\s+${G}push\\b[^\\n;|&]*(--delete\\b|\\s:\\S)`,
26933
+ "i"
26934
+ )
26935
+ },
26936
+ { op: "close", re: new RegExp(`${P}gh\\s+(pr|issue)\\s+close\\b`, "i") },
26937
+ { op: "push", re: new RegExp(`${P}git\\s+${G}push\\b`, "i") },
26938
+ { op: "commit", re: new RegExp(`${P}git\\s+${G}commit\\b`, "i") },
26939
+ { op: "branch", re: new RegExp(`${P}git\\s+${G}(checkout\\s+-b|switch\\s+-c)\\b`, "i") }
26940
+ ];
26941
+ function substitutionPayloads(segment) {
26942
+ const out = [];
26943
+ for (let i = 0; i < segment.length; i += 1) {
26944
+ const ch = segment[i];
26945
+ if (ch === "\\") {
26946
+ i += 1;
26947
+ continue;
26948
+ }
26949
+ if ((ch === "$" || ch === "<" || ch === ">") && segment[i + 1] === "(") {
26950
+ let open = 1;
26951
+ let j = i + 2;
26952
+ const start = j;
26953
+ for (; j < segment.length && open > 0; j += 1) {
26954
+ const c = segment[j];
26955
+ if (c === "\\") {
26956
+ j += 1;
26957
+ } else if (c === "(") {
26958
+ open += 1;
26959
+ } else if (c === ")") {
26960
+ open -= 1;
26961
+ }
26962
+ }
26963
+ out.push(segment.slice(start, open === 0 ? j - 1 : segment.length));
26964
+ i = j - 1;
26965
+ continue;
26966
+ }
26967
+ if (ch === "`") {
26968
+ const end = segment.indexOf("`", i + 1);
26969
+ out.push(segment.slice(i + 1, end === -1 ? segment.length : end));
26970
+ i = end === -1 ? segment.length : end;
27302
26971
  }
27303
26972
  }
27304
- return run12(readHookStdin(), { consumer_root });
27305
- }
27306
- function _isCliEntry26() {
27307
- if (true) {
27308
- return false;
27309
- }
27310
- if (process.argv[1] === void 0) {
27311
- return false;
27312
- }
27313
- const argvUrl = pathToFileURL28(path57.resolve(process.argv[1])).href;
27314
- if (import.meta.url === argvUrl) {
27315
- return true;
27316
- }
27317
- try {
27318
- const here = fs57.realpathSync(fileURLToPath35(import.meta.url));
27319
- const argv = fs57.realpathSync(path57.resolve(process.argv[1]));
27320
- return here === argv;
27321
- } catch {
27322
- return false;
27323
- }
27324
- }
27325
- if (_isCliEntry26()) {
27326
- process.exit(main32());
26973
+ return out;
27327
26974
  }
27328
26975
 
27329
26976
  // src/scripts/hooks/block_no_verify.ts
27330
- import * as fs58 from "node:fs";
27331
- import { fileURLToPath as fileURLToPath36, pathToFileURL as pathToFileURL29 } from "node:url";
27332
- import * as path58 from "node:path";
27333
26977
  var _HERE4 = fileURLToPath36(import.meta.url);
27334
26978
  var _SHELL_SEPARATORS = /* @__PURE__ */ new Set(["&&", "||", ";", "|", "&"]);
27335
26979
  var _OPERATOR_CHARS = ";|&";
@@ -27766,7 +27410,7 @@ function main33(argv) {
27766
27410
  }
27767
27411
  return 0;
27768
27412
  }
27769
- function _isCliEntry27() {
27413
+ function _isCliEntry26() {
27770
27414
  if (true) {
27771
27415
  return false;
27772
27416
  }
@@ -27785,7 +27429,7 @@ function _isCliEntry27() {
27785
27429
  return false;
27786
27430
  }
27787
27431
  }
27788
- if (_isCliEntry27() || false) {
27432
+ if (_isCliEntry26() || false) {
27789
27433
  process.exitCode = main33();
27790
27434
  }
27791
27435
 
@@ -27794,7 +27438,7 @@ import * as fs59 from "node:fs";
27794
27438
  import { fileURLToPath as fileURLToPath37, pathToFileURL as pathToFileURL30 } from "node:url";
27795
27439
  import * as path59 from "node:path";
27796
27440
  var _HERE5 = fileURLToPath37(import.meta.url);
27797
- function _isObject11(v) {
27441
+ function _isObject10(v) {
27798
27442
  return v !== null && v !== void 0 && typeof v === "object" && !Array.isArray(v);
27799
27443
  }
27800
27444
  var _PATH_KEYS = [
@@ -27806,10 +27450,10 @@ var _PATH_KEYS = [
27806
27450
  "notebook_path"
27807
27451
  ];
27808
27452
  function _extract(envelope) {
27809
- const payload = _isObject11(envelope["payload"]) ? envelope["payload"] : envelope;
27453
+ const payload = _isObject10(envelope["payload"]) ? envelope["payload"] : envelope;
27810
27454
  const nameVal = payload["tool_name"] ?? payload["toolName"] ?? payload["tool"] ?? envelope["tool_name"] ?? envelope["tool"];
27811
27455
  const tool = typeof nameVal === "string" ? nameVal : "";
27812
- const ti = _isObject11(payload["tool_input"]) ? payload["tool_input"] : _isObject11(envelope["tool_input"]) ? envelope["tool_input"] : null;
27456
+ const ti = _isObject10(payload["tool_input"]) ? payload["tool_input"] : _isObject10(envelope["tool_input"]) ? envelope["tool_input"] : null;
27813
27457
  const paths = [];
27814
27458
  if (ti !== null) {
27815
27459
  for (const key of _PATH_KEYS) {
@@ -27940,8 +27584,8 @@ function check_envelope(envelope) {
27940
27584
  return [false, ""];
27941
27585
  }
27942
27586
  function _extract_command3(envelope) {
27943
- const payload = _isObject11(envelope["payload"]) ? envelope["payload"] : envelope;
27944
- const ti = _isObject11(payload["tool_input"]) ? payload["tool_input"] : _isObject11(envelope["tool_input"]) ? envelope["tool_input"] : null;
27587
+ const payload = _isObject10(envelope["payload"]) ? envelope["payload"] : envelope;
27588
+ const ti = _isObject10(payload["tool_input"]) ? payload["tool_input"] : _isObject10(envelope["tool_input"]) ? envelope["tool_input"] : null;
27945
27589
  for (const src of [ti, payload]) {
27946
27590
  if (src === null) {
27947
27591
  continue;
@@ -27954,7 +27598,7 @@ function _extract_command3(envelope) {
27954
27598
  return null;
27955
27599
  }
27956
27600
  function _asObject2(v) {
27957
- return _isObject11(v) ? v : null;
27601
+ return _isObject10(v) ? v : null;
27958
27602
  }
27959
27603
  function _readStdin12() {
27960
27604
  return readHookStdin();
@@ -27984,7 +27628,7 @@ function main34() {
27984
27628
  }
27985
27629
  return 0;
27986
27630
  }
27987
- function _isCliEntry28() {
27631
+ function _isCliEntry27() {
27988
27632
  if (true) {
27989
27633
  return false;
27990
27634
  }
@@ -28003,7 +27647,7 @@ function _isCliEntry28() {
28003
27647
  return false;
28004
27648
  }
28005
27649
  }
28006
- if (_isCliEntry28() || false) {
27650
+ if (_isCliEntry27() || false) {
28007
27651
  process.exitCode = main34();
28008
27652
  }
28009
27653
 
@@ -28013,11 +27657,11 @@ import * as path60 from "node:path";
28013
27657
  import { fileURLToPath as fileURLToPath38, pathToFileURL as pathToFileURL31 } from "node:url";
28014
27658
  var _HERE6 = fileURLToPath38(import.meta.url);
28015
27659
  var EXIT_ALLOW13 = 0;
28016
- var EXIT_BLOCK3 = 1;
28017
- var EXIT_WARN4 = 2;
27660
+ var EXIT_BLOCK2 = 1;
27661
+ var EXIT_WARN5 = 2;
28018
27662
  var SESSION_ENTRY_CAP = 20;
28019
27663
  var SESSION_WARN_AT = 5;
28020
- function _isObject12(v) {
27664
+ function _isObject11(v) {
28021
27665
  return v !== null && v !== void 0 && typeof v === "object" && !Array.isArray(v);
28022
27666
  }
28023
27667
  var _PATH_KEYS2 = ["file_path", "path", "target_file", "filePath", "notebook_path"];
@@ -28070,7 +27714,7 @@ function added_entries(tool_input, on_disk) {
28070
27714
  }
28071
27715
  return 0;
28072
27716
  }
28073
- function decide3(kind, rel_path, session_total, added) {
27717
+ function decide2(kind, rel_path, session_total, added) {
28074
27718
  if (kind === null || added <= 0) {
28075
27719
  return { action: "allow", reason: "" };
28076
27720
  }
@@ -28119,10 +27763,10 @@ function bump_session(root, session, key, added) {
28119
27763
  return total;
28120
27764
  }
28121
27765
  function _extract2(envelope) {
28122
- const payload = _isObject12(envelope["payload"]) ? envelope["payload"] : envelope;
27766
+ const payload = _isObject11(envelope["payload"]) ? envelope["payload"] : envelope;
28123
27767
  const nameVal = payload["tool_name"] ?? payload["toolName"] ?? payload["tool"] ?? envelope["tool_name"] ?? envelope["tool"];
28124
27768
  const tool = typeof nameVal === "string" ? nameVal : "";
28125
- const ti = _isObject12(payload["tool_input"]) ? payload["tool_input"] : _isObject12(envelope["tool_input"]) ? envelope["tool_input"] : null;
27769
+ const ti = _isObject11(payload["tool_input"]) ? payload["tool_input"] : _isObject11(envelope["tool_input"]) ? envelope["tool_input"] : null;
28126
27770
  const paths = [];
28127
27771
  if (ti !== null) {
28128
27772
  for (const key of _PATH_KEYS2) {
@@ -28142,7 +27786,7 @@ function main35() {
28142
27786
  } catch {
28143
27787
  return EXIT_ALLOW13;
28144
27788
  }
28145
- if (!_isObject12(envelope)) {
27789
+ if (!_isObject11(envelope)) {
28146
27790
  return EXIT_ALLOW13;
28147
27791
  }
28148
27792
  const { tool, paths, ti } = _extract2(envelope);
@@ -28172,21 +27816,21 @@ function main35() {
28172
27816
  }
28173
27817
  const rel = path60.relative(root, abs) || p;
28174
27818
  const total = kind === "allowlist" ? bump_session(root, session, rel, added) : added;
28175
- const d = decide3(kind, rel, total, added);
27819
+ const d = decide2(kind, rel, total, added);
28176
27820
  if (d.action === "block") {
28177
27821
  process.stderr.write(`block-config-weakening: BLOCKED \u2014 ${d.reason}
28178
27822
  `);
28179
- return EXIT_BLOCK3;
27823
+ return EXIT_BLOCK2;
28180
27824
  }
28181
27825
  if (d.action === "warn") {
28182
27826
  process.stdout.write(`${JSON.stringify({ decision: "warn", reason: d.reason })}
28183
27827
  `);
28184
- return EXIT_WARN4;
27828
+ return EXIT_WARN5;
28185
27829
  }
28186
27830
  }
28187
27831
  return EXIT_ALLOW13;
28188
27832
  }
28189
- function _isCliEntry29() {
27833
+ function _isCliEntry28() {
28190
27834
  if (true) {
28191
27835
  return false;
28192
27836
  }
@@ -28203,7 +27847,7 @@ function _isCliEntry29() {
28203
27847
  return false;
28204
27848
  }
28205
27849
  }
28206
- if (_isCliEntry29() || process.argv[1] === _HERE6) {
27850
+ if (_isCliEntry28() || process.argv[1] === _HERE6) {
28207
27851
  process.exit(main35());
28208
27852
  }
28209
27853
 
@@ -28236,7 +27880,7 @@ var _PATH_KEYS3 = [
28236
27880
  "filePath",
28237
27881
  "notebook_path"
28238
27882
  ];
28239
- function _isObject13(v) {
27883
+ function _isObject12(v) {
28240
27884
  return v !== null && v !== void 0 && typeof v === "object" && !Array.isArray(v);
28241
27885
  }
28242
27886
  var INBOX_RE = /(?:^|\/)agents\/tmp(?:\.old)?\/([^/]+)\/./;
@@ -28309,8 +27953,8 @@ function main36() {
28309
27953
  return 0;
28310
27954
  }
28311
27955
  try {
28312
- const payload = _isObject13(envelope["payload"]) ? envelope["payload"] : envelope;
28313
- const ti = _isObject13(payload["tool_input"]) ? payload["tool_input"] : _isObject13(envelope["tool_input"]) ? envelope["tool_input"] : null;
27956
+ const payload = _isObject12(envelope["payload"]) ? envelope["payload"] : envelope;
27957
+ const ti = _isObject12(payload["tool_input"]) ? payload["tool_input"] : _isObject12(envelope["tool_input"]) ? envelope["tool_input"] : null;
28314
27958
  if (ti === null) {
28315
27959
  return 0;
28316
27960
  }
@@ -28322,7 +27966,7 @@ function main36() {
28322
27966
  candidates.push(v);
28323
27967
  }
28324
27968
  }
28325
- const cmd = ti["command"] ?? (_isObject13(envelope["payload"]) ? envelope["payload"]["command"] : void 0);
27969
+ const cmd = ti["command"] ?? (_isObject12(envelope["payload"]) ? envelope["payload"]["command"] : void 0);
28326
27970
  if (typeof cmd === "string" && cmd) {
28327
27971
  for (const tok of cmd.split(/[\s"'`(){};|&<>]+/)) {
28328
27972
  if (tok) {
@@ -28342,7 +27986,7 @@ function main36() {
28342
27986
  }
28343
27987
  return 0;
28344
27988
  }
28345
- function _isCliEntry30() {
27989
+ function _isCliEntry29() {
28346
27990
  if (process.argv[1] === void 0) {
28347
27991
  return false;
28348
27992
  }
@@ -28355,7 +27999,7 @@ function _isCliEntry30() {
28355
27999
  return false;
28356
28000
  }
28357
28001
  }
28358
- if (_isCliEntry30()) {
28002
+ if (_isCliEntry29()) {
28359
28003
  process.exit(main36());
28360
28004
  }
28361
28005
 
@@ -28475,7 +28119,7 @@ function detectRtkCached(options = {}) {
28475
28119
  // src/scripts/hooks/rtk_wrap_hook.ts
28476
28120
  var SETTINGS_FILE6 = ".agent-settings.yml";
28477
28121
  var EXIT_ALLOW14 = 0;
28478
- var EXIT_WARN5 = 2;
28122
+ var EXIT_WARN6 = 2;
28479
28123
  var _RTK_PROGRAMS = /* @__PURE__ */ new Set([
28480
28124
  "git",
28481
28125
  "phpstan",
@@ -28500,7 +28144,7 @@ var _RTK_PROGRAMS = /* @__PURE__ */ new Set([
28500
28144
  "kubectl",
28501
28145
  "terraform"
28502
28146
  ]);
28503
- function _isObject14(v) {
28147
+ function _isObject13(v) {
28504
28148
  return typeof v === "object" && v !== null && !Array.isArray(v);
28505
28149
  }
28506
28150
  function _enabled2(root) {
@@ -28559,8 +28203,8 @@ function rtk_available(env = process.env) {
28559
28203
  return false;
28560
28204
  }
28561
28205
  function _extract_command4(envelope) {
28562
- const payload = _isObject14(envelope["payload"]) ? envelope["payload"] : {};
28563
- const tool_input = _isObject14(payload["tool_input"]) ? payload["tool_input"] : {};
28206
+ const payload = _isObject13(envelope["payload"]) ? envelope["payload"] : {};
28207
+ const tool_input = _isObject13(payload["tool_input"]) ? payload["tool_input"] : {};
28564
28208
  for (const src of [tool_input["command"], payload["command"], envelope["command"]]) {
28565
28209
  if (typeof src === "string") return src;
28566
28210
  }
@@ -28663,7 +28307,7 @@ function main37() {
28663
28307
  } catch {
28664
28308
  return EXIT_ALLOW14;
28665
28309
  }
28666
- if (!_isObject14(envelope)) return EXIT_ALLOW14;
28310
+ if (!_isObject13(envelope)) return EXIT_ALLOW14;
28667
28311
  const cwd = envelope["cwd"];
28668
28312
  const projectRoot = envelope["workspace_root"] ?? envelope["project_root"];
28669
28313
  const root = typeof cwd === "string" && cwd ? cwd : typeof projectRoot === "string" && projectRoot ? projectRoot : ".";
@@ -28676,7 +28320,7 @@ function main37() {
28676
28320
  const reason = `rtk is installed and wraps verbose CLI output (upstream reports 60\u201390% fewer output tokens). Re-run wrapped: \`rtk ${command.trim()}\`. (Skip for completeness-critical output like \`git diff\`.)`;
28677
28321
  process.stdout.write(`${_jsonReason(reason)}
28678
28322
  `);
28679
- return EXIT_WARN5;
28323
+ return EXIT_WARN6;
28680
28324
  }
28681
28325
  }
28682
28326
  const cap = classifyCap(command);
@@ -28684,11 +28328,11 @@ function main37() {
28684
28328
  const reason = `Unbounded \`${cap.program}\` output: a tree-wide search can return hundreds of KB into context (measured here: 302 KB raw vs 21 KB bounded \u2014 internal/bench/rtk-savings/RESULTS.md). Prefer a bounded form \u2014 ${cap.hint}. Re-running unbounded is fine when completeness is required.`;
28685
28329
  process.stdout.write(`${_jsonReason(reason)}
28686
28330
  `);
28687
- return EXIT_WARN5;
28331
+ return EXIT_WARN6;
28688
28332
  }
28689
28333
  return EXIT_ALLOW14;
28690
28334
  }
28691
- function _isCliEntry31() {
28335
+ function _isCliEntry30() {
28692
28336
  if (true) {
28693
28337
  return false;
28694
28338
  }
@@ -28707,7 +28351,7 @@ function _isCliEntry31() {
28707
28351
  return false;
28708
28352
  }
28709
28353
  }
28710
- if (_isCliEntry31()) {
28354
+ if (_isCliEntry30()) {
28711
28355
  process.exit(main37());
28712
28356
  }
28713
28357
 
@@ -29165,14 +28809,14 @@ var SLOP_RULES = [
29165
28809
  gated: (ctx) => ctx.has("brutalist", "uniform grid", "repetitive grid"),
29166
28810
  detect: ({ content }) => {
29167
28811
  const bodies = sectionBodies(content);
29168
- let run13 = 0;
28812
+ let run12 = 0;
29169
28813
  let maxRun = 0;
29170
28814
  for (const b of bodies) {
29171
28815
  if (sectionSignature(b).mediaText) {
29172
- run13 += 1;
29173
- maxRun = Math.max(maxRun, run13);
28816
+ run12 += 1;
28817
+ maxRun = Math.max(maxRun, run12);
29174
28818
  } else {
29175
- run13 = 0;
28819
+ run12 = 0;
29176
28820
  }
29177
28821
  }
29178
28822
  if (maxRun > 2) return [{ line: 1, snippet: `${maxRun} consecutive media+text sections` }];
@@ -29470,7 +29114,7 @@ if (invokedDirectly) main38();
29470
29114
 
29471
29115
  // src/scripts/hooks/design_pass_hook.ts
29472
29116
  var EXIT_ALLOW15 = 0;
29473
- var EXIT_WARN6 = 2;
29117
+ var EXIT_WARN7 = 2;
29474
29118
  var SETTINGS_FILE7 = ".agent-settings.yml";
29475
29119
  var STATE_REL2 = path64.join("agents", "runtime", "state", "design-pass-hook.json");
29476
29120
  var AUDIT_REL = path64.join("agents", "runtime", "state", "ui-audit.json");
@@ -29514,7 +29158,7 @@ function auditIsFresh(root, target) {
29514
29158
  return false;
29515
29159
  }
29516
29160
  }
29517
- function decide4(slot, findings, auditMissing, already, renderAvailable2) {
29161
+ function decide3(slot, findings, auditMissing, already, renderAvailable2) {
29518
29162
  const sig = (f) => `${f.file}::${f.rule}::${f.line}`;
29519
29163
  const fresh = findings.filter((f) => !already.has(sig(f)));
29520
29164
  const blocked = slot === "stop" ? fresh.filter((f) => f.severity === "P0") : [];
@@ -29630,7 +29274,7 @@ function main39() {
29630
29274
  scanFailed = String(err);
29631
29275
  }
29632
29276
  const auditMissing = targets.filter((t) => !auditIsFresh(root, t));
29633
- let result = decide4(slot, findings, auditMissing, new Set(state.surfaced), renderAvailable(root));
29277
+ let result = decide3(slot, findings, auditMissing, new Set(state.surfaced), renderAvailable(root));
29634
29278
  if (scanFailed) {
29635
29279
  result = { ...result, verification: "unverified", degradation_reason: `detector unavailable: ${scanFailed}` };
29636
29280
  }
@@ -29642,7 +29286,7 @@ function main39() {
29642
29286
  }
29643
29287
  process.stdout.write(`${JSON.stringify({ reason: render(result) })}
29644
29288
  `);
29645
- return EXIT_WARN6;
29289
+ return EXIT_WARN7;
29646
29290
  }
29647
29291
  if (process.argv[1] && pathToFileURL34(process.argv[1]).href === import.meta.url) {
29648
29292
  process.exit(main39());
@@ -29655,9 +29299,9 @@ import path65 from "node:path";
29655
29299
  import { fileURLToPath as fileURLToPath42, pathToFileURL as pathToFileURL35 } from "node:url";
29656
29300
  var SETTINGS_FILE8 = ".agent-settings.yml";
29657
29301
  var EXIT_ALLOW16 = 0;
29658
- var EXIT_WARN7 = 2;
29302
+ var EXIT_WARN8 = 2;
29659
29303
  var DEGRADE_AFTER = 3;
29660
- function isObject4(v) {
29304
+ function isObject5(v) {
29661
29305
  return typeof v === "object" && v !== null && !Array.isArray(v);
29662
29306
  }
29663
29307
  function enabled3(root) {
@@ -29692,12 +29336,12 @@ function enabled3(root) {
29692
29336
  }
29693
29337
  function _unwrap2(envelope) {
29694
29338
  const inner = envelope["payload"];
29695
- return isObject4(inner) ? inner : envelope;
29339
+ return isObject5(inner) ? inner : envelope;
29696
29340
  }
29697
29341
  function extract(outer) {
29698
29342
  const envelope = _unwrap2(outer);
29699
29343
  const ti = envelope["tool_input"] ?? envelope["toolInput"] ?? envelope["input"];
29700
- if (!isObject4(ti)) return null;
29344
+ if (!isObject5(ti)) return null;
29701
29345
  const fileVal = ti["file_path"] ?? ti["path"] ?? ti["filePath"];
29702
29346
  const file = typeof fileVal === "string" ? fileVal : "";
29703
29347
  for (const key of ["content", "new_string", "new_str", "text", "newText"]) {
@@ -29713,7 +29357,7 @@ function readState2(root) {
29713
29357
  try {
29714
29358
  const t = fs65.readFileSync(stateFile(root), "utf-8");
29715
29359
  const parsed = JSON.parse(t);
29716
- return isObject4(parsed) ? parsed : {};
29360
+ return isObject5(parsed) ? parsed : {};
29717
29361
  } catch {
29718
29362
  return {};
29719
29363
  }
@@ -29737,7 +29381,7 @@ function main40() {
29737
29381
  } catch {
29738
29382
  return EXIT_ALLOW16;
29739
29383
  }
29740
- if (!isObject4(envelope)) return EXIT_ALLOW16;
29384
+ if (!isObject5(envelope)) return EXIT_ALLOW16;
29741
29385
  const rootVal = envelope["cwd"] ?? envelope["project_root"] ?? ".";
29742
29386
  const root = typeof rootVal === "string" && rootVal ? rootVal : ".";
29743
29387
  if (!enabled3(root)) return EXIT_ALLOW16;
@@ -29771,9 +29415,9 @@ function main40() {
29771
29415
  const lines = surfaced.map((f) => `${f.catalogId} (${f.rule}) ${f.file}:${f.line} \u2014 ${f.message}`).join("; ");
29772
29416
  const reason = "\u26A0\uFE0F Anti-slop: high-severity aesthetic tell(s) in the proposed UI \u2014 " + lines + ". Rebuttable: declare intent in DESIGN.md, add design-slop-disable-next-line, or proceed if deliberate (this is a flag, not a block).";
29773
29417
  process.stdout.write(JSON.stringify({ decision: "warn", reason }) + "\n");
29774
- return EXIT_WARN7;
29418
+ return EXIT_WARN8;
29775
29419
  }
29776
- function _isCliEntry32() {
29420
+ function _isCliEntry31() {
29777
29421
  if (true) {
29778
29422
  return false;
29779
29423
  }
@@ -29792,8 +29436,8 @@ function _isCliEntry32() {
29792
29436
  return false;
29793
29437
  }
29794
29438
  }
29795
- var isCliEntry10 = _isCliEntry32();
29796
- if (isCliEntry10) process.exit(main40());
29439
+ var isCliEntry11 = _isCliEntry31();
29440
+ if (isCliEntry11) process.exit(main40());
29797
29441
 
29798
29442
  // src/scripts/hooks/code_graph_nudge_hook.ts
29799
29443
  import fs67 from "node:fs";
@@ -29808,7 +29452,18 @@ import * as path66 from "node:path";
29808
29452
  // src/scripts/code_graph/validate.ts
29809
29453
  var RELATIONS = /* @__PURE__ */ new Set(["calls", "imports", "uses", "inherits", "member"]);
29810
29454
  var CONFIDENCES = /* @__PURE__ */ new Set(["EXTRACTED", "INFERRED", "AMBIGUOUS"]);
29811
- var KINDS = /* @__PURE__ */ new Set(["file", "class", "interface", "trait", "function", "method", "skipped"]);
29455
+ var KINDS = /* @__PURE__ */ new Set([
29456
+ "file",
29457
+ "class",
29458
+ "interface",
29459
+ "trait",
29460
+ "function",
29461
+ "method",
29462
+ "constant",
29463
+ "type",
29464
+ "enum",
29465
+ "skipped"
29466
+ ]);
29812
29467
  function validateGraph(g) {
29813
29468
  const errors = [];
29814
29469
  const push = (m) => {
@@ -29933,9 +29588,9 @@ function pickSource(verdicts) {
29933
29588
  // src/scripts/hooks/code_graph_nudge_hook.ts
29934
29589
  var SETTINGS_FILE9 = ".agent-settings.yml";
29935
29590
  var EXIT_ALLOW17 = 0;
29936
- var EXIT_WARN8 = 2;
29591
+ var EXIT_WARN9 = 2;
29937
29592
  var CODE_EXT = /\.(php|ts|tsx|mts|cts|js|jsx|mjs|cjs)$/i;
29938
- function isObject5(v) {
29593
+ function isObject6(v) {
29939
29594
  return typeof v === "object" && v !== null && !Array.isArray(v);
29940
29595
  }
29941
29596
  function enabled4(root) {
@@ -29969,13 +29624,13 @@ function enabled4(root) {
29969
29624
  return false;
29970
29625
  }
29971
29626
  function classifyTool(envelope) {
29972
- const payload = isObject5(envelope["payload"]) ? envelope["payload"] : envelope;
29627
+ const payload = isObject6(envelope["payload"]) ? envelope["payload"] : envelope;
29973
29628
  const nameVal = payload["tool_name"] ?? payload["toolName"] ?? payload["tool"] ?? envelope["tool_name"] ?? envelope["tool"];
29974
29629
  const name = typeof nameVal === "string" ? nameVal : "";
29975
- const ti = isObject5(payload["tool_input"]) ? payload["tool_input"] : envelope["tool_input"];
29630
+ const ti = isObject6(payload["tool_input"]) ? payload["tool_input"] : envelope["tool_input"];
29976
29631
  const isSearch = name === "Grep" || name === "Glob";
29977
29632
  let isCodeRead = false;
29978
- if (name === "Read" && isObject5(ti)) {
29633
+ if (name === "Read" && isObject6(ti)) {
29979
29634
  const fp = ti["file_path"] ?? ti["path"];
29980
29635
  if (typeof fp === "string") isCodeRead = CODE_EXT.test(fp);
29981
29636
  }
@@ -30030,7 +29685,7 @@ function main41() {
30030
29685
  } catch {
30031
29686
  return EXIT_ALLOW17;
30032
29687
  }
30033
- if (!isObject5(envelope)) return EXIT_ALLOW17;
29688
+ if (!isObject6(envelope)) return EXIT_ALLOW17;
30034
29689
  const cwd = envelope["cwd"];
30035
29690
  const pr = envelope["workspace_root"] ?? envelope["project_root"];
30036
29691
  const root = typeof cwd === "string" && cwd ? cwd : typeof pr === "string" && pr ? pr : ".";
@@ -30048,9 +29703,9 @@ function main41() {
30048
29703
  latch(root, session);
30049
29704
  process.stdout.write(`${JSON.stringify({ decision: "warn", reason })}
30050
29705
  `);
30051
- return EXIT_WARN8;
29706
+ return EXIT_WARN9;
30052
29707
  }
30053
- function isCliEntry11() {
29708
+ function isCliEntry12() {
30054
29709
  if (true) {
30055
29710
  return false;
30056
29711
  }
@@ -30063,7 +29718,7 @@ function isCliEntry11() {
30063
29718
  return false;
30064
29719
  }
30065
29720
  }
30066
- if (isCliEntry11()) process.exit(main41());
29721
+ if (isCliEntry12()) process.exit(main41());
30067
29722
 
30068
29723
  // src/scripts/hooks/suggestion_capture_hook.ts
30069
29724
  import fs68 from "node:fs";
@@ -30074,7 +29729,7 @@ var SETTINGS_FILE10 = ".agent-settings.yml";
30074
29729
  var SINK_REL = path68.join("agents", "runtime", "state", "audit", "suggestion-capture.jsonl");
30075
29730
  var LATCH_REL = path68.join("agents", "runtime", "state", "suggestion-latch.json");
30076
29731
  var LATCH_TTL_MS = 15 * 60 * 1e3;
30077
- var isObject6 = (v) => typeof v === "object" && v !== null && !Array.isArray(v);
29732
+ var isObject7 = (v) => typeof v === "object" && v !== null && !Array.isArray(v);
30078
29733
  var str3 = (v) => typeof v === "string" ? v : "";
30079
29734
  function detectBlock(text) {
30080
29735
  if (text === "") return { emitted: false, optionsCount: 0 };
@@ -30153,7 +29808,7 @@ function consumeLatch(root) {
30153
29808
  }
30154
29809
  try {
30155
29810
  const v = JSON.parse(raw);
30156
- if (!isObject6(v)) return null;
29811
+ if (!isObject7(v)) return null;
30157
29812
  const at = v["at"];
30158
29813
  const oc = v["options_count"];
30159
29814
  const pid = v["prompt_id"];
@@ -30256,7 +29911,7 @@ function main42(_argv = [], now = /* @__PURE__ */ new Date()) {
30256
29911
  }
30257
29912
  return EXIT_ALLOW18;
30258
29913
  }
30259
- function isCliEntry12() {
29914
+ function isCliEntry13() {
30260
29915
  if (true) return false;
30261
29916
  if (process.argv[1] === void 0) return false;
30262
29917
  const argvUrl = pathToFileURL37(path68.resolve(process.argv[1])).href;
@@ -30267,7 +29922,7 @@ function isCliEntry12() {
30267
29922
  return false;
30268
29923
  }
30269
29924
  }
30270
- if (isCliEntry12()) process.exit(main42());
29925
+ if (isCliEntry13()) process.exit(main42());
30271
29926
 
30272
29927
  // src/scripts/hooks/ui_route_nudge_hook.ts
30273
29928
  import * as fs70 from "node:fs";
@@ -30340,7 +29995,7 @@ function leanProjectionModeRaw(root) {
30340
29995
 
30341
29996
  // src/scripts/hooks/ui_route_nudge_hook.ts
30342
29997
  var EXIT_ALLOW19 = 0;
30343
- var EXIT_WARN9 = 2;
29998
+ var EXIT_WARN10 = 2;
30344
29999
  var MAX_NUDGES = 2;
30345
30000
  var DESIGN_SURFACES = [
30346
30001
  "fe-design",
@@ -30348,17 +30003,17 @@ var DESIGN_SURFACES = [
30348
30003
  "design-review",
30349
30004
  "design-intelligence"
30350
30005
  ];
30351
- function isObject7(v) {
30006
+ function isObject8(v) {
30352
30007
  return typeof v === "object" && v !== null && !Array.isArray(v);
30353
30008
  }
30354
- function unwrap2(envelope) {
30009
+ function unwrap3(envelope) {
30355
30010
  const inner = envelope["payload"];
30356
- return isObject7(inner) ? inner : envelope;
30011
+ return isObject8(inner) ? inner : envelope;
30357
30012
  }
30358
30013
  function extractEvent(outer) {
30359
- const envelope = unwrap2(outer);
30014
+ const envelope = unwrap3(outer);
30360
30015
  const ti = envelope["tool_input"] ?? envelope["toolInput"] ?? envelope["input"];
30361
- if (!isObject7(ti)) return null;
30016
+ if (!isObject8(ti)) return null;
30362
30017
  const fileVal = ti["file_path"] ?? ti["path"] ?? ti["filePath"];
30363
30018
  const file = typeof fileVal === "string" ? fileVal : "";
30364
30019
  let isWrite = false;
@@ -30414,7 +30069,7 @@ function writeState3(root, session, state) {
30414
30069
  } catch {
30415
30070
  }
30416
30071
  }
30417
- function decide5(event, state) {
30072
+ function decide4(event, state) {
30418
30073
  if (isConsultation(event)) {
30419
30074
  return { state: { ...state, consulted: true }, warn: false };
30420
30075
  }
@@ -30438,7 +30093,7 @@ function main43() {
30438
30093
  } catch {
30439
30094
  return EXIT_ALLOW19;
30440
30095
  }
30441
- if (!isObject7(envelope)) return EXIT_ALLOW19;
30096
+ if (!isObject8(envelope)) return EXIT_ALLOW19;
30442
30097
  const rootVal = envelope["workspace_root"];
30443
30098
  const root = typeof rootVal === "string" && rootVal ? rootVal : process.cwd();
30444
30099
  if (!hookSectionEnabled(root, "ui_route_nudge")) return EXIT_ALLOW19;
@@ -30447,21 +30102,21 @@ function main43() {
30447
30102
  const event = extractEvent(envelope);
30448
30103
  if (!event) return EXIT_ALLOW19;
30449
30104
  const before = readState3(root, session);
30450
- const { state, warn } = decide5(event, before);
30105
+ const { state, warn } = decide4(event, before);
30451
30106
  if (stateChanged(before, state)) {
30452
30107
  writeState3(root, session, state);
30453
30108
  }
30454
30109
  if (!warn) return EXIT_ALLOW19;
30455
30110
  process.stdout.write(`${JSON.stringify({ reason: nudgeReason2(event.file) })}
30456
30111
  `);
30457
- return EXIT_WARN9;
30112
+ return EXIT_WARN10;
30458
30113
  }
30459
- function isCliEntry13() {
30114
+ function isCliEntry14() {
30460
30115
  const entry = process.argv[1];
30461
30116
  if (!entry) return false;
30462
30117
  return pathToFileURL38(path70.resolve(entry)).href === import.meta.url;
30463
30118
  }
30464
- if (isCliEntry13()) process.exit(main43());
30119
+ if (isCliEntry14()) process.exit(main43());
30465
30120
  var _HOOK_FILE = fileURLToPath45(import.meta.url);
30466
30121
 
30467
30122
  // src/scripts/hooks/orchestration_record_hook.ts
@@ -30854,13 +30509,13 @@ if (process.argv[1] !== void 0) {
30854
30509
 
30855
30510
  // src/scripts/hooks/orchestration_record_hook.ts
30856
30511
  var EXIT_ALLOW20 = 0;
30857
- function isObject8(v) {
30512
+ function isObject9(v) {
30858
30513
  return typeof v === "object" && v !== null && !Array.isArray(v);
30859
30514
  }
30860
30515
  var DISPATCH_TOOL_NAMES = /* @__PURE__ */ new Set(["Agent", "Task"]);
30861
30516
  function unwrapPayload2(envelope) {
30862
30517
  const inner = envelope["payload"];
30863
- return isObject8(inner) ? inner : envelope;
30518
+ return isObject9(inner) ? inner : envelope;
30864
30519
  }
30865
30520
  function extractToolName2(payload) {
30866
30521
  const v = payload["tool_name"] ?? payload["toolName"] ?? payload["tool"];
@@ -30868,12 +30523,12 @@ function extractToolName2(payload) {
30868
30523
  }
30869
30524
  function extractToolInput(payload) {
30870
30525
  const v = payload["tool_input"] ?? payload["toolInput"];
30871
- return isObject8(v) ? v : null;
30526
+ return isObject9(v) ? v : null;
30872
30527
  }
30873
30528
  function extractToolResult(payload) {
30874
30529
  for (const key of ["tool_response", "toolResponse", "tool_result", "toolUseResult"]) {
30875
30530
  const v = payload[key];
30876
- if (isObject8(v)) return v;
30531
+ if (isObject9(v)) return v;
30877
30532
  }
30878
30533
  return null;
30879
30534
  }
@@ -30894,7 +30549,7 @@ function extractDispatchFacts(payload) {
30894
30549
  const result = extractToolResult(payload);
30895
30550
  const resolvedModel = result && typeof result["resolvedModel"] === "string" ? result["resolvedModel"] : null;
30896
30551
  let totalTokens = result ? numOrNull(result["totalTokens"]) : null;
30897
- if (totalTokens === null && result && isObject8(result["usage"])) {
30552
+ if (totalTokens === null && result && isObject9(result["usage"])) {
30898
30553
  const usage = result["usage"];
30899
30554
  const inTok = numOrNull(usage["input_tokens"]);
30900
30555
  const outTok = numOrNull(usage["output_tokens"]);
@@ -30955,7 +30610,7 @@ function appendLine(consumerRoot, ts, line) {
30955
30610
  }
30956
30611
  function processEnvelope2(envelope, consumer_root) {
30957
30612
  try {
30958
- if (!isObject8(envelope)) return EXIT_ALLOW20;
30613
+ if (!isObject9(envelope)) return EXIT_ALLOW20;
30959
30614
  const payload = unwrapPayload2(envelope);
30960
30615
  const toolName2 = extractToolName2(payload);
30961
30616
  if (toolName2 === null || !DISPATCH_TOOL_NAMES.has(toolName2)) return EXIT_ALLOW20;
@@ -30972,7 +30627,7 @@ function processEnvelope2(envelope, consumer_root) {
30972
30627
  return EXIT_ALLOW20;
30973
30628
  }
30974
30629
  function _resolveRoot2(envelope) {
30975
- if (isObject8(envelope)) {
30630
+ if (isObject9(envelope)) {
30976
30631
  const cwd = envelope["cwd"];
30977
30632
  if (typeof cwd === "string" && cwd) return cwd;
30978
30633
  const pr = envelope["workspace_root"] ?? envelope["project_root"];
@@ -30990,7 +30645,7 @@ function main45() {
30990
30645
  }
30991
30646
  return processEnvelope2(envelope, _resolveRoot2(envelope));
30992
30647
  }
30993
- function _isCliEntry33() {
30648
+ function _isCliEntry32() {
30994
30649
  if (true) {
30995
30650
  return false;
30996
30651
  }
@@ -31003,7 +30658,7 @@ function _isCliEntry33() {
31003
30658
  return false;
31004
30659
  }
31005
30660
  }
31006
- if (_isCliEntry33()) process.exit(main45());
30661
+ if (_isCliEntry32()) process.exit(main45());
31007
30662
 
31008
30663
  // src/scripts/hooks/telemetry_flush_hook.ts
31009
30664
  import * as fs73 from "node:fs";
@@ -31052,7 +30707,7 @@ function main46() {
31052
30707
  flushFor(_resolveRoot(envelope));
31053
30708
  return EXIT_ALLOW21;
31054
30709
  }
31055
- function _isCliEntry34() {
30710
+ function _isCliEntry33() {
31056
30711
  if (true) {
31057
30712
  return false;
31058
30713
  }
@@ -31065,7 +30720,7 @@ function _isCliEntry34() {
31065
30720
  return false;
31066
30721
  }
31067
30722
  }
31068
- if (_isCliEntry34()) process.exit(main46());
30723
+ if (_isCliEntry33()) process.exit(main46());
31069
30724
 
31070
30725
  // src/scripts/hooks/delegation_nudge_hook.ts
31071
30726
  import fs74 from "node:fs";
@@ -31400,8 +31055,8 @@ function resolveSubagentRouting(inp) {
31400
31055
 
31401
31056
  // src/scripts/hooks/delegation_nudge_hook.ts
31402
31057
  var EXIT_ALLOW22 = 0;
31403
- var EXIT_WARN10 = 2;
31404
- function _isObject15(v) {
31058
+ var EXIT_WARN11 = 2;
31059
+ function _isObject14(v) {
31405
31060
  return typeof v === "object" && v !== null && !Array.isArray(v);
31406
31061
  }
31407
31062
  var FILE_TOKEN_RE = /`?\b[\w][\w.\-]{0,80}\.(ts|tsx|js|jsx|mjs|cjs|py|php|rb|go|rs|java|kt|swift|md|mdx|json|ya?ml|css|scss|less|html|vue|svelte|sql|sh|bash|c|cpp|h|hpp|cs|toml|xml)\b`?/gi;
@@ -31568,13 +31223,13 @@ function main47() {
31568
31223
  } catch {
31569
31224
  return EXIT_ALLOW22;
31570
31225
  }
31571
- const env = _isObject15(envelope) ? envelope : {};
31226
+ const env = _isObject14(envelope) ? envelope : {};
31572
31227
  const event = env["event"];
31573
31228
  const slot = typeof event === "string" && event !== "" ? event : "user_prompt_submit";
31574
31229
  if (slot !== "user_prompt_submit") {
31575
31230
  return EXIT_ALLOW22;
31576
31231
  }
31577
- const payload = _isObject15(env["payload"]) ? env["payload"] : env;
31232
+ const payload = _isObject14(env["payload"]) ? env["payload"] : env;
31578
31233
  const prompt = _extractPrompt2(payload);
31579
31234
  if (!prompt) {
31580
31235
  return EXIT_ALLOW22;
@@ -31597,9 +31252,9 @@ function main47() {
31597
31252
  })}
31598
31253
  `
31599
31254
  );
31600
- return EXIT_WARN10;
31255
+ return EXIT_WARN11;
31601
31256
  }
31602
- function _isCliEntry35() {
31257
+ function _isCliEntry34() {
31603
31258
  if (true) {
31604
31259
  return false;
31605
31260
  }
@@ -31618,7 +31273,7 @@ function _isCliEntry35() {
31618
31273
  return false;
31619
31274
  }
31620
31275
  }
31621
- if (_isCliEntry35()) {
31276
+ if (_isCliEntry34()) {
31622
31277
  process.exit(main47());
31623
31278
  }
31624
31279
 
@@ -32191,7 +31846,7 @@ This is NOT "no skill matches": nothing was read, so no conclusion about skill c
32191
31846
  }
32192
31847
  return 0;
32193
31848
  }
32194
- function _isCliEntry36() {
31849
+ function _isCliEntry35() {
32195
31850
  if (process.argv[1] === void 0) {
32196
31851
  return false;
32197
31852
  }
@@ -32207,18 +31862,18 @@ function _isCliEntry36() {
32207
31862
  return false;
32208
31863
  }
32209
31864
  }
32210
- var _isMain5 = _isCliEntry36();
31865
+ var _isMain5 = _isCliEntry35();
32211
31866
  if (_isMain5) {
32212
31867
  process.exitCode = main48();
32213
31868
  }
32214
31869
 
32215
31870
  // src/scripts/hooks/skill_route_hook.ts
32216
31871
  var EXIT_ALLOW23 = 0;
32217
- var EXIT_WARN11 = 2;
31872
+ var EXIT_WARN12 = 2;
32218
31873
  var MIN_TOP_SCORE = 31;
32219
31874
  var MIN_TASK_TERMS = 3;
32220
31875
  var TOP_K = 3;
32221
- function _isObject16(v) {
31876
+ function _isObject15(v) {
32222
31877
  return typeof v === "object" && v !== null && !Array.isArray(v);
32223
31878
  }
32224
31879
  function knownBareForHost(workspaceRoot3, host) {
@@ -32284,11 +31939,11 @@ function main49() {
32284
31939
  } catch {
32285
31940
  return EXIT_ALLOW23;
32286
31941
  }
32287
- const env = _isObject16(envelope) ? envelope : {};
31942
+ const env = _isObject15(envelope) ? envelope : {};
32288
31943
  const event = env["event"];
32289
31944
  const slot = typeof event === "string" && event !== "" ? event : "user_prompt_submit";
32290
31945
  if (slot !== "user_prompt_submit") return EXIT_ALLOW23;
32291
- const payload = _isObject16(env["payload"]) ? env["payload"] : env;
31946
+ const payload = _isObject15(env["payload"]) ? env["payload"] : env;
32292
31947
  const prompt = _extractPrompt3(payload);
32293
31948
  if (!prompt) return EXIT_ALLOW23;
32294
31949
  if (isSyntheticPrompt(prompt)) return EXIT_ALLOW23;
@@ -32311,9 +31966,9 @@ function main49() {
32311
31966
  })}
32312
31967
  `
32313
31968
  );
32314
- return EXIT_WARN11;
31969
+ return EXIT_WARN12;
32315
31970
  }
32316
- function _isCliEntry37() {
31971
+ function _isCliEntry36() {
32317
31972
  if (true) return false;
32318
31973
  if (process.argv[1] === void 0) return false;
32319
31974
  const argvUrl = pathToFileURL44(path77.resolve(process.argv[1])).href;
@@ -32326,7 +31981,7 @@ function _isCliEntry37() {
32326
31981
  return false;
32327
31982
  }
32328
31983
  }
32329
- if (_isCliEntry37()) {
31984
+ if (_isCliEntry36()) {
32330
31985
  process.exit(main49());
32331
31986
  }
32332
31987
 
@@ -32617,10 +32272,10 @@ function selectForInjection(repoRoot, matches, capBytes, shortlist) {
32617
32272
 
32618
32273
  // src/scripts/hooks/rule_inject_hook.ts
32619
32274
  var EXIT_ALLOW24 = 0;
32620
- var EXIT_WARN12 = 2;
32275
+ var EXIT_WARN13 = 2;
32621
32276
  var CAP_BYTES = 20480;
32622
32277
  var FILE_TOOLS = /* @__PURE__ */ new Set(["Write", "Edit", "NotebookEdit", "Read", "MultiEdit"]);
32623
- function isObject9(v) {
32278
+ function isObject10(v) {
32624
32279
  return typeof v === "object" && v !== null && !Array.isArray(v);
32625
32280
  }
32626
32281
  function str5(o, ...keys) {
@@ -32668,7 +32323,7 @@ function extractPrompt(payload) {
32668
32323
  }
32669
32324
  function extractFilePath(payload) {
32670
32325
  const ti = payload["tool_input"] ?? payload["toolInput"] ?? payload["input"];
32671
- if (!isObject9(ti)) return null;
32326
+ if (!isObject10(ti)) return null;
32672
32327
  return str5(ti, "file_path", "path", "filePath", "notebook_path");
32673
32328
  }
32674
32329
  function buildInjection(root, prompt, openFiles, command, seen) {
@@ -32713,12 +32368,12 @@ function main50(argv = process12.argv.slice(2)) {
32713
32368
  try {
32714
32369
  const raw = readHookStdin();
32715
32370
  const parsed = raw.trim() ? JSON.parse(raw) : {};
32716
- env = isObject9(parsed) ? parsed : {};
32371
+ env = isObject10(parsed) ? parsed : {};
32717
32372
  } catch {
32718
32373
  return EXIT_ALLOW24;
32719
32374
  }
32720
32375
  const root = workspaceRoot2(env);
32721
- const payload = isObject9(env["payload"]) ? env["payload"] : env;
32376
+ const payload = isObject10(env["payload"]) ? env["payload"] : env;
32722
32377
  const slot = eventOverride ?? str5(env, "event") ?? "user_prompt_submit";
32723
32378
  const session = str5(env, "session_id", "sessionId") ?? str5(payload, "session_id", "sessionId") ?? "unknown";
32724
32379
  if (slot === "pre_compact") {
@@ -32726,7 +32381,7 @@ function main50(argv = process12.argv.slice(2)) {
32726
32381
  return EXIT_ALLOW24;
32727
32382
  }
32728
32383
  if (slot !== "user_prompt_submit" && slot !== "pre_tool_use") return EXIT_ALLOW24;
32729
- if (!gateOpen(root, _isCliEntry38())) return EXIT_ALLOW24;
32384
+ if (!gateOpen(root, _isCliEntry37())) return EXIT_ALLOW24;
32730
32385
  let prompt = "";
32731
32386
  let openFiles = null;
32732
32387
  let command = null;
@@ -32755,9 +32410,9 @@ function main50(argv = process12.argv.slice(2)) {
32755
32410
  })}
32756
32411
  `
32757
32412
  );
32758
- return EXIT_WARN12;
32413
+ return EXIT_WARN13;
32759
32414
  }
32760
- function _isCliEntry38() {
32415
+ function _isCliEntry37() {
32761
32416
  if (true) return false;
32762
32417
  if (process12.argv[1] === void 0) return false;
32763
32418
  const argvUrl = pathToFileURL45(path79.resolve(process12.argv[1])).href;
@@ -32768,7 +32423,7 @@ function _isCliEntry38() {
32768
32423
  return false;
32769
32424
  }
32770
32425
  }
32771
- if (_isCliEntry38()) {
32426
+ if (_isCliEntry37()) {
32772
32427
  process12.exit(main50());
32773
32428
  }
32774
32429
 
@@ -32847,7 +32502,7 @@ function isSafeTranscriptPath(rawPath, opts = {}) {
32847
32502
  return false;
32848
32503
  }
32849
32504
  }
32850
- var EXIT_WARN13 = 2;
32505
+ var EXIT_WARN14 = 2;
32851
32506
  function parseNumstat(raw) {
32852
32507
  const rows = [];
32853
32508
  for (const line of raw.split("\n")) {
@@ -32932,7 +32587,7 @@ function totalNonDocMutatedLinesWithMeasure(cwd) {
32932
32587
  );
32933
32588
  return { lines: trackedLines + untrackedLines, measure: "exact" };
32934
32589
  }
32935
- function isObject10(v) {
32590
+ function isObject11(v) {
32936
32591
  return typeof v === "object" && v !== null && !Array.isArray(v);
32937
32592
  }
32938
32593
  function str6(v) {
@@ -32952,16 +32607,16 @@ function scanTranscriptForReviewer(transcriptText) {
32952
32607
  } catch {
32953
32608
  continue;
32954
32609
  }
32955
- if (!isObject10(obj) || obj["type"] !== "assistant") continue;
32610
+ if (!isObject11(obj) || obj["type"] !== "assistant") continue;
32956
32611
  const msg = obj["message"];
32957
- if (!isObject10(msg)) continue;
32612
+ if (!isObject11(msg)) continue;
32958
32613
  const content = msg["content"];
32959
32614
  if (!Array.isArray(content)) continue;
32960
32615
  for (const blk of content) {
32961
- if (!isObject10(blk) || blk["type"] !== "tool_use") continue;
32616
+ if (!isObject11(blk) || blk["type"] !== "tool_use") continue;
32962
32617
  const name = str6(blk["name"]);
32963
32618
  const input = blk["input"];
32964
- const inputObj = isObject10(input) ? input : {};
32619
+ const inputObj = isObject11(input) ? input : {};
32965
32620
  if (DISPATCH_TOOL_RE.test(name)) {
32966
32621
  const label = [
32967
32622
  str6(inputObj["description"]),
@@ -33081,9 +32736,9 @@ function main51() {
33081
32736
  })}
33082
32737
  `
33083
32738
  );
33084
- return EXIT_WARN13;
32739
+ return EXIT_WARN14;
33085
32740
  }
33086
- function _isCliEntry39() {
32741
+ function _isCliEntry38() {
33087
32742
  if (true) {
33088
32743
  return false;
33089
32744
  }
@@ -33102,7 +32757,7 @@ function _isCliEntry39() {
33102
32757
  return false;
33103
32758
  }
33104
32759
  }
33105
- if (_isCliEntry39()) {
32760
+ if (_isCliEntry38()) {
33106
32761
  process.exit(main51());
33107
32762
  }
33108
32763
 
@@ -33218,7 +32873,7 @@ function validateResponse(input) {
33218
32873
 
33219
32874
  // src/scripts/hooks/subagent_ledger_hook.ts
33220
32875
  var EXIT_ALLOW25 = 0;
33221
- function isObject11(v) {
32876
+ function isObject12(v) {
33222
32877
  return typeof v === "object" && v !== null && !Array.isArray(v);
33223
32878
  }
33224
32879
  var LEDGER_DIR = path81.join("agents", "runtime", "state", "subagent-ledger");
@@ -33229,7 +32884,7 @@ function refFor(agentId) {
33229
32884
  }
33230
32885
  function unwrapPayload3(envelope) {
33231
32886
  const inner = envelope["payload"];
33232
- return isObject11(inner) ? inner : envelope;
32887
+ return isObject12(inner) ? inner : envelope;
33233
32888
  }
33234
32889
  function str7(payload, ...keys) {
33235
32890
  for (const k of keys) {
@@ -33242,7 +32897,7 @@ function extractParentId(payload, ownId) {
33242
32897
  const explicit = str7(payload, "parent_agent_id", "parentAgentId");
33243
32898
  if (explicit) return explicit;
33244
32899
  const session = payload["session"];
33245
- if (isObject11(session)) {
32900
+ if (isObject12(session)) {
33246
32901
  const sessionAgent = str7(session, "agent_id", "agentId");
33247
32902
  if (sessionAgent && sessionAgent !== ownId) return sessionAgent;
33248
32903
  }
@@ -33318,7 +32973,7 @@ function openFile(root, ref) {
33318
32973
  }
33319
32974
  var DEPTH_BASES = /* @__PURE__ */ new Set(["observed", "asserted-parent", "assumed-root"]);
33320
32975
  function _asOpenRecord(value, expectedRef) {
33321
- if (!isObject11(value)) return null;
32976
+ if (!isObject12(value)) return null;
33322
32977
  const ref = value["ref"];
33323
32978
  if (typeof ref !== "string" || ref !== expectedRef) return null;
33324
32979
  if (typeof value["started_at"] !== "string") return null;
@@ -33545,7 +33200,7 @@ function handleStop(root, payload, nowIso, sessionId2) {
33545
33200
  }
33546
33201
  function processEnvelope3(envelope, consumerRoot) {
33547
33202
  try {
33548
- if (!isObject11(envelope)) return EXIT_ALLOW25;
33203
+ if (!isObject12(envelope)) return EXIT_ALLOW25;
33549
33204
  const event = envelope["event"];
33550
33205
  if (event !== "subagent_start" && event !== "subagent_stop") return EXIT_ALLOW25;
33551
33206
  const payload = unwrapPayload3(envelope);
@@ -33560,7 +33215,7 @@ function processEnvelope3(envelope, consumerRoot) {
33560
33215
  return EXIT_ALLOW25;
33561
33216
  }
33562
33217
  function resolveConsumerRoot(envelope) {
33563
- if (isObject11(envelope)) {
33218
+ if (isObject12(envelope)) {
33564
33219
  const pr = str7(envelope, "workspace_root", "project_root");
33565
33220
  if (pr) return pr;
33566
33221
  const payload = unwrapPayload3(envelope);
@@ -33579,7 +33234,7 @@ function main52() {
33579
33234
  }
33580
33235
  return processEnvelope3(envelope, resolveConsumerRoot(envelope));
33581
33236
  }
33582
- function _isCliEntry40() {
33237
+ function _isCliEntry39() {
33583
33238
  if (true) {
33584
33239
  return false;
33585
33240
  }
@@ -33592,10 +33247,10 @@ function _isCliEntry40() {
33592
33247
  return false;
33593
33248
  }
33594
33249
  }
33595
- if (_isCliEntry40()) process.exit(main52());
33250
+ if (_isCliEntry39()) process.exit(main52());
33596
33251
 
33597
33252
  // src/scripts/hooks/turn_end_gate_hook.ts
33598
- var EXIT_BLOCK4 = 1;
33253
+ var EXIT_BLOCK3 = 1;
33599
33254
  var EXIT_ALLOW26 = 0;
33600
33255
  var TRANSCRIPT_READ_MAX_BYTES = 8 * 1024 * 1024;
33601
33256
  function stripFencedBlocks(text) {
@@ -33979,9 +33634,9 @@ ${lines.join("\n")}
33979
33634
  This turn will not be refused a second time.
33980
33635
  `
33981
33636
  );
33982
- return EXIT_BLOCK4;
33637
+ return EXIT_BLOCK3;
33983
33638
  }
33984
- function _isCliEntry41() {
33639
+ function _isCliEntry40() {
33985
33640
  if (true) {
33986
33641
  return false;
33987
33642
  }
@@ -34000,7 +33655,7 @@ function _isCliEntry41() {
34000
33655
  return false;
34001
33656
  }
34002
33657
  }
34003
- if (_isCliEntry41()) {
33658
+ if (_isCliEntry40()) {
34004
33659
  process.exit(main53());
34005
33660
  }
34006
33661
 
@@ -34011,7 +33666,7 @@ import * as fs83 from "node:fs";
34011
33666
  import * as path83 from "node:path";
34012
33667
  import { fileURLToPath as fileURLToPath55, pathToFileURL as pathToFileURL49 } from "node:url";
34013
33668
  var EXIT_ALLOW27 = 0;
34014
- var EXIT_WARN14 = 2;
33669
+ var EXIT_WARN15 = 2;
34015
33670
  var MIN_FILE_LINES = 50;
34016
33671
  var MAX_DIFF_RATIO = 0.2;
34017
33672
  var EXEMPT_PATH_PATTERNS = [
@@ -34026,7 +33681,7 @@ var EXEMPT_PATH_PATTERNS = [
34026
33681
  /(^|\/)agents\/runtime\//i
34027
33682
  // agents/runtime/**
34028
33683
  ];
34029
- function isObject12(v) {
33684
+ function isObject13(v) {
34030
33685
  return typeof v === "object" && v !== null && !Array.isArray(v);
34031
33686
  }
34032
33687
  function str9(v) {
@@ -34101,7 +33756,7 @@ function extractToolName3(payload) {
34101
33756
  }
34102
33757
  function extractFilePath2(payload) {
34103
33758
  const ti = payload["tool_input"] ?? payload["toolInput"] ?? payload["input"];
34104
- if (!isObject12(ti)) return "";
33759
+ if (!isObject13(ti)) return "";
34105
33760
  return str9(ti["file_path"] ?? ti["path"] ?? ti["filePath"]);
34106
33761
  }
34107
33762
  function main54() {
@@ -34133,12 +33788,12 @@ function main54() {
34133
33788
  })}
34134
33789
  `
34135
33790
  );
34136
- return EXIT_WARN14;
33791
+ return EXIT_WARN15;
34137
33792
  } catch {
34138
33793
  return EXIT_ALLOW27;
34139
33794
  }
34140
33795
  }
34141
- function _isCliEntry42() {
33796
+ function _isCliEntry41() {
34142
33797
  if (true) {
34143
33798
  return false;
34144
33799
  }
@@ -34157,7 +33812,7 @@ function _isCliEntry42() {
34157
33812
  return false;
34158
33813
  }
34159
33814
  }
34160
- if (_isCliEntry42()) {
33815
+ if (_isCliEntry41()) {
34161
33816
  process.exit(main54());
34162
33817
  }
34163
33818
 
@@ -34825,12 +34480,12 @@ if (_isMain6) process14.exit(main55(process14.argv.slice(2)));
34825
34480
 
34826
34481
  // src/scripts/hooks/comment_discipline_hook.ts
34827
34482
  var EXIT_ALLOW28 = 0;
34828
- var EXIT_WARN15 = 2;
34483
+ var EXIT_WARN16 = 2;
34829
34484
  var MAX_REPORTED = 3;
34830
34485
  function str10(v) {
34831
34486
  return typeof v === "string" ? v : "";
34832
34487
  }
34833
- function isObject13(v) {
34488
+ function isObject14(v) {
34834
34489
  return typeof v === "object" && v !== null && !Array.isArray(v);
34835
34490
  }
34836
34491
  function writtenText(toolName2, toolInput) {
@@ -34858,7 +34513,7 @@ function main56() {
34858
34513
  );
34859
34514
  if (toolName2 !== "Write" && toolName2 !== "Edit") return EXIT_ALLOW28;
34860
34515
  const ti = payload["tool_input"] ?? payload["toolInput"] ?? payload["input"];
34861
- if (!isObject13(ti)) return EXIT_ALLOW28;
34516
+ if (!isObject14(ti)) return EXIT_ALLOW28;
34862
34517
  const filePath = str10(ti["file_path"] ?? ti["path"] ?? ti["filePath"]);
34863
34518
  if (!filePath || !isScannable(filePath)) return EXIT_ALLOW28;
34864
34519
  const text = writtenText(toolName2, ti);
@@ -34877,12 +34532,12 @@ function main56() {
34877
34532
  })}
34878
34533
  `
34879
34534
  );
34880
- return EXIT_WARN15;
34535
+ return EXIT_WARN16;
34881
34536
  } catch {
34882
34537
  return EXIT_ALLOW28;
34883
34538
  }
34884
34539
  }
34885
- function _isCliEntry43() {
34540
+ function _isCliEntry42() {
34886
34541
  if (true) return false;
34887
34542
  if (process.argv[1] === void 0) return false;
34888
34543
  const argvUrl = pathToFileURL50(path86.resolve(process.argv[1])).href;
@@ -34893,7 +34548,7 @@ function _isCliEntry43() {
34893
34548
  return false;
34894
34549
  }
34895
34550
  }
34896
- if (_isCliEntry43()) process.exit(main56());
34551
+ if (_isCliEntry42()) process.exit(main56());
34897
34552
 
34898
34553
  // src/scripts/hooks/reread_guard_hook.ts
34899
34554
  import * as crypto12 from "node:crypto";
@@ -34901,7 +34556,7 @@ import * as fs86 from "node:fs";
34901
34556
  import * as path87 from "node:path";
34902
34557
  import { fileURLToPath as fileURLToPath58, pathToFileURL as pathToFileURL51 } from "node:url";
34903
34558
  var EXIT_ALLOW29 = 0;
34904
- var EXIT_WARN16 = 2;
34559
+ var EXIT_WARN17 = 2;
34905
34560
  var EXEMPT_PATH_PATTERNS2 = [
34906
34561
  /(^|\/)dist\//i,
34907
34562
  // dist/**
@@ -34916,7 +34571,7 @@ var EXEMPT_PATH_PATTERNS2 = [
34916
34571
  ];
34917
34572
  var READ_TOOLS = /* @__PURE__ */ new Set(["Read"]);
34918
34573
  var WRITE_TOOLS2 = /* @__PURE__ */ new Set(["Edit", "Write"]);
34919
- function isObject14(v) {
34574
+ function isObject15(v) {
34920
34575
  return typeof v === "object" && v !== null && !Array.isArray(v);
34921
34576
  }
34922
34577
  function str11(v) {
@@ -34940,11 +34595,11 @@ function ledgerFile(workspaceRoot3, sessionKey) {
34940
34595
  function readLedger(workspaceRoot3, sessionKey) {
34941
34596
  try {
34942
34597
  const parsed = JSON.parse(fs86.readFileSync(ledgerFile(workspaceRoot3, sessionKey), "utf8"));
34943
- if (!isObject14(parsed)) return emptyLedger();
34598
+ if (!isObject15(parsed)) return emptyLedger();
34944
34599
  return {
34945
- reads: isObject14(parsed["reads"]) ? parsed["reads"] : {},
34946
- writes: isObject14(parsed["writes"]) ? parsed["writes"] : {},
34947
- fired: isObject14(parsed["fired"]) ? parsed["fired"] : {}
34600
+ reads: isObject15(parsed["reads"]) ? parsed["reads"] : {},
34601
+ writes: isObject15(parsed["writes"]) ? parsed["writes"] : {},
34602
+ fired: isObject15(parsed["fired"]) ? parsed["fired"] : {}
34948
34603
  };
34949
34604
  } catch {
34950
34605
  return emptyLedger();
@@ -34961,7 +34616,7 @@ function extractToolName4(payload) {
34961
34616
  }
34962
34617
  function extractToolInput2(payload) {
34963
34618
  const ti = payload["tool_input"] ?? payload["toolInput"] ?? payload["input"];
34964
- return isObject14(ti) ? ti : {};
34619
+ return isObject15(ti) ? ti : {};
34965
34620
  }
34966
34621
  function extractFilePath3(toolInput) {
34967
34622
  return str11(toolInput["file_path"] ?? toolInput["path"] ?? toolInput["filePath"]);
@@ -35038,12 +34693,12 @@ function main57() {
35038
34693
  })}
35039
34694
  `
35040
34695
  );
35041
- return EXIT_WARN16;
34696
+ return EXIT_WARN17;
35042
34697
  } catch {
35043
34698
  return EXIT_ALLOW29;
35044
34699
  }
35045
34700
  }
35046
- function _isCliEntry44() {
34701
+ function _isCliEntry43() {
35047
34702
  if (true) {
35048
34703
  return false;
35049
34704
  }
@@ -35062,7 +34717,7 @@ function _isCliEntry44() {
35062
34717
  return false;
35063
34718
  }
35064
34719
  }
35065
- if (_isCliEntry44()) {
34720
+ if (_isCliEntry43()) {
35066
34721
  process.exit(main57());
35067
34722
  }
35068
34723
 
@@ -35473,7 +35128,7 @@ function writeCheckpoint(repoRoot, cp) {
35473
35128
  }
35474
35129
 
35475
35130
  // src/scripts/hooks/session_eol_hook.ts
35476
- var EXIT_WARN17 = 2;
35131
+ var EXIT_WARN18 = 2;
35477
35132
  var THRESHOLD_OVERRIDE_ENV = "AGENT_RECYCLE_THRESHOLD_TOKENS";
35478
35133
  var CONTEXT_FILL_REL = path93.join("agents", "runtime", "state", "context-fill.json");
35479
35134
  function str12(value) {
@@ -35625,7 +35280,7 @@ function main58() {
35625
35280
  })}
35626
35281
  `
35627
35282
  );
35628
- return EXIT_WARN17;
35283
+ return EXIT_WARN18;
35629
35284
  }
35630
35285
  if (shouldWarnMissing) {
35631
35286
  process15.stdout.write(
@@ -35636,11 +35291,11 @@ function main58() {
35636
35291
  })}
35637
35292
  `
35638
35293
  );
35639
- return EXIT_WARN17;
35294
+ return EXIT_WARN18;
35640
35295
  }
35641
35296
  return 0;
35642
35297
  }
35643
- function _isCliEntry45() {
35298
+ function _isCliEntry44() {
35644
35299
  if (true) {
35645
35300
  return false;
35646
35301
  }
@@ -35659,7 +35314,7 @@ function _isCliEntry45() {
35659
35314
  return false;
35660
35315
  }
35661
35316
  }
35662
- if (_isCliEntry45()) {
35317
+ if (_isCliEntry44()) {
35663
35318
  process15.exit(main58());
35664
35319
  }
35665
35320
 
@@ -35668,7 +35323,7 @@ import * as fs92 from "node:fs";
35668
35323
  import * as path94 from "node:path";
35669
35324
  import { fileURLToPath as fileURLToPath60, pathToFileURL as pathToFileURL53 } from "node:url";
35670
35325
  var EXIT_ALLOW30 = 0;
35671
- function isObject15(v) {
35326
+ function isObject16(v) {
35672
35327
  return typeof v === "object" && v !== null && !Array.isArray(v);
35673
35328
  }
35674
35329
  var CENSUS_FILE = path94.join("agents", "runtime", "state", "tool-result-census.jsonl");
@@ -35703,7 +35358,7 @@ function _toolName(payload, envelope) {
35703
35358
  }
35704
35359
  function unwrapPayload4(envelope) {
35705
35360
  const inner = envelope["payload"];
35706
- return isObject15(inner) ? inner : envelope;
35361
+ return isObject16(inner) ? inner : envelope;
35707
35362
  }
35708
35363
  function censusFile(consumerRoot) {
35709
35364
  return path94.join(consumerRoot, CENSUS_FILE);
@@ -35717,7 +35372,7 @@ function _appendCensusLine(consumerRoot, line) {
35717
35372
  }
35718
35373
  function processEnvelope4(envelope, consumerRoot) {
35719
35374
  try {
35720
- if (!isObject15(envelope)) return EXIT_ALLOW30;
35375
+ if (!isObject16(envelope)) return EXIT_ALLOW30;
35721
35376
  if (envelope["event"] !== "post_tool_use") return EXIT_ALLOW30;
35722
35377
  const payload = unwrapPayload4(envelope);
35723
35378
  const bytes = _resultBytes(payload);
@@ -35733,7 +35388,7 @@ function processEnvelope4(envelope, consumerRoot) {
35733
35388
  return EXIT_ALLOW30;
35734
35389
  }
35735
35390
  function resolveConsumerRoot2(envelope) {
35736
- if (isObject15(envelope)) {
35391
+ if (isObject16(envelope)) {
35737
35392
  for (const key of ["workspace_root", "project_root"]) {
35738
35393
  const v = envelope[key];
35739
35394
  if (typeof v === "string" && v) return v;
@@ -35753,7 +35408,7 @@ function main59() {
35753
35408
  }
35754
35409
  return processEnvelope4(envelope, resolveConsumerRoot2(envelope));
35755
35410
  }
35756
- function _isCliEntry46() {
35411
+ function _isCliEntry45() {
35757
35412
  if (true) {
35758
35413
  return false;
35759
35414
  }
@@ -35766,14 +35421,14 @@ function _isCliEntry46() {
35766
35421
  return false;
35767
35422
  }
35768
35423
  }
35769
- if (_isCliEntry46()) process.exit(main59());
35424
+ if (_isCliEntry45()) process.exit(main59());
35770
35425
 
35771
35426
  // src/scripts/hooks/spawn_guard_shadow_hook.ts
35772
35427
  import * as fs93 from "node:fs";
35773
35428
  import * as path95 from "node:path";
35774
35429
  import { fileURLToPath as fileURLToPath61, pathToFileURL as pathToFileURL54 } from "node:url";
35775
35430
  var EXIT_ALLOW31 = 0;
35776
- function isObject16(v) {
35431
+ function isObject17(v) {
35777
35432
  return typeof v === "object" && v !== null && !Array.isArray(v);
35778
35433
  }
35779
35434
  var DISPATCH_TOOL_NAMES2 = /* @__PURE__ */ new Set(["Agent", "Task"]);
@@ -35792,7 +35447,7 @@ function evaluateCandidates(depthEstimate, concurrentOpen) {
35792
35447
  }
35793
35448
  function unwrapPayload5(envelope) {
35794
35449
  const inner = envelope["payload"];
35795
- return isObject16(inner) ? inner : envelope;
35450
+ return isObject17(inner) ? inner : envelope;
35796
35451
  }
35797
35452
  function extractToolName5(payload) {
35798
35453
  const v = payload["tool_name"] ?? payload["toolName"] ?? payload["tool"];
@@ -35800,7 +35455,7 @@ function extractToolName5(payload) {
35800
35455
  }
35801
35456
  function processEnvelope5(envelope, consumerRoot) {
35802
35457
  try {
35803
- if (!isObject16(envelope)) return EXIT_ALLOW31;
35458
+ if (!isObject17(envelope)) return EXIT_ALLOW31;
35804
35459
  const payload = unwrapPayload5(envelope);
35805
35460
  const toolName2 = extractToolName5(payload);
35806
35461
  if (toolName2 === null || !DISPATCH_TOOL_NAMES2.has(toolName2)) return EXIT_ALLOW31;
@@ -35845,7 +35500,7 @@ function main60() {
35845
35500
  }
35846
35501
  return processEnvelope5(envelope, resolveConsumerRoot(envelope));
35847
35502
  }
35848
- function _isCliEntry47() {
35503
+ function _isCliEntry46() {
35849
35504
  if (true) return false;
35850
35505
  if (process.argv[1] === void 0) return false;
35851
35506
  const argvUrl = pathToFileURL54(path95.resolve(process.argv[1])).href;
@@ -35856,7 +35511,7 @@ function _isCliEntry47() {
35856
35511
  return false;
35857
35512
  }
35858
35513
  }
35859
- if (_isCliEntry47()) process.exit(main60());
35514
+ if (_isCliEntry46()) process.exit(main60());
35860
35515
 
35861
35516
  // src/scripts/hooks/source_first_gate_hook.ts
35862
35517
  import * as fs94 from "node:fs";
@@ -35866,12 +35521,12 @@ var EXIT_ALLOW32 = 0;
35866
35521
  var MAX_SHADOW_WARNS = 2;
35867
35522
  var SHADOW_LOG = path96.join("agents", "runtime", "state", "source-first-gate.jsonl");
35868
35523
  var STATE_FILE9 = path96.join("agents", "runtime", "state", "source-first-gate.json");
35869
- function isObject17(v) {
35524
+ function isObject18(v) {
35870
35525
  return typeof v === "object" && v !== null && !Array.isArray(v);
35871
35526
  }
35872
35527
  function unwrapPayload6(envelope) {
35873
35528
  const inner = envelope["payload"];
35874
- return isObject17(inner) ? inner : envelope;
35529
+ return isObject18(inner) ? inner : envelope;
35875
35530
  }
35876
35531
  var TOOL_MATCHERS = [
35877
35532
  { pattern: /^browser_take_screenshot$/i, hit: { label: "playwright-mcp", capture_kind: "page" } },
@@ -35899,11 +35554,11 @@ function str13(o, ...keys) {
35899
35554
  return null;
35900
35555
  }
35901
35556
  function extractEvent2(outer) {
35902
- if (!isObject17(outer)) return null;
35557
+ if (!isObject18(outer)) return null;
35903
35558
  const payload = unwrapPayload6(outer);
35904
35559
  const toolName2 = str13(payload, "tool_name", "toolName", "tool");
35905
35560
  const ti = payload["tool_input"] ?? payload["toolInput"] ?? payload["input"];
35906
- const input = isObject17(ti) ? ti : {};
35561
+ const input = isObject18(ti) ? ti : {};
35907
35562
  const file = str13(input, "file_path", "path", "filePath") ?? "";
35908
35563
  let isWrite = false;
35909
35564
  for (const key of ["content", "new_string", "new_str", "text", "newText"]) {
@@ -35957,7 +35612,7 @@ function writeState4(root, session, state) {
35957
35612
  all = JSON.parse(fs94.readFileSync(file, "utf-8"));
35958
35613
  } catch {
35959
35614
  }
35960
- if (!isObject17(all)) all = {};
35615
+ if (!isObject18(all)) all = {};
35961
35616
  all[session] = state;
35962
35617
  const keys = Object.keys(all);
35963
35618
  if (keys.length > MAX_SESSIONS2) {
@@ -36066,11 +35721,11 @@ function main61() {
36066
35721
  } catch {
36067
35722
  return EXIT_ALLOW32;
36068
35723
  }
36069
- const sessionVal = isObject17(envelope) ? envelope["session_id"] : null;
35724
+ const sessionVal = isObject18(envelope) ? envelope["session_id"] : null;
36070
35725
  const session = typeof sessionVal === "string" && sessionVal ? sessionVal : "unknown";
36071
35726
  return processEnvelope6(envelope, resolveConsumerRoot(envelope), session);
36072
35727
  }
36073
- function _isCliEntry48() {
35728
+ function _isCliEntry47() {
36074
35729
  if (true) return false;
36075
35730
  if (process.argv[1] === void 0) return false;
36076
35731
  const argvUrl = pathToFileURL55(path96.resolve(process.argv[1])).href;
@@ -36081,7 +35736,7 @@ function _isCliEntry48() {
36081
35736
  return false;
36082
35737
  }
36083
35738
  }
36084
- if (_isCliEntry48()) process.exit(main61());
35739
+ if (_isCliEntry47()) process.exit(main61());
36085
35740
 
36086
35741
  // src/scripts/hooks/interruption_ledger_hook.ts
36087
35742
  import * as fs95 from "node:fs";
@@ -36194,7 +35849,7 @@ function main62() {
36194
35849
  }
36195
35850
  return EXIT_OK2;
36196
35851
  }
36197
- function _isCliEntry49() {
35852
+ function _isCliEntry48() {
36198
35853
  if (process.argv[1] === void 0) {
36199
35854
  return false;
36200
35855
  }
@@ -36210,7 +35865,7 @@ function _isCliEntry49() {
36210
35865
  return false;
36211
35866
  }
36212
35867
  }
36213
- if (_isCliEntry49()) {
35868
+ if (_isCliEntry48()) {
36214
35869
  process.exit(main62());
36215
35870
  }
36216
35871
 
@@ -36325,7 +35980,7 @@ function parseHaltStamp(v) {
36325
35980
 
36326
35981
  // src/scripts/hooks/run_continuation_hook.ts
36327
35982
  var EXIT_ALLOW33 = 0;
36328
- var EXIT_BLOCK5 = 1;
35983
+ var EXIT_BLOCK4 = 1;
36329
35984
  var BLOCKED_BY_MARKER = /<!--\s*blocked-by:\s*\S[^>]*-->/;
36330
35985
  var LEDGER_TAIL_MAX_BYTES = 512 * 1024;
36331
35986
  var EVENTS_RELPATH = path99.join(
@@ -36739,7 +36394,7 @@ function main63() {
36739
36394
  const scan = scanOpenSteps(roadmapText);
36740
36395
  if (isDuplicateFire(prev, turnOrdinal, scan.open, Date.now(), roadmapFile)) {
36741
36396
  process.stderr.write(_continuationText(slug, scan, state.iterations));
36742
- return EXIT_BLOCK5;
36397
+ return EXIT_BLOCK4;
36743
36398
  }
36744
36399
  if (state.history_source !== roadmapFile) {
36745
36400
  state.history = [];
@@ -36816,7 +36471,7 @@ function main63() {
36816
36471
  ...roots
36817
36472
  });
36818
36473
  process.stderr.write(_continuationText(slug, scan, state.iterations));
36819
- return EXIT_BLOCK5;
36474
+ return EXIT_BLOCK4;
36820
36475
  }
36821
36476
  function _continuationText(slug, scan, iteration) {
36822
36477
  const stepLine = scan.next ? `Next step: ${scan.next.text}` + (scan.next.verify ? `
@@ -36826,7 +36481,7 @@ ${stepLine}
36826
36481
  Continue with this step now: do the work, run its verify line, flip the box, then end the turn. Escalate instead of continuing ONLY for a locked decision class (high_impact / user_required) or a halt your contract names.
36827
36482
  `;
36828
36483
  }
36829
- function _isCliEntry50() {
36484
+ function _isCliEntry49() {
36830
36485
  if (true) {
36831
36486
  return false;
36832
36487
  }
@@ -36841,7 +36496,7 @@ function _isCliEntry50() {
36841
36496
  return false;
36842
36497
  }
36843
36498
  }
36844
- if (_isCliEntry50()) {
36499
+ if (_isCliEntry49()) {
36845
36500
  process.exit(main63());
36846
36501
  }
36847
36502
 
@@ -37216,12 +36871,12 @@ function recordEvent(h, input) {
37216
36871
  // src/scripts/hooks/journal_record_hook.ts
37217
36872
  var EXIT_ALLOW34 = 0;
37218
36873
  var SETTINGS_SECTION = "runtime_journal";
37219
- function isObject18(v) {
36874
+ function isObject19(v) {
37220
36875
  return typeof v === "object" && v !== null && !Array.isArray(v);
37221
36876
  }
37222
36877
  function unwrapPayload7(envelope) {
37223
36878
  const inner = envelope["payload"];
37224
- return isObject18(inner) ? inner : envelope;
36879
+ return isObject19(inner) ? inner : envelope;
37225
36880
  }
37226
36881
  function firstString(envelope, payload, keys) {
37227
36882
  for (const source of [envelope, payload]) {
@@ -37264,7 +36919,7 @@ function reduceEnvelope(envelope) {
37264
36919
  };
37265
36920
  }
37266
36921
  function resolveConsumerRoot3(envelope) {
37267
- if (isObject18(envelope)) {
36922
+ if (isObject19(envelope)) {
37268
36923
  for (const key of ["workspace_root", "project_root"]) {
37269
36924
  const v = envelope[key];
37270
36925
  if (typeof v === "string" && v) return v;
@@ -37276,7 +36931,7 @@ function resolveConsumerRoot3(envelope) {
37276
36931
  }
37277
36932
  function processEnvelope7(envelope, consumerRoot) {
37278
36933
  try {
37279
- if (!isObject18(envelope)) return EXIT_ALLOW34;
36934
+ if (!isObject19(envelope)) return EXIT_ALLOW34;
37280
36935
  if (is_replay_mode()) return EXIT_ALLOW34;
37281
36936
  if (!hookSectionEnabled(consumerRoot, SETTINGS_SECTION)) return EXIT_ALLOW34;
37282
36937
  if (!isJournalAvailable()) return EXIT_ALLOW34;
@@ -37306,7 +36961,7 @@ function main64() {
37306
36961
  }
37307
36962
  return processEnvelope7(envelope, resolveConsumerRoot3(envelope));
37308
36963
  }
37309
- function _isCliEntry51() {
36964
+ function _isCliEntry50() {
37310
36965
  if (true) {
37311
36966
  return false;
37312
36967
  }
@@ -37319,7 +36974,7 @@ function _isCliEntry51() {
37319
36974
  return false;
37320
36975
  }
37321
36976
  }
37322
- if (_isCliEntry51()) process.exit(main64());
36977
+ if (_isCliEntry50()) process.exit(main64());
37323
36978
 
37324
36979
  // src/scripts/hooks/concern_registry.ts
37325
36980
  var CONCERN_REGISTRY = {
@@ -37340,14 +36995,14 @@ var CONCERN_REGISTRY = {
37340
36995
  "src/scripts/surface_probe_hook.ts": main20,
37341
36996
  "src/scripts/team_review_gate_hook.ts": main21,
37342
36997
  "src/scripts/pr_url_reminder_hook.ts": main22,
37343
- "src/scripts/session_canary_hook.ts": main23,
37344
- "src/scripts/council_availability_hook.ts": main24,
37345
- "src/scripts/telemetry_disclosure_hook.ts": main26,
37346
- "src/scripts/self_repair_hook.ts": main27,
37347
- "src/scripts/session_register_hook.ts": main28,
37348
- "src/scripts/language_mirror_hook.ts": main29,
37349
- "src/scripts/git_authorization_hook.ts": main30,
37350
- "src/scripts/hooks/block_unauthorized_git.ts": main31,
36998
+ "src/scripts/hooks/push_settle_hook.ts": main23,
36999
+ "src/scripts/session_canary_hook.ts": main24,
37000
+ "src/scripts/council_availability_hook.ts": main25,
37001
+ "src/scripts/telemetry_disclosure_hook.ts": main27,
37002
+ "src/scripts/self_repair_hook.ts": main28,
37003
+ "src/scripts/session_register_hook.ts": main29,
37004
+ "src/scripts/language_mirror_hook.ts": main30,
37005
+ "src/scripts/git_authorization_hook.ts": main31,
37351
37006
  "src/scripts/hooks/evidence_independence.ts": main32,
37352
37007
  "src/scripts/hooks/block_no_verify.ts": main33,
37353
37008
  "src/scripts/hooks/block_kernel_rule_writes.ts": main34,
@@ -37360,7 +37015,7 @@ var CONCERN_REGISTRY = {
37360
37015
  "src/scripts/hooks/suggestion_capture_hook.ts": main42,
37361
37016
  "src/scripts/hooks/ui_route_nudge_hook.ts": main43,
37362
37017
  "src/scripts/hooks/orchestration_record_hook.ts": main45,
37363
- "src/scripts/hooks/telemetry_usage_hook.ts": main25,
37018
+ "src/scripts/hooks/telemetry_usage_hook.ts": main26,
37364
37019
  "src/scripts/hooks/telemetry_flush_hook.ts": main46,
37365
37020
  "src/scripts/hooks/delegation_nudge_hook.ts": main47,
37366
37021
  "src/scripts/hooks/skill_route_hook.ts": main49,
@@ -37745,8 +37400,8 @@ var REPO_ROOT = path104.resolve(
37745
37400
  );
37746
37401
  var MANIFEST_PATH = path104.join(REPO_ROOT, "src", "scripts", "hook_manifest.yaml");
37747
37402
  var EXIT_ALLOW35 = 0;
37748
- var EXIT_BLOCK6 = 1;
37749
- var EXIT_WARN18 = 2;
37403
+ var EXIT_BLOCK5 = 1;
37404
+ var EXIT_WARN19 = 2;
37750
37405
  var EVENT_VOCABULARY = /* @__PURE__ */ new Set([
37751
37406
  "session_start",
37752
37407
  "session_end",
@@ -37761,10 +37416,10 @@ var EVENT_VOCABULARY = /* @__PURE__ */ new Set([
37761
37416
  ]);
37762
37417
  var _SEVERITY_BY_EXIT = {
37763
37418
  [EXIT_ALLOW35]: "allow",
37764
- [EXIT_BLOCK6]: "block",
37765
- [EXIT_WARN18]: "warn"
37419
+ [EXIT_BLOCK5]: "block",
37420
+ [EXIT_WARN19]: "warn"
37766
37421
  };
37767
- function _isObject17(v) {
37422
+ function _isObject16(v) {
37768
37423
  return typeof v === "object" && v !== null && !Array.isArray(v);
37769
37424
  }
37770
37425
  function _severity_for(rc) {
@@ -37794,7 +37449,7 @@ function _parse_concern_stdout(stdout_text) {
37794
37449
  } catch {
37795
37450
  return { _raw_stdout: text.slice(0, 500) };
37796
37451
  }
37797
- return _isObject17(parsed) ? parsed : { _raw: parsed };
37452
+ return _isObject16(parsed) ? parsed : { _raw: parsed };
37798
37453
  }
37799
37454
  function _manifest_fingerprint(text) {
37800
37455
  let h = 2166136261;
@@ -37810,18 +37465,18 @@ function _load_yaml3(p) {
37810
37465
  if (compiled !== p) {
37811
37466
  try {
37812
37467
  const raw = JSON.parse(fs102.readFileSync(compiled, "utf-8"));
37813
- if (_isObject17(raw) && raw["fingerprint"] === _manifest_fingerprint(text) && _isObject17(raw["manifest"])) {
37468
+ if (_isObject16(raw) && raw["fingerprint"] === _manifest_fingerprint(text) && _isObject16(raw["manifest"])) {
37814
37469
  return raw["manifest"];
37815
37470
  }
37816
37471
  } catch {
37817
37472
  }
37818
37473
  }
37819
37474
  const data = (0, import_yaml6.parse)(text, { version: "1.1" });
37820
- return _isObject17(data) ? data : {};
37475
+ return _isObject16(data) ? data : {};
37821
37476
  }
37822
37477
  function _payload_tool_name(envelope) {
37823
37478
  const payload = envelope["payload"];
37824
- if (!_isObject17(payload)) {
37479
+ if (!_isObject16(payload)) {
37825
37480
  return "";
37826
37481
  }
37827
37482
  const raw = payload["tool_name"];
@@ -37849,8 +37504,8 @@ function _role_drop_set(manifest, role, event) {
37849
37504
  return /* @__PURE__ */ new Set();
37850
37505
  }
37851
37506
  const rolesRaw = manifest["roles"];
37852
- const roleSpec = _isObject17(rolesRaw) ? rolesRaw[role] : void 0;
37853
- if (!_isObject17(roleSpec)) {
37507
+ const roleSpec = _isObject16(rolesRaw) ? rolesRaw[role] : void 0;
37508
+ if (!_isObject16(roleSpec)) {
37854
37509
  return /* @__PURE__ */ new Set();
37855
37510
  }
37856
37511
  const drop = roleSpec["drop"];
@@ -37863,9 +37518,9 @@ function _is_refusal_retry(event, payload_text) {
37863
37518
  if (event !== "stop") return false;
37864
37519
  try {
37865
37520
  const parsed = JSON.parse(payload_text);
37866
- if (!_isObject17(parsed)) return false;
37521
+ if (!_isObject16(parsed)) return false;
37867
37522
  const payload = parsed["payload"];
37868
- const source = _isObject17(payload) ? payload : parsed;
37523
+ const source = _isObject16(payload) ? payload : parsed;
37869
37524
  return source["stop_hook_active"] === true;
37870
37525
  } catch {
37871
37526
  return false;
@@ -37873,28 +37528,28 @@ function _is_refusal_retry(event, payload_text) {
37873
37528
  }
37874
37529
  function _resolve_concerns(manifest, platform, event, role = "orchestrator", opts = {}) {
37875
37530
  const platformsRaw = manifest["platforms"];
37876
- const platforms = _isObject17(platformsRaw) ? platformsRaw : {};
37531
+ const platforms = _isObject16(platformsRaw) ? platformsRaw : {};
37877
37532
  const block = platforms[platform];
37878
37533
  if (!block) {
37879
37534
  return [];
37880
37535
  }
37881
- if (_isObject17(block) && block["fallback_only"]) {
37536
+ if (_isObject16(block) && block["fallback_only"]) {
37882
37537
  return [];
37883
37538
  }
37884
- const names = _isObject17(block) ? block[event] : null;
37539
+ const names = _isObject16(block) ? block[event] : null;
37885
37540
  if (!Array.isArray(names)) {
37886
37541
  return [];
37887
37542
  }
37888
37543
  const dropped = _role_drop_set(manifest, role, event);
37889
37544
  const concernsRaw = manifest["concerns"];
37890
- const concerns_def = _isObject17(concernsRaw) ? concernsRaw : {};
37545
+ const concerns_def = _isObject16(concernsRaw) ? concernsRaw : {};
37891
37546
  const out = [];
37892
37547
  for (const name of names) {
37893
37548
  if (typeof name === "string" && dropped.has(name)) {
37894
37549
  continue;
37895
37550
  }
37896
37551
  const spec = typeof name === "string" ? concerns_def[name] : void 0;
37897
- if (!spec || !_isObject17(spec)) {
37552
+ if (!spec || !_isObject16(spec)) {
37898
37553
  process.stderr.write(
37899
37554
  `dispatch_hook: unknown concern '${String(name)}' in manifest
37900
37555
  `
@@ -37952,7 +37607,7 @@ function _build_envelope(args, payload_text) {
37952
37607
  let payload;
37953
37608
  try {
37954
37609
  payload = payload_text.trim() ? JSON.parse(payload_text) : {};
37955
- if (!_isObject17(payload)) {
37610
+ if (!_isObject16(payload)) {
37956
37611
  payload = { _raw: payload };
37957
37612
  }
37958
37613
  } catch {
@@ -38137,11 +37792,11 @@ function _compactJsonDumps(value) {
38137
37792
  return JSON.stringify(value);
38138
37793
  }
38139
37794
  function _reduce(rcs) {
38140
- if (rcs.some((rc) => rc === EXIT_BLOCK6)) {
38141
- return EXIT_BLOCK6;
37795
+ if (rcs.some((rc) => rc === EXIT_BLOCK5)) {
37796
+ return EXIT_BLOCK5;
38142
37797
  }
38143
- if (rcs.some((rc) => rc === EXIT_WARN18)) {
38144
- return EXIT_WARN18;
37798
+ if (rcs.some((rc) => rc === EXIT_WARN19)) {
37799
+ return EXIT_WARN19;
38145
37800
  }
38146
37801
  return EXIT_ALLOW35;
38147
37802
  }
@@ -38232,7 +37887,7 @@ var SUMMARY_INVOCATION_CAP = 20;
38232
37887
  function _record_rule_trips(envelope, entries) {
38233
37888
  if (is_replay_mode()) return;
38234
37889
  const tripped = entries.filter(
38235
- (e) => e["exit_code"] === EXIT_BLOCK6 || e["exit_code"] === EXIT_WARN18
37890
+ (e) => e["exit_code"] === EXIT_BLOCK5 || e["exit_code"] === EXIT_WARN19
38236
37891
  );
38237
37892
  if (tripped.length === 0) return;
38238
37893
  try {
@@ -38243,14 +37898,14 @@ function _record_rule_trips(envelope, entries) {
38243
37898
  update_json_under_lock(target, (loaded) => {
38244
37899
  const doc = { schema_version: 1, concerns: {}, ...loaded };
38245
37900
  const concernsRaw = doc["concerns"];
38246
- const concerns = _isObject17(concernsRaw) ? concernsRaw : {};
37901
+ const concerns = _isObject16(concernsRaw) ? concernsRaw : {};
38247
37902
  for (const e of tripped) {
38248
37903
  const name = String(e["concern"]);
38249
37904
  const prevRaw = concerns[name];
38250
- const prev = _isObject17(prevRaw) ? prevRaw : { block: 0, warn: 0 };
37905
+ const prev = _isObject16(prevRaw) ? prevRaw : { block: 0, warn: 0 };
38251
37906
  concerns[name] = {
38252
- block: (Number(prev["block"]) || 0) + (e["exit_code"] === EXIT_BLOCK6 ? 1 : 0),
38253
- warn: (Number(prev["warn"]) || 0) + (e["exit_code"] === EXIT_WARN18 ? 1 : 0),
37907
+ block: (Number(prev["block"]) || 0) + (e["exit_code"] === EXIT_BLOCK5 ? 1 : 0),
37908
+ warn: (Number(prev["warn"]) || 0) + (e["exit_code"] === EXIT_WARN19 ? 1 : 0),
38254
37909
  last_trip: today
38255
37910
  };
38256
37911
  }
@@ -38365,7 +38020,7 @@ function main65(argv) {
38365
38020
  }
38366
38021
  const envelope2 = _build_envelope(args, probe.text);
38367
38022
  process.stderr.write(
38368
- `dispatch_hook: --read-exit ok (${probe.text.length} chars, ${Object.keys(_isObject17(envelope2["payload"]) ? envelope2["payload"] : {}).length} payload keys)
38023
+ `dispatch_hook: --read-exit ok (${probe.text.length} chars, ${Object.keys(_isObject16(envelope2["payload"]) ? envelope2["payload"] : {}).length} payload keys)
38369
38024
  `
38370
38025
  );
38371
38026
  return EXIT_ALLOW35;
@@ -38437,7 +38092,7 @@ function main65(argv) {
38437
38092
  if (_stdin_read_failed !== null) {
38438
38093
  const deny = denyOnStdinFailure(args.platform, args.event, concerns, _stdin_read_failed);
38439
38094
  if (deny !== null) {
38440
- const emission2 = emitFor(args.platform, args.event, "block", [deny.reason], EXIT_BLOCK6);
38095
+ const emission2 = emitFor(args.platform, args.event, "block", [deny.reason], EXIT_BLOCK5);
38441
38096
  if (emission2.stdout) process.stdout.write(emission2.stdout);
38442
38097
  if (emission2.stderr) process.stderr.write(emission2.stderr);
38443
38098
  return emission2.exit;
@@ -38473,18 +38128,18 @@ function main65(argv) {
38473
38128
  if (!concern["fail_closed"]) {
38474
38129
  rc = EXIT_ALLOW35;
38475
38130
  } else {
38476
- rc = EXIT_BLOCK6;
38131
+ rc = EXIT_BLOCK5;
38477
38132
  }
38478
38133
  if (stderr_text) {
38479
38134
  process.stderr.write(stderr_text);
38480
38135
  }
38481
38136
  }
38482
- if (rc === EXIT_BLOCK6 && _is_advisory(concern)) {
38137
+ if (rc === EXIT_BLOCK5 && _is_advisory(concern)) {
38483
38138
  process.stderr.write(
38484
38139
  `dispatch_hook: concern '${String(concern["name"])}' is declared severity: advisory but returned BLOCK \u2014 downgraded to warn.
38485
38140
  `
38486
38141
  );
38487
- rc = EXIT_WARN18;
38142
+ rc = EXIT_WARN19;
38488
38143
  }
38489
38144
  rcs.push(rc);
38490
38145
  const reply = _parse_concern_stdout(stdout_text);
@@ -38557,7 +38212,7 @@ function _sortedRepr(s) {
38557
38212
  return `[${items.map((x) => `'${x}'`).join(", ")}]`;
38558
38213
  }
38559
38214
  var _stdin_read_failed = null;
38560
- function _isCliEntry52() {
38215
+ function _isCliEntry51() {
38561
38216
  if (true) {
38562
38217
  return false;
38563
38218
  }
@@ -38576,8 +38231,8 @@ function _isCliEntry52() {
38576
38231
  return false;
38577
38232
  }
38578
38233
  }
38579
- var isCliEntry14 = _isCliEntry52();
38580
- if (isCliEntry14) {
38234
+ var isCliEntry15 = _isCliEntry51();
38235
+ if (isCliEntry15) {
38581
38236
  process.exit(main65(process.argv.slice(2)));
38582
38237
  }
38583
38238