@kanonak-protocol/cli 4.8.0 → 4.9.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.
Files changed (2) hide show
  1. package/dist/index.js +1 -1
  2. package/package.json +3 -3
package/dist/index.js CHANGED
@@ -138,7 +138,7 @@ ${l.join(", ")}.`),s>0&&(console.error("Integrity verification FAILED \u2014 a p
138
138
  `)}}async function Ba(n,e){if(n.endsWith(".kan.yml")){let i=Aa(n);if(!Da(i))throw new Error(`kanonak hash: file not found: ${i}`);let c=Ta(i,"utf-8");return{document:e.parse(c),source:i}}let t=Fa(n);if(t.kind!=="package")throw new Error(`kanonak hash: expected a package address (publisher/package[@version]) or a path ending in .kan.yml; got ${t.kind} address "${n}"`);let r=await(await $(process.cwd(),e)).getDocumentsByNamespaceAsync(t.publisher,t.package_);if(r.length===0)throw new Error(`kanonak hash: could not find ${n} in local workspace, global cache, or publisher HTTP`);let a=t.version?`${t.version.major}.${t.version.minor}.${t.version.patch}`:void 0,s=Ma(r,a?{requestedVersion:a}:{});if(!s.chosen){let i=a?`@${a}`:"";throw new Error(`kanonak hash: no version of ${t.publisher}/${t.package_}${i} available across local/cache/HTTP`)}return{document:s.chosen,source:n}}function qa(n,e,t){let o=new Set(["kanonak.org/core-kanonak"]);for(let a of n.metadata.allImports??[])o.add(`${a.publisher??"kanonak.org"}/${a.packageName}`);let r=[...o].filter(a=>!e.packages[a]);if(r.length>0)throw new Error(`kanonak hash --frozen: kanonak.lock (${t}) is missing pins for: ${r.join(", ")}. Run 'kanonak install' to refresh the lock.`)}function Wa(n){return n.endsWith(".kan.yml")?N(Ea(n)):process.cwd()}import{Command as mt}from"commander";function W(n){return`${P}/${C}/${n}`}var He={[W("fetch-and-deploy")]:(n,e,t,o)=>n.add(e,t[0],o),[W("remove-deployed")]:(n,e,t,o)=>n.remove(e,t[0],o),[W("list-deployed")]:(n,e,t,o)=>n.list(e,o),[W("update-deployed")]:(n,e,t,o)=>n.update(e,t[0],o),[W("search-available")]:(n,e,t,o)=>n.search(e,o),[W("show-info")]:(n,e,t,o)=>n.info(e,t[0],o)};function ft(n,e,t){for(let o of e){let r=new mt(o.commandName).description(o.description.trim());for(let a of o.commands){let s=r.command(Ga(a));s.description(a.description);for(let i of a.arguments)if(i.isOption){let c=i.defaultValue!=null?`--${i.argumentName} [value]`:`--${i.argumentName} <value>`;s.option(c,"",i.defaultValue)}s.action(async(...i)=>{let c=Ja(i);await Ya(t,o,a,i,c)})}n.addCommand(r)}}function Ga(n){let e=n.arguments.filter(t=>!t.isOption).map(t=>t.required?`<${t.argumentName}>`:`[${t.argumentName}]`);return[n.subcommandName,...e].join(" ")}function Ja(n){for(let e=n.length-1;e>=0;e--)if(n[e]&&typeof n[e]=="object"&&!(n[e]instanceof mt))return n[e];return{}}async function Ya(n,e,t,o,r){let a=[];for(let i of o)if(typeof i=="string")a.push(i);else break;t.actionKey||(console.error(`Capability subcommand '${t.subcommandName}' has no resolved \`performs:\` Action. Every CapabilityCommand must declare a performs value pointing at a named Action instance from the capabilities ontology. Known actions: ${Object.keys(He).join(", ")}.`),process.exit(1));let s=He[t.actionKey];s||(console.error(`Capability subcommand '${t.subcommandName}' references unknown Action '${t.actionKey}'. Known actions: ${Object.keys(He).join(", ")}.`),process.exit(1)),await s(n,e,a,r)}import{existsSync as gt,readFileSync as Xa,statSync as ht}from"fs";import{resolve as Za}from"path";import{KanonakObjectParser as Qa,PublisherIndex as ze,PublisherConfigResolver as ei,formatVersion as kt,pickHighestDocument as ni}from"@kanonak-protocol/sdk";import{SingleDocumentRepository as yt}from"@kanonak-protocol/sdk/uri-helpers";import{uriKey as G,findSubjectsByType as wt}from"@kanonak-protocol/sdk/uri-helpers";var se=class{constructor(e,t,o,r,a,s){this.fileCache=e;this.parser=t;this.publisherIndex=o;this.fetchFn=r;this.handlerRegistry=a;this.repository=s}fileCache;parser;publisherIndex;fetchFn;handlerRegistry;repository;objectParser=new Qa;async add(e,t,o){let r=this.tryLoadFromLocalFile(t);if(r){this.fileCache.put(r.publisher,r.packageName,r.version,r.content),await this.deployFromDoc(e,r.doc,r.publisher,r.packageName,r.version,void 0,`local file ${t}`,o);return}let a=T(t);a||(console.error(`Invalid package reference: "${t}"`),console.error(""),console.error("Accepted forms:"),console.error(" publisher/package (install all instances, latest version)"),console.error(" publisher/package@version (install all instances, pinned)"),console.error(" publisher/package/instance (install one instance, latest version)"),console.error(" publisher/package@version/instance (install one instance, pinned)"),console.error(" ./path/to/file.kan.yml (install all instances from a local document)"),console.error(""),console.error("Tip: copy a URI directly from `kanonak "+e.commandName+" search`."),process.exit(1));let{publisher:s,packageName:i,version:c,instanceName:l}=a,u=await this.repository.getDocumentsByNamespaceAsync(s,i);if(u.length>0){let g=ni(u,{requestedVersion:c??void 0});if(g.chosen){let f=g.chosen.metadata.namespace_;(!f||!f.version)&&(console.error(`Document for ${s}/${i} is missing namespace metadata.`),process.exit(1));let m=kt(f.version);this.fileCache.put(s,i,m,this.parser.save(g.chosen)),await this.deployFromDoc(e,g.chosen,s,i,m,l??void 0,`${s}/${i}@${m}`,o);return}}let p=c??await this.publisherIndex.getHighestVersion(s,i);p||(console.error(`Could not resolve version for "${s}/${i}".`),await this.printPackageSuggestions(s,i,e.commandName),process.exit(1));let d=this.fileCache.get(s,i,p);if(!d){let g=await this.publisherIndex.getPackageUrl(s,i,p),f=await this.fetchFn(g,s);f.ok||(f.status===404?(console.error(`Package ${s}/${i}@${p} not found at ${g}.`),console.error(`The publisher index lists this version but the file is missing \u2014 it may have been unpublished. Try \`kanonak ${e.commandName} search\` to see the current catalogue.`)):console.error(`Failed to fetch ${g} (${f.status} ${f.statusText}).`),process.exit(1)),d=await f.text(),this.fileCache.put(s,i,p,d)}await this.deployFromDoc(e,this.parser.parse(d),s,i,p,l??void 0,`${s}/${i}@${p}`,o)}tryLoadFromLocalFile(e){if(!(/^[.\/\\]/.test(e)||/^[A-Za-z]:[\\/]/.test(e)||e.endsWith(".kan.yml")||gt(e)&&ht(e).isFile()))return;let o=Za(e);(!gt(o)||!ht(o).isFile())&&(console.error(`Local file not found: ${e}`),process.exit(1));let r=Xa(o,"utf-8"),a=this.parser.parse(r),s=a.metadata.namespace_;return(!s||!s.version)&&(console.error(`${e} has no namespace metadata; cannot determine publisher/package/version. A Kanonak document must declare \`type: Package\` with publisher and version.`),process.exit(1)),{doc:a,content:r,publisher:s.publisher,packageName:s.package_,version:kt(s.version)}}async deployFromDoc(e,t,o,r,a,s,i,c){let l=new yt(t,this.repository),u=await this.objectParser.parseKanonaks(l),p=bt(e.managesTypeKey);p||(console.error(`Capability "${e.commandName}" has no resolved managesType.`),process.exit(1));let d=wt(u,p);d.length===0&&(console.error(`${i} does not contain any ${G(p)} instances.`),process.exit(1));let g=d;if(s&&(g=d.filter(h=>h.name===s),g.length===0)){console.error(`Instance "${s}" not found in ${i}.`),console.error(""),console.error(`Available ${G(p)} instance(s):`);for(let h of d)console.error(` - ${h.name}`);console.error(""),console.error("To install all of them, drop the instance suffix:"),console.error(` kanonak ${e.commandName} add ${o}/${r}`),process.exit(1)}let f=s?`${s} from ${i}`:`${g.length} ${G(p)} instance(s) from ${i}`;console.log(`Installing ${f}...`);let m=this.handlerRegistry.get(e.deploymentTargetKey);m?await m.deploy({instances:g,allKanonaks:u,repository:this.repository,options:c}):console.log(`Cached ${o}/${r}@${a} (no deployment handler for "${e.deploymentTargetKey}")`)}async printPackageSuggestions(e,t,o){let r;try{r=await this.publisherIndex.listLatestPackages(e)}catch{return}let a=r.map(s=>({name:s.packageName,version:s.version,score:ti(t,s.packageName)})).filter(s=>s.score>0).sort((s,i)=>i.score-s.score).slice(0,5);if(a.length!==0){console.error(""),console.error("Did you mean one of:");for(let s of a)console.error(` kanonak ${o} add ${e}/${s.name}`)}}async remove(e,t,o){await this.requireHandler(e).undeploy(t,{repository:this.repository,options:o})}async list(e,t){let r=await this.requireHandler(e).list({repository:this.repository,options:t}),a=e.managesTypeKey||"managed";if(r.length===0){console.log(`No ${a} instances installed.`);return}console.log(`Installed ${a} instances:
139
139
  `);for(let s of r){let i=s.publisher?`${s.publisher}/${s.package_}@${s.version}`:"unmanaged";console.log(` ${s.name} (${i}) ${s.path}`)}}async update(e,t,o){let a=await this.requireHandler(e).list({repository:this.repository,options:o}),s=t?a.filter(c=>c.name===t):a.filter(c=>c.publisher);if(s.length===0){console.log(t?`"${t}" not found.`:"No managed instances to update.");return}let i=0;for(let c of s){let l=await this.publisherIndex.getHighestVersion(c.publisher,c.package_);!l||l===c.version||(console.log(`Updating ${c.name}: ${c.version} \u2192 ${l}`),await this.add(e,`${c.publisher}/${c.package_}@${l}`,o),i++)}console.log(i===0?"All instances are up to date.":`
140
140
  Updated ${i} instance(s).`)}async search(e,t){let o=t.publisher??"kanonak.org",r=bt(e.managesTypeKey);if(!r){console.error("Capability has no resolved managesType; nothing to search for.");return}console.log(`Searching ${o} for ${G(r)} instances...
141
- `);let a=new ei,s=await a.getConfig(o),i=a.resolveIndexUrl(o,s),c=await this.fetchFn(i,o);if(!c.ok){console.error(`Failed to fetch package index from ${o}.`);return}let l=await c.text(),u=ze.parseIndex(l);if(u.size===0){console.error(`No packages found for publisher "${o}".`);return}let p=new Map;for(let[m,h]of u){let k=[...h].sort((y,w)=>{let b=ze.parseVersion(y),v=ze.parseVersion(w);return!b||!v?0:b.major!==v.major?v.major-b.major:b.minor!==v.minor?v.minor-b.minor:v.patch-b.patch});p.set(m,k[0])}let d=[],g=0;for(let[m,h]of p){let k=this.fileCache.get(o,m,h);if(!k)try{let y=await this.publisherIndex.getPackageUrl(o,m,h),w=await this.fetchFn(y,o);if(!w.ok)continue;k=await w.text(),this.fileCache.put(o,m,h,k)}catch{continue}try{let y=this.parser.parse(k),w=new yt(y,this.repository),b=await this.objectParser.parseKanonaks(w),v=wt(b,r);for(let _ of v)d.push({publisher:o,package_:m,version:h,subject:_});g++}catch{continue}}if(d.length===0){console.log(`No ${G(r)} instances found across ${g} package(s).`);return}console.log(`Found ${d.length} ${G(r)} instance(s) in ${g} package(s):
141
+ `);let a=new ei(this.fetchFn),s=await a.getConfig(o),i=a.resolveIndexUrl(o,s),c=await this.fetchFn(i,o);if(!c.ok){console.error(`Failed to fetch package index from ${o}.`);return}let l=await c.text(),u=ze.parseIndex(l);if(u.size===0){console.error(`No packages found for publisher "${o}".`);return}let p=new Map;for(let[m,h]of u){let k=[...h].sort((y,w)=>{let b=ze.parseVersion(y),v=ze.parseVersion(w);return!b||!v?0:b.major!==v.major?v.major-b.major:b.minor!==v.minor?v.minor-b.minor:v.patch-b.patch});p.set(m,k[0])}let d=[],g=0;for(let[m,h]of p){let k=this.fileCache.get(o,m,h);if(!k)try{let y=await this.publisherIndex.getPackageUrl(o,m,h),w=await this.fetchFn(y,o);if(!w.ok)continue;k=await w.text(),this.fileCache.put(o,m,h,k)}catch{continue}try{let y=this.parser.parse(k),w=new yt(y,this.repository),b=await this.objectParser.parseKanonaks(w),v=wt(b,r);for(let _ of v)d.push({publisher:o,package_:m,version:h,subject:_});g++}catch{continue}}if(d.length===0){console.log(`No ${G(r)} instances found across ${g} package(s).`);return}console.log(`Found ${d.length} ${G(r)} instance(s) in ${g} package(s):
142
142
  `);let f=new Map;for(let m of d){let h=`${m.publisher}/${m.package_}@${m.version}`,k=f.get(h);k?k.push(m):f.set(h,[m])}for(let[m,h]of f){let k=h[0],y=`${k.publisher}/${k.package_}`,w=h.length===1;console.log(` ${m}`),console.log(` ${h.length} skill${w?"":"s"}:`);for(let b of h)console.log(` - ${b.subject.name}`);if(console.log(""),w)console.log(" install:"),console.log(` kanonak ${e.commandName} add ${y}/${k.subject.name}`);else{console.log(" install one of them:");for(let b of h)console.log(` kanonak ${e.commandName} add ${y}/${b.subject.name}`);console.log(" install all of them:"),console.log(` kanonak ${e.commandName} add ${y}`)}console.log("")}}async info(e,t,o){let s=(await this.requireHandler(e).list({repository:this.repository,options:o})).find(i=>i.name===t);s||(console.error(`"${t}" is not installed.`),process.exit(1)),console.log(`Name: ${s.name}`),console.log(`Type: ${e.managesTypeKey||"n/a"}`),console.log(`Publisher: ${s.publisher||"unmanaged"}`),console.log(`Package: ${s.package_||"n/a"}`),console.log(`Version: ${s.version||"n/a"}`),console.log(`Path: ${s.path}`)}requireHandler(e){let t=this.handlerRegistry.get(e.deploymentTargetKey);return t||(console.error(`No deployment handler registered for "${e.deploymentTargetKey}". Ensure the capability's deploymentTarget resolves to a DeploymentTarget instance whose URI is registered in the CLI at startup.`),process.exit(1)),t}};function bt(n){if(!n)return;let e=n.split("/");if(e.length===3)return{publisher:e[0],package_:e[1],name:e[2]}}function ti(n,e){let t=n.toLowerCase(),o=e.toLowerCase();if(t===o)return 100;if(o.includes(t)||t.includes(o))return 50;let r=new Set(t.split("-").filter(Boolean)),a=new Set(o.split("-").filter(Boolean)),s=0;for(let c of r)a.has(c)&&s++;if(s>0)return s*10;let i=oi(t,o);return i===0?100:i<=2?Math.max(1,20-i*5):0}function oi(n,e){if(n===e)return 0;if(n.length===0)return e.length;if(e.length===0)return n.length;let t=new Array(e.length+1),o=new Array(e.length+1);for(let r=0;r<=e.length;r++)t[r]=r;for(let r=0;r<n.length;r++){o[0]=r+1;for(let a=0;a<e.length;a++){let s=n[r]===e[a]?0:1;o[a+1]=Math.min(o[a]+1,t[a+1]+1,t[a]+s)}for(let a=0;a<=e.length;a++)t[a]=o[a]}return t[e.length]}var ae=class{handlers=new Map;register(e,t){this.handlers.set(e,t)}get(e){return this.handlers.get(e)??null}};import{mkdirSync as gi,rmSync as hi,existsSync as ue,readdirSync as ki,writeFileSync as yi}from"fs";import{join as pe}from"path";import{KanonakObjectParser as wi,KanonakParser as bi,computeIntegrity as vi,compareVersions as $i}from"@kanonak-protocol/sdk";import{findSubjectsByType as Si}from"@kanonak-protocol/sdk/uri-helpers";import{SingleDocumentRepository as Pi}from"@kanonak-protocol/sdk/uri-helpers";import{TransformationRunnerV3 as Ci}from"@kanonak-protocol/sdk/transformations";import{TX_V3 as Ri}from"@kanonak-protocol/sdk/transformations";import{join as Be}from"path";import{homedir as vt}from"os";import{KanonakObjectParser as ri}from"@kanonak-protocol/sdk";import{SingleDocumentRepository as si}from"@kanonak-protocol/sdk/uri-helpers";import{findSubjectsByType as St,getStringValue as ie}from"@kanonak-protocol/sdk/uri-helpers";var U="kanonak.org",F="agent-skills",Pt={publisher:U,package_:F,name:"Client"},Ct={publisher:U,package_:F,name:"clientId"},ai={publisher:U,package_:F,name:"projectSkillDir"},ii={publisher:U,package_:F,name:"userSkillDir"},ci={publisher:U,package_:F,name:"skillFileName"},Rt="agents";async function Q(n,e){let t=(n.client??_t()??Rt).toLowerCase(),o=n.scope??"project",r=await It(t,e);if(!r){let i=await li(e);throw new Error(`Unknown client "${t}". Known clients: ${i.join(", ")||"(none)"}. Add a Client instance to a package that imports kanonak.org/agent-skills and install that package to make it available.`)}let s=ie(r,o==="user"?ii:ai);if(!s)throw new Error(`Client "${t}" has no ${o==="user"?"userSkillDir":"projectSkillDir"} declared.`);return ui(s)}async function ce(n,e,t){let o=await Q(e,t);return Be(o,n)}async function qe(n,e){let t=(n.client??_t()??Rt).toLowerCase(),o=await It(t,e);return o?ie(o,ci)??"SKILL.md":"SKILL.md"}function _t(){if(process.env.CLAUDE_CODE||process.env.CLAUDE_PROJECT_DIR)return"claude-code"}var $t=new WeakMap;async function xt(n){let e=$t.get(n);if(e)return e;let t=await n.getDocumentsByNamespaceAsync(U,F);if(t.length===0)throw new Error(`Could not find ${U}/${F} in the repository. Install a skill capability (which transitively imports agent-skills) or fetch agent-skills directly to populate the cache.`);let r=[...t].sort((c,l)=>{let u=c.metadata.namespace_?.version,p=l.metadata.namespace_?.version;return!u||!p?0:u.major!==p.major?p.major-u.major:u.minor!==p.minor?p.minor-u.minor:p.patch-u.patch})[0],a=new ri,s=new si(r,n),i=await a.parseKanonaks(s);return $t.set(n,i),i}async function It(n,e){let t=await xt(e),o=St(t,Pt);for(let r of o)if(ie(r,Ct)===n)return r}async function li(n){let e=await xt(n),t=St(e,Pt),o=[];for(let r of t){let a=ie(r,Ct);a&&o.push(a)}return o}function ui(n){return n.startsWith("~/")?Be(vt(),n.slice(2)):n==="~"?vt():n.startsWith("/")||/^[A-Za-z]:[\\/]/.test(n)?n:Be(process.cwd(),n)}import{readFileSync as pi,writeFileSync as di,existsSync as mi}from"fs";import{join as Kt}from"path";import Dt from"js-yaml";var Tt="skills.lock",fi=`# This file is generated by Kanonak CLI. Do not edit manually.
143
143
  `;function le(n){let e=Kt(n,Tt);if(!mi(e))return{version:"1",lastUpdated:new Date().toISOString(),skills:{}};let t=pi(e,"utf-8"),o=Dt.load(t);return!o||typeof o!="object"||o.version!=="1"?{version:"1",lastUpdated:new Date().toISOString(),skills:{}}:{version:"1",lastUpdated:o.lastUpdated??new Date().toISOString(),skills:o.skills??{}}}function We(n,e){e.lastUpdated=new Date().toISOString();let t={};for(let a of Object.keys(e.skills).sort())t[a]=e.skills[a];e.skills=t;let o=Kt(n,Tt),r=Dt.dump(e,{lineWidth:-1,sortKeys:!1,quotingType:'"'});di(o,fi+r,"utf-8")}var Et="kanonak.org",jt="skill-to-skill-md",de=class{parser=new bi;objectParser=new wi;runner=new Ci;async deploy(e){let{instances:t,allKanonaks:o,repository:r,options:a}=e;if(t.length===0){console.error("No Skill instances to deploy.");return}let s=await _i(r,this.objectParser);if(!s){console.error(`Cannot deploy: ${Et}/${jt}@3.0.0 is not installed in the workspace or cache.`);return}let i=await this.runner.run({transformation:s,instances:t,allKanonaks:o,repository:r,parser:this.parser,objectParser:this.objectParser,outputFormat:"markdown-with-frontmatter"});if(i.length===0){console.error("No skills could be transformed from the package.");return}let c=await Q(a,r),l=await qe(a,r),u=le(c),p=t[0].namespace,{publisher:d,package_:g,version:f}=xi(p);for(let m of i){let h=await ce(m.fileName,a,r),k=ue(pe(h,l));gi(h,{recursive:!0}),yi(pe(h,l),m.content,"utf-8"),u.skills[m.fileName]={publisher:d,package_:g,version:f,resolved:d?`kanonak://${d}/${g}@${f}`:"",integrity:vi(m.content)},console.log(` ${k?"Updated":"Installed"} skill "${m.fileName}" \u2192 ${h}`)}We(c,u)}async undeploy(e,t){let{repository:o,options:r}=t,a=await ce(e,r,o);ue(a)||(console.error(`Skill "${e}" is not installed at ${a}`),process.exit(1)),hi(a,{recursive:!0,force:!0});let s=await Q(r,o),i=le(s);delete i.skills[e],We(s,i),console.log(`Removed skill "${e}" from ${a}`)}async list(e){let{repository:t,options:o}=e,r=await Q(o,t),a=le(r),s=[];for(let[c,l]of Object.entries(a.skills))s.push({name:c,publisher:l.publisher,package_:l.package_,version:l.version,path:await ce(c,o,t)});let i=await qe(o,t);if(ue(r))try{let c=ki(r,{withFileTypes:!0});for(let l of c){if(!l.isDirectory()||a.skills[l.name])continue;let u=pe(r,l.name,i);ue(u)&&s.push({name:l.name,publisher:"",package_:"",version:"",path:pe(r,l.name)})}}catch{}return s}};async function _i(n,e){let t=await n.getDocumentsByNamespaceAsync(Et,jt);if(t.length===0)return;let o=[...t].sort((r,a)=>{let s=r.metadata.namespace_?.version,i=a.metadata.namespace_?.version;return!s||!i?0:$i(i,s)});for(let r of o){let a=new Pi(r,n),s=await e.parseKanonaks(a),i=Si(s,Ri.InstanceTransformation);if(i[0])return i[0]}}function xi(n){if(!n)return{publisher:"",package_:"",version:""};let e=n.indexOf("@");if(e===-1)return{publisher:"",package_:"",version:""};let t=n.substring(0,e),o=n.substring(e+1),r=t.indexOf("/");return r===-1?{publisher:"",package_:"",version:""}:{publisher:t.substring(0,r),package_:t.substring(r+1),version:o}}import{mkdirSync as zi,rmSync as Bi,existsSync as Ye,readdirSync as qi,writeFileSync as Wi,statSync as Gi}from"fs";import{join as ge}from"path";import{KanonakObjectParser as Ji,KanonakParser as Yi,computeIntegrity as Xi}from"@kanonak-protocol/sdk";import{findSubjectsByType as Zi}from"@kanonak-protocol/sdk/uri-helpers";import{SingleDocumentRepository as Qi}from"@kanonak-protocol/sdk/uri-helpers";import{TransformationRunnerV3 as ec}from"@kanonak-protocol/sdk/transformations";import{TX_V3 as nc}from"@kanonak-protocol/sdk/transformations";import{join as At}from"path";import{homedir as Ot}from"os";import{KanonakObjectParser as Ii}from"@kanonak-protocol/sdk";import{SingleDocumentRepository as Ki}from"@kanonak-protocol/sdk/uri-helpers";import{findSubjectsByType as Lt,getStringValue as Ge,getReferenceUri as Di}from"@kanonak-protocol/sdk/uri-helpers";var M="kanonak.org",V="agent-skills",Ut={publisher:M,package_:V,name:"Client"},Ft={publisher:M,package_:V,name:"clientId"},Ti={publisher:M,package_:V,name:"projectAgentDir"},Ei={publisher:M,package_:V,name:"userAgentDir"},ji={publisher:M,package_:V,name:"agentFileFormat"},Ai="agents";function Oi(){if(process.env.CLAUDE_CODE||process.env.CLAUDE_PROJECT_DIR)return"claude-code"}async function me(n,e){let t=(n.client??Oi()??Ai).toLowerCase(),o=n.scope??"project",r=await Ni(t,e);if(!r){let u=await Li(e);throw new Error(`Unknown client "${t}". Known clients: ${u.join(", ")||"(none)"}. Add a Client instance to a package that imports kanonak.org/agent-skills and install that package to make it available.`)}let s=Ge(r,o==="user"?Ei:Ti);if(!s)throw new Error(`Client "${t}" has no ${o==="user"?"userAgentDir":"projectAgentDir"} declared.`);let c=Di(r,ji)?.name==="toml"?"toml":"markdown-frontmatter",l=c==="toml"?".toml":".md";return{agentsDir:Ui(s),format:c,fileExtension:l}}var Nt=new WeakMap;async function Mt(n){let e=Nt.get(n);if(e)return e;let t=await n.getDocumentsByNamespaceAsync(M,V);if(t.length===0)throw new Error(`Could not find ${M}/${V} in the repository. Install a capability that imports agent-skills to populate the cache.`);let r=[...t].sort((c,l)=>{let u=c.metadata.namespace_?.version,p=l.metadata.namespace_?.version;return!u||!p?0:u.major!==p.major?p.major-u.major:u.minor!==p.minor?p.minor-u.minor:p.patch-u.patch})[0],a=new Ii,s=new Ki(r,n),i=await a.parseKanonaks(s);return Nt.set(n,i),i}async function Ni(n,e){let t=await Mt(e),o=Lt(t,Ut);for(let r of o)if(Ge(r,Ft)===n)return r}async function Li(n){let e=await Mt(n),t=Lt(e,Ut),o=[];for(let r of t){let a=Ge(r,Ft);a&&o.push(a)}return o}function Ui(n){return n.startsWith("~/")?At(Ot(),n.slice(2)):n==="~"?Ot():n.startsWith("/")||/^[A-Za-z]:[\\/]/.test(n)?n:At(process.cwd(),n)}import{readFileSync as Fi,writeFileSync as Mi,existsSync as Vi}from"fs";import{join as Vt}from"path";import Ht from"js-yaml";var zt="agents.lock",Hi=`# This file is generated by Kanonak CLI. Do not edit manually.
144
144
  `;function fe(n){let e=Vt(n,zt);if(!Vi(e))return{version:"1",lastUpdated:new Date().toISOString(),agents:{}};let t=Fi(e,"utf-8"),o=Ht.load(t);return!o||typeof o!="object"||o.version!=="1"?{version:"1",lastUpdated:new Date().toISOString(),agents:{}}:{version:"1",lastUpdated:o.lastUpdated??new Date().toISOString(),agents:o.agents??{}}}function Je(n,e){e.lastUpdated=new Date().toISOString();let t={};for(let a of Object.keys(e.agents).sort())t[a]=e.agents[a];e.agents=t;let o=Vt(n,zt),r=Ht.dump(e,{lineWidth:-1,sortKeys:!1,quotingType:'"'});Mi(o,Hi+r,"utf-8")}var Bt="kanonak.org",qt="agent-to-agent-file",he=class{parser=new Yi;objectParser=new Ji;runner=new ec;async deploy(e){let{instances:t,allKanonaks:o,repository:r,options:a}=e;if(t.length===0){console.error("No Agent instances to deploy.");return}let{agentsDir:s,format:i,fileExtension:c}=await me(a,r),l=await tc(r,this.objectParser);if(!l){console.error(`Cannot deploy: ${Bt}/${qt}@3.0.0 is not installed in the workspace or cache.`);return}let u=i==="toml"?"toml":"markdown-with-frontmatter",p=await this.runner.run({transformation:l,instances:t,allKanonaks:o,repository:r,parser:this.parser,objectParser:this.objectParser,outputFormat:u});if(p.length===0){console.error("No agents could be transformed from the package.");return}zi(s,{recursive:!0});let d=fe(s),g=t[0].namespace,{publisher:f,package_:m,version:h}=rc(g);for(let k of p){let y=`${k.fileName}${c}`,w=ge(s,y),b=Ye(w);Wi(w,k.content,"utf-8"),d.agents[k.fileName]={publisher:f,package_:m,version:h,resolved:f?`kanonak://${f}/${m}@${h}`:"",integrity:Xi(k.content),fileName:y},console.log(` ${b?"Updated":"Installed"} agent "${k.fileName}" \u2192 ${w}`)}Je(s,d)}async undeploy(e,t){let{repository:o,options:r}=t,{agentsDir:a}=await me(r,o),s=fe(a),i=s.agents[e];i||(console.error(`Agent "${e}" is not installed at ${a}`),process.exit(1));let c=ge(a,i.fileName);Ye(c)&&Bi(c,{force:!0}),delete s.agents[e],Je(a,s),console.log(`Removed agent "${e}" from ${c}`)}async list(e){let{repository:t,options:o}=e,{agentsDir:r}=await me(o,t),a=fe(r),s=[];for(let[i,c]of Object.entries(a.agents))s.push({name:i,publisher:c.publisher,package_:c.package_,version:c.version,path:ge(r,c.fileName)});if(Ye(r))try{let i=qi(r,{withFileTypes:!0});for(let c of i){if(!c.isFile()||c.name==="agents.lock")continue;let l=ge(r,c.name),u=oc(c.name);if(!a.agents[u]){try{if(!Gi(l).isFile())continue}catch{continue}s.push({name:u,publisher:"",package_:"",version:"",path:l})}}}catch{}return s}};async function tc(n,e){let t=await n.getDocumentsByNamespaceAsync(Bt,qt);if(t.length===0)return;let o=new Qi(t[0],n),r=await e.parseKanonaks(o);return Zi(r,nc.InstanceTransformation)[0]}function oc(n){let e=n.lastIndexOf(".");return e===-1?n:n.substring(0,e)}function rc(n){if(!n)return{publisher:"",package_:"",version:""};let e=n.indexOf("@");if(e===-1)return{publisher:"",package_:"",version:""};let t=n.substring(0,e),o=n.substring(e+1),r=t.indexOf("/");return r===-1?{publisher:"",package_:"",version:""}:{publisher:t.substring(0,r),package_:t.substring(r+1),version:o}}var fc=cc(ic(import.meta.url)),gc=JSON.parse(ac(lc(fc,"..","package.json"),"utf-8")),R=new sc;R.name("kanonak").description("Kanonak Protocol CLI - Validate and resolve Kanonak ontology packages").version(gc.version);R.command("validate <path>").description("Validate .kan.yml file(s). Resolves imports via HTTP from publisher domains.").action(async n=>{await rn(n)});R.command("install [package]").description("Install a package and its dependencies, or install all from kanonak.lock.").action(async n=>{await sn(n)});R.command("deps <path>").description("Show resolved dependency tree for a .kan.yml file.").action(async n=>{await cn(n)});R.command("login <publisher>").description("Authenticate with a package publisher using OAuth 2.0.").action(async n=>{await mn(n)});R.command("logout <publisher>").description("Revoke tokens and remove stored credentials for a publisher.").action(async n=>{await fn(n)});R.command("hash <target>").description("Print the canonical structural hash (sha256:\u2026) of a Kanonak package.").option("-v, --verbose","Also print the canonical form on stderr.").option("--frozen","Resolve identity strictly through kanonak.lock; error if the lock or any needed pin is missing.").action(async(n,e)=>{await dt(n,e)});R.addCommand(In());R.addCommand(On());R.addCommand(Vn());R.addCommand(Hn());R.addCommand(Bn());R.addCommand(Qn());R.addCommand(st());R.addCommand(pt());R.addCommand(at());async function hc(){try{let n=new K,e=new uc,t=new dc,o=mc(t),r=new pc({fetchFn:o}),a=await $(process.cwd(),e),s=new ae;s.register("kanonak.org/capabilities/agent-skill-deployment",new de),s.register("kanonak.org/agent-capabilities/agent-instance-deployment",new he);let i=await Rn(n,e,a),c=new se(n,e,r,o,s,a);ft(R,i,c)}catch{}}await hc();R.parse();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kanonak-protocol/cli",
3
- "version": "4.8.0",
3
+ "version": "4.9.0",
4
4
  "description": "Command-line tool for the Kanonak Protocol — validate, resolve, preview, and publish semantic ontology packages.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -35,8 +35,8 @@
35
35
  "semantic-web"
36
36
  ],
37
37
  "dependencies": {
38
- "@kanonak-protocol/sdk": "^4.8.0",
39
- "@kanonak-protocol/types": "^4.8.0",
38
+ "@kanonak-protocol/sdk": "^4.9.0",
39
+ "@kanonak-protocol/types": "^4.9.0",
40
40
  "commander": "^13.0.0",
41
41
  "js-yaml": "^4.1.1"
42
42
  },