agentix-cli 0.47.0 → 0.48.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/apps/mac-helper/Sources/AgentXHelper/Buffer.swift +65 -0
- package/apps/mac-helper/Sources/AgentXHelper/Notify.swift +26 -0
- package/apps/mac-helper/Sources/AgentXHelper/Ring.swift +58 -0
- package/apps/mac-helper/Sources/AgentXHelper/Screens.swift +7 -0
- package/apps/mac-helper/Sources/AgentXHelper/Vision.swift +13 -8
- package/apps/mac-helper/Sources/AgentXHelper/Watch.swift +87 -0
- package/apps/mac-helper/Sources/AgentXHelper/main.swift +72 -18
- package/dist/{App-RZDJH6MK.js → App-EXB4HP3B.js} +2 -2
- package/dist/{ChatApp-6TXOFUDH.js → ChatApp-XMNE3SPH.js} +2 -2
- package/dist/{agent-ZEVB6LE4.js → agent-ORYXXL5K.js} +2 -2
- package/dist/{board-dashboard-GADOZ7XY.js → board-dashboard-2B3HYIXD.js} +493 -131
- package/dist/board-dashboard-2B3HYIXD.js.map +1 -0
- package/dist/{chunk-BZLHS3VF.js → chunk-26OP3X5B.js} +2 -2
- package/dist/{chunk-VHTFHGVW.js → chunk-2GSEEKQK.js} +51 -51
- package/dist/chunk-2GSEEKQK.js.map +1 -0
- package/dist/{chunk-FNLGY4UV.js → chunk-2WPTP5HO.js} +2 -2
- package/dist/{chunk-MDTKQZC6.js → chunk-3WLO2UKI.js} +2 -2
- package/dist/chunk-3ZHMIWSV.js +2 -0
- package/dist/chunk-3ZHMIWSV.js.map +1 -0
- package/dist/{chunk-KFXLQNDQ.js → chunk-4ZX4E7P3.js} +185 -179
- package/dist/chunk-4ZX4E7P3.js.map +1 -0
- package/dist/chunk-7DXE264B.js +2 -0
- package/dist/chunk-7DXE264B.js.map +1 -0
- package/dist/chunk-DIV66W3N.js +28 -0
- package/dist/chunk-DIV66W3N.js.map +1 -0
- package/dist/{chunk-7CVJ4JOE.js → chunk-DLKRPK5M.js} +2 -2
- package/dist/chunk-DVNIFP7S.js +23 -0
- package/dist/chunk-DVNIFP7S.js.map +1 -0
- package/dist/chunk-FULEQYM6.js +13 -0
- package/dist/chunk-FULEQYM6.js.map +1 -0
- package/dist/chunk-GAGVFSZM.js +15 -0
- package/dist/{chunk-ANLKBCYH.js.map → chunk-GAGVFSZM.js.map} +1 -1
- package/dist/{chunk-3RHPZXCR.js → chunk-GCHUE3TN.js} +2 -2
- package/dist/chunk-GIK7S3OY.js +19 -0
- package/dist/chunk-GIK7S3OY.js.map +1 -0
- package/dist/{chunk-J63MRNXF.js → chunk-HEQPHUTR.js} +2 -2
- package/dist/{chunk-KTM7HSEB.js → chunk-LDILAHMN.js} +2 -2
- package/dist/{chunk-V7FYSZSV.js → chunk-LQRBGQIR.js} +2 -2
- package/dist/chunk-LQRBGQIR.js.map +1 -0
- package/dist/chunk-M5R3PWW5.js +123 -0
- package/dist/chunk-M5R3PWW5.js.map +1 -0
- package/dist/{chunk-BJWK7FPT.js → chunk-MLLEOFX2.js} +2 -2
- package/dist/{chunk-3AZ2OZMU.js → chunk-OZX7HVHC.js} +168 -165
- package/dist/chunk-OZX7HVHC.js.map +1 -0
- package/dist/chunk-P5JXQRBH.js +7 -0
- package/dist/chunk-P5JXQRBH.js.map +1 -0
- package/dist/{schedule-tool-3EFQMD2F.js → chunk-P7MR53U7.js} +3 -3
- package/dist/{schedule-tool-3EFQMD2F.js.map → chunk-P7MR53U7.js.map} +1 -1
- package/dist/chunk-RKPAVWXF.js +2 -0
- package/dist/chunk-RKPAVWXF.js.map +1 -0
- package/dist/{chunk-VZDKE2EZ.js → chunk-RYLTCOYE.js} +2 -2
- package/dist/{chunk-FPXYQ4IM.js → chunk-SL657MIM.js} +2 -2
- package/dist/chunk-WMI5B36E.js +5 -0
- package/dist/{chunk-BHPIAG3E.js.map → chunk-WMI5B36E.js.map} +1 -1
- package/dist/{chunk-NXJBAKBR.js → chunk-XM7ZQW4F.js} +2 -2
- package/dist/chunk-ZUZESPCH.js +150 -0
- package/dist/chunk-ZUZESPCH.js.map +1 -0
- package/dist/cli.js +1 -1
- package/dist/cli.js.map +1 -1
- package/dist/client-6HCY7UMW.js +2 -0
- package/dist/{compaction-QXU3A4LQ.js → compaction-U5SAYTX6.js} +2 -2
- package/dist/config-ROQ4VEU3.js +2 -0
- package/dist/config-mutator-ML4BAOFT.js +2 -0
- package/dist/doctor-3HWGAPET.js +2 -0
- package/dist/index.d.ts +268 -6
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/memory-extract-YZI2QZVR.js +2 -0
- package/dist/processes-XWRGOLMT.js +2 -0
- package/dist/program-JLZOHWIU.js +2 -0
- package/dist/{promote-RNSGW4AJ.js → promote-YGNTKEXI.js} +2 -2
- package/dist/query-V76JDSOC.js +2 -0
- package/dist/registry-DKN4HEI3.js +2 -0
- package/dist/{request-planner-5354IOYM.js → request-planner-FAFNFVFX.js} +2 -2
- package/dist/{review-candidates-UTWMO7UO.js → review-candidates-2XKJ2R6U.js} +2 -2
- package/dist/{routing-JGNWB6VJ.js → routing-PUPVGJ77.js} +2 -2
- package/dist/schedule-tool-6J7AHAHH.js +2 -0
- package/dist/scheduler-ZHQBSSRH.js +2 -0
- package/dist/{seat-STLDEYSO.js → seat-2MW3DEXX.js} +2 -2
- package/dist/{select-VP66P6XB.js → select-Q3AGLQQX.js} +2 -2
- package/dist/tool-IVUNSAXY.js +2 -0
- package/dist/tool-IVUNSAXY.js.map +1 -0
- package/dist/wiki-FPX2YBKS.js +2 -0
- package/dist/wiki-FPX2YBKS.js.map +1 -0
- package/package.json +1 -1
- package/dist/board-dashboard-GADOZ7XY.js.map +0 -1
- package/dist/chunk-3AZ2OZMU.js.map +0 -1
- package/dist/chunk-7L6M3P2N.js +0 -13
- package/dist/chunk-7L6M3P2N.js.map +0 -1
- package/dist/chunk-ANLKBCYH.js +0 -15
- package/dist/chunk-BHPIAG3E.js +0 -5
- package/dist/chunk-CQR6C5FU.js +0 -23
- package/dist/chunk-CQR6C5FU.js.map +0 -1
- package/dist/chunk-GPQTI5KD.js +0 -2
- package/dist/chunk-GPQTI5KD.js.map +0 -1
- package/dist/chunk-KFXLQNDQ.js.map +0 -1
- package/dist/chunk-PTFW5TYY.js +0 -9
- package/dist/chunk-PTFW5TYY.js.map +0 -1
- package/dist/chunk-V7FYSZSV.js.map +0 -1
- package/dist/chunk-VCT7ZPIA.js +0 -123
- package/dist/chunk-VCT7ZPIA.js.map +0 -1
- package/dist/chunk-VHTFHGVW.js.map +0 -1
- package/dist/chunk-W544ZCCO.js +0 -7
- package/dist/chunk-W544ZCCO.js.map +0 -1
- package/dist/chunk-WCAKT4FN.js +0 -25
- package/dist/chunk-WCAKT4FN.js.map +0 -1
- package/dist/chunk-ZYL3TO4I.js +0 -160
- package/dist/chunk-ZYL3TO4I.js.map +0 -1
- package/dist/client-LAIP23IP.js +0 -2
- package/dist/config-OZ2OOKFA.js +0 -2
- package/dist/config-mutator-EUF7QQ4V.js +0 -2
- package/dist/doctor-PEE3F5TX.js +0 -2
- package/dist/memory-extract-3TO7UC5B.js +0 -2
- package/dist/processes-I3XAPHG7.js +0 -2
- package/dist/program-3IZMYDWS.js +0 -2
- package/dist/query-BOUVRUU4.js +0 -2
- package/dist/registry-GROS7A2D.js +0 -2
- package/dist/scheduler-NT4YXVA6.js +0 -2
- package/dist/wiki-SKIIAVCU.js +0 -2
- /package/dist/{App-RZDJH6MK.js.map → App-EXB4HP3B.js.map} +0 -0
- /package/dist/{ChatApp-6TXOFUDH.js.map → ChatApp-XMNE3SPH.js.map} +0 -0
- /package/dist/{agent-ZEVB6LE4.js.map → agent-ORYXXL5K.js.map} +0 -0
- /package/dist/{chunk-BZLHS3VF.js.map → chunk-26OP3X5B.js.map} +0 -0
- /package/dist/{chunk-FNLGY4UV.js.map → chunk-2WPTP5HO.js.map} +0 -0
- /package/dist/{chunk-MDTKQZC6.js.map → chunk-3WLO2UKI.js.map} +0 -0
- /package/dist/{chunk-7CVJ4JOE.js.map → chunk-DLKRPK5M.js.map} +0 -0
- /package/dist/{chunk-3RHPZXCR.js.map → chunk-GCHUE3TN.js.map} +0 -0
- /package/dist/{chunk-J63MRNXF.js.map → chunk-HEQPHUTR.js.map} +0 -0
- /package/dist/{chunk-KTM7HSEB.js.map → chunk-LDILAHMN.js.map} +0 -0
- /package/dist/{chunk-BJWK7FPT.js.map → chunk-MLLEOFX2.js.map} +0 -0
- /package/dist/{chunk-VZDKE2EZ.js.map → chunk-RYLTCOYE.js.map} +0 -0
- /package/dist/{chunk-FPXYQ4IM.js.map → chunk-SL657MIM.js.map} +0 -0
- /package/dist/{chunk-NXJBAKBR.js.map → chunk-XM7ZQW4F.js.map} +0 -0
- /package/dist/{client-LAIP23IP.js.map → client-6HCY7UMW.js.map} +0 -0
- /package/dist/{compaction-QXU3A4LQ.js.map → compaction-U5SAYTX6.js.map} +0 -0
- /package/dist/{config-OZ2OOKFA.js.map → config-ROQ4VEU3.js.map} +0 -0
- /package/dist/{config-mutator-EUF7QQ4V.js.map → config-mutator-ML4BAOFT.js.map} +0 -0
- /package/dist/{doctor-PEE3F5TX.js.map → doctor-3HWGAPET.js.map} +0 -0
- /package/dist/{memory-extract-3TO7UC5B.js.map → memory-extract-YZI2QZVR.js.map} +0 -0
- /package/dist/{processes-I3XAPHG7.js.map → processes-XWRGOLMT.js.map} +0 -0
- /package/dist/{program-3IZMYDWS.js.map → program-JLZOHWIU.js.map} +0 -0
- /package/dist/{promote-RNSGW4AJ.js.map → promote-YGNTKEXI.js.map} +0 -0
- /package/dist/{query-BOUVRUU4.js.map → query-V76JDSOC.js.map} +0 -0
- /package/dist/{registry-GROS7A2D.js.map → registry-DKN4HEI3.js.map} +0 -0
- /package/dist/{request-planner-5354IOYM.js.map → request-planner-FAFNFVFX.js.map} +0 -0
- /package/dist/{review-candidates-UTWMO7UO.js.map → review-candidates-2XKJ2R6U.js.map} +0 -0
- /package/dist/{routing-JGNWB6VJ.js.map → routing-PUPVGJ77.js.map} +0 -0
- /package/dist/{scheduler-NT4YXVA6.js.map → schedule-tool-6J7AHAHH.js.map} +0 -0
- /package/dist/{seat-STLDEYSO.js.map → scheduler-ZHQBSSRH.js.map} +0 -0
- /package/dist/{wiki-SKIIAVCU.js.map → seat-2MW3DEXX.js.map} +0 -0
- /package/dist/{select-VP66P6XB.js.map → select-Q3AGLQQX.js.map} +0 -0
package/dist/chunk-7L6M3P2N.js
DELETED
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import{existsSync as l}from"node:fs";import{dirname as a,join as i}from"node:path";var p="tn.acme.agentx.voice",A="AgentX Desktop.app",c="AgentX Helper.app";function d(t,n,r){return t!=="darwin"||n!=="arm64"||Number(r.split(".")[0])<23?"AgentX Desktop currently requires Apple Silicon and macOS 14 or newer.":null}function f(t,n){if(n&&!Object.hasOwn(t,n))throw new Error(`Unknown agent: ${n}. Run agentx agent list.`);let r=n||Object.keys(t)[0];if(!r)throw new Error("No agents configured. Run agentx setup first.");return r}function g(t){return`'${t.replace(/'/g,"'\\''")}'`}var o="/usr/bin:/bin:/usr/sbin:/sbin";function m(t,n){return n||[...new Set([...t?[a(t)]:[],...o.split(":")])].join(":")}function x(t){let n=t.match(/<key>PATH<\/key>\s*<string>([^<]*)<\/string>/);if(!n)return o;let r={amp:"&",lt:"<",gt:">",quot:'"',apos:"'"};return n[1].replace(/&(amp|lt|gt|quot|apos);/g,(e,s)=>r[s])}function P(t,n,r){for(let e of n.split(":"))if(e&&r(i(e,t)))return i(e,t);return null}function E(t){let n=e=>e.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""").replace(/'/g,"'"),r={PATH:t.path,AGENTX_VOICE_AGENT:t.agent,AGENTX_DAEMON_URL:t.url,AGENTX_MAC_HELPER:t.helper,AGENTX_PASTE_COMMAND:`cd ${g(t.cwd)} && ${g(t.node)} ${g(t.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>${p}</string>
|
|
5
|
-
<key>ProgramArguments</key><array><string>${n(t.executable)}</string></array>
|
|
6
|
-
<key>WorkingDirectory</key><string>${n(t.cwd)}</string>
|
|
7
|
-
<key>EnvironmentVariables</key><dict>${Object.entries(r).map(([e,s])=>`<key>${e}</key><string>${n(s)}</string>`).join("")}</dict>
|
|
8
|
-
<key>RunAtLoad</key><true/><key>KeepAlive</key><true/>
|
|
9
|
-
<key>ProcessType</key><string>Interactive</string>
|
|
10
|
-
<key>StandardErrorPath</key><string>${n(t.log)}</string>
|
|
11
|
-
</dict></plist>
|
|
12
|
-
`}function h(t){return t?["--icon",t]:[]}function u(t){return i(t,"Applications",c,"Contents/MacOS/agentx-mac-helper")}function T(t,n,r){if(r)return r;let e=u(n);return l(e)?e:i(t,"apps/mac-helper/build/AgentX Helper.app/Contents/MacOS/agentx-mac-helper")}export{p as a,A as b,c,d,f as e,m as f,x as g,P as h,E as i,h as j,u as k,T as l};
|
|
13
|
-
//# sourceMappingURL=chunk-7L6M3P2N.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/desktop/install.ts"],"sourcesContent":["import { existsSync } from 'node:fs'\nimport { dirname, join } from 'node:path'\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}\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 if (!m) return LAUNCHD_PATH\n const ents: Record<string, string> = { amp: '&', lt: '<', gt: '>', quot: '\"', apos: \"'\" }\n return m[1].replace(/&(amp|lt|gt|quot|apos);/g, (_, e) => ents[e])\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}\nexport function desktopPlist(opts: { 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 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>${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}\nexport function resolveHelper(cwd: string, home: string, override?: string): string {\n if (override) return override\n const installed = installedHelper(home)\n return existsSync(installed) ? installed : join(cwd, 'apps/mac-helper/build/AgentX Helper.app/Contents/MacOS/agentx-mac-helper')\n}\n"],"mappings":"AAAA,OAAS,cAAAA,MAAkB,UAC3B,OAAS,WAAAC,EAAS,QAAAC,MAAY,YAEvB,IAAMC,EAAgB,uBAChBC,EAAc,qBACdC,EAAa,oBACnB,SAASC,EAAqBC,EAAkBC,EAAcC,EAAgC,CACnG,OAAIF,IAAa,UAAYC,IAAS,SAAW,OAAOC,EAAQ,MAAM,GAAG,EAAE,CAAC,CAAC,EAAI,GACxE,yEACF,IACT,CACO,SAASC,EAAmBC,EAAiCC,EAA4B,CAC9F,GAAIA,GAAa,CAAC,OAAO,OAAOD,EAAQC,CAAS,EAAG,MAAM,IAAI,MAAM,kBAAkBA,2BAAmC,EACzH,IAAMC,EAAKD,GAAa,OAAO,KAAKD,CAAM,EAAE,CAAC,EAC7C,GAAI,CAACE,EAAI,MAAM,IAAI,MAAM,+CAA+C,EACxE,OAAOA,CACT,CACO,SAASC,EAAWC,EAAuB,CAAE,MAAO,IAAIA,EAAM,QAAQ,KAAM,OAAO,IAAK,CAExF,IAAMC,EAAe,gCAGrB,SAASC,EAAYC,EAAuBC,EAA2B,CAC5E,OAAIA,GACG,CAAC,GAAG,IAAI,IAAI,CAAC,GAAID,EAAS,CAACjB,EAAQiB,CAAM,CAAC,EAAI,CAAC,EAAI,GAAGF,EAAa,MAAM,GAAG,CAAC,CAAC,CAAC,EAAE,KAAK,GAAG,CAClG,CAEO,SAASI,EAAaC,EAAuB,CAClD,IAAMC,EAAID,EAAM,MAAM,8CAA8C,EACpE,GAAI,CAACC,EAAG,OAAON,EACf,IAAMO,EAA+B,CAAE,IAAK,IAAK,GAAI,IAAK,GAAI,IAAK,KAAM,IAAK,KAAM,GAAI,EACxF,OAAOD,EAAE,CAAC,EAAE,QAAQ,2BAA4B,CAACE,EAAGC,IAAMF,EAAKE,CAAC,CAAC,CACnE,CAEO,SAASC,EAAWC,EAAaC,EAAcC,EAAwD,CAC5G,QAAWC,KAAOF,EAAK,MAAM,GAAG,EAAG,GAAIE,GAAOD,EAAa3B,EAAK4B,EAAKH,CAAG,CAAC,EAAG,OAAOzB,EAAK4B,EAAKH,CAAG,EAChG,OAAO,IACT,CACO,SAASI,EAAaC,EAAqJ,CAChL,IAAMC,EAAOC,GAAcA,EAAE,QAAQ,KAAM,OAAO,EAAE,QAAQ,KAAM,MAAM,EAAE,QAAQ,KAAM,MAAM,EAAE,QAAQ,KAAM,QAAQ,EAAE,QAAQ,KAAM,QAAQ,EACxIC,EAAM,CACV,KAAMH,EAAK,KACX,mBAAoBA,EAAK,MACzB,kBAAmBA,EAAK,IACxB,kBAAmBA,EAAK,OACxB,qBAAsB,MAAMlB,EAAWkB,EAAK,GAAG,QAAQlB,EAAWkB,EAAK,IAAI,KAAKlB,EAAWkB,EAAK,GAAG,SACrG,EACA,MAAO;AAAA;AAAA;AAAA,0BAGiB7B;AAAA,4CACkB8B,EAAID,EAAK,UAAU;AAAA,qCAC1BC,EAAID,EAAK,GAAG;AAAA,uCACV,OAAO,QAAQG,CAAG,EAAE,IAAI,CAAC,CAACC,EAAEC,CAAC,IAAM,QAAQD,kBAAkBH,EAAII,CAAC,YAAY,EAAE,KAAK,EAAE;AAAA;AAAA;AAAA,sCAGxFJ,EAAID,EAAK,GAAG;AAAA;AAAA,CAElD,CAGO,SAASM,EAAgBC,EAAyB,CACvD,OAAOA,EAAO,CAAC,SAAUA,CAAI,EAAI,CAAC,CACpC,CACO,SAASC,EAAgBC,EAAsB,CACpD,OAAOvC,EAAKuC,EAAM,eAAgBpC,EAAY,kCAAkC,CAClF,CACO,SAASqC,EAAcC,EAAaF,EAActB,EAA2B,CAClF,GAAIA,EAAU,OAAOA,EACrB,IAAMyB,EAAYJ,EAAgBC,CAAI,EACtC,OAAOzC,EAAW4C,CAAS,EAAIA,EAAY1C,EAAKyC,EAAK,0EAA0E,CACjI","names":["existsSync","dirname","join","DESKTOP_LABEL","DESKTOP_APP","HELPER_APP","desktopPlatformError","platform","arch","release","selectDesktopAgent","agents","requested","id","shellQuote","value","LAUNCHD_PATH","desktopPath","ffmpeg","override","plistPathEnv","plist","m","ents","_","e","findOnPath","bin","path","isExecutable","dir","desktopPlist","opts","xml","s","env","k","v","helperBuildArgs","icon","installedHelper","home","resolveHelper","cwd","installed"]}
|
package/dist/chunk-ANLKBCYH.js
DELETED
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
import{b as g,c as W}from"./chunk-FIOB3MEX.js";import{z as a}from"zod";var U,N,q,G,Z,K,H,F,V,S,w=g(()=>{"use strict";U=a.enum(["mon","tue","wed","thu","fri","sat","sun"]),N=a.object({days:a.array(U).default(["mon","tue","wed","thu","fri"]),start:a.string().regex(/^\d{2}:\d{2}$/),end:a.string().regex(/^\d{2}:\d{2}$/),lunch:a.object({start:a.string().regex(/^\d{2}:\d{2}$/),end:a.string().regex(/^\d{2}:\d{2}$/)}).optional()}),q=a.object({title:a.string(),responsibilities:a.array(a.string()).default([]),sopPath:a.string().optional(),kpis:a.array(a.string()).default([])}),G=a.object({role:a.string(),reportsTo:a.string().optional(),schedule:N,utilizationTarget:a.number().min(0).max(1).default(.8)}),Z=a.object({channel:a.string(),chatId:a.string(),accountId:a.string().optional()}),K=a.discriminatedUnion("type",[a.object({type:a.literal("backlog"),path:a.string().default(".agentx/backlog.md")}),a.object({type:a.literal("gitlab"),projects:a.array(a.string()).default([])}),a.object({type:a.literal("wiki"),path:a.string(),glob:a.string().default("**/*.md")})]),H=a.object({id:a.string(),pm:a.string().optional(),client:a.string().optional()}),F=a.object({channel:a.string().optional(),chatId:a.string().optional(),username:a.string().optional(),senderId:a.string().optional(),client:a.string(),project:a.string().optional(),displayName:a.string().optional()}),V=a.object({name:a.string().optional(),kind:a.enum(["client","internal","own"]).optional(),respondWithin:a.string().optional(),standing:a.array(a.string()).default([])}),S=a.object({enabled:a.boolean().default(!1),timezone:a.string().default("UTC"),mainChannel:Z,workSource:K,roles:a.record(a.string(),q).default({}),orgChart:a.record(a.string(),G).default({}),projects:a.array(H).default([]),contactMap:a.array(F).default([]),clients:a.record(a.string(),V).default({}),workTickMinutes:a.number().int().min(1).max(60).default(15),idleQueueThreshold:a.number().int().min(0).default(0),standup:a.object({enabled:a.boolean().default(!0),plansDir:a.string().default(".agentx/plans"),maxAgentsPerDay:a.number().int().min(1).max(100).default(20),dryRun:a.boolean().default(!1)}).default({})})});import{z as l}from"zod";function Qe(t,n){let r=new Set(t.labels||[]);if(t.state==="closed"){let i=n.find(s=>s.kind==="closed");if(i)return i.id}for(let i of n)if(i.kind==="scoped-label"&&i.scopedLabel&&r.has(i.scopedLabel))return i.id;for(let i of n)if(i.kind==="label"&&i.mapsToLabel&&r.has(i.mapsToLabel))return i.id;let o=n.find(i=>i.kind==="open-backlog");if(o){let i=o.scopedPrefix+"::";return[...r].some(d=>d.startsWith(i))?null:o.id}return n[0]?.id??null}function et(t,n){let r=[],o=[],i=!1,s=!1;return n.kind==="scoped-label"&&n.scopedLabel?r.push(n.scopedLabel):n.kind==="label"&&n.mapsToLabel?r.push(n.mapsToLabel):n.kind==="closed"&&(i=!0),t&&(t.kind==="scoped-label"&&t.scopedLabel?o.push(t.scopedLabel):t.kind==="label"&&t.mapsToLabel?o.push(t.mapsToLabel):t.kind==="closed"&&n.kind!=="closed"&&(s=!0)),{addLabels:r.length?r:void 0,removeLabels:o.length?o:void 0,closeIssue:i||void 0,reopen:s||void 0}}var Y,J,X,Q,ee,te,k,ne,v,j=g(()=>{"use strict";Y=l.object({name:l.string(),color:l.string().regex(/^#[0-9a-f]{6}$/i).default("#6366f1"),description:l.string().optional()}),J=l.object({id:l.string().regex(/^[a-z0-9_-]+$/,"column id must be lowercase slug"),title:l.string(),kind:l.enum(["open-backlog","scoped-label","closed","label"]).default("label"),mapsToLabel:l.string().optional(),scopedLabel:l.string().optional(),scopedPrefix:l.string().default("Status"),accent:l.string().optional()}),X=l.object({enabled:l.boolean().default(!0),staleDoingMinutes:l.number().int().min(1).default(45),respectLunchBreak:l.boolean().default(!0),respectSchedule:l.boolean().default(!0),action:l.enum(["badge","notify"]).default("badge")}),Q=l.discriminatedUnion("type",[l.object({type:l.literal("gitlab"),projects:l.array(l.string()).min(1)})]),ee=[{id:"open",title:"Open",kind:"open-backlog",scopedPrefix:"Status",accent:"#6b7280"},{id:"todo",title:"To Do",kind:"scoped-label",scopedLabel:"Status::To Do",scopedPrefix:"Status",accent:"#fb7a35"},{id:"doing",title:"Doing",kind:"scoped-label",scopedLabel:"Status::Doing",scopedPrefix:"Status",accent:"#22c55e"},{id:"onhold",title:"On Hold",kind:"scoped-label",scopedLabel:"Status::On Hold",scopedPrefix:"Status",accent:"#f59e0b"},{id:"review",title:"Review",kind:"scoped-label",scopedLabel:"Status::Review",scopedPrefix:"Status",accent:"#3b82f6"},{id:"closed",title:"Closed",kind:"closed",scopedPrefix:"Status",accent:"#6b7280"}],te=l.object({id:l.string().regex(/^[a-z0-9_-]+$/,"board id must be lowercase slug"),name:l.string(),source:Q,primaryToolLabel:l.string().optional(),labels:l.array(Y).default([]),columns:l.array(J).min(1).default(ee),timeRangeDays:l.number().int().min(1).max(365).default(30),closedWindowDays:l.number().int().min(1).max(365).default(30),reconciliation:X.default({})}),k=l.array(te).default([]),ne=l.object({name:l.string(),url:l.string(),dashboardUrl:l.string().optional(),token:l.string().optional(),dashboardToken:l.string().optional()}),v=l.object({enabled:l.boolean().default(!1),port:l.number().int().default(4202),bind:l.string().default("127.0.0.1"),token:l.string().optional(),daemonUrl:l.string().default("http://localhost:18800"),daemons:l.array(ne).default([]),draftAgent:l.string().optional()}).default({})});import{z as oe}from"zod";function ot(t){return t==="report"||t==="propose"}function ie(t){return t.replace(/([a-z0-9])([A-Z])/g,"$1 $2").split(/[^A-Za-z0-9]+/).filter(Boolean).map(n=>n.toLowerCase())}function y(t){return ie(t).slice(2).join(" ").replace(/\b(merge|pull)\s+requests?\b/g,"mergerequest").split(" ").filter(Boolean)}function C(t){let n=t.replace(/<<-?\s*(['"]?)([A-Za-z_][A-Za-z0-9_]*)\1([\s\S]*?)^\s*\2\s*$/gm,(i,s,d,c)=>!s&&/\$\(|`/.test(c)?i:i.split(`
|
|
2
|
-
`)[0]+`
|
|
3
|
-
`),r="",o=0;for(;o<n.length;){let i=n[o];if(i==="\\"){r+=n.slice(o,o+2),o+=2;continue}if(i==="'"){let s=n.indexOf("'",o+1);if(s<0)return null;r+="''",o=s+1;continue}if(i==='"'){let s=o+1;for(;s<n.length&&n[s]!=='"';)s+=n[s]==="\\"?2:1;if(s>=n.length)return null;let d=n.slice(o+1,s);r+=/\$\(|`/.test(d)?` ${d} `:'""',o=s+1;continue}r+=i,o++}return r}function _(t){return t.split(/\|\||&&|[;|&\n`()]|\$\(|<\(|>\(/).map(n=>n.trim().split(/\s+/).filter(Boolean)).filter(n=>n.length>0)}function R(t){let n=0;for(;n<t.length;){let r=t[n];if(de.has(r))return[];if(le.has(r)||/^[A-Za-z_][A-Za-z0-9_]*=/.test(r)){n++;continue}break}return t.slice(n)}function D(t){let n=0;for(;n<t.length&&t[n].startsWith("-");)n+=/^-(C|c)$|^--(git-dir|work-tree|namespace)$/.test(t[n])?2:1;return{sub:t[n],rest:t.slice(n+1)}}function fe(t){let[n,...r]=t,o=n.replace(/^.*\//,"");if(!ce.has(o))return`\`${o}\` is not a read-only command`;let i=s=>r.some(d=>s.test(d));switch(o){case"find":return i(/^-(exec|execdir|ok|okdir|delete|fprint|fprint0|fprintf|fls)$/)?"find with -exec/-delete":null;case"sort":return i(/^(-o|--output)/)?"sort -o writes a file":null;case"git":{if(i(/^(-c|--exec-path|--output)/))return"git option that can execute or write";let{sub:s,rest:d}=D(r);return!s||!ue.has(s)?`git ${s??""} is not read-only`.trim():s==="branch"&&d.some(c=>/^-(d|D|m|M|c|C|f|u)$|^--(delete|move|copy|force|set-upstream|unset-upstream|edit-description)/.test(c)||!c.startsWith("-"))?"git branch that changes branches":s==="tag"&&d.some(c=>!/^(-l|--list|-n\d*|--contains|--points-at|--sort=.*|--merged|--no-merged)$/.test(c))?"git tag that creates or deletes tags":s==="remote"&&d.length>0&&!/^(-v|--verbose|show|get-url)$/.test(d[0])?"git remote that changes remotes":s==="config"&&!d.some(c=>/^(--get|--get-all|--get-regexp|--list|-l)$/.test(c))?"git config write":s==="reflog"&&d.length>0&&!/^(show|-)/.test(d[0])?"git reflog that expires or deletes":null}case"gh":case"glab":{let[s,d]=r.filter(c=>!c.startsWith("-"));if(s==="search")return null;if(s==="api"){let c=r.findIndex(p=>/^(-X|--method)$/.test(p));return c>=0&&!/^GET$/i.test(r[c+1]??"")?`${o} api with a non-GET method`:i(/^-X(?!GET$)\w+|^--method=(?!GET$)/i)?`${o} api with a non-GET method`:i(/^(-f|-F|--field|--raw-field|--input)/)?`${o} api with a request body`:null}return!d||!pe.has(d)?`${o} ${s??""} ${d??""} is not read-only`.replace(/\s+/g," ").trim():null}case"curl":{let s=r.findIndex(d=>/^(-X|--request)$/.test(d));return s>=0&&!/^(GET|HEAD|OPTIONS)$/i.test(r[s+1]??"")||i(/^-X(?!GET$|HEAD$)\w+|^--request=(?!GET$|HEAD$)/i)?"curl with a non-GET method":i(/^(-d|--data|--data-\w+|--json|-F|--form|-T|--upload-file|-o|--output|-O|--remote-name|-K|--config)/)?"curl that sends a body or writes a file":null}default:return null}}function ge(t){let n=t.replace(/\d*>>?\s*\/dev\/null/g," ").replace(/&>>?\s*\/dev\/null/g," ").replace(/\d*>&\s*\d+/g," ");return/[>]/.test(n)}function me(t){let n=C(t);if(n===null)return u("report","shell","command too irregular to verify as read-only");if(ge(n))return u("report","shell","output redirection writes a file");for(let r of _(n)){let o=R(r);if(o.length===0)continue;let i=fe(o);if(i)return u("report","shell",i)}return f}function be(t){if(ae.has(t.tool))return u("report","write",`${t.tool} modifies files`);if(t.tool==="Bash")return me(t.command??"");if(re.has(t.tool))return f;if(t.tool.startsWith("mcp__")){let n=y(t.tool),r=n.find(o=>se.has(o));return r?u("report","outward",`tool "${t.tool}" can change state (${r})`):n.some(o=>T.has(o))?f:u("report","outward",`tool "${t.tool}" is not recognisably read-only`)}return u("report","tool",`tool "${t.tool}" is not on the read-only list`)}function we(t){let n=[];for(let o=0;o<t.length;o++){let i=t[o];if(Se.test(i)){o++;continue}if(/^(--force.*|-d|--delete|--mirror|--all|--tags|--prune)$/.test(i)||/^-[a-zA-Z]*f/.test(i))return u("propose","push","force, delete, mirror and tag pushes are act-level actions");i.startsWith("-")||n.push(i)}let r=n.slice(1);if(r.length===0)return u("propose","push","name the feature branch explicitly: git push <remote> <branch>");for(let o of r){if(o.startsWith("+")||o.startsWith(":"))return u("propose","push",`refspec "${o}" force-pushes or deletes`);let i=(o.includes(":")?o.slice(o.indexOf(":")+1):o).replace(/^refs\/heads\//,"");if(xe.test(i))return u("propose","push",`pushing to "${i}" is an act-level action; push a feature branch and open a merge request`)}return null}function ke(t){for(let r of he)if(r.re.test(t))return u("propose",r.id,r.reason);let n=C(t);if(n===null)return u("propose","shell","command too irregular to verify");for(let r of _(n)){let o=R(r);if(o.length===0)continue;let i=[A(o[0]),...o.slice(1)].join(" ");for(let s of ye)if(s.re.test(i))return u("propose",s.id,s.reason);if(A(o[0])==="git"){let{sub:s,rest:d}=D(o.slice(1));if(s==="push"){let c=we(d);if(c)return c}}}return f}function ve(t){if(t.tool==="Bash")return ke(t.command??"");if(t.tool.startsWith("mcp__")){let n=y(t.tool).find(r=>E.has(r));if(n)return u("propose","outward",`tool "${t.tool}" performs an act-level action (${n})`);if(je(y(t.tool)))return u("propose","delegate",`tool "${t.tool}" hands work to another agent, which would run at its own full autonomy`)}return f}function je(t){return t.includes("delegate")||t.includes("handoff")||t.includes("agent")&&t.some(n=>n==="send"||n==="ask"||n==="message"||n==="task")?!0:t.includes("task")&&!t.some(n=>T.has(n))}function at(t,n){return t==="report"?be(n):t==="propose"?ve(n):f}function rt(t){return t==="report"?"[Autonomy: report] This routine runs read-only. Investigate and report; do not modify files, run mutating commands, or post anywhere. Your final answer is the deliverable. Blocked actions are enforced and logged; if something needs doing, describe it in the report instead.":t==="propose"?"[Autonomy: propose] You may edit files, commit, push a named feature branch, and open a merge request or draft. You may not merge, deploy, delete, force-push, push to protected branches, or operate hosts. These limits are enforced and logged; leave act-level steps as clear recommendations.":""}var $,f,u,ae,re,T,E,se,le,de,A,ce,ue,pe,he,ye,xe,Se,I=g(()=>{"use strict";$=oe.enum(["report","propose","act"]);f={allowed:!0,ruleId:null,reason:null},u=(t,n,r)=>({allowed:!1,ruleId:`autonomy.${t}.${n}`,reason:r}),ae=new Set(["Write","Edit","MultiEdit","NotebookEdit"]),re=new Set(["Read","Glob","Grep","LS","NotebookRead","WebFetch","WebSearch","TodoWrite","TodoRead","Task","Agent","Skill","ToolSearch","BashOutput","KillShell","ExitPlanMode","EnterPlanMode","ListMcpResourcesTool","ReadMcpResourceTool"]);T=new Set(["get","list","search","read","view","fetch","query","find","show","describe","status","diff","inspect","lookup","count","stats","browse","whoami","download"]),E=new Set(["merge","delete","remove","destroy","drop","deploy","publish","release","approve","archive","revoke","purge","close","transfer","force","rollback","restart","erase","unprotect","truncate","wipe","kill","terminate","unpublish","promote"]),se=new Set([...E,"create","update","post","send","write","edit","add","set","comment","reply","push","run","execute","exec","trigger","upload","move","rename","cancel","retry","assign","label","react","invite","notify","schedule","start","stop","submit","save","patch","put","insert","upsert","apply","install","import","mark","toggle","enable","disable","open","commit","sync","reset","store","remember","forget","broadcast","message","call","dispatch","enqueue","resolve","unassign","lock","unlock","pin"]);le=new Set(["then","do","else","elif","if","while","until","!","{","}","time"]),de=new Set(["done","fi","esac","for","case","select","in",";;"]);A=t=>t.replace(/^.*\//,""),ce=new Set(["ls","pwd","cd","cat","head","tail","wc","grep","egrep","fgrep","rg","fd","tree","stat","file","du","df","date","whoami","id","hostname","uname","which","type","sort","uniq","cut","tr","diff","cmp","comm","basename","dirname","realpath","readlink","jq","column","nl","seq","true","false","test","[","sleep","ps","uptime","echo","printf","base64","md5","md5sum","shasum","sha256sum","less","more","printenv","dig","nslookup","host","find","git","gh","glab","curl"]),ue=new Set(["status","log","diff","show","rev-parse","ls-files","ls-tree","blame","shortlog","describe","cat-file","grep","branch","tag","remote","config","reflog","rev-list","merge-base","name-rev","show-ref","for-each-ref","whatchanged"]),pe=new Set(["view","list","diff","status","checks","ls"]);he=[{id:"merge",re:/merge_when_pipeline_succeeds|\bauto[_-]merge\b/i,reason:"auto-merging is an act-level action"},{id:"merge",re:/\b(curl|wget|http|gh\s+api|glab\s+api)\b[^\n]*\/merges?\b/i,reason:"calling a merge endpoint is an act-level action"},{id:"delete",re:/(?:^|\W)(drop|truncate)\s+(table|database|schema|index|collection)\b|(?:^|\W)delete\s+from\b|\bflushall\b|\bflushdb\b/i,reason:"destroying data is an act-level action"},{id:"delete",re:/(-X|--request)[\s=]*['"]?DELETE\b/i,reason:"HTTP DELETE is an act-level action"},{id:"delegate",re:/\b(curl|wget|http)\b[^\n]*(localhost|127\.0\.0\.1|\[::1\])[^\n]*\/(ask|task|send|chat|mesh|workflows?|crons?|reload|config)\b/i,reason:"calling the local daemon to dispatch work escapes this routine's limit"}],ye=[{id:"merge",re:/^(gh\s+pr\s+merge|glab\s+mr\s+merge)\b/i,reason:"merging is an act-level action"},{id:"delete",re:/^rm\s+(.*\s)?(-\w*[rR]\w*|--recursive)\b|^(shred|dropdb)\b|^find\b.*\s-delete\b/i,reason:"deleting is an act-level action"},{id:"delete",re:/^git\s+(clean\s+-\w*f|reset\s+--hard|branch\s+(-\w*[dD]\w*|--delete)|tag\s+(-d|--delete)|stash\s+(drop|clear)|remote\s+(remove|rm))\b/i,reason:"deleting is an act-level action"},{id:"delete",re:/^(gh|glab)\s+\S+\s+delete\b|^docker\s+(rm|rmi|volume\s+rm|system\s+prune)\b|^(kubectl\s+delete|aws\s+s3\s+(rm|rb)|gsutil\s+rm)\b|^doctl\s+.*\sdelete\b/i,reason:"deleting is an act-level action"},{id:"deploy",re:/^(kubectl\s+(apply|rollout|scale|set|patch|replace|create|edit)|helm\s+(install|upgrade|rollback|uninstall|delete)|terraform\s+(apply|destroy|import|taint)|pulumi\s+(up|destroy)|docker\s+push|netlify\s+deploy|fly(ctl)?\s+deploy|serverless\s+deploy|vercel\b.*--prod)\b/i,reason:"deploying is an act-level action"},{id:"deploy",re:/^((npm|pnpm|yarn|bun)(\s+run)?|make|just|task|rake)\s+(\S+:)?deploy\b|^((ba|z)?sh|node|python3?)\s+\S*deploy[^\s/]*$|^\S*\/deploy(\.\w+)?\b|^deploy(\.\w+)?\b/i,reason:"deploying is an act-level action"},{id:"deploy",re:/^((npm|pnpm|yarn|bun)\s+publish|cargo\s+publish|twine\s+upload|(gh|glab)\s+release\s+(create|upload|edit)|(npx\s+)?prisma\s+(migrate\s+(deploy|reset)|db\s+push))\b/i,reason:"publishing or migrating is an act-level action"},{id:"prod",re:/^(ssh|scp|sudo|doas|systemctl|launchctl|service|kill|pkill|killall|reboot|shutdown)\b|^rsync\b.*\s\S+:\S*/i,reason:"operating hosts and services is an act-level action"},{id:"delegate",re:/^(agentx|agentix)\s+(ask|send|task|exec|run|chat|mesh|cron|workflow|daemon|config)\b/i,reason:"handing work to another agent or reconfiguring the daemon escapes this routine's limit"}],xe=/^(main|master|trunk|develop|development|prod|production|staging|stable|release([/-].*)?|HEAD|@)$/i,Se=/^(-o|--push-option|--repo|--receive-pack|--exec)$/});var Fe={};W(Fe,{INTEGRATION_KINDS:()=>De,daemonConfigSchema:()=>M,expandEnvVars:()=>h,loadDaemonConfig:()=>Ke,validateWorkspaces:()=>He});import{z as e}from"zod";import{readFileSync as L,existsSync as m}from"fs";import{resolve as b}from"path";function Ae(t){let n=b(t,".env");if(!m(n))return;let r=L(n,"utf-8");for(let o of r.split(`
|
|
4
|
-
`)){let i=o.trim();if(!i||i.startsWith("#"))continue;let s=i.indexOf("=");if(s===-1)continue;let d=i.slice(0,s).trim(),c=i.slice(s+1).trim();process.env[d]||(process.env[d]=c)}}function h(t){if(typeof t=="string")return t.replace(/\$\{(\w+)\}/g,(n,r)=>process.env[r]||"");if(Array.isArray(t))return t.map(h);if(t!==null&&typeof t=="object"){let n={};for(let[r,o]of Object.entries(t))n[r]=h(o);return n}return t}function Ze(t,n){let r=[],o=new Set;for(let i of t){let s=i.path.join("."),d=/^channels\.telegram\.accounts\.([^.]+)\.token$/.exec(s);if(d&&i.message.toLowerCase().includes("required")){let c=d[1],p=`tg:${c}`;if(o.has(p))continue;o.add(p),r.push(`Hint: Telegram account "${c}" is enabled but has no bot token.
|
|
5
|
-
Either:
|
|
6
|
-
A) Open ${n} and set channels.telegram.accounts.${c}.token to your bot token (or "\${TG_${c.toUpperCase()}_BOT_TOKEN}" + the matching .env entry).
|
|
7
|
-
B) If you don't need Telegram on this instance, remove the entire "telegram" block under "channels" (or set channels.telegram.enabled to false AND drop accounts.${c}).`)}}return r}function Ke(t){let n=t?[t]:[b(process.cwd(),"agentx.json"),b(process.cwd(),".agentx/config.json")];Ae(process.cwd());let r,o;for(let c of n)if(m(c)){r=L(c,"utf-8"),o=c;break}if(!r||!o)throw new Error(`No config found. Create agentx.json or .agentx/config.json
|
|
8
|
-
Searched: ${n.join(", ")}`);let i;try{i=JSON.parse(r)}catch(c){throw new Error(`Invalid JSON in ${o}: ${c.message}`)}let s=h(i),d=M.safeParse(s);if(!d.success){let c=d.error.issues.map(x=>` ${x.path.join(".")}: ${x.message}`).join(`
|
|
9
|
-
`),p=Ze(d.error.issues,o),z=p.length?`
|
|
10
|
-
|
|
11
|
-
${p.join(`
|
|
12
|
-
|
|
13
|
-
`)}`:"";throw new Error(`Config validation failed (${o}):
|
|
14
|
-
${c}${z}`)}return d.data}function He(t){let n=[];for(let[r,o]of Object.entries(t.agents)){if(!m(o.workspace)){n.push(`Agent "${r}": workspace not found at ${o.workspace}`);continue}if(o.tier==="claude-code"){let d=b(o.workspace,".claude");m(d)||n.push(`Agent "${r}": no .claude/ directory in workspace ${o.workspace}. Claude Code native features (hooks, MCP, skills) won't be available.`)}let i=o.provider||"claude",s=t.providers[i];!["claude-code","codex-cli","opencode"].includes(o.tier)&&(!s||!s.apiKey)&&n.push(`Agent "${r}": provider "${i}" has no API key configured. Set providers.${i}.apiKey in config or use a CLI-backed tier ("claude-code", "codex-cli", or "opencode").`)}for(let[r,o]of Object.entries(t.crons))t.agents[o.agent]||n.push(`Cron "${r}": references unknown agent "${o.agent}"`);if(t.channels.telegram.enabled)for(let[r,o]of Object.entries(t.channels.telegram.accounts))t.agents[o.agentBinding]||n.push(`Telegram account "${r}": references unknown agent "${o.agentBinding}"`);return n}var $e,Te,Ee,Ce,_e,Re,De,P,O,B,Ie,Le,Pe,Oe,Be,Me,ze,We,Ue,Ne,qe,Ge,M,Ve=g(()=>{w();j();I();$e=e.object({apiKey:e.string().optional(),defaultModel:e.string().optional(),baseUrl:e.string().optional(),thinking:e.boolean().optional()}),Te=e.object({type:e.literal("stdio").optional(),command:e.string(),args:e.array(e.string()).default([]),env:e.record(e.string(),e.string()).optional()}),Ee=e.object({type:e.literal("http"),url:e.string().url(),headers:e.record(e.string(),e.string()).optional()}),Ce=e.union([Ee,Te]),_e=e.object({tokenEnv:e.string().regex(/^[A-Z][A-Z0-9_]*$/).optional(),privateAppTokenEnv:e.string().regex(/^[A-Z][A-Z0-9_]*$/).optional(),apiKeyEnv:e.string().regex(/^[A-Z][A-Z0-9_]*$/).optional(),refreshTokenEnv:e.string().regex(/^[A-Z][A-Z0-9_]*$/).optional(),clientIdEnv:e.string().regex(/^[A-Z][A-Z0-9_]*$/).optional(),clientSecretEnv:e.string().regex(/^[A-Z][A-Z0-9_]*$/).optional(),auth:e.literal("keyring").optional(),sessionDir:e.string().optional()}).strict(),Re=e.object({kind:e.string().min(1),label:e.string().min(1),credentials:_e.default({}),metadata:e.record(e.string(),e.union([e.string(),e.number(),e.boolean()])).default({}),enabled:e.boolean().default(!0)}),De=["telegram-bot","whatsapp","gitlab-user","github-user","gmail","hotmail","smtp","hubspot","salesforce","pipedrive","odoo","trello","linear","asana","jira","notion","stripe","sentry","vercel","twilio","custom"],P=e.enum(["system","elevenlabs"]),O=e.union([e.string(),e.record(e.string(),e.string())]),B=e.object({provider:P.optional(),system:O.optional(),elevenlabsVoiceId:e.string().optional(),gender:e.enum(["female","male","neutral"]).optional(),style:e.string().optional(),intro:e.string().optional(),narrate:e.enum(["off","on","all"]).optional()}),Ie=e.object({name:e.string(),workspace:e.string(),tier:e.enum(["claude-code","codex-cli","opencode","sdk","orchestrator"]).default("claude-code"),provider:e.string().optional(),model:e.string().optional(),systemPrompt:e.string().optional(),mentions:e.array(e.string()).default([]),intents:e.array(e.string()).default([]),maxDelegationDepth:e.number().int().min(0).max(50).default(5),mcp:e.record(e.string(),Ce).optional(),codegraph:e.boolean().default(!1),contextStrategy:e.enum(["layered","planner"]).optional(),contextReferences:e.boolean().default(!1),richMessages:e.boolean().default(!0),maxConcurrent:e.number().default(1),maxExecutionMinutes:e.number().int().min(1).max(240).default(20),permissionMode:e.string().default("default"),billing:e.enum(["subscription","api"]).default("subscription"),toolUseRequired:e.array(e.string()).default([]),gitlabAutoReply:e.boolean().optional(),persistentProcess:e.boolean().default(!1),queueMode:e.enum(["collect","followup","drop"]).default("collect"),heartbeat:e.object({enabled:e.boolean().default(!1),intervalMinutes:e.number().default(30),prompt:e.string().default("Check inbox, pending tasks, and system health. Report anything that needs attention."),channel:e.string().default("heartbeat")}).default({}),access:e.enum(["private","public"]).default("private"),admin:e.boolean().optional(),integrations:e.array(Re).default([]),voice:B.optional(),presence:e.object({color:e.string().regex(/^#[0-9a-fA-F]{6}$/).optional(),initial:e.string().max(2).optional(),label:e.string().optional(),allowActions:e.boolean().optional()}).optional()}),Le=e.object({token:e.string(),agentBinding:e.string(),allowFrom:e.array(e.string()).optional(),pollInbound:e.boolean().default(!0)}),Pe=e.object({telegram:e.object({enabled:e.boolean().default(!1),accounts:e.record(e.string(),Le).default({}),policy:e.object({dm:e.enum(["pair","block"]).default("pair"),group:e.enum(["mention-required","all"]).default("mention-required"),allowFrom:e.array(e.string()).optional()}).default({})}).default({}),whatsapp:e.object({enabled:e.boolean().default(!1),sessionDir:e.string().default(".agentx/whatsapp-sessions"),defaultAgent:e.string().optional(),allowFrom:e.array(e.string()).optional(),routes:e.array(e.object({contact:e.string().optional(),group:e.string().optional(),agent:e.string()})).default([]),ingest:e.object({enabled:e.boolean().default(!1),mode:e.enum(["metadata-only","messages"]).default("metadata-only"),allowContacts:e.array(e.string()).default([]),allowGroups:e.array(e.string()).default([]),denyContacts:e.array(e.string()).default([]),denyGroups:e.array(e.string()).default([]),messageCap:e.number().int().min(1).max(500).default(50),historyDays:e.number().int().min(1).max(365).default(30),contactRefreshDays:e.number().int().min(1).max(90).default(7),throttle:e.object({minMsBetweenCalls:e.number().int().min(100).default(1500),maxCallsPerMinute:e.number().int().min(1).default(20),maxChatsPerSweep:e.number().int().min(1).default(25)}).default({}),retentionDays:e.number().int().min(0).default(0)}).default({})}).default({}),gitlab:e.object({enabled:e.boolean().default(!1),webhookPort:e.number().default(18810),webhookSecret:e.string().optional(),host:e.string().default("https://gitlab.com"),token:e.string().optional(),autoReplyLegacy:e.boolean().default(!0),routes:e.array(e.object({project:e.string(),agent:e.string()})).default([]),agentMappings:e.array(e.object({agentId:e.string(),gitlabUsernames:e.array(e.string()).default([]),keywords:e.array(e.string()).default([]),token:e.string().optional(),node:e.string().optional()})).default([])}).default({}),github:e.object({enabled:e.boolean().default(!1),autoReplyLegacy:e.boolean().default(!0),token:e.string().optional(),tokenFile:e.string().optional(),appId:e.number().optional(),clientId:e.string().optional(),privateKeyFile:e.string().optional(),webhookSecret:e.string().optional(),routes:e.array(e.object({repo:e.string(),agent:e.string()})).default([]),agentMappings:e.array(e.object({agentId:e.string(),githubUsernames:e.array(e.string()).default([]),token:e.string().optional(),tokenFile:e.string().optional(),node:e.string().optional()})).default([])}).default({}),ntfy:e.object({enabled:e.boolean().default(!1),server:e.string().default("https://ntfy.sh"),topic:e.string().optional(),token:e.string().optional(),defaultPriority:e.number().int().min(1).max(5).default(3),defaultTitle:e.string().optional()}).default({}),webrtc:e.object({enabled:e.boolean().default(!1),stunServers:e.array(e.string()).default(["stun:stun.l.google.com:19302"]),turnServers:e.array(e.object({urls:e.string(),username:e.string().optional(),credential:e.string().optional()})).default([]),allowedCallers:e.array(e.string()).default([]),ringNotify:e.array(e.object({channel:e.string(),chatId:e.string(),accountId:e.string().optional()})).default([]),callUrlBase:e.string().optional(),bot:e.object({enabled:e.boolean().default(!1),defaultAgentId:e.string().optional(),whisperBackend:e.enum(["auto","mlx","openai"]).default("auto"),whisperModel:e.string().optional(),whisperLanguage:e.string().default("auto"),mlxBinary:e.string().optional(),transcriptChannel:e.object({channel:e.string(),chatId:e.string(),accountId:e.string().optional()}).optional(),maxCallMinutes:e.number().int().min(1).max(240).default(30)}).default({})}).default({})}),Oe=e.object({enabled:e.boolean().default(!0),schedule:e.string(),timezone:e.string().default("UTC"),agent:e.string(),prompt:e.string().default(""),command:e.string().optional(),timeout:e.number().default(600),model:e.string().optional(),maxOutputTokens:e.number().int().min(50).max(8e3).optional(),autonomy:$.optional(),onError:e.union([e.enum(["log","notify","disable"]),e.array(e.enum(["log","notify","disable"]))]).default("log").transform(t=>Array.isArray(t)?t:[t]),notify:e.object({channel:e.string(),chatId:e.string(),accountId:e.string().optional()}).optional(),fireToken:e.string().optional(),createdBy:e.string().optional(),approval:e.object({action:e.enum(["create","delete"]),requestedBy:e.string(),requestedAt:e.string()}).optional()}).refine(t=>!!(t.command?.trim()||t.prompt?.trim()),{message:"a cron needs either a prompt (dispatch an agent) or a command (run it directly)"}).refine(t=>!(t.command?.trim()&&t.autonomy&&t.autonomy!=="act"),{message:"autonomy applies to agent routines; a command cron runs no agent (remove autonomy or the command)"}),Be=e.object({name:e.string(),triggers:e.array(e.object({pattern:e.string(),channel:e.string().optional()})),allowedContacts:e.array(e.string()).optional(),agent:e.string(),prompt:e.string(),schedule:e.string().optional(),timezone:e.string().default("UTC"),notify:e.object({channel:e.string(),chatId:e.string(),accountId:e.string().optional()}).optional()}),Me=e.object({url:e.string(),name:e.string(),token:e.string().optional()}),ze=e.object({name:e.string(),agent:e.string(),enabled:e.boolean().default(!0)}),We=e.object({enabled:e.boolean().default(!1),peers:e.array(Me).default([]),inboxes:e.array(ze).default([]),discovery:e.enum(["static","mdns"]).default("static"),healthCheck:e.object({interval:e.number().default(60),timeout:e.number().default(10)}).default({})}),Ue=e.object({enabled:e.boolean().default(!1),baseDir:e.string().default(".agentx/graph"),draftAgent:e.string().optional(),reviewAgent:e.string().optional(),autoApproveStructure:e.enum(["strict","extend-leaves","any"]).default("extend-leaves"),autoApproveConfidence:e.number().min(0).max(1).default(1),classifierModel:e.string().default("claude-haiku-4-5-20251001"),retrievalWeights:e.object({graph:e.number().min(0).default(.6),bm25:e.number().min(0).default(.4)}).default({})}).default({}),Ne=e.object({mode:e.enum(["off","shadow","active"]).default("off"),backend:e.string().optional(),model:e.string().optional(),timeoutMs:e.number().int().min(100).default(1e4),temperature:e.number().min(.01).default(1),explore:e.number().min(0).max(1).default(.15),holdout:e.number().min(0).max(1).optional()}).default({}),qe=e.object({enabled:e.boolean().default(!1),dbPath:e.string().default(".agentx/decisions/decisions.sqlite"),redactState:e.boolean().default(!1),keepStateRows:e.number().int().min(0).default(2e3),defaultBackend:e.string().default("local"),backends:e.object({local:e.object({provider:e.string().default("claude-code"),model:e.string().default("claude-haiku-4-5-20251001"),structureMode:e.enum(["auto","tool","text"]).default("auto"),normalizeProbabilities:e.boolean().default(!0),nRetryMalformedStructure:e.number().int().min(0).max(3).default(1),maxStateChars:e.number().int().min(500).default(24e3)}).default({}),simpleJev:e.object({baseUrl:e.string().default("http://127.0.0.1:8000/v1"),model:e.string().optional(),apiKeyEnv:e.string().optional(),timeoutMs:e.number().int().min(100).default(3e4),maxStateChars:e.number().int().min(500).default(6e3),maxChoiceOptions:e.number().int().min(2).max(255).default(50)}).default({}),jev:e.object({baseUrl:e.string().default("https://openrouter.ai/api/alpha"),path:e.string().default("/decisions"),model:e.string().default("jev-latest"),apiKeyEnv:e.string().default("OPENROUTER_API_KEY"),timeoutMs:e.number().int().min(100).default(3e4),maxStateChars:e.number().int().min(500).default(9e4),maxChoiceOptions:e.number().int().min(2).max(255).default(255)}).default({}),typesafe:e.object({baseUrl:e.string().default("https://api.typesafe.ai/v1"),path:e.string().default("/systemone"),model:e.string().default("jev-latest"),apiKeyEnv:e.string().default("TYPESAFE_API_KEY"),timeoutMs:e.number().int().min(100).default(3e4),maxStateChars:e.number().int().min(500).default(9e4),maxChoiceOptions:e.number().int().min(2).max(255).default(255)}).default({})}).default({}),seats:e.record(e.string(),Ne).default({}),routing:e.object({cheapModel:e.string().optional(),cheapModels:e.object({"claude-code":e.string().optional(),"codex-cli":e.string().optional()}).optional()}).default({})}).default({}),Ge=e.object({longTaskThreshold:e.number().default(30),destination:e.object({channel:e.string(),chatId:e.string(),accountId:e.string().optional()}).optional(),on:e.object({taskComplete:e.boolean().default(!0),taskError:e.boolean().default(!0),taskQueued:e.boolean().default(!1)}).default({}),local:e.object({banner:e.boolean().default(!0),sound:e.boolean().default(!0),soundName:e.string().regex(/^[\w -]+$/).default("Glass"),volume:e.number().min(0).max(1).default(.4),icon:e.string().optional()}).default({})}).default({}),M=e.object({node:e.object({id:e.string(),name:e.string(),bind:e.string().default("127.0.0.1:18800"),defaultAgent:e.string().optional()}),providers:e.record(e.string(),$e).default({}),agents:e.record(e.string(),Ie).default({}),channels:Pe.default({}),crons:e.record(e.string(),Oe).default({}),services:e.record(e.string(),Be).default({}),notifications:Ge,resume:e.object({enabled:e.boolean().default(!0),maxAgeMinutes:e.number().int().positive().default(30),maxAttempts:e.number().int().min(0).default(1),reportOnlyChannels:e.array(e.string()).default([]),directChannels:e.array(e.string()).default([]),crashLoop:e.object({restarts:e.number().int().positive().default(3),windowMinutes:e.number().positive().default(10)}).default({})}).default({}),mesh:We.default({}),meshVoices:e.record(e.string(),B.extend({name:e.string().optional()})).default({}),voice:e.object({provider:P.default("system"),fallback:e.enum(["system","none"]).default("system"),system:O.optional(),locale:e.string().default("en"),listener:e.string().optional()}).default({}),business:S.optional(),boards:k,dashboard:v,graph:Ue,decisions:qe,workflows:e.object({enabled:e.boolean().default(!1),dir:e.string().default(".agentx/workflows"),n8n:e.object({baseUrl:e.string().default(""),apiKey:e.string().default("")}).default({baseUrl:"",apiKey:""}),matching:e.object({enabled:e.boolean().default(!1),mode:e.enum(["suggest","auto"]).default("suggest"),autoRunThreshold:e.number().min(0).max(1).default(.85),suggestThreshold:e.number().min(0).max(1).default(.65)}).default({}),editor:e.enum(["disabled","readonly","edit"]).default("edit")}).default({}),procedures:e.object({enabled:e.boolean().default(!0),dir:e.string().default(".agentx/procedures"),extraction:e.object({enabled:e.boolean().default(!1),onTaskCompletion:e.boolean().default(!1),minOccurrences:e.number().int().min(2).default(3),sinceDays:e.number().int().min(1).default(7),maxClusters:e.number().int().min(1).default(5),via:e.string().optional()}).default({}),injection:e.object({enabled:e.boolean().default(!0),maxProcedures:e.number().int().min(1).default(2),minScore:e.number().min(0).max(1).default(.5)}).default({})}).default({}),webhooks:e.array(e.object({id:e.string().regex(/^[a-z0-9][a-z0-9_-]*$/,"webhook id must be lowercase slug"),source:e.string().min(1),agentId:e.string(),secretEnv:e.string().optional(),description:e.string().optional(),enabled:e.boolean().default(!0),node:e.string().optional(),triggers:e.record(e.string(),e.string()).optional(),defaultWorkflow:e.string().optional()})).default([]),session:e.object({staleMinutes:e.number().int().min(1).max(1440).default(720),maxTurnsPerSession:e.number().int().min(2).max(200).default(40),tierTwoThresholdTokens:e.number().int().min(5e4).max(2e5).default(18e4),contextStrategy:e.enum(["layered","planner"]).default("layered"),maxClaudeCodeDispatchesPerHour:e.number().int().min(1).max(1e4).default(80),maxClaudeCodeDispatchesPer5h:e.number().int().min(1).max(5e4).default(180),continuityStateTurns:e.number().int().min(0).max(5).default(0)}).default({}),plugins:e.array(e.string()).default([]),processPool:e.object({maxIdleSeconds:e.number().int().min(5).max(86400).default(30),maxAgeSeconds:e.number().int().min(60).max(86400).default(2700),sweepIntervalSeconds:e.number().int().min(1).max(300).default(5)}).default({})})});export{Qe as a,et as b,j as c,$ as d,ot as e,at as f,rt as g,I as h,De as i,M as j,h as k,Ke as l,He as m,Fe as n,Ve as o};
|
|
15
|
-
//# sourceMappingURL=chunk-ANLKBCYH.js.map
|
package/dist/chunk-BHPIAG3E.js
DELETED
|
@@ -1,5 +0,0 @@
|
|
|
1
|
-
import{l as m,o as b}from"./chunk-ANLKBCYH.js";b();function w(t){let e=typeof t.node=="string"?t.node:"",n=typeof t.token=="string"?t.token:"";if(!e||!n)try{let o=m(t.config);e||(e=o.dashboard?.daemonUrl||""),n||(n=o.dashboard?.token||"")}catch{}return e||(e="http://localhost:18800"),{baseUrl:e.replace(/\/+$/,""),token:n}}async function d(t,e,n){let o={Accept:"application/json"};t.token&&(o.Authorization=`Bearer ${t.token}`);let r=await fetch(`${t.baseUrl}${e}`,{headers:o,signal:n});if(!r.ok)throw new Error(`GET ${e} \u2192 HTTP ${r.status}`);return await r.json()}function R(t,e){return d(t,"/agents",e)}async function S(t,e){return(await d(t,"/api/processes",e)).processes??[]}function P(t,e){return d(t,"/crons",e)}async function h(t,e,n,o){let r={Accept:"application/json","Content-Type":"application/json"};t.token&&(r.Authorization=`Bearer ${t.token}`);let s=await fetch(`${t.baseUrl}${e}`,{method:"POST",headers:r,body:JSON.stringify(n),signal:o}),a=await s.text(),i;try{i=a?JSON.parse(a):{}}catch{i={raw:a}}if(!s.ok)throw new Error(i?.error||`POST ${e} \u2192 HTTP ${s.status}`);return i}function A(t,e,n="tui"){return h(t,"/api/processes/kill",{...e,reason:n})}function C(t,e,n,o){return h(t,"/task",{agent:e,message:n,context:o??{channel:"tui",chatId:"tui:operator"}})}async function $(t,e,n,o={}){let r={Accept:"text/event-stream","Content-Type":"application/json"};t.token&&(r.Authorization=`Bearer ${t.token}`);let s=await fetch(`${t.baseUrl}/task`,{method:"POST",headers:r,body:JSON.stringify({agent:e,message:n,stream:!0,context:{channel:o.channel??"chat-cli",chatId:o.chatId??"chat-cli:operator"}}),signal:o.signal});if(!s.ok||!s.body){let g=await s.text().catch(()=>"");throw new Error(`POST /task (stream) \u2192 HTTP ${s.status}${g?`: ${g.slice(0,200)}`:""}`)}let a=s.body.getReader(),i=new TextDecoder,u={content:""},c="";try{for(;;){let{done:g,value:p}=await a.read();if(g)break;c+=i.decode(p,{stream:!0});let l;for(;(l=c.indexOf(`
|
|
2
|
-
|
|
3
|
-
`))>=0;){let k=c.slice(0,l);c=c.slice(l+2);let f=x(k);f&&T(f,o,u)}}}finally{try{a.releaseLock()}catch{}}return u}function T(t,e,n){let{event:o,data:r}=t;switch(o){case"text":r?.text&&(n.content+=r.text,e.onText?.(r.text));break;case"thinking":r?.text&&e.onThinking?.(r.text);break;case"tool":e.onTool?.(r);break;case"done":typeof r?.content=="string"&&(n.content=r.content),n.usage=r?.usage,n.duration=r?.duration;break;case"error":n.error=r?.error,n.errorKind=r?.errorKind;break}}function x(t){let e="message",n="";for(let r of t.split(`
|
|
4
|
-
`))r.startsWith("event: ")?e=r.slice(7).trim():r.startsWith("data: ")&&(n=r.slice(6));if(!n)return null;let o;try{o=JSON.parse(n)}catch{o=n}return{event:e,data:o}}export{w as a,R as b,S as c,P as d,A as e,C as f,$ as g};
|
|
5
|
-
//# sourceMappingURL=chunk-BHPIAG3E.js.map
|
package/dist/chunk-CQR6C5FU.js
DELETED
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
var g=new Set(["cron","a2a","workflow","selftest"]),m=[[/^User:\s*You are\s/i,"role brief"],[/^User:\s*(Run|Execute)\s/i,"run instruction"],[/^User:\s*\[MISSED RUN/i,"missed cron run"],[/^User:\s*(\[[^\]]{0,40}\]:?\s*)?\[Recent group conversation\]/i,"group chat dump"]];function p(e){if(e.responseLength<=50)return{capture:!1,reason:"response too short"};let o=(e.channel??"").toLowerCase().split("@")[0];if(g.has(o))return{capture:!1,reason:`machine channel: ${o}`};let r=e.content.slice(0,400);for(let[s,u]of m)if(s.test(r))return{capture:!1,reason:u};return{capture:!0}}var y=new Set(["cli","chat-cli","exec","tui","dashboard","admin","test-drive","workflow-editor","voice","opencode","mcp","ntfy"]),w=new Set(["telegram","whatsapp","slack","discord","gitlab","github","api","a2a","mesh","subagent","compaction","cron","workflow","business","heartbeat","selftest"]);function c(e){let t=(e??"").toLowerCase().split("@")[0];return y.has(t)?"operator":w.has(t)?"internal":"external"}var b=[/\bglpat-[A-Za-z0-9_-]{16,}/,/\bgh[pousr]_[A-Za-z0-9]{30,}/,/\bgithub_pat_[A-Za-z0-9_]{20,}/,/\bsk-ant-[A-Za-z0-9_-]{16,}/,/\bsk-(proj-)?[A-Za-z0-9_-]{20,}/,/\bxox[abprs]-[A-Za-z0-9-]{10,}/,/\bAKIA[0-9A-Z]{16}\b/,/\bAIza[0-9A-Za-z_-]{35}\b/,/\b\d{8,10}:[A-Za-z0-9_-]{35}\b/,/-----BEGIN [A-Z ]*PRIVATE KEY-----/,/\beyJ[A-Za-z0-9_-]{10,}\.eyJ[A-Za-z0-9_-]{10,}\.[A-Za-z0-9_-]{10,}/,/\b(password|passwd|pwd|secret|api[_-]?key|access[_-]?key|token)\s*[:=]\s*["']?[^\s"',;]{8,}/i,/\b[a-z][a-z0-9+.-]*:\/\/[^\s:/@]+:[^\s:/@]{6,}@/i];function i(e){return b.some(t=>t.test(e))}function A(e){return e.source.trust??c(e.source.channel)}function R(e){return e==="external"?"held":void 0}function _(e){return e.category==="secret"||i(e.content)||e.review==="rejected"||e.review==="held"?!1:A(e)==="external"?e.review==="approved":!0}var v="claude-haiku-4-20250514",x=`You are a memory extraction system for an AI agent. Given a conversation exchange, extract facts worth remembering for future conversations across different chat sessions.
|
|
2
|
-
|
|
3
|
-
Extract ONLY facts that would help the agent in FUTURE, DIFFERENT conversations:
|
|
4
|
-
- User preferences and instructions ("never do X", "always use Y")
|
|
5
|
-
- Commitments the agent made ("I will deploy by Friday")
|
|
6
|
-
- Relationships ("Alex is the admin", "Marketing handles content")
|
|
7
|
-
- Task state ("GitLab tokens need deploying to peer-server")
|
|
8
|
-
- Important facts about infrastructure, config, or processes
|
|
9
|
-
|
|
10
|
-
SKIP:
|
|
11
|
-
- Credentials of any kind: passwords, tokens, API keys, private keys, connection strings. Never repeat one, not even partly. At most note that a credential exists and where it is kept, without its value.
|
|
12
|
-
- Routine greetings, acknowledgments, status updates
|
|
13
|
-
- Information derivable from code or config files
|
|
14
|
-
- Transient conversation flow ("let me check", "here's what I found")
|
|
15
|
-
- Facts already obvious from the agent's system prompt
|
|
16
|
-
|
|
17
|
-
For each fact, output a JSON array:
|
|
18
|
-
[{"category":"fact|preference|commitment|task-state","content":"concise fact, 1-2 sentences","keywords":["keyword1","keyword2"]}]
|
|
19
|
-
|
|
20
|
-
If nothing worth remembering, output: []`;async function F(e,t,o,r,s){if(t.length<20&&o.length<50||!p({channel:r.channel,content:`User: ${t}`,responseLength:o.length}).capture)return;let{createProvider:d}=await import("./providers-KO2DODIO.js"),l=(await d("claude").generate([{role:"system",content:x},{role:"user",content:`${r.sender} (via ${r.channel}): ${t}
|
|
21
|
-
|
|
22
|
-
Agent: ${o}`}],{model:v,maxTokens:512})).content.trim().match(/\[[\s\S]*\]/);if(!l)return;let a=JSON.parse(l[0]);if(!Array.isArray(a)||a.length===0)return;let f=new Date().toISOString().slice(0,10),h=c(r.channel);for(let n of a)typeof n?.content=="string"&&(n.category==="secret"||i(n.content)||s.hasSimilar(e,n.content)||s.addMemory(e,{agentId:e,category:n.category,content:n.content,keywords:n.keywords||[],source:{...r,date:f,trust:h},expiresAt:n.category==="task-state"?new Date(Date.now()+7*24*60*60*1e3).toISOString():void 0}));Math.random()<.02&&s.prune(e)}export{p as a,c as b,i as c,A as d,R as e,_ as f,F as g};
|
|
23
|
-
//# sourceMappingURL=chunk-CQR6C5FU.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/wiki/capture-filter.ts","../src/agents/memory-trust.ts","../src/agents/memory-extract.ts"],"sourcesContent":["// What deserves to become a raw wiki entry.\n//\n// Until now the only gate was `response.content.length > 50`. Every agent\n// task was captured, with the task's own message as the \"User:\" half — so\n// a cron's prompt became an entry, a role brief became an entry, and a\n// \"[MISSED RUN]\" notice became an entry.\n//\n// Measured over the 10,703 entries that produced: 30% arrived on a\n// machine-origin channel, 33% are prompt-shaped, and 47.5% are one or\n// both. That is the bulk of a corpus that has yielded 257 articles and is\n// read about three times a quarter.\n//\n// These rules are deterministic and free. They are deliberately\n// conservative — each one describes a shape that cannot contain knowledge\n// about the world, rather than guessing at value. Judging whether the\n// REMAINDER is worth keeping is a different question, and belongs to the\n// entry-triage seat, which costs money and can be wrong.\n\n/** Channels where both sides of the exchange are machines. A cron's\n * prompt is configuration, and its reply is a status report. */\nconst MACHINE_CHANNELS = new Set([\"cron\", \"a2a\", \"workflow\", \"selftest\"])\n\n/** Shapes that are an instruction to an agent, not a record of anything.\n * Anchored at the start of the captured content, which always begins\n * \"User: \" followed by the task message. */\nconst PROMPT_SHAPES: Array<[RegExp, string]> = [\n [/^User:\\s*You are\\s/i, \"role brief\"],\n [/^User:\\s*(Run|Execute)\\s/i, \"run instruction\"],\n [/^User:\\s*\\[MISSED RUN/i, \"missed cron run\"],\n // The bracketed prefix varies: some arrive as \"[Group, 09:43]: [Recent\n // group conversation]\". Anchoring on the bare marker missed 367 entries\n // in the first purge, so allow one leading bracketed segment.\n [/^User:\\s*(\\[[^\\]]{0,40}\\]:?\\s*)?\\[Recent group conversation\\]/i, \"group chat dump\"],\n]\n\nexport interface CaptureDecision {\n capture: boolean\n /** Why it was rejected, for logging and for counting what the filter\n * actually removes once it is live. */\n reason?: string\n}\n\nexport function shouldCaptureEntry(input: {\n channel: string | undefined\n content: string\n responseLength: number\n}): CaptureDecision {\n if (input.responseLength <= 50) return { capture: false, reason: \"response too short\" }\n\n const channel = (input.channel ?? \"\").toLowerCase()\n // Channels carry a node suffix: \"telegram@peer-server\".\n const base = channel.split(\"@\")[0]\n if (MACHINE_CHANNELS.has(base)) return { capture: false, reason: `machine channel: ${base}` }\n\n const head = input.content.slice(0, 400)\n for (const [shape, reason] of PROMPT_SHAPES) {\n if (shape.test(head)) return { capture: false, reason }\n }\n\n return { capture: true }\n}\n","// --- What extracted memory may keep, and what it may inject ---\n//\n// Facts are extracted from conversations after every reply and injected\n// into later tasks of the same agent, in any chat. Three rules keep that\n// from becoming a leak or a persistent prompt injection:\n//\n// 1. Secrets are never stored or injected. A credential pasted into one\n// chat must not follow the agent into every other chat.\n// 2. Every fact records how far its source can be trusted, from the\n// channel it came through.\n// 3. Facts from external sources (webhooks, public widgets, anything\n// unknown) are held out of injection until someone approves them:\n// anybody can write to those channels.\n//\n// Pure functions, unit tested.\n\nexport type SourceTrust =\n /** Only the operator can reach it: CLI, dashboard, local voice and TUI. */\n | \"operator\"\n /** Authenticated people or peers: allow-listed chat senders, forge\n * project members, mesh callers. */\n | \"internal\"\n /** Anyone can write to it. */\n | \"external\"\n\nexport type FactReview = \"held\" | \"approved\" | \"rejected\"\n\nconst OPERATOR_CHANNELS = new Set([\n \"cli\", \"chat-cli\", \"exec\", \"tui\", \"dashboard\", \"admin\", \"test-drive\",\n \"workflow-editor\", \"voice\", \"opencode\", \"mcp\", \"ntfy\",\n])\n\n/** People behind an allow-list or project membership, mesh peers, and\n * this node's own automation. New extraction skips the machine channels\n * (cron, workflow, a2a) anyway; older facts from them keep working. */\nconst INTERNAL_CHANNELS = new Set([\n \"telegram\", \"whatsapp\", \"slack\", \"discord\", \"gitlab\", \"github\",\n \"api\", \"a2a\", \"mesh\", \"subagent\", \"compaction\",\n \"cron\", \"workflow\", \"business\", \"heartbeat\", \"selftest\",\n])\n\n/** Trust for a fact's source channel. Channels carry a node suffix\n * (\"telegram@peer-server\"). Anything else, including web-chat,\n * public-api, webhooks and channels added later, is external. */\nexport function trustForChannel(channel: string | undefined): SourceTrust {\n const base = (channel ?? \"\").toLowerCase().split(\"@\")[0]\n if (OPERATOR_CHANNELS.has(base)) return \"operator\"\n if (INTERNAL_CHANNELS.has(base)) return \"internal\"\n return \"external\"\n}\n\n// Shapes of credentials. Deliberately specific: each pattern is a known\n// token format or an explicit assignment, so ordinary prose about \"the\n// token\" or \"a password reset\" is not caught.\nconst SECRET_PATTERNS: RegExp[] = [\n /\\bglpat-[A-Za-z0-9_-]{16,}/, // GitLab PAT\n /\\bgh[pousr]_[A-Za-z0-9]{30,}/, // GitHub tokens\n /\\bgithub_pat_[A-Za-z0-9_]{20,}/,\n /\\bsk-ant-[A-Za-z0-9_-]{16,}/, // Anthropic\n /\\bsk-(proj-)?[A-Za-z0-9_-]{20,}/, // OpenAI-style\n /\\bxox[abprs]-[A-Za-z0-9-]{10,}/, // Slack\n /\\bAKIA[0-9A-Z]{16}\\b/, // AWS access key\n /\\bAIza[0-9A-Za-z_-]{35}\\b/, // Google API key\n /\\b\\d{8,10}:[A-Za-z0-9_-]{35}\\b/, // Telegram bot token\n /-----BEGIN [A-Z ]*PRIVATE KEY-----/,\n /\\beyJ[A-Za-z0-9_-]{10,}\\.eyJ[A-Za-z0-9_-]{10,}\\.[A-Za-z0-9_-]{10,}/, // JWT\n /\\b(password|passwd|pwd|secret|api[_-]?key|access[_-]?key|token)\\s*[:=]\\s*[\"']?[^\\s\"',;]{8,}/i,\n /\\b[a-z][a-z0-9+.-]*:\\/\\/[^\\s:/@]+:[^\\s:/@]{6,}@/i, // URL with user:password@\n]\n\nexport function containsSecret(text: string): boolean {\n return SECRET_PATTERNS.some((p) => p.test(text))\n}\n\n/** The fields of a stored fact this module reads. Older facts have no\n * trust or review; trust then comes from their source channel. */\nexport interface FactTrustFields {\n category: string\n content: string\n source: { channel: string; trust?: SourceTrust }\n review?: FactReview\n}\n\nexport function factTrust(f: FactTrustFields): SourceTrust {\n return f.source.trust ?? trustForChannel(f.source.channel)\n}\n\n/** Whether a new fact from this source waits for review before use. */\nexport function initialReview(trust: SourceTrust): FactReview | undefined {\n return trust === \"external\" ? \"held\" : undefined\n}\n\n/** Whether a stored fact may be injected into a prompt. */\nexport function isInjectable(f: FactTrustFields): boolean {\n if (f.category === \"secret\" || containsSecret(f.content)) return false\n if (f.review === \"rejected\" || f.review === \"held\") return false\n if (factTrust(f) === \"external\") return f.review === \"approved\"\n return true\n}\n","import type { MemoryStore } from \"./memory-store\"\nimport { shouldCaptureEntry } from \"@/wiki/capture-filter\"\nimport { containsSecret, trustForChannel } from \"./memory-trust\"\n\n// --- Haiku-powered memory extraction ---\n// Fire-and-forget after each agent response.\n// Extracts memorable facts and writes them to the persistent store.\n\nconst EXTRACTION_MODEL = \"claude-haiku-4-20250514\"\n\nconst EXTRACTION_PROMPT = `You are a memory extraction system for an AI agent. Given a conversation exchange, extract facts worth remembering for future conversations across different chat sessions.\n\nExtract ONLY facts that would help the agent in FUTURE, DIFFERENT conversations:\n- User preferences and instructions (\"never do X\", \"always use Y\")\n- Commitments the agent made (\"I will deploy by Friday\")\n- Relationships (\"Alex is the admin\", \"Marketing handles content\")\n- Task state (\"GitLab tokens need deploying to peer-server\")\n- Important facts about infrastructure, config, or processes\n\nSKIP:\n- Credentials of any kind: passwords, tokens, API keys, private keys, connection strings. Never repeat one, not even partly. At most note that a credential exists and where it is kept, without its value.\n- Routine greetings, acknowledgments, status updates\n- Information derivable from code or config files\n- Transient conversation flow (\"let me check\", \"here's what I found\")\n- Facts already obvious from the agent's system prompt\n\nFor each fact, output a JSON array:\n[{\"category\":\"fact|preference|commitment|task-state\",\"content\":\"concise fact, 1-2 sentences\",\"keywords\":[\"keyword1\",\"keyword2\"]}]\n\nIf nothing worth remembering, output: []`\n\nexport async function extractMemories(\n agentId: string,\n userMessage: string,\n agentResponse: string,\n source: { channel: string; chatId: string; sender: string },\n store: MemoryStore,\n): Promise<void> {\n // Skip very short exchanges (unlikely to contain memorable facts)\n if (userMessage.length < 20 && agentResponse.length < 50) return\n\n // Same gate as wiki capture: machine channels (cron, a2a, workflow) and\n // prompt-shaped messages hold configuration, not facts about the world.\n const gate = shouldCaptureEntry({\n channel: source.channel,\n content: `User: ${userMessage}`,\n responseLength: agentResponse.length,\n })\n if (!gate.capture) return\n\n const { createProvider } = await import(\"@/agent/providers\")\n const provider = createProvider(\"claude\")\n\n const result = await provider.generate(\n [\n { role: \"system\", content: EXTRACTION_PROMPT },\n {\n role: \"user\",\n content: `${source.sender} (via ${source.channel}): ${userMessage}\\n\\nAgent: ${agentResponse}`,\n },\n ],\n { model: EXTRACTION_MODEL, maxTokens: 512 },\n )\n\n // Parse JSON array from response\n const content = result.content.trim()\n const jsonMatch = content.match(/\\[[\\s\\S]*\\]/)\n if (!jsonMatch) return\n\n const facts = JSON.parse(jsonMatch[0]) as Array<{\n category: string\n content: string\n keywords: string[]\n }>\n\n if (!Array.isArray(facts) || facts.length === 0) return\n\n const date = new Date().toISOString().slice(0, 10)\n const trust = trustForChannel(source.channel)\n\n for (const fact of facts) {\n if (typeof fact?.content !== \"string\") continue\n // The prompt says never to extract credentials; this holds when the\n // model does it anyway. addMemory refuses them too.\n if (fact.category === \"secret\" || containsSecret(fact.content)) continue\n // Skip duplicates\n if (store.hasSimilar(agentId, fact.content)) continue\n\n store.addMemory(agentId, {\n agentId,\n category: fact.category as any,\n content: fact.content,\n keywords: fact.keywords || [],\n source: { ...source, date, trust },\n expiresAt: fact.category === \"task-state\"\n ? new Date(Date.now() + 7 * 24 * 60 * 60 * 1000).toISOString()\n : undefined,\n })\n }\n\n // Prune occasionally (every ~50 calls, probabilistic)\n if (Math.random() < 0.02) {\n store.prune(agentId)\n }\n}\n"],"mappings":"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","names":["MACHINE_CHANNELS","PROMPT_SHAPES","shouldCaptureEntry","input","base","head","shape","reason","OPERATOR_CHANNELS","INTERNAL_CHANNELS","trustForChannel","channel","base","SECRET_PATTERNS","containsSecret","text","p","factTrust","f","initialReview","trust","isInjectable","EXTRACTION_MODEL","EXTRACTION_PROMPT","extractMemories","agentId","userMessage","agentResponse","source","store","shouldCaptureEntry","createProvider","jsonMatch","facts","date","trust","trustForChannel","fact","containsSecret"]}
|
package/dist/chunk-GPQTI5KD.js
DELETED
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
import{i as w}from"./chunk-VCT7ZPIA.js";import{b as h,c as v,d as f,e as g}from"./chunk-J63MRNXF.js";import T from"cronstrue";var y={sun:0,sunday:0,mon:1,monday:1,tue:2,tuesday:2,tues:2,wed:3,wednesday:3,thu:4,thursday:4,thurs:4,fri:5,friday:5,sat:6,saturday:6},p={morning:{h:9,m:0},afternoon:{h:14,m:0},evening:{h:18,m:0},night:{h:22,m:0},noon:{h:12,m:0},midnight:{h:0,m:0}};function l(e){try{return T.toString(e,{use24HourTimeFormat:!1})}catch{return e}}function S(e){if(/\b(noon|midday)\b/.test(e))return p.noon;if(/\bmidnight\b/.test(e))return p.midnight;let t=e.match(/\b(?:at|by|@)\s*(\d{1,2})(?::(\d{2}))?\s*(am|pm)?\b/);if(t){let n=parseInt(t[1],10),s=t[2]?parseInt(t[2],10):0,a=t[3];return a==="pm"&&n<12&&(n+=12),a==="am"&&n===12&&(n=0),n>23||s>59?null:{h:n,m:s}}return null}function k(e){let t=e.trim().toLowerCase();if(!t)return null;let n;if(n=t.match(/\bevery\s+(\d+)\s*(minutes|mins|m)\b/)){let r=parseInt(n[1],10);return r<1||r>59?null:{cron:`*/${r} * * * *`,human:l(`*/${r} * * * *`),matched:n[0]}}if(/\bevery\s+minute\b/.test(t))return{cron:"* * * * *",human:l("* * * * *"),matched:"every minute"};if(n=t.match(/\bevery\s+(\d+)\s*(hours|hrs|h)\b/)){let r=parseInt(n[1],10);return r<1||r>23?null:{cron:`0 */${r} * * *`,human:l(`0 */${r} * * *`),matched:n[0]}}if(/\b(every hour|hourly)\b/.test(t))return{cron:"0 * * * *",human:l("0 * * * *"),matched:"every hour"};let s=S(t),a=null;for(let[r,o]of Object.entries(p))if(!(r==="noon"||r==="midnight")&&new RegExp(`\\b(every\\s+)?${r}s?\\b`).test(t)){a=o;break}let i=s||a,c=t.match(/\b(first|1st|2nd|3rd|last|(\d+)(?:st|nd|rd|th)?)\s+(day\s+)?of\s+(every|each|the)\s+month\b/);if(c){let r=c[1],o=1;if(r==="last"||(/^\d+(st|nd|rd|th)?$/.test(r)?o=parseInt(r,10):r==="first"||r==="1st"?o=1:r==="2nd"?o=2:r==="3rd"&&(o=3),o<1||o>31))return null;let u=i||{h:9,m:0},d=`${u.m} ${u.h} ${o} * *`;return{cron:d,human:l(d),matched:c[0]}}let m=[],b=Object.keys(y).join("|"),E=new RegExp(`\\b(?:every|on|each|by)\\s+((?:${b})s?(?:\\s*(?:,|and|&)\\s*(?:${b})s?)*)\\b`),$=t.match(E);if($){let r=$[1];for(let o of Object.keys(y))if(new RegExp(`\\b${o}s?\\b`).test(r)){let u=y[o];m.includes(u)||m.push(u)}}if(m.length){let r=i||{h:9,m:0};m.sort((d,x)=>d-x);let o=m.join(","),u=`${r.m} ${r.h} * * ${o}`;return{cron:u,human:l(u),matched:`on ${o}`}}if(/\b(weekday|workday|business day)s?\b/.test(t)){let r=i||{h:9,m:0},o=`${r.m} ${r.h} * * 1-5`;return{cron:o,human:l(o),matched:"weekdays"}}if(/\bweekends?\b/.test(t)){let r=i||{h:9,m:0},o=`${r.m} ${r.h} * * 0,6`;return{cron:o,human:l(o),matched:"weekends"}}if(/\b(every day|daily|each day)\b/.test(t)||a){let r=i||{h:9,m:0},o=`${r.m} ${r.h} * * *`;return{cron:o,human:l(o),matched:a&&Object.entries(p).find(([,u])=>u===a)?.[0]||"daily"}}if(s){let r=`${s.m} ${s.h} * * *`;return{cron:r,human:l(r),matched:`at ${s.h}:${String(s.m).padStart(2,"0")}`}}return null}function D(e,t){return`${e.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"").slice(0,40)||"job"}-${t}`}import A from"cronstrue";var I=Intl.DateTimeFormat().resolvedOptions().timeZone,P=600,M='Try: "every morning at 9", "weekdays at 6pm", "every 15 minutes", "every monday at 10am", "1st of every month at noon", "daily at 9:30am", "every hour"',R=/^[A-Za-z0-9][A-Za-z0-9_-]{0,63}$/;function N(e){return R.test(e)}function U(e){try{return new Intl.DateTimeFormat("en-US",{timeZone:e}),!0}catch{return!1}}function q(e){return e?e.split(",").map(t=>t.trim().toLowerCase()).filter(t=>t==="log"||t==="notify"||t==="disable"):["log"]}function z(e){let t=[...e.onError??["log"]];e.notify&&!t.includes("notify")&&t.push("notify");let n={enabled:e.enabled??!0,schedule:e.parsed.cron,timezone:e.timezone||I,agent:e.agent,prompt:e.prompt,timeout:e.timeout??P,onError:t};return e.model&&(n.model=e.model),e.notify&&(n.notify=e.notify),e.createdBy&&(n.createdBy=e.createdBy),e.approval&&(n.approval=e.approval),n}function B(e){try{return A.toString(e,{use24HourTimeFormat:!1})}catch{return e}}function H(e,t,n=new Date){try{return w(e,n,t)}catch{return null}}function V(e,t){if(!e)return"unknown (no match within a year)";try{return`${new Intl.DateTimeFormat("en-GB",{timeZone:t,weekday:"short",day:"2-digit",month:"short",year:"numeric",hour:"2-digit",minute:"2-digit",hour12:!1}).format(e)} (${t})`}catch{return e.toISOString()}}function O(e){return e?.approval?.action==="create"}async function Z(e,t={}){let n="",s=await h(a=>{let i=f(a,`crons.${e}`);if(!i)throw new Error(`cron "${e}" not found`);let c=i.approval;if(!c)throw new Error(`cron "${e}" has no pending request`);c.action==="create"?(delete i.approval,i.enabled=!0,n=`${e} approved and enabled (requested by ${c.requestedBy})`):(g(a,`crons.${e}`),n=`${e} deletion approved; job removed (requested by ${c.requestedBy})`)},{configPath:t.configPath,reload:t.reload});return s.success?{success:!0,message:n,result:s}:{success:!1,message:s.error||"failed",result:s}}async function J(e,t={}){let n="",s=await h(a=>{let i=f(a,`crons.${e}`);if(!i)throw new Error(`cron "${e}" not found`);let c=i.approval;if(!c)throw new Error(`cron "${e}" has no pending request`);c.action==="create"?(g(a,`crons.${e}`),n=`${e} rejected; pending job removed`):(delete i.approval,n=`${e} deletion rejected; job kept`)},{configPath:t.configPath,reload:t.reload});return s.success?{success:!0,message:n,result:s}:{success:!1,message:s.error||"failed",result:s}}async function K(e,t,n={}){return h(s=>{let a=f(s,`crons.${e}`);if(!a)throw new Error(`cron "${e}" not found`);if(t&&O(a))throw new Error(`cron "${e}" is awaiting approval; run \`agentx schedule approve ${e}\``);v(s,`crons.${e}.enabled`,t)},{configPath:n.configPath,reload:n.reload})}export{k as a,D as b,I as c,M as d,N as e,U as f,q as g,z as h,B as i,H as j,V as k,O as l,Z as m,J as n,K as o};
|
|
2
|
-
//# sourceMappingURL=chunk-GPQTI5KD.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/utils/nl-cron.ts","../src/crons/schedule-ops.ts"],"sourcesContent":["import cronstrue from \"cronstrue\"\n\n// --- Natural-language → cron ---\n//\n// Hand-coded pattern matcher for the dozen English phrasings people actually\n// type. Covers every morning/evening, weekdays/weekends, every N minutes,\n// every Monday, daily at X, first of every month, etc.\n//\n// Returns `null` for anything unrecognized rather than guessing — the caller\n// should surface the error to the user with a list of supported phrasings.\n\nexport interface NlCronResult {\n /** Standard 5-field cron expression. */\n cron: string\n /** Human-readable rendering from cronstrue. */\n human: string\n /** The bit of input that matched (useful for error messages + id generation). */\n matched: string\n}\n\ninterface Time { h: number; m: number }\n\nconst DAY_OF_WEEK: Record<string, number> = {\n sun: 0, sunday: 0,\n mon: 1, monday: 1,\n tue: 2, tuesday: 2, tues: 2,\n wed: 3, wednesday: 3,\n thu: 4, thursday: 4, thurs: 4,\n fri: 5, friday: 5,\n sat: 6, saturday: 6,\n}\n\nconst DEFAULT_TIMES: Record<string, Time> = {\n morning: { h: 9, m: 0 },\n afternoon: { h: 14, m: 0 },\n evening: { h: 18, m: 0 },\n night: { h: 22, m: 0 },\n noon: { h: 12, m: 0 },\n midnight: { h: 0, m: 0 },\n}\n\nfunction humanize(cron: string): string {\n try {\n return cronstrue.toString(cron, { use24HourTimeFormat: false })\n } catch {\n return cron\n }\n}\n\n/**\n * Pull out the first \"at HH(:MM)?(am|pm)?\" clause. Also accepts bare\n * \"noon\" / \"midnight\". Returns null if nothing time-like is present.\n */\nfunction extractTime(text: string): Time | null {\n // \"at noon\" / \"at midnight\" / standalone \"noon\" / \"midnight\"\n if (/\\b(noon|midday)\\b/.test(text)) return DEFAULT_TIMES.noon\n if (/\\bmidnight\\b/.test(text)) return DEFAULT_TIMES.midnight\n\n // \"at 9\" / \"at 9am\" / \"at 9:30am\" / \"at 14:30\" / \"by 9am\"\n const m = text.match(/\\b(?:at|by|@)\\s*(\\d{1,2})(?::(\\d{2}))?\\s*(am|pm)?\\b/)\n if (m) {\n let h = parseInt(m[1], 10)\n const min = m[2] ? parseInt(m[2], 10) : 0\n const ampm = m[3]\n if (ampm === \"pm\" && h < 12) h += 12\n if (ampm === \"am\" && h === 12) h = 0\n if (h > 23 || min > 59) return null\n return { h, m: min }\n }\n\n return null\n}\n\n/**\n * Main entry. Returns `null` if we don't recognize the phrasing.\n */\nexport function parseEnglishToCron(raw: string): NlCronResult | null {\n const text = raw.trim().toLowerCase()\n if (!text) return null\n\n // ── every N minutes / every minute ─────────────────────────────────\n let m: RegExpMatchArray | null\n if ((m = text.match(/\\bevery\\s+(\\d+)\\s*(minutes|mins|m)\\b/))) {\n const n = parseInt(m[1], 10)\n if (n < 1 || n > 59) return null\n return { cron: `*/${n} * * * *`, human: humanize(`*/${n} * * * *`), matched: m[0] }\n }\n if (/\\bevery\\s+minute\\b/.test(text)) {\n return { cron: `* * * * *`, human: humanize(`* * * * *`), matched: \"every minute\" }\n }\n\n // ── every hour / hourly / every N hours ────────────────────────────\n if ((m = text.match(/\\bevery\\s+(\\d+)\\s*(hours|hrs|h)\\b/))) {\n const n = parseInt(m[1], 10)\n if (n < 1 || n > 23) return null\n return { cron: `0 */${n} * * *`, human: humanize(`0 */${n} * * *`), matched: m[0] }\n }\n if (/\\b(every hour|hourly)\\b/.test(text)) {\n return { cron: `0 * * * *`, human: humanize(`0 * * * *`), matched: \"every hour\" }\n }\n\n const time = extractTime(text)\n\n // ── keyword-default times (every morning/evening/…) ────────────────\n let dayKeywordTime: Time | null = null\n for (const [kw, t] of Object.entries(DEFAULT_TIMES)) {\n if (kw === \"noon\" || kw === \"midnight\") continue\n if (new RegExp(`\\\\b(every\\\\s+)?${kw}s?\\\\b`).test(text)) {\n dayKeywordTime = t\n break\n }\n }\n const resolvedTime = time || dayKeywordTime\n // If we have no time at all, we can't build a cron for most patterns.\n\n // ── first / nth day of every month ─────────────────────────────────\n const domMatch = text.match(/\\b(first|1st|2nd|3rd|last|(\\d+)(?:st|nd|rd|th)?)\\s+(day\\s+)?of\\s+(every|each|the)\\s+month\\b/)\n if (domMatch) {\n const tok = domMatch[1]\n let dom = 1\n if (tok === \"last\") return null // cron doesn't cleanly support L; punt\n else if (/^\\d+(st|nd|rd|th)?$/.test(tok)) dom = parseInt(tok, 10)\n else if (tok === \"first\" || tok === \"1st\") dom = 1\n else if (tok === \"2nd\") dom = 2\n else if (tok === \"3rd\") dom = 3\n if (dom < 1 || dom > 31) return null\n const t = resolvedTime || { h: 9, m: 0 }\n const cron = `${t.m} ${t.h} ${dom} * *`\n return { cron, human: humanize(cron), matched: domMatch[0] }\n }\n\n // ── named days of the week (mon, tue…) ─────────────────────────────\n // \"every monday at 9\" / \"on mondays\" / \"every monday and friday at 10\"\n //\n // We require a structural anchor (\"every\"/\"on\"/\"each\") before the first day\n // to avoid false positives like \"sun aligns with mars\".\n const dayTokens: number[] = []\n const dayWordsAlt = Object.keys(DAY_OF_WEEK).join(\"|\")\n const anchorRe = new RegExp(`\\\\b(?:every|on|each|by)\\\\s+((?:${dayWordsAlt})s?(?:\\\\s*(?:,|and|&)\\\\s*(?:${dayWordsAlt})s?)*)\\\\b`)\n const anchor = text.match(anchorRe)\n if (anchor) {\n const list = anchor[1]\n for (const w of Object.keys(DAY_OF_WEEK)) {\n if (new RegExp(`\\\\b${w}s?\\\\b`).test(list)) {\n const n = DAY_OF_WEEK[w]\n if (!dayTokens.includes(n)) dayTokens.push(n)\n }\n }\n }\n if (dayTokens.length) {\n const t = resolvedTime || { h: 9, m: 0 }\n dayTokens.sort((a, b) => a - b)\n const dow = dayTokens.join(\",\")\n const cron = `${t.m} ${t.h} * * ${dow}`\n return { cron, human: humanize(cron), matched: `on ${dow}` }\n }\n\n // ── weekdays / weekends ────────────────────────────────────────────\n if (/\\b(weekday|workday|business day)s?\\b/.test(text)) {\n const t = resolvedTime || { h: 9, m: 0 }\n const cron = `${t.m} ${t.h} * * 1-5`\n return { cron, human: humanize(cron), matched: \"weekdays\" }\n }\n if (/\\bweekends?\\b/.test(text)) {\n const t = resolvedTime || { h: 9, m: 0 }\n const cron = `${t.m} ${t.h} * * 0,6`\n return { cron, human: humanize(cron), matched: \"weekends\" }\n }\n\n // ── daily / every day ──────────────────────────────────────────────\n if (/\\b(every day|daily|each day)\\b/.test(text) || dayKeywordTime) {\n const t = resolvedTime || { h: 9, m: 0 }\n const cron = `${t.m} ${t.h} * * *`\n return { cron, human: humanize(cron), matched: dayKeywordTime ? (Object.entries(DEFAULT_TIMES).find(([, v]) => v === dayKeywordTime)?.[0] || \"daily\") : \"daily\" }\n }\n\n // ── bare \"at 9am\" → assume daily ───────────────────────────────────\n if (time) {\n const cron = `${time.m} ${time.h} * * *`\n return { cron, human: humanize(cron), matched: `at ${time.h}:${String(time.m).padStart(2, \"0\")}` }\n }\n\n return null\n}\n\n/** Build a stable slug for cron id from the matched phrase + agent. */\nexport function slugifyScheduleId(phrase: string, agent: string): string {\n const slug = phrase\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, \"-\")\n .replace(/^-+|-+$/g, \"\")\n .slice(0, 40)\n return `${slug || \"job\"}-${agent}`\n}\n","import cronstrue from \"cronstrue\"\nimport { applyConfigMutation, getAtPath, setAtPath, unsetAtPath, type MutationResult } from \"@/daemon/config-mutator\"\nimport type { NlCronResult } from \"@/utils/nl-cron\"\nimport { getNextCronDate } from \"./scheduler\"\n\n// --- Shared schedule operations ---\n//\n// One code path for everything that writes a `crons.<id>` entry from a\n// natural-language schedule: the `agentx schedule` CLI and the agent-facing\n// `agentx_schedule` MCP tool both build jobs here, so the two can never\n// drift into writing different shapes.\n//\n// Also owns the operator side of the approval flow (approve / reject), which\n// only the CLI exposes. Agents can request; they cannot approve.\n\nexport type OnErrorValue = \"log\" | \"notify\" | \"disable\"\n\nexport interface NotifyTarget {\n channel: string\n chatId: string\n accountId?: string\n}\n\nexport interface ScheduleApproval {\n action: \"create\" | \"delete\"\n requestedBy: string\n requestedAt: string\n}\n\n/** Default timezone for schedules created without one: this machine's, the\n * same as the CLI's `--timezone` default. */\nexport const DEFAULT_SCHEDULE_TIMEZONE = Intl.DateTimeFormat().resolvedOptions().timeZone\nexport const DEFAULT_SCHEDULE_TIMEOUT = 600\n\nexport const SUPPORTED_PHRASES_HINT =\n 'Try: \"every morning at 9\", \"weekdays at 6pm\", \"every 15 minutes\", \"every monday at 10am\", ' +\n '\"1st of every month at noon\", \"daily at 9:30am\", \"every hour\"'\n\n/** Cron ids become a dot-path segment (`crons.<id>`), so dots and other\n * separators are refused rather than silently nesting the config. */\nconst SCHEDULE_ID_RE = /^[A-Za-z0-9][A-Za-z0-9_-]{0,63}$/\n\nexport function isValidScheduleId(id: string): boolean {\n return SCHEDULE_ID_RE.test(id)\n}\n\nexport function isValidTimezone(tz: string): boolean {\n try {\n new Intl.DateTimeFormat(\"en-US\", { timeZone: tz })\n return true\n } catch {\n return false\n }\n}\n\nexport function parseOnError(flag: string | undefined): OnErrorValue[] {\n if (!flag) return [\"log\"]\n return flag\n .split(\",\")\n .map((s) => s.trim().toLowerCase())\n .filter((s): s is OnErrorValue => s === \"log\" || s === \"notify\" || s === \"disable\")\n}\n\nexport interface ScheduleJobInput {\n parsed: NlCronResult\n agent: string\n prompt: string\n timezone?: string\n timeout?: number\n model?: string\n notify?: NotifyTarget\n onError?: OnErrorValue[]\n enabled?: boolean\n createdBy?: string\n approval?: ScheduleApproval\n}\n\n/** Build the `crons.<id>` object. A notify target implies the \"notify\"\n * error mode, exactly as the CLI always did. */\nexport function buildScheduleJob(input: ScheduleJobInput): Record<string, unknown> {\n const onError = [...(input.onError ?? [\"log\"])]\n if (input.notify && !onError.includes(\"notify\")) onError.push(\"notify\")\n\n const job: Record<string, unknown> = {\n enabled: input.enabled ?? true,\n schedule: input.parsed.cron,\n timezone: input.timezone || DEFAULT_SCHEDULE_TIMEZONE,\n agent: input.agent,\n prompt: input.prompt,\n timeout: input.timeout ?? DEFAULT_SCHEDULE_TIMEOUT,\n onError,\n }\n if (input.model) job.model = input.model\n if (input.notify) job.notify = input.notify\n if (input.createdBy) job.createdBy = input.createdBy\n if (input.approval) job.approval = input.approval\n return job\n}\n\nexport function humanizeCron(cron: string): string {\n try {\n return cronstrue.toString(cron, { use24HourTimeFormat: false })\n } catch {\n return cron\n }\n}\n\nexport function nextFireTime(cron: string, timezone: string, now: Date = new Date()): Date | null {\n try {\n return getNextCronDate(cron, now, timezone)\n } catch {\n return null\n }\n}\n\n/** \"Mon, 28 Sep 2026, 10:00 (<tz>)\" — the wall-clock time where the job\n * runs, which is what an operator reading an approval request cares about. */\nexport function formatFireTime(d: Date | null, timezone: string): string {\n if (!d) return \"unknown (no match within a year)\"\n try {\n const local = new Intl.DateTimeFormat(\"en-GB\", {\n timeZone: timezone,\n weekday: \"short\",\n day: \"2-digit\",\n month: \"short\",\n year: \"numeric\",\n hour: \"2-digit\",\n minute: \"2-digit\",\n hour12: false,\n }).format(d)\n return `${local} (${timezone})`\n } catch {\n return d.toISOString()\n }\n}\n\nexport function isPendingCreate(job: any): boolean {\n return job?.approval?.action === \"create\"\n}\n\n// ── Operator approval ────────────────────────────────────────────────\n\nexport interface ApprovalOutcome {\n success: boolean\n /** What happened, for the CLI to print. */\n message: string\n result?: MutationResult\n}\n\n/**\n * Apply a pending agent request. `create` → enable and clear the marker;\n * `delete` → remove the job. Hot-reloads the daemon through the same\n * mutator the CLI uses.\n */\nexport async function approveSchedule(\n id: string,\n opts: { configPath?: string; reload?: boolean } = {},\n): Promise<ApprovalOutcome> {\n let message = \"\"\n const result = await applyConfigMutation((cfg) => {\n const job: any = getAtPath(cfg, `crons.${id}`)\n if (!job) throw new Error(`cron \"${id}\" not found`)\n const approval = job.approval as ScheduleApproval | undefined\n if (!approval) throw new Error(`cron \"${id}\" has no pending request`)\n if (approval.action === \"create\") {\n delete job.approval\n job.enabled = true\n message = `${id} approved and enabled (requested by ${approval.requestedBy})`\n } else {\n unsetAtPath(cfg, `crons.${id}`)\n message = `${id} deletion approved; job removed (requested by ${approval.requestedBy})`\n }\n }, { configPath: opts.configPath, reload: opts.reload })\n if (!result.success) return { success: false, message: result.error || \"failed\", result }\n return { success: true, message, result }\n}\n\n/** Refuse a pending request. `create` → drop the never-run job; `delete` →\n * keep the job exactly as it was and clear the marker. */\nexport async function rejectSchedule(\n id: string,\n opts: { configPath?: string; reload?: boolean } = {},\n): Promise<ApprovalOutcome> {\n let message = \"\"\n const result = await applyConfigMutation((cfg) => {\n const job: any = getAtPath(cfg, `crons.${id}`)\n if (!job) throw new Error(`cron \"${id}\" not found`)\n const approval = job.approval as ScheduleApproval | undefined\n if (!approval) throw new Error(`cron \"${id}\" has no pending request`)\n if (approval.action === \"create\") {\n unsetAtPath(cfg, `crons.${id}`)\n message = `${id} rejected; pending job removed`\n } else {\n delete job.approval\n message = `${id} deletion rejected; job kept`\n }\n }, { configPath: opts.configPath, reload: opts.reload })\n if (!result.success) return { success: false, message: result.error || \"failed\", result }\n return { success: true, message, result }\n}\n\n/** Enable/disable, refusing to enable a job still awaiting approval. */\nexport async function setScheduleEnabled(\n id: string,\n enabled: boolean,\n opts: { configPath?: string; reload?: boolean } = {},\n): Promise<MutationResult> {\n return applyConfigMutation((cfg) => {\n const job: any = getAtPath(cfg, `crons.${id}`)\n if (!job) throw new Error(`cron \"${id}\" not found`)\n if (enabled && isPendingCreate(job)) {\n throw new Error(`cron \"${id}\" is awaiting approval; run \\`agentx schedule approve ${id}\\``)\n }\n setAtPath(cfg, `crons.${id}.enabled`, enabled)\n }, { configPath: opts.configPath, reload: opts.reload })\n}\n"],"mappings":"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","names":["cronstrue","DAY_OF_WEEK","DEFAULT_TIMES","humanize","cron","extractTime","text","m","h","min","ampm","parseEnglishToCron","raw","n","time","dayKeywordTime","kw","t","resolvedTime","domMatch","tok","dom","dayTokens","dayWordsAlt","anchorRe","anchor","list","w","a","b","dow","v","slugifyScheduleId","phrase","agent","cronstrue","DEFAULT_SCHEDULE_TIMEZONE","DEFAULT_SCHEDULE_TIMEOUT","SUPPORTED_PHRASES_HINT","SCHEDULE_ID_RE","isValidScheduleId","id","isValidTimezone","tz","parseOnError","flag","s","buildScheduleJob","input","onError","job","humanizeCron","cron","cronstrue","nextFireTime","timezone","now","getNextCronDate","formatFireTime","d","isPendingCreate","approveSchedule","opts","message","result","applyConfigMutation","cfg","getAtPath","approval","unsetAtPath","rejectSchedule","setScheduleEnabled","enabled","setAtPath"]}
|