/** * `vendo_text_me` — one text to the person the run is FOR, from any surface. * * It exists because the text channel could only ever answer: a conversation the * user started, in the turn they started it. Everything that wants to reach them * later — an away automation, a web turn that finishes after they have closed the * tab — had nothing to call, so the channel's own grounding told the model to * point at the app and promise "coming soon" (channel-turn.ts). This is the other * half: the action an automation holds a grant for, so "text me when the rent * clears" is armed once and delivered forever. * * MISUSE RESISTANCE IS THE SHAPE, not a check: the input is `{ text }` and * nothing else. There is no number to pass, so no model output can aim a text at * a phone that is not the current subject's own — the destination is read from * the link row under `ctx.principal`, which only ever exists because that signed-in * user asked for it and texted a code back (channel-links.ts). * * Consent is the existing machinery, untouched: a `write` descriptor on the one * registry, so a present turn parks a card under whatever the host's policy says, * and an away firing needs the standing grant that arming mints (automations * `grants.ts`). No new consent path, no per-tool allowlist. */ import { type Principal, type ToolRegistry } from "./core/index.js"; import type { ChannelLinkRepository } from "./channel-links.js"; import type { ChannelsService, TextChannelInvite } from "./channels.js"; export declare const VENDO_TEXT_ME_TOOL = "vendo_text_me"; export interface TextMeDeps { channel: ChannelsService; links: ChannelLinkRepository; /** The connect flow's own invite — the same `sms:` URL the link page hands * out, so an agent that finds no phone offers the ONE link that fixes it. */ invite: (principal: Principal) => Promise; } /** * The `vendo_text_me` door as a one-tool registry, composed alongside the others * (compose-channels.ts) and ONLY when a channel adapter is configured — the same * "no adapter, no tool" rule knowledge and the connector pair follow. A * deployment that never asked for texts must not be shown a tool whose every * call would refuse. */ export declare function textMeRegistry(deps: TextMeDeps): ToolRegistry;