@kanonak-protocol/cli 2.1.0 → 2.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,201 @@
1
+ Apache License
2
+ Version 2.0, January 2004
3
+ http://www.apache.org/licenses/
4
+
5
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6
+
7
+ 1. Definitions.
8
+
9
+ "License" shall mean the terms and conditions for use, reproduction,
10
+ and distribution as defined by Sections 1 through 9 of this document.
11
+
12
+ "Licensor" shall mean the copyright owner or entity authorized by
13
+ the copyright owner that is granting the License.
14
+
15
+ "Legal Entity" shall mean the union of the acting entity and all
16
+ other entities that control, are controlled by, or are under common
17
+ control with that entity. For the purposes of this definition,
18
+ "control" means (i) the power, direct or indirect, to cause the
19
+ direction or management of such entity, whether by contract or
20
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
21
+ outstanding shares, or (iii) beneficial ownership of such entity.
22
+
23
+ "You" (or "Your") shall mean an individual or Legal Entity
24
+ exercising permissions granted by this License.
25
+
26
+ "Source" form shall mean the preferred form for making modifications,
27
+ including but not limited to software source code, documentation
28
+ source, and configuration files.
29
+
30
+ "Object" form shall mean any form resulting from mechanical
31
+ transformation or translation of a Source form, including but
32
+ not limited to compiled object code, generated documentation,
33
+ and conversions to other media types.
34
+
35
+ "Work" shall mean the work of authorship, whether in Source or
36
+ Object form, made available under the License, as indicated by a
37
+ copyright notice that is included in or attached to the work
38
+ (an example is provided in the Appendix below).
39
+
40
+ "Derivative Works" shall mean any work, whether in Source or Object
41
+ form, that is based on (or derived from) the Work and for which the
42
+ editorial revisions, annotations, elaborations, or other modifications
43
+ represent, as a whole, an original work of authorship. For the purposes
44
+ of this License, Derivative Works shall not include works that remain
45
+ separable from, or merely link (or bind by name) to the interfaces of,
46
+ the Work and Derivative Works thereof.
47
+
48
+ "Contribution" shall mean any work of authorship, including
49
+ the original version of the Work and any modifications or additions
50
+ to that Work or Derivative Works thereof, that is intentionally
51
+ submitted to Licensor for inclusion in the Work by the copyright owner
52
+ or by an individual or Legal Entity authorized to submit on behalf of
53
+ the copyright owner. For the purposes of this definition, "submitted"
54
+ means any form of electronic, verbal, or written communication sent
55
+ to the Licensor or its representatives, including but not limited to
56
+ communication on electronic mailing lists, source code control systems,
57
+ and issue tracking systems that are managed by, or on behalf of, the
58
+ Licensor for the purpose of discussing and improving the Work, but
59
+ excluding communication that is conspicuously marked or otherwise
60
+ designated in writing by the copyright owner as "Not a Contribution."
61
+
62
+ "Contributor" shall mean Licensor and any individual or Legal Entity
63
+ on behalf of whom a Contribution has been received by Licensor and
64
+ subsequently incorporated within the Work.
65
+
66
+ 2. Grant of Copyright License. Subject to the terms and conditions of
67
+ this License, each Contributor hereby grants to You a perpetual,
68
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
69
+ copyright license to reproduce, prepare Derivative Works of,
70
+ publicly display, publicly perform, sublicense, and distribute the
71
+ Work and such Derivative Works in Source or Object form.
72
+
73
+ 3. Grant of Patent License. Subject to the terms and conditions of
74
+ this License, each Contributor hereby grants to You a perpetual,
75
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
76
+ (except as stated in this section) patent license to make, have made,
77
+ use, offer to sell, sell, import, and otherwise transfer the Work,
78
+ where such license applies only to those patent claims licensable
79
+ by such Contributor that are necessarily infringed by their
80
+ Contribution(s) alone or by combination of their Contribution(s)
81
+ with the Work to which such Contribution(s) was submitted. If You
82
+ institute patent litigation against any entity (including a
83
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
84
+ or a Contribution incorporated within the Work constitutes direct
85
+ or contributory patent infringement, then any patent licenses
86
+ granted to You under this License for that Work shall terminate
87
+ as of the date such litigation is filed.
88
+
89
+ 4. Redistribution. You may reproduce and distribute copies of the
90
+ Work or Derivative Works thereof in any medium, with or without
91
+ modifications, and in Source or Object form, provided that You
92
+ meet the following conditions:
93
+
94
+ (a) You must give any other recipients of the Work or
95
+ Derivative Works a copy of this License; and
96
+
97
+ (b) You must cause any modified files to carry prominent notices
98
+ stating that You changed the files; and
99
+
100
+ (c) You must retain, in the Source form of any Derivative Works
101
+ that You distribute, all copyright, patent, trademark, and
102
+ attribution notices from the Source form of the Work,
103
+ excluding those notices that do not pertain to any part of
104
+ the Derivative Works; and
105
+
106
+ (d) If the Work includes a "NOTICE" text file as part of its
107
+ distribution, then any Derivative Works that You distribute must
108
+ include a readable copy of the attribution notices contained
109
+ within such NOTICE file, excluding those notices that do not
110
+ pertain to any part of the Derivative Works, in at least one
111
+ of the following places: within a NOTICE text file distributed
112
+ as part of the Derivative Works; within the Source form or
113
+ documentation, if provided along with the Derivative Works; or,
114
+ within a display generated by the Derivative Works, if and
115
+ wherever such third-party notices normally appear. The contents
116
+ of the NOTICE file are for informational purposes only and
117
+ do not modify the License. You may add Your own attribution
118
+ notices within Derivative Works that You distribute, alongside
119
+ or as an addendum to the NOTICE text from the Work, provided
120
+ that such additional attribution notices cannot be construed
121
+ as modifying the License.
122
+
123
+ You may add Your own copyright statement to Your modifications and
124
+ may provide additional or different license terms and conditions
125
+ for use, reproduction, or distribution of Your modifications, or
126
+ for any such Derivative Works as a whole, provided Your use,
127
+ reproduction, and distribution of the Work otherwise complies with
128
+ the conditions stated in this License.
129
+
130
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
131
+ any Contribution intentionally submitted for inclusion in the Work
132
+ by You to the Licensor shall be under the terms and conditions of
133
+ this License, without any additional terms or conditions.
134
+ Notwithstanding the above, nothing herein shall supersede or modify
135
+ the terms of any separate license agreement you may have executed
136
+ with Licensor regarding such Contributions.
137
+
138
+ 6. Trademarks. This License does not grant permission to use the trade
139
+ names, trademarks, service marks, or product names of the Licensor,
140
+ except as required for reasonable and customary use in describing the
141
+ origin of the Work and reproducing the content of the NOTICE file.
142
+
143
+ 7. Disclaimer of Warranty. Unless required by applicable law or
144
+ agreed to in writing, Licensor provides the Work (and each
145
+ Contributor provides its Contributions) on an "AS IS" BASIS,
146
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
147
+ implied, including, without limitation, any warranties or conditions
148
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
149
+ PARTICULAR PURPOSE. You are solely responsible for determining the
150
+ appropriateness of using or redistributing the Work and assume any
151
+ risks associated with Your exercise of permissions under this License.
152
+
153
+ 8. Limitation of Liability. In no event and under no legal theory,
154
+ whether in tort (including negligence), contract, or otherwise,
155
+ unless required by applicable law (such as deliberate and grossly
156
+ negligent acts) or agreed to in writing, shall any Contributor be
157
+ liable to You for damages, including any direct, indirect, special,
158
+ incidental, or consequential damages of any character arising as a
159
+ result of this License or out of the use or inability to use the
160
+ Work (including but not limited to damages for loss of goodwill,
161
+ work stoppage, computer failure or malfunction, or any and all
162
+ other commercial damages or losses), even if such Contributor
163
+ has been advised of the possibility of such damages.
164
+
165
+ 9. Accepting Warranty or Additional Liability. While redistributing
166
+ the Work or Derivative Works thereof, You may choose to offer,
167
+ and charge a fee for, acceptance of support, warranty, indemnity,
168
+ or other liability obligations and/or rights consistent with this
169
+ License. However, in accepting such obligations, You may act only
170
+ on Your own behalf and on Your sole responsibility, not on behalf
171
+ of any other Contributor, and only if You agree to indemnify,
172
+ defend, and hold each Contributor harmless for any liability
173
+ incurred by, or claims asserted against, such Contributor by reason
174
+ of your accepting any such warranty or additional liability.
175
+
176
+ END OF TERMS AND CONDITIONS
177
+
178
+ APPENDIX: How to apply the Apache License to your work.
179
+
180
+ To apply the Apache License to your work, attach the following
181
+ boilerplate notice, with the fields enclosed by brackets "[]"
182
+ replaced with your own identifying information. (Don't include
183
+ the brackets!) The text should be enclosed in the appropriate
184
+ comment syntax for the file format. We also recommend that a
185
+ file or class name and description of purpose be included on the
186
+ same "printed page" as the copyright notice for easier
187
+ identification within third-party archives.
188
+
189
+ Copyright 2024-2026 Genval LLC
190
+
191
+ Licensed under the Apache License, Version 2.0 (the "License");
192
+ you may not use this file except in compliance with the License.
193
+ You may obtain a copy of the License at
194
+
195
+ http://www.apache.org/licenses/LICENSE-2.0
196
+
197
+ Unless required by applicable law or agreed to in writing, software
198
+ distributed under the License is distributed on an "AS IS" BASIS,
199
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
200
+ See the License for the specific language governing permissions and
201
+ limitations under the License.
@@ -27,8 +27,41 @@ export declare class GenericCapabilityHandler {
27
27
  * type. If the parsed reference includes an `instanceName`, only
28
28
  * that one instance is deployed; otherwise every matching instance
29
29
  * in the package is deployed.
30
+ *
31
+ * Resolution order for `packageRef`:
32
+ * 1. Literal local file path (`./skill.kan.yml`, `C:\…\skill.kan.yml`,
33
+ * or any existing path ending in `.kan.yml`) — read it directly
34
+ * through the SDK parser, no workspace/cache/HTTP lookup.
35
+ * 2. `publisher/package[@version][/instance]` URI — resolved
36
+ * against the workspace + global cache repository tiers first,
37
+ * falling back to the publisher's HTTP origin only when nothing
38
+ * local matches. This makes `<cap> add` work for skills/agents
39
+ * that the user has authored locally and not yet published.
30
40
  */
31
41
  add(capability: LoadedCapability, packageRef: string, options: Record<string, string>): Promise<void>;
42
+ /**
43
+ * Try to load `packageRef` as a literal local file path. Recognizes
44
+ * any string that points to an existing file (typically with a
45
+ * `.kan.yml` suffix). Returns `undefined` for anything that doesn't
46
+ * look like a path — the caller falls back to URI-form parsing.
47
+ *
48
+ * Parsing goes through `KanonakParser.parse`; namespace metadata is
49
+ * pulled directly from the parsed document so publisher/package/
50
+ * version come from the file's own declarations rather than any
51
+ * heuristic on the path.
52
+ */
53
+ private tryLoadFromLocalFile;
54
+ /**
55
+ * Shared deployment path used by both the URI-form `add()` and the
56
+ * local-file-path form. Parses the document through the SDK object
57
+ * model, finds matching instances of the capability's managed type,
58
+ * and dispatches to the deployment handler keyed by deploymentTarget.
59
+ *
60
+ * `description` is the human-readable source label (a package URI
61
+ * or `local file <path>`) used in the user-facing output and error
62
+ * messages — keeping the URI flow's wording stable.
63
+ */
64
+ private deployFromDoc;
32
65
  /**
33
66
  * On a "package not found" error, scan the publisher index for
34
67
  * approximate name matches and print up to 5 suggestions. Helps
package/dist/index.js CHANGED
@@ -1,95 +1,94 @@
1
1
  #!/usr/bin/env node
2
- import{Command as Ys}from"commander";import{readFileSync as Zs}from"fs";import{fileURLToPath as Qs}from"url";import{dirname as ei,join as ni}from"path";import{KanonakParser as ti,PublisherIndex as oi,CredentialStore as ri,createAuthenticatedFetch as ai}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 fn}from"@kanonak-protocol/sdk";import{readFileSync as qt,readdirSync as Gt}from"fs";import{join as Wt,dirname as Xt,basename as pn}from"path";import{InMemoryKanonakDocumentRepository as Jt,FileSystemKanonakDocumentRepository as Yt,HttpKanonakDocumentRepository as Zt,getGlobalCachePath as Qt}from"@kanonak-protocol/sdk";import{mkdirSync as Ft,readFileSync as dn,writeFileSync as mn,existsSync as Be,appendFileSync as Mt}from"fs";import{join as Bt,dirname as Vt,isAbsolute as Ht}from"path";import{getGlobalCachePath as zt}from"@kanonak-protocol/sdk";var T=class{constructor(e=zt()){this.cacheDir=e;this.isProjectLocal=!Ht(e)}cacheDir;gitignoreChecked=!1;isProjectLocal;get(e,t,o){let r=this.getPath(e,t,o);return Be(r)?dn(r,"utf-8"):null}put(e,t,o,r){let a=this.getPath(e,t,o);Ft(Vt(a),{recursive:!0}),mn(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(dn(e,"utf-8").split(`
3
- `).some(r=>r.trim()===t||r.trim()===t+"/"))return;Mt(e,`
2
+ import{Command as ui}from"commander";import{readFileSync as di}from"fs";import{fileURLToPath as mi}from"url";import{dirname as pi,join as fi}from"path";import{KanonakParser as gi,PublisherIndex as hi,CredentialStore as ki,createAuthenticatedFetch as yi}from"@kanonak-protocol/sdk";import{readFileSync as co,statSync as lo}from"fs";import{resolve as uo,dirname as mo}from"path";import{KanonakParser as po,KanonakObjectValidator as fo,ValidationSeverity as gn}from"@kanonak-protocol/sdk";import{readFileSync as eo,readdirSync as no}from"fs";import{join as to,dirname as oo,basename as fn}from"path";import{InMemoryKanonakDocumentRepository as ro,FileSystemKanonakDocumentRepository as ao,HttpKanonakDocumentRepository as so,getGlobalCachePath as io}from"@kanonak-protocol/sdk";import{mkdirSync as Wt,readFileSync as mn,writeFileSync as pn,existsSync as Be,appendFileSync as Xt}from"fs";import{join as Jt,dirname as Yt,isAbsolute as Zt}from"path";import{getGlobalCachePath as Qt}from"@kanonak-protocol/sdk";var T=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)?mn(r,"utf-8"):null}put(e,t,o,r){let a=this.getPath(e,t,o);Wt(Yt(a),{recursive:!0}),pn(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(mn(e,"utf-8").split(`
3
+ `).some(r=>r.trim()===t||r.trim()===t+"/"))return;Xt(e,`
4
4
  ${t}/
5
- `)}else mn(e,`${t}/
6
- `)}getPath(e,t,o){return Bt(this.cacheDir,e,`${t}@${o}.kan.yml`)}};function ie(n){let e=n;for(;;){let t=Xt(e);if(t===e)break;if(pn(e).includes(".")||pn(t).includes(".")){e=t;continue}break}return e}function he(n,e){for(let t of Gt(n,{withFileTypes:!0})){let o=Wt(n,t.name);t.isDirectory()&&t.name!=="node_modules"&&t.name!==".kanonak"?he(o,e):t.name.endsWith(".kan.yml")&&e.push(o)}}var Ve=class{repos;constructor(...e){this.repos=e}async getHighestCompatibleVersionAsync(e,t){for(let o of this.repos)try{let r=await o.getHighestCompatibleVersionAsync(e,t);if(r)return r}catch{}return null}async getAllDocumentsAsync(){let e=[];for(let t of this.repos)try{e.push(...await t.getAllDocumentsAsync())}catch{}return e}async getDocumentAsync(e){for(let t of this.repos)try{let o=await t.getDocumentAsync(e);if(o)return o}catch{}return null}async getDocumentsByNamespaceAsync(e,t){for(let o of this.repos)try{let r=await o.getDocumentsByNamespaceAsync(e,t);if(r.length>0)return r}catch{}return[]}async saveDocumentAsync(e,t){await this.repos[0].saveDocumentAsync(e,t)}async deleteDocumentAsync(e){await this.repos[0].deleteDocumentAsync(e)}async clearNamespaceAsync(e,t){await this.repos[0].clearNamespaceAsync(e,t)}async getAllDocumentReferencesAsync(){return this.repos[0].getAllDocumentReferencesAsync()}async getDocumentContentAsync(e){for(let t of this.repos)try{let o=await t.getDocumentContentAsync(e);if(o)return o}catch{}return null}async getDocumentUriAsync(e){for(let t of this.repos)try{let o=await t.getDocumentUriAsync(e);if(o)return o}catch{}return null}};async function j(n,e){let t=[];he(n,t);let o=new Jt(e);for(let c of t)try{let i=qt(c,"utf-8"),l=e.parse(i),u=l.metadata.namespace_;if(u){let d=`${u.publisher}/${u.package_}@${u.version}`;await o.saveDocumentAsync(l,d)}}catch{}let r=new Yt(Qt(),!0,e),a=new T,s=new Zt({getFromCache:(c,i,l)=>a.get(c,i,l),onFetch:(c,i,l,u)=>a.put(c,i,l,u)});return new Ve(o,r,s)}async function gn(n){let e=to(n),t=no(e),o=t.isDirectory()?ie(e):ie(oo(e)),r=new ro,a=new ao(r),s=await j(o,r),c=[];if(t.isDirectory()?he(e,c):c.push(e),c.length===0){console.log("No .kan.yml files found.");return}let i=0,l=0;for(let u of c){let d=eo(u,"utf-8"),p=r.parseWithErrors(d);if(p.errors&&p.errors.length>0){console.log(`
7
- ${u}:`);for(let h of p.errors)console.log(` ERROR (parse): ${h.message} [line ${h.line}:${h.column}]`),i++;continue}let y=p.document;if(!y){console.log(`
8
- ${u}:`),console.log(" ERROR: Failed to parse document"),i++;continue}let b=await a.validateAsync(y,s),f=b.errors.filter(h=>h.severity===fn.Error),k=b.errors.filter(h=>h.severity===fn.Warning);if(f.length>0||k.length>0){let h=y.metadata.namespace_,$=h?`${h.publisher}/${h.package_}@${h.version}`:u;console.log(`
9
- ${$}:`);for(let w of f)console.log(` ERROR: ${w.message}`),w.suggestion&&console.log(` -> ${w.suggestion}`);for(let w of k)console.log(` WARN: ${w.message}`)}i+=f.length,l+=k.length}console.log(`
10
- ${c.length} file(s) validated. ${i} error(s), ${l} warning(s).`),i>0&&process.exit(1)}import{KanonakParser as mo,PublisherIndex as po,CredentialStore as fo,createAuthenticatedFetch as go}from"@kanonak-protocol/sdk";import{readFileSync as so,writeFileSync as io,existsSync as co}from"fs";import{createHash as lo}from"crypto";import hn from"js-yaml";var He="kanonak.lock",uo=`# This file is generated by Kanonak CLI. Do not edit manually.
11
- `;function kn(){if(!co(He))return null;let n=so(He,"utf-8"),e=hn.load(n);return!e||typeof e!="object"||e.version!=="1"?null:{version:"1",lastUpdated:e.lastUpdated??new Date().toISOString(),packages:e.packages??{}}}function yn(n){n.lastUpdated=new Date().toISOString();let e={};for(let o of Object.keys(n.packages).sort())e[o]=n.packages[o];n.packages=e;let t=hn.dump(n,{lineWidth:-1,sortKeys:!1,quotingType:'"'});io(He,uo+t,"utf-8")}function L(n){return`sha256:${lo("sha256").update(n).digest("hex")}`}function W(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,c=o.indexOf("@");if(c!==-1){r=o.substring(0,c);let i=o.substring(c+1),l=i.indexOf("/");l===-1?a=i||null:(a=i.substring(0,l)||null,s=i.substring(l+1)||null)}else{let i=o.indexOf("/");i===-1?r=o:(r=o.substring(0,i),s=o.substring(i+1)||null)}return!r||s&&s.includes("/")||a&&a.includes("@")?null:{publisher:t,packageName:r,version:a,instanceName:s}}async function bn(n){let e=new T,t=new mo,o=new fo,r=go(o),a=new po({fetchFn:r}),s=kn()??{version:"1",lastUpdated:new Date().toISOString(),packages:{}};if(!n){Object.keys(s.packages).length===0&&(console.error("No kanonak.lock file found or lock file is empty."),console.error("Usage: kanonak install {publisher}/{package}[@{version}]"),process.exit(1)),console.log(`Installing ${Object.keys(s.packages).length} package(s) from kanonak.lock...`);for(let[b,f]of Object.entries(s.packages)){let k=b.indexOf("/"),h=b.substring(0,k),$=b.substring(k+1),w=e.get(h,$,f.version);if(w)console.log(` ${b}@${f.version} (cached)`);else{let v=f.resolved,D=await r(v,h);if(!D.ok)throw new Error(`Failed to fetch ${v} (${D.status} ${D.statusText})`);w=await D.text(),e.put(h,$,f.version,w),console.log(` ${b}@${f.version}`)}}console.log(`
12
- Installed ${Object.keys(s.packages).length} package(s) from lock file.`);return}let c=W(n);c||(console.error(`Invalid package reference: "${n}"`),console.error("Expected format: {publisher}/{package}[@{version}]"),process.exit(1));let{publisher:i,packageName:l,version:u,instanceName:d}=c;d&&(console.error(`\`kanonak install\` works on whole packages \u2014 got an instance suffix "/${d}".`),console.error(`Try: kanonak install ${i}/${l}${u?"@"+u:""}`),console.error("(Use `kanonak <capability> add` if you want to install one named instance.)"),process.exit(1));let p=u??await a.getHighestVersion(i,l);p||(console.error(`Could not resolve version for "${i}/${l}".`),console.error("Check the spelling, or run a search to see what the publisher offers."),process.exit(1)),console.log(`Installing ${i}/${l}@${p}...`);let y=new Set;await wn(i,l,p,e,t,a,r,y,s),yn(s),console.log(`
13
- Installed ${y.size} package(s).`)}async function wn(n,e,t,o,r,a,s,c,i){let l=`${n}/${e}@${t}`;if(c.has(l))return;c.add(l);let u=`${n}/${e}`,d=o.get(n,e,t),p;if(d)console.log(` ${l} (cached)`),p=await a.getPackageUrl(n,e,t);else{p=await a.getPackageUrl(n,e,t);let f=await s(p,n);if(!f.ok)throw new Error(`Failed to fetch ${p} (${f.status} ${f.statusText})`);d=await f.text(),o.put(n,e,t,d),console.log(` ${l}`)}let y={},b=r.parse(d);if(b.metadata.imports)for(let[f,k]of Object.entries(b.metadata.imports))for(let h of k){let $=await a.resolveVersion(f,h);$?(y[`${f}/${h.packageName}`]=$,await wn(f,h.packageName,$,o,r,a,s,c,i)):console.error(` WARNING: Could not resolve ${f}/${h.packageName} ${h.package_}`)}i.packages[u]={version:t,resolved:p,integrity:L(d),dependencies:y}}import{readFileSync as ho}from"fs";import{resolve as ko,dirname as yo}from"path";import{KanonakParser as bo}from"@kanonak-protocol/sdk";async function $n(n){let e=ko(n),t=ho(e,"utf-8"),o=new bo,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 c=ie(yo(e)),i=await j(c,o),l=new Set;for(let[u,d]of Object.entries(r.metadata.imports))for(let p of d)await Sn(u,p,i,l," ")}async function Sn(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 c=s.metadata.namespace_?.version?.toString()??"?";if(console.log(`${r}${n}/${e.packageName}@${c}`),s.metadata.imports)for(let[i,l]of Object.entries(s.metadata.imports))for(let u of l)await Sn(i,u,t,o,r+" ")}import{createHash as $o,randomBytes as An}from"crypto";import{createServer as So}from"http";import{execFile as ze}from"child_process";import{CredentialStore as vo,generateDPoPKeyPair as Do,createDPoPProof as vn,serverSupportsDPoP as Ao}from"@kanonak-protocol/sdk";import{normalizeHost as wo}from"@kanonak-protocol/sdk";var F=class{cache=new Map;async discover(e){let t=wo(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:ce(o.issuer),authorizationEndpoint:ce(o.authorization_endpoint),tokenEndpoint:ce(o.token_endpoint),registrationEndpoint:ce(o.registration_endpoint),revocationEndpoint:ce(o.revocation_endpoint),scopesSupported:X(o.scopes_supported),responseTypesSupported:X(o.response_types_supported),grantTypesSupported:X(o.grant_types_supported),codeChallengeMethodsSupported:X(o.code_challenge_methods_supported),tokenEndpointAuthMethodsSupported:X(o.token_endpoint_auth_methods_supported),dpopSigningAlgValuesSupported:X(o.dpop_signing_alg_values_supported)}}};function ce(n){return typeof n=="string"?n:null}function X(n){return Array.isArray(n)?n.filter(e=>typeof e=="string"):null}var Y=class{discovery;credentialStore;constructor(e,t){this.discovery=e??new F,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 R(`No OAuth discovery endpoint found for '${e}'.
5
+ `)}else pn(e,`${t}/
6
+ `)}getPath(e,t,o){return Jt(this.cacheDir,e,`${t}@${o}.kan.yml`)}};function se(n){let e=n;for(;;){let t=oo(e);if(t===e)break;if(fn(e).includes(".")||fn(t).includes(".")){e=t;continue}break}return e}function ge(n,e){for(let t of no(n,{withFileTypes:!0})){let o=to(n,t.name);t.isDirectory()&&t.name!=="node_modules"&&t.name!==".kanonak"?ge(o,e):t.name.endsWith(".kan.yml")&&e.push(o)}}var Ve=class{repos;constructor(...e){this.repos=e}async getHighestCompatibleVersionAsync(e,t){for(let o of this.repos)try{let r=await o.getHighestCompatibleVersionAsync(e,t);if(r)return r}catch{}return null}async getAllDocumentsAsync(){let e=[];for(let t of this.repos)try{e.push(...await t.getAllDocumentsAsync())}catch{}return e}async getDocumentAsync(e){for(let t of this.repos)try{let o=await t.getDocumentAsync(e);if(o)return o}catch{}return null}async getDocumentsByNamespaceAsync(e,t){for(let o of this.repos)try{let r=await o.getDocumentsByNamespaceAsync(e,t);if(r.length>0)return r}catch{}return[]}async saveDocumentAsync(e,t){await this.repos[0].saveDocumentAsync(e,t)}async deleteDocumentAsync(e){await this.repos[0].deleteDocumentAsync(e)}async clearNamespaceAsync(e,t){await this.repos[0].clearNamespaceAsync(e,t)}async getAllDocumentReferencesAsync(){return this.repos[0].getAllDocumentReferencesAsync()}async getDocumentContentAsync(e){for(let t of this.repos)try{let o=await t.getDocumentContentAsync(e);if(o)return o}catch{}return null}async getDocumentUriAsync(e){for(let t of this.repos)try{let o=await t.getDocumentUriAsync(e);if(o)return o}catch{}return null}};async function x(n,e){let t=[];ge(n,t);let o=new ro(e);for(let i of t)try{let c=eo(i,"utf-8"),l=e.parse(c),u=l.metadata.namespace_;if(u){let d=`${u.publisher}/${u.package_}@${u.version}`;await o.saveDocumentAsync(l,d)}}catch{}let r=new ao(io(),!0,e),a=new T,s=new so({getFromCache:(i,c,l)=>a.get(i,c,l),onFetch:(i,c,l,u)=>a.put(i,c,l,u)});return new Ve(o,r,s)}async function hn(n){let e=uo(n),t=lo(e),o=t.isDirectory()?se(e):se(mo(e)),r=new po,a=new fo(r),s=await x(o,r),i=[];if(t.isDirectory()?ge(e,i):i.push(e),i.length===0){console.log("No .kan.yml files found.");return}let c=0,l=0;for(let u of i){let d=co(u,"utf-8"),m=r.parseWithErrors(d);if(m.errors&&m.errors.length>0){console.log(`
7
+ ${u}:`);for(let y of m.errors)console.log(` ERROR (parse): ${y.message} [line ${y.line}:${y.column}]`),c++;continue}let g=m.document;if(!g){console.log(`
8
+ ${u}:`),console.log(" ERROR: Failed to parse document"),c++;continue}let h=await a.validateAsync(g,s),f=h.errors.filter(y=>y.severity===gn.Error),k=h.errors.filter(y=>y.severity===gn.Warning);if(f.length>0||k.length>0){let y=g.metadata.namespace_,w=y?`${y.publisher}/${y.package_}@${y.version}`:u;console.log(`
9
+ ${w}:`);for(let $ of f)console.log(` ERROR: ${$.message}`),$.suggestion&&console.log(` -> ${$.suggestion}`);for(let $ of k)console.log(` WARN: ${$.message}`)}c+=f.length,l+=k.length}console.log(`
10
+ ${i.length} file(s) validated. ${c} error(s), ${l} warning(s).`),c>0&&process.exit(1)}import{KanonakParser as go,PublisherIndex as ho,CredentialStore as ko,createAuthenticatedFetch as yo}from"@kanonak-protocol/sdk";import{loadLockFile as bo,saveLockFile as wo,computeIntegrity as $o}from"@kanonak-protocol/sdk";function X(n){if(!n)return null;let e=n.indexOf("/");if(e===-1)return null;let t=n.substring(0,e),o=n.substring(e+1);if(!t||!o)return null;let r,a=null,s=null,i=o.indexOf("@");if(i!==-1){r=o.substring(0,i);let c=o.substring(i+1),l=c.indexOf("/");l===-1?a=c||null:(a=c.substring(0,l)||null,s=c.substring(l+1)||null)}else{let c=o.indexOf("/");c===-1?r=o:(r=o.substring(0,c),s=o.substring(c+1)||null)}return!r||s&&s.includes("/")||a&&a.includes("@")?null:{publisher:t,packageName:r,version:a,instanceName:s}}async function kn(n){let e=new T,t=new go,o=new ko,r=yo(o),a=new ho({fetchFn:r}),s=bo()??{version:"1",lastUpdated:new Date().toISOString(),packages:{}};if(!n){Object.keys(s.packages).length===0&&(console.error("No kanonak.lock file found or lock file is empty."),console.error("Usage: kanonak install {publisher}/{package}[@{version}]"),process.exit(1)),console.log(`Installing ${Object.keys(s.packages).length} package(s) from kanonak.lock...`);for(let[h,f]of Object.entries(s.packages)){let k=h.indexOf("/"),y=h.substring(0,k),w=h.substring(k+1),$=e.get(y,w,f.version);if($)console.log(` ${h}@${f.version} (cached)`);else{let v=f.resolved,D=await r(v,y);if(!D.ok)throw new Error(`Failed to fetch ${v} (${D.status} ${D.statusText})`);$=await D.text(),e.put(y,w,f.version,$),console.log(` ${h}@${f.version}`)}}console.log(`
11
+ Installed ${Object.keys(s.packages).length} package(s) from lock file.`);return}let i=X(n);i||(console.error(`Invalid package reference: "${n}"`),console.error("Expected format: {publisher}/{package}[@{version}]"),process.exit(1));let{publisher:c,packageName:l,version:u,instanceName:d}=i;d&&(console.error(`\`kanonak install\` works on whole packages \u2014 got an instance suffix "/${d}".`),console.error(`Try: kanonak install ${c}/${l}${u?"@"+u:""}`),console.error("(Use `kanonak <capability> add` if you want to install one named instance.)"),process.exit(1));let m=u??await a.getHighestVersion(c,l);m||(console.error(`Could not resolve version for "${c}/${l}".`),console.error("Check the spelling, or run a search to see what the publisher offers."),process.exit(1)),console.log(`Installing ${c}/${l}@${m}...`);let g=new Set;await yn(c,l,m,e,t,a,r,g,s),wo(s),console.log(`
12
+ Installed ${g.size} package(s).`)}async function yn(n,e,t,o,r,a,s,i,c){let l=`${n}/${e}@${t}`;if(i.has(l))return;i.add(l);let u=`${n}/${e}`,d=o.get(n,e,t),m;if(d)console.log(` ${l} (cached)`),m=await a.getPackageUrl(n,e,t);else{m=await a.getPackageUrl(n,e,t);let f=await s(m,n);if(!f.ok)throw new Error(`Failed to fetch ${m} (${f.status} ${f.statusText})`);d=await f.text(),o.put(n,e,t,d),console.log(` ${l}`)}let g={},h=r.parse(d);if(h.metadata.imports)for(let[f,k]of Object.entries(h.metadata.imports))for(let y of k){let w=await a.resolveVersion(f,y);w?(g[`${f}/${y.packageName}`]=w,await yn(f,y.packageName,w,o,r,a,s,i,c)):console.error(` WARNING: Could not resolve ${f}/${y.packageName} ${y.package_}`)}c.packages[u]={version:t,resolved:m,integrity:$o(d),dependencies:g}}import{readFileSync as So}from"fs";import{resolve as vo,dirname as Do}from"path";import{KanonakParser as Ko}from"@kanonak-protocol/sdk";async function bn(n){let e=vo(n),t=So(e,"utf-8"),o=new Ko,r=o.parse(t),a=r.metadata.namespace_,s=a?`${a.publisher}/${a.package_}@${a.version}`:n;if(console.log(s),!r.metadata.imports){console.log(" (no imports)");return}let i=se(Do(e)),c=await x(i,o),l=new Set;for(let[u,d]of Object.entries(r.metadata.imports))for(let m of d)await wn(u,m,c,l," ")}async function wn(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 wn(c,u,t,o,r+" ")}import{createHash as Co,randomBytes as vn}from"crypto";import{createServer as Po}from"http";import{execFile as He}from"child_process";import{CredentialStore as Eo,generateDPoPKeyPair as _o,createDPoPProof as $n,serverSupportsDPoP as Io}from"@kanonak-protocol/sdk";import{normalizeHost as Ao}from"@kanonak-protocol/sdk";var L=class{cache=new Map;async discover(e){let t=Ao(e);if(this.cache.has(t))return this.cache.get(t);let o=`https://${t}/.well-known/oauth-authorization-server`,r=await this.tryEndpoint(o);if(!r){let a=`https://${t}/.well-known/openid-configuration`;r=await this.tryEndpoint(a)}return this.cache.set(t,r),r}async supportsOAuth(e){return await this.discover(e)!==null}static supportsPkceS256(e){return e.codeChallengeMethodsSupported?.some(t=>t.toUpperCase()==="S256")??!1}static supportsDynamicRegistration(e){return!!e.registrationEndpoint}static supportsAuthorizationCode(e){return e.responseTypesSupported?.some(t=>t.toLowerCase()==="code")??!1}async tryEndpoint(e){let t;try{t=await fetch(e)}catch(r){let a=r instanceof Error?r.message:String(r);return a.includes("ENOTFOUND")||a.includes("ECONNREFUSED")?(console.error(` OAuth discovery: ${e} \u2014 host unreachable (${a})`),console.error(" If the server is behind a VPN, ensure you are connected.")):a.includes("CERT")||a.includes("SSL")||a.includes("TLS")?(console.error(` OAuth discovery: ${e} \u2014 TLS error (${a})`),console.error(" If using a custom CA certificate, set NODE_EXTRA_CA_CERTS=/path/to/ca.pem")):console.error(` OAuth discovery: ${e} \u2014 network error: ${a}`),null}if(!t.ok)return t.status===404||(t.status===403?(console.error(` OAuth discovery: ${e} \u2014 HTTP 403 Forbidden`),console.error(" Access may be blocked by a firewall, proxy, or WAF.")):t.status>=500&&(console.error(` OAuth discovery: ${e} \u2014 HTTP ${t.status} server error`),console.error(" The authorization server returned an internal error. Contact your IDP administrator."))),null;let o;try{o=await t.json()}catch{return console.error(` OAuth discovery: ${e} \u2014 response is not valid JSON`),console.error(" The endpoint may be returning HTML instead of JSON. Check IDP configuration."),null}return{issuer:ie(o.issuer),authorizationEndpoint:ie(o.authorization_endpoint),tokenEndpoint:ie(o.token_endpoint),registrationEndpoint:ie(o.registration_endpoint),revocationEndpoint:ie(o.revocation_endpoint),scopesSupported:J(o.scopes_supported),responseTypesSupported:J(o.response_types_supported),grantTypesSupported:J(o.grant_types_supported),codeChallengeMethodsSupported:J(o.code_challenge_methods_supported),tokenEndpointAuthMethodsSupported:J(o.token_endpoint_auth_methods_supported),dpopSigningAlgValuesSupported:J(o.dpop_signing_alg_values_supported)}}};function ie(n){return typeof n=="string"?n:null}function J(n){return Array.isArray(n)?n.filter(e=>typeof e=="string"):null}var Z=class{discovery;credentialStore;constructor(e,t){this.discovery=e??new L,this.credentialStore=t??new Eo}async authorize(e,t=[]){console.log(`Starting OAuth flow for ${e}...`);let o=await this.discovery.discover(e);if(!o)return R(`No OAuth discovery endpoint found for '${e}'.
14
13
  The server must expose one of:
15
14
  - https://${e}/.well-known/oauth-authorization-server (RFC 8414)
16
15
  - https://${e}/.well-known/openid-configuration (OpenID Connect)
17
16
  Verify the hostname is correct and HTTPS is configured.
18
17
  If using a corporate proxy, ensure it is not blocking the discovery request.`);let r=[];if(o.authorizationEndpoint||r.push("authorization_endpoint"),o.tokenEndpoint||r.push("token_endpoint"),r.length>0)return R(`OAuth metadata for '${e}' is missing required fields: ${r.join(", ")}.
19
- Contact the IDP administrator to ensure these are included in the discovery document.`);let a=Ao(o.dpopSigningAlgValuesSupported),s=null;if(a){console.log(" Server supports DPoP (RFC 9449) \u2014 generating key pair...");try{s=Do()}catch(D){return R(`Failed to generate DPoP key pair: ${J(D)}
20
- Ensure your Node.js installation supports EC P-256 curves.`)}}let{redirectUri:c,port:i,waitForCallback:l,close:u}=await Ro(),d=await this.credentialStore.getCredential(e),p=d?.clientId??null,y=d?.clientSecret??null;if(!p&&o.registrationEndpoint){console.log(" Registering dynamic OAuth client (RFC 7591)...");let D=await this.registerClient(o.registrationEndpoint,c);if(!D.success)return u(),R(D.error);p=D.clientId,y=D.clientSecret??null}if(!p)return u(),R(`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=Io(o.dpopSigningAlgValuesSupported),s=null;if(a){console.log(" Server supports DPoP (RFC 9449) \u2014 generating key pair...");try{s=_o()}catch(D){return R(`Failed to generate DPoP key pair: ${Y(D)}
19
+ Ensure your Node.js installation supports EC P-256 curves.`)}}let{redirectUri:i,port:c,waitForCallback:l,close:u}=await Oo(),d=await this.credentialStore.getCredential(e),m=d?.clientId??null,g=d?.clientSecret??null;if(!m&&o.registrationEndpoint){console.log(" Registering dynamic OAuth client (RFC 7591)...");let D=await this.registerClient(o.registrationEndpoint,i);if(!D.success)return u(),R(D.error);m=D.clientId,g=D.clientSecret??null}if(!m)return u(),R(`No OAuth client credentials for '${e}' and the server does not support dynamic client registration (no registration_endpoint in metadata).
21
20
  You must pre-register a client with your IDP and configure the client_id.
22
21
  Ask your IDP administrator to enable dynamic client registration (RFC 7591),
23
- or add a registration_endpoint to the OAuth metadata.`);let b=Co(),f=Po(b),k=Eo(),h=_o(o.authorizationEndpoint,p,c,t,k,f);console.log(` Opening browser for authorization on port ${i}...`),console.log(" If the browser doesn't open, navigate to:"),console.log(` ${h}`),jo(h);let $=await l();if(u(),!$)return R(`Authorization timed out after 5 minutes.
22
+ or add a registration_endpoint to the OAuth metadata.`);let h=To(),f=xo(h),k=jo(),y=Uo(o.authorizationEndpoint,m,i,t,k,f);console.log(` Opening browser for authorization on port ${c}...`),console.log(" If the browser doesn't open, navigate to:"),console.log(` ${y}`),Fo(y);let w=await l();if(u(),!w)return R(`Authorization timed out after 5 minutes.
24
23
  The browser authorization was not completed in time.
25
- Re-run 'kanonak login ${e}' and complete the browser authorization promptly.`);if(!$.code){let D=$.error?`: ${$.error}`:"";return R(`No authorization code received${D}.
24
+ Re-run 'kanonak login ${e}' and complete the browser authorization promptly.`);if(!w.code){let D=w.error?`: ${w.error}`:"";return R(`No authorization code received${D}.
26
25
  The IDP may have rejected the authorization request.
27
- Check the IDP admin console for error details.`)}if($.state!==k)return R(`Authorization state mismatch \u2014 possible CSRF attack.
26
+ Check the IDP admin console for error details.`)}if(w.state!==k)return R(`Authorization state mismatch \u2014 possible CSRF attack.
28
27
  The response did not match the expected session.
29
- Re-run 'kanonak login ${e}' to start a fresh authorization flow.`);console.log(" Exchanging authorization code for tokens...");let w=await this.exchangeCode(o.tokenEndpoint,p,y,$.code,c,b,s);if(!w.success)return R(w.error);let v={clientId:p,clientSecret:y,accessToken:w.tokens.accessToken,refreshToken:w.tokens.refreshToken,expiresAt:w.tokens.expiresIn?new Date(Date.now()+w.tokens.expiresIn*1e3).toISOString():null,tokenEndpoint:o.tokenEndpoint,dpopKeyPair:s};return await this.credentialStore.store(e,v),console.log(` Successfully authenticated with ${e}`),a&&console.log(" DPoP proof-of-possession is active"),{success:!0,host:e}}async refresh(e){let t=await this.credentialStore.getCredential(e);if(!t)return R(`No stored credentials for '${e}'. Run 'kanonak login ${e}' to authenticate first.`);if(!t.refreshToken)return R(`No refresh token available for '${e}'.
28
+ Re-run 'kanonak login ${e}' to start a fresh authorization flow.`);console.log(" Exchanging authorization code for tokens...");let $=await this.exchangeCode(o.tokenEndpoint,m,g,w.code,i,h,s);if(!$.success)return R($.error);let v={clientId:m,clientSecret:g,accessToken:$.tokens.accessToken,refreshToken:$.tokens.refreshToken,expiresAt:$.tokens.expiresIn?new Date(Date.now()+$.tokens.expiresIn*1e3).toISOString():null,tokenEndpoint:o.tokenEndpoint,dpopKeyPair:s};return await this.credentialStore.store(e,v),console.log(` Successfully authenticated with ${e}`),a&&console.log(" DPoP proof-of-possession is active"),{success:!0,host:e}}async refresh(e){let t=await this.credentialStore.getCredential(e);if(!t)return R(`No stored credentials for '${e}'. Run 'kanonak login ${e}' to authenticate first.`);if(!t.refreshToken)return R(`No refresh token available for '${e}'.
30
29
  The authorization server may not issue refresh tokens for this client.
31
30
  Run 'kanonak login ${e}' to re-authenticate.`);if(!t.clientId)return R(`No client ID in stored credentials for '${e}'.
32
31
  The stored credential may be corrupted. Run 'kanonak logout ${e}' then 'kanonak login ${e}'.`);let o=t.tokenEndpoint;if(!o){let a=await this.discovery.discover(e);if(!a?.tokenEndpoint)return R(`Cannot find token endpoint for '${e}'.
33
32
  The OAuth discovery endpoint may be unreachable.
34
33
  Check network connectivity and run 'kanonak login ${e}' to re-authenticate.`);o=a.tokenEndpoint}let r=await this.refreshTokenRequest(o,t.clientId,t.clientSecret,t.refreshToken,t.dpopKeyPair);return r.success?(t.accessToken=r.tokens.accessToken,r.tokens.refreshToken&&(t.refreshToken=r.tokens.refreshToken),t.expiresAt=r.tokens.expiresIn?new Date(Date.now()+r.tokens.expiresIn*1e3).toISOString():null,t.tokenEndpoint=o,await this.credentialStore.store(e,t),{success:!0,host:e}):R(`${r.error}
35
34
  The refresh token may have expired. Run 'kanonak login ${e}' to re-authenticate.`)}async logout(e){let t=await this.credentialStore.getCredential(e);if(!t)return R(`No stored credentials for '${e}'.
36
- You may not be logged in, or credentials may be stored in a different backend.`);let o=await this.discovery.discover(e);if(o?.revocationEndpoint&&t.accessToken&&t.clientId)try{await this.revokeToken(o.revocationEndpoint,t.accessToken,t.clientId)}catch{console.warn(` Warning: Token revocation failed for '${e}'. The token has been removed locally but may still be valid on the server until it expires.`)}return await this.credentialStore.remove(e),{success:!0,host:e}}async registerClient(e,t){let o;try{o=await fetch(e,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({client_name:"Kanonak CLI",redirect_uris:[t],grant_types:["authorization_code","refresh_token"],response_types:["code"],token_endpoint_auth_method:"none"})})}catch(s){return{success:!1,error:`Dynamic client registration request to ${e} failed: ${J(s)}
35
+ You may not be logged in, or credentials may be stored in a different backend.`);let o=await this.discovery.discover(e);if(o?.revocationEndpoint&&t.accessToken&&t.clientId)try{await this.revokeToken(o.revocationEndpoint,t.accessToken,t.clientId)}catch{console.warn(` Warning: Token revocation failed for '${e}'. The token has been removed locally but may still be valid on the server until it expires.`)}return await this.credentialStore.remove(e),{success:!0,host:e}}async registerClient(e,t){let o;try{o=await fetch(e,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({client_name:"Kanonak CLI",redirect_uris:[t],grant_types:["authorization_code","refresh_token"],response_types:["code"],token_endpoint_auth_method:"none"})})}catch(s){return{success:!1,error:`Dynamic client registration request to ${e} failed: ${Y(s)}
37
36
  Ensure the IDP is reachable and HTTPS is properly configured.
38
- If using a corporate proxy or custom CA, set NODE_EXTRA_CA_CERTS.`}}if(!o.ok){let s=await qe(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 ze(o);return{success:!1,error:`Dynamic client registration (RFC 7591) failed.
39
38
  Endpoint: ${e}
40
39
  HTTP ${o.status}: ${s}
41
40
  The IDP may not support dynamic registration for public clients.
42
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.
43
- The IDP response may be malformed. Contact your IDP administrator.`}}async exchangeCode(e,t,o,r,a,s,c){let i=new URLSearchParams({grant_type:"authorization_code",client_id:t,code:r,redirect_uri:a,code_verifier:s});o&&i.set("client_secret",o);let l={"Content-Type":"application/x-www-form-urlencoded"};if(c)try{l.DPoP=vn(c.privateKey,c.publicKey,"POST",e)}catch(d){return{success:!1,error:`Failed to create DPoP proof for token exchange: ${J(d)}
44
- The stored key pair may be corrupted. Run 'kanonak login' to re-authenticate.`}}let u;try{u=await fetch(e,{method:"POST",headers:l,body:i.toString()})}catch(d){return{success:!1,error:`Token exchange request to ${e} failed: ${J(d)}
45
- Ensure the token endpoint is reachable.`}}if(!u.ok){let d=await qe(u),p=Ko(d);return{success:!1,error:`Token exchange failed.
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=$n(i.privateKey,i.publicKey,"POST",e)}catch(d){return{success:!1,error:`Failed to create DPoP proof for token exchange: ${Y(d)}
43
+ The stored key pair may be corrupted. Run 'kanonak login' to re-authenticate.`}}let u;try{u=await fetch(e,{method:"POST",headers:l,body:c.toString()})}catch(d){return{success:!1,error:`Token exchange request to ${e} failed: ${Y(d)}
44
+ Ensure the token endpoint is reachable.`}}if(!u.ok){let d=await ze(u),m=Ro(d);return{success:!1,error:`Token exchange failed.
46
45
  Endpoint: ${e}
47
- HTTP ${u.status}: ${d}`+(p?`
48
- ${p}`:"")}}return{success:!0,tokens:Dn(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 c={"Content-Type":"application/x-www-form-urlencoded"};if(a)try{c.DPoP=vn(a.privateKey,a.publicKey,"POST",e)}catch(l){return{success:!1,error:`Failed to create DPoP proof for token refresh: ${J(l)}`}}let i;try{i=await fetch(e,{method:"POST",headers:c,body:s.toString()})}catch(l){return{success:!1,error:`Token refresh request to ${e} failed: ${J(l)}`}}if(!i.ok){let l=await qe(i);return{success:!1,error:`Token refresh failed \u2014 HTTP ${i.status}: ${l}`}}return{success:!0,tokens:Dn(await i.json())}}async revokeToken(e,t,o){await fetch(e,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams({token:t,client_id:o}).toString()})}};function R(n){return{success:!1,error:n}}function Dn(n){return{accessToken:n.access_token,refreshToken:n.refresh_token,expiresIn:typeof n.expires_in=="number"?n.expires_in:void 0}}function J(n){return n instanceof Error?n.message:String(n)}async function qe(n){try{return await n.text()}catch{return"(could not read response body)"}}function Ko(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 Co(){return An(32).toString("base64url")}function Po(n){return $o("sha256").update(n).digest("base64url")}function Eo(){return An(16).toString("base64url")}function _o(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 Io=300*1e3;async function Ro(){return new Promise(n=>{let e=So((r,a)=>{let s=new URL(r.url,"http://localhost"),c=s.searchParams.get("code")??void 0,i=s.searchParams.get("state")??void 0,l=s.searchParams.get("error")??s.searchParams.get("error_description")??void 0,u=l?To(l):null,d=u?`<html><body><h1>Authorization failed</h1><p>${u}</p></body></html>`:"<html><body><h1>Authorization successful!</h1><p>You can close this window.</p></body></html>";a.writeHead(200,{"Content-Type":"text/html"}),a.end(d),t({code:c,state:i,error:l})}),t,o=new Promise(r=>{t=r,setTimeout(()=>{r(null),e.close()},Io)});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 jo(n){try{process.platform==="win32"?ze("cmd",["/c","start","",n]):process.platform==="darwin"?ze("open",[n]):ze("xdg-open",[n])}catch{console.log(" Could not open browser automatically. Please navigate to the URL above manually.")}}import{CredentialStore as xo}from"@kanonak-protocol/sdk";async function Kn(n){try{let e=new F,t=new xo,r=await new Y(e,t).authorize(n);r.success?console.log(`
46
+ HTTP ${u.status}: ${d}`+(m?`
47
+ ${m}`:"")}}return{success:!0,tokens:Sn(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=$n(a.privateKey,a.publicKey,"POST",e)}catch(l){return{success:!1,error:`Failed to create DPoP proof for token refresh: ${Y(l)}`}}let c;try{c=await fetch(e,{method:"POST",headers:i,body:s.toString()})}catch(l){return{success:!1,error:`Token refresh request to ${e} failed: ${Y(l)}`}}if(!c.ok){let l=await ze(c);return{success:!1,error:`Token refresh failed \u2014 HTTP ${c.status}: ${l}`}}return{success:!0,tokens:Sn(await c.json())}}async revokeToken(e,t,o){await fetch(e,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams({token:t,client_id:o}).toString()})}};function R(n){return{success:!1,error:n}}function Sn(n){return{accessToken:n.access_token,refreshToken:n.refresh_token,expiresIn:typeof n.expires_in=="number"?n.expires_in:void 0}}function Y(n){return n instanceof Error?n.message:String(n)}async function ze(n){try{return await n.text()}catch{return"(could not read response body)"}}function Ro(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 To(){return vn(32).toString("base64url")}function xo(n){return Co("sha256").update(n).digest("base64url")}function jo(){return vn(16).toString("base64url")}function Uo(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 No=300*1e3;async function Oo(){return new Promise(n=>{let e=Po((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?Lo(l):null,d=u?`<html><body><h1>Authorization failed</h1><p>${u}</p></body></html>`:"<html><body><h1>Authorization successful!</h1><p>You can close this window.</p></body></html>";a.writeHead(200,{"Content-Type":"text/html"}),a.end(d),t({code:i,state:c,error:l})}),t,o=new Promise(r=>{t=r,setTimeout(()=>{r(null),e.close()},No)});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 Lo(n){return n.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;")}function Fo(n){try{process.platform==="win32"?He("cmd",["/c","start","",n]):process.platform==="darwin"?He("open",[n]):He("xdg-open",[n])}catch{console.log(" Could not open browser automatically. Please navigate to the URL above manually.")}}import{CredentialStore as Mo}from"@kanonak-protocol/sdk";async function Dn(n){try{let e=new L,t=new Mo,r=await new Z(e,t).authorize(n);r.success?console.log(`
49
48
  Authenticated with ${n}.`):(console.error(`
50
49
  Authentication failed:
51
50
  ${r.error}`),process.exit(1))}catch(e){let t=e instanceof Error?e.message:String(e);console.error(`
52
51
  Authentication failed unexpectedly:
53
52
  ${t}`),console.error(`
54
- If this persists, file an issue at https://github.com/kanonak-protocol/typescript/issues`),process.exit(1)}}import{CredentialStore as Uo}from"@kanonak-protocol/sdk";async function Cn(n){try{let e=new F,t=new Uo,r=await new Y(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 Bo}from"@kanonak-protocol/sdk";async function Kn(n){try{let e=new L,t=new Bo,r=await new Z(e,t).logout(n);r.success?console.log(`Logged out from ${n}.`):(console.error(`
55
54
  Logout failed:
56
55
  ${r.error}`),process.exit(1))}catch(e){let t=e instanceof Error?e.message:String(e);console.error(`
57
56
  Logout failed unexpectedly:
58
- ${t}`),process.exit(1)}}import{Command as lr}from"commander";import{KanonakParser as ur,KanonakObjectParser as dr,PublisherIndex as mr,CredentialStore as pr,createAuthenticatedFetch as fr}from"@kanonak-protocol/sdk";import{readFileSync as No,writeFileSync as Oo,existsSync as Lo}from"fs";import{join as Fo}from"path";import Pn from"js-yaml";import{getGlobalCachePath as Mo}from"@kanonak-protocol/sdk";var Bo=`# This file is generated by Kanonak CLI. Do not edit manually.
59
- `;function En(){let n=Mo();return Fo(n,"..","capabilities.lock")}function Z(){let n=En();if(!Lo(n))return{version:"1",lastUpdated:new Date().toISOString(),capabilities:{}};let e=No(n,"utf-8"),t=Pn.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 Ge(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=Pn.dump(n,{lineWidth:-1,sortKeys:!1,quotingType:'"'});Oo(En(),Bo+t,"utf-8")}var K=class{constructor(e,t){this.doc=e;this.broader=t}doc;broader;async getAllDocumentsAsync(){return[this.doc]}async getDocumentAsync(e){return this.broader.getDocumentAsync(e)}async getDocumentsByNamespaceAsync(e,t){return this.broader.getDocumentsByNamespaceAsync(e,t)}async getHighestCompatibleVersionAsync(e,t){return this.broader.getHighestCompatibleVersionAsync(e,t)}async saveDocumentAsync(){throw new Error("SingleDocumentRepository is read-only")}async deleteDocumentAsync(){throw new Error("SingleDocumentRepository is read-only")}async clearNamespaceAsync(){throw new Error("SingleDocumentRepository is read-only")}async getAllDocumentReferencesAsync(){return[]}async getDocumentContentAsync(e){return this.broader.getDocumentContentAsync(e)}async getDocumentUriAsync(e){return this.broader.getDocumentUriAsync(e)}};import{KanonakObjectParser as Jo,EmbeddedKanonak as xn,ReferenceKanonak as Un}from"@kanonak-protocol/sdk";import{SubjectKanonak as _n,DefinedKanonak as Vo,StringStatement as Ho,NumberStatement as zo,BooleanStatement as qo,ReferenceStatement as In,EmbeddedStatement as Go,ListStatement as Wo}from"@kanonak-protocol/sdk";function N(n){return`${n.publisher}/${n.package_}/${n.name}`}function M(n,e){return n.publisher===e.publisher&&n.package_===e.package_&&n.name===e.name}function Xo(n,e){if(!(n instanceof Vo))return!1;for(let t of n.statement)if(t.predicate?.subject?.name==="type"&&t instanceof In){let r=t.object;if(M(r.subject,e))return!0}return!1}function C(n,e){let t=[];for(let o of n)o instanceof _n&&Xo(o,e)&&t.push(o);return t}function ke(n,e){for(let t of n){if(!(t instanceof _n)||t.name!==e.name)continue;if((t.namespace||"").startsWith(`${e.publisher}/${e.package_}@`))return t}}function ye(n,e){for(let t of n.statement){let o=t.predicate;if(o?.subject&&M(o.subject,e))return t}}function le(n,e){let t=ye(n,e);if(t&&(t instanceof Ho||t instanceof zo||t instanceof qo))return t.object}function P(n,e){let t=le(n,e);return typeof t=="string"?t:void 0}function B(n,e){let t=ye(n,e);if(t instanceof In)return t.object.subject}function H(n,e){let t=ye(n,e);if(t instanceof Go)return t.object}function Q(n,e){let t=ye(n,e);return t instanceof Wo?t.object??[]:[]}var E="kanonak.org",_="capabilities",We={publisher:E,package_:_,name:"Capability"},Yo={publisher:E,package_:_,name:"commandName"},Nn={publisher:E,package_:_,name:"description"},Zo={publisher:E,package_:_,name:"managesType"},Qo={publisher:E,package_:_,name:"deploymentTarget"},er={publisher:E,package_:_,name:"hasCommand"},nr={publisher:E,package_:_,name:"subcommandName"},tr={publisher:E,package_:_,name:"performs"},or={publisher:E,package_:_,name:"hasArgument"},rr={publisher:E,package_:_,name:"argumentName"},Rn={publisher:E,package_:_,name:"isRequired"},Tn={publisher:E,package_:_,name:"isOption"},ar={publisher:E,package_:_,name:"defaultValue"};async function On(n,e,t){let o=Z(),r=new Jo,a=[];for(let[s,c]of Object.entries(o.capabilities)){let i=n.get(c.publisher,c.package_,c.version);if(!i){console.error(` WARNING: Cached content missing for capability "${s}" (${c.publisher}/${c.package_}@${c.version})`);continue}try{let l=e.parse(i),u=new K(l,t),d=await r.parseKanonaks(u),p=sr(d,c.publisher,c.package_,c.version);p?a.push(p):console.error(` WARNING: No Capability instance found in "${s}" (${c.publisher}/${c.package_}@${c.version})`)}catch(l){console.error(` WARNING: Failed to parse capability "${s}": ${l}`)}}return a}function sr(n,e,t,o){let r=C(n,We);if(r.length===0)return;let a=r[0],s=P(a,Yo)??"",c=P(a,Nn)??"",i=B(a,Zo),l=B(a,Qo),u=[];for(let d of Q(a,er)){let p=ir(d,n);p&&u.push(p)}return{commandName:s,description:c,managesTypeKey:i?N(i):"",deploymentTargetKey:l?N(l):"",commands:u,publisher:e,package_:t,version:o}}function ir(n,e){let t;if(n instanceof xn)t=n;else if(n instanceof Un){let i=Ln(e,n.subject.publisher,n.subject.package_,n.subject.name);i&&(t=i)}if(!t)return;let o=P(t,nr)??"",r=P(t,Nn)??"",a=B(t,tr),s=Q(t,or),c=[];for(let i of s){let l=cr(i,e);l&&c.push(l)}return{subcommandName:o,description:r,arguments:c,actionKey:a?N(a):""}}function cr(n,e){let t;if(n instanceof xn)t=n;else if(n instanceof Un){let i=Ln(e,n.subject.publisher,n.subject.package_,n.subject.name);i&&(t=i)}if(!t)return;let o=P(t,rr)??"",r=P(t,Rn)==="true"||jn(t,Rn)===!0,a=P(t,Tn)==="true"||jn(t,Tn)===!0,s=P(t,ar),c={argumentName:o,required:r,isOption:a};return s!==void 0&&(c.defaultValue=s),c}function jn(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 Ln(n,e,t,o){for(let r of n){if(!("name"in r)||!("namespace"in r))continue;let a=r;if(a.name===o&&!(!a.namespace||typeof a.namespace!="string")&&a.namespace.startsWith(`${e}/${t}@`))return r}}var gr={publisher:E,package_:_,name:"commandName"};function Fn(){let n=new lr("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 hr(e)}),n.command("remove <name>").description("Remove an installed capability").action(async e=>{await kr(e)}),n.command("list").description("List installed capabilities").action(async()=>{await yr()}),n}async function hr(n){let e=W(n);e||(console.error(`Invalid package reference: "${n}"`),console.error("Expected format: {publisher}/{package}[@{version}]"),process.exit(1));let{publisher:t,packageName:o,version:r,instanceName:a}=e;a&&(console.error(`\`kanonak capability add\` installs whole packages \u2014 got an instance suffix "/${a}".`),console.error(`Try: kanonak capability add ${t}/${o}${r?"@"+r:""}`),process.exit(1));let s=new T,c=new ur,i=new dr,l=new pr,u=fr(l),d=new mr({fetchFn:u}),p=r??await d.getHighestVersion(t,o);p||(console.error(`Could not resolve version for "${t}/${o}".`),process.exit(1)),console.log(`Installing capability ${t}/${o}@${p}...`);let y=s.get(t,o,p);if(!y){let G=await d.getPackageUrl(t,o,p),ge=await u(G,t);if(!ge.ok)throw new Error(`Failed to fetch ${G} (${ge.status} ${ge.statusText})`);y=await ge.text(),s.put(t,o,p,y)}let b=c.parse(y),f=await j(process.cwd(),c),k=new K(b,f),h=await i.parseKanonaks(k),$=C(h,We);$.length===0&&(console.error(`Package ${t}/${o}@${p} does not contain a ${E}/${_}/Capability instance.`),process.exit(1));let w=$[0],v=P(w,gr);v||(console.error(`Capability instance in ${t}/${o}@${p} has no commandName property.`),process.exit(1));let D=Z();D.capabilities[v]={publisher:t,package_:o,version:p,resolved:await d.getPackageUrl(t,o,p),integrity:L(y)},Ge(D),console.log(`
60
- Installed capability "${v}".`),console.log(`Run "kanonak ${v} --help" to get started.`)}async function kr(n){let e=Z();e.capabilities[n]||(console.error(`Capability "${n}" is not installed.`),process.exit(1));let t=e.capabilities[n];delete e.capabilities[n],Ge(e),console.log(`Removed capability "${n}" (${t.publisher}/${t.package_}@${t.version}).`)}async function yr(){let n=Z(),e=Object.entries(n.capabilities);if(e.length===0){console.log("No capabilities installed."),console.log("Install one with: kanonak capability add {publisher}/{package}");return}console.log(`Installed capabilities:
61
- `);for(let[t,o]of e)console.log(` ${t} ${o.publisher}/${o.package_}@${o.version}`)}import{Command as pe}from"commander";import{readFileSync as Sa,writeFileSync as va,mkdirSync as Da,existsSync as it,statSync as Aa}from"fs";import{join as Ka,resolve as Ca}from"path";import{KanonakParser as nn,KanonakObjectParser as tn,SubjectKanonak as Pa,Reasoner as Ea,KanonakVocabulary as _a,makeUriKey as ct}from"@kanonak-protocol/sdk";var br="kanonak.org",wr="document-ast",S=n=>({publisher:br,package_:wr,name:n}),x={Document:S("Document"),Block:S("Block"),Inline:S("Inline"),StructuredValue:S("StructuredValue"),Heading:S("Heading"),Paragraph:S("Paragraph"),RawBlock:S("RawBlock"),Text:S("Text"),StructuredMap:S("StructuredMap"),StructuredEntry:S("StructuredEntry"),StructuredList:S("StructuredList"),StringScalar:S("StringScalar"),IntegerScalar:S("IntegerScalar"),EscapeHint:S("EscapeHint"),MediaType:S("MediaType"),metadata:S("metadata"),children:S("children"),level:S("level"),inlines:S("inlines"),text:S("text"),entries:S("entries"),key:S("key"),value:S("value"),escapeHint:S("escapeHint"),items:S("items"),stringValue:S("stringValue"),integerValue:S("integerValue"),rawContent:S("rawContent"),mediaType:S("mediaType"),mimeType:S("mimeType"),ESC_RAW:S("esc-raw"),ESC_YAML_SAFE:S("esc-yaml-safe"),ESC_TOML_STRING:S("esc-toml-string"),ESC_TOML_MULTILINE:S("esc-toml-multiline"),ESC_JSON:S("esc-json"),TEXT_PLAIN:S("text-plain"),TEXT_MARKDOWN:S("text-markdown"),TEXT_HTML:S("text-html"),APPLICATION_JSON:S("application-json"),TEXT_YAML:S("text-yaml"),IMAGE_SVG_XML:S("image-svg-xml")},$r="kanonak.org",Sr="transformations",m=n=>({publisher:$r,package_:Sr,name:n}),g={Transformation:m("Transformation"),InputPattern:m("InputPattern"),Expression:m("Expression"),ExpressionKind:m("ExpressionKind"),ExpressionFragment:m("ExpressionFragment"),AstFieldBinding:m("AstFieldBinding"),OutputFormat:m("OutputFormat"),FormatOverride:m("FormatOverride"),RenameEntry:m("RenameEntry"),Artifact:m("Artifact"),NormalizeKind:m("NormalizeKind"),inputPattern:m("inputPattern"),rule:m("rule"),artifactName:m("artifactName"),outputs:m("outputs"),formatOverrides:m("formatOverrides"),matchesClass:m("matchesClass"),requires:m("requires"),kind:m("kind"),astClass:m("astClass"),set:m("set"),iterate:m("iterate"),loopVar:m("loopVar"),emit:m("emit"),condition:m("condition"),thenBuild:m("thenBuild"),elseBuild:m("elseBuild"),parts:m("parts"),stringLiteral:m("stringLiteral"),integerLiteral:m("integerLiteral"),booleanLiteral:m("booleanLiteral"),varName:m("varName"),readSource:m("readSource"),readProp:m("readProp"),traverseSource:m("traverseSource"),through:m("through"),step:m("step"),primary:m("primary"),alternate:m("alternate"),uriNameOf:m("uriNameOf"),listMapSource:m("listMapSource"),mapBody:m("mapBody"),separator:m("separator"),items:m("items"),normSource:m("normSource"),normKind:m("normKind"),checkExpr:m("checkExpr"),refTo:m("refTo"),fragmentRef:m("fragmentRef"),expr:m("expr"),labelTarget:m("labelTarget"),labelSource:m("labelSource"),resolveSource:m("resolveSource"),field:m("field"),bindValue:m("bindValue"),backendUri:m("backendUri"),formatTarget:m("formatTarget"),metadataKeys:m("metadataKeys"),metadataRenames:m("metadataRenames"),trailingNewline:m("trailingNewline"),fromKey:m("fromKey"),toKey:m("toKey"),KIND_BUILD_AST_NODE:m("build-ast-node"),KIND_FOR_EACH:m("for-each"),KIND_WHEN:m("when"),KIND_CONCAT:m("concat"),KIND_STRING_LITERAL:m("string-literal"),KIND_INTEGER_LITERAL:m("integer-literal"),KIND_BOOLEAN_LITERAL:m("boolean-literal"),KIND_VAR_REF:m("var-ref"),KIND_PROPERTY_READ:m("property-read"),KIND_TRAVERSE:m("traverse"),KIND_FALLBACK:m("fallback"),KIND_URI_NAME:m("uri-name"),KIND_LIST_MAP:m("list-map"),KIND_JOIN:m("join"),KIND_NORMALIZE:m("normalize"),KIND_IS_SET:m("is-set"),KIND_URI_LITERAL:m("uri-literal"),KIND_CALL_FRAGMENT:m("call-fragment"),KIND_DISPLAY_LABEL:m("display-label"),KIND_RESOLVE_REF:m("resolve-ref"),NORM_TRIM_END:m("trim-end"),FMT_MARKDOWN_FRONTMATTER:m("markdown-with-frontmatter"),FMT_TOML:m("toml"),FMT_JSON:m("json"),FMT_PLAIN_MARKDOWN:m("plain-markdown")};import{SubjectKanonak as Mn}from"@kanonak-protocol/sdk";var be=class{constructor(e,t,o){this.repository=e;this.parser=t;this.objectParser=o}repository;parser;objectParser;cache=new Map;async resolveSubject(e,t){let o=ke(t,e);if(o)return o;let r=`${e.publisher}/${e.package_}`,a=this.cache.get(r);if(!a){let s=await this.repository.getDocumentsByNamespaceAsync(e.publisher,e.package_);if(s.length===0)return;let c=s[0],i=new K(c,this.repository);a=await this.objectParser.parseKanonaks(i),this.cache.set(r,a)}for(let s of a)if(s instanceof Mn&&s.name===e.name&&s.namespace&&s.namespace.startsWith(`${e.publisher}/${e.package_}@`))return s;for(let s of a)if(s instanceof Mn&&s.name===e.name)return s}};import{DefinedKanonak as Bn,LiteralKanonak as vr,ReferenceKanonak as we,StringStatement as Dr,NumberStatement as Ar,BooleanStatement as Kr,ReferenceStatement as Cr,EmbeddedStatement as Pr,ListStatement as Er}from"@kanonak-protocol/sdk";var $e=class extends Error{constructor(e){super(e)}},Se=class{constructor(e,t){this.resolver=e;this.allKanonaks=t}resolver;allKanonaks;async evaluate(e,t){switch(e.kind){case"var-ref":{if(!t.has(e.varName))throw new $e(`Unbound variable "${e.varName}"`);return t.get(e.varName)}case"string-literal":return e.value;case"integer-literal":return e.value;case"boolean-literal":return e.value;case"uri-literal":return{...e.refTo};case"property-read":{let o=await this.evaluate(e.source,t);return o instanceof Bn?Xe(o,e.readProp):void 0}case"traverse":{let o=await this.evaluate(e.source,t);if(!(o instanceof Bn))return;let r=Xe(o,e.through),a;if(r instanceof we?a=r.subject:Array.isArray(r)&&r.length>0&&r[0]instanceof we&&(a=r[0].subject),!a)return;let s=await this.resolver.resolveSubject(a,this.allKanonaks);if(!s)return;let c=new Map(t);return c.set("input",s),this.evaluate(e.step,c)}case"fallback":{let o=await this.evaluate(e.primary,t);return Hn(o)?o:this.evaluate(e.alternate,t)}case"uri-name":{let o=await this.evaluate(e.of,t);return o instanceof we?o.subject.name:zn(o)?o.name:void 0}case"list-map":{let o=await this.evaluate(e.source,t),r=Je(o),a=[];for(let s of r){let c=new Map(t);c.set(e.loopVar,s),a.push(await this.evaluate(e.mapBody,c))}return a}case"join":{let o=await this.evaluate(e.items,t),r=Je(o),a=[];for(let s of r)s!=null&&a.push(String(s));return a.join(e.separator)}case"normalize":{let o=await this.evaluate(e.source,t);return typeof o!="string"?o:e.normKind==="trim-end"?o.trimEnd():o}case"is-set":{let o=await this.evaluate(e.check,t);return Hn(o)}case"when":{let o=await this.evaluate(e.condition,t);return Tr(o)?this.evaluate(e.thenBuild,t):e.elseBuild?this.evaluate(e.elseBuild,t):void 0}case"concat":{let o=[];for(let r of e.parts){let a=await this.evaluate(r,t);if(a!=null)if(Array.isArray(a))for(let s of a)o.push(s);else o.push(a)}return o}case"for-each":{let o=await this.evaluate(e.iterate,t),r=Je(o),a=[];for(let s of r){let c=new Map(t);c.set(e.loopVar,s);let i=await this.evaluate(e.emit,c);if(i!=null)if(Array.isArray(i))for(let l of i)a.push(l);else a.push(i)}return a}case"build-ast-node":return this.buildAstNode(e,t);case"resolve-ref":{let o=await this.evaluate(e.source,t),r;return o instanceof we?r=o.subject:zn(o)&&(r=o),r?this.resolver.resolveSubject(r,this.allKanonaks):void 0}case"display-label":{let o={publisher:e.labelTarget.publisher,package_:e.labelTarget.package_,name:e.labelTarget.name},r=await this.resolver.resolveSubject(o,this.allKanonaks);if(r){let a=Xe(r,e.labelSource);if(typeof a=="string"&&a.length>0)return a}return e.labelTarget.name}default:{let o=e;throw new $e(`Unhandled expression kind: ${JSON.stringify(o)}`)}}}async buildAstNode(e,t){let o={kind:e.astClass.name};for(let r of e.set){let a=await this.evaluate(r.value,t);if(a==null||Array.isArray(a)&&a.length===0)continue;let s=r.field.name;Array.isArray(a)&&_r.has(s)&&a.every(c=>Ir(c))&&(a=a.map(c=>String(c)).join("")),o[s]=a}return o}},_r=new Set(["stringValue","text","rawContent","key"]);function Ir(n){return typeof n=="string"||typeof n=="number"||typeof n=="boolean"}function Xe(n,e){let t=[];for(let r of n.statement){let a=r.predicate;a?.subject&&M(a.subject,e)&&t.push(r)}if(t.length===0)return;if(t.length===1&&t[0]instanceof Er)return Rr(t[0].object);if(t.length===1)return Vn(t[0]);let o=[];for(let r of t){let a=Vn(r);a!==void 0&&o.push(a)}return o}function Rr(n){let e=[];for(let t of n)t instanceof vr?e.push(t.value):e.push(t);return e}function Vn(n){if(n instanceof Dr||n instanceof Ar||n instanceof Kr||n instanceof Cr||n instanceof Pr)return n.object}function Hn(n){return n==null?!1:typeof n=="string"||Array.isArray(n)?n.length>0:!0}function Tr(n){return n==null?!1:typeof n=="boolean"?n:typeof n=="string"?n.length>0:typeof n=="number"?n!==0:Array.isArray(n)?n.length>0:!0}function Je(n){return n==null?[]:Array.isArray(n)?n:[n]}function zn(n){return n!==null&&typeof n=="object"&&"publisher"in n&&"package_"in n&&"name"in n}import{EmbeddedKanonak as jr,ReferenceKanonak as Ye,SubjectKanonak as xr,ListStatement as Gn,StringStatement as Ur,ReferenceStatement as Ze}from"@kanonak-protocol/sdk";var A=class extends Error{constructor(t,o){super(`${t} (at ${o})`);this.path=o}path},qn=16;function Nr(n){return n.predicate?.subject}function Wn(n,e){let t=[];for(let o of n.statement){let r=Nr(o);r&&M(r,e)&&t.push(o)}return t}function U(n,e){let t=B(n,e);if(t)return t;let o=Q(n,e);if(o.length===1&&o[0]instanceof Ye)return o[0].subject}function ve(n,e){let t=Q(n,e),o=[];for(let r of t)r instanceof jr&&o.push(r);return o}function Xn(n,e){let t=[];for(let o of Wn(n,e))if(o instanceof Ur)t.push(o.object);else if(o instanceof Gn)for(let r of o.object)typeof r=="string"?t.push(r):r instanceof Ye&&t.push(r.subject.name);else o instanceof Ze&&t.push(o.object.subject.name);return t}function Or(n,e){let t=n.split("/");if(t.length<3)throw new A(`Invalid property URI "${n}" \u2014 expected publisher/package/name`,e);let[o,r,...a]=t;return{publisher:o,package_:r,name:a.join("/")}}function ne(n,e){let t=n.name,o=`transformation[${t}]`,r={catalog:e,depth:0},a=H(n,g.inputPattern);if(!a)throw new A("Transformation has no inputPattern",o);let s=Lr(a,r,`${o}.inputPattern`),c=H(n,g.rule);if(!c)throw new A("Transformation has no rule",o);let i=ee(c,r,`${o}.rule`),l=H(n,g.artifactName);if(!l)throw new A("Transformation has no artifactName",o);let u=ee(l,r,`${o}.artifactName`),d=new Set;for(let y of Wn(n,g.outputs))if(y instanceof Ze)d.add(y.object.subject.name);else if(y instanceof Gn)for(let b of y.object)b instanceof Ye&&d.add(b.subject.name);if(d.size===0)throw new A("Transformation has no outputs",o);let p=new Map;for(let y of ve(n,g.formatOverrides)){let b=`${o}.formatOverrides[]`,f=U(y,g.formatTarget);if(!f)throw new A("FormatOverride missing formatTarget",b);p.set(f.name,Fr(y,b))}return{name:t,inputPattern:s,rule:i,artifactName:u,outputs:d,overrides:p}}function Lr(n,e,t){let o=U(n,g.matchesClass);if(!o)throw new A("InputPattern has no matchesClass",t);let r={publisher:o.publisher,package_:o.package_,name:o.name},s=Xn(n,g.requires).map((c,i)=>Or(c,`${t}.requires[${i}]`));return{matchesClass:r,requires:s}}function Fr(n,e){let t=Xn(n,g.metadataKeys),o=t.length>0?t:void 0,r=new Map;for(let c of ve(n,g.metadataRenames)){let i=P(c,g.fromKey),l=P(c,g.toKey);i&&l&&r.set(i,l)}let a=le(n,g.trailingNewline);return{metadataKeys:o,metadataRenames:r,trailingNewline:typeof a=="boolean"?a:void 0}}function ee(n,e,t){let o=U(n,g.kind);if(!o)throw new A("Expression has no kind",t);let r=o.name;switch(r){case"build-ast-node":return Vr(n,e,t);case"for-each":return Hr(n,e,t);case"when":return zr(n,e,t);case"concat":return qr(n,e,t);case"string-literal":return{kind:"string-literal",value:ue(n,g.stringLiteral,t)};case"integer-literal":return{kind:"integer-literal",value:Zr(n,g.integerLiteral,t)};case"boolean-literal":return{kind:"boolean-literal",value:Qr(n,g.booleanLiteral,t)};case"var-ref":return{kind:"var-ref",varName:ue(n,g.varName,t)};case"property-read":return Gr(n,e,t);case"traverse":return Wr(n,e,t);case"fallback":return Xr(n,e,t);case"uri-name":return{kind:"uri-name",of:I(n,g.uriNameOf,e,`${t}.uriNameOf`)};case"list-map":return Jr(n,e,t);case"join":return{kind:"join",separator:ue(n,g.separator,t),items:I(n,g.items,e,`${t}.items`)};case"normalize":return Yr(n,e,t);case"is-set":return{kind:"is-set",check:I(n,g.checkExpr,e,`${t}.checkExpr`)};case"uri-literal":{let a=U(n,g.refTo);if(!a)throw new A("uri-literal has no refTo",t);return{kind:"uri-literal",refTo:{publisher:a.publisher,package_:a.package_,name:a.name}}}case"display-label":{let a=U(n,g.labelTarget);if(!a)throw new A("display-label has no labelTarget",t);let s=U(n,g.labelSource);if(!s)throw new A("display-label has no labelSource",t);return{kind:"display-label",labelTarget:{publisher:a.publisher,package_:a.package_,name:a.name},labelSource:{publisher:s.publisher,package_:s.package_,name:s.name}}}case"resolve-ref":return{kind:"resolve-ref",source:I(n,g.resolveSource,e,`${t}.resolveSource`)};case"call-fragment":{if(e.depth>=qn)throw new A(`call-fragment recursion exceeded ${qn} levels (cycle?)`,t);let a=U(n,g.fragmentRef);if(!a)throw new A("call-fragment has no fragmentRef",t);let s=Mr(e.catalog,a);if(!s)throw new A(`call-fragment: no ExpressionFragment found matching ${a.publisher}/${a.package_}/${a.name} \u2014 either the fragment is missing or its package is not in the compilation catalog`,t);let c=H(s,g.expr);if(!c)throw new A(`ExpressionFragment "${s.name}" has no expr`,t);let i={catalog:e.catalog,depth:e.depth+1};return ee(c,i,`${t}\u2192fragment[${s.name}]`)}default:throw new A(`Unknown ExpressionKind "${r}"`,t)}}function Mr(n,e){for(let t of n)if(t instanceof xr&&t.name===e.name&&t.namespace&&t.namespace.startsWith(`${e.publisher}/${e.package_}@`)&&Br(t))return t}function Br(n){for(let e of n.statement){let t=e.predicate;if(!(!t||t.subject?.name!=="type")&&e instanceof Ze){let o=e.object.subject;if(o.publisher===g.ExpressionFragment.publisher&&o.package_===g.ExpressionFragment.package_&&o.name===g.ExpressionFragment.name)return!0}}return!1}function Vr(n,e,t){let o=U(n,g.astClass);if(!o)throw new A("build-ast-node has no astClass",t);let r={publisher:o.publisher,package_:o.package_,name:o.name},a=[];return ve(n,g.set).forEach((c,i)=>{let l=`${t}.set[${i}]`,u=U(c,g.field);if(!u)throw new A("AstFieldBinding has no field",l);let d=I(c,g.bindValue,e,`${l}.bindValue`);a.push({field:{publisher:u.publisher,package_:u.package_,name:u.name},value:d})}),{kind:"build-ast-node",astClass:r,set:a}}function Hr(n,e,t){return{kind:"for-each",iterate:I(n,g.iterate,e,`${t}.iterate`),loopVar:ue(n,g.loopVar,t),emit:I(n,g.emit,e,`${t}.emit`)}}function zr(n,e,t){let o=H(n,g.elseBuild);return{kind:"when",condition:I(n,g.condition,e,`${t}.condition`),thenBuild:I(n,g.thenBuild,e,`${t}.thenBuild`),elseBuild:o?ee(o,e,`${t}.elseBuild`):void 0}}function qr(n,e,t){return{kind:"concat",parts:ve(n,g.parts).map((r,a)=>ee(r,e,`${t}.parts[${a}]`))}}function Gr(n,e,t){let o=U(n,g.readProp);if(!o)throw new A("property-read has no readProp",t);return{kind:"property-read",source:I(n,g.readSource,e,`${t}.readSource`),readProp:{publisher:o.publisher,package_:o.package_,name:o.name}}}function Wr(n,e,t){let o=U(n,g.through);if(!o)throw new A("traverse has no through",t);return{kind:"traverse",source:I(n,g.traverseSource,e,`${t}.traverseSource`),through:{publisher:o.publisher,package_:o.package_,name:o.name},step:I(n,g.step,e,`${t}.step`)}}function Xr(n,e,t){return{kind:"fallback",primary:I(n,g.primary,e,`${t}.primary`),alternate:I(n,g.alternate,e,`${t}.alternate`)}}function Jr(n,e,t){return{kind:"list-map",source:I(n,g.listMapSource,e,`${t}.listMapSource`),loopVar:ue(n,g.loopVar,t),mapBody:I(n,g.mapBody,e,`${t}.mapBody`)}}function Yr(n,e,t){let o=U(n,g.normKind);if(!o)throw new A("normalize has no normKind",t);let r=o.name;if(r!=="trim-end")throw new A(`Unknown NormalizeKind "${r}"`,t);return{kind:"normalize",source:I(n,g.normSource,e,`${t}.normSource`),normKind:r}}function I(n,e,t,o){let r=H(n,e);if(!r){let a=`${e.publisher}/${e.package_}/${e.name}`,s=n.statement.length,c=n.statement.some(u=>{let d=u.predicate?.subject;return d&&d.publisher==="kanonak.org"&&d.package_==="transformations"&&d.name==="kind"}),i=`${e.publisher}/${e.package_}`,l;throw s===0?l=" (parent Expression has no statements at all \u2014 the parser produced an empty node, which usually means the containing YAML block did not resolve to an Expression-typed embedded)":c&&s<3?l=` \u2014 expected property ${a} but the parent Expression only has ${s} statement(s) including its 'kind'. The most likely cause is a STALE local copy of the Kanonak package ${i} that declares the expression kind but not the '${e.name}' property. Refresh your workspace copy of ${i} and re-resolve imports so the runner picks up the current property definitions.`:l=` \u2014 expected property ${a}. Parent Expression has ${s} statement(s) but none match that predicate URI. Either the YAML is missing the '${e.name}' key for this expression kind, or your local copy of the Kanonak package ${i} is out of date.`,new A(`missing child expression${l}`,o)}return ee(r,t,o)}function ue(n,e,t){let o=P(n,e);if(typeof o!="string")throw new A(`missing required string property "${e.name}"`,t);return o}function Zr(n,e,t){let o=le(n,e);if(typeof o!="number")throw new A(`missing required integer property "${e.name}"`,t);return o}function Qr(n,e,t){let o=le(n,e);if(typeof o!="boolean")throw new A(`missing required boolean property "${e.name}"`,t);return o}function Jn(n,e){return n.publisher===e.publisher&&n.package_===e.package_&&n.name===e.name}var De=class{backendUri="kanonak.org/transformations/markdown-with-frontmatter";render(e,t){let o=ea(e.metadata,t),r=oa(e.children),s=["---",...o,"---","",r].join(`
57
+ ${t}`),process.exit(1)}}import{Command as br}from"commander";import{KanonakParser as wr,KanonakObjectParser as $r,PublisherIndex as Sr,CredentialStore as vr,createAuthenticatedFetch as Dr,computeIntegrity as Kr}from"@kanonak-protocol/sdk";import{readFileSync as Vo,writeFileSync as Ho,existsSync as zo}from"fs";import{join as qo}from"path";import An from"js-yaml";import{getGlobalCachePath as Go}from"@kanonak-protocol/sdk";var Wo=`# This file is generated by Kanonak CLI. Do not edit manually.
58
+ `;function Cn(){let n=Go();return qo(n,"..","capabilities.lock")}function Q(){let n=Cn();if(!zo(n))return{version:"1",lastUpdated:new Date().toISOString(),capabilities:{}};let e=Vo(n,"utf-8"),t=An.load(e);return!t||typeof t!="object"||t.version!=="1"?{version:"1",lastUpdated:new Date().toISOString(),capabilities:{}}:{version:"1",lastUpdated:t.lastUpdated??new Date().toISOString(),capabilities:t.capabilities??{}}}function ce(n){n.lastUpdated=new Date().toISOString();let e={};for(let o of Object.keys(n.capabilities).sort())e[o]=n.capabilities[o];n.capabilities=e;let t=An.dump(n,{lineWidth:-1,sortKeys:!1,quotingType:'"'});Ho(Cn(),Wo+t,"utf-8")}var A=class{constructor(e,t){this.doc=e;this.broader=t}doc;broader;async getAllDocumentsAsync(){return[this.doc]}async getDocumentAsync(e){return this.broader.getDocumentAsync(e)}async getDocumentsByNamespaceAsync(e,t){return this.broader.getDocumentsByNamespaceAsync(e,t)}async getHighestCompatibleVersionAsync(e,t){return this.broader.getHighestCompatibleVersionAsync(e,t)}async saveDocumentAsync(){throw new Error("SingleDocumentRepository is read-only")}async deleteDocumentAsync(){throw new Error("SingleDocumentRepository is read-only")}async clearNamespaceAsync(){throw new Error("SingleDocumentRepository is read-only")}async getAllDocumentReferencesAsync(){return[]}async getDocumentContentAsync(e){return this.broader.getDocumentContentAsync(e)}async getDocumentUriAsync(e){return this.broader.getDocumentUriAsync(e)}};import{existsSync as tr,readdirSync as or,readFileSync as rr}from"fs";import{join as _n}from"path";import{KanonakObjectParser as ar,EmbeddedKanonak as xn,ReferenceKanonak as jn,getGlobalCachePath as sr}from"@kanonak-protocol/sdk";import{SubjectKanonak as Pn,DefinedKanonak as Xo,StringStatement as Jo,NumberStatement as Yo,BooleanStatement as Zo,ReferenceStatement as En,EmbeddedStatement as Qo,ListStatement as er}from"@kanonak-protocol/sdk";function N(n){return`${n.publisher}/${n.package_}/${n.name}`}function F(n,e){return n.publisher===e.publisher&&n.package_===e.package_&&n.name===e.name}function nr(n,e){if(!(n instanceof Xo))return!1;for(let t of n.statement)if(t.predicate?.subject?.name==="type"&&t instanceof En){let r=t.object;if(F(r.subject,e))return!0}return!1}function P(n,e){let t=[];for(let o of n)o instanceof Pn&&nr(o,e)&&t.push(o);return t}function he(n,e){for(let t of n){if(!(t instanceof Pn)||t.name!==e.name)continue;if((t.namespace||"").startsWith(`${e.publisher}/${e.package_}@`))return t}}function ke(n,e){for(let t of n.statement){let o=t.predicate;if(o?.subject&&F(o.subject,e))return t}}function le(n,e){let t=ke(n,e);if(t&&(t instanceof Jo||t instanceof Yo||t instanceof Zo))return t.object}function C(n,e){let t=le(n,e);return typeof t=="string"?t:void 0}function M(n,e){let t=ke(n,e);if(t instanceof En)return t.object.subject}function V(n,e){let t=ke(n,e);if(t instanceof Qo)return t.object}function ee(n,e){let t=ke(n,e);return t instanceof er?t.object??[]:[]}var E="kanonak.org",_="capabilities",qe={publisher:E,package_:_,name:"Capability"},ir={publisher:E,package_:_,name:"commandName"},Un={publisher:E,package_:_,name:"description"},cr={publisher:E,package_:_,name:"managesType"},lr={publisher:E,package_:_,name:"deploymentTarget"},ur={publisher:E,package_:_,name:"hasCommand"},dr={publisher:E,package_:_,name:"subcommandName"},mr={publisher:E,package_:_,name:"performs"},pr={publisher:E,package_:_,name:"hasArgument"},fr={publisher:E,package_:_,name:"argumentName"},In={publisher:E,package_:_,name:"isRequired"},Rn={publisher:E,package_:_,name:"isOption"},gr={publisher:E,package_:_,name:"defaultValue"};async function Nn(n,e,t){let o=Q(),r=new ar,a=[],s=!1;for(let[i,c]of Object.entries(o.capabilities)){let l=c,u=n.get(l.publisher,l.package_,l.version);if(!u){let d=await hr(i,l,e,r,t);if(d)console.error(` Healed capability "${i}": ${l.publisher}/${l.package_}@${l.version} \u2192 ${d.entry.publisher}/${d.entry.package_}@${d.entry.version} (package was renamed)`),o.capabilities[i]=d.entry,l=d.entry,u=d.content,s=!0;else{console.error(` WARNING: Cached content missing for capability "${i}" (${l.publisher}/${l.package_}@${l.version}). Reinstall it with: kanonak capability remove ${i} && kanonak capability add ${l.publisher}/${l.package_}`);continue}}try{let d=e.parse(u),m=new A(d,t),g=await r.parseKanonaks(m),h=On(g,l.publisher,l.package_,l.version);h?a.push(h):console.error(` WARNING: No Capability instance found in "${i}" (${l.publisher}/${l.package_}@${l.version})`)}catch(d){console.error(` WARNING: Failed to parse capability "${i}": ${d}`)}}return s&&ce(o),a}async function hr(n,e,t,o,r){let a=_n(sr(),e.publisher);if(!tr(a))return;let s=[];for(let i of or(a)){if(!i.endsWith(".kan.yml"))continue;let c=i.slice(0,-8),l=c.lastIndexOf("@");if(l===-1)continue;let u=c.substring(0,l),d=c.substring(l+1);if(u===e.package_&&d===e.version)continue;let m;try{m=rr(_n(a,i),"utf-8")}catch{continue}let g;try{let h=t.parse(m),f=new A(h,r),k=await o.parseKanonaks(f);g=On(k,e.publisher,u,d)?.commandName}catch{continue}g===n&&s.push({entry:{publisher:e.publisher,package_:u,version:d,resolved:`kanonak://${e.publisher}/${u}@${d}`,integrity:""},content:m})}if(s.length===1)return s[0]}function On(n,e,t,o){let r=P(n,qe);if(r.length===0)return;let a=r[0],s=C(a,ir)??"",i=C(a,Un)??"",c=M(a,cr),l=M(a,lr),u=[];for(let d of ee(a,ur)){let m=kr(d,n);m&&u.push(m)}return{commandName:s,description:i,managesTypeKey:c?N(c):"",deploymentTargetKey:l?N(l):"",commands:u,publisher:e,package_:t,version:o}}function kr(n,e){let t;if(n instanceof xn)t=n;else if(n instanceof jn){let c=Ln(e,n.subject.publisher,n.subject.package_,n.subject.name);c&&(t=c)}if(!t)return;let o=C(t,dr)??"",r=C(t,Un)??"",a=M(t,mr),s=ee(t,pr),i=[];for(let c of s){let l=yr(c,e);l&&i.push(l)}return{subcommandName:o,description:r,arguments:i,actionKey:a?N(a):""}}function yr(n,e){let t;if(n instanceof xn)t=n;else if(n instanceof jn){let c=Ln(e,n.subject.publisher,n.subject.package_,n.subject.name);c&&(t=c)}if(!t)return;let o=C(t,fr)??"",r=C(t,In)==="true"||Tn(t,In)===!0,a=C(t,Rn)==="true"||Tn(t,Rn)===!0,s=C(t,gr),i={argumentName:o,required:r,isOption:a};return s!==void 0&&(i.defaultValue=s),i}function Tn(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 Ln(n,e,t,o){for(let r of n){if(!("name"in r)||!("namespace"in r))continue;let a=r;if(a.name===o&&!(!a.namespace||typeof a.namespace!="string")&&a.namespace.startsWith(`${e}/${t}@`))return r}}var Ar={publisher:E,package_:_,name:"commandName"};function Fn(){let n=new br("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 Cr(e)}),n.command("remove <name>").description("Remove an installed capability").action(async e=>{await Pr(e)}),n.command("list").description("List installed capabilities").action(async()=>{await Er()}),n}async function Cr(n){let e=X(n);e||(console.error(`Invalid package reference: "${n}"`),console.error("Expected format: {publisher}/{package}[@{version}]"),process.exit(1));let{publisher:t,packageName:o,version:r,instanceName:a}=e;a&&(console.error(`\`kanonak capability add\` installs whole packages \u2014 got an instance suffix "/${a}".`),console.error(`Try: kanonak capability add ${t}/${o}${r?"@"+r:""}`),process.exit(1));let s=new T,i=new wr,c=new $r,l=new vr,u=Dr(l),d=new Sr({fetchFn:u}),m=r??await d.getHighestVersion(t,o);m||(console.error(`Could not resolve version for "${t}/${o}".`),process.exit(1)),console.log(`Installing capability ${t}/${o}@${m}...`);let g=s.get(t,o,m);if(!g){let W=await d.getPackageUrl(t,o,m),fe=await u(W,t);if(!fe.ok)throw new Error(`Failed to fetch ${W} (${fe.status} ${fe.statusText})`);g=await fe.text(),s.put(t,o,m,g)}let h=i.parse(g),f=await x(process.cwd(),i),k=new A(h,f),y=await c.parseKanonaks(k),w=P(y,qe);w.length===0&&(console.error(`Package ${t}/${o}@${m} does not contain a ${E}/${_}/Capability instance.`),process.exit(1));let $=w[0],v=C($,Ar);v||(console.error(`Capability instance in ${t}/${o}@${m} has no commandName property.`),process.exit(1));let D=Q();D.capabilities[v]={publisher:t,package_:o,version:m,resolved:await d.getPackageUrl(t,o,m),integrity:Kr(g)},ce(D),console.log(`
59
+ Installed capability "${v}".`),console.log(`Run "kanonak ${v} --help" to get started.`)}async function Pr(n){let e=Q();e.capabilities[n]||(console.error(`Capability "${n}" is not installed.`),process.exit(1));let t=e.capabilities[n];delete e.capabilities[n],ce(e),console.log(`Removed capability "${n}" (${t.publisher}/${t.package_}@${t.version}).`)}async function Er(){let n=Q(),e=Object.entries(n.capabilities);if(e.length===0){console.log("No capabilities installed."),console.log("Install one with: kanonak capability add {publisher}/{package}");return}console.log(`Installed capabilities:
60
+ `);for(let[t,o]of e)console.log(` ${t} ${o.publisher}/${o.package_}@${o.version}`)}import{Command as me}from"commander";import{readFileSync as xa,writeFileSync as ja,mkdirSync as Ua,existsSync as it,statSync as Na}from"fs";import{join as Oa,resolve as La}from"path";import{KanonakParser as Qe,KanonakObjectParser as en,SubjectKanonak as Fa,Reasoner as Ma,KanonakVocabulary as Ba,makeUriKey as lt,pickHighestDocument as nn,formatVersion as ut}from"@kanonak-protocol/sdk";var _r="kanonak.org",Ir="document-ast",S=n=>({publisher:_r,package_:Ir,name:n}),j={Document:S("Document"),Block:S("Block"),Inline:S("Inline"),StructuredValue:S("StructuredValue"),Heading:S("Heading"),Paragraph:S("Paragraph"),RawBlock:S("RawBlock"),Text:S("Text"),StructuredMap:S("StructuredMap"),StructuredEntry:S("StructuredEntry"),StructuredList:S("StructuredList"),StringScalar:S("StringScalar"),IntegerScalar:S("IntegerScalar"),EscapeHint:S("EscapeHint"),MediaType:S("MediaType"),metadata:S("metadata"),children:S("children"),level:S("level"),inlines:S("inlines"),text:S("text"),entries:S("entries"),key:S("key"),value:S("value"),escapeHint:S("escapeHint"),items:S("items"),stringValue:S("stringValue"),integerValue:S("integerValue"),rawContent:S("rawContent"),mediaType:S("mediaType"),mimeType:S("mimeType"),ESC_RAW:S("esc-raw"),ESC_YAML_SAFE:S("esc-yaml-safe"),ESC_TOML_STRING:S("esc-toml-string"),ESC_TOML_MULTILINE:S("esc-toml-multiline"),ESC_JSON:S("esc-json"),TEXT_PLAIN:S("text-plain"),TEXT_MARKDOWN:S("text-markdown"),TEXT_HTML:S("text-html"),APPLICATION_JSON:S("application-json"),TEXT_YAML:S("text-yaml"),IMAGE_SVG_XML:S("image-svg-xml")},Rr="kanonak.org",Tr="transformations",p=n=>({publisher:Rr,package_:Tr,name:n}),b={Transformation:p("Transformation"),InputPattern:p("InputPattern"),Expression:p("Expression"),ExpressionKind:p("ExpressionKind"),ExpressionFragment:p("ExpressionFragment"),AstFieldBinding:p("AstFieldBinding"),OutputFormat:p("OutputFormat"),FormatOverride:p("FormatOverride"),RenameEntry:p("RenameEntry"),Artifact:p("Artifact"),NormalizeKind:p("NormalizeKind"),inputPattern:p("inputPattern"),rule:p("rule"),artifactName:p("artifactName"),outputs:p("outputs"),formatOverrides:p("formatOverrides"),matchesClass:p("matchesClass"),requires:p("requires"),kind:p("kind"),astClass:p("astClass"),set:p("set"),iterate:p("iterate"),loopVar:p("loopVar"),emit:p("emit"),condition:p("condition"),thenBuild:p("thenBuild"),elseBuild:p("elseBuild"),parts:p("parts"),stringLiteral:p("stringLiteral"),integerLiteral:p("integerLiteral"),booleanLiteral:p("booleanLiteral"),varName:p("varName"),readSource:p("readSource"),readProp:p("readProp"),traverseSource:p("traverseSource"),through:p("through"),step:p("step"),primary:p("primary"),alternate:p("alternate"),uriNameOf:p("uriNameOf"),listMapSource:p("listMapSource"),mapBody:p("mapBody"),separator:p("separator"),items:p("items"),normSource:p("normSource"),normKind:p("normKind"),checkExpr:p("checkExpr"),refTo:p("refTo"),fragmentRef:p("fragmentRef"),expr:p("expr"),labelTarget:p("labelTarget"),labelSource:p("labelSource"),resolveSource:p("resolveSource"),field:p("field"),bindValue:p("bindValue"),backendUri:p("backendUri"),formatTarget:p("formatTarget"),metadataKeys:p("metadataKeys"),metadataRenames:p("metadataRenames"),trailingNewline:p("trailingNewline"),fromKey:p("fromKey"),toKey:p("toKey"),KIND_BUILD_AST_NODE:p("build-ast-node"),KIND_FOR_EACH:p("for-each"),KIND_WHEN:p("when"),KIND_CONCAT:p("concat"),KIND_STRING_LITERAL:p("string-literal"),KIND_INTEGER_LITERAL:p("integer-literal"),KIND_BOOLEAN_LITERAL:p("boolean-literal"),KIND_VAR_REF:p("var-ref"),KIND_PROPERTY_READ:p("property-read"),KIND_TRAVERSE:p("traverse"),KIND_FALLBACK:p("fallback"),KIND_URI_NAME:p("uri-name"),KIND_LIST_MAP:p("list-map"),KIND_JOIN:p("join"),KIND_NORMALIZE:p("normalize"),KIND_IS_SET:p("is-set"),KIND_URI_LITERAL:p("uri-literal"),KIND_CALL_FRAGMENT:p("call-fragment"),KIND_DISPLAY_LABEL:p("display-label"),KIND_RESOLVE_REF:p("resolve-ref"),NORM_TRIM_END:p("trim-end"),FMT_MARKDOWN_FRONTMATTER:p("markdown-with-frontmatter"),FMT_TOML:p("toml"),FMT_JSON:p("json"),FMT_PLAIN_MARKDOWN:p("plain-markdown")};import{SubjectKanonak as Mn}from"@kanonak-protocol/sdk";var ye=class{constructor(e,t,o){this.repository=e;this.parser=t;this.objectParser=o}repository;parser;objectParser;cache=new Map;async resolveSubject(e,t){let o=he(t,e);if(o)return o;let r=`${e.publisher}/${e.package_}`,a=this.cache.get(r);if(!a){let s=await this.repository.getDocumentsByNamespaceAsync(e.publisher,e.package_);if(s.length===0)return;let i=s[0],c=new A(i,this.repository);a=await this.objectParser.parseKanonaks(c),this.cache.set(r,a)}for(let s of a)if(s instanceof Mn&&s.name===e.name&&s.namespace&&s.namespace.startsWith(`${e.publisher}/${e.package_}@`))return s;for(let s of a)if(s instanceof Mn&&s.name===e.name)return s}};import{DefinedKanonak as Bn,LiteralKanonak as xr,ReferenceKanonak as be,StringStatement as jr,NumberStatement as Ur,BooleanStatement as Nr,ReferenceStatement as Or,EmbeddedStatement as Lr,ListStatement as Fr}from"@kanonak-protocol/sdk";var we=class extends Error{constructor(e){super(e)}},$e=class{constructor(e,t){this.resolver=e;this.allKanonaks=t}resolver;allKanonaks;async evaluate(e,t){switch(e.kind){case"var-ref":{if(!t.has(e.varName))throw new we(`Unbound variable "${e.varName}"`);return t.get(e.varName)}case"string-literal":return e.value;case"integer-literal":return e.value;case"boolean-literal":return e.value;case"uri-literal":return{...e.refTo};case"property-read":{let o=await this.evaluate(e.source,t);return o instanceof Bn?Ge(o,e.readProp):void 0}case"traverse":{let o=await this.evaluate(e.source,t);if(!(o instanceof Bn))return;let r=Ge(o,e.through),a;if(r instanceof be?a=r.subject:Array.isArray(r)&&r.length>0&&r[0]instanceof be&&(a=r[0].subject),!a)return;let s=await this.resolver.resolveSubject(a,this.allKanonaks);if(!s)return;let i=new Map(t);return i.set("input",s),this.evaluate(e.step,i)}case"fallback":{let o=await this.evaluate(e.primary,t);return Hn(o)?o:this.evaluate(e.alternate,t)}case"uri-name":{let o=await this.evaluate(e.of,t);return o instanceof be?o.subject.name:zn(o)?o.name:void 0}case"list-map":{let o=await this.evaluate(e.source,t),r=We(o),a=[];for(let s of r){let i=new Map(t);i.set(e.loopVar,s),a.push(await this.evaluate(e.mapBody,i))}return a}case"join":{let o=await this.evaluate(e.items,t),r=We(o),a=[];for(let s of r)s!=null&&a.push(String(s));return a.join(e.separator)}case"normalize":{let o=await this.evaluate(e.source,t);return typeof o!="string"?o:e.normKind==="trim-end"?o.trimEnd():o}case"is-set":{let o=await this.evaluate(e.check,t);return Hn(o)}case"when":{let o=await this.evaluate(e.condition,t);return Hr(o)?this.evaluate(e.thenBuild,t):e.elseBuild?this.evaluate(e.elseBuild,t):void 0}case"concat":{let o=[];for(let r of e.parts){let a=await this.evaluate(r,t);if(a!=null)if(Array.isArray(a))for(let s of a)o.push(s);else o.push(a)}return o}case"for-each":{let o=await this.evaluate(e.iterate,t),r=We(o),a=[];for(let s of r){let i=new Map(t);i.set(e.loopVar,s);let c=await this.evaluate(e.emit,i);if(c!=null)if(Array.isArray(c))for(let l of c)a.push(l);else a.push(c)}return a}case"build-ast-node":return this.buildAstNode(e,t);case"resolve-ref":{let o=await this.evaluate(e.source,t),r;return o instanceof be?r=o.subject:zn(o)&&(r=o),r?this.resolver.resolveSubject(r,this.allKanonaks):void 0}case"display-label":{let o={publisher:e.labelTarget.publisher,package_:e.labelTarget.package_,name:e.labelTarget.name},r=await this.resolver.resolveSubject(o,this.allKanonaks);if(r){let a=Ge(r,e.labelSource);if(typeof a=="string"&&a.length>0)return a}return e.labelTarget.name}default:{let o=e;throw new we(`Unhandled expression kind: ${JSON.stringify(o)}`)}}}async buildAstNode(e,t){let o={kind:e.astClass.name};for(let r of e.set){let a=await this.evaluate(r.value,t);if(a==null||Array.isArray(a)&&a.length===0)continue;let s=r.field.name;Array.isArray(a)&&Mr.has(s)&&a.every(i=>Br(i))&&(a=a.map(i=>String(i)).join("")),o[s]=a}return o}},Mr=new Set(["stringValue","text","rawContent","key"]);function Br(n){return typeof n=="string"||typeof n=="number"||typeof n=="boolean"}function Ge(n,e){let t=[];for(let r of n.statement){let a=r.predicate;a?.subject&&F(a.subject,e)&&t.push(r)}if(t.length===0)return;if(t.length===1&&t[0]instanceof Fr)return Vr(t[0].object);if(t.length===1)return Vn(t[0]);let o=[];for(let r of t){let a=Vn(r);a!==void 0&&o.push(a)}return o}function Vr(n){let e=[];for(let t of n)t instanceof xr?e.push(t.value):e.push(t);return e}function Vn(n){if(n instanceof jr||n instanceof Ur||n instanceof Nr||n instanceof Or||n instanceof Lr)return n.object}function Hn(n){return n==null?!1:typeof n=="string"||Array.isArray(n)?n.length>0:!0}function Hr(n){return n==null?!1:typeof n=="boolean"?n:typeof n=="string"?n.length>0:typeof n=="number"?n!==0:Array.isArray(n)?n.length>0:!0}function We(n){return n==null?[]:Array.isArray(n)?n:[n]}function zn(n){return n!==null&&typeof n=="object"&&"publisher"in n&&"package_"in n&&"name"in n}import{EmbeddedKanonak as zr,LiteralKanonak as qr,ReferenceKanonak as Xe,SubjectKanonak as Gr,ListStatement as Gn,StringStatement as Wr,ReferenceStatement as Je}from"@kanonak-protocol/sdk";var K=class extends Error{constructor(t,o){super(`${t} (at ${o})`);this.path=o}path},qn=16;function Xr(n){return n.predicate?.subject}function Wn(n,e){let t=[];for(let o of n.statement){let r=Xr(o);r&&F(r,e)&&t.push(o)}return t}function U(n,e){let t=M(n,e);if(t)return t;let o=ee(n,e);if(o.length===1&&o[0]instanceof Xe)return o[0].subject}function Se(n,e){let t=ee(n,e),o=[];for(let r of t)r instanceof zr&&o.push(r);return o}function Xn(n,e){let t=[];for(let o of Wn(n,e))if(o instanceof Wr)t.push(o.object);else if(o instanceof Gn)for(let r of o.object)typeof r=="string"?t.push(r):r instanceof qr?typeof r.value=="string"&&t.push(r.value):r instanceof Xe&&t.push(r.subject.name);else o instanceof Je&&t.push(o.object.subject.name);return t}function Jr(n,e){let t=n.split("/");if(t.length<3)throw new K(`Invalid property URI "${n}" \u2014 expected publisher/package/name`,e);let[o,r,...a]=t;return{publisher:o,package_:r,name:a.join("/")}}function te(n,e){let t=n.name,o=`transformation[${t}]`,r={catalog:e,depth:0},a=V(n,b.inputPattern);if(!a)throw new K("Transformation has no inputPattern",o);let s=Yr(a,r,`${o}.inputPattern`),i=V(n,b.rule);if(!i)throw new K("Transformation has no rule",o);let c=ne(i,r,`${o}.rule`),l=V(n,b.artifactName);if(!l)throw new K("Transformation has no artifactName",o);let u=ne(l,r,`${o}.artifactName`),d=new Set;for(let g of Wn(n,b.outputs))if(g instanceof Je)d.add(g.object.subject.name);else if(g instanceof Gn)for(let h of g.object)h instanceof Xe&&d.add(h.subject.name);if(d.size===0)throw new K("Transformation has no outputs",o);let m=new Map;for(let g of Se(n,b.formatOverrides)){let h=`${o}.formatOverrides[]`,f=U(g,b.formatTarget);if(!f)throw new K("FormatOverride missing formatTarget",h);m.set(f.name,Zr(g,h))}return{name:t,inputPattern:s,rule:c,artifactName:u,outputs:d,overrides:m}}function Yr(n,e,t){let o=U(n,b.matchesClass);if(!o)throw new K("InputPattern has no matchesClass",t);let r={publisher:o.publisher,package_:o.package_,name:o.name},s=Xn(n,b.requires).map((i,c)=>Jr(i,`${t}.requires[${c}]`));return{matchesClass:r,requires:s}}function Zr(n,e){let t=Xn(n,b.metadataKeys),o=t.length>0?t:void 0,r=new Map;for(let i of Se(n,b.metadataRenames)){let c=C(i,b.fromKey),l=C(i,b.toKey);c&&l&&r.set(c,l)}let a=le(n,b.trailingNewline);return{metadataKeys:o,metadataRenames:r,trailingNewline:typeof a=="boolean"?a:void 0}}function ne(n,e,t){let o=U(n,b.kind);if(!o)throw new K("Expression has no kind",t);let r=o.name;switch(r){case"build-ast-node":return na(n,e,t);case"for-each":return ta(n,e,t);case"when":return oa(n,e,t);case"concat":return ra(n,e,t);case"string-literal":return{kind:"string-literal",value:ue(n,b.stringLiteral,t)};case"integer-literal":return{kind:"integer-literal",value:ua(n,b.integerLiteral,t)};case"boolean-literal":return{kind:"boolean-literal",value:da(n,b.booleanLiteral,t)};case"var-ref":return{kind:"var-ref",varName:ue(n,b.varName,t)};case"property-read":return aa(n,e,t);case"traverse":return sa(n,e,t);case"fallback":return ia(n,e,t);case"uri-name":return{kind:"uri-name",of:I(n,b.uriNameOf,e,`${t}.uriNameOf`)};case"list-map":return ca(n,e,t);case"join":return{kind:"join",separator:ue(n,b.separator,t),items:I(n,b.items,e,`${t}.items`)};case"normalize":return la(n,e,t);case"is-set":return{kind:"is-set",check:I(n,b.checkExpr,e,`${t}.checkExpr`)};case"uri-literal":{let a=U(n,b.refTo);if(!a)throw new K("uri-literal has no refTo",t);return{kind:"uri-literal",refTo:{publisher:a.publisher,package_:a.package_,name:a.name}}}case"display-label":{let a=U(n,b.labelTarget);if(!a)throw new K("display-label has no labelTarget",t);let s=U(n,b.labelSource);if(!s)throw new K("display-label has no labelSource",t);return{kind:"display-label",labelTarget:{publisher:a.publisher,package_:a.package_,name:a.name},labelSource:{publisher:s.publisher,package_:s.package_,name:s.name}}}case"resolve-ref":return{kind:"resolve-ref",source:I(n,b.resolveSource,e,`${t}.resolveSource`)};case"call-fragment":{if(e.depth>=qn)throw new K(`call-fragment recursion exceeded ${qn} levels (cycle?)`,t);let a=U(n,b.fragmentRef);if(!a)throw new K("call-fragment has no fragmentRef",t);let s=Qr(e.catalog,a);if(!s)throw new K(`call-fragment: no ExpressionFragment found matching ${a.publisher}/${a.package_}/${a.name} \u2014 either the fragment is missing or its package is not in the compilation catalog`,t);let i=V(s,b.expr);if(!i)throw new K(`ExpressionFragment "${s.name}" has no expr`,t);let c={catalog:e.catalog,depth:e.depth+1};return ne(i,c,`${t}\u2192fragment[${s.name}]`)}default:throw new K(`Unknown ExpressionKind "${r}"`,t)}}function Qr(n,e){for(let t of n)if(t instanceof Gr&&t.name===e.name&&t.namespace&&t.namespace.startsWith(`${e.publisher}/${e.package_}@`)&&ea(t))return t}function ea(n){for(let e of n.statement){let t=e.predicate;if(!(!t||t.subject?.name!=="type")&&e instanceof Je){let o=e.object.subject;if(o.publisher===b.ExpressionFragment.publisher&&o.package_===b.ExpressionFragment.package_&&o.name===b.ExpressionFragment.name)return!0}}return!1}function na(n,e,t){let o=U(n,b.astClass);if(!o)throw new K("build-ast-node has no astClass",t);let r={publisher:o.publisher,package_:o.package_,name:o.name},a=[];return Se(n,b.set).forEach((i,c)=>{let l=`${t}.set[${c}]`,u=U(i,b.field);if(!u)throw new K("AstFieldBinding has no field",l);let d=I(i,b.bindValue,e,`${l}.bindValue`);a.push({field:{publisher:u.publisher,package_:u.package_,name:u.name},value:d})}),{kind:"build-ast-node",astClass:r,set:a}}function ta(n,e,t){return{kind:"for-each",iterate:I(n,b.iterate,e,`${t}.iterate`),loopVar:ue(n,b.loopVar,t),emit:I(n,b.emit,e,`${t}.emit`)}}function oa(n,e,t){let o=V(n,b.elseBuild);return{kind:"when",condition:I(n,b.condition,e,`${t}.condition`),thenBuild:I(n,b.thenBuild,e,`${t}.thenBuild`),elseBuild:o?ne(o,e,`${t}.elseBuild`):void 0}}function ra(n,e,t){return{kind:"concat",parts:Se(n,b.parts).map((r,a)=>ne(r,e,`${t}.parts[${a}]`))}}function aa(n,e,t){let o=U(n,b.readProp);if(!o)throw new K("property-read has no readProp",t);return{kind:"property-read",source:I(n,b.readSource,e,`${t}.readSource`),readProp:{publisher:o.publisher,package_:o.package_,name:o.name}}}function sa(n,e,t){let o=U(n,b.through);if(!o)throw new K("traverse has no through",t);return{kind:"traverse",source:I(n,b.traverseSource,e,`${t}.traverseSource`),through:{publisher:o.publisher,package_:o.package_,name:o.name},step:I(n,b.step,e,`${t}.step`)}}function ia(n,e,t){return{kind:"fallback",primary:I(n,b.primary,e,`${t}.primary`),alternate:I(n,b.alternate,e,`${t}.alternate`)}}function ca(n,e,t){return{kind:"list-map",source:I(n,b.listMapSource,e,`${t}.listMapSource`),loopVar:ue(n,b.loopVar,t),mapBody:I(n,b.mapBody,e,`${t}.mapBody`)}}function la(n,e,t){let o=U(n,b.normKind);if(!o)throw new K("normalize has no normKind",t);let r=o.name;if(r!=="trim-end")throw new K(`Unknown NormalizeKind "${r}"`,t);return{kind:"normalize",source:I(n,b.normSource,e,`${t}.normSource`),normKind:r}}function I(n,e,t,o){let r=V(n,e);if(!r){let a=`${e.publisher}/${e.package_}/${e.name}`,s=n.statement.length,i=n.statement.some(u=>{let d=u.predicate?.subject;return d&&d.publisher==="kanonak.org"&&d.package_==="transformations"&&d.name==="kind"}),c=`${e.publisher}/${e.package_}`,l;throw s===0?l=" (parent Expression has no statements at all \u2014 the parser produced an empty node, which usually means the containing YAML block did not resolve to an Expression-typed embedded)":i&&s<3?l=` \u2014 expected property ${a} but the parent Expression only has ${s} statement(s) including its 'kind'. The most likely cause is a STALE local copy of the Kanonak package ${c} that declares the expression kind but not the '${e.name}' property. Refresh your workspace copy of ${c} and re-resolve imports so the runner picks up the current property definitions.`:l=` \u2014 expected property ${a}. Parent Expression has ${s} statement(s) but none match that predicate URI. Either the YAML is missing the '${e.name}' key for this expression kind, or your local copy of the Kanonak package ${c} is out of date.`,new K(`missing child expression${l}`,o)}return ne(r,t,o)}function ue(n,e,t){let o=C(n,e);if(typeof o!="string")throw new K(`missing required string property "${e.name}"`,t);return o}function ua(n,e,t){let o=le(n,e);if(typeof o!="number")throw new K(`missing required integer property "${e.name}"`,t);return o}function da(n,e,t){let o=le(n,e);if(typeof o!="boolean")throw new K(`missing required boolean property "${e.name}"`,t);return o}function Jn(n,e){return n.publisher===e.publisher&&n.package_===e.package_&&n.name===e.name}var ve=class{backendUri="kanonak.org/transformations/markdown-with-frontmatter";render(e,t){let o=ma(e.metadata,t),r=ga(e.children),s=["---",...o,"---","",r].join(`
62
61
  `);return t?.trailingNewline&&(s.endsWith(`
63
62
  `)||(s+=`
64
- `)),s}};function ea(n,e){if(!n)return[];let t=new Map;for(let a of n.entries)t.set(a.key,a);let o=e?.metadataKeys??n.entries.map(a=>a.key),r=[];for(let a of o){let s=t.get(a);if(!s)continue;let c=e?.metadataRenames.get(a)??a,i=Zn(s.value,s.escapeHint);i!==void 0&&r.push(`${c}: ${i}`)}return r}function Zn(n,e){switch(n.kind){case"StringScalar":return na(n.stringValue,e);case"IntegerScalar":return String(n.integerValue);case"StructuredList":{let t=[];for(let o of n.items){let r=Zn(o,e);r!==void 0&&t.push(r)}return t.join(", ")}case"StructuredMap":return;default:return}}function na(n,e){return!e||Jn(e,x.ESC_RAW)?n:Jn(e,x.ESC_YAML_SAFE)?ta(n):n}function ta(n){return n.includes(`
63
+ `)),s}};function ma(n,e){if(!n)return[];let t=new Map;for(let a of n.entries)t.set(a.key,a);let o=e?.metadataKeys??n.entries.map(a=>a.key),r=[];for(let a of o){let s=t.get(a);if(!s)continue;let i=e?.metadataRenames.get(a)??a,c=Zn(s.value,s.escapeHint);c!==void 0&&r.push(`${i}: ${c}`)}return r}function Zn(n,e){switch(n.kind){case"StringScalar":return pa(n.stringValue,e);case"IntegerScalar":return String(n.integerValue);case"StructuredList":{let t=[];for(let o of n.items){let r=Zn(o,e);r!==void 0&&t.push(r)}return t.join(", ")}case"StructuredMap":return;default:return}}function pa(n,e){return!e||Jn(e,j.ESC_RAW)?n:Jn(e,j.ESC_YAML_SAFE)?fa(n):n}function fa(n){return n.includes(`
65
64
  `)?`|-
66
65
  ${n.replace(/\n/g,`
67
- `).trimEnd()}`:/[:#\[\]{}&*!|>'"%@`,]/.test(n)?`"${n.replace(/\\/g,"\\\\").replace(/"/g,'\\"')}"`:n}function oa(n){let e=[];for(let t of n){let o=ra(t);o&&e.push(o)}return e.join(`
66
+ `).trimEnd()}`:/[:#\[\]{}&*!|>'"%@`,]/.test(n)?`"${n.replace(/\\/g,"\\\\").replace(/"/g,'\\"')}"`:n}function ga(n){let e=[];for(let t of n){let o=ha(t);o&&e.push(o)}return e.join(`
68
67
 
69
- `)}function ra(n){switch(n.kind){case"Heading":return`${"#".repeat(n.level)} ${Yn(n.inlines)}`;case"Paragraph":return Yn(n.inlines);case"RawBlock":return n.rawContent;default:return""}}function Yn(n){let e=[];for(let t of n)t.kind==="Text"&&e.push(t.text);return e.join("")}function aa(n,e){return n.publisher===e.publisher&&n.package_===e.package_&&n.name===e.name}var Ae=class{backendUri="kanonak.org/transformations/toml";render(e,t){let r=sa(e.metadata,t).join(`
68
+ `)}function ha(n){switch(n.kind){case"Heading":return`${"#".repeat(n.level)} ${Yn(n.inlines)}`;case"Paragraph":return Yn(n.inlines);case"RawBlock":return n.rawContent;default:return""}}function Yn(n){let e=[];for(let t of n)t.kind==="Text"&&e.push(t.text);return e.join("")}function ka(n,e){return n.publisher===e.publisher&&n.package_===e.package_&&n.name===e.name}var De=class{backendUri="kanonak.org/transformations/toml";render(e,t){let r=ya(e.metadata,t).join(`
70
69
  `);return t?.trailingNewline&&(r.endsWith(`
71
70
  `)||(r+=`
72
- `)),r}};function sa(n,e){if(!n)return[];let t=new Map;for(let a of n.entries)t.set(a.key,a);let o=e?.metadataKeys??n.entries.map(a=>a.key),r=[];for(let a of o){let s=t.get(a);if(!s)continue;let c=e?.metadataRenames.get(a)??a,i=Qn(s.value,s.escapeHint);i!==void 0&&r.push(`${c} = ${i}`)}return r}function Qn(n,e){switch(n.kind){case"StringScalar":return ia(n.stringValue,e);case"IntegerScalar":return String(n.integerValue);case"StructuredList":{let t=[];for(let o of n.items){let r=Qn(o,e);r!==void 0&&t.push(r)}return`[${t.join(", ")}]`}case"StructuredMap":return;default:return}}function ia(n,e){return e&&aa(e,x.ESC_TOML_MULTILINE)?la(n):ca(n)}function ca(n){return`"${n.replace(/\\/g,"\\\\").replace(/"/g,'\\"').replace(/\n/g,"\\n")}"`}function la(n){return`"""
71
+ `)),r}};function ya(n,e){if(!n)return[];let t=new Map;for(let a of n.entries)t.set(a.key,a);let o=e?.metadataKeys??n.entries.map(a=>a.key),r=[];for(let a of o){let s=t.get(a);if(!s)continue;let i=e?.metadataRenames.get(a)??a,c=Qn(s.value,s.escapeHint);c!==void 0&&r.push(`${i} = ${c}`)}return r}function Qn(n,e){switch(n.kind){case"StringScalar":return ba(n.stringValue,e);case"IntegerScalar":return String(n.integerValue);case"StructuredList":{let t=[];for(let o of n.items){let r=Qn(o,e);r!==void 0&&t.push(r)}return`[${t.join(", ")}]`}case"StructuredMap":return;default:return}}function ba(n,e){return e&&ka(e,j.ESC_TOML_MULTILINE)?$a(n):wa(n)}function wa(n){return`"${n.replace(/\\/g,"\\\\").replace(/"/g,'\\"').replace(/\n/g,"\\n")}"`}function $a(n){return`"""
73
72
  ${n.replace(/"""/g,'\\"\\"\\"')}
74
73
  """`}var Ke=class{backendUri="kanonak.org/transformations/json";render(e,t){let o=JSON.stringify(e,null,2);return t?.trailingNewline&&!o.endsWith(`
75
74
  `)?o+`
76
75
  `:o}};function nt(n){let e=n.replace(/\r\n/g,`
77
76
  `).split(`
78
- `),t=[],o=0;for(;o<e.length;){let r=e[o];if(r.trim()===""){o++;continue}let a=/^(\s*)```(\S*)\s*$/.exec(r);if(a){let i=a[2],l=[];for(o++;o<e.length&&!/^(\s*)```\s*$/.test(e[o]);)l.push(e[o]),o++;o++;let u=tt(l.join(`
79
- `)),d=i?` class="language-${ot(i)}"`:"";t.push(`<pre><code${d}>${u}</code></pre>`);continue}let s=/^(#{1,6})\s+(.*)$/.exec(r);if(s){let i=s[1].length,l=te(s[2].trim());t.push(`<h${i}>${l}</h${i}>`),o++;continue}if(r.includes("|")&&o+1<e.length&&et(e[o+1])){let i=Qe(r),l=ua(e[o+1]);o+=2;let u=[];for(;o<e.length&&e[o].trim()!==""&&e[o].includes("|");)u.push(Qe(e[o])),o++;t.push(da(i,l,u));continue}if(/^\s*[-*]\s+/.test(r)){let i=[];for(;o<e.length&&/^\s*[-*]\s+/.test(e[o]);){let l=[e[o].replace(/^\s*[-*]\s+/,"")];for(o++;o<e.length&&e[o].trim()!==""&&!/^\s*[-*]\s+/.test(e[o])&&!/^\s*\d+\.\s+/.test(e[o]);)l.push(e[o]),o++;o<e.length&&e[o].trim()===""&&o++,i.push(`<li>${te(l.join(" ").trim())}</li>`)}t.push(`<ul>
80
- ${i.join(`
77
+ `),t=[],o=0;for(;o<e.length;){let r=e[o];if(r.trim()===""){o++;continue}let a=/^(\s*)```(\S*)\s*$/.exec(r);if(a){let c=a[2],l=[];for(o++;o<e.length&&!/^(\s*)```\s*$/.test(e[o]);)l.push(e[o]),o++;o++;let u=tt(l.join(`
78
+ `)),d=c?` class="language-${ot(c)}"`:"";t.push(`<pre><code${d}>${u}</code></pre>`);continue}let s=/^(#{1,6})\s+(.*)$/.exec(r);if(s){let c=s[1].length,l=oe(s[2].trim());t.push(`<h${c}>${l}</h${c}>`),o++;continue}if(r.includes("|")&&o+1<e.length&&et(e[o+1])){let c=Ye(r),l=Sa(e[o+1]);o+=2;let u=[];for(;o<e.length&&e[o].trim()!==""&&e[o].includes("|");)u.push(Ye(e[o])),o++;t.push(va(c,l,u));continue}if(/^\s*[-*]\s+/.test(r)){let c=[];for(;o<e.length&&/^\s*[-*]\s+/.test(e[o]);){let l=[e[o].replace(/^\s*[-*]\s+/,"")];for(o++;o<e.length&&e[o].trim()!==""&&!/^\s*[-*]\s+/.test(e[o])&&!/^\s*\d+\.\s+/.test(e[o]);)l.push(e[o]),o++;o<e.length&&e[o].trim()===""&&o++,c.push(`<li>${oe(l.join(" ").trim())}</li>`)}t.push(`<ul>
79
+ ${c.join(`
81
80
  `)}
82
- </ul>`);continue}if(/^\s*\d+\.\s+/.test(r)){let i=[];for(;o<e.length&&/^\s*\d+\.\s+/.test(e[o]);){let l=[e[o].replace(/^\s*\d+\.\s+/,"")];for(o++;o<e.length&&e[o].trim()!==""&&!/^\s*\d+\.\s+/.test(e[o])&&!/^\s*[-*]\s+/.test(e[o]);)l.push(e[o]),o++;o<e.length&&e[o].trim()===""&&o++,i.push(`<li>${te(l.join(" ").trim())}</li>`)}t.push(`<ol>
83
- ${i.join(`
81
+ </ul>`);continue}if(/^\s*\d+\.\s+/.test(r)){let c=[];for(;o<e.length&&/^\s*\d+\.\s+/.test(e[o]);){let l=[e[o].replace(/^\s*\d+\.\s+/,"")];for(o++;o<e.length&&e[o].trim()!==""&&!/^\s*\d+\.\s+/.test(e[o])&&!/^\s*[-*]\s+/.test(e[o]);)l.push(e[o]),o++;o<e.length&&e[o].trim()===""&&o++,c.push(`<li>${oe(l.join(" ").trim())}</li>`)}t.push(`<ol>
82
+ ${c.join(`
84
83
  `)}
85
- </ol>`);continue}let c=[r];for(o++;o<e.length&&e[o].trim()!==""&&!/^(#{1,6})\s+/.test(e[o])&&!/^(\s*)```/.test(e[o])&&!/^\s*[-*]\s+/.test(e[o])&&!/^\s*\d+\.\s+/.test(e[o])&&!(e[o].includes("|")&&o+1<e.length&&et(e[o+1]));)c.push(e[o]),o++;t.push(`<p>${te(c.join(" "))}</p>`)}return t.join(`
86
- `)}function et(n){return n.includes("-")?/^[\s|:-]+$/.test(n):!1}function Qe(n){let e=n.trim();return e.startsWith("|")&&(e=e.slice(1)),e.endsWith("|")&&(e=e.slice(0,-1)),e.split("|").map(t=>t.trim())}function ua(n){return Qe(n).map(e=>{let t=e.startsWith(":"),o=e.endsWith(":");return t&&o?"center":o?"right":t?"left":null})}function da(n,e,t){let o=s=>{let c=e[s];return c?` style="text-align:${c}"`:""},r=n.map((s,c)=>`<th${o(c)}>${te(s)}</th>`).join(""),a=t.map(s=>`<tr>${s.map((i,l)=>`<td${o(l)}>${te(i)}</td>`).join("")}</tr>`).join(`
84
+ </ol>`);continue}let i=[r];for(o++;o<e.length&&e[o].trim()!==""&&!/^(#{1,6})\s+/.test(e[o])&&!/^(\s*)```/.test(e[o])&&!/^\s*[-*]\s+/.test(e[o])&&!/^\s*\d+\.\s+/.test(e[o])&&!(e[o].includes("|")&&o+1<e.length&&et(e[o+1]));)i.push(e[o]),o++;t.push(`<p>${oe(i.join(" "))}</p>`)}return t.join(`
85
+ `)}function et(n){return n.includes("-")?/^[\s|:-]+$/.test(n):!1}function Ye(n){let e=n.trim();return e.startsWith("|")&&(e=e.slice(1)),e.endsWith("|")&&(e=e.slice(0,-1)),e.split("|").map(t=>t.trim())}function Sa(n){return Ye(n).map(e=>{let t=e.startsWith(":"),o=e.endsWith(":");return t&&o?"center":o?"right":t?"left":null})}function va(n,e,t){let o=s=>{let i=e[s];return i?` style="text-align:${i}"`:""},r=n.map((s,i)=>`<th${o(i)}>${oe(s)}</th>`).join(""),a=t.map(s=>`<tr>${s.map((c,l)=>`<td${o(l)}>${oe(c)}</td>`).join("")}</tr>`).join(`
87
86
  `);return`<table>
88
87
  <thead><tr>${r}</tr></thead>
89
88
  <tbody>
90
89
  ${a}
91
90
  </tbody>
92
- </table>`}function te(n){let e=tt(n);return e=e.replace(/`([^`\n]+)`/g,(t,o)=>`<code>${o}</code>`),e=e.replace(/\[([^\]]+)\]\(([^)\s]+)\)/g,(t,o,r)=>`<a href="${ot(r)}">${o}</a>`),e=e.replace(/\*\*([^*\n]+)\*\*/g,(t,o)=>`<strong>${o}</strong>`),e=e.replace(/(^|[^*])\*([^*\n]+)\*(?!\*)/g,(t,o,r)=>`${o}<em>${r}</em>`),e=e.replace(/(^|[\s(])_([^_\n]+)_(?=[\s).,;:!?]|$)/g,(t,o,r)=>`${o}<em>${r}</em>`),e}function tt(n){return n.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&#39;")}function ot(n){return n.replace(/"/g,"&quot;").replace(/&/g,"&amp;")}function en(n,e){return n.publisher===e.publisher&&n.package_===e.package_&&n.name===e.name}var Ce=class{backendUri="kanonak.org/transformations/html";render(e,t){let o=ma(e.metadata)??"Untitled",r=pa(e.metadata,t),a=fa(e.children),s=`<!DOCTYPE html>
91
+ </table>`}function oe(n){let e=tt(n);return e=e.replace(/`([^`\n]+)`/g,(t,o)=>`<code>${o}</code>`),e=e.replace(/\[([^\]]+)\]\(([^)\s]+)\)/g,(t,o,r)=>`<a href="${ot(r)}">${o}</a>`),e=e.replace(/\*\*([^*\n]+)\*\*/g,(t,o)=>`<strong>${o}</strong>`),e=e.replace(/(^|[^*])\*([^*\n]+)\*(?!\*)/g,(t,o,r)=>`${o}<em>${r}</em>`),e=e.replace(/(^|[\s(])_([^_\n]+)_(?=[\s).,;:!?]|$)/g,(t,o,r)=>`${o}<em>${r}</em>`),e}function tt(n){return n.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&#39;")}function ot(n){return n.replace(/"/g,"&quot;").replace(/&/g,"&amp;")}function Ze(n,e){return n.publisher===e.publisher&&n.package_===e.package_&&n.name===e.name}var Ae=class{backendUri="kanonak.org/transformations/html";render(e,t){let o=Da(e.metadata)??"Untitled",r=Ka(e.metadata,t),a=Aa(e.children),s=`<!DOCTYPE html>
93
92
  <html lang="en">
94
93
  <head>
95
94
  <meta charset="utf-8">
@@ -119,17 +118,17 @@ ${r}${a}
119
118
  </body>
120
119
  </html>
121
120
  `;return t?.trailingNewline===!1&&s.endsWith(`
122
- `)?s.slice(0,-1):s}};function ma(n){if(n){for(let e of n.entries)if((e.key==="title"||e.key==="name")&&e.value.kind==="StringScalar")return e.value.stringValue}}function pa(n,e){if(!n||n.entries.length===0)return"";let t=e?.metadataKeys??n.entries.map(a=>a.key),o=new Map(n.entries.map(a=>[a.key,a])),r=[];for(let a of t){let s=o.get(a);if(!s)continue;let c=e?.metadataRenames.get(a)??a,i=at(s.value);i!==void 0&&r.push(` <dt>${de(c)}</dt>
123
- <dd>${i}</dd>`)}return r.length===0?"":`<dl class="metadata">
121
+ `)?s.slice(0,-1):s}};function Da(n){if(n){for(let e of n.entries)if((e.key==="title"||e.key==="name")&&e.value.kind==="StringScalar")return e.value.stringValue}}function Ka(n,e){if(!n||n.entries.length===0)return"";let t=e?.metadataKeys??n.entries.map(a=>a.key),o=new Map(n.entries.map(a=>[a.key,a])),r=[];for(let a of t){let s=o.get(a);if(!s)continue;let i=e?.metadataRenames.get(a)??a,c=at(s.value);c!==void 0&&r.push(` <dt>${de(i)}</dt>
122
+ <dd>${c}</dd>`)}return r.length===0?"":`<dl class="metadata">
124
123
  ${r.join(`
125
124
  `)}
126
125
  </dl>
127
- `}function at(n){switch(n.kind){case"StringScalar":return de(n.stringValue);case"IntegerScalar":return String(n.integerValue);case"StructuredList":{let e=[];for(let t of n.items){let o=at(t);o!==void 0&&e.push(`<code>${o}</code>`)}return e.join(", ")}case"StructuredMap":return;default:return}}function fa(n){let e=[];for(let t of n){let o=ga(t);o&&e.push(o)}return e.join(`
128
- `)}function ga(n){switch(n.kind){case"Heading":{let e=Math.max(1,Math.min(6,n.level));return`<h${e}>${rt(n.inlines)}</h${e}>`}case"Paragraph":return`<p>${rt(n.inlines)}</p>`;case"RawBlock":return ha(n);default:return""}}function ha(n){let e=n.mediaType;return e&&en(e,x.TEXT_MARKDOWN)?nt(n.rawContent):e&&en(e,x.TEXT_HTML)?n.rawContent:e&&en(e,x.IMAGE_SVG_XML)?`<figure class="svg-figure">
126
+ `}function at(n){switch(n.kind){case"StringScalar":return de(n.stringValue);case"IntegerScalar":return String(n.integerValue);case"StructuredList":{let e=[];for(let t of n.items){let o=at(t);o!==void 0&&e.push(`<code>${o}</code>`)}return e.join(", ")}case"StructuredMap":return;default:return}}function Aa(n){let e=[];for(let t of n){let o=Ca(t);o&&e.push(o)}return e.join(`
127
+ `)}function Ca(n){switch(n.kind){case"Heading":{let e=Math.max(1,Math.min(6,n.level));return`<h${e}>${rt(n.inlines)}</h${e}>`}case"Paragraph":return`<p>${rt(n.inlines)}</p>`;case"RawBlock":return Pa(n);default:return""}}function Pa(n){let e=n.mediaType;return e&&Ze(e,j.TEXT_MARKDOWN)?nt(n.rawContent):e&&Ze(e,j.TEXT_HTML)?n.rawContent:e&&Ze(e,j.IMAGE_SVG_XML)?`<figure class="svg-figure">
129
128
  ${n.rawContent}
130
- </figure>`:`<pre${e?` class="media-${ka(e.name)}"`:""}><code>${de(n.rawContent)}</code></pre>`}function rt(n){let e=[];for(let t of n)t.kind==="Text"&&e.push(de(t.text));return e.join("")}function de(n){return n.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&#39;")}function ka(n){return n.replace(/"/g,"&quot;").replace(/&/g,"&amp;")}function ya(n,e){return n.publisher===e.publisher&&n.package_===e.package_&&n.name===e.name}var Pe=class{backendUri="kanonak.org/transformations/svg";render(e,t){for(let o of e.children)if(o.kind==="RawBlock"&&o.mediaType&&ya(o.mediaType,x.IMAGE_SVG_XML)){let r=o.rawContent;return t?.trailingNewline&&!r.endsWith(`
129
+ </figure>`:`<pre${e?` class="media-${Ea(e.name)}"`:""}><code>${de(n.rawContent)}</code></pre>`}function rt(n){let e=[];for(let t of n)t.kind==="Text"&&e.push(de(t.text));return e.join("")}function de(n){return n.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&#39;")}function Ea(n){return n.replace(/"/g,"&quot;").replace(/&/g,"&amp;")}function _a(n,e){return n.publisher===e.publisher&&n.package_===e.package_&&n.name===e.name}var Ce=class{backendUri="kanonak.org/transformations/svg";render(e,t){for(let o of e.children)if(o.kind==="RawBlock"&&o.mediaType&&_a(o.mediaType,j.IMAGE_SVG_XML)){let r=o.rawContent;return t?.trailingNewline&&!r.endsWith(`
131
130
  `)&&(r+=`
132
- `),r}return'<svg xmlns="http://www.w3.org/2000/svg" width="1" height="1"/>'}};var Ee={"markdown-with-frontmatter":{formatUri:"kanonak.org/transformations/markdown-with-frontmatter",extension:".md"},toml:{formatUri:"kanonak.org/transformations/toml",extension:".toml"},json:{formatUri:"kanonak.org/transformations/json",extension:".json"},"plain-markdown":{formatUri:"kanonak.org/transformations/plain-markdown",extension:".md"},html:{formatUri:"kanonak.org/transformations/html",extension:".html"},svg:{formatUri:"kanonak.org/transformations/svg",extension:".svg"}},oe=class extends Error{},V=class{backends=new Map;constructor(){this.register(new De),this.register(new Ae),this.register(new Ke),this.register(new Ce),this.register(new Pe)}register(e){this.backends.set(e.backendUri,e)}async run(e){let t=e.transformationKanonaks??e.allKanonaks,o=ne(e.transformation,t);if(!o.outputs.has(e.outputFormat))throw new oe(`Transformation "${o.name}" does not support output format "${e.outputFormat}". Declared outputs: ${Array.from(o.outputs).join(", ")}`);let r=new be(e.repository,e.parser,e.objectParser),a=new Se(r,e.allKanonaks),s=e.instances.filter(u=>ba(u,o)),c=this.findBackendForFormat(e.outputFormat);if(!c)throw new oe(`No backend registered for OutputFormat "${e.outputFormat}".`);let i=o.overrides.get(e.outputFormat),l=[];for(let u of s){let d=new Map;d.set("input",u);let p=await a.evaluate(o.rule,d);if(!$a(p))throw new oe(`Transformation "${o.name}" rule did not yield a Document for input "${u.name}". Got: ${st(p)}`);let y=await a.evaluate(o.artifactName,d);if(typeof y!="string")throw new oe(`Transformation "${o.name}" artifactName did not yield a string for input "${u.name}". Got: ${st(y)}`);let b=c.render(p,i);l.push({fileName:y,format:e.outputFormat,content:b,sourceName:u.name})}return l}findBackendForFormat(e){let t=Ee[e];if(t)return this.backends.get(t.formatUri)}};function ba(n,e){for(let t of e.inputPattern.requires)if(!wa(n,t))return!1;return!0}function wa(n,e){for(let t of n.statement){let o=t.predicate?.subject;if(o&&M(o,e)){let r=t.object;if(r==null||typeof r=="string"&&r.length===0||Array.isArray(r)&&r.length===0)continue;return!0}}return!1}function $a(n){return typeof n=="object"&&n!==null&&n.kind==="Document"&&Array.isArray(n.children)}function st(n){if(n===void 0)return"undefined";if(n===null)return"null";if(Array.isArray(n))return`array(${n.length})`;if(typeof n=="object"){let e=n.kind;return e?`object(kind=${e})`:"object"}return typeof n}function lt(){let n=new pe("transform").description("Run ontology-driven transformations against Kanonak packages. Transformations are declarative YAML rules (instances of `kanonak.org/transformations/Transformation`) that convert ontology instances into output files. The runner produces one or more Artifacts per matched input; format backends serialize them to Markdown, HTML, SVG, TOML, JSON, or (with post-processing) PDF.").addHelpText("after",`
131
+ `),r}return'<svg xmlns="http://www.w3.org/2000/svg" width="1" height="1"/>'}};var Pe={"markdown-with-frontmatter":{formatUri:"kanonak.org/transformations/markdown-with-frontmatter",extension:".md"},toml:{formatUri:"kanonak.org/transformations/toml",extension:".toml"},json:{formatUri:"kanonak.org/transformations/json",extension:".json"},"plain-markdown":{formatUri:"kanonak.org/transformations/plain-markdown",extension:".md"},html:{formatUri:"kanonak.org/transformations/html",extension:".html"},svg:{formatUri:"kanonak.org/transformations/svg",extension:".svg"}},re=class extends Error{},B=class{backends=new Map;constructor(){this.register(new ve),this.register(new De),this.register(new Ke),this.register(new Ae),this.register(new Ce)}register(e){this.backends.set(e.backendUri,e)}async run(e){let t=e.transformationKanonaks??e.allKanonaks,o=te(e.transformation,t);if(!o.outputs.has(e.outputFormat))throw new re(`Transformation "${o.name}" does not support output format "${e.outputFormat}". Declared outputs: ${Array.from(o.outputs).join(", ")}`);let r=new ye(e.repository,e.parser,e.objectParser),a=new $e(r,e.allKanonaks),s=e.instances.filter(u=>Ia(u,o)),i=this.findBackendForFormat(e.outputFormat);if(!i)throw new re(`No backend registered for OutputFormat "${e.outputFormat}".`);let c=o.overrides.get(e.outputFormat),l=[];for(let u of s){let d=new Map;d.set("input",u);let m=await a.evaluate(o.rule,d);if(!Ta(m))throw new re(`Transformation "${o.name}" rule did not yield a Document for input "${u.name}". Got: ${st(m)}`);let g=await a.evaluate(o.artifactName,d);if(typeof g!="string")throw new re(`Transformation "${o.name}" artifactName did not yield a string for input "${u.name}". Got: ${st(g)}`);let h=i.render(m,c);l.push({fileName:g,format:e.outputFormat,content:h,sourceName:u.name})}return l}findBackendForFormat(e){let t=Pe[e];if(t)return this.backends.get(t.formatUri)}};function Ia(n,e){for(let t of e.inputPattern.requires)if(!Ra(n,t))return!1;return!0}function Ra(n,e){for(let t of n.statement){let o=t.predicate?.subject;if(o&&F(o,e)){let r=t.object;if(r==null||typeof r=="string"&&r.length===0||Array.isArray(r)&&r.length===0)continue;return!0}}return!1}function Ta(n){return typeof n=="object"&&n!==null&&n.kind==="Document"&&Array.isArray(n.children)}function st(n){if(n===void 0)return"undefined";if(n===null)return"null";if(Array.isArray(n))return`array(${n.length})`;if(typeof n=="object"){let e=n.kind;return e?`object(kind=${e})`:"object"}return typeof n}function dt(){let n=new me("transform").description("Run ontology-driven transformations against Kanonak packages. Transformations are declarative YAML rules (instances of `kanonak.org/transformations/Transformation`) that convert ontology instances into output files. The runner produces one or more Artifacts per matched input; format backends serialize them to Markdown, HTML, SVG, TOML, JSON, or (with post-processing) PDF.").addHelpText("after",`
133
132
  Examples:
134
133
 
135
134
  # List every Transformation available in the local workspace
@@ -158,14 +157,14 @@ Examples:
158
157
 
159
158
  # List the registered format backends
160
159
  $ kanonak transform formats
161
- `);return n.addCommand(Ia()),n.addCommand(ja()),n.addCommand(Ua()),n.addCommand(Oa()),n}function Ia(){return new pe("run").description("Run a transformation against an input scope and write the resulting Artifacts to disk.").argument("<transformation>","Transformation URI (`publisher/package/name`, optional `@version`) or just the local name if unique in the workspace.").requiredOption("--scope <scope>","Input source \u2014 either a package URI `publisher/package[@version]` (resolved via the local workspace + cache + HTTP tiers) or a file path to a `.kan.yml` document.").option("--format <name>","OutputFormat name to target (e.g. `markdown-with-frontmatter`, `html`, `svg`, `json`). If omitted and the transformation declares exactly one output, that single format is used.").option("--out <dir>","Directory to write artifacts into.",".").action(async(n,e)=>{try{await Ra(n,e)}catch(t){console.error(`Error: ${t.message}`),process.exit(1)}})}async function Ra(n,e){let t=new nn,o=new tn,r=await j(process.cwd(),t),a=await ut(n,r,o),{transformation:s,transformationKanonaks:c}=a;console.log(`Transformation: ${me(s)}`);let i=ne(s,c),l=await La(e.scope,r,t,o),u=await Va(l,i.inputPattern.matchesClass,r);console.log(`Scope: ${e.scope} \u2014 found ${u.length} instance(s) of ${i.inputPattern.matchesClass.publisher}/${i.inputPattern.matchesClass.package_}/${i.inputPattern.matchesClass.name}`),u.length===0&&(console.error("No matching input instances in scope. Check the transformation's inputPattern.matchesClass vs. the scope package."),process.exit(1));let d=Ta(i.outputs,e.format);console.log(`Output format: ${d}`);let p=Ee[d];if(!p)throw new Error(`Unknown format "${d}". Run \`kanonak transform formats\` to see what the runner supports.`);let b=await new V().run({transformation:s,instances:u,allKanonaks:l,transformationKanonaks:c,repository:r,parser:t,objectParser:o,outputFormat:d}),f=Ca(e.out);Da(f,{recursive:!0});for(let k of b){let h=Ba(k.fileName),$=Ka(f,`${h}${p.extension}`);va($,k.content,"utf-8"),console.log(` wrote ${$}`)}console.log(`Done. ${b.length} artifact(s) written to ${f}`)}function Ta(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 ja(){return new pe("list").description("Scan the local workspace + cache for every Transformation instance and print a one-line summary per hit.").action(async()=>{try{await xa()}catch(n){console.error(`Error: ${n.message}`),process.exit(1)}})}async function xa(){let n=new nn,e=new tn,t=await j(process.cwd(),n),o=await t.getAllDocumentsAsync(),r=[];for(let a of o)try{let s=new K(a,t),c=await e.parseKanonaks(s),i=C(c,g.Transformation);for(let l of i)r.push(Ma(l,c))}catch{}if(r.length===0){console.log("No Transformation instances found in the current workspace.");return}r.sort((a,s)=>a.uri.localeCompare(s.uri));for(let a of r)console.log(`${a.uri}`),console.log(` matches: ${a.matchesClass}`),console.log(` outputs: ${a.outputs.join(", ")}`)}function Ua(){return new pe("show").description("Compile a transformation and print a human-readable summary (input pattern, outputs, format overrides, rule shape).").argument("<transformation>","Transformation URI or local name").action(async n=>{try{await Na(n)}catch(e){console.error(`Error: ${e.message}`),process.exit(1)}})}async function Na(n){let e=new nn,t=new tn,o=await j(process.cwd(),e),{transformation:r,transformationKanonaks:a}=await ut(n,o,t),s=ne(r,a);if(console.log(`Transformation: ${me(r)}`),console.log(),console.log("Input pattern:"),console.log(` Matches class: ${_e(s.inputPattern.matchesClass)}`),s.inputPattern.requires.length>0){console.log(" Required properties:");for(let c of s.inputPattern.requires)console.log(` - ${_e(c)}`)}else console.log(" Required properties: (none)");if(console.log(),console.log(`Outputs: ${Array.from(s.outputs).sort().join(", ")}`),console.log(),s.overrides.size>0){console.log("Format overrides:");for(let[c,i]of s.overrides){if(console.log(` ${c}:`),i.metadataKeys&&console.log(` metadata keys: ${i.metadataKeys.join(", ")}`),i.metadataRenames.size>0){let l=[];for(let[u,d]of i.metadataRenames)l.push(`${u} \u2192 ${d}`);console.log(` metadata renames: ${l.join(", ")}`)}i.trailingNewline!==void 0&&console.log(` trailing newline: ${i.trailingNewline}`)}console.log()}console.log(`Rule root kind: ${s.rule.kind}`),s.rule.kind==="build-ast-node"&&(console.log(`Rule root AST class: ${_e(s.rule.astClass)}`),console.log(`Rule root bindings: ${s.rule.set.length} field(s)`)),console.log(`Artifact name root kind: ${s.artifactName.kind}`)}function Oa(){return new pe("formats").description("List the OutputFormat names the runner can serialize to.").action(()=>{console.log("Registered format backends:");let n=Object.entries(Ee).sort(([e],[t])=>e.localeCompare(t));for(let[e,t]of n)console.log(` ${e.padEnd(28)} ${t.extension.padEnd(6)} ${t.formatUri}`)})}async function ut(n,e,t){let o,r,a;if(n.includes("/")){let i=n.indexOf("@"),l=n;if(i!==-1){let d=n.indexOf("/",i);if(d===-1)throw new Error(`Transformation URI "${n}" has @version but no trailing /<name>`);l=n.substring(0,i)+n.substring(d)}let u=l.split("/");if(u.length<3)throw new Error(`Invalid transformation URI "${n}" \u2014 expected publisher/package/name or publisher/package@version/name`);o=u[0],r=u[1],a=u.slice(2).join("/")}else a=n;if(o&&r){let i=await e.getDocumentsByNamespaceAsync(o,r);if(i.length===0)throw new Error(`Package ${o}/${r} not found in the local workspace or cache.`);let l=Fa(n),u=dt(i,l,`${o}/${r}`),d=new K(u,e),p=await t.parseKanonaks(d),y=ke(p,{publisher:o,package_:r,name:a,version:""});if(!y){let b=C(p,g.Transformation),f=b.find(k=>k.name===a);if(!f)throw new Error(`Transformation "${a}" not found in package ${o}/${r}. Package contains ${b.length} Transformation(s): ${b.map(k=>k.name).join(", ")||"(none)"}`);return{transformation:f,transformationKanonaks:p}}return{transformation:y,transformationKanonaks:p}}let s=await e.getAllDocumentsAsync(),c=[];for(let i of s)try{let l=new K(i,e),u=await t.parseKanonaks(l),d=C(u,g.Transformation);for(let p of d)p.name===a&&c.push({tx:p,kanonaks:u})}catch{}if(c.length===0)throw new Error(`No Transformation named "${a}" found in the workspace. Try \`kanonak transform list\` to see available transformations.`);if(c.length>1){let i=c.map(l=>me(l.tx)).join(`
160
+ `);return n.addCommand(Va()),n.addCommand(qa()),n.addCommand(Wa()),n.addCommand(Ja()),n}function Va(){return new me("run").description("Run a transformation against an input scope and write the resulting Artifacts to disk.").argument("<transformation>","Transformation URI (`publisher/package/name`, optional `@version`) or just the local name if unique in the workspace.").requiredOption("--scope <scope>","Input source \u2014 either a package URI `publisher/package[@version]` (resolved via the local workspace + cache + HTTP tiers) or a file path to a `.kan.yml` document.").option("--format <name>","OutputFormat name to target (e.g. `markdown-with-frontmatter`, `html`, `svg`, `json`). If omitted and the transformation declares exactly one output, that single format is used.").option("--out <dir>","Directory to write artifacts into.",".").action(async(n,e)=>{try{await Ha(n,e)}catch(t){console.error(`Error: ${t.message}`),process.exit(1)}})}async function Ha(n,e){let t=new Qe,o=new en,r=await x(process.cwd(),t),a=await mt(n,r,o),{transformation:s,transformationKanonaks:i}=a;console.log(`Transformation: ${_e(s)}`);let c=te(s,i),l=await Ya(e.scope,r,t,o),u=await es(l,c.inputPattern.matchesClass,r);console.log(`Scope: ${e.scope} \u2014 found ${u.length} instance(s) of ${c.inputPattern.matchesClass.publisher}/${c.inputPattern.matchesClass.package_}/${c.inputPattern.matchesClass.name}`),u.length===0&&(console.error("No matching input instances in scope. Check the transformation's inputPattern.matchesClass vs. the scope package."),process.exit(1));let d=za(c.outputs,e.format);console.log(`Output format: ${d}`);let m=Pe[d];if(!m)throw new Error(`Unknown format "${d}". Run \`kanonak transform formats\` to see what the runner supports.`);let h=await new B().run({transformation:s,instances:u,allKanonaks:l,transformationKanonaks:i,repository:r,parser:t,objectParser:o,outputFormat:d}),f=La(e.out);Ua(f,{recursive:!0});for(let k of h){let y=Qa(k.fileName),w=Oa(f,`${y}${m.extension}`);ja(w,k.content,"utf-8"),console.log(` wrote ${w}`)}console.log(`Done. ${h.length} artifact(s) written to ${f}`)}function za(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 qa(){return new me("list").description("Scan the local workspace + cache for every Transformation instance and print a one-line summary per hit.").action(async()=>{try{await Ga()}catch(n){console.error(`Error: ${n.message}`),process.exit(1)}})}async function Ga(){let n=new Qe,e=new en,t=await x(process.cwd(),n),o=await t.getAllDocumentsAsync(),r=new Map;for(let s of o)try{let i=new A(s,t),c=await e.parseKanonaks(i),l=P(c,b.Transformation);for(let u of l){let d=tn(u);if(!d)continue;let m=r.get(d)??[];m.push({tx:u,kanonaks:c,doc:s}),r.set(d,m)}}catch{}let a=[];for(let s of r.values()){if(s.length===1){a.push(ct(s[0].tx,s[0].kanonaks));continue}let i=nn(s.map(l=>l.doc));if(!i.chosen)continue;let c=s.find(l=>l.doc===i.chosen);c&&a.push(ct(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 Wa(){return new me("show").description("Compile a transformation and print a human-readable summary (input pattern, outputs, format overrides, rule shape).").argument("<transformation>","Transformation URI or local name").action(async n=>{try{await Xa(n)}catch(e){console.error(`Error: ${e.message}`),process.exit(1)}})}async function Xa(n){let e=new Qe,t=new en,o=await x(process.cwd(),e),{transformation:r,transformationKanonaks:a}=await mt(n,o,t),s=te(r,a);if(console.log(`Transformation: ${_e(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,d]of c.metadataRenames)l.push(`${u} \u2192 ${d}`);console.log(` metadata renames: ${l.join(", ")}`)}c.trailingNewline!==void 0&&console.log(` trailing newline: ${c.trailingNewline}`)}console.log()}console.log(`Rule root kind: ${s.rule.kind}`),s.rule.kind==="build-ast-node"&&(console.log(`Rule root AST class: ${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 Ja(){return new me("formats").description("List the OutputFormat names the runner can serialize to.").action(()=>{console.log("Registered format backends:");let n=Object.entries(Pe).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 mt(n,e,t){let o,r,a;if(n.includes("/")){let m=n.indexOf("@"),g=n;if(m!==-1){let f=n.indexOf("/",m);if(f===-1)throw new Error(`Transformation URI "${n}" has @version but no trailing /<name>`);g=n.substring(0,m)+n.substring(f)}let h=g.split("/");if(h.length<3)throw new Error(`Invalid transformation URI "${n}" \u2014 expected publisher/package/name or publisher/package@version/name`);o=h[0],r=h[1],a=h.slice(2).join("/")}else a=n;if(o&&r){let m=await e.getDocumentsByNamespaceAsync(o,r);if(m.length===0)throw new Error(`Package ${o}/${r} not found in the local workspace or cache.`);let g=Za(n),h=pt(m,g,`${o}/${r}`),f=new A(h,e),k=await t.parseKanonaks(f),y=he(k,{publisher:o,package_:r,name:a,version:""});if(!y){let w=P(k,b.Transformation),$=w.find(v=>v.name===a);if(!$)throw new Error(`Transformation "${a}" not found in package ${o}/${r}. Package contains ${w.length} Transformation(s): ${w.map(v=>v.name).join(", ")||"(none)"}`);return{transformation:$,transformationKanonaks:k}}return{transformation:y,transformationKanonaks:k}}let s=await e.getAllDocumentsAsync(),i=new Map;for(let m of s)try{let g=new A(m,e),h=await t.parseKanonaks(g),f=P(h,b.Transformation);for(let k of f){if(k.name!==a)continue;let y=tn(k);if(!y)continue;let w=i.get(y)??[];w.push({tx:k,kanonaks:h,doc:m}),i.set(y,w)}}catch{}if(i.size===0)throw new Error(`No Transformation named "${a}" found in the workspace. Try \`kanonak transform list\` to see available transformations.`);if(i.size>1){let m=Array.from(i.keys()).sort().join(`
162
161
  `);throw new Error(`Multiple Transformations named "${a}" in the workspace \u2014 disambiguate with a full publisher/package/name URI:
163
- ${i}`)}return{transformation:c[0].tx,transformationKanonaks:c[0].kanonaks}}async function La(n,e,t,o){if(/^[.\/\\]/.test(n)||/^[A-Za-z]:/.test(n)||n.endsWith(".kan.yml")||it(n)&&Aa(n).isFile()){if(!it(n))throw new Error(`Scope file not found: ${n}`);let b=Sa(n,"utf-8"),f=t.parse(b),k=new K(f,e);return o.parseKanonaks(k)}let a=n.indexOf("@"),s=a===-1?n:n.substring(0,a),c=a===-1?void 0:n.substring(a+1),i=s.indexOf("/");if(i===-1)throw new Error(`Invalid scope "${n}" \u2014 expected a file path or publisher/package[@version] URI`);let l=s.substring(0,i),u=s.substring(i+1),d=await e.getDocumentsByNamespaceAsync(l,u);if(d.length===0)throw new Error(`Scope package ${l}/${u} not found in the local workspace or cache.`);let p=dt(d,c,`${l}/${u}`),y=new K(p,e);return o.parseKanonaks(y)}function Fa(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 dt(n,e,t){function o(s){let c=s.metadata.namespace_?.version;return c?`${c.major}.${c.minor}.${c.patch}`:""}if(e){let s=n.find(i=>o(i)===e);if(s)return s;let c=n.map(o).filter(Boolean).sort().join(", ");throw new Error(`${t}@${e} not found in the local workspace or cache. Available versions: ${c||"(none with parseable namespace)"}`)}if(n.length===1)return n[0];let a=[...n].sort((s,c)=>{let i=s.metadata.namespace_?.version,l=c.metadata.namespace_?.version;return!i||!l?0:i.major!==l.major?l.major-i.major:i.minor!==l.minor?l.minor-i.minor:l.patch-i.patch})[0];return console.warn(`Warning: ${t} has ${n.length} versions present (${n.map(o).filter(Boolean).join(", ")}); using @${o(a)}. Pin with ${t}@<version> to suppress this warning.`),a}function Ma(n,e){try{let t=ne(n,e);return{uri:me(n),matchesClass:_e(t.inputPattern.matchesClass),outputs:Array.from(t.outputs).sort()}}catch(t){return{uri:me(n),matchesClass:`(compile error: ${t.message})`,outputs:[]}}}function me(n){let e=n.namespace||"",t=e.indexOf("@");return`${t===-1?e:e.substring(0,t)}/${n.name}`}function _e(n){return`${n.publisher}/${n.package_}/${n.name}`}function Ba(n){return n.replace(/[\\/:*?"<>|\s]+/g,"_").replace(/^_+|_+$/g,"")}async function Va(n,e,t){let o=new Map;for(let s of n){if(!(s instanceof Pa))continue;let c=Ha(s);c&&o.set(c,s)}let r=[];try{r=(await new Ea({vocabulary:new _a}).reason(t)).getInstancesOfClass(ct(e.publisher,e.package_,e.name))}catch{}let a=[];for(let s of r){let c=o.get(s);c&&a.push(c)}return a.length>0?a:C(n,e)}function Ha(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:ct(o.substring(0,r),o.substring(r+1),n.name)}import{Command as za}from"commander";import{KanonakParser as qa,PublisherIndex as mt,CredentialStore as pt,createAuthenticatedFetch as ft,FileSystemKanonakDocumentRepository as Ga,Reasoner as Wa,KanonakVocabulary as Xa,getGlobalCachePath as Ja,makeUriKey as Ya}from"@kanonak-protocol/sdk";function Za(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 gt(){return new za("search").description("Browse a publisher's catalogue or find instances of a class via the SDK reasoner").argument("<publisher>","Publisher domain (e.g. kanonak.org)").option("--type <uri>","Class URI to search for, in publisher/package/Name form").action(async(n,e)=>{e.type?await es(n,e.type):await Qa(n)})}async function Qa(n){let e=new pt,t=ft(e),o=new mt({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}:
164
- `);let a=r.reduce((s,c)=>Math.max(s,c.packageName.length),0);for(let{packageName:s,version:c}of r)console.log(` ${s.padEnd(a)} @${c}`)}async function es(n,e){let t=Za(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 qa,r=new pt,a=ft(r),s=new mt({fetchFn:a}),c=new T,i=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)i.add(`${n}|${k}|${h}`);await on(s,c,a,"kanonak.org","core-rdf",i),await on(s,c,a,"kanonak.org","core-owl",i),await on(s,c,a,t.publisher,t.package_,i);for(let k of i){let[h,$,w]=k.split("|");if(!c.has(h,$,w))try{let v=await s.getPackageUrl(h,$,w),D=await a(v,h);if(!D.ok){console.error(`Warning: failed to fetch ${h}/${$}@${w}: ${D.status} ${D.statusText}`);continue}let G=await D.text();c.put(h,$,w,G)}catch(v){console.error(`Warning: failed to fetch ${h}/${$}@${w}: ${v.message}`)}}let u=new Ga(Ja(),!0,o),p=await new Wa({vocabulary:new Xa}).reason(u),y=Ya(t.publisher,t.package_,t.name),f=p.getInstancesOfClass(y).filter(k=>k!==y);if(f.length===0){console.log(`No instances of ${y} found in ${n}'s catalogue.`);return}console.log(`Instances of ${y} in ${n}'s catalogue:
165
- `),f.sort();for(let k of f)console.log(` ${k}`)}async function on(n,e,t,o,r,a){try{let s=await n.getHighestVersion(o,r);if(!s)return;a.add(`${o}|${r}|${s}`)}catch{}}import{Command as ht}from"commander";function re(n){return`${E}/${_}/${n}`}var rn={[re("fetch-and-deploy")]:(n,e,t,o)=>n.add(e,t[0],o),[re("remove-deployed")]:(n,e,t,o)=>n.remove(e,t[0],o),[re("list-deployed")]:(n,e,t,o)=>n.list(e,o),[re("update-deployed")]:(n,e,t,o)=>n.update(e,t[0],o),[re("search-available")]:(n,e,t,o)=>n.search(e,o),[re("show-info")]:(n,e,t,o)=>n.info(e,t[0],o)};function kt(n,e,t){for(let o of e){let r=new ht(o.commandName).description(o.description.trim());for(let a of o.commands){let s=r.command(ns(a));s.description(a.description);for(let c of a.arguments)if(c.isOption){let i=c.defaultValue!=null?`--${c.argumentName} [value]`:`--${c.argumentName} <value>`;s.option(i,"",c.defaultValue)}s.action(async(...c)=>{let i=ts(c);await os(t,o,a,c,i)})}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 ts(n){for(let e=n.length-1;e>=0;e--)if(n[e]&&typeof n[e]=="object"&&!(n[e]instanceof ht))return n[e];return{}}async function os(n,e,t,o,r){let a=[];for(let c of o)if(typeof c=="string")a.push(c);else break;t.actionKey||(console.error(`Capability subcommand '${t.subcommandName}' has no resolved \`performs:\` Action. Every CapabilityCommand must declare a performs value pointing at a named Action instance from the capabilities ontology. Known actions: ${Object.keys(rn).join(", ")}.`),process.exit(1));let s=rn[t.actionKey];s||(console.error(`Capability subcommand '${t.subcommandName}' references unknown Action '${t.actionKey}'. Known actions: ${Object.keys(rn).join(", ")}.`),process.exit(1)),await s(n,e,a,r)}import{KanonakObjectParser as rs,PublisherIndex as an,PublisherConfigResolver as as}from"@kanonak-protocol/sdk";var Ie=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 rs;async add(e,t,o){let r=W(t);r||(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(""),console.error("Tip: copy a URI directly from `kanonak "+e.commandName+" search`."),process.exit(1));let{publisher:a,packageName:s,version:c,instanceName:i}=r,l=c??await this.publisherIndex.getHighestVersion(a,s);l||(console.error(`Could not resolve version for "${a}/${s}".`),await this.printPackageSuggestions(a,s,e.commandName),process.exit(1));let u=this.fileCache.get(a,s,l);if(!u){let w=await this.publisherIndex.getPackageUrl(a,s,l),v=await this.fetchFn(w,a);v.ok||(v.status===404?(console.error(`Package ${a}/${s}@${l} not found at ${w}.`),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 ${w} (${v.status} ${v.statusText}).`),process.exit(1)),u=await v.text(),this.fileCache.put(a,s,l,u)}let d=this.parser.parse(u),p=new K(d,this.repository),y=await this.objectParser.parseKanonaks(p),b=yt(e.managesTypeKey);b||(console.error(`Capability "${e.commandName}" has no resolved managesType.`),process.exit(1));let f=C(y,b);f.length===0&&(console.error(`Package ${a}/${s}@${l} does not contain any ${N(b)} instances.`),process.exit(1));let k=f;if(i&&(k=f.filter(w=>w.name===i),k.length===0)){console.error(`Instance "${i}" not found in ${a}/${s}@${l}.`),console.error(""),console.error(`This package contains ${f.length} ${N(b)} instance(s):`);for(let w of f)console.error(` - ${w.name}`);console.error(""),console.error("To install all of them, drop the instance suffix:"),console.error(` kanonak ${e.commandName} add ${a}/${s}`),process.exit(1)}let h=i?`${i} from ${a}/${s}@${l}`:`${k.length} ${N(b)} instance(s) from ${a}/${s}@${l}`;console.log(`Installing ${h}...`);let $=this.handlerRegistry.get(e.deploymentTargetKey);$?await $.deploy({instances:k,allKanonaks:y,repository:this.repository,options:o}):console.log(`Cached ${a}/${s}@${l} (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:ss(t,s.packageName)})).filter(s=>s.score>0).sort((s,c)=>c.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:
166
- `);for(let s of r){let c=s.publisher?`${s.publisher}/${s.package_}@${s.version}`:"unmanaged";console.log(` ${s.name} (${c}) ${s.path}`)}}async update(e,t,o){let a=await this.requireHandler(e).list({repository:this.repository,options:o}),s=t?a.filter(i=>i.name===t):a.filter(i=>i.publisher);if(s.length===0){console.log(t?`"${t}" not found.`:"No managed instances to update.");return}let c=0;for(let i of s){let l=await this.publisherIndex.getHighestVersion(i.publisher,i.package_);!l||l===i.version||(console.log(`Updating ${i.name}: ${i.version} \u2192 ${l}`),await this.add(e,`${i.publisher}/${i.package_}@${l}`,o),c++)}console.log(c===0?"All instances are up to date.":`
167
- Updated ${c} 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 ${N(r)} instances...
168
- `);let a=new as,s=await a.getConfig(o),c=a.resolveIndexUrl(o,s),i=await this.fetchFn(c,o);if(!i.ok){console.error(`Failed to fetch package index from ${o}.`);return}let l=await i.text(),u=an.parseIndex(l);if(u.size===0){console.error(`No packages found for publisher "${o}".`);return}let d=new Map;for(let[f,k]of u){let h=[...k].sort(($,w)=>{let v=an.parseVersion($),D=an.parseVersion(w);return!v||!D?0:v.major!==D.major?D.major-v.major:v.minor!==D.minor?D.minor-v.minor:D.patch-v.patch});d.set(f,h[0])}let p=[],y=0;for(let[f,k]of d){let h=this.fileCache.get(o,f,k);if(!h)try{let $=await this.publisherIndex.getPackageUrl(o,f,k),w=await this.fetchFn($,o);if(!w.ok)continue;h=await w.text(),this.fileCache.put(o,f,k,h)}catch{continue}try{let $=this.parser.parse(h),w=new K($,this.repository),v=await this.objectParser.parseKanonaks(w),D=C(v,r);for(let G of D)p.push({publisher:o,package_:f,version:k,subject:G});y++}catch{continue}}if(p.length===0){console.log(`No ${N(r)} instances found across ${y} package(s).`);return}console.log(`Found ${p.length} ${N(r)} instance(s) in ${y} package(s):
169
- `);let b=new Map;for(let f of p){let k=`${f.publisher}/${f.package_}@${f.version}`,h=b.get(k);h?h.push(f):b.set(k,[f])}for(let[f,k]of b){let h=k[0],$=`${h.publisher}/${h.package_}`,w=k.length===1;console.log(` ${f}`),console.log(` ${k.length} skill${w?"":"s"}:`);for(let v of k)console.log(` - ${v.subject.name}`);if(console.log(""),w)console.log(" install:"),console.log(` kanonak ${e.commandName} add ${$}/${h.subject.name}`);else{console.log(" install one of them:");for(let v of k)console.log(` kanonak ${e.commandName} add ${$}/${v.subject.name}`);console.log(" install all of them:"),console.log(` kanonak ${e.commandName} add ${$}`)}console.log("")}}async info(e,t,o){let s=(await this.requireHandler(e).list({repository:this.repository,options:o})).find(c=>c.name===t);s||(console.error(`"${t}" is not installed.`),process.exit(1)),console.log(`Name: ${s.name}`),console.log(`Type: ${e.managesTypeKey||"n/a"}`),console.log(`Publisher: ${s.publisher||"unmanaged"}`),console.log(`Package: ${s.package_||"n/a"}`),console.log(`Version: ${s.version||"n/a"}`),console.log(`Path: ${s.path}`)}requireHandler(e){let t=this.handlerRegistry.get(e.deploymentTargetKey);return t||(console.error(`No deployment handler registered for "${e.deploymentTargetKey}". Ensure the capability's deploymentTarget resolves to a DeploymentTarget instance whose URI is registered in the CLI at startup.`),process.exit(1)),t}};function yt(n){if(!n)return;let e=n.split("/");if(e.length===3)return{publisher:e[0],package_:e[1],name:e[2]}}function ss(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 i of r)a.has(i)&&s++;if(s>0)return s*10;let c=is(t,o);return c===0?100:c<=2?Math.max(1,20-c*5):0}function is(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 Re=class{handlers=new Map;register(e,t){this.handlers.set(e,t)}get(e){return this.handlers.get(e)??null}};import{mkdirSync as ws,rmSync as $s,existsSync as xe,readdirSync as Ss,writeFileSync as vs}from"fs";import{join as Ue}from"path";import{KanonakObjectParser as Ds,KanonakParser as As}from"@kanonak-protocol/sdk";import{join as sn}from"path";import{homedir as bt}from"os";import{KanonakObjectParser as cs}from"@kanonak-protocol/sdk";var ae="kanonak.org",se="agent-skills",$t={publisher:ae,package_:se,name:"Client"},St={publisher:ae,package_:se,name:"clientId"},ls={publisher:ae,package_:se,name:"projectSkillDir"},us={publisher:ae,package_:se,name:"userSkillDir"},ds="agents";async function fe(n,e){let t=(n.client??ms()??ds).toLowerCase(),o=n.scope??"project",r=await ps(t,e);if(!r){let c=await fs(e);throw new Error(`Unknown client "${t}". Known clients: ${c.join(", ")||"(none)"}. Add a Client instance to a package that imports kanonak.org/agent-skills and install that package to make it available.`)}let s=P(r,o==="user"?us:ls);if(!s)throw new Error(`Client "${t}" has no ${o==="user"?"userSkillDir":"projectSkillDir"} declared.`);return gs(s)}async function Te(n,e,t){let o=await fe(e,t);return sn(o,n)}function ms(){if(process.env.CLAUDE_CODE||process.env.CLAUDE_PROJECT_DIR)return"claude-code"}var wt=new WeakMap;async function vt(n){let e=wt.get(n);if(e)return e;let t=await n.getDocumentsByNamespaceAsync(ae,se);if(t.length===0)throw new Error(`Could not find ${ae}/${se} 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((i,l)=>{let u=i.metadata.namespace_?.version,d=l.metadata.namespace_?.version;return!u||!d?0:u.major!==d.major?d.major-u.major:u.minor!==d.minor?d.minor-u.minor:d.patch-u.patch})[0],a=new cs,s=new K(r,n),c=await a.parseKanonaks(s);return wt.set(n,c),c}async function ps(n,e){let t=await vt(e),o=C(t,$t);for(let r of o)if(P(r,St)===n)return r}async function fs(n){let e=await vt(n),t=C(e,$t),o=[];for(let r of t){let a=P(r,St);a&&o.push(a)}return o}function gs(n){return n.startsWith("~/")?sn(bt(),n.slice(2)):n==="~"?bt():n.startsWith("/")||/^[A-Za-z]:[\\/]/.test(n)?n:sn(process.cwd(),n)}import{readFileSync as hs,writeFileSync as ks,existsSync as ys}from"fs";import{join as Dt}from"path";import At from"js-yaml";var Kt="skills.lock",bs=`# This file is generated by Kanonak CLI. Do not edit manually.
170
- `;function je(n){let e=Dt(n,Kt);if(!ys(e))return{version:"1",lastUpdated:new Date().toISOString(),skills:{}};let t=hs(e,"utf-8"),o=At.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 cn(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=Dt(n,Kt),r=At.dump(e,{lineWidth:-1,sortKeys:!1,quotingType:'"'});ks(o,bs+r,"utf-8")}var Ct="kanonak.org",Pt="skill-to-skill-md",Ne=class{parser=new As;objectParser=new Ds;runner=new V;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 Ks(r,this.objectParser);if(!s){console.error(`Cannot deploy: ${Ct}/${Pt}@1.0.0 is not installed in the workspace or cache.`);return}let c=await this.runner.run({transformation:s,instances:t,allKanonaks:o,repository:r,parser:this.parser,objectParser:this.objectParser,outputFormat:"markdown-with-frontmatter"});if(c.length===0){console.error("No skills could be transformed from the package.");return}let i=await fe(a,r),l=je(i),u=t[0].namespace,{publisher:d,package_:p,version:y}=Cs(u);for(let b of c){let f=await Te(b.fileName,a,r),k=xe(Ue(f,"SKILL.md"));ws(f,{recursive:!0}),vs(Ue(f,"SKILL.md"),b.content,"utf-8"),l.skills[b.fileName]={publisher:d,package_:p,version:y,resolved:d?`kanonak://${d}/${p}@${y}`:"",integrity:L(b.content)},console.log(` ${k?"Updated":"Installed"} skill "${b.fileName}" \u2192 ${f}`)}cn(i,l)}async undeploy(e,t){let{repository:o,options:r}=t,a=await Te(e,r,o);xe(a)||(console.error(`Skill "${e}" is not installed at ${a}`),process.exit(1)),$s(a,{recursive:!0,force:!0});let s=await fe(r,o),c=je(s);delete c.skills[e],cn(s,c),console.log(`Removed skill "${e}" from ${a}`)}async list(e){let{repository:t,options:o}=e,r=await fe(o,t),a=je(r),s=[];for(let[c,i]of Object.entries(a.skills))s.push({name:c,publisher:i.publisher,package_:i.package_,version:i.version,path:await Te(c,o,t)});if(xe(r))try{let c=Ss(r,{withFileTypes:!0});for(let i of c){if(!i.isDirectory()||a.skills[i.name])continue;let l=Ue(r,i.name,"SKILL.md");xe(l)&&s.push({name:i.name,publisher:"",package_:"",version:"",path:Ue(r,i.name)})}}catch{}return s}};async function Ks(n,e){let t=await n.getDocumentsByNamespaceAsync(Ct,Pt);if(t.length===0)return;let o=new K(t[0],n),r=await e.parseKanonaks(o);return C(r,g.Transformation)[0]}function Cs(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 Ms,rmSync as Bs,existsSync as un,readdirSync as Vs,writeFileSync as Hs,statSync as zs}from"fs";import{join as Fe}from"path";import{KanonakObjectParser as qs,KanonakParser as Gs}from"@kanonak-protocol/sdk";import{join as Et}from"path";import{homedir as _t}from"os";import{KanonakObjectParser as Ps}from"@kanonak-protocol/sdk";var z="kanonak.org",q="agent-skills",Rt={publisher:z,package_:q,name:"Client"},Tt={publisher:z,package_:q,name:"clientId"},Es={publisher:z,package_:q,name:"projectAgentDir"},_s={publisher:z,package_:q,name:"userAgentDir"},Is={publisher:z,package_:q,name:"agentFileFormat"},Rs="agents";function Ts(){if(process.env.CLAUDE_CODE||process.env.CLAUDE_PROJECT_DIR)return"claude-code"}async function Oe(n,e){let t=(n.client??Ts()??Rs).toLowerCase(),o=n.scope??"project",r=await js(t,e);if(!r){let u=await xs(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=P(r,o==="user"?_s:Es);if(!s)throw new Error(`Client "${t}" has no ${o==="user"?"userAgentDir":"projectAgentDir"} declared.`);let i=B(r,Is)?.name==="toml"?"toml":"markdown-frontmatter",l=i==="toml"?".toml":".md";return{agentsDir:Us(s),format:i,fileExtension:l}}var It=new WeakMap;async function jt(n){let e=It.get(n);if(e)return e;let t=await n.getDocumentsByNamespaceAsync(z,q);if(t.length===0)throw new Error(`Could not find ${z}/${q} in the repository. Install a capability that imports agent-skills to populate the cache.`);let r=[...t].sort((i,l)=>{let u=i.metadata.namespace_?.version,d=l.metadata.namespace_?.version;return!u||!d?0:u.major!==d.major?d.major-u.major:u.minor!==d.minor?d.minor-u.minor:d.patch-u.patch})[0],a=new Ps,s=new K(r,n),c=await a.parseKanonaks(s);return It.set(n,c),c}async function js(n,e){let t=await jt(e),o=C(t,Rt);for(let r of o)if(P(r,Tt)===n)return r}async function xs(n){let e=await jt(n),t=C(e,Rt),o=[];for(let r of t){let a=P(r,Tt);a&&o.push(a)}return o}function Us(n){return n.startsWith("~/")?Et(_t(),n.slice(2)):n==="~"?_t():n.startsWith("/")||/^[A-Za-z]:[\\/]/.test(n)?n:Et(process.cwd(),n)}import{readFileSync as Ns,writeFileSync as Os,existsSync as Ls}from"fs";import{join as xt}from"path";import Ut from"js-yaml";var Nt="agents.lock",Fs=`# This file is generated by Kanonak CLI. Do not edit manually.
171
- `;function Le(n){let e=xt(n,Nt);if(!Ls(e))return{version:"1",lastUpdated:new Date().toISOString(),agents:{}};let t=Ns(e,"utf-8"),o=Ut.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 ln(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=xt(n,Nt),r=Ut.dump(e,{lineWidth:-1,sortKeys:!1,quotingType:'"'});Os(o,Fs+r,"utf-8")}var Ot="kanonak.org",Lt="agent-to-agent-file",Me=class{parser=new Gs;objectParser=new qs;runner=new V;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:c,fileExtension:i}=await Oe(a,r),l=await Ws(r,this.objectParser);if(!l){console.error(`Cannot deploy: ${Ot}/${Lt}@1.0.0 is not installed in the workspace or cache.`);return}let u=c==="toml"?"toml":"markdown-with-frontmatter",d=await this.runner.run({transformation:l,instances:t,allKanonaks:o,repository:r,parser:this.parser,objectParser:this.objectParser,outputFormat:u});if(d.length===0){console.error("No agents could be transformed from the package.");return}Ms(s,{recursive:!0});let p=Le(s),y=t[0].namespace,{publisher:b,package_:f,version:k}=Js(y);for(let h of d){let $=`${h.fileName}${i}`,w=Fe(s,$),v=un(w);Hs(w,h.content,"utf-8"),p.agents[h.fileName]={publisher:b,package_:f,version:k,resolved:b?`kanonak://${b}/${f}@${k}`:"",integrity:L(h.content),fileName:$},console.log(` ${v?"Updated":"Installed"} agent "${h.fileName}" \u2192 ${w}`)}ln(s,p)}async undeploy(e,t){let{repository:o,options:r}=t,{agentsDir:a}=await Oe(r,o),s=Le(a),c=s.agents[e];c||(console.error(`Agent "${e}" is not installed at ${a}`),process.exit(1));let i=Fe(a,c.fileName);un(i)&&Bs(i,{force:!0}),delete s.agents[e],ln(a,s),console.log(`Removed agent "${e}" from ${i}`)}async list(e){let{repository:t,options:o}=e,{agentsDir:r}=await Oe(o,t),a=Le(r),s=[];for(let[c,i]of Object.entries(a.agents))s.push({name:c,publisher:i.publisher,package_:i.package_,version:i.version,path:Fe(r,i.fileName)});if(un(r))try{let c=Vs(r,{withFileTypes:!0});for(let i of c){if(!i.isFile()||i.name==="agents.lock")continue;let l=Fe(r,i.name),u=Xs(i.name);if(!a.agents[u]){try{if(!zs(l).isFile())continue}catch{continue}s.push({name:u,publisher:"",package_:"",version:"",path:l})}}}catch{}return s}};async function Ws(n,e){let t=await n.getDocumentsByNamespaceAsync(Ot,Lt);if(t.length===0)return;let o=new K(t[0],n),r=await e.parseKanonaks(o);return C(r,g.Transformation)[0]}function Xs(n){let e=n.lastIndexOf(".");return e===-1?n:n.substring(0,e)}function Js(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 si=ei(Qs(import.meta.url)),ii=JSON.parse(Zs(ni(si,"..","package.json"),"utf-8")),O=new Ys;O.name("kanonak").description("Kanonak Protocol CLI - Validate and resolve Kanonak ontology packages").version(ii.version);O.command("validate <path>").description("Validate .kan.yml file(s). Resolves imports via HTTP from publisher domains.").action(async n=>{await gn(n)});O.command("install [package]").description("Install a package and its dependencies, or install all from kanonak.lock.").action(async n=>{await bn(n)});O.command("deps <path>").description("Show resolved dependency tree for a .kan.yml file.").action(async n=>{await $n(n)});O.command("login <publisher>").description("Authenticate with a package publisher using OAuth 2.0.").action(async n=>{await Kn(n)});O.command("logout <publisher>").description("Revoke tokens and remove stored credentials for a publisher.").action(async n=>{await Cn(n)});O.addCommand(Fn());O.addCommand(lt());O.addCommand(gt());async function ci(){try{let n=new T,e=new ti,t=new ri,o=ai(t),r=new oi({fetchFn:o}),a=await j(process.cwd(),e),s=new Re;s.register("kanonak.org/capabilities/agent-skill-deployment",new Ne),s.register("kanonak.org/agent-capabilities/agent-instance-deployment",new Me);let c=await On(n,e,a),i=new Ie(n,e,r,o,s,a);kt(O,c,i)}catch{}}await ci();O.parse();
162
+ ${m}`)}let c=Array.from(i.values())[0];if(c.length===1)return{transformation:c[0].tx,transformationKanonaks:c[0].kanonaks};let l=new Map(c.map(m=>[m.doc,m])),u=nn(c.map(m=>m.doc));if(!u.chosen)throw new Error(`Could not select a Transformation version for "${a}".`);let d=l.get(u.chosen);if(u.multipleVersionsPresent){let m=f=>{let k=f.metadata.namespace_?.version;return k?ut(k):""},g=d.tx.namespace??"",h=g.includes("@")?g.substring(0,g.indexOf("@")):g;console.warn(`Warning: Transformation "${a}" has ${c.length} versions present (${c.map(f=>m(f.doc)).filter(Boolean).join(", ")}); using @${m(u.chosen)}. Pin with ${h}@<version>/${a} to suppress this warning.`)}return{transformation:d.tx,transformationKanonaks:d.kanonaks}}async function Ya(n,e,t,o){if(/^[.\/\\]/.test(n)||/^[A-Za-z]:/.test(n)||n.endsWith(".kan.yml")||it(n)&&Na(n).isFile()){if(!it(n))throw new Error(`Scope file not found: ${n}`);let h=xa(n,"utf-8"),f=t.parse(h),k=new A(f,e);return o.parseKanonaks(k)}let a=n.indexOf("@"),s=a===-1?n:n.substring(0,a),i=a===-1?void 0:n.substring(a+1),c=s.indexOf("/");if(c===-1)throw new Error(`Invalid scope "${n}" \u2014 expected a file path or publisher/package[@version] URI`);let l=s.substring(0,c),u=s.substring(c+1),d=await e.getDocumentsByNamespaceAsync(l,u);if(d.length===0)throw new Error(`Scope package ${l}/${u} not found in the local workspace or cache.`);let m=pt(d,i,`${l}/${u}`),g=new A(m,e);return o.parseKanonaks(g)}function Za(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 pt(n,e,t){let o=a=>{let s=a.metadata.namespace_?.version;return s?ut(s):""},r=nn(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 ct(n,e){try{let t=te(n,e);return{uri:_e(n),matchesClass:Ee(t.inputPattern.matchesClass),outputs:Array.from(t.outputs).sort()}}catch(t){return{uri:_e(n),matchesClass:`(compile error: ${t.message})`,outputs:[]}}}function _e(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 Qa(n){return n.replace(/[\\/:*?"<>|\s]+/g,"_").replace(/^_+|_+$/g,"")}async function es(n,e,t){let o=new Map;for(let s of n){if(!(s instanceof Fa))continue;let i=tn(s);i&&o.set(i,s)}let r=[];try{r=(await new Ma({vocabulary:new Ba}).reason(t)).getInstancesOfClass(lt(e.publisher,e.package_,e.name))}catch{}let a=[];for(let s of r){let i=o.get(s);i&&a.push(i)}return a.length>0?a:P(n,e)}function tn(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:lt(o.substring(0,r),o.substring(r+1),n.name)}import{Command as ns}from"commander";import{KanonakParser as ts,PublisherIndex as ft,CredentialStore as gt,createAuthenticatedFetch as ht,FileSystemKanonakDocumentRepository as os,Reasoner as rs,KanonakVocabulary as as,getGlobalCachePath as ss,makeUriKey as is}from"@kanonak-protocol/sdk";function cs(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 kt(){return new ns("search").description("Browse a publisher's catalogue or find instances of a class via the SDK reasoner").argument("<publisher>","Publisher domain (e.g. kanonak.org)").option("--type <uri>","Class URI to search for, in publisher/package/Name form").action(async(n,e)=>{e.type?await us(n,e.type):await ls(n)})}async function ls(n){let e=new gt,t=ht(e),o=new ft({fetchFn:t}),r;try{r=await o.listLatestPackages(n)}catch(s){console.error(`Failed to fetch publisher index for ${n}: ${s.message}`),process.exit(1)}if(r.length===0){console.log(`No packages found at ${n}.`);return}console.log(`Packages published by ${n}:
163
+ `);let a=r.reduce((s,i)=>Math.max(s,i.packageName.length),0);for(let{packageName:s,version:i}of r)console.log(` ${s.padEnd(a)} @${i}`)}async function us(n,e){let t=cs(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 ts,r=new gt,a=ht(r),s=new ft({fetchFn:a}),i=new T,c=new Set,l=[];try{l=await s.listLatestPackages(n)}catch(k){console.error(`Failed to fetch publisher index for ${n}: ${k.message}`),process.exit(1)}for(let{packageName:k,version:y}of l)c.add(`${n}|${k}|${y}`);await on(s,i,a,"kanonak.org","core-rdf",c),await on(s,i,a,"kanonak.org","core-owl",c),await on(s,i,a,t.publisher,t.package_,c);for(let k of c){let[y,w,$]=k.split("|");if(!i.has(y,w,$))try{let v=await s.getPackageUrl(y,w,$),D=await a(v,y);if(!D.ok){console.error(`Warning: failed to fetch ${y}/${w}@${$}: ${D.status} ${D.statusText}`);continue}let W=await D.text();i.put(y,w,$,W)}catch(v){console.error(`Warning: failed to fetch ${y}/${w}@${$}: ${v.message}`)}}let u=new os(ss(),!0,o),m=await new rs({vocabulary:new as}).reason(u),g=is(t.publisher,t.package_,t.name),f=m.getInstancesOfClass(g).filter(k=>k!==g);if(f.length===0){console.log(`No instances of ${g} found in ${n}'s catalogue.`);return}console.log(`Instances of ${g} in ${n}'s catalogue:
164
+ `),f.sort();for(let k of f)console.log(` ${k}`)}async function on(n,e,t,o,r,a){try{let s=await n.getHighestVersion(o,r);if(!s)return;a.add(`${o}|${r}|${s}`)}catch{}}import{Command as yt}from"commander";function ae(n){return`${E}/${_}/${n}`}var rn={[ae("fetch-and-deploy")]:(n,e,t,o)=>n.add(e,t[0],o),[ae("remove-deployed")]:(n,e,t,o)=>n.remove(e,t[0],o),[ae("list-deployed")]:(n,e,t,o)=>n.list(e,o),[ae("update-deployed")]:(n,e,t,o)=>n.update(e,t[0],o),[ae("search-available")]:(n,e,t,o)=>n.search(e,o),[ae("show-info")]:(n,e,t,o)=>n.info(e,t[0],o)};function bt(n,e,t){for(let o of e){let r=new yt(o.commandName).description(o.description.trim());for(let a of o.commands){let s=r.command(ds(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=ms(i);await ps(t,o,a,i,c)})}n.addCommand(r)}}function ds(n){let e=n.arguments.filter(t=>!t.isOption).map(t=>t.required?`<${t.argumentName}>`:`[${t.argumentName}]`);return[n.subcommandName,...e].join(" ")}function ms(n){for(let e=n.length-1;e>=0;e--)if(n[e]&&typeof n[e]=="object"&&!(n[e]instanceof yt))return n[e];return{}}async function ps(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(rn).join(", ")}.`),process.exit(1));let s=rn[t.actionKey];s||(console.error(`Capability subcommand '${t.subcommandName}' references unknown Action '${t.actionKey}'. Known actions: ${Object.keys(rn).join(", ")}.`),process.exit(1)),await s(n,e,a,r)}import{existsSync as wt,readFileSync as fs,statSync as $t}from"fs";import{resolve as gs}from"path";import{KanonakObjectParser as hs,PublisherIndex as an,PublisherConfigResolver as ks,formatVersion as St,pickHighestDocument as ys}from"@kanonak-protocol/sdk";var Ie=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 hs;async add(e,t,o){let r=this.tryLoadFromLocalFile(t);if(r){this.fileCache.put(r.publisher,r.packageName,r.version,r.content),await this.deployFromDoc(e,r.doc,r.publisher,r.packageName,r.version,void 0,`local file ${t}`,o);return}let a=X(t);a||(console.error(`Invalid package reference: "${t}"`),console.error(""),console.error("Accepted forms:"),console.error(" publisher/package (install all instances, latest version)"),console.error(" publisher/package@version (install all instances, pinned)"),console.error(" publisher/package/instance (install one instance, latest version)"),console.error(" publisher/package@version/instance (install one instance, pinned)"),console.error(" ./path/to/file.kan.yml (install all instances from a local document)"),console.error(""),console.error("Tip: copy a URI directly from `kanonak "+e.commandName+" search`."),process.exit(1));let{publisher:s,packageName:i,version:c,instanceName:l}=a,u=await this.repository.getDocumentsByNamespaceAsync(s,i);if(u.length>0){let g=ys(u,{requestedVersion:c??void 0});if(g.chosen){let h=g.chosen.metadata.namespace_;(!h||!h.version)&&(console.error(`Document for ${s}/${i} is missing namespace metadata.`),process.exit(1));let f=St(h.version);this.fileCache.put(s,i,f,this.parser.save(g.chosen)),await this.deployFromDoc(e,g.chosen,s,i,f,l??void 0,`${s}/${i}@${f}`,o);return}}let d=c??await this.publisherIndex.getHighestVersion(s,i);d||(console.error(`Could not resolve version for "${s}/${i}".`),await this.printPackageSuggestions(s,i,e.commandName),process.exit(1));let m=this.fileCache.get(s,i,d);if(!m){let g=await this.publisherIndex.getPackageUrl(s,i,d),h=await this.fetchFn(g,s);h.ok||(h.status===404?(console.error(`Package ${s}/${i}@${d} not found at ${g}.`),console.error(`The publisher index lists this version but the file is missing \u2014 it may have been unpublished. Try \`kanonak ${e.commandName} search\` to see the current catalogue.`)):console.error(`Failed to fetch ${g} (${h.status} ${h.statusText}).`),process.exit(1)),m=await h.text(),this.fileCache.put(s,i,d,m)}await this.deployFromDoc(e,this.parser.parse(m),s,i,d,l??void 0,`${s}/${i}@${d}`,o)}tryLoadFromLocalFile(e){if(!(/^[.\/\\]/.test(e)||/^[A-Za-z]:[\\/]/.test(e)||e.endsWith(".kan.yml")||wt(e)&&$t(e).isFile()))return;let o=gs(e);(!wt(o)||!$t(o).isFile())&&(console.error(`Local file not found: ${e}`),process.exit(1));let r=fs(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:St(s.version)}}async deployFromDoc(e,t,o,r,a,s,i,c){let l=new A(t,this.repository),u=await this.objectParser.parseKanonaks(l),d=vt(e.managesTypeKey);d||(console.error(`Capability "${e.commandName}" has no resolved managesType.`),process.exit(1));let m=P(u,d);m.length===0&&(console.error(`${i} does not contain any ${N(d)} instances.`),process.exit(1));let g=m;if(s&&(g=m.filter(k=>k.name===s),g.length===0)){console.error(`Instance "${s}" not found in ${i}.`),console.error(""),console.error(`Available ${N(d)} instance(s):`);for(let k of m)console.error(` - ${k.name}`);console.error(""),console.error("To install all of them, drop the instance suffix:"),console.error(` kanonak ${e.commandName} add ${o}/${r}`),process.exit(1)}let h=s?`${s} from ${i}`:`${g.length} ${N(d)} instance(s) from ${i}`;console.log(`Installing ${h}...`);let f=this.handlerRegistry.get(e.deploymentTargetKey);f?await f.deploy({instances:g,allKanonaks:u,repository:this.repository,options:c}):console.log(`Cached ${o}/${r}@${a} (no deployment handler for "${e.deploymentTargetKey}")`)}async printPackageSuggestions(e,t,o){let r;try{r=await this.publisherIndex.listLatestPackages(e)}catch{return}let a=r.map(s=>({name:s.packageName,version:s.version,score:bs(t,s.packageName)})).filter(s=>s.score>0).sort((s,i)=>i.score-s.score).slice(0,5);if(a.length!==0){console.error(""),console.error("Did you mean one of:");for(let s of a)console.error(` kanonak ${o} add ${e}/${s.name}`)}}async remove(e,t,o){await this.requireHandler(e).undeploy(t,{repository:this.repository,options:o})}async list(e,t){let r=await this.requireHandler(e).list({repository:this.repository,options:t}),a=e.managesTypeKey||"managed";if(r.length===0){console.log(`No ${a} instances installed.`);return}console.log(`Installed ${a} instances:
165
+ `);for(let s of r){let i=s.publisher?`${s.publisher}/${s.package_}@${s.version}`:"unmanaged";console.log(` ${s.name} (${i}) ${s.path}`)}}async update(e,t,o){let a=await this.requireHandler(e).list({repository:this.repository,options:o}),s=t?a.filter(c=>c.name===t):a.filter(c=>c.publisher);if(s.length===0){console.log(t?`"${t}" not found.`:"No managed instances to update.");return}let i=0;for(let c of s){let l=await this.publisherIndex.getHighestVersion(c.publisher,c.package_);!l||l===c.version||(console.log(`Updating ${c.name}: ${c.version} \u2192 ${l}`),await this.add(e,`${c.publisher}/${c.package_}@${l}`,o),i++)}console.log(i===0?"All instances are up to date.":`
166
+ Updated ${i} instance(s).`)}async search(e,t){let o=t.publisher??"kanonak.org",r=vt(e.managesTypeKey);if(!r){console.error("Capability has no resolved managesType; nothing to search for.");return}console.log(`Searching ${o} for ${N(r)} instances...
167
+ `);let a=new ks,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=an.parseIndex(l);if(u.size===0){console.error(`No packages found for publisher "${o}".`);return}let d=new Map;for(let[f,k]of u){let y=[...k].sort((w,$)=>{let v=an.parseVersion(w),D=an.parseVersion($);return!v||!D?0:v.major!==D.major?D.major-v.major:v.minor!==D.minor?D.minor-v.minor:D.patch-v.patch});d.set(f,y[0])}let m=[],g=0;for(let[f,k]of d){let y=this.fileCache.get(o,f,k);if(!y)try{let w=await this.publisherIndex.getPackageUrl(o,f,k),$=await this.fetchFn(w,o);if(!$.ok)continue;y=await $.text(),this.fileCache.put(o,f,k,y)}catch{continue}try{let w=this.parser.parse(y),$=new A(w,this.repository),v=await this.objectParser.parseKanonaks($),D=P(v,r);for(let W of D)m.push({publisher:o,package_:f,version:k,subject:W});g++}catch{continue}}if(m.length===0){console.log(`No ${N(r)} instances found across ${g} package(s).`);return}console.log(`Found ${m.length} ${N(r)} instance(s) in ${g} package(s):
168
+ `);let h=new Map;for(let f of m){let k=`${f.publisher}/${f.package_}@${f.version}`,y=h.get(k);y?y.push(f):h.set(k,[f])}for(let[f,k]of h){let y=k[0],w=`${y.publisher}/${y.package_}`,$=k.length===1;console.log(` ${f}`),console.log(` ${k.length} skill${$?"":"s"}:`);for(let v of k)console.log(` - ${v.subject.name}`);if(console.log(""),$)console.log(" install:"),console.log(` kanonak ${e.commandName} add ${w}/${y.subject.name}`);else{console.log(" install one of them:");for(let v of k)console.log(` kanonak ${e.commandName} add ${w}/${v.subject.name}`);console.log(" install all of them:"),console.log(` kanonak ${e.commandName} add ${w}`)}console.log("")}}async info(e,t,o){let s=(await this.requireHandler(e).list({repository:this.repository,options:o})).find(i=>i.name===t);s||(console.error(`"${t}" is not installed.`),process.exit(1)),console.log(`Name: ${s.name}`),console.log(`Type: ${e.managesTypeKey||"n/a"}`),console.log(`Publisher: ${s.publisher||"unmanaged"}`),console.log(`Package: ${s.package_||"n/a"}`),console.log(`Version: ${s.version||"n/a"}`),console.log(`Path: ${s.path}`)}requireHandler(e){let t=this.handlerRegistry.get(e.deploymentTargetKey);return t||(console.error(`No deployment handler registered for "${e.deploymentTargetKey}". Ensure the capability's deploymentTarget resolves to a DeploymentTarget instance whose URI is registered in the CLI at startup.`),process.exit(1)),t}};function vt(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)),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=ws(t,o);return i===0?100:i<=2?Math.max(1,20-i*5):0}function ws(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 Re=class{handlers=new Map;register(e,t){this.handlers.set(e,t)}get(e){return this.handlers.get(e)??null}};import{mkdirSync as Is,rmSync as Rs,existsSync as je,readdirSync as Ts,writeFileSync as xs}from"fs";import{join as Ue}from"path";import{KanonakObjectParser as js,KanonakParser as Us,computeIntegrity as Ns}from"@kanonak-protocol/sdk";import{join as sn}from"path";import{homedir as Dt}from"os";import{KanonakObjectParser as $s}from"@kanonak-protocol/sdk";var H="kanonak.org",z="agent-skills",At={publisher:H,package_:z,name:"Client"},Ct={publisher:H,package_:z,name:"clientId"},Ss={publisher:H,package_:z,name:"projectSkillDir"},vs={publisher:H,package_:z,name:"userSkillDir"},Ds={publisher:H,package_:z,name:"skillFileName"},Pt="agents";async function pe(n,e){let t=(n.client??Et()??Pt).toLowerCase(),o=n.scope??"project",r=await It(t,e);if(!r){let i=await Ks(e);throw new Error(`Unknown client "${t}". Known clients: ${i.join(", ")||"(none)"}. Add a Client instance to a package that imports kanonak.org/agent-skills and install that package to make it available.`)}let s=C(r,o==="user"?vs:Ss);if(!s)throw new Error(`Client "${t}" has no ${o==="user"?"userSkillDir":"projectSkillDir"} declared.`);return As(s)}async function Te(n,e,t){let o=await pe(e,t);return sn(o,n)}async function cn(n,e){let t=(n.client??Et()??Pt).toLowerCase(),o=await It(t,e);return o?C(o,Ds)??"SKILL.md":"SKILL.md"}function Et(){if(process.env.CLAUDE_CODE||process.env.CLAUDE_PROJECT_DIR)return"claude-code"}var Kt=new WeakMap;async function _t(n){let e=Kt.get(n);if(e)return e;let t=await n.getDocumentsByNamespaceAsync(H,z);if(t.length===0)throw new Error(`Could not find ${H}/${z} in the repository. Install a skill capability (which transitively imports agent-skills) or fetch agent-skills directly to populate the cache.`);let r=[...t].sort((c,l)=>{let u=c.metadata.namespace_?.version,d=l.metadata.namespace_?.version;return!u||!d?0:u.major!==d.major?d.major-u.major:u.minor!==d.minor?d.minor-u.minor:d.patch-u.patch})[0],a=new $s,s=new A(r,n),i=await a.parseKanonaks(s);return Kt.set(n,i),i}async function It(n,e){let t=await _t(e),o=P(t,At);for(let r of o)if(C(r,Ct)===n)return r}async function Ks(n){let e=await _t(n),t=P(e,At),o=[];for(let r of t){let a=C(r,Ct);a&&o.push(a)}return o}function As(n){return n.startsWith("~/")?sn(Dt(),n.slice(2)):n==="~"?Dt():n.startsWith("/")||/^[A-Za-z]:[\\/]/.test(n)?n:sn(process.cwd(),n)}import{readFileSync as Cs,writeFileSync as Ps,existsSync as Es}from"fs";import{join as Rt}from"path";import Tt from"js-yaml";var xt="skills.lock",_s=`# This file is generated by Kanonak CLI. Do not edit manually.
169
+ `;function xe(n){let e=Rt(n,xt);if(!Es(e))return{version:"1",lastUpdated:new Date().toISOString(),skills:{}};let t=Cs(e,"utf-8"),o=Tt.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 ln(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=Rt(n,xt),r=Tt.dump(e,{lineWidth:-1,sortKeys:!1,quotingType:'"'});Ps(o,_s+r,"utf-8")}var jt="kanonak.org",Ut="skill-to-skill-md",Ne=class{parser=new Us;objectParser=new js;runner=new B;async deploy(e){let{instances:t,allKanonaks:o,repository:r,options:a}=e;if(t.length===0){console.error("No Skill instances to deploy.");return}let s=await Os(r,this.objectParser);if(!s){console.error(`Cannot deploy: ${jt}/${Ut}@1.0.0 is not installed in the workspace or cache.`);return}let i=await this.runner.run({transformation:s,instances:t,allKanonaks:o,repository:r,parser:this.parser,objectParser:this.objectParser,outputFormat:"markdown-with-frontmatter"});if(i.length===0){console.error("No skills could be transformed from the package.");return}let c=await pe(a,r),l=await cn(a,r),u=xe(c),d=t[0].namespace,{publisher:m,package_:g,version:h}=Ls(d);for(let f of i){let k=await Te(f.fileName,a,r),y=je(Ue(k,l));Is(k,{recursive:!0}),xs(Ue(k,l),f.content,"utf-8"),u.skills[f.fileName]={publisher:m,package_:g,version:h,resolved:m?`kanonak://${m}/${g}@${h}`:"",integrity:Ns(f.content)},console.log(` ${y?"Updated":"Installed"} skill "${f.fileName}" \u2192 ${k}`)}ln(c,u)}async undeploy(e,t){let{repository:o,options:r}=t,a=await Te(e,r,o);je(a)||(console.error(`Skill "${e}" is not installed at ${a}`),process.exit(1)),Rs(a,{recursive:!0,force:!0});let s=await pe(r,o),i=xe(s);delete i.skills[e],ln(s,i),console.log(`Removed skill "${e}" from ${a}`)}async list(e){let{repository:t,options:o}=e,r=await pe(o,t),a=xe(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 Te(c,o,t)});let i=await cn(o,t);if(je(r))try{let c=Ts(r,{withFileTypes:!0});for(let l of c){if(!l.isDirectory()||a.skills[l.name])continue;let u=Ue(r,l.name,i);je(u)&&s.push({name:l.name,publisher:"",package_:"",version:"",path:Ue(r,l.name)})}}catch{}return s}};async function Os(n,e){let t=await n.getDocumentsByNamespaceAsync(jt,Ut);if(t.length===0)return;let o=new A(t[0],n),r=await e.parseKanonaks(o);return P(r,b.Transformation)[0]}function Ls(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 Qs,rmSync as ei,existsSync as dn,readdirSync as ni,writeFileSync as ti,statSync as oi}from"fs";import{join as Fe}from"path";import{KanonakObjectParser as ri,KanonakParser as ai,computeIntegrity as si}from"@kanonak-protocol/sdk";import{join as Nt}from"path";import{homedir as Ot}from"os";import{KanonakObjectParser as Fs}from"@kanonak-protocol/sdk";var q="kanonak.org",G="agent-skills",Ft={publisher:q,package_:G,name:"Client"},Mt={publisher:q,package_:G,name:"clientId"},Ms={publisher:q,package_:G,name:"projectAgentDir"},Bs={publisher:q,package_:G,name:"userAgentDir"},Vs={publisher:q,package_:G,name:"agentFileFormat"},Hs="agents";function zs(){if(process.env.CLAUDE_CODE||process.env.CLAUDE_PROJECT_DIR)return"claude-code"}async function Oe(n,e){let t=(n.client??zs()??Hs).toLowerCase(),o=n.scope??"project",r=await qs(t,e);if(!r){let u=await Gs(e);throw new Error(`Unknown client "${t}". Known clients: ${u.join(", ")||"(none)"}. Add a Client instance to a package that imports kanonak.org/agent-skills and install that package to make it available.`)}let s=C(r,o==="user"?Bs:Ms);if(!s)throw new Error(`Client "${t}" has no ${o==="user"?"userAgentDir":"projectAgentDir"} declared.`);let c=M(r,Vs)?.name==="toml"?"toml":"markdown-frontmatter",l=c==="toml"?".toml":".md";return{agentsDir:Ws(s),format:c,fileExtension:l}}var Lt=new WeakMap;async function Bt(n){let e=Lt.get(n);if(e)return e;let t=await n.getDocumentsByNamespaceAsync(q,G);if(t.length===0)throw new Error(`Could not find ${q}/${G} in the repository. Install a capability that imports agent-skills to populate the cache.`);let r=[...t].sort((c,l)=>{let u=c.metadata.namespace_?.version,d=l.metadata.namespace_?.version;return!u||!d?0:u.major!==d.major?d.major-u.major:u.minor!==d.minor?d.minor-u.minor:d.patch-u.patch})[0],a=new Fs,s=new A(r,n),i=await a.parseKanonaks(s);return Lt.set(n,i),i}async function qs(n,e){let t=await Bt(e),o=P(t,Ft);for(let r of o)if(C(r,Mt)===n)return r}async function Gs(n){let e=await Bt(n),t=P(e,Ft),o=[];for(let r of t){let a=C(r,Mt);a&&o.push(a)}return o}function Ws(n){return n.startsWith("~/")?Nt(Ot(),n.slice(2)):n==="~"?Ot():n.startsWith("/")||/^[A-Za-z]:[\\/]/.test(n)?n:Nt(process.cwd(),n)}import{readFileSync as Xs,writeFileSync as Js,existsSync as Ys}from"fs";import{join as Vt}from"path";import Ht from"js-yaml";var zt="agents.lock",Zs=`# This file is generated by Kanonak CLI. Do not edit manually.
170
+ `;function Le(n){let e=Vt(n,zt);if(!Ys(e))return{version:"1",lastUpdated:new Date().toISOString(),agents:{}};let t=Xs(e,"utf-8"),o=Ht.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 un(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=Vt(n,zt),r=Ht.dump(e,{lineWidth:-1,sortKeys:!1,quotingType:'"'});Js(o,Zs+r,"utf-8")}var qt="kanonak.org",Gt="agent-to-agent-file",Me=class{parser=new ai;objectParser=new ri;runner=new B;async deploy(e){let{instances:t,allKanonaks:o,repository:r,options:a}=e;if(t.length===0){console.error("No Agent instances to deploy.");return}let{agentsDir:s,format:i,fileExtension:c}=await Oe(a,r),l=await ii(r,this.objectParser);if(!l){console.error(`Cannot deploy: ${qt}/${Gt}@1.0.0 is not installed in the workspace or cache.`);return}let u=i==="toml"?"toml":"markdown-with-frontmatter",d=await this.runner.run({transformation:l,instances:t,allKanonaks:o,repository:r,parser:this.parser,objectParser:this.objectParser,outputFormat:u});if(d.length===0){console.error("No agents could be transformed from the package.");return}Qs(s,{recursive:!0});let m=Le(s),g=t[0].namespace,{publisher:h,package_:f,version:k}=li(g);for(let y of d){let w=`${y.fileName}${c}`,$=Fe(s,w),v=dn($);ti($,y.content,"utf-8"),m.agents[y.fileName]={publisher:h,package_:f,version:k,resolved:h?`kanonak://${h}/${f}@${k}`:"",integrity:si(y.content),fileName:w},console.log(` ${v?"Updated":"Installed"} agent "${y.fileName}" \u2192 ${$}`)}un(s,m)}async undeploy(e,t){let{repository:o,options:r}=t,{agentsDir:a}=await Oe(r,o),s=Le(a),i=s.agents[e];i||(console.error(`Agent "${e}" is not installed at ${a}`),process.exit(1));let c=Fe(a,i.fileName);dn(c)&&ei(c,{force:!0}),delete s.agents[e],un(a,s),console.log(`Removed agent "${e}" from ${c}`)}async list(e){let{repository:t,options:o}=e,{agentsDir:r}=await Oe(o,t),a=Le(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:Fe(r,c.fileName)});if(dn(r))try{let i=ni(r,{withFileTypes:!0});for(let c of i){if(!c.isFile()||c.name==="agents.lock")continue;let l=Fe(r,c.name),u=ci(c.name);if(!a.agents[u]){try{if(!oi(l).isFile())continue}catch{continue}s.push({name:u,publisher:"",package_:"",version:"",path:l})}}}catch{}return s}};async function ii(n,e){let t=await n.getDocumentsByNamespaceAsync(qt,Gt);if(t.length===0)return;let o=new A(t[0],n),r=await e.parseKanonaks(o);return P(r,b.Transformation)[0]}function ci(n){let e=n.lastIndexOf(".");return e===-1?n:n.substring(0,e)}function li(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 bi=pi(mi(import.meta.url)),wi=JSON.parse(di(fi(bi,"..","package.json"),"utf-8")),O=new ui;O.name("kanonak").description("Kanonak Protocol CLI - Validate and resolve Kanonak ontology packages").version(wi.version);O.command("validate <path>").description("Validate .kan.yml file(s). Resolves imports via HTTP from publisher domains.").action(async n=>{await hn(n)});O.command("install [package]").description("Install a package and its dependencies, or install all from kanonak.lock.").action(async n=>{await kn(n)});O.command("deps <path>").description("Show resolved dependency tree for a .kan.yml file.").action(async n=>{await bn(n)});O.command("login <publisher>").description("Authenticate with a package publisher using OAuth 2.0.").action(async n=>{await Dn(n)});O.command("logout <publisher>").description("Revoke tokens and remove stored credentials for a publisher.").action(async n=>{await Kn(n)});O.addCommand(Fn());O.addCommand(dt());O.addCommand(kt());async function $i(){try{let n=new T,e=new gi,t=new ki,o=yi(t),r=new hi({fetchFn:o}),a=await x(process.cwd(),e),s=new Re;s.register("kanonak.org/capabilities/agent-skill-deployment",new Ne),s.register("kanonak.org/agent-capabilities/agent-instance-deployment",new Me);let i=await Nn(n,e,a),c=new Ie(n,e,r,o,s,a);bt(O,i,c)}catch{}}await $i();O.parse();
@@ -28,6 +28,14 @@ export declare function resolveSkillsDir(options: SkillPathOptions, repository:
28
28
  * Resolve the directory for a specific skill by name.
29
29
  */
30
30
  export declare function resolveSkillDir(skillName: string, options: SkillPathOptions, repository: IKanonakDocumentRepository): Promise<string>;
31
+ /**
32
+ * Resolve the file name to use inside a skill directory for the
33
+ * configured Client. Pulled from the Client's `skillFileName` property
34
+ * in agent-skills@1.2.0+. Defaults to `SKILL.md` when the Client
35
+ * predates the property or doesn't declare it explicitly — which
36
+ * matches the Agent Skills convention every shipped Client follows.
37
+ */
38
+ export declare function resolveSkillFileName(options: SkillPathOptions, repository: IKanonakDocumentRepository): Promise<string>;
31
39
  /**
32
40
  * Auto-detect the current AI agent client from environment variables.
33
41
  * Returns a clientId matching a named Client instance in the
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kanonak-protocol/cli",
3
- "version": "2.1.0",
3
+ "version": "2.3.0",
4
4
  "description": "Kanonak Protocol CLI - Validate and resolve Kanonak ontology packages",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -24,8 +24,7 @@
24
24
  },
25
25
  "repository": {
26
26
  "type": "git",
27
- "url": "git+https://github.com/kanonak-protocol/typescript.git",
28
- "directory": "cli"
27
+ "url": "https://github.com/kanonak-protocol"
29
28
  },
30
29
  "keywords": [
31
30
  "kanonak",
@@ -35,8 +34,8 @@
35
34
  "semantic-web"
36
35
  ],
37
36
  "dependencies": {
38
- "@kanonak-protocol/sdk": "^2.1.0",
39
- "@kanonak-protocol/types": "^2.1.0",
37
+ "@kanonak-protocol/sdk": "^2.3.0",
38
+ "@kanonak-protocol/types": "^2.3.0",
40
39
  "commander": "^13.0.0",
41
40
  "js-yaml": "^4.1.1"
42
41
  },
@@ -1,14 +0,0 @@
1
- export interface LockEntry {
2
- version: string;
3
- resolved: string;
4
- integrity: string;
5
- dependencies: Record<string, string>;
6
- }
7
- export interface LockFile {
8
- version: string;
9
- lastUpdated: string;
10
- packages: Record<string, LockEntry>;
11
- }
12
- export declare function loadLockFile(): LockFile | null;
13
- export declare function saveLockFile(lock: LockFile): void;
14
- export declare function computeIntegrity(content: string): string;