@kanonak-protocol/cli 4.4.0 → 4.6.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.
@@ -24,4 +24,5 @@
24
24
  */
25
25
  export declare function hashCommand(target: string, options?: {
26
26
  verbose?: boolean;
27
+ frozen?: boolean;
27
28
  }): Promise<void>;
package/dist/index.js CHANGED
@@ -1,21 +1,21 @@
1
1
  #!/usr/bin/env node
2
- import{Command as Xi}from"commander";import{readFileSync as Zi}from"fs";import{fileURLToPath as Qi}from"url";import{dirname as ec,join as nc}from"path";import{KanonakParser as tc,PublisherIndex as oc,CredentialStore as rc,createAuthenticatedFetch as sc}from"@kanonak-protocol/sdk";import{readFileSync as so,statSync as ao}from"fs";import{resolve as io,dirname as co}from"path";import{KanonakParser as lo,KanonakObjectValidator as uo,ValidationSeverity as on}from"@kanonak-protocol/sdk";import{readdirSync as no}from"fs";import{join as to,dirname as oo,basename as tn}from"path";import{LocalFirstRepository as kc,buildLocalFirstRepository as ro}from"@kanonak-protocol/sdk";import{mkdirSync as Jt,readFileSync as en,writeFileSync as nn,existsSync as we,appendFileSync as Yt}from"fs";import{join as Xt,dirname as Zt,isAbsolute as Qt}from"path";import{getGlobalCachePath as eo}from"@kanonak-protocol/sdk";var K=class{constructor(e=eo()){this.cacheDir=e;this.isProjectLocal=!Qt(e)}cacheDir;gitignoreChecked=!1;isProjectLocal;get(e,t,o){let r=this.getPath(e,t,o);return we(r)?en(r,"utf-8"):null}put(e,t,o,r){let a=this.getPath(e,t,o);Jt(Zt(a),{recursive:!0}),nn(a,r,"utf-8"),this.isProjectLocal&&this.ensureGitignore()}has(e,t,o){return we(this.getPath(e,t,o))}ensureGitignore(){if(this.gitignoreChecked)return;this.gitignoreChecked=!0;let e=".gitignore",t=this.cacheDir;if(we(e)){if(en(e,"utf-8").split(`
2
+ import{Command as nc}from"commander";import{readFileSync as tc}from"fs";import{fileURLToPath as oc}from"url";import{dirname as rc,join as ac}from"path";import{KanonakParser as sc,PublisherIndex as ic,CredentialStore as cc,createAuthenticatedFetch as lc}from"@kanonak-protocol/sdk";import{readFileSync as ao,statSync as so}from"fs";import{resolve as io,dirname as co}from"path";import{KanonakParser as lo,KanonakObjectValidator as uo,ValidationSeverity as on}from"@kanonak-protocol/sdk";import{readdirSync as no}from"fs";import{join as to,dirname as oo,basename as tn}from"path";import{LocalFirstRepository as vc,buildLocalFirstRepository as ro}from"@kanonak-protocol/sdk";import{mkdirSync as Jt,readFileSync as en,writeFileSync as nn,existsSync as we,appendFileSync as Yt}from"fs";import{join as Xt,dirname as Zt,isAbsolute as Qt}from"path";import{getGlobalCachePath as eo}from"@kanonak-protocol/sdk";var K=class{constructor(e=eo()){this.cacheDir=e;this.isProjectLocal=!Qt(e)}cacheDir;gitignoreChecked=!1;isProjectLocal;get(e,t,o){let r=this.getPath(e,t,o);return we(r)?en(r,"utf-8"):null}put(e,t,o,r){let s=this.getPath(e,t,o);Jt(Zt(s),{recursive:!0}),nn(s,r,"utf-8"),this.isProjectLocal&&this.ensureGitignore()}has(e,t,o){return we(this.getPath(e,t,o))}ensureGitignore(){if(this.gitignoreChecked)return;this.gitignoreChecked=!0;let e=".gitignore",t=this.cacheDir;if(we(e)){if(en(e,"utf-8").split(`
3
3
  `).some(r=>r.trim()===t||r.trim()===t+"/"))return;Yt(e,`
4
4
  ${t}/
5
5
  `)}else nn(e,`${t}/
6
- `)}getPath(e,t,o){return Xt(this.cacheDir,e,`${t}@${o}.kan.yml`)}};function N(n){let e=n;for(;;){let t=oo(e);if(t===e)break;if(tn(e).includes(".")||tn(t).includes(".")){e=t;continue}break}return e}function be(n,e){for(let t of no(n,{withFileTypes:!0})){let o=to(n,t.name);t.isDirectory()&&t.name!=="node_modules"&&t.name!==".kanonak"?be(o,e):t.name.endsWith(".kan.yml")&&e.push(o)}}async function $(n,e){let t=new K;return ro(n,e,{httpCache:{getFromCache:(o,r,a)=>t.get(o,r,a),onFetch:(o,r,a,s)=>t.put(o,r,a,s)}})}async function rn(n){let e=io(n),t=ao(e),o=t.isDirectory()?N(e):N(co(e)),r=new lo,a=new uo(r),s=await $(o,r),i=[];if(t.isDirectory()?be(e,i):i.push(e),i.length===0){console.log("No .kan.yml files found.");return}let c=0,l=0,u=[];for(let f of i){let m=so(f,"utf-8"),h=r.parseWithErrors(m);if(h.errors&&h.errors.length>0){console.log(`
6
+ `)}getPath(e,t,o){return Xt(this.cacheDir,e,`${t}@${o}.kan.yml`)}};function N(n){let e=n;for(;;){let t=oo(e);if(t===e)break;if(tn(e).includes(".")||tn(t).includes(".")){e=t;continue}break}return e}function be(n,e){for(let t of no(n,{withFileTypes:!0})){let o=to(n,t.name);t.isDirectory()&&t.name!=="node_modules"&&t.name!==".kanonak"?be(o,e):t.name.endsWith(".kan.yml")&&e.push(o)}}async function $(n,e){let t=new K;return ro(n,e,{httpCache:{getFromCache:(o,r,s)=>t.get(o,r,s),onFetch:(o,r,s,a)=>t.put(o,r,s,a)}})}async function rn(n){let e=io(n),t=so(e),o=t.isDirectory()?N(e):N(co(e)),r=new lo,s=new uo(r),a=await $(o,r),i=[];if(t.isDirectory()?be(e,i):i.push(e),i.length===0){console.log("No .kan.yml files found.");return}let c=0,l=0,u=[];for(let f of i){let m=ao(f,"utf-8"),h=r.parseWithErrors(m);if(h.errors&&h.errors.length>0){console.log(`
7
7
  ${f}:`);for(let k of h.errors)console.log(` ERROR (parse): ${k.message} [line ${k.line}:${k.column}]`),c++;continue}if(!h.document){console.log(`
8
- ${f}:`),console.log(" ERROR: Failed to parse document"),c++;continue}u.push({file:f,document:h.document})}let p=u.map(f=>f.document),d=new Map(u.map(f=>[f.document,f.file])),g=await a.validateDocumentsAsync(p,s);for(let{document:f,result:m}of g){let h=m.errors.filter(y=>y.severity===on.Error),k=m.warnings.filter(y=>y.severity===on.Warning);if(h.length>0||k.length>0){let y=f.metadata.namespace_,w=y?`${y.publisher}/${y.package_}@${y.version}`:d.get(f)??"(unknown)";console.log(`
8
+ ${f}:`),console.log(" ERROR: Failed to parse document"),c++;continue}u.push({file:f,document:h.document})}let p=u.map(f=>f.document),d=new Map(u.map(f=>[f.document,f.file])),g=await s.validateDocumentsAsync(p,a);for(let{document:f,result:m}of g){let h=m.errors.filter(y=>y.severity===on.Error),k=m.warnings.filter(y=>y.severity===on.Warning);if(h.length>0||k.length>0){let y=f.metadata.namespace_,w=y?`${y.publisher}/${y.package_}@${y.version}`:d.get(f)??"(unknown)";console.log(`
9
9
  ${w}:`);for(let b of h)console.log(` ERROR: ${b.message}`),b.suggestion&&console.log(` -> ${b.suggestion}`);for(let b of k)console.log(` WARN: ${b.message}`)}c+=h.length,l+=k.length}console.log(`
10
- ${i.length} file(s) validated. ${c} error(s), ${l} warning(s).`),c>0&&process.exit(1)}import{KanonakParser as po,PublisherIndex as mo,CredentialStore as fo,createAuthenticatedFetch as go}from"@kanonak-protocol/sdk";import{loadLockFile as ho,saveLockFile as ko,computeIntegrity as yo,assertPackageIdentity as wo}from"@kanonak-protocol/sdk";function T(n){if(!n)return null;let e=n.indexOf("/");if(e===-1)return null;let t=n.substring(0,e),o=n.substring(e+1);if(!t||!o)return null;let r,a=null,s=null,i=o.indexOf("@");if(i!==-1){r=o.substring(0,i);let c=o.substring(i+1),l=c.indexOf("/");l===-1?a=c||null:(a=c.substring(0,l)||null,s=c.substring(l+1)||null)}else{let c=o.indexOf("/");c===-1?r=o:(r=o.substring(0,c),s=o.substring(c+1)||null)}return!r||s&&s.includes("/")||a&&a.includes("@")?null:{publisher:t,packageName:r,version:a,instanceName:s}}async function sn(n){let e=new K,t=new po,o=new fo,r=go(o),a=new mo({fetchFn:r}),s=ho()??{version:"1",lastUpdated:new Date().toISOString(),packages:{}};if(!n){Object.keys(s.packages).length===0&&(console.error("No kanonak.lock file found or lock file is empty."),console.error("Usage: kanonak install {publisher}/{package}[@{version}]"),process.exit(1)),console.log(`Installing ${Object.keys(s.packages).length} package(s) from kanonak.lock...`);for(let[f,m]of Object.entries(s.packages)){let h=f.indexOf("/"),k=f.substring(0,h),y=f.substring(h+1),w=e.get(k,y,m.version);if(w)console.log(` ${f}@${m.version} (cached)`);else{let b=m.resolved,v=await r(b,k);if(!v.ok)throw new Error(`Failed to fetch ${b} (${v.status} ${v.statusText})`);w=await v.text(),e.put(k,y,m.version,w),console.log(` ${f}@${m.version}`)}}console.log(`
11
- Installed ${Object.keys(s.packages).length} package(s) from lock file.`);return}let i=T(n);i||(console.error(`Invalid package reference: "${n}"`),console.error("Expected format: {publisher}/{package}[@{version}]"),process.exit(1));let{publisher:c,packageName:l,version:u,instanceName:p}=i;p&&(console.error(`\`kanonak install\` works on whole packages \u2014 got an instance suffix "/${p}".`),console.error(`Try: kanonak install ${c}/${l}${u?"@"+u:""}`),console.error("(Use `kanonak <capability> add` if you want to install one named instance.)"),process.exit(1));let d=u??await a.getHighestVersion(c,l);d||(console.error(`Could not resolve version for "${c}/${l}".`),console.error("Check the spelling, or run a search to see what the publisher offers."),process.exit(1)),console.log(`Installing ${c}/${l}@${d}...`);let g=new Set;await an(c,l,d,e,t,a,r,g,s),ko(s),console.log(`
12
- Installed ${g.size} package(s).`)}async function an(n,e,t,o,r,a,s,i,c){let l=`${n}/${e}@${t}`;if(i.has(l))return;i.add(l);let u=`${n}/${e}`,p=o.get(n,e,t),d=await a.getPackageUrl(n,e,t),g,f=!1;if(p)g=p;else{let k=await s(d,n);if(!k.ok)throw new Error(`Failed to fetch ${d} (${k.status} ${k.statusText})`);g=await k.text(),f=!0}let m=r.parse(g);wo(m,n,e,t),f&&o.put(n,e,t,g),console.log(` ${l}${f?"":" (cached)"}`);let h={};if(m.metadata.imports)for(let[k,y]of Object.entries(m.metadata.imports))for(let w of y){let b=await a.resolveVersion(k,w);b?(h[`${k}/${w.packageName}`]=b,await an(k,w.packageName,b,o,r,a,s,i,c)):console.error(` WARNING: Could not resolve ${k}/${w.packageName} ${w.package_}`)}c.packages[u]={version:t,resolved:d,integrity:yo(g),dependencies:h}}import{readFileSync as bo}from"fs";import{resolve as vo,dirname as $o}from"path";import{KanonakParser as So}from"@kanonak-protocol/sdk";async function cn(n){let e=vo(n),t=bo(e,"utf-8"),o=new So,r=o.parse(t),a=r.metadata.namespace_,s=a?`${a.publisher}/${a.package_}@${a.version}`:n;if(console.log(s),!r.metadata.imports){console.log(" (no imports)");return}let i=N($o(e)),c=await $(i,o),l=new Set;for(let[u,p]of Object.entries(r.metadata.imports))for(let d of p)await ln(u,d,c,l," ")}async function ln(n,e,t,o,r){let a=`${n}/${e.packageName}`;if(o.has(a)){console.log(`${r}${a} (${e.package_}) [circular]`);return}o.add(a);let s;try{s=await t.getHighestCompatibleVersionAsync(n,e)}catch{console.log(`${r}${a} (${e.package_}) [fetch failed]`);return}if(!s){console.log(`${r}${a} (${e.package_}) [not found]`);return}let i=s.metadata.namespace_?.version?.toString()??"?";if(console.log(`${r}${n}/${e.packageName}@${i}`),s.metadata.imports)for(let[c,l]of Object.entries(s.metadata.imports))for(let u of l)await ln(c,u,t,o,r+" ")}import{createHash as Co,randomBytes as dn}from"crypto";import{createServer as Ro}from"http";import{execFile as ve}from"child_process";import{CredentialStore as _o,generateDPoPKeyPair as xo,createDPoPProof as un,serverSupportsDPoP as Io}from"@kanonak-protocol/sdk";import{normalizeHost as Po}from"@kanonak-protocol/sdk";var A=class{cache=new Map;async discover(e){let t=Po(e);if(this.cache.has(t))return this.cache.get(t);let o=`https://${t}/.well-known/oauth-authorization-server`,r=await this.tryEndpoint(o);if(!r){let a=`https://${t}/.well-known/openid-configuration`;r=await this.tryEndpoint(a)}return this.cache.set(t,r),r}async supportsOAuth(e){return await this.discover(e)!==null}static supportsPkceS256(e){return e.codeChallengeMethodsSupported?.some(t=>t.toUpperCase()==="S256")??!1}static supportsDynamicRegistration(e){return!!e.registrationEndpoint}static supportsAuthorizationCode(e){return e.responseTypesSupported?.some(t=>t.toLowerCase()==="code")??!1}async tryEndpoint(e){let t;try{t=await fetch(e)}catch(r){let a=r instanceof Error?r.message:String(r);return a.includes("ENOTFOUND")||a.includes("ECONNREFUSED")?(console.error(` OAuth discovery: ${e} \u2014 host unreachable (${a})`),console.error(" If the server is behind a VPN, ensure you are connected.")):a.includes("CERT")||a.includes("SSL")||a.includes("TLS")?(console.error(` OAuth discovery: ${e} \u2014 TLS error (${a})`),console.error(" If using a custom CA certificate, set NODE_EXTRA_CA_CERTS=/path/to/ca.pem")):console.error(` OAuth discovery: ${e} \u2014 network error: ${a}`),null}if(!t.ok)return t.status===404||(t.status===403?(console.error(` OAuth discovery: ${e} \u2014 HTTP 403 Forbidden`),console.error(" Access may be blocked by a firewall, proxy, or WAF.")):t.status>=500&&(console.error(` OAuth discovery: ${e} \u2014 HTTP ${t.status} server error`),console.error(" The authorization server returned an internal error. Contact your IDP administrator."))),null;let o;try{o=await t.json()}catch{return console.error(` OAuth discovery: ${e} \u2014 response is not valid JSON`),console.error(" The endpoint may be returning HTML instead of JSON. Check IDP configuration."),null}return{issuer:J(o.issuer),authorizationEndpoint:J(o.authorization_endpoint),tokenEndpoint:J(o.token_endpoint),registrationEndpoint:J(o.registration_endpoint),revocationEndpoint:J(o.revocation_endpoint),scopesSupported:H(o.scopes_supported),responseTypesSupported:H(o.response_types_supported),grantTypesSupported:H(o.grant_types_supported),codeChallengeMethodsSupported:H(o.code_challenge_methods_supported),tokenEndpointAuthMethodsSupported:H(o.token_endpoint_auth_methods_supported),dpopSigningAlgValuesSupported:H(o.dpop_signing_alg_values_supported)}}};function J(n){return typeof n=="string"?n:null}function H(n){return Array.isArray(n)?n.filter(e=>typeof e=="string"):null}var B=class{discovery;credentialStore;constructor(e,t){this.discovery=e??new A,this.credentialStore=t??new _o}async authorize(e,t=[]){console.log(`Starting OAuth flow for ${e}...`);let o=await this.discovery.discover(e);if(!o)return I(`No OAuth discovery endpoint found for '${e}'.
10
+ ${i.length} file(s) validated. ${c} error(s), ${l} warning(s).`),c>0&&process.exit(1)}import{KanonakParser as po,PublisherIndex as mo,CredentialStore as fo,createAuthenticatedFetch as go}from"@kanonak-protocol/sdk";import{loadLockFile as ho,saveLockFile as ko,computeIntegrity as yo,assertPackageIdentity as wo}from"@kanonak-protocol/sdk";function T(n){if(!n)return null;let e=n.indexOf("/");if(e===-1)return null;let t=n.substring(0,e),o=n.substring(e+1);if(!t||!o)return null;let r,s=null,a=null,i=o.indexOf("@");if(i!==-1){r=o.substring(0,i);let c=o.substring(i+1),l=c.indexOf("/");l===-1?s=c||null:(s=c.substring(0,l)||null,a=c.substring(l+1)||null)}else{let c=o.indexOf("/");c===-1?r=o:(r=o.substring(0,c),a=o.substring(c+1)||null)}return!r||a&&a.includes("/")||s&&s.includes("@")?null:{publisher:t,packageName:r,version:s,instanceName:a}}async function an(n){let e=new K,t=new po,o=new fo,r=go(o),s=new mo({fetchFn:r}),a=ho()??{version:"1",lastUpdated:new Date().toISOString(),packages:{}};if(!n){Object.keys(a.packages).length===0&&(console.error("No kanonak.lock file found or lock file is empty."),console.error("Usage: kanonak install {publisher}/{package}[@{version}]"),process.exit(1)),console.log(`Installing ${Object.keys(a.packages).length} package(s) from kanonak.lock...`);for(let[f,m]of Object.entries(a.packages)){let h=f.indexOf("/"),k=f.substring(0,h),y=f.substring(h+1),w=e.get(k,y,m.version);if(w)console.log(` ${f}@${m.version} (cached)`);else{let b=m.resolved,v=await r(b,k);if(!v.ok)throw new Error(`Failed to fetch ${b} (${v.status} ${v.statusText})`);w=await v.text(),e.put(k,y,m.version,w),console.log(` ${f}@${m.version}`)}}console.log(`
11
+ Installed ${Object.keys(a.packages).length} package(s) from lock file.`);return}let i=T(n);i||(console.error(`Invalid package reference: "${n}"`),console.error("Expected format: {publisher}/{package}[@{version}]"),process.exit(1));let{publisher:c,packageName:l,version:u,instanceName:p}=i;p&&(console.error(`\`kanonak install\` works on whole packages \u2014 got an instance suffix "/${p}".`),console.error(`Try: kanonak install ${c}/${l}${u?"@"+u:""}`),console.error("(Use `kanonak <capability> add` if you want to install one named instance.)"),process.exit(1));let d=u??await s.getHighestVersion(c,l);d||(console.error(`Could not resolve version for "${c}/${l}".`),console.error("Check the spelling, or run a search to see what the publisher offers."),process.exit(1)),console.log(`Installing ${c}/${l}@${d}...`);let g=new Set;await sn(c,l,d,e,t,s,r,g,a),ko(a),console.log(`
12
+ Installed ${g.size} package(s).`)}async function sn(n,e,t,o,r,s,a,i,c){let l=`${n}/${e}@${t}`;if(i.has(l))return;i.add(l);let u=`${n}/${e}`,p=o.get(n,e,t),d=await s.getPackageUrl(n,e,t),g,f=!1;if(p)g=p;else{let k=await a(d,n);if(!k.ok)throw new Error(`Failed to fetch ${d} (${k.status} ${k.statusText})`);g=await k.text(),f=!0}let m=r.parse(g);wo(m,n,e,t),f&&o.put(n,e,t,g),console.log(` ${l}${f?"":" (cached)"}`);let h={};if(m.metadata.imports)for(let[k,y]of Object.entries(m.metadata.imports))for(let w of y){let b=await s.resolveVersion(k,w);b?(h[`${k}/${w.packageName}`]=b,await sn(k,w.packageName,b,o,r,s,a,i,c)):console.error(` WARNING: Could not resolve ${k}/${w.packageName} ${w.package_}`)}c.packages[u]={version:t,resolved:d,integrity:yo(g),dependencies:h}}import{readFileSync as bo}from"fs";import{resolve as vo,dirname as $o}from"path";import{KanonakParser as So}from"@kanonak-protocol/sdk";async function cn(n){let e=vo(n),t=bo(e,"utf-8"),o=new So,r=o.parse(t),s=r.metadata.namespace_,a=s?`${s.publisher}/${s.package_}@${s.version}`:n;if(console.log(a),!r.metadata.imports){console.log(" (no imports)");return}let i=N($o(e)),c=await $(i,o),l=new Set;for(let[u,p]of Object.entries(r.metadata.imports))for(let d of p)await ln(u,d,c,l," ")}async function ln(n,e,t,o,r){let s=`${n}/${e.packageName}`;if(o.has(s)){console.log(`${r}${s} (${e.package_}) [circular]`);return}o.add(s);let a;try{a=await t.getHighestCompatibleVersionAsync(n,e)}catch{console.log(`${r}${s} (${e.package_}) [fetch failed]`);return}if(!a){console.log(`${r}${s} (${e.package_}) [not found]`);return}let i=a.metadata.namespace_?.version?.toString()??"?";if(console.log(`${r}${n}/${e.packageName}@${i}`),a.metadata.imports)for(let[c,l]of Object.entries(a.metadata.imports))for(let u of l)await ln(c,u,t,o,r+" ")}import{createHash as Co,randomBytes as dn}from"crypto";import{createServer as Ro}from"http";import{execFile as ve}from"child_process";import{CredentialStore as _o,generateDPoPKeyPair as xo,createDPoPProof as un,serverSupportsDPoP as Io}from"@kanonak-protocol/sdk";import{normalizeHost as Po}from"@kanonak-protocol/sdk";var A=class{cache=new Map;async discover(e){let t=Po(e);if(this.cache.has(t))return this.cache.get(t);let o=`https://${t}/.well-known/oauth-authorization-server`,r=await this.tryEndpoint(o);if(!r){let s=`https://${t}/.well-known/openid-configuration`;r=await this.tryEndpoint(s)}return this.cache.set(t,r),r}async supportsOAuth(e){return await this.discover(e)!==null}static supportsPkceS256(e){return e.codeChallengeMethodsSupported?.some(t=>t.toUpperCase()==="S256")??!1}static supportsDynamicRegistration(e){return!!e.registrationEndpoint}static supportsAuthorizationCode(e){return e.responseTypesSupported?.some(t=>t.toLowerCase()==="code")??!1}async tryEndpoint(e){let t;try{t=await fetch(e)}catch(r){let s=r instanceof Error?r.message:String(r);return s.includes("ENOTFOUND")||s.includes("ECONNREFUSED")?(console.error(` OAuth discovery: ${e} \u2014 host unreachable (${s})`),console.error(" If the server is behind a VPN, ensure you are connected.")):s.includes("CERT")||s.includes("SSL")||s.includes("TLS")?(console.error(` OAuth discovery: ${e} \u2014 TLS error (${s})`),console.error(" If using a custom CA certificate, set NODE_EXTRA_CA_CERTS=/path/to/ca.pem")):console.error(` OAuth discovery: ${e} \u2014 network error: ${s}`),null}if(!t.ok)return t.status===404||(t.status===403?(console.error(` OAuth discovery: ${e} \u2014 HTTP 403 Forbidden`),console.error(" Access may be blocked by a firewall, proxy, or WAF.")):t.status>=500&&(console.error(` OAuth discovery: ${e} \u2014 HTTP ${t.status} server error`),console.error(" The authorization server returned an internal error. Contact your IDP administrator."))),null;let o;try{o=await t.json()}catch{return console.error(` OAuth discovery: ${e} \u2014 response is not valid JSON`),console.error(" The endpoint may be returning HTML instead of JSON. Check IDP configuration."),null}return{issuer:J(o.issuer),authorizationEndpoint:J(o.authorization_endpoint),tokenEndpoint:J(o.token_endpoint),registrationEndpoint:J(o.registration_endpoint),revocationEndpoint:J(o.revocation_endpoint),scopesSupported:H(o.scopes_supported),responseTypesSupported:H(o.response_types_supported),grantTypesSupported:H(o.grant_types_supported),codeChallengeMethodsSupported:H(o.code_challenge_methods_supported),tokenEndpointAuthMethodsSupported:H(o.token_endpoint_auth_methods_supported),dpopSigningAlgValuesSupported:H(o.dpop_signing_alg_values_supported)}}};function J(n){return typeof n=="string"?n:null}function H(n){return Array.isArray(n)?n.filter(e=>typeof e=="string"):null}var B=class{discovery;credentialStore;constructor(e,t){this.discovery=e??new A,this.credentialStore=t??new _o}async authorize(e,t=[]){console.log(`Starting OAuth flow for ${e}...`);let o=await this.discovery.discover(e);if(!o)return I(`No OAuth discovery endpoint found for '${e}'.
13
13
  The server must expose one of:
14
14
  - https://${e}/.well-known/oauth-authorization-server (RFC 8414)
15
15
  - https://${e}/.well-known/openid-configuration (OpenID Connect)
16
16
  Verify the hostname is correct and HTTPS is configured.
17
17
  If using a corporate proxy, ensure it is not blocking the discovery request.`);let r=[];if(o.authorizationEndpoint||r.push("authorization_endpoint"),o.tokenEndpoint||r.push("token_endpoint"),r.length>0)return I(`OAuth metadata for '${e}' is missing required fields: ${r.join(", ")}.
18
- Contact the IDP administrator to ensure these are included in the discovery document.`);let a=Io(o.dpopSigningAlgValuesSupported),s=null;if(a){console.log(" Server supports DPoP (RFC 9449) \u2014 generating key pair...");try{s=xo()}catch(v){return I(`Failed to generate DPoP key pair: ${z(v)}
18
+ Contact the IDP administrator to ensure these are included in the discovery document.`);let s=Io(o.dpopSigningAlgValuesSupported),a=null;if(s){console.log(" Server supports DPoP (RFC 9449) \u2014 generating key pair...");try{a=xo()}catch(v){return I(`Failed to generate DPoP key pair: ${z(v)}
19
19
  Ensure your Node.js installation supports EC P-256 curves.`)}}let{redirectUri:i,port:c,waitForCallback:l,close:u}=await Oo(),p=await this.credentialStore.getCredential(e),d=p?.clientId??null,g=p?.clientSecret??null;if(!d&&o.registrationEndpoint){console.log(" Registering dynamic OAuth client (RFC 7591)...");let v=await this.registerClient(o.registrationEndpoint,i);if(!v.success)return u(),I(v.error);d=v.clientId,g=v.clientSecret??null}if(!d)return u(),I(`No OAuth client credentials for '${e}' and the server does not support dynamic client registration (no registration_endpoint in metadata).
20
20
  You must pre-register a client with your IDP and configure the client_id.
21
21
  Ask your IDP administrator to enable dynamic client registration (RFC 7591),
@@ -25,26 +25,26 @@ Installed ${g.size} package(s).`)}async function an(n,e,t,o,r,a,s,i,c){let l=`${
25
25
  The IDP may have rejected the authorization request.
26
26
  Check the IDP admin console for error details.`)}if(y.state!==h)return I(`Authorization state mismatch \u2014 possible CSRF attack.
27
27
  The response did not match the expected session.
28
- Re-run 'kanonak login ${e}' to start a fresh authorization flow.`);console.log(" Exchanging authorization code for tokens...");let w=await this.exchangeCode(o.tokenEndpoint,d,g,y.code,i,f,s);if(!w.success)return I(w.error);let b={clientId:d,clientSecret:g,accessToken:w.tokens.accessToken,refreshToken:w.tokens.refreshToken,expiresAt:w.tokens.expiresIn?new Date(Date.now()+w.tokens.expiresIn*1e3).toISOString():null,tokenEndpoint:o.tokenEndpoint,dpopKeyPair:s};return await this.credentialStore.store(e,b),console.log(` Successfully authenticated with ${e}`),a&&console.log(" DPoP proof-of-possession is active"),{success:!0,host:e}}async refresh(e){let t=await this.credentialStore.getCredential(e);if(!t)return I(`No stored credentials for '${e}'. Run 'kanonak login ${e}' to authenticate first.`);if(!t.refreshToken)return I(`No refresh token available for '${e}'.
28
+ Re-run 'kanonak login ${e}' to start a fresh authorization flow.`);console.log(" Exchanging authorization code for tokens...");let w=await this.exchangeCode(o.tokenEndpoint,d,g,y.code,i,f,a);if(!w.success)return I(w.error);let b={clientId:d,clientSecret:g,accessToken:w.tokens.accessToken,refreshToken:w.tokens.refreshToken,expiresAt:w.tokens.expiresIn?new Date(Date.now()+w.tokens.expiresIn*1e3).toISOString():null,tokenEndpoint:o.tokenEndpoint,dpopKeyPair:a};return await this.credentialStore.store(e,b),console.log(` Successfully authenticated with ${e}`),s&&console.log(" DPoP proof-of-possession is active"),{success:!0,host:e}}async refresh(e){let t=await this.credentialStore.getCredential(e);if(!t)return I(`No stored credentials for '${e}'. Run 'kanonak login ${e}' to authenticate first.`);if(!t.refreshToken)return I(`No refresh token available for '${e}'.
29
29
  The authorization server may not issue refresh tokens for this client.
30
30
  Run 'kanonak login ${e}' to re-authenticate.`);if(!t.clientId)return I(`No client ID in stored credentials for '${e}'.
31
- The stored credential may be corrupted. Run 'kanonak logout ${e}' then 'kanonak login ${e}'.`);let o=t.tokenEndpoint;if(!o){let a=await this.discovery.discover(e);if(!a?.tokenEndpoint)return I(`Cannot find token endpoint for '${e}'.
31
+ The stored credential may be corrupted. Run 'kanonak logout ${e}' then 'kanonak login ${e}'.`);let o=t.tokenEndpoint;if(!o){let s=await this.discovery.discover(e);if(!s?.tokenEndpoint)return I(`Cannot find token endpoint for '${e}'.
32
32
  The OAuth discovery endpoint may be unreachable.
33
- Check network connectivity and run 'kanonak login ${e}' to re-authenticate.`);o=a.tokenEndpoint}let r=await this.refreshTokenRequest(o,t.clientId,t.clientSecret,t.refreshToken,t.dpopKeyPair);return r.success?(t.accessToken=r.tokens.accessToken,r.tokens.refreshToken&&(t.refreshToken=r.tokens.refreshToken),t.expiresAt=r.tokens.expiresIn?new Date(Date.now()+r.tokens.expiresIn*1e3).toISOString():null,t.tokenEndpoint=o,await this.credentialStore.store(e,t),{success:!0,host:e}):I(`${r.error}
33
+ Check network connectivity and run 'kanonak login ${e}' to re-authenticate.`);o=s.tokenEndpoint}let r=await this.refreshTokenRequest(o,t.clientId,t.clientSecret,t.refreshToken,t.dpopKeyPair);return r.success?(t.accessToken=r.tokens.accessToken,r.tokens.refreshToken&&(t.refreshToken=r.tokens.refreshToken),t.expiresAt=r.tokens.expiresIn?new Date(Date.now()+r.tokens.expiresIn*1e3).toISOString():null,t.tokenEndpoint=o,await this.credentialStore.store(e,t),{success:!0,host:e}):I(`${r.error}
34
34
  The refresh token may have expired. Run 'kanonak login ${e}' to re-authenticate.`)}async logout(e){let t=await this.credentialStore.getCredential(e);if(!t)return I(`No stored credentials for '${e}'.
35
- You may not be logged in, or credentials may be stored in a different backend.`);let o=await this.discovery.discover(e);if(o?.revocationEndpoint&&t.accessToken&&t.clientId)try{await this.revokeToken(o.revocationEndpoint,t.accessToken,t.clientId)}catch{console.warn(` Warning: Token revocation failed for '${e}'. The token has been removed locally but may still be valid on the server until it expires.`)}return await this.credentialStore.remove(e),{success:!0,host:e}}async registerClient(e,t){let o;try{o=await fetch(e,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({client_name:"Kanonak CLI",redirect_uris:[t],grant_types:["authorization_code","refresh_token"],response_types:["code"],token_endpoint_auth_method:"none"})})}catch(s){return{success:!1,error:`Dynamic client registration request to ${e} failed: ${z(s)}
35
+ You may not be logged in, or credentials may be stored in a different backend.`);let o=await this.discovery.discover(e);if(o?.revocationEndpoint&&t.accessToken&&t.clientId)try{await this.revokeToken(o.revocationEndpoint,t.accessToken,t.clientId)}catch{console.warn(` Warning: Token revocation failed for '${e}'. The token has been removed locally but may still be valid on the server until it expires.`)}return await this.credentialStore.remove(e),{success:!0,host:e}}async registerClient(e,t){let o;try{o=await fetch(e,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({client_name:"Kanonak CLI",redirect_uris:[t],grant_types:["authorization_code","refresh_token"],response_types:["code"],token_endpoint_auth_method:"none"})})}catch(a){return{success:!1,error:`Dynamic client registration request to ${e} failed: ${z(a)}
36
36
  Ensure the IDP is reachable and HTTPS is properly configured.
37
- If using a corporate proxy or custom CA, set NODE_EXTRA_CA_CERTS.`}}if(!o.ok){let s=await $e(o);return{success:!1,error:`Dynamic client registration (RFC 7591) failed.
37
+ If using a corporate proxy or custom CA, set NODE_EXTRA_CA_CERTS.`}}if(!o.ok){let a=await $e(o);return{success:!1,error:`Dynamic client registration (RFC 7591) failed.
38
38
  Endpoint: ${e}
39
- HTTP ${o.status}: ${s}
39
+ HTTP ${o.status}: ${a}
40
40
  The IDP may not support dynamic registration for public clients.
41
- Ask your IDP administrator to enable RFC 7591 support, or pre-register a client manually.`}}let r=await o.json(),a=r.client_id;return a?{success:!0,clientId:a,clientSecret:r.client_secret}:{success:!1,error:`Dynamic client registration response from ${e} did not contain a client_id.
42
- The IDP response may be malformed. Contact your IDP administrator.`}}async exchangeCode(e,t,o,r,a,s,i){let c=new URLSearchParams({grant_type:"authorization_code",client_id:t,code:r,redirect_uri:a,code_verifier:s});o&&c.set("client_secret",o);let l={"Content-Type":"application/x-www-form-urlencoded"};if(i)try{l.DPoP=un(i.privateKey,i.publicKey,"POST",e)}catch(p){return{success:!1,error:`Failed to create DPoP proof for token exchange: ${z(p)}
41
+ Ask your IDP administrator to enable RFC 7591 support, or pre-register a client manually.`}}let r=await o.json(),s=r.client_id;return s?{success:!0,clientId:s,clientSecret:r.client_secret}:{success:!1,error:`Dynamic client registration response from ${e} did not contain a client_id.
42
+ The IDP response may be malformed. Contact your IDP administrator.`}}async exchangeCode(e,t,o,r,s,a,i){let c=new URLSearchParams({grant_type:"authorization_code",client_id:t,code:r,redirect_uri:s,code_verifier:a});o&&c.set("client_secret",o);let l={"Content-Type":"application/x-www-form-urlencoded"};if(i)try{l.DPoP=un(i.privateKey,i.publicKey,"POST",e)}catch(p){return{success:!1,error:`Failed to create DPoP proof for token exchange: ${z(p)}
43
43
  The stored key pair may be corrupted. Run 'kanonak login' to re-authenticate.`}}let u;try{u=await fetch(e,{method:"POST",headers:l,body:c.toString()})}catch(p){return{success:!1,error:`Token exchange request to ${e} failed: ${z(p)}
44
44
  Ensure the token endpoint is reachable.`}}if(!u.ok){let p=await $e(u),d=Ko(p);return{success:!1,error:`Token exchange failed.
45
45
  Endpoint: ${e}
46
46
  HTTP ${u.status}: ${p}`+(d?`
47
- ${d}`:"")}}return{success:!0,tokens:pn(await u.json())}}async refreshTokenRequest(e,t,o,r,a){let s=new URLSearchParams({grant_type:"refresh_token",client_id:t,refresh_token:r});o&&s.set("client_secret",o);let i={"Content-Type":"application/x-www-form-urlencoded"};if(a)try{i.DPoP=un(a.privateKey,a.publicKey,"POST",e)}catch(l){return{success:!1,error:`Failed to create DPoP proof for token refresh: ${z(l)}`}}let c;try{c=await fetch(e,{method:"POST",headers:i,body:s.toString()})}catch(l){return{success:!1,error:`Token refresh request to ${e} failed: ${z(l)}`}}if(!c.ok){let l=await $e(c);return{success:!1,error:`Token refresh failed \u2014 HTTP ${c.status}: ${l}`}}return{success:!0,tokens:pn(await c.json())}}async revokeToken(e,t,o){await fetch(e,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams({token:t,client_id:o}).toString()})}};function I(n){return{success:!1,error:n}}function pn(n){return{accessToken:n.access_token,refreshToken:n.refresh_token,expiresIn:typeof n.expires_in=="number"?n.expires_in:void 0}}function z(n){return n instanceof Error?n.message:String(n)}async function $e(n){try{return await n.text()}catch{return"(could not read response body)"}}function Ko(n){try{let e=JSON.parse(n);switch(e.error){case"invalid_grant":return"Hint: The authorization code may have expired or already been used. Re-run the login flow.";case"invalid_client":return"Hint: The client credentials were rejected. The client_id may be invalid or the client_secret may be wrong.";case"redirect_uri_mismatch":return"Hint: The redirect_uri does not match what was registered with the IDP.";case"unsupported_grant_type":return"Hint: The IDP does not support authorization_code grants. Contact your IDP administrator.";case"invalid_scope":return"Hint: One or more requested scopes are not allowed. Check the scopes configured on the IDP.";case"use_dpop_nonce":return"Hint: The server requires a DPoP nonce. This should be handled automatically \u2014 please report this as a bug.";default:return e.error_description?`IDP says: ${e.error_description}`:null}}catch{return null}}function Do(){return dn(32).toString("base64url")}function To(n){return Co("sha256").update(n).digest("base64url")}function Eo(){return dn(16).toString("base64url")}function jo(n,e,t,o,r,a){let s=new URLSearchParams({client_id:e,response_type:"code",redirect_uri:t,scope:o.join(" "),state:r,code_challenge:a,code_challenge_method:"S256"});return`${n}?${s}`}var Ao=300*1e3;async function Oo(){return new Promise(n=>{let e=Ro((r,a)=>{let s=new URL(r.url,"http://localhost"),i=s.searchParams.get("code")??void 0,c=s.searchParams.get("state")??void 0,l=s.searchParams.get("error")??s.searchParams.get("error_description")??void 0,u=l?No(l):null,p=u?`<html><body><h1>Authorization failed</h1><p>${u}</p></body></html>`:"<html><body><h1>Authorization successful!</h1><p>You can close this window.</p></body></html>";a.writeHead(200,{"Content-Type":"text/html"}),a.end(p),t({code:i,state:c,error:l})}),t,o=new Promise(r=>{t=r,setTimeout(()=>{r(null),e.close()},Ao)});e.listen(0,"127.0.0.1",()=>{let r=e.address();n({redirectUri:`http://localhost:${r.port}/callback`,port:r.port,waitForCallback:()=>o,close:()=>e.close()})})})}function No(n){return n.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;")}function Lo(n){try{process.platform==="win32"?ve("cmd",["/c","start","",n]):process.platform==="darwin"?ve("open",[n]):ve("xdg-open",[n])}catch{console.log(" Could not open browser automatically. Please navigate to the URL above manually.")}}import{CredentialStore as Uo}from"@kanonak-protocol/sdk";async function mn(n){try{let e=new A,t=new Uo,r=await new B(e,t).authorize(n);r.success?console.log(`
47
+ ${d}`:"")}}return{success:!0,tokens:pn(await u.json())}}async refreshTokenRequest(e,t,o,r,s){let a=new URLSearchParams({grant_type:"refresh_token",client_id:t,refresh_token:r});o&&a.set("client_secret",o);let i={"Content-Type":"application/x-www-form-urlencoded"};if(s)try{i.DPoP=un(s.privateKey,s.publicKey,"POST",e)}catch(l){return{success:!1,error:`Failed to create DPoP proof for token refresh: ${z(l)}`}}let c;try{c=await fetch(e,{method:"POST",headers:i,body:a.toString()})}catch(l){return{success:!1,error:`Token refresh request to ${e} failed: ${z(l)}`}}if(!c.ok){let l=await $e(c);return{success:!1,error:`Token refresh failed \u2014 HTTP ${c.status}: ${l}`}}return{success:!0,tokens:pn(await c.json())}}async revokeToken(e,t,o){await fetch(e,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams({token:t,client_id:o}).toString()})}};function I(n){return{success:!1,error:n}}function pn(n){return{accessToken:n.access_token,refreshToken:n.refresh_token,expiresIn:typeof n.expires_in=="number"?n.expires_in:void 0}}function z(n){return n instanceof Error?n.message:String(n)}async function $e(n){try{return await n.text()}catch{return"(could not read response body)"}}function Ko(n){try{let e=JSON.parse(n);switch(e.error){case"invalid_grant":return"Hint: The authorization code may have expired or already been used. Re-run the login flow.";case"invalid_client":return"Hint: The client credentials were rejected. The client_id may be invalid or the client_secret may be wrong.";case"redirect_uri_mismatch":return"Hint: The redirect_uri does not match what was registered with the IDP.";case"unsupported_grant_type":return"Hint: The IDP does not support authorization_code grants. Contact your IDP administrator.";case"invalid_scope":return"Hint: One or more requested scopes are not allowed. Check the scopes configured on the IDP.";case"use_dpop_nonce":return"Hint: The server requires a DPoP nonce. This should be handled automatically \u2014 please report this as a bug.";default:return e.error_description?`IDP says: ${e.error_description}`:null}}catch{return null}}function Do(){return dn(32).toString("base64url")}function To(n){return Co("sha256").update(n).digest("base64url")}function Eo(){return dn(16).toString("base64url")}function jo(n,e,t,o,r,s){let a=new URLSearchParams({client_id:e,response_type:"code",redirect_uri:t,scope:o.join(" "),state:r,code_challenge:s,code_challenge_method:"S256"});return`${n}?${a}`}var Ao=300*1e3;async function Oo(){return new Promise(n=>{let e=Ro((r,s)=>{let a=new URL(r.url,"http://localhost"),i=a.searchParams.get("code")??void 0,c=a.searchParams.get("state")??void 0,l=a.searchParams.get("error")??a.searchParams.get("error_description")??void 0,u=l?No(l):null,p=u?`<html><body><h1>Authorization failed</h1><p>${u}</p></body></html>`:"<html><body><h1>Authorization successful!</h1><p>You can close this window.</p></body></html>";s.writeHead(200,{"Content-Type":"text/html"}),s.end(p),t({code:i,state:c,error:l})}),t,o=new Promise(r=>{t=r,setTimeout(()=>{r(null),e.close()},Ao)});e.listen(0,"127.0.0.1",()=>{let r=e.address();n({redirectUri:`http://localhost:${r.port}/callback`,port:r.port,waitForCallback:()=>o,close:()=>e.close()})})})}function No(n){return n.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;")}function Lo(n){try{process.platform==="win32"?ve("cmd",["/c","start","",n]):process.platform==="darwin"?ve("open",[n]):ve("xdg-open",[n])}catch{console.log(" Could not open browser automatically. Please navigate to the URL above manually.")}}import{CredentialStore as Uo}from"@kanonak-protocol/sdk";async function mn(n){try{let e=new A,t=new Uo,r=await new B(e,t).authorize(n);r.success?console.log(`
48
48
  Authenticated with ${n}.`):(console.error(`
49
49
  Authentication failed:
50
50
  ${r.error}`),process.exit(1))}catch(e){let t=e instanceof Error?e.message:String(e);console.error(`
@@ -55,7 +55,7 @@ Logout failed:
55
55
  ${r.error}`),process.exit(1))}catch(e){let t=e instanceof Error?e.message:String(e);console.error(`
56
56
  Logout failed unexpectedly:
57
57
  ${t}`),process.exit(1)}}import{Command as pr}from"commander";import{KanonakParser as dr,KanonakObjectParser as mr,PublisherIndex as fr,CredentialStore as gr,createAuthenticatedFetch as hr,computeIntegrity as kr}from"@kanonak-protocol/sdk";import{readFileSync as Mo,writeFileSync as Vo,existsSync as Ho}from"fs";import{join as zo}from"path";import gn from"js-yaml";import{getGlobalCachePath as Bo}from"@kanonak-protocol/sdk";var qo=`# This file is generated by Kanonak CLI. Do not edit manually.
58
- `;function hn(){let n=Bo();return zo(n,"..","capabilities.lock")}function q(){let n=hn();if(!Ho(n))return{version:"1",lastUpdated:new Date().toISOString(),capabilities:{}};let e=Mo(n,"utf-8"),t=gn.load(e);return!t||typeof t!="object"||t.version!=="1"?{version:"1",lastUpdated:new Date().toISOString(),capabilities:{}}:{version:"1",lastUpdated:t.lastUpdated??new Date().toISOString(),capabilities:t.capabilities??{}}}function Y(n){n.lastUpdated=new Date().toISOString();let e={};for(let o of Object.keys(n.capabilities).sort())e[o]=n.capabilities[o];n.capabilities=e;let t=gn.dump(n,{lineWidth:-1,sortKeys:!1,quotingType:'"'});Vo(hn(),qo+t,"utf-8")}import{SingleDocumentRepository as yr}from"@kanonak-protocol/sdk/uri-helpers";import{existsSync as Wo,readdirSync as Go,readFileSync as Jo}from"fs";import{join as kn}from"path";import{KanonakObjectParser as Yo,EmbeddedKanonak as vn,ReferenceKanonak as $n,getGlobalCachePath as Xo}from"@kanonak-protocol/sdk";import{SingleDocumentRepository as Sn}from"@kanonak-protocol/sdk/uri-helpers";import{uriKey as Se,findSubjectsByType as Zo,getStringValue as O,getReferenceUri as Pe,getListValues as Pn}from"@kanonak-protocol/sdk/uri-helpers";var P="kanonak.org",C="capabilities",Ce={publisher:P,package_:C,name:"Capability"},Qo={publisher:P,package_:C,name:"commandName"},Cn={publisher:P,package_:C,name:"description"},er={publisher:P,package_:C,name:"managesType"},nr={publisher:P,package_:C,name:"deploymentTarget"},tr={publisher:P,package_:C,name:"hasCommand"},or={publisher:P,package_:C,name:"subcommandName"},rr={publisher:P,package_:C,name:"performs"},sr={publisher:P,package_:C,name:"hasArgument"},ar={publisher:P,package_:C,name:"argumentName"},yn={publisher:P,package_:C,name:"isRequired"},wn={publisher:P,package_:C,name:"isOption"},ir={publisher:P,package_:C,name:"defaultValue"};async function Rn(n,e,t){let o=q(),r=new Yo,a=[],s=!1;for(let[i,c]of Object.entries(o.capabilities)){let l=c,u=n.get(l.publisher,l.package_,l.version);if(!u){let p=await cr(i,l,e,r,t);if(p)console.error(` Healed capability "${i}": ${l.publisher}/${l.package_}@${l.version} \u2192 ${p.entry.publisher}/${p.entry.package_}@${p.entry.version} (package was renamed)`),o.capabilities[i]=p.entry,l=p.entry,u=p.content,s=!0;else{console.error(` WARNING: Cached content missing for capability "${i}" (${l.publisher}/${l.package_}@${l.version}). Reinstall it with: kanonak capability remove ${i} && kanonak capability add ${l.publisher}/${l.package_}`);continue}}try{let p=e.parse(u),d=new Sn(p,t),g=await r.parseKanonaks(d),f=_n(g,l.publisher,l.package_,l.version);f?a.push(f):console.error(` WARNING: No Capability instance found in "${i}" (${l.publisher}/${l.package_}@${l.version})`)}catch(p){console.error(` WARNING: Failed to parse capability "${i}": ${p}`)}}return s&&Y(o),a}async function cr(n,e,t,o,r){let a=kn(Xo(),e.publisher);if(!Wo(a))return;let s=[];for(let i of Go(a)){if(!i.endsWith(".kan.yml"))continue;let c=i.slice(0,-8),l=c.lastIndexOf("@");if(l===-1)continue;let u=c.substring(0,l),p=c.substring(l+1);if(u===e.package_&&p===e.version)continue;let d;try{d=Jo(kn(a,i),"utf-8")}catch{continue}let g;try{let f=t.parse(d),m=new Sn(f,r),h=await o.parseKanonaks(m);g=_n(h,e.publisher,u,p)?.commandName}catch{continue}g===n&&s.push({entry:{publisher:e.publisher,package_:u,version:p,resolved:`kanonak://${e.publisher}/${u}@${p}`,integrity:""},content:d})}if(s.length===1)return s[0]}function _n(n,e,t,o){let r=Zo(n,Ce);if(r.length===0)return;let a=r[0],s=O(a,Qo)??"",i=O(a,Cn)??"",c=Pe(a,er),l=Pe(a,nr),u=[];for(let p of Pn(a,tr)){let d=lr(p,n);d&&u.push(d)}return{commandName:s,description:i,managesTypeKey:c?Se(c):"",deploymentTargetKey:l?Se(l):"",commands:u,publisher:e,package_:t,version:o}}function lr(n,e){let t;if(n instanceof vn)t=n;else if(n instanceof $n){let c=xn(e,n.subject.publisher,n.subject.package_,n.subject.name);c&&(t=c)}if(!t)return;let o=O(t,or)??"",r=O(t,Cn)??"",a=Pe(t,rr),s=Pn(t,sr),i=[];for(let c of s){let l=ur(c,e);l&&i.push(l)}return{subcommandName:o,description:r,arguments:i,actionKey:a?Se(a):""}}function ur(n,e){let t;if(n instanceof vn)t=n;else if(n instanceof $n){let c=xn(e,n.subject.publisher,n.subject.package_,n.subject.name);c&&(t=c)}if(!t)return;let o=O(t,ar)??"",r=O(t,yn)==="true"||bn(t,yn)===!0,a=O(t,wn)==="true"||bn(t,wn)===!0,s=O(t,ir),i={argumentName:o,required:r,isOption:a};return s!==void 0&&(i.defaultValue=s),i}function bn(n,e){for(let t of n.statement){let o=t,r=o.predicate;if(r?.subject&&r.subject.publisher===e.publisher&&r.subject.package_===e.package_&&r.subject.name===e.name)return typeof o.object=="boolean"?o.object:void 0}}function xn(n,e,t,o){for(let r of n){if(!("name"in r)||!("namespace"in r))continue;let a=r;if(a.name===o&&!(!a.namespace||typeof a.namespace!="string")&&a.namespace.startsWith(`${e}/${t}@`))return r}}import{findSubjectsByType as wr,getStringValue as br}from"@kanonak-protocol/sdk/uri-helpers";var vr={publisher:P,package_:C,name:"commandName"};function In(){let n=new pr("capability").description("Manage Kanonak CLI capabilities (pluggable command groups)");return n.command("add <package>").description("Install a capability from a Kanonak publisher").action(async e=>{await $r(e)}),n.command("remove <name>").description("Remove an installed capability").action(async e=>{await Sr(e)}),n.command("list").description("List installed capabilities").action(async()=>{await Pr()}),n}async function $r(n){let e=T(n);e||(console.error(`Invalid package reference: "${n}"`),console.error("Expected format: {publisher}/{package}[@{version}]"),process.exit(1));let{publisher:t,packageName:o,version:r,instanceName:a}=e;a&&(console.error(`\`kanonak capability add\` installs whole packages \u2014 got an instance suffix "/${a}".`),console.error(`Try: kanonak capability add ${t}/${o}${r?"@"+r:""}`),process.exit(1));let s=new K,i=new dr,c=new mr,l=new gr,u=hr(l),p=new fr({fetchFn:u}),d=r??await p.getHighestVersion(t,o);d||(console.error(`Could not resolve version for "${t}/${o}".`),process.exit(1)),console.log(`Installing capability ${t}/${o}@${d}...`);let g=s.get(t,o,d);if(!g){let _=await p.getPackageUrl(t,o,d),D=await u(_,t);if(!D.ok)throw new Error(`Failed to fetch ${_} (${D.status} ${D.statusText})`);g=await D.text(),s.put(t,o,d,g)}let f=i.parse(g),m=await $(process.cwd(),i),h=new yr(f,m),k=await c.parseKanonaks(h),y=wr(k,Ce);y.length===0&&(console.error(`Package ${t}/${o}@${d} does not contain a ${P}/${C}/Capability instance.`),process.exit(1));let w=y[0],b=br(w,vr);b||(console.error(`Capability instance in ${t}/${o}@${d} has no commandName property.`),process.exit(1));let v=q();v.capabilities[b]={publisher:t,package_:o,version:d,resolved:await p.getPackageUrl(t,o,d),integrity:kr(g)},Y(v),console.log(`
58
+ `;function hn(){let n=Bo();return zo(n,"..","capabilities.lock")}function q(){let n=hn();if(!Ho(n))return{version:"1",lastUpdated:new Date().toISOString(),capabilities:{}};let e=Mo(n,"utf-8"),t=gn.load(e);return!t||typeof t!="object"||t.version!=="1"?{version:"1",lastUpdated:new Date().toISOString(),capabilities:{}}:{version:"1",lastUpdated:t.lastUpdated??new Date().toISOString(),capabilities:t.capabilities??{}}}function Y(n){n.lastUpdated=new Date().toISOString();let e={};for(let o of Object.keys(n.capabilities).sort())e[o]=n.capabilities[o];n.capabilities=e;let t=gn.dump(n,{lineWidth:-1,sortKeys:!1,quotingType:'"'});Vo(hn(),qo+t,"utf-8")}import{SingleDocumentRepository as yr}from"@kanonak-protocol/sdk/uri-helpers";import{existsSync as Wo,readdirSync as Go,readFileSync as Jo}from"fs";import{join as kn}from"path";import{KanonakObjectParser as Yo,EmbeddedKanonak as vn,ReferenceKanonak as $n,getGlobalCachePath as Xo}from"@kanonak-protocol/sdk";import{SingleDocumentRepository as Sn}from"@kanonak-protocol/sdk/uri-helpers";import{uriKey as Se,findSubjectsByType as Zo,getStringValue as O,getReferenceUri as Pe,getListValues as Pn}from"@kanonak-protocol/sdk/uri-helpers";var P="kanonak.org",C="capabilities",Ce={publisher:P,package_:C,name:"Capability"},Qo={publisher:P,package_:C,name:"commandName"},Cn={publisher:P,package_:C,name:"description"},er={publisher:P,package_:C,name:"managesType"},nr={publisher:P,package_:C,name:"deploymentTarget"},tr={publisher:P,package_:C,name:"hasCommand"},or={publisher:P,package_:C,name:"subcommandName"},rr={publisher:P,package_:C,name:"performs"},ar={publisher:P,package_:C,name:"hasArgument"},sr={publisher:P,package_:C,name:"argumentName"},yn={publisher:P,package_:C,name:"isRequired"},wn={publisher:P,package_:C,name:"isOption"},ir={publisher:P,package_:C,name:"defaultValue"};async function Rn(n,e,t){let o=q(),r=new Yo,s=[],a=!1;for(let[i,c]of Object.entries(o.capabilities)){let l=c,u=n.get(l.publisher,l.package_,l.version);if(!u){let p=await cr(i,l,e,r,t);if(p)console.error(` Healed capability "${i}": ${l.publisher}/${l.package_}@${l.version} \u2192 ${p.entry.publisher}/${p.entry.package_}@${p.entry.version} (package was renamed)`),o.capabilities[i]=p.entry,l=p.entry,u=p.content,a=!0;else{console.error(` WARNING: Cached content missing for capability "${i}" (${l.publisher}/${l.package_}@${l.version}). Reinstall it with: kanonak capability remove ${i} && kanonak capability add ${l.publisher}/${l.package_}`);continue}}try{let p=e.parse(u),d=new Sn(p,t),g=await r.parseKanonaks(d),f=_n(g,l.publisher,l.package_,l.version);f?s.push(f):console.error(` WARNING: No Capability instance found in "${i}" (${l.publisher}/${l.package_}@${l.version})`)}catch(p){console.error(` WARNING: Failed to parse capability "${i}": ${p}`)}}return a&&Y(o),s}async function cr(n,e,t,o,r){let s=kn(Xo(),e.publisher);if(!Wo(s))return;let a=[];for(let i of Go(s)){if(!i.endsWith(".kan.yml"))continue;let c=i.slice(0,-8),l=c.lastIndexOf("@");if(l===-1)continue;let u=c.substring(0,l),p=c.substring(l+1);if(u===e.package_&&p===e.version)continue;let d;try{d=Jo(kn(s,i),"utf-8")}catch{continue}let g;try{let f=t.parse(d),m=new Sn(f,r),h=await o.parseKanonaks(m);g=_n(h,e.publisher,u,p)?.commandName}catch{continue}g===n&&a.push({entry:{publisher:e.publisher,package_:u,version:p,resolved:`kanonak://${e.publisher}/${u}@${p}`,integrity:""},content:d})}if(a.length===1)return a[0]}function _n(n,e,t,o){let r=Zo(n,Ce);if(r.length===0)return;let s=r[0],a=O(s,Qo)??"",i=O(s,Cn)??"",c=Pe(s,er),l=Pe(s,nr),u=[];for(let p of Pn(s,tr)){let d=lr(p,n);d&&u.push(d)}return{commandName:a,description:i,managesTypeKey:c?Se(c):"",deploymentTargetKey:l?Se(l):"",commands:u,publisher:e,package_:t,version:o}}function lr(n,e){let t;if(n instanceof vn)t=n;else if(n instanceof $n){let c=xn(e,n.subject.publisher,n.subject.package_,n.subject.name);c&&(t=c)}if(!t)return;let o=O(t,or)??"",r=O(t,Cn)??"",s=Pe(t,rr),a=Pn(t,ar),i=[];for(let c of a){let l=ur(c,e);l&&i.push(l)}return{subcommandName:o,description:r,arguments:i,actionKey:s?Se(s):""}}function ur(n,e){let t;if(n instanceof vn)t=n;else if(n instanceof $n){let c=xn(e,n.subject.publisher,n.subject.package_,n.subject.name);c&&(t=c)}if(!t)return;let o=O(t,sr)??"",r=O(t,yn)==="true"||bn(t,yn)===!0,s=O(t,wn)==="true"||bn(t,wn)===!0,a=O(t,ir),i={argumentName:o,required:r,isOption:s};return a!==void 0&&(i.defaultValue=a),i}function bn(n,e){for(let t of n.statement){let o=t,r=o.predicate;if(r?.subject&&r.subject.publisher===e.publisher&&r.subject.package_===e.package_&&r.subject.name===e.name)return typeof o.object=="boolean"?o.object:void 0}}function xn(n,e,t,o){for(let r of n){if(!("name"in r)||!("namespace"in r))continue;let s=r;if(s.name===o&&!(!s.namespace||typeof s.namespace!="string")&&s.namespace.startsWith(`${e}/${t}@`))return r}}import{findSubjectsByType as wr,getStringValue as br}from"@kanonak-protocol/sdk/uri-helpers";var vr={publisher:P,package_:C,name:"commandName"};function In(){let n=new pr("capability").description("Manage Kanonak CLI capabilities (pluggable command groups)");return n.command("add <package>").description("Install a capability from a Kanonak publisher").action(async e=>{await $r(e)}),n.command("remove <name>").description("Remove an installed capability").action(async e=>{await Sr(e)}),n.command("list").description("List installed capabilities").action(async()=>{await Pr()}),n}async function $r(n){let e=T(n);e||(console.error(`Invalid package reference: "${n}"`),console.error("Expected format: {publisher}/{package}[@{version}]"),process.exit(1));let{publisher:t,packageName:o,version:r,instanceName:s}=e;s&&(console.error(`\`kanonak capability add\` installs whole packages \u2014 got an instance suffix "/${s}".`),console.error(`Try: kanonak capability add ${t}/${o}${r?"@"+r:""}`),process.exit(1));let a=new K,i=new dr,c=new mr,l=new gr,u=hr(l),p=new fr({fetchFn:u}),d=r??await p.getHighestVersion(t,o);d||(console.error(`Could not resolve version for "${t}/${o}".`),process.exit(1)),console.log(`Installing capability ${t}/${o}@${d}...`);let g=a.get(t,o,d);if(!g){let _=await p.getPackageUrl(t,o,d),D=await u(_,t);if(!D.ok)throw new Error(`Failed to fetch ${_} (${D.status} ${D.statusText})`);g=await D.text(),a.put(t,o,d,g)}let f=i.parse(g),m=await $(process.cwd(),i),h=new yr(f,m),k=await c.parseKanonaks(h),y=wr(k,Ce);y.length===0&&(console.error(`Package ${t}/${o}@${d} does not contain a ${P}/${C}/Capability instance.`),process.exit(1));let w=y[0],b=br(w,vr);b||(console.error(`Capability instance in ${t}/${o}@${d} has no commandName property.`),process.exit(1));let v=q();v.capabilities[b]={publisher:t,package_:o,version:d,resolved:await p.getPackageUrl(t,o,d),integrity:kr(g)},Y(v),console.log(`
59
59
  Installed capability "${b}".`),console.log(`Run "kanonak ${b} --help" to get started.`)}async function Sr(n){let e=q();e.capabilities[n]||(console.error(`Capability "${n}" is not installed.`),process.exit(1));let t=e.capabilities[n];delete e.capabilities[n],Y(e),console.log(`Removed capability "${n}" (${t.publisher}/${t.package_}@${t.version}).`)}async function Pr(){let n=q(),e=Object.entries(n.capabilities);if(e.length===0){console.log("No capabilities installed."),console.log("Install one with: kanonak capability add {publisher}/{package}");return}console.log(`Installed capabilities:
60
60
  `);for(let[t,o]of e)console.log(` ${t} ${o.publisher}/${o.package_}@${o.version}`)}import{Command as Z}from"commander";import{readFileSync as Cr,writeFileSync as Rr,mkdirSync as _r,existsSync as Kn,statSync as xr}from"fs";import{join as Ir,resolve as Kr}from"path";import{KanonakParser as xe,KanonakObjectParser as Ie,SubjectKanonak as Dr,Reasoner as Tr,KanonakVocabulary as Er,makeUriKey as En,pickHighestDocument as Ke,formatVersion as jn}from"@kanonak-protocol/sdk";import{SingleDocumentRepository as X}from"@kanonak-protocol/sdk/uri-helpers";import{findSubjectsByType as Re,findSubjectByUri as jr}from"@kanonak-protocol/sdk/uri-helpers";import{TX_V3 as Dn}from"@kanonak-protocol/sdk/transformations";import{TransformationRunnerV3 as Ar,SUPPORTED_FORMATS_V3 as An}from"@kanonak-protocol/sdk/transformations";import{compileTransformationV3 as De}from"@kanonak-protocol/sdk/transformations";function _e(n){return[...Re(n,Dn.InstanceTransformation),...Re(n,Dn.SetTransformation)]}function On(){let n=new Z("transform").description("Run ontology-driven transformations against Kanonak packages. Transformations are declarative YAML rules (instances of `kanonak.org/transformations/Transformation`) that convert ontology instances into output files. The runner produces one or more Artifacts per matched input; format backends serialize them to Markdown, HTML, SVG, TOML, JSON, or (with post-processing) PDF.").addHelpText("after",`
61
61
  Examples:
@@ -95,9 +95,9 @@ Examples:
95
95
 
96
96
  # List the registered format backends
97
97
  $ kanonak transform formats
98
- `);return n.addCommand(Or()),n.addCommand(Fr()),n.addCommand(Vr()),n.addCommand(zr()),n}function Or(){return new Z("run").description("Run a transformation against an input scope and write the resulting Artifacts to disk.").argument("<transformation>","Transformation URI (`publisher/package/name`, optional `@version`) or just the local name if unique in the workspace.").requiredOption("--scope <scope>","Input source \u2014 either a package URI `publisher/package[@version]` (resolved via the local workspace + cache + HTTP tiers) or a file path to a `.kan.yml` document. Repeatable: pass `--scope X --scope Y` to aggregate matching instances across multiple packages, useful for index pages and other cross-package SetTransformations.",Nr,[]).option("--format <name>","OutputFormat name to target (e.g. `markdown-with-frontmatter`, `html`, `svg`, `json`). If omitted and the transformation declares exactly one output, that single format is used.").option("--out <dir>","Directory to write artifacts into.",".").action(async(n,e)=>{try{await Lr(n,e)}catch(t){console.error(`Error: ${t.message}`),process.exit(1)}})}function Nr(n,e){return[...e,n]}async function Lr(n,e){let t=new xe,o=new Ie,r=await $(process.cwd(),t),a=await Nn(n,r,o),{transformation:s,transformationKanonaks:i}=a;console.log(`Transformation: ${ne(s)}`);let c=De(s,i);e.scope.length===0&&(console.error("At least one --scope is required."),process.exit(1));let l=[],u=new Map;for(let y of e.scope){let w=await Br(y,r,t,o);l.push(...w);let b=await Gr(w,c.inputPattern.matchesClass,r);for(let v of b){let _=Jr(v);_&&!u.has(_)&&u.set(_,v)}console.log(`Scope: ${y} \u2014 found ${b.length} instance(s) of ${c.inputPattern.matchesClass.publisher}/${c.inputPattern.matchesClass.package_}/${c.inputPattern.matchesClass.name}`)}let p=[...u.values()],d=l;e.scope.length>1&&console.log(`Total across ${e.scope.length} scope(s): ${p.length} unique instance(s)`),p.length===0&&c.kind==="instance"&&(console.error("No matching input instances across the supplied scope(s). Check the transformation's inputPattern.matchesClass vs. the scope package(s)."),process.exit(1));let g=Ur(c.outputs,e.format);console.log(`Output format: ${g}`);let f=An[g];if(!f)throw new Error(`Unknown format "${g}". Run \`kanonak transform formats\` to see what the runner supports.`);let h=await new Ar().run({transformation:s,instances:p,allKanonaks:d,transformationKanonaks:i,repository:r,parser:t,objectParser:o,outputFormat:g}),k=Kr(e.out);_r(k,{recursive:!0});for(let y of h){let w=Wr(y.fileName),b=Ir(k,`${w}${f.extension}`);Rr(b,y.content,"utf-8"),console.log(` wrote ${b}`)}console.log(`Done. ${h.length} artifact(s) written to ${k}`)}function Ur(n,e){if(e){if(!n.has(e))throw new Error(`Transformation does not declare --format "${e}" in its outputs. Declared outputs: ${Array.from(n).sort().join(", ")}`);return e}if(n.size===1)return Array.from(n)[0];throw new Error(`Transformation supports multiple output formats (${Array.from(n).sort().join(", ")}); pass --format <name> to select one.`)}function Fr(){return new Z("list").description("Scan the local workspace + cache for every Transformation instance and print a one-line summary per hit.").action(async()=>{try{await Mr()}catch(n){console.error(`Error: ${n.message}`),process.exit(1)}})}async function Mr(){let n=new xe,e=new Ie,t=await $(process.cwd(),n),o=await t.getAllDocumentsAsync(),r=new Map;for(let s of o)try{let i=new X(s,t),c=await e.parseKanonaks(i),l=_e(c);for(let u of l){let p=Te(u);if(!p)continue;let d=r.get(p)??[];d.push({tx:u,kanonaks:c,doc:s}),r.set(p,d)}}catch{}let a=[];for(let s of r.values()){if(s.length===1){a.push(Tn(s[0].tx,s[0].kanonaks));continue}let i=Ke(s.map(l=>l.doc));if(!i.chosen)continue;let c=s.find(l=>l.doc===i.chosen);c&&a.push(Tn(c.tx,c.kanonaks))}if(a.length===0){console.log("No Transformation instances found in the current workspace.");return}a.sort((s,i)=>s.uri.localeCompare(i.uri));for(let s of a)console.log(`${s.uri}`),console.log(` matches: ${s.matchesClass}`),console.log(` outputs: ${s.outputs.join(", ")}`)}function Vr(){return new Z("show").description("Compile a transformation and print a human-readable summary (input pattern, outputs, format overrides, rule shape).").argument("<transformation>","Transformation URI or local name").action(async n=>{try{await Hr(n)}catch(e){console.error(`Error: ${e.message}`),process.exit(1)}})}async function Hr(n){let e=new xe,t=new Ie,o=await $(process.cwd(),e),{transformation:r,transformationKanonaks:a}=await Nn(n,o,t),s=De(r,a);if(console.log(`Transformation: ${ne(r)}`),console.log(),console.log("Input pattern:"),console.log(` Matches class: ${ee(s.inputPattern.matchesClass)}`),s.inputPattern.requires.length>0){console.log(" Required properties:");for(let i of s.inputPattern.requires)console.log(` - ${ee(i)}`)}else console.log(" Required properties: (none)");if(console.log(),console.log(`Outputs: ${Array.from(s.outputs).sort().join(", ")}`),console.log(),s.overrides.size>0){console.log("Format overrides:");for(let[i,c]of s.overrides){if(console.log(` ${i}:`),c.metadataKeys&&console.log(` metadata keys: ${c.metadataKeys.join(", ")}`),c.metadataRenames.size>0){let l=[];for(let[u,p]of c.metadataRenames)l.push(`${u} \u2192 ${p}`);console.log(` metadata renames: ${l.join(", ")}`)}c.trailingNewline!==void 0&&console.log(` trailing newline: ${c.trailingNewline}`)}console.log()}console.log(`Rule root kind: ${s.rule.kind}`),s.rule.kind==="build-ast-node"&&(console.log(`Rule root AST class: ${ee(s.rule.astClass)}`),console.log(`Rule root bindings: ${s.rule.set.length} field(s)`)),console.log(`Artifact name root kind: ${s.artifactName.kind}`)}function zr(){return new Z("formats").description("List the OutputFormat names the runner can serialize to.").action(()=>{console.log("Registered format backends:");let n=Object.entries(An).sort(([e],[t])=>e.localeCompare(t));for(let[e,t]of n)console.log(` ${e.padEnd(28)} ${t.extension.padEnd(6)} ${t.formatUri}`)})}async function Nn(n,e,t){let o,r,a;if(n.includes("/")){let d=n.indexOf("@"),g=n;if(d!==-1){let m=n.indexOf("/",d);if(m===-1)throw new Error(`Transformation URI "${n}" has @version but no trailing /<name>`);g=n.substring(0,d)+n.substring(m)}let f=g.split("/");if(f.length<3)throw new Error(`Invalid transformation URI "${n}" \u2014 expected publisher/package/name or publisher/package@version/name`);o=f[0],r=f[1],a=f.slice(2).join("/")}else a=n;if(o&&r){let d=await e.getDocumentsByNamespaceAsync(o,r);if(d.length===0)throw new Error(`Package ${o}/${r} not found in the local workspace or cache.`);let g=qr(n),f=Ln(d,g,`${o}/${r}`),m=new X(f,e),h=await t.parseKanonaks(m),k=jr(h,{publisher:o,package_:r,name:a,version:""});if(!k){let y=_e(h),w=y.find(b=>b.name===a);if(!w)throw new Error(`Transformation "${a}" not found in package ${o}/${r}. Package contains ${y.length} Transformation(s): ${y.map(b=>b.name).join(", ")||"(none)"}`);return{transformation:w,transformationKanonaks:h}}return{transformation:k,transformationKanonaks:h}}let s=await e.getAllDocumentsAsync(),i=new Map;for(let d of s)try{let g=new X(d,e),f=await t.parseKanonaks(g),m=_e(f);for(let h of m){if(h.name!==a)continue;let k=Te(h);if(!k)continue;let y=i.get(k)??[];y.push({tx:h,kanonaks:f,doc:d}),i.set(k,y)}}catch{}if(i.size===0)throw new Error(`No Transformation named "${a}" found in the workspace. Try \`kanonak transform list\` to see available transformations.`);if(i.size>1){let d=Array.from(i.keys()).sort().join(`
99
- `);throw new Error(`Multiple Transformations named "${a}" in the workspace \u2014 disambiguate with a full publisher/package/name URI:
100
- ${d}`)}let c=Array.from(i.values())[0];if(c.length===1)return{transformation:c[0].tx,transformationKanonaks:c[0].kanonaks};let l=new Map(c.map(d=>[d.doc,d])),u=Ke(c.map(d=>d.doc));if(!u.chosen)throw new Error(`Could not select a Transformation version for "${a}".`);let p=l.get(u.chosen);if(u.multipleVersionsPresent){let d=m=>{let h=m.metadata.namespace_?.version;return h?jn(h):""},g=p.tx.namespace??"",f=g.includes("@")?g.substring(0,g.indexOf("@")):g;console.warn(`Warning: Transformation "${a}" has ${c.length} versions present (${c.map(m=>d(m.doc)).filter(Boolean).join(", ")}); using @${d(u.chosen)}. Pin with ${f}@<version>/${a} to suppress this warning.`)}return{transformation:p.tx,transformationKanonaks:p.kanonaks}}async function Br(n,e,t,o){if(/^[.\/\\]/.test(n)||/^[A-Za-z]:/.test(n)||n.endsWith(".kan.yml")||Kn(n)&&xr(n).isFile()){if(!Kn(n))throw new Error(`Scope file not found: ${n}`);let f=Cr(n,"utf-8"),m=t.parse(f),h=new X(m,e);return o.parseKanonaks(h)}let a=n.indexOf("@"),s=a===-1?n:n.substring(0,a),i=a===-1?void 0:n.substring(a+1),c=s.indexOf("/");if(c===-1)throw new Error(`Invalid scope "${n}" \u2014 expected a file path or publisher/package[@version] URI`);let l=s.substring(0,c),u=s.substring(c+1),p=await e.getDocumentsByNamespaceAsync(l,u);if(p.length===0)throw new Error(`Scope package ${l}/${u} not found in the local workspace or cache.`);let d=Ln(p,i,`${l}/${u}`),g=new X(d,e);return o.parseKanonaks(g)}function qr(n){let e=n.indexOf("@");if(e===-1)return;let t=n.substring(e+1),o=t.indexOf("/");return o===-1?t:t.substring(0,o)}function Ln(n,e,t){let o=a=>{let s=a.metadata.namespace_?.version;return s?jn(s):""},r=Ke(n,{requestedVersion:e});if(r.exactRequestedVersionMissing){let a=n.map(o).filter(Boolean).sort().join(", ");throw new Error(`${t}@${e} not found in the local workspace or cache. Available versions: ${a||"(none with parseable namespace)"}`)}if(!r.chosen)throw new Error(`${t} not found in the local workspace or cache.`);return!e&&r.multipleVersionsPresent&&console.warn(`Warning: ${t} has ${n.length} versions present (${n.map(o).filter(Boolean).join(", ")}); using @${o(r.chosen)}. Pin with ${t}@<version> to suppress this warning.`),r.chosen}function Tn(n,e){try{let t=De(n,e);return{uri:ne(n),matchesClass:ee(t.inputPattern.matchesClass),outputs:Array.from(t.outputs).sort()}}catch(t){return{uri:ne(n),matchesClass:`(compile error: ${t.message})`,outputs:[]}}}function ne(n){let e=n.namespace||"",t=e.indexOf("@");return`${t===-1?e:e.substring(0,t)}/${n.name}`}function ee(n){return`${n.publisher}/${n.package_}/${n.name}`}function Wr(n){return n.replace(/[\\/:*?"<>|\s]+/g,"_").replace(/^_+|_+$/g,"")}async function Gr(n,e,t){let o=new Map;for(let s of n){if(!(s instanceof Dr))continue;let i=Te(s);i&&o.set(i,s)}let r=[];try{r=(await new Tr({vocabulary:new Er}).reason(t)).getInstancesOfClass(En(e.publisher,e.package_,e.name))}catch{}let a=[];for(let s of r){let i=o.get(s);i&&a.push(i)}return a.length>0?a:Re(n,e)}function Te(n){let e=n.namespace??"",t=e.indexOf("@"),o=t===-1?e:e.substring(0,t),r=o.indexOf("/");return r===-1||!n.name?null:En(o.substring(0,r),o.substring(r+1),n.name)}function Jr(n){let e=n.namespace??"";return!e||!n.name?null:`${e}/${n.name}`}import{Command as Yr}from"commander";import{writeFileSync as Xr,mkdirSync as Zr}from"fs";import{join as Qr,resolve as es}from"path";import{KanonakParser as ns,KanonakObjectParser as ts,SubjectKanonak as Mn,findDerivation as os}from"@kanonak-protocol/sdk";import{TransformationRunnerV3 as rs}from"@kanonak-protocol/sdk/transformations";var ss={publisher:"kanonak.org",package_:"formats",name:"html"},as={publisher:"kanonak.org",package_:"derivation",name:"default"},is={html:".html",markdown:".md",json:".json",yaml:".yaml",xml:".xml",svg:".svg",typescript:".ts","c-sharp":".cs",rust:".rs",python:".py"};function cs(n){return n==="markdown"?"markdown-with-frontmatter":n}function Vn(){return new Yr("derive").description("Materialize a derived artifact from a Kanonak resource by walking the polymorphic derivation discovery: instance overrides \u2192 class hierarchy \u2192 universal defaults. The result is written to disk.").argument("<resource>","Resource URI in the form publisher/package[@version]/name. Identifies the specific instance to derive.").option("--format <name>","Format instance name (e.g. html, markdown, json). Defaults to html.","html").option("--variant <name>","Variant instance name (e.g. default, compact, summary). Defaults to default.","default").option("--out <dir>","Directory to write the artifact into.",".").addHelpText("after",`
98
+ `);return n.addCommand(Or()),n.addCommand(Fr()),n.addCommand(Vr()),n.addCommand(zr()),n}function Or(){return new Z("run").description("Run a transformation against an input scope and write the resulting Artifacts to disk.").argument("<transformation>","Transformation URI (`publisher/package/name`, optional `@version`) or just the local name if unique in the workspace.").requiredOption("--scope <scope>","Input source \u2014 either a package URI `publisher/package[@version]` (resolved via the local workspace + cache + HTTP tiers) or a file path to a `.kan.yml` document. Repeatable: pass `--scope X --scope Y` to aggregate matching instances across multiple packages, useful for index pages and other cross-package SetTransformations.",Nr,[]).option("--format <name>","OutputFormat name to target (e.g. `markdown-with-frontmatter`, `html`, `svg`, `json`). If omitted and the transformation declares exactly one output, that single format is used.").option("--out <dir>","Directory to write artifacts into.",".").action(async(n,e)=>{try{await Lr(n,e)}catch(t){console.error(`Error: ${t.message}`),process.exit(1)}})}function Nr(n,e){return[...e,n]}async function Lr(n,e){let t=new xe,o=new Ie,r=await $(process.cwd(),t),s=await Nn(n,r,o),{transformation:a,transformationKanonaks:i}=s;console.log(`Transformation: ${ne(a)}`);let c=De(a,i);e.scope.length===0&&(console.error("At least one --scope is required."),process.exit(1));let l=[],u=new Map;for(let y of e.scope){let w=await Br(y,r,t,o);l.push(...w);let b=await Gr(w,c.inputPattern.matchesClass,r);for(let v of b){let _=Jr(v);_&&!u.has(_)&&u.set(_,v)}console.log(`Scope: ${y} \u2014 found ${b.length} instance(s) of ${c.inputPattern.matchesClass.publisher}/${c.inputPattern.matchesClass.package_}/${c.inputPattern.matchesClass.name}`)}let p=[...u.values()],d=l;e.scope.length>1&&console.log(`Total across ${e.scope.length} scope(s): ${p.length} unique instance(s)`),p.length===0&&c.kind==="instance"&&(console.error("No matching input instances across the supplied scope(s). Check the transformation's inputPattern.matchesClass vs. the scope package(s)."),process.exit(1));let g=Ur(c.outputs,e.format);console.log(`Output format: ${g}`);let f=An[g];if(!f)throw new Error(`Unknown format "${g}". Run \`kanonak transform formats\` to see what the runner supports.`);let h=await new Ar().run({transformation:a,instances:p,allKanonaks:d,transformationKanonaks:i,repository:r,parser:t,objectParser:o,outputFormat:g}),k=Kr(e.out);_r(k,{recursive:!0});for(let y of h){let w=Wr(y.fileName),b=Ir(k,`${w}${f.extension}`);Rr(b,y.content,"utf-8"),console.log(` wrote ${b}`)}console.log(`Done. ${h.length} artifact(s) written to ${k}`)}function Ur(n,e){if(e){if(!n.has(e))throw new Error(`Transformation does not declare --format "${e}" in its outputs. Declared outputs: ${Array.from(n).sort().join(", ")}`);return e}if(n.size===1)return Array.from(n)[0];throw new Error(`Transformation supports multiple output formats (${Array.from(n).sort().join(", ")}); pass --format <name> to select one.`)}function Fr(){return new Z("list").description("Scan the local workspace + cache for every Transformation instance and print a one-line summary per hit.").action(async()=>{try{await Mr()}catch(n){console.error(`Error: ${n.message}`),process.exit(1)}})}async function Mr(){let n=new xe,e=new Ie,t=await $(process.cwd(),n),o=await t.getAllDocumentsAsync(),r=new Map;for(let a of o)try{let i=new X(a,t),c=await e.parseKanonaks(i),l=_e(c);for(let u of l){let p=Te(u);if(!p)continue;let d=r.get(p)??[];d.push({tx:u,kanonaks:c,doc:a}),r.set(p,d)}}catch{}let s=[];for(let a of r.values()){if(a.length===1){s.push(Tn(a[0].tx,a[0].kanonaks));continue}let i=Ke(a.map(l=>l.doc));if(!i.chosen)continue;let c=a.find(l=>l.doc===i.chosen);c&&s.push(Tn(c.tx,c.kanonaks))}if(s.length===0){console.log("No Transformation instances found in the current workspace.");return}s.sort((a,i)=>a.uri.localeCompare(i.uri));for(let a of s)console.log(`${a.uri}`),console.log(` matches: ${a.matchesClass}`),console.log(` outputs: ${a.outputs.join(", ")}`)}function Vr(){return new Z("show").description("Compile a transformation and print a human-readable summary (input pattern, outputs, format overrides, rule shape).").argument("<transformation>","Transformation URI or local name").action(async n=>{try{await Hr(n)}catch(e){console.error(`Error: ${e.message}`),process.exit(1)}})}async function Hr(n){let e=new xe,t=new Ie,o=await $(process.cwd(),e),{transformation:r,transformationKanonaks:s}=await Nn(n,o,t),a=De(r,s);if(console.log(`Transformation: ${ne(r)}`),console.log(),console.log("Input pattern:"),console.log(` Matches class: ${ee(a.inputPattern.matchesClass)}`),a.inputPattern.requires.length>0){console.log(" Required properties:");for(let i of a.inputPattern.requires)console.log(` - ${ee(i)}`)}else console.log(" Required properties: (none)");if(console.log(),console.log(`Outputs: ${Array.from(a.outputs).sort().join(", ")}`),console.log(),a.overrides.size>0){console.log("Format overrides:");for(let[i,c]of a.overrides){if(console.log(` ${i}:`),c.metadataKeys&&console.log(` metadata keys: ${c.metadataKeys.join(", ")}`),c.metadataRenames.size>0){let l=[];for(let[u,p]of c.metadataRenames)l.push(`${u} \u2192 ${p}`);console.log(` metadata renames: ${l.join(", ")}`)}c.trailingNewline!==void 0&&console.log(` trailing newline: ${c.trailingNewline}`)}console.log()}console.log(`Rule root kind: ${a.rule.kind}`),a.rule.kind==="build-ast-node"&&(console.log(`Rule root AST class: ${ee(a.rule.astClass)}`),console.log(`Rule root bindings: ${a.rule.set.length} field(s)`)),console.log(`Artifact name root kind: ${a.artifactName.kind}`)}function zr(){return new Z("formats").description("List the OutputFormat names the runner can serialize to.").action(()=>{console.log("Registered format backends:");let n=Object.entries(An).sort(([e],[t])=>e.localeCompare(t));for(let[e,t]of n)console.log(` ${e.padEnd(28)} ${t.extension.padEnd(6)} ${t.formatUri}`)})}async function Nn(n,e,t){let o,r,s;if(n.includes("/")){let d=n.indexOf("@"),g=n;if(d!==-1){let m=n.indexOf("/",d);if(m===-1)throw new Error(`Transformation URI "${n}" has @version but no trailing /<name>`);g=n.substring(0,d)+n.substring(m)}let f=g.split("/");if(f.length<3)throw new Error(`Invalid transformation URI "${n}" \u2014 expected publisher/package/name or publisher/package@version/name`);o=f[0],r=f[1],s=f.slice(2).join("/")}else s=n;if(o&&r){let d=await e.getDocumentsByNamespaceAsync(o,r);if(d.length===0)throw new Error(`Package ${o}/${r} not found in the local workspace or cache.`);let g=qr(n),f=Ln(d,g,`${o}/${r}`),m=new X(f,e),h=await t.parseKanonaks(m),k=jr(h,{publisher:o,package_:r,name:s,version:""});if(!k){let y=_e(h),w=y.find(b=>b.name===s);if(!w)throw new Error(`Transformation "${s}" not found in package ${o}/${r}. Package contains ${y.length} Transformation(s): ${y.map(b=>b.name).join(", ")||"(none)"}`);return{transformation:w,transformationKanonaks:h}}return{transformation:k,transformationKanonaks:h}}let a=await e.getAllDocumentsAsync(),i=new Map;for(let d of a)try{let g=new X(d,e),f=await t.parseKanonaks(g),m=_e(f);for(let h of m){if(h.name!==s)continue;let k=Te(h);if(!k)continue;let y=i.get(k)??[];y.push({tx:h,kanonaks:f,doc:d}),i.set(k,y)}}catch{}if(i.size===0)throw new Error(`No Transformation named "${s}" found in the workspace. Try \`kanonak transform list\` to see available transformations.`);if(i.size>1){let d=Array.from(i.keys()).sort().join(`
99
+ `);throw new Error(`Multiple Transformations named "${s}" in the workspace \u2014 disambiguate with a full publisher/package/name URI:
100
+ ${d}`)}let c=Array.from(i.values())[0];if(c.length===1)return{transformation:c[0].tx,transformationKanonaks:c[0].kanonaks};let l=new Map(c.map(d=>[d.doc,d])),u=Ke(c.map(d=>d.doc));if(!u.chosen)throw new Error(`Could not select a Transformation version for "${s}".`);let p=l.get(u.chosen);if(u.multipleVersionsPresent){let d=m=>{let h=m.metadata.namespace_?.version;return h?jn(h):""},g=p.tx.namespace??"",f=g.includes("@")?g.substring(0,g.indexOf("@")):g;console.warn(`Warning: Transformation "${s}" has ${c.length} versions present (${c.map(m=>d(m.doc)).filter(Boolean).join(", ")}); using @${d(u.chosen)}. Pin with ${f}@<version>/${s} to suppress this warning.`)}return{transformation:p.tx,transformationKanonaks:p.kanonaks}}async function Br(n,e,t,o){if(/^[.\/\\]/.test(n)||/^[A-Za-z]:/.test(n)||n.endsWith(".kan.yml")||Kn(n)&&xr(n).isFile()){if(!Kn(n))throw new Error(`Scope file not found: ${n}`);let f=Cr(n,"utf-8"),m=t.parse(f),h=new X(m,e);return o.parseKanonaks(h)}let s=n.indexOf("@"),a=s===-1?n:n.substring(0,s),i=s===-1?void 0:n.substring(s+1),c=a.indexOf("/");if(c===-1)throw new Error(`Invalid scope "${n}" \u2014 expected a file path or publisher/package[@version] URI`);let l=a.substring(0,c),u=a.substring(c+1),p=await e.getDocumentsByNamespaceAsync(l,u);if(p.length===0)throw new Error(`Scope package ${l}/${u} not found in the local workspace or cache.`);let d=Ln(p,i,`${l}/${u}`),g=new X(d,e);return o.parseKanonaks(g)}function qr(n){let e=n.indexOf("@");if(e===-1)return;let t=n.substring(e+1),o=t.indexOf("/");return o===-1?t:t.substring(0,o)}function Ln(n,e,t){let o=s=>{let a=s.metadata.namespace_?.version;return a?jn(a):""},r=Ke(n,{requestedVersion:e});if(r.exactRequestedVersionMissing){let s=n.map(o).filter(Boolean).sort().join(", ");throw new Error(`${t}@${e} not found in the local workspace or cache. Available versions: ${s||"(none with parseable namespace)"}`)}if(!r.chosen)throw new Error(`${t} not found in the local workspace or cache.`);return!e&&r.multipleVersionsPresent&&console.warn(`Warning: ${t} has ${n.length} versions present (${n.map(o).filter(Boolean).join(", ")}); using @${o(r.chosen)}. Pin with ${t}@<version> to suppress this warning.`),r.chosen}function Tn(n,e){try{let t=De(n,e);return{uri:ne(n),matchesClass:ee(t.inputPattern.matchesClass),outputs:Array.from(t.outputs).sort()}}catch(t){return{uri:ne(n),matchesClass:`(compile error: ${t.message})`,outputs:[]}}}function ne(n){let e=n.namespace||"",t=e.indexOf("@");return`${t===-1?e:e.substring(0,t)}/${n.name}`}function ee(n){return`${n.publisher}/${n.package_}/${n.name}`}function Wr(n){return n.replace(/[\\/:*?"<>|\s]+/g,"_").replace(/^_+|_+$/g,"")}async function Gr(n,e,t){let o=new Map;for(let a of n){if(!(a instanceof Dr))continue;let i=Te(a);i&&o.set(i,a)}let r=[];try{r=(await new Tr({vocabulary:new Er}).reason(t)).getInstancesOfClass(En(e.publisher,e.package_,e.name))}catch{}let s=[];for(let a of r){let i=o.get(a);i&&s.push(i)}return s.length>0?s:Re(n,e)}function Te(n){let e=n.namespace??"",t=e.indexOf("@"),o=t===-1?e:e.substring(0,t),r=o.indexOf("/");return r===-1||!n.name?null:En(o.substring(0,r),o.substring(r+1),n.name)}function Jr(n){let e=n.namespace??"";return!e||!n.name?null:`${e}/${n.name}`}import{Command as Yr}from"commander";import{writeFileSync as Xr,mkdirSync as Zr}from"fs";import{join as Qr,resolve as ea}from"path";import{KanonakParser as na,KanonakObjectParser as ta,SubjectKanonak as Mn,findDerivation as oa}from"@kanonak-protocol/sdk";import{TransformationRunnerV3 as ra}from"@kanonak-protocol/sdk/transformations";var aa={publisher:"kanonak.org",package_:"formats",name:"html"},sa={publisher:"kanonak.org",package_:"derivation",name:"default"},ia={html:".html",markdown:".md",json:".json",yaml:".yaml",xml:".xml",svg:".svg",typescript:".ts","c-sharp":".cs",rust:".rs",python:".py"};function ca(n){return n==="markdown"?"markdown-with-frontmatter":n}function Vn(){return new Yr("derive").description("Materialize a derived artifact from a Kanonak resource by walking the polymorphic derivation discovery: instance overrides \u2192 class hierarchy \u2192 universal defaults. The result is written to disk.").argument("<resource>","Resource URI in the form publisher/package[@version]/name. Identifies the specific instance to derive.").option("--format <name>","Format instance name (e.g. html, markdown, json). Defaults to html.","html").option("--variant <name>","Variant instance name (e.g. default, compact, summary). Defaults to default.","default").option("--out <dir>","Directory to write the artifact into.",".").addHelpText("after",`
101
101
  Examples:
102
102
 
103
103
  # Render a resource as HTML using whatever derivation the discovery
@@ -108,7 +108,7 @@ Examples:
108
108
 
109
109
  # Materialize the JSON view (universal default unless overridden).
110
110
  $ kanonak derive my-publisher.com/my-package/my-resource --format json
111
- `).action(async(n,e)=>{try{await ls(n,e)}catch(t){console.error(`Error: ${t.message}`),process.exit(1)}})}async function ls(n,e){let t=T(n);if(!t||!t.instanceName)throw new Error(`Invalid resource URI "${n}". Expected publisher/package[@version]/instance.`);let o=new ns,r=new ts,a=await $(process.cwd(),o),s=await r.parseKanonaks(a),i=us(s,t);if(!i)throw new Error(`Resource ${t.publisher}/${t.packageName}${t.version?`@${t.version}`:""}/${t.instanceName} not found in the workspace or cache.`);console.log(`Resource: ${Un(i)}`);let c=ds(e.format),l=ms(e.variant),u=os(i,c,l,s);if(!u)throw new Error(`No derivation found for resource ${Un(i)} at (format=${e.format}, variant=${e.variant}). The class hierarchy declares no binding and no universal default applies.`);console.log(`Derivation: ${fs(u)} \u2192 ${Fn(u.transformation)}`);let p=ps(s,u.transformation);if(!p)throw new Error(`Transformation ${Fn(u.transformation)} not found in the workspace or cache. The binding pointed at a transformation the resolver cannot locate.`);let d=cs(e.format),f=await new rs().run({transformation:p,instances:[i],allKanonaks:s,repository:a,parser:o,objectParser:r,outputFormat:d}),m=es(e.out);Zr(m,{recursive:!0});let h=is[e.format]??"";for(let k of f){let y=gs(k.fileName),w=Qr(m,`${y}${h}`);Xr(w,k.content,"utf-8"),console.log(` wrote ${w}`)}console.log(`Done. ${f.length} artifact(s) written to ${m}`)}function us(n,e){for(let t of n){if(!(t instanceof Mn)||t.name!==e.instanceName)continue;let o=t.namespace||"",r=`${e.publisher}/${e.packageName}@`;if(o.startsWith(r))if(e.version){if(o===`${e.publisher}/${e.packageName}@${e.version}`)return t}else return t}}function ps(n,e){let t=`${e.publisher}/${e.package_}@${e.version}`;for(let o of n)if(o instanceof Mn&&o.name===e.name&&o.namespace===t)return o}function ds(n){if(n.includes("/")){let e=T(n);if(!e||!e.instanceName)throw new Error(`Invalid --format URI "${n}".`);return{publisher:e.publisher,package_:e.packageName,name:e.instanceName}}return{...ss,name:n}}function ms(n){if(n.includes("/")){let e=T(n);if(!e||!e.instanceName)throw new Error(`Invalid --variant URI "${n}".`);return{publisher:e.publisher,package_:e.packageName,name:e.instanceName}}return{...as,name:n}}function Un(n){return`${n.namespace}/${n.name}`}function Fn(n){return`${n.publisher}/${n.package_}@${n.version}/${n.name}`}function fs(n){return n.source==="instance"?"instance override":`class ${n.source.publisher}/${n.source.package_}/${n.source.name}`}function gs(n){return n.replace(/[^a-zA-Z0-9._@-]+/g,"_")}import{Command as hs}from"commander";import{writeFileSync as ks}from"fs";import{resolve as ys}from"path";import{KanonakParser as ws,ViewMaterializer as bs}from"@kanonak-protocol/sdk";function Hn(){let n=new hs("view").description("Run and materialize Views \u2014 the producer-agnostic query primitive. A View selects instances of its bind class, filters by its where predicates, and projects each into its produces output class.");return n.command("run").description("Materialize a view.View against the local catalog into an EphemeralPackage (content-addressed, versionless). Prints the result as .kan.yml, or writes it with --out.").argument("<view>","View URI in the form publisher/package[@version]/name. May name a view.View directly or a view.ViewPackage (its rootView is followed).").option("--out <file>","Write the EphemeralPackage to this file instead of stdout.").option("--id <id>","Record a per-invocation id on the result (provenance, not identity).").addHelpText("after",`
111
+ `).action(async(n,e)=>{try{await la(n,e)}catch(t){console.error(`Error: ${t.message}`),process.exit(1)}})}async function la(n,e){let t=T(n);if(!t||!t.instanceName)throw new Error(`Invalid resource URI "${n}". Expected publisher/package[@version]/instance.`);let o=new na,r=new ta,s=await $(process.cwd(),o),a=await r.parseKanonaks(s),i=ua(a,t);if(!i)throw new Error(`Resource ${t.publisher}/${t.packageName}${t.version?`@${t.version}`:""}/${t.instanceName} not found in the workspace or cache.`);console.log(`Resource: ${Un(i)}`);let c=da(e.format),l=ma(e.variant),u=oa(i,c,l,a);if(!u)throw new Error(`No derivation found for resource ${Un(i)} at (format=${e.format}, variant=${e.variant}). The class hierarchy declares no binding and no universal default applies.`);console.log(`Derivation: ${fa(u)} \u2192 ${Fn(u.transformation)}`);let p=pa(a,u.transformation);if(!p)throw new Error(`Transformation ${Fn(u.transformation)} not found in the workspace or cache. The binding pointed at a transformation the resolver cannot locate.`);let d=ca(e.format),f=await new ra().run({transformation:p,instances:[i],allKanonaks:a,repository:s,parser:o,objectParser:r,outputFormat:d}),m=ea(e.out);Zr(m,{recursive:!0});let h=ia[e.format]??"";for(let k of f){let y=ga(k.fileName),w=Qr(m,`${y}${h}`);Xr(w,k.content,"utf-8"),console.log(` wrote ${w}`)}console.log(`Done. ${f.length} artifact(s) written to ${m}`)}function ua(n,e){for(let t of n){if(!(t instanceof Mn)||t.name!==e.instanceName)continue;let o=t.namespace||"",r=`${e.publisher}/${e.packageName}@`;if(o.startsWith(r))if(e.version){if(o===`${e.publisher}/${e.packageName}@${e.version}`)return t}else return t}}function pa(n,e){let t=`${e.publisher}/${e.package_}@${e.version}`;for(let o of n)if(o instanceof Mn&&o.name===e.name&&o.namespace===t)return o}function da(n){if(n.includes("/")){let e=T(n);if(!e||!e.instanceName)throw new Error(`Invalid --format URI "${n}".`);return{publisher:e.publisher,package_:e.packageName,name:e.instanceName}}return{...aa,name:n}}function ma(n){if(n.includes("/")){let e=T(n);if(!e||!e.instanceName)throw new Error(`Invalid --variant URI "${n}".`);return{publisher:e.publisher,package_:e.packageName,name:e.instanceName}}return{...sa,name:n}}function Un(n){return`${n.namespace}/${n.name}`}function Fn(n){return`${n.publisher}/${n.package_}@${n.version}/${n.name}`}function fa(n){return n.source==="instance"?"instance override":`class ${n.source.publisher}/${n.source.package_}/${n.source.name}`}function ga(n){return n.replace(/[^a-zA-Z0-9._@-]+/g,"_")}import{Command as ha}from"commander";import{writeFileSync as ka}from"fs";import{resolve as ya}from"path";import{KanonakParser as wa,ViewMaterializer as ba}from"@kanonak-protocol/sdk";function Hn(){let n=new ha("view").description("Run and materialize Views \u2014 the producer-agnostic query primitive. A View selects instances of its bind class, filters by its where predicates, and projects each into its produces output class.");return n.command("run").description("Materialize a view.View against the local catalog into an EphemeralPackage (content-addressed, versionless). Prints the result as .kan.yml, or writes it with --out.").argument("<view>","View URI in the form publisher/package[@version]/name. May name a view.View directly or a view.ViewPackage (its rootView is followed).").option("--out <file>","Write the EphemeralPackage to this file instead of stdout.").option("--id <id>","Record a per-invocation id on the result (provenance, not identity).").addHelpText("after",`
112
112
  Examples:
113
113
 
114
114
  # Materialize a published view and print the EphemeralPackage.
@@ -116,29 +116,29 @@ Examples:
116
116
 
117
117
  # Write the result to a file.
118
118
  $ kanonak view run example.org/authors/AuthorView --out ./result.kan.yml
119
- `).action(async(e,t)=>{try{await vs(e,t)}catch(o){console.error(`Error: ${o.message}`),process.exit(1)}}),n}async function vs(n,e){let t=T(n);if(!t||!t.instanceName)throw new Error(`Invalid view URI "${n}". Expected publisher/package[@version]/name.`);let o=new ws,r=await $(process.cwd(),o),a=new bs(r,o),s={resolvedAt:new Date().toISOString()};e.id&&(s.invocationId=e.id);let i=await a.materialize({publisher:t.publisher,package_:t.packageName,name:t.instanceName},s);if(e.out){let c=ys(e.out);ks(c,i.yaml,"utf-8"),console.error(`Materialized ${i.rowCount} result(s) \u2192 ${c}
120
- ${i.publisher}/${i.packageName} (${i.contentHash})`)}else process.stdout.write(i.yaml)}import{Command as $s}from"commander";import{writeFileSync as x,mkdirSync as L}from"fs";import{join as S,resolve as zn,dirname as Ss}from"path";import{SubjectKanonak as Ps}from"@kanonak-protocol/sdk";import{loadServerModel as Cs,route as Rs}from"@kanonak-protocol/sdk/server";function Bn(){return new $s("publish").description("Generate a static Kanonak site from the local workspace \u2014 the same origin `kanonak serve` produces (it shares serve's model + renderer), frozen to disk under --out.").option("--workspace <dir>","Workspace directory containing .kan.yml package files. Defaults to current directory.",process.cwd()).option("--out <dir>","Output directory for the generated site. Defaults to _site.","_site").option("--publisher <domain>","Publisher to publish (required only if the workspace has more than one).").action(async n=>{await _s(n)})}async function _s(n){let e=zn(n.workspace),t=zn(n.out),o=await Cs(e,n.publisher?{publisher:n.publisher}:{}),{catalog:r,lookRenderer:a,localNamespaces:s,rawByNsKey:i,publisher:c}=o;L(t,{recursive:!0}),console.log(`Publishing ${c} \u2014 ${s.size} package version(s) to ${t}`);let l=r.filter(f=>f instanceof Ps&&s.has(f.namespace||""));console.log(`Rendering ${l.length} resource(s).`);let u=0,p=0;for(let f of l){let m=(f.namespace||"").split("/")[1]??"",[h,k]=m.split("@");if(!h||!k)continue;let y=S(t,h,k);L(y,{recursive:!0});try{let w=a.renderRawMarkdown(f);w!==void 0&&(x(S(y,`${f.name}.md`),w,"utf-8"),u+=1),x(S(y,`${f.name}.html`),await a.renderDocument(f),"utf-8"),x(S(y,`${f.name}.css`),a.renderStylesheet(f),"utf-8"),x(S(y,`${f.name}.svg`),await a.renderSvg(f),"utf-8"),u+=3}catch(w){console.warn(` ${f.namespace}/${f.name}: ${w.message}`),p+=1}}console.log(`Done. ${u} artifact(s) written, ${p} skipped.`);let d=await Is(t,l,a);console.log(`Wrote ${d} package overview page(s).`),await Ks(t,l,a);let g=Ds(t,l);console.log(`Wrote ${g} version-form redirect stub(s).`),await xs(t,o)}async function xs(n,e){if(e.rawByNsKey.size===0)return;let t=async(o,r)=>{let a=S(n,r);L(Ss(a),{recursive:!0}),x(a,(await Rs(e,o)).body,"utf-8")};await t("/.well-known/kanonak.json",".well-known/kanonak.json"),await t("/index.txt","index.txt");for(let o of e.rawByNsKey.keys()){let[r,a]=o.split("@");!r||!a||await t(`/${r}/${a}.kan.yml`,`${r}/${a}.kan.yml`)}console.log(`Wrote publisher endpoints: index.txt, .well-known/kanonak.json, and ${e.rawByNsKey.size} raw package source(s).`)}async function Is(n,e,t){let o=new Map,r=new Map;for(let i of e){let c=i.namespace||"",[,l]=c.split("/");if(!l)continue;let[u,p]=l.split("@");if(!u||!p||i.name!==u)continue;let d=p.split(".").map(Number);if(d.length!==3||d.some(m=>Number.isNaN(m)))continue;let g={verStr:p,major:d[0],minor:d[1],patch:d[2]};o.has(u)||o.set(u,[]),o.get(u).push({resource:i,ver:g});let f=r.get(u);(!f||g.major>f.ver.major||g.major===f.ver.major&&g.minor>f.ver.minor||g.major===f.ver.major&&g.minor===f.ver.minor&&g.patch>f.ver.patch)&&r.set(u,{resource:i,ver:g})}let a=async(i,c)=>{try{return L(i,{recursive:!0}),x(S(i,"index.html"),await t.renderDocument(c),"utf-8"),x(S(i,`${c.name}.css`),t.renderStylesheet(c),"utf-8"),!0}catch{return!1}},s=0;for(let[i,c]of o)for(let{resource:l,ver:u}of c)await a(S(n,i,u.verStr),l)&&(s+=1);for(let[i,{resource:c}]of r){let l=S(n,i);try{if(L(l,{recursive:!0}),t.hasDeclaredView(c))x(S(l,"index.html"),await t.renderDocument(c,{bareOverview:!0}),"utf-8"),x(S(l,`${c.name}.css`),t.renderStylesheet(c),"utf-8");else{let u=(o.get(i)??[]).slice().sort((p,d)=>d.ver.major-p.ver.major||d.ver.minor-p.ver.minor||d.ver.patch-p.ver.patch).map(p=>p.ver.verStr);x(S(l,"index.html"),t.renderPackageVersionList(i,u,c),"utf-8"),x(S(l,`${c.name}.css`),t.renderStylesheet(c),"utf-8")}s+=1}catch{}}return s}async function Ks(n,e,t){let o="",r=new Map;for(let s of e){let c=(s.namespace||"").split("/"),[l]=(c[1]??"").split("@");if(!c[0]||!l||(o||(o=c[0]),s.name!==l))continue;let u=(c[1]??"").split("@")[1]??"",p=u.split(".").map(Number);if(p.length!==3||p.some(f=>Number.isNaN(f)))continue;let d={verStr:u,major:p[0],minor:p[1],patch:p[2]},g=r.get(l);(!g||d.major>g.ver.major||d.major===g.ver.major&&d.minor>g.ver.minor||d.major===g.ver.major&&d.minor===g.ver.minor&&d.patch>g.ver.patch)&&r.set(l,{resource:s,ver:d})}if(!o||r.size===0)return;let a=t.publisherSubject(o);x(S(n,"index.html"),await t.renderDocument(a,{rootIndex:!0}),"utf-8"),x(S(n,"index.css"),t.renderStylesheet(a),"utf-8")}function Ds(n,e){let t=new Map;for(let r of e){let a=r.namespace||"",[,s]=a.split("/");if(!s)continue;let[i,c]=s.split("@");if(!i||!c)continue;let l=c.split(".").map(Number);if(l.length!==3||l.some(p=>Number.isNaN(p)))continue;let u=`${i}/${r.name}`;t.has(u)||t.set(u,[]),t.get(u).push({verStr:c,major:l[0],minor:l[1],patch:l[2]})}let o=0;for(let[r,a]of t){let[s,i]=r.split("/");a.sort((p,d)=>d.major-p.major||d.minor-p.minor||d.patch-p.patch);let c=a[0];x(S(n,s,`${i}.html`),Ee(`/${s}/${c.verStr}/${i}`),"utf-8"),o+=1;let l=new Set;for(let p of a){if(l.has(p.major))continue;l.add(p.major);let d=S(n,s,String(p.major));L(d,{recursive:!0}),x(S(d,`${i}.html`),Ee(`/${s}/${p.verStr}/${i}`),"utf-8"),o+=1}let u=new Set;for(let p of a){let d=`${p.major}.${p.minor}`;if(u.has(d))continue;u.add(d);let g=S(n,s,d);L(g,{recursive:!0}),x(S(g,`${i}.html`),Ee(`/${s}/${p.verStr}/${i}`),"utf-8"),o+=1}}return o}function Ee(n){let e=n.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;");return`<!doctype html>
119
+ `).action(async(e,t)=>{try{await va(e,t)}catch(o){console.error(`Error: ${o.message}`),process.exit(1)}}),n}async function va(n,e){let t=T(n);if(!t||!t.instanceName)throw new Error(`Invalid view URI "${n}". Expected publisher/package[@version]/name.`);let o=new wa,r=await $(process.cwd(),o),s=new ba(r,o),a={resolvedAt:new Date().toISOString()};e.id&&(a.invocationId=e.id);let i=await s.materialize({publisher:t.publisher,package_:t.packageName,name:t.instanceName},a);if(e.out){let c=ya(e.out);ka(c,i.yaml,"utf-8"),console.error(`Materialized ${i.rowCount} result(s) \u2192 ${c}
120
+ ${i.publisher}/${i.packageName} (${i.contentHash})`)}else process.stdout.write(i.yaml)}import{Command as $a}from"commander";import{writeFileSync as x,mkdirSync as L}from"fs";import{join as S,resolve as zn,dirname as Sa}from"path";import{SubjectKanonak as Pa}from"@kanonak-protocol/sdk";import{loadServerModel as Ca,route as Ra}from"@kanonak-protocol/sdk/server";function Bn(){return new $a("publish").description("Generate a static Kanonak site from the local workspace \u2014 the same origin `kanonak serve` produces (it shares serve's model + renderer), frozen to disk under --out.").option("--workspace <dir>","Workspace directory containing .kan.yml package files. Defaults to current directory.",process.cwd()).option("--out <dir>","Output directory for the generated site. Defaults to _site.","_site").option("--publisher <domain>","Publisher to publish (required only if the workspace has more than one).").action(async n=>{await _a(n)})}async function _a(n){let e=zn(n.workspace),t=zn(n.out),o=await Ca(e,n.publisher?{publisher:n.publisher}:{}),{catalog:r,lookRenderer:s,localNamespaces:a,rawByNsKey:i,publisher:c}=o;L(t,{recursive:!0}),console.log(`Publishing ${c} \u2014 ${a.size} package version(s) to ${t}`);let l=r.filter(f=>f instanceof Pa&&a.has(f.namespace||""));console.log(`Rendering ${l.length} resource(s).`);let u=0,p=0;for(let f of l){let m=(f.namespace||"").split("/")[1]??"",[h,k]=m.split("@");if(!h||!k)continue;let y=S(t,h,k);L(y,{recursive:!0});try{let w=s.renderRawMarkdown(f);w!==void 0&&(x(S(y,`${f.name}.md`),w,"utf-8"),u+=1),x(S(y,`${f.name}.html`),await s.renderDocument(f),"utf-8"),x(S(y,`${f.name}.css`),s.renderStylesheet(f),"utf-8"),x(S(y,`${f.name}.svg`),await s.renderSvg(f),"utf-8"),u+=3}catch(w){console.warn(` ${f.namespace}/${f.name}: ${w.message}`),p+=1}}console.log(`Done. ${u} artifact(s) written, ${p} skipped.`);let d=await Ia(t,l,s);console.log(`Wrote ${d} package overview page(s).`),await Ka(t,l,s);let g=Da(t,l);console.log(`Wrote ${g} version-form redirect stub(s).`),await xa(t,o)}async function xa(n,e){if(e.rawByNsKey.size===0)return;let t=async(o,r)=>{let s=S(n,r);L(Sa(s),{recursive:!0}),x(s,(await Ra(e,o)).body,"utf-8")};await t("/.well-known/kanonak.json",".well-known/kanonak.json"),await t("/index.txt","index.txt");for(let o of e.rawByNsKey.keys()){let[r,s]=o.split("@");!r||!s||await t(`/${r}/${s}.kan.yml`,`${r}/${s}.kan.yml`)}console.log(`Wrote publisher endpoints: index.txt, .well-known/kanonak.json, and ${e.rawByNsKey.size} raw package source(s).`)}async function Ia(n,e,t){let o=new Map,r=new Map;for(let i of e){let c=i.namespace||"",[,l]=c.split("/");if(!l)continue;let[u,p]=l.split("@");if(!u||!p||i.name!==u)continue;let d=p.split(".").map(Number);if(d.length!==3||d.some(m=>Number.isNaN(m)))continue;let g={verStr:p,major:d[0],minor:d[1],patch:d[2]};o.has(u)||o.set(u,[]),o.get(u).push({resource:i,ver:g});let f=r.get(u);(!f||g.major>f.ver.major||g.major===f.ver.major&&g.minor>f.ver.minor||g.major===f.ver.major&&g.minor===f.ver.minor&&g.patch>f.ver.patch)&&r.set(u,{resource:i,ver:g})}let s=async(i,c)=>{try{return L(i,{recursive:!0}),x(S(i,"index.html"),await t.renderDocument(c),"utf-8"),x(S(i,`${c.name}.css`),t.renderStylesheet(c),"utf-8"),!0}catch{return!1}},a=0;for(let[i,c]of o)for(let{resource:l,ver:u}of c)await s(S(n,i,u.verStr),l)&&(a+=1);for(let[i,{resource:c}]of r){let l=S(n,i);try{if(L(l,{recursive:!0}),t.hasDeclaredView(c))x(S(l,"index.html"),await t.renderDocument(c,{bareOverview:!0}),"utf-8"),x(S(l,`${c.name}.css`),t.renderStylesheet(c),"utf-8");else{let u=(o.get(i)??[]).slice().sort((p,d)=>d.ver.major-p.ver.major||d.ver.minor-p.ver.minor||d.ver.patch-p.ver.patch).map(p=>p.ver.verStr);x(S(l,"index.html"),t.renderPackageVersionList(i,u,c),"utf-8"),x(S(l,`${c.name}.css`),t.renderStylesheet(c),"utf-8")}a+=1}catch{}}return a}async function Ka(n,e,t){let o="",r=new Map;for(let a of e){let c=(a.namespace||"").split("/"),[l]=(c[1]??"").split("@");if(!c[0]||!l||(o||(o=c[0]),a.name!==l))continue;let u=(c[1]??"").split("@")[1]??"",p=u.split(".").map(Number);if(p.length!==3||p.some(f=>Number.isNaN(f)))continue;let d={verStr:u,major:p[0],minor:p[1],patch:p[2]},g=r.get(l);(!g||d.major>g.ver.major||d.major===g.ver.major&&d.minor>g.ver.minor||d.major===g.ver.major&&d.minor===g.ver.minor&&d.patch>g.ver.patch)&&r.set(l,{resource:a,ver:d})}if(!o||r.size===0)return;let s=t.publisherSubject(o);x(S(n,"index.html"),await t.renderDocument(s,{rootIndex:!0}),"utf-8"),x(S(n,"index.css"),t.renderStylesheet(s),"utf-8")}function Da(n,e){let t=new Map;for(let r of e){let s=r.namespace||"",[,a]=s.split("/");if(!a)continue;let[i,c]=a.split("@");if(!i||!c)continue;let l=c.split(".").map(Number);if(l.length!==3||l.some(p=>Number.isNaN(p)))continue;let u=`${i}/${r.name}`;t.has(u)||t.set(u,[]),t.get(u).push({verStr:c,major:l[0],minor:l[1],patch:l[2]})}let o=0;for(let[r,s]of t){let[a,i]=r.split("/");s.sort((p,d)=>d.major-p.major||d.minor-p.minor||d.patch-p.patch);let c=s[0];x(S(n,a,`${i}.html`),Ee(`/${a}/${c.verStr}/${i}`),"utf-8"),o+=1;let l=new Set;for(let p of s){if(l.has(p.major))continue;l.add(p.major);let d=S(n,a,String(p.major));L(d,{recursive:!0}),x(S(d,`${i}.html`),Ee(`/${a}/${p.verStr}/${i}`),"utf-8"),o+=1}let u=new Set;for(let p of s){let d=`${p.major}.${p.minor}`;if(u.has(d))continue;u.add(d);let g=S(n,a,d);L(g,{recursive:!0}),x(S(g,`${i}.html`),Ee(`/${a}/${p.verStr}/${i}`),"utf-8"),o+=1}}return o}function Ee(n){let e=n.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;");return`<!doctype html>
121
121
  <meta charset="utf-8">
122
122
  <title>Redirecting\u2026</title>
123
123
  <meta http-equiv="refresh" content="0; url=${e}">
124
124
  <link rel="canonical" href="${e}">
125
125
  <p>If you are not redirected automatically, follow this <a href="${e}">link</a>.</p>
126
- `}import{Command as Yn}from"commander";import{writeFileSync as je,mkdirSync as te}from"fs";import{join as Ae,resolve as Ts,dirname as Oe}from"path";import{KanonakParser as Es,KanonakObjectParser as js,SubjectKanonak as Xn,ReferenceStatement as As,ReferenceKanonak as Os,ListStatement as Ns,StringStatement as Zn,EmbeddedStatement as Ls,findDerivation as qn}from"@kanonak-protocol/sdk";import{SingleDocumentRepository as Us}from"@kanonak-protocol/sdk/uri-helpers";import{TransformationRunnerV3 as Fs}from"@kanonak-protocol/sdk/transformations";import{findSubjectsByType as oe}from"@kanonak-protocol/sdk/uri-helpers";var E="kanonak.org",j="site",Wn={publisher:"kanonak.org",package_:"formats",name:"html"},Gn={publisher:"kanonak.org",package_:"derivation",name:"default"};function Qn(){let n=new Yn("site").description("Materialize a publisher's site \u2014 every StaticPage and AggregateView in the workspace gets rendered to its declared output path under the --out directory.");return n.addCommand(Ms()),n}function Ms(){return new Yn("build").description("Walk the workspace, find every StaticPage and AggregateView, and write each materialized artifact to its declared output path under the --out directory.").option("--out <dir>","Output base directory.","./_site").action(async n=>{try{await Vs(n)}catch(e){console.error(`Error: ${e.message}`),process.exit(1)}})}async function Vs(n){let e=new Es,t=new js,o=await $(process.cwd(),e),r=await t.parseKanonaks(o),a=Ts(n.out);te(a,{recursive:!0});let s=await o.getAllDocumentsAsync(),i=new Set;for(let m of s){let h=m.metadata.namespace_?.toString();h&&i.add(h)}let c={publisher:E,package_:j,name:"StaticPage"},l={publisher:E,package_:j,name:"ResourcePage"},u={publisher:E,package_:j,name:"AggregateView"},p=oe(r,c).filter(m=>i.has(m.namespace||"")),d=oe(r,l).filter(m=>i.has(m.namespace||"")),g=oe(r,u).filter(m=>i.has(m.namespace||""));console.log(`Found ${p.length} StaticPage(s), ${d.length} ResourcePage(s), and ${g.length} AggregateView(s) in the workspace.`);let f=new Fs;for(let m of p){let h=Ne(m,E,j,"outputPath")??`${m.name}.html`,k=qn(m,Wn,Gn,r);if(!k){console.warn(` [skip] ${m.name}: no HTML/default derivation found (check class hierarchy or universal-derivations is loaded)`);continue}let y=Le(r,k.transformation);if(!y){console.warn(` [skip] ${m.name}: transformation ${Ue(k.transformation)} not found`);continue}let w=await f.run({transformation:y,instances:[m],allKanonaks:r,repository:o,parser:e,objectParser:t,outputFormat:"html"});if(w.length===0){console.warn(` [skip] ${m.name}: transformation produced no artifacts`);continue}let b=Ae(a,h);te(Oe(b),{recursive:!0}),je(b,w[0].content,"utf-8"),console.log(` wrote ${b} (StaticPage ${m.name})`)}for(let m of d){let h=Ne(m,E,j,"outputPath")??`${m.name}.html`,k=Jn(m,E,j,"pageOf");if(!k){console.warn(` [skip] ${m.name}: no pageOf declared`);continue}let y=r.find(D=>D instanceof Xn&&D.name===k.name&&(D.namespace||"").startsWith(`${k.publisher}/${k.package_}@`));if(!y){console.warn(` [skip] ${m.name}: pageOf target ${k.publisher}/${k.package_}/${k.name} not found`);continue}let w=qn(y,Wn,Gn,r);if(!w){console.warn(` [skip] ${m.name}: no derivation for target ${y.name}`);continue}let b=Le(r,w.transformation);if(!b){console.warn(` [skip] ${m.name}: transformation ${Ue(w.transformation)} not found`);continue}let v=await f.run({transformation:b,instances:[y],allKanonaks:r,repository:o,parser:e,objectParser:t,outputFormat:"html"});if(v.length===0){console.warn(` [skip] ${m.name}: transformation produced no artifacts`);continue}let _=Ae(a,h);te(Oe(_),{recursive:!0}),je(_,v[0].content,"utf-8"),console.log(` wrote ${_} (ResourcePage ${m.name} \u2192 ${y.name})`)}for(let m of g){let h=Ne(m,E,j,"outputPath");if(!h){console.warn(` [skip] ${m.name}: no outputPath declared`);continue}let k=Jn(m,E,j,"scopeClass");if(!k){console.warn(` [skip] ${m.name}: no scopeClass declared`);continue}let y={publisher:k.publisher,package_:k.package_,name:k.name},w=Hs(m,E,j,"scopeSources"),b=zs(m);if(!b){console.warn(` [skip] ${m.name}: no transformation declared`);continue}let v=Le(r,b);if(!v){console.warn(` [skip] ${m.name}: transformation ${Ue(b)} not found`);continue}let _=await qs(w,o),D=[],Xe=new Set;for(let qt of _){let Wt=await Ws(qt,o,e,t),Gt=oe(Wt,y);for(let ye of Gt){let Qe=`${ye.namespace}/${ye.name}`;Xe.has(Qe)||(Xe.add(Qe),D.push(ye))}}console.log(` ${m.name}: ${D.length} instance(s) of ${y.publisher}/${y.package_}/${y.name} across ${_.length} scope(s)`);let Ze=await f.run({transformation:v,instances:D,allKanonaks:r,repository:o,parser:e,objectParser:t,outputFormat:"html"});if(Ze.length===0){console.warn(` [skip] ${m.name}: transformation produced no artifacts`);continue}let ke=Ae(a,h);te(Oe(ke),{recursive:!0}),je(ke,Ze[0].content,"utf-8"),console.log(` wrote ${ke} (AggregateView ${m.name})`)}console.log("Site build complete.")}function Ne(n,e,t,o){for(let r of n.statement)if(r instanceof Zn&&re(r,e,t,o))return r.object}function Hs(n,e,t,o){for(let r of n.statement){if(!(r instanceof Ns)||!re(r,e,t,o))continue;let a=[];for(let s of r.object??[]){let i=s.value;typeof i=="string"&&a.push(i)}return a}return[]}function Jn(n,e,t,o){for(let r of n.statement)if(r instanceof As&&re(r,e,t,o)&&r.object instanceof Os)return{publisher:r.object.subject.publisher,package_:r.object.subject.package_,name:r.object.subject.name}}function zs(n){for(let e of n.statement)if(e instanceof Ls&&re(e,E,j,"transformation"))return Bs(e.object)}function Bs(n){let e,t,o,r;for(let a of n.statement){if(!(a instanceof Zn))continue;let s=a.predicate?.subject?.name;s==="publisher"?e=a.object:s==="package"?t=a.object:s==="version"?o=a.object:s==="name"&&(r=a.object)}if(!(!e||!t||!o||!r))return{publisher:e,package_:t,version:o,name:r}}function re(n,e,t,o){let r=n.predicate?.subject;return r?r.publisher===e&&r.package_===t&&r.name===o:!1}function Le(n,e){let t=`${e.publisher}/${e.package_}@${e.version}`;for(let o of n)if(o instanceof Xn&&o.name===e.name&&o.namespace===t)return o}function Ue(n){return`${n.publisher}/${n.package_}@${n.version}/${n.name}`}async function qs(n,e){let t=[];for(let o of n){let r=o.indexOf("@*");if(r===-1){t.push(o);continue}let a=o.substring(0,r),s=a.indexOf("/");if(s===-1){t.push(o);continue}let i=a.substring(0,s),c=a.substring(s+1),l=await e.getDocumentsByNamespaceAsync(i,c);for(let u of l){let p=u.metadata.namespace_;if(!p)continue;let d=p.version;t.push(`${p.publisher}/${p.package_}@${d.major}.${d.minor}.${d.patch}`)}}return t}async function Ws(n,e,t,o){let r=n.indexOf("/"),a=n.indexOf("@");if(r===-1||a===-1)return[];let s=n.substring(0,r),i=n.substring(r+1,a),c=n.substring(a+1),l=await e.getDocumentsByNamespaceAsync(s,i);for(let u of l){let p=u.metadata.namespace_?.version;if(p&&`${p.major}.${p.minor}.${p.patch}`===c){let d=new Us(u,e);return o.parseKanonaks(d)}}return[]}import{Command as Gs}from"commander";import{createServer as et}from"http";import{watch as nt}from"fs";import{resolve as Js}from"path";import{loadServerModel as tt,route as Ys,RequestRouter as Xs}from"@kanonak-protocol/sdk/server";var Fe={"Access-Control-Allow-Origin":"*"};function ot(n,e){n.writeHead(e.status,{...e.headers,...Fe}),n.end(e.body)}function rt(){return new Gs("serve").description("Serve Kanonak resources as a live origin \u2014 the same rendering `kanonak publish` produces, plus the machine-facing publisher endpoints, from one process. With --publisher it serves that single publisher (closed world, like the published site); without it, it serves any publisher per request path and links across publishers (open world). Use --watch for a dev preview.").option("--root <dir>","Workspace root to serve.",".").option("--port <number>","Port to listen on.","8080").option("--publisher <domain>","Serve ONLY this publisher (closed world \u2014 no links to other publishers, mirroring the published site). Omit for the open-world model.").option("--watch","Re-load on .kan.yml changes.",!1).action(async n=>{let e=Js(n.root),t=Number(n.port);if(!Number.isInteger(t)||t<=0||t>65535)throw new Error(`Invalid --port "${n.port}".`);if(n.publisher){let o;try{o=await tt(e,{publisher:n.publisher})}catch(r){console.error(`[error] ${r.message}`),process.exitCode=1;return}Zs(e,t,n,o)}else Qs(e,t,n)})}function Zs(n,e,t,o){let r=o,a=async s=>{let i=Date.now();r=await tt(n,t.publisher?{publisher:t.publisher}:{});let c=r.availablePublishers.filter(l=>l!==r.publisher);console.log(`[model] serving ${r.publisher} \u2014 ${r.pkgVersions.size} package(s)${s?` (${s})`:""} in ${Date.now()-i}ms`+(c.length?` [also in workspace: ${c.join(", ")} \u2014 switch with --publisher]`:""))};if(t.watch){let s;nt(n,{recursive:!0},(i,c)=>{!c||!String(c).endsWith(".kan.yml")||(clearTimeout(s),s=setTimeout(()=>{a(`changed: ${c}`).catch(l=>console.error("[reload error]",l.message))},150))}),console.log("[watch] re-loading on .kan.yml changes")}et(async(s,i)=>{let c="/";try{let l=new URL(s.url??"/","http://localhost");c=decodeURIComponent(l.pathname);let u=await Ys(r,c,s.headers.accept??"");ot(i,u),console.log(`${u.status} ${s.method} ${c}${u.headers.Location?` -> ${u.headers.Location}`:""}`)}catch(l){i.writeHead(500,{"Content-Type":"text/plain; charset=utf-8",...Fe}),i.end(String(l?.stack??l)),console.error(`500 ${c}: ${l?.message??l}`)}}).listen(e,()=>{console.log(`kanonak origin server \u2192 http://localhost:${e}/ (root=${n}, publisher=${r.publisher})`)})}function Qs(n,e,t){let o=new Xs({root:n});if(t.watch){let r;nt(n,{recursive:!0},(a,s)=>{!s||!String(s).endsWith(".kan.yml")||(clearTimeout(r),r=setTimeout(()=>{o.clearCache(),console.log("[watch] cleared model cache")},150))}),console.log("[watch] clearing model cache on .kan.yml changes")}et(async(r,a)=>{let s="/";try{let i=new URL(r.url??"/","http://localhost");s=decodeURIComponent(i.pathname);let c=await o.handle(s,r.headers.accept??"");ot(a,c),console.log(`${c.status} ${r.method} ${s}${c.headers.Location?` -> ${c.headers.Location}`:""}`)}catch(i){a.writeHead(502,{"Content-Type":"text/plain; charset=utf-8",...Fe}),a.end(String(i?.message??i)),console.error(`502 ${s}: ${i?.message??i}`)}}).listen(e,()=>{console.log(`kanonak request-driven origin \u2192 http://localhost:${e}/ (root=${n})`),console.log("[request-driven] no publisher pinned \u2014 derive per path: /{publisher}/{package}/{version}/{resource}")})}import{Command as ea}from"commander";import{resolve as na,join as ta}from"path";import{loadLockFile as oa,computeIntegrity as Me}from"@kanonak-protocol/sdk";function st(){return new ea("verify").description("Verify cached packages against kanonak.lock (the cache is untrusted). With --remote, also re-fetch each package from its origin and compare. Exits non-zero on any integrity mismatch.").option("--workspace <dir>","Workspace directory containing kanonak.lock.",process.cwd()).option("--remote","Also re-fetch each package from its recorded origin and verify.",!1).action(async n=>{await sa(n)})}function ra(n){let e=n.indexOf("/");if(!(e<0))return{publisher:n.slice(0,e),package_:n.slice(e+1)}}async function sa(n){let e=na(n.workspace),t=oa(ta(e,"kanonak.lock"));t||(console.error(`No kanonak.lock found in ${e} \u2014 nothing to verify (run \`kanonak install\` first).`),process.exit(1));let o=new K,r=Object.entries(t.packages);console.log(`Verifying ${r.length} locked package(s) against kanonak.lock${n.remote?" (cache + origin)":" (cache)"}\u2026`);let a=0,s=0,i=0,c=0;for(let[u,p]of r){let d=ra(u);if(!d){console.error(` \u2717 ${u} \u2014 unparseable lock key`),s+=1;continue}let{publisher:g,package_:f}=d,m=o.get(g,f,p.version);if(m===null?(console.warn(` ? ${u} \u2014 not in cache`),i+=1):Me(m)===p.integrity?a+=1:(console.error(` \u2717 ${u} \u2014 CACHE does not match lock`),console.error(` lock: ${p.integrity}`),console.error(` cache: ${Me(m)}`),s+=1),n.remote){let h=await aa(u,p);h?(console.error(h),s+=1):c+=1}}let l=[`${a} cache OK`];n.remote&&l.push(`${c} origin OK`),i&&l.push(`${i} not cached`),l.push(`${s} mismatch`),console.log(`
127
- ${l.join(", ")}.`),s>0&&(console.error("Integrity verification FAILED \u2014 a package does not match the committed lock."),process.exit(1)),console.log("Integrity verified.")}async function aa(n,e){try{let t=await fetch(e.resolved);if(!t.ok)return` \u2717 ${n} \u2014 origin fetch ${t.status} from ${e.resolved}`;let o=await t.text(),r=Me(o);return r===e.integrity?void 0:` \u2717 ${n} \u2014 ORIGIN does not match lock (${e.resolved})
126
+ `}import{Command as Yn}from"commander";import{writeFileSync as je,mkdirSync as te}from"fs";import{join as Ae,resolve as Ta,dirname as Oe}from"path";import{KanonakParser as Ea,KanonakObjectParser as ja,SubjectKanonak as Xn,ReferenceStatement as Aa,ReferenceKanonak as Oa,ListStatement as Na,StringStatement as Zn,EmbeddedStatement as La,findDerivation as qn}from"@kanonak-protocol/sdk";import{SingleDocumentRepository as Ua}from"@kanonak-protocol/sdk/uri-helpers";import{TransformationRunnerV3 as Fa}from"@kanonak-protocol/sdk/transformations";import{findSubjectsByType as oe}from"@kanonak-protocol/sdk/uri-helpers";var E="kanonak.org",j="site",Wn={publisher:"kanonak.org",package_:"formats",name:"html"},Gn={publisher:"kanonak.org",package_:"derivation",name:"default"};function Qn(){let n=new Yn("site").description("Materialize a publisher's site \u2014 every StaticPage and AggregateView in the workspace gets rendered to its declared output path under the --out directory.");return n.addCommand(Ma()),n}function Ma(){return new Yn("build").description("Walk the workspace, find every StaticPage and AggregateView, and write each materialized artifact to its declared output path under the --out directory.").option("--out <dir>","Output base directory.","./_site").action(async n=>{try{await Va(n)}catch(e){console.error(`Error: ${e.message}`),process.exit(1)}})}async function Va(n){let e=new Ea,t=new ja,o=await $(process.cwd(),e),r=await t.parseKanonaks(o),s=Ta(n.out);te(s,{recursive:!0});let a=await o.getAllDocumentsAsync(),i=new Set;for(let m of a){let h=m.metadata.namespace_?.toString();h&&i.add(h)}let c={publisher:E,package_:j,name:"StaticPage"},l={publisher:E,package_:j,name:"ResourcePage"},u={publisher:E,package_:j,name:"AggregateView"},p=oe(r,c).filter(m=>i.has(m.namespace||"")),d=oe(r,l).filter(m=>i.has(m.namespace||"")),g=oe(r,u).filter(m=>i.has(m.namespace||""));console.log(`Found ${p.length} StaticPage(s), ${d.length} ResourcePage(s), and ${g.length} AggregateView(s) in the workspace.`);let f=new Fa;for(let m of p){let h=Ne(m,E,j,"outputPath")??`${m.name}.html`,k=qn(m,Wn,Gn,r);if(!k){console.warn(` [skip] ${m.name}: no HTML/default derivation found (check class hierarchy or universal-derivations is loaded)`);continue}let y=Le(r,k.transformation);if(!y){console.warn(` [skip] ${m.name}: transformation ${Ue(k.transformation)} not found`);continue}let w=await f.run({transformation:y,instances:[m],allKanonaks:r,repository:o,parser:e,objectParser:t,outputFormat:"html"});if(w.length===0){console.warn(` [skip] ${m.name}: transformation produced no artifacts`);continue}let b=Ae(s,h);te(Oe(b),{recursive:!0}),je(b,w[0].content,"utf-8"),console.log(` wrote ${b} (StaticPage ${m.name})`)}for(let m of d){let h=Ne(m,E,j,"outputPath")??`${m.name}.html`,k=Jn(m,E,j,"pageOf");if(!k){console.warn(` [skip] ${m.name}: no pageOf declared`);continue}let y=r.find(D=>D instanceof Xn&&D.name===k.name&&(D.namespace||"").startsWith(`${k.publisher}/${k.package_}@`));if(!y){console.warn(` [skip] ${m.name}: pageOf target ${k.publisher}/${k.package_}/${k.name} not found`);continue}let w=qn(y,Wn,Gn,r);if(!w){console.warn(` [skip] ${m.name}: no derivation for target ${y.name}`);continue}let b=Le(r,w.transformation);if(!b){console.warn(` [skip] ${m.name}: transformation ${Ue(w.transformation)} not found`);continue}let v=await f.run({transformation:b,instances:[y],allKanonaks:r,repository:o,parser:e,objectParser:t,outputFormat:"html"});if(v.length===0){console.warn(` [skip] ${m.name}: transformation produced no artifacts`);continue}let _=Ae(s,h);te(Oe(_),{recursive:!0}),je(_,v[0].content,"utf-8"),console.log(` wrote ${_} (ResourcePage ${m.name} \u2192 ${y.name})`)}for(let m of g){let h=Ne(m,E,j,"outputPath");if(!h){console.warn(` [skip] ${m.name}: no outputPath declared`);continue}let k=Jn(m,E,j,"scopeClass");if(!k){console.warn(` [skip] ${m.name}: no scopeClass declared`);continue}let y={publisher:k.publisher,package_:k.package_,name:k.name},w=Ha(m,E,j,"scopeSources"),b=za(m);if(!b){console.warn(` [skip] ${m.name}: no transformation declared`);continue}let v=Le(r,b);if(!v){console.warn(` [skip] ${m.name}: transformation ${Ue(b)} not found`);continue}let _=await qa(w,o),D=[],Xe=new Set;for(let qt of _){let Wt=await Wa(qt,o,e,t),Gt=oe(Wt,y);for(let ye of Gt){let Qe=`${ye.namespace}/${ye.name}`;Xe.has(Qe)||(Xe.add(Qe),D.push(ye))}}console.log(` ${m.name}: ${D.length} instance(s) of ${y.publisher}/${y.package_}/${y.name} across ${_.length} scope(s)`);let Ze=await f.run({transformation:v,instances:D,allKanonaks:r,repository:o,parser:e,objectParser:t,outputFormat:"html"});if(Ze.length===0){console.warn(` [skip] ${m.name}: transformation produced no artifacts`);continue}let ke=Ae(s,h);te(Oe(ke),{recursive:!0}),je(ke,Ze[0].content,"utf-8"),console.log(` wrote ${ke} (AggregateView ${m.name})`)}console.log("Site build complete.")}function Ne(n,e,t,o){for(let r of n.statement)if(r instanceof Zn&&re(r,e,t,o))return r.object}function Ha(n,e,t,o){for(let r of n.statement){if(!(r instanceof Na)||!re(r,e,t,o))continue;let s=[];for(let a of r.object??[]){let i=a.value;typeof i=="string"&&s.push(i)}return s}return[]}function Jn(n,e,t,o){for(let r of n.statement)if(r instanceof Aa&&re(r,e,t,o)&&r.object instanceof Oa)return{publisher:r.object.subject.publisher,package_:r.object.subject.package_,name:r.object.subject.name}}function za(n){for(let e of n.statement)if(e instanceof La&&re(e,E,j,"transformation"))return Ba(e.object)}function Ba(n){let e,t,o,r;for(let s of n.statement){if(!(s instanceof Zn))continue;let a=s.predicate?.subject?.name;a==="publisher"?e=s.object:a==="package"?t=s.object:a==="version"?o=s.object:a==="name"&&(r=s.object)}if(!(!e||!t||!o||!r))return{publisher:e,package_:t,version:o,name:r}}function re(n,e,t,o){let r=n.predicate?.subject;return r?r.publisher===e&&r.package_===t&&r.name===o:!1}function Le(n,e){let t=`${e.publisher}/${e.package_}@${e.version}`;for(let o of n)if(o instanceof Xn&&o.name===e.name&&o.namespace===t)return o}function Ue(n){return`${n.publisher}/${n.package_}@${n.version}/${n.name}`}async function qa(n,e){let t=[];for(let o of n){let r=o.indexOf("@*");if(r===-1){t.push(o);continue}let s=o.substring(0,r),a=s.indexOf("/");if(a===-1){t.push(o);continue}let i=s.substring(0,a),c=s.substring(a+1),l=await e.getDocumentsByNamespaceAsync(i,c);for(let u of l){let p=u.metadata.namespace_;if(!p)continue;let d=p.version;t.push(`${p.publisher}/${p.package_}@${d.major}.${d.minor}.${d.patch}`)}}return t}async function Wa(n,e,t,o){let r=n.indexOf("/"),s=n.indexOf("@");if(r===-1||s===-1)return[];let a=n.substring(0,r),i=n.substring(r+1,s),c=n.substring(s+1),l=await e.getDocumentsByNamespaceAsync(a,i);for(let u of l){let p=u.metadata.namespace_?.version;if(p&&`${p.major}.${p.minor}.${p.patch}`===c){let d=new Ua(u,e);return o.parseKanonaks(d)}}return[]}import{Command as Ga}from"commander";import{createServer as et}from"http";import{watch as nt}from"fs";import{resolve as Ja}from"path";import{loadServerModel as tt,route as Ya,RequestRouter as Xa}from"@kanonak-protocol/sdk/server";var Fe={"Access-Control-Allow-Origin":"*"};function ot(n,e){n.writeHead(e.status,{...e.headers,...Fe}),n.end(e.body)}function rt(){return new Ga("serve").description("Serve Kanonak resources as a live origin \u2014 the same rendering `kanonak publish` produces, plus the machine-facing publisher endpoints, from one process. With --publisher it serves that single publisher (closed world, like the published site); without it, it serves any publisher per request path and links across publishers (open world). Use --watch for a dev preview.").option("--root <dir>","Workspace root to serve.",".").option("--port <number>","Port to listen on.","8080").option("--publisher <domain>","Serve ONLY this publisher (closed world \u2014 no links to other publishers, mirroring the published site). Omit for the open-world model.").option("--watch","Re-load on .kan.yml changes.",!1).action(async n=>{let e=Ja(n.root),t=Number(n.port);if(!Number.isInteger(t)||t<=0||t>65535)throw new Error(`Invalid --port "${n.port}".`);if(n.publisher){let o;try{o=await tt(e,{publisher:n.publisher})}catch(r){console.error(`[error] ${r.message}`),process.exitCode=1;return}Za(e,t,n,o)}else Qa(e,t,n)})}function Za(n,e,t,o){let r=o,s=async a=>{let i=Date.now();r=await tt(n,t.publisher?{publisher:t.publisher}:{});let c=r.availablePublishers.filter(l=>l!==r.publisher);console.log(`[model] serving ${r.publisher} \u2014 ${r.pkgVersions.size} package(s)${a?` (${a})`:""} in ${Date.now()-i}ms`+(c.length?` [also in workspace: ${c.join(", ")} \u2014 switch with --publisher]`:""))};if(t.watch){let a;nt(n,{recursive:!0},(i,c)=>{!c||!String(c).endsWith(".kan.yml")||(clearTimeout(a),a=setTimeout(()=>{s(`changed: ${c}`).catch(l=>console.error("[reload error]",l.message))},150))}),console.log("[watch] re-loading on .kan.yml changes")}et(async(a,i)=>{let c="/";try{let l=new URL(a.url??"/","http://localhost");c=decodeURIComponent(l.pathname);let u=await Ya(r,c,a.headers.accept??"");ot(i,u),console.log(`${u.status} ${a.method} ${c}${u.headers.Location?` -> ${u.headers.Location}`:""}`)}catch(l){i.writeHead(500,{"Content-Type":"text/plain; charset=utf-8",...Fe}),i.end(String(l?.stack??l)),console.error(`500 ${c}: ${l?.message??l}`)}}).listen(e,()=>{console.log(`kanonak origin server \u2192 http://localhost:${e}/ (root=${n}, publisher=${r.publisher})`)})}function Qa(n,e,t){let o=new Xa({root:n});if(t.watch){let r;nt(n,{recursive:!0},(s,a)=>{!a||!String(a).endsWith(".kan.yml")||(clearTimeout(r),r=setTimeout(()=>{o.clearCache(),console.log("[watch] cleared model cache")},150))}),console.log("[watch] clearing model cache on .kan.yml changes")}et(async(r,s)=>{let a="/";try{let i=new URL(r.url??"/","http://localhost");a=decodeURIComponent(i.pathname);let c=await o.handle(a,r.headers.accept??"");ot(s,c),console.log(`${c.status} ${r.method} ${a}${c.headers.Location?` -> ${c.headers.Location}`:""}`)}catch(i){s.writeHead(502,{"Content-Type":"text/plain; charset=utf-8",...Fe}),s.end(String(i?.message??i)),console.error(`502 ${a}: ${i?.message??i}`)}}).listen(e,()=>{console.log(`kanonak request-driven origin \u2192 http://localhost:${e}/ (root=${n})`),console.log("[request-driven] no publisher pinned \u2014 derive per path: /{publisher}/{package}/{version}/{resource}")})}import{Command as es}from"commander";import{resolve as ns,join as ts}from"path";import{loadLockFile as os,computeIntegrity as Me}from"@kanonak-protocol/sdk";function at(){return new es("verify").description("Verify cached packages against kanonak.lock (the cache is untrusted). With --remote, also re-fetch each package from its origin and compare. Exits non-zero on any integrity mismatch.").option("--workspace <dir>","Workspace directory containing kanonak.lock.",process.cwd()).option("--remote","Also re-fetch each package from its recorded origin and verify.",!1).action(async n=>{await as(n)})}function rs(n){let e=n.indexOf("/");if(!(e<0))return{publisher:n.slice(0,e),package_:n.slice(e+1)}}async function as(n){let e=ns(n.workspace),t=os(ts(e,"kanonak.lock"));t||(console.error(`No kanonak.lock found in ${e} \u2014 nothing to verify (run \`kanonak install\` first).`),process.exit(1));let o=new K,r=Object.entries(t.packages);console.log(`Verifying ${r.length} locked package(s) against kanonak.lock${n.remote?" (cache + origin)":" (cache)"}\u2026`);let s=0,a=0,i=0,c=0;for(let[u,p]of r){let d=rs(u);if(!d){console.error(` \u2717 ${u} \u2014 unparseable lock key`),a+=1;continue}let{publisher:g,package_:f}=d,m=o.get(g,f,p.version);if(m===null?(console.warn(` ? ${u} \u2014 not in cache`),i+=1):Me(m)===p.integrity?s+=1:(console.error(` \u2717 ${u} \u2014 CACHE does not match lock`),console.error(` lock: ${p.integrity}`),console.error(` cache: ${Me(m)}`),a+=1),n.remote){let h=await ss(u,p);h?(console.error(h),a+=1):c+=1}}let l=[`${s} cache OK`];n.remote&&l.push(`${c} origin OK`),i&&l.push(`${i} not cached`),l.push(`${a} mismatch`),console.log(`
127
+ ${l.join(", ")}.`),a>0&&(console.error("Integrity verification FAILED \u2014 a package does not match the committed lock."),process.exit(1)),console.log("Integrity verified.")}async function ss(n,e){try{let t=await fetch(e.resolved);if(!t.ok)return` \u2717 ${n} \u2014 origin fetch ${t.status} from ${e.resolved}`;let o=await t.text(),r=Me(o);return r===e.integrity?void 0:` \u2717 ${n} \u2014 ORIGIN does not match lock (${e.resolved})
128
128
  lock: ${e.integrity}
129
- origin: ${r}`}catch(t){return` \u2717 ${n} \u2014 origin fetch failed: ${t.message}`}}import{Command as ia}from"commander";import{resolve as ca,join as la}from"path";import{homedir as ua}from"os";import{readFileSync as pa}from"fs";import{KanonakParser as at,KanonakObjectParser as da,PublisherIndex as it,CredentialStore as ct,createAuthenticatedFetch as lt,FileSystemKanonakDocumentRepository as ma,Reasoner as fa,KanonakVocabulary as ga,getGlobalCachePath as ha,makeUriKey as ka,resolveDisplayValue as ya,subjectUri as wa,contextTypesOf as ba,collectKanonakFiles as va}from"@kanonak-protocol/sdk";import{SearchIndex as $a}from"@kanonak-protocol/sdk/search";function Sa(n){let e=n.split("/");if(e.length!==3)return null;let[t,o,r]=e;return!t||!o||!r?null:{publisher:t,package_:o,name:r}}function ut(){return new ia("search").description("Semantic-search your workspace (-q), browse a publisher's catalogue, or find instances of a class").argument("[publisher]","Publisher domain (e.g. kanonak.org) \u2014 for the catalogue / --type modes").option("-q, --query <text>","Semantically search the LOCAL workspace for resources matching free-text keywords").option("--root <dir>","Workspace root for -q",".").option("--scope <prefix>","Limit -q to namespaces starting with this prefix (e.g. kanonak.org/look@)").option("--limit <n>","Max results for -q","20").option("--format <fmt>","Output for -q: text | json","text").option("--all","For -q: index imported packages too (default: only your workspace's own resources)",!1).option("--type <uri>","Class URI to search for, in publisher/package/Name form").action(async(n,e)=>{if(e.query){await Pa(e);return}n||(console.error(`Nothing to search. Either:
129
+ origin: ${r}`}catch(t){return` \u2717 ${n} \u2014 origin fetch failed: ${t.message}`}}import{Command as is}from"commander";import{resolve as cs,join as ls}from"path";import{homedir as us}from"os";import{readFileSync as ps}from"fs";import{KanonakParser as st,KanonakObjectParser as ds,PublisherIndex as it,CredentialStore as ct,createAuthenticatedFetch as lt,FileSystemKanonakDocumentRepository as ms,Reasoner as fs,KanonakVocabulary as gs,getGlobalCachePath as hs,makeUriKey as ks,resolveDisplayValue as ys,subjectUri as ws,contextTypesOf as bs,collectKanonakFiles as vs}from"@kanonak-protocol/sdk";import{SearchIndex as $s}from"@kanonak-protocol/sdk/search";function Ss(n){let e=n.split("/");if(e.length!==3)return null;let[t,o,r]=e;return!t||!o||!r?null:{publisher:t,package_:o,name:r}}function ut(){return new is("search").description("Semantic-search your workspace (-q), browse a publisher's catalogue, or find instances of a class").argument("[publisher]","Publisher domain (e.g. kanonak.org) \u2014 for the catalogue / --type modes").option("-q, --query <text>","Semantically search the LOCAL workspace for resources matching free-text keywords").option("--root <dir>","Workspace root for -q",".").option("--scope <prefix>","Limit -q to namespaces starting with this prefix (e.g. kanonak.org/look@)").option("--limit <n>","Max results for -q","20").option("--format <fmt>","Output for -q: text | json","text").option("--all","For -q: index imported packages too (default: only your workspace's own resources)",!1).option("--type <uri>","Class URI to search for, in publisher/package/Name form").action(async(n,e)=>{if(e.query){await Ps(e);return}n||(console.error(`Nothing to search. Either:
130
130
  \u2022 semantic-search your workspace: kanonak search -q "<keywords>"
131
131
  \u2022 browse a publisher's catalogue: kanonak search <publisher>
132
- \u2022 find instances of a class: kanonak search <publisher> --type <pub>/<pkg>/<Name>`),process.exit(1)),e.type?await Ra(n,e.type):await Ca(n)})}async function Pa(n){let e=ca(n.root??"."),t=new at,o;try{let u=await $(e,t);o=await new da().parseKanonaks(u)}catch(u){console.error(`Failed to load workspace at ${e}: ${u.message}`),process.exit(1)}let r={cacheDir:la(ua(),".kanonak","search"),onProgress:(u,p)=>process.stderr.write(`\r embedding ${u}/${p}\u2026 `)};if(!n.all){let u=new Set;for(let p of va(e))try{let d=t.parse(pa(p,"utf-8")).metadata?.namespace_;d?.version&&u.add(`${d.publisher}/${d.package_}@${d.version.major}.${d.version.minor}.${d.version.patch}`)}catch{}r.include=p=>u.has(p.namespace??"")}let a=new $a,s;try{s=await a.build(o,r),s.size>0&&!s.cached&&process.stderr.write(`
133
- `)}catch(u){console.error(u.message),process.exit(1)}s.size===0&&(console.error(n.all?`No resources found in the workspace at ${e}.`:`No resources defined in the workspace at ${e}. (It imports packages but defines none of its own \u2014 use --all to also search imported packages.)`),process.exit(1));let i=Number(n.limit)||20,l=(await a.query(n.query,{scope:n.scope,limit:i})).map(u=>{let p=ya(o,u.subject),d=wa(u.subject),g=ba(u.subject)[0]?.name;return{uri:d?`${d.publisher}/${d.package_}/${d.name}`:u.subject.name,label:p.label,type:g??null,score:Number(u.score.toFixed(4))}});if(n.format==="json"){console.log(JSON.stringify(l,null,2));return}if(l.length===0){console.log(`No matches for "${n.query}".`);return}console.log(`Results for "${n.query}":
134
- `);for(let u of l)console.log(` ${u.score.toFixed(3)} ${u.label}${u.type?` (${u.type})`:""}`),console.log(` ${u.uri}`)}async function Ca(n){let e=new ct,t=lt(e),o=new it({fetchFn:t}),r;try{r=await o.listLatestPackages(n)}catch(s){console.error(`Failed to fetch publisher index for ${n}: ${s.message}`),process.exit(1)}if(r.length===0){console.log(`No packages found at ${n}.`);return}console.log(`Packages published by ${n}:
135
- `);let a=r.reduce((s,i)=>Math.max(s,i.packageName.length),0);for(let{packageName:s,version:i}of r)console.log(` ${s.padEnd(a)} @${i}`)}async function Ra(n,e){let t=Sa(e);t||(console.error(`Invalid --type value: ${e}`),console.error("Expected: publisher/package/Name (e.g. kanonak.org/capabilities/Capability)"),process.exit(1));let o=new at,r=new ct,a=lt(r),s=new it({fetchFn:a}),i=new K,c=new Set,l=[];try{l=await s.listLatestPackages(n)}catch(h){console.error(`Failed to fetch publisher index for ${n}: ${h.message}`),process.exit(1)}for(let{packageName:h,version:k}of l)c.add(`${n}|${h}|${k}`);await Ve(s,i,a,"kanonak.org","core-rdf",c),await Ve(s,i,a,"kanonak.org","core-owl",c),await Ve(s,i,a,t.publisher,t.package_,c);for(let h of c){let[k,y,w]=h.split("|");if(!i.has(k,y,w))try{let b=await s.getPackageUrl(k,y,w),v=await a(b,k);if(!v.ok){console.error(`Warning: failed to fetch ${k}/${y}@${w}: ${v.status} ${v.statusText}`);continue}let _=await v.text();i.put(k,y,w,_)}catch(b){console.error(`Warning: failed to fetch ${k}/${y}@${w}: ${b.message}`)}}let u=new ma(ha(),!0,o),d=await new fa({vocabulary:new ga}).reason(u),g=ka(t.publisher,t.package_,t.name),m=d.getInstancesOfClass(g).filter(h=>h!==g);if(m.length===0){console.log(`No instances of ${g} found in ${n}'s catalogue.`);return}console.log(`Instances of ${g} in ${n}'s catalogue:
136
- `),m.sort();for(let h of m)console.log(` ${h}`)}async function Ve(n,e,t,o,r,a){try{let s=await n.getHighestVersion(o,r);if(!s)return;a.add(`${o}|${r}|${s}`)}catch{}}import{existsSync as _a,readFileSync as xa}from"fs";import{dirname as Ia,resolve as Ka}from"path";import{KanonakObjectParser as Da,KanonakParser as Ta,canonicalForm as Ea,canonicalHash as ja,parseKanonakAddress as Aa,pickHighestDocument as Oa}from"@kanonak-protocol/sdk";import{SingleDocumentRepository as Na}from"@kanonak-protocol/sdk/uri-helpers";async function pt(n,e={}){let t=new Ta,o=new Da,{document:r,source:a}=await La(n,t),s=await $(Ua(a),t),i=new Na(r,s),c=await o.parseKanonaks(i),l=ja(c);if(console.log(l),e.verbose){let u=Ea(c);process.stderr.write(`# canonical form for ${a}
137
- `),process.stderr.write(u),process.stderr.write(`
138
- `)}}async function La(n,e){if(n.endsWith(".kan.yml")){let i=Ka(n);if(!_a(i))throw new Error(`kanonak hash: file not found: ${i}`);let c=xa(i,"utf-8");return{document:e.parse(c),source:i}}let t=Aa(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=Oa(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 Ua(n){return n.endsWith(".kan.yml")?N(Ia(n)):process.cwd()}import{Command as dt}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 mt(n,e,t){for(let o of e){let r=new dt(o.commandName).description(o.description.trim());for(let a of o.commands){let s=r.command(Fa(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=Ma(i);await Va(t,o,a,i,c)})}n.addCommand(r)}}function Fa(n){let e=n.arguments.filter(t=>!t.isOption).map(t=>t.required?`<${t.argumentName}>`:`[${t.argumentName}]`);return[n.subcommandName,...e].join(" ")}function Ma(n){for(let e=n.length-1;e>=0;e--)if(n[e]&&typeof n[e]=="object"&&!(n[e]instanceof dt))return n[e];return{}}async function Va(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 ft,readFileSync as Ha,statSync as gt}from"fs";import{resolve as za}from"path";import{KanonakObjectParser as Ba,PublisherIndex as ze,PublisherConfigResolver as qa,formatVersion as ht,pickHighestDocument as Wa}from"@kanonak-protocol/sdk";import{SingleDocumentRepository as kt}from"@kanonak-protocol/sdk/uri-helpers";import{uriKey as G,findSubjectsByType as yt}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 Ba;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=Wa(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=ht(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")||ft(e)&&gt(e).isFile()))return;let o=za(e);(!ft(o)||!gt(o).isFile())&&(console.error(`Local file not found: ${e}`),process.exit(1));let r=Ha(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:ht(s.version)}}async deployFromDoc(e,t,o,r,a,s,i,c){let l=new kt(t,this.repository),u=await this.objectParser.parseKanonaks(l),p=wt(e.managesTypeKey);p||(console.error(`Capability "${e.commandName}" has no resolved managesType.`),process.exit(1));let d=yt(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:Ga(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
- `);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.":`
132
+ \u2022 find instances of a class: kanonak search <publisher> --type <pub>/<pkg>/<Name>`),process.exit(1)),e.type?await Rs(n,e.type):await Cs(n)})}async function Ps(n){let e=cs(n.root??"."),t=new st,o;try{let u=await $(e,t);o=await new ds().parseKanonaks(u)}catch(u){console.error(`Failed to load workspace at ${e}: ${u.message}`),process.exit(1)}let r={cacheDir:ls(us(),".kanonak","search"),onProgress:(u,p)=>process.stderr.write(`\r embedding ${u}/${p}\u2026 `)};if(!n.all){let u=new Set;for(let p of vs(e))try{let d=t.parse(ps(p,"utf-8")).metadata?.namespace_;d?.version&&u.add(`${d.publisher}/${d.package_}@${d.version.major}.${d.version.minor}.${d.version.patch}`)}catch{}r.include=p=>u.has(p.namespace??"")}let s=new $s,a;try{a=await s.build(o,r),a.size>0&&!a.cached&&process.stderr.write(`
133
+ `)}catch(u){console.error(u.message),process.exit(1)}a.size===0&&(console.error(n.all?`No resources found in the workspace at ${e}.`:`No resources defined in the workspace at ${e}. (It imports packages but defines none of its own \u2014 use --all to also search imported packages.)`),process.exit(1));let i=Number(n.limit)||20,l=(await s.query(n.query,{scope:n.scope,limit:i})).map(u=>{let p=ys(o,u.subject),d=ws(u.subject),g=bs(u.subject)[0]?.name;return{uri:d?`${d.publisher}/${d.package_}/${d.name}`:u.subject.name,label:p.label,type:g??null,score:Number(u.score.toFixed(4))}});if(n.format==="json"){console.log(JSON.stringify(l,null,2));return}if(l.length===0){console.log(`No matches for "${n.query}".`);return}console.log(`Results for "${n.query}":
134
+ `);for(let u of l)console.log(` ${u.score.toFixed(3)} ${u.label}${u.type?` (${u.type})`:""}`),console.log(` ${u.uri}`)}async function Cs(n){let e=new ct,t=lt(e),o=new it({fetchFn:t}),r;try{r=await o.listLatestPackages(n)}catch(a){console.error(`Failed to fetch publisher index for ${n}: ${a.message}`),process.exit(1)}if(r.length===0){console.log(`No packages found at ${n}.`);return}console.log(`Packages published by ${n}:
135
+ `);let s=r.reduce((a,i)=>Math.max(a,i.packageName.length),0);for(let{packageName:a,version:i}of r)console.log(` ${a.padEnd(s)} @${i}`)}async function Rs(n,e){let t=Ss(e);t||(console.error(`Invalid --type value: ${e}`),console.error("Expected: publisher/package/Name (e.g. kanonak.org/capabilities/Capability)"),process.exit(1));let o=new st,r=new ct,s=lt(r),a=new it({fetchFn:s}),i=new K,c=new Set,l=[];try{l=await a.listLatestPackages(n)}catch(h){console.error(`Failed to fetch publisher index for ${n}: ${h.message}`),process.exit(1)}for(let{packageName:h,version:k}of l)c.add(`${n}|${h}|${k}`);await Ve(a,i,s,"kanonak.org","core-rdf",c),await Ve(a,i,s,"kanonak.org","core-owl",c),await Ve(a,i,s,t.publisher,t.package_,c);for(let h of c){let[k,y,w]=h.split("|");if(!i.has(k,y,w))try{let b=await a.getPackageUrl(k,y,w),v=await s(b,k);if(!v.ok){console.error(`Warning: failed to fetch ${k}/${y}@${w}: ${v.status} ${v.statusText}`);continue}let _=await v.text();i.put(k,y,w,_)}catch(b){console.error(`Warning: failed to fetch ${k}/${y}@${w}: ${b.message}`)}}let u=new ms(hs(),!0,o),d=await new fs({vocabulary:new gs}).reason(u),g=ks(t.publisher,t.package_,t.name),m=d.getInstancesOfClass(g).filter(h=>h!==g);if(m.length===0){console.log(`No instances of ${g} found in ${n}'s catalogue.`);return}console.log(`Instances of ${g} in ${n}'s catalogue:
136
+ `),m.sort();for(let h of m)console.log(` ${h}`)}async function Ve(n,e,t,o,r,s){try{let a=await n.getHighestVersion(o,r);if(!a)return;s.add(`${o}|${r}|${a}`)}catch{}}import{existsSync as _s,readFileSync as xs}from"fs";import{dirname as Is,join as Ks,resolve as Ds}from"path";import{KanonakObjectParser as Ts,KanonakParser as Es,canonicalForm as js,canonicalHash as As,parseKanonakAddress as Os,pickHighestDocument as Ns,loadLockFile as Ls,LockAwareRepository as Us}from"@kanonak-protocol/sdk";import{SingleDocumentRepository as Fs}from"@kanonak-protocol/sdk/uri-helpers";async function pt(n,e={}){let t=new Es,o=new Ts,{document:r,source:s}=await Ms(n,t),a=Hs(s),i=await $(a,t),c=Ks(a,"kanonak.lock"),l=Ls(c);if(e.frozen){if(!l)throw new Error(`kanonak hash --frozen: no kanonak.lock found at ${c}. Run 'kanonak install' to generate one.`);Vs(r,l,c)}let u=l?new Us(i,l):i,p=new Fs(r,u),d=await o.parseKanonaks(p),g=As(d);if(console.log(g),e.verbose){let f=js(d);process.stderr.write(`# canonical form for ${s}
137
+ `),process.stderr.write(f),process.stderr.write(`
138
+ `)}}async function Ms(n,e){if(n.endsWith(".kan.yml")){let i=Ds(n);if(!_s(i))throw new Error(`kanonak hash: file not found: ${i}`);let c=xs(i,"utf-8");return{document:e.parse(c),source:i}}let t=Os(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 s=t.version?`${t.version.major}.${t.version.minor}.${t.version.patch}`:void 0,a=Ns(r,s?{requestedVersion:s}:{});if(!a.chosen){let i=s?`@${s}`:"";throw new Error(`kanonak hash: no version of ${t.publisher}/${t.package_}${i} available across local/cache/HTTP`)}return{document:a.chosen,source:n}}function Vs(n,e,t){let o=new Set(["kanonak.org/core-kanonak"]);for(let s of n.metadata.allImports??[])o.add(`${s.publisher??"kanonak.org"}/${s.packageName}`);let r=[...o].filter(s=>!e.packages[s]);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 Hs(n){return n.endsWith(".kan.yml")?N(Is(n)):process.cwd()}import{Command as dt}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 mt(n,e,t){for(let o of e){let r=new dt(o.commandName).description(o.description.trim());for(let s of o.commands){let a=r.command(zs(s));a.description(s.description);for(let i of s.arguments)if(i.isOption){let c=i.defaultValue!=null?`--${i.argumentName} [value]`:`--${i.argumentName} <value>`;a.option(c,"",i.defaultValue)}a.action(async(...i)=>{let c=Bs(i);await qs(t,o,s,i,c)})}n.addCommand(r)}}function zs(n){let e=n.arguments.filter(t=>!t.isOption).map(t=>t.required?`<${t.argumentName}>`:`[${t.argumentName}]`);return[n.subcommandName,...e].join(" ")}function Bs(n){for(let e=n.length-1;e>=0;e--)if(n[e]&&typeof n[e]=="object"&&!(n[e]instanceof dt))return n[e];return{}}async function qs(n,e,t,o,r){let s=[];for(let i of o)if(typeof i=="string")s.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 a=He[t.actionKey];a||(console.error(`Capability subcommand '${t.subcommandName}' references unknown Action '${t.actionKey}'. Known actions: ${Object.keys(He).join(", ")}.`),process.exit(1)),await a(n,e,s,r)}import{existsSync as ft,readFileSync as Ws,statSync as gt}from"fs";import{resolve as Gs}from"path";import{KanonakObjectParser as Js,PublisherIndex as ze,PublisherConfigResolver as Ys,formatVersion as ht,pickHighestDocument as Xs}from"@kanonak-protocol/sdk";import{SingleDocumentRepository as kt}from"@kanonak-protocol/sdk/uri-helpers";import{uriKey as G,findSubjectsByType as yt}from"@kanonak-protocol/sdk/uri-helpers";var ae=class{constructor(e,t,o,r,s,a){this.fileCache=e;this.parser=t;this.publisherIndex=o;this.fetchFn=r;this.handlerRegistry=s;this.repository=a}fileCache;parser;publisherIndex;fetchFn;handlerRegistry;repository;objectParser=new Js;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 s=T(t);s||(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:a,packageName:i,version:c,instanceName:l}=s,u=await this.repository.getDocumentsByNamespaceAsync(a,i);if(u.length>0){let g=Xs(u,{requestedVersion:c??void 0});if(g.chosen){let f=g.chosen.metadata.namespace_;(!f||!f.version)&&(console.error(`Document for ${a}/${i} is missing namespace metadata.`),process.exit(1));let m=ht(f.version);this.fileCache.put(a,i,m,this.parser.save(g.chosen)),await this.deployFromDoc(e,g.chosen,a,i,m,l??void 0,`${a}/${i}@${m}`,o);return}}let p=c??await this.publisherIndex.getHighestVersion(a,i);p||(console.error(`Could not resolve version for "${a}/${i}".`),await this.printPackageSuggestions(a,i,e.commandName),process.exit(1));let d=this.fileCache.get(a,i,p);if(!d){let g=await this.publisherIndex.getPackageUrl(a,i,p),f=await this.fetchFn(g,a);f.ok||(f.status===404?(console.error(`Package ${a}/${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(a,i,p,d)}await this.deployFromDoc(e,this.parser.parse(d),a,i,p,l??void 0,`${a}/${i}@${p}`,o)}tryLoadFromLocalFile(e){if(!(/^[.\/\\]/.test(e)||/^[A-Za-z]:[\\/]/.test(e)||e.endsWith(".kan.yml")||ft(e)&&gt(e).isFile()))return;let o=Gs(e);(!ft(o)||!gt(o).isFile())&&(console.error(`Local file not found: ${e}`),process.exit(1));let r=Ws(o,"utf-8"),s=this.parser.parse(r),a=s.metadata.namespace_;return(!a||!a.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:s,content:r,publisher:a.publisher,packageName:a.package_,version:ht(a.version)}}async deployFromDoc(e,t,o,r,s,a,i,c){let l=new kt(t,this.repository),u=await this.objectParser.parseKanonaks(l),p=wt(e.managesTypeKey);p||(console.error(`Capability "${e.commandName}" has no resolved managesType.`),process.exit(1));let d=yt(u,p);d.length===0&&(console.error(`${i} does not contain any ${G(p)} instances.`),process.exit(1));let g=d;if(a&&(g=d.filter(h=>h.name===a),g.length===0)){console.error(`Instance "${a}" 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=a?`${a} 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}@${s} (no deployment handler for "${e.deploymentTargetKey}")`)}async printPackageSuggestions(e,t,o){let r;try{r=await this.publisherIndex.listLatestPackages(e)}catch{return}let s=r.map(a=>({name:a.packageName,version:a.version,score:Zs(t,a.packageName)})).filter(a=>a.score>0).sort((a,i)=>i.score-a.score).slice(0,5);if(s.length!==0){console.error(""),console.error("Did you mean one of:");for(let a of s)console.error(` kanonak ${o} add ${e}/${a.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}),s=e.managesTypeKey||"managed";if(r.length===0){console.log(`No ${s} instances installed.`);return}console.log(`Installed ${s} instances:
139
+ `);for(let a of r){let i=a.publisher?`${a.publisher}/${a.package_}@${a.version}`:"unmanaged";console.log(` ${a.name} (${i}) ${a.path}`)}}async update(e,t,o){let s=await this.requireHandler(e).list({repository:this.repository,options:o}),a=t?s.filter(c=>c.name===t):s.filter(c=>c.publisher);if(a.length===0){console.log(t?`"${t}" not found.`:"No managed instances to update.");return}let i=0;for(let c of a){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=wt(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 qa,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 kt(y,this.repository),b=await this.objectParser.parseKanonaks(w),v=yt(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
- `);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 wt(n){if(!n)return;let e=n.split("/");if(e.length===3)return{publisher:e[0],package_:e[1],name:e[2]}}function Ga(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=Ja(t,o);return i===0?100:i<=2?Math.max(1,20-i*5):0}function Ja(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 ii,rmSync as ci,existsSync as ue,readdirSync as li,writeFileSync as ui}from"fs";import{join as pe}from"path";import{KanonakObjectParser as pi,KanonakParser as di,computeIntegrity as mi,compareVersions as fi}from"@kanonak-protocol/sdk";import{findSubjectsByType as gi}from"@kanonak-protocol/sdk/uri-helpers";import{SingleDocumentRepository as hi}from"@kanonak-protocol/sdk/uri-helpers";import{TransformationRunnerV3 as ki}from"@kanonak-protocol/sdk/transformations";import{TX_V3 as yi}from"@kanonak-protocol/sdk/transformations";import{join as Be}from"path";import{homedir as bt}from"os";import{KanonakObjectParser as Ya}from"@kanonak-protocol/sdk";import{SingleDocumentRepository as Xa}from"@kanonak-protocol/sdk/uri-helpers";import{findSubjectsByType as $t,getStringValue as ie}from"@kanonak-protocol/sdk/uri-helpers";var U="kanonak.org",F="agent-skills",St={publisher:U,package_:F,name:"Client"},Pt={publisher:U,package_:F,name:"clientId"},Za={publisher:U,package_:F,name:"projectSkillDir"},Qa={publisher:U,package_:F,name:"userSkillDir"},ei={publisher:U,package_:F,name:"skillFileName"},Ct="agents";async function Q(n,e){let t=(n.client??Rt()??Ct).toLowerCase(),o=n.scope??"project",r=await xt(t,e);if(!r){let i=await ni(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"?Qa:Za);if(!s)throw new Error(`Client "${t}" has no ${o==="user"?"userSkillDir":"projectSkillDir"} declared.`);return ti(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??Rt()??Ct).toLowerCase(),o=await xt(t,e);return o?ie(o,ei)??"SKILL.md":"SKILL.md"}function Rt(){if(process.env.CLAUDE_CODE||process.env.CLAUDE_PROJECT_DIR)return"claude-code"}var vt=new WeakMap;async function _t(n){let e=vt.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 Ya,s=new Xa(r,n),i=await a.parseKanonaks(s);return vt.set(n,i),i}async function xt(n,e){let t=await _t(e),o=$t(t,St);for(let r of o)if(ie(r,Pt)===n)return r}async function ni(n){let e=await _t(n),t=$t(e,St),o=[];for(let r of t){let a=ie(r,Pt);a&&o.push(a)}return o}function ti(n){return n.startsWith("~/")?Be(bt(),n.slice(2)):n==="~"?bt():n.startsWith("/")||/^[A-Za-z]:[\\/]/.test(n)?n:Be(process.cwd(),n)}import{readFileSync as oi,writeFileSync as ri,existsSync as si}from"fs";import{join as It}from"path";import Kt from"js-yaml";var Dt="skills.lock",ai=`# This file is generated by Kanonak CLI. Do not edit manually.
143
- `;function le(n){let e=It(n,Dt);if(!si(e))return{version:"1",lastUpdated:new Date().toISOString(),skills:{}};let t=oi(e,"utf-8"),o=Kt.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=It(n,Dt),r=Kt.dump(e,{lineWidth:-1,sortKeys:!1,quotingType:'"'});ri(o,ai+r,"utf-8")}var Tt="kanonak.org",Et="skill-to-skill-md",de=class{parser=new di;objectParser=new pi;runner=new ki;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 wi(r,this.objectParser);if(!s){console.error(`Cannot deploy: ${Tt}/${Et}@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}=bi(p);for(let m of i){let h=await ce(m.fileName,a,r),k=ue(pe(h,l));ii(h,{recursive:!0}),ui(pe(h,l),m.content,"utf-8"),u.skills[m.fileName]={publisher:d,package_:g,version:f,resolved:d?`kanonak://${d}/${g}@${f}`:"",integrity:mi(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)),ci(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=li(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 wi(n,e){let t=await n.getDocumentsByNamespaceAsync(Tt,Et);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:fi(i,s)});for(let r of o){let a=new hi(r,n),s=await e.parseKanonaks(a),i=gi(s,yi.InstanceTransformation);if(i[0])return i[0]}}function bi(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 Oi,rmSync as Ni,existsSync as Ye,readdirSync as Li,writeFileSync as Ui,statSync as Fi}from"fs";import{join as ge}from"path";import{KanonakObjectParser as Mi,KanonakParser as Vi,computeIntegrity as Hi}from"@kanonak-protocol/sdk";import{findSubjectsByType as zi}from"@kanonak-protocol/sdk/uri-helpers";import{SingleDocumentRepository as Bi}from"@kanonak-protocol/sdk/uri-helpers";import{TransformationRunnerV3 as qi}from"@kanonak-protocol/sdk/transformations";import{TX_V3 as Wi}from"@kanonak-protocol/sdk/transformations";import{join as jt}from"path";import{homedir as At}from"os";import{KanonakObjectParser as vi}from"@kanonak-protocol/sdk";import{SingleDocumentRepository as $i}from"@kanonak-protocol/sdk/uri-helpers";import{findSubjectsByType as Nt,getStringValue as Ge,getReferenceUri as Si}from"@kanonak-protocol/sdk/uri-helpers";var M="kanonak.org",V="agent-skills",Lt={publisher:M,package_:V,name:"Client"},Ut={publisher:M,package_:V,name:"clientId"},Pi={publisher:M,package_:V,name:"projectAgentDir"},Ci={publisher:M,package_:V,name:"userAgentDir"},Ri={publisher:M,package_:V,name:"agentFileFormat"},_i="agents";function xi(){if(process.env.CLAUDE_CODE||process.env.CLAUDE_PROJECT_DIR)return"claude-code"}async function me(n,e){let t=(n.client??xi()??_i).toLowerCase(),o=n.scope??"project",r=await Ii(t,e);if(!r){let u=await Ki(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"?Ci:Pi);if(!s)throw new Error(`Client "${t}" has no ${o==="user"?"userAgentDir":"projectAgentDir"} declared.`);let c=Si(r,Ri)?.name==="toml"?"toml":"markdown-frontmatter",l=c==="toml"?".toml":".md";return{agentsDir:Di(s),format:c,fileExtension:l}}var Ot=new WeakMap;async function Ft(n){let e=Ot.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 vi,s=new $i(r,n),i=await a.parseKanonaks(s);return Ot.set(n,i),i}async function Ii(n,e){let t=await Ft(e),o=Nt(t,Lt);for(let r of o)if(Ge(r,Ut)===n)return r}async function Ki(n){let e=await Ft(n),t=Nt(e,Lt),o=[];for(let r of t){let a=Ge(r,Ut);a&&o.push(a)}return o}function Di(n){return n.startsWith("~/")?jt(At(),n.slice(2)):n==="~"?At():n.startsWith("/")||/^[A-Za-z]:[\\/]/.test(n)?n:jt(process.cwd(),n)}import{readFileSync as Ti,writeFileSync as Ei,existsSync as ji}from"fs";import{join as Mt}from"path";import Vt from"js-yaml";var Ht="agents.lock",Ai=`# This file is generated by Kanonak CLI. Do not edit manually.
144
- `;function fe(n){let e=Mt(n,Ht);if(!ji(e))return{version:"1",lastUpdated:new Date().toISOString(),agents:{}};let t=Ti(e,"utf-8"),o=Vt.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=Mt(n,Ht),r=Vt.dump(e,{lineWidth:-1,sortKeys:!1,quotingType:'"'});Ei(o,Ai+r,"utf-8")}var zt="kanonak.org",Bt="agent-to-agent-file",he=class{parser=new Vi;objectParser=new Mi;runner=new qi;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 Gi(r,this.objectParser);if(!l){console.error(`Cannot deploy: ${zt}/${Bt}@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}Oi(s,{recursive:!0});let d=fe(s),g=t[0].namespace,{publisher:f,package_:m,version:h}=Yi(g);for(let k of p){let y=`${k.fileName}${c}`,w=ge(s,y),b=Ye(w);Ui(w,k.content,"utf-8"),d.agents[k.fileName]={publisher:f,package_:m,version:h,resolved:f?`kanonak://${f}/${m}@${h}`:"",integrity:Hi(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)&&Ni(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=Li(r,{withFileTypes:!0});for(let c of i){if(!c.isFile()||c.name==="agents.lock")continue;let l=ge(r,c.name),u=Ji(c.name);if(!a.agents[u]){try{if(!Fi(l).isFile())continue}catch{continue}s.push({name:u,publisher:"",package_:"",version:"",path:l})}}}catch{}return s}};async function Gi(n,e){let t=await n.getDocumentsByNamespaceAsync(zt,Bt);if(t.length===0)return;let o=new Bi(t[0],n),r=await e.parseKanonaks(o);return zi(r,Wi.InstanceTransformation)[0]}function Ji(n){let e=n.lastIndexOf(".");return e===-1?n:n.substring(0,e)}function Yi(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 ac=ec(Qi(import.meta.url)),ic=JSON.parse(Zi(nc(ac,"..","package.json"),"utf-8")),R=new Xi;R.name("kanonak").description("Kanonak Protocol CLI - Validate and resolve Kanonak ontology packages").version(ic.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.").action(async(n,e)=>{await pt(n,e)});R.addCommand(In());R.addCommand(On());R.addCommand(Vn());R.addCommand(Hn());R.addCommand(Bn());R.addCommand(Qn());R.addCommand(rt());R.addCommand(ut());R.addCommand(st());async function cc(){try{let n=new K,e=new tc,t=new rc,o=sc(t),r=new oc({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);mt(R,i,c)}catch{}}await cc();R.parse();
141
+ `);let s=new Ys,a=await s.getConfig(o),i=s.resolveIndexUrl(o,a),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 kt(y,this.repository),b=await this.objectParser.parseKanonaks(w),v=yt(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
+ `);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 a=(await this.requireHandler(e).list({repository:this.repository,options:o})).find(i=>i.name===t);a||(console.error(`"${t}" is not installed.`),process.exit(1)),console.log(`Name: ${a.name}`),console.log(`Type: ${e.managesTypeKey||"n/a"}`),console.log(`Publisher: ${a.publisher||"unmanaged"}`),console.log(`Package: ${a.package_||"n/a"}`),console.log(`Version: ${a.version||"n/a"}`),console.log(`Path: ${a.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 wt(n){if(!n)return;let e=n.split("/");if(e.length===3)return{publisher:e[0],package_:e[1],name:e[2]}}function Zs(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)),s=new Set(o.split("-").filter(Boolean)),a=0;for(let c of r)s.has(c)&&a++;if(a>0)return a*10;let i=Qs(t,o);return i===0?100:i<=2?Math.max(1,20-i*5):0}function Qs(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 s=0;s<e.length;s++){let a=n[r]===e[s]?0:1;o[s+1]=Math.min(o[s]+1,t[s+1]+1,t[s]+a)}for(let s=0;s<=e.length;s++)t[s]=o[s]}return t[e.length]}var se=class{handlers=new Map;register(e,t){this.handlers.set(e,t)}get(e){return this.handlers.get(e)??null}};import{mkdirSync as pi,rmSync as di,existsSync as ue,readdirSync as mi,writeFileSync as fi}from"fs";import{join as pe}from"path";import{KanonakObjectParser as gi,KanonakParser as hi,computeIntegrity as ki,compareVersions as yi}from"@kanonak-protocol/sdk";import{findSubjectsByType as wi}from"@kanonak-protocol/sdk/uri-helpers";import{SingleDocumentRepository as bi}from"@kanonak-protocol/sdk/uri-helpers";import{TransformationRunnerV3 as vi}from"@kanonak-protocol/sdk/transformations";import{TX_V3 as $i}from"@kanonak-protocol/sdk/transformations";import{join as Be}from"path";import{homedir as bt}from"os";import{KanonakObjectParser as ei}from"@kanonak-protocol/sdk";import{SingleDocumentRepository as ni}from"@kanonak-protocol/sdk/uri-helpers";import{findSubjectsByType as $t,getStringValue as ie}from"@kanonak-protocol/sdk/uri-helpers";var U="kanonak.org",F="agent-skills",St={publisher:U,package_:F,name:"Client"},Pt={publisher:U,package_:F,name:"clientId"},ti={publisher:U,package_:F,name:"projectSkillDir"},oi={publisher:U,package_:F,name:"userSkillDir"},ri={publisher:U,package_:F,name:"skillFileName"},Ct="agents";async function Q(n,e){let t=(n.client??Rt()??Ct).toLowerCase(),o=n.scope??"project",r=await xt(t,e);if(!r){let i=await ai(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 a=ie(r,o==="user"?oi:ti);if(!a)throw new Error(`Client "${t}" has no ${o==="user"?"userSkillDir":"projectSkillDir"} declared.`);return si(a)}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??Rt()??Ct).toLowerCase(),o=await xt(t,e);return o?ie(o,ri)??"SKILL.md":"SKILL.md"}function Rt(){if(process.env.CLAUDE_CODE||process.env.CLAUDE_PROJECT_DIR)return"claude-code"}var vt=new WeakMap;async function _t(n){let e=vt.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],s=new ei,a=new ni(r,n),i=await s.parseKanonaks(a);return vt.set(n,i),i}async function xt(n,e){let t=await _t(e),o=$t(t,St);for(let r of o)if(ie(r,Pt)===n)return r}async function ai(n){let e=await _t(n),t=$t(e,St),o=[];for(let r of t){let s=ie(r,Pt);s&&o.push(s)}return o}function si(n){return n.startsWith("~/")?Be(bt(),n.slice(2)):n==="~"?bt():n.startsWith("/")||/^[A-Za-z]:[\\/]/.test(n)?n:Be(process.cwd(),n)}import{readFileSync as ii,writeFileSync as ci,existsSync as li}from"fs";import{join as It}from"path";import Kt from"js-yaml";var Dt="skills.lock",ui=`# This file is generated by Kanonak CLI. Do not edit manually.
143
+ `;function le(n){let e=It(n,Dt);if(!li(e))return{version:"1",lastUpdated:new Date().toISOString(),skills:{}};let t=ii(e,"utf-8"),o=Kt.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 s of Object.keys(e.skills).sort())t[s]=e.skills[s];e.skills=t;let o=It(n,Dt),r=Kt.dump(e,{lineWidth:-1,sortKeys:!1,quotingType:'"'});ci(o,ui+r,"utf-8")}var Tt="kanonak.org",Et="skill-to-skill-md",de=class{parser=new hi;objectParser=new gi;runner=new vi;async deploy(e){let{instances:t,allKanonaks:o,repository:r,options:s}=e;if(t.length===0){console.error("No Skill instances to deploy.");return}let a=await Si(r,this.objectParser);if(!a){console.error(`Cannot deploy: ${Tt}/${Et}@3.0.0 is not installed in the workspace or cache.`);return}let i=await this.runner.run({transformation:a,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(s,r),l=await qe(s,r),u=le(c),p=t[0].namespace,{publisher:d,package_:g,version:f}=Pi(p);for(let m of i){let h=await ce(m.fileName,s,r),k=ue(pe(h,l));pi(h,{recursive:!0}),fi(pe(h,l),m.content,"utf-8"),u.skills[m.fileName]={publisher:d,package_:g,version:f,resolved:d?`kanonak://${d}/${g}@${f}`:"",integrity:ki(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,s=await ce(e,r,o);ue(s)||(console.error(`Skill "${e}" is not installed at ${s}`),process.exit(1)),di(s,{recursive:!0,force:!0});let a=await Q(r,o),i=le(a);delete i.skills[e],We(a,i),console.log(`Removed skill "${e}" from ${s}`)}async list(e){let{repository:t,options:o}=e,r=await Q(o,t),s=le(r),a=[];for(let[c,l]of Object.entries(s.skills))a.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=mi(r,{withFileTypes:!0});for(let l of c){if(!l.isDirectory()||s.skills[l.name])continue;let u=pe(r,l.name,i);ue(u)&&a.push({name:l.name,publisher:"",package_:"",version:"",path:pe(r,l.name)})}}catch{}return a}};async function Si(n,e){let t=await n.getDocumentsByNamespaceAsync(Tt,Et);if(t.length===0)return;let o=[...t].sort((r,s)=>{let a=r.metadata.namespace_?.version,i=s.metadata.namespace_?.version;return!a||!i?0:yi(i,a)});for(let r of o){let s=new bi(r,n),a=await e.parseKanonaks(s),i=wi(a,$i.InstanceTransformation);if(i[0])return i[0]}}function Pi(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 Fi,rmSync as Mi,existsSync as Ye,readdirSync as Vi,writeFileSync as Hi,statSync as zi}from"fs";import{join as ge}from"path";import{KanonakObjectParser as Bi,KanonakParser as qi,computeIntegrity as Wi}from"@kanonak-protocol/sdk";import{findSubjectsByType as Gi}from"@kanonak-protocol/sdk/uri-helpers";import{SingleDocumentRepository as Ji}from"@kanonak-protocol/sdk/uri-helpers";import{TransformationRunnerV3 as Yi}from"@kanonak-protocol/sdk/transformations";import{TX_V3 as Xi}from"@kanonak-protocol/sdk/transformations";import{join as jt}from"path";import{homedir as At}from"os";import{KanonakObjectParser as Ci}from"@kanonak-protocol/sdk";import{SingleDocumentRepository as Ri}from"@kanonak-protocol/sdk/uri-helpers";import{findSubjectsByType as Nt,getStringValue as Ge,getReferenceUri as _i}from"@kanonak-protocol/sdk/uri-helpers";var M="kanonak.org",V="agent-skills",Lt={publisher:M,package_:V,name:"Client"},Ut={publisher:M,package_:V,name:"clientId"},xi={publisher:M,package_:V,name:"projectAgentDir"},Ii={publisher:M,package_:V,name:"userAgentDir"},Ki={publisher:M,package_:V,name:"agentFileFormat"},Di="agents";function Ti(){if(process.env.CLAUDE_CODE||process.env.CLAUDE_PROJECT_DIR)return"claude-code"}async function me(n,e){let t=(n.client??Ti()??Di).toLowerCase(),o=n.scope??"project",r=await Ei(t,e);if(!r){let u=await ji(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 a=Ge(r,o==="user"?Ii:xi);if(!a)throw new Error(`Client "${t}" has no ${o==="user"?"userAgentDir":"projectAgentDir"} declared.`);let c=_i(r,Ki)?.name==="toml"?"toml":"markdown-frontmatter",l=c==="toml"?".toml":".md";return{agentsDir:Ai(a),format:c,fileExtension:l}}var Ot=new WeakMap;async function Ft(n){let e=Ot.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],s=new Ci,a=new Ri(r,n),i=await s.parseKanonaks(a);return Ot.set(n,i),i}async function Ei(n,e){let t=await Ft(e),o=Nt(t,Lt);for(let r of o)if(Ge(r,Ut)===n)return r}async function ji(n){let e=await Ft(n),t=Nt(e,Lt),o=[];for(let r of t){let s=Ge(r,Ut);s&&o.push(s)}return o}function Ai(n){return n.startsWith("~/")?jt(At(),n.slice(2)):n==="~"?At():n.startsWith("/")||/^[A-Za-z]:[\\/]/.test(n)?n:jt(process.cwd(),n)}import{readFileSync as Oi,writeFileSync as Ni,existsSync as Li}from"fs";import{join as Mt}from"path";import Vt from"js-yaml";var Ht="agents.lock",Ui=`# This file is generated by Kanonak CLI. Do not edit manually.
144
+ `;function fe(n){let e=Mt(n,Ht);if(!Li(e))return{version:"1",lastUpdated:new Date().toISOString(),agents:{}};let t=Oi(e,"utf-8"),o=Vt.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 s of Object.keys(e.agents).sort())t[s]=e.agents[s];e.agents=t;let o=Mt(n,Ht),r=Vt.dump(e,{lineWidth:-1,sortKeys:!1,quotingType:'"'});Ni(o,Ui+r,"utf-8")}var zt="kanonak.org",Bt="agent-to-agent-file",he=class{parser=new qi;objectParser=new Bi;runner=new Yi;async deploy(e){let{instances:t,allKanonaks:o,repository:r,options:s}=e;if(t.length===0){console.error("No Agent instances to deploy.");return}let{agentsDir:a,format:i,fileExtension:c}=await me(s,r),l=await Zi(r,this.objectParser);if(!l){console.error(`Cannot deploy: ${zt}/${Bt}@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}Fi(a,{recursive:!0});let d=fe(a),g=t[0].namespace,{publisher:f,package_:m,version:h}=ec(g);for(let k of p){let y=`${k.fileName}${c}`,w=ge(a,y),b=Ye(w);Hi(w,k.content,"utf-8"),d.agents[k.fileName]={publisher:f,package_:m,version:h,resolved:f?`kanonak://${f}/${m}@${h}`:"",integrity:Wi(k.content),fileName:y},console.log(` ${b?"Updated":"Installed"} agent "${k.fileName}" \u2192 ${w}`)}Je(a,d)}async undeploy(e,t){let{repository:o,options:r}=t,{agentsDir:s}=await me(r,o),a=fe(s),i=a.agents[e];i||(console.error(`Agent "${e}" is not installed at ${s}`),process.exit(1));let c=ge(s,i.fileName);Ye(c)&&Mi(c,{force:!0}),delete a.agents[e],Je(s,a),console.log(`Removed agent "${e}" from ${c}`)}async list(e){let{repository:t,options:o}=e,{agentsDir:r}=await me(o,t),s=fe(r),a=[];for(let[i,c]of Object.entries(s.agents))a.push({name:i,publisher:c.publisher,package_:c.package_,version:c.version,path:ge(r,c.fileName)});if(Ye(r))try{let i=Vi(r,{withFileTypes:!0});for(let c of i){if(!c.isFile()||c.name==="agents.lock")continue;let l=ge(r,c.name),u=Qi(c.name);if(!s.agents[u]){try{if(!zi(l).isFile())continue}catch{continue}a.push({name:u,publisher:"",package_:"",version:"",path:l})}}}catch{}return a}};async function Zi(n,e){let t=await n.getDocumentsByNamespaceAsync(zt,Bt);if(t.length===0)return;let o=new Ji(t[0],n),r=await e.parseKanonaks(o);return Gi(r,Xi.InstanceTransformation)[0]}function Qi(n){let e=n.lastIndexOf(".");return e===-1?n:n.substring(0,e)}function ec(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 uc=rc(oc(import.meta.url)),pc=JSON.parse(tc(ac(uc,"..","package.json"),"utf-8")),R=new nc;R.name("kanonak").description("Kanonak Protocol CLI - Validate and resolve Kanonak ontology packages").version(pc.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 an(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 pt(n,e)});R.addCommand(In());R.addCommand(On());R.addCommand(Vn());R.addCommand(Hn());R.addCommand(Bn());R.addCommand(Qn());R.addCommand(rt());R.addCommand(ut());R.addCommand(at());async function dc(){try{let n=new K,e=new sc,t=new cc,o=lc(t),r=new ic({fetchFn:o}),s=await $(process.cwd(),e),a=new se;a.register("kanonak.org/capabilities/agent-skill-deployment",new de),a.register("kanonak.org/agent-capabilities/agent-instance-deployment",new he);let i=await Rn(n,e,s),c=new ae(n,e,r,o,a,s);mt(R,i,c)}catch{}}await dc();R.parse();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kanonak-protocol/cli",
3
- "version": "4.4.0",
3
+ "version": "4.6.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.4.0",
39
- "@kanonak-protocol/types": "^4.4.0",
38
+ "@kanonak-protocol/sdk": "^4.6.0",
39
+ "@kanonak-protocol/types": "^4.6.0",
40
40
  "commander": "^13.0.0",
41
41
  "js-yaml": "^4.1.1"
42
42
  },