/**
 * Threadline hub commands — deterministic "open this" / "tie this to <topic>"
 * (CMT-529). Both the `POST /threadline/hub/bind` route AND the structural
 * intercept in `telegram.onTopicMessage` use `bindHubConversation`, so the
 * behavior is identical regardless of how the message arrived. `parseHubCommand`
 * is a pure, tightly-anchored matcher so ordinary hub chat falls through to the
 * agent.
 */
import type { CollaborationSurfacer } from './CollaborationSurfacer.js';
import type { ConversationStore } from './ConversationStore.js';
import type { CommitmentTracker } from '../monitoring/CommitmentTracker.js';
import { type BriefDeps } from './openConversationBrief.js';
export type HubCommand = {
    action: 'open';
} | {
    action: 'tie';
    targetTopicId?: number;
    targetTopicName?: string;
};
/**
 * Deterministically classify a hub-topic message. Returns null for anything
 * that isn't *only* a hub command, so "can you open this and explain it?" is
 * left to the conversational agent.
 */
export declare function parseHubCommand(text: string): HubCommand | null;
export interface HubBindDeps {
    collaborationSurfacer: CollaborationSurfacer;
    conversationStore: ConversationStore;
    commitmentTracker: CommitmentTracker | null;
    telegram: {
        findOrCreateForumTopic(name: string, iconColor?: number, opts?: {
            origin?: 'user' | 'system' | 'auto';
            label?: string;
        }): Promise<{
            topicId: number;
            name: string;
            reused: boolean;
        }>;
        sendToTopic(topicId: number, text: string, options?: {
            silent?: boolean;
        }): Promise<unknown>;
    };
    /**
     * Deps for the LLM topic-name + first-message summary (CMT-567). Optional:
     * when absent, the `open` path degrades to the slug name + legacy tie-marker
     * (exactly the pre-CMT-567 behavior). When present but its own sub-deps are
     * null, `generateConversationBrief` degrades to its template/slug tiers.
     */
    brief?: BriefDeps;
}
export interface HubBindArgs {
    action: 'open' | 'tie';
    threadId?: string;
    targetTopicId?: number;
    targetTopicName?: string;
    /** When true (the human "open this" intercept), resolve the ambiguous case to
     * the most-recent unbound instead of returning a 409. The API path leaves this
     * false so a scripted caller gets the explicit "specify threadId" error. */
    autoPick?: boolean;
}
export type HubBindResult = {
    ok: true;
    action: 'open' | 'tie';
    threadId: string;
    topicId: number;
    topicName: string;
} | {
    ok: false;
    status: number;
    error: string;
};
/**
 * Authoritatively bind a surfaced hub conversation to a topic. Returns a
 * discriminated result — NEVER touches an HTTP response; each caller owns its
 * own response + any extra messaging.
 */
export declare function bindHubConversation(deps: HubBindDeps, args: HubBindArgs): Promise<HubBindResult>;
//# sourceMappingURL=hubCommands.d.ts.map