@kanonak-protocol/cli 3.60.0 → 3.62.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/README.md CHANGED
@@ -1,51 +1,25 @@
1
1
  # @kanonak-protocol/cli
2
2
 
3
- Command-line tool for [Kanonak Protocol](https://kanonak.org) — validate, install, and inspect semantic ontology packages.
3
+ The command-line tool for the [Kanonak Protocol](https://kanonak.org) — validate, resolve, preview, and publish semantic ontology packages (`.kan.yml`).
4
4
 
5
- ## Installation
5
+ ## Install
6
6
 
7
7
  ```bash
8
8
  npm install -g @kanonak-protocol/cli
9
9
  ```
10
10
 
11
- ## Commands
12
-
13
- ### Validate
14
-
15
- Check `.kan.yml` files for type errors, missing imports, and structural issues:
16
-
17
- ```bash
18
- kanonak validate . # Validate all files in current directory
19
- kanonak validate contacts.kan.yml # Validate a specific file
20
- kanonak validate ontologies/ # Validate a directory
21
- ```
22
-
23
- ### Install
24
-
25
- Download Kanonak packages and their dependencies:
11
+ ## Usage
26
12
 
27
13
  ```bash
28
- kanonak install kanonak.org/core-rdf # Install a package
29
- kanonak install kanonak.org/docs-complete # Install documentation bundle
30
- kanonak install # Install from kanonak.lock
14
+ kanonak --help # list every command
15
+ kanonak <command> --help # details for one command
31
16
  ```
32
17
 
33
- ### Inspect dependencies
18
+ `kanonak --help` is the authoritative, always-current command reference. In brief, the CLI validates packages against the object model, resolves and installs their dependency closure, previews them through a local origin server, and publishes a publisher's site.
34
19
 
35
- Show the resolved dependency tree:
20
+ ## Documentation
36
21
 
37
- ```bash
38
- kanonak deps contacts.kan.yml
39
- ```
40
-
41
- ### Authentication
42
-
43
- Authenticate with private package registries:
44
-
45
- ```bash
46
- kanonak login registry.example.com # OAuth 2.0 + PKCE + DPoP
47
- kanonak logout registry.example.com
48
- ```
22
+ Guides, conventions, and the protocol specification live at **[kanonak.org](https://kanonak.org)**.
49
23
 
50
24
  ## License
51
25
 
@@ -2,17 +2,28 @@
2
2
  * `kanonak serve` — a live origin server on the SDK's routing/rendering core.
3
3
  *
4
4
  * Thin wrapper: an HTTP listener + optional workspace watcher. All routing and
5
- * rendering lives in `@kanonak-protocol/sdk/server` (`loadServerModel` + `route`),
6
- * which makes the SAME `LookRenderer` calls `kanonak publish` does — so a live
7
- * response is byte-equivalent to the static page `publish` would write, plus the
8
- * machine-facing endpoints publish omits (`/.well-known/kanonak.json`,
9
- * `/index.txt`, raw `{package}/{version}.kan.yml`).
5
+ * rendering lives in `@kanonak-protocol/sdk/server` (`loadServerModel` /
6
+ * `loadResourceModel` + `route`), which makes the SAME `LookRenderer` calls
7
+ * `kanonak publish` does — so a live response is byte-equivalent to the static
8
+ * page `publish` would write, plus the machine-facing endpoints publish omits
9
+ * (`/.well-known/kanonak.json`, `/index.txt`, raw `{package}/{version}.kan.yml`).
10
10
  *
11
- * - Local dev: `kanonak serve --watch` edit a `.kan.yml`, refresh, see the
12
- * exact page publish would emit. No publish step.
13
- * - Production: run the same process behind a load balancer + domain + TLS and
14
- * it IS the publisher origin, serving human- and machine-facing content from
15
- * one source of truth (the workspace).
11
+ * serve does ONE thing be the origin (render + machine endpoints). It is not
12
+ * a search engine: ad-hoc site search is a separate, stateful concern that
13
+ * can't be expressed as static output, so it stays out of the origin. Use
14
+ * `kanonak search -q` for local/workspace discovery; a publisher wanting site
15
+ * search can layer a real search service on top of their origin.
16
+ *
17
+ * Two modes (#43):
18
+ * - PINNED — a `--publisher` flag, or a single-publisher workspace, fixes one
19
+ * publisher and serves publisher-relative paths (`/{package}/{version}/…`).
20
+ * This is the dev loop (`--watch`) and the production single-origin case.
21
+ * - REQUEST-DRIVEN — with no `--publisher` and an empty or multi-publisher
22
+ * workspace, the publisher is derived from each request's FIRST path segment
23
+ * (`/{publisher}/{package}/{version}/{resource}`). A per-publisher model is
24
+ * built on demand — from the workspace if that publisher is local, else
25
+ * fetched over HTTP via `loadResourceModel` — so one process can serve any
26
+ * publisher with no flag and no workspace.
16
27
  */
17
28
  import { Command } from 'commander';
18
29
  export declare function serveCommand(): Command;
package/dist/index.js CHANGED
@@ -1,63 +1,63 @@
1
1
  #!/usr/bin/env node
2
- import{Command as Gi}from"commander";import{readFileSync as Ji}from"fs";import{fileURLToPath as Yi}from"url";import{dirname as Xi,join as Zi}from"path";import{KanonakParser as Qi,PublisherIndex as ec,CredentialStore as nc,createAuthenticatedFetch as tc}from"@kanonak-protocol/sdk";import{readFileSync as eo,statSync as no}from"fs";import{resolve as to,dirname as oo}from"path";import{KanonakParser as ro,KanonakObjectValidator as ao,ValidationSeverity as on}from"@kanonak-protocol/sdk";import{readdirSync as Yt}from"fs";import{join as Xt,dirname as Zt,basename as tn}from"path";import{LocalFirstRepository as fc,buildLocalFirstRepository as Qt}from"@kanonak-protocol/sdk";import{mkdirSync as zt,readFileSync as en,writeFileSync as nn,existsSync as we,appendFileSync as Bt}from"fs";import{join as qt,dirname as Wt,isAbsolute as Gt}from"path";import{getGlobalCachePath as Jt}from"@kanonak-protocol/sdk";var K=class{constructor(e=Jt()){this.cacheDir=e;this.isProjectLocal=!Gt(e)}cacheDir;gitignoreChecked=!1;isProjectLocal;get(e,t,o){let r=this.getPath(e,t,o);return we(r)?en(r,"utf-8"):null}put(e,t,o,r){let s=this.getPath(e,t,o);zt(Wt(s),{recursive:!0}),nn(s,r,"utf-8"),this.isProjectLocal&&this.ensureGitignore()}has(e,t,o){return we(this.getPath(e,t,o))}ensureGitignore(){if(this.gitignoreChecked)return;this.gitignoreChecked=!0;let e=".gitignore",t=this.cacheDir;if(we(e)){if(en(e,"utf-8").split(`
3
- `).some(r=>r.trim()===t||r.trim()===t+"/"))return;Bt(e,`
2
+ import{Command as Bi}from"commander";import{readFileSync as zi}from"fs";import{fileURLToPath as qi}from"url";import{dirname as Wi,join as Gi}from"path";import{KanonakParser as Ji,PublisherIndex as Yi,CredentialStore as Xi,createAuthenticatedFetch as Zi}from"@kanonak-protocol/sdk";import{readFileSync as ro,statSync as so}from"fs";import{resolve as ao,dirname as io}from"path";import{KanonakParser as co,KanonakObjectValidator as lo,ValidationSeverity as on}from"@kanonak-protocol/sdk";import{readdirSync as eo}from"fs";import{join as no,dirname as to,basename as tn}from"path";import{LocalFirstRepository as uc,buildLocalFirstRepository as oo}from"@kanonak-protocol/sdk";import{mkdirSync as Gt,readFileSync as en,writeFileSync as nn,existsSync as be,appendFileSync as Jt}from"fs";import{join as Yt,dirname as Xt,isAbsolute as Zt}from"path";import{getGlobalCachePath as Qt}from"@kanonak-protocol/sdk";var K=class{constructor(e=Qt()){this.cacheDir=e;this.isProjectLocal=!Zt(e)}cacheDir;gitignoreChecked=!1;isProjectLocal;get(e,t,o){let r=this.getPath(e,t,o);return be(r)?en(r,"utf-8"):null}put(e,t,o,r){let a=this.getPath(e,t,o);Gt(Xt(a),{recursive:!0}),nn(a,r,"utf-8"),this.isProjectLocal&&this.ensureGitignore()}has(e,t,o){return be(this.getPath(e,t,o))}ensureGitignore(){if(this.gitignoreChecked)return;this.gitignoreChecked=!0;let e=".gitignore",t=this.cacheDir;if(be(e)){if(en(e,"utf-8").split(`
3
+ `).some(r=>r.trim()===t||r.trim()===t+"/"))return;Jt(e,`
4
4
  ${t}/
5
5
  `)}else nn(e,`${t}/
6
- `)}getPath(e,t,o){return qt(this.cacheDir,e,`${t}@${o}.kan.yml`)}};function N(n){let e=n;for(;;){let t=Zt(e);if(t===e)break;if(tn(e).includes(".")||tn(t).includes(".")){e=t;continue}break}return e}function $e(n,e){for(let t of Yt(n,{withFileTypes:!0})){let o=Xt(n,t.name);t.isDirectory()&&t.name!=="node_modules"&&t.name!==".kanonak"?$e(o,e):t.name.endsWith(".kan.yml")&&e.push(o)}}async function v(n,e){let t=new K;return Qt(n,e,{httpCache:{getFromCache:(o,r,s)=>t.get(o,r,s),onFetch:(o,r,s,a)=>t.put(o,r,s,a)}})}async function rn(n){let e=to(n),t=no(e),o=t.isDirectory()?N(e):N(oo(e)),r=new ro,s=new ao(r),a=await v(o,r),i=[];if(t.isDirectory()?$e(e,i):i.push(e),i.length===0){console.log("No .kan.yml files found.");return}let c=0,l=0;for(let u of i){let p=eo(u,"utf-8"),d=r.parseWithErrors(p);if(d.errors&&d.errors.length>0){console.log(`
6
+ `)}getPath(e,t,o){return Yt(this.cacheDir,e,`${t}@${o}.kan.yml`)}};function N(n){let e=n;for(;;){let t=to(e);if(t===e)break;if(tn(e).includes(".")||tn(t).includes(".")){e=t;continue}break}return e}function we(n,e){for(let t of eo(n,{withFileTypes:!0})){let o=no(n,t.name);t.isDirectory()&&t.name!=="node_modules"&&t.name!==".kanonak"?we(o,e):t.name.endsWith(".kan.yml")&&e.push(o)}}async function v(n,e){let t=new K;return oo(n,e,{httpCache:{getFromCache:(o,r,a)=>t.get(o,r,a),onFetch:(o,r,a,s)=>t.put(o,r,a,s)}})}async function rn(n){let e=ao(n),t=so(e),o=t.isDirectory()?N(e):N(io(e)),r=new co,a=new lo(r),s=await v(o,r),i=[];if(t.isDirectory()?we(e,i):i.push(e),i.length===0){console.log("No .kan.yml files found.");return}let c=0,l=0;for(let u of i){let p=ro(u,"utf-8"),d=r.parseWithErrors(p);if(d.errors&&d.errors.length>0){console.log(`
7
7
  ${u}:`);for(let h of d.errors)console.log(` ERROR (parse): ${h.message} [line ${h.line}:${h.column}]`),c++;continue}let f=d.document;if(!f){console.log(`
8
- ${u}:`),console.log(" ERROR: Failed to parse document"),c++;continue}let g=await s.validateAsync(f,a),m=g.errors.filter(h=>h.severity===on.Error),k=g.warnings.filter(h=>h.severity===on.Warning);if(m.length>0||k.length>0){let h=f.metadata.namespace_,y=h?`${h.publisher}/${h.package_}@${h.version}`:u;console.log(`
8
+ ${u}:`),console.log(" ERROR: Failed to parse document"),c++;continue}let g=await a.validateAsync(f,s),m=g.errors.filter(h=>h.severity===on.Error),k=g.warnings.filter(h=>h.severity===on.Warning);if(m.length>0||k.length>0){let h=f.metadata.namespace_,y=h?`${h.publisher}/${h.package_}@${h.version}`:u;console.log(`
9
9
  ${y}:`);for(let b of m)console.log(` ERROR: ${b.message}`),b.suggestion&&console.log(` -> ${b.suggestion}`);for(let b of k)console.log(` WARN: ${b.message}`)}c+=m.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 so,PublisherIndex as io,CredentialStore as co,createAuthenticatedFetch as lo}from"@kanonak-protocol/sdk";import{loadLockFile as uo,saveLockFile as po,computeIntegrity as mo,assertPackageIdentity as fo}from"@kanonak-protocol/sdk";function T(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,s=null,a=null,i=o.indexOf("@");if(i!==-1){r=o.substring(0,i);let c=o.substring(i+1),l=c.indexOf("/");l===-1?s=c||null:(s=c.substring(0,l)||null,a=c.substring(l+1)||null)}else{let c=o.indexOf("/");c===-1?r=o:(r=o.substring(0,c),a=o.substring(c+1)||null)}return!r||a&&a.includes("/")||s&&s.includes("@")?null:{publisher:t,packageName:r,version:s,instanceName:a}}async function an(n){let e=new K,t=new so,o=new co,r=lo(o),s=new io({fetchFn:r}),a=uo()??{version:"1",lastUpdated:new Date().toISOString(),packages:{}};if(!n){Object.keys(a.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(a.packages).length} package(s) from kanonak.lock...`);for(let[g,m]of Object.entries(a.packages)){let k=g.indexOf("/"),h=g.substring(0,k),y=g.substring(k+1),b=e.get(h,y,m.version);if(b)console.log(` ${g}@${m.version} (cached)`);else{let w=m.resolved,$=await r(w,h);if(!$.ok)throw new Error(`Failed to fetch ${w} (${$.status} ${$.statusText})`);b=await $.text(),e.put(h,y,m.version,b),console.log(` ${g}@${m.version}`)}}console.log(`
11
- Installed ${Object.keys(a.packages).length} package(s) from lock file.`);return}let i=T(n);i||(console.error(`Invalid package reference: "${n}"`),console.error("Expected format: {publisher}/{package}[@{version}]"),process.exit(1));let{publisher:c,packageName:l,version:u,instanceName:p}=i;p&&(console.error(`\`kanonak install\` works on whole packages \u2014 got an instance suffix "/${p}".`),console.error(`Try: kanonak install ${c}/${l}${u?"@"+u:""}`),console.error("(Use `kanonak <capability> add` if you want to install one named instance.)"),process.exit(1));let d=u??await s.getHighestVersion(c,l);d||(console.error(`Could not resolve version for "${c}/${l}".`),console.error("Check the spelling, or run a search to see what the publisher offers."),process.exit(1)),console.log(`Installing ${c}/${l}@${d}...`);let f=new Set;await sn(c,l,d,e,t,s,r,f,a),po(a),console.log(`
12
- Installed ${f.size} package(s).`)}async function sn(n,e,t,o,r,s,a,i,c){let l=`${n}/${e}@${t}`;if(i.has(l))return;i.add(l);let u=`${n}/${e}`,p=o.get(n,e,t),d=await s.getPackageUrl(n,e,t),f,g=!1;if(p)f=p;else{let h=await a(d,n);if(!h.ok)throw new Error(`Failed to fetch ${d} (${h.status} ${h.statusText})`);f=await h.text(),g=!0}let m=r.parse(f);fo(m,n,e,t),g&&o.put(n,e,t,f),console.log(` ${l}${g?"":" (cached)"}`);let k={};if(m.metadata.imports)for(let[h,y]of Object.entries(m.metadata.imports))for(let b of y){let w=await s.resolveVersion(h,b);w?(k[`${h}/${b.packageName}`]=w,await sn(h,b.packageName,w,o,r,s,a,i,c)):console.error(` WARNING: Could not resolve ${h}/${b.packageName} ${b.package_}`)}c.packages[u]={version:t,resolved:d,integrity:mo(f),dependencies:k}}import{readFileSync as go}from"fs";import{resolve as ho,dirname as ko}from"path";import{KanonakParser as yo}from"@kanonak-protocol/sdk";async function cn(n){let e=ho(n),t=go(e,"utf-8"),o=new yo,r=o.parse(t),s=r.metadata.namespace_,a=s?`${s.publisher}/${s.package_}@${s.version}`:n;if(console.log(a),!r.metadata.imports){console.log(" (no imports)");return}let i=N(ko(e)),c=await v(i,o),l=new Set;for(let[u,p]of Object.entries(r.metadata.imports))for(let d of p)await ln(u,d,c,l," ")}async function ln(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 a;try{a=await t.getHighestCompatibleVersionAsync(n,e)}catch{console.log(`${r}${s} (${e.package_}) [fetch failed]`);return}if(!a){console.log(`${r}${s} (${e.package_}) [not found]`);return}let i=a.metadata.namespace_?.version?.toString()??"?";if(console.log(`${r}${n}/${e.packageName}@${i}`),a.metadata.imports)for(let[c,l]of Object.entries(a.metadata.imports))for(let u of l)await ln(c,u,t,o,r+" ")}import{createHash as wo,randomBytes as dn}from"crypto";import{createServer as $o}from"http";import{execFile as ve}from"child_process";import{CredentialStore as vo,generateDPoPKeyPair as So,createDPoPProof as un,serverSupportsDPoP as Po}from"@kanonak-protocol/sdk";import{normalizeHost as bo}from"@kanonak-protocol/sdk";var A=class{cache=new Map;async discover(e){let t=bo(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:Y(o.issuer),authorizationEndpoint:Y(o.authorization_endpoint),tokenEndpoint:Y(o.token_endpoint),registrationEndpoint:Y(o.registration_endpoint),revocationEndpoint:Y(o.revocation_endpoint),scopesSupported:H(o.scopes_supported),responseTypesSupported:H(o.response_types_supported),grantTypesSupported:H(o.grant_types_supported),codeChallengeMethodsSupported:H(o.code_challenge_methods_supported),tokenEndpointAuthMethodsSupported:H(o.token_endpoint_auth_methods_supported),dpopSigningAlgValuesSupported:H(o.dpop_signing_alg_values_supported)}}};function Y(n){return typeof n=="string"?n:null}function H(n){return Array.isArray(n)?n.filter(e=>typeof e=="string"):null}var B=class{discovery;credentialStore;constructor(e,t){this.discovery=e??new A,this.credentialStore=t??new vo}async authorize(e,t=[]){console.log(`Starting OAuth flow for ${e}...`);let o=await this.discovery.discover(e);if(!o)return I(`No OAuth discovery endpoint found for '${e}'.
10
+ ${i.length} file(s) validated. ${c} error(s), ${l} warning(s).`),c>0&&process.exit(1)}import{KanonakParser as uo,PublisherIndex as po,CredentialStore as mo,createAuthenticatedFetch as fo}from"@kanonak-protocol/sdk";import{loadLockFile as go,saveLockFile as ho,computeIntegrity as ko,assertPackageIdentity as yo}from"@kanonak-protocol/sdk";function D(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 sn(n){let e=new K,t=new uo,o=new mo,r=fo(o),a=new po({fetchFn:r}),s=go()??{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[g,m]of Object.entries(s.packages)){let k=g.indexOf("/"),h=g.substring(0,k),y=g.substring(k+1),b=e.get(h,y,m.version);if(b)console.log(` ${g}@${m.version} (cached)`);else{let w=m.resolved,$=await r(w,h);if(!$.ok)throw new Error(`Failed to fetch ${w} (${$.status} ${$.statusText})`);b=await $.text(),e.put(h,y,m.version,b),console.log(` ${g}@${m.version}`)}}console.log(`
11
+ Installed ${Object.keys(s.packages).length} package(s) from lock file.`);return}let i=D(n);i||(console.error(`Invalid package reference: "${n}"`),console.error("Expected format: {publisher}/{package}[@{version}]"),process.exit(1));let{publisher:c,packageName:l,version:u,instanceName:p}=i;p&&(console.error(`\`kanonak install\` works on whole packages \u2014 got an instance suffix "/${p}".`),console.error(`Try: kanonak install ${c}/${l}${u?"@"+u:""}`),console.error("(Use `kanonak <capability> add` if you want to install one named instance.)"),process.exit(1));let d=u??await a.getHighestVersion(c,l);d||(console.error(`Could not resolve version for "${c}/${l}".`),console.error("Check the spelling, or run a search to see what the publisher offers."),process.exit(1)),console.log(`Installing ${c}/${l}@${d}...`);let f=new Set;await an(c,l,d,e,t,a,r,f,s),ho(s),console.log(`
12
+ Installed ${f.size} package(s).`)}async function an(n,e,t,o,r,a,s,i,c){let l=`${n}/${e}@${t}`;if(i.has(l))return;i.add(l);let u=`${n}/${e}`,p=o.get(n,e,t),d=await a.getPackageUrl(n,e,t),f,g=!1;if(p)f=p;else{let h=await s(d,n);if(!h.ok)throw new Error(`Failed to fetch ${d} (${h.status} ${h.statusText})`);f=await h.text(),g=!0}let m=r.parse(f);yo(m,n,e,t),g&&o.put(n,e,t,f),console.log(` ${l}${g?"":" (cached)"}`);let k={};if(m.metadata.imports)for(let[h,y]of Object.entries(m.metadata.imports))for(let b of y){let w=await a.resolveVersion(h,b);w?(k[`${h}/${b.packageName}`]=w,await an(h,b.packageName,w,o,r,a,s,i,c)):console.error(` WARNING: Could not resolve ${h}/${b.packageName} ${b.package_}`)}c.packages[u]={version:t,resolved:d,integrity:ko(f),dependencies:k}}import{readFileSync as bo}from"fs";import{resolve as wo,dirname as $o}from"path";import{KanonakParser as vo}from"@kanonak-protocol/sdk";async function cn(n){let e=wo(n),t=bo(e,"utf-8"),o=new vo,r=o.parse(t),a=r.metadata.namespace_,s=a?`${a.publisher}/${a.package_}@${a.version}`:n;if(console.log(s),!r.metadata.imports){console.log(" (no imports)");return}let i=N($o(e)),c=await v(i,o),l=new Set;for(let[u,p]of Object.entries(r.metadata.imports))for(let d of p)await ln(u,d,c,l," ")}async function ln(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 ln(c,u,t,o,r+" ")}import{createHash as Po,randomBytes as dn}from"crypto";import{createServer as Co}from"http";import{execFile as $e}from"child_process";import{CredentialStore as Ro,generateDPoPKeyPair as _o,createDPoPProof as un,serverSupportsDPoP as xo}from"@kanonak-protocol/sdk";import{normalizeHost as So}from"@kanonak-protocol/sdk";var A=class{cache=new Map;async discover(e){let t=So(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:J(o.issuer),authorizationEndpoint:J(o.authorization_endpoint),tokenEndpoint:J(o.token_endpoint),registrationEndpoint:J(o.registration_endpoint),revocationEndpoint:J(o.revocation_endpoint),scopesSupported:H(o.scopes_supported),responseTypesSupported:H(o.response_types_supported),grantTypesSupported:H(o.grant_types_supported),codeChallengeMethodsSupported:H(o.code_challenge_methods_supported),tokenEndpointAuthMethodsSupported:H(o.token_endpoint_auth_methods_supported),dpopSigningAlgValuesSupported:H(o.dpop_signing_alg_values_supported)}}};function J(n){return typeof n=="string"?n:null}function H(n){return Array.isArray(n)?n.filter(e=>typeof e=="string"):null}var z=class{discovery;credentialStore;constructor(e,t){this.discovery=e??new A,this.credentialStore=t??new Ro}async authorize(e,t=[]){console.log(`Starting OAuth flow for ${e}...`);let o=await this.discovery.discover(e);if(!o)return I(`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 I(`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 s=Po(o.dpopSigningAlgValuesSupported),a=null;if(s){console.log(" Server supports DPoP (RFC 9449) \u2014 generating key pair...");try{a=So()}catch($){return I(`Failed to generate DPoP key pair: ${z($)}
19
- Ensure your Node.js installation supports EC P-256 curves.`)}}let{redirectUri:i,port:c,waitForCallback:l,close:u}=await Do(),p=await this.credentialStore.getCredential(e),d=p?.clientId??null,f=p?.clientSecret??null;if(!d&&o.registrationEndpoint){console.log(" Registering dynamic OAuth client (RFC 7591)...");let $=await this.registerClient(o.registrationEndpoint,i);if(!$.success)return u(),I($.error);d=$.clientId,f=$.clientSecret??null}if(!d)return u(),I(`No OAuth client credentials for '${e}' and the server does not support dynamic client registration (no registration_endpoint in metadata).
18
+ Contact the IDP administrator to ensure these are included in the discovery document.`);let a=xo(o.dpopSigningAlgValuesSupported),s=null;if(a){console.log(" Server supports DPoP (RFC 9449) \u2014 generating key pair...");try{s=_o()}catch($){return I(`Failed to generate DPoP key pair: ${B($)}
19
+ Ensure your Node.js installation supports EC P-256 curves.`)}}let{redirectUri:i,port:c,waitForCallback:l,close:u}=await Ao(),p=await this.credentialStore.getCredential(e),d=p?.clientId??null,f=p?.clientSecret??null;if(!d&&o.registrationEndpoint){console.log(" Registering dynamic OAuth client (RFC 7591)...");let $=await this.registerClient(o.registrationEndpoint,i);if(!$.success)return u(),I($.error);d=$.clientId,f=$.clientSecret??null}if(!d)return u(),I(`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 g=_o(),m=Ro(g),k=xo(),h=Io(o.authorizationEndpoint,d,i,t,k,m);console.log(` Opening browser for authorization on port ${c}...`),console.log(" If the browser doesn't open, navigate to:"),console.log(` ${h}`),Eo(h);let y=await l();if(u(),!y)return I(`Authorization timed out after 5 minutes.
22
+ or add a registration_endpoint to the OAuth metadata.`);let g=Ko(),m=To(g),k=Do(),h=Eo(o.authorizationEndpoint,d,i,t,k,m);console.log(` Opening browser for authorization on port ${c}...`),console.log(" If the browser doesn't open, navigate to:"),console.log(` ${h}`),No(h);let y=await l();if(u(),!y)return I(`Authorization timed out after 5 minutes.
23
23
  The browser authorization was not completed in time.
24
24
  Re-run 'kanonak login ${e}' and complete the browser authorization promptly.`);if(!y.code){let $=y.error?`: ${y.error}`:"";return I(`No authorization code received${$}.
25
25
  The IDP may have rejected the authorization request.
26
26
  Check the IDP admin console for error details.`)}if(y.state!==k)return I(`Authorization state mismatch \u2014 possible CSRF attack.
27
27
  The response did not match the expected session.
28
- Re-run 'kanonak login ${e}' to start a fresh authorization flow.`);console.log(" Exchanging authorization code for tokens...");let b=await this.exchangeCode(o.tokenEndpoint,d,f,y.code,i,g,a);if(!b.success)return I(b.error);let w={clientId:d,clientSecret:f,accessToken:b.tokens.accessToken,refreshToken:b.tokens.refreshToken,expiresAt:b.tokens.expiresIn?new Date(Date.now()+b.tokens.expiresIn*1e3).toISOString():null,tokenEndpoint:o.tokenEndpoint,dpopKeyPair:a};return await this.credentialStore.store(e,w),console.log(` Successfully authenticated with ${e}`),s&&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 I(`No stored credentials for '${e}'. Run 'kanonak login ${e}' to authenticate first.`);if(!t.refreshToken)return I(`No refresh token available for '${e}'.
28
+ Re-run 'kanonak login ${e}' to start a fresh authorization flow.`);console.log(" Exchanging authorization code for tokens...");let b=await this.exchangeCode(o.tokenEndpoint,d,f,y.code,i,g,s);if(!b.success)return I(b.error);let w={clientId:d,clientSecret:f,accessToken:b.tokens.accessToken,refreshToken:b.tokens.refreshToken,expiresAt:b.tokens.expiresIn?new Date(Date.now()+b.tokens.expiresIn*1e3).toISOString():null,tokenEndpoint:o.tokenEndpoint,dpopKeyPair:s};return await this.credentialStore.store(e,w),console.log(` Successfully authenticated with ${e}`),a&&console.log(" DPoP proof-of-possession is active"),{success:!0,host:e}}async refresh(e){let t=await this.credentialStore.getCredential(e);if(!t)return I(`No stored credentials for '${e}'. Run 'kanonak login ${e}' to authenticate first.`);if(!t.refreshToken)return I(`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 I(`No client ID in stored credentials for '${e}'.
31
- The stored credential may be corrupted. Run 'kanonak logout ${e}' then 'kanonak login ${e}'.`);let o=t.tokenEndpoint;if(!o){let s=await this.discovery.discover(e);if(!s?.tokenEndpoint)return I(`Cannot find token endpoint for '${e}'.
31
+ The stored credential may be corrupted. Run 'kanonak logout ${e}' then 'kanonak login ${e}'.`);let o=t.tokenEndpoint;if(!o){let a=await this.discovery.discover(e);if(!a?.tokenEndpoint)return I(`Cannot find token endpoint for '${e}'.
32
32
  The OAuth discovery endpoint may be unreachable.
33
- Check network connectivity and run 'kanonak login ${e}' to re-authenticate.`);o=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}):I(`${r.error}
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}):I(`${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 I(`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(a){return{success:!1,error:`Dynamic client registration request to ${e} failed: ${z(a)}
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: ${B(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 a=await Se(o);return{success:!1,error:`Dynamic client registration (RFC 7591) failed.
37
+ If using a corporate proxy or custom CA, set NODE_EXTRA_CA_CERTS.`}}if(!o.ok){let s=await ve(o);return{success:!1,error:`Dynamic client registration (RFC 7591) failed.
38
38
  Endpoint: ${e}
39
- HTTP ${o.status}: ${a}
39
+ HTTP ${o.status}: ${s}
40
40
  The IDP may not support dynamic registration for public clients.
41
- Ask your IDP administrator to enable RFC 7591 support, or pre-register a client manually.`}}let r=await o.json(),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.
42
- The IDP response may be malformed. Contact your IDP administrator.`}}async exchangeCode(e,t,o,r,s,a,i){let c=new URLSearchParams({grant_type:"authorization_code",client_id:t,code:r,redirect_uri:s,code_verifier:a});o&&c.set("client_secret",o);let l={"Content-Type":"application/x-www-form-urlencoded"};if(i)try{l.DPoP=un(i.privateKey,i.publicKey,"POST",e)}catch(p){return{success:!1,error:`Failed to create DPoP proof for token exchange: ${z(p)}
43
- The stored key pair may be corrupted. Run 'kanonak login' to re-authenticate.`}}let u;try{u=await fetch(e,{method:"POST",headers:l,body:c.toString()})}catch(p){return{success:!1,error:`Token exchange request to ${e} failed: ${z(p)}
44
- Ensure the token endpoint is reachable.`}}if(!u.ok){let p=await Se(u),d=Co(p);return{success:!1,error:`Token exchange failed.
41
+ Ask your IDP administrator to enable RFC 7591 support, or pre-register a client manually.`}}let r=await o.json(),a=r.client_id;return a?{success:!0,clientId:a,clientSecret:r.client_secret}:{success:!1,error:`Dynamic client registration response from ${e} did not contain a client_id.
42
+ The IDP response may be malformed. Contact your IDP administrator.`}}async exchangeCode(e,t,o,r,a,s,i){let c=new URLSearchParams({grant_type:"authorization_code",client_id:t,code:r,redirect_uri:a,code_verifier:s});o&&c.set("client_secret",o);let l={"Content-Type":"application/x-www-form-urlencoded"};if(i)try{l.DPoP=un(i.privateKey,i.publicKey,"POST",e)}catch(p){return{success:!1,error:`Failed to create DPoP proof for token exchange: ${B(p)}
43
+ The stored key pair may be corrupted. Run 'kanonak login' to re-authenticate.`}}let u;try{u=await fetch(e,{method:"POST",headers:l,body:c.toString()})}catch(p){return{success:!1,error:`Token exchange request to ${e} failed: ${B(p)}
44
+ Ensure the token endpoint is reachable.`}}if(!u.ok){let p=await ve(u),d=Io(p);return{success:!1,error:`Token exchange failed.
45
45
  Endpoint: ${e}
46
46
  HTTP ${u.status}: ${p}`+(d?`
47
- ${d}`:"")}}return{success:!0,tokens:pn(await u.json())}}async refreshTokenRequest(e,t,o,r,s){let a=new URLSearchParams({grant_type:"refresh_token",client_id:t,refresh_token:r});o&&a.set("client_secret",o);let i={"Content-Type":"application/x-www-form-urlencoded"};if(s)try{i.DPoP=un(s.privateKey,s.publicKey,"POST",e)}catch(l){return{success:!1,error:`Failed to create DPoP proof for token refresh: ${z(l)}`}}let c;try{c=await fetch(e,{method:"POST",headers:i,body:a.toString()})}catch(l){return{success:!1,error:`Token refresh request to ${e} failed: ${z(l)}`}}if(!c.ok){let l=await Se(c);return{success:!1,error:`Token refresh failed \u2014 HTTP ${c.status}: ${l}`}}return{success:!0,tokens:pn(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 I(n){return{success:!1,error:n}}function pn(n){return{accessToken:n.access_token,refreshToken:n.refresh_token,expiresIn:typeof n.expires_in=="number"?n.expires_in:void 0}}function z(n){return n instanceof Error?n.message:String(n)}async function Se(n){try{return await n.text()}catch{return"(could not read response body)"}}function Co(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 _o(){return dn(32).toString("base64url")}function Ro(n){return wo("sha256").update(n).digest("base64url")}function xo(){return dn(16).toString("base64url")}function Io(n,e,t,o,r,s){let a=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}?${a}`}var Ko=300*1e3;async function Do(){return new Promise(n=>{let e=$o((r,s)=>{let a=new URL(r.url,"http://localhost"),i=a.searchParams.get("code")??void 0,c=a.searchParams.get("state")??void 0,l=a.searchParams.get("error")??a.searchParams.get("error_description")??void 0,u=l?To(l):null,p=u?`<html><body><h1>Authorization failed</h1><p>${u}</p></body></html>`:"<html><body><h1>Authorization successful!</h1><p>You can close this window.</p></body></html>";s.writeHead(200,{"Content-Type":"text/html"}),s.end(p),t({code:i,state:c,error:l})}),t,o=new Promise(r=>{t=r,setTimeout(()=>{r(null),e.close()},Ko)});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 To(n){return n.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;")}function Eo(n){try{process.platform==="win32"?ve("cmd",["/c","start","",n]):process.platform==="darwin"?ve("open",[n]):ve("xdg-open",[n])}catch{console.log(" Could not open browser automatically. Please navigate to the URL above manually.")}}import{CredentialStore as jo}from"@kanonak-protocol/sdk";async function mn(n){try{let e=new A,t=new jo,r=await new B(e,t).authorize(n);r.success?console.log(`
47
+ ${d}`:"")}}return{success:!0,tokens:pn(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=un(a.privateKey,a.publicKey,"POST",e)}catch(l){return{success:!1,error:`Failed to create DPoP proof for token refresh: ${B(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: ${B(l)}`}}if(!c.ok){let l=await ve(c);return{success:!1,error:`Token refresh failed \u2014 HTTP ${c.status}: ${l}`}}return{success:!0,tokens:pn(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 I(n){return{success:!1,error:n}}function pn(n){return{accessToken:n.access_token,refreshToken:n.refresh_token,expiresIn:typeof n.expires_in=="number"?n.expires_in:void 0}}function B(n){return n instanceof Error?n.message:String(n)}async function ve(n){try{return await n.text()}catch{return"(could not read response body)"}}function Io(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 Ko(){return dn(32).toString("base64url")}function To(n){return Po("sha256").update(n).digest("base64url")}function Do(){return dn(16).toString("base64url")}function Eo(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 jo=300*1e3;async function Ao(){return new Promise(n=>{let e=Co((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?Oo(l):null,p=u?`<html><body><h1>Authorization failed</h1><p>${u}</p></body></html>`:"<html><body><h1>Authorization successful!</h1><p>You can close this window.</p></body></html>";a.writeHead(200,{"Content-Type":"text/html"}),a.end(p),t({code:i,state:c,error:l})}),t,o=new Promise(r=>{t=r,setTimeout(()=>{r(null),e.close()},jo)});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 Oo(n){return n.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;")}function No(n){try{process.platform==="win32"?$e("cmd",["/c","start","",n]):process.platform==="darwin"?$e("open",[n]):$e("xdg-open",[n])}catch{console.log(" Could not open browser automatically. Please navigate to the URL above manually.")}}import{CredentialStore as Lo}from"@kanonak-protocol/sdk";async function mn(n){try{let e=new A,t=new Lo,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 Ao}from"@kanonak-protocol/sdk";async function fn(n){try{let e=new A,t=new Ao,r=await new B(e,t).logout(n);r.success?console.log(`Logged out from ${n}.`):(console.error(`
53
+ If this persists, see https://github.com/kanonak-protocol for support channels.`),process.exit(1)}}import{CredentialStore as Uo}from"@kanonak-protocol/sdk";async function fn(n){try{let e=new A,t=new Uo,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 sr}from"commander";import{KanonakParser as ir,KanonakObjectParser as cr,PublisherIndex as lr,CredentialStore as ur,createAuthenticatedFetch as pr,computeIntegrity as dr}from"@kanonak-protocol/sdk";import{readFileSync as Oo,writeFileSync as No,existsSync as Lo}from"fs";import{join as Uo}from"path";import gn from"js-yaml";import{getGlobalCachePath as Fo}from"@kanonak-protocol/sdk";var Mo=`# This file is generated by Kanonak CLI. Do not edit manually.
58
- `;function hn(){let n=Fo();return Uo(n,"..","capabilities.lock")}function q(){let n=hn();if(!Lo(n))return{version:"1",lastUpdated:new Date().toISOString(),capabilities:{}};let e=Oo(n,"utf-8"),t=gn.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 X(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=gn.dump(n,{lineWidth:-1,sortKeys:!1,quotingType:'"'});No(hn(),Mo+t,"utf-8")}import{SingleDocumentRepository as mr}from"@kanonak-protocol/sdk/uri-helpers";import{existsSync as Vo,readdirSync as Ho,readFileSync as zo}from"fs";import{join as kn}from"path";import{KanonakObjectParser as Bo,EmbeddedKanonak as $n,ReferenceKanonak as vn,getGlobalCachePath as qo}from"@kanonak-protocol/sdk";import{SingleDocumentRepository as Sn}from"@kanonak-protocol/sdk/uri-helpers";import{uriKey as Pe,findSubjectsByType as Wo,getStringValue as O,getReferenceUri as Ce,getListValues as Pn}from"@kanonak-protocol/sdk/uri-helpers";var P="kanonak.org",C="capabilities",_e={publisher:P,package_:C,name:"Capability"},Go={publisher:P,package_:C,name:"commandName"},Cn={publisher:P,package_:C,name:"description"},Jo={publisher:P,package_:C,name:"managesType"},Yo={publisher:P,package_:C,name:"deploymentTarget"},Xo={publisher:P,package_:C,name:"hasCommand"},Zo={publisher:P,package_:C,name:"subcommandName"},Qo={publisher:P,package_:C,name:"performs"},er={publisher:P,package_:C,name:"hasArgument"},nr={publisher:P,package_:C,name:"argumentName"},yn={publisher:P,package_:C,name:"isRequired"},bn={publisher:P,package_:C,name:"isOption"},tr={publisher:P,package_:C,name:"defaultValue"};async function _n(n,e,t){let o=q(),r=new Bo,s=[],a=!1;for(let[i,c]of Object.entries(o.capabilities)){let l=c,u=n.get(l.publisher,l.package_,l.version);if(!u){let p=await or(i,l,e,r,t);if(p)console.error(` Healed capability "${i}": ${l.publisher}/${l.package_}@${l.version} \u2192 ${p.entry.publisher}/${p.entry.package_}@${p.entry.version} (package was renamed)`),o.capabilities[i]=p.entry,l=p.entry,u=p.content,a=!0;else{console.error(` WARNING: Cached content missing for capability "${i}" (${l.publisher}/${l.package_}@${l.version}). Reinstall it with: kanonak capability remove ${i} && kanonak capability add ${l.publisher}/${l.package_}`);continue}}try{let p=e.parse(u),d=new Sn(p,t),f=await r.parseKanonaks(d),g=Rn(f,l.publisher,l.package_,l.version);g?s.push(g):console.error(` WARNING: No Capability instance found in "${i}" (${l.publisher}/${l.package_}@${l.version})`)}catch(p){console.error(` WARNING: Failed to parse capability "${i}": ${p}`)}}return a&&X(o),s}async function or(n,e,t,o,r){let s=kn(qo(),e.publisher);if(!Vo(s))return;let a=[];for(let i of Ho(s)){if(!i.endsWith(".kan.yml"))continue;let c=i.slice(0,-8),l=c.lastIndexOf("@");if(l===-1)continue;let u=c.substring(0,l),p=c.substring(l+1);if(u===e.package_&&p===e.version)continue;let d;try{d=zo(kn(s,i),"utf-8")}catch{continue}let f;try{let g=t.parse(d),m=new Sn(g,r),k=await o.parseKanonaks(m);f=Rn(k,e.publisher,u,p)?.commandName}catch{continue}f===n&&a.push({entry:{publisher:e.publisher,package_:u,version:p,resolved:`kanonak://${e.publisher}/${u}@${p}`,integrity:""},content:d})}if(a.length===1)return a[0]}function Rn(n,e,t,o){let r=Wo(n,_e);if(r.length===0)return;let s=r[0],a=O(s,Go)??"",i=O(s,Cn)??"",c=Ce(s,Jo),l=Ce(s,Yo),u=[];for(let p of Pn(s,Xo)){let d=rr(p,n);d&&u.push(d)}return{commandName:a,description:i,managesTypeKey:c?Pe(c):"",deploymentTargetKey:l?Pe(l):"",commands:u,publisher:e,package_:t,version:o}}function rr(n,e){let t;if(n instanceof $n)t=n;else if(n instanceof vn){let c=xn(e,n.subject.publisher,n.subject.package_,n.subject.name);c&&(t=c)}if(!t)return;let o=O(t,Zo)??"",r=O(t,Cn)??"",s=Ce(t,Qo),a=Pn(t,er),i=[];for(let c of a){let l=ar(c,e);l&&i.push(l)}return{subcommandName:o,description:r,arguments:i,actionKey:s?Pe(s):""}}function ar(n,e){let t;if(n instanceof $n)t=n;else if(n instanceof vn){let c=xn(e,n.subject.publisher,n.subject.package_,n.subject.name);c&&(t=c)}if(!t)return;let o=O(t,nr)??"",r=O(t,yn)==="true"||wn(t,yn)===!0,s=O(t,bn)==="true"||wn(t,bn)===!0,a=O(t,tr),i={argumentName:o,required:r,isOption:s};return a!==void 0&&(i.defaultValue=a),i}function wn(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 xn(n,e,t,o){for(let r of n){if(!("name"in r)||!("namespace"in r))continue;let s=r;if(s.name===o&&!(!s.namespace||typeof s.namespace!="string")&&s.namespace.startsWith(`${e}/${t}@`))return r}}import{findSubjectsByType as fr,getStringValue as gr}from"@kanonak-protocol/sdk/uri-helpers";var hr={publisher:P,package_:C,name:"commandName"};function In(){let n=new sr("capability").description("Manage Kanonak CLI capabilities (pluggable command groups)");return n.command("add <package>").description("Install a capability from a Kanonak publisher").action(async e=>{await kr(e)}),n.command("remove <name>").description("Remove an installed capability").action(async e=>{await yr(e)}),n.command("list").description("List installed capabilities").action(async()=>{await br()}),n}async function kr(n){let e=T(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:s}=e;s&&(console.error(`\`kanonak capability add\` installs whole packages \u2014 got an instance suffix "/${s}".`),console.error(`Try: kanonak capability add ${t}/${o}${r?"@"+r:""}`),process.exit(1));let a=new K,i=new ir,c=new cr,l=new ur,u=pr(l),p=new lr({fetchFn:u}),d=r??await p.getHighestVersion(t,o);d||(console.error(`Could not resolve version for "${t}/${o}".`),process.exit(1)),console.log(`Installing capability ${t}/${o}@${d}...`);let f=a.get(t,o,d);if(!f){let _=await p.getPackageUrl(t,o,d),D=await u(_,t);if(!D.ok)throw new Error(`Failed to fetch ${_} (${D.status} ${D.statusText})`);f=await D.text(),a.put(t,o,d,f)}let g=i.parse(f),m=await v(process.cwd(),i),k=new mr(g,m),h=await c.parseKanonaks(k),y=fr(h,_e);y.length===0&&(console.error(`Package ${t}/${o}@${d} does not contain a ${P}/${C}/Capability instance.`),process.exit(1));let b=y[0],w=gr(b,hr);w||(console.error(`Capability instance in ${t}/${o}@${d} has no commandName property.`),process.exit(1));let $=q();$.capabilities[w]={publisher:t,package_:o,version:d,resolved:await p.getPackageUrl(t,o,d),integrity:dr(f)},X($),console.log(`
59
- Installed capability "${w}".`),console.log(`Run "kanonak ${w} --help" to get started.`)}async function yr(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],X(e),console.log(`Removed capability "${n}" (${t.publisher}/${t.package_}@${t.version}).`)}async function br(){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 Q}from"commander";import{readFileSync as wr,writeFileSync as $r,mkdirSync as vr,existsSync as Kn,statSync as Sr}from"fs";import{join as Pr,resolve as Cr}from"path";import{KanonakParser as Ie,KanonakObjectParser as Ke,SubjectKanonak as _r,Reasoner as Rr,KanonakVocabulary as xr,makeUriKey as En,pickHighestDocument as De,formatVersion as jn}from"@kanonak-protocol/sdk";import{SingleDocumentRepository as Z}from"@kanonak-protocol/sdk/uri-helpers";import{findSubjectsByType as Re,findSubjectByUri as Ir}from"@kanonak-protocol/sdk/uri-helpers";import{TX_V3 as Dn}from"@kanonak-protocol/sdk/transformations";import{TransformationRunnerV3 as Kr,SUPPORTED_FORMATS_V3 as An}from"@kanonak-protocol/sdk/transformations";import{compileTransformationV3 as Te}from"@kanonak-protocol/sdk/transformations";function xe(n){return[...Re(n,Dn.InstanceTransformation),...Re(n,Dn.SetTransformation)]}function On(){let n=new Q("transform").description("Run ontology-driven transformations against Kanonak packages. Transformations are declarative YAML rules (instances of `kanonak.org/transformations/Transformation`) that convert ontology instances into output files. The runner produces one or more Artifacts per matched input; format backends serialize them to Markdown, HTML, SVG, TOML, JSON, or (with post-processing) PDF.").addHelpText("after",`
57
+ ${t}`),process.exit(1)}}import{Command as ur}from"commander";import{KanonakParser as pr,KanonakObjectParser as dr,PublisherIndex as mr,CredentialStore as fr,createAuthenticatedFetch as gr,computeIntegrity as hr}from"@kanonak-protocol/sdk";import{readFileSync as Fo,writeFileSync as Mo,existsSync as Vo}from"fs";import{join as Ho}from"path";import gn from"js-yaml";import{getGlobalCachePath as Bo}from"@kanonak-protocol/sdk";var zo=`# This file is generated by Kanonak CLI. Do not edit manually.
58
+ `;function hn(){let n=Bo();return Ho(n,"..","capabilities.lock")}function q(){let n=hn();if(!Vo(n))return{version:"1",lastUpdated:new Date().toISOString(),capabilities:{}};let e=Fo(n,"utf-8"),t=gn.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=gn.dump(n,{lineWidth:-1,sortKeys:!1,quotingType:'"'});Mo(hn(),zo+t,"utf-8")}import{SingleDocumentRepository as kr}from"@kanonak-protocol/sdk/uri-helpers";import{existsSync as qo,readdirSync as Wo,readFileSync as Go}from"fs";import{join as kn}from"path";import{KanonakObjectParser as Jo,EmbeddedKanonak as $n,ReferenceKanonak as vn,getGlobalCachePath as Yo}from"@kanonak-protocol/sdk";import{SingleDocumentRepository as Sn}from"@kanonak-protocol/sdk/uri-helpers";import{uriKey as Se,findSubjectsByType as Xo,getStringValue as O,getReferenceUri as Pe,getListValues as Pn}from"@kanonak-protocol/sdk/uri-helpers";var P="kanonak.org",C="capabilities",Ce={publisher:P,package_:C,name:"Capability"},Zo={publisher:P,package_:C,name:"commandName"},Cn={publisher:P,package_:C,name:"description"},Qo={publisher:P,package_:C,name:"managesType"},er={publisher:P,package_:C,name:"deploymentTarget"},nr={publisher:P,package_:C,name:"hasCommand"},tr={publisher:P,package_:C,name:"subcommandName"},or={publisher:P,package_:C,name:"performs"},rr={publisher:P,package_:C,name:"hasArgument"},sr={publisher:P,package_:C,name:"argumentName"},yn={publisher:P,package_:C,name:"isRequired"},bn={publisher:P,package_:C,name:"isOption"},ar={publisher:P,package_:C,name:"defaultValue"};async function Rn(n,e,t){let o=q(),r=new Jo,a=[],s=!1;for(let[i,c]of Object.entries(o.capabilities)){let l=c,u=n.get(l.publisher,l.package_,l.version);if(!u){let p=await ir(i,l,e,r,t);if(p)console.error(` Healed capability "${i}": ${l.publisher}/${l.package_}@${l.version} \u2192 ${p.entry.publisher}/${p.entry.package_}@${p.entry.version} (package was renamed)`),o.capabilities[i]=p.entry,l=p.entry,u=p.content,s=!0;else{console.error(` WARNING: Cached content missing for capability "${i}" (${l.publisher}/${l.package_}@${l.version}). Reinstall it with: kanonak capability remove ${i} && kanonak capability add ${l.publisher}/${l.package_}`);continue}}try{let p=e.parse(u),d=new Sn(p,t),f=await r.parseKanonaks(d),g=_n(f,l.publisher,l.package_,l.version);g?a.push(g):console.error(` WARNING: No Capability instance found in "${i}" (${l.publisher}/${l.package_}@${l.version})`)}catch(p){console.error(` WARNING: Failed to parse capability "${i}": ${p}`)}}return s&&Y(o),a}async function ir(n,e,t,o,r){let a=kn(Yo(),e.publisher);if(!qo(a))return;let s=[];for(let i of Wo(a)){if(!i.endsWith(".kan.yml"))continue;let c=i.slice(0,-8),l=c.lastIndexOf("@");if(l===-1)continue;let u=c.substring(0,l),p=c.substring(l+1);if(u===e.package_&&p===e.version)continue;let d;try{d=Go(kn(a,i),"utf-8")}catch{continue}let f;try{let g=t.parse(d),m=new Sn(g,r),k=await o.parseKanonaks(m);f=_n(k,e.publisher,u,p)?.commandName}catch{continue}f===n&&s.push({entry:{publisher:e.publisher,package_:u,version:p,resolved:`kanonak://${e.publisher}/${u}@${p}`,integrity:""},content:d})}if(s.length===1)return s[0]}function _n(n,e,t,o){let r=Xo(n,Ce);if(r.length===0)return;let a=r[0],s=O(a,Zo)??"",i=O(a,Cn)??"",c=Pe(a,Qo),l=Pe(a,er),u=[];for(let p of Pn(a,nr)){let d=cr(p,n);d&&u.push(d)}return{commandName:s,description:i,managesTypeKey:c?Se(c):"",deploymentTargetKey:l?Se(l):"",commands:u,publisher:e,package_:t,version:o}}function cr(n,e){let t;if(n instanceof $n)t=n;else if(n instanceof vn){let c=xn(e,n.subject.publisher,n.subject.package_,n.subject.name);c&&(t=c)}if(!t)return;let o=O(t,tr)??"",r=O(t,Cn)??"",a=Pe(t,or),s=Pn(t,rr),i=[];for(let c of s){let l=lr(c,e);l&&i.push(l)}return{subcommandName:o,description:r,arguments:i,actionKey:a?Se(a):""}}function lr(n,e){let t;if(n instanceof $n)t=n;else if(n instanceof vn){let c=xn(e,n.subject.publisher,n.subject.package_,n.subject.name);c&&(t=c)}if(!t)return;let o=O(t,sr)??"",r=O(t,yn)==="true"||wn(t,yn)===!0,a=O(t,bn)==="true"||wn(t,bn)===!0,s=O(t,ar),i={argumentName:o,required:r,isOption:a};return s!==void 0&&(i.defaultValue=s),i}function wn(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 xn(n,e,t,o){for(let r of n){if(!("name"in r)||!("namespace"in r))continue;let a=r;if(a.name===o&&!(!a.namespace||typeof a.namespace!="string")&&a.namespace.startsWith(`${e}/${t}@`))return r}}import{findSubjectsByType as yr,getStringValue as br}from"@kanonak-protocol/sdk/uri-helpers";var wr={publisher:P,package_:C,name:"commandName"};function In(){let n=new ur("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 $r(e)}),n.command("remove <name>").description("Remove an installed capability").action(async e=>{await vr(e)}),n.command("list").description("List installed capabilities").action(async()=>{await Sr()}),n}async function $r(n){let e=D(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 K,i=new pr,c=new dr,l=new fr,u=gr(l),p=new mr({fetchFn:u}),d=r??await p.getHighestVersion(t,o);d||(console.error(`Could not resolve version for "${t}/${o}".`),process.exit(1)),console.log(`Installing capability ${t}/${o}@${d}...`);let f=s.get(t,o,d);if(!f){let R=await p.getPackageUrl(t,o,d),T=await u(R,t);if(!T.ok)throw new Error(`Failed to fetch ${R} (${T.status} ${T.statusText})`);f=await T.text(),s.put(t,o,d,f)}let g=i.parse(f),m=await v(process.cwd(),i),k=new kr(g,m),h=await c.parseKanonaks(k),y=yr(h,Ce);y.length===0&&(console.error(`Package ${t}/${o}@${d} does not contain a ${P}/${C}/Capability instance.`),process.exit(1));let b=y[0],w=br(b,wr);w||(console.error(`Capability instance in ${t}/${o}@${d} has no commandName property.`),process.exit(1));let $=q();$.capabilities[w]={publisher:t,package_:o,version:d,resolved:await p.getPackageUrl(t,o,d),integrity:hr(f)},Y($),console.log(`
59
+ Installed capability "${w}".`),console.log(`Run "kanonak ${w} --help" to get started.`)}async function vr(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],Y(e),console.log(`Removed capability "${n}" (${t.publisher}/${t.package_}@${t.version}).`)}async function Sr(){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 Z}from"commander";import{readFileSync as Pr,writeFileSync as Cr,mkdirSync as Rr,existsSync as Kn,statSync as _r}from"fs";import{join as xr,resolve as Ir}from"path";import{KanonakParser as xe,KanonakObjectParser as Ie,SubjectKanonak as Kr,Reasoner as Tr,KanonakVocabulary as Dr,makeUriKey as En,pickHighestDocument as Ke,formatVersion as jn}from"@kanonak-protocol/sdk";import{SingleDocumentRepository as X}from"@kanonak-protocol/sdk/uri-helpers";import{findSubjectsByType as Re,findSubjectByUri as Er}from"@kanonak-protocol/sdk/uri-helpers";import{TX_V3 as Tn}from"@kanonak-protocol/sdk/transformations";import{TransformationRunnerV3 as jr,SUPPORTED_FORMATS_V3 as An}from"@kanonak-protocol/sdk/transformations";import{compileTransformationV3 as Te}from"@kanonak-protocol/sdk/transformations";function _e(n){return[...Re(n,Tn.InstanceTransformation),...Re(n,Tn.SetTransformation)]}function On(){let n=new Z("transform").description("Run ontology-driven transformations against Kanonak packages. Transformations are declarative YAML rules (instances of `kanonak.org/transformations/Transformation`) that convert ontology instances into output files. The runner produces one or more Artifacts per matched input; format backends serialize them to Markdown, HTML, SVG, TOML, JSON, or (with post-processing) PDF.").addHelpText("after",`
61
61
  Examples:
62
62
 
63
63
  # List every Transformation available in the local workspace
@@ -95,9 +95,9 @@ Examples:
95
95
 
96
96
  # List the registered format backends
97
97
  $ kanonak transform formats
98
- `);return n.addCommand(Dr()),n.addCommand(Ar()),n.addCommand(Nr()),n.addCommand(Ur()),n}function Dr(){return new Q("run").description("Run a transformation against an input scope and write the resulting Artifacts to disk.").argument("<transformation>","Transformation URI (`publisher/package/name`, optional `@version`) or just the local name if unique in the workspace.").requiredOption("--scope <scope>","Input source \u2014 either a package URI `publisher/package[@version]` (resolved via the local workspace + cache + HTTP tiers) or a file path to a `.kan.yml` document. Repeatable: pass `--scope X --scope Y` to aggregate matching instances across multiple packages, useful for index pages and other cross-package SetTransformations.",Tr,[]).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 Er(n,e)}catch(t){console.error(`Error: ${t.message}`),process.exit(1)}})}function Tr(n,e){return[...e,n]}async function Er(n,e){let t=new Ie,o=new Ke,r=await v(process.cwd(),t),s=await Nn(n,r,o),{transformation:a,transformationKanonaks:i}=s;console.log(`Transformation: ${te(a)}`);let c=Te(a,i);e.scope.length===0&&(console.error("At least one --scope is required."),process.exit(1));let l=[],u=new Map;for(let y of e.scope){let b=await Fr(y,r,t,o);l.push(...b);let w=await Hr(b,c.inputPattern.matchesClass,r);for(let $ of w){let _=zr($);_&&!u.has(_)&&u.set(_,$)}console.log(`Scope: ${y} \u2014 found ${w.length} instance(s) of ${c.inputPattern.matchesClass.publisher}/${c.inputPattern.matchesClass.package_}/${c.inputPattern.matchesClass.name}`)}let p=[...u.values()],d=l;e.scope.length>1&&console.log(`Total across ${e.scope.length} scope(s): ${p.length} unique instance(s)`),p.length===0&&c.kind==="instance"&&(console.error("No matching input instances across the supplied scope(s). Check the transformation's inputPattern.matchesClass vs. the scope package(s)."),process.exit(1));let f=jr(c.outputs,e.format);console.log(`Output format: ${f}`);let g=An[f];if(!g)throw new Error(`Unknown format "${f}". Run \`kanonak transform formats\` to see what the runner supports.`);let k=await new Kr().run({transformation:a,instances:p,allKanonaks:d,transformationKanonaks:i,repository:r,parser:t,objectParser:o,outputFormat:f}),h=Cr(e.out);vr(h,{recursive:!0});for(let y of k){let b=Vr(y.fileName),w=Pr(h,`${b}${g.extension}`);$r(w,y.content,"utf-8"),console.log(` wrote ${w}`)}console.log(`Done. ${k.length} artifact(s) written to ${h}`)}function jr(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 Ar(){return new Q("list").description("Scan the local workspace + cache for every Transformation instance and print a one-line summary per hit.").action(async()=>{try{await Or()}catch(n){console.error(`Error: ${n.message}`),process.exit(1)}})}async function Or(){let n=new Ie,e=new Ke,t=await v(process.cwd(),n),o=await t.getAllDocumentsAsync(),r=new Map;for(let a of o)try{let i=new Z(a,t),c=await e.parseKanonaks(i),l=xe(c);for(let u of l){let p=Ee(u);if(!p)continue;let d=r.get(p)??[];d.push({tx:u,kanonaks:c,doc:a}),r.set(p,d)}}catch{}let s=[];for(let a of r.values()){if(a.length===1){s.push(Tn(a[0].tx,a[0].kanonaks));continue}let i=De(a.map(l=>l.doc));if(!i.chosen)continue;let c=a.find(l=>l.doc===i.chosen);c&&s.push(Tn(c.tx,c.kanonaks))}if(s.length===0){console.log("No Transformation instances found in the current workspace.");return}s.sort((a,i)=>a.uri.localeCompare(i.uri));for(let a of s)console.log(`${a.uri}`),console.log(` matches: ${a.matchesClass}`),console.log(` outputs: ${a.outputs.join(", ")}`)}function Nr(){return new Q("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 Lr(n)}catch(e){console.error(`Error: ${e.message}`),process.exit(1)}})}async function Lr(n){let e=new Ie,t=new Ke,o=await v(process.cwd(),e),{transformation:r,transformationKanonaks:s}=await Nn(n,o,t),a=Te(r,s);if(console.log(`Transformation: ${te(r)}`),console.log(),console.log("Input pattern:"),console.log(` Matches class: ${ne(a.inputPattern.matchesClass)}`),a.inputPattern.requires.length>0){console.log(" Required properties:");for(let i of a.inputPattern.requires)console.log(` - ${ne(i)}`)}else console.log(" Required properties: (none)");if(console.log(),console.log(`Outputs: ${Array.from(a.outputs).sort().join(", ")}`),console.log(),a.overrides.size>0){console.log("Format overrides:");for(let[i,c]of a.overrides){if(console.log(` ${i}:`),c.metadataKeys&&console.log(` metadata keys: ${c.metadataKeys.join(", ")}`),c.metadataRenames.size>0){let l=[];for(let[u,p]of c.metadataRenames)l.push(`${u} \u2192 ${p}`);console.log(` metadata renames: ${l.join(", ")}`)}c.trailingNewline!==void 0&&console.log(` trailing newline: ${c.trailingNewline}`)}console.log()}console.log(`Rule root kind: ${a.rule.kind}`),a.rule.kind==="build-ast-node"&&(console.log(`Rule root AST class: ${ne(a.rule.astClass)}`),console.log(`Rule root bindings: ${a.rule.set.length} field(s)`)),console.log(`Artifact name root kind: ${a.artifactName.kind}`)}function Ur(){return new Q("formats").description("List the OutputFormat names the runner can serialize to.").action(()=>{console.log("Registered format backends:");let n=Object.entries(An).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 Nn(n,e,t){let o,r,s;if(n.includes("/")){let d=n.indexOf("@"),f=n;if(d!==-1){let m=n.indexOf("/",d);if(m===-1)throw new Error(`Transformation URI "${n}" has @version but no trailing /<name>`);f=n.substring(0,d)+n.substring(m)}let g=f.split("/");if(g.length<3)throw new Error(`Invalid transformation URI "${n}" \u2014 expected publisher/package/name or publisher/package@version/name`);o=g[0],r=g[1],s=g.slice(2).join("/")}else s=n;if(o&&r){let d=await e.getDocumentsByNamespaceAsync(o,r);if(d.length===0)throw new Error(`Package ${o}/${r} not found in the local workspace or cache.`);let f=Mr(n),g=Ln(d,f,`${o}/${r}`),m=new Z(g,e),k=await t.parseKanonaks(m),h=Ir(k,{publisher:o,package_:r,name:s,version:""});if(!h){let y=xe(k),b=y.find(w=>w.name===s);if(!b)throw new Error(`Transformation "${s}" not found in package ${o}/${r}. Package contains ${y.length} Transformation(s): ${y.map(w=>w.name).join(", ")||"(none)"}`);return{transformation:b,transformationKanonaks:k}}return{transformation:h,transformationKanonaks:k}}let a=await e.getAllDocumentsAsync(),i=new Map;for(let d of a)try{let f=new Z(d,e),g=await t.parseKanonaks(f),m=xe(g);for(let k of m){if(k.name!==s)continue;let h=Ee(k);if(!h)continue;let y=i.get(h)??[];y.push({tx:k,kanonaks:g,doc:d}),i.set(h,y)}}catch{}if(i.size===0)throw new Error(`No Transformation named "${s}" found in the workspace. Try \`kanonak transform list\` to see available transformations.`);if(i.size>1){let d=Array.from(i.keys()).sort().join(`
99
- `);throw new Error(`Multiple Transformations named "${s}" in the workspace \u2014 disambiguate with a full publisher/package/name URI:
100
- ${d}`)}let c=Array.from(i.values())[0];if(c.length===1)return{transformation:c[0].tx,transformationKanonaks:c[0].kanonaks};let l=new Map(c.map(d=>[d.doc,d])),u=De(c.map(d=>d.doc));if(!u.chosen)throw new Error(`Could not select a Transformation version for "${s}".`);let p=l.get(u.chosen);if(u.multipleVersionsPresent){let d=m=>{let k=m.metadata.namespace_?.version;return k?jn(k):""},f=p.tx.namespace??"",g=f.includes("@")?f.substring(0,f.indexOf("@")):f;console.warn(`Warning: Transformation "${s}" has ${c.length} versions present (${c.map(m=>d(m.doc)).filter(Boolean).join(", ")}); using @${d(u.chosen)}. Pin with ${g}@<version>/${s} to suppress this warning.`)}return{transformation:p.tx,transformationKanonaks:p.kanonaks}}async function Fr(n,e,t,o){if(/^[.\/\\]/.test(n)||/^[A-Za-z]:/.test(n)||n.endsWith(".kan.yml")||Kn(n)&&Sr(n).isFile()){if(!Kn(n))throw new Error(`Scope file not found: ${n}`);let g=wr(n,"utf-8"),m=t.parse(g),k=new Z(m,e);return o.parseKanonaks(k)}let s=n.indexOf("@"),a=s===-1?n:n.substring(0,s),i=s===-1?void 0:n.substring(s+1),c=a.indexOf("/");if(c===-1)throw new Error(`Invalid scope "${n}" \u2014 expected a file path or publisher/package[@version] URI`);let l=a.substring(0,c),u=a.substring(c+1),p=await e.getDocumentsByNamespaceAsync(l,u);if(p.length===0)throw new Error(`Scope package ${l}/${u} not found in the local workspace or cache.`);let d=Ln(p,i,`${l}/${u}`),f=new Z(d,e);return o.parseKanonaks(f)}function Mr(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 Ln(n,e,t){let o=s=>{let a=s.metadata.namespace_?.version;return a?jn(a):""},r=De(n,{requestedVersion:e});if(r.exactRequestedVersionMissing){let s=n.map(o).filter(Boolean).sort().join(", ");throw new Error(`${t}@${e} not found in the local workspace or cache. Available versions: ${s||"(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 Tn(n,e){try{let t=Te(n,e);return{uri:te(n),matchesClass:ne(t.inputPattern.matchesClass),outputs:Array.from(t.outputs).sort()}}catch(t){return{uri:te(n),matchesClass:`(compile error: ${t.message})`,outputs:[]}}}function te(n){let e=n.namespace||"",t=e.indexOf("@");return`${t===-1?e:e.substring(0,t)}/${n.name}`}function ne(n){return`${n.publisher}/${n.package_}/${n.name}`}function Vr(n){return n.replace(/[\\/:*?"<>|\s]+/g,"_").replace(/^_+|_+$/g,"")}async function Hr(n,e,t){let o=new Map;for(let a of n){if(!(a instanceof _r))continue;let i=Ee(a);i&&o.set(i,a)}let r=[];try{r=(await new Rr({vocabulary:new xr}).reason(t)).getInstancesOfClass(En(e.publisher,e.package_,e.name))}catch{}let s=[];for(let a of r){let i=o.get(a);i&&s.push(i)}return s.length>0?s:Re(n,e)}function Ee(n){let e=n.namespace??"",t=e.indexOf("@"),o=t===-1?e:e.substring(0,t),r=o.indexOf("/");return r===-1||!n.name?null:En(o.substring(0,r),o.substring(r+1),n.name)}function zr(n){let e=n.namespace??"";return!e||!n.name?null:`${e}/${n.name}`}import{Command as Br}from"commander";import{writeFileSync as qr,mkdirSync as Wr}from"fs";import{join as Gr,resolve as Jr}from"path";import{KanonakParser as Yr,KanonakObjectParser as Xr,SubjectKanonak as Mn,findDerivation as Zr}from"@kanonak-protocol/sdk";import{TransformationRunnerV3 as Qr}from"@kanonak-protocol/sdk/transformations";var ea={publisher:"kanonak.org",package_:"formats",name:"html"},na={publisher:"kanonak.org",package_:"derivation",name:"default"},ta={html:".html",markdown:".md",json:".json",yaml:".yaml",xml:".xml",svg:".svg",typescript:".ts","c-sharp":".cs",rust:".rs",python:".py"};function oa(n){return n==="markdown"?"markdown-with-frontmatter":n}function Vn(){return new Br("derive").description("Materialize a derived artifact from a Kanonak resource by walking the polymorphic derivation discovery: instance overrides \u2192 class hierarchy \u2192 universal defaults. The result is written to disk.").argument("<resource>","Resource URI in the form publisher/package[@version]/name. Identifies the specific instance to derive.").option("--format <name>","Format instance name (e.g. html, markdown, json). Defaults to html.","html").option("--variant <name>","Variant instance name (e.g. default, compact, summary). Defaults to default.","default").option("--out <dir>","Directory to write the artifact into.",".").addHelpText("after",`
98
+ `);return n.addCommand(Ar()),n.addCommand(Ur()),n.addCommand(Mr()),n.addCommand(Hr()),n}function Ar(){return new Z("run").description("Run a transformation against an input scope and write the resulting Artifacts to disk.").argument("<transformation>","Transformation URI (`publisher/package/name`, optional `@version`) or just the local name if unique in the workspace.").requiredOption("--scope <scope>","Input source \u2014 either a package URI `publisher/package[@version]` (resolved via the local workspace + cache + HTTP tiers) or a file path to a `.kan.yml` document. Repeatable: pass `--scope X --scope Y` to aggregate matching instances across multiple packages, useful for index pages and other cross-package SetTransformations.",Or,[]).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 Nr(n,e)}catch(t){console.error(`Error: ${t.message}`),process.exit(1)}})}function Or(n,e){return[...e,n]}async function Nr(n,e){let t=new xe,o=new Ie,r=await v(process.cwd(),t),a=await Nn(n,r,o),{transformation:s,transformationKanonaks:i}=a;console.log(`Transformation: ${ne(s)}`);let c=Te(s,i);e.scope.length===0&&(console.error("At least one --scope is required."),process.exit(1));let l=[],u=new Map;for(let y of e.scope){let b=await Br(y,r,t,o);l.push(...b);let w=await Wr(b,c.inputPattern.matchesClass,r);for(let $ of w){let R=Gr($);R&&!u.has(R)&&u.set(R,$)}console.log(`Scope: ${y} \u2014 found ${w.length} instance(s) of ${c.inputPattern.matchesClass.publisher}/${c.inputPattern.matchesClass.package_}/${c.inputPattern.matchesClass.name}`)}let p=[...u.values()],d=l;e.scope.length>1&&console.log(`Total across ${e.scope.length} scope(s): ${p.length} unique instance(s)`),p.length===0&&c.kind==="instance"&&(console.error("No matching input instances across the supplied scope(s). Check the transformation's inputPattern.matchesClass vs. the scope package(s)."),process.exit(1));let f=Lr(c.outputs,e.format);console.log(`Output format: ${f}`);let g=An[f];if(!g)throw new Error(`Unknown format "${f}". Run \`kanonak transform formats\` to see what the runner supports.`);let k=await new jr().run({transformation:s,instances:p,allKanonaks:d,transformationKanonaks:i,repository:r,parser:t,objectParser:o,outputFormat:f}),h=Ir(e.out);Rr(h,{recursive:!0});for(let y of k){let b=qr(y.fileName),w=xr(h,`${b}${g.extension}`);Cr(w,y.content,"utf-8"),console.log(` wrote ${w}`)}console.log(`Done. ${k.length} artifact(s) written to ${h}`)}function Lr(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 Ur(){return new Z("list").description("Scan the local workspace + cache for every Transformation instance and print a one-line summary per hit.").action(async()=>{try{await Fr()}catch(n){console.error(`Error: ${n.message}`),process.exit(1)}})}async function Fr(){let n=new xe,e=new Ie,t=await v(process.cwd(),n),o=await t.getAllDocumentsAsync(),r=new Map;for(let s of o)try{let i=new X(s,t),c=await e.parseKanonaks(i),l=_e(c);for(let u of l){let p=De(u);if(!p)continue;let d=r.get(p)??[];d.push({tx:u,kanonaks:c,doc:s}),r.set(p,d)}}catch{}let a=[];for(let s of r.values()){if(s.length===1){a.push(Dn(s[0].tx,s[0].kanonaks));continue}let i=Ke(s.map(l=>l.doc));if(!i.chosen)continue;let c=s.find(l=>l.doc===i.chosen);c&&a.push(Dn(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 Mr(){return new Z("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 Vr(n)}catch(e){console.error(`Error: ${e.message}`),process.exit(1)}})}async function Vr(n){let e=new xe,t=new Ie,o=await v(process.cwd(),e),{transformation:r,transformationKanonaks:a}=await Nn(n,o,t),s=Te(r,a);if(console.log(`Transformation: ${ne(r)}`),console.log(),console.log("Input pattern:"),console.log(` Matches class: ${ee(s.inputPattern.matchesClass)}`),s.inputPattern.requires.length>0){console.log(" Required properties:");for(let i of s.inputPattern.requires)console.log(` - ${ee(i)}`)}else console.log(" Required properties: (none)");if(console.log(),console.log(`Outputs: ${Array.from(s.outputs).sort().join(", ")}`),console.log(),s.overrides.size>0){console.log("Format overrides:");for(let[i,c]of s.overrides){if(console.log(` ${i}:`),c.metadataKeys&&console.log(` metadata keys: ${c.metadataKeys.join(", ")}`),c.metadataRenames.size>0){let l=[];for(let[u,p]of c.metadataRenames)l.push(`${u} \u2192 ${p}`);console.log(` metadata renames: ${l.join(", ")}`)}c.trailingNewline!==void 0&&console.log(` trailing newline: ${c.trailingNewline}`)}console.log()}console.log(`Rule root kind: ${s.rule.kind}`),s.rule.kind==="build-ast-node"&&(console.log(`Rule root AST class: ${ee(s.rule.astClass)}`),console.log(`Rule root bindings: ${s.rule.set.length} field(s)`)),console.log(`Artifact name root kind: ${s.artifactName.kind}`)}function Hr(){return new Z("formats").description("List the OutputFormat names the runner can serialize to.").action(()=>{console.log("Registered format backends:");let n=Object.entries(An).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 Nn(n,e,t){let o,r,a;if(n.includes("/")){let d=n.indexOf("@"),f=n;if(d!==-1){let m=n.indexOf("/",d);if(m===-1)throw new Error(`Transformation URI "${n}" has @version but no trailing /<name>`);f=n.substring(0,d)+n.substring(m)}let g=f.split("/");if(g.length<3)throw new Error(`Invalid transformation URI "${n}" \u2014 expected publisher/package/name or publisher/package@version/name`);o=g[0],r=g[1],a=g.slice(2).join("/")}else a=n;if(o&&r){let d=await e.getDocumentsByNamespaceAsync(o,r);if(d.length===0)throw new Error(`Package ${o}/${r} not found in the local workspace or cache.`);let f=zr(n),g=Ln(d,f,`${o}/${r}`),m=new X(g,e),k=await t.parseKanonaks(m),h=Er(k,{publisher:o,package_:r,name:a,version:""});if(!h){let y=_e(k),b=y.find(w=>w.name===a);if(!b)throw new Error(`Transformation "${a}" not found in package ${o}/${r}. Package contains ${y.length} Transformation(s): ${y.map(w=>w.name).join(", ")||"(none)"}`);return{transformation:b,transformationKanonaks:k}}return{transformation:h,transformationKanonaks:k}}let s=await e.getAllDocumentsAsync(),i=new Map;for(let d of s)try{let f=new X(d,e),g=await t.parseKanonaks(f),m=_e(g);for(let k of m){if(k.name!==a)continue;let h=De(k);if(!h)continue;let y=i.get(h)??[];y.push({tx:k,kanonaks:g,doc:d}),i.set(h,y)}}catch{}if(i.size===0)throw new Error(`No Transformation named "${a}" found in the workspace. Try \`kanonak transform list\` to see available transformations.`);if(i.size>1){let d=Array.from(i.keys()).sort().join(`
99
+ `);throw new Error(`Multiple Transformations named "${a}" in the workspace \u2014 disambiguate with a full publisher/package/name URI:
100
+ ${d}`)}let c=Array.from(i.values())[0];if(c.length===1)return{transformation:c[0].tx,transformationKanonaks:c[0].kanonaks};let l=new Map(c.map(d=>[d.doc,d])),u=Ke(c.map(d=>d.doc));if(!u.chosen)throw new Error(`Could not select a Transformation version for "${a}".`);let p=l.get(u.chosen);if(u.multipleVersionsPresent){let d=m=>{let k=m.metadata.namespace_?.version;return k?jn(k):""},f=p.tx.namespace??"",g=f.includes("@")?f.substring(0,f.indexOf("@")):f;console.warn(`Warning: Transformation "${a}" has ${c.length} versions present (${c.map(m=>d(m.doc)).filter(Boolean).join(", ")}); using @${d(u.chosen)}. Pin with ${g}@<version>/${a} to suppress this warning.`)}return{transformation:p.tx,transformationKanonaks:p.kanonaks}}async function Br(n,e,t,o){if(/^[.\/\\]/.test(n)||/^[A-Za-z]:/.test(n)||n.endsWith(".kan.yml")||Kn(n)&&_r(n).isFile()){if(!Kn(n))throw new Error(`Scope file not found: ${n}`);let g=Pr(n,"utf-8"),m=t.parse(g),k=new X(m,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),p=await e.getDocumentsByNamespaceAsync(l,u);if(p.length===0)throw new Error(`Scope package ${l}/${u} not found in the local workspace or cache.`);let d=Ln(p,i,`${l}/${u}`),f=new X(d,e);return o.parseKanonaks(f)}function zr(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 Ln(n,e,t){let o=a=>{let s=a.metadata.namespace_?.version;return s?jn(s):""},r=Ke(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 Dn(n,e){try{let t=Te(n,e);return{uri:ne(n),matchesClass:ee(t.inputPattern.matchesClass),outputs:Array.from(t.outputs).sort()}}catch(t){return{uri:ne(n),matchesClass:`(compile error: ${t.message})`,outputs:[]}}}function ne(n){let e=n.namespace||"",t=e.indexOf("@");return`${t===-1?e:e.substring(0,t)}/${n.name}`}function ee(n){return`${n.publisher}/${n.package_}/${n.name}`}function qr(n){return n.replace(/[\\/:*?"<>|\s]+/g,"_").replace(/^_+|_+$/g,"")}async function Wr(n,e,t){let o=new Map;for(let s of n){if(!(s instanceof Kr))continue;let i=De(s);i&&o.set(i,s)}let r=[];try{r=(await new Tr({vocabulary:new Dr}).reason(t)).getInstancesOfClass(En(e.publisher,e.package_,e.name))}catch{}let a=[];for(let s of r){let i=o.get(s);i&&a.push(i)}return a.length>0?a:Re(n,e)}function De(n){let e=n.namespace??"",t=e.indexOf("@"),o=t===-1?e:e.substring(0,t),r=o.indexOf("/");return r===-1||!n.name?null:En(o.substring(0,r),o.substring(r+1),n.name)}function Gr(n){let e=n.namespace??"";return!e||!n.name?null:`${e}/${n.name}`}import{Command as Jr}from"commander";import{writeFileSync as Yr,mkdirSync as Xr}from"fs";import{join as Zr,resolve as Qr}from"path";import{KanonakParser as es,KanonakObjectParser as ns,SubjectKanonak as Mn,findDerivation as ts}from"@kanonak-protocol/sdk";import{TransformationRunnerV3 as os}from"@kanonak-protocol/sdk/transformations";var rs={publisher:"kanonak.org",package_:"formats",name:"html"},ss={publisher:"kanonak.org",package_:"derivation",name:"default"},as={html:".html",markdown:".md",json:".json",yaml:".yaml",xml:".xml",svg:".svg",typescript:".ts","c-sharp":".cs",rust:".rs",python:".py"};function is(n){return n==="markdown"?"markdown-with-frontmatter":n}function Vn(){return new Jr("derive").description("Materialize a derived artifact from a Kanonak resource by walking the polymorphic derivation discovery: instance overrides \u2192 class hierarchy \u2192 universal defaults. The result is written to disk.").argument("<resource>","Resource URI in the form publisher/package[@version]/name. Identifies the specific instance to derive.").option("--format <name>","Format instance name (e.g. html, markdown, json). Defaults to html.","html").option("--variant <name>","Variant instance name (e.g. default, compact, summary). Defaults to default.","default").option("--out <dir>","Directory to write the artifact into.",".").addHelpText("after",`
101
101
  Examples:
102
102
 
103
103
  # Render a resource as HTML using whatever derivation the discovery
@@ -108,28 +108,28 @@ Examples:
108
108
 
109
109
  # Materialize the JSON view (universal default unless overridden).
110
110
  $ kanonak derive my-publisher.com/my-package/my-resource --format json
111
- `).action(async(n,e)=>{try{await ra(n,e)}catch(t){console.error(`Error: ${t.message}`),process.exit(1)}})}async function ra(n,e){let t=T(n);if(!t||!t.instanceName)throw new Error(`Invalid resource URI "${n}". Expected publisher/package[@version]/instance.`);let o=new Yr,r=new Xr,s=await v(process.cwd(),o),a=await r.parseKanonaks(s),i=aa(a,t);if(!i)throw new Error(`Resource ${t.publisher}/${t.packageName}${t.version?`@${t.version}`:""}/${t.instanceName} not found in the workspace or cache.`);console.log(`Resource: ${Un(i)}`);let c=ia(e.format),l=ca(e.variant),u=Zr(i,c,l,a);if(!u)throw new Error(`No derivation found for resource ${Un(i)} at (format=${e.format}, variant=${e.variant}). The class hierarchy declares no binding and no universal default applies.`);console.log(`Derivation: ${la(u)} \u2192 ${Fn(u.transformation)}`);let p=sa(a,u.transformation);if(!p)throw new Error(`Transformation ${Fn(u.transformation)} not found in the workspace or cache. The binding pointed at a transformation the resolver cannot locate.`);let d=oa(e.format),g=await new Qr().run({transformation:p,instances:[i],allKanonaks:a,repository:s,parser:o,objectParser:r,outputFormat:d}),m=Jr(e.out);Wr(m,{recursive:!0});let k=ta[e.format]??"";for(let h of g){let y=ua(h.fileName),b=Gr(m,`${y}${k}`);qr(b,h.content,"utf-8"),console.log(` wrote ${b}`)}console.log(`Done. ${g.length} artifact(s) written to ${m}`)}function aa(n,e){for(let t of n){if(!(t instanceof Mn)||t.name!==e.instanceName)continue;let o=t.namespace||"",r=`${e.publisher}/${e.packageName}@`;if(o.startsWith(r))if(e.version){if(o===`${e.publisher}/${e.packageName}@${e.version}`)return t}else return t}}function sa(n,e){let t=`${e.publisher}/${e.package_}@${e.version}`;for(let o of n)if(o instanceof Mn&&o.name===e.name&&o.namespace===t)return o}function ia(n){if(n.includes("/")){let e=T(n);if(!e||!e.instanceName)throw new Error(`Invalid --format URI "${n}".`);return{publisher:e.publisher,package_:e.packageName,name:e.instanceName}}return{...ea,name:n}}function ca(n){if(n.includes("/")){let e=T(n);if(!e||!e.instanceName)throw new Error(`Invalid --variant URI "${n}".`);return{publisher:e.publisher,package_:e.packageName,name:e.instanceName}}return{...na,name:n}}function Un(n){return`${n.namespace}/${n.name}`}function Fn(n){return`${n.publisher}/${n.package_}@${n.version}/${n.name}`}function la(n){return n.source==="instance"?"instance override":`class ${n.source.publisher}/${n.source.package_}/${n.source.name}`}function ua(n){return n.replace(/[^a-zA-Z0-9._@-]+/g,"_")}import{Command as pa}from"commander";import{writeFileSync as x,mkdirSync as L}from"fs";import{join as S,resolve as Hn,dirname as da}from"path";import{SubjectKanonak as ma}from"@kanonak-protocol/sdk";import{loadServerModel as fa,route as ga}from"@kanonak-protocol/sdk/server";function zn(){return new pa("publish").description("Generate a static Kanonak site from the local workspace \u2014 the same origin `kanonak serve` produces (it shares serve's model + renderer), frozen to disk under --out.").option("--workspace <dir>","Workspace directory containing .kan.yml package files. Defaults to current directory.",process.cwd()).option("--out <dir>","Output directory for the generated site. Defaults to _site.","_site").option("--publisher <domain>","Publisher to publish (required only if the workspace has more than one).").action(async n=>{await ha(n)})}async function ha(n){let e=Hn(n.workspace),t=Hn(n.out),o=await fa(e,n.publisher?{publisher:n.publisher}:{}),{catalog:r,lookRenderer:s,localNamespaces:a,rawByNsKey:i,publisher:c}=o;L(t,{recursive:!0}),console.log(`Publishing ${c} \u2014 ${a.size} package version(s) to ${t}`);let l=r.filter(g=>g instanceof ma&&a.has(g.namespace||""));console.log(`Rendering ${l.length} resource(s).`);let u=0,p=0;for(let g of l){let m=(g.namespace||"").split("/")[1]??"",[k,h]=m.split("@");if(!k||!h)continue;let y=S(t,k,h);L(y,{recursive:!0});try{let b=s.renderRawMarkdown(g);b!==void 0&&(x(S(y,`${g.name}.md`),b,"utf-8"),u+=1),x(S(y,`${g.name}.html`),s.renderDocument(g),"utf-8"),x(S(y,`${g.name}.css`),s.renderStylesheet(g),"utf-8"),x(S(y,`${g.name}.svg`),s.renderSvg(g),"utf-8"),u+=3}catch(b){console.warn(` ${g.namespace}/${g.name}: ${b.message}`),p+=1}}console.log(`Done. ${u} artifact(s) written, ${p} skipped.`);let d=ya(t,l,s);console.log(`Wrote ${d} package overview page(s).`),ba(t,l,s);let f=wa(t,l);console.log(`Wrote ${f} version-form redirect stub(s).`),ka(t,o)}function ka(n,e){if(e.rawByNsKey.size===0)return;let t=(o,r)=>{let s=S(n,r);L(da(s),{recursive:!0}),x(s,ga(e,o).body,"utf-8")};t("/.well-known/kanonak.json",".well-known/kanonak.json"),t("/index.txt","index.txt");for(let o of e.rawByNsKey.keys()){let[r,s]=o.split("@");!r||!s||t(`/${r}/${s}.kan.yml`,`${r}/${s}.kan.yml`)}console.log(`Wrote publisher endpoints: index.txt, .well-known/kanonak.json, and ${e.rawByNsKey.size} raw package source(s).`)}function ya(n,e,t){let o=new Map,r=new Map;for(let i of e){let c=i.namespace||"",[,l]=c.split("/");if(!l)continue;let[u,p]=l.split("@");if(!u||!p||i.name!==u)continue;let d=p.split(".").map(Number);if(d.length!==3||d.some(m=>Number.isNaN(m)))continue;let f={verStr:p,major:d[0],minor:d[1],patch:d[2]};o.has(u)||o.set(u,[]),o.get(u).push({resource:i,ver:f});let g=r.get(u);(!g||f.major>g.ver.major||f.major===g.ver.major&&f.minor>g.ver.minor||f.major===g.ver.major&&f.minor===g.ver.minor&&f.patch>g.ver.patch)&&r.set(u,{resource:i,ver:f})}let s=(i,c)=>{try{return L(i,{recursive:!0}),x(S(i,"index.html"),t.renderDocument(c),"utf-8"),x(S(i,`${c.name}.css`),t.renderStylesheet(c),"utf-8"),!0}catch{return!1}},a=0;for(let[i,c]of o)for(let{resource:l,ver:u}of c)s(S(n,i,u.verStr),l)&&(a+=1);for(let[i,{resource:c}]of r){let l=S(n,i);try{if(L(l,{recursive:!0}),t.hasDeclaredView(c))x(S(l,"index.html"),t.renderDocument(c,{bareOverview:!0}),"utf-8"),x(S(l,`${c.name}.css`),t.renderStylesheet(c),"utf-8");else{let u=(o.get(i)??[]).slice().sort((p,d)=>d.ver.major-p.ver.major||d.ver.minor-p.ver.minor||d.ver.patch-p.ver.patch).map(p=>p.ver.verStr);x(S(l,"index.html"),t.renderPackageVersionList(i,u,c),"utf-8"),x(S(l,`${c.name}.css`),t.renderStylesheet(c),"utf-8")}a+=1}catch{}}return a}function ba(n,e,t){let o="",r=new Map;for(let a of e){let c=(a.namespace||"").split("/"),[l]=(c[1]??"").split("@");if(!c[0]||!l||(o||(o=c[0]),a.name!==l))continue;let u=(c[1]??"").split("@")[1]??"",p=u.split(".").map(Number);if(p.length!==3||p.some(g=>Number.isNaN(g)))continue;let d={verStr:u,major:p[0],minor:p[1],patch:p[2]},f=r.get(l);(!f||d.major>f.ver.major||d.major===f.ver.major&&d.minor>f.ver.minor||d.major===f.ver.major&&d.minor===f.ver.minor&&d.patch>f.ver.patch)&&r.set(l,{resource:a,ver:d})}if(!o||r.size===0)return;let s=t.publisherSubject(o);x(S(n,"index.html"),t.renderDocument(s,{rootIndex:!0}),"utf-8"),x(S(n,"index.css"),t.renderStylesheet(s),"utf-8")}function wa(n,e){let t=new Map;for(let r of e){let s=r.namespace||"",[,a]=s.split("/");if(!a)continue;let[i,c]=a.split("@");if(!i||!c)continue;let l=c.split(".").map(Number);if(l.length!==3||l.some(p=>Number.isNaN(p)))continue;let u=`${i}/${r.name}`;t.has(u)||t.set(u,[]),t.get(u).push({verStr:c,major:l[0],minor:l[1],patch:l[2]})}let o=0;for(let[r,s]of t){let[a,i]=r.split("/");s.sort((p,d)=>d.major-p.major||d.minor-p.minor||d.patch-p.patch);let c=s[0];x(S(n,a,`${i}.html`),je(`/${a}/${c.verStr}/${i}`),"utf-8"),o+=1;let l=new Set;for(let p of s){if(l.has(p.major))continue;l.add(p.major);let d=S(n,a,String(p.major));L(d,{recursive:!0}),x(S(d,`${i}.html`),je(`/${a}/${p.verStr}/${i}`),"utf-8"),o+=1}let u=new Set;for(let p of s){let d=`${p.major}.${p.minor}`;if(u.has(d))continue;u.add(d);let f=S(n,a,d);L(f,{recursive:!0}),x(S(f,`${i}.html`),je(`/${a}/${p.verStr}/${i}`),"utf-8"),o+=1}}return o}function je(n){let e=n.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;");return`<!doctype html>
111
+ `).action(async(n,e)=>{try{await cs(n,e)}catch(t){console.error(`Error: ${t.message}`),process.exit(1)}})}async function cs(n,e){let t=D(n);if(!t||!t.instanceName)throw new Error(`Invalid resource URI "${n}". Expected publisher/package[@version]/instance.`);let o=new es,r=new ns,a=await v(process.cwd(),o),s=await r.parseKanonaks(a),i=ls(s,t);if(!i)throw new Error(`Resource ${t.publisher}/${t.packageName}${t.version?`@${t.version}`:""}/${t.instanceName} not found in the workspace or cache.`);console.log(`Resource: ${Un(i)}`);let c=ps(e.format),l=ds(e.variant),u=ts(i,c,l,s);if(!u)throw new Error(`No derivation found for resource ${Un(i)} at (format=${e.format}, variant=${e.variant}). The class hierarchy declares no binding and no universal default applies.`);console.log(`Derivation: ${ms(u)} \u2192 ${Fn(u.transformation)}`);let p=us(s,u.transformation);if(!p)throw new Error(`Transformation ${Fn(u.transformation)} not found in the workspace or cache. The binding pointed at a transformation the resolver cannot locate.`);let d=is(e.format),g=await new os().run({transformation:p,instances:[i],allKanonaks:s,repository:a,parser:o,objectParser:r,outputFormat:d}),m=Qr(e.out);Xr(m,{recursive:!0});let k=as[e.format]??"";for(let h of g){let y=fs(h.fileName),b=Zr(m,`${y}${k}`);Yr(b,h.content,"utf-8"),console.log(` wrote ${b}`)}console.log(`Done. ${g.length} artifact(s) written to ${m}`)}function ls(n,e){for(let t of n){if(!(t instanceof Mn)||t.name!==e.instanceName)continue;let o=t.namespace||"",r=`${e.publisher}/${e.packageName}@`;if(o.startsWith(r))if(e.version){if(o===`${e.publisher}/${e.packageName}@${e.version}`)return t}else return t}}function us(n,e){let t=`${e.publisher}/${e.package_}@${e.version}`;for(let o of n)if(o instanceof Mn&&o.name===e.name&&o.namespace===t)return o}function ps(n){if(n.includes("/")){let e=D(n);if(!e||!e.instanceName)throw new Error(`Invalid --format URI "${n}".`);return{publisher:e.publisher,package_:e.packageName,name:e.instanceName}}return{...rs,name:n}}function ds(n){if(n.includes("/")){let e=D(n);if(!e||!e.instanceName)throw new Error(`Invalid --variant URI "${n}".`);return{publisher:e.publisher,package_:e.packageName,name:e.instanceName}}return{...ss,name:n}}function Un(n){return`${n.namespace}/${n.name}`}function Fn(n){return`${n.publisher}/${n.package_}@${n.version}/${n.name}`}function ms(n){return n.source==="instance"?"instance override":`class ${n.source.publisher}/${n.source.package_}/${n.source.name}`}function fs(n){return n.replace(/[^a-zA-Z0-9._@-]+/g,"_")}import{Command as gs}from"commander";import{writeFileSync as x,mkdirSync as L}from"fs";import{join as S,resolve as Hn,dirname as hs}from"path";import{SubjectKanonak as ks}from"@kanonak-protocol/sdk";import{loadServerModel as ys,route as bs}from"@kanonak-protocol/sdk/server";function Bn(){return new gs("publish").description("Generate a static Kanonak site from the local workspace \u2014 the same origin `kanonak serve` produces (it shares serve's model + renderer), frozen to disk under --out.").option("--workspace <dir>","Workspace directory containing .kan.yml package files. Defaults to current directory.",process.cwd()).option("--out <dir>","Output directory for the generated site. Defaults to _site.","_site").option("--publisher <domain>","Publisher to publish (required only if the workspace has more than one).").action(async n=>{await ws(n)})}async function ws(n){let e=Hn(n.workspace),t=Hn(n.out),o=await ys(e,n.publisher?{publisher:n.publisher}:{}),{catalog:r,lookRenderer:a,localNamespaces:s,rawByNsKey:i,publisher:c}=o;L(t,{recursive:!0}),console.log(`Publishing ${c} \u2014 ${s.size} package version(s) to ${t}`);let l=r.filter(g=>g instanceof ks&&s.has(g.namespace||""));console.log(`Rendering ${l.length} resource(s).`);let u=0,p=0;for(let g of l){let m=(g.namespace||"").split("/")[1]??"",[k,h]=m.split("@");if(!k||!h)continue;let y=S(t,k,h);L(y,{recursive:!0});try{let b=a.renderRawMarkdown(g);b!==void 0&&(x(S(y,`${g.name}.md`),b,"utf-8"),u+=1),x(S(y,`${g.name}.html`),a.renderDocument(g),"utf-8"),x(S(y,`${g.name}.css`),a.renderStylesheet(g),"utf-8"),x(S(y,`${g.name}.svg`),a.renderSvg(g),"utf-8"),u+=3}catch(b){console.warn(` ${g.namespace}/${g.name}: ${b.message}`),p+=1}}console.log(`Done. ${u} artifact(s) written, ${p} skipped.`);let d=vs(t,l,a);console.log(`Wrote ${d} package overview page(s).`),Ss(t,l,a);let f=Ps(t,l);console.log(`Wrote ${f} version-form redirect stub(s).`),$s(t,o)}function $s(n,e){if(e.rawByNsKey.size===0)return;let t=(o,r)=>{let a=S(n,r);L(hs(a),{recursive:!0}),x(a,bs(e,o).body,"utf-8")};t("/.well-known/kanonak.json",".well-known/kanonak.json"),t("/index.txt","index.txt");for(let o of e.rawByNsKey.keys()){let[r,a]=o.split("@");!r||!a||t(`/${r}/${a}.kan.yml`,`${r}/${a}.kan.yml`)}console.log(`Wrote publisher endpoints: index.txt, .well-known/kanonak.json, and ${e.rawByNsKey.size} raw package source(s).`)}function vs(n,e,t){let o=new Map,r=new Map;for(let i of e){let c=i.namespace||"",[,l]=c.split("/");if(!l)continue;let[u,p]=l.split("@");if(!u||!p||i.name!==u)continue;let d=p.split(".").map(Number);if(d.length!==3||d.some(m=>Number.isNaN(m)))continue;let f={verStr:p,major:d[0],minor:d[1],patch:d[2]};o.has(u)||o.set(u,[]),o.get(u).push({resource:i,ver:f});let g=r.get(u);(!g||f.major>g.ver.major||f.major===g.ver.major&&f.minor>g.ver.minor||f.major===g.ver.major&&f.minor===g.ver.minor&&f.patch>g.ver.patch)&&r.set(u,{resource:i,ver:f})}let a=(i,c)=>{try{return L(i,{recursive:!0}),x(S(i,"index.html"),t.renderDocument(c),"utf-8"),x(S(i,`${c.name}.css`),t.renderStylesheet(c),"utf-8"),!0}catch{return!1}},s=0;for(let[i,c]of o)for(let{resource:l,ver:u}of c)a(S(n,i,u.verStr),l)&&(s+=1);for(let[i,{resource:c}]of r){let l=S(n,i);try{if(L(l,{recursive:!0}),t.hasDeclaredView(c))x(S(l,"index.html"),t.renderDocument(c,{bareOverview:!0}),"utf-8"),x(S(l,`${c.name}.css`),t.renderStylesheet(c),"utf-8");else{let u=(o.get(i)??[]).slice().sort((p,d)=>d.ver.major-p.ver.major||d.ver.minor-p.ver.minor||d.ver.patch-p.ver.patch).map(p=>p.ver.verStr);x(S(l,"index.html"),t.renderPackageVersionList(i,u,c),"utf-8"),x(S(l,`${c.name}.css`),t.renderStylesheet(c),"utf-8")}s+=1}catch{}}return s}function Ss(n,e,t){let o="",r=new Map;for(let s of e){let c=(s.namespace||"").split("/"),[l]=(c[1]??"").split("@");if(!c[0]||!l||(o||(o=c[0]),s.name!==l))continue;let u=(c[1]??"").split("@")[1]??"",p=u.split(".").map(Number);if(p.length!==3||p.some(g=>Number.isNaN(g)))continue;let d={verStr:u,major:p[0],minor:p[1],patch:p[2]},f=r.get(l);(!f||d.major>f.ver.major||d.major===f.ver.major&&d.minor>f.ver.minor||d.major===f.ver.major&&d.minor===f.ver.minor&&d.patch>f.ver.patch)&&r.set(l,{resource:s,ver:d})}if(!o||r.size===0)return;let a=t.publisherSubject(o);x(S(n,"index.html"),t.renderDocument(a,{rootIndex:!0}),"utf-8"),x(S(n,"index.css"),t.renderStylesheet(a),"utf-8")}function Ps(n,e){let t=new Map;for(let r of e){let a=r.namespace||"",[,s]=a.split("/");if(!s)continue;let[i,c]=s.split("@");if(!i||!c)continue;let l=c.split(".").map(Number);if(l.length!==3||l.some(p=>Number.isNaN(p)))continue;let u=`${i}/${r.name}`;t.has(u)||t.set(u,[]),t.get(u).push({verStr:c,major:l[0],minor:l[1],patch:l[2]})}let o=0;for(let[r,a]of t){let[s,i]=r.split("/");a.sort((p,d)=>d.major-p.major||d.minor-p.minor||d.patch-p.patch);let c=a[0];x(S(n,s,`${i}.html`),Ee(`/${s}/${c.verStr}/${i}`),"utf-8"),o+=1;let l=new Set;for(let p of a){if(l.has(p.major))continue;l.add(p.major);let d=S(n,s,String(p.major));L(d,{recursive:!0}),x(S(d,`${i}.html`),Ee(`/${s}/${p.verStr}/${i}`),"utf-8"),o+=1}let u=new Set;for(let p of a){let d=`${p.major}.${p.minor}`;if(u.has(d))continue;u.add(d);let f=S(n,s,d);L(f,{recursive:!0}),x(S(f,`${i}.html`),Ee(`/${s}/${p.verStr}/${i}`),"utf-8"),o+=1}}return o}function Ee(n){let e=n.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;");return`<!doctype html>
112
112
  <meta charset="utf-8">
113
113
  <title>Redirecting\u2026</title>
114
114
  <meta http-equiv="refresh" content="0; url=${e}">
115
115
  <link rel="canonical" href="${e}">
116
116
  <p>If you are not redirected automatically, follow this <a href="${e}">link</a>.</p>
117
- `}import{Command as Jn}from"commander";import{writeFileSync as Ae,mkdirSync as oe}from"fs";import{join as Oe,resolve as $a,dirname as Ne}from"path";import{KanonakParser as va,KanonakObjectParser as Sa,SubjectKanonak as Yn,ReferenceStatement as Pa,ReferenceKanonak as Ca,ListStatement as _a,StringStatement as Xn,EmbeddedStatement as Ra,findDerivation as Bn}from"@kanonak-protocol/sdk";import{SingleDocumentRepository as xa}from"@kanonak-protocol/sdk/uri-helpers";import{TransformationRunnerV3 as Ia}from"@kanonak-protocol/sdk/transformations";import{findSubjectsByType as re}from"@kanonak-protocol/sdk/uri-helpers";var E="kanonak.org",j="site",qn={publisher:"kanonak.org",package_:"formats",name:"html"},Wn={publisher:"kanonak.org",package_:"derivation",name:"default"};function Zn(){let n=new Jn("site").description("Materialize a publisher's site \u2014 every StaticPage and AggregateView in the workspace gets rendered to its declared output path under the --out directory.");return n.addCommand(Ka()),n}function Ka(){return new Jn("build").description("Walk the workspace, find every StaticPage and AggregateView, and write each materialized artifact to its declared output path under the --out directory.").option("--out <dir>","Output base directory.","./_site").action(async n=>{try{await Da(n)}catch(e){console.error(`Error: ${e.message}`),process.exit(1)}})}async function Da(n){let e=new va,t=new Sa,o=await v(process.cwd(),e),r=await t.parseKanonaks(o),s=$a(n.out);oe(s,{recursive:!0});let a=await o.getAllDocumentsAsync(),i=new Set;for(let m of a){let k=m.metadata.namespace_?.toString();k&&i.add(k)}let c={publisher:E,package_:j,name:"StaticPage"},l={publisher:E,package_:j,name:"ResourcePage"},u={publisher:E,package_:j,name:"AggregateView"},p=re(r,c).filter(m=>i.has(m.namespace||"")),d=re(r,l).filter(m=>i.has(m.namespace||"")),f=re(r,u).filter(m=>i.has(m.namespace||""));console.log(`Found ${p.length} StaticPage(s), ${d.length} ResourcePage(s), and ${f.length} AggregateView(s) in the workspace.`);let g=new Ia;for(let m of p){let k=Le(m,E,j,"outputPath")??`${m.name}.html`,h=Bn(m,qn,Wn,r);if(!h){console.warn(` [skip] ${m.name}: no HTML/default derivation found (check class hierarchy or universal-derivations is loaded)`);continue}let y=Ue(r,h.transformation);if(!y){console.warn(` [skip] ${m.name}: transformation ${Fe(h.transformation)} not found`);continue}let b=await g.run({transformation:y,instances:[m],allKanonaks:r,repository:o,parser:e,objectParser:t,outputFormat:"html"});if(b.length===0){console.warn(` [skip] ${m.name}: transformation produced no artifacts`);continue}let w=Oe(s,k);oe(Ne(w),{recursive:!0}),Ae(w,b[0].content,"utf-8"),console.log(` wrote ${w} (StaticPage ${m.name})`)}for(let m of d){let k=Le(m,E,j,"outputPath")??`${m.name}.html`,h=Gn(m,E,j,"pageOf");if(!h){console.warn(` [skip] ${m.name}: no pageOf declared`);continue}let y=r.find(D=>D instanceof Yn&&D.name===h.name&&(D.namespace||"").startsWith(`${h.publisher}/${h.package_}@`));if(!y){console.warn(` [skip] ${m.name}: pageOf target ${h.publisher}/${h.package_}/${h.name} not found`);continue}let b=Bn(y,qn,Wn,r);if(!b){console.warn(` [skip] ${m.name}: no derivation for target ${y.name}`);continue}let w=Ue(r,b.transformation);if(!w){console.warn(` [skip] ${m.name}: transformation ${Fe(b.transformation)} not found`);continue}let $=await g.run({transformation:w,instances:[y],allKanonaks:r,repository:o,parser:e,objectParser:t,outputFormat:"html"});if($.length===0){console.warn(` [skip] ${m.name}: transformation produced no artifacts`);continue}let _=Oe(s,k);oe(Ne(_),{recursive:!0}),Ae(_,$[0].content,"utf-8"),console.log(` wrote ${_} (ResourcePage ${m.name} \u2192 ${y.name})`)}for(let m of f){let k=Le(m,E,j,"outputPath");if(!k){console.warn(` [skip] ${m.name}: no outputPath declared`);continue}let h=Gn(m,E,j,"scopeClass");if(!h){console.warn(` [skip] ${m.name}: no scopeClass declared`);continue}let y={publisher:h.publisher,package_:h.package_,name:h.name},b=Ta(m,E,j,"scopeSources"),w=Ea(m);if(!w){console.warn(` [skip] ${m.name}: no transformation declared`);continue}let $=Ue(r,w);if(!$){console.warn(` [skip] ${m.name}: transformation ${Fe(w)} not found`);continue}let _=await Aa(b,o),D=[],Xe=new Set;for(let Mt of _){let Vt=await Oa(Mt,o,e,t),Ht=re(Vt,y);for(let be of Ht){let Qe=`${be.namespace}/${be.name}`;Xe.has(Qe)||(Xe.add(Qe),D.push(be))}}console.log(` ${m.name}: ${D.length} instance(s) of ${y.publisher}/${y.package_}/${y.name} across ${_.length} scope(s)`);let Ze=await g.run({transformation:$,instances:D,allKanonaks:r,repository:o,parser:e,objectParser:t,outputFormat:"html"});if(Ze.length===0){console.warn(` [skip] ${m.name}: transformation produced no artifacts`);continue}let ye=Oe(s,k);oe(Ne(ye),{recursive:!0}),Ae(ye,Ze[0].content,"utf-8"),console.log(` wrote ${ye} (AggregateView ${m.name})`)}console.log("Site build complete.")}function Le(n,e,t,o){for(let r of n.statement)if(r instanceof Xn&&ae(r,e,t,o))return r.object}function Ta(n,e,t,o){for(let r of n.statement){if(!(r instanceof _a)||!ae(r,e,t,o))continue;let s=[];for(let a of r.object??[]){let i=a.value;typeof i=="string"&&s.push(i)}return s}return[]}function Gn(n,e,t,o){for(let r of n.statement)if(r instanceof Pa&&ae(r,e,t,o)&&r.object instanceof Ca)return{publisher:r.object.subject.publisher,package_:r.object.subject.package_,name:r.object.subject.name}}function Ea(n){for(let e of n.statement)if(e instanceof Ra&&ae(e,E,j,"transformation"))return ja(e.object)}function ja(n){let e,t,o,r;for(let s of n.statement){if(!(s instanceof Xn))continue;let a=s.predicate?.subject?.name;a==="publisher"?e=s.object:a==="package"?t=s.object:a==="version"?o=s.object:a==="name"&&(r=s.object)}if(!(!e||!t||!o||!r))return{publisher:e,package_:t,version:o,name:r}}function ae(n,e,t,o){let r=n.predicate?.subject;return r?r.publisher===e&&r.package_===t&&r.name===o:!1}function Ue(n,e){let t=`${e.publisher}/${e.package_}@${e.version}`;for(let o of n)if(o instanceof Yn&&o.name===e.name&&o.namespace===t)return o}function Fe(n){return`${n.publisher}/${n.package_}@${n.version}/${n.name}`}async function Aa(n,e){let t=[];for(let o of n){let r=o.indexOf("@*");if(r===-1){t.push(o);continue}let s=o.substring(0,r),a=s.indexOf("/");if(a===-1){t.push(o);continue}let i=s.substring(0,a),c=s.substring(a+1),l=await e.getDocumentsByNamespaceAsync(i,c);for(let u of l){let p=u.metadata.namespace_;if(!p)continue;let d=p.version;t.push(`${p.publisher}/${p.package_}@${d.major}.${d.minor}.${d.patch}`)}}return t}async function Oa(n,e,t,o){let r=n.indexOf("/"),s=n.indexOf("@");if(r===-1||s===-1)return[];let a=n.substring(0,r),i=n.substring(r+1,s),c=n.substring(s+1),l=await e.getDocumentsByNamespaceAsync(a,i);for(let u of l){let p=u.metadata.namespace_?.version;if(p&&`${p.major}.${p.minor}.${p.patch}`===c){let d=new xa(u,e);return o.parseKanonaks(d)}}return[]}import{Command as Na}from"commander";import{createServer as La}from"http";import{watch as Ua}from"fs";import{resolve as Fa,join as Ma}from"path";import{homedir as Va}from"os";import{loadServerModel as Ha,route as za}from"@kanonak-protocol/sdk/server";import{SearchIndex as Ba}from"@kanonak-protocol/sdk/search";import{resolveDisplayValue as qa,subjectUri as Wa}from"@kanonak-protocol/sdk";function Qn(){return new Na("serve").description("Serve a publisher's workspace as a live origin \u2014 the same rendering `kanonak publish` produces, plus the machine-facing publisher endpoints, from one process. Use --watch for a dev preview.").option("--root <dir>","Workspace root to serve.",".").option("--port <number>","Port to listen on.","8080").option("--publisher <domain>","Publisher to serve (required only if the workspace has more than one).").option("--watch","Re-load the workspace on .kan.yml changes.",!1).option("--search","Enable opt-in semantic search at ?q= (builds an embedding index).",!1).action(async n=>{let e=Fa(n.root),t=Number(n.port);if(!Number.isInteger(t)||t<=0||t>65535)throw new Error(`Invalid --port "${n.port}".`);let o,r,s=async a=>{let i=Date.now(),c=await Ha(e,n.publisher?{publisher:n.publisher}:{});if(o=c,n.search){let u=new Ba,p=await u.build(c.catalog,{cacheDir:Ma(Va(),".kanonak","search"),include:d=>c.localNamespaces.has(d.namespace??"")});r=u,console.log(`[search] indexed ${p.size} resource(s)${p.cached?" (from cache)":""}`)}let l=c.availablePublishers.filter(u=>u!==c.publisher);console.log(`[model] serving ${c.publisher} \u2014 ${c.pkgVersions.size} package(s)${a?` (${a})`:""} in ${Date.now()-i}ms`+(l.length?` [also in workspace: ${l.join(", ")} \u2014 switch with --publisher]`:""))};try{await s()}catch(a){console.error(`[error] ${a.message}`),process.exitCode=1;return}if(n.watch){let a;Ua(e,{recursive:!0},(i,c)=>{!c||!String(c).endsWith(".kan.yml")||(clearTimeout(a),a=setTimeout(()=>{s(`changed: ${c}`).catch(l=>console.error("[reload error]",l.message))},150))}),console.log("[watch] re-loading on .kan.yml changes")}La(async(a,i)=>{let c="/";try{let l=new URL(a.url??"/","http://localhost");c=decodeURIComponent(l.pathname);let u=l.searchParams.get("q");if(u&&r){let d=await r.query(u,{scope:Ga(o.publisher,c),limit:30}),f=Ya(o,u,d);i.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),i.end(f),console.log(`200 ${a.method} ${c}?q=${u} (${d.length} hit(s))`);return}let p=za(o,c,a.headers.accept??"");i.writeHead(p.status,p.headers),i.end(p.body),console.log(`${p.status} ${a.method} ${c}${p.headers.Location?` -> ${p.headers.Location}`:""}`)}catch(l){i.writeHead(500,{"Content-Type":"text/plain; charset=utf-8"}),i.end(String(l?.stack??l)),console.error(`500 ${c}: ${l?.message??l}`)}}).listen(t,()=>{console.log(`kanonak origin server \u2192 http://localhost:${t}/ (root=${e})`),n.search&&console.log("[search] enabled \u2014 append ?q=<keywords> at any level")})})}function Ga(n,e){let t=e.split("/").filter(Boolean);if(t.length!==0)return`${n}/${t[0]}@`}function Ja(n,e){let t=Wa(e);if(!t)return"#";let o=t.version?`/${t.version.major}.${t.version.minor}.${t.version.patch}`:"";return t.publisher===n.publisher?`/${t.package_}${o}/${t.name}`:`https://${t.publisher}/${t.package_}${o}/${t.name}`}function W(n){return n.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;")}function Ya(n,e,t){let o=t.map(r=>{let s=qa(n.catalog,r.subject),a=Ja(n,r.subject),i=Math.max(0,Math.min(100,Math.round(r.score*100))),c=s.summary?`<span class="kan-pkg-card-comment">${W(s.summary.slice(0,160))}</span>`:"";return`<a class="kan-pkg-card" href="${W(a)}"><span class="kan-pkg-card-body"><span class="kan-pkg-card-title">${W(s.label)}</span>${c}<span style="display:block;height:5px;border-radius:3px;margin-top:8px;background:var(--kan-accent,#888);width:${i}%"></span><span class="kan-pkg-card-comment">${i}% match</span></span></a>`}).join("");return`<!doctype html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>Search: ${W(e)}</title><link rel="stylesheet" href="/index.css"></head><body><main class="kan-page" style="max-width:960px;margin:0 auto;padding:2rem"><form method="get" style="margin-bottom:1.5rem"><input name="q" value="${W(e)}" placeholder="Search\u2026" style="width:100%;padding:.6rem .8rem;font-size:1rem;box-sizing:border-box"></form><h1>Results for \u201C${W(e)}\u201D</h1><section class="kan-pkg-grid">${o||"<p>No matches.</p>"}</section></main></body></html>`}import{Command as Xa}from"commander";import{resolve as Za,join as Qa}from"path";import{loadLockFile as es,computeIntegrity as Me}from"@kanonak-protocol/sdk";function et(){return new Xa("verify").description("Verify cached packages against kanonak.lock (the cache is untrusted). With --remote, also re-fetch each package from its origin and compare. Exits non-zero on any integrity mismatch.").option("--workspace <dir>","Workspace directory containing kanonak.lock.",process.cwd()).option("--remote","Also re-fetch each package from its recorded origin and verify.",!1).action(async n=>{await ts(n)})}function ns(n){let e=n.indexOf("/");if(!(e<0))return{publisher:n.slice(0,e),package_:n.slice(e+1)}}async function ts(n){let e=Za(n.workspace),t=es(Qa(e,"kanonak.lock"));t||(console.error(`No kanonak.lock found in ${e} \u2014 nothing to verify (run \`kanonak install\` first).`),process.exit(1));let o=new K,r=Object.entries(t.packages);console.log(`Verifying ${r.length} locked package(s) against kanonak.lock${n.remote?" (cache + origin)":" (cache)"}\u2026`);let s=0,a=0,i=0,c=0;for(let[u,p]of r){let d=ns(u);if(!d){console.error(` \u2717 ${u} \u2014 unparseable lock key`),a+=1;continue}let{publisher:f,package_:g}=d,m=o.get(f,g,p.version);if(m===null?(console.warn(` ? ${u} \u2014 not in cache`),i+=1):Me(m)===p.integrity?s+=1:(console.error(` \u2717 ${u} \u2014 CACHE does not match lock`),console.error(` lock: ${p.integrity}`),console.error(` cache: ${Me(m)}`),a+=1),n.remote){let k=await os(u,p);k?(console.error(k),a+=1):c+=1}}let l=[`${s} cache OK`];n.remote&&l.push(`${c} origin OK`),i&&l.push(`${i} not cached`),l.push(`${a} mismatch`),console.log(`
118
- ${l.join(", ")}.`),a>0&&(console.error("Integrity verification FAILED \u2014 a package does not match the committed lock."),process.exit(1)),console.log("Integrity verified.")}async function os(n,e){try{let t=await fetch(e.resolved);if(!t.ok)return` \u2717 ${n} \u2014 origin fetch ${t.status} from ${e.resolved}`;let o=await t.text(),r=Me(o);return r===e.integrity?void 0:` \u2717 ${n} \u2014 ORIGIN does not match lock (${e.resolved})
117
+ `}import{Command as Jn}from"commander";import{writeFileSync as je,mkdirSync as te}from"fs";import{join as Ae,resolve as Cs,dirname as Oe}from"path";import{KanonakParser as Rs,KanonakObjectParser as _s,SubjectKanonak as Yn,ReferenceStatement as xs,ReferenceKanonak as Is,ListStatement as Ks,StringStatement as Xn,EmbeddedStatement as Ts,findDerivation as zn}from"@kanonak-protocol/sdk";import{SingleDocumentRepository as Ds}from"@kanonak-protocol/sdk/uri-helpers";import{TransformationRunnerV3 as Es}from"@kanonak-protocol/sdk/transformations";import{findSubjectsByType as oe}from"@kanonak-protocol/sdk/uri-helpers";var E="kanonak.org",j="site",qn={publisher:"kanonak.org",package_:"formats",name:"html"},Wn={publisher:"kanonak.org",package_:"derivation",name:"default"};function Zn(){let n=new Jn("site").description("Materialize a publisher's site \u2014 every StaticPage and AggregateView in the workspace gets rendered to its declared output path under the --out directory.");return n.addCommand(js()),n}function js(){return new Jn("build").description("Walk the workspace, find every StaticPage and AggregateView, and write each materialized artifact to its declared output path under the --out directory.").option("--out <dir>","Output base directory.","./_site").action(async n=>{try{await As(n)}catch(e){console.error(`Error: ${e.message}`),process.exit(1)}})}async function As(n){let e=new Rs,t=new _s,o=await v(process.cwd(),e),r=await t.parseKanonaks(o),a=Cs(n.out);te(a,{recursive:!0});let s=await o.getAllDocumentsAsync(),i=new Set;for(let m of s){let k=m.metadata.namespace_?.toString();k&&i.add(k)}let c={publisher:E,package_:j,name:"StaticPage"},l={publisher:E,package_:j,name:"ResourcePage"},u={publisher:E,package_:j,name:"AggregateView"},p=oe(r,c).filter(m=>i.has(m.namespace||"")),d=oe(r,l).filter(m=>i.has(m.namespace||"")),f=oe(r,u).filter(m=>i.has(m.namespace||""));console.log(`Found ${p.length} StaticPage(s), ${d.length} ResourcePage(s), and ${f.length} AggregateView(s) in the workspace.`);let g=new Es;for(let m of p){let k=Ne(m,E,j,"outputPath")??`${m.name}.html`,h=zn(m,qn,Wn,r);if(!h){console.warn(` [skip] ${m.name}: no HTML/default derivation found (check class hierarchy or universal-derivations is loaded)`);continue}let y=Le(r,h.transformation);if(!y){console.warn(` [skip] ${m.name}: transformation ${Ue(h.transformation)} not found`);continue}let b=await g.run({transformation:y,instances:[m],allKanonaks:r,repository:o,parser:e,objectParser:t,outputFormat:"html"});if(b.length===0){console.warn(` [skip] ${m.name}: transformation produced no artifacts`);continue}let w=Ae(a,k);te(Oe(w),{recursive:!0}),je(w,b[0].content,"utf-8"),console.log(` wrote ${w} (StaticPage ${m.name})`)}for(let m of d){let k=Ne(m,E,j,"outputPath")??`${m.name}.html`,h=Gn(m,E,j,"pageOf");if(!h){console.warn(` [skip] ${m.name}: no pageOf declared`);continue}let y=r.find(T=>T instanceof Yn&&T.name===h.name&&(T.namespace||"").startsWith(`${h.publisher}/${h.package_}@`));if(!y){console.warn(` [skip] ${m.name}: pageOf target ${h.publisher}/${h.package_}/${h.name} not found`);continue}let b=zn(y,qn,Wn,r);if(!b){console.warn(` [skip] ${m.name}: no derivation for target ${y.name}`);continue}let w=Le(r,b.transformation);if(!w){console.warn(` [skip] ${m.name}: transformation ${Ue(b.transformation)} not found`);continue}let $=await g.run({transformation:w,instances:[y],allKanonaks:r,repository:o,parser:e,objectParser:t,outputFormat:"html"});if($.length===0){console.warn(` [skip] ${m.name}: transformation produced no artifacts`);continue}let R=Ae(a,k);te(Oe(R),{recursive:!0}),je(R,$[0].content,"utf-8"),console.log(` wrote ${R} (ResourcePage ${m.name} \u2192 ${y.name})`)}for(let m of f){let k=Ne(m,E,j,"outputPath");if(!k){console.warn(` [skip] ${m.name}: no outputPath declared`);continue}let h=Gn(m,E,j,"scopeClass");if(!h){console.warn(` [skip] ${m.name}: no scopeClass declared`);continue}let y={publisher:h.publisher,package_:h.package_,name:h.name},b=Os(m,E,j,"scopeSources"),w=Ns(m);if(!w){console.warn(` [skip] ${m.name}: no transformation declared`);continue}let $=Le(r,w);if(!$){console.warn(` [skip] ${m.name}: transformation ${Ue(w)} not found`);continue}let R=await Us(b,o),T=[],Xe=new Set;for(let zt of R){let qt=await Fs(zt,o,e,t),Wt=oe(qt,y);for(let ye of Wt){let Qe=`${ye.namespace}/${ye.name}`;Xe.has(Qe)||(Xe.add(Qe),T.push(ye))}}console.log(` ${m.name}: ${T.length} instance(s) of ${y.publisher}/${y.package_}/${y.name} across ${R.length} scope(s)`);let Ze=await g.run({transformation:$,instances:T,allKanonaks:r,repository:o,parser:e,objectParser:t,outputFormat:"html"});if(Ze.length===0){console.warn(` [skip] ${m.name}: transformation produced no artifacts`);continue}let ke=Ae(a,k);te(Oe(ke),{recursive:!0}),je(ke,Ze[0].content,"utf-8"),console.log(` wrote ${ke} (AggregateView ${m.name})`)}console.log("Site build complete.")}function Ne(n,e,t,o){for(let r of n.statement)if(r instanceof Xn&&re(r,e,t,o))return r.object}function Os(n,e,t,o){for(let r of n.statement){if(!(r instanceof Ks)||!re(r,e,t,o))continue;let a=[];for(let s of r.object??[]){let i=s.value;typeof i=="string"&&a.push(i)}return a}return[]}function Gn(n,e,t,o){for(let r of n.statement)if(r instanceof xs&&re(r,e,t,o)&&r.object instanceof Is)return{publisher:r.object.subject.publisher,package_:r.object.subject.package_,name:r.object.subject.name}}function Ns(n){for(let e of n.statement)if(e instanceof Ts&&re(e,E,j,"transformation"))return Ls(e.object)}function Ls(n){let e,t,o,r;for(let a of n.statement){if(!(a instanceof Xn))continue;let s=a.predicate?.subject?.name;s==="publisher"?e=a.object:s==="package"?t=a.object:s==="version"?o=a.object:s==="name"&&(r=a.object)}if(!(!e||!t||!o||!r))return{publisher:e,package_:t,version:o,name:r}}function re(n,e,t,o){let r=n.predicate?.subject;return r?r.publisher===e&&r.package_===t&&r.name===o:!1}function Le(n,e){let t=`${e.publisher}/${e.package_}@${e.version}`;for(let o of n)if(o instanceof Yn&&o.name===e.name&&o.namespace===t)return o}function Ue(n){return`${n.publisher}/${n.package_}@${n.version}/${n.name}`}async function Us(n,e){let t=[];for(let o of n){let r=o.indexOf("@*");if(r===-1){t.push(o);continue}let a=o.substring(0,r),s=a.indexOf("/");if(s===-1){t.push(o);continue}let i=a.substring(0,s),c=a.substring(s+1),l=await e.getDocumentsByNamespaceAsync(i,c);for(let u of l){let p=u.metadata.namespace_;if(!p)continue;let d=p.version;t.push(`${p.publisher}/${p.package_}@${d.major}.${d.minor}.${d.patch}`)}}return t}async function Fs(n,e,t,o){let r=n.indexOf("/"),a=n.indexOf("@");if(r===-1||a===-1)return[];let s=n.substring(0,r),i=n.substring(r+1,a),c=n.substring(a+1),l=await e.getDocumentsByNamespaceAsync(s,i);for(let u of l){let p=u.metadata.namespace_?.version;if(p&&`${p.major}.${p.minor}.${p.patch}`===c){let d=new Ds(u,e);return o.parseKanonaks(d)}}return[]}import{Command as Ms}from"commander";import{createServer as Qn}from"http";import{watch as et}from"fs";import{resolve as Vs}from"path";import{loadServerModel as nt,route as Hs,RequestRouter as Bs}from"@kanonak-protocol/sdk/server";var Fe={"Access-Control-Allow-Origin":"*"};function tt(n,e){n.writeHead(e.status,{...e.headers,...Fe}),n.end(e.body)}function ot(){return new Ms("serve").description("Serve Kanonak resources as a live origin \u2014 the same rendering `kanonak publish` produces, plus the machine-facing publisher endpoints, from one process. With --publisher it serves that single publisher (closed world, like the published site); without it, it serves any publisher per request path and links across publishers (open world). Use --watch for a dev preview.").option("--root <dir>","Workspace root to serve.",".").option("--port <number>","Port to listen on.","8080").option("--publisher <domain>","Serve ONLY this publisher (closed world \u2014 no links to other publishers, mirroring the published site). Omit for the open-world model.").option("--watch","Re-load on .kan.yml changes.",!1).action(async n=>{let e=Vs(n.root),t=Number(n.port);if(!Number.isInteger(t)||t<=0||t>65535)throw new Error(`Invalid --port "${n.port}".`);if(n.publisher){let o;try{o=await nt(e,{publisher:n.publisher})}catch(r){console.error(`[error] ${r.message}`),process.exitCode=1;return}zs(e,t,n,o)}else qs(e,t,n)})}function zs(n,e,t,o){let r=o,a=async s=>{let i=Date.now();r=await nt(n,t.publisher?{publisher:t.publisher}:{});let c=r.availablePublishers.filter(l=>l!==r.publisher);console.log(`[model] serving ${r.publisher} \u2014 ${r.pkgVersions.size} package(s)${s?` (${s})`:""} in ${Date.now()-i}ms`+(c.length?` [also in workspace: ${c.join(", ")} \u2014 switch with --publisher]`:""))};if(t.watch){let s;et(n,{recursive:!0},(i,c)=>{!c||!String(c).endsWith(".kan.yml")||(clearTimeout(s),s=setTimeout(()=>{a(`changed: ${c}`).catch(l=>console.error("[reload error]",l.message))},150))}),console.log("[watch] re-loading on .kan.yml changes")}Qn((s,i)=>{let c="/";try{let l=new URL(s.url??"/","http://localhost");c=decodeURIComponent(l.pathname);let u=Hs(r,c,s.headers.accept??"");tt(i,u),console.log(`${u.status} ${s.method} ${c}${u.headers.Location?` -> ${u.headers.Location}`:""}`)}catch(l){i.writeHead(500,{"Content-Type":"text/plain; charset=utf-8",...Fe}),i.end(String(l?.stack??l)),console.error(`500 ${c}: ${l?.message??l}`)}}).listen(e,()=>{console.log(`kanonak origin server \u2192 http://localhost:${e}/ (root=${n}, publisher=${r.publisher})`)})}function qs(n,e,t){let o=new Bs({root:n});if(t.watch){let r;et(n,{recursive:!0},(a,s)=>{!s||!String(s).endsWith(".kan.yml")||(clearTimeout(r),r=setTimeout(()=>{o.clearCache(),console.log("[watch] cleared model cache")},150))}),console.log("[watch] clearing model cache on .kan.yml changes")}Qn(async(r,a)=>{let s="/";try{let i=new URL(r.url??"/","http://localhost");s=decodeURIComponent(i.pathname);let c=await o.handle(s,r.headers.accept??"");tt(a,c),console.log(`${c.status} ${r.method} ${s}${c.headers.Location?` -> ${c.headers.Location}`:""}`)}catch(i){a.writeHead(502,{"Content-Type":"text/plain; charset=utf-8",...Fe}),a.end(String(i?.message??i)),console.error(`502 ${s}: ${i?.message??i}`)}}).listen(e,()=>{console.log(`kanonak request-driven origin \u2192 http://localhost:${e}/ (root=${n})`),console.log("[request-driven] no publisher pinned \u2014 derive per path: /{publisher}/{package}/{version}/{resource}")})}import{Command as Ws}from"commander";import{resolve as Gs,join as Js}from"path";import{loadLockFile as Ys,computeIntegrity as Me}from"@kanonak-protocol/sdk";function rt(){return new Ws("verify").description("Verify cached packages against kanonak.lock (the cache is untrusted). With --remote, also re-fetch each package from its origin and compare. Exits non-zero on any integrity mismatch.").option("--workspace <dir>","Workspace directory containing kanonak.lock.",process.cwd()).option("--remote","Also re-fetch each package from its recorded origin and verify.",!1).action(async n=>{await Zs(n)})}function Xs(n){let e=n.indexOf("/");if(!(e<0))return{publisher:n.slice(0,e),package_:n.slice(e+1)}}async function Zs(n){let e=Gs(n.workspace),t=Ys(Js(e,"kanonak.lock"));t||(console.error(`No kanonak.lock found in ${e} \u2014 nothing to verify (run \`kanonak install\` first).`),process.exit(1));let o=new K,r=Object.entries(t.packages);console.log(`Verifying ${r.length} locked package(s) against kanonak.lock${n.remote?" (cache + origin)":" (cache)"}\u2026`);let a=0,s=0,i=0,c=0;for(let[u,p]of r){let d=Xs(u);if(!d){console.error(` \u2717 ${u} \u2014 unparseable lock key`),s+=1;continue}let{publisher:f,package_:g}=d,m=o.get(f,g,p.version);if(m===null?(console.warn(` ? ${u} \u2014 not in cache`),i+=1):Me(m)===p.integrity?a+=1:(console.error(` \u2717 ${u} \u2014 CACHE does not match lock`),console.error(` lock: ${p.integrity}`),console.error(` cache: ${Me(m)}`),s+=1),n.remote){let k=await Qs(u,p);k?(console.error(k),s+=1):c+=1}}let l=[`${a} cache OK`];n.remote&&l.push(`${c} origin OK`),i&&l.push(`${i} not cached`),l.push(`${s} mismatch`),console.log(`
118
+ ${l.join(", ")}.`),s>0&&(console.error("Integrity verification FAILED \u2014 a package does not match the committed lock."),process.exit(1)),console.log("Integrity verified.")}async function Qs(n,e){try{let t=await fetch(e.resolved);if(!t.ok)return` \u2717 ${n} \u2014 origin fetch ${t.status} from ${e.resolved}`;let o=await t.text(),r=Me(o);return r===e.integrity?void 0:` \u2717 ${n} \u2014 ORIGIN does not match lock (${e.resolved})
119
119
  lock: ${e.integrity}
120
- origin: ${r}`}catch(t){return` \u2717 ${n} \u2014 origin fetch failed: ${t.message}`}}import{Command as rs}from"commander";import{resolve as as,join as ss}from"path";import{homedir as is}from"os";import{readFileSync as cs}from"fs";import{KanonakParser as nt,KanonakObjectParser as ls,PublisherIndex as tt,CredentialStore as ot,createAuthenticatedFetch as rt,FileSystemKanonakDocumentRepository as us,Reasoner as ps,KanonakVocabulary as ds,getGlobalCachePath as ms,makeUriKey as fs,resolveDisplayValue as gs,subjectUri as hs,contextTypesOf as ks,collectKanonakFiles as ys}from"@kanonak-protocol/sdk";import{SearchIndex as bs}from"@kanonak-protocol/sdk/search";function ws(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 at(){return new rs("search").description("Semantic-search your workspace (-q), browse a publisher's catalogue, or find instances of a class").argument("[publisher]","Publisher domain (e.g. kanonak.org) \u2014 for the catalogue / --type modes").option("-q, --query <text>","Semantically search the LOCAL workspace for resources matching free-text keywords").option("--root <dir>","Workspace root for -q",".").option("--scope <prefix>","Limit -q to namespaces starting with this prefix (e.g. kanonak.org/look@)").option("--limit <n>","Max results for -q","20").option("--format <fmt>","Output for -q: text | json","text").option("--all","For -q: index imported packages too (default: only your workspace's own resources)",!1).option("--type <uri>","Class URI to search for, in publisher/package/Name form").action(async(n,e)=>{if(e.query){await $s(e);return}n||(console.error(`Nothing to search. Either:
120
+ origin: ${r}`}catch(t){return` \u2717 ${n} \u2014 origin fetch failed: ${t.message}`}}import{Command as ea}from"commander";import{resolve as na,join as ta}from"path";import{homedir as oa}from"os";import{readFileSync as ra}from"fs";import{KanonakParser as st,KanonakObjectParser as sa,PublisherIndex as at,CredentialStore as it,createAuthenticatedFetch as ct,FileSystemKanonakDocumentRepository as aa,Reasoner as ia,KanonakVocabulary as ca,getGlobalCachePath as la,makeUriKey as ua,resolveDisplayValue as pa,subjectUri as da,contextTypesOf as ma,collectKanonakFiles as fa}from"@kanonak-protocol/sdk";import{SearchIndex as ga}from"@kanonak-protocol/sdk/search";function ha(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 lt(){return new ea("search").description("Semantic-search your workspace (-q), browse a publisher's catalogue, or find instances of a class").argument("[publisher]","Publisher domain (e.g. kanonak.org) \u2014 for the catalogue / --type modes").option("-q, --query <text>","Semantically search the LOCAL workspace for resources matching free-text keywords").option("--root <dir>","Workspace root for -q",".").option("--scope <prefix>","Limit -q to namespaces starting with this prefix (e.g. kanonak.org/look@)").option("--limit <n>","Max results for -q","20").option("--format <fmt>","Output for -q: text | json","text").option("--all","For -q: index imported packages too (default: only your workspace's own resources)",!1).option("--type <uri>","Class URI to search for, in publisher/package/Name form").action(async(n,e)=>{if(e.query){await ka(e);return}n||(console.error(`Nothing to search. Either:
121
121
  \u2022 semantic-search your workspace: kanonak search -q "<keywords>"
122
122
  \u2022 browse a publisher's catalogue: kanonak search <publisher>
123
- \u2022 find instances of a class: kanonak search <publisher> --type <pub>/<pkg>/<Name>`),process.exit(1)),e.type?await Ss(n,e.type):await vs(n)})}async function $s(n){let e=as(n.root??"."),t=new nt,o;try{let u=await v(e,t);o=await new ls().parseKanonaks(u)}catch(u){console.error(`Failed to load workspace at ${e}: ${u.message}`),process.exit(1)}let r={cacheDir:ss(is(),".kanonak","search"),onProgress:(u,p)=>process.stderr.write(`\r embedding ${u}/${p}\u2026 `)};if(!n.all){let u=new Set;for(let p of ys(e))try{let d=t.parse(cs(p,"utf-8")).metadata?.namespace_;d?.version&&u.add(`${d.publisher}/${d.package_}@${d.version.major}.${d.version.minor}.${d.version.patch}`)}catch{}r.include=p=>u.has(p.namespace??"")}let s=new bs,a;try{a=await s.build(o,r),a.size>0&&!a.cached&&process.stderr.write(`
124
- `)}catch(u){console.error(u.message),process.exit(1)}a.size===0&&(console.error(n.all?`No resources found in the workspace at ${e}.`:`No resources defined in the workspace at ${e}. (It imports packages but defines none of its own \u2014 use --all to also search imported packages.)`),process.exit(1));let i=Number(n.limit)||20,l=(await s.query(n.query,{scope:n.scope,limit:i})).map(u=>{let p=gs(o,u.subject),d=hs(u.subject),f=ks(u.subject)[0]?.name;return{uri:d?`${d.publisher}/${d.package_}/${d.name}`:u.subject.name,label:p.label,type:f??null,score:Number(u.score.toFixed(4))}});if(n.format==="json"){console.log(JSON.stringify(l,null,2));return}if(l.length===0){console.log(`No matches for "${n.query}".`);return}console.log(`Results for "${n.query}":
125
- `);for(let u of l)console.log(` ${u.score.toFixed(3)} ${u.label}${u.type?` (${u.type})`:""}`),console.log(` ${u.uri}`)}async function vs(n){let e=new ot,t=rt(e),o=new tt({fetchFn:t}),r;try{r=await o.listLatestPackages(n)}catch(a){console.error(`Failed to fetch publisher index for ${n}: ${a.message}`),process.exit(1)}if(r.length===0){console.log(`No packages found at ${n}.`);return}console.log(`Packages published by ${n}:
126
- `);let s=r.reduce((a,i)=>Math.max(a,i.packageName.length),0);for(let{packageName:a,version:i}of r)console.log(` ${a.padEnd(s)} @${i}`)}async function Ss(n,e){let t=ws(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 nt,r=new ot,s=rt(r),a=new tt({fetchFn:s}),i=new K,c=new Set,l=[];try{l=await a.listLatestPackages(n)}catch(k){console.error(`Failed to fetch publisher index for ${n}: ${k.message}`),process.exit(1)}for(let{packageName:k,version:h}of l)c.add(`${n}|${k}|${h}`);await Ve(a,i,s,"kanonak.org","core-rdf",c),await Ve(a,i,s,"kanonak.org","core-owl",c),await Ve(a,i,s,t.publisher,t.package_,c);for(let k of c){let[h,y,b]=k.split("|");if(!i.has(h,y,b))try{let w=await a.getPackageUrl(h,y,b),$=await s(w,h);if(!$.ok){console.error(`Warning: failed to fetch ${h}/${y}@${b}: ${$.status} ${$.statusText}`);continue}let _=await $.text();i.put(h,y,b,_)}catch(w){console.error(`Warning: failed to fetch ${h}/${y}@${b}: ${w.message}`)}}let u=new us(ms(),!0,o),d=await new ps({vocabulary:new ds}).reason(u),f=fs(t.publisher,t.package_,t.name),m=d.getInstancesOfClass(f).filter(k=>k!==f);if(m.length===0){console.log(`No instances of ${f} found in ${n}'s catalogue.`);return}console.log(`Instances of ${f} in ${n}'s catalogue:
127
- `),m.sort();for(let k of m)console.log(` ${k}`)}async function Ve(n,e,t,o,r,s){try{let a=await n.getHighestVersion(o,r);if(!a)return;s.add(`${o}|${r}|${a}`)}catch{}}import{existsSync as Ps,readFileSync as Cs}from"fs";import{dirname as _s,resolve as Rs}from"path";import{KanonakObjectParser as xs,KanonakParser as Is,canonicalForm as Ks,canonicalHash as Ds,parseKanonakAddress as Ts,pickHighestDocument as Es}from"@kanonak-protocol/sdk";import{SingleDocumentRepository as js}from"@kanonak-protocol/sdk/uri-helpers";async function st(n,e={}){let t=new Is,o=new xs,{document:r,source:s}=await As(n,t),a=await v(Os(s),t),i=new js(r,a),c=await o.parseKanonaks(i),l=Ds(c);if(console.log(l),e.verbose){let u=Ks(c);process.stderr.write(`# canonical form for ${s}
123
+ \u2022 find instances of a class: kanonak search <publisher> --type <pub>/<pkg>/<Name>`),process.exit(1)),e.type?await ba(n,e.type):await ya(n)})}async function ka(n){let e=na(n.root??"."),t=new st,o;try{let u=await v(e,t);o=await new sa().parseKanonaks(u)}catch(u){console.error(`Failed to load workspace at ${e}: ${u.message}`),process.exit(1)}let r={cacheDir:ta(oa(),".kanonak","search"),onProgress:(u,p)=>process.stderr.write(`\r embedding ${u}/${p}\u2026 `)};if(!n.all){let u=new Set;for(let p of fa(e))try{let d=t.parse(ra(p,"utf-8")).metadata?.namespace_;d?.version&&u.add(`${d.publisher}/${d.package_}@${d.version.major}.${d.version.minor}.${d.version.patch}`)}catch{}r.include=p=>u.has(p.namespace??"")}let a=new ga,s;try{s=await a.build(o,r),s.size>0&&!s.cached&&process.stderr.write(`
124
+ `)}catch(u){console.error(u.message),process.exit(1)}s.size===0&&(console.error(n.all?`No resources found in the workspace at ${e}.`:`No resources defined in the workspace at ${e}. (It imports packages but defines none of its own \u2014 use --all to also search imported packages.)`),process.exit(1));let i=Number(n.limit)||20,l=(await a.query(n.query,{scope:n.scope,limit:i})).map(u=>{let p=pa(o,u.subject),d=da(u.subject),f=ma(u.subject)[0]?.name;return{uri:d?`${d.publisher}/${d.package_}/${d.name}`:u.subject.name,label:p.label,type:f??null,score:Number(u.score.toFixed(4))}});if(n.format==="json"){console.log(JSON.stringify(l,null,2));return}if(l.length===0){console.log(`No matches for "${n.query}".`);return}console.log(`Results for "${n.query}":
125
+ `);for(let u of l)console.log(` ${u.score.toFixed(3)} ${u.label}${u.type?` (${u.type})`:""}`),console.log(` ${u.uri}`)}async function ya(n){let e=new it,t=ct(e),o=new at({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}:
126
+ `);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 ba(n,e){let t=ha(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 st,r=new it,a=ct(r),s=new at({fetchFn:a}),i=new K,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:h}of l)c.add(`${n}|${k}|${h}`);await Ve(s,i,a,"kanonak.org","core-rdf",c),await Ve(s,i,a,"kanonak.org","core-owl",c),await Ve(s,i,a,t.publisher,t.package_,c);for(let k of c){let[h,y,b]=k.split("|");if(!i.has(h,y,b))try{let w=await s.getPackageUrl(h,y,b),$=await a(w,h);if(!$.ok){console.error(`Warning: failed to fetch ${h}/${y}@${b}: ${$.status} ${$.statusText}`);continue}let R=await $.text();i.put(h,y,b,R)}catch(w){console.error(`Warning: failed to fetch ${h}/${y}@${b}: ${w.message}`)}}let u=new aa(la(),!0,o),d=await new ia({vocabulary:new ca}).reason(u),f=ua(t.publisher,t.package_,t.name),m=d.getInstancesOfClass(f).filter(k=>k!==f);if(m.length===0){console.log(`No instances of ${f} found in ${n}'s catalogue.`);return}console.log(`Instances of ${f} in ${n}'s catalogue:
127
+ `),m.sort();for(let k of m)console.log(` ${k}`)}async function Ve(n,e,t,o,r,a){try{let s=await n.getHighestVersion(o,r);if(!s)return;a.add(`${o}|${r}|${s}`)}catch{}}import{existsSync as wa,readFileSync as $a}from"fs";import{dirname as va,resolve as Sa}from"path";import{KanonakObjectParser as Pa,KanonakParser as Ca,canonicalForm as Ra,canonicalHash as _a,parseKanonakAddress as xa,pickHighestDocument as Ia}from"@kanonak-protocol/sdk";import{SingleDocumentRepository as Ka}from"@kanonak-protocol/sdk/uri-helpers";async function ut(n,e={}){let t=new Ca,o=new Pa,{document:r,source:a}=await Ta(n,t),s=await v(Da(a),t),i=new Ka(r,s),c=await o.parseKanonaks(i),l=_a(c);if(console.log(l),e.verbose){let u=Ra(c);process.stderr.write(`# canonical form for ${a}
128
128
  `),process.stderr.write(u),process.stderr.write(`
129
- `)}}async function As(n,e){if(n.endsWith(".kan.yml")){let i=Rs(n);if(!Ps(i))throw new Error(`kanonak hash: file not found: ${i}`);let c=Cs(i,"utf-8");return{document:e.parse(c),source:i}}let t=Ts(n);if(t.kind!=="package")throw new Error(`kanonak hash: expected a package address (publisher/package[@version]) or a path ending in .kan.yml; got ${t.kind} address "${n}"`);let r=await(await v(process.cwd(),e)).getDocumentsByNamespaceAsync(t.publisher,t.package_);if(r.length===0)throw new Error(`kanonak hash: could not find ${n} in local workspace, global cache, or publisher HTTP`);let s=t.version?`${t.version.major}.${t.version.minor}.${t.version.patch}`:void 0,a=Es(r,s?{requestedVersion:s}:{});if(!a.chosen){let i=s?`@${s}`:"";throw new Error(`kanonak hash: no version of ${t.publisher}/${t.package_}${i} available across local/cache/HTTP`)}return{document:a.chosen,source:n}}function Os(n){return n.endsWith(".kan.yml")?N(_s(n)):process.cwd()}import{Command as it}from"commander";function G(n){return`${P}/${C}/${n}`}var He={[G("fetch-and-deploy")]:(n,e,t,o)=>n.add(e,t[0],o),[G("remove-deployed")]:(n,e,t,o)=>n.remove(e,t[0],o),[G("list-deployed")]:(n,e,t,o)=>n.list(e,o),[G("update-deployed")]:(n,e,t,o)=>n.update(e,t[0],o),[G("search-available")]:(n,e,t,o)=>n.search(e,o),[G("show-info")]:(n,e,t,o)=>n.info(e,t[0],o)};function ct(n,e,t){for(let o of e){let r=new it(o.commandName).description(o.description.trim());for(let s of o.commands){let a=r.command(Ns(s));a.description(s.description);for(let i of s.arguments)if(i.isOption){let c=i.defaultValue!=null?`--${i.argumentName} [value]`:`--${i.argumentName} <value>`;a.option(c,"",i.defaultValue)}a.action(async(...i)=>{let c=Ls(i);await Us(t,o,s,i,c)})}n.addCommand(r)}}function Ns(n){let e=n.arguments.filter(t=>!t.isOption).map(t=>t.required?`<${t.argumentName}>`:`[${t.argumentName}]`);return[n.subcommandName,...e].join(" ")}function Ls(n){for(let e=n.length-1;e>=0;e--)if(n[e]&&typeof n[e]=="object"&&!(n[e]instanceof it))return n[e];return{}}async function Us(n,e,t,o,r){let s=[];for(let i of o)if(typeof i=="string")s.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(He).join(", ")}.`),process.exit(1));let a=He[t.actionKey];a||(console.error(`Capability subcommand '${t.subcommandName}' references unknown Action '${t.actionKey}'. Known actions: ${Object.keys(He).join(", ")}.`),process.exit(1)),await a(n,e,s,r)}import{existsSync as lt,readFileSync as Fs,statSync as ut}from"fs";import{resolve as Ms}from"path";import{KanonakObjectParser as Vs,PublisherIndex as ze,PublisherConfigResolver as Hs,formatVersion as pt,pickHighestDocument as zs}from"@kanonak-protocol/sdk";import{SingleDocumentRepository as dt}from"@kanonak-protocol/sdk/uri-helpers";import{uriKey as J,findSubjectsByType as mt}from"@kanonak-protocol/sdk/uri-helpers";var se=class{constructor(e,t,o,r,s,a){this.fileCache=e;this.parser=t;this.publisherIndex=o;this.fetchFn=r;this.handlerRegistry=s;this.repository=a}fileCache;parser;publisherIndex;fetchFn;handlerRegistry;repository;objectParser=new Vs;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 s=T(t);s||(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:a,packageName:i,version:c,instanceName:l}=s,u=await this.repository.getDocumentsByNamespaceAsync(a,i);if(u.length>0){let f=zs(u,{requestedVersion:c??void 0});if(f.chosen){let g=f.chosen.metadata.namespace_;(!g||!g.version)&&(console.error(`Document for ${a}/${i} is missing namespace metadata.`),process.exit(1));let m=pt(g.version);this.fileCache.put(a,i,m,this.parser.save(f.chosen)),await this.deployFromDoc(e,f.chosen,a,i,m,l??void 0,`${a}/${i}@${m}`,o);return}}let p=c??await this.publisherIndex.getHighestVersion(a,i);p||(console.error(`Could not resolve version for "${a}/${i}".`),await this.printPackageSuggestions(a,i,e.commandName),process.exit(1));let d=this.fileCache.get(a,i,p);if(!d){let f=await this.publisherIndex.getPackageUrl(a,i,p),g=await this.fetchFn(f,a);g.ok||(g.status===404?(console.error(`Package ${a}/${i}@${p} not found at ${f}.`),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 ${f} (${g.status} ${g.statusText}).`),process.exit(1)),d=await g.text(),this.fileCache.put(a,i,p,d)}await this.deployFromDoc(e,this.parser.parse(d),a,i,p,l??void 0,`${a}/${i}@${p}`,o)}tryLoadFromLocalFile(e){if(!(/^[.\/\\]/.test(e)||/^[A-Za-z]:[\\/]/.test(e)||e.endsWith(".kan.yml")||lt(e)&&ut(e).isFile()))return;let o=Ms(e);(!lt(o)||!ut(o).isFile())&&(console.error(`Local file not found: ${e}`),process.exit(1));let r=Fs(o,"utf-8"),s=this.parser.parse(r),a=s.metadata.namespace_;return(!a||!a.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:s,content:r,publisher:a.publisher,packageName:a.package_,version:pt(a.version)}}async deployFromDoc(e,t,o,r,s,a,i,c){let l=new dt(t,this.repository),u=await this.objectParser.parseKanonaks(l),p=ft(e.managesTypeKey);p||(console.error(`Capability "${e.commandName}" has no resolved managesType.`),process.exit(1));let d=mt(u,p);d.length===0&&(console.error(`${i} does not contain any ${J(p)} instances.`),process.exit(1));let f=d;if(a&&(f=d.filter(k=>k.name===a),f.length===0)){console.error(`Instance "${a}" not found in ${i}.`),console.error(""),console.error(`Available ${J(p)} instance(s):`);for(let k of d)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 g=a?`${a} from ${i}`:`${f.length} ${J(p)} instance(s) from ${i}`;console.log(`Installing ${g}...`);let m=this.handlerRegistry.get(e.deploymentTargetKey);m?await m.deploy({instances:f,allKanonaks:u,repository:this.repository,options:c}):console.log(`Cached ${o}/${r}@${s} (no deployment handler for "${e.deploymentTargetKey}")`)}async printPackageSuggestions(e,t,o){let r;try{r=await this.publisherIndex.listLatestPackages(e)}catch{return}let s=r.map(a=>({name:a.packageName,version:a.version,score:Bs(t,a.packageName)})).filter(a=>a.score>0).sort((a,i)=>i.score-a.score).slice(0,5);if(s.length!==0){console.error(""),console.error("Did you mean one of:");for(let a of s)console.error(` kanonak ${o} add ${e}/${a.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}),s=e.managesTypeKey||"managed";if(r.length===0){console.log(`No ${s} instances installed.`);return}console.log(`Installed ${s} instances:
130
- `);for(let a of r){let i=a.publisher?`${a.publisher}/${a.package_}@${a.version}`:"unmanaged";console.log(` ${a.name} (${i}) ${a.path}`)}}async update(e,t,o){let s=await this.requireHandler(e).list({repository:this.repository,options:o}),a=t?s.filter(c=>c.name===t):s.filter(c=>c.publisher);if(a.length===0){console.log(t?`"${t}" not found.`:"No managed instances to update.");return}let i=0;for(let c of a){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.":`
131
- Updated ${i} instance(s).`)}async search(e,t){let o=t.publisher??"kanonak.org",r=ft(e.managesTypeKey);if(!r){console.error("Capability has no resolved managesType; nothing to search for.");return}console.log(`Searching ${o} for ${J(r)} instances...
132
- `);let s=new Hs,a=await s.getConfig(o),i=s.resolveIndexUrl(o,a),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=ze.parseIndex(l);if(u.size===0){console.error(`No packages found for publisher "${o}".`);return}let p=new Map;for(let[m,k]of u){let h=[...k].sort((y,b)=>{let w=ze.parseVersion(y),$=ze.parseVersion(b);return!w||!$?0:w.major!==$.major?$.major-w.major:w.minor!==$.minor?$.minor-w.minor:$.patch-w.patch});p.set(m,h[0])}let d=[],f=0;for(let[m,k]of p){let h=this.fileCache.get(o,m,k);if(!h)try{let y=await this.publisherIndex.getPackageUrl(o,m,k),b=await this.fetchFn(y,o);if(!b.ok)continue;h=await b.text(),this.fileCache.put(o,m,k,h)}catch{continue}try{let y=this.parser.parse(h),b=new dt(y,this.repository),w=await this.objectParser.parseKanonaks(b),$=mt(w,r);for(let _ of $)d.push({publisher:o,package_:m,version:k,subject:_});f++}catch{continue}}if(d.length===0){console.log(`No ${J(r)} instances found across ${f} package(s).`);return}console.log(`Found ${d.length} ${J(r)} instance(s) in ${f} package(s):
133
- `);let g=new Map;for(let m of d){let k=`${m.publisher}/${m.package_}@${m.version}`,h=g.get(k);h?h.push(m):g.set(k,[m])}for(let[m,k]of g){let h=k[0],y=`${h.publisher}/${h.package_}`,b=k.length===1;console.log(` ${m}`),console.log(` ${k.length} skill${b?"":"s"}:`);for(let w of k)console.log(` - ${w.subject.name}`);if(console.log(""),b)console.log(" install:"),console.log(` kanonak ${e.commandName} add ${y}/${h.subject.name}`);else{console.log(" install one of them:");for(let w of k)console.log(` kanonak ${e.commandName} add ${y}/${w.subject.name}`);console.log(" install all of them:"),console.log(` kanonak ${e.commandName} add ${y}`)}console.log("")}}async info(e,t,o){let a=(await this.requireHandler(e).list({repository:this.repository,options:o})).find(i=>i.name===t);a||(console.error(`"${t}" is not installed.`),process.exit(1)),console.log(`Name: ${a.name}`),console.log(`Type: ${e.managesTypeKey||"n/a"}`),console.log(`Publisher: ${a.publisher||"unmanaged"}`),console.log(`Package: ${a.package_||"n/a"}`),console.log(`Version: ${a.version||"n/a"}`),console.log(`Path: ${a.path}`)}requireHandler(e){let 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 ft(n){if(!n)return;let e=n.split("/");if(e.length===3)return{publisher:e[0],package_:e[1],name:e[2]}}function Bs(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)),s=new Set(o.split("-").filter(Boolean)),a=0;for(let c of r)s.has(c)&&a++;if(a>0)return a*10;let i=qs(t,o);return i===0?100:i<=2?Math.max(1,20-i*5):0}function qs(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 s=0;s<e.length;s++){let a=n[r]===e[s]?0:1;o[s+1]=Math.min(o[s]+1,t[s+1]+1,t[s]+a)}for(let s=0;s<=e.length;s++)t[s]=o[s]}return t[e.length]}var ie=class{handlers=new Map;register(e,t){this.handlers.set(e,t)}get(e){return this.handlers.get(e)??null}};import{mkdirSync as ri,rmSync as ai,existsSync as pe,readdirSync as si,writeFileSync as ii}from"fs";import{join as de}from"path";import{KanonakObjectParser as ci,KanonakParser as li,computeIntegrity as ui,compareVersions as pi}from"@kanonak-protocol/sdk";import{findSubjectsByType as di}from"@kanonak-protocol/sdk/uri-helpers";import{SingleDocumentRepository as mi}from"@kanonak-protocol/sdk/uri-helpers";import{TransformationRunnerV3 as fi}from"@kanonak-protocol/sdk/transformations";import{TX_V3 as gi}from"@kanonak-protocol/sdk/transformations";import{join as Be}from"path";import{homedir as gt}from"os";import{KanonakObjectParser as Ws}from"@kanonak-protocol/sdk";import{SingleDocumentRepository as Gs}from"@kanonak-protocol/sdk/uri-helpers";import{findSubjectsByType as kt,getStringValue as ce}from"@kanonak-protocol/sdk/uri-helpers";var U="kanonak.org",F="agent-skills",yt={publisher:U,package_:F,name:"Client"},bt={publisher:U,package_:F,name:"clientId"},Js={publisher:U,package_:F,name:"projectSkillDir"},Ys={publisher:U,package_:F,name:"userSkillDir"},Xs={publisher:U,package_:F,name:"skillFileName"},wt="agents";async function ee(n,e){let t=(n.client??$t()??wt).toLowerCase(),o=n.scope??"project",r=await St(t,e);if(!r){let i=await Zs(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 a=ce(r,o==="user"?Ys:Js);if(!a)throw new Error(`Client "${t}" has no ${o==="user"?"userSkillDir":"projectSkillDir"} declared.`);return Qs(a)}async function le(n,e,t){let o=await ee(e,t);return Be(o,n)}async function qe(n,e){let t=(n.client??$t()??wt).toLowerCase(),o=await St(t,e);return o?ce(o,Xs)??"SKILL.md":"SKILL.md"}function $t(){if(process.env.CLAUDE_CODE||process.env.CLAUDE_PROJECT_DIR)return"claude-code"}var ht=new WeakMap;async function vt(n){let e=ht.get(n);if(e)return e;let t=await n.getDocumentsByNamespaceAsync(U,F);if(t.length===0)throw new Error(`Could not find ${U}/${F} in the repository. Install a skill capability (which transitively imports agent-skills) or fetch agent-skills directly to populate the cache.`);let r=[...t].sort((c,l)=>{let u=c.metadata.namespace_?.version,p=l.metadata.namespace_?.version;return!u||!p?0:u.major!==p.major?p.major-u.major:u.minor!==p.minor?p.minor-u.minor:p.patch-u.patch})[0],s=new Ws,a=new Gs(r,n),i=await s.parseKanonaks(a);return ht.set(n,i),i}async function St(n,e){let t=await vt(e),o=kt(t,yt);for(let r of o)if(ce(r,bt)===n)return r}async function Zs(n){let e=await vt(n),t=kt(e,yt),o=[];for(let r of t){let s=ce(r,bt);s&&o.push(s)}return o}function Qs(n){return n.startsWith("~/")?Be(gt(),n.slice(2)):n==="~"?gt():n.startsWith("/")||/^[A-Za-z]:[\\/]/.test(n)?n:Be(process.cwd(),n)}import{readFileSync as ei,writeFileSync as ni,existsSync as ti}from"fs";import{join as Pt}from"path";import Ct from"js-yaml";var _t="skills.lock",oi=`# This file is generated by Kanonak CLI. Do not edit manually.
134
- `;function ue(n){let e=Pt(n,_t);if(!ti(e))return{version:"1",lastUpdated:new Date().toISOString(),skills:{}};let t=ei(e,"utf-8"),o=Ct.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 We(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=Pt(n,_t),r=Ct.dump(e,{lineWidth:-1,sortKeys:!1,quotingType:'"'});ni(o,oi+r,"utf-8")}var Rt="kanonak.org",xt="skill-to-skill-md",me=class{parser=new li;objectParser=new ci;runner=new fi;async deploy(e){let{instances:t,allKanonaks:o,repository:r,options:s}=e;if(t.length===0){console.error("No Skill instances to deploy.");return}let a=await hi(r,this.objectParser);if(!a){console.error(`Cannot deploy: ${Rt}/${xt}@3.0.0 is not installed in the workspace or cache.`);return}let i=await this.runner.run({transformation:a,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 ee(s,r),l=await qe(s,r),u=ue(c),p=t[0].namespace,{publisher:d,package_:f,version:g}=ki(p);for(let m of i){let k=await le(m.fileName,s,r),h=pe(de(k,l));ri(k,{recursive:!0}),ii(de(k,l),m.content,"utf-8"),u.skills[m.fileName]={publisher:d,package_:f,version:g,resolved:d?`kanonak://${d}/${f}@${g}`:"",integrity:ui(m.content)},console.log(` ${h?"Updated":"Installed"} skill "${m.fileName}" \u2192 ${k}`)}We(c,u)}async undeploy(e,t){let{repository:o,options:r}=t,s=await le(e,r,o);pe(s)||(console.error(`Skill "${e}" is not installed at ${s}`),process.exit(1)),ai(s,{recursive:!0,force:!0});let a=await ee(r,o),i=ue(a);delete i.skills[e],We(a,i),console.log(`Removed skill "${e}" from ${s}`)}async list(e){let{repository:t,options:o}=e,r=await ee(o,t),s=ue(r),a=[];for(let[c,l]of Object.entries(s.skills))a.push({name:c,publisher:l.publisher,package_:l.package_,version:l.version,path:await le(c,o,t)});let i=await qe(o,t);if(pe(r))try{let c=si(r,{withFileTypes:!0});for(let l of c){if(!l.isDirectory()||s.skills[l.name])continue;let u=de(r,l.name,i);pe(u)&&a.push({name:l.name,publisher:"",package_:"",version:"",path:de(r,l.name)})}}catch{}return a}};async function hi(n,e){let t=await n.getDocumentsByNamespaceAsync(Rt,xt);if(t.length===0)return;let o=[...t].sort((r,s)=>{let a=r.metadata.namespace_?.version,i=s.metadata.namespace_?.version;return!a||!i?0:pi(i,a)});for(let r of o){let s=new mi(r,n),a=await e.parseKanonaks(s),i=di(a,gi.InstanceTransformation);if(i[0])return i[0]}}function ki(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 ji,existsSync as Ye,readdirSync as Ai,writeFileSync as Oi,statSync as Ni}from"fs";import{join as he}from"path";import{KanonakObjectParser as Li,KanonakParser as Ui,computeIntegrity as Fi}from"@kanonak-protocol/sdk";import{findSubjectsByType as Mi}from"@kanonak-protocol/sdk/uri-helpers";import{SingleDocumentRepository as Vi}from"@kanonak-protocol/sdk/uri-helpers";import{TransformationRunnerV3 as Hi}from"@kanonak-protocol/sdk/transformations";import{TX_V3 as zi}from"@kanonak-protocol/sdk/transformations";import{join as It}from"path";import{homedir as Kt}from"os";import{KanonakObjectParser as yi}from"@kanonak-protocol/sdk";import{SingleDocumentRepository as bi}from"@kanonak-protocol/sdk/uri-helpers";import{findSubjectsByType as Tt,getStringValue as Ge,getReferenceUri as wi}from"@kanonak-protocol/sdk/uri-helpers";var M="kanonak.org",V="agent-skills",Et={publisher:M,package_:V,name:"Client"},jt={publisher:M,package_:V,name:"clientId"},$i={publisher:M,package_:V,name:"projectAgentDir"},vi={publisher:M,package_:V,name:"userAgentDir"},Si={publisher:M,package_:V,name:"agentFileFormat"},Pi="agents";function Ci(){if(process.env.CLAUDE_CODE||process.env.CLAUDE_PROJECT_DIR)return"claude-code"}async function fe(n,e){let t=(n.client??Ci()??Pi).toLowerCase(),o=n.scope??"project",r=await _i(t,e);if(!r){let u=await Ri(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 a=Ge(r,o==="user"?vi:$i);if(!a)throw new Error(`Client "${t}" has no ${o==="user"?"userAgentDir":"projectAgentDir"} declared.`);let c=wi(r,Si)?.name==="toml"?"toml":"markdown-frontmatter",l=c==="toml"?".toml":".md";return{agentsDir:xi(a),format:c,fileExtension:l}}var Dt=new WeakMap;async function At(n){let e=Dt.get(n);if(e)return e;let t=await n.getDocumentsByNamespaceAsync(M,V);if(t.length===0)throw new Error(`Could not find ${M}/${V} in the repository. Install a capability that imports agent-skills to populate the cache.`);let r=[...t].sort((c,l)=>{let u=c.metadata.namespace_?.version,p=l.metadata.namespace_?.version;return!u||!p?0:u.major!==p.major?p.major-u.major:u.minor!==p.minor?p.minor-u.minor:p.patch-u.patch})[0],s=new yi,a=new bi(r,n),i=await s.parseKanonaks(a);return Dt.set(n,i),i}async function _i(n,e){let t=await At(e),o=Tt(t,Et);for(let r of o)if(Ge(r,jt)===n)return r}async function Ri(n){let e=await At(n),t=Tt(e,Et),o=[];for(let r of t){let s=Ge(r,jt);s&&o.push(s)}return o}function xi(n){return n.startsWith("~/")?It(Kt(),n.slice(2)):n==="~"?Kt():n.startsWith("/")||/^[A-Za-z]:[\\/]/.test(n)?n:It(process.cwd(),n)}import{readFileSync as Ii,writeFileSync as Ki,existsSync as Di}from"fs";import{join as Ot}from"path";import Nt from"js-yaml";var Lt="agents.lock",Ti=`# This file is generated by Kanonak CLI. Do not edit manually.
135
- `;function ge(n){let e=Ot(n,Lt);if(!Di(e))return{version:"1",lastUpdated:new Date().toISOString(),agents:{}};let t=Ii(e,"utf-8"),o=Nt.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 Je(n,e){e.lastUpdated=new Date().toISOString();let t={};for(let s of Object.keys(e.agents).sort())t[s]=e.agents[s];e.agents=t;let o=Ot(n,Lt),r=Nt.dump(e,{lineWidth:-1,sortKeys:!1,quotingType:'"'});Ki(o,Ti+r,"utf-8")}var Ut="kanonak.org",Ft="agent-to-agent-file",ke=class{parser=new Ui;objectParser=new Li;runner=new Hi;async deploy(e){let{instances:t,allKanonaks:o,repository:r,options:s}=e;if(t.length===0){console.error("No Agent instances to deploy.");return}let{agentsDir:a,format:i,fileExtension:c}=await fe(s,r),l=await Bi(r,this.objectParser);if(!l){console.error(`Cannot deploy: ${Ut}/${Ft}@3.0.0 is not installed in the workspace or cache.`);return}let u=i==="toml"?"toml":"markdown-with-frontmatter",p=await this.runner.run({transformation:l,instances:t,allKanonaks:o,repository:r,parser:this.parser,objectParser:this.objectParser,outputFormat:u});if(p.length===0){console.error("No agents could be transformed from the package.");return}Ei(a,{recursive:!0});let d=ge(a),f=t[0].namespace,{publisher:g,package_:m,version:k}=Wi(f);for(let h of p){let y=`${h.fileName}${c}`,b=he(a,y),w=Ye(b);Oi(b,h.content,"utf-8"),d.agents[h.fileName]={publisher:g,package_:m,version:k,resolved:g?`kanonak://${g}/${m}@${k}`:"",integrity:Fi(h.content),fileName:y},console.log(` ${w?"Updated":"Installed"} agent "${h.fileName}" \u2192 ${b}`)}Je(a,d)}async undeploy(e,t){let{repository:o,options:r}=t,{agentsDir:s}=await fe(r,o),a=ge(s),i=a.agents[e];i||(console.error(`Agent "${e}" is not installed at ${s}`),process.exit(1));let c=he(s,i.fileName);Ye(c)&&ji(c,{force:!0}),delete a.agents[e],Je(s,a),console.log(`Removed agent "${e}" from ${c}`)}async list(e){let{repository:t,options:o}=e,{agentsDir:r}=await fe(o,t),s=ge(r),a=[];for(let[i,c]of Object.entries(s.agents))a.push({name:i,publisher:c.publisher,package_:c.package_,version:c.version,path:he(r,c.fileName)});if(Ye(r))try{let i=Ai(r,{withFileTypes:!0});for(let c of i){if(!c.isFile()||c.name==="agents.lock")continue;let l=he(r,c.name),u=qi(c.name);if(!s.agents[u]){try{if(!Ni(l).isFile())continue}catch{continue}a.push({name:u,publisher:"",package_:"",version:"",path:l})}}}catch{}return a}};async function Bi(n,e){let t=await n.getDocumentsByNamespaceAsync(Ut,Ft);if(t.length===0)return;let o=new Vi(t[0],n),r=await e.parseKanonaks(o);return Mi(r,zi.InstanceTransformation)[0]}function qi(n){let e=n.lastIndexOf(".");return e===-1?n:n.substring(0,e)}function Wi(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 oc=Xi(Yi(import.meta.url)),rc=JSON.parse(Ji(Zi(oc,"..","package.json"),"utf-8")),R=new Gi;R.name("kanonak").description("Kanonak Protocol CLI - Validate and resolve Kanonak ontology packages").version(rc.version);R.command("validate <path>").description("Validate .kan.yml file(s). Resolves imports via HTTP from publisher domains.").action(async n=>{await rn(n)});R.command("install [package]").description("Install a package and its dependencies, or install all from kanonak.lock.").action(async n=>{await an(n)});R.command("deps <path>").description("Show resolved dependency tree for a .kan.yml file.").action(async n=>{await cn(n)});R.command("login <publisher>").description("Authenticate with a package publisher using OAuth 2.0.").action(async n=>{await mn(n)});R.command("logout <publisher>").description("Revoke tokens and remove stored credentials for a publisher.").action(async n=>{await fn(n)});R.command("hash <target>").description("Print the canonical structural hash (sha256:\u2026) of a Kanonak package.").option("-v, --verbose","Also print the canonical form on stderr.").action(async(n,e)=>{await st(n,e)});R.addCommand(In());R.addCommand(On());R.addCommand(Vn());R.addCommand(zn());R.addCommand(Zn());R.addCommand(Qn());R.addCommand(at());R.addCommand(et());async function ac(){try{let n=new K,e=new Qi,t=new nc,o=tc(t),r=new ec({fetchFn:o}),s=await v(process.cwd(),e),a=new ie;a.register("kanonak.org/capabilities/agent-skill-deployment",new me),a.register("kanonak.org/agent-capabilities/agent-instance-deployment",new ke);let i=await _n(n,e,s),c=new se(n,e,r,o,a,s);ct(R,i,c)}catch{}}await ac();R.parse();
129
+ `)}}async function Ta(n,e){if(n.endsWith(".kan.yml")){let i=Sa(n);if(!wa(i))throw new Error(`kanonak hash: file not found: ${i}`);let c=$a(i,"utf-8");return{document:e.parse(c),source:i}}let t=xa(n);if(t.kind!=="package")throw new Error(`kanonak hash: expected a package address (publisher/package[@version]) or a path ending in .kan.yml; got ${t.kind} address "${n}"`);let r=await(await v(process.cwd(),e)).getDocumentsByNamespaceAsync(t.publisher,t.package_);if(r.length===0)throw new Error(`kanonak hash: could not find ${n} in local workspace, global cache, or publisher HTTP`);let a=t.version?`${t.version.major}.${t.version.minor}.${t.version.patch}`:void 0,s=Ia(r,a?{requestedVersion:a}:{});if(!s.chosen){let i=a?`@${a}`:"";throw new Error(`kanonak hash: no version of ${t.publisher}/${t.package_}${i} available across local/cache/HTTP`)}return{document:s.chosen,source:n}}function Da(n){return n.endsWith(".kan.yml")?N(va(n)):process.cwd()}import{Command as pt}from"commander";function W(n){return`${P}/${C}/${n}`}var He={[W("fetch-and-deploy")]:(n,e,t,o)=>n.add(e,t[0],o),[W("remove-deployed")]:(n,e,t,o)=>n.remove(e,t[0],o),[W("list-deployed")]:(n,e,t,o)=>n.list(e,o),[W("update-deployed")]:(n,e,t,o)=>n.update(e,t[0],o),[W("search-available")]:(n,e,t,o)=>n.search(e,o),[W("show-info")]:(n,e,t,o)=>n.info(e,t[0],o)};function dt(n,e,t){for(let o of e){let r=new pt(o.commandName).description(o.description.trim());for(let a of o.commands){let s=r.command(Ea(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=ja(i);await Aa(t,o,a,i,c)})}n.addCommand(r)}}function Ea(n){let e=n.arguments.filter(t=>!t.isOption).map(t=>t.required?`<${t.argumentName}>`:`[${t.argumentName}]`);return[n.subcommandName,...e].join(" ")}function ja(n){for(let e=n.length-1;e>=0;e--)if(n[e]&&typeof n[e]=="object"&&!(n[e]instanceof pt))return n[e];return{}}async function Aa(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(He).join(", ")}.`),process.exit(1));let s=He[t.actionKey];s||(console.error(`Capability subcommand '${t.subcommandName}' references unknown Action '${t.actionKey}'. Known actions: ${Object.keys(He).join(", ")}.`),process.exit(1)),await s(n,e,a,r)}import{existsSync as mt,readFileSync as Oa,statSync as ft}from"fs";import{resolve as Na}from"path";import{KanonakObjectParser as La,PublisherIndex as Be,PublisherConfigResolver as Ua,formatVersion as gt,pickHighestDocument as Fa}from"@kanonak-protocol/sdk";import{SingleDocumentRepository as ht}from"@kanonak-protocol/sdk/uri-helpers";import{uriKey as G,findSubjectsByType as kt}from"@kanonak-protocol/sdk/uri-helpers";var se=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 La;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=D(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 f=Fa(u,{requestedVersion:c??void 0});if(f.chosen){let g=f.chosen.metadata.namespace_;(!g||!g.version)&&(console.error(`Document for ${s}/${i} is missing namespace metadata.`),process.exit(1));let m=gt(g.version);this.fileCache.put(s,i,m,this.parser.save(f.chosen)),await this.deployFromDoc(e,f.chosen,s,i,m,l??void 0,`${s}/${i}@${m}`,o);return}}let p=c??await this.publisherIndex.getHighestVersion(s,i);p||(console.error(`Could not resolve version for "${s}/${i}".`),await this.printPackageSuggestions(s,i,e.commandName),process.exit(1));let d=this.fileCache.get(s,i,p);if(!d){let f=await this.publisherIndex.getPackageUrl(s,i,p),g=await this.fetchFn(f,s);g.ok||(g.status===404?(console.error(`Package ${s}/${i}@${p} not found at ${f}.`),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 ${f} (${g.status} ${g.statusText}).`),process.exit(1)),d=await g.text(),this.fileCache.put(s,i,p,d)}await this.deployFromDoc(e,this.parser.parse(d),s,i,p,l??void 0,`${s}/${i}@${p}`,o)}tryLoadFromLocalFile(e){if(!(/^[.\/\\]/.test(e)||/^[A-Za-z]:[\\/]/.test(e)||e.endsWith(".kan.yml")||mt(e)&&ft(e).isFile()))return;let o=Na(e);(!mt(o)||!ft(o).isFile())&&(console.error(`Local file not found: ${e}`),process.exit(1));let r=Oa(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:gt(s.version)}}async deployFromDoc(e,t,o,r,a,s,i,c){let l=new ht(t,this.repository),u=await this.objectParser.parseKanonaks(l),p=yt(e.managesTypeKey);p||(console.error(`Capability "${e.commandName}" has no resolved managesType.`),process.exit(1));let d=kt(u,p);d.length===0&&(console.error(`${i} does not contain any ${G(p)} instances.`),process.exit(1));let f=d;if(s&&(f=d.filter(k=>k.name===s),f.length===0)){console.error(`Instance "${s}" not found in ${i}.`),console.error(""),console.error(`Available ${G(p)} instance(s):`);for(let k of d)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 g=s?`${s} from ${i}`:`${f.length} ${G(p)} instance(s) from ${i}`;console.log(`Installing ${g}...`);let m=this.handlerRegistry.get(e.deploymentTargetKey);m?await m.deploy({instances:f,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:Ma(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:
130
+ `);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.":`
131
+ Updated ${i} instance(s).`)}async search(e,t){let o=t.publisher??"kanonak.org",r=yt(e.managesTypeKey);if(!r){console.error("Capability has no resolved managesType; nothing to search for.");return}console.log(`Searching ${o} for ${G(r)} instances...
132
+ `);let a=new Ua,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=Be.parseIndex(l);if(u.size===0){console.error(`No packages found for publisher "${o}".`);return}let p=new Map;for(let[m,k]of u){let h=[...k].sort((y,b)=>{let w=Be.parseVersion(y),$=Be.parseVersion(b);return!w||!$?0:w.major!==$.major?$.major-w.major:w.minor!==$.minor?$.minor-w.minor:$.patch-w.patch});p.set(m,h[0])}let d=[],f=0;for(let[m,k]of p){let h=this.fileCache.get(o,m,k);if(!h)try{let y=await this.publisherIndex.getPackageUrl(o,m,k),b=await this.fetchFn(y,o);if(!b.ok)continue;h=await b.text(),this.fileCache.put(o,m,k,h)}catch{continue}try{let y=this.parser.parse(h),b=new ht(y,this.repository),w=await this.objectParser.parseKanonaks(b),$=kt(w,r);for(let R of $)d.push({publisher:o,package_:m,version:k,subject:R});f++}catch{continue}}if(d.length===0){console.log(`No ${G(r)} instances found across ${f} package(s).`);return}console.log(`Found ${d.length} ${G(r)} instance(s) in ${f} package(s):
133
+ `);let g=new Map;for(let m of d){let k=`${m.publisher}/${m.package_}@${m.version}`,h=g.get(k);h?h.push(m):g.set(k,[m])}for(let[m,k]of g){let h=k[0],y=`${h.publisher}/${h.package_}`,b=k.length===1;console.log(` ${m}`),console.log(` ${k.length} skill${b?"":"s"}:`);for(let w of k)console.log(` - ${w.subject.name}`);if(console.log(""),b)console.log(" install:"),console.log(` kanonak ${e.commandName} add ${y}/${h.subject.name}`);else{console.log(" install one of them:");for(let w of k)console.log(` kanonak ${e.commandName} add ${y}/${w.subject.name}`);console.log(" install all of them:"),console.log(` kanonak ${e.commandName} add ${y}`)}console.log("")}}async info(e,t,o){let s=(await this.requireHandler(e).list({repository:this.repository,options:o})).find(i=>i.name===t);s||(console.error(`"${t}" is not installed.`),process.exit(1)),console.log(`Name: ${s.name}`),console.log(`Type: ${e.managesTypeKey||"n/a"}`),console.log(`Publisher: ${s.publisher||"unmanaged"}`),console.log(`Package: ${s.package_||"n/a"}`),console.log(`Version: ${s.version||"n/a"}`),console.log(`Path: ${s.path}`)}requireHandler(e){let t=this.handlerRegistry.get(e.deploymentTargetKey);return t||(console.error(`No deployment handler registered for "${e.deploymentTargetKey}". Ensure the capability's deploymentTarget resolves to a DeploymentTarget instance whose URI is registered in the CLI at startup.`),process.exit(1)),t}};function yt(n){if(!n)return;let e=n.split("/");if(e.length===3)return{publisher:e[0],package_:e[1],name:e[2]}}function Ma(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=Va(t,o);return i===0?100:i<=2?Math.max(1,20-i*5):0}function Va(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 ae=class{handlers=new Map;register(e,t){this.handlers.set(e,t)}get(e){return this.handlers.get(e)??null}};import{mkdirSync as ei,rmSync as ni,existsSync as ue,readdirSync as ti,writeFileSync as oi}from"fs";import{join as pe}from"path";import{KanonakObjectParser as ri,KanonakParser as si,computeIntegrity as ai,compareVersions as ii}from"@kanonak-protocol/sdk";import{findSubjectsByType as ci}from"@kanonak-protocol/sdk/uri-helpers";import{SingleDocumentRepository as li}from"@kanonak-protocol/sdk/uri-helpers";import{TransformationRunnerV3 as ui}from"@kanonak-protocol/sdk/transformations";import{TX_V3 as pi}from"@kanonak-protocol/sdk/transformations";import{join as ze}from"path";import{homedir as bt}from"os";import{KanonakObjectParser as Ha}from"@kanonak-protocol/sdk";import{SingleDocumentRepository as Ba}from"@kanonak-protocol/sdk/uri-helpers";import{findSubjectsByType as $t,getStringValue as ie}from"@kanonak-protocol/sdk/uri-helpers";var U="kanonak.org",F="agent-skills",vt={publisher:U,package_:F,name:"Client"},St={publisher:U,package_:F,name:"clientId"},za={publisher:U,package_:F,name:"projectSkillDir"},qa={publisher:U,package_:F,name:"userSkillDir"},Wa={publisher:U,package_:F,name:"skillFileName"},Pt="agents";async function Q(n,e){let t=(n.client??Ct()??Pt).toLowerCase(),o=n.scope??"project",r=await _t(t,e);if(!r){let i=await Ga(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=ie(r,o==="user"?qa:za);if(!s)throw new Error(`Client "${t}" has no ${o==="user"?"userSkillDir":"projectSkillDir"} declared.`);return Ja(s)}async function ce(n,e,t){let o=await Q(e,t);return ze(o,n)}async function qe(n,e){let t=(n.client??Ct()??Pt).toLowerCase(),o=await _t(t,e);return o?ie(o,Wa)??"SKILL.md":"SKILL.md"}function Ct(){if(process.env.CLAUDE_CODE||process.env.CLAUDE_PROJECT_DIR)return"claude-code"}var wt=new WeakMap;async function Rt(n){let e=wt.get(n);if(e)return e;let t=await n.getDocumentsByNamespaceAsync(U,F);if(t.length===0)throw new Error(`Could not find ${U}/${F} in the repository. Install a skill capability (which transitively imports agent-skills) or fetch agent-skills directly to populate the cache.`);let r=[...t].sort((c,l)=>{let u=c.metadata.namespace_?.version,p=l.metadata.namespace_?.version;return!u||!p?0:u.major!==p.major?p.major-u.major:u.minor!==p.minor?p.minor-u.minor:p.patch-u.patch})[0],a=new Ha,s=new Ba(r,n),i=await a.parseKanonaks(s);return wt.set(n,i),i}async function _t(n,e){let t=await Rt(e),o=$t(t,vt);for(let r of o)if(ie(r,St)===n)return r}async function Ga(n){let e=await Rt(n),t=$t(e,vt),o=[];for(let r of t){let a=ie(r,St);a&&o.push(a)}return o}function Ja(n){return n.startsWith("~/")?ze(bt(),n.slice(2)):n==="~"?bt():n.startsWith("/")||/^[A-Za-z]:[\\/]/.test(n)?n:ze(process.cwd(),n)}import{readFileSync as Ya,writeFileSync as Xa,existsSync as Za}from"fs";import{join as xt}from"path";import It from"js-yaml";var Kt="skills.lock",Qa=`# This file is generated by Kanonak CLI. Do not edit manually.
134
+ `;function le(n){let e=xt(n,Kt);if(!Za(e))return{version:"1",lastUpdated:new Date().toISOString(),skills:{}};let t=Ya(e,"utf-8"),o=It.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 We(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=xt(n,Kt),r=It.dump(e,{lineWidth:-1,sortKeys:!1,quotingType:'"'});Xa(o,Qa+r,"utf-8")}var Tt="kanonak.org",Dt="skill-to-skill-md",de=class{parser=new si;objectParser=new ri;runner=new ui;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 di(r,this.objectParser);if(!s){console.error(`Cannot deploy: ${Tt}/${Dt}@3.0.0 is not installed in the workspace or cache.`);return}let i=await this.runner.run({transformation:s,instances:t,allKanonaks:o,repository:r,parser:this.parser,objectParser:this.objectParser,outputFormat:"markdown-with-frontmatter"});if(i.length===0){console.error("No skills could be transformed from the package.");return}let c=await Q(a,r),l=await qe(a,r),u=le(c),p=t[0].namespace,{publisher:d,package_:f,version:g}=mi(p);for(let m of i){let k=await ce(m.fileName,a,r),h=ue(pe(k,l));ei(k,{recursive:!0}),oi(pe(k,l),m.content,"utf-8"),u.skills[m.fileName]={publisher:d,package_:f,version:g,resolved:d?`kanonak://${d}/${f}@${g}`:"",integrity:ai(m.content)},console.log(` ${h?"Updated":"Installed"} skill "${m.fileName}" \u2192 ${k}`)}We(c,u)}async undeploy(e,t){let{repository:o,options:r}=t,a=await ce(e,r,o);ue(a)||(console.error(`Skill "${e}" is not installed at ${a}`),process.exit(1)),ni(a,{recursive:!0,force:!0});let s=await Q(r,o),i=le(s);delete i.skills[e],We(s,i),console.log(`Removed skill "${e}" from ${a}`)}async list(e){let{repository:t,options:o}=e,r=await Q(o,t),a=le(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 ce(c,o,t)});let i=await qe(o,t);if(ue(r))try{let c=ti(r,{withFileTypes:!0});for(let l of c){if(!l.isDirectory()||a.skills[l.name])continue;let u=pe(r,l.name,i);ue(u)&&s.push({name:l.name,publisher:"",package_:"",version:"",path:pe(r,l.name)})}}catch{}return s}};async function di(n,e){let t=await n.getDocumentsByNamespaceAsync(Tt,Dt);if(t.length===0)return;let o=[...t].sort((r,a)=>{let s=r.metadata.namespace_?.version,i=a.metadata.namespace_?.version;return!s||!i?0:ii(i,s)});for(let r of o){let a=new li(r,n),s=await e.parseKanonaks(a),i=ci(s,pi.InstanceTransformation);if(i[0])return i[0]}}function mi(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 Ii,rmSync as Ki,existsSync as Ye,readdirSync as Ti,writeFileSync as Di,statSync as Ei}from"fs";import{join as ge}from"path";import{KanonakObjectParser as ji,KanonakParser as Ai,computeIntegrity as Oi}from"@kanonak-protocol/sdk";import{findSubjectsByType as Ni}from"@kanonak-protocol/sdk/uri-helpers";import{SingleDocumentRepository as Li}from"@kanonak-protocol/sdk/uri-helpers";import{TransformationRunnerV3 as Ui}from"@kanonak-protocol/sdk/transformations";import{TX_V3 as Fi}from"@kanonak-protocol/sdk/transformations";import{join as Et}from"path";import{homedir as jt}from"os";import{KanonakObjectParser as fi}from"@kanonak-protocol/sdk";import{SingleDocumentRepository as gi}from"@kanonak-protocol/sdk/uri-helpers";import{findSubjectsByType as Ot,getStringValue as Ge,getReferenceUri as hi}from"@kanonak-protocol/sdk/uri-helpers";var M="kanonak.org",V="agent-skills",Nt={publisher:M,package_:V,name:"Client"},Lt={publisher:M,package_:V,name:"clientId"},ki={publisher:M,package_:V,name:"projectAgentDir"},yi={publisher:M,package_:V,name:"userAgentDir"},bi={publisher:M,package_:V,name:"agentFileFormat"},wi="agents";function $i(){if(process.env.CLAUDE_CODE||process.env.CLAUDE_PROJECT_DIR)return"claude-code"}async function me(n,e){let t=(n.client??$i()??wi).toLowerCase(),o=n.scope??"project",r=await vi(t,e);if(!r){let u=await Si(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=Ge(r,o==="user"?yi:ki);if(!s)throw new Error(`Client "${t}" has no ${o==="user"?"userAgentDir":"projectAgentDir"} declared.`);let c=hi(r,bi)?.name==="toml"?"toml":"markdown-frontmatter",l=c==="toml"?".toml":".md";return{agentsDir:Pi(s),format:c,fileExtension:l}}var At=new WeakMap;async function Ut(n){let e=At.get(n);if(e)return e;let t=await n.getDocumentsByNamespaceAsync(M,V);if(t.length===0)throw new Error(`Could not find ${M}/${V} in the repository. Install a capability that imports agent-skills to populate the cache.`);let r=[...t].sort((c,l)=>{let u=c.metadata.namespace_?.version,p=l.metadata.namespace_?.version;return!u||!p?0:u.major!==p.major?p.major-u.major:u.minor!==p.minor?p.minor-u.minor:p.patch-u.patch})[0],a=new fi,s=new gi(r,n),i=await a.parseKanonaks(s);return At.set(n,i),i}async function vi(n,e){let t=await Ut(e),o=Ot(t,Nt);for(let r of o)if(Ge(r,Lt)===n)return r}async function Si(n){let e=await Ut(n),t=Ot(e,Nt),o=[];for(let r of t){let a=Ge(r,Lt);a&&o.push(a)}return o}function Pi(n){return n.startsWith("~/")?Et(jt(),n.slice(2)):n==="~"?jt():n.startsWith("/")||/^[A-Za-z]:[\\/]/.test(n)?n:Et(process.cwd(),n)}import{readFileSync as Ci,writeFileSync as Ri,existsSync as _i}from"fs";import{join as Ft}from"path";import Mt from"js-yaml";var Vt="agents.lock",xi=`# This file is generated by Kanonak CLI. Do not edit manually.
135
+ `;function fe(n){let e=Ft(n,Vt);if(!_i(e))return{version:"1",lastUpdated:new Date().toISOString(),agents:{}};let t=Ci(e,"utf-8"),o=Mt.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 Je(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=Ft(n,Vt),r=Mt.dump(e,{lineWidth:-1,sortKeys:!1,quotingType:'"'});Ri(o,xi+r,"utf-8")}var Ht="kanonak.org",Bt="agent-to-agent-file",he=class{parser=new Ai;objectParser=new ji;runner=new Ui;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 me(a,r),l=await Mi(r,this.objectParser);if(!l){console.error(`Cannot deploy: ${Ht}/${Bt}@3.0.0 is not installed in the workspace or cache.`);return}let u=i==="toml"?"toml":"markdown-with-frontmatter",p=await this.runner.run({transformation:l,instances:t,allKanonaks:o,repository:r,parser:this.parser,objectParser:this.objectParser,outputFormat:u});if(p.length===0){console.error("No agents could be transformed from the package.");return}Ii(s,{recursive:!0});let d=fe(s),f=t[0].namespace,{publisher:g,package_:m,version:k}=Hi(f);for(let h of p){let y=`${h.fileName}${c}`,b=ge(s,y),w=Ye(b);Di(b,h.content,"utf-8"),d.agents[h.fileName]={publisher:g,package_:m,version:k,resolved:g?`kanonak://${g}/${m}@${k}`:"",integrity:Oi(h.content),fileName:y},console.log(` ${w?"Updated":"Installed"} agent "${h.fileName}" \u2192 ${b}`)}Je(s,d)}async undeploy(e,t){let{repository:o,options:r}=t,{agentsDir:a}=await me(r,o),s=fe(a),i=s.agents[e];i||(console.error(`Agent "${e}" is not installed at ${a}`),process.exit(1));let c=ge(a,i.fileName);Ye(c)&&Ki(c,{force:!0}),delete s.agents[e],Je(a,s),console.log(`Removed agent "${e}" from ${c}`)}async list(e){let{repository:t,options:o}=e,{agentsDir:r}=await me(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:ge(r,c.fileName)});if(Ye(r))try{let i=Ti(r,{withFileTypes:!0});for(let c of i){if(!c.isFile()||c.name==="agents.lock")continue;let l=ge(r,c.name),u=Vi(c.name);if(!a.agents[u]){try{if(!Ei(l).isFile())continue}catch{continue}s.push({name:u,publisher:"",package_:"",version:"",path:l})}}}catch{}return s}};async function Mi(n,e){let t=await n.getDocumentsByNamespaceAsync(Ht,Bt);if(t.length===0)return;let o=new Li(t[0],n),r=await e.parseKanonaks(o);return Ni(r,Fi.InstanceTransformation)[0]}function Vi(n){let e=n.lastIndexOf(".");return e===-1?n:n.substring(0,e)}function Hi(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 Qi=Wi(qi(import.meta.url)),ec=JSON.parse(zi(Gi(Qi,"..","package.json"),"utf-8")),_=new Bi;_.name("kanonak").description("Kanonak Protocol CLI - Validate and resolve Kanonak ontology packages").version(ec.version);_.command("validate <path>").description("Validate .kan.yml file(s). Resolves imports via HTTP from publisher domains.").action(async n=>{await rn(n)});_.command("install [package]").description("Install a package and its dependencies, or install all from kanonak.lock.").action(async n=>{await sn(n)});_.command("deps <path>").description("Show resolved dependency tree for a .kan.yml file.").action(async n=>{await cn(n)});_.command("login <publisher>").description("Authenticate with a package publisher using OAuth 2.0.").action(async n=>{await mn(n)});_.command("logout <publisher>").description("Revoke tokens and remove stored credentials for a publisher.").action(async n=>{await fn(n)});_.command("hash <target>").description("Print the canonical structural hash (sha256:\u2026) of a Kanonak package.").option("-v, --verbose","Also print the canonical form on stderr.").action(async(n,e)=>{await ut(n,e)});_.addCommand(In());_.addCommand(On());_.addCommand(Vn());_.addCommand(Bn());_.addCommand(Zn());_.addCommand(ot());_.addCommand(lt());_.addCommand(rt());async function nc(){try{let n=new K,e=new Ji,t=new Xi,o=Zi(t),r=new Yi({fetchFn:o}),a=await v(process.cwd(),e),s=new ae;s.register("kanonak.org/capabilities/agent-skill-deployment",new de),s.register("kanonak.org/agent-capabilities/agent-instance-deployment",new he);let i=await Rn(n,e,a),c=new se(n,e,r,o,s,a);dt(_,i,c)}catch{}}await nc();_.parse();
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@kanonak-protocol/cli",
3
- "version": "3.60.0",
4
- "description": "Kanonak Protocol CLI - Validate and resolve Kanonak ontology packages",
3
+ "version": "3.62.0",
4
+ "description": "Command-line tool for the Kanonak Protocol validate, resolve, preview, and publish semantic ontology packages.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
7
7
  "types": "./dist/index.d.ts",
@@ -26,6 +26,7 @@
26
26
  "type": "git",
27
27
  "url": "https://github.com/kanonak-protocol"
28
28
  },
29
+ "homepage": "https://kanonak.org",
29
30
  "keywords": [
30
31
  "kanonak",
31
32
  "ontology",
@@ -34,8 +35,8 @@
34
35
  "semantic-web"
35
36
  ],
36
37
  "dependencies": {
37
- "@kanonak-protocol/sdk": "^3.60.0",
38
- "@kanonak-protocol/types": "^3.60.0",
38
+ "@kanonak-protocol/sdk": "^3.62.0",
39
+ "@kanonak-protocol/types": "^3.62.0",
39
40
  "commander": "^13.0.0",
40
41
  "js-yaml": "^4.1.1"
41
42
  },