agentix-cli 0.146.0 → 0.148.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/{App-EU2AJWW5.js → App-2O2UUZGG.js} +2 -2
- package/dist/{ChatApp-ORR3U3AN.js → ChatApp-YU4NF63L.js} +2 -2
- package/dist/{absorb-eval-3VGPDRWS.js → absorb-eval-WHWOJYDX.js} +2 -2
- package/dist/{agent-NVJNOK5L.js → agent-NLCR6VBE.js} +2 -2
- package/dist/{board-dashboard-JV2JNRWD.js → board-dashboard-KXSZIMWV.js} +216 -216
- package/dist/board-dashboard-KXSZIMWV.js.map +1 -0
- package/dist/{chunk-UFX6INNI.js → chunk-2MW32M2D.js} +2 -2
- package/dist/{chunk-5YAUENDI.js → chunk-3HVRWULP.js} +2 -2
- package/dist/{chunk-7O7VDA3J.js → chunk-5IHUZVPU.js} +2 -2
- package/dist/{chunk-USTNT7P7.js → chunk-5QXRPYOY.js} +2 -2
- package/dist/{chunk-3BMIZY6X.js → chunk-6QFDFYI7.js} +2 -2
- package/dist/{chunk-5TFXFLMN.js → chunk-6TJNWUMA.js} +3 -3
- package/dist/{chunk-MOCKFVYE.js → chunk-6YNRLI6I.js} +2 -2
- package/dist/{chunk-OEB6RTRA.js → chunk-AONY6U45.js} +2 -2
- package/dist/{chunk-WCOT35YG.js → chunk-ATCIRFH6.js} +2 -2
- package/dist/{chunk-O7ZJS33Z.js → chunk-BZ6Y264Z.js} +2 -2
- package/dist/{chunk-TYONASHA.js → chunk-CHBZHUIF.js} +41 -41
- package/dist/chunk-CHBZHUIF.js.map +1 -0
- package/dist/{chunk-NBDYBTI6.js → chunk-CJVAIAD7.js} +259 -259
- package/dist/chunk-CJVAIAD7.js.map +1 -0
- package/dist/{chunk-UVJLIHLL.js → chunk-DWOERPBG.js} +2 -2
- package/dist/chunk-E7LPZAXP.js +7 -0
- package/dist/chunk-E7LPZAXP.js.map +1 -0
- package/dist/{chunk-UTYNYG7M.js → chunk-EIY2HRAS.js} +2 -2
- package/dist/{chunk-OT5KLHUT.js → chunk-GMMRBTLQ.js} +2 -2
- package/dist/{chunk-GECGRCYC.js → chunk-GRI5HOPC.js} +2 -2
- package/dist/{chunk-UYLVSS6I.js → chunk-IGA3T3ZT.js} +2 -2
- package/dist/chunk-INT5PIF3.js +533 -0
- package/dist/chunk-INT5PIF3.js.map +1 -0
- package/dist/{chunk-WBG6NA7R.js → chunk-KP7KDLZ2.js} +2 -2
- package/dist/{chunk-QNS3WHGU.js → chunk-NMYC5RW7.js} +2 -2
- package/dist/{chunk-DTWBB7B7.js → chunk-NW4N67TU.js} +2 -2
- package/dist/chunk-OIMJLAWD.js +7 -0
- package/dist/chunk-OIMJLAWD.js.map +1 -0
- package/dist/{chunk-TZVJP4H3.js → chunk-OWMKQ4HZ.js} +2 -2
- package/dist/chunk-PXKIPU27.js +64 -0
- package/dist/chunk-PXKIPU27.js.map +1 -0
- package/dist/{chunk-DG2DC43E.js → chunk-PYHR4HXO.js} +2 -2
- package/dist/{chunk-SK24JFEK.js → chunk-S22IBRY6.js} +2 -2
- package/dist/chunk-S5NGIJDI.js +35 -0
- package/dist/chunk-S5NGIJDI.js.map +1 -0
- package/dist/chunk-X7UQY7CH.js +5 -0
- package/dist/chunk-X7UQY7CH.js.map +1 -0
- package/dist/{chunk-SNCRLEH3.js → chunk-Z7GEW2SR.js} +5 -5
- package/dist/cli.js +1 -1
- package/dist/{client-6KZZKCN2.js → client-A2N6ETK2.js} +2 -2
- package/dist/config-2QM2WTI2.js +2 -0
- package/dist/{config-mutate-57YT7BNB.js → config-mutate-UJS4F7BT.js} +2 -2
- package/dist/config-mutator-VWR3SMD3.js +2 -0
- package/dist/{contributions-Y6B6LG7X.js → contributions-43FWZOGF.js} +2 -2
- package/dist/doctor-5R6X7JH6.js +2 -0
- package/dist/{follow-up-tool-5AMZKVI4.js → follow-up-tool-VB7K6HCL.js} +2 -2
- package/dist/{hub-BZF3ZYQ5.js → hub-JNNNUAZM.js} +2 -2
- package/dist/index.d.ts +119 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/note-tool-EZWSB3J3.js +2 -0
- package/dist/note-tool-EZWSB3J3.js.map +1 -0
- package/dist/{program-MO7HLAP5.js → program-VS6QDZNX.js} +209 -209
- package/dist/program-VS6QDZNX.js.map +1 -0
- package/dist/{promote-IJANZNQK.js → promote-VFYVWVTL.js} +2 -2
- package/dist/{query-DC74NB3R.js → query-RB2MU2HV.js} +2 -2
- package/dist/{query-settings-RXFOATOZ.js → query-settings-5B54WHCS.js} +2 -2
- package/dist/{registry-24IXRDWX.js → registry-6OX7U6FV.js} +2 -2
- package/dist/{request-planner-33CWWCJU.js → request-planner-TUHVEYSF.js} +2 -2
- package/dist/{review-candidates-ENWB6LHD.js → review-candidates-FDYTGG2N.js} +2 -2
- package/dist/{routing-AUFJ4MNP.js → routing-U35SFPEI.js} +2 -2
- package/dist/schedule-tool-EPQKUYJX.js +2 -0
- package/dist/{scheduler-KWSBBZKW.js → scheduler-H2QHWNQ2.js} +2 -2
- package/dist/{seat-YGMLJ6KS.js → seat-EB3KJMIE.js} +2 -2
- package/dist/{select-JJGBM6ZT.js → select-IU4IOVSO.js} +2 -2
- package/dist/{set-enabled-THE7QIGQ.js → set-enabled-64BSJ7LR.js} +2 -2
- package/dist/{tool-4ACTSFKC.js → tool-PLM6Z42O.js} +2 -2
- package/dist/{tool-6LR6VORJ.js → tool-W3CIQZJ7.js} +2 -2
- package/dist/{wiki-YAW7UEOQ.js → wiki-4KMRUD5C.js} +2 -2
- package/dist/wiki-enrich-N4GLW2JX.js +2 -0
- package/package.json +1 -1
- package/dist/board-dashboard-JV2JNRWD.js.map +0 -1
- package/dist/chunk-IBK7AG4S.js +0 -62
- package/dist/chunk-IBK7AG4S.js.map +0 -1
- package/dist/chunk-J723FL3J.js +0 -7
- package/dist/chunk-J723FL3J.js.map +0 -1
- package/dist/chunk-K3QDK4BX.js +0 -5
- package/dist/chunk-K3QDK4BX.js.map +0 -1
- package/dist/chunk-MO7DH5L6.js +0 -535
- package/dist/chunk-MO7DH5L6.js.map +0 -1
- package/dist/chunk-NBDYBTI6.js.map +0 -1
- package/dist/chunk-S2GAEH2F.js +0 -13
- package/dist/chunk-S2GAEH2F.js.map +0 -1
- package/dist/chunk-TYONASHA.js.map +0 -1
- package/dist/config-W6JNVPBY.js +0 -2
- package/dist/config-mutator-6NWQPE7K.js +0 -2
- package/dist/doctor-ZP4KADAD.js +0 -2
- package/dist/program-MO7HLAP5.js.map +0 -1
- package/dist/schedule-tool-NAMOBMZE.js +0 -2
- package/dist/wiki-enrich-6ANFA2VB.js +0 -2
- /package/dist/{App-EU2AJWW5.js.map → App-2O2UUZGG.js.map} +0 -0
- /package/dist/{ChatApp-ORR3U3AN.js.map → ChatApp-YU4NF63L.js.map} +0 -0
- /package/dist/{absorb-eval-3VGPDRWS.js.map → absorb-eval-WHWOJYDX.js.map} +0 -0
- /package/dist/{agent-NVJNOK5L.js.map → agent-NLCR6VBE.js.map} +0 -0
- /package/dist/{chunk-UFX6INNI.js.map → chunk-2MW32M2D.js.map} +0 -0
- /package/dist/{chunk-5YAUENDI.js.map → chunk-3HVRWULP.js.map} +0 -0
- /package/dist/{chunk-7O7VDA3J.js.map → chunk-5IHUZVPU.js.map} +0 -0
- /package/dist/{chunk-USTNT7P7.js.map → chunk-5QXRPYOY.js.map} +0 -0
- /package/dist/{chunk-3BMIZY6X.js.map → chunk-6QFDFYI7.js.map} +0 -0
- /package/dist/{chunk-5TFXFLMN.js.map → chunk-6TJNWUMA.js.map} +0 -0
- /package/dist/{chunk-MOCKFVYE.js.map → chunk-6YNRLI6I.js.map} +0 -0
- /package/dist/{chunk-OEB6RTRA.js.map → chunk-AONY6U45.js.map} +0 -0
- /package/dist/{chunk-WCOT35YG.js.map → chunk-ATCIRFH6.js.map} +0 -0
- /package/dist/{chunk-O7ZJS33Z.js.map → chunk-BZ6Y264Z.js.map} +0 -0
- /package/dist/{chunk-UVJLIHLL.js.map → chunk-DWOERPBG.js.map} +0 -0
- /package/dist/{chunk-UTYNYG7M.js.map → chunk-EIY2HRAS.js.map} +0 -0
- /package/dist/{chunk-OT5KLHUT.js.map → chunk-GMMRBTLQ.js.map} +0 -0
- /package/dist/{chunk-GECGRCYC.js.map → chunk-GRI5HOPC.js.map} +0 -0
- /package/dist/{chunk-UYLVSS6I.js.map → chunk-IGA3T3ZT.js.map} +0 -0
- /package/dist/{chunk-WBG6NA7R.js.map → chunk-KP7KDLZ2.js.map} +0 -0
- /package/dist/{chunk-QNS3WHGU.js.map → chunk-NMYC5RW7.js.map} +0 -0
- /package/dist/{chunk-DTWBB7B7.js.map → chunk-NW4N67TU.js.map} +0 -0
- /package/dist/{chunk-TZVJP4H3.js.map → chunk-OWMKQ4HZ.js.map} +0 -0
- /package/dist/{chunk-DG2DC43E.js.map → chunk-PYHR4HXO.js.map} +0 -0
- /package/dist/{chunk-SK24JFEK.js.map → chunk-S22IBRY6.js.map} +0 -0
- /package/dist/{chunk-SNCRLEH3.js.map → chunk-Z7GEW2SR.js.map} +0 -0
- /package/dist/{client-6KZZKCN2.js.map → client-A2N6ETK2.js.map} +0 -0
- /package/dist/{config-W6JNVPBY.js.map → config-2QM2WTI2.js.map} +0 -0
- /package/dist/{config-mutate-57YT7BNB.js.map → config-mutate-UJS4F7BT.js.map} +0 -0
- /package/dist/{config-mutator-6NWQPE7K.js.map → config-mutator-VWR3SMD3.js.map} +0 -0
- /package/dist/{contributions-Y6B6LG7X.js.map → contributions-43FWZOGF.js.map} +0 -0
- /package/dist/{doctor-ZP4KADAD.js.map → doctor-5R6X7JH6.js.map} +0 -0
- /package/dist/{follow-up-tool-5AMZKVI4.js.map → follow-up-tool-VB7K6HCL.js.map} +0 -0
- /package/dist/{hub-BZF3ZYQ5.js.map → hub-JNNNUAZM.js.map} +0 -0
- /package/dist/{promote-IJANZNQK.js.map → promote-VFYVWVTL.js.map} +0 -0
- /package/dist/{query-DC74NB3R.js.map → query-RB2MU2HV.js.map} +0 -0
- /package/dist/{query-settings-RXFOATOZ.js.map → query-settings-5B54WHCS.js.map} +0 -0
- /package/dist/{registry-24IXRDWX.js.map → registry-6OX7U6FV.js.map} +0 -0
- /package/dist/{request-planner-33CWWCJU.js.map → request-planner-TUHVEYSF.js.map} +0 -0
- /package/dist/{review-candidates-ENWB6LHD.js.map → review-candidates-FDYTGG2N.js.map} +0 -0
- /package/dist/{routing-AUFJ4MNP.js.map → routing-U35SFPEI.js.map} +0 -0
- /package/dist/{schedule-tool-NAMOBMZE.js.map → schedule-tool-EPQKUYJX.js.map} +0 -0
- /package/dist/{scheduler-KWSBBZKW.js.map → scheduler-H2QHWNQ2.js.map} +0 -0
- /package/dist/{seat-YGMLJ6KS.js.map → seat-EB3KJMIE.js.map} +0 -0
- /package/dist/{select-JJGBM6ZT.js.map → select-IU4IOVSO.js.map} +0 -0
- /package/dist/{set-enabled-THE7QIGQ.js.map → set-enabled-64BSJ7LR.js.map} +0 -0
- /package/dist/{tool-4ACTSFKC.js.map → tool-PLM6Z42O.js.map} +0 -0
- /package/dist/{tool-6LR6VORJ.js.map → tool-W3CIQZJ7.js.map} +0 -0
- /package/dist/{wiki-YAW7UEOQ.js.map → wiki-4KMRUD5C.js.map} +0 -0
- /package/dist/{wiki-enrich-6ANFA2VB.js.map → wiki-enrich-N4GLW2JX.js.map} +0 -0
package/dist/chunk-S2GAEH2F.js
DELETED
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import{existsSync as w,readFileSync as A}from"node:fs";import{dirname as g,join as a}from"node:path";import{fileURLToPath as L}from"node:url";var p="tn.acme.agentx.voice",H="AgentX Desktop.app",d="AgentX Helper.app";function I(n,t,r){return n!=="darwin"||t!=="arm64"||Number(r.split(".")[0])<23?"AgentX Desktop currently requires Apple Silicon and macOS 14 or newer.":null}function M(n,t){if(t&&!Object.hasOwn(n,t))throw new Error(`Unknown agent: ${t}. Run agentx agent list.`);let r=t||Object.keys(n)[0];if(!r)throw new Error("No agents configured. Run agentx setup first.");return r}function c(n){return`'${n.replace(/'/g,"'\\''")}'`}var y="/usr/bin:/bin:/usr/sbin:/sbin";function C(n,t){return t||[...new Set([...n?[g(n)]:[],...y.split(":")])].join(":")}function u(n){let t={amp:"&",lt:"<",gt:">",quot:'"',apos:"'"};return n.replace(/&(amp|lt|gt|quot|apos);/g,(r,e)=>t[e])}function j(n){let t=n.match(/<key>PATH<\/key>\s*<string>([^<]*)<\/string>/);return t?u(t[1]):y}var X=n=>/agentx\.voice.*\.plist$/.test(n);function U(n,t){let r=null,e=[];for(let{file:i,plist:l}of[...t].sort((s,o)=>s.file<o.file?-1:1)){let s=l.match(/<key>Label<\/key>\s*<string>([^<]*)<\/string>/)?.[1],o=l.match(/<key>ProgramArguments<\/key>\s*<array>\s*<string>([^<]*)<\/string>/)?.[1];!s||!o||!u(o).endsWith("/Contents/MacOS/AgentXVoice")||(r?e.push({file:i,label:u(s)}):r={file:i,label:u(s)})}return{keep:r??{file:a(n,`${p}.plist`),label:p},remove:e}}function G(n,t,r){for(let e of t.split(":"))if(e&&r(a(e,n)))return a(e,n);return null}function F(n){let t=e=>e.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""").replace(/'/g,"'"),r={PATH:n.path,...n.agent?{AGENTX_VOICE_AGENT:n.agent}:{},AGENTX_DAEMON_URL:n.url,AGENTX_MAC_HELPER:n.helper,AGENTX_PASTE_COMMAND:`cd ${c(n.cwd)} && ${c(n.node)} ${c(n.cli)} paste`};return`<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
-
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
3
|
-
<plist version="1.0"><dict>
|
|
4
|
-
<key>Label</key><string>${t(n.label??p)}</string>
|
|
5
|
-
<key>ProgramArguments</key><array><string>${t(n.executable)}</string></array>
|
|
6
|
-
<key>WorkingDirectory</key><string>${t(n.cwd)}</string>
|
|
7
|
-
<key>EnvironmentVariables</key><dict>${Object.entries(r).map(([e,i])=>`<key>${e}</key><string>${t(i)}</string>`).join("")}</dict>
|
|
8
|
-
<key>RunAtLoad</key><true/><key>KeepAlive</key><true/>
|
|
9
|
-
<key>ProcessType</key><string>Interactive</string>
|
|
10
|
-
<key>StandardErrorPath</key><string>${t(n.log)}</string>
|
|
11
|
-
</dict></plist>
|
|
12
|
-
`}function B(n){return n?["--icon",n]:[]}function S(n){return a(n,"Applications",d,"Contents/MacOS/agentx-mac-helper")}function k(n=g(L(import.meta.url))){for(let t=n;;t=g(t)){try{if(JSON.parse(A(a(t,"package.json"),"utf8")).name==="agentix-cli")return t}catch{}if(g(t)===t)return null}}function x(n,t,r){if(r)return r;let e=S(t);return w(e)||!n?e:a(n,"apps/mac-helper/build",d,"Contents/MacOS/agentx-mac-helper")}import{execFile as E}from"child_process";import{existsSync as m}from"fs";import{homedir as b}from"os";import{isAbsolute as v}from"path";var N={banner:!0,sound:!0,soundName:"Glass",volume:.4},T=5e3,$=(n,t)=>new Promise(r=>{try{E(n,t,{timeout:T},e=>r(!e))}catch{r(!1)}});function Y(n){return{...N,...n??{}}}function P(n){if(!/^[\w -]+$/.test(n))return null;let t=`/System/Library/Sounds/${n}.aiff`;return m(t)?t:null}function _(){let n=x(k(),b(),process.env.AGENTX_MAC_HELPER);return m(n)?n:null}function z(n,t={}){let r=t.run??$,e=t.platform??process.platform,i=async(l,s)=>{let o=t.helper===void 0?_():t.helper;o&&await r(o,["notify","--title",l,"--message",s])||await r("/usr/bin/osascript",["-e","on run argv","-e","display notification (item 2 of argv) with title (item 1 of argv)","-e","end run",l,s])};return async(l,s)=>{if(e!=="darwin")return;let o=[];n.banner&&o.push(i(l,s));let f=n.sound?P(n.soundName):null;if(f){let h=Math.min(1,Math.max(0,n.volume));o.push(r("/usr/bin/afplay",["-v",String(h),f]))}await Promise.all(o)}}function Z(n,t,r=process.platform){let e={...n??{}};if("banner"in t&&(e.banner=!!t.banner),"sound"in t&&(e.sound=!!t.sound),"soundName"in t){let i=String(t.soundName).trim();if(!(r==="darwin"?P(i)!==null:/^[\w -]+$/.test(i)))throw new Error(`no system sound named "${i}" in /System/Library/Sounds`);e.soundName=i}if("icon"in t){let i=String(t.icon??"").trim().replace(/^~(?=\/)/,b());if(!i)delete e.icon;else{if(!v(i)||!/\.(png|jpe?g|icns)$/i.test(i))throw new Error("icon must be the full path to a .png, .jpg or .icns file");if(r==="darwin"&&!m(i))throw new Error(`no icon file at ${i}`);e.icon=i}}if("volume"in t){let i=Number(t.volume);if(!Number.isFinite(i)||i<0||i>1)throw new Error("volume must be between 0 and 1");e.volume=i}return e}export{H as a,d as b,I as c,M as d,C as e,j as f,X as g,U as h,G as i,F as j,B as k,S as l,k as m,x as n,N as o,Y as p,P as q,_ as r,z as s,Z as t};
|
|
13
|
-
//# sourceMappingURL=chunk-S2GAEH2F.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/desktop/install.ts","../src/notify/local.ts"],"sourcesContent":["import { existsSync, readFileSync } from 'node:fs'\nimport { dirname, join } from 'node:path'\nimport { fileURLToPath } from 'node:url'\n\nexport const DESKTOP_LABEL = 'tn.acme.agentx.voice'\nexport const DESKTOP_APP = 'AgentX Desktop.app'\nexport const HELPER_APP = 'AgentX Helper.app'\nexport function desktopPlatformError(platform: string, arch: string, release: string): string | null {\n if (platform !== 'darwin' || arch !== 'arm64' || Number(release.split('.')[0]) < 23)\n return 'AgentX Desktop currently requires Apple Silicon and macOS 14 or newer.'\n return null\n}\nexport function selectDesktopAgent(agents: Record<string, unknown>, requested?: string): string {\n if (requested && !Object.hasOwn(agents, requested)) throw new Error(`Unknown agent: ${requested}. Run agentx agent list.`)\n const id = requested || Object.keys(agents)[0]\n if (!id) throw new Error('No agents configured. Run agentx setup first.')\n return id\n}\nexport function shellQuote(value: string): string { return `'${value.replace(/'/g, \"'\\\\''\")}'` }\n/** launchd's default PATH, which is all a login item gets unless the plist sets one. */\nexport const LAUNCHD_PATH = '/usr/bin:/bin:/usr/sbin:/sbin'\n/** PATH for the login item: AGENTX_VOICE_PATH when set, else the folder of\n * the ffmpeg found at install time (mlx_whisper needs it) ahead of launchd's default. */\nexport function desktopPath(ffmpeg: string | null, override?: string): string {\n if (override) return override\n return [...new Set([...(ffmpeg ? [dirname(ffmpeg)] : []), ...LAUNCHD_PATH.split(':')])].join(':')\n}\nfunction unxml(s: string): string {\n const ents: Record<string, string> = { amp: '&', lt: '<', gt: '>', quot: '\"', apos: \"'\" }\n return s.replace(/&(amp|lt|gt|quot|apos);/g, (_, e) => ents[e])\n}\n/** The PATH a login item plist sets, or launchd's default when it sets none. */\nexport function plistPathEnv(plist: string): string {\n const m = plist.match(/<key>PATH<\\/key>\\s*<string>([^<]*)<\\/string>/)\n return m ? unxml(m[1]) : LAUNCHD_PATH\n}\n/** Login item files the voice app may have been installed under. */\nexport const isVoiceLoginItemFile = (name: string) => /agentx\\.voice.*\\.plist$/.test(name)\nexport type LoginItem = { file: string; label: string }\n/** One login item per Mac. The label was renamed once and\n * apps/mac-voice/install.sh writes its own, so adopt the first existing\n * `*agentx.voice*` item that runs the voice app (any bundle name) and\n * retire the others; with none, use DESKTOP_LABEL. Plists are XML text. */\nexport function adoptLoginItem(dir: string, items: { file: string; plist: string }[]): { keep: LoginItem; remove: LoginItem[] } {\n let keep: LoginItem | null = null\n const remove: LoginItem[] = []\n for (const { file, plist } of [...items].sort((a, b) => (a.file < b.file ? -1 : 1))) {\n const label = plist.match(/<key>Label<\\/key>\\s*<string>([^<]*)<\\/string>/)?.[1]\n const program = plist.match(/<key>ProgramArguments<\\/key>\\s*<array>\\s*<string>([^<]*)<\\/string>/)?.[1]\n if (!label || !program || !unxml(program).endsWith('/Contents/MacOS/AgentXVoice')) continue\n if (keep) remove.push({ file, label: unxml(label) })\n else keep = { file, label: unxml(label) }\n }\n return { keep: keep ?? { file: join(dir, `${DESKTOP_LABEL}.plist`), label: DESKTOP_LABEL }, remove }\n}\n/** The file that a process with this PATH would run, or null. */\nexport function findOnPath(bin: string, path: string, isExecutable: (file: string) => boolean): string | null {\n for (const dir of path.split(':')) if (dir && isExecutable(join(dir, bin))) return join(dir, bin)\n return null\n}\n/** Without `agent` the app talks to the agent picked in its menu-bar\n * icon; with it, that agent is pinned and the menu cannot switch. */\nexport function desktopPlist(opts: { label?: string; executable: string; cwd: string; agent?: string; url: string; helper: string; cli: string; node: string; log: string; path: string }): string {\n const xml = (s: string) => s.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>').replace(/\"/g, '"').replace(/'/g, ''')\n const env = {\n PATH: opts.path,\n ...(opts.agent ? { AGENTX_VOICE_AGENT: opts.agent } : {}),\n AGENTX_DAEMON_URL: opts.url,\n AGENTX_MAC_HELPER: opts.helper,\n AGENTX_PASTE_COMMAND: `cd ${shellQuote(opts.cwd)} && ${shellQuote(opts.node)} ${shellQuote(opts.cli)} paste`,\n }\n return `<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\"><dict>\n<key>Label</key><string>${xml(opts.label ?? DESKTOP_LABEL)}</string>\n<key>ProgramArguments</key><array><string>${xml(opts.executable)}</string></array>\n<key>WorkingDirectory</key><string>${xml(opts.cwd)}</string>\n<key>EnvironmentVariables</key><dict>${Object.entries(env).map(([k,v]) => `<key>${k}</key><string>${xml(v)}</string>`).join('')}</dict>\n<key>RunAtLoad</key><true/><key>KeepAlive</key><true/>\n<key>ProcessType</key><string>Interactive</string>\n<key>StandardErrorPath</key><string>${xml(opts.log)}</string>\n</dict></plist>\\n`\n}\n/** build.sh arguments for the helper: the banner icon from\n * notifications.local.icon, or none for the bundled AgentX logo. */\nexport function helperBuildArgs(icon?: string): string[] {\n return icon ? ['--icon', icon] : []\n}\nexport function installedHelper(home: string): string {\n return join(home, 'Applications', HELPER_APP, 'Contents/MacOS/agentx-mac-helper')\n}\n/** The AgentX package folder, found by walking up from this file (dist/\n * when installed, src/ in a checkout) — never from the caller's cwd, so\n * `agentx notify` finds a repo-built helper from any folder. */\nexport function packageRoot(from = dirname(fileURLToPath(import.meta.url))): string | null {\n for (let dir = from; ; dir = dirname(dir)) {\n try {\n if (JSON.parse(readFileSync(join(dir, 'package.json'), 'utf8')).name === 'agentix-cli') return dir\n } catch { /* no package.json here — keep walking up */ }\n if (dirname(dir) === dir) return null\n }\n}\n/** The helper to run: an explicit path, else the one `agentx desktop\n * install` put in ~/Applications, else one built in the package. */\nexport function resolveHelper(root: string | null, home: string, override?: string): string {\n if (override) return override\n const installed = installedHelper(home)\n if (existsSync(installed) || !root) return installed\n return join(root, 'apps/mac-helper/build', HELPER_APP, 'Contents/MacOS/agentx-mac-helper')\n}\n","import { execFile } from \"child_process\"\nimport { existsSync } from \"fs\"\nimport { homedir } from \"os\"\nimport { isAbsolute } from \"path\"\nimport { packageRoot, resolveHelper } from \"@/desktop/install\"\n\n// What happens on THIS machine when a notification is delivered: a banner\n// on screen and a short sound. The push goes to the phone; these are for\n// the person sitting at the Mac that raised the event.\n//\n// Both are awaited rather than fired and forgotten. A caller that exits\n// straight after notifying — a `launchctl submit` job that removes itself,\n// a cron one-liner — used to take the sound down with it before it\n// played. Waiting costs about a second and makes the step reliable.\n//\n// The banner is posted by the AgentX Helper app when it is installed, so\n// it carries the helper's icon (the AgentX logo by default). Without the\n// helper, or before macOS has allowed it to notify, osascript posts it,\n// and macOS shows it as coming from Script Editor.\n//\n// Never fatal: a notification whose banner failed still arrived, and no\n// caller should have to handle an audio error to say a build finished.\n\nexport interface LocalSettings {\n /** Show a desktop banner (macOS only; other platforms skip it). */\n banner: boolean\n /** Play a sound (macOS only). */\n sound: boolean\n /** A macOS system sound, by name: /System/Library/Sounds/<name>.aiff. */\n soundName: string\n /** 0 (silent) … 1 (full). */\n volume: number\n /** Image for the helper's app icon, which macOS puts on its banners.\n * Unset: the AgentX logo. Applied when `agentx desktop install` builds\n * the helper, since macOS reads the icon from the app, not the banner. */\n icon?: string\n}\n\n/** Glass is the gentlest system sound that is still audible over a\n * keyboard — Basso and Sosumi are alerts, Funk and Frog are jokes, and\n * Ping is the one every other app already uses. */\nexport const DEFAULT_LOCAL: LocalSettings = { banner: true, sound: true, soundName: \"Glass\", volume: 0.4 }\n\n/** Shows the banner and plays the sound for one delivered notification. */\nexport type LocalAlert = (title: string, message: string) => Promise<void>\n\n/** Runs a command; resolves true when it exited 0. */\ntype Run = (file: string, args: string[]) => Promise<boolean>\n\n/** Neither step may hold a caller hostage: afplay on a long custom sound,\n * or osascript stuck on a permission prompt, is cut off here. */\nconst STEP_TIMEOUT_MS = 5_000\n\nconst run: Run = (file, args) =>\n new Promise((done) => {\n try {\n execFile(file, args, { timeout: STEP_TIMEOUT_MS }, (err) => done(!err))\n } catch {\n done(false) // no osascript / afplay on this machine — not worth reporting\n }\n })\n\n/** Fill gaps in a partial `notifications.local` block with the defaults. */\nexport function localSettings(cfg: Partial<LocalSettings> | undefined): LocalSettings {\n return { ...DEFAULT_LOCAL, ...(cfg ?? {}) }\n}\n\n/** The system sound file for a name, or null when there is none. Names\n * only — a path in the config must not reach afplay. */\nexport function soundPath(name: string): string | null {\n if (!/^[\\w -]+$/.test(name)) return null\n const path = `/System/Library/Sounds/${name}.aiff`\n return existsSync(path) ? path : null\n}\n\n/** The AgentX Helper binary when one is built or installed, else null.\n * AGENTX_MAC_HELPER points at a helper somewhere else. */\nexport function findHelper(): string | null {\n const path = resolveHelper(packageRoot(), homedir(), process.env.AGENTX_MAC_HELPER)\n return existsSync(path) ? path : null\n}\n\nexport function localAlert(\n settings: LocalSettings,\n deps: { run?: Run; platform?: NodeJS.Platform; helper?: string | null } = {},\n): LocalAlert {\n const exec = deps.run ?? run\n const platform = deps.platform ?? process.platform\n const banner = async (title: string, message: string): Promise<void> => {\n const helper = deps.helper === undefined ? findHelper() : deps.helper\n // A non-zero exit is usually \"not allowed to notify yet\" — the first\n // banner asks — so this one goes through osascript instead.\n if (helper && await exec(helper, [\"notify\", \"--title\", title, \"--message\", message])) return\n // Title and message travel as argv, never spliced into the script,\n // so a quote in either cannot turn into AppleScript.\n await exec(\"/usr/bin/osascript\", [\n \"-e\", \"on run argv\",\n \"-e\", \"display notification (item 2 of argv) with title (item 1 of argv)\",\n \"-e\", \"end run\",\n title, message,\n ])\n }\n return async (title, message) => {\n if (platform !== \"darwin\") return\n const steps: Promise<unknown>[] = []\n if (settings.banner) steps.push(banner(title, message))\n const path = settings.sound ? soundPath(settings.soundName) : null\n if (path) {\n const volume = Math.min(1, Math.max(0, settings.volume))\n steps.push(exec(\"/usr/bin/afplay\", [\"-v\", String(volume), path]))\n }\n await Promise.all(steps)\n }\n}\n\n/**\n * Apply a change to a stored `notifications.local` block, the one rule\n * both the CLI and the dashboard write through. Returns the new block;\n * throws on a value that would not load. Only a Mac has sounds to check a\n * name against — elsewhere the setting is inert, so it need only be\n * well-formed.\n */\nexport function patchLocal(\n current: Partial<LocalSettings> | undefined,\n patch: Record<string, unknown>,\n platform: NodeJS.Platform = process.platform,\n): Partial<LocalSettings> {\n const next = { ...(current ?? {}) }\n if (\"banner\" in patch) next.banner = Boolean(patch.banner)\n if (\"sound\" in patch) next.sound = Boolean(patch.sound)\n if (\"soundName\" in patch) {\n const name = String(patch.soundName).trim()\n const ok = platform === \"darwin\" ? soundPath(name) !== null : /^[\\w -]+$/.test(name)\n if (!ok) throw new Error(`no system sound named \"${name}\" in /System/Library/Sounds`)\n next.soundName = name\n }\n if (\"icon\" in patch) {\n const icon = String(patch.icon ?? \"\").trim().replace(/^~(?=\\/)/, homedir())\n if (!icon) delete next.icon\n else {\n if (!isAbsolute(icon) || !/\\.(png|jpe?g|icns)$/i.test(icon)) throw new Error(\"icon must be the full path to a .png, .jpg or .icns file\")\n if (platform === \"darwin\" && !existsSync(icon)) throw new Error(`no icon file at ${icon}`)\n next.icon = icon\n }\n }\n if (\"volume\" in patch) {\n const v = Number(patch.volume)\n if (!Number.isFinite(v) || v < 0 || v > 1) throw new Error(\"volume must be between 0 and 1\")\n next.volume = v\n }\n return next\n}\n"],"mappings":"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","names":["existsSync","readFileSync","dirname","join","fileURLToPath","DESKTOP_LABEL","DESKTOP_APP","HELPER_APP","desktopPlatformError","platform","arch","release","selectDesktopAgent","agents","requested","id","shellQuote","value","LAUNCHD_PATH","desktopPath","ffmpeg","override","unxml","s","ents","_","plistPathEnv","plist","m","isVoiceLoginItemFile","name","adoptLoginItem","dir","items","keep","remove","file","a","b","label","program","findOnPath","bin","path","isExecutable","desktopPlist","opts","xml","env","k","v","helperBuildArgs","icon","installedHelper","home","packageRoot","from","resolveHelper","root","installed","execFile","existsSync","homedir","isAbsolute","DEFAULT_LOCAL","STEP_TIMEOUT_MS","run","file","args","done","execFile","err","localSettings","cfg","soundPath","name","path","existsSync","findHelper","resolveHelper","packageRoot","homedir","localAlert","settings","deps","exec","platform","banner","title","message","helper","steps","volume","patchLocal","current","patch","next","icon","isAbsolute","v"]}
|