@kanonak-protocol/cli 2.2.0 → 2.4.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.
|
@@ -27,8 +27,41 @@ export declare class GenericCapabilityHandler {
|
|
|
27
27
|
* type. If the parsed reference includes an `instanceName`, only
|
|
28
28
|
* that one instance is deployed; otherwise every matching instance
|
|
29
29
|
* in the package is deployed.
|
|
30
|
+
*
|
|
31
|
+
* Resolution order for `packageRef`:
|
|
32
|
+
* 1. Literal local file path (`./skill.kan.yml`, `C:\…\skill.kan.yml`,
|
|
33
|
+
* or any existing path ending in `.kan.yml`) — read it directly
|
|
34
|
+
* through the SDK parser, no workspace/cache/HTTP lookup.
|
|
35
|
+
* 2. `publisher/package[@version][/instance]` URI — resolved
|
|
36
|
+
* against the workspace + global cache repository tiers first,
|
|
37
|
+
* falling back to the publisher's HTTP origin only when nothing
|
|
38
|
+
* local matches. This makes `<cap> add` work for skills/agents
|
|
39
|
+
* that the user has authored locally and not yet published.
|
|
30
40
|
*/
|
|
31
41
|
add(capability: LoadedCapability, packageRef: string, options: Record<string, string>): Promise<void>;
|
|
42
|
+
/**
|
|
43
|
+
* Try to load `packageRef` as a literal local file path. Recognizes
|
|
44
|
+
* any string that points to an existing file (typically with a
|
|
45
|
+
* `.kan.yml` suffix). Returns `undefined` for anything that doesn't
|
|
46
|
+
* look like a path — the caller falls back to URI-form parsing.
|
|
47
|
+
*
|
|
48
|
+
* Parsing goes through `KanonakParser.parse`; namespace metadata is
|
|
49
|
+
* pulled directly from the parsed document so publisher/package/
|
|
50
|
+
* version come from the file's own declarations rather than any
|
|
51
|
+
* heuristic on the path.
|
|
52
|
+
*/
|
|
53
|
+
private tryLoadFromLocalFile;
|
|
54
|
+
/**
|
|
55
|
+
* Shared deployment path used by both the URI-form `add()` and the
|
|
56
|
+
* local-file-path form. Parses the document through the SDK object
|
|
57
|
+
* model, finds matching instances of the capability's managed type,
|
|
58
|
+
* and dispatches to the deployment handler keyed by deploymentTarget.
|
|
59
|
+
*
|
|
60
|
+
* `description` is the human-readable source label (a package URI
|
|
61
|
+
* or `local file <path>`) used in the user-facing output and error
|
|
62
|
+
* messages — keeping the URI flow's wording stable.
|
|
63
|
+
*/
|
|
64
|
+
private deployFromDoc;
|
|
32
65
|
/**
|
|
33
66
|
* On a "package not found" error, scan the publisher index for
|
|
34
67
|
* approximate name matches and print up to 5 suggestions. Helps
|
package/dist/index.js
CHANGED
|
@@ -1,98 +1,98 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import{Command as
|
|
3
|
-
`).some(r=>r.trim()===t||r.trim()===t+"/"))return;
|
|
2
|
+
import{Command as di}from"commander";import{readFileSync as mi}from"fs";import{fileURLToPath as pi}from"url";import{dirname as fi,join as gi}from"path";import{KanonakParser as hi,PublisherIndex as ki,CredentialStore as yi,createAuthenticatedFetch as bi}from"@kanonak-protocol/sdk";import{readFileSync as lo,statSync as uo}from"fs";import{resolve as mo,dirname as po}from"path";import{KanonakParser as fo,KanonakObjectValidator as go,ValidationSeverity as hn}from"@kanonak-protocol/sdk";import{readFileSync as no,readdirSync as to}from"fs";import{join as oo,dirname as ro,basename as gn}from"path";import{InMemoryKanonakDocumentRepository as ao,FileSystemKanonakDocumentRepository as so,HttpKanonakDocumentRepository as io,getGlobalCachePath as co}from"@kanonak-protocol/sdk";import{mkdirSync as Xt,readFileSync as pn,writeFileSync as fn,existsSync as Ve,appendFileSync as Jt}from"fs";import{join as Yt,dirname as Zt,isAbsolute as Qt}from"path";import{getGlobalCachePath as eo}from"@kanonak-protocol/sdk";var T=class{constructor(e=eo()){this.cacheDir=e;this.isProjectLocal=!Qt(e)}cacheDir;gitignoreChecked=!1;isProjectLocal;get(e,t,o){let r=this.getPath(e,t,o);return Ve(r)?pn(r,"utf-8"):null}put(e,t,o,r){let a=this.getPath(e,t,o);Xt(Zt(a),{recursive:!0}),fn(a,r,"utf-8"),this.isProjectLocal&&this.ensureGitignore()}has(e,t,o){return Ve(this.getPath(e,t,o))}ensureGitignore(){if(this.gitignoreChecked)return;this.gitignoreChecked=!0;let e=".gitignore",t=this.cacheDir;if(Ve(e)){if(pn(e,"utf-8").split(`
|
|
3
|
+
`).some(r=>r.trim()===t||r.trim()===t+"/"))return;Jt(e,`
|
|
4
4
|
${t}/
|
|
5
|
-
`)}else
|
|
6
|
-
`)}getPath(e,t,o){return
|
|
7
|
-
${u}:`);for(let
|
|
8
|
-
${u}:`),console.log(" ERROR: Failed to parse document"),
|
|
9
|
-
${w}:`);for(let $ of f)console.log(` ERROR: ${$.message}`),$.suggestion&&console.log(` -> ${$.suggestion}`);for(let $ of
|
|
10
|
-
${
|
|
11
|
-
Installed ${Object.keys(s.packages).length} package(s) from lock file.`);return}let
|
|
12
|
-
Installed ${
|
|
5
|
+
`)}else fn(e,`${t}/
|
|
6
|
+
`)}getPath(e,t,o){return Yt(this.cacheDir,e,`${t}@${o}.kan.yml`)}};function se(n){let e=n;for(;;){let t=ro(e);if(t===e)break;if(gn(e).includes(".")||gn(t).includes(".")){e=t;continue}break}return e}function ge(n,e){for(let t of to(n,{withFileTypes:!0})){let o=oo(n,t.name);t.isDirectory()&&t.name!=="node_modules"&&t.name!==".kanonak"?ge(o,e):t.name.endsWith(".kan.yml")&&e.push(o)}}var He=class{repos;constructor(...e){this.repos=e}async getHighestCompatibleVersionAsync(e,t){for(let o of this.repos)try{let r=await o.getHighestCompatibleVersionAsync(e,t);if(r)return r}catch{}return null}async getAllDocumentsAsync(){let e=[];for(let t of this.repos)try{e.push(...await t.getAllDocumentsAsync())}catch{}return e}async getDocumentAsync(e){for(let t of this.repos)try{let o=await t.getDocumentAsync(e);if(o)return o}catch{}return null}async getDocumentsByNamespaceAsync(e,t){for(let o of this.repos)try{let r=await o.getDocumentsByNamespaceAsync(e,t);if(r.length>0)return r}catch{}return[]}async saveDocumentAsync(e,t){await this.repos[0].saveDocumentAsync(e,t)}async deleteDocumentAsync(e){await this.repos[0].deleteDocumentAsync(e)}async clearNamespaceAsync(e,t){await this.repos[0].clearNamespaceAsync(e,t)}async getAllDocumentReferencesAsync(){return this.repos[0].getAllDocumentReferencesAsync()}async getDocumentContentAsync(e){for(let t of this.repos)try{let o=await t.getDocumentContentAsync(e);if(o)return o}catch{}return null}async getDocumentUriAsync(e){for(let t of this.repos)try{let o=await t.getDocumentUriAsync(e);if(o)return o}catch{}return null}};async function x(n,e){let t=[];ge(n,t);let o=new ao(e);for(let i of t)try{let c=no(i,"utf-8"),l=e.parse(c),u=l.metadata.namespace_;if(u){let d=`${u.publisher}/${u.package_}@${u.version}`;await o.saveDocumentAsync(l,d)}}catch{}let r=new so(co(),!0,e),a=new T,s=new io({getFromCache:(i,c,l)=>a.get(i,c,l),onFetch:(i,c,l,u)=>a.put(i,c,l,u)});return new He(o,r,s)}async function kn(n){let e=mo(n),t=uo(e),o=t.isDirectory()?se(e):se(po(e)),r=new fo,a=new go(r),s=await x(o,r),i=[];if(t.isDirectory()?ge(e,i):i.push(e),i.length===0){console.log("No .kan.yml files found.");return}let c=0,l=0;for(let u of i){let d=lo(u,"utf-8"),m=r.parseWithErrors(d);if(m.errors&&m.errors.length>0){console.log(`
|
|
7
|
+
${u}:`);for(let y of m.errors)console.log(` ERROR (parse): ${y.message} [line ${y.line}:${y.column}]`),c++;continue}let g=m.document;if(!g){console.log(`
|
|
8
|
+
${u}:`),console.log(" ERROR: Failed to parse document"),c++;continue}let h=await a.validateAsync(g,s),f=h.errors.filter(y=>y.severity===hn.Error),k=h.errors.filter(y=>y.severity===hn.Warning);if(f.length>0||k.length>0){let y=g.metadata.namespace_,w=y?`${y.publisher}/${y.package_}@${y.version}`:u;console.log(`
|
|
9
|
+
${w}:`);for(let $ of f)console.log(` ERROR: ${$.message}`),$.suggestion&&console.log(` -> ${$.suggestion}`);for(let $ of k)console.log(` WARN: ${$.message}`)}c+=f.length,l+=k.length}console.log(`
|
|
10
|
+
${i.length} file(s) validated. ${c} error(s), ${l} warning(s).`),c>0&&process.exit(1)}import{KanonakParser as ho,PublisherIndex as ko,CredentialStore as yo,createAuthenticatedFetch as bo}from"@kanonak-protocol/sdk";import{loadLockFile as wo,saveLockFile as $o,computeIntegrity as So}from"@kanonak-protocol/sdk";function X(n){if(!n)return null;let e=n.indexOf("/");if(e===-1)return null;let t=n.substring(0,e),o=n.substring(e+1);if(!t||!o)return null;let r,a=null,s=null,i=o.indexOf("@");if(i!==-1){r=o.substring(0,i);let c=o.substring(i+1),l=c.indexOf("/");l===-1?a=c||null:(a=c.substring(0,l)||null,s=c.substring(l+1)||null)}else{let c=o.indexOf("/");c===-1?r=o:(r=o.substring(0,c),s=o.substring(c+1)||null)}return!r||s&&s.includes("/")||a&&a.includes("@")?null:{publisher:t,packageName:r,version:a,instanceName:s}}async function yn(n){let e=new T,t=new ho,o=new yo,r=bo(o),a=new ko({fetchFn:r}),s=wo()??{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[h,f]of Object.entries(s.packages)){let k=h.indexOf("/"),y=h.substring(0,k),w=h.substring(k+1),$=e.get(y,w,f.version);if($)console.log(` ${h}@${f.version} (cached)`);else{let v=f.resolved,D=await r(v,y);if(!D.ok)throw new Error(`Failed to fetch ${v} (${D.status} ${D.statusText})`);$=await D.text(),e.put(y,w,f.version,$),console.log(` ${h}@${f.version}`)}}console.log(`
|
|
11
|
+
Installed ${Object.keys(s.packages).length} package(s) from lock file.`);return}let i=X(n);i||(console.error(`Invalid package reference: "${n}"`),console.error("Expected format: {publisher}/{package}[@{version}]"),process.exit(1));let{publisher:c,packageName:l,version:u,instanceName:d}=i;d&&(console.error(`\`kanonak install\` works on whole packages \u2014 got an instance suffix "/${d}".`),console.error(`Try: kanonak install ${c}/${l}${u?"@"+u:""}`),console.error("(Use `kanonak <capability> add` if you want to install one named instance.)"),process.exit(1));let m=u??await a.getHighestVersion(c,l);m||(console.error(`Could not resolve version for "${c}/${l}".`),console.error("Check the spelling, or run a search to see what the publisher offers."),process.exit(1)),console.log(`Installing ${c}/${l}@${m}...`);let g=new Set;await bn(c,l,m,e,t,a,r,g,s),$o(s),console.log(`
|
|
12
|
+
Installed ${g.size} package(s).`)}async function bn(n,e,t,o,r,a,s,i,c){let l=`${n}/${e}@${t}`;if(i.has(l))return;i.add(l);let u=`${n}/${e}`,d=o.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 f=await s(m,n);if(!f.ok)throw new Error(`Failed to fetch ${m} (${f.status} ${f.statusText})`);d=await f.text(),o.put(n,e,t,d),console.log(` ${l}`)}let g={},h=r.parse(d);if(h.metadata.imports)for(let[f,k]of Object.entries(h.metadata.imports))for(let y of k){let w=await a.resolveVersion(f,y);w?(g[`${f}/${y.packageName}`]=w,await bn(f,y.packageName,w,o,r,a,s,i,c)):console.error(` WARNING: Could not resolve ${f}/${y.packageName} ${y.package_}`)}c.packages[u]={version:t,resolved:m,integrity:So(d),dependencies:g}}import{readFileSync as vo}from"fs";import{resolve as Do,dirname as Ko}from"path";import{KanonakParser as Ao}from"@kanonak-protocol/sdk";async function wn(n){let e=Do(n),t=vo(e,"utf-8"),o=new Ao,r=o.parse(t),a=r.metadata.namespace_,s=a?`${a.publisher}/${a.package_}@${a.version}`:n;if(console.log(s),!r.metadata.imports){console.log(" (no imports)");return}let i=se(Ko(e)),c=await x(i,o),l=new Set;for(let[u,d]of Object.entries(r.metadata.imports))for(let m of d)await $n(u,m,c,l," ")}async function $n(n,e,t,o,r){let a=`${n}/${e.packageName}`;if(o.has(a)){console.log(`${r}${a} (${e.package_}) [circular]`);return}o.add(a);let s;try{s=await t.getHighestCompatibleVersionAsync(n,e)}catch{console.log(`${r}${a} (${e.package_}) [fetch failed]`);return}if(!s){console.log(`${r}${a} (${e.package_}) [not found]`);return}let i=s.metadata.namespace_?.version?.toString()??"?";if(console.log(`${r}${n}/${e.packageName}@${i}`),s.metadata.imports)for(let[c,l]of Object.entries(s.metadata.imports))for(let u of l)await $n(c,u,t,o,r+" ")}import{createHash as Po,randomBytes as Dn}from"crypto";import{createServer as Eo}from"http";import{execFile as ze}from"child_process";import{CredentialStore as _o,generateDPoPKeyPair as Io,createDPoPProof as Sn,serverSupportsDPoP as Ro}from"@kanonak-protocol/sdk";import{normalizeHost as Co}from"@kanonak-protocol/sdk";var L=class{cache=new Map;async discover(e){let t=Co(e);if(this.cache.has(t))return this.cache.get(t);let o=`https://${t}/.well-known/oauth-authorization-server`,r=await this.tryEndpoint(o);if(!r){let a=`https://${t}/.well-known/openid-configuration`;r=await this.tryEndpoint(a)}return this.cache.set(t,r),r}async supportsOAuth(e){return await this.discover(e)!==null}static supportsPkceS256(e){return e.codeChallengeMethodsSupported?.some(t=>t.toUpperCase()==="S256")??!1}static supportsDynamicRegistration(e){return!!e.registrationEndpoint}static supportsAuthorizationCode(e){return e.responseTypesSupported?.some(t=>t.toLowerCase()==="code")??!1}async tryEndpoint(e){let t;try{t=await fetch(e)}catch(r){let a=r instanceof Error?r.message:String(r);return a.includes("ENOTFOUND")||a.includes("ECONNREFUSED")?(console.error(` OAuth discovery: ${e} \u2014 host unreachable (${a})`),console.error(" If the server is behind a VPN, ensure you are connected.")):a.includes("CERT")||a.includes("SSL")||a.includes("TLS")?(console.error(` OAuth discovery: ${e} \u2014 TLS error (${a})`),console.error(" If using a custom CA certificate, set NODE_EXTRA_CA_CERTS=/path/to/ca.pem")):console.error(` OAuth discovery: ${e} \u2014 network error: ${a}`),null}if(!t.ok)return t.status===404||(t.status===403?(console.error(` OAuth discovery: ${e} \u2014 HTTP 403 Forbidden`),console.error(" Access may be blocked by a firewall, proxy, or WAF.")):t.status>=500&&(console.error(` OAuth discovery: ${e} \u2014 HTTP ${t.status} server error`),console.error(" The authorization server returned an internal error. Contact your IDP administrator."))),null;let o;try{o=await t.json()}catch{return console.error(` OAuth discovery: ${e} \u2014 response is not valid JSON`),console.error(" The endpoint may be returning HTML instead of JSON. Check IDP configuration."),null}return{issuer:ie(o.issuer),authorizationEndpoint:ie(o.authorization_endpoint),tokenEndpoint:ie(o.token_endpoint),registrationEndpoint:ie(o.registration_endpoint),revocationEndpoint:ie(o.revocation_endpoint),scopesSupported:J(o.scopes_supported),responseTypesSupported:J(o.response_types_supported),grantTypesSupported:J(o.grant_types_supported),codeChallengeMethodsSupported:J(o.code_challenge_methods_supported),tokenEndpointAuthMethodsSupported:J(o.token_endpoint_auth_methods_supported),dpopSigningAlgValuesSupported:J(o.dpop_signing_alg_values_supported)}}};function ie(n){return typeof n=="string"?n:null}function J(n){return Array.isArray(n)?n.filter(e=>typeof e=="string"):null}var Z=class{discovery;credentialStore;constructor(e,t){this.discovery=e??new L,this.credentialStore=t??new _o}async authorize(e,t=[]){console.log(`Starting OAuth flow for ${e}...`);let o=await this.discovery.discover(e);if(!o)return R(`No OAuth discovery endpoint found for '${e}'.
|
|
13
13
|
The server must expose one of:
|
|
14
14
|
- https://${e}/.well-known/oauth-authorization-server (RFC 8414)
|
|
15
15
|
- https://${e}/.well-known/openid-configuration (OpenID Connect)
|
|
16
16
|
Verify the hostname is correct and HTTPS is configured.
|
|
17
17
|
If using a corporate proxy, ensure it is not blocking the discovery request.`);let r=[];if(o.authorizationEndpoint||r.push("authorization_endpoint"),o.tokenEndpoint||r.push("token_endpoint"),r.length>0)return R(`OAuth metadata for '${e}' is missing required fields: ${r.join(", ")}.
|
|
18
|
-
Contact the IDP administrator to ensure these are included in the discovery document.`);let a=
|
|
19
|
-
Ensure your Node.js installation supports EC P-256 curves.`)}}let{redirectUri:
|
|
18
|
+
Contact the IDP administrator to ensure these are included in the discovery document.`);let a=Ro(o.dpopSigningAlgValuesSupported),s=null;if(a){console.log(" Server supports DPoP (RFC 9449) \u2014 generating key pair...");try{s=Io()}catch(D){return R(`Failed to generate DPoP key pair: ${Y(D)}
|
|
19
|
+
Ensure your Node.js installation supports EC P-256 curves.`)}}let{redirectUri:i,port:c,waitForCallback:l,close:u}=await Lo(),d=await this.credentialStore.getCredential(e),m=d?.clientId??null,g=d?.clientSecret??null;if(!m&&o.registrationEndpoint){console.log(" Registering dynamic OAuth client (RFC 7591)...");let D=await this.registerClient(o.registrationEndpoint,i);if(!D.success)return u(),R(D.error);m=D.clientId,g=D.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).
|
|
20
20
|
You must pre-register a client with your IDP and configure the client_id.
|
|
21
21
|
Ask your IDP administrator to enable dynamic client registration (RFC 7591),
|
|
22
|
-
or add a registration_endpoint to the OAuth metadata.`);let
|
|
22
|
+
or add a registration_endpoint to the OAuth metadata.`);let h=xo(),f=jo(h),k=Uo(),y=No(o.authorizationEndpoint,m,i,t,k,f);console.log(` Opening browser for authorization on port ${c}...`),console.log(" If the browser doesn't open, navigate to:"),console.log(` ${y}`),Mo(y);let w=await l();if(u(),!w)return R(`Authorization timed out after 5 minutes.
|
|
23
23
|
The browser authorization was not completed in time.
|
|
24
24
|
Re-run 'kanonak login ${e}' and complete the browser authorization promptly.`);if(!w.code){let D=w.error?`: ${w.error}`:"";return R(`No authorization code received${D}.
|
|
25
25
|
The IDP may have rejected the authorization request.
|
|
26
|
-
Check the IDP admin console for error details.`)}if(w.state!==
|
|
26
|
+
Check the IDP admin console for error details.`)}if(w.state!==k)return R(`Authorization state mismatch \u2014 possible CSRF attack.
|
|
27
27
|
The response did not match the expected session.
|
|
28
|
-
Re-run 'kanonak login ${e}' to start a fresh authorization flow.`);console.log(" Exchanging authorization code for tokens...");let $=await this.exchangeCode(o.tokenEndpoint,m,
|
|
28
|
+
Re-run 'kanonak login ${e}' to start a fresh authorization flow.`);console.log(" Exchanging authorization code for tokens...");let $=await this.exchangeCode(o.tokenEndpoint,m,g,w.code,i,h,s);if(!$.success)return R($.error);let v={clientId:m,clientSecret:g,accessToken:$.tokens.accessToken,refreshToken:$.tokens.refreshToken,expiresAt:$.tokens.expiresIn?new Date(Date.now()+$.tokens.expiresIn*1e3).toISOString():null,tokenEndpoint:o.tokenEndpoint,dpopKeyPair:s};return await this.credentialStore.store(e,v),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}'.
|
|
29
29
|
The authorization server may not issue refresh tokens for this client.
|
|
30
30
|
Run 'kanonak login ${e}' to re-authenticate.`);if(!t.clientId)return R(`No client ID in stored credentials for '${e}'.
|
|
31
31
|
The stored credential may be corrupted. Run 'kanonak logout ${e}' then 'kanonak login ${e}'.`);let o=t.tokenEndpoint;if(!o){let a=await this.discovery.discover(e);if(!a?.tokenEndpoint)return R(`Cannot find token endpoint for '${e}'.
|
|
32
32
|
The OAuth discovery endpoint may be unreachable.
|
|
33
33
|
Check network connectivity and run 'kanonak login ${e}' to re-authenticate.`);o=a.tokenEndpoint}let r=await this.refreshTokenRequest(o,t.clientId,t.clientSecret,t.refreshToken,t.dpopKeyPair);return r.success?(t.accessToken=r.tokens.accessToken,r.tokens.refreshToken&&(t.refreshToken=r.tokens.refreshToken),t.expiresAt=r.tokens.expiresIn?new Date(Date.now()+r.tokens.expiresIn*1e3).toISOString():null,t.tokenEndpoint=o,await this.credentialStore.store(e,t),{success:!0,host:e}):R(`${r.error}
|
|
34
34
|
The refresh token may have expired. Run 'kanonak login ${e}' to re-authenticate.`)}async logout(e){let t=await this.credentialStore.getCredential(e);if(!t)return R(`No stored credentials for '${e}'.
|
|
35
|
-
You may not be logged in, or credentials may be stored in a different backend.`);let o=await this.discovery.discover(e);if(o?.revocationEndpoint&&t.accessToken&&t.clientId)try{await this.revokeToken(o.revocationEndpoint,t.accessToken,t.clientId)}catch{console.warn(` Warning: Token revocation failed for '${e}'. The token has been removed locally but may still be valid on the server until it expires.`)}return await this.credentialStore.remove(e),{success:!0,host:e}}async registerClient(e,t){let o;try{o=await fetch(e,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({client_name:"Kanonak CLI",redirect_uris:[t],grant_types:["authorization_code","refresh_token"],response_types:["code"],token_endpoint_auth_method:"none"})})}catch(s){return{success:!1,error:`Dynamic client registration request to ${e} failed: ${
|
|
35
|
+
You may not be logged in, or credentials may be stored in a different backend.`);let o=await this.discovery.discover(e);if(o?.revocationEndpoint&&t.accessToken&&t.clientId)try{await this.revokeToken(o.revocationEndpoint,t.accessToken,t.clientId)}catch{console.warn(` Warning: Token revocation failed for '${e}'. The token has been removed locally but may still be valid on the server until it expires.`)}return await this.credentialStore.remove(e),{success:!0,host:e}}async registerClient(e,t){let o;try{o=await fetch(e,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({client_name:"Kanonak CLI",redirect_uris:[t],grant_types:["authorization_code","refresh_token"],response_types:["code"],token_endpoint_auth_method:"none"})})}catch(s){return{success:!1,error:`Dynamic client registration request to ${e} failed: ${Y(s)}
|
|
36
36
|
Ensure the IDP is reachable and HTTPS is properly configured.
|
|
37
|
-
If using a corporate proxy or custom CA, set NODE_EXTRA_CA_CERTS.`}}if(!o.ok){let s=await
|
|
37
|
+
If using a corporate proxy or custom CA, set NODE_EXTRA_CA_CERTS.`}}if(!o.ok){let s=await qe(o);return{success:!1,error:`Dynamic client registration (RFC 7591) failed.
|
|
38
38
|
Endpoint: ${e}
|
|
39
39
|
HTTP ${o.status}: ${s}
|
|
40
40
|
The IDP may not support dynamic registration for public clients.
|
|
41
41
|
Ask your IDP administrator to enable RFC 7591 support, or pre-register a client manually.`}}let r=await o.json(),a=r.client_id;return a?{success:!0,clientId:a,clientSecret:r.client_secret}:{success:!1,error:`Dynamic client registration response from ${e} did not contain a client_id.
|
|
42
|
-
The IDP response may be malformed. Contact your IDP administrator.`}}async exchangeCode(e,t,o,r,a,s,
|
|
43
|
-
The stored key pair may be corrupted. Run 'kanonak login' to re-authenticate.`}}let u;try{u=await fetch(e,{method:"POST",headers:l,body:
|
|
44
|
-
Ensure the token endpoint is reachable.`}}if(!u.ok){let d=await
|
|
42
|
+
The IDP response may be malformed. Contact your IDP administrator.`}}async exchangeCode(e,t,o,r,a,s,i){let c=new URLSearchParams({grant_type:"authorization_code",client_id:t,code:r,redirect_uri:a,code_verifier:s});o&&c.set("client_secret",o);let l={"Content-Type":"application/x-www-form-urlencoded"};if(i)try{l.DPoP=Sn(i.privateKey,i.publicKey,"POST",e)}catch(d){return{success:!1,error:`Failed to create DPoP proof for token exchange: ${Y(d)}
|
|
43
|
+
The stored key pair may be corrupted. Run 'kanonak login' to re-authenticate.`}}let u;try{u=await fetch(e,{method:"POST",headers:l,body:c.toString()})}catch(d){return{success:!1,error:`Token exchange request to ${e} failed: ${Y(d)}
|
|
44
|
+
Ensure the token endpoint is reachable.`}}if(!u.ok){let d=await qe(u),m=To(d);return{success:!1,error:`Token exchange failed.
|
|
45
45
|
Endpoint: ${e}
|
|
46
46
|
HTTP ${u.status}: ${d}`+(m?`
|
|
47
|
-
${m}`:"")}}return{success:!0,tokens
|
|
47
|
+
${m}`:"")}}return{success:!0,tokens:vn(await u.json())}}async refreshTokenRequest(e,t,o,r,a){let s=new URLSearchParams({grant_type:"refresh_token",client_id:t,refresh_token:r});o&&s.set("client_secret",o);let i={"Content-Type":"application/x-www-form-urlencoded"};if(a)try{i.DPoP=Sn(a.privateKey,a.publicKey,"POST",e)}catch(l){return{success:!1,error:`Failed to create DPoP proof for token refresh: ${Y(l)}`}}let c;try{c=await fetch(e,{method:"POST",headers:i,body:s.toString()})}catch(l){return{success:!1,error:`Token refresh request to ${e} failed: ${Y(l)}`}}if(!c.ok){let l=await qe(c);return{success:!1,error:`Token refresh failed \u2014 HTTP ${c.status}: ${l}`}}return{success:!0,tokens:vn(await c.json())}}async revokeToken(e,t,o){await fetch(e,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams({token:t,client_id:o}).toString()})}};function 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 Y(n){return n instanceof Error?n.message:String(n)}async function qe(n){try{return await n.text()}catch{return"(could not read response body)"}}function To(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 xo(){return Dn(32).toString("base64url")}function jo(n){return Po("sha256").update(n).digest("base64url")}function Uo(){return Dn(16).toString("base64url")}function No(n,e,t,o,r,a){let s=new URLSearchParams({client_id:e,response_type:"code",redirect_uri:t,scope:o.join(" "),state:r,code_challenge:a,code_challenge_method:"S256"});return`${n}?${s}`}var Oo=300*1e3;async function Lo(){return new Promise(n=>{let e=Eo((r,a)=>{let s=new URL(r.url,"http://localhost"),i=s.searchParams.get("code")??void 0,c=s.searchParams.get("state")??void 0,l=s.searchParams.get("error")??s.searchParams.get("error_description")??void 0,u=l?Fo(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:i,state:c,error:l})}),t,o=new Promise(r=>{t=r,setTimeout(()=>{r(null),e.close()},Oo)});e.listen(0,"127.0.0.1",()=>{let r=e.address();n({redirectUri:`http://localhost:${r.port}/callback`,port:r.port,waitForCallback:()=>o,close:()=>e.close()})})})}function Fo(n){return n.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""")}function Mo(n){try{process.platform==="win32"?ze("cmd",["/c","start","",n]):process.platform==="darwin"?ze("open",[n]):ze("xdg-open",[n])}catch{console.log(" Could not open browser automatically. Please navigate to the URL above manually.")}}import{CredentialStore as Bo}from"@kanonak-protocol/sdk";async function Kn(n){try{let e=new L,t=new Bo,r=await new Z(e,t).authorize(n);r.success?console.log(`
|
|
48
48
|
Authenticated with ${n}.`):(console.error(`
|
|
49
49
|
Authentication failed:
|
|
50
50
|
${r.error}`),process.exit(1))}catch(e){let t=e instanceof Error?e.message:String(e);console.error(`
|
|
51
51
|
Authentication failed unexpectedly:
|
|
52
52
|
${t}`),console.error(`
|
|
53
|
-
If this persists, see https://github.com/kanonak-protocol for support channels.`),process.exit(1)}}import{CredentialStore as
|
|
53
|
+
If this persists, see https://github.com/kanonak-protocol for support channels.`),process.exit(1)}}import{CredentialStore as Vo}from"@kanonak-protocol/sdk";async function An(n){try{let e=new L,t=new Vo,r=await new Z(e,t).logout(n);r.success?console.log(`Logged out from ${n}.`):(console.error(`
|
|
54
54
|
Logout failed:
|
|
55
55
|
${r.error}`),process.exit(1))}catch(e){let t=e instanceof Error?e.message:String(e);console.error(`
|
|
56
56
|
Logout failed unexpectedly:
|
|
57
|
-
${t}`),process.exit(1)}}import{Command as
|
|
58
|
-
`;function
|
|
59
|
-
Installed capability "${v}".`),console.log(`Run "kanonak ${v} --help" to get started.`)}async function
|
|
60
|
-
`);for(let[t,o]of e)console.log(` ${t} ${o.publisher}/${o.package_}@${o.version}`)}import{Command as de}from"commander";import{readFileSync as $a,writeFileSync as Sa,mkdirSync as va,existsSync as rt,statSync as Da}from"fs";import{join as Ka,resolve as Aa}from"path";import{KanonakParser as Qe,KanonakObjectParser as en,SubjectKanonak as Ca,Reasoner as Pa,KanonakVocabulary as Ea,makeUriKey as st,pickHighestDocument as nn,formatVersion as it}from"@kanonak-protocol/sdk";var kr="kanonak.org",yr="document-ast",S=n=>({publisher:kr,package_:yr,name:n}),j={Document:S("Document"),Block:S("Block"),Inline:S("Inline"),StructuredValue:S("StructuredValue"),Heading:S("Heading"),Paragraph:S("Paragraph"),RawBlock:S("RawBlock"),Text:S("Text"),StructuredMap:S("StructuredMap"),StructuredEntry:S("StructuredEntry"),StructuredList:S("StructuredList"),StringScalar:S("StringScalar"),IntegerScalar:S("IntegerScalar"),EscapeHint:S("EscapeHint"),MediaType:S("MediaType"),metadata:S("metadata"),children:S("children"),level:S("level"),inlines:S("inlines"),text:S("text"),entries:S("entries"),key:S("key"),value:S("value"),escapeHint:S("escapeHint"),items:S("items"),stringValue:S("stringValue"),integerValue:S("integerValue"),rawContent:S("rawContent"),mediaType:S("mediaType"),mimeType:S("mimeType"),ESC_RAW:S("esc-raw"),ESC_YAML_SAFE:S("esc-yaml-safe"),ESC_TOML_STRING:S("esc-toml-string"),ESC_TOML_MULTILINE:S("esc-toml-multiline"),ESC_JSON:S("esc-json"),TEXT_PLAIN:S("text-plain"),TEXT_MARKDOWN:S("text-markdown"),TEXT_HTML:S("text-html"),APPLICATION_JSON:S("application-json"),TEXT_YAML:S("text-yaml"),IMAGE_SVG_XML:S("image-svg-xml")},br="kanonak.org",wr="transformations",p=n=>({publisher:br,package_:wr,name:n}),y={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"),resolveSource:p("resolveSource"),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"),KIND_RESOLVE_REF:p("resolve-ref"),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 On}from"@kanonak-protocol/sdk";var ke=class{constructor(e,t,o){this.repository=e;this.parser=t;this.objectParser=o}repository;parser;objectParser;cache=new Map;async resolveSubject(e,t){let o=ge(t,e);if(o)return o;let r=`${e.publisher}/${e.package_}`,a=this.cache.get(r);if(!a){let s=await this.repository.getDocumentsByNamespaceAsync(e.publisher,e.package_);if(s.length===0)return;let c=s[0],i=new A(c,this.repository);a=await this.objectParser.parseKanonaks(i),this.cache.set(r,a)}for(let s of a)if(s instanceof On&&s.name===e.name&&s.namespace&&s.namespace.startsWith(`${e.publisher}/${e.package_}@`))return s;for(let s of a)if(s instanceof On&&s.name===e.name)return s}};import{DefinedKanonak as Ln,LiteralKanonak as $r,ReferenceKanonak as ye,StringStatement as Sr,NumberStatement as vr,BooleanStatement as Dr,ReferenceStatement as Kr,EmbeddedStatement as Ar,ListStatement as Cr}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 o=await this.evaluate(e.source,t);return o instanceof Ln?Ge(o,e.readProp):void 0}case"traverse":{let o=await this.evaluate(e.source,t);if(!(o instanceof Ln))return;let r=Ge(o,e.through),a;if(r instanceof ye?a=r.subject:Array.isArray(r)&&r.length>0&&r[0]instanceof ye&&(a=r[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 o=await this.evaluate(e.primary,t);return Mn(o)?o:this.evaluate(e.alternate,t)}case"uri-name":{let o=await this.evaluate(e.of,t);return o instanceof ye?o.subject.name:Bn(o)?o.name:void 0}case"list-map":{let o=await this.evaluate(e.source,t),r=We(o),a=[];for(let s of r){let c=new Map(t);c.set(e.loopVar,s),a.push(await this.evaluate(e.mapBody,c))}return a}case"join":{let o=await this.evaluate(e.items,t),r=We(o),a=[];for(let s of r)s!=null&&a.push(String(s));return a.join(e.separator)}case"normalize":{let o=await this.evaluate(e.source,t);return typeof o!="string"?o:e.normKind==="trim-end"?o.trimEnd():o}case"is-set":{let o=await this.evaluate(e.check,t);return Mn(o)}case"when":{let o=await this.evaluate(e.condition,t);return Ir(o)?this.evaluate(e.thenBuild,t):e.elseBuild?this.evaluate(e.elseBuild,t):void 0}case"concat":{let o=[];for(let r of e.parts){let a=await this.evaluate(r,t);if(a!=null)if(Array.isArray(a))for(let s of a)o.push(s);else o.push(a)}return o}case"for-each":{let o=await this.evaluate(e.iterate,t),r=We(o),a=[];for(let s of r){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"resolve-ref":{let o=await this.evaluate(e.source,t),r;return o instanceof ye?r=o.subject:Bn(o)&&(r=o),r?this.resolver.resolveSubject(r,this.allKanonaks):void 0}case"display-label":{let o={publisher:e.labelTarget.publisher,package_:e.labelTarget.package_,name:e.labelTarget.name},r=await this.resolver.resolveSubject(o,this.allKanonaks);if(r){let a=Ge(r,e.labelSource);if(typeof a=="string"&&a.length>0)return a}return e.labelTarget.name}default:{let o=e;throw new be(`Unhandled expression kind: ${JSON.stringify(o)}`)}}}async buildAstNode(e,t){let o={kind:e.astClass.name};for(let r of e.set){let a=await this.evaluate(r.value,t);if(a==null||Array.isArray(a)&&a.length===0)continue;let s=r.field.name;Array.isArray(a)&&Pr.has(s)&&a.every(c=>Er(c))&&(a=a.map(c=>String(c)).join("")),o[s]=a}return o}},Pr=new Set(["stringValue","text","rawContent","key"]);function Er(n){return typeof n=="string"||typeof n=="number"||typeof n=="boolean"}function Ge(n,e){let t=[];for(let r of n.statement){let a=r.predicate;a?.subject&&F(a.subject,e)&&t.push(r)}if(t.length===0)return;if(t.length===1&&t[0]instanceof Cr)return _r(t[0].object);if(t.length===1)return Fn(t[0]);let o=[];for(let r of t){let a=Fn(r);a!==void 0&&o.push(a)}return o}function _r(n){let e=[];for(let t of n)t instanceof $r?e.push(t.value):e.push(t);return e}function Fn(n){if(n instanceof Sr||n instanceof vr||n instanceof Dr||n instanceof Kr||n instanceof Ar)return n.object}function Mn(n){return n==null?!1:typeof n=="string"||Array.isArray(n)?n.length>0:!0}function Ir(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 We(n){return n==null?[]:Array.isArray(n)?n:[n]}function Bn(n){return n!==null&&typeof n=="object"&&"publisher"in n&&"package_"in n&&"name"in n}import{EmbeddedKanonak as Rr,LiteralKanonak as Tr,ReferenceKanonak as Xe,SubjectKanonak as xr,ListStatement as Hn,StringStatement as jr,ReferenceStatement as Je}from"@kanonak-protocol/sdk";var K=class extends Error{constructor(t,o){super(`${t} (at ${o})`);this.path=o}path},Vn=16;function Ur(n){return n.predicate?.subject}function zn(n,e){let t=[];for(let o of n.statement){let r=Ur(o);r&&F(r,e)&&t.push(o)}return t}function U(n,e){let t=M(n,e);if(t)return t;let o=Z(n,e);if(o.length===1&&o[0]instanceof Xe)return o[0].subject}function $e(n,e){let t=Z(n,e),o=[];for(let r of t)r instanceof Rr&&o.push(r);return o}function qn(n,e){let t=[];for(let o of zn(n,e))if(o instanceof jr)t.push(o.object);else if(o instanceof Hn)for(let r of o.object)typeof r=="string"?t.push(r):r instanceof Tr?typeof r.value=="string"&&t.push(r.value):r instanceof Xe&&t.push(r.subject.name);else o instanceof Je&&t.push(o.object.subject.name);return t}function Nr(n,e){let t=n.split("/");if(t.length<3)throw new K(`Invalid property URI "${n}" \u2014 expected publisher/package/name`,e);let[o,r,...a]=t;return{publisher:o,package_:r,name:a.join("/")}}function ee(n,e){let t=n.name,o=`transformation[${t}]`,r={catalog:e,depth:0},a=V(n,y.inputPattern);if(!a)throw new K("Transformation has no inputPattern",o);let s=Or(a,r,`${o}.inputPattern`),c=V(n,y.rule);if(!c)throw new K("Transformation has no rule",o);let i=Q(c,r,`${o}.rule`),l=V(n,y.artifactName);if(!l)throw new K("Transformation has no artifactName",o);let u=Q(l,r,`${o}.artifactName`),d=new Set;for(let k of zn(n,y.outputs))if(k instanceof Je)d.add(k.object.subject.name);else if(k instanceof Hn)for(let b of k.object)b instanceof Xe&&d.add(b.subject.name);if(d.size===0)throw new K("Transformation has no outputs",o);let m=new Map;for(let k of $e(n,y.formatOverrides)){let b=`${o}.formatOverrides[]`,f=U(k,y.formatTarget);if(!f)throw new K("FormatOverride missing formatTarget",b);m.set(f.name,Lr(k,b))}return{name:t,inputPattern:s,rule:i,artifactName:u,outputs:d,overrides:m}}function Or(n,e,t){let o=U(n,y.matchesClass);if(!o)throw new K("InputPattern has no matchesClass",t);let r={publisher:o.publisher,package_:o.package_,name:o.name},s=qn(n,y.requires).map((c,i)=>Nr(c,`${t}.requires[${i}]`));return{matchesClass:r,requires:s}}function Lr(n,e){let t=qn(n,y.metadataKeys),o=t.length>0?t:void 0,r=new Map;for(let c of $e(n,y.metadataRenames)){let i=P(c,y.fromKey),l=P(c,y.toKey);i&&l&&r.set(i,l)}let a=ce(n,y.trailingNewline);return{metadataKeys:o,metadataRenames:r,trailingNewline:typeof a=="boolean"?a:void 0}}function Q(n,e,t){let o=U(n,y.kind);if(!o)throw new K("Expression has no kind",t);let r=o.name;switch(r){case"build-ast-node":return Br(n,e,t);case"for-each":return Vr(n,e,t);case"when":return Hr(n,e,t);case"concat":return zr(n,e,t);case"string-literal":return{kind:"string-literal",value:le(n,y.stringLiteral,t)};case"integer-literal":return{kind:"integer-literal",value:Yr(n,y.integerLiteral,t)};case"boolean-literal":return{kind:"boolean-literal",value:Zr(n,y.booleanLiteral,t)};case"var-ref":return{kind:"var-ref",varName:le(n,y.varName,t)};case"property-read":return qr(n,e,t);case"traverse":return Gr(n,e,t);case"fallback":return Wr(n,e,t);case"uri-name":return{kind:"uri-name",of:I(n,y.uriNameOf,e,`${t}.uriNameOf`)};case"list-map":return Xr(n,e,t);case"join":return{kind:"join",separator:le(n,y.separator,t),items:I(n,y.items,e,`${t}.items`)};case"normalize":return Jr(n,e,t);case"is-set":return{kind:"is-set",check:I(n,y.checkExpr,e,`${t}.checkExpr`)};case"uri-literal":{let a=U(n,y.refTo);if(!a)throw new K("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=U(n,y.labelTarget);if(!a)throw new K("display-label has no labelTarget",t);let s=U(n,y.labelSource);if(!s)throw new K("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"resolve-ref":return{kind:"resolve-ref",source:I(n,y.resolveSource,e,`${t}.resolveSource`)};case"call-fragment":{if(e.depth>=Vn)throw new K(`call-fragment recursion exceeded ${Vn} levels (cycle?)`,t);let a=U(n,y.fragmentRef);if(!a)throw new K("call-fragment has no fragmentRef",t);let s=Fr(e.catalog,a);if(!s)throw new K(`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=V(s,y.expr);if(!c)throw new K(`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 K(`Unknown ExpressionKind "${r}"`,t)}}function Fr(n,e){for(let t of n)if(t instanceof xr&&t.name===e.name&&t.namespace&&t.namespace.startsWith(`${e.publisher}/${e.package_}@`)&&Mr(t))return t}function Mr(n){for(let e of n.statement){let t=e.predicate;if(!(!t||t.subject?.name!=="type")&&e instanceof Je){let o=e.object.subject;if(o.publisher===y.ExpressionFragment.publisher&&o.package_===y.ExpressionFragment.package_&&o.name===y.ExpressionFragment.name)return!0}}return!1}function Br(n,e,t){let o=U(n,y.astClass);if(!o)throw new K("build-ast-node has no astClass",t);let r={publisher:o.publisher,package_:o.package_,name:o.name},a=[];return $e(n,y.set).forEach((c,i)=>{let l=`${t}.set[${i}]`,u=U(c,y.field);if(!u)throw new K("AstFieldBinding has no field",l);let d=I(c,y.bindValue,e,`${l}.bindValue`);a.push({field:{publisher:u.publisher,package_:u.package_,name:u.name},value:d})}),{kind:"build-ast-node",astClass:r,set:a}}function Vr(n,e,t){return{kind:"for-each",iterate:I(n,y.iterate,e,`${t}.iterate`),loopVar:le(n,y.loopVar,t),emit:I(n,y.emit,e,`${t}.emit`)}}function Hr(n,e,t){let o=V(n,y.elseBuild);return{kind:"when",condition:I(n,y.condition,e,`${t}.condition`),thenBuild:I(n,y.thenBuild,e,`${t}.thenBuild`),elseBuild:o?Q(o,e,`${t}.elseBuild`):void 0}}function zr(n,e,t){return{kind:"concat",parts:$e(n,y.parts).map((r,a)=>Q(r,e,`${t}.parts[${a}]`))}}function qr(n,e,t){let o=U(n,y.readProp);if(!o)throw new K("property-read has no readProp",t);return{kind:"property-read",source:I(n,y.readSource,e,`${t}.readSource`),readProp:{publisher:o.publisher,package_:o.package_,name:o.name}}}function Gr(n,e,t){let o=U(n,y.through);if(!o)throw new K("traverse has no through",t);return{kind:"traverse",source:I(n,y.traverseSource,e,`${t}.traverseSource`),through:{publisher:o.publisher,package_:o.package_,name:o.name},step:I(n,y.step,e,`${t}.step`)}}function Wr(n,e,t){return{kind:"fallback",primary:I(n,y.primary,e,`${t}.primary`),alternate:I(n,y.alternate,e,`${t}.alternate`)}}function Xr(n,e,t){return{kind:"list-map",source:I(n,y.listMapSource,e,`${t}.listMapSource`),loopVar:le(n,y.loopVar,t),mapBody:I(n,y.mapBody,e,`${t}.mapBody`)}}function Jr(n,e,t){let o=U(n,y.normKind);if(!o)throw new K("normalize has no normKind",t);let r=o.name;if(r!=="trim-end")throw new K(`Unknown NormalizeKind "${r}"`,t);return{kind:"normalize",source:I(n,y.normSource,e,`${t}.normSource`),normKind:r}}function I(n,e,t,o){let r=V(n,e);if(!r){let a=`${e.publisher}/${e.package_}/${e.name}`,s=n.statement.length,c=n.statement.some(u=>{let d=u.predicate?.subject;return d&&d.publisher==="kanonak.org"&&d.package_==="transformations"&&d.name==="kind"}),i=`${e.publisher}/${e.package_}`,l;throw s===0?l=" (parent Expression has no statements at all \u2014 the parser produced an empty node, which usually means the containing YAML block did not resolve to an Expression-typed embedded)":c&&s<3?l=` \u2014 expected property ${a} but the parent Expression only has ${s} statement(s) including its 'kind'. The most likely cause is a STALE local copy of the Kanonak package ${i} that declares the expression kind but not the '${e.name}' property. Refresh your workspace copy of ${i} and re-resolve imports so the runner picks up the current property definitions.`:l=` \u2014 expected property ${a}. Parent Expression has ${s} statement(s) but none match that predicate URI. Either the YAML is missing the '${e.name}' key for this expression kind, or your local copy of the Kanonak package ${i} is out of date.`,new K(`missing child expression${l}`,o)}return Q(r,t,o)}function le(n,e,t){let o=P(n,e);if(typeof o!="string")throw new K(`missing required string property "${e.name}"`,t);return o}function Yr(n,e,t){let o=ce(n,e);if(typeof o!="number")throw new K(`missing required integer property "${e.name}"`,t);return o}function Zr(n,e,t){let o=ce(n,e);if(typeof o!="boolean")throw new K(`missing required boolean property "${e.name}"`,t);return o}function Gn(n,e){return n.publisher===e.publisher&&n.package_===e.package_&&n.name===e.name}var Se=class{backendUri="kanonak.org/transformations/markdown-with-frontmatter";render(e,t){let o=Qr(e.metadata,t),r=ta(e.children),s=["---",...o,"---","",r].join(`
|
|
57
|
+
${t}`),process.exit(1)}}import{Command as wr}from"commander";import{KanonakParser as $r,KanonakObjectParser as Sr,PublisherIndex as vr,CredentialStore as Dr,createAuthenticatedFetch as Kr,computeIntegrity as Ar}from"@kanonak-protocol/sdk";import{readFileSync as Ho,writeFileSync as zo,existsSync as qo}from"fs";import{join as Go}from"path";import Cn from"js-yaml";import{getGlobalCachePath as Wo}from"@kanonak-protocol/sdk";var Xo=`# This file is generated by Kanonak CLI. Do not edit manually.
|
|
58
|
+
`;function Pn(){let n=Wo();return Go(n,"..","capabilities.lock")}function Q(){let n=Pn();if(!qo(n))return{version:"1",lastUpdated:new Date().toISOString(),capabilities:{}};let e=Ho(n,"utf-8"),t=Cn.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 ce(n){n.lastUpdated=new Date().toISOString();let e={};for(let o of Object.keys(n.capabilities).sort())e[o]=n.capabilities[o];n.capabilities=e;let t=Cn.dump(n,{lineWidth:-1,sortKeys:!1,quotingType:'"'});zo(Pn(),Xo+t,"utf-8")}var A=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{existsSync as or,readdirSync as rr,readFileSync as ar}from"fs";import{join as In}from"path";import{KanonakObjectParser as sr,EmbeddedKanonak as jn,ReferenceKanonak as Un,getGlobalCachePath as ir}from"@kanonak-protocol/sdk";import{SubjectKanonak as En,DefinedKanonak as Jo,StringStatement as Yo,NumberStatement as Zo,BooleanStatement as Qo,ReferenceStatement as _n,EmbeddedStatement as er,ListStatement as nr}from"@kanonak-protocol/sdk";function N(n){return`${n.publisher}/${n.package_}/${n.name}`}function F(n,e){return n.publisher===e.publisher&&n.package_===e.package_&&n.name===e.name}function tr(n,e){if(!(n instanceof Jo))return!1;for(let t of n.statement)if(t.predicate?.subject?.name==="type"&&t instanceof _n){let r=t.object;if(F(r.subject,e))return!0}return!1}function P(n,e){let t=[];for(let o of n)o instanceof En&&tr(o,e)&&t.push(o);return t}function he(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 ke(n,e){for(let t of n.statement){let o=t.predicate;if(o?.subject&&F(o.subject,e))return t}}function le(n,e){let t=ke(n,e);if(t&&(t instanceof Yo||t instanceof Zo||t instanceof Qo))return t.object}function C(n,e){let t=le(n,e);return typeof t=="string"?t:void 0}function M(n,e){let t=ke(n,e);if(t instanceof _n)return t.object.subject}function V(n,e){let t=ke(n,e);if(t instanceof er)return t.object}function ee(n,e){let t=ke(n,e);return t instanceof nr?t.object??[]:[]}var E="kanonak.org",_="capabilities",Ge={publisher:E,package_:_,name:"Capability"},cr={publisher:E,package_:_,name:"commandName"},Nn={publisher:E,package_:_,name:"description"},lr={publisher:E,package_:_,name:"managesType"},ur={publisher:E,package_:_,name:"deploymentTarget"},dr={publisher:E,package_:_,name:"hasCommand"},mr={publisher:E,package_:_,name:"subcommandName"},pr={publisher:E,package_:_,name:"performs"},fr={publisher:E,package_:_,name:"hasArgument"},gr={publisher:E,package_:_,name:"argumentName"},Rn={publisher:E,package_:_,name:"isRequired"},Tn={publisher:E,package_:_,name:"isOption"},hr={publisher:E,package_:_,name:"defaultValue"};async function On(n,e,t){let o=Q(),r=new sr,a=[],s=!1;for(let[i,c]of Object.entries(o.capabilities)){let l=c,u=n.get(l.publisher,l.package_,l.version);if(!u){let d=await kr(i,l,e,r,t);if(d)console.error(` Healed capability "${i}": ${l.publisher}/${l.package_}@${l.version} \u2192 ${d.entry.publisher}/${d.entry.package_}@${d.entry.version} (package was renamed)`),o.capabilities[i]=d.entry,l=d.entry,u=d.content,s=!0;else{console.error(` WARNING: Cached content missing for capability "${i}" (${l.publisher}/${l.package_}@${l.version}). Reinstall it with: kanonak capability remove ${i} && kanonak capability add ${l.publisher}/${l.package_}`);continue}}try{let d=e.parse(u),m=new A(d,t),g=await r.parseKanonaks(m),h=Ln(g,l.publisher,l.package_,l.version);h?a.push(h):console.error(` WARNING: No Capability instance found in "${i}" (${l.publisher}/${l.package_}@${l.version})`)}catch(d){console.error(` WARNING: Failed to parse capability "${i}": ${d}`)}}return s&&ce(o),a}async function kr(n,e,t,o,r){let a=In(ir(),e.publisher);if(!or(a))return;let s=[];for(let i of rr(a)){if(!i.endsWith(".kan.yml"))continue;let c=i.slice(0,-8),l=c.lastIndexOf("@");if(l===-1)continue;let u=c.substring(0,l),d=c.substring(l+1);if(u===e.package_&&d===e.version)continue;let m;try{m=ar(In(a,i),"utf-8")}catch{continue}let g;try{let h=t.parse(m),f=new A(h,r),k=await o.parseKanonaks(f);g=Ln(k,e.publisher,u,d)?.commandName}catch{continue}g===n&&s.push({entry:{publisher:e.publisher,package_:u,version:d,resolved:`kanonak://${e.publisher}/${u}@${d}`,integrity:""},content:m})}if(s.length===1)return s[0]}function Ln(n,e,t,o){let r=P(n,Ge);if(r.length===0)return;let a=r[0],s=C(a,cr)??"",i=C(a,Nn)??"",c=M(a,lr),l=M(a,ur),u=[];for(let d of ee(a,dr)){let m=yr(d,n);m&&u.push(m)}return{commandName:s,description:i,managesTypeKey:c?N(c):"",deploymentTargetKey:l?N(l):"",commands:u,publisher:e,package_:t,version:o}}function yr(n,e){let t;if(n instanceof jn)t=n;else if(n instanceof Un){let c=Fn(e,n.subject.publisher,n.subject.package_,n.subject.name);c&&(t=c)}if(!t)return;let o=C(t,mr)??"",r=C(t,Nn)??"",a=M(t,pr),s=ee(t,fr),i=[];for(let c of s){let l=br(c,e);l&&i.push(l)}return{subcommandName:o,description:r,arguments:i,actionKey:a?N(a):""}}function br(n,e){let t;if(n instanceof jn)t=n;else if(n instanceof Un){let c=Fn(e,n.subject.publisher,n.subject.package_,n.subject.name);c&&(t=c)}if(!t)return;let o=C(t,gr)??"",r=C(t,Rn)==="true"||xn(t,Rn)===!0,a=C(t,Tn)==="true"||xn(t,Tn)===!0,s=C(t,hr),i={argumentName:o,required:r,isOption:a};return s!==void 0&&(i.defaultValue=s),i}function xn(n,e){for(let t of n.statement){let o=t,r=o.predicate;if(r?.subject&&r.subject.publisher===e.publisher&&r.subject.package_===e.package_&&r.subject.name===e.name)return typeof o.object=="boolean"?o.object:void 0}}function Fn(n,e,t,o){for(let r of n){if(!("name"in r)||!("namespace"in r))continue;let a=r;if(a.name===o&&!(!a.namespace||typeof a.namespace!="string")&&a.namespace.startsWith(`${e}/${t}@`))return r}}var Cr={publisher:E,package_:_,name:"commandName"};function Mn(){let n=new wr("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 Pr(e)}),n.command("remove <name>").description("Remove an installed capability").action(async e=>{await Er(e)}),n.command("list").description("List installed capabilities").action(async()=>{await _r()}),n}async function Pr(n){let e=X(n);e||(console.error(`Invalid package reference: "${n}"`),console.error("Expected format: {publisher}/{package}[@{version}]"),process.exit(1));let{publisher:t,packageName:o,version:r,instanceName:a}=e;a&&(console.error(`\`kanonak capability add\` installs whole packages \u2014 got an instance suffix "/${a}".`),console.error(`Try: kanonak capability add ${t}/${o}${r?"@"+r:""}`),process.exit(1));let s=new T,i=new $r,c=new Sr,l=new Dr,u=Kr(l),d=new vr({fetchFn:u}),m=r??await d.getHighestVersion(t,o);m||(console.error(`Could not resolve version for "${t}/${o}".`),process.exit(1)),console.log(`Installing capability ${t}/${o}@${m}...`);let g=s.get(t,o,m);if(!g){let W=await d.getPackageUrl(t,o,m),fe=await u(W,t);if(!fe.ok)throw new Error(`Failed to fetch ${W} (${fe.status} ${fe.statusText})`);g=await fe.text(),s.put(t,o,m,g)}let h=i.parse(g),f=await x(process.cwd(),i),k=new A(h,f),y=await c.parseKanonaks(k),w=P(y,Ge);w.length===0&&(console.error(`Package ${t}/${o}@${m} does not contain a ${E}/${_}/Capability instance.`),process.exit(1));let $=w[0],v=C($,Cr);v||(console.error(`Capability instance in ${t}/${o}@${m} has no commandName property.`),process.exit(1));let D=Q();D.capabilities[v]={publisher:t,package_:o,version:m,resolved:await d.getPackageUrl(t,o,m),integrity:Ar(g)},ce(D),console.log(`
|
|
59
|
+
Installed capability "${v}".`),console.log(`Run "kanonak ${v} --help" to get started.`)}async function Er(n){let e=Q();e.capabilities[n]||(console.error(`Capability "${n}" is not installed.`),process.exit(1));let t=e.capabilities[n];delete e.capabilities[n],ce(e),console.log(`Removed capability "${n}" (${t.publisher}/${t.package_}@${t.version}).`)}async function _r(){let n=Q(),e=Object.entries(n.capabilities);if(e.length===0){console.log("No capabilities installed."),console.log("Install one with: kanonak capability add {publisher}/{package}");return}console.log(`Installed capabilities:
|
|
60
|
+
`);for(let[t,o]of e)console.log(` ${t} ${o.publisher}/${o.package_}@${o.version}`)}import{Command as me}from"commander";import{readFileSync as ja,writeFileSync as Ua,mkdirSync as Na,existsSync as ct,statSync as Oa}from"fs";import{join as La,resolve as Fa}from"path";import{KanonakParser as en,KanonakObjectParser as nn,SubjectKanonak as Ma,Reasoner as Ba,KanonakVocabulary as Va,makeUriKey as ut,pickHighestDocument as tn,formatVersion as dt}from"@kanonak-protocol/sdk";var Ir="kanonak.org",Rr="document-ast",S=n=>({publisher:Ir,package_:Rr,name:n}),j={Document:S("Document"),Block:S("Block"),Inline:S("Inline"),StructuredValue:S("StructuredValue"),Heading:S("Heading"),Paragraph:S("Paragraph"),RawBlock:S("RawBlock"),Text:S("Text"),StructuredMap:S("StructuredMap"),StructuredEntry:S("StructuredEntry"),StructuredList:S("StructuredList"),StringScalar:S("StringScalar"),IntegerScalar:S("IntegerScalar"),EscapeHint:S("EscapeHint"),MediaType:S("MediaType"),metadata:S("metadata"),children:S("children"),level:S("level"),inlines:S("inlines"),text:S("text"),entries:S("entries"),key:S("key"),value:S("value"),escapeHint:S("escapeHint"),items:S("items"),stringValue:S("stringValue"),integerValue:S("integerValue"),rawContent:S("rawContent"),mediaType:S("mediaType"),mimeType:S("mimeType"),ESC_RAW:S("esc-raw"),ESC_YAML_SAFE:S("esc-yaml-safe"),ESC_TOML_STRING:S("esc-toml-string"),ESC_TOML_MULTILINE:S("esc-toml-multiline"),ESC_JSON:S("esc-json"),TEXT_PLAIN:S("text-plain"),TEXT_MARKDOWN:S("text-markdown"),TEXT_HTML:S("text-html"),APPLICATION_JSON:S("application-json"),TEXT_YAML:S("text-yaml"),IMAGE_SVG_XML:S("image-svg-xml")},Tr="kanonak.org",xr="transformations",p=n=>({publisher:Tr,package_:xr,name:n}),b={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"),resolveSource:p("resolveSource"),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"),KIND_RESOLVE_REF:p("resolve-ref"),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 Bn}from"@kanonak-protocol/sdk";var ye=class{constructor(e,t,o){this.repository=e;this.parser=t;this.objectParser=o}repository;parser;objectParser;cache=new Map;async resolveSubject(e,t){let o=he(t,e);if(o)return o;let r=`${e.publisher}/${e.package_}`,a=this.cache.get(r);if(!a){let s=await this.repository.getDocumentsByNamespaceAsync(e.publisher,e.package_);if(s.length===0)return;let i=s[0],c=new A(i,this.repository);a=await this.objectParser.parseKanonaks(c),this.cache.set(r,a)}for(let s of a)if(s instanceof Bn&&s.name===e.name&&s.namespace&&s.namespace.startsWith(`${e.publisher}/${e.package_}@`))return s;for(let s of a)if(s instanceof Bn&&s.name===e.name)return s}};import{DefinedKanonak as Vn,LiteralKanonak as jr,ReferenceKanonak as be,StringStatement as Ur,NumberStatement as Nr,BooleanStatement as Or,ReferenceStatement as Lr,EmbeddedStatement as Fr,ListStatement as Mr}from"@kanonak-protocol/sdk";var we=class extends Error{constructor(e){super(e)}},$e=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 we(`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 o=await this.evaluate(e.source,t);return o instanceof Vn?We(o,e.readProp):void 0}case"traverse":{let o=await this.evaluate(e.source,t);if(!(o instanceof Vn))return;let r=We(o,e.through),a;if(r instanceof be?a=r.subject:Array.isArray(r)&&r.length>0&&r[0]instanceof be&&(a=r[0].subject),!a)return;let s=await this.resolver.resolveSubject(a,this.allKanonaks);if(!s)return;let i=new Map(t);return i.set("input",s),this.evaluate(e.step,i)}case"fallback":{let o=await this.evaluate(e.primary,t);return zn(o)?o:this.evaluate(e.alternate,t)}case"uri-name":{let o=await this.evaluate(e.of,t);return o instanceof be?o.subject.name:qn(o)?o.name:void 0}case"list-map":{let o=await this.evaluate(e.source,t),r=Xe(o),a=[];for(let s of r){let i=new Map(t);i.set(e.loopVar,s),a.push(await this.evaluate(e.mapBody,i))}return a}case"join":{let o=await this.evaluate(e.items,t),r=Xe(o),a=[];for(let s of r)s!=null&&a.push(String(s));return a.join(e.separator)}case"normalize":{let o=await this.evaluate(e.source,t);return typeof o!="string"?o:e.normKind==="trim-end"?o.trimEnd():o}case"is-set":{let o=await this.evaluate(e.check,t);return zn(o)}case"when":{let o=await this.evaluate(e.condition,t);return zr(o)?this.evaluate(e.thenBuild,t):e.elseBuild?this.evaluate(e.elseBuild,t):void 0}case"concat":{let o=[];for(let r of e.parts){let a=await this.evaluate(r,t);if(a!=null)if(Array.isArray(a))for(let s of a)o.push(s);else o.push(a)}return o}case"for-each":{let o=await this.evaluate(e.iterate,t),r=Xe(o),a=[];for(let s of r){let i=new Map(t);i.set(e.loopVar,s);let c=await this.evaluate(e.emit,i);if(c!=null)if(Array.isArray(c))for(let l of c)a.push(l);else a.push(c)}return a}case"build-ast-node":return this.buildAstNode(e,t);case"resolve-ref":{let o=await this.evaluate(e.source,t),r;return o instanceof be?r=o.subject:qn(o)&&(r=o),r?this.resolver.resolveSubject(r,this.allKanonaks):void 0}case"display-label":{let o={publisher:e.labelTarget.publisher,package_:e.labelTarget.package_,name:e.labelTarget.name},r=await this.resolver.resolveSubject(o,this.allKanonaks);if(r){let a=We(r,e.labelSource);if(typeof a=="string"&&a.length>0)return a}return e.labelTarget.name}default:{let o=e;throw new we(`Unhandled expression kind: ${JSON.stringify(o)}`)}}}async buildAstNode(e,t){let o={kind:e.astClass.name};for(let r of e.set){let a=await this.evaluate(r.value,t);if(a==null||Array.isArray(a)&&a.length===0)continue;let s=r.field.name;Array.isArray(a)&&Br.has(s)&&a.every(i=>Vr(i))&&(a=a.map(i=>String(i)).join("")),o[s]=a}return o}},Br=new Set(["stringValue","text","rawContent","key"]);function Vr(n){return typeof n=="string"||typeof n=="number"||typeof n=="boolean"}function We(n,e){let t=[];for(let r of n.statement){let a=r.predicate;a?.subject&&F(a.subject,e)&&t.push(r)}if(t.length===0)return;if(t.length===1&&t[0]instanceof Mr)return Hr(t[0].object);if(t.length===1)return Hn(t[0]);let o=[];for(let r of t){let a=Hn(r);a!==void 0&&o.push(a)}return o}function Hr(n){let e=[];for(let t of n)t instanceof jr?e.push(t.value):e.push(t);return e}function Hn(n){if(n instanceof Ur||n instanceof Nr||n instanceof Or||n instanceof Lr||n instanceof Fr)return n.object}function zn(n){return n==null?!1:typeof n=="string"||Array.isArray(n)?n.length>0:!0}function zr(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 Xe(n){return n==null?[]:Array.isArray(n)?n:[n]}function qn(n){return n!==null&&typeof n=="object"&&"publisher"in n&&"package_"in n&&"name"in n}import{EmbeddedKanonak as qr,LiteralKanonak as Gr,ReferenceKanonak as Je,SubjectKanonak as Wr,ListStatement as Wn,StringStatement as Xr,ReferenceStatement as Ye}from"@kanonak-protocol/sdk";var K=class extends Error{constructor(t,o){super(`${t} (at ${o})`);this.path=o}path},Gn=16;function Jr(n){return n.predicate?.subject}function Xn(n,e){let t=[];for(let o of n.statement){let r=Jr(o);r&&F(r,e)&&t.push(o)}return t}function U(n,e){let t=M(n,e);if(t)return t;let o=ee(n,e);if(o.length===1&&o[0]instanceof Je)return o[0].subject}function Se(n,e){let t=ee(n,e),o=[];for(let r of t)r instanceof qr&&o.push(r);return o}function Jn(n,e){let t=[];for(let o of Xn(n,e))if(o instanceof Xr)t.push(o.object);else if(o instanceof Wn)for(let r of o.object)typeof r=="string"?t.push(r):r instanceof Gr?typeof r.value=="string"&&t.push(r.value):r instanceof Je&&t.push(r.subject.name);else o instanceof Ye&&t.push(o.object.subject.name);return t}function Yr(n,e){let t=n.split("/");if(t.length<3)throw new K(`Invalid property URI "${n}" \u2014 expected publisher/package/name`,e);let[o,r,...a]=t;return{publisher:o,package_:r,name:a.join("/")}}function te(n,e){let t=n.name,o=`transformation[${t}]`,r={catalog:e,depth:0},a=V(n,b.inputPattern);if(!a)throw new K("Transformation has no inputPattern",o);let s=Zr(a,r,`${o}.inputPattern`),i=V(n,b.rule);if(!i)throw new K("Transformation has no rule",o);let c=ne(i,r,`${o}.rule`),l=V(n,b.artifactName);if(!l)throw new K("Transformation has no artifactName",o);let u=ne(l,r,`${o}.artifactName`),d=new Set;for(let g of Xn(n,b.outputs))if(g instanceof Ye)d.add(g.object.subject.name);else if(g instanceof Wn)for(let h of g.object)h instanceof Je&&d.add(h.subject.name);if(d.size===0)throw new K("Transformation has no outputs",o);let m=new Map;for(let g of Se(n,b.formatOverrides)){let h=`${o}.formatOverrides[]`,f=U(g,b.formatTarget);if(!f)throw new K("FormatOverride missing formatTarget",h);m.set(f.name,Qr(g,h))}return{name:t,inputPattern:s,rule:c,artifactName:u,outputs:d,overrides:m}}function Zr(n,e,t){let o=U(n,b.matchesClass);if(!o)throw new K("InputPattern has no matchesClass",t);let r={publisher:o.publisher,package_:o.package_,name:o.name},s=Jn(n,b.requires).map((i,c)=>Yr(i,`${t}.requires[${c}]`));return{matchesClass:r,requires:s}}function Qr(n,e){let t=Jn(n,b.metadataKeys),o=t.length>0?t:void 0,r=new Map;for(let i of Se(n,b.metadataRenames)){let c=C(i,b.fromKey),l=C(i,b.toKey);c&&l&&r.set(c,l)}let a=le(n,b.trailingNewline);return{metadataKeys:o,metadataRenames:r,trailingNewline:typeof a=="boolean"?a:void 0}}function ne(n,e,t){let o=U(n,b.kind);if(!o)throw new K("Expression has no kind",t);let r=o.name;switch(r){case"build-ast-node":return ta(n,e,t);case"for-each":return oa(n,e,t);case"when":return ra(n,e,t);case"concat":return aa(n,e,t);case"string-literal":return{kind:"string-literal",value:ue(n,b.stringLiteral,t)};case"integer-literal":return{kind:"integer-literal",value:da(n,b.integerLiteral,t)};case"boolean-literal":return{kind:"boolean-literal",value:ma(n,b.booleanLiteral,t)};case"var-ref":return{kind:"var-ref",varName:ue(n,b.varName,t)};case"property-read":return sa(n,e,t);case"traverse":return ia(n,e,t);case"fallback":return ca(n,e,t);case"uri-name":return{kind:"uri-name",of:I(n,b.uriNameOf,e,`${t}.uriNameOf`)};case"list-map":return la(n,e,t);case"join":return{kind:"join",separator:ue(n,b.separator,t),items:I(n,b.items,e,`${t}.items`)};case"normalize":return ua(n,e,t);case"is-set":return{kind:"is-set",check:I(n,b.checkExpr,e,`${t}.checkExpr`)};case"uri-literal":{let a=U(n,b.refTo);if(!a)throw new K("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=U(n,b.labelTarget);if(!a)throw new K("display-label has no labelTarget",t);let s=U(n,b.labelSource);if(!s)throw new K("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"resolve-ref":return{kind:"resolve-ref",source:I(n,b.resolveSource,e,`${t}.resolveSource`)};case"call-fragment":{if(e.depth>=Gn)throw new K(`call-fragment recursion exceeded ${Gn} levels (cycle?)`,t);let a=U(n,b.fragmentRef);if(!a)throw new K("call-fragment has no fragmentRef",t);let s=ea(e.catalog,a);if(!s)throw new K(`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 i=V(s,b.expr);if(!i)throw new K(`ExpressionFragment "${s.name}" has no expr`,t);let c={catalog:e.catalog,depth:e.depth+1};return ne(i,c,`${t}\u2192fragment[${s.name}]`)}default:throw new K(`Unknown ExpressionKind "${r}"`,t)}}function ea(n,e){for(let t of n)if(t instanceof Wr&&t.name===e.name&&t.namespace&&t.namespace.startsWith(`${e.publisher}/${e.package_}@`)&&na(t))return t}function na(n){for(let e of n.statement){let t=e.predicate;if(!(!t||t.subject?.name!=="type")&&e instanceof Ye){let o=e.object.subject;if(o.publisher===b.ExpressionFragment.publisher&&o.package_===b.ExpressionFragment.package_&&o.name===b.ExpressionFragment.name)return!0}}return!1}function ta(n,e,t){let o=U(n,b.astClass);if(!o)throw new K("build-ast-node has no astClass",t);let r={publisher:o.publisher,package_:o.package_,name:o.name},a=[];return Se(n,b.set).forEach((i,c)=>{let l=`${t}.set[${c}]`,u=U(i,b.field);if(!u)throw new K("AstFieldBinding has no field",l);let d=I(i,b.bindValue,e,`${l}.bindValue`);a.push({field:{publisher:u.publisher,package_:u.package_,name:u.name},value:d})}),{kind:"build-ast-node",astClass:r,set:a}}function oa(n,e,t){return{kind:"for-each",iterate:I(n,b.iterate,e,`${t}.iterate`),loopVar:ue(n,b.loopVar,t),emit:I(n,b.emit,e,`${t}.emit`)}}function ra(n,e,t){let o=V(n,b.elseBuild);return{kind:"when",condition:I(n,b.condition,e,`${t}.condition`),thenBuild:I(n,b.thenBuild,e,`${t}.thenBuild`),elseBuild:o?ne(o,e,`${t}.elseBuild`):void 0}}function aa(n,e,t){return{kind:"concat",parts:Se(n,b.parts).map((r,a)=>ne(r,e,`${t}.parts[${a}]`))}}function sa(n,e,t){let o=U(n,b.readProp);if(!o)throw new K("property-read has no readProp",t);return{kind:"property-read",source:I(n,b.readSource,e,`${t}.readSource`),readProp:{publisher:o.publisher,package_:o.package_,name:o.name}}}function ia(n,e,t){let o=U(n,b.through);if(!o)throw new K("traverse has no through",t);return{kind:"traverse",source:I(n,b.traverseSource,e,`${t}.traverseSource`),through:{publisher:o.publisher,package_:o.package_,name:o.name},step:I(n,b.step,e,`${t}.step`)}}function ca(n,e,t){return{kind:"fallback",primary:I(n,b.primary,e,`${t}.primary`),alternate:I(n,b.alternate,e,`${t}.alternate`)}}function la(n,e,t){return{kind:"list-map",source:I(n,b.listMapSource,e,`${t}.listMapSource`),loopVar:ue(n,b.loopVar,t),mapBody:I(n,b.mapBody,e,`${t}.mapBody`)}}function ua(n,e,t){let o=U(n,b.normKind);if(!o)throw new K("normalize has no normKind",t);let r=o.name;if(r!=="trim-end")throw new K(`Unknown NormalizeKind "${r}"`,t);return{kind:"normalize",source:I(n,b.normSource,e,`${t}.normSource`),normKind:r}}function I(n,e,t,o){let r=V(n,e);if(!r){let a=`${e.publisher}/${e.package_}/${e.name}`,s=n.statement.length,i=n.statement.some(u=>{let d=u.predicate?.subject;return d&&d.publisher==="kanonak.org"&&d.package_==="transformations"&&d.name==="kind"}),c=`${e.publisher}/${e.package_}`,l;throw s===0?l=" (parent Expression has no statements at all \u2014 the parser produced an empty node, which usually means the containing YAML block did not resolve to an Expression-typed embedded)":i&&s<3?l=` \u2014 expected property ${a} but the parent Expression only has ${s} statement(s) including its 'kind'. The most likely cause is a STALE local copy of the Kanonak package ${c} that declares the expression kind but not the '${e.name}' property. Refresh your workspace copy of ${c} and re-resolve imports so the runner picks up the current property definitions.`:l=` \u2014 expected property ${a}. Parent Expression has ${s} statement(s) but none match that predicate URI. Either the YAML is missing the '${e.name}' key for this expression kind, or your local copy of the Kanonak package ${c} is out of date.`,new K(`missing child expression${l}`,o)}return ne(r,t,o)}function ue(n,e,t){let o=C(n,e);if(typeof o!="string")throw new K(`missing required string property "${e.name}"`,t);return o}function da(n,e,t){let o=le(n,e);if(typeof o!="number")throw new K(`missing required integer property "${e.name}"`,t);return o}function ma(n,e,t){let o=le(n,e);if(typeof o!="boolean")throw new K(`missing required boolean property "${e.name}"`,t);return o}function Yn(n,e){return n.publisher===e.publisher&&n.package_===e.package_&&n.name===e.name}var De=class{backendUri="kanonak.org/transformations/markdown-with-frontmatter";render(e,t){let o=pa(e.metadata,t),r=ha(e.children),s=["---",...o,"---","",r].join(`
|
|
61
61
|
`);return t?.trailingNewline&&(s.endsWith(`
|
|
62
62
|
`)||(s+=`
|
|
63
|
-
`)),s}};function
|
|
63
|
+
`)),s}};function pa(n,e){if(!n)return[];let t=new Map;for(let i of n.entries)t.set(ve(i.key),i);let o=new Map;if(e?.metadataRenames)for(let[i,c]of e.metadataRenames)o.set(ve(i),c);let a=(e?.metadataKeys??n.entries.map(i=>i.key)).map(ve),s=[];for(let i of a){let c=t.get(i);if(!c)continue;let l=o.get(i),u=ve(l??i),d=Qn(c.value,c.escapeHint);d!==void 0&&s.push(`${u}: ${d}`)}return s}function ve(n){let e=n.lastIndexOf(".");return e===-1?n:n.substring(e+1)||n}function Qn(n,e){switch(n.kind){case"StringScalar":return fa(n.stringValue,e);case"IntegerScalar":return String(n.integerValue);case"StructuredList":{let t=[];for(let o of n.items){let r=Qn(o,e);r!==void 0&&t.push(r)}return t.join(", ")}case"StructuredMap":return;default:return}}function fa(n,e){return!e||Yn(e,j.ESC_RAW)?n:Yn(e,j.ESC_YAML_SAFE)?ga(n):n}function ga(n){return n.includes(`
|
|
64
64
|
`)?`|-
|
|
65
65
|
${n.replace(/\n/g,`
|
|
66
|
-
`).trimEnd()}`:/[:#\[\]{}&*!|>'"%@`,]/.test(n)?`"${n.replace(/\\/g,"\\\\").replace(/"/g,'\\"')}"`:n}function
|
|
66
|
+
`).trimEnd()}`:/[:#\[\]{}&*!|>'"%@`,]/.test(n)?`"${n.replace(/\\/g,"\\\\").replace(/"/g,'\\"')}"`:n}function ha(n){let e=[];for(let t of n){let o=ka(t);o&&e.push(o)}return e.join(`
|
|
67
67
|
|
|
68
|
-
`)}function
|
|
68
|
+
`)}function ka(n){switch(n.kind){case"Heading":return`${"#".repeat(n.level)} ${Zn(n.inlines)}`;case"Paragraph":return Zn(n.inlines);case"RawBlock":return n.rawContent;default:return""}}function Zn(n){let e=[];for(let t of n)t.kind==="Text"&&e.push(t.text);return e.join("")}function ya(n,e){return n.publisher===e.publisher&&n.package_===e.package_&&n.name===e.name}var Ke=class{backendUri="kanonak.org/transformations/toml";render(e,t){let r=ba(e.metadata,t).join(`
|
|
69
69
|
`);return t?.trailingNewline&&(r.endsWith(`
|
|
70
70
|
`)||(r+=`
|
|
71
|
-
`)),r}};function
|
|
71
|
+
`)),r}};function ba(n,e){if(!n)return[];let t=new Map;for(let a of n.entries)t.set(a.key,a);let o=e?.metadataKeys??n.entries.map(a=>a.key),r=[];for(let a of o){let s=t.get(a);if(!s)continue;let i=e?.metadataRenames.get(a)??a,c=et(s.value,s.escapeHint);c!==void 0&&r.push(`${i} = ${c}`)}return r}function et(n,e){switch(n.kind){case"StringScalar":return wa(n.stringValue,e);case"IntegerScalar":return String(n.integerValue);case"StructuredList":{let t=[];for(let o of n.items){let r=et(o,e);r!==void 0&&t.push(r)}return`[${t.join(", ")}]`}case"StructuredMap":return;default:return}}function wa(n,e){return e&&ya(e,j.ESC_TOML_MULTILINE)?Sa(n):$a(n)}function $a(n){return`"${n.replace(/\\/g,"\\\\").replace(/"/g,'\\"').replace(/\n/g,"\\n")}"`}function Sa(n){return`"""
|
|
72
72
|
${n.replace(/"""/g,'\\"\\"\\"')}
|
|
73
|
-
"""`}var
|
|
73
|
+
"""`}var Ae=class{backendUri="kanonak.org/transformations/json";render(e,t){let o=JSON.stringify(e,null,2);return t?.trailingNewline&&!o.endsWith(`
|
|
74
74
|
`)?o+`
|
|
75
|
-
`:o}};function
|
|
75
|
+
`:o}};function tt(n){let e=n.replace(/\r\n/g,`
|
|
76
76
|
`).split(`
|
|
77
|
-
`),t=[],o=0;for(;o<e.length;){let r=e[o];if(r.trim()===""){o++;continue}let a=/^(\s*)```(\S*)\s*$/.exec(r);if(a){let
|
|
78
|
-
`)),d=
|
|
79
|
-
${
|
|
77
|
+
`),t=[],o=0;for(;o<e.length;){let r=e[o];if(r.trim()===""){o++;continue}let a=/^(\s*)```(\S*)\s*$/.exec(r);if(a){let c=a[2],l=[];for(o++;o<e.length&&!/^(\s*)```\s*$/.test(e[o]);)l.push(e[o]),o++;o++;let u=ot(l.join(`
|
|
78
|
+
`)),d=c?` class="language-${rt(c)}"`:"";t.push(`<pre><code${d}>${u}</code></pre>`);continue}let s=/^(#{1,6})\s+(.*)$/.exec(r);if(s){let c=s[1].length,l=oe(s[2].trim());t.push(`<h${c}>${l}</h${c}>`),o++;continue}if(r.includes("|")&&o+1<e.length&&nt(e[o+1])){let c=Ze(r),l=va(e[o+1]);o+=2;let u=[];for(;o<e.length&&e[o].trim()!==""&&e[o].includes("|");)u.push(Ze(e[o])),o++;t.push(Da(c,l,u));continue}if(/^\s*[-*]\s+/.test(r)){let c=[];for(;o<e.length&&/^\s*[-*]\s+/.test(e[o]);){let l=[e[o].replace(/^\s*[-*]\s+/,"")];for(o++;o<e.length&&e[o].trim()!==""&&!/^\s*[-*]\s+/.test(e[o])&&!/^\s*\d+\.\s+/.test(e[o]);)l.push(e[o]),o++;o<e.length&&e[o].trim()===""&&o++,c.push(`<li>${oe(l.join(" ").trim())}</li>`)}t.push(`<ul>
|
|
79
|
+
${c.join(`
|
|
80
80
|
`)}
|
|
81
|
-
</ul>`);continue}if(/^\s*\d+\.\s+/.test(r)){let
|
|
82
|
-
${
|
|
81
|
+
</ul>`);continue}if(/^\s*\d+\.\s+/.test(r)){let c=[];for(;o<e.length&&/^\s*\d+\.\s+/.test(e[o]);){let l=[e[o].replace(/^\s*\d+\.\s+/,"")];for(o++;o<e.length&&e[o].trim()!==""&&!/^\s*\d+\.\s+/.test(e[o])&&!/^\s*[-*]\s+/.test(e[o]);)l.push(e[o]),o++;o<e.length&&e[o].trim()===""&&o++,c.push(`<li>${oe(l.join(" ").trim())}</li>`)}t.push(`<ol>
|
|
82
|
+
${c.join(`
|
|
83
83
|
`)}
|
|
84
|
-
</ol>`);continue}let
|
|
85
|
-
`)}function
|
|
84
|
+
</ol>`);continue}let i=[r];for(o++;o<e.length&&e[o].trim()!==""&&!/^(#{1,6})\s+/.test(e[o])&&!/^(\s*)```/.test(e[o])&&!/^\s*[-*]\s+/.test(e[o])&&!/^\s*\d+\.\s+/.test(e[o])&&!(e[o].includes("|")&&o+1<e.length&&nt(e[o+1]));)i.push(e[o]),o++;t.push(`<p>${oe(i.join(" "))}</p>`)}return t.join(`
|
|
85
|
+
`)}function nt(n){return n.includes("-")?/^[\s|:-]+$/.test(n):!1}function Ze(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 va(n){return Ze(n).map(e=>{let t=e.startsWith(":"),o=e.endsWith(":");return t&&o?"center":o?"right":t?"left":null})}function Da(n,e,t){let o=s=>{let i=e[s];return i?` style="text-align:${i}"`:""},r=n.map((s,i)=>`<th${o(i)}>${oe(s)}</th>`).join(""),a=t.map(s=>`<tr>${s.map((c,l)=>`<td${o(l)}>${oe(c)}</td>`).join("")}</tr>`).join(`
|
|
86
86
|
`);return`<table>
|
|
87
87
|
<thead><tr>${r}</tr></thead>
|
|
88
88
|
<tbody>
|
|
89
89
|
${a}
|
|
90
90
|
</tbody>
|
|
91
|
-
</table>`}function
|
|
91
|
+
</table>`}function oe(n){let e=ot(n);return e=e.replace(/`([^`\n]+)`/g,(t,o)=>`<code>${o}</code>`),e=e.replace(/\[([^\]]+)\]\(([^)\s]+)\)/g,(t,o,r)=>`<a href="${rt(r)}">${o}</a>`),e=e.replace(/\*\*([^*\n]+)\*\*/g,(t,o)=>`<strong>${o}</strong>`),e=e.replace(/(^|[^*])\*([^*\n]+)\*(?!\*)/g,(t,o,r)=>`${o}<em>${r}</em>`),e=e.replace(/(^|[\s(])_([^_\n]+)_(?=[\s).,;:!?]|$)/g,(t,o,r)=>`${o}<em>${r}</em>`),e}function ot(n){return n.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""").replace(/'/g,"'")}function rt(n){return n.replace(/"/g,""").replace(/&/g,"&")}function Qe(n,e){return n.publisher===e.publisher&&n.package_===e.package_&&n.name===e.name}var Ce=class{backendUri="kanonak.org/transformations/html";render(e,t){let o=Ka(e.metadata)??"Untitled",r=Aa(e.metadata,t),a=Ca(e.children),s=`<!DOCTYPE html>
|
|
92
92
|
<html lang="en">
|
|
93
93
|
<head>
|
|
94
94
|
<meta charset="utf-8">
|
|
95
|
-
<title>${
|
|
95
|
+
<title>${de(o)}</title>
|
|
96
96
|
<style>
|
|
97
97
|
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; }
|
|
98
98
|
h1, h2, h3, h4 { line-height: 1.2; }
|
|
@@ -118,17 +118,17 @@ ${r}${a}
|
|
|
118
118
|
</body>
|
|
119
119
|
</html>
|
|
120
120
|
`;return t?.trailingNewline===!1&&s.endsWith(`
|
|
121
|
-
`)?s.slice(0,-1):s}};function
|
|
122
|
-
<dd>${
|
|
121
|
+
`)?s.slice(0,-1):s}};function Ka(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 Aa(n,e){if(!n||n.entries.length===0)return"";let t=e?.metadataKeys??n.entries.map(a=>a.key),o=new Map(n.entries.map(a=>[a.key,a])),r=[];for(let a of t){let s=o.get(a);if(!s)continue;let i=e?.metadataRenames.get(a)??a,c=st(s.value);c!==void 0&&r.push(` <dt>${de(i)}</dt>
|
|
122
|
+
<dd>${c}</dd>`)}return r.length===0?"":`<dl class="metadata">
|
|
123
123
|
${r.join(`
|
|
124
124
|
`)}
|
|
125
125
|
</dl>
|
|
126
|
-
`}function
|
|
127
|
-
`)}function
|
|
126
|
+
`}function st(n){switch(n.kind){case"StringScalar":return de(n.stringValue);case"IntegerScalar":return String(n.integerValue);case"StructuredList":{let e=[];for(let t of n.items){let o=st(t);o!==void 0&&e.push(`<code>${o}</code>`)}return e.join(", ")}case"StructuredMap":return;default:return}}function Ca(n){let e=[];for(let t of n){let o=Pa(t);o&&e.push(o)}return e.join(`
|
|
127
|
+
`)}function Pa(n){switch(n.kind){case"Heading":{let e=Math.max(1,Math.min(6,n.level));return`<h${e}>${at(n.inlines)}</h${e}>`}case"Paragraph":return`<p>${at(n.inlines)}</p>`;case"RawBlock":return Ea(n);default:return""}}function Ea(n){let e=n.mediaType;return e&&Qe(e,j.TEXT_MARKDOWN)?tt(n.rawContent):e&&Qe(e,j.TEXT_HTML)?n.rawContent:e&&Qe(e,j.IMAGE_SVG_XML)?`<figure class="svg-figure">
|
|
128
128
|
${n.rawContent}
|
|
129
|
-
</figure>`:`<pre${e?` class="media-${
|
|
129
|
+
</figure>`:`<pre${e?` class="media-${_a(e.name)}"`:""}><code>${de(n.rawContent)}</code></pre>`}function at(n){let e=[];for(let t of n)t.kind==="Text"&&e.push(de(t.text));return e.join("")}function de(n){return n.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""").replace(/'/g,"'")}function _a(n){return n.replace(/"/g,""").replace(/&/g,"&")}function Ia(n,e){return n.publisher===e.publisher&&n.package_===e.package_&&n.name===e.name}var Pe=class{backendUri="kanonak.org/transformations/svg";render(e,t){for(let o of e.children)if(o.kind==="RawBlock"&&o.mediaType&&Ia(o.mediaType,j.IMAGE_SVG_XML)){let r=o.rawContent;return t?.trailingNewline&&!r.endsWith(`
|
|
130
130
|
`)&&(r+=`
|
|
131
|
-
`),r}return'<svg xmlns="http://www.w3.org/2000/svg" width="1" height="1"/>'}};var
|
|
131
|
+
`),r}return'<svg xmlns="http://www.w3.org/2000/svg" width="1" height="1"/>'}};var Ee={"markdown-with-frontmatter":{formatUri:"kanonak.org/transformations/markdown-with-frontmatter",extension:".md"},toml:{formatUri:"kanonak.org/transformations/toml",extension:".toml"},json:{formatUri:"kanonak.org/transformations/json",extension:".json"},"plain-markdown":{formatUri:"kanonak.org/transformations/plain-markdown",extension:".md"},html:{formatUri:"kanonak.org/transformations/html",extension:".html"},svg:{formatUri:"kanonak.org/transformations/svg",extension:".svg"}},re=class extends Error{},B=class{backends=new Map;constructor(){this.register(new De),this.register(new Ke),this.register(new Ae),this.register(new Ce),this.register(new Pe)}register(e){this.backends.set(e.backendUri,e)}async run(e){let t=e.transformationKanonaks??e.allKanonaks,o=te(e.transformation,t);if(!o.outputs.has(e.outputFormat))throw new re(`Transformation "${o.name}" does not support output format "${e.outputFormat}". Declared outputs: ${Array.from(o.outputs).join(", ")}`);let r=new ye(e.repository,e.parser,e.objectParser),a=new $e(r,e.allKanonaks),s=e.instances.filter(u=>Ra(u,o)),i=this.findBackendForFormat(e.outputFormat);if(!i)throw new re(`No backend registered for OutputFormat "${e.outputFormat}".`);let c=o.overrides.get(e.outputFormat),l=[];for(let u of s){let d=new Map;d.set("input",u);let m=await a.evaluate(o.rule,d);if(!xa(m))throw new re(`Transformation "${o.name}" rule did not yield a Document for input "${u.name}". Got: ${it(m)}`);let g=await a.evaluate(o.artifactName,d);if(typeof g!="string")throw new re(`Transformation "${o.name}" artifactName did not yield a string for input "${u.name}". Got: ${it(g)}`);let h=i.render(m,c);l.push({fileName:g,format:e.outputFormat,content:h,sourceName:u.name})}return l}findBackendForFormat(e){let t=Ee[e];if(t)return this.backends.get(t.formatUri)}};function Ra(n,e){for(let t of e.inputPattern.requires)if(!Ta(n,t))return!1;return!0}function Ta(n,e){for(let t of n.statement){let o=t.predicate?.subject;if(o&&F(o,e)){let r=t.object;if(r==null||typeof r=="string"&&r.length===0||Array.isArray(r)&&r.length===0)continue;return!0}}return!1}function xa(n){return typeof n=="object"&&n!==null&&n.kind==="Document"&&Array.isArray(n.children)}function it(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 mt(){let n=new me("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",`
|
|
132
132
|
Examples:
|
|
133
133
|
|
|
134
134
|
# List every Transformation available in the local workspace
|
|
@@ -157,14 +157,14 @@ Examples:
|
|
|
157
157
|
|
|
158
158
|
# List the registered format backends
|
|
159
159
|
$ kanonak transform formats
|
|
160
|
-
`);return n.addCommand(
|
|
160
|
+
`);return n.addCommand(Ha()),n.addCommand(Ga()),n.addCommand(Xa()),n.addCommand(Ya()),n}function Ha(){return new me("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 za(n,e)}catch(t){console.error(`Error: ${t.message}`),process.exit(1)}})}async function za(n,e){let t=new en,o=new nn,r=await x(process.cwd(),t),a=await pt(n,r,o),{transformation:s,transformationKanonaks:i}=a;console.log(`Transformation: ${Ie(s)}`);let c=te(s,i),l=await Za(e.scope,r,t,o),u=await ns(l,c.inputPattern.matchesClass,r);console.log(`Scope: ${e.scope} \u2014 found ${u.length} instance(s) of ${c.inputPattern.matchesClass.publisher}/${c.inputPattern.matchesClass.package_}/${c.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=qa(c.outputs,e.format);console.log(`Output format: ${d}`);let m=Ee[d];if(!m)throw new Error(`Unknown format "${d}". Run \`kanonak transform formats\` to see what the runner supports.`);let h=await new B().run({transformation:s,instances:u,allKanonaks:l,transformationKanonaks:i,repository:r,parser:t,objectParser:o,outputFormat:d}),f=Fa(e.out);Na(f,{recursive:!0});for(let k of h){let y=es(k.fileName),w=La(f,`${y}${m.extension}`);Ua(w,k.content,"utf-8"),console.log(` wrote ${w}`)}console.log(`Done. ${h.length} artifact(s) written to ${f}`)}function qa(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 Ga(){return new me("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 en,e=new nn,t=await x(process.cwd(),n),o=await t.getAllDocumentsAsync(),r=new Map;for(let s of o)try{let i=new A(s,t),c=await e.parseKanonaks(i),l=P(c,b.Transformation);for(let u of l){let d=on(u);if(!d)continue;let m=r.get(d)??[];m.push({tx:u,kanonaks:c,doc:s}),r.set(d,m)}}catch{}let a=[];for(let s of r.values()){if(s.length===1){a.push(lt(s[0].tx,s[0].kanonaks));continue}let i=tn(s.map(l=>l.doc));if(!i.chosen)continue;let c=s.find(l=>l.doc===i.chosen);c&&a.push(lt(c.tx,c.kanonaks))}if(a.length===0){console.log("No Transformation instances found in the current workspace.");return}a.sort((s,i)=>s.uri.localeCompare(i.uri));for(let s of a)console.log(`${s.uri}`),console.log(` matches: ${s.matchesClass}`),console.log(` outputs: ${s.outputs.join(", ")}`)}function Xa(){return new me("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 Ja(n)}catch(e){console.error(`Error: ${e.message}`),process.exit(1)}})}async function Ja(n){let e=new en,t=new nn,o=await x(process.cwd(),e),{transformation:r,transformationKanonaks:a}=await pt(n,o,t),s=te(r,a);if(console.log(`Transformation: ${Ie(r)}`),console.log(),console.log("Input pattern:"),console.log(` Matches class: ${_e(s.inputPattern.matchesClass)}`),s.inputPattern.requires.length>0){console.log(" Required properties:");for(let i of s.inputPattern.requires)console.log(` - ${_e(i)}`)}else console.log(" Required properties: (none)");if(console.log(),console.log(`Outputs: ${Array.from(s.outputs).sort().join(", ")}`),console.log(),s.overrides.size>0){console.log("Format overrides:");for(let[i,c]of s.overrides){if(console.log(` ${i}:`),c.metadataKeys&&console.log(` metadata keys: ${c.metadataKeys.join(", ")}`),c.metadataRenames.size>0){let l=[];for(let[u,d]of c.metadataRenames)l.push(`${u} \u2192 ${d}`);console.log(` metadata renames: ${l.join(", ")}`)}c.trailingNewline!==void 0&&console.log(` trailing newline: ${c.trailingNewline}`)}console.log()}console.log(`Rule root kind: ${s.rule.kind}`),s.rule.kind==="build-ast-node"&&(console.log(`Rule root AST class: ${_e(s.rule.astClass)}`),console.log(`Rule root bindings: ${s.rule.set.length} field(s)`)),console.log(`Artifact name root kind: ${s.artifactName.kind}`)}function Ya(){return new me("formats").description("List the OutputFormat names the runner can serialize to.").action(()=>{console.log("Registered format backends:");let n=Object.entries(Ee).sort(([e],[t])=>e.localeCompare(t));for(let[e,t]of n)console.log(` ${e.padEnd(28)} ${t.extension.padEnd(6)} ${t.formatUri}`)})}async function pt(n,e,t){let o,r,a;if(n.includes("/")){let m=n.indexOf("@"),g=n;if(m!==-1){let f=n.indexOf("/",m);if(f===-1)throw new Error(`Transformation URI "${n}" has @version but no trailing /<name>`);g=n.substring(0,m)+n.substring(f)}let h=g.split("/");if(h.length<3)throw new Error(`Invalid transformation URI "${n}" \u2014 expected publisher/package/name or publisher/package@version/name`);o=h[0],r=h[1],a=h.slice(2).join("/")}else a=n;if(o&&r){let m=await e.getDocumentsByNamespaceAsync(o,r);if(m.length===0)throw new Error(`Package ${o}/${r} not found in the local workspace or cache.`);let g=Qa(n),h=ft(m,g,`${o}/${r}`),f=new A(h,e),k=await t.parseKanonaks(f),y=he(k,{publisher:o,package_:r,name:a,version:""});if(!y){let w=P(k,b.Transformation),$=w.find(v=>v.name===a);if(!$)throw new Error(`Transformation "${a}" not found in package ${o}/${r}. Package contains ${w.length} Transformation(s): ${w.map(v=>v.name).join(", ")||"(none)"}`);return{transformation:$,transformationKanonaks:k}}return{transformation:y,transformationKanonaks:k}}let s=await e.getAllDocumentsAsync(),i=new Map;for(let m of s)try{let g=new A(m,e),h=await t.parseKanonaks(g),f=P(h,b.Transformation);for(let k of f){if(k.name!==a)continue;let y=on(k);if(!y)continue;let w=i.get(y)??[];w.push({tx:k,kanonaks:h,doc:m}),i.set(y,w)}}catch{}if(i.size===0)throw new Error(`No Transformation named "${a}" found in the workspace. Try \`kanonak transform list\` to see available transformations.`);if(i.size>1){let m=Array.from(i.keys()).sort().join(`
|
|
161
161
|
`);throw new Error(`Multiple Transformations named "${a}" in the workspace \u2014 disambiguate with a full publisher/package/name URI:
|
|
162
|
-
${m}`)}let
|
|
163
|
-
`);let a=r.reduce((s,
|
|
164
|
-
`),f.sort();for(let
|
|
165
|
-
`);for(let s of r){let
|
|
166
|
-
Updated ${
|
|
167
|
-
`);let a=new
|
|
168
|
-
`);let
|
|
169
|
-
`;function
|
|
170
|
-
`;function
|
|
162
|
+
${m}`)}let c=Array.from(i.values())[0];if(c.length===1)return{transformation:c[0].tx,transformationKanonaks:c[0].kanonaks};let l=new Map(c.map(m=>[m.doc,m])),u=tn(c.map(m=>m.doc));if(!u.chosen)throw new Error(`Could not select a Transformation version for "${a}".`);let d=l.get(u.chosen);if(u.multipleVersionsPresent){let m=f=>{let k=f.metadata.namespace_?.version;return k?dt(k):""},g=d.tx.namespace??"",h=g.includes("@")?g.substring(0,g.indexOf("@")):g;console.warn(`Warning: Transformation "${a}" has ${c.length} versions present (${c.map(f=>m(f.doc)).filter(Boolean).join(", ")}); using @${m(u.chosen)}. Pin with ${h}@<version>/${a} to suppress this warning.`)}return{transformation:d.tx,transformationKanonaks:d.kanonaks}}async function Za(n,e,t,o){if(/^[.\/\\]/.test(n)||/^[A-Za-z]:/.test(n)||n.endsWith(".kan.yml")||ct(n)&&Oa(n).isFile()){if(!ct(n))throw new Error(`Scope file not found: ${n}`);let h=ja(n,"utf-8"),f=t.parse(h),k=new A(f,e);return o.parseKanonaks(k)}let a=n.indexOf("@"),s=a===-1?n:n.substring(0,a),i=a===-1?void 0:n.substring(a+1),c=s.indexOf("/");if(c===-1)throw new Error(`Invalid scope "${n}" \u2014 expected a file path or publisher/package[@version] URI`);let l=s.substring(0,c),u=s.substring(c+1),d=await e.getDocumentsByNamespaceAsync(l,u);if(d.length===0)throw new Error(`Scope package ${l}/${u} not found in the local workspace or cache.`);let m=ft(d,i,`${l}/${u}`),g=new A(m,e);return o.parseKanonaks(g)}function Qa(n){let e=n.indexOf("@");if(e===-1)return;let t=n.substring(e+1),o=t.indexOf("/");return o===-1?t:t.substring(0,o)}function ft(n,e,t){let o=a=>{let s=a.metadata.namespace_?.version;return s?dt(s):""},r=tn(n,{requestedVersion:e});if(r.exactRequestedVersionMissing){let a=n.map(o).filter(Boolean).sort().join(", ");throw new Error(`${t}@${e} not found in the local workspace or cache. Available versions: ${a||"(none with parseable namespace)"}`)}if(!r.chosen)throw new Error(`${t} not found in the local workspace or cache.`);return!e&&r.multipleVersionsPresent&&console.warn(`Warning: ${t} has ${n.length} versions present (${n.map(o).filter(Boolean).join(", ")}); using @${o(r.chosen)}. Pin with ${t}@<version> to suppress this warning.`),r.chosen}function lt(n,e){try{let t=te(n,e);return{uri:Ie(n),matchesClass:_e(t.inputPattern.matchesClass),outputs:Array.from(t.outputs).sort()}}catch(t){return{uri:Ie(n),matchesClass:`(compile error: ${t.message})`,outputs:[]}}}function Ie(n){let e=n.namespace||"",t=e.indexOf("@");return`${t===-1?e:e.substring(0,t)}/${n.name}`}function _e(n){return`${n.publisher}/${n.package_}/${n.name}`}function es(n){return n.replace(/[\\/:*?"<>|\s]+/g,"_").replace(/^_+|_+$/g,"")}async function ns(n,e,t){let o=new Map;for(let s of n){if(!(s instanceof Ma))continue;let i=on(s);i&&o.set(i,s)}let r=[];try{r=(await new Ba({vocabulary:new Va}).reason(t)).getInstancesOfClass(ut(e.publisher,e.package_,e.name))}catch{}let a=[];for(let s of r){let i=o.get(s);i&&a.push(i)}return a.length>0?a:P(n,e)}function on(n){let e=n.namespace??"",t=e.indexOf("@"),o=t===-1?e:e.substring(0,t),r=o.indexOf("/");return r===-1||!n.name?null:ut(o.substring(0,r),o.substring(r+1),n.name)}import{Command as ts}from"commander";import{KanonakParser as os,PublisherIndex as gt,CredentialStore as ht,createAuthenticatedFetch as kt,FileSystemKanonakDocumentRepository as rs,Reasoner as as,KanonakVocabulary as ss,getGlobalCachePath as is,makeUriKey as cs}from"@kanonak-protocol/sdk";function ls(n){let e=n.split("/");if(e.length!==3)return null;let[t,o,r]=e;return!t||!o||!r?null:{publisher:t,package_:o,name:r}}function yt(){return new ts("search").description("Browse a publisher's catalogue or find instances of a class via the SDK reasoner").argument("<publisher>","Publisher domain (e.g. kanonak.org)").option("--type <uri>","Class URI to search for, in publisher/package/Name form").action(async(n,e)=>{e.type?await ds(n,e.type):await us(n)})}async function us(n){let e=new ht,t=kt(e),o=new gt({fetchFn:t}),r;try{r=await o.listLatestPackages(n)}catch(s){console.error(`Failed to fetch publisher index for ${n}: ${s.message}`),process.exit(1)}if(r.length===0){console.log(`No packages found at ${n}.`);return}console.log(`Packages published by ${n}:
|
|
163
|
+
`);let a=r.reduce((s,i)=>Math.max(s,i.packageName.length),0);for(let{packageName:s,version:i}of r)console.log(` ${s.padEnd(a)} @${i}`)}async function ds(n,e){let t=ls(e);t||(console.error(`Invalid --type value: ${e}`),console.error("Expected: publisher/package/Name (e.g. kanonak.org/capabilities/Capability)"),process.exit(1));let o=new os,r=new ht,a=kt(r),s=new gt({fetchFn:a}),i=new T,c=new Set,l=[];try{l=await s.listLatestPackages(n)}catch(k){console.error(`Failed to fetch publisher index for ${n}: ${k.message}`),process.exit(1)}for(let{packageName:k,version:y}of l)c.add(`${n}|${k}|${y}`);await rn(s,i,a,"kanonak.org","core-rdf",c),await rn(s,i,a,"kanonak.org","core-owl",c),await rn(s,i,a,t.publisher,t.package_,c);for(let k of c){let[y,w,$]=k.split("|");if(!i.has(y,w,$))try{let v=await s.getPackageUrl(y,w,$),D=await a(v,y);if(!D.ok){console.error(`Warning: failed to fetch ${y}/${w}@${$}: ${D.status} ${D.statusText}`);continue}let W=await D.text();i.put(y,w,$,W)}catch(v){console.error(`Warning: failed to fetch ${y}/${w}@${$}: ${v.message}`)}}let u=new rs(is(),!0,o),m=await new as({vocabulary:new ss}).reason(u),g=cs(t.publisher,t.package_,t.name),f=m.getInstancesOfClass(g).filter(k=>k!==g);if(f.length===0){console.log(`No instances of ${g} found in ${n}'s catalogue.`);return}console.log(`Instances of ${g} in ${n}'s catalogue:
|
|
164
|
+
`),f.sort();for(let k of f)console.log(` ${k}`)}async function rn(n,e,t,o,r,a){try{let s=await n.getHighestVersion(o,r);if(!s)return;a.add(`${o}|${r}|${s}`)}catch{}}import{Command as bt}from"commander";function ae(n){return`${E}/${_}/${n}`}var an={[ae("fetch-and-deploy")]:(n,e,t,o)=>n.add(e,t[0],o),[ae("remove-deployed")]:(n,e,t,o)=>n.remove(e,t[0],o),[ae("list-deployed")]:(n,e,t,o)=>n.list(e,o),[ae("update-deployed")]:(n,e,t,o)=>n.update(e,t[0],o),[ae("search-available")]:(n,e,t,o)=>n.search(e,o),[ae("show-info")]:(n,e,t,o)=>n.info(e,t[0],o)};function wt(n,e,t){for(let o of e){let r=new bt(o.commandName).description(o.description.trim());for(let a of o.commands){let s=r.command(ms(a));s.description(a.description);for(let i of a.arguments)if(i.isOption){let c=i.defaultValue!=null?`--${i.argumentName} [value]`:`--${i.argumentName} <value>`;s.option(c,"",i.defaultValue)}s.action(async(...i)=>{let c=ps(i);await fs(t,o,a,i,c)})}n.addCommand(r)}}function ms(n){let e=n.arguments.filter(t=>!t.isOption).map(t=>t.required?`<${t.argumentName}>`:`[${t.argumentName}]`);return[n.subcommandName,...e].join(" ")}function ps(n){for(let e=n.length-1;e>=0;e--)if(n[e]&&typeof n[e]=="object"&&!(n[e]instanceof bt))return n[e];return{}}async function fs(n,e,t,o,r){let a=[];for(let i of o)if(typeof i=="string")a.push(i);else break;t.actionKey||(console.error(`Capability subcommand '${t.subcommandName}' has no resolved \`performs:\` Action. Every CapabilityCommand must declare a performs value pointing at a named Action instance from the capabilities ontology. Known actions: ${Object.keys(an).join(", ")}.`),process.exit(1));let s=an[t.actionKey];s||(console.error(`Capability subcommand '${t.subcommandName}' references unknown Action '${t.actionKey}'. Known actions: ${Object.keys(an).join(", ")}.`),process.exit(1)),await s(n,e,a,r)}import{existsSync as $t,readFileSync as gs,statSync as St}from"fs";import{resolve as hs}from"path";import{KanonakObjectParser as ks,PublisherIndex as sn,PublisherConfigResolver as ys,formatVersion as vt,pickHighestDocument as bs}from"@kanonak-protocol/sdk";var Re=class{constructor(e,t,o,r,a,s){this.fileCache=e;this.parser=t;this.publisherIndex=o;this.fetchFn=r;this.handlerRegistry=a;this.repository=s}fileCache;parser;publisherIndex;fetchFn;handlerRegistry;repository;objectParser=new ks;async add(e,t,o){let r=this.tryLoadFromLocalFile(t);if(r){this.fileCache.put(r.publisher,r.packageName,r.version,r.content),await this.deployFromDoc(e,r.doc,r.publisher,r.packageName,r.version,void 0,`local file ${t}`,o);return}let a=X(t);a||(console.error(`Invalid package reference: "${t}"`),console.error(""),console.error("Accepted forms:"),console.error(" publisher/package (install all instances, latest version)"),console.error(" publisher/package@version (install all instances, pinned)"),console.error(" publisher/package/instance (install one instance, latest version)"),console.error(" publisher/package@version/instance (install one instance, pinned)"),console.error(" ./path/to/file.kan.yml (install all instances from a local document)"),console.error(""),console.error("Tip: copy a URI directly from `kanonak "+e.commandName+" search`."),process.exit(1));let{publisher:s,packageName:i,version:c,instanceName:l}=a,u=await this.repository.getDocumentsByNamespaceAsync(s,i);if(u.length>0){let g=bs(u,{requestedVersion:c??void 0});if(g.chosen){let h=g.chosen.metadata.namespace_;(!h||!h.version)&&(console.error(`Document for ${s}/${i} is missing namespace metadata.`),process.exit(1));let f=vt(h.version);this.fileCache.put(s,i,f,this.parser.save(g.chosen)),await this.deployFromDoc(e,g.chosen,s,i,f,l??void 0,`${s}/${i}@${f}`,o);return}}let d=c??await this.publisherIndex.getHighestVersion(s,i);d||(console.error(`Could not resolve version for "${s}/${i}".`),await this.printPackageSuggestions(s,i,e.commandName),process.exit(1));let m=this.fileCache.get(s,i,d);if(!m){let g=await this.publisherIndex.getPackageUrl(s,i,d),h=await this.fetchFn(g,s);h.ok||(h.status===404?(console.error(`Package ${s}/${i}@${d} not found at ${g}.`),console.error(`The publisher index lists this version but the file is missing \u2014 it may have been unpublished. Try \`kanonak ${e.commandName} search\` to see the current catalogue.`)):console.error(`Failed to fetch ${g} (${h.status} ${h.statusText}).`),process.exit(1)),m=await h.text(),this.fileCache.put(s,i,d,m)}await this.deployFromDoc(e,this.parser.parse(m),s,i,d,l??void 0,`${s}/${i}@${d}`,o)}tryLoadFromLocalFile(e){if(!(/^[.\/\\]/.test(e)||/^[A-Za-z]:[\\/]/.test(e)||e.endsWith(".kan.yml")||$t(e)&&St(e).isFile()))return;let o=hs(e);(!$t(o)||!St(o).isFile())&&(console.error(`Local file not found: ${e}`),process.exit(1));let r=gs(o,"utf-8"),a=this.parser.parse(r),s=a.metadata.namespace_;return(!s||!s.version)&&(console.error(`${e} has no namespace metadata; cannot determine publisher/package/version. A Kanonak document must declare \`type: Package\` with publisher and version.`),process.exit(1)),{doc:a,content:r,publisher:s.publisher,packageName:s.package_,version:vt(s.version)}}async deployFromDoc(e,t,o,r,a,s,i,c){let l=new A(t,this.repository),u=await this.objectParser.parseKanonaks(l),d=Dt(e.managesTypeKey);d||(console.error(`Capability "${e.commandName}" has no resolved managesType.`),process.exit(1));let m=P(u,d);m.length===0&&(console.error(`${i} does not contain any ${N(d)} instances.`),process.exit(1));let g=m;if(s&&(g=m.filter(k=>k.name===s),g.length===0)){console.error(`Instance "${s}" not found in ${i}.`),console.error(""),console.error(`Available ${N(d)} instance(s):`);for(let k of m)console.error(` - ${k.name}`);console.error(""),console.error("To install all of them, drop the instance suffix:"),console.error(` kanonak ${e.commandName} add ${o}/${r}`),process.exit(1)}let h=s?`${s} from ${i}`:`${g.length} ${N(d)} instance(s) from ${i}`;console.log(`Installing ${h}...`);let f=this.handlerRegistry.get(e.deploymentTargetKey);f?await f.deploy({instances:g,allKanonaks:u,repository:this.repository,options:c}):console.log(`Cached ${o}/${r}@${a} (no deployment handler for "${e.deploymentTargetKey}")`)}async printPackageSuggestions(e,t,o){let r;try{r=await this.publisherIndex.listLatestPackages(e)}catch{return}let a=r.map(s=>({name:s.packageName,version:s.version,score:ws(t,s.packageName)})).filter(s=>s.score>0).sort((s,i)=>i.score-s.score).slice(0,5);if(a.length!==0){console.error(""),console.error("Did you mean one of:");for(let s of a)console.error(` kanonak ${o} add ${e}/${s.name}`)}}async remove(e,t,o){await this.requireHandler(e).undeploy(t,{repository:this.repository,options:o})}async list(e,t){let r=await this.requireHandler(e).list({repository:this.repository,options:t}),a=e.managesTypeKey||"managed";if(r.length===0){console.log(`No ${a} instances installed.`);return}console.log(`Installed ${a} instances:
|
|
165
|
+
`);for(let s of r){let i=s.publisher?`${s.publisher}/${s.package_}@${s.version}`:"unmanaged";console.log(` ${s.name} (${i}) ${s.path}`)}}async update(e,t,o){let a=await this.requireHandler(e).list({repository:this.repository,options:o}),s=t?a.filter(c=>c.name===t):a.filter(c=>c.publisher);if(s.length===0){console.log(t?`"${t}" not found.`:"No managed instances to update.");return}let i=0;for(let c of s){let l=await this.publisherIndex.getHighestVersion(c.publisher,c.package_);!l||l===c.version||(console.log(`Updating ${c.name}: ${c.version} \u2192 ${l}`),await this.add(e,`${c.publisher}/${c.package_}@${l}`,o),i++)}console.log(i===0?"All instances are up to date.":`
|
|
166
|
+
Updated ${i} instance(s).`)}async search(e,t){let o=t.publisher??"kanonak.org",r=Dt(e.managesTypeKey);if(!r){console.error("Capability has no resolved managesType; nothing to search for.");return}console.log(`Searching ${o} for ${N(r)} instances...
|
|
167
|
+
`);let a=new ys,s=await a.getConfig(o),i=a.resolveIndexUrl(o,s),c=await this.fetchFn(i,o);if(!c.ok){console.error(`Failed to fetch package index from ${o}.`);return}let l=await c.text(),u=sn.parseIndex(l);if(u.size===0){console.error(`No packages found for publisher "${o}".`);return}let d=new Map;for(let[f,k]of u){let y=[...k].sort((w,$)=>{let v=sn.parseVersion(w),D=sn.parseVersion($);return!v||!D?0:v.major!==D.major?D.major-v.major:v.minor!==D.minor?D.minor-v.minor:D.patch-v.patch});d.set(f,y[0])}let m=[],g=0;for(let[f,k]of d){let y=this.fileCache.get(o,f,k);if(!y)try{let w=await this.publisherIndex.getPackageUrl(o,f,k),$=await this.fetchFn(w,o);if(!$.ok)continue;y=await $.text(),this.fileCache.put(o,f,k,y)}catch{continue}try{let w=this.parser.parse(y),$=new A(w,this.repository),v=await this.objectParser.parseKanonaks($),D=P(v,r);for(let W of D)m.push({publisher:o,package_:f,version:k,subject:W});g++}catch{continue}}if(m.length===0){console.log(`No ${N(r)} instances found across ${g} package(s).`);return}console.log(`Found ${m.length} ${N(r)} instance(s) in ${g} package(s):
|
|
168
|
+
`);let h=new Map;for(let f of m){let k=`${f.publisher}/${f.package_}@${f.version}`,y=h.get(k);y?y.push(f):h.set(k,[f])}for(let[f,k]of h){let y=k[0],w=`${y.publisher}/${y.package_}`,$=k.length===1;console.log(` ${f}`),console.log(` ${k.length} skill${$?"":"s"}:`);for(let v of k)console.log(` - ${v.subject.name}`);if(console.log(""),$)console.log(" install:"),console.log(` kanonak ${e.commandName} add ${w}/${y.subject.name}`);else{console.log(" install one of them:");for(let v of k)console.log(` kanonak ${e.commandName} add ${w}/${v.subject.name}`);console.log(" install all of them:"),console.log(` kanonak ${e.commandName} add ${w}`)}console.log("")}}async info(e,t,o){let s=(await this.requireHandler(e).list({repository:this.repository,options:o})).find(i=>i.name===t);s||(console.error(`"${t}" is not installed.`),process.exit(1)),console.log(`Name: ${s.name}`),console.log(`Type: ${e.managesTypeKey||"n/a"}`),console.log(`Publisher: ${s.publisher||"unmanaged"}`),console.log(`Package: ${s.package_||"n/a"}`),console.log(`Version: ${s.version||"n/a"}`),console.log(`Path: ${s.path}`)}requireHandler(e){let t=this.handlerRegistry.get(e.deploymentTargetKey);return t||(console.error(`No deployment handler registered for "${e.deploymentTargetKey}". Ensure the capability's deploymentTarget resolves to a DeploymentTarget instance whose URI is registered in the CLI at startup.`),process.exit(1)),t}};function Dt(n){if(!n)return;let e=n.split("/");if(e.length===3)return{publisher:e[0],package_:e[1],name:e[2]}}function ws(n,e){let t=n.toLowerCase(),o=e.toLowerCase();if(t===o)return 100;if(o.includes(t)||t.includes(o))return 50;let r=new Set(t.split("-").filter(Boolean)),a=new Set(o.split("-").filter(Boolean)),s=0;for(let c of r)a.has(c)&&s++;if(s>0)return s*10;let i=$s(t,o);return i===0?100:i<=2?Math.max(1,20-i*5):0}function $s(n,e){if(n===e)return 0;if(n.length===0)return e.length;if(e.length===0)return n.length;let t=new Array(e.length+1),o=new Array(e.length+1);for(let r=0;r<=e.length;r++)t[r]=r;for(let r=0;r<n.length;r++){o[0]=r+1;for(let a=0;a<e.length;a++){let s=n[r]===e[a]?0:1;o[a+1]=Math.min(o[a]+1,t[a+1]+1,t[a]+s)}for(let a=0;a<=e.length;a++)t[a]=o[a]}return t[e.length]}var Te=class{handlers=new Map;register(e,t){this.handlers.set(e,t)}get(e){return this.handlers.get(e)??null}};import{mkdirSync as Rs,rmSync as Ts,existsSync as Ue,readdirSync as xs,writeFileSync as js}from"fs";import{join as Ne}from"path";import{KanonakObjectParser as Us,KanonakParser as Ns,computeIntegrity as Os}from"@kanonak-protocol/sdk";import{join as cn}from"path";import{homedir as Kt}from"os";import{KanonakObjectParser as Ss}from"@kanonak-protocol/sdk";var H="kanonak.org",z="agent-skills",Ct={publisher:H,package_:z,name:"Client"},Pt={publisher:H,package_:z,name:"clientId"},vs={publisher:H,package_:z,name:"projectSkillDir"},Ds={publisher:H,package_:z,name:"userSkillDir"},Ks={publisher:H,package_:z,name:"skillFileName"},Et="agents";async function pe(n,e){let t=(n.client??_t()??Et).toLowerCase(),o=n.scope??"project",r=await Rt(t,e);if(!r){let i=await As(e);throw new Error(`Unknown client "${t}". Known clients: ${i.join(", ")||"(none)"}. Add a Client instance to a package that imports kanonak.org/agent-skills and install that package to make it available.`)}let s=C(r,o==="user"?Ds:vs);if(!s)throw new Error(`Client "${t}" has no ${o==="user"?"userSkillDir":"projectSkillDir"} declared.`);return Cs(s)}async function xe(n,e,t){let o=await pe(e,t);return cn(o,n)}async function ln(n,e){let t=(n.client??_t()??Et).toLowerCase(),o=await Rt(t,e);return o?C(o,Ks)??"SKILL.md":"SKILL.md"}function _t(){if(process.env.CLAUDE_CODE||process.env.CLAUDE_PROJECT_DIR)return"claude-code"}var At=new WeakMap;async function It(n){let e=At.get(n);if(e)return e;let t=await n.getDocumentsByNamespaceAsync(H,z);if(t.length===0)throw new Error(`Could not find ${H}/${z} in the repository. Install a skill capability (which transitively imports agent-skills) or fetch agent-skills directly to populate the cache.`);let r=[...t].sort((c,l)=>{let u=c.metadata.namespace_?.version,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 Ss,s=new A(r,n),i=await a.parseKanonaks(s);return At.set(n,i),i}async function Rt(n,e){let t=await It(e),o=P(t,Ct);for(let r of o)if(C(r,Pt)===n)return r}async function As(n){let e=await It(n),t=P(e,Ct),o=[];for(let r of t){let a=C(r,Pt);a&&o.push(a)}return o}function Cs(n){return n.startsWith("~/")?cn(Kt(),n.slice(2)):n==="~"?Kt():n.startsWith("/")||/^[A-Za-z]:[\\/]/.test(n)?n:cn(process.cwd(),n)}import{readFileSync as Ps,writeFileSync as Es,existsSync as _s}from"fs";import{join as Tt}from"path";import xt from"js-yaml";var jt="skills.lock",Is=`# This file is generated by Kanonak CLI. Do not edit manually.
|
|
169
|
+
`;function je(n){let e=Tt(n,jt);if(!_s(e))return{version:"1",lastUpdated:new Date().toISOString(),skills:{}};let t=Ps(e,"utf-8"),o=xt.load(t);return!o||typeof o!="object"||o.version!=="1"?{version:"1",lastUpdated:new Date().toISOString(),skills:{}}:{version:"1",lastUpdated:o.lastUpdated??new Date().toISOString(),skills:o.skills??{}}}function un(n,e){e.lastUpdated=new Date().toISOString();let t={};for(let a of Object.keys(e.skills).sort())t[a]=e.skills[a];e.skills=t;let o=Tt(n,jt),r=xt.dump(e,{lineWidth:-1,sortKeys:!1,quotingType:'"'});Es(o,Is+r,"utf-8")}var Ut="kanonak.org",Nt="skill-to-skill-md",Oe=class{parser=new Ns;objectParser=new Us;runner=new B;async deploy(e){let{instances:t,allKanonaks:o,repository:r,options:a}=e;if(t.length===0){console.error("No Skill instances to deploy.");return}let s=await Ls(r,this.objectParser);if(!s){console.error(`Cannot deploy: ${Ut}/${Nt}@1.0.0 is not installed in the workspace or cache.`);return}let i=await this.runner.run({transformation:s,instances:t,allKanonaks:o,repository:r,parser:this.parser,objectParser:this.objectParser,outputFormat:"markdown-with-frontmatter"});if(i.length===0){console.error("No skills could be transformed from the package.");return}let c=await pe(a,r),l=await ln(a,r),u=je(c),d=t[0].namespace,{publisher:m,package_:g,version:h}=Fs(d);for(let f of i){let k=await xe(f.fileName,a,r),y=Ue(Ne(k,l));Rs(k,{recursive:!0}),js(Ne(k,l),f.content,"utf-8"),u.skills[f.fileName]={publisher:m,package_:g,version:h,resolved:m?`kanonak://${m}/${g}@${h}`:"",integrity:Os(f.content)},console.log(` ${y?"Updated":"Installed"} skill "${f.fileName}" \u2192 ${k}`)}un(c,u)}async undeploy(e,t){let{repository:o,options:r}=t,a=await xe(e,r,o);Ue(a)||(console.error(`Skill "${e}" is not installed at ${a}`),process.exit(1)),Ts(a,{recursive:!0,force:!0});let s=await pe(r,o),i=je(s);delete i.skills[e],un(s,i),console.log(`Removed skill "${e}" from ${a}`)}async list(e){let{repository:t,options:o}=e,r=await pe(o,t),a=je(r),s=[];for(let[c,l]of Object.entries(a.skills))s.push({name:c,publisher:l.publisher,package_:l.package_,version:l.version,path:await xe(c,o,t)});let i=await ln(o,t);if(Ue(r))try{let c=xs(r,{withFileTypes:!0});for(let l of c){if(!l.isDirectory()||a.skills[l.name])continue;let u=Ne(r,l.name,i);Ue(u)&&s.push({name:l.name,publisher:"",package_:"",version:"",path:Ne(r,l.name)})}}catch{}return s}};async function Ls(n,e){let t=await n.getDocumentsByNamespaceAsync(Ut,Nt);if(t.length===0)return;let o=new A(t[0],n),r=await e.parseKanonaks(o);return P(r,b.Transformation)[0]}function Fs(n){if(!n)return{publisher:"",package_:"",version:""};let e=n.indexOf("@");if(e===-1)return{publisher:"",package_:"",version:""};let t=n.substring(0,e),o=n.substring(e+1),r=t.indexOf("/");return r===-1?{publisher:"",package_:"",version:""}:{publisher:t.substring(0,r),package_:t.substring(r+1),version:o}}import{mkdirSync as ei,rmSync as ni,existsSync as mn,readdirSync as ti,writeFileSync as oi,statSync as ri}from"fs";import{join as Me}from"path";import{KanonakObjectParser as ai,KanonakParser as si,computeIntegrity as ii}from"@kanonak-protocol/sdk";import{join as Ot}from"path";import{homedir as Lt}from"os";import{KanonakObjectParser as Ms}from"@kanonak-protocol/sdk";var q="kanonak.org",G="agent-skills",Mt={publisher:q,package_:G,name:"Client"},Bt={publisher:q,package_:G,name:"clientId"},Bs={publisher:q,package_:G,name:"projectAgentDir"},Vs={publisher:q,package_:G,name:"userAgentDir"},Hs={publisher:q,package_:G,name:"agentFileFormat"},zs="agents";function qs(){if(process.env.CLAUDE_CODE||process.env.CLAUDE_PROJECT_DIR)return"claude-code"}async function Le(n,e){let t=(n.client??qs()??zs).toLowerCase(),o=n.scope??"project",r=await Gs(t,e);if(!r){let u=await Ws(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(r,o==="user"?Vs:Bs);if(!s)throw new Error(`Client "${t}" has no ${o==="user"?"userAgentDir":"projectAgentDir"} declared.`);let c=M(r,Hs)?.name==="toml"?"toml":"markdown-frontmatter",l=c==="toml"?".toml":".md";return{agentsDir:Xs(s),format:c,fileExtension:l}}var Ft=new WeakMap;async function Vt(n){let e=Ft.get(n);if(e)return e;let t=await n.getDocumentsByNamespaceAsync(q,G);if(t.length===0)throw new Error(`Could not find ${q}/${G} in the repository. Install a capability that imports agent-skills to populate the cache.`);let r=[...t].sort((c,l)=>{let u=c.metadata.namespace_?.version,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 Ms,s=new A(r,n),i=await a.parseKanonaks(s);return Ft.set(n,i),i}async function Gs(n,e){let t=await Vt(e),o=P(t,Mt);for(let r of o)if(C(r,Bt)===n)return r}async function Ws(n){let e=await Vt(n),t=P(e,Mt),o=[];for(let r of t){let a=C(r,Bt);a&&o.push(a)}return o}function Xs(n){return n.startsWith("~/")?Ot(Lt(),n.slice(2)):n==="~"?Lt():n.startsWith("/")||/^[A-Za-z]:[\\/]/.test(n)?n:Ot(process.cwd(),n)}import{readFileSync as Js,writeFileSync as Ys,existsSync as Zs}from"fs";import{join as Ht}from"path";import zt from"js-yaml";var qt="agents.lock",Qs=`# This file is generated by Kanonak CLI. Do not edit manually.
|
|
170
|
+
`;function Fe(n){let e=Ht(n,qt);if(!Zs(e))return{version:"1",lastUpdated:new Date().toISOString(),agents:{}};let t=Js(e,"utf-8"),o=zt.load(t);return!o||typeof o!="object"||o.version!=="1"?{version:"1",lastUpdated:new Date().toISOString(),agents:{}}:{version:"1",lastUpdated:o.lastUpdated??new Date().toISOString(),agents:o.agents??{}}}function dn(n,e){e.lastUpdated=new Date().toISOString();let t={};for(let a of Object.keys(e.agents).sort())t[a]=e.agents[a];e.agents=t;let o=Ht(n,qt),r=zt.dump(e,{lineWidth:-1,sortKeys:!1,quotingType:'"'});Ys(o,Qs+r,"utf-8")}var Gt="kanonak.org",Wt="agent-to-agent-file",Be=class{parser=new si;objectParser=new ai;runner=new B;async deploy(e){let{instances:t,allKanonaks:o,repository:r,options:a}=e;if(t.length===0){console.error("No Agent instances to deploy.");return}let{agentsDir:s,format:i,fileExtension:c}=await Le(a,r),l=await ci(r,this.objectParser);if(!l){console.error(`Cannot deploy: ${Gt}/${Wt}@1.0.0 is not installed in the workspace or cache.`);return}let u=i==="toml"?"toml":"markdown-with-frontmatter",d=await this.runner.run({transformation:l,instances:t,allKanonaks:o,repository:r,parser:this.parser,objectParser:this.objectParser,outputFormat:u});if(d.length===0){console.error("No agents could be transformed from the package.");return}ei(s,{recursive:!0});let m=Fe(s),g=t[0].namespace,{publisher:h,package_:f,version:k}=ui(g);for(let y of d){let w=`${y.fileName}${c}`,$=Me(s,w),v=mn($);oi($,y.content,"utf-8"),m.agents[y.fileName]={publisher:h,package_:f,version:k,resolved:h?`kanonak://${h}/${f}@${k}`:"",integrity:ii(y.content),fileName:w},console.log(` ${v?"Updated":"Installed"} agent "${y.fileName}" \u2192 ${$}`)}dn(s,m)}async undeploy(e,t){let{repository:o,options:r}=t,{agentsDir:a}=await Le(r,o),s=Fe(a),i=s.agents[e];i||(console.error(`Agent "${e}" is not installed at ${a}`),process.exit(1));let c=Me(a,i.fileName);mn(c)&&ni(c,{force:!0}),delete s.agents[e],dn(a,s),console.log(`Removed agent "${e}" from ${c}`)}async list(e){let{repository:t,options:o}=e,{agentsDir:r}=await Le(o,t),a=Fe(r),s=[];for(let[i,c]of Object.entries(a.agents))s.push({name:i,publisher:c.publisher,package_:c.package_,version:c.version,path:Me(r,c.fileName)});if(mn(r))try{let i=ti(r,{withFileTypes:!0});for(let c of i){if(!c.isFile()||c.name==="agents.lock")continue;let l=Me(r,c.name),u=li(c.name);if(!a.agents[u]){try{if(!ri(l).isFile())continue}catch{continue}s.push({name:u,publisher:"",package_:"",version:"",path:l})}}}catch{}return s}};async function ci(n,e){let t=await n.getDocumentsByNamespaceAsync(Gt,Wt);if(t.length===0)return;let o=new A(t[0],n),r=await e.parseKanonaks(o);return P(r,b.Transformation)[0]}function li(n){let e=n.lastIndexOf(".");return e===-1?n:n.substring(0,e)}function ui(n){if(!n)return{publisher:"",package_:"",version:""};let e=n.indexOf("@");if(e===-1)return{publisher:"",package_:"",version:""};let t=n.substring(0,e),o=n.substring(e+1),r=t.indexOf("/");return r===-1?{publisher:"",package_:"",version:""}:{publisher:t.substring(0,r),package_:t.substring(r+1),version:o}}var wi=fi(pi(import.meta.url)),$i=JSON.parse(mi(gi(wi,"..","package.json"),"utf-8")),O=new di;O.name("kanonak").description("Kanonak Protocol CLI - Validate and resolve Kanonak ontology packages").version($i.version);O.command("validate <path>").description("Validate .kan.yml file(s). Resolves imports via HTTP from publisher domains.").action(async n=>{await kn(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 Kn(n)});O.command("logout <publisher>").description("Revoke tokens and remove stored credentials for a publisher.").action(async n=>{await An(n)});O.addCommand(Mn());O.addCommand(mt());O.addCommand(yt());async function Si(){try{let n=new T,e=new hi,t=new yi,o=bi(t),r=new ki({fetchFn:o}),a=await x(process.cwd(),e),s=new Te;s.register("kanonak.org/capabilities/agent-skill-deployment",new Oe),s.register("kanonak.org/agent-capabilities/agent-instance-deployment",new Be);let i=await On(n,e,a),c=new Re(n,e,r,o,s,a);wt(O,i,c)}catch{}}await Si();O.parse();
|
|
@@ -28,6 +28,14 @@ export declare function resolveSkillsDir(options: SkillPathOptions, repository:
|
|
|
28
28
|
* Resolve the directory for a specific skill by name.
|
|
29
29
|
*/
|
|
30
30
|
export declare function resolveSkillDir(skillName: string, options: SkillPathOptions, repository: IKanonakDocumentRepository): Promise<string>;
|
|
31
|
+
/**
|
|
32
|
+
* Resolve the file name to use inside a skill directory for the
|
|
33
|
+
* configured Client. Pulled from the Client's `skillFileName` property
|
|
34
|
+
* in agent-skills@1.2.0+. Defaults to `SKILL.md` when the Client
|
|
35
|
+
* predates the property or doesn't declare it explicitly — which
|
|
36
|
+
* matches the Agent Skills convention every shipped Client follows.
|
|
37
|
+
*/
|
|
38
|
+
export declare function resolveSkillFileName(options: SkillPathOptions, repository: IKanonakDocumentRepository): Promise<string>;
|
|
31
39
|
/**
|
|
32
40
|
* Auto-detect the current AI agent client from environment variables.
|
|
33
41
|
* Returns a clientId matching a named Client instance in the
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kanonak-protocol/cli",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.4.0",
|
|
4
4
|
"description": "Kanonak Protocol CLI - Validate and resolve Kanonak ontology packages",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -34,8 +34,8 @@
|
|
|
34
34
|
"semantic-web"
|
|
35
35
|
],
|
|
36
36
|
"dependencies": {
|
|
37
|
-
"@kanonak-protocol/sdk": "^2.
|
|
38
|
-
"@kanonak-protocol/types": "^2.
|
|
37
|
+
"@kanonak-protocol/sdk": "^2.4.0",
|
|
38
|
+
"@kanonak-protocol/types": "^2.4.0",
|
|
39
39
|
"commander": "^13.0.0",
|
|
40
40
|
"js-yaml": "^4.1.1"
|
|
41
41
|
},
|