import { BrowserOAuthClient } from '@atproto/oauth-client-browser' import { Agent } from '@atproto/api' import './agents-launch.js' import './agents-list.js' import { AgentsCubit, SCOPE } from './agents-cubit.js' import { pageClientId } from 'atlibs/oauth/index.js' // Wiring only: user events go to the cubit, cubit state goes to the views. One OAuth session, whose // only scope is minting service auth for the agents service's three methods. // pageClientId: the loopback client on localhost, ./stage.json's clientId when deployed. const client = pageClientId(SCOPE).then((clientId) => BrowserOAuthClient.load({ clientId, handleResolver: 'https://bsky.social' })); const service = new URLSearchParams(location.search).get('service') ?? undefined; const agents = new AgentsCubit({ client, makeAgent: (session) => new Agent(session), service }); globalThis.agentsCubit = agents; const show = (id, on) => (document.getElementById(id).style.display = on ? "block" : "none"); async function init() { const names = ["agents-launch", "agents-list"]; await Promise.all(names.map((name) => customElements.whenDefined(name))); const views = names.map((name) => document.querySelector(name)); const on = (type, fn) => document.addEventListener(type, (e) => fn(e.detail ?? {})); on("login", ({ username }) => agents.login(username)); on("set-service", ({ service }) => agents.setService(service).catch((error) => alert(error.message))); on("launch", (input) => agents.launch(input)); on("refresh", () => agents.refresh()); on("status", ({ rkey }) => agents.status(rkey)); on("shutdown", ({ rkey, delete: remove }) => agents.shutdown(rkey, remove)); document.getElementById("logout-nav").onclick = (e) => { e.preventDefault(); agents.logout(); }; let previous; const render = () => { const state = agents.state; show("loading", state.session === "loading"); show("loading-error", state.session === "error"); document.getElementById("loading-error").innerText = state.error ?? ""; show("logout-nav", state.session === "signed-in"); document.getElementById("whoami").innerText = state.did ? `${state.handle ?? ""} ${state.did}` : ""; for (const view of views) view.render(state, previous); previous = state; }; agents.subscribe(render); await agents.init(); } init();