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