@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.
- package/.augment-plugin/marketplace.json +3 -3
- package/.augment-plugin/plugin.json +1 -1
- package/.claude-plugin/marketplace.json +1 -1
- package/CHANGELOG.md +170 -79
- package/README.md +1 -1
- package/dist/agent-src/commands/pr/merge.md +35 -44
- package/dist/agent-src/skills/accessibility-auditor/SKILL.md +2 -0
- package/dist/agent-src/skills/ai-code-blindspots/SKILL.md +27 -1
- package/dist/agent-src/skills/code-intelligence/SKILL.md +60 -12
- package/dist/agent-src/skills/complexity-first-planning/SKILL.md +27 -0
- package/dist/agent-src/skills/design-review/SKILL.md +2 -0
- package/dist/agent-src/skills/feature-planning/SKILL.md +34 -0
- package/dist/agent-src/skills/git-workflow/SKILL.md +37 -12
- package/dist/agent-src/skills/git-workflow/references/push-closes-its-loop.md +176 -0
- package/dist/agent-src/skills/laravel-mail/SKILL.md +44 -0
- package/dist/agent-src/skills/testing-anti-patterns/SKILL.md +40 -0
- package/dist/agent-src/skills/using-git-worktrees/SKILL.md +12 -0
- package/dist/agent-src/skills/verify-repair-loop/SKILL.md +53 -8
- package/dist/agent-src/skills/worktree-lifecycle/SKILL.md +3 -1
- package/dist/agent-src/templates/agents/agent-project-settings.example.yml +1 -1
- package/dist/cli-delegate/cmd_conformance.js +335 -659
- package/dist/discovery/deprecation-report.md +1 -1
- package/dist/discovery/discovery-manifest.json +15 -15
- package/dist/discovery/discovery-manifest.json.sha256 +1 -1
- package/dist/discovery/discovery-manifest.summary.md +1 -1
- package/dist/discovery/dormancy-report.md +1 -1
- package/dist/discovery/orphan-report.md +1 -1
- package/dist/discovery/packs.json +2 -2
- package/dist/discovery/trust-report.md +1 -1
- package/dist/discovery/workspaces.json +2 -2
- package/dist/hooks/dispatch.js +959 -1304
- package/dist/mcp/registry-manifest.json +2 -2
- package/dist/mcp/server.json +2 -2
- package/dist/mcp/server.mjs +671 -1002
- package/dist/shared/settingsConsent.js +1 -1
- package/package.json +1 -1
- package/src/config/conformance-claim-baseline.json +9 -0
- package/src/config/gate-violation-baselines.json +3 -3
- package/src/config/release-gate-locality.yml +129 -0
- package/src/scripts/_lib/release_highlights.ts +172 -1
- package/src/scripts/_lib/release_material.ts +66 -0
- package/src/scripts/_lib/repeated_run.ts +77 -0
- package/src/scripts/_lib/tamper_vocabulary.ts +242 -0
- package/src/scripts/_lib/unified_diff.ts +121 -0
- package/src/scripts/check_finding_dispositions.ts +179 -3
- package/src/scripts/check_installed_hooks_fresh.ts +381 -0
- package/src/scripts/check_release_highlights.ts +25 -13
- package/src/scripts/check_suppression_hygiene.ts +11 -0
- package/src/scripts/code_graph/build.ts +230 -33
- package/src/scripts/code_graph/extract.ts +168 -33
- package/src/scripts/code_graph/types.ts +37 -2
- package/src/scripts/code_graph/validate.ts +12 -1
- package/src/scripts/conformance_scan.ts +2 -2
- package/src/scripts/detect_silent_catch.ts +403 -0
- package/src/scripts/detect_verification_tampering.ts +538 -0
- package/src/scripts/git_authorization_hook.ts +153 -17
- package/src/scripts/hook_manifest.json +1 -1
- package/src/scripts/hook_manifest.yaml +33 -19
- package/src/scripts/hooks/block_no_verify.ts +3 -3
- package/src/scripts/hooks/concern_registry.ts +2 -2
- package/src/scripts/hooks/evidence_independence.ts +21 -2
- package/src/scripts/hooks/{block_unauthorized_git.ts → git_command_classifier.ts} +25 -369
- package/src/scripts/hooks/push_settle_hook.ts +250 -0
- package/src/scripts/hooks/ship_diff_volume_hook.ts +1 -1
- package/src/scripts/install-hooks.sh +134 -1
- package/src/scripts/language_mirror_hook.ts +27 -5
- package/src/scripts/release.ts +31 -143
- package/src/scripts/release_drill.ts +71 -1
- package/src/scripts/release_publication.ts +243 -3
- package/src/scripts/release_verify.ts +220 -0
- package/src/scripts/schemas/review-findings.schema.json +1 -1
- package/src/scripts/schemas/skill.schema.json +11 -1
- package/src/scripts/self_review_gate.ts +10 -1
- package/src/shared/settingsConsent.ts +1 -1
package/dist/hooks/dispatch.js
CHANGED
|
@@ -22673,11 +22673,137 @@ if (_isCliEntry18()) {
|
|
|
22673
22673
|
process.exit(main22());
|
|
22674
22674
|
}
|
|
22675
22675
|
|
|
22676
|
-
// src/scripts/
|
|
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 (!
|
|
22814
|
+
if (!fs41.statSync(settings_path).isFile()) {
|
|
22689
22815
|
return null;
|
|
22690
22816
|
}
|
|
22691
|
-
text =
|
|
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 (!
|
|
22842
|
+
if (!fs41.statSync(user_yml_path).isFile()) {
|
|
22717
22843
|
return null;
|
|
22718
22844
|
}
|
|
22719
|
-
text =
|
|
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(
|
|
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
|
-
|
|
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(
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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 =
|
|
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 =
|
|
22841
|
-
const argv =
|
|
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(
|
|
22974
|
+
process.exit(main24());
|
|
22849
22975
|
}
|
|
22850
22976
|
|
|
22851
22977
|
// src/scripts/council_availability_hook.ts
|
|
22852
|
-
import * as
|
|
22853
|
-
import * as
|
|
22854
|
-
import { fileURLToPath as
|
|
22855
|
-
var
|
|
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 =
|
|
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
|
|
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
|
|
23048
|
+
return EXIT_ALLOW6;
|
|
22923
23049
|
}
|
|
22924
23050
|
const a = resolveAvailability(_workspaceRoot3(envelope), options.env ?? process.env);
|
|
22925
23051
|
if (a === null) {
|
|
22926
|
-
return
|
|
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
|
|
23062
|
+
return EXIT_ALLOW6;
|
|
22937
23063
|
}
|
|
22938
|
-
function
|
|
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 ===
|
|
23077
|
+
return import.meta.url === pathToFileURL22(path42.resolve(process.argv[1])).href;
|
|
22952
23078
|
}
|
|
22953
23079
|
if (_isCliEntry20()) {
|
|
22954
|
-
process.exit(
|
|
23080
|
+
process.exit(main25());
|
|
22955
23081
|
}
|
|
22956
23082
|
|
|
22957
23083
|
// src/scripts/telemetry_disclosure_hook.ts
|
|
22958
|
-
import * as
|
|
22959
|
-
import * as
|
|
22960
|
-
import { pathToFileURL as
|
|
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
|
|
22965
|
-
import { fileURLToPath as
|
|
22966
|
-
import * as
|
|
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
|
|
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
|
|
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(
|
|
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
|
|
23131
|
-
import * as
|
|
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 =
|
|
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 =
|
|
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
|
-
|
|
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 =
|
|
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 =
|
|
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
|
-
|
|
23510
|
-
|
|
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
|
-
|
|
23515
|
-
|
|
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
|
|
23532
|
-
import * as
|
|
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 =
|
|
23537
|
-
const base =
|
|
23538
|
-
return
|
|
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
|
|
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
|
|
23696
|
+
var EXIT_ALLOW7 = 0;
|
|
23571
23697
|
var SKILL_TOOL_NAME = "Skill";
|
|
23572
23698
|
var SETTINGS_FILENAME = ".agent-settings.yml";
|
|
23573
|
-
function
|
|
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
|
|
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 (!
|
|
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 =
|
|
23751
|
+
let dir = path45.resolve(start);
|
|
23626
23752
|
for (; ; ) {
|
|
23627
|
-
const candidate =
|
|
23753
|
+
const candidate = path45.join(dir, SETTINGS_FILENAME);
|
|
23628
23754
|
try {
|
|
23629
|
-
if (
|
|
23755
|
+
if (fs46.statSync(candidate).isFile()) return candidate;
|
|
23630
23756
|
} catch {
|
|
23631
23757
|
}
|
|
23632
|
-
const parent =
|
|
23633
|
-
if (parent === dir) return
|
|
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 =
|
|
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:
|
|
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 (!
|
|
23779
|
+
if (!isObject3(envelope)) return EXIT_ALLOW7;
|
|
23654
23780
|
const payload = unwrapPayload(envelope);
|
|
23655
|
-
if (extractToolName(payload) !== SKILL_TOOL_NAME) return
|
|
23781
|
+
if (extractToolName(payload) !== SKILL_TOOL_NAME) return EXIT_ALLOW7;
|
|
23656
23782
|
const { settings, text, root } = readSettingsFor(consumer_root);
|
|
23657
|
-
if (!settings.active) return
|
|
23658
|
-
if (is_replay_mode()) return
|
|
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
|
|
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 =
|
|
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
|
|
23811
|
+
return EXIT_ALLOW7;
|
|
23686
23812
|
}
|
|
23687
|
-
return
|
|
23813
|
+
return EXIT_ALLOW7;
|
|
23688
23814
|
}
|
|
23689
23815
|
function _resolveRoot(envelope) {
|
|
23690
|
-
if (
|
|
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
|
|
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
|
|
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 =
|
|
23839
|
+
const argvUrl = pathToFileURL23(path45.resolve(process.argv[1])).href;
|
|
23714
23840
|
if (import.meta.url === argvUrl) return true;
|
|
23715
23841
|
try {
|
|
23716
|
-
return
|
|
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(
|
|
23847
|
+
if (_isCliEntry21()) process.exit(main26());
|
|
23722
23848
|
|
|
23723
23849
|
// src/scripts/telemetry_disclosure_hook.ts
|
|
23724
|
-
var
|
|
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 =
|
|
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 =
|
|
23755
|
-
|
|
23756
|
-
|
|
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
|
|
23912
|
+
return EXIT_ALLOW8;
|
|
23787
23913
|
}
|
|
23788
23914
|
}
|
|
23789
23915
|
if (envelope["event"] !== "session_start") {
|
|
23790
|
-
return
|
|
23916
|
+
return EXIT_ALLOW8;
|
|
23791
23917
|
}
|
|
23792
23918
|
if (is_replay_mode()) {
|
|
23793
|
-
return
|
|
23919
|
+
return EXIT_ALLOW8;
|
|
23794
23920
|
}
|
|
23795
23921
|
const settingsFile = options.settingsFile ?? resolveSettingsPath(_resolveRoot(envelope));
|
|
23796
|
-
const root =
|
|
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
|
|
23927
|
+
return EXIT_ALLOW8;
|
|
23802
23928
|
}
|
|
23803
23929
|
if (!settings.active) {
|
|
23804
|
-
return
|
|
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
|
|
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
|
|
23949
|
+
return EXIT_ALLOW8;
|
|
23824
23950
|
}
|
|
23825
|
-
function
|
|
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 ===
|
|
23963
|
+
return import.meta.url === pathToFileURL24(path46.resolve(process.argv[1])).href;
|
|
23838
23964
|
}
|
|
23839
23965
|
if (_isCliEntry22()) {
|
|
23840
|
-
process.exit(
|
|
23966
|
+
process.exit(main27());
|
|
23841
23967
|
}
|
|
23842
23968
|
|
|
23843
23969
|
// src/scripts/self_repair_hook.ts
|
|
23844
|
-
import * as
|
|
23845
|
-
import * as
|
|
23846
|
-
import { fileURLToPath as
|
|
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
|
|
24084
|
-
import * as
|
|
24085
|
-
var STORE_REL =
|
|
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
|
|
24213
|
+
return path47.join(root, STORE_REL);
|
|
24088
24214
|
}
|
|
24089
24215
|
function recordPath(root, fp) {
|
|
24090
|
-
return
|
|
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(
|
|
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
|
-
|
|
24110
|
-
|
|
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 =
|
|
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
|
|
24268
|
+
return path47.join(storeDir(root), OVERFLOW_FILE);
|
|
24143
24269
|
}
|
|
24144
24270
|
function readOverflow(root) {
|
|
24145
24271
|
try {
|
|
24146
|
-
const parsed = JSON.parse(
|
|
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
|
-
|
|
24158
|
-
|
|
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
|
|
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 =
|
|
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
|
|
24227
|
-
function
|
|
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 =
|
|
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 (!
|
|
24388
|
+
if (!isObject4(obj)) {
|
|
24263
24389
|
continue;
|
|
24264
24390
|
}
|
|
24265
24391
|
const msg = obj["message"];
|
|
24266
|
-
if (!
|
|
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 (!
|
|
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 =
|
|
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
|
|
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 =
|
|
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
|
|
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
|
|
24479
|
+
return EXIT_ALLOW9;
|
|
24354
24480
|
}
|
|
24355
24481
|
let open;
|
|
24356
24482
|
try {
|
|
24357
24483
|
open = openRecords(root);
|
|
24358
24484
|
} catch {
|
|
24359
|
-
return
|
|
24485
|
+
return EXIT_ALLOW9;
|
|
24360
24486
|
}
|
|
24361
24487
|
if (open.length === 0) {
|
|
24362
|
-
return
|
|
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
|
|
24502
|
+
return EXIT_ALLOW9;
|
|
24377
24503
|
}
|
|
24378
|
-
function
|
|
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 =
|
|
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
|
|
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 (
|
|
24396
|
-
process.exit(
|
|
24521
|
+
if (isCliEntry10()) {
|
|
24522
|
+
process.exit(main28());
|
|
24397
24523
|
}
|
|
24398
24524
|
|
|
24399
24525
|
// src/scripts/session_register_hook.ts
|
|
24400
|
-
import * as
|
|
24401
|
-
import * as
|
|
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
|
|
24529
|
+
import { fileURLToPath as fileURLToPath32 } from "node:url";
|
|
24404
24530
|
|
|
24405
24531
|
// src/scripts/_lib/session_register.ts
|
|
24406
|
-
import
|
|
24407
|
-
import
|
|
24532
|
+
import fs51 from "node:fs";
|
|
24533
|
+
import path51 from "node:path";
|
|
24408
24534
|
|
|
24409
24535
|
// src/scripts/_lib/fs_atomic.ts
|
|
24410
|
-
import
|
|
24411
|
-
import
|
|
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 =
|
|
24428
|
-
const parent =
|
|
24429
|
-
|
|
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 =
|
|
24569
|
+
tmp_path = path50.join(
|
|
24444
24570
|
parent,
|
|
24445
|
-
`.${
|
|
24571
|
+
`.${path50.basename(target)}.tmp.${randomBytes(6).toString("hex")}`
|
|
24446
24572
|
);
|
|
24447
24573
|
try {
|
|
24448
|
-
fd =
|
|
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 +=
|
|
24588
|
+
offset += fs50.writeSync(fd, payload, offset, payload.length - offset);
|
|
24463
24589
|
}
|
|
24464
24590
|
try {
|
|
24465
|
-
|
|
24591
|
+
fs50.fsyncSync(fd);
|
|
24466
24592
|
} catch {
|
|
24467
24593
|
}
|
|
24468
|
-
|
|
24594
|
+
fs50.closeSync(fd);
|
|
24469
24595
|
closed = true;
|
|
24470
|
-
|
|
24596
|
+
fs50.renameSync(tmp_path, target);
|
|
24471
24597
|
} catch (err) {
|
|
24472
24598
|
if (!closed) {
|
|
24473
24599
|
try {
|
|
24474
|
-
|
|
24600
|
+
fs50.closeSync(fd);
|
|
24475
24601
|
} catch {
|
|
24476
24602
|
}
|
|
24477
24603
|
}
|
|
24478
24604
|
try {
|
|
24479
|
-
|
|
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 =
|
|
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
|
-
|
|
24622
|
+
fs50.fsyncSync(dir_fd);
|
|
24497
24623
|
} catch {
|
|
24498
24624
|
}
|
|
24499
24625
|
} finally {
|
|
24500
|
-
|
|
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 :
|
|
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 =
|
|
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 =
|
|
24572
|
-
const parsed = JSON.parse(
|
|
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
|
-
|
|
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 =
|
|
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 =
|
|
24725
|
+
const full = path51.join(dir, name);
|
|
24600
24726
|
let rec = null;
|
|
24601
24727
|
try {
|
|
24602
|
-
const parsed = JSON.parse(
|
|
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
|
-
|
|
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
|
|
24651
|
-
import * as
|
|
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
|
|
24780
|
+
import * as fs52 from "node:fs";
|
|
24655
24781
|
import * as os9 from "node:os";
|
|
24656
|
-
import * as
|
|
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
|
|
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 =
|
|
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 =
|
|
24886
|
+
var REFUSAL_STATE_REL = path53.join("agents", "runtime", "state", "turn-end-gate");
|
|
24761
24887
|
function refusalStateDir(workspaceRoot3) {
|
|
24762
|
-
return
|
|
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
|
|
24894
|
+
return path53.join(refusalStateDir(workspaceRoot3), `${sessionKey}.json`);
|
|
24769
24895
|
}
|
|
24770
24896
|
function readSessionCounts(workspaceRoot3, sessionId2) {
|
|
24771
24897
|
try {
|
|
24772
|
-
const raw =
|
|
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 =
|
|
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 =
|
|
25008
|
+
const file = path53.join(dir, name);
|
|
24883
25009
|
let rec = null;
|
|
24884
25010
|
try {
|
|
24885
|
-
rec = parseRecord(
|
|
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
|
-
|
|
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 =
|
|
24911
|
-
var ROADMAP_CLAIM_REL =
|
|
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 =
|
|
24918
|
-
const norm =
|
|
24919
|
-
if (!norm.startsWith(`${_STATE_REL}${
|
|
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 :
|
|
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(
|
|
25060
|
+
out.push(path54.join(dir, path54.basename(rel)));
|
|
24935
25061
|
if (rel !== ROADMAP_CLAIM_REL) {
|
|
24936
|
-
out.push(
|
|
25062
|
+
out.push(path54.join(dir, path54.basename(ROADMAP_CLAIM_REL)));
|
|
24937
25063
|
}
|
|
24938
25064
|
}
|
|
24939
|
-
out.push(
|
|
25065
|
+
out.push(path54.join(workspace_root, rel));
|
|
24940
25066
|
if (rel !== ROADMAP_CLAIM_REL) {
|
|
24941
|
-
out.push(
|
|
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(
|
|
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 (
|
|
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 (
|
|
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 =
|
|
25018
|
-
const inside =
|
|
25019
|
-
if (!inside ||
|
|
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 (
|
|
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 (!
|
|
25043
|
-
start =
|
|
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 =
|
|
25181
|
+
const abs = path54.resolve(p);
|
|
25056
25182
|
try {
|
|
25057
|
-
return
|
|
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 =
|
|
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
|
|
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 (
|
|
25358
|
+
if (path54.basename(p) !== path54.basename(roadmap_claim_rel(session_id))) continue;
|
|
25233
25359
|
try {
|
|
25234
|
-
|
|
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 &&
|
|
25283
|
-
process10.exit(
|
|
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
|
|
25288
|
-
import
|
|
25289
|
-
import { fileURLToPath as
|
|
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
|
|
25347
|
-
var
|
|
25348
|
-
var STATE_FILE6 =
|
|
25349
|
-
var STATE_DIR4 =
|
|
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 =
|
|
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
|
|
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 =
|
|
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 =
|
|
25637
|
+
const legacy = path55.join(consumer_root, PIN_LOST_DIR);
|
|
25512
25638
|
try {
|
|
25513
|
-
if (
|
|
25514
|
-
|
|
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(
|
|
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
|
|
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
|
-
|
|
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
|
|
25673
|
+
return EXIT_ALLOW10;
|
|
25544
25674
|
}
|
|
25545
25675
|
if (!_pinLost(consumer_root, session_id)) {
|
|
25546
|
-
return
|
|
25676
|
+
return EXIT_ALLOW10;
|
|
25547
25677
|
}
|
|
25548
|
-
return _withToolWriteLock(consumer_root, session_id,
|
|
25549
|
-
const previous = _loadState(
|
|
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
|
|
25684
|
+
return EXIT_ALLOW10;
|
|
25555
25685
|
}
|
|
25556
25686
|
if (!_ownsPin(previous, session_id)) {
|
|
25557
|
-
return
|
|
25687
|
+
return EXIT_ALLOW10;
|
|
25558
25688
|
}
|
|
25559
25689
|
if (!_resetDistance(consumer_root, previous, session_id, write_json)) {
|
|
25560
|
-
return
|
|
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
|
|
25700
|
+
return EXIT_WARN4;
|
|
25571
25701
|
});
|
|
25572
25702
|
}
|
|
25573
25703
|
function _pruneLegacyState(consumer_root) {
|
|
25574
|
-
prune_legacy_state_file(
|
|
25704
|
+
prune_legacy_state_file(path55.join(consumer_root, STATE_FILE6));
|
|
25575
25705
|
}
|
|
25576
|
-
function _pruneStaleSessions(consumer_root, now_ms, mtimeOf = (target) =>
|
|
25706
|
+
function _pruneStaleSessions(consumer_root, now_ms, mtimeOf = (target) => fs55.statSync(target).mtimeMs) {
|
|
25577
25707
|
return prune_stale_session_states(
|
|
25578
|
-
|
|
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 = `${
|
|
25716
|
+
const lock = `${path55.join(consumer_root, statePathFor2(session_id))}.lock`;
|
|
25587
25717
|
let fd;
|
|
25588
25718
|
const acquire = () => {
|
|
25589
25719
|
try {
|
|
25590
|
-
|
|
25591
|
-
return
|
|
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 -
|
|
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
|
-
|
|
25603
|
-
return
|
|
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
|
-
|
|
25746
|
+
fs55.closeSync(fd);
|
|
25617
25747
|
} catch {
|
|
25618
25748
|
}
|
|
25619
25749
|
try {
|
|
25620
|
-
|
|
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 =
|
|
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
|
|
25780
|
+
return EXIT_ALLOW10;
|
|
25651
25781
|
}
|
|
25652
25782
|
if (!hasStableSessionId(session_id)) {
|
|
25653
|
-
return
|
|
25783
|
+
return EXIT_ALLOW10;
|
|
25654
25784
|
}
|
|
25655
|
-
return _withToolWriteLock(consumer_root, session_id,
|
|
25656
|
-
const previous = _loadState(
|
|
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
|
|
25789
|
+
return EXIT_ALLOW10;
|
|
25660
25790
|
}
|
|
25661
25791
|
if (!_ownsPin(previous, session_id)) {
|
|
25662
|
-
return
|
|
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
|
|
25805
|
+
return EXIT_ALLOW10;
|
|
25676
25806
|
}
|
|
25677
25807
|
if (!written) {
|
|
25678
|
-
return
|
|
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
|
|
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
|
|
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
|
|
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
|
|
25851
|
+
return EXIT_ALLOW10;
|
|
25722
25852
|
}
|
|
25723
25853
|
if (isSyntheticPrompt(prompt)) {
|
|
25724
|
-
return
|
|
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 ?
|
|
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
|
|
25892
|
+
return EXIT_WARN4;
|
|
25759
25893
|
}
|
|
25760
|
-
return
|
|
25894
|
+
return EXIT_ALLOW10;
|
|
25761
25895
|
}
|
|
25762
|
-
function
|
|
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 =
|
|
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 =
|
|
25789
|
-
const argv =
|
|
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(
|
|
25934
|
+
process.exit(main30());
|
|
25797
25935
|
}
|
|
25798
25936
|
|
|
25799
25937
|
// src/scripts/git_authorization_hook.ts
|
|
25800
|
-
import
|
|
25801
|
-
import
|
|
25802
|
-
import { fileURLToPath as
|
|
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
|
|
25821
|
-
var STATE_FILE7 =
|
|
25822
|
-
var STATE_DIR5 =
|
|
25823
|
-
var PENDING_DIR =
|
|
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
|
|
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
|
|
25975
|
+
return path56.join(PENDING_DIR, `${sessionSlug(session_id)}.json`);
|
|
25838
25976
|
}
|
|
25839
|
-
var PENDING_FILE =
|
|
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
|
|
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
|
|
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
|
-
|
|
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
|
|
26147
|
-
var
|
|
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 =
|
|
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 =
|
|
26468
|
+
const file = path56.join(consumer_root, pendingFileFor(session_id));
|
|
26337
26469
|
let raw;
|
|
26338
26470
|
try {
|
|
26339
|
-
raw =
|
|
26471
|
+
raw = fs56.readFileSync(file, "utf8");
|
|
26340
26472
|
} catch {
|
|
26341
26473
|
return null;
|
|
26342
26474
|
}
|
|
26343
26475
|
try {
|
|
26344
|
-
|
|
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
|
-
|
|
26978
|
-
|
|
26979
|
-
|
|
26980
|
-
|
|
26981
|
-
|
|
26982
|
-
|
|
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
|
|
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 (
|
|
26506
|
+
if (_isObject8(decoded)) {
|
|
27037
26507
|
envelope = decoded;
|
|
27038
26508
|
}
|
|
27039
26509
|
} catch {
|
|
27040
26510
|
return EXIT_ALLOW11;
|
|
27041
26511
|
}
|
|
27042
26512
|
}
|
|
27043
|
-
const
|
|
27044
|
-
|
|
27045
|
-
const
|
|
27046
|
-
|
|
27047
|
-
|
|
27048
|
-
|
|
27049
|
-
|
|
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
|
-
|
|
27059
|
-
|
|
27060
|
-
consumeGrantTarget(options.consumer_root, session_id, decision.consumedTarget);
|
|
26522
|
+
if (!prompt) {
|
|
26523
|
+
return EXIT_ALLOW11;
|
|
27061
26524
|
}
|
|
27062
|
-
|
|
27063
|
-
|
|
27064
|
-
|
|
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
|
-
|
|
27073
|
-
|
|
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
|
-
|
|
27076
|
-
|
|
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
|
|
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
|
|
26576
|
+
return run10(readHookStdin(), { consumer_root });
|
|
27093
26577
|
}
|
|
27094
|
-
function
|
|
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 (
|
|
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
|
|
26607
|
+
var EXIT_BLOCK = 1;
|
|
27124
26608
|
var STATE_FILE8 = path57.join("agents", "state", "evidence-dispatch.json");
|
|
27125
|
-
function
|
|
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 =
|
|
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 =
|
|
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 (
|
|
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
|
|
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:
|
|
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
|
|
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 (
|
|
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 =
|
|
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
|
|
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
|
|
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 (
|
|
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
|
|
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 =
|
|
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 =
|
|
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 =
|
|
27944
|
-
const ti =
|
|
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
|
|
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
|
|
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 (
|
|
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
|
|
28017
|
-
var
|
|
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
|
|
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
|
|
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 =
|
|
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 =
|
|
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 (!
|
|
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 =
|
|
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
|
|
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
|
|
27828
|
+
return EXIT_WARN5;
|
|
28185
27829
|
}
|
|
28186
27830
|
}
|
|
28187
27831
|
return EXIT_ALLOW13;
|
|
28188
27832
|
}
|
|
28189
|
-
function
|
|
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 (
|
|
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
|
|
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 =
|
|
28313
|
-
const ti =
|
|
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"] ?? (
|
|
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
|
|
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 (
|
|
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
|
|
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
|
|
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 =
|
|
28563
|
-
const 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 (!
|
|
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
|
|
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
|
|
28331
|
+
return EXIT_WARN6;
|
|
28688
28332
|
}
|
|
28689
28333
|
return EXIT_ALLOW14;
|
|
28690
28334
|
}
|
|
28691
|
-
function
|
|
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 (
|
|
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
|
|
28812
|
+
let run12 = 0;
|
|
29169
28813
|
let maxRun = 0;
|
|
29170
28814
|
for (const b of bodies) {
|
|
29171
28815
|
if (sectionSignature(b).mediaText) {
|
|
29172
|
-
|
|
29173
|
-
maxRun = Math.max(maxRun,
|
|
28816
|
+
run12 += 1;
|
|
28817
|
+
maxRun = Math.max(maxRun, run12);
|
|
29174
28818
|
} else {
|
|
29175
|
-
|
|
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
|
|
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
|
|
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 =
|
|
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
|
|
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
|
|
29302
|
+
var EXIT_WARN8 = 2;
|
|
29659
29303
|
var DEGRADE_AFTER = 3;
|
|
29660
|
-
function
|
|
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
|
|
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 (!
|
|
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
|
|
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 (!
|
|
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
|
|
29418
|
+
return EXIT_WARN8;
|
|
29775
29419
|
}
|
|
29776
|
-
function
|
|
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
|
|
29796
|
-
if (
|
|
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([
|
|
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
|
|
29591
|
+
var EXIT_WARN9 = 2;
|
|
29937
29592
|
var CODE_EXT = /\.(php|ts|tsx|mts|cts|js|jsx|mjs|cjs)$/i;
|
|
29938
|
-
function
|
|
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 =
|
|
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 =
|
|
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" &&
|
|
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 (!
|
|
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
|
|
29706
|
+
return EXIT_WARN9;
|
|
30052
29707
|
}
|
|
30053
|
-
function
|
|
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 (
|
|
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
|
|
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 (!
|
|
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
|
|
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 (
|
|
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
|
|
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
|
|
30006
|
+
function isObject8(v) {
|
|
30352
30007
|
return typeof v === "object" && v !== null && !Array.isArray(v);
|
|
30353
30008
|
}
|
|
30354
|
-
function
|
|
30009
|
+
function unwrap3(envelope) {
|
|
30355
30010
|
const inner = envelope["payload"];
|
|
30356
|
-
return
|
|
30011
|
+
return isObject8(inner) ? inner : envelope;
|
|
30357
30012
|
}
|
|
30358
30013
|
function extractEvent(outer) {
|
|
30359
|
-
const envelope =
|
|
30014
|
+
const envelope = unwrap3(outer);
|
|
30360
30015
|
const ti = envelope["tool_input"] ?? envelope["toolInput"] ?? envelope["input"];
|
|
30361
|
-
if (!
|
|
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
|
|
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 (!
|
|
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 } =
|
|
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
|
|
30112
|
+
return EXIT_WARN10;
|
|
30458
30113
|
}
|
|
30459
|
-
function
|
|
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 (
|
|
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
|
|
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
|
|
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
|
|
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 (
|
|
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 &&
|
|
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 (!
|
|
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 (
|
|
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
|
|
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 (
|
|
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
|
|
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 (
|
|
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
|
|
31404
|
-
function
|
|
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 =
|
|
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 =
|
|
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
|
|
31255
|
+
return EXIT_WARN11;
|
|
31601
31256
|
}
|
|
31602
|
-
function
|
|
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 (
|
|
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
|
|
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 =
|
|
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
|
|
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
|
|
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 =
|
|
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 =
|
|
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
|
|
31969
|
+
return EXIT_WARN12;
|
|
32315
31970
|
}
|
|
32316
|
-
function
|
|
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 (
|
|
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
|
|
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
|
|
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 (!
|
|
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 =
|
|
32371
|
+
env = isObject10(parsed) ? parsed : {};
|
|
32717
32372
|
} catch {
|
|
32718
32373
|
return EXIT_ALLOW24;
|
|
32719
32374
|
}
|
|
32720
32375
|
const root = workspaceRoot2(env);
|
|
32721
|
-
const payload =
|
|
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,
|
|
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
|
|
32413
|
+
return EXIT_WARN13;
|
|
32759
32414
|
}
|
|
32760
|
-
function
|
|
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 (
|
|
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
|
|
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
|
|
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 (!
|
|
32610
|
+
if (!isObject11(obj) || obj["type"] !== "assistant") continue;
|
|
32956
32611
|
const msg = obj["message"];
|
|
32957
|
-
if (!
|
|
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 (!
|
|
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 =
|
|
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
|
|
32739
|
+
return EXIT_WARN14;
|
|
33085
32740
|
}
|
|
33086
|
-
function
|
|
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 (
|
|
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
|
|
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
|
|
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 (
|
|
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 (!
|
|
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 (!
|
|
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 (
|
|
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
|
|
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 (
|
|
33250
|
+
if (_isCliEntry39()) process.exit(main52());
|
|
33596
33251
|
|
|
33597
33252
|
// src/scripts/hooks/turn_end_gate_hook.ts
|
|
33598
|
-
var
|
|
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
|
|
33637
|
+
return EXIT_BLOCK3;
|
|
33983
33638
|
}
|
|
33984
|
-
function
|
|
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 (
|
|
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
|
|
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
|
|
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 (!
|
|
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
|
|
33791
|
+
return EXIT_WARN15;
|
|
34137
33792
|
} catch {
|
|
34138
33793
|
return EXIT_ALLOW27;
|
|
34139
33794
|
}
|
|
34140
33795
|
}
|
|
34141
|
-
function
|
|
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 (
|
|
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
|
|
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
|
|
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 (!
|
|
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
|
|
34535
|
+
return EXIT_WARN16;
|
|
34881
34536
|
} catch {
|
|
34882
34537
|
return EXIT_ALLOW28;
|
|
34883
34538
|
}
|
|
34884
34539
|
}
|
|
34885
|
-
function
|
|
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 (
|
|
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
|
|
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
|
|
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 (!
|
|
34598
|
+
if (!isObject15(parsed)) return emptyLedger();
|
|
34944
34599
|
return {
|
|
34945
|
-
reads:
|
|
34946
|
-
writes:
|
|
34947
|
-
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
|
|
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
|
|
34696
|
+
return EXIT_WARN17;
|
|
35042
34697
|
} catch {
|
|
35043
34698
|
return EXIT_ALLOW29;
|
|
35044
34699
|
}
|
|
35045
34700
|
}
|
|
35046
|
-
function
|
|
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 (
|
|
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
|
|
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
|
|
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
|
|
35294
|
+
return EXIT_WARN18;
|
|
35640
35295
|
}
|
|
35641
35296
|
return 0;
|
|
35642
35297
|
}
|
|
35643
|
-
function
|
|
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 (
|
|
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
|
|
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
|
|
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 (!
|
|
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 (
|
|
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
|
|
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 (
|
|
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
|
|
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
|
|
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 (!
|
|
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
|
|
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 (
|
|
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
|
|
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
|
|
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 (!
|
|
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 =
|
|
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 (!
|
|
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 =
|
|
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
|
|
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 (
|
|
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
|
|
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 (
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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 (
|
|
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
|
|
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
|
|
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 (
|
|
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 (!
|
|
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
|
|
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 (
|
|
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/
|
|
37344
|
-
"src/scripts/
|
|
37345
|
-
"src/scripts/
|
|
37346
|
-
"src/scripts/
|
|
37347
|
-
"src/scripts/
|
|
37348
|
-
"src/scripts/
|
|
37349
|
-
"src/scripts/
|
|
37350
|
-
"src/scripts/
|
|
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":
|
|
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
|
|
37749
|
-
var
|
|
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
|
-
[
|
|
37765
|
-
[
|
|
37419
|
+
[EXIT_BLOCK5]: "block",
|
|
37420
|
+
[EXIT_WARN19]: "warn"
|
|
37766
37421
|
};
|
|
37767
|
-
function
|
|
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
|
|
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 (
|
|
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
|
|
37475
|
+
return _isObject16(data) ? data : {};
|
|
37821
37476
|
}
|
|
37822
37477
|
function _payload_tool_name(envelope) {
|
|
37823
37478
|
const payload = envelope["payload"];
|
|
37824
|
-
if (!
|
|
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 =
|
|
37853
|
-
if (!
|
|
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 (!
|
|
37521
|
+
if (!_isObject16(parsed)) return false;
|
|
37867
37522
|
const payload = parsed["payload"];
|
|
37868
|
-
const source =
|
|
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 =
|
|
37531
|
+
const platforms = _isObject16(platformsRaw) ? platformsRaw : {};
|
|
37877
37532
|
const block = platforms[platform];
|
|
37878
37533
|
if (!block) {
|
|
37879
37534
|
return [];
|
|
37880
37535
|
}
|
|
37881
|
-
if (
|
|
37536
|
+
if (_isObject16(block) && block["fallback_only"]) {
|
|
37882
37537
|
return [];
|
|
37883
37538
|
}
|
|
37884
|
-
const names =
|
|
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 =
|
|
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 || !
|
|
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 (!
|
|
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 ===
|
|
38141
|
-
return
|
|
37795
|
+
if (rcs.some((rc) => rc === EXIT_BLOCK5)) {
|
|
37796
|
+
return EXIT_BLOCK5;
|
|
38142
37797
|
}
|
|
38143
|
-
if (rcs.some((rc) => rc ===
|
|
38144
|
-
return
|
|
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"] ===
|
|
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 =
|
|
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 =
|
|
37905
|
+
const prev = _isObject16(prevRaw) ? prevRaw : { block: 0, warn: 0 };
|
|
38251
37906
|
concerns[name] = {
|
|
38252
|
-
block: (Number(prev["block"]) || 0) + (e["exit_code"] ===
|
|
38253
|
-
warn: (Number(prev["warn"]) || 0) + (e["exit_code"] ===
|
|
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(
|
|
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],
|
|
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 =
|
|
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 ===
|
|
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 =
|
|
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
|
|
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
|
|
38580
|
-
if (
|
|
38234
|
+
var isCliEntry15 = _isCliEntry51();
|
|
38235
|
+
if (isCliEntry15) {
|
|
38581
38236
|
process.exit(main65(process.argv.slice(2)));
|
|
38582
38237
|
}
|
|
38583
38238
|
|