'use strict';

var client = require('./generated/client.cjs');
var contract = require('./generated/contract.cjs');
var process = require('./runtime/process.cjs');
var errors = require('./runtime/errors.cjs');
var skills = require('./skills.cjs');
var tools = require('./tools.cjs');
var intentDispatch_generated = require('./generated/intent-dispatch.generated.cjs');
var presets = require('./presets.cjs');

// ---------------------------------------------------------------------------
// Session-bound runtime wrapper
// ---------------------------------------------------------------------------
/**
 * Wraps a raw runtime and injects a fixed sessionId into every invoke call.
 * Implements RuntimeInvoker so generated code can use it directly.
 *
 * @internal
 */
class BoundRuntime {
    runtime;
    sessionId;
    closed = false;
    constructor(runtime, sessionId) {
        this.runtime = runtime;
        this.sessionId = sessionId;
    }
    async invoke(operation, params = {}, options = {}) {
        if (this.closed) {
            throw new errors.SuperDocCliError(`Document handle is closed; cannot invoke ${operation.operationId}.`, {
                code: 'DOCUMENT_CLOSED',
                details: { sessionId: this.sessionId, operationId: operation.operationId },
            });
        }
        return this.runtime.invoke(operation, { ...params, sessionId: this.sessionId }, options);
    }
    markClosed() {
        this.closed = true;
    }
}
// ---------------------------------------------------------------------------
// Document handle
// ---------------------------------------------------------------------------
/**
 * Bound document handle. All document operations are available as typed methods.
 * The handle injects its session id automatically — callers never pass
 * doc or sessionId.
 */
class SuperDocDocumentCore {
    boundRuntime;
    _sessionId;
    _openResult;
    client;
    /** @internal */
    constructor(boundRuntime, sessionId, openResult, client$1) {
        this.boundRuntime = boundRuntime;
        this._sessionId = sessionId;
        this._openResult = openResult;
        this.client = client$1;
        attachBoundDocApi(this, client.createBoundDocApi(this.boundRuntime));
    }
    get sessionId() {
        return this._sessionId;
    }
    /** Read-only snapshot of the initial doc.open response metadata. */
    get openResult() {
        return this._openResult;
    }
    async save(params = {}, options = {}) {
        return this.boundRuntime.invoke(contract.CONTRACT.operations['doc.save'], params, options);
    }
    async close(params = {}, options = {}) {
        const result = await this.boundRuntime.invoke(contract.CONTRACT.operations['doc.close'], params, options);
        this.boundRuntime.markClosed();
        this.client.removeHandle(this._sessionId);
        return result;
    }
    /** @internal */
    markClosed() {
        this.boundRuntime.markClosed();
    }
    async formatRange(params, options = {}) {
        const { properties, ...rest } = params;
        return this.boundRuntime.invoke(contract.CONTRACT.operations['doc.format.apply'], {
            ...rest,
            inline: properties,
        }, options);
    }
}
function attachBoundDocApi(target, api) {
    const { save: _save, close: _close, ...boundMethods } = api;
    Object.assign(target, boundMethods);
}
const SuperDocDocument = SuperDocDocumentCore;
/**
 * SuperDoc client — transport manager and document factory.
 *
 * Use `client.open()` to get bound document handles. Each handle is
 * independently session-scoped and safe for concurrent use.
 *
 *     const client = new SuperDocClient({ user: { name: 'bot' } });
 *     await client.connect();
 *     const doc = await client.open({ doc: './file.docx' });
 *     const markdown = await doc.getMarkdown();
 *     await doc.close();
 *     await client.dispose();
 */
class SuperDocClient {
    runtime;
    rawApi;
    handles = new Map();
    constructor(options = {}) {
        this.runtime = new process.SuperDocRuntime(options);
        this.rawApi = client.createDocApi(this.runtime);
    }
    async connect() {
        await this.runtime.connect();
    }
    /**
     * Open a document and return a bound document handle.
     *
     * The returned handle injects its session id into every operation
     * automatically. The same file can be opened multiple times with
     * different session ids (useful for diff workflows).
     */
    async open(params, options) {
        const explicitSessionId = params.sessionId;
        if (typeof explicitSessionId === 'string' && this.handles.has(explicitSessionId)) {
            throw new errors.SuperDocCliError(`Session id already open in this client: ${explicitSessionId}`, {
                code: 'SESSION_ALREADY_OPEN',
                details: { sessionId: explicitSessionId },
            });
        }
        const result = (await this.rawApi.open(params, options));
        const contextId = result.contextId;
        const boundRuntime = new BoundRuntime(this.runtime, contextId);
        const handle = new SuperDocDocument(boundRuntime, contextId, result, this);
        this.handles.set(contextId, handle);
        return handle;
    }
    async describe(params = {}, options) {
        return this.rawApi.describe(params, options);
    }
    async describeCommand(params, options) {
        return this.rawApi.describeCommand(params, options);
    }
    async dispose() {
        for (const handle of this.handles.values()) {
            handle.markClosed();
        }
        this.handles.clear();
        await this.runtime.dispose();
    }
    /** @internal */
    removeHandle(sessionId) {
        this.handles.delete(sessionId);
    }
}
function createSuperDocClient(options = {}) {
    return new SuperDocClient(options);
}

exports.SuperDocCliError = errors.SuperDocCliError;
exports.getSkill = skills.getSkill;
exports.installSkill = skills.installSkill;
exports.listSkills = skills.listSkills;
exports.chooseTools = tools.chooseTools;
exports.dispatchSuperDocTool = tools.dispatchSuperDocTool;
exports.getMcpPrompt = tools.getMcpPrompt;
exports.getSystemPrompt = tools.getSystemPrompt;
exports.getSystemPromptForProvider = tools.getSystemPromptForProvider;
exports.getToolCatalog = tools.getToolCatalog;
exports.listTools = tools.listTools;
exports.dispatchIntentTool = intentDispatch_generated.dispatchIntentTool;
exports.DEFAULT_PRESET = presets.DEFAULT_PRESET;
exports.getPreset = presets.getPreset;
exports.listPresets = presets.listPresets;
exports.SuperDocClient = SuperDocClient;
exports.SuperDocDocument = SuperDocDocument;
exports.createSuperDocClient = createSuperDocClient;
