@tangle-network/agent-app 0.49.23 → 0.49.25

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/channels/context.tsx","../../src/channels/hooks.ts","../../src/channels/components.tsx","../../src/channels/numbers.ts","../../src/channels/ui.tsx","../../src/channels/payment.tsx"],"sourcesContent":["import { createContext, useContext, type ReactNode } from 'react'\nimport type { ChannelsClient } from './types'\n\nconst Context = createContext<{ client: ChannelsClient; pollInterval: number | false } | null>(null)\n\n/** Mount below authentication. Changing scope remounts all channel state. */\nexport function ChannelsProvider({ client, pollInterval = 3000, children }: {\n client: ChannelsClient\n /** Poll after a read settles, never concurrently. false disables polling. */\n pollInterval?: number | false\n children: ReactNode\n}) {\n if (pollInterval !== false && (!Number.isFinite(pollInterval) || pollInterval < 100)) {\n throw new Error('ChannelsProvider pollInterval must be false or at least 100 ms.')\n }\n return <Context.Provider value={{ client, pollInterval }} key={client.scope}>{children}</Context.Provider>\n}\n\nexport function useChannelsClient(): ChannelsClient {\n return useChannelsContext().client\n}\n\nexport function useChannelsContext() {\n const value = useContext(Context)\n if (!value) throw new Error('Channel components and hooks require ChannelsProvider.')\n return value\n}\n","import { useCallback, useEffect, useRef } from 'react'\nimport { confirmWrite, rejectWrite, useAsyncResource, useConfirmedMutation } from '../web-react/async'\nimport type { AsyncLoadContext, AsyncResourceState, MutationOutcome } from '../web-react/async'\nimport { useChannelsContext } from './context'\nimport type { ChannelVerification, ConnectChannelInput, Line, LineTransport } from './types'\n\n/** Reuse the kit's abort/sequence-aware read machine; polling never overlaps a read. */\nexport function useChannelResource<T>(load: (context: AsyncLoadContext) => Promise<T>, deps: readonly unknown[], enabled = true, poll = true): AsyncResourceState<T> {\n const { client, pollInterval } = useChannelsContext()\n const resource = useAsyncResource({ load, deps: [client, client.scope, ...deps], enabled })\n useEffect(() => {\n if (!enabled || !poll || pollInterval === false || resource.status === 'loading' || resource.status === 'idle') return\n const delay = typeof document !== 'undefined' && document.hidden ? Math.max(15000, pollInterval) : pollInterval\n const timer = setTimeout(resource.retry, delay)\n return () => clearTimeout(timer)\n }, [enabled, poll, pollInterval, resource.status, resource.retry, resource])\n return enabled ? resource : { status: 'idle', retry: resource.retry }\n}\n\n/** Single-flight on top of the shared confirmed-write primitive. */\nexport function useChannelMutation<I, O>(mutate: (input: I, context: AsyncLoadContext) => Promise<O>, onSucceeded?: (value: O) => void) {\n const { client } = useChannelsContext()\n const lock = useRef<object | null>(null)\n const mutation = useConfirmedMutation<I, O>({\n mutate: async (input, context) => confirmWrite(await mutate(input, context)),\n onSucceeded,\n })\n const { reset, run } = mutation\n useEffect(() => {\n reset()\n return () => { lock.current = null; reset() }\n }, [client, client.scope, reset])\n const singleRun = useCallback(async (input: I): Promise<MutationOutcome<O>> => {\n if (lock.current) return rejectWrite('Another channel operation is still in progress.')\n const token = {}\n lock.current = token\n try { return await run(input) }\n finally { if (lock.current === token) lock.current = null }\n }, [run])\n return { ...mutation, run: singleRun }\n}\n\nexport function useChannels() {\n const { client } = useChannelsContext()\n return useChannelResource(() => client.lines.list(), [])\n}\n\nexport function useChannelConnections(transport: LineTransport) {\n const { client } = useChannelsContext()\n return useChannelResource(context => client.setup.connections(transport, context), [transport], true, false)\n}\n\nexport function useWhatsAppNumbers(connectionId: string) {\n const { client } = useChannelsContext()\n return useChannelResource(context => client.setup.whatsappNumbers(connectionId, context), [connectionId], !!connectionId, false)\n}\n\n/** Connect only acquires/binds a line. It never labels it verified or activates replies. */\nexport function useConnectChannel(onConnected?: (line: Line) => void) {\n const { client } = useChannelsContext()\n return useChannelMutation<ConnectChannelInput, Line>(async input => {\n if (input.kind === 'connection') {\n if (!input.input.connectionId.trim()) throw new Error('Choose a connection.')\n if (input.input.transport === 'whatsapp' && !input.input.phoneNumberId.trim()) throw new Error('Choose a WhatsApp number.')\n return client.lines.fromConnection(input.input)\n }\n if (input.kind === 'order') {\n if (!input.orderId.trim()) throw new Error('Choose a number order.')\n return client.setup.fromOrder(input.orderId)\n }\n const address = input.address.trim().toLowerCase()\n if (!input.connectionId.trim() || !/^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/.test(address)) throw new Error('Choose a connection and enter a valid mailbox address.')\n return client.setup.fromEmail({ connectionId: input.connectionId, address })\n }, onConnected)\n}\n\nexport function verificationExpired(test: ChannelVerification, now = Date.now()): boolean {\n return test.expired || (test.status !== 'verified' && test.expiresAt <= now)\n}\n\nexport type VerificationAction = 'start' | 'resume' | 'send' | 'activate' | 'reset'\n\nexport function useChannel(lineId: string) {\n const { client } = useChannelsContext()\n const resource = useChannelResource(async context => {\n const [line, verification] = await Promise.all([client.lines.get(lineId), client.setup.verification(lineId, context)])\n if (line.id !== lineId || (line.attachment && line.attachment.lineId !== lineId) || (verification && verification.lineId !== lineId)) throw new Error('Channel binding changed. Reload channel setup.')\n return { line, verification }\n }, [lineId], !!lineId)\n const mutation = useChannelMutation<{ action: VerificationAction; confirm?: boolean }, void>(async ({ action, confirm }) => {\n if (resource.status !== 'ready') throw new Error('Read the current channel state before changing it.')\n const { line, verification: test } = resource.value\n if (line.id !== lineId) throw new Error('Channel binding changed. Reload channel setup.')\n if (action !== 'reset' && line.status !== 'active') throw new Error('This line is not active.')\n if (action === 'start') {\n if (test && test.status !== 'revoked') throw new Error('Stop the existing test before starting another.')\n await client.setup.start(lineId)\n return\n }\n if (!test || test.lineId !== lineId) throw new Error('Start a channel test first.')\n if (action === 'reset') {\n if (confirm !== true) throw new Error('Confirm stopping this test.')\n await client.setup.reset(lineId, test.id)\n return\n }\n if (verificationExpired(test)) throw new Error('This test expired. Stop it and start a new test.')\n if (action === 'activate') {\n if (test.status !== 'verified') throw new Error('Verify inbound delivery and the test reply before activation.')\n const activated = await client.setup.activate(lineId, test.id)\n if (activated.id !== lineId || activated.status !== 'active' || activated.attachment?.status !== 'active' || activated.attachment.lineId !== lineId) throw new Error('Messaging activation was not confirmed.')\n } else if (action === 'send') {\n if (test.status !== 'received') throw new Error('Wait for the inbound test message before sending a reply.')\n await client.setup.send(lineId, test.id)\n } else {\n if (test.status !== 'configuring' && test.status !== 'uncertain') throw new Error('This test is not waiting for a setup check.')\n await client.setup.resume(lineId, test.id)\n }\n }, resource.retry)\n useEffect(() => mutation.reset(), [lineId, mutation.reset])\n return { resource, ...mutation }\n}\n\nexport function useChannelConversations(lineId: string) {\n const { client } = useChannelsContext()\n return useChannelResource(async () => {\n const threads = await client.lines.threads(lineId).list()\n if (threads.some(thread => thread.lineId !== lineId)) throw new Error('The thread response belongs to another line.')\n return threads\n }, [lineId], !!lineId)\n}\n\nexport function useChannelConversation(lineId: string, threadId: string) {\n const { client } = useChannelsContext()\n return useChannelResource(async () => {\n const messages = await client.lines.threads(lineId).messages(threadId)\n // The SDK returns newest first. Never mutate it, and never render another thread.\n if (messages.some(message => message.threadId !== threadId)) throw new Error('The message response belongs to another conversation.')\n return [...new Map(messages.map(message => [message.id, message])).values()]\n .sort((a, b) => a.createdAt.localeCompare(b.createdAt) || a.id.localeCompare(b.id))\n }, [lineId, threadId], !!lineId && !!threadId)\n}\n","import { useEffect, useId, useState } from 'react'\nimport { useChannelsClient } from './context'\nimport { useChannel, useChannelConnections, useChannelConversation, useChannelConversations, useChannels, useConnectChannel, useWhatsAppNumbers, verificationExpired } from './hooks'\nimport { NUMBER_CHARGE_NOTICE, NUMBER_RETRY_NOTICE, numberStage, useNumberChannel } from './numbers'\nimport type { Line, LineTransport } from './types'\nimport { ChannelFailure, ChannelState, buttonClass, primaryButtonClass, inputClass, panelClass } from './ui'\n\nconst labels: Record<LineTransport, string> = { imessage: 'iMessage', whatsapp: 'WhatsApp', sms: 'SMS', email: 'Email' }\n\n/** User-facing deep links, not provider API calls. Invalid addresses render as text only. */\nexport function channelMessageLink(line: Line, instruction: string): string | null {\n if (line.transport === 'email') {\n if (!/^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/.test(line.address)) return null\n return `mailto:${encodeURIComponent(line.address)}?subject=Channel%20test&body=${encodeURIComponent(instruction)}`\n }\n const address = line.routerAddress ?? line.address\n if (!/^\\+[1-9]\\d{7,14}$/.test(address)) return null\n if (line.transport === 'whatsapp') return `https://wa.me/${address.slice(1)}?text=${encodeURIComponent(instruction)}`\n return `sms:${address}?body=${encodeURIComponent(line.connect ?? instruction)}`\n}\n\nfunction CopyLine({ text }: { text: string }) {\n const [message, setMessage] = useState('')\n return <div className=\"space-y-2\"><div className=\"flex items-start gap-2 rounded-md bg-muted p-3\">\n <code className=\"min-w-0 flex-1 break-all\">{text}</code>\n <button type=\"button\" className={buttonClass} aria-label={`Copy ${text}`} onClick={async () => {\n try { await navigator.clipboard.writeText(text); setMessage('Copied') }\n catch { setMessage('Copy is unavailable. Select and copy the displayed text.') }\n }}>Copy</button>\n </div>{message && <p role=\"status\" className=\"text-sm\">{message}</p>}</div>\n}\n\n/** Delivery evidence comes exclusively from the host. An acquired line is not proof. */\nexport function ChannelVerificationPanel({ lineId, className = '' }: { lineId: string; className?: string }) {\n const channel = useChannel(lineId)\n const [confirming, setConfirming] = useState(false)\n useEffect(() => setConfirming(false), [lineId])\n const busy = channel.state.status === 'pending'\n const act = (action: 'start' | 'resume' | 'send' | 'activate') => void channel.run({ action })\n return <section className={`${panelClass} ${className}`} aria-label=\"Channel verification\" aria-busy={busy}>\n <h2 className=\"text-lg font-semibold\">Verify this channel</h2>\n <ChannelState resource={channel.resource} empty=\"The channel is unavailable.\">{({ line, verification: test }) => {\n const expired = test ? verificationExpired(test) : false\n const active = line.status === 'active' && line.attachment?.status === 'active'\n const link = test ? channelMessageLink(line, test.instruction) : null\n return <>\n <p className=\"break-all font-medium\">{labels[line.transport]} · {line.address}</p>\n {line.status !== 'active' ? <p role=\"alert\">This line is {line.status}. Check the line’s status before testing or activating it.</p>\n : active && test?.status === 'verified' && !expired ? <>\n <p role=\"status\">Both directions verified. Answering {labels[line.transport]} messages.</p>\n <p>{line.connect && line.routerAddress ? `Share this: send ${line.connect} to ${line.routerAddress}.` : 'Share this channel address so people can start a conversation.'}</p>\n <CopyLine text={line.connect ?? line.address} />\n </>\n : !test || test.status === 'revoked' ? <>\n {active && <p>Attached to an agent, but no completed delivery test was returned.</p>}\n <p>Test inbound delivery and a reply before this agent answers people.</p>\n <button type=\"button\" className={primaryButtonClass} disabled={busy} onClick={() => act('start')}>Start channel test</button>\n </> : expired ? <p role=\"alert\">This test expired. Stop it before starting a new test.</p>\n : test.status === 'verified' ? <><p>Both directions verified. Messaging is not turned on yet.</p>\n <button type=\"button\" className={primaryButtonClass} disabled={busy} onClick={() => act('activate')}>Turn on messaging</button></>\n : test.status === 'configuring' ? <><p>Connecting incoming messages to Tangle.</p>\n <button type=\"button\" className={primaryButtonClass} disabled={busy} onClick={() => act('resume')}>Check setup</button></>\n : test.status === 'waiting' ? <>\n {line.connect && line.routerAddress && <><p>First, send this to {line.routerAddress}. The router replies with your agent’s number.</p><CopyLine text={line.connect} /></>}\n <p>{line.transport === 'email' ? `From another email address, send this line to ${line.address}.` : line.connect ? 'Then send this in the conversation the router opens:' : `From your phone, send this to ${line.address}:`}</p>\n <CopyLine text={test.instruction} />\n {link && <a className={primaryButtonClass} href={link} target={line.transport === 'whatsapp' ? '_blank' : undefined} rel=\"noopener noreferrer\">Open {line.transport === 'email' ? 'Email' : line.transport === 'whatsapp' ? 'WhatsApp' : 'Messages'}</a>}\n </> : test.status === 'received' ? <><p role=\"status\">Your test message arrived.</p><button type=\"button\" className={primaryButtonClass} disabled={busy} onClick={() => act('send')}>Send test reply</button></>\n : test.status === 'sending' ? <p role=\"status\">The test reply is being sent. Do not send another.</p>\n : test.status === 'uncertain' ? <><p role=\"alert\">The reply result is uncertain. Check its status instead of sending another.</p><button type=\"button\" className={primaryButtonClass} disabled={busy} onClick={() => act('resume')}>Check reply status</button></>\n : test.status === 'needs_review' ? <p role=\"alert\">Incoming message setup needs operator review. No delivery success is claimed.</p>\n : <p>Reply with the CONFIRM line in the message you received, in the same conversation.</p>}\n {test?.error && <p role=\"alert\" className=\"text-destructive\">{test.error}</p>}\n {test && test.status !== 'revoked' && !(active && test.status === 'verified' && !expired) && <>\n {!confirming ? <button type=\"button\" className={buttonClass} disabled={busy} onClick={() => setConfirming(true)}>Stop this test</button> : <fieldset className=\"space-y-2\"><legend>Stop this test and revoke its setup?</legend>\n <button type=\"button\" className={buttonClass} disabled={busy} onClick={async () => { const outcome = await channel.run({ action: 'reset', confirm: true }); if (outcome.succeeded) setConfirming(false) }}>Confirm stop</button>{' '}\n <button type=\"button\" className={buttonClass} disabled={busy} onClick={() => setConfirming(false)}>Keep testing</button>\n </fieldset>}\n </>}\n <button type=\"button\" className={buttonClass} disabled={busy} onClick={channel.resource.retry}>Refresh channel status</button>\n </>\n }}</ChannelState>\n <ChannelFailure state={channel.state} />\n </section>\n}\n\nfunction ConnectionPicker({ transport, onConnected }: { transport: Exclude<LineTransport, 'sms'>; onConnected: (line: Line) => void }) {\n const client = useChannelsClient()\n const connections = useChannelConnections(transport)\n const [connectionId, setConnectionId] = useState('')\n const [numberId, setNumberId] = useState('')\n const [address, setAddress] = useState('')\n const [showNumbers, setShowNumbers] = useState(false)\n const numbers = useWhatsAppNumbers(showNumbers ? connectionId : '')\n const connect = useConnectChannel(onConnected)\n const busy = connect.state.status === 'pending'\n useEffect(() => { setConnectionId(''); setNumberId(''); setShowNumbers(false); setAddress('') }, [client, transport])\n useEffect(() => {\n if (connections.status === 'ready' && connections.value.length === 1) setConnectionId(connections.value[0]!.id)\n }, [connections])\n useEffect(() => {\n if (numbers.status === 'ready' && numbers.value.length === 1) setNumberId(numbers.value[0]!.id)\n }, [numbers])\n return <>\n <ChannelState resource={connections} empty=\"No eligible Hub connections. Connect an identity in your app’s Integrations first.\">{items => <form className=\"space-y-4\" onSubmit={event => {\n event.preventDefault()\n if (transport === 'email') void connect.run({ kind: 'email', connectionId, address })\n else if (transport === 'whatsapp') void connect.run({ kind: 'connection', input: { transport, connectionId, phoneNumberId: numberId } })\n else void connect.run({ kind: 'connection', input: { transport, connectionId } })\n }}>\n <label className=\"block\">Connection<select className={inputClass} value={connectionId} disabled={busy} onChange={event => { setConnectionId(event.target.value); setNumberId(''); setShowNumbers(false) }} required>\n <option value=\"\">Choose a connection</option>{items.map(item => <option key={item.id} value={item.id}>{item.account ?? item.displayName}</option>)}\n </select></label>\n {transport === 'email' && <label className=\"block\">Mailbox address<input className={inputClass} type=\"email\" required value={address} disabled={busy} onChange={event => setAddress(event.target.value)} placeholder=\"hello@example.com\" /></label>}\n {transport === 'whatsapp' && <>\n <button type=\"button\" className={buttonClass} disabled={!connectionId || busy} onClick={() => { setShowNumbers(true); numbers.retry() }}>Show owned numbers</button>\n {showNumbers && <ChannelState resource={numbers} empty=\"This connection has no eligible WhatsApp numbers.\">{owned => <label className=\"block\">WhatsApp number<select className={inputClass} required value={numberId} disabled={busy} onChange={event => setNumberId(event.target.value)}>\n <option value=\"\">Choose a number</option>{owned.map(number => <option key={number.id} value={number.id}>{number.address}</option>)}\n </select></label>}</ChannelState>}\n </>}\n <p className=\"text-sm text-muted-foreground\">Connect an owned line, then test both directions. Each person must message first. Permissions remain managed in Tangle Hub.</p>\n <button type=\"submit\" className={primaryButtonClass} disabled={busy || !connectionId || (transport === 'email' && !address.trim()) || (transport === 'whatsapp' && (!numberId || !showNumbers || numbers.status !== 'ready'))}>{busy ? 'Connecting…' : 'Connect channel'}</button>\n </form>}</ChannelState>\n <ChannelFailure state={connect.state} />\n </>\n}\n\nexport interface ChannelConnectProps { transport: LineTransport; initialLineId?: string; className?: string }\n\n/** Select an existing line or connect an owned source, then verify it. */\nexport function ChannelConnect({ transport, initialLineId = '', className = '' }: ChannelConnectProps) {\n const [selected, setSelected] = useState(initialLineId)\n const lines = useChannels()\n const id = useId()\n useEffect(() => setSelected(initialLineId), [transport, initialLineId])\n return <div className={`space-y-4 ${className}`}>\n <section className={panelClass} aria-label={`${labels[transport]} channel`}>\n <h2 className=\"text-lg font-semibold\">Connect {labels[transport]}</h2>\n {transport === 'imessage' && <p>Use a free shared iMessage identity, or acquire a dedicated number. A shared identity requires a connect message to the router first.</p>}\n <ChannelState resource={lines} empty=\"No lines connected to this agent yet.\">{all => {\n const matching = all.filter(line => line.transport === transport && line.status !== 'released')\n return matching.length ? <><label htmlFor={id}>Existing line</label><select id={id} className={inputClass} value={selected} onChange={event => setSelected(event.target.value)}>\n <option value=\"\">Choose or connect a line</option>{matching.map(line => <option value={line.id} key={line.id}>{line.label ?? line.address}</option>)}\n </select></> : <p>No {labels[transport]} lines connected yet.</p>\n }}</ChannelState>\n {!selected && transport !== 'sms' && <ConnectionPicker key={transport} transport={transport} onConnected={line => { setSelected(line.id); lines.retry() }} />}\n {selected && <button type=\"button\" className={buttonClass} onClick={() => setSelected('')}>Choose another line</button>}\n </section>\n {selected ? <ChannelVerificationPanel key={selected} lineId={selected} /> : (transport === 'sms' || transport === 'imessage') && <NumberChannel transport={transport} />}\n </div>\n}\n\ntype TransportPanelProps = Omit<ChannelConnectProps, 'transport'>\nexport function IMessageChannel(props: TransportPanelProps) { return <ChannelConnect {...props} transport=\"imessage\" /> }\nexport function WhatsAppChannel(props: TransportPanelProps) { return <ChannelConnect {...props} transport=\"whatsapp\" /> }\nexport function EmailChannel(props: TransportPanelProps) { return <ChannelConnect {...props} transport=\"email\" /> }\nexport function SMSChannel(props: TransportPanelProps) { return <ChannelConnect {...props} transport=\"sms\" /> }\n\n/** A transport's managed number activation, with explicit consent and cancellation. */\nexport function NumberChannel({ transport, className = '' }: { transport: 'sms' | 'imessage'; className?: string }) {\n const client = useChannelsClient()\n const number = useNumberChannel(transport)\n const [consent, setConsent] = useState(false)\n const [cancelId, setCancelId] = useState<string | null>(null)\n const [lineId, setLineId] = useState('')\n const connect = useConnectChannel(line => setLineId(line.id))\n useEffect(() => { setConsent(false) }, [number.quote?.token])\n useEffect(() => { setCancelId(null); setLineId(''); connect.reset() }, [transport, client, connect.reset])\n const busy = number.state.status === 'pending' || connect.state.status === 'pending'\n const money = (cents: number) => new Intl.NumberFormat('en-US', { style: 'currency', currency: 'USD' }).format(cents / 100)\n return <section className={`${panelClass} ${className}`} aria-label={`${labels[transport]} number`} aria-busy={busy}>\n <h2 className=\"text-lg font-semibold\">Get a {labels[transport]} number</h2>\n {!client.ordering ? <p>Number ordering is unavailable. Existing numbers are unchanged.</p> : <ChannelState resource={number.resource} empty=\"Number availability has not been confirmed.\">{({ readiness, complete }) => <>\n {!readiness.configured && <p>New orders are disabled. Existing numbers still require separate cancellation.</p>}\n {!complete && <p role=\"alert\">The order list is incomplete. New purchases are disabled until ownership can be confirmed.</p>}\n {number.held && <p>This agent already holds an order for this transport. Cancel and release it before ordering another.</p>}\n <button type=\"button\" className={primaryButtonClass} disabled={busy || !complete || !readiness.configured || !readiness.transports.includes(transport) || !!number.held || number.uncertain} onClick={() => void number.run({ action: 'quote' })}>See activation price</button>\n </>}</ChannelState>}\n {number.quote && <div className=\"space-y-3 rounded-md border border-border p-4\">\n <h3 className=\"font-medium\">Activation · {money(number.quote.activationCents)}</h3>\n <p className=\"whitespace-pre-wrap\">{number.quote.terms || 'Published activation terms are missing. Ordering is disabled.'}</p>\n <p>{NUMBER_CHARGE_NOTICE}</p>\n <label className=\"flex items-start gap-2\"><input type=\"checkbox\" checked={consent} disabled={busy} onChange={event => setConsent(event.target.checked)} />I authorize this one-time activation charge. The number is not live until channel setup is complete.</label>\n {!number.uncertain && number.quote.expiresAt <= Date.now() && <p role=\"alert\">This quote expired. Read a new activation price before ordering.</p>}\n <button type=\"button\" className={primaryButtonClass} disabled={busy || !consent || !number.quote.terms.trim() || (!number.uncertain && number.quote.expiresAt <= Date.now())} onClick={() => void number.run({ action: 'purchase', consent })}>{number.uncertain ? 'Retry approved purchase' : `Order for ${money(number.quote.activationCents)}`}</button>\n </div>}\n {number.uncertain && <p role=\"alert\">The purchase response was lost or refused. Its outcome is not confirmed. {NUMBER_RETRY_NOTICE}</p>}\n {number.orders.map(order => <article key={order.id} className=\"space-y-3 rounded-md border border-border p-4\">\n <h3 className=\"break-all font-medium\">{order.address ?? 'Your number order'}</h3><p>{numberStage(order)}</p>\n {order.errorCode && <p role=\"status\">Status: {order.errorCode.replace(/_/g, ' ')}</p>}\n {order.status === 'ready_for_setup' && order.cancellation === 'none' && <><p>The number is acquired, not delivery-verified. Test it before connecting conversations.</p>\n <button type=\"button\" className={buttonClass} disabled={busy} onClick={() => void connect.run({ kind: 'order', orderId: order.id })}>Test this number</button></>}\n <button type=\"button\" className={buttonClass} disabled={busy} onClick={() => void number.run({ action: 'advance', orderId: order.id })}>Check progress</button>{' '}\n {order.cancellation === 'none' && (cancelId !== order.id ? <button type=\"button\" className={buttonClass} disabled={busy} onClick={() => setCancelId(order.id)}>Cancel number</button> : <fieldset className=\"space-y-2\"><legend>Cancel this number? Access will be removed. Paid activation is not automatically refunded.</legend>\n <button type=\"button\" className={buttonClass} disabled={busy} onClick={async () => { const result = await number.run({ action: 'cancel', orderId: order.id, confirm: true }); if (result.succeeded) setCancelId(null) }}>Confirm cancellation</button>{' '}\n <button type=\"button\" className={buttonClass} disabled={busy} onClick={() => setCancelId(null)}>Keep number</button>\n </fieldset>)}\n </article>)}\n <button type=\"button\" className={buttonClass} disabled={busy} onClick={number.resource.retry}>Refresh number status</button>\n <p className=\"text-sm text-muted-foreground\">SMS and iMessage are separate activations. Buying a number does not enable WhatsApp.</p>\n <ChannelFailure state={number.state} /><ChannelFailure state={connect.state} />\n {lineId && <ChannelVerificationPanel lineId={lineId} key={lineId} />}\n </section>\n}\n\n/** Read-only history. Messages stay on their original channel; no synthetic composer. */\nexport function ChannelConversation({ lineId, threadId, className = '' }: { lineId: string; threadId: string; className?: string }) {\n const messages = useChannelConversation(lineId, threadId)\n return <section className={`${panelClass} ${className}`} aria-label=\"Channel conversation\">\n <h3 className=\"font-semibold\">Conversation</h3>\n <ChannelState resource={messages} empty=\"No messages in this conversation yet.\">{items => <ol role=\"log\" aria-live=\"polite\" aria-label=\"Messages\" className=\"space-y-3\">\n {items.map(message => <li key={message.id} className=\"space-y-1 rounded-md bg-muted p-3\" data-direction={message.direction}>\n <p className=\"text-xs text-muted-foreground\">{message.direction === 'in' ? 'Incoming' : 'Outgoing'} · {message.kind} · <time dateTime={message.createdAt}>{message.createdAt}</time></p>\n <p className=\"whitespace-pre-wrap break-words\">{message.text ?? 'Non-text message'}</p>\n <p className=\"text-xs\">{message.status}{message.errorCode ? ` · ${message.errorCode}` : ''}</p>\n </li>)}\n </ol>}</ChannelState>\n <button type=\"button\" className={buttonClass} onClick={messages.retry}>Refresh messages</button>\n </section>\n}\n\n/** A channel's separate member threads. Changing line never reuses another line's selection. */\nexport function ChannelConversations({ lineId, className = '' }: { lineId: string; className?: string }) {\n const threads = useChannelConversations(lineId)\n const [selected, setSelected] = useState<{ lineId: string; threadId: string } | null>(null)\n const threadId = selected?.lineId === lineId ? selected.threadId : ''\n return <div className={`space-y-4 ${className}`}>\n <section className={panelClass} aria-label=\"Channel conversations\"><h2 className=\"text-lg font-semibold\">Conversations</h2>\n <ChannelState resource={threads} empty=\"No conversations yet. Members must message the line first.\">{items => <nav aria-label=\"Choose a conversation\" className=\"flex flex-wrap gap-2\">\n {items.map(thread => <button type=\"button\" key={thread.id} className={buttonClass} aria-pressed={thread.id === threadId} onClick={() => setSelected({ lineId, threadId: thread.id })}>{thread.memberId} · {thread.status}</button>)}\n </nav>}</ChannelState>\n </section>\n {threadId && <ChannelConversation key={`${lineId}:${threadId}`} lineId={lineId} threadId={threadId} />}\n </div>\n}\n","import { useEffect, useRef, useState } from 'react'\nimport type { HubNumberOrder, HubNumberQuote } from '@tangle-network/hub-sdk'\nimport { useChannelsContext } from './context'\nimport { useChannelMutation, useChannelResource } from './hooks'\n\nexport const NUMBER_CHARGE_NOTICE = 'This is a one-time activation charge. Tangle does not bill recurring carrier rental for this number. Your provider’s message rates are separate.'\nexport const NUMBER_RETRY_NOTICE = 'Retry uses the same approved quote, not a new purchase. Do not order again while the result is unknown.'\n\nexport function holdsNumber(order: HubNumberOrder): boolean {\n return order.cancellation !== 'released' && order.cancellation !== 'abandoned'\n}\n\nexport function numberStage(order: HubNumberOrder): string {\n if (order.cancellation === 'released' || order.cancellation === 'abandoned') return 'Released'\n if (order.cancellation === 'needs_review') return 'Release needs review'\n if (order.cancellation === 'requested' || order.status === 'cancelled') return 'Cancelling'\n if (order.status === 'needs_review') return 'Needs operator review'\n if (order.status === 'ready_for_setup') return 'Number acquired — channel setup next'\n if (order.errorCode === 'funding_required') return 'Add funds to continue'\n if (order.errorCode === 'sms_not_ready') return 'Waiting for SMS activation'\n return 'Provisioning'\n}\n\n/** Hub owns prices, terms, idempotency, funding, and cancellation. */\nexport function useNumberChannel(transport: 'sms' | 'imessage') {\n const { client } = useChannelsContext()\n const ordering = client.ordering\n const reference = ordering?.references[transport]\n const [quote, setQuote] = useState<HubNumberQuote | null>(null)\n const [receipts, setReceipts] = useState<HubNumberOrder[]>([])\n const [uncertain, setUncertain] = useState(false)\n // Set synchronously at dispatch, before React renders another click.\n const attempted = useRef(false)\n const resource = useChannelResource(async ({ signal }) => {\n if (!ordering || !reference) throw new Error('Number ordering is unavailable.')\n const readiness = await ordering.numbers.readiness()\n const orders: HubNumberOrder[] = []\n const seen = new Set<string>()\n let cursor: string | undefined\n let complete = false\n do {\n if (signal.aborted) throw new Error('Number read was superseded.')\n const page = await ordering.numbers.list({ clientReference: reference, cursor, limit: 100 })\n if (page.orders.some(order => order.clientReference !== reference || order.transport !== transport)) throw new Error('The number list belongs to another binding.')\n orders.push(...page.orders)\n if (page.nextCursor == null) {\n // Older Hub responses omit cursor metadata. An incomplete page cannot\n // establish that this agent has no order, even when the page is empty.\n complete = page.nextCursor === null\n break\n }\n if (seen.has(page.nextCursor) || seen.size >= 100) throw new Error('The number list could not be read completely.')\n seen.add(page.nextCursor)\n cursor = page.nextCursor\n } while (cursor)\n return { readiness, orders, complete }\n }, [ordering, reference, transport], !!ordering)\n const loaded = resource.status === 'ready' ? resource.value : null\n const orders = [...new Map([...(loaded?.orders ?? []), ...receipts].map(order => [order.id, order])).values()]\n const held = orders.find(holdsNumber) ?? null\n\n const mutation = useChannelMutation<\n | { action: 'quote' }\n | { action: 'purchase'; consent: boolean }\n | { action: 'advance'; orderId: string }\n | { action: 'cancel'; orderId: string; confirm: boolean }, void\n >(async (input, { signal }) => {\n if (!ordering || !reference) throw new Error('Number ordering is unavailable.')\n if (input.action === 'quote') {\n if (attempted.current) throw new Error('The previous purchase is unresolved. Retry its approved quote or check progress.')\n if (!loaded?.complete || !loaded.readiness.configured || !loaded.readiness.transports.includes(transport)) throw new Error('Number availability and existing orders must be confirmed first.')\n if (held) throw new Error('This agent already holds a number order for this transport.')\n const { quote: next } = await ordering.numbers.quote({ transport, clientReference: reference })\n if (next.transport !== transport || (next.clientReference !== undefined && next.clientReference !== reference)) throw new Error('The quote belongs to another binding.')\n if (!signal.aborted) setQuote(next)\n return\n }\n if (input.action === 'purchase') {\n if (!quote || !input.consent) throw new Error('Approve the quoted activation charge before ordering.')\n if (!quote.terms.trim() || !Number.isSafeInteger(quote.activationCents) || quote.activationCents < 0 || !quote.token) throw new Error('A valid price and published activation terms are required.')\n if (held) throw new Error('This agent already holds a number order for this transport.')\n if (!attempted.current && (!loaded?.complete || !loaded.readiness.configured || quote.expiresAt <= Date.now())) throw new Error('The quote or order information expired. Read the current state first.')\n attempted.current = true\n try {\n const { order } = await ordering.numbers.create({ quoteToken: quote.token, consent: true, clientReference: reference, transport })\n if (order.clientReference !== reference || order.transport !== transport) throw new Error('The purchase response belongs to another binding. Check progress before ordering again.')\n if (!signal.aborted) {\n // Preserve the acknowledged order before a follow-up read can fail.\n setReceipts(current => [order, ...current.filter(item => item.id !== order.id)])\n setQuote(null)\n setUncertain(false)\n }\n } catch (error) {\n if (!signal.aborted) setUncertain(true)\n throw error\n } finally {\n if (!signal.aborted) resource.retry()\n }\n return\n }\n if (!orders.some(order => order.id === input.orderId)) throw new Error('Read this number order before changing it.')\n if (input.action === 'cancel' && !input.confirm) throw new Error('Confirm cancelling this number.')\n const { order } = await ordering.numbers[input.action](input.orderId)\n if (order.id !== input.orderId || order.clientReference !== reference || order.transport !== transport) throw new Error('The number response belongs to another binding.')\n if (!signal.aborted) {\n setReceipts(current => [order, ...current.filter(item => item.id !== order.id)])\n resource.retry()\n }\n })\n useEffect(() => {\n setQuote(null); setReceipts([]); setUncertain(false); attempted.current = false\n mutation.reset()\n }, [client, client.scope, transport, reference, mutation.reset])\n useEffect(() => {\n if (loaded) setReceipts(current => current.filter(receipt => !loaded.orders.some(order => order.id === receipt.id)))\n if (loaded?.orders.some(holdsNumber)) {\n setQuote(null); setUncertain(false); attempted.current = false\n } else if (!uncertain && !quote && loaded?.complete && orders.length > 0 && orders.every(order => !holdsNumber(order))) {\n attempted.current = false\n }\n }, [loaded])\n return { resource, orders, held, quote, uncertain, ...mutation }\n}\n","import type { ReactNode } from 'react'\nimport { AsyncView, MutationStatus, type AsyncResourceState, type MutationState } from '../web-react/async'\n\nexport const panelClass = 'space-y-4 rounded-xl border border-border bg-card p-6 text-foreground'\nexport const buttonClass = 'inline-flex items-center justify-center rounded-md border border-border px-3 py-2 text-sm font-medium transition hover:bg-accent focus-visible:outline focus-visible:outline-2 focus-visible:outline-ring focus-visible:outline-offset-2 disabled:cursor-not-allowed disabled:opacity-50'\nexport const primaryButtonClass = `${buttonClass} border-primary bg-primary text-primary-foreground hover:bg-primary/90`\nexport const inputClass = 'block w-full rounded-md border border-input bg-background px-3 py-2 text-foreground focus-visible:outline focus-visible:outline-2 focus-visible:outline-ring'\n\nexport function ChannelFailure({ state }: { state: MutationState<unknown> }) {\n return state.status === 'failed' ? <MutationStatus state={state} className=\"text-sm text-destructive\" /> : null\n}\n\n/** Channel copy around the shared async view, not a second state renderer. */\nexport function ChannelState<T>({ resource, children, empty }: { resource: AsyncResourceState<T>; children: (value: T) => ReactNode; empty: string }) {\n return <AsyncView state={resource} empty={{ title: empty, action: { label: 'Refresh', onClick: resource.retry } }}\n loadingLabel=\"Loading channel…\" retryLabel=\"Try again\"\n renderIdle={() => <p className=\"text-sm text-muted-foreground\">Choose a channel to continue.</p>}>\n {children}\n </AsyncView>\n}\n","import { useEffect, useState } from 'react'\nimport { useChannelsContext } from './context'\nimport { useChannelMutation, useChannelResource } from './hooks'\nimport { ChannelState, ChannelFailure, buttonClass, primaryButtonClass, panelClass } from './ui'\n\n/** Only same-origin relative paths or credential-free HTTPS checkout URLs. */\nexport function safeCheckoutUrl(value: string): string {\n if (/^\\/(?!\\/)/.test(value) && !/[\\\\\\s]/.test(value)) return value\n const url = new URL(value)\n if (url.protocol !== 'https:' || url.username || url.password) throw new Error('Checkout returned an unsafe URL.')\n return url.href\n}\n\nexport function useLinePayment(lineId: string) {\n const { client } = useChannelsContext()\n const resource = useChannelResource(context => {\n if (!client.payment) throw new Error('Payments are unavailable for this line.')\n return client.payment.read(lineId, context)\n }, [lineId], !!lineId && !!client.payment)\n const mutation = useChannelMutation<{ consent: boolean }, string>(async ({ consent }) => {\n if (!client.payment || resource.status !== 'ready') throw new Error('Read the current allowance before checkout.')\n const { plan, allowance, terms } = resource.value\n if (!consent || !terms.trim()) throw new Error('Accept the published terms before checkout.')\n if (!plan.configured || !plan.paid || !Number.isFinite(plan.paid.priceUsdMonthly) || plan.paid.priceUsdMonthly <= 0 || allowance.decision !== 'paywall' || !allowance.paywall || allowance.tier !== 'free') throw new Error('Checkout is not available for this allowance.')\n return safeCheckoutUrl((await client.payment.checkout(lineId)).url)\n })\n useEffect(() => mutation.reset(), [lineId, mutation.reset])\n return { resource, ...mutation, available: !!client.payment }\n}\n\n/** End-user allowance/checkout page, not number acquisition or creator payouts. */\nexport function LinePayPage({ lineId, className = '' }: { lineId: string; className?: string }) {\n const payment = useLinePayment(lineId)\n const [consentedTerms, setConsentedTerms] = useState<string | null>(null)\n const currentTerms = payment.resource.status === 'ready'\n ? JSON.stringify([lineId, payment.resource.value.terms, payment.resource.value.plan.paid])\n : null\n const consent = currentTerms !== null && consentedTerms === currentTerms\n return <section className={`${panelClass} ${className}`} aria-label=\"Line subscription\">\n <h2 className=\"text-lg font-semibold\">Your line plan</h2>\n {!payment.available ? <p>Payments are unavailable for this line.</p> : <ChannelState resource={payment.resource} empty=\"No plan is available.\">{value => <>\n <h3 className=\"font-medium\">{value.label}</h3>\n <p>{value.allowance.turns.used} of {value.allowance.turns.limit} turns used today.</p>\n {value.allowance.tier === 'paid' ? <p role=\"status\">Your paid allowance is active.{value.allowance.decision === 'allowance_reached' ? ' Its current limit is exhausted; another checkout cannot lift it.' : ''}</p> : value.allowance.decision === 'paywall' && value.plan.paid ? <>\n <p>{new Intl.NumberFormat('en-US', { style: 'currency', currency: 'USD' }).format(value.plan.paid.priceUsdMonthly)} per month · {value.plan.paid.turnsPerDay} turns per day.</p>\n <p className=\"whitespace-pre-wrap\">{value.terms || 'Plan terms are unavailable. Checkout is disabled.'}</p>\n <label className=\"flex items-start gap-2\"><input type=\"checkbox\" checked={consent} onChange={event => setConsentedTerms(event.target.checked ? currentTerms : null)} />I accept these subscription terms.</label>\n <button type=\"button\" className={primaryButtonClass} disabled={!consent || !value.terms.trim() || payment.state.status === 'pending'} onClick={() => void payment.run({ consent })}>Continue to checkout</button>\n <p className=\"text-sm text-muted-foreground\">Payment is confirmed by the server after settlement, not by returning to this page.</p>\n </> : <p>{value.allowance.decision === 'allowance_reached' ? 'Your allowance is exhausted. Paying does not lift this limit today.' : 'Your current allowance is available.'} Resets at {value.allowance.resetsAt}.</p>}\n <button type=\"button\" className={buttonClass} onClick={payment.resource.retry}>Check payment status</button>\n </>}</ChannelState>}\n {payment.state.status === 'succeeded' && consent && <a className=\"underline\" href={payment.state.value} rel=\"noopener noreferrer\">Open secure checkout</a>}\n <ChannelFailure state={payment.state} />\n </section>\n}\n"],"mappings":"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","names":["useEffect","useState","useEffect","useRef","useRef","orders","order","useEffect","jsx","jsx","useState","useEffect","useEffect","useState","Fragment","jsx","jsxs","useEffect","useState"]}
@@ -0,0 +1,32 @@
1
+ import type { HubNumberOrder, HubNumberQuote } from '@tangle-network/hub-sdk';
2
+ export declare const NUMBER_CHARGE_NOTICE = "This is a one-time activation charge. Tangle does not bill recurring carrier rental for this number. Your provider\u2019s message rates are separate.";
3
+ export declare const NUMBER_RETRY_NOTICE = "Retry uses the same approved quote, not a new purchase. Do not order again while the result is unknown.";
4
+ export declare function holdsNumber(order: HubNumberOrder): boolean;
5
+ export declare function numberStage(order: HubNumberOrder): string;
6
+ /** Hub owns prices, terms, idempotency, funding, and cancellation. */
7
+ export declare function useNumberChannel(transport: 'sms' | 'imessage'): {
8
+ state: import("../web-react/async").MutationState<void>;
9
+ reset: () => void;
10
+ run: (input: {
11
+ action: 'quote';
12
+ } | {
13
+ action: 'purchase';
14
+ consent: boolean;
15
+ } | {
16
+ action: 'advance';
17
+ orderId: string;
18
+ } | {
19
+ action: 'cancel';
20
+ orderId: string;
21
+ confirm: boolean;
22
+ }) => Promise<import("../web-react/async").MutationOutcome<void>>;
23
+ resource: import("../web-react/async").AsyncResourceState<{
24
+ readiness: import("@tangle-network/hub-sdk").HubNumberReadiness;
25
+ orders: HubNumberOrder[];
26
+ complete: boolean;
27
+ }>;
28
+ orders: HubNumberOrder[];
29
+ held: HubNumberOrder | null;
30
+ quote: HubNumberQuote | null;
31
+ uncertain: boolean;
32
+ };
@@ -0,0 +1,16 @@
1
+ /** Only same-origin relative paths or credential-free HTTPS checkout URLs. */
2
+ export declare function safeCheckoutUrl(value: string): string;
3
+ export declare function useLinePayment(lineId: string): {
4
+ state: import("../web-react/async").MutationState<string>;
5
+ reset: () => void;
6
+ run: (input: {
7
+ consent: boolean;
8
+ }) => Promise<import("../web-react/async").MutationOutcome<string>>;
9
+ resource: import("../web-react/async").AsyncResourceState<import("./types").LinePayment>;
10
+ available: boolean;
11
+ };
12
+ /** End-user allowance/checkout page, not number acquisition or creator payouts. */
13
+ export declare function LinePayPage({ lineId, className }: {
14
+ lineId: string;
15
+ className?: string;
16
+ }): import("react").JSX.Element;
@@ -0,0 +1,96 @@
1
+ import type { Line, LineFromConnectionInput, LinesClient, LineTransport } from '@tangle-network/sandbox';
2
+ import type { HubAllowanceDecision, HubAllowancePlan, HubManagedNumbersClient } from '@tangle-network/hub-sdk';
3
+ export type { Line, LineAttachment, LineFromConnectionInput, LineMessage, LineThread, LineTransport } from '@tangle-network/sandbox';
4
+ export type { HubNumberOrder, HubNumberQuote, HubNumberReadiness } from '@tangle-network/hub-sdk';
5
+ /** Public evidence only. The host never returns a confirmation secret or sender identity. */
6
+ export interface ChannelVerification {
7
+ id: string;
8
+ lineId: string;
9
+ status: 'configuring' | 'waiting' | 'received' | 'sending' | 'uncertain' | 'sent' | 'verified' | 'revoked' | 'needs_review';
10
+ instruction: string;
11
+ expiresAt: number;
12
+ expired: boolean;
13
+ error: string | null;
14
+ }
15
+ export interface ChannelConnection {
16
+ id: string;
17
+ displayName: string;
18
+ account: string | null;
19
+ }
20
+ export interface ChannelNumber {
21
+ id: string;
22
+ address: string;
23
+ }
24
+ export interface ChannelReadContext {
25
+ signal: AbortSignal;
26
+ }
27
+ export interface LinePayment {
28
+ label: string;
29
+ plan: HubAllowancePlan;
30
+ allowance: HubAllowanceDecision;
31
+ /** Published terms, required before checkout is offered. */
32
+ terms: string;
33
+ }
34
+ export type ConnectChannelInput = {
35
+ kind: 'connection';
36
+ input: LineFromConnectionInput;
37
+ } | {
38
+ kind: 'email';
39
+ connectionId: string;
40
+ address: string;
41
+ } | {
42
+ kind: 'order';
43
+ orderId: string;
44
+ };
45
+ /**
46
+ * The one authenticated, agent-scoped boundary. Keep this object stable.
47
+ *
48
+ * `lines` delegates to Sandbox SDK client.lines (list MUST be scoped to this
49
+ * agent). `setup` is the host's existing Hub/hosted-agent control plane: it
50
+ * verifies ownership and delivery before sandbox.lines.attach, and never runs
51
+ * provider HTTP calls in the browser. No execution, webhook, credential,
52
+ * consent, or billing authority is implemented by this React subpath.
53
+ *
54
+ * Sandbox 0.51+ supplies fromConnection/get/threads; it does not supply email
55
+ * creation, managed-order binding, or delivery verification. Those operations
56
+ * deliberately remain injected instead of pretending they exist on the SDK.
57
+ * The hosted-agent export is server-only. Its existing attachLine operation
58
+ * belongs in setup.activate after proof validation, never in this browser bundle.
59
+ */
60
+ export interface ChannelsClient {
61
+ /** Changes whenever the authenticated agent or owner changes. Not an auth credential. */
62
+ scope: string;
63
+ lines: Pick<LinesClient, 'fromConnection' | 'get' | 'threads'> & {
64
+ list(): Promise<Line[]>;
65
+ };
66
+ setup: {
67
+ connections(transport: LineTransport, context: ChannelReadContext): Promise<ChannelConnection[]>;
68
+ whatsappNumbers(connectionId: string, context: ChannelReadContext): Promise<ChannelNumber[]>;
69
+ fromEmail(input: {
70
+ connectionId: string;
71
+ address: string;
72
+ }): Promise<Line>;
73
+ fromOrder(orderId: string): Promise<Line>;
74
+ verification(lineId: string, context: ChannelReadContext): Promise<ChannelVerification | null>;
75
+ start(lineId: string): Promise<ChannelVerification>;
76
+ resume(lineId: string, testId: string): Promise<ChannelVerification>;
77
+ send(lineId: string, testId: string): Promise<ChannelVerification>;
78
+ reset(lineId: string, testId: string): Promise<void>;
79
+ /** Recheck proof and ownership server-side; attach through sandbox.lines. */
80
+ activate(lineId: string, testId: string): Promise<Line>;
81
+ };
82
+ /** Optional owner-only number ordering, delegated to hub.numbers. */
83
+ ordering?: {
84
+ numbers: Pick<HubManagedNumbersClient, 'readiness' | 'list' | 'quote' | 'create' | 'advance' | 'cancel'>;
85
+ references: Record<'sms' | 'imessage', string>;
86
+ };
87
+ /** Optional member pay page. The host derives member/meter from authentication. */
88
+ payment?: {
89
+ /** Read Hub allowance plan/status, never admit a turn or grant a paid tier. */
90
+ read(lineId: string, context: ChannelReadContext): Promise<LinePayment>;
91
+ /** Host-owned checkout; only a payment settlement may grant Hub allowance. */
92
+ checkout(lineId: string): Promise<{
93
+ url: string;
94
+ }>;
95
+ };
96
+ }
@@ -0,0 +1,15 @@
1
+ import type { ReactNode } from 'react';
2
+ import { type AsyncResourceState, type MutationState } from '../web-react/async';
3
+ export declare const panelClass = "space-y-4 rounded-xl border border-border bg-card p-6 text-foreground";
4
+ export declare const buttonClass = "inline-flex items-center justify-center rounded-md border border-border px-3 py-2 text-sm font-medium transition hover:bg-accent focus-visible:outline focus-visible:outline-2 focus-visible:outline-ring focus-visible:outline-offset-2 disabled:cursor-not-allowed disabled:opacity-50";
5
+ export declare const primaryButtonClass = "inline-flex items-center justify-center rounded-md border border-border px-3 py-2 text-sm font-medium transition hover:bg-accent focus-visible:outline focus-visible:outline-2 focus-visible:outline-ring focus-visible:outline-offset-2 disabled:cursor-not-allowed disabled:opacity-50 border-primary bg-primary text-primary-foreground hover:bg-primary/90";
6
+ export declare const inputClass = "block w-full rounded-md border border-input bg-background px-3 py-2 text-foreground focus-visible:outline focus-visible:outline-2 focus-visible:outline-ring";
7
+ export declare function ChannelFailure({ state }: {
8
+ state: MutationState<unknown>;
9
+ }): import("react").JSX.Element | null;
10
+ /** Channel copy around the shared async view, not a second state renderer. */
11
+ export declare function ChannelState<T>({ resource, children, empty }: {
12
+ resource: AsyncResourceState<T>;
13
+ children: (value: T) => ReactNode;
14
+ empty: string;
15
+ }): import("react").JSX.Element;
@@ -11,4 +11,4 @@ export {
11
11
  DesignCanvasLazy,
12
12
  DesignCanvasChromeLazy
13
13
  };
14
- //# sourceMappingURL=chunk-WAMJSZYB.js.map
14
+ //# sourceMappingURL=chunk-4S36HWE4.js.map
@@ -4,9 +4,6 @@ import {
4
4
  charAt,
5
5
  charBefore
6
6
  } from "./chunk-3HUFJ5LO.js";
7
- import {
8
- AsyncView
9
- } from "./chunk-3UBAO3N5.js";
10
7
  import {
11
8
  stepActivityFlowTrace
12
9
  } from "./chunk-FBVLEGEG.js";
@@ -31,6 +28,9 @@ import {
31
28
  filterCommandPaletteItems,
32
29
  groupCommandPaletteItems
33
30
  } from "./chunk-SJWIZT7B.js";
31
+ import {
32
+ AsyncView
33
+ } from "./chunk-3UBAO3N5.js";
34
34
  import {
35
35
  attachmentPartsFromMessageParts
36
36
  } from "./chunk-4PZE7XAM.js";
@@ -6167,4 +6167,4 @@ export {
6167
6167
  useThinkingSeconds,
6168
6168
  ChatMessages
6169
6169
  };
6170
- //# sourceMappingURL=chunk-WHHMYVDB.js.map
6170
+ //# sourceMappingURL=chunk-VIL6MHHQ.js.map
@@ -43,10 +43,6 @@ import {
43
43
  selectTickStep
44
44
  } from "../chunk-KWN5PGXM.js";
45
45
  import "../chunk-Q2QKEV6J.js";
46
- import {
47
- DesignCanvasChromeLazy,
48
- DesignCanvasLazy
49
- } from "../chunk-WAMJSZYB.js";
50
46
  import "../chunk-ZN5J47UX.js";
51
47
  import {
52
48
  DEFAULT_INSERT_TEMPLATES,
@@ -89,6 +85,10 @@ import {
89
85
  setPagePropsCommand,
90
86
  ungroupElementCommand
91
87
  } from "../chunk-FEVVF6JJ.js";
88
+ import {
89
+ DesignCanvasChromeLazy,
90
+ DesignCanvasLazy
91
+ } from "../chunk-4S36HWE4.js";
92
92
  import {
93
93
  assertSceneMediaSrc,
94
94
  bleedAwareExportBounds,
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  DesignCanvasChromeLazy,
3
3
  DesignCanvasLazy
4
- } from "../chunk-WAMJSZYB.js";
4
+ } from "../chunk-4S36HWE4.js";
5
5
  export {
6
6
  DesignCanvasChromeLazy,
7
7
  DesignCanvasLazy
@@ -0,0 +1,18 @@
1
+ import type { ChannelsClient, ChannelVerification, Line, LineAttachment, LineMessage, LineThread, HubNumberOrder, LinePayment } from '../../channels/types';
2
+ export declare function channelLine(overrides?: Partial<Line>): Line;
3
+ export declare function channelAttachment(): LineAttachment;
4
+ export declare function channelTest(status?: ChannelVerification['status']): ChannelVerification;
5
+ export declare function channelMessage(id?: string, overrides?: Partial<LineMessage>): LineMessage;
6
+ export declare function numberOrder(overrides?: Partial<HubNumberOrder>): HubNumberOrder;
7
+ /** Deterministic, in-memory SDK-shaped fixture. Never connects to a provider. */
8
+ export declare function createChannelsFixture(): {
9
+ client: ChannelsClient;
10
+ state: {
11
+ line: Line;
12
+ test: ChannelVerification | null;
13
+ messages: LineMessage[];
14
+ orders: HubNumberOrder[];
15
+ payment: LinePayment;
16
+ };
17
+ thread: LineThread;
18
+ };
@@ -128,7 +128,7 @@ import {
128
128
  withoutRecordGridCreated,
129
129
  withoutRecordGridRemoved,
130
130
  withoutRecordGridUpdate
131
- } from "../chunk-WHHMYVDB.js";
131
+ } from "../chunk-VIL6MHHQ.js";
132
132
  import {
133
133
  SessionHistoryPanel,
134
134
  formatSessionTimestamp,
@@ -139,7 +139,10 @@ import {
139
139
  import {
140
140
  MENTION_PILL_CLASS
141
141
  } from "../chunk-3HUFJ5LO.js";
142
- import "../chunk-3UBAO3N5.js";
142
+ import {
143
+ tabTerminalConnectionId,
144
+ useSandboxTerminalConnection
145
+ } from "../chunk-BATKJP3P.js";
143
146
  import "../chunk-FBVLEGEG.js";
144
147
  import {
145
148
  EvidenceLineageTable,
@@ -191,10 +194,7 @@ import {
191
194
  usePopover
192
195
  } from "../chunk-4I76LTZS.js";
193
196
  import "../chunk-SJWIZT7B.js";
194
- import {
195
- tabTerminalConnectionId,
196
- useSandboxTerminalConnection
197
- } from "../chunk-BATKJP3P.js";
197
+ import "../chunk-3UBAO3N5.js";
198
198
  import "../chunk-FQYAJYPW.js";
199
199
  import {
200
200
  ATTACHMENT_ACCEPT
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tangle-network/agent-app",
3
- "version": "0.49.23",
3
+ "version": "0.49.25",
4
4
  "packageManager": "pnpm@11.24.0",
5
5
  "description": "Build agent applications with typed chat, tools, sandboxes, integrations, billing, and evaluation.",
6
6
  "keywords": [
@@ -212,6 +212,11 @@
212
212
  "import": "./dist/integrations/index.js",
213
213
  "default": "./dist/integrations/index.js"
214
214
  },
215
+ "./channels": {
216
+ "types": "./dist/channels/index.d.ts",
217
+ "import": "./dist/channels/index.js",
218
+ "default": "./dist/channels/index.js"
219
+ },
215
220
  "./hosted-agent": {
216
221
  "types": "./dist/hosted-agent/index.d.ts",
217
222
  "import": "./dist/hosted-agent/index.js",
@@ -546,8 +551,9 @@
546
551
  "@tangle-network/agent-interface": "2.12.0",
547
552
  "@tangle-network/agent-knowledge": "17.1.5",
548
553
  "@tangle-network/agent-profile-materialize": "0.20.1",
549
- "@tangle-network/agent-runtime": "0.273.5",
554
+ "@tangle-network/agent-runtime": "0.274.0",
550
555
  "@tangle-network/brand": "1.5.0",
556
+ "@tangle-network/hub-sdk": "0.19.0",
551
557
  "@tangle-network/sandbox": "0.53.0",
552
558
  "@tangle-network/sandbox-ui": "0.113.3",
553
559
  "@tangle-network/ui": "11.9.0",
@@ -606,8 +612,9 @@
606
612
  "@tangle-network/agent-interface": "^2.11.0",
607
613
  "@tangle-network/agent-knowledge": "^17.1.2",
608
614
  "@tangle-network/agent-profile-materialize": ">=0.20.1 <0.21.0",
609
- "@tangle-network/agent-runtime": ">=0.262.0 <0.274.0",
615
+ "@tangle-network/agent-runtime": ">=0.262.0 <0.275.0",
610
616
  "@tangle-network/brand": ">=1.5.0",
617
+ "@tangle-network/hub-sdk": ">=0.19.0 <0.20.0",
611
618
  "@tangle-network/sandbox": ">=0.45.0 <0.48.0 || ^0.49.0 || ^0.50.0 || ^0.51.0 || ^0.52.0 || ^0.53.0",
612
619
  "@tangle-network/sandbox-ui": ">=0.113.3 <0.114.0",
613
620
  "@tangle-network/ui": ">=11.6.0 <12.0.0",
@@ -707,6 +714,9 @@
707
714
  },
708
715
  "react-dom": {
709
716
  "optional": true
717
+ },
718
+ "@tangle-network/hub-sdk": {
719
+ "optional": true
710
720
  }
711
721
  },
712
722
  "dependencies": {