pocolobby 0.12.2 → 0.14.0

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.
package/dist/cli.js CHANGED
@@ -1,10 +1,10 @@
1
1
  #!/usr/bin/env node
2
- var V=Object.defineProperty;var y=(m,i)=>V(m,"name",{value:i,configurable:!0});import{execFileSync as Z,spawn as Q}from"node:child_process";import{randomBytes as ee,randomUUID as oe}from"node:crypto";import{appendFileSync as te,mkdirSync as ne,readFileSync as re,realpathSync as k}from"node:fs";import{lstat as se,open as ae,readFile as R,stat as D,unlink as ie,writeFile as ce}from"node:fs/promises";import{homedir as le}from"node:os";import{dirname as x,isAbsolute as H,relative as de,resolve as B,sep as me}from"node:path";import{fileURLToPath as j,pathToFileURL as pe}from"node:url";import{parseArgs as ue}from"node:util";import{ZodError as be}from"zod";import{loadConfig as G,readConfig as fe,reserveConfig as he,setConfigUrl as ge,validateConfig as q,writeConfigExclusive as we}from"./config.js";import{BoardAgentsSchema as ye,BoardSourceSchema as Oe,RepoName as F}from"./board-model.js";import{LobbyClient as K,LobbyClientError as Ee}from"./client.js";import{postmarkMailer as _e}from"./mail.js";import{commandOnPath as Te,launchScript as Ae,packageRoot as U,pocolobbyVersion as $,stableLaunchPaths as Se}from"./launch.js";import{unsupportedNodeMessage as Be}from"./node-version.js";import{AgentId as I,CancelScheduledSchema as ve,Email as X,MIN_PUSH_BYTES as Ne,MAX_PUSH_BYTES as Pe,LobbyId as Y,NewLobbyId as Ie,ProvisionSchema as Ce,UpdateAgentSchema as Le,RoomId as C,RoomMembersSchema as Me,RoomMemberChangesSchema as ke,SendSchema as Re}from"./protocol.js";const z=y(m=>m.split(",").map(i=>i.trim()).filter(Boolean),"listOf"),J=`PocoLobby \u2014 a little place for agents to meet.
2
+ var V=Object.defineProperty;var y=(m,i)=>V(m,"name",{value:i,configurable:!0});import{execFileSync as Z,spawn as Q}from"node:child_process";import{randomBytes as ee,randomUUID as oe}from"node:crypto";import{appendFileSync as te,mkdirSync as ne,readFileSync as re,realpathSync as M}from"node:fs";import{lstat as se,open as ae,readFile as R,stat as D,unlink as ie,writeFile as ce}from"node:fs/promises";import{homedir as de}from"node:os";import{dirname as x,isAbsolute as H,relative as le,resolve as B,sep as me}from"node:path";import{fileURLToPath as j,pathToFileURL as ue}from"node:url";import{parseArgs as pe}from"node:util";import{ZodError as be}from"zod";import{loadConfig as G,readConfig as fe,reserveConfig as he,setConfigUrl as ge,validateConfig as q,writeConfigExclusive as we}from"./config.js";import{BoardAgentsSchema as ye,BoardSourceSchema as Oe,RepoName as F}from"./board-model.js";import{LobbyClient as K,LobbyClientError as Ee}from"./client.js";import{postmarkMailer as _e}from"./mail.js";import{commandOnPath as Te,launchScript as Ae,packageRoot as U,pocolobbyVersion as $,stableLaunchPaths as Se}from"./launch.js";import{unsupportedNodeMessage as Be}from"./node-version.js";import{AgentId as I,CancelScheduledSchema as ve,Email as X,MIN_PUSH_BYTES as Ne,MAX_PUSH_BYTES as Pe,LobbyId as Y,NewLobbyId as Ie,ProvisionSchema as Ce,UpdateAgentSchema as ke,RoomId as C,RoomMembersSchema as Le,RoomMemberChangesSchema as Me,SendSchema as Re}from"./protocol.js";const z=y(m=>m.split(",").map(i=>i.trim()).filter(Boolean),"listOf"),J=`PocoLobby \u2014 a little place for agents to meet.
3
3
 
4
4
  pocolobby init --config owner.json [--url http://127.0.0.1:8787]
5
5
  pocolobby server --db state.db [--config owner.json] [--host 127.0.0.1] [--port 8787]
6
- pocolobby agent add NAME --config owner.json --out agent.json [--lobby NAME] [--coordinator] [--role-file role.txt] [--work TEXT] [--machine NAME] [--screen yes|no] [--broadcast] [--allow PEER]
7
- pocolobby agent describe NAME --config owner.json [--work TEXT] [--machine NAME] [--screen yes|no]
6
+ pocolobby agent add NAME --config owner.json --out agent.json [--lobby NAME] [--coordinator] [--role-file role.txt] [--work TEXT] [--machine NAME] [--screen yes|no] [--kind worker|on-demand] [--broadcast] [--allow PEER]
7
+ pocolobby agent describe NAME --config owner.json [--work TEXT] [--machine NAME] [--screen yes|no] [--kind worker|on-demand]
8
8
  pocolobby agent rotate NAME --config owner.json --out new-agent.json
9
9
  pocolobby agent pause|resume|disable|enable|retry|reset-runtime NAME --config owner.json
10
10
  pocolobby agents --config owner.json
@@ -114,10 +114,10 @@ The server reads these optional settings from its environment:
114
114
  POSTMARK_TOKEN Postmark server token for sign-in codes
115
115
  POCOLOBBY_MAIL_FROM sign-in sender, e.g. "PocoLobby <signin@example.com>"
116
116
  POCOLOBBY_EXCHANGE_RATES ecb: fetch the ECB's daily rates, for costs in a lobby's currency
117
- `,De=new Set([...J.matchAll(/^ pocolobby ([a-z-]+)/gmu)].map(m=>m[1]));function $e(m){const i=y((S,g,v)=>{const o=m[S];if(o===void 0||o==="")return;if(!/^\d+$/u.test(o)||!Number.isSafeInteger(Number(o)))throw new Error(`${S} must be a whole number.`);const s=Number(o);if(s<g||s>v)throw new Error(`${S} must be between ${g} and ${v}.`);return s},"integer"),p=i("POCOLOBBY_ATTACHMENT_RETENTION_DAYS",1,3650),b=i("POCOLOBBY_ATTACHMENT_GRACE_SECONDS",60,168*3600),f=m.POCOLOBBY_ATTACHMENTS_DIR;if(f!==void 0&&f!==""&&!H(f))throw new Error("POCOLOBBY_ATTACHMENTS_DIR must be an absolute path.");const e={maxImageBytes:i("POCOLOBBY_ATTACHMENT_MAX_IMAGE_BYTES",1024,1024**3),maxTextBytes:i("POCOLOBBY_ATTACHMENT_MAX_TEXT_BYTES",1024,1024**3),maxLobbyAttachmentBytes:i("POCOLOBBY_ATTACHMENT_LOBBY_BYTES",0,1024**4),attachmentDiskReserveBytes:i("POCOLOBBY_ATTACHMENT_DISK_RESERVE_BYTES",0,1024**4),attachmentRetentionMs:p===void 0?void 0:p*24*60*60*1e3,attachmentGraceMs:b===void 0?void 0:b*1e3,attachmentsDir:f||void 0},A=m.POCOLOBBY_DASHBOARD_DOMAIN;if(A&&!/^(?=.{1,200}$)([a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z]{2,}$/u.test(A))throw new Error("POCOLOBBY_DASHBOARD_DOMAIN must be a domain name such as pocolobby.com.");const r=m.POCOLOBBY_CLIENT_IP_HEADER;if(r&&!/^[A-Za-z0-9-]{1,64}$/u.test(r))throw new Error("POCOLOBBY_CLIENT_IP_HEADER must be a header name such as fly-client-ip.");const t=i("POCOLOBBY_DASHBOARD_NOTES_SECONDS",30,3600),w=i("POCOLOBBY_DASHBOARD_SUMMARY_SECONDS",60,86400),_={domain:A,githubToken:m.GITHUB_TOKEN||void 0,anthropicApiKey:m.ANTHROPIC_API_KEY||void 0,notesIntervalMs:t===void 0?void 0:t*1e3,summaryIntervalMs:w===void 0?void 0:w*1e3,clientIpHeader:r||void 0},n=y(S=>Object.fromEntries(Object.entries(S).filter(([,g])=>g!==void 0)),"defined"),E=m.POCOLOBBY_SETTINGS_ORIGIN;if(E&&!/^https?:\/\/[a-z0-9.-]+(:\d{1,5})?$/u.test(E))throw new Error("POCOLOBBY_SETTINGS_ORIGIN must be an origin such as https://pocolobby.com, without a path.");const a=m.POSTMARK_TOKEN||void 0,h=m.POCOLOBBY_MAIL_FROM||void 0,T=[...a?[]:["POSTMARK_TOKEN"],...h?[]:["POCOLOBBY_MAIL_FROM"]],c=m.POCOLOBBY_EXCHANGE_RATES;if(c&&c!=="ecb")throw new Error("POCOLOBBY_EXCHANGE_RATES must be ecb, or unset to fetch no exchange rates.");return{pushBytes:i("POCOLOBBY_PUSH_BYTES",Ne,Pe),uploadInflightBytes:i("POCOLOBBY_UPLOAD_INFLIGHT_BYTES",1024,1024**4),...c?{exchangeRates:{source:"ecb"}}:{},storeOptions:n(e),board:n(_),console:{...E?{origin:E}:{},mailer:a&&h?_e({token:a,from:h}):null,missing:T}}}y($e,"serverSettings");function Ye(m){const[i,p]=process.platform==="win32"?["cmd",["/c","start",'""',m]]:process.platform==="darwin"?["open",[m]]:["xdg-open",[m]],b=Q(i,p,{detached:!0,stdio:"ignore",windowsVerbatimArguments:!0});b.on("error",()=>{}),b.unref()}y(Ye,"browse");async function W(){const m=[];for await(const i of process.stdin)m.push(i);return Buffer.concat(m).toString("utf8")}y(W,"readStdin");async function xe(m,i={}){const p=i.stdout??(o=>process.stdout.write(`${o}
117
+ `,De=new Set([...J.matchAll(/^ pocolobby ([a-z-]+)/gmu)].map(m=>m[1]));function $e(m){const i=y((S,g,v)=>{const o=m[S];if(o===void 0||o==="")return;if(!/^\d+$/u.test(o)||!Number.isSafeInteger(Number(o)))throw new Error(`${S} must be a whole number.`);const s=Number(o);if(s<g||s>v)throw new Error(`${S} must be between ${g} and ${v}.`);return s},"integer"),u=i("POCOLOBBY_ATTACHMENT_RETENTION_DAYS",1,3650),b=i("POCOLOBBY_ATTACHMENT_GRACE_SECONDS",60,168*3600),f=m.POCOLOBBY_ATTACHMENTS_DIR;if(f!==void 0&&f!==""&&!H(f))throw new Error("POCOLOBBY_ATTACHMENTS_DIR must be an absolute path.");const e={maxImageBytes:i("POCOLOBBY_ATTACHMENT_MAX_IMAGE_BYTES",1024,1024**3),maxTextBytes:i("POCOLOBBY_ATTACHMENT_MAX_TEXT_BYTES",1024,1024**3),maxLobbyAttachmentBytes:i("POCOLOBBY_ATTACHMENT_LOBBY_BYTES",0,1024**4),attachmentDiskReserveBytes:i("POCOLOBBY_ATTACHMENT_DISK_RESERVE_BYTES",0,1024**4),attachmentRetentionMs:u===void 0?void 0:u*24*60*60*1e3,attachmentGraceMs:b===void 0?void 0:b*1e3,attachmentsDir:f||void 0},A=m.POCOLOBBY_DASHBOARD_DOMAIN;if(A&&!/^(?=.{1,200}$)([a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z]{2,}$/u.test(A))throw new Error("POCOLOBBY_DASHBOARD_DOMAIN must be a domain name such as pocolobby.com.");const r=m.POCOLOBBY_CLIENT_IP_HEADER;if(r&&!/^[A-Za-z0-9-]{1,64}$/u.test(r))throw new Error("POCOLOBBY_CLIENT_IP_HEADER must be a header name such as fly-client-ip.");const t=i("POCOLOBBY_DASHBOARD_NOTES_SECONDS",30,3600),w=i("POCOLOBBY_DASHBOARD_SUMMARY_SECONDS",60,86400),_={domain:A,githubToken:m.GITHUB_TOKEN||void 0,anthropicApiKey:m.ANTHROPIC_API_KEY||void 0,notesIntervalMs:t===void 0?void 0:t*1e3,summaryIntervalMs:w===void 0?void 0:w*1e3,clientIpHeader:r||void 0},n=y(S=>Object.fromEntries(Object.entries(S).filter(([,g])=>g!==void 0)),"defined"),E=m.POCOLOBBY_SETTINGS_ORIGIN;if(E&&!/^https?:\/\/[a-z0-9.-]+(:\d{1,5})?$/u.test(E))throw new Error("POCOLOBBY_SETTINGS_ORIGIN must be an origin such as https://pocolobby.com, without a path.");const a=m.POSTMARK_TOKEN||void 0,h=m.POCOLOBBY_MAIL_FROM||void 0,T=[...a?[]:["POSTMARK_TOKEN"],...h?[]:["POCOLOBBY_MAIL_FROM"]],c=m.POCOLOBBY_EXCHANGE_RATES;if(c&&c!=="ecb")throw new Error("POCOLOBBY_EXCHANGE_RATES must be ecb, or unset to fetch no exchange rates.");return{pushBytes:i("POCOLOBBY_PUSH_BYTES",Ne,Pe),uploadInflightBytes:i("POCOLOBBY_UPLOAD_INFLIGHT_BYTES",1024,1024**4),...c?{exchangeRates:{source:"ecb"}}:{},storeOptions:n(e),board:n(_),console:{...E?{origin:E}:{},mailer:a&&h?_e({token:a,from:h}):null,missing:T}}}y($e,"serverSettings");function Ye(m){const[i,u]=process.platform==="win32"?["cmd",["/c","start",'""',m]]:process.platform==="darwin"?["open",[m]]:["xdg-open",[m]],b=Q(i,u,{detached:!0,stdio:"ignore",windowsVerbatimArguments:!0});b.on("error",()=>{}),b.unref()}y(Ye,"browse");async function W(){const m=[];for await(const i of process.stdin)m.push(i);return Buffer.concat(m).toString("utf8")}y(W,"readStdin");async function xe(m,i={}){const u=i.stdout??(o=>process.stdout.write(`${o}
118
118
  `)),b=i.stderr??(o=>process.stderr.write(`${o}
119
- `)),f=i.env??process.env,{values:e,positionals:A}=ue({args:m,allowPositionals:!0,options:{help:{type:"boolean",short:"h"},config:{type:"string"},lobby:{type:"string"},coordinator:{type:"boolean"},agents:{type:"string"},member:{type:"string",multiple:!0},url:{type:"string"},db:{type:"string"},out:{type:"string"},host:{type:"string"},port:{type:"string"},"allow-remote":{type:"boolean"},"role-file":{type:"string"},work:{type:"string"},memory:{type:"string"},machine:{type:"string"},screen:{type:"string"},"content-file":{type:"string"},"request-id":{type:"string"},"correlation-id":{type:"string"},kind:{type:"string"},"deliver-at":{type:"string"},cancel:{type:"string"},important:{type:"boolean"},broadcast:{type:"boolean"},allow:{type:"string",multiple:!0},mode:{type:"string"},cursor:{type:"string"},limit:{type:"string"},"mcp-config":{type:"string"},session:{type:"string"},repo:{type:"string"},ref:{type:"string"},notes:{type:"string",multiple:!0},agent:{type:"string",multiple:!0},hide:{type:"string",multiple:!0},support:{type:"string",multiple:!0},"dry-run":{type:"boolean"},room:{type:"string"},force:{type:"boolean"},review:{type:"boolean"},"report-to":{type:"string"}}}),[r,t,...w]=A;if(e.help||!r){p(J);return}const _=y((o,s)=>{if(!o)throw new Error(`${s} is required. See --help.`);return o},"required"),n=y(o=>{if(A.length!==o)throw new Error("Unexpected or missing arguments. See --help.")},"exact"),E=y((o,s,l)=>{if(o===void 0)return s;if(!/^\d+$/u.test(o))throw new Error("Expected an unsigned integer option.");const d=Number(o);if(!Number.isSafeInteger(d)||d>l)throw new Error("Numeric option is out of range.");return d},"number"),a=y(o=>p(JSON.stringify(o,null,2)),"print");if(r==="init"){n(1);const o=_(e.config,"--config");await we(o,{url:e.url??"http://127.0.0.1:8787",token:ee(32).toString("base64url")}),p(`Owner credentials saved to ${B(o)}.`);return}if(r==="server"){n(1);const o=e.config?await fe(e.config):void 0,s=f.POCOLOBBY_ADMIN_TOKEN||o?.token;if(!s||s.length<32||/[\r\n]/u.test(s))throw new Error("Set POCOLOBBY_ADMIN_TOKEN (at least 32 characters), or provide --config.");const l=$e(f),{startServer:d}=await import("./server.js"),u=await d({database:B(_(e.db,"--db")),adminToken:s,host:e.host??"127.0.0.1",port:E(e.port,8787,65535),allowRemote:e["allow-remote"]??!1,...l});p(`PocoLobby listening at ${u.url}.`),await new Promise((O,L)=>{let N=!1;const P=y(()=>{N||(N=!0,process.off("SIGINT",P),process.off("SIGTERM",P),u.close().then(O,L))},"stop");process.on("SIGINT",P),process.on("SIGTERM",P)});return}if(r==="backup"||r==="recover"){n(1);const o=B(_(e.db,"--db")),{acquireDatabaseLock:s}=await import("./lock.js"),{backupDatabase:l,LobbyStore:d}=await import("./store.js");if(!(await D(o).catch(()=>null))?.isFile())throw new Error("Database must be an existing regular file.");const u=s(o);try{if(r==="backup"){const O=B(_(e.out,"--out"));await(await ae(O,"wx",384)).close();try{await l(o,O)}catch(N){throw await ie(O).catch(()=>{}),N}p(`Backup saved to ${O}. Treat it as sensitive data.`)}else{const O=new d(o);try{O.enterRecovery()}finally{O.close()}p("Recovery mode enabled. Re-establish credentials and reconcile agent state before resuming delivery.")}}finally{u()}return}if(r==="check-config"){n(1);const o=await He(B(_(e["mcp-config"],"--mcp-config")),f.PATH??f.Path);if(a(o),o.problems.length)throw new Error(o.problems.join(" "));return}if(r==="launch-script"){const o=e.session??f.CLAUDE_CODE_SESSION_ID;if(!o)throw new Error("Run launch-script in the agent's own Claude conversation, or pass --session ID.");const s=B(_(e["mcp-config"],"--mcp-config"));if(!(await D(s)).isFile())throw new Error("--mcp-config must name the agent's generated MCP file.");const l=Ae({sessionId:o,mcpConfig:s,profile:f.CLAUDE_CONFIG_DIR||void 0,flags:A.slice(1),home:le(),windows:process.platform==="win32"}),d=B("launch-agent");await ce(d,l,{mode:493,flag:"wx"}),p(`Saved ${d}: run ./launch-agent to relaunch this conversation.`),b(Ue(d));return}if(!De.has(r))throw new Error(`Unknown command ${r}. See --help.`);const{config:h,identity:T}=await G(_(e.config,"--config"));if(r==="set-url"){n(1);const o=q({...h,url:_(e.url,"--url")});await new K(o).request("GET","/v1/agents"),await ge(T.path,o.url),p(`${T.path} now uses ${o.url}. A running adapter moves on /mcp reconnect pocolobby.`);return}if(r==="statusline"){n(1);const{runStatusLine:o}=await import("./statusline.js");p(await o(h,T.path,await(i.stdin??W)(),{dryRun:e["dry-run"]??!1}));return}if(r==="memory"&&t==="curate"){n(2);const{curate:o}=await import("./memory-curate.js"),s=await o(h,{room:C.parse(_(e.room,"--room")),repo:e.repo??process.cwd(),force:e.force??!1,review:e.review??!1,dryRun:e["dry-run"]??!1,...e["report-to"]?{reportTo:I.parse(e["report-to"])}:{}});for(const l of s.lines)p(l);if(s.failed)throw new Error("The curation failed; see above.");return}if(r==="repo"&&t==="stats"){n(2);const{repoStats:o}=await import("./code-stats.js");p(await o(h,{room:C.parse(_(e.room,"--room")),repo:e.repo??process.cwd()}));return}if(r==="hook"){n(1);const{memoryHook:o,runHook:s}=await import("./hook.js"),l=await(i.stdin??W)();if(e.memory!==void 0){const u=Number(e.memory);if(u!==1&&u!==2&&u!==3)throw new Error("--memory takes 1, 2 or 3.");const O=await o(h,u);O&&p(O);return}const d=await s(h,l,{dryRun:e["dry-run"]??!1});d&&p(d);return}if(r==="adapter"){if(n(1),e.lobby)throw new Error("An agent lobby is bound to its credential; --lobby is for owner administration.");const{runClaudeAdapter:o}=await import("./adapters/claude.js");await o({...h,hostSessionId:f.CLAUDE_CODE_SESSION_ID,credentialFile:T});return}if(r==="mcp-config"){if(n(1),e.lobby)throw new Error("An agent lobby is bound to its credential; --lobby is for owner administration.");const o=Se({execPath:process.execPath,script:j(import.meta.url),version:process.versions.node,searchPath:f.PATH??f.Path});a({mcpServers:{pocolobby:{command:o.command,args:[o.script,"adapter","--config",B(e.config)]}}}),b(`pocolobby: the adapter runs ${o.command} ${o.script} (PocoLobby ${$(o.script)??"of unknown version"}).`),o.versionPinned&&b(`pocolobby: these paths name Node ${process.versions.node}'s own directory. Run mcp-config again after upgrading or removing that Node version.`);return}const c=new K(h),S=e.lobby===void 0?void 0:Y.parse(e.lobby),g=y(o=>S===void 0?o:`${o}${o.includes("?")?"&":"?"}lobby=${encodeURIComponent(S)}`,"scoped");if(r==="settings"){n(1);const{ticket:o}=await c.request("POST","/v1/admin/settings/ticket"),s=`${new URL("/",c.url).href}#ticket=${o}`;p(s),(i.browse??Ye)(s);return}if(r==="lobbies"){n(1),a(await c.request("GET","/v1/admin/lobbies"));return}if(r==="lobby"){if(t==="display-name"){if(A.length!==3&&A.length!==4)throw new Error("Unexpected or missing arguments. See --help.");a(await c.request("PATCH",`/v1/admin/lobbies/${Y.parse(w[0])}`,{display_name:w[1]??null}));return}if(n(3),t!=="create")throw new Error("Unknown lobby operation. See --help.");a(await c.request("POST","/v1/admin/lobbies",{lobby_id:Ie.parse(w[0])}));return}if(r==="rooms"){n(1),a(await c.request("GET",g("/v1/admin/rooms")));return}if(r==="room"){n(3);const o=C.parse(w[0]);if(t==="create")a(await c.request("POST",g("/v1/admin/rooms"),{room_id:o}));else if(t==="delete")a(await c.request("DELETE",g(`/v1/admin/rooms/${o}`)));else if(t==="add"||t==="remove"){if(e.agents!==void 0&&e.member!==void 0)throw new Error("Use --agents or repeated --member, not both.");const s=e.member??z(e.agents??"");a(await c.request("PATCH",g(`/v1/admin/rooms/${o}/members`),ke.parse({[t]:s})))}else if(t==="members"){if(e.agents!==void 0&&e.member!==void 0)throw new Error("Use --agents or repeated --member, not both.");if(e.agents===void 0&&e.member===void 0)throw new Error('Provide --agents or repeated --member; use --agents "" to clear membership.');const s=e.member??z(e.agents);a(await c.request("PUT",g(`/v1/admin/rooms/${o}/members`),Me.parse({members:s})))}else throw new Error("Unknown room operation. See --help.");return}if(r==="memory"){if(t==="show"){n(2),a(await c.request("GET",g("/v1/admin/memory")));return}if(t==="curator"){n(4);const o=C.parse(w[0]),s=w[1]==="none"?null:I.parse(w[1]);a(await c.request("PUT",g(`/v1/admin/memory/rooms/${encodeURIComponent(o)}/curator`),{agent_id:s}));return}throw new Error("Unknown memory operation. See --help.")}if(r==="agents"){n(1),a(await c.request("GET",g("/v1/admin/agents")));return}if(r==="agent"){n(3);const o=y(()=>{if(e.screen!==void 0&&!["yes","no"].includes(e.screen))throw new Error("--screen takes yes or no.");return{...e.work!==void 0?{work_description:e.work}:{},...e.machine!==void 0?{machine:e.machine}:{},...e.screen!==void 0?{screen:e.screen==="yes"}:{}}},"description"),s=I.parse(w[0]),l=`/v1/admin/agents/${encodeURIComponent(s)}`;if(t==="add"||t==="rotate"){const u=_(e.out,"--out"),O=t==="add"?Ce.parse({agent_id:s,lobby_id:S,manage_rooms:e.coordinator??!1,role:e["role-file"]?await R(e["role-file"],"utf8"):"",...o(),can_broadcast:e.broadcast??!1,allowed_recipients:e.allow??null}):void 0,L=await he(u);let N=!1,P=S?`${S}/`:"";try{const M=await c.request("POST",g(t==="add"?"/v1/admin/agents":`${l}/rotate`),O??{});N=!0,await L.write(q({url:h.url,token:M.token})),M.agent&&(P=`${M.agent.lobby_id}/`)}catch(M){throw await L.abort(),N?new Error("Server changed the credential, but its file could not be saved. Use owner agent rotate with a new writable --out path."):M}p(`Agent ${P}${s} credentials saved to ${B(u)}.`);return}const d={pause:{paused:!0},resume:{paused:!1},disable:{enabled:!1},enable:{enabled:!0}};if(t&&d[t])a(await c.request("PATCH",g(l),d[t]));else if(t==="describe"){const u=o();if(!Object.keys(u).length)throw new Error("Name what to change: --work, --machine or --screen yes|no.");a(await c.request("PATCH",g(l),Le.parse(u)))}else if(t==="retry"||t==="reset-runtime")a(await c.request("POST",g(`${l}/${t}`),{}));else throw new Error("Unknown agent operation. See --help.");return}if(r==="send"||r==="broadcast"||r==="send-room"){const o=r==="send"?I.parse(t):"*",s=r==="broadcast"?A.slice(1):w;if(e["content-file"]&&s.length>0)throw new Error("Use a message argument or --content-file, not both.");if(!e["content-file"]&&s.length!==1)throw new Error("Provide exactly one quoted message or --content-file.");const l=e["content-file"]?await R(e["content-file"],"utf8"):s[0],d=e["request-id"]??oe(),u=Re.parse({client_request_id:d,to:o,priority:e.important?"important":"info",content:l,correlation_id:e["correlation-id"],...r==="send-room"?{room:C.parse(t)}:{},...e.kind===void 0?{}:{kind:e.kind},...e["deliver-at"]===void 0?{}:{deliver_at:e["deliver-at"]}});b(`Request ID: ${d}`),a(await c.request("POST",g("/v1/messages"),u));return}if(r==="schedules"){n(2);const o=I.parse(t);a(e.cancel===void 0?await c.request("GET",g(`/v1/admin/agents/${o}/schedules`)):await c.request("POST",g(`/v1/admin/agents/${o}/schedules/cancel`),ve.parse({id:e.cancel})));return}if(r==="dashboard"){const o=y((l,d="")=>`/v1/admin/dashboard${d}?lobby=${encodeURIComponent(Y.parse(l))}`,"boardPath");if(t==="source"){n(5);const[l,d,u]=w,O=o(d,`/sources/${C.parse(u)}`);if(l==="set")a(await c.request("PUT",O,Oe.parse({repo:e.repo,ref:e.ref,notes:e.notes})));else if(l==="remove")a(await c.request("DELETE",O));else throw new Error("Unknown dashboard source operation. See --help.");return}if(t==="icon"){const[l,d,u]=w;if(l==="set"){n(5);const O=(await R(u)).toString("base64");a(await c.request("PUT",o(d,"/icon"),{png:O}))}else if(l==="remove")n(4),a(await c.request("DELETE",o(d,"/icon")));else throw new Error("Unknown dashboard icon operation. See --help.");return}n(3);const s=w[0];if(t==="status")a(await c.request("GET",o(s)));else if(t==="agents"){if(!e.agent?.length&&!e.hide?.length&&!e.support?.length)throw new Error("Give at least one --agent ID=EMOJI or --hide ID.");const l=Object.fromEntries((e.agent??[]).map(d=>{const u=/^([^=\s]+)=(\S+)(?:\s+(.+))?$/u.exec(d.trim());if(!u)throw new Error('Use --agent ID=EMOJI or --agent "ID=EMOJI Name".');return[u[1],{emoji:u[2],...u[3]?{name:u[3].trim()}:{}}]}));for(const d of e.hide??[])l[d]={...l[d],hidden:!0};for(const d of e.support??[])l[d]={...l[d],support:!0};a(await c.request("PUT",o(s,"/agents"),ye.parse({agents:l})))}else throw new Error("Unknown dashboard operation. See --help.");return}const v=y((o,s)=>`/v1/admin/settings/${s}?lobby=${encodeURIComponent(Y.parse(o))}`,"settingsPath");if(r==="accounts"){if(t==="list")n(2),a(await c.request("GET","/v1/admin/settings/accounts"));else if(t==="allow"||t==="enable"||t==="disable")n(3),a(await c.request("POST","/v1/admin/settings/accounts",{email:X.parse(w[0]),enabled:t!=="disable",...t==="allow"?{may_create_lobbies:!0}:{}}));else if(t==="grant"||t==="revoke")n(4),a(await c.request(t==="grant"?"PUT":"POST",v(w[1],t==="grant"?"owner":"owner/revoke"),{email:X.parse(w[0])}));else throw new Error("Unknown accounts operation. See --help.");return}if(r==="repos"){const[o,s]=w;if(o==="list"||o===void 0)n(o===void 0?2:3),a(await c.request("GET",v(t,"repos")));else if(o==="add")n(4),a(await c.request("POST",v(t,"repos"),{repo:F.parse(s)}));else if(o==="remove"){n(4);const[l,d]=F.parse(s).split("/");a(await c.request("DELETE",v(t,`repos/${encodeURIComponent(l)}/${encodeURIComponent(d)}`)))}else throw new Error("Unknown repos operation. See --help.");return}if(r==="attachments"){if(t!==void 0&&t!=="usage")throw new Error("Unknown attachments operation. See --help.");if(n(t===void 0?1:2),t==="usage"){a(await c.request("GET",g("/v1/admin/attachments/usage")));return}const o=new URLSearchParams({limit:String(E(e.limit,50,100))});e.cursor!==void 0&&o.set("cursor",String(E(e.cursor,0,Number.MAX_SAFE_INTEGER))),a(await c.request("GET",g(`/v1/admin/attachments?${o}`)));return}if(r==="inbox"||r==="context"){n(2);const o=I.parse(t);if(r==="context")a(await c.request("GET",g(`/v1/admin/agents/${o}/context`)));else{const s=e.mode??"pending";if(!["pending","history","reconciliation"].includes(s))throw new Error("Unknown inbox mode.");const l=new URLSearchParams({mode:s,limit:String(E(e.limit,50,100))});e.cursor!==void 0&&l.set("cursor",String(E(e.cursor,0,Number.MAX_SAFE_INTEGER))),a(await c.request("GET",g(`/v1/admin/agents/${o}/messages?${l}`)))}return}throw new Error("Unknown command. See --help.")}y(xe,"runCli");function Ue(m){let i,p;try{[i,p]=Z("git",["rev-parse","--show-toplevel","--git-path","info/exclude"],{cwd:x(m),encoding:"utf8",stdio:["ignore","pipe","ignore"]}).trim().split(/\r?\n/u)}catch{}if(!i||!p)return"pocolobby: this is not a Git checkout, so nothing was excluded.";const b=`/${de(k(i),k(m)).split(me).join("/").replace(/[*?[\\]/gu,"\\$&")}`,f=B(x(m),p);let e="";try{e=re(f,"utf8")}catch{ne(x(f),{recursive:!0})}return e.split(/\r?\n/u).includes(b)||te(f,`${e&&!e.endsWith(`
119
+ `)),f=i.env??process.env,{values:e,positionals:A}=pe({args:m,allowPositionals:!0,options:{help:{type:"boolean",short:"h"},config:{type:"string"},lobby:{type:"string"},coordinator:{type:"boolean"},agents:{type:"string"},member:{type:"string",multiple:!0},url:{type:"string"},db:{type:"string"},out:{type:"string"},host:{type:"string"},port:{type:"string"},"allow-remote":{type:"boolean"},"role-file":{type:"string"},work:{type:"string"},memory:{type:"string"},machine:{type:"string"},screen:{type:"string"},"content-file":{type:"string"},"request-id":{type:"string"},"correlation-id":{type:"string"},kind:{type:"string"},"deliver-at":{type:"string"},cancel:{type:"string"},important:{type:"boolean"},broadcast:{type:"boolean"},allow:{type:"string",multiple:!0},mode:{type:"string"},cursor:{type:"string"},limit:{type:"string"},"mcp-config":{type:"string"},session:{type:"string"},repo:{type:"string"},ref:{type:"string"},notes:{type:"string",multiple:!0},agent:{type:"string",multiple:!0},hide:{type:"string",multiple:!0},support:{type:"string",multiple:!0},"dry-run":{type:"boolean"},room:{type:"string"},force:{type:"boolean"},review:{type:"boolean"},"report-to":{type:"string"}}}),[r,t,...w]=A;if(e.help||!r){u(J);return}const _=y((o,s)=>{if(!o)throw new Error(`${s} is required. See --help.`);return o},"required"),n=y(o=>{if(A.length!==o)throw new Error("Unexpected or missing arguments. See --help.")},"exact"),E=y((o,s,d)=>{if(o===void 0)return s;if(!/^\d+$/u.test(o))throw new Error("Expected an unsigned integer option.");const l=Number(o);if(!Number.isSafeInteger(l)||l>d)throw new Error("Numeric option is out of range.");return l},"number"),a=y(o=>u(JSON.stringify(o,null,2)),"print");if(r==="init"){n(1);const o=_(e.config,"--config");await we(o,{url:e.url??"http://127.0.0.1:8787",token:ee(32).toString("base64url")}),u(`Owner credentials saved to ${B(o)}.`);return}if(r==="server"){n(1);const o=e.config?await fe(e.config):void 0,s=f.POCOLOBBY_ADMIN_TOKEN||o?.token;if(!s||s.length<32||/[\r\n]/u.test(s))throw new Error("Set POCOLOBBY_ADMIN_TOKEN (at least 32 characters), or provide --config.");const d=$e(f),{startServer:l}=await import("./server.js"),p=await l({database:B(_(e.db,"--db")),adminToken:s,host:e.host??"127.0.0.1",port:E(e.port,8787,65535),allowRemote:e["allow-remote"]??!1,...d});u(`PocoLobby listening at ${p.url}.`),await new Promise((O,k)=>{let N=!1;const P=y(()=>{N||(N=!0,process.off("SIGINT",P),process.off("SIGTERM",P),p.close().then(O,k))},"stop");process.on("SIGINT",P),process.on("SIGTERM",P)});return}if(r==="backup"||r==="recover"){n(1);const o=B(_(e.db,"--db")),{acquireDatabaseLock:s}=await import("./lock.js"),{backupDatabase:d,LobbyStore:l}=await import("./store.js");if(!(await D(o).catch(()=>null))?.isFile())throw new Error("Database must be an existing regular file.");const p=s(o);try{if(r==="backup"){const O=B(_(e.out,"--out"));await(await ae(O,"wx",384)).close();try{await d(o,O)}catch(N){throw await ie(O).catch(()=>{}),N}u(`Backup saved to ${O}. Treat it as sensitive data.`)}else{const O=new l(o);try{O.enterRecovery()}finally{O.close()}u("Recovery mode enabled. Re-establish credentials and reconcile agent state before resuming delivery.")}}finally{p()}return}if(r==="check-config"){n(1);const o=await He(B(_(e["mcp-config"],"--mcp-config")),f.PATH??f.Path);if(a(o),o.problems.length)throw new Error(o.problems.join(" "));return}if(r==="launch-script"){const o=e.session??f.CLAUDE_CODE_SESSION_ID;if(!o)throw new Error("Run launch-script in the agent's own Claude conversation, or pass --session ID.");const s=B(_(e["mcp-config"],"--mcp-config"));if(!(await D(s)).isFile())throw new Error("--mcp-config must name the agent's generated MCP file.");const d=Ae({sessionId:o,mcpConfig:s,profile:f.CLAUDE_CONFIG_DIR||void 0,flags:A.slice(1),home:de(),windows:process.platform==="win32"}),l=B("launch-agent");await ce(l,d,{mode:493,flag:"wx"}),u(`Saved ${l}: run ./launch-agent to relaunch this conversation.`),b(Ue(l));return}if(!De.has(r))throw new Error(`Unknown command ${r}. See --help.`);const{config:h,identity:T}=await G(_(e.config,"--config"));if(r==="set-url"){n(1);const o=q({...h,url:_(e.url,"--url")});await new K(o).request("GET","/v1/agents"),await ge(T.path,o.url),u(`${T.path} now uses ${o.url}. A running adapter moves on /mcp reconnect pocolobby.`);return}if(r==="statusline"){n(1);const{runStatusLine:o}=await import("./statusline.js");u(await o(h,T.path,await(i.stdin??W)(),{dryRun:e["dry-run"]??!1}));return}if(r==="memory"&&t==="curate"){n(2);const{curate:o}=await import("./memory-curate.js"),s=await o(h,{room:C.parse(_(e.room,"--room")),repo:e.repo??process.cwd(),force:e.force??!1,review:e.review??!1,dryRun:e["dry-run"]??!1,...e["report-to"]?{reportTo:I.parse(e["report-to"])}:{}});for(const d of s.lines)u(d);if(s.failed)throw new Error("The curation failed; see above.");return}if(r==="repo"&&t==="stats"){n(2);const{repoStats:o}=await import("./code-stats.js");u(await o(h,{room:C.parse(_(e.room,"--room")),repo:e.repo??process.cwd()}));return}if(r==="hook"){n(1);const{memoryHook:o,runHook:s}=await import("./hook.js"),d=await(i.stdin??W)();if(e.memory!==void 0){const p=Number(e.memory);if(p!==1&&p!==2&&p!==3)throw new Error("--memory takes 1, 2 or 3.");const O=await o(h,p);O&&u(O);return}const l=await s(h,d,{dryRun:e["dry-run"]??!1});l&&u(l);return}if(r==="adapter"){if(n(1),e.lobby)throw new Error("An agent lobby is bound to its credential; --lobby is for owner administration.");const{runClaudeAdapter:o}=await import("./adapters/claude.js");await o({...h,hostSessionId:f.CLAUDE_CODE_SESSION_ID,credentialFile:T});return}if(r==="mcp-config"){if(n(1),e.lobby)throw new Error("An agent lobby is bound to its credential; --lobby is for owner administration.");const o=Se({execPath:process.execPath,script:j(import.meta.url),version:process.versions.node,searchPath:f.PATH??f.Path});a({mcpServers:{pocolobby:{command:o.command,args:[o.script,"adapter","--config",B(e.config)]}}}),b(`pocolobby: the adapter runs ${o.command} ${o.script} (PocoLobby ${$(o.script)??"of unknown version"}).`),o.versionPinned&&b(`pocolobby: these paths name Node ${process.versions.node}'s own directory. Run mcp-config again after upgrading or removing that Node version.`);return}const c=new K(h),S=e.lobby===void 0?void 0:Y.parse(e.lobby),g=y(o=>S===void 0?o:`${o}${o.includes("?")?"&":"?"}lobby=${encodeURIComponent(S)}`,"scoped");if(r==="settings"){n(1);const{ticket:o}=await c.request("POST","/v1/admin/settings/ticket"),s=`${new URL("/",c.url).href}#ticket=${o}`;u(s),(i.browse??Ye)(s);return}if(r==="lobbies"){n(1),a(await c.request("GET","/v1/admin/lobbies"));return}if(r==="lobby"){if(t==="display-name"){if(A.length!==3&&A.length!==4)throw new Error("Unexpected or missing arguments. See --help.");a(await c.request("PATCH",`/v1/admin/lobbies/${Y.parse(w[0])}`,{display_name:w[1]??null}));return}if(n(3),t!=="create")throw new Error("Unknown lobby operation. See --help.");a(await c.request("POST","/v1/admin/lobbies",{lobby_id:Ie.parse(w[0])}));return}if(r==="rooms"){n(1),a(await c.request("GET",g("/v1/admin/rooms")));return}if(r==="room"){n(3);const o=C.parse(w[0]);if(t==="create")a(await c.request("POST",g("/v1/admin/rooms"),{room_id:o}));else if(t==="delete")a(await c.request("DELETE",g(`/v1/admin/rooms/${o}`)));else if(t==="add"||t==="remove"){if(e.agents!==void 0&&e.member!==void 0)throw new Error("Use --agents or repeated --member, not both.");const s=e.member??z(e.agents??"");a(await c.request("PATCH",g(`/v1/admin/rooms/${o}/members`),Me.parse({[t]:s})))}else if(t==="members"){if(e.agents!==void 0&&e.member!==void 0)throw new Error("Use --agents or repeated --member, not both.");if(e.agents===void 0&&e.member===void 0)throw new Error('Provide --agents or repeated --member; use --agents "" to clear membership.');const s=e.member??z(e.agents);a(await c.request("PUT",g(`/v1/admin/rooms/${o}/members`),Le.parse({members:s})))}else throw new Error("Unknown room operation. See --help.");return}if(r==="memory"){if(t==="show"){n(2),a(await c.request("GET",g("/v1/admin/memory")));return}if(t==="curator"){n(4);const o=C.parse(w[0]),s=w[1]==="none"?null:I.parse(w[1]);a(await c.request("PUT",g(`/v1/admin/memory/rooms/${encodeURIComponent(o)}/curator`),{agent_id:s}));return}throw new Error("Unknown memory operation. See --help.")}if(r==="agents"){n(1),a(await c.request("GET",g("/v1/admin/agents")));return}if(r==="agent"){n(3);const o=y(()=>{if(e.screen!==void 0&&!["yes","no"].includes(e.screen))throw new Error("--screen takes yes or no.");if(e.kind!==void 0&&!["worker","on-demand"].includes(e.kind))throw new Error("--kind takes worker or on-demand.");return{...e.work!==void 0?{work_description:e.work}:{},...e.machine!==void 0?{machine:e.machine}:{},...e.screen!==void 0?{screen:e.screen==="yes"}:{},...e.kind!==void 0?{kind:e.kind==="worker"?"worker":"on_demand"}:{}}},"description"),s=I.parse(w[0]),d=`/v1/admin/agents/${encodeURIComponent(s)}`;if(t==="add"||t==="rotate"){const p=_(e.out,"--out"),O=t==="add"?Ce.parse({agent_id:s,lobby_id:S,manage_rooms:e.coordinator??!1,role:e["role-file"]?await R(e["role-file"],"utf8"):"",...o(),can_broadcast:e.broadcast??!1,allowed_recipients:e.allow??null}):void 0,k=await he(p);let N=!1,P=S?`${S}/`:"";try{const L=await c.request("POST",g(t==="add"?"/v1/admin/agents":`${d}/rotate`),O??{});N=!0,await k.write(q({url:h.url,token:L.token})),L.agent&&(P=`${L.agent.lobby_id}/`)}catch(L){throw await k.abort(),N?new Error("Server changed the credential, but its file could not be saved. Use owner agent rotate with a new writable --out path."):L}u(`Agent ${P}${s} credentials saved to ${B(p)}.`);return}const l={pause:{paused:!0},resume:{paused:!1},disable:{enabled:!1},enable:{enabled:!0}};if(t&&l[t])a(await c.request("PATCH",g(d),l[t]));else if(t==="describe"){const p=o();if(!Object.keys(p).length)throw new Error("Name what to change: --work, --machine, --screen yes|no or --kind worker|on-demand.");a(await c.request("PATCH",g(d),ke.parse(p)))}else if(t==="retry"||t==="reset-runtime")a(await c.request("POST",g(`${d}/${t}`),{}));else throw new Error("Unknown agent operation. See --help.");return}if(r==="send"||r==="broadcast"||r==="send-room"){const o=r==="send"?I.parse(t):"*",s=r==="broadcast"?A.slice(1):w;if(e["content-file"]&&s.length>0)throw new Error("Use a message argument or --content-file, not both.");if(!e["content-file"]&&s.length!==1)throw new Error("Provide exactly one quoted message or --content-file.");const d=e["content-file"]?await R(e["content-file"],"utf8"):s[0],l=e["request-id"]??oe(),p=Re.parse({client_request_id:l,to:o,priority:e.important?"important":"info",content:d,correlation_id:e["correlation-id"],...r==="send-room"?{room:C.parse(t)}:{},...e.kind===void 0?{}:{kind:e.kind},...e["deliver-at"]===void 0?{}:{deliver_at:e["deliver-at"]}});b(`Request ID: ${l}`),a(await c.request("POST",g("/v1/messages"),p));return}if(r==="schedules"){n(2);const o=I.parse(t);a(e.cancel===void 0?await c.request("GET",g(`/v1/admin/agents/${o}/schedules`)):await c.request("POST",g(`/v1/admin/agents/${o}/schedules/cancel`),ve.parse({id:e.cancel})));return}if(r==="dashboard"){const o=y((d,l="")=>`/v1/admin/dashboard${l}?lobby=${encodeURIComponent(Y.parse(d))}`,"boardPath");if(t==="source"){n(5);const[d,l,p]=w,O=o(l,`/sources/${C.parse(p)}`);if(d==="set")a(await c.request("PUT",O,Oe.parse({repo:e.repo,ref:e.ref,notes:e.notes})));else if(d==="remove")a(await c.request("DELETE",O));else throw new Error("Unknown dashboard source operation. See --help.");return}if(t==="icon"){const[d,l,p]=w;if(d==="set"){n(5);const O=(await R(p)).toString("base64");a(await c.request("PUT",o(l,"/icon"),{png:O}))}else if(d==="remove")n(4),a(await c.request("DELETE",o(l,"/icon")));else throw new Error("Unknown dashboard icon operation. See --help.");return}n(3);const s=w[0];if(t==="status")a(await c.request("GET",o(s)));else if(t==="agents"){if(!e.agent?.length&&!e.hide?.length&&!e.support?.length)throw new Error("Give at least one --agent ID=EMOJI or --hide ID.");const d=Object.fromEntries((e.agent??[]).map(l=>{const p=/^([^=\s]+)=(\S+)(?:\s+(.+))?$/u.exec(l.trim());if(!p)throw new Error('Use --agent ID=EMOJI or --agent "ID=EMOJI Name".');return[p[1],{emoji:p[2],...p[3]?{name:p[3].trim()}:{}}]}));for(const l of e.hide??[])d[l]={...d[l],hidden:!0};for(const l of e.support??[])d[l]={...d[l],support:!0};a(await c.request("PUT",o(s,"/agents"),ye.parse({agents:d})))}else throw new Error("Unknown dashboard operation. See --help.");return}const v=y((o,s)=>`/v1/admin/settings/${s}?lobby=${encodeURIComponent(Y.parse(o))}`,"settingsPath");if(r==="accounts"){if(t==="list")n(2),a(await c.request("GET","/v1/admin/settings/accounts"));else if(t==="allow"||t==="enable"||t==="disable")n(3),a(await c.request("POST","/v1/admin/settings/accounts",{email:X.parse(w[0]),enabled:t!=="disable",...t==="allow"?{may_create_lobbies:!0}:{}}));else if(t==="grant"||t==="revoke")n(4),a(await c.request(t==="grant"?"PUT":"POST",v(w[1],t==="grant"?"owner":"owner/revoke"),{email:X.parse(w[0])}));else throw new Error("Unknown accounts operation. See --help.");return}if(r==="repos"){const[o,s]=w;if(o==="list"||o===void 0)n(o===void 0?2:3),a(await c.request("GET",v(t,"repos")));else if(o==="add")n(4),a(await c.request("POST",v(t,"repos"),{repo:F.parse(s)}));else if(o==="remove"){n(4);const[d,l]=F.parse(s).split("/");a(await c.request("DELETE",v(t,`repos/${encodeURIComponent(d)}/${encodeURIComponent(l)}`)))}else throw new Error("Unknown repos operation. See --help.");return}if(r==="attachments"){if(t!==void 0&&t!=="usage")throw new Error("Unknown attachments operation. See --help.");if(n(t===void 0?1:2),t==="usage"){a(await c.request("GET",g("/v1/admin/attachments/usage")));return}const o=new URLSearchParams({limit:String(E(e.limit,50,100))});e.cursor!==void 0&&o.set("cursor",String(E(e.cursor,0,Number.MAX_SAFE_INTEGER))),a(await c.request("GET",g(`/v1/admin/attachments?${o}`)));return}if(r==="inbox"||r==="context"){n(2);const o=I.parse(t);if(r==="context")a(await c.request("GET",g(`/v1/admin/agents/${o}/context`)));else{const s=e.mode??"pending";if(!["pending","history","reconciliation"].includes(s))throw new Error("Unknown inbox mode.");const d=new URLSearchParams({mode:s,limit:String(E(e.limit,50,100))});e.cursor!==void 0&&d.set("cursor",String(E(e.cursor,0,Number.MAX_SAFE_INTEGER))),a(await c.request("GET",g(`/v1/admin/agents/${o}/messages?${d}`)))}return}throw new Error("Unknown command. See --help.")}y(xe,"runCli");function Ue(m){let i,u;try{[i,u]=Z("git",["rev-parse","--show-toplevel","--git-path","info/exclude"],{cwd:x(m),encoding:"utf8",stdio:["ignore","pipe","ignore"]}).trim().split(/\r?\n/u)}catch{}if(!i||!u)return"pocolobby: this is not a Git checkout, so nothing was excluded.";const b=`/${le(M(i),M(m)).split(me).join("/").replace(/[*?[\\]/gu,"\\$&")}`,f=B(x(m),u);let e="";try{e=re(f,"utf8")}catch{ne(x(f),{recursive:!0})}return e.split(/\r?\n/u).includes(b)||te(f,`${e&&!e.endsWith(`
120
120
  `)?`
121
121
  `:""}${b}
122
- `),`pocolobby: Git ignores ${b} through ${f}.`}y(Ue,"excludeFromGit");async function He(m,i){const p=await D(m);if(!p.isFile()||p.size>1024*1024)throw new Error("The MCP configuration must be a regular file smaller than 1 MiB.");let b;try{b=JSON.parse(await R(m,"utf8")).mcpServers?.pocolobby}catch{throw new Error("The MCP configuration is not valid JSON.")}if(!b||typeof b.command!="string"||!Array.isArray(b.args)||!b.args.every(T=>typeof T=="string"))throw new Error("The MCP configuration has no mcpServers.pocolobby entry with command and args.");const f=b.args,e=y(async T=>T!==void 0&&H(T)&&((await D(T).catch(()=>null))?.isFile()??!1),"exists"),A=b.command,r=f[0]??"",t=f[1]==="adapter"&&f[2]==="--config"?f[3]:void 0,w=j(import.meta.url),_=y(T=>{try{return k(T)}catch{return null}},"real"),n={mcp_config:m,command:{path:A,exists:await e(A),real_path:_(A)},module:{path:r,exists:await e(r),version:await e(r)?$(r):null,real_path:_(r)},credential_config:{path:t??null,exists:await e(t),broker_url:null},path_command:null,this_cli:{module:w,version:$(w),package_root:U(w)},same_install_as_path:null,problems:[]},E=Te(i);E&&(n.path_command={...E,version:E.module?$(E.module):null,package_root:E.module?U(E.module):null});const a=n.module.exists?U(r):null;a&&n.path_command?.package_root&&(n.same_install_as_path=a===n.path_command.package_root);const h=n.problems;if(n.command.exists||h.push(`Its command ${A} does not exist, so Claude cannot start the adapter.`),n.module.exists?n.module.version||h.push(`Its module ${r} is not part of PocoLobby.`):h.push(`Its module ${r} does not exist.`),f.length!==4||t===void 0)h.push('Its arguments are not "<module> adapter --config <file>".');else if(!n.credential_config.exists)h.push(`Its credential configuration ${t} does not exist.`);else if((await se(t).catch(()=>null))?.isSymbolicLink())h.push(`Its credential configuration ${t} is a symbolic link; the adapter refuses links. Point the MCP file at the file itself.`);else try{n.credential_config.broker_url=(await G(t)).config.url}catch(T){h.push(`Its credential configuration ${t} cannot be used: ${T.message}`)}return n.same_install_as_path!==!0&&n.module.version&&n.path_command?.version&&n.module.version!==n.path_command.version&&h.push(`It starts PocoLobby ${n.module.version}, but pocolobby on PATH is ${n.path_command.version} (${n.path_command.module}). Install the package and run mcp-config with the same Node and npm prefix, then save the file again.`),h.length&&h.push("Generate the file again with pocolobby mcp-config from the intended install."),n}y(He,"checkMcpConfig");async function je(){const m=Be(process.versions.node,process.execPath);try{if(m)throw new Error(m);await xe(process.argv.slice(2))}catch(i){const p=i instanceof Ee&&i.detail?`${i.message} ${i.detail}`:i instanceof be?`invalid arguments: ${i.issues.map(b=>`${b.path.join(".")||"value"}: ${b.message}`).join("; ")}`:i instanceof Error?i.message:"Command failed.";process.stderr.write(`pocolobby: ${p}
123
- `),process.exitCode=1}}y(je,"main"),process.argv[1]&&import.meta.url===pe(k(process.argv[1])).href&&je();export{He as checkMcpConfig,je as main,xe as runCli,$e as serverSettings};
122
+ `),`pocolobby: Git ignores ${b} through ${f}.`}y(Ue,"excludeFromGit");async function He(m,i){const u=await D(m);if(!u.isFile()||u.size>1024*1024)throw new Error("The MCP configuration must be a regular file smaller than 1 MiB.");let b;try{b=JSON.parse(await R(m,"utf8")).mcpServers?.pocolobby}catch{throw new Error("The MCP configuration is not valid JSON.")}if(!b||typeof b.command!="string"||!Array.isArray(b.args)||!b.args.every(T=>typeof T=="string"))throw new Error("The MCP configuration has no mcpServers.pocolobby entry with command and args.");const f=b.args,e=y(async T=>T!==void 0&&H(T)&&((await D(T).catch(()=>null))?.isFile()??!1),"exists"),A=b.command,r=f[0]??"",t=f[1]==="adapter"&&f[2]==="--config"?f[3]:void 0,w=j(import.meta.url),_=y(T=>{try{return M(T)}catch{return null}},"real"),n={mcp_config:m,command:{path:A,exists:await e(A),real_path:_(A)},module:{path:r,exists:await e(r),version:await e(r)?$(r):null,real_path:_(r)},credential_config:{path:t??null,exists:await e(t),broker_url:null},path_command:null,this_cli:{module:w,version:$(w),package_root:U(w)},same_install_as_path:null,problems:[]},E=Te(i);E&&(n.path_command={...E,version:E.module?$(E.module):null,package_root:E.module?U(E.module):null});const a=n.module.exists?U(r):null;a&&n.path_command?.package_root&&(n.same_install_as_path=a===n.path_command.package_root);const h=n.problems;if(n.command.exists||h.push(`Its command ${A} does not exist, so Claude cannot start the adapter.`),n.module.exists?n.module.version||h.push(`Its module ${r} is not part of PocoLobby.`):h.push(`Its module ${r} does not exist.`),f.length!==4||t===void 0)h.push('Its arguments are not "<module> adapter --config <file>".');else if(!n.credential_config.exists)h.push(`Its credential configuration ${t} does not exist.`);else if((await se(t).catch(()=>null))?.isSymbolicLink())h.push(`Its credential configuration ${t} is a symbolic link; the adapter refuses links. Point the MCP file at the file itself.`);else try{n.credential_config.broker_url=(await G(t)).config.url}catch(T){h.push(`Its credential configuration ${t} cannot be used: ${T.message}`)}return n.same_install_as_path!==!0&&n.module.version&&n.path_command?.version&&n.module.version!==n.path_command.version&&h.push(`It starts PocoLobby ${n.module.version}, but pocolobby on PATH is ${n.path_command.version} (${n.path_command.module}). Install the package and run mcp-config with the same Node and npm prefix, then save the file again.`),h.length&&h.push("Generate the file again with pocolobby mcp-config from the intended install."),n}y(He,"checkMcpConfig");async function je(){const m=Be(process.versions.node,process.execPath);try{if(m)throw new Error(m);await xe(process.argv.slice(2))}catch(i){const u=i instanceof Ee&&i.detail?`${i.message} ${i.detail}`:i instanceof be?`invalid arguments: ${i.issues.map(b=>`${b.path.join(".")||"value"}: ${b.message}`).join("; ")}`:i instanceof Error?i.message:"Command failed.";process.stderr.write(`pocolobby: ${u}
123
+ `),process.exitCode=1}}y(je,"main"),process.argv[1]&&import.meta.url===ue(M(process.argv[1])).href&&je();export{He as checkMcpConfig,je as main,xe as runCli,$e as serverSettings};