@gorlitzer-labs/apiary 1.13.3

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.
Files changed (45) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +328 -0
  3. package/dist/agent/index.d.ts +689 -0
  4. package/dist/agent/index.js +34 -0
  5. package/dist/agent/index.js.map +1 -0
  6. package/dist/chunk-5V7QLCGB.js +184 -0
  7. package/dist/chunk-5V7QLCGB.js.map +1 -0
  8. package/dist/chunk-AYQJIAR5.js +152 -0
  9. package/dist/chunk-AYQJIAR5.js.map +1 -0
  10. package/dist/chunk-BZ4VDWC2.js +76 -0
  11. package/dist/chunk-BZ4VDWC2.js.map +1 -0
  12. package/dist/chunk-CFY6Z6Q6.js +95 -0
  13. package/dist/chunk-CFY6Z6Q6.js.map +1 -0
  14. package/dist/chunk-CZHO4DBN.js +1719 -0
  15. package/dist/chunk-CZHO4DBN.js.map +1 -0
  16. package/dist/chunk-D7DXZQWT.js +208 -0
  17. package/dist/chunk-D7DXZQWT.js.map +1 -0
  18. package/dist/chunk-ED6ROH6B.js +2021 -0
  19. package/dist/chunk-ED6ROH6B.js.map +1 -0
  20. package/dist/chunk-PEB6HEFT.js +606 -0
  21. package/dist/chunk-PEB6HEFT.js.map +1 -0
  22. package/dist/chunk-QL66XSDB.js +157 -0
  23. package/dist/chunk-QL66XSDB.js.map +1 -0
  24. package/dist/chunk-TPNFOQA7.js +288 -0
  25. package/dist/chunk-TPNFOQA7.js.map +1 -0
  26. package/dist/chunk-ZEFRNAX6.js +1771 -0
  27. package/dist/chunk-ZEFRNAX6.js.map +1 -0
  28. package/dist/cli/index.d.ts +1 -0
  29. package/dist/cli/index.js +2432 -0
  30. package/dist/cli/index.js.map +1 -0
  31. package/dist/index-Dp3QSGog.d.ts +837 -0
  32. package/dist/index.d.ts +2 -0
  33. package/dist/index.js +22 -0
  34. package/dist/index.js.map +1 -0
  35. package/dist/invites-OFXIQLLN.js +23 -0
  36. package/dist/invites-OFXIQLLN.js.map +1 -0
  37. package/dist/join-CQXEF65B.js +15 -0
  38. package/dist/join-CQXEF65B.js.map +1 -0
  39. package/dist/room-Z7KDRVYD.js +1099 -0
  40. package/dist/room-Z7KDRVYD.js.map +1 -0
  41. package/dist/run-DOADB4T7.js +90 -0
  42. package/dist/run-DOADB4T7.js.map +1 -0
  43. package/dist/update-JGE3WCQB.js +11 -0
  44. package/dist/update-JGE3WCQB.js.map +1 -0
  45. package/package.json +72 -0
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/cli/invites.ts"],"sourcesContent":["/**\n * Invite queue — bridge between `apiary room create` (writer) and the agent\n * runtimes (reader).\n *\n * When the wizard background-spawns an agent, it stashes the room's join URL\n * at ~/.apiary/invites/<agentName>. On startup the agent runtime reads that\n * file and asks the LLM to call `join_room(url)`, so the agent shows up in the\n * room without the user having to paste anything.\n *\n * The invite is only *cleared* once the agent has actually joined. A CLI that\n * boots into a login screen, an onboarding prompt or a crash has not consumed\n * anything, and deleting the file there strands the agent outside the room with\n * nothing left to retry from — the URL is gone and `room resume` has no invite\n * to hand back. Read with `peekInvite`, delete with `clearInvite`, and let\n * `deliverInvite` sequence the two.\n */\n\nimport { existsSync, readFileSync, unlinkSync } from \"node:fs\";\nimport { join as pathJoin } from \"node:path\";\nimport { INVITES_DIR } from \"./serve.js\";\nimport type { ContentPart } from \"../agent/types.js\";\n\n/** Read the queued invite for an agent without removing it. Returns the join URL, or null. */\nexport function peekInvite(agentName: string): string | null {\n const path = pathJoin(INVITES_DIR, agentName);\n if (!existsSync(path)) return null;\n try {\n const url = readFileSync(path, \"utf-8\").trim();\n return url || null;\n } catch {\n return null;\n }\n}\n\n/** Remove the queued invite for an agent. Never throws. */\nexport function clearInvite(agentName: string): void {\n try {\n unlinkSync(pathJoin(INVITES_DIR, agentName));\n } catch {\n /* already gone */\n }\n}\n\n/** Read and remove the queued invite in one step. Returns the join URL, or null. */\nexport function consumeInvite(agentName: string): string | null {\n const url = peekInvite(agentName);\n if (url !== null) clearInvite(agentName);\n return url;\n}\n\n/**\n * True if two URLs point at the same apiary server.\n *\n * Used to tell \"the agent joined the room it was invited to\" from \"the agent\n * joined some other room\". Falls back to `true` on an unparseable URL: an\n * over-eager clear costs one un-auto-joined agent, whereas never clearing\n * leaves the runtime pestering an agent that is already in the room.\n */\nexport function sameApiaryServer(a: string, b: string): boolean {\n try {\n return new URL(a).origin === new URL(b).origin;\n } catch {\n return true;\n }\n}\n\n/** The prompt handed to the agent so it joins the room it was invited to. */\nexport function invitePrompt(url: string): ContentPart[] {\n return [{\n type: \"text\",\n text: `Please join the apiary room you were invited to by calling the join_room tool with this URL: ${url}`,\n }];\n}\n\nexport interface DeliverInviteOptions {\n agentName: string;\n /** Push the prompt at the agent (the runtime's tmux bridge / stdout writer). */\n deliver: (parts: ContentPart[]) => Promise<void> | void;\n /**\n * True once the agent is actually in the invited room — the only success\n * signal that counts. Receives the invite URL so the caller can tell the\n * invited room from some other room the agent joined on its own.\n */\n hasJoined: (inviteUrl: string) => boolean;\n /** How many times to hand the agent the invite. Default: 6. */\n maxAttempts?: number;\n /** Gap between attempts, also the post-delivery grace period (ms). Default: 20_000. */\n retryIntervalMs?: number;\n /** Cooperative cancellation — checked between polls. */\n signal?: AbortSignal;\n /** Injected for tests. */\n sleep?: (ms: number) => Promise<void>;\n}\n\nexport type DeliverInviteOutcome =\n | \"no-invite\" // nothing queued for this agent\n | \"joined\" // agent joined; invite cleared\n | \"abandoned\" // attempts exhausted; invite left on disk for the next launch\n | \"cancelled\"; // runtime shut down mid-delivery; invite left on disk\n\nconst POLL_STEP_MS = 500;\n\n/**\n * Hand an agent its queued invite and keep at it until the agent is really in\n * the room, then clear the invite.\n *\n * On give-up the invite file is deliberately left in place: the next\n * `apiary room resume` (or a manual relaunch) picks it straight back up, which\n * is the difference between \"the agent was slow to boot\" and \"the agent is\n * permanently locked out of the room\".\n */\nexport async function deliverInvite(opts: DeliverInviteOptions): Promise<DeliverInviteOutcome> {\n const {\n agentName,\n deliver,\n hasJoined,\n maxAttempts = 6,\n retryIntervalMs = 20_000,\n signal,\n // unref'd: a pending retry must never be the reason the process stays up.\n sleep = (ms: number) => new Promise<void>((r) => { setTimeout(r, ms).unref?.(); }),\n } = opts;\n\n const url = peekInvite(agentName);\n if (url === null) return \"no-invite\";\n\n // Already in a room (a resumed session, say) — nothing to ask for.\n if (hasJoined(url)) {\n clearInvite(agentName);\n return \"joined\";\n }\n\n const parts = invitePrompt(url);\n\n for (let attempt = 0; attempt < maxAttempts; attempt++) {\n if (signal?.aborted) return \"cancelled\";\n\n try {\n await deliver(parts);\n } catch {\n /* delivery is best-effort — a wedged pane still gets the next attempt */\n }\n\n // Poll in short steps so a join is noticed promptly and a shutdown isn't\n // stuck waiting out the full retry interval. Counted rather than\n // wall-clocked, so an injected instant `sleep` cannot spin hot.\n const steps = Math.max(1, Math.ceil(retryIntervalMs / POLL_STEP_MS));\n for (let step = 0; step < steps; step++) {\n if (signal?.aborted) return \"cancelled\";\n if (hasJoined(url)) {\n clearInvite(agentName);\n return \"joined\";\n }\n await sleep(POLL_STEP_MS);\n }\n }\n\n if (signal?.aborted) return \"cancelled\";\n if (hasJoined(url)) {\n clearInvite(agentName);\n return \"joined\";\n }\n\n return \"abandoned\";\n}\n"],"mappings":";;;;;AAiBA,SAAS,YAAY,cAAc,kBAAkB;AACrD,SAAS,QAAQ,gBAAgB;AAK1B,SAAS,WAAW,WAAkC;AAC3D,QAAM,OAAO,SAAS,aAAa,SAAS;AAC5C,MAAI,CAAC,WAAW,IAAI,EAAG,QAAO;AAC9B,MAAI;AACF,UAAM,MAAM,aAAa,MAAM,OAAO,EAAE,KAAK;AAC7C,WAAO,OAAO;AAAA,EAChB,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAGO,SAAS,YAAY,WAAyB;AACnD,MAAI;AACF,eAAW,SAAS,aAAa,SAAS,CAAC;AAAA,EAC7C,QAAQ;AAAA,EAER;AACF;AAGO,SAAS,cAAc,WAAkC;AAC9D,QAAM,MAAM,WAAW,SAAS;AAChC,MAAI,QAAQ,KAAM,aAAY,SAAS;AACvC,SAAO;AACT;AAUO,SAAS,iBAAiB,GAAW,GAAoB;AAC9D,MAAI;AACF,WAAO,IAAI,IAAI,CAAC,EAAE,WAAW,IAAI,IAAI,CAAC,EAAE;AAAA,EAC1C,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAGO,SAAS,aAAa,KAA4B;AACvD,SAAO,CAAC;AAAA,IACN,MAAM;AAAA,IACN,MAAM,gGAAgG,GAAG;AAAA,EAC3G,CAAC;AACH;AA4BA,IAAM,eAAe;AAWrB,eAAsB,cAAc,MAA2D;AAC7F,QAAM;AAAA,IACJ;AAAA,IACA;AAAA,IACA;AAAA,IACA,cAAc;AAAA,IACd,kBAAkB;AAAA,IAClB;AAAA;AAAA,IAEA,QAAQ,CAAC,OAAe,IAAI,QAAc,CAAC,MAAM;AAAE,iBAAW,GAAG,EAAE,EAAE,QAAQ;AAAA,IAAG,CAAC;AAAA,EACnF,IAAI;AAEJ,QAAM,MAAM,WAAW,SAAS;AAChC,MAAI,QAAQ,KAAM,QAAO;AAGzB,MAAI,UAAU,GAAG,GAAG;AAClB,gBAAY,SAAS;AACrB,WAAO;AAAA,EACT;AAEA,QAAM,QAAQ,aAAa,GAAG;AAE9B,WAAS,UAAU,GAAG,UAAU,aAAa,WAAW;AACtD,QAAI,QAAQ,QAAS,QAAO;AAE5B,QAAI;AACF,YAAM,QAAQ,KAAK;AAAA,IACrB,QAAQ;AAAA,IAER;AAKA,UAAM,QAAQ,KAAK,IAAI,GAAG,KAAK,KAAK,kBAAkB,YAAY,CAAC;AACnE,aAAS,OAAO,GAAG,OAAO,OAAO,QAAQ;AACvC,UAAI,QAAQ,QAAS,QAAO;AAC5B,UAAI,UAAU,GAAG,GAAG;AAClB,oBAAY,SAAS;AACrB,eAAO;AAAA,MACT;AACA,YAAM,MAAM,YAAY;AAAA,IAC1B;AAAA,EACF;AAEA,MAAI,QAAQ,QAAS,QAAO;AAC5B,MAAI,UAAU,GAAG,GAAG;AAClB,gBAAY,SAAS;AACrB,WAAO;AAAA,EACT;AAEA,SAAO;AACT;","names":[]}