@primitive.ai/prim 0.1.0-alpha.83 → 0.1.0-alpha.84

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.
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  analyzeShellTargets,
3
3
  extractFileTargets
4
- } from "./chunk-BQUJ4AFJ.js";
4
+ } from "./chunk-PPQYQEIR.js";
5
5
  import {
6
6
  canonicalRepositoryPath
7
7
  } from "./chunk-TJTVHDJ5.js";
@@ -26,7 +26,7 @@ function preserveHookFileMetadata(payload, resolution) {
26
26
  return { ...payload, primitive };
27
27
  }
28
28
  function resolveHookFileRefs(args) {
29
- const command = (args.agent === "claude_code" || args.agent === "codex") && args.toolName === "Bash" && args.toolInput && typeof args.toolInput === "object" && typeof args.toolInput.command === "string" ? args.toolInput.command : void 0;
29
+ const command = (args.agent === "claude_code" || args.agent === "codex") && args.toolName === "Bash" ? typeof args.toolInput === "string" ? args.toolInput : args.toolInput && typeof args.toolInput === "object" && typeof args.toolInput.command === "string" ? args.toolInput.command : void 0 : void 0;
30
30
  const shell = command === void 0 ? void 0 : analyzeShellTargets(command);
31
31
  const shellMutation = shell?.mutation === "none" ? "none" : shell?.coverage === "complete" ? "resolved" : shell ? "unresolved" : void 0;
32
32
  const readPath = args.agent === "claude_code" && args.toolName === "Read" && args.toolInput && typeof args.toolInput === "object" && typeof args.toolInput.file_path === "string" ? [args.toolInput.file_path] : void 0;
@@ -136,11 +136,18 @@ function extractCodexFileTargets(toolName, toolInput) {
136
136
  if (toolName !== "apply_patch") {
137
137
  return null;
138
138
  }
139
- if (!toolInput || typeof toolInput !== "object") {
140
- return { paths: [], complete: false };
139
+ const text = codexPatchText(toolInput);
140
+ return text !== null ? parseApplyPatchTargets(text) : { paths: [], complete: false };
141
+ }
142
+ function codexPatchText(toolInput) {
143
+ if (typeof toolInput === "string") return toolInput;
144
+ if (!toolInput || typeof toolInput !== "object") return null;
145
+ const input = toolInput;
146
+ for (const key of ["command", "input", "patch"]) {
147
+ const value = input[key];
148
+ if (typeof value === "string") return value;
141
149
  }
142
- const command = toolInput.command;
143
- return typeof command === "string" ? parseApplyPatchTargets(command) : { paths: [], complete: false };
150
+ return null;
144
151
  }
145
152
  var HERMES_EDITING_TOOLS = /* @__PURE__ */ new Set(["write_file", "patch"]);
146
153
  function extractHermesFileTargets(toolName, toolInput) {
@@ -674,6 +681,31 @@ function visitRedirect(redirect, state) {
674
681
  recordTarget(redirect.target, state);
675
682
  else unknown(state);
676
683
  }
684
+ function visitApplyPatch(command, state) {
685
+ state.mutation = true;
686
+ state.definiteEdit = true;
687
+ let hasBody = false;
688
+ if (command.suffix.length > 0) state.complete = false;
689
+ for (const redirect of command.redirects) {
690
+ if (redirect.operator !== "<<") {
691
+ visitRedirect(redirect, state);
692
+ continue;
693
+ }
694
+ if (typeof redirect.content !== "string") {
695
+ state.complete = false;
696
+ continue;
697
+ }
698
+ hasBody = true;
699
+ if (redirect.heredocQuoted !== true && redirect.body !== void 0) {
700
+ state.complete = false;
701
+ continue;
702
+ }
703
+ const targets = parseApplyPatchTargets(redirect.content);
704
+ for (const path of targets.paths) state.paths.add(path);
705
+ if (!targets.complete) state.complete = false;
706
+ }
707
+ if (!hasBody) state.complete = false;
708
+ }
677
709
  function operands(words, short = "", long = /* @__PURE__ */ new Set()) {
678
710
  const result = [];
679
711
  let optionsEnded = false;
@@ -688,10 +720,16 @@ function operands(words, short = "", long = /* @__PURE__ */ new Set()) {
688
720
  return result;
689
721
  }
690
722
  function visitCommand(command, state) {
691
- for (const redirect of command.redirects) visitRedirect(redirect, state);
692
723
  const name = staticWord(command.name);
693
- if (!name || name.includes("/") || command.suffix.some((word) => !staticWord(word))) {
724
+ const literalApplyPatch = name === "apply_patch" && !command.redirects.some((redirect) => redirect.operator === "<<-");
725
+ if (literalApplyPatch) {
726
+ visitApplyPatch(command, state);
727
+ } else {
728
+ for (const redirect of command.redirects) visitRedirect(redirect, state);
729
+ }
730
+ if (!name || name.includes("/") || !literalApplyPatch && command.suffix.some((word) => !staticWord(word))) {
694
731
  unknown(state);
732
+ } else if (literalApplyPatch) {
695
733
  } else if (!READ_ONLY_COMMANDS.has(name) && !knownNoWorktreeMutation(name, staticArgs(command.suffix))) {
696
734
  state.mutation = true;
697
735
  let targets;
@@ -744,13 +782,19 @@ function analyzeShellTargets(source) {
744
782
  return { paths: [], coverage: "complete", mutation: "none" };
745
783
  try {
746
784
  const script = parse(source);
747
- const state = { paths: /* @__PURE__ */ new Set(), complete: !script.errors?.length, mutation: false };
785
+ const state = {
786
+ paths: /* @__PURE__ */ new Set(),
787
+ complete: !script.errors?.length,
788
+ mutation: false,
789
+ definiteEdit: false
790
+ };
748
791
  for (const statement of script.commands) visitStatement(statement, state);
749
792
  if (script.errors?.length) state.mutation = true;
750
793
  return {
751
794
  paths: [...state.paths],
752
795
  coverage: state.complete ? "complete" : "unverified",
753
- mutation: state.mutation ? "present" : "none"
796
+ mutation: state.mutation ? "present" : "none",
797
+ ...state.definiteEdit ? { definiteEdit: true } : {}
754
798
  };
755
799
  } catch {
756
800
  return { paths: [], coverage: "unverified", mutation: "present" };
@@ -2380,11 +2380,18 @@ function extractCodexFileTargets(toolName, toolInput) {
2380
2380
  if (toolName !== "apply_patch") {
2381
2381
  return null;
2382
2382
  }
2383
- if (!toolInput || typeof toolInput !== "object") {
2384
- return { paths: [], complete: false };
2383
+ const text = codexPatchText(toolInput);
2384
+ return text !== null ? parseApplyPatchTargets(text) : { paths: [], complete: false };
2385
+ }
2386
+ function codexPatchText(toolInput) {
2387
+ if (typeof toolInput === "string") return toolInput;
2388
+ if (!toolInput || typeof toolInput !== "object") return null;
2389
+ const input = toolInput;
2390
+ for (const key of ["command", "input", "patch"]) {
2391
+ const value = input[key];
2392
+ if (typeof value === "string") return value;
2385
2393
  }
2386
- const command = toolInput.command;
2387
- return typeof command === "string" ? parseApplyPatchTargets(command) : { paths: [], complete: false };
2394
+ return null;
2388
2395
  }
2389
2396
  var HERMES_EDITING_TOOLS = /* @__PURE__ */ new Set(["write_file", "patch"]);
2390
2397
  function extractHermesFileTargets(toolName, toolInput) {
@@ -6732,6 +6739,31 @@ function visitRedirect(redirect, state) {
6732
6739
  recordTarget(redirect.target, state);
6733
6740
  else unknown(state);
6734
6741
  }
6742
+ function visitApplyPatch(command, state) {
6743
+ state.mutation = true;
6744
+ state.definiteEdit = true;
6745
+ let hasBody = false;
6746
+ if (command.suffix.length > 0) state.complete = false;
6747
+ for (const redirect of command.redirects) {
6748
+ if (redirect.operator !== "<<") {
6749
+ visitRedirect(redirect, state);
6750
+ continue;
6751
+ }
6752
+ if (typeof redirect.content !== "string") {
6753
+ state.complete = false;
6754
+ continue;
6755
+ }
6756
+ hasBody = true;
6757
+ if (redirect.heredocQuoted !== true && redirect.body !== void 0) {
6758
+ state.complete = false;
6759
+ continue;
6760
+ }
6761
+ const targets = parseApplyPatchTargets(redirect.content);
6762
+ for (const path of targets.paths) state.paths.add(path);
6763
+ if (!targets.complete) state.complete = false;
6764
+ }
6765
+ if (!hasBody) state.complete = false;
6766
+ }
6735
6767
  function operands(words, short = "", long = /* @__PURE__ */ new Set()) {
6736
6768
  const result = [];
6737
6769
  let optionsEnded = false;
@@ -6746,10 +6778,16 @@ function operands(words, short = "", long = /* @__PURE__ */ new Set()) {
6746
6778
  return result;
6747
6779
  }
6748
6780
  function visitCommand(command, state) {
6749
- for (const redirect of command.redirects) visitRedirect(redirect, state);
6750
6781
  const name = staticWord(command.name);
6751
- if (!name || name.includes("/") || command.suffix.some((word) => !staticWord(word))) {
6782
+ const literalApplyPatch = name === "apply_patch" && !command.redirects.some((redirect) => redirect.operator === "<<-");
6783
+ if (literalApplyPatch) {
6784
+ visitApplyPatch(command, state);
6785
+ } else {
6786
+ for (const redirect of command.redirects) visitRedirect(redirect, state);
6787
+ }
6788
+ if (!name || name.includes("/") || !literalApplyPatch && command.suffix.some((word) => !staticWord(word))) {
6752
6789
  unknown(state);
6790
+ } else if (literalApplyPatch) {
6753
6791
  } else if (!READ_ONLY_COMMANDS.has(name) && !knownNoWorktreeMutation(name, staticArgs(command.suffix))) {
6754
6792
  state.mutation = true;
6755
6793
  let targets;
@@ -6802,13 +6840,19 @@ function analyzeShellTargets(source) {
6802
6840
  return { paths: [], coverage: "complete", mutation: "none" };
6803
6841
  try {
6804
6842
  const script = parse(source);
6805
- const state = { paths: /* @__PURE__ */ new Set(), complete: !script.errors?.length, mutation: false };
6843
+ const state = {
6844
+ paths: /* @__PURE__ */ new Set(),
6845
+ complete: !script.errors?.length,
6846
+ mutation: false,
6847
+ definiteEdit: false
6848
+ };
6806
6849
  for (const statement of script.commands) visitStatement(statement, state);
6807
6850
  if (script.errors?.length) state.mutation = true;
6808
6851
  return {
6809
6852
  paths: [...state.paths],
6810
6853
  coverage: state.complete ? "complete" : "unverified",
6811
- mutation: state.mutation ? "present" : "none"
6854
+ mutation: state.mutation ? "present" : "none",
6855
+ ...state.definiteEdit ? { definiteEdit: true } : {}
6812
6856
  };
6813
6857
  } catch {
6814
6858
  return { paths: [], coverage: "unverified", mutation: "present" };
@@ -6835,7 +6879,7 @@ function preserveHookFileMetadata(payload, resolution) {
6835
6879
  return { ...payload, primitive };
6836
6880
  }
6837
6881
  function resolveHookFileRefs(args) {
6838
- const command = (args.agent === "claude_code" || args.agent === "codex") && args.toolName === "Bash" && args.toolInput && typeof args.toolInput === "object" && typeof args.toolInput.command === "string" ? args.toolInput.command : void 0;
6882
+ const command = (args.agent === "claude_code" || args.agent === "codex") && args.toolName === "Bash" ? typeof args.toolInput === "string" ? args.toolInput : args.toolInput && typeof args.toolInput === "object" && typeof args.toolInput.command === "string" ? args.toolInput.command : void 0 : void 0;
6839
6883
  const shell = command === void 0 ? void 0 : analyzeShellTargets(command);
6840
6884
  const shellMutation = shell?.mutation === "none" ? "none" : shell?.coverage === "complete" ? "resolved" : shell ? "unresolved" : void 0;
6841
6885
  const readPath = args.agent === "claude_code" && args.toolName === "Read" && args.toolInput && typeof args.toolInput === "object" && typeof args.toolInput.file_path === "string" ? [args.toolInput.file_path] : void 0;
@@ -2194,11 +2194,18 @@ function extractCodexFileTargets(toolName, toolInput) {
2194
2194
  if (toolName !== "apply_patch") {
2195
2195
  return null;
2196
2196
  }
2197
- if (!toolInput || typeof toolInput !== "object") {
2198
- return { paths: [], complete: false };
2197
+ const text = codexPatchText(toolInput);
2198
+ return text !== null ? parseApplyPatchTargets(text) : { paths: [], complete: false };
2199
+ }
2200
+ function codexPatchText(toolInput) {
2201
+ if (typeof toolInput === "string") return toolInput;
2202
+ if (!toolInput || typeof toolInput !== "object") return null;
2203
+ const input = toolInput;
2204
+ for (const key of ["command", "input", "patch"]) {
2205
+ const value = input[key];
2206
+ if (typeof value === "string") return value;
2199
2207
  }
2200
- const command = toolInput.command;
2201
- return typeof command === "string" ? parseApplyPatchTargets(command) : { paths: [], complete: false };
2208
+ return null;
2202
2209
  }
2203
2210
  var HERMES_EDITING_TOOLS = /* @__PURE__ */ new Set(["write_file", "patch"]);
2204
2211
  function extractHermesFileTargets(toolName, toolInput) {
@@ -6711,6 +6718,31 @@ function visitRedirect(redirect, state) {
6711
6718
  recordTarget(redirect.target, state);
6712
6719
  else unknown(state);
6713
6720
  }
6721
+ function visitApplyPatch(command, state) {
6722
+ state.mutation = true;
6723
+ state.definiteEdit = true;
6724
+ let hasBody = false;
6725
+ if (command.suffix.length > 0) state.complete = false;
6726
+ for (const redirect of command.redirects) {
6727
+ if (redirect.operator !== "<<") {
6728
+ visitRedirect(redirect, state);
6729
+ continue;
6730
+ }
6731
+ if (typeof redirect.content !== "string") {
6732
+ state.complete = false;
6733
+ continue;
6734
+ }
6735
+ hasBody = true;
6736
+ if (redirect.heredocQuoted !== true && redirect.body !== void 0) {
6737
+ state.complete = false;
6738
+ continue;
6739
+ }
6740
+ const targets = parseApplyPatchTargets(redirect.content);
6741
+ for (const path of targets.paths) state.paths.add(path);
6742
+ if (!targets.complete) state.complete = false;
6743
+ }
6744
+ if (!hasBody) state.complete = false;
6745
+ }
6714
6746
  function operands(words, short = "", long = /* @__PURE__ */ new Set()) {
6715
6747
  const result = [];
6716
6748
  let optionsEnded = false;
@@ -6725,10 +6757,16 @@ function operands(words, short = "", long = /* @__PURE__ */ new Set()) {
6725
6757
  return result;
6726
6758
  }
6727
6759
  function visitCommand(command, state) {
6728
- for (const redirect of command.redirects) visitRedirect(redirect, state);
6729
6760
  const name = staticWord(command.name);
6730
- if (!name || name.includes("/") || command.suffix.some((word) => !staticWord(word))) {
6761
+ const literalApplyPatch = name === "apply_patch" && !command.redirects.some((redirect) => redirect.operator === "<<-");
6762
+ if (literalApplyPatch) {
6763
+ visitApplyPatch(command, state);
6764
+ } else {
6765
+ for (const redirect of command.redirects) visitRedirect(redirect, state);
6766
+ }
6767
+ if (!name || name.includes("/") || !literalApplyPatch && command.suffix.some((word) => !staticWord(word))) {
6731
6768
  unknown(state);
6769
+ } else if (literalApplyPatch) {
6732
6770
  } else if (!READ_ONLY_COMMANDS.has(name) && !knownNoWorktreeMutation(name, staticArgs(command.suffix))) {
6733
6771
  state.mutation = true;
6734
6772
  let targets;
@@ -6781,13 +6819,19 @@ function analyzeShellTargets(source) {
6781
6819
  return { paths: [], coverage: "complete", mutation: "none" };
6782
6820
  try {
6783
6821
  const script = parse(source);
6784
- const state = { paths: /* @__PURE__ */ new Set(), complete: !script.errors?.length, mutation: false };
6822
+ const state = {
6823
+ paths: /* @__PURE__ */ new Set(),
6824
+ complete: !script.errors?.length,
6825
+ mutation: false,
6826
+ definiteEdit: false
6827
+ };
6785
6828
  for (const statement of script.commands) visitStatement(statement, state);
6786
6829
  if (script.errors?.length) state.mutation = true;
6787
6830
  return {
6788
6831
  paths: [...state.paths],
6789
6832
  coverage: state.complete ? "complete" : "unverified",
6790
- mutation: state.mutation ? "present" : "none"
6833
+ mutation: state.mutation ? "present" : "none",
6834
+ ...state.definiteEdit ? { definiteEdit: true } : {}
6791
6835
  };
6792
6836
  } catch {
6793
6837
  return { paths: [], coverage: "unverified", mutation: "present" };
@@ -6811,8 +6855,9 @@ function resolvePreflightTargets(args) {
6811
6855
  let rawPaths;
6812
6856
  let coverage = "complete";
6813
6857
  let mutation = "present";
6814
- if (args.agent === "claude_code" && args.toolName === "Bash") {
6815
- const command = args.toolInput && typeof args.toolInput === "object" ? args.toolInput.command : void 0;
6858
+ let definite = false;
6859
+ if ((args.agent === "claude_code" || args.agent === "codex") && args.toolName === "Bash") {
6860
+ const command = typeof args.toolInput === "string" ? args.toolInput : args.toolInput && typeof args.toolInput === "object" ? args.toolInput.command : void 0;
6816
6861
  if (typeof command !== "string") {
6817
6862
  return { paths: [], coverage: "unverified", mutation: "present" };
6818
6863
  }
@@ -6820,11 +6865,13 @@ function resolvePreflightTargets(args) {
6820
6865
  rawPaths = shell.paths;
6821
6866
  coverage = shell.coverage;
6822
6867
  mutation = shell.mutation;
6868
+ definite = shell.definiteEdit === true;
6823
6869
  } else {
6824
6870
  const extracted = extractFileTargets(args.toolName, args.toolInput, args.agent);
6825
6871
  if (!extracted) return { paths: [], coverage: "complete", mutation: "none" };
6826
6872
  rawPaths = extracted.paths;
6827
6873
  if (!extracted.complete) coverage = "unverified";
6874
+ definite = true;
6828
6875
  }
6829
6876
  const root = canonicalGitRoot(args.cwd);
6830
6877
  const paths = /* @__PURE__ */ new Set();
@@ -6835,7 +6882,11 @@ function resolvePreflightTargets(args) {
6835
6882
  }
6836
6883
  const bounded = [...paths];
6837
6884
  if (bounded.length > MAX_PREFLIGHT_PATHS) coverage = "unverified";
6838
- return { paths: bounded.slice(0, MAX_PREFLIGHT_PATHS), coverage, mutation };
6885
+ const resolved = bounded.slice(0, MAX_PREFLIGHT_PATHS);
6886
+ if (definite && resolved.length === 0 && mutation === "present") {
6887
+ return { paths: resolved, coverage: "unverified", mutation, definite: true };
6888
+ }
6889
+ return { paths: resolved, coverage, mutation };
6839
6890
  }
6840
6891
  function truncateUtf8(value, maxBytes) {
6841
6892
  const encoded = Buffer2.from(value);
@@ -7035,7 +7086,7 @@ async function main() {
7035
7086
  await emit(failOpen());
7036
7087
  return;
7037
7088
  }
7038
- if (targets.paths.length === 0) {
7089
+ if (targets.paths.length === 0 && !targets.definite) {
7039
7090
  await emit(failOpen());
7040
7091
  return;
7041
7092
  }
@@ -2678,11 +2678,18 @@ function extractCodexFileTargets(toolName, toolInput) {
2678
2678
  if (toolName !== "apply_patch") {
2679
2679
  return null;
2680
2680
  }
2681
- if (!toolInput || typeof toolInput !== "object") {
2682
- return { paths: [], complete: false };
2681
+ const text = codexPatchText(toolInput);
2682
+ return text !== null ? parseApplyPatchTargets(text) : { paths: [], complete: false };
2683
+ }
2684
+ function codexPatchText(toolInput) {
2685
+ if (typeof toolInput === "string") return toolInput;
2686
+ if (!toolInput || typeof toolInput !== "object") return null;
2687
+ const input = toolInput;
2688
+ for (const key of ["command", "input", "patch"]) {
2689
+ const value = input[key];
2690
+ if (typeof value === "string") return value;
2683
2691
  }
2684
- const command = toolInput.command;
2685
- return typeof command === "string" ? parseApplyPatchTargets(command) : { paths: [], complete: false };
2692
+ return null;
2686
2693
  }
2687
2694
  var HERMES_EDITING_TOOLS = /* @__PURE__ */ new Set(["write_file", "patch"]);
2688
2695
  function extractHermesFileTargets(toolName, toolInput) {
@@ -7030,6 +7037,31 @@ function visitRedirect(redirect, state) {
7030
7037
  recordTarget(redirect.target, state);
7031
7038
  else unknown(state);
7032
7039
  }
7040
+ function visitApplyPatch(command, state) {
7041
+ state.mutation = true;
7042
+ state.definiteEdit = true;
7043
+ let hasBody = false;
7044
+ if (command.suffix.length > 0) state.complete = false;
7045
+ for (const redirect of command.redirects) {
7046
+ if (redirect.operator !== "<<") {
7047
+ visitRedirect(redirect, state);
7048
+ continue;
7049
+ }
7050
+ if (typeof redirect.content !== "string") {
7051
+ state.complete = false;
7052
+ continue;
7053
+ }
7054
+ hasBody = true;
7055
+ if (redirect.heredocQuoted !== true && redirect.body !== void 0) {
7056
+ state.complete = false;
7057
+ continue;
7058
+ }
7059
+ const targets = parseApplyPatchTargets(redirect.content);
7060
+ for (const path of targets.paths) state.paths.add(path);
7061
+ if (!targets.complete) state.complete = false;
7062
+ }
7063
+ if (!hasBody) state.complete = false;
7064
+ }
7033
7065
  function operands(words, short = "", long = /* @__PURE__ */ new Set()) {
7034
7066
  const result = [];
7035
7067
  let optionsEnded = false;
@@ -7044,10 +7076,16 @@ function operands(words, short = "", long = /* @__PURE__ */ new Set()) {
7044
7076
  return result;
7045
7077
  }
7046
7078
  function visitCommand(command, state) {
7047
- for (const redirect of command.redirects) visitRedirect(redirect, state);
7048
7079
  const name = staticWord(command.name);
7049
- if (!name || name.includes("/") || command.suffix.some((word) => !staticWord(word))) {
7080
+ const literalApplyPatch = name === "apply_patch" && !command.redirects.some((redirect) => redirect.operator === "<<-");
7081
+ if (literalApplyPatch) {
7082
+ visitApplyPatch(command, state);
7083
+ } else {
7084
+ for (const redirect of command.redirects) visitRedirect(redirect, state);
7085
+ }
7086
+ if (!name || name.includes("/") || !literalApplyPatch && command.suffix.some((word) => !staticWord(word))) {
7050
7087
  unknown(state);
7088
+ } else if (literalApplyPatch) {
7051
7089
  } else if (!READ_ONLY_COMMANDS.has(name) && !knownNoWorktreeMutation(name, staticArgs(command.suffix))) {
7052
7090
  state.mutation = true;
7053
7091
  let targets;
@@ -7100,13 +7138,19 @@ function analyzeShellTargets(source) {
7100
7138
  return { paths: [], coverage: "complete", mutation: "none" };
7101
7139
  try {
7102
7140
  const script = parse(source);
7103
- const state = { paths: /* @__PURE__ */ new Set(), complete: !script.errors?.length, mutation: false };
7141
+ const state = {
7142
+ paths: /* @__PURE__ */ new Set(),
7143
+ complete: !script.errors?.length,
7144
+ mutation: false,
7145
+ definiteEdit: false
7146
+ };
7104
7147
  for (const statement of script.commands) visitStatement(statement, state);
7105
7148
  if (script.errors?.length) state.mutation = true;
7106
7149
  return {
7107
7150
  paths: [...state.paths],
7108
7151
  coverage: state.complete ? "complete" : "unverified",
7109
- mutation: state.mutation ? "present" : "none"
7152
+ mutation: state.mutation ? "present" : "none",
7153
+ ...state.definiteEdit ? { definiteEdit: true } : {}
7110
7154
  };
7111
7155
  } catch {
7112
7156
  return { paths: [], coverage: "unverified", mutation: "present" };
@@ -7133,7 +7177,7 @@ function preserveHookFileMetadata(payload, resolution) {
7133
7177
  return { ...payload, primitive };
7134
7178
  }
7135
7179
  function resolveHookFileRefs(args) {
7136
- const command = (args.agent === "claude_code" || args.agent === "codex") && args.toolName === "Bash" && args.toolInput && typeof args.toolInput === "object" && typeof args.toolInput.command === "string" ? args.toolInput.command : void 0;
7180
+ const command = (args.agent === "claude_code" || args.agent === "codex") && args.toolName === "Bash" ? typeof args.toolInput === "string" ? args.toolInput : args.toolInput && typeof args.toolInput === "object" && typeof args.toolInput.command === "string" ? args.toolInput.command : void 0 : void 0;
7137
7181
  const shell = command === void 0 ? void 0 : analyzeShellTargets(command);
7138
7182
  const shellMutation = shell?.mutation === "none" ? "none" : shell?.coverage === "complete" ? "resolved" : shell ? "unresolved" : void 0;
7139
7183
  const readPath = args.agent === "claude_code" && args.toolName === "Read" && args.toolInput && typeof args.toolInput === "object" && typeof args.toolInput.file_path === "string" ? [args.toolInput.file_path] : void 0;
@@ -29606,7 +29606,7 @@ var GATE_BIN2 = "prim-pre-tool-use";
29606
29606
  var POST_TOOL_USE_BIN2 = "prim-post-tool-use";
29607
29607
  var SESSION_START_BIN2 = "prim-session-start";
29608
29608
  var CODEX_ARGS = "--agent codex";
29609
- var CODEX_EDIT_MATCHER = "apply_patch";
29609
+ var CODEX_EDIT_MATCHER = "apply_patch|Bash";
29610
29610
  var CODEX_POST_TOOL_MATCHER = "apply_patch|Bash";
29611
29611
  var JSON_INDENT2 = 2;
29612
29612
  var CODEX_CAPTURE_EVENTS = [
@@ -5,7 +5,7 @@ import {
5
5
  import {
6
6
  enrichHookPayloadWithFileRefs,
7
7
  preserveHookFileMetadata
8
- } from "../chunk-ZOSNEO5N.js";
8
+ } from "../chunk-7O6NAUKJ.js";
9
9
  import {
10
10
  postToolInvocationId,
11
11
  toMove,
@@ -18,7 +18,7 @@ import {
18
18
  appendMove,
19
19
  resolveOrg
20
20
  } from "../chunk-YWO7O6QG.js";
21
- import "../chunk-BQUJ4AFJ.js";
21
+ import "../chunk-PPQYQEIR.js";
22
22
  import {
23
23
  appendCodexContext,
24
24
  prepareCodexContext
@@ -10,7 +10,7 @@ import {
10
10
  failOpenHermes,
11
11
  failOpenOutput,
12
12
  readHookMode
13
- } from "../chunk-BQUJ4AFJ.js";
13
+ } from "../chunk-PPQYQEIR.js";
14
14
  import {
15
15
  appendCodexContext,
16
16
  hasVisibleCodexMessage,
@@ -60,8 +60,9 @@ function resolvePreflightTargets(args) {
60
60
  let rawPaths;
61
61
  let coverage = "complete";
62
62
  let mutation = "present";
63
- if (args.agent === "claude_code" && args.toolName === "Bash") {
64
- const command = args.toolInput && typeof args.toolInput === "object" ? args.toolInput.command : void 0;
63
+ let definite = false;
64
+ if ((args.agent === "claude_code" || args.agent === "codex") && args.toolName === "Bash") {
65
+ const command = typeof args.toolInput === "string" ? args.toolInput : args.toolInput && typeof args.toolInput === "object" ? args.toolInput.command : void 0;
65
66
  if (typeof command !== "string") {
66
67
  return { paths: [], coverage: "unverified", mutation: "present" };
67
68
  }
@@ -69,11 +70,13 @@ function resolvePreflightTargets(args) {
69
70
  rawPaths = shell.paths;
70
71
  coverage = shell.coverage;
71
72
  mutation = shell.mutation;
73
+ definite = shell.definiteEdit === true;
72
74
  } else {
73
75
  const extracted = extractFileTargets(args.toolName, args.toolInput, args.agent);
74
76
  if (!extracted) return { paths: [], coverage: "complete", mutation: "none" };
75
77
  rawPaths = extracted.paths;
76
78
  if (!extracted.complete) coverage = "unverified";
79
+ definite = true;
77
80
  }
78
81
  const root = canonicalGitRoot(args.cwd);
79
82
  const paths = /* @__PURE__ */ new Set();
@@ -84,7 +87,11 @@ function resolvePreflightTargets(args) {
84
87
  }
85
88
  const bounded = [...paths];
86
89
  if (bounded.length > MAX_PREFLIGHT_PATHS) coverage = "unverified";
87
- return { paths: bounded.slice(0, MAX_PREFLIGHT_PATHS), coverage, mutation };
90
+ const resolved = bounded.slice(0, MAX_PREFLIGHT_PATHS);
91
+ if (definite && resolved.length === 0 && mutation === "present") {
92
+ return { paths: resolved, coverage: "unverified", mutation, definite: true };
93
+ }
94
+ return { paths: resolved, coverage, mutation };
88
95
  }
89
96
  function truncateUtf8(value, maxBytes) {
90
97
  const encoded = Buffer2.from(value);
@@ -284,7 +291,7 @@ async function main() {
284
291
  await emit(failOpen());
285
292
  return;
286
293
  }
287
- if (targets.paths.length === 0) {
294
+ if (targets.paths.length === 0 && !targets.definite) {
288
295
  await emit(failOpen());
289
296
  return;
290
297
  }
@@ -12,7 +12,7 @@ import {
12
12
  import {
13
13
  enrichHookPayloadWithFileRefs,
14
14
  preserveHookFileMetadata
15
- } from "../chunk-ZOSNEO5N.js";
15
+ } from "../chunk-7O6NAUKJ.js";
16
16
  import {
17
17
  postToolInvocationId,
18
18
  shouldFlushAfter,
@@ -25,7 +25,7 @@ import {
25
25
  appendMove,
26
26
  resolveOrg
27
27
  } from "../chunk-YWO7O6QG.js";
28
- import "../chunk-BQUJ4AFJ.js";
28
+ import "../chunk-PPQYQEIR.js";
29
29
  import {
30
30
  prepareCodexContext
31
31
  } from "../chunk-4CZTNXIS.js";
package/dist/index.js CHANGED
@@ -14660,7 +14660,7 @@ var GATE_BIN2 = "prim-pre-tool-use";
14660
14660
  var POST_TOOL_USE_BIN2 = "prim-post-tool-use";
14661
14661
  var SESSION_START_BIN2 = "prim-session-start";
14662
14662
  var CODEX_ARGS = "--agent codex";
14663
- var CODEX_EDIT_MATCHER = "apply_patch";
14663
+ var CODEX_EDIT_MATCHER = "apply_patch|Bash";
14664
14664
  var CODEX_POST_TOOL_MATCHER = "apply_patch|Bash";
14665
14665
  var JSON_INDENT2 = 2;
14666
14666
  var CODEX_CAPTURE_EVENTS = [
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@primitive.ai/prim",
3
- "version": "0.1.0-alpha.83",
3
+ "version": "0.1.0-alpha.84",
4
4
  "description": "CLI for Primitive's decision graph — passive decision capture, conflict gate, and team presence",
5
5
  "type": "module",
6
6
  "license": "MIT",