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

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.
@@ -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;