@gitkraken/conflict-tools 0.2.4-beta.10 → 0.2.4-beta.11
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/CHANGELOG.md
CHANGED
|
@@ -23,6 +23,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/).
|
|
|
23
23
|
|
|
24
24
|
### Fixed
|
|
25
25
|
|
|
26
|
+
- A non-abort error in the refine pass no longer destroys the pre-refine resolution. Previously the refine `catch` rethrew, bubbling to `resolveOne` and degrading a good resolve-stage result into a take-side fallback (confidence 0) — the same class of failure as a throwing validator, one stage later. The pre-refine resolution is now kept, its confidence capped (the enhancement did not complete), and the error reported via `refine:failed`. A user abort still cancels (rethrown past the fallback).
|
|
26
27
|
- A throwing consumer validator no longer destroys a good resolution. The post-refine `validator.validate()` call is now guarded: a validator error is reported via a new `validation:failed` progress event and the resolution is kept intact, instead of bubbling to `resolveOne` and degrading a successful AI resolve into a whole-file take-side fallback (confidence 0) — the exact dropped-side loss the tool guards against. The validator stays advisory.
|
|
27
28
|
- A user abort mid-resolve now cancels the operation instead of degrading into a take-side fallback. `resolveOne` rethrows when `signal.aborted` (covering aborts raised from the resolve loop, refine, or the validator), bypassing the emergency fallback rather than turning a cancellation into a whole-file take-one-side resolution.
|
|
28
29
|
- The refine pass no longer floods its bounded step budget when the model spirals. After a run of consecutive `edit_file_lines` apply errors (a model repeatedly proposing ops that never apply), the pass bails early — keeping whatever edits landed — and emits a new `refine:bailed` progress event, instead of executing failing tool calls until the step budget is exhausted.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{resolveChunkContent as e}from"../resolution/chunk-apply.js";import{createResolution as t}from"../resolution/create-resolution.js";import{checkResidualMarkers as n}from"../ports/verify.js";import{mergeUsages as r}from"../resolution/metrics.js";import{runResolverLoop as i}from"./loop.js";import{runRefinePass as a}from"./refine-pass.js";import{buildThreeWayDiff as o}from"./three-way-diff.js";const s={refineNoAction:.6,refineApplied:.9};async function c(c,l,u){let d=l.threeWayDiff||!l.refs?l:{...l,threeWayDiff:await o(c.filePath,l.refs,{git:u.git,signal:u.signal})},{chunks:f,strategy:p,confidence:m,description:h,metrics:g,followUpInstructions:_}=await i(c,d,{model:u.model,git:u.git,config:u.config,onProgress:u.onProgress,signal:u.signal}),v=t(c,f,{confidence:m,description:h,metrics:g,...p?{fileStrategy:p}:{},...d.threeWayDiff?{threeWayDiff:d.threeWayDiff}:{}}),y=_&&_.length>0;if(c.type===`text`&&y){u.onProgress?.({type:`refine:started`,filePath:c.filePath});let t=0;try{let i=await a(v.content,v.description,_,{model:u.model,signal:u.signal,temperature:u.config?.temperature,refineMaxSteps:u.config?.refineMaxSteps,onProgress:u.onProgress,filePath:c.filePath});if(i.edits.length>0){let e=n(c.filePath,i.content);if(e.valid)v={...v,content:i.content,edits:i.edits,strategy:`ai`},t=i.edits.length;else{let t=(e.issues??[]).map(e=>e.message).join(` `);u.onProgress?.({type:`refine:discarded`,filePath:c.filePath,reason:`Edits introduced conflict markers: ${t}`})}}if(t>0){v={...v,confidence:Math.min(v.confidence,s.refineApplied)};let t=[];for(let n=0;n<c.markers.length;n++){let r=c.markers[n];if(!r||r.userResolution==null)continue;let a=e({markerIndex:n,...r.userResolution},r);a!==``&&(i.content.includes(a)||t.push(n))}t.length>0&&(u.onProgress?.({type:`refine:touched-user-region`,filePath:c.filePath,markerIndexes:t}),v={...v,note:`Refine modified user-resolved region(s): marker ${t.join(`, `)}.`})}else i.edits.length===0&&i.verifies>0||(v={...v,confidence:Math.min(v.confidence,s.refineNoAction)});if(i.usage){let e=r(v.metrics??{inputTokens:0,outputTokens:0},i.usage);v={...v,metrics:{...v.metrics,...e}}}u.onProgress?.({type:`refine:completed`,filePath:c.filePath,appliedCount:t})}catch(e){let t=e instanceof Error?e.message:String(e);
|
|
1
|
+
import{resolveChunkContent as e}from"../resolution/chunk-apply.js";import{createResolution as t}from"../resolution/create-resolution.js";import{checkResidualMarkers as n}from"../ports/verify.js";import{mergeUsages as r}from"../resolution/metrics.js";import{runResolverLoop as i}from"./loop.js";import{runRefinePass as a}from"./refine-pass.js";import{buildThreeWayDiff as o}from"./three-way-diff.js";const s={refineNoAction:.6,refineApplied:.9};async function c(c,l,u){let d=l.threeWayDiff||!l.refs?l:{...l,threeWayDiff:await o(c.filePath,l.refs,{git:u.git,signal:u.signal})},{chunks:f,strategy:p,confidence:m,description:h,metrics:g,followUpInstructions:_}=await i(c,d,{model:u.model,git:u.git,config:u.config,onProgress:u.onProgress,signal:u.signal}),v=t(c,f,{confidence:m,description:h,metrics:g,...p?{fileStrategy:p}:{},...d.threeWayDiff?{threeWayDiff:d.threeWayDiff}:{}}),y=_&&_.length>0;if(c.type===`text`&&y){u.onProgress?.({type:`refine:started`,filePath:c.filePath});let t=0;try{let i=await a(v.content,v.description,_,{model:u.model,signal:u.signal,temperature:u.config?.temperature,refineMaxSteps:u.config?.refineMaxSteps,onProgress:u.onProgress,filePath:c.filePath});if(i.edits.length>0){let e=n(c.filePath,i.content);if(e.valid)v={...v,content:i.content,edits:i.edits,strategy:`ai`},t=i.edits.length;else{let t=(e.issues??[]).map(e=>e.message).join(` `);u.onProgress?.({type:`refine:discarded`,filePath:c.filePath,reason:`Edits introduced conflict markers: ${t}`})}}if(t>0){v={...v,confidence:Math.min(v.confidence,s.refineApplied)};let t=[];for(let n=0;n<c.markers.length;n++){let r=c.markers[n];if(!r||r.userResolution==null)continue;let a=e({markerIndex:n,...r.userResolution},r);a!==``&&(i.content.includes(a)||t.push(n))}t.length>0&&(u.onProgress?.({type:`refine:touched-user-region`,filePath:c.filePath,markerIndexes:t}),v={...v,note:`Refine modified user-resolved region(s): marker ${t.join(`, `)}.`})}else i.edits.length===0&&i.verifies>0||(v={...v,confidence:Math.min(v.confidence,s.refineNoAction)});if(i.usage){let e=r(v.metrics??{inputTokens:0,outputTokens:0},i.usage);v={...v,metrics:{...v.metrics,...e}}}u.onProgress?.({type:`refine:completed`,filePath:c.filePath,appliedCount:t})}catch(e){if(u.signal?.aborted)throw e;let t=e instanceof Error?e.message:String(e);u.onProgress?.({type:`refine:failed`,filePath:c.filePath,reason:t}),v={...v,confidence:Math.min(v.confidence,s.refineNoAction)}}}else u.onProgress?.({type:`refine:skipped`,filePath:c.filePath,reason:`no-follow-ups`});if(u.validator&&c.type===`text`)try{let e=await u.validator.validate(new Map([[c.filePath,v.content]]));if(e.length>0){let t=e.map(e=>({category:e.category,severity:e.severity,tier:`file`,location:{file:e.file,...e.line==null?{line:1}:{line:e.line}},message:e.message}));v={...v,findings:t}}}catch(e){if(u.signal?.aborted)throw e;let t=e instanceof Error?e.message:String(e);u.onProgress?.({type:`validation:failed`,filePath:c.filePath,reason:t})}return u.onProgress?.({type:`resolver:completed`,filePath:c.filePath,stepCount:g.stepCount??0}),v}export{c as resolveConflict};
|