@kanonak-protocol/cli 1.2.0 → 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/capabilities/CapabilityLoader.d.ts +9 -1
- package/dist/index.js +30 -30
- package/package.json +3 -3
|
@@ -16,6 +16,14 @@ export interface LoadedCommand {
|
|
|
16
16
|
subcommandName: string;
|
|
17
17
|
description: string;
|
|
18
18
|
arguments: LoadedArgument[];
|
|
19
|
+
/**
|
|
20
|
+
* Name of the Action that this subcommand performs (e.g., "fetchAndDeploy",
|
|
21
|
+
* "listDeployed"). Extracted from the `performs` property on the Kanonak
|
|
22
|
+
* CapabilityCommand instance. Empty string when no action is specified — in
|
|
23
|
+
* that case the dispatcher falls back to interpreting the subcommand verb
|
|
24
|
+
* as a legacy action (add → fetchAndDeploy, list → listDeployed, etc.).
|
|
25
|
+
*/
|
|
26
|
+
actionName: string;
|
|
19
27
|
}
|
|
20
28
|
/**
|
|
21
29
|
* A fully loaded capability with its command structure.
|
|
@@ -24,7 +32,7 @@ export interface LoadedCapability {
|
|
|
24
32
|
commandName: string;
|
|
25
33
|
description: string;
|
|
26
34
|
managesType: string;
|
|
27
|
-
|
|
35
|
+
deploymentTargetName: string;
|
|
28
36
|
commands: LoadedCommand[];
|
|
29
37
|
publisher: string;
|
|
30
38
|
package_: string;
|
package/dist/index.js
CHANGED
|
@@ -1,26 +1,26 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import{Command as
|
|
3
|
-
`).some(r=>r.trim()===t||r.trim()===t+"/"))return;
|
|
2
|
+
import{Command as yn}from"commander";import{readFileSync as kn}from"fs";import{fileURLToPath as bn}from"url";import{dirname as wn,join as vn}from"path";import{KanonakParser as $n,PublisherIndex as Sn,CredentialStore as Cn,createAuthenticatedFetch as Pn}from"@kanonak-protocol/sdk";import{readFileSync as Ge,statSync as Be}from"fs";import{resolve as Je,dirname as Xe}from"path";import{KanonakParser as Ye,KanonakObjectValidator as Qe,ValidationSeverity as se}from"@kanonak-protocol/sdk";import{readFileSync as Ke,readdirSync as Ue}from"fs";import{join as He,dirname as ze,basename as re}from"path";import{InMemoryKanonakDocumentRepository as Ve,FileSystemKanonakDocumentRepository as Me,HttpKanonakDocumentRepository as We,getGlobalCachePath as qe}from"@kanonak-protocol/sdk";import{mkdirSync as Oe,readFileSync as ne,writeFileSync as oe,existsSync as q,appendFileSync as Ne}from"fs";import{join as Le,dirname as Ee,isAbsolute as Fe}from"path";import{getGlobalCachePath as je}from"@kanonak-protocol/sdk";var $=class{constructor(e=je()){this.cacheDir=e;this.isProjectLocal=!Fe(e)}cacheDir;gitignoreChecked=!1;isProjectLocal;get(e,t,o){let r=this.getPath(e,t,o);return q(r)?ne(r,"utf-8"):null}put(e,t,o,r){let s=this.getPath(e,t,o);Oe(Ee(s),{recursive:!0}),oe(s,r,"utf-8"),this.isProjectLocal&&this.ensureGitignore()}has(e,t,o){return q(this.getPath(e,t,o))}ensureGitignore(){if(this.gitignoreChecked)return;this.gitignoreChecked=!0;let e=".gitignore",t=this.cacheDir;if(q(e)){if(ne(e,"utf-8").split(`
|
|
3
|
+
`).some(r=>r.trim()===t||r.trim()===t+"/"))return;Ne(e,`
|
|
4
4
|
${t}/
|
|
5
|
-
`)}else
|
|
6
|
-
`)}getPath(e,t,o){return
|
|
5
|
+
`)}else oe(e,`${t}/
|
|
6
|
+
`)}getPath(e,t,o){return Le(this.cacheDir,e,`${t}@${o}.kan.yml`)}};function O(n){let e=n;for(;;){let t=ze(e);if(t===e)break;if(re(e).includes(".")||re(t).includes(".")){e=t;continue}break}return e}function F(n,e){for(let t of Ue(n,{withFileTypes:!0})){let o=He(n,t.name);t.isDirectory()&&t.name!=="node_modules"&&t.name!==".kanonak"?F(o,e):t.name.endsWith(".kan.yml")&&e.push(o)}}var G=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 j(n,e){let t=[];F(n,t);let o=new Ve(e);for(let a of t)try{let c=Ke(a,"utf-8"),l=e.parse(c),d=l.metadata.namespace_;if(d){let p=`${d.publisher}/${d.package_}@${d.version}`;await o.saveDocumentAsync(l,p)}}catch{}let r=new Me(qe(),!0,e),s=new $,i=new We({getFromCache:(a,c,l)=>s.get(a,c,l),onFetch:(a,c,l,d)=>s.put(a,c,l,d)});return new G(o,r,i)}async function ie(n){let e=Je(n),t=Be(e),o=t.isDirectory()?O(e):O(Xe(e)),r=new Ye,s=new Qe(r),i=await j(o,r),a=[];if(t.isDirectory()?F(e,a):a.push(e),a.length===0){console.log("No .kan.yml files found.");return}let c=0,l=0;for(let d of a){let p=Ge(d,"utf-8"),u=r.parseWithErrors(p);if(u.errors&&u.errors.length>0){console.log(`
|
|
7
7
|
${d}:`);for(let f of u.errors)console.log(` ERROR (parse): ${f.message} [line ${f.line}:${f.column}]`),c++;continue}let y=u.document;if(!y){console.log(`
|
|
8
|
-
${d}:`),console.log(" ERROR: Failed to parse document"),c++;continue}let m=await s.validateAsync(y,i),g=m.errors.filter(f=>f.severity===
|
|
8
|
+
${d}:`),console.log(" ERROR: Failed to parse document"),c++;continue}let m=await s.validateAsync(y,i),g=m.errors.filter(f=>f.severity===se.Error),k=m.errors.filter(f=>f.severity===se.Warning);if(g.length>0||k.length>0){let f=y.metadata.namespace_,h=f?`${f.publisher}/${f.package_}@${f.version}`:d;console.log(`
|
|
9
9
|
${h}:`);for(let b of g)console.log(` ERROR: ${b.message}`),b.suggestion&&console.log(` -> ${b.suggestion}`);for(let b of k)console.log(` WARN: ${b.message}`)}c+=g.length,l+=k.length}console.log(`
|
|
10
|
-
${a.length} file(s) validated. ${c} error(s), ${l} warning(s).`),c>0&&process.exit(1)}import{KanonakParser as
|
|
11
|
-
`;function
|
|
12
|
-
Installed ${Object.keys(i.packages).length} package(s) from lock file.`);return}let a=
|
|
13
|
-
Installed ${u.size} package(s).`)}async function
|
|
10
|
+
${a.length} file(s) validated. ${c} error(s), ${l} warning(s).`),c>0&&process.exit(1)}import{KanonakParser as rt,PublisherIndex as st,CredentialStore as it,createAuthenticatedFetch as at}from"@kanonak-protocol/sdk";import{readFileSync as Ze,writeFileSync as et,existsSync as tt}from"fs";import{createHash as nt}from"crypto";import ae from"js-yaml";var B="kanonak.lock",ot=`# This file is generated by Kanonak CLI. Do not edit manually.
|
|
11
|
+
`;function ce(){if(!tt(B))return null;let n=Ze(B,"utf-8"),e=ae.load(n);return!e||typeof e!="object"||e.version!=="1"?null:{version:"1",lastUpdated:e.lastUpdated??new Date().toISOString(),packages:e.packages??{}}}function le(n){n.lastUpdated=new Date().toISOString();let e={};for(let o of Object.keys(n.packages).sort())e[o]=n.packages[o];n.packages=e;let t=ae.dump(n,{lineWidth:-1,sortKeys:!1,quotingType:'"'});et(B,ot+t,"utf-8")}function D(n){return`sha256:${nt("sha256").update(n).digest("hex")}`}function T(n){let e=n.indexOf("@"),t,o=null;e!==-1?(t=n.substring(0,e),o=n.substring(e+1)||null):t=n;let r=t.indexOf("/");if(r===-1)return null;let s=t.substring(0,r),i=t.substring(r+1);return!s||!i?null:{publisher:s,packageName:i,version:o}}async function de(n){let e=new $,t=new rt,o=new it,r=at(o),s=new st({fetchFn:r}),i=ce()??{version:"1",lastUpdated:new Date().toISOString(),packages:{}};if(!n){Object.keys(i.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(i.packages).length} package(s) from kanonak.lock...`);for(let[y,m]of Object.entries(i.packages)){let g=y.indexOf("/"),k=y.substring(0,g),f=y.substring(g+1),h=e.get(k,f,m.version);if(h)console.log(` ${y}@${m.version} (cached)`);else{let b=m.resolved,w=await r(b,k);if(!w.ok)throw new Error(`Failed to fetch ${b} (${w.status} ${w.statusText})`);h=await w.text(),e.put(k,f,m.version,h),console.log(` ${y}@${m.version}`)}}console.log(`
|
|
12
|
+
Installed ${Object.keys(i.packages).length} package(s) from lock file.`);return}let a=T(n);a||(console.error(`Invalid package reference: ${n}`),console.error("Expected format: {publisher}/{package}@{version} or {publisher}/{package}"),process.exit(1));let{publisher:c,packageName:l,version:d}=a,p=d??await s.getHighestVersion(c,l);p||(console.error(`Could not resolve version for ${c}/${l}`),process.exit(1)),console.log(`Installing ${c}/${l}@${p}...`);let u=new Set;await pe(c,l,p,e,t,s,r,u,i),le(i),console.log(`
|
|
13
|
+
Installed ${u.size} package(s).`)}async function pe(n,e,t,o,r,s,i,a,c){let l=`${n}/${e}@${t}`;if(a.has(l))return;a.add(l);let d=`${n}/${e}`,p=o.get(n,e,t),u;if(p)console.log(` ${l} (cached)`),u=await s.getPackageUrl(n,e,t);else{u=await s.getPackageUrl(n,e,t);let g=await i(u,n);if(!g.ok)throw new Error(`Failed to fetch ${u} (${g.status} ${g.statusText})`);p=await g.text(),o.put(n,e,t,p),console.log(` ${l}`)}let y={},m=r.parse(p);if(m.metadata.imports)for(let[g,k]of Object.entries(m.metadata.imports))for(let f of k){let h=await s.resolveVersion(g,f);h?(y[`${g}/${f.packageName}`]=h,await pe(g,f.packageName,h,o,r,s,i,a,c)):console.error(` WARNING: Could not resolve ${g}/${f.packageName} ${f.package_}`)}c.packages[d]={version:t,resolved:u,integrity:D(p),dependencies:y}}import{readFileSync as ct}from"fs";import{resolve as lt,dirname as dt}from"path";import{KanonakParser as pt}from"@kanonak-protocol/sdk";async function ue(n){let e=lt(n),t=ct(e,"utf-8"),o=new pt,r=o.parse(t),s=r.metadata.namespace_,i=s?`${s.publisher}/${s.package_}@${s.version}`:n;if(console.log(i),!r.metadata.imports){console.log(" (no imports)");return}let a=O(dt(e)),c=await j(a,o),l=new Set;for(let[d,p]of Object.entries(r.metadata.imports))for(let u of p)await ge(d,u,c,l," ")}async function ge(n,e,t,o,r){let s=`${n}/${e.packageName}`;if(o.has(s)){console.log(`${r}${s} (${e.package_}) [circular]`);return}o.add(s);let i;try{i=await t.getHighestCompatibleVersionAsync(n,e)}catch{console.log(`${r}${s} (${e.package_}) [fetch failed]`);return}if(!i){console.log(`${r}${s} (${e.package_}) [not found]`);return}let a=i.metadata.namespace_?.version?.toString()??"?";if(console.log(`${r}${n}/${e.packageName}@${a}`),i.metadata.imports)for(let[c,l]of Object.entries(i.metadata.imports))for(let d of l)await ge(c,d,t,o,r+" ")}import{createHash as gt,randomBytes as he}from"crypto";import{createServer as mt}from"http";import{execFile as J}from"child_process";import{CredentialStore as ft,generateDPoPKeyPair as ht,createDPoPProof as me,serverSupportsDPoP as yt}from"@kanonak-protocol/sdk";import{normalizeHost as ut}from"@kanonak-protocol/sdk";var P=class{cache=new Map;async discover(e){let t=ut(e);if(this.cache.has(t))return this.cache.get(t);let o=`https://${t}/.well-known/oauth-authorization-server`,r=await this.tryEndpoint(o);if(!r){let s=`https://${t}/.well-known/openid-configuration`;r=await this.tryEndpoint(s)}return this.cache.set(t,r),r}async supportsOAuth(e){return await this.discover(e)!==null}static supportsPkceS256(e){return e.codeChallengeMethodsSupported?.some(t=>t.toUpperCase()==="S256")??!1}static supportsDynamicRegistration(e){return!!e.registrationEndpoint}static supportsAuthorizationCode(e){return e.responseTypesSupported?.some(t=>t.toLowerCase()==="code")??!1}async tryEndpoint(e){let t;try{t=await fetch(e)}catch(r){let s=r instanceof Error?r.message:String(r);return s.includes("ENOTFOUND")||s.includes("ECONNREFUSED")?(console.error(` OAuth discovery: ${e} \u2014 host unreachable (${s})`),console.error(" If the server is behind a VPN, ensure you are connected.")):s.includes("CERT")||s.includes("SSL")||s.includes("TLS")?(console.error(` OAuth discovery: ${e} \u2014 TLS error (${s})`),console.error(" If using a custom CA certificate, set NODE_EXTRA_CA_CERTS=/path/to/ca.pem")):console.error(` OAuth discovery: ${e} \u2014 network error: ${s}`),null}if(!t.ok)return t.status===404||(t.status===403?(console.error(` OAuth discovery: ${e} \u2014 HTTP 403 Forbidden`),console.error(" Access may be blocked by a firewall, proxy, or WAF.")):t.status>=500&&(console.error(` OAuth discovery: ${e} \u2014 HTTP ${t.status} server error`),console.error(" The authorization server returned an internal error. Contact your IDP administrator."))),null;let o;try{o=await t.json()}catch{return console.error(` OAuth discovery: ${e} \u2014 response is not valid JSON`),console.error(" The endpoint may be returning HTML instead of JSON. Check IDP configuration."),null}return{issuer:N(o.issuer),authorizationEndpoint:N(o.authorization_endpoint),tokenEndpoint:N(o.token_endpoint),registrationEndpoint:N(o.registration_endpoint),revocationEndpoint:N(o.revocation_endpoint),scopesSupported:x(o.scopes_supported),responseTypesSupported:x(o.response_types_supported),grantTypesSupported:x(o.grant_types_supported),codeChallengeMethodsSupported:x(o.code_challenge_methods_supported),tokenEndpointAuthMethodsSupported:x(o.token_endpoint_auth_methods_supported),dpopSigningAlgValuesSupported:x(o.dpop_signing_alg_values_supported)}}};function N(n){return typeof n=="string"?n:null}function x(n){return Array.isArray(n)?n.filter(e=>typeof e=="string"):null}var I=class{discovery;credentialStore;constructor(e,t){this.discovery=e??new P,this.credentialStore=t??new ft}async authorize(e,t=[]){console.log(`Starting OAuth flow for ${e}...`);let o=await this.discovery.discover(e);if(!o)return v(`No OAuth discovery endpoint found for '${e}'.
|
|
14
14
|
The server must expose one of:
|
|
15
15
|
- https://${e}/.well-known/oauth-authorization-server (RFC 8414)
|
|
16
16
|
- https://${e}/.well-known/openid-configuration (OpenID Connect)
|
|
17
17
|
Verify the hostname is correct and HTTPS is configured.
|
|
18
18
|
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 v(`OAuth metadata for '${e}' is missing required fields: ${r.join(", ")}.
|
|
19
|
-
Contact the IDP administrator to ensure these are included in the discovery document.`);let s=
|
|
20
|
-
Ensure your Node.js installation supports EC P-256 curves.`)}}let{redirectUri:a,port:c,waitForCallback:l,close:d}=await
|
|
19
|
+
Contact the IDP administrator to ensure these are included in the discovery document.`);let s=yt(o.dpopSigningAlgValuesSupported),i=null;if(s){console.log(" Server supports DPoP (RFC 9449) \u2014 generating key pair...");try{i=ht()}catch(C){return v(`Failed to generate DPoP key pair: ${A(C)}
|
|
20
|
+
Ensure your Node.js installation supports EC P-256 curves.`)}}let{redirectUri:a,port:c,waitForCallback:l,close:d}=await Ct(),p=await this.credentialStore.getCredential(e),u=p?.clientId??null,y=p?.clientSecret??null;if(!u&&o.registrationEndpoint){console.log(" Registering dynamic OAuth client (RFC 7591)...");let C=await this.registerClient(o.registrationEndpoint,a);if(!C.success)return d(),v(C.error);u=C.clientId,y=C.clientSecret??null}if(!u)return d(),v(`No OAuth client credentials for '${e}' and the server does not support dynamic client registration (no registration_endpoint in metadata).
|
|
21
21
|
You must pre-register a client with your IDP and configure the client_id.
|
|
22
22
|
Ask your IDP administrator to enable dynamic client registration (RFC 7591),
|
|
23
|
-
or add a registration_endpoint to the OAuth metadata.`);let m=
|
|
23
|
+
or add a registration_endpoint to the OAuth metadata.`);let m=bt(),g=wt(m),k=vt(),f=$t(o.authorizationEndpoint,u,a,t,k,g);console.log(` Opening browser for authorization on port ${c}...`),console.log(" If the browser doesn't open, navigate to:"),console.log(` ${f}`),Rt(f);let h=await l();if(d(),!h)return v(`Authorization timed out after 5 minutes.
|
|
24
24
|
The browser authorization was not completed in time.
|
|
25
25
|
Re-run 'kanonak login ${e}' and complete the browser authorization promptly.`);if(!h.code){let C=h.error?`: ${h.error}`:"";return v(`No authorization code received${C}.
|
|
26
26
|
The IDP may have rejected the authorization request.
|
|
@@ -33,41 +33,41 @@ Installed ${u.size} package(s).`)}async function le(n,e,t,o,r,s,i,a,c){let l=`${
|
|
|
33
33
|
The OAuth discovery endpoint may be unreachable.
|
|
34
34
|
Check network connectivity and run 'kanonak login ${e}' to re-authenticate.`);o=s.tokenEndpoint}let r=await this.refreshTokenRequest(o,t.clientId,t.clientSecret,t.refreshToken,t.dpopKeyPair);return r.success?(t.accessToken=r.tokens.accessToken,r.tokens.refreshToken&&(t.refreshToken=r.tokens.refreshToken),t.expiresAt=r.tokens.expiresIn?new Date(Date.now()+r.tokens.expiresIn*1e3).toISOString():null,t.tokenEndpoint=o,await this.credentialStore.store(e,t),{success:!0,host:e}):v(`${r.error}
|
|
35
35
|
The refresh token may have expired. Run 'kanonak login ${e}' to re-authenticate.`)}async logout(e){let t=await this.credentialStore.getCredential(e);if(!t)return v(`No stored credentials for '${e}'.
|
|
36
|
-
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(i){return{success:!1,error:`Dynamic client registration request to ${e} failed: ${
|
|
36
|
+
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(i){return{success:!1,error:`Dynamic client registration request to ${e} failed: ${A(i)}
|
|
37
37
|
Ensure the IDP is reachable and HTTPS is properly configured.
|
|
38
38
|
If using a corporate proxy or custom CA, set NODE_EXTRA_CA_CERTS.`}}if(!o.ok){let i=await X(o);return{success:!1,error:`Dynamic client registration (RFC 7591) failed.
|
|
39
39
|
Endpoint: ${e}
|
|
40
40
|
HTTP ${o.status}: ${i}
|
|
41
41
|
The IDP may not support dynamic registration for public clients.
|
|
42
42
|
Ask your IDP administrator to enable RFC 7591 support, or pre-register a client manually.`}}let r=await o.json(),s=r.client_id;return s?{success:!0,clientId:s,clientSecret:r.client_secret}:{success:!1,error:`Dynamic client registration response from ${e} did not contain a client_id.
|
|
43
|
-
The IDP response may be malformed. Contact your IDP administrator.`}}async exchangeCode(e,t,o,r,s,i,a){let c=new URLSearchParams({grant_type:"authorization_code",client_id:t,code:r,redirect_uri:s,code_verifier:i});o&&c.set("client_secret",o);let l={"Content-Type":"application/x-www-form-urlencoded"};if(a)try{l.DPoP=
|
|
44
|
-
The stored key pair may be corrupted. Run 'kanonak login' to re-authenticate.`}}let d;try{d=await fetch(e,{method:"POST",headers:l,body:c.toString()})}catch(p){return{success:!1,error:`Token exchange request to ${e} failed: ${
|
|
45
|
-
Ensure the token endpoint is reachable.`}}if(!d.ok){let p=await X(d),u=
|
|
43
|
+
The IDP response may be malformed. Contact your IDP administrator.`}}async exchangeCode(e,t,o,r,s,i,a){let c=new URLSearchParams({grant_type:"authorization_code",client_id:t,code:r,redirect_uri:s,code_verifier:i});o&&c.set("client_secret",o);let l={"Content-Type":"application/x-www-form-urlencoded"};if(a)try{l.DPoP=me(a.privateKey,a.publicKey,"POST",e)}catch(p){return{success:!1,error:`Failed to create DPoP proof for token exchange: ${A(p)}
|
|
44
|
+
The stored key pair may be corrupted. Run 'kanonak login' to re-authenticate.`}}let d;try{d=await fetch(e,{method:"POST",headers:l,body:c.toString()})}catch(p){return{success:!1,error:`Token exchange request to ${e} failed: ${A(p)}
|
|
45
|
+
Ensure the token endpoint is reachable.`}}if(!d.ok){let p=await X(d),u=kt(p);return{success:!1,error:`Token exchange failed.
|
|
46
46
|
Endpoint: ${e}
|
|
47
47
|
HTTP ${d.status}: ${p}`+(u?`
|
|
48
|
-
${u}`:"")}}return{success:!0,tokens:
|
|
48
|
+
${u}`:"")}}return{success:!0,tokens:fe(await d.json())}}async refreshTokenRequest(e,t,o,r,s){let i=new URLSearchParams({grant_type:"refresh_token",client_id:t,refresh_token:r});o&&i.set("client_secret",o);let a={"Content-Type":"application/x-www-form-urlencoded"};if(s)try{a.DPoP=me(s.privateKey,s.publicKey,"POST",e)}catch(l){return{success:!1,error:`Failed to create DPoP proof for token refresh: ${A(l)}`}}let c;try{c=await fetch(e,{method:"POST",headers:a,body:i.toString()})}catch(l){return{success:!1,error:`Token refresh request to ${e} failed: ${A(l)}`}}if(!c.ok){let l=await X(c);return{success:!1,error:`Token refresh failed \u2014 HTTP ${c.status}: ${l}`}}return{success:!0,tokens:fe(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 v(n){return{success:!1,error:n}}function fe(n){return{accessToken:n.access_token,refreshToken:n.refresh_token,expiresIn:typeof n.expires_in=="number"?n.expires_in:void 0}}function A(n){return n instanceof Error?n.message:String(n)}async function X(n){try{return await n.text()}catch{return"(could not read response body)"}}function kt(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 bt(){return he(32).toString("base64url")}function wt(n){return gt("sha256").update(n).digest("base64url")}function vt(){return he(16).toString("base64url")}function $t(n,e,t,o,r,s){let i=new URLSearchParams({client_id:e,response_type:"code",redirect_uri:t,scope:o.join(" "),state:r,code_challenge:s,code_challenge_method:"S256"});return`${n}?${i}`}var St=300*1e3;async function Ct(){return new Promise(n=>{let e=mt((r,s)=>{let i=new URL(r.url,"http://localhost"),a=i.searchParams.get("code")??void 0,c=i.searchParams.get("state")??void 0,l=i.searchParams.get("error")??i.searchParams.get("error_description")??void 0,d=l?Pt(l):null,p=d?`<html><body><h1>Authorization failed</h1><p>${d}</p></body></html>`:"<html><body><h1>Authorization successful!</h1><p>You can close this window.</p></body></html>";s.writeHead(200,{"Content-Type":"text/html"}),s.end(p),t({code:a,state:c,error:l})}),t,o=new Promise(r=>{t=r,setTimeout(()=>{r(null),e.close()},St)});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 Pt(n){return n.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""")}function Rt(n){try{process.platform==="win32"?J("cmd",["/c","start","",n]):process.platform==="darwin"?J("open",[n]):J("xdg-open",[n])}catch{console.log(" Could not open browser automatically. Please navigate to the URL above manually.")}}import{CredentialStore as Dt}from"@kanonak-protocol/sdk";async function ye(n){try{let e=new P,t=new Dt,r=await new I(e,t).authorize(n);r.success?console.log(`
|
|
49
49
|
Authenticated with ${n}.`):(console.error(`
|
|
50
50
|
Authentication failed:
|
|
51
51
|
${r.error}`),process.exit(1))}catch(e){let t=e instanceof Error?e.message:String(e);console.error(`
|
|
52
52
|
Authentication failed unexpectedly:
|
|
53
53
|
${t}`),console.error(`
|
|
54
|
-
If this persists, file an issue at https://github.com/kanonak-protocol/typescript/issues`),process.exit(1)}}import{CredentialStore as
|
|
54
|
+
If this persists, file an issue at https://github.com/kanonak-protocol/typescript/issues`),process.exit(1)}}import{CredentialStore as Tt}from"@kanonak-protocol/sdk";async function ke(n){try{let e=new P,t=new Tt,r=await new I(e,t).logout(n);r.success?console.log(`Logged out from ${n}.`):(console.error(`
|
|
55
55
|
Logout failed:
|
|
56
56
|
${r.error}`),process.exit(1))}catch(e){let t=e instanceof Error?e.message:String(e);console.error(`
|
|
57
57
|
Logout failed unexpectedly:
|
|
58
|
-
${t}`),process.exit(1)}}import{Command as
|
|
59
|
-
`;function
|
|
60
|
-
Installed capability "${y}".`),console.log(`Run "kanonak ${y} --help" to get started.`)}async function
|
|
61
|
-
`);for(let[t,o]of e)console.log(` ${t} ${o.publisher}/${o.package_}@${o.version}`)}async function
|
|
62
|
-
`);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 r=this.handlerRegistry.get(e.
|
|
58
|
+
${t}`),process.exit(1)}}import{Command as Lt}from"commander";import{KanonakParser as Et,PublisherIndex as Ft,CredentialStore as jt,createAuthenticatedFetch as Kt}from"@kanonak-protocol/sdk";import{readFileSync as xt,writeFileSync as At,existsSync as It}from"fs";import{join as _t}from"path";import be from"js-yaml";import{getGlobalCachePath as Ot}from"@kanonak-protocol/sdk";var Nt=`# This file is generated by Kanonak CLI. Do not edit manually.
|
|
59
|
+
`;function we(){let n=Ot();return _t(n,"..","capabilities.lock")}function _(){let n=we();if(!It(n))return{version:"1",lastUpdated:new Date().toISOString(),capabilities:{}};let e=xt(n,"utf-8"),t=be.load(e);return!t||typeof t!="object"||t.version!=="1"?{version:"1",lastUpdated:new Date().toISOString(),capabilities:{}}:{version:"1",lastUpdated:t.lastUpdated??new Date().toISOString(),capabilities:t.capabilities??{}}}function Y(n){n.lastUpdated=new Date().toISOString();let e={};for(let o of Object.keys(n.capabilities).sort())e[o]=n.capabilities[o];n.capabilities=e;let t=be.dump(n,{lineWidth:-1,sortKeys:!1,quotingType:'"'});At(we(),Nt+t,"utf-8")}function ve(){let n=new Lt("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 Ut(e)}),n.command("remove <name>").description("Remove an installed capability").action(async e=>{await Ht(e)}),n.command("list").description("List installed capabilities").action(async()=>{await zt()}),n}async function Ut(n){let e=T(n);e||(console.error(`Invalid package reference: ${n}`),console.error("Expected format: {publisher}/{package}@{version} or {publisher}/{package}"),process.exit(1));let{publisher:t,packageName:o,version:r}=e,s=new $,i=new Et,a=new jt,c=Kt(a),l=new Ft({fetchFn:c}),d=r??await l.getHighestVersion(t,o);d||(console.error(`Could not resolve version for ${t}/${o}`),process.exit(1)),console.log(`Installing capability ${t}/${o}@${d}...`);let p=s.get(t,o,d);if(!p){let g=await l.getPackageUrl(t,o,d),k=await c(g,t);if(!k.ok)throw new Error(`Failed to fetch ${g} (${k.status} ${k.statusText})`);p=await k.text(),s.put(t,o,d,p)}let u=i.parse(p),y=null;for(let[,g]of Object.entries(u.body)){if(!g||typeof g!="object")continue;let k=String(g.type??"");if(k==="Capability"||k.endsWith(".Capability")){y=g.commandName??null;break}}y||(console.error(`Package ${t}/${o}@${d} does not contain a Capability instance.`),process.exit(1));let m=_();m.capabilities[y]={publisher:t,package_:o,version:d,resolved:await l.getPackageUrl(t,o,d),integrity:D(p)},Y(m),console.log(`
|
|
60
|
+
Installed capability "${y}".`),console.log(`Run "kanonak ${y} --help" to get started.`)}async function Ht(n){let e=_();e.capabilities[n]||(console.error(`Capability "${n}" is not installed.`),process.exit(1));let t=e.capabilities[n];delete e.capabilities[n],Y(e),console.log(`Removed capability "${n}" (${t.publisher}/${t.package_}@${t.version}).`)}async function zt(){let n=_(),e=Object.entries(n.capabilities);if(e.length===0){console.log("No capabilities installed."),console.log("Install one with: kanonak capability add {publisher}/{package}");return}console.log(`Installed capabilities:
|
|
61
|
+
`);for(let[t,o]of e)console.log(` ${t} ${o.publisher}/${o.package_}@${o.version}`)}async function $e(n,e){let t=_(),o=[];for(let[r,s]of Object.entries(t.capabilities)){let i=n.get(s.publisher,s.package_,s.version);if(!i){console.error(` WARNING: Cached content missing for capability "${r}" (${s.publisher}/${s.package_}@${s.version})`);continue}try{let a=e.parse(i),c=Vt(a.body,r,s.publisher,s.package_,s.version);c&&o.push(c)}catch(a){console.error(` WARNING: Failed to parse capability "${r}": ${a}`)}}return o}function Vt(n,e,t,o,r){for(let[,s]of Object.entries(n)){if(!s||typeof s!="object")continue;let i=String(s.type??"");if(i!=="Capability"&&!i.endsWith(".Capability"))continue;let a=s.commandName??e,c=s.description??"",l=Mt(s.managesType),d=Wt(s.deploymentTarget),p=qt(s.hasCommand);return{commandName:a,description:c,managesType:l,deploymentTargetName:d,commands:p,publisher:t,package_:o,version:r}}return null}function Mt(n){return typeof n=="string"?Q(n):""}function Wt(n){return typeof n=="string"?Q(n):""}function Se(n){return n==null?[]:Array.isArray(n)?n.filter(e=>typeof e=="object"&&e!==null&&!Array.isArray(e)):typeof n=="object"?Object.entries(n).filter(([,t])=>typeof t=="object"&&t!==null&&!Array.isArray(t)).map(([t,o])=>({__key:t,...o})):[]}function Q(n){if(typeof n!="string")return"";let e=n.indexOf(".");return e===-1?n:n.slice(e+1)}function qt(n){return Se(n).map(e=>({subcommandName:String(e.subcommandName??e.__key??""),description:String(e.description??""),arguments:Gt(e.hasArgument),actionName:Q(e.performs)}))}function Gt(n){return Se(n).map(e=>({argumentName:String(e.argumentName??e.__key??""),required:e.isRequired===!0,isOption:e.isOption===!0,...e.defaultValue!=null?{defaultValue:String(e.defaultValue)}:{}}))}import{Command as Ce}from"commander";var Z={fetchAndDeploy:(n,e,t,o)=>n.add(e,t[0],o),removeDeployed:(n,e,t,o)=>n.remove(e,t[0],o),listDeployed:(n,e,t,o)=>n.list(e,o),updateDeployed:(n,e,t,o)=>n.update(e,t[0],o),searchAvailable:(n,e,t,o)=>n.search(e,o),showInfo:(n,e,t,o)=>n.info(e,t[0],o)};function Pe(n,e,t){for(let o of e){let r=new Ce(o.commandName).description(o.description.trim());for(let s of o.commands){let i=r.command(Bt(s));i.description(s.description);for(let a of s.arguments)if(a.isOption){let c=a.defaultValue!=null?`--${a.argumentName} [value]`:`--${a.argumentName} <value>`;i.option(c,"",a.defaultValue)}i.action(async(...a)=>{let c=Jt(a);await Xt(t,o,s,a,c)})}n.addCommand(r)}}function Bt(n){let e=n.arguments.filter(t=>!t.isOption).map(t=>t.required?`<${t.argumentName}>`:`[${t.argumentName}]`);return[n.subcommandName,...e].join(" ")}function Jt(n){for(let e=n.length-1;e>=0;e--)if(n[e]&&typeof n[e]=="object"&&!(n[e]instanceof Ce))return n[e];return{}}async function Xt(n,e,t,o,r){let s=[];for(let a of o)if(typeof a=="string")s.push(a);else break;t.actionName||(console.error(`Capability subcommand '${t.subcommandName}' has no \`performs\` Action. Every CapabilityCommand must declare a \`performs:\` value pointing at a named Action instance from the capabilities ontology. Known actions: ${Object.keys(Z).join(", ")}.`),process.exit(1));let i=Z[t.actionName];i||(console.error(`Capability subcommand '${t.subcommandName}' references unknown Action '${t.actionName}'. Known actions: ${Object.keys(Z).join(", ")}.`),process.exit(1)),await i(n,e,s,r)}import{PublisherIndex as ee,PublisherConfigResolver as Yt,InMemoryKanonakDocumentRepository as Re,findInstancesByType as De}from"@kanonak-protocol/sdk";var K=class{constructor(e,t,o,r,s){this.fileCache=e;this.parser=t;this.publisherIndex=o;this.fetchFn=r;this.handlerRegistry=s}fileCache;parser;publisherIndex;fetchFn;handlerRegistry;async add(e,t,o){let r=T(t);r||(console.error(`Invalid package reference: ${t}`),console.error("Expected format: {publisher}/{package}@{version} or {publisher}/{package}"),process.exit(1));let{publisher:s,packageName:i,version:a}=r,c=a??await this.publisherIndex.getHighestVersion(s,i);c||(console.error(`Could not resolve version for ${s}/${i}`),process.exit(1));let l=this.fileCache.get(s,i,c);if(!l){let f=await this.publisherIndex.getPackageUrl(s,i,c),h=await this.fetchFn(f,s);if(!h.ok)throw new Error(`Failed to fetch ${f} (${h.status} ${h.statusText})`);l=await h.text(),this.fileCache.put(s,i,c,l)}let d=this.parser.parse(l),p=new Re(this.parser),u=d.metadata.namespace_,y=u?.version?`${u.version.major}.${u.version.minor}.${u.version.patch}`:"0.0.0",m=u?`${u.publisher}/${u.package_}/${y}`:t;await p.saveDocumentAsync(d,m);let g=await De(p,e.managesType);g.length===0&&(console.error(`Package ${s}/${i}@${c} does not contain any ${e.managesType} instances.`),process.exit(1));let k=this.handlerRegistry.get(e.deploymentTargetName);k?await k.deploy(d,g,o):console.log(`Cached ${s}/${i}@${c} (no deployment handler for "${e.deploymentTargetName}")`)}async remove(e,t,o){let r=this.handlerRegistry.get(e.deploymentTargetName);r||(console.error(`No deployment handler registered for "${e.deploymentTargetName}"`),process.exit(1)),await r.undeploy(t,o)}async list(e,t){let o=this.handlerRegistry.get(e.deploymentTargetName);o||(console.error(`No deployment handler registered for "${e.deploymentTargetName}"`),process.exit(1));let r=await o.list(t);if(r.length===0){console.log(`No ${e.managesType} instances installed.`);return}console.log(`Installed ${e.managesType} instances:
|
|
62
|
+
`);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 r=this.handlerRegistry.get(e.deploymentTargetName);r||(console.error(`No deployment handler registered for "${e.deploymentTargetName}"`),process.exit(1));let s=await r.list(o),i=t?s.filter(c=>c.name===t):s.filter(c=>c.publisher);if(i.length===0){console.log(t?`Skill "${t}" not found.`:"No managed instances to update.");return}let a=0;for(let c of i){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),a++)}console.log(a===0?"All instances are up to date.":`
|
|
63
63
|
Updated ${a} instance(s).`)}async search(e,t){let o=t.publisher??"kanonak.org";console.log(`Searching ${o} for ${e.managesType} instances...
|
|
64
|
-
`);let r=new
|
|
65
|
-
`);for(let m of y){let g=m.entity.description?String(m.entity.description).trim().substring(0,80):"";console.log(` ${m.publisher}/${m.package_}@${m.version}`),console.log(` ${m.entityName}: ${g}`),console.log()}}async info(e,t,o){let r=this.handlerRegistry.get(e.
|
|
66
|
-
`);return{name:e,description:t,skillMd:c}}function
|
|
64
|
+
`);let r=new Yt,s=await r.getConfig(o),i=r.resolveIndexUrl(o,s),a=await this.fetchFn(i,o);if(!a.ok){console.error(`Failed to fetch package index from ${o}.`);return}let c=await a.text(),l=ee.parseIndex(c);if(l.size===0){console.error(`No packages found for publisher "${o}".`);return}let d=new Map;for(let[m,g]of l){let k=[...g].sort((f,h)=>{let b=ee.parseVersion(f),w=ee.parseVersion(h);return!b||!w?0:b.major!==w.major?w.major-b.major:b.minor!==w.minor?w.minor-b.minor:w.patch-b.patch});d.set(m,k[0])}let p=new Re(this.parser),u=0;for(let[m,g]of d){let k=this.fileCache.get(o,m,g);if(!k)try{let f=await this.publisherIndex.getPackageUrl(o,m,g),h=await this.fetchFn(f,o);if(!h.ok)continue;k=await h.text(),this.fileCache.put(o,m,g,k)}catch{continue}try{let f=this.parser.parse(k),h=f.metadata.namespace_,b=h?.version?`${h.version.major}.${h.version.minor}.${h.version.patch}`:"0.0.0",w=h?`${h.publisher}/${h.package_}/${b}`:`${o}/${m}/${g}`;await p.saveDocumentAsync(f,w),u++}catch{continue}}let y=await De(p,e.managesType);if(y.length===0){console.log(`No ${e.managesType} instances found across ${u} package(s).`);return}console.log(`Found ${y.length} ${e.managesType} instance(s):
|
|
65
|
+
`);for(let m of y){let g=m.entity.description?String(m.entity.description).trim().substring(0,80):"";console.log(` ${m.publisher}/${m.package_}@${m.version}`),console.log(` ${m.entityName}: ${g}`),console.log()}}async info(e,t,o){let r=this.handlerRegistry.get(e.deploymentTargetName);r||(console.error(`No deployment handler registered for "${e.deploymentTargetName}"`),process.exit(1));let i=(await r.list(o)).find(a=>a.name===t);i||(console.error(`${e.managesType} "${t}" is not installed.`),process.exit(1)),console.log(`Name: ${i.name}`),console.log(`Type: ${e.managesType}`),console.log(`Publisher: ${i.publisher||"unmanaged"}`),console.log(`Package: ${i.package_||"n/a"}`),console.log(`Version: ${i.version||"n/a"}`),console.log(`Path: ${i.path}`)}};var U=class{handlers=new Map;register(e,t){this.handlers.set(e,t)}get(e){return this.handlers.get(e)??null}};import{mkdirSync as gn,rmSync as mn,existsSync as V,readdirSync as fn,writeFileSync as hn}from"fs";import{join as M}from"path";var Qt={bash:"Bash",read:"Read",write:"Write",edit:"Edit",glob:"Glob",grep:"Grep","web-search":"Web Search","web-fetch":"Web Fetch"};function Te(n){let e=[];for(let[,t]of Object.entries(n.body)){if(!t||typeof t!="object")continue;let o=String(t.type??"");if(!Zt(o))continue;let r=en(t);r&&e.push(r)}return e}function Zt(n){return n==="Skill"||n.endsWith(".Skill")}function en(n){let e=R(n,"name"),t=L(R(n,"description"));if(!e||!t)return null;let o=[];o.push(`name: ${e}`),o.push(`description: ${t}`);let r=on(R(n,"allowedTools"));r&&o.push(`allowed-tools: ${r}`);let s=R(n,"license");s&&o.push(`license: ${rn(s)}`);let i=R(n,"compatibility");i&&o.push(`compatibility: ${L(i)}`);let a=tn(R(n,"hasSection"))||nn(R(n,"hasResource"),n),c=["---",...o,"---","",a].join(`
|
|
66
|
+
`);return{name:e,description:t,skillMd:c}}function tn(n){if(!Array.isArray(n)||n.length===0)return"";let e=[];for(let t of n){if(!t||typeof t!="object")continue;let o=t.title,r=L(t.body);o&&e.push(`## ${o}`),r&&e.push(r)}return e.join(`
|
|
67
67
|
|
|
68
|
-
`)}function
|
|
68
|
+
`)}function nn(n,e){if(!Array.isArray(n)||n.length===0)return"";let t=[];for(let o of n){let r=typeof o=="string"?e[o]:o;if(!r||typeof r!="object")continue;let s=String(r.type??""),i=r.title??r.resourceTitle??"";if(i&&t.push(`## ${i}`),s==="ScriptResource"||s.endsWith(".ScriptResource")){let a=r.language??"bash",c=L(r.command);c&&t.push(`\`\`\`${a}
|
|
69
69
|
${c}
|
|
70
|
-
\`\`\``)}else if(s==="ReferenceResource"||s.endsWith(".ReferenceResource")){let a=
|
|
70
|
+
\`\`\``)}else if(s==="ReferenceResource"||s.endsWith(".ReferenceResource")){let a=L(r.content);a&&t.push(a)}}return t.join(`
|
|
71
71
|
|
|
72
|
-
`)}function
|
|
73
|
-
`;function
|
|
72
|
+
`)}function on(n){return Array.isArray(n)?n.map(e=>{let t=String(e);return Qt[t]??sn(t)}).join(", "):""}function rn(n){let e=String(n);return e.includes(".")?e.substring(e.lastIndexOf(".")+1):e}function sn(n){return n.split("-").map(e=>e.charAt(0).toUpperCase()+e.slice(1)).join(" ")}function R(n,e){if(e in n)return n[e];for(let t of Object.keys(n))if(t.endsWith(`.${e}`))return n[t]}function L(n){return typeof n!="string"?"":n.trimEnd()}import{join as xe}from"path";import{homedir as an}from"os";function E(n){let e=n.scope??"project",t=n.client??cn(),o=t?`.${t}`:".agents",r=e==="user"?an():process.cwd();return xe(r,o,"skills")}function H(n,e){return xe(E(e),n)}function cn(){if(process.env.CLAUDE_CODE||process.env.CLAUDE_PROJECT_DIR)return"claude";if(process.env.GEMINI_CLI)return"gemini";if(process.env.CODEX_CLI||process.env.OPENAI_CODEX)return"codex"}import{readFileSync as ln,writeFileSync as dn,existsSync as pn}from"fs";import{join as Ae}from"path";import Ie from"js-yaml";var _e="skills.lock",un=`# This file is generated by Kanonak CLI. Do not edit manually.
|
|
73
|
+
`;function z(n){let e=Ae(n,_e);if(!pn(e))return{version:"1",lastUpdated:new Date().toISOString(),skills:{}};let t=ln(e,"utf-8"),o=Ie.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 te(n,e){e.lastUpdated=new Date().toISOString();let t={};for(let s of Object.keys(e.skills).sort())t[s]=e.skills[s];e.skills=t;let o=Ae(n,_e),r=Ie.dump(e,{lineWidth:-1,sortKeys:!1,quotingType:'"'});dn(o,un+r,"utf-8")}var W=class{async deploy(e,t,o){let r=Te(e);if(r.length===0){console.error("No skills could be transformed from the package.");return}let s=E(o),i=z(s),a=e.metadata.namespace_,c=a?.publisher??"",l=a?.package_??"",d=a?.version?`${a.version.major}.${a.version.minor}.${a.version.patch}`:"";for(let p of r){let u=H(p.name,o),y=V(M(u,"SKILL.md"));gn(u,{recursive:!0}),hn(M(u,"SKILL.md"),p.skillMd,"utf-8"),i.skills[p.name]={publisher:c,package_:l,version:d,resolved:a?`kanonak://${c}/${l}@${d}`:"",integrity:D(p.skillMd)},console.log(` ${y?"Updated":"Installed"} skill "${p.name}" \u2192 ${u}`)}te(s,i)}async undeploy(e,t){let o=H(e,t);V(o)||(console.error(`Skill "${e}" is not installed at ${o}`),process.exit(1)),mn(o,{recursive:!0,force:!0});let r=E(t),s=z(r);delete s.skills[e],te(r,s),console.log(`Removed skill "${e}" from ${o}`)}async list(e){let t=E(e),o=z(t),r=[];for(let[s,i]of Object.entries(o.skills))r.push({name:s,publisher:i.publisher,package_:i.package_,version:i.version,path:H(s,e)});if(V(t))try{let s=fn(t,{withFileTypes:!0});for(let i of s){if(!i.isDirectory()||o.skills[i.name])continue;let a=M(t,i.name,"SKILL.md");V(a)&&r.push({name:i.name,publisher:"",package_:"",version:"",path:M(t,i.name)})}}catch{}return r}};var Rn=wn(bn(import.meta.url)),Dn=JSON.parse(kn(vn(Rn,"..","package.json"),"utf-8")),S=new yn;S.name("kanonak").description("Kanonak Protocol CLI - Validate and resolve Kanonak ontology packages").version(Dn.version);S.command("validate <path>").description("Validate .kan.yml file(s). Resolves imports via HTTP from publisher domains.").action(async n=>{await ie(n)});S.command("install [package]").description("Install a package and its dependencies, or install all from kanonak.lock.").action(async n=>{await de(n)});S.command("deps <path>").description("Show resolved dependency tree for a .kan.yml file.").action(async n=>{await ue(n)});S.command("login <publisher>").description("Authenticate with a package publisher using OAuth 2.0.").action(async n=>{await ye(n)});S.command("logout <publisher>").description("Revoke tokens and remove stored credentials for a publisher.").action(async n=>{await ke(n)});S.addCommand(ve());async function Tn(){try{let n=new $,e=new $n,t=new Cn,o=Pn(t),r=new Sn({fetchFn:o}),s=new U;s.register("AgentSkillDeployment",new W);let i=await $e(n,e),a=new K(n,e,r,o,s);Pe(S,i,a)}catch{}}await Tn();S.parse();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kanonak-protocol/cli",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.3.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": "^1.
|
|
38
|
-
"@kanonak-protocol/types": "^1.
|
|
37
|
+
"@kanonak-protocol/sdk": "^1.3.0",
|
|
38
|
+
"@kanonak-protocol/types": "^1.3.0",
|
|
39
39
|
"commander": "^13.0.0",
|
|
40
40
|
"js-yaml": "^4.1.1"
|
|
41
41
|
},
|