hunter-harness 0.2.29 → 0.2.30

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/bin.js +20 -6
  2. package/package.json +1 -1
package/dist/bin.js CHANGED
@@ -2290,6 +2290,10 @@ async function readReceipt(root) {
2290
2290
  }
2291
2291
  return { schema_version: 1, source_hashes: {}, targets: {} };
2292
2292
  }
2293
+ async function readManagedProjectRuleProjectionPaths(projectRoot) {
2294
+ const receipt = await readReceipt(resolve3(projectRoot));
2295
+ return new Set(Object.keys(receipt.targets).filter((target) => AGENT_RULE_ROOTS.some((ruleRoot) => target.startsWith(`${ruleRoot}/`))));
2296
+ }
2293
2297
  async function markdownFiles(root) {
2294
2298
  try {
2295
2299
  return (await readdir2(root, { withFileTypes: true })).filter((entry) => entry.isFile() && [".md", ".mdc"].includes(extname(entry.name).toLowerCase())).map((entry) => entry.name).filter((name) => !MANAGED_NAMES.has(name)).sort();
@@ -4591,7 +4595,8 @@ function planArtifactRebase(input) {
4591
4595
  plan.alreadyApplied.push({ path: target, operation });
4592
4596
  continue;
4593
4597
  }
4594
- const staticDecision = decideUpdate(policy, false);
4598
+ const projectionManaged = input.protocolOnlyPaths?.has(source) === true || input.protocolOnlyPaths?.has(target) === true;
4599
+ const staticDecision = projectionManaged ? { apply: false, reason: "protocol-only" } : decideUpdate(policy, false);
4595
4600
  if (!staticDecision.apply) {
4596
4601
  const acknowledgeReason = staticDecision.reason === "protocol-only" ? "protocol-only" : "policy-never";
4597
4602
  const entry2 = acknowledgedEntry(operation, context, input.projectVersion, acknowledgeReason);
@@ -4802,7 +4807,7 @@ function applyBaselineUpdates(baseline, plan) {
4802
4807
  }
4803
4808
  return next;
4804
4809
  }
4805
- async function planSingleArtifact(root, baseline, manifest, client, requestId, dryRun, conflictStrategy, resolveOverrides) {
4810
+ async function planSingleArtifact(root, baseline, manifest, client, requestId, dryRun, conflictStrategy, resolveOverrides, protocolOnlyPaths) {
4806
4811
  if (manifest.project_version === null) {
4807
4812
  throw new Error("artifact manifest missing project_version");
4808
4813
  }
@@ -4812,7 +4817,8 @@ async function planSingleArtifact(root, baseline, manifest, client, requestId, d
4812
4817
  projectVersion: manifest.project_version,
4813
4818
  contexts,
4814
4819
  conflictStrategy,
4815
- ...resolveOverrides === void 0 ? {} : { resolveOverrides }
4820
+ ...resolveOverrides === void 0 ? {} : { resolveOverrides },
4821
+ ...protocolOnlyPaths === void 0 ? {} : { protocolOnlyPaths }
4816
4822
  });
4817
4823
  }
4818
4824
  async function saveConflictReport(root, requestId, manifest, plan) {
@@ -4876,7 +4882,7 @@ async function synchronizeArtifacts(options, initialBaseline) {
4876
4882
  if (manifest.artifact_id !== discovery.artifact_id || manifest.project_id !== projectId || manifest.project_version === null || manifestPayloadHash(manifest) !== manifest.manifest_sha256) {
4877
4883
  throw new Error("ARTIFACT_HASH_MISMATCH");
4878
4884
  }
4879
- let plan = await planSingleArtifact(root, baseline, manifest, options.client, options.requestId, options.dryRun, conflictStrategy, options.resolveOverrides);
4885
+ let plan = await planSingleArtifact(root, baseline, manifest, options.client, options.requestId, options.dryRun, conflictStrategy, options.resolveOverrides, options.protocolOnlyPaths);
4880
4886
  if (plan.conflicts.length > 0 && options.confirmConflictStrategy !== void 0) {
4881
4887
  const confirmed = await options.confirmConflictStrategy(plan.conflicts);
4882
4888
  if (confirmed === false) {
@@ -4890,7 +4896,7 @@ async function synchronizeArtifacts(options, initialBaseline) {
4890
4896
  aggregate.artifactId = manifest.artifact_id;
4891
4897
  return aggregate;
4892
4898
  }
4893
- plan = await planSingleArtifact(root, baseline, manifest, options.client, options.requestId, options.dryRun, confirmed, options.resolveOverrides);
4899
+ plan = await planSingleArtifact(root, baseline, manifest, options.client, options.requestId, options.dryRun, confirmed, options.resolveOverrides, options.protocolOnlyPaths);
4894
4900
  }
4895
4901
  const paths = pathsFromPlan(plan);
4896
4902
  aggregate.applied.push(...paths.applied);
@@ -5958,6 +5964,7 @@ async function updateProject(options) {
5958
5964
  }
5959
5965
  const requestId = uuidV7();
5960
5966
  const baseline = await readBaseline(root);
5967
+ const protocolOnlyPaths = await readManagedProjectRuleProjectionPaths(root);
5961
5968
  let parsedServerUrl;
5962
5969
  try {
5963
5970
  parsedServerUrl = new URL(serverUrl);
@@ -5979,6 +5986,7 @@ async function updateProject(options) {
5979
5986
  client,
5980
5987
  requestId,
5981
5988
  dryRun: options.dryRun,
5989
+ protocolOnlyPaths,
5982
5990
  ...options.conflictStrategy === void 0 ? {} : { conflictStrategy: options.conflictStrategy },
5983
5991
  ...options.resolveOverrides === void 0 ? {} : { resolveOverrides: options.resolveOverrides },
5984
5992
  ...options.confirmConflictStrategy === void 0 ? {} : { confirmConflictStrategy: options.confirmConflictStrategy },
@@ -5989,7 +5997,13 @@ async function updateProject(options) {
5989
5997
  const parsed = harnessAgentSchema.safeParse(agent);
5990
5998
  return parsed.success ? [parsed.data] : [];
5991
5999
  });
5992
- await synchronizeProjectRules(root, agents, project.adapter_options?.codebuddy?.surface ?? "both");
6000
+ const projections = await synchronizeProjectRules(root, agents, project.adapter_options?.codebuddy?.surface ?? "both");
6001
+ for (const path of projections.conflicts) {
6002
+ result.conflicts.push({ path, operation: "modify", reason: "local-dirty" });
6003
+ if (!result.skipped.some((item2) => item2.path === path)) {
6004
+ result.skipped.push({ path, operation: "modify", reason: "local-dirty" });
6005
+ }
6006
+ }
5993
6007
  }
5994
6008
  return result;
5995
6009
  } catch (error) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "hunter-harness",
3
- "version": "0.2.29",
3
+ "version": "0.2.30",
4
4
  "description": "Local-first, server-governed agent harness",
5
5
  "license": "MIT",
6
6
  "type": "module",