agent-afk 2.3.0 → 2.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.mjs +1 -1
- package/package.json +12 -12
package/dist/cli.mjs
CHANGED
|
@@ -1905,7 +1905,7 @@ complete -c afk -l trigger -x -a '${n}' -d 'Trigger type'`}function Tp(e){e.comm
|
|
|
1905
1905
|
`);return r.length>0&&r[r.length-1]===""&&r.pop(),r.slice(-t)}catch{return[]}}function Lv(e){try{if(process.platform==="linux"){let t=`/proc/${e}/stat`;if(!$t(t))return{};let r=Mo(t,"utf-8").split(" "),o=Number.parseInt(r[21]??"0",10),l=Rv("/proc/1").mtimeMs/1e3+o/100,c=Math.floor(Date.now()/1e3-l),p=Mo(`/proc/${e}/status`,"utf-8").match(/VmRSS:\s+(\d+)\s+kB/),m=p?Math.round(Number.parseInt(p[1]??"0",10)/1024):void 0;return{uptimeSec:c,memoryMb:m}}if(process.platform==="darwin"){let{execFileSync:t}=Bp("child_process"),n=t("ps",["-p",String(e),"-o","etime=,rss="],{encoding:"utf-8",stdio:["ignore","pipe","ignore"]}).trim(),[r,o]=n.split(/\s+/);return{uptimeSec:Fv(r??""),memoryMb:o?Math.round(Number.parseInt(o,10)/1024):void 0}}}catch{}return{}}function Fv(e){if(!e)return;let t=e.split("-"),n=0,r=e;t.length===2&&(n=Number.parseInt(t[0]??"0",10),r=t[1]??"");let o=r.split(":").map(l=>Number.parseInt(l,10));if(o.some(l=>!Number.isFinite(l)))return;let s=0,a=0,i=0;if(o.length===3)[s,a,i]=o;else if(o.length===2)[a,i]=o;else if(o.length===1)[i]=o;else return;return n*86400+s*3600+a*60+i}import{createInterface as Nv}from"readline";import te from"chalk";var Cp="https://api.telegram.org";async function Pp(e){try{let t=await fetch(`${Cp}/bot${e}/getMe`);if(!t.ok)return null;let n=await t.json();return!n.ok||!n.result?.id||!n.result?.first_name?null:{id:n.result.id,...n.result.username!==void 0?{username:n.result.username}:{},firstName:n.result.first_name}}catch{return null}}function Uv(e){let t=new Map;for(let n of e){let o=(n.message??n.edited_message)?.chat;!o||typeof o.id!="number"||t.set(o.id,{chatId:o.id,type:o.type??"unknown",...o.username!==void 0?{username:o.username}:{},...o.first_name!==void 0?{firstName:o.first_name}:{}})}return[...t.values()].reverse()}async function jv(e){try{let t=await fetch(`${Cp}/bot${e}/getUpdates`);if(!t.ok)return[];let n=await t.json();return!n.ok||!Array.isArray(n.result)?[]:n.result}catch{return[]}}async function Bv(e,t={}){let n=t.maxAttempts??30,r=t.intervalMs??2e3;for(let o=0;o<n;o++){let s=await jv(e),a=Uv(s);if(a.length>0)return a;o<n-1&&await new Promise(i=>setTimeout(i,r))}return[]}function bi(e){let t=Nv({input:process.stdin,output:process.stdout});return new Promise(n=>{t.question(e,r=>{t.close(),n(r.trim())})})}async function Ip(){let e=Ke();console.log(""),console.log(te.bold("\u{1F916} Telegram bot setup")),console.log(""),console.log(te.gray(`Config will be written to ${e}`)),console.log("");let t=process.env.TELEGRAM_BOT_TOKEN?.trim()??"",n=null;for(t&&(console.log(te.gray("Validating existing TELEGRAM_BOT_TOKEN...")),n=await Pp(t),n?console.log(te.green(`\u2713 Token valid for @${n.username??n.firstName} (id ${n.id})`)):(console.log(te.yellow("\u26A0 Existing TELEGRAM_BOT_TOKEN is invalid; prompting for a new one")),t=""));!n;)t=await bi("Paste your bot token (from @BotFather): "),t||(console.error(te.red("No token provided. Aborting.")),process.exit(1)),n=await Pp(t),n||console.log(te.red("\u2717 Token rejected by getMe. Try again or Ctrl-C to abort."));on(e,"TELEGRAM_BOT_TOKEN",t),console.log(te.green(`\u2713 Saved TELEGRAM_BOT_TOKEN \u2192 ${e}`)),console.log(""),console.log(te.bold("Now DM your bot to authorize your account."));let r=n.username?`@${n.username}`:`"${n.firstName}"`;console.log(` 1. Open Telegram and find ${te.cyan(r)}`),console.log(' 2. Send any message (e.g. "hi")'),console.log(""),console.log(te.gray("Polling for your chat ID (up to 60s)..."));let o=await Bv(t);if(o.length===0){console.error(te.red("\u2717 No chats found after 60s.")),console.error(te.gray(" Send a message to the bot and run `afk telegram setup` again,")),console.error(te.gray(" or paste your chat ID manually:"));let a=await bi("Chat ID: "),i=Number.parseInt(a,10);return Number.isFinite(i)||(console.error(te.red("Invalid chat ID. Aborting.")),process.exit(1)),on(e,"AFK_TELEGRAM_ALLOWED_CHAT_IDS",String(i)),console.log(te.green(`\u2713 Saved AFK_TELEGRAM_ALLOWED_CHAT_IDS=${i}`)),{envPath:e,bot:n,chatId:i}}let s=o[0];if(o.length>1){console.log(te.bold(`
|
|
1906
1906
|
Multiple chats found:`)),o.forEach((l,c)=>{let u=l.username?`@${l.username}`:l.firstName??l.type;console.log(` [${c+1}] ${u} (id ${l.chatId}, ${l.type})`)});let a=await bi("Which chat should be allowed? [1]: "),i=Number.parseInt(a||"1",10)-1;Number.isFinite(i)&&i>=0&&i<o.length&&(s=o[i])}else{let a=s.username?`@${s.username}`:s.firstName??s.type;console.log(te.green(`\u2713 Found chat with ${a} (id ${s.chatId})`))}return on(e,"AFK_TELEGRAM_ALLOWED_CHAT_IDS",String(s.chatId)),console.log(te.green(`\u2713 Saved AFK_TELEGRAM_ALLOWED_CHAT_IDS=${s.chatId} \u2192 ${e}`)),console.log(""),console.log(te.bold("Setup complete. Start the bot with:")),console.log(te.cyan(" afk telegram start")),console.log(""),{envPath:e,bot:n,chatId:s.chatId}}function _p(e){let t=e.command("telegram").description("Manage the Agent AFK Telegram bot (setup, start, stop, status)");t.command("setup").description("Interactive setup: validate bot token, discover chat ID, persist to ~/.afk/config/afk.env").action(async()=>{try{await Ip()}catch(n){console.error(Q.red(`Setup failed: ${n.message}`)),process.exit(1)}}),t.command("start").description("Start the bot as a background daemon").action(async()=>{let n=await hi();if(n.kind==="started"){console.log(Q.green(`\u2713 Bot started (PID ${n.pid})`)),console.log(Q.gray(` Logs: ${n.logFile}`)),console.log(Q.gray(" Tail with: afk telegram logs --follow"));return}if(n.kind==="already-running"&&(console.log(Q.yellow(`\u26A0 ${n.message}`)),process.exit(1)),n.kind==="exited-immediately"){if(console.error(Q.red(`\u2717 ${n.message}`)),n.logTail&&n.logTail.length>0){console.error(""),console.error(Q.bold("Last log entries:"));for(let r of n.logTail)console.error(Q.gray(` ${r}`))}process.exit(1)}console.error(Q.red(`\u2717 ${n.message}`)),process.exit(1)}),t.command("stop").description("Stop the bot (SIGTERM, then SIGKILL after 5s)").action(async()=>{let n=await yi();if(n.kind==="not-running"){console.log(Q.yellow("\u26A0 Bot is not running"));return}if(n.kind==="stopped"){console.log(Q.green(`\u2713 Bot stopped (PID ${n.pid})`));return}console.log(Q.yellow(`\u26A0 Bot force-killed (PID ${n.pid}); graceful shutdown timed out`))}),t.command("restart").description("Stop and restart the bot").action(async()=>{let n=await yi();(n.kind==="stopped"||n.kind==="force-killed")&&console.log(Q.gray(`Stopped (PID ${n.pid})`));let r=await hi();if(r.kind==="started"){console.log(Q.green(`\u2713 Bot restarted (PID ${r.pid})`));return}console.error(Q.red(`\u2717 Restart failed: ${r.message}`)),process.exit(1)}),t.command("status").description("Show running state, uptime, memory, and recent log entries").action(()=>{let n=ki();Gv(n)}),t.command("logs").description("Show or follow the bot log").option("-f, --follow","Stream new log entries (like tail -f)",!1).option("-n, --lines <count>","Number of trailing lines to show","50").action(n=>{let{logFile:r}=ki();if(!Wv(r)){console.log(Q.yellow(`No log file at ${r}`)),console.log(Q.gray("Start the bot first: afk telegram start"));return}let o=Number.parseInt(n.lines??"50",10);if(n.follow){Hv("tail",["-n",String(o),"-f",r],{stdio:"inherit"}).on("error",i=>{console.error(Q.red(`Failed to spawn tail: ${i.message}`))});return}let s=Kv(r,"utf-8").split(`
|
|
1907
1907
|
`).slice(-o-1);console.log(s.join(`
|
|
1908
|
-
`))})}function Gv(e){if(console.log(Q.bold("\u{1F4CA} Telegram Bot Status")),console.log(""),e.running?(console.log(` ${Q.green("\u25CF")} Running (PID ${e.pid})`),e.uptimeSec!==void 0&&console.log(` Uptime: ${zv(e.uptimeSec)}`),e.memoryMb!==void 0&&console.log(` Memory: ${e.memoryMb} MB`)):console.log(` ${Q.red("\u25CF")} Stopped`),console.log(` PID: ${e.pidFile}`),console.log(` Logs: ${e.logFile}`),e.logTail&&e.logTail.length>0){console.log(""),console.log(Q.bold("Recent log entries:"));for(let t of e.logTail)console.log(Q.gray(` ${t}`))}}function zv(e){if(e<60)return`${e}s`;let t=Math.floor(e/60);if(t<60)return`${t}m ${e%60}s`;let n=Math.floor(t/60);return n<24?`${n}h ${t%60}m`:`${Math.floor(n/24)}d ${n%24}h`}import{readFileSync as qv}from"fs";import{dirname as Vv,join as Yv}from"path";import{fileURLToPath as Jv}from"url";function Wn(){try{return"2.3.
|
|
1908
|
+
`))})}function Gv(e){if(console.log(Q.bold("\u{1F4CA} Telegram Bot Status")),console.log(""),e.running?(console.log(` ${Q.green("\u25CF")} Running (PID ${e.pid})`),e.uptimeSec!==void 0&&console.log(` Uptime: ${zv(e.uptimeSec)}`),e.memoryMb!==void 0&&console.log(` Memory: ${e.memoryMb} MB`)):console.log(` ${Q.red("\u25CF")} Stopped`),console.log(` PID: ${e.pidFile}`),console.log(` Logs: ${e.logFile}`),e.logTail&&e.logTail.length>0){console.log(""),console.log(Q.bold("Recent log entries:"));for(let t of e.logTail)console.log(Q.gray(` ${t}`))}}function zv(e){if(e<60)return`${e}s`;let t=Math.floor(e/60);if(t<60)return`${t}m ${e%60}s`;let n=Math.floor(t/60);return n<24?`${n}h ${t%60}m`:`${Math.floor(n/24)}d ${n%24}h`}import{readFileSync as qv}from"fs";import{dirname as Vv,join as Yv}from"path";import{fileURLToPath as Jv}from"url";function Wn(){try{return"2.3.1"}catch{}try{let e=Vv(Jv(import.meta.url));for(let t of["../../package.json","../package.json"])try{let n=JSON.parse(qv(Yv(e,t),"utf-8"));if(typeof n.version=="string")return n.version}catch{}}catch{}return"0.0.0-unknown"}import{spawn as Mp}from"child_process";import{existsSync as Xv,mkdirSync as Qv,readFileSync as Rp,unlinkSync as Zv,writeFileSync as ex}from"fs";import{join as $p}from"path";var tx=1440*60*1e3,nx="update-check.json",rx="pending-update.json";function Op(){return $p(Vn(),nx)}function wi(){return $p(Vn(),rx)}function Dp(){let e=Vn();Xv(e)||Qv(e,{recursive:!0})}function ox(e,t){let n=e.split(".").map(Number),r=t.split(".").map(Number),o=Math.max(n.length,r.length);for(let s=0;s<o;s++){let a=n[s]??0,i=r[s]??0;if(i>a)return!0;if(i<a)return!1}return!1}function sx(){try{let e=Rp(Op(),"utf-8"),t=JSON.parse(e);if(typeof t.latestVersion=="string"&&typeof t.checkedAt=="number")return t}catch{}return null}function ix(){try{Dp();let e=`
|
|
1909
1909
|
const https = require('https');
|
|
1910
1910
|
const fs = require('fs');
|
|
1911
1911
|
const url = 'https://registry.npmjs.org/agent-afk/latest';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "agent-afk",
|
|
3
|
-
"version": "2.3.
|
|
3
|
+
"version": "2.3.1",
|
|
4
4
|
"description": "CLI tool for interacting with AI agents via multiple interfaces",
|
|
5
5
|
"main": "dist/index.mjs",
|
|
6
6
|
"type": "module",
|
|
@@ -58,17 +58,17 @@
|
|
|
58
58
|
"postinstall": "node dist/postinstall.mjs || true",
|
|
59
59
|
"build": "tsc && node scripts/copy-prompts.js",
|
|
60
60
|
"dev": "tsx watch src/cli/index.ts",
|
|
61
|
-
"start": "node dist/cli.
|
|
62
|
-
"start:chat": "node dist/cli.
|
|
63
|
-
"start:interactive": "node dist/cli.
|
|
64
|
-
"start:status": "node dist/cli.
|
|
65
|
-
"telegram": "node dist/cli.
|
|
66
|
-
"telegram:setup": "node dist/cli.
|
|
67
|
-
"telegram:start": "node dist/cli.
|
|
68
|
-
"telegram:stop": "node dist/cli.
|
|
69
|
-
"telegram:status": "node dist/cli.
|
|
70
|
-
"telegram:restart": "node dist/cli.
|
|
71
|
-
"telegram:logs": "node dist/cli.
|
|
61
|
+
"start": "node dist/cli/index.js",
|
|
62
|
+
"start:chat": "node dist/cli/index.js chat",
|
|
63
|
+
"start:interactive": "node dist/cli/index.js interactive",
|
|
64
|
+
"start:status": "node dist/cli/index.js status",
|
|
65
|
+
"telegram": "node dist/cli/index.js telegram start",
|
|
66
|
+
"telegram:setup": "node dist/cli/index.js telegram setup",
|
|
67
|
+
"telegram:start": "node dist/cli/index.js telegram start",
|
|
68
|
+
"telegram:stop": "node dist/cli/index.js telegram stop",
|
|
69
|
+
"telegram:status": "node dist/cli/index.js telegram status",
|
|
70
|
+
"telegram:restart": "node dist/cli/index.js telegram restart",
|
|
71
|
+
"telegram:logs": "node dist/cli/index.js telegram logs",
|
|
72
72
|
"test": "vitest run",
|
|
73
73
|
"test:integration": "vitest run tests/integration",
|
|
74
74
|
"test:e2e": "vitest run tests/e2e",
|