agentix-cli 0.20.0 → 0.21.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{agent-57MG4LBM.js → agent-I3ILI3MO.js} +2 -2
- package/dist/{board-dashboard-HXDOYGIG.js → board-dashboard-ASI6MDKX.js} +339 -97
- package/dist/board-dashboard-ASI6MDKX.js.map +1 -0
- package/dist/{chunk-WFHIIVLL.js → chunk-2B2DIQKD.js} +75 -51
- package/dist/chunk-2B2DIQKD.js.map +1 -0
- package/dist/{chunk-MBOLXKA2.js → chunk-5GDCJ2SF.js} +13 -6
- package/dist/chunk-5GDCJ2SF.js.map +1 -0
- package/dist/{chunk-23AUU4S2.js → chunk-5XZ73VM4.js} +38 -38
- package/dist/chunk-5XZ73VM4.js.map +1 -0
- package/dist/{chunk-DLVOHCTA.js → chunk-AANSVC5A.js} +2 -2
- package/dist/{chunk-TC3BSUP7.js → chunk-AGINLNAW.js} +2 -2
- package/dist/{chunk-6B74TO2J.js → chunk-BLRLUF2H.js} +2 -2
- package/dist/chunk-EQNM3TOF.js +15 -0
- package/dist/chunk-EQNM3TOF.js.map +1 -0
- package/dist/{chunk-WPPUOTY6.js → chunk-FUYZUGNQ.js} +2 -2
- package/dist/chunk-GSX4NK2N.js +2 -0
- package/dist/chunk-GSX4NK2N.js.map +1 -0
- package/dist/chunk-GV7S5BAX.js +2 -0
- package/dist/chunk-GV7S5BAX.js.map +1 -0
- package/dist/{chunk-7GVXCOLO.js → chunk-IFQQVDM6.js} +85 -83
- package/dist/chunk-IFQQVDM6.js.map +1 -0
- package/dist/{chunk-QW2OYR3N.js → chunk-K6MC66D6.js} +2 -2
- package/dist/chunk-SZDACK6O.js +2 -0
- package/dist/chunk-SZDACK6O.js.map +1 -0
- package/dist/cli.js +1 -1
- package/dist/cli.js.map +1 -1
- package/dist/{config-QXWKEQON.js → config-RWHSEE4N.js} +2 -2
- package/dist/config-mutator-JKCNCY2F.js +2 -0
- package/dist/doctor-KWN7NUFQ.js +2 -0
- package/dist/index.js +1 -1
- package/dist/program-JEKM7SCS.js +2 -0
- package/dist/{registry-HM4ELSXS.js → registry-EGKDMVSP.js} +2 -2
- package/dist/runner-BFYDWPUO.js +2 -0
- package/dist/scheduler-ED4FCI2Y.js +2 -0
- package/dist/scheduler-ED4FCI2Y.js.map +1 -0
- package/dist/store-I3HEWVLQ.js +2 -0
- package/dist/store-I3HEWVLQ.js.map +1 -0
- package/dist/types-Y6ZCZ52Z.js +2 -0
- package/dist/types-Y6ZCZ52Z.js.map +1 -0
- package/dist/web/workflow-editor.global.js +12 -10
- package/dist/web/workflow-editor.global.js.map +1 -1
- package/package.json +1 -1
- package/dist/board-dashboard-HXDOYGIG.js.map +0 -1
- package/dist/chunk-23AUU4S2.js.map +0 -1
- package/dist/chunk-7GVXCOLO.js.map +0 -1
- package/dist/chunk-E4ZZILAK.js +0 -15
- package/dist/chunk-E4ZZILAK.js.map +0 -1
- package/dist/chunk-MBOLXKA2.js.map +0 -1
- package/dist/chunk-WFHIIVLL.js.map +0 -1
- package/dist/config-mutator-53XGR2NT.js +0 -2
- package/dist/doctor-SEOUFHSL.js +0 -2
- package/dist/program-WWCXMRU2.js +0 -2
- package/dist/scheduler-XVFIK4XH.js +0 -2
- /package/dist/{agent-57MG4LBM.js.map → agent-I3ILI3MO.js.map} +0 -0
- /package/dist/{chunk-DLVOHCTA.js.map → chunk-AANSVC5A.js.map} +0 -0
- /package/dist/{chunk-TC3BSUP7.js.map → chunk-AGINLNAW.js.map} +0 -0
- /package/dist/{chunk-6B74TO2J.js.map → chunk-BLRLUF2H.js.map} +0 -0
- /package/dist/{chunk-WPPUOTY6.js.map → chunk-FUYZUGNQ.js.map} +0 -0
- /package/dist/{chunk-QW2OYR3N.js.map → chunk-K6MC66D6.js.map} +0 -0
- /package/dist/{config-QXWKEQON.js.map → config-RWHSEE4N.js.map} +0 -0
- /package/dist/{config-mutator-53XGR2NT.js.map → config-mutator-JKCNCY2F.js.map} +0 -0
- /package/dist/{doctor-SEOUFHSL.js.map → doctor-KWN7NUFQ.js.map} +0 -0
- /package/dist/{program-WWCXMRU2.js.map → program-JEKM7SCS.js.map} +0 -0
- /package/dist/{registry-HM4ELSXS.js.map → registry-EGKDMVSP.js.map} +0 -0
- /package/dist/{scheduler-XVFIK4XH.js.map → runner-BFYDWPUO.js.map} +0 -0
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import{a as C,b as T}from"./chunk-
|
|
1
|
+
import{a as C,b as T}from"./chunk-AANSVC5A.js";import{a as S,c as x}from"./chunk-4MREHZP5.js";import{a as L}from"./chunk-VJUTQAPJ.js";import{writeFileSync as P,mkdirSync as R,existsSync as D,readFileSync as q}from"fs";import{resolve as v}from"path";var H=["off","shadow","authoritative"],z={telegram:"INTENT_LEDGER_MODE_TELEGRAM",slack:"INTENT_LEDGER_MODE_SLACK",whatsapp:"INTENT_LEDGER_MODE_WHATSAPP",discord:"INTENT_LEDGER_MODE_DISCORD",gitlab:"INTENT_LEDGER_MODE_GITLAB",github:"INTENT_LEDGER_MODE_GITHUB",workflow:"INTENT_LEDGER_MODE_WORKFLOW",cron:"INTENT_LEDGER_MODE_CRON",mesh:"INTENT_LEDGER_MODE_MESH"},K="INTENT_LEDGER_MODE";function O(s,e=process.env){let n=_(e[z[s]]);if(n)return n;let t=_(e[K]);return t||"off"}function _(s){if(typeof s!="string")return null;let e=s.trim().toLowerCase();return H.includes(e)?e:null}var A;function X(s){A=s}function N(){return A}function k(s,e,n,t=Date.now,r){return s.db.transaction(i=>{let c=s.recordEvent(e),a=r??N(),u=a?.pmFor?.(c.project),d=u?`pm:${u}`:n.decidedBy,p=s.getDecisionsForEvent(c.id).find(h=>h.decidedBy===d);if(p)return p;let y=s.getActiveDecisionForSubject(c.project,c.subject);if(y){let h={eventId:c.id,decidedAt:i,decidedBy:d,agentId:null,outcome:"deduped",reason:`active dispatch in flight: ${y.decidedBy} \u2192 ${y.agentId??"?"}`};return s.recordDecision(h),h}let g=n.decide(c),l=g?g.agentId:null,f=g?g.outcome:"halted",m=g?g.reason:"no policy match";if(a?.canHandle&&f==="dispatched"&&l&&!a.canHandle(l,c.project,c.intent)){let $=l;l=null,f="halted",m=`org-chart: agent "${$}" cannot handle (${c.project??"no-project"}/${c.intent??"no-intent"})`}if(a?.withinDelegationBudget&&f==="dispatched"&&l&&!a.withinDelegationBudget(l,c.project,c.subject)){let h=l;l=null,f="halted",m=`delegation-budget: agent "${h}" depth-limit exceeded on ${c.project??"?"}/${c.subject??"?"}`}u&&f==="dispatched"&&l&&(m=m?`${m} (pm-gate: rubber-stamped by ${u})`:`pm-gate: rubber-stamped by ${u}`);let E={eventId:c.id,decidedAt:i,decidedBy:d,agentId:l,outcome:f,reason:m};return s.recordDecision(E),E})(t())}function M(s,e,n,t,r=Date.now){if(U(n,t))return!1;let o=r(),i={id:S(o),ts:o,source:e,eventId:n.eventId,decidedBy:n.decidedBy,ledgerAgentId:n.agentId,ledgerOutcome:n.outcome,ledgerReason:n.reason,legacyAgentId:t.agentId,legacyOutcome:t.outcome,legacyReason:t.reason??null};return s.recordDivergence(i),L.warn(`[ledger-divergence] source=${e} event=${n.eventId} decided_by=${n.decidedBy} ledger=${n.outcome}/${n.agentId??"null"} legacy=${t.outcome}/${t.agentId??"null"}`),!0}function U(s,e){return s.outcome===e.outcome&&s.agentId===e.agentId}function V(s,e,n=Date.now){return{ts:n(),source:"cron",sourceEventId:`${s.jobId}:${s.firedAt.getTime()}`,project:null,subject:`cron:${s.jobId}`,intent:"cron.fired",rawJson:e}}function W(s){return{decidedBy:"cron-scheduler",decide:()=>({agentId:s.agentId,outcome:s.outcome==="deduped"?"halted":s.outcome,reason:s.outcome==="deduped"?`legacy-dedup: ${s.reason??""}`.trim():s.reason??null})}}function J(s,e,n,t,r=Date.now){let o=V(e,n,r),i=W(t),c=k(s,o,i,r);return M(s,"cron",c,t,r),c}function F(s,e){if(!e)return s;let n=e*4;return`${s}
|
|
2
2
|
|
|
3
3
|
[Response budget]
|
|
4
4
|
Keep your response under ~${e} tokens (~${n} chars). Be concise \u2014 this is automated batch work, not a conversation.`}function b(s,e,n){let t=[];for(let r of s.split(","))if(r==="*")for(let o=e;o<=n;o++)t.push(o);else if(r.includes("/")){let[o,i]=r.split("/"),c=parseInt(i,10),a=o==="*"?e:parseInt(o,10);for(let u=a;u<=n;u+=c)t.push(u)}else if(r.includes("-")){let[o,i]=r.split("-").map(Number);for(let c=o;c<=i;c++)t.push(c)}else t.push(parseInt(r,10));return[...new Set(t)].sort((r,o)=>r-o)}function B(s,e,n){let t=s.trim().split(/\s+/);if(t.length!==5)throw new Error(`Invalid cron: ${s}`);let r=b(t[0],0,59),o=b(t[1],0,23),i=b(t[2],1,31),c=b(t[3],1,12),a=b(t[4],0,6),u=new Intl.DateTimeFormat("en-US",{timeZone:n,year:"numeric",month:"2-digit",day:"2-digit",hour:"2-digit",minute:"2-digit",hour12:!1}),d=new Date(e.getTime()+6e4);d.setSeconds(0,0);let p=new Date(d.getTime()+366*24*60*60*1e3);for(;d<p;){let y=u.formatToParts(d),g=$=>parseInt(y.find(j=>j.type===$)?.value||"0",10),l=g("minute"),f=g("hour"),m=g("day"),E=g("month"),h=d.getDay();if(r.includes(l)&&o.includes(f)&&i.includes(m)&&c.includes(E)&&a.includes(h))return d;d.setTime(d.getTime()+6e4)}throw new Error(`No next run found for cron "${s}" within 1 year`)}var I=5,w=[3e4,6e4,3e5,9e5,36e5],G=class{jobs=new Map;timers=new Map;registry;hooks;runsDir;lastRunFile;running=!1;notifyCallback;log;constructor(e,n,t,r=console.error.bind(console,"[cron]")){this.registry=n,this.hooks=t,this.log=r,this.runsDir=v(process.cwd(),".agentx/cron/runs"),this.lastRunFile=v(process.cwd(),".agentx/cron/last-runs.json");for(let[o,i]of Object.entries(e.crons))this.jobs.set(o,{id:o,enabled:i.enabled,schedule:i.schedule,timezone:i.timezone,agent:i.agent,prompt:i.prompt,timeout:i.timeout,model:i.model,maxOutputTokens:i.maxOutputTokens,onError:i.onError,consecutiveErrors:0,totalRuns:0,totalFailures:0})}setNotifyCallback(e){this.notifyCallback=e}async start(){this.running=!0,D(this.runsDir)||R(this.runsDir,{recursive:!0});let e=this.detectMissedRuns();if(e.length>0){this.log(`Detected ${e.length} missed cron run(s) while daemon was down:`);for(let{jobId:n,missedAt:t}of e)this.log(` "${n}" should have run at ${t.toISOString()}`);this.executeMissedRuns(e).catch(n=>{this.log(`Error executing missed runs: ${n.message}`)})}for(let[n,t]of this.jobs){if(!t.enabled){this.log(`Job "${n}" is disabled, skipping`);continue}this.scheduleNext(n)}this.log(`${this.jobs.size} cron job(s) loaded, ${Array.from(this.jobs.values()).filter(n=>n.enabled).length} enabled`)}async stop(){this.running=!1;for(let e of this.timers.values())clearTimeout(e);this.timers.clear(),this.saveLastRuns()}scheduleNext(e){let n=this.jobs.get(e);if(!n||!n.enabled||!this.running)return;let t=this.timers.get(e);t&&clearTimeout(t);try{let r=B(n.schedule,new Date,n.timezone);n.nextRun=r,n.retryPending=!1;let o=r.getTime()-Date.now();this.log(`Job "${e}" next run: ${r.toISOString()} (in ${Math.round(o/1e3)}s)`);let i=setTimeout(()=>this.executeJob(e),o);this.timers.set(e,i)}catch(r){this.log(`Failed to schedule "${e}": ${r.message}`)}}scheduleRetry(e,n){let t=this.jobs.get(e);if(!t||!t.enabled||!this.running)return;if(n>=I){this.log(`Job "${e}" exhausted all ${I} retries, scheduling next regular run`),this.scheduleNext(e);return}let r=w[n]||w[w.length-1];t.retryPending=!0,this.log(`Job "${e}" retry ${n+1}/${I} in ${Math.round(r/1e3)}s`);let o=setTimeout(()=>this.executeJob(e,n+1),r);this.timers.set(e,o)}recordCronDecisionInLedger(e,n,t,r){if(O("cron")!=="off")try{let o=J(x(),{jobId:e,agentId:n,firedAt:t},JSON.stringify({jobId:e,agentId:n,firedAt:t.toISOString()}),r);return o.outcome==="dispatched"?{eventId:o.eventId,decidedBy:o.decidedBy}:void 0}catch(o){this.log(`[ledger] cron "${e}" record failed: ${o?.message??o}`);return}}async executeJob(e,n=0){let t=this.jobs.get(e);if(!t||!this.running)return;let r=n>0,o=new Date;if(this.hooks?.has("pre:cron-run")){let a=await this.hooks.execute("pre:cron-run",{event:"pre:cron-run",jobId:e,agent:t.agent,prompt:t.prompt});if(a.blocked){this.log(`Job "${e}" blocked by hook: ${a.message}`),this.recordCronDecisionInLedger(e,t.agent,o,{agentId:null,outcome:"halted",reason:`pre-hook blocked: ${a.message??""}`.trim()}),this.scheduleNext(e);return}}this.log(`${r?`[retry ${n}] `:""}Executing job "${e}" -> agent "${t.agent}"`);let i=o;t.lastRun=i,t.totalRuns++;let c=this.recordCronDecisionInLedger(e,t.agent,o,{agentId:t.agent,outcome:"dispatched",reason:r?`retry ${n}`:null});try{let a=await this.registry.execute({message:F(t.prompt,t.maxOutputTokens),agentId:t.agent,model:t.model,intentRef:c,context:{channel:"cron",chatId:`cron:${e}`}}),u={jobId:e,startedAt:i,completedAt:new Date,success:!a.error,response:a.content,error:a.error,duration:a.duration||Date.now()-i.getTime(),isRetry:r,retryAttempt:n};if(a.error){if(t.consecutiveErrors++,t.totalFailures++,t.lastError=a.error,this.log(`Job "${e}" failed (${t.consecutiveErrors} consecutive): ${a.error}`),await this.notifyFailure(t,a.error),t.onError.includes("disable")&&t.consecutiveErrors>=3){t.enabled=!1,this.log(`Job "${e}" disabled after ${t.consecutiveErrors} consecutive errors`);try{let d=await C(p=>T(p,`crons.${e}.enabled`,!1),{reload:!1});d.success||this.log(`Failed to persist disable for "${e}": ${d.error}`)}catch(d){this.log(`Failed to persist disable for "${e}": ${d.message}`)}await this.notifyDisabled(t)}this.logRun(u),this.scheduleRetry(e,n);return}else t.consecutiveErrors>0&&this.log(`Job "${e}" recovered after ${t.consecutiveErrors} failure(s)`),t.consecutiveErrors=0,t.lastSuccess=new Date,t.lastError=void 0,t.retryPending=!1,this.log(`Job "${e}" completed in ${u.duration}ms`);this.logRun(u),this.hooks?.has("post:cron-run")&&await this.hooks.execute("post:cron-run",{event:"post:cron-run",jobId:e,success:u.success,duration:u.duration,error:u.error?new Error(u.error):void 0})}catch(a){t.consecutiveErrors++,t.totalFailures++,t.lastError=a.message,this.log(`Job "${e}" threw: ${a.message}`),await this.notifyFailure(t,a.message),this.scheduleRetry(e,n);return}this.saveLastRuns(),this.scheduleNext(e)}detectMissedRuns(){let e=[],n=this.loadLastRuns();if(!n)return e;for(let[t,r]of this.jobs){if(!r.enabled)continue;let o=n[t];if(!o)continue;let i=new Date(o);try{let c=B(r.schedule,i,r.timezone);c.getTime()<Date.now()&&e.push({jobId:t,missedAt:c})}catch{}}return e}async executeMissedRuns(e){for(let{jobId:n,missedAt:t}of e){let r=this.jobs.get(n);if(!(!r||!r.enabled)){this.log(`Running missed job "${n}" (was due at ${t.toISOString()})`);try{let o=await this.registry.execute({message:F(`[MISSED RUN \u2014 was scheduled for ${t.toISOString()}]
|
|
5
5
|
|
|
6
6
|
${r.prompt}`,r.maxOutputTokens),agentId:r.agent,context:{channel:"cron",chatId:`cron:${n}`}}),i={jobId:n,startedAt:new Date,completedAt:new Date,success:!o.error,response:o.content,error:o.error,duration:o.duration||0,isRetry:!1};this.logRun(i),o.error?this.log(`Missed job "${n}" failed: ${o.error}`):(this.log(`Missed job "${n}" completed`),r.lastSuccess=new Date),r.lastRun=new Date,r.totalRuns++}catch(o){this.log(`Missed job "${n}" threw: ${o.message}`)}}}this.saveLastRuns()}async notifyFailure(e,n){if(!(!e.onError.includes("notify")&&e.consecutiveErrors<2)){if(!this.notifyCallback){this.log(`[ALERT] Cron "${e.id}" failed (${e.consecutiveErrors}x): ${n.slice(0,200)}`);return}try{await this.notifyCallback(e.id,e.agent,n,e.consecutiveErrors)}catch{}}}async notifyDisabled(e){if(!this.notifyCallback){this.log(`[ALERT] Cron "${e.id}" has been DISABLED after ${e.consecutiveErrors} consecutive failures`);return}try{await this.notifyCallback(e.id,e.agent,`AUTO-DISABLED after ${e.consecutiveErrors} consecutive failures. Last error: ${e.lastError||"unknown"}`,e.consecutiveErrors)}catch{}}saveLastRuns(){try{let e={};for(let[t,r]of this.jobs)r.lastRun&&(e[t]=r.lastRun.toISOString());let n=v(process.cwd(),".agentx/cron");D(n)||R(n,{recursive:!0}),P(this.lastRunFile,JSON.stringify(e,null,2))}catch{}}loadLastRuns(){try{return D(this.lastRunFile)?JSON.parse(q(this.lastRunFile,"utf-8")):null}catch{return null}}logRun(e){try{let n=v(this.runsDir,e.jobId);D(n)||R(n,{recursive:!0});let t=`${e.startedAt.toISOString().replace(/[:.]/g,"-")}.json`;P(v(n,t),JSON.stringify(e,null,2))}catch{}}list(){return Array.from(this.jobs.values())}health(){let e=Array.from(this.jobs.values()),n=this.detectMissedRuns();return{healthy:e.filter(t=>t.enabled&&t.consecutiveErrors===0).length,failing:e.filter(t=>t.enabled&&t.consecutiveErrors>0).length,disabled:e.filter(t=>!t.enabled).length,missed:n.length,jobs:e.map(t=>({id:t.id,status:t.enabled?t.retryPending?"retrying":t.consecutiveErrors>0?"failing":"healthy":"disabled",consecutiveErrors:t.consecutiveErrors,lastError:t.lastError}))}}};export{O as a,X as b,k as c,M as d,B as e,G as f};
|
|
7
|
-
//# sourceMappingURL=chunk-
|
|
7
|
+
//# sourceMappingURL=chunk-K6MC66D6.js.map
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{exec as A}from"child_process";var m=32*1024;function f(n,r){return n.replace(/\{\{\s*([a-zA-Z_][a-zA-Z0-9_]*)\s*\}\}/g,(o,e)=>{let t=r[e];return t==null?"":String(t)}).replace(/\$\{?([A-Z_][A-Z0-9_]*)\}?/g,(o,e)=>process.env[e]??"")}function k(n,r){let o={};for(let e of n.inputs){let t=r[e.name]??e.defaultValue;if(t===void 0||t===""){if(e.required)throw new Error(`input "${e.name}" is required`);continue}if(e.type==="number"){let i=typeof t=="number"?t:Number(t);if(!Number.isFinite(i))throw new Error(`input "${e.name}" must be a number`);t=i}else e.type==="boolean"?t=t===!0||t==="true"||t==="1"||t===1:t=String(t);o[e.name]=t}return o}async function y(n,r={}){let o=Date.now(),e=k(n,r);if(n.kind==="shell")return R(n,e,o);if(n.kind==="http")return b(n,e,o);throw new Error(`unsupported action kind: ${n.kind}`)}function R(n,r,o){let e=f(n.command,r),t={...process.env};if(n.env)for(let[c,d]of Object.entries(n.env))t[c]=f(d,r);let i=n.cwd?f(n.cwd,r):process.cwd();return new Promise(c=>{let d=!1,u=s=>{d||(d=!0,c(s))};A(e,{cwd:i,env:t,timeout:n.timeoutMs,maxBuffer:m},(s,a,p)=>{let w=String(a||"").slice(0,m),g=String(p||"").slice(0,m),l=s?s.code??1:0;u({ok:!s,output:w,errors:g||(s?s.message:void 0),status:typeof l=="number"?l:1,durationMs:Date.now()-o})})})}async function b(n,r,o){let e=f(n.url,r),t={};if(n.headers)for(let[u,s]of Object.entries(n.headers))t[u]=f(s,r);let i=n.method==="GET"||n.method==="DELETE"?void 0:n.body?f(n.body,r):void 0,c=new AbortController,d=setTimeout(()=>c.abort(),n.timeoutMs);try{let u=await fetch(e,{method:n.method,headers:t,body:i,signal:c.signal}),s=(await u.text()).slice(0,m);return{ok:u.ok,output:s,status:u.status,durationMs:Date.now()-o}}catch(u){return{ok:!1,output:"",errors:u?.message||String(u),status:0,durationMs:Date.now()-o}}finally{clearTimeout(d)}}export{f as a,k as b,y as c};
|
|
2
|
+
//# sourceMappingURL=chunk-SZDACK6O.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/actions/runner.ts"],"sourcesContent":["import { exec } from \"child_process\"\nimport type { Action, ActionRunResult, ActionInput } from \"./types\"\n\n// --- Action runner ---\n//\n// Resolves {{name}} markers from `inputs` and ${VAR} from process.env,\n// then dispatches by kind:\n// - \"shell\" — exec the command (cwd-aware, env-merge)\n// - \"http\" — fetch the url with method/headers/body\n//\n// Output is capped at ~32KB so a runaway command doesn't blow up the\n// dashboard JSON response.\n\nconst MAX_OUTPUT = 32 * 1024\n\n/** Fill {{name}} markers from values; ${VAR} from process.env. */\nexport function template(s: string, values: Record<string, unknown>): string {\n return s\n .replace(/\\{\\{\\s*([a-zA-Z_][a-zA-Z0-9_]*)\\s*\\}\\}/g, (_, name) => {\n const v = values[name]\n return v === undefined || v === null ? \"\" : String(v)\n })\n .replace(/\\$\\{?([A-Z_][A-Z0-9_]*)\\}?/g, (_, name) => process.env[name] ?? \"\")\n}\n\n/** Validate inputs against the action's declared schema, applying defaults\n * and rejecting missing required fields. Returns the cleaned values\n * (booleans/numbers coerced from string CLI input). */\nexport function resolveInputs(action: Action, raw: Record<string, unknown>): Record<string, unknown> {\n const out: Record<string, unknown> = {}\n for (const def of action.inputs as ActionInput[]) {\n let v: unknown = raw[def.name] ?? def.defaultValue\n if (v === undefined || v === \"\") {\n if (def.required) throw new Error(`input \"${def.name}\" is required`)\n continue\n }\n if (def.type === \"number\") {\n const n = typeof v === \"number\" ? v : Number(v)\n if (!Number.isFinite(n)) throw new Error(`input \"${def.name}\" must be a number`)\n v = n\n } else if (def.type === \"boolean\") {\n v = v === true || v === \"true\" || v === \"1\" || v === 1\n } else {\n v = String(v)\n }\n out[def.name] = v\n }\n return out\n}\n\nexport async function runAction(action: Action, rawInputs: Record<string, unknown> = {}): Promise<ActionRunResult> {\n const start = Date.now()\n const values = resolveInputs(action, rawInputs)\n if (action.kind === \"shell\") return runShell(action, values, start)\n if (action.kind === \"http\") return runHttp(action, values, start)\n throw new Error(`unsupported action kind: ${(action as Action).kind}`)\n}\n\nfunction runShell(action: Extract<Action, { kind: \"shell\" }>, values: Record<string, unknown>, start: number): Promise<ActionRunResult> {\n const cmd = template(action.command, values)\n const env: NodeJS.ProcessEnv = { ...process.env }\n if (action.env) {\n for (const [k, v] of Object.entries(action.env)) env[k] = template(v, values)\n }\n const cwd = action.cwd ? template(action.cwd, values) : process.cwd()\n\n return new Promise<ActionRunResult>((resolve) => {\n let settled = false\n const finish = (r: ActionRunResult) => { if (settled) return; settled = true; resolve(r) }\n exec(cmd, { cwd, env, timeout: action.timeoutMs, maxBuffer: MAX_OUTPUT }, (err, stdout, stderr) => {\n const out = String(stdout || \"\").slice(0, MAX_OUTPUT)\n const errs = String(stderr || \"\").slice(0, MAX_OUTPUT)\n const status = err ? (err as NodeJS.ErrnoException & { code?: number }).code ?? 1 : 0\n finish({\n ok: !err,\n output: out,\n errors: errs || (err ? err.message : undefined),\n status: typeof status === \"number\" ? status : 1,\n durationMs: Date.now() - start,\n })\n })\n })\n}\n\nasync function runHttp(action: Extract<Action, { kind: \"http\" }>, values: Record<string, unknown>, start: number): Promise<ActionRunResult> {\n const url = template(action.url, values)\n const headers: Record<string, string> = {}\n if (action.headers) for (const [k, v] of Object.entries(action.headers)) headers[k] = template(v, values)\n const body = action.method === \"GET\" || action.method === \"DELETE\" ? undefined : (action.body ? template(action.body, values) : undefined)\n const ac = new AbortController()\n const timer = setTimeout(() => ac.abort(), action.timeoutMs)\n try {\n const res = await fetch(url, { method: action.method, headers, body, signal: ac.signal })\n const text = (await res.text()).slice(0, MAX_OUTPUT)\n return {\n ok: res.ok,\n output: text,\n status: res.status,\n durationMs: Date.now() - start,\n }\n } catch (e: any) {\n return {\n ok: false,\n output: \"\",\n errors: e?.message || String(e),\n status: 0,\n durationMs: Date.now() - start,\n }\n } finally {\n clearTimeout(timer)\n }\n}\n"],"mappings":"AAAA,OAAS,QAAAA,MAAY,gBAarB,IAAMC,EAAa,GAAK,KAGjB,SAASC,EAASC,EAAWC,EAAyC,CAC3E,OAAOD,EACJ,QAAQ,0CAA2C,CAACE,EAAGC,IAAS,CAC/D,IAAMC,EAAIH,EAAOE,CAAI,EACrB,OAA0BC,GAAM,KAAO,GAAK,OAAOA,CAAC,CACtD,CAAC,EACA,QAAQ,8BAA+B,CAACF,EAAGC,IAAS,QAAQ,IAAIA,CAAI,GAAK,EAAE,CAChF,CAKO,SAASE,EAAcC,EAAgBC,EAAuD,CACnG,IAAMC,EAA+B,CAAC,EACtC,QAAWC,KAAOH,EAAO,OAAyB,CAChD,IAAIF,EAAaG,EAAIE,EAAI,IAAI,GAAKA,EAAI,aACtC,GAAIL,IAAM,QAAaA,IAAM,GAAI,CAC/B,GAAIK,EAAI,SAAU,MAAM,IAAI,MAAM,UAAUA,EAAI,mBAAmB,EACnE,SAEF,GAAIA,EAAI,OAAS,SAAU,CACzB,IAAMC,EAAI,OAAON,GAAM,SAAWA,EAAI,OAAOA,CAAC,EAC9C,GAAI,CAAC,OAAO,SAASM,CAAC,EAAG,MAAM,IAAI,MAAM,UAAUD,EAAI,wBAAwB,EAC/EL,EAAIM,OACKD,EAAI,OAAS,UACtBL,EAAIA,IAAM,IAAQA,IAAM,QAAUA,IAAM,KAAOA,IAAM,EAErDA,EAAI,OAAOA,CAAC,EAEdI,EAAIC,EAAI,IAAI,EAAIL,EAElB,OAAOI,CACT,CAEA,eAAsBG,EAAUL,EAAgBM,EAAqC,CAAC,EAA6B,CACjH,IAAMC,EAAQ,KAAK,IAAI,EACjBZ,EAASI,EAAcC,EAAQM,CAAS,EAC9C,GAAIN,EAAO,OAAS,QAAS,OAAOQ,EAASR,EAAQL,EAAQY,CAAK,EAClE,GAAIP,EAAO,OAAS,OAAQ,OAAOS,EAAQT,EAAQL,EAAQY,CAAK,EAChE,MAAM,IAAI,MAAM,4BAA6BP,EAAkB,MAAM,CACvE,CAEA,SAASQ,EAASR,EAA4CL,EAAiCY,EAAyC,CACtI,IAAMG,EAAMjB,EAASO,EAAO,QAASL,CAAM,EACrCgB,EAAyB,CAAE,GAAG,QAAQ,GAAI,EAChD,GAAIX,EAAO,IACT,OAAW,CAACY,EAAGd,CAAC,IAAK,OAAO,QAAQE,EAAO,GAAG,EAAGW,EAAIC,CAAC,EAAInB,EAASK,EAAGH,CAAM,EAE9E,IAAMkB,EAAMb,EAAO,IAAMP,EAASO,EAAO,IAAKL,CAAM,EAAI,QAAQ,IAAI,EAEpE,OAAO,IAAI,QAA0BmB,GAAY,CAC/C,IAAIC,EAAU,GACRC,EAAUC,GAAuB,CAAMF,IAAiBA,EAAU,GAAMD,EAAQG,CAAC,EAAE,EACzF1B,EAAKmB,EAAK,CAAE,IAAAG,EAAK,IAAAF,EAAK,QAASX,EAAO,UAAW,UAAWR,CAAW,EAAG,CAAC0B,EAAKC,EAAQC,IAAW,CACjG,IAAMlB,EAAM,OAAOiB,GAAU,EAAE,EAAE,MAAM,EAAG3B,CAAU,EAC9C6B,EAAO,OAAOD,GAAU,EAAE,EAAE,MAAM,EAAG5B,CAAU,EAC/C8B,EAASJ,EAAOA,EAAkD,MAAQ,EAAI,EACpFF,EAAO,CACL,GAAI,CAACE,EACL,OAAQhB,EACR,OAAQmB,IAASH,EAAMA,EAAI,QAAU,QACrC,OAAQ,OAAOI,GAAW,SAAWA,EAAS,EAC9C,WAAY,KAAK,IAAI,EAAIf,CAC3B,CAAC,CACH,CAAC,CACH,CAAC,CACH,CAEA,eAAeE,EAAQT,EAA2CL,EAAiCY,EAAyC,CAC1I,IAAMgB,EAAM9B,EAASO,EAAO,IAAKL,CAAM,EACjC6B,EAAkC,CAAC,EACzC,GAAIxB,EAAO,QAAS,OAAW,CAACY,EAAGd,CAAC,IAAK,OAAO,QAAQE,EAAO,OAAO,EAAGwB,EAAQZ,CAAC,EAAInB,EAASK,EAAGH,CAAM,EACxG,IAAM8B,EAAOzB,EAAO,SAAW,OAASA,EAAO,SAAW,SAAW,OAAaA,EAAO,KAAOP,EAASO,EAAO,KAAML,CAAM,EAAI,OAC1H+B,EAAK,IAAI,gBACTC,EAAQ,WAAW,IAAMD,EAAG,MAAM,EAAG1B,EAAO,SAAS,EAC3D,GAAI,CACF,IAAM4B,EAAM,MAAM,MAAML,EAAK,CAAE,OAAQvB,EAAO,OAAQ,QAAAwB,EAAS,KAAAC,EAAM,OAAQC,EAAG,MAAO,CAAC,EAClFG,GAAQ,MAAMD,EAAI,KAAK,GAAG,MAAM,EAAGpC,CAAU,EACnD,MAAO,CACL,GAAIoC,EAAI,GACR,OAAQC,EACR,OAAQD,EAAI,OACZ,WAAY,KAAK,IAAI,EAAIrB,CAC3B,CACF,OAASuB,EAAP,CACA,MAAO,CACL,GAAI,GACJ,OAAQ,GACR,OAAQA,GAAG,SAAW,OAAOA,CAAC,EAC9B,OAAQ,EACR,WAAY,KAAK,IAAI,EAAIvB,CAC3B,CACF,QAAE,CACA,aAAaoB,CAAK,CACpB,CACF","names":["exec","MAX_OUTPUT","template","s","values","_","name","v","resolveInputs","action","raw","out","def","n","runAction","rawInputs","start","runShell","runHttp","cmd","env","k","cwd","resolve","settled","finish","r","err","stdout","stderr","errs","status","url","headers","body","ac","timer","res","text","e"]}
|
package/dist/cli.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import{a as s}from"./chunk-
|
|
2
|
+
import{a as s}from"./chunk-IFQQVDM6.js";import"./chunk-2B2DIQKD.js";import"./chunk-CNNLREHD.js";import"./chunk-FUYZUGNQ.js";import"./chunk-SZDACK6O.js";import"./chunk-GV7S5BAX.js";import"./chunk-GSX4NK2N.js";import"./chunk-BLRLUF2H.js";import"./chunk-EQNM3TOF.js";import"./chunk-N67JZAXU.js";import"./chunk-AFRHKA7B.js";import"./chunk-EW27SCCC.js";import"./chunk-ZE2YFX4K.js";import"./chunk-AGINLNAW.js";import"./chunk-SFQUP3BP.js";import"./chunk-K6MC66D6.js";import"./chunk-AANSVC5A.js";import"./chunk-5GDCJ2SF.js";import"./chunk-CDNWCYF7.js";import"./chunk-5XZ73VM4.js";import"./chunk-5F3J55LG.js";import"./chunk-WJXU5F4Z.js";import"./chunk-4MREHZP5.js";import"./chunk-VWTBHLMX.js";import"./chunk-7P5QRX5W.js";import"./chunk-JTJIPNXY.js";import"./chunk-64P4QHSZ.js";import"./chunk-BFZUG66X.js";import"./chunk-SR3X25TN.js";import"./chunk-53NRX2NA.js";import"./chunk-A6BKSZQA.js";import"./chunk-JGXE2YNV.js";import"./chunk-VJUTQAPJ.js";import"./chunk-DJEZ2HVU.js";import"./chunk-DSYKYZMT.js";import"./chunk-IKBHHTIT.js";import"./chunk-QOYAX2FT.js";import"./chunk-4YCH6IZV.js";process.on("SIGINT",()=>process.exit(0));process.on("SIGTERM",()=>process.exit(0));async function o(){let r=await s();if(process.argv.slice(2).length===0){r.outputHelp();return}r.parse()}o();
|
|
3
3
|
//# sourceMappingURL=cli.js.map
|
package/dist/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/cli.ts"],"sourcesContent":["#!/usr/bin/env node\nimport { buildProgram } from \"@/program\"\n\nprocess.on(\"SIGINT\", () => process.exit(0))\nprocess.on(\"SIGTERM\", () => process.exit(0))\n\nasync function main() {\n const program = await buildProgram()\n\n const args = process.argv.slice(2)\n if (args.length === 0) {\n program.outputHelp()\n return\n }\n\n program.parse()\n}\n\nmain()\n"],"mappings":";
|
|
1
|
+
{"version":3,"sources":["../src/cli.ts"],"sourcesContent":["#!/usr/bin/env node\nimport { buildProgram } from \"@/program\"\n\nprocess.on(\"SIGINT\", () => process.exit(0))\nprocess.on(\"SIGTERM\", () => process.exit(0))\n\nasync function main() {\n const program = await buildProgram()\n\n const args = process.argv.slice(2)\n if (args.length === 0) {\n program.outputHelp()\n return\n }\n\n program.parse()\n}\n\nmain()\n"],"mappings":";ojCAGA,QAAQ,GAAG,SAAU,IAAM,QAAQ,KAAK,CAAC,CAAC,EAC1C,QAAQ,GAAG,UAAW,IAAM,QAAQ,KAAK,CAAC,CAAC,EAE3C,eAAeA,GAAO,CACpB,IAAMC,EAAU,MAAMC,EAAa,EAGnC,GADa,QAAQ,KAAK,MAAM,CAAC,EACxB,SAAW,EAAG,CACrBD,EAAQ,WAAW,EACnB,OAGFA,EAAQ,MAAM,CAChB,CAEAD,EAAK","names":["main","program","buildProgram"]}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{c as a,d as b,e as c,f as d}from"./chunk-
|
|
2
|
-
//# sourceMappingURL=config-
|
|
1
|
+
import{c as a,d as b,e as c,f as d}from"./chunk-5GDCJ2SF.js";import"./chunk-4YCH6IZV.js";export{a as daemonConfigSchema,b as expandEnvVars,c as loadDaemonConfig,d as validateWorkspaces};
|
|
2
|
+
//# sourceMappingURL=config-RWHSEE4N.js.map
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{a as U}from"./chunk-4ITQP3XL.js";import{a as yt,b as re,c as ae,d as vt,e as xt,f as Ct,i as bt,j as $t,k as Tt}from"./chunk-
|
|
1
|
+
import{a as U}from"./chunk-4ITQP3XL.js";import{a as yt,b as re,c as ae,d as vt,e as xt,f as Ct,i as bt,j as $t,k as Tt}from"./chunk-BLRLUF2H.js";import"./chunk-EQNM3TOF.js";import"./chunk-N67JZAXU.js";import"./chunk-AFRHKA7B.js";import"./chunk-EW27SCCC.js";import"./chunk-ZE2YFX4K.js";import{A as H,B as E,C as I,a as be,b as $e,c as Te,d as je,e as _e,f as Ue,g as Be,h as We,i as qe,j as Ve,k as Ye,l as F,m as Q,n as Ze,o as et,p as tt,q as j,r as st,s as ot,t as nt,u as P,v as Z,w as it,x as rt,y as at,z as ht}from"./chunk-AGINLNAW.js";import{a as X,b as M,c as _}from"./chunk-SFQUP3BP.js";import{f as Pt}from"./chunk-K6MC66D6.js";import"./chunk-AANSVC5A.js";import{c as kt,e as wt,f as St}from"./chunk-5GDCJ2SF.js";import"./chunk-CDNWCYF7.js";import{a as lt,b as ct,c as dt,d as pt,i as ut}from"./chunk-5XZ73VM4.js";import"./chunk-5F3J55LG.js";import"./chunk-WJXU5F4Z.js";import"./chunk-4MREHZP5.js";import"./chunk-VWTBHLMX.js";import{a as gt,b as mt,e as ft}from"./chunk-7P5QRX5W.js";import"./chunk-JTJIPNXY.js";import"./chunk-64P4QHSZ.js";import"./chunk-BFZUG66X.js";import"./chunk-SR3X25TN.js";import"./chunk-53NRX2NA.js";import"./chunk-A6BKSZQA.js";import{a as Re,b as Ae,c as Me,d as Ee,e as Ie,f as Oe,g as Ge,h as De,i as Le,j as Ne,k as Fe,l as A}from"./chunk-JGXE2YNV.js";import{a as m}from"./chunk-VJUTQAPJ.js";import{a as He,b as Je,c as N,d as Ke}from"./chunk-DJEZ2HVU.js";import{a as ze,b as Xe,e as Qe}from"./chunk-DSYKYZMT.js";import"./chunk-IKBHHTIT.js";import"./chunk-QOYAX2FT.js";import"./chunk-4YCH6IZV.js";import{execa as Rt}from"execa";import{existsSync as le,promises as ee}from"fs";import x from"path";import pe from"node-fetch";async function At(n,e){let t=n.split("/");if(t.length<2)throw new Error(`Invalid skill package ID: ${n}. Expected format: owner/repo`);let s=t[0],i=t[1],o=t[2];try{let a=o?`${s}/${i}/${o}`:`${s}/${i}`;await Rt("npx",["-y","skills","add",a],{cwd:e,stdio:"pipe"}),m.success(`Installed skill package: ${n}`);let r=x.resolve(e,".skills",`${s}_${i}`);if(le(r))return await de(r,n);let l=x.resolve(e,".skills");return le(l)?await de(l,n):[]}catch{return m.info(`Fetching skills directly from GitHub: ${s}/${i}`),await Mt(s,i,o,e)}}async function Mt(n,e,t,s){let i=[];try{let o=`https://api.github.com/repos/${n}/${e}/git/trees/main?recursive=1`,a=await pe(o);if(!a.ok)throw new Error(`GitHub API error: ${a.status}`);let l=(await a.json()).tree.filter(c=>c.type==="blob"&&c.path.endsWith("SKILL.md"));if(t){let c=l.find(g=>g.path.includes(`/${t}/`)||g.path===`${t}/SKILL.md`);if(c){let g=await ce(n,e,c.path,s);g&&i.push(g)}}else for(let c of l){let g=await ce(n,e,c.path,s);g&&i.push(g)}}catch(o){m.error(`Failed to fetch skills from GitHub: ${o.message}`)}return i}async function ce(n,e,t,s){try{let i=`https://raw.githubusercontent.com/${n}/${e}/main/${t}`,o=await pe(i);if(!o.ok)return null;let a=await o.text(),r=N(a);if(r){r.source="remote",r.packageId=`${n}/${e}`;let l=x.dirname(t),c=x.resolve(s,".skills",`${n}_${e}`,l);await ee.mkdir(c,{recursive:!0}),await ee.writeFile(x.resolve(c,"SKILL.md"),a),r.path=x.resolve(c,"SKILL.md")}return r}catch{return null}}async function de(n,e){let t=[],{default:s}=await import("fast-glob"),i=await s.glob("**/SKILL.md",{cwd:n,deep:5});for(let o of i)try{let a=x.resolve(n,o),r=await ee.readFile(a,"utf8"),l=N(r);l&&(l.source="remote",l.path=a,l.packageId=e,t.push(l))}catch{}return t}async function Et(n,e,t,s,i){let o=["---",`name: ${n}`,`description: ${e}`];if(s?.length){o.push("tags:");for(let a of s)o.push(` - ${a}`)}if(i?.length){o.push("globs:");for(let a of i)o.push(` - ${a}`)}return o.push("---"),`${o.join(`
|
|
2
2
|
`)}
|
|
3
3
|
|
|
4
4
|
${t}`}async function It(n){let{loadLocalSkills:e}=await import("./loader-5CA3O5GM.js");return e(n)}async function Ot(n,e,t,s,i){let a=[{role:"system",content:`You are a skill author for the Agent Skills ecosystem (skills.sh).
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{a}from"./chunk-IFQQVDM6.js";import"./chunk-2B2DIQKD.js";import"./chunk-CNNLREHD.js";import"./chunk-FUYZUGNQ.js";import"./chunk-SZDACK6O.js";import"./chunk-GV7S5BAX.js";import"./chunk-GSX4NK2N.js";import"./chunk-BLRLUF2H.js";import"./chunk-EQNM3TOF.js";import"./chunk-N67JZAXU.js";import"./chunk-AFRHKA7B.js";import"./chunk-EW27SCCC.js";import"./chunk-ZE2YFX4K.js";import"./chunk-AGINLNAW.js";import"./chunk-SFQUP3BP.js";import"./chunk-K6MC66D6.js";import"./chunk-AANSVC5A.js";import"./chunk-5GDCJ2SF.js";import"./chunk-CDNWCYF7.js";import"./chunk-5XZ73VM4.js";import"./chunk-5F3J55LG.js";import"./chunk-WJXU5F4Z.js";import"./chunk-4MREHZP5.js";import"./chunk-VWTBHLMX.js";import"./chunk-7P5QRX5W.js";import"./chunk-JTJIPNXY.js";import"./chunk-64P4QHSZ.js";import"./chunk-BFZUG66X.js";import"./chunk-SR3X25TN.js";import"./chunk-53NRX2NA.js";import"./chunk-A6BKSZQA.js";import"./chunk-JGXE2YNV.js";import"./chunk-VJUTQAPJ.js";import"./chunk-DJEZ2HVU.js";import"./chunk-DSYKYZMT.js";import"./chunk-IKBHHTIT.js";import"./chunk-QOYAX2FT.js";import"./chunk-4YCH6IZV.js";export{a as buildProgram};
|
|
2
|
+
//# sourceMappingURL=program-JEKM7SCS.js.map
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{g as a,h as b,i as c}from"./chunk-
|
|
2
|
-
//# sourceMappingURL=registry-
|
|
1
|
+
import{g as a,h as b,i as c}from"./chunk-5XZ73VM4.js";import"./chunk-5F3J55LG.js";import"./chunk-WJXU5F4Z.js";import"./chunk-4MREHZP5.js";import"./chunk-VWTBHLMX.js";import"./chunk-7P5QRX5W.js";import"./chunk-JTJIPNXY.js";import"./chunk-64P4QHSZ.js";import"./chunk-BFZUG66X.js";import"./chunk-SR3X25TN.js";import"./chunk-53NRX2NA.js";import"./chunk-A6BKSZQA.js";import"./chunk-JGXE2YNV.js";import"./chunk-VJUTQAPJ.js";import"./chunk-DSYKYZMT.js";import"./chunk-IKBHHTIT.js";import"./chunk-QOYAX2FT.js";import"./chunk-4YCH6IZV.js";export{c as AgentRegistry,b as getGlobalRegistry,a as setGlobalRegistry};
|
|
2
|
+
//# sourceMappingURL=registry-EGKDMVSP.js.map
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{e as a,f as b}from"./chunk-K6MC66D6.js";import"./chunk-AANSVC5A.js";import"./chunk-5GDCJ2SF.js";import"./chunk-4MREHZP5.js";import"./chunk-VJUTQAPJ.js";import"./chunk-4YCH6IZV.js";export{b as CronScheduler,a as getNextCronDate};
|
|
2
|
+
//# sourceMappingURL=scheduler-ED4FCI2Y.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|