@madh-io/alfred-ai 0.9.0 → 0.9.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/bundle/index.js +50 -50
  2. package/package.json +1 -1
package/bundle/index.js CHANGED
@@ -218,7 +218,7 @@ var Ar=Object.defineProperty;var d=(c,e)=>Ar(c,"name",{value:e,configurable:!0})
218
218
  `).run(i.id,i.platform,i.platformUserId,i.username??null,i.displayName??null,i.createdAt,i.updatedAt),i}findById(e){let t=this.db.prepare("SELECT * FROM users WHERE id = ?").get(e);if(t)return this.mapRow(t)}update(e,t){let s=[],r=[];t.username!==void 0&&(s.push("username = ?"),r.push(t.username??null)),t.displayName!==void 0&&(s.push("display_name = ?"),r.push(t.displayName??null)),s.length!==0&&(s.push("updated_at = ?"),r.push(new Date().toISOString()),r.push(e),this.db.prepare(`UPDATE users SET ${s.join(", ")} WHERE id = ?`).run(...r))}updateProfile(e,t){let s=[],r=[];t.timezone!==void 0&&(s.push("timezone = ?"),r.push(t.timezone??null)),t.language!==void 0&&(s.push("language = ?"),r.push(t.language??null)),t.bio!==void 0&&(s.push("bio = ?"),r.push(t.bio??null)),t.preferences!==void 0&&(s.push("preferences = ?"),r.push(t.preferences?JSON.stringify(t.preferences):null)),s.length!==0&&(s.push("updated_at = ?"),r.push(new Date().toISOString()),r.push(e),this.db.prepare(`UPDATE users SET ${s.join(", ")} WHERE id = ?`).run(...r))}getProfile(e){let t=this.db.prepare("SELECT display_name, timezone, language, bio, preferences FROM users WHERE id = ?").get(e);if(t)return{displayName:t.display_name??void 0,timezone:t.timezone??void 0,language:t.language??void 0,bio:t.bio??void 0,preferences:t.preferences?JSON.parse(t.preferences):void 0}}setMasterUser(e,t){this.db.prepare("UPDATE users SET master_user_id = ?, updated_at = ? WHERE id = ?").run(t,new Date().toISOString(),e)}getLinkedUsers(e){return this.db.prepare("SELECT DISTINCT * FROM users WHERE master_user_id = ? OR id = ?").all(e,e).map(s=>this.mapRow(s))}getMasterUserId(e){return this.db.prepare("SELECT master_user_id FROM users WHERE id = ?").get(e)?.master_user_id??e}mapRow(e){return{id:e.id,platform:e.platform,platformUserId:e.platform_user_id,username:e.username??void 0,displayName:e.display_name??void 0,timezone:e.timezone??void 0,language:e.language??void 0,bio:e.bio??void 0,preferences:e.preferences?JSON.parse(e.preferences):void 0,masterUserId:e.master_user_id??void 0,createdAt:e.created_at,updatedAt:e.updated_at}}}});var ue,Vr=f(()=>{"use strict";ue=class{static{d(this,"AuditRepository")}db;constructor(e){this.db=e}log(e){this.db.prepare(`
219
219
  INSERT INTO audit_log (id, timestamp, user_id, action, risk_level, rule_id, effect, platform, chat_id, context)
220
220
  VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
221
- `).run(e.id,e.timestamp.toISOString(),e.userId,e.action,e.riskLevel,e.ruleId??null,e.effect,e.platform,e.chatId??null,e.context?JSON.stringify(e.context):null)}query(e){let t=[],s=[];e.userId&&(t.push("user_id = ?"),s.push(e.userId)),e.action&&(t.push("action = ?"),s.push(e.action)),e.effect&&(t.push("effect = ?"),s.push(e.effect));let r=t.length>0?`WHERE ${t.join(" AND ")}`:"",n=e.limit??100;return s.push(n),this.db.prepare(`SELECT * FROM audit_log ${r} ORDER BY timestamp DESC LIMIT ?`).all(...s).map(i=>this.mapRow(i))}count(e){let t=[],s=[];e.userId&&(t.push("user_id = ?"),s.push(e.userId)),e.effect&&(t.push("effect = ?"),s.push(e.effect));let r=t.length>0?`WHERE ${t.join(" AND ")}`:"";return this.db.prepare(`SELECT COUNT(*) as count FROM audit_log ${r}`).get(...s).count}mapRow(e){return{id:e.id,timestamp:new Date(e.timestamp),userId:e.user_id,action:e.action,riskLevel:e.risk_level,ruleId:e.rule_id??void 0,effect:e.effect,platform:e.platform,chatId:e.chat_id??void 0,context:e.context?JSON.parse(e.context):void 0}}}});import{randomUUID as pi}from"node:crypto";var at,Gr=f(()=>{"use strict";at=class{static{d(this,"MemoryRepository")}db;constructor(e){this.db=e}save(e,t,s,r="general"){return this.saveWithMetadata(e,t,s,r,"general",1,"manual")}saveWithMetadata(e,t,s,r,n,o,i){let a=new Date().toISOString(),l=this.db.prepare("SELECT id FROM memories WHERE user_id = ? AND key = ?").get(e,t);if(l){this.db.prepare("UPDATE memories SET value = ?, category = ?, type = ?, confidence = ?, source = ?, updated_at = ? WHERE id = ?").run(s,r,n,o,i,a,l.id);let p=this.db.prepare("SELECT * FROM memories WHERE id = ?").get(l.id);return this.mapRow(p)}let u=pi();return this.db.prepare("INSERT INTO memories (id, user_id, key, value, category, type, confidence, source, created_at, updated_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)").run(u,e,t,s,r,n,o,i,a,a),{id:u,userId:e,key:t,value:s,category:r,type:n,confidence:o,source:i,lastAccessedAt:null,accessCount:0,createdAt:a,updatedAt:a}}recall(e,t){let s=this.db.prepare("SELECT * FROM memories WHERE user_id = ? AND key = ?").get(e,t);if(s)return this.mapRow(s)}search(e,t){let s=`%${t}%`;return this.db.prepare("SELECT * FROM memories WHERE user_id = ? AND (key LIKE ? OR value LIKE ?) ORDER BY updated_at DESC").all(e,s,s).map(n=>this.mapRow(n))}keywordSearch(e,t,s=20){let r=t.toLowerCase().split(/\s+/).filter(l=>l.length>=2);if(r.length===0)return[];let n=r.map(()=>"(LOWER(key) LIKE ? OR LOWER(value) LIKE ?)").join(" OR "),o=[e];for(let l of r)o.push(`%${l}%`,`%${l}%`);let a=this.db.prepare(`SELECT * FROM memories WHERE user_id = ? AND (${n}) ORDER BY updated_at DESC`).all(...o).map(l=>{let u=this.mapRow(l),p=`${u.key} ${u.value}`.toLowerCase(),m=0;for(let h of r)p.includes(h)&&(m+=1);return{entry:u,score:m/r.length}});return a.sort((l,u)=>u.score-l.score),a.slice(0,s).map(l=>l.entry)}recordAccess(e){let t=new Date().toISOString();this.db.prepare("UPDATE memories SET last_accessed_at = ?, access_count = access_count + 1 WHERE id = ?").run(t,e)}findStale(e,t,s){let r=new Date(Date.now()-t*24*60*60*1e3).toISOString();return this.db.prepare("SELECT * FROM memories WHERE user_id = ? AND updated_at < ? AND confidence <= ? ORDER BY confidence ASC").all(e,r,s).map(o=>this.mapRow(o))}deleteByIds(e){if(e.length===0)return 0;let t=e.map(()=>"?").join(",");return this.db.prepare(`DELETE FROM memories WHERE id IN (${t})`).run(...e).changes}listByCategory(e,t){return this.db.prepare("SELECT * FROM memories WHERE user_id = ? AND category = ? ORDER BY updated_at DESC").all(e,t).map(r=>this.mapRow(r))}listAll(e){return this.db.prepare("SELECT * FROM memories WHERE user_id = ? ORDER BY updated_at DESC").all(e).map(s=>this.mapRow(s))}delete(e,t){return this.db.prepare("DELETE FROM memories WHERE user_id = ? AND key = ?").run(e,t).changes>0}getRecentForPrompt(e,t=20){return this.db.prepare("SELECT * FROM memories WHERE user_id = ? ORDER BY updated_at DESC LIMIT ?").all(e,t).map(r=>this.mapRow(r))}mapRow(e){return{id:e.id,userId:e.user_id,key:e.key,value:e.value,category:e.category||"general",type:e.type||"general",confidence:e.confidence??1,source:e.source||"manual",lastAccessedAt:e.last_accessed_at||null,accessCount:e.access_count??0,createdAt:e.created_at,updatedAt:e.updated_at}}}});import{randomUUID as hi}from"node:crypto";var ct,Yr=f(()=>{"use strict";ct=class{static{d(this,"ReminderRepository")}db;constructor(e){this.db=e}create(e,t,s,r,n){let o={id:hi(),userId:e,platform:t,chatId:s,message:r,triggerAt:n.toISOString(),createdAt:new Date().toISOString(),fired:!1};return this.db.prepare(`
221
+ `).run(e.id,e.timestamp.toISOString(),e.userId,e.action,e.riskLevel,e.ruleId??null,e.effect,e.platform,e.chatId??null,e.context?JSON.stringify(e.context):null)}query(e){let t=[],s=[];e.userId&&(t.push("user_id = ?"),s.push(e.userId)),e.action&&(t.push("action = ?"),s.push(e.action)),e.effect&&(t.push("effect = ?"),s.push(e.effect));let r=t.length>0?`WHERE ${t.join(" AND ")}`:"",n=e.limit??100;return s.push(n),this.db.prepare(`SELECT * FROM audit_log ${r} ORDER BY timestamp DESC LIMIT ?`).all(...s).map(i=>this.mapRow(i))}count(e){let t=[],s=[];e.userId&&(t.push("user_id = ?"),s.push(e.userId)),e.effect&&(t.push("effect = ?"),s.push(e.effect));let r=t.length>0?`WHERE ${t.join(" AND ")}`:"";return this.db.prepare(`SELECT COUNT(*) as count FROM audit_log ${r}`).get(...s).count}mapRow(e){return{id:e.id,timestamp:new Date(e.timestamp),userId:e.user_id,action:e.action,riskLevel:e.risk_level,ruleId:e.rule_id??void 0,effect:e.effect,platform:e.platform,chatId:e.chat_id??void 0,context:e.context?JSON.parse(e.context):void 0}}}});import{randomUUID as pi}from"node:crypto";var at,Gr=f(()=>{"use strict";at=class{static{d(this,"MemoryRepository")}db;constructor(e){this.db=e}save(e,t,s,r="general"){return this.saveWithMetadata(e,t,s,r,"general",1,"manual")}saveWithMetadata(e,t,s,r,n,o,i){let a=new Date().toISOString(),l=this.db.prepare("SELECT id FROM memories WHERE user_id = ? AND key = ?").get(e,t);if(l){this.db.prepare("UPDATE memories SET value = ?, category = ?, type = ?, confidence = ?, source = ?, updated_at = ? WHERE id = ?").run(s,r,n,o,i,a,l.id);let h=this.db.prepare("SELECT * FROM memories WHERE id = ?").get(l.id);return this.mapRow(h)}let u=pi();return this.db.prepare("INSERT INTO memories (id, user_id, key, value, category, type, confidence, source, created_at, updated_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)").run(u,e,t,s,r,n,o,i,a,a),{id:u,userId:e,key:t,value:s,category:r,type:n,confidence:o,source:i,lastAccessedAt:null,accessCount:0,createdAt:a,updatedAt:a}}recall(e,t){let s=this.db.prepare("SELECT * FROM memories WHERE user_id = ? AND key = ?").get(e,t);if(s)return this.mapRow(s)}search(e,t){let s=`%${t}%`;return this.db.prepare("SELECT * FROM memories WHERE user_id = ? AND (key LIKE ? OR value LIKE ?) ORDER BY updated_at DESC").all(e,s,s).map(n=>this.mapRow(n))}keywordSearch(e,t,s=20){let r=t.toLowerCase().split(/\s+/).filter(l=>l.length>=2);if(r.length===0)return[];let n=r.map(()=>"(LOWER(key) LIKE ? OR LOWER(value) LIKE ?)").join(" OR "),o=[e];for(let l of r)o.push(`%${l}%`,`%${l}%`);let a=this.db.prepare(`SELECT * FROM memories WHERE user_id = ? AND (${n}) ORDER BY updated_at DESC`).all(...o).map(l=>{let u=this.mapRow(l),h=`${u.key} ${u.value}`.toLowerCase(),m=0;for(let p of r)h.includes(p)&&(m+=1);return{entry:u,score:m/r.length}});return a.sort((l,u)=>u.score-l.score),a.slice(0,s).map(l=>l.entry)}recordAccess(e){let t=new Date().toISOString();this.db.prepare("UPDATE memories SET last_accessed_at = ?, access_count = access_count + 1 WHERE id = ?").run(t,e)}findStale(e,t,s){let r=new Date(Date.now()-t*24*60*60*1e3).toISOString();return this.db.prepare("SELECT * FROM memories WHERE user_id = ? AND updated_at < ? AND confidence <= ? ORDER BY confidence ASC").all(e,r,s).map(o=>this.mapRow(o))}deleteByIds(e){if(e.length===0)return 0;let t=e.map(()=>"?").join(",");return this.db.prepare(`DELETE FROM memories WHERE id IN (${t})`).run(...e).changes}listByCategory(e,t){return this.db.prepare("SELECT * FROM memories WHERE user_id = ? AND category = ? ORDER BY updated_at DESC").all(e,t).map(r=>this.mapRow(r))}listAll(e){return this.db.prepare("SELECT * FROM memories WHERE user_id = ? ORDER BY updated_at DESC").all(e).map(s=>this.mapRow(s))}delete(e,t){return this.db.prepare("DELETE FROM memories WHERE user_id = ? AND key = ?").run(e,t).changes>0}getRecentForPrompt(e,t=20){return this.db.prepare("SELECT * FROM memories WHERE user_id = ? ORDER BY updated_at DESC LIMIT ?").all(e,t).map(r=>this.mapRow(r))}mapRow(e){return{id:e.id,userId:e.user_id,key:e.key,value:e.value,category:e.category||"general",type:e.type||"general",confidence:e.confidence??1,source:e.source||"manual",lastAccessedAt:e.last_accessed_at||null,accessCount:e.access_count??0,createdAt:e.created_at,updatedAt:e.updated_at}}}});import{randomUUID as hi}from"node:crypto";var ct,Yr=f(()=>{"use strict";ct=class{static{d(this,"ReminderRepository")}db;constructor(e){this.db=e}create(e,t,s,r,n){let o={id:hi(),userId:e,platform:t,chatId:s,message:r,triggerAt:n.toISOString(),createdAt:new Date().toISOString(),fired:!1};return this.db.prepare(`
222
222
  INSERT INTO reminders (id, user_id, platform, chat_id, message, trigger_at, created_at, fired)
223
223
  VALUES (?, ?, ?, ?, ?, ?, ?, ?)
224
224
  `).run(o.id,o.userId,o.platform,o.chatId,o.message,o.triggerAt,o.createdAt,0),o}getDue(){let e=new Date().toISOString();return this.db.prepare("SELECT * FROM reminders WHERE fired = 0 AND trigger_at <= ? ORDER BY trigger_at ASC").all(e).map(s=>this.mapRow(s))}getByUser(e){return this.db.prepare("SELECT * FROM reminders WHERE fired = 0 AND user_id = ? ORDER BY trigger_at ASC").all(e).map(s=>this.mapRow(s))}markFired(e){this.db.prepare("UPDATE reminders SET fired = 1 WHERE id = ?").run(e)}cancel(e){return this.db.prepare("DELETE FROM reminders WHERE id = ?").run(e).changes>0}mapRow(e){return{id:e.id,userId:e.user_id,platform:e.platform,chatId:e.chat_id,message:e.message,triggerAt:e.trigger_at,createdAt:e.created_at,fired:e.fired===1}}}});import{randomUUID as fi}from"node:crypto";var lt,Jr=f(()=>{"use strict";lt=class{static{d(this,"NoteRepository")}db;constructor(e){this.db=e}save(e,t,s){let r=new Date().toISOString(),n=fi();return this.db.prepare("INSERT INTO notes (id, user_id, title, content, created_at, updated_at) VALUES (?, ?, ?, ?, ?, ?)").run(n,e,t,s,r,r),{id:n,userId:e,title:t,content:s,createdAt:r,updatedAt:r}}getById(e){let t=this.db.prepare("SELECT * FROM notes WHERE id = ?").get(e);return t?this.mapRow(t):void 0}list(e,t=50){return this.db.prepare("SELECT * FROM notes WHERE user_id = ? ORDER BY updated_at DESC LIMIT ?").all(e,t).map(r=>this.mapRow(r))}search(e,t){let s=`%${t}%`;return this.db.prepare("SELECT * FROM notes WHERE user_id = ? AND (title LIKE ? OR content LIKE ?) ORDER BY updated_at DESC").all(e,s,s).map(n=>this.mapRow(n))}update(e,t,s){let r=this.getById(e);if(!r)return;let n=new Date().toISOString(),o=t??r.title,i=s??r.content;return this.db.prepare("UPDATE notes SET title = ?, content = ?, updated_at = ? WHERE id = ?").run(o,i,n,e),{...r,title:o,content:i,updatedAt:n}}delete(e){return this.db.prepare("DELETE FROM notes WHERE id = ?").run(e).changes>0}mapRow(e){return{id:e.id,userId:e.user_id,title:e.title,content:e.content,createdAt:e.created_at,updatedAt:e.updated_at}}}});import{randomUUID as gi}from"node:crypto";var dt,Zr=f(()=>{"use strict";dt=class{static{d(this,"EmbeddingRepository")}db;constructor(e){this.db=e}store(e){let t=gi(),s=new Date().toISOString();this.db.prepare("DELETE FROM embeddings WHERE user_id = ? AND source_type = ? AND source_id = ?").run(e.userId,e.sourceType,e.sourceId);let r=Buffer.from(new Float32Array(e.embedding).buffer);return this.db.prepare("INSERT INTO embeddings (id, user_id, source_type, source_id, content, embedding, model, dimensions, created_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)").run(t,e.userId,e.sourceType,e.sourceId,e.content,r,e.model,e.dimensions,s),{id:t,userId:e.userId,sourceType:e.sourceType,sourceId:e.sourceId,content:e.content,embedding:e.embedding,model:e.model,dimensions:e.dimensions,createdAt:s}}findByUser(e){return this.db.prepare("SELECT * FROM embeddings WHERE user_id = ? ORDER BY created_at DESC").all(e).map(s=>this.mapRow(s))}findBySource(e,t){let s=this.db.prepare("SELECT * FROM embeddings WHERE source_type = ? AND source_id = ?").get(e,t);if(s)return this.mapRow(s)}delete(e,t){return this.db.prepare("DELETE FROM embeddings WHERE source_type = ? AND source_id = ?").run(e,t).changes>0}mapRow(e){let t=e.embedding,s=new Float32Array(t.buffer,t.byteOffset,t.byteLength/4),r=Array.from(s);return{id:e.id,userId:e.user_id,sourceType:e.source_type,sourceId:e.source_id,content:e.content,embedding:r,model:e.model,dimensions:e.dimensions,createdAt:e.created_at}}}});import yi from"node:crypto";var ut,Qr=f(()=>{"use strict";ut=class{static{d(this,"LinkTokenRepository")}db;constructor(e){this.db=e}create(e,t){for(let s=0;s<5;s++){let r={id:yi.randomUUID(),code:String(Math.floor(1e5+Math.random()*9e5)),userId:e,platform:t,createdAt:new Date().toISOString(),expiresAt:new Date(Date.now()+6e5).toISOString()};try{return this.db.prepare(`
@@ -251,9 +251,9 @@ var Ar=Object.defineProperty;var d=(c,e)=>Ar(c,"name",{value:e,configurable:!0})
251
251
  UPDATE scheduled_actions
252
252
  SET last_run_at = ?, next_run_at = ?
253
253
  WHERE id = ?
254
- `).run(t,s,e)}setEnabled(e,t){return this.db.prepare("UPDATE scheduled_actions SET enabled = ? WHERE id = ?").run(t?1:0,e).changes>0}delete(e){return this.db.prepare("DELETE FROM scheduled_actions WHERE id = ?").run(e).changes>0}calculateInitialNextRun(e,t){let s=new Date;switch(e){case"interval":{let r=parseInt(t,10);return isNaN(r)||r<=0?null:new Date(s.getTime()+r*6e4).toISOString()}case"once":return new Date(t).toISOString();case"cron":return this.getNextCronDate(t,s)?.toISOString()??null;default:return null}}getNextCronDate(e,t){let s=e.trim().split(/\s+/);if(s.length!==5)return null;let r=new Date(t.getTime()+6e4);r.setSeconds(0,0);for(let n=0;n<1440;n++){if(this.matchesCron(s,r))return r;r.setTime(r.getTime()+6e4)}return null}matchesCron(e,t){let s=t.getMinutes(),r=t.getHours(),n=t.getDate(),o=t.getMonth()+1,i=t.getDay();return this.matchCronField(e[0],s)&&this.matchCronField(e[1],r)&&this.matchCronField(e[2],n)&&this.matchCronField(e[3],o)&&this.matchCronField(e[4],i)}matchCronField(e,t){if(e==="*")return!0;let s=/^\*\/(\d+)$/.exec(e);if(s){let n=parseInt(s[1],10);return t%n===0}let r=parseInt(e,10);return isNaN(r)?!1:t===r}mapRow(e){return{id:e.id,userId:e.user_id,platform:e.platform,chatId:e.chat_id,name:e.name,description:e.description,scheduleType:e.schedule_type,scheduleValue:e.schedule_value,skillName:e.skill_name,skillInput:e.skill_input,promptTemplate:e.prompt_template,enabled:e.enabled===1,lastRunAt:e.last_run_at,nextRunAt:e.next_run_at,createdAt:e.created_at}}}});import{randomUUID as sn}from"node:crypto";var ht,rn=f(()=>{"use strict";ht=class{static{d(this,"DocumentRepository")}db;constructor(e){this.db=e}createDocument(e,t,s,r){let n=sn(),o=new Date().toISOString();return this.db.prepare("INSERT INTO documents (id, user_id, filename, mime_type, size_bytes, chunk_count, created_at) VALUES (?, ?, ?, ?, ?, 0, ?)").run(n,e,t,s,r,o),{id:n,userId:e,filename:t,mimeType:s,sizeBytes:r,chunkCount:0,createdAt:o}}updateChunkCount(e,t){this.db.prepare("UPDATE documents SET chunk_count = ? WHERE id = ?").run(t,e)}addChunk(e,t,s,r){let n=sn(),o=new Date().toISOString();return this.db.prepare("INSERT INTO document_chunks (id, document_id, chunk_index, content, embedding_id, created_at) VALUES (?, ?, ?, ?, ?, ?)").run(n,e,t,s,r??null,o),{id:n,documentId:e,chunkIndex:t,content:s,embeddingId:r,createdAt:o}}getDocument(e){let t=this.db.prepare("SELECT * FROM documents WHERE id = ?").get(e);return t?this.mapDocumentRow(t):void 0}getChunks(e){return this.db.prepare("SELECT * FROM document_chunks WHERE document_id = ? ORDER BY chunk_index ASC").all(e).map(s=>this.mapChunkRow(s))}listByUser(e){return this.db.prepare("SELECT * FROM documents WHERE user_id = ? ORDER BY created_at DESC").all(e).map(s=>this.mapDocumentRow(s))}deleteDocument(e){this.db.transaction(()=>{let s=this.db.prepare("SELECT embedding_id FROM document_chunks WHERE document_id = ? AND embedding_id IS NOT NULL").all(e);if(s.length>0){let r=s.map(o=>o.embedding_id),n=r.map(()=>"?").join(", ");this.db.prepare(`DELETE FROM embeddings WHERE key IN (${n})`).run(...r)}this.db.prepare("DELETE FROM document_chunks WHERE document_id = ?").run(e),this.db.prepare("DELETE FROM documents WHERE id = ?").run(e)})()}getChunksByEmbeddingIds(e){if(e.length===0)return[];let t=e.map(()=>"?").join(", ");return this.db.prepare(`SELECT * FROM document_chunks WHERE embedding_id IN (${t}) ORDER BY chunk_index ASC`).all(...e).map(r=>this.mapChunkRow(r))}mapDocumentRow(e){return{id:e.id,userId:e.user_id,filename:e.filename,mimeType:e.mime_type,sizeBytes:e.size_bytes,chunkCount:e.chunk_count,createdAt:e.created_at}}mapChunkRow(e){return{id:e.id,documentId:e.document_id,chunkIndex:e.chunk_index,content:e.content,embeddingId:e.embedding_id||void 0,createdAt:e.created_at}}}});var Ds=f(()=>{"use strict";Xr();qr();Kr();Vr();Gr();Zt();Ns();Yr();Jr();Zr();Qr();en();tn();rn()});function me(c){if(Os[c])return Os[c];for(let[e,t]of Object.entries(Os))if(c.startsWith(e))return t}var Os,Ti,K,xe=f(()=>{"use strict";Os={"claude-opus-4-20250514":{maxInputTokens:2e5,maxOutputTokens:32e3},"claude-sonnet-4-20250514":{maxInputTokens:2e5,maxOutputTokens:16e3},"claude-haiku-3-5-20241022":{maxInputTokens:2e5,maxOutputTokens:8192},"gpt-4o":{maxInputTokens:128e3,maxOutputTokens:16384},"gpt-4o-mini":{maxInputTokens:128e3,maxOutputTokens:16384},"gpt-4-turbo":{maxInputTokens:128e3,maxOutputTokens:4096},"gpt-4":{maxInputTokens:8192,maxOutputTokens:4096},"gpt-3.5-turbo":{maxInputTokens:16384,maxOutputTokens:4096},o1:{maxInputTokens:2e5,maxOutputTokens:1e5},"o1-mini":{maxInputTokens:128e3,maxOutputTokens:65536},"o3-mini":{maxInputTokens:2e5,maxOutputTokens:1e5},"llama3.2":{maxInputTokens:128e3,maxOutputTokens:4096},"llama3.1":{maxInputTokens:128e3,maxOutputTokens:4096},llama3:{maxInputTokens:8192,maxOutputTokens:4096},mistral:{maxInputTokens:32e3,maxOutputTokens:4096},"mistral-small":{maxInputTokens:32e3,maxOutputTokens:4096},mixtral:{maxInputTokens:32e3,maxOutputTokens:4096},gemma2:{maxInputTokens:8192,maxOutputTokens:4096},"qwen2.5":{maxInputTokens:128e3,maxOutputTokens:4096},phi3:{maxInputTokens:128e3,maxOutputTokens:4096},"deepseek-r1":{maxInputTokens:128e3,maxOutputTokens:8192},"command-r":{maxInputTokens:128e3,maxOutputTokens:4096}},Ti={maxInputTokens:8192,maxOutputTokens:4096};d(me,"lookupContextWindow");K=class{static{d(this,"LLMProvider")}config;contextWindow=Ti;constructor(e){this.config=e}getContextWindow(){return this.contextWindow}async embed(e){}supportsEmbeddings(){return!1}}});import bi from"@anthropic-ai/sdk";var ft,Cs=f(()=>{"use strict";xe();ft=class extends K{static{d(this,"AnthropicProvider")}client;constructor(e){super(e)}async initialize(){this.client=new bi({apiKey:this.config.apiKey});let e=me(this.config.model);e&&(this.contextWindow=e)}async complete(e){let t=this.mapMessages(e.messages),s=e.tools?this.mapTools(e.tools):void 0,r={model:this.config.model,max_tokens:e.maxTokens??this.config.maxTokens??4096,temperature:e.temperature??this.config.temperature,system:e.system,messages:t,tools:s},n=await this.client.messages.create(r);return this.mapResponse(n)}async*stream(e){let t=this.mapMessages(e.messages),s=e.tools?this.mapTools(e.tools):void 0,r=this.client.messages.stream({model:this.config.model,max_tokens:e.maxTokens??this.config.maxTokens??4096,temperature:e.temperature??this.config.temperature,system:e.system,messages:t,tools:s});for await(let n of r)if(n.type==="content_block_delta")n.delta.type==="text_delta"?yield{type:"text_delta",text:n.delta.text}:n.delta.type==="input_json_delta"&&(yield{type:"tool_use_delta",toolCall:{input:n.delta.partial_json}});else if(n.type==="content_block_start")n.content_block.type==="tool_use"&&(yield{type:"tool_use_start",toolCall:{id:n.content_block.id,name:n.content_block.name}});else if(n.type==="message_stop"){let o=await r.finalMessage();yield{type:"message_complete",response:this.mapResponse(o)}}}isAvailable(){return!!this.config.apiKey}mapMessages(e){return e.map(t=>{if(typeof t.content=="string")return{role:t.role,content:t.content};let s=t.content.map(r=>{switch(r.type){case"text":return{type:"text",text:r.text};case"image":return{type:"image",source:{type:"base64",media_type:r.source.media_type,data:r.source.data}};case"tool_use":return{type:"tool_use",id:r.id,name:r.name,input:r.input};case"tool_result":return{type:"tool_result",tool_use_id:r.tool_use_id,content:r.content,is_error:r.is_error}}});return{role:t.role,content:s}})}mapTools(e){return e.map(t=>({name:t.name,description:t.description,input_schema:t.inputSchema}))}mapResponse(e){let t="",s=[];for(let r of e.content)r.type==="text"?t+=r.text:r.type==="tool_use"&&s.push({id:r.id,name:r.name,input:r.input});return{content:t,toolCalls:s.length>0?s:void 0,usage:{inputTokens:e.usage.input_tokens,outputTokens:e.usage.output_tokens},stopReason:e.stop_reason}}}});import Si from"openai";var Q,gt=f(()=>{"use strict";xe();Q=class extends K{static{d(this,"OpenAIProvider")}client;constructor(e){super(e)}async initialize(){this.client=new Si({apiKey:this.config.apiKey,baseURL:this.config.baseUrl});let e=me(this.config.model);e&&(this.contextWindow=e)}async complete(e){let t=this.mapMessages(e.messages,e.system),s=e.tools?this.mapTools(e.tools):void 0,r={model:this.config.model,max_tokens:e.maxTokens??this.config.maxTokens??4096,temperature:e.temperature??this.config.temperature,messages:t,...s?{tools:s}:{}},n=await this.client.chat.completions.create(r);return this.mapResponse(n)}async*stream(e){let t=this.mapMessages(e.messages,e.system),s=e.tools?this.mapTools(e.tools):void 0,r=await this.client.chat.completions.create({model:this.config.model,max_tokens:e.maxTokens??this.config.maxTokens??4096,temperature:e.temperature??this.config.temperature,messages:t,...s?{tools:s}:{},stream:!0}),n,o,i="",a="",l=[],u=null,p=0,m=0;for await(let h of r){let E=h.choices[0];if(!E)continue;let w=E.delta;if(w?.content&&(a+=w.content,yield{type:"text_delta",text:w.content}),w?.tool_calls)for(let T of w.tool_calls)T.id?(n&&l.push({id:n,name:o,input:JSON.parse(i||"{}")}),n=T.id,o=T.function?.name,i=T.function?.arguments??"",yield{type:"tool_use_start",toolCall:{id:n,name:o}}):T.function?.arguments&&(i+=T.function.arguments,yield{type:"tool_use_delta",toolCall:{input:T.function.arguments}});E.finish_reason&&(u=E.finish_reason),h.usage&&(p=h.usage.prompt_tokens,m=h.usage.completion_tokens)}n&&l.push({id:n,name:o,input:JSON.parse(i||"{}")}),yield{type:"message_complete",response:{content:a,toolCalls:l.length>0?l:void 0,usage:{inputTokens:p,outputTokens:m},stopReason:this.mapStopReason(u)}}}isAvailable(){return!!this.config.apiKey}async embed(e){try{let s=(await this.client.embeddings.create({model:"text-embedding-3-small",input:e})).data[0];return{embedding:s.embedding,model:"text-embedding-3-small",dimensions:s.embedding.length}}catch{return}}supportsEmbeddings(){return!0}mapMessages(e,t){let s=[];t&&s.push({role:"system",content:t});for(let r of e){if(typeof r.content=="string"){s.push({role:r.role,content:r.content});continue}let n=[],o=[],i=[];for(let a of r.content)switch(a.type){case"text":n.push({type:"text",text:a.text});break;case"image":n.push({type:"image_url",image_url:{url:`data:${a.source.media_type};base64,${a.source.data}`}});break;case"tool_use":o.push({id:a.id,type:"function",function:{name:a.name,arguments:JSON.stringify(a.input)}});break;case"tool_result":i.push({tool_call_id:a.tool_use_id,content:a.content});break}if(r.role==="assistant"&&o.length>0){let a=n.map(l=>l.text).join("");s.push({role:"assistant",content:a||null,tool_calls:o})}else if(i.length>0)for(let a of i)s.push({role:"tool",tool_call_id:a.tool_call_id,content:a.content});else n.length>0&&(r.role==="user"?s.push({role:"user",content:n}):s.push({role:r.role,content:n.map(a=>a.text).join("")}))}return s}mapTools(e){return e.map(t=>({type:"function",function:{name:t.name,description:t.description,parameters:t.inputSchema}}))}mapResponse(e){let t=e.choices[0],s=t?.message,r=s?.content??"",n=s?.tool_calls?.map(o=>({id:o.id,name:o.function.name,input:(()=>{try{return JSON.parse(o.function.arguments)}catch{return{}}})()}));return{content:r,toolCalls:n&&n.length>0?n:void 0,usage:{inputTokens:e.usage?.prompt_tokens??0,outputTokens:e.usage?.completion_tokens??0},stopReason:this.mapStopReason(t?.finish_reason??null)}}mapStopReason(e){switch(e){case"stop":return"end_turn";case"tool_calls":return"tool_use";case"length":return"max_tokens";default:return"end_turn"}}}});var yt,Us=f(()=>{"use strict";gt();yt=class extends Q{static{d(this,"OpenRouterProvider")}constructor(e){super({...e,baseUrl:e.baseUrl??"https://openrouter.ai/api/v1"})}isAvailable(){return!!this.config.apiKey}supportsEmbeddings(){return!1}}});var wt,Ps=f(()=>{"use strict";xe();wt=class extends K{static{d(this,"OllamaProvider")}baseUrl="";constructor(e){super(e)}apiKey="";async initialize(){let e=this.config.baseUrl??"http://localhost:11434";this.baseUrl=e.replace(/\/v1\/?$/,"").replace(/\/+$/,""),this.apiKey=this.config.apiKey??"";let t=me(this.config.model);t?this.contextWindow=t:await this.fetchModelContextWindow()}async fetchModelContextWindow(){try{let e=await fetch(`${this.baseUrl}/api/show`,{method:"POST",headers:this.getHeaders(),body:JSON.stringify({name:this.config.model})});if(!e.ok)return;let s=(await e.json()).model_info??{},r=Object.keys(s).find(o=>o.includes("context_length")||o==="num_ctx"),n=r?Number(s[r]):0;n>0&&(this.contextWindow={maxInputTokens:n,maxOutputTokens:Math.min(n,4096)})}catch{}}getHeaders(){let e={"Content-Type":"application/json"};return this.apiKey&&(e.Authorization=`Bearer ${this.apiKey}`),e}async complete(e){let t=this.buildMessages(e.messages,e.system),s=e.tools?this.mapTools(e.tools):void 0,r={model:this.config.model,messages:t,stream:!1,options:this.buildOptions(e)};s&&s.length>0&&(r.tools=s);let n=await fetch(`${this.baseUrl}/api/chat`,{method:"POST",headers:this.getHeaders(),body:JSON.stringify(r)});if(!n.ok){let i=await n.text();throw new Error(`Ollama API error (${n.status}): ${i}`)}let o=await n.json();return this.mapResponse(o)}async*stream(e){let t=this.buildMessages(e.messages,e.system),s=e.tools?this.mapTools(e.tools):void 0,r={model:this.config.model,messages:t,stream:!0,options:this.buildOptions(e)};s&&s.length>0&&(r.tools=s);let n=await fetch(`${this.baseUrl}/api/chat`,{method:"POST",headers:this.getHeaders(),body:JSON.stringify(r)});if(!n.ok){let h=await n.text();throw new Error(`Ollama API error (${n.status}): ${h}`)}if(!n.body)throw new Error("Ollama streaming response has no body");let o=n.body.getReader(),i=new TextDecoder,a="",l="",u=0,p=0,m=[];try{for(;;){let{done:h,value:E}=await o.read();if(h)break;a+=i.decode(E,{stream:!0});let w=a.split(`
255
- `);a=w.pop()??"";for(let T of w){let I=T.trim();if(!I)continue;let _;try{_=JSON.parse(I)}catch{continue}if(_.message?.content&&(l+=_.message.content,yield{type:"text_delta",text:_.message.content}),_.message?.tool_calls)for(let k of _.message.tool_calls){let A={id:`ollama_tool_${m.length}`,name:k.function.name,input:k.function.arguments};m.push(A),yield{type:"tool_use_start",toolCall:{id:A.id,name:A.name}},yield{type:"tool_use_delta",toolCall:{input:A.input}}}_.done&&(u=_.prompt_eval_count??0,p=_.eval_count??0,yield{type:"message_complete",response:{content:l,toolCalls:m.length>0?m:void 0,usage:{inputTokens:u,outputTokens:p},stopReason:m.length>0?"tool_use":"end_turn"}})}}if(a.trim()){let h;try{h=JSON.parse(a.trim())}catch{return}if(h.message?.content&&(l+=h.message.content,yield{type:"text_delta",text:h.message.content}),h.message?.tool_calls)for(let E of h.message.tool_calls){let w={id:`ollama_tool_${m.length}`,name:E.function.name,input:E.function.arguments};m.push(w),yield{type:"tool_use_start",toolCall:{id:w.id,name:w.name}},yield{type:"tool_use_delta",toolCall:{input:w.input}}}h.done&&(u=h.prompt_eval_count??0,p=h.eval_count??0,yield{type:"message_complete",response:{content:l,toolCalls:m.length>0?m:void 0,usage:{inputTokens:u,outputTokens:p},stopReason:m.length>0?"tool_use":"end_turn"}})}}finally{o.releaseLock()}}isAvailable(){try{return this.baseUrl.length>0}catch{return!1}}async embed(e){try{let t=await fetch(`${this.baseUrl}/api/embed`,{method:"POST",headers:this.getHeaders(),body:JSON.stringify({model:"nomic-embed-text",input:e})});if(!t.ok)return;let s=await t.json();if(!s.embeddings||s.embeddings.length===0)return;let r=s.embeddings[0];return{embedding:r,model:"nomic-embed-text",dimensions:r.length}}catch{return}}supportsEmbeddings(){return!0}buildOptions(e){let t={},s=e.temperature??this.config.temperature;s!==void 0&&(t.temperature=s);let r=e.maxTokens??this.config.maxTokens;return r!==void 0&&(t.num_predict=r),t}buildMessages(e,t){let s=[];t&&s.push({role:"system",content:t});for(let r of e)typeof r.content=="string"?s.push({role:r.role,content:r.content}):s.push(this.mapContentBlocks(r.role,r.content));return s}mapContentBlocks(e,t){let s=[],r=[];for(let o of t)switch(o.type){case"text":s.push(o.text);break;case"image":r.push(o.source.data);break;case"tool_use":s.push(`[Tool call: ${o.name}(${JSON.stringify(o.input)})]`);break;case"tool_result":s.push(`[Tool result for ${o.tool_use_id}]: ${o.content}`);break}let n={role:e,content:s.join(`
256
- `)};return r.length>0&&(n.images=r),n}mapTools(e){return e.map(t=>({type:"function",function:{name:t.name,description:t.description,parameters:t.inputSchema}}))}mapResponse(e){let t=[];if(e.message.tool_calls)for(let s of e.message.tool_calls)t.push({id:`ollama_tool_${t.length}`,name:s.function.name,input:s.function.arguments});return{content:e.message.content,toolCalls:t.length>0?t:void 0,usage:{inputTokens:e.prompt_eval_count??0,outputTokens:e.eval_count??0},stopReason:t.length>0?"tool_use":"end_turn"}}}});var Et,Fs=f(()=>{"use strict";gt();Et=class extends Q{static{d(this,"OpenWebUIProvider")}constructor(e){super({...e,apiKey:e.apiKey||"openwebui",baseUrl:e.baseUrl??"http://localhost:3000/api/v1"})}isAvailable(){return!0}supportsEmbeddings(){return!1}}});function js(c){switch(c.provider){case"anthropic":return new ft(c);case"openai":return new Q(c);case"openrouter":return new yt(c);case"ollama":return new wt(c);case"openwebui":return new Et(c);default:throw new Error(`Unknown LLM provider: ${c.provider}`)}}var Bs=f(()=>{"use strict";Cs();gt();Us();Ps();Fs();d(js,"createLLMProvider")});function Ws(c){return new Qt(c)}var _i,Qt,nn=f(()=>{"use strict";xe();Bs();_i=["default","strong","fast","embeddings","local"],Qt=class extends K{static{d(this,"ModelRouter")}providers=new Map;multiConfig;constructor(e){super(e.default),this.multiConfig=e}async initialize(){for(let e of _i){let t=this.multiConfig[e];if(t){let s=js(t);await s.initialize(),this.providers.set(e,s)}}}resolve(e){return e&&this.providers.has(e)?this.providers.get(e):this.providers.get("default")}async complete(e){return this.resolve(e.tier).complete(e)}async*stream(e){yield*this.resolve(e.tier).stream(e)}async embed(e){return(this.providers.get("embeddings")??this.resolve()).embed(e)}supportsEmbeddings(){return(this.providers.get("embeddings")??this.resolve()).supportsEmbeddings()}isAvailable(){return this.resolve().isAvailable()}getContextWindow(){return this.resolve().getContextWindow()}};d(Ws,"createModelRouter")});function ne(c){return Math.ceil(c.length/3.5)}function es(c){if(typeof c.content=="string")return ne(c.content)+4;let e=4;for(let t of c.content)switch(t.type){case"text":e+=ne(t.text);break;case"image":e+=1e3;break;case"tool_use":e+=ne(t.name)+ne(JSON.stringify(t.input));break;case"tool_result":e+=ne(t.content);break}return e}var Tt,on=f(()=>{"use strict";d(ne,"estimateTokens");d(es,"estimateMessageTokens");Tt=class{static{d(this,"PromptBuilder")}buildSystemPrompt(e={}){let{memories:t,skills:s,userProfile:r,todayEvents:n}=e,o=process.platform==="darwin"?"macOS":process.platform==="win32"?"Windows":"Linux",i=process.env.HOME||process.env.USERPROFILE||"~",a=`You are Alfred, a personal AI assistant. You run on ${o} (home: ${i}).
254
+ `).run(t,s,e)}setEnabled(e,t){return this.db.prepare("UPDATE scheduled_actions SET enabled = ? WHERE id = ?").run(t?1:0,e).changes>0}delete(e){return this.db.prepare("DELETE FROM scheduled_actions WHERE id = ?").run(e).changes>0}calculateInitialNextRun(e,t){let s=new Date;switch(e){case"interval":{let r=parseInt(t,10);return isNaN(r)||r<=0?null:new Date(s.getTime()+r*6e4).toISOString()}case"once":return new Date(t).toISOString();case"cron":return this.getNextCronDate(t,s)?.toISOString()??null;default:return null}}getNextCronDate(e,t){let s=e.trim().split(/\s+/);if(s.length!==5)return null;let r=new Date(t.getTime()+6e4);r.setSeconds(0,0);for(let n=0;n<1440;n++){if(this.matchesCron(s,r))return r;r.setTime(r.getTime()+6e4)}return null}matchesCron(e,t){let s=t.getMinutes(),r=t.getHours(),n=t.getDate(),o=t.getMonth()+1,i=t.getDay();return this.matchCronField(e[0],s)&&this.matchCronField(e[1],r)&&this.matchCronField(e[2],n)&&this.matchCronField(e[3],o)&&this.matchCronField(e[4],i)}matchCronField(e,t){if(e==="*")return!0;let s=/^\*\/(\d+)$/.exec(e);if(s){let n=parseInt(s[1],10);return t%n===0}let r=parseInt(e,10);return isNaN(r)?!1:t===r}mapRow(e){return{id:e.id,userId:e.user_id,platform:e.platform,chatId:e.chat_id,name:e.name,description:e.description,scheduleType:e.schedule_type,scheduleValue:e.schedule_value,skillName:e.skill_name,skillInput:e.skill_input,promptTemplate:e.prompt_template,enabled:e.enabled===1,lastRunAt:e.last_run_at,nextRunAt:e.next_run_at,createdAt:e.created_at}}}});import{randomUUID as sn}from"node:crypto";var ht,rn=f(()=>{"use strict";ht=class{static{d(this,"DocumentRepository")}db;constructor(e){this.db=e}createDocument(e,t,s,r){let n=sn(),o=new Date().toISOString();return this.db.prepare("INSERT INTO documents (id, user_id, filename, mime_type, size_bytes, chunk_count, created_at) VALUES (?, ?, ?, ?, ?, 0, ?)").run(n,e,t,s,r,o),{id:n,userId:e,filename:t,mimeType:s,sizeBytes:r,chunkCount:0,createdAt:o}}updateChunkCount(e,t){this.db.prepare("UPDATE documents SET chunk_count = ? WHERE id = ?").run(t,e)}addChunk(e,t,s,r){let n=sn(),o=new Date().toISOString();return this.db.prepare("INSERT INTO document_chunks (id, document_id, chunk_index, content, embedding_id, created_at) VALUES (?, ?, ?, ?, ?, ?)").run(n,e,t,s,r??null,o),{id:n,documentId:e,chunkIndex:t,content:s,embeddingId:r,createdAt:o}}getDocument(e){let t=this.db.prepare("SELECT * FROM documents WHERE id = ?").get(e);return t?this.mapDocumentRow(t):void 0}getChunks(e){return this.db.prepare("SELECT * FROM document_chunks WHERE document_id = ? ORDER BY chunk_index ASC").all(e).map(s=>this.mapChunkRow(s))}listByUser(e){return this.db.prepare("SELECT * FROM documents WHERE user_id = ? ORDER BY created_at DESC").all(e).map(s=>this.mapDocumentRow(s))}deleteDocument(e){this.db.transaction(()=>{let s=this.db.prepare("SELECT embedding_id FROM document_chunks WHERE document_id = ? AND embedding_id IS NOT NULL").all(e);if(s.length>0){let r=s.map(o=>o.embedding_id),n=r.map(()=>"?").join(", ");this.db.prepare(`DELETE FROM embeddings WHERE key IN (${n})`).run(...r)}this.db.prepare("DELETE FROM document_chunks WHERE document_id = ?").run(e),this.db.prepare("DELETE FROM documents WHERE id = ?").run(e)})()}getChunksByEmbeddingIds(e){if(e.length===0)return[];let t=e.map(()=>"?").join(", ");return this.db.prepare(`SELECT * FROM document_chunks WHERE embedding_id IN (${t}) ORDER BY chunk_index ASC`).all(...e).map(r=>this.mapChunkRow(r))}mapDocumentRow(e){return{id:e.id,userId:e.user_id,filename:e.filename,mimeType:e.mime_type,sizeBytes:e.size_bytes,chunkCount:e.chunk_count,createdAt:e.created_at}}mapChunkRow(e){return{id:e.id,documentId:e.document_id,chunkIndex:e.chunk_index,content:e.content,embeddingId:e.embedding_id||void 0,createdAt:e.created_at}}}});var Ds=f(()=>{"use strict";Xr();qr();Kr();Vr();Gr();Zt();Ns();Yr();Jr();Zr();Qr();en();tn();rn()});function me(c){if(Os[c])return Os[c];for(let[e,t]of Object.entries(Os))if(c.startsWith(e))return t}var Os,Ti,K,xe=f(()=>{"use strict";Os={"claude-opus-4-20250514":{maxInputTokens:2e5,maxOutputTokens:32e3},"claude-sonnet-4-20250514":{maxInputTokens:2e5,maxOutputTokens:16e3},"claude-haiku-3-5-20241022":{maxInputTokens:2e5,maxOutputTokens:8192},"gpt-4o":{maxInputTokens:128e3,maxOutputTokens:16384},"gpt-4o-mini":{maxInputTokens:128e3,maxOutputTokens:16384},"gpt-4-turbo":{maxInputTokens:128e3,maxOutputTokens:4096},"gpt-4":{maxInputTokens:8192,maxOutputTokens:4096},"gpt-3.5-turbo":{maxInputTokens:16384,maxOutputTokens:4096},o1:{maxInputTokens:2e5,maxOutputTokens:1e5},"o1-mini":{maxInputTokens:128e3,maxOutputTokens:65536},"o3-mini":{maxInputTokens:2e5,maxOutputTokens:1e5},"llama3.2":{maxInputTokens:128e3,maxOutputTokens:4096},"llama3.1":{maxInputTokens:128e3,maxOutputTokens:4096},llama3:{maxInputTokens:8192,maxOutputTokens:4096},mistral:{maxInputTokens:32e3,maxOutputTokens:4096},"mistral-small":{maxInputTokens:32e3,maxOutputTokens:4096},mixtral:{maxInputTokens:32e3,maxOutputTokens:4096},gemma2:{maxInputTokens:8192,maxOutputTokens:4096},"qwen2.5":{maxInputTokens:128e3,maxOutputTokens:4096},phi3:{maxInputTokens:128e3,maxOutputTokens:4096},"deepseek-r1":{maxInputTokens:128e3,maxOutputTokens:8192},"command-r":{maxInputTokens:128e3,maxOutputTokens:4096}},Ti={maxInputTokens:8192,maxOutputTokens:4096};d(me,"lookupContextWindow");K=class{static{d(this,"LLMProvider")}config;contextWindow=Ti;constructor(e){this.config=e}getContextWindow(){return this.contextWindow}async embed(e){}supportsEmbeddings(){return!1}}});import bi from"@anthropic-ai/sdk";var ft,Cs=f(()=>{"use strict";xe();ft=class extends K{static{d(this,"AnthropicProvider")}client;constructor(e){super(e)}async initialize(){this.client=new bi({apiKey:this.config.apiKey});let e=me(this.config.model);e&&(this.contextWindow=e)}async complete(e){let t=this.mapMessages(e.messages),s=e.tools?this.mapTools(e.tools):void 0,r={model:this.config.model,max_tokens:e.maxTokens??this.config.maxTokens??4096,temperature:e.temperature??this.config.temperature,system:e.system,messages:t,tools:s},n=await this.client.messages.create(r);return this.mapResponse(n)}async*stream(e){let t=this.mapMessages(e.messages),s=e.tools?this.mapTools(e.tools):void 0,r=this.client.messages.stream({model:this.config.model,max_tokens:e.maxTokens??this.config.maxTokens??4096,temperature:e.temperature??this.config.temperature,system:e.system,messages:t,tools:s});for await(let n of r)if(n.type==="content_block_delta")n.delta.type==="text_delta"?yield{type:"text_delta",text:n.delta.text}:n.delta.type==="input_json_delta"&&(yield{type:"tool_use_delta",toolCall:{input:n.delta.partial_json}});else if(n.type==="content_block_start")n.content_block.type==="tool_use"&&(yield{type:"tool_use_start",toolCall:{id:n.content_block.id,name:n.content_block.name}});else if(n.type==="message_stop"){let o=await r.finalMessage();yield{type:"message_complete",response:this.mapResponse(o)}}}isAvailable(){return!!this.config.apiKey}mapMessages(e){return e.map(t=>{if(typeof t.content=="string")return{role:t.role,content:t.content};let s=t.content.map(r=>{switch(r.type){case"text":return{type:"text",text:r.text};case"image":return{type:"image",source:{type:"base64",media_type:r.source.media_type,data:r.source.data}};case"tool_use":return{type:"tool_use",id:r.id,name:r.name,input:r.input};case"tool_result":return{type:"tool_result",tool_use_id:r.tool_use_id,content:r.content,is_error:r.is_error}}});return{role:t.role,content:s}})}mapTools(e){return e.map(t=>({name:t.name,description:t.description,input_schema:t.inputSchema}))}mapResponse(e){let t="",s=[];for(let r of e.content)r.type==="text"?t+=r.text:r.type==="tool_use"&&s.push({id:r.id,name:r.name,input:r.input});return{content:t,toolCalls:s.length>0?s:void 0,usage:{inputTokens:e.usage.input_tokens,outputTokens:e.usage.output_tokens},stopReason:e.stop_reason}}}});import _i from"openai";var Q,gt=f(()=>{"use strict";xe();Q=class extends K{static{d(this,"OpenAIProvider")}client;constructor(e){super(e)}async initialize(){this.client=new _i({apiKey:this.config.apiKey,baseURL:this.config.baseUrl});let e=me(this.config.model);e&&(this.contextWindow=e)}async complete(e){let t=this.mapMessages(e.messages,e.system),s=e.tools?this.mapTools(e.tools):void 0,r={model:this.config.model,max_tokens:e.maxTokens??this.config.maxTokens??4096,temperature:e.temperature??this.config.temperature,messages:t,...s?{tools:s}:{}},n=await this.client.chat.completions.create(r);return this.mapResponse(n)}async*stream(e){let t=this.mapMessages(e.messages,e.system),s=e.tools?this.mapTools(e.tools):void 0,r=await this.client.chat.completions.create({model:this.config.model,max_tokens:e.maxTokens??this.config.maxTokens??4096,temperature:e.temperature??this.config.temperature,messages:t,...s?{tools:s}:{},stream:!0}),n,o,i="",a="",l=[],u=null,h=0,m=0;for await(let p of r){let E=p.choices[0];if(!E)continue;let w=E.delta;if(w?.content&&(a+=w.content,yield{type:"text_delta",text:w.content}),w?.tool_calls)for(let T of w.tool_calls)T.id?(n&&l.push({id:n,name:o,input:JSON.parse(i||"{}")}),n=T.id,o=T.function?.name,i=T.function?.arguments??"",yield{type:"tool_use_start",toolCall:{id:n,name:o}}):T.function?.arguments&&(i+=T.function.arguments,yield{type:"tool_use_delta",toolCall:{input:T.function.arguments}});E.finish_reason&&(u=E.finish_reason),p.usage&&(h=p.usage.prompt_tokens,m=p.usage.completion_tokens)}n&&l.push({id:n,name:o,input:JSON.parse(i||"{}")}),yield{type:"message_complete",response:{content:a,toolCalls:l.length>0?l:void 0,usage:{inputTokens:h,outputTokens:m},stopReason:this.mapStopReason(u)}}}isAvailable(){return!!this.config.apiKey}async embed(e){try{let s=(await this.client.embeddings.create({model:"text-embedding-3-small",input:e})).data[0];return{embedding:s.embedding,model:"text-embedding-3-small",dimensions:s.embedding.length}}catch{return}}supportsEmbeddings(){return!0}mapMessages(e,t){let s=[];t&&s.push({role:"system",content:t});for(let r of e){if(typeof r.content=="string"){s.push({role:r.role,content:r.content});continue}let n=[],o=[],i=[];for(let a of r.content)switch(a.type){case"text":n.push({type:"text",text:a.text});break;case"image":n.push({type:"image_url",image_url:{url:`data:${a.source.media_type};base64,${a.source.data}`}});break;case"tool_use":o.push({id:a.id,type:"function",function:{name:a.name,arguments:JSON.stringify(a.input)}});break;case"tool_result":i.push({tool_call_id:a.tool_use_id,content:a.content});break}if(r.role==="assistant"&&o.length>0){let a=n.map(l=>l.text).join("");s.push({role:"assistant",content:a||null,tool_calls:o})}else if(i.length>0)for(let a of i)s.push({role:"tool",tool_call_id:a.tool_call_id,content:a.content});else n.length>0&&(r.role==="user"?s.push({role:"user",content:n}):s.push({role:r.role,content:n.map(a=>a.text).join("")}))}return s}mapTools(e){return e.map(t=>({type:"function",function:{name:t.name,description:t.description,parameters:t.inputSchema}}))}mapResponse(e){let t=e.choices[0],s=t?.message,r=s?.content??"",n=s?.tool_calls?.map(o=>({id:o.id,name:o.function.name,input:(()=>{try{return JSON.parse(o.function.arguments)}catch{return{}}})()}));return{content:r,toolCalls:n&&n.length>0?n:void 0,usage:{inputTokens:e.usage?.prompt_tokens??0,outputTokens:e.usage?.completion_tokens??0},stopReason:this.mapStopReason(t?.finish_reason??null)}}mapStopReason(e){switch(e){case"stop":return"end_turn";case"tool_calls":return"tool_use";case"length":return"max_tokens";default:return"end_turn"}}}});var yt,Us=f(()=>{"use strict";gt();yt=class extends Q{static{d(this,"OpenRouterProvider")}constructor(e){super({...e,baseUrl:e.baseUrl??"https://openrouter.ai/api/v1"})}isAvailable(){return!!this.config.apiKey}supportsEmbeddings(){return!1}}});var wt,Ps=f(()=>{"use strict";xe();wt=class extends K{static{d(this,"OllamaProvider")}baseUrl="";constructor(e){super(e)}apiKey="";async initialize(){let e=this.config.baseUrl??"http://localhost:11434";this.baseUrl=e.replace(/\/v1\/?$/,"").replace(/\/+$/,""),this.apiKey=this.config.apiKey??"";let t=me(this.config.model);t?this.contextWindow=t:await this.fetchModelContextWindow()}async fetchModelContextWindow(){try{let e=await fetch(`${this.baseUrl}/api/show`,{method:"POST",headers:this.getHeaders(),body:JSON.stringify({name:this.config.model})});if(!e.ok)return;let s=(await e.json()).model_info??{},r=Object.keys(s).find(o=>o.includes("context_length")||o==="num_ctx"),n=r?Number(s[r]):0;n>0&&(this.contextWindow={maxInputTokens:n,maxOutputTokens:Math.min(n,4096)})}catch{}}getHeaders(){let e={"Content-Type":"application/json"};return this.apiKey&&(e.Authorization=`Bearer ${this.apiKey}`),e}async complete(e){let t=this.buildMessages(e.messages,e.system),s=e.tools?this.mapTools(e.tools):void 0,r={model:this.config.model,messages:t,stream:!1,options:this.buildOptions(e)};s&&s.length>0&&(r.tools=s);let n=await fetch(`${this.baseUrl}/api/chat`,{method:"POST",headers:this.getHeaders(),body:JSON.stringify(r)});if(!n.ok){let i=await n.text();throw new Error(`Ollama API error (${n.status}): ${i}`)}let o=await n.json();return this.mapResponse(o)}async*stream(e){let t=this.buildMessages(e.messages,e.system),s=e.tools?this.mapTools(e.tools):void 0,r={model:this.config.model,messages:t,stream:!0,options:this.buildOptions(e)};s&&s.length>0&&(r.tools=s);let n=await fetch(`${this.baseUrl}/api/chat`,{method:"POST",headers:this.getHeaders(),body:JSON.stringify(r)});if(!n.ok){let p=await n.text();throw new Error(`Ollama API error (${n.status}): ${p}`)}if(!n.body)throw new Error("Ollama streaming response has no body");let o=n.body.getReader(),i=new TextDecoder,a="",l="",u=0,h=0,m=[];try{for(;;){let{done:p,value:E}=await o.read();if(p)break;a+=i.decode(E,{stream:!0});let w=a.split(`
255
+ `);a=w.pop()??"";for(let T of w){let x=T.trim();if(!x)continue;let S;try{S=JSON.parse(x)}catch{continue}if(S.message?.content&&(l+=S.message.content,yield{type:"text_delta",text:S.message.content}),S.message?.tool_calls)for(let k of S.message.tool_calls){let A={id:`ollama_tool_${m.length}`,name:k.function.name,input:k.function.arguments};m.push(A),yield{type:"tool_use_start",toolCall:{id:A.id,name:A.name}},yield{type:"tool_use_delta",toolCall:{input:A.input}}}S.done&&(u=S.prompt_eval_count??0,h=S.eval_count??0,yield{type:"message_complete",response:{content:l,toolCalls:m.length>0?m:void 0,usage:{inputTokens:u,outputTokens:h},stopReason:m.length>0?"tool_use":"end_turn"}})}}if(a.trim()){let p;try{p=JSON.parse(a.trim())}catch{return}if(p.message?.content&&(l+=p.message.content,yield{type:"text_delta",text:p.message.content}),p.message?.tool_calls)for(let E of p.message.tool_calls){let w={id:`ollama_tool_${m.length}`,name:E.function.name,input:E.function.arguments};m.push(w),yield{type:"tool_use_start",toolCall:{id:w.id,name:w.name}},yield{type:"tool_use_delta",toolCall:{input:w.input}}}p.done&&(u=p.prompt_eval_count??0,h=p.eval_count??0,yield{type:"message_complete",response:{content:l,toolCalls:m.length>0?m:void 0,usage:{inputTokens:u,outputTokens:h},stopReason:m.length>0?"tool_use":"end_turn"}})}}finally{o.releaseLock()}}isAvailable(){try{return this.baseUrl.length>0}catch{return!1}}async embed(e){try{let t=await fetch(`${this.baseUrl}/api/embed`,{method:"POST",headers:this.getHeaders(),body:JSON.stringify({model:"nomic-embed-text",input:e})});if(!t.ok)return;let s=await t.json();if(!s.embeddings||s.embeddings.length===0)return;let r=s.embeddings[0];return{embedding:r,model:"nomic-embed-text",dimensions:r.length}}catch{return}}supportsEmbeddings(){return!0}buildOptions(e){let t={},s=e.temperature??this.config.temperature;s!==void 0&&(t.temperature=s);let r=e.maxTokens??this.config.maxTokens;return r!==void 0&&(t.num_predict=r),t}buildMessages(e,t){let s=[];t&&s.push({role:"system",content:t});for(let r of e)typeof r.content=="string"?s.push({role:r.role,content:r.content}):s.push(this.mapContentBlocks(r.role,r.content));return s}mapContentBlocks(e,t){let s=[],r=[];for(let o of t)switch(o.type){case"text":s.push(o.text);break;case"image":r.push(o.source.data);break;case"tool_use":s.push(`[Tool call: ${o.name}(${JSON.stringify(o.input)})]`);break;case"tool_result":s.push(`[Tool result for ${o.tool_use_id}]: ${o.content}`);break}let n={role:e,content:s.join(`
256
+ `)};return r.length>0&&(n.images=r),n}mapTools(e){return e.map(t=>({type:"function",function:{name:t.name,description:t.description,parameters:t.inputSchema}}))}mapResponse(e){let t=[];if(e.message.tool_calls)for(let s of e.message.tool_calls)t.push({id:`ollama_tool_${t.length}`,name:s.function.name,input:s.function.arguments});return{content:e.message.content,toolCalls:t.length>0?t:void 0,usage:{inputTokens:e.prompt_eval_count??0,outputTokens:e.eval_count??0},stopReason:t.length>0?"tool_use":"end_turn"}}}});var Et,Fs=f(()=>{"use strict";gt();Et=class extends Q{static{d(this,"OpenWebUIProvider")}constructor(e){super({...e,apiKey:e.apiKey||"openwebui",baseUrl:e.baseUrl??"http://localhost:3000/api/v1"})}isAvailable(){return!0}supportsEmbeddings(){return!1}}});function js(c){switch(c.provider){case"anthropic":return new ft(c);case"openai":return new Q(c);case"openrouter":return new yt(c);case"ollama":return new wt(c);case"openwebui":return new Et(c);default:throw new Error(`Unknown LLM provider: ${c.provider}`)}}var Bs=f(()=>{"use strict";Cs();gt();Us();Ps();Fs();d(js,"createLLMProvider")});function Ws(c){return new Qt(c)}var Si,Qt,nn=f(()=>{"use strict";xe();Bs();Si=["default","strong","fast","embeddings","local"],Qt=class extends K{static{d(this,"ModelRouter")}providers=new Map;multiConfig;constructor(e){super(e.default),this.multiConfig=e}async initialize(){for(let e of Si){let t=this.multiConfig[e];if(t){let s=js(t);await s.initialize(),this.providers.set(e,s)}}}resolve(e){return e&&this.providers.has(e)?this.providers.get(e):this.providers.get("default")}async complete(e){return this.resolve(e.tier).complete(e)}async*stream(e){yield*this.resolve(e.tier).stream(e)}async embed(e){return(this.providers.get("embeddings")??this.resolve()).embed(e)}supportsEmbeddings(){return(this.providers.get("embeddings")??this.resolve()).supportsEmbeddings()}isAvailable(){return this.resolve().isAvailable()}getContextWindow(){return this.resolve().getContextWindow()}};d(Ws,"createModelRouter")});function ne(c){return Math.ceil(c.length/3.5)}function es(c){if(typeof c.content=="string")return ne(c.content)+4;let e=4;for(let t of c.content)switch(t.type){case"text":e+=ne(t.text);break;case"image":e+=1e3;break;case"tool_use":e+=ne(t.name)+ne(JSON.stringify(t.input));break;case"tool_result":e+=ne(t.content);break}return e}var Tt,on=f(()=>{"use strict";d(ne,"estimateTokens");d(es,"estimateMessageTokens");Tt=class{static{d(this,"PromptBuilder")}buildSystemPrompt(e={}){let{memories:t,skills:s,userProfile:r,todayEvents:n}=e,o=process.platform==="darwin"?"macOS":process.platform==="win32"?"Windows":"Linux",i=process.env.HOME||process.env.USERPROFILE||"~",a=`You are Alfred, a personal AI assistant. You run on ${o} (home: ${i}).
257
257
 
258
258
  ## Core principles
259
259
  - ACT, don't just talk. When the user asks you to do something, USE YOUR TOOLS immediately. Never say "I could do X" \u2014 just do X.
@@ -273,11 +273,11 @@ For complex tasks, work through multiple steps:
273
273
  - Home: ${i}
274
274
  - Documents: ${i}/Documents
275
275
  - Desktop: ${i}/Desktop
276
- - Downloads: ${i}/Downloads`,l=Intl.DateTimeFormat().resolvedOptions().timeZone,u=r?.timezone||l,p=new Date,m=p.toLocaleTimeString("en-GB",{timeZone:u,hour:"2-digit",minute:"2-digit"}),h=p.toLocaleDateString("en-CA",{timeZone:u}),E=p.toLocaleDateString("en-US",{timeZone:u,weekday:"long"});if(a+=`
276
+ - Downloads: ${i}/Downloads`,l=Intl.DateTimeFormat().resolvedOptions().timeZone,u=r?.timezone||l,h=new Date,m=h.toLocaleTimeString("en-GB",{timeZone:u,hour:"2-digit",minute:"2-digit"}),p=h.toLocaleDateString("en-CA",{timeZone:u}),E=h.toLocaleDateString("en-US",{timeZone:u,weekday:"long"});if(a+=`
277
277
 
278
278
  ## Current date & time`,a+=`
279
279
  - Timezone: ${u}`,a+=`
280
- - Date: ${h} (${E})`,a+=`
280
+ - Date: ${p} (${E})`,a+=`
281
281
  - Time: ${m}`,r?.timezone&&r.timezone!==l&&(a+=`
282
282
  - Server timezone: ${l}`),s&&s.length>0){a+=`
283
283
 
@@ -291,24 +291,24 @@ For complex tasks, work through multiple steps:
291
291
  - Language: ${r.language}`),r.bio&&(a+=`
292
292
  - Bio: ${r.bio}`)),n&&n.length>0){a+=`
293
293
 
294
- ## Today's events`;for(let w of n){let T=w.allDay?"All day":w.start.toLocaleTimeString("en-GB",{hour:"2-digit",minute:"2-digit",...r?.timezone?{timeZone:r.timezone}:{}}),I=w.allDay?"":`-${w.end.toLocaleTimeString("en-GB",{hour:"2-digit",minute:"2-digit",...r?.timezone?{timeZone:r.timezone}:{}})}`,_=w.location?` @ ${w.location}`:"";a+=`
295
- - ${T}${I}: ${w.title}${_}`}}if(t&&t.length>0){if(a+=`
294
+ ## Today's events`;for(let w of n){let T=w.allDay?"All day":w.start.toLocaleTimeString("en-GB",{hour:"2-digit",minute:"2-digit",...r?.timezone?{timeZone:r.timezone}:{}}),x=w.allDay?"":`-${w.end.toLocaleTimeString("en-GB",{hour:"2-digit",minute:"2-digit",...r?.timezone?{timeZone:r.timezone}:{}})}`,S=w.location?` @ ${w.location}`:"";a+=`
295
+ - ${T}${x}: ${w.title}${S}`}}if(t&&t.length>0){if(a+=`
296
296
 
297
297
  ## Memories about this user
298
- `,t.some(T=>T.type&&T.type!=="general")){let T=new Map;for(let _ of t){let k=_.type||"general",A=T.get(k);A||(A=[],T.set(k,A)),A.push(_)}let I={fact:"Facts",preference:"Preferences",correction:"Corrections",entity:"Entities",decision:"Decisions",relationship:"Relationships",principle:"Principles",commitment:"Commitments",moment:"Moments",skill:"Skills",general:"General"};for(let[_,k]of T){a+=`
299
- ### ${I[_]||_}
298
+ `,t.some(T=>T.type&&T.type!=="general")){let T=new Map;for(let S of t){let k=S.type||"general",A=T.get(k);A||(A=[],T.set(k,A)),A.push(S)}let x={fact:"Facts",preference:"Preferences",correction:"Corrections",entity:"Entities",decision:"Decisions",relationship:"Relationships",principle:"Principles",commitment:"Commitments",moment:"Moments",skill:"Skills",general:"General"};for(let[S,k]of T){a+=`
299
+ ### ${x[S]||S}
300
300
  `;for(let A of k)a+=`- ${A.key}: ${A.value}
301
301
  `}}else for(let T of t)a+=`- [${T.category}] ${T.key}: ${T.value}
302
302
  `;a+=`
303
303
  Use these memories to personalize your responses. When the user tells you new facts or preferences, use the memory tool to save them.`}else a+=`
304
304
 
305
- When the user tells you facts about themselves or preferences, use the memory tool to save them for future reference.`;return a}buildMessages(e){return e.filter(t=>t.role==="user"||t.role==="assistant").map(t=>{if(t.toolCalls){let s;try{s=JSON.parse(t.toolCalls)}catch{s=[]}if(t.role==="assistant"){let o=s,i=[];t.content&&i.push({type:"text",text:t.content});for(let a of o)i.push({type:"tool_use",id:a.id,name:a.name,input:a.input});return{role:"assistant",content:i}}let r=s,n=[];for(let o of r)o.type==="tool_result"&&n.push(o);return n.length>0?{role:"user",content:n}:{role:"user",content:t.content||""}}return{role:t.role,content:t.content}})}buildTools(e){return e.map(t=>({name:t.name,description:t.description,inputSchema:t.inputSchema}))}}});var Hs=f(()=>{"use strict";xe();Cs();gt();Us();Ps();Fs();Bs();nn();on()});var bt,Xs=f(()=>{"use strict";bt=class{static{d(this,"RateLimiter")}buckets=new Map;check(e,t){let s=Date.now(),r=t.windowSeconds*1e3,n=this.buckets.get(e);if(!n)return{allowed:!0,remaining:t.maxInvocations,resetsAt:s+r};if(s>n.windowStart+r)return{allowed:!0,remaining:t.maxInvocations,resetsAt:s+r};let o=Math.max(0,t.maxInvocations-n.count);return{allowed:n.count<t.maxInvocations,remaining:o,resetsAt:n.windowStart+r}}increment(e,t){let s=Date.now(),r=t.windowSeconds*1e3,n=this.buckets.get(e);!n||s>n.windowStart+r?this.buckets.set(e,{count:1,windowStart:s}):n.count+=1}reset(){this.buckets.clear()}}});var St,an=f(()=>{"use strict";Xs();St=class{static{d(this,"RuleEngine")}rules=[];rateLimiter=new bt;loadRules(e){this.rules=[...e].sort((t,s)=>t.priority-s.priority)}getRules(){return this.rules}evaluate(e){for(let t of this.rules)if(this.ruleMatches(t,e))return t.rateLimit&&t.effect==="allow"&&!this.checkRateLimit(t,e)?{allowed:!1,matchedRule:t,reason:`Rate limit exceeded for rule: ${t.id}`,timestamp:new Date}:{allowed:t.effect==="allow",matchedRule:t,reason:`Matched rule: ${t.id}`,timestamp:new Date};return{allowed:!1,matchedRule:void 0,reason:"No matching rule found \u2014 default deny",timestamp:new Date}}checkRateLimit(e,t){if(!e.rateLimit)return!0;let s=this.getScopeKey(e.scope,t),r=`${e.id}:${s}`;return this.rateLimiter.check(r,e.rateLimit).allowed?(this.rateLimiter.increment(r,e.rateLimit),!0):!1}resetRateLimits(){this.rateLimiter.reset()}getScopeKey(e,t){switch(e){case"global":return"global";case"user":return t.userId;case"conversation":return t.chatId??"unknown";case"platform":return t.platform}}ruleMatches(e,t){return!(!e.actions.includes("*")&&!e.actions.includes(t.action)||!e.riskLevels.includes(t.riskLevel)||e.conditions&&(e.conditions.users&&e.conditions.users.length>0&&!e.conditions.users.includes(t.userId)||e.conditions.platforms&&e.conditions.platforms.length>0&&!e.conditions.platforms.includes(t.platform)||e.conditions.chatType&&t.chatType&&e.conditions.chatType!==t.chatType||e.conditions.timeWindow&&!this.matchesTimeWindow(e.conditions.timeWindow)))}matchesTimeWindow(e){if(!e)return!0;let t=new Date;if(e.daysOfWeek&&e.daysOfWeek.length>0&&!e.daysOfWeek.includes(t.getDay()))return!1;let s=t.getHours();if(e.startHour!==void 0&&e.endHour!==void 0){if(e.startHour<=e.endHour){if(s<e.startHour||s>=e.endHour)return!1}else if(s>=e.endHour&&s<e.startHour)return!1}else if(e.startHour!==void 0){if(s<e.startHour)return!1}else if(e.endHour!==void 0&&s>=e.endHour)return!1;return!0}}});var cn,ln,dn,pe,un=f(()=>{"use strict";cn=["allow","deny"],ln=["global","user","conversation","platform"],dn=["read","write","destructive","admin"],pe=class{static{d(this,"RuleLoader")}loadFromObject(e){if(!e||!Array.isArray(e.rules))throw new Error('Invalid data: expected an object with a "rules" array');return e.rules.map((t,s)=>this.validateRule(t,s))}validateRule(e,t){if(typeof e!="object"||e===null)throw new Error(`Rule at index ${t} is not an object`);let s=e;if(typeof s.id!="string"||s.id.length===0)throw new Error(`Rule at index ${t} is missing a valid "id" string`);if(typeof s.effect!="string"||!cn.includes(s.effect))throw new Error(`Rule "${s.id}" has invalid "effect": expected one of ${cn.join(", ")}`);if(typeof s.priority!="number"||!Number.isFinite(s.priority))throw new Error(`Rule "${s.id}" is missing a valid "priority" number`);if(typeof s.scope!="string"||!ln.includes(s.scope))throw new Error(`Rule "${s.id}" has invalid "scope": expected one of ${ln.join(", ")}`);if(!Array.isArray(s.actions)||s.actions.length===0)throw new Error(`Rule "${s.id}" is missing a valid "actions" array`);for(let n of s.actions)if(typeof n!="string")throw new Error(`Rule "${s.id}" has a non-string entry in "actions"`);if(!Array.isArray(s.riskLevels)||s.riskLevels.length===0)throw new Error(`Rule "${s.id}" is missing a valid "riskLevels" array`);for(let n of s.riskLevels)if(!dn.includes(n))throw new Error(`Rule "${s.id}" has invalid risk level "${n}": expected one of ${dn.join(", ")}`);let r={id:s.id,effect:s.effect,priority:s.priority,scope:s.scope,actions:s.actions,riskLevels:s.riskLevels};if(s.conditions!==void 0){if(typeof s.conditions!="object"||s.conditions===null)throw new Error(`Rule "${s.id}" has invalid "conditions": expected an object`);r.conditions=s.conditions}if(s.rateLimit!==void 0){if(typeof s.rateLimit!="object"||s.rateLimit===null)throw new Error(`Rule "${s.id}" has invalid "rateLimit": expected an object`);let n=s.rateLimit;if(typeof n.maxInvocations!="number"||typeof n.windowSeconds!="number")throw new Error(`Rule "${s.id}" has invalid "rateLimit": expected maxInvocations and windowSeconds numbers`);r.rateLimit=s.rateLimit}return r}}});import ki from"node:crypto";var _t,mn=f(()=>{"use strict";_t=class{static{d(this,"SecurityManager")}ruleEngine;auditRepository;logger;constructor(e,t,s){this.ruleEngine=e,this.auditRepository=t,this.logger=s}evaluate(e){let t=this.ruleEngine.evaluate(e),s={id:ki.randomUUID(),timestamp:t.timestamp,userId:e.userId,action:e.action,riskLevel:e.riskLevel,ruleId:t.matchedRule?.id,effect:t.allowed?"allow":"deny",platform:e.platform,chatId:e.chatId,context:{chatType:e.chatType,reason:t.reason}};try{this.auditRepository.log(s)}catch(r){this.logger.error({err:r,auditEntry:s},"Failed to write audit log entry")}return this.logger.debug({userId:e.userId,action:e.action,allowed:t.allowed,ruleId:t.matchedRule?.id,reason:t.reason},"Security evaluation completed"),t}}});var ts=f(()=>{"use strict";an();Xs();un();mn()});var b,N=f(()=>{"use strict";b=class{static{d(this,"Skill")}}});var Ie,pn=f(()=>{"use strict";Ie=class{static{d(this,"SkillRegistry")}skills=new Map;register(e){let{name:t}=e.metadata;if(this.skills.has(t))throw new Error(`Skill "${t}" is already registered`);this.skills.set(t,e)}get(e){return this.skills.get(e)}getAll(){return[...this.skills.values()]}has(e){return this.skills.has(e)}toToolDefinitions(){return this.getAll().map(e=>({name:e.metadata.name,description:e.metadata.description,inputSchema:e.metadata.inputSchema}))}}});var $e,hn=f(()=>{"use strict";$e=class{static{d(this,"SkillSandbox")}logger;constructor(e){this.logger=e}async execute(e,t,s,r,n){r=r??e.metadata.timeoutMs??3e4;let{name:o}=e.metadata;return this.logger.info({skill:o,input:t},"Skill execution started"),n?this.executeWithTracker(e,t,s,o,r,n):this.executeWithHardTimeout(e,t,s,o,r)}async executeWithTracker(e,t,s,r,n,o){return new Promise(i=>{let a=!1,l,u,p,m=d(()=>{l&&clearInterval(l),u&&clearTimeout(u),p&&clearTimeout(p)},"cleanup"),h=d(E=>{a||(a=!0,m(),i(E))},"finish");e.execute(t,s).then(E=>{this.logger.info({skill:r,success:E.success},"Skill execution completed"),h(E)},E=>{let w=E instanceof Error?E.message:String(E);this.logger.error({skill:r,error:w},"Skill execution failed"),h({success:!1,error:w})}),p=setTimeout(()=>{if(a)return;let E=o.getIdleMs();if(E>=12e4){let T=o.getSnapshot();this.logger.warn({skill:r,idleMs:E,state:T.state,iteration:T.iteration},"Agent inactive after initial timeout \u2014 aborting"),h({success:!1,error:`Skill "${r}" timed out \u2014 inactive for ${Math.round(E/1e3)}s (last state: ${T.state})`});return}let w=o.getSnapshot();this.logger.info({skill:r,idleMs:E,state:w.state,iteration:w.iteration,totalMs:w.totalElapsedMs},"Initial timeout reached but agent is active \u2014 extending"),l=setInterval(()=>{if(a){m();return}let T=o.getIdleMs(),I=o.getSnapshot();T>=12e4?(this.logger.warn({skill:r,idleMs:T,state:I.state,iteration:I.iteration,totalMs:I.totalElapsedMs},"Agent went inactive \u2014 aborting"),h({success:!1,error:`Skill "${r}" killed \u2014 inactive for ${Math.round(T/1e3)}s (last state: ${I.state})`})):this.logger.debug({skill:r,idleMs:T,state:I.state,iteration:I.iteration},"Agent still active, continuing...")},1e4)},n),u=setTimeout(()=>{if(a)return;let E=o.getSnapshot();this.logger.error({skill:r,totalMs:E.totalElapsedMs,state:E.state,iteration:E.iteration},"Absolute time limit reached \u2014 force killing agent"),h({success:!1,error:`Skill "${r}" force-killed after ${Math.round(12e5/6e4)} minutes (safety limit)`})},12e5)})}async executeWithHardTimeout(e,t,s,r,n){try{let o=await Promise.race([e.execute(t,s),new Promise((i,a)=>{setTimeout(()=>a(new Error(`Skill "${r}" timed out after ${n}ms`)),n)})]);return this.logger.info({skill:r,success:o.success},"Skill execution completed"),o}catch(o){let i=o instanceof Error?o.message:String(o);return this.logger.error({skill:r,error:i},"Skill execution failed"),{success:!1,error:i}}}}});var he,zs=f(()=>{"use strict";he=class{static{d(this,"ActivityTracker")}state="starting";iteration=0;maxIterations=0;currentTool;lastPingAt;startedAt;history=[];onProgress;constructor(e){this.startedAt=Date.now(),this.lastPingAt=Date.now(),this.onProgress=e}ping(e,t){this.state=e,this.lastPingAt=Date.now(),t?.iteration!==void 0&&(this.iteration=t.iteration),t?.maxIterations!==void 0&&(this.maxIterations=t.maxIterations),this.currentTool=t?.tool,this.history.push({state:e,tool:t?.tool,iteration:this.iteration,timestamp:this.lastPingAt}),this.onProgress&&this.onProgress(this.formatStatus())}getIdleMs(){return Date.now()-this.lastPingAt}getTotalElapsedMs(){return Date.now()-this.startedAt}formatStatus(){let e=this.maxIterations>0?` (${this.iteration}/${this.maxIterations})`:"";switch(this.state){case"starting":return"Sub-agent starting...";case"llm_call":return`Sub-agent thinking...${e}`;case"tool_call":return this.currentTool?`Sub-agent using ${this.currentTool}${e}`:`Sub-agent using tool...${e}`;case"processing":return`Sub-agent processing...${e}`;case"done":return`Sub-agent done${e}`;default:return`Sub-agent working...${e}`}}getSnapshot(){return{state:this.state,iteration:this.iteration,maxIterations:this.maxIterations,lastPingAt:this.lastPingAt,idleMs:this.getIdleMs(),currentTool:this.currentTool,totalElapsedMs:this.getTotalElapsedMs(),history:[...this.history]}}}});import vi from"node:fs";import qs from"node:path";var ss,fn=f(()=>{"use strict";N();ss=class{static{d(this,"PluginLoader")}async loadFromDirectory(e){let t=qs.resolve(e),s;try{s=await vi.promises.readdir(t)}catch(o){let i=o instanceof Error?o.message:String(o);return console.warn(`PluginLoader: failed to read directory "${t}": ${i}`),[]}let r=s.filter(o=>o.endsWith(".js")),n=[];for(let o of r){let i=qs.join(t,o);try{let a=await this.loadFromFile(i);n.push(a)}catch(a){let l=a instanceof Error?a.message:String(a);console.warn(`PluginLoader: skipping "${i}": ${l}`)}}return n}async loadFromFile(e){let t=qs.resolve(e),n=(await import(`file:///${t.replace(/\\/g,"/")}`)).default;if(typeof n!="function")throw new Error(`Module "${t}" does not have a default export that is a class`);let o=new n;if(!(o instanceof b))throw new Error(`Default export of "${t}" does not extend Skill`);return this.validateMetadata(o,t),o}validateMetadata(e,t){let{metadata:s}=e;if(!s)throw new Error(`Plugin "${t}" is missing metadata`);if(!s.name||typeof s.name!="string")throw new Error(`Plugin "${t}" has invalid or missing metadata.name`);if(!s.description||typeof s.description!="string")throw new Error(`Plugin "${t}" has invalid or missing metadata.description`);if(!["read","write","destructive","admin"].includes(s.riskLevel))throw new Error(`Plugin "${t}" has invalid metadata.riskLevel: "${String(s.riskLevel)}"`);if(!s.version||typeof s.version!="string")throw new Error(`Plugin "${t}" has invalid or missing metadata.version`)}}});var xi,Ii,Re,gn=f(()=>{"use strict";N();xi=/^[\d+\-*/().,%\s]|Math\.(sin|cos|tan|sqrt|pow|abs|floor|ceil|round|log|log2|log10|PI|E)/,Ii=/^[0-9+\-*/().,\s%]*(Math\.(sin|cos|tan|sqrt|pow|abs|floor|ceil|round|log|log2|log10|PI|E)[(0-9+\-*/().,\s%]*)*$/,Re=class extends b{static{d(this,"CalculatorSkill")}metadata={name:"calculator",description:"Evaluate mathematical expressions. Use for any calculation, unit conversion, or math question the user asks.",riskLevel:"read",version:"1.0.0",inputSchema:{type:"object",properties:{expression:{type:"string",description:"The mathematical expression to evaluate"}},required:["expression"]}};async execute(e,t){let s=e.expression;if(!s||typeof s!="string")return{success:!1,error:"Invalid expression: input must be a non-empty string"};let r=s.trim();if(!xi.test(r))return{success:!1,error:`Invalid expression: "${r}" contains disallowed characters`};if(!Ii.test(r))return{success:!1,error:`Invalid expression: "${r}" contains disallowed constructs`};try{let o=new Function("Math",`"use strict"; return (${r});`)(Math);return typeof o!="number"||!isFinite(o)?{success:!1,error:`Invalid expression: "${r}" did not produce a finite number`}:{success:!0,data:o,display:`${r} = ${o}`}}catch{return{success:!1,error:`Invalid expression: "${r}"`}}}}});var Ae,yn=f(()=>{"use strict";N();Ae=class extends b{static{d(this,"SystemInfoSkill")}metadata={name:"system_info",description:'Get system information: current date/time (datetime), system stats (general), memory usage (memory), or uptime (uptime). Use "datetime" when the user asks what day/time it is.',riskLevel:"read",version:"1.0.0",inputSchema:{type:"object",properties:{category:{type:"string",enum:["general","memory","uptime","datetime"],description:"Category of system info (use datetime for current date/time)"}},required:["category"]}};async execute(e,t){let s=e.category;switch(s){case"general":return this.getGeneralInfo();case"memory":return this.getMemoryInfo();case"uptime":return this.getUptimeInfo();case"datetime":return this.getDateTimeInfo();default:return{success:!1,error:`Unknown category: "${String(s)}". Valid categories: general, memory, uptime`}}}getGeneralInfo(){let e={nodeVersion:process.version,platform:process.platform,arch:process.arch};return{success:!0,data:e,display:`Node.js ${e.nodeVersion} on ${e.platform} (${e.arch})`}}getMemoryInfo(){let e=process.memoryUsage(),t=d(r=>(r/1024/1024).toFixed(2),"toMB"),s={rss:`${t(e.rss)} MB`,heapTotal:`${t(e.heapTotal)} MB`,heapUsed:`${t(e.heapUsed)} MB`,external:`${t(e.external)} MB`};return{success:!0,data:s,display:`Memory \u2014 RSS: ${s.rss}, Heap: ${s.heapUsed} / ${s.heapTotal}, External: ${s.external}`}}getUptimeInfo(){let e=process.uptime(),t=Math.floor(e/3600),s=Math.floor(e%3600/60),r=Math.floor(e%60),n={uptimeSeconds:e,formatted:`${t}h ${s}m ${r}s`};return{success:!0,data:n,display:`Uptime: ${n.formatted}`}}getDateTimeInfo(){let e=new Date,t={iso:e.toISOString(),date:e.toLocaleDateString("de-DE",{weekday:"long",year:"numeric",month:"long",day:"numeric"}),time:e.toLocaleTimeString("de-DE"),timezone:Intl.DateTimeFormat().resolvedOptions().timeZone,timestamp:e.getTime()};return{success:!0,data:t,display:`${t.date}, ${t.time} (${t.timezone})`}}}});var Le,wn=f(()=>{"use strict";N();Le=class extends b{static{d(this,"WebSearchSkill")}config;metadata={name:"web_search",description:"Search the internet for current information, news, facts, or anything the user asks about that you don't know. Use this whenever you need up-to-date information.",riskLevel:"read",version:"1.1.0",inputSchema:{type:"object",properties:{query:{type:"string",description:"The search query"},count:{type:"number",description:"Number of results to return (default: 5, max: 10)"}},required:["query"]}};constructor(e){super(),this.config=e}async execute(e,t){let s=e.query,r=Math.min(Math.max(1,e.count||5),10);if(!s||typeof s!="string")return{success:!1,error:'Invalid input: "query" must be a non-empty string'};if(!this.config)return{success:!1,error:"Web search is not configured. Run `alfred setup` to configure a search provider."};if((this.config.provider==="brave"||this.config.provider==="tavily")&&!this.config.apiKey)return{success:!1,error:`Web search requires an API key for ${this.config.provider}. Run \`alfred setup\` to configure it.`};try{let o;switch(this.config.provider){case"brave":o=await this.searchBrave(s,r);break;case"searxng":o=await this.searchSearXNG(s,r);break;case"tavily":o=await this.searchTavily(s,r);break;case"duckduckgo":o=await this.searchDuckDuckGo(s,r);break;default:return{success:!1,error:`Unknown search provider: ${this.config.provider}`}}if(o.length===0)return{success:!0,data:{results:[]},display:`No results found for "${s}".`};let i=o.map((a,l)=>`${l+1}. **${a.title}**
305
+ When the user tells you facts about themselves or preferences, use the memory tool to save them for future reference.`;return a}buildMessages(e){let t=e.filter(s=>s.role==="user"||s.role==="assistant").map(s=>{if(s.toolCalls){let r;try{r=JSON.parse(s.toolCalls)}catch{r=[]}if(s.role==="assistant"){let i=r,a=[];s.content&&a.push({type:"text",text:s.content});for(let l of i)a.push({type:"tool_use",id:l.id,name:l.name,input:l.input});return{role:"assistant",content:a}}let n=r,o=[];for(let i of n)i.type==="tool_result"&&o.push(i);return o.length>0?{role:"user",content:o}:{role:"user",content:s.content||""}}return{role:s.role,content:s.content}});return this.sanitizeToolMessages(t)}sanitizeToolMessages(e){let t=new Set;for(let r of e)if(r.role==="assistant"&&Array.isArray(r.content))for(let n of r.content)n.type==="tool_use"&&t.add(n.id);let s=new Set;for(let r of e)if(r.role==="user"&&Array.isArray(r.content))for(let n of r.content)n.type==="tool_result"&&s.add(n.tool_use_id);return e.filter(r=>Array.isArray(r.content)?r.role==="assistant"?r.content.some(i=>i.type==="tool_use")?r.content.filter(i=>i.type==="tool_use").every(i=>s.has(i.id)):!0:r.role==="user"&&r.content.some(i=>i.type==="tool_result")?r.content.filter(i=>i.type==="tool_result").every(i=>t.has(i.tool_use_id)):!0:!0)}buildTools(e){return e.map(t=>({name:t.name,description:t.description,inputSchema:t.inputSchema}))}}});var Hs=f(()=>{"use strict";xe();Cs();gt();Us();Ps();Fs();Bs();nn();on()});var bt,Xs=f(()=>{"use strict";bt=class{static{d(this,"RateLimiter")}buckets=new Map;check(e,t){let s=Date.now(),r=t.windowSeconds*1e3,n=this.buckets.get(e);if(!n)return{allowed:!0,remaining:t.maxInvocations,resetsAt:s+r};if(s>n.windowStart+r)return{allowed:!0,remaining:t.maxInvocations,resetsAt:s+r};let o=Math.max(0,t.maxInvocations-n.count);return{allowed:n.count<t.maxInvocations,remaining:o,resetsAt:n.windowStart+r}}increment(e,t){let s=Date.now(),r=t.windowSeconds*1e3,n=this.buckets.get(e);!n||s>n.windowStart+r?this.buckets.set(e,{count:1,windowStart:s}):n.count+=1}reset(){this.buckets.clear()}}});var _t,an=f(()=>{"use strict";Xs();_t=class{static{d(this,"RuleEngine")}rules=[];rateLimiter=new bt;loadRules(e){this.rules=[...e].sort((t,s)=>t.priority-s.priority)}getRules(){return this.rules}evaluate(e){for(let t of this.rules)if(this.ruleMatches(t,e))return t.rateLimit&&t.effect==="allow"&&!this.checkRateLimit(t,e)?{allowed:!1,matchedRule:t,reason:`Rate limit exceeded for rule: ${t.id}`,timestamp:new Date}:{allowed:t.effect==="allow",matchedRule:t,reason:`Matched rule: ${t.id}`,timestamp:new Date};return{allowed:!1,matchedRule:void 0,reason:"No matching rule found \u2014 default deny",timestamp:new Date}}checkRateLimit(e,t){if(!e.rateLimit)return!0;let s=this.getScopeKey(e.scope,t),r=`${e.id}:${s}`;return this.rateLimiter.check(r,e.rateLimit).allowed?(this.rateLimiter.increment(r,e.rateLimit),!0):!1}resetRateLimits(){this.rateLimiter.reset()}getScopeKey(e,t){switch(e){case"global":return"global";case"user":return t.userId;case"conversation":return t.chatId??"unknown";case"platform":return t.platform}}ruleMatches(e,t){return!(!e.actions.includes("*")&&!e.actions.includes(t.action)||!e.riskLevels.includes(t.riskLevel)||e.conditions&&(e.conditions.users&&e.conditions.users.length>0&&!e.conditions.users.includes(t.userId)||e.conditions.platforms&&e.conditions.platforms.length>0&&!e.conditions.platforms.includes(t.platform)||e.conditions.chatType&&t.chatType&&e.conditions.chatType!==t.chatType||e.conditions.timeWindow&&!this.matchesTimeWindow(e.conditions.timeWindow)))}matchesTimeWindow(e){if(!e)return!0;let t=new Date;if(e.daysOfWeek&&e.daysOfWeek.length>0&&!e.daysOfWeek.includes(t.getDay()))return!1;let s=t.getHours();if(e.startHour!==void 0&&e.endHour!==void 0){if(e.startHour<=e.endHour){if(s<e.startHour||s>=e.endHour)return!1}else if(s>=e.endHour&&s<e.startHour)return!1}else if(e.startHour!==void 0){if(s<e.startHour)return!1}else if(e.endHour!==void 0&&s>=e.endHour)return!1;return!0}}});var cn,ln,dn,pe,un=f(()=>{"use strict";cn=["allow","deny"],ln=["global","user","conversation","platform"],dn=["read","write","destructive","admin"],pe=class{static{d(this,"RuleLoader")}loadFromObject(e){if(!e||!Array.isArray(e.rules))throw new Error('Invalid data: expected an object with a "rules" array');return e.rules.map((t,s)=>this.validateRule(t,s))}validateRule(e,t){if(typeof e!="object"||e===null)throw new Error(`Rule at index ${t} is not an object`);let s=e;if(typeof s.id!="string"||s.id.length===0)throw new Error(`Rule at index ${t} is missing a valid "id" string`);if(typeof s.effect!="string"||!cn.includes(s.effect))throw new Error(`Rule "${s.id}" has invalid "effect": expected one of ${cn.join(", ")}`);if(typeof s.priority!="number"||!Number.isFinite(s.priority))throw new Error(`Rule "${s.id}" is missing a valid "priority" number`);if(typeof s.scope!="string"||!ln.includes(s.scope))throw new Error(`Rule "${s.id}" has invalid "scope": expected one of ${ln.join(", ")}`);if(!Array.isArray(s.actions)||s.actions.length===0)throw new Error(`Rule "${s.id}" is missing a valid "actions" array`);for(let n of s.actions)if(typeof n!="string")throw new Error(`Rule "${s.id}" has a non-string entry in "actions"`);if(!Array.isArray(s.riskLevels)||s.riskLevels.length===0)throw new Error(`Rule "${s.id}" is missing a valid "riskLevels" array`);for(let n of s.riskLevels)if(!dn.includes(n))throw new Error(`Rule "${s.id}" has invalid risk level "${n}": expected one of ${dn.join(", ")}`);let r={id:s.id,effect:s.effect,priority:s.priority,scope:s.scope,actions:s.actions,riskLevels:s.riskLevels};if(s.conditions!==void 0){if(typeof s.conditions!="object"||s.conditions===null)throw new Error(`Rule "${s.id}" has invalid "conditions": expected an object`);r.conditions=s.conditions}if(s.rateLimit!==void 0){if(typeof s.rateLimit!="object"||s.rateLimit===null)throw new Error(`Rule "${s.id}" has invalid "rateLimit": expected an object`);let n=s.rateLimit;if(typeof n.maxInvocations!="number"||typeof n.windowSeconds!="number")throw new Error(`Rule "${s.id}" has invalid "rateLimit": expected maxInvocations and windowSeconds numbers`);r.rateLimit=s.rateLimit}return r}}});import ki from"node:crypto";var St,mn=f(()=>{"use strict";St=class{static{d(this,"SecurityManager")}ruleEngine;auditRepository;logger;constructor(e,t,s){this.ruleEngine=e,this.auditRepository=t,this.logger=s}evaluate(e){let t=this.ruleEngine.evaluate(e),s={id:ki.randomUUID(),timestamp:t.timestamp,userId:e.userId,action:e.action,riskLevel:e.riskLevel,ruleId:t.matchedRule?.id,effect:t.allowed?"allow":"deny",platform:e.platform,chatId:e.chatId,context:{chatType:e.chatType,reason:t.reason}};try{this.auditRepository.log(s)}catch(r){this.logger.error({err:r,auditEntry:s},"Failed to write audit log entry")}return this.logger.debug({userId:e.userId,action:e.action,allowed:t.allowed,ruleId:t.matchedRule?.id,reason:t.reason},"Security evaluation completed"),t}}});var ts=f(()=>{"use strict";an();Xs();un();mn()});var b,N=f(()=>{"use strict";b=class{static{d(this,"Skill")}}});var Ie,pn=f(()=>{"use strict";Ie=class{static{d(this,"SkillRegistry")}skills=new Map;register(e){let{name:t}=e.metadata;if(this.skills.has(t))throw new Error(`Skill "${t}" is already registered`);this.skills.set(t,e)}get(e){return this.skills.get(e)}getAll(){return[...this.skills.values()]}has(e){return this.skills.has(e)}toToolDefinitions(){return this.getAll().map(e=>({name:e.metadata.name,description:e.metadata.description,inputSchema:e.metadata.inputSchema}))}}});var $e,hn=f(()=>{"use strict";$e=class{static{d(this,"SkillSandbox")}logger;constructor(e){this.logger=e}async execute(e,t,s,r,n){r=r??e.metadata.timeoutMs??3e4;let{name:o}=e.metadata;return this.logger.info({skill:o,input:t},"Skill execution started"),n?this.executeWithTracker(e,t,s,o,r,n):this.executeWithHardTimeout(e,t,s,o,r)}async executeWithTracker(e,t,s,r,n,o){return new Promise(i=>{let a=!1,l,u,h,m=d(()=>{l&&clearInterval(l),u&&clearTimeout(u),h&&clearTimeout(h)},"cleanup"),p=d(E=>{a||(a=!0,m(),i(E))},"finish");e.execute(t,s).then(E=>{this.logger.info({skill:r,success:E.success},"Skill execution completed"),p(E)},E=>{let w=E instanceof Error?E.message:String(E);this.logger.error({skill:r,error:w},"Skill execution failed"),p({success:!1,error:w})}),h=setTimeout(()=>{if(a)return;let E=o.getIdleMs();if(E>=12e4){let T=o.getSnapshot();this.logger.warn({skill:r,idleMs:E,state:T.state,iteration:T.iteration},"Agent inactive after initial timeout \u2014 aborting"),p({success:!1,error:`Skill "${r}" timed out \u2014 inactive for ${Math.round(E/1e3)}s (last state: ${T.state})`});return}let w=o.getSnapshot();this.logger.info({skill:r,idleMs:E,state:w.state,iteration:w.iteration,totalMs:w.totalElapsedMs},"Initial timeout reached but agent is active \u2014 extending"),l=setInterval(()=>{if(a){m();return}let T=o.getIdleMs(),x=o.getSnapshot();T>=12e4?(this.logger.warn({skill:r,idleMs:T,state:x.state,iteration:x.iteration,totalMs:x.totalElapsedMs},"Agent went inactive \u2014 aborting"),p({success:!1,error:`Skill "${r}" killed \u2014 inactive for ${Math.round(T/1e3)}s (last state: ${x.state})`})):this.logger.debug({skill:r,idleMs:T,state:x.state,iteration:x.iteration},"Agent still active, continuing...")},1e4)},n),u=setTimeout(()=>{if(a)return;let E=o.getSnapshot();this.logger.error({skill:r,totalMs:E.totalElapsedMs,state:E.state,iteration:E.iteration},"Absolute time limit reached \u2014 force killing agent"),p({success:!1,error:`Skill "${r}" force-killed after ${Math.round(12e5/6e4)} minutes (safety limit)`})},12e5)})}async executeWithHardTimeout(e,t,s,r,n){try{let o=await Promise.race([e.execute(t,s),new Promise((i,a)=>{setTimeout(()=>a(new Error(`Skill "${r}" timed out after ${n}ms`)),n)})]);return this.logger.info({skill:r,success:o.success},"Skill execution completed"),o}catch(o){let i=o instanceof Error?o.message:String(o);return this.logger.error({skill:r,error:i},"Skill execution failed"),{success:!1,error:i}}}}});var he,zs=f(()=>{"use strict";he=class{static{d(this,"ActivityTracker")}state="starting";iteration=0;maxIterations=0;currentTool;lastPingAt;startedAt;history=[];onProgress;constructor(e){this.startedAt=Date.now(),this.lastPingAt=Date.now(),this.onProgress=e}ping(e,t){this.state=e,this.lastPingAt=Date.now(),t?.iteration!==void 0&&(this.iteration=t.iteration),t?.maxIterations!==void 0&&(this.maxIterations=t.maxIterations),this.currentTool=t?.tool,this.history.push({state:e,tool:t?.tool,iteration:this.iteration,timestamp:this.lastPingAt}),this.onProgress&&this.onProgress(this.formatStatus())}getIdleMs(){return Date.now()-this.lastPingAt}getTotalElapsedMs(){return Date.now()-this.startedAt}formatStatus(){let e=this.maxIterations>0?` (${this.iteration}/${this.maxIterations})`:"";switch(this.state){case"starting":return"Sub-agent starting...";case"llm_call":return`Sub-agent thinking...${e}`;case"tool_call":return this.currentTool?`Sub-agent using ${this.currentTool}${e}`:`Sub-agent using tool...${e}`;case"processing":return`Sub-agent processing...${e}`;case"done":return`Sub-agent done${e}`;default:return`Sub-agent working...${e}`}}getSnapshot(){return{state:this.state,iteration:this.iteration,maxIterations:this.maxIterations,lastPingAt:this.lastPingAt,idleMs:this.getIdleMs(),currentTool:this.currentTool,totalElapsedMs:this.getTotalElapsedMs(),history:[...this.history]}}}});import vi from"node:fs";import qs from"node:path";var ss,fn=f(()=>{"use strict";N();ss=class{static{d(this,"PluginLoader")}async loadFromDirectory(e){let t=qs.resolve(e),s;try{s=await vi.promises.readdir(t)}catch(o){let i=o instanceof Error?o.message:String(o);return console.warn(`PluginLoader: failed to read directory "${t}": ${i}`),[]}let r=s.filter(o=>o.endsWith(".js")),n=[];for(let o of r){let i=qs.join(t,o);try{let a=await this.loadFromFile(i);n.push(a)}catch(a){let l=a instanceof Error?a.message:String(a);console.warn(`PluginLoader: skipping "${i}": ${l}`)}}return n}async loadFromFile(e){let t=qs.resolve(e),n=(await import(`file:///${t.replace(/\\/g,"/")}`)).default;if(typeof n!="function")throw new Error(`Module "${t}" does not have a default export that is a class`);let o=new n;if(!(o instanceof b))throw new Error(`Default export of "${t}" does not extend Skill`);return this.validateMetadata(o,t),o}validateMetadata(e,t){let{metadata:s}=e;if(!s)throw new Error(`Plugin "${t}" is missing metadata`);if(!s.name||typeof s.name!="string")throw new Error(`Plugin "${t}" has invalid or missing metadata.name`);if(!s.description||typeof s.description!="string")throw new Error(`Plugin "${t}" has invalid or missing metadata.description`);if(!["read","write","destructive","admin"].includes(s.riskLevel))throw new Error(`Plugin "${t}" has invalid metadata.riskLevel: "${String(s.riskLevel)}"`);if(!s.version||typeof s.version!="string")throw new Error(`Plugin "${t}" has invalid or missing metadata.version`)}}});var xi,Ii,Re,gn=f(()=>{"use strict";N();xi=/^[\d+\-*/().,%\s]|Math\.(sin|cos|tan|sqrt|pow|abs|floor|ceil|round|log|log2|log10|PI|E)/,Ii=/^[0-9+\-*/().,\s%]*(Math\.(sin|cos|tan|sqrt|pow|abs|floor|ceil|round|log|log2|log10|PI|E)[(0-9+\-*/().,\s%]*)*$/,Re=class extends b{static{d(this,"CalculatorSkill")}metadata={name:"calculator",description:"Evaluate mathematical expressions. Use for any calculation, unit conversion, or math question the user asks.",riskLevel:"read",version:"1.0.0",inputSchema:{type:"object",properties:{expression:{type:"string",description:"The mathematical expression to evaluate"}},required:["expression"]}};async execute(e,t){let s=e.expression;if(!s||typeof s!="string")return{success:!1,error:"Invalid expression: input must be a non-empty string"};let r=s.trim();if(!xi.test(r))return{success:!1,error:`Invalid expression: "${r}" contains disallowed characters`};if(!Ii.test(r))return{success:!1,error:`Invalid expression: "${r}" contains disallowed constructs`};try{let o=new Function("Math",`"use strict"; return (${r});`)(Math);return typeof o!="number"||!isFinite(o)?{success:!1,error:`Invalid expression: "${r}" did not produce a finite number`}:{success:!0,data:o,display:`${r} = ${o}`}}catch{return{success:!1,error:`Invalid expression: "${r}"`}}}}});var Ae,yn=f(()=>{"use strict";N();Ae=class extends b{static{d(this,"SystemInfoSkill")}metadata={name:"system_info",description:'Get system information: current date/time (datetime), system stats (general), memory usage (memory), or uptime (uptime). Use "datetime" when the user asks what day/time it is.',riskLevel:"read",version:"1.0.0",inputSchema:{type:"object",properties:{category:{type:"string",enum:["general","memory","uptime","datetime"],description:"Category of system info (use datetime for current date/time)"}},required:["category"]}};async execute(e,t){let s=e.category;switch(s){case"general":return this.getGeneralInfo();case"memory":return this.getMemoryInfo();case"uptime":return this.getUptimeInfo();case"datetime":return this.getDateTimeInfo();default:return{success:!1,error:`Unknown category: "${String(s)}". Valid categories: general, memory, uptime`}}}getGeneralInfo(){let e={nodeVersion:process.version,platform:process.platform,arch:process.arch};return{success:!0,data:e,display:`Node.js ${e.nodeVersion} on ${e.platform} (${e.arch})`}}getMemoryInfo(){let e=process.memoryUsage(),t=d(r=>(r/1024/1024).toFixed(2),"toMB"),s={rss:`${t(e.rss)} MB`,heapTotal:`${t(e.heapTotal)} MB`,heapUsed:`${t(e.heapUsed)} MB`,external:`${t(e.external)} MB`};return{success:!0,data:s,display:`Memory \u2014 RSS: ${s.rss}, Heap: ${s.heapUsed} / ${s.heapTotal}, External: ${s.external}`}}getUptimeInfo(){let e=process.uptime(),t=Math.floor(e/3600),s=Math.floor(e%3600/60),r=Math.floor(e%60),n={uptimeSeconds:e,formatted:`${t}h ${s}m ${r}s`};return{success:!0,data:n,display:`Uptime: ${n.formatted}`}}getDateTimeInfo(){let e=new Date,t={iso:e.toISOString(),date:e.toLocaleDateString("de-DE",{weekday:"long",year:"numeric",month:"long",day:"numeric"}),time:e.toLocaleTimeString("de-DE"),timezone:Intl.DateTimeFormat().resolvedOptions().timeZone,timestamp:e.getTime()};return{success:!0,data:t,display:`${t.date}, ${t.time} (${t.timezone})`}}}});var Le,wn=f(()=>{"use strict";N();Le=class extends b{static{d(this,"WebSearchSkill")}config;metadata={name:"web_search",description:"Search the internet for current information, news, facts, or anything the user asks about that you don't know. Use this whenever you need up-to-date information.",riskLevel:"read",version:"1.1.0",inputSchema:{type:"object",properties:{query:{type:"string",description:"The search query"},count:{type:"number",description:"Number of results to return (default: 5, max: 10)"}},required:["query"]}};constructor(e){super(),this.config=e}async execute(e,t){let s=e.query,r=Math.min(Math.max(1,e.count||5),10);if(!s||typeof s!="string")return{success:!1,error:'Invalid input: "query" must be a non-empty string'};if(!this.config)return{success:!1,error:"Web search is not configured. Run `alfred setup` to configure a search provider."};if((this.config.provider==="brave"||this.config.provider==="tavily")&&!this.config.apiKey)return{success:!1,error:`Web search requires an API key for ${this.config.provider}. Run \`alfred setup\` to configure it.`};try{let o;switch(this.config.provider){case"brave":o=await this.searchBrave(s,r);break;case"searxng":o=await this.searchSearXNG(s,r);break;case"tavily":o=await this.searchTavily(s,r);break;case"duckduckgo":o=await this.searchDuckDuckGo(s,r);break;default:return{success:!1,error:`Unknown search provider: ${this.config.provider}`}}if(o.length===0)return{success:!0,data:{results:[]},display:`No results found for "${s}".`};let i=o.map((a,l)=>`${l+1}. **${a.title}**
306
306
  ${a.url}
307
307
  ${a.snippet}`).join(`
308
308
 
309
309
  `);return{success:!0,data:{query:s,results:o},display:`Search results for "${s}":
310
310
 
311
- ${i}`}}catch(o){return{success:!1,error:`Search failed: ${o instanceof Error?o.message:String(o)}`}}}async searchBrave(e,t){let s=new URL("https://api.search.brave.com/res/v1/web/search");s.searchParams.set("q",e),s.searchParams.set("count",String(t));let r=await fetch(s.toString(),{headers:{Accept:"application/json","Accept-Encoding":"gzip","X-Subscription-Token":this.config.apiKey}});if(!r.ok)throw new Error(`Brave Search API returned ${r.status}: ${r.statusText}`);return((await r.json()).web?.results??[]).slice(0,t).map(o=>({title:o.title,url:o.url,snippet:o.description}))}async searchSearXNG(e,t){let s=(this.config.baseUrl??"http://localhost:8080").replace(/\/+$/,""),r=new URL(`${s}/search`);r.searchParams.set("q",e),r.searchParams.set("format","json"),r.searchParams.set("pageno","1");let n=await fetch(r.toString(),{headers:{Accept:"application/json"}});if(!n.ok)throw new Error(`SearXNG returned ${n.status}: ${n.statusText}`);return((await n.json()).results??[]).slice(0,t).map(i=>({title:i.title,url:i.url,snippet:i.content}))}async searchTavily(e,t){let s=await fetch("https://api.tavily.com/search",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({api_key:this.config.apiKey,query:e,max_results:t,include_answer:!1})});if(!s.ok)throw new Error(`Tavily API returned ${s.status}: ${s.statusText}`);return((await s.json()).results??[]).slice(0,t).map(n=>({title:n.title,url:n.url,snippet:n.content}))}async searchDuckDuckGo(e,t){let s=new URL("https://html.duckduckgo.com/html/");s.searchParams.set("q",e);let r=await fetch(s.toString(),{headers:{"User-Agent":"Mozilla/5.0 (compatible; Alfred/1.0)"}});if(!r.ok)throw new Error(`DuckDuckGo returned ${r.status}: ${r.statusText}`);let n=await r.text();return this.parseDuckDuckGoHtml(n,t)}parseDuckDuckGoHtml(e,t){let s=[],r=/<a[^>]+class="result__a"[^>]+href="([^"]*)"[^>]*>([\s\S]*?)<\/a>/g,n=/<a[^>]+class="result__snippet"[^>]*>([\s\S]*?)<\/a>/g,o=[],i;for(;(i=r.exec(e))!==null;){let l=i[1],u=this.stripHtml(i[2]).trim(),p=this.extractDdgUrl(l);u&&p&&o.push({url:p,title:u})}let a=[];for(;(i=n.exec(e))!==null;)a.push(this.stripHtml(i[1]).trim());for(let l=0;l<Math.min(o.length,t);l++)s.push({title:o[l].title,url:o[l].url,snippet:a[l]??""});return s}extractDdgUrl(e){try{if(e.includes("uddg=")){let s=new URL(e,"https://duckduckgo.com").searchParams.get("uddg");if(s)return decodeURIComponent(s)}}catch{}return e.startsWith("http")?e:""}stripHtml(e){return e.replace(/<[^>]*>/g,"").replace(/&amp;/g,"&").replace(/&lt;/g,"<").replace(/&gt;/g,">").replace(/&quot;/g,'"').replace(/&#x27;/g,"'").replace(/&nbsp;/g," ").replace(/\s+/g," ")}}});var Me,En=f(()=>{"use strict";N();Me=class extends b{static{d(this,"ReminderSkill")}reminderRepo;metadata={name:"reminder",description:'Set timed reminders that notify the user later. Use when the user says "remind me", "erinnere mich", or asks to be notified about something at a specific time. Prefer triggerAt (absolute time like "14:30" or "2026-02-28 09:00") over delayMinutes \u2014 it is more precise and avoids calculation errors.',riskLevel:"write",version:"3.0.0",inputSchema:{type:"object",properties:{action:{type:"string",enum:["set","list","cancel"],description:"The reminder action to perform"},message:{type:"string",description:"The reminder message (required for set)"},triggerAt:{type:"string",description:'Absolute time for the reminder. Accepts "HH:MM" for today or "YYYY-MM-DD HH:MM" for a specific date. Preferred over delayMinutes for time-specific reminders.'},delayMinutes:{type:"number",description:"Minutes until the reminder triggers. Use triggerAt instead when the user specifies a clock time."},reminderId:{type:"string",description:"The ID of the reminder to cancel (required for cancel)"}},required:["action"]}};constructor(e){super(),this.reminderRepo=e}async execute(e,t){let s=e.action;switch(s){case"set":return this.setReminder(e,t);case"list":return this.listReminders(t);case"cancel":return this.cancelReminder(e);default:return{success:!1,error:`Unknown action: "${String(s)}". Valid actions: set, list, cancel`}}}setReminder(e,t){let s=e.message,r=e.triggerAt,n=e.delayMinutes;if(!s||typeof s!="string")return{success:!1,error:'Missing required field "message" for set action'};let o;if(r&&typeof r=="string"){let p=this.parseTriggerAt(r,t.timezone);if(!p)return{success:!1,error:`Could not parse triggerAt "${r}". Use "HH:MM" for today or "YYYY-MM-DD HH:MM" for a specific date.`};if(p.getTime()<=Date.now())return{success:!1,error:`The time "${r}" is in the past. Please specify a future time.`};o=p}else if(n!==void 0&&typeof n=="number"&&n>0)o=new Date(Date.now()+n*60*1e3);else return{success:!1,error:'Provide either "triggerAt" (e.g. "14:30") or "delayMinutes" (positive number) for set action.'};let i=this.reminderRepo.create(t.userId,t.platform,t.chatId,s,o),a=o.getTime()-Date.now(),l=Math.round(a/6e4),u=o.toLocaleTimeString("en-GB",{hour:"2-digit",minute:"2-digit",...t.timezone?{timeZone:t.timezone}:{}});return{success:!0,data:{reminderId:i.id,message:s,triggerAt:i.triggerAt},display:`Reminder set (${i.id}): "${s}" at ${u} (in ${l} min)`}}parseTriggerAt(e,t){let s=e.trim(),r=/^(\d{1,2}):(\d{2})$/.exec(s);if(r){let o=parseInt(r[1],10),i=parseInt(r[2],10);return o>23||i>59?void 0:this.buildDateInTimezone(o,i,void 0,t)}let n=/^(\d{4})-(\d{2})-(\d{2})\s+(\d{1,2}):(\d{2})$/.exec(s);if(n){let o=parseInt(n[1],10),i=parseInt(n[2],10)-1,a=parseInt(n[3],10),l=parseInt(n[4],10),u=parseInt(n[5],10);return l>23||u>59||i>11||a>31?void 0:this.buildDateInTimezone(l,u,{year:o,month:i,day:a},t)}}buildDateInTimezone(e,t,s,r){if(!r){let h=s?new Date(s.year,s.month,s.day,e,t,0,0):new Date;return s||h.setHours(e,t,0,0),h}let n=new Date,o=s?new Date(Date.UTC(s.year,s.month,s.day,e,t,0)):new Date(Date.UTC(n.getFullYear(),n.getMonth(),n.getDate(),e,t,0)),i=new Intl.DateTimeFormat("en-CA",{timeZone:r,year:"numeric",month:"2-digit",day:"2-digit",hour:"2-digit",minute:"2-digit",second:"2-digit",hour12:!1});if(!s){let h=i.formatToParts(n),E=parseInt(h.find(v=>v.type==="year").value,10),w=parseInt(h.find(v=>v.type==="month").value,10)-1,T=parseInt(h.find(v=>v.type==="day").value,10),I=new Date(Date.UTC(E,w,T,e,t,0)),_=i.formatToParts(I),k=parseInt(_.find(v=>v.type==="hour").value,10),A=parseInt(_.find(v=>v.type==="minute").value,10),x=(e-k)*60+(t-A);return I=new Date(I.getTime()+x*6e4),I}let a=o,l=i.formatToParts(a),u=parseInt(l.find(h=>h.type==="hour").value,10),p=parseInt(l.find(h=>h.type==="minute").value,10),m=(e-u)*60+(t-p);return a=new Date(a.getTime()+m*6e4),a}listReminders(e){let s=this.reminderRepo.getByUser(e.userId).map(r=>({reminderId:r.id,message:r.message,triggerAt:r.triggerAt}));return{success:!0,data:s,display:s.length===0?"No active reminders.":`Active reminders:
311
+ ${i}`}}catch(o){return{success:!1,error:`Search failed: ${o instanceof Error?o.message:String(o)}`}}}async searchBrave(e,t){let s=new URL("https://api.search.brave.com/res/v1/web/search");s.searchParams.set("q",e),s.searchParams.set("count",String(t));let r=await fetch(s.toString(),{headers:{Accept:"application/json","Accept-Encoding":"gzip","X-Subscription-Token":this.config.apiKey}});if(!r.ok)throw new Error(`Brave Search API returned ${r.status}: ${r.statusText}`);return((await r.json()).web?.results??[]).slice(0,t).map(o=>({title:o.title,url:o.url,snippet:o.description}))}async searchSearXNG(e,t){let s=(this.config.baseUrl??"http://localhost:8080").replace(/\/+$/,""),r=new URL(`${s}/search`);r.searchParams.set("q",e),r.searchParams.set("format","json"),r.searchParams.set("pageno","1");let n=await fetch(r.toString(),{headers:{Accept:"application/json"}});if(!n.ok)throw new Error(`SearXNG returned ${n.status}: ${n.statusText}`);return((await n.json()).results??[]).slice(0,t).map(i=>({title:i.title,url:i.url,snippet:i.content}))}async searchTavily(e,t){let s=await fetch("https://api.tavily.com/search",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({api_key:this.config.apiKey,query:e,max_results:t,include_answer:!1})});if(!s.ok)throw new Error(`Tavily API returned ${s.status}: ${s.statusText}`);return((await s.json()).results??[]).slice(0,t).map(n=>({title:n.title,url:n.url,snippet:n.content}))}async searchDuckDuckGo(e,t){let s=new URL("https://html.duckduckgo.com/html/");s.searchParams.set("q",e);let r=await fetch(s.toString(),{headers:{"User-Agent":"Mozilla/5.0 (compatible; Alfred/1.0)"}});if(!r.ok)throw new Error(`DuckDuckGo returned ${r.status}: ${r.statusText}`);let n=await r.text();return this.parseDuckDuckGoHtml(n,t)}parseDuckDuckGoHtml(e,t){let s=[],r=/<a[^>]+class="result__a"[^>]+href="([^"]*)"[^>]*>([\s\S]*?)<\/a>/g,n=/<a[^>]+class="result__snippet"[^>]*>([\s\S]*?)<\/a>/g,o=[],i;for(;(i=r.exec(e))!==null;){let l=i[1],u=this.stripHtml(i[2]).trim(),h=this.extractDdgUrl(l);u&&h&&o.push({url:h,title:u})}let a=[];for(;(i=n.exec(e))!==null;)a.push(this.stripHtml(i[1]).trim());for(let l=0;l<Math.min(o.length,t);l++)s.push({title:o[l].title,url:o[l].url,snippet:a[l]??""});return s}extractDdgUrl(e){try{if(e.includes("uddg=")){let s=new URL(e,"https://duckduckgo.com").searchParams.get("uddg");if(s)return decodeURIComponent(s)}}catch{}return e.startsWith("http")?e:""}stripHtml(e){return e.replace(/<[^>]*>/g,"").replace(/&amp;/g,"&").replace(/&lt;/g,"<").replace(/&gt;/g,">").replace(/&quot;/g,'"').replace(/&#x27;/g,"'").replace(/&nbsp;/g," ").replace(/\s+/g," ")}}});var Me,En=f(()=>{"use strict";N();Me=class extends b{static{d(this,"ReminderSkill")}reminderRepo;metadata={name:"reminder",description:'Set timed reminders that notify the user later. Use when the user says "remind me", "erinnere mich", or asks to be notified about something at a specific time. Prefer triggerAt (absolute time like "14:30" or "2026-02-28 09:00") over delayMinutes \u2014 it is more precise and avoids calculation errors.',riskLevel:"write",version:"3.0.0",inputSchema:{type:"object",properties:{action:{type:"string",enum:["set","list","cancel"],description:"The reminder action to perform"},message:{type:"string",description:"The reminder message (required for set)"},triggerAt:{type:"string",description:'Absolute time for the reminder. Accepts "HH:MM" for today or "YYYY-MM-DD HH:MM" for a specific date. Preferred over delayMinutes for time-specific reminders.'},delayMinutes:{type:"number",description:"Minutes until the reminder triggers. Use triggerAt instead when the user specifies a clock time."},reminderId:{type:"string",description:"The ID of the reminder to cancel (required for cancel)"}},required:["action"]}};constructor(e){super(),this.reminderRepo=e}async execute(e,t){let s=e.action;switch(s){case"set":return this.setReminder(e,t);case"list":return this.listReminders(t);case"cancel":return this.cancelReminder(e);default:return{success:!1,error:`Unknown action: "${String(s)}". Valid actions: set, list, cancel`}}}setReminder(e,t){let s=e.message,r=e.triggerAt,n=e.delayMinutes;if(!s||typeof s!="string")return{success:!1,error:'Missing required field "message" for set action'};let o;if(r&&typeof r=="string"){let h=this.parseTriggerAt(r,t.timezone);if(!h)return{success:!1,error:`Could not parse triggerAt "${r}". Use "HH:MM" for today or "YYYY-MM-DD HH:MM" for a specific date.`};if(h.getTime()<=Date.now())return{success:!1,error:`The time "${r}" is in the past. Please specify a future time.`};o=h}else if(n!==void 0&&typeof n=="number"&&n>0)o=new Date(Date.now()+n*60*1e3);else return{success:!1,error:'Provide either "triggerAt" (e.g. "14:30") or "delayMinutes" (positive number) for set action.'};let i=this.reminderRepo.create(t.userId,t.platform,t.chatId,s,o),a=o.getTime()-Date.now(),l=Math.round(a/6e4),u=o.toLocaleTimeString("en-GB",{hour:"2-digit",minute:"2-digit",...t.timezone?{timeZone:t.timezone}:{}});return{success:!0,data:{reminderId:i.id,message:s,triggerAt:i.triggerAt},display:`Reminder set (${i.id}): "${s}" at ${u} (in ${l} min)`}}parseTriggerAt(e,t){let s=e.trim(),r=/^(\d{1,2}):(\d{2})$/.exec(s);if(r){let o=parseInt(r[1],10),i=parseInt(r[2],10);return o>23||i>59?void 0:this.buildDateInTimezone(o,i,void 0,t)}let n=/^(\d{4})-(\d{2})-(\d{2})\s+(\d{1,2}):(\d{2})$/.exec(s);if(n){let o=parseInt(n[1],10),i=parseInt(n[2],10)-1,a=parseInt(n[3],10),l=parseInt(n[4],10),u=parseInt(n[5],10);return l>23||u>59||i>11||a>31?void 0:this.buildDateInTimezone(l,u,{year:o,month:i,day:a},t)}}buildDateInTimezone(e,t,s,r){if(!r){let p=s?new Date(s.year,s.month,s.day,e,t,0,0):new Date;return s||p.setHours(e,t,0,0),p}let n=new Date,o=s?new Date(Date.UTC(s.year,s.month,s.day,e,t,0)):new Date(Date.UTC(n.getFullYear(),n.getMonth(),n.getDate(),e,t,0)),i=new Intl.DateTimeFormat("en-CA",{timeZone:r,year:"numeric",month:"2-digit",day:"2-digit",hour:"2-digit",minute:"2-digit",second:"2-digit",hour12:!1});if(!s){let p=i.formatToParts(n),E=parseInt(p.find(v=>v.type==="year").value,10),w=parseInt(p.find(v=>v.type==="month").value,10)-1,T=parseInt(p.find(v=>v.type==="day").value,10),x=new Date(Date.UTC(E,w,T,e,t,0)),S=i.formatToParts(x),k=parseInt(S.find(v=>v.type==="hour").value,10),A=parseInt(S.find(v=>v.type==="minute").value,10),I=(e-k)*60+(t-A);return x=new Date(x.getTime()+I*6e4),x}let a=o,l=i.formatToParts(a),u=parseInt(l.find(p=>p.type==="hour").value,10),h=parseInt(l.find(p=>p.type==="minute").value,10),m=(e-u)*60+(t-h);return a=new Date(a.getTime()+m*6e4),a}listReminders(e){let s=this.reminderRepo.getByUser(e.userId).map(r=>({reminderId:r.id,message:r.message,triggerAt:r.triggerAt}));return{success:!0,data:s,display:s.length===0?"No active reminders.":`Active reminders:
312
312
  ${s.map(r=>`- ${r.reminderId}: "${r.message}" (triggers at ${r.triggerAt})`).join(`
313
313
  `)}`}}cancelReminder(e){let t=e.reminderId;return!t||typeof t!="string"?{success:!1,error:'Missing required field "reminderId" for cancel action'}:this.reminderRepo.cancel(t)?{success:!0,data:{reminderId:t},display:`Reminder "${t}" cancelled.`}:{success:!1,error:`Reminder "${t}" not found`}}}});var Ne,Tn=f(()=>{"use strict";N();Ne=class extends b{static{d(this,"NoteSkill")}noteRepo;metadata={name:"note",description:"Save, list, search, or delete persistent notes (stored in SQLite). Use when the user wants to write down or retrieve text notes, lists, or ideas.",riskLevel:"write",version:"2.0.0",inputSchema:{type:"object",properties:{action:{type:"string",enum:["save","list","search","delete"],description:"The note action to perform"},title:{type:"string",description:"The note title (required for save)"},content:{type:"string",description:"The note content (required for save)"},noteId:{type:"string",description:"The ID of the note to delete (required for delete)"},query:{type:"string",description:"Search query to filter notes (required for search)"}},required:["action"]}};constructor(e){super(),this.noteRepo=e}async execute(e,t){let s=e.action;switch(s){case"save":return this.saveNote(e,t);case"list":return this.listNotes(t);case"search":return this.searchNotes(e,t);case"delete":return this.deleteNote(e);default:return{success:!1,error:`Unknown action: "${String(s)}". Valid actions: save, list, search, delete`}}}saveNote(e,t){let s=e.title,r=e.content;if(!s||typeof s!="string")return{success:!1,error:'Missing required field "title" for save action'};if(!r||typeof r!="string")return{success:!1,error:'Missing required field "content" for save action'};let n=this.noteRepo.save(t.userId,s,r);return{success:!0,data:{noteId:n.id,title:n.title},display:`Note saved: "${s}"`}}listNotes(e){let t=this.noteRepo.list(e.userId);if(t.length===0)return{success:!0,data:[],display:"No notes found."};let s=t.map(r=>`- **${r.title}** (${r.id.slice(0,8)}\u2026)
314
314
  ${r.content.slice(0,100)}${r.content.length>100?"\u2026":""}`).join(`
@@ -317,10 +317,10 @@ ${s}`}}searchNotes(e,t){let s=e.query;if(!s||typeof s!="string")return{success:!
317
317
  ${o.content.slice(0,100)}${o.content.length>100?"\u2026":""}`).join(`
318
318
  `);return{success:!0,data:r,display:`Found ${r.length} note(s):
319
319
  ${n}`}}deleteNote(e){let t=e.noteId;return!t||typeof t!="string"?{success:!1,error:'Missing required field "noteId" for delete action'}:this.noteRepo.delete(t)?{success:!0,data:{noteId:t},display:"Note deleted."}:{success:!1,error:`Note "${t}" not found`}}}});var $i,De,bn=f(()=>{"use strict";N();$i={0:"Clear sky",1:"Mainly clear",2:"Partly cloudy",3:"Overcast",45:"Foggy",48:"Depositing rime fog",51:"Light drizzle",53:"Moderate drizzle",55:"Dense drizzle",61:"Slight rain",63:"Moderate rain",65:"Heavy rain",71:"Slight snow",73:"Moderate snow",75:"Heavy snow",77:"Snow grains",80:"Slight rain showers",81:"Moderate rain showers",82:"Violent rain showers",85:"Slight snow showers",86:"Heavy snow showers",95:"Thunderstorm",96:"Thunderstorm with slight hail",99:"Thunderstorm with heavy hail"},De=class extends b{static{d(this,"WeatherSkill")}metadata={name:"weather",description:"Get current weather for any location. Uses Open-Meteo (free, no API key). Use when the user asks about weather, temperature, or conditions somewhere.",riskLevel:"read",version:"2.0.0",inputSchema:{type:"object",properties:{location:{type:"string",description:'City or place name (e.g. "Vienna", "New York", "Tokyo")'}},required:["location"]}};async execute(e,t){let s=e.location;if(!s||typeof s!="string")return{success:!1,error:'Missing required field "location"'};try{let r=await this.geocode(s);if(!r)return{success:!1,error:`Location "${s}" not found`};let n=await this.fetchWeather(r.latitude,r.longitude),o=$i[n.weathercode]??`Code ${n.weathercode}`,i=r.admin1?`${r.name}, ${r.admin1}, ${r.country}`:`${r.name}, ${r.country}`,a={location:i,temperature:n.temperature,unit:"\xB0C",condition:o,windSpeed:n.windspeed,windDirection:n.winddirection,isDay:n.is_day===1},l=`${i}: ${n.temperature}\xB0C, ${o}
320
- Wind: ${n.windspeed} km/h`;return{success:!0,data:a,display:l}}catch(r){return{success:!1,error:`Weather fetch failed: ${r instanceof Error?r.message:String(r)}`}}}async geocode(e){let t=`https://geocoding-api.open-meteo.com/v1/search?name=${encodeURIComponent(e)}&count=1&language=en&format=json`,s=await fetch(t);if(!s.ok)throw new Error(`Geocoding API returned ${s.status}`);return(await s.json()).results?.[0]}async fetchWeather(e,t){let s=`https://api.open-meteo.com/v1/forecast?latitude=${e}&longitude=${t}&current_weather=true&timezone=auto`,r=await fetch(s);if(!r.ok)throw new Error(`Weather API returned ${r.status}`);return(await r.json()).current_weather}}});import{exec as Ri}from"node:child_process";function _n(c){return c.length>Sn?c.slice(0,Sn)+`
321
- [output truncated]`:c}var Ai,Sn,Oe,kn=f(()=>{"use strict";N();Ai=3e4,Sn=1e4;d(_n,"truncate");Oe=class extends b{static{d(this,"ShellSkill")}metadata={name:"shell",description:"Execute shell commands on the host system. Use this for ANY task involving files, folders, system operations, or running programs: ls, cat, find, file, du, mkdir, cp, mv, grep, etc. When the user asks about their documents, files, or anything on disk \u2014 use this tool.",riskLevel:"admin",version:"1.0.0",inputSchema:{type:"object",properties:{command:{type:"string",description:"The shell command to execute"},timeout:{type:"number",description:"Timeout in milliseconds (default: 30000)"},cwd:{type:"string",description:"Working directory for the command"}},required:["command"]}};async execute(e,t){let s=e.command;if(!s||typeof s!="string")return{success:!1,error:'Missing required field "command"'};let r=[/\brm\s+-rf\s+\/(?:\s|$)/,/:(){ :|:& };:/,/>\s*\/dev\/sd[a-z]/,/\bmkfs\b/,/\bdd\s+.*of=\/dev/];for(let i of r)if(i.test(s))return{success:!1,error:"Command blocked: potentially destructive system operation"};let n=typeof e.timeout=="number"&&e.timeout>0?e.timeout:Ai,o=typeof e.cwd=="string"&&e.cwd.length>0?e.cwd:void 0;try{let{stdout:i,stderr:a,exitCode:l}=await this.run(s,n,o),u=[];return i&&u.push(`stdout:
322
- ${_n(i)}`),a&&u.push(`stderr:
323
- ${_n(a)}`),u.length===0&&u.push("(no output)"),u.push(`exit code: ${l}`),{success:l===0,data:{stdout:i,stderr:a,exitCode:l},display:u.join(`
320
+ Wind: ${n.windspeed} km/h`;return{success:!0,data:a,display:l}}catch(r){return{success:!1,error:`Weather fetch failed: ${r instanceof Error?r.message:String(r)}`}}}async geocode(e){let t=`https://geocoding-api.open-meteo.com/v1/search?name=${encodeURIComponent(e)}&count=1&language=en&format=json`,s=await fetch(t);if(!s.ok)throw new Error(`Geocoding API returned ${s.status}`);return(await s.json()).results?.[0]}async fetchWeather(e,t){let s=`https://api.open-meteo.com/v1/forecast?latitude=${e}&longitude=${t}&current_weather=true&timezone=auto`,r=await fetch(s);if(!r.ok)throw new Error(`Weather API returned ${r.status}`);return(await r.json()).current_weather}}});import{exec as Ri}from"node:child_process";function Sn(c){return c.length>_n?c.slice(0,_n)+`
321
+ [output truncated]`:c}var Ai,_n,Oe,kn=f(()=>{"use strict";N();Ai=3e4,_n=1e4;d(Sn,"truncate");Oe=class extends b{static{d(this,"ShellSkill")}metadata={name:"shell",description:"Execute shell commands on the host system. Use this for ANY task involving files, folders, system operations, or running programs: ls, cat, find, file, du, mkdir, cp, mv, grep, etc. When the user asks about their documents, files, or anything on disk \u2014 use this tool.",riskLevel:"admin",version:"1.0.0",inputSchema:{type:"object",properties:{command:{type:"string",description:"The shell command to execute"},timeout:{type:"number",description:"Timeout in milliseconds (default: 30000)"},cwd:{type:"string",description:"Working directory for the command"}},required:["command"]}};async execute(e,t){let s=e.command;if(!s||typeof s!="string")return{success:!1,error:'Missing required field "command"'};let r=[/\brm\s+-rf\s+\/(?:\s|$)/,/:(){ :|:& };:/,/>\s*\/dev\/sd[a-z]/,/\bmkfs\b/,/\bdd\s+.*of=\/dev/];for(let i of r)if(i.test(s))return{success:!1,error:"Command blocked: potentially destructive system operation"};let n=typeof e.timeout=="number"&&e.timeout>0?e.timeout:Ai,o=typeof e.cwd=="string"&&e.cwd.length>0?e.cwd:void 0;try{let{stdout:i,stderr:a,exitCode:l}=await this.run(s,n,o),u=[];return i&&u.push(`stdout:
322
+ ${Sn(i)}`),a&&u.push(`stderr:
323
+ ${Sn(a)}`),u.length===0&&u.push("(no output)"),u.push(`exit code: ${l}`),{success:l===0,data:{stdout:i,stderr:a,exitCode:l},display:u.join(`
324
324
 
325
325
  `),...l!==0&&{error:`Command exited with code ${l}`}}}catch(i){return{success:!1,error:`Shell execution failed: ${i instanceof Error?i.message:String(i)}`}}}run(e,t,s){return new Promise(r=>{Ri(e,{timeout:t,cwd:s},(n,o,i)=>{let a=n&&"code"in n&&typeof n.code=="number"?n.code:n?1:0;r({stdout:typeof o=="string"?o:"",stderr:typeof i=="string"?i:"",exitCode:a})})})}}});var Ce,vn=f(()=>{"use strict";N();Ce=class extends b{static{d(this,"MemorySkill")}memoryRepo;embeddingService;metadata={name:"memory",description:"Store and retrieve persistent memories. Use this to remember user preferences, facts, and important information across conversations.",riskLevel:"write",version:"1.0.0",inputSchema:{type:"object",properties:{action:{type:"string",enum:["save","recall","search","list","delete","semantic_search"],description:"The memory action to perform"},key:{type:"string",description:"The memory key/label"},value:{type:"string",description:"The value to remember (for save)"},category:{type:"string",description:"Optional category (for save/list)"},query:{type:"string",description:"Search query (for search)"}},required:["action"]}};constructor(e,t){super(),this.memoryRepo=e,this.embeddingService=t}async execute(e,t){let s=e.action;switch(s){case"save":return this.saveMemory(e,t);case"recall":return this.recallMemory(e,t);case"search":return this.searchMemories(e,t);case"list":return this.listMemories(e,t);case"delete":return this.deleteMemory(e,t);case"semantic_search":return this.semanticSearchMemories(e,t);default:return{success:!1,error:`Unknown action: "${String(s)}". Valid actions: save, recall, search, list, delete, semantic_search`}}}saveMemory(e,t){let s=e.key,r=e.value,n=e.category;if(!s||typeof s!="string")return{success:!1,error:'Missing required field "key" for save action'};if(!r||typeof r!="string")return{success:!1,error:'Missing required field "value" for save action'};let o=this.memoryRepo.save(t.userId,s,r,n??"general");return this.embeddingService&&this.embeddingService.embedAndStore(t.userId,`${s}: ${r}`,"memory",s).catch(()=>{}),{success:!0,data:o,display:`Remembered "${s}" = "${r}" (category: ${o.category})`}}recallMemory(e,t){let s=e.key;if(!s||typeof s!="string")return{success:!1,error:'Missing required field "key" for recall action'};let r=this.memoryRepo.recall(t.userId,s);return r?{success:!0,data:r,display:`${s} = "${r.value}" (category: ${r.category}, updated: ${r.updatedAt})`}:{success:!0,data:null,display:`No memory found for key "${s}".`}}searchMemories(e,t){let s=e.query;if(!s||typeof s!="string")return{success:!1,error:'Missing required field "query" for search action'};let r=this.memoryRepo.search(t.userId,s);return{success:!0,data:r,display:r.length===0?`No memories matching "${s}".`:`Found ${r.length} memory(ies):
326
326
  ${r.map(n=>`- ${n.key}: "${n.value}"`).join(`
@@ -328,24 +328,24 @@ ${r.map(n=>`- ${n.key}: "${n.value}"`).join(`
328
328
  ${r.map(o=>`- [${o.category}] ${o.key}: "${o.value}"`).join(`
329
329
  `)}`}}deleteMemory(e,t){let s=e.key;if(!s||typeof s!="string")return{success:!1,error:'Missing required field "key" for delete action'};let r=this.memoryRepo.delete(t.userId,s);return{success:!0,data:{key:s,deleted:r},display:r?`Memory "${s}" deleted.`:`No memory found for key "${s}".`}}async semanticSearchMemories(e,t){let s=e.query;if(!s||typeof s!="string")return{success:!1,error:'Missing required field "query" for semantic_search action'};if(!this.embeddingService)return this.searchMemories(e,t);let r=await this.embeddingService.semanticSearch(t.userId,s,10);return r.length===0?this.searchMemories(e,t):{success:!0,data:r,display:`Found ${r.length} semantically related memory(ies):
330
330
  ${r.map(n=>`- ${n.key}: "${n.value}" (score: ${n.score.toFixed(2)})`).join(`
331
- `)}`}}}});var Li,Mi,Ni,Ue,xn=f(()=>{"use strict";N();zs();Li=5,Mi=15,Ni=12e4,Ue=class extends b{static{d(this,"DelegateSkill")}llm;skillRegistry;skillSandbox;securityManager;metadata={name:"delegate",description:'Delegate a complex sub-task to an autonomous sub-agent that has full tool access. The sub-agent can use shell, web search, calculator, memory, email, and all other tools. Use when a task is independent enough to run in parallel or when it requires a focused, multi-step workflow (e.g. "research X and summarize", "find all TODO files and list them", "check the weather and draft a packing list"). Control depth with max_iterations (default 5, max 15).',riskLevel:"write",version:"3.0.0",timeoutMs:Ni,inputSchema:{type:"object",properties:{task:{type:"string",description:"The task to delegate to the sub-agent. Be specific about what you want."},context:{type:"string",description:"Additional context the sub-agent needs (optional)"},max_iterations:{type:"number",description:"Max tool iterations (1-15). Use higher values for complex multi-step tasks. Default: 5."}},required:["task"]}};onProgress;constructor(e,t,s,r){super(),this.llm=e,this.skillRegistry=t,this.skillSandbox=s,this.securityManager=r}setProgressCallback(e){this.onProgress=e}createTracker(){return new he(this.onProgress)}async execute(e,t){let s=e.task,r=e.context;if(!s||typeof s!="string")return{success:!1,error:'Missing required field "task"'};let n=e.max_iterations,o=n?Math.max(1,Math.min(Mi,Math.round(n))):Li,i=t.onProgress??this.onProgress,a=t.tracker?t.tracker:new he(i);a.ping("starting",{maxIterations:o});let l=this.buildSubAgentTools(),u="You are a sub-agent of Alfred, a personal AI assistant. Complete the assigned task using the tools available to you. Work step by step: use tools to gather information, then synthesize a clear result. Be concise and return only the final answer when done.",p=s;r&&typeof r=="string"&&(p=`${s}
331
+ `)}`}}}});var Li,Mi,Ni,Ue,xn=f(()=>{"use strict";N();zs();Li=5,Mi=15,Ni=12e4,Ue=class extends b{static{d(this,"DelegateSkill")}llm;skillRegistry;skillSandbox;securityManager;metadata={name:"delegate",description:'Delegate a complex sub-task to an autonomous sub-agent that has full tool access. The sub-agent can use shell, web search, calculator, memory, email, and all other tools. Use when a task is independent enough to run in parallel or when it requires a focused, multi-step workflow (e.g. "research X and summarize", "find all TODO files and list them", "check the weather and draft a packing list"). Control depth with max_iterations (default 5, max 15).',riskLevel:"write",version:"3.0.0",timeoutMs:Ni,inputSchema:{type:"object",properties:{task:{type:"string",description:"The task to delegate to the sub-agent. Be specific about what you want."},context:{type:"string",description:"Additional context the sub-agent needs (optional)"},max_iterations:{type:"number",description:"Max tool iterations (1-15). Use higher values for complex multi-step tasks. Default: 5."}},required:["task"]}};onProgress;constructor(e,t,s,r){super(),this.llm=e,this.skillRegistry=t,this.skillSandbox=s,this.securityManager=r}setProgressCallback(e){this.onProgress=e}createTracker(){return new he(this.onProgress)}async execute(e,t){let s=e.task,r=e.context;if(!s||typeof s!="string")return{success:!1,error:'Missing required field "task"'};let n=e.max_iterations,o=n?Math.max(1,Math.min(Mi,Math.round(n))):Li,i=t.onProgress??this.onProgress,a=t.tracker?t.tracker:new he(i);a.ping("starting",{maxIterations:o});let l=this.buildSubAgentTools(),u="You are a sub-agent of Alfred, a personal AI assistant. Complete the assigned task using the tools available to you. Work step by step: use tools to gather information, then synthesize a clear result. Be concise and return only the final answer when done.",h=s;r&&typeof r=="string"&&(h=`${s}
332
332
 
333
- Additional context: ${r}`);let m=[{role:"user",content:p}];try{let h=0,E=0,w=0;for(;;){a.ping("llm_call",{iteration:h,maxIterations:o});let T=await this.llm.complete({messages:m,system:u,tools:l.length>0?l:void 0,maxTokens:2048,tier:"strong"});if(E+=T.usage.inputTokens,w+=T.usage.outputTokens,a.ping("processing",{iteration:h,maxIterations:o}),!T.toolCalls||T.toolCalls.length===0||h>=o)return a.ping("done",{iteration:h,maxIterations:o}),{success:!0,data:{response:T.content,iterations:h,usage:{inputTokens:E,outputTokens:w}},display:T.content};h++;let I=[];T.content&&I.push({type:"text",text:T.content});for(let k of T.toolCalls)I.push({type:"tool_use",id:k.id,name:k.name,input:k.input});m.push({role:"assistant",content:I});let _=[];for(let k of T.toolCalls){a.ping("tool_call",{iteration:h,maxIterations:o,tool:k.name});let A=await this.executeSubAgentTool(k,t);_.push({type:"tool_result",tool_use_id:k.id,content:A.content,is_error:A.isError})}m.push({role:"user",content:_})}}catch(h){return{success:!1,error:`Sub-agent failed: ${h instanceof Error?h.message:String(h)}`}}}buildSubAgentTools(){return this.skillRegistry?this.skillRegistry.getAll().filter(e=>e.metadata.name!=="delegate").map(e=>({name:e.metadata.name,description:e.metadata.description,inputSchema:e.metadata.inputSchema})):[]}async executeSubAgentTool(e,t){let s=this.skillRegistry?.get(e.name);if(!s)return{content:`Error: Unknown tool "${e.name}"`,isError:!0};if(this.securityManager){let r=this.securityManager.evaluate({userId:t.userId,action:e.name,riskLevel:s.metadata.riskLevel,platform:t.platform,chatId:t.chatId,chatType:t.chatType});if(!r.allowed)return{content:`Access denied: ${r.reason}`,isError:!0}}if(this.skillSandbox){let r=await this.skillSandbox.execute(s,e.input,t);return{content:r.display??(r.success?JSON.stringify(r.data):r.error??"Unknown error"),isError:!r.success}}try{let r=await s.execute(e.input,t);return{content:r.display??(r.success?JSON.stringify(r.data):r.error??"Unknown error"),isError:!r.success}}catch(r){return{content:`Skill execution failed: ${r instanceof Error?r.message:String(r)}`,isError:!0}}}}});var Pe,In=f(()=>{"use strict";N();Pe=class extends b{static{d(this,"EmailSkill")}config;metadata={name:"email",description:"Access the user's email: check inbox, read messages, search emails, or send new emails. Use when the user asks about their emails or wants to send one.",riskLevel:"write",version:"1.0.0",inputSchema:{type:"object",properties:{action:{type:"string",enum:["inbox","read","search","send"],description:"The email action to perform"},count:{type:"number",description:"Number of emails to fetch (for inbox, default: 10)"},messageId:{type:"string",description:"Message sequence number to read (for read action)"},query:{type:"string",description:"Search query (for search action)"},to:{type:"string",description:"Recipient email address (for send action)"},subject:{type:"string",description:"Email subject (for send action)"},body:{type:"string",description:"Email body text (for send action)"}},required:["action"]}};constructor(e){super(),this.config=e}async execute(e,t){if(!this.config)return{success:!1,error:"Email is not configured. Run `alfred setup` to configure email access."};let s=e.action;try{switch(s){case"inbox":return await this.fetchInbox(e.count);case"read":return await this.readMessage(e.messageId);case"search":return await this.searchMessages(e.query,e.count);case"send":return await this.sendMessage(e.to,e.subject,e.body);default:return{success:!1,error:`Unknown action: ${s}. Use: inbox, read, search, send`}}}catch(r){return{success:!1,error:`Email error: ${r instanceof Error?r.message:String(r)}`}}}async fetchInbox(e){let t=Math.min(Math.max(1,e??10),50),{ImapFlow:s}=await import("imapflow"),r=new s({host:this.config.imap.host,port:this.config.imap.port,secure:this.config.imap.secure,auth:this.config.auth,logger:!1});try{await r.connect();let n=await r.getMailboxLock("INBOX");try{let o=[],i=r.mailbox,a=i&&typeof i=="object"?i.exists??0:0;if(a===0)return{success:!0,data:{messages:[]},display:"Inbox is empty."};let u=`${Math.max(1,a-t+1)}:*`;for await(let h of r.fetch(u,{envelope:!0,flags:!0})){let E=h.envelope?.from?.[0],w=E?E.name?`${E.name} <${E.address}>`:E.address??"unknown":"unknown";o.push({seq:h.seq,from:w,subject:h.envelope?.subject??"(no subject)",date:h.envelope?.date?.toISOString()??"",seen:h.flags?.has("\\Seen")??!1})}o.reverse();let p=o.length===0?"No messages found.":o.map((h,E)=>{let w=h.seen?"":" [UNREAD]";return`${E+1}. [#${h.seq}]${w} ${h.subject}
334
- From: ${h.from}
335
- Date: ${h.date}`}).join(`
333
+ Additional context: ${r}`);let m=[{role:"user",content:h}];try{let p=0,E=0,w=0;for(;;){a.ping("llm_call",{iteration:p,maxIterations:o});let T=await this.llm.complete({messages:m,system:u,tools:l.length>0?l:void 0,maxTokens:2048,tier:"strong"});if(E+=T.usage.inputTokens,w+=T.usage.outputTokens,a.ping("processing",{iteration:p,maxIterations:o}),!T.toolCalls||T.toolCalls.length===0||p>=o)return a.ping("done",{iteration:p,maxIterations:o}),{success:!0,data:{response:T.content,iterations:p,usage:{inputTokens:E,outputTokens:w}},display:T.content};p++;let x=[];T.content&&x.push({type:"text",text:T.content});for(let k of T.toolCalls)x.push({type:"tool_use",id:k.id,name:k.name,input:k.input});m.push({role:"assistant",content:x});let S=[];for(let k of T.toolCalls){a.ping("tool_call",{iteration:p,maxIterations:o,tool:k.name});let A=await this.executeSubAgentTool(k,t);S.push({type:"tool_result",tool_use_id:k.id,content:A.content,is_error:A.isError})}m.push({role:"user",content:S})}}catch(p){return{success:!1,error:`Sub-agent failed: ${p instanceof Error?p.message:String(p)}`}}}buildSubAgentTools(){return this.skillRegistry?this.skillRegistry.getAll().filter(e=>e.metadata.name!=="delegate").map(e=>({name:e.metadata.name,description:e.metadata.description,inputSchema:e.metadata.inputSchema})):[]}async executeSubAgentTool(e,t){let s=this.skillRegistry?.get(e.name);if(!s)return{content:`Error: Unknown tool "${e.name}"`,isError:!0};if(this.securityManager){let r=this.securityManager.evaluate({userId:t.userId,action:e.name,riskLevel:s.metadata.riskLevel,platform:t.platform,chatId:t.chatId,chatType:t.chatType});if(!r.allowed)return{content:`Access denied: ${r.reason}`,isError:!0}}if(this.skillSandbox){let r=await this.skillSandbox.execute(s,e.input,t);return{content:r.display??(r.success?JSON.stringify(r.data):r.error??"Unknown error"),isError:!r.success}}try{let r=await s.execute(e.input,t);return{content:r.display??(r.success?JSON.stringify(r.data):r.error??"Unknown error"),isError:!r.success}}catch(r){return{content:`Skill execution failed: ${r instanceof Error?r.message:String(r)}`,isError:!0}}}}});var Pe,In=f(()=>{"use strict";N();Pe=class extends b{static{d(this,"EmailSkill")}config;metadata={name:"email",description:"Access the user's email: check inbox, read messages, search emails, or send new emails. Use when the user asks about their emails or wants to send one.",riskLevel:"write",version:"1.0.0",inputSchema:{type:"object",properties:{action:{type:"string",enum:["inbox","read","search","send"],description:"The email action to perform"},count:{type:"number",description:"Number of emails to fetch (for inbox, default: 10)"},messageId:{type:"string",description:"Message sequence number to read (for read action)"},query:{type:"string",description:"Search query (for search action)"},to:{type:"string",description:"Recipient email address (for send action)"},subject:{type:"string",description:"Email subject (for send action)"},body:{type:"string",description:"Email body text (for send action)"}},required:["action"]}};constructor(e){super(),this.config=e}async execute(e,t){if(!this.config)return{success:!1,error:"Email is not configured. Run `alfred setup` to configure email access."};let s=e.action;try{switch(s){case"inbox":return await this.fetchInbox(e.count);case"read":return await this.readMessage(e.messageId);case"search":return await this.searchMessages(e.query,e.count);case"send":return await this.sendMessage(e.to,e.subject,e.body);default:return{success:!1,error:`Unknown action: ${s}. Use: inbox, read, search, send`}}}catch(r){return{success:!1,error:`Email error: ${r instanceof Error?r.message:String(r)}`}}}async fetchInbox(e){let t=Math.min(Math.max(1,e??10),50),{ImapFlow:s}=await import("imapflow"),r=new s({host:this.config.imap.host,port:this.config.imap.port,secure:this.config.imap.secure,auth:this.config.auth,logger:!1});try{await r.connect();let n=await r.getMailboxLock("INBOX");try{let o=[],i=r.mailbox,a=i&&typeof i=="object"?i.exists??0:0;if(a===0)return{success:!0,data:{messages:[]},display:"Inbox is empty."};let u=`${Math.max(1,a-t+1)}:*`;for await(let p of r.fetch(u,{envelope:!0,flags:!0})){let E=p.envelope?.from?.[0],w=E?E.name?`${E.name} <${E.address}>`:E.address??"unknown":"unknown";o.push({seq:p.seq,from:w,subject:p.envelope?.subject??"(no subject)",date:p.envelope?.date?.toISOString()??"",seen:p.flags?.has("\\Seen")??!1})}o.reverse();let h=o.length===0?"No messages found.":o.map((p,E)=>{let w=p.seen?"":" [UNREAD]";return`${E+1}. [#${p.seq}]${w} ${p.subject}
334
+ From: ${p.from}
335
+ Date: ${p.date}`}).join(`
336
336
 
337
- `),m=o.filter(h=>!h.seen).length;return{success:!0,data:{messages:o,totalMessages:a,unreadCount:m},display:`Inbox (${a} total, ${m} unread):
337
+ `),m=o.filter(p=>!p.seen).length;return{success:!0,data:{messages:o,totalMessages:a,unreadCount:m},display:`Inbox (${a} total, ${m} unread):
338
338
 
339
- ${p}`}}finally{n.release()}}finally{await r.logout()}}async readMessage(e){if(!e)return{success:!1,error:"messageId is required. Use the sequence number from inbox."};let t=parseInt(e,10);if(isNaN(t)||t<1)return{success:!1,error:"messageId must be a positive number (sequence number)."};let{ImapFlow:s}=await import("imapflow"),r=new s({host:this.config.imap.host,port:this.config.imap.port,secure:this.config.imap.secure,auth:this.config.auth,logger:!1});try{await r.connect();let n=await r.getMailboxLock("INBOX");try{let o=await r.fetchOne(String(t),{envelope:!0,source:!0});if(!o)return{success:!1,error:`Message #${t} not found.`};let i=o.envelope?.from?.[0],a=i?i.name?`${i.name} <${i.address}>`:i.address??"unknown":"unknown",l=o.envelope?.to?.map(m=>m.name?`${m.name} <${m.address}>`:m.address??"").join(", ")??"",u=o.source?.toString()??"",p=this.extractTextBody(u);return{success:!0,data:{seq:t,from:a,to:l,subject:o.envelope?.subject??"(no subject)",date:o.envelope?.date?.toISOString()??"",body:p},display:[`From: ${a}`,`To: ${l}`,`Subject: ${o.envelope?.subject??"(no subject)"}`,`Date: ${o.envelope?.date?.toISOString()??""}`,"",p.slice(0,3e3)+(p.length>3e3?`
339
+ ${h}`}}finally{n.release()}}finally{await r.logout()}}async readMessage(e){if(!e)return{success:!1,error:"messageId is required. Use the sequence number from inbox."};let t=parseInt(e,10);if(isNaN(t)||t<1)return{success:!1,error:"messageId must be a positive number (sequence number)."};let{ImapFlow:s}=await import("imapflow"),r=new s({host:this.config.imap.host,port:this.config.imap.port,secure:this.config.imap.secure,auth:this.config.auth,logger:!1});try{await r.connect();let n=await r.getMailboxLock("INBOX");try{let o=await r.fetchOne(String(t),{envelope:!0,source:!0});if(!o)return{success:!1,error:`Message #${t} not found.`};let i=o.envelope?.from?.[0],a=i?i.name?`${i.name} <${i.address}>`:i.address??"unknown":"unknown",l=o.envelope?.to?.map(m=>m.name?`${m.name} <${m.address}>`:m.address??"").join(", ")??"",u=o.source?.toString()??"",h=this.extractTextBody(u);return{success:!0,data:{seq:t,from:a,to:l,subject:o.envelope?.subject??"(no subject)",date:o.envelope?.date?.toISOString()??"",body:h},display:[`From: ${a}`,`To: ${l}`,`Subject: ${o.envelope?.subject??"(no subject)"}`,`Date: ${o.envelope?.date?.toISOString()??""}`,"",h.slice(0,3e3)+(h.length>3e3?`
340
340
 
341
341
  ... (truncated)`:"")].join(`
342
- `)}}finally{n.release()}}finally{await r.logout()}}async searchMessages(e,t){if(!e)return{success:!1,error:"query is required for search."};let s=Math.min(Math.max(1,t??10),50),{ImapFlow:r}=await import("imapflow"),n=new r({host:this.config.imap.host,port:this.config.imap.port,secure:this.config.imap.secure,auth:this.config.auth,logger:!1});try{await n.connect();let o=await n.getMailboxLock("INBOX");try{let i=await n.search({or:[{subject:e},{from:e},{body:e}]}),a=Array.isArray(i)?i:[];if(a.length===0)return{success:!0,data:{results:[]},display:`No emails found for "${e}".`};let l=a.slice(-s),u=[];for await(let m of n.fetch(l,{envelope:!0})){let h=m.envelope?.from?.[0],E=h?h.name?`${h.name} <${h.address}>`:h.address??"unknown":"unknown";u.push({seq:m.seq,from:E,subject:m.envelope?.subject??"(no subject)",date:m.envelope?.date?.toISOString()??""})}u.reverse();let p=u.map((m,h)=>`${h+1}. [#${m.seq}] ${m.subject}
342
+ `)}}finally{n.release()}}finally{await r.logout()}}async searchMessages(e,t){if(!e)return{success:!1,error:"query is required for search."};let s=Math.min(Math.max(1,t??10),50),{ImapFlow:r}=await import("imapflow"),n=new r({host:this.config.imap.host,port:this.config.imap.port,secure:this.config.imap.secure,auth:this.config.auth,logger:!1});try{await n.connect();let o=await n.getMailboxLock("INBOX");try{let i=await n.search({or:[{subject:e},{from:e},{body:e}]}),a=Array.isArray(i)?i:[];if(a.length===0)return{success:!0,data:{results:[]},display:`No emails found for "${e}".`};let l=a.slice(-s),u=[];for await(let m of n.fetch(l,{envelope:!0})){let p=m.envelope?.from?.[0],E=p?p.name?`${p.name} <${p.address}>`:p.address??"unknown":"unknown";u.push({seq:m.seq,from:E,subject:m.envelope?.subject??"(no subject)",date:m.envelope?.date?.toISOString()??""})}u.reverse();let h=u.map((m,p)=>`${p+1}. [#${m.seq}] ${m.subject}
343
343
  From: ${m.from}
344
344
  Date: ${m.date}`).join(`
345
345
 
346
346
  `);return{success:!0,data:{query:e,results:u,totalMatches:l.length},display:`Search results for "${e}" (${l.length} matches):
347
347
 
348
- ${p}`}}finally{o.release()}}finally{await n.logout()}}async sendMessage(e,t,s){if(!e)return{success:!1,error:'"to" (recipient email) is required.'};if(!t)return{success:!1,error:'"subject" is required.'};if(!s)return{success:!1,error:'"body" is required.'};let o=await(await import("nodemailer")).createTransport({host:this.config.smtp.host,port:this.config.smtp.port,secure:this.config.smtp.secure,auth:this.config.auth}).sendMail({from:this.config.auth.user,to:e,subject:t,text:s});return{success:!0,data:{messageId:o.messageId,to:e,subject:t},display:`Email sent to ${e}
348
+ ${h}`}}finally{o.release()}}finally{await n.logout()}}async sendMessage(e,t,s){if(!e)return{success:!1,error:'"to" (recipient email) is required.'};if(!t)return{success:!1,error:'"subject" is required.'};if(!s)return{success:!1,error:'"body" is required.'};let o=await(await import("nodemailer")).createTransport({host:this.config.smtp.host,port:this.config.smtp.port,secure:this.config.smtp.secure,auth:this.config.auth}).sendMail({from:this.config.auth.user,to:e,subject:t,text:s});return{success:!0,data:{messageId:o.messageId,to:e,subject:t},display:`Email sent to ${e}
349
349
  Subject: ${t}
350
350
  Message ID: ${o.messageId}`}}extractTextBody(e){let t=e.split(/\r?\n\r?\n/);if(t.length<2)return e;let s=t[0].toLowerCase();if(!s.includes("multipart"))return this.decodeBody(t.slice(1).join(`
351
351
 
@@ -357,9 +357,9 @@ Message ID: ${o.messageId}`}}extractTextBody(e){let t=e.split(/\r?\n\r?\n/);if(t
357
357
  \r
358
358
  `);if(u>=0)return this.decodeBody(i.slice(u+4))}}return this.decodeBody(t.slice(1).join(`
359
359
 
360
- `).slice(0,5e3))}decodeBody(e){return e.replace(/=\r?\n/g,"").replace(/=([0-9A-Fa-f]{2})/g,(t,s)=>String.fromCharCode(parseInt(s,16))).trim()}}});var $n,Fe,Rn=f(()=>{"use strict";N();$n=1e5,Fe=class extends b{static{d(this,"HttpSkill")}metadata={name:"http",description:"Make HTTP requests to fetch web pages or call REST APIs. Use when you need to read a URL, call an API endpoint, or fetch data from the web. Supports GET, POST, PUT, PATCH, DELETE methods.",riskLevel:"write",version:"1.0.0",inputSchema:{type:"object",properties:{url:{type:"string",description:"The URL to request"},method:{type:"string",enum:["GET","POST","PUT","PATCH","DELETE"],description:"HTTP method (default: GET)"},headers:{type:"object",description:"Request headers as key-value pairs (optional)"},body:{type:"string",description:"Request body for POST/PUT/PATCH (optional)"}},required:["url"]}};async execute(e,t){let s=e.url,r=(e.method??"GET").toUpperCase(),n=e.headers,o=e.body;if(!s||typeof s!="string")return{success:!1,error:'Missing required field "url"'};let i;try{i=new URL(s)}catch{return{success:!1,error:`Invalid URL: "${s}"`}}if(i.protocol!=="http:"&&i.protocol!=="https:")return{success:!1,error:`Unsupported URL scheme "${i.protocol}". Only http: and https: are allowed.`};try{let a={method:r,headers:{"User-Agent":"Alfred/1.0",...n??{}},signal:AbortSignal.timeout(15e3)};o&&["POST","PUT","PATCH"].includes(r)&&(a.body=o,!n?.["Content-Type"]&&!n?.["content-type"]&&(a.headers["Content-Type"]="application/json"));let l=await fetch(s,a),u=l.headers.get("content-type")??"",p=await l.text(),m=p.length>$n,h=m?p.slice(0,$n)+`
360
+ `).slice(0,5e3))}decodeBody(e){return e.replace(/=\r?\n/g,"").replace(/=([0-9A-Fa-f]{2})/g,(t,s)=>String.fromCharCode(parseInt(s,16))).trim()}}});var $n,Fe,Rn=f(()=>{"use strict";N();$n=1e5,Fe=class extends b{static{d(this,"HttpSkill")}metadata={name:"http",description:"Make HTTP requests to fetch web pages or call REST APIs. Use when you need to read a URL, call an API endpoint, or fetch data from the web. Supports GET, POST, PUT, PATCH, DELETE methods.",riskLevel:"write",version:"1.0.0",inputSchema:{type:"object",properties:{url:{type:"string",description:"The URL to request"},method:{type:"string",enum:["GET","POST","PUT","PATCH","DELETE"],description:"HTTP method (default: GET)"},headers:{type:"object",description:"Request headers as key-value pairs (optional)"},body:{type:"string",description:"Request body for POST/PUT/PATCH (optional)"}},required:["url"]}};async execute(e,t){let s=e.url,r=(e.method??"GET").toUpperCase(),n=e.headers,o=e.body;if(!s||typeof s!="string")return{success:!1,error:'Missing required field "url"'};let i;try{i=new URL(s)}catch{return{success:!1,error:`Invalid URL: "${s}"`}}if(i.protocol!=="http:"&&i.protocol!=="https:")return{success:!1,error:`Unsupported URL scheme "${i.protocol}". Only http: and https: are allowed.`};try{let a={method:r,headers:{"User-Agent":"Alfred/1.0",...n??{}},signal:AbortSignal.timeout(15e3)};o&&["POST","PUT","PATCH"].includes(r)&&(a.body=o,!n?.["Content-Type"]&&!n?.["content-type"]&&(a.headers["Content-Type"]="application/json"));let l=await fetch(s,a),u=l.headers.get("content-type")??"",h=await l.text(),m=h.length>$n,p=m?h.slice(0,$n)+`
361
361
 
362
- [... truncated]`:p,E=h;u.includes("text/html")&&(E=this.stripHtml(h).slice(0,1e4));let w={status:l.status,statusText:l.statusText,contentType:u,bodyLength:p.length,truncated:m,body:h};return l.ok?{success:!0,data:w,display:`HTTP ${l.status} OK (${p.length} bytes)
362
+ [... truncated]`:h,E=p;u.includes("text/html")&&(E=this.stripHtml(p).slice(0,1e4));let w={status:l.status,statusText:l.statusText,contentType:u,bodyLength:h.length,truncated:m,body:p};return l.ok?{success:!0,data:w,display:`HTTP ${l.status} OK (${h.length} bytes)
363
363
 
364
364
  ${E.slice(0,5e3)}`}:{success:!0,data:w,display:`HTTP ${l.status} ${l.statusText}
365
365
 
@@ -385,7 +385,7 @@ Or add it to Alfred: npm install puppeteer`};switch(s){case"open":return this.op
385
385
  ${a}`}}catch(r){return{success:!1,error:`Failed to open "${s}": ${r.message}`}}}async screenshotPage(e,t){try{let s=await this.ensurePage(e),r=t.url;r&&await s.goto(r,{waitUntil:"networkidle2",timeout:3e4});let n=s.url();if(n==="about:blank")return{success:!1,error:'No page is open. Use action "open" with a URL first, or provide a URL.'};let o=new Date().toISOString().replace(/[:.]/g,"-").slice(0,19),i=t.path||Oi.join(Ci.homedir(),"Desktop",`browser-${o}.png`);return await s.screenshot({path:i,fullPage:!1}),{success:!0,data:{path:i,url:n},display:`Screenshot saved to ${i}`}}catch(s){return{success:!1,error:`Screenshot failed: ${s.message}`}}}async clickElement(e){let t=e.selector;if(!t)return{success:!1,error:'Missing "selector" for click action'};if(!this.page)return{success:!1,error:'No page is open. Use action "open" first.'};try{await this.page.waitForSelector(t,{timeout:5e3}),await this.page.click(t);try{await this.page.waitForNavigation({timeout:3e3})}catch{}let s=await this.page.title();return{success:!0,data:{selector:t,url:this.page.url(),title:s},display:`Clicked "${t}" \u2014 now on: ${s} (${this.page.url()})`}}catch(s){return{success:!1,error:`Click failed on "${t}": ${s.message}`}}}async typeText(e){let t=e.selector,s=e.text;if(!t)return{success:!1,error:'Missing "selector" for type action'};if(!s)return{success:!1,error:'Missing "text" for type action'};if(!this.page)return{success:!1,error:'No page is open. Use action "open" first.'};try{return await this.page.waitForSelector(t,{timeout:5e3}),await this.page.click(t),await this.page.type(t,s,{delay:50}),{success:!0,data:{selector:t,textLength:s.length},display:`Typed ${s.length} characters into "${t}"`}}catch(r){return{success:!1,error:`Type failed on "${t}": ${r.message}`}}}async evaluateScript(e){let t=e.script;if(!t)return{success:!1,error:'Missing "script" for evaluate action'};if(!this.page)return{success:!1,error:'No page is open. Use action "open" first.'};try{let s=await this.page.evaluate(t),r=typeof s=="string"?s:JSON.stringify(s,null,2);return{success:!0,data:{result:s},display:r?.slice(0,1e4)??"(no output)"}}catch(s){return{success:!1,error:`Evaluate failed: ${s.message}`}}}async closeBrowser(){try{return this.page=null,this.browser&&(await this.browser.close(),this.browser=null),{success:!0,display:"Browser closed."}}catch(e){return this.browser=null,this.page=null,{success:!1,error:`Close failed: ${e.message}`}}}}});var ze,Cn=f(()=>{"use strict";N();ze=class extends b{static{d(this,"ProfileSkill")}userRepo;metadata={name:"profile",description:"Manage user profile settings including timezone, language, and bio. Use this to personalize Alfred for each user.",riskLevel:"write",version:"1.0.0",inputSchema:{type:"object",properties:{action:{type:"string",enum:["get","set_timezone","set_language","set_bio","set_preference"],description:"The profile action to perform"},value:{type:"string",description:"The value to set (for set_* actions)"},preference_key:{type:"string",description:"The preference key (for set_preference)"},preference_value:{type:"string",description:"The preference value (for set_preference)"}},required:["action"]}};constructor(e){super(),this.userRepo=e}async execute(e,t){let s=e.action,r=this.userRepo.findOrCreate(t.platform,t.userId);switch(s){case"get":return this.getProfile(r.id);case"set_timezone":return this.setField(r.id,"timezone",e.value);case"set_language":return this.setField(r.id,"language",e.value);case"set_bio":return this.setField(r.id,"bio",e.value);case"set_preference":return this.setPreference(r.id,e.preference_key,e.preference_value);default:return{success:!1,error:`Unknown action: "${String(s)}"`}}}getProfile(e){let t=this.userRepo.getProfile(e);if(!t)return{success:!0,data:null,display:"No profile found. Set your timezone, language, or bio to create one."};let s=[];if(t.displayName&&s.push(`Name: ${t.displayName}`),t.timezone&&s.push(`Timezone: ${t.timezone}`),t.language&&s.push(`Language: ${t.language}`),t.bio&&s.push(`Bio: ${t.bio}`),t.preferences)for(let[r,n]of Object.entries(t.preferences))s.push(`${r}: ${String(n)}`);return{success:!0,data:t,display:s.length>0?`Profile:
386
386
  ${s.map(r=>`- ${r}`).join(`
387
387
  `)}`:"Profile is empty."}}setField(e,t,s){return!s||typeof s!="string"?{success:!1,error:`Missing required "value" for ${t}`}:(this.userRepo.updateProfile(e,{[t]:s}),{success:!0,data:{[t]:s},display:`${t} set to "${s}"`})}setPreference(e,t,s){if(!t||typeof t!="string")return{success:!1,error:'Missing required "preference_key"'};let n=this.userRepo.getProfile(e)?.preferences??{};return n[t]=s,this.userRepo.updateProfile(e,{preferences:n}),{success:!0,data:{key:t,value:s},display:`Preference "${t}" set to "${s}"`}}}});var V,xt=f(()=>{"use strict";V=class{static{d(this,"CalendarProvider")}}});var Un={};q(Un,{CalDAVProvider:()=>rs});var rs,Vs=f(()=>{"use strict";xt();rs=class extends V{static{d(this,"CalDAVProvider")}config;client;constructor(e){super(),this.config=e}async initialize(){try{let e=await import("tsdav"),{createDAVClient:t}=e;this.client=await t({serverUrl:this.config.serverUrl,credentials:{username:this.config.username,password:this.config.password},authMethod:"Basic",defaultAccountType:"caldav"})}catch(e){throw new Error(`CalDAV initialization failed: ${e instanceof Error?e.message:String(e)}`)}}async listEvents(e,t){let s=await this.client.fetchCalendars();if(!s||s.length===0)return[];let r=[];for(let n of s){let o=await this.client.fetchCalendarObjects({calendar:n,timeRange:{start:e.toISOString(),end:t.toISOString()}});for(let i of o){let a=this.parseICalEvent(i.data,i.url);a&&r.push(a)}}return r.sort((n,o)=>n.start.getTime()-o.start.getTime())}async createEvent(e){let t=await this.client.fetchCalendars();if(!t||t.length===0)throw new Error("No calendars found");let s=`alfred-${Date.now()}@alfred`,r=this.buildICalEvent(s,e);return await this.client.createCalendarObject({calendar:t[0],filename:`${s}.ics`,iCalString:r}),{id:s,title:e.title,start:e.start,end:e.end,location:e.location,description:e.description,allDay:e.allDay}}async updateEvent(e,t){let s=await this.client.fetchCalendars();for(let r of s){let n=await this.client.fetchCalendarObjects({calendar:r});for(let o of n)if(o.url?.includes(e)||o.data?.includes(e)){let i=this.parseICalEvent(o.data,o.url);if(!i)continue;let a={title:t.title??i.title,start:t.start??i.start,end:t.end??i.end,location:t.location??i.location,description:t.description??i.description,allDay:t.allDay??i.allDay},l=this.buildICalEvent(e,a);return await this.client.updateCalendarObject({calendarObject:{...o,data:l}}),{id:e,...a}}}throw new Error(`Event ${e} not found`)}async deleteEvent(e){let t=await this.client.fetchCalendars();for(let s of t){let r=await this.client.fetchCalendarObjects({calendar:s});for(let n of r)if(n.url?.includes(e)||n.data?.includes(e)){await this.client.deleteCalendarObject({calendarObject:n});return}}throw new Error(`Event ${e} not found`)}async checkAvailability(e,t){let r=(await this.listEvents(e,t)).filter(n=>!n.allDay&&n.start<t&&n.end>e);return{available:r.length===0,conflicts:r}}parseICalEvent(e,t){try{let s=e.split(`
388
- `).map(m=>m.trim()),r=d(m=>s.find(h=>h.startsWith(m+":"))?.slice(m.length+1),"get"),n=r("SUMMARY"),o=r("DTSTART")??r("DTSTART;VALUE=DATE"),i=r("DTEND")??r("DTEND;VALUE=DATE"),a=r("LOCATION"),l=r("DESCRIPTION"),u=r("UID")??t;if(!n||!o)return;let p=o.length===8;return{id:u,title:n,start:this.parseICalDate(o),end:i?this.parseICalDate(i):this.parseICalDate(o),location:a||void 0,description:l||void 0,allDay:p}}catch(s){console.error("[caldav] Failed to parse iCal event",s);return}}parseICalDate(e){if(e.length===8)return new Date(`${e.slice(0,4)}-${e.slice(4,6)}-${e.slice(6,8)}`);let t=e.replace(/[^0-9TZ]/g,"");return t.length>=15?new Date(`${t.slice(0,4)}-${t.slice(4,6)}-${t.slice(6,8)}T${t.slice(9,11)}:${t.slice(11,13)}:${t.slice(13,15)}Z`):new Date(e)}buildICalEvent(e,t){let s=d((n,o)=>o?n.toISOString().slice(0,10).replace(/-/g,""):n.toISOString().replace(/[-:]/g,"").replace(/\.\d{3}/,""),"formatDate"),r=`BEGIN:VCALENDAR\r
388
+ `).map(m=>m.trim()),r=d(m=>s.find(p=>p.startsWith(m+":"))?.slice(m.length+1),"get"),n=r("SUMMARY"),o=r("DTSTART")??r("DTSTART;VALUE=DATE"),i=r("DTEND")??r("DTEND;VALUE=DATE"),a=r("LOCATION"),l=r("DESCRIPTION"),u=r("UID")??t;if(!n||!o)return;let h=o.length===8;return{id:u,title:n,start:this.parseICalDate(o),end:i?this.parseICalDate(i):this.parseICalDate(o),location:a||void 0,description:l||void 0,allDay:h}}catch(s){console.error("[caldav] Failed to parse iCal event",s);return}}parseICalDate(e){if(e.length===8)return new Date(`${e.slice(0,4)}-${e.slice(4,6)}-${e.slice(6,8)}`);let t=e.replace(/[^0-9TZ]/g,"");return t.length>=15?new Date(`${t.slice(0,4)}-${t.slice(4,6)}-${t.slice(6,8)}T${t.slice(9,11)}:${t.slice(11,13)}:${t.slice(13,15)}Z`):new Date(e)}buildICalEvent(e,t){let s=d((n,o)=>o?n.toISOString().slice(0,10).replace(/-/g,""):n.toISOString().replace(/[-:]/g,"").replace(/\.\d{3}/,""),"formatDate"),r=`BEGIN:VCALENDAR\r
389
389
  VERSION:2.0\r
390
390
  PRODID:-//Alfred//EN\r
391
391
  BEGIN:VEVENT\r
@@ -407,17 +407,17 @@ ${r.conflicts.map(o=>this.formatEvent(o)).join(`
407
407
  `)}`;return{success:!0,data:r,display:n}}catch(r){return{success:!1,error:`Failed to check availability: ${r instanceof Error?r.message:String(r)}`}}}formatEvent(e){let t={hour:"2-digit",minute:"2-digit",...this.timezone?{timeZone:this.timezone}:{}};if(e.allDay)return`- All day: ${e.title}${e.location?` @ ${e.location}`:""}`;let s=e.start.toLocaleTimeString("en-GB",t),r=e.end.toLocaleTimeString("en-GB",t);return`- ${s}-${r}: ${e.title}${e.location?` @ ${e.location}`:""}`}}});var Wn=f(()=>{"use strict";xt();Vs();Gs();Ys();jn();Bn()});var qe,Hn=f(()=>{"use strict";N();qe=class extends b{static{d(this,"CrossPlatformSkill")}users;linkTokens;adapters;metadata={name:"cross_platform",description:"Manage cross-platform identity linking and messaging. Actions: link_start (generate a linking code on current platform), link_confirm (enter a code from another platform to link accounts), send_message (send a message to a linked platform), list_identities (show all linked platforms), unlink (remove a platform link).",riskLevel:"write",version:"1.0.0",inputSchema:{type:"object",properties:{action:{type:"string",enum:["link_start","link_confirm","send_message","list_identities","unlink"],description:"The action to perform"},code:{type:"string",description:"The 6-digit linking code (for link_confirm)"},platform:{type:"string",description:"Target platform (for send_message or unlink)"},chat_id:{type:"string",description:"Target chat ID (for send_message)"},message:{type:"string",description:"Message text to send (for send_message)"}},required:["action"]}};constructor(e,t,s){super(),this.users=e,this.linkTokens=t,this.adapters=s}async execute(e,t){let s=e.action;switch(s){case"link_start":return this.linkStart(t);case"link_confirm":return this.linkConfirm(e,t);case"send_message":return this.sendMessage(e);case"list_identities":return this.listIdentities(t);case"unlink":return this.unlink(e,t);default:return{success:!1,error:`Unknown action: ${s}`}}}failedConfirmAttempts=new Map;checkConfirmRateLimit(e){let t=Date.now(),s=this.failedConfirmAttempts.get(e);return s&&t<s.resetAt&&s.count>=5?`Too many failed attempts. Please wait ${Math.ceil((s.resetAt-t)/1e3)}s before trying again.`:null}recordFailedConfirm(e){let t=Date.now(),s=this.failedConfirmAttempts.get(e);s&&t<s.resetAt?s.count++:this.failedConfirmAttempts.set(e,{count:1,resetAt:t+5*6e4})}async linkStart(e){if(this.linkTokens.cleanup(),this.linkTokens.countRecentByUser(e.userId,10)>=5)return{success:!1,error:"Too many linking codes generated recently. Please wait a few minutes."};let s=this.linkTokens.create(e.userId,e.platform);return{success:!0,data:{code:s.code,expiresAt:s.expiresAt},display:`Your linking code is: **${s.code}**
408
408
 
409
409
  Enter this code on your other platform within 10 minutes using:
410
- "Link my account with code ${s.code}"`}}async linkConfirm(e,t){let s=e.code;if(!s)return{success:!1,error:'Missing required field "code"'};let r=this.checkConfirmRateLimit(t.userId);if(r)return{success:!1,error:r};let n=this.linkTokens.findByCode(s.trim());if(!n)return this.recordFailedConfirm(t.userId),{success:!1,error:"Invalid or expired linking code. Please generate a new one."};if(n.userId===t.userId)return{success:!1,error:"Cannot link an account to itself. Use the code on a different platform."};let o=this.users.getMasterUserId(n.userId),i=this.users.getMasterUserId(t.userId),a;if(o!==n.userId?a=o:i!==t.userId?a=i:a=n.userId,o!==n.userId&&i!==t.userId&&o!==i){let p=this.users.getLinkedUsers(i);for(let m of p)this.users.setMasterUser(m.id,a)}n.userId!==a&&this.users.setMasterUser(n.userId,a),t.userId!==a&&this.users.setMasterUser(t.userId,a),this.linkTokens.consume(n.id);let l=this.users.findById(n.userId),u=n.platform;return{success:!0,data:{masterUserId:a,linkedPlatform:u},display:`Account linked successfully! Your ${u} account (${l?.displayName??l?.username??"unknown"}) is now linked to this ${t.platform} account.
410
+ "Link my account with code ${s.code}"`}}async linkConfirm(e,t){let s=e.code;if(!s)return{success:!1,error:'Missing required field "code"'};let r=this.checkConfirmRateLimit(t.userId);if(r)return{success:!1,error:r};let n=this.linkTokens.findByCode(s.trim());if(!n)return this.recordFailedConfirm(t.userId),{success:!1,error:"Invalid or expired linking code. Please generate a new one."};if(n.userId===t.userId)return{success:!1,error:"Cannot link an account to itself. Use the code on a different platform."};let o=this.users.getMasterUserId(n.userId),i=this.users.getMasterUserId(t.userId),a;if(o!==n.userId?a=o:i!==t.userId?a=i:a=n.userId,o!==n.userId&&i!==t.userId&&o!==i){let h=this.users.getLinkedUsers(i);for(let m of h)this.users.setMasterUser(m.id,a)}n.userId!==a&&this.users.setMasterUser(n.userId,a),t.userId!==a&&this.users.setMasterUser(t.userId,a),this.linkTokens.consume(n.id);let l=this.users.findById(n.userId),u=n.platform;return{success:!0,data:{masterUserId:a,linkedPlatform:u},display:`Account linked successfully! Your ${u} account (${l?.displayName??l?.username??"unknown"}) is now linked to this ${t.platform} account.
411
411
 
412
412
  Your memories, preferences, and context are now shared across platforms.`}}async sendMessage(e){let t=e.platform,s=e.chat_id,r=e.message;if(!t)return{success:!1,error:'Missing required field "platform"'};if(!s)return{success:!1,error:'Missing required field "chat_id"'};if(!r)return{success:!1,error:'Missing required field "message"'};let n=this.adapters.get(t);if(!n)return{success:!1,error:`Platform "${t}" is not connected. Available: ${[...this.adapters.keys()].join(", ")}`};try{return{success:!0,data:{messageId:await n.sendMessage(s,r),platform:t,chatId:s},display:`Message sent to ${t} (chat ${s}).`}}catch(o){return{success:!1,error:`Failed to send message: ${o instanceof Error?o.message:String(o)}`}}}async listIdentities(e){let t=this.users.getMasterUserId(e.userId),s=this.users.getLinkedUsers(t);if(s.length<=1)return{success:!0,data:{identities:s},display:`No linked accounts found. To link another platform, use:
413
413
  "Start linking my account" on the platform you want to link from, then enter the code on the other platform.`};let r=s.map(n=>{let o=n.id===e.userId?" (current)":"",i=n.displayName??n.username??n.platformUserId;return`- **${n.platform}**: ${i}${o}`});return{success:!0,data:{identities:s.map(n=>({platform:n.platform,username:n.username,displayName:n.displayName}))},display:`Linked accounts:
414
414
  ${r.join(`
415
415
  `)}`}}async unlink(e,t){let s=e.platform;if(!s)return{success:!1,error:'Missing required field "platform"'};let r=this.users.getMasterUserId(t.userId),o=this.users.getLinkedUsers(r).find(i=>i.platform===s&&i.id!==t.userId);return o?(this.users.setMasterUser(o.id,o.id),{success:!0,data:{unlinkedPlatform:s,unlinkedUserId:o.id},display:`Unlinked ${s} account (${o.displayName??o.username??o.platformUserId}).`}):{success:!1,error:`No linked account found on platform "${s}".`}}}});var Ke,Xn=f(()=>{"use strict";N();Ke=class extends b{static{d(this,"BackgroundTaskSkill")}taskRepo;metadata={name:"background_task",description:'Schedule, list, or cancel background tasks that run independently. Use "schedule" to queue a skill to execute in the background (user will be notified when done). Use "list" to see active/recent tasks. Use "cancel" to stop a pending or running task.',riskLevel:"write",version:"1.0.0",inputSchema:{type:"object",properties:{action:{type:"string",enum:["schedule","list","cancel"],description:"The background task action to perform"},description:{type:"string",description:"Human-readable description of what the task does (for schedule)"},skill_name:{type:"string",description:"The skill to run in the background (for schedule)"},skill_input:{type:"object",description:"Input to pass to the skill (for schedule)"},task_id:{type:"string",description:"Task ID (for cancel)"}},required:["action"]}};constructor(e){super(),this.taskRepo=e}async execute(e,t){let s=e.action;switch(s){case"schedule":return this.scheduleTask(e,t);case"list":return this.listTasks(t);case"cancel":return this.cancelTask(e);default:return{success:!1,error:`Unknown action: "${String(s)}". Valid actions: schedule, list, cancel`}}}scheduleTask(e,t){let s=e.description,r=e.skill_name,n=e.skill_input;if(!s||typeof s!="string")return{success:!1,error:'Missing required field "description" for schedule action'};if(!r||typeof r!="string")return{success:!1,error:'Missing required field "skill_name" for schedule action'};let o=this.taskRepo.create(t.userId,t.platform,t.chatId,s,r,JSON.stringify(n??{}));return{success:!0,data:{taskId:o.id,description:s,skillName:r,status:o.status},display:`Background task scheduled (${o.id}): "${s}" using skill "${r}". You'll be notified when it completes.`}}listTasks(e){let t=this.taskRepo.getByUser(e.userId);if(t.length===0)return{success:!0,data:[],display:"No active or recent background tasks."};let s={pending:"\u23F3",running:"\u25B6\uFE0F",completed:"\u2705",failed:"\u274C"},r=t.map(n=>`- ${s[n.status]??"?"} ${n.id}: "${n.description}" [${n.status}] (${n.skillName})`);return{success:!0,data:t.map(n=>({taskId:n.id,description:n.description,status:n.status,skillName:n.skillName,createdAt:n.createdAt,completedAt:n.completedAt})),display:`Background tasks:
416
416
  ${r.join(`
417
- `)}`}}cancelTask(e){let t=e.task_id;return!t||typeof t!="string"?{success:!1,error:'Missing required field "task_id" for cancel action'}:this.taskRepo.cancel(t)?{success:!0,data:{taskId:t},display:`Background task "${t}" cancelled.`}:{success:!1,error:`Task "${t}" not found or already completed`}}}});var Ve,zn=f(()=>{"use strict";N();Ve=class extends b{static{d(this,"ScheduledTaskSkill")}actionRepo;metadata={name:"scheduled_task",description:'Create, list, enable, disable, or delete scheduled actions that run automatically on a recurring basis. Supports cron expressions (e.g. "0 9 * * *" for daily at 9 AM), intervals (in minutes), and one-time schedules. Each scheduled action executes a skill or sends a prompt to the LLM at the configured time.',riskLevel:"write",version:"1.0.0",inputSchema:{type:"object",properties:{action:{type:"string",enum:["create","list","enable","disable","delete"],description:"The scheduled task action to perform"},name:{type:"string",description:"Name for the scheduled action (for create)"},description:{type:"string",description:"What the scheduled action does (for create)"},schedule_type:{type:"string",enum:["cron","interval","once"],description:"Type of schedule: cron expression, interval in minutes, or one-time ISO date (for create)"},schedule_value:{type:"string",description:"Schedule value: cron expression, minutes as string, or ISO date (for create)"},skill_name:{type:"string",description:"The skill to execute on schedule (for create)"},skill_input:{type:"object",description:"Input to pass to the skill (for create)"},prompt_template:{type:"string",description:"Optional LLM prompt to run instead of a skill (for create)"},action_id:{type:"string",description:"Scheduled action ID (for enable, disable, delete)"}},required:["action"]}};constructor(e){super(),this.actionRepo=e}async execute(e,t){let s=e.action;switch(s){case"create":return this.createAction(e,t);case"list":return this.listActions(t);case"enable":return this.toggleAction(e,!0);case"disable":return this.toggleAction(e,!1);case"delete":return this.deleteAction(e);default:return{success:!1,error:`Unknown action: "${String(s)}". Valid actions: create, list, enable, disable, delete`}}}createAction(e,t){let s=e.name,r=e.description,n=e.schedule_type,o=e.schedule_value,i=e.skill_name,a=e.skill_input,l=e.prompt_template;if(!s||typeof s!="string")return{success:!1,error:'Missing required field "name" for create action'};if(!r||typeof r!="string")return{success:!1,error:'Missing required field "description" for create action'};if(!n||!["cron","interval","once"].includes(n))return{success:!1,error:'Missing or invalid "schedule_type". Must be "cron", "interval", or "once"'};if(!o||typeof o!="string")return{success:!1,error:'Missing required field "schedule_value" for create action'};if(!i||typeof i!="string")return{success:!1,error:'Missing required field "skill_name" for create action'};if(n==="interval"){let m=parseInt(o,10);if(isNaN(m)||m<=0)return{success:!1,error:"For interval schedule, value must be a positive number of minutes"}}if(n==="cron"&&o.trim().split(/\s+/).length!==5)return{success:!1,error:"Cron expression must have 5 fields: minute hour dayOfMonth month dayOfWeek"};if(n==="once"){let m=new Date(o);if(isNaN(m.getTime()))return{success:!1,error:"For once schedule, value must be a valid ISO date string"};if(m.getTime()<=Date.now())return{success:!1,error:"The scheduled time is in the past. Please specify a future time."}}let u=this.actionRepo.create({userId:t.userId,platform:t.platform,chatId:t.chatId,name:s,description:r,scheduleType:n,scheduleValue:o,skillName:i,skillInput:JSON.stringify(a??{}),promptTemplate:l}),p=n==="cron"?`cron: ${o}`:n==="interval"?`every ${o} minutes`:`once at ${o}`;return{success:!0,data:{actionId:u.id,name:s,scheduleType:n,scheduleValue:o,skillName:i},display:`Scheduled action created (${u.id}): "${s}" \u2014 ${p}, running "${i}"${u.nextRunAt?`. Next run: ${u.nextRunAt}`:""}`}}listActions(e){let t=this.actionRepo.getByUser(e.userId);if(t.length===0)return{success:!0,data:[],display:"No scheduled actions."};let s=t.map(r=>{let n=r.enabled?"\u2705":"\u23F8\uFE0F",o=r.scheduleType==="cron"?`cron: ${r.scheduleValue}`:r.scheduleType==="interval"?`every ${r.scheduleValue} min`:`once: ${r.scheduleValue}`,i=r.nextRunAt?` | next: ${r.nextRunAt}`:"";return`- ${n} ${r.id}: "${r.name}" [${o}] \u2192 ${r.skillName}${i}`});return{success:!0,data:t.map(r=>({actionId:r.id,name:r.name,scheduleType:r.scheduleType,scheduleValue:r.scheduleValue,skillName:r.skillName,enabled:r.enabled,nextRunAt:r.nextRunAt,lastRunAt:r.lastRunAt})),display:`Scheduled actions:
417
+ `)}`}}cancelTask(e){let t=e.task_id;return!t||typeof t!="string"?{success:!1,error:'Missing required field "task_id" for cancel action'}:this.taskRepo.cancel(t)?{success:!0,data:{taskId:t},display:`Background task "${t}" cancelled.`}:{success:!1,error:`Task "${t}" not found or already completed`}}}});var Ve,zn=f(()=>{"use strict";N();Ve=class extends b{static{d(this,"ScheduledTaskSkill")}actionRepo;metadata={name:"scheduled_task",description:'Create, list, enable, disable, or delete scheduled actions that run automatically on a recurring basis. Supports cron expressions (e.g. "0 9 * * *" for daily at 9 AM), intervals (in minutes), and one-time schedules. Each scheduled action executes a skill or sends a prompt to the LLM at the configured time.',riskLevel:"write",version:"1.0.0",inputSchema:{type:"object",properties:{action:{type:"string",enum:["create","list","enable","disable","delete"],description:"The scheduled task action to perform"},name:{type:"string",description:"Name for the scheduled action (for create)"},description:{type:"string",description:"What the scheduled action does (for create)"},schedule_type:{type:"string",enum:["cron","interval","once"],description:"Type of schedule: cron expression, interval in minutes, or one-time ISO date (for create)"},schedule_value:{type:"string",description:"Schedule value: cron expression, minutes as string, or ISO date (for create)"},skill_name:{type:"string",description:"The skill to execute on schedule (for create)"},skill_input:{type:"object",description:"Input to pass to the skill (for create)"},prompt_template:{type:"string",description:"Optional LLM prompt to run instead of a skill (for create)"},action_id:{type:"string",description:"Scheduled action ID (for enable, disable, delete)"}},required:["action"]}};constructor(e){super(),this.actionRepo=e}async execute(e,t){let s=e.action;switch(s){case"create":return this.createAction(e,t);case"list":return this.listActions(t);case"enable":return this.toggleAction(e,!0);case"disable":return this.toggleAction(e,!1);case"delete":return this.deleteAction(e);default:return{success:!1,error:`Unknown action: "${String(s)}". Valid actions: create, list, enable, disable, delete`}}}createAction(e,t){let s=e.name,r=e.description,n=e.schedule_type,o=e.schedule_value,i=e.skill_name,a=e.skill_input,l=e.prompt_template;if(!s||typeof s!="string")return{success:!1,error:'Missing required field "name" for create action'};if(!r||typeof r!="string")return{success:!1,error:'Missing required field "description" for create action'};if(!n||!["cron","interval","once"].includes(n))return{success:!1,error:'Missing or invalid "schedule_type". Must be "cron", "interval", or "once"'};if(!o||typeof o!="string")return{success:!1,error:'Missing required field "schedule_value" for create action'};if(!i||typeof i!="string")return{success:!1,error:'Missing required field "skill_name" for create action'};if(n==="interval"){let m=parseInt(o,10);if(isNaN(m)||m<=0)return{success:!1,error:"For interval schedule, value must be a positive number of minutes"}}if(n==="cron"&&o.trim().split(/\s+/).length!==5)return{success:!1,error:"Cron expression must have 5 fields: minute hour dayOfMonth month dayOfWeek"};if(n==="once"){let m=new Date(o);if(isNaN(m.getTime()))return{success:!1,error:"For once schedule, value must be a valid ISO date string"};if(m.getTime()<=Date.now())return{success:!1,error:"The scheduled time is in the past. Please specify a future time."}}let u=this.actionRepo.create({userId:t.userId,platform:t.platform,chatId:t.chatId,name:s,description:r,scheduleType:n,scheduleValue:o,skillName:i,skillInput:JSON.stringify(a??{}),promptTemplate:l}),h=n==="cron"?`cron: ${o}`:n==="interval"?`every ${o} minutes`:`once at ${o}`;return{success:!0,data:{actionId:u.id,name:s,scheduleType:n,scheduleValue:o,skillName:i},display:`Scheduled action created (${u.id}): "${s}" \u2014 ${h}, running "${i}"${u.nextRunAt?`. Next run: ${u.nextRunAt}`:""}`}}listActions(e){let t=this.actionRepo.getByUser(e.userId);if(t.length===0)return{success:!0,data:[],display:"No scheduled actions."};let s=t.map(r=>{let n=r.enabled?"\u2705":"\u23F8\uFE0F",o=r.scheduleType==="cron"?`cron: ${r.scheduleValue}`:r.scheduleType==="interval"?`every ${r.scheduleValue} min`:`once: ${r.scheduleValue}`,i=r.nextRunAt?` | next: ${r.nextRunAt}`:"";return`- ${n} ${r.id}: "${r.name}" [${o}] \u2192 ${r.skillName}${i}`});return{success:!0,data:t.map(r=>({actionId:r.id,name:r.name,scheduleType:r.scheduleType,scheduleValue:r.scheduleValue,skillName:r.skillName,enabled:r.enabled,nextRunAt:r.nextRunAt,lastRunAt:r.lastRunAt})),display:`Scheduled actions:
418
418
  ${s.join(`
419
419
  `)}`}}toggleAction(e,t){let s=e.action_id;return!s||typeof s!="string"?{success:!1,error:`Missing required field "action_id" for ${t?"enable":"disable"} action`}:this.actionRepo.setEnabled(s,t)?{success:!0,data:{actionId:s,enabled:t},display:`Scheduled action "${s}" ${t?"enabled":"disabled"}.`}:{success:!1,error:`Scheduled action "${s}" not found`}}deleteAction(e){let t=e.action_id;return!t||typeof t!="string"?{success:!1,error:'Missing required field "action_id" for delete action'}:this.actionRepo.delete(t)?{success:!0,data:{actionId:t},display:`Scheduled action "${t}" deleted.`}:{success:!1,error:`Scheduled action "${t}" not found`}}}});var ge,Js=f(()=>{"use strict";ge=class{static{d(this,"MCPClient")}serverName;config;logger;client;transport;connected=!1;constructor(e,t,s){this.serverName=e,this.config=t,this.logger=s}async connect(){try{let{Client:e}=await import("@modelcontextprotocol/sdk/client/index.js");if(this.client=new e({name:`alfred-${this.serverName}`,version:"1.0.0"},{capabilities:{}}),this.config.command){let{StdioClientTransport:t}=await import("@modelcontextprotocol/sdk/client/stdio.js"),s={PATH:process.env.PATH??"",HOME:process.env.HOME??process.env.USERPROFILE??"",LANG:process.env.LANG??"en_US.UTF-8",NODE_ENV:process.env.NODE_ENV??"",SYSTEMROOT:process.env.SYSTEMROOT??""};if(this.config.env)for(let[r,n]of Object.entries(this.config.env))s[r]=n.replace(/\$\{(\w+)\}/g,(o,i)=>process.env[i]??"");this.transport=new t({command:this.config.command,args:this.config.args??[],env:s})}else if(this.config.url){let{SSEClientTransport:t}=await import("@modelcontextprotocol/sdk/client/sse.js");this.transport=new t(new URL(this.config.url))}else throw new Error(`MCP server "${this.serverName}": must specify either command or url`);await this.client.connect(this.transport),this.connected=!0,this.logger.info({server:this.serverName},"MCP server connected")}catch(e){throw this.logger.error({server:this.serverName,err:e},"Failed to connect MCP server"),e}}async listTools(){if(!this.connected||!this.client)return[];try{return((await this.client.listTools()).tools??[]).map(t=>({name:t.name,description:t.description,inputSchema:t.inputSchema??{type:"object",properties:{}}}))}catch(e){return this.logger.error({server:this.serverName,err:e},"Failed to list MCP tools"),[]}}async callTool(e,t){if(!this.connected||!this.client)return{content:"MCP server not connected",isError:!0};try{let s=await this.client.callTool({name:e,arguments:t});return{content:(s.content??[]).map(n=>n.text??JSON.stringify(n)).join(`
420
- `),isError:s.isError}}catch(s){return{content:`MCP tool error: ${s instanceof Error?s.message:String(s)}`,isError:!0}}}async disconnect(){if(this.transport)try{await this.transport.close?.()}catch{}this.connected=!1,this.logger.info({server:this.serverName},"MCP server disconnected")}}});var ye,Zs=f(()=>{"use strict";N();ye=class extends b{static{d(this,"MCPSkillAdapter")}client;serverName;toolName;metadata;constructor(e,t,s,r,n){super(),this.client=e,this.serverName=t,this.toolName=s,this.metadata={name:`mcp__${t}__${s}`,description:`[MCP/${t}] ${r||s}`,riskLevel:"write",version:"1.0.0",inputSchema:n}}async execute(e,t){let s=await this.client.callTool(this.toolName,e);return{success:s.isError!==!0,data:s.content,display:s.content,error:s.isError===!0?s.content:void 0}}}});var $t,qn=f(()=>{"use strict";Js();Zs();$t=class{static{d(this,"MCPManager")}logger;clients=[];skills=[];constructor(e){this.logger=e}async initialize(e){for(let t of e.servers)try{let s=new ge(t.name,t,this.logger.child({mcp:t.name}));await s.connect(),this.clients.push(s);let r=await s.listTools();for(let n of r){let o=new ye(s,t.name,n.name,n.description??"",n.inputSchema);this.skills.push(o)}this.logger.info({server:t.name,tools:r.length},"MCP server initialized")}catch(s){this.logger.error({server:t.name,err:s},"Failed to initialize MCP server")}}getSkills(){return this.skills}async shutdown(){for(let e of this.clients)await e.disconnect();this.clients.length=0,this.skills.length=0}}});var Kn=f(()=>{"use strict";Js();Zs();qn()});import{spawn as Ui}from"node:child_process";import Ge from"node:fs";import Qs from"node:path";import Pi from"node:os";import Fi from"node:crypto";var we,er=f(()=>{"use strict";we=class{static{d(this,"CodeExecutor")}async execute(e,t,s){let r=Math.min(s?.timeout??3e4,12e4),n=Qs.join(Pi.tmpdir(),`alfred-sandbox-${Fi.randomUUID()}`);Ge.mkdirSync(n,{recursive:!0});try{let o=t==="javascript"?"js":"py",i=Qs.join(n,`script.${o}`);Ge.writeFileSync(i,e);let a=t==="javascript"?"node":process.platform==="win32"?"python":"python3",l=[i],u=Date.now();return await new Promise(p=>{let m=Ui(a,l,{cwd:n,timeout:r,env:{PATH:process.env.PATH??"",HOME:process.env.HOME??process.env.USERPROFILE??"",LANG:process.env.LANG??"en_US.UTF-8",NODE_ENV:"sandbox",PYTHONDONTWRITEBYTECODE:"1",...s?.env,TMPDIR:n,TEMP:n,TMP:n},stdio:["pipe","pipe","pipe"]}),h="",E="";m.stdout.on("data",w=>{h+=w.toString()}),m.stderr.on("data",w=>{E+=w.toString()}),m.on("close",w=>{let T=Date.now()-u,I=[];try{let _=Ge.readdirSync(n).filter(k=>!k.startsWith("script."));for(let k of _){let A=Qs.join(n,k),x=Ge.statSync(A);if(x.isFile()&&x.size<1e7){let v=Ge.readFileSync(A),F=k.endsWith(".png")?"image/png":k.endsWith(".jpg")||k.endsWith(".jpeg")?"image/jpeg":k.endsWith(".svg")?"image/svg+xml":k.endsWith(".csv")?"text/csv":k.endsWith(".json")?"application/json":"application/octet-stream";I.push({name:k,data:v,mimeType:F})}}}catch{}p({stdout:h.slice(0,5e4),stderr:E.slice(0,1e4),exitCode:w??1,files:I.length>0?I:void 0,durationMs:T})}),m.on("error",w=>{p({stdout:"",stderr:w.message,exitCode:1,durationMs:Date.now()-u})}),m.stdin.end()})}finally{try{Ge.rmSync(n,{recursive:!0,force:!0})}catch{}}}}});var Rt,Vn=f(()=>{"use strict";N();er();Rt=class extends b{static{d(this,"CodeExecutionSkill")}metadata={name:"code_sandbox",description:"Execute code in a sandboxed environment. Supports JavaScript (Node.js) and Python. Use for calculations, data processing, generating charts, or testing code snippets. Code runs in an isolated temp directory with a timeout.",riskLevel:"destructive",version:"1.0.0",timeoutMs:12e4,inputSchema:{type:"object",properties:{action:{type:"string",enum:["run","run_with_data"],description:"Action to perform"},code:{type:"string",description:"Code to execute"},language:{type:"string",enum:["javascript","python"],description:"Programming language"},data:{type:"string",description:"Input data to pass (available as DATA env var or stdin)"},timeout:{type:"number",description:"Timeout in ms (max 120000)"}},required:["action","code","language"]}};executor=new we;allowedLanguages;maxTimeout;constructor(e){super(),this.allowedLanguages=new Set(e?.allowedLanguages??["javascript","python"]),this.maxTimeout=e?.maxTimeoutMs??12e4}async execute(e,t){let s=e.action,r=e.code,n=e.language,o=e.data,i=Math.min(e.timeout??3e4,this.maxTimeout);if(!r)return{success:!1,error:'Missing required field "code"'};if(!n)return{success:!1,error:'Missing required field "language"'};if(!this.allowedLanguages.has(n))return{success:!1,error:`Language "${n}" is not allowed. Allowed: ${[...this.allowedLanguages].join(", ")}`};let a=r;s==="run_with_data"&&o&&(n==="javascript"?a=`const INPUT_DATA = ${JSON.stringify(o)};
420
+ `),isError:s.isError}}catch(s){return{content:`MCP tool error: ${s instanceof Error?s.message:String(s)}`,isError:!0}}}async disconnect(){if(this.transport)try{await this.transport.close?.()}catch{}this.connected=!1,this.logger.info({server:this.serverName},"MCP server disconnected")}}});var ye,Zs=f(()=>{"use strict";N();ye=class extends b{static{d(this,"MCPSkillAdapter")}client;serverName;toolName;metadata;constructor(e,t,s,r,n){super(),this.client=e,this.serverName=t,this.toolName=s,this.metadata={name:`mcp__${t}__${s}`,description:`[MCP/${t}] ${r||s}`,riskLevel:"write",version:"1.0.0",inputSchema:n}}async execute(e,t){let s=await this.client.callTool(this.toolName,e);return{success:s.isError!==!0,data:s.content,display:s.content,error:s.isError===!0?s.content:void 0}}}});var $t,qn=f(()=>{"use strict";Js();Zs();$t=class{static{d(this,"MCPManager")}logger;clients=[];skills=[];constructor(e){this.logger=e}async initialize(e){for(let t of e.servers)try{let s=new ge(t.name,t,this.logger.child({mcp:t.name}));await s.connect(),this.clients.push(s);let r=await s.listTools();for(let n of r){let o=new ye(s,t.name,n.name,n.description??"",n.inputSchema);this.skills.push(o)}this.logger.info({server:t.name,tools:r.length},"MCP server initialized")}catch(s){this.logger.error({server:t.name,err:s},"Failed to initialize MCP server")}}getSkills(){return this.skills}async shutdown(){for(let e of this.clients)await e.disconnect();this.clients.length=0,this.skills.length=0}}});var Kn=f(()=>{"use strict";Js();Zs();qn()});import{spawn as Ui}from"node:child_process";import Ge from"node:fs";import Qs from"node:path";import Pi from"node:os";import Fi from"node:crypto";var we,er=f(()=>{"use strict";we=class{static{d(this,"CodeExecutor")}async execute(e,t,s){let r=Math.min(s?.timeout??3e4,12e4),n=Qs.join(Pi.tmpdir(),`alfred-sandbox-${Fi.randomUUID()}`);Ge.mkdirSync(n,{recursive:!0});try{let o=t==="javascript"?"js":"py",i=Qs.join(n,`script.${o}`);Ge.writeFileSync(i,e);let a=t==="javascript"?"node":process.platform==="win32"?"python":"python3",l=[i],u=Date.now();return await new Promise(h=>{let m=Ui(a,l,{cwd:n,timeout:r,env:{PATH:process.env.PATH??"",HOME:process.env.HOME??process.env.USERPROFILE??"",LANG:process.env.LANG??"en_US.UTF-8",NODE_ENV:"sandbox",PYTHONDONTWRITEBYTECODE:"1",...s?.env,TMPDIR:n,TEMP:n,TMP:n},stdio:["pipe","pipe","pipe"]}),p="",E="";m.stdout.on("data",w=>{p+=w.toString()}),m.stderr.on("data",w=>{E+=w.toString()}),m.on("close",w=>{let T=Date.now()-u,x=[];try{let S=Ge.readdirSync(n).filter(k=>!k.startsWith("script."));for(let k of S){let A=Qs.join(n,k),I=Ge.statSync(A);if(I.isFile()&&I.size<1e7){let v=Ge.readFileSync(A),F=k.endsWith(".png")?"image/png":k.endsWith(".jpg")||k.endsWith(".jpeg")?"image/jpeg":k.endsWith(".svg")?"image/svg+xml":k.endsWith(".csv")?"text/csv":k.endsWith(".json")?"application/json":"application/octet-stream";x.push({name:k,data:v,mimeType:F})}}}catch{}h({stdout:p.slice(0,5e4),stderr:E.slice(0,1e4),exitCode:w??1,files:x.length>0?x:void 0,durationMs:T})}),m.on("error",w=>{h({stdout:"",stderr:w.message,exitCode:1,durationMs:Date.now()-u})}),m.stdin.end()})}finally{try{Ge.rmSync(n,{recursive:!0,force:!0})}catch{}}}}});var Rt,Vn=f(()=>{"use strict";N();er();Rt=class extends b{static{d(this,"CodeExecutionSkill")}metadata={name:"code_sandbox",description:"Execute code in a sandboxed environment. Supports JavaScript (Node.js) and Python. Use for calculations, data processing, generating charts, or testing code snippets. Code runs in an isolated temp directory with a timeout.",riskLevel:"destructive",version:"1.0.0",timeoutMs:12e4,inputSchema:{type:"object",properties:{action:{type:"string",enum:["run","run_with_data"],description:"Action to perform"},code:{type:"string",description:"Code to execute"},language:{type:"string",enum:["javascript","python"],description:"Programming language"},data:{type:"string",description:"Input data to pass (available as DATA env var or stdin)"},timeout:{type:"number",description:"Timeout in ms (max 120000)"}},required:["action","code","language"]}};executor=new we;allowedLanguages;maxTimeout;constructor(e){super(),this.allowedLanguages=new Set(e?.allowedLanguages??["javascript","python"]),this.maxTimeout=e?.maxTimeoutMs??12e4}async execute(e,t){let s=e.action,r=e.code,n=e.language,o=e.data,i=Math.min(e.timeout??3e4,this.maxTimeout);if(!r)return{success:!1,error:'Missing required field "code"'};if(!n)return{success:!1,error:'Missing required field "language"'};if(!this.allowedLanguages.has(n))return{success:!1,error:`Language "${n}" is not allowed. Allowed: ${[...this.allowedLanguages].join(", ")}`};let a=r;s==="run_with_data"&&o&&(n==="javascript"?a=`const INPUT_DATA = ${JSON.stringify(o)};
421
421
  ${r}`:a=`INPUT_DATA = ${JSON.stringify(o)}
422
422
  ${r}`);let l=await this.executor.execute(a,n,{timeout:i}),u=[l.stdout?`Output:
423
423
  ${l.stdout}`:"",l.stderr?`Errors:
@@ -435,17 +435,17 @@ ${i}`}}summarize(e){let t=e.document_id;if(!t||typeof t!="string")return{success
435
435
 
436
436
  ${a}`}}list(e,t){let s=e.limit||50,n=this.docRepo.listByUser(t.userId).slice(0,s);if(n.length===0)return{success:!0,data:[],display:"No documents found."};let o=n.map(i=>`- **${i.filename}** (${i.id.slice(0,8)}...) \u2014 ${i.mimeType}, ${i.chunkCount} chunks, ${i.sizeBytes} bytes`).join(`
437
437
  `);return{success:!0,data:n,display:`${n.length} document(s):
438
- ${o}`}}deleteDoc(e){let t=e.document_id;if(!t||typeof t!="string")return{success:!1,error:'Missing required field "document_id" for delete action'};let s=this.docRepo.getDocument(t);return s?(this.docRepo.deleteDocument(t),{success:!0,data:{documentId:t},display:`Document "${s.filename}" deleted.`}):{success:!1,error:`Document "${t}" not found`}}}});var is={};q(is,{ActivityTracker:()=>he,BackgroundTaskSkill:()=>Ke,BrowserSkill:()=>Xe,CalculatorSkill:()=>Re,CalendarProvider:()=>V,CalendarSkill:()=>fe,ClipboardSkill:()=>We,CodeExecutionSkill:()=>Rt,CodeExecutor:()=>we,CrossPlatformSkill:()=>qe,DelegateSkill:()=>Ue,DocumentSkill:()=>Ye,EmailSkill:()=>Pe,FileSkill:()=>je,HttpSkill:()=>Fe,MCPClient:()=>ge,MCPManager:()=>$t,MCPSkillAdapter:()=>ye,MemorySkill:()=>Ce,NoteSkill:()=>Ne,PluginLoader:()=>ss,ProfileSkill:()=>ze,ReminderSkill:()=>Me,ScheduledTaskSkill:()=>Ve,ScreenshotSkill:()=>He,ShellSkill:()=>Oe,Skill:()=>b,SkillRegistry:()=>Ie,SkillSandbox:()=>$e,SystemInfoSkill:()=>Ae,WeatherSkill:()=>De,WebSearchSkill:()=>Le,createCalendarProvider:()=>It});var At=f(()=>{"use strict";N();pn();hn();zs();fn();gn();yn();wn();En();Tn();bn();kn();vn();xn();In();Rn();An();Ln();Nn();On();Cn();Wn();Hn();Xn();zn();Kn();Gn();Yn()});var Lt,tr=f(()=>{"use strict";Lt=class{static{d(this,"ConversationManager")}conversations;constructor(e){this.conversations=e}getOrCreateConversation(e,t,s){let r=this.conversations.findByPlatformChat(e,t);return r?(this.conversations.updateTimestamp(r.id),r):this.conversations.create(e,t,s)}addMessage(e,t,s,r){return this.conversations.addMessage(e,t,s,r)}getHistory(e,t=20){return this.conversations.getMessages(e,t)}}});import Jn from"node:fs";import Zn from"node:path";var sr,ji,Bi,Mt,rr=f(()=>{"use strict";Hs();sr=10,ji=.85,Bi=1e5,Mt=class{static{d(this,"MessagePipeline")}promptBuilder;llm;conversationManager;users;logger;skillRegistry;skillSandbox;securityManager;memoryRepo;speechTranscriber;inboxPath;embeddingService;activeLearning;memoryRetriever;activeAgents=new Map;agentIdCounter=0;constructor(e){this.llm=e.llm,this.conversationManager=e.conversationManager,this.users=e.users,this.logger=e.logger,this.skillRegistry=e.skillRegistry,this.skillSandbox=e.skillSandbox,this.securityManager=e.securityManager,this.memoryRepo=e.memoryRepo,this.speechTranscriber=e.speechTranscriber,this.inboxPath=e.inboxPath,this.embeddingService=e.embeddingService,this.activeLearning=e.activeLearning,this.memoryRetriever=e.memoryRetriever,this.promptBuilder=new Tt}async process(e,t){let s=Date.now();this.logger.info({platform:e.platform,userId:e.userId,chatId:e.chatId},"Processing message");try{let r=this.users.findOrCreate(e.platform,e.userId,e.userName,e.displayName),n="getMasterUserId"in this.users?this.users.getMasterUserId(r.id):r.id,o=this.conversationManager.getOrCreateConversation(e.platform,e.chatId,r.id),i=this.conversationManager.getHistory(o.id,50);this.conversationManager.addMessage(o.id,"user",e.text);let a;if(this.memoryRetriever&&e.text)try{a=await this.memoryRetriever.retrieve(n,e.text,15)}catch(v){this.logger.debug({err:v},"Hybrid memory retrieval failed")}if(!a&&this.memoryRepo)try{if(this.embeddingService&&e.text&&this.llm.supportsEmbeddings()){let v=await this.embeddingService.semanticSearch(n,e.text,10),F=this.memoryRepo.getRecentForPrompt(n,5),O=new Set;a=[];for(let W of v)O.has(W.key)||(O.add(W.key),a.push(W));for(let W of F)O.has(W.key)||(O.add(W.key),a.push(W))}else a=this.memoryRepo.getRecentForPrompt(n,20)}catch(v){this.logger.debug({err:v},"Memory loading failed")}let l;try{"getProfile"in this.users&&(l=this.users.getProfile(r.id),l&&!l.displayName&&(l.displayName=r.displayName??r.username))}catch(v){this.logger.debug({err:v},"Profile loading failed")}let u=l?.timezone||Intl.DateTimeFormat().resolvedOptions().timeZone,p=this.skillRegistry?this.skillRegistry.getAll().map(v=>v.metadata):void 0,m=p?this.promptBuilder.buildTools(p):void 0,h=this.promptBuilder.buildSystemPrompt({memories:a,skills:p,userProfile:l}),E=this.buildActiveAgentStatus();E&&(h+=`
438
+ ${o}`}}deleteDoc(e){let t=e.document_id;if(!t||typeof t!="string")return{success:!1,error:'Missing required field "document_id" for delete action'};let s=this.docRepo.getDocument(t);return s?(this.docRepo.deleteDocument(t),{success:!0,data:{documentId:t},display:`Document "${s.filename}" deleted.`}):{success:!1,error:`Document "${t}" not found`}}}});var is={};q(is,{ActivityTracker:()=>he,BackgroundTaskSkill:()=>Ke,BrowserSkill:()=>Xe,CalculatorSkill:()=>Re,CalendarProvider:()=>V,CalendarSkill:()=>fe,ClipboardSkill:()=>We,CodeExecutionSkill:()=>Rt,CodeExecutor:()=>we,CrossPlatformSkill:()=>qe,DelegateSkill:()=>Ue,DocumentSkill:()=>Ye,EmailSkill:()=>Pe,FileSkill:()=>je,HttpSkill:()=>Fe,MCPClient:()=>ge,MCPManager:()=>$t,MCPSkillAdapter:()=>ye,MemorySkill:()=>Ce,NoteSkill:()=>Ne,PluginLoader:()=>ss,ProfileSkill:()=>ze,ReminderSkill:()=>Me,ScheduledTaskSkill:()=>Ve,ScreenshotSkill:()=>He,ShellSkill:()=>Oe,Skill:()=>b,SkillRegistry:()=>Ie,SkillSandbox:()=>$e,SystemInfoSkill:()=>Ae,WeatherSkill:()=>De,WebSearchSkill:()=>Le,createCalendarProvider:()=>It});var At=f(()=>{"use strict";N();pn();hn();zs();fn();gn();yn();wn();En();Tn();bn();kn();vn();xn();In();Rn();An();Ln();Nn();On();Cn();Wn();Hn();Xn();zn();Kn();Gn();Yn()});var Lt,tr=f(()=>{"use strict";Lt=class{static{d(this,"ConversationManager")}conversations;constructor(e){this.conversations=e}getOrCreateConversation(e,t,s){let r=this.conversations.findByPlatformChat(e,t);return r?(this.conversations.updateTimestamp(r.id),r):this.conversations.create(e,t,s)}addMessage(e,t,s,r){return this.conversations.addMessage(e,t,s,r)}getHistory(e,t=20){return this.conversations.getMessages(e,t)}}});import Jn from"node:fs";import Zn from"node:path";var sr,ji,Bi,Mt,rr=f(()=>{"use strict";Hs();sr=10,ji=.85,Bi=1e5,Mt=class{static{d(this,"MessagePipeline")}promptBuilder;llm;conversationManager;users;logger;skillRegistry;skillSandbox;securityManager;memoryRepo;speechTranscriber;inboxPath;embeddingService;activeLearning;memoryRetriever;activeAgents=new Map;agentIdCounter=0;constructor(e){this.llm=e.llm,this.conversationManager=e.conversationManager,this.users=e.users,this.logger=e.logger,this.skillRegistry=e.skillRegistry,this.skillSandbox=e.skillSandbox,this.securityManager=e.securityManager,this.memoryRepo=e.memoryRepo,this.speechTranscriber=e.speechTranscriber,this.inboxPath=e.inboxPath,this.embeddingService=e.embeddingService,this.activeLearning=e.activeLearning,this.memoryRetriever=e.memoryRetriever,this.promptBuilder=new Tt}async process(e,t){let s=Date.now();this.logger.info({platform:e.platform,userId:e.userId,chatId:e.chatId},"Processing message");try{let r=this.users.findOrCreate(e.platform,e.userId,e.userName,e.displayName),n="getMasterUserId"in this.users?this.users.getMasterUserId(r.id):r.id,o=this.conversationManager.getOrCreateConversation(e.platform,e.chatId,r.id),i=this.conversationManager.getHistory(o.id,50);this.conversationManager.addMessage(o.id,"user",e.text);let a;if(this.memoryRetriever&&e.text)try{a=await this.memoryRetriever.retrieve(n,e.text,15)}catch(v){this.logger.debug({err:v},"Hybrid memory retrieval failed")}if(!a&&this.memoryRepo)try{if(this.embeddingService&&e.text&&this.llm.supportsEmbeddings()){let v=await this.embeddingService.semanticSearch(n,e.text,10),F=this.memoryRepo.getRecentForPrompt(n,5),O=new Set;a=[];for(let W of v)O.has(W.key)||(O.add(W.key),a.push(W));for(let W of F)O.has(W.key)||(O.add(W.key),a.push(W))}else a=this.memoryRepo.getRecentForPrompt(n,20)}catch(v){this.logger.debug({err:v},"Memory loading failed")}let l;try{"getProfile"in this.users&&(l=this.users.getProfile(r.id),l&&!l.displayName&&(l.displayName=r.displayName??r.username))}catch(v){this.logger.debug({err:v},"Profile loading failed")}let u=l?.timezone||Intl.DateTimeFormat().resolvedOptions().timeZone,h=this.skillRegistry?this.skillRegistry.getAll().map(v=>v.metadata):void 0,m=h?this.promptBuilder.buildTools(h):void 0,p=this.promptBuilder.buildSystemPrompt({memories:a,skills:h,userProfile:l}),E=this.buildActiveAgentStatus();E&&(p+=`
439
439
 
440
- `+E);let w=this.promptBuilder.buildMessages(i),T=await this.buildUserContent(e,t);w.push({role:"user",content:T});let I=this.trimToContextWindow(h,w),_,k=0;for(t?.("Thinking...");;){if(_=await this.llm.complete({messages:I,system:h,tools:m&&m.length>0?m:void 0}),!_.toolCalls||_.toolCalls.length===0||k>=sr){k>=sr&&_.toolCalls?.length&&this.logger.warn({iteration:k},"Max tool iterations reached, stopping loop");break}k++,this.logger.info({iteration:k,toolCalls:_.toolCalls.length},"Processing tool calls");let v=[];_.content&&v.push({type:"text",text:_.content});for(let O of _.toolCalls)v.push({type:"tool_use",id:O.id,name:O.name,input:O.input});I.push({role:"assistant",content:v});let F=await this.executeToolCallsParallel(_.toolCalls,{userId:e.userId,chatId:e.chatId,chatType:e.chatType,platform:e.platform,conversationId:o.id,timezone:u},t);this.conversationManager.addMessage(o.id,"assistant",_.content??"",JSON.stringify(_.toolCalls)),this.conversationManager.addMessage(o.id,"user","",JSON.stringify(F)),I.push({role:"user",content:F}),k<sr&&t?.("Thinking...")}let A=_.content||"(no response)";this.conversationManager.addMessage(o.id,"assistant",A),this.activeLearning&&this.activeLearning.onMessageProcessed(n,e.text,A);let x=Date.now()-s;return this.logger.info({duration:x,tokens:_.usage,stopReason:_.stopReason,toolIterations:k},"Message processed"),A}catch(r){throw this.logger.error({err:r},"Failed to process message"),r}}async executeToolCallsParallel(e,t,s){if(e.length===1){let n=e[0],o=this.getToolLabel(n.name,n.input);s?.(o);let i=await this.executeToolCall(n,t,s);return[{type:"tool_result",tool_use_id:n.id,content:i.content,is_error:i.isError}]}s?.(`Running ${e.length} tools in parallel...`);let r=await Promise.allSettled(e.map(n=>this.executeToolCall(n,t,s)));return e.map((n,o)=>{let i=r[o];return i.status==="fulfilled"?{type:"tool_result",tool_use_id:n.id,content:i.value.content,is_error:i.value.isError}:{type:"tool_result",tool_use_id:n.id,content:`Tool execution failed: ${i.reason}`,is_error:!0}})}async executeToolCall(e,t,s){let r=this.skillRegistry?.get(e.name);if(!r)return this.logger.warn({tool:e.name},"Unknown skill requested"),{content:`Error: Unknown tool "${e.name}"`,isError:!0};if(this.securityManager){let n=this.securityManager.evaluate({userId:t.userId,action:e.name,riskLevel:r.metadata.riskLevel,platform:t.platform,chatId:t.chatId,chatType:t.chatType});if(!n.allowed)return this.logger.warn({tool:e.name,reason:n.reason,rule:n.matchedRule?.id},"Skill execution denied by security rules"),{content:`Access denied: ${n.reason}`,isError:!0}}if(this.skillSandbox){let n,o;if(e.name==="delegate"){let{ActivityTracker:a}=await Promise.resolve().then(()=>(At(),is));n=new a(s),o=`agent-${++this.agentIdCounter}`,this.activeAgents.set(o,{chatId:t.chatId,task:String(e.input.task??"").slice(0,200),tracker:n,startedAt:Date.now()})}let i=e.name==="delegate"?{...t,tracker:n,onProgress:s}:t;try{let a=await this.skillSandbox.execute(r,e.input,i,void 0,n);return{content:a.display??(a.success?JSON.stringify(a.data):a.error??"Unknown error"),isError:!a.success}}finally{o&&this.activeAgents.delete(o)}}try{let n=await r.execute(e.input,t);return{content:n.display??(n.success?JSON.stringify(n.data):n.error??"Unknown error"),isError:!n.success}}catch(n){return{content:`Skill execution failed: ${n instanceof Error?n.message:String(n)}`,isError:!0}}}getToolLabel(e,t){switch(e){case"shell":return`Running: ${String(t.command??"").slice(0,60)}`;case"web_search":return`Searching: ${String(t.query??"")}`;case"email":return`Email: ${String(t.action??"")}`;case"memory":return`Memory: ${String(t.action??"")}`;case"reminder":return`Reminder: ${String(t.action??"")}`;case"calculator":return"Calculating...";case"system_info":return"Getting system info...";case"delegate":return"Delegating sub-task...";case"http":return`Fetching: ${String(t.url??"").slice(0,60)}`;case"file":return`File: ${String(t.action??"")} ${String(t.path??"").slice(0,50)}`;case"clipboard":return`Clipboard: ${String(t.action??"")}`;case"screenshot":return"Taking screenshot...";case"browser":return`Browser: ${String(t.action??"")} ${String(t.url??"").slice(0,50)}`;case"weather":return`Weather: ${String(t.location??"")}`;case"note":return`Note: ${String(t.action??"")}`;case"profile":return`Profile: ${String(t.action??"")}`;case"calendar":return`Calendar: ${String(t.action??"")}`;case"background_task":return`Background task: ${String(t.action??"")}`;case"scheduled_task":return`Scheduled task: ${String(t.action??"")}`;case"cross_platform":return`Cross-platform: ${String(t.action??"")}`;case"code_sandbox":return"Running code...";case"document":return`Document: ${String(t.action??"")}`;default:return`Using ${e}...`}}buildActiveAgentStatus(){if(this.activeAgents.size===0)return;let e=["## Currently running sub-agents"];for(let[t,s]of this.activeAgents){let r=s.tracker.getSnapshot(),n=Math.round(r.totalElapsedMs/1e3);e.push(`- **${t}**: "${s.task}"`,` Status: ${s.tracker.formatStatus()}`,` Running for ${n}s | Last activity ${Math.round(r.idleMs/1e3)}s ago`)}return e.push(""),e.push("If the user asks what you or the agent is doing, describe the above status in natural language."),e.join(`
441
- `)}trimToContextWindow(e,t){let s=this.llm.getContextWindow(),r=Math.floor(s.maxInputTokens*ji),n=ne(e),o=t[t.length-1],i=es(o),a=n+i+200,l=r-a;if(l<=0)return this.logger.warn({maxInputTokens:r,systemTokens:n,latestTokens:i},"Context window very tight, sending only latest message"),[o];let u=[];for(let m=t.length-2;m>=0;m--){let h=es(t[m]);if(h>l)break;l-=h,u.unshift(t[m])}let p=t.length-1-u.length;return p>0&&(this.logger.info({trimmedCount:p,totalMessages:t.length,maxInputTokens:r},"Trimmed conversation history to fit context window"),u.unshift({role:"user",content:`[System note: ${p} older message(s) were omitted to fit the context window. The conversation continues from the most recent messages.]`})),u.push(o),u}async buildUserContent(e,t){let s=e.attachments?.filter(o=>o.data)??[];if(s.length===0)return e.text;let r=[];for(let o of s)if(o.type==="image"&&o.data)r.push({type:"image",source:{type:"base64",media_type:o.mimeType??"image/jpeg",data:o.data.toString("base64")}}),this.logger.info({mimeType:o.mimeType,size:o.size},"Image attached to LLM request");else if(o.type==="audio"&&o.data)if(this.speechTranscriber){t?.("Transcribing voice...");try{let i=await this.speechTranscriber.transcribe(o.data,o.mimeType??"audio/ogg"),a=e.text==="[Voice message]"?"":`${e.text}
440
+ `+E);let w=this.promptBuilder.buildMessages(i),T=await this.buildUserContent(e,t);w.push({role:"user",content:T});let x=this.trimToContextWindow(p,w),S,k=0;for(t?.("Thinking...");;){if(S=await this.llm.complete({messages:x,system:p,tools:m&&m.length>0?m:void 0}),!S.toolCalls||S.toolCalls.length===0||k>=sr){k>=sr&&S.toolCalls?.length&&this.logger.warn({iteration:k},"Max tool iterations reached, stopping loop");break}k++,this.logger.info({iteration:k,toolCalls:S.toolCalls.length},"Processing tool calls");let v=[];S.content&&v.push({type:"text",text:S.content});for(let O of S.toolCalls)v.push({type:"tool_use",id:O.id,name:O.name,input:O.input});x.push({role:"assistant",content:v});let F=await this.executeToolCallsParallel(S.toolCalls,{userId:e.userId,chatId:e.chatId,chatType:e.chatType,platform:e.platform,conversationId:o.id,timezone:u},t);this.conversationManager.addMessage(o.id,"assistant",S.content??"",JSON.stringify(S.toolCalls)),this.conversationManager.addMessage(o.id,"user","",JSON.stringify(F)),x.push({role:"user",content:F}),k<sr&&t?.("Thinking...")}let A=S.content||"(no response)";this.conversationManager.addMessage(o.id,"assistant",A),this.activeLearning&&this.activeLearning.onMessageProcessed(n,e.text,A);let I=Date.now()-s;return this.logger.info({duration:I,tokens:S.usage,stopReason:S.stopReason,toolIterations:k},"Message processed"),A}catch(r){throw this.logger.error({err:r},"Failed to process message"),r}}async executeToolCallsParallel(e,t,s){if(e.length===1){let n=e[0],o=this.getToolLabel(n.name,n.input);s?.(o);let i=await this.executeToolCall(n,t,s);return[{type:"tool_result",tool_use_id:n.id,content:i.content,is_error:i.isError}]}s?.(`Running ${e.length} tools in parallel...`);let r=await Promise.allSettled(e.map(n=>this.executeToolCall(n,t,s)));return e.map((n,o)=>{let i=r[o];return i.status==="fulfilled"?{type:"tool_result",tool_use_id:n.id,content:i.value.content,is_error:i.value.isError}:{type:"tool_result",tool_use_id:n.id,content:`Tool execution failed: ${i.reason}`,is_error:!0}})}async executeToolCall(e,t,s){let r=this.skillRegistry?.get(e.name);if(!r)return this.logger.warn({tool:e.name},"Unknown skill requested"),{content:`Error: Unknown tool "${e.name}"`,isError:!0};if(this.securityManager){let n=this.securityManager.evaluate({userId:t.userId,action:e.name,riskLevel:r.metadata.riskLevel,platform:t.platform,chatId:t.chatId,chatType:t.chatType});if(!n.allowed)return this.logger.warn({tool:e.name,reason:n.reason,rule:n.matchedRule?.id},"Skill execution denied by security rules"),{content:`Access denied: ${n.reason}`,isError:!0}}if(this.skillSandbox){let n,o;if(e.name==="delegate"){let{ActivityTracker:a}=await Promise.resolve().then(()=>(At(),is));n=new a(s),o=`agent-${++this.agentIdCounter}`,this.activeAgents.set(o,{chatId:t.chatId,task:String(e.input.task??"").slice(0,200),tracker:n,startedAt:Date.now()})}let i=e.name==="delegate"?{...t,tracker:n,onProgress:s}:t;try{let a=await this.skillSandbox.execute(r,e.input,i,void 0,n);return{content:a.display??(a.success?JSON.stringify(a.data):a.error??"Unknown error"),isError:!a.success}}finally{o&&this.activeAgents.delete(o)}}try{let n=await r.execute(e.input,t);return{content:n.display??(n.success?JSON.stringify(n.data):n.error??"Unknown error"),isError:!n.success}}catch(n){return{content:`Skill execution failed: ${n instanceof Error?n.message:String(n)}`,isError:!0}}}getToolLabel(e,t){switch(e){case"shell":return`Running: ${String(t.command??"").slice(0,60)}`;case"web_search":return`Searching: ${String(t.query??"")}`;case"email":return`Email: ${String(t.action??"")}`;case"memory":return`Memory: ${String(t.action??"")}`;case"reminder":return`Reminder: ${String(t.action??"")}`;case"calculator":return"Calculating...";case"system_info":return"Getting system info...";case"delegate":return"Delegating sub-task...";case"http":return`Fetching: ${String(t.url??"").slice(0,60)}`;case"file":return`File: ${String(t.action??"")} ${String(t.path??"").slice(0,50)}`;case"clipboard":return`Clipboard: ${String(t.action??"")}`;case"screenshot":return"Taking screenshot...";case"browser":return`Browser: ${String(t.action??"")} ${String(t.url??"").slice(0,50)}`;case"weather":return`Weather: ${String(t.location??"")}`;case"note":return`Note: ${String(t.action??"")}`;case"profile":return`Profile: ${String(t.action??"")}`;case"calendar":return`Calendar: ${String(t.action??"")}`;case"background_task":return`Background task: ${String(t.action??"")}`;case"scheduled_task":return`Scheduled task: ${String(t.action??"")}`;case"cross_platform":return`Cross-platform: ${String(t.action??"")}`;case"code_sandbox":return"Running code...";case"document":return`Document: ${String(t.action??"")}`;default:return`Using ${e}...`}}buildActiveAgentStatus(){if(this.activeAgents.size===0)return;let e=["## Currently running sub-agents"];for(let[t,s]of this.activeAgents){let r=s.tracker.getSnapshot(),n=Math.round(r.totalElapsedMs/1e3);e.push(`- **${t}**: "${s.task}"`,` Status: ${s.tracker.formatStatus()}`,` Running for ${n}s | Last activity ${Math.round(r.idleMs/1e3)}s ago`)}return e.push(""),e.push("If the user asks what you or the agent is doing, describe the above status in natural language."),e.join(`
441
+ `)}trimToContextWindow(e,t){let s=this.llm.getContextWindow(),r=Math.floor(s.maxInputTokens*ji),n=ne(e),o=t[t.length-1],i=es(o),a=n+i+200,l=r-a;if(l<=0)return this.logger.warn({maxInputTokens:r,systemTokens:n,latestTokens:i},"Context window very tight, sending only latest message"),[o];let u=t.slice(0,-1),h=this.groupToolPairs(u),m=[];for(let w=h.length-1;w>=0;w--){let T=h[w].reduce((x,S)=>x+es(S),0);if(T>l)break;l-=T,m.unshift(h[w])}let p=m.flat(),E=u.length-p.length;return E>0&&(this.logger.info({trimmedCount:E,totalMessages:t.length,maxInputTokens:r},"Trimmed conversation history to fit context window"),p.unshift({role:"user",content:`[System note: ${E} older message(s) were omitted to fit the context window. The conversation continues from the most recent messages.]`})),p.push(o),p}groupToolPairs(e){let t=[],s=0;for(;s<e.length;){let r=e[s];if(r.role==="assistant"&&Array.isArray(r.content)&&r.content.some(n=>n.type==="tool_use")){let n=[r];if(s+1<e.length&&e[s+1].role==="user"){let o=e[s+1];if(Array.isArray(o.content)&&o.content.some(i=>i.type==="tool_result")){n.push(o),s+=2,t.push(n);continue}}t.push(n),s++}else t.push([r]),s++}return t}async buildUserContent(e,t){let s=e.attachments?.filter(o=>o.data)??[];if(s.length===0)return e.text;let r=[];for(let o of s)if(o.type==="image"&&o.data)r.push({type:"image",source:{type:"base64",media_type:o.mimeType??"image/jpeg",data:o.data.toString("base64")}}),this.logger.info({mimeType:o.mimeType,size:o.size},"Image attached to LLM request");else if(o.type==="audio"&&o.data)if(this.speechTranscriber){t?.("Transcribing voice...");try{let i=await this.speechTranscriber.transcribe(o.data,o.mimeType??"audio/ogg"),a=e.text==="[Voice message]"?"":`${e.text}
442
442
 
443
443
  `;return r.push({type:"text",text:`${a}[Voice transcript]: ${i}`}),this.logger.info({transcriptLength:i.length},"Voice message transcribed"),r.length===1&&r[0].type==="text"?r[0].text:r}catch(i){this.logger.error({err:i},"Voice transcription failed"),r.push({type:"text",text:"[Voice message could not be transcribed]"})}}else r.push({type:"text",text:"[Voice message received but speech-to-text is not configured. Add speech config to enable transcription.]"});else if((o.type==="document"||o.type==="video"||o.type==="other")&&o.data){let i=this.saveToInbox(o);if(i){let a=this.isTextMimeType(o.mimeType),l=`[File received: "${o.fileName??"unknown"}" (${this.formatBytes(o.data.length)}, ${o.mimeType??"unknown type"})]
444
444
  [Saved to: ${i}]`;if(a&&o.data.length<=Bi){let u=o.data.toString("utf-8");l+=`
445
445
  [File content]:
446
- ${u}`}r.push({type:"text",text:l}),this.logger.info({fileName:o.fileName,savedPath:i,size:o.data.length},"File saved to inbox")}}let n=["[Photo]","[Voice message]","[Video]","[Video note]","[Document]","[File]"];return e.text&&!n.includes(e.text)?r.push({type:"text",text:e.text}):r.some(o=>o.type==="image")&&!r.some(o=>o.type==="text")?r.push({type:"text",text:"What do you see in this image?"}):r.length===0&&r.push({type:"text",text:e.text||"(empty message)"}),r}saveToInbox(e){if(!e.data)return;let t=this.inboxPath??Zn.resolve("./data/inbox");try{Jn.mkdirSync(t,{recursive:!0})}catch{this.logger.error({inboxDir:t},"Cannot create inbox directory");return}let s=new Date().toISOString().replace(/[:.]/g,"-"),n=(e.fileName??`file_${s}`).replace(/[<>:"/\\|?*]/g,"_"),o=`${s}_${n}`,i=Zn.join(t,o);try{return Jn.writeFileSync(i,e.data),i}catch(a){this.logger.error({err:a,filePath:i},"Failed to save file to inbox");return}}isTextMimeType(e){return e?["text/","application/json","application/xml","application/javascript","application/typescript","application/x-yaml","application/yaml","application/toml","application/x-sh","application/sql","application/csv","application/x-csv"].some(s=>e.startsWith(s)):!1}formatBytes(e){return e<1024?`${e} B`:e<1024*1024?`${(e/1024).toFixed(1)} KB`:`${(e/(1024*1024)).toFixed(1)} MB`}}});var Nt,nr=f(()=>{"use strict";Nt=class{static{d(this,"ReminderScheduler")}reminderRepo;sendMessage;logger;intervalId;checkIntervalMs;constructor(e,t,s,r=15e3){this.reminderRepo=e,this.sendMessage=t,this.logger=s,this.checkIntervalMs=r}start(){this.logger.info("Reminder scheduler started"),this.intervalId=setInterval(()=>this.checkDueReminders(),this.checkIntervalMs),this.checkDueReminders()}stop(){this.intervalId&&(clearInterval(this.intervalId),this.intervalId=void 0),this.logger.info("Reminder scheduler stopped")}async checkDueReminders(){try{let e=this.reminderRepo.getDue();for(let t of e)try{await this.sendMessage(t.platform,t.chatId,`\u23F0 Reminder: ${t.message}`),this.reminderRepo.markFired(t.id),this.logger.info({reminderId:t.id},"Reminder fired")}catch(s){this.logger.error({err:s,reminderId:t.id},"Failed to send reminder")}}catch(e){this.logger.error({err:e},"Error checking due reminders")}}}});var Dt,or=f(()=>{"use strict";Dt=class{static{d(this,"SpeechTranscriber")}logger;apiKey;baseUrl;constructor(e,t){this.logger=t,this.apiKey=e.apiKey,e.provider==="groq"?this.baseUrl=e.baseUrl??"https://api.groq.com/openai/v1":this.baseUrl=e.baseUrl??"https://api.openai.com/v1"}async transcribe(e,t){let s=this.mimeToExtension(t),r=new FormData;r.append("file",new Blob([e],{type:t}),`audio.${s}`),r.append("model","whisper-1");try{let n=await fetch(`${this.baseUrl}/audio/transcriptions`,{method:"POST",headers:{Authorization:`Bearer ${this.apiKey}`},body:r});if(!n.ok){let i=await n.text();throw new Error(`Whisper API ${n.status}: ${i}`)}let o=await n.json();return this.logger.info({textLength:o.text.length},"Voice transcribed"),o.text}catch(n){throw this.logger.error({err:n},"Voice transcription failed"),n}}mimeToExtension(e){return{"audio/ogg":"ogg","audio/mpeg":"mp3","audio/mp4":"m4a","audio/wav":"wav","audio/webm":"webm","audio/x-m4a":"m4a"}[e]??"ogg"}}});var Ot,ir=f(()=>{"use strict";Ot=class{static{d(this,"ResponseFormatter")}format(e,t){switch(t){case"telegram":return{text:this.toTelegramHTML(e),parseMode:"html"};case"discord":return{text:e,parseMode:"markdown"};case"matrix":return{text:this.toMatrixHTML(e),parseMode:"html"};case"whatsapp":return{text:this.toWhatsApp(e),parseMode:"text"};case"signal":return{text:this.stripFormatting(e),parseMode:"text"};default:return{text:e,parseMode:"text"}}}toTelegramHTML(e){let t=e;return t=t.replace(/```(\w*)\n([\s\S]*?)```/g,(s,r,n)=>`<pre>${this.escapeHTML(n.trimEnd())}</pre>`),t=t.replace(/`([^`]+)`/g,(s,r)=>`<code>${this.escapeHTML(r)}</code>`),t=t.replace(/\*\*(.+?)\*\*/g,"<b>$1</b>"),t=t.replace(/(?<!\*)\*(?!\*)(.+?)(?<!\*)\*(?!\*)/g,"<i>$1</i>"),t=t.replace(/~~(.+?)~~/g,"<s>$1</s>"),t=t.replace(/\[([^\]]+)\]\(([^)]+)\)/g,'<a href="$2">$1</a>'),t}toMatrixHTML(e){return this.toTelegramHTML(e)}toWhatsApp(e){let t=e;return t=t.replace(/\*\*(.+?)\*\*/g,"*$1*"),t=t.replace(/(?<!\*)\*(?!\*)(.+?)(?<!\*)\*(?!\*)/g,"_$1_"),t=t.replace(/~~(.+?)~~/g,"~$1~"),t=t.replace(/\[([^\]]+)\]\(([^)]+)\)/g,"$1 ($2)"),t}stripFormatting(e){let t=e;return t=t.replace(/```\w*\n?/g,""),t=t.replace(/`([^`]+)`/g,"$1"),t=t.replace(/\*\*(.+?)\*\*/g,"$1"),t=t.replace(/(?<!\*)\*(?!\*)(.+?)(?<!\*)\*(?!\*)/g,"$1"),t=t.replace(/~~(.+?)~~/g,"$1"),t=t.replace(/\[([^\]]+)\]\(([^)]+)\)/g,"$1 ($2)"),t}escapeHTML(e){return e.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}}});var Ct,ar=f(()=>{"use strict";Ct=class{static{d(this,"EmbeddingService")}llm;embeddingRepo;logger;constructor(e,t,s){this.llm=e,this.embeddingRepo=t,this.logger=s}async embedAndStore(e,t,s,r){if(this.llm.supportsEmbeddings())try{let n=await this.llm.embed(t);if(!n)return;this.embeddingRepo.store({userId:e,sourceType:s,sourceId:r,content:t,embedding:n.embedding,model:n.model,dimensions:n.dimensions}),this.logger.debug({userId:e,sourceType:s,sourceId:r},"Embedding stored")}catch(n){this.logger.error({err:n,userId:e,sourceType:s,sourceId:r},"Failed to embed content")}}async semanticSearch(e,t,s=10){if(!this.llm.supportsEmbeddings())return[];try{let r=await this.llm.embed(t);if(!r)return[];let n=this.embeddingRepo.findByUser(e);if(n.length===0)return[];let o=n.map(a=>{let l=this.cosineSimilarity(r.embedding,a.embedding);return{...a,score:l}});return o.sort((a,l)=>l.score-a.score),o.slice(0,s).map(a=>({key:a.sourceId,value:a.content,category:a.sourceType,score:a.score}))}catch(r){return this.logger.error({err:r},"Semantic search failed"),[]}}cosineSimilarity(e,t){if(e.length!==t.length)return 0;let s=0,r=0,n=0;for(let i=0;i<e.length;i++)s+=e[i]*t[i],r+=e[i]*e[i],n+=t[i]*t[i];let o=Math.sqrt(r)*Math.sqrt(n);return o===0?0:s/o}}});var Ut,cr=f(()=>{"use strict";Ut=class{static{d(this,"DocumentProcessor")}docRepo;embeddingService;logger;constructor(e,t,s){this.docRepo=e,this.embeddingService=t,this.logger=s}async ingest(e,t,s,r){let n=await this.extractText(t,r),i=(await import("node:fs")).statSync(t),a=this.docRepo.createDocument(e,s,r,i.size),l=this.chunkText(n,500,50);for(let u=0;u<l.length;u++){let p;try{await this.embeddingService.embedAndStore(e,l[u],"document",`${a.id}:${u}`),p=`${a.id}:${u}`}catch(m){this.logger.warn({documentId:a.id,chunkIndex:u,err:m},"Embedding failed for chunk, continuing")}this.docRepo.addChunk(a.id,u,l[u],p)}return this.docRepo.updateChunkCount(a.id,l.length),this.logger.info({documentId:a.id,filename:s,chunkCount:l.length},"Document ingested"),{documentId:a.id,chunkCount:l.length}}async extractText(e,t){let s=await import("node:fs");if(t==="application/pdf")try{let r=(await import("pdf-parse")).default,n=s.readFileSync(e);return(await r(n)).text}catch(r){throw this.logger.error({err:r},"PDF parsing failed"),new Error("Failed to parse PDF")}if(t==="application/vnd.openxmlformats-officedocument.wordprocessingml.document"||t==="application/msword")try{return(await(await import("mammoth")).extractRawText({path:e})).value}catch(r){throw this.logger.error({err:r},"DOCX parsing failed"),new Error("Failed to parse DOCX")}return s.readFileSync(e,"utf-8")}chunkText(e,t,s){let n=Math.round(t*3.5),o=Math.round(s*3.5),i=[],a=0;for(;a<e.length;){let l=a+n;if(l>=e.length){i.push(e.slice(a).trim());break}let u=Math.max(l-200,a),p=e.slice(u,l+200),m=p.lastIndexOf(`
446
+ ${u}`}r.push({type:"text",text:l}),this.logger.info({fileName:o.fileName,savedPath:i,size:o.data.length},"File saved to inbox")}}let n=["[Photo]","[Voice message]","[Video]","[Video note]","[Document]","[File]"];return e.text&&!n.includes(e.text)?r.push({type:"text",text:e.text}):r.some(o=>o.type==="image")&&!r.some(o=>o.type==="text")?r.push({type:"text",text:"What do you see in this image?"}):r.length===0&&r.push({type:"text",text:e.text||"(empty message)"}),r}saveToInbox(e){if(!e.data)return;let t=this.inboxPath??Zn.resolve("./data/inbox");try{Jn.mkdirSync(t,{recursive:!0})}catch{this.logger.error({inboxDir:t},"Cannot create inbox directory");return}let s=new Date().toISOString().replace(/[:.]/g,"-"),n=(e.fileName??`file_${s}`).replace(/[<>:"/\\|?*]/g,"_"),o=`${s}_${n}`,i=Zn.join(t,o);try{return Jn.writeFileSync(i,e.data),i}catch(a){this.logger.error({err:a,filePath:i},"Failed to save file to inbox");return}}isTextMimeType(e){return e?["text/","application/json","application/xml","application/javascript","application/typescript","application/x-yaml","application/yaml","application/toml","application/x-sh","application/sql","application/csv","application/x-csv"].some(s=>e.startsWith(s)):!1}formatBytes(e){return e<1024?`${e} B`:e<1024*1024?`${(e/1024).toFixed(1)} KB`:`${(e/(1024*1024)).toFixed(1)} MB`}}});var Nt,nr=f(()=>{"use strict";Nt=class{static{d(this,"ReminderScheduler")}reminderRepo;sendMessage;logger;intervalId;checkIntervalMs;constructor(e,t,s,r=15e3){this.reminderRepo=e,this.sendMessage=t,this.logger=s,this.checkIntervalMs=r}start(){this.logger.info("Reminder scheduler started"),this.intervalId=setInterval(()=>this.checkDueReminders(),this.checkIntervalMs),this.checkDueReminders()}stop(){this.intervalId&&(clearInterval(this.intervalId),this.intervalId=void 0),this.logger.info("Reminder scheduler stopped")}async checkDueReminders(){try{let e=this.reminderRepo.getDue();for(let t of e)try{await this.sendMessage(t.platform,t.chatId,`\u23F0 Reminder: ${t.message}`),this.reminderRepo.markFired(t.id),this.logger.info({reminderId:t.id},"Reminder fired")}catch(s){this.logger.error({err:s,reminderId:t.id},"Failed to send reminder")}}catch(e){this.logger.error({err:e},"Error checking due reminders")}}}});var Dt,or=f(()=>{"use strict";Dt=class{static{d(this,"SpeechTranscriber")}logger;apiKey;baseUrl;constructor(e,t){this.logger=t,this.apiKey=e.apiKey,e.provider==="groq"?this.baseUrl=e.baseUrl??"https://api.groq.com/openai/v1":this.baseUrl=e.baseUrl??"https://api.openai.com/v1"}async transcribe(e,t){let s=this.mimeToExtension(t),r=new FormData;r.append("file",new Blob([e],{type:t}),`audio.${s}`),r.append("model","whisper-1");try{let n=await fetch(`${this.baseUrl}/audio/transcriptions`,{method:"POST",headers:{Authorization:`Bearer ${this.apiKey}`},body:r});if(!n.ok){let i=await n.text();throw new Error(`Whisper API ${n.status}: ${i}`)}let o=await n.json();return this.logger.info({textLength:o.text.length},"Voice transcribed"),o.text}catch(n){throw this.logger.error({err:n},"Voice transcription failed"),n}}mimeToExtension(e){return{"audio/ogg":"ogg","audio/mpeg":"mp3","audio/mp4":"m4a","audio/wav":"wav","audio/webm":"webm","audio/x-m4a":"m4a"}[e]??"ogg"}}});var Ot,ir=f(()=>{"use strict";Ot=class{static{d(this,"ResponseFormatter")}format(e,t){switch(t){case"telegram":return{text:this.toTelegramHTML(e),parseMode:"html"};case"discord":return{text:e,parseMode:"markdown"};case"matrix":return{text:this.toMatrixHTML(e),parseMode:"html"};case"whatsapp":return{text:this.toWhatsApp(e),parseMode:"text"};case"signal":return{text:this.stripFormatting(e),parseMode:"text"};default:return{text:e,parseMode:"text"}}}toTelegramHTML(e){let t=e;return t=t.replace(/```(\w*)\n([\s\S]*?)```/g,(s,r,n)=>`<pre>${this.escapeHTML(n.trimEnd())}</pre>`),t=t.replace(/`([^`]+)`/g,(s,r)=>`<code>${this.escapeHTML(r)}</code>`),t=t.replace(/\*\*(.+?)\*\*/g,"<b>$1</b>"),t=t.replace(/(?<!\*)\*(?!\*)(.+?)(?<!\*)\*(?!\*)/g,"<i>$1</i>"),t=t.replace(/~~(.+?)~~/g,"<s>$1</s>"),t=t.replace(/\[([^\]]+)\]\(([^)]+)\)/g,'<a href="$2">$1</a>'),t}toMatrixHTML(e){return this.toTelegramHTML(e)}toWhatsApp(e){let t=e;return t=t.replace(/\*\*(.+?)\*\*/g,"*$1*"),t=t.replace(/(?<!\*)\*(?!\*)(.+?)(?<!\*)\*(?!\*)/g,"_$1_"),t=t.replace(/~~(.+?)~~/g,"~$1~"),t=t.replace(/\[([^\]]+)\]\(([^)]+)\)/g,"$1 ($2)"),t}stripFormatting(e){let t=e;return t=t.replace(/```\w*\n?/g,""),t=t.replace(/`([^`]+)`/g,"$1"),t=t.replace(/\*\*(.+?)\*\*/g,"$1"),t=t.replace(/(?<!\*)\*(?!\*)(.+?)(?<!\*)\*(?!\*)/g,"$1"),t=t.replace(/~~(.+?)~~/g,"$1"),t=t.replace(/\[([^\]]+)\]\(([^)]+)\)/g,"$1 ($2)"),t}escapeHTML(e){return e.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}}});var Ct,ar=f(()=>{"use strict";Ct=class{static{d(this,"EmbeddingService")}llm;embeddingRepo;logger;constructor(e,t,s){this.llm=e,this.embeddingRepo=t,this.logger=s}async embedAndStore(e,t,s,r){if(this.llm.supportsEmbeddings())try{let n=await this.llm.embed(t);if(!n)return;this.embeddingRepo.store({userId:e,sourceType:s,sourceId:r,content:t,embedding:n.embedding,model:n.model,dimensions:n.dimensions}),this.logger.debug({userId:e,sourceType:s,sourceId:r},"Embedding stored")}catch(n){this.logger.error({err:n,userId:e,sourceType:s,sourceId:r},"Failed to embed content")}}async semanticSearch(e,t,s=10){if(!this.llm.supportsEmbeddings())return[];try{let r=await this.llm.embed(t);if(!r)return[];let n=this.embeddingRepo.findByUser(e);if(n.length===0)return[];let o=n.map(a=>{let l=this.cosineSimilarity(r.embedding,a.embedding);return{...a,score:l}});return o.sort((a,l)=>l.score-a.score),o.slice(0,s).map(a=>({key:a.sourceId,value:a.content,category:a.sourceType,score:a.score}))}catch(r){return this.logger.error({err:r},"Semantic search failed"),[]}}cosineSimilarity(e,t){if(e.length!==t.length)return 0;let s=0,r=0,n=0;for(let i=0;i<e.length;i++)s+=e[i]*t[i],r+=e[i]*e[i],n+=t[i]*t[i];let o=Math.sqrt(r)*Math.sqrt(n);return o===0?0:s/o}}});var Ut,cr=f(()=>{"use strict";Ut=class{static{d(this,"DocumentProcessor")}docRepo;embeddingService;logger;constructor(e,t,s){this.docRepo=e,this.embeddingService=t,this.logger=s}async ingest(e,t,s,r){let n=await this.extractText(t,r),i=(await import("node:fs")).statSync(t),a=this.docRepo.createDocument(e,s,r,i.size),l=this.chunkText(n,500,50);for(let u=0;u<l.length;u++){let h;try{await this.embeddingService.embedAndStore(e,l[u],"document",`${a.id}:${u}`),h=`${a.id}:${u}`}catch(m){this.logger.warn({documentId:a.id,chunkIndex:u,err:m},"Embedding failed for chunk, continuing")}this.docRepo.addChunk(a.id,u,l[u],h)}return this.docRepo.updateChunkCount(a.id,l.length),this.logger.info({documentId:a.id,filename:s,chunkCount:l.length},"Document ingested"),{documentId:a.id,chunkCount:l.length}}async extractText(e,t){let s=await import("node:fs");if(t==="application/pdf")try{let r=(await import("pdf-parse")).default,n=s.readFileSync(e);return(await r(n)).text}catch(r){throw this.logger.error({err:r},"PDF parsing failed"),new Error("Failed to parse PDF")}if(t==="application/vnd.openxmlformats-officedocument.wordprocessingml.document"||t==="application/msword")try{return(await(await import("mammoth")).extractRawText({path:e})).value}catch(r){throw this.logger.error({err:r},"DOCX parsing failed"),new Error("Failed to parse DOCX")}return s.readFileSync(e,"utf-8")}chunkText(e,t,s){let n=Math.round(t*3.5),o=Math.round(s*3.5),i=[],a=0;for(;a<e.length;){let l=a+n;if(l>=e.length){i.push(e.slice(a).trim());break}let u=Math.max(l-200,a),h=e.slice(u,l+200),m=h.lastIndexOf(`
447
447
 
448
- `);if(m>0)l=u+m;else{let E=p.lastIndexOf(". ");E>0&&(l=u+E+1)}let h=e.slice(a,l).trim();h&&i.push(h),a=l-o}return i.filter(l=>l.length>0)}}});var Pt,lr=f(()=>{"use strict";Pt=class{static{d(this,"BackgroundTaskRunner")}skillRegistry;skillSandbox;taskRepo;adapters;logger;pollTimer;running=0;maxConcurrent=3;pollIntervalMs=5e3;taskTimeoutMs=5*6e4;constructor(e,t,s,r,n){this.skillRegistry=e,this.skillSandbox=t,this.taskRepo=s,this.adapters=r,this.logger=n}start(){this.pollTimer=setInterval(()=>this.poll(),this.pollIntervalMs),this.logger.info("Background task runner started")}stop(){this.pollTimer&&(clearInterval(this.pollTimer),this.pollTimer=void 0),this.logger.info("Background task runner stopped")}async poll(){if(!(this.running>=this.maxConcurrent))try{let e=this.maxConcurrent-this.running,t=this.taskRepo.getPending(e);for(let s of t)this.running++,this.runTask(s).finally(()=>{this.running--})}catch(e){this.logger.error({err:e},"Error polling for background tasks")}}async runTask(e){this.taskRepo.updateStatus(e.id,"running");try{let t=this.skillRegistry.get(e.skillName);if(!t){this.taskRepo.updateStatus(e.id,"failed",void 0,`Unknown skill: ${e.skillName}`);return}let s;try{s=JSON.parse(e.skillInput)}catch(l){this.logger.warn({taskId:e.id,err:l},"Malformed skill input JSON"),this.taskRepo.updateStatus(e.id,"failed",void 0,"Malformed skill input JSON");return}let r={userId:e.userId,chatId:e.chatId,platform:e.platform,conversationId:"",chatType:"dm"},n=new Promise((l,u)=>setTimeout(()=>u(new Error("Background task timed out")),this.taskTimeoutMs)),o=await Promise.race([this.skillSandbox.execute(t,s,r),n]),i=JSON.stringify(o.data??o.display??o.error);this.taskRepo.updateStatus(e.id,o.success?"completed":"failed",i,o.error);let a=this.adapters.get(e.platform);if(a){let l=o.success?`\u2705 Background task completed: ${e.description}
448
+ `);if(m>0)l=u+m;else{let E=h.lastIndexOf(". ");E>0&&(l=u+E+1)}let p=e.slice(a,l).trim();p&&i.push(p),a=l-o}return i.filter(l=>l.length>0)}}});var Pt,lr=f(()=>{"use strict";Pt=class{static{d(this,"BackgroundTaskRunner")}skillRegistry;skillSandbox;taskRepo;adapters;logger;pollTimer;running=0;maxConcurrent=3;pollIntervalMs=5e3;taskTimeoutMs=5*6e4;constructor(e,t,s,r,n){this.skillRegistry=e,this.skillSandbox=t,this.taskRepo=s,this.adapters=r,this.logger=n}start(){this.pollTimer=setInterval(()=>this.poll(),this.pollIntervalMs),this.logger.info("Background task runner started")}stop(){this.pollTimer&&(clearInterval(this.pollTimer),this.pollTimer=void 0),this.logger.info("Background task runner stopped")}async poll(){if(!(this.running>=this.maxConcurrent))try{let e=this.maxConcurrent-this.running,t=this.taskRepo.getPending(e);for(let s of t)this.running++,this.runTask(s).finally(()=>{this.running--})}catch(e){this.logger.error({err:e},"Error polling for background tasks")}}async runTask(e){this.taskRepo.updateStatus(e.id,"running");try{let t=this.skillRegistry.get(e.skillName);if(!t){this.taskRepo.updateStatus(e.id,"failed",void 0,`Unknown skill: ${e.skillName}`);return}let s;try{s=JSON.parse(e.skillInput)}catch(l){this.logger.warn({taskId:e.id,err:l},"Malformed skill input JSON"),this.taskRepo.updateStatus(e.id,"failed",void 0,"Malformed skill input JSON");return}let r={userId:e.userId,chatId:e.chatId,platform:e.platform,conversationId:"",chatType:"dm"},n=new Promise((l,u)=>setTimeout(()=>u(new Error("Background task timed out")),this.taskTimeoutMs)),o=await Promise.race([this.skillSandbox.execute(t,s,r),n]),i=JSON.stringify(o.data??o.display??o.error);this.taskRepo.updateStatus(e.id,o.success?"completed":"failed",i,o.error);let a=this.adapters.get(e.platform);if(a){let l=o.success?`\u2705 Background task completed: ${e.description}
449
449
 
450
450
  Result: ${o.display??JSON.stringify(o.data)}`:`\u274C Background task failed: ${e.description}
451
451
 
@@ -473,29 +473,29 @@ Extract memories from this conversation:
473
473
  User: {USER_MESSAGE}
474
474
  Assistant: {ASSISTANT_RESPONSE}
475
475
 
476
- Return ONLY a valid JSON array, no explanation:`,jt=class{static{d(this,"MemoryExtractor")}llm;memoryRepo;logger;embeddingService;minConfidence;constructor(e,t,s,r,n=.4){this.llm=e,this.memoryRepo=t,this.logger=s,this.embeddingService=r,this.minConfidence=n}async extract(e,t,s){try{let r=zi.replace("{USER_MESSAGE}",t).replace("{ASSISTANT_RESPONSE}",s),n=await this.llm.complete({messages:[{role:"user",content:r}],temperature:.1,tier:"fast",maxTokens:1024}),o=this.parseResponse(n.content);if(o.length===0)return 0;let i=0;for(let a of o)if(!(a.confidence<this.minConfidence))try{let l=this.memoryRepo.saveWithMetadata(e,a.key,a.value,a.category,a.type,a.confidence,"auto");this.embeddingService&&this.embeddingService.embedAndStore(e,`${a.key}: ${a.value}`,"memory",l.id).catch(u=>this.logger.debug({err:u},"Auto-embed failed")),i++,this.logger.info({key:a.key,type:a.type,confidence:a.confidence},"Auto-extracted memory saved")}catch(l){this.logger.warn({err:l,key:a.key},"Failed to save extracted memory")}return i}catch(r){return this.logger.error({err:r},"Memory extraction failed"),0}}parseResponse(e){try{let t=e.match(/\[[\s\S]*\]/);if(!t)return[];let s=JSON.parse(t[0]);return Array.isArray(s)?s.filter(r=>typeof r=="object"&&r!==null).map(r=>({key:String(r.key||""),value:String(r.value||""),type:this.validateType(String(r.type||"fact")),confidence:this.clampConfidence(Number(r.confidence)||.5),category:String(r.category||"general")})).filter(r=>r.key&&r.value):[]}catch{return this.logger.debug({content:e.slice(0,200)},"Failed to parse extraction response"),[]}}validateType(e){return Xi.includes(e)?e:"fact"}clampConfidence(e){return Math.max(0,Math.min(1,e))}}});var Bt,hr=f(()=>{"use strict";mr();pr();Bt=class{static{d(this,"ActiveLearningService")}extractor;logger;minMessageLength;maxExtractionsPerMinute;extractionTimestamps=new Map;constructor(e){this.logger=e.logger,this.minMessageLength=e.minMessageLength??15,this.maxExtractionsPerMinute=e.maxExtractionsPerMinute??5,this.extractor=new jt(e.llm,e.memoryRepo,this.logger,e.embeddingService,e.minConfidence??.4)}onMessageProcessed(e,t,s){if(!t||t.length<this.minMessageLength)return;let r=ur(t);if(r.level==="low"){this.logger.debug({signal:"low"},"Skipping extraction \u2014 low signal");return}if(!this.checkRateLimit(e)){this.logger.debug({userId:e},"Skipping extraction \u2014 rate limit reached");return}this.logger.info({signal:r.level,patterns:r.matchedPatterns},"High signal detected, triggering extraction"),this.extractor.extract(e,t,s).then(n=>{n>0&&this.logger.info({userId:e,extractedCount:n},"Auto-extraction complete")}).catch(n=>{this.logger.error({err:n},"Auto-extraction failed")})}checkRateLimit(e){let t=Date.now(),s=t-6e4,r=this.extractionTimestamps.get(e);r||(r=[],this.extractionTimestamps.set(e,r));let n=r.filter(o=>o>s);return this.extractionTimestamps.set(e,n),n.length>=this.maxExtractionsPerMinute?!1:(n.push(t),!0)}}});var qi,Ki,Vi,Gi,Wt,fr=f(()=>{"use strict";qi=Math.LN2,Ki=.3,Vi=.7,Gi=3,Wt=class{static{d(this,"MemoryRetriever")}memoryRepo;logger;embeddingService;constructor(e,t,s){this.memoryRepo=e,this.logger=t,this.embeddingService=s}async retrieve(e,t,s=15){try{let r=this.memoryRepo.keywordSearch(e,t,30),n=[],o=!1;if(this.embeddingService)try{n=await this.embeddingService.semanticSearch(e,t,30),o=n.length>0}catch(m){this.logger.debug({err:m},"Semantic search failed, falling back to keyword-only")}let i=new Map,a=r.length;for(let m=0;m<r.length;m++){let h=r[m],E=a>0?1-m/a:0,w=o?Ki:1,T=this.applyBoosts(E*w,h);i.set(h.id,{memory:{key:h.key,value:h.value,category:h.category,type:h.type,score:T},score:T}),this.memoryRepo.recordAccess(h.id)}if(o)for(let m of n){let h=m.score*Vi,E=i.get(m.key);if(E)E.score+=h,E.memory.score=E.score;else{let w=this.memoryRepo.recall(e,m.key),T=this.applyBoosts(h,w||void 0);i.set(m.key,{memory:{key:m.key,value:m.value,category:m.category,type:w?.type||"general",score:T},score:T}),w&&this.memoryRepo.recordAccess(w.id)}}let l=Array.from(i.values()).sort((m,h)=>h.score-m.score),u=new Map,p=[];for(let{memory:m}of l){let h=u.get(m.type)||0;if(!(h>=Gi)&&(u.set(m.type,h+1),p.push(m),p.length>=s))break}return this.logger.debug({keywordCount:r.length,semanticCount:n.length,resultCount:p.length,hasSemanticSearch:o},"Hybrid memory retrieval complete"),p}catch(r){return this.logger.error({err:r},"Memory retrieval failed"),this.memoryRepo.getRecentForPrompt(e,s).map(n=>({key:n.key,value:n.value,category:n.category,type:n.type,score:0}))}}applyBoosts(e,t){let s=e;if(t){s*=.5+.5*t.confidence;let r=new Date(t.updatedAt).getTime(),n=Date.now()-r,o=Math.exp(-qi*n/2592e6);s*=o}return s}}});import{EventEmitter as Yi}from"node:events";var B,oe=f(()=>{"use strict";B=class extends Yi{static{d(this,"MessagingAdapter")}status="disconnected";async sendPhoto(e,t,s){}async sendFile(e,t,s,r){}getStatus(){return this.status}}});import{Bot as Ji,InputFile as Qn}from"grammy";function eo(c){if(c==="markdown")return"MarkdownV2";if(c==="html")return"HTML"}var as,to=f(()=>{"use strict";oe();d(eo,"mapParseMode");as=class extends B{static{d(this,"TelegramAdapter")}platform="telegram";bot;constructor(e){super(),this.bot=new Ji(e)}async connect(){this.status="connecting",this.bot.on("message:text",e=>{this.emit("message",this.normalizeMessage(e.message,e.message.text))}),this.bot.on("message:photo",async e=>{let t=e.message,r=(t.caption??"")||"[Photo]",n=t.photo[t.photo.length-1],o=await this.downloadAttachment(n.file_id,"image","image/jpeg"),i=this.normalizeMessage(t,r);i.attachments=o?[o]:void 0,this.emit("message",i)}),this.bot.on("message:voice",async e=>{let t=e.message,s=await this.downloadAttachment(t.voice.file_id,"audio",t.voice.mime_type??"audio/ogg"),r=this.normalizeMessage(t,"[Voice message]");r.attachments=s?[s]:void 0,this.emit("message",r)}),this.bot.on("message:audio",async e=>{let t=e.message,r=(t.caption??"")||`[Audio: ${t.audio.file_name??"audio"}]`,n=await this.downloadAttachment(t.audio.file_id,"audio",t.audio.mime_type??"audio/mpeg"),o=this.normalizeMessage(t,r);o.attachments=n?[n]:void 0,this.emit("message",o)}),this.bot.on("message:video",async e=>{let t=e.message,r=(t.caption??"")||"[Video]",n=await this.downloadAttachment(t.video.file_id,"video",t.video.mime_type??"video/mp4"),o=this.normalizeMessage(t,r);o.attachments=n?[n]:void 0,this.emit("message",o)}),this.bot.on("message:document",async e=>{let t=e.message,s=t.document,n=(t.caption??"")||`[Document: ${s.file_name??"file"}]`,o=await this.downloadAttachment(s.file_id,"document",s.mime_type??"application/octet-stream",s.file_name),i=this.normalizeMessage(t,n);i.attachments=o?[o]:void 0,this.emit("message",i)}),this.bot.on("message:video_note",async e=>{let t=e.message,s=await this.downloadAttachment(t.video_note.file_id,"video","video/mp4"),r=this.normalizeMessage(t,"[Video note]");r.attachments=s?[s]:void 0,this.emit("message",r)}),this.bot.on("message:sticker",e=>{let t=e.message,s=t.sticker.emoji??"\u{1F3F7}\uFE0F";this.emit("message",this.normalizeMessage(t,`[Sticker: ${s}]`))}),this.bot.catch(e=>{this.emit("error",e.error)}),this.bot.start({onStart:d(()=>{this.status="connected",this.emit("connected")},"onStart")})}async disconnect(){await this.bot.stop(),this.status="disconnected",this.emit("disconnected")}async sendMessage(e,t,s){let r=await this.bot.api.sendMessage(Number(e),t,{reply_to_message_id:s?.replyToMessageId?Number(s.replyToMessageId):void 0,parse_mode:eo(s?.parseMode)});return String(r.message_id)}async editMessage(e,t,s,r){await this.bot.api.editMessageText(Number(e),Number(t),s,{parse_mode:eo(r?.parseMode)})}async deleteMessage(e,t){await this.bot.api.deleteMessage(Number(e),Number(t))}async sendPhoto(e,t,s){let r=await this.bot.api.sendPhoto(Number(e),new Qn(t,"image.png"),{caption:s});return String(r.message_id)}async sendFile(e,t,s,r){let n=await this.bot.api.sendDocument(Number(e),new Qn(t,s),{caption:r});return String(n.message_id)}normalizeMessage(e,t){return{id:String(e.message_id),platform:"telegram",chatId:String(e.chat.id),chatType:e.chat.type==="private"?"dm":"group",userId:String(e.from.id),userName:e.from.username??String(e.from.id),displayName:[e.from.first_name,e.from.last_name].filter(Boolean).join(" "),text:t,timestamp:new Date(e.date*1e3),replyToMessageId:e.reply_to_message?String(e.reply_to_message.message_id):void 0}}async downloadAttachment(e,t,s,r){try{let o=(await this.bot.api.getFile(e)).file_path;if(!o)return;let i=`https://api.telegram.org/file/bot${this.bot.token}/${o}`,a=await fetch(i);if(!a.ok)return;let l=Buffer.from(await a.arrayBuffer());return{type:t,mimeType:s,fileName:r??o.split("/").pop(),size:l.length,data:l}}catch(n){console.error("[telegram] Failed to download file",e,n);return}}}});import{Client as Zi,GatewayIntentBits as cs,Events as gr}from"discord.js";var ls,so=f(()=>{"use strict";oe();ls=class extends B{static{d(this,"DiscordAdapter")}platform="discord";client=null;token;constructor(e){super(),this.token=e}async connect(){this.status="connecting",this.client=new Zi({intents:[cs.Guilds,cs.GuildMessages,cs.MessageContent,cs.DirectMessages]}),this.client.on(gr.MessageCreate,async e=>{if(!e.author.bot)try{let t=await this.downloadAttachments(e),s=e.content||this.inferTextFromAttachments(t),r={id:e.id,platform:"discord",chatId:e.channelId,chatType:e.channel.isDMBased()?"dm":"group",userId:e.author.id,userName:e.author.username,displayName:e.author.displayName,text:s,timestamp:e.createdAt,replyToMessageId:e.reference?.messageId??void 0,attachments:t.length>0?t:void 0};this.emit("message",r)}catch(t){this.emit("error",t instanceof Error?t:new Error(String(t)))}}),this.client.on(gr.ClientReady,()=>{this.status="connected",this.emit("connected")}),this.client.on(gr.Error,e=>{this.emit("error",e)}),await this.client.login(this.token)}async disconnect(){this.client?.destroy(),this.client=null,this.status="disconnected",this.emit("disconnected")}async sendMessage(e,t,s){if(!this.client)throw new Error("Client is not connected");let r=await this.client.channels.fetch(e);if(!r?.isTextBased()||!("send"in r))throw new Error(`Channel ${e} is not a text channel`);return s?.replyToMessageId?(await(await r.messages.fetch(s.replyToMessageId)).reply(t)).id:(await r.send(t)).id}async editMessage(e,t,s,r){if(!this.client)throw new Error("Client is not connected");let n=await this.client.channels.fetch(e);if(!n?.isTextBased()||!("messages"in n))throw new Error(`Channel ${e} is not a text channel`);await(await n.messages.fetch(t)).edit(s)}async deleteMessage(e,t){if(!this.client)throw new Error("Client is not connected");let s=await this.client.channels.fetch(e);if(!s?.isTextBased()||!("messages"in s))throw new Error(`Channel ${e} is not a text channel`);await(await s.messages.fetch(t)).delete()}async sendPhoto(e,t,s){if(!this.client)return;let r=await this.client.channels.fetch(e);return!r?.isTextBased()||!("send"in r)?void 0:(await r.send({content:s,files:[{attachment:t,name:"image.png"}]})).id}async sendFile(e,t,s,r){if(!this.client)return;let n=await this.client.channels.fetch(e);return!n?.isTextBased()||!("send"in n)?void 0:(await n.send({content:r,files:[{attachment:t,name:s}]})).id}async downloadAttachments(e){let t=[],s=e.attachments;if(!s||s.size===0)return t;for(let[,r]of s)try{let n=await fetch(r.url);if(!n.ok)continue;let o=await n.arrayBuffer(),i=Buffer.from(o),a=this.classifyContentType(r.contentType);t.push({type:a,url:r.url,mimeType:r.contentType??void 0,fileName:r.name??void 0,size:r.size??i.length,data:i})}catch(n){console.error("[discord] Failed to download attachment",r.url,n)}return t}classifyContentType(e){return e?e.startsWith("image/")?"image":e.startsWith("audio/")?"audio":e.startsWith("video/")?"video":"document":"other"}inferTextFromAttachments(e){if(e.length===0)return"";let t=e.map(s=>s.type);return t.includes("image")?"[Photo]":t.includes("audio")?"[Voice message]":t.includes("video")?"[Video]":t.includes("document")?"[Document]":"[File]"}}});var ds,ro=f(()=>{"use strict";oe();ds=class extends B{static{d(this,"MatrixAdapter")}platform="matrix";client;homeserverUrl;accessToken;botUserId;constructor(e,t,s){super(),this.homeserverUrl=e.replace(/\/+$/,""),this.accessToken=t,this.botUserId=s}async connect(){this.status="connecting";let{MatrixClient:e,SimpleFsStorageProvider:t,AutojoinRoomsMixin:s}=await import("matrix-bot-sdk"),r=new t("./data/matrix-storage");this.client=new e(this.homeserverUrl,this.accessToken,r),s.setupOnClient(this.client),this.client.on("room.message",async(n,o)=>{if(o.sender===this.botUserId)return;let i=o.content?.msgtype;if(i)try{let a=await this.normalizeEvent(n,o,i);a&&this.emit("message",a)}catch(a){this.emit("error",a instanceof Error?a:new Error(String(a)))}}),await this.client.start(),this.status="connected",this.emit("connected")}async disconnect(){this.client.stop(),this.status="disconnected",this.emit("disconnected")}async sendMessage(e,t,s){return s?.parseMode==="html"?await this.client.sendEvent(e,"m.room.message",{msgtype:"m.text",body:t.replace(/<[^>]*>/g,""),format:"org.matrix.custom.html",formatted_body:t}):await this.client.sendText(e,t)}async editMessage(e,t,s,r){let n=r?.parseMode==="html",o={msgtype:"m.text",body:"* "+(n?s.replace(/<[^>]*>/g,""):s),"m.new_content":{msgtype:"m.text",body:n?s.replace(/<[^>]*>/g,""):s,...n?{format:"org.matrix.custom.html",formatted_body:s}:{}},"m.relates_to":{rel_type:"m.replace",event_id:t}};await this.client.sendEvent(e,"m.room.message",o)}async deleteMessage(e,t){await this.client.redactEvent(e,t)}async sendPhoto(e,t,s){let r=await this.client.uploadContent(t,"image/png","image.png"),n={msgtype:"m.image",body:s??"image.png",url:r,info:{mimetype:"image/png",size:t.length}};return await this.client.sendEvent(e,"m.room.message",n)}async sendFile(e,t,s,r){let n=this.guessMimeType(s),o=await this.client.uploadContent(t,n,s),i={msgtype:"m.file",body:r??s,filename:s,url:o,info:{mimetype:n,size:t.length}};return await this.client.sendEvent(e,"m.room.message",i)}async normalizeEvent(e,t,s){let r={id:t.event_id,platform:"matrix",chatId:e,chatType:"group",userId:t.sender,userName:t.sender.split(":")[0].slice(1),timestamp:new Date(t.origin_server_ts),replyToMessageId:t.content["m.relates_to"]?.["m.in_reply_to"]?.event_id};switch(s){case"m.text":return{...r,text:t.content.body};case"m.image":{let n=await this.downloadAttachment(t.content,"image");return{...r,text:t.content.body??"[Photo]",attachments:n?[n]:void 0}}case"m.audio":{let n=await this.downloadAttachment(t.content,"audio");return{...r,text:t.content.body??"[Voice message]",attachments:n?[n]:void 0}}case"m.video":{let n=await this.downloadAttachment(t.content,"video");return{...r,text:t.content.body??"[Video]",attachments:n?[n]:void 0}}case"m.file":{let n=await this.downloadAttachment(t.content,"document");return{...r,text:t.content.body??"[Document]",attachments:n?[n]:void 0}}default:return t.content.body?{...r,text:t.content.body}:void 0}}async downloadAttachment(e,t){let s=e.url;if(!s||!s.startsWith("mxc://"))return;let r=e.info??{},n=r.mimetype,o=r.size,i=e.filename??e.body??"file";try{let a=s.slice(6),l=`${this.homeserverUrl}/_matrix/media/v3/download/${a}`,u=await fetch(l,{headers:{Authorization:`Bearer ${this.accessToken}`}});if(!u.ok)return;let p=await u.arrayBuffer(),m=Buffer.from(p);return{type:t,mimeType:n,fileName:i,size:o??m.length,data:m}}catch(a){console.error("[matrix] Failed to download attachment",s,a);return}}guessMimeType(e){let t=e.split(".").pop()?.toLowerCase();return{pdf:"application/pdf",txt:"text/plain",json:"application/json",csv:"text/csv",png:"image/png",jpg:"image/jpeg",jpeg:"image/jpeg",gif:"image/gif",mp3:"audio/mpeg",ogg:"audio/ogg",mp4:"video/mp4",zip:"application/zip",doc:"application/msword",docx:"application/vnd.openxmlformats-officedocument.wordprocessingml.document",xlsx:"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"}[t??""]??"application/octet-stream"}}});var us,no=f(()=>{"use strict";oe();us=class extends B{static{d(this,"WhatsAppAdapter")}platform="whatsapp";socket;downloadMedia;dataPath;reconnectAttempts=0;reconnectTimer;constructor(e){super(),this.dataPath=e}async connect(){this.status="connecting";let e=await import("@whiskeysockets/baileys"),t=e.default??e,{makeWASocket:s,useMultiFileAuthState:r,DisconnectReason:n,downloadMediaMessage:o}=t;this.downloadMedia=o;let{state:i,saveCreds:a}=await r(this.dataPath);this.socket=s({auth:i,printQRInTerminal:!0}),this.socket.ev.on("creds.update",a),this.socket.ev.on("connection.update",l=>{if(l.connection==="open"&&(this.status="connected",this.reconnectAttempts=0,this.emit("connected")),l.connection==="close"){let p=l.lastDisconnect?.error?.output?.statusCode!==n.loggedOut;if(this.status="disconnected",this.emit("disconnected"),p){let m=Math.min(1e3*Math.pow(2,this.reconnectAttempts),6e4);this.reconnectAttempts++,this.reconnectTimer=setTimeout(()=>this.connect(),m)}}}),this.socket.ev.on("messages.upsert",({messages:l,type:u})=>{if(u==="notify")for(let p of l)p.message&&(p.key.fromMe||this.processMessage(p).catch(m=>{this.emit("error",m instanceof Error?m:new Error(String(m)))}))})}async disconnect(){this.reconnectTimer&&(clearTimeout(this.reconnectTimer),this.reconnectTimer=void 0),this.reconnectAttempts=0,this.socket?.end(void 0),this.socket=void 0,this.status="disconnected",this.emit("disconnected")}async sendMessage(e,t,s){return(await this.socket.sendMessage(e,{text:t},s?.replyToMessageId?{quoted:{key:{remoteJid:e,id:s.replyToMessageId},message:{}}}:void 0))?.key?.id??""}async editMessage(e,t,s,r){await this.socket.sendMessage(e,{text:s,edit:{remoteJid:e,id:t,fromMe:!0}})}async deleteMessage(e,t){await this.socket.sendMessage(e,{delete:{remoteJid:e,id:t,fromMe:!0}})}async sendPhoto(e,t,s){return(await this.socket.sendMessage(e,{image:t,caption:s}))?.key?.id}async sendFile(e,t,s,r){return(await this.socket.sendMessage(e,{document:t,fileName:s,caption:r,mimetype:this.guessMimeType(s)}))?.key?.id}async processMessage(e){let t=e.message,s=t.conversation??t.extendedTextMessage?.text??t.imageMessage?.caption??t.videoMessage?.caption??t.documentMessage?.caption??"",r=[],n=s;if(t.imageMessage){let i=await this.downloadMediaSafe(e);i&&r.push({type:"image",mimeType:t.imageMessage.mimetype??"image/jpeg",size:t.imageMessage.fileLength??i.length,data:i}),n||(n="[Photo]")}else if(t.audioMessage){let i=await this.downloadMediaSafe(e);i&&r.push({type:"audio",mimeType:t.audioMessage.mimetype??"audio/ogg",size:t.audioMessage.fileLength??i.length,data:i}),n||(n="[Voice message]")}else if(t.videoMessage){let i=await this.downloadMediaSafe(e);i&&r.push({type:"video",mimeType:t.videoMessage.mimetype??"video/mp4",size:t.videoMessage.fileLength??i.length,data:i}),n||(n="[Video]")}else if(t.documentMessage){let i=await this.downloadMediaSafe(e);i&&r.push({type:"document",mimeType:t.documentMessage.mimetype??"application/octet-stream",fileName:t.documentMessage.fileName??"document",size:t.documentMessage.fileLength??i.length,data:i}),n||(n="[Document]")}else if(t.stickerMessage&&!s)return;if(!n&&r.length===0)return;let o={id:e.key.id??"",platform:"whatsapp",chatId:e.key.remoteJid??"",chatType:e.key.remoteJid?.endsWith("@g.us")?"group":"dm",userId:e.key.participant??e.key.remoteJid??"",userName:e.pushName??e.key.participant??e.key.remoteJid??"",text:n,timestamp:new Date(e.messageTimestamp*1e3),replyToMessageId:t.extendedTextMessage?.contextInfo?.stanzaId??void 0,attachments:r.length>0?r:void 0};this.emit("message",o)}async downloadMediaSafe(e){try{if(!this.downloadMedia)return;let t=await this.downloadMedia(e,"buffer",{});return Buffer.isBuffer(t)?t:Buffer.from(t)}catch(t){console.error("[whatsapp] Failed to download media",t);return}}guessMimeType(e){let t=e.split(".").pop()?.toLowerCase();return{pdf:"application/pdf",txt:"text/plain",json:"application/json",csv:"text/csv",png:"image/png",jpg:"image/jpeg",jpeg:"image/jpeg",gif:"image/gif",mp3:"audio/mpeg",ogg:"audio/ogg",mp4:"video/mp4",zip:"application/zip",doc:"application/msword",docx:"application/vnd.openxmlformats-officedocument.wordprocessingml.document",xlsx:"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"}[t??""]??"application/octet-stream"}}});var ms,oo=f(()=>{"use strict";oe();ms=class extends B{static{d(this,"SignalAdapter")}apiUrl;phoneNumber;platform="signal";pollingInterval;constructor(e,t){super(),this.apiUrl=e,this.phoneNumber=t}async connect(){this.status="connecting";try{let e=await fetch(`${this.apiUrl}/v1/about`);if(!e.ok)throw new Error(`Signal API not reachable: ${e.status}`);this.pollingInterval=setInterval(()=>{this.pollMessages().catch(t=>{this.emit("error",t instanceof Error?t:new Error(String(t)))})},2e3),this.status="connected",this.emit("connected")}catch(e){this.status="error",this.emit("error",e instanceof Error?e:new Error(String(e)))}}async disconnect(){this.pollingInterval&&(clearInterval(this.pollingInterval),this.pollingInterval=void 0),this.status="disconnected",this.emit("disconnected")}async sendMessage(e,t,s){let r=e.startsWith("group."),n={message:t,number:this.phoneNumber};r?n.recipients=[e.replace("group.","")]:n.recipients=[e];let o=await fetch(`${this.apiUrl}/v2/send`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(n)});if(!o.ok)throw new Error(`Signal send failed: ${o.status} ${await o.text()}`);let i=await o.json();return String(i.timestamp??Date.now())}async editMessage(e,t,s,r){throw new Error("Signal does not support message editing")}async deleteMessage(e,t){let s={number:this.phoneNumber,recipients:[e],timestamp:Number(t)},r=await fetch(`${this.apiUrl}/v1/deleteMessage`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(s)});if(!r.ok)throw new Error(`Signal delete failed: ${r.status} ${await r.text()}`)}async pollMessages(){let e=await fetch(`${this.apiUrl}/v1/receive/${this.phoneNumber}`);if(!e.ok)return;let t=await e.json();for(let s of t){let r=s.envelope?.dataMessage;if(!r||!r.message&&(!r.attachments||r.attachments.length===0))continue;let n=s.envelope,o=r.groupInfo?.groupId?`group.${r.groupInfo.groupId}`:n.sourceNumber??n.source??"",i=[];if(r.attachments)for(let u of r.attachments){let p=await this.downloadAttachment(u);p&&i.push(p)}let a=r.message||this.inferTextFromAttachments(i)||"";if(!a&&i.length===0)continue;let l={id:String(r.timestamp??Date.now()),platform:"signal",chatId:o,chatType:r.groupInfo?"group":"dm",userId:n.sourceNumber??n.source??"",userName:n.sourceName??n.sourceNumber??n.source??"",displayName:n.sourceName,text:a,timestamp:new Date(r.timestamp??Date.now()),attachments:i.length>0?i:void 0};this.emit("message",l)}}async downloadAttachment(e){if(e.id)try{let t=await fetch(`${this.apiUrl}/v1/attachments/${e.id}`);if(!t.ok)return;let s=await t.arrayBuffer(),r=Buffer.from(s);return{type:this.classifyContentType(e.contentType),mimeType:e.contentType??void 0,fileName:e.filename??void 0,size:e.size??r.length,data:r}}catch(t){console.error("[signal] Failed to download attachment",e.id,t);return}}classifyContentType(e){return e?e.startsWith("image/")?"image":e.startsWith("audio/")?"audio":e.startsWith("video/")?"video":"document":"other"}inferTextFromAttachments(e){if(e.length===0)return"";let t=e.map(s=>s.type);return t.includes("image")?"[Photo]":t.includes("audio")?"[Voice message]":t.includes("video")?"[Video]":t.includes("document")?"[Document]":"[File]"}}});import yr from"node:readline";var ps,io=f(()=>{"use strict";oe();ps=class extends B{static{d(this,"CLIAdapter")}platform="cli";rl;messageCounter=0;async connect(){this.status="connecting",this.rl=yr.createInterface({input:process.stdin,output:process.stdout,prompt:"You: "}),console.log(`
476
+ Return ONLY a valid JSON array, no explanation:`,jt=class{static{d(this,"MemoryExtractor")}llm;memoryRepo;logger;embeddingService;minConfidence;constructor(e,t,s,r,n=.4){this.llm=e,this.memoryRepo=t,this.logger=s,this.embeddingService=r,this.minConfidence=n}async extract(e,t,s){try{let r=zi.replace("{USER_MESSAGE}",t).replace("{ASSISTANT_RESPONSE}",s),n=await this.llm.complete({messages:[{role:"user",content:r}],temperature:.1,tier:"fast",maxTokens:1024}),o=this.parseResponse(n.content);if(o.length===0)return 0;let i=0;for(let a of o)if(!(a.confidence<this.minConfidence))try{let l=this.memoryRepo.saveWithMetadata(e,a.key,a.value,a.category,a.type,a.confidence,"auto");this.embeddingService&&this.embeddingService.embedAndStore(e,`${a.key}: ${a.value}`,"memory",l.id).catch(u=>this.logger.debug({err:u},"Auto-embed failed")),i++,this.logger.info({key:a.key,type:a.type,confidence:a.confidence},"Auto-extracted memory saved")}catch(l){this.logger.warn({err:l,key:a.key},"Failed to save extracted memory")}return i}catch(r){return this.logger.error({err:r},"Memory extraction failed"),0}}parseResponse(e){try{let t=e.match(/\[[\s\S]*\]/);if(!t)return[];let s=JSON.parse(t[0]);return Array.isArray(s)?s.filter(r=>typeof r=="object"&&r!==null).map(r=>({key:String(r.key||""),value:String(r.value||""),type:this.validateType(String(r.type||"fact")),confidence:this.clampConfidence(Number(r.confidence)||.5),category:String(r.category||"general")})).filter(r=>r.key&&r.value):[]}catch{return this.logger.debug({content:e.slice(0,200)},"Failed to parse extraction response"),[]}}validateType(e){return Xi.includes(e)?e:"fact"}clampConfidence(e){return Math.max(0,Math.min(1,e))}}});var Bt,hr=f(()=>{"use strict";mr();pr();Bt=class{static{d(this,"ActiveLearningService")}extractor;logger;minMessageLength;maxExtractionsPerMinute;extractionTimestamps=new Map;constructor(e){this.logger=e.logger,this.minMessageLength=e.minMessageLength??15,this.maxExtractionsPerMinute=e.maxExtractionsPerMinute??5,this.extractor=new jt(e.llm,e.memoryRepo,this.logger,e.embeddingService,e.minConfidence??.4)}onMessageProcessed(e,t,s){if(!t||t.length<this.minMessageLength)return;let r=ur(t);if(r.level==="low"){this.logger.debug({signal:"low"},"Skipping extraction \u2014 low signal");return}if(!this.checkRateLimit(e)){this.logger.debug({userId:e},"Skipping extraction \u2014 rate limit reached");return}this.logger.info({signal:r.level,patterns:r.matchedPatterns},"High signal detected, triggering extraction"),this.extractor.extract(e,t,s).then(n=>{n>0&&this.logger.info({userId:e,extractedCount:n},"Auto-extraction complete")}).catch(n=>{this.logger.error({err:n},"Auto-extraction failed")})}checkRateLimit(e){let t=Date.now(),s=t-6e4,r=this.extractionTimestamps.get(e);r||(r=[],this.extractionTimestamps.set(e,r));let n=r.filter(o=>o>s);return this.extractionTimestamps.set(e,n),n.length>=this.maxExtractionsPerMinute?!1:(n.push(t),!0)}}});var qi,Ki,Vi,Gi,Wt,fr=f(()=>{"use strict";qi=Math.LN2,Ki=.3,Vi=.7,Gi=3,Wt=class{static{d(this,"MemoryRetriever")}memoryRepo;logger;embeddingService;constructor(e,t,s){this.memoryRepo=e,this.logger=t,this.embeddingService=s}async retrieve(e,t,s=15){try{let r=this.memoryRepo.keywordSearch(e,t,30),n=[],o=!1;if(this.embeddingService)try{n=await this.embeddingService.semanticSearch(e,t,30),o=n.length>0}catch(m){this.logger.debug({err:m},"Semantic search failed, falling back to keyword-only")}let i=new Map,a=r.length;for(let m=0;m<r.length;m++){let p=r[m],E=a>0?1-m/a:0,w=o?Ki:1,T=this.applyBoosts(E*w,p);i.set(p.id,{memory:{key:p.key,value:p.value,category:p.category,type:p.type,score:T},score:T}),this.memoryRepo.recordAccess(p.id)}if(o)for(let m of n){let p=m.score*Vi,E=i.get(m.key);if(E)E.score+=p,E.memory.score=E.score;else{let w=this.memoryRepo.recall(e,m.key),T=this.applyBoosts(p,w||void 0);i.set(m.key,{memory:{key:m.key,value:m.value,category:m.category,type:w?.type||"general",score:T},score:T}),w&&this.memoryRepo.recordAccess(w.id)}}let l=Array.from(i.values()).sort((m,p)=>p.score-m.score),u=new Map,h=[];for(let{memory:m}of l){let p=u.get(m.type)||0;if(!(p>=Gi)&&(u.set(m.type,p+1),h.push(m),h.length>=s))break}return this.logger.debug({keywordCount:r.length,semanticCount:n.length,resultCount:h.length,hasSemanticSearch:o},"Hybrid memory retrieval complete"),h}catch(r){return this.logger.error({err:r},"Memory retrieval failed"),this.memoryRepo.getRecentForPrompt(e,s).map(n=>({key:n.key,value:n.value,category:n.category,type:n.type,score:0}))}}applyBoosts(e,t){let s=e;if(t){s*=.5+.5*t.confidence;let r=new Date(t.updatedAt).getTime(),n=Date.now()-r,o=Math.exp(-qi*n/2592e6);s*=o}return s}}});import{EventEmitter as Yi}from"node:events";var B,oe=f(()=>{"use strict";B=class extends Yi{static{d(this,"MessagingAdapter")}status="disconnected";async sendPhoto(e,t,s){}async sendFile(e,t,s,r){}getStatus(){return this.status}}});import{Bot as Ji,InputFile as Qn}from"grammy";function eo(c){if(c==="markdown")return"MarkdownV2";if(c==="html")return"HTML"}var as,to=f(()=>{"use strict";oe();d(eo,"mapParseMode");as=class extends B{static{d(this,"TelegramAdapter")}platform="telegram";bot;constructor(e){super(),this.bot=new Ji(e)}async connect(){this.status="connecting",this.bot.on("message:text",e=>{this.emit("message",this.normalizeMessage(e.message,e.message.text))}),this.bot.on("message:photo",async e=>{let t=e.message,r=(t.caption??"")||"[Photo]",n=t.photo[t.photo.length-1],o=await this.downloadAttachment(n.file_id,"image","image/jpeg"),i=this.normalizeMessage(t,r);i.attachments=o?[o]:void 0,this.emit("message",i)}),this.bot.on("message:voice",async e=>{let t=e.message,s=await this.downloadAttachment(t.voice.file_id,"audio",t.voice.mime_type??"audio/ogg"),r=this.normalizeMessage(t,"[Voice message]");r.attachments=s?[s]:void 0,this.emit("message",r)}),this.bot.on("message:audio",async e=>{let t=e.message,r=(t.caption??"")||`[Audio: ${t.audio.file_name??"audio"}]`,n=await this.downloadAttachment(t.audio.file_id,"audio",t.audio.mime_type??"audio/mpeg"),o=this.normalizeMessage(t,r);o.attachments=n?[n]:void 0,this.emit("message",o)}),this.bot.on("message:video",async e=>{let t=e.message,r=(t.caption??"")||"[Video]",n=await this.downloadAttachment(t.video.file_id,"video",t.video.mime_type??"video/mp4"),o=this.normalizeMessage(t,r);o.attachments=n?[n]:void 0,this.emit("message",o)}),this.bot.on("message:document",async e=>{let t=e.message,s=t.document,n=(t.caption??"")||`[Document: ${s.file_name??"file"}]`,o=await this.downloadAttachment(s.file_id,"document",s.mime_type??"application/octet-stream",s.file_name),i=this.normalizeMessage(t,n);i.attachments=o?[o]:void 0,this.emit("message",i)}),this.bot.on("message:video_note",async e=>{let t=e.message,s=await this.downloadAttachment(t.video_note.file_id,"video","video/mp4"),r=this.normalizeMessage(t,"[Video note]");r.attachments=s?[s]:void 0,this.emit("message",r)}),this.bot.on("message:sticker",e=>{let t=e.message,s=t.sticker.emoji??"\u{1F3F7}\uFE0F";this.emit("message",this.normalizeMessage(t,`[Sticker: ${s}]`))}),this.bot.catch(e=>{this.emit("error",e.error)}),this.bot.start({onStart:d(()=>{this.status="connected",this.emit("connected")},"onStart")})}async disconnect(){await this.bot.stop(),this.status="disconnected",this.emit("disconnected")}async sendMessage(e,t,s){let r=await this.bot.api.sendMessage(Number(e),t,{reply_to_message_id:s?.replyToMessageId?Number(s.replyToMessageId):void 0,parse_mode:eo(s?.parseMode)});return String(r.message_id)}async editMessage(e,t,s,r){await this.bot.api.editMessageText(Number(e),Number(t),s,{parse_mode:eo(r?.parseMode)})}async deleteMessage(e,t){await this.bot.api.deleteMessage(Number(e),Number(t))}async sendPhoto(e,t,s){let r=await this.bot.api.sendPhoto(Number(e),new Qn(t,"image.png"),{caption:s});return String(r.message_id)}async sendFile(e,t,s,r){let n=await this.bot.api.sendDocument(Number(e),new Qn(t,s),{caption:r});return String(n.message_id)}normalizeMessage(e,t){return{id:String(e.message_id),platform:"telegram",chatId:String(e.chat.id),chatType:e.chat.type==="private"?"dm":"group",userId:String(e.from.id),userName:e.from.username??String(e.from.id),displayName:[e.from.first_name,e.from.last_name].filter(Boolean).join(" "),text:t,timestamp:new Date(e.date*1e3),replyToMessageId:e.reply_to_message?String(e.reply_to_message.message_id):void 0}}async downloadAttachment(e,t,s,r){try{let o=(await this.bot.api.getFile(e)).file_path;if(!o)return;let i=`https://api.telegram.org/file/bot${this.bot.token}/${o}`,a=await fetch(i);if(!a.ok)return;let l=Buffer.from(await a.arrayBuffer());return{type:t,mimeType:s,fileName:r??o.split("/").pop(),size:l.length,data:l}}catch(n){console.error("[telegram] Failed to download file",e,n);return}}}});import{Client as Zi,GatewayIntentBits as cs,Events as gr}from"discord.js";var ls,so=f(()=>{"use strict";oe();ls=class extends B{static{d(this,"DiscordAdapter")}platform="discord";client=null;token;constructor(e){super(),this.token=e}async connect(){this.status="connecting",this.client=new Zi({intents:[cs.Guilds,cs.GuildMessages,cs.MessageContent,cs.DirectMessages]}),this.client.on(gr.MessageCreate,async e=>{if(!e.author.bot)try{let t=await this.downloadAttachments(e),s=e.content||this.inferTextFromAttachments(t),r={id:e.id,platform:"discord",chatId:e.channelId,chatType:e.channel.isDMBased()?"dm":"group",userId:e.author.id,userName:e.author.username,displayName:e.author.displayName,text:s,timestamp:e.createdAt,replyToMessageId:e.reference?.messageId??void 0,attachments:t.length>0?t:void 0};this.emit("message",r)}catch(t){this.emit("error",t instanceof Error?t:new Error(String(t)))}}),this.client.on(gr.ClientReady,()=>{this.status="connected",this.emit("connected")}),this.client.on(gr.Error,e=>{this.emit("error",e)}),await this.client.login(this.token)}async disconnect(){this.client?.destroy(),this.client=null,this.status="disconnected",this.emit("disconnected")}async sendMessage(e,t,s){if(!this.client)throw new Error("Client is not connected");let r=await this.client.channels.fetch(e);if(!r?.isTextBased()||!("send"in r))throw new Error(`Channel ${e} is not a text channel`);return s?.replyToMessageId?(await(await r.messages.fetch(s.replyToMessageId)).reply(t)).id:(await r.send(t)).id}async editMessage(e,t,s,r){if(!this.client)throw new Error("Client is not connected");let n=await this.client.channels.fetch(e);if(!n?.isTextBased()||!("messages"in n))throw new Error(`Channel ${e} is not a text channel`);await(await n.messages.fetch(t)).edit(s)}async deleteMessage(e,t){if(!this.client)throw new Error("Client is not connected");let s=await this.client.channels.fetch(e);if(!s?.isTextBased()||!("messages"in s))throw new Error(`Channel ${e} is not a text channel`);await(await s.messages.fetch(t)).delete()}async sendPhoto(e,t,s){if(!this.client)return;let r=await this.client.channels.fetch(e);return!r?.isTextBased()||!("send"in r)?void 0:(await r.send({content:s,files:[{attachment:t,name:"image.png"}]})).id}async sendFile(e,t,s,r){if(!this.client)return;let n=await this.client.channels.fetch(e);return!n?.isTextBased()||!("send"in n)?void 0:(await n.send({content:r,files:[{attachment:t,name:s}]})).id}async downloadAttachments(e){let t=[],s=e.attachments;if(!s||s.size===0)return t;for(let[,r]of s)try{let n=await fetch(r.url);if(!n.ok)continue;let o=await n.arrayBuffer(),i=Buffer.from(o),a=this.classifyContentType(r.contentType);t.push({type:a,url:r.url,mimeType:r.contentType??void 0,fileName:r.name??void 0,size:r.size??i.length,data:i})}catch(n){console.error("[discord] Failed to download attachment",r.url,n)}return t}classifyContentType(e){return e?e.startsWith("image/")?"image":e.startsWith("audio/")?"audio":e.startsWith("video/")?"video":"document":"other"}inferTextFromAttachments(e){if(e.length===0)return"";let t=e.map(s=>s.type);return t.includes("image")?"[Photo]":t.includes("audio")?"[Voice message]":t.includes("video")?"[Video]":t.includes("document")?"[Document]":"[File]"}}});var ds,ro=f(()=>{"use strict";oe();ds=class extends B{static{d(this,"MatrixAdapter")}platform="matrix";client;homeserverUrl;accessToken;botUserId;constructor(e,t,s){super(),this.homeserverUrl=e.replace(/\/+$/,""),this.accessToken=t,this.botUserId=s}async connect(){this.status="connecting";let{MatrixClient:e,SimpleFsStorageProvider:t,AutojoinRoomsMixin:s}=await import("matrix-bot-sdk"),r=new t("./data/matrix-storage");this.client=new e(this.homeserverUrl,this.accessToken,r),s.setupOnClient(this.client),this.client.on("room.message",async(n,o)=>{if(o.sender===this.botUserId)return;let i=o.content?.msgtype;if(i)try{let a=await this.normalizeEvent(n,o,i);a&&this.emit("message",a)}catch(a){this.emit("error",a instanceof Error?a:new Error(String(a)))}}),await this.client.start(),this.status="connected",this.emit("connected")}async disconnect(){this.client.stop(),this.status="disconnected",this.emit("disconnected")}async sendMessage(e,t,s){return s?.parseMode==="html"?await this.client.sendEvent(e,"m.room.message",{msgtype:"m.text",body:t.replace(/<[^>]*>/g,""),format:"org.matrix.custom.html",formatted_body:t}):await this.client.sendText(e,t)}async editMessage(e,t,s,r){let n=r?.parseMode==="html",o={msgtype:"m.text",body:"* "+(n?s.replace(/<[^>]*>/g,""):s),"m.new_content":{msgtype:"m.text",body:n?s.replace(/<[^>]*>/g,""):s,...n?{format:"org.matrix.custom.html",formatted_body:s}:{}},"m.relates_to":{rel_type:"m.replace",event_id:t}};await this.client.sendEvent(e,"m.room.message",o)}async deleteMessage(e,t){await this.client.redactEvent(e,t)}async sendPhoto(e,t,s){let r=await this.client.uploadContent(t,"image/png","image.png"),n={msgtype:"m.image",body:s??"image.png",url:r,info:{mimetype:"image/png",size:t.length}};return await this.client.sendEvent(e,"m.room.message",n)}async sendFile(e,t,s,r){let n=this.guessMimeType(s),o=await this.client.uploadContent(t,n,s),i={msgtype:"m.file",body:r??s,filename:s,url:o,info:{mimetype:n,size:t.length}};return await this.client.sendEvent(e,"m.room.message",i)}async normalizeEvent(e,t,s){let r={id:t.event_id,platform:"matrix",chatId:e,chatType:"group",userId:t.sender,userName:t.sender.split(":")[0].slice(1),timestamp:new Date(t.origin_server_ts),replyToMessageId:t.content["m.relates_to"]?.["m.in_reply_to"]?.event_id};switch(s){case"m.text":return{...r,text:t.content.body};case"m.image":{let n=await this.downloadAttachment(t.content,"image");return{...r,text:t.content.body??"[Photo]",attachments:n?[n]:void 0}}case"m.audio":{let n=await this.downloadAttachment(t.content,"audio");return{...r,text:t.content.body??"[Voice message]",attachments:n?[n]:void 0}}case"m.video":{let n=await this.downloadAttachment(t.content,"video");return{...r,text:t.content.body??"[Video]",attachments:n?[n]:void 0}}case"m.file":{let n=await this.downloadAttachment(t.content,"document");return{...r,text:t.content.body??"[Document]",attachments:n?[n]:void 0}}default:return t.content.body?{...r,text:t.content.body}:void 0}}async downloadAttachment(e,t){let s=e.url;if(!s||!s.startsWith("mxc://"))return;let r=e.info??{},n=r.mimetype,o=r.size,i=e.filename??e.body??"file";try{let a=s.slice(6),l=`${this.homeserverUrl}/_matrix/media/v3/download/${a}`,u=await fetch(l,{headers:{Authorization:`Bearer ${this.accessToken}`}});if(!u.ok)return;let h=await u.arrayBuffer(),m=Buffer.from(h);return{type:t,mimeType:n,fileName:i,size:o??m.length,data:m}}catch(a){console.error("[matrix] Failed to download attachment",s,a);return}}guessMimeType(e){let t=e.split(".").pop()?.toLowerCase();return{pdf:"application/pdf",txt:"text/plain",json:"application/json",csv:"text/csv",png:"image/png",jpg:"image/jpeg",jpeg:"image/jpeg",gif:"image/gif",mp3:"audio/mpeg",ogg:"audio/ogg",mp4:"video/mp4",zip:"application/zip",doc:"application/msword",docx:"application/vnd.openxmlformats-officedocument.wordprocessingml.document",xlsx:"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"}[t??""]??"application/octet-stream"}}});var us,no=f(()=>{"use strict";oe();us=class extends B{static{d(this,"WhatsAppAdapter")}platform="whatsapp";socket;downloadMedia;dataPath;reconnectAttempts=0;reconnectTimer;constructor(e){super(),this.dataPath=e}async connect(){this.status="connecting";let e=await import("@whiskeysockets/baileys"),t=e.default??e,{makeWASocket:s,useMultiFileAuthState:r,DisconnectReason:n,downloadMediaMessage:o}=t;this.downloadMedia=o;let{state:i,saveCreds:a}=await r(this.dataPath);this.socket=s({auth:i,printQRInTerminal:!0}),this.socket.ev.on("creds.update",a),this.socket.ev.on("connection.update",l=>{if(l.connection==="open"&&(this.status="connected",this.reconnectAttempts=0,this.emit("connected")),l.connection==="close"){let h=l.lastDisconnect?.error?.output?.statusCode!==n.loggedOut;if(this.status="disconnected",this.emit("disconnected"),h){let m=Math.min(1e3*Math.pow(2,this.reconnectAttempts),6e4);this.reconnectAttempts++,this.reconnectTimer=setTimeout(()=>this.connect(),m)}}}),this.socket.ev.on("messages.upsert",({messages:l,type:u})=>{if(u==="notify")for(let h of l)h.message&&(h.key.fromMe||this.processMessage(h).catch(m=>{this.emit("error",m instanceof Error?m:new Error(String(m)))}))})}async disconnect(){this.reconnectTimer&&(clearTimeout(this.reconnectTimer),this.reconnectTimer=void 0),this.reconnectAttempts=0,this.socket?.end(void 0),this.socket=void 0,this.status="disconnected",this.emit("disconnected")}async sendMessage(e,t,s){return(await this.socket.sendMessage(e,{text:t},s?.replyToMessageId?{quoted:{key:{remoteJid:e,id:s.replyToMessageId},message:{}}}:void 0))?.key?.id??""}async editMessage(e,t,s,r){await this.socket.sendMessage(e,{text:s,edit:{remoteJid:e,id:t,fromMe:!0}})}async deleteMessage(e,t){await this.socket.sendMessage(e,{delete:{remoteJid:e,id:t,fromMe:!0}})}async sendPhoto(e,t,s){return(await this.socket.sendMessage(e,{image:t,caption:s}))?.key?.id}async sendFile(e,t,s,r){return(await this.socket.sendMessage(e,{document:t,fileName:s,caption:r,mimetype:this.guessMimeType(s)}))?.key?.id}async processMessage(e){let t=e.message,s=t.conversation??t.extendedTextMessage?.text??t.imageMessage?.caption??t.videoMessage?.caption??t.documentMessage?.caption??"",r=[],n=s;if(t.imageMessage){let i=await this.downloadMediaSafe(e);i&&r.push({type:"image",mimeType:t.imageMessage.mimetype??"image/jpeg",size:t.imageMessage.fileLength??i.length,data:i}),n||(n="[Photo]")}else if(t.audioMessage){let i=await this.downloadMediaSafe(e);i&&r.push({type:"audio",mimeType:t.audioMessage.mimetype??"audio/ogg",size:t.audioMessage.fileLength??i.length,data:i}),n||(n="[Voice message]")}else if(t.videoMessage){let i=await this.downloadMediaSafe(e);i&&r.push({type:"video",mimeType:t.videoMessage.mimetype??"video/mp4",size:t.videoMessage.fileLength??i.length,data:i}),n||(n="[Video]")}else if(t.documentMessage){let i=await this.downloadMediaSafe(e);i&&r.push({type:"document",mimeType:t.documentMessage.mimetype??"application/octet-stream",fileName:t.documentMessage.fileName??"document",size:t.documentMessage.fileLength??i.length,data:i}),n||(n="[Document]")}else if(t.stickerMessage&&!s)return;if(!n&&r.length===0)return;let o={id:e.key.id??"",platform:"whatsapp",chatId:e.key.remoteJid??"",chatType:e.key.remoteJid?.endsWith("@g.us")?"group":"dm",userId:e.key.participant??e.key.remoteJid??"",userName:e.pushName??e.key.participant??e.key.remoteJid??"",text:n,timestamp:new Date(e.messageTimestamp*1e3),replyToMessageId:t.extendedTextMessage?.contextInfo?.stanzaId??void 0,attachments:r.length>0?r:void 0};this.emit("message",o)}async downloadMediaSafe(e){try{if(!this.downloadMedia)return;let t=await this.downloadMedia(e,"buffer",{});return Buffer.isBuffer(t)?t:Buffer.from(t)}catch(t){console.error("[whatsapp] Failed to download media",t);return}}guessMimeType(e){let t=e.split(".").pop()?.toLowerCase();return{pdf:"application/pdf",txt:"text/plain",json:"application/json",csv:"text/csv",png:"image/png",jpg:"image/jpeg",jpeg:"image/jpeg",gif:"image/gif",mp3:"audio/mpeg",ogg:"audio/ogg",mp4:"video/mp4",zip:"application/zip",doc:"application/msword",docx:"application/vnd.openxmlformats-officedocument.wordprocessingml.document",xlsx:"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"}[t??""]??"application/octet-stream"}}});var ms,oo=f(()=>{"use strict";oe();ms=class extends B{static{d(this,"SignalAdapter")}apiUrl;phoneNumber;platform="signal";pollingInterval;constructor(e,t){super(),this.apiUrl=e,this.phoneNumber=t}async connect(){this.status="connecting";try{let e=await fetch(`${this.apiUrl}/v1/about`);if(!e.ok)throw new Error(`Signal API not reachable: ${e.status}`);this.pollingInterval=setInterval(()=>{this.pollMessages().catch(t=>{this.emit("error",t instanceof Error?t:new Error(String(t)))})},2e3),this.status="connected",this.emit("connected")}catch(e){this.status="error",this.emit("error",e instanceof Error?e:new Error(String(e)))}}async disconnect(){this.pollingInterval&&(clearInterval(this.pollingInterval),this.pollingInterval=void 0),this.status="disconnected",this.emit("disconnected")}async sendMessage(e,t,s){let r=e.startsWith("group."),n={message:t,number:this.phoneNumber};r?n.recipients=[e.replace("group.","")]:n.recipients=[e];let o=await fetch(`${this.apiUrl}/v2/send`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(n)});if(!o.ok)throw new Error(`Signal send failed: ${o.status} ${await o.text()}`);let i=await o.json();return String(i.timestamp??Date.now())}async editMessage(e,t,s,r){throw new Error("Signal does not support message editing")}async deleteMessage(e,t){let s={number:this.phoneNumber,recipients:[e],timestamp:Number(t)},r=await fetch(`${this.apiUrl}/v1/deleteMessage`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(s)});if(!r.ok)throw new Error(`Signal delete failed: ${r.status} ${await r.text()}`)}async pollMessages(){let e=await fetch(`${this.apiUrl}/v1/receive/${this.phoneNumber}`);if(!e.ok)return;let t=await e.json();for(let s of t){let r=s.envelope?.dataMessage;if(!r||!r.message&&(!r.attachments||r.attachments.length===0))continue;let n=s.envelope,o=r.groupInfo?.groupId?`group.${r.groupInfo.groupId}`:n.sourceNumber??n.source??"",i=[];if(r.attachments)for(let u of r.attachments){let h=await this.downloadAttachment(u);h&&i.push(h)}let a=r.message||this.inferTextFromAttachments(i)||"";if(!a&&i.length===0)continue;let l={id:String(r.timestamp??Date.now()),platform:"signal",chatId:o,chatType:r.groupInfo?"group":"dm",userId:n.sourceNumber??n.source??"",userName:n.sourceName??n.sourceNumber??n.source??"",displayName:n.sourceName,text:a,timestamp:new Date(r.timestamp??Date.now()),attachments:i.length>0?i:void 0};this.emit("message",l)}}async downloadAttachment(e){if(e.id)try{let t=await fetch(`${this.apiUrl}/v1/attachments/${e.id}`);if(!t.ok)return;let s=await t.arrayBuffer(),r=Buffer.from(s);return{type:this.classifyContentType(e.contentType),mimeType:e.contentType??void 0,fileName:e.filename??void 0,size:e.size??r.length,data:r}}catch(t){console.error("[signal] Failed to download attachment",e.id,t);return}}classifyContentType(e){return e?e.startsWith("image/")?"image":e.startsWith("audio/")?"audio":e.startsWith("video/")?"video":"document":"other"}inferTextFromAttachments(e){if(e.length===0)return"";let t=e.map(s=>s.type);return t.includes("image")?"[Photo]":t.includes("audio")?"[Voice message]":t.includes("video")?"[Video]":t.includes("document")?"[Document]":"[File]"}}});import yr from"node:readline";var ps,io=f(()=>{"use strict";oe();ps=class extends B{static{d(this,"CLIAdapter")}platform="cli";rl;messageCounter=0;async connect(){this.status="connecting",this.rl=yr.createInterface({input:process.stdin,output:process.stdout,prompt:"You: "}),console.log(`
477
477
  Alfred Chat \u2014 type your message and press Enter. Use /quit or /exit to leave.
478
478
  `),this.rl.on("line",e=>{let t=e.trim();if(!t){this.prompt();return}if(t==="/quit"||t==="/exit"){console.log(`
479
479
  Goodbye!
480
480
  `),this.emit("disconnected");return}this.messageCounter++;let s={id:`cli-${this.messageCounter}`,platform:"cli",chatId:"cli-chat",chatType:"dm",userId:"cli-user",userName:"cli-user",displayName:"You",text:t,timestamp:new Date};this.emit("message",s)}),this.rl.on("close",()=>{this.emit("disconnected")}),this.status="connected",this.emit("connected"),this.prompt()}async disconnect(){this.rl?.close(),this.rl=void 0,this.status="disconnected"}async sendMessage(e,t,s){let r=`cli-resp-${++this.messageCounter}`;return process.stdout.write(`
481
481
  Alfred: ${t}
482
- `),this.prompt(),r}async editMessage(e,t,s,r){yr.clearLine(process.stdout,0),yr.cursorTo(process.stdout,0),process.stdout.write(`Alfred: ${s}`)}async deleteMessage(e,t){}prompt(){this.rl?.prompt()}}});var Ee={};q(Ee,{CLIAdapter:()=>ps,DiscordAdapter:()=>ls,MatrixAdapter:()=>ds,MessagingAdapter:()=>B,SignalAdapter:()=>ms,TelegramAdapter:()=>as,WhatsAppAdapter:()=>us});var Te=f(()=>{"use strict";oe();to();so();ro();no();oo();io()});import hs from"node:fs";import fs from"node:path";import Qi from"js-yaml";var be,ao=f(()=>{"use strict";Ls();Ds();Hs();ts();At();tr();rr();nr();or();ir();ar();cr();lr();dr();hr();fr();be=class{static{d(this,"Alfred")}config;logger;database;pipeline;reminderScheduler;backgroundTaskRunner;proactiveScheduler;adapters=new Map;formatter=new Ot;mcpManager;calendarSkill;constructor(e){this.config=e,this.logger=nt("alfred",e.logger.level)}async initialize(){this.logger.info("Initializing Alfred..."),this.database=new de(this.config.storage.path);let e=this.database.getDb(),t=new ot(e),s=new it(e),r=new ue(e),n=new at(e),o=new ct(e),i=new lt(e),a=new dt(e),l=new ut(e),u=new mt(e),p=new pt(e);this.logger.info("Storage initialized");let m=new St,h=this.loadSecurityRules();m.loadRules(h);let E=new _t(m,r,this.logger.child({component:"security"}));this.logger.info({ruleCount:h.length},"Security engine initialized");let w=Ws(this.config.llm);await w.initialize(),this.logger.info({provider:this.config.llm.default.provider,model:this.config.llm.default.model},"LLM provider initialized");let T=new Ct(w,a,this.logger.child({component:"embeddings"})),I=this.config.activeLearning?.enabled!==!1,_,k;I&&(_=new Bt({llm:w,memoryRepo:n,logger:this.logger.child({component:"active-learning"}),embeddingService:T,minMessageLength:this.config.activeLearning?.minMessageLength,minConfidence:this.config.activeLearning?.minConfidence,maxExtractionsPerMinute:this.config.activeLearning?.maxExtractionsPerMinute}),k=new Wt(n,this.logger.child({component:"memory-retriever"}),T),this.logger.info("Active learning & memory retriever initialized"));let A=new $e(this.logger.child({component:"sandbox"})),x=new Ie;x.register(new Re),x.register(new Ae),x.register(new Le(this.config.search?{provider:this.config.search.provider,apiKey:this.config.search.apiKey,baseUrl:this.config.search.baseUrl}:void 0)),x.register(new Me(o)),x.register(new Ne(i)),x.register(new De),x.register(new Oe),x.register(new Ce(n,T)),x.register(new Ue(w,x,A,E)),x.register(new Pe(this.config.email?{imap:this.config.email.imap,smtp:this.config.email.smtp,auth:this.config.email.auth}:void 0)),x.register(new Fe),x.register(new je),x.register(new We),x.register(new He),x.register(new Xe),x.register(new ze(s)),x.register(new qe(s,l,this.adapters)),x.register(new Ke(u)),x.register(new Ve(p));let v=new ht(e),F=new Ut(v,T,this.logger.child({component:"documents"}));x.register(new Ye(v,F,T));let O;if(this.config.calendar)try{let D=await It(this.config.calendar);O=new fe(D),x.register(O),this.logger.info({provider:this.config.calendar.provider},"Calendar initialized")}catch(D){this.logger.warn({err:D},"Calendar initialization failed, continuing without calendar")}if(this.calendarSkill=O,this.config.mcp?.servers?.length){let{MCPManager:D}=await Promise.resolve().then(()=>(At(),is));this.mcpManager=new D(this.logger.child({component:"mcp"})),await this.mcpManager.initialize(this.config.mcp);for(let te of this.mcpManager.getSkills())x.register(te);this.logger.info({mcpSkills:this.mcpManager.getSkills().length},"MCP skills registered")}if(this.config.codeSandbox?.enabled){let{CodeExecutionSkill:D}=await Promise.resolve().then(()=>(At(),is));x.register(new D({allowedLanguages:this.config.codeSandbox.allowedLanguages,maxTimeoutMs:this.config.codeSandbox.maxTimeoutMs})),this.logger.info("Code sandbox enabled")}this.logger.info({skills:x.getAll().map(D=>D.metadata.name)},"Skills registered");let W;this.config.speech?.apiKey&&(W=new Dt(this.config.speech,this.logger.child({component:"speech"})),this.logger.info({provider:this.config.speech.provider},"Speech-to-text initialized"));let Qe=new Lt(t),Es=fs.resolve(fs.dirname(this.config.storage.path),"inbox");this.pipeline=new Mt({llm:w,conversationManager:Qe,users:s,logger:this.logger.child({component:"pipeline"}),skillRegistry:x,skillSandbox:A,securityManager:E,memoryRepo:n,speechTranscriber:W,inboxPath:Es,embeddingService:T,activeLearning:_,memoryRetriever:k}),this.reminderScheduler=new Nt(o,async(D,te,G)=>{let et=this.adapters.get(D);et?await et.sendMessage(te,G):this.logger.warn({platform:D,chatId:te},"No adapter for reminder platform")},this.logger.child({component:"reminders"})),this.backgroundTaskRunner=new Pt(x,A,u,this.adapters,this.logger.child({component:"background-tasks"})),this.proactiveScheduler=new Ft(p,x,A,w,this.adapters,this.logger.child({component:"proactive-scheduler"})),await this.initializeAdapters(),this.logger.info("Alfred initialized")}async initializeAdapters(){let{config:e}=this;if(e.telegram.enabled&&e.telegram.token){let{TelegramAdapter:t}=await Promise.resolve().then(()=>(Te(),Ee));this.adapters.set("telegram",new t(e.telegram.token)),this.logger.info("Telegram adapter registered")}if(e.discord?.enabled&&e.discord.token){let{DiscordAdapter:t}=await Promise.resolve().then(()=>(Te(),Ee));this.adapters.set("discord",new t(e.discord.token)),this.logger.info("Discord adapter registered")}if(e.whatsapp?.enabled){let{WhatsAppAdapter:t}=await Promise.resolve().then(()=>(Te(),Ee));this.adapters.set("whatsapp",new t(e.whatsapp.dataPath)),this.logger.info("WhatsApp adapter registered")}if(e.matrix?.enabled&&e.matrix.accessToken){let{MatrixAdapter:t}=await Promise.resolve().then(()=>(Te(),Ee));this.adapters.set("matrix",new t(e.matrix.homeserverUrl,e.matrix.accessToken,e.matrix.userId)),this.logger.info("Matrix adapter registered")}if(e.signal?.enabled&&e.signal.phoneNumber){let{SignalAdapter:t}=await Promise.resolve().then(()=>(Te(),Ee));this.adapters.set("signal",new t(e.signal.apiUrl,e.signal.phoneNumber)),this.logger.info("Signal adapter registered")}}async start(){this.logger.info("Starting Alfred...");for(let[e,t]of this.adapters)this.setupAdapterHandlers(e,t),await t.connect(),this.logger.info({platform:e},"Adapter connected");this.reminderScheduler?.start(),this.backgroundTaskRunner?.start(),this.proactiveScheduler?.start(),this.adapters.size===0&&this.logger.warn("No messaging adapters enabled. Configure at least one platform."),this.logger.info(`Alfred is running with ${this.adapters.size} adapter(s)`)}async startWithCLI(){this.adapters.clear();let{CLIAdapter:e}=await Promise.resolve().then(()=>(Te(),Ee)),t=new e;this.adapters.set("cli",t),this.setupAdapterHandlers("cli",t),t.on("disconnected",()=>{this.stop().then(()=>process.exit(0))}),await this.start()}async stop(){this.logger.info("Stopping Alfred..."),this.reminderScheduler?.stop(),this.backgroundTaskRunner?.stop(),this.proactiveScheduler?.stop(),this.mcpManager&&await this.mcpManager.shutdown();for(let[e,t]of this.adapters)try{await t.disconnect(),this.logger.info({platform:e},"Adapter disconnected")}catch(s){this.logger.error({platform:e,err:s},"Failed to disconnect adapter")}this.database.close(),this.logger.info("Alfred stopped")}setupAdapterHandlers(e,t){t.on("message",async s=>{try{let r,n="",o=d(async u=>{if(u!==n){n=u;try{r?await t.editMessage(s.chatId,r,u):r=await t.sendMessage(s.chatId,u)}catch(p){this.logger.debug({err:p,chatId:s.chatId},"Status message edit failed")}}},"onProgress"),i=await this.pipeline.process(s,o),a=this.formatter.format(i,s.platform),l=a.parseMode!=="text"?{parseMode:a.parseMode}:void 0;if(r)try{await t.editMessage(s.chatId,r,a.text,l)}catch(u){this.logger.debug({err:u,chatId:s.chatId},"Final response edit failed, sending as new message"),await t.sendMessage(s.chatId,a.text,l)}else await t.sendMessage(s.chatId,a.text,l)}catch(r){this.logger.error({platform:e,err:r,chatId:s.chatId},"Failed to handle message");try{await t.sendMessage(s.chatId,"Sorry, I encountered an error processing your message. Please try again.")}catch(n){this.logger.error({err:n},"Failed to send error message")}}}),t.on("error",s=>{this.logger.error({platform:e,err:s},"Adapter error")}),t.on("connected",()=>{this.logger.info({platform:e},"Adapter connected")}),t.on("disconnected",()=>{this.logger.warn({platform:e},"Adapter disconnected")})}loadSecurityRules(){let e=fs.resolve(this.config.security.rulesPath),t=[];if(!hs.existsSync(e))return this.logger.warn({rulesPath:e},"Security rules directory not found, using default deny"),t;if(!hs.statSync(e).isDirectory())return this.logger.warn({rulesPath:e},"Security rules path is not a directory"),t;let r=hs.readdirSync(e).filter(n=>n.endsWith(".yml")||n.endsWith(".yaml"));for(let n of r)try{let o=fs.join(e,n),i=hs.readFileSync(o,"utf-8"),a=Qi.load(i);a?.rules&&Array.isArray(a.rules)&&(t.push(...a.rules),this.logger.info({file:n,count:a.rules.length},"Loaded security rules"))}catch(o){this.logger.error({err:o,file:n},"Failed to load security rules file")}return t}}});var co=f(()=>{"use strict"});var wr=f(()=>{"use strict";ao();rr();tr();nr();or();ir();ar();lr();dr();cr();hr();fr();pr();co();mr()});var lo={};q(lo,{startCommand:()=>ea});async function ea(){let c=new H,e;try{e=c.loadConfig()}catch(o){console.error("Failed to load configuration:",o.message),process.exit(1)}let t=nt("cli",e.logger.level);t.info({name:e.name},"Configuration loaded");let s=new be(e),r=!1,n=d(async o=>{if(!r){r=!0,t.info({signal:o},"Received shutdown signal");try{await s.stop(),t.info("Graceful shutdown complete"),process.exit(0)}catch(i){t.error({error:i},"Error during shutdown"),process.exit(1)}}},"shutdown");process.on("SIGINT",()=>n("SIGINT")),process.on("SIGTERM",()=>n("SIGTERM")),process.on("uncaughtException",o=>{t.fatal({error:o},"Uncaught exception"),n("uncaughtException")}),process.on("unhandledRejection",o=>{t.fatal({reason:o},"Unhandled rejection"),n("unhandledRejection")});try{await s.initialize(),await s.start(),t.info("Alfred is ready")}catch(o){t.fatal({error:o},"Failed to start Alfred"),process.exit(1)}}var uo=f(()=>{"use strict";le();Ls();wr();d(ea,"startCommand")});var mo={};q(mo,{chatCommand:()=>ta});async function ta(c){let e=new H,t;try{t=e.loadConfig()}catch(r){console.error("Failed to load configuration:",r.message),process.exit(1)}if(t.logger.level="warn",c.model&&(t.llm.default.model=c.model),c.tier){let r=t.llm[c.tier];r?t.llm.default=r:(console.error(`Unknown tier: ${c.tier}. Available tiers: default, strong, fast, embeddings, local`),process.exit(1))}let s=new be(t);try{await s.initialize(),await s.startWithCLI()}catch(r){console.error("Failed to start chat:",r.message),process.exit(1)}}var po=f(()=>{"use strict";le();wr();d(ta,"chatCommand")});var fo={};q(fo,{setupCommand:()=>la});import{createInterface as sa}from"node:readline/promises";import{stdin as ra,stdout as na}from"node:process";import X from"node:fs";import ee from"node:path";import Tr from"js-yaml";function C(c){return`${gs}${c}${L}`}function aa(c){return`${J}${c}${L}`}function Se(c){return`${ys}${c}${L}`}function ho(c){return`${oa}${c}${L}`}function $(c){return`${Ze}${c}${L}`}function S(c){return`${ae}${c}${L}`}function _e(c){return c.length<=4?"****":"*".repeat(c.length-4)+c.slice(-4)}function ca(c){let e={},t={},s=!1,r=!1,n=30,o=ee.join(c,"config","default.yml");if(X.existsSync(o))try{let l=Tr.load(X.readFileSync(o,"utf-8"));l&&typeof l=="object"&&Object.assign(e,l)}catch{}let i=ee.join(c,".env");if(X.existsSync(i))try{let l=X.readFileSync(i,"utf-8").split(`
483
- `);for(let u of l){let p=u.trim();if(!p||p.startsWith("#"))continue;let m=p.indexOf("=");m>0&&(t[p.slice(0,m)]=p.slice(m+1))}}catch{}let a=ee.join(c,"config","rules","default-rules.yml");if(X.existsSync(a))try{let l=Tr.load(X.readFileSync(a,"utf-8"));if(l?.rules){s=l.rules.some(m=>m.id==="allow-owner-admin"&&m.effect==="allow"),l.rules.find(m=>m.id==="allow-write-for-dm"||m.id==="allow-write-all")?.id==="allow-write-all"&&(r=!0);let p=l.rules.find(m=>m.id==="rate-limit-write");p?.rateLimit?.maxInvocations&&(n=p.rateLimit.maxInvocations)}}catch{}return{config:e,env:t,shellEnabled:s,writeInGroups:r,rateLimit:n}}async function la(){let c=sa({input:ra,output:na}),e=process.cwd(),t=ca(e),s=Object.keys(t.config).length>0;try{da(),console.log(s?`${ys}Existing configuration found \u2014 press Enter to keep current values.${L}
482
+ `),this.prompt(),r}async editMessage(e,t,s,r){yr.clearLine(process.stdout,0),yr.cursorTo(process.stdout,0),process.stdout.write(`Alfred: ${s}`)}async deleteMessage(e,t){}prompt(){this.rl?.prompt()}}});var Ee={};q(Ee,{CLIAdapter:()=>ps,DiscordAdapter:()=>ls,MatrixAdapter:()=>ds,MessagingAdapter:()=>B,SignalAdapter:()=>ms,TelegramAdapter:()=>as,WhatsAppAdapter:()=>us});var Te=f(()=>{"use strict";oe();to();so();ro();no();oo();io()});import hs from"node:fs";import fs from"node:path";import Qi from"js-yaml";var be,ao=f(()=>{"use strict";Ls();Ds();Hs();ts();At();tr();rr();nr();or();ir();ar();cr();lr();dr();hr();fr();be=class{static{d(this,"Alfred")}config;logger;database;pipeline;reminderScheduler;backgroundTaskRunner;proactiveScheduler;adapters=new Map;formatter=new Ot;mcpManager;calendarSkill;constructor(e){this.config=e,this.logger=nt("alfred",e.logger.level)}async initialize(){this.logger.info("Initializing Alfred..."),this.database=new de(this.config.storage.path);let e=this.database.getDb(),t=new ot(e),s=new it(e),r=new ue(e),n=new at(e),o=new ct(e),i=new lt(e),a=new dt(e),l=new ut(e),u=new mt(e),h=new pt(e);this.logger.info("Storage initialized");let m=new _t,p=this.loadSecurityRules();m.loadRules(p);let E=new St(m,r,this.logger.child({component:"security"}));this.logger.info({ruleCount:p.length},"Security engine initialized");let w=Ws(this.config.llm);await w.initialize(),this.logger.info({provider:this.config.llm.default.provider,model:this.config.llm.default.model},"LLM provider initialized");let T=new Ct(w,a,this.logger.child({component:"embeddings"})),x=this.config.activeLearning?.enabled!==!1,S,k;x&&(S=new Bt({llm:w,memoryRepo:n,logger:this.logger.child({component:"active-learning"}),embeddingService:T,minMessageLength:this.config.activeLearning?.minMessageLength,minConfidence:this.config.activeLearning?.minConfidence,maxExtractionsPerMinute:this.config.activeLearning?.maxExtractionsPerMinute}),k=new Wt(n,this.logger.child({component:"memory-retriever"}),T),this.logger.info("Active learning & memory retriever initialized"));let A=new $e(this.logger.child({component:"sandbox"})),I=new Ie;I.register(new Re),I.register(new Ae),I.register(new Le(this.config.search?{provider:this.config.search.provider,apiKey:this.config.search.apiKey,baseUrl:this.config.search.baseUrl}:void 0)),I.register(new Me(o)),I.register(new Ne(i)),I.register(new De),I.register(new Oe),I.register(new Ce(n,T)),I.register(new Ue(w,I,A,E)),I.register(new Pe(this.config.email?{imap:this.config.email.imap,smtp:this.config.email.smtp,auth:this.config.email.auth}:void 0)),I.register(new Fe),I.register(new je),I.register(new We),I.register(new He),I.register(new Xe),I.register(new ze(s)),I.register(new qe(s,l,this.adapters)),I.register(new Ke(u)),I.register(new Ve(h));let v=new ht(e),F=new Ut(v,T,this.logger.child({component:"documents"}));I.register(new Ye(v,F,T));let O;if(this.config.calendar)try{let D=await It(this.config.calendar);O=new fe(D),I.register(O),this.logger.info({provider:this.config.calendar.provider},"Calendar initialized")}catch(D){this.logger.warn({err:D},"Calendar initialization failed, continuing without calendar")}if(this.calendarSkill=O,this.config.mcp?.servers?.length){let{MCPManager:D}=await Promise.resolve().then(()=>(At(),is));this.mcpManager=new D(this.logger.child({component:"mcp"})),await this.mcpManager.initialize(this.config.mcp);for(let te of this.mcpManager.getSkills())I.register(te);this.logger.info({mcpSkills:this.mcpManager.getSkills().length},"MCP skills registered")}if(this.config.codeSandbox?.enabled){let{CodeExecutionSkill:D}=await Promise.resolve().then(()=>(At(),is));I.register(new D({allowedLanguages:this.config.codeSandbox.allowedLanguages,maxTimeoutMs:this.config.codeSandbox.maxTimeoutMs})),this.logger.info("Code sandbox enabled")}this.logger.info({skills:I.getAll().map(D=>D.metadata.name)},"Skills registered");let W;this.config.speech?.apiKey&&(W=new Dt(this.config.speech,this.logger.child({component:"speech"})),this.logger.info({provider:this.config.speech.provider},"Speech-to-text initialized"));let Qe=new Lt(t),Es=fs.resolve(fs.dirname(this.config.storage.path),"inbox");this.pipeline=new Mt({llm:w,conversationManager:Qe,users:s,logger:this.logger.child({component:"pipeline"}),skillRegistry:I,skillSandbox:A,securityManager:E,memoryRepo:n,speechTranscriber:W,inboxPath:Es,embeddingService:T,activeLearning:S,memoryRetriever:k}),this.reminderScheduler=new Nt(o,async(D,te,G)=>{let et=this.adapters.get(D);et?await et.sendMessage(te,G):this.logger.warn({platform:D,chatId:te},"No adapter for reminder platform")},this.logger.child({component:"reminders"})),this.backgroundTaskRunner=new Pt(I,A,u,this.adapters,this.logger.child({component:"background-tasks"})),this.proactiveScheduler=new Ft(h,I,A,w,this.adapters,this.logger.child({component:"proactive-scheduler"})),await this.initializeAdapters(),this.logger.info("Alfred initialized")}async initializeAdapters(){let{config:e}=this;if(e.telegram.enabled&&e.telegram.token){let{TelegramAdapter:t}=await Promise.resolve().then(()=>(Te(),Ee));this.adapters.set("telegram",new t(e.telegram.token)),this.logger.info("Telegram adapter registered")}if(e.discord?.enabled&&e.discord.token){let{DiscordAdapter:t}=await Promise.resolve().then(()=>(Te(),Ee));this.adapters.set("discord",new t(e.discord.token)),this.logger.info("Discord adapter registered")}if(e.whatsapp?.enabled){let{WhatsAppAdapter:t}=await Promise.resolve().then(()=>(Te(),Ee));this.adapters.set("whatsapp",new t(e.whatsapp.dataPath)),this.logger.info("WhatsApp adapter registered")}if(e.matrix?.enabled&&e.matrix.accessToken){let{MatrixAdapter:t}=await Promise.resolve().then(()=>(Te(),Ee));this.adapters.set("matrix",new t(e.matrix.homeserverUrl,e.matrix.accessToken,e.matrix.userId)),this.logger.info("Matrix adapter registered")}if(e.signal?.enabled&&e.signal.phoneNumber){let{SignalAdapter:t}=await Promise.resolve().then(()=>(Te(),Ee));this.adapters.set("signal",new t(e.signal.apiUrl,e.signal.phoneNumber)),this.logger.info("Signal adapter registered")}}async start(){this.logger.info("Starting Alfred...");for(let[e,t]of this.adapters)this.setupAdapterHandlers(e,t),await t.connect(),this.logger.info({platform:e},"Adapter connected");this.reminderScheduler?.start(),this.backgroundTaskRunner?.start(),this.proactiveScheduler?.start(),this.adapters.size===0&&this.logger.warn("No messaging adapters enabled. Configure at least one platform."),this.logger.info(`Alfred is running with ${this.adapters.size} adapter(s)`)}async startWithCLI(){this.adapters.clear();let{CLIAdapter:e}=await Promise.resolve().then(()=>(Te(),Ee)),t=new e;this.adapters.set("cli",t),this.setupAdapterHandlers("cli",t),t.on("disconnected",()=>{this.stop().then(()=>process.exit(0))}),await this.start()}async stop(){this.logger.info("Stopping Alfred..."),this.reminderScheduler?.stop(),this.backgroundTaskRunner?.stop(),this.proactiveScheduler?.stop(),this.mcpManager&&await this.mcpManager.shutdown();for(let[e,t]of this.adapters)try{await t.disconnect(),this.logger.info({platform:e},"Adapter disconnected")}catch(s){this.logger.error({platform:e,err:s},"Failed to disconnect adapter")}this.database.close(),this.logger.info("Alfred stopped")}setupAdapterHandlers(e,t){t.on("message",async s=>{try{let r,n="",o=d(async u=>{if(u!==n){n=u;try{r?await t.editMessage(s.chatId,r,u):r=await t.sendMessage(s.chatId,u)}catch(h){this.logger.debug({err:h,chatId:s.chatId},"Status message edit failed")}}},"onProgress"),i=await this.pipeline.process(s,o),a=this.formatter.format(i,s.platform),l=a.parseMode!=="text"?{parseMode:a.parseMode}:void 0;if(r)try{await t.editMessage(s.chatId,r,a.text,l)}catch(u){this.logger.debug({err:u,chatId:s.chatId},"Final response edit failed, sending as new message"),await t.sendMessage(s.chatId,a.text,l)}else await t.sendMessage(s.chatId,a.text,l)}catch(r){this.logger.error({platform:e,err:r,chatId:s.chatId},"Failed to handle message");try{await t.sendMessage(s.chatId,"Sorry, I encountered an error processing your message. Please try again.")}catch(n){this.logger.error({err:n},"Failed to send error message")}}}),t.on("error",s=>{this.logger.error({platform:e,err:s},"Adapter error")}),t.on("connected",()=>{this.logger.info({platform:e},"Adapter connected")}),t.on("disconnected",()=>{this.logger.warn({platform:e},"Adapter disconnected")})}loadSecurityRules(){let e=fs.resolve(this.config.security.rulesPath),t=[];if(!hs.existsSync(e))return this.logger.warn({rulesPath:e},"Security rules directory not found, using default deny"),t;if(!hs.statSync(e).isDirectory())return this.logger.warn({rulesPath:e},"Security rules path is not a directory"),t;let r=hs.readdirSync(e).filter(n=>n.endsWith(".yml")||n.endsWith(".yaml"));for(let n of r)try{let o=fs.join(e,n),i=hs.readFileSync(o,"utf-8"),a=Qi.load(i);a?.rules&&Array.isArray(a.rules)&&(t.push(...a.rules),this.logger.info({file:n,count:a.rules.length},"Loaded security rules"))}catch(o){this.logger.error({err:o,file:n},"Failed to load security rules file")}return t}}});var co=f(()=>{"use strict"});var wr=f(()=>{"use strict";ao();rr();tr();nr();or();ir();ar();lr();dr();cr();hr();fr();pr();co();mr()});var lo={};q(lo,{startCommand:()=>ea});async function ea(){let c=new H,e;try{e=c.loadConfig()}catch(o){console.error("Failed to load configuration:",o.message),process.exit(1)}let t=nt("cli",e.logger.level);t.info({name:e.name},"Configuration loaded");let s=new be(e),r=!1,n=d(async o=>{if(!r){r=!0,t.info({signal:o},"Received shutdown signal");try{await s.stop(),t.info("Graceful shutdown complete"),process.exit(0)}catch(i){t.error({error:i},"Error during shutdown"),process.exit(1)}}},"shutdown");process.on("SIGINT",()=>n("SIGINT")),process.on("SIGTERM",()=>n("SIGTERM")),process.on("uncaughtException",o=>{t.fatal({error:o},"Uncaught exception"),n("uncaughtException")}),process.on("unhandledRejection",o=>{t.fatal({reason:o},"Unhandled rejection"),n("unhandledRejection")});try{await s.initialize(),await s.start(),t.info("Alfred is ready")}catch(o){t.fatal({error:o},"Failed to start Alfred"),process.exit(1)}}var uo=f(()=>{"use strict";le();Ls();wr();d(ea,"startCommand")});var mo={};q(mo,{chatCommand:()=>ta});async function ta(c){let e=new H,t;try{t=e.loadConfig()}catch(r){console.error("Failed to load configuration:",r.message),process.exit(1)}if(t.logger.level="warn",c.model&&(t.llm.default.model=c.model),c.tier){let r=t.llm[c.tier];r?t.llm.default=r:(console.error(`Unknown tier: ${c.tier}. Available tiers: default, strong, fast, embeddings, local`),process.exit(1))}let s=new be(t);try{await s.initialize(),await s.startWithCLI()}catch(r){console.error("Failed to start chat:",r.message),process.exit(1)}}var po=f(()=>{"use strict";le();wr();d(ta,"chatCommand")});var fo={};q(fo,{setupCommand:()=>la});import{createInterface as sa}from"node:readline/promises";import{stdin as ra,stdout as na}from"node:process";import X from"node:fs";import ee from"node:path";import Tr from"js-yaml";function C(c){return`${gs}${c}${L}`}function aa(c){return`${J}${c}${L}`}function _e(c){return`${ys}${c}${L}`}function ho(c){return`${oa}${c}${L}`}function $(c){return`${Ze}${c}${L}`}function _(c){return`${ae}${c}${L}`}function Se(c){return c.length<=4?"****":"*".repeat(c.length-4)+c.slice(-4)}function ca(c){let e={},t={},s=!1,r=!1,n=30,o=ee.join(c,"config","default.yml");if(X.existsSync(o))try{let l=Tr.load(X.readFileSync(o,"utf-8"));l&&typeof l=="object"&&Object.assign(e,l)}catch{}let i=ee.join(c,".env");if(X.existsSync(i))try{let l=X.readFileSync(i,"utf-8").split(`
483
+ `);for(let u of l){let h=u.trim();if(!h||h.startsWith("#"))continue;let m=h.indexOf("=");m>0&&(t[h.slice(0,m)]=h.slice(m+1))}}catch{}let a=ee.join(c,"config","rules","default-rules.yml");if(X.existsSync(a))try{let l=Tr.load(X.readFileSync(a,"utf-8"));if(l?.rules){s=l.rules.some(m=>m.id==="allow-owner-admin"&&m.effect==="allow"),l.rules.find(m=>m.id==="allow-write-for-dm"||m.id==="allow-write-all")?.id==="allow-write-all"&&(r=!0);let h=l.rules.find(m=>m.id==="rate-limit-write");h?.rateLimit?.maxInvocations&&(n=h.rateLimit.maxInvocations)}}catch{}return{config:e,env:t,shellEnabled:s,writeInGroups:r,rateLimit:n}}async function la(){let c=sa({input:ra,output:na}),e=process.cwd(),t=ca(e),s=Object.keys(t.config).length>0;try{da(),console.log(s?`${ys}Existing configuration found \u2014 press Enter to keep current values.${L}
484
484
  ${ae}Only change what you need to update.${L}
485
485
  `:`${ys}Welcome to the Alfred setup wizard!${L}
486
486
  ${ae}This will walk you through configuring your AI assistant.${L}
487
487
  ${ae}Press Enter to accept defaults shown in [brackets].${L}
488
488
  `);let r=await P(c,"What should your bot be called?",t.config.name??"Alfred"),n=t.config.llm?.provider?Ht.findIndex(y=>y.name===t.config.llm?.provider):-1,o=n>=0?n+1:1;console.log(`
489
- ${$("Which LLM provider would you like to use?")}`);for(let y=0;y<Ht.length;y++){let R=y===n?` ${S("(current)")}`:"";console.log(` ${Se(String(y+1)+")")} ${Ht[y].label}${R}`)}let i=await Er(c,"> ",1,Ht.length,o),a=Ht[i-1];console.log(` ${C(">")} Selected: ${$(a.label)}`);let l="",u=t.env[a.envKeyName]??"";a.needsApiKey&&(console.log(""),u?l=await P(c,`${a.name.charAt(0).toUpperCase()+a.name.slice(1)} API key`,u):l=await ie(c,`Enter your ${a.name.charAt(0).toUpperCase()+a.name.slice(1)} API key`),console.log(` ${C(">")} API key set: ${S(_e(l))}`));let p=a.baseUrl??"";if(["ollama","openwebui","openai","openrouter"].includes(a.name)){let R=(t.config.llm?.baseUrl??t.env.ALFRED_LLM_BASE_URL??"")||a.baseUrl||"";if(R){let j={ollama:"Ollama URL (use a remote address if Ollama runs on another machine)",openwebui:"OpenWebUI URL",openai:"OpenAI-compatible API URL (leave default for official API)",openrouter:"OpenRouter API URL"};console.log(""),p=await P(c,j[a.name]??"API Base URL",R.replace(/\/+$/,"")),p=p.replace(/\/+$/,""),console.log(` ${C(">")} URL: ${S(p)}`)}}let h=t.config.llm?.model??a.defaultModel;console.log("");let E=await P(c,"Which model?",h),w=["brave","tavily","duckduckgo","searxng"],T=t.config.search?.provider??t.env.ALFRED_SEARCH_PROVIDER??"",I=w.indexOf(T),_=I>=0?I+1:0;console.log(`
490
- ${$("Web Search provider (for searching the internet):")}`);let k=["Brave Search \u2014 recommended, free tier (2,000/month)","Tavily \u2014 built for AI agents, free tier (1,000/month)","DuckDuckGo \u2014 free, no API key needed","SearXNG \u2014 self-hosted, no API key needed"],A=d(y=>I===y?` ${S("(current)")}`:"","mark");console.log(` ${Se("0)")} None (disable web search)${I===-1&&T===""?` ${S("(current)")}`:""}`);for(let y=0;y<k.length;y++)console.log(` ${Se(String(y+1)+")")} ${k[y]}${A(y)}`);let x=await Er(c,"> ",0,w.length,_),v,F="",O="";if(x>=1&&x<=w.length&&(v=w[x-1]),v==="brave"){let y=t.env.ALFRED_SEARCH_API_KEY??"";y?F=await P(c," Brave Search API key",y):(console.log(` ${S("Get your free API key at: https://brave.com/search/api/")}`),F=await ie(c," Brave Search API key")),console.log(` ${C(">")} Brave Search: ${S(_e(F))}`)}else if(v==="tavily"){let y=t.env.ALFRED_SEARCH_API_KEY??"";y?F=await P(c," Tavily API key",y):(console.log(` ${S("Get your free API key at: https://tavily.com/")}`),F=await ie(c," Tavily API key")),console.log(` ${C(">")} Tavily: ${S(_e(F))}`)}else if(v==="duckduckgo")console.log(` ${C(">")} DuckDuckGo: ${S("no API key needed")}`);else if(v==="searxng"){let y=t.config.search?.baseUrl??t.env.ALFRED_SEARCH_BASE_URL??"http://localhost:8080";O=await P(c," SearXNG URL",y),O=O.replace(/\/+$/,""),console.log(` ${C(">")} SearXNG: ${S(O)}`)}else console.log(` ${S("Web search disabled \u2014 you can configure it later.")}`);let W=[];for(let y=0;y<Je.length;y++){let R=Je[y];t.config[R.configKey]?.enabled&&W.push(y+1)}let Qe=W.length>0?W.join(","):"";console.log(`
491
- ${$("Which messaging platforms do you want to enable?")}`),console.log(`${S("(Enter comma-separated numbers, e.g. 1,3)")}`);for(let y=0;y<Je.length;y++){let R=W.includes(y+1)?` ${S("(enabled)")}`:"";console.log(` ${Se(String(y+1)+")")} ${Je[y].label}${R}`)}console.log(` ${Se("0)")} None (configure later)`);let Es=(await c.question(`${J}> ${L}${Qe?S(`[${Qe}] `):""}`)).trim(),D=[],te=Es||Qe;if(te&&te!=="0"){let y=te.split(",").map(R=>parseInt(R.trim(),10));for(let R of y)if(R>=1&&R<=Je.length){let j=Je[R-1];D.includes(j)||D.push(j)}}D.length>0?console.log(` ${C(">")} Enabling: ${D.map(y=>$(y.label)).join(", ")}`):console.log(` ${S("No platforms selected \u2014 you can configure them later.")}`);let G={},et={};for(let y of D){if(y.credentials.length===0){y.name==="whatsapp"&&console.log(`
489
+ ${$("Which LLM provider would you like to use?")}`);for(let y=0;y<Ht.length;y++){let R=y===n?` ${_("(current)")}`:"";console.log(` ${_e(String(y+1)+")")} ${Ht[y].label}${R}`)}let i=await Er(c,"> ",1,Ht.length,o),a=Ht[i-1];console.log(` ${C(">")} Selected: ${$(a.label)}`);let l="",u=t.env[a.envKeyName]??"";a.needsApiKey&&(console.log(""),u?l=await P(c,`${a.name.charAt(0).toUpperCase()+a.name.slice(1)} API key`,u):l=await ie(c,`Enter your ${a.name.charAt(0).toUpperCase()+a.name.slice(1)} API key`),console.log(` ${C(">")} API key set: ${_(Se(l))}`));let h=a.baseUrl??"";if(["ollama","openwebui","openai","openrouter"].includes(a.name)){let R=(t.config.llm?.baseUrl??t.env.ALFRED_LLM_BASE_URL??"")||a.baseUrl||"";if(R){let j={ollama:"Ollama URL (use a remote address if Ollama runs on another machine)",openwebui:"OpenWebUI URL",openai:"OpenAI-compatible API URL (leave default for official API)",openrouter:"OpenRouter API URL"};console.log(""),h=await P(c,j[a.name]??"API Base URL",R.replace(/\/+$/,"")),h=h.replace(/\/+$/,""),console.log(` ${C(">")} URL: ${_(h)}`)}}let p=t.config.llm?.model??a.defaultModel;console.log("");let E=await P(c,"Which model?",p),w=["brave","tavily","duckduckgo","searxng"],T=t.config.search?.provider??t.env.ALFRED_SEARCH_PROVIDER??"",x=w.indexOf(T),S=x>=0?x+1:0;console.log(`
490
+ ${$("Web Search provider (for searching the internet):")}`);let k=["Brave Search \u2014 recommended, free tier (2,000/month)","Tavily \u2014 built for AI agents, free tier (1,000/month)","DuckDuckGo \u2014 free, no API key needed","SearXNG \u2014 self-hosted, no API key needed"],A=d(y=>x===y?` ${_("(current)")}`:"","mark");console.log(` ${_e("0)")} None (disable web search)${x===-1&&T===""?` ${_("(current)")}`:""}`);for(let y=0;y<k.length;y++)console.log(` ${_e(String(y+1)+")")} ${k[y]}${A(y)}`);let I=await Er(c,"> ",0,w.length,S),v,F="",O="";if(I>=1&&I<=w.length&&(v=w[I-1]),v==="brave"){let y=t.env.ALFRED_SEARCH_API_KEY??"";y?F=await P(c," Brave Search API key",y):(console.log(` ${_("Get your free API key at: https://brave.com/search/api/")}`),F=await ie(c," Brave Search API key")),console.log(` ${C(">")} Brave Search: ${_(Se(F))}`)}else if(v==="tavily"){let y=t.env.ALFRED_SEARCH_API_KEY??"";y?F=await P(c," Tavily API key",y):(console.log(` ${_("Get your free API key at: https://tavily.com/")}`),F=await ie(c," Tavily API key")),console.log(` ${C(">")} Tavily: ${_(Se(F))}`)}else if(v==="duckduckgo")console.log(` ${C(">")} DuckDuckGo: ${_("no API key needed")}`);else if(v==="searxng"){let y=t.config.search?.baseUrl??t.env.ALFRED_SEARCH_BASE_URL??"http://localhost:8080";O=await P(c," SearXNG URL",y),O=O.replace(/\/+$/,""),console.log(` ${C(">")} SearXNG: ${_(O)}`)}else console.log(` ${_("Web search disabled \u2014 you can configure it later.")}`);let W=[];for(let y=0;y<Je.length;y++){let R=Je[y];t.config[R.configKey]?.enabled&&W.push(y+1)}let Qe=W.length>0?W.join(","):"";console.log(`
491
+ ${$("Which messaging platforms do you want to enable?")}`),console.log(`${_("(Enter comma-separated numbers, e.g. 1,3)")}`);for(let y=0;y<Je.length;y++){let R=W.includes(y+1)?` ${_("(enabled)")}`:"";console.log(` ${_e(String(y+1)+")")} ${Je[y].label}${R}`)}console.log(` ${_e("0)")} None (configure later)`);let Es=(await c.question(`${J}> ${L}${Qe?_(`[${Qe}] `):""}`)).trim(),D=[],te=Es||Qe;if(te&&te!=="0"){let y=te.split(",").map(R=>parseInt(R.trim(),10));for(let R of y)if(R>=1&&R<=Je.length){let j=Je[R-1];D.includes(j)||D.push(j)}}D.length>0?console.log(` ${C(">")} Enabling: ${D.map(y=>$(y.label)).join(", ")}`):console.log(` ${_("No platforms selected \u2014 you can configure them later.")}`);let G={},et={};for(let y of D){if(y.credentials.length===0){y.name==="whatsapp"&&console.log(`
492
492
  ${aa("i")} WhatsApp: a QR code will be displayed on first start.`);continue}console.log(`
493
- ${$(y.label+" configuration:")}`);let R={};for(let j of y.credentials){let ke=t.env[j.envKey]??"",Y;ke?Y=await P(c,` ${j.prompt}`,ke):j.defaultValue?Y=await P(c,` ${j.prompt}`,j.defaultValue):j.required?Y=await ie(c,` ${j.prompt}`):(Y=(await c.question(` ${j.prompt}: ${J}`)).trim(),process.stdout.write(L)),R[j.configField]=Y,et[j.envKey]=Y,j.configField==="token"||j.configField==="accessToken"?console.log(` ${C(">")} Set: ${S(_e(Y))}`):console.log(` ${C(">")} Set: ${S(Y)}`)}G[y.configKey]=R}let _r=t.config.email?.auth?.user??t.env.ALFRED_EMAIL_USER??"",kr=!!_r,$o=kr?"Y/n":"y/N";console.log(`
494
- ${$("Email access (read & send emails via IMAP/SMTP)?")}`),console.log(`${S("Works with Gmail, Outlook, or any IMAP/SMTP provider.")}`);let Ts=(await c.question(`${J}> ${L}${S(`[${$o}] `)}`)).trim().toLowerCase(),zt=Ts===""?kr:Ts==="y"||Ts==="yes",se="",qt="",Kt="",bs=993,vr="",Ss=587;if(zt){console.log(""),se=await P(c," Email address",_r||""),se||(se=await ie(c," Email address"));let y=t.env.ALFRED_EMAIL_PASS??"";y?qt=await P(c," Password / App password",y):(console.log(` ${S("For Gmail: use an App Password (not your regular password)")}`),console.log(` ${S(" \u2192 Google Account \u2192 Security \u2192 2-Step \u2192 App passwords")}`),qt=await ie(c," Password / App password"));let R=se.split("@")[1]?.toLowerCase()??"",ke={"gmail.com":{imap:"imap.gmail.com",smtp:"smtp.gmail.com"},"googlemail.com":{imap:"imap.gmail.com",smtp:"smtp.gmail.com"},"outlook.com":{imap:"outlook.office365.com",smtp:"smtp.office365.com"},"hotmail.com":{imap:"outlook.office365.com",smtp:"smtp.office365.com"},"live.com":{imap:"outlook.office365.com",smtp:"smtp.office365.com"},"yahoo.com":{imap:"imap.mail.yahoo.com",smtp:"smtp.mail.yahoo.com"},"icloud.com":{imap:"imap.mail.me.com",smtp:"smtp.mail.me.com"},"me.com":{imap:"imap.mail.me.com",smtp:"smtp.mail.me.com"},"gmx.de":{imap:"imap.gmx.net",smtp:"mail.gmx.net"},"gmx.net":{imap:"imap.gmx.net",smtp:"mail.gmx.net"},"web.de":{imap:"imap.web.de",smtp:"smtp.web.de"},"posteo.de":{imap:"posteo.de",smtp:"posteo.de"},"mailbox.org":{imap:"imap.mailbox.org",smtp:"smtp.mailbox.org"},"protonmail.com":{imap:"127.0.0.1",smtp:"127.0.0.1"},"proton.me":{imap:"127.0.0.1",smtp:"127.0.0.1"}}[R],Y=t.config.email?.imap?.host??ke?.imap??`imap.${R}`,jo=t.config.email?.smtp?.host??ke?.smtp??`smtp.${R}`,Bo=t.config.email?.imap?.port??993,Wo=t.config.email?.smtp?.port??587;ke&&console.log(` ${C(">")} Detected ${R} \u2014 using preset server settings`),Kt=await P(c," IMAP server",Y);let Ho=await P(c," IMAP port",String(Bo));bs=parseInt(Ho,10)||993,vr=await P(c," SMTP server",jo);let Xo=await P(c," SMTP port",String(Wo));Ss=parseInt(Xo,10)||587,console.log(` ${C(">")} Email: ${S(se)} via ${S(Kt)}`)}else console.log(` ${S("Email disabled \u2014 you can configure it later.")}`);let Vt=["openai","groq"],Ro=t.config.speech?.provider??t.env.ALFRED_SPEECH_PROVIDER??"",Gt=Vt.indexOf(Ro),Ao=Gt>=0?Gt+1:0;console.log(`
495
- ${$("Voice message transcription (Speech-to-Text via Whisper)?")}`),console.log(`${S("Transcribes voice messages from Telegram, Discord, etc.")}`);let xr=["OpenAI Whisper \u2014 best quality","Groq Whisper \u2014 fast & free"];console.log(` ${Se("0)")} None (disable voice transcription)${Gt===-1?` ${S("(current)")}`:""}`);for(let y=0;y<xr.length;y++){let R=Gt===y?` ${S("(current)")}`:"";console.log(` ${Se(String(y+1)+")")} ${xr[y]}${R}`)}let _s=await Er(c,"> ",0,Vt.length,Ao),Z,re="",tt="";if(_s>=1&&_s<=Vt.length&&(Z=Vt[_s-1]),Z==="openai"){let y=t.env.ALFRED_SPEECH_API_KEY??"";y?re=await P(c," OpenAI API key (for Whisper)",y):(console.log(` ${S("Uses your OpenAI API key for Whisper transcription.")}`),re=await ie(c," OpenAI API key")),console.log(` ${C(">")} OpenAI Whisper: ${S(_e(re))}`)}else if(Z==="groq"){let y=t.env.ALFRED_SPEECH_API_KEY??"";y?re=await P(c," Groq API key",y):(console.log(` ${S("Get your free API key at: https://console.groq.com/")}`),re=await ie(c," Groq API key"));let R=t.env.ALFRED_SPEECH_BASE_URL??"";R&&(tt=await P(c," Groq API URL",R)),console.log(` ${C(">")} Groq Whisper: ${S(_e(re))}`)}else console.log(` ${S("Voice transcription disabled \u2014 you can configure it later.")}`);console.log(`
496
- ${$("Security configuration:")}`);let Ir=t.config.security?.ownerUserId??t.env.ALFRED_OWNER_USER_ID??"",z;if(Ir)z=await P(c,"Owner user ID (for elevated permissions)",Ir);else{let y=(await c.question(`${Ze}Owner user ID${L} ${S("(optional, for elevated permissions)")}: ${J}`)).trim();process.stdout.write(L),z=y}let st=!1;if(z){let y=t.shellEnabled?"Y/n":"y/N";console.log(""),console.log(` ${$("Enable shell access (admin commands) for the owner?")}`),console.log(` ${S("Allows Alfred to execute shell commands. Only for the owner.")}`);let R=(await c.question(` ${J}> ${L}${S(`[${y}] `)}`)).trim().toLowerCase();R===""?st=t.shellEnabled:st=R==="y"||R==="yes",console.log(st?` ${C(">")} Shell access ${$("enabled")} for owner ${S(z)}`:` ${S("Shell access disabled.")}`)}let Lo=t.writeInGroups?"Y/n":"y/N";console.log(""),console.log(` ${$("Allow write actions (notes, reminders, memory) in group chats?")}`),console.log(` ${S("By default, write actions are only allowed in DMs.")}`);let ks=(await c.question(` ${J}> ${L}${S(`[${Lo}] `)}`)).trim().toLowerCase(),rt;ks===""?rt=t.writeInGroups:rt=ks==="y"||ks==="yes",console.log(rt?` ${C(">")} Write actions ${$("enabled")} in groups`:` ${S("Write actions only in DMs (default).")}`);let Mo=t.rateLimit??30;console.log("");let No=await P(c," Rate limit (max write actions per hour per user)",String(Mo)),Yt=Math.max(1,parseInt(No,10)||30);console.log(` ${C(">")} Rate limit: ${$(String(Yt))} per hour`),console.log(`
497
- ${$("Writing configuration files...")}`);let M=["# Alfred Environment Variables","# Generated by `alfred setup`","","# === LLM ===","",`ALFRED_LLM_PROVIDER=${a.name}`];if(l){let y=a.envKeyName||"ALFRED_OLLAMA_API_KEY";M.push(`${y}=${l}`)}E!==a.defaultModel&&M.push(`ALFRED_LLM_MODEL=${E}`),p&&M.push(`ALFRED_LLM_BASE_URL=${p}`),M.push("","# === Messaging Platforms ===","");for(let[y,R]of Object.entries(et))M.push(`${y}=${R}`);M.push("","# === Web Search ===",""),v?(M.push(`ALFRED_SEARCH_PROVIDER=${v}`),F&&M.push(`ALFRED_SEARCH_API_KEY=${F}`),O&&M.push(`ALFRED_SEARCH_BASE_URL=${O}`)):(M.push("# ALFRED_SEARCH_PROVIDER=brave"),M.push("# ALFRED_SEARCH_API_KEY=")),M.push("","# === Email ===",""),zt?(M.push(`ALFRED_EMAIL_USER=${se}`),M.push(`ALFRED_EMAIL_PASS=${qt}`)):(M.push("# ALFRED_EMAIL_USER="),M.push("# ALFRED_EMAIL_PASS=")),M.push("","# === Speech-to-Text ===",""),Z?(M.push(`ALFRED_SPEECH_PROVIDER=${Z}`),M.push(`ALFRED_SPEECH_API_KEY=${re}`),tt&&M.push(`ALFRED_SPEECH_BASE_URL=${tt}`)):(M.push("# ALFRED_SPEECH_PROVIDER=groq"),M.push("# ALFRED_SPEECH_API_KEY=")),M.push("","# === Security ===",""),z?M.push(`ALFRED_OWNER_USER_ID=${z}`):M.push("# ALFRED_OWNER_USER_ID="),M.push("");let Do=ee.join(e,".env");X.writeFileSync(Do,M.join(`
498
- `),"utf-8"),console.log(` ${C("+")} ${S(".env")} written`);let Jt=ee.join(e,"config");X.existsSync(Jt)||X.mkdirSync(Jt,{recursive:!0});let $r={name:r,telegram:{token:G.telegram?.token??"",enabled:D.some(y=>y.name==="telegram")},discord:{token:G.discord?.token??"",enabled:D.some(y=>y.name==="discord")},whatsapp:{enabled:D.some(y=>y.name==="whatsapp"),dataPath:"./data/whatsapp"},matrix:{homeserverUrl:G.matrix?.homeserverUrl??"https://matrix.org",accessToken:G.matrix?.accessToken??"",userId:G.matrix?.userId??"",enabled:D.some(y=>y.name==="matrix")},signal:{apiUrl:G.signal?.apiUrl??"http://localhost:8080",phoneNumber:G.signal?.phoneNumber??"",enabled:D.some(y=>y.name==="signal")},llm:{provider:a.name,model:E,...p?{baseUrl:p}:{},temperature:.7,maxTokens:4096},...v?{search:{provider:v,...F?{apiKey:F}:{},...O?{baseUrl:O}:{}}}:{},...zt?{email:{imap:{host:Kt,port:bs,secure:bs===993},smtp:{host:vr,port:Ss,secure:Ss===465},auth:{user:se,pass:qt}}}:{},...Z?{speech:{provider:Z,apiKey:re,...tt?{baseUrl:tt}:{}}}:{},storage:{path:"./data/alfred.db"},logger:{level:"info",pretty:!0,auditLogPath:"./data/audit.log"},security:{rulesPath:"./config/rules",defaultEffect:"deny"}};z&&($r.security.ownerUserId=z);let Oo="# Alfred \u2014 Configuration\n# Generated by `alfred setup`\n# Edit manually or re-run `alfred setup` to reconfigure.\n\n"+Tr.dump($r,{lineWidth:120,noRefs:!0,sortKeys:!1}),Co=ee.join(Jt,"default.yml");X.writeFileSync(Co,Oo,"utf-8"),console.log(` ${C("+")} ${S("config/default.yml")} written`);let vs=ee.join(Jt,"rules");X.existsSync(vs)||X.mkdirSync(vs,{recursive:!0});let Uo=st&&z?`
493
+ ${$(y.label+" configuration:")}`);let R={};for(let j of y.credentials){let ke=t.env[j.envKey]??"",Y;ke?Y=await P(c,` ${j.prompt}`,ke):j.defaultValue?Y=await P(c,` ${j.prompt}`,j.defaultValue):j.required?Y=await ie(c,` ${j.prompt}`):(Y=(await c.question(` ${j.prompt}: ${J}`)).trim(),process.stdout.write(L)),R[j.configField]=Y,et[j.envKey]=Y,j.configField==="token"||j.configField==="accessToken"?console.log(` ${C(">")} Set: ${_(Se(Y))}`):console.log(` ${C(">")} Set: ${_(Y)}`)}G[y.configKey]=R}let Sr=t.config.email?.auth?.user??t.env.ALFRED_EMAIL_USER??"",kr=!!Sr,$o=kr?"Y/n":"y/N";console.log(`
494
+ ${$("Email access (read & send emails via IMAP/SMTP)?")}`),console.log(`${_("Works with Gmail, Outlook, or any IMAP/SMTP provider.")}`);let Ts=(await c.question(`${J}> ${L}${_(`[${$o}] `)}`)).trim().toLowerCase(),zt=Ts===""?kr:Ts==="y"||Ts==="yes",se="",qt="",Kt="",bs=993,vr="",_s=587;if(zt){console.log(""),se=await P(c," Email address",Sr||""),se||(se=await ie(c," Email address"));let y=t.env.ALFRED_EMAIL_PASS??"";y?qt=await P(c," Password / App password",y):(console.log(` ${_("For Gmail: use an App Password (not your regular password)")}`),console.log(` ${_(" \u2192 Google Account \u2192 Security \u2192 2-Step \u2192 App passwords")}`),qt=await ie(c," Password / App password"));let R=se.split("@")[1]?.toLowerCase()??"",ke={"gmail.com":{imap:"imap.gmail.com",smtp:"smtp.gmail.com"},"googlemail.com":{imap:"imap.gmail.com",smtp:"smtp.gmail.com"},"outlook.com":{imap:"outlook.office365.com",smtp:"smtp.office365.com"},"hotmail.com":{imap:"outlook.office365.com",smtp:"smtp.office365.com"},"live.com":{imap:"outlook.office365.com",smtp:"smtp.office365.com"},"yahoo.com":{imap:"imap.mail.yahoo.com",smtp:"smtp.mail.yahoo.com"},"icloud.com":{imap:"imap.mail.me.com",smtp:"smtp.mail.me.com"},"me.com":{imap:"imap.mail.me.com",smtp:"smtp.mail.me.com"},"gmx.de":{imap:"imap.gmx.net",smtp:"mail.gmx.net"},"gmx.net":{imap:"imap.gmx.net",smtp:"mail.gmx.net"},"web.de":{imap:"imap.web.de",smtp:"smtp.web.de"},"posteo.de":{imap:"posteo.de",smtp:"posteo.de"},"mailbox.org":{imap:"imap.mailbox.org",smtp:"smtp.mailbox.org"},"protonmail.com":{imap:"127.0.0.1",smtp:"127.0.0.1"},"proton.me":{imap:"127.0.0.1",smtp:"127.0.0.1"}}[R],Y=t.config.email?.imap?.host??ke?.imap??`imap.${R}`,jo=t.config.email?.smtp?.host??ke?.smtp??`smtp.${R}`,Bo=t.config.email?.imap?.port??993,Wo=t.config.email?.smtp?.port??587;ke&&console.log(` ${C(">")} Detected ${R} \u2014 using preset server settings`),Kt=await P(c," IMAP server",Y);let Ho=await P(c," IMAP port",String(Bo));bs=parseInt(Ho,10)||993,vr=await P(c," SMTP server",jo);let Xo=await P(c," SMTP port",String(Wo));_s=parseInt(Xo,10)||587,console.log(` ${C(">")} Email: ${_(se)} via ${_(Kt)}`)}else console.log(` ${_("Email disabled \u2014 you can configure it later.")}`);let Vt=["openai","groq"],Ro=t.config.speech?.provider??t.env.ALFRED_SPEECH_PROVIDER??"",Gt=Vt.indexOf(Ro),Ao=Gt>=0?Gt+1:0;console.log(`
495
+ ${$("Voice message transcription (Speech-to-Text via Whisper)?")}`),console.log(`${_("Transcribes voice messages from Telegram, Discord, etc.")}`);let xr=["OpenAI Whisper \u2014 best quality","Groq Whisper \u2014 fast & free"];console.log(` ${_e("0)")} None (disable voice transcription)${Gt===-1?` ${_("(current)")}`:""}`);for(let y=0;y<xr.length;y++){let R=Gt===y?` ${_("(current)")}`:"";console.log(` ${_e(String(y+1)+")")} ${xr[y]}${R}`)}let Ss=await Er(c,"> ",0,Vt.length,Ao),Z,re="",tt="";if(Ss>=1&&Ss<=Vt.length&&(Z=Vt[Ss-1]),Z==="openai"){let y=t.env.ALFRED_SPEECH_API_KEY??"";y?re=await P(c," OpenAI API key (for Whisper)",y):(console.log(` ${_("Uses your OpenAI API key for Whisper transcription.")}`),re=await ie(c," OpenAI API key")),console.log(` ${C(">")} OpenAI Whisper: ${_(Se(re))}`)}else if(Z==="groq"){let y=t.env.ALFRED_SPEECH_API_KEY??"";y?re=await P(c," Groq API key",y):(console.log(` ${_("Get your free API key at: https://console.groq.com/")}`),re=await ie(c," Groq API key"));let R=t.env.ALFRED_SPEECH_BASE_URL??"";R&&(tt=await P(c," Groq API URL",R)),console.log(` ${C(">")} Groq Whisper: ${_(Se(re))}`)}else console.log(` ${_("Voice transcription disabled \u2014 you can configure it later.")}`);console.log(`
496
+ ${$("Security configuration:")}`);let Ir=t.config.security?.ownerUserId??t.env.ALFRED_OWNER_USER_ID??"",z;if(Ir)z=await P(c,"Owner user ID (for elevated permissions)",Ir);else{let y=(await c.question(`${Ze}Owner user ID${L} ${_("(optional, for elevated permissions)")}: ${J}`)).trim();process.stdout.write(L),z=y}let st=!1;if(z){let y=t.shellEnabled?"Y/n":"y/N";console.log(""),console.log(` ${$("Enable shell access (admin commands) for the owner?")}`),console.log(` ${_("Allows Alfred to execute shell commands. Only for the owner.")}`);let R=(await c.question(` ${J}> ${L}${_(`[${y}] `)}`)).trim().toLowerCase();R===""?st=t.shellEnabled:st=R==="y"||R==="yes",console.log(st?` ${C(">")} Shell access ${$("enabled")} for owner ${_(z)}`:` ${_("Shell access disabled.")}`)}let Lo=t.writeInGroups?"Y/n":"y/N";console.log(""),console.log(` ${$("Allow write actions (notes, reminders, memory) in group chats?")}`),console.log(` ${_("By default, write actions are only allowed in DMs.")}`);let ks=(await c.question(` ${J}> ${L}${_(`[${Lo}] `)}`)).trim().toLowerCase(),rt;ks===""?rt=t.writeInGroups:rt=ks==="y"||ks==="yes",console.log(rt?` ${C(">")} Write actions ${$("enabled")} in groups`:` ${_("Write actions only in DMs (default).")}`);let Mo=t.rateLimit??30;console.log("");let No=await P(c," Rate limit (max write actions per hour per user)",String(Mo)),Yt=Math.max(1,parseInt(No,10)||30);console.log(` ${C(">")} Rate limit: ${$(String(Yt))} per hour`),console.log(`
497
+ ${$("Writing configuration files...")}`);let M=["# Alfred Environment Variables","# Generated by `alfred setup`","","# === LLM ===","",`ALFRED_LLM_PROVIDER=${a.name}`];if(l){let y=a.envKeyName||"ALFRED_OLLAMA_API_KEY";M.push(`${y}=${l}`)}E!==a.defaultModel&&M.push(`ALFRED_LLM_MODEL=${E}`),h&&M.push(`ALFRED_LLM_BASE_URL=${h}`),M.push("","# === Messaging Platforms ===","");for(let[y,R]of Object.entries(et))M.push(`${y}=${R}`);M.push("","# === Web Search ===",""),v?(M.push(`ALFRED_SEARCH_PROVIDER=${v}`),F&&M.push(`ALFRED_SEARCH_API_KEY=${F}`),O&&M.push(`ALFRED_SEARCH_BASE_URL=${O}`)):(M.push("# ALFRED_SEARCH_PROVIDER=brave"),M.push("# ALFRED_SEARCH_API_KEY=")),M.push("","# === Email ===",""),zt?(M.push(`ALFRED_EMAIL_USER=${se}`),M.push(`ALFRED_EMAIL_PASS=${qt}`)):(M.push("# ALFRED_EMAIL_USER="),M.push("# ALFRED_EMAIL_PASS=")),M.push("","# === Speech-to-Text ===",""),Z?(M.push(`ALFRED_SPEECH_PROVIDER=${Z}`),M.push(`ALFRED_SPEECH_API_KEY=${re}`),tt&&M.push(`ALFRED_SPEECH_BASE_URL=${tt}`)):(M.push("# ALFRED_SPEECH_PROVIDER=groq"),M.push("# ALFRED_SPEECH_API_KEY=")),M.push("","# === Security ===",""),z?M.push(`ALFRED_OWNER_USER_ID=${z}`):M.push("# ALFRED_OWNER_USER_ID="),M.push("");let Do=ee.join(e,".env");X.writeFileSync(Do,M.join(`
498
+ `),"utf-8"),console.log(` ${C("+")} ${_(".env")} written`);let Jt=ee.join(e,"config");X.existsSync(Jt)||X.mkdirSync(Jt,{recursive:!0});let $r={name:r,telegram:{token:G.telegram?.token??"",enabled:D.some(y=>y.name==="telegram")},discord:{token:G.discord?.token??"",enabled:D.some(y=>y.name==="discord")},whatsapp:{enabled:D.some(y=>y.name==="whatsapp"),dataPath:"./data/whatsapp"},matrix:{homeserverUrl:G.matrix?.homeserverUrl??"https://matrix.org",accessToken:G.matrix?.accessToken??"",userId:G.matrix?.userId??"",enabled:D.some(y=>y.name==="matrix")},signal:{apiUrl:G.signal?.apiUrl??"http://localhost:8080",phoneNumber:G.signal?.phoneNumber??"",enabled:D.some(y=>y.name==="signal")},llm:{provider:a.name,model:E,...h?{baseUrl:h}:{},temperature:.7,maxTokens:4096},...v?{search:{provider:v,...F?{apiKey:F}:{},...O?{baseUrl:O}:{}}}:{},...zt?{email:{imap:{host:Kt,port:bs,secure:bs===993},smtp:{host:vr,port:_s,secure:_s===465},auth:{user:se,pass:qt}}}:{},...Z?{speech:{provider:Z,apiKey:re,...tt?{baseUrl:tt}:{}}}:{},storage:{path:"./data/alfred.db"},logger:{level:"info",pretty:!0,auditLogPath:"./data/audit.log"},security:{rulesPath:"./config/rules",defaultEffect:"deny"}};z&&($r.security.ownerUserId=z);let Oo="# Alfred \u2014 Configuration\n# Generated by `alfred setup`\n# Edit manually or re-run `alfred setup` to reconfigure.\n\n"+Tr.dump($r,{lineWidth:120,noRefs:!0,sortKeys:!1}),Co=ee.join(Jt,"default.yml");X.writeFileSync(Co,Oo,"utf-8"),console.log(` ${C("+")} ${_("config/default.yml")} written`);let vs=ee.join(Jt,"rules");X.existsSync(vs)||X.mkdirSync(vs,{recursive:!0});let Uo=st&&z?`
499
499
  # Allow admin actions (shell, etc.) for the owner only
500
500
  - id: allow-owner-admin
501
501
  effect: allow
@@ -571,14 +571,14 @@ ${Uo}
571
571
  scope: global
572
572
  actions: ["*"]
573
573
  riskLevels: [read, write, destructive, admin]
574
- `,Fo=ee.join(vs,"default-rules.yml");X.writeFileSync(Fo,Po,"utf-8"),console.log(` ${C("+")} ${S("config/rules/default-rules.yml")} written`);let Rr=ee.join(e,"data");if(X.existsSync(Rr)||(X.mkdirSync(Rr,{recursive:!0}),console.log(` ${C("+")} ${S("data/")} directory created`)),console.log(""),console.log(`${gs}${"=".repeat(52)}${L}`),console.log(`${gs}${Ze} Setup complete!${L}`),console.log(`${gs}${"=".repeat(52)}${L}`),console.log(""),console.log(` ${$("Bot name:")} ${r}`),console.log(` ${$("LLM provider:")} ${a.name} (${E})`),l&&console.log(` ${$("API key:")} ${_e(l)}`),D.length>0?console.log(` ${$("Platforms:")} ${D.map(y=>y.label).join(", ")}`):console.log(` ${$("Platforms:")} none (configure later)`),v){let y={brave:"Brave Search",tavily:"Tavily",duckduckgo:"DuckDuckGo",searxng:`SearXNG (${O})`};console.log(` ${$("Web search:")} ${y[v]}`)}else console.log(` ${$("Web search:")} ${S("disabled")}`);if(console.log(zt?` ${$("Email:")} ${se} (${Kt})`:` ${$("Email:")} ${S("disabled")}`),Z){let y={openai:"OpenAI Whisper",groq:"Groq Whisper"};console.log(` ${$("Voice:")} ${y[Z]}`)}else console.log(` ${$("Voice:")} ${S("disabled")}`);z&&(console.log(` ${$("Owner ID:")} ${z}`),console.log(` ${$("Shell access:")} ${st?C("enabled"):S("disabled")}`)),console.log(` ${$("Write scope:")} ${rt?"DMs + Groups":"DMs only"}`),console.log(` ${$("Rate limit:")} ${Yt}/hour per user`),console.log(""),console.log(`${ys}Next steps:${L}`),console.log(` ${$("alfred start")} Start Alfred`),console.log(` ${$("alfred status")} Check configuration`),console.log(` ${$("alfred --help")} Show all commands`),console.log(""),console.log(`${ae}Edit ${$(".env")}${ae} or ${$("config/default.yml")}${ae} for manual configuration.${L}`),console.log("")}finally{c.close()}}async function P(c,e,t){let s=(await c.question(`${Ze}${e}${L} ${S(`[${t}]`)}: ${J}`)).trim();return process.stdout.write(L),s||t}async function ie(c,e){for(;;){let t=(await c.question(`${Ze}${e}${L}: ${J}`)).trim();if(process.stdout.write(L),t)return t;console.log(` ${ho("!")} This field is required. Please enter a value.`)}}async function Er(c,e,t,s,r){for(;;){let n=(await c.question(`${J}${e}${L}`)).trim();if(!n)return r;let o=parseInt(n,10);if(!Number.isNaN(o)&&o>=t&&o<=s)return o;console.log(` ${ho("!")} Please enter a number between ${t} and ${s}.`)}}function da(){console.log(`
574
+ `,Fo=ee.join(vs,"default-rules.yml");X.writeFileSync(Fo,Po,"utf-8"),console.log(` ${C("+")} ${_("config/rules/default-rules.yml")} written`);let Rr=ee.join(e,"data");if(X.existsSync(Rr)||(X.mkdirSync(Rr,{recursive:!0}),console.log(` ${C("+")} ${_("data/")} directory created`)),console.log(""),console.log(`${gs}${"=".repeat(52)}${L}`),console.log(`${gs}${Ze} Setup complete!${L}`),console.log(`${gs}${"=".repeat(52)}${L}`),console.log(""),console.log(` ${$("Bot name:")} ${r}`),console.log(` ${$("LLM provider:")} ${a.name} (${E})`),l&&console.log(` ${$("API key:")} ${Se(l)}`),D.length>0?console.log(` ${$("Platforms:")} ${D.map(y=>y.label).join(", ")}`):console.log(` ${$("Platforms:")} none (configure later)`),v){let y={brave:"Brave Search",tavily:"Tavily",duckduckgo:"DuckDuckGo",searxng:`SearXNG (${O})`};console.log(` ${$("Web search:")} ${y[v]}`)}else console.log(` ${$("Web search:")} ${_("disabled")}`);if(console.log(zt?` ${$("Email:")} ${se} (${Kt})`:` ${$("Email:")} ${_("disabled")}`),Z){let y={openai:"OpenAI Whisper",groq:"Groq Whisper"};console.log(` ${$("Voice:")} ${y[Z]}`)}else console.log(` ${$("Voice:")} ${_("disabled")}`);z&&(console.log(` ${$("Owner ID:")} ${z}`),console.log(` ${$("Shell access:")} ${st?C("enabled"):_("disabled")}`)),console.log(` ${$("Write scope:")} ${rt?"DMs + Groups":"DMs only"}`),console.log(` ${$("Rate limit:")} ${Yt}/hour per user`),console.log(""),console.log(`${ys}Next steps:${L}`),console.log(` ${$("alfred start")} Start Alfred`),console.log(` ${$("alfred status")} Check configuration`),console.log(` ${$("alfred --help")} Show all commands`),console.log(""),console.log(`${ae}Edit ${$(".env")}${ae} or ${$("config/default.yml")}${ae} for manual configuration.${L}`),console.log("")}finally{c.close()}}async function P(c,e,t){let s=(await c.question(`${Ze}${e}${L} ${_(`[${t}]`)}: ${J}`)).trim();return process.stdout.write(L),s||t}async function ie(c,e){for(;;){let t=(await c.question(`${Ze}${e}${L}: ${J}`)).trim();if(process.stdout.write(L),t)return t;console.log(` ${ho("!")} This field is required. Please enter a value.`)}}async function Er(c,e,t,s,r){for(;;){let n=(await c.question(`${J}${e}${L}`)).trim();if(!n)return r;let o=parseInt(n,10);if(!Number.isNaN(o)&&o>=t&&o<=s)return o;console.log(` ${ho("!")} Please enter a number between ${t} and ${s}.`)}}function da(){console.log(`
575
575
  ${ia}${Ze} _ _ _____ ____ _____ ____
576
576
  / \\ | | | ___| _ \\| ____| _ \\
577
577
  / _ \\ | | | |_ | |_) | _| | | | |
578
578
  / ___ \\| |___| _| | _ <| |___| |_| |
579
579
  /_/ \\_\\_____|_| |_| \\_\\_____|____/ ${L}
580
580
  ${ae} Personal AI Assistant \u2014 Setup Wizard${L}
581
- `)}var L,Ze,ae,gs,J,ys,oa,ia,Ht,Je,go=f(()=>{"use strict";L="\x1B[0m",Ze="\x1B[1m",ae="\x1B[2m",gs="\x1B[32m",J="\x1B[33m",ys="\x1B[36m",oa="\x1B[31m",ia="\x1B[35m";d(C,"green");d(aa,"yellow");d(Se,"cyan");d(ho,"red");d($,"bold");d(S,"dim");d(_e,"maskKey");Ht=[{name:"anthropic",label:"Anthropic (Claude) \u2014 recommended",defaultModel:"claude-sonnet-4-20250514",envKeyName:"ALFRED_ANTHROPIC_API_KEY",needsApiKey:!0},{name:"openai",label:"OpenAI (GPT)",defaultModel:"gpt-4o",envKeyName:"ALFRED_OPENAI_API_KEY",needsApiKey:!0},{name:"openrouter",label:"OpenRouter (multiple providers)",defaultModel:"anthropic/claude-sonnet-4-20250514",envKeyName:"ALFRED_OPENROUTER_API_KEY",needsApiKey:!0,baseUrl:"https://openrouter.ai/api/v1"},{name:"ollama",label:"Ollama (local, no API key needed)",defaultModel:"llama3.2",envKeyName:"",needsApiKey:!1,baseUrl:"http://localhost:11434"},{name:"openwebui",label:"OpenWebUI (local OpenAI-compatible UI)",defaultModel:"llama3.2",envKeyName:"ALFRED_OPENWEBUI_API_KEY",needsApiKey:!0,baseUrl:"http://localhost:3000/api/v1"}],Je=[{name:"telegram",label:"Telegram",configKey:"telegram",credentials:[{envKey:"ALFRED_TELEGRAM_TOKEN",configField:"token",prompt:"Enter your Telegram Bot token (from @BotFather)",required:!0}]},{name:"discord",label:"Discord",configKey:"discord",credentials:[{envKey:"ALFRED_DISCORD_TOKEN",configField:"token",prompt:"Enter your Discord Bot token",required:!0}]},{name:"whatsapp",label:"WhatsApp",configKey:"whatsapp",credentials:[]},{name:"matrix",label:"Matrix",configKey:"matrix",credentials:[{envKey:"ALFRED_MATRIX_HOMESERVER_URL",configField:"homeserverUrl",prompt:"Enter your Matrix homeserver URL",defaultValue:"https://matrix.org",required:!0},{envKey:"ALFRED_MATRIX_ACCESS_TOKEN",configField:"accessToken",prompt:"Enter your Matrix access token",required:!0},{envKey:"ALFRED_MATRIX_USER_ID",configField:"userId",prompt:"Enter your Matrix user ID (e.g. @bot:matrix.org)",required:!0}]},{name:"signal",label:"Signal",configKey:"signal",credentials:[{envKey:"ALFRED_SIGNAL_API_URL",configField:"apiUrl",prompt:"Enter the Signal REST API URL",defaultValue:"http://localhost:8080",required:!0},{envKey:"ALFRED_SIGNAL_PHONE_NUMBER",configField:"phoneNumber",prompt:"Enter the Signal phone number (e.g. +15551234567)",required:!0}]}];d(ca,"loadExistingConfig");d(la,"setupCommand");d(P,"askWithDefault");d(ie,"askRequired");d(Er,"askNumber");d(da,"printBanner")});var wo={};q(wo,{configCommand:()=>ha});function ma(c){let e=c.toLowerCase();return ua.some(t=>e.includes(t))}function pa(c){return typeof c!="string"||c.length===0?"(empty)":c.length<=8?"***":c.slice(0,4)+"..."+c.slice(-4)}function yo(c){let e={};for(let[t,s]of Object.entries(c))ma(t)?e[t]=pa(s):s!=null&&typeof s=="object"&&!Array.isArray(s)?e[t]=yo(s):e[t]=s;return e}async function ha(){let c=new H,e;try{e=c.loadConfig()}catch(s){console.error("Failed to load configuration:",s.message),process.exit(1)}let t=yo(e);console.log("Alfred \u2014 Resolved Configuration"),console.log("================================"),console.log(JSON.stringify(t,null,2))}var ua,Eo=f(()=>{"use strict";le();ua=["token","apikey","api_key","accesstoken","secret","password"];d(ma,"isSensitiveKey");d(pa,"redactValue");d(yo,"redactObject");d(ha,"configCommand")});var bo={};q(bo,{rulesCommand:()=>ga});import ws from"node:fs";import To from"node:path";import fa from"js-yaml";async function ga(){let c=new H,e;try{e=c.loadConfig()}catch(a){console.error("Failed to load configuration:",a.message),process.exit(1)}let t=To.resolve(e.security.rulesPath);if(!ws.existsSync(t)){console.log(`Rules directory not found: ${t}`),console.log("No security rules loaded.");return}ws.statSync(t).isDirectory()||(console.error(`Rules path is not a directory: ${t}`),process.exit(1));let r=ws.readdirSync(t).filter(a=>a.endsWith(".yml")||a.endsWith(".yaml"));if(r.length===0){console.log(`No YAML rule files found in: ${t}`);return}let n=new pe,o=[],i=[];for(let a of r){let l=To.join(t,a);try{let u=ws.readFileSync(l,"utf-8"),p=fa.load(u),m=n.loadFromObject(p);o.push(...m)}catch(u){i.push(` ${a}: ${u.message}`)}}if(console.log("Alfred \u2014 Security Rules"),console.log("======================="),console.log(`Rules directory: ${t}`),console.log(`Rule files found: ${r.length}`),console.log(`Total rules loaded: ${o.length}`),console.log(""),i.length>0){console.log("Errors:");for(let a of i)console.log(a);console.log("")}if(o.length!==0){o.sort((a,l)=>a.priority-l.priority),console.log("Loaded rules (sorted by priority):"),console.log("");for(let a of o){let l=a.rateLimit?` | rate-limit: ${a.rateLimit.maxInvocations}/${a.rateLimit.windowSeconds}s`:"";console.log(` [${a.priority}] ${a.id}`),console.log(` effect: ${a.effect} | scope: ${a.scope}`),console.log(` actions: ${a.actions.join(", ")}`),console.log(` risk levels: ${a.riskLevels.join(", ")}${l}`),a.conditions&&console.log(` conditions: ${JSON.stringify(a.conditions)}`),console.log("")}}}var So=f(()=>{"use strict";le();ts();d(ga,"rulesCommand")});var _o={};q(_o,{statusCommand:()=>wa});import Xt from"node:fs";import br from"node:path";import ya from"js-yaml";async function wa(){let c=new H,e;try{e=c.loadConfig()}catch(l){console.error("Failed to load configuration:",l.message),process.exit(1)}console.log("Alfred \u2014 Status"),console.log("================"),console.log("");let t=[{name:"Telegram",enabled:e.telegram.enabled,configured:!!e.telegram.token},{name:"Discord",enabled:!!e.discord?.enabled,configured:!!e.discord?.token},{name:"WhatsApp",enabled:!!e.whatsapp?.enabled,configured:!!e.whatsapp?.dataPath},{name:"Matrix",enabled:!!e.matrix?.enabled,configured:!!e.matrix?.accessToken},{name:"Signal",enabled:!!e.signal?.enabled,configured:!!e.signal?.phoneNumber}];console.log("Messaging Adapters:");for(let l of t){let u=l.enabled?"enabled":l.configured?"configured (disabled)":"not configured",p=l.enabled?"+":"-";console.log(` [${p}] ${l.name}: ${u}`)}console.log(""),console.log("LLM Provider:");let s=e.llm.default;console.log(` Provider: ${s.provider}`),console.log(` Model: ${s.model}`),console.log(` API Key: ${s.apiKey?"set":"not set"}`),s.baseUrl&&console.log(` Base URL: ${s.baseUrl}`);for(let l of["strong","fast","embeddings","local"]){let u=e.llm[l];u&&console.log(` ${l}: ${u.provider}/${u.model}`)}console.log(""),console.log("Storage:");let r=br.resolve(e.storage.path),n=Xt.existsSync(r);console.log(` Database: ${r}`),console.log(` Status: ${n?"exists":"not yet created"}`),console.log("");let o=br.resolve(e.security.rulesPath),i=0,a=0;if(Xt.existsSync(o)&&Xt.statSync(o).isDirectory()){let l=Xt.readdirSync(o).filter(p=>p.endsWith(".yml")||p.endsWith(".yaml"));a=l.length;let u=new pe;for(let p of l){let m=br.join(o,p);try{let h=Xt.readFileSync(m,"utf-8"),E=ya.load(h),w=u.loadFromObject(E);i+=w.length}catch{}}}console.log("Security:"),console.log(` Rules path: ${o}`),console.log(` Rule files: ${a}`),console.log(` Rules loaded: ${i}`),console.log(` Default effect: ${e.security.defaultEffect}`),e.security.ownerUserId&&console.log(` Owner user ID: ${e.security.ownerUserId}`),console.log(""),console.log("Logger:"),console.log(` Level: ${e.logger.level}`),console.log(` Pretty: ${e.logger.pretty}`)}var ko=f(()=>{"use strict";le();ts();d(wa,"statusCommand")});var vo={};q(vo,{logsCommand:()=>ba});import Ea from"node:fs";import Ta from"node:path";async function ba(c){let e=new H,t;try{t=e.loadConfig()}catch(n){console.error("Failed to load configuration:",n.message),process.exit(1)}let s=Ta.resolve(t.storage.path);if(!Ea.existsSync(s)){console.log(`Database not found at: ${s}`),console.log("No audit log entries. Alfred has not been run yet, or the database path is incorrect.");return}let r;try{r=new de(s);let n=new ue(r.getDb()),o=n.count({}),i=n.query({limit:c});if(console.log("Alfred \u2014 Audit Log"),console.log("==================="),console.log(`Total entries: ${o}`),console.log(`Showing last ${Math.min(c,o)} entries:`),console.log(""),i.length===0){console.log("No audit log entries found.");return}for(let a of i){let l=a.timestamp.toISOString(),u=a.effect==="allow"?"ALLOW":"DENY ";console.log(` ${l} [${u}] ${a.action}`),console.log(` user: ${a.userId} | platform: ${a.platform} | risk: ${a.riskLevel}`),a.ruleId&&console.log(` rule: ${a.ruleId}`),a.chatId&&console.log(` chat: ${a.chatId}`),a.context&&console.log(` context: ${JSON.stringify(a.context)}`),console.log("")}}catch(n){console.error("Failed to read audit log:",n.message),process.exit(1)}finally{r&&r.close()}}var xo=f(()=>{"use strict";le();Ds();d(ba,"logsCommand")});import{readFileSync as Sa}from"node:fs";import{fileURLToPath as _a}from"node:url";import{dirname as ka,join as va}from"node:path";function xa(){try{let c=ka(_a(import.meta.url));for(let e of["../package.json","../../package.json"])try{let t=JSON.parse(Sa(va(c,e),"utf-8"));if(t.version)return t.version}catch{}}catch{}return"0.0.0"}d(xa,"getVersion");var Io=xa(),Sr=`
581
+ `)}var L,Ze,ae,gs,J,ys,oa,ia,Ht,Je,go=f(()=>{"use strict";L="\x1B[0m",Ze="\x1B[1m",ae="\x1B[2m",gs="\x1B[32m",J="\x1B[33m",ys="\x1B[36m",oa="\x1B[31m",ia="\x1B[35m";d(C,"green");d(aa,"yellow");d(_e,"cyan");d(ho,"red");d($,"bold");d(_,"dim");d(Se,"maskKey");Ht=[{name:"anthropic",label:"Anthropic (Claude) \u2014 recommended",defaultModel:"claude-sonnet-4-20250514",envKeyName:"ALFRED_ANTHROPIC_API_KEY",needsApiKey:!0},{name:"openai",label:"OpenAI (GPT)",defaultModel:"gpt-4o",envKeyName:"ALFRED_OPENAI_API_KEY",needsApiKey:!0},{name:"openrouter",label:"OpenRouter (multiple providers)",defaultModel:"anthropic/claude-sonnet-4-20250514",envKeyName:"ALFRED_OPENROUTER_API_KEY",needsApiKey:!0,baseUrl:"https://openrouter.ai/api/v1"},{name:"ollama",label:"Ollama (local, no API key needed)",defaultModel:"llama3.2",envKeyName:"",needsApiKey:!1,baseUrl:"http://localhost:11434"},{name:"openwebui",label:"OpenWebUI (local OpenAI-compatible UI)",defaultModel:"llama3.2",envKeyName:"ALFRED_OPENWEBUI_API_KEY",needsApiKey:!0,baseUrl:"http://localhost:3000/api/v1"}],Je=[{name:"telegram",label:"Telegram",configKey:"telegram",credentials:[{envKey:"ALFRED_TELEGRAM_TOKEN",configField:"token",prompt:"Enter your Telegram Bot token (from @BotFather)",required:!0}]},{name:"discord",label:"Discord",configKey:"discord",credentials:[{envKey:"ALFRED_DISCORD_TOKEN",configField:"token",prompt:"Enter your Discord Bot token",required:!0}]},{name:"whatsapp",label:"WhatsApp",configKey:"whatsapp",credentials:[]},{name:"matrix",label:"Matrix",configKey:"matrix",credentials:[{envKey:"ALFRED_MATRIX_HOMESERVER_URL",configField:"homeserverUrl",prompt:"Enter your Matrix homeserver URL",defaultValue:"https://matrix.org",required:!0},{envKey:"ALFRED_MATRIX_ACCESS_TOKEN",configField:"accessToken",prompt:"Enter your Matrix access token",required:!0},{envKey:"ALFRED_MATRIX_USER_ID",configField:"userId",prompt:"Enter your Matrix user ID (e.g. @bot:matrix.org)",required:!0}]},{name:"signal",label:"Signal",configKey:"signal",credentials:[{envKey:"ALFRED_SIGNAL_API_URL",configField:"apiUrl",prompt:"Enter the Signal REST API URL",defaultValue:"http://localhost:8080",required:!0},{envKey:"ALFRED_SIGNAL_PHONE_NUMBER",configField:"phoneNumber",prompt:"Enter the Signal phone number (e.g. +15551234567)",required:!0}]}];d(ca,"loadExistingConfig");d(la,"setupCommand");d(P,"askWithDefault");d(ie,"askRequired");d(Er,"askNumber");d(da,"printBanner")});var wo={};q(wo,{configCommand:()=>ha});function ma(c){let e=c.toLowerCase();return ua.some(t=>e.includes(t))}function pa(c){return typeof c!="string"||c.length===0?"(empty)":c.length<=8?"***":c.slice(0,4)+"..."+c.slice(-4)}function yo(c){let e={};for(let[t,s]of Object.entries(c))ma(t)?e[t]=pa(s):s!=null&&typeof s=="object"&&!Array.isArray(s)?e[t]=yo(s):e[t]=s;return e}async function ha(){let c=new H,e;try{e=c.loadConfig()}catch(s){console.error("Failed to load configuration:",s.message),process.exit(1)}let t=yo(e);console.log("Alfred \u2014 Resolved Configuration"),console.log("================================"),console.log(JSON.stringify(t,null,2))}var ua,Eo=f(()=>{"use strict";le();ua=["token","apikey","api_key","accesstoken","secret","password"];d(ma,"isSensitiveKey");d(pa,"redactValue");d(yo,"redactObject");d(ha,"configCommand")});var bo={};q(bo,{rulesCommand:()=>ga});import ws from"node:fs";import To from"node:path";import fa from"js-yaml";async function ga(){let c=new H,e;try{e=c.loadConfig()}catch(a){console.error("Failed to load configuration:",a.message),process.exit(1)}let t=To.resolve(e.security.rulesPath);if(!ws.existsSync(t)){console.log(`Rules directory not found: ${t}`),console.log("No security rules loaded.");return}ws.statSync(t).isDirectory()||(console.error(`Rules path is not a directory: ${t}`),process.exit(1));let r=ws.readdirSync(t).filter(a=>a.endsWith(".yml")||a.endsWith(".yaml"));if(r.length===0){console.log(`No YAML rule files found in: ${t}`);return}let n=new pe,o=[],i=[];for(let a of r){let l=To.join(t,a);try{let u=ws.readFileSync(l,"utf-8"),h=fa.load(u),m=n.loadFromObject(h);o.push(...m)}catch(u){i.push(` ${a}: ${u.message}`)}}if(console.log("Alfred \u2014 Security Rules"),console.log("======================="),console.log(`Rules directory: ${t}`),console.log(`Rule files found: ${r.length}`),console.log(`Total rules loaded: ${o.length}`),console.log(""),i.length>0){console.log("Errors:");for(let a of i)console.log(a);console.log("")}if(o.length!==0){o.sort((a,l)=>a.priority-l.priority),console.log("Loaded rules (sorted by priority):"),console.log("");for(let a of o){let l=a.rateLimit?` | rate-limit: ${a.rateLimit.maxInvocations}/${a.rateLimit.windowSeconds}s`:"";console.log(` [${a.priority}] ${a.id}`),console.log(` effect: ${a.effect} | scope: ${a.scope}`),console.log(` actions: ${a.actions.join(", ")}`),console.log(` risk levels: ${a.riskLevels.join(", ")}${l}`),a.conditions&&console.log(` conditions: ${JSON.stringify(a.conditions)}`),console.log("")}}}var _o=f(()=>{"use strict";le();ts();d(ga,"rulesCommand")});var So={};q(So,{statusCommand:()=>wa});import Xt from"node:fs";import br from"node:path";import ya from"js-yaml";async function wa(){let c=new H,e;try{e=c.loadConfig()}catch(l){console.error("Failed to load configuration:",l.message),process.exit(1)}console.log("Alfred \u2014 Status"),console.log("================"),console.log("");let t=[{name:"Telegram",enabled:e.telegram.enabled,configured:!!e.telegram.token},{name:"Discord",enabled:!!e.discord?.enabled,configured:!!e.discord?.token},{name:"WhatsApp",enabled:!!e.whatsapp?.enabled,configured:!!e.whatsapp?.dataPath},{name:"Matrix",enabled:!!e.matrix?.enabled,configured:!!e.matrix?.accessToken},{name:"Signal",enabled:!!e.signal?.enabled,configured:!!e.signal?.phoneNumber}];console.log("Messaging Adapters:");for(let l of t){let u=l.enabled?"enabled":l.configured?"configured (disabled)":"not configured",h=l.enabled?"+":"-";console.log(` [${h}] ${l.name}: ${u}`)}console.log(""),console.log("LLM Provider:");let s=e.llm.default;console.log(` Provider: ${s.provider}`),console.log(` Model: ${s.model}`),console.log(` API Key: ${s.apiKey?"set":"not set"}`),s.baseUrl&&console.log(` Base URL: ${s.baseUrl}`);for(let l of["strong","fast","embeddings","local"]){let u=e.llm[l];u&&console.log(` ${l}: ${u.provider}/${u.model}`)}console.log(""),console.log("Storage:");let r=br.resolve(e.storage.path),n=Xt.existsSync(r);console.log(` Database: ${r}`),console.log(` Status: ${n?"exists":"not yet created"}`),console.log("");let o=br.resolve(e.security.rulesPath),i=0,a=0;if(Xt.existsSync(o)&&Xt.statSync(o).isDirectory()){let l=Xt.readdirSync(o).filter(h=>h.endsWith(".yml")||h.endsWith(".yaml"));a=l.length;let u=new pe;for(let h of l){let m=br.join(o,h);try{let p=Xt.readFileSync(m,"utf-8"),E=ya.load(p),w=u.loadFromObject(E);i+=w.length}catch{}}}console.log("Security:"),console.log(` Rules path: ${o}`),console.log(` Rule files: ${a}`),console.log(` Rules loaded: ${i}`),console.log(` Default effect: ${e.security.defaultEffect}`),e.security.ownerUserId&&console.log(` Owner user ID: ${e.security.ownerUserId}`),console.log(""),console.log("Logger:"),console.log(` Level: ${e.logger.level}`),console.log(` Pretty: ${e.logger.pretty}`)}var ko=f(()=>{"use strict";le();ts();d(wa,"statusCommand")});var vo={};q(vo,{logsCommand:()=>ba});import Ea from"node:fs";import Ta from"node:path";async function ba(c){let e=new H,t;try{t=e.loadConfig()}catch(n){console.error("Failed to load configuration:",n.message),process.exit(1)}let s=Ta.resolve(t.storage.path);if(!Ea.existsSync(s)){console.log(`Database not found at: ${s}`),console.log("No audit log entries. Alfred has not been run yet, or the database path is incorrect.");return}let r;try{r=new de(s);let n=new ue(r.getDb()),o=n.count({}),i=n.query({limit:c});if(console.log("Alfred \u2014 Audit Log"),console.log("==================="),console.log(`Total entries: ${o}`),console.log(`Showing last ${Math.min(c,o)} entries:`),console.log(""),i.length===0){console.log("No audit log entries found.");return}for(let a of i){let l=a.timestamp.toISOString(),u=a.effect==="allow"?"ALLOW":"DENY ";console.log(` ${l} [${u}] ${a.action}`),console.log(` user: ${a.userId} | platform: ${a.platform} | risk: ${a.riskLevel}`),a.ruleId&&console.log(` rule: ${a.ruleId}`),a.chatId&&console.log(` chat: ${a.chatId}`),a.context&&console.log(` context: ${JSON.stringify(a.context)}`),console.log("")}}catch(n){console.error("Failed to read audit log:",n.message),process.exit(1)}finally{r&&r.close()}}var xo=f(()=>{"use strict";le();Ds();d(ba,"logsCommand")});import{readFileSync as _a}from"node:fs";import{fileURLToPath as Sa}from"node:url";import{dirname as ka,join as va}from"node:path";function xa(){try{let c=ka(Sa(import.meta.url));for(let e of["../package.json","../../package.json"])try{let t=JSON.parse(_a(va(c,e),"utf-8"));if(t.version)return t.version}catch{}}catch{}return"0.0.0"}d(xa,"getVersion");var Io=xa(),_r=`
582
582
  Alfred CLI v${Io}
583
583
  Personal AI Assistant
584
584
 
@@ -597,4 +597,4 @@ Commands:
597
597
  Options:
598
598
  --help, -h Show this help message
599
599
  --version, -v Show version number
600
- `.trim();function Ia(c){let e=c.slice(2),t=e.length>0&&!e[0].startsWith("-")?e[0]:"",s=t?e.slice(1):e,r={},n=[],o=0;for(;o<s.length;){let i=s[o];if(i.startsWith("--")){let a=i.slice(2);o+1<s.length&&!s[o+1].startsWith("-")?(r[a]=s[o+1],o+=2):(r[a]=!0,o+=1)}else if(i.startsWith("-")&&i.length===2){let a=i.slice(1);o+1<s.length&&!s[o+1].startsWith("-")?(r[a]=s[o+1],o+=2):(r[a]=!0,o+=1)}else n.push(i),o+=1}return{command:t,flags:r,positional:n}}d(Ia,"parseArgs");async function $a(){let c=Ia(process.argv);switch((c.flags.help||c.flags.h)&&(console.log(Sr),process.exit(0)),(c.flags.version||c.flags.v)&&(console.log(`alfred v${Io}`),process.exit(0)),c.command){case"start":{let{startCommand:e}=await Promise.resolve().then(()=>(uo(),lo));await e();break}case"chat":{let{chatCommand:e}=await Promise.resolve().then(()=>(po(),mo));await e({model:typeof c.flags.model=="string"?c.flags.model:void 0,tier:typeof c.flags.tier=="string"?c.flags.tier:void 0});break}case"setup":{let{setupCommand:e}=await Promise.resolve().then(()=>(go(),fo));await e();break}case"config":{let{configCommand:e}=await Promise.resolve().then(()=>(Eo(),wo));await e();break}case"rules":{let{rulesCommand:e}=await Promise.resolve().then(()=>(So(),bo));await e();break}case"status":{let{statusCommand:e}=await Promise.resolve().then(()=>(ko(),_o));await e();break}case"logs":{let e=c.flags.tail,t=20;if(typeof e=="string"){let r=parseInt(e,10);(Number.isNaN(r)||r<=0)&&(console.error("Error: --tail must be a positive integer"),process.exit(1)),t=r}let{logsCommand:s}=await Promise.resolve().then(()=>(xo(),vo));await s(t);break}case"help":console.log(Sr);break;case"":console.log(Sr),process.exit(0);break;default:console.error(`Unknown command: ${c.command}`),console.error(""),console.error('Run "alfred --help" for usage information.'),process.exit(1)}}d($a,"main");$a().catch(c=>{console.error("Fatal error:",c),process.exit(1)});
600
+ `.trim();function Ia(c){let e=c.slice(2),t=e.length>0&&!e[0].startsWith("-")?e[0]:"",s=t?e.slice(1):e,r={},n=[],o=0;for(;o<s.length;){let i=s[o];if(i.startsWith("--")){let a=i.slice(2);o+1<s.length&&!s[o+1].startsWith("-")?(r[a]=s[o+1],o+=2):(r[a]=!0,o+=1)}else if(i.startsWith("-")&&i.length===2){let a=i.slice(1);o+1<s.length&&!s[o+1].startsWith("-")?(r[a]=s[o+1],o+=2):(r[a]=!0,o+=1)}else n.push(i),o+=1}return{command:t,flags:r,positional:n}}d(Ia,"parseArgs");async function $a(){let c=Ia(process.argv);switch((c.flags.help||c.flags.h)&&(console.log(_r),process.exit(0)),(c.flags.version||c.flags.v)&&(console.log(`alfred v${Io}`),process.exit(0)),c.command){case"start":{let{startCommand:e}=await Promise.resolve().then(()=>(uo(),lo));await e();break}case"chat":{let{chatCommand:e}=await Promise.resolve().then(()=>(po(),mo));await e({model:typeof c.flags.model=="string"?c.flags.model:void 0,tier:typeof c.flags.tier=="string"?c.flags.tier:void 0});break}case"setup":{let{setupCommand:e}=await Promise.resolve().then(()=>(go(),fo));await e();break}case"config":{let{configCommand:e}=await Promise.resolve().then(()=>(Eo(),wo));await e();break}case"rules":{let{rulesCommand:e}=await Promise.resolve().then(()=>(_o(),bo));await e();break}case"status":{let{statusCommand:e}=await Promise.resolve().then(()=>(ko(),So));await e();break}case"logs":{let e=c.flags.tail,t=20;if(typeof e=="string"){let r=parseInt(e,10);(Number.isNaN(r)||r<=0)&&(console.error("Error: --tail must be a positive integer"),process.exit(1)),t=r}let{logsCommand:s}=await Promise.resolve().then(()=>(xo(),vo));await s(t);break}case"help":console.log(_r);break;case"":console.log(_r),process.exit(0);break;default:console.error(`Unknown command: ${c.command}`),console.error(""),console.error('Run "alfred --help" for usage information.'),process.exit(1)}}d($a,"main");$a().catch(c=>{console.error("Fatal error:",c),process.exit(1)});
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@madh-io/alfred-ai",
3
- "version": "0.9.0",
3
+ "version": "0.9.2",
4
4
  "description": "Alfred — Personal AI Assistant across Telegram, Discord, WhatsApp, Matrix & Signal",
5
5
  "type": "module",
6
6
  "bin": {