@kanonak-protocol/cli 3.18.0 → 3.20.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.
@@ -0,0 +1,27 @@
1
+ /**
2
+ * Print the canonical structural hash of a Kanonak package.
3
+ *
4
+ * The hash is a function of the package's semantic content
5
+ * — `sha256:<hex>` over the canonical JSON form defined by
6
+ * `@kanonak-protocol/sdk`'s `canonicalForm`. Invariant under
7
+ * resource ordering, statement ordering within a resource, YAML
8
+ * styling, and `#` comments. Lists keep source order.
9
+ *
10
+ * Usage:
11
+ *
12
+ * kanonak hash <path> (e.g. contacts.kan.yml)
13
+ * kanonak hash <publisher/package[@version]> (e.g. kanonak.org/core-rdf@1.0.0)
14
+ *
15
+ * The second form resolves the package through the standard
16
+ * three-tier repository (local workspace + global cache + HTTP);
17
+ * the first form reads the file directly. Heuristic: any argument
18
+ * ending in `.kan.yml` is treated as a path, anything else as a
19
+ * Kanonak package address.
20
+ *
21
+ * Prints the hash on stdout and `--verbose` also prints the
22
+ * canonical form (the JSON that was hashed) on stderr so a user
23
+ * debugging a hash divergence can compare forms.
24
+ */
25
+ export declare function hashCommand(target: string, options?: {
26
+ verbose?: boolean;
27
+ }): Promise<void>;
package/dist/index.js CHANGED
@@ -1,25 +1,25 @@
1
1
  #!/usr/bin/env node
2
- import{Command as Fa}from"commander";import{readFileSync as Ha}from"fs";import{fileURLToPath as Ma}from"url";import{dirname as Va,join as Ba}from"path";import{KanonakParser as za,PublisherIndex as Ga,CredentialStore as qa,createAuthenticatedFetch as Wa}from"@kanonak-protocol/sdk";import{readFileSync as qt,statSync as Wt}from"fs";import{resolve as Jt,dirname as Yt}from"path";import{KanonakParser as Xt,KanonakObjectValidator as Zt,ValidationSeverity as Ze}from"@kanonak-protocol/sdk";import{readFileSync as Ut,readdirSync as Ft}from"fs";import{join as Ht,dirname as Mt,basename as Xe}from"path";import{InMemoryKanonakDocumentRepository as Vt,FileSystemKanonakDocumentRepository as Bt,HttpKanonakDocumentRepository as zt,getGlobalCachePath as Gt}from"@kanonak-protocol/sdk";import{mkdirSync as At,readFileSync as Je,writeFileSync as Ye,existsSync as ke,appendFileSync as Et}from"fs";import{join as jt,dirname as Ot,isAbsolute as Nt}from"path";import{getGlobalCachePath as Lt}from"@kanonak-protocol/sdk";var D=class{constructor(e=Lt()){this.cacheDir=e;this.isProjectLocal=!Nt(e)}cacheDir;gitignoreChecked=!1;isProjectLocal;get(e,t,o){let r=this.getPath(e,t,o);return ke(r)?Je(r,"utf-8"):null}put(e,t,o,r){let a=this.getPath(e,t,o);At(Ot(a),{recursive:!0}),Ye(a,r,"utf-8"),this.isProjectLocal&&this.ensureGitignore()}has(e,t,o){return ke(this.getPath(e,t,o))}ensureGitignore(){if(this.gitignoreChecked)return;this.gitignoreChecked=!0;let e=".gitignore",t=this.cacheDir;if(ke(e)){if(Je(e,"utf-8").split(`
3
- `).some(r=>r.trim()===t||r.trim()===t+"/"))return;Et(e,`
2
+ import{Command as ei}from"commander";import{readFileSync as ni}from"fs";import{fileURLToPath as ti}from"url";import{dirname as oi,join as ri}from"path";import{KanonakParser as si,PublisherIndex as ai,CredentialStore as ii,createAuthenticatedFetch as ci}from"@kanonak-protocol/sdk";import{readFileSync as Wt,statSync as Jt}from"fs";import{resolve as Yt,dirname as Xt}from"path";import{KanonakParser as Zt,KanonakObjectValidator as Qt,ValidationSeverity as Ze}from"@kanonak-protocol/sdk";import{readFileSync as Ft,readdirSync as Ht}from"fs";import{join as Mt,dirname as Vt,basename as Xe}from"path";import{InMemoryKanonakDocumentRepository as Bt,FileSystemKanonakDocumentRepository as zt,HttpKanonakDocumentRepository as qt,getGlobalCachePath as Gt}from"@kanonak-protocol/sdk";import{mkdirSync as Et,readFileSync as Je,writeFileSync as Ye,existsSync as ke,appendFileSync as jt}from"fs";import{join as Ot,dirname as Nt,isAbsolute as Lt}from"path";import{getGlobalCachePath as Ut}from"@kanonak-protocol/sdk";var D=class{constructor(e=Ut()){this.cacheDir=e;this.isProjectLocal=!Lt(e)}cacheDir;gitignoreChecked=!1;isProjectLocal;get(e,t,o){let r=this.getPath(e,t,o);return ke(r)?Je(r,"utf-8"):null}put(e,t,o,r){let a=this.getPath(e,t,o);Et(Nt(a),{recursive:!0}),Ye(a,r,"utf-8"),this.isProjectLocal&&this.ensureGitignore()}has(e,t,o){return ke(this.getPath(e,t,o))}ensureGitignore(){if(this.gitignoreChecked)return;this.gitignoreChecked=!0;let e=".gitignore",t=this.cacheDir;if(ke(e)){if(Je(e,"utf-8").split(`
3
+ `).some(r=>r.trim()===t||r.trim()===t+"/"))return;jt(e,`
4
4
  ${t}/
5
5
  `)}else Ye(e,`${t}/
6
- `)}getPath(e,t,o){return jt(this.cacheDir,e,`${t}@${o}.kan.yml`)}};function z(n){let e=n;for(;;){let t=Mt(e);if(t===e)break;if(Xe(e).includes(".")||Xe(t).includes(".")){e=t;continue}break}return e}function X(n,e){for(let t of Ft(n,{withFileTypes:!0})){let o=Ht(n,t.name);t.isDirectory()&&t.name!=="node_modules"&&t.name!==".kanonak"?X(o,e):t.name.endsWith(".kan.yml")&&e.push(o)}}var ye=class{repos;constructor(...e){this.repos=e}async getHighestCompatibleVersionAsync(e,t){for(let o of this.repos)try{let r=await o.getHighestCompatibleVersionAsync(e,t);if(r)return r}catch{}return null}async getAllDocumentsAsync(){let e=[];for(let t of this.repos)try{e.push(...await t.getAllDocumentsAsync())}catch{}return e}async getDocumentAsync(e){for(let t of this.repos)try{let o=await t.getDocumentAsync(e);if(o)return o}catch{}return null}async getDocumentsByNamespaceAsync(e,t){for(let o of this.repos)try{let r=await o.getDocumentsByNamespaceAsync(e,t);if(r.length>0)return r}catch{}return[]}async saveDocumentAsync(e,t){await this.repos[0].saveDocumentAsync(e,t)}async deleteDocumentAsync(e){await this.repos[0].deleteDocumentAsync(e)}async clearNamespaceAsync(e,t){await this.repos[0].clearNamespaceAsync(e,t)}async getAllDocumentReferencesAsync(){return this.repos[0].getAllDocumentReferencesAsync()}async getDocumentContentAsync(e){for(let t of this.repos)try{let o=await t.getDocumentContentAsync(e);if(o)return o}catch{}return null}async getDocumentUriAsync(e){for(let t of this.repos)try{let o=await t.getDocumentUriAsync(e);if(o)return o}catch{}return null}};async function R(n,e){let t=[];X(n,t);let o=new Vt(e);for(let i of t)try{let c=Ut(i,"utf-8"),l=e.parse(c),p=l.metadata.namespace_;if(p){let u=`${p.publisher}/${p.package_}@${p.version}`;await o.saveDocumentAsync(l,u)}}catch{}let r=new Bt(Gt(),!0,e),a=new D,s=new zt({getFromCache:(i,c,l)=>a.get(i,c,l),onFetch:(i,c,l,p)=>a.put(i,c,l,p)});return new ye(o,r,s)}async function Qe(n){let e=Jt(n),t=Wt(e),o=t.isDirectory()?z(e):z(Yt(e)),r=new Xt,a=new Zt(r),s=await R(o,r),i=[];if(t.isDirectory()?X(e,i):i.push(e),i.length===0){console.log("No .kan.yml files found.");return}let c=0,l=0;for(let p of i){let u=qt(p,"utf-8"),m=r.parseWithErrors(u);if(m.errors&&m.errors.length>0){console.log(`
7
- ${p}:`);for(let f of m.errors)console.log(` ERROR (parse): ${f.message} [line ${f.line}:${f.column}]`),c++;continue}let h=m.document;if(!h){console.log(`
8
- ${p}:`),console.log(" ERROR: Failed to parse document"),c++;continue}let k=await a.validateAsync(h,s),d=k.errors.filter(f=>f.severity===Ze.Error),g=k.errors.filter(f=>f.severity===Ze.Warning);if(d.length>0||g.length>0){let f=h.metadata.namespace_,y=f?`${f.publisher}/${f.package_}@${f.version}`:p;console.log(`
6
+ `)}getPath(e,t,o){return Ot(this.cacheDir,e,`${t}@${o}.kan.yml`)}};function j(n){let e=n;for(;;){let t=Vt(e);if(t===e)break;if(Xe(e).includes(".")||Xe(t).includes(".")){e=t;continue}break}return e}function X(n,e){for(let t of Ht(n,{withFileTypes:!0})){let o=Mt(n,t.name);t.isDirectory()&&t.name!=="node_modules"&&t.name!==".kanonak"?X(o,e):t.name.endsWith(".kan.yml")&&e.push(o)}}var ye=class{repos;constructor(...e){this.repos=e}async getHighestCompatibleVersionAsync(e,t){for(let o of this.repos)try{let r=await o.getHighestCompatibleVersionAsync(e,t);if(r)return r}catch{}return null}async getAllDocumentsAsync(){let e=[];for(let t of this.repos)try{e.push(...await t.getAllDocumentsAsync())}catch{}return e}async getDocumentAsync(e){for(let t of this.repos)try{let o=await t.getDocumentAsync(e);if(o)return o}catch{}return null}async getDocumentsByNamespaceAsync(e,t){for(let o of this.repos)try{let r=await o.getDocumentsByNamespaceAsync(e,t);if(r.length>0)return r}catch{}return[]}async saveDocumentAsync(e,t){await this.repos[0].saveDocumentAsync(e,t)}async deleteDocumentAsync(e){await this.repos[0].deleteDocumentAsync(e)}async clearNamespaceAsync(e,t){await this.repos[0].clearNamespaceAsync(e,t)}async getAllDocumentReferencesAsync(){return this.repos[0].getAllDocumentReferencesAsync()}async getDocumentContentAsync(e){for(let t of this.repos)try{let o=await t.getDocumentContentAsync(e);if(o)return o}catch{}return null}async getDocumentUriAsync(e){for(let t of this.repos)try{let o=await t.getDocumentUriAsync(e);if(o)return o}catch{}return null}};async function v(n,e){let t=[];X(n,t);let o=new Bt(e);for(let i of t)try{let c=Ft(i,"utf-8"),l=e.parse(c),u=l.metadata.namespace_;if(u){let p=`${u.publisher}/${u.package_}@${u.version}`;await o.saveDocumentAsync(l,p)}}catch{}let r=new zt(Gt(),!0,e),a=new D,s=new qt({getFromCache:(i,c,l)=>a.get(i,c,l),onFetch:(i,c,l,u)=>a.put(i,c,l,u)});return new ye(o,r,s)}async function Qe(n){let e=Yt(n),t=Jt(e),o=t.isDirectory()?j(e):j(Xt(e)),r=new Zt,a=new Qt(r),s=await v(o,r),i=[];if(t.isDirectory()?X(e,i):i.push(e),i.length===0){console.log("No .kan.yml files found.");return}let c=0,l=0;for(let u of i){let p=Wt(u,"utf-8"),m=r.parseWithErrors(p);if(m.errors&&m.errors.length>0){console.log(`
7
+ ${u}:`);for(let f of m.errors)console.log(` ERROR (parse): ${f.message} [line ${f.line}:${f.column}]`),c++;continue}let h=m.document;if(!h){console.log(`
8
+ ${u}:`),console.log(" ERROR: Failed to parse document"),c++;continue}let k=await a.validateAsync(h,s),d=k.errors.filter(f=>f.severity===Ze.Error),g=k.errors.filter(f=>f.severity===Ze.Warning);if(d.length>0||g.length>0){let f=h.metadata.namespace_,y=f?`${f.publisher}/${f.package_}@${f.version}`:u;console.log(`
9
9
  ${y}:`);for(let b of d)console.log(` ERROR: ${b.message}`),b.suggestion&&console.log(` -> ${b.suggestion}`);for(let b of g)console.log(` WARN: ${b.message}`)}c+=d.length,l+=g.length}console.log(`
10
- ${i.length} file(s) validated. ${c} error(s), ${l} warning(s).`),c>0&&process.exit(1)}import{KanonakParser as Qt,PublisherIndex as eo,CredentialStore as no,createAuthenticatedFetch as to}from"@kanonak-protocol/sdk";import{loadLockFile as oo,saveLockFile as ro,computeIntegrity as so}from"@kanonak-protocol/sdk";function K(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 en(n){let e=new D,t=new Qt,o=new no,r=to(o),a=new eo({fetchFn:r}),s=oo()??{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[k,d]of Object.entries(s.packages)){let g=k.indexOf("/"),f=k.substring(0,g),y=k.substring(g+1),b=e.get(f,y,d.version);if(b)console.log(` ${k}@${d.version} (cached)`);else{let w=d.resolved,$=await r(w,f);if(!$.ok)throw new Error(`Failed to fetch ${w} (${$.status} ${$.statusText})`);b=await $.text(),e.put(f,y,d.version,b),console.log(` ${k}@${d.version}`)}}console.log(`
11
- Installed ${Object.keys(s.packages).length} package(s) from lock file.`);return}let i=K(n);i||(console.error(`Invalid package reference: "${n}"`),console.error("Expected format: {publisher}/{package}[@{version}]"),process.exit(1));let{publisher:c,packageName:l,version:p,instanceName:u}=i;u&&(console.error(`\`kanonak install\` works on whole packages \u2014 got an instance suffix "/${u}".`),console.error(`Try: kanonak install ${c}/${l}${p?"@"+p:""}`),console.error("(Use `kanonak <capability> add` if you want to install one named instance.)"),process.exit(1));let m=p??await a.getHighestVersion(c,l);m||(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}@${m}...`);let h=new Set;await nn(c,l,m,e,t,a,r,h,s),ro(s),console.log(`
12
- Installed ${h.size} package(s).`)}async function nn(n,e,t,o,r,a,s,i,c){let l=`${n}/${e}@${t}`;if(i.has(l))return;i.add(l);let p=`${n}/${e}`,u=o.get(n,e,t),m;if(u)console.log(` ${l} (cached)`),m=await a.getPackageUrl(n,e,t);else{m=await a.getPackageUrl(n,e,t);let d=await s(m,n);if(!d.ok)throw new Error(`Failed to fetch ${m} (${d.status} ${d.statusText})`);u=await d.text(),o.put(n,e,t,u),console.log(` ${l}`)}let h={},k=r.parse(u);if(k.metadata.imports)for(let[d,g]of Object.entries(k.metadata.imports))for(let f of g){let y=await a.resolveVersion(d,f);y?(h[`${d}/${f.packageName}`]=y,await nn(d,f.packageName,y,o,r,a,s,i,c)):console.error(` WARNING: Could not resolve ${d}/${f.packageName} ${f.package_}`)}c.packages[p]={version:t,resolved:m,integrity:so(u),dependencies:h}}import{readFileSync as ao}from"fs";import{resolve as io,dirname as co}from"path";import{KanonakParser as lo}from"@kanonak-protocol/sdk";async function tn(n){let e=io(n),t=ao(e,"utf-8"),o=new lo,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=z(co(e)),c=await R(i,o),l=new Set;for(let[p,u]of Object.entries(r.metadata.imports))for(let m of u)await on(p,m,c,l," ")}async function on(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 p of l)await on(c,p,t,o,r+" ")}import{createHash as po,randomBytes as an}from"crypto";import{createServer as mo}from"http";import{execFile as be}from"child_process";import{CredentialStore as fo,generateDPoPKeyPair as go,createDPoPProof as rn,serverSupportsDPoP as ho}from"@kanonak-protocol/sdk";import{normalizeHost as uo}from"@kanonak-protocol/sdk";var A=class{cache=new Map;async discover(e){let t=uo(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:G(o.issuer),authorizationEndpoint:G(o.authorization_endpoint),tokenEndpoint:G(o.token_endpoint),registrationEndpoint:G(o.registration_endpoint),revocationEndpoint:G(o.revocation_endpoint),scopesSupported:U(o.scopes_supported),responseTypesSupported:U(o.response_types_supported),grantTypesSupported:U(o.grant_types_supported),codeChallengeMethodsSupported:U(o.code_challenge_methods_supported),tokenEndpointAuthMethodsSupported:U(o.token_endpoint_auth_methods_supported),dpopSigningAlgValuesSupported:U(o.dpop_signing_alg_values_supported)}}};function G(n){return typeof n=="string"?n:null}function U(n){return Array.isArray(n)?n.filter(e=>typeof e=="string"):null}var H=class{discovery;credentialStore;constructor(e,t){this.discovery=e??new A,this.credentialStore=t??new fo}async authorize(e,t=[]){console.log(`Starting OAuth flow for ${e}...`);let o=await this.discovery.discover(e);if(!o)return _(`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 eo,PublisherIndex as no,CredentialStore as to,createAuthenticatedFetch as oo}from"@kanonak-protocol/sdk";import{loadLockFile as ro,saveLockFile as so,computeIntegrity as ao}from"@kanonak-protocol/sdk";function K(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 en(n){let e=new D,t=new eo,o=new to,r=oo(o),a=new no({fetchFn:r}),s=ro()??{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[k,d]of Object.entries(s.packages)){let g=k.indexOf("/"),f=k.substring(0,g),y=k.substring(g+1),b=e.get(f,y,d.version);if(b)console.log(` ${k}@${d.version} (cached)`);else{let w=d.resolved,$=await r(w,f);if(!$.ok)throw new Error(`Failed to fetch ${w} (${$.status} ${$.statusText})`);b=await $.text(),e.put(f,y,d.version,b),console.log(` ${k}@${d.version}`)}}console.log(`
11
+ Installed ${Object.keys(s.packages).length} package(s) from lock file.`);return}let i=K(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 m=u??await a.getHighestVersion(c,l);m||(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}@${m}...`);let h=new Set;await nn(c,l,m,e,t,a,r,h,s),so(s),console.log(`
12
+ Installed ${h.size} package(s).`)}async function nn(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),m;if(p)console.log(` ${l} (cached)`),m=await a.getPackageUrl(n,e,t);else{m=await a.getPackageUrl(n,e,t);let d=await s(m,n);if(!d.ok)throw new Error(`Failed to fetch ${m} (${d.status} ${d.statusText})`);p=await d.text(),o.put(n,e,t,p),console.log(` ${l}`)}let h={},k=r.parse(p);if(k.metadata.imports)for(let[d,g]of Object.entries(k.metadata.imports))for(let f of g){let y=await a.resolveVersion(d,f);y?(h[`${d}/${f.packageName}`]=y,await nn(d,f.packageName,y,o,r,a,s,i,c)):console.error(` WARNING: Could not resolve ${d}/${f.packageName} ${f.package_}`)}c.packages[u]={version:t,resolved:m,integrity:ao(p),dependencies:h}}import{readFileSync as io}from"fs";import{resolve as co,dirname as lo}from"path";import{KanonakParser as uo}from"@kanonak-protocol/sdk";async function tn(n){let e=co(n),t=io(e,"utf-8"),o=new uo,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=j(lo(e)),c=await v(i,o),l=new Set;for(let[u,p]of Object.entries(r.metadata.imports))for(let m of p)await on(u,m,c,l," ")}async function on(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 on(c,u,t,o,r+" ")}import{createHash as mo,randomBytes as an}from"crypto";import{createServer as fo}from"http";import{execFile as be}from"child_process";import{CredentialStore as go,generateDPoPKeyPair as ho,createDPoPProof as rn,serverSupportsDPoP as ko}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:q(o.issuer),authorizationEndpoint:q(o.authorization_endpoint),tokenEndpoint:q(o.token_endpoint),registrationEndpoint:q(o.registration_endpoint),revocationEndpoint:q(o.revocation_endpoint),scopesSupported:F(o.scopes_supported),responseTypesSupported:F(o.response_types_supported),grantTypesSupported:F(o.grant_types_supported),codeChallengeMethodsSupported:F(o.code_challenge_methods_supported),tokenEndpointAuthMethodsSupported:F(o.token_endpoint_auth_methods_supported),dpopSigningAlgValuesSupported:F(o.dpop_signing_alg_values_supported)}}};function q(n){return typeof n=="string"?n:null}function F(n){return Array.isArray(n)?n.filter(e=>typeof e=="string"):null}var M=class{discovery;credentialStore;constructor(e,t){this.discovery=e??new A,this.credentialStore=t??new go}async authorize(e,t=[]){console.log(`Starting OAuth flow for ${e}...`);let o=await this.discovery.discover(e);if(!o)return _(`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 _(`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=ho(o.dpopSigningAlgValuesSupported),s=null;if(a){console.log(" Server supports DPoP (RFC 9449) \u2014 generating key pair...");try{s=go()}catch($){return _(`Failed to generate DPoP key pair: ${F($)}
19
- Ensure your Node.js installation supports EC P-256 curves.`)}}let{redirectUri:i,port:c,waitForCallback:l,close:p}=await Po(),u=await this.credentialStore.getCredential(e),m=u?.clientId??null,h=u?.clientSecret??null;if(!m&&o.registrationEndpoint){console.log(" Registering dynamic OAuth client (RFC 7591)...");let $=await this.registerClient(o.registrationEndpoint,i);if(!$.success)return p(),_($.error);m=$.clientId,h=$.clientSecret??null}if(!m)return p(),_(`No OAuth client credentials for '${e}' and the server does not support dynamic client registration (no registration_endpoint in metadata).
18
+ Contact the IDP administrator to ensure these are included in the discovery document.`);let a=ko(o.dpopSigningAlgValuesSupported),s=null;if(a){console.log(" Server supports DPoP (RFC 9449) \u2014 generating key pair...");try{s=ho()}catch($){return _(`Failed to generate DPoP key pair: ${H($)}
19
+ Ensure your Node.js installation supports EC P-256 curves.`)}}let{redirectUri:i,port:c,waitForCallback:l,close:u}=await So(),p=await this.credentialStore.getCredential(e),m=p?.clientId??null,h=p?.clientSecret??null;if(!m&&o.registrationEndpoint){console.log(" Registering dynamic OAuth client (RFC 7591)...");let $=await this.registerClient(o.registrationEndpoint,i);if(!$.success)return u(),_($.error);m=$.clientId,h=$.clientSecret??null}if(!m)return u(),_(`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),
22
- or add a registration_endpoint to the OAuth metadata.`);let k=yo(),d=bo(k),g=wo(),f=$o(o.authorizationEndpoint,m,i,t,g,d);console.log(` Opening browser for authorization on port ${c}...`),console.log(" If the browser doesn't open, navigate to:"),console.log(` ${f}`),Ro(f);let y=await l();if(p(),!y)return _(`Authorization timed out after 5 minutes.
22
+ or add a registration_endpoint to the OAuth metadata.`);let k=bo(),d=wo(k),g=$o(),f=vo(o.authorizationEndpoint,m,i,t,g,d);console.log(` Opening browser for authorization on port ${c}...`),console.log(" If the browser doesn't open, navigate to:"),console.log(` ${f}`),_o(f);let y=await l();if(u(),!y)return _(`Authorization timed out after 5 minutes.
23
23
  The browser authorization was not completed in time.
24
24
  Re-run 'kanonak login ${e}' and complete the browser authorization promptly.`);if(!y.code){let $=y.error?`: ${y.error}`:"";return _(`No authorization code received${$}.
25
25
  The IDP may have rejected the authorization request.
@@ -32,32 +32,32 @@ Installed ${h.size} package(s).`)}async function nn(n,e,t,o,r,a,s,i,c){let l=`${
32
32
  The OAuth discovery endpoint may be unreachable.
33
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}):_(`${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 _(`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: ${F(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(s){return{success:!1,error:`Dynamic client registration request to ${e} failed: ${H(s)}
36
36
  Ensure the IDP is reachable and HTTPS is properly configured.
37
37
  If using a corporate proxy or custom CA, set NODE_EXTRA_CA_CERTS.`}}if(!o.ok){let s=await we(o);return{success:!1,error:`Dynamic client registration (RFC 7591) failed.
38
38
  Endpoint: ${e}
39
39
  HTTP ${o.status}: ${s}
40
40
  The IDP may not support dynamic registration for public clients.
41
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=rn(i.privateKey,i.publicKey,"POST",e)}catch(u){return{success:!1,error:`Failed to create DPoP proof for token exchange: ${F(u)}
43
- The stored key pair may be corrupted. Run 'kanonak login' to re-authenticate.`}}let p;try{p=await fetch(e,{method:"POST",headers:l,body:c.toString()})}catch(u){return{success:!1,error:`Token exchange request to ${e} failed: ${F(u)}
44
- Ensure the token endpoint is reachable.`}}if(!p.ok){let u=await we(p),m=ko(u);return{success:!1,error:`Token exchange failed.
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=rn(i.privateKey,i.publicKey,"POST",e)}catch(p){return{success:!1,error:`Failed to create DPoP proof for token exchange: ${H(p)}
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: ${H(p)}
44
+ Ensure the token endpoint is reachable.`}}if(!u.ok){let p=await we(u),m=yo(p);return{success:!1,error:`Token exchange failed.
45
45
  Endpoint: ${e}
46
- HTTP ${p.status}: ${u}`+(m?`
47
- ${m}`:"")}}return{success:!0,tokens:sn(await p.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=rn(a.privateKey,a.publicKey,"POST",e)}catch(l){return{success:!1,error:`Failed to create DPoP proof for token refresh: ${F(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: ${F(l)}`}}if(!c.ok){let l=await we(c);return{success:!1,error:`Token refresh failed \u2014 HTTP ${c.status}: ${l}`}}return{success:!0,tokens:sn(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 _(n){return{success:!1,error:n}}function sn(n){return{accessToken:n.access_token,refreshToken:n.refresh_token,expiresIn:typeof n.expires_in=="number"?n.expires_in:void 0}}function F(n){return n instanceof Error?n.message:String(n)}async function we(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 yo(){return an(32).toString("base64url")}function bo(n){return po("sha256").update(n).digest("base64url")}function wo(){return an(16).toString("base64url")}function $o(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 vo=300*1e3;async function Po(){return new Promise(n=>{let e=mo((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,p=l?So(l):null,u=p?`<html><body><h1>Authorization failed</h1><p>${p}</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(u),t({code:i,state:c,error:l})}),t,o=new Promise(r=>{t=r,setTimeout(()=>{r(null),e.close()},vo)});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 So(n){return n.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;")}function Ro(n){try{process.platform==="win32"?be("cmd",["/c","start","",n]):process.platform==="darwin"?be("open",[n]):be("xdg-open",[n])}catch{console.log(" Could not open browser automatically. Please navigate to the URL above manually.")}}import{CredentialStore as _o}from"@kanonak-protocol/sdk";async function cn(n){try{let e=new A,t=new _o,r=await new H(e,t).authorize(n);r.success?console.log(`
46
+ HTTP ${u.status}: ${p}`+(m?`
47
+ ${m}`:"")}}return{success:!0,tokens:sn(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=rn(a.privateKey,a.publicKey,"POST",e)}catch(l){return{success:!1,error:`Failed to create DPoP proof for token refresh: ${H(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: ${H(l)}`}}if(!c.ok){let l=await we(c);return{success:!1,error:`Token refresh failed \u2014 HTTP ${c.status}: ${l}`}}return{success:!0,tokens:sn(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 _(n){return{success:!1,error:n}}function sn(n){return{accessToken:n.access_token,refreshToken:n.refresh_token,expiresIn:typeof n.expires_in=="number"?n.expires_in:void 0}}function H(n){return n instanceof Error?n.message:String(n)}async function we(n){try{return await n.text()}catch{return"(could not read response body)"}}function yo(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 bo(){return an(32).toString("base64url")}function wo(n){return mo("sha256").update(n).digest("base64url")}function $o(){return an(16).toString("base64url")}function vo(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 Po=300*1e3;async function So(){return new Promise(n=>{let e=fo((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?Ro(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()},Po)});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 Ro(n){return n.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;")}function _o(n){try{process.platform==="win32"?be("cmd",["/c","start","",n]):process.platform==="darwin"?be("open",[n]):be("xdg-open",[n])}catch{console.log(" Could not open browser automatically. Please navigate to the URL above manually.")}}import{CredentialStore as Co}from"@kanonak-protocol/sdk";async function cn(n){try{let e=new A,t=new Co,r=await new M(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(`
51
51
  Authentication failed unexpectedly:
52
52
  ${t}`),console.error(`
53
- If this persists, see https://github.com/kanonak-protocol for support channels.`),process.exit(1)}}import{CredentialStore as Co}from"@kanonak-protocol/sdk";async function ln(n){try{let e=new A,t=new Co,r=await new H(e,t).logout(n);r.success?console.log(`Logged out from ${n}.`):(console.error(`
53
+ If this persists, see https://github.com/kanonak-protocol for support channels.`),process.exit(1)}}import{CredentialStore as Io}from"@kanonak-protocol/sdk";async function ln(n){try{let e=new A,t=new Io,r=await new M(e,t).logout(n);r.success?console.log(`Logged out from ${n}.`):(console.error(`
54
54
  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
- ${t}`),process.exit(1)}}import{Command as Zo}from"commander";import{KanonakParser as Qo,KanonakObjectParser as er,PublisherIndex as nr,CredentialStore as tr,createAuthenticatedFetch as or,computeIntegrity as rr}from"@kanonak-protocol/sdk";import{readFileSync as Io,writeFileSync as Do,existsSync as Ko}from"fs";import{join as xo}from"path";import un from"js-yaml";import{getGlobalCachePath as To}from"@kanonak-protocol/sdk";var Ao=`# This file is generated by Kanonak CLI. Do not edit manually.
58
- `;function pn(){let n=To();return xo(n,"..","capabilities.lock")}function M(){let n=pn();if(!Ko(n))return{version:"1",lastUpdated:new Date().toISOString(),capabilities:{}};let e=Io(n,"utf-8"),t=un.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 q(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=un.dump(n,{lineWidth:-1,sortKeys:!1,quotingType:'"'});Do(pn(),Ao+t,"utf-8")}import{SingleDocumentRepository as sr}from"@kanonak-protocol/sdk/uri-helpers";import{existsSync as Eo,readdirSync as jo,readFileSync as Oo}from"fs";import{join as dn}from"path";import{KanonakObjectParser as No,EmbeddedKanonak as hn,ReferenceKanonak as kn,getGlobalCachePath as Lo}from"@kanonak-protocol/sdk";import{SingleDocumentRepository as yn}from"@kanonak-protocol/sdk/uri-helpers";import{uriKey as $e,findSubjectsByType as Uo,getStringValue as E,getReferenceUri as ve,getListValues as bn}from"@kanonak-protocol/sdk/uri-helpers";var v="kanonak.org",P="capabilities",Pe={publisher:v,package_:P,name:"Capability"},Fo={publisher:v,package_:P,name:"commandName"},wn={publisher:v,package_:P,name:"description"},Ho={publisher:v,package_:P,name:"managesType"},Mo={publisher:v,package_:P,name:"deploymentTarget"},Vo={publisher:v,package_:P,name:"hasCommand"},Bo={publisher:v,package_:P,name:"subcommandName"},zo={publisher:v,package_:P,name:"performs"},Go={publisher:v,package_:P,name:"hasArgument"},qo={publisher:v,package_:P,name:"argumentName"},mn={publisher:v,package_:P,name:"isRequired"},fn={publisher:v,package_:P,name:"isOption"},Wo={publisher:v,package_:P,name:"defaultValue"};async function $n(n,e,t){let o=M(),r=new No,a=[],s=!1;for(let[i,c]of Object.entries(o.capabilities)){let l=c,p=n.get(l.publisher,l.package_,l.version);if(!p){let u=await Jo(i,l,e,r,t);if(u)console.error(` Healed capability "${i}": ${l.publisher}/${l.package_}@${l.version} \u2192 ${u.entry.publisher}/${u.entry.package_}@${u.entry.version} (package was renamed)`),o.capabilities[i]=u.entry,l=u.entry,p=u.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 u=e.parse(p),m=new yn(u,t),h=await r.parseKanonaks(m),k=vn(h,l.publisher,l.package_,l.version);k?a.push(k):console.error(` WARNING: No Capability instance found in "${i}" (${l.publisher}/${l.package_}@${l.version})`)}catch(u){console.error(` WARNING: Failed to parse capability "${i}": ${u}`)}}return s&&q(o),a}async function Jo(n,e,t,o,r){let a=dn(Lo(),e.publisher);if(!Eo(a))return;let s=[];for(let i of jo(a)){if(!i.endsWith(".kan.yml"))continue;let c=i.slice(0,-8),l=c.lastIndexOf("@");if(l===-1)continue;let p=c.substring(0,l),u=c.substring(l+1);if(p===e.package_&&u===e.version)continue;let m;try{m=Oo(dn(a,i),"utf-8")}catch{continue}let h;try{let k=t.parse(m),d=new yn(k,r),g=await o.parseKanonaks(d);h=vn(g,e.publisher,p,u)?.commandName}catch{continue}h===n&&s.push({entry:{publisher:e.publisher,package_:p,version:u,resolved:`kanonak://${e.publisher}/${p}@${u}`,integrity:""},content:m})}if(s.length===1)return s[0]}function vn(n,e,t,o){let r=Uo(n,Pe);if(r.length===0)return;let a=r[0],s=E(a,Fo)??"",i=E(a,wn)??"",c=ve(a,Ho),l=ve(a,Mo),p=[];for(let u of bn(a,Vo)){let m=Yo(u,n);m&&p.push(m)}return{commandName:s,description:i,managesTypeKey:c?$e(c):"",deploymentTargetKey:l?$e(l):"",commands:p,publisher:e,package_:t,version:o}}function Yo(n,e){let t;if(n instanceof hn)t=n;else if(n instanceof kn){let c=Pn(e,n.subject.publisher,n.subject.package_,n.subject.name);c&&(t=c)}if(!t)return;let o=E(t,Bo)??"",r=E(t,wn)??"",a=ve(t,zo),s=bn(t,Go),i=[];for(let c of s){let l=Xo(c,e);l&&i.push(l)}return{subcommandName:o,description:r,arguments:i,actionKey:a?$e(a):""}}function Xo(n,e){let t;if(n instanceof hn)t=n;else if(n instanceof kn){let c=Pn(e,n.subject.publisher,n.subject.package_,n.subject.name);c&&(t=c)}if(!t)return;let o=E(t,qo)??"",r=E(t,mn)==="true"||gn(t,mn)===!0,a=E(t,fn)==="true"||gn(t,fn)===!0,s=E(t,Wo),i={argumentName:o,required:r,isOption:a};return s!==void 0&&(i.defaultValue=s),i}function gn(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 Pn(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 ar,getStringValue as ir}from"@kanonak-protocol/sdk/uri-helpers";var cr={publisher:v,package_:P,name:"commandName"};function Sn(){let n=new Zo("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 lr(e)}),n.command("remove <name>").description("Remove an installed capability").action(async e=>{await ur(e)}),n.command("list").description("List installed capabilities").action(async()=>{await pr()}),n}async function lr(n){let e=K(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 D,i=new Qo,c=new er,l=new tr,p=or(l),u=new nr({fetchFn:p}),m=r??await u.getHighestVersion(t,o);m||(console.error(`Could not resolve version for "${t}/${o}".`),process.exit(1)),console.log(`Installing capability ${t}/${o}@${m}...`);let h=s.get(t,o,m);if(!h){let S=await u.getPackageUrl(t,o,m),I=await p(S,t);if(!I.ok)throw new Error(`Failed to fetch ${S} (${I.status} ${I.statusText})`);h=await I.text(),s.put(t,o,m,h)}let k=i.parse(h),d=await R(process.cwd(),i),g=new sr(k,d),f=await c.parseKanonaks(g),y=ar(f,Pe);y.length===0&&(console.error(`Package ${t}/${o}@${m} does not contain a ${v}/${P}/Capability instance.`),process.exit(1));let b=y[0],w=ir(b,cr);w||(console.error(`Capability instance in ${t}/${o}@${m} has no commandName property.`),process.exit(1));let $=M();$.capabilities[w]={publisher:t,package_:o,version:m,resolved:await u.getPackageUrl(t,o,m),integrity:rr(h)},q($),console.log(`
59
- Installed capability "${w}".`),console.log(`Run "kanonak ${w} --help" to get started.`)}async function ur(n){let e=M();e.capabilities[n]||(console.error(`Capability "${n}" is not installed.`),process.exit(1));let t=e.capabilities[n];delete e.capabilities[n],q(e),console.log(`Removed capability "${n}" (${t.publisher}/${t.package_}@${t.version}).`)}async function pr(){let n=M(),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
- `);for(let[t,o]of e)console.log(` ${t} ${o.publisher}/${o.package_}@${o.version}`)}import{Command as J}from"commander";import{readFileSync as dr,writeFileSync as mr,mkdirSync as fr,existsSync as Rn,statSync as gr}from"fs";import{join as hr,resolve as kr}from"path";import{KanonakParser as _e,KanonakObjectParser as Ce,SubjectKanonak as yr,Reasoner as br,KanonakVocabulary as wr,makeUriKey as In,pickHighestDocument as Ie,formatVersion as Dn}from"@kanonak-protocol/sdk";import{SingleDocumentRepository as W}from"@kanonak-protocol/sdk/uri-helpers";import{findSubjectsByType as Se,findSubjectByUri as $r}from"@kanonak-protocol/sdk/uri-helpers";import{TX_V3 as _n}from"@kanonak-protocol/sdk/transformations";import{TransformationRunnerV3 as vr,SUPPORTED_FORMATS_V3 as Kn}from"@kanonak-protocol/sdk/transformations";import{compileTransformationV3 as De}from"@kanonak-protocol/sdk/transformations";function Re(n){return[...Se(n,_n.InstanceTransformation),...Se(n,_n.SetTransformation)]}function xn(){let n=new J("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",`
57
+ ${t}`),process.exit(1)}}import{Command as Qo}from"commander";import{KanonakParser as er,KanonakObjectParser as nr,PublisherIndex as tr,CredentialStore as or,createAuthenticatedFetch as rr,computeIntegrity as sr}from"@kanonak-protocol/sdk";import{readFileSync as Do,writeFileSync as Ko,existsSync as xo}from"fs";import{join as To}from"path";import un from"js-yaml";import{getGlobalCachePath as Ao}from"@kanonak-protocol/sdk";var Eo=`# This file is generated by Kanonak CLI. Do not edit manually.
58
+ `;function pn(){let n=Ao();return To(n,"..","capabilities.lock")}function V(){let n=pn();if(!xo(n))return{version:"1",lastUpdated:new Date().toISOString(),capabilities:{}};let e=Do(n,"utf-8"),t=un.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 G(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=un.dump(n,{lineWidth:-1,sortKeys:!1,quotingType:'"'});Ko(pn(),Eo+t,"utf-8")}import{SingleDocumentRepository as ar}from"@kanonak-protocol/sdk/uri-helpers";import{existsSync as jo,readdirSync as Oo,readFileSync as No}from"fs";import{join as dn}from"path";import{KanonakObjectParser as Lo,EmbeddedKanonak as hn,ReferenceKanonak as kn,getGlobalCachePath as Uo}from"@kanonak-protocol/sdk";import{SingleDocumentRepository as yn}from"@kanonak-protocol/sdk/uri-helpers";import{uriKey as $e,findSubjectsByType as Fo,getStringValue as E,getReferenceUri as ve,getListValues as bn}from"@kanonak-protocol/sdk/uri-helpers";var P="kanonak.org",S="capabilities",Pe={publisher:P,package_:S,name:"Capability"},Ho={publisher:P,package_:S,name:"commandName"},wn={publisher:P,package_:S,name:"description"},Mo={publisher:P,package_:S,name:"managesType"},Vo={publisher:P,package_:S,name:"deploymentTarget"},Bo={publisher:P,package_:S,name:"hasCommand"},zo={publisher:P,package_:S,name:"subcommandName"},qo={publisher:P,package_:S,name:"performs"},Go={publisher:P,package_:S,name:"hasArgument"},Wo={publisher:P,package_:S,name:"argumentName"},mn={publisher:P,package_:S,name:"isRequired"},fn={publisher:P,package_:S,name:"isOption"},Jo={publisher:P,package_:S,name:"defaultValue"};async function $n(n,e,t){let o=V(),r=new Lo,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 Yo(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),m=new yn(p,t),h=await r.parseKanonaks(m),k=vn(h,l.publisher,l.package_,l.version);k?a.push(k):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&&G(o),a}async function Yo(n,e,t,o,r){let a=dn(Uo(),e.publisher);if(!jo(a))return;let s=[];for(let i of Oo(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 m;try{m=No(dn(a,i),"utf-8")}catch{continue}let h;try{let k=t.parse(m),d=new yn(k,r),g=await o.parseKanonaks(d);h=vn(g,e.publisher,u,p)?.commandName}catch{continue}h===n&&s.push({entry:{publisher:e.publisher,package_:u,version:p,resolved:`kanonak://${e.publisher}/${u}@${p}`,integrity:""},content:m})}if(s.length===1)return s[0]}function vn(n,e,t,o){let r=Fo(n,Pe);if(r.length===0)return;let a=r[0],s=E(a,Ho)??"",i=E(a,wn)??"",c=ve(a,Mo),l=ve(a,Vo),u=[];for(let p of bn(a,Bo)){let m=Xo(p,n);m&&u.push(m)}return{commandName:s,description:i,managesTypeKey:c?$e(c):"",deploymentTargetKey:l?$e(l):"",commands:u,publisher:e,package_:t,version:o}}function Xo(n,e){let t;if(n instanceof hn)t=n;else if(n instanceof kn){let c=Pn(e,n.subject.publisher,n.subject.package_,n.subject.name);c&&(t=c)}if(!t)return;let o=E(t,zo)??"",r=E(t,wn)??"",a=ve(t,qo),s=bn(t,Go),i=[];for(let c of s){let l=Zo(c,e);l&&i.push(l)}return{subcommandName:o,description:r,arguments:i,actionKey:a?$e(a):""}}function Zo(n,e){let t;if(n instanceof hn)t=n;else if(n instanceof kn){let c=Pn(e,n.subject.publisher,n.subject.package_,n.subject.name);c&&(t=c)}if(!t)return;let o=E(t,Wo)??"",r=E(t,mn)==="true"||gn(t,mn)===!0,a=E(t,fn)==="true"||gn(t,fn)===!0,s=E(t,Jo),i={argumentName:o,required:r,isOption:a};return s!==void 0&&(i.defaultValue=s),i}function gn(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 Pn(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 ir,getStringValue as cr}from"@kanonak-protocol/sdk/uri-helpers";var lr={publisher:P,package_:S,name:"commandName"};function Sn(){let n=new Qo("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 ur(e)}),n.command("remove <name>").description("Remove an installed capability").action(async e=>{await pr(e)}),n.command("list").description("List installed capabilities").action(async()=>{await dr()}),n}async function ur(n){let e=K(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 D,i=new er,c=new nr,l=new or,u=rr(l),p=new tr({fetchFn:u}),m=r??await p.getHighestVersion(t,o);m||(console.error(`Could not resolve version for "${t}/${o}".`),process.exit(1)),console.log(`Installing capability ${t}/${o}@${m}...`);let h=s.get(t,o,m);if(!h){let R=await p.getPackageUrl(t,o,m),I=await u(R,t);if(!I.ok)throw new Error(`Failed to fetch ${R} (${I.status} ${I.statusText})`);h=await I.text(),s.put(t,o,m,h)}let k=i.parse(h),d=await v(process.cwd(),i),g=new ar(k,d),f=await c.parseKanonaks(g),y=ir(f,Pe);y.length===0&&(console.error(`Package ${t}/${o}@${m} does not contain a ${P}/${S}/Capability instance.`),process.exit(1));let b=y[0],w=cr(b,lr);w||(console.error(`Capability instance in ${t}/${o}@${m} has no commandName property.`),process.exit(1));let $=V();$.capabilities[w]={publisher:t,package_:o,version:m,resolved:await p.getPackageUrl(t,o,m),integrity:sr(h)},G($),console.log(`
59
+ Installed capability "${w}".`),console.log(`Run "kanonak ${w} --help" to get started.`)}async function pr(n){let e=V();e.capabilities[n]||(console.error(`Capability "${n}" is not installed.`),process.exit(1));let t=e.capabilities[n];delete e.capabilities[n],G(e),console.log(`Removed capability "${n}" (${t.publisher}/${t.package_}@${t.version}).`)}async function dr(){let n=V(),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
+ `);for(let[t,o]of e)console.log(` ${t} ${o.publisher}/${o.package_}@${o.version}`)}import{Command as J}from"commander";import{readFileSync as mr,writeFileSync as fr,mkdirSync as gr,existsSync as Rn,statSync as hr}from"fs";import{join as kr,resolve as yr}from"path";import{KanonakParser as _e,KanonakObjectParser as Ce,SubjectKanonak as br,Reasoner as wr,KanonakVocabulary as $r,makeUriKey as In,pickHighestDocument as Ie,formatVersion as Dn}from"@kanonak-protocol/sdk";import{SingleDocumentRepository as W}from"@kanonak-protocol/sdk/uri-helpers";import{findSubjectsByType as Se,findSubjectByUri as vr}from"@kanonak-protocol/sdk/uri-helpers";import{TX_V3 as _n}from"@kanonak-protocol/sdk/transformations";import{TransformationRunnerV3 as Pr,SUPPORTED_FORMATS_V3 as Kn}from"@kanonak-protocol/sdk/transformations";import{compileTransformationV3 as De}from"@kanonak-protocol/sdk/transformations";function Re(n){return[...Se(n,_n.InstanceTransformation),...Se(n,_n.SetTransformation)]}function xn(){let n=new J("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:
62
62
 
63
63
  # List every Transformation available in the local workspace
@@ -95,9 +95,9 @@ Examples:
95
95
 
96
96
  # List the registered format backends
97
97
  $ kanonak transform formats
98
- `);return n.addCommand(Pr()),n.addCommand(Cr()),n.addCommand(Dr()),n.addCommand(xr()),n}function Pr(){return new J("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.",Sr,[]).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 Rr(n,e)}catch(t){console.error(`Error: ${t.message}`),process.exit(1)}})}function Sr(n,e){return[...e,n]}async function Rr(n,e){let t=new _e,o=new Ce,r=await R(process.cwd(),t),a=await Tn(n,r,o),{transformation:s,transformationKanonaks:i}=a;console.log(`Transformation: ${Q(s)}`);let c=De(s,i);e.scope.length===0&&(console.error("At least one --scope is required."),process.exit(1));let l=[],p=new Map;for(let y of e.scope){let b=await Tr(y,r,t,o);l.push(...b);let w=await jr(b,c.inputPattern.matchesClass,r);for(let $ of w){let S=Or($);S&&!p.has(S)&&p.set(S,$)}console.log(`Scope: ${y} \u2014 found ${w.length} instance(s) of ${c.inputPattern.matchesClass.publisher}/${c.inputPattern.matchesClass.package_}/${c.inputPattern.matchesClass.name}`)}let u=[...p.values()],m=l;e.scope.length>1&&console.log(`Total across ${e.scope.length} scope(s): ${u.length} unique instance(s)`),u.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 h=_r(c.outputs,e.format);console.log(`Output format: ${h}`);let k=Kn[h];if(!k)throw new Error(`Unknown format "${h}". Run \`kanonak transform formats\` to see what the runner supports.`);let g=await new vr().run({transformation:s,instances:u,allKanonaks:m,transformationKanonaks:i,repository:r,parser:t,objectParser:o,outputFormat:h}),f=kr(e.out);fr(f,{recursive:!0});for(let y of g){let b=Er(y.fileName),w=hr(f,`${b}${k.extension}`);mr(w,y.content,"utf-8"),console.log(` wrote ${w}`)}console.log(`Done. ${g.length} artifact(s) written to ${f}`)}function _r(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 Cr(){return new J("list").description("Scan the local workspace + cache for every Transformation instance and print a one-line summary per hit.").action(async()=>{try{await Ir()}catch(n){console.error(`Error: ${n.message}`),process.exit(1)}})}async function Ir(){let n=new _e,e=new Ce,t=await R(process.cwd(),n),o=await t.getAllDocumentsAsync(),r=new Map;for(let s of o)try{let i=new W(s,t),c=await e.parseKanonaks(i),l=Re(c);for(let p of l){let u=Ke(p);if(!u)continue;let m=r.get(u)??[];m.push({tx:p,kanonaks:c,doc:s}),r.set(u,m)}}catch{}let a=[];for(let s of r.values()){if(s.length===1){a.push(Cn(s[0].tx,s[0].kanonaks));continue}let i=Ie(s.map(l=>l.doc));if(!i.chosen)continue;let c=s.find(l=>l.doc===i.chosen);c&&a.push(Cn(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 Dr(){return new J("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 Kr(n)}catch(e){console.error(`Error: ${e.message}`),process.exit(1)}})}async function Kr(n){let e=new _e,t=new Ce,o=await R(process.cwd(),e),{transformation:r,transformationKanonaks:a}=await Tn(n,o,t),s=De(r,a);if(console.log(`Transformation: ${Q(r)}`),console.log(),console.log("Input pattern:"),console.log(` Matches class: ${Z(s.inputPattern.matchesClass)}`),s.inputPattern.requires.length>0){console.log(" Required properties:");for(let i of s.inputPattern.requires)console.log(` - ${Z(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[p,u]of c.metadataRenames)l.push(`${p} \u2192 ${u}`);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: ${Z(s.rule.astClass)}`),console.log(`Rule root bindings: ${s.rule.set.length} field(s)`)),console.log(`Artifact name root kind: ${s.artifactName.kind}`)}function xr(){return new J("formats").description("List the OutputFormat names the runner can serialize to.").action(()=>{console.log("Registered format backends:");let n=Object.entries(Kn).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 Tn(n,e,t){let o,r,a;if(n.includes("/")){let m=n.indexOf("@"),h=n;if(m!==-1){let d=n.indexOf("/",m);if(d===-1)throw new Error(`Transformation URI "${n}" has @version but no trailing /<name>`);h=n.substring(0,m)+n.substring(d)}let k=h.split("/");if(k.length<3)throw new Error(`Invalid transformation URI "${n}" \u2014 expected publisher/package/name or publisher/package@version/name`);o=k[0],r=k[1],a=k.slice(2).join("/")}else a=n;if(o&&r){let m=await e.getDocumentsByNamespaceAsync(o,r);if(m.length===0)throw new Error(`Package ${o}/${r} not found in the local workspace or cache.`);let h=Ar(n),k=An(m,h,`${o}/${r}`),d=new W(k,e),g=await t.parseKanonaks(d),f=$r(g,{publisher:o,package_:r,name:a,version:""});if(!f){let y=Re(g),b=y.find(w=>w.name===a);if(!b)throw new Error(`Transformation "${a}" not found in package ${o}/${r}. Package contains ${y.length} Transformation(s): ${y.map(w=>w.name).join(", ")||"(none)"}`);return{transformation:b,transformationKanonaks:g}}return{transformation:f,transformationKanonaks:g}}let s=await e.getAllDocumentsAsync(),i=new Map;for(let m of s)try{let h=new W(m,e),k=await t.parseKanonaks(h),d=Re(k);for(let g of d){if(g.name!==a)continue;let f=Ke(g);if(!f)continue;let y=i.get(f)??[];y.push({tx:g,kanonaks:k,doc:m}),i.set(f,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 m=Array.from(i.keys()).sort().join(`
98
+ `);return n.addCommand(Sr()),n.addCommand(Ir()),n.addCommand(Kr()),n.addCommand(Tr()),n}function Sr(){return new J("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.",Rr,[]).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 _r(n,e)}catch(t){console.error(`Error: ${t.message}`),process.exit(1)}})}function Rr(n,e){return[...e,n]}async function _r(n,e){let t=new _e,o=new Ce,r=await v(process.cwd(),t),a=await Tn(n,r,o),{transformation:s,transformationKanonaks:i}=a;console.log(`Transformation: ${Q(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 b=await Ar(y,r,t,o);l.push(...b);let w=await Or(b,c.inputPattern.matchesClass,r);for(let $ of w){let R=Nr($);R&&!u.has(R)&&u.set(R,$)}console.log(`Scope: ${y} \u2014 found ${w.length} instance(s) of ${c.inputPattern.matchesClass.publisher}/${c.inputPattern.matchesClass.package_}/${c.inputPattern.matchesClass.name}`)}let p=[...u.values()],m=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 h=Cr(c.outputs,e.format);console.log(`Output format: ${h}`);let k=Kn[h];if(!k)throw new Error(`Unknown format "${h}". Run \`kanonak transform formats\` to see what the runner supports.`);let g=await new Pr().run({transformation:s,instances:p,allKanonaks:m,transformationKanonaks:i,repository:r,parser:t,objectParser:o,outputFormat:h}),f=yr(e.out);gr(f,{recursive:!0});for(let y of g){let b=jr(y.fileName),w=kr(f,`${b}${k.extension}`);fr(w,y.content,"utf-8"),console.log(` wrote ${w}`)}console.log(`Done. ${g.length} artifact(s) written to ${f}`)}function Cr(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 Ir(){return new J("list").description("Scan the local workspace + cache for every Transformation instance and print a one-line summary per hit.").action(async()=>{try{await Dr()}catch(n){console.error(`Error: ${n.message}`),process.exit(1)}})}async function Dr(){let n=new _e,e=new Ce,t=await v(process.cwd(),n),o=await t.getAllDocumentsAsync(),r=new Map;for(let s of o)try{let i=new W(s,t),c=await e.parseKanonaks(i),l=Re(c);for(let u of l){let p=Ke(u);if(!p)continue;let m=r.get(p)??[];m.push({tx:u,kanonaks:c,doc:s}),r.set(p,m)}}catch{}let a=[];for(let s of r.values()){if(s.length===1){a.push(Cn(s[0].tx,s[0].kanonaks));continue}let i=Ie(s.map(l=>l.doc));if(!i.chosen)continue;let c=s.find(l=>l.doc===i.chosen);c&&a.push(Cn(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 Kr(){return new J("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 xr(n)}catch(e){console.error(`Error: ${e.message}`),process.exit(1)}})}async function xr(n){let e=new _e,t=new Ce,o=await v(process.cwd(),e),{transformation:r,transformationKanonaks:a}=await Tn(n,o,t),s=De(r,a);if(console.log(`Transformation: ${Q(r)}`),console.log(),console.log("Input pattern:"),console.log(` Matches class: ${Z(s.inputPattern.matchesClass)}`),s.inputPattern.requires.length>0){console.log(" Required properties:");for(let i of s.inputPattern.requires)console.log(` - ${Z(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: ${Z(s.rule.astClass)}`),console.log(`Rule root bindings: ${s.rule.set.length} field(s)`)),console.log(`Artifact name root kind: ${s.artifactName.kind}`)}function Tr(){return new J("formats").description("List the OutputFormat names the runner can serialize to.").action(()=>{console.log("Registered format backends:");let n=Object.entries(Kn).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 Tn(n,e,t){let o,r,a;if(n.includes("/")){let m=n.indexOf("@"),h=n;if(m!==-1){let d=n.indexOf("/",m);if(d===-1)throw new Error(`Transformation URI "${n}" has @version but no trailing /<name>`);h=n.substring(0,m)+n.substring(d)}let k=h.split("/");if(k.length<3)throw new Error(`Invalid transformation URI "${n}" \u2014 expected publisher/package/name or publisher/package@version/name`);o=k[0],r=k[1],a=k.slice(2).join("/")}else a=n;if(o&&r){let m=await e.getDocumentsByNamespaceAsync(o,r);if(m.length===0)throw new Error(`Package ${o}/${r} not found in the local workspace or cache.`);let h=Er(n),k=An(m,h,`${o}/${r}`),d=new W(k,e),g=await t.parseKanonaks(d),f=vr(g,{publisher:o,package_:r,name:a,version:""});if(!f){let y=Re(g),b=y.find(w=>w.name===a);if(!b)throw new Error(`Transformation "${a}" not found in package ${o}/${r}. Package contains ${y.length} Transformation(s): ${y.map(w=>w.name).join(", ")||"(none)"}`);return{transformation:b,transformationKanonaks:g}}return{transformation:f,transformationKanonaks:g}}let s=await e.getAllDocumentsAsync(),i=new Map;for(let m of s)try{let h=new W(m,e),k=await t.parseKanonaks(h),d=Re(k);for(let g of d){if(g.name!==a)continue;let f=Ke(g);if(!f)continue;let y=i.get(f)??[];y.push({tx:g,kanonaks:k,doc:m}),i.set(f,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 m=Array.from(i.keys()).sort().join(`
99
99
  `);throw new Error(`Multiple Transformations named "${a}" in the workspace \u2014 disambiguate with a full publisher/package/name URI:
100
- ${m}`)}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(m=>[m.doc,m])),p=Ie(c.map(m=>m.doc));if(!p.chosen)throw new Error(`Could not select a Transformation version for "${a}".`);let u=l.get(p.chosen);if(p.multipleVersionsPresent){let m=d=>{let g=d.metadata.namespace_?.version;return g?Dn(g):""},h=u.tx.namespace??"",k=h.includes("@")?h.substring(0,h.indexOf("@")):h;console.warn(`Warning: Transformation "${a}" has ${c.length} versions present (${c.map(d=>m(d.doc)).filter(Boolean).join(", ")}); using @${m(p.chosen)}. Pin with ${k}@<version>/${a} to suppress this warning.`)}return{transformation:u.tx,transformationKanonaks:u.kanonaks}}async function Tr(n,e,t,o){if(/^[.\/\\]/.test(n)||/^[A-Za-z]:/.test(n)||n.endsWith(".kan.yml")||Rn(n)&&gr(n).isFile()){if(!Rn(n))throw new Error(`Scope file not found: ${n}`);let k=dr(n,"utf-8"),d=t.parse(k),g=new W(d,e);return o.parseKanonaks(g)}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),p=s.substring(c+1),u=await e.getDocumentsByNamespaceAsync(l,p);if(u.length===0)throw new Error(`Scope package ${l}/${p} not found in the local workspace or cache.`);let m=An(u,i,`${l}/${p}`),h=new W(m,e);return o.parseKanonaks(h)}function Ar(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 An(n,e,t){let o=a=>{let s=a.metadata.namespace_?.version;return s?Dn(s):""},r=Ie(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 Cn(n,e){try{let t=De(n,e);return{uri:Q(n),matchesClass:Z(t.inputPattern.matchesClass),outputs:Array.from(t.outputs).sort()}}catch(t){return{uri:Q(n),matchesClass:`(compile error: ${t.message})`,outputs:[]}}}function Q(n){let e=n.namespace||"",t=e.indexOf("@");return`${t===-1?e:e.substring(0,t)}/${n.name}`}function Z(n){return`${n.publisher}/${n.package_}/${n.name}`}function Er(n){return n.replace(/[\\/:*?"<>|\s]+/g,"_").replace(/^_+|_+$/g,"")}async function jr(n,e,t){let o=new Map;for(let s of n){if(!(s instanceof yr))continue;let i=Ke(s);i&&o.set(i,s)}let r=[];try{r=(await new br({vocabulary:new wr}).reason(t)).getInstancesOfClass(In(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:Se(n,e)}function Ke(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:In(o.substring(0,r),o.substring(r+1),n.name)}function Or(n){let e=n.namespace??"";return!e||!n.name?null:`${e}/${n.name}`}import{Command as Nr}from"commander";import{writeFileSync as Lr,mkdirSync as Ur}from"fs";import{join as Fr,resolve as Hr}from"path";import{KanonakParser as Mr,KanonakObjectParser as Vr,SubjectKanonak as On,findDerivation as Br}from"@kanonak-protocol/sdk";import{TransformationRunnerV3 as zr}from"@kanonak-protocol/sdk/transformations";var Gr={publisher:"kanonak.org",package_:"formats",name:"html"},qr={publisher:"kanonak.org",package_:"derivation",name:"default"},Wr={html:".html",markdown:".md",json:".json",yaml:".yaml",xml:".xml",svg:".svg",typescript:".ts","c-sharp":".cs",rust:".rs",python:".py"};function Jr(n){return n==="markdown"?"markdown-with-frontmatter":n}function Nn(){return new Nr("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",`
100
+ ${m}`)}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(m=>[m.doc,m])),u=Ie(c.map(m=>m.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 m=d=>{let g=d.metadata.namespace_?.version;return g?Dn(g):""},h=p.tx.namespace??"",k=h.includes("@")?h.substring(0,h.indexOf("@")):h;console.warn(`Warning: Transformation "${a}" has ${c.length} versions present (${c.map(d=>m(d.doc)).filter(Boolean).join(", ")}); using @${m(u.chosen)}. Pin with ${k}@<version>/${a} to suppress this warning.`)}return{transformation:p.tx,transformationKanonaks:p.kanonaks}}async function Ar(n,e,t,o){if(/^[.\/\\]/.test(n)||/^[A-Za-z]:/.test(n)||n.endsWith(".kan.yml")||Rn(n)&&hr(n).isFile()){if(!Rn(n))throw new Error(`Scope file not found: ${n}`);let k=mr(n,"utf-8"),d=t.parse(k),g=new W(d,e);return o.parseKanonaks(g)}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 m=An(p,i,`${l}/${u}`),h=new W(m,e);return o.parseKanonaks(h)}function Er(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 An(n,e,t){let o=a=>{let s=a.metadata.namespace_?.version;return s?Dn(s):""},r=Ie(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 Cn(n,e){try{let t=De(n,e);return{uri:Q(n),matchesClass:Z(t.inputPattern.matchesClass),outputs:Array.from(t.outputs).sort()}}catch(t){return{uri:Q(n),matchesClass:`(compile error: ${t.message})`,outputs:[]}}}function Q(n){let e=n.namespace||"",t=e.indexOf("@");return`${t===-1?e:e.substring(0,t)}/${n.name}`}function Z(n){return`${n.publisher}/${n.package_}/${n.name}`}function jr(n){return n.replace(/[\\/:*?"<>|\s]+/g,"_").replace(/^_+|_+$/g,"")}async function Or(n,e,t){let o=new Map;for(let s of n){if(!(s instanceof br))continue;let i=Ke(s);i&&o.set(i,s)}let r=[];try{r=(await new wr({vocabulary:new $r}).reason(t)).getInstancesOfClass(In(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:Se(n,e)}function Ke(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:In(o.substring(0,r),o.substring(r+1),n.name)}function Nr(n){let e=n.namespace??"";return!e||!n.name?null:`${e}/${n.name}`}import{Command as Lr}from"commander";import{writeFileSync as Ur,mkdirSync as Fr}from"fs";import{join as Hr,resolve as Mr}from"path";import{KanonakParser as Vr,KanonakObjectParser as Br,SubjectKanonak as On,findDerivation as zr}from"@kanonak-protocol/sdk";import{TransformationRunnerV3 as qr}from"@kanonak-protocol/sdk/transformations";var Gr={publisher:"kanonak.org",package_:"formats",name:"html"},Wr={publisher:"kanonak.org",package_:"derivation",name:"default"},Jr={html:".html",markdown:".md",json:".json",yaml:".yaml",xml:".xml",svg:".svg",typescript:".ts","c-sharp":".cs",rust:".rs",python:".py"};function Yr(n){return n==="markdown"?"markdown-with-frontmatter":n}function Nn(){return new Lr("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,12 +108,14 @@ 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 Yr(n,e)}catch(t){console.error(`Error: ${t.message}`),process.exit(1)}})}async function Yr(n,e){let t=K(n);if(!t||!t.instanceName)throw new Error(`Invalid resource URI "${n}". Expected publisher/package[@version]/instance.`);let o=new Mr,r=new Vr,a=await R(process.cwd(),o),s=await r.parseKanonaks(a),i=Xr(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: ${En(i)}`);let c=Qr(e.format),l=es(e.variant),p=Br(i,c,l,s);if(!p)throw new Error(`No derivation found for resource ${En(i)} at (format=${e.format}, variant=${e.variant}). The class hierarchy declares no binding and no universal default applies.`);console.log(`Derivation: ${ns(p)} \u2192 ${jn(p.transformation)}`);let u=Zr(s,p.transformation);if(!u)throw new Error(`Transformation ${jn(p.transformation)} not found in the workspace or cache. The binding pointed at a transformation the resolver cannot locate.`);let m=Jr(e.format),k=await new zr().run({transformation:u,instances:[i],allKanonaks:s,repository:a,parser:o,objectParser:r,outputFormat:m}),d=Hr(e.out);Ur(d,{recursive:!0});let g=Wr[e.format]??"";for(let f of k){let y=ts(f.fileName),b=Fr(d,`${y}${g}`);Lr(b,f.content,"utf-8"),console.log(` wrote ${b}`)}console.log(`Done. ${k.length} artifact(s) written to ${d}`)}function Xr(n,e){for(let t of n){if(!(t instanceof On)||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 Zr(n,e){let t=`${e.publisher}/${e.package_}@${e.version}`;for(let o of n)if(o instanceof On&&o.name===e.name&&o.namespace===t)return o}function Qr(n){if(n.includes("/")){let e=K(n);if(!e||!e.instanceName)throw new Error(`Invalid --format URI "${n}".`);return{publisher:e.publisher,package_:e.packageName,name:e.instanceName}}return{...Gr,name:n}}function es(n){if(n.includes("/")){let e=K(n);if(!e||!e.instanceName)throw new Error(`Invalid --variant URI "${n}".`);return{publisher:e.publisher,package_:e.packageName,name:e.instanceName}}return{...qr,name:n}}function En(n){return`${n.namespace}/${n.name}`}function jn(n){return`${n.publisher}/${n.package_}@${n.version}/${n.name}`}function ns(n){return n.source==="instance"?"instance override":`class ${n.source.publisher}/${n.source.package_}/${n.source.name}`}function ts(n){return n.replace(/[^a-zA-Z0-9._@-]+/g,"_")}import{Command as Mn}from"commander";import{writeFileSync as xe,mkdirSync as ee}from"fs";import{join as Te,resolve as os,dirname as Ae}from"path";import{KanonakParser as rs,KanonakObjectParser as ss,SubjectKanonak as Vn,ReferenceStatement as as,ReferenceKanonak as is,ListStatement as cs,StringStatement as Bn,EmbeddedStatement as ls,findDerivation as Ln}from"@kanonak-protocol/sdk";import{SingleDocumentRepository as us}from"@kanonak-protocol/sdk/uri-helpers";import{TransformationRunnerV3 as ps}from"@kanonak-protocol/sdk/transformations";import{findSubjectsByType as ne}from"@kanonak-protocol/sdk/uri-helpers";var x="kanonak.org",T="site",Un={publisher:"kanonak.org",package_:"formats",name:"html"},Fn={publisher:"kanonak.org",package_:"derivation",name:"default"};function zn(){let n=new Mn("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(ds()),n}function ds(){return new Mn("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 ms(n)}catch(e){console.error(`Error: ${e.message}`),process.exit(1)}})}async function ms(n){let e=new rs,t=new ss,o=await R(process.cwd(),e),r=await t.parseKanonaks(o),a=os(n.out);ee(a,{recursive:!0});let s=await o.getAllDocumentsAsync(),i=new Set;for(let d of s){let g=d.metadata.namespace_?.toString();g&&i.add(g)}let c={publisher:x,package_:T,name:"StaticPage"},l={publisher:x,package_:T,name:"ResourcePage"},p={publisher:x,package_:T,name:"AggregateView"},u=ne(r,c).filter(d=>i.has(d.namespace||"")),m=ne(r,l).filter(d=>i.has(d.namespace||"")),h=ne(r,p).filter(d=>i.has(d.namespace||""));console.log(`Found ${u.length} StaticPage(s), ${m.length} ResourcePage(s), and ${h.length} AggregateView(s) in the workspace.`);let k=new ps;for(let d of u){let g=Ee(d,x,T,"outputPath")??`${d.name}.html`,f=Ln(d,Un,Fn,r);if(!f){console.warn(` [skip] ${d.name}: no HTML/default derivation found (check class hierarchy or universal-derivations is loaded)`);continue}let y=je(r,f.transformation);if(!y){console.warn(` [skip] ${d.name}: transformation ${Oe(f.transformation)} not found`);continue}let b=await k.run({transformation:y,instances:[d],allKanonaks:r,repository:o,parser:e,objectParser:t,outputFormat:"html"});if(b.length===0){console.warn(` [skip] ${d.name}: transformation produced no artifacts`);continue}let w=Te(a,g);ee(Ae(w),{recursive:!0}),xe(w,b[0].content,"utf-8"),console.log(` wrote ${w} (StaticPage ${d.name})`)}for(let d of m){let g=Ee(d,x,T,"outputPath")??`${d.name}.html`,f=Hn(d,x,T,"pageOf");if(!f){console.warn(` [skip] ${d.name}: no pageOf declared`);continue}let y=r.find(I=>I instanceof Vn&&I.name===f.name&&(I.namespace||"").startsWith(`${f.publisher}/${f.package_}@`));if(!y){console.warn(` [skip] ${d.name}: pageOf target ${f.publisher}/${f.package_}/${f.name} not found`);continue}let b=Ln(y,Un,Fn,r);if(!b){console.warn(` [skip] ${d.name}: no derivation for target ${y.name}`);continue}let w=je(r,b.transformation);if(!w){console.warn(` [skip] ${d.name}: transformation ${Oe(b.transformation)} not found`);continue}let $=await k.run({transformation:w,instances:[y],allKanonaks:r,repository:o,parser:e,objectParser:t,outputFormat:"html"});if($.length===0){console.warn(` [skip] ${d.name}: transformation produced no artifacts`);continue}let S=Te(a,g);ee(Ae(S),{recursive:!0}),xe(S,$[0].content,"utf-8"),console.log(` wrote ${S} (ResourcePage ${d.name} \u2192 ${y.name})`)}for(let d of h){let g=Ee(d,x,T,"outputPath");if(!g){console.warn(` [skip] ${d.name}: no outputPath declared`);continue}let f=Hn(d,x,T,"scopeClass");if(!f){console.warn(` [skip] ${d.name}: no scopeClass declared`);continue}let y={publisher:f.publisher,package_:f.package_,name:f.name},b=fs(d,x,T,"scopeSources"),w=gs(d);if(!w){console.warn(` [skip] ${d.name}: no transformation declared`);continue}let $=je(r,w);if(!$){console.warn(` [skip] ${d.name}: transformation ${Oe(w)} not found`);continue}let S=await ks(b,o),I=[],Ge=new Set;for(let Kt of S){let xt=await ys(Kt,o,e,t),Tt=ne(xt,y);for(let he of Tt){let We=`${he.namespace}/${he.name}`;Ge.has(We)||(Ge.add(We),I.push(he))}}console.log(` ${d.name}: ${I.length} instance(s) of ${y.publisher}/${y.package_}/${y.name} across ${S.length} scope(s)`);let qe=await k.run({transformation:$,instances:I,allKanonaks:r,repository:o,parser:e,objectParser:t,outputFormat:"html"});if(qe.length===0){console.warn(` [skip] ${d.name}: transformation produced no artifacts`);continue}let ge=Te(a,g);ee(Ae(ge),{recursive:!0}),xe(ge,qe[0].content,"utf-8"),console.log(` wrote ${ge} (AggregateView ${d.name})`)}console.log("Site build complete.")}function Ee(n,e,t,o){for(let r of n.statement)if(r instanceof Bn&&te(r,e,t,o))return r.object}function fs(n,e,t,o){for(let r of n.statement){if(!(r instanceof cs)||!te(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 Hn(n,e,t,o){for(let r of n.statement)if(r instanceof as&&te(r,e,t,o)&&r.object instanceof is)return{publisher:r.object.subject.publisher,package_:r.object.subject.package_,name:r.object.subject.name}}function gs(n){for(let e of n.statement)if(e instanceof ls&&te(e,x,T,"transformation"))return hs(e.object)}function hs(n){let e,t,o,r;for(let a of n.statement){if(!(a instanceof Bn))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 te(n,e,t,o){let r=n.predicate?.subject;return r?r.publisher===e&&r.package_===t&&r.name===o:!1}function je(n,e){let t=`${e.publisher}/${e.package_}@${e.version}`;for(let o of n)if(o instanceof Vn&&o.name===e.name&&o.namespace===t)return o}function Oe(n){return`${n.publisher}/${n.package_}@${n.version}/${n.name}`}async function ks(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 p of l){let u=p.metadata.namespace_;if(!u)continue;let m=u.version;t.push(`${u.publisher}/${u.package_}@${m.major}.${m.minor}.${m.patch}`)}}return t}async function ys(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 p of l){let u=p.metadata.namespace_?.version;if(u&&`${u.major}.${u.minor}.${u.patch}`===c){let m=new us(p,e);return o.parseKanonaks(m)}}return[]}import{Command as bs}from"commander";import{KanonakParser as ws,PublisherIndex as Gn,CredentialStore as qn,createAuthenticatedFetch as Wn,FileSystemKanonakDocumentRepository as $s,Reasoner as vs,KanonakVocabulary as Ps,getGlobalCachePath as Ss,makeUriKey as Rs}from"@kanonak-protocol/sdk";function _s(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 Jn(){return new bs("search").description("Browse a publisher's catalogue or find instances of a class via the SDK reasoner").argument("<publisher>","Publisher domain (e.g. kanonak.org)").option("--type <uri>","Class URI to search for, in publisher/package/Name form").action(async(n,e)=>{e.type?await Is(n,e.type):await Cs(n)})}async function Cs(n){let e=new qn,t=Wn(e),o=new Gn({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}:
112
- `);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 Is(n,e){let t=_s(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 ws,r=new qn,a=Wn(r),s=new Gn({fetchFn:a}),i=new D,c=new Set,l=[];try{l=await s.listLatestPackages(n)}catch(g){console.error(`Failed to fetch publisher index for ${n}: ${g.message}`),process.exit(1)}for(let{packageName:g,version:f}of l)c.add(`${n}|${g}|${f}`);await Ne(s,i,a,"kanonak.org","core-rdf",c),await Ne(s,i,a,"kanonak.org","core-owl",c),await Ne(s,i,a,t.publisher,t.package_,c);for(let g of c){let[f,y,b]=g.split("|");if(!i.has(f,y,b))try{let w=await s.getPackageUrl(f,y,b),$=await a(w,f);if(!$.ok){console.error(`Warning: failed to fetch ${f}/${y}@${b}: ${$.status} ${$.statusText}`);continue}let S=await $.text();i.put(f,y,b,S)}catch(w){console.error(`Warning: failed to fetch ${f}/${y}@${b}: ${w.message}`)}}let p=new $s(Ss(),!0,o),m=await new vs({vocabulary:new Ps}).reason(p),h=Rs(t.publisher,t.package_,t.name),d=m.getInstancesOfClass(h).filter(g=>g!==h);if(d.length===0){console.log(`No instances of ${h} found in ${n}'s catalogue.`);return}console.log(`Instances of ${h} in ${n}'s catalogue:
113
- `),d.sort();for(let g of d)console.log(` ${g}`)}async function Ne(n,e,t,o,r,a){try{let s=await n.getHighestVersion(o,r);if(!s)return;a.add(`${o}|${r}|${s}`)}catch{}}import{Command as Yn}from"commander";function V(n){return`${v}/${P}/${n}`}var Le={[V("fetch-and-deploy")]:(n,e,t,o)=>n.add(e,t[0],o),[V("remove-deployed")]:(n,e,t,o)=>n.remove(e,t[0],o),[V("list-deployed")]:(n,e,t,o)=>n.list(e,o),[V("update-deployed")]:(n,e,t,o)=>n.update(e,t[0],o),[V("search-available")]:(n,e,t,o)=>n.search(e,o),[V("show-info")]:(n,e,t,o)=>n.info(e,t[0],o)};function Xn(n,e,t){for(let o of e){let r=new Yn(o.commandName).description(o.description.trim());for(let a of o.commands){let s=r.command(Ds(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=Ks(i);await xs(t,o,a,i,c)})}n.addCommand(r)}}function Ds(n){let e=n.arguments.filter(t=>!t.isOption).map(t=>t.required?`<${t.argumentName}>`:`[${t.argumentName}]`);return[n.subcommandName,...e].join(" ")}function Ks(n){for(let e=n.length-1;e>=0;e--)if(n[e]&&typeof n[e]=="object"&&!(n[e]instanceof Yn))return n[e];return{}}async function xs(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(Le).join(", ")}.`),process.exit(1));let s=Le[t.actionKey];s||(console.error(`Capability subcommand '${t.subcommandName}' references unknown Action '${t.actionKey}'. Known actions: ${Object.keys(Le).join(", ")}.`),process.exit(1)),await s(n,e,a,r)}import{existsSync as Zn,readFileSync as Ts,statSync as Qn}from"fs";import{resolve as As}from"path";import{KanonakObjectParser as Es,PublisherIndex as Ue,PublisherConfigResolver as js,formatVersion as et,pickHighestDocument as Os}from"@kanonak-protocol/sdk";import{SingleDocumentRepository as nt}from"@kanonak-protocol/sdk/uri-helpers";import{uriKey as B,findSubjectsByType as tt}from"@kanonak-protocol/sdk/uri-helpers";var oe=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 Es;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=K(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,p=await this.repository.getDocumentsByNamespaceAsync(s,i);if(p.length>0){let h=Os(p,{requestedVersion:c??void 0});if(h.chosen){let k=h.chosen.metadata.namespace_;(!k||!k.version)&&(console.error(`Document for ${s}/${i} is missing namespace metadata.`),process.exit(1));let d=et(k.version);this.fileCache.put(s,i,d,this.parser.save(h.chosen)),await this.deployFromDoc(e,h.chosen,s,i,d,l??void 0,`${s}/${i}@${d}`,o);return}}let u=c??await this.publisherIndex.getHighestVersion(s,i);u||(console.error(`Could not resolve version for "${s}/${i}".`),await this.printPackageSuggestions(s,i,e.commandName),process.exit(1));let m=this.fileCache.get(s,i,u);if(!m){let h=await this.publisherIndex.getPackageUrl(s,i,u),k=await this.fetchFn(h,s);k.ok||(k.status===404?(console.error(`Package ${s}/${i}@${u} not found at ${h}.`),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 ${h} (${k.status} ${k.statusText}).`),process.exit(1)),m=await k.text(),this.fileCache.put(s,i,u,m)}await this.deployFromDoc(e,this.parser.parse(m),s,i,u,l??void 0,`${s}/${i}@${u}`,o)}tryLoadFromLocalFile(e){if(!(/^[.\/\\]/.test(e)||/^[A-Za-z]:[\\/]/.test(e)||e.endsWith(".kan.yml")||Zn(e)&&Qn(e).isFile()))return;let o=As(e);(!Zn(o)||!Qn(o).isFile())&&(console.error(`Local file not found: ${e}`),process.exit(1));let r=Ts(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:et(s.version)}}async deployFromDoc(e,t,o,r,a,s,i,c){let l=new nt(t,this.repository),p=await this.objectParser.parseKanonaks(l),u=ot(e.managesTypeKey);u||(console.error(`Capability "${e.commandName}" has no resolved managesType.`),process.exit(1));let m=tt(p,u);m.length===0&&(console.error(`${i} does not contain any ${B(u)} instances.`),process.exit(1));let h=m;if(s&&(h=m.filter(g=>g.name===s),h.length===0)){console.error(`Instance "${s}" not found in ${i}.`),console.error(""),console.error(`Available ${B(u)} instance(s):`);for(let g of m)console.error(` - ${g.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 k=s?`${s} from ${i}`:`${h.length} ${B(u)} instance(s) from ${i}`;console.log(`Installing ${k}...`);let d=this.handlerRegistry.get(e.deploymentTargetKey);d?await d.deploy({instances:h,allKanonaks:p,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:Ns(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:
111
+ `).action(async(n,e)=>{try{await Xr(n,e)}catch(t){console.error(`Error: ${t.message}`),process.exit(1)}})}async function Xr(n,e){let t=K(n);if(!t||!t.instanceName)throw new Error(`Invalid resource URI "${n}". Expected publisher/package[@version]/instance.`);let o=new Vr,r=new Br,a=await v(process.cwd(),o),s=await r.parseKanonaks(a),i=Zr(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: ${En(i)}`);let c=es(e.format),l=ns(e.variant),u=zr(i,c,l,s);if(!u)throw new Error(`No derivation found for resource ${En(i)} at (format=${e.format}, variant=${e.variant}). The class hierarchy declares no binding and no universal default applies.`);console.log(`Derivation: ${ts(u)} \u2192 ${jn(u.transformation)}`);let p=Qr(s,u.transformation);if(!p)throw new Error(`Transformation ${jn(u.transformation)} not found in the workspace or cache. The binding pointed at a transformation the resolver cannot locate.`);let m=Yr(e.format),k=await new qr().run({transformation:p,instances:[i],allKanonaks:s,repository:a,parser:o,objectParser:r,outputFormat:m}),d=Mr(e.out);Fr(d,{recursive:!0});let g=Jr[e.format]??"";for(let f of k){let y=os(f.fileName),b=Hr(d,`${y}${g}`);Ur(b,f.content,"utf-8"),console.log(` wrote ${b}`)}console.log(`Done. ${k.length} artifact(s) written to ${d}`)}function Zr(n,e){for(let t of n){if(!(t instanceof On)||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 Qr(n,e){let t=`${e.publisher}/${e.package_}@${e.version}`;for(let o of n)if(o instanceof On&&o.name===e.name&&o.namespace===t)return o}function es(n){if(n.includes("/")){let e=K(n);if(!e||!e.instanceName)throw new Error(`Invalid --format URI "${n}".`);return{publisher:e.publisher,package_:e.packageName,name:e.instanceName}}return{...Gr,name:n}}function ns(n){if(n.includes("/")){let e=K(n);if(!e||!e.instanceName)throw new Error(`Invalid --variant URI "${n}".`);return{publisher:e.publisher,package_:e.packageName,name:e.instanceName}}return{...Wr,name:n}}function En(n){return`${n.namespace}/${n.name}`}function jn(n){return`${n.publisher}/${n.package_}@${n.version}/${n.name}`}function ts(n){return n.source==="instance"?"instance override":`class ${n.source.publisher}/${n.source.package_}/${n.source.name}`}function os(n){return n.replace(/[^a-zA-Z0-9._@-]+/g,"_")}import{Command as Mn}from"commander";import{writeFileSync as xe,mkdirSync as ee}from"fs";import{join as Te,resolve as rs,dirname as Ae}from"path";import{KanonakParser as ss,KanonakObjectParser as as,SubjectKanonak as Vn,ReferenceStatement as is,ReferenceKanonak as cs,ListStatement as ls,StringStatement as Bn,EmbeddedStatement as us,findDerivation as Ln}from"@kanonak-protocol/sdk";import{SingleDocumentRepository as ps}from"@kanonak-protocol/sdk/uri-helpers";import{TransformationRunnerV3 as ds}from"@kanonak-protocol/sdk/transformations";import{findSubjectsByType as ne}from"@kanonak-protocol/sdk/uri-helpers";var x="kanonak.org",T="site",Un={publisher:"kanonak.org",package_:"formats",name:"html"},Fn={publisher:"kanonak.org",package_:"derivation",name:"default"};function zn(){let n=new Mn("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 Mn("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 fs(n)}catch(e){console.error(`Error: ${e.message}`),process.exit(1)}})}async function fs(n){let e=new ss,t=new as,o=await v(process.cwd(),e),r=await t.parseKanonaks(o),a=rs(n.out);ee(a,{recursive:!0});let s=await o.getAllDocumentsAsync(),i=new Set;for(let d of s){let g=d.metadata.namespace_?.toString();g&&i.add(g)}let c={publisher:x,package_:T,name:"StaticPage"},l={publisher:x,package_:T,name:"ResourcePage"},u={publisher:x,package_:T,name:"AggregateView"},p=ne(r,c).filter(d=>i.has(d.namespace||"")),m=ne(r,l).filter(d=>i.has(d.namespace||"")),h=ne(r,u).filter(d=>i.has(d.namespace||""));console.log(`Found ${p.length} StaticPage(s), ${m.length} ResourcePage(s), and ${h.length} AggregateView(s) in the workspace.`);let k=new ds;for(let d of p){let g=Ee(d,x,T,"outputPath")??`${d.name}.html`,f=Ln(d,Un,Fn,r);if(!f){console.warn(` [skip] ${d.name}: no HTML/default derivation found (check class hierarchy or universal-derivations is loaded)`);continue}let y=je(r,f.transformation);if(!y){console.warn(` [skip] ${d.name}: transformation ${Oe(f.transformation)} not found`);continue}let b=await k.run({transformation:y,instances:[d],allKanonaks:r,repository:o,parser:e,objectParser:t,outputFormat:"html"});if(b.length===0){console.warn(` [skip] ${d.name}: transformation produced no artifacts`);continue}let w=Te(a,g);ee(Ae(w),{recursive:!0}),xe(w,b[0].content,"utf-8"),console.log(` wrote ${w} (StaticPage ${d.name})`)}for(let d of m){let g=Ee(d,x,T,"outputPath")??`${d.name}.html`,f=Hn(d,x,T,"pageOf");if(!f){console.warn(` [skip] ${d.name}: no pageOf declared`);continue}let y=r.find(I=>I instanceof Vn&&I.name===f.name&&(I.namespace||"").startsWith(`${f.publisher}/${f.package_}@`));if(!y){console.warn(` [skip] ${d.name}: pageOf target ${f.publisher}/${f.package_}/${f.name} not found`);continue}let b=Ln(y,Un,Fn,r);if(!b){console.warn(` [skip] ${d.name}: no derivation for target ${y.name}`);continue}let w=je(r,b.transformation);if(!w){console.warn(` [skip] ${d.name}: transformation ${Oe(b.transformation)} not found`);continue}let $=await k.run({transformation:w,instances:[y],allKanonaks:r,repository:o,parser:e,objectParser:t,outputFormat:"html"});if($.length===0){console.warn(` [skip] ${d.name}: transformation produced no artifacts`);continue}let R=Te(a,g);ee(Ae(R),{recursive:!0}),xe(R,$[0].content,"utf-8"),console.log(` wrote ${R} (ResourcePage ${d.name} \u2192 ${y.name})`)}for(let d of h){let g=Ee(d,x,T,"outputPath");if(!g){console.warn(` [skip] ${d.name}: no outputPath declared`);continue}let f=Hn(d,x,T,"scopeClass");if(!f){console.warn(` [skip] ${d.name}: no scopeClass declared`);continue}let y={publisher:f.publisher,package_:f.package_,name:f.name},b=gs(d,x,T,"scopeSources"),w=hs(d);if(!w){console.warn(` [skip] ${d.name}: no transformation declared`);continue}let $=je(r,w);if(!$){console.warn(` [skip] ${d.name}: transformation ${Oe(w)} not found`);continue}let R=await ys(b,o),I=[],qe=new Set;for(let xt of R){let Tt=await bs(xt,o,e,t),At=ne(Tt,y);for(let he of At){let We=`${he.namespace}/${he.name}`;qe.has(We)||(qe.add(We),I.push(he))}}console.log(` ${d.name}: ${I.length} instance(s) of ${y.publisher}/${y.package_}/${y.name} across ${R.length} scope(s)`);let Ge=await k.run({transformation:$,instances:I,allKanonaks:r,repository:o,parser:e,objectParser:t,outputFormat:"html"});if(Ge.length===0){console.warn(` [skip] ${d.name}: transformation produced no artifacts`);continue}let ge=Te(a,g);ee(Ae(ge),{recursive:!0}),xe(ge,Ge[0].content,"utf-8"),console.log(` wrote ${ge} (AggregateView ${d.name})`)}console.log("Site build complete.")}function Ee(n,e,t,o){for(let r of n.statement)if(r instanceof Bn&&te(r,e,t,o))return r.object}function gs(n,e,t,o){for(let r of n.statement){if(!(r instanceof ls)||!te(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 Hn(n,e,t,o){for(let r of n.statement)if(r instanceof is&&te(r,e,t,o)&&r.object instanceof cs)return{publisher:r.object.subject.publisher,package_:r.object.subject.package_,name:r.object.subject.name}}function hs(n){for(let e of n.statement)if(e instanceof us&&te(e,x,T,"transformation"))return ks(e.object)}function ks(n){let e,t,o,r;for(let a of n.statement){if(!(a instanceof Bn))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 te(n,e,t,o){let r=n.predicate?.subject;return r?r.publisher===e&&r.package_===t&&r.name===o:!1}function je(n,e){let t=`${e.publisher}/${e.package_}@${e.version}`;for(let o of n)if(o instanceof Vn&&o.name===e.name&&o.namespace===t)return o}function Oe(n){return`${n.publisher}/${n.package_}@${n.version}/${n.name}`}async function ys(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 m=p.version;t.push(`${p.publisher}/${p.package_}@${m.major}.${m.minor}.${m.patch}`)}}return t}async function bs(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 m=new ps(u,e);return o.parseKanonaks(m)}}return[]}import{Command as ws}from"commander";import{KanonakParser as $s,PublisherIndex as qn,CredentialStore as Gn,createAuthenticatedFetch as Wn,FileSystemKanonakDocumentRepository as vs,Reasoner as Ps,KanonakVocabulary as Ss,getGlobalCachePath as Rs,makeUriKey as _s}from"@kanonak-protocol/sdk";function Cs(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 Jn(){return new ws("search").description("Browse a publisher's catalogue or find instances of a class via the SDK reasoner").argument("<publisher>","Publisher domain (e.g. kanonak.org)").option("--type <uri>","Class URI to search for, in publisher/package/Name form").action(async(n,e)=>{e.type?await Ds(n,e.type):await Is(n)})}async function Is(n){let e=new Gn,t=Wn(e),o=new qn({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}:
112
+ `);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 Ds(n,e){let t=Cs(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 $s,r=new Gn,a=Wn(r),s=new qn({fetchFn:a}),i=new D,c=new Set,l=[];try{l=await s.listLatestPackages(n)}catch(g){console.error(`Failed to fetch publisher index for ${n}: ${g.message}`),process.exit(1)}for(let{packageName:g,version:f}of l)c.add(`${n}|${g}|${f}`);await Ne(s,i,a,"kanonak.org","core-rdf",c),await Ne(s,i,a,"kanonak.org","core-owl",c),await Ne(s,i,a,t.publisher,t.package_,c);for(let g of c){let[f,y,b]=g.split("|");if(!i.has(f,y,b))try{let w=await s.getPackageUrl(f,y,b),$=await a(w,f);if(!$.ok){console.error(`Warning: failed to fetch ${f}/${y}@${b}: ${$.status} ${$.statusText}`);continue}let R=await $.text();i.put(f,y,b,R)}catch(w){console.error(`Warning: failed to fetch ${f}/${y}@${b}: ${w.message}`)}}let u=new vs(Rs(),!0,o),m=await new Ps({vocabulary:new Ss}).reason(u),h=_s(t.publisher,t.package_,t.name),d=m.getInstancesOfClass(h).filter(g=>g!==h);if(d.length===0){console.log(`No instances of ${h} found in ${n}'s catalogue.`);return}console.log(`Instances of ${h} in ${n}'s catalogue:
113
+ `),d.sort();for(let g of d)console.log(` ${g}`)}async function Ne(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 Ks,readFileSync as xs}from"fs";import{dirname as Ts,resolve as As}from"path";import{KanonakObjectParser as Es,KanonakParser as js,canonicalForm as Os,canonicalHash as Ns,parseKanonakAddress as Ls,pickHighestDocument as Us}from"@kanonak-protocol/sdk";import{SingleDocumentRepository as Fs}from"@kanonak-protocol/sdk/uri-helpers";async function Yn(n,e={}){let t=new js,o=new Es,{document:r,source:a}=await Hs(n,t),s=await v(Ms(a),t),i=new Fs(r,s),c=await o.parseKanonaks(i),l=Ns(c);if(console.log(l),e.verbose){let u=Os(c);process.stderr.write(`# canonical form for ${a}
114
+ `),process.stderr.write(u),process.stderr.write(`
115
+ `)}}async function Hs(n,e){if(n.endsWith(".kan.yml")){let i=As(n);if(!Ks(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=Ls(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 v(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=Us(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 Ms(n){return n.endsWith(".kan.yml")?j(Ts(n)):process.cwd()}import{Command as Xn}from"commander";function B(n){return`${P}/${S}/${n}`}var Le={[B("fetch-and-deploy")]:(n,e,t,o)=>n.add(e,t[0],o),[B("remove-deployed")]:(n,e,t,o)=>n.remove(e,t[0],o),[B("list-deployed")]:(n,e,t,o)=>n.list(e,o),[B("update-deployed")]:(n,e,t,o)=>n.update(e,t[0],o),[B("search-available")]:(n,e,t,o)=>n.search(e,o),[B("show-info")]:(n,e,t,o)=>n.info(e,t[0],o)};function Zn(n,e,t){for(let o of e){let r=new Xn(o.commandName).description(o.description.trim());for(let a of o.commands){let s=r.command(Vs(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=Bs(i);await zs(t,o,a,i,c)})}n.addCommand(r)}}function Vs(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 Xn))return n[e];return{}}async function zs(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(Le).join(", ")}.`),process.exit(1));let s=Le[t.actionKey];s||(console.error(`Capability subcommand '${t.subcommandName}' references unknown Action '${t.actionKey}'. Known actions: ${Object.keys(Le).join(", ")}.`),process.exit(1)),await s(n,e,a,r)}import{existsSync as Qn,readFileSync as qs,statSync as et}from"fs";import{resolve as Gs}from"path";import{KanonakObjectParser as Ws,PublisherIndex as Ue,PublisherConfigResolver as Js,formatVersion as nt,pickHighestDocument as Ys}from"@kanonak-protocol/sdk";import{SingleDocumentRepository as tt}from"@kanonak-protocol/sdk/uri-helpers";import{uriKey as z,findSubjectsByType as ot}from"@kanonak-protocol/sdk/uri-helpers";var oe=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 Ws;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=K(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 h=Ys(u,{requestedVersion:c??void 0});if(h.chosen){let k=h.chosen.metadata.namespace_;(!k||!k.version)&&(console.error(`Document for ${s}/${i} is missing namespace metadata.`),process.exit(1));let d=nt(k.version);this.fileCache.put(s,i,d,this.parser.save(h.chosen)),await this.deployFromDoc(e,h.chosen,s,i,d,l??void 0,`${s}/${i}@${d}`,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 m=this.fileCache.get(s,i,p);if(!m){let h=await this.publisherIndex.getPackageUrl(s,i,p),k=await this.fetchFn(h,s);k.ok||(k.status===404?(console.error(`Package ${s}/${i}@${p} not found at ${h}.`),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 ${h} (${k.status} ${k.statusText}).`),process.exit(1)),m=await k.text(),this.fileCache.put(s,i,p,m)}await this.deployFromDoc(e,this.parser.parse(m),s,i,p,l??void 0,`${s}/${i}@${p}`,o)}tryLoadFromLocalFile(e){if(!(/^[.\/\\]/.test(e)||/^[A-Za-z]:[\\/]/.test(e)||e.endsWith(".kan.yml")||Qn(e)&&et(e).isFile()))return;let o=Gs(e);(!Qn(o)||!et(o).isFile())&&(console.error(`Local file not found: ${e}`),process.exit(1));let r=qs(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:nt(s.version)}}async deployFromDoc(e,t,o,r,a,s,i,c){let l=new tt(t,this.repository),u=await this.objectParser.parseKanonaks(l),p=rt(e.managesTypeKey);p||(console.error(`Capability "${e.commandName}" has no resolved managesType.`),process.exit(1));let m=ot(u,p);m.length===0&&(console.error(`${i} does not contain any ${z(p)} instances.`),process.exit(1));let h=m;if(s&&(h=m.filter(g=>g.name===s),h.length===0)){console.error(`Instance "${s}" not found in ${i}.`),console.error(""),console.error(`Available ${z(p)} instance(s):`);for(let g of m)console.error(` - ${g.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 k=s?`${s} from ${i}`:`${h.length} ${z(p)} instance(s) from ${i}`;console.log(`Installing ${k}...`);let d=this.handlerRegistry.get(e.deploymentTargetKey);d?await d.deploy({instances:h,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:Xs(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:
114
116
  `);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.":`
115
- Updated ${i} instance(s).`)}async search(e,t){let o=t.publisher??"kanonak.org",r=ot(e.managesTypeKey);if(!r){console.error("Capability has no resolved managesType; nothing to search for.");return}console.log(`Searching ${o} for ${B(r)} instances...
116
- `);let a=new js,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(),p=Ue.parseIndex(l);if(p.size===0){console.error(`No packages found for publisher "${o}".`);return}let u=new Map;for(let[d,g]of p){let f=[...g].sort((y,b)=>{let w=Ue.parseVersion(y),$=Ue.parseVersion(b);return!w||!$?0:w.major!==$.major?$.major-w.major:w.minor!==$.minor?$.minor-w.minor:$.patch-w.patch});u.set(d,f[0])}let m=[],h=0;for(let[d,g]of u){let f=this.fileCache.get(o,d,g);if(!f)try{let y=await this.publisherIndex.getPackageUrl(o,d,g),b=await this.fetchFn(y,o);if(!b.ok)continue;f=await b.text(),this.fileCache.put(o,d,g,f)}catch{continue}try{let y=this.parser.parse(f),b=new nt(y,this.repository),w=await this.objectParser.parseKanonaks(b),$=tt(w,r);for(let S of $)m.push({publisher:o,package_:d,version:g,subject:S});h++}catch{continue}}if(m.length===0){console.log(`No ${B(r)} instances found across ${h} package(s).`);return}console.log(`Found ${m.length} ${B(r)} instance(s) in ${h} package(s):
117
- `);let k=new Map;for(let d of m){let g=`${d.publisher}/${d.package_}@${d.version}`,f=k.get(g);f?f.push(d):k.set(g,[d])}for(let[d,g]of k){let f=g[0],y=`${f.publisher}/${f.package_}`,b=g.length===1;console.log(` ${d}`),console.log(` ${g.length} skill${b?"":"s"}:`);for(let w of g)console.log(` - ${w.subject.name}`);if(console.log(""),b)console.log(" install:"),console.log(` kanonak ${e.commandName} add ${y}/${f.subject.name}`);else{console.log(" install one of them:");for(let w of g)console.log(` kanonak ${e.commandName} add ${y}/${w.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 ot(n){if(!n)return;let e=n.split("/");if(e.length===3)return{publisher:e[0],package_:e[1],name:e[2]}}function Ns(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=Ls(t,o);return i===0?100:i<=2?Math.max(1,20-i*5):0}function Ls(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 re=class{handlers=new Map;register(e,t){this.handlers.set(e,t)}get(e){return this.handlers.get(e)??null}};import{mkdirSync as Ys,rmSync as Xs,existsSync as ce,readdirSync as Zs,writeFileSync as Qs}from"fs";import{join as le}from"path";import{KanonakObjectParser as ea,KanonakParser as na,computeIntegrity as ta,compareVersions as oa}from"@kanonak-protocol/sdk";import{findSubjectsByType as ra}from"@kanonak-protocol/sdk/uri-helpers";import{SingleDocumentRepository as sa}from"@kanonak-protocol/sdk/uri-helpers";import{TransformationRunnerV3 as aa}from"@kanonak-protocol/sdk/transformations";import{TX_V3 as ia}from"@kanonak-protocol/sdk/transformations";import{join as Fe}from"path";import{homedir as rt}from"os";import{KanonakObjectParser as Us}from"@kanonak-protocol/sdk";import{SingleDocumentRepository as Fs}from"@kanonak-protocol/sdk/uri-helpers";import{findSubjectsByType as at,getStringValue as se}from"@kanonak-protocol/sdk/uri-helpers";var j="kanonak.org",O="agent-skills",it={publisher:j,package_:O,name:"Client"},ct={publisher:j,package_:O,name:"clientId"},Hs={publisher:j,package_:O,name:"projectSkillDir"},Ms={publisher:j,package_:O,name:"userSkillDir"},Vs={publisher:j,package_:O,name:"skillFileName"},lt="agents";async function Y(n,e){let t=(n.client??ut()??lt).toLowerCase(),o=n.scope??"project",r=await dt(t,e);if(!r){let i=await Bs(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=se(r,o==="user"?Ms:Hs);if(!s)throw new Error(`Client "${t}" has no ${o==="user"?"userSkillDir":"projectSkillDir"} declared.`);return zs(s)}async function ae(n,e,t){let o=await Y(e,t);return Fe(o,n)}async function He(n,e){let t=(n.client??ut()??lt).toLowerCase(),o=await dt(t,e);return o?se(o,Vs)??"SKILL.md":"SKILL.md"}function ut(){if(process.env.CLAUDE_CODE||process.env.CLAUDE_PROJECT_DIR)return"claude-code"}var st=new WeakMap;async function pt(n){let e=st.get(n);if(e)return e;let t=await n.getDocumentsByNamespaceAsync(j,O);if(t.length===0)throw new Error(`Could not find ${j}/${O} 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 p=c.metadata.namespace_?.version,u=l.metadata.namespace_?.version;return!p||!u?0:p.major!==u.major?u.major-p.major:p.minor!==u.minor?u.minor-p.minor:u.patch-p.patch})[0],a=new Us,s=new Fs(r,n),i=await a.parseKanonaks(s);return st.set(n,i),i}async function dt(n,e){let t=await pt(e),o=at(t,it);for(let r of o)if(se(r,ct)===n)return r}async function Bs(n){let e=await pt(n),t=at(e,it),o=[];for(let r of t){let a=se(r,ct);a&&o.push(a)}return o}function zs(n){return n.startsWith("~/")?Fe(rt(),n.slice(2)):n==="~"?rt():n.startsWith("/")||/^[A-Za-z]:[\\/]/.test(n)?n:Fe(process.cwd(),n)}import{readFileSync as Gs,writeFileSync as qs,existsSync as Ws}from"fs";import{join as mt}from"path";import ft from"js-yaml";var gt="skills.lock",Js=`# This file is generated by Kanonak CLI. Do not edit manually.
118
- `;function ie(n){let e=mt(n,gt);if(!Ws(e))return{version:"1",lastUpdated:new Date().toISOString(),skills:{}};let t=Gs(e,"utf-8"),o=ft.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 Me(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=mt(n,gt),r=ft.dump(e,{lineWidth:-1,sortKeys:!1,quotingType:'"'});qs(o,Js+r,"utf-8")}var ht="kanonak.org",kt="skill-to-skill-md",ue=class{parser=new na;objectParser=new ea;runner=new aa;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 ca(r,this.objectParser);if(!s){console.error(`Cannot deploy: ${ht}/${kt}@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 Y(a,r),l=await He(a,r),p=ie(c),u=t[0].namespace,{publisher:m,package_:h,version:k}=la(u);for(let d of i){let g=await ae(d.fileName,a,r),f=ce(le(g,l));Ys(g,{recursive:!0}),Qs(le(g,l),d.content,"utf-8"),p.skills[d.fileName]={publisher:m,package_:h,version:k,resolved:m?`kanonak://${m}/${h}@${k}`:"",integrity:ta(d.content)},console.log(` ${f?"Updated":"Installed"} skill "${d.fileName}" \u2192 ${g}`)}Me(c,p)}async undeploy(e,t){let{repository:o,options:r}=t,a=await ae(e,r,o);ce(a)||(console.error(`Skill "${e}" is not installed at ${a}`),process.exit(1)),Xs(a,{recursive:!0,force:!0});let s=await Y(r,o),i=ie(s);delete i.skills[e],Me(s,i),console.log(`Removed skill "${e}" from ${a}`)}async list(e){let{repository:t,options:o}=e,r=await Y(o,t),a=ie(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 ae(c,o,t)});let i=await He(o,t);if(ce(r))try{let c=Zs(r,{withFileTypes:!0});for(let l of c){if(!l.isDirectory()||a.skills[l.name])continue;let p=le(r,l.name,i);ce(p)&&s.push({name:l.name,publisher:"",package_:"",version:"",path:le(r,l.name)})}}catch{}return s}};async function ca(n,e){let t=await n.getDocumentsByNamespaceAsync(ht,kt);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:oa(i,s)});for(let r of o){let a=new sa(r,n),s=await e.parseKanonaks(a),i=ra(s,ia.InstanceTransformation);if(i[0])return i[0]}}function la(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 Ra,rmSync as _a,existsSync as ze,readdirSync as Ca,writeFileSync as Ia,statSync as Da}from"fs";import{join as me}from"path";import{KanonakObjectParser as Ka,KanonakParser as xa,computeIntegrity as Ta}from"@kanonak-protocol/sdk";import{findSubjectsByType as Aa}from"@kanonak-protocol/sdk/uri-helpers";import{SingleDocumentRepository as Ea}from"@kanonak-protocol/sdk/uri-helpers";import{TransformationRunnerV3 as ja}from"@kanonak-protocol/sdk/transformations";import{TX_V3 as Oa}from"@kanonak-protocol/sdk/transformations";import{join as yt}from"path";import{homedir as bt}from"os";import{KanonakObjectParser as ua}from"@kanonak-protocol/sdk";import{SingleDocumentRepository as pa}from"@kanonak-protocol/sdk/uri-helpers";import{findSubjectsByType as $t,getStringValue as Ve,getReferenceUri as da}from"@kanonak-protocol/sdk/uri-helpers";var N="kanonak.org",L="agent-skills",vt={publisher:N,package_:L,name:"Client"},Pt={publisher:N,package_:L,name:"clientId"},ma={publisher:N,package_:L,name:"projectAgentDir"},fa={publisher:N,package_:L,name:"userAgentDir"},ga={publisher:N,package_:L,name:"agentFileFormat"},ha="agents";function ka(){if(process.env.CLAUDE_CODE||process.env.CLAUDE_PROJECT_DIR)return"claude-code"}async function pe(n,e){let t=(n.client??ka()??ha).toLowerCase(),o=n.scope??"project",r=await ya(t,e);if(!r){let p=await ba(e);throw new Error(`Unknown client "${t}". Known clients: ${p.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=Ve(r,o==="user"?fa:ma);if(!s)throw new Error(`Client "${t}" has no ${o==="user"?"userAgentDir":"projectAgentDir"} declared.`);let c=da(r,ga)?.name==="toml"?"toml":"markdown-frontmatter",l=c==="toml"?".toml":".md";return{agentsDir:wa(s),format:c,fileExtension:l}}var wt=new WeakMap;async function St(n){let e=wt.get(n);if(e)return e;let t=await n.getDocumentsByNamespaceAsync(N,L);if(t.length===0)throw new Error(`Could not find ${N}/${L} in the repository. Install a capability that imports agent-skills to populate the cache.`);let r=[...t].sort((c,l)=>{let p=c.metadata.namespace_?.version,u=l.metadata.namespace_?.version;return!p||!u?0:p.major!==u.major?u.major-p.major:p.minor!==u.minor?u.minor-p.minor:u.patch-p.patch})[0],a=new ua,s=new pa(r,n),i=await a.parseKanonaks(s);return wt.set(n,i),i}async function ya(n,e){let t=await St(e),o=$t(t,vt);for(let r of o)if(Ve(r,Pt)===n)return r}async function ba(n){let e=await St(n),t=$t(e,vt),o=[];for(let r of t){let a=Ve(r,Pt);a&&o.push(a)}return o}function wa(n){return n.startsWith("~/")?yt(bt(),n.slice(2)):n==="~"?bt():n.startsWith("/")||/^[A-Za-z]:[\\/]/.test(n)?n:yt(process.cwd(),n)}import{readFileSync as $a,writeFileSync as va,existsSync as Pa}from"fs";import{join as Rt}from"path";import _t from"js-yaml";var Ct="agents.lock",Sa=`# This file is generated by Kanonak CLI. Do not edit manually.
119
- `;function de(n){let e=Rt(n,Ct);if(!Pa(e))return{version:"1",lastUpdated:new Date().toISOString(),agents:{}};let t=$a(e,"utf-8"),o=_t.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 Be(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=Rt(n,Ct),r=_t.dump(e,{lineWidth:-1,sortKeys:!1,quotingType:'"'});va(o,Sa+r,"utf-8")}var It="kanonak.org",Dt="agent-to-agent-file",fe=class{parser=new xa;objectParser=new Ka;runner=new ja;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 pe(a,r),l=await Na(r,this.objectParser);if(!l){console.error(`Cannot deploy: ${It}/${Dt}@3.0.0 is not installed in the workspace or cache.`);return}let p=i==="toml"?"toml":"markdown-with-frontmatter",u=await this.runner.run({transformation:l,instances:t,allKanonaks:o,repository:r,parser:this.parser,objectParser:this.objectParser,outputFormat:p});if(u.length===0){console.error("No agents could be transformed from the package.");return}Ra(s,{recursive:!0});let m=de(s),h=t[0].namespace,{publisher:k,package_:d,version:g}=Ua(h);for(let f of u){let y=`${f.fileName}${c}`,b=me(s,y),w=ze(b);Ia(b,f.content,"utf-8"),m.agents[f.fileName]={publisher:k,package_:d,version:g,resolved:k?`kanonak://${k}/${d}@${g}`:"",integrity:Ta(f.content),fileName:y},console.log(` ${w?"Updated":"Installed"} agent "${f.fileName}" \u2192 ${b}`)}Be(s,m)}async undeploy(e,t){let{repository:o,options:r}=t,{agentsDir:a}=await pe(r,o),s=de(a),i=s.agents[e];i||(console.error(`Agent "${e}" is not installed at ${a}`),process.exit(1));let c=me(a,i.fileName);ze(c)&&_a(c,{force:!0}),delete s.agents[e],Be(a,s),console.log(`Removed agent "${e}" from ${c}`)}async list(e){let{repository:t,options:o}=e,{agentsDir:r}=await pe(o,t),a=de(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:me(r,c.fileName)});if(ze(r))try{let i=Ca(r,{withFileTypes:!0});for(let c of i){if(!c.isFile()||c.name==="agents.lock")continue;let l=me(r,c.name),p=La(c.name);if(!a.agents[p]){try{if(!Da(l).isFile())continue}catch{continue}s.push({name:p,publisher:"",package_:"",version:"",path:l})}}}catch{}return s}};async function Na(n,e){let t=await n.getDocumentsByNamespaceAsync(It,Dt);if(t.length===0)return;let o=new Ea(t[0],n),r=await e.parseKanonaks(o);return Aa(r,Oa.InstanceTransformation)[0]}function La(n){let e=n.lastIndexOf(".");return e===-1?n:n.substring(0,e)}function Ua(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 Ja=Va(Ma(import.meta.url)),Ya=JSON.parse(Ha(Ba(Ja,"..","package.json"),"utf-8")),C=new Fa;C.name("kanonak").description("Kanonak Protocol CLI - Validate and resolve Kanonak ontology packages").version(Ya.version);C.command("validate <path>").description("Validate .kan.yml file(s). Resolves imports via HTTP from publisher domains.").action(async n=>{await Qe(n)});C.command("install [package]").description("Install a package and its dependencies, or install all from kanonak.lock.").action(async n=>{await en(n)});C.command("deps <path>").description("Show resolved dependency tree for a .kan.yml file.").action(async n=>{await tn(n)});C.command("login <publisher>").description("Authenticate with a package publisher using OAuth 2.0.").action(async n=>{await cn(n)});C.command("logout <publisher>").description("Revoke tokens and remove stored credentials for a publisher.").action(async n=>{await ln(n)});C.addCommand(Sn());C.addCommand(xn());C.addCommand(Nn());C.addCommand(zn());C.addCommand(Jn());async function Xa(){try{let n=new D,e=new za,t=new qa,o=Wa(t),r=new Ga({fetchFn:o}),a=await R(process.cwd(),e),s=new re;s.register("kanonak.org/capabilities/agent-skill-deployment",new ue),s.register("kanonak.org/agent-capabilities/agent-instance-deployment",new fe);let i=await $n(n,e,a),c=new oe(n,e,r,o,s,a);Xn(C,i,c)}catch{}}await Xa();C.parse();
117
+ Updated ${i} instance(s).`)}async search(e,t){let o=t.publisher??"kanonak.org",r=rt(e.managesTypeKey);if(!r){console.error("Capability has no resolved managesType; nothing to search for.");return}console.log(`Searching ${o} for ${z(r)} instances...
118
+ `);let a=new Js,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=Ue.parseIndex(l);if(u.size===0){console.error(`No packages found for publisher "${o}".`);return}let p=new Map;for(let[d,g]of u){let f=[...g].sort((y,b)=>{let w=Ue.parseVersion(y),$=Ue.parseVersion(b);return!w||!$?0:w.major!==$.major?$.major-w.major:w.minor!==$.minor?$.minor-w.minor:$.patch-w.patch});p.set(d,f[0])}let m=[],h=0;for(let[d,g]of p){let f=this.fileCache.get(o,d,g);if(!f)try{let y=await this.publisherIndex.getPackageUrl(o,d,g),b=await this.fetchFn(y,o);if(!b.ok)continue;f=await b.text(),this.fileCache.put(o,d,g,f)}catch{continue}try{let y=this.parser.parse(f),b=new tt(y,this.repository),w=await this.objectParser.parseKanonaks(b),$=ot(w,r);for(let R of $)m.push({publisher:o,package_:d,version:g,subject:R});h++}catch{continue}}if(m.length===0){console.log(`No ${z(r)} instances found across ${h} package(s).`);return}console.log(`Found ${m.length} ${z(r)} instance(s) in ${h} package(s):
119
+ `);let k=new Map;for(let d of m){let g=`${d.publisher}/${d.package_}@${d.version}`,f=k.get(g);f?f.push(d):k.set(g,[d])}for(let[d,g]of k){let f=g[0],y=`${f.publisher}/${f.package_}`,b=g.length===1;console.log(` ${d}`),console.log(` ${g.length} skill${b?"":"s"}:`);for(let w of g)console.log(` - ${w.subject.name}`);if(console.log(""),b)console.log(" install:"),console.log(` kanonak ${e.commandName} add ${y}/${f.subject.name}`);else{console.log(" install one of them:");for(let w of g)console.log(` kanonak ${e.commandName} add ${y}/${w.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 rt(n){if(!n)return;let e=n.split("/");if(e.length===3)return{publisher:e[0],package_:e[1],name:e[2]}}function Xs(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=Zs(t,o);return i===0?100:i<=2?Math.max(1,20-i*5):0}function Zs(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 re=class{handlers=new Map;register(e,t){this.handlers.set(e,t)}get(e){return this.handlers.get(e)??null}};import{mkdirSync as ua,rmSync as pa,existsSync as ce,readdirSync as da,writeFileSync as ma}from"fs";import{join as le}from"path";import{KanonakObjectParser as fa,KanonakParser as ga,computeIntegrity as ha,compareVersions as ka}from"@kanonak-protocol/sdk";import{findSubjectsByType as ya}from"@kanonak-protocol/sdk/uri-helpers";import{SingleDocumentRepository as ba}from"@kanonak-protocol/sdk/uri-helpers";import{TransformationRunnerV3 as wa}from"@kanonak-protocol/sdk/transformations";import{TX_V3 as $a}from"@kanonak-protocol/sdk/transformations";import{join as Fe}from"path";import{homedir as st}from"os";import{KanonakObjectParser as Qs}from"@kanonak-protocol/sdk";import{SingleDocumentRepository as ea}from"@kanonak-protocol/sdk/uri-helpers";import{findSubjectsByType as it,getStringValue as se}from"@kanonak-protocol/sdk/uri-helpers";var O="kanonak.org",N="agent-skills",ct={publisher:O,package_:N,name:"Client"},lt={publisher:O,package_:N,name:"clientId"},na={publisher:O,package_:N,name:"projectSkillDir"},ta={publisher:O,package_:N,name:"userSkillDir"},oa={publisher:O,package_:N,name:"skillFileName"},ut="agents";async function Y(n,e){let t=(n.client??pt()??ut).toLowerCase(),o=n.scope??"project",r=await mt(t,e);if(!r){let i=await ra(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=se(r,o==="user"?ta:na);if(!s)throw new Error(`Client "${t}" has no ${o==="user"?"userSkillDir":"projectSkillDir"} declared.`);return sa(s)}async function ae(n,e,t){let o=await Y(e,t);return Fe(o,n)}async function He(n,e){let t=(n.client??pt()??ut).toLowerCase(),o=await mt(t,e);return o?se(o,oa)??"SKILL.md":"SKILL.md"}function pt(){if(process.env.CLAUDE_CODE||process.env.CLAUDE_PROJECT_DIR)return"claude-code"}var at=new WeakMap;async function dt(n){let e=at.get(n);if(e)return e;let t=await n.getDocumentsByNamespaceAsync(O,N);if(t.length===0)throw new Error(`Could not find ${O}/${N} 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 Qs,s=new ea(r,n),i=await a.parseKanonaks(s);return at.set(n,i),i}async function mt(n,e){let t=await dt(e),o=it(t,ct);for(let r of o)if(se(r,lt)===n)return r}async function ra(n){let e=await dt(n),t=it(e,ct),o=[];for(let r of t){let a=se(r,lt);a&&o.push(a)}return o}function sa(n){return n.startsWith("~/")?Fe(st(),n.slice(2)):n==="~"?st():n.startsWith("/")||/^[A-Za-z]:[\\/]/.test(n)?n:Fe(process.cwd(),n)}import{readFileSync as aa,writeFileSync as ia,existsSync as ca}from"fs";import{join as ft}from"path";import gt from"js-yaml";var ht="skills.lock",la=`# This file is generated by Kanonak CLI. Do not edit manually.
120
+ `;function ie(n){let e=ft(n,ht);if(!ca(e))return{version:"1",lastUpdated:new Date().toISOString(),skills:{}};let t=aa(e,"utf-8"),o=gt.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 Me(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=ft(n,ht),r=gt.dump(e,{lineWidth:-1,sortKeys:!1,quotingType:'"'});ia(o,la+r,"utf-8")}var kt="kanonak.org",yt="skill-to-skill-md",ue=class{parser=new ga;objectParser=new fa;runner=new wa;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 va(r,this.objectParser);if(!s){console.error(`Cannot deploy: ${kt}/${yt}@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 Y(a,r),l=await He(a,r),u=ie(c),p=t[0].namespace,{publisher:m,package_:h,version:k}=Pa(p);for(let d of i){let g=await ae(d.fileName,a,r),f=ce(le(g,l));ua(g,{recursive:!0}),ma(le(g,l),d.content,"utf-8"),u.skills[d.fileName]={publisher:m,package_:h,version:k,resolved:m?`kanonak://${m}/${h}@${k}`:"",integrity:ha(d.content)},console.log(` ${f?"Updated":"Installed"} skill "${d.fileName}" \u2192 ${g}`)}Me(c,u)}async undeploy(e,t){let{repository:o,options:r}=t,a=await ae(e,r,o);ce(a)||(console.error(`Skill "${e}" is not installed at ${a}`),process.exit(1)),pa(a,{recursive:!0,force:!0});let s=await Y(r,o),i=ie(s);delete i.skills[e],Me(s,i),console.log(`Removed skill "${e}" from ${a}`)}async list(e){let{repository:t,options:o}=e,r=await Y(o,t),a=ie(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 ae(c,o,t)});let i=await He(o,t);if(ce(r))try{let c=da(r,{withFileTypes:!0});for(let l of c){if(!l.isDirectory()||a.skills[l.name])continue;let u=le(r,l.name,i);ce(u)&&s.push({name:l.name,publisher:"",package_:"",version:"",path:le(r,l.name)})}}catch{}return s}};async function va(n,e){let t=await n.getDocumentsByNamespaceAsync(kt,yt);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:ka(i,s)});for(let r of o){let a=new ba(r,n),s=await e.parseKanonaks(a),i=ya(s,$a.InstanceTransformation);if(i[0])return i[0]}}function Pa(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 Ua,rmSync as Fa,existsSync as ze,readdirSync as Ha,writeFileSync as Ma,statSync as Va}from"fs";import{join as me}from"path";import{KanonakObjectParser as Ba,KanonakParser as za,computeIntegrity as qa}from"@kanonak-protocol/sdk";import{findSubjectsByType as Ga}from"@kanonak-protocol/sdk/uri-helpers";import{SingleDocumentRepository as Wa}from"@kanonak-protocol/sdk/uri-helpers";import{TransformationRunnerV3 as Ja}from"@kanonak-protocol/sdk/transformations";import{TX_V3 as Ya}from"@kanonak-protocol/sdk/transformations";import{join as bt}from"path";import{homedir as wt}from"os";import{KanonakObjectParser as Sa}from"@kanonak-protocol/sdk";import{SingleDocumentRepository as Ra}from"@kanonak-protocol/sdk/uri-helpers";import{findSubjectsByType as vt,getStringValue as Ve,getReferenceUri as _a}from"@kanonak-protocol/sdk/uri-helpers";var L="kanonak.org",U="agent-skills",Pt={publisher:L,package_:U,name:"Client"},St={publisher:L,package_:U,name:"clientId"},Ca={publisher:L,package_:U,name:"projectAgentDir"},Ia={publisher:L,package_:U,name:"userAgentDir"},Da={publisher:L,package_:U,name:"agentFileFormat"},Ka="agents";function xa(){if(process.env.CLAUDE_CODE||process.env.CLAUDE_PROJECT_DIR)return"claude-code"}async function pe(n,e){let t=(n.client??xa()??Ka).toLowerCase(),o=n.scope??"project",r=await Ta(t,e);if(!r){let u=await Aa(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=Ve(r,o==="user"?Ia:Ca);if(!s)throw new Error(`Client "${t}" has no ${o==="user"?"userAgentDir":"projectAgentDir"} declared.`);let c=_a(r,Da)?.name==="toml"?"toml":"markdown-frontmatter",l=c==="toml"?".toml":".md";return{agentsDir:Ea(s),format:c,fileExtension:l}}var $t=new WeakMap;async function Rt(n){let e=$t.get(n);if(e)return e;let t=await n.getDocumentsByNamespaceAsync(L,U);if(t.length===0)throw new Error(`Could not find ${L}/${U} 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 Sa,s=new Ra(r,n),i=await a.parseKanonaks(s);return $t.set(n,i),i}async function Ta(n,e){let t=await Rt(e),o=vt(t,Pt);for(let r of o)if(Ve(r,St)===n)return r}async function Aa(n){let e=await Rt(n),t=vt(e,Pt),o=[];for(let r of t){let a=Ve(r,St);a&&o.push(a)}return o}function Ea(n){return n.startsWith("~/")?bt(wt(),n.slice(2)):n==="~"?wt():n.startsWith("/")||/^[A-Za-z]:[\\/]/.test(n)?n:bt(process.cwd(),n)}import{readFileSync as ja,writeFileSync as Oa,existsSync as Na}from"fs";import{join as _t}from"path";import Ct from"js-yaml";var It="agents.lock",La=`# This file is generated by Kanonak CLI. Do not edit manually.
121
+ `;function de(n){let e=_t(n,It);if(!Na(e))return{version:"1",lastUpdated:new Date().toISOString(),agents:{}};let t=ja(e,"utf-8"),o=Ct.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 Be(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=_t(n,It),r=Ct.dump(e,{lineWidth:-1,sortKeys:!1,quotingType:'"'});Oa(o,La+r,"utf-8")}var Dt="kanonak.org",Kt="agent-to-agent-file",fe=class{parser=new za;objectParser=new Ba;runner=new Ja;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 pe(a,r),l=await Xa(r,this.objectParser);if(!l){console.error(`Cannot deploy: ${Dt}/${Kt}@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}Ua(s,{recursive:!0});let m=de(s),h=t[0].namespace,{publisher:k,package_:d,version:g}=Qa(h);for(let f of p){let y=`${f.fileName}${c}`,b=me(s,y),w=ze(b);Ma(b,f.content,"utf-8"),m.agents[f.fileName]={publisher:k,package_:d,version:g,resolved:k?`kanonak://${k}/${d}@${g}`:"",integrity:qa(f.content),fileName:y},console.log(` ${w?"Updated":"Installed"} agent "${f.fileName}" \u2192 ${b}`)}Be(s,m)}async undeploy(e,t){let{repository:o,options:r}=t,{agentsDir:a}=await pe(r,o),s=de(a),i=s.agents[e];i||(console.error(`Agent "${e}" is not installed at ${a}`),process.exit(1));let c=me(a,i.fileName);ze(c)&&Fa(c,{force:!0}),delete s.agents[e],Be(a,s),console.log(`Removed agent "${e}" from ${c}`)}async list(e){let{repository:t,options:o}=e,{agentsDir:r}=await pe(o,t),a=de(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:me(r,c.fileName)});if(ze(r))try{let i=Ha(r,{withFileTypes:!0});for(let c of i){if(!c.isFile()||c.name==="agents.lock")continue;let l=me(r,c.name),u=Za(c.name);if(!a.agents[u]){try{if(!Va(l).isFile())continue}catch{continue}s.push({name:u,publisher:"",package_:"",version:"",path:l})}}}catch{}return s}};async function Xa(n,e){let t=await n.getDocumentsByNamespaceAsync(Dt,Kt);if(t.length===0)return;let o=new Wa(t[0],n),r=await e.parseKanonaks(o);return Ga(r,Ya.InstanceTransformation)[0]}function Za(n){let e=n.lastIndexOf(".");return e===-1?n:n.substring(0,e)}function Qa(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 li=oi(ti(import.meta.url)),ui=JSON.parse(ni(ri(li,"..","package.json"),"utf-8")),C=new ei;C.name("kanonak").description("Kanonak Protocol CLI - Validate and resolve Kanonak ontology packages").version(ui.version);C.command("validate <path>").description("Validate .kan.yml file(s). Resolves imports via HTTP from publisher domains.").action(async n=>{await Qe(n)});C.command("install [package]").description("Install a package and its dependencies, or install all from kanonak.lock.").action(async n=>{await en(n)});C.command("deps <path>").description("Show resolved dependency tree for a .kan.yml file.").action(async n=>{await tn(n)});C.command("login <publisher>").description("Authenticate with a package publisher using OAuth 2.0.").action(async n=>{await cn(n)});C.command("logout <publisher>").description("Revoke tokens and remove stored credentials for a publisher.").action(async n=>{await ln(n)});C.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 Yn(n,e)});C.addCommand(Sn());C.addCommand(xn());C.addCommand(Nn());C.addCommand(zn());C.addCommand(Jn());async function pi(){try{let n=new D,e=new si,t=new ii,o=ci(t),r=new ai({fetchFn:o}),a=await v(process.cwd(),e),s=new re;s.register("kanonak.org/capabilities/agent-skill-deployment",new ue),s.register("kanonak.org/agent-capabilities/agent-instance-deployment",new fe);let i=await $n(n,e,a),c=new oe(n,e,r,o,s,a);Zn(C,i,c)}catch{}}await pi();C.parse();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kanonak-protocol/cli",
3
- "version": "3.18.0",
3
+ "version": "3.20.0",
4
4
  "description": "Kanonak Protocol CLI - Validate and resolve Kanonak ontology packages",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -34,8 +34,8 @@
34
34
  "semantic-web"
35
35
  ],
36
36
  "dependencies": {
37
- "@kanonak-protocol/sdk": "^3.18.0",
38
- "@kanonak-protocol/types": "^3.18.0",
37
+ "@kanonak-protocol/sdk": "^3.20.0",
38
+ "@kanonak-protocol/types": "^3.20.0",
39
39
  "commander": "^13.0.0",
40
40
  "js-yaml": "^4.1.1"
41
41
  },