agentix-cli 0.115.0 → 0.117.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.
Files changed (133) hide show
  1. package/apps/mac-voice/Sources/AgentXVoice/AnswerView.swift +24 -2
  2. package/apps/mac-voice/Sources/AgentXVoice/ListenAgain.swift +26 -0
  3. package/apps/mac-voice/Sources/AgentXVoice/main.swift +54 -0
  4. package/dist/{App-6OMMZW2M.js → App-UQP7UQYV.js} +2 -2
  5. package/dist/{ChatApp-EDDROHNA.js → ChatApp-VGSP5O6N.js} +2 -2
  6. package/dist/{agent-VPM3EEUB.js → agent-MO27U4Y7.js} +2 -2
  7. package/dist/{board-dashboard-4GQ7RTH3.js → board-dashboard-CSS7XMIZ.js} +255 -224
  8. package/dist/board-dashboard-CSS7XMIZ.js.map +1 -0
  9. package/dist/chunk-2WK5A3UV.js +482 -0
  10. package/dist/chunk-2WK5A3UV.js.map +1 -0
  11. package/dist/{chunk-S4XSVAAG.js → chunk-45GOH6F7.js} +2 -2
  12. package/dist/chunk-45YETJY4.js +2 -0
  13. package/dist/chunk-45YETJY4.js.map +1 -0
  14. package/dist/{chunk-CJJULHPJ.js → chunk-4ELAUGOP.js} +4 -4
  15. package/dist/{chunk-5FY7PWXW.js → chunk-5PPMPCHG.js} +2 -2
  16. package/dist/{chunk-BU4LE2RT.js → chunk-746KHKT4.js} +2 -2
  17. package/dist/{chunk-QLB76BGE.js → chunk-BQ2HJ7TS.js} +2 -2
  18. package/dist/{chunk-PITMPRVP.js → chunk-CKQ2YDFP.js} +2 -2
  19. package/dist/{chunk-7T7IXLLA.js → chunk-CUZTLQH2.js} +2 -2
  20. package/dist/chunk-DMHQIACQ.js +3 -0
  21. package/dist/chunk-DMHQIACQ.js.map +1 -0
  22. package/dist/chunk-EMGB23H5.js +3 -0
  23. package/dist/chunk-EMGB23H5.js.map +1 -0
  24. package/dist/chunk-FJI5GRBH.js +54 -0
  25. package/dist/chunk-FJI5GRBH.js.map +1 -0
  26. package/dist/chunk-GRMCAO3Q.js +2 -0
  27. package/dist/chunk-GRMCAO3Q.js.map +1 -0
  28. package/dist/{chunk-PX2AOZ5G.js → chunk-HVZVFCJX.js} +2 -2
  29. package/dist/{chunk-BXYKFWAI.js → chunk-HYGMWCUU.js} +2 -2
  30. package/dist/{chunk-ECBVOIIK.js → chunk-IZMXAXW3.js} +182 -182
  31. package/dist/chunk-IZMXAXW3.js.map +1 -0
  32. package/dist/{chunk-YE4HKOS5.js → chunk-J2YLOGNN.js} +2 -2
  33. package/dist/{chunk-2NYP4OQU.js → chunk-LNY6N73E.js} +4 -4
  34. package/dist/{chunk-2NYP4OQU.js.map → chunk-LNY6N73E.js.map} +1 -1
  35. package/dist/{chunk-EVXL6X2R.js → chunk-MSP25HE5.js} +58 -58
  36. package/dist/{chunk-EVXL6X2R.js.map → chunk-MSP25HE5.js.map} +1 -1
  37. package/dist/{chunk-MG5LRE5B.js → chunk-OJ7KM2UO.js} +2 -2
  38. package/dist/{chunk-4STXRZZS.js → chunk-PFK3QO6S.js} +2 -2
  39. package/dist/{chunk-K3BG77KK.js → chunk-PMQ47IPT.js} +2 -2
  40. package/dist/{chunk-KTF4YF4M.js → chunk-T2VDHVYW.js} +2 -2
  41. package/dist/{chunk-J5TZ6QGD.js → chunk-VEHTVYP6.js} +2 -2
  42. package/dist/{chunk-SDOSQ6TJ.js → chunk-VRXJW6JJ.js} +2 -2
  43. package/dist/{chunk-UQX2HY5M.js → chunk-W7WNRPNQ.js} +2 -2
  44. package/dist/cli.js +1 -1
  45. package/dist/{client-VUNPLVCG.js → client-5UMNDY7Z.js} +2 -2
  46. package/dist/{config-HE2LGTTG.js → config-O44DOHFW.js} +2 -2
  47. package/dist/config-mutator-PRLY2TCE.js +2 -0
  48. package/dist/doctor-NKPH74F7.js +2 -0
  49. package/dist/index.d.ts +55 -5
  50. package/dist/index.js +1 -1
  51. package/dist/index.js.map +1 -1
  52. package/dist/{program-53CQJEUZ.js → program-RHIJYCEJ.js} +191 -187
  53. package/dist/program-RHIJYCEJ.js.map +1 -0
  54. package/dist/{promote-4PPJJ6AW.js → promote-ZRNVPWTD.js} +2 -2
  55. package/dist/push-DID6RZYI.js +2 -0
  56. package/dist/push-bridge-VPTQNM43.js +2 -0
  57. package/dist/push-store-L5QHMSST.js +2 -0
  58. package/dist/{query-ETDKC7WC.js → query-HURONGKA.js} +2 -2
  59. package/dist/{registry-AMETOJ3S.js → registry-AYGFAKTC.js} +2 -2
  60. package/dist/{request-planner-VFWWT5XR.js → request-planner-ZZRSOBQZ.js} +2 -2
  61. package/dist/{review-candidates-2PI4CGZO.js → review-candidates-KHH47PK7.js} +2 -2
  62. package/dist/routing-GUBKKWPT.js +2 -0
  63. package/dist/schedule-tool-VH77T3N3.js +2 -0
  64. package/dist/scheduler-SZ4YYXJE.js +2 -0
  65. package/dist/{seat-TVNR245I.js → seat-CVTTTE5V.js} +2 -2
  66. package/dist/{select-KY7B4HAS.js → select-OUTM6OBC.js} +2 -2
  67. package/dist/{set-enabled-NEINY2I2.js → set-enabled-2QKQRVUN.js} +2 -2
  68. package/dist/token-store-AY6OBDVI.js +2 -0
  69. package/dist/token-store-AY6OBDVI.js.map +1 -0
  70. package/dist/{tool-5JGMWH62.js → tool-OFXHMLE5.js} +2 -2
  71. package/dist/{tool-MQQ2W5LJ.js → tool-XY7QGHLV.js} +2 -2
  72. package/dist/wiki-46GMWX34.js +2 -0
  73. package/dist/wiki-46GMWX34.js.map +1 -0
  74. package/package.json +1 -1
  75. package/dist/board-dashboard-4GQ7RTH3.js.map +0 -1
  76. package/dist/chunk-2QSG53RN.js +0 -482
  77. package/dist/chunk-2QSG53RN.js.map +0 -1
  78. package/dist/chunk-ACFQBLPX.js +0 -3
  79. package/dist/chunk-ACFQBLPX.js.map +0 -1
  80. package/dist/chunk-ECBVOIIK.js.map +0 -1
  81. package/dist/chunk-IGORU3XR.js +0 -54
  82. package/dist/chunk-IGORU3XR.js.map +0 -1
  83. package/dist/config-mutator-22AVTST2.js +0 -2
  84. package/dist/doctor-6RDRST4G.js +0 -2
  85. package/dist/program-53CQJEUZ.js.map +0 -1
  86. package/dist/push-HEDA6P3B.js +0 -2
  87. package/dist/push-HEDA6P3B.js.map +0 -1
  88. package/dist/push-store-5VJ4FNI4.js +0 -2
  89. package/dist/routing-M7MDLD7Q.js +0 -2
  90. package/dist/schedule-tool-2EQ53IOQ.js +0 -2
  91. package/dist/scheduler-YGVINPZF.js +0 -2
  92. package/dist/token-store-YBSU2DTV.js +0 -2
  93. package/dist/wiki-COAUQ6TQ.js +0 -2
  94. /package/dist/{App-6OMMZW2M.js.map → App-UQP7UQYV.js.map} +0 -0
  95. /package/dist/{ChatApp-EDDROHNA.js.map → ChatApp-VGSP5O6N.js.map} +0 -0
  96. /package/dist/{agent-VPM3EEUB.js.map → agent-MO27U4Y7.js.map} +0 -0
  97. /package/dist/{chunk-S4XSVAAG.js.map → chunk-45GOH6F7.js.map} +0 -0
  98. /package/dist/{chunk-CJJULHPJ.js.map → chunk-4ELAUGOP.js.map} +0 -0
  99. /package/dist/{chunk-5FY7PWXW.js.map → chunk-5PPMPCHG.js.map} +0 -0
  100. /package/dist/{chunk-BU4LE2RT.js.map → chunk-746KHKT4.js.map} +0 -0
  101. /package/dist/{chunk-QLB76BGE.js.map → chunk-BQ2HJ7TS.js.map} +0 -0
  102. /package/dist/{chunk-PITMPRVP.js.map → chunk-CKQ2YDFP.js.map} +0 -0
  103. /package/dist/{chunk-7T7IXLLA.js.map → chunk-CUZTLQH2.js.map} +0 -0
  104. /package/dist/{chunk-PX2AOZ5G.js.map → chunk-HVZVFCJX.js.map} +0 -0
  105. /package/dist/{chunk-BXYKFWAI.js.map → chunk-HYGMWCUU.js.map} +0 -0
  106. /package/dist/{chunk-YE4HKOS5.js.map → chunk-J2YLOGNN.js.map} +0 -0
  107. /package/dist/{chunk-MG5LRE5B.js.map → chunk-OJ7KM2UO.js.map} +0 -0
  108. /package/dist/{chunk-4STXRZZS.js.map → chunk-PFK3QO6S.js.map} +0 -0
  109. /package/dist/{chunk-K3BG77KK.js.map → chunk-PMQ47IPT.js.map} +0 -0
  110. /package/dist/{chunk-KTF4YF4M.js.map → chunk-T2VDHVYW.js.map} +0 -0
  111. /package/dist/{chunk-J5TZ6QGD.js.map → chunk-VEHTVYP6.js.map} +0 -0
  112. /package/dist/{chunk-SDOSQ6TJ.js.map → chunk-VRXJW6JJ.js.map} +0 -0
  113. /package/dist/{chunk-UQX2HY5M.js.map → chunk-W7WNRPNQ.js.map} +0 -0
  114. /package/dist/{client-VUNPLVCG.js.map → client-5UMNDY7Z.js.map} +0 -0
  115. /package/dist/{config-HE2LGTTG.js.map → config-O44DOHFW.js.map} +0 -0
  116. /package/dist/{config-mutator-22AVTST2.js.map → config-mutator-PRLY2TCE.js.map} +0 -0
  117. /package/dist/{doctor-6RDRST4G.js.map → doctor-NKPH74F7.js.map} +0 -0
  118. /package/dist/{promote-4PPJJ6AW.js.map → promote-ZRNVPWTD.js.map} +0 -0
  119. /package/dist/{push-store-5VJ4FNI4.js.map → push-DID6RZYI.js.map} +0 -0
  120. /package/dist/{query-ETDKC7WC.js.map → push-bridge-VPTQNM43.js.map} +0 -0
  121. /package/dist/{registry-AMETOJ3S.js.map → push-store-L5QHMSST.js.map} +0 -0
  122. /package/dist/{routing-M7MDLD7Q.js.map → query-HURONGKA.js.map} +0 -0
  123. /package/dist/{schedule-tool-2EQ53IOQ.js.map → registry-AYGFAKTC.js.map} +0 -0
  124. /package/dist/{request-planner-VFWWT5XR.js.map → request-planner-ZZRSOBQZ.js.map} +0 -0
  125. /package/dist/{review-candidates-2PI4CGZO.js.map → review-candidates-KHH47PK7.js.map} +0 -0
  126. /package/dist/{scheduler-YGVINPZF.js.map → routing-GUBKKWPT.js.map} +0 -0
  127. /package/dist/{seat-TVNR245I.js.map → schedule-tool-VH77T3N3.js.map} +0 -0
  128. /package/dist/{token-store-YBSU2DTV.js.map → scheduler-SZ4YYXJE.js.map} +0 -0
  129. /package/dist/{wiki-COAUQ6TQ.js.map → seat-CVTTTE5V.js.map} +0 -0
  130. /package/dist/{select-KY7B4HAS.js.map → select-OUTM6OBC.js.map} +0 -0
  131. /package/dist/{set-enabled-NEINY2I2.js.map → set-enabled-2QKQRVUN.js.map} +0 -0
  132. /package/dist/{tool-5JGMWH62.js.map → tool-OFXHMLE5.js.map} +0 -0
  133. /package/dist/{tool-MQQ2W5LJ.js.map → tool-XY7QGHLV.js.map} +0 -0
@@ -0,0 +1,2 @@
1
+ import{a as c}from"./chunk-KZKDVIOE.js";function f(n,e){return`${n}:${e}`}function m(n){return n.includes(":")}var P="/app#alerts",h=3e3,x=2,w=40,A=120,k=1e3;function M(n,e="AgentX"){let o=c(n.text||""),r=(n.buttons??[]).filter(t=>t.url&&t.url.length<=k).slice(0,x).map((t,d)=>({action:`b${d}`,title:g(t.label,w),url:t.url})),s={title:g(o.title||e,A),body:o.body,url:r[0]?.url??P,actions:r},a=()=>Buffer.byteLength(JSON.stringify(s),"utf8");if(a()>h){let t=[...s.body],d=a()-h;for(t=t.slice(0,Math.max(0,t.length-d-1)),s.body=t.join("")+"\u2026";a()>h&&t.length>0;)t=t.slice(0,Math.max(0,t.length-32)),s.body=t.join("")+"\u2026"}return s}function g(n,e){let o=[...n];return o.length>e?o.slice(0,e-1).join("")+"\u2026":n}var y=class{constructor(e){this.deps=e;this.log=e.log??console.error.bind(console,"[push]")}name="push";log;async start(){let e=this.deps.store.list().length;this.log(`push: ready (${e} subscribed phone${e===1?"":"s"})${this.deps.keys()?"":" \u2014 no keys yet, run: agentx app push-keys"}`)}async stop(){}onMessage(e){}async send(e){let o=this.deps.keys();if(!o)throw new Error("push: no keys \u2014 run `agentx app push-keys` on this node");let r=(e.chatId||"").trim(),s=r&&r!=="default"?r:void 0;s&&e.origin&&!m(s)&&(s=f(e.origin,s));let a=[];for(let i of this.deps.store.list(s))this.deps.deviceActive(i.deviceId)&&i.publicKey===o.publicKey?a.push(i):this.deps.store.unsubscribe(i.endpoint);if(a.length===0)throw new Error(s?`push: phone ${s} has not turned on notifications`:"push: no phone has turned on notifications \u2014 open Alerts in the phone app");let t=M(e),d=JSON.stringify(t),v={vapidDetails:{subject:this.deps.subject,publicKey:o.publicKey,privateKey:o.privateKey},TTL:this.deps.ttlSeconds},u=0,l=[];if(await Promise.all(a.map(async i=>{try{await this.deps.sender({endpoint:i.endpoint,keys:{p256dh:i.p256dh,auth:i.auth}},d,v),u++}catch(p){p?.statusCode===404||p?.statusCode===410?(this.deps.store.unsubscribe(i.endpoint),this.log(`push: removed expired subscription for ${i.deviceName}`)):l.push(`${i.deviceName}: ${p?.statusCode?`HTTP ${p.statusCode} `:""}${p?.body||p?.message||p}`.slice(0,200))}})),u===0)throw new Error(`push: not delivered \u2014 ${l.join("; ")||"every subscription had expired"}`);return l.length&&this.log(`push: ${l.length} phone(s) failed: ${l.join("; ")}`),this.deps.store.log({title:t.title,body:t.body,url:t.url,delivered:u,deviceId:s??null},this.deps.keepRecent),String(u)}},b=class{constructor(e,o,r=console.error.bind(console,"[push]"),s){this.peer=e;this.forward=o;this.log=r;this.origin=s}name="push";async start(){this.log(`push: relaying to ${this.peer}`)}async stop(){}onMessage(e){}async send(e){if(e.relayed)throw new Error(`push: this node relays too (channels.push.relayTo = ${this.peer}); set relayTo only on nodes that don't host the phone app`);return this.forward(this.peer,{channel:"push",chatId:e.chatId||"default",text:e.text,...e.buttons?.length?{buttons:e.buttons}:{},relayed:!0,...this.origin?{origin:this.origin}:{}})}};export{f as a,m as b,P as c,h as d,M as e,y as f,b as g};
2
+ //# sourceMappingURL=chunk-GRMCAO3Q.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/channels/push.ts"],"sourcesContent":["import type { ChannelAdapter, IncomingMessage, OutgoingMessage } from \"./types\"\nimport type { PushStore, PushSubscriptionRow } from \"./push-store\"\nimport type { PushKeys } from \"./push-keys\"\nimport { splitTitle } from \"./ntfy\"\n\n// --- push channel — Web Push to the phone app ---\n//\n// Outbound only, like ntfy, and registered as a ChannelAdapter for the same\n// reason: notifications.destination, POST /send, `agentx notify`, cron\n// failure pings and Focus digests all reach it through router.sendOutbound().\n//\n// One node hosts the phone app (/app) and so holds the subscriptions; it\n// runs PushAdapter. Every other node runs PushRelayAdapter under the same\n// channel name, which forwards to the host over the mesh, so callers never\n// need to know where the phone is paired.\n//\n// Addressing: `chatId` \"default\" (or empty) means every subscribed phone;\n// anything else is one phone's device id (the tok_… id from\n// `agentx app devices`).\n//\n// A phone paired with a relaying node subscribes on the host too, through\n// that node (push-bridge.ts). Its rows carry a scoped device id,\n// \"<node>:<tok_…>\", so two nodes' token ids never collide, and a push the\n// relay addresses to one of its phones (chatId tok_…, origin <node>) is\n// mapped to that id here (#711).\n\n/** Device id on the host for a phone paired with relaying node `origin`. */\nexport function remoteDeviceId(origin: string, deviceId: string): string {\n return `${origin}:${deviceId}`\n}\n\n/** True for a scoped id (remoteDeviceId); local token ids have no colon. */\nexport function isRemoteDevice(deviceId: string): boolean {\n return deviceId.includes(\":\")\n}\n\n/** Where a tap lands when the message has no button of its own. */\nexport const DEFAULT_OPEN_URL = \"/app#alerts\"\n/** Push services refuse payloads over 4096 bytes after encryption (413,\n * which is not retried). The JSON is kept well under that, in bytes. */\nexport const MAX_PAYLOAD_BYTES = 3000\n/** Chrome shows at most two action buttons. */\nconst MAX_ACTIONS = 2\nconst MAX_LABEL = 40\nconst MAX_TITLE = 120\n/** Longer links are dropped rather than cut, since a cut link is broken. */\nconst MAX_URL = 1000\n\nexport interface PushPayload {\n title: string\n body: string\n /** Opened when the notification itself is tapped. */\n url: string\n actions: Array<{ action: string; title: string; url: string }>\n}\n\n/** What web-push's sendNotification needs; injected so tests stay offline. */\nexport type PushSender = (\n sub: { endpoint: string; keys: { p256dh: string; auth: string } },\n payload: string,\n opts: { vapidDetails: { subject: string; publicKey: string; privateKey: string }; TTL: number },\n) => Promise<unknown>\n\nexport interface PushAdapterDeps {\n store: PushStore\n keys: () => PushKeys | null\n /** mailto: or https: contact the push services can reach you at. */\n subject: string\n ttlSeconds: number\n keepRecent: number\n /** False for a phone whose device token was revoked or expired. */\n deviceActive: (deviceId: string) => boolean\n sender: PushSender\n log?: (...args: unknown[]) => void\n}\n\nexport function buildPushPayload(msg: OutgoingMessage, defaultTitle = \"AgentX\"): PushPayload {\n const split = splitTitle(msg.text || \"\")\n const actions = (msg.buttons ?? [])\n .filter((b) => b.url && b.url.length <= MAX_URL)\n .slice(0, MAX_ACTIONS)\n .map((b, i) => ({ action: `b${i}`, title: clip(b.label, MAX_LABEL), url: b.url }))\n const payload: PushPayload = {\n title: clip(split.title || defaultTitle, MAX_TITLE),\n body: split.body,\n url: actions[0]?.url ?? DEFAULT_OPEN_URL,\n actions,\n }\n // Trim the body by bytes, not characters: Arabic, CJK and emoji take\n // several bytes each.\n const size = () => Buffer.byteLength(JSON.stringify(payload), \"utf8\")\n if (size() > MAX_PAYLOAD_BYTES) {\n let chars = [...payload.body]\n const over = size() - MAX_PAYLOAD_BYTES\n chars = chars.slice(0, Math.max(0, chars.length - over - 1))\n payload.body = chars.join(\"\") + \"…\"\n while (size() > MAX_PAYLOAD_BYTES && chars.length > 0) {\n chars = chars.slice(0, Math.max(0, chars.length - 32))\n payload.body = chars.join(\"\") + \"…\"\n }\n }\n return payload\n}\n\nfunction clip(s: string, max: number): string {\n const chars = [...s]\n return chars.length > max ? chars.slice(0, max - 1).join(\"\") + \"…\" : s\n}\n\nexport class PushAdapter implements ChannelAdapter {\n readonly name = \"push\"\n private log: (...args: unknown[]) => void\n\n constructor(private deps: PushAdapterDeps) {\n this.log = deps.log ?? console.error.bind(console, \"[push]\")\n }\n\n async start(): Promise<void> {\n const n = this.deps.store.list().length\n this.log(`push: ready (${n} subscribed phone${n === 1 ? \"\" : \"s\"})${this.deps.keys() ? \"\" : \" — no keys yet, run: agentx app push-keys\"}`)\n }\n\n async stop(): Promise<void> {}\n\n onMessage(_handler: (msg: IncomingMessage) => Promise<void>): void {}\n\n async send(msg: OutgoingMessage & { origin?: string }): Promise<string | void> {\n const keys = this.deps.keys()\n if (!keys) throw new Error(\"push: no keys — run `agentx app push-keys` on this node\")\n const requested = (msg.chatId || \"\").trim()\n let device = requested && requested !== \"default\" ? requested : undefined\n // A relay addressed one of its own phones: only the id it has here, so\n // a token id that happens to match a phone paired here never gets it.\n if (device && msg.origin && !isRemoteDevice(device)) device = remoteDeviceId(msg.origin, device)\n\n const subs: PushSubscriptionRow[] = []\n for (const s of this.deps.store.list(device)) {\n // A revoked phone stops getting pushes even if its browser never\n // unsubscribed, and a row made with replaced keys can never be\n // delivered; either goes, so it isn't retried every time. The phone\n // re-subscribes with the new key when the app next opens.\n if (this.deps.deviceActive(s.deviceId) && s.publicKey === keys.publicKey) subs.push(s)\n else this.deps.store.unsubscribe(s.endpoint)\n }\n if (subs.length === 0) {\n throw new Error(device\n ? `push: phone ${device} has not turned on notifications`\n : \"push: no phone has turned on notifications — open Alerts in the phone app\")\n }\n\n const payload = buildPushPayload(msg)\n const body = JSON.stringify(payload)\n const opts = {\n vapidDetails: { subject: this.deps.subject, publicKey: keys.publicKey, privateKey: keys.privateKey },\n TTL: this.deps.ttlSeconds,\n }\n let delivered = 0\n const errors: string[] = []\n await Promise.all(subs.map(async (s) => {\n try {\n await this.deps.sender({ endpoint: s.endpoint, keys: { p256dh: s.p256dh, auth: s.auth } }, body, opts)\n delivered++\n } catch (e: any) {\n // 404/410: the browser dropped the subscription (app removed,\n // permission withdrawn). Anything else may be temporary; keep it.\n if (e?.statusCode === 404 || e?.statusCode === 410) {\n this.deps.store.unsubscribe(s.endpoint)\n this.log(`push: removed expired subscription for ${s.deviceName}`)\n } else {\n errors.push(`${s.deviceName}: ${e?.statusCode ? `HTTP ${e.statusCode} ` : \"\"}${e?.body || e?.message || e}`.slice(0, 200))\n }\n }\n }))\n\n if (delivered === 0) throw new Error(`push: not delivered — ${errors.join(\"; \") || \"every subscription had expired\"}`)\n if (errors.length) this.log(`push: ${errors.length} phone(s) failed: ${errors.join(\"; \")}`)\n this.deps.store.log({ title: payload.title, body: payload.body, url: payload.url, delivered, deviceId: device ?? null }, this.deps.keepRecent)\n return String(delivered)\n }\n}\n\n/** Payload for the host's POST /channel/send. */\nexport interface PushRelayPayload {\n channel: \"push\"\n chatId: string\n text: string\n buttons?: OutgoingMessage[\"buttons\"]\n relayed: true\n /** The relaying node's name, so the host can find its phones. */\n origin?: string\n}\n\n/** The `push` channel on a node that doesn't host the phone app: forwards\n * each message to the host (channels.push.relayTo) over the mesh. */\nexport class PushRelayAdapter implements ChannelAdapter {\n readonly name = \"push\"\n\n constructor(\n private peer: string,\n private forward: (peer: string, payload: PushRelayPayload) => Promise<string | void>,\n private log: (...args: unknown[]) => void = console.error.bind(console, \"[push]\"),\n private origin?: string,\n ) {}\n\n async start(): Promise<void> {\n this.log(`push: relaying to ${this.peer}`)\n }\n\n async stop(): Promise<void> {}\n\n onMessage(_handler: (msg: IncomingMessage) => Promise<void>): void {}\n\n async send(msg: OutgoingMessage & { relayed?: boolean }): Promise<string | void> {\n // Two nodes each set to relay to the other would bounce a message forever.\n if (msg.relayed) throw new Error(`push: this node relays too (channels.push.relayTo = ${this.peer}); set relayTo only on nodes that don't host the phone app`)\n return this.forward(this.peer, {\n channel: \"push\",\n chatId: msg.chatId || \"default\",\n text: msg.text,\n ...(msg.buttons?.length ? { buttons: msg.buttons } : {}),\n relayed: true,\n ...(this.origin ? { origin: this.origin } : {}),\n })\n }\n}\n"],"mappings":"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","names":["remoteDeviceId","origin","deviceId","isRemoteDevice","DEFAULT_OPEN_URL","MAX_PAYLOAD_BYTES","MAX_ACTIONS","MAX_LABEL","MAX_TITLE","MAX_URL","buildPushPayload","msg","defaultTitle","split","splitTitle","actions","b","i","clip","payload","size","chars","over","s","max","PushAdapter","deps","n","_handler","keys","requested","device","subs","body","opts","delivered","errors","e","PushRelayAdapter","peer","forward","log"]}
@@ -1,5 +1,5 @@
1
- import{ha as m,ia as $,ma as x}from"./chunk-IGORU3XR.js";x();import{readFileSync as S,writeFileSync as P,existsSync as b}from"fs";import{resolve as f}from"path";function w(r){if(r)return f(r);let e=[f(process.cwd(),"agentx.json"),f(process.cwd(),".agentx/config.json")];for(let n of e)if(b(n))return n;return e[0]}function v(r){return JSON.parse(JSON.stringify(r))}async function O(r){try{let e=await fetch(`${r.replace(/\/$/,"")}/reload`,{method:"POST",signal:AbortSignal.timeout(3e3)});return e.ok?{ok:!0}:{ok:!1,reason:`HTTP ${e.status}`}}catch(e){return{ok:!1,reason:e?.cause?.code||e?.message||"unreachable"}}}async function J(r,e={}){let{validate:n=!0,dryRun:t=!1,reload:s=!0,configPath:u,daemonUrl:c}=e,o=w(u);if(!b(o))return{success:!1,path:o,error:`Config not found at ${o}. Run \`agentx init\` first.`};let d;try{d=S(o,"utf-8")}catch(a){return{success:!1,path:o,error:`Cannot read ${o}: ${a.message}`}}let g;try{g=JSON.parse(d)}catch(a){return{success:!1,path:o,error:`Invalid JSON in ${o}: ${a.message}`}}let i=v(g);try{await r(i)}catch(a){return{success:!1,path:o,error:`Mutator threw: ${a.message}`}}if(n){let a=$(i),l=m.safeParse(a);if(!l.success){let k=l.error.issues.map(y=>` ${y.path.join(".")||"<root>"}: ${y.message}`).join(`
1
+ import{ha as m,ia as $,ma as x}from"./chunk-FJI5GRBH.js";x();import{readFileSync as S,writeFileSync as P,existsSync as b}from"fs";import{resolve as f}from"path";function w(r){if(r)return f(r);let e=[f(process.cwd(),"agentx.json"),f(process.cwd(),".agentx/config.json")];for(let n of e)if(b(n))return n;return e[0]}function v(r){return JSON.parse(JSON.stringify(r))}async function O(r){try{let e=await fetch(`${r.replace(/\/$/,"")}/reload`,{method:"POST",signal:AbortSignal.timeout(3e3)});return e.ok?{ok:!0}:{ok:!1,reason:`HTTP ${e.status}`}}catch(e){return{ok:!1,reason:e?.cause?.code||e?.message||"unreachable"}}}async function J(r,e={}){let{validate:n=!0,dryRun:t=!1,reload:s=!0,configPath:u,daemonUrl:c}=e,o=w(u);if(!b(o))return{success:!1,path:o,error:`Config not found at ${o}. Run \`agentx init\` first.`};let d;try{d=S(o,"utf-8")}catch(a){return{success:!1,path:o,error:`Cannot read ${o}: ${a.message}`}}let g;try{g=JSON.parse(d)}catch(a){return{success:!1,path:o,error:`Invalid JSON in ${o}: ${a.message}`}}let i=v(g);try{await r(i)}catch(a){return{success:!1,path:o,error:`Mutator threw: ${a.message}`}}if(n){let a=$(i),l=m.safeParse(a);if(!l.success){let k=l.error.issues.map(y=>` ${y.path.join(".")||"<root>"}: ${y.message}`).join(`
2
2
  `);return{success:!1,path:o,error:`Validation failed:
3
3
  ${k}`,after:i}}}if(t)return{success:!0,path:o,after:i,dryRun:!0};try{P(o,JSON.stringify(i,null,2)+`
4
4
  `)}catch(a){return{success:!1,path:o,error:`Write failed: ${a.message}`,after:i}}let p=!1,h;if(s){let a=c||R(i),l=await O(a);l.ok?p=!0:h=l.reason}return{success:!0,path:o,after:i,reloaded:p,reloadSkipped:h}}function R(r){let e=r?.node?.bind;if(!e)return"http://127.0.0.1:18800";let[n,t]=e.split(":");return`http://${n==="0.0.0.0"||n==="::"?"127.0.0.1":n}:${t}`}function N(r,e,n){let t=e.split("."),s=r;for(let u=0;u<t.length-1;u++){let c=t[u];(s[c]===void 0||s[c]===null)&&(s[c]={}),s=s[c]}s[t[t.length-1]]=n}function j(r,e){let n=e.split("."),t=r;for(let s of n){if(t==null)return;t=t[s]}return t}function A(r,e){let n=e.split("."),t=r;for(let s=0;s<n.length-1;s++){if(t==null)return;t=t[n[s]]}t!=null&&delete t[n[n.length-1]]}export{w as a,J as b,N as c,j as d,A as e};
5
- //# sourceMappingURL=chunk-PX2AOZ5G.js.map
5
+ //# sourceMappingURL=chunk-HVZVFCJX.js.map
@@ -1,4 +1,4 @@
1
- import{b as S,c as O}from"./chunk-PX2AOZ5G.js";import{a as I,b as X}from"./chunk-FCPTN6NF.js";import{a as F,b as oe}from"./chunk-7I7IEX4S.js";import{d as M}from"./chunk-QIJLFPWE.js";import{execFile as Le}from"child_process";import{writeFileSync as ee,mkdirSync as w,existsSync as b,readFileSync as $e}from"fs";import{resolve as _}from"path";var ce=["off","shadow","authoritative"],ae={telegram:"INTENT_LEDGER_MODE_TELEGRAM",slack:"INTENT_LEDGER_MODE_SLACK",whatsapp:"INTENT_LEDGER_MODE_WHATSAPP",discord:"INTENT_LEDGER_MODE_DISCORD",gitlab:"INTENT_LEDGER_MODE_GITLAB",github:"INTENT_LEDGER_MODE_GITHUB",workflow:"INTENT_LEDGER_MODE_WORKFLOW",cron:"INTENT_LEDGER_MODE_CRON",mesh:"INTENT_LEDGER_MODE_MESH"},de="INTENT_LEDGER_MODE";function B(n,e=process.env){let t=P(e[ae[n]]);if(t)return t;let i=P(e[de]);return i||"off"}function P(n){if(typeof n!="string")return null;let e=n.trim().toLowerCase();return ce.includes(e)?e:null}X();import ue from"better-sqlite3";import{existsSync as Pe,mkdirSync as le}from"fs";import{dirname as ge,resolve as me}from"path";var T=class{db;path;constructor(e={}){this.path=me(process.cwd(),e.path??".agentx/intent/ledger.sqlite"),le(ge(this.path),{recursive:!0}),this.db=new ue(this.path),this.db.pragma("journal_mode = WAL"),this.db.pragma("synchronous = NORMAL"),this.db.pragma("foreign_keys = ON"),fe(this.db)}close(){this.db.close()}schemaVersion(){return this.db.prepare("SELECT MAX(v) AS v FROM schema_version").get().v??0}recordEvent(e){if(e.sourceEventId!==null){let i=this.findEventBySourceId(e.source,e.sourceEventId);if(i)return i}let t={id:e.id??I(e.ts),ts:e.ts,source:e.source,sourceEventId:e.sourceEventId,project:e.project,subject:e.subject,intent:e.intent,rawJson:e.rawJson};return this.db.prepare(`INSERT INTO intent_events (id, ts, source, source_event_id, project, subject, intent, raw_json)
1
+ import{b as S,c as O}from"./chunk-HVZVFCJX.js";import{a as I,b as X}from"./chunk-FCPTN6NF.js";import{a as F,b as oe}from"./chunk-7I7IEX4S.js";import{d as M}from"./chunk-QIJLFPWE.js";import{execFile as Le}from"child_process";import{writeFileSync as ee,mkdirSync as w,existsSync as b,readFileSync as $e}from"fs";import{resolve as _}from"path";var ce=["off","shadow","authoritative"],ae={telegram:"INTENT_LEDGER_MODE_TELEGRAM",slack:"INTENT_LEDGER_MODE_SLACK",whatsapp:"INTENT_LEDGER_MODE_WHATSAPP",discord:"INTENT_LEDGER_MODE_DISCORD",gitlab:"INTENT_LEDGER_MODE_GITLAB",github:"INTENT_LEDGER_MODE_GITHUB",workflow:"INTENT_LEDGER_MODE_WORKFLOW",cron:"INTENT_LEDGER_MODE_CRON",mesh:"INTENT_LEDGER_MODE_MESH"},de="INTENT_LEDGER_MODE";function B(n,e=process.env){let t=P(e[ae[n]]);if(t)return t;let i=P(e[de]);return i||"off"}function P(n){if(typeof n!="string")return null;let e=n.trim().toLowerCase();return ce.includes(e)?e:null}X();import ue from"better-sqlite3";import{existsSync as Pe,mkdirSync as le}from"fs";import{dirname as ge,resolve as me}from"path";var T=class{db;path;constructor(e={}){this.path=me(process.cwd(),e.path??".agentx/intent/ledger.sqlite"),le(ge(this.path),{recursive:!0}),this.db=new ue(this.path),this.db.pragma("journal_mode = WAL"),this.db.pragma("synchronous = NORMAL"),this.db.pragma("foreign_keys = ON"),fe(this.db)}close(){this.db.close()}schemaVersion(){return this.db.prepare("SELECT MAX(v) AS v FROM schema_version").get().v??0}recordEvent(e){if(e.sourceEventId!==null){let i=this.findEventBySourceId(e.source,e.sourceEventId);if(i)return i}let t={id:e.id??I(e.ts),ts:e.ts,source:e.source,sourceEventId:e.sourceEventId,project:e.project,subject:e.subject,intent:e.intent,rawJson:e.rawJson};return this.db.prepare(`INSERT INTO intent_events (id, ts, source, source_event_id, project, subject, intent, raw_json)
2
2
  VALUES (?, ?, ?, ?, ?, ?, ?, ?)`).run(t.id,t.ts,t.source,t.sourceEventId,t.project,t.subject,t.intent,t.rawJson),t}findEventBySourceId(e,t){let i=this.db.prepare(`SELECT id, ts, source, source_event_id, project, subject, intent, raw_json
3
3
  FROM intent_events WHERE source = ? AND source_event_id = ?`).get(e,t);return i?U(i):null}getEventById(e){let t=this.db.prepare(`SELECT id, ts, source, source_event_id, project, subject, intent, raw_json
4
4
  FROM intent_events WHERE id = ?`).get(e);return t?U(t):null}recordDecision(e){this.db.prepare(`INSERT INTO intent_decisions (event_id, decided_at, decided_by, agent_id, outcome, reason)
@@ -123,4 +123,4 @@ ${r.prompt}`,r.maxOutputTokens),agentId:r.agent,autonomy:r.autonomy,timeoutMinut
123
123
  `);return t.length<=e?t.join(`
124
124
  `):t.slice(-e).join(`
125
125
  `)}function Ce(n,e,t){return new Promise((i,r)=>{Le("/bin/sh",["-c",n],{timeout:e,maxBuffer:8*1024*1024,...t?{env:t}:{}},(s,c,o)=>{if(s&&s.killed){r(new Error(`command timed out after ${Math.round(e/1e3)}s`));return}i({stdout:String(c??""),stderr:String(o??""),code:s?typeof s.code=="number"?s.code:1:0})})})}export{T as a,G as b,it as c,De as d,rt as e,st as f,$ as g,Q as h,B as i,je as j,V as k,K as l,at as m,Ae as n,ne as o,ie as p,re as q,we as r,C as s};
126
- //# sourceMappingURL=chunk-BXYKFWAI.js.map
126
+ //# sourceMappingURL=chunk-HYGMWCUU.js.map