greprag 5.77.0 → 5.78.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -24,9 +24,9 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
24
24
 
25
25
  // src/opencode-plugin.ts
26
26
  var crypto5 = __toESM(require("crypto"));
27
- var fs7 = __toESM(require("fs"));
28
- var os2 = __toESM(require("os"));
29
- var path7 = __toESM(require("path"));
27
+ var fs8 = __toESM(require("fs"));
28
+ var os3 = __toESM(require("os"));
29
+ var path8 = __toESM(require("path"));
30
30
 
31
31
  // src/opencode-plugin-helpers.ts
32
32
  var crypto = __toESM(require("crypto"));
@@ -2572,6 +2572,216 @@ function collectAnnounces(env, registry = REGISTRY) {
2572
2572
  return out;
2573
2573
  }
2574
2574
 
2575
+ // src/app-settings.ts
2576
+ var fs3 = __toESM(require("node:fs"));
2577
+ var os2 = __toESM(require("node:os"));
2578
+ var path3 = __toESM(require("node:path"));
2579
+
2580
+ // src/project-anchor.ts
2581
+ var path2 = __toESM(require("path"));
2582
+ var fs2 = __toESM(require("fs"));
2583
+ var crypto2 = __toESM(require("crypto"));
2584
+ var os = __toESM(require("os"));
2585
+ var ANCHOR_DIR = ".greprag";
2586
+ var ANCHOR_FILE = "project.json";
2587
+ var LEGACY_ANCHOR_DIR = ".claude";
2588
+ function anchorPathIn(dir) {
2589
+ return path2.join(dir, ANCHOR_DIR, ANCHOR_FILE);
2590
+ }
2591
+ function legacyAnchorPathIn(dir) {
2592
+ return path2.join(dir, LEGACY_ANCHOR_DIR, ANCHOR_FILE);
2593
+ }
2594
+ function globalAnchorPath() {
2595
+ return anchorPathIn(os.homedir());
2596
+ }
2597
+ function legacyGlobalAnchorPath() {
2598
+ return legacyAnchorPathIn(os.homedir());
2599
+ }
2600
+ function findExistingAnchor(startDir) {
2601
+ const homeAnchor = globalAnchorPath();
2602
+ const legacyHomeAnchor = legacyGlobalAnchorPath();
2603
+ let dir = path2.resolve(startDir);
2604
+ while (true) {
2605
+ const candidate = anchorPathIn(dir);
2606
+ if (candidate !== homeAnchor && fs2.existsSync(candidate))
2607
+ return candidate;
2608
+ const legacyCandidate = legacyAnchorPathIn(dir);
2609
+ if (legacyCandidate !== legacyHomeAnchor && fs2.existsSync(legacyCandidate))
2610
+ return legacyCandidate;
2611
+ const parent = path2.dirname(dir);
2612
+ if (parent === dir)
2613
+ return null;
2614
+ dir = parent;
2615
+ }
2616
+ }
2617
+ function isEphemeralCwd2(cwd) {
2618
+ const norm = path2.resolve(cwd).replace(/\\/g, "/").toLowerCase();
2619
+ if (norm.includes("/appdata/roaming/claude/local-agent-mode-sessions/"))
2620
+ return true;
2621
+ if (norm.includes("/appdata/local/claude/local-agent-mode-sessions/"))
2622
+ return true;
2623
+ if (norm.startsWith("/tmp/"))
2624
+ return true;
2625
+ if (norm.startsWith("/var/tmp/"))
2626
+ return true;
2627
+ if (norm.startsWith("/private/tmp/"))
2628
+ return true;
2629
+ return false;
2630
+ }
2631
+ function computeGitDerivedProjectId2(workingDir) {
2632
+ try {
2633
+ const out = safeExecSync("git rev-list --max-parents=0 HEAD", {
2634
+ cwd: workingDir,
2635
+ encoding: "utf-8",
2636
+ stdio: ["pipe", "pipe", "pipe"]
2637
+ });
2638
+ const roots = out.trim().split(/\s+/).filter(Boolean).sort();
2639
+ if (roots.length === 0)
2640
+ return null;
2641
+ const hash = crypto2.createHash("sha256").update(roots.join("\n")).digest("hex");
2642
+ return [
2643
+ hash.slice(0, 8),
2644
+ hash.slice(8, 12),
2645
+ "4" + hash.slice(13, 16),
2646
+ // version 4 nibble
2647
+ "8" + hash.slice(17, 20),
2648
+ // variant nibble
2649
+ hash.slice(20, 32)
2650
+ ].join("-");
2651
+ } catch {
2652
+ return null;
2653
+ }
2654
+ }
2655
+ function deterministicProjectId2(workingDir) {
2656
+ const normalized = path2.resolve(workingDir).toLowerCase();
2657
+ const hash = crypto2.createHash("sha256").update(normalized).digest("hex");
2658
+ return [
2659
+ hash.slice(0, 8),
2660
+ hash.slice(8, 12),
2661
+ "4" + hash.slice(13, 16),
2662
+ // version 4 nibble
2663
+ "8" + hash.slice(17, 20),
2664
+ // variant nibble
2665
+ hash.slice(20, 32)
2666
+ ].join("-");
2667
+ }
2668
+ function tryReadAnchorFileContents(filePath) {
2669
+ try {
2670
+ const raw = JSON.parse(fs2.readFileSync(filePath, "utf-8"));
2671
+ const notifyRaw = raw.inbox_notify;
2672
+ const inboxNotify = notifyRaw === "off" || notifyRaw === "session_start_only" ? notifyRaw : "every_turn";
2673
+ return {
2674
+ projectId: raw.project_id,
2675
+ projectName: raw.project_name,
2676
+ created: raw.created,
2677
+ memoryCapture: raw.memory_capture !== false,
2678
+ sessionStartRecap: raw.session_start_recap !== false,
2679
+ inboxNotify,
2680
+ emailDir: typeof raw.email_dir === "string" ? raw.email_dir : void 0,
2681
+ emailAutosave: raw.email_autosave === true,
2682
+ role: typeof raw.role === "string" ? raw.role : void 0
2683
+ };
2684
+ } catch {
2685
+ return null;
2686
+ }
2687
+ }
2688
+ function readAnchor2(cwd) {
2689
+ const existingPath = findExistingAnchor(cwd);
2690
+ const fileContents = existingPath ? tryReadAnchorFileContents(existingPath) : null;
2691
+ if (existingPath && fileContents && fileContents.projectId && fileContents.projectName) {
2692
+ return {
2693
+ projectId: fileContents.projectId,
2694
+ projectName: fileContents.projectName,
2695
+ initialized: true,
2696
+ source: "file",
2697
+ anchorPath: existingPath,
2698
+ created: fileContents.created,
2699
+ memoryCapture: fileContents.memoryCapture,
2700
+ sessionStartRecap: fileContents.sessionStartRecap,
2701
+ inboxNotify: fileContents.inboxNotify,
2702
+ emailDir: fileContents.emailDir,
2703
+ emailAutosave: fileContents.emailAutosave,
2704
+ role: fileContents.role
2705
+ };
2706
+ }
2707
+ const gitId = computeGitDerivedProjectId2(cwd);
2708
+ if (gitId) {
2709
+ const root2 = path2.resolve(cwd);
2710
+ return {
2711
+ projectId: gitId,
2712
+ projectName: fileContents?.projectName || path2.basename(root2).toLowerCase(),
2713
+ initialized: true,
2714
+ source: "git",
2715
+ anchorPath: existingPath || anchorPathIn(root2),
2716
+ created: fileContents?.created,
2717
+ memoryCapture: fileContents?.memoryCapture ?? true,
2718
+ sessionStartRecap: fileContents?.sessionStartRecap ?? true,
2719
+ inboxNotify: fileContents?.inboxNotify ?? "every_turn",
2720
+ emailDir: fileContents?.emailDir,
2721
+ emailAutosave: fileContents?.emailAutosave,
2722
+ role: fileContents?.role
2723
+ };
2724
+ }
2725
+ if (isEphemeralCwd2(cwd)) {
2726
+ const globalPath = fs2.existsSync(globalAnchorPath()) ? globalAnchorPath() : legacyGlobalAnchorPath();
2727
+ const globalContents = tryReadAnchorFileContents(globalPath);
2728
+ if (globalContents && globalContents.projectId && globalContents.projectName) {
2729
+ return {
2730
+ projectId: globalContents.projectId,
2731
+ projectName: globalContents.projectName,
2732
+ initialized: true,
2733
+ source: "global",
2734
+ anchorPath: globalPath,
2735
+ created: globalContents.created,
2736
+ memoryCapture: globalContents.memoryCapture,
2737
+ sessionStartRecap: globalContents.sessionStartRecap,
2738
+ inboxNotify: globalContents.inboxNotify,
2739
+ emailDir: globalContents.emailDir,
2740
+ emailAutosave: globalContents.emailAutosave,
2741
+ role: globalContents.role
2742
+ };
2743
+ }
2744
+ }
2745
+ const root = path2.resolve(cwd);
2746
+ return {
2747
+ projectId: deterministicProjectId2(root),
2748
+ projectName: fileContents?.projectName || path2.basename(root).toLowerCase(),
2749
+ initialized: false,
2750
+ source: "hash",
2751
+ anchorPath: existingPath || anchorPathIn(root),
2752
+ created: fileContents?.created,
2753
+ memoryCapture: fileContents?.memoryCapture ?? true,
2754
+ sessionStartRecap: fileContents?.sessionStartRecap ?? true,
2755
+ inboxNotify: fileContents?.inboxNotify ?? "every_turn",
2756
+ emailDir: fileContents?.emailDir,
2757
+ emailAutosave: fileContents?.emailAutosave,
2758
+ role: fileContents?.role
2759
+ };
2760
+ }
2761
+
2762
+ // src/app-settings.ts
2763
+ function readJson(file) {
2764
+ try {
2765
+ const parsed = JSON.parse(fs3.readFileSync(file, "utf8"));
2766
+ return parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : {};
2767
+ } catch {
2768
+ return {};
2769
+ }
2770
+ }
2771
+ function localAppSettingsPath(homeDir = os2.homedir()) {
2772
+ return path3.join(homeDir, ".greprag", "settings.json");
2773
+ }
2774
+ function readLocalAppSettings(homeDir = os2.homedir()) {
2775
+ const raw = readJson(localAppSettingsPath(homeDir));
2776
+ const interrupts = raw.interrupts && typeof raw.interrupts === "object" ? raw.interrupts : {};
2777
+ const disabled = Array.isArray(interrupts.disabled) ? [...new Set(interrupts.disabled.filter((id) => typeof id === "string" && /^[a-z0-9-]{1,80}$/.test(id)))] : [];
2778
+ return { version: 1, interrupts: { disabled } };
2779
+ }
2780
+ function filterEnabledInterrupts(modules, settings = readLocalAppSettings()) {
2781
+ const disabled = new Set(settings.interrupts.disabled);
2782
+ return modules.filter((module2) => !disabled.has(module2.id));
2783
+ }
2784
+
2575
2785
  // src/commands/opencode-interrupt.ts
2576
2786
  var opencodeRegistry = harnessModules("opencode");
2577
2787
  var OPENCODE_QUOTA_WAITLIST_ANNOUNCE = [
@@ -2606,18 +2816,18 @@ function buildOpenCodeEnv(params) {
2606
2816
  };
2607
2817
  }
2608
2818
  function getOpenCodeAnnounces(env) {
2609
- return [...collectAnnounces(env, opencodeRegistry), OPENCODE_QUOTA_WAITLIST_ANNOUNCE];
2819
+ return [...collectAnnounces(env, filterEnabledInterrupts(opencodeRegistry)), OPENCODE_QUOTA_WAITLIST_ANNOUNCE];
2610
2820
  }
2611
2821
  function getOpenCodePersistentAnnounces(env) {
2612
- return collectAnnounces(env, opencodeRegistry.filter((m) => m.id === "persona-announce"));
2822
+ return collectAnnounces(env, filterEnabledInterrupts(opencodeRegistry.filter((m) => m.id === "persona-announce")));
2613
2823
  }
2614
2824
  function getOpenCodeReminders(env) {
2615
- return collectReminders(env, opencodeRegistry);
2825
+ return collectReminders(env, filterEnabledInterrupts(opencodeRegistry));
2616
2826
  }
2617
2827
 
2618
2828
  // src/procedure.ts
2619
- var path2 = __toESM(require("path"));
2620
- var fs2 = __toESM(require("fs"));
2829
+ var path4 = __toESM(require("path"));
2830
+ var fs4 = __toESM(require("fs"));
2621
2831
 
2622
2832
  // src/delivery-lifecycle.ts
2623
2833
  var DELIVERY_LIFECYCLE_VERBS = [
@@ -2636,14 +2846,14 @@ function isDeliveryLifecycleVerb(verb) {
2636
2846
  var PROCEDURE_STORE_VERSION = "2";
2637
2847
  function stateDir() {
2638
2848
  const home = process.env.HOME || process.env.USERPROFILE || "";
2639
- return path2.join(home, ".greprag", "state");
2849
+ return path4.join(home, ".greprag", "state");
2640
2850
  }
2641
2851
  function procedureStorePath(projectId) {
2642
- return path2.join(stateDir(), `procedures-${projectId}.json`);
2852
+ return path4.join(stateDir(), `procedures-${projectId}.json`);
2643
2853
  }
2644
2854
  function readProcedureStore(projectId) {
2645
2855
  try {
2646
- const raw = fs2.readFileSync(procedureStorePath(projectId), "utf-8");
2856
+ const raw = fs4.readFileSync(procedureStorePath(projectId), "utf-8");
2647
2857
  const parsed = JSON.parse(raw);
2648
2858
  if (parsed && Array.isArray(parsed.procedures)) {
2649
2859
  return normalizeProcedureStore({
@@ -2876,191 +3086,9 @@ function activeProcedureAnnounces(store) {
2876
3086
  // src/procedure-runtime.ts
2877
3087
  var crypto4 = __toESM(require("crypto"));
2878
3088
 
2879
- // src/project-anchor.ts
2880
- var path3 = __toESM(require("path"));
2881
- var fs3 = __toESM(require("fs"));
2882
- var crypto2 = __toESM(require("crypto"));
2883
- var os = __toESM(require("os"));
2884
- var ANCHOR_DIR = ".greprag";
2885
- var ANCHOR_FILE = "project.json";
2886
- var LEGACY_ANCHOR_DIR = ".claude";
2887
- function anchorPathIn(dir) {
2888
- return path3.join(dir, ANCHOR_DIR, ANCHOR_FILE);
2889
- }
2890
- function legacyAnchorPathIn(dir) {
2891
- return path3.join(dir, LEGACY_ANCHOR_DIR, ANCHOR_FILE);
2892
- }
2893
- function globalAnchorPath() {
2894
- return anchorPathIn(os.homedir());
2895
- }
2896
- function legacyGlobalAnchorPath() {
2897
- return legacyAnchorPathIn(os.homedir());
2898
- }
2899
- function findExistingAnchor(startDir) {
2900
- const homeAnchor = globalAnchorPath();
2901
- const legacyHomeAnchor = legacyGlobalAnchorPath();
2902
- let dir = path3.resolve(startDir);
2903
- while (true) {
2904
- const candidate = anchorPathIn(dir);
2905
- if (candidate !== homeAnchor && fs3.existsSync(candidate))
2906
- return candidate;
2907
- const legacyCandidate = legacyAnchorPathIn(dir);
2908
- if (legacyCandidate !== legacyHomeAnchor && fs3.existsSync(legacyCandidate))
2909
- return legacyCandidate;
2910
- const parent = path3.dirname(dir);
2911
- if (parent === dir)
2912
- return null;
2913
- dir = parent;
2914
- }
2915
- }
2916
- function isEphemeralCwd2(cwd) {
2917
- const norm = path3.resolve(cwd).replace(/\\/g, "/").toLowerCase();
2918
- if (norm.includes("/appdata/roaming/claude/local-agent-mode-sessions/"))
2919
- return true;
2920
- if (norm.includes("/appdata/local/claude/local-agent-mode-sessions/"))
2921
- return true;
2922
- if (norm.startsWith("/tmp/"))
2923
- return true;
2924
- if (norm.startsWith("/var/tmp/"))
2925
- return true;
2926
- if (norm.startsWith("/private/tmp/"))
2927
- return true;
2928
- return false;
2929
- }
2930
- function computeGitDerivedProjectId2(workingDir) {
2931
- try {
2932
- const out = safeExecSync("git rev-list --max-parents=0 HEAD", {
2933
- cwd: workingDir,
2934
- encoding: "utf-8",
2935
- stdio: ["pipe", "pipe", "pipe"]
2936
- });
2937
- const roots = out.trim().split(/\s+/).filter(Boolean).sort();
2938
- if (roots.length === 0)
2939
- return null;
2940
- const hash = crypto2.createHash("sha256").update(roots.join("\n")).digest("hex");
2941
- return [
2942
- hash.slice(0, 8),
2943
- hash.slice(8, 12),
2944
- "4" + hash.slice(13, 16),
2945
- // version 4 nibble
2946
- "8" + hash.slice(17, 20),
2947
- // variant nibble
2948
- hash.slice(20, 32)
2949
- ].join("-");
2950
- } catch {
2951
- return null;
2952
- }
2953
- }
2954
- function deterministicProjectId2(workingDir) {
2955
- const normalized = path3.resolve(workingDir).toLowerCase();
2956
- const hash = crypto2.createHash("sha256").update(normalized).digest("hex");
2957
- return [
2958
- hash.slice(0, 8),
2959
- hash.slice(8, 12),
2960
- "4" + hash.slice(13, 16),
2961
- // version 4 nibble
2962
- "8" + hash.slice(17, 20),
2963
- // variant nibble
2964
- hash.slice(20, 32)
2965
- ].join("-");
2966
- }
2967
- function tryReadAnchorFileContents(filePath) {
2968
- try {
2969
- const raw = JSON.parse(fs3.readFileSync(filePath, "utf-8"));
2970
- const notifyRaw = raw.inbox_notify;
2971
- const inboxNotify = notifyRaw === "off" || notifyRaw === "session_start_only" ? notifyRaw : "every_turn";
2972
- return {
2973
- projectId: raw.project_id,
2974
- projectName: raw.project_name,
2975
- created: raw.created,
2976
- memoryCapture: raw.memory_capture !== false,
2977
- sessionStartRecap: raw.session_start_recap !== false,
2978
- inboxNotify,
2979
- emailDir: typeof raw.email_dir === "string" ? raw.email_dir : void 0,
2980
- emailAutosave: raw.email_autosave === true,
2981
- role: typeof raw.role === "string" ? raw.role : void 0
2982
- };
2983
- } catch {
2984
- return null;
2985
- }
2986
- }
2987
- function readAnchor2(cwd) {
2988
- const existingPath = findExistingAnchor(cwd);
2989
- const fileContents = existingPath ? tryReadAnchorFileContents(existingPath) : null;
2990
- if (existingPath && fileContents && fileContents.projectId && fileContents.projectName) {
2991
- return {
2992
- projectId: fileContents.projectId,
2993
- projectName: fileContents.projectName,
2994
- initialized: true,
2995
- source: "file",
2996
- anchorPath: existingPath,
2997
- created: fileContents.created,
2998
- memoryCapture: fileContents.memoryCapture,
2999
- sessionStartRecap: fileContents.sessionStartRecap,
3000
- inboxNotify: fileContents.inboxNotify,
3001
- emailDir: fileContents.emailDir,
3002
- emailAutosave: fileContents.emailAutosave,
3003
- role: fileContents.role
3004
- };
3005
- }
3006
- const gitId = computeGitDerivedProjectId2(cwd);
3007
- if (gitId) {
3008
- const root2 = path3.resolve(cwd);
3009
- return {
3010
- projectId: gitId,
3011
- projectName: fileContents?.projectName || path3.basename(root2).toLowerCase(),
3012
- initialized: true,
3013
- source: "git",
3014
- anchorPath: existingPath || anchorPathIn(root2),
3015
- created: fileContents?.created,
3016
- memoryCapture: fileContents?.memoryCapture ?? true,
3017
- sessionStartRecap: fileContents?.sessionStartRecap ?? true,
3018
- inboxNotify: fileContents?.inboxNotify ?? "every_turn",
3019
- emailDir: fileContents?.emailDir,
3020
- emailAutosave: fileContents?.emailAutosave,
3021
- role: fileContents?.role
3022
- };
3023
- }
3024
- if (isEphemeralCwd2(cwd)) {
3025
- const globalPath = fs3.existsSync(globalAnchorPath()) ? globalAnchorPath() : legacyGlobalAnchorPath();
3026
- const globalContents = tryReadAnchorFileContents(globalPath);
3027
- if (globalContents && globalContents.projectId && globalContents.projectName) {
3028
- return {
3029
- projectId: globalContents.projectId,
3030
- projectName: globalContents.projectName,
3031
- initialized: true,
3032
- source: "global",
3033
- anchorPath: globalPath,
3034
- created: globalContents.created,
3035
- memoryCapture: globalContents.memoryCapture,
3036
- sessionStartRecap: globalContents.sessionStartRecap,
3037
- inboxNotify: globalContents.inboxNotify,
3038
- emailDir: globalContents.emailDir,
3039
- emailAutosave: globalContents.emailAutosave,
3040
- role: globalContents.role
3041
- };
3042
- }
3043
- }
3044
- const root = path3.resolve(cwd);
3045
- return {
3046
- projectId: deterministicProjectId2(root),
3047
- projectName: fileContents?.projectName || path3.basename(root).toLowerCase(),
3048
- initialized: false,
3049
- source: "hash",
3050
- anchorPath: existingPath || anchorPathIn(root),
3051
- created: fileContents?.created,
3052
- memoryCapture: fileContents?.memoryCapture ?? true,
3053
- sessionStartRecap: fileContents?.sessionStartRecap ?? true,
3054
- inboxNotify: fileContents?.inboxNotify ?? "every_turn",
3055
- emailDir: fileContents?.emailDir,
3056
- emailAutosave: fileContents?.emailAutosave,
3057
- role: fileContents?.role
3058
- };
3059
- }
3060
-
3061
3089
  // src/procedure-watch.ts
3062
- var path4 = __toESM(require("path"));
3063
- var fs4 = __toESM(require("fs"));
3090
+ var path5 = __toESM(require("path"));
3091
+ var fs5 = __toESM(require("fs"));
3064
3092
  var TIER1_LEARN_TRIGGERS = [
3065
3093
  { verb: "deploy", triggers: ["deploy", "deploy the api", "deploy the worker", "redeploy"], steps: "", status: "seeded" },
3066
3094
  { verb: "push", triggers: ["push", "git push", "push to remote", "push it up", "push upstream"], steps: "", status: "seeded", destructive: true },
@@ -3093,24 +3121,24 @@ function openWatch(verb, phase, openedAt, shadowRunId) {
3093
3121
  }
3094
3122
  function stateDir2() {
3095
3123
  const home = process.env.HOME || process.env.USERPROFILE || "";
3096
- return path4.join(home, ".greprag", "state");
3124
+ return path5.join(home, ".greprag", "state");
3097
3125
  }
3098
3126
  function procedureWatchPath(projectId) {
3099
- return path4.join(stateDir2(), `procedure-watch-${projectId}.json`);
3127
+ return path5.join(stateDir2(), `procedure-watch-${projectId}.json`);
3100
3128
  }
3101
3129
  function hasProcedureWatch(projectId) {
3102
3130
  try {
3103
- return fs4.existsSync(procedureWatchPath(projectId));
3131
+ return fs5.existsSync(procedureWatchPath(projectId));
3104
3132
  } catch {
3105
3133
  return false;
3106
3134
  }
3107
3135
  }
3108
3136
  function writeProcedureWatch(projectId, watch) {
3109
3137
  const file = procedureWatchPath(projectId);
3110
- const dir = path4.dirname(file);
3111
- if (!fs4.existsSync(dir))
3112
- fs4.mkdirSync(dir, { recursive: true });
3113
- fs4.writeFileSync(file, JSON.stringify(watch, null, 2) + "\n");
3138
+ const dir = path5.dirname(file);
3139
+ if (!fs5.existsSync(dir))
3140
+ fs5.mkdirSync(dir, { recursive: true });
3141
+ fs5.writeFileSync(file, JSON.stringify(watch, null, 2) + "\n");
3114
3142
  }
3115
3143
  function openWatchIfIdle(projectId, verb, phase, shadowRunId) {
3116
3144
  if (hasProcedureWatch(projectId))
@@ -3121,20 +3149,20 @@ function openWatchIfIdle(projectId, verb, phase, shadowRunId) {
3121
3149
 
3122
3150
  // src/procedure-shadow.ts
3123
3151
  var crypto3 = __toESM(require("crypto"));
3124
- var fs5 = __toESM(require("fs"));
3125
- var path5 = __toESM(require("path"));
3152
+ var fs6 = __toESM(require("fs"));
3153
+ var path6 = __toESM(require("path"));
3126
3154
  function stateDir3() {
3127
3155
  const home = process.env.HOME || process.env.USERPROFILE || "";
3128
- return path5.join(home, ".greprag", "state");
3156
+ return path6.join(home, ".greprag", "state");
3129
3157
  }
3130
3158
  function procedureShadowPath(projectId) {
3131
- return path5.join(stateDir3(), `procedure-shadow-${projectId}.jsonl`);
3159
+ return path6.join(stateDir3(), `procedure-shadow-${projectId}.jsonl`);
3132
3160
  }
3133
3161
  function appendShadowEvent(projectId, event) {
3134
3162
  try {
3135
3163
  const file = procedureShadowPath(projectId);
3136
- fs5.mkdirSync(path5.dirname(file), { recursive: true });
3137
- fs5.appendFileSync(file, JSON.stringify(event) + "\n");
3164
+ fs6.mkdirSync(path6.dirname(file), { recursive: true });
3165
+ fs6.appendFileSync(file, JSON.stringify(event) + "\n");
3138
3166
  } catch {
3139
3167
  }
3140
3168
  }
@@ -3854,29 +3882,29 @@ function recodeMessagesToPng(messages, opts) {
3854
3882
  }
3855
3883
 
3856
3884
  // src/skill-activation-manifest.ts
3857
- var fs6 = __toESM(require("fs"));
3858
- var path6 = __toESM(require("path"));
3885
+ var fs7 = __toESM(require("fs"));
3886
+ var path7 = __toESM(require("path"));
3859
3887
  var MAX_NATIVE_SKILL_FILES = 1500;
3860
3888
  var MAX_SCAN_DEPTH = 7;
3861
3889
  function homeRoots(homeDir, platform) {
3862
3890
  if (platform === "claude-code") {
3863
- return [path6.join(homeDir, ".claude", "skills")];
3891
+ return [path7.join(homeDir, ".claude", "skills")];
3864
3892
  }
3865
3893
  if (platform === "codex") {
3866
3894
  return [
3867
- path6.join(homeDir, ".codex", "skills"),
3868
- path6.join(homeDir, ".agents", "skills"),
3869
- path6.join(homeDir, ".codex", "plugins", "cache")
3895
+ path7.join(homeDir, ".codex", "skills"),
3896
+ path7.join(homeDir, ".agents", "skills"),
3897
+ path7.join(homeDir, ".codex", "plugins", "cache")
3870
3898
  ];
3871
3899
  }
3872
- return [path6.join(homeDir, ".config", "opencode", "skills")];
3900
+ return [path7.join(homeDir, ".config", "opencode", "skills")];
3873
3901
  }
3874
3902
  function ancestorDirs(cwd) {
3875
3903
  const dirs = [];
3876
- let current = path6.resolve(cwd);
3904
+ let current = path7.resolve(cwd);
3877
3905
  for (let depth = 0; depth < 16; depth++) {
3878
3906
  dirs.push(current);
3879
- const parent = path6.dirname(current);
3907
+ const parent = path7.dirname(current);
3880
3908
  if (parent === current)
3881
3909
  break;
3882
3910
  current = parent;
@@ -3886,11 +3914,11 @@ function ancestorDirs(cwd) {
3886
3914
  function repoRoots(cwd, platform) {
3887
3915
  return ancestorDirs(cwd).flatMap((dir) => {
3888
3916
  if (platform === "claude-code")
3889
- return [path6.join(dir, ".claude", "skills")];
3917
+ return [path7.join(dir, ".claude", "skills")];
3890
3918
  if (platform === "codex") {
3891
- return [path6.join(dir, ".codex", "skills"), path6.join(dir, ".agents", "skills")];
3919
+ return [path7.join(dir, ".codex", "skills"), path7.join(dir, ".agents", "skills")];
3892
3920
  }
3893
- return [path6.join(dir, ".opencode", "skills")];
3921
+ return [path7.join(dir, ".opencode", "skills")];
3894
3922
  });
3895
3923
  }
3896
3924
  function frontmatterName(content) {
@@ -3906,14 +3934,14 @@ function readNativeSkillNames(params) {
3906
3934
  return;
3907
3935
  let entries;
3908
3936
  try {
3909
- entries = fs6.readdirSync(dir, { withFileTypes: true });
3937
+ entries = fs7.readdirSync(dir, { withFileTypes: true });
3910
3938
  } catch {
3911
3939
  return;
3912
3940
  }
3913
3941
  for (const entry of entries) {
3914
3942
  if (visited >= MAX_NATIVE_SKILL_FILES)
3915
3943
  return;
3916
- const full = path6.join(dir, entry.name);
3944
+ const full = path7.join(dir, entry.name);
3917
3945
  if (entry.isDirectory()) {
3918
3946
  walk(full, depth + 1);
3919
3947
  continue;
@@ -3921,9 +3949,9 @@ function readNativeSkillNames(params) {
3921
3949
  if (!entry.isFile() || entry.name.toLowerCase() !== "skill.md")
3922
3950
  continue;
3923
3951
  visited++;
3924
- names.add(path6.basename(path6.dirname(full)).toLowerCase());
3952
+ names.add(path7.basename(path7.dirname(full)).toLowerCase());
3925
3953
  try {
3926
- const declared = frontmatterName(fs6.readFileSync(full, "utf8"));
3954
+ const declared = frontmatterName(fs7.readFileSync(full, "utf8"));
3927
3955
  if (declared)
3928
3956
  names.add(declared.toLowerCase());
3929
3957
  } catch {
@@ -3955,14 +3983,14 @@ function activationFromApiRows(params) {
3955
3983
  }
3956
3984
 
3957
3985
  // src/opencode-plugin.ts
3958
- var DEBUG_LOG_PATH = path7.join(os2.homedir(), ".greprag", "opencode-plugin-debug.log");
3986
+ var DEBUG_LOG_PATH = path8.join(os3.homedir(), ".greprag", "opencode-plugin-debug.log");
3959
3987
  var _debugLogReady = false;
3960
3988
  function dlogInit() {
3961
3989
  if (_debugLogReady)
3962
3990
  return;
3963
3991
  _debugLogReady = true;
3964
3992
  try {
3965
- fs7.writeFileSync(DEBUG_LOG_PATH, "");
3993
+ fs8.writeFileSync(DEBUG_LOG_PATH, "");
3966
3994
  } catch {
3967
3995
  }
3968
3996
  }
@@ -3971,7 +3999,7 @@ function dlog(msg) {
3971
3999
  const line = `[${(/* @__PURE__ */ new Date()).toISOString()}] [greprag-memory] ${msg}
3972
4000
  `;
3973
4001
  try {
3974
- fs7.appendFileSync(DEBUG_LOG_PATH, line);
4002
+ fs8.appendFileSync(DEBUG_LOG_PATH, line);
3975
4003
  } catch {
3976
4004
  }
3977
4005
  }
@@ -3979,9 +4007,9 @@ dlog(`module top reached: pid=${process.pid} argv0=${process.argv[0]} distPath=$
3979
4007
  var API_URL = "https://api.greprag.com";
3980
4008
  function loadEnvFile(filePath) {
3981
4009
  try {
3982
- if (!fs7.existsSync(filePath))
4010
+ if (!fs8.existsSync(filePath))
3983
4011
  return;
3984
- const raw = fs7.readFileSync(filePath, "utf-8");
4012
+ const raw = fs8.readFileSync(filePath, "utf-8");
3985
4013
  for (const line of raw.split(/\r?\n/)) {
3986
4014
  const trimmed = line.trim();
3987
4015
  if (!trimmed || trimmed.startsWith("#"))
@@ -4001,12 +4029,12 @@ function loadEnvFile(filePath) {
4001
4029
  }
4002
4030
  }
4003
4031
  function loadGrepragEnv() {
4004
- loadEnvFile(path7.join(HOME, ".greprag", ".env"));
4032
+ loadEnvFile(path8.join(HOME, ".greprag", ".env"));
4005
4033
  try {
4006
- const p = path7.join(HOME, ".claude", "settings.json");
4007
- if (!fs7.existsSync(p))
4034
+ const p = path8.join(HOME, ".claude", "settings.json");
4035
+ if (!fs8.existsSync(p))
4008
4036
  return;
4009
- const data = JSON.parse(fs7.readFileSync(p, "utf-8"));
4037
+ const data = JSON.parse(fs8.readFileSync(p, "utf-8"));
4010
4038
  if (data && data.env && typeof data.env === "object") {
4011
4039
  for (const [key, val] of Object.entries(data.env)) {
4012
4040
  if (!process.env[key] && typeof val === "string") {
@@ -4019,11 +4047,11 @@ function loadGrepragEnv() {
4019
4047
  }
4020
4048
  loadGrepragEnv();
4021
4049
  dlog(`env loaded: MEMORY_HOOK_ENABLED=${process.env.MEMORY_HOOK_ENABLED || "<unset>"} GREPRAG_API_KEY=${process.env.GREPRAG_API_KEY ? "set" : "<unset>"} GREPRAG_OPENCODE_CAPTURE=${process.env.GREPRAG_OPENCODE_CAPTURE || "<unset>"}`);
4022
- var WATCHER_LOCK = path7.join(HOME || os2.homedir(), ".greprag", "opencode-watch.lock");
4050
+ var WATCHER_LOCK = path8.join(HOME || os3.homedir(), ".greprag", "opencode-watch.lock");
4023
4051
  var WATCHER_STALE_MS = 3e4;
4024
4052
  function findGrepragBinary() {
4025
4053
  const override = process.env.GREPRAG_BIN;
4026
- if (override && fs7.existsSync(override))
4054
+ if (override && fs8.existsSync(override))
4027
4055
  return override;
4028
4056
  const binaryName = process.platform === "win32" ? "greprag.cmd" : "greprag";
4029
4057
  try {
@@ -4032,14 +4060,14 @@ function findGrepragBinary() {
4032
4060
  const candidate = line.trim();
4033
4061
  if (!candidate)
4034
4062
  continue;
4035
- if (!fs7.existsSync(candidate))
4063
+ if (!fs8.existsSync(candidate))
4036
4064
  continue;
4037
4065
  if (process.platform === "win32") {
4038
- const ext = path7.extname(candidate).toLowerCase();
4066
+ const ext = path8.extname(candidate).toLowerCase();
4039
4067
  if (ext === ".cmd" || ext === ".exe" || ext === ".bat")
4040
4068
  return candidate;
4041
4069
  const cmdSibling = candidate + ".cmd";
4042
- if (fs7.existsSync(cmdSibling))
4070
+ if (fs8.existsSync(cmdSibling))
4043
4071
  return cmdSibling;
4044
4072
  continue;
4045
4073
  }
@@ -4048,19 +4076,19 @@ function findGrepragBinary() {
4048
4076
  } catch {
4049
4077
  }
4050
4078
  const candidates = process.platform === "win32" ? [
4051
- path7.join(HOME, "AppData", "Roaming", "npm", "greprag.cmd"),
4052
- path7.join(HOME, "AppData", "Roaming", "npm", "greprag"),
4053
- path7.join(HOME, "AppData", "Local", "Yarn", "bin", "greprag.cmd"),
4054
- path7.join(HOME, "AppData", "Local", "pnpm", "bin", "greprag.cmd")
4079
+ path8.join(HOME, "AppData", "Roaming", "npm", "greprag.cmd"),
4080
+ path8.join(HOME, "AppData", "Roaming", "npm", "greprag"),
4081
+ path8.join(HOME, "AppData", "Local", "Yarn", "bin", "greprag.cmd"),
4082
+ path8.join(HOME, "AppData", "Local", "pnpm", "bin", "greprag.cmd")
4055
4083
  ] : [
4056
4084
  "/usr/local/bin/greprag",
4057
4085
  "/opt/homebrew/bin/greprag",
4058
- path7.join(HOME || "", ".local", "bin", "greprag"),
4059
- path7.join(HOME || "", ".yarn", "bin", "greprag")
4086
+ path8.join(HOME || "", ".local", "bin", "greprag"),
4087
+ path8.join(HOME || "", ".yarn", "bin", "greprag")
4060
4088
  ];
4061
4089
  for (const c of candidates) {
4062
4090
  try {
4063
- if (c && fs7.existsSync(c))
4091
+ if (c && fs8.existsSync(c))
4064
4092
  return c;
4065
4093
  } catch {
4066
4094
  }
@@ -4069,18 +4097,18 @@ function findGrepragBinary() {
4069
4097
  }
4070
4098
  function tryClaimWatcherLock() {
4071
4099
  try {
4072
- const fd = fs7.openSync(WATCHER_LOCK, "wx");
4100
+ const fd = fs8.openSync(WATCHER_LOCK, "wx");
4073
4101
  return { ok: true, fd };
4074
4102
  } catch (err) {
4075
4103
  if (err.code !== "EEXIST") {
4076
4104
  return { ok: false, reason: "lock-create-failed" };
4077
4105
  }
4078
4106
  try {
4079
- const stat = fs7.statSync(WATCHER_LOCK);
4107
+ const stat = fs8.statSync(WATCHER_LOCK);
4080
4108
  const ageMs = Date.now() - stat.mtimeMs;
4081
4109
  let pidAlive = false;
4082
4110
  try {
4083
- const pid = parseInt(fs7.readFileSync(WATCHER_LOCK, "utf-8").trim(), 10);
4111
+ const pid = parseInt(fs8.readFileSync(WATCHER_LOCK, "utf-8").trim(), 10);
4084
4112
  pidAlive = pid > 0 && isPidAlive(pid);
4085
4113
  } catch {
4086
4114
  }
@@ -4088,10 +4116,10 @@ function tryClaimWatcherLock() {
4088
4116
  return { ok: false, reason: "busy" };
4089
4117
  }
4090
4118
  try {
4091
- fs7.unlinkSync(WATCHER_LOCK);
4119
+ fs8.unlinkSync(WATCHER_LOCK);
4092
4120
  } catch {
4093
4121
  }
4094
- const fd = fs7.openSync(WATCHER_LOCK, "wx");
4122
+ const fd = fs8.openSync(WATCHER_LOCK, "wx");
4095
4123
  return { ok: true, fd };
4096
4124
  } catch (err2) {
4097
4125
  return { ok: false, reason: "lock-stale-replace-failed" };
@@ -4132,11 +4160,11 @@ function startCaptureWatcher() {
4132
4160
  return;
4133
4161
  }
4134
4162
  try {
4135
- fs7.writeSync(claim.fd, String(process.pid));
4136
- fs7.closeSync(claim.fd);
4163
+ fs8.writeSync(claim.fd, String(process.pid));
4164
+ fs8.closeSync(claim.fd);
4137
4165
  } catch {
4138
4166
  try {
4139
- fs7.unlinkSync(WATCHER_LOCK);
4167
+ fs8.unlinkSync(WATCHER_LOCK);
4140
4168
  } catch {
4141
4169
  }
4142
4170
  return;
@@ -4152,11 +4180,11 @@ function startCaptureWatcher() {
4152
4180
  const claim2 = tryClaimWatcherLock();
4153
4181
  if (claim2.ok) {
4154
4182
  try {
4155
- fs7.writeSync(claim2.fd, String(process.pid));
4156
- fs7.closeSync(claim2.fd);
4183
+ fs8.writeSync(claim2.fd, String(process.pid));
4184
+ fs8.closeSync(claim2.fd);
4157
4185
  } catch {
4158
4186
  try {
4159
- fs7.unlinkSync(WATCHER_LOCK);
4187
+ fs8.unlinkSync(WATCHER_LOCK);
4160
4188
  } catch {
4161
4189
  }
4162
4190
  return false;
@@ -4199,7 +4227,7 @@ function startCaptureWatcher() {
4199
4227
  childStartTime = Date.now();
4200
4228
  dlog(`startCaptureWatcher: spawned 'greprag opencode watch' pid=${child.pid ?? "<none>"}`);
4201
4229
  try {
4202
- fs7.writeFileSync(WATCHER_LOCK, String(child.pid));
4230
+ fs8.writeFileSync(WATCHER_LOCK, String(child.pid));
4203
4231
  } catch {
4204
4232
  }
4205
4233
  child.stderr?.on("data", (chunk2) => {
@@ -4211,9 +4239,9 @@ function startCaptureWatcher() {
4211
4239
  child.on("exit", (code, signal) => {
4212
4240
  dlog(`startCaptureWatcher: child pid=${child.pid ?? "<none>"} exited code=${code} signal=${signal || "none"}`);
4213
4241
  try {
4214
- const current = fs7.readFileSync(WATCHER_LOCK, "utf-8").trim();
4242
+ const current = fs8.readFileSync(WATCHER_LOCK, "utf-8").trim();
4215
4243
  if (current === String(child.pid))
4216
- fs7.unlinkSync(WATCHER_LOCK);
4244
+ fs8.unlinkSync(WATCHER_LOCK);
4217
4245
  } catch {
4218
4246
  }
4219
4247
  currentChild = null;
@@ -4242,7 +4270,7 @@ function startCaptureWatcher() {
4242
4270
  `
4243
4271
  );
4244
4272
  try {
4245
- fs7.unlinkSync(WATCHER_LOCK);
4273
+ fs8.unlinkSync(WATCHER_LOCK);
4246
4274
  } catch {
4247
4275
  }
4248
4276
  return;
@@ -4274,7 +4302,7 @@ function startCaptureWatcher() {
4274
4302
  }, 2e3).unref();
4275
4303
  }
4276
4304
  try {
4277
- fs7.unlinkSync(WATCHER_LOCK);
4305
+ fs8.unlinkSync(WATCHER_LOCK);
4278
4306
  } catch {
4279
4307
  }
4280
4308
  };
@@ -4411,11 +4439,11 @@ function startSessionRelay(sessionId, serverUrl) {
4411
4439
  return;
4412
4440
  }
4413
4441
  try {
4414
- fs7.writeSync(claim.fd, String(process.pid));
4415
- fs7.closeSync(claim.fd);
4442
+ fs8.writeSync(claim.fd, String(process.pid));
4443
+ fs8.closeSync(claim.fd);
4416
4444
  } catch {
4417
4445
  try {
4418
- fs7.unlinkSync(lockPath);
4446
+ fs8.unlinkSync(lockPath);
4419
4447
  } catch {
4420
4448
  }
4421
4449
  return;
@@ -4430,11 +4458,11 @@ function startSessionRelay(sessionId, serverUrl) {
4430
4458
  const claim2 = tryClaimRelayLock(lockPath);
4431
4459
  if (claim2.ok) {
4432
4460
  try {
4433
- fs7.writeSync(claim2.fd, String(process.pid));
4434
- fs7.closeSync(claim2.fd);
4461
+ fs8.writeSync(claim2.fd, String(process.pid));
4462
+ fs8.closeSync(claim2.fd);
4435
4463
  } catch {
4436
4464
  try {
4437
- fs7.unlinkSync(lockPath);
4465
+ fs8.unlinkSync(lockPath);
4438
4466
  } catch {
4439
4467
  }
4440
4468
  return false;
@@ -4470,7 +4498,7 @@ function startSessionRelay(sessionId, serverUrl) {
4470
4498
  childStartTime = Date.now();
4471
4499
  dlog(`startSessionRelay: spawned 'greprag opencode relay' pid=${child.pid ?? "<none>"}`);
4472
4500
  try {
4473
- fs7.writeFileSync(lockPath, String(child.pid));
4501
+ fs8.writeFileSync(lockPath, String(child.pid));
4474
4502
  } catch {
4475
4503
  }
4476
4504
  child.stderr?.on("data", (chunk2) => {
@@ -4481,9 +4509,9 @@ function startSessionRelay(sessionId, serverUrl) {
4481
4509
  });
4482
4510
  child.on("exit", (code, signal) => {
4483
4511
  try {
4484
- const current = fs7.readFileSync(lockPath, "utf-8").trim();
4512
+ const current = fs8.readFileSync(lockPath, "utf-8").trim();
4485
4513
  if (current === String(child.pid))
4486
- fs7.unlinkSync(lockPath);
4514
+ fs8.unlinkSync(lockPath);
4487
4515
  } catch {
4488
4516
  }
4489
4517
  currentChild = null;
@@ -4510,7 +4538,7 @@ function startSessionRelay(sessionId, serverUrl) {
4510
4538
  `
4511
4539
  );
4512
4540
  try {
4513
- fs7.unlinkSync(lockPath);
4541
+ fs8.unlinkSync(lockPath);
4514
4542
  } catch {
4515
4543
  }
4516
4544
  return;
@@ -4542,7 +4570,7 @@ function startSessionRelay(sessionId, serverUrl) {
4542
4570
  }, 2e3).unref();
4543
4571
  }
4544
4572
  try {
4545
- fs7.unlinkSync(lockPath);
4573
+ fs8.unlinkSync(lockPath);
4546
4574
  } catch {
4547
4575
  }
4548
4576
  };