/** * dsh-arc-context preset bridge — replace a mounted preset's official Basic * compaction backend with ARC inside its original service realm, through * official Loader patch semantics and zero file writes. * * Mechanism (every step is a public, documented Loader/Include behavior): * * 1. the bridge row (inserted by this package's `cordis.patch.yml` bundle * layer) registers the engine class in the Loader's public builtin * registry, the same registry app-boot itself uses for `cordis:group`; * 2. on every `agent/created`, the standing preset mount of the agent's * scope is located through the public `standingMountFor()` export of * `@deepseek-ai/dsh-agent-presets`; * 3. the mount's Include config gains runtime patches — disable the * `compaction-basic` row (guarded by its official package name) and * insert the ARC engine row into the unchanged `compaction` isolate * group — then `fiber.update(config, true)` re-reads the composition, * re-applies the patches, and reconciles the tree transactionally; * 4. the group keeps its `isolate: { compaction: true }` realm, so the ARC * engine provides `ctx.compaction` exactly where Basic did and the * sibling rows (`command-compact`, `tool-result-pruner`) rebind to it * without any change of their own. * * Nothing is ever written to disk: preset files, row ids, group nesting, and * user patches stay byte-identical, and both uninstall and a plain restart * remount the untouched original composition. The fiber mutation is owned by * a Cordis effect whose reverse update restores the original Include config * (the same transactional re-apply, run backwards). * * @module dsh-arc-context/bridge */ import type { Context, Fiber } from '@deepseek-ai/cordis'; import { Config, type Config as ArcConfig } from './index.ts'; /** Structural loader patch shape (`PatchOptions` without the type-only dependency). */ interface EntryPatch { readonly id: string; readonly name?: string; readonly disabled?: boolean; readonly insert?: ReadonlyArray>; } /** Live Include config of a preset mount. */ interface PresetIncludeConfig { readonly path: string; patches?: EntryPatch[]; readonly [key: string]: unknown; } /** One patched preset mount, restorable by effect-owned teardown. */ interface TrackedMount { readonly config: PresetIncludeConfig; readonly hadPatches: boolean; readonly originalPatches: EntryPatch[] | undefined; } /** A standing preset mount as the bridge addresses it. */ export interface PresetMountHandle { readonly presetId: string; readonly fiber: Fiber; } /** Outcome of one takeover attempt. */ export type TakeoverStatus = 'taken-over' | 'already-arc' | 'no-basic-row' | 'unrecognized-carrier'; /** * Patches that swap Basic for ARC inside the preset's own compaction realm: * the name guard means only the official Basic row is ever disabled, and the * insert keeps the group (and therefore its isolate map) untouched. * @param config - ARC engine config applied to the inserted row. * @returns the patch list to append to the mount's Include config. */ export declare function buildTakeoverPatches(config: ArcConfig): [EntryPatch, EntryPatch]; /** * Swap one standing preset mount's compaction backend in-realm. The mount's * live Include config object is mutated in place — never replaced — so the * tree keeps its original config identity (the harness-base record for bare * `@deepseek-ai/*` imports is keyed by that object). * * The swap runs as TWO sequential Include updates, not one: a group update * force-restarts every unchanged sibling row, so retiring Basic and mounting * ARC in the same update would race Basic's re-construction against the * engine's service registration inside the realm. Sequential updates give * the ordering the concurrent reconcile cannot: phase 1 disables the Basic * row (nothing new starts), phase 2 inserts the engine row into the vacated * realm. * * @param ctx - the bridge's Cordis context. * @param config - ARC engine config applied to the inserted row. * @param mount - the standing preset mount to patch. * @param tracked - effect-owned registry of patched mounts (restored on dispose). * @returns the takeover outcome; `fiber.update` failures propagate after * in-place rollback of the config mutation. */ export declare function takeoverMount(ctx: Context, config: ArcConfig, mount: PresetMountHandle, tracked: Map): Promise; /** * Revert one patched mount with the same two-phase ordering, run backwards: * first remove the inserted engine row (Basic stays disabled, so the engine * leaves the realm unopposed), then re-enable the official Basic row in the * vacated realm. * @param fiber - the standing mount's Include fiber previously patched. * @param tracked - the effect-owned registry of patched mounts. */ export declare function rollbackMount(fiber: Fiber, tracked: Map): Promise; export declare const name = "dsh-arc-context-bridge"; export declare const inject: string[]; export { Config }; /** * Install the preset bridge. The engine is published as a loader builtin for * preset rows, every agent creation swaps its standing preset's Basic row for * ARC in-realm, and disposing the bridge fiber first reverts every patched * mount (transactional re-apply of the original Include config) and then * removes the builtin registration. A process restart reaches the same * unpatched state from the untouched files. * * @param ctx - host context carrying the public Loader and agent-presets services. * @param config - ARC configuration applied to every replaced Basic row. */ export declare function apply(ctx: Context, config: ArcConfig): void;