@kanonak-protocol/cli 4.6.0 → 4.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +17 -17
- package/package.json +3 -3
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import{Command as
|
|
2
|
+
import{Command as rc}from"commander";import{readFileSync as ac}from"fs";import{fileURLToPath as sc}from"url";import{dirname as ic,join as cc}from"path";import{KanonakParser as lc,PublisherIndex as uc,CredentialStore as pc,createAuthenticatedFetch as dc}from"@kanonak-protocol/sdk";import{readFileSync as ao,statSync as so}from"fs";import{resolve as io,dirname as co}from"path";import{KanonakParser as lo,KanonakObjectValidator as uo,ValidationSeverity as on}from"@kanonak-protocol/sdk";import{readdirSync as no}from"fs";import{join as to,dirname as oo,basename as tn}from"path";import{LocalFirstRepository as Pc,buildLocalFirstRepository as ro}from"@kanonak-protocol/sdk";import{mkdirSync as Jt,readFileSync as en,writeFileSync as nn,existsSync as we,appendFileSync as Yt}from"fs";import{join as Xt,dirname as Zt,isAbsolute as Qt}from"path";import{getGlobalCachePath as eo}from"@kanonak-protocol/sdk";var K=class{constructor(e=eo()){this.cacheDir=e;this.isProjectLocal=!Qt(e)}cacheDir;gitignoreChecked=!1;isProjectLocal;get(e,t,o){let r=this.getPath(e,t,o);return we(r)?en(r,"utf-8"):null}put(e,t,o,r){let s=this.getPath(e,t,o);Jt(Zt(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
3
|
`).some(r=>r.trim()===t||r.trim()===t+"/"))return;Yt(e,`
|
|
4
4
|
${t}/
|
|
5
5
|
`)}else nn(e,`${t}/
|
|
@@ -108,7 +108,7 @@ 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 la(n,e)}catch(t){console.error(`Error: ${t.message}`),process.exit(1)}})}async function la(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 na,r=new ta,s=await $(process.cwd(),o),a=await r.parseKanonaks(s),i=ua(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=da(e.format),l=ma(e.variant),u=oa(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: ${fa(u)} \u2192 ${Fn(u.transformation)}`);let p=pa(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=ca(e.format),f=await new ra().run({transformation:p,instances:[i],allKanonaks:a,repository:s,parser:o,objectParser:r,outputFormat:d}),m=ea(e.out);Zr(m,{recursive:!0});let h=ia[e.format]??"";for(let k of f){let y=ga(k.fileName),w=Qr(m,`${y}${h}`);Xr(w,k.content,"utf-8"),console.log(` wrote ${w}`)}console.log(`Done. ${f.length} artifact(s) written to ${m}`)}function ua(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 pa(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 da(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{...aa,name:n}}function ma(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{...sa,name:n}}function Un(n){return`${n.namespace}/${n.name}`}function Fn(n){return`${n.publisher}/${n.package_}@${n.version}/${n.name}`}function fa(n){return n.source==="instance"?"instance override":`class ${n.source.publisher}/${n.source.package_}/${n.source.name}`}function ga(n){return n.replace(/[^a-zA-Z0-9._@-]+/g,"_")}import{Command as ha}from"commander";import{writeFileSync as ka}from"fs";import{resolve as
|
|
111
|
+
`).action(async(n,e)=>{try{await la(n,e)}catch(t){console.error(`Error: ${t.message}`),process.exit(1)}})}async function la(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 na,r=new ta,s=await $(process.cwd(),o),a=await r.parseKanonaks(s),i=ua(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=da(e.format),l=ma(e.variant),u=oa(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: ${fa(u)} \u2192 ${Fn(u.transformation)}`);let p=pa(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=ca(e.format),f=await new ra().run({transformation:p,instances:[i],allKanonaks:a,repository:s,parser:o,objectParser:r,outputFormat:d}),m=ea(e.out);Zr(m,{recursive:!0});let h=ia[e.format]??"";for(let k of f){let y=ga(k.fileName),w=Qr(m,`${y}${h}`);Xr(w,k.content,"utf-8"),console.log(` wrote ${w}`)}console.log(`Done. ${f.length} artifact(s) written to ${m}`)}function ua(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 pa(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 da(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{...aa,name:n}}function ma(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{...sa,name:n}}function Un(n){return`${n.namespace}/${n.name}`}function Fn(n){return`${n.publisher}/${n.package_}@${n.version}/${n.name}`}function fa(n){return n.source==="instance"?"instance override":`class ${n.source.publisher}/${n.source.package_}/${n.source.name}`}function ga(n){return n.replace(/[^a-zA-Z0-9._@-]+/g,"_")}import{Command as ha}from"commander";import{writeFileSync as ka}from"fs";import{join as ya,resolve as wa}from"path";import{KanonakParser as ba,ViewMaterializer as va,LockAwareRepository as $a,loadLockFile as Sa}from"@kanonak-protocol/sdk";function Hn(){let n=new ha("view").description("Run and materialize Views \u2014 the producer-agnostic query primitive. A View selects instances of its bind class, filters by its where predicates, and projects each into its produces output class.");return n.command("run").description("Materialize a view.View against the local catalog into an EphemeralPackage (content-addressed, versionless). Prints the result as .kan.yml, or writes it with --out.").argument("<view>","View URI in the form publisher/package[@version]/name. May name a view.View directly or a view.ViewPackage (its rootView is followed).").option("--out <file>","Write the EphemeralPackage to this file instead of stdout.").option("--id <id>","Record a per-invocation id on the result (provenance, not identity).").addHelpText("after",`
|
|
112
112
|
Examples:
|
|
113
113
|
|
|
114
114
|
# Materialize a published view and print the EphemeralPackage.
|
|
@@ -116,29 +116,29 @@ Examples:
|
|
|
116
116
|
|
|
117
117
|
# Write the result to a file.
|
|
118
118
|
$ kanonak view run example.org/authors/AuthorView --out ./result.kan.yml
|
|
119
|
-
`).action(async(e,t)=>{try{await
|
|
120
|
-
${
|
|
119
|
+
`).action(async(e,t)=>{try{await Pa(e,t)}catch(o){console.error(`Error: ${o.message}`),process.exit(1)}}),n}async function Pa(n,e){let t=T(n);if(!t||!t.instanceName)throw new Error(`Invalid view URI "${n}". Expected publisher/package[@version]/name.`);let o=new ba,r=await $(process.cwd(),o),s=Sa(ya(process.cwd(),"kanonak.lock")),a=s?new $a(r,s):r,i=new va(a,o),c={resolvedAt:new Date().toISOString()};e.id&&(c.invocationId=e.id);let l=await i.materialize({publisher:t.publisher,package_:t.packageName,name:t.instanceName},c);if(e.out){let u=wa(e.out);ka(u,l.yaml,"utf-8"),console.error(`Materialized ${l.rowCount} result(s) \u2192 ${u}
|
|
120
|
+
${l.publisher}/${l.packageName} (${l.contentHash})`)}else process.stdout.write(l.yaml)}import{Command as Ca}from"commander";import{writeFileSync as x,mkdirSync as L}from"fs";import{join as S,resolve as zn,dirname as Ra}from"path";import{SubjectKanonak as _a}from"@kanonak-protocol/sdk";import{loadServerModel as xa,route as Ia}from"@kanonak-protocol/sdk/server";function Bn(){return new Ca("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 Ka(n)})}async function Ka(n){let e=zn(n.workspace),t=zn(n.out),o=await xa(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(f=>f instanceof _a&&a.has(f.namespace||""));console.log(`Rendering ${l.length} resource(s).`);let u=0,p=0;for(let f of l){let m=(f.namespace||"").split("/")[1]??"",[h,k]=m.split("@");if(!h||!k)continue;let y=S(t,h,k);L(y,{recursive:!0});try{let w=s.renderRawMarkdown(f);w!==void 0&&(x(S(y,`${f.name}.md`),w,"utf-8"),u+=1),x(S(y,`${f.name}.html`),await s.renderDocument(f),"utf-8"),x(S(y,`${f.name}.css`),s.renderStylesheet(f),"utf-8"),x(S(y,`${f.name}.svg`),await s.renderSvg(f),"utf-8"),u+=3}catch(w){console.warn(` ${f.namespace}/${f.name}: ${w.message}`),p+=1}}console.log(`Done. ${u} artifact(s) written, ${p} skipped.`);let d=await Ta(t,l,s);console.log(`Wrote ${d} package overview page(s).`),await Ea(t,l,s);let g=ja(t,l);console.log(`Wrote ${g} version-form redirect stub(s).`),await Da(t,o)}async function Da(n,e){if(e.rawByNsKey.size===0)return;let t=async(o,r)=>{let s=S(n,r);L(Ra(s),{recursive:!0}),x(s,(await Ia(e,o)).body,"utf-8")};await t("/.well-known/kanonak.json",".well-known/kanonak.json"),await t("/index.txt","index.txt");for(let o of e.rawByNsKey.keys()){let[r,s]=o.split("@");!r||!s||await 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).`)}async function Ta(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 g={verStr:p,major:d[0],minor:d[1],patch:d[2]};o.has(u)||o.set(u,[]),o.get(u).push({resource:i,ver:g});let f=r.get(u);(!f||g.major>f.ver.major||g.major===f.ver.major&&g.minor>f.ver.minor||g.major===f.ver.major&&g.minor===f.ver.minor&&g.patch>f.ver.patch)&&r.set(u,{resource:i,ver:g})}let s=async(i,c)=>{try{return L(i,{recursive:!0}),x(S(i,"index.html"),await 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)await 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"),await 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}async function Ea(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(f=>Number.isNaN(f)))continue;let d={verStr:u,major:p[0],minor:p[1],patch:p[2]},g=r.get(l);(!g||d.major>g.ver.major||d.major===g.ver.major&&d.minor>g.ver.minor||d.major===g.ver.major&&d.minor===g.ver.minor&&d.patch>g.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"),await t.renderDocument(s,{rootIndex:!0}),"utf-8"),x(S(n,"index.css"),t.renderStylesheet(s),"utf-8")}function ja(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`),Ee(`/${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`),Ee(`/${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 g=S(n,a,d);L(g,{recursive:!0}),x(S(g,`${i}.html`),Ee(`/${a}/${p.verStr}/${i}`),"utf-8"),o+=1}}return o}function Ee(n){let e=n.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""");return`<!doctype html>
|
|
121
121
|
<meta charset="utf-8">
|
|
122
122
|
<title>Redirecting\u2026</title>
|
|
123
123
|
<meta http-equiv="refresh" content="0; url=${e}">
|
|
124
124
|
<link rel="canonical" href="${e}">
|
|
125
125
|
<p>If you are not redirected automatically, follow this <a href="${e}">link</a>.</p>
|
|
126
|
-
`}import{Command as Yn}from"commander";import{writeFileSync as je,mkdirSync as te}from"fs";import{join as Ae,resolve as Ta,dirname as Oe}from"path";import{KanonakParser as Ea,KanonakObjectParser as ja,SubjectKanonak as Xn,ReferenceStatement as Aa,ReferenceKanonak as Oa,ListStatement as Na,StringStatement as Zn,EmbeddedStatement as La,findDerivation as qn}from"@kanonak-protocol/sdk";import{SingleDocumentRepository as Ua}from"@kanonak-protocol/sdk/uri-helpers";import{TransformationRunnerV3 as Fa}from"@kanonak-protocol/sdk/transformations";import{findSubjectsByType as oe}from"@kanonak-protocol/sdk/uri-helpers";var E="kanonak.org",j="site",Wn={publisher:"kanonak.org",package_:"formats",name:"html"},Gn={publisher:"kanonak.org",package_:"derivation",name:"default"};function Qn(){let n=new Yn("site").description("Materialize a publisher's site \u2014 every StaticPage and AggregateView in the workspace gets rendered to its declared output path under the --out directory.");return n.addCommand(Ma()),n}function Ma(){return new Yn("build").description("Walk the workspace, find every StaticPage and AggregateView, and write each materialized artifact to its declared output path under the --out directory.").option("--out <dir>","Output base directory.","./_site").action(async n=>{try{await Va(n)}catch(e){console.error(`Error: ${e.message}`),process.exit(1)}})}async function Va(n){let e=new Ea,t=new ja,o=await $(process.cwd(),e),r=await t.parseKanonaks(o),s=Ta(n.out);te(s,{recursive:!0});let a=await o.getAllDocumentsAsync(),i=new Set;for(let m of a){let h=m.metadata.namespace_?.toString();h&&i.add(h)}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||"")),g=oe(r,u).filter(m=>i.has(m.namespace||""));console.log(`Found ${p.length} StaticPage(s), ${d.length} ResourcePage(s), and ${g.length} AggregateView(s) in the workspace.`);let f=new Fa;for(let m of p){let h=Ne(m,E,j,"outputPath")??`${m.name}.html`,k=qn(m,Wn,Gn,r);if(!k){console.warn(` [skip] ${m.name}: no HTML/default derivation found (check class hierarchy or universal-derivations is loaded)`);continue}let y=Le(r,k.transformation);if(!y){console.warn(` [skip] ${m.name}: transformation ${Ue(k.transformation)} not found`);continue}let w=await f.run({transformation:y,instances:[m],allKanonaks:r,repository:o,parser:e,objectParser:t,outputFormat:"html"});if(w.length===0){console.warn(` [skip] ${m.name}: transformation produced no artifacts`);continue}let b=Ae(s,h);te(Oe(b),{recursive:!0}),je(b,w[0].content,"utf-8"),console.log(` wrote ${b} (StaticPage ${m.name})`)}for(let m of d){let h=Ne(m,E,j,"outputPath")??`${m.name}.html`,k=Jn(m,E,j,"pageOf");if(!k){console.warn(` [skip] ${m.name}: no pageOf declared`);continue}let y=r.find(D=>D instanceof Xn&&D.name===k.name&&(D.namespace||"").startsWith(`${k.publisher}/${k.package_}@`));if(!y){console.warn(` [skip] ${m.name}: pageOf target ${k.publisher}/${k.package_}/${k.name} not found`);continue}let w=qn(y,Wn,Gn,r);if(!w){console.warn(` [skip] ${m.name}: no derivation for target ${y.name}`);continue}let b=Le(r,w.transformation);if(!b){console.warn(` [skip] ${m.name}: transformation ${Ue(w.transformation)} not found`);continue}let v=await f.run({transformation:b,instances:[y],allKanonaks:r,repository:o,parser:e,objectParser:t,outputFormat:"html"});if(v.length===0){console.warn(` [skip] ${m.name}: transformation produced no artifacts`);continue}let _=Ae(s,h);te(Oe(_),{recursive:!0}),je(_,v[0].content,"utf-8"),console.log(` wrote ${_} (ResourcePage ${m.name} \u2192 ${y.name})`)}for(let m of g){let h=Ne(m,E,j,"outputPath");if(!h){console.warn(` [skip] ${m.name}: no outputPath declared`);continue}let k=Jn(m,E,j,"scopeClass");if(!k){console.warn(` [skip] ${m.name}: no scopeClass declared`);continue}let y={publisher:k.publisher,package_:k.package_,name:k.name},w=Ha(m,E,j,"scopeSources"),b=za(m);if(!b){console.warn(` [skip] ${m.name}: no transformation declared`);continue}let v=Le(r,b);if(!v){console.warn(` [skip] ${m.name}: transformation ${Ue(b)} not found`);continue}let _=await qa(w,o),D=[],Xe=new Set;for(let qt of _){let Wt=await Wa(qt,o,e,t),Gt=oe(Wt,y);for(let ye of Gt){let Qe=`${ye.namespace}/${ye.name}`;Xe.has(Qe)||(Xe.add(Qe),D.push(ye))}}console.log(` ${m.name}: ${D.length} instance(s) of ${y.publisher}/${y.package_}/${y.name} across ${_.length} scope(s)`);let Ze=await f.run({transformation:v,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 ke=Ae(s,h);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 Zn&&re(r,e,t,o))return r.object}function Ha(n,e,t,o){for(let r of n.statement){if(!(r instanceof Na)||!re(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 Jn(n,e,t,o){for(let r of n.statement)if(r instanceof Aa&&re(r,e,t,o)&&r.object instanceof Oa)return{publisher:r.object.subject.publisher,package_:r.object.subject.package_,name:r.object.subject.name}}function za(n){for(let e of n.statement)if(e instanceof La&&re(e,E,j,"transformation"))return Ba(e.object)}function Ba(n){let e,t,o,r;for(let s of n.statement){if(!(s instanceof Zn))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 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 Xn&&o.name===e.name&&o.namespace===t)return o}function Ue(n){return`${n.publisher}/${n.package_}@${n.version}/${n.name}`}async function qa(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 Wa(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 Ua(u,e);return o.parseKanonaks(d)}}return[]}import{Command as Ga}from"commander";import{createServer as et}from"http";import{watch as nt}from"fs";import{resolve as Ja}from"path";import{loadServerModel as tt,route as Ya,RequestRouter as Xa}from"@kanonak-protocol/sdk/server";var Fe={"Access-Control-Allow-Origin":"*"};function ot(n,e){n.writeHead(e.status,{...e.headers,...Fe}),n.end(e.body)}function rt(){return new Ga("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=Ja(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 tt(e,{publisher:n.publisher})}catch(r){console.error(`[error] ${r.message}`),process.exitCode=1;return}Za(e,t,n,o)}else Qa(e,t,n)})}function Za(n,e,t,o){let r=o,s=async a=>{let i=Date.now();r=await tt(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)${a?` (${a})`:""} in ${Date.now()-i}ms`+(c.length?` [also in workspace: ${c.join(", ")} \u2014 switch with --publisher]`:""))};if(t.watch){let a;nt(n,{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")}et(async(a,i)=>{let c="/";try{let l=new URL(a.url??"/","http://localhost");c=decodeURIComponent(l.pathname);let u=await Ya(r,c,a.headers.accept??"");ot(i,u),console.log(`${u.status} ${a.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 Qa(n,e,t){let o=new Xa({root:n});if(t.watch){let r;nt(n,{recursive:!0},(s,a)=>{!a||!String(a).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")}et(async(r,s)=>{let a="/";try{let i=new URL(r.url??"/","http://localhost");a=decodeURIComponent(i.pathname);let c=await o.handle(a,r.headers.accept??"");ot(s,c),console.log(`${c.status} ${r.method} ${a}${c.headers.Location?` -> ${c.headers.Location}`:""}`)}catch(i){s.writeHead(502,{"Content-Type":"text/plain; charset=utf-8",...Fe}),s.end(String(i?.message??i)),console.error(`502 ${a}: ${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 es}from"commander";import{resolve as ns,join as ts}from"path";import{loadLockFile as os,computeIntegrity as Me}from"@kanonak-protocol/sdk";function at(){return new es("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 as(n)})}function rs(n){let e=n.indexOf("/");if(!(e<0))return{publisher:n.slice(0,e),package_:n.slice(e+1)}}async function as(n){let e=ns(n.workspace),t=os(ts(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=rs(u);if(!d){console.error(` \u2717 ${u} \u2014 unparseable lock key`),a+=1;continue}let{publisher:g,package_:f}=d,m=o.get(g,f,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 h=await ss(u,p);h?(console.error(h),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(`
|
|
127
|
-
${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
|
|
126
|
+
`}import{Command as Yn}from"commander";import{writeFileSync as je,mkdirSync as te}from"fs";import{join as Ae,resolve as Aa,dirname as Oe}from"path";import{KanonakParser as Oa,KanonakObjectParser as Na,SubjectKanonak as Xn,ReferenceStatement as La,ReferenceKanonak as Ua,ListStatement as Fa,StringStatement as Zn,EmbeddedStatement as Ma,findDerivation as qn}from"@kanonak-protocol/sdk";import{SingleDocumentRepository as Va}from"@kanonak-protocol/sdk/uri-helpers";import{TransformationRunnerV3 as Ha}from"@kanonak-protocol/sdk/transformations";import{findSubjectsByType as oe}from"@kanonak-protocol/sdk/uri-helpers";var E="kanonak.org",j="site",Wn={publisher:"kanonak.org",package_:"formats",name:"html"},Gn={publisher:"kanonak.org",package_:"derivation",name:"default"};function Qn(){let n=new Yn("site").description("Materialize a publisher's site \u2014 every StaticPage and AggregateView in the workspace gets rendered to its declared output path under the --out directory.");return n.addCommand(za()),n}function za(){return new Yn("build").description("Walk the workspace, find every StaticPage and AggregateView, and write each materialized artifact to its declared output path under the --out directory.").option("--out <dir>","Output base directory.","./_site").action(async n=>{try{await Ba(n)}catch(e){console.error(`Error: ${e.message}`),process.exit(1)}})}async function Ba(n){let e=new Oa,t=new Na,o=await $(process.cwd(),e),r=await t.parseKanonaks(o),s=Aa(n.out);te(s,{recursive:!0});let a=await o.getAllDocumentsAsync(),i=new Set;for(let m of a){let h=m.metadata.namespace_?.toString();h&&i.add(h)}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||"")),g=oe(r,u).filter(m=>i.has(m.namespace||""));console.log(`Found ${p.length} StaticPage(s), ${d.length} ResourcePage(s), and ${g.length} AggregateView(s) in the workspace.`);let f=new Ha;for(let m of p){let h=Ne(m,E,j,"outputPath")??`${m.name}.html`,k=qn(m,Wn,Gn,r);if(!k){console.warn(` [skip] ${m.name}: no HTML/default derivation found (check class hierarchy or universal-derivations is loaded)`);continue}let y=Le(r,k.transformation);if(!y){console.warn(` [skip] ${m.name}: transformation ${Ue(k.transformation)} not found`);continue}let w=await f.run({transformation:y,instances:[m],allKanonaks:r,repository:o,parser:e,objectParser:t,outputFormat:"html"});if(w.length===0){console.warn(` [skip] ${m.name}: transformation produced no artifacts`);continue}let b=Ae(s,h);te(Oe(b),{recursive:!0}),je(b,w[0].content,"utf-8"),console.log(` wrote ${b} (StaticPage ${m.name})`)}for(let m of d){let h=Ne(m,E,j,"outputPath")??`${m.name}.html`,k=Jn(m,E,j,"pageOf");if(!k){console.warn(` [skip] ${m.name}: no pageOf declared`);continue}let y=r.find(D=>D instanceof Xn&&D.name===k.name&&(D.namespace||"").startsWith(`${k.publisher}/${k.package_}@`));if(!y){console.warn(` [skip] ${m.name}: pageOf target ${k.publisher}/${k.package_}/${k.name} not found`);continue}let w=qn(y,Wn,Gn,r);if(!w){console.warn(` [skip] ${m.name}: no derivation for target ${y.name}`);continue}let b=Le(r,w.transformation);if(!b){console.warn(` [skip] ${m.name}: transformation ${Ue(w.transformation)} not found`);continue}let v=await f.run({transformation:b,instances:[y],allKanonaks:r,repository:o,parser:e,objectParser:t,outputFormat:"html"});if(v.length===0){console.warn(` [skip] ${m.name}: transformation produced no artifacts`);continue}let _=Ae(s,h);te(Oe(_),{recursive:!0}),je(_,v[0].content,"utf-8"),console.log(` wrote ${_} (ResourcePage ${m.name} \u2192 ${y.name})`)}for(let m of g){let h=Ne(m,E,j,"outputPath");if(!h){console.warn(` [skip] ${m.name}: no outputPath declared`);continue}let k=Jn(m,E,j,"scopeClass");if(!k){console.warn(` [skip] ${m.name}: no scopeClass declared`);continue}let y={publisher:k.publisher,package_:k.package_,name:k.name},w=qa(m,E,j,"scopeSources"),b=Wa(m);if(!b){console.warn(` [skip] ${m.name}: no transformation declared`);continue}let v=Le(r,b);if(!v){console.warn(` [skip] ${m.name}: transformation ${Ue(b)} not found`);continue}let _=await Ja(w,o),D=[],Xe=new Set;for(let qt of _){let Wt=await Ya(qt,o,e,t),Gt=oe(Wt,y);for(let ye of Gt){let Qe=`${ye.namespace}/${ye.name}`;Xe.has(Qe)||(Xe.add(Qe),D.push(ye))}}console.log(` ${m.name}: ${D.length} instance(s) of ${y.publisher}/${y.package_}/${y.name} across ${_.length} scope(s)`);let Ze=await f.run({transformation:v,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 ke=Ae(s,h);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 Zn&&re(r,e,t,o))return r.object}function qa(n,e,t,o){for(let r of n.statement){if(!(r instanceof Fa)||!re(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 Jn(n,e,t,o){for(let r of n.statement)if(r instanceof La&&re(r,e,t,o)&&r.object instanceof Ua)return{publisher:r.object.subject.publisher,package_:r.object.subject.package_,name:r.object.subject.name}}function Wa(n){for(let e of n.statement)if(e instanceof Ma&&re(e,E,j,"transformation"))return Ga(e.object)}function Ga(n){let e,t,o,r;for(let s of n.statement){if(!(s instanceof Zn))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 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 Xn&&o.name===e.name&&o.namespace===t)return o}function Ue(n){return`${n.publisher}/${n.package_}@${n.version}/${n.name}`}async function Ja(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 Ya(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 Va(u,e);return o.parseKanonaks(d)}}return[]}import{Command as Xa}from"commander";import{createServer as et}from"http";import{watch as nt}from"fs";import{resolve as Za}from"path";import{loadServerModel as tt,route as Qa,RequestRouter as es}from"@kanonak-protocol/sdk/server";var Fe={"Access-Control-Allow-Origin":"*"};function ot(n,e){n.writeHead(e.status,{...e.headers,...Fe}),n.end(e.body)}function rt(){return new Xa("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=Za(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 tt(e,{publisher:n.publisher})}catch(r){console.error(`[error] ${r.message}`),process.exitCode=1;return}ns(e,t,n,o)}else ts(e,t,n)})}function ns(n,e,t,o){let r=o,s=async a=>{let i=Date.now();r=await tt(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)${a?` (${a})`:""} in ${Date.now()-i}ms`+(c.length?` [also in workspace: ${c.join(", ")} \u2014 switch with --publisher]`:""))};if(t.watch){let a;nt(n,{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")}et(async(a,i)=>{let c="/";try{let l=new URL(a.url??"/","http://localhost");c=decodeURIComponent(l.pathname);let u=await Qa(r,c,a.headers.accept??"");ot(i,u),console.log(`${u.status} ${a.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 ts(n,e,t){let o=new es({root:n});if(t.watch){let r;nt(n,{recursive:!0},(s,a)=>{!a||!String(a).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")}et(async(r,s)=>{let a="/";try{let i=new URL(r.url??"/","http://localhost");a=decodeURIComponent(i.pathname);let c=await o.handle(a,r.headers.accept??"");ot(s,c),console.log(`${c.status} ${r.method} ${a}${c.headers.Location?` -> ${c.headers.Location}`:""}`)}catch(i){s.writeHead(502,{"Content-Type":"text/plain; charset=utf-8",...Fe}),s.end(String(i?.message??i)),console.error(`502 ${a}: ${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 os}from"commander";import{resolve as rs,join as as}from"path";import{loadLockFile as ss,computeIntegrity as Me}from"@kanonak-protocol/sdk";function at(){return new os("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 cs(n)})}function is(n){let e=n.indexOf("/");if(!(e<0))return{publisher:n.slice(0,e),package_:n.slice(e+1)}}async function cs(n){let e=rs(n.workspace),t=ss(as(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=is(u);if(!d){console.error(` \u2717 ${u} \u2014 unparseable lock key`),a+=1;continue}let{publisher:g,package_:f}=d,m=o.get(g,f,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 h=await ls(u,p);h?(console.error(h),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(`
|
|
127
|
+
${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 ls(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})
|
|
128
128
|
lock: ${e.integrity}
|
|
129
|
-
origin: ${r}`}catch(t){return` \u2717 ${n} \u2014 origin fetch failed: ${t.message}`}}import{Command as
|
|
129
|
+
origin: ${r}`}catch(t){return` \u2717 ${n} \u2014 origin fetch failed: ${t.message}`}}import{Command as us}from"commander";import{resolve as ps,join as ds}from"path";import{homedir as ms}from"os";import{readFileSync as fs}from"fs";import{KanonakParser as st,KanonakObjectParser as gs,PublisherIndex as it,CredentialStore as ct,createAuthenticatedFetch as lt,FileSystemKanonakDocumentRepository as hs,Reasoner as ks,KanonakVocabulary as ys,getGlobalCachePath as ws,makeUriKey as bs,resolveDisplayValue as vs,subjectUri as $s,contextTypesOf as Ss,collectKanonakFiles as Ps}from"@kanonak-protocol/sdk";import{SearchIndex as Cs}from"@kanonak-protocol/sdk/search";function Rs(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 ut(){return new us("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:
|
|
130
130
|
\u2022 semantic-search your workspace: kanonak search -q "<keywords>"
|
|
131
131
|
\u2022 browse a publisher's catalogue: kanonak search <publisher>
|
|
132
|
-
\u2022 find instances of a class: kanonak search <publisher> --type <pub>/<pkg>/<Name>`),process.exit(1)),e.type?await
|
|
133
|
-
`)}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=
|
|
134
|
-
`);for(let u of l)console.log(` ${u.score.toFixed(3)} ${u.label}${u.type?` (${u.type})`:""}`),console.log(` ${u.uri}`)}async function
|
|
135
|
-
`);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
|
|
136
|
-
`),m.sort();for(let h of m)console.log(` ${h}`)}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
|
|
132
|
+
\u2022 find instances of a class: kanonak search <publisher> --type <pub>/<pkg>/<Name>`),process.exit(1)),e.type?await Is(n,e.type):await xs(n)})}async function _s(n){let e=ps(n.root??"."),t=new st,o;try{let u=await $(e,t);o=await new gs().parseKanonaks(u)}catch(u){console.error(`Failed to load workspace at ${e}: ${u.message}`),process.exit(1)}let r={cacheDir:ds(ms(),".kanonak","search"),onProgress:(u,p)=>process.stderr.write(`\r embedding ${u}/${p}\u2026 `)};if(!n.all){let u=new Set;for(let p of Ps(e))try{let d=t.parse(fs(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 Cs,a;try{a=await s.build(o,r),a.size>0&&!a.cached&&process.stderr.write(`
|
|
133
|
+
`)}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=vs(o,u.subject),d=$s(u.subject),g=Ss(u.subject)[0]?.name;return{uri:d?`${d.publisher}/${d.package_}/${d.name}`:u.subject.name,label:p.label,type:g??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}":
|
|
134
|
+
`);for(let u of l)console.log(` ${u.score.toFixed(3)} ${u.label}${u.type?` (${u.type})`:""}`),console.log(` ${u.uri}`)}async function xs(n){let e=new ct,t=lt(e),o=new it({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}:
|
|
135
|
+
`);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 Is(n,e){let t=Rs(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 ct,s=lt(r),a=new it({fetchFn:s}),i=new K,c=new Set,l=[];try{l=await a.listLatestPackages(n)}catch(h){console.error(`Failed to fetch publisher index for ${n}: ${h.message}`),process.exit(1)}for(let{packageName:h,version:k}of l)c.add(`${n}|${h}|${k}`);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 h of c){let[k,y,w]=h.split("|");if(!i.has(k,y,w))try{let b=await a.getPackageUrl(k,y,w),v=await s(b,k);if(!v.ok){console.error(`Warning: failed to fetch ${k}/${y}@${w}: ${v.status} ${v.statusText}`);continue}let _=await v.text();i.put(k,y,w,_)}catch(b){console.error(`Warning: failed to fetch ${k}/${y}@${w}: ${b.message}`)}}let u=new hs(ws(),!0,o),d=await new ks({vocabulary:new ys}).reason(u),g=bs(t.publisher,t.package_,t.name),m=d.getInstancesOfClass(g).filter(h=>h!==g);if(m.length===0){console.log(`No instances of ${g} found in ${n}'s catalogue.`);return}console.log(`Instances of ${g} in ${n}'s catalogue:
|
|
136
|
+
`),m.sort();for(let h of m)console.log(` ${h}`)}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 Ks,readFileSync as Ds}from"fs";import{dirname as Ts,join as Es,resolve as js}from"path";import{KanonakObjectParser as As,KanonakParser as Os,canonicalForm as Ns,canonicalHash as Ls,parseKanonakAddress as Us,pickHighestDocument as Fs,loadLockFile as Ms,LockAwareRepository as Vs}from"@kanonak-protocol/sdk";import{SingleDocumentRepository as Hs}from"@kanonak-protocol/sdk/uri-helpers";async function pt(n,e={}){let t=new Os,o=new As,{document:r,source:s}=await zs(n,t),a=qs(s),i=await $(a,t),c=Es(a,"kanonak.lock"),l=Ms(c);if(e.frozen){if(!l)throw new Error(`kanonak hash --frozen: no kanonak.lock found at ${c}. Run 'kanonak install' to generate one.`);Bs(r,l,c)}let u=l?new Vs(i,l):i,p=new Hs(r,u),d=await o.parseKanonaks(p),g=Ls(d);if(console.log(g),e.verbose){let f=Ns(d);process.stderr.write(`# canonical form for ${s}
|
|
137
137
|
`),process.stderr.write(f),process.stderr.write(`
|
|
138
|
-
`)}}async function
|
|
138
|
+
`)}}async function zs(n,e){if(n.endsWith(".kan.yml")){let i=js(n);if(!Ks(i))throw new Error(`kanonak hash: file not found: ${i}`);let c=Ds(i,"utf-8");return{document:e.parse(c),source:i}}let t=Us(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 $(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=Fs(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 Bs(n,e,t){let o=new Set(["kanonak.org/core-kanonak"]);for(let s of n.metadata.allImports??[])o.add(`${s.publisher??"kanonak.org"}/${s.packageName}`);let r=[...o].filter(s=>!e.packages[s]);if(r.length>0)throw new Error(`kanonak hash --frozen: kanonak.lock (${t}) is missing pins for: ${r.join(", ")}. Run 'kanonak install' to refresh the lock.`)}function qs(n){return n.endsWith(".kan.yml")?N(Ts(n)):process.cwd()}import{Command as dt}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 mt(n,e,t){for(let o of e){let r=new dt(o.commandName).description(o.description.trim());for(let s of o.commands){let a=r.command(Ws(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=Gs(i);await Js(t,o,s,i,c)})}n.addCommand(r)}}function Ws(n){let e=n.arguments.filter(t=>!t.isOption).map(t=>t.required?`<${t.argumentName}>`:`[${t.argumentName}]`);return[n.subcommandName,...e].join(" ")}function Gs(n){for(let e=n.length-1;e>=0;e--)if(n[e]&&typeof n[e]=="object"&&!(n[e]instanceof dt))return n[e];return{}}async function Js(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 ft,readFileSync as Ys,statSync as gt}from"fs";import{resolve as Xs}from"path";import{KanonakObjectParser as Zs,PublisherIndex as ze,PublisherConfigResolver as Qs,formatVersion as ht,pickHighestDocument as ei}from"@kanonak-protocol/sdk";import{SingleDocumentRepository as kt}from"@kanonak-protocol/sdk/uri-helpers";import{uriKey as G,findSubjectsByType as yt}from"@kanonak-protocol/sdk/uri-helpers";var ae=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 Zs;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 g=ei(u,{requestedVersion:c??void 0});if(g.chosen){let f=g.chosen.metadata.namespace_;(!f||!f.version)&&(console.error(`Document for ${a}/${i} is missing namespace metadata.`),process.exit(1));let m=ht(f.version);this.fileCache.put(a,i,m,this.parser.save(g.chosen)),await this.deployFromDoc(e,g.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 g=await this.publisherIndex.getPackageUrl(a,i,p),f=await this.fetchFn(g,a);f.ok||(f.status===404?(console.error(`Package ${a}/${i}@${p} not found at ${g}.`),console.error(`The publisher index lists this version but the file is missing \u2014 it may have been unpublished. Try \`kanonak ${e.commandName} search\` to see the current catalogue.`)):console.error(`Failed to fetch ${g} (${f.status} ${f.statusText}).`),process.exit(1)),d=await f.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")||ft(e)&>(e).isFile()))return;let o=Xs(e);(!ft(o)||!gt(o).isFile())&&(console.error(`Local file not found: ${e}`),process.exit(1));let r=Ys(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:ht(a.version)}}async deployFromDoc(e,t,o,r,s,a,i,c){let l=new kt(t,this.repository),u=await this.objectParser.parseKanonaks(l),p=wt(e.managesTypeKey);p||(console.error(`Capability "${e.commandName}" has no resolved managesType.`),process.exit(1));let d=yt(u,p);d.length===0&&(console.error(`${i} does not contain any ${G(p)} instances.`),process.exit(1));let g=d;if(a&&(g=d.filter(h=>h.name===a),g.length===0)){console.error(`Instance "${a}" not found in ${i}.`),console.error(""),console.error(`Available ${G(p)} instance(s):`);for(let h of d)console.error(` - ${h.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 f=a?`${a} from ${i}`:`${g.length} ${G(p)} instance(s) from ${i}`;console.log(`Installing ${f}...`);let m=this.handlerRegistry.get(e.deploymentTargetKey);m?await m.deploy({instances:g,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:ni(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:
|
|
139
139
|
`);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.":`
|
|
140
140
|
Updated ${i} instance(s).`)}async search(e,t){let o=t.publisher??"kanonak.org",r=wt(e.managesTypeKey);if(!r){console.error("Capability has no resolved managesType; nothing to search for.");return}console.log(`Searching ${o} for ${G(r)} instances...
|
|
141
|
-
`);let s=new
|
|
142
|
-
`);let f=new Map;for(let m of d){let h=`${m.publisher}/${m.package_}@${m.version}`,k=f.get(h);k?k.push(m):f.set(h,[m])}for(let[m,h]of f){let k=h[0],y=`${k.publisher}/${k.package_}`,w=h.length===1;console.log(` ${m}`),console.log(` ${h.length} skill${w?"":"s"}:`);for(let b of h)console.log(` - ${b.subject.name}`);if(console.log(""),w)console.log(" install:"),console.log(` kanonak ${e.commandName} add ${y}/${k.subject.name}`);else{console.log(" install one of them:");for(let b of h)console.log(` kanonak ${e.commandName} add ${y}/${b.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 wt(n){if(!n)return;let e=n.split("/");if(e.length===3)return{publisher:e[0],package_:e[1],name:e[2]}}function
|
|
143
|
-
`;function le(n){let e=It(n,Dt);if(!
|
|
144
|
-
`;function fe(n){let e=Mt(n,Ht);if(!
|
|
141
|
+
`);let s=new Qs,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,h]of u){let k=[...h].sort((y,w)=>{let b=ze.parseVersion(y),v=ze.parseVersion(w);return!b||!v?0:b.major!==v.major?v.major-b.major:b.minor!==v.minor?v.minor-b.minor:v.patch-b.patch});p.set(m,k[0])}let d=[],g=0;for(let[m,h]of p){let k=this.fileCache.get(o,m,h);if(!k)try{let y=await this.publisherIndex.getPackageUrl(o,m,h),w=await this.fetchFn(y,o);if(!w.ok)continue;k=await w.text(),this.fileCache.put(o,m,h,k)}catch{continue}try{let y=this.parser.parse(k),w=new kt(y,this.repository),b=await this.objectParser.parseKanonaks(w),v=yt(b,r);for(let _ of v)d.push({publisher:o,package_:m,version:h,subject:_});g++}catch{continue}}if(d.length===0){console.log(`No ${G(r)} instances found across ${g} package(s).`);return}console.log(`Found ${d.length} ${G(r)} instance(s) in ${g} package(s):
|
|
142
|
+
`);let f=new Map;for(let m of d){let h=`${m.publisher}/${m.package_}@${m.version}`,k=f.get(h);k?k.push(m):f.set(h,[m])}for(let[m,h]of f){let k=h[0],y=`${k.publisher}/${k.package_}`,w=h.length===1;console.log(` ${m}`),console.log(` ${h.length} skill${w?"":"s"}:`);for(let b of h)console.log(` - ${b.subject.name}`);if(console.log(""),w)console.log(" install:"),console.log(` kanonak ${e.commandName} add ${y}/${k.subject.name}`);else{console.log(" install one of them:");for(let b of h)console.log(` kanonak ${e.commandName} add ${y}/${b.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 wt(n){if(!n)return;let e=n.split("/");if(e.length===3)return{publisher:e[0],package_:e[1],name:e[2]}}function ni(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=ti(t,o);return i===0?100:i<=2?Math.max(1,20-i*5):0}function ti(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 se=class{handlers=new Map;register(e,t){this.handlers.set(e,t)}get(e){return this.handlers.get(e)??null}};import{mkdirSync as fi,rmSync as gi,existsSync as ue,readdirSync as hi,writeFileSync as ki}from"fs";import{join as pe}from"path";import{KanonakObjectParser as yi,KanonakParser as wi,computeIntegrity as bi,compareVersions as vi}from"@kanonak-protocol/sdk";import{findSubjectsByType as $i}from"@kanonak-protocol/sdk/uri-helpers";import{SingleDocumentRepository as Si}from"@kanonak-protocol/sdk/uri-helpers";import{TransformationRunnerV3 as Pi}from"@kanonak-protocol/sdk/transformations";import{TX_V3 as Ci}from"@kanonak-protocol/sdk/transformations";import{join as Be}from"path";import{homedir as bt}from"os";import{KanonakObjectParser as oi}from"@kanonak-protocol/sdk";import{SingleDocumentRepository as ri}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",St={publisher:U,package_:F,name:"Client"},Pt={publisher:U,package_:F,name:"clientId"},ai={publisher:U,package_:F,name:"projectSkillDir"},si={publisher:U,package_:F,name:"userSkillDir"},ii={publisher:U,package_:F,name:"skillFileName"},Ct="agents";async function Q(n,e){let t=(n.client??Rt()??Ct).toLowerCase(),o=n.scope??"project",r=await xt(t,e);if(!r){let i=await ci(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=ie(r,o==="user"?si:ai);if(!a)throw new Error(`Client "${t}" has no ${o==="user"?"userSkillDir":"projectSkillDir"} declared.`);return li(a)}async function ce(n,e,t){let o=await Q(e,t);return Be(o,n)}async function qe(n,e){let t=(n.client??Rt()??Ct).toLowerCase(),o=await xt(t,e);return o?ie(o,ii)??"SKILL.md":"SKILL.md"}function Rt(){if(process.env.CLAUDE_CODE||process.env.CLAUDE_PROJECT_DIR)return"claude-code"}var vt=new WeakMap;async function _t(n){let e=vt.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 oi,a=new ri(r,n),i=await s.parseKanonaks(a);return vt.set(n,i),i}async function xt(n,e){let t=await _t(e),o=$t(t,St);for(let r of o)if(ie(r,Pt)===n)return r}async function ci(n){let e=await _t(n),t=$t(e,St),o=[];for(let r of t){let s=ie(r,Pt);s&&o.push(s)}return o}function li(n){return n.startsWith("~/")?Be(bt(),n.slice(2)):n==="~"?bt():n.startsWith("/")||/^[A-Za-z]:[\\/]/.test(n)?n:Be(process.cwd(),n)}import{readFileSync as ui,writeFileSync as pi,existsSync as di}from"fs";import{join as It}from"path";import Kt from"js-yaml";var Dt="skills.lock",mi=`# This file is generated by Kanonak CLI. Do not edit manually.
|
|
143
|
+
`;function le(n){let e=It(n,Dt);if(!di(e))return{version:"1",lastUpdated:new Date().toISOString(),skills:{}};let t=ui(e,"utf-8"),o=Kt.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=It(n,Dt),r=Kt.dump(e,{lineWidth:-1,sortKeys:!1,quotingType:'"'});pi(o,mi+r,"utf-8")}var Tt="kanonak.org",Et="skill-to-skill-md",de=class{parser=new wi;objectParser=new yi;runner=new Pi;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 Ri(r,this.objectParser);if(!a){console.error(`Cannot deploy: ${Tt}/${Et}@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 Q(s,r),l=await qe(s,r),u=le(c),p=t[0].namespace,{publisher:d,package_:g,version:f}=_i(p);for(let m of i){let h=await ce(m.fileName,s,r),k=ue(pe(h,l));fi(h,{recursive:!0}),ki(pe(h,l),m.content,"utf-8"),u.skills[m.fileName]={publisher:d,package_:g,version:f,resolved:d?`kanonak://${d}/${g}@${f}`:"",integrity:bi(m.content)},console.log(` ${k?"Updated":"Installed"} skill "${m.fileName}" \u2192 ${h}`)}We(c,u)}async undeploy(e,t){let{repository:o,options:r}=t,s=await ce(e,r,o);ue(s)||(console.error(`Skill "${e}" is not installed at ${s}`),process.exit(1)),gi(s,{recursive:!0,force:!0});let a=await Q(r,o),i=le(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 Q(o,t),s=le(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 ce(c,o,t)});let i=await qe(o,t);if(ue(r))try{let c=hi(r,{withFileTypes:!0});for(let l of c){if(!l.isDirectory()||s.skills[l.name])continue;let u=pe(r,l.name,i);ue(u)&&a.push({name:l.name,publisher:"",package_:"",version:"",path:pe(r,l.name)})}}catch{}return a}};async function Ri(n,e){let t=await n.getDocumentsByNamespaceAsync(Tt,Et);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:vi(i,a)});for(let r of o){let s=new Si(r,n),a=await e.parseKanonaks(s),i=$i(a,Ci.InstanceTransformation);if(i[0])return i[0]}}function _i(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 Hi,rmSync as zi,existsSync as Ye,readdirSync as Bi,writeFileSync as qi,statSync as Wi}from"fs";import{join as ge}from"path";import{KanonakObjectParser as Gi,KanonakParser as Ji,computeIntegrity as Yi}from"@kanonak-protocol/sdk";import{findSubjectsByType as Xi}from"@kanonak-protocol/sdk/uri-helpers";import{SingleDocumentRepository as Zi}from"@kanonak-protocol/sdk/uri-helpers";import{TransformationRunnerV3 as Qi}from"@kanonak-protocol/sdk/transformations";import{TX_V3 as ec}from"@kanonak-protocol/sdk/transformations";import{join as jt}from"path";import{homedir as At}from"os";import{KanonakObjectParser as xi}from"@kanonak-protocol/sdk";import{SingleDocumentRepository as Ii}from"@kanonak-protocol/sdk/uri-helpers";import{findSubjectsByType as Nt,getStringValue as Ge,getReferenceUri as Ki}from"@kanonak-protocol/sdk/uri-helpers";var M="kanonak.org",V="agent-skills",Lt={publisher:M,package_:V,name:"Client"},Ut={publisher:M,package_:V,name:"clientId"},Di={publisher:M,package_:V,name:"projectAgentDir"},Ti={publisher:M,package_:V,name:"userAgentDir"},Ei={publisher:M,package_:V,name:"agentFileFormat"},ji="agents";function Ai(){if(process.env.CLAUDE_CODE||process.env.CLAUDE_PROJECT_DIR)return"claude-code"}async function me(n,e){let t=(n.client??Ai()??ji).toLowerCase(),o=n.scope??"project",r=await Oi(t,e);if(!r){let u=await Ni(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"?Ti:Di);if(!a)throw new Error(`Client "${t}" has no ${o==="user"?"userAgentDir":"projectAgentDir"} declared.`);let c=Ki(r,Ei)?.name==="toml"?"toml":"markdown-frontmatter",l=c==="toml"?".toml":".md";return{agentsDir:Li(a),format:c,fileExtension:l}}var Ot=new WeakMap;async function Ft(n){let e=Ot.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 xi,a=new Ii(r,n),i=await s.parseKanonaks(a);return Ot.set(n,i),i}async function Oi(n,e){let t=await Ft(e),o=Nt(t,Lt);for(let r of o)if(Ge(r,Ut)===n)return r}async function Ni(n){let e=await Ft(n),t=Nt(e,Lt),o=[];for(let r of t){let s=Ge(r,Ut);s&&o.push(s)}return o}function Li(n){return n.startsWith("~/")?jt(At(),n.slice(2)):n==="~"?At():n.startsWith("/")||/^[A-Za-z]:[\\/]/.test(n)?n:jt(process.cwd(),n)}import{readFileSync as Ui,writeFileSync as Fi,existsSync as Mi}from"fs";import{join as Mt}from"path";import Vt from"js-yaml";var Ht="agents.lock",Vi=`# This file is generated by Kanonak CLI. Do not edit manually.
|
|
144
|
+
`;function fe(n){let e=Mt(n,Ht);if(!Mi(e))return{version:"1",lastUpdated:new Date().toISOString(),agents:{}};let t=Ui(e,"utf-8"),o=Vt.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=Mt(n,Ht),r=Vt.dump(e,{lineWidth:-1,sortKeys:!1,quotingType:'"'});Fi(o,Vi+r,"utf-8")}var zt="kanonak.org",Bt="agent-to-agent-file",he=class{parser=new Ji;objectParser=new Gi;runner=new Qi;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 me(s,r),l=await nc(r,this.objectParser);if(!l){console.error(`Cannot deploy: ${zt}/${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}Hi(a,{recursive:!0});let d=fe(a),g=t[0].namespace,{publisher:f,package_:m,version:h}=oc(g);for(let k of p){let y=`${k.fileName}${c}`,w=ge(a,y),b=Ye(w);qi(w,k.content,"utf-8"),d.agents[k.fileName]={publisher:f,package_:m,version:h,resolved:f?`kanonak://${f}/${m}@${h}`:"",integrity:Yi(k.content),fileName:y},console.log(` ${b?"Updated":"Installed"} agent "${k.fileName}" \u2192 ${w}`)}Je(a,d)}async undeploy(e,t){let{repository:o,options:r}=t,{agentsDir:s}=await me(r,o),a=fe(s),i=a.agents[e];i||(console.error(`Agent "${e}" is not installed at ${s}`),process.exit(1));let c=ge(s,i.fileName);Ye(c)&&zi(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 me(o,t),s=fe(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:ge(r,c.fileName)});if(Ye(r))try{let i=Bi(r,{withFileTypes:!0});for(let c of i){if(!c.isFile()||c.name==="agents.lock")continue;let l=ge(r,c.name),u=tc(c.name);if(!s.agents[u]){try{if(!Wi(l).isFile())continue}catch{continue}a.push({name:u,publisher:"",package_:"",version:"",path:l})}}}catch{}return a}};async function nc(n,e){let t=await n.getDocumentsByNamespaceAsync(zt,Bt);if(t.length===0)return;let o=new Zi(t[0],n),r=await e.parseKanonaks(o);return Xi(r,ec.InstanceTransformation)[0]}function tc(n){let e=n.lastIndexOf(".");return e===-1?n:n.substring(0,e)}function oc(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 mc=ic(sc(import.meta.url)),fc=JSON.parse(ac(cc(mc,"..","package.json"),"utf-8")),R=new rc;R.name("kanonak").description("Kanonak Protocol CLI - Validate and resolve Kanonak ontology packages").version(fc.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.").option("--frozen","Resolve identity strictly through kanonak.lock; error if the lock or any needed pin is missing.").action(async(n,e)=>{await pt(n,e)});R.addCommand(In());R.addCommand(On());R.addCommand(Vn());R.addCommand(Hn());R.addCommand(Bn());R.addCommand(Qn());R.addCommand(rt());R.addCommand(ut());R.addCommand(at());async function gc(){try{let n=new K,e=new lc,t=new pc,o=dc(t),r=new uc({fetchFn:o}),s=await $(process.cwd(),e),a=new se;a.register("kanonak.org/capabilities/agent-skill-deployment",new de),a.register("kanonak.org/agent-capabilities/agent-instance-deployment",new he);let i=await Rn(n,e,s),c=new ae(n,e,r,o,a,s);mt(R,i,c)}catch{}}await gc();R.parse();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kanonak-protocol/cli",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.7.0",
|
|
4
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",
|
|
@@ -35,8 +35,8 @@
|
|
|
35
35
|
"semantic-web"
|
|
36
36
|
],
|
|
37
37
|
"dependencies": {
|
|
38
|
-
"@kanonak-protocol/sdk": "^4.
|
|
39
|
-
"@kanonak-protocol/types": "^4.
|
|
38
|
+
"@kanonak-protocol/sdk": "^4.7.0",
|
|
39
|
+
"@kanonak-protocol/types": "^4.7.0",
|
|
40
40
|
"commander": "^13.0.0",
|
|
41
41
|
"js-yaml": "^4.1.1"
|
|
42
42
|
},
|