@michaelfromyeg/weft-cli 1.0.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 +21 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +755 -0
- package/dist/index.js.map +1 -0
- package/package.json +57 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Michael DeMarco
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/dist/index.d.ts
ADDED
package/dist/index.js
ADDED
|
@@ -0,0 +1,755 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { createPrivateKey, createPublicKey } from 'crypto';
|
|
3
|
+
import { mkdirSync, writeFileSync, existsSync, readFileSync } from 'fs';
|
|
4
|
+
import { join, resolve as resolve$1, basename, relative } from 'path';
|
|
5
|
+
import { lint, resolveSourceDir, hasMarketplaceManifest, buildMarketplace, build, installMarketplace, install, readLock, lockDirForScope, update, generateSigningKeys, signLock, verifyArtifacts, importNativePlugin, uninstall, WEFT_VERSION, CompileError, AdapterRegistry } from '@michaelfromyeg/weft-core';
|
|
6
|
+
import { discoverEvals, runEval, drivers } from '@michaelfromyeg/weft-eval';
|
|
7
|
+
import { publishCheck, indexFromPluginDirs, fetchMcpRegistry, federate, serializeIndex } from '@michaelfromyeg/weft-index';
|
|
8
|
+
import { defineCommand, runMain, renderUsage } from 'citty';
|
|
9
|
+
import claudeAdapter from '@michaelfromyeg/weft-adapter-claude';
|
|
10
|
+
import codexAdapter from '@michaelfromyeg/weft-adapter-codex';
|
|
11
|
+
import copilotAdapter from '@michaelfromyeg/weft-adapter-copilot';
|
|
12
|
+
import cursorAdapter from '@michaelfromyeg/weft-adapter-cursor';
|
|
13
|
+
import opencodeAdapter from '@michaelfromyeg/weft-adapter-opencode';
|
|
14
|
+
|
|
15
|
+
async function resolve(r) {
|
|
16
|
+
return typeof r === "function" ? await r() : r;
|
|
17
|
+
}
|
|
18
|
+
async function renderCliReference(main2) {
|
|
19
|
+
const out = [
|
|
20
|
+
"# Weft CLI reference",
|
|
21
|
+
"",
|
|
22
|
+
"_Generated from the CLI definition by `weft docs` -- do not edit by hand._",
|
|
23
|
+
"",
|
|
24
|
+
"## `weft`",
|
|
25
|
+
"",
|
|
26
|
+
"```",
|
|
27
|
+
(await renderUsage(main2)).trim(),
|
|
28
|
+
"```",
|
|
29
|
+
""
|
|
30
|
+
];
|
|
31
|
+
const subs = main2.subCommands ? await resolve(main2.subCommands) : {};
|
|
32
|
+
for (const name of Object.keys(subs).sort()) {
|
|
33
|
+
const sub = await resolve(subs[name]);
|
|
34
|
+
const meta = await resolve(sub.meta);
|
|
35
|
+
out.push(`## \`weft ${name}\``, "");
|
|
36
|
+
if (meta?.description) out.push(meta.description, "");
|
|
37
|
+
out.push("```", (await renderUsage(sub, main2)).trim(), "```", "");
|
|
38
|
+
}
|
|
39
|
+
return `${out.join("\n")}
|
|
40
|
+
`;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// src/logger.ts
|
|
44
|
+
var RANK = { error: 0, warn: 1, info: 2, debug: 3 };
|
|
45
|
+
function thresholdFrom(argv) {
|
|
46
|
+
if (argv.includes("--json")) return RANK.error;
|
|
47
|
+
if (argv.includes("--quiet") || argv.includes("-q")) return RANK.error;
|
|
48
|
+
if (argv.includes("--verbose") || argv.includes("-v")) return RANK.debug;
|
|
49
|
+
return RANK.info;
|
|
50
|
+
}
|
|
51
|
+
var isJson = process.argv.includes("--json");
|
|
52
|
+
var threshold = thresholdFrom(process.argv);
|
|
53
|
+
function emit(level, message) {
|
|
54
|
+
if (RANK[level] > threshold) return;
|
|
55
|
+
if (level === "error" || level === "warn") console.error(message);
|
|
56
|
+
else console.log(message);
|
|
57
|
+
}
|
|
58
|
+
var log = {
|
|
59
|
+
/** True when --json is set; commands emit a result object via `data` instead of prose. */
|
|
60
|
+
json: isJson,
|
|
61
|
+
error: (message) => emit("error", message),
|
|
62
|
+
warn: (message) => emit("warn", message),
|
|
63
|
+
info: (message) => emit("info", message),
|
|
64
|
+
debug: (message) => emit("debug", message),
|
|
65
|
+
/** Emit a structured result. Prints JSON only in --json mode; a no-op otherwise. */
|
|
66
|
+
data: (obj) => {
|
|
67
|
+
if (isJson) console.log(JSON.stringify(obj));
|
|
68
|
+
}
|
|
69
|
+
};
|
|
70
|
+
function buildRegistry() {
|
|
71
|
+
return new AdapterRegistry().register(claudeAdapter).register(codexAdapter).register(cursorAdapter).register(copilotAdapter).register(opencodeAdapter);
|
|
72
|
+
}
|
|
73
|
+
function allDrivers() {
|
|
74
|
+
return drivers;
|
|
75
|
+
}
|
|
76
|
+
function parseList(value) {
|
|
77
|
+
if (!value) return void 0;
|
|
78
|
+
const items = value.split(",").map((t) => t.trim()).filter(Boolean);
|
|
79
|
+
return items.length > 0 ? items : void 0;
|
|
80
|
+
}
|
|
81
|
+
function parseTargets(value) {
|
|
82
|
+
return parseList(value);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// src/report.ts
|
|
86
|
+
function formatDiagnostic(d) {
|
|
87
|
+
const tag = d.severity === "error" ? "error" : d.severity === "warning" ? "warn" : "info";
|
|
88
|
+
const where = d.where ? `${d.where}: ` : "";
|
|
89
|
+
return ` ${tag.padEnd(5)} ${where}${d.message}`;
|
|
90
|
+
}
|
|
91
|
+
function printDiagnostics(items) {
|
|
92
|
+
for (const d of items) {
|
|
93
|
+
const line = formatDiagnostic(d);
|
|
94
|
+
if (d.severity === "error") log.error(line);
|
|
95
|
+
else log.warn(line);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
function printTrustSummary(result) {
|
|
99
|
+
const { plugin } = result.fb;
|
|
100
|
+
const components = result.components;
|
|
101
|
+
log.info(`
|
|
102
|
+
Trust summary for ${result.id}@${plugin.version}`);
|
|
103
|
+
log.info(` publisher: ${plugin.owner.name} <${plugin.owner.namespace}> (unverified)`);
|
|
104
|
+
const counts = /* @__PURE__ */ new Map();
|
|
105
|
+
for (const c of components) counts.set(c.kind, (counts.get(c.kind) ?? 0) + 1);
|
|
106
|
+
const summary = [...counts.entries()].map(([k, n]) => `${n} ${k}`).join(", ");
|
|
107
|
+
log.info(` components: ${summary || "none"}`);
|
|
108
|
+
const executables = result.targets.flatMap(
|
|
109
|
+
(t) => t.artifacts.filter((p) => p.artifact.executable).map((p) => `${t.target}:${p.artifact.relPath}`)
|
|
110
|
+
);
|
|
111
|
+
log.info(
|
|
112
|
+
executables.length > 0 ? ` executables (placed DISABLED): ${executables.join(", ")}` : " executables: none"
|
|
113
|
+
);
|
|
114
|
+
log.info(` mcp servers that will run: ${counts.get("mcp") ?? 0}`);
|
|
115
|
+
log.info(" badges: valid (computed) | signed/verified/scanned: not yet\n");
|
|
116
|
+
}
|
|
117
|
+
function printEvalReport(report) {
|
|
118
|
+
log.data(report);
|
|
119
|
+
log.info(`
|
|
120
|
+
Eval: ${report.component}`);
|
|
121
|
+
for (const h of report.harnesses) {
|
|
122
|
+
if (h.status === "untested") {
|
|
123
|
+
log.info(` ${h.harness}: UNTESTED (${h.reason})`);
|
|
124
|
+
continue;
|
|
125
|
+
}
|
|
126
|
+
log.info(` ${h.harness}: ${h.pass ? "PASS" : "FAIL"}`);
|
|
127
|
+
for (const c of h.cases) {
|
|
128
|
+
log.info(` - ${c.name}: ${c.pass ? "pass" : "fail"}`);
|
|
129
|
+
for (const a of c.assertions) {
|
|
130
|
+
log.info(` ${a.kind}: ${a.status} (${a.detail})`);
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
function kebab(s) {
|
|
136
|
+
return s.toLowerCase().replace(/[^a-z0-9-]+/g, "-").replace(/^-+|-+$/g, "") || "my-plugin";
|
|
137
|
+
}
|
|
138
|
+
function scaffoldPlugin(opts) {
|
|
139
|
+
const dir = resolve$1(opts.dir);
|
|
140
|
+
mkdirSync(dir, { recursive: true });
|
|
141
|
+
const manifestPath = join(dir, "weft.yaml");
|
|
142
|
+
if (existsSync(manifestPath)) {
|
|
143
|
+
throw new Error(`a plugin already exists at ${manifestPath}`);
|
|
144
|
+
}
|
|
145
|
+
const name = kebab(opts.name ?? basename(dir));
|
|
146
|
+
const namespace = opts.namespace ?? "com.example";
|
|
147
|
+
const files = [];
|
|
148
|
+
const weftYaml = `name: ${name}
|
|
149
|
+
version: 0.1.0
|
|
150
|
+
owner:
|
|
151
|
+
name: Your Name
|
|
152
|
+
namespace: ${namespace}
|
|
153
|
+
description: A Weft plugin.
|
|
154
|
+
components:
|
|
155
|
+
- skill: skills/hello
|
|
156
|
+
`;
|
|
157
|
+
writeFileSync(manifestPath, weftYaml);
|
|
158
|
+
files.push(relative(dir, manifestPath));
|
|
159
|
+
const skillDir = join(dir, "skills", "hello");
|
|
160
|
+
mkdirSync(skillDir, { recursive: true });
|
|
161
|
+
const skillMd = `---
|
|
162
|
+
name: hello
|
|
163
|
+
description: Greet the user and explain what this skill does.
|
|
164
|
+
---
|
|
165
|
+
|
|
166
|
+
When invoked, greet the user warmly and summarize the task at hand.
|
|
167
|
+
`;
|
|
168
|
+
const skillPath = join(skillDir, "SKILL.md");
|
|
169
|
+
writeFileSync(skillPath, skillMd);
|
|
170
|
+
files.push(relative(dir, skillPath));
|
|
171
|
+
return { dir, name, files };
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
// src/index.ts
|
|
175
|
+
async function detectPresent(requested) {
|
|
176
|
+
const drivers2 = allDrivers();
|
|
177
|
+
const present = [];
|
|
178
|
+
const missing = [];
|
|
179
|
+
for (const t of requested) {
|
|
180
|
+
if (await drivers2[t]?.available()) present.push(t);
|
|
181
|
+
else missing.push(t);
|
|
182
|
+
}
|
|
183
|
+
return { present, missing };
|
|
184
|
+
}
|
|
185
|
+
function countByTarget(written) {
|
|
186
|
+
const counts = /* @__PURE__ */ new Map();
|
|
187
|
+
for (const w of written) counts.set(w.target, (counts.get(w.target) ?? 0) + 1);
|
|
188
|
+
return counts;
|
|
189
|
+
}
|
|
190
|
+
function fail(err) {
|
|
191
|
+
if (err instanceof CompileError) {
|
|
192
|
+
log.error(`
|
|
193
|
+
${err.message}:`);
|
|
194
|
+
printDiagnostics(err.diagnostics);
|
|
195
|
+
} else {
|
|
196
|
+
log.error(`
|
|
197
|
+
${err.message}`);
|
|
198
|
+
}
|
|
199
|
+
process.exit(1);
|
|
200
|
+
}
|
|
201
|
+
var initCmd = defineCommand({
|
|
202
|
+
meta: { name: "init", description: "Scaffold a new plugin (weft.yaml + a sample skill)" },
|
|
203
|
+
args: {
|
|
204
|
+
dir: { type: "positional", required: false, default: ".", description: "Target directory" },
|
|
205
|
+
name: { type: "string", description: "Plugin name (kebab-case)" },
|
|
206
|
+
namespace: { type: "string", description: "Reverse-DNS namespace, e.g. com.acme" }
|
|
207
|
+
},
|
|
208
|
+
run({ args }) {
|
|
209
|
+
const created = scaffoldPlugin({
|
|
210
|
+
dir: args.dir,
|
|
211
|
+
name: args.name,
|
|
212
|
+
namespace: args.namespace
|
|
213
|
+
});
|
|
214
|
+
log.info(`Scaffolded plugin "${created.name}" in ${created.dir}`);
|
|
215
|
+
for (const f of created.files) log.info(` + ${f}`);
|
|
216
|
+
log.info(`
|
|
217
|
+
Next: weft validate ${args.dir} && weft build ${args.dir}`);
|
|
218
|
+
}
|
|
219
|
+
});
|
|
220
|
+
var validateCmd = defineCommand({
|
|
221
|
+
meta: { name: "validate", description: "Statically validate a plugin (the valid badge)" },
|
|
222
|
+
args: {
|
|
223
|
+
dir: { type: "positional", required: false, default: ".", description: "Plugin directory" }
|
|
224
|
+
},
|
|
225
|
+
run({ args }) {
|
|
226
|
+
try {
|
|
227
|
+
const result = lint(args.dir);
|
|
228
|
+
const { items, hasErrors } = result.diagnostics;
|
|
229
|
+
if (items.length > 0) printDiagnostics(items);
|
|
230
|
+
if (hasErrors) {
|
|
231
|
+
log.error(`
|
|
232
|
+
${result.id}: invalid`);
|
|
233
|
+
process.exit(1);
|
|
234
|
+
}
|
|
235
|
+
log.data({ id: result.id, valid: true, components: result.plugin.components.length });
|
|
236
|
+
log.info(`${result.id}: valid (${result.plugin.components.length} components)`);
|
|
237
|
+
} catch (err) {
|
|
238
|
+
fail(err);
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
});
|
|
242
|
+
var buildCmd = defineCommand({
|
|
243
|
+
meta: {
|
|
244
|
+
name: "build",
|
|
245
|
+
description: "Compile a plugin (or a marketplace of plugins) to harness manifests"
|
|
246
|
+
},
|
|
247
|
+
args: {
|
|
248
|
+
dir: {
|
|
249
|
+
type: "positional",
|
|
250
|
+
required: false,
|
|
251
|
+
default: ".",
|
|
252
|
+
description: "Local dir, or a remote ref (github:/npm:/owner/repo, optional //subdir)"
|
|
253
|
+
},
|
|
254
|
+
out: { type: "string", default: ".weft-out", description: "Output directory" },
|
|
255
|
+
target: { type: "string", description: "Comma-separated targets (default: all registered)" }
|
|
256
|
+
},
|
|
257
|
+
async run({ args }) {
|
|
258
|
+
try {
|
|
259
|
+
const registry = buildRegistry();
|
|
260
|
+
const targets = parseTargets(args.target);
|
|
261
|
+
const { dir } = await resolveSourceDir(args.dir, process.cwd());
|
|
262
|
+
if (hasMarketplaceManifest(dir)) {
|
|
263
|
+
const { marketplace, plugins, written: written2 } = await buildMarketplace({
|
|
264
|
+
marketplaceDir: dir,
|
|
265
|
+
outDir: args.out,
|
|
266
|
+
registry,
|
|
267
|
+
targets
|
|
268
|
+
});
|
|
269
|
+
log.data({
|
|
270
|
+
marketplace: marketplace.name,
|
|
271
|
+
plugins: plugins.length,
|
|
272
|
+
out: args.out,
|
|
273
|
+
files: Object.fromEntries(countByTarget(written2))
|
|
274
|
+
});
|
|
275
|
+
log.info(
|
|
276
|
+
`Built marketplace ${marketplace.name} (${plugins.length} plugins) -> ${args.out}/`
|
|
277
|
+
);
|
|
278
|
+
for (const [t, n] of countByTarget(written2)) log.info(` ${t}: ${n} files`);
|
|
279
|
+
return;
|
|
280
|
+
}
|
|
281
|
+
const { result, written } = await build({
|
|
282
|
+
pluginDir: dir,
|
|
283
|
+
outDir: args.out,
|
|
284
|
+
registry,
|
|
285
|
+
targets
|
|
286
|
+
});
|
|
287
|
+
if (result.diagnostics.items.length > 0) printDiagnostics(result.diagnostics.items);
|
|
288
|
+
log.data({ id: result.id, out: args.out, files: Object.fromEntries(countByTarget(written)) });
|
|
289
|
+
log.info(`Built ${result.id} -> ${args.out}/`);
|
|
290
|
+
for (const [t, n] of countByTarget(written)) {
|
|
291
|
+
log.info(` ${t}: ${n} files (catalog at ${args.out}/${t})`);
|
|
292
|
+
}
|
|
293
|
+
} catch (err) {
|
|
294
|
+
fail(err);
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
});
|
|
298
|
+
var installCmd = defineCommand({
|
|
299
|
+
meta: {
|
|
300
|
+
name: "install",
|
|
301
|
+
description: "Compile + place a plugin (or a whole marketplace) into harness scopes"
|
|
302
|
+
},
|
|
303
|
+
args: {
|
|
304
|
+
dir: {
|
|
305
|
+
type: "positional",
|
|
306
|
+
required: false,
|
|
307
|
+
default: ".",
|
|
308
|
+
description: "Local dir, or a remote ref (github:/npm:/owner/repo, optional //subdir)"
|
|
309
|
+
},
|
|
310
|
+
scope: { type: "string", default: "project", description: "user | project" },
|
|
311
|
+
target: { type: "string", description: "Comma-separated targets (default: all registered)" },
|
|
312
|
+
only: {
|
|
313
|
+
type: "string",
|
|
314
|
+
description: "Comma-separated component names to install piecemeal (e.g. one skill)"
|
|
315
|
+
},
|
|
316
|
+
all: {
|
|
317
|
+
type: "boolean",
|
|
318
|
+
description: "Install to requested targets even if the harness is not detected"
|
|
319
|
+
},
|
|
320
|
+
managed: {
|
|
321
|
+
type: "string",
|
|
322
|
+
description: "Managed mode: only allow these namespaces (comma-separated allowlist)"
|
|
323
|
+
},
|
|
324
|
+
cwd: { type: "string", description: "Project root for project-scope placement (default: cwd)" }
|
|
325
|
+
},
|
|
326
|
+
async run({ args }) {
|
|
327
|
+
try {
|
|
328
|
+
const registry = buildRegistry();
|
|
329
|
+
const scope = args.scope === "user" ? "user" : "project";
|
|
330
|
+
const requested = parseTargets(args.target) ?? registry.targets;
|
|
331
|
+
const allow = parseList(args.managed);
|
|
332
|
+
let targets = requested;
|
|
333
|
+
if (!args.all) {
|
|
334
|
+
const { present, missing } = await detectPresent(requested);
|
|
335
|
+
for (const t of missing) log.info(` skipped ${t}: harness not detected`);
|
|
336
|
+
if (present.length === 0) {
|
|
337
|
+
log.error("No requested harness is installed. Use --all to place anyway.");
|
|
338
|
+
process.exit(1);
|
|
339
|
+
}
|
|
340
|
+
targets = present;
|
|
341
|
+
}
|
|
342
|
+
const { dir } = await resolveSourceDir(args.dir, process.cwd());
|
|
343
|
+
if (hasMarketplaceManifest(dir)) {
|
|
344
|
+
const mp = await installMarketplace({
|
|
345
|
+
marketplaceDir: dir,
|
|
346
|
+
scope,
|
|
347
|
+
cwd: args.cwd ?? process.cwd(),
|
|
348
|
+
registry,
|
|
349
|
+
targets,
|
|
350
|
+
...allow ? { managed: { allowNamespaces: allow } } : {}
|
|
351
|
+
});
|
|
352
|
+
log.data({
|
|
353
|
+
marketplace: mp.marketplace.name,
|
|
354
|
+
plugins: mp.installs.map((i) => i.result.id),
|
|
355
|
+
scope,
|
|
356
|
+
lockfile: mp.lockPath
|
|
357
|
+
});
|
|
358
|
+
log.info(
|
|
359
|
+
`Installed marketplace ${mp.marketplace.name} (${mp.installs.length} plugins, ${scope})`
|
|
360
|
+
);
|
|
361
|
+
for (const i of mp.installs) {
|
|
362
|
+
log.info(
|
|
363
|
+
` ${i.result.id}@${i.result.fb.plugin.version}: ${i.entry.artifacts.length} artifacts`
|
|
364
|
+
);
|
|
365
|
+
}
|
|
366
|
+
log.info(` lockfile: ${mp.lockPath}`);
|
|
367
|
+
return;
|
|
368
|
+
}
|
|
369
|
+
const result = await install({
|
|
370
|
+
pluginDir: dir,
|
|
371
|
+
scope,
|
|
372
|
+
cwd: args.cwd ?? process.cwd(),
|
|
373
|
+
registry,
|
|
374
|
+
targets,
|
|
375
|
+
only: parseList(args.only),
|
|
376
|
+
...allow ? { managed: { allowNamespaces: allow } } : {}
|
|
377
|
+
});
|
|
378
|
+
printTrustSummary(result.result);
|
|
379
|
+
log.data({
|
|
380
|
+
id: result.result.id,
|
|
381
|
+
version: result.result.fb.plugin.version,
|
|
382
|
+
scope,
|
|
383
|
+
artifacts: result.entry.artifacts.length,
|
|
384
|
+
lockfile: result.lockPath
|
|
385
|
+
});
|
|
386
|
+
log.info(`Installed ${result.result.id}@${result.result.fb.plugin.version} (${scope})`);
|
|
387
|
+
log.info(` ${result.entry.artifacts.length} artifacts placed`);
|
|
388
|
+
if (result.secrets.resolved.length > 0) {
|
|
389
|
+
const missing = result.secrets.resolved.filter((r) => r.source === "missing");
|
|
390
|
+
log.info(
|
|
391
|
+
` config: ${result.secrets.resolved.length} declared` + (result.secrets.path ? ` -> ${result.secrets.path} (gitignored)` : "") + (missing.length > 0 ? `; missing: ${missing.map((m) => m.env).join(", ")}` : "")
|
|
392
|
+
);
|
|
393
|
+
}
|
|
394
|
+
log.info(` lockfile: ${result.lockPath}`);
|
|
395
|
+
} catch (err) {
|
|
396
|
+
fail(err);
|
|
397
|
+
}
|
|
398
|
+
}
|
|
399
|
+
});
|
|
400
|
+
var updateCmd = defineCommand({
|
|
401
|
+
meta: {
|
|
402
|
+
name: "update",
|
|
403
|
+
description: "Re-resolve refs, recompile, and re-place only artifacts whose hash changed"
|
|
404
|
+
},
|
|
405
|
+
args: {
|
|
406
|
+
dir: { type: "positional", required: false, default: ".", description: "Plugin directory" },
|
|
407
|
+
scope: { type: "string", default: "project", description: "user | project" },
|
|
408
|
+
target: { type: "string", description: "Comma-separated targets (default: all registered)" },
|
|
409
|
+
cwd: { type: "string", description: "Project root for project-scope placement (default: cwd)" }
|
|
410
|
+
},
|
|
411
|
+
async run({ args }) {
|
|
412
|
+
try {
|
|
413
|
+
const scope = args.scope === "user" ? "user" : "project";
|
|
414
|
+
const cwd = args.cwd ?? process.cwd();
|
|
415
|
+
const lock = readLock(lockDirForScope(scope, cwd));
|
|
416
|
+
const lockedTargets = lock ? [...new Set(lock.artifacts.map((a) => a.target))] : void 0;
|
|
417
|
+
const result = await update({
|
|
418
|
+
pluginDir: args.dir,
|
|
419
|
+
scope,
|
|
420
|
+
cwd,
|
|
421
|
+
registry: buildRegistry(),
|
|
422
|
+
targets: parseTargets(args.target) ?? lockedTargets
|
|
423
|
+
});
|
|
424
|
+
log.data({ id: result.id, changed: result.changed });
|
|
425
|
+
log.info(`Updated ${result.id}: ${result.changed.length} artifact(s) changed`);
|
|
426
|
+
for (const p of result.changed) log.info(` ~ ${p}`);
|
|
427
|
+
} catch (err) {
|
|
428
|
+
fail(err);
|
|
429
|
+
}
|
|
430
|
+
}
|
|
431
|
+
});
|
|
432
|
+
var evalCmd = defineCommand({
|
|
433
|
+
meta: {
|
|
434
|
+
name: "eval",
|
|
435
|
+
description: "Run a component's evals against the real harnesses (reports UNTESTED honestly)"
|
|
436
|
+
},
|
|
437
|
+
args: {
|
|
438
|
+
dir: { type: "positional", required: false, default: ".", description: "Plugin directory" },
|
|
439
|
+
component: { type: "string", description: "Only eval this component leaf name" },
|
|
440
|
+
harness: { type: "string", description: "Restrict to these harnesses (comma-separated)" }
|
|
441
|
+
},
|
|
442
|
+
async run({ args }) {
|
|
443
|
+
try {
|
|
444
|
+
const registry = buildRegistry();
|
|
445
|
+
const drivers2 = allDrivers();
|
|
446
|
+
const discovered = discoverEvals(args.dir).filter(
|
|
447
|
+
(d) => !args.component || d.componentLeaf === args.component
|
|
448
|
+
);
|
|
449
|
+
if (discovered.length === 0) {
|
|
450
|
+
log.info("No evals found (a component adds them with an `evals:` file).");
|
|
451
|
+
return;
|
|
452
|
+
}
|
|
453
|
+
const onlyHarness = parseTargets(args.harness);
|
|
454
|
+
let anyFail = false;
|
|
455
|
+
for (const d of discovered) {
|
|
456
|
+
const evalFile = onlyHarness ? {
|
|
457
|
+
...d.evalFile,
|
|
458
|
+
harnesses: d.evalFile.harnesses.filter((h) => onlyHarness.includes(h))
|
|
459
|
+
} : d.evalFile;
|
|
460
|
+
const report = await runEval({
|
|
461
|
+
evalFile,
|
|
462
|
+
pluginDir: args.dir,
|
|
463
|
+
componentLeaf: d.componentLeaf,
|
|
464
|
+
registry,
|
|
465
|
+
drivers: drivers2
|
|
466
|
+
});
|
|
467
|
+
printEvalReport(report);
|
|
468
|
+
if (report.harnesses.some((h) => h.status === "tested" && !h.pass)) anyFail = true;
|
|
469
|
+
}
|
|
470
|
+
if (anyFail) process.exit(1);
|
|
471
|
+
} catch (err) {
|
|
472
|
+
fail(err);
|
|
473
|
+
}
|
|
474
|
+
}
|
|
475
|
+
});
|
|
476
|
+
var publishCmd = defineCommand({
|
|
477
|
+
meta: {
|
|
478
|
+
name: "publish",
|
|
479
|
+
description: "Run the deterministic publish gate (static valid + trace/output evals)"
|
|
480
|
+
},
|
|
481
|
+
args: {
|
|
482
|
+
dir: { type: "positional", required: false, default: ".", description: "Plugin directory" },
|
|
483
|
+
snapshot: {
|
|
484
|
+
type: "boolean",
|
|
485
|
+
description: "Snapshot eval scores into evals/.baselines/ for the next release"
|
|
486
|
+
}
|
|
487
|
+
},
|
|
488
|
+
async run({ args }) {
|
|
489
|
+
try {
|
|
490
|
+
const res = await publishCheck(args.dir, {
|
|
491
|
+
registry: buildRegistry(),
|
|
492
|
+
drivers: allDrivers(),
|
|
493
|
+
snapshot: Boolean(args.snapshot)
|
|
494
|
+
});
|
|
495
|
+
log.data({
|
|
496
|
+
id: res.id,
|
|
497
|
+
version: res.version,
|
|
498
|
+
ok: res.ok,
|
|
499
|
+
valid: res.validPassed,
|
|
500
|
+
scanClean: res.scan.clean,
|
|
501
|
+
badges: res.badges,
|
|
502
|
+
harnessCoverage: res.harnessCoverage
|
|
503
|
+
});
|
|
504
|
+
log.info(`Publish check: ${res.id}@${res.version}`);
|
|
505
|
+
if (res.diagnostics.length > 0) printDiagnostics(res.diagnostics);
|
|
506
|
+
log.info(` valid: ${res.validPassed ? "yes" : "NO"}`);
|
|
507
|
+
log.info(` scan: ${res.scan.clean ? "clean" : `${res.scan.findings.length} finding(s)`}`);
|
|
508
|
+
log.info(` badges: ${res.badges.join(", ") || "none"}`);
|
|
509
|
+
log.info(` harness coverage: ${res.harnessCoverage.join(", ") || "none"}`);
|
|
510
|
+
for (const r of res.evalReports) printEvalReport(r);
|
|
511
|
+
if (!res.ok) {
|
|
512
|
+
log.error("\nPublish BLOCKED: the deterministic tier failed.");
|
|
513
|
+
process.exit(1);
|
|
514
|
+
}
|
|
515
|
+
log.info("\nPublish gate passed.");
|
|
516
|
+
} catch (err) {
|
|
517
|
+
fail(err);
|
|
518
|
+
}
|
|
519
|
+
}
|
|
520
|
+
});
|
|
521
|
+
var signCmd = defineCommand({
|
|
522
|
+
meta: {
|
|
523
|
+
name: "sign",
|
|
524
|
+
description: "Sign weft.lock's artifact set (ed25519) -> weft.sig + weft.pub (the signed badge)"
|
|
525
|
+
},
|
|
526
|
+
args: {
|
|
527
|
+
dir: {
|
|
528
|
+
type: "positional",
|
|
529
|
+
required: false,
|
|
530
|
+
default: ".",
|
|
531
|
+
description: "Plugin dir with weft.lock"
|
|
532
|
+
}
|
|
533
|
+
},
|
|
534
|
+
run({ args }) {
|
|
535
|
+
try {
|
|
536
|
+
const lock = readLock(args.dir);
|
|
537
|
+
if (!lock) {
|
|
538
|
+
log.error("no weft.lock found (run `weft install` first)");
|
|
539
|
+
process.exit(1);
|
|
540
|
+
}
|
|
541
|
+
const weftDir = join(args.dir, ".weft");
|
|
542
|
+
mkdirSync(weftDir, { recursive: true });
|
|
543
|
+
writeFileSync(join(weftDir, ".gitignore"), "*\n");
|
|
544
|
+
const keyPath = join(weftDir, "signing.key");
|
|
545
|
+
let privateKey;
|
|
546
|
+
if (existsSync(keyPath)) {
|
|
547
|
+
privateKey = createPrivateKey(readFileSync(keyPath));
|
|
548
|
+
} else {
|
|
549
|
+
const keys = generateSigningKeys();
|
|
550
|
+
privateKey = keys.privateKey;
|
|
551
|
+
writeFileSync(keyPath, keys.privateKey.export({ type: "pkcs8", format: "pem" }));
|
|
552
|
+
writeFileSync(
|
|
553
|
+
join(args.dir, "weft.pub"),
|
|
554
|
+
keys.publicKey.export({ type: "spki", format: "pem" })
|
|
555
|
+
);
|
|
556
|
+
}
|
|
557
|
+
writeFileSync(join(args.dir, "weft.sig"), `${signLock(lock, privateKey)}
|
|
558
|
+
`);
|
|
559
|
+
log.info(
|
|
560
|
+
`Signed ${lock.artifacts.length} artifacts -> weft.sig (key kept in .weft/, public key in weft.pub)`
|
|
561
|
+
);
|
|
562
|
+
} catch (err) {
|
|
563
|
+
fail(err);
|
|
564
|
+
}
|
|
565
|
+
}
|
|
566
|
+
});
|
|
567
|
+
var verifyCmd = defineCommand({
|
|
568
|
+
meta: {
|
|
569
|
+
name: "verify",
|
|
570
|
+
description: "Verify weft.sig against weft.lock and the on-disk artifacts"
|
|
571
|
+
},
|
|
572
|
+
args: {
|
|
573
|
+
dir: {
|
|
574
|
+
type: "positional",
|
|
575
|
+
required: false,
|
|
576
|
+
default: ".",
|
|
577
|
+
description: "Plugin dir with weft.lock"
|
|
578
|
+
}
|
|
579
|
+
},
|
|
580
|
+
run({ args }) {
|
|
581
|
+
try {
|
|
582
|
+
const lock = readLock(args.dir);
|
|
583
|
+
if (!lock) {
|
|
584
|
+
log.error("no weft.lock found");
|
|
585
|
+
process.exit(1);
|
|
586
|
+
}
|
|
587
|
+
const sig = readFileSync(join(args.dir, "weft.sig"), "utf8").trim();
|
|
588
|
+
const publicKey = createPublicKey(readFileSync(join(args.dir, "weft.pub")));
|
|
589
|
+
const res = verifyArtifacts(lock, publicKey, sig);
|
|
590
|
+
log.data({ signatureValid: res.signatureValid, tampered: res.tampered });
|
|
591
|
+
log.info(`signature: ${res.signatureValid ? "valid" : "INVALID"}`);
|
|
592
|
+
log.info(`tampered artifacts: ${res.tampered.length}`);
|
|
593
|
+
for (const p of res.tampered) log.info(` ! ${p}`);
|
|
594
|
+
if (!res.signatureValid || res.tampered.length > 0) process.exit(1);
|
|
595
|
+
log.info("signed badge verified.");
|
|
596
|
+
} catch (err) {
|
|
597
|
+
fail(err);
|
|
598
|
+
}
|
|
599
|
+
}
|
|
600
|
+
});
|
|
601
|
+
var indexCmd = defineCommand({
|
|
602
|
+
meta: {
|
|
603
|
+
name: "index",
|
|
604
|
+
description: "Build a metadata index from plugin dirs (optionally federating the MCP Registry)"
|
|
605
|
+
},
|
|
606
|
+
args: {
|
|
607
|
+
dir: { type: "positional", required: false, default: ".", description: "Plugin directories" },
|
|
608
|
+
out: { type: "string", default: "index.json", description: "Output index file" },
|
|
609
|
+
federate: { type: "boolean", description: "Ingest the MCP Registry (GET /v0.1/servers)" }
|
|
610
|
+
},
|
|
611
|
+
async run({ args }) {
|
|
612
|
+
try {
|
|
613
|
+
const positionals = args._ ?? [];
|
|
614
|
+
const dirs = positionals.length > 0 ? positionals : ["."];
|
|
615
|
+
let index = await indexFromPluginDirs(dirs);
|
|
616
|
+
if (args.federate) {
|
|
617
|
+
const servers = await fetchMcpRegistry({ limit: 30 });
|
|
618
|
+
index = federate(index, servers, (/* @__PURE__ */ new Date()).toISOString());
|
|
619
|
+
}
|
|
620
|
+
writeFileSync(args.out, serializeIndex(index));
|
|
621
|
+
const fed = args.federate ? `, federated ${index.federated?.length ?? 0} source(s)` : "";
|
|
622
|
+
log.data({
|
|
623
|
+
plugins: index.plugins.length,
|
|
624
|
+
federated: index.federated?.length ?? 0,
|
|
625
|
+
out: args.out
|
|
626
|
+
});
|
|
627
|
+
log.info(`Wrote index (${index.plugins.length} plugins${fed}) -> ${args.out}`);
|
|
628
|
+
} catch (err) {
|
|
629
|
+
fail(err);
|
|
630
|
+
}
|
|
631
|
+
}
|
|
632
|
+
});
|
|
633
|
+
var importCmd = defineCommand({
|
|
634
|
+
meta: {
|
|
635
|
+
name: "import",
|
|
636
|
+
description: "Reverse-compile an existing native plugin/marketplace into a Weft plugin"
|
|
637
|
+
},
|
|
638
|
+
args: {
|
|
639
|
+
dir: {
|
|
640
|
+
type: "positional",
|
|
641
|
+
required: false,
|
|
642
|
+
default: ".",
|
|
643
|
+
description: "Dir with an existing native plugin or marketplace"
|
|
644
|
+
},
|
|
645
|
+
from: { type: "string", default: "claude", description: "Source harness format" },
|
|
646
|
+
out: { type: "string", default: "imported", description: "Output directory" },
|
|
647
|
+
namespace: {
|
|
648
|
+
type: "string",
|
|
649
|
+
description: "Reverse-DNS namespace to assign (default com.imported)"
|
|
650
|
+
}
|
|
651
|
+
},
|
|
652
|
+
run({ args }) {
|
|
653
|
+
try {
|
|
654
|
+
const adapter = buildRegistry().get(args.from);
|
|
655
|
+
if (!adapter) {
|
|
656
|
+
log.error(`unknown source harness "${args.from}"`);
|
|
657
|
+
process.exit(1);
|
|
658
|
+
}
|
|
659
|
+
const res = importNativePlugin({
|
|
660
|
+
dir: args.dir,
|
|
661
|
+
adapter,
|
|
662
|
+
outDir: args.out,
|
|
663
|
+
...args.namespace ? { namespace: args.namespace } : {}
|
|
664
|
+
});
|
|
665
|
+
log.data({
|
|
666
|
+
kind: res.kind,
|
|
667
|
+
name: res.name,
|
|
668
|
+
manifest: res.manifestPath,
|
|
669
|
+
out: res.outDir,
|
|
670
|
+
...res.kind === "plugin" ? { files: res.fileCount } : {}
|
|
671
|
+
});
|
|
672
|
+
log.info(`Imported ${res.kind} "${res.name}" -> ${res.manifestPath}`);
|
|
673
|
+
if (res.kind === "plugin") log.info(` ${res.fileCount} component file(s)`);
|
|
674
|
+
log.info(` next: weft build ${res.outDir}`);
|
|
675
|
+
} catch (err) {
|
|
676
|
+
fail(err);
|
|
677
|
+
}
|
|
678
|
+
}
|
|
679
|
+
});
|
|
680
|
+
var uninstallCmd = defineCommand({
|
|
681
|
+
meta: {
|
|
682
|
+
name: "uninstall",
|
|
683
|
+
description: "Remove what install placed into this project (read from its weft.lock)"
|
|
684
|
+
},
|
|
685
|
+
args: {
|
|
686
|
+
dir: {
|
|
687
|
+
type: "positional",
|
|
688
|
+
required: false,
|
|
689
|
+
default: ".",
|
|
690
|
+
description: "Install target holding weft.lock (default: derived from --scope)"
|
|
691
|
+
},
|
|
692
|
+
scope: { type: "string", default: "project", description: "user | project" },
|
|
693
|
+
plugin: {
|
|
694
|
+
type: "string",
|
|
695
|
+
description: "Remove only this plugin (id or bare name); default removes all"
|
|
696
|
+
}
|
|
697
|
+
},
|
|
698
|
+
run({ args }) {
|
|
699
|
+
try {
|
|
700
|
+
const scope = args.scope === "user" ? "user" : "project";
|
|
701
|
+
const dir = args.dir === "." ? lockDirForScope(scope, process.cwd()) : args.dir;
|
|
702
|
+
const res = uninstall({ dir, ...args.plugin ? { plugin: args.plugin } : {} });
|
|
703
|
+
log.data({ removed: res.removed, plugins: res.plugins });
|
|
704
|
+
log.info(`Uninstalled ${res.plugins.length} plugin(s), ${res.removed.length} artifact(s)`);
|
|
705
|
+
} catch (err) {
|
|
706
|
+
fail(err);
|
|
707
|
+
}
|
|
708
|
+
}
|
|
709
|
+
});
|
|
710
|
+
var docsCmd = defineCommand({
|
|
711
|
+
meta: {
|
|
712
|
+
name: "docs",
|
|
713
|
+
description: "Print the full CLI reference (a CLI map), generated from the command tree"
|
|
714
|
+
},
|
|
715
|
+
args: {
|
|
716
|
+
out: {
|
|
717
|
+
type: "string",
|
|
718
|
+
description: "Write the Markdown reference to this file instead of stdout"
|
|
719
|
+
}
|
|
720
|
+
},
|
|
721
|
+
async run({ args }) {
|
|
722
|
+
const md = await renderCliReference(main);
|
|
723
|
+
if (args.out) {
|
|
724
|
+
writeFileSync(args.out, md);
|
|
725
|
+
log.info(`Wrote CLI reference to ${args.out}`);
|
|
726
|
+
} else {
|
|
727
|
+
process.stdout.write(md);
|
|
728
|
+
}
|
|
729
|
+
}
|
|
730
|
+
});
|
|
731
|
+
var main = defineCommand({
|
|
732
|
+
meta: {
|
|
733
|
+
name: "weft",
|
|
734
|
+
version: WEFT_VERSION,
|
|
735
|
+
description: "Author once, compile to every coding-agent harness."
|
|
736
|
+
},
|
|
737
|
+
subCommands: {
|
|
738
|
+
init: initCmd,
|
|
739
|
+
validate: validateCmd,
|
|
740
|
+
build: buildCmd,
|
|
741
|
+
install: installCmd,
|
|
742
|
+
uninstall: uninstallCmd,
|
|
743
|
+
update: updateCmd,
|
|
744
|
+
import: importCmd,
|
|
745
|
+
eval: evalCmd,
|
|
746
|
+
publish: publishCmd,
|
|
747
|
+
sign: signCmd,
|
|
748
|
+
verify: verifyCmd,
|
|
749
|
+
index: indexCmd,
|
|
750
|
+
docs: docsCmd
|
|
751
|
+
}
|
|
752
|
+
});
|
|
753
|
+
runMain(main);
|
|
754
|
+
//# sourceMappingURL=index.js.map
|
|
755
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/cli-docs.ts","../src/logger.ts","../src/registry.ts","../src/report.ts","../src/scaffold.ts","../src/index.ts"],"names":["main","resolve","drivers","written","join","mkdirSync","writeFileSync","existsSync"],"mappings":";;;;;;;;;;;;;;AAIA,eAAe,QAAW,CAAA,EAA8B;AACtD,EAAA,OAAO,OAAO,CAAA,KAAM,UAAA,GAAa,MAAO,GAA2B,GAAI,CAAA;AACzE;AAOA,eAAsB,mBAAmBA,KAAAA,EAAmC;AAC1E,EAAA,MAAM,GAAA,GAAgB;AAAA,IACpB,sBAAA;AAAA,IACA,EAAA;AAAA,IACA,4EAAA;AAAA,IACA,EAAA;AAAA,IACA,WAAA;AAAA,IACA,EAAA;AAAA,IACA,KAAA;AAAA,IAAA,CACC,MAAM,WAAA,CAAYA,KAAI,CAAA,EAAG,IAAA,EAAK;AAAA,IAC/B,KAAA;AAAA,IACA;AAAA,GACF;AAEA,EAAA,MAAM,IAAA,GAAOA,MAAK,WAAA,GAAc,MAAM,QAAQA,KAAAA,CAAK,WAAW,IAAI,EAAC;AACnE,EAAA,KAAA,MAAW,QAAQ,MAAA,CAAO,IAAA,CAAK,IAAI,CAAA,CAAE,MAAK,EAAG;AAC3C,IAAA,MAAM,GAAA,GAAM,MAAM,OAAA,CAAQ,IAAA,CAAK,IAAI,CAA2B,CAAA;AAC9D,IAAA,MAAM,IAAA,GAAO,MAAM,OAAA,CAAQ,GAAA,CAAI,IAAI,CAAA;AACnC,IAAA,GAAA,CAAI,IAAA,CAAK,CAAA,UAAA,EAAa,IAAI,CAAA,EAAA,CAAA,EAAM,EAAE,CAAA;AAClC,IAAA,IAAI,MAAM,WAAA,EAAa,GAAA,CAAI,IAAA,CAAK,IAAA,CAAK,aAAuB,EAAE,CAAA;AAC9D,IAAA,GAAA,CAAI,IAAA,CAAK,KAAA,EAAA,CAAQ,MAAM,WAAA,CAAY,GAAA,EAAKA,KAAI,CAAA,EAAG,IAAA,EAAK,EAAG,KAAA,EAAO,EAAE,CAAA;AAAA,EAClE;AAEA,EAAA,OAAO,CAAA,EAAG,GAAA,CAAI,IAAA,CAAK,IAAI,CAAC;AAAA,CAAA;AAC1B;;;AC7BA,IAAM,IAAA,GAA8B,EAAE,KAAA,EAAO,CAAA,EAAG,MAAM,CAAA,EAAG,IAAA,EAAM,CAAA,EAAG,KAAA,EAAO,CAAA,EAAE;AAE3E,SAAS,cAAc,IAAA,EAAwB;AAC7C,EAAA,IAAI,IAAA,CAAK,QAAA,CAAS,QAAQ,CAAA,SAAU,IAAA,CAAK,KAAA;AACzC,EAAA,IAAI,IAAA,CAAK,SAAS,SAAS,CAAA,IAAK,KAAK,QAAA,CAAS,IAAI,CAAA,EAAG,OAAO,IAAA,CAAK,KAAA;AACjE,EAAA,IAAI,IAAA,CAAK,SAAS,WAAW,CAAA,IAAK,KAAK,QAAA,CAAS,IAAI,CAAA,EAAG,OAAO,IAAA,CAAK,KAAA;AACnE,EAAA,OAAO,IAAA,CAAK,IAAA;AACd;AAEA,IAAM,MAAA,GAAS,OAAA,CAAQ,IAAA,CAAK,QAAA,CAAS,QAAQ,CAAA;AAC7C,IAAM,SAAA,GAAY,aAAA,CAAc,OAAA,CAAQ,IAAI,CAAA;AAE5C,SAAS,IAAA,CAAK,OAAc,OAAA,EAAuB;AACjD,EAAA,IAAI,IAAA,CAAK,KAAK,CAAA,GAAI,SAAA,EAAW;AAE7B,EAAA,IAAI,UAAU,OAAA,IAAW,KAAA,KAAU,MAAA,EAAQ,OAAA,CAAQ,MAAM,OAAO,CAAA;AAAA,OAE3D,OAAA,CAAQ,IAAI,OAAO,CAAA;AAC1B;AAEO,IAAM,GAAA,GAAM;AAAA;AAAA,EAEjB,IAAA,EAAM,MAAA;AAAA,EACN,KAAA,EAAO,CAAC,OAAA,KAA0B,IAAA,CAAK,SAAS,OAAO,CAAA;AAAA,EACvD,IAAA,EAAM,CAAC,OAAA,KAA0B,IAAA,CAAK,QAAQ,OAAO,CAAA;AAAA,EACrD,IAAA,EAAM,CAAC,OAAA,KAA0B,IAAA,CAAK,QAAQ,OAAO,CAAA;AAAA,EACrD,KAAA,EAAO,CAAC,OAAA,KAA0B,IAAA,CAAK,SAAS,OAAO,CAAA;AAAA;AAAA,EAEvD,IAAA,EAAM,CAAC,GAAA,KAAuB;AAE5B,IAAA,IAAI,QAAQ,OAAA,CAAQ,GAAA,CAAI,IAAA,CAAK,SAAA,CAAU,GAAG,CAAC,CAAA;AAAA,EAC7C;AACF,CAAA;ACzBO,SAAS,aAAA,GAAiC;AAC/C,EAAA,OAAO,IAAI,eAAA,EAAgB,CACxB,QAAA,CAAS,aAAa,EACtB,QAAA,CAAS,YAAY,CAAA,CACrB,QAAA,CAAS,aAAa,CAAA,CACtB,QAAA,CAAS,cAAc,CAAA,CACvB,SAAS,eAAe,CAAA;AAC7B;AAGO,SAAS,UAAA,GAA4C;AAC1D,EAAA,OAAO,OAAA;AACT;AAGO,SAAS,UAAU,KAAA,EAAiD;AACzE,EAAA,IAAI,CAAC,OAAO,OAAO,MAAA;AACnB,EAAA,MAAM,KAAA,GAAQ,KAAA,CACX,KAAA,CAAM,GAAG,CAAA,CACT,GAAA,CAAI,CAAC,CAAA,KAAM,CAAA,CAAE,IAAA,EAAM,CAAA,CACnB,OAAO,OAAO,CAAA;AACjB,EAAA,OAAO,KAAA,CAAM,MAAA,GAAS,CAAA,GAAI,KAAA,GAAQ,MAAA;AACpC;AAGO,SAAS,aAAa,KAAA,EAAiD;AAC5E,EAAA,OAAO,UAAU,KAAK,CAAA;AACxB;;;ACtCO,SAAS,iBAAiB,CAAA,EAAuB;AACtD,EAAA,MAAM,GAAA,GAAM,EAAE,QAAA,KAAa,OAAA,GAAU,UAAU,CAAA,CAAE,QAAA,KAAa,YAAY,MAAA,GAAS,MAAA;AACnF,EAAA,MAAM,QAAQ,CAAA,CAAE,KAAA,GAAQ,CAAA,EAAG,CAAA,CAAE,KAAK,CAAA,EAAA,CAAA,GAAO,EAAA;AACzC,EAAA,OAAO,CAAA,EAAA,EAAK,IAAI,MAAA,CAAO,CAAC,CAAC,CAAA,CAAA,EAAI,KAAK,CAAA,EAAG,CAAA,CAAE,OAAO,CAAA,CAAA;AAChD;AAEO,SAAS,iBAAiB,KAAA,EAA2B;AAC1D,EAAA,KAAA,MAAW,KAAK,KAAA,EAAO;AACrB,IAAA,MAAM,IAAA,GAAO,iBAAiB,CAAC,CAAA;AAC/B,IAAA,IAAI,CAAA,CAAE,QAAA,KAAa,OAAA,EAAS,GAAA,CAAI,MAAM,IAAI,CAAA;AAAA,SACrC,GAAA,CAAI,KAAK,IAAI,CAAA;AAAA,EACpB;AACF;AAOO,SAAS,kBAAkB,MAAA,EAA6B;AAC7D,EAAA,MAAM,EAAE,MAAA,EAAO,GAAI,MAAA,CAAO,EAAA;AAE1B,EAAA,MAAM,aAAa,MAAA,CAAO,UAAA;AAC1B,EAAA,GAAA,CAAI,IAAA,CAAK;AAAA,kBAAA,EAAuB,MAAA,CAAO,EAAE,CAAA,CAAA,EAAI,MAAA,CAAO,OAAO,CAAA,CAAE,CAAA;AAC7D,EAAA,GAAA,CAAI,IAAA,CAAK,gBAAgB,MAAA,CAAO,KAAA,CAAM,IAAI,CAAA,EAAA,EAAK,MAAA,CAAO,KAAA,CAAM,SAAS,CAAA,cAAA,CAAgB,CAAA;AAErF,EAAA,MAAM,MAAA,uBAAa,GAAA,EAAoB;AACvC,EAAA,KAAA,MAAW,CAAA,IAAK,UAAA,EAAY,MAAA,CAAO,GAAA,CAAI,CAAA,CAAE,IAAA,EAAA,CAAO,MAAA,CAAO,GAAA,CAAI,CAAA,CAAE,IAAI,CAAA,IAAK,CAAA,IAAK,CAAC,CAAA;AAC5E,EAAA,MAAM,OAAA,GAAU,CAAC,GAAG,MAAA,CAAO,SAAS,CAAA,CAAE,IAAI,CAAC,CAAC,GAAG,CAAC,CAAA,KAAM,GAAG,CAAC,CAAA,CAAA,EAAI,CAAC,CAAA,CAAE,CAAA,CAAE,KAAK,IAAI,CAAA;AAC5E,EAAA,GAAA,CAAI,IAAA,CAAK,CAAA,cAAA,EAAiB,OAAA,IAAW,MAAM,CAAA,CAAE,CAAA;AAE7C,EAAA,MAAM,WAAA,GAAc,OAAO,OAAA,CAAQ,OAAA;AAAA,IAAQ,CAAC,MAC1C,CAAA,CAAE,SAAA,CACC,OAAO,CAAC,CAAA,KAAM,EAAE,QAAA,CAAS,UAAU,EACnC,GAAA,CAAI,CAAC,MAAM,CAAA,EAAG,CAAA,CAAE,MAAM,CAAA,CAAA,EAAI,CAAA,CAAE,QAAA,CAAS,OAAO,CAAA,CAAE;AAAA,GACnD;AACA,EAAA,GAAA,CAAI,IAAA;AAAA,IACF,WAAA,CAAY,SAAS,CAAA,GACjB,CAAA,iCAAA,EAAoC,YAAY,IAAA,CAAK,IAAI,CAAC,CAAA,CAAA,GAC1D;AAAA,GACN;AAEA,EAAA,GAAA,CAAI,KAAK,CAAA,6BAAA,EAAgC,MAAA,CAAO,IAAI,KAAK,CAAA,IAAK,CAAC,CAAA,CAAE,CAAA;AACjE,EAAA,GAAA,CAAI,KAAK,iEAAiE,CAAA;AAC5E;AAGO,SAAS,gBAAgB,MAAA,EAA0B;AACxD,EAAA,GAAA,CAAI,KAAK,MAAM,CAAA;AACf,EAAA,GAAA,CAAI,IAAA,CAAK;AAAA,MAAA,EAAW,MAAA,CAAO,SAAS,CAAA,CAAE,CAAA;AACtC,EAAA,KAAA,MAAW,CAAA,IAAK,OAAO,SAAA,EAAW;AAChC,IAAA,IAAI,CAAA,CAAE,WAAW,UAAA,EAAY;AAC3B,MAAA,GAAA,CAAI,KAAK,CAAA,EAAA,EAAK,CAAA,CAAE,OAAO,CAAA,YAAA,EAAe,CAAA,CAAE,MAAM,CAAA,CAAA,CAAG,CAAA;AACjD,MAAA;AAAA,IACF;AACA,IAAA,GAAA,CAAI,IAAA,CAAK,KAAK,CAAA,CAAE,OAAO,KAAK,CAAA,CAAE,IAAA,GAAO,MAAA,GAAS,MAAM,CAAA,CAAE,CAAA;AACtD,IAAA,KAAA,MAAW,CAAA,IAAK,EAAE,KAAA,EAAO;AACvB,MAAA,GAAA,CAAI,IAAA,CAAK,SAAS,CAAA,CAAE,IAAI,KAAK,CAAA,CAAE,IAAA,GAAO,MAAA,GAAS,MAAM,CAAA,CAAE,CAAA;AACvD,MAAA,KAAA,MAAW,CAAA,IAAK,EAAE,UAAA,EAAY;AAC5B,QAAA,GAAA,CAAI,IAAA,CAAK,CAAA,QAAA,EAAW,CAAA,CAAE,IAAI,CAAA,EAAA,EAAK,EAAE,MAAM,CAAA,EAAA,EAAK,CAAA,CAAE,MAAM,CAAA,CAAA,CAAG,CAAA;AAAA,MACzD;AAAA,IACF;AAAA,EACF;AACF;ACpDA,SAAS,MAAM,CAAA,EAAmB;AAChC,EAAA,OACE,CAAA,CACG,WAAA,EAAY,CACZ,OAAA,CAAQ,cAAA,EAAgB,GAAG,CAAA,CAC3B,OAAA,CAAQ,UAAA,EAAY,EAAE,CAAA,IAAK,WAAA;AAElC;AAGO,SAAS,eAAe,IAAA,EAAuC;AACpE,EAAA,MAAM,GAAA,GAAMC,SAAAA,CAAQ,IAAA,CAAK,GAAG,CAAA;AAC5B,EAAA,SAAA,CAAU,GAAA,EAAK,EAAE,SAAA,EAAW,IAAA,EAAM,CAAA;AAElC,EAAA,MAAM,YAAA,GAAe,IAAA,CAAK,GAAA,EAAK,WAAW,CAAA;AAC1C,EAAA,IAAI,UAAA,CAAW,YAAY,CAAA,EAAG;AAC5B,IAAA,MAAM,IAAI,KAAA,CAAM,CAAA,2BAAA,EAA8B,YAAY,CAAA,CAAE,CAAA;AAAA,EAC9D;AAEA,EAAA,MAAM,OAAO,KAAA,CAAM,IAAA,CAAK,IAAA,IAAQ,QAAA,CAAS,GAAG,CAAC,CAAA;AAC7C,EAAA,MAAM,SAAA,GAAY,KAAK,SAAA,IAAa,aAAA;AACpC,EAAA,MAAM,QAAkB,EAAC;AAEzB,EAAA,MAAM,QAAA,GAAW,SAAS,IAAI;AAAA;AAAA;AAAA;AAAA,aAAA,EAIjB,SAAS;AAAA;AAAA;AAAA;AAAA,CAAA;AAKtB,EAAA,aAAA,CAAc,cAAc,QAAQ,CAAA;AACpC,EAAA,KAAA,CAAM,IAAA,CAAK,QAAA,CAAS,GAAA,EAAK,YAAY,CAAC,CAAA;AAEtC,EAAA,MAAM,QAAA,GAAW,IAAA,CAAK,GAAA,EAAK,QAAA,EAAU,OAAO,CAAA;AAC5C,EAAA,SAAA,CAAU,QAAA,EAAU,EAAE,SAAA,EAAW,IAAA,EAAM,CAAA;AACvC,EAAA,MAAM,OAAA,GAAU,CAAA;AAAA;AAAA;AAAA;;AAAA;AAAA,CAAA;AAOhB,EAAA,MAAM,SAAA,GAAY,IAAA,CAAK,QAAA,EAAU,UAAU,CAAA;AAC3C,EAAA,aAAA,CAAc,WAAW,OAAO,CAAA;AAChC,EAAA,KAAA,CAAM,IAAA,CAAK,QAAA,CAAS,GAAA,EAAK,SAAS,CAAC,CAAA;AAEnC,EAAA,OAAO,EAAE,GAAA,EAAK,IAAA,EAAM,KAAA,EAAM;AAC5B;;;ACzBA,eAAe,cACb,SAAA,EACmD;AACnD,EAAA,MAAMC,WAAU,UAAA,EAAW;AAC3B,EAAA,MAAM,UAAoB,EAAC;AAC3B,EAAA,MAAM,UAAoB,EAAC;AAC3B,EAAA,KAAA,MAAW,KAAK,SAAA,EAAW;AACzB,IAAA,IAAI,MAAMA,SAAQ,CAAC,CAAA,EAAG,WAAU,EAAG,OAAA,CAAQ,KAAK,CAAC,CAAA;AAAA,SAC5C,OAAA,CAAQ,KAAK,CAAC,CAAA;AAAA,EACrB;AACA,EAAA,OAAO,EAAE,SAAS,OAAA,EAAQ;AAC5B;AAEA,SAAS,cAAc,OAAA,EAAoD;AACzE,EAAA,MAAM,MAAA,uBAAa,GAAA,EAAoB;AACvC,EAAA,KAAA,MAAW,CAAA,IAAK,OAAA,EAAS,MAAA,CAAO,GAAA,CAAI,CAAA,CAAE,MAAA,EAAA,CAAS,MAAA,CAAO,GAAA,CAAI,CAAA,CAAE,MAAM,CAAA,IAAK,CAAA,IAAK,CAAC,CAAA;AAC7E,EAAA,OAAO,MAAA;AACT;AAEA,SAAS,KAAK,GAAA,EAAqB;AACjC,EAAA,IAAI,eAAe,YAAA,EAAc;AAC/B,IAAA,GAAA,CAAI,KAAA,CAAM;AAAA,EAAK,GAAA,CAAI,OAAO,CAAA,CAAA,CAAG,CAAA;AAC7B,IAAA,gBAAA,CAAiB,IAAI,WAAW,CAAA;AAAA,EAClC,CAAA,MAAO;AACL,IAAA,GAAA,CAAI,KAAA,CAAM;AAAA,EAAM,GAAA,CAAc,OAAO,CAAA,CAAE,CAAA;AAAA,EACzC;AACA,EAAA,OAAA,CAAQ,KAAK,CAAC,CAAA;AAChB;AAEA,IAAM,UAAU,aAAA,CAAc;AAAA,EAC5B,IAAA,EAAM,EAAE,IAAA,EAAM,MAAA,EAAQ,aAAa,oDAAA,EAAqD;AAAA,EACxF,IAAA,EAAM;AAAA,IACJ,GAAA,EAAK,EAAE,IAAA,EAAM,YAAA,EAAc,UAAU,KAAA,EAAO,OAAA,EAAS,GAAA,EAAK,WAAA,EAAa,kBAAA,EAAmB;AAAA,IAC1F,IAAA,EAAM,EAAE,IAAA,EAAM,QAAA,EAAU,aAAa,0BAAA,EAA2B;AAAA,IAChE,SAAA,EAAW,EAAE,IAAA,EAAM,QAAA,EAAU,aAAa,sCAAA;AAAuC,GACnF;AAAA,EACA,GAAA,CAAI,EAAE,IAAA,EAAK,EAAG;AACZ,IAAA,MAAM,UAAU,cAAA,CAAe;AAAA,MAC7B,KAAK,IAAA,CAAK,GAAA;AAAA,MACV,MAAM,IAAA,CAAK,IAAA;AAAA,MACX,WAAW,IAAA,CAAK;AAAA,KACjB,CAAA;AACD,IAAA,GAAA,CAAI,KAAK,CAAA,mBAAA,EAAsB,OAAA,CAAQ,IAAI,CAAA,KAAA,EAAQ,OAAA,CAAQ,GAAG,CAAA,CAAE,CAAA;AAChE,IAAA,KAAA,MAAW,KAAK,OAAA,CAAQ,KAAA,MAAW,IAAA,CAAK,CAAA,IAAA,EAAO,CAAC,CAAA,CAAE,CAAA;AAClD,IAAA,GAAA,CAAI,IAAA,CAAK;AAAA,oBAAA,EAAyB,IAAA,CAAK,GAAG,CAAA,eAAA,EAAkB,IAAA,CAAK,GAAG,CAAA,CAAE,CAAA;AAAA,EACxE;AACF,CAAC,CAAA;AAED,IAAM,cAAc,aAAA,CAAc;AAAA,EAChC,IAAA,EAAM,EAAE,IAAA,EAAM,UAAA,EAAY,aAAa,gDAAA,EAAiD;AAAA,EACxF,IAAA,EAAM;AAAA,IACJ,GAAA,EAAK,EAAE,IAAA,EAAM,YAAA,EAAc,UAAU,KAAA,EAAO,OAAA,EAAS,GAAA,EAAK,WAAA,EAAa,kBAAA;AAAmB,GAC5F;AAAA,EACA,GAAA,CAAI,EAAE,IAAA,EAAK,EAAG;AACZ,IAAA,IAAI;AACF,MAAA,MAAM,MAAA,GAAS,IAAA,CAAK,IAAA,CAAK,GAAG,CAAA;AAC5B,MAAA,MAAM,EAAE,KAAA,EAAO,SAAA,EAAU,GAAI,MAAA,CAAO,WAAA;AACpC,MAAA,IAAI,KAAA,CAAM,MAAA,GAAS,CAAA,EAAG,gBAAA,CAAiB,KAAK,CAAA;AAC5C,MAAA,IAAI,SAAA,EAAW;AACb,QAAA,GAAA,CAAI,KAAA,CAAM;AAAA,EAAK,MAAA,CAAO,EAAE,CAAA,SAAA,CAAW,CAAA;AACnC,QAAA,OAAA,CAAQ,KAAK,CAAC,CAAA;AAAA,MAChB;AACA,MAAA,GAAA,CAAI,IAAA,CAAK,EAAE,EAAA,EAAI,MAAA,CAAO,EAAA,EAAI,KAAA,EAAO,IAAA,EAAM,UAAA,EAAY,MAAA,CAAO,MAAA,CAAO,UAAA,CAAW,MAAA,EAAQ,CAAA;AACpF,MAAA,GAAA,CAAI,IAAA,CAAK,GAAG,MAAA,CAAO,EAAE,YAAY,MAAA,CAAO,MAAA,CAAO,UAAA,CAAW,MAAM,CAAA,YAAA,CAAc,CAAA;AAAA,IAChF,SAAS,GAAA,EAAK;AACZ,MAAA,IAAA,CAAK,GAAG,CAAA;AAAA,IACV;AAAA,EACF;AACF,CAAC,CAAA;AAED,IAAM,WAAW,aAAA,CAAc;AAAA,EAC7B,IAAA,EAAM;AAAA,IACJ,IAAA,EAAM,OAAA;AAAA,IACN,WAAA,EAAa;AAAA,GACf;AAAA,EACA,IAAA,EAAM;AAAA,IACJ,GAAA,EAAK;AAAA,MACH,IAAA,EAAM,YAAA;AAAA,MACN,QAAA,EAAU,KAAA;AAAA,MACV,OAAA,EAAS,GAAA;AAAA,MACT,WAAA,EAAa;AAAA,KACf;AAAA,IACA,KAAK,EAAE,IAAA,EAAM,UAAU,OAAA,EAAS,WAAA,EAAa,aAAa,kBAAA,EAAmB;AAAA,IAC7E,MAAA,EAAQ,EAAE,IAAA,EAAM,QAAA,EAAU,aAAa,mDAAA;AAAoD,GAC7F;AAAA,EACA,MAAM,GAAA,CAAI,EAAE,IAAA,EAAK,EAAG;AAClB,IAAA,IAAI;AACF,MAAA,MAAM,WAAW,aAAA,EAAc;AAC/B,MAAA,MAAM,OAAA,GAAU,YAAA,CAAa,IAAA,CAAK,MAAM,CAAA;AAGxC,MAAA,MAAM,EAAE,KAAI,GAAI,MAAM,iBAAiB,IAAA,CAAK,GAAA,EAAK,OAAA,CAAQ,GAAA,EAAK,CAAA;AAG9D,MAAA,IAAI,sBAAA,CAAuB,GAAG,CAAA,EAAG;AAC/B,QAAA,MAAM,EAAE,WAAA,EAAa,OAAA,EAAS,SAAAC,QAAAA,EAAQ,GAAI,MAAM,gBAAA,CAAiB;AAAA,UAC/D,cAAA,EAAgB,GAAA;AAAA,UAChB,QAAQ,IAAA,CAAK,GAAA;AAAA,UACb,QAAA;AAAA,UACA;AAAA,SACD,CAAA;AACD,QAAA,GAAA,CAAI,IAAA,CAAK;AAAA,UACP,aAAa,WAAA,CAAY,IAAA;AAAA,UACzB,SAAS,OAAA,CAAQ,MAAA;AAAA,UACjB,KAAK,IAAA,CAAK,GAAA;AAAA,UACV,KAAA,EAAO,MAAA,CAAO,WAAA,CAAY,aAAA,CAAcA,QAAO,CAAC;AAAA,SACjD,CAAA;AACD,QAAA,GAAA,CAAI,IAAA;AAAA,UACF,CAAA,kBAAA,EAAqB,YAAY,IAAI,CAAA,EAAA,EAAK,QAAQ,MAAM,CAAA,aAAA,EAAgB,KAAK,GAAG,CAAA,CAAA;AAAA,SAClF;AACA,QAAA,KAAA,MAAW,CAAC,CAAA,EAAG,CAAC,CAAA,IAAK,aAAA,CAAcA,QAAO,CAAA,EAAG,GAAA,CAAI,IAAA,CAAK,CAAA,EAAA,EAAK,CAAC,CAAA,EAAA,EAAK,CAAC,CAAA,MAAA,CAAQ,CAAA;AAC1E,QAAA;AAAA,MACF;AAEA,MAAA,MAAM,EAAE,MAAA,EAAQ,OAAA,EAAQ,GAAI,MAAM,KAAA,CAAM;AAAA,QACtC,SAAA,EAAW,GAAA;AAAA,QACX,QAAQ,IAAA,CAAK,GAAA;AAAA,QACb,QAAA;AAAA,QACA;AAAA,OACD,CAAA;AACD,MAAA,IAAI,MAAA,CAAO,YAAY,KAAA,CAAM,MAAA,GAAS,GAAG,gBAAA,CAAiB,MAAA,CAAO,YAAY,KAAK,CAAA;AAClF,MAAA,GAAA,CAAI,IAAA,CAAK,EAAE,EAAA,EAAI,MAAA,CAAO,IAAI,GAAA,EAAK,IAAA,CAAK,GAAA,EAAK,KAAA,EAAO,OAAO,WAAA,CAAY,aAAA,CAAc,OAAO,CAAC,GAAG,CAAA;AAC5F,MAAA,GAAA,CAAI,KAAK,CAAA,MAAA,EAAS,MAAA,CAAO,EAAE,CAAA,IAAA,EAAO,IAAA,CAAK,GAAG,CAAA,CAAA,CAAG,CAAA;AAC7C,MAAA,KAAA,MAAW,CAAC,CAAA,EAAG,CAAC,CAAA,IAAK,aAAA,CAAc,OAAO,CAAA,EAAG;AAC3C,QAAA,GAAA,CAAI,IAAA,CAAK,CAAA,EAAA,EAAK,CAAC,CAAA,EAAA,EAAK,CAAC,sBAAsB,IAAA,CAAK,GAAG,CAAA,CAAA,EAAI,CAAC,CAAA,CAAA,CAAG,CAAA;AAAA,MAC7D;AAAA,IACF,SAAS,GAAA,EAAK;AACZ,MAAA,IAAA,CAAK,GAAG,CAAA;AAAA,IACV;AAAA,EACF;AACF,CAAC,CAAA;AAED,IAAM,aAAa,aAAA,CAAc;AAAA,EAC/B,IAAA,EAAM;AAAA,IACJ,IAAA,EAAM,SAAA;AAAA,IACN,WAAA,EAAa;AAAA,GACf;AAAA,EACA,IAAA,EAAM;AAAA,IACJ,GAAA,EAAK;AAAA,MACH,IAAA,EAAM,YAAA;AAAA,MACN,QAAA,EAAU,KAAA;AAAA,MACV,OAAA,EAAS,GAAA;AAAA,MACT,WAAA,EAAa;AAAA,KACf;AAAA,IACA,OAAO,EAAE,IAAA,EAAM,UAAU,OAAA,EAAS,SAAA,EAAW,aAAa,gBAAA,EAAiB;AAAA,IAC3E,MAAA,EAAQ,EAAE,IAAA,EAAM,QAAA,EAAU,aAAa,mDAAA,EAAoD;AAAA,IAC3F,IAAA,EAAM;AAAA,MACJ,IAAA,EAAM,QAAA;AAAA,MACN,WAAA,EAAa;AAAA,KACf;AAAA,IACA,GAAA,EAAK;AAAA,MACH,IAAA,EAAM,SAAA;AAAA,MACN,WAAA,EAAa;AAAA,KACf;AAAA,IACA,OAAA,EAAS;AAAA,MACP,IAAA,EAAM,QAAA;AAAA,MACN,WAAA,EAAa;AAAA,KACf;AAAA,IACA,GAAA,EAAK,EAAE,IAAA,EAAM,QAAA,EAAU,aAAa,yDAAA;AAA0D,GAChG;AAAA,EACA,MAAM,GAAA,CAAI,EAAE,IAAA,EAAK,EAAG;AAClB,IAAA,IAAI;AACF,MAAA,MAAM,WAAW,aAAA,EAAc;AAC/B,MAAA,MAAM,KAAA,GAAS,IAAA,CAAK,KAAA,KAAU,MAAA,GAAS,MAAA,GAAS,SAAA;AAChD,MAAA,MAAM,SAAA,GAAY,YAAA,CAAa,IAAA,CAAK,MAAM,KAAK,QAAA,CAAS,OAAA;AACxD,MAAA,MAAM,KAAA,GAAQ,SAAA,CAAU,IAAA,CAAK,OAAO,CAAA;AAGpC,MAAA,IAAI,OAAA,GAAU,SAAA;AACd,MAAA,IAAI,CAAC,KAAK,GAAA,EAAK;AACb,QAAA,MAAM,EAAE,OAAA,EAAS,OAAA,EAAQ,GAAI,MAAM,cAAc,SAAS,CAAA;AAC1D,QAAA,KAAA,MAAW,KAAK,OAAA,EAAS,GAAA,CAAI,IAAA,CAAK,CAAA,UAAA,EAAa,CAAC,CAAA,sBAAA,CAAwB,CAAA;AACxE,QAAA,IAAI,OAAA,CAAQ,WAAW,CAAA,EAAG;AACxB,UAAA,GAAA,CAAI,MAAM,+DAA+D,CAAA;AACzE,UAAA,OAAA,CAAQ,KAAK,CAAC,CAAA;AAAA,QAChB;AACA,QAAA,OAAA,GAAU,OAAA;AAAA,MACZ;AAIA,MAAA,MAAM,EAAE,KAAI,GAAI,MAAM,iBAAiB,IAAA,CAAK,GAAA,EAAK,OAAA,CAAQ,GAAA,EAAK,CAAA;AAG9D,MAAA,IAAI,sBAAA,CAAuB,GAAG,CAAA,EAAG;AAC/B,QAAA,MAAM,EAAA,GAAK,MAAM,kBAAA,CAAmB;AAAA,UAClC,cAAA,EAAgB,GAAA;AAAA,UAChB,KAAA;AAAA,UACA,GAAA,EAAK,IAAA,CAAK,GAAA,IAAO,OAAA,CAAQ,GAAA,EAAI;AAAA,UAC7B,QAAA;AAAA,UACA,OAAA;AAAA,UACA,GAAI,QAAQ,EAAE,OAAA,EAAS,EAAE,eAAA,EAAiB,KAAA,EAAM,EAAE,GAAI;AAAC,SACxD,CAAA;AACD,QAAA,GAAA,CAAI,IAAA,CAAK;AAAA,UACP,WAAA,EAAa,GAAG,WAAA,CAAY,IAAA;AAAA,UAC5B,OAAA,EAAS,GAAG,QAAA,CAAS,GAAA,CAAI,CAAC,CAAA,KAAM,CAAA,CAAE,OAAO,EAAE,CAAA;AAAA,UAC3C,KAAA;AAAA,UACA,UAAU,EAAA,CAAG;AAAA,SACd,CAAA;AACD,QAAA,GAAA,CAAI,IAAA;AAAA,UACF,CAAA,sBAAA,EAAyB,GAAG,WAAA,CAAY,IAAI,KAAK,EAAA,CAAG,QAAA,CAAS,MAAM,CAAA,UAAA,EAAa,KAAK,CAAA,CAAA;AAAA,SACvF;AACA,QAAA,KAAA,MAAW,CAAA,IAAK,GAAG,QAAA,EAAU;AAC3B,UAAA,GAAA,CAAI,IAAA;AAAA,YACF,CAAA,EAAA,EAAK,CAAA,CAAE,MAAA,CAAO,EAAE,IAAI,CAAA,CAAE,MAAA,CAAO,EAAA,CAAG,MAAA,CAAO,OAAO,CAAA,EAAA,EAAK,CAAA,CAAE,KAAA,CAAM,UAAU,MAAM,CAAA,UAAA;AAAA,WAC7E;AAAA,QACF;AACA,QAAA,GAAA,CAAI,IAAA,CAAK,CAAA,YAAA,EAAe,EAAA,CAAG,QAAQ,CAAA,CAAE,CAAA;AACrC,QAAA;AAAA,MACF;AAEA,MAAA,MAAM,MAAA,GAAS,MAAM,OAAA,CAAQ;AAAA,QAC3B,SAAA,EAAW,GAAA;AAAA,QACX,KAAA;AAAA,QACA,GAAA,EAAK,IAAA,CAAK,GAAA,IAAO,OAAA,CAAQ,GAAA,EAAI;AAAA,QAC7B,QAAA;AAAA,QACA,OAAA;AAAA,QACA,IAAA,EAAM,SAAA,CAAU,IAAA,CAAK,IAAI,CAAA;AAAA,QACzB,GAAI,QAAQ,EAAE,OAAA,EAAS,EAAE,eAAA,EAAiB,KAAA,EAAM,EAAE,GAAI;AAAC,OACxD,CAAA;AACD,MAAA,iBAAA,CAAkB,OAAO,MAAM,CAAA;AAC/B,MAAA,GAAA,CAAI,IAAA,CAAK;AAAA,QACP,EAAA,EAAI,OAAO,MAAA,CAAO,EAAA;AAAA,QAClB,OAAA,EAAS,MAAA,CAAO,MAAA,CAAO,EAAA,CAAG,MAAA,CAAO,OAAA;AAAA,QACjC,KAAA;AAAA,QACA,SAAA,EAAW,MAAA,CAAO,KAAA,CAAM,SAAA,CAAU,MAAA;AAAA,QAClC,UAAU,MAAA,CAAO;AAAA,OAClB,CAAA;AACD,MAAA,GAAA,CAAI,IAAA,CAAK,CAAA,UAAA,EAAa,MAAA,CAAO,MAAA,CAAO,EAAE,CAAA,CAAA,EAAI,MAAA,CAAO,MAAA,CAAO,EAAA,CAAG,MAAA,CAAO,OAAO,CAAA,EAAA,EAAK,KAAK,CAAA,CAAA,CAAG,CAAA;AACtF,MAAA,GAAA,CAAI,KAAK,CAAA,EAAA,EAAK,MAAA,CAAO,KAAA,CAAM,SAAA,CAAU,MAAM,CAAA,iBAAA,CAAmB,CAAA;AAC9D,MAAA,IAAI,MAAA,CAAO,OAAA,CAAQ,QAAA,CAAS,MAAA,GAAS,CAAA,EAAG;AACtC,QAAA,MAAM,OAAA,GAAU,OAAO,OAAA,CAAQ,QAAA,CAAS,OAAO,CAAC,CAAA,KAAM,CAAA,CAAE,MAAA,KAAW,SAAS,CAAA;AAC5E,QAAA,GAAA,CAAI,IAAA;AAAA,UACF,CAAA,UAAA,EAAa,MAAA,CAAO,OAAA,CAAQ,QAAA,CAAS,MAAM,CAAA,SAAA,CAAA,IACxC,MAAA,CAAO,OAAA,CAAQ,IAAA,GAAO,CAAA,IAAA,EAAO,MAAA,CAAO,OAAA,CAAQ,IAAI,CAAA,aAAA,CAAA,GAAkB,EAAA,CAAA,IAClE,OAAA,CAAQ,MAAA,GAAS,CAAA,GAAI,CAAA,WAAA,EAAc,OAAA,CAAQ,GAAA,CAAI,CAAC,CAAA,KAAM,CAAA,CAAE,GAAG,CAAA,CAAE,IAAA,CAAK,IAAI,CAAC,CAAA,CAAA,GAAK,EAAA;AAAA,SACjF;AAAA,MACF;AACA,MAAA,GAAA,CAAI,IAAA,CAAK,CAAA,YAAA,EAAe,MAAA,CAAO,QAAQ,CAAA,CAAE,CAAA;AAAA,IAC3C,SAAS,GAAA,EAAK;AACZ,MAAA,IAAA,CAAK,GAAG,CAAA;AAAA,IACV;AAAA,EACF;AACF,CAAC,CAAA;AAED,IAAM,YAAY,aAAA,CAAc;AAAA,EAC9B,IAAA,EAAM;AAAA,IACJ,IAAA,EAAM,QAAA;AAAA,IACN,WAAA,EAAa;AAAA,GACf;AAAA,EACA,IAAA,EAAM;AAAA,IACJ,GAAA,EAAK,EAAE,IAAA,EAAM,YAAA,EAAc,UAAU,KAAA,EAAO,OAAA,EAAS,GAAA,EAAK,WAAA,EAAa,kBAAA,EAAmB;AAAA,IAC1F,OAAO,EAAE,IAAA,EAAM,UAAU,OAAA,EAAS,SAAA,EAAW,aAAa,gBAAA,EAAiB;AAAA,IAC3E,MAAA,EAAQ,EAAE,IAAA,EAAM,QAAA,EAAU,aAAa,mDAAA,EAAoD;AAAA,IAC3F,GAAA,EAAK,EAAE,IAAA,EAAM,QAAA,EAAU,aAAa,yDAAA;AAA0D,GAChG;AAAA,EACA,MAAM,GAAA,CAAI,EAAE,IAAA,EAAK,EAAG;AAClB,IAAA,IAAI;AACF,MAAA,MAAM,KAAA,GAAS,IAAA,CAAK,KAAA,KAAU,MAAA,GAAS,MAAA,GAAS,SAAA;AAChD,MAAA,MAAM,GAAA,GAAM,IAAA,CAAK,GAAA,IAAO,OAAA,CAAQ,GAAA,EAAI;AAGpC,MAAA,MAAM,IAAA,GAAO,QAAA,CAAS,eAAA,CAAgB,KAAA,EAAO,GAAG,CAAC,CAAA;AACjD,MAAA,MAAM,aAAA,GAAgB,IAAA,GACjB,CAAC,GAAG,IAAI,GAAA,CAAI,IAAA,CAAK,SAAA,CAAU,GAAA,CAAI,CAAC,CAAA,KAAM,CAAA,CAAE,MAAM,CAAC,CAAC,CAAA,GACjD,KAAA,CAAA;AACJ,MAAA,MAAM,MAAA,GAAS,MAAM,MAAA,CAAO;AAAA,QAC1B,WAAW,IAAA,CAAK,GAAA;AAAA,QAChB,KAAA;AAAA,QACA,GAAA;AAAA,QACA,UAAU,aAAA,EAAc;AAAA,QACxB,OAAA,EAAS,YAAA,CAAa,IAAA,CAAK,MAAM,CAAA,IAAK;AAAA,OACvC,CAAA;AACD,MAAA,GAAA,CAAI,IAAA,CAAK,EAAE,EAAA,EAAI,MAAA,CAAO,IAAI,OAAA,EAAS,MAAA,CAAO,SAAS,CAAA;AACnD,MAAA,GAAA,CAAI,IAAA,CAAK,WAAW,MAAA,CAAO,EAAE,KAAK,MAAA,CAAO,OAAA,CAAQ,MAAM,CAAA,oBAAA,CAAsB,CAAA;AAC7E,MAAA,KAAA,MAAW,KAAK,MAAA,CAAO,OAAA,MAAa,IAAA,CAAK,CAAA,IAAA,EAAO,CAAC,CAAA,CAAE,CAAA;AAAA,IACrD,SAAS,GAAA,EAAK;AACZ,MAAA,IAAA,CAAK,GAAG,CAAA;AAAA,IACV;AAAA,EACF;AACF,CAAC,CAAA;AAED,IAAM,UAAU,aAAA,CAAc;AAAA,EAC5B,IAAA,EAAM;AAAA,IACJ,IAAA,EAAM,MAAA;AAAA,IACN,WAAA,EAAa;AAAA,GACf;AAAA,EACA,IAAA,EAAM;AAAA,IACJ,GAAA,EAAK,EAAE,IAAA,EAAM,YAAA,EAAc,UAAU,KAAA,EAAO,OAAA,EAAS,GAAA,EAAK,WAAA,EAAa,kBAAA,EAAmB;AAAA,IAC1F,SAAA,EAAW,EAAE,IAAA,EAAM,QAAA,EAAU,aAAa,oCAAA,EAAqC;AAAA,IAC/E,OAAA,EAAS,EAAE,IAAA,EAAM,QAAA,EAAU,aAAa,+CAAA;AAAgD,GAC1F;AAAA,EACA,MAAM,GAAA,CAAI,EAAE,IAAA,EAAK,EAAG;AAClB,IAAA,IAAI;AACF,MAAA,MAAM,WAAW,aAAA,EAAc;AAC/B,MAAA,MAAMD,WAAU,UAAA,EAAW;AAC3B,MAAA,MAAM,UAAA,GAAa,aAAA,CAAc,IAAA,CAAK,GAAG,CAAA,CAAE,MAAA;AAAA,QACzC,CAAC,CAAA,KAAM,CAAC,KAAK,SAAA,IAAa,CAAA,CAAE,kBAAkB,IAAA,CAAK;AAAA,OACrD;AACA,MAAA,IAAI,UAAA,CAAW,WAAW,CAAA,EAAG;AAC3B,QAAA,GAAA,CAAI,KAAK,+DAA+D,CAAA;AACxE,QAAA;AAAA,MACF;AACA,MAAA,MAAM,WAAA,GAAc,YAAA,CAAa,IAAA,CAAK,OAAO,CAAA;AAC7C,MAAA,IAAI,OAAA,GAAU,KAAA;AACd,MAAA,KAAA,MAAW,KAAK,UAAA,EAAY;AAC1B,QAAA,MAAM,WAAW,WAAA,GACb;AAAA,UACE,GAAG,CAAA,CAAE,QAAA;AAAA,UACL,SAAA,EAAW,CAAA,CAAE,QAAA,CAAS,SAAA,CAAU,MAAA,CAAO,CAAC,CAAA,KAAM,WAAA,CAAY,QAAA,CAAS,CAAC,CAAC;AAAA,YAEvE,CAAA,CAAE,QAAA;AACN,QAAA,MAAM,MAAA,GAAS,MAAM,OAAA,CAAQ;AAAA,UAC3B,QAAA;AAAA,UACA,WAAW,IAAA,CAAK,GAAA;AAAA,UAChB,eAAe,CAAA,CAAE,aAAA;AAAA,UACjB,QAAA;AAAA,UACA,OAAA,EAAAA;AAAA,SACD,CAAA;AACD,QAAA,eAAA,CAAgB,MAAM,CAAA;AACtB,QAAA,IAAI,MAAA,CAAO,SAAA,CAAU,IAAA,CAAK,CAAC,CAAA,KAAM,CAAA,CAAE,MAAA,KAAW,QAAA,IAAY,CAAC,CAAA,CAAE,IAAI,CAAA,EAAG,OAAA,GAAU,IAAA;AAAA,MAChF;AACA,MAAA,IAAI,OAAA,EAAS,OAAA,CAAQ,IAAA,CAAK,CAAC,CAAA;AAAA,IAC7B,SAAS,GAAA,EAAK;AACZ,MAAA,IAAA,CAAK,GAAG,CAAA;AAAA,IACV;AAAA,EACF;AACF,CAAC,CAAA;AAED,IAAM,aAAa,aAAA,CAAc;AAAA,EAC/B,IAAA,EAAM;AAAA,IACJ,IAAA,EAAM,SAAA;AAAA,IACN,WAAA,EAAa;AAAA,GACf;AAAA,EACA,IAAA,EAAM;AAAA,IACJ,GAAA,EAAK,EAAE,IAAA,EAAM,YAAA,EAAc,UAAU,KAAA,EAAO,OAAA,EAAS,GAAA,EAAK,WAAA,EAAa,kBAAA,EAAmB;AAAA,IAC1F,QAAA,EAAU;AAAA,MACR,IAAA,EAAM,SAAA;AAAA,MACN,WAAA,EAAa;AAAA;AACf,GACF;AAAA,EACA,MAAM,GAAA,CAAI,EAAE,IAAA,EAAK,EAAG;AAClB,IAAA,IAAI;AACF,MAAA,MAAM,GAAA,GAAM,MAAM,YAAA,CAAa,IAAA,CAAK,GAAA,EAAK;AAAA,QACvC,UAAU,aAAA,EAAc;AAAA,QACxB,SAAS,UAAA,EAAW;AAAA,QACpB,QAAA,EAAU,OAAA,CAAQ,IAAA,CAAK,QAAQ;AAAA,OAChC,CAAA;AACD,MAAA,GAAA,CAAI,IAAA,CAAK;AAAA,QACP,IAAI,GAAA,CAAI,EAAA;AAAA,QACR,SAAS,GAAA,CAAI,OAAA;AAAA,QACb,IAAI,GAAA,CAAI,EAAA;AAAA,QACR,OAAO,GAAA,CAAI,WAAA;AAAA,QACX,SAAA,EAAW,IAAI,IAAA,CAAK,KAAA;AAAA,QACpB,QAAQ,GAAA,CAAI,MAAA;AAAA,QACZ,iBAAiB,GAAA,CAAI;AAAA,OACtB,CAAA;AACD,MAAA,GAAA,CAAI,KAAK,CAAA,eAAA,EAAkB,GAAA,CAAI,EAAE,CAAA,CAAA,EAAI,GAAA,CAAI,OAAO,CAAA,CAAE,CAAA;AAClD,MAAA,IAAI,IAAI,WAAA,CAAY,MAAA,GAAS,CAAA,EAAG,gBAAA,CAAiB,IAAI,WAAW,CAAA;AAChE,MAAA,GAAA,CAAI,KAAK,CAAA,SAAA,EAAY,GAAA,CAAI,WAAA,GAAc,KAAA,GAAQ,IAAI,CAAA,CAAE,CAAA;AACrD,MAAA,GAAA,CAAI,IAAA,CAAK,CAAA,QAAA,EAAW,GAAA,CAAI,IAAA,CAAK,KAAA,GAAQ,OAAA,GAAU,CAAA,EAAG,GAAA,CAAI,IAAA,CAAK,QAAA,CAAS,MAAM,CAAA,WAAA,CAAa,CAAA,CAAE,CAAA;AACzF,MAAA,GAAA,CAAI,IAAA,CAAK,aAAa,GAAA,CAAI,MAAA,CAAO,KAAK,IAAI,CAAA,IAAK,MAAM,CAAA,CAAE,CAAA;AACvD,MAAA,GAAA,CAAI,IAAA,CAAK,uBAAuB,GAAA,CAAI,eAAA,CAAgB,KAAK,IAAI,CAAA,IAAK,MAAM,CAAA,CAAE,CAAA;AAC1E,MAAA,KAAA,MAAW,CAAA,IAAK,GAAA,CAAI,WAAA,EAAa,eAAA,CAAgB,CAAC,CAAA;AAClD,MAAA,IAAI,CAAC,IAAI,EAAA,EAAI;AACX,QAAA,GAAA,CAAI,MAAM,mDAAmD,CAAA;AAC7D,QAAA,OAAA,CAAQ,KAAK,CAAC,CAAA;AAAA,MAChB;AACA,MAAA,GAAA,CAAI,KAAK,wBAAwB,CAAA;AAAA,IACnC,SAAS,GAAA,EAAK;AACZ,MAAA,IAAA,CAAK,GAAG,CAAA;AAAA,IACV;AAAA,EACF;AACF,CAAC,CAAA;AAED,IAAM,UAAU,aAAA,CAAc;AAAA,EAC5B,IAAA,EAAM;AAAA,IACJ,IAAA,EAAM,MAAA;AAAA,IACN,WAAA,EACE;AAAA,GACJ;AAAA,EACA,IAAA,EAAM;AAAA,IACJ,GAAA,EAAK;AAAA,MACH,IAAA,EAAM,YAAA;AAAA,MACN,QAAA,EAAU,KAAA;AAAA,MACV,OAAA,EAAS,GAAA;AAAA,MACT,WAAA,EAAa;AAAA;AACf,GACF;AAAA,EACA,GAAA,CAAI,EAAE,IAAA,EAAK,EAAG;AACZ,IAAA,IAAI;AACF,MAAA,MAAM,IAAA,GAAO,QAAA,CAAS,IAAA,CAAK,GAAG,CAAA;AAC9B,MAAA,IAAI,CAAC,IAAA,EAAM;AACT,QAAA,GAAA,CAAI,MAAM,+CAA+C,CAAA;AACzD,QAAA,OAAA,CAAQ,KAAK,CAAC,CAAA;AAAA,MAChB;AACA,MAAA,MAAM,OAAA,GAAUE,IAAAA,CAAK,IAAA,CAAK,GAAA,EAAK,OAAO,CAAA;AACtC,MAAAC,SAAAA,CAAU,OAAA,EAAS,EAAE,SAAA,EAAW,MAAM,CAAA;AACtC,MAAAC,aAAAA,CAAcF,IAAAA,CAAK,OAAA,EAAS,YAAY,GAAG,KAAK,CAAA;AAChD,MAAA,MAAM,OAAA,GAAUA,IAAAA,CAAK,OAAA,EAAS,aAAa,CAAA;AAE3C,MAAA,IAAI,UAAA;AACJ,MAAA,IAAIG,UAAAA,CAAW,OAAO,CAAA,EAAG;AACvB,QAAA,UAAA,GAAa,gBAAA,CAAiB,YAAA,CAAa,OAAO,CAAC,CAAA;AAAA,MACrD,CAAA,MAAO;AACL,QAAA,MAAM,OAAO,mBAAA,EAAoB;AACjC,QAAA,UAAA,GAAa,IAAA,CAAK,UAAA;AAClB,QAAAD,aAAAA,CAAc,OAAA,EAAS,IAAA,CAAK,UAAA,CAAW,MAAA,CAAO,EAAE,IAAA,EAAM,OAAA,EAAS,MAAA,EAAQ,KAAA,EAAO,CAAC,CAAA;AAC/E,QAAAA,aAAAA;AAAA,UACEF,IAAAA,CAAK,IAAA,CAAK,GAAA,EAAK,UAAU,CAAA;AAAA,UACzB,IAAA,CAAK,UAAU,MAAA,CAAO,EAAE,MAAM,MAAA,EAAQ,MAAA,EAAQ,OAAO;AAAA,SACvD;AAAA,MACF;AACA,MAAAE,aAAAA,CAAcF,IAAAA,CAAK,IAAA,CAAK,GAAA,EAAK,UAAU,GAAG,CAAA,EAAG,QAAA,CAAS,IAAA,EAAM,UAAU,CAAC;AAAA,CAAI,CAAA;AAC3E,MAAA,GAAA,CAAI,IAAA;AAAA,QACF,CAAA,OAAA,EAAU,IAAA,CAAK,SAAA,CAAU,MAAM,CAAA,mEAAA;AAAA,OACjC;AAAA,IACF,SAAS,GAAA,EAAK;AACZ,MAAA,IAAA,CAAK,GAAG,CAAA;AAAA,IACV;AAAA,EACF;AACF,CAAC,CAAA;AAED,IAAM,YAAY,aAAA,CAAc;AAAA,EAC9B,IAAA,EAAM;AAAA,IACJ,IAAA,EAAM,QAAA;AAAA,IACN,WAAA,EAAa;AAAA,GACf;AAAA,EACA,IAAA,EAAM;AAAA,IACJ,GAAA,EAAK;AAAA,MACH,IAAA,EAAM,YAAA;AAAA,MACN,QAAA,EAAU,KAAA;AAAA,MACV,OAAA,EAAS,GAAA;AAAA,MACT,WAAA,EAAa;AAAA;AACf,GACF;AAAA,EACA,GAAA,CAAI,EAAE,IAAA,EAAK,EAAG;AACZ,IAAA,IAAI;AACF,MAAA,MAAM,IAAA,GAAO,QAAA,CAAS,IAAA,CAAK,GAAG,CAAA;AAC9B,MAAA,IAAI,CAAC,IAAA,EAAM;AACT,QAAA,GAAA,CAAI,MAAM,oBAAoB,CAAA;AAC9B,QAAA,OAAA,CAAQ,KAAK,CAAC,CAAA;AAAA,MAChB;AACA,MAAA,MAAM,GAAA,GAAM,aAAaA,IAAAA,CAAK,IAAA,CAAK,KAAK,UAAU,CAAA,EAAG,MAAM,CAAA,CAAE,IAAA,EAAK;AAClE,MAAA,MAAM,SAAA,GAAY,gBAAgB,YAAA,CAAaA,IAAAA,CAAK,KAAK,GAAA,EAAK,UAAU,CAAC,CAAC,CAAA;AAC1E,MAAA,MAAM,GAAA,GAAM,eAAA,CAAgB,IAAA,EAAM,SAAA,EAAW,GAAG,CAAA;AAChD,MAAA,GAAA,CAAI,IAAA,CAAK,EAAE,cAAA,EAAgB,GAAA,CAAI,gBAAgB,QAAA,EAAU,GAAA,CAAI,UAAU,CAAA;AACvE,MAAA,GAAA,CAAI,KAAK,CAAA,WAAA,EAAc,GAAA,CAAI,cAAA,GAAiB,OAAA,GAAU,SAAS,CAAA,CAAE,CAAA;AACjE,MAAA,GAAA,CAAI,IAAA,CAAK,CAAA,oBAAA,EAAuB,GAAA,CAAI,QAAA,CAAS,MAAM,CAAA,CAAE,CAAA;AACrD,MAAA,KAAA,MAAW,KAAK,GAAA,CAAI,QAAA,MAAc,IAAA,CAAK,CAAA,IAAA,EAAO,CAAC,CAAA,CAAE,CAAA;AACjD,MAAA,IAAI,CAAC,IAAI,cAAA,IAAkB,GAAA,CAAI,SAAS,MAAA,GAAS,CAAA,EAAG,OAAA,CAAQ,IAAA,CAAK,CAAC,CAAA;AAClE,MAAA,GAAA,CAAI,KAAK,wBAAwB,CAAA;AAAA,IACnC,SAAS,GAAA,EAAK;AACZ,MAAA,IAAA,CAAK,GAAG,CAAA;AAAA,IACV;AAAA,EACF;AACF,CAAC,CAAA;AAED,IAAM,WAAW,aAAA,CAAc;AAAA,EAC7B,IAAA,EAAM;AAAA,IACJ,IAAA,EAAM,OAAA;AAAA,IACN,WAAA,EAAa;AAAA,GACf;AAAA,EACA,IAAA,EAAM;AAAA,IACJ,GAAA,EAAK,EAAE,IAAA,EAAM,YAAA,EAAc,UAAU,KAAA,EAAO,OAAA,EAAS,GAAA,EAAK,WAAA,EAAa,oBAAA,EAAqB;AAAA,IAC5F,KAAK,EAAE,IAAA,EAAM,UAAU,OAAA,EAAS,YAAA,EAAc,aAAa,mBAAA,EAAoB;AAAA,IAC/E,QAAA,EAAU,EAAE,IAAA,EAAM,SAAA,EAAW,aAAa,6CAAA;AAA8C,GAC1F;AAAA,EACA,MAAM,GAAA,CAAI,EAAE,IAAA,EAAK,EAAG;AAClB,IAAA,IAAI;AAEF,MAAA,MAAM,WAAA,GAAe,IAAA,CAAK,CAAA,IAA8B,EAAC;AACzD,MAAA,MAAM,OAAO,WAAA,CAAY,MAAA,GAAS,CAAA,GAAI,WAAA,GAAc,CAAC,GAAG,CAAA;AACxD,MAAA,IAAI,KAAA,GAAQ,MAAM,mBAAA,CAAoB,IAAI,CAAA;AAC1C,MAAA,IAAI,KAAK,QAAA,EAAU;AACjB,QAAA,MAAM,UAAU,MAAM,gBAAA,CAAiB,EAAE,KAAA,EAAO,IAAI,CAAA;AACpD,QAAA,KAAA,GAAQ,SAAS,KAAA,EAAO,OAAA,EAAA,qBAAa,IAAA,EAAK,EAAE,aAAa,CAAA;AAAA,MAC3D;AACA,MAAAE,aAAAA,CAAc,IAAA,CAAK,GAAA,EAAK,cAAA,CAAe,KAAK,CAAC,CAAA;AAC7C,MAAA,MAAM,GAAA,GAAM,KAAK,QAAA,GAAW,CAAA,YAAA,EAAe,MAAM,SAAA,EAAW,MAAA,IAAU,CAAC,CAAA,UAAA,CAAA,GAAe,EAAA;AACtF,MAAA,GAAA,CAAI,IAAA,CAAK;AAAA,QACP,OAAA,EAAS,MAAM,OAAA,CAAQ,MAAA;AAAA,QACvB,SAAA,EAAW,KAAA,CAAM,SAAA,EAAW,MAAA,IAAU,CAAA;AAAA,QACtC,KAAK,IAAA,CAAK;AAAA,OACX,CAAA;AACD,MAAA,GAAA,CAAI,IAAA,CAAK,CAAA,aAAA,EAAgB,KAAA,CAAM,OAAA,CAAQ,MAAM,WAAW,GAAG,CAAA,KAAA,EAAQ,IAAA,CAAK,GAAG,CAAA,CAAE,CAAA;AAAA,IAC/E,SAAS,GAAA,EAAK;AACZ,MAAA,IAAA,CAAK,GAAG,CAAA;AAAA,IACV;AAAA,EACF;AACF,CAAC,CAAA;AAED,IAAM,YAAY,aAAA,CAAc;AAAA,EAC9B,IAAA,EAAM;AAAA,IACJ,IAAA,EAAM,QAAA;AAAA,IACN,WAAA,EAAa;AAAA,GACf;AAAA,EACA,IAAA,EAAM;AAAA,IACJ,GAAA,EAAK;AAAA,MACH,IAAA,EAAM,YAAA;AAAA,MACN,QAAA,EAAU,KAAA;AAAA,MACV,OAAA,EAAS,GAAA;AAAA,MACT,WAAA,EAAa;AAAA,KACf;AAAA,IACA,MAAM,EAAE,IAAA,EAAM,UAAU,OAAA,EAAS,QAAA,EAAU,aAAa,uBAAA,EAAwB;AAAA,IAChF,KAAK,EAAE,IAAA,EAAM,UAAU,OAAA,EAAS,UAAA,EAAY,aAAa,kBAAA,EAAmB;AAAA,IAC5E,SAAA,EAAW;AAAA,MACT,IAAA,EAAM,QAAA;AAAA,MACN,WAAA,EAAa;AAAA;AACf,GACF;AAAA,EACA,GAAA,CAAI,EAAE,IAAA,EAAK,EAAG;AACZ,IAAA,IAAI;AACF,MAAA,MAAM,OAAA,GAAU,aAAA,EAAc,CAAE,GAAA,CAAI,KAAK,IAAc,CAAA;AACvD,MAAA,IAAI,CAAC,OAAA,EAAS;AACZ,QAAA,GAAA,CAAI,KAAA,CAAM,CAAA,wBAAA,EAA2B,IAAA,CAAK,IAAI,CAAA,CAAA,CAAG,CAAA;AACjD,QAAA,OAAA,CAAQ,KAAK,CAAC,CAAA;AAAA,MAChB;AACA,MAAA,MAAM,MAAM,kBAAA,CAAmB;AAAA,QAC7B,KAAK,IAAA,CAAK,GAAA;AAAA,QACV,OAAA;AAAA,QACA,QAAQ,IAAA,CAAK,GAAA;AAAA,QACb,GAAI,KAAK,SAAA,GAAY,EAAE,WAAW,IAAA,CAAK,SAAA,KAAc;AAAC,OACvD,CAAA;AACD,MAAA,GAAA,CAAI,IAAA,CAAK;AAAA,QACP,MAAM,GAAA,CAAI,IAAA;AAAA,QACV,MAAM,GAAA,CAAI,IAAA;AAAA,QACV,UAAU,GAAA,CAAI,YAAA;AAAA,QACd,KAAK,GAAA,CAAI,MAAA;AAAA,QACT,GAAI,IAAI,IAAA,KAAS,QAAA,GAAW,EAAE,KAAA,EAAO,GAAA,CAAI,SAAA,EAAU,GAAI;AAAC,OACzD,CAAA;AACD,MAAA,GAAA,CAAI,IAAA,CAAK,CAAA,SAAA,EAAY,GAAA,CAAI,IAAI,CAAA,EAAA,EAAK,IAAI,IAAI,CAAA,KAAA,EAAQ,GAAA,CAAI,YAAY,CAAA,CAAE,CAAA;AACpE,MAAA,IAAI,GAAA,CAAI,SAAS,QAAA,EAAU,GAAA,CAAI,KAAK,CAAA,EAAA,EAAK,GAAA,CAAI,SAAS,CAAA,kBAAA,CAAoB,CAAA;AAC1E,MAAA,GAAA,CAAI,IAAA,CAAK,CAAA,mBAAA,EAAsB,GAAA,CAAI,MAAM,CAAA,CAAE,CAAA;AAAA,IAC7C,SAAS,GAAA,EAAK;AACZ,MAAA,IAAA,CAAK,GAAG,CAAA;AAAA,IACV;AAAA,EACF;AACF,CAAC,CAAA;AAED,IAAM,eAAe,aAAA,CAAc;AAAA,EACjC,IAAA,EAAM;AAAA,IACJ,IAAA,EAAM,WAAA;AAAA,IACN,WAAA,EAAa;AAAA,GACf;AAAA,EACA,IAAA,EAAM;AAAA,IACJ,GAAA,EAAK;AAAA,MACH,IAAA,EAAM,YAAA;AAAA,MACN,QAAA,EAAU,KAAA;AAAA,MACV,OAAA,EAAS,GAAA;AAAA,MACT,WAAA,EAAa;AAAA,KACf;AAAA,IACA,OAAO,EAAE,IAAA,EAAM,UAAU,OAAA,EAAS,SAAA,EAAW,aAAa,gBAAA,EAAiB;AAAA,IAC3E,MAAA,EAAQ;AAAA,MACN,IAAA,EAAM,QAAA;AAAA,MACN,WAAA,EAAa;AAAA;AACf,GACF;AAAA,EACA,GAAA,CAAI,EAAE,IAAA,EAAK,EAAG;AACZ,IAAA,IAAI;AACF,MAAA,MAAM,KAAA,GAAS,IAAA,CAAK,KAAA,KAAU,MAAA,GAAS,MAAA,GAAS,SAAA;AAGhD,MAAA,MAAM,GAAA,GAAM,IAAA,CAAK,GAAA,KAAQ,GAAA,GAAM,eAAA,CAAgB,OAAO,OAAA,CAAQ,GAAA,EAAK,CAAA,GAAI,IAAA,CAAK,GAAA;AAC5E,MAAA,MAAM,GAAA,GAAM,SAAA,CAAU,EAAE,GAAA,EAAK,GAAI,IAAA,CAAK,MAAA,GAAS,EAAE,MAAA,EAAQ,IAAA,CAAK,MAAA,EAAO,GAAI,IAAK,CAAA;AAC9E,MAAA,GAAA,CAAI,IAAA,CAAK,EAAE,OAAA,EAAS,GAAA,CAAI,SAAS,OAAA,EAAS,GAAA,CAAI,SAAS,CAAA;AACvD,MAAA,GAAA,CAAI,IAAA,CAAK,eAAe,GAAA,CAAI,OAAA,CAAQ,MAAM,CAAA,YAAA,EAAe,GAAA,CAAI,OAAA,CAAQ,MAAM,CAAA,YAAA,CAAc,CAAA;AAAA,IAC3F,SAAS,GAAA,EAAK;AACZ,MAAA,IAAA,CAAK,GAAG,CAAA;AAAA,IACV;AAAA,EACF;AACF,CAAC,CAAA;AAED,IAAM,UAAU,aAAA,CAAc;AAAA,EAC5B,IAAA,EAAM;AAAA,IACJ,IAAA,EAAM,MAAA;AAAA,IACN,WAAA,EAAa;AAAA,GACf;AAAA,EACA,IAAA,EAAM;AAAA,IACJ,GAAA,EAAK;AAAA,MACH,IAAA,EAAM,QAAA;AAAA,MACN,WAAA,EAAa;AAAA;AACf,GACF;AAAA,EACA,MAAM,GAAA,CAAI,EAAE,IAAA,EAAK,EAAG;AAClB,IAAA,MAAM,EAAA,GAAK,MAAM,kBAAA,CAAmB,IAAI,CAAA;AACxC,IAAA,IAAI,KAAK,GAAA,EAAK;AACZ,MAAAA,aAAAA,CAAc,IAAA,CAAK,GAAA,EAAK,EAAE,CAAA;AAC1B,MAAA,GAAA,CAAI,IAAA,CAAK,CAAA,uBAAA,EAA0B,IAAA,CAAK,GAAG,CAAA,CAAE,CAAA;AAAA,IAC/C,CAAA,MAAO;AACL,MAAA,OAAA,CAAQ,MAAA,CAAO,MAAM,EAAE,CAAA;AAAA,IACzB;AAAA,EACF;AACF,CAAC,CAAA;AAED,IAAM,OAAO,aAAA,CAAc;AAAA,EACzB,IAAA,EAAM;AAAA,IACJ,IAAA,EAAM,MAAA;AAAA,IACN,OAAA,EAAS,YAAA;AAAA,IACT,WAAA,EAAa;AAAA,GACf;AAAA,EACA,WAAA,EAAa;AAAA,IACX,IAAA,EAAM,OAAA;AAAA,IACN,QAAA,EAAU,WAAA;AAAA,IACV,KAAA,EAAO,QAAA;AAAA,IACP,OAAA,EAAS,UAAA;AAAA,IACT,SAAA,EAAW,YAAA;AAAA,IACX,MAAA,EAAQ,SAAA;AAAA,IACR,MAAA,EAAQ,SAAA;AAAA,IACR,IAAA,EAAM,OAAA;AAAA,IACN,OAAA,EAAS,UAAA;AAAA,IACT,IAAA,EAAM,OAAA;AAAA,IACN,MAAA,EAAQ,SAAA;AAAA,IACR,KAAA,EAAO,QAAA;AAAA,IACP,IAAA,EAAM;AAAA;AAEV,CAAC,CAAA;AAED,OAAA,CAAQ,IAAI,CAAA","file":"index.js","sourcesContent":["import { type CommandDef, renderUsage } from \"citty\";\n\ntype Resolvable<T> = T | (() => T | Promise<T>);\n\nasync function resolve<T>(r: Resolvable<T>): Promise<T> {\n return typeof r === \"function\" ? await (r as () => T | Promise<T>)() : r;\n}\n\n/**\n * Render a full Markdown CLI reference straight from the citty command tree, so\n * the docs can never drift from the actual commands -- the same single-source\n * principle Weft applies to manifests, applied to its own CLI.\n */\nexport async function renderCliReference(main: CommandDef): Promise<string> {\n const out: string[] = [\n \"# Weft CLI reference\",\n \"\",\n \"_Generated from the CLI definition by `weft docs` -- do not edit by hand._\",\n \"\",\n \"## `weft`\",\n \"\",\n \"```\",\n (await renderUsage(main)).trim(),\n \"```\",\n \"\",\n ];\n\n const subs = main.subCommands ? await resolve(main.subCommands) : {};\n for (const name of Object.keys(subs).sort()) {\n const sub = await resolve(subs[name] as Resolvable<CommandDef>);\n const meta = await resolve(sub.meta);\n out.push(`## \\`weft ${name}\\``, \"\");\n if (meta?.description) out.push(meta.description as string, \"\");\n out.push(\"```\", (await renderUsage(sub, main)).trim(), \"```\", \"\");\n }\n\n return `${out.join(\"\\n\")}\\n`;\n}\n","// The CLI's single output funnel: every other file logs through `log`, so the\n// libraries stay console-free and verbosity is controlled in one place. Flags are\n// read once from argv (citty parses them per-command; we only need their presence):\n// --quiet/-q errors only\n// --verbose/-v include debug lines\n// --json machine-readable output (human lines suppressed; use log.data)\n\ntype Level = \"error\" | \"warn\" | \"info\" | \"debug\";\nconst RANK: Record<Level, number> = { error: 0, warn: 1, info: 2, debug: 3 };\n\nfunction thresholdFrom(argv: string[]): number {\n if (argv.includes(\"--json\")) return RANK.error;\n if (argv.includes(\"--quiet\") || argv.includes(\"-q\")) return RANK.error;\n if (argv.includes(\"--verbose\") || argv.includes(\"-v\")) return RANK.debug;\n return RANK.info;\n}\n\nconst isJson = process.argv.includes(\"--json\");\nconst threshold = thresholdFrom(process.argv);\n\nfunction emit(level: Level, message: string): void {\n if (RANK[level] > threshold) return;\n // biome-ignore lint/suspicious/noConsole: this module is the CLI's output funnel.\n if (level === \"error\" || level === \"warn\") console.error(message);\n // biome-ignore lint/suspicious/noConsole: this module is the CLI's output funnel.\n else console.log(message);\n}\n\nexport const log = {\n /** True when --json is set; commands emit a result object via `data` instead of prose. */\n json: isJson,\n error: (message: string): void => emit(\"error\", message),\n warn: (message: string): void => emit(\"warn\", message),\n info: (message: string): void => emit(\"info\", message),\n debug: (message: string): void => emit(\"debug\", message),\n /** Emit a structured result. Prints JSON only in --json mode; a no-op otherwise. */\n data: (obj: unknown): void => {\n // biome-ignore lint/suspicious/noConsole: this module is the CLI's output funnel.\n if (isJson) console.log(JSON.stringify(obj));\n },\n};\n","import claudeAdapter from \"@michaelfromyeg/weft-adapter-claude\";\nimport codexAdapter from \"@michaelfromyeg/weft-adapter-codex\";\nimport copilotAdapter from \"@michaelfromyeg/weft-adapter-copilot\";\nimport cursorAdapter from \"@michaelfromyeg/weft-adapter-cursor\";\nimport type { HarnessDriver } from \"@michaelfromyeg/weft-adapter-kit\";\nimport opencodeAdapter from \"@michaelfromyeg/weft-adapter-opencode\";\nimport { AdapterRegistry } from \"@michaelfromyeg/weft-core\";\nimport { drivers } from \"@michaelfromyeg/weft-eval\";\nimport type { Target } from \"@michaelfromyeg/weft-schema\";\n\n/**\n * Wire every concrete adapter into a registry. The CLI sits at the top of the\n * dependency graph, so it -- not core -- knows the full adapter set. Community\n * adapters are added the same way.\n */\nexport function buildRegistry(): AdapterRegistry {\n return new AdapterRegistry()\n .register(claudeAdapter)\n .register(codexAdapter)\n .register(cursorAdapter)\n .register(copilotAdapter)\n .register(opencodeAdapter);\n}\n\n/** The headless eval drivers, keyed by Target (from @michaelfromyeg/weft-eval). */\nexport function allDrivers(): Record<Target, HarnessDriver> {\n return drivers;\n}\n\n/** Parse a comma-separated CLI value into a trimmed list, or undefined when empty. */\nexport function parseList(value: string | undefined): string[] | undefined {\n if (!value) return undefined;\n const items = value\n .split(\",\")\n .map((t) => t.trim())\n .filter(Boolean);\n return items.length > 0 ? items : undefined;\n}\n\n/** Parse a comma-separated --target value into a typed list, or undefined for all. */\nexport function parseTargets(value: string | undefined): Target[] | undefined {\n return parseList(value) as Target[] | undefined;\n}\n","import type { CompileResult, Diagnostic } from \"@michaelfromyeg/weft-core\";\nimport type { EvalReport } from \"@michaelfromyeg/weft-eval\";\nimport { log } from \"./logger\";\n\nexport function formatDiagnostic(d: Diagnostic): string {\n const tag = d.severity === \"error\" ? \"error\" : d.severity === \"warning\" ? \"warn\" : \"info\";\n const where = d.where ? `${d.where}: ` : \"\";\n return ` ${tag.padEnd(5)} ${where}${d.message}`;\n}\n\nexport function printDiagnostics(items: Diagnostic[]): void {\n for (const d of items) {\n const line = formatDiagnostic(d);\n if (d.severity === \"error\") log.error(line);\n else log.warn(line);\n }\n}\n\n/**\n * The trust summary required before first install (spec §11): what runs and on\n * whose authority. Lists components by kind, every executable artifact, every MCP\n * server, and the publisher-verification state.\n */\nexport function printTrustSummary(result: CompileResult): void {\n const { plugin } = result.fb;\n // Count from the components actually installed (accurate for piecemeal installs).\n const components = result.components;\n log.info(`\\nTrust summary for ${result.id}@${plugin.version}`);\n log.info(` publisher: ${plugin.owner.name} <${plugin.owner.namespace}> (unverified)`);\n\n const counts = new Map<string, number>();\n for (const c of components) counts.set(c.kind, (counts.get(c.kind) ?? 0) + 1);\n const summary = [...counts.entries()].map(([k, n]) => `${n} ${k}`).join(\", \");\n log.info(` components: ${summary || \"none\"}`);\n\n const executables = result.targets.flatMap((t) =>\n t.artifacts\n .filter((p) => p.artifact.executable)\n .map((p) => `${t.target}:${p.artifact.relPath}`),\n );\n log.info(\n executables.length > 0\n ? ` executables (placed DISABLED): ${executables.join(\", \")}`\n : \" executables: none\",\n );\n\n log.info(` mcp servers that will run: ${counts.get(\"mcp\") ?? 0}`);\n log.info(\" badges: valid (computed) | signed/verified/scanned: not yet\\n\");\n}\n\n/** Render an eval report: per-harness PASS/FAIL/UNTESTED with per-assertion status. */\nexport function printEvalReport(report: EvalReport): void {\n log.data(report);\n log.info(`\\nEval: ${report.component}`);\n for (const h of report.harnesses) {\n if (h.status === \"untested\") {\n log.info(` ${h.harness}: UNTESTED (${h.reason})`);\n continue;\n }\n log.info(` ${h.harness}: ${h.pass ? \"PASS\" : \"FAIL\"}`);\n for (const c of h.cases) {\n log.info(` - ${c.name}: ${c.pass ? \"pass\" : \"fail\"}`);\n for (const a of c.assertions) {\n log.info(` ${a.kind}: ${a.status} (${a.detail})`);\n }\n }\n }\n}\n","import { existsSync, mkdirSync, writeFileSync } from \"node:fs\";\nimport { basename, join, relative, resolve } from \"node:path\";\n\nexport interface ScaffoldOptions {\n dir: string;\n name?: string;\n namespace?: string;\n}\n\nexport interface ScaffoldResult {\n dir: string;\n name: string;\n files: string[];\n}\n\nfunction kebab(s: string): string {\n return (\n s\n .toLowerCase()\n .replace(/[^a-z0-9-]+/g, \"-\")\n .replace(/^-+|-+$/g, \"\") || \"my-plugin\"\n );\n}\n\n/** Create a minimal, valid plugin: weft.yaml + one sample skill. Never clobbers. */\nexport function scaffoldPlugin(opts: ScaffoldOptions): ScaffoldResult {\n const dir = resolve(opts.dir);\n mkdirSync(dir, { recursive: true });\n\n const manifestPath = join(dir, \"weft.yaml\");\n if (existsSync(manifestPath)) {\n throw new Error(`a plugin already exists at ${manifestPath}`);\n }\n\n const name = kebab(opts.name ?? basename(dir));\n const namespace = opts.namespace ?? \"com.example\";\n const files: string[] = [];\n\n const weftYaml = `name: ${name}\nversion: 0.1.0\nowner:\n name: Your Name\n namespace: ${namespace}\ndescription: A Weft plugin.\ncomponents:\n - skill: skills/hello\n`;\n writeFileSync(manifestPath, weftYaml);\n files.push(relative(dir, manifestPath));\n\n const skillDir = join(dir, \"skills\", \"hello\");\n mkdirSync(skillDir, { recursive: true });\n const skillMd = `---\nname: hello\ndescription: Greet the user and explain what this skill does.\n---\n\nWhen invoked, greet the user warmly and summarize the task at hand.\n`;\n const skillPath = join(skillDir, \"SKILL.md\");\n writeFileSync(skillPath, skillMd);\n files.push(relative(dir, skillPath));\n\n return { dir, name, files };\n}\n","import { createPrivateKey, createPublicKey } from \"node:crypto\";\nimport { existsSync, mkdirSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport {\n build,\n buildMarketplace,\n CompileError,\n generateSigningKeys,\n hasMarketplaceManifest,\n importNativePlugin,\n install,\n installMarketplace,\n WEFT_VERSION,\n lint,\n lockDirForScope,\n readLock,\n resolveSourceDir,\n signLock,\n uninstall,\n update,\n verifyArtifacts,\n} from \"@michaelfromyeg/weft-core\";\nimport { discoverEvals, runEval } from \"@michaelfromyeg/weft-eval\";\nimport {\n federate,\n fetchMcpRegistry,\n indexFromPluginDirs,\n publishCheck,\n serializeIndex,\n} from \"@michaelfromyeg/weft-index\";\nimport type { Scope, Target } from \"@michaelfromyeg/weft-schema\";\nimport { defineCommand, runMain } from \"citty\";\nimport { renderCliReference } from \"./cli-docs\";\nimport { log } from \"./logger\";\nimport { allDrivers, buildRegistry, parseList, parseTargets } from \"./registry\";\nimport { printDiagnostics, printEvalReport, printTrustSummary } from \"./report\";\nimport { scaffoldPlugin } from \"./scaffold\";\n\n/** Filter requested targets to harnesses actually present on this machine. */\nasync function detectPresent(\n requested: Target[],\n): Promise<{ present: Target[]; missing: Target[] }> {\n const drivers = allDrivers();\n const present: Target[] = [];\n const missing: Target[] = [];\n for (const t of requested) {\n if (await drivers[t]?.available()) present.push(t);\n else missing.push(t);\n }\n return { present, missing };\n}\n\nfunction countByTarget(written: { target: string }[]): Map<string, number> {\n const counts = new Map<string, number>();\n for (const w of written) counts.set(w.target, (counts.get(w.target) ?? 0) + 1);\n return counts;\n}\n\nfunction fail(err: unknown): never {\n if (err instanceof CompileError) {\n log.error(`\\n${err.message}:`);\n printDiagnostics(err.diagnostics);\n } else {\n log.error(`\\n${(err as Error).message}`);\n }\n process.exit(1);\n}\n\nconst initCmd = defineCommand({\n meta: { name: \"init\", description: \"Scaffold a new plugin (weft.yaml + a sample skill)\" },\n args: {\n dir: { type: \"positional\", required: false, default: \".\", description: \"Target directory\" },\n name: { type: \"string\", description: \"Plugin name (kebab-case)\" },\n namespace: { type: \"string\", description: \"Reverse-DNS namespace, e.g. com.acme\" },\n },\n run({ args }) {\n const created = scaffoldPlugin({\n dir: args.dir,\n name: args.name,\n namespace: args.namespace,\n });\n log.info(`Scaffolded plugin \"${created.name}\" in ${created.dir}`);\n for (const f of created.files) log.info(` + ${f}`);\n log.info(`\\nNext: weft validate ${args.dir} && weft build ${args.dir}`);\n },\n});\n\nconst validateCmd = defineCommand({\n meta: { name: \"validate\", description: \"Statically validate a plugin (the valid badge)\" },\n args: {\n dir: { type: \"positional\", required: false, default: \".\", description: \"Plugin directory\" },\n },\n run({ args }) {\n try {\n const result = lint(args.dir);\n const { items, hasErrors } = result.diagnostics;\n if (items.length > 0) printDiagnostics(items);\n if (hasErrors) {\n log.error(`\\n${result.id}: invalid`);\n process.exit(1);\n }\n log.data({ id: result.id, valid: true, components: result.plugin.components.length });\n log.info(`${result.id}: valid (${result.plugin.components.length} components)`);\n } catch (err) {\n fail(err);\n }\n },\n});\n\nconst buildCmd = defineCommand({\n meta: {\n name: \"build\",\n description: \"Compile a plugin (or a marketplace of plugins) to harness manifests\",\n },\n args: {\n dir: {\n type: \"positional\",\n required: false,\n default: \".\",\n description: \"Local dir, or a remote ref (github:/npm:/owner/repo, optional //subdir)\",\n },\n out: { type: \"string\", default: \".weft-out\", description: \"Output directory\" },\n target: { type: \"string\", description: \"Comma-separated targets (default: all registered)\" },\n },\n async run({ args }) {\n try {\n const registry = buildRegistry();\n const targets = parseTargets(args.target);\n // A remote ref (github:/git/owner-repo, optionally //subdir) clones into the\n // cache; a local path is used as-is.\n const { dir } = await resolveSourceDir(args.dir, process.cwd());\n\n // A marketplace.yaml packages many plugins into one catalog.\n if (hasMarketplaceManifest(dir)) {\n const { marketplace, plugins, written } = await buildMarketplace({\n marketplaceDir: dir,\n outDir: args.out,\n registry,\n targets,\n });\n log.data({\n marketplace: marketplace.name,\n plugins: plugins.length,\n out: args.out,\n files: Object.fromEntries(countByTarget(written)),\n });\n log.info(\n `Built marketplace ${marketplace.name} (${plugins.length} plugins) -> ${args.out}/`,\n );\n for (const [t, n] of countByTarget(written)) log.info(` ${t}: ${n} files`);\n return;\n }\n\n const { result, written } = await build({\n pluginDir: dir,\n outDir: args.out,\n registry,\n targets,\n });\n if (result.diagnostics.items.length > 0) printDiagnostics(result.diagnostics.items);\n log.data({ id: result.id, out: args.out, files: Object.fromEntries(countByTarget(written)) });\n log.info(`Built ${result.id} -> ${args.out}/`);\n for (const [t, n] of countByTarget(written)) {\n log.info(` ${t}: ${n} files (catalog at ${args.out}/${t})`);\n }\n } catch (err) {\n fail(err);\n }\n },\n});\n\nconst installCmd = defineCommand({\n meta: {\n name: \"install\",\n description: \"Compile + place a plugin (or a whole marketplace) into harness scopes\",\n },\n args: {\n dir: {\n type: \"positional\",\n required: false,\n default: \".\",\n description: \"Local dir, or a remote ref (github:/npm:/owner/repo, optional //subdir)\",\n },\n scope: { type: \"string\", default: \"project\", description: \"user | project\" },\n target: { type: \"string\", description: \"Comma-separated targets (default: all registered)\" },\n only: {\n type: \"string\",\n description: \"Comma-separated component names to install piecemeal (e.g. one skill)\",\n },\n all: {\n type: \"boolean\",\n description: \"Install to requested targets even if the harness is not detected\",\n },\n managed: {\n type: \"string\",\n description: \"Managed mode: only allow these namespaces (comma-separated allowlist)\",\n },\n cwd: { type: \"string\", description: \"Project root for project-scope placement (default: cwd)\" },\n },\n async run({ args }) {\n try {\n const registry = buildRegistry();\n const scope = (args.scope === \"user\" ? \"user\" : \"project\") as Scope;\n const requested = parseTargets(args.target) ?? registry.targets;\n const allow = parseList(args.managed);\n\n // Skip targets whose harness isn't on this machine, and say so (spec §9.2).\n let targets = requested;\n if (!args.all) {\n const { present, missing } = await detectPresent(requested);\n for (const t of missing) log.info(` skipped ${t}: harness not detected`);\n if (present.length === 0) {\n log.error(\"No requested harness is installed. Use --all to place anyway.\");\n process.exit(1);\n }\n targets = present;\n }\n\n // A remote ref (github:/git/npm/owner-repo, optionally //subdir) is fetched\n // into the cache; a local path is used as-is.\n const { dir } = await resolveSourceDir(args.dir, process.cwd());\n\n // A marketplace.yaml installs all of its plugins across the targets at once.\n if (hasMarketplaceManifest(dir)) {\n const mp = await installMarketplace({\n marketplaceDir: dir,\n scope,\n cwd: args.cwd ?? process.cwd(),\n registry,\n targets,\n ...(allow ? { managed: { allowNamespaces: allow } } : {}),\n });\n log.data({\n marketplace: mp.marketplace.name,\n plugins: mp.installs.map((i) => i.result.id),\n scope,\n lockfile: mp.lockPath,\n });\n log.info(\n `Installed marketplace ${mp.marketplace.name} (${mp.installs.length} plugins, ${scope})`,\n );\n for (const i of mp.installs) {\n log.info(\n ` ${i.result.id}@${i.result.fb.plugin.version}: ${i.entry.artifacts.length} artifacts`,\n );\n }\n log.info(` lockfile: ${mp.lockPath}`);\n return;\n }\n\n const result = await install({\n pluginDir: dir,\n scope,\n cwd: args.cwd ?? process.cwd(),\n registry,\n targets,\n only: parseList(args.only),\n ...(allow ? { managed: { allowNamespaces: allow } } : {}),\n });\n printTrustSummary(result.result);\n log.data({\n id: result.result.id,\n version: result.result.fb.plugin.version,\n scope,\n artifacts: result.entry.artifacts.length,\n lockfile: result.lockPath,\n });\n log.info(`Installed ${result.result.id}@${result.result.fb.plugin.version} (${scope})`);\n log.info(` ${result.entry.artifacts.length} artifacts placed`);\n if (result.secrets.resolved.length > 0) {\n const missing = result.secrets.resolved.filter((r) => r.source === \"missing\");\n log.info(\n ` config: ${result.secrets.resolved.length} declared` +\n (result.secrets.path ? ` -> ${result.secrets.path} (gitignored)` : \"\") +\n (missing.length > 0 ? `; missing: ${missing.map((m) => m.env).join(\", \")}` : \"\"),\n );\n }\n log.info(` lockfile: ${result.lockPath}`);\n } catch (err) {\n fail(err);\n }\n },\n});\n\nconst updateCmd = defineCommand({\n meta: {\n name: \"update\",\n description: \"Re-resolve refs, recompile, and re-place only artifacts whose hash changed\",\n },\n args: {\n dir: { type: \"positional\", required: false, default: \".\", description: \"Plugin directory\" },\n scope: { type: \"string\", default: \"project\", description: \"user | project\" },\n target: { type: \"string\", description: \"Comma-separated targets (default: all registered)\" },\n cwd: { type: \"string\", description: \"Project root for project-scope placement (default: cwd)\" },\n },\n async run({ args }) {\n try {\n const scope = (args.scope === \"user\" ? \"user\" : \"project\") as Scope;\n const cwd = args.cwd ?? process.cwd();\n // Default to the targets already in the target lockfile, so update matches\n // what install placed (not every registered adapter).\n const lock = readLock(lockDirForScope(scope, cwd));\n const lockedTargets = lock\n ? ([...new Set(lock.artifacts.map((a) => a.target))] as Target[])\n : undefined;\n const result = await update({\n pluginDir: args.dir,\n scope,\n cwd,\n registry: buildRegistry(),\n targets: parseTargets(args.target) ?? lockedTargets,\n });\n log.data({ id: result.id, changed: result.changed });\n log.info(`Updated ${result.id}: ${result.changed.length} artifact(s) changed`);\n for (const p of result.changed) log.info(` ~ ${p}`);\n } catch (err) {\n fail(err);\n }\n },\n});\n\nconst evalCmd = defineCommand({\n meta: {\n name: \"eval\",\n description: \"Run a component's evals against the real harnesses (reports UNTESTED honestly)\",\n },\n args: {\n dir: { type: \"positional\", required: false, default: \".\", description: \"Plugin directory\" },\n component: { type: \"string\", description: \"Only eval this component leaf name\" },\n harness: { type: \"string\", description: \"Restrict to these harnesses (comma-separated)\" },\n },\n async run({ args }) {\n try {\n const registry = buildRegistry();\n const drivers = allDrivers();\n const discovered = discoverEvals(args.dir).filter(\n (d) => !args.component || d.componentLeaf === args.component,\n );\n if (discovered.length === 0) {\n log.info(\"No evals found (a component adds them with an `evals:` file).\");\n return;\n }\n const onlyHarness = parseTargets(args.harness);\n let anyFail = false;\n for (const d of discovered) {\n const evalFile = onlyHarness\n ? {\n ...d.evalFile,\n harnesses: d.evalFile.harnesses.filter((h) => onlyHarness.includes(h)),\n }\n : d.evalFile;\n const report = await runEval({\n evalFile,\n pluginDir: args.dir,\n componentLeaf: d.componentLeaf,\n registry,\n drivers,\n });\n printEvalReport(report);\n if (report.harnesses.some((h) => h.status === \"tested\" && !h.pass)) anyFail = true;\n }\n if (anyFail) process.exit(1);\n } catch (err) {\n fail(err);\n }\n },\n});\n\nconst publishCmd = defineCommand({\n meta: {\n name: \"publish\",\n description: \"Run the deterministic publish gate (static valid + trace/output evals)\",\n },\n args: {\n dir: { type: \"positional\", required: false, default: \".\", description: \"Plugin directory\" },\n snapshot: {\n type: \"boolean\",\n description: \"Snapshot eval scores into evals/.baselines/ for the next release\",\n },\n },\n async run({ args }) {\n try {\n const res = await publishCheck(args.dir, {\n registry: buildRegistry(),\n drivers: allDrivers(),\n snapshot: Boolean(args.snapshot),\n });\n log.data({\n id: res.id,\n version: res.version,\n ok: res.ok,\n valid: res.validPassed,\n scanClean: res.scan.clean,\n badges: res.badges,\n harnessCoverage: res.harnessCoverage,\n });\n log.info(`Publish check: ${res.id}@${res.version}`);\n if (res.diagnostics.length > 0) printDiagnostics(res.diagnostics);\n log.info(` valid: ${res.validPassed ? \"yes\" : \"NO\"}`);\n log.info(` scan: ${res.scan.clean ? \"clean\" : `${res.scan.findings.length} finding(s)`}`);\n log.info(` badges: ${res.badges.join(\", \") || \"none\"}`);\n log.info(` harness coverage: ${res.harnessCoverage.join(\", \") || \"none\"}`);\n for (const r of res.evalReports) printEvalReport(r);\n if (!res.ok) {\n log.error(\"\\nPublish BLOCKED: the deterministic tier failed.\");\n process.exit(1);\n }\n log.info(\"\\nPublish gate passed.\");\n } catch (err) {\n fail(err);\n }\n },\n});\n\nconst signCmd = defineCommand({\n meta: {\n name: \"sign\",\n description:\n \"Sign weft.lock's artifact set (ed25519) -> weft.sig + weft.pub (the signed badge)\",\n },\n args: {\n dir: {\n type: \"positional\",\n required: false,\n default: \".\",\n description: \"Plugin dir with weft.lock\",\n },\n },\n run({ args }) {\n try {\n const lock = readLock(args.dir);\n if (!lock) {\n log.error(\"no weft.lock found (run `weft install` first)\");\n process.exit(1);\n }\n const weftDir = join(args.dir, \".weft\");\n mkdirSync(weftDir, { recursive: true });\n writeFileSync(join(weftDir, \".gitignore\"), \"*\\n\");\n const keyPath = join(weftDir, \"signing.key\");\n\n let privateKey: ReturnType<typeof createPrivateKey>;\n if (existsSync(keyPath)) {\n privateKey = createPrivateKey(readFileSync(keyPath));\n } else {\n const keys = generateSigningKeys();\n privateKey = keys.privateKey;\n writeFileSync(keyPath, keys.privateKey.export({ type: \"pkcs8\", format: \"pem\" }));\n writeFileSync(\n join(args.dir, \"weft.pub\"),\n keys.publicKey.export({ type: \"spki\", format: \"pem\" }),\n );\n }\n writeFileSync(join(args.dir, \"weft.sig\"), `${signLock(lock, privateKey)}\\n`);\n log.info(\n `Signed ${lock.artifacts.length} artifacts -> weft.sig (key kept in .weft/, public key in weft.pub)`,\n );\n } catch (err) {\n fail(err);\n }\n },\n});\n\nconst verifyCmd = defineCommand({\n meta: {\n name: \"verify\",\n description: \"Verify weft.sig against weft.lock and the on-disk artifacts\",\n },\n args: {\n dir: {\n type: \"positional\",\n required: false,\n default: \".\",\n description: \"Plugin dir with weft.lock\",\n },\n },\n run({ args }) {\n try {\n const lock = readLock(args.dir);\n if (!lock) {\n log.error(\"no weft.lock found\");\n process.exit(1);\n }\n const sig = readFileSync(join(args.dir, \"weft.sig\"), \"utf8\").trim();\n const publicKey = createPublicKey(readFileSync(join(args.dir, \"weft.pub\")));\n const res = verifyArtifacts(lock, publicKey, sig);\n log.data({ signatureValid: res.signatureValid, tampered: res.tampered });\n log.info(`signature: ${res.signatureValid ? \"valid\" : \"INVALID\"}`);\n log.info(`tampered artifacts: ${res.tampered.length}`);\n for (const p of res.tampered) log.info(` ! ${p}`);\n if (!res.signatureValid || res.tampered.length > 0) process.exit(1);\n log.info(\"signed badge verified.\");\n } catch (err) {\n fail(err);\n }\n },\n});\n\nconst indexCmd = defineCommand({\n meta: {\n name: \"index\",\n description: \"Build a metadata index from plugin dirs (optionally federating the MCP Registry)\",\n },\n args: {\n dir: { type: \"positional\", required: false, default: \".\", description: \"Plugin directories\" },\n out: { type: \"string\", default: \"index.json\", description: \"Output index file\" },\n federate: { type: \"boolean\", description: \"Ingest the MCP Registry (GET /v0.1/servers)\" },\n },\n async run({ args }) {\n try {\n // citty puts every positional in `_`; default to the current dir when none.\n const positionals = (args._ as string[] | undefined) ?? [];\n const dirs = positionals.length > 0 ? positionals : [\".\"];\n let index = await indexFromPluginDirs(dirs);\n if (args.federate) {\n const servers = await fetchMcpRegistry({ limit: 30 });\n index = federate(index, servers, new Date().toISOString());\n }\n writeFileSync(args.out, serializeIndex(index));\n const fed = args.federate ? `, federated ${index.federated?.length ?? 0} source(s)` : \"\";\n log.data({\n plugins: index.plugins.length,\n federated: index.federated?.length ?? 0,\n out: args.out,\n });\n log.info(`Wrote index (${index.plugins.length} plugins${fed}) -> ${args.out}`);\n } catch (err) {\n fail(err);\n }\n },\n});\n\nconst importCmd = defineCommand({\n meta: {\n name: \"import\",\n description: \"Reverse-compile an existing native plugin/marketplace into a Weft plugin\",\n },\n args: {\n dir: {\n type: \"positional\",\n required: false,\n default: \".\",\n description: \"Dir with an existing native plugin or marketplace\",\n },\n from: { type: \"string\", default: \"claude\", description: \"Source harness format\" },\n out: { type: \"string\", default: \"imported\", description: \"Output directory\" },\n namespace: {\n type: \"string\",\n description: \"Reverse-DNS namespace to assign (default com.imported)\",\n },\n },\n run({ args }) {\n try {\n const adapter = buildRegistry().get(args.from as Target);\n if (!adapter) {\n log.error(`unknown source harness \"${args.from}\"`);\n process.exit(1);\n }\n const res = importNativePlugin({\n dir: args.dir,\n adapter,\n outDir: args.out,\n ...(args.namespace ? { namespace: args.namespace } : {}),\n });\n log.data({\n kind: res.kind,\n name: res.name,\n manifest: res.manifestPath,\n out: res.outDir,\n ...(res.kind === \"plugin\" ? { files: res.fileCount } : {}),\n });\n log.info(`Imported ${res.kind} \"${res.name}\" -> ${res.manifestPath}`);\n if (res.kind === \"plugin\") log.info(` ${res.fileCount} component file(s)`);\n log.info(` next: weft build ${res.outDir}`);\n } catch (err) {\n fail(err);\n }\n },\n});\n\nconst uninstallCmd = defineCommand({\n meta: {\n name: \"uninstall\",\n description: \"Remove what install placed into this project (read from its weft.lock)\",\n },\n args: {\n dir: {\n type: \"positional\",\n required: false,\n default: \".\",\n description: \"Install target holding weft.lock (default: derived from --scope)\",\n },\n scope: { type: \"string\", default: \"project\", description: \"user | project\" },\n plugin: {\n type: \"string\",\n description: \"Remove only this plugin (id or bare name); default removes all\",\n },\n },\n run({ args }) {\n try {\n const scope = (args.scope === \"user\" ? \"user\" : \"project\") as Scope;\n // An explicit dir wins; otherwise read the lock from the scope's target\n // (the project cwd for project scope, ~/.weft for user scope).\n const dir = args.dir === \".\" ? lockDirForScope(scope, process.cwd()) : args.dir;\n const res = uninstall({ dir, ...(args.plugin ? { plugin: args.plugin } : {}) });\n log.data({ removed: res.removed, plugins: res.plugins });\n log.info(`Uninstalled ${res.plugins.length} plugin(s), ${res.removed.length} artifact(s)`);\n } catch (err) {\n fail(err);\n }\n },\n});\n\nconst docsCmd = defineCommand({\n meta: {\n name: \"docs\",\n description: \"Print the full CLI reference (a CLI map), generated from the command tree\",\n },\n args: {\n out: {\n type: \"string\",\n description: \"Write the Markdown reference to this file instead of stdout\",\n },\n },\n async run({ args }) {\n const md = await renderCliReference(main);\n if (args.out) {\n writeFileSync(args.out, md);\n log.info(`Wrote CLI reference to ${args.out}`);\n } else {\n process.stdout.write(md);\n }\n },\n});\n\nconst main = defineCommand({\n meta: {\n name: \"weft\",\n version: WEFT_VERSION,\n description: \"Author once, compile to every coding-agent harness.\",\n },\n subCommands: {\n init: initCmd,\n validate: validateCmd,\n build: buildCmd,\n install: installCmd,\n uninstall: uninstallCmd,\n update: updateCmd,\n import: importCmd,\n eval: evalCmd,\n publish: publishCmd,\n sign: signCmd,\n verify: verifyCmd,\n index: indexCmd,\n docs: docsCmd,\n },\n});\n\nrunMain(main);\n"]}
|
package/package.json
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@michaelfromyeg/weft-cli",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "The `weft` CLI: a thin shell over @michaelfromyeg/weft-core and the harness adapters.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"bin": {
|
|
7
|
+
"weft": "./dist/index.js"
|
|
8
|
+
},
|
|
9
|
+
"main": "./dist/index.js",
|
|
10
|
+
"files": [
|
|
11
|
+
"dist"
|
|
12
|
+
],
|
|
13
|
+
"dependencies": {
|
|
14
|
+
"citty": "^0.1.6",
|
|
15
|
+
"@michaelfromyeg/weft-adapter-claude": "1.0.0",
|
|
16
|
+
"@michaelfromyeg/weft-adapter-codex": "1.0.0",
|
|
17
|
+
"@michaelfromyeg/weft-adapter-cursor": "1.0.0",
|
|
18
|
+
"@michaelfromyeg/weft-adapter-kit": "1.0.0",
|
|
19
|
+
"@michaelfromyeg/weft-adapter-copilot": "1.0.0",
|
|
20
|
+
"@michaelfromyeg/weft-adapter-opencode": "1.0.0",
|
|
21
|
+
"@michaelfromyeg/weft-core": "1.0.0",
|
|
22
|
+
"@michaelfromyeg/weft-eval": "1.0.0",
|
|
23
|
+
"@michaelfromyeg/weft-schema": "1.0.0",
|
|
24
|
+
"@michaelfromyeg/weft-index": "1.0.0"
|
|
25
|
+
},
|
|
26
|
+
"license": "MIT",
|
|
27
|
+
"author": "Michael DeMarco",
|
|
28
|
+
"homepage": "https://github.com/michaelfromyeg/weft#readme",
|
|
29
|
+
"repository": {
|
|
30
|
+
"type": "git",
|
|
31
|
+
"url": "git+https://github.com/michaelfromyeg/weft.git",
|
|
32
|
+
"directory": "packages/cli"
|
|
33
|
+
},
|
|
34
|
+
"bugs": {
|
|
35
|
+
"url": "https://github.com/michaelfromyeg/weft/issues"
|
|
36
|
+
},
|
|
37
|
+
"keywords": [
|
|
38
|
+
"weft",
|
|
39
|
+
"coding-agent",
|
|
40
|
+
"ai-agent",
|
|
41
|
+
"claude-code",
|
|
42
|
+
"codex",
|
|
43
|
+
"cursor",
|
|
44
|
+
"copilot",
|
|
45
|
+
"opencode",
|
|
46
|
+
"mcp",
|
|
47
|
+
"plugin",
|
|
48
|
+
"skill",
|
|
49
|
+
"compiler"
|
|
50
|
+
],
|
|
51
|
+
"publishConfig": {
|
|
52
|
+
"access": "public"
|
|
53
|
+
},
|
|
54
|
+
"scripts": {
|
|
55
|
+
"build": "tsup"
|
|
56
|
+
}
|
|
57
|
+
}
|