resolveEditMode function

EditModePlan resolveEditMode({
  1. required String? path,
  2. required String? oldText,
  3. required String? newText,
  4. required String? patch,
})

Resolves an edit tool call's mode from its raw arguments (UT-1..3, E1).

Deterministic policy (card OQ1, patch-first):

  • A usable patch wins whenever present — the hashline header is self-validating and a stale tag rejects before any write, so a complete patch is the safer of the two modes.
  • A malformed patch with a complete exact-match triple falls back to exact-match (AC2) instead of rejecting.
  • Only "neither mode complete" rejects, with the remedy example (AC3).

Implementation

EditModePlan resolveEditMode({
  required String? path,
  required String? oldText,
  required String? newText,
  required String? patch,
}) {
  final exactComplete = exactMatchComplete(
    path: path,
    oldText: oldText,
    newText: newText,
  );
  // ONE parse, honoring the executor's fallbackPath contract, carried
  // through the plan (issue #862 review).
  final parse = parsePatch(patch, fallbackPath: path);

  if (parse.usable) {
    final mixed = oldText != null || newText != null;
    return EditRunPatch(
      parsed: parse.patch!,
      notice: mixed
          ? bothModesNotice(winner: 'the hashline patch')
          : null,
    );
  }
  if (exactComplete) {
    final patchSent = patch != null && patch.trim().isNotEmpty;
    return EditRunExactMatch(
      path: path!,
      oldText: oldText!,
      newText: newText!,
      notice: patchSent
          ? bothModesNotice(winner: 'the exact-match replace')
          : null,
    );
  }
  if (patch != null && patch.trim().isNotEmpty) {
    // A patch was attempted but is malformed, and exact-match cannot
    // rescue the call: reject with the parser's focused diagnostic plus
    // the remedy (AC3's sibling shape).
    return EditReject(
      'The patch input is not a valid hashline patch '
      '(${parse.error}), and the exact-match arguments are '
      'incomplete. $editRemedyExample',
    );
  }
  return EditReject(
    'Missing arguments: provide either patch (hashline mode) or path + '
    'oldText + newText (exact-match mode). $editRemedyExample',
  );
}