@kanonak-protocol/cli 1.6.0 → 1.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `kanonak transform` command group.
|
|
3
|
+
*
|
|
4
|
+
* User-facing entry point to the declarative transformation runner
|
|
5
|
+
* — run, list, show, and formats subcommands. Everything here is a
|
|
6
|
+
* thin wrapper around TransformationRunner; no runtime logic lives
|
|
7
|
+
* in the CLI layer.
|
|
8
|
+
*/
|
|
9
|
+
import { Command } from 'commander';
|
|
10
|
+
export declare function transformCommand(): Command;
|
package/dist/index.js
CHANGED
|
@@ -1,103 +1,99 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import{Command as
|
|
3
|
-
`).some(o=>o.trim()===
|
|
4
|
-
${
|
|
5
|
-
`)}else
|
|
6
|
-
`)}getPath(e,
|
|
7
|
-
${u}:`);for(let
|
|
8
|
-
${u}:`),console.log(" ERROR: Failed to parse document"),
|
|
9
|
-
${
|
|
10
|
-
${c.length} file(s) validated. ${
|
|
11
|
-
`;function
|
|
12
|
-
Installed ${Object.keys(
|
|
13
|
-
Installed ${m.size} package(s).`)}async function
|
|
2
|
+
import{Command as Ss}from"commander";import{readFileSync as $s}from"fs";import{fileURLToPath as vs}from"url";import{dirname as Ds,join as As}from"path";import{KanonakParser as Cs,PublisherIndex as Ks,CredentialStore as Ps,createAuthenticatedFetch as Es}from"@kanonak-protocol/sdk";import{readFileSync as qt,statSync as Gt}from"fs";import{resolve as Wt,dirname as Xt}from"path";import{KanonakParser as Jt,KanonakObjectValidator as Yt,ValidationSeverity as mn}from"@kanonak-protocol/sdk";import{readFileSync as Lt,readdirSync as Nt}from"fs";import{join as Ft,dirname as Mt,basename as pn}from"path";import{InMemoryKanonakDocumentRepository as Bt,FileSystemKanonakDocumentRepository as Vt,HttpKanonakDocumentRepository as Ht,getGlobalCachePath as zt}from"@kanonak-protocol/sdk";import{mkdirSync as It,readFileSync as un,writeFileSync as dn,existsSync as Fe,appendFileSync as Tt}from"fs";import{join as jt,dirname as xt,isAbsolute as Ut}from"path";import{getGlobalCachePath as Ot}from"@kanonak-protocol/sdk";var U=class{constructor(e=Ot()){this.cacheDir=e;this.isProjectLocal=!Ut(e)}cacheDir;gitignoreChecked=!1;isProjectLocal;get(e,t,r){let o=this.getPath(e,t,r);return Fe(o)?un(o,"utf-8"):null}put(e,t,r,o){let a=this.getPath(e,t,r);It(xt(a),{recursive:!0}),dn(a,o,"utf-8"),this.isProjectLocal&&this.ensureGitignore()}has(e,t,r){return Fe(this.getPath(e,t,r))}ensureGitignore(){if(this.gitignoreChecked)return;this.gitignoreChecked=!0;let e=".gitignore",t=this.cacheDir;if(Fe(e)){if(un(e,"utf-8").split(`
|
|
3
|
+
`).some(o=>o.trim()===t||o.trim()===t+"/"))return;Tt(e,`
|
|
4
|
+
${t}/
|
|
5
|
+
`)}else dn(e,`${t}/
|
|
6
|
+
`)}getPath(e,t,r){return jt(this.cacheDir,e,`${t}@${r}.kan.yml`)}};function se(n){let e=n;for(;;){let t=Mt(e);if(t===e)break;if(pn(e).includes(".")||pn(t).includes(".")){e=t;continue}break}return e}function ge(n,e){for(let t of Nt(n,{withFileTypes:!0})){let r=Ft(n,t.name);t.isDirectory()&&t.name!=="node_modules"&&t.name!==".kanonak"?ge(r,e):t.name.endsWith(".kan.yml")&&e.push(r)}}var Me=class{repos;constructor(...e){this.repos=e}async getHighestCompatibleVersionAsync(e,t){for(let r of this.repos)try{let o=await r.getHighestCompatibleVersionAsync(e,t);if(o)return o}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 r=await t.getDocumentAsync(e);if(r)return r}catch{}return null}async getDocumentsByNamespaceAsync(e,t){for(let r of this.repos)try{let o=await r.getDocumentsByNamespaceAsync(e,t);if(o.length>0)return o}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 r=await t.getDocumentContentAsync(e);if(r)return r}catch{}return null}async getDocumentUriAsync(e){for(let t of this.repos)try{let r=await t.getDocumentUriAsync(e);if(r)return r}catch{}return null}};async function T(n,e){let t=[];ge(n,t);let r=new Bt(e);for(let c of t)try{let i=Lt(c,"utf-8"),l=e.parse(i),u=l.metadata.namespace_;if(u){let d=`${u.publisher}/${u.package_}@${u.version}`;await r.saveDocumentAsync(l,d)}}catch{}let o=new Vt(zt(),!0,e),a=new U,s=new Ht({getFromCache:(c,i,l)=>a.get(c,i,l),onFetch:(c,i,l,u)=>a.put(c,i,l,u)});return new Me(r,o,s)}async function fn(n){let e=Wt(n),t=Gt(e),r=t.isDirectory()?se(e):se(Xt(e)),o=new Jt,a=new Yt(o),s=await T(r,o),c=[];if(t.isDirectory()?ge(e,c):c.push(e),c.length===0){console.log("No .kan.yml files found.");return}let i=0,l=0;for(let u of c){let d=qt(u,"utf-8"),m=o.parseWithErrors(d);if(m.errors&&m.errors.length>0){console.log(`
|
|
7
|
+
${u}:`);for(let h of m.errors)console.log(` ERROR (parse): ${h.message} [line ${h.line}:${h.column}]`),i++;continue}let k=m.document;if(!k){console.log(`
|
|
8
|
+
${u}:`),console.log(" ERROR: Failed to parse document"),i++;continue}let g=await a.validateAsync(k,s),y=g.errors.filter(h=>h.severity===mn.Error),S=g.errors.filter(h=>h.severity===mn.Warning);if(y.length>0||S.length>0){let h=k.metadata.namespace_,$=h?`${h.publisher}/${h.package_}@${h.version}`:u;console.log(`
|
|
9
|
+
${$}:`);for(let w of y)console.log(` ERROR: ${w.message}`),w.suggestion&&console.log(` -> ${w.suggestion}`);for(let w of S)console.log(` WARN: ${w.message}`)}i+=y.length,l+=S.length}console.log(`
|
|
10
|
+
${c.length} file(s) validated. ${i} error(s), ${l} warning(s).`),i>0&&process.exit(1)}import{KanonakParser as rr,PublisherIndex as or,CredentialStore as ar,createAuthenticatedFetch as sr}from"@kanonak-protocol/sdk";import{readFileSync as Zt,writeFileSync as Qt,existsSync as er}from"fs";import{createHash as nr}from"crypto";import gn from"js-yaml";var Be="kanonak.lock",tr=`# This file is generated by Kanonak CLI. Do not edit manually.
|
|
11
|
+
`;function kn(){if(!er(Be))return null;let n=Zt(Be,"utf-8"),e=gn.load(n);return!e||typeof e!="object"||e.version!=="1"?null:{version:"1",lastUpdated:e.lastUpdated??new Date().toISOString(),packages:e.packages??{}}}function hn(n){n.lastUpdated=new Date().toISOString();let e={};for(let r of Object.keys(n.packages).sort())e[r]=n.packages[r];n.packages=e;let t=gn.dump(n,{lineWidth:-1,sortKeys:!1,quotingType:'"'});Qt(Be,tr+t,"utf-8")}function N(n){return`sha256:${nr("sha256").update(n).digest("hex")}`}function G(n){let e=n.indexOf("@"),t,r=null;e!==-1?(t=n.substring(0,e),r=n.substring(e+1)||null):t=n;let o=t.indexOf("/");if(o===-1)return null;let a=t.substring(0,o),s=t.substring(o+1);return!a||!s?null:{publisher:a,packageName:s,version:r}}async function yn(n){let e=new U,t=new rr,r=new ar,o=sr(r),a=new or({fetchFn:o}),s=kn()??{version:"1",lastUpdated:new Date().toISOString(),packages:{}};if(!n){Object.keys(s.packages).length===0&&(console.error("No kanonak.lock file found or lock file is empty."),console.error("Usage: kanonak install {publisher}/{package}[@{version}]"),process.exit(1)),console.log(`Installing ${Object.keys(s.packages).length} package(s) from kanonak.lock...`);for(let[k,g]of Object.entries(s.packages)){let y=k.indexOf("/"),S=k.substring(0,y),h=k.substring(y+1),$=e.get(S,h,g.version);if($)console.log(` ${k}@${g.version} (cached)`);else{let w=g.resolved,K=await o(w,S);if(!K.ok)throw new Error(`Failed to fetch ${w} (${K.status} ${K.statusText})`);$=await K.text(),e.put(S,h,g.version,$),console.log(` ${k}@${g.version}`)}}console.log(`
|
|
12
|
+
Installed ${Object.keys(s.packages).length} package(s) from lock file.`);return}let c=G(n);c||(console.error(`Invalid package reference: ${n}`),console.error("Expected format: {publisher}/{package}@{version} or {publisher}/{package}"),process.exit(1));let{publisher:i,packageName:l,version:u}=c,d=u??await a.getHighestVersion(i,l);d||(console.error(`Could not resolve version for ${i}/${l}`),process.exit(1)),console.log(`Installing ${i}/${l}@${d}...`);let m=new Set;await bn(i,l,d,e,t,a,o,m,s),hn(s),console.log(`
|
|
13
|
+
Installed ${m.size} package(s).`)}async function bn(n,e,t,r,o,a,s,c,i){let l=`${n}/${e}@${t}`;if(c.has(l))return;c.add(l);let u=`${n}/${e}`,d=r.get(n,e,t),m;if(d)console.log(` ${l} (cached)`),m=await a.getPackageUrl(n,e,t);else{m=await a.getPackageUrl(n,e,t);let y=await s(m,n);if(!y.ok)throw new Error(`Failed to fetch ${m} (${y.status} ${y.statusText})`);d=await y.text(),r.put(n,e,t,d),console.log(` ${l}`)}let k={},g=o.parse(d);if(g.metadata.imports)for(let[y,S]of Object.entries(g.metadata.imports))for(let h of S){let $=await a.resolveVersion(y,h);$?(k[`${y}/${h.packageName}`]=$,await bn(y,h.packageName,$,r,o,a,s,c,i)):console.error(` WARNING: Could not resolve ${y}/${h.packageName} ${h.package_}`)}i.packages[u]={version:t,resolved:m,integrity:N(d),dependencies:k}}import{readFileSync as ir}from"fs";import{resolve as cr,dirname as lr}from"path";import{KanonakParser as ur}from"@kanonak-protocol/sdk";async function wn(n){let e=cr(n),t=ir(e,"utf-8"),r=new ur,o=r.parse(t),a=o.metadata.namespace_,s=a?`${a.publisher}/${a.package_}@${a.version}`:n;if(console.log(s),!o.metadata.imports){console.log(" (no imports)");return}let c=se(lr(e)),i=await T(c,r),l=new Set;for(let[u,d]of Object.entries(o.metadata.imports))for(let m of d)await Sn(u,m,i,l," ")}async function Sn(n,e,t,r,o){let a=`${n}/${e.packageName}`;if(r.has(a)){console.log(`${o}${a} (${e.package_}) [circular]`);return}r.add(a);let s;try{s=await t.getHighestCompatibleVersionAsync(n,e)}catch{console.log(`${o}${a} (${e.package_}) [fetch failed]`);return}if(!s){console.log(`${o}${a} (${e.package_}) [not found]`);return}let c=s.metadata.namespace_?.version?.toString()??"?";if(console.log(`${o}${n}/${e.packageName}@${c}`),s.metadata.imports)for(let[i,l]of Object.entries(s.metadata.imports))for(let u of l)await Sn(i,u,t,r,o+" ")}import{createHash as pr,randomBytes as Dn}from"crypto";import{createServer as mr}from"http";import{execFile as Ve}from"child_process";import{CredentialStore as fr,generateDPoPKeyPair as gr,createDPoPProof as $n,serverSupportsDPoP as kr}from"@kanonak-protocol/sdk";import{normalizeHost as dr}from"@kanonak-protocol/sdk";var F=class{cache=new Map;async discover(e){let t=dr(e);if(this.cache.has(t))return this.cache.get(t);let r=`https://${t}/.well-known/oauth-authorization-server`,o=await this.tryEndpoint(r);if(!o){let a=`https://${t}/.well-known/openid-configuration`;o=await this.tryEndpoint(a)}return this.cache.set(t,o),o}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(o){let a=o instanceof Error?o.message:String(o);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 r;try{r=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:ie(r.issuer),authorizationEndpoint:ie(r.authorization_endpoint),tokenEndpoint:ie(r.token_endpoint),registrationEndpoint:ie(r.registration_endpoint),revocationEndpoint:ie(r.revocation_endpoint),scopesSupported:W(r.scopes_supported),responseTypesSupported:W(r.response_types_supported),grantTypesSupported:W(r.grant_types_supported),codeChallengeMethodsSupported:W(r.code_challenge_methods_supported),tokenEndpointAuthMethodsSupported:W(r.token_endpoint_auth_methods_supported),dpopSigningAlgValuesSupported:W(r.dpop_signing_alg_values_supported)}}};function ie(n){return typeof n=="string"?n:null}function W(n){return Array.isArray(n)?n.filter(e=>typeof e=="string"):null}var J=class{discovery;credentialStore;constructor(e,t){this.discovery=e??new F,this.credentialStore=t??new fr}async authorize(e,t=[]){console.log(`Starting OAuth flow for ${e}...`);let r=await this.discovery.discover(e);if(!r)return R(`No OAuth discovery endpoint found for '${e}'.
|
|
14
14
|
The server must expose one of:
|
|
15
15
|
- https://${e}/.well-known/oauth-authorization-server (RFC 8414)
|
|
16
16
|
- https://${e}/.well-known/openid-configuration (OpenID Connect)
|
|
17
17
|
Verify the hostname is correct and HTTPS is configured.
|
|
18
|
-
If using a corporate proxy, ensure it is not blocking the discovery request.`);let o=[];if(r.authorizationEndpoint||o.push("authorization_endpoint"),r.tokenEndpoint||o.push("token_endpoint"),o.length>0)return
|
|
19
|
-
Contact the IDP administrator to ensure these are included in the discovery document.`);let
|
|
20
|
-
Ensure your Node.js installation supports EC P-256 curves.`)}}let{redirectUri:c,port:
|
|
18
|
+
If using a corporate proxy, ensure it is not blocking the discovery request.`);let o=[];if(r.authorizationEndpoint||o.push("authorization_endpoint"),r.tokenEndpoint||o.push("token_endpoint"),o.length>0)return R(`OAuth metadata for '${e}' is missing required fields: ${o.join(", ")}.
|
|
19
|
+
Contact the IDP administrator to ensure these are included in the discovery document.`);let a=kr(r.dpopSigningAlgValuesSupported),s=null;if(a){console.log(" Server supports DPoP (RFC 9449) \u2014 generating key pair...");try{s=gr()}catch(I){return R(`Failed to generate DPoP key pair: ${X(I)}
|
|
20
|
+
Ensure your Node.js installation supports EC P-256 curves.`)}}let{redirectUri:c,port:i,waitForCallback:l,close:u}=await vr(),d=await this.credentialStore.getCredential(e),m=d?.clientId??null,k=d?.clientSecret??null;if(!m&&r.registrationEndpoint){console.log(" Registering dynamic OAuth client (RFC 7591)...");let I=await this.registerClient(r.registrationEndpoint,c);if(!I.success)return u(),R(I.error);m=I.clientId,k=I.clientSecret??null}if(!m)return u(),R(`No OAuth client credentials for '${e}' and the server does not support dynamic client registration (no registration_endpoint in metadata).
|
|
21
21
|
You must pre-register a client with your IDP and configure the client_id.
|
|
22
22
|
Ask your IDP administrator to enable dynamic client registration (RFC 7591),
|
|
23
|
-
or add a registration_endpoint to the OAuth metadata.`);let g=
|
|
23
|
+
or add a registration_endpoint to the OAuth metadata.`);let g=yr(),y=br(g),S=wr(),h=Sr(r.authorizationEndpoint,m,c,t,S,y);console.log(` Opening browser for authorization on port ${i}...`),console.log(" If the browser doesn't open, navigate to:"),console.log(` ${h}`),Ar(h);let $=await l();if(u(),!$)return R(`Authorization timed out after 5 minutes.
|
|
24
24
|
The browser authorization was not completed in time.
|
|
25
|
-
Re-run 'kanonak login ${e}' and complete the browser authorization promptly.`);if(
|
|
25
|
+
Re-run 'kanonak login ${e}' and complete the browser authorization promptly.`);if(!$.code){let I=$.error?`: ${$.error}`:"";return R(`No authorization code received${I}.
|
|
26
26
|
The IDP may have rejected the authorization request.
|
|
27
|
-
Check the IDP admin console for error details.`)}if(
|
|
27
|
+
Check the IDP admin console for error details.`)}if($.state!==S)return R(`Authorization state mismatch \u2014 possible CSRF attack.
|
|
28
28
|
The response did not match the expected session.
|
|
29
|
-
Re-run 'kanonak login ${e}' to start a fresh authorization flow.`);console.log(" Exchanging authorization code for tokens...");let w=await this.exchangeCode(r.tokenEndpoint,m,
|
|
29
|
+
Re-run 'kanonak login ${e}' to start a fresh authorization flow.`);console.log(" Exchanging authorization code for tokens...");let w=await this.exchangeCode(r.tokenEndpoint,m,k,$.code,c,g,s);if(!w.success)return R(w.error);let K={clientId:m,clientSecret:k,accessToken:w.tokens.accessToken,refreshToken:w.tokens.refreshToken,expiresAt:w.tokens.expiresIn?new Date(Date.now()+w.tokens.expiresIn*1e3).toISOString():null,tokenEndpoint:r.tokenEndpoint,dpopKeyPair:s};return await this.credentialStore.store(e,K),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 R(`No stored credentials for '${e}'. Run 'kanonak login ${e}' to authenticate first.`);if(!t.refreshToken)return R(`No refresh token available for '${e}'.
|
|
30
30
|
The authorization server may not issue refresh tokens for this client.
|
|
31
|
-
Run 'kanonak login ${e}' to re-authenticate.`);if(!
|
|
32
|
-
The stored credential may be corrupted. Run 'kanonak logout ${e}' then 'kanonak login ${e}'.`);let r=
|
|
31
|
+
Run 'kanonak login ${e}' to re-authenticate.`);if(!t.clientId)return R(`No client ID in stored credentials for '${e}'.
|
|
32
|
+
The stored credential may be corrupted. Run 'kanonak logout ${e}' then 'kanonak login ${e}'.`);let r=t.tokenEndpoint;if(!r){let a=await this.discovery.discover(e);if(!a?.tokenEndpoint)return R(`Cannot find token endpoint for '${e}'.
|
|
33
33
|
The OAuth discovery endpoint may be unreachable.
|
|
34
|
-
Check network connectivity and run 'kanonak login ${e}' to re-authenticate.`);r=
|
|
35
|
-
The refresh token may have expired. Run 'kanonak login ${e}' to re-authenticate.`)}async logout(e){let
|
|
36
|
-
You may not be logged in, or credentials may be stored in a different backend.`);let r=await this.discovery.discover(e);if(r?.revocationEndpoint&&
|
|
34
|
+
Check network connectivity and run 'kanonak login ${e}' to re-authenticate.`);r=a.tokenEndpoint}let o=await this.refreshTokenRequest(r,t.clientId,t.clientSecret,t.refreshToken,t.dpopKeyPair);return o.success?(t.accessToken=o.tokens.accessToken,o.tokens.refreshToken&&(t.refreshToken=o.tokens.refreshToken),t.expiresAt=o.tokens.expiresIn?new Date(Date.now()+o.tokens.expiresIn*1e3).toISOString():null,t.tokenEndpoint=r,await this.credentialStore.store(e,t),{success:!0,host:e}):R(`${o.error}
|
|
35
|
+
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 R(`No stored credentials for '${e}'.
|
|
36
|
+
You may not be logged in, or credentials may be stored in a different backend.`);let r=await this.discovery.discover(e);if(r?.revocationEndpoint&&t.accessToken&&t.clientId)try{await this.revokeToken(r.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 r;try{r=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: ${X(s)}
|
|
37
37
|
Ensure the IDP is reachable and HTTPS is properly configured.
|
|
38
|
-
If using a corporate proxy or custom CA, set NODE_EXTRA_CA_CERTS.`}}if(!r.ok){let
|
|
38
|
+
If using a corporate proxy or custom CA, set NODE_EXTRA_CA_CERTS.`}}if(!r.ok){let s=await He(r);return{success:!1,error:`Dynamic client registration (RFC 7591) failed.
|
|
39
39
|
Endpoint: ${e}
|
|
40
|
-
HTTP ${r.status}: ${
|
|
40
|
+
HTTP ${r.status}: ${s}
|
|
41
41
|
The IDP may not support dynamic registration for public clients.
|
|
42
|
-
Ask your IDP administrator to enable RFC 7591 support, or pre-register a client manually.`}}let o=await r.json(),
|
|
43
|
-
The IDP response may be malformed. Contact your IDP administrator.`}}async exchangeCode(e,
|
|
44
|
-
The stored key pair may be corrupted. Run 'kanonak login' to re-authenticate.`}}let u;try{u=await fetch(e,{method:"POST",headers:l,body:
|
|
45
|
-
Ensure the token endpoint is reachable.`}}if(!u.ok){let
|
|
42
|
+
Ask your IDP administrator to enable RFC 7591 support, or pre-register a client manually.`}}let o=await r.json(),a=o.client_id;return a?{success:!0,clientId:a,clientSecret:o.client_secret}:{success:!1,error:`Dynamic client registration response from ${e} did not contain a client_id.
|
|
43
|
+
The IDP response may be malformed. Contact your IDP administrator.`}}async exchangeCode(e,t,r,o,a,s,c){let i=new URLSearchParams({grant_type:"authorization_code",client_id:t,code:o,redirect_uri:a,code_verifier:s});r&&i.set("client_secret",r);let l={"Content-Type":"application/x-www-form-urlencoded"};if(c)try{l.DPoP=$n(c.privateKey,c.publicKey,"POST",e)}catch(d){return{success:!1,error:`Failed to create DPoP proof for token exchange: ${X(d)}
|
|
44
|
+
The stored key pair may be corrupted. Run 'kanonak login' to re-authenticate.`}}let u;try{u=await fetch(e,{method:"POST",headers:l,body:i.toString()})}catch(d){return{success:!1,error:`Token exchange request to ${e} failed: ${X(d)}
|
|
45
|
+
Ensure the token endpoint is reachable.`}}if(!u.ok){let d=await He(u),m=hr(d);return{success:!1,error:`Token exchange failed.
|
|
46
46
|
Endpoint: ${e}
|
|
47
|
-
HTTP ${u.status}: ${
|
|
48
|
-
${m}`:"")}}return{success:!0,tokens:
|
|
49
|
-
Authenticated with ${
|
|
47
|
+
HTTP ${u.status}: ${d}`+(m?`
|
|
48
|
+
${m}`:"")}}return{success:!0,tokens:vn(await u.json())}}async refreshTokenRequest(e,t,r,o,a){let s=new URLSearchParams({grant_type:"refresh_token",client_id:t,refresh_token:o});r&&s.set("client_secret",r);let c={"Content-Type":"application/x-www-form-urlencoded"};if(a)try{c.DPoP=$n(a.privateKey,a.publicKey,"POST",e)}catch(l){return{success:!1,error:`Failed to create DPoP proof for token refresh: ${X(l)}`}}let i;try{i=await fetch(e,{method:"POST",headers:c,body:s.toString()})}catch(l){return{success:!1,error:`Token refresh request to ${e} failed: ${X(l)}`}}if(!i.ok){let l=await He(i);return{success:!1,error:`Token refresh failed \u2014 HTTP ${i.status}: ${l}`}}return{success:!0,tokens:vn(await i.json())}}async revokeToken(e,t,r){await fetch(e,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams({token:t,client_id:r}).toString()})}};function R(n){return{success:!1,error:n}}function vn(n){return{accessToken:n.access_token,refreshToken:n.refresh_token,expiresIn:typeof n.expires_in=="number"?n.expires_in:void 0}}function X(n){return n instanceof Error?n.message:String(n)}async function He(n){try{return await n.text()}catch{return"(could not read response body)"}}function hr(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 yr(){return Dn(32).toString("base64url")}function br(n){return pr("sha256").update(n).digest("base64url")}function wr(){return Dn(16).toString("base64url")}function Sr(n,e,t,r,o,a){let s=new URLSearchParams({client_id:e,response_type:"code",redirect_uri:t,scope:r.join(" "),state:o,code_challenge:a,code_challenge_method:"S256"});return`${n}?${s}`}var $r=300*1e3;async function vr(){return new Promise(n=>{let e=mr((o,a)=>{let s=new URL(o.url,"http://localhost"),c=s.searchParams.get("code")??void 0,i=s.searchParams.get("state")??void 0,l=s.searchParams.get("error")??s.searchParams.get("error_description")??void 0,u=l?Dr(l):null,d=u?`<html><body><h1>Authorization failed</h1><p>${u}</p></body></html>`:"<html><body><h1>Authorization successful!</h1><p>You can close this window.</p></body></html>";a.writeHead(200,{"Content-Type":"text/html"}),a.end(d),t({code:c,state:i,error:l})}),t,r=new Promise(o=>{t=o,setTimeout(()=>{o(null),e.close()},$r)});e.listen(0,"127.0.0.1",()=>{let o=e.address();n({redirectUri:`http://localhost:${o.port}/callback`,port:o.port,waitForCallback:()=>r,close:()=>e.close()})})})}function Dr(n){return n.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""")}function Ar(n){try{process.platform==="win32"?Ve("cmd",["/c","start","",n]):process.platform==="darwin"?Ve("open",[n]):Ve("xdg-open",[n])}catch{console.log(" Could not open browser automatically. Please navigate to the URL above manually.")}}import{CredentialStore as Cr}from"@kanonak-protocol/sdk";async function An(n){try{let e=new F,t=new Cr,o=await new J(e,t).authorize(n);o.success?console.log(`
|
|
49
|
+
Authenticated with ${n}.`):(console.error(`
|
|
50
50
|
Authentication failed:
|
|
51
|
-
${o.error}`),process.exit(1))}catch(e){let
|
|
51
|
+
${o.error}`),process.exit(1))}catch(e){let t=e instanceof Error?e.message:String(e);console.error(`
|
|
52
52
|
Authentication failed unexpectedly:
|
|
53
|
-
${
|
|
54
|
-
If this persists, file an issue at https://github.com/kanonak-protocol/typescript/issues`),process.exit(1)}}import{CredentialStore as
|
|
53
|
+
${t}`),console.error(`
|
|
54
|
+
If this persists, file an issue at https://github.com/kanonak-protocol/typescript/issues`),process.exit(1)}}import{CredentialStore as Kr}from"@kanonak-protocol/sdk";async function Cn(n){try{let e=new F,t=new Kr,o=await new J(e,t).logout(n);o.success?console.log(`Logged out from ${n}.`):(console.error(`
|
|
55
55
|
Logout failed:
|
|
56
|
-
${o.error}`),process.exit(1))}catch(e){let
|
|
56
|
+
${o.error}`),process.exit(1))}catch(e){let t=e instanceof Error?e.message:String(e);console.error(`
|
|
57
57
|
Logout failed unexpectedly:
|
|
58
|
-
${
|
|
59
|
-
`;function
|
|
60
|
-
Installed capability "${w}".`),console.log(`Run "kanonak ${w} --help" to get started.`)}async function
|
|
61
|
-
`);for(let[n,r]of e)console.log(` ${n} ${r.publisher}/${r.package_}@${r.version}`)}import{Command as Rt}from"commander";function Z(t){return`${K}/${P}/${t}`}var Be={[Z("fetch-and-deploy")]:(t,e,n,r)=>t.add(e,n[0],r),[Z("remove-deployed")]:(t,e,n,r)=>t.remove(e,n[0],r),[Z("list-deployed")]:(t,e,n,r)=>t.list(e,r),[Z("update-deployed")]:(t,e,n,r)=>t.update(e,n[0],r),[Z("search-available")]:(t,e,n,r)=>t.search(e,r),[Z("show-info")]:(t,e,n,r)=>t.info(e,n[0],r)};function Tt(t,e,n){for(let r of e){let o=new Rt(r.commandName).description(r.description.trim());for(let i of r.commands){let a=o.command(eo(i));a.description(i.description);for(let c of i.arguments)if(c.isOption){let s=c.defaultValue!=null?`--${c.argumentName} [value]`:`--${c.argumentName} <value>`;a.option(s,"",c.defaultValue)}a.action(async(...c)=>{let s=to(c);await no(n,r,i,c,s)})}t.addCommand(o)}}function eo(t){let e=t.arguments.filter(n=>!n.isOption).map(n=>n.required?`<${n.argumentName}>`:`[${n.argumentName}]`);return[t.subcommandName,...e].join(" ")}function to(t){for(let e=t.length-1;e>=0;e--)if(t[e]&&typeof t[e]=="object"&&!(t[e]instanceof Rt))return t[e];return{}}async function no(t,e,n,r,o){let i=[];for(let c of r)if(typeof c=="string")i.push(c);else break;n.actionKey||(console.error(`Capability subcommand '${n.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(Be).join(", ")}.`),process.exit(1));let a=Be[n.actionKey];a||(console.error(`Capability subcommand '${n.subcommandName}' references unknown Action '${n.actionKey}'. Known actions: ${Object.keys(Be).join(", ")}.`),process.exit(1)),await a(t,e,i,o)}import{KanonakObjectParser as ro,PublisherIndex as Ve,PublisherConfigResolver as oo}from"@kanonak-protocol/sdk";var fe=class{constructor(e,n,r,o,i,a){this.fileCache=e;this.parser=n;this.publisherIndex=r;this.fetchFn=o;this.handlerRegistry=i;this.repository=a}fileCache;parser;publisherIndex;fetchFn;handlerRegistry;repository;objectParser=new ro;async add(e,n,r){let o=G(n);o||(console.error(`Invalid package reference: ${n}`),console.error("Expected format: {publisher}/{package}@{version} or {publisher}/{package}"),process.exit(1));let{publisher:i,packageName:a,version:c}=o,s=c??await this.publisherIndex.getHighestVersion(i,a);s||(console.error(`Could not resolve version for ${i}/${a}`),process.exit(1));let l=this.fileCache.get(i,a,s);if(!l){let S=await this.publisherIndex.getPackageUrl(i,a,s),y=await this.fetchFn(S,i);if(!y.ok)throw new Error(`Failed to fetch ${S} (${y.status} ${y.statusText})`);l=await y.text(),this.fileCache.put(i,a,s,l)}let u=this.parser.parse(l),p=new C(u,this.repository),m=await this.objectParser.parseKanonaks(p),h=jt(e.managesTypeKey);h||(console.error(`Capability "${e.commandName}" has no resolved managesType.`),process.exit(1));let g=_(m,h);g.length===0&&(console.error(`Package ${i}/${a}@${s} does not contain any ${x(h)} instances.`),process.exit(1));let k=this.handlerRegistry.get(e.deploymentTargetKey);k?await k.deploy({instances:g,allKanonaks:m,repository:this.repository,options:r}):console.log(`Cached ${i}/${a}@${s} (no deployment handler for "${e.deploymentTargetKey}")`)}async remove(e,n,r){await this.requireHandler(e).undeploy(n,{repository:this.repository,options:r})}async list(e,n){let o=await this.requireHandler(e).list({repository:this.repository,options:n}),i=e.managesTypeKey||"managed";if(o.length===0){console.log(`No ${i} instances installed.`);return}console.log(`Installed ${i} instances:
|
|
62
|
-
`);
|
|
63
|
-
|
|
64
|
-
`)
|
|
65
|
-
`);for(let g of m)console.log(` ${g.publisher}/${g.package_}@${g.version}`),console.log(` ${g.subject.name}`),console.log()}async info(e,n,r){let a=(await this.requireHandler(e).list({repository:this.repository,options:r})).find(c=>c.name===n);a||(console.error(`"${n}" is not installed.`),process.exit(1)),console.log(`Name: ${a.name}`),console.log(`Type: ${e.managesTypeKey||"n/a"}`),console.log(`Publisher: ${a.publisher||"unmanaged"}`),console.log(`Package: ${a.package_||"n/a"}`),console.log(`Version: ${a.version||"n/a"}`),console.log(`Path: ${a.path}`)}requireHandler(e){let n=this.handlerRegistry.get(e.deploymentTargetKey);return n||(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)),n}};function jt(t){if(!t)return;let e=t.split("/");if(e.length===3)return{publisher:e[0],package_:e[1],name:e[2]}}var ge=class{handlers=new Map;register(e,n){this.handlers.set(e,n)}get(e){return this.handlers.get(e)??null}};import{mkdirSync as ki,rmSync as bi,existsSync as _e,readdirSync as wi,writeFileSync as Si}from"fs";import{join as Ke}from"path";import{KanonakObjectParser as Di,KanonakParser as vi}from"@kanonak-protocol/sdk";import{SubjectKanonak as Ut}from"@kanonak-protocol/sdk";var ye=class{constructor(e,n,r){this.repository=e;this.parser=n;this.objectParser=r}repository;parser;objectParser;cache=new Map;async resolveSubject(e,n){let r=Dt(n,e);if(r)return r;let o=`${e.publisher}/${e.package_}`,i=this.cache.get(o);if(!i){let a=await this.repository.getDocumentsByNamespaceAsync(e.publisher,e.package_);if(a.length===0)return;let c=a[0],s=new C(c,this.repository);i=await this.objectParser.parseKanonaks(s),this.cache.set(o,i)}for(let a of i)if(a instanceof Ut&&a.name===e.name&&a.namespace&&a.namespace.startsWith(`${e.publisher}/${e.package_}@`))return a;for(let a of i)if(a instanceof Ut&&a.name===e.name)return a}};import{DefinedKanonak as xt,ReferenceKanonak as He,StringStatement as lo,NumberStatement as uo,BooleanStatement as po,ReferenceStatement as mo,EmbeddedStatement as fo,ListStatement as go}from"@kanonak-protocol/sdk";var io="kanonak.org",ao="document-ast",b=t=>({publisher:io,package_:ao,name:t}),T={Document:b("Document"),Block:b("Block"),Inline:b("Inline"),StructuredValue:b("StructuredValue"),Heading:b("Heading"),Paragraph:b("Paragraph"),RawBlock:b("RawBlock"),Text:b("Text"),StructuredMap:b("StructuredMap"),StructuredEntry:b("StructuredEntry"),StructuredList:b("StructuredList"),StringScalar:b("StringScalar"),IntegerScalar:b("IntegerScalar"),EscapeHint:b("EscapeHint"),MediaType:b("MediaType"),metadata:b("metadata"),children:b("children"),level:b("level"),inlines:b("inlines"),text:b("text"),entries:b("entries"),key:b("key"),value:b("value"),escapeHint:b("escapeHint"),items:b("items"),stringValue:b("stringValue"),integerValue:b("integerValue"),rawContent:b("rawContent"),mediaType:b("mediaType"),mimeType:b("mimeType"),ESC_RAW:b("esc-raw"),ESC_YAML_SAFE:b("esc-yaml-safe"),ESC_TOML_STRING:b("esc-toml-string"),ESC_TOML_MULTILINE:b("esc-toml-multiline"),ESC_JSON:b("esc-json"),TEXT_PLAIN:b("text-plain"),TEXT_MARKDOWN:b("text-markdown"),TEXT_HTML:b("text-html"),APPLICATION_JSON:b("application-json"),TEXT_YAML:b("text-yaml"),IMAGE_SVG_XML:b("image-svg-xml")},so="kanonak.org",co="transformations",d=t=>({publisher:so,package_:co,name:t}),f={Transformation:d("Transformation"),InputPattern:d("InputPattern"),Expression:d("Expression"),ExpressionKind:d("ExpressionKind"),ExpressionFragment:d("ExpressionFragment"),AstFieldBinding:d("AstFieldBinding"),OutputFormat:d("OutputFormat"),FormatOverride:d("FormatOverride"),RenameEntry:d("RenameEntry"),Artifact:d("Artifact"),NormalizeKind:d("NormalizeKind"),inputPattern:d("inputPattern"),rule:d("rule"),artifactName:d("artifactName"),outputs:d("outputs"),formatOverrides:d("formatOverrides"),matchesClass:d("matchesClass"),requires:d("requires"),kind:d("kind"),astClass:d("astClass"),set:d("set"),iterate:d("iterate"),loopVar:d("loopVar"),emit:d("emit"),condition:d("condition"),thenBuild:d("thenBuild"),elseBuild:d("elseBuild"),parts:d("parts"),stringLiteral:d("stringLiteral"),integerLiteral:d("integerLiteral"),booleanLiteral:d("booleanLiteral"),varName:d("varName"),readSource:d("readSource"),readProp:d("readProp"),traverseSource:d("traverseSource"),through:d("through"),step:d("step"),primary:d("primary"),alternate:d("alternate"),uriNameOf:d("uriNameOf"),listMapSource:d("listMapSource"),mapBody:d("mapBody"),separator:d("separator"),items:d("items"),normSource:d("normSource"),normKind:d("normKind"),checkExpr:d("checkExpr"),refTo:d("refTo"),fragmentRef:d("fragmentRef"),expr:d("expr"),labelTarget:d("labelTarget"),labelSource:d("labelSource"),field:d("field"),bindValue:d("bindValue"),backendUri:d("backendUri"),formatTarget:d("formatTarget"),metadataKeys:d("metadataKeys"),metadataRenames:d("metadataRenames"),trailingNewline:d("trailingNewline"),fromKey:d("fromKey"),toKey:d("toKey"),KIND_BUILD_AST_NODE:d("build-ast-node"),KIND_FOR_EACH:d("for-each"),KIND_WHEN:d("when"),KIND_CONCAT:d("concat"),KIND_STRING_LITERAL:d("string-literal"),KIND_INTEGER_LITERAL:d("integer-literal"),KIND_BOOLEAN_LITERAL:d("boolean-literal"),KIND_VAR_REF:d("var-ref"),KIND_PROPERTY_READ:d("property-read"),KIND_TRAVERSE:d("traverse"),KIND_FALLBACK:d("fallback"),KIND_URI_NAME:d("uri-name"),KIND_LIST_MAP:d("list-map"),KIND_JOIN:d("join"),KIND_NORMALIZE:d("normalize"),KIND_IS_SET:d("is-set"),KIND_URI_LITERAL:d("uri-literal"),KIND_CALL_FRAGMENT:d("call-fragment"),KIND_DISPLAY_LABEL:d("display-label"),NORM_TRIM_END:d("trim-end"),FMT_MARKDOWN_FRONTMATTER:d("markdown-with-frontmatter"),FMT_TOML:d("toml"),FMT_JSON:d("json"),FMT_PLAIN_MARKDOWN:d("plain-markdown")};var he=class extends Error{constructor(e){super(e)}},ke=class{constructor(e,n){this.resolver=e;this.allKanonaks=n}resolver;allKanonaks;async evaluate(e,n){switch(e.kind){case"var-ref":{if(!n.has(e.varName))throw new he(`Unbound variable "${e.varName}"`);return n.get(e.varName)}case"string-literal":return e.value;case"integer-literal":return e.value;case"boolean-literal":return e.value;case"uri-literal":return{...e.refTo};case"property-read":{let r=await this.evaluate(e.source,n);return r instanceof xt?ze(r,e.readProp):void 0}case"traverse":{let r=await this.evaluate(e.source,n);if(!(r instanceof xt))return;let o=ze(r,e.through),i;if(o instanceof He?i=o.subject:Array.isArray(o)&&o.length>0&&o[0]instanceof He&&(i=o[0].subject),!i)return;let a=await this.resolver.resolveSubject(i,this.allKanonaks);if(!a)return;let c=new Map(n);return c.set("input",a),this.evaluate(e.step,c)}case"fallback":{let r=await this.evaluate(e.primary,n);return Lt(r)?r:this.evaluate(e.alternate,n)}case"uri-name":{let r=await this.evaluate(e.of,n);return r instanceof He?r.subject.name:ho(r)?r.name:void 0}case"list-map":{let r=await this.evaluate(e.source,n),o=Ge(r),i=[];for(let a of o){let c=new Map(n);c.set(e.loopVar,a),i.push(await this.evaluate(e.mapBody,c))}return i}case"join":{let r=await this.evaluate(e.items,n),o=Ge(r),i=[];for(let a of o)a!=null&&i.push(String(a));return i.join(e.separator)}case"normalize":{let r=await this.evaluate(e.source,n);return typeof r!="string"?r:e.normKind==="trim-end"?r.trimEnd():r}case"is-set":{let r=await this.evaluate(e.check,n);return Lt(r)}case"when":{let r=await this.evaluate(e.condition,n);return yo(r)?this.evaluate(e.thenBuild,n):e.elseBuild?this.evaluate(e.elseBuild,n):void 0}case"concat":{let r=[];for(let o of e.parts){let i=await this.evaluate(o,n);if(i!=null)if(Array.isArray(i))for(let a of i)r.push(a);else r.push(i)}return r}case"for-each":{let r=await this.evaluate(e.iterate,n),o=Ge(r),i=[];for(let a of o){let c=new Map(n);c.set(e.loopVar,a);let s=await this.evaluate(e.emit,c);if(s!=null)if(Array.isArray(s))for(let l of s)i.push(l);else i.push(s)}return i}case"build-ast-node":return this.buildAstNode(e,n);case"display-label":{let r={publisher:e.labelTarget.publisher,package_:e.labelTarget.package_,name:e.labelTarget.name},o=await this.resolver.resolveSubject(r,this.allKanonaks);if(o){let i=ze(o,e.labelSource);if(typeof i=="string"&&i.length>0)return i}return e.labelTarget.name}default:{let r=e;throw new he(`Unhandled expression kind: ${JSON.stringify(r)}`)}}}async buildAstNode(e,n){let r={kind:e.astClass.name};for(let o of e.set){let i=await this.evaluate(o.value,n);if(i==null||Array.isArray(i)&&i.length===0)continue;let a=o.field.name;r[a]=i}return r}};function ze(t,e){let n=[];for(let o of t.statement){let i=o.predicate;i?.subject&&M(i.subject,e)&&n.push(o)}if(n.length===0)return;if(n.length===1&&n[0]instanceof go)return n[0].object;if(n.length===1)return Ot(n[0]);let r=[];for(let o of n){let i=Ot(o);i!==void 0&&r.push(i)}return r}function Ot(t){if(t instanceof lo||t instanceof uo||t instanceof po||t instanceof mo||t instanceof fo)return t.object}function Lt(t){return t==null?!1:typeof t=="string"||Array.isArray(t)?t.length>0:!0}function yo(t){return t==null?!1:typeof t=="boolean"?t:typeof t=="string"?t.length>0:typeof t=="number"?t!==0:Array.isArray(t)?t.length>0:!0}function Ge(t){return t==null?[]:Array.isArray(t)?t:[t]}function ho(t){return t!==null&&typeof t=="object"&&"publisher"in t&&"package_"in t&&"name"in t}import{EmbeddedKanonak as ko,ReferenceKanonak as qe,SubjectKanonak as bo,ListStatement as Ft,StringStatement as wo,ReferenceStatement as We}from"@kanonak-protocol/sdk";var v=class extends Error{constructor(n,r){super(`${n} (at ${r})`);this.path=r}path},Nt=16;function So(t){return t.predicate?.subject}function Mt(t,e){let n=[];for(let r of t.statement){let o=So(r);o&&M(o,e)&&n.push(r)}return n}function j(t,e){let n=B(t,e);if(n)return n;let r=Y(t,e);if(r.length===1&&r[0]instanceof qe)return r[0].subject}function be(t,e){let n=Y(t,e),r=[];for(let o of n)o instanceof ko&&r.push(o);return r}function Bt(t,e){let n=[];for(let r of Mt(t,e))if(r instanceof wo)n.push(r.object);else if(r instanceof Ft)for(let o of r.object)typeof o=="string"?n.push(o):o instanceof qe&&n.push(o.subject.name);else r instanceof We&&n.push(r.object.subject.name);return n}function Do(t,e){let n=t.split("/");if(n.length<3)throw new v(`Invalid property URI "${t}" \u2014 expected publisher/package/name`,e);let[r,o,...i]=n;return{publisher:r,package_:o,name:i.join("/")}}function Vt(t,e){let n=t.name,r=`transformation[${n}]`,o={catalog:e,depth:0},i=V(t,f.inputPattern);if(!i)throw new v("Transformation has no inputPattern",r);let a=vo(i,o,`${r}.inputPattern`),c=V(t,f.rule);if(!c)throw new v("Transformation has no rule",r);let s=Q(c,o,`${r}.rule`),l=V(t,f.artifactName);if(!l)throw new v("Transformation has no artifactName",r);let u=Q(l,o,`${r}.artifactName`),p=new Set;for(let h of Mt(t,f.outputs))if(h instanceof We)p.add(h.object.subject.name);else if(h instanceof Ft)for(let g of h.object)g instanceof qe&&p.add(g.subject.name);if(p.size===0)throw new v("Transformation has no outputs",r);let m=new Map;for(let h of be(t,f.formatOverrides)){let g=`${r}.formatOverrides[]`,k=j(h,f.formatTarget);if(!k)throw new v("FormatOverride missing formatTarget",g);m.set(k.name,Ao(h,g))}return{name:n,inputPattern:a,rule:s,artifactName:u,outputs:p,overrides:m}}function vo(t,e,n){let r=j(t,f.matchesClass);if(!r)throw new v("InputPattern has no matchesClass",n);let o={publisher:r.publisher,package_:r.package_,name:r.name},a=Bt(t,f.requires).map((c,s)=>Do(c,`${n}.requires[${s}]`));return{matchesClass:o,requires:a}}function Ao(t,e){let n=Bt(t,f.metadataKeys),r=n.length>0?n:void 0,o=new Map;for(let c of be(t,f.metadataRenames)){let s=A(c,f.fromKey),l=A(c,f.toKey);s&&l&&o.set(s,l)}let i=se(t,f.trailingNewline);return{metadataKeys:r,metadataRenames:o,trailingNewline:typeof i=="boolean"?i:void 0}}function Q(t,e,n){let r=j(t,f.kind);if(!r)throw new v("Expression has no kind",n);let o=r.name;switch(o){case"build-ast-node":return _o(t,e,n);case"for-each":return Ko(t,e,n);case"when":return Po(t,e,n);case"concat":return Eo(t,e,n);case"string-literal":return{kind:"string-literal",value:ce(t,f.stringLiteral,n)};case"integer-literal":return{kind:"integer-literal",value:xo(t,f.integerLiteral,n)};case"boolean-literal":return{kind:"boolean-literal",value:Oo(t,f.booleanLiteral,n)};case"var-ref":return{kind:"var-ref",varName:ce(t,f.varName,n)};case"property-read":return Io(t,e,n);case"traverse":return Ro(t,e,n);case"fallback":return To(t,e,n);case"uri-name":return{kind:"uri-name",of:E(t,f.uriNameOf,e,`${n}.uriNameOf`)};case"list-map":return jo(t,e,n);case"join":return{kind:"join",separator:ce(t,f.separator,n),items:E(t,f.items,e,`${n}.items`)};case"normalize":return Uo(t,e,n);case"is-set":return{kind:"is-set",check:E(t,f.checkExpr,e,`${n}.checkExpr`)};case"uri-literal":{let i=j(t,f.refTo);if(!i)throw new v("uri-literal has no refTo",n);return{kind:"uri-literal",refTo:{publisher:i.publisher,package_:i.package_,name:i.name}}}case"display-label":{let i=j(t,f.labelTarget);if(!i)throw new v("display-label has no labelTarget",n);let a=j(t,f.labelSource);if(!a)throw new v("display-label has no labelSource",n);return{kind:"display-label",labelTarget:{publisher:i.publisher,package_:i.package_,name:i.name},labelSource:{publisher:a.publisher,package_:a.package_,name:a.name}}}case"call-fragment":{if(e.depth>=Nt)throw new v(`call-fragment recursion exceeded ${Nt} levels (cycle?)`,n);let i=j(t,f.fragmentRef);if(!i)throw new v("call-fragment has no fragmentRef",n);let a=$o(e.catalog,i);if(!a)throw new v(`call-fragment: no ExpressionFragment found matching ${i.publisher}/${i.package_}/${i.name} \u2014 either the fragment is missing or its package is not in the compilation catalog`,n);let c=V(a,f.expr);if(!c)throw new v(`ExpressionFragment "${a.name}" has no expr`,n);let s={catalog:e.catalog,depth:e.depth+1};return Q(c,s,`${n}\u2192fragment[${a.name}]`)}default:throw new v(`Unknown ExpressionKind "${o}"`,n)}}function $o(t,e){for(let n of t)if(n instanceof bo&&n.name===e.name&&n.namespace&&n.namespace.startsWith(`${e.publisher}/${e.package_}@`)&&Co(n))return n}function Co(t){for(let e of t.statement){let n=e.predicate;if(!(!n||n.subject?.name!=="type")&&e instanceof We){let r=e.object.subject;if(r.publisher===f.ExpressionFragment.publisher&&r.package_===f.ExpressionFragment.package_&&r.name===f.ExpressionFragment.name)return!0}}return!1}function _o(t,e,n){let r=j(t,f.astClass);if(!r)throw new v("build-ast-node has no astClass",n);let o={publisher:r.publisher,package_:r.package_,name:r.name},i=[];return be(t,f.set).forEach((c,s)=>{let l=`${n}.set[${s}]`,u=j(c,f.field);if(!u)throw new v("AstFieldBinding has no field",l);let p=E(c,f.bindValue,e,`${l}.bindValue`);i.push({field:{publisher:u.publisher,package_:u.package_,name:u.name},value:p})}),{kind:"build-ast-node",astClass:o,set:i}}function Ko(t,e,n){return{kind:"for-each",iterate:E(t,f.iterate,e,`${n}.iterate`),loopVar:ce(t,f.loopVar,n),emit:E(t,f.emit,e,`${n}.emit`)}}function Po(t,e,n){let r=V(t,f.elseBuild);return{kind:"when",condition:E(t,f.condition,e,`${n}.condition`),thenBuild:E(t,f.thenBuild,e,`${n}.thenBuild`),elseBuild:r?Q(r,e,`${n}.elseBuild`):void 0}}function Eo(t,e,n){return{kind:"concat",parts:be(t,f.parts).map((o,i)=>Q(o,e,`${n}.parts[${i}]`))}}function Io(t,e,n){let r=j(t,f.readProp);if(!r)throw new v("property-read has no readProp",n);return{kind:"property-read",source:E(t,f.readSource,e,`${n}.readSource`),readProp:{publisher:r.publisher,package_:r.package_,name:r.name}}}function Ro(t,e,n){let r=j(t,f.through);if(!r)throw new v("traverse has no through",n);return{kind:"traverse",source:E(t,f.traverseSource,e,`${n}.traverseSource`),through:{publisher:r.publisher,package_:r.package_,name:r.name},step:E(t,f.step,e,`${n}.step`)}}function To(t,e,n){return{kind:"fallback",primary:E(t,f.primary,e,`${n}.primary`),alternate:E(t,f.alternate,e,`${n}.alternate`)}}function jo(t,e,n){return{kind:"list-map",source:E(t,f.listMapSource,e,`${n}.listMapSource`),loopVar:ce(t,f.loopVar,n),mapBody:E(t,f.mapBody,e,`${n}.mapBody`)}}function Uo(t,e,n){let r=j(t,f.normKind);if(!r)throw new v("normalize has no normKind",n);let o=r.name;if(o!=="trim-end")throw new v(`Unknown NormalizeKind "${o}"`,n);return{kind:"normalize",source:E(t,f.normSource,e,`${n}.normSource`),normKind:o}}function E(t,e,n,r){let o=V(t,e);if(!o)throw new v("missing child expression",r);return Q(o,n,r)}function ce(t,e,n){let r=A(t,e);if(typeof r!="string")throw new v(`missing required string property "${e.name}"`,n);return r}function xo(t,e,n){let r=se(t,e);if(typeof r!="number")throw new v(`missing required integer property "${e.name}"`,n);return r}function Oo(t,e,n){let r=se(t,e);if(typeof r!="boolean")throw new v(`missing required boolean property "${e.name}"`,n);return r}function Ht(t,e){return t.publisher===e.publisher&&t.package_===e.package_&&t.name===e.name}var we=class{backendUri="kanonak.org/transformations/backend/markdown-with-frontmatter";render(e,n){let r=Lo(e.metadata,n),o=Mo(e.children),a=["---",...r,"---","",o].join(`
|
|
66
|
-
`);return n?.trailingNewline&&(a.endsWith(`
|
|
67
|
-
`)||(a+=`
|
|
68
|
-
`)),a}};function Lo(t,e){if(!t)return[];let n=new Map;for(let i of t.entries)n.set(i.key,i);let r=e?.metadataKeys??t.entries.map(i=>i.key),o=[];for(let i of r){let a=n.get(i);if(!a)continue;let c=e?.metadataRenames.get(i)??i,s=Gt(a.value,a.escapeHint);s!==void 0&&o.push(`${c}: ${s}`)}return o}function Gt(t,e){switch(t.kind){case"StringScalar":return No(t.stringValue,e);case"IntegerScalar":return String(t.integerValue);case"StructuredList":{let n=[];for(let r of t.items){let o=Gt(r,e);o!==void 0&&n.push(o)}return n.join(", ")}case"StructuredMap":return;default:return}}function No(t,e){return!e||Ht(e,T.ESC_RAW)?t:Ht(e,T.ESC_YAML_SAFE)?Fo(t):t}function Fo(t){return t.includes(`
|
|
58
|
+
${t}`),process.exit(1)}}import{Command as Qr}from"commander";import{KanonakParser as eo,KanonakObjectParser as no,PublisherIndex as to,CredentialStore as ro,createAuthenticatedFetch as oo}from"@kanonak-protocol/sdk";import{readFileSync as Pr,writeFileSync as Er,existsSync as _r}from"fs";import{join as Rr}from"path";import Kn from"js-yaml";import{getGlobalCachePath as Ir}from"@kanonak-protocol/sdk";var Tr=`# This file is generated by Kanonak CLI. Do not edit manually.
|
|
59
|
+
`;function Pn(){let n=Ir();return Rr(n,"..","capabilities.lock")}function Y(){let n=Pn();if(!_r(n))return{version:"1",lastUpdated:new Date().toISOString(),capabilities:{}};let e=Pr(n,"utf-8"),t=Kn.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 ze(n){n.lastUpdated=new Date().toISOString();let e={};for(let r of Object.keys(n.capabilities).sort())e[r]=n.capabilities[r];n.capabilities=e;let t=Kn.dump(n,{lineWidth:-1,sortKeys:!1,quotingType:'"'});Er(Pn(),Tr+t,"utf-8")}var D=class{constructor(e,t){this.doc=e;this.broader=t}doc;broader;async getAllDocumentsAsync(){return[this.doc]}async getDocumentAsync(e){return this.broader.getDocumentAsync(e)}async getDocumentsByNamespaceAsync(e,t){return this.broader.getDocumentsByNamespaceAsync(e,t)}async getHighestCompatibleVersionAsync(e,t){return this.broader.getHighestCompatibleVersionAsync(e,t)}async saveDocumentAsync(){throw new Error("SingleDocumentRepository is read-only")}async deleteDocumentAsync(){throw new Error("SingleDocumentRepository is read-only")}async clearNamespaceAsync(){throw new Error("SingleDocumentRepository is read-only")}async getAllDocumentReferencesAsync(){return[]}async getDocumentContentAsync(e){return this.broader.getDocumentContentAsync(e)}async getDocumentUriAsync(e){return this.broader.getDocumentUriAsync(e)}};import{KanonakObjectParser as Fr,EmbeddedKanonak as jn,ReferenceKanonak as xn}from"@kanonak-protocol/sdk";import{SubjectKanonak as En,DefinedKanonak as jr,StringStatement as xr,NumberStatement as Ur,BooleanStatement as Or,ReferenceStatement as _n,EmbeddedStatement as Lr,ListStatement as Nr}from"@kanonak-protocol/sdk";function L(n){return`${n.publisher}/${n.package_}/${n.name}`}function M(n,e){return n.publisher===e.publisher&&n.package_===e.package_&&n.name===e.name}function qe(n,e){if(!(n instanceof jr))return!1;for(let t of n.statement)if(t.predicate?.subject?.name==="type"&&t instanceof _n){let o=t.object;if(M(o.subject,e))return!0}return!1}function A(n,e){let t=[];for(let r of n)r instanceof En&&qe(r,e)&&t.push(r);return t}function ke(n,e){for(let t of n){if(!(t instanceof En)||t.name!==e.name)continue;if((t.namespace||"").startsWith(`${e.publisher}/${e.package_}@`))return t}}function he(n,e){for(let t of n.statement){let r=t.predicate;if(r?.subject&&M(r.subject,e))return t}}function ce(n,e){let t=he(n,e);if(t&&(t instanceof xr||t instanceof Ur||t instanceof Or))return t.object}function C(n,e){let t=ce(n,e);return typeof t=="string"?t:void 0}function B(n,e){let t=he(n,e);if(t instanceof _n)return t.object.subject}function H(n,e){let t=he(n,e);if(t instanceof Lr)return t.object}function Z(n,e){let t=he(n,e);return t instanceof Nr?t.object??[]:[]}var P="kanonak.org",E="capabilities",Ge={publisher:P,package_:E,name:"Capability"},Mr={publisher:P,package_:E,name:"commandName"},Un={publisher:P,package_:E,name:"description"},Br={publisher:P,package_:E,name:"managesType"},Vr={publisher:P,package_:E,name:"deploymentTarget"},Hr={publisher:P,package_:E,name:"hasCommand"},zr={publisher:P,package_:E,name:"subcommandName"},qr={publisher:P,package_:E,name:"performs"},Gr={publisher:P,package_:E,name:"hasArgument"},Wr={publisher:P,package_:E,name:"argumentName"},Rn={publisher:P,package_:E,name:"isRequired"},In={publisher:P,package_:E,name:"isOption"},Xr={publisher:P,package_:E,name:"defaultValue"};async function On(n,e,t){let r=Y(),o=new Fr,a=[];for(let[s,c]of Object.entries(r.capabilities)){let i=n.get(c.publisher,c.package_,c.version);if(!i){console.error(` WARNING: Cached content missing for capability "${s}" (${c.publisher}/${c.package_}@${c.version})`);continue}try{let l=e.parse(i),u=new D(l,t),d=await o.parseKanonaks(u),m=Jr(d,c.publisher,c.package_,c.version);m?a.push(m):console.error(` WARNING: No Capability instance found in "${s}" (${c.publisher}/${c.package_}@${c.version})`)}catch(l){console.error(` WARNING: Failed to parse capability "${s}": ${l}`)}}return a}function Jr(n,e,t,r){let o=A(n,Ge);if(o.length===0)return;let a=o[0],s=C(a,Mr)??"",c=C(a,Un)??"",i=B(a,Br),l=B(a,Vr),u=[];for(let d of Z(a,Hr)){let m=Yr(d,n);m&&u.push(m)}return{commandName:s,description:c,managesTypeKey:i?L(i):"",deploymentTargetKey:l?L(l):"",commands:u,publisher:e,package_:t,version:r}}function Yr(n,e){let t;if(n instanceof jn)t=n;else if(n instanceof xn){let i=Ln(e,n.subject.publisher,n.subject.package_,n.subject.name);i&&(t=i)}if(!t)return;let r=C(t,zr)??"",o=C(t,Un)??"",a=B(t,qr),s=Z(t,Gr),c=[];for(let i of s){let l=Zr(i,e);l&&c.push(l)}return{subcommandName:r,description:o,arguments:c,actionKey:a?L(a):""}}function Zr(n,e){let t;if(n instanceof jn)t=n;else if(n instanceof xn){let i=Ln(e,n.subject.publisher,n.subject.package_,n.subject.name);i&&(t=i)}if(!t)return;let r=C(t,Wr)??"",o=C(t,Rn)==="true"||Tn(t,Rn)===!0,a=C(t,In)==="true"||Tn(t,In)===!0,s=C(t,Xr),c={argumentName:r,required:o,isOption:a};return s!==void 0&&(c.defaultValue=s),c}function Tn(n,e){for(let t of n.statement){let r=t,o=r.predicate;if(o?.subject&&o.subject.publisher===e.publisher&&o.subject.package_===e.package_&&o.subject.name===e.name)return typeof r.object=="boolean"?r.object:void 0}}function Ln(n,e,t,r){for(let o of n){if(!("name"in o)||!("namespace"in o))continue;let a=o;if(a.name===r&&!(!a.namespace||typeof a.namespace!="string")&&a.namespace.startsWith(`${e}/${t}@`))return o}}var ao={publisher:P,package_:E,name:"commandName"};function Nn(){let n=new Qr("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 so(e)}),n.command("remove <name>").description("Remove an installed capability").action(async e=>{await io(e)}),n.command("list").description("List installed capabilities").action(async()=>{await co()}),n}async function so(n){let e=G(n);e||(console.error(`Invalid package reference: ${n}`),console.error("Expected format: {publisher}/{package}@{version} or {publisher}/{package}"),process.exit(1));let{publisher:t,packageName:r,version:o}=e,a=new U,s=new eo,c=new no,i=new ro,l=oo(i),u=new to({fetchFn:l}),d=o??await u.getHighestVersion(t,r);d||(console.error(`Could not resolve version for ${t}/${r}`),process.exit(1)),console.log(`Installing capability ${t}/${r}@${d}...`);let m=a.get(t,r,d);if(!m){let I=await u.getPackageUrl(t,r,d),fe=await l(I,t);if(!fe.ok)throw new Error(`Failed to fetch ${I} (${fe.status} ${fe.statusText})`);m=await fe.text(),a.put(t,r,d,m)}let k=s.parse(m),g=await T(process.cwd(),s),y=new D(k,g),S=await c.parseKanonaks(y),h=A(S,Ge);h.length===0&&(console.error(`Package ${t}/${r}@${d} does not contain a ${P}/${E}/Capability instance.`),process.exit(1));let $=h[0],w=C($,ao);w||(console.error(`Capability instance in ${t}/${r}@${d} has no commandName property.`),process.exit(1));let K=Y();K.capabilities[w]={publisher:t,package_:r,version:d,resolved:await u.getPackageUrl(t,r,d),integrity:N(m)},ze(K),console.log(`
|
|
60
|
+
Installed capability "${w}".`),console.log(`Run "kanonak ${w} --help" to get started.`)}async function io(n){let e=Y();e.capabilities[n]||(console.error(`Capability "${n}" is not installed.`),process.exit(1));let t=e.capabilities[n];delete e.capabilities[n],ze(e),console.log(`Removed capability "${n}" (${t.publisher}/${t.package_}@${t.version}).`)}async function co(){let n=Y(),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:
|
|
61
|
+
`);for(let[t,r]of e)console.log(` ${t} ${r.publisher}/${r.package_}@${r.version}`)}import{Command as pe}from"commander";import{readFileSync as ua,writeFileSync as da,mkdirSync as pa,existsSync as at,statSync as ma}from"fs";import{join as fa,resolve as ga}from"path";import{KanonakParser as nn,KanonakObjectParser as tn}from"@kanonak-protocol/sdk";var lo="kanonak.org",uo="document-ast",b=n=>({publisher:lo,package_:uo,name:n}),j={Document:b("Document"),Block:b("Block"),Inline:b("Inline"),StructuredValue:b("StructuredValue"),Heading:b("Heading"),Paragraph:b("Paragraph"),RawBlock:b("RawBlock"),Text:b("Text"),StructuredMap:b("StructuredMap"),StructuredEntry:b("StructuredEntry"),StructuredList:b("StructuredList"),StringScalar:b("StringScalar"),IntegerScalar:b("IntegerScalar"),EscapeHint:b("EscapeHint"),MediaType:b("MediaType"),metadata:b("metadata"),children:b("children"),level:b("level"),inlines:b("inlines"),text:b("text"),entries:b("entries"),key:b("key"),value:b("value"),escapeHint:b("escapeHint"),items:b("items"),stringValue:b("stringValue"),integerValue:b("integerValue"),rawContent:b("rawContent"),mediaType:b("mediaType"),mimeType:b("mimeType"),ESC_RAW:b("esc-raw"),ESC_YAML_SAFE:b("esc-yaml-safe"),ESC_TOML_STRING:b("esc-toml-string"),ESC_TOML_MULTILINE:b("esc-toml-multiline"),ESC_JSON:b("esc-json"),TEXT_PLAIN:b("text-plain"),TEXT_MARKDOWN:b("text-markdown"),TEXT_HTML:b("text-html"),APPLICATION_JSON:b("application-json"),TEXT_YAML:b("text-yaml"),IMAGE_SVG_XML:b("image-svg-xml")},po="kanonak.org",mo="transformations",p=n=>({publisher:po,package_:mo,name:n}),f={Transformation:p("Transformation"),InputPattern:p("InputPattern"),Expression:p("Expression"),ExpressionKind:p("ExpressionKind"),ExpressionFragment:p("ExpressionFragment"),AstFieldBinding:p("AstFieldBinding"),OutputFormat:p("OutputFormat"),FormatOverride:p("FormatOverride"),RenameEntry:p("RenameEntry"),Artifact:p("Artifact"),NormalizeKind:p("NormalizeKind"),inputPattern:p("inputPattern"),rule:p("rule"),artifactName:p("artifactName"),outputs:p("outputs"),formatOverrides:p("formatOverrides"),matchesClass:p("matchesClass"),requires:p("requires"),kind:p("kind"),astClass:p("astClass"),set:p("set"),iterate:p("iterate"),loopVar:p("loopVar"),emit:p("emit"),condition:p("condition"),thenBuild:p("thenBuild"),elseBuild:p("elseBuild"),parts:p("parts"),stringLiteral:p("stringLiteral"),integerLiteral:p("integerLiteral"),booleanLiteral:p("booleanLiteral"),varName:p("varName"),readSource:p("readSource"),readProp:p("readProp"),traverseSource:p("traverseSource"),through:p("through"),step:p("step"),primary:p("primary"),alternate:p("alternate"),uriNameOf:p("uriNameOf"),listMapSource:p("listMapSource"),mapBody:p("mapBody"),separator:p("separator"),items:p("items"),normSource:p("normSource"),normKind:p("normKind"),checkExpr:p("checkExpr"),refTo:p("refTo"),fragmentRef:p("fragmentRef"),expr:p("expr"),labelTarget:p("labelTarget"),labelSource:p("labelSource"),field:p("field"),bindValue:p("bindValue"),backendUri:p("backendUri"),formatTarget:p("formatTarget"),metadataKeys:p("metadataKeys"),metadataRenames:p("metadataRenames"),trailingNewline:p("trailingNewline"),fromKey:p("fromKey"),toKey:p("toKey"),KIND_BUILD_AST_NODE:p("build-ast-node"),KIND_FOR_EACH:p("for-each"),KIND_WHEN:p("when"),KIND_CONCAT:p("concat"),KIND_STRING_LITERAL:p("string-literal"),KIND_INTEGER_LITERAL:p("integer-literal"),KIND_BOOLEAN_LITERAL:p("boolean-literal"),KIND_VAR_REF:p("var-ref"),KIND_PROPERTY_READ:p("property-read"),KIND_TRAVERSE:p("traverse"),KIND_FALLBACK:p("fallback"),KIND_URI_NAME:p("uri-name"),KIND_LIST_MAP:p("list-map"),KIND_JOIN:p("join"),KIND_NORMALIZE:p("normalize"),KIND_IS_SET:p("is-set"),KIND_URI_LITERAL:p("uri-literal"),KIND_CALL_FRAGMENT:p("call-fragment"),KIND_DISPLAY_LABEL:p("display-label"),NORM_TRIM_END:p("trim-end"),FMT_MARKDOWN_FRONTMATTER:p("markdown-with-frontmatter"),FMT_TOML:p("toml"),FMT_JSON:p("json"),FMT_PLAIN_MARKDOWN:p("plain-markdown")};import{SubjectKanonak as Fn}from"@kanonak-protocol/sdk";var ye=class{constructor(e,t,r){this.repository=e;this.parser=t;this.objectParser=r}repository;parser;objectParser;cache=new Map;async resolveSubject(e,t){let r=ke(t,e);if(r)return r;let o=`${e.publisher}/${e.package_}`,a=this.cache.get(o);if(!a){let s=await this.repository.getDocumentsByNamespaceAsync(e.publisher,e.package_);if(s.length===0)return;let c=s[0],i=new D(c,this.repository);a=await this.objectParser.parseKanonaks(i),this.cache.set(o,a)}for(let s of a)if(s instanceof Fn&&s.name===e.name&&s.namespace&&s.namespace.startsWith(`${e.publisher}/${e.package_}@`))return s;for(let s of a)if(s instanceof Fn&&s.name===e.name)return s}};import{DefinedKanonak as Mn,ReferenceKanonak as We,StringStatement as fo,NumberStatement as go,BooleanStatement as ko,ReferenceStatement as ho,EmbeddedStatement as yo,ListStatement as bo}from"@kanonak-protocol/sdk";var be=class extends Error{constructor(e){super(e)}},we=class{constructor(e,t){this.resolver=e;this.allKanonaks=t}resolver;allKanonaks;async evaluate(e,t){switch(e.kind){case"var-ref":{if(!t.has(e.varName))throw new be(`Unbound variable "${e.varName}"`);return t.get(e.varName)}case"string-literal":return e.value;case"integer-literal":return e.value;case"boolean-literal":return e.value;case"uri-literal":return{...e.refTo};case"property-read":{let r=await this.evaluate(e.source,t);return r instanceof Mn?Xe(r,e.readProp):void 0}case"traverse":{let r=await this.evaluate(e.source,t);if(!(r instanceof Mn))return;let o=Xe(r,e.through),a;if(o instanceof We?a=o.subject:Array.isArray(o)&&o.length>0&&o[0]instanceof We&&(a=o[0].subject),!a)return;let s=await this.resolver.resolveSubject(a,this.allKanonaks);if(!s)return;let c=new Map(t);return c.set("input",s),this.evaluate(e.step,c)}case"fallback":{let r=await this.evaluate(e.primary,t);return Vn(r)?r:this.evaluate(e.alternate,t)}case"uri-name":{let r=await this.evaluate(e.of,t);return r instanceof We?r.subject.name:So(r)?r.name:void 0}case"list-map":{let r=await this.evaluate(e.source,t),o=Je(r),a=[];for(let s of o){let c=new Map(t);c.set(e.loopVar,s),a.push(await this.evaluate(e.mapBody,c))}return a}case"join":{let r=await this.evaluate(e.items,t),o=Je(r),a=[];for(let s of o)s!=null&&a.push(String(s));return a.join(e.separator)}case"normalize":{let r=await this.evaluate(e.source,t);return typeof r!="string"?r:e.normKind==="trim-end"?r.trimEnd():r}case"is-set":{let r=await this.evaluate(e.check,t);return Vn(r)}case"when":{let r=await this.evaluate(e.condition,t);return wo(r)?this.evaluate(e.thenBuild,t):e.elseBuild?this.evaluate(e.elseBuild,t):void 0}case"concat":{let r=[];for(let o of e.parts){let a=await this.evaluate(o,t);if(a!=null)if(Array.isArray(a))for(let s of a)r.push(s);else r.push(a)}return r}case"for-each":{let r=await this.evaluate(e.iterate,t),o=Je(r),a=[];for(let s of o){let c=new Map(t);c.set(e.loopVar,s);let i=await this.evaluate(e.emit,c);if(i!=null)if(Array.isArray(i))for(let l of i)a.push(l);else a.push(i)}return a}case"build-ast-node":return this.buildAstNode(e,t);case"display-label":{let r={publisher:e.labelTarget.publisher,package_:e.labelTarget.package_,name:e.labelTarget.name},o=await this.resolver.resolveSubject(r,this.allKanonaks);if(o){let a=Xe(o,e.labelSource);if(typeof a=="string"&&a.length>0)return a}return e.labelTarget.name}default:{let r=e;throw new be(`Unhandled expression kind: ${JSON.stringify(r)}`)}}}async buildAstNode(e,t){let r={kind:e.astClass.name};for(let o of e.set){let a=await this.evaluate(o.value,t);if(a==null||Array.isArray(a)&&a.length===0)continue;let s=o.field.name;r[s]=a}return r}};function Xe(n,e){let t=[];for(let o of n.statement){let a=o.predicate;a?.subject&&M(a.subject,e)&&t.push(o)}if(t.length===0)return;if(t.length===1&&t[0]instanceof bo)return t[0].object;if(t.length===1)return Bn(t[0]);let r=[];for(let o of t){let a=Bn(o);a!==void 0&&r.push(a)}return r}function Bn(n){if(n instanceof fo||n instanceof go||n instanceof ko||n instanceof ho||n instanceof yo)return n.object}function Vn(n){return n==null?!1:typeof n=="string"||Array.isArray(n)?n.length>0:!0}function wo(n){return n==null?!1:typeof n=="boolean"?n:typeof n=="string"?n.length>0:typeof n=="number"?n!==0:Array.isArray(n)?n.length>0:!0}function Je(n){return n==null?[]:Array.isArray(n)?n:[n]}function So(n){return n!==null&&typeof n=="object"&&"publisher"in n&&"package_"in n&&"name"in n}import{EmbeddedKanonak as $o,ReferenceKanonak as Ye,SubjectKanonak as vo,ListStatement as zn,StringStatement as Do,ReferenceStatement as Ze}from"@kanonak-protocol/sdk";var v=class extends Error{constructor(t,r){super(`${t} (at ${r})`);this.path=r}path},Hn=16;function Ao(n){return n.predicate?.subject}function qn(n,e){let t=[];for(let r of n.statement){let o=Ao(r);o&&M(o,e)&&t.push(r)}return t}function x(n,e){let t=B(n,e);if(t)return t;let r=Z(n,e);if(r.length===1&&r[0]instanceof Ye)return r[0].subject}function Se(n,e){let t=Z(n,e),r=[];for(let o of t)o instanceof $o&&r.push(o);return r}function Gn(n,e){let t=[];for(let r of qn(n,e))if(r instanceof Do)t.push(r.object);else if(r instanceof zn)for(let o of r.object)typeof o=="string"?t.push(o):o instanceof Ye&&t.push(o.subject.name);else r instanceof Ze&&t.push(r.object.subject.name);return t}function Co(n,e){let t=n.split("/");if(t.length<3)throw new v(`Invalid property URI "${n}" \u2014 expected publisher/package/name`,e);let[r,o,...a]=t;return{publisher:r,package_:o,name:a.join("/")}}function ee(n,e){let t=n.name,r=`transformation[${t}]`,o={catalog:e,depth:0},a=H(n,f.inputPattern);if(!a)throw new v("Transformation has no inputPattern",r);let s=Ko(a,o,`${r}.inputPattern`),c=H(n,f.rule);if(!c)throw new v("Transformation has no rule",r);let i=Q(c,o,`${r}.rule`),l=H(n,f.artifactName);if(!l)throw new v("Transformation has no artifactName",r);let u=Q(l,o,`${r}.artifactName`),d=new Set;for(let k of qn(n,f.outputs))if(k instanceof Ze)d.add(k.object.subject.name);else if(k instanceof zn)for(let g of k.object)g instanceof Ye&&d.add(g.subject.name);if(d.size===0)throw new v("Transformation has no outputs",r);let m=new Map;for(let k of Se(n,f.formatOverrides)){let g=`${r}.formatOverrides[]`,y=x(k,f.formatTarget);if(!y)throw new v("FormatOverride missing formatTarget",g);m.set(y.name,Po(k,g))}return{name:t,inputPattern:s,rule:i,artifactName:u,outputs:d,overrides:m}}function Ko(n,e,t){let r=x(n,f.matchesClass);if(!r)throw new v("InputPattern has no matchesClass",t);let o={publisher:r.publisher,package_:r.package_,name:r.name},s=Gn(n,f.requires).map((c,i)=>Co(c,`${t}.requires[${i}]`));return{matchesClass:o,requires:s}}function Po(n,e){let t=Gn(n,f.metadataKeys),r=t.length>0?t:void 0,o=new Map;for(let c of Se(n,f.metadataRenames)){let i=C(c,f.fromKey),l=C(c,f.toKey);i&&l&&o.set(i,l)}let a=ce(n,f.trailingNewline);return{metadataKeys:r,metadataRenames:o,trailingNewline:typeof a=="boolean"?a:void 0}}function Q(n,e,t){let r=x(n,f.kind);if(!r)throw new v("Expression has no kind",t);let o=r.name;switch(o){case"build-ast-node":return Ro(n,e,t);case"for-each":return Io(n,e,t);case"when":return To(n,e,t);case"concat":return jo(n,e,t);case"string-literal":return{kind:"string-literal",value:le(n,f.stringLiteral,t)};case"integer-literal":return{kind:"integer-literal",value:Fo(n,f.integerLiteral,t)};case"boolean-literal":return{kind:"boolean-literal",value:Mo(n,f.booleanLiteral,t)};case"var-ref":return{kind:"var-ref",varName:le(n,f.varName,t)};case"property-read":return xo(n,e,t);case"traverse":return Uo(n,e,t);case"fallback":return Oo(n,e,t);case"uri-name":return{kind:"uri-name",of:_(n,f.uriNameOf,e,`${t}.uriNameOf`)};case"list-map":return Lo(n,e,t);case"join":return{kind:"join",separator:le(n,f.separator,t),items:_(n,f.items,e,`${t}.items`)};case"normalize":return No(n,e,t);case"is-set":return{kind:"is-set",check:_(n,f.checkExpr,e,`${t}.checkExpr`)};case"uri-literal":{let a=x(n,f.refTo);if(!a)throw new v("uri-literal has no refTo",t);return{kind:"uri-literal",refTo:{publisher:a.publisher,package_:a.package_,name:a.name}}}case"display-label":{let a=x(n,f.labelTarget);if(!a)throw new v("display-label has no labelTarget",t);let s=x(n,f.labelSource);if(!s)throw new v("display-label has no labelSource",t);return{kind:"display-label",labelTarget:{publisher:a.publisher,package_:a.package_,name:a.name},labelSource:{publisher:s.publisher,package_:s.package_,name:s.name}}}case"call-fragment":{if(e.depth>=Hn)throw new v(`call-fragment recursion exceeded ${Hn} levels (cycle?)`,t);let a=x(n,f.fragmentRef);if(!a)throw new v("call-fragment has no fragmentRef",t);let s=Eo(e.catalog,a);if(!s)throw new v(`call-fragment: no ExpressionFragment found matching ${a.publisher}/${a.package_}/${a.name} \u2014 either the fragment is missing or its package is not in the compilation catalog`,t);let c=H(s,f.expr);if(!c)throw new v(`ExpressionFragment "${s.name}" has no expr`,t);let i={catalog:e.catalog,depth:e.depth+1};return Q(c,i,`${t}\u2192fragment[${s.name}]`)}default:throw new v(`Unknown ExpressionKind "${o}"`,t)}}function Eo(n,e){for(let t of n)if(t instanceof vo&&t.name===e.name&&t.namespace&&t.namespace.startsWith(`${e.publisher}/${e.package_}@`)&&_o(t))return t}function _o(n){for(let e of n.statement){let t=e.predicate;if(!(!t||t.subject?.name!=="type")&&e instanceof Ze){let r=e.object.subject;if(r.publisher===f.ExpressionFragment.publisher&&r.package_===f.ExpressionFragment.package_&&r.name===f.ExpressionFragment.name)return!0}}return!1}function Ro(n,e,t){let r=x(n,f.astClass);if(!r)throw new v("build-ast-node has no astClass",t);let o={publisher:r.publisher,package_:r.package_,name:r.name},a=[];return Se(n,f.set).forEach((c,i)=>{let l=`${t}.set[${i}]`,u=x(c,f.field);if(!u)throw new v("AstFieldBinding has no field",l);let d=_(c,f.bindValue,e,`${l}.bindValue`);a.push({field:{publisher:u.publisher,package_:u.package_,name:u.name},value:d})}),{kind:"build-ast-node",astClass:o,set:a}}function Io(n,e,t){return{kind:"for-each",iterate:_(n,f.iterate,e,`${t}.iterate`),loopVar:le(n,f.loopVar,t),emit:_(n,f.emit,e,`${t}.emit`)}}function To(n,e,t){let r=H(n,f.elseBuild);return{kind:"when",condition:_(n,f.condition,e,`${t}.condition`),thenBuild:_(n,f.thenBuild,e,`${t}.thenBuild`),elseBuild:r?Q(r,e,`${t}.elseBuild`):void 0}}function jo(n,e,t){return{kind:"concat",parts:Se(n,f.parts).map((o,a)=>Q(o,e,`${t}.parts[${a}]`))}}function xo(n,e,t){let r=x(n,f.readProp);if(!r)throw new v("property-read has no readProp",t);return{kind:"property-read",source:_(n,f.readSource,e,`${t}.readSource`),readProp:{publisher:r.publisher,package_:r.package_,name:r.name}}}function Uo(n,e,t){let r=x(n,f.through);if(!r)throw new v("traverse has no through",t);return{kind:"traverse",source:_(n,f.traverseSource,e,`${t}.traverseSource`),through:{publisher:r.publisher,package_:r.package_,name:r.name},step:_(n,f.step,e,`${t}.step`)}}function Oo(n,e,t){return{kind:"fallback",primary:_(n,f.primary,e,`${t}.primary`),alternate:_(n,f.alternate,e,`${t}.alternate`)}}function Lo(n,e,t){return{kind:"list-map",source:_(n,f.listMapSource,e,`${t}.listMapSource`),loopVar:le(n,f.loopVar,t),mapBody:_(n,f.mapBody,e,`${t}.mapBody`)}}function No(n,e,t){let r=x(n,f.normKind);if(!r)throw new v("normalize has no normKind",t);let o=r.name;if(o!=="trim-end")throw new v(`Unknown NormalizeKind "${o}"`,t);return{kind:"normalize",source:_(n,f.normSource,e,`${t}.normSource`),normKind:o}}function _(n,e,t,r){let o=H(n,e);if(!o)throw new v("missing child expression",r);return Q(o,t,r)}function le(n,e,t){let r=C(n,e);if(typeof r!="string")throw new v(`missing required string property "${e.name}"`,t);return r}function Fo(n,e,t){let r=ce(n,e);if(typeof r!="number")throw new v(`missing required integer property "${e.name}"`,t);return r}function Mo(n,e,t){let r=ce(n,e);if(typeof r!="boolean")throw new v(`missing required boolean property "${e.name}"`,t);return r}function Wn(n,e){return n.publisher===e.publisher&&n.package_===e.package_&&n.name===e.name}var $e=class{backendUri="kanonak.org/transformations/backend/markdown-with-frontmatter";render(e,t){let r=Bo(e.metadata,t),o=zo(e.children),s=["---",...r,"---","",o].join(`
|
|
62
|
+
`);return t?.trailingNewline&&(s.endsWith(`
|
|
63
|
+
`)||(s+=`
|
|
64
|
+
`)),s}};function Bo(n,e){if(!n)return[];let t=new Map;for(let a of n.entries)t.set(a.key,a);let r=e?.metadataKeys??n.entries.map(a=>a.key),o=[];for(let a of r){let s=t.get(a);if(!s)continue;let c=e?.metadataRenames.get(a)??a,i=Jn(s.value,s.escapeHint);i!==void 0&&o.push(`${c}: ${i}`)}return o}function Jn(n,e){switch(n.kind){case"StringScalar":return Vo(n.stringValue,e);case"IntegerScalar":return String(n.integerValue);case"StructuredList":{let t=[];for(let r of n.items){let o=Jn(r,e);o!==void 0&&t.push(o)}return t.join(", ")}case"StructuredMap":return;default:return}}function Vo(n,e){return!e||Wn(e,j.ESC_RAW)?n:Wn(e,j.ESC_YAML_SAFE)?Ho(n):n}function Ho(n){return n.includes(`
|
|
69
65
|
`)?`|-
|
|
70
|
-
${
|
|
71
|
-
`).trimEnd()}`:/[:#\[\]{}&*!|>'"%@`,]/.test(
|
|
66
|
+
${n.replace(/\n/g,`
|
|
67
|
+
`).trimEnd()}`:/[:#\[\]{}&*!|>'"%@`,]/.test(n)?`"${n.replace(/\\/g,"\\\\").replace(/"/g,'\\"')}"`:n}function zo(n){let e=[];for(let t of n){let r=qo(t);r&&e.push(r)}return e.join(`
|
|
72
68
|
|
|
73
|
-
`)}function
|
|
74
|
-
`);return
|
|
69
|
+
`)}function qo(n){switch(n.kind){case"Heading":return`${"#".repeat(n.level)} ${Xn(n.inlines)}`;case"Paragraph":return Xn(n.inlines);case"RawBlock":return n.rawContent;default:return""}}function Xn(n){let e=[];for(let t of n)t.kind==="Text"&&e.push(t.text);return e.join("")}function Go(n,e){return n.publisher===e.publisher&&n.package_===e.package_&&n.name===e.name}var ve=class{backendUri="kanonak.org/transformations/backend/toml";render(e,t){let o=Wo(e.metadata,t).join(`
|
|
70
|
+
`);return t?.trailingNewline&&(o.endsWith(`
|
|
75
71
|
`)||(o+=`
|
|
76
|
-
`)),o}};function
|
|
77
|
-
${
|
|
78
|
-
"""`}var De=class{backendUri="kanonak.org/transformations/backend/json";render(e,
|
|
72
|
+
`)),o}};function Wo(n,e){if(!n)return[];let t=new Map;for(let a of n.entries)t.set(a.key,a);let r=e?.metadataKeys??n.entries.map(a=>a.key),o=[];for(let a of r){let s=t.get(a);if(!s)continue;let c=e?.metadataRenames.get(a)??a,i=Yn(s.value,s.escapeHint);i!==void 0&&o.push(`${c} = ${i}`)}return o}function Yn(n,e){switch(n.kind){case"StringScalar":return Xo(n.stringValue,e);case"IntegerScalar":return String(n.integerValue);case"StructuredList":{let t=[];for(let r of n.items){let o=Yn(r,e);o!==void 0&&t.push(o)}return`[${t.join(", ")}]`}case"StructuredMap":return;default:return}}function Xo(n,e){return e&&Go(e,j.ESC_TOML_MULTILINE)?Yo(n):Jo(n)}function Jo(n){return`"${n.replace(/\\/g,"\\\\").replace(/"/g,'\\"').replace(/\n/g,"\\n")}"`}function Yo(n){return`"""
|
|
73
|
+
${n.replace(/"""/g,'\\"\\"\\"')}
|
|
74
|
+
"""`}var De=class{backendUri="kanonak.org/transformations/backend/json";render(e,t){let r=JSON.stringify(e,null,2);return t?.trailingNewline&&!r.endsWith(`
|
|
79
75
|
`)?r+`
|
|
80
|
-
`:r}};function
|
|
76
|
+
`:r}};function Qn(n){let e=n.replace(/\r\n/g,`
|
|
81
77
|
`).split(`
|
|
82
|
-
`),
|
|
83
|
-
`)),
|
|
84
|
-
${
|
|
78
|
+
`),t=[],r=0;for(;r<e.length;){let o=e[r];if(o.trim()===""){r++;continue}let a=/^(\s*)```(\S*)\s*$/.exec(o);if(a){let i=a[2],l=[];for(r++;r<e.length&&!/^(\s*)```\s*$/.test(e[r]);)l.push(e[r]),r++;r++;let u=et(l.join(`
|
|
79
|
+
`)),d=i?` class="language-${nt(i)}"`:"";t.push(`<pre><code${d}>${u}</code></pre>`);continue}let s=/^(#{1,6})\s+(.*)$/.exec(o);if(s){let i=s[1].length,l=ne(s[2].trim());t.push(`<h${i}>${l}</h${i}>`),r++;continue}if(o.includes("|")&&r+1<e.length&&Zn(e[r+1])){let i=Qe(o),l=Zo(e[r+1]);r+=2;let u=[];for(;r<e.length&&e[r].trim()!==""&&e[r].includes("|");)u.push(Qe(e[r])),r++;t.push(Qo(i,l,u));continue}if(/^\s*[-*]\s+/.test(o)){let i=[];for(;r<e.length&&/^\s*[-*]\s+/.test(e[r]);){let l=[e[r].replace(/^\s*[-*]\s+/,"")];for(r++;r<e.length&&e[r].trim()!==""&&!/^\s*[-*]\s+/.test(e[r])&&!/^\s*\d+\.\s+/.test(e[r]);)l.push(e[r]),r++;r<e.length&&e[r].trim()===""&&r++,i.push(`<li>${ne(l.join(" ").trim())}</li>`)}t.push(`<ul>
|
|
80
|
+
${i.join(`
|
|
85
81
|
`)}
|
|
86
|
-
</ul>`);continue}if(/^\s*\d+\.\s+/.test(o)){let
|
|
87
|
-
${
|
|
82
|
+
</ul>`);continue}if(/^\s*\d+\.\s+/.test(o)){let i=[];for(;r<e.length&&/^\s*\d+\.\s+/.test(e[r]);){let l=[e[r].replace(/^\s*\d+\.\s+/,"")];for(r++;r<e.length&&e[r].trim()!==""&&!/^\s*\d+\.\s+/.test(e[r])&&!/^\s*[-*]\s+/.test(e[r]);)l.push(e[r]),r++;r<e.length&&e[r].trim()===""&&r++,i.push(`<li>${ne(l.join(" ").trim())}</li>`)}t.push(`<ol>
|
|
83
|
+
${i.join(`
|
|
88
84
|
`)}
|
|
89
|
-
</ol>`);continue}let c=[o];for(r++;r<e.length&&e[r].trim()!==""&&!/^(#{1,6})\s+/.test(e[r])&&!/^(\s*)```/.test(e[r])&&!/^\s*[-*]\s+/.test(e[r])&&!/^\s*\d+\.\s+/.test(e[r])&&!(e[r].includes("|")&&r+1<e.length&&
|
|
90
|
-
`)}function
|
|
85
|
+
</ol>`);continue}let c=[o];for(r++;r<e.length&&e[r].trim()!==""&&!/^(#{1,6})\s+/.test(e[r])&&!/^(\s*)```/.test(e[r])&&!/^\s*[-*]\s+/.test(e[r])&&!/^\s*\d+\.\s+/.test(e[r])&&!(e[r].includes("|")&&r+1<e.length&&Zn(e[r+1]));)c.push(e[r]),r++;t.push(`<p>${ne(c.join(" "))}</p>`)}return t.join(`
|
|
86
|
+
`)}function Zn(n){return n.includes("-")?/^[\s|:-]+$/.test(n):!1}function Qe(n){let e=n.trim();return e.startsWith("|")&&(e=e.slice(1)),e.endsWith("|")&&(e=e.slice(0,-1)),e.split("|").map(t=>t.trim())}function Zo(n){return Qe(n).map(e=>{let t=e.startsWith(":"),r=e.endsWith(":");return t&&r?"center":r?"right":t?"left":null})}function Qo(n,e,t){let r=s=>{let c=e[s];return c?` style="text-align:${c}"`:""},o=n.map((s,c)=>`<th${r(c)}>${ne(s)}</th>`).join(""),a=t.map(s=>`<tr>${s.map((i,l)=>`<td${r(l)}>${ne(i)}</td>`).join("")}</tr>`).join(`
|
|
91
87
|
`);return`<table>
|
|
92
88
|
<thead><tr>${o}</tr></thead>
|
|
93
89
|
<tbody>
|
|
94
|
-
${
|
|
90
|
+
${a}
|
|
95
91
|
</tbody>
|
|
96
|
-
</table>`}function
|
|
92
|
+
</table>`}function ne(n){let e=et(n);return e=e.replace(/`([^`\n]+)`/g,(t,r)=>`<code>${r}</code>`),e=e.replace(/\[([^\]]+)\]\(([^)\s]+)\)/g,(t,r,o)=>`<a href="${nt(o)}">${r}</a>`),e=e.replace(/\*\*([^*\n]+)\*\*/g,(t,r)=>`<strong>${r}</strong>`),e=e.replace(/(^|[^*])\*([^*\n]+)\*(?!\*)/g,(t,r,o)=>`${r}<em>${o}</em>`),e=e.replace(/(^|[\s(])_([^_\n]+)_(?=[\s).,;:!?]|$)/g,(t,r,o)=>`${r}<em>${o}</em>`),e}function et(n){return n.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""").replace(/'/g,"'")}function nt(n){return n.replace(/"/g,""").replace(/&/g,"&")}function en(n,e){return n.publisher===e.publisher&&n.package_===e.package_&&n.name===e.name}var Ae=class{backendUri="kanonak.org/transformations/backend/html";render(e,t){let r=ea(e.metadata)??"Untitled",o=na(e.metadata,t),a=ta(e.children),s=`<!DOCTYPE html>
|
|
97
93
|
<html lang="en">
|
|
98
94
|
<head>
|
|
99
95
|
<meta charset="utf-8">
|
|
100
|
-
<title>${
|
|
96
|
+
<title>${ue(r)}</title>
|
|
101
97
|
<style>
|
|
102
98
|
body { font-family: -apple-system, Segoe UI, Helvetica, Arial, sans-serif; max-width: 860px; margin: 2rem auto; padding: 0 1rem; color: #222; line-height: 1.55; }
|
|
103
99
|
h1, h2, h3, h4 { line-height: 1.2; }
|
|
@@ -119,20 +115,55 @@ figure.svg-figure svg { max-width: 100%; height: auto; }
|
|
|
119
115
|
</style>
|
|
120
116
|
</head>
|
|
121
117
|
<body>
|
|
122
|
-
${o}${
|
|
118
|
+
${o}${a}
|
|
123
119
|
</body>
|
|
124
120
|
</html>
|
|
125
|
-
`;return
|
|
126
|
-
`)?
|
|
127
|
-
<dd>${
|
|
121
|
+
`;return t?.trailingNewline===!1&&s.endsWith(`
|
|
122
|
+
`)?s.slice(0,-1):s}};function ea(n){if(n){for(let e of n.entries)if((e.key==="title"||e.key==="name")&&e.value.kind==="StringScalar")return e.value.stringValue}}function na(n,e){if(!n||n.entries.length===0)return"";let t=e?.metadataKeys??n.entries.map(a=>a.key),r=new Map(n.entries.map(a=>[a.key,a])),o=[];for(let a of t){let s=r.get(a);if(!s)continue;let c=e?.metadataRenames.get(a)??a,i=rt(s.value);i!==void 0&&o.push(` <dt>${ue(c)}</dt>
|
|
123
|
+
<dd>${i}</dd>`)}return o.length===0?"":`<dl class="metadata">
|
|
128
124
|
${o.join(`
|
|
129
125
|
`)}
|
|
130
126
|
</dl>
|
|
131
|
-
`}function
|
|
132
|
-
`)}function
|
|
133
|
-
${
|
|
134
|
-
</figure>`:`<pre${e?` class="media-${
|
|
127
|
+
`}function rt(n){switch(n.kind){case"StringScalar":return ue(n.stringValue);case"IntegerScalar":return String(n.integerValue);case"StructuredList":{let e=[];for(let t of n.items){let r=rt(t);r!==void 0&&e.push(`<code>${r}</code>`)}return e.join(", ")}case"StructuredMap":return;default:return}}function ta(n){let e=[];for(let t of n){let r=ra(t);r&&e.push(r)}return e.join(`
|
|
128
|
+
`)}function ra(n){switch(n.kind){case"Heading":{let e=Math.max(1,Math.min(6,n.level));return`<h${e}>${tt(n.inlines)}</h${e}>`}case"Paragraph":return`<p>${tt(n.inlines)}</p>`;case"RawBlock":return oa(n);default:return""}}function oa(n){let e=n.mediaType;return e&&en(e,j.TEXT_MARKDOWN)?Qn(n.rawContent):e&&en(e,j.TEXT_HTML)?n.rawContent:e&&en(e,j.IMAGE_SVG_XML)?`<figure class="svg-figure">
|
|
129
|
+
${n.rawContent}
|
|
130
|
+
</figure>`:`<pre${e?` class="media-${aa(e.name)}"`:""}><code>${ue(n.rawContent)}</code></pre>`}function tt(n){let e=[];for(let t of n)t.kind==="Text"&&e.push(ue(t.text));return e.join("")}function ue(n){return n.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""").replace(/'/g,"'")}function aa(n){return n.replace(/"/g,""").replace(/&/g,"&")}function sa(n,e){return n.publisher===e.publisher&&n.package_===e.package_&&n.name===e.name}var Ce=class{backendUri="kanonak.org/transformations/backend/svg";render(e,t){for(let r of e.children)if(r.kind==="RawBlock"&&r.mediaType&&sa(r.mediaType,j.IMAGE_SVG_XML)){let o=r.rawContent;return t?.trailingNewline&&!o.endsWith(`
|
|
135
131
|
`)&&(o+=`
|
|
136
|
-
`),o}return'<svg xmlns="http://www.w3.org/2000/svg" width="1" height="1"/>'}};var te=class extends Error{},
|
|
137
|
-
|
|
138
|
-
|
|
132
|
+
`),o}return'<svg xmlns="http://www.w3.org/2000/svg" width="1" height="1"/>'}};var Ke={"markdown-with-frontmatter":{backendUri:"kanonak.org/transformations/backend/markdown-with-frontmatter",extension:".md"},toml:{backendUri:"kanonak.org/transformations/backend/toml",extension:".toml"},json:{backendUri:"kanonak.org/transformations/backend/json",extension:".json"},"plain-markdown":{backendUri:"kanonak.org/transformations/backend/plain-markdown",extension:".md"},html:{backendUri:"kanonak.org/transformations/backend/html",extension:".html"},svg:{backendUri:"kanonak.org/transformations/backend/svg",extension:".svg"}},te=class extends Error{},V=class{backends=new Map;constructor(){this.register(new $e),this.register(new ve),this.register(new De),this.register(new Ae),this.register(new Ce)}register(e){this.backends.set(e.backendUri,e)}async run(e){let t=e.transformationKanonaks??e.allKanonaks,r=ee(e.transformation,t);if(!r.outputs.has(e.outputFormat))throw new te(`Transformation "${r.name}" does not support output format "${e.outputFormat}". Declared outputs: ${Array.from(r.outputs).join(", ")}`);let o=new ye(e.repository,e.parser,e.objectParser),a=new we(o,e.allKanonaks),s=e.instances.filter(u=>ia(u,r)),c=this.findBackendForFormat(e.outputFormat);if(!c)throw new te(`No backend registered for OutputFormat "${e.outputFormat}".`);let i=r.overrides.get(e.outputFormat),l=[];for(let u of s){let d=new Map;d.set("input",u);let m=await a.evaluate(r.rule,d);if(!la(m))throw new te(`Transformation "${r.name}" rule did not yield a Document for input "${u.name}". Got: ${ot(m)}`);let k=await a.evaluate(r.artifactName,d);if(typeof k!="string")throw new te(`Transformation "${r.name}" artifactName did not yield a string for input "${u.name}". Got: ${ot(k)}`);let g=c.render(m,i);l.push({fileName:k,format:e.outputFormat,content:g,sourceName:u.name})}return l}findBackendForFormat(e){let t=Ke[e];if(t)return this.backends.get(t.backendUri)}};function ia(n,e){if(!qe(n,e.inputPattern.matchesClass))return!1;for(let t of e.inputPattern.requires)if(!ca(n,t))return!1;return!0}function ca(n,e){for(let t of n.statement){let r=t.predicate?.subject;if(r&&M(r,e)){let o=t.object;if(o==null||typeof o=="string"&&o.length===0||Array.isArray(o)&&o.length===0)continue;return!0}}return!1}function la(n){return typeof n=="object"&&n!==null&&n.kind==="Document"&&Array.isArray(n.children)}function ot(n){if(n===void 0)return"undefined";if(n===null)return"null";if(Array.isArray(n))return`array(${n.length})`;if(typeof n=="object"){let e=n.kind;return e?`object(kind=${e})`:"object"}return typeof n}function st(){let n=new pe("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",`
|
|
133
|
+
Examples:
|
|
134
|
+
|
|
135
|
+
# List every Transformation available in the local workspace
|
|
136
|
+
$ kanonak transform list
|
|
137
|
+
|
|
138
|
+
# Inspect a specific transformation's shape
|
|
139
|
+
$ kanonak transform show kanonak.org/skill-to-skill-md/skill-to-skill-md-transformation
|
|
140
|
+
|
|
141
|
+
# Emit SKILL.md files for every Skill in a package
|
|
142
|
+
$ kanonak transform run skill-to-skill-md-transformation \\
|
|
143
|
+
--scope kanonak.org/kanonak-skills \\
|
|
144
|
+
--format markdown-with-frontmatter \\
|
|
145
|
+
--out ./build/skills/
|
|
146
|
+
|
|
147
|
+
# Same input, different visualization \u2014 render each skill as HTML
|
|
148
|
+
$ kanonak transform run kanonak.org/ats-skill-visualizations/skill-to-html-transformation \\
|
|
149
|
+
--scope kanonak.org/kanonak-skills \\
|
|
150
|
+
--format html \\
|
|
151
|
+
--out ./build/html/
|
|
152
|
+
|
|
153
|
+
# Render each skill as a standalone .svg
|
|
154
|
+
$ kanonak transform run kanonak.org/ats-skill-visualizations/skill-panel-transformation \\
|
|
155
|
+
--scope kanonak.org/kanonak-skills \\
|
|
156
|
+
--format svg \\
|
|
157
|
+
--out ./build/svg/
|
|
158
|
+
|
|
159
|
+
# List the registered format backends
|
|
160
|
+
$ kanonak transform formats
|
|
161
|
+
`);return n.addCommand(ka()),n.addCommand(ba()),n.addCommand(Sa()),n.addCommand(va()),n}function ka(){return new pe("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.").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 ha(n,e)}catch(t){console.error(`Error: ${t.message}`),process.exit(1)}})}async function ha(n,e){let t=new nn,r=new tn,o=await T(process.cwd(),t),a=await it(n,o,r),{transformation:s,transformationKanonaks:c}=a;console.log(`Transformation: ${de(s)}`);let i=ee(s,c),l=await Da(e.scope,o,t,r),u=A(l,i.inputPattern.matchesClass);console.log(`Scope: ${e.scope} \u2014 found ${u.length} instance(s) of ${i.inputPattern.matchesClass.publisher}/${i.inputPattern.matchesClass.package_}/${i.inputPattern.matchesClass.name}`),u.length===0&&(console.error("No matching input instances in scope. Check the transformation's inputPattern.matchesClass vs. the scope package."),process.exit(1));let d=ya(i.outputs,e.format);console.log(`Output format: ${d}`);let m=Ke[d];if(!m)throw new Error(`Unknown format "${d}". Run \`kanonak transform formats\` to see what the runner supports.`);let g=await new V().run({transformation:s,instances:u,allKanonaks:l,transformationKanonaks:c,repository:o,parser:t,objectParser:r,outputFormat:d}),y=ga(e.out);pa(y,{recursive:!0});for(let S of g){let h=Ca(S.fileName),$=fa(y,`${h}${m.extension}`);da($,S.content,"utf-8"),console.log(` wrote ${$}`)}console.log(`Done. ${g.length} artifact(s) written to ${y}`)}function ya(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 ba(){return new pe("list").description("Scan the local workspace + cache for every Transformation instance and print a one-line summary per hit.").action(async()=>{try{await wa()}catch(n){console.error(`Error: ${n.message}`),process.exit(1)}})}async function wa(){let n=new nn,e=new tn,t=await T(process.cwd(),n),r=await t.getAllDocumentsAsync(),o=[];for(let a of r)try{let s=new D(a,t),c=await e.parseKanonaks(s),i=A(c,f.Transformation);for(let l of i)o.push(Aa(l,c))}catch{}if(o.length===0){console.log("No Transformation instances found in the current workspace.");return}o.sort((a,s)=>a.uri.localeCompare(s.uri));for(let a of o)console.log(`${a.uri}`),console.log(` matches: ${a.matchesClass}`),console.log(` outputs: ${a.outputs.join(", ")}`)}function Sa(){return new pe("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 $a(n)}catch(e){console.error(`Error: ${e.message}`),process.exit(1)}})}async function $a(n){let e=new nn,t=new tn,r=await T(process.cwd(),e),{transformation:o,transformationKanonaks:a}=await it(n,r,t),s=ee(o,a);if(console.log(`Transformation: ${de(o)}`),console.log(),console.log("Input pattern:"),console.log(` Matches class: ${Pe(s.inputPattern.matchesClass)}`),s.inputPattern.requires.length>0){console.log(" Required properties:");for(let c of s.inputPattern.requires)console.log(` - ${Pe(c)}`)}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[c,i]of s.overrides){if(console.log(` ${c}:`),i.metadataKeys&&console.log(` metadata keys: ${i.metadataKeys.join(", ")}`),i.metadataRenames.size>0){let l=[];for(let[u,d]of i.metadataRenames)l.push(`${u} \u2192 ${d}`);console.log(` metadata renames: ${l.join(", ")}`)}i.trailingNewline!==void 0&&console.log(` trailing newline: ${i.trailingNewline}`)}console.log()}console.log(`Rule root kind: ${s.rule.kind}`),s.rule.kind==="build-ast-node"&&(console.log(`Rule root AST class: ${Pe(s.rule.astClass)}`),console.log(`Rule root bindings: ${s.rule.set.length} field(s)`)),console.log(`Artifact name root kind: ${s.artifactName.kind}`)}function va(){return new pe("formats").description("List the OutputFormat names the runner can serialize to.").action(()=>{console.log("Registered format backends:");let n=Object.entries(Ke).sort(([e],[t])=>e.localeCompare(t));for(let[e,t]of n)console.log(` ${e.padEnd(28)} ${t.extension.padEnd(6)} ${t.backendUri}`)})}async function it(n,e,t){let r,o,a;if(n.includes("/")){let i=n.indexOf("@"),l=n;if(i!==-1){let d=n.indexOf("/",i);if(d===-1)throw new Error(`Transformation URI "${n}" has @version but no trailing /<name>`);l=n.substring(0,i)+n.substring(d)}let u=l.split("/");if(u.length<3)throw new Error(`Invalid transformation URI "${n}" \u2014 expected publisher/package/name or publisher/package@version/name`);r=u[0],o=u[1],a=u.slice(2).join("/")}else a=n;if(r&&o){let i=await e.getDocumentsByNamespaceAsync(r,o);if(i.length===0)throw new Error(`Package ${r}/${o} not found in the local workspace or cache.`);let l=new D(i[0],e),u=await t.parseKanonaks(l),d=ke(u,{publisher:r,package_:o,name:a,version:""});if(!d){let m=A(u,f.Transformation),k=m.find(g=>g.name===a);if(!k)throw new Error(`Transformation "${a}" not found in package ${r}/${o}. Package contains ${m.length} Transformation(s): ${m.map(g=>g.name).join(", ")||"(none)"}`);return{transformation:k,transformationKanonaks:u}}return{transformation:d,transformationKanonaks:u}}let s=await e.getAllDocumentsAsync(),c=[];for(let i of s)try{let l=new D(i,e),u=await t.parseKanonaks(l),d=A(u,f.Transformation);for(let m of d)m.name===a&&c.push({tx:m,kanonaks:u})}catch{}if(c.length===0)throw new Error(`No Transformation named "${a}" found in the workspace. Try \`kanonak transform list\` to see available transformations.`);if(c.length>1){let i=c.map(l=>de(l.tx)).join(`
|
|
162
|
+
`);throw new Error(`Multiple Transformations named "${a}" in the workspace \u2014 disambiguate with a full publisher/package/name URI:
|
|
163
|
+
${i}`)}return{transformation:c[0].tx,transformationKanonaks:c[0].kanonaks}}async function Da(n,e,t,r){if(/^[.\/\\]/.test(n)||/^[A-Za-z]:/.test(n)||n.endsWith(".kan.yml")||at(n)&&ma(n).isFile()){if(!at(n))throw new Error(`Scope file not found: ${n}`);let m=ua(n,"utf-8"),k=t.parse(m),g=new D(k,e);return r.parseKanonaks(g)}let a=n.indexOf("@"),s=a===-1?n:n.substring(0,a),c=s.indexOf("/");if(c===-1)throw new Error(`Invalid scope "${n}" \u2014 expected a file path or publisher/package[@version] URI`);let i=s.substring(0,c),l=s.substring(c+1),u=await e.getDocumentsByNamespaceAsync(i,l);if(u.length===0)throw new Error(`Scope package ${i}/${l} not found in the local workspace or cache.`);let d=new D(u[0],e);return r.parseKanonaks(d)}function Aa(n,e){try{let t=ee(n,e);return{uri:de(n),matchesClass:Pe(t.inputPattern.matchesClass),outputs:Array.from(t.outputs).sort()}}catch(t){return{uri:de(n),matchesClass:`(compile error: ${t.message})`,outputs:[]}}}function de(n){let e=n.namespace||"",t=e.indexOf("@");return`${t===-1?e:e.substring(0,t)}/${n.name}`}function Pe(n){return`${n.publisher}/${n.package_}/${n.name}`}function Ca(n){return n.replace(/[\\/:*?"<>|\s]+/g,"_").replace(/^_+|_+$/g,"")}import{Command as ct}from"commander";function re(n){return`${P}/${E}/${n}`}var rn={[re("fetch-and-deploy")]:(n,e,t,r)=>n.add(e,t[0],r),[re("remove-deployed")]:(n,e,t,r)=>n.remove(e,t[0],r),[re("list-deployed")]:(n,e,t,r)=>n.list(e,r),[re("update-deployed")]:(n,e,t,r)=>n.update(e,t[0],r),[re("search-available")]:(n,e,t,r)=>n.search(e,r),[re("show-info")]:(n,e,t,r)=>n.info(e,t[0],r)};function lt(n,e,t){for(let r of e){let o=new ct(r.commandName).description(r.description.trim());for(let a of r.commands){let s=o.command(Ka(a));s.description(a.description);for(let c of a.arguments)if(c.isOption){let i=c.defaultValue!=null?`--${c.argumentName} [value]`:`--${c.argumentName} <value>`;s.option(i,"",c.defaultValue)}s.action(async(...c)=>{let i=Pa(c);await Ea(t,r,a,c,i)})}n.addCommand(o)}}function Ka(n){let e=n.arguments.filter(t=>!t.isOption).map(t=>t.required?`<${t.argumentName}>`:`[${t.argumentName}]`);return[n.subcommandName,...e].join(" ")}function Pa(n){for(let e=n.length-1;e>=0;e--)if(n[e]&&typeof n[e]=="object"&&!(n[e]instanceof ct))return n[e];return{}}async function Ea(n,e,t,r,o){let a=[];for(let c of r)if(typeof c=="string")a.push(c);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(rn).join(", ")}.`),process.exit(1));let s=rn[t.actionKey];s||(console.error(`Capability subcommand '${t.subcommandName}' references unknown Action '${t.actionKey}'. Known actions: ${Object.keys(rn).join(", ")}.`),process.exit(1)),await s(n,e,a,o)}import{KanonakObjectParser as _a,PublisherIndex as on,PublisherConfigResolver as Ra}from"@kanonak-protocol/sdk";var Ee=class{constructor(e,t,r,o,a,s){this.fileCache=e;this.parser=t;this.publisherIndex=r;this.fetchFn=o;this.handlerRegistry=a;this.repository=s}fileCache;parser;publisherIndex;fetchFn;handlerRegistry;repository;objectParser=new _a;async add(e,t,r){let o=G(t);o||(console.error(`Invalid package reference: ${t}`),console.error("Expected format: {publisher}/{package}@{version} or {publisher}/{package}"),process.exit(1));let{publisher:a,packageName:s,version:c}=o,i=c??await this.publisherIndex.getHighestVersion(a,s);i||(console.error(`Could not resolve version for ${a}/${s}`),process.exit(1));let l=this.fileCache.get(a,s,i);if(!l){let S=await this.publisherIndex.getPackageUrl(a,s,i),h=await this.fetchFn(S,a);if(!h.ok)throw new Error(`Failed to fetch ${S} (${h.status} ${h.statusText})`);l=await h.text(),this.fileCache.put(a,s,i,l)}let u=this.parser.parse(l),d=new D(u,this.repository),m=await this.objectParser.parseKanonaks(d),k=ut(e.managesTypeKey);k||(console.error(`Capability "${e.commandName}" has no resolved managesType.`),process.exit(1));let g=A(m,k);g.length===0&&(console.error(`Package ${a}/${s}@${i} does not contain any ${L(k)} instances.`),process.exit(1));let y=this.handlerRegistry.get(e.deploymentTargetKey);y?await y.deploy({instances:g,allKanonaks:m,repository:this.repository,options:r}):console.log(`Cached ${a}/${s}@${i} (no deployment handler for "${e.deploymentTargetKey}")`)}async remove(e,t,r){await this.requireHandler(e).undeploy(t,{repository:this.repository,options:r})}async list(e,t){let o=await this.requireHandler(e).list({repository:this.repository,options:t}),a=e.managesTypeKey||"managed";if(o.length===0){console.log(`No ${a} instances installed.`);return}console.log(`Installed ${a} instances:
|
|
164
|
+
`);for(let s of o){let c=s.publisher?`${s.publisher}/${s.package_}@${s.version}`:"unmanaged";console.log(` ${s.name} (${c}) ${s.path}`)}}async update(e,t,r){let a=await this.requireHandler(e).list({repository:this.repository,options:r}),s=t?a.filter(i=>i.name===t):a.filter(i=>i.publisher);if(s.length===0){console.log(t?`"${t}" not found.`:"No managed instances to update.");return}let c=0;for(let i of s){let l=await this.publisherIndex.getHighestVersion(i.publisher,i.package_);!l||l===i.version||(console.log(`Updating ${i.name}: ${i.version} \u2192 ${l}`),await this.add(e,`${i.publisher}/${i.package_}@${l}`,r),c++)}console.log(c===0?"All instances are up to date.":`
|
|
165
|
+
Updated ${c} instance(s).`)}async search(e,t){let r=t.publisher??"kanonak.org",o=ut(e.managesTypeKey);if(!o){console.error("Capability has no resolved managesType; nothing to search for.");return}console.log(`Searching ${r} for ${L(o)} instances...
|
|
166
|
+
`);let a=new Ra,s=await a.getConfig(r),c=a.resolveIndexUrl(r,s),i=await this.fetchFn(c,r);if(!i.ok){console.error(`Failed to fetch package index from ${r}.`);return}let l=await i.text(),u=on.parseIndex(l);if(u.size===0){console.error(`No packages found for publisher "${r}".`);return}let d=new Map;for(let[g,y]of u){let S=[...y].sort((h,$)=>{let w=on.parseVersion(h),K=on.parseVersion($);return!w||!K?0:w.major!==K.major?K.major-w.major:w.minor!==K.minor?K.minor-w.minor:K.patch-w.patch});d.set(g,S[0])}let m=[],k=0;for(let[g,y]of d){let S=this.fileCache.get(r,g,y);if(!S)try{let h=await this.publisherIndex.getPackageUrl(r,g,y),$=await this.fetchFn(h,r);if(!$.ok)continue;S=await $.text(),this.fileCache.put(r,g,y,S)}catch{continue}try{let h=this.parser.parse(S),$=new D(h,this.repository),w=await this.objectParser.parseKanonaks($),K=A(w,o);for(let I of K)m.push({publisher:r,package_:g,version:y,subject:I});k++}catch{continue}}if(m.length===0){console.log(`No ${L(o)} instances found across ${k} package(s).`);return}console.log(`Found ${m.length} ${L(o)} instance(s):
|
|
167
|
+
`);for(let g of m)console.log(` ${g.publisher}/${g.package_}@${g.version}`),console.log(` ${g.subject.name}`),console.log()}async info(e,t,r){let s=(await this.requireHandler(e).list({repository:this.repository,options:r})).find(c=>c.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 ut(n){if(!n)return;let e=n.split("/");if(e.length===3)return{publisher:e[0],package_:e[1],name:e[2]}}var _e=class{handlers=new Map;register(e,t){this.handlers.set(e,t)}get(e){return this.handlers.get(e)??null}};import{mkdirSync as Ha,rmSync as za,existsSync as Te,readdirSync as qa,writeFileSync as Ga}from"fs";import{join as je}from"path";import{KanonakObjectParser as Wa,KanonakParser as Xa}from"@kanonak-protocol/sdk";import{join as an}from"path";import{homedir as dt}from"os";import{KanonakObjectParser as Ia}from"@kanonak-protocol/sdk";var oe="kanonak.org",ae="agent-skills",mt={publisher:oe,package_:ae,name:"Client"},ft={publisher:oe,package_:ae,name:"clientId"},Ta={publisher:oe,package_:ae,name:"projectSkillDir"},ja={publisher:oe,package_:ae,name:"userSkillDir"},xa="agents";async function me(n,e){let t=(n.client??Ua()??xa).toLowerCase(),r=n.scope??"project",o=await Oa(t,e);if(!o){let c=await La(e);throw new Error(`Unknown client "${t}". Known clients: ${c.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=C(o,r==="user"?ja:Ta);if(!s)throw new Error(`Client "${t}" has no ${r==="user"?"userSkillDir":"projectSkillDir"} declared.`);return Na(s)}async function Re(n,e,t){let r=await me(e,t);return an(r,n)}function Ua(){if(process.env.CLAUDE_CODE||process.env.CLAUDE_PROJECT_DIR)return"claude-code"}var pt=new WeakMap;async function gt(n){let e=pt.get(n);if(e)return e;let t=await n.getDocumentsByNamespaceAsync(oe,ae);if(t.length===0)throw new Error(`Could not find ${oe}/${ae} in the repository. Install a skill capability (which transitively imports agent-skills) or fetch agent-skills directly to populate the cache.`);let o=[...t].sort((i,l)=>{let u=i.metadata.namespace_?.version,d=l.metadata.namespace_?.version;return!u||!d?0:u.major!==d.major?d.major-u.major:u.minor!==d.minor?d.minor-u.minor:d.patch-u.patch})[0],a=new Ia,s=new D(o,n),c=await a.parseKanonaks(s);return pt.set(n,c),c}async function Oa(n,e){let t=await gt(e),r=A(t,mt);for(let o of r)if(C(o,ft)===n)return o}async function La(n){let e=await gt(n),t=A(e,mt),r=[];for(let o of t){let a=C(o,ft);a&&r.push(a)}return r}function Na(n){return n.startsWith("~/")?an(dt(),n.slice(2)):n==="~"?dt():n.startsWith("/")||/^[A-Za-z]:[\\/]/.test(n)?n:an(process.cwd(),n)}import{readFileSync as Fa,writeFileSync as Ma,existsSync as Ba}from"fs";import{join as kt}from"path";import ht from"js-yaml";var yt="skills.lock",Va=`# This file is generated by Kanonak CLI. Do not edit manually.
|
|
168
|
+
`;function Ie(n){let e=kt(n,yt);if(!Ba(e))return{version:"1",lastUpdated:new Date().toISOString(),skills:{}};let t=Fa(e,"utf-8"),r=ht.load(t);return!r||typeof r!="object"||r.version!=="1"?{version:"1",lastUpdated:new Date().toISOString(),skills:{}}:{version:"1",lastUpdated:r.lastUpdated??new Date().toISOString(),skills:r.skills??{}}}function sn(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 r=kt(n,yt),o=ht.dump(e,{lineWidth:-1,sortKeys:!1,quotingType:'"'});Ma(r,Va+o,"utf-8")}var bt="kanonak.org",wt="skill-to-skill-md",xe=class{parser=new Xa;objectParser=new Wa;runner=new V;async deploy(e){let{instances:t,allKanonaks:r,repository:o,options:a}=e;if(t.length===0){console.error("No Skill instances to deploy.");return}let s=await Ja(o,this.objectParser);if(!s){console.error(`Cannot deploy: ${bt}/${wt}@1.0.0 is not installed in the workspace or cache.`);return}let c=await this.runner.run({transformation:s,instances:t,allKanonaks:r,repository:o,parser:this.parser,objectParser:this.objectParser,outputFormat:"markdown-with-frontmatter"});if(c.length===0){console.error("No skills could be transformed from the package.");return}let i=await me(a,o),l=Ie(i),u=t[0].namespace,{publisher:d,package_:m,version:k}=Ya(u);for(let g of c){let y=await Re(g.fileName,a,o),S=Te(je(y,"SKILL.md"));Ha(y,{recursive:!0}),Ga(je(y,"SKILL.md"),g.content,"utf-8"),l.skills[g.fileName]={publisher:d,package_:m,version:k,resolved:d?`kanonak://${d}/${m}@${k}`:"",integrity:N(g.content)},console.log(` ${S?"Updated":"Installed"} skill "${g.fileName}" \u2192 ${y}`)}sn(i,l)}async undeploy(e,t){let{repository:r,options:o}=t,a=await Re(e,o,r);Te(a)||(console.error(`Skill "${e}" is not installed at ${a}`),process.exit(1)),za(a,{recursive:!0,force:!0});let s=await me(o,r),c=Ie(s);delete c.skills[e],sn(s,c),console.log(`Removed skill "${e}" from ${a}`)}async list(e){let{repository:t,options:r}=e,o=await me(r,t),a=Ie(o),s=[];for(let[c,i]of Object.entries(a.skills))s.push({name:c,publisher:i.publisher,package_:i.package_,version:i.version,path:await Re(c,r,t)});if(Te(o))try{let c=qa(o,{withFileTypes:!0});for(let i of c){if(!i.isDirectory()||a.skills[i.name])continue;let l=je(o,i.name,"SKILL.md");Te(l)&&s.push({name:i.name,publisher:"",package_:"",version:"",path:je(o,i.name)})}}catch{}return s}};async function Ja(n,e){let t=await n.getDocumentsByNamespaceAsync(bt,wt);if(t.length===0)return;let r=new D(t[0],n),o=await e.parseKanonaks(r);return A(o,f.Transformation)[0]}function Ya(n){if(!n)return{publisher:"",package_:"",version:""};let e=n.indexOf("@");if(e===-1)return{publisher:"",package_:"",version:""};let t=n.substring(0,e),r=n.substring(e+1),o=t.indexOf("/");return o===-1?{publisher:"",package_:"",version:""}:{publisher:t.substring(0,o),package_:t.substring(o+1),version:r}}import{mkdirSync as ds,rmSync as ps,existsSync as ln,readdirSync as ms,writeFileSync as fs,statSync as gs}from"fs";import{join as Le}from"path";import{KanonakObjectParser as ks,KanonakParser as hs}from"@kanonak-protocol/sdk";import{join as St}from"path";import{homedir as $t}from"os";import{KanonakObjectParser as Za}from"@kanonak-protocol/sdk";var z="kanonak.org",q="agent-skills",Dt={publisher:z,package_:q,name:"Client"},At={publisher:z,package_:q,name:"clientId"},Qa={publisher:z,package_:q,name:"projectAgentDir"},es={publisher:z,package_:q,name:"userAgentDir"},ns={publisher:z,package_:q,name:"agentFileFormat"},ts="agents";function rs(){if(process.env.CLAUDE_CODE||process.env.CLAUDE_PROJECT_DIR)return"claude-code"}async function Ue(n,e){let t=(n.client??rs()??ts).toLowerCase(),r=n.scope??"project",o=await os(t,e);if(!o){let u=await as(e);throw new Error(`Unknown client "${t}". Known clients: ${u.join(", ")||"(none)"}. Add a Client instance to a package that imports kanonak.org/agent-skills and install that package to make it available.`)}let s=C(o,r==="user"?es:Qa);if(!s)throw new Error(`Client "${t}" has no ${r==="user"?"userAgentDir":"projectAgentDir"} declared.`);let i=B(o,ns)?.name==="toml"?"toml":"markdown-frontmatter",l=i==="toml"?".toml":".md";return{agentsDir:ss(s),format:i,fileExtension:l}}var vt=new WeakMap;async function Ct(n){let e=vt.get(n);if(e)return e;let t=await n.getDocumentsByNamespaceAsync(z,q);if(t.length===0)throw new Error(`Could not find ${z}/${q} in the repository. Install a capability that imports agent-skills to populate the cache.`);let o=[...t].sort((i,l)=>{let u=i.metadata.namespace_?.version,d=l.metadata.namespace_?.version;return!u||!d?0:u.major!==d.major?d.major-u.major:u.minor!==d.minor?d.minor-u.minor:d.patch-u.patch})[0],a=new Za,s=new D(o,n),c=await a.parseKanonaks(s);return vt.set(n,c),c}async function os(n,e){let t=await Ct(e),r=A(t,Dt);for(let o of r)if(C(o,At)===n)return o}async function as(n){let e=await Ct(n),t=A(e,Dt),r=[];for(let o of t){let a=C(o,At);a&&r.push(a)}return r}function ss(n){return n.startsWith("~/")?St($t(),n.slice(2)):n==="~"?$t():n.startsWith("/")||/^[A-Za-z]:[\\/]/.test(n)?n:St(process.cwd(),n)}import{readFileSync as is,writeFileSync as cs,existsSync as ls}from"fs";import{join as Kt}from"path";import Pt from"js-yaml";var Et="agents.lock",us=`# This file is generated by Kanonak CLI. Do not edit manually.
|
|
169
|
+
`;function Oe(n){let e=Kt(n,Et);if(!ls(e))return{version:"1",lastUpdated:new Date().toISOString(),agents:{}};let t=is(e,"utf-8"),r=Pt.load(t);return!r||typeof r!="object"||r.version!=="1"?{version:"1",lastUpdated:new Date().toISOString(),agents:{}}:{version:"1",lastUpdated:r.lastUpdated??new Date().toISOString(),agents:r.agents??{}}}function cn(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 r=Kt(n,Et),o=Pt.dump(e,{lineWidth:-1,sortKeys:!1,quotingType:'"'});cs(r,us+o,"utf-8")}var _t="kanonak.org",Rt="agent-to-agent-file",Ne=class{parser=new hs;objectParser=new ks;runner=new V;async deploy(e){let{instances:t,allKanonaks:r,repository:o,options:a}=e;if(t.length===0){console.error("No Agent instances to deploy.");return}let{agentsDir:s,format:c,fileExtension:i}=await Ue(a,o),l=await ys(o,this.objectParser);if(!l){console.error(`Cannot deploy: ${_t}/${Rt}@1.0.0 is not installed in the workspace or cache.`);return}let u=c==="toml"?"toml":"markdown-with-frontmatter",d=await this.runner.run({transformation:l,instances:t,allKanonaks:r,repository:o,parser:this.parser,objectParser:this.objectParser,outputFormat:u});if(d.length===0){console.error("No agents could be transformed from the package.");return}ds(s,{recursive:!0});let m=Oe(s),k=t[0].namespace,{publisher:g,package_:y,version:S}=ws(k);for(let h of d){let $=`${h.fileName}${i}`,w=Le(s,$),K=ln(w);fs(w,h.content,"utf-8"),m.agents[h.fileName]={publisher:g,package_:y,version:S,resolved:g?`kanonak://${g}/${y}@${S}`:"",integrity:N(h.content),fileName:$},console.log(` ${K?"Updated":"Installed"} agent "${h.fileName}" \u2192 ${w}`)}cn(s,m)}async undeploy(e,t){let{repository:r,options:o}=t,{agentsDir:a}=await Ue(o,r),s=Oe(a),c=s.agents[e];c||(console.error(`Agent "${e}" is not installed at ${a}`),process.exit(1));let i=Le(a,c.fileName);ln(i)&&ps(i,{force:!0}),delete s.agents[e],cn(a,s),console.log(`Removed agent "${e}" from ${i}`)}async list(e){let{repository:t,options:r}=e,{agentsDir:o}=await Ue(r,t),a=Oe(o),s=[];for(let[c,i]of Object.entries(a.agents))s.push({name:c,publisher:i.publisher,package_:i.package_,version:i.version,path:Le(o,i.fileName)});if(ln(o))try{let c=ms(o,{withFileTypes:!0});for(let i of c){if(!i.isFile()||i.name==="agents.lock")continue;let l=Le(o,i.name),u=bs(i.name);if(!a.agents[u]){try{if(!gs(l).isFile())continue}catch{continue}s.push({name:u,publisher:"",package_:"",version:"",path:l})}}}catch{}return s}};async function ys(n,e){let t=await n.getDocumentsByNamespaceAsync(_t,Rt);if(t.length===0)return;let r=new D(t[0],n),o=await e.parseKanonaks(r);return A(o,f.Transformation)[0]}function bs(n){let e=n.lastIndexOf(".");return e===-1?n:n.substring(0,e)}function ws(n){if(!n)return{publisher:"",package_:"",version:""};let e=n.indexOf("@");if(e===-1)return{publisher:"",package_:"",version:""};let t=n.substring(0,e),r=n.substring(e+1),o=t.indexOf("/");return o===-1?{publisher:"",package_:"",version:""}:{publisher:t.substring(0,o),package_:t.substring(o+1),version:r}}var _s=Ds(vs(import.meta.url)),Rs=JSON.parse($s(As(_s,"..","package.json"),"utf-8")),O=new Ss;O.name("kanonak").description("Kanonak Protocol CLI - Validate and resolve Kanonak ontology packages").version(Rs.version);O.command("validate <path>").description("Validate .kan.yml file(s). Resolves imports via HTTP from publisher domains.").action(async n=>{await fn(n)});O.command("install [package]").description("Install a package and its dependencies, or install all from kanonak.lock.").action(async n=>{await yn(n)});O.command("deps <path>").description("Show resolved dependency tree for a .kan.yml file.").action(async n=>{await wn(n)});O.command("login <publisher>").description("Authenticate with a package publisher using OAuth 2.0.").action(async n=>{await An(n)});O.command("logout <publisher>").description("Revoke tokens and remove stored credentials for a publisher.").action(async n=>{await Cn(n)});O.addCommand(Nn());O.addCommand(st());async function Is(){try{let n=new U,e=new Cs,t=new Ps,r=Es(t),o=new Ks({fetchFn:r}),a=await T(process.cwd(),e),s=new _e;s.register("kanonak.org/capabilities/agent-skill-deployment",new xe),s.register("kanonak.org/agent-capabilities/agent-instance-deployment",new Ne);let c=await On(n,e,a),i=new Ee(n,e,o,r,s,a);lt(O,c,i)}catch{}}await Is();O.parse();
|
|
@@ -27,6 +27,20 @@ export interface Artifact {
|
|
|
27
27
|
/** The source subject this artifact was produced from. */
|
|
28
28
|
sourceName: string;
|
|
29
29
|
}
|
|
30
|
+
/**
|
|
31
|
+
* Metadata about one OutputFormat the runner knows how to serialize:
|
|
32
|
+
* the internal backend URI that resolves to an IDocumentAstBackend,
|
|
33
|
+
* and the filename extension the CLI should append when writing
|
|
34
|
+
* artifacts to disk. Kept alongside the runner so callers (like the
|
|
35
|
+
* `kanonak transform` command) don't have to duplicate this table.
|
|
36
|
+
*/
|
|
37
|
+
export interface FormatDescriptor {
|
|
38
|
+
/** Canonical backend URI (matches IDocumentAstBackend.backendUri). */
|
|
39
|
+
backendUri: string;
|
|
40
|
+
/** Filename extension including the leading dot (e.g. `.md`). */
|
|
41
|
+
extension: string;
|
|
42
|
+
}
|
|
43
|
+
export declare const SUPPORTED_FORMATS: Record<string, FormatDescriptor>;
|
|
30
44
|
export interface RunInput {
|
|
31
45
|
transformation: SubjectKanonak;
|
|
32
46
|
/** Candidate input subjects to run the transformation against. */
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kanonak-protocol/cli",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.7.0",
|
|
4
4
|
"description": "Kanonak Protocol CLI - Validate and resolve Kanonak ontology packages",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -35,8 +35,8 @@
|
|
|
35
35
|
"semantic-web"
|
|
36
36
|
],
|
|
37
37
|
"dependencies": {
|
|
38
|
-
"@kanonak-protocol/sdk": "^1.
|
|
39
|
-
"@kanonak-protocol/types": "^1.
|
|
38
|
+
"@kanonak-protocol/sdk": "^1.7.0",
|
|
39
|
+
"@kanonak-protocol/types": "^1.7.0",
|
|
40
40
|
"commander": "^13.0.0",
|
|
41
41
|
"js-yaml": "^4.1.1"
|
|
42
42
|
},
|