import { Receipt, TrackChangeInfo, TrackChangesListQuery, TrackChangesListResult } from '../types/index.js'; import { StoryLocator } from '../types/story.types.js'; import { TextTarget } from '../types/address.js'; import { RevisionGuardOptions } from '../write/write.js'; export type TrackChangesListInput = TrackChangesListQuery; export interface TrackChangesGetInput { id: string; /** Story containing the tracked change. Omit for body (backward compatible). */ story?: StoryLocator; } export interface TrackChangesAcceptInput { id: string; /** Story containing the tracked change. Omit for body (backward compatible). */ story?: StoryLocator; /** * Optional replacement side. When the id resolves to a paired replacement, * `'inserted'` / `'deleted'` decides only that half, leaving the other half * as a standalone pending change. */ side?: 'inserted' | 'deleted'; } export interface TrackChangesRejectInput { id: string; /** Story containing the tracked change. Omit for body (backward compatible). */ story?: StoryLocator; /** * Optional replacement side. When the id resolves to a paired replacement, * `'inserted'` / `'deleted'` decides only that half, leaving the other half * as a standalone pending change. */ side?: 'inserted' | 'deleted'; } export interface TrackChangesAcceptAllInput { story?: StoryLocator | 'all'; } export interface TrackChangesRejectAllInput { story?: StoryLocator | 'all'; } export interface TrackChangesRangeInput { range: TextTarget; story?: StoryLocator; } export type ReviewDecideTargetSide = 'insert' | 'inserted' | 'delete' | 'deleted' | 'source' | 'destination'; /** * Replacement side for an `id` decide target: which half of a paired * replacement to resolve. Only `'inserted'` / `'deleted'` are valid here (a * paired replacement has no move roles), matching the published schema and the * runtime validator. The broader {@link ReviewDecideTargetSide} — which also * carries range/move-only values — applies to `range` targets. */ export type ReplacementSide = 'inserted' | 'deleted'; /** * Tracked-move pairing assertion for a decide target. Callers that resolved an * ambiguous shape (e.g. surface guesses a paragraph delete+insert might be a * move) can ask the decide adapter to verify the projection before applying * the decision. `'pair'` asserts the resolved entry must be a paired move; * `'source'` / `'destination'` further narrow to a specific half. When the * assertion does not hold the adapter fails closed with an explicit failure * code instead of silently treating the target as a non-move decision. */ export type ReviewDecideTargetMoveRole = 'pair' | 'source' | 'destination'; export interface ReviewDecideRangeTargetOptions { /** * Optional logical overlap selector for callers that already resolved an * ambiguous overlap surface. The adapter owns interpretation. */ overlap?: string; /** Optional revision side for paired replacement or move targets. */ side?: ReviewDecideTargetSide; /** Optional story containing the range. */ story?: StoryLocator; /** Compatibility alias used by older range callers; interpretation is adapter-owned. */ part?: string; } export type ReviewDecideTextRangeTarget = ReviewDecideRangeTargetOptions & { kind: 'range'; range: TextTarget; }; export type ReviewDecideLogicalRangeTarget = ReviewDecideRangeTargetOptions & { kind: 'range'; range: { anchor: string; relativeStart: number; relativeEnd: number; }; }; /** Semantic target for {@link ReviewDecideInput}. */ export type ReviewDecideTarget = { kind: 'id'; id: string; story?: StoryLocator; moveRole?: ReviewDecideTargetMoveRole; side?: ReplacementSide; } | ReviewDecideTextRangeTarget | ReviewDecideLogicalRangeTarget | { kind: 'all'; story?: StoryLocator | 'all'; }; /** Legacy compatibility shapes accepted by the validator. */ export type LegacyReviewDecideTarget = { id: string; story?: StoryLocator; moveRole?: ReviewDecideTargetMoveRole; side?: ReplacementSide; } | { scope: 'all'; story?: StoryLocator | 'all'; }; export type ReviewDecisionTarget = ReviewDecideTarget | LegacyReviewDecideTarget; export interface ReviewDecideInput { decision: 'accept' | 'reject'; target: ReviewDecideTarget | LegacyReviewDecideTarget; /** * Backward-compatible alias for `options.expectedRevision`. Explicit options * take precedence when both are supplied. */ expectedRevision?: string; } /** * Internal canonical decide target — the legacy shapes have been promoted to * `{ kind: 'id' }` / `{ kind: 'all' }`. Adapters consume this normalized * form so the kernel side does not need to re-handle legacy aliases. */ export interface ReviewDecideRangeInput { decision: 'accept' | 'reject'; target: ReviewDecideTarget; } export interface TrackChangesAdapter { /** List tracked changes matching the given query. */ list(input?: TrackChangesListInput): TrackChangesListResult; /** Retrieve full information for a single tracked change. */ get(input: TrackChangesGetInput): TrackChangeInfo; /** * Apply an accept / reject decision against the document. By-id, range, * routes by-id, range, and bulk targets through this single entrypoint; * legacy `accept` / `reject` / `acceptAll` / `rejectAll` adapter methods * remain as compatibility shims until callers migrate. */ decide?(input: ReviewDecideRangeInput, options?: RevisionGuardOptions): Receipt; /** Accept a tracked change, applying it to the document. */ accept(input: TrackChangesAcceptInput, options?: RevisionGuardOptions): Receipt; /** Reject a tracked change, reverting it from the document. */ reject(input: TrackChangesRejectInput, options?: RevisionGuardOptions): Receipt; /** Accept all tracked changes matching the requested bulk filter. */ acceptAll(input: TrackChangesAcceptAllInput, options?: RevisionGuardOptions): Receipt; /** Reject all tracked changes matching the requested bulk filter. */ rejectAll(input: TrackChangesRejectAllInput, options?: RevisionGuardOptions): Receipt; /** * Compatibility range entrypoint for adapters that predate the canonical * `decide` method but can still resolve TextTarget range decisions. */ decideRange?(input: { decision: 'accept' | 'reject'; } & TrackChangesRangeInput, options?: RevisionGuardOptions): Receipt; } /** Public surface for trackChanges on DocumentApi. */ export interface TrackChangesApi { list(input?: TrackChangesListInput): TrackChangesListResult; get(input: TrackChangesGetInput): TrackChangeInfo; decide(input: ReviewDecideInput, options?: RevisionGuardOptions): Receipt; } /** * Execute wrappers below are the canonical interception point for input * normalization and validation before delegating to the adapter. */ export declare function executeTrackChangesList(adapter: TrackChangesAdapter, input?: TrackChangesListInput): TrackChangesListResult; export declare function executeTrackChangesGet(adapter: TrackChangesAdapter, input: TrackChangesGetInput): TrackChangeInfo; /** * Executes the consolidated `trackChanges.decide` operation by routing to the * appropriate adapter method based on the discriminated input. * * Accepting/rejecting changes is a resolution action, not a content mutation - * changeMode and dryRun are not applicable, so this accepts * {@link RevisionGuardOptions} rather than `MutationOptions`. * * Validates the canonical discriminated target shape * (`{ kind: 'id' | 'range' | 'all' }`) and transparently promotes the * legacy `{ id, story? }` / `{ scope: 'all' }` shapes. Adapters that * implement the new {@link TrackChangesAdapter.decide} entrypoint receive * the normalized canonical input; older adapters that only expose * accept/reject/acceptAll/rejectAll still work for id and all targets. */ export declare function executeTrackChangesDecide(adapter: TrackChangesAdapter, rawInput: ReviewDecideInput, options?: RevisionGuardOptions): Receipt; /** * Validate and normalize a `trackChanges.decide` input into the canonical * `{ kind: 'id' | 'range' | 'all' }` target shape. Exposed for adapters / * tests that need to share the same validation surface. */ export declare function validateReviewDecideInput(rawInput: ReviewDecideInput): ReviewDecideRangeInput; //# sourceMappingURL=track-changes.d.ts.map