@sequelsh/cli 0.1.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +6 -3
- package/dist/index.js +403 -51
- package/dist/index.js.map +1 -1
- package/package.json +2 -1
package/README.md
CHANGED
|
@@ -25,14 +25,17 @@ The installed command is `sequel`.
|
|
|
25
25
|
```bash
|
|
26
26
|
sequel login # sign in via your browser (OAuth)
|
|
27
27
|
sequel connect # connect a data source
|
|
28
|
-
sequel install # add the Sequel MCP server to a coding agent
|
|
28
|
+
sequel install # add the Sequel MCP server (and skill, where supported) to a coding agent
|
|
29
|
+
sequel skills # list the playbooks your agent can follow (no login needed)
|
|
30
|
+
sequel skills show seo # print one playbook
|
|
29
31
|
```
|
|
30
32
|
|
|
31
33
|
## Commands
|
|
32
34
|
|
|
33
35
|
| Command | Description |
|
|
34
36
|
| --- | --- |
|
|
35
|
-
| `sequel
|
|
37
|
+
| `sequel upgrade` | Upgrade the CLI to the latest version from npm. |
|
|
38
|
+
| `sequel login` | Sign in to Sequel. `--no-browser` prints the sign-in URL instead of opening it. |
|
|
36
39
|
| `sequel logout` | Sign out and remove cached credentials. |
|
|
37
40
|
| `sequel switch` | Switch the active organization. |
|
|
38
41
|
| `sequel connect [source]` | Connect a new data source (interactive, or pass a connector id). |
|
|
@@ -40,7 +43,7 @@ sequel install # add the Sequel MCP server to a coding agent
|
|
|
40
43
|
| `sequel sources active` | List sources with live health status. |
|
|
41
44
|
| `sequel sources info <id>` | Show details for a source. |
|
|
42
45
|
| `sequel sources delete <id>` | Delete a source. |
|
|
43
|
-
| `sequel install [agent]` | Install the Sequel MCP server into a coding agent (Claude, Cursor, VS Code, and more). |
|
|
46
|
+
| `sequel install [agent]` | Install the Sequel MCP server into a coding agent (Claude, Cursor, VS Code, and more). `--scope global\|local` skips the scope prompt; with an agent slug it runs without prompting. |
|
|
44
47
|
| `sequel search <use case>` | Find the right tools for a use case across your sources. |
|
|
45
48
|
| `sequel execute` | Execute a tool against a connection. |
|
|
46
49
|
|
package/dist/index.js
CHANGED
|
@@ -7,6 +7,7 @@ import { homedir, platform } from "node:os";
|
|
|
7
7
|
import { dirname, join } from "node:path";
|
|
8
8
|
import { chmodSync, existsSync, mkdirSync, readFileSync, rmSync, writeFileSync } from "node:fs";
|
|
9
9
|
import pc from "picocolors";
|
|
10
|
+
import * as p$5 from "@clack/prompts";
|
|
10
11
|
import * as p$4 from "@clack/prompts";
|
|
11
12
|
import * as p$3 from "@clack/prompts";
|
|
12
13
|
import * as p$2 from "@clack/prompts";
|
|
@@ -14,10 +15,90 @@ import * as p$1 from "@clack/prompts";
|
|
|
14
15
|
import * as p from "@clack/prompts";
|
|
15
16
|
import { execFileSync } from "node:child_process";
|
|
16
17
|
import YAML from "yaml";
|
|
18
|
+
import { writeFile } from "node:fs/promises";
|
|
17
19
|
|
|
20
|
+
//#region package.json
|
|
21
|
+
var name = "@sequelsh/cli";
|
|
22
|
+
var version = "0.3.0";
|
|
23
|
+
var description = "Sequel CLI — connect data sources and run tools from your terminal.";
|
|
24
|
+
var license = "MIT";
|
|
25
|
+
var type = "module";
|
|
26
|
+
var bin = { "sequel": "./dist/index.js" };
|
|
27
|
+
var files = ["dist"];
|
|
28
|
+
var exports = { ".": {
|
|
29
|
+
"import": "./dist/index.js",
|
|
30
|
+
"types": "./dist/index.d.ts"
|
|
31
|
+
} };
|
|
32
|
+
var engines = { "node": ">=18" };
|
|
33
|
+
var repository = {
|
|
34
|
+
"type": "git",
|
|
35
|
+
"url": "git+https://github.com/sequelsh/sequel.git",
|
|
36
|
+
"directory": "packages/cli"
|
|
37
|
+
};
|
|
38
|
+
var homepage = "https://sequel.sh";
|
|
39
|
+
var keywords = [
|
|
40
|
+
"sequel",
|
|
41
|
+
"cli",
|
|
42
|
+
"mcp",
|
|
43
|
+
"sql",
|
|
44
|
+
"data",
|
|
45
|
+
"ai",
|
|
46
|
+
"agents"
|
|
47
|
+
];
|
|
48
|
+
var publishConfig = { "access": "public" };
|
|
49
|
+
var scripts = {
|
|
50
|
+
"dev": "bun run src/index.ts",
|
|
51
|
+
"cli": "bun run src/index.ts",
|
|
52
|
+
"build": "tsdown",
|
|
53
|
+
"build:binaries": "bun run scripts/build-binaries.ts",
|
|
54
|
+
"test": "vitest run",
|
|
55
|
+
"test:watch": "vitest",
|
|
56
|
+
"typecheck": "tsc --noEmit",
|
|
57
|
+
"clean": "rm -rf dist"
|
|
58
|
+
};
|
|
59
|
+
var dependencies = {
|
|
60
|
+
"@clack/prompts": "^0.8.2",
|
|
61
|
+
"commander": "^12.1.0",
|
|
62
|
+
"open": "^10.1.0",
|
|
63
|
+
"picocolors": "^1.1.1",
|
|
64
|
+
"yaml": "^2.5.1"
|
|
65
|
+
};
|
|
66
|
+
var devDependencies = {
|
|
67
|
+
"@sequel/mcp-clients": "workspace:*",
|
|
68
|
+
"@sequel/typescript-config": "workspace:*",
|
|
69
|
+
"@types/node": "^22.10.0",
|
|
70
|
+
"tsdown": "^0.9.0",
|
|
71
|
+
"typescript": "^5.7.0",
|
|
72
|
+
"vitest": "^3.0.0"
|
|
73
|
+
};
|
|
74
|
+
var package_default = {
|
|
75
|
+
name,
|
|
76
|
+
version,
|
|
77
|
+
description,
|
|
78
|
+
license,
|
|
79
|
+
type,
|
|
80
|
+
bin,
|
|
81
|
+
files,
|
|
82
|
+
exports,
|
|
83
|
+
engines,
|
|
84
|
+
repository,
|
|
85
|
+
homepage,
|
|
86
|
+
keywords,
|
|
87
|
+
publishConfig,
|
|
88
|
+
scripts,
|
|
89
|
+
dependencies,
|
|
90
|
+
devDependencies
|
|
91
|
+
};
|
|
92
|
+
|
|
93
|
+
//#endregion
|
|
18
94
|
//#region src/lib/config.ts
|
|
19
95
|
/** Default production API base. Override with SEQUEL_API_URL for local/dev. */
|
|
20
96
|
const DEFAULT_API_URL = "https://api.sequel.sh";
|
|
97
|
+
/** Default marketing site, which publishes the Sequel skill. Override with SEQUEL_SITE_URL. */
|
|
98
|
+
const DEFAULT_SITE_URL = "https://sequel.sh";
|
|
99
|
+
function resolveSiteUrl() {
|
|
100
|
+
return process.env.SEQUEL_SITE_URL || DEFAULT_SITE_URL;
|
|
101
|
+
}
|
|
21
102
|
/** Directory holding the CLI's state. Overridable for tests. */
|
|
22
103
|
function configDir() {
|
|
23
104
|
return process.env.SEQUEL_CONFIG_DIR || join(homedir(), ".sequel");
|
|
@@ -408,14 +489,21 @@ function search(useCase, connectionIds) {
|
|
|
408
489
|
}
|
|
409
490
|
});
|
|
410
491
|
}
|
|
411
|
-
async function createApiKey(name) {
|
|
492
|
+
async function createApiKey(name$1) {
|
|
412
493
|
const orgId = await activeOrgId();
|
|
413
494
|
return request(`/organizations/${orgId}/api-keys`, {
|
|
414
495
|
method: "POST",
|
|
415
496
|
org: "none",
|
|
416
|
-
body: { name }
|
|
497
|
+
body: { name: name$1 }
|
|
417
498
|
});
|
|
418
499
|
}
|
|
500
|
+
/** Get a signed URL to download a file produced in a session (by sequel_execute / workbench). */
|
|
501
|
+
function getFileDownloadUrl(sessionId, path) {
|
|
502
|
+
return request("/files/download", { query: {
|
|
503
|
+
session_id: sessionId,
|
|
504
|
+
path
|
|
505
|
+
} });
|
|
506
|
+
}
|
|
419
507
|
|
|
420
508
|
//#endregion
|
|
421
509
|
//#region src/lib/output.ts
|
|
@@ -449,13 +537,14 @@ function renderTable(rows, columns) {
|
|
|
449
537
|
return `${header}\n${pc.dim(sep)}\n${body}`;
|
|
450
538
|
}
|
|
451
539
|
function printTable(rows, columns) {
|
|
540
|
+
if (jsonMode) return;
|
|
452
541
|
process.stdout.write(`${renderTable(rows, columns)}\n`);
|
|
453
542
|
}
|
|
454
543
|
function success(message) {
|
|
455
|
-
process.stdout.write(`${pc.green("✓")} ${message}\n`);
|
|
544
|
+
(jsonMode ? process.stderr : process.stdout).write(`${pc.green("✓")} ${message}\n`);
|
|
456
545
|
}
|
|
457
546
|
function info(message) {
|
|
458
|
-
process.stdout.write(`${message}\n`);
|
|
547
|
+
(jsonMode ? process.stderr : process.stdout).write(`${message}\n`);
|
|
459
548
|
}
|
|
460
549
|
function fail(message) {
|
|
461
550
|
process.stderr.write(`${pc.red("✗")} ${message}\n`);
|
|
@@ -463,12 +552,23 @@ function fail(message) {
|
|
|
463
552
|
|
|
464
553
|
//#endregion
|
|
465
554
|
//#region src/commands/login.ts
|
|
466
|
-
async function loginCommand() {
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
const
|
|
555
|
+
async function loginCommand(opts = {}) {
|
|
556
|
+
const json = isJsonMode();
|
|
557
|
+
const openBrowser = opts.browser !== false;
|
|
558
|
+
const opening = openBrowser ? "Opening your browser to authorize…" : "Sign in with the URL below…";
|
|
559
|
+
if (json) info(opening);
|
|
560
|
+
else {
|
|
561
|
+
p$5.intro(pc.cyan("Sign in to Sequel"));
|
|
562
|
+
p$5.log.info(opening);
|
|
563
|
+
}
|
|
564
|
+
const res = await runLoginFlow({ silent: !openBrowser });
|
|
565
|
+
if (json) return printJson({
|
|
566
|
+
status: "logged_in",
|
|
567
|
+
user: res.user,
|
|
568
|
+
org: res.org ?? null
|
|
569
|
+
});
|
|
470
570
|
success(`Logged in as ${pc.bold(res.user.email)}${res.org ? ` · ${pc.bold(res.org.name)}` : ""}`);
|
|
471
|
-
p$
|
|
571
|
+
p$5.outro("You're all set. Try `sequel sources list` or `sequel connect`.");
|
|
472
572
|
}
|
|
473
573
|
|
|
474
574
|
//#endregion
|
|
@@ -476,16 +576,19 @@ async function loginCommand() {
|
|
|
476
576
|
async function logoutCommand() {
|
|
477
577
|
const config = readConfig();
|
|
478
578
|
if (!isLoggedIn$1(config)) {
|
|
579
|
+
if (isJsonMode()) return printJson({ status: "not_logged_in" });
|
|
479
580
|
info("You are not logged in.");
|
|
480
581
|
return;
|
|
481
582
|
}
|
|
482
583
|
clearConfig();
|
|
584
|
+
if (isJsonMode()) return printJson({ status: "logged_out" });
|
|
483
585
|
success("Logged out. Cached credentials removed from ~/.sequel/auth.json.");
|
|
484
586
|
}
|
|
485
587
|
|
|
486
588
|
//#endregion
|
|
487
589
|
//#region src/commands/switch.ts
|
|
488
590
|
async function switchCommand() {
|
|
591
|
+
if (isJsonMode()) throw new Error("`sequel switch` is interactive (it prompts for an organization) — run it in a terminal, not piped/--json.");
|
|
489
592
|
const config = readConfig();
|
|
490
593
|
if (!isLoggedIn$1(config)) throw new Error("Not logged in. Run `sequel login` first.");
|
|
491
594
|
let orgs = config.orgs ?? [];
|
|
@@ -498,7 +601,7 @@ async function switchCommand() {
|
|
|
498
601
|
});
|
|
499
602
|
} catch {}
|
|
500
603
|
if (orgs.length === 0) throw new Error("No organizations available for this account.");
|
|
501
|
-
const selection = await p$
|
|
604
|
+
const selection = await p$4.select({
|
|
502
605
|
message: "Switch to organization",
|
|
503
606
|
options: orgs.map((o) => ({
|
|
504
607
|
value: o.id,
|
|
@@ -506,8 +609,8 @@ async function switchCommand() {
|
|
|
506
609
|
hint: config.tokens[o.id] ? o.role : "sign-in required"
|
|
507
610
|
}))
|
|
508
611
|
});
|
|
509
|
-
if (p$
|
|
510
|
-
p$
|
|
612
|
+
if (p$4.isCancel(selection)) {
|
|
613
|
+
p$4.cancel("Cancelled.");
|
|
511
614
|
return;
|
|
512
615
|
}
|
|
513
616
|
const orgId = selection;
|
|
@@ -521,7 +624,7 @@ async function switchCommand() {
|
|
|
521
624
|
success(`Switched to ${pc.bold(org?.name ?? orgId)}.`);
|
|
522
625
|
return;
|
|
523
626
|
}
|
|
524
|
-
p$
|
|
627
|
+
p$4.log.info(`You haven't authorized ${pc.bold(org?.name ?? orgId)} yet — opening your browser…`);
|
|
525
628
|
const res = await runLoginFlow();
|
|
526
629
|
success(`Switched to ${pc.bold(res.org?.name ?? res.organizationId)}.`);
|
|
527
630
|
}
|
|
@@ -560,13 +663,14 @@ async function pollLink(token) {
|
|
|
560
663
|
};
|
|
561
664
|
}
|
|
562
665
|
async function connectCommand(source) {
|
|
666
|
+
if (isJsonMode()) throw new Error("`sequel connect` is interactive (it prompts for credentials/consent) — run it in a terminal, not piped/--json.");
|
|
563
667
|
const connectors = await listConnectors();
|
|
564
668
|
let connector;
|
|
565
669
|
if (source) {
|
|
566
670
|
connector = connectors.find((c) => c.id === source);
|
|
567
671
|
if (!connector) throw new Error(`Unknown connector "${source}". Available: ${connectors.map((c) => c.id).join(", ")}`);
|
|
568
672
|
} else {
|
|
569
|
-
const choice = await p$
|
|
673
|
+
const choice = await p$3.select({
|
|
570
674
|
message: "Which data source do you want to connect?",
|
|
571
675
|
options: connectors.slice().sort((a, b) => a.appType.localeCompare(b.appType) || a.name.localeCompare(b.name)).map((c) => ({
|
|
572
676
|
value: c.id,
|
|
@@ -574,38 +678,38 @@ async function connectCommand(source) {
|
|
|
574
678
|
hint: c.appType
|
|
575
679
|
}))
|
|
576
680
|
});
|
|
577
|
-
if (p$
|
|
578
|
-
p$
|
|
681
|
+
if (p$3.isCancel(choice)) {
|
|
682
|
+
p$3.cancel("Cancelled.");
|
|
579
683
|
return;
|
|
580
684
|
}
|
|
581
685
|
connector = connectors.find((c) => c.id === choice);
|
|
582
686
|
}
|
|
583
|
-
p$
|
|
687
|
+
p$3.intro(`Connect ${pc.bold(connector.name)}`);
|
|
584
688
|
if (!isOAuth(connector)) {
|
|
585
689
|
const fields = fieldsFor(connector);
|
|
586
690
|
const credentials = {};
|
|
587
691
|
for (const field of fields) {
|
|
588
692
|
const secret = SECRET_RE.test(field);
|
|
589
|
-
const value = await (secret ? p$
|
|
590
|
-
if (p$
|
|
591
|
-
p$
|
|
693
|
+
const value = await (secret ? p$3.password : p$3.text)({ message: field });
|
|
694
|
+
if (p$3.isCancel(value)) {
|
|
695
|
+
p$3.cancel("Cancelled.");
|
|
592
696
|
return;
|
|
593
697
|
}
|
|
594
698
|
credentials[field] = value;
|
|
595
699
|
}
|
|
596
|
-
const name = await p$
|
|
700
|
+
const name$1 = await p$3.text({
|
|
597
701
|
message: "Name for this source (optional)",
|
|
598
702
|
placeholder: connector.name
|
|
599
703
|
});
|
|
600
|
-
if (p$
|
|
601
|
-
p$
|
|
704
|
+
if (p$3.isCancel(name$1)) {
|
|
705
|
+
p$3.cancel("Cancelled.");
|
|
602
706
|
return;
|
|
603
707
|
}
|
|
604
|
-
const s$1 = p$
|
|
708
|
+
const s$1 = p$3.spinner();
|
|
605
709
|
s$1.start("Validating credentials…");
|
|
606
710
|
const res$1 = await createLink(connector.id, {
|
|
607
711
|
credentials,
|
|
608
|
-
...name ? { name } : {}
|
|
712
|
+
...name$1 ? { name: name$1 } : {}
|
|
609
713
|
});
|
|
610
714
|
if (res$1.status === "success") {
|
|
611
715
|
s$1.stop("Connected.");
|
|
@@ -627,7 +731,7 @@ async function connectCommand(source) {
|
|
|
627
731
|
}
|
|
628
732
|
open(res.redirect_url).catch(() => {});
|
|
629
733
|
info(`Complete authorization in your browser:\n${res.redirect_url}`);
|
|
630
|
-
const s = p$
|
|
734
|
+
const s = p$3.spinner();
|
|
631
735
|
s.start("Waiting for you to finish in the browser…");
|
|
632
736
|
const result = await pollLink(res.link_token);
|
|
633
737
|
if (result.ok) {
|
|
@@ -654,7 +758,7 @@ async function pickConnection(message) {
|
|
|
654
758
|
info("No sources connected yet. Run `sequel connect`.");
|
|
655
759
|
return void 0;
|
|
656
760
|
}
|
|
657
|
-
const choice = await p$
|
|
761
|
+
const choice = await p$2.select({
|
|
658
762
|
message,
|
|
659
763
|
options: all.map((c) => ({
|
|
660
764
|
value: c.shortId,
|
|
@@ -662,7 +766,7 @@ async function pickConnection(message) {
|
|
|
662
766
|
hint: c.type
|
|
663
767
|
}))
|
|
664
768
|
});
|
|
665
|
-
if (p$
|
|
769
|
+
if (p$2.isCancel(choice)) return void 0;
|
|
666
770
|
return all.find((c) => c.shortId === choice);
|
|
667
771
|
}
|
|
668
772
|
function toRow(c) {
|
|
@@ -731,8 +835,8 @@ async function sourcesInfo(idOrShort) {
|
|
|
731
835
|
async function sourcesDelete(idOrShort) {
|
|
732
836
|
const conn = idOrShort ? await resolveConnection(idOrShort) : await pickConnection("Source to delete");
|
|
733
837
|
if (!conn) return;
|
|
734
|
-
const confirmed = await p$
|
|
735
|
-
if (p$
|
|
838
|
+
const confirmed = await p$2.confirm({ message: `Delete ${pc.bold(conn.name)} (${conn.shortId})? This cannot be undone.` });
|
|
839
|
+
if (p$2.isCancel(confirmed) || !confirmed) {
|
|
736
840
|
info("Cancelled.");
|
|
737
841
|
return;
|
|
738
842
|
}
|
|
@@ -741,8 +845,48 @@ async function sourcesDelete(idOrShort) {
|
|
|
741
845
|
}
|
|
742
846
|
|
|
743
847
|
//#endregion
|
|
744
|
-
//#region src/
|
|
848
|
+
//#region src/commands/skills.ts
|
|
849
|
+
async function publicGet(path) {
|
|
850
|
+
const res = await fetch(`${resolveApiUrl(readConfig())}${path}`, { headers: { Accept: "application/json" } });
|
|
851
|
+
if (res.status === 404) throw new Error(`No skill found matching "${path.split("/").pop()}". Run \`sequel skills list\`.`);
|
|
852
|
+
if (!res.ok) throw new Error(`Request failed (${res.status})`);
|
|
853
|
+
return await res.json();
|
|
854
|
+
}
|
|
855
|
+
async function skillsList() {
|
|
856
|
+
const skills$1 = await publicGet("/marketplace/skills");
|
|
857
|
+
const rows = skills$1.map((s) => ({
|
|
858
|
+
id: s.slug,
|
|
859
|
+
name: s.name
|
|
860
|
+
}));
|
|
861
|
+
if (isJsonMode()) return printJson(rows);
|
|
862
|
+
printTable(rows, ["id", "name"]);
|
|
863
|
+
info(`${rows.length} skills. \`sequel skills show <id>\` prints one; \`sequel install\` gives your agent all of them.`);
|
|
864
|
+
}
|
|
865
|
+
async function skillsShow(slug) {
|
|
866
|
+
const skill = await publicGet(`/marketplace/skills/${encodeURIComponent(slug)}`);
|
|
867
|
+
if (isJsonMode()) return printJson(skill);
|
|
868
|
+
process.stdout.write(`${pc.bold(skill.name)} ${pc.dim(skill.slug)}\n${skill.description}\n` + (skill.apps.length ? `${pc.dim("apps:")} ${skill.apps.join(", ")}\n` : "") + `\n${skill.instructions}\n`);
|
|
869
|
+
}
|
|
870
|
+
|
|
871
|
+
//#endregion
|
|
872
|
+
//#region ../mcp-clients/dist/install.js
|
|
745
873
|
const SERVER_NAME = "sequel";
|
|
874
|
+
/** Folder name of the Sequel skill inside an agent's skills directory. */
|
|
875
|
+
const SKILL_NAME = "sequel";
|
|
876
|
+
/**
|
|
877
|
+
* Write the Sequel SKILL.md into `<dir>/sequel/SKILL.md`, replacing any previous
|
|
878
|
+
* copy. Skill files are plain markdown, so unlike the MCP configs there is
|
|
879
|
+
* nothing to merge: the whole file is ours.
|
|
880
|
+
*/
|
|
881
|
+
function installSkill({ dir, markdown }) {
|
|
882
|
+
const path = join(dir, SKILL_NAME, "SKILL.md");
|
|
883
|
+
mkdirSync(dirname(path), { recursive: true });
|
|
884
|
+
writeFileSync(path, markdown.endsWith("\n") ? markdown : `${markdown}\n`);
|
|
885
|
+
return {
|
|
886
|
+
kind: "file",
|
|
887
|
+
path
|
|
888
|
+
};
|
|
889
|
+
}
|
|
746
890
|
const mcpUrl = (apiUrl) => `${apiUrl.replace(/\/$/, "")}/mcp`;
|
|
747
891
|
const bearer = (apiKey) => `Bearer ${apiKey}`;
|
|
748
892
|
function home(opts) {
|
|
@@ -811,6 +955,7 @@ const mcpClients = [
|
|
|
811
955
|
name: "Claude Code",
|
|
812
956
|
scopes: ["global", "local"],
|
|
813
957
|
describe: (o) => `claude mcp add --scope ${o.scope === "global" ? "user" : "local"} --transport http ${SERVER_NAME} …`,
|
|
958
|
+
skillsDir: (o) => o.scope === "global" ? join(home(o), ".claude", "skills") : join(cwd(o), ".claude", "skills"),
|
|
814
959
|
install(o) {
|
|
815
960
|
return {
|
|
816
961
|
kind: "command",
|
|
@@ -915,37 +1060,117 @@ const mcpClients = [
|
|
|
915
1060
|
path
|
|
916
1061
|
};
|
|
917
1062
|
}
|
|
1063
|
+
},
|
|
1064
|
+
{
|
|
1065
|
+
slug: "openclaw",
|
|
1066
|
+
name: "OpenClaw",
|
|
1067
|
+
scopes: ["global"],
|
|
1068
|
+
describe: () => `openclaw mcp set ${SERVER_NAME} …`,
|
|
1069
|
+
install(o) {
|
|
1070
|
+
const def = JSON.stringify({
|
|
1071
|
+
url: mcpUrl(o.apiUrl),
|
|
1072
|
+
transport: "streamable-http",
|
|
1073
|
+
headers: { Authorization: bearer(o.apiKey) }
|
|
1074
|
+
});
|
|
1075
|
+
return {
|
|
1076
|
+
kind: "command",
|
|
1077
|
+
command: "openclaw",
|
|
1078
|
+
args: [
|
|
1079
|
+
"mcp",
|
|
1080
|
+
"set",
|
|
1081
|
+
SERVER_NAME,
|
|
1082
|
+
def
|
|
1083
|
+
]
|
|
1084
|
+
};
|
|
1085
|
+
}
|
|
1086
|
+
},
|
|
1087
|
+
{
|
|
1088
|
+
slug: "hermes",
|
|
1089
|
+
name: "Hermes",
|
|
1090
|
+
scopes: ["global"],
|
|
1091
|
+
describe: (o) => join(home(o), ".hermes", "config.yaml"),
|
|
1092
|
+
install(o) {
|
|
1093
|
+
const path = join(home(o), ".hermes", "config.yaml");
|
|
1094
|
+
mergeYaml(path, (cfg) => setNested(cfg, "mcp_servers", {
|
|
1095
|
+
url: mcpUrl(o.apiUrl),
|
|
1096
|
+
headers: { Authorization: bearer(o.apiKey) }
|
|
1097
|
+
}));
|
|
1098
|
+
return {
|
|
1099
|
+
kind: "file",
|
|
1100
|
+
path
|
|
1101
|
+
};
|
|
1102
|
+
}
|
|
918
1103
|
}
|
|
919
1104
|
];
|
|
920
1105
|
function getMcpClient(slug) {
|
|
921
1106
|
return mcpClients.find((c) => c.slug === slug);
|
|
922
1107
|
}
|
|
923
1108
|
|
|
1109
|
+
//#endregion
|
|
1110
|
+
//#region src/lib/skills.ts
|
|
1111
|
+
/**
|
|
1112
|
+
* The canonical Sequel skill is published by the marketing site under the Agent
|
|
1113
|
+
* Skills discovery convention. The CLI downloads it at install time rather than
|
|
1114
|
+
* bundling a copy, so an installed skill is always the current one and there is
|
|
1115
|
+
* a single source of truth for its content.
|
|
1116
|
+
*/
|
|
1117
|
+
function skillMarkdownUrl() {
|
|
1118
|
+
return `${resolveSiteUrl().replace(/\/$/, "")}/.well-known/agent-skills/sequel/SKILL.md`;
|
|
1119
|
+
}
|
|
1120
|
+
async function fetchSkillMarkdown() {
|
|
1121
|
+
const url = skillMarkdownUrl();
|
|
1122
|
+
const res = await fetch(url, { headers: { Accept: "text/markdown, text/plain;q=0.9, */*;q=0.1" } });
|
|
1123
|
+
if (!res.ok) throw new Error(`Could not download the Sequel skill (${res.status}) from ${url}`);
|
|
1124
|
+
const text = await res.text();
|
|
1125
|
+
if (!text.trimStart().startsWith("---")) throw new Error(`Unexpected response from ${url}: not a SKILL.md`);
|
|
1126
|
+
return text;
|
|
1127
|
+
}
|
|
1128
|
+
|
|
924
1129
|
//#endregion
|
|
925
1130
|
//#region src/commands/install.ts
|
|
926
|
-
|
|
927
|
-
|
|
1131
|
+
const SCOPES = ["global", "local"];
|
|
1132
|
+
async function installCommand(slugArg, opts = {}) {
|
|
1133
|
+
const interactive = !isJsonMode();
|
|
1134
|
+
const slugList = mcpClients.map((c) => c.slug).join(", ");
|
|
1135
|
+
if (interactive) p$1.intro(pc.cyan("Install the Sequel MCP server and skill"));
|
|
1136
|
+
if (slugArg && !getMcpClient(slugArg)) throw new Error(`Unknown agent "${slugArg}". Options: ${slugList}`);
|
|
1137
|
+
if (!slugArg && !interactive) throw new Error(`Pass the agent slug when running non-interactively: \`sequel install <agent>\`. Options: ${slugList}`);
|
|
928
1138
|
if (!isLoggedIn()) {
|
|
929
|
-
|
|
930
|
-
|
|
1139
|
+
const msg = "You need to sign in to Sequel first — opening your browser…";
|
|
1140
|
+
if (interactive) p$1.log.info(msg);
|
|
1141
|
+
else info(msg);
|
|
1142
|
+
try {
|
|
1143
|
+
const result$1 = await runLoginFlow({ silent: opts.browser === false });
|
|
1144
|
+
const signedIn = `Signed in as ${result$1.user.email}${result$1.org ? ` (${result$1.org.name})` : ""}.`;
|
|
1145
|
+
if (interactive) p$1.log.success(signedIn);
|
|
1146
|
+
else success(signedIn);
|
|
1147
|
+
} catch (err) {
|
|
1148
|
+
if (!interactive) throw err;
|
|
1149
|
+
p$1.cancel(err instanceof Error ? err.message : String(err));
|
|
1150
|
+
return;
|
|
1151
|
+
}
|
|
931
1152
|
}
|
|
932
1153
|
let slug = slugArg;
|
|
933
1154
|
if (!slug) {
|
|
934
|
-
const choice = await p.select({
|
|
1155
|
+
const choice = await p$1.select({
|
|
935
1156
|
message: "Which coding agent do you want to install Sequel into?",
|
|
936
1157
|
options: mcpClients.map((c) => ({
|
|
937
1158
|
value: c.slug,
|
|
938
1159
|
label: c.name
|
|
939
1160
|
}))
|
|
940
1161
|
});
|
|
941
|
-
if (p.isCancel(choice)) return p.cancel("Cancelled.");
|
|
1162
|
+
if (p$1.isCancel(choice)) return p$1.cancel("Cancelled.");
|
|
942
1163
|
slug = choice;
|
|
943
1164
|
}
|
|
944
1165
|
const client = getMcpClient(slug);
|
|
945
|
-
if (!client) throw new Error(`Unknown agent "${slug}". Options: ${
|
|
1166
|
+
if (!client) throw new Error(`Unknown agent "${slug}". Options: ${slugList}`);
|
|
946
1167
|
let scope = client.scopes[0];
|
|
947
|
-
if (
|
|
948
|
-
|
|
1168
|
+
if (opts.scope !== void 0) {
|
|
1169
|
+
if (!SCOPES.includes(opts.scope)) throw new Error(`Unknown scope "${opts.scope}". Options: ${SCOPES.join(", ")}`);
|
|
1170
|
+
if (!client.scopes.includes(opts.scope)) throw new Error(`${client.name} only supports the ${client.scopes.join("/")} scope.`);
|
|
1171
|
+
scope = opts.scope;
|
|
1172
|
+
} else if (client.scopes.length > 1 && interactive) {
|
|
1173
|
+
const choice = await p$1.select({
|
|
949
1174
|
message: "Install scope",
|
|
950
1175
|
options: [{
|
|
951
1176
|
value: "global",
|
|
@@ -957,21 +1182,21 @@ async function installCommand(slugArg) {
|
|
|
957
1182
|
hint: "this project only"
|
|
958
1183
|
}].filter((o) => client.scopes.includes(o.value))
|
|
959
1184
|
});
|
|
960
|
-
if (p.isCancel(choice)) return p.cancel("Cancelled.");
|
|
1185
|
+
if (p$1.isCancel(choice)) return p$1.cancel("Cancelled.");
|
|
961
1186
|
scope = choice;
|
|
962
1187
|
}
|
|
963
1188
|
const config = readConfig();
|
|
964
1189
|
const apiUrl = resolveApiUrl(config);
|
|
965
|
-
const s = p.spinner();
|
|
966
|
-
s
|
|
1190
|
+
const s = interactive ? p$1.spinner() : null;
|
|
1191
|
+
s?.start("Creating a Sequel API key for this agent…");
|
|
967
1192
|
let key;
|
|
968
1193
|
try {
|
|
969
1194
|
({key} = await createApiKey(`Sequel CLI (${client.name})`));
|
|
970
1195
|
} catch (err) {
|
|
971
|
-
s
|
|
1196
|
+
s?.stop("Failed to create API key.");
|
|
972
1197
|
throw err;
|
|
973
1198
|
}
|
|
974
|
-
s.stop("API key created.");
|
|
1199
|
+
s ? s.stop("API key created.") : info("API key created.");
|
|
975
1200
|
const result = client.install({
|
|
976
1201
|
apiUrl,
|
|
977
1202
|
apiKey: key,
|
|
@@ -986,9 +1211,34 @@ async function installCommand(slugArg) {
|
|
|
986
1211
|
success(`Installed Sequel into ${client.name} (${scope}).`);
|
|
987
1212
|
} else {
|
|
988
1213
|
success(`Installed Sequel into ${client.name}.`);
|
|
989
|
-
|
|
1214
|
+
info(`Config written to ${pc.dim(result.path)}`);
|
|
990
1215
|
}
|
|
991
|
-
|
|
1216
|
+
const skillsDir = client.skillsDir?.({
|
|
1217
|
+
apiUrl,
|
|
1218
|
+
apiKey: key,
|
|
1219
|
+
scope
|
|
1220
|
+
}) ?? null;
|
|
1221
|
+
if (skillsDir) {
|
|
1222
|
+
const sk = interactive ? p$1.spinner() : null;
|
|
1223
|
+
sk?.start("Installing the Sequel skill…");
|
|
1224
|
+
try {
|
|
1225
|
+
const markdown = await fetchSkillMarkdown();
|
|
1226
|
+
const written = installSkill({
|
|
1227
|
+
dir: skillsDir,
|
|
1228
|
+
markdown
|
|
1229
|
+
});
|
|
1230
|
+
sk ? sk.stop("Sequel skill installed.") : success("Sequel skill installed.");
|
|
1231
|
+
info(`Skill written to ${pc.dim(written.path)}`);
|
|
1232
|
+
} catch (err) {
|
|
1233
|
+
sk?.stop("Could not install the Sequel skill.");
|
|
1234
|
+
const warning = `${err instanceof Error ? err.message : String(err)}\nSequel still works through MCP; rerun \`sequel install ${client.slug}\` later to add the skill.`;
|
|
1235
|
+
if (interactive) p$1.log.warn(warning);
|
|
1236
|
+
else info(`Could not install the Sequel skill. ${warning}`);
|
|
1237
|
+
}
|
|
1238
|
+
} else info(`${client.name} has no skills directory the CLI can write to; the Sequel skill is skipped. Playbooks are still available through MCP.`);
|
|
1239
|
+
const done = `Restart ${client.name} and ask it to "list my Sequel connections" to verify.`;
|
|
1240
|
+
if (interactive) p$1.outro(done);
|
|
1241
|
+
else info(done);
|
|
992
1242
|
}
|
|
993
1243
|
|
|
994
1244
|
//#endregion
|
|
@@ -1030,14 +1280,111 @@ async function executeCommand(connectionId, tool, opts) {
|
|
|
1030
1280
|
info(pc.dim(`\n${res.row_count} row(s)${res.truncated ? " (truncated)" : ""}`));
|
|
1031
1281
|
}
|
|
1032
1282
|
|
|
1283
|
+
//#endregion
|
|
1284
|
+
//#region src/commands/download.ts
|
|
1285
|
+
function formatBytes(n) {
|
|
1286
|
+
if (n < 1024) return `${n} B`;
|
|
1287
|
+
if (n < 1024 * 1024) return `${(n / 1024).toFixed(1)} KB`;
|
|
1288
|
+
return `${(n / (1024 * 1024)).toFixed(1)} MB`;
|
|
1289
|
+
}
|
|
1290
|
+
async function downloadCommand(sessionId, filePath, opts) {
|
|
1291
|
+
const meta = await getFileDownloadUrl(sessionId, filePath);
|
|
1292
|
+
if (isJsonMode()) return printJson(meta);
|
|
1293
|
+
const res = await fetch(meta.url);
|
|
1294
|
+
if (!res.ok) throw new Error(`Download failed (${res.status} ${res.statusText})`);
|
|
1295
|
+
const dest = opts.output ?? meta.filename;
|
|
1296
|
+
await writeFile(dest, Buffer.from(await res.arrayBuffer()));
|
|
1297
|
+
info(`${pc.green("✓")} Downloaded ${pc.bold(meta.filename)} (${formatBytes(meta.size)}) → ${dest}`);
|
|
1298
|
+
}
|
|
1299
|
+
|
|
1300
|
+
//#endregion
|
|
1301
|
+
//#region src/commands/upgrade.ts
|
|
1302
|
+
const PKG = "@sequelsh/cli@latest";
|
|
1303
|
+
const MANAGERS = [
|
|
1304
|
+
{
|
|
1305
|
+
name: "npm",
|
|
1306
|
+
cmd: "npm",
|
|
1307
|
+
args: [
|
|
1308
|
+
"install",
|
|
1309
|
+
"-g",
|
|
1310
|
+
PKG
|
|
1311
|
+
]
|
|
1312
|
+
},
|
|
1313
|
+
{
|
|
1314
|
+
name: "pnpm",
|
|
1315
|
+
cmd: "pnpm",
|
|
1316
|
+
args: [
|
|
1317
|
+
"add",
|
|
1318
|
+
"-g",
|
|
1319
|
+
PKG
|
|
1320
|
+
]
|
|
1321
|
+
},
|
|
1322
|
+
{
|
|
1323
|
+
name: "bun",
|
|
1324
|
+
cmd: "bun",
|
|
1325
|
+
args: [
|
|
1326
|
+
"add",
|
|
1327
|
+
"-g",
|
|
1328
|
+
PKG
|
|
1329
|
+
]
|
|
1330
|
+
},
|
|
1331
|
+
{
|
|
1332
|
+
name: "yarn",
|
|
1333
|
+
cmd: "yarn",
|
|
1334
|
+
args: [
|
|
1335
|
+
"global",
|
|
1336
|
+
"add",
|
|
1337
|
+
PKG
|
|
1338
|
+
]
|
|
1339
|
+
}
|
|
1340
|
+
];
|
|
1341
|
+
function has(cmd) {
|
|
1342
|
+
try {
|
|
1343
|
+
execFileSync(process.platform === "win32" ? "where" : "which", [cmd], { stdio: "ignore" });
|
|
1344
|
+
return true;
|
|
1345
|
+
} catch {
|
|
1346
|
+
return false;
|
|
1347
|
+
}
|
|
1348
|
+
}
|
|
1349
|
+
async function upgradeCommand() {
|
|
1350
|
+
const json = isJsonMode();
|
|
1351
|
+
if (!json) p.intro(pc.cyan("Upgrade the Sequel CLI"));
|
|
1352
|
+
const manager = MANAGERS.find((m) => has(m.cmd));
|
|
1353
|
+
if (!manager) {
|
|
1354
|
+
const msg = "No supported package manager found (npm, pnpm, bun, or yarn). Install Node.js from https://nodejs.org and try again.";
|
|
1355
|
+
if (json) return printJson({
|
|
1356
|
+
status: "error",
|
|
1357
|
+
error: msg
|
|
1358
|
+
});
|
|
1359
|
+
p.cancel(msg);
|
|
1360
|
+
return;
|
|
1361
|
+
}
|
|
1362
|
+
const s = json ? null : p.spinner();
|
|
1363
|
+
s?.start(`Updating ${PKG} with ${manager.name}…`);
|
|
1364
|
+
try {
|
|
1365
|
+
execFileSync(manager.cmd, manager.args, { stdio: "pipe" });
|
|
1366
|
+
} catch (err) {
|
|
1367
|
+
s?.stop("Upgrade failed.");
|
|
1368
|
+
throw new Error(`Failed to run \`${manager.cmd} ${manager.args.join(" ")}\`.\n${err instanceof Error ? err.message : String(err)}`);
|
|
1369
|
+
}
|
|
1370
|
+
s?.stop("Updated.");
|
|
1371
|
+
if (json) return printJson({
|
|
1372
|
+
status: "upgraded",
|
|
1373
|
+
package: PKG,
|
|
1374
|
+
manager: manager.name
|
|
1375
|
+
});
|
|
1376
|
+
success("Sequel CLI is now on the latest version.");
|
|
1377
|
+
p.outro("Run `sequel --version` to confirm.");
|
|
1378
|
+
}
|
|
1379
|
+
|
|
1033
1380
|
//#endregion
|
|
1034
1381
|
//#region src/index.ts
|
|
1035
1382
|
const program = new Command();
|
|
1036
|
-
program.name("sequel").description("Sequel CLI — connect data sources and run tools from your terminal").version(
|
|
1383
|
+
program.name("sequel").description("Sequel CLI — connect data sources and run tools from your terminal").version(package_default.version).option("--json", "output machine-readable JSON").enablePositionalOptions();
|
|
1037
1384
|
/** Wrap a command action with shared --json handling and error reporting. */
|
|
1038
1385
|
function action(fn) {
|
|
1039
1386
|
return async (...args) => {
|
|
1040
|
-
if (program.opts().json) setJsonMode(true);
|
|
1387
|
+
if (program.opts().json || !process.stdout.isTTY) setJsonMode(true);
|
|
1041
1388
|
try {
|
|
1042
1389
|
await fn(...args);
|
|
1043
1390
|
} catch (err) {
|
|
@@ -1047,7 +1394,8 @@ function action(fn) {
|
|
|
1047
1394
|
}
|
|
1048
1395
|
};
|
|
1049
1396
|
}
|
|
1050
|
-
program.command("
|
|
1397
|
+
program.command("upgrade").description("Upgrade the Sequel CLI to the latest version").action(action(upgradeCommand));
|
|
1398
|
+
program.command("login").description("Sign in to Sequel").option("--no-browser", "print the sign-in URL instead of opening a browser").action(action(loginCommand));
|
|
1051
1399
|
program.command("logout").description("Sign out and remove cached credentials").action(action(logoutCommand));
|
|
1052
1400
|
program.command("switch").description("Switch the active organization").action(action(switchCommand));
|
|
1053
1401
|
program.command("connect").argument("[source]", "connector id (e.g. postgres); omit to choose interactively").description("Connect a new data source").action(action(connectCommand));
|
|
@@ -1056,9 +1404,13 @@ sources.command("list", { isDefault: true }).description("List connected sources
|
|
|
1056
1404
|
sources.command("active").description("List sources with live health status").action(action(sourcesActive));
|
|
1057
1405
|
sources.command("info").argument("[id]", "source id or short id").description("Show details for a source").action(action(sourcesInfo));
|
|
1058
1406
|
sources.command("delete").argument("[id]", "source id or short id").description("Delete a source").action(action(sourcesDelete));
|
|
1059
|
-
program.command("
|
|
1407
|
+
const skills = program.command("skills").description("Browse the playbooks your agent can follow");
|
|
1408
|
+
skills.command("list", { isDefault: true }).description("List every skill (id and name)").action(action(skillsList));
|
|
1409
|
+
skills.command("show").argument("<id>", "skill id, e.g. seo").description("Print a skill's playbook").action(action((id) => skillsShow(id)));
|
|
1410
|
+
program.command("install").argument("[agent]", "coding agent slug (e.g. cursor, claude-code)").option("-s, --scope <scope>", "global or local; skips the prompt (defaults to global when piped)").option("--no-browser", "print the sign-in URL instead of opening a browser if sign-in is needed").description("Install the Sequel MCP server into a coding agent").action(action(installCommand));
|
|
1060
1411
|
program.command("search").argument("<usecase>", "what you want to do, e.g. \"monthly revenue\"").option("-c, --connection <id...>", "limit to specific connection short ids").description("Find the right tools for a use case across your sources").action(action((usecase, opts) => searchCommand(usecase, opts)));
|
|
1061
1412
|
program.command("execute").argument("<connection_id>", "connection short id").argument("<tool>", "tool id, e.g. postgres.query").option("-d, --data <json>", "tool input as a JSON string").description("Execute a tool against a connection").action(action((connectionId, tool, opts) => executeCommand(connectionId, tool, opts)));
|
|
1413
|
+
program.command("download").argument("<session_id>", "session id (from `sequel search` or an agent session)").argument("<path>", "file path, e.g. /data/result.csv or result.csv").option("-o, --output <file>", "write to this path (default: the file's own name)").description("Download a file produced by a query or workbench run").action(action((sessionId, path, opts) => downloadCommand(sessionId, path, opts)));
|
|
1062
1414
|
program.parseAsync(process.argv).catch((err) => {
|
|
1063
1415
|
fail(err instanceof Error ? err.message : String(err));
|
|
1064
1416
|
process.exit(1);
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":["config?: AuthConfig | null","config: AuthConfig","isLoggedIn","buf: Buffer","apiUrl: string","params: Record<string, string>","redirectUri: string","accessToken: string","expectedState: string","resolveCode!: (code: string) => void","rejectCode!: (err: Error) => void","title: string","message: string","options?: { silent?: boolean }","next: AuthConfig","entry: TokenEntry","status: number","message: string","path: string","options: RequestOptions","headers: Record<string, string>","body: string | undefined","text","id: string","appId: string","body: Record<string, unknown>","token: string","connectionId: string","tool: string","params: Record<string, unknown>","useCase: string","connectionIds?: string[]","name: string","on: boolean","data: unknown","value: unknown","rows: Array<Record<string, unknown>>","columns?: string[]","message: string","connector: Connector","token: string","source?: string","connector: Connector | undefined","credentials: Record<string, string>","p","s","res","result","idOrShort: string","message: string","c: Connection","idOrShort?: string","config: { schemaFilters: string[] | null; instructions: string | null } | null","apiUrl: string","apiKey: string","opts: InstallOptions","vendor: string","path: string","mutate: (cfg: Record<string, unknown>) => void","cfg: Record<string, unknown>","key: string","value: unknown","mcpClients: McpClientDef[]","slug: string","slugArg?: string","scope: Scope","key: string","useCase: string","opts: { connection?: string[] }","connectionId: string","tool: string","opts: { data?: string }","params: Record<string, unknown>","fn: (...args: A) => Promise<void>","usecase: string","opts: { connection?: string[] }","connectionId: string","tool: string","opts: { data?: string }"],"sources":["../src/lib/config.ts","../src/lib/auth.ts","../src/lib/api.ts","../src/lib/output.ts","../src/commands/login.ts","../src/commands/logout.ts","../src/commands/switch.ts","../src/commands/connect.ts","../src/commands/sources.ts","../src/lib/mcp-clients.ts","../src/commands/install.ts","../src/commands/search.ts","../src/commands/execute.ts","../src/index.ts"],"sourcesContent":["import { homedir } from \"node:os\";\nimport { join } from \"node:path\";\nimport { mkdirSync, readFileSync, writeFileSync, rmSync, existsSync, chmodSync } from \"node:fs\";\n\n/** Default production API base. Override with SEQUEL_API_URL for local/dev. */\nexport const DEFAULT_API_URL = \"https://api.sequel.sh\";\n\n/** One OAuth token bundle, scoped to a single organization. */\nexport interface TokenEntry {\n accessToken: string;\n refreshToken: string;\n /** ms epoch when the access token expires. */\n expiresAt: number;\n}\n\nexport interface OrgRef {\n id: string;\n name: string;\n slug: string;\n role: string;\n}\n\nexport interface UserRef {\n id: string;\n email: string;\n name: string;\n}\n\n/**\n * The on-disk shape of ~/.sequel/auth.json.\n *\n * Multi-token cache: one genuine org-bound OAuth token per organization, keyed\n * by org id. `activeOrgId` selects which token requests use right now. Switching\n * orgs is an offline swap when the target org already has a cached token.\n */\nexport interface AuthConfig {\n version: 1;\n apiUrl: string;\n /** Persisted dynamic client registration, reused across logins. */\n clientId?: string;\n activeOrgId?: string;\n tokens: Record<string, TokenEntry>;\n user?: UserRef;\n /** Cached membership list for the `switch` UI. */\n orgs?: OrgRef[];\n}\n\n/** Directory holding the CLI's state. Overridable for tests. */\nexport function configDir(): string {\n return process.env.SEQUEL_CONFIG_DIR || join(homedir(), \".sequel\");\n}\n\nexport function configPath(): string {\n return join(configDir(), \"auth.json\");\n}\n\n/** The API base URL: explicit env wins, then a saved value, then the default. */\nexport function resolveApiUrl(config?: AuthConfig | null): string {\n return process.env.SEQUEL_API_URL || config?.apiUrl || DEFAULT_API_URL;\n}\n\nfunction emptyConfig(): AuthConfig {\n return { version: 1, apiUrl: resolveApiUrl(), tokens: {} };\n}\n\n/** Read auth.json, returning a fresh empty config if missing or corrupt. */\nexport function readConfig(): AuthConfig {\n const path = configPath();\n if (!existsSync(path)) return emptyConfig();\n try {\n const parsed = JSON.parse(readFileSync(path, \"utf8\")) as AuthConfig;\n if (!parsed || typeof parsed !== \"object\" || !parsed.tokens) return emptyConfig();\n parsed.tokens ??= {};\n return parsed;\n } catch {\n // Corrupt file — start clean rather than crash.\n return emptyConfig();\n }\n}\n\n/** Persist auth.json with locked-down permissions (dir 0700, file 0600). */\nexport function writeConfig(config: AuthConfig): void {\n const dir = configDir();\n mkdirSync(dir, { recursive: true, mode: 0o700 });\n const path = configPath();\n writeFileSync(path, `${JSON.stringify(config, null, 2)}\\n`, { mode: 0o600 });\n // writeFileSync only applies mode on create; enforce it on existing files too.\n chmodSync(path, 0o600);\n}\n\n/** Remove all stored credentials. Idempotent. */\nexport function clearConfig(): void {\n const path = configPath();\n if (existsSync(path)) rmSync(path);\n}\n\nexport function isLoggedIn(config: AuthConfig): boolean {\n return Boolean(config.activeOrgId && config.tokens[config.activeOrgId]);\n}\n","import { createHash, randomBytes } from \"node:crypto\";\nimport { createServer } from \"node:http\";\nimport { AddressInfo } from \"node:net\";\nimport open from \"open\";\nimport {\n type AuthConfig,\n type OrgRef,\n type TokenEntry,\n type UserRef,\n readConfig,\n writeConfig,\n resolveApiUrl,\n} from \"./config\";\n\n/** Refresh a token this many ms before it actually expires. */\nconst EXPIRY_SKEW_MS = 60_000;\n\nfunction base64url(buf: Buffer): string {\n return buf.toString(\"base64url\");\n}\n\n/** PKCE pair: challenge = base64url(sha256(verifier)), matching the API's S256. */\nexport function generatePkce(): { verifier: string; challenge: string } {\n const verifier = base64url(randomBytes(32));\n const challenge = base64url(createHash(\"sha256\").update(verifier).digest());\n return { verifier, challenge };\n}\n\ninterface TokenResponse {\n access_token: string;\n refresh_token: string;\n expires_in: number;\n token_type: string;\n}\n\ninterface WhoAmI {\n id: string;\n name: string;\n email: string;\n organizationId: string;\n}\n\n/** POST the OAuth token endpoint (form-encoded, per RFC 6749). */\nasync function postToken(apiUrl: string, params: Record<string, string>): Promise<TokenResponse> {\n const res = await fetch(`${apiUrl}/oauth/token`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/x-www-form-urlencoded\" },\n body: new URLSearchParams(params).toString(),\n });\n if (!res.ok) {\n const body = await res.text().catch(() => \"\");\n throw new Error(`Token request failed (${res.status}): ${body}`);\n }\n return (await res.json()) as TokenResponse;\n}\n\n/** Register a fresh dynamic OAuth client bound to this run's loopback URI. */\nasync function registerClient(apiUrl: string, redirectUri: string): Promise<string> {\n const res = await fetch(`${apiUrl}/oauth/register`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ client_name: \"Sequel CLI\", redirect_uris: [redirectUri] }),\n });\n if (!res.ok) {\n const body = await res.text().catch(() => \"\");\n throw new Error(`Client registration failed (${res.status}): ${body}`);\n }\n const data = (await res.json()) as { client_id: string };\n return data.client_id;\n}\n\nasync function fetchWhoAmI(apiUrl: string, accessToken: string): Promise<WhoAmI> {\n const res = await fetch(`${apiUrl}/users/me`, {\n headers: { Authorization: `Bearer ${accessToken}` },\n });\n if (!res.ok) throw new Error(`Failed to resolve identity (${res.status})`);\n return (await res.json()) as WhoAmI;\n}\n\nexport async function fetchOrganizations(apiUrl: string, accessToken: string): Promise<OrgRef[]> {\n const res = await fetch(`${apiUrl}/organizations`, {\n headers: { Authorization: `Bearer ${accessToken}` },\n });\n if (!res.ok) throw new Error(`Failed to list organizations (${res.status})`);\n const rows = (await res.json()) as Array<{\n role: string;\n organization: { id: string; name: string; slug: string };\n }>;\n return rows.map((r) => ({\n id: r.organization.id,\n name: r.organization.name,\n slug: r.organization.slug,\n role: r.role,\n }));\n}\n\n/**\n * Wait for the browser to hit the loopback redirect and hand back `?code&state`.\n * Resolves with the authorization code once `state` is verified.\n */\nfunction waitForCallback(\n expectedState: string,\n): { server: ReturnType<typeof createServer>; port: Promise<number>; code: Promise<string> } {\n let resolveCode!: (code: string) => void;\n let rejectCode!: (err: Error) => void;\n const code = new Promise<string>((resolve, reject) => {\n resolveCode = resolve;\n rejectCode = reject;\n });\n\n const server = createServer((req, res) => {\n const url = new URL(req.url ?? \"/\", \"http://127.0.0.1\");\n if (url.pathname !== \"/callback\") {\n res.writeHead(404).end(\"Not found\");\n return;\n }\n const error = url.searchParams.get(\"error\");\n const returnedState = url.searchParams.get(\"state\");\n const returnedCode = url.searchParams.get(\"code\");\n\n const finish = (title: string, message: string) => {\n res.writeHead(200, { \"Content-Type\": \"text/html; charset=utf-8\" });\n res.end(\n `<!doctype html><html><head><title>${title}</title></head><body style=\"font-family:system-ui;padding:3rem;text-align:center\"><h2>${title}</h2><p>${message}</p><p>You can close this tab and return to your terminal.</p></body></html>`,\n );\n };\n\n if (error) {\n finish(\"Sign-in failed\", `The authorization server returned: ${error}`);\n rejectCode(new Error(`Authorization failed: ${error}`));\n return;\n }\n if (!returnedState || returnedState !== expectedState) {\n finish(\"Sign-in failed\", \"State mismatch — possible CSRF. Please try again.\");\n rejectCode(new Error(\"State mismatch in OAuth callback\"));\n return;\n }\n if (!returnedCode) {\n finish(\"Sign-in failed\", \"No authorization code was returned.\");\n rejectCode(new Error(\"Missing authorization code\"));\n return;\n }\n finish(\"Signed in to Sequel\", \"Authentication complete.\");\n resolveCode(returnedCode);\n });\n\n const port = new Promise<number>((resolve, reject) => {\n server.on(\"error\", reject);\n server.listen(0, \"127.0.0.1\", () => resolve((server.address() as AddressInfo).port));\n });\n\n return { server, port, code };\n}\n\nexport interface LoginResult {\n user: UserRef;\n org: OrgRef | undefined;\n organizationId: string;\n}\n\n/**\n * Run the full OAuth 2.0 + PKCE loopback flow: register a client, open the\n * browser to the consent page (where the user picks an org), capture the code,\n * exchange it for an org-bound token, then cache that token keyed by its org.\n *\n * Shared by `login` and `switch` (for orgs without a cached token).\n */\nexport async function runLoginFlow(options?: { silent?: boolean }): Promise<LoginResult> {\n const config = readConfig();\n const apiUrl = resolveApiUrl(config);\n\n const { verifier, challenge } = generatePkce();\n const state = base64url(randomBytes(16));\n\n const { server, port: portPromise, code: codePromise } = waitForCallback(state);\n const port = await portPromise;\n const redirectUri = `http://127.0.0.1:${port}/callback`;\n\n try {\n const clientId = await registerClient(apiUrl, redirectUri);\n\n const authorizeUrl = new URL(`${apiUrl}/oauth/authorize`);\n authorizeUrl.searchParams.set(\"client_id\", clientId);\n authorizeUrl.searchParams.set(\"redirect_uri\", redirectUri);\n authorizeUrl.searchParams.set(\"response_type\", \"code\");\n authorizeUrl.searchParams.set(\"code_challenge\", challenge);\n authorizeUrl.searchParams.set(\"code_challenge_method\", \"S256\");\n authorizeUrl.searchParams.set(\"state\", state);\n\n if (!options?.silent) {\n // open() can fail in headless envs — never block the flow on it.\n open(authorizeUrl.toString()).catch(() => {});\n }\n // Always surface the URL so the user can open it manually if needed.\n process.stderr.write(`\\nOpen this URL to continue:\\n${authorizeUrl.toString()}\\n\\n`);\n\n const code = await codePromise;\n\n const token = await postToken(apiUrl, {\n grant_type: \"authorization_code\",\n code,\n redirect_uri: redirectUri,\n client_id: clientId,\n code_verifier: verifier,\n });\n\n const me = await fetchWhoAmI(apiUrl, token.access_token);\n const orgs = await fetchOrganizations(apiUrl, token.access_token).catch(() => config.orgs ?? []);\n\n const next: AuthConfig = {\n ...config,\n version: 1,\n apiUrl,\n clientId,\n activeOrgId: me.organizationId,\n tokens: {\n ...config.tokens,\n [me.organizationId]: {\n accessToken: token.access_token,\n refreshToken: token.refresh_token,\n expiresAt: Date.now() + token.expires_in * 1000,\n },\n },\n user: { id: me.id, email: me.email, name: me.name },\n orgs,\n };\n writeConfig(next);\n\n return {\n user: next.user!,\n org: orgs.find((o) => o.id === me.organizationId),\n organizationId: me.organizationId,\n };\n } finally {\n server.close();\n }\n}\n\n/** True when there's a cached token for the active org (cheap, non-throwing). */\nexport function isLoggedIn(): boolean {\n const config = readConfig();\n const orgId = config.activeOrgId;\n return Boolean(orgId && config.tokens[orgId]);\n}\n\n/**\n * Return a valid access token for the active org, refreshing it in place when\n * expired. Throws a friendly error if there is no token or the refresh fails.\n */\nexport async function getValidAccessToken(): Promise<{ token: string; config: AuthConfig }> {\n const config = readConfig();\n const orgId = config.activeOrgId;\n if (!orgId || !config.tokens[orgId]) {\n throw new Error(\"Not logged in. Run `sequel login` first.\");\n }\n\n const entry: TokenEntry = config.tokens[orgId];\n if (entry.expiresAt - EXPIRY_SKEW_MS > Date.now()) {\n return { token: entry.accessToken, config };\n }\n\n // Access token expired — rotate via the refresh grant.\n const apiUrl = resolveApiUrl(config);\n try {\n const refreshed = await postToken(apiUrl, {\n grant_type: \"refresh_token\",\n refresh_token: entry.refreshToken,\n client_id: config.clientId ?? \"\",\n });\n config.tokens[orgId] = {\n accessToken: refreshed.access_token,\n refreshToken: refreshed.refresh_token,\n expiresAt: Date.now() + refreshed.expires_in * 1000,\n };\n writeConfig(config);\n return { token: refreshed.access_token, config };\n } catch {\n throw new Error(\n \"Your session for this organization has expired. Run `sequel login` (or `sequel switch`) to sign in again.\",\n );\n }\n}\n","import { getValidAccessToken } from \"./auth\";\nimport { resolveApiUrl } from \"./config\";\n\nexport class ApiError extends Error {\n constructor(\n public status: number,\n message: string,\n ) {\n super(message);\n this.name = \"ApiError\";\n }\n}\n\ninterface RequestOptions {\n method?: string;\n query?: Record<string, string | undefined>;\n body?: Record<string, unknown>;\n /**\n * How the active org id is attached to the request:\n * - \"query\" → ?organizationId=<org> (default; most GET/DELETE routes)\n * - \"organizationId\" → merged into the JSON body as organizationId\n * - \"organization_id\" → merged into the JSON body as organization_id (execute)\n * - \"none\" → not attached (e.g. /connectors, /oauth/*)\n */\n org?: \"query\" | \"organizationId\" | \"organization_id\" | \"none\";\n}\n\n/**\n * Authenticated request against the Sequel API using the active org's token.\n * Refreshes the token transparently and scopes the call to that org.\n */\nexport async function request<T = unknown>(path: string, options: RequestOptions = {}): Promise<T> {\n const { token, config } = await getValidAccessToken();\n const apiUrl = resolveApiUrl(config);\n const orgId = config.activeOrgId;\n const orgMode = options.org ?? \"query\";\n\n const url = new URL(`${apiUrl}${path}`);\n if (orgMode === \"query\" && orgId) url.searchParams.set(\"organizationId\", orgId);\n for (const [k, v] of Object.entries(options.query ?? {})) {\n if (v !== undefined) url.searchParams.set(k, v);\n }\n\n let bodyObj = options.body;\n if ((orgMode === \"organizationId\" || orgMode === \"organization_id\") && orgId) {\n bodyObj = { ...(bodyObj ?? {}), [orgMode]: orgId };\n }\n\n const headers: Record<string, string> = { Authorization: `Bearer ${token}` };\n let body: string | undefined;\n if (bodyObj !== undefined) {\n headers[\"Content-Type\"] = \"application/json\";\n body = JSON.stringify(bodyObj);\n }\n\n const res = await fetch(url.toString(), { method: options.method ?? \"GET\", headers, body });\n\n if (!res.ok) {\n let message = `Request failed (${res.status})`;\n const text = await res.text().catch(() => \"\");\n try {\n const json = JSON.parse(text) as { error?: string };\n if (json.error) message = json.error;\n } catch {\n if (text) message = text;\n }\n throw new ApiError(res.status, message);\n }\n\n if (res.status === 204) return undefined as T;\n const text = await res.text();\n return (text ? JSON.parse(text) : undefined) as T;\n}\n\n/** The active organization id, or throws if not logged in. */\nexport async function activeOrgId(): Promise<string> {\n const { config } = await getValidAccessToken();\n if (!config.activeOrgId) throw new Error(\"No active organization. Run `sequel login`.\");\n return config.activeOrgId;\n}\n\n// ── Types ──────────────────────────────────────────────────────────────────────\n\nexport interface Connector {\n id: string;\n name: string;\n description: string;\n icon: string;\n appType: \"database\" | \"app\" | \"mcp\";\n live: boolean;\n authId: string;\n credentialsSchema?: Record<string, unknown>;\n userInputFields?: string[];\n canResolveName?: boolean;\n configuration?: { type: string } | null;\n}\n\nexport interface Connection {\n id: string;\n shortId: string;\n name: string;\n type: string;\n createdBy?: string;\n createdAt: string;\n updatedAt: string;\n}\n\nexport type LinkCreateResponse =\n | { status: \"success\"; connection: Connection }\n | { status: \"pending\"; link_token: string; redirect_url: string; expires_at: string };\n\nexport interface LinkStatus {\n status: \"pending\" | \"oauth_in_progress\" | \"awaiting_configuration\" | \"success\" | \"failed\" | \"completed\";\n connectionId?: string;\n connection_id?: string;\n reason?: string;\n}\n\nexport interface ExecuteResult {\n data: Array<Record<string, unknown>>;\n columns: string[];\n row_count: number;\n truncated: boolean;\n}\n\nexport interface SearchToolRef {\n tool_id: string;\n input_schema: Record<string, unknown>;\n output_schema: Record<string, unknown> | null;\n relevant_tables: string[];\n}\n\nexport interface SearchResult {\n connection_id: string;\n connection_name: string;\n app_id: string;\n use_case: string;\n instructions: string;\n tools: SearchToolRef[];\n}\n\n// ── Endpoint wrappers ───────────────────────────────────────────────────────────\n\nexport function listConnectors(): Promise<Connector[]> {\n return request<Connector[]>(\"/connectors\", { org: \"none\" });\n}\n\nexport function listConnections(): Promise<Connection[]> {\n return request<Connection[]>(\"/connections\");\n}\n\nexport function getConnection(id: string): Promise<Connection> {\n return request<Connection>(`/connections/${id}`);\n}\n\nexport function deleteConnection(id: string): Promise<Connection> {\n return request<Connection>(`/connections/${id}`, { method: \"DELETE\" });\n}\n\nexport function testConnection(id: string): Promise<{ success: boolean; message: string }> {\n return request(`/connections/${id}/test`, { method: \"POST\", org: \"organizationId\" });\n}\n\nexport function getConnectionConfig(\n id: string,\n): Promise<{ schemaFilters: string[] | null; instructions: string | null }> {\n return request(`/connections/${id}/config`);\n}\n\n/** Mint a connect link / create a connection for the given connector. */\nexport function createLink(appId: string, body: Record<string, unknown>): Promise<LinkCreateResponse> {\n // POST /link/:appId resolves the org from the token's session, which always\n // matches the active org in the multi-token model — no org param needed.\n return request<LinkCreateResponse>(`/link/${appId}`, { method: \"POST\", org: \"none\", body });\n}\n\n/**\n * Poll a connect link's status. Uses the authenticated route, which (unlike the\n * public one) reports terminal states — `completed`/`failed` — so the CLI can\n * tell when the browser flow has finished.\n */\nexport function getLinkStatus(token: string): Promise<LinkStatus> {\n return request<LinkStatus>(`/link/${token}/status`, { org: \"none\" });\n}\n\nexport function execute(\n connectionId: string,\n tool: string,\n params: Record<string, unknown>,\n): Promise<ExecuteResult> {\n return request<ExecuteResult>(\"/execute\", {\n method: \"POST\",\n org: \"organization_id\",\n body: { connection_id: connectionId, tool, params },\n });\n}\n\nexport function search(useCase: string, connectionIds?: string[]): Promise<{ results: SearchResult[] }> {\n return request<{ results: SearchResult[] }>(\"/search\", {\n method: \"POST\",\n org: \"organization_id\",\n body: {\n action_info: `CLI search: ${useCase}`,\n use_case: useCase,\n connection_ids: connectionIds,\n },\n });\n}\n\nexport async function createApiKey(name: string): Promise<{ key: string; keyPrefix: string }> {\n const orgId = await activeOrgId();\n return request(`/organizations/${orgId}/api-keys`, { method: \"POST\", org: \"none\", body: { name } });\n}\n","import pc from \"picocolors\";\n\nexport { pc };\n\n/** True when the user passed a global --json flag (set by index.ts). */\nlet jsonMode = false;\nexport function setJsonMode(on: boolean): void {\n jsonMode = on;\n}\nexport function isJsonMode(): boolean {\n return jsonMode;\n}\n\nexport function printJson(data: unknown): void {\n process.stdout.write(`${JSON.stringify(data, null, 2)}\\n`);\n}\n\nfunction cell(value: unknown): string {\n if (value === null || value === undefined) return \"\";\n if (typeof value === \"object\") return JSON.stringify(value);\n return String(value);\n}\n\n/**\n * Render an array of records as an aligned text table. `columns` controls order\n * and which keys are shown; defaults to the union of keys in the first row.\n */\nexport function renderTable(rows: Array<Record<string, unknown>>, columns?: string[]): string {\n if (rows.length === 0) return pc.dim(\"(no rows)\");\n const cols = columns ?? Object.keys(rows[0]);\n const widths = cols.map((c) => Math.max(c.length, ...rows.map((r) => cell(r[c]).length)));\n\n const header = cols.map((c, i) => pc.bold(c.padEnd(widths[i]))).join(\" \");\n const sep = cols.map((_, i) => \"─\".repeat(widths[i])).join(\" \");\n const body = rows\n .map((r) => cols.map((c, i) => cell(r[c]).padEnd(widths[i])).join(\" \"))\n .join(\"\\n\");\n\n return `${header}\\n${pc.dim(sep)}\\n${body}`;\n}\n\nexport function printTable(rows: Array<Record<string, unknown>>, columns?: string[]): void {\n process.stdout.write(`${renderTable(rows, columns)}\\n`);\n}\n\nexport function success(message: string): void {\n process.stdout.write(`${pc.green(\"✓\")} ${message}\\n`);\n}\n\nexport function info(message: string): void {\n process.stdout.write(`${message}\\n`);\n}\n\nexport function fail(message: string): void {\n process.stderr.write(`${pc.red(\"✗\")} ${message}\\n`);\n}\n","import * as p from \"@clack/prompts\";\nimport { runLoginFlow } from \"../lib/auth\";\nimport { pc, success } from \"../lib/output\";\n\nexport async function loginCommand(): Promise<void> {\n p.intro(pc.cyan(\"Sign in to Sequel\"));\n p.log.info(\"Opening your browser to authorize…\");\n const res = await runLoginFlow();\n success(`Logged in as ${pc.bold(res.user.email)}${res.org ? ` · ${pc.bold(res.org.name)}` : \"\"}`);\n p.outro(\"You're all set. Try `sequel sources list` or `sequel connect`.\");\n}\n","import { clearConfig, isLoggedIn, readConfig } from \"../lib/config\";\nimport { info, success } from \"../lib/output\";\n\nexport async function logoutCommand(): Promise<void> {\n const config = readConfig();\n if (!isLoggedIn(config)) {\n info(\"You are not logged in.\");\n return;\n }\n clearConfig();\n success(\"Logged out. Cached credentials removed from ~/.sequel/auth.json.\");\n}\n","import * as p from \"@clack/prompts\";\nimport { fetchOrganizations, getValidAccessToken, runLoginFlow } from \"../lib/auth\";\nimport { isLoggedIn, readConfig, resolveApiUrl, writeConfig } from \"../lib/config\";\nimport { pc, success } from \"../lib/output\";\n\nexport async function switchCommand(): Promise<void> {\n const config = readConfig();\n if (!isLoggedIn(config)) {\n throw new Error(\"Not logged in. Run `sequel login` first.\");\n }\n\n // Refresh the membership list with the active org's token.\n let orgs = config.orgs ?? [];\n try {\n const { token } = await getValidAccessToken();\n orgs = await fetchOrganizations(resolveApiUrl(config), token);\n writeConfig({ ...readConfig(), orgs });\n } catch {\n // fall back to cached orgs\n }\n if (orgs.length === 0) throw new Error(\"No organizations available for this account.\");\n\n const selection = await p.select({\n message: \"Switch to organization\",\n options: orgs.map((o) => ({\n value: o.id,\n label: o.id === config.activeOrgId ? `${o.name} ${pc.dim(\"(current)\")}` : o.name,\n hint: config.tokens[o.id] ? o.role : \"sign-in required\",\n })),\n });\n if (p.isCancel(selection)) {\n p.cancel(\"Cancelled.\");\n return;\n }\n\n const orgId = selection as string;\n const org = orgs.find((o) => o.id === orgId);\n const fresh = readConfig();\n\n if (fresh.tokens[orgId]) {\n // Already authorized — instant, offline swap.\n writeConfig({ ...fresh, activeOrgId: orgId });\n success(`Switched to ${pc.bold(org?.name ?? orgId)}.`);\n return;\n }\n\n // No cached token for this org — sign in so the user can authorize it.\n p.log.info(`You haven't authorized ${pc.bold(org?.name ?? orgId)} yet — opening your browser…`);\n const res = await runLoginFlow();\n success(`Switched to ${pc.bold(res.org?.name ?? res.organizationId)}.`);\n}\n","import * as p from \"@clack/prompts\";\nimport open from \"open\";\nimport {\n type Connector,\n createLink,\n getLinkStatus,\n listConnectors,\n} from \"../lib/api\";\nimport { info, pc, success } from \"../lib/output\";\n\nconst SECRET_RE = /pass|secret|token|key|connection|credential/i;\n\nfunction fieldsFor(connector: Connector): string[] {\n if (connector.userInputFields?.length) return connector.userInputFields;\n const props = (connector.credentialsSchema as { properties?: Record<string, unknown> } | undefined)?.properties;\n return props ? Object.keys(props) : [];\n}\n\nfunction isOAuth(connector: Connector): boolean {\n return Boolean(connector.configuration) || /oauth/i.test(connector.authId);\n}\n\n/** Poll a pending connect link until it completes or fails (or times out). */\nasync function pollLink(token: string): Promise<{ ok: boolean; reason?: string }> {\n const deadline = Date.now() + 5 * 60_000;\n while (Date.now() < deadline) {\n await new Promise((r) => setTimeout(r, 2000));\n let status;\n try {\n status = await getLinkStatus(token);\n } catch {\n continue; // transient — keep polling\n }\n if (status.status === \"failed\") return { ok: false, reason: status.reason };\n if (status.status === \"success\" || status.status === \"completed\") return { ok: true };\n }\n return { ok: false, reason: \"Timed out waiting for the browser to finish.\" };\n}\n\nexport async function connectCommand(source?: string): Promise<void> {\n const connectors = await listConnectors();\n\n let connector: Connector | undefined;\n if (source) {\n connector = connectors.find((c) => c.id === source);\n if (!connector) {\n throw new Error(\n `Unknown connector \"${source}\". Available: ${connectors.map((c) => c.id).join(\", \")}`,\n );\n }\n } else {\n const choice = await p.select({\n message: \"Which data source do you want to connect?\",\n options: connectors\n .slice()\n .sort((a, b) => a.appType.localeCompare(b.appType) || a.name.localeCompare(b.name))\n .map((c) => ({ value: c.id, label: c.name, hint: c.appType })),\n });\n if (p.isCancel(choice)) {\n p.cancel(\"Cancelled.\");\n return;\n }\n connector = connectors.find((c) => c.id === (choice as string))!;\n }\n\n p.intro(`Connect ${pc.bold(connector.name)}`);\n\n if (!isOAuth(connector)) {\n // Pre-auth connector: collect credential fields in the terminal.\n const fields = fieldsFor(connector);\n const credentials: Record<string, string> = {};\n for (const field of fields) {\n const secret = SECRET_RE.test(field);\n const value = await (secret ? p.password : p.text)({\n message: field,\n });\n if (p.isCancel(value)) {\n p.cancel(\"Cancelled.\");\n return;\n }\n credentials[field] = value as string;\n }\n const name = await p.text({ message: \"Name for this source (optional)\", placeholder: connector.name });\n if (p.isCancel(name)) {\n p.cancel(\"Cancelled.\");\n return;\n }\n\n const s = p.spinner();\n s.start(\"Validating credentials…\");\n const res = await createLink(connector.id, {\n credentials,\n ...(name ? { name } : {}),\n });\n if (res.status === \"success\") {\n s.stop(\"Connected.\");\n success(`Created source ${pc.bold(res.connection.name)} (${res.connection.shortId}).`);\n return;\n }\n // Fallback: server wants more input — finish in the browser.\n s.stop(\"Continue in your browser…\");\n open(res.redirect_url).catch(() => {});\n info(`Open: ${res.redirect_url}`);\n const result = await pollLink(res.link_token);\n if (result.ok) success(\"Connected.\");\n else throw new Error(result.reason ?? \"Connection failed.\");\n return;\n }\n\n // OAuth connector: mint a link and let the polished web flow handle consent\n // (and any pre-OAuth fields like a project id), then poll for completion.\n const res = await createLink(connector.id, {});\n if (res.status === \"success\") {\n success(`Created source ${pc.bold(res.connection.name)} (${res.connection.shortId}).`);\n return;\n }\n open(res.redirect_url).catch(() => {});\n info(`Complete authorization in your browser:\\n${res.redirect_url}`);\n const s = p.spinner();\n s.start(\"Waiting for you to finish in the browser…\");\n const result = await pollLink(res.link_token);\n if (result.ok) {\n s.stop(\"Connected.\");\n success(\"Source connected.\");\n } else {\n s.stop(\"Failed.\");\n throw new Error(result.reason ?? \"Connection failed.\");\n }\n}\n","import * as p from \"@clack/prompts\";\nimport {\n type Connection,\n deleteConnection,\n getConnection,\n getConnectionConfig,\n listConnections,\n testConnection,\n} from \"../lib/api\";\nimport { info, isJsonMode, pc, printJson, printTable, success } from \"../lib/output\";\n\n/** Resolve a user-supplied id (uuid or shortId) to the connection's real id. */\nasync function resolveConnection(idOrShort: string): Promise<Connection> {\n const all = await listConnections();\n const match = all.find((c) => c.id === idOrShort || c.shortId === idOrShort);\n if (!match) throw new Error(`No source found matching \"${idOrShort}\".`);\n return match;\n}\n\nasync function pickConnection(message: string): Promise<Connection | undefined> {\n const all = await listConnections();\n if (all.length === 0) {\n info(\"No sources connected yet. Run `sequel connect`.\");\n return undefined;\n }\n const choice = await p.select({\n message,\n options: all.map((c) => ({ value: c.shortId, label: `${c.name} (${c.shortId})`, hint: c.type })),\n });\n if (p.isCancel(choice)) return undefined;\n return all.find((c) => c.shortId === (choice as string));\n}\n\nfunction toRow(c: Connection): Record<string, unknown> {\n return { id: c.shortId, name: c.name, type: c.type, created: c.createdAt.slice(0, 10) };\n}\n\nexport async function sourcesList(): Promise<void> {\n const connections = await listConnections();\n if (isJsonMode()) return printJson(connections);\n if (connections.length === 0) return info(\"No sources connected yet. Run `sequel connect`.\");\n printTable(connections.map(toRow), [\"id\", \"name\", \"type\", \"created\"]);\n}\n\nexport async function sourcesActive(): Promise<void> {\n const connections = await listConnections();\n const rows = await Promise.all(\n connections.map(async (c) => {\n let status = \"unknown\";\n try {\n const t = await testConnection(c.id);\n status = t.success ? \"healthy\" : \"error\";\n } catch {\n status = \"error\";\n }\n return { ...toRow(c), status };\n }),\n );\n if (isJsonMode()) return printJson(rows);\n if (rows.length === 0) return info(\"No sources connected yet. Run `sequel connect`.\");\n printTable(rows, [\"id\", \"name\", \"type\", \"status\", \"created\"]);\n}\n\nexport async function sourcesInfo(idOrShort?: string): Promise<void> {\n const conn = idOrShort ? await resolveConnection(idOrShort) : await pickConnection(\"Source to inspect\");\n if (!conn) return;\n const full = await getConnection(conn.id);\n let config: { schemaFilters: string[] | null; instructions: string | null } | null = null;\n try {\n config = await getConnectionConfig(conn.id);\n } catch {\n /* config may be absent */\n }\n if (isJsonMode()) return printJson({ ...full, config });\n\n info(`${pc.bold(full.name)} ${pc.dim(full.shortId)}`);\n info(`type: ${full.type}`);\n info(`id: ${full.id}`);\n info(`created: ${full.createdAt}`);\n if (config?.schemaFilters?.length) info(`schemas: ${config.schemaFilters.join(\", \")}`);\n if (config?.instructions) info(`\\n${pc.dim(config.instructions)}`);\n}\n\nexport async function sourcesDelete(idOrShort?: string): Promise<void> {\n const conn = idOrShort ? await resolveConnection(idOrShort) : await pickConnection(\"Source to delete\");\n if (!conn) return;\n const confirmed = await p.confirm({ message: `Delete ${pc.bold(conn.name)} (${conn.shortId})? This cannot be undone.` });\n if (p.isCancel(confirmed) || !confirmed) {\n info(\"Cancelled.\");\n return;\n }\n await deleteConnection(conn.id);\n success(`Deleted ${conn.name} (${conn.shortId}).`);\n}\n","import { homedir, platform } from \"node:os\";\nimport { join } from \"node:path\";\nimport { existsSync, mkdirSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { dirname } from \"node:path\";\nimport YAML from \"yaml\";\n\nexport type Scope = \"global\" | \"local\";\n\nexport interface InstallOptions {\n apiUrl: string;\n apiKey: string;\n scope: Scope;\n /** Project root for local scope (defaults to cwd). Injectable for tests. */\n cwd?: string;\n /** Home dir override for tests. */\n home?: string;\n}\n\n/** What happened during install — either a file we wrote or a command to run. */\nexport type InstallResult =\n | { kind: \"file\"; path: string }\n | { kind: \"command\"; command: string; args: string[] };\n\nexport interface McpClientDef {\n slug: string;\n name: string;\n scopes: Scope[];\n /** Human-readable target (path or command) for a scope, for previews. */\n describe(opts: InstallOptions): string;\n install(opts: InstallOptions): InstallResult;\n}\n\nconst SERVER_NAME = \"sequel\";\nconst mcpUrl = (apiUrl: string) => `${apiUrl.replace(/\\/$/, \"\")}/mcp`;\nconst bearer = (apiKey: string) => `Bearer ${apiKey}`;\n\nfunction home(opts: InstallOptions): string {\n return opts.home ?? homedir();\n}\nfunction cwd(opts: InstallOptions): string {\n return opts.cwd ?? process.cwd();\n}\n\n/** OS-specific application-support dir for a vendor folder. */\nfunction appSupport(opts: InstallOptions, vendor: string): string {\n const h = home(opts);\n switch (platform()) {\n case \"darwin\":\n return join(h, \"Library\", \"Application Support\", vendor);\n case \"win32\":\n return join(process.env.APPDATA ?? join(h, \"AppData\", \"Roaming\"), vendor);\n default:\n return join(process.env.XDG_CONFIG_HOME ?? join(h, \".config\"), vendor);\n }\n}\n\n/** Read+merge+write a JSON config, preserving every other key already present. */\nfunction mergeJson(path: string, mutate: (cfg: Record<string, unknown>) => void): void {\n let cfg: Record<string, unknown> = {};\n if (existsSync(path)) {\n try {\n cfg = JSON.parse(readFileSync(path, \"utf8\")) as Record<string, unknown>;\n } catch {\n cfg = {};\n }\n }\n mutate(cfg);\n mkdirSync(dirname(path), { recursive: true });\n writeFileSync(path, `${JSON.stringify(cfg, null, 2)}\\n`);\n}\n\nfunction mergeYaml(path: string, mutate: (cfg: Record<string, unknown>) => void): void {\n let cfg: Record<string, unknown> = {};\n if (existsSync(path)) {\n try {\n cfg = (YAML.parse(readFileSync(path, \"utf8\")) as Record<string, unknown>) ?? {};\n } catch {\n cfg = {};\n }\n }\n mutate(cfg);\n mkdirSync(dirname(path), { recursive: true });\n writeFileSync(path, YAML.stringify(cfg));\n}\n\nfunction setNested(cfg: Record<string, unknown>, key: string, value: unknown): void {\n const obj = (cfg[key] as Record<string, unknown>) ?? {};\n obj[SERVER_NAME] = value;\n cfg[key] = obj;\n}\n\n// ── Client definitions ──────────────────────────────────────────────────────────\n\nexport const mcpClients: McpClientDef[] = [\n {\n slug: \"claude\",\n name: \"Claude Desktop\",\n scopes: [\"global\"],\n describe: (o) => join(appSupport(o, \"Claude\"), \"claude_desktop_config.json\"),\n install(o) {\n const path = join(appSupport(o, \"Claude\"), \"claude_desktop_config.json\");\n mergeJson(path, (cfg) =>\n setNested(cfg, \"mcpServers\", {\n url: mcpUrl(o.apiUrl),\n headers: { Authorization: bearer(o.apiKey) },\n }),\n );\n return { kind: \"file\", path };\n },\n },\n {\n slug: \"claude-code\",\n name: \"Claude Code\",\n scopes: [\"global\", \"local\"],\n describe: (o) =>\n `claude mcp add --scope ${o.scope === \"global\" ? \"user\" : \"local\"} --transport http ${SERVER_NAME} …`,\n install(o) {\n return {\n kind: \"command\",\n command: \"claude\",\n args: [\n \"mcp\",\n \"add\",\n \"--scope\",\n o.scope === \"global\" ? \"user\" : \"local\",\n \"--transport\",\n \"http\",\n SERVER_NAME,\n mcpUrl(o.apiUrl),\n \"--header\",\n `Authorization: ${bearer(o.apiKey)}`,\n ],\n };\n },\n },\n {\n slug: \"cursor\",\n name: \"Cursor\",\n scopes: [\"global\", \"local\"],\n describe: (o) => (o.scope === \"global\" ? join(home(o), \".cursor\", \"mcp.json\") : join(cwd(o), \".cursor\", \"mcp.json\")),\n install(o) {\n const path = o.scope === \"global\" ? join(home(o), \".cursor\", \"mcp.json\") : join(cwd(o), \".cursor\", \"mcp.json\");\n mergeJson(path, (cfg) =>\n setNested(cfg, \"mcpServers\", {\n url: mcpUrl(o.apiUrl),\n headers: { Authorization: bearer(o.apiKey) },\n }),\n );\n return { kind: \"file\", path };\n },\n },\n {\n slug: \"vscode\",\n name: \"VS Code\",\n scopes: [\"global\", \"local\"],\n describe: (o) =>\n o.scope === \"global\" ? join(appSupport(o, \"Code\"), \"User\", \"mcp.json\") : join(cwd(o), \".vscode\", \"mcp.json\"),\n install(o) {\n const path =\n o.scope === \"global\" ? join(appSupport(o, \"Code\"), \"User\", \"mcp.json\") : join(cwd(o), \".vscode\", \"mcp.json\");\n mergeJson(path, (cfg) =>\n setNested(cfg, \"servers\", {\n url: mcpUrl(o.apiUrl),\n type: \"http\",\n headers: { Authorization: bearer(o.apiKey) },\n }),\n );\n return { kind: \"file\", path };\n },\n },\n {\n slug: \"windsurf\",\n name: \"Windsurf\",\n scopes: [\"global\"],\n describe: (o) => join(home(o), \".codeium\", \"windsurf\", \"mcp_config.json\"),\n install(o) {\n const path = join(home(o), \".codeium\", \"windsurf\", \"mcp_config.json\");\n mergeJson(path, (cfg) =>\n setNested(cfg, \"mcpServers\", {\n // Windsurf uses `serverUrl`, not `url`.\n serverUrl: mcpUrl(o.apiUrl),\n headers: { Authorization: bearer(o.apiKey) },\n }),\n );\n return { kind: \"file\", path };\n },\n },\n {\n slug: \"zed\",\n name: \"Zed\",\n scopes: [\"global\", \"local\"],\n describe: (o) =>\n o.scope === \"global\" ? join(home(o), \".config\", \"zed\", \"settings.json\") : join(cwd(o), \".zed\", \"settings.json\"),\n install(o) {\n const path =\n o.scope === \"global\"\n ? join(home(o), \".config\", \"zed\", \"settings.json\")\n : join(cwd(o), \".zed\", \"settings.json\");\n mergeJson(path, (cfg) =>\n setNested(cfg, \"context_servers\", {\n url: mcpUrl(o.apiUrl),\n settings: { headers: { Authorization: bearer(o.apiKey) } },\n }),\n );\n return { kind: \"file\", path };\n },\n },\n {\n slug: \"codex\",\n name: \"Codex\",\n scopes: [\"global\"],\n describe: (o) => join(home(o), \".codex\", \"config.yaml\"),\n install(o) {\n const path = join(home(o), \".codex\", \"config.yaml\");\n mergeYaml(path, (cfg) =>\n setNested(cfg, \"mcp_servers\", {\n url: mcpUrl(o.apiUrl),\n headers: { Authorization: bearer(o.apiKey) },\n }),\n );\n return { kind: \"file\", path };\n },\n },\n];\n\nexport function getMcpClient(slug: string): McpClientDef | undefined {\n return mcpClients.find((c) => c.slug === slug);\n}\n","import { execFileSync } from \"node:child_process\";\nimport * as p from \"@clack/prompts\";\nimport { createApiKey } from \"../lib/api\";\nimport { isLoggedIn } from \"../lib/auth\";\nimport { readConfig, resolveApiUrl } from \"../lib/config\";\nimport { type Scope, getMcpClient, mcpClients } from \"../lib/mcp-clients\";\nimport { pc, success } from \"../lib/output\";\n\nexport async function installCommand(slugArg?: string): Promise<void> {\n p.intro(pc.cyan(\"Install the Sequel MCP server\"));\n\n if (!isLoggedIn()) {\n p.cancel(\"Not logged in. Run `sequel login` first.\");\n return;\n }\n\n let slug = slugArg;\n if (!slug) {\n const choice = await p.select({\n message: \"Which coding agent do you want to install Sequel into?\",\n options: mcpClients.map((c) => ({ value: c.slug, label: c.name })),\n });\n if (p.isCancel(choice)) return p.cancel(\"Cancelled.\");\n slug = choice as string;\n }\n\n const client = getMcpClient(slug);\n if (!client) throw new Error(`Unknown agent \"${slug}\". Options: ${mcpClients.map((c) => c.slug).join(\", \")}`);\n\n let scope: Scope = client.scopes[0];\n if (client.scopes.length > 1) {\n const choice = await p.select({\n message: \"Install scope\",\n options: [\n { value: \"global\", label: \"Global\", hint: \"available everywhere on this machine\" },\n { value: \"local\", label: \"Local\", hint: \"this project only\" },\n ].filter((o) => client.scopes.includes(o.value as Scope)),\n });\n if (p.isCancel(choice)) return p.cancel(\"Cancelled.\");\n scope = choice as Scope;\n }\n\n const config = readConfig();\n const apiUrl = resolveApiUrl(config);\n\n const s = p.spinner();\n s.start(\"Creating a Sequel API key for this agent…\");\n let key: string;\n try {\n ({ key } = await createApiKey(`Sequel CLI (${client.name})`));\n } catch (err) {\n s.stop(\"Failed to create API key.\");\n throw err;\n }\n s.stop(\"API key created.\");\n\n const result = client.install({ apiUrl, apiKey: key, scope });\n\n if (result.kind === \"command\") {\n // e.g. Claude Code: run `claude mcp add …`.\n try {\n execFileSync(result.command, result.args, { stdio: \"inherit\" });\n } catch {\n throw new Error(\n `Failed to run \\`${result.command}\\`. Make sure it's installed, or run manually:\\n${result.command} ${result.args.join(\" \")}`,\n );\n }\n success(`Installed Sequel into ${client.name} (${scope}).`);\n } else {\n success(`Installed Sequel into ${client.name}.`);\n p.log.info(`Config written to ${pc.dim(result.path)}`);\n }\n\n p.outro(`Restart ${client.name} and ask it to \"list my Sequel connections\" to verify.`);\n}\n","import { search } from \"../lib/api\";\nimport { info, isJsonMode, pc, printJson } from \"../lib/output\";\n\nexport async function searchCommand(useCase: string, opts: { connection?: string[] }): Promise<void> {\n const res = await search(useCase, opts.connection);\n if (isJsonMode()) return printJson(res);\n\n if (res.results.length === 0) {\n info(\"No matching tools found across your connected sources.\");\n return;\n }\n\n for (const r of res.results) {\n info(`\\n${pc.bold(r.connection_name)} ${pc.dim(`(${r.connection_id} · ${r.app_id})`)}`);\n if (r.instructions) info(pc.dim(r.instructions));\n for (const tool of r.tools) {\n info(` ${pc.cyan(tool.tool_id)}`);\n if (tool.relevant_tables?.length) info(` tables: ${tool.relevant_tables.join(\", \")}`);\n }\n info(pc.dim(` → sequel execute ${r.connection_id} ${r.tools[0]?.tool_id ?? \"<tool>\"} -d '{…}'`));\n }\n}\n","import { execute } from \"../lib/api\";\nimport { info, isJsonMode, pc, printJson, printTable } from \"../lib/output\";\n\nexport async function executeCommand(\n connectionId: string,\n tool: string,\n opts: { data?: string },\n): Promise<void> {\n let params: Record<string, unknown> = {};\n if (opts.data) {\n try {\n params = JSON.parse(opts.data) as Record<string, unknown>;\n } catch {\n throw new Error(\"Invalid JSON passed to -d/--data.\");\n }\n }\n\n const res = await execute(connectionId, tool, params);\n if (isJsonMode()) return printJson(res);\n\n if (res.data.length === 0) {\n info(pc.dim(\"(0 rows)\"));\n return;\n }\n printTable(res.data, res.columns.length ? res.columns : undefined);\n info(pc.dim(`\\n${res.row_count} row(s)${res.truncated ? \" (truncated)\" : \"\"}`));\n}\n","import { Command } from \"commander\";\nimport { ApiError } from \"./lib/api\";\nimport { fail, setJsonMode } from \"./lib/output\";\nimport { loginCommand } from \"./commands/login\";\nimport { logoutCommand } from \"./commands/logout\";\nimport { switchCommand } from \"./commands/switch\";\nimport { connectCommand } from \"./commands/connect\";\nimport { sourcesActive, sourcesDelete, sourcesInfo, sourcesList } from \"./commands/sources\";\nimport { installCommand } from \"./commands/install\";\nimport { searchCommand } from \"./commands/search\";\nimport { executeCommand } from \"./commands/execute\";\n\nconst program = new Command();\n\nprogram\n .name(\"sequel\")\n .description(\"Sequel CLI — connect data sources and run tools from your terminal\")\n .version(\"0.0.0\")\n .option(\"--json\", \"output machine-readable JSON\")\n .enablePositionalOptions();\n\n/** Wrap a command action with shared --json handling and error reporting. */\nfunction action<A extends unknown[]>(fn: (...args: A) => Promise<void>) {\n return async (...args: A) => {\n if (program.opts().json) setJsonMode(true);\n try {\n await fn(...args);\n } catch (err) {\n if (err instanceof ApiError && err.status === 401) {\n fail(\"Unauthorized. Run `sequel login` to sign in again.\");\n } else {\n fail(err instanceof Error ? err.message : String(err));\n }\n process.exitCode = 1;\n }\n };\n}\n\nprogram.command(\"login\").description(\"Sign in to Sequel\").action(action(loginCommand));\nprogram.command(\"logout\").description(\"Sign out and remove cached credentials\").action(action(logoutCommand));\nprogram.command(\"switch\").description(\"Switch the active organization\").action(action(switchCommand));\n\nprogram\n .command(\"connect\")\n .argument(\"[source]\", \"connector id (e.g. postgres); omit to choose interactively\")\n .description(\"Connect a new data source\")\n .action(action(connectCommand));\n\nconst sources = program.command(\"sources\").description(\"Manage connected data sources\");\nsources.command(\"list\", { isDefault: true }).description(\"List connected sources\").action(action(sourcesList));\nsources.command(\"active\").description(\"List sources with live health status\").action(action(sourcesActive));\nsources\n .command(\"info\")\n .argument(\"[id]\", \"source id or short id\")\n .description(\"Show details for a source\")\n .action(action(sourcesInfo));\nsources\n .command(\"delete\")\n .argument(\"[id]\", \"source id or short id\")\n .description(\"Delete a source\")\n .action(action(sourcesDelete));\n\nprogram\n .command(\"install\")\n .argument(\"[agent]\", \"coding agent slug (e.g. cursor, claude-code)\")\n .description(\"Install the Sequel MCP server into a coding agent\")\n .action(action(installCommand));\n\nprogram\n .command(\"search\")\n .argument(\"<usecase>\", \"what you want to do, e.g. \\\"monthly revenue\\\"\")\n .option(\"-c, --connection <id...>\", \"limit to specific connection short ids\")\n .description(\"Find the right tools for a use case across your sources\")\n .action(action((usecase: string, opts: { connection?: string[] }) => searchCommand(usecase, opts)));\n\nprogram\n .command(\"execute\")\n .argument(\"<connection_id>\", \"connection short id\")\n .argument(\"<tool>\", \"tool id, e.g. postgres.query\")\n .option(\"-d, --data <json>\", \"tool input as a JSON string\")\n .description(\"Execute a tool against a connection\")\n .action(action((connectionId: string, tool: string, opts: { data?: string }) => executeCommand(connectionId, tool, opts)));\n\nprogram.parseAsync(process.argv).catch((err) => {\n fail(err instanceof Error ? err.message : String(err));\n process.exit(1);\n});\n"],"mappings":";;;;;;;;;;;;;;;;;;;AAKA,MAAa,kBAAkB;;AA2C/B,SAAgB,YAAoB;AAClC,QAAO,QAAQ,IAAI,qBAAqB,KAAK,SAAS,EAAE,UAAU;AACnE;AAED,SAAgB,aAAqB;AACnC,QAAO,KAAK,WAAW,EAAE,YAAY;AACtC;;AAGD,SAAgB,cAAcA,QAAoC;AAChE,QAAO,QAAQ,IAAI,kBAAkB,QAAQ,UAAU;AACxD;AAED,SAAS,cAA0B;AACjC,QAAO;EAAE,SAAS;EAAG,QAAQ,eAAe;EAAE,QAAQ,CAAE;CAAE;AAC3D;;AAGD,SAAgB,aAAyB;CACvC,MAAM,OAAO,YAAY;AACzB,MAAK,WAAW,KAAK,CAAE,QAAO,aAAa;AAC3C,KAAI;EACF,MAAM,SAAS,KAAK,MAAM,aAAa,MAAM,OAAO,CAAC;AACrD,OAAK,iBAAiB,WAAW,aAAa,OAAO,OAAQ,QAAO,aAAa;AACjF,SAAO,WAAW,CAAE;AACpB,SAAO;CACR,QAAO;AAEN,SAAO,aAAa;CACrB;AACF;;AAGD,SAAgB,YAAYC,QAA0B;CACpD,MAAM,MAAM,WAAW;AACvB,WAAU,KAAK;EAAE,WAAW;EAAM,MAAM;CAAO,EAAC;CAChD,MAAM,OAAO,YAAY;AACzB,eAAc,OAAO,EAAE,KAAK,UAAU,QAAQ,MAAM,EAAE,CAAC,KAAK,EAAE,MAAM,IAAO,EAAC;AAE5E,WAAU,MAAM,IAAM;AACvB;;AAGD,SAAgB,cAAoB;CAClC,MAAM,OAAO,YAAY;AACzB,KAAI,WAAW,KAAK,CAAE,QAAO,KAAK;AACnC;AAED,SAAgBC,aAAWD,QAA6B;AACtD,QAAO,QAAQ,OAAO,eAAe,OAAO,OAAO,OAAO,aAAa;AACxE;;;;;ACnFD,MAAM,iBAAiB;AAEvB,SAAS,UAAUE,KAAqB;AACtC,QAAO,IAAI,SAAS,YAAY;AACjC;;AAGD,SAAgB,eAAwD;CACtE,MAAM,WAAW,UAAU,YAAY,GAAG,CAAC;CAC3C,MAAM,YAAY,UAAU,WAAW,SAAS,CAAC,OAAO,SAAS,CAAC,QAAQ,CAAC;AAC3E,QAAO;EAAE;EAAU;CAAW;AAC/B;;AAiBD,eAAe,UAAUC,QAAgBC,QAAwD;CAC/F,MAAM,MAAM,MAAM,OAAO,EAAE,OAAO,eAAe;EAC/C,QAAQ;EACR,SAAS,EAAE,gBAAgB,oCAAqC;EAChE,MAAM,IAAI,gBAAgB,QAAQ,UAAU;CAC7C,EAAC;AACF,MAAK,IAAI,IAAI;EACX,MAAM,OAAO,MAAM,IAAI,MAAM,CAAC,MAAM,MAAM,GAAG;AAC7C,QAAM,IAAI,OAAO,wBAAwB,IAAI,OAAO,KAAK,KAAK;CAC/D;AACD,QAAQ,MAAM,IAAI,MAAM;AACzB;;AAGD,eAAe,eAAeD,QAAgBE,aAAsC;CAClF,MAAM,MAAM,MAAM,OAAO,EAAE,OAAO,kBAAkB;EAClD,QAAQ;EACR,SAAS,EAAE,gBAAgB,mBAAoB;EAC/C,MAAM,KAAK,UAAU;GAAE,aAAa;GAAc,eAAe,CAAC,WAAY;EAAE,EAAC;CAClF,EAAC;AACF,MAAK,IAAI,IAAI;EACX,MAAM,OAAO,MAAM,IAAI,MAAM,CAAC,MAAM,MAAM,GAAG;AAC7C,QAAM,IAAI,OAAO,8BAA8B,IAAI,OAAO,KAAK,KAAK;CACrE;CACD,MAAM,OAAQ,MAAM,IAAI,MAAM;AAC9B,QAAO,KAAK;AACb;AAED,eAAe,YAAYF,QAAgBG,aAAsC;CAC/E,MAAM,MAAM,MAAM,OAAO,EAAE,OAAO,YAAY,EAC5C,SAAS,EAAE,gBAAgB,SAAS,YAAY,EAAG,EACpD,EAAC;AACF,MAAK,IAAI,GAAI,OAAM,IAAI,OAAO,8BAA8B,IAAI,OAAO;AACvE,QAAQ,MAAM,IAAI,MAAM;AACzB;AAED,eAAsB,mBAAmBH,QAAgBG,aAAwC;CAC/F,MAAM,MAAM,MAAM,OAAO,EAAE,OAAO,iBAAiB,EACjD,SAAS,EAAE,gBAAgB,SAAS,YAAY,EAAG,EACpD,EAAC;AACF,MAAK,IAAI,GAAI,OAAM,IAAI,OAAO,gCAAgC,IAAI,OAAO;CACzE,MAAM,OAAQ,MAAM,IAAI,MAAM;AAI9B,QAAO,KAAK,IAAI,CAAC,OAAO;EACtB,IAAI,EAAE,aAAa;EACnB,MAAM,EAAE,aAAa;EACrB,MAAM,EAAE,aAAa;EACrB,MAAM,EAAE;CACT,GAAE;AACJ;;;;;AAMD,SAAS,gBACPC,eAC2F;CAC3F,IAAIC;CACJ,IAAIC;CACJ,MAAM,OAAO,IAAI,QAAgB,CAAC,SAAS,WAAW;AACpD,gBAAc;AACd,eAAa;CACd;CAED,MAAM,SAAS,aAAa,CAAC,KAAK,QAAQ;EACxC,MAAM,MAAM,IAAI,IAAI,IAAI,OAAO,KAAK;AACpC,MAAI,IAAI,aAAa,aAAa;AAChC,OAAI,UAAU,IAAI,CAAC,IAAI,YAAY;AACnC;EACD;EACD,MAAM,QAAQ,IAAI,aAAa,IAAI,QAAQ;EAC3C,MAAM,gBAAgB,IAAI,aAAa,IAAI,QAAQ;EACnD,MAAM,eAAe,IAAI,aAAa,IAAI,OAAO;EAEjD,MAAM,SAAS,CAACC,OAAeC,YAAoB;AACjD,OAAI,UAAU,KAAK,EAAE,gBAAgB,2BAA4B,EAAC;AAClE,OAAI,KACD,oCAAoC,MAAM,wFAAwF,MAAM,UAAU,QAAQ,8EAC5J;EACF;AAED,MAAI,OAAO;AACT,UAAO,mBAAmB,qCAAqC,MAAM,EAAE;AACvE,cAAW,IAAI,OAAO,wBAAwB,MAAM,GAAG;AACvD;EACD;AACD,OAAK,iBAAiB,kBAAkB,eAAe;AACrD,UAAO,kBAAkB,oDAAoD;AAC7E,cAAW,IAAI,MAAM,oCAAoC;AACzD;EACD;AACD,OAAK,cAAc;AACjB,UAAO,kBAAkB,sCAAsC;AAC/D,cAAW,IAAI,MAAM,8BAA8B;AACnD;EACD;AACD,SAAO,uBAAuB,2BAA2B;AACzD,cAAY,aAAa;CAC1B,EAAC;CAEF,MAAM,OAAO,IAAI,QAAgB,CAAC,SAAS,WAAW;AACpD,SAAO,GAAG,SAAS,OAAO;AAC1B,SAAO,OAAO,GAAG,aAAa,MAAM,QAAS,OAAO,SAAS,CAAiB,KAAK,CAAC;CACrF;AAED,QAAO;EAAE;EAAQ;EAAM;CAAM;AAC9B;;;;;;;;AAeD,eAAsB,aAAaC,SAAsD;CACvF,MAAM,SAAS,YAAY;CAC3B,MAAM,SAAS,cAAc,OAAO;CAEpC,MAAM,EAAE,UAAU,WAAW,GAAG,cAAc;CAC9C,MAAM,QAAQ,UAAU,YAAY,GAAG,CAAC;CAExC,MAAM,EAAE,QAAQ,MAAM,aAAa,MAAM,aAAa,GAAG,gBAAgB,MAAM;CAC/E,MAAM,OAAO,MAAM;CACnB,MAAM,eAAe,mBAAmB,KAAK;AAE7C,KAAI;EACF,MAAM,WAAW,MAAM,eAAe,QAAQ,YAAY;EAE1D,MAAM,eAAe,IAAI,KAAK,EAAE,OAAO;AACvC,eAAa,aAAa,IAAI,aAAa,SAAS;AACpD,eAAa,aAAa,IAAI,gBAAgB,YAAY;AAC1D,eAAa,aAAa,IAAI,iBAAiB,OAAO;AACtD,eAAa,aAAa,IAAI,kBAAkB,UAAU;AAC1D,eAAa,aAAa,IAAI,yBAAyB,OAAO;AAC9D,eAAa,aAAa,IAAI,SAAS,MAAM;AAE7C,OAAK,SAAS,OAEZ,MAAK,aAAa,UAAU,CAAC,CAAC,MAAM,MAAM,CAAE,EAAC;AAG/C,UAAQ,OAAO,OAAO,gCAAgC,aAAa,UAAU,CAAC,MAAM;EAEpF,MAAM,OAAO,MAAM;EAEnB,MAAM,QAAQ,MAAM,UAAU,QAAQ;GACpC,YAAY;GACZ;GACA,cAAc;GACd,WAAW;GACX,eAAe;EAChB,EAAC;EAEF,MAAM,KAAK,MAAM,YAAY,QAAQ,MAAM,aAAa;EACxD,MAAM,OAAO,MAAM,mBAAmB,QAAQ,MAAM,aAAa,CAAC,MAAM,MAAM,OAAO,QAAQ,CAAE,EAAC;EAEhG,MAAMC,OAAmB;GACvB,GAAG;GACH,SAAS;GACT;GACA;GACA,aAAa,GAAG;GAChB,QAAQ;IACN,GAAG,OAAO;KACT,GAAG,iBAAiB;KACnB,aAAa,MAAM;KACnB,cAAc,MAAM;KACpB,WAAW,KAAK,KAAK,GAAG,MAAM,aAAa;IAC5C;GACF;GACD,MAAM;IAAE,IAAI,GAAG;IAAI,OAAO,GAAG;IAAO,MAAM,GAAG;GAAM;GACnD;EACD;AACD,cAAY,KAAK;AAEjB,SAAO;GACL,MAAM,KAAK;GACX,KAAK,KAAK,KAAK,CAAC,MAAM,EAAE,OAAO,GAAG,eAAe;GACjD,gBAAgB,GAAG;EACpB;CACF,UAAS;AACR,SAAO,OAAO;CACf;AACF;;AAGD,SAAgB,aAAsB;CACpC,MAAM,SAAS,YAAY;CAC3B,MAAM,QAAQ,OAAO;AACrB,QAAO,QAAQ,SAAS,OAAO,OAAO,OAAO;AAC9C;;;;;AAMD,eAAsB,sBAAsE;CAC1F,MAAM,SAAS,YAAY;CAC3B,MAAM,QAAQ,OAAO;AACrB,MAAK,UAAU,OAAO,OAAO,OAC3B,OAAM,IAAI,MAAM;CAGlB,MAAMC,QAAoB,OAAO,OAAO;AACxC,KAAI,MAAM,YAAY,iBAAiB,KAAK,KAAK,CAC/C,QAAO;EAAE,OAAO,MAAM;EAAa;CAAQ;CAI7C,MAAM,SAAS,cAAc,OAAO;AACpC,KAAI;EACF,MAAM,YAAY,MAAM,UAAU,QAAQ;GACxC,YAAY;GACZ,eAAe,MAAM;GACrB,WAAW,OAAO,YAAY;EAC/B,EAAC;AACF,SAAO,OAAO,SAAS;GACrB,aAAa,UAAU;GACvB,cAAc,UAAU;GACxB,WAAW,KAAK,KAAK,GAAG,UAAU,aAAa;EAChD;AACD,cAAY,OAAO;AACnB,SAAO;GAAE,OAAO,UAAU;GAAc;EAAQ;CACjD,QAAO;AACN,QAAM,IAAI,MACR;CAEH;AACF;;;;ACtRD,IAAa,WAAb,cAA8B,MAAM;CAClC,YACSC,QACPC,SACA;AACA,QAAM,QAAQ;EA6MjB,KAhNU;AAIP,OAAK,OAAO;CACb;AACF;;;;;AAoBD,eAAsB,QAAqBC,MAAcC,UAA0B,CAAE,GAAc;CACjG,MAAM,EAAE,OAAO,QAAQ,GAAG,MAAM,qBAAqB;CACrD,MAAM,SAAS,cAAc,OAAO;CACpC,MAAM,QAAQ,OAAO;CACrB,MAAM,UAAU,QAAQ,OAAO;CAE/B,MAAM,MAAM,IAAI,KAAK,EAAE,OAAO,EAAE,KAAK;AACrC,KAAI,YAAY,WAAW,MAAO,KAAI,aAAa,IAAI,kBAAkB,MAAM;AAC/E,MAAK,MAAM,CAAC,GAAG,EAAE,IAAI,OAAO,QAAQ,QAAQ,SAAS,CAAE,EAAC,CACtD,KAAI,aAAiB,KAAI,aAAa,IAAI,GAAG,EAAE;CAGjD,IAAI,UAAU,QAAQ;AACtB,MAAK,YAAY,oBAAoB,YAAY,sBAAsB,MACrE,WAAU;EAAE,GAAI,WAAW,CAAE;GAAI,UAAU;CAAO;CAGpD,MAAMC,UAAkC,EAAE,gBAAgB,SAAS,MAAM,EAAG;CAC5E,IAAIC;AACJ,KAAI,oBAAuB;AACzB,UAAQ,kBAAkB;AAC1B,SAAO,KAAK,UAAU,QAAQ;CAC/B;CAED,MAAM,MAAM,MAAM,MAAM,IAAI,UAAU,EAAE;EAAE,QAAQ,QAAQ,UAAU;EAAO;EAAS;CAAM,EAAC;AAE3F,MAAK,IAAI,IAAI;EACX,IAAI,WAAW,kBAAkB,IAAI,OAAO;EAC5C,MAAMC,SAAO,MAAM,IAAI,MAAM,CAAC,MAAM,MAAM,GAAG;AAC7C,MAAI;GACF,MAAM,OAAO,KAAK,MAAMA,OAAK;AAC7B,OAAI,KAAK,MAAO,WAAU,KAAK;EAChC,QAAO;AACN,OAAIA,OAAM,WAAUA;EACrB;AACD,QAAM,IAAI,SAAS,IAAI,QAAQ;CAChC;AAED,KAAI,IAAI,WAAW,IAAK;CACxB,MAAM,OAAO,MAAM,IAAI,MAAM;AAC7B,QAAQ,OAAO,KAAK,MAAM,KAAK;AAChC;;AAGD,eAAsB,cAA+B;CACnD,MAAM,EAAE,QAAQ,GAAG,MAAM,qBAAqB;AAC9C,MAAK,OAAO,YAAa,OAAM,IAAI,MAAM;AACzC,QAAO,OAAO;AACf;AAgED,SAAgB,iBAAuC;AACrD,QAAO,QAAqB,eAAe,EAAE,KAAK,OAAQ,EAAC;AAC5D;AAED,SAAgB,kBAAyC;AACvD,QAAO,QAAsB,eAAe;AAC7C;AAED,SAAgB,cAAcC,IAAiC;AAC7D,QAAO,SAAqB,eAAe,GAAG,EAAE;AACjD;AAED,SAAgB,iBAAiBA,IAAiC;AAChE,QAAO,SAAqB,eAAe,GAAG,GAAG,EAAE,QAAQ,SAAU,EAAC;AACvE;AAED,SAAgB,eAAeA,IAA4D;AACzF,QAAO,SAAS,eAAe,GAAG,QAAQ;EAAE,QAAQ;EAAQ,KAAK;CAAkB,EAAC;AACrF;AAED,SAAgB,oBACdA,IAC0E;AAC1E,QAAO,SAAS,eAAe,GAAG,SAAS;AAC5C;;AAGD,SAAgB,WAAWC,OAAeC,MAA4D;AAGpG,QAAO,SAA6B,QAAQ,MAAM,GAAG;EAAE,QAAQ;EAAQ,KAAK;EAAQ;CAAM,EAAC;AAC5F;;;;;;AAOD,SAAgB,cAAcC,OAAoC;AAChE,QAAO,SAAqB,QAAQ,MAAM,UAAU,EAAE,KAAK,OAAQ,EAAC;AACrE;AAED,SAAgB,QACdC,cACAC,MACAC,QACwB;AACxB,QAAO,QAAuB,YAAY;EACxC,QAAQ;EACR,KAAK;EACL,MAAM;GAAE,eAAe;GAAc;GAAM;EAAQ;CACpD,EAAC;AACH;AAED,SAAgB,OAAOC,SAAiBC,eAAgE;AACtG,QAAO,QAAqC,WAAW;EACrD,QAAQ;EACR,KAAK;EACL,MAAM;GACJ,cAAc,cAAc,QAAQ;GACpC,UAAU;GACV,gBAAgB;EACjB;CACF,EAAC;AACH;AAED,eAAsB,aAAaC,MAA2D;CAC5F,MAAM,QAAQ,MAAM,aAAa;AACjC,QAAO,SAAS,iBAAiB,MAAM,YAAY;EAAE,QAAQ;EAAQ,KAAK;EAAQ,MAAM,EAAE,KAAM;CAAE,EAAC;AACpG;;;;;AC/MD,IAAI,WAAW;AACf,SAAgB,YAAYC,IAAmB;AAC7C,YAAW;AACZ;AACD,SAAgB,aAAsB;AACpC,QAAO;AACR;AAED,SAAgB,UAAUC,MAAqB;AAC7C,SAAQ,OAAO,OAAO,EAAE,KAAK,UAAU,MAAM,MAAM,EAAE,CAAC,IAAI;AAC3D;AAED,SAAS,KAAKC,OAAwB;AACpC,KAAI,UAAU,QAAQ,iBAAqB,QAAO;AAClD,YAAW,UAAU,SAAU,QAAO,KAAK,UAAU,MAAM;AAC3D,QAAO,OAAO,MAAM;AACrB;;;;;AAMD,SAAgB,YAAYC,MAAsCC,SAA4B;AAC5F,KAAI,KAAK,WAAW,EAAG,QAAO,GAAG,IAAI,YAAY;CACjD,MAAM,OAAO,WAAW,OAAO,KAAK,KAAK,GAAG;CAC5C,MAAM,SAAS,KAAK,IAAI,CAAC,MAAM,KAAK,IAAI,EAAE,QAAQ,GAAG,KAAK,IAAI,CAAC,MAAM,KAAK,EAAE,GAAG,CAAC,OAAO,CAAC,CAAC;CAEzF,MAAM,SAAS,KAAK,IAAI,CAAC,GAAG,MAAM,GAAG,KAAK,EAAE,OAAO,OAAO,GAAG,CAAC,CAAC,CAAC,KAAK,KAAK;CAC1E,MAAM,MAAM,KAAK,IAAI,CAAC,GAAG,MAAM,IAAI,OAAO,OAAO,GAAG,CAAC,CAAC,KAAK,KAAK;CAChE,MAAM,OAAO,KACV,IAAI,CAAC,MAAM,KAAK,IAAI,CAAC,GAAG,MAAM,KAAK,EAAE,GAAG,CAAC,OAAO,OAAO,GAAG,CAAC,CAAC,KAAK,KAAK,CAAC,CACvE,KAAK,KAAK;AAEb,SAAQ,EAAE,OAAO,IAAI,GAAG,IAAI,IAAI,CAAC,IAAI,KAAK;AAC3C;AAED,SAAgB,WAAWD,MAAsCC,SAA0B;AACzF,SAAQ,OAAO,OAAO,EAAE,YAAY,MAAM,QAAQ,CAAC,IAAI;AACxD;AAED,SAAgB,QAAQC,SAAuB;AAC7C,SAAQ,OAAO,OAAO,EAAE,GAAG,MAAM,IAAI,CAAC,GAAG,QAAQ,IAAI;AACtD;AAED,SAAgB,KAAKA,SAAuB;AAC1C,SAAQ,OAAO,OAAO,EAAE,QAAQ,IAAI;AACrC;AAED,SAAgB,KAAKA,SAAuB;AAC1C,SAAQ,OAAO,OAAO,EAAE,GAAG,IAAI,IAAI,CAAC,GAAG,QAAQ,IAAI;AACpD;;;;ACnDD,eAAsB,eAA8B;AAClD,KAAE,MAAM,GAAG,KAAK,oBAAoB,CAAC;AACrC,KAAE,IAAI,KAAK,qCAAqC;CAChD,MAAM,MAAM,MAAM,cAAc;AAChC,UAAS,eAAe,GAAG,KAAK,IAAI,KAAK,MAAM,CAAC,EAAE,IAAI,OAAO,KAAK,GAAG,KAAK,IAAI,IAAI,KAAK,CAAC,IAAI,GAAG,EAAE;AACjG,KAAE,MAAM,iEAAiE;AAC1E;;;;ACPD,eAAsB,gBAA+B;CACnD,MAAM,SAAS,YAAY;AAC3B,MAAK,aAAW,OAAO,EAAE;AACvB,OAAK,yBAAyB;AAC9B;CACD;AACD,cAAa;AACb,SAAQ,mEAAmE;AAC5E;;;;ACND,eAAsB,gBAA+B;CACnD,MAAM,SAAS,YAAY;AAC3B,MAAK,aAAW,OAAO,CACrB,OAAM,IAAI,MAAM;CAIlB,IAAI,OAAO,OAAO,QAAQ,CAAE;AAC5B,KAAI;EACF,MAAM,EAAE,OAAO,GAAG,MAAM,qBAAqB;AAC7C,SAAO,MAAM,mBAAmB,cAAc,OAAO,EAAE,MAAM;AAC7D,cAAY;GAAE,GAAG,YAAY;GAAE;EAAM,EAAC;CACvC,QAAO,CAEP;AACD,KAAI,KAAK,WAAW,EAAG,OAAM,IAAI,MAAM;CAEvC,MAAM,YAAY,MAAM,IAAE,OAAO;EAC/B,SAAS;EACT,SAAS,KAAK,IAAI,CAAC,OAAO;GACxB,OAAO,EAAE;GACT,OAAO,EAAE,OAAO,OAAO,eAAe,EAAE,EAAE,KAAK,GAAG,GAAG,IAAI,YAAY,CAAC,IAAI,EAAE;GAC5E,MAAM,OAAO,OAAO,EAAE,MAAM,EAAE,OAAO;EACtC,GAAE;CACJ,EAAC;AACF,KAAI,IAAE,SAAS,UAAU,EAAE;AACzB,MAAE,OAAO,aAAa;AACtB;CACD;CAED,MAAM,QAAQ;CACd,MAAM,MAAM,KAAK,KAAK,CAAC,MAAM,EAAE,OAAO,MAAM;CAC5C,MAAM,QAAQ,YAAY;AAE1B,KAAI,MAAM,OAAO,QAAQ;AAEvB,cAAY;GAAE,GAAG;GAAO,aAAa;EAAO,EAAC;AAC7C,WAAS,cAAc,GAAG,KAAK,KAAK,QAAQ,MAAM,CAAC,GAAG;AACtD;CACD;AAGD,KAAE,IAAI,MAAM,yBAAyB,GAAG,KAAK,KAAK,QAAQ,MAAM,CAAC,8BAA8B;CAC/F,MAAM,MAAM,MAAM,cAAc;AAChC,UAAS,cAAc,GAAG,KAAK,IAAI,KAAK,QAAQ,IAAI,eAAe,CAAC,GAAG;AACxE;;;;ACxCD,MAAM,YAAY;AAElB,SAAS,UAAUC,WAAgC;AACjD,KAAI,UAAU,iBAAiB,OAAQ,QAAO,UAAU;CACxD,MAAM,QAAS,UAAU,mBAA4E;AACrG,QAAO,QAAQ,OAAO,KAAK,MAAM,GAAG,CAAE;AACvC;AAED,SAAS,QAAQA,WAA+B;AAC9C,QAAO,QAAQ,UAAU,cAAc,IAAI,SAAS,KAAK,UAAU,OAAO;AAC3E;;AAGD,eAAe,SAASC,OAA0D;CAChF,MAAM,WAAW,KAAK,KAAK,GAAG,IAAI;AAClC,QAAO,KAAK,KAAK,GAAG,UAAU;AAC5B,QAAM,IAAI,QAAQ,CAAC,MAAM,WAAW,GAAG,IAAK;EAC5C,IAAI;AACJ,MAAI;AACF,YAAS,MAAM,cAAc,MAAM;EACpC,QAAO;AACN;EACD;AACD,MAAI,OAAO,WAAW,SAAU,QAAO;GAAE,IAAI;GAAO,QAAQ,OAAO;EAAQ;AAC3E,MAAI,OAAO,WAAW,aAAa,OAAO,WAAW,YAAa,QAAO,EAAE,IAAI,KAAM;CACtF;AACD,QAAO;EAAE,IAAI;EAAO,QAAQ;CAAgD;AAC7E;AAED,eAAsB,eAAeC,QAAgC;CACnE,MAAM,aAAa,MAAM,gBAAgB;CAEzC,IAAIC;AACJ,KAAI,QAAQ;AACV,cAAY,WAAW,KAAK,CAAC,MAAM,EAAE,OAAO,OAAO;AACnD,OAAK,UACH,OAAM,IAAI,OACP,qBAAqB,OAAO,gBAAgB,WAAW,IAAI,CAAC,MAAM,EAAE,GAAG,CAAC,KAAK,KAAK,CAAC;CAGzF,OAAM;EACL,MAAM,SAAS,MAAM,IAAE,OAAO;GAC5B,SAAS;GACT,SAAS,WACN,OAAO,CACP,KAAK,CAAC,GAAG,MAAM,EAAE,QAAQ,cAAc,EAAE,QAAQ,IAAI,EAAE,KAAK,cAAc,EAAE,KAAK,CAAC,CAClF,IAAI,CAAC,OAAO;IAAE,OAAO,EAAE;IAAI,OAAO,EAAE;IAAM,MAAM,EAAE;GAAS,GAAE;EACjE,EAAC;AACF,MAAI,IAAE,SAAS,OAAO,EAAE;AACtB,OAAE,OAAO,aAAa;AACtB;EACD;AACD,cAAY,WAAW,KAAK,CAAC,MAAM,EAAE,OAAQ,OAAkB;CAChE;AAED,KAAE,OAAO,UAAU,GAAG,KAAK,UAAU,KAAK,CAAC,EAAE;AAE7C,MAAK,QAAQ,UAAU,EAAE;EAEvB,MAAM,SAAS,UAAU,UAAU;EACnC,MAAMC,cAAsC,CAAE;AAC9C,OAAK,MAAM,SAAS,QAAQ;GAC1B,MAAM,SAAS,UAAU,KAAK,MAAM;GACpC,MAAM,QAAQ,MAAM,CAAC,SAASC,IAAE,WAAWA,IAAE,MAAM,EACjD,SAAS,MACV,EAAC;AACF,OAAI,IAAE,SAAS,MAAM,EAAE;AACrB,QAAE,OAAO,aAAa;AACtB;GACD;AACD,eAAY,SAAS;EACtB;EACD,MAAM,OAAO,MAAM,IAAE,KAAK;GAAE,SAAS;GAAmC,aAAa,UAAU;EAAM,EAAC;AACtG,MAAI,IAAE,SAAS,KAAK,EAAE;AACpB,OAAE,OAAO,aAAa;AACtB;EACD;EAED,MAAMC,MAAI,IAAE,SAAS;AACrB,MAAE,MAAM,0BAA0B;EAClC,MAAMC,QAAM,MAAM,WAAW,UAAU,IAAI;GACzC;GACA,GAAI,OAAO,EAAE,KAAM,IAAG,CAAE;EACzB,EAAC;AACF,MAAIA,MAAI,WAAW,WAAW;AAC5B,OAAE,KAAK,aAAa;AACpB,YAAS,iBAAiB,GAAG,KAAKA,MAAI,WAAW,KAAK,CAAC,IAAIA,MAAI,WAAW,QAAQ,IAAI;AACtF;EACD;AAED,MAAE,KAAK,4BAA4B;AACnC,OAAKA,MAAI,aAAa,CAAC,MAAM,MAAM,CAAE,EAAC;AACtC,QAAM,QAAQA,MAAI,aAAa,EAAE;EACjC,MAAMC,WAAS,MAAM,SAASD,MAAI,WAAW;AAC7C,MAAIC,SAAO,GAAI,SAAQ,aAAa;MAC/B,OAAM,IAAI,MAAMA,SAAO,UAAU;AACtC;CACD;CAID,MAAM,MAAM,MAAM,WAAW,UAAU,IAAI,CAAE,EAAC;AAC9C,KAAI,IAAI,WAAW,WAAW;AAC5B,WAAS,iBAAiB,GAAG,KAAK,IAAI,WAAW,KAAK,CAAC,IAAI,IAAI,WAAW,QAAQ,IAAI;AACtF;CACD;AACD,MAAK,IAAI,aAAa,CAAC,MAAM,MAAM,CAAE,EAAC;AACtC,OAAM,2CAA2C,IAAI,aAAa,EAAE;CACpE,MAAM,IAAI,IAAE,SAAS;AACrB,GAAE,MAAM,4CAA4C;CACpD,MAAM,SAAS,MAAM,SAAS,IAAI,WAAW;AAC7C,KAAI,OAAO,IAAI;AACb,IAAE,KAAK,aAAa;AACpB,UAAQ,oBAAoB;CAC7B,OAAM;AACL,IAAE,KAAK,UAAU;AACjB,QAAM,IAAI,MAAM,OAAO,UAAU;CAClC;AACF;;;;;ACpHD,eAAe,kBAAkBC,WAAwC;CACvE,MAAM,MAAM,MAAM,iBAAiB;CACnC,MAAM,QAAQ,IAAI,KAAK,CAAC,MAAM,EAAE,OAAO,aAAa,EAAE,YAAY,UAAU;AAC5E,MAAK,MAAO,OAAM,IAAI,OAAO,4BAA4B,UAAU;AACnE,QAAO;AACR;AAED,eAAe,eAAeC,SAAkD;CAC9E,MAAM,MAAM,MAAM,iBAAiB;AACnC,KAAI,IAAI,WAAW,GAAG;AACpB,OAAK,kDAAkD;AACvD;CACD;CACD,MAAM,SAAS,MAAM,IAAE,OAAO;EAC5B;EACA,SAAS,IAAI,IAAI,CAAC,OAAO;GAAE,OAAO,EAAE;GAAS,QAAQ,EAAE,EAAE,KAAK,IAAI,EAAE,QAAQ;GAAI,MAAM,EAAE;EAAM,GAAE;CACjG,EAAC;AACF,KAAI,IAAE,SAAS,OAAO,CAAE;AACxB,QAAO,IAAI,KAAK,CAAC,MAAM,EAAE,YAAa,OAAkB;AACzD;AAED,SAAS,MAAMC,GAAwC;AACrD,QAAO;EAAE,IAAI,EAAE;EAAS,MAAM,EAAE;EAAM,MAAM,EAAE;EAAM,SAAS,EAAE,UAAU,MAAM,GAAG,GAAG;CAAE;AACxF;AAED,eAAsB,cAA6B;CACjD,MAAM,cAAc,MAAM,iBAAiB;AAC3C,KAAI,YAAY,CAAE,QAAO,UAAU,YAAY;AAC/C,KAAI,YAAY,WAAW,EAAG,QAAO,KAAK,kDAAkD;AAC5F,YAAW,YAAY,IAAI,MAAM,EAAE;EAAC;EAAM;EAAQ;EAAQ;CAAU,EAAC;AACtE;AAED,eAAsB,gBAA+B;CACnD,MAAM,cAAc,MAAM,iBAAiB;CAC3C,MAAM,OAAO,MAAM,QAAQ,IACzB,YAAY,IAAI,OAAO,MAAM;EAC3B,IAAI,SAAS;AACb,MAAI;GACF,MAAM,IAAI,MAAM,eAAe,EAAE,GAAG;AACpC,YAAS,EAAE,UAAU,YAAY;EAClC,QAAO;AACN,YAAS;EACV;AACD,SAAO;GAAE,GAAG,MAAM,EAAE;GAAE;EAAQ;CAC/B,EAAC,CACH;AACD,KAAI,YAAY,CAAE,QAAO,UAAU,KAAK;AACxC,KAAI,KAAK,WAAW,EAAG,QAAO,KAAK,kDAAkD;AACrF,YAAW,MAAM;EAAC;EAAM;EAAQ;EAAQ;EAAU;CAAU,EAAC;AAC9D;AAED,eAAsB,YAAYC,WAAmC;CACnE,MAAM,OAAO,YAAY,MAAM,kBAAkB,UAAU,GAAG,MAAM,eAAe,oBAAoB;AACvG,MAAK,KAAM;CACX,MAAM,OAAO,MAAM,cAAc,KAAK,GAAG;CACzC,IAAIC,SAAiF;AACrF,KAAI;AACF,WAAS,MAAM,oBAAoB,KAAK,GAAG;CAC5C,QAAO,CAEP;AACD,KAAI,YAAY,CAAE,QAAO,UAAU;EAAE,GAAG;EAAM;CAAQ,EAAC;AAEvD,OAAM,EAAE,GAAG,KAAK,KAAK,KAAK,CAAC,IAAI,GAAG,IAAI,KAAK,QAAQ,CAAC,EAAE;AACtD,OAAM,WAAW,KAAK,KAAK,EAAE;AAC7B,OAAM,WAAW,KAAK,GAAG,EAAE;AAC3B,OAAM,WAAW,KAAK,UAAU,EAAE;AAClC,KAAI,QAAQ,eAAe,OAAQ,OAAM,WAAW,OAAO,cAAc,KAAK,KAAK,CAAC,EAAE;AACtF,KAAI,QAAQ,aAAc,OAAM,IAAI,GAAG,IAAI,OAAO,aAAa,CAAC,EAAE;AACnE;AAED,eAAsB,cAAcD,WAAmC;CACrE,MAAM,OAAO,YAAY,MAAM,kBAAkB,UAAU,GAAG,MAAM,eAAe,mBAAmB;AACtG,MAAK,KAAM;CACX,MAAM,YAAY,MAAM,IAAE,QAAQ,EAAE,UAAU,SAAS,GAAG,KAAK,KAAK,KAAK,CAAC,IAAI,KAAK,QAAQ,2BAA4B,EAAC;AACxH,KAAI,IAAE,SAAS,UAAU,KAAK,WAAW;AACvC,OAAK,aAAa;AAClB;CACD;AACD,OAAM,iBAAiB,KAAK,GAAG;AAC/B,UAAS,UAAU,KAAK,KAAK,IAAI,KAAK,QAAQ,IAAI;AACnD;;;;AC7DD,MAAM,cAAc;AACpB,MAAM,SAAS,CAACE,YAAoB,EAAE,OAAO,QAAQ,OAAO,GAAG,CAAC;AAChE,MAAM,SAAS,CAACC,YAAoB,SAAS,OAAO;AAEpD,SAAS,KAAKC,MAA8B;AAC1C,QAAO,KAAK,QAAQ,SAAS;AAC9B;AACD,SAAS,IAAIA,MAA8B;AACzC,QAAO,KAAK,OAAO,QAAQ,KAAK;AACjC;;AAGD,SAAS,WAAWA,MAAsBC,QAAwB;CAChE,MAAM,IAAI,KAAK,KAAK;AACpB,SAAQ,UAAU,EAAlB;EACE,KAAK,SACH,QAAO,KAAK,GAAG,WAAW,uBAAuB,OAAO;EAC1D,KAAK,QACH,QAAO,KAAK,QAAQ,IAAI,WAAW,KAAK,GAAG,WAAW,UAAU,EAAE,OAAO;EAC3E,QACE,QAAO,KAAK,QAAQ,IAAI,mBAAmB,KAAK,GAAG,UAAU,EAAE,OAAO;CACzE;AACF;;AAGD,SAAS,UAAUC,MAAcC,QAAsD;CACrF,IAAIC,MAA+B,CAAE;AACrC,KAAI,WAAW,KAAK,CAClB,KAAI;AACF,QAAM,KAAK,MAAM,aAAa,MAAM,OAAO,CAAC;CAC7C,QAAO;AACN,QAAM,CAAE;CACT;AAEH,QAAO,IAAI;AACX,WAAU,QAAQ,KAAK,EAAE,EAAE,WAAW,KAAM,EAAC;AAC7C,eAAc,OAAO,EAAE,KAAK,UAAU,KAAK,MAAM,EAAE,CAAC,IAAI;AACzD;AAED,SAAS,UAAUF,MAAcC,QAAsD;CACrF,IAAIC,MAA+B,CAAE;AACrC,KAAI,WAAW,KAAK,CAClB,KAAI;AACF,QAAO,KAAK,MAAM,aAAa,MAAM,OAAO,CAAC,IAAgC,CAAE;CAChF,QAAO;AACN,QAAM,CAAE;CACT;AAEH,QAAO,IAAI;AACX,WAAU,QAAQ,KAAK,EAAE,EAAE,WAAW,KAAM,EAAC;AAC7C,eAAc,MAAM,KAAK,UAAU,IAAI,CAAC;AACzC;AAED,SAAS,UAAUA,KAA8BC,KAAaC,OAAsB;CAClF,MAAM,MAAO,IAAI,QAAoC,CAAE;AACvD,KAAI,eAAe;AACnB,KAAI,OAAO;AACZ;AAID,MAAaC,aAA6B;CACxC;EACE,MAAM;EACN,MAAM;EACN,QAAQ,CAAC,QAAS;EAClB,UAAU,CAAC,MAAM,KAAK,WAAW,GAAG,SAAS,EAAE,6BAA6B;EAC5E,QAAQ,GAAG;GACT,MAAM,OAAO,KAAK,WAAW,GAAG,SAAS,EAAE,6BAA6B;AACxE,aAAU,MAAM,CAAC,QACf,UAAU,KAAK,cAAc;IAC3B,KAAK,OAAO,EAAE,OAAO;IACrB,SAAS,EAAE,eAAe,OAAO,EAAE,OAAO,CAAE;GAC7C,EAAC,CACH;AACD,UAAO;IAAE,MAAM;IAAQ;GAAM;EAC9B;CACF;CACD;EACE,MAAM;EACN,MAAM;EACN,QAAQ,CAAC,UAAU,OAAQ;EAC3B,UAAU,CAAC,OACR,yBAAyB,EAAE,UAAU,WAAW,SAAS,QAAQ,oBAAoB,YAAY;EACpG,QAAQ,GAAG;AACT,UAAO;IACL,MAAM;IACN,SAAS;IACT,MAAM;KACJ;KACA;KACA;KACA,EAAE,UAAU,WAAW,SAAS;KAChC;KACA;KACA;KACA,OAAO,EAAE,OAAO;KAChB;MACC,iBAAiB,OAAO,EAAE,OAAO,CAAC;IACpC;GACF;EACF;CACF;CACD;EACE,MAAM;EACN,MAAM;EACN,QAAQ,CAAC,UAAU,OAAQ;EAC3B,UAAU,CAAC,MAAO,EAAE,UAAU,WAAW,KAAK,KAAK,EAAE,EAAE,WAAW,WAAW,GAAG,KAAK,IAAI,EAAE,EAAE,WAAW,WAAW;EACnH,QAAQ,GAAG;GACT,MAAM,OAAO,EAAE,UAAU,WAAW,KAAK,KAAK,EAAE,EAAE,WAAW,WAAW,GAAG,KAAK,IAAI,EAAE,EAAE,WAAW,WAAW;AAC9G,aAAU,MAAM,CAAC,QACf,UAAU,KAAK,cAAc;IAC3B,KAAK,OAAO,EAAE,OAAO;IACrB,SAAS,EAAE,eAAe,OAAO,EAAE,OAAO,CAAE;GAC7C,EAAC,CACH;AACD,UAAO;IAAE,MAAM;IAAQ;GAAM;EAC9B;CACF;CACD;EACE,MAAM;EACN,MAAM;EACN,QAAQ,CAAC,UAAU,OAAQ;EAC3B,UAAU,CAAC,MACT,EAAE,UAAU,WAAW,KAAK,WAAW,GAAG,OAAO,EAAE,QAAQ,WAAW,GAAG,KAAK,IAAI,EAAE,EAAE,WAAW,WAAW;EAC9G,QAAQ,GAAG;GACT,MAAM,OACJ,EAAE,UAAU,WAAW,KAAK,WAAW,GAAG,OAAO,EAAE,QAAQ,WAAW,GAAG,KAAK,IAAI,EAAE,EAAE,WAAW,WAAW;AAC9G,aAAU,MAAM,CAAC,QACf,UAAU,KAAK,WAAW;IACxB,KAAK,OAAO,EAAE,OAAO;IACrB,MAAM;IACN,SAAS,EAAE,eAAe,OAAO,EAAE,OAAO,CAAE;GAC7C,EAAC,CACH;AACD,UAAO;IAAE,MAAM;IAAQ;GAAM;EAC9B;CACF;CACD;EACE,MAAM;EACN,MAAM;EACN,QAAQ,CAAC,QAAS;EAClB,UAAU,CAAC,MAAM,KAAK,KAAK,EAAE,EAAE,YAAY,YAAY,kBAAkB;EACzE,QAAQ,GAAG;GACT,MAAM,OAAO,KAAK,KAAK,EAAE,EAAE,YAAY,YAAY,kBAAkB;AACrE,aAAU,MAAM,CAAC,QACf,UAAU,KAAK,cAAc;IAE3B,WAAW,OAAO,EAAE,OAAO;IAC3B,SAAS,EAAE,eAAe,OAAO,EAAE,OAAO,CAAE;GAC7C,EAAC,CACH;AACD,UAAO;IAAE,MAAM;IAAQ;GAAM;EAC9B;CACF;CACD;EACE,MAAM;EACN,MAAM;EACN,QAAQ,CAAC,UAAU,OAAQ;EAC3B,UAAU,CAAC,MACT,EAAE,UAAU,WAAW,KAAK,KAAK,EAAE,EAAE,WAAW,OAAO,gBAAgB,GAAG,KAAK,IAAI,EAAE,EAAE,QAAQ,gBAAgB;EACjH,QAAQ,GAAG;GACT,MAAM,OACJ,EAAE,UAAU,WACR,KAAK,KAAK,EAAE,EAAE,WAAW,OAAO,gBAAgB,GAChD,KAAK,IAAI,EAAE,EAAE,QAAQ,gBAAgB;AAC3C,aAAU,MAAM,CAAC,QACf,UAAU,KAAK,mBAAmB;IAChC,KAAK,OAAO,EAAE,OAAO;IACrB,UAAU,EAAE,SAAS,EAAE,eAAe,OAAO,EAAE,OAAO,CAAE,EAAE;GAC3D,EAAC,CACH;AACD,UAAO;IAAE,MAAM;IAAQ;GAAM;EAC9B;CACF;CACD;EACE,MAAM;EACN,MAAM;EACN,QAAQ,CAAC,QAAS;EAClB,UAAU,CAAC,MAAM,KAAK,KAAK,EAAE,EAAE,UAAU,cAAc;EACvD,QAAQ,GAAG;GACT,MAAM,OAAO,KAAK,KAAK,EAAE,EAAE,UAAU,cAAc;AACnD,aAAU,MAAM,CAAC,QACf,UAAU,KAAK,eAAe;IAC5B,KAAK,OAAO,EAAE,OAAO;IACrB,SAAS,EAAE,eAAe,OAAO,EAAE,OAAO,CAAE;GAC7C,EAAC,CACH;AACD,UAAO;IAAE,MAAM;IAAQ;GAAM;EAC9B;CACF;AACF;AAED,SAAgB,aAAaC,MAAwC;AACnE,QAAO,WAAW,KAAK,CAAC,MAAM,EAAE,SAAS,KAAK;AAC/C;;;;AC3ND,eAAsB,eAAeC,SAAiC;AACpE,GAAE,MAAM,GAAG,KAAK,gCAAgC,CAAC;AAEjD,MAAK,YAAY,EAAE;AACjB,IAAE,OAAO,2CAA2C;AACpD;CACD;CAED,IAAI,OAAO;AACX,MAAK,MAAM;EACT,MAAM,SAAS,MAAM,EAAE,OAAO;GAC5B,SAAS;GACT,SAAS,WAAW,IAAI,CAAC,OAAO;IAAE,OAAO,EAAE;IAAM,OAAO,EAAE;GAAM,GAAE;EACnE,EAAC;AACF,MAAI,EAAE,SAAS,OAAO,CAAE,QAAO,EAAE,OAAO,aAAa;AACrD,SAAO;CACR;CAED,MAAM,SAAS,aAAa,KAAK;AACjC,MAAK,OAAQ,OAAM,IAAI,OAAO,iBAAiB,KAAK,cAAc,WAAW,IAAI,CAAC,MAAM,EAAE,KAAK,CAAC,KAAK,KAAK,CAAC;CAE3G,IAAIC,QAAe,OAAO,OAAO;AACjC,KAAI,OAAO,OAAO,SAAS,GAAG;EAC5B,MAAM,SAAS,MAAM,EAAE,OAAO;GAC5B,SAAS;GACT,SAAS,CACP;IAAE,OAAO;IAAU,OAAO;IAAU,MAAM;GAAwC,GAClF;IAAE,OAAO;IAAS,OAAO;IAAS,MAAM;GAAqB,CAC9D,EAAC,OAAO,CAAC,MAAM,OAAO,OAAO,SAAS,EAAE,MAAe,CAAC;EAC1D,EAAC;AACF,MAAI,EAAE,SAAS,OAAO,CAAE,QAAO,EAAE,OAAO,aAAa;AACrD,UAAQ;CACT;CAED,MAAM,SAAS,YAAY;CAC3B,MAAM,SAAS,cAAc,OAAO;CAEpC,MAAM,IAAI,EAAE,SAAS;AACrB,GAAE,MAAM,4CAA4C;CACpD,IAAIC;AACJ,KAAI;AACF,GAAC,CAAE,IAAK,GAAG,MAAM,cAAc,cAAc,OAAO,KAAK,GAAG;CAC7D,SAAQ,KAAK;AACZ,IAAE,KAAK,4BAA4B;AACnC,QAAM;CACP;AACD,GAAE,KAAK,mBAAmB;CAE1B,MAAM,SAAS,OAAO,QAAQ;EAAE;EAAQ,QAAQ;EAAK;CAAO,EAAC;AAE7D,KAAI,OAAO,SAAS,WAAW;AAE7B,MAAI;AACF,gBAAa,OAAO,SAAS,OAAO,MAAM,EAAE,OAAO,UAAW,EAAC;EAChE,QAAO;AACN,SAAM,IAAI,OACP,kBAAkB,OAAO,QAAQ,kDAAkD,OAAO,QAAQ,GAAG,OAAO,KAAK,KAAK,IAAI,CAAC;EAE/H;AACD,WAAS,wBAAwB,OAAO,KAAK,IAAI,MAAM,IAAI;CAC5D,OAAM;AACL,WAAS,wBAAwB,OAAO,KAAK,GAAG;AAChD,IAAE,IAAI,MAAM,oBAAoB,GAAG,IAAI,OAAO,KAAK,CAAC,EAAE;CACvD;AAED,GAAE,OAAO,UAAU,OAAO,KAAK,wDAAwD;AACxF;;;;ACvED,eAAsB,cAAcC,SAAiBC,MAAgD;CACnG,MAAM,MAAM,MAAM,OAAO,SAAS,KAAK,WAAW;AAClD,KAAI,YAAY,CAAE,QAAO,UAAU,IAAI;AAEvC,KAAI,IAAI,QAAQ,WAAW,GAAG;AAC5B,OAAK,yDAAyD;AAC9D;CACD;AAED,MAAK,MAAM,KAAK,IAAI,SAAS;AAC3B,QAAM,IAAI,GAAG,KAAK,EAAE,gBAAgB,CAAC,GAAG,GAAG,KAAK,GAAG,EAAE,cAAc,KAAK,EAAE,OAAO,GAAG,CAAC,EAAE;AACvF,MAAI,EAAE,aAAc,MAAK,GAAG,IAAI,EAAE,aAAa,CAAC;AAChD,OAAK,MAAM,QAAQ,EAAE,OAAO;AAC1B,SAAM,IAAI,GAAG,KAAK,KAAK,QAAQ,CAAC,EAAE;AAClC,OAAI,KAAK,iBAAiB,OAAQ,OAAM,cAAc,KAAK,gBAAgB,KAAK,KAAK,CAAC,EAAE;EACzF;AACD,OAAK,GAAG,KAAK,qBAAqB,EAAE,cAAc,GAAG,EAAE,MAAM,IAAI,WAAW,SAAS,WAAW,CAAC;CAClG;AACF;;;;AClBD,eAAsB,eACpBC,cACAC,MACAC,MACe;CACf,IAAIC,SAAkC,CAAE;AACxC,KAAI,KAAK,KACP,KAAI;AACF,WAAS,KAAK,MAAM,KAAK,KAAK;CAC/B,QAAO;AACN,QAAM,IAAI,MAAM;CACjB;CAGH,MAAM,MAAM,MAAM,QAAQ,cAAc,MAAM,OAAO;AACrD,KAAI,YAAY,CAAE,QAAO,UAAU,IAAI;AAEvC,KAAI,IAAI,KAAK,WAAW,GAAG;AACzB,OAAK,GAAG,IAAI,WAAW,CAAC;AACxB;CACD;AACD,YAAW,IAAI,MAAM,IAAI,QAAQ,SAAS,IAAI,iBAAoB;AAClE,MAAK,GAAG,KAAK,IAAI,IAAI,UAAU,SAAS,IAAI,YAAY,iBAAiB,GAAG,EAAE,CAAC;AAChF;;;;ACdD,MAAM,UAAU,IAAI;AAEpB,QACG,KAAK,SAAS,CACd,YAAY,qEAAqE,CACjF,QAAQ,QAAQ,CAChB,OAAO,UAAU,+BAA+B,CAChD,yBAAyB;;AAG5B,SAAS,OAA4BC,IAAmC;AACtE,QAAO,OAAO,GAAG,SAAY;AAC3B,MAAI,QAAQ,MAAM,CAAC,KAAM,aAAY,KAAK;AAC1C,MAAI;AACF,SAAM,GAAG,GAAG,KAAK;EAClB,SAAQ,KAAK;AACZ,OAAI,eAAe,YAAY,IAAI,WAAW,IAC5C,MAAK,qDAAqD;OAE1D,MAAK,eAAe,QAAQ,IAAI,UAAU,OAAO,IAAI,CAAC;AAExD,WAAQ,WAAW;EACpB;CACF;AACF;AAED,QAAQ,QAAQ,QAAQ,CAAC,YAAY,oBAAoB,CAAC,OAAO,OAAO,aAAa,CAAC;AACtF,QAAQ,QAAQ,SAAS,CAAC,YAAY,yCAAyC,CAAC,OAAO,OAAO,cAAc,CAAC;AAC7G,QAAQ,QAAQ,SAAS,CAAC,YAAY,iCAAiC,CAAC,OAAO,OAAO,cAAc,CAAC;AAErG,QACG,QAAQ,UAAU,CAClB,SAAS,YAAY,6DAA6D,CAClF,YAAY,4BAA4B,CACxC,OAAO,OAAO,eAAe,CAAC;AAEjC,MAAM,UAAU,QAAQ,QAAQ,UAAU,CAAC,YAAY,gCAAgC;AACvF,QAAQ,QAAQ,QAAQ,EAAE,WAAW,KAAM,EAAC,CAAC,YAAY,yBAAyB,CAAC,OAAO,OAAO,YAAY,CAAC;AAC9G,QAAQ,QAAQ,SAAS,CAAC,YAAY,uCAAuC,CAAC,OAAO,OAAO,cAAc,CAAC;AAC3G,QACG,QAAQ,OAAO,CACf,SAAS,QAAQ,wBAAwB,CACzC,YAAY,4BAA4B,CACxC,OAAO,OAAO,YAAY,CAAC;AAC9B,QACG,QAAQ,SAAS,CACjB,SAAS,QAAQ,wBAAwB,CACzC,YAAY,kBAAkB,CAC9B,OAAO,OAAO,cAAc,CAAC;AAEhC,QACG,QAAQ,UAAU,CAClB,SAAS,WAAW,+CAA+C,CACnE,YAAY,oDAAoD,CAChE,OAAO,OAAO,eAAe,CAAC;AAEjC,QACG,QAAQ,SAAS,CACjB,SAAS,aAAa,gDAAgD,CACtE,OAAO,4BAA4B,yCAAyC,CAC5E,YAAY,0DAA0D,CACtE,OAAO,OAAO,CAACC,SAAiBC,SAAoC,cAAc,SAAS,KAAK,CAAC,CAAC;AAErG,QACG,QAAQ,UAAU,CAClB,SAAS,mBAAmB,sBAAsB,CAClD,SAAS,UAAU,+BAA+B,CAClD,OAAO,qBAAqB,8BAA8B,CAC1D,YAAY,sCAAsC,CAClD,OAAO,OAAO,CAACC,cAAsBC,MAAcC,SAA4B,eAAe,cAAc,MAAM,KAAK,CAAC,CAAC;AAE5H,QAAQ,WAAW,QAAQ,KAAK,CAAC,MAAM,CAAC,QAAQ;AAC9C,MAAK,eAAe,QAAQ,IAAI,UAAU,OAAO,IAAI,CAAC;AACtD,SAAQ,KAAK,EAAE;AAChB,EAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","names":["config?: AuthConfig | null","config: AuthConfig","isLoggedIn","buf: Buffer","apiUrl: string","params: Record<string, string>","redirectUri: string","accessToken: string","expectedState: string","resolveCode!: (code: string) => void","rejectCode!: (err: Error) => void","title: string","message: string","options?: { silent?: boolean }","next: AuthConfig","entry: TokenEntry","status: number","message: string","path: string","options: RequestOptions","headers: Record<string, string>","body: string | undefined","text","id: string","appId: string","body: Record<string, unknown>","token: string","connectionId: string","tool: string","params: Record<string, unknown>","useCase: string","connectionIds?: string[]","name: string","sessionId: string","on: boolean","data: unknown","value: unknown","rows: Array<Record<string, unknown>>","columns?: string[]","message: string","opts: LoginOptions","connector: Connector","token: string","source?: string","connector: Connector | undefined","credentials: Record<string, string>","p","name","s","res","result","idOrShort: string","message: string","c: Connection","idOrShort?: string","config: { schemaFilters: string[] | null; instructions: string | null } | null","path: string","skills","slug: string","SCOPES: readonly Scope[]","slugArg?: string","opts: InstallOptions","result","scope: Scope","key: string","useCase: string","opts: { connection?: string[] }","connectionId: string","tool: string","opts: { data?: string }","params: Record<string, unknown>","n: number","sessionId: string","filePath: string","opts: { output?: string }","MANAGERS: Manager[]","cmd: string","pkg","fn: (...args: A) => Promise<void>","id: string","usecase: string","opts: { connection?: string[] }","connectionId: string","tool: string","opts: { data?: string }","sessionId: string","path: string","opts: { output?: string }"],"sources":["../package.json","../src/lib/config.ts","../src/lib/auth.ts","../src/lib/api.ts","../src/lib/output.ts","../src/commands/login.ts","../src/commands/logout.ts","../src/commands/switch.ts","../src/commands/connect.ts","../src/commands/sources.ts","../src/commands/skills.ts","../../mcp-clients/dist/install.js","../src/lib/skills.ts","../src/commands/install.ts","../src/commands/search.ts","../src/commands/execute.ts","../src/commands/download.ts","../src/commands/upgrade.ts","../src/index.ts"],"sourcesContent":["{\n \"name\": \"@sequelsh/cli\",\n \"version\": \"0.3.0\",\n \"description\": \"Sequel CLI — connect data sources and run tools from your terminal.\",\n \"license\": \"MIT\",\n \"type\": \"module\",\n \"bin\": {\n \"sequel\": \"./dist/index.js\"\n },\n \"files\": [\n \"dist\"\n ],\n \"exports\": {\n \".\": {\n \"import\": \"./dist/index.js\",\n \"types\": \"./dist/index.d.ts\"\n }\n },\n \"engines\": {\n \"node\": \">=18\"\n },\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"git+https://github.com/sequelsh/sequel.git\",\n \"directory\": \"packages/cli\"\n },\n \"homepage\": \"https://sequel.sh\",\n \"keywords\": [\n \"sequel\",\n \"cli\",\n \"mcp\",\n \"sql\",\n \"data\",\n \"ai\",\n \"agents\"\n ],\n \"publishConfig\": {\n \"access\": \"public\"\n },\n \"scripts\": {\n \"dev\": \"bun run src/index.ts\",\n \"cli\": \"bun run src/index.ts\",\n \"build\": \"tsdown\",\n \"build:binaries\": \"bun run scripts/build-binaries.ts\",\n \"test\": \"vitest run\",\n \"test:watch\": \"vitest\",\n \"typecheck\": \"tsc --noEmit\",\n \"clean\": \"rm -rf dist\"\n },\n \"dependencies\": {\n \"@clack/prompts\": \"^0.8.2\",\n \"commander\": \"^12.1.0\",\n \"open\": \"^10.1.0\",\n \"picocolors\": \"^1.1.1\",\n \"yaml\": \"^2.5.1\"\n },\n \"devDependencies\": {\n \"@sequel/mcp-clients\": \"workspace:*\",\n \"@sequel/typescript-config\": \"workspace:*\",\n \"@types/node\": \"^22.10.0\",\n \"tsdown\": \"^0.9.0\",\n \"typescript\": \"^5.7.0\",\n \"vitest\": \"^3.0.0\"\n }\n}\n","import { homedir } from \"node:os\";\nimport { join } from \"node:path\";\nimport { mkdirSync, readFileSync, writeFileSync, rmSync, existsSync, chmodSync } from \"node:fs\";\n\n/** Default production API base. Override with SEQUEL_API_URL for local/dev. */\nexport const DEFAULT_API_URL = \"https://api.sequel.sh\";\n\n/** Default marketing site, which publishes the Sequel skill. Override with SEQUEL_SITE_URL. */\nexport const DEFAULT_SITE_URL = \"https://sequel.sh\";\n\nexport function resolveSiteUrl(): string {\n return process.env.SEQUEL_SITE_URL || DEFAULT_SITE_URL;\n}\n\n/** One OAuth token bundle, scoped to a single organization. */\nexport interface TokenEntry {\n accessToken: string;\n refreshToken: string;\n /** ms epoch when the access token expires. */\n expiresAt: number;\n}\n\nexport interface OrgRef {\n id: string;\n name: string;\n slug: string;\n role: string;\n}\n\nexport interface UserRef {\n id: string;\n email: string;\n name: string;\n}\n\n/**\n * The on-disk shape of ~/.sequel/auth.json.\n *\n * Multi-token cache: one genuine org-bound OAuth token per organization, keyed\n * by org id. `activeOrgId` selects which token requests use right now. Switching\n * orgs is an offline swap when the target org already has a cached token.\n */\nexport interface AuthConfig {\n version: 1;\n apiUrl: string;\n /** Persisted dynamic client registration, reused across logins. */\n clientId?: string;\n activeOrgId?: string;\n tokens: Record<string, TokenEntry>;\n user?: UserRef;\n /** Cached membership list for the `switch` UI. */\n orgs?: OrgRef[];\n}\n\n/** Directory holding the CLI's state. Overridable for tests. */\nexport function configDir(): string {\n return process.env.SEQUEL_CONFIG_DIR || join(homedir(), \".sequel\");\n}\n\nexport function configPath(): string {\n return join(configDir(), \"auth.json\");\n}\n\n/** The API base URL: explicit env wins, then a saved value, then the default. */\nexport function resolveApiUrl(config?: AuthConfig | null): string {\n return process.env.SEQUEL_API_URL || config?.apiUrl || DEFAULT_API_URL;\n}\n\nfunction emptyConfig(): AuthConfig {\n return { version: 1, apiUrl: resolveApiUrl(), tokens: {} };\n}\n\n/** Read auth.json, returning a fresh empty config if missing or corrupt. */\nexport function readConfig(): AuthConfig {\n const path = configPath();\n if (!existsSync(path)) return emptyConfig();\n try {\n const parsed = JSON.parse(readFileSync(path, \"utf8\")) as AuthConfig;\n if (!parsed || typeof parsed !== \"object\" || !parsed.tokens) return emptyConfig();\n parsed.tokens ??= {};\n return parsed;\n } catch {\n // Corrupt file — start clean rather than crash.\n return emptyConfig();\n }\n}\n\n/** Persist auth.json with locked-down permissions (dir 0700, file 0600). */\nexport function writeConfig(config: AuthConfig): void {\n const dir = configDir();\n mkdirSync(dir, { recursive: true, mode: 0o700 });\n const path = configPath();\n writeFileSync(path, `${JSON.stringify(config, null, 2)}\\n`, { mode: 0o600 });\n // writeFileSync only applies mode on create; enforce it on existing files too.\n chmodSync(path, 0o600);\n}\n\n/** Remove all stored credentials. Idempotent. */\nexport function clearConfig(): void {\n const path = configPath();\n if (existsSync(path)) rmSync(path);\n}\n\nexport function isLoggedIn(config: AuthConfig): boolean {\n return Boolean(config.activeOrgId && config.tokens[config.activeOrgId]);\n}\n","import { createHash, randomBytes } from \"node:crypto\";\nimport { createServer } from \"node:http\";\nimport { AddressInfo } from \"node:net\";\nimport open from \"open\";\nimport {\n type AuthConfig,\n type OrgRef,\n type TokenEntry,\n type UserRef,\n readConfig,\n writeConfig,\n resolveApiUrl,\n} from \"./config\";\n\n/** Refresh a token this many ms before it actually expires. */\nconst EXPIRY_SKEW_MS = 60_000;\n\nfunction base64url(buf: Buffer): string {\n return buf.toString(\"base64url\");\n}\n\n/** PKCE pair: challenge = base64url(sha256(verifier)), matching the API's S256. */\nexport function generatePkce(): { verifier: string; challenge: string } {\n const verifier = base64url(randomBytes(32));\n const challenge = base64url(createHash(\"sha256\").update(verifier).digest());\n return { verifier, challenge };\n}\n\ninterface TokenResponse {\n access_token: string;\n refresh_token: string;\n expires_in: number;\n token_type: string;\n}\n\ninterface WhoAmI {\n id: string;\n name: string;\n email: string;\n organizationId: string;\n}\n\n/** POST the OAuth token endpoint (form-encoded, per RFC 6749). */\nasync function postToken(apiUrl: string, params: Record<string, string>): Promise<TokenResponse> {\n const res = await fetch(`${apiUrl}/oauth/token`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/x-www-form-urlencoded\" },\n body: new URLSearchParams(params).toString(),\n });\n if (!res.ok) {\n const body = await res.text().catch(() => \"\");\n throw new Error(`Token request failed (${res.status}): ${body}`);\n }\n return (await res.json()) as TokenResponse;\n}\n\n/** Register a fresh dynamic OAuth client bound to this run's loopback URI. */\nasync function registerClient(apiUrl: string, redirectUri: string): Promise<string> {\n const res = await fetch(`${apiUrl}/oauth/register`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ client_name: \"Sequel CLI\", redirect_uris: [redirectUri] }),\n });\n if (!res.ok) {\n const body = await res.text().catch(() => \"\");\n throw new Error(`Client registration failed (${res.status}): ${body}`);\n }\n const data = (await res.json()) as { client_id: string };\n return data.client_id;\n}\n\nasync function fetchWhoAmI(apiUrl: string, accessToken: string): Promise<WhoAmI> {\n const res = await fetch(`${apiUrl}/users/me`, {\n headers: { Authorization: `Bearer ${accessToken}` },\n });\n if (!res.ok) throw new Error(`Failed to resolve identity (${res.status})`);\n return (await res.json()) as WhoAmI;\n}\n\nexport async function fetchOrganizations(apiUrl: string, accessToken: string): Promise<OrgRef[]> {\n const res = await fetch(`${apiUrl}/organizations`, {\n headers: { Authorization: `Bearer ${accessToken}` },\n });\n if (!res.ok) throw new Error(`Failed to list organizations (${res.status})`);\n const rows = (await res.json()) as Array<{\n role: string;\n organization: { id: string; name: string; slug: string };\n }>;\n return rows.map((r) => ({\n id: r.organization.id,\n name: r.organization.name,\n slug: r.organization.slug,\n role: r.role,\n }));\n}\n\n/**\n * Wait for the browser to hit the loopback redirect and hand back `?code&state`.\n * Resolves with the authorization code once `state` is verified.\n */\nfunction waitForCallback(\n expectedState: string,\n): { server: ReturnType<typeof createServer>; port: Promise<number>; code: Promise<string> } {\n let resolveCode!: (code: string) => void;\n let rejectCode!: (err: Error) => void;\n const code = new Promise<string>((resolve, reject) => {\n resolveCode = resolve;\n rejectCode = reject;\n });\n\n const server = createServer((req, res) => {\n const url = new URL(req.url ?? \"/\", \"http://127.0.0.1\");\n if (url.pathname !== \"/callback\") {\n res.writeHead(404).end(\"Not found\");\n return;\n }\n const error = url.searchParams.get(\"error\");\n const returnedState = url.searchParams.get(\"state\");\n const returnedCode = url.searchParams.get(\"code\");\n\n const finish = (title: string, message: string) => {\n res.writeHead(200, { \"Content-Type\": \"text/html; charset=utf-8\" });\n res.end(\n `<!doctype html><html><head><title>${title}</title></head><body style=\"font-family:system-ui;padding:3rem;text-align:center\"><h2>${title}</h2><p>${message}</p><p>You can close this tab and return to your terminal.</p></body></html>`,\n );\n };\n\n if (error) {\n finish(\"Sign-in failed\", `The authorization server returned: ${error}`);\n rejectCode(new Error(`Authorization failed: ${error}`));\n return;\n }\n if (!returnedState || returnedState !== expectedState) {\n finish(\"Sign-in failed\", \"State mismatch — possible CSRF. Please try again.\");\n rejectCode(new Error(\"State mismatch in OAuth callback\"));\n return;\n }\n if (!returnedCode) {\n finish(\"Sign-in failed\", \"No authorization code was returned.\");\n rejectCode(new Error(\"Missing authorization code\"));\n return;\n }\n finish(\"Signed in to Sequel\", \"Authentication complete.\");\n resolveCode(returnedCode);\n });\n\n const port = new Promise<number>((resolve, reject) => {\n server.on(\"error\", reject);\n server.listen(0, \"127.0.0.1\", () => resolve((server.address() as AddressInfo).port));\n });\n\n return { server, port, code };\n}\n\nexport interface LoginResult {\n user: UserRef;\n org: OrgRef | undefined;\n organizationId: string;\n}\n\n/**\n * Run the full OAuth 2.0 + PKCE loopback flow: register a client, open the\n * browser to the consent page (where the user picks an org), capture the code,\n * exchange it for an org-bound token, then cache that token keyed by its org.\n *\n * Shared by `login` and `switch` (for orgs without a cached token).\n */\nexport async function runLoginFlow(options?: { silent?: boolean }): Promise<LoginResult> {\n const config = readConfig();\n const apiUrl = resolveApiUrl(config);\n\n const { verifier, challenge } = generatePkce();\n const state = base64url(randomBytes(16));\n\n const { server, port: portPromise, code: codePromise } = waitForCallback(state);\n const port = await portPromise;\n const redirectUri = `http://127.0.0.1:${port}/callback`;\n\n try {\n const clientId = await registerClient(apiUrl, redirectUri);\n\n const authorizeUrl = new URL(`${apiUrl}/oauth/authorize`);\n authorizeUrl.searchParams.set(\"client_id\", clientId);\n authorizeUrl.searchParams.set(\"redirect_uri\", redirectUri);\n authorizeUrl.searchParams.set(\"response_type\", \"code\");\n authorizeUrl.searchParams.set(\"code_challenge\", challenge);\n authorizeUrl.searchParams.set(\"code_challenge_method\", \"S256\");\n authorizeUrl.searchParams.set(\"state\", state);\n\n if (!options?.silent) {\n // open() can fail in headless envs — never block the flow on it.\n open(authorizeUrl.toString()).catch(() => {});\n }\n // Always surface the URL so the user can open it manually if needed.\n process.stderr.write(`\\nOpen this URL to continue:\\n${authorizeUrl.toString()}\\n\\n`);\n\n const code = await codePromise;\n\n const token = await postToken(apiUrl, {\n grant_type: \"authorization_code\",\n code,\n redirect_uri: redirectUri,\n client_id: clientId,\n code_verifier: verifier,\n });\n\n const me = await fetchWhoAmI(apiUrl, token.access_token);\n const orgs = await fetchOrganizations(apiUrl, token.access_token).catch(() => config.orgs ?? []);\n\n const next: AuthConfig = {\n ...config,\n version: 1,\n apiUrl,\n clientId,\n activeOrgId: me.organizationId,\n tokens: {\n ...config.tokens,\n [me.organizationId]: {\n accessToken: token.access_token,\n refreshToken: token.refresh_token,\n expiresAt: Date.now() + token.expires_in * 1000,\n },\n },\n user: { id: me.id, email: me.email, name: me.name },\n orgs,\n };\n writeConfig(next);\n\n return {\n user: next.user!,\n org: orgs.find((o) => o.id === me.organizationId),\n organizationId: me.organizationId,\n };\n } finally {\n server.close();\n }\n}\n\n/** True when there's a cached token for the active org (cheap, non-throwing). */\nexport function isLoggedIn(): boolean {\n const config = readConfig();\n const orgId = config.activeOrgId;\n return Boolean(orgId && config.tokens[orgId]);\n}\n\n/**\n * Return a valid access token for the active org, refreshing it in place when\n * expired. Throws a friendly error if there is no token or the refresh fails.\n */\nexport async function getValidAccessToken(): Promise<{ token: string; config: AuthConfig }> {\n const config = readConfig();\n const orgId = config.activeOrgId;\n if (!orgId || !config.tokens[orgId]) {\n throw new Error(\"Not logged in. Run `sequel login` first.\");\n }\n\n const entry: TokenEntry = config.tokens[orgId];\n if (entry.expiresAt - EXPIRY_SKEW_MS > Date.now()) {\n return { token: entry.accessToken, config };\n }\n\n // Access token expired — rotate via the refresh grant.\n const apiUrl = resolveApiUrl(config);\n try {\n const refreshed = await postToken(apiUrl, {\n grant_type: \"refresh_token\",\n refresh_token: entry.refreshToken,\n client_id: config.clientId ?? \"\",\n });\n config.tokens[orgId] = {\n accessToken: refreshed.access_token,\n refreshToken: refreshed.refresh_token,\n expiresAt: Date.now() + refreshed.expires_in * 1000,\n };\n writeConfig(config);\n return { token: refreshed.access_token, config };\n } catch {\n throw new Error(\n \"Your session for this organization has expired. Run `sequel login` (or `sequel switch`) to sign in again.\",\n );\n }\n}\n","import { getValidAccessToken } from \"./auth\";\nimport { resolveApiUrl } from \"./config\";\n\nexport class ApiError extends Error {\n constructor(\n public status: number,\n message: string,\n ) {\n super(message);\n this.name = \"ApiError\";\n }\n}\n\ninterface RequestOptions {\n method?: string;\n query?: Record<string, string | undefined>;\n body?: Record<string, unknown>;\n /**\n * How the active org id is attached to the request:\n * - \"query\" → ?organizationId=<org> (default; most GET/DELETE routes)\n * - \"organizationId\" → merged into the JSON body as organizationId\n * - \"organization_id\" → merged into the JSON body as organization_id (execute)\n * - \"none\" → not attached (e.g. /connectors, /oauth/*)\n */\n org?: \"query\" | \"organizationId\" | \"organization_id\" | \"none\";\n}\n\n/**\n * Authenticated request against the Sequel API using the active org's token.\n * Refreshes the token transparently and scopes the call to that org.\n */\nexport async function request<T = unknown>(path: string, options: RequestOptions = {}): Promise<T> {\n const { token, config } = await getValidAccessToken();\n const apiUrl = resolveApiUrl(config);\n const orgId = config.activeOrgId;\n const orgMode = options.org ?? \"query\";\n\n const url = new URL(`${apiUrl}${path}`);\n if (orgMode === \"query\" && orgId) url.searchParams.set(\"organizationId\", orgId);\n for (const [k, v] of Object.entries(options.query ?? {})) {\n if (v !== undefined) url.searchParams.set(k, v);\n }\n\n let bodyObj = options.body;\n if ((orgMode === \"organizationId\" || orgMode === \"organization_id\") && orgId) {\n bodyObj = { ...(bodyObj ?? {}), [orgMode]: orgId };\n }\n\n const headers: Record<string, string> = { Authorization: `Bearer ${token}` };\n let body: string | undefined;\n if (bodyObj !== undefined) {\n headers[\"Content-Type\"] = \"application/json\";\n body = JSON.stringify(bodyObj);\n }\n\n const res = await fetch(url.toString(), { method: options.method ?? \"GET\", headers, body });\n\n if (!res.ok) {\n let message = `Request failed (${res.status})`;\n const text = await res.text().catch(() => \"\");\n try {\n const json = JSON.parse(text) as { error?: string };\n if (json.error) message = json.error;\n } catch {\n if (text) message = text;\n }\n throw new ApiError(res.status, message);\n }\n\n if (res.status === 204) return undefined as T;\n const text = await res.text();\n return (text ? JSON.parse(text) : undefined) as T;\n}\n\n/** The active organization id, or throws if not logged in. */\nexport async function activeOrgId(): Promise<string> {\n const { config } = await getValidAccessToken();\n if (!config.activeOrgId) throw new Error(\"No active organization. Run `sequel login`.\");\n return config.activeOrgId;\n}\n\n// ── Types ──────────────────────────────────────────────────────────────────────\n\nexport interface Connector {\n id: string;\n name: string;\n description: string;\n icon: string;\n appType: \"database\" | \"app\" | \"mcp\";\n live: boolean;\n authId: string;\n credentialsSchema?: Record<string, unknown>;\n userInputFields?: string[];\n canResolveName?: boolean;\n configuration?: { type: string } | null;\n}\n\nexport interface Connection {\n id: string;\n shortId: string;\n name: string;\n type: string;\n createdBy?: string;\n createdAt: string;\n updatedAt: string;\n}\n\nexport type LinkCreateResponse =\n | { status: \"success\"; connection: Connection }\n | { status: \"pending\"; link_token: string; redirect_url: string; expires_at: string };\n\nexport interface LinkStatus {\n status: \"pending\" | \"oauth_in_progress\" | \"awaiting_configuration\" | \"success\" | \"failed\" | \"completed\";\n connectionId?: string;\n connection_id?: string;\n reason?: string;\n}\n\nexport interface ExecuteResult {\n data: Array<Record<string, unknown>>;\n columns: string[];\n row_count: number;\n truncated: boolean;\n}\n\nexport interface SearchToolRef {\n tool_id: string;\n input_schema: Record<string, unknown>;\n output_schema: Record<string, unknown> | null;\n relevant_tables: string[];\n}\n\nexport interface SearchResult {\n connection_id: string;\n connection_name: string;\n app_id: string;\n use_case: string;\n instructions: string;\n tools: SearchToolRef[];\n}\n\n// ── Endpoint wrappers ───────────────────────────────────────────────────────────\n\nexport function listConnectors(): Promise<Connector[]> {\n return request<Connector[]>(\"/connectors\", { org: \"none\" });\n}\n\nexport function listConnections(): Promise<Connection[]> {\n return request<Connection[]>(\"/connections\");\n}\n\nexport function getConnection(id: string): Promise<Connection> {\n return request<Connection>(`/connections/${id}`);\n}\n\nexport function deleteConnection(id: string): Promise<Connection> {\n return request<Connection>(`/connections/${id}`, { method: \"DELETE\" });\n}\n\nexport function testConnection(id: string): Promise<{ success: boolean; message: string }> {\n return request(`/connections/${id}/test`, { method: \"POST\", org: \"organizationId\" });\n}\n\nexport function getConnectionConfig(\n id: string,\n): Promise<{ schemaFilters: string[] | null; instructions: string | null }> {\n return request(`/connections/${id}/config`);\n}\n\n/** Mint a connect link / create a connection for the given connector. */\nexport function createLink(appId: string, body: Record<string, unknown>): Promise<LinkCreateResponse> {\n // POST /link/:appId resolves the org from the token's session, which always\n // matches the active org in the multi-token model — no org param needed.\n return request<LinkCreateResponse>(`/link/${appId}`, { method: \"POST\", org: \"none\", body });\n}\n\n/**\n * Poll a connect link's status. Uses the authenticated route, which (unlike the\n * public one) reports terminal states — `completed`/`failed` — so the CLI can\n * tell when the browser flow has finished.\n */\nexport function getLinkStatus(token: string): Promise<LinkStatus> {\n return request<LinkStatus>(`/link/${token}/status`, { org: \"none\" });\n}\n\nexport function execute(\n connectionId: string,\n tool: string,\n params: Record<string, unknown>,\n): Promise<ExecuteResult> {\n return request<ExecuteResult>(\"/execute\", {\n method: \"POST\",\n org: \"organization_id\",\n body: { connection_id: connectionId, tool, params },\n });\n}\n\nexport function search(useCase: string, connectionIds?: string[]): Promise<{ results: SearchResult[] }> {\n return request<{ results: SearchResult[] }>(\"/search\", {\n method: \"POST\",\n org: \"organization_id\",\n body: {\n action_info: `CLI search: ${useCase}`,\n use_case: useCase,\n connection_ids: connectionIds,\n },\n });\n}\n\nexport async function createApiKey(name: string): Promise<{ key: string; keyPrefix: string }> {\n const orgId = await activeOrgId();\n return request(`/organizations/${orgId}/api-keys`, { method: \"POST\", org: \"none\", body: { name } });\n}\n\nexport interface FileDownloadInfo {\n url: string;\n filename: string;\n size: number;\n expires_in_seconds: number;\n}\n\n/** Get a signed URL to download a file produced in a session (by sequel_execute / workbench). */\nexport function getFileDownloadUrl(sessionId: string, path: string): Promise<FileDownloadInfo> {\n return request<FileDownloadInfo>(\"/files/download\", { query: { session_id: sessionId, path } });\n}\n","import pc from \"picocolors\";\n\nexport { pc };\n\n/** True when the user passed a global --json flag (set by index.ts). */\nlet jsonMode = false;\nexport function setJsonMode(on: boolean): void {\n jsonMode = on;\n}\nexport function isJsonMode(): boolean {\n return jsonMode;\n}\n\nexport function printJson(data: unknown): void {\n process.stdout.write(`${JSON.stringify(data, null, 2)}\\n`);\n}\n\nfunction cell(value: unknown): string {\n if (value === null || value === undefined) return \"\";\n if (typeof value === \"object\") return JSON.stringify(value);\n return String(value);\n}\n\n/**\n * Render an array of records as an aligned text table. `columns` controls order\n * and which keys are shown; defaults to the union of keys in the first row.\n */\nexport function renderTable(rows: Array<Record<string, unknown>>, columns?: string[]): string {\n if (rows.length === 0) return pc.dim(\"(no rows)\");\n const cols = columns ?? Object.keys(rows[0]);\n const widths = cols.map((c) => Math.max(c.length, ...rows.map((r) => cell(r[c]).length)));\n\n const header = cols.map((c, i) => pc.bold(c.padEnd(widths[i]))).join(\" \");\n const sep = cols.map((_, i) => \"─\".repeat(widths[i])).join(\" \");\n const body = rows\n .map((r) => cols.map((c, i) => cell(r[c]).padEnd(widths[i])).join(\" \"))\n .join(\"\\n\");\n\n return `${header}\\n${pc.dim(sep)}\\n${body}`;\n}\n\nexport function printTable(rows: Array<Record<string, unknown>>, columns?: string[]): void {\n // Never emit human tables to stdout in JSON mode — keep stdout valid JSON for jq.\n if (jsonMode) return;\n process.stdout.write(`${renderTable(rows, columns)}\\n`);\n}\n\n// In JSON mode, human-facing lines go to stderr so stdout stays pure JSON.\nexport function success(message: string): void {\n (jsonMode ? process.stderr : process.stdout).write(`${pc.green(\"✓\")} ${message}\\n`);\n}\n\nexport function info(message: string): void {\n (jsonMode ? process.stderr : process.stdout).write(`${message}\\n`);\n}\n\nexport function fail(message: string): void {\n process.stderr.write(`${pc.red(\"✗\")} ${message}\\n`);\n}\n","import * as p from \"@clack/prompts\";\nimport { runLoginFlow } from \"../lib/auth\";\nimport { info, isJsonMode, pc, printJson, success } from \"../lib/output\";\n\nexport interface LoginOptions {\n /** Commander's `--no-browser` sets this to false: print the URL, don't open it. */\n browser?: boolean;\n}\n\nexport async function loginCommand(opts: LoginOptions = {}): Promise<void> {\n const json = isJsonMode();\n const openBrowser = opts.browser !== false;\n const opening = openBrowser ? \"Opening your browser to authorize…\" : \"Sign in with the URL below…\";\n if (json) {\n info(opening); // → stderr in JSON mode\n } else {\n p.intro(pc.cyan(\"Sign in to Sequel\"));\n p.log.info(opening);\n }\n\n const res = await runLoginFlow({ silent: !openBrowser });\n\n if (json) return printJson({ status: \"logged_in\", user: res.user, org: res.org ?? null });\n success(`Logged in as ${pc.bold(res.user.email)}${res.org ? ` · ${pc.bold(res.org.name)}` : \"\"}`);\n p.outro(\"You're all set. Try `sequel sources list` or `sequel connect`.\");\n}\n","import { clearConfig, isLoggedIn, readConfig } from \"../lib/config\";\nimport { info, isJsonMode, printJson, success } from \"../lib/output\";\n\nexport async function logoutCommand(): Promise<void> {\n const config = readConfig();\n if (!isLoggedIn(config)) {\n if (isJsonMode()) return printJson({ status: \"not_logged_in\" });\n info(\"You are not logged in.\");\n return;\n }\n clearConfig();\n if (isJsonMode()) return printJson({ status: \"logged_out\" });\n success(\"Logged out. Cached credentials removed from ~/.sequel/auth.json.\");\n}\n","import * as p from \"@clack/prompts\";\nimport { fetchOrganizations, getValidAccessToken, runLoginFlow } from \"../lib/auth\";\nimport { isLoggedIn, readConfig, resolveApiUrl, writeConfig } from \"../lib/config\";\nimport { isJsonMode, pc, success } from \"../lib/output\";\n\nexport async function switchCommand(): Promise<void> {\n if (isJsonMode()) {\n throw new Error(\n \"`sequel switch` is interactive (it prompts for an organization) — run it in a terminal, not piped/--json.\",\n );\n }\n const config = readConfig();\n if (!isLoggedIn(config)) {\n throw new Error(\"Not logged in. Run `sequel login` first.\");\n }\n\n // Refresh the membership list with the active org's token.\n let orgs = config.orgs ?? [];\n try {\n const { token } = await getValidAccessToken();\n orgs = await fetchOrganizations(resolveApiUrl(config), token);\n writeConfig({ ...readConfig(), orgs });\n } catch {\n // fall back to cached orgs\n }\n if (orgs.length === 0) throw new Error(\"No organizations available for this account.\");\n\n const selection = await p.select({\n message: \"Switch to organization\",\n options: orgs.map((o) => ({\n value: o.id,\n label: o.id === config.activeOrgId ? `${o.name} ${pc.dim(\"(current)\")}` : o.name,\n hint: config.tokens[o.id] ? o.role : \"sign-in required\",\n })),\n });\n if (p.isCancel(selection)) {\n p.cancel(\"Cancelled.\");\n return;\n }\n\n const orgId = selection as string;\n const org = orgs.find((o) => o.id === orgId);\n const fresh = readConfig();\n\n if (fresh.tokens[orgId]) {\n // Already authorized — instant, offline swap.\n writeConfig({ ...fresh, activeOrgId: orgId });\n success(`Switched to ${pc.bold(org?.name ?? orgId)}.`);\n return;\n }\n\n // No cached token for this org — sign in so the user can authorize it.\n p.log.info(`You haven't authorized ${pc.bold(org?.name ?? orgId)} yet — opening your browser…`);\n const res = await runLoginFlow();\n success(`Switched to ${pc.bold(res.org?.name ?? res.organizationId)}.`);\n}\n","import * as p from \"@clack/prompts\";\nimport open from \"open\";\nimport {\n type Connector,\n createLink,\n getLinkStatus,\n listConnectors,\n} from \"../lib/api\";\nimport { info, isJsonMode, pc, success } from \"../lib/output\";\n\nconst SECRET_RE = /pass|secret|token|key|connection|credential/i;\n\nfunction fieldsFor(connector: Connector): string[] {\n if (connector.userInputFields?.length) return connector.userInputFields;\n const props = (connector.credentialsSchema as { properties?: Record<string, unknown> } | undefined)?.properties;\n return props ? Object.keys(props) : [];\n}\n\nfunction isOAuth(connector: Connector): boolean {\n return Boolean(connector.configuration) || /oauth/i.test(connector.authId);\n}\n\n/** Poll a pending connect link until it completes or fails (or times out). */\nasync function pollLink(token: string): Promise<{ ok: boolean; reason?: string }> {\n const deadline = Date.now() + 5 * 60_000;\n while (Date.now() < deadline) {\n await new Promise((r) => setTimeout(r, 2000));\n let status;\n try {\n status = await getLinkStatus(token);\n } catch {\n continue; // transient — keep polling\n }\n if (status.status === \"failed\") return { ok: false, reason: status.reason };\n if (status.status === \"success\" || status.status === \"completed\") return { ok: true };\n }\n return { ok: false, reason: \"Timed out waiting for the browser to finish.\" };\n}\n\nexport async function connectCommand(source?: string): Promise<void> {\n if (isJsonMode()) {\n throw new Error(\n \"`sequel connect` is interactive (it prompts for credentials/consent) — run it in a terminal, not piped/--json.\",\n );\n }\n const connectors = await listConnectors();\n\n let connector: Connector | undefined;\n if (source) {\n connector = connectors.find((c) => c.id === source);\n if (!connector) {\n throw new Error(\n `Unknown connector \"${source}\". Available: ${connectors.map((c) => c.id).join(\", \")}`,\n );\n }\n } else {\n const choice = await p.select({\n message: \"Which data source do you want to connect?\",\n options: connectors\n .slice()\n .sort((a, b) => a.appType.localeCompare(b.appType) || a.name.localeCompare(b.name))\n .map((c) => ({ value: c.id, label: c.name, hint: c.appType })),\n });\n if (p.isCancel(choice)) {\n p.cancel(\"Cancelled.\");\n return;\n }\n connector = connectors.find((c) => c.id === (choice as string))!;\n }\n\n p.intro(`Connect ${pc.bold(connector.name)}`);\n\n if (!isOAuth(connector)) {\n // Pre-auth connector: collect credential fields in the terminal.\n const fields = fieldsFor(connector);\n const credentials: Record<string, string> = {};\n for (const field of fields) {\n const secret = SECRET_RE.test(field);\n const value = await (secret ? p.password : p.text)({\n message: field,\n });\n if (p.isCancel(value)) {\n p.cancel(\"Cancelled.\");\n return;\n }\n credentials[field] = value as string;\n }\n const name = await p.text({ message: \"Name for this source (optional)\", placeholder: connector.name });\n if (p.isCancel(name)) {\n p.cancel(\"Cancelled.\");\n return;\n }\n\n const s = p.spinner();\n s.start(\"Validating credentials…\");\n const res = await createLink(connector.id, {\n credentials,\n ...(name ? { name } : {}),\n });\n if (res.status === \"success\") {\n s.stop(\"Connected.\");\n success(`Created source ${pc.bold(res.connection.name)} (${res.connection.shortId}).`);\n return;\n }\n // Fallback: server wants more input — finish in the browser.\n s.stop(\"Continue in your browser…\");\n open(res.redirect_url).catch(() => {});\n info(`Open: ${res.redirect_url}`);\n const result = await pollLink(res.link_token);\n if (result.ok) success(\"Connected.\");\n else throw new Error(result.reason ?? \"Connection failed.\");\n return;\n }\n\n // OAuth connector: mint a link and let the polished web flow handle consent\n // (and any pre-OAuth fields like a project id), then poll for completion.\n const res = await createLink(connector.id, {});\n if (res.status === \"success\") {\n success(`Created source ${pc.bold(res.connection.name)} (${res.connection.shortId}).`);\n return;\n }\n open(res.redirect_url).catch(() => {});\n info(`Complete authorization in your browser:\\n${res.redirect_url}`);\n const s = p.spinner();\n s.start(\"Waiting for you to finish in the browser…\");\n const result = await pollLink(res.link_token);\n if (result.ok) {\n s.stop(\"Connected.\");\n success(\"Source connected.\");\n } else {\n s.stop(\"Failed.\");\n throw new Error(result.reason ?? \"Connection failed.\");\n }\n}\n","import * as p from \"@clack/prompts\";\nimport {\n type Connection,\n deleteConnection,\n getConnection,\n getConnectionConfig,\n listConnections,\n testConnection,\n} from \"../lib/api\";\nimport { info, isJsonMode, pc, printJson, printTable, success } from \"../lib/output\";\n\n/** Resolve a user-supplied id (uuid or shortId) to the connection's real id. */\nasync function resolveConnection(idOrShort: string): Promise<Connection> {\n const all = await listConnections();\n const match = all.find((c) => c.id === idOrShort || c.shortId === idOrShort);\n if (!match) throw new Error(`No source found matching \"${idOrShort}\".`);\n return match;\n}\n\nasync function pickConnection(message: string): Promise<Connection | undefined> {\n const all = await listConnections();\n if (all.length === 0) {\n info(\"No sources connected yet. Run `sequel connect`.\");\n return undefined;\n }\n const choice = await p.select({\n message,\n options: all.map((c) => ({ value: c.shortId, label: `${c.name} (${c.shortId})`, hint: c.type })),\n });\n if (p.isCancel(choice)) return undefined;\n return all.find((c) => c.shortId === (choice as string));\n}\n\nfunction toRow(c: Connection): Record<string, unknown> {\n return { id: c.shortId, name: c.name, type: c.type, created: c.createdAt.slice(0, 10) };\n}\n\nexport async function sourcesList(): Promise<void> {\n const connections = await listConnections();\n if (isJsonMode()) return printJson(connections);\n if (connections.length === 0) return info(\"No sources connected yet. Run `sequel connect`.\");\n printTable(connections.map(toRow), [\"id\", \"name\", \"type\", \"created\"]);\n}\n\nexport async function sourcesActive(): Promise<void> {\n const connections = await listConnections();\n const rows = await Promise.all(\n connections.map(async (c) => {\n let status = \"unknown\";\n try {\n const t = await testConnection(c.id);\n status = t.success ? \"healthy\" : \"error\";\n } catch {\n status = \"error\";\n }\n return { ...toRow(c), status };\n }),\n );\n if (isJsonMode()) return printJson(rows);\n if (rows.length === 0) return info(\"No sources connected yet. Run `sequel connect`.\");\n printTable(rows, [\"id\", \"name\", \"type\", \"status\", \"created\"]);\n}\n\nexport async function sourcesInfo(idOrShort?: string): Promise<void> {\n const conn = idOrShort ? await resolveConnection(idOrShort) : await pickConnection(\"Source to inspect\");\n if (!conn) return;\n const full = await getConnection(conn.id);\n let config: { schemaFilters: string[] | null; instructions: string | null } | null = null;\n try {\n config = await getConnectionConfig(conn.id);\n } catch {\n /* config may be absent */\n }\n if (isJsonMode()) return printJson({ ...full, config });\n\n info(`${pc.bold(full.name)} ${pc.dim(full.shortId)}`);\n info(`type: ${full.type}`);\n info(`id: ${full.id}`);\n info(`created: ${full.createdAt}`);\n if (config?.schemaFilters?.length) info(`schemas: ${config.schemaFilters.join(\", \")}`);\n if (config?.instructions) info(`\\n${pc.dim(config.instructions)}`);\n}\n\nexport async function sourcesDelete(idOrShort?: string): Promise<void> {\n const conn = idOrShort ? await resolveConnection(idOrShort) : await pickConnection(\"Source to delete\");\n if (!conn) return;\n const confirmed = await p.confirm({ message: `Delete ${pc.bold(conn.name)} (${conn.shortId})? This cannot be undone.` });\n if (p.isCancel(confirmed) || !confirmed) {\n info(\"Cancelled.\");\n return;\n }\n await deleteConnection(conn.id);\n success(`Deleted ${conn.name} (${conn.shortId}).`);\n}\n","import { readConfig, resolveApiUrl } from \"../lib/config\";\nimport { info, isJsonMode, pc, printJson, printTable } from \"../lib/output\";\n\ntype PublicSkill = { id: string; slug: string; name: string; category: string; apps: string[] };\ntype PublicSkillDetail = PublicSkill & { description: string; instructions: string };\n\n// Skills are public, so these hit the unauthenticated marketplace endpoints and\n// work before `sequel login`.\nasync function publicGet<T>(path: string): Promise<T> {\n const res = await fetch(`${resolveApiUrl(readConfig())}${path}`, { headers: { Accept: \"application/json\" } });\n if (res.status === 404) throw new Error(`No skill found matching \"${path.split(\"/\").pop()}\". Run \\`sequel skills list\\`.`);\n if (!res.ok) throw new Error(`Request failed (${res.status})`);\n return (await res.json()) as T;\n}\n\nexport async function skillsList(): Promise<void> {\n const skills = await publicGet<PublicSkill[]>(\"/marketplace/skills\");\n const rows = skills.map((s) => ({ id: s.slug, name: s.name }));\n if (isJsonMode()) return printJson(rows);\n printTable(rows, [\"id\", \"name\"]);\n info(`${rows.length} skills. \\`sequel skills show <id>\\` prints one; \\`sequel install\\` gives your agent all of them.`);\n}\n\nexport async function skillsShow(slug: string): Promise<void> {\n const skill = await publicGet<PublicSkillDetail>(`/marketplace/skills/${encodeURIComponent(slug)}`);\n if (isJsonMode()) return printJson(skill);\n process.stdout.write(\n `${pc.bold(skill.name)} ${pc.dim(skill.slug)}\\n${skill.description}\\n` +\n (skill.apps.length ? `${pc.dim(\"apps:\")} ${skill.apps.join(\", \")}\\n` : \"\") +\n `\\n${skill.instructions}\\n`,\n );\n}\n","import { homedir, platform } from \"node:os\";\nimport { dirname, join } from \"node:path\";\nimport { existsSync, mkdirSync, readFileSync, writeFileSync } from \"node:fs\";\nimport YAML from \"yaml\";\n\n//#region src/install.ts\nconst SERVER_NAME = \"sequel\";\n/** Folder name of the Sequel skill inside an agent's skills directory. */\nconst SKILL_NAME = \"sequel\";\n/**\n* Write the Sequel SKILL.md into `<dir>/sequel/SKILL.md`, replacing any previous\n* copy. Skill files are plain markdown, so unlike the MCP configs there is\n* nothing to merge: the whole file is ours.\n*/\nfunction installSkill({ dir, markdown }) {\n\tconst path = join(dir, SKILL_NAME, \"SKILL.md\");\n\tmkdirSync(dirname(path), { recursive: true });\n\twriteFileSync(path, markdown.endsWith(\"\\n\") ? markdown : `${markdown}\\n`);\n\treturn {\n\t\tkind: \"file\",\n\t\tpath\n\t};\n}\nconst mcpUrl = (apiUrl) => `${apiUrl.replace(/\\/$/, \"\")}/mcp`;\nconst bearer = (apiKey) => `Bearer ${apiKey}`;\nfunction home(opts) {\n\treturn opts.home ?? homedir();\n}\nfunction cwd(opts) {\n\treturn opts.cwd ?? process.cwd();\n}\n/** OS-specific application-support dir for a vendor folder. */\nfunction appSupport(opts, vendor) {\n\tconst h = home(opts);\n\tswitch (platform()) {\n\t\tcase \"darwin\": return join(h, \"Library\", \"Application Support\", vendor);\n\t\tcase \"win32\": return join(process.env.APPDATA ?? join(h, \"AppData\", \"Roaming\"), vendor);\n\t\tdefault: return join(process.env.XDG_CONFIG_HOME ?? join(h, \".config\"), vendor);\n\t}\n}\n/** Read+merge+write a JSON config, preserving every other key already present. */\nfunction mergeJson(path, mutate) {\n\tlet cfg = {};\n\tif (existsSync(path)) try {\n\t\tcfg = JSON.parse(readFileSync(path, \"utf8\"));\n\t} catch {\n\t\tcfg = {};\n\t}\n\tmutate(cfg);\n\tmkdirSync(dirname(path), { recursive: true });\n\twriteFileSync(path, `${JSON.stringify(cfg, null, 2)}\\n`);\n}\nfunction mergeYaml(path, mutate) {\n\tlet cfg = {};\n\tif (existsSync(path)) try {\n\t\tcfg = YAML.parse(readFileSync(path, \"utf8\")) ?? {};\n\t} catch {\n\t\tcfg = {};\n\t}\n\tmutate(cfg);\n\tmkdirSync(dirname(path), { recursive: true });\n\twriteFileSync(path, YAML.stringify(cfg));\n}\nfunction setNested(cfg, key, value) {\n\tconst obj = cfg[key] ?? {};\n\tobj[SERVER_NAME] = value;\n\tcfg[key] = obj;\n}\nconst mcpClients = [\n\t{\n\t\tslug: \"claude\",\n\t\tname: \"Claude Desktop\",\n\t\tscopes: [\"global\"],\n\t\tdescribe: (o) => join(appSupport(o, \"Claude\"), \"claude_desktop_config.json\"),\n\t\tinstall(o) {\n\t\t\tconst path = join(appSupport(o, \"Claude\"), \"claude_desktop_config.json\");\n\t\t\tmergeJson(path, (cfg) => setNested(cfg, \"mcpServers\", {\n\t\t\t\turl: mcpUrl(o.apiUrl),\n\t\t\t\theaders: { Authorization: bearer(o.apiKey) }\n\t\t\t}));\n\t\t\treturn {\n\t\t\t\tkind: \"file\",\n\t\t\t\tpath\n\t\t\t};\n\t\t}\n\t},\n\t{\n\t\tslug: \"claude-code\",\n\t\tname: \"Claude Code\",\n\t\tscopes: [\"global\", \"local\"],\n\t\tdescribe: (o) => `claude mcp add --scope ${o.scope === \"global\" ? \"user\" : \"local\"} --transport http ${SERVER_NAME} …`,\n\t\tskillsDir: (o) => o.scope === \"global\" ? join(home(o), \".claude\", \"skills\") : join(cwd(o), \".claude\", \"skills\"),\n\t\tinstall(o) {\n\t\t\treturn {\n\t\t\t\tkind: \"command\",\n\t\t\t\tcommand: \"claude\",\n\t\t\t\targs: [\n\t\t\t\t\t\"mcp\",\n\t\t\t\t\t\"add\",\n\t\t\t\t\t\"--scope\",\n\t\t\t\t\to.scope === \"global\" ? \"user\" : \"local\",\n\t\t\t\t\t\"--transport\",\n\t\t\t\t\t\"http\",\n\t\t\t\t\tSERVER_NAME,\n\t\t\t\t\tmcpUrl(o.apiUrl),\n\t\t\t\t\t\"--header\",\n\t\t\t\t\t`Authorization: ${bearer(o.apiKey)}`\n\t\t\t\t]\n\t\t\t};\n\t\t}\n\t},\n\t{\n\t\tslug: \"cursor\",\n\t\tname: \"Cursor\",\n\t\tscopes: [\"global\", \"local\"],\n\t\tdescribe: (o) => o.scope === \"global\" ? join(home(o), \".cursor\", \"mcp.json\") : join(cwd(o), \".cursor\", \"mcp.json\"),\n\t\tinstall(o) {\n\t\t\tconst path = o.scope === \"global\" ? join(home(o), \".cursor\", \"mcp.json\") : join(cwd(o), \".cursor\", \"mcp.json\");\n\t\t\tmergeJson(path, (cfg) => setNested(cfg, \"mcpServers\", {\n\t\t\t\turl: mcpUrl(o.apiUrl),\n\t\t\t\theaders: { Authorization: bearer(o.apiKey) }\n\t\t\t}));\n\t\t\treturn {\n\t\t\t\tkind: \"file\",\n\t\t\t\tpath\n\t\t\t};\n\t\t}\n\t},\n\t{\n\t\tslug: \"vscode\",\n\t\tname: \"VS Code\",\n\t\tscopes: [\"global\", \"local\"],\n\t\tdescribe: (o) => o.scope === \"global\" ? join(appSupport(o, \"Code\"), \"User\", \"mcp.json\") : join(cwd(o), \".vscode\", \"mcp.json\"),\n\t\tinstall(o) {\n\t\t\tconst path = o.scope === \"global\" ? join(appSupport(o, \"Code\"), \"User\", \"mcp.json\") : join(cwd(o), \".vscode\", \"mcp.json\");\n\t\t\tmergeJson(path, (cfg) => setNested(cfg, \"servers\", {\n\t\t\t\turl: mcpUrl(o.apiUrl),\n\t\t\t\ttype: \"http\",\n\t\t\t\theaders: { Authorization: bearer(o.apiKey) }\n\t\t\t}));\n\t\t\treturn {\n\t\t\t\tkind: \"file\",\n\t\t\t\tpath\n\t\t\t};\n\t\t}\n\t},\n\t{\n\t\tslug: \"windsurf\",\n\t\tname: \"Windsurf\",\n\t\tscopes: [\"global\"],\n\t\tdescribe: (o) => join(home(o), \".codeium\", \"windsurf\", \"mcp_config.json\"),\n\t\tinstall(o) {\n\t\t\tconst path = join(home(o), \".codeium\", \"windsurf\", \"mcp_config.json\");\n\t\t\tmergeJson(path, (cfg) => setNested(cfg, \"mcpServers\", {\n\t\t\t\tserverUrl: mcpUrl(o.apiUrl),\n\t\t\t\theaders: { Authorization: bearer(o.apiKey) }\n\t\t\t}));\n\t\t\treturn {\n\t\t\t\tkind: \"file\",\n\t\t\t\tpath\n\t\t\t};\n\t\t}\n\t},\n\t{\n\t\tslug: \"zed\",\n\t\tname: \"Zed\",\n\t\tscopes: [\"global\", \"local\"],\n\t\tdescribe: (o) => o.scope === \"global\" ? join(home(o), \".config\", \"zed\", \"settings.json\") : join(cwd(o), \".zed\", \"settings.json\"),\n\t\tinstall(o) {\n\t\t\tconst path = o.scope === \"global\" ? join(home(o), \".config\", \"zed\", \"settings.json\") : join(cwd(o), \".zed\", \"settings.json\");\n\t\t\tmergeJson(path, (cfg) => setNested(cfg, \"context_servers\", {\n\t\t\t\turl: mcpUrl(o.apiUrl),\n\t\t\t\tsettings: { headers: { Authorization: bearer(o.apiKey) } }\n\t\t\t}));\n\t\t\treturn {\n\t\t\t\tkind: \"file\",\n\t\t\t\tpath\n\t\t\t};\n\t\t}\n\t},\n\t{\n\t\tslug: \"codex\",\n\t\tname: \"Codex\",\n\t\tscopes: [\"global\"],\n\t\tdescribe: (o) => join(home(o), \".codex\", \"config.yaml\"),\n\t\tinstall(o) {\n\t\t\tconst path = join(home(o), \".codex\", \"config.yaml\");\n\t\t\tmergeYaml(path, (cfg) => setNested(cfg, \"mcp_servers\", {\n\t\t\t\turl: mcpUrl(o.apiUrl),\n\t\t\t\theaders: { Authorization: bearer(o.apiKey) }\n\t\t\t}));\n\t\t\treturn {\n\t\t\t\tkind: \"file\",\n\t\t\t\tpath\n\t\t\t};\n\t\t}\n\t},\n\t{\n\t\tslug: \"openclaw\",\n\t\tname: \"OpenClaw\",\n\t\tscopes: [\"global\"],\n\t\tdescribe: () => `openclaw mcp set ${SERVER_NAME} …`,\n\t\tinstall(o) {\n\t\t\tconst def = JSON.stringify({\n\t\t\t\turl: mcpUrl(o.apiUrl),\n\t\t\t\ttransport: \"streamable-http\",\n\t\t\t\theaders: { Authorization: bearer(o.apiKey) }\n\t\t\t});\n\t\t\treturn {\n\t\t\t\tkind: \"command\",\n\t\t\t\tcommand: \"openclaw\",\n\t\t\t\targs: [\n\t\t\t\t\t\"mcp\",\n\t\t\t\t\t\"set\",\n\t\t\t\t\tSERVER_NAME,\n\t\t\t\t\tdef\n\t\t\t\t]\n\t\t\t};\n\t\t}\n\t},\n\t{\n\t\tslug: \"hermes\",\n\t\tname: \"Hermes\",\n\t\tscopes: [\"global\"],\n\t\tdescribe: (o) => join(home(o), \".hermes\", \"config.yaml\"),\n\t\tinstall(o) {\n\t\t\tconst path = join(home(o), \".hermes\", \"config.yaml\");\n\t\t\tmergeYaml(path, (cfg) => setNested(cfg, \"mcp_servers\", {\n\t\t\t\turl: mcpUrl(o.apiUrl),\n\t\t\t\theaders: { Authorization: bearer(o.apiKey) }\n\t\t\t}));\n\t\t\treturn {\n\t\t\t\tkind: \"file\",\n\t\t\t\tpath\n\t\t\t};\n\t\t}\n\t}\n];\nfunction getMcpClient(slug) {\n\treturn mcpClients.find((c) => c.slug === slug);\n}\n\n//#endregion\nexport { SKILL_NAME, getMcpClient, installSkill, mcpClients };\n//# sourceMappingURL=install.js.map","import { resolveSiteUrl } from \"./config\";\n\n/**\n * The canonical Sequel skill is published by the marketing site under the Agent\n * Skills discovery convention. The CLI downloads it at install time rather than\n * bundling a copy, so an installed skill is always the current one and there is\n * a single source of truth for its content.\n */\nexport function skillMarkdownUrl(): string {\n return `${resolveSiteUrl().replace(/\\/$/, \"\")}/.well-known/agent-skills/sequel/SKILL.md`;\n}\n\nexport async function fetchSkillMarkdown(): Promise<string> {\n const url = skillMarkdownUrl();\n const res = await fetch(url, { headers: { Accept: \"text/markdown, text/plain;q=0.9, */*;q=0.1\" } });\n if (!res.ok) throw new Error(`Could not download the Sequel skill (${res.status}) from ${url}`);\n const text = await res.text();\n // A SKILL.md starts with YAML frontmatter; anything else is an error page.\n if (!text.trimStart().startsWith(\"---\")) {\n throw new Error(`Unexpected response from ${url}: not a SKILL.md`);\n }\n return text;\n}\n","import { execFileSync } from \"node:child_process\";\nimport * as p from \"@clack/prompts\";\nimport { createApiKey } from \"../lib/api\";\nimport { isLoggedIn, runLoginFlow } from \"../lib/auth\";\nimport { readConfig, resolveApiUrl } from \"../lib/config\";\nimport { type Scope, getMcpClient, installSkill, mcpClients } from \"../lib/mcp-clients\";\nimport { info, isJsonMode, pc, success } from \"../lib/output\";\nimport { fetchSkillMarkdown } from \"../lib/skills\";\n\nexport interface InstallOptions {\n /** `--scope global|local`; skips the scope prompt. Defaults to the agent's first scope when non-interactive. */\n scope?: string;\n /** Commander's `--no-browser` sets this to false: print the sign-in URL instead of opening it. */\n browser?: boolean;\n}\n\nconst SCOPES: readonly Scope[] = [\"global\", \"local\"];\n\nexport async function installCommand(slugArg?: string, opts: InstallOptions = {}): Promise<void> {\n // Piped/--json (how coding agents run us): no prompts at all. Everything the\n // prompts would have asked must come from the argument and flags instead.\n const interactive = !isJsonMode();\n const slugList = mcpClients.map((c) => c.slug).join(\", \");\n\n if (interactive) p.intro(pc.cyan(\"Install the Sequel MCP server and skill\"));\n\n // Reject a bad slug before opening a browser for sign-in.\n if (slugArg && !getMcpClient(slugArg)) throw new Error(`Unknown agent \"${slugArg}\". Options: ${slugList}`);\n if (!slugArg && !interactive) {\n throw new Error(`Pass the agent slug when running non-interactively: \\`sequel install <agent>\\`. Options: ${slugList}`);\n }\n\n // Sign in first if needed, then continue with the install.\n if (!isLoggedIn()) {\n const msg = \"You need to sign in to Sequel first — opening your browser…\";\n if (interactive) p.log.info(msg);\n else info(msg);\n try {\n const result = await runLoginFlow({ silent: opts.browser === false });\n const signedIn = `Signed in as ${result.user.email}${result.org ? ` (${result.org.name})` : \"\"}.`;\n if (interactive) p.log.success(signedIn);\n else success(signedIn);\n } catch (err) {\n if (!interactive) throw err;\n p.cancel(err instanceof Error ? err.message : String(err));\n return;\n }\n }\n\n let slug = slugArg;\n if (!slug) {\n const choice = await p.select({\n message: \"Which coding agent do you want to install Sequel into?\",\n options: mcpClients.map((c) => ({ value: c.slug, label: c.name })),\n });\n if (p.isCancel(choice)) return p.cancel(\"Cancelled.\");\n slug = choice as string;\n }\n\n const client = getMcpClient(slug);\n if (!client) throw new Error(`Unknown agent \"${slug}\". Options: ${slugList}`);\n\n let scope: Scope = client.scopes[0];\n if (opts.scope !== undefined) {\n if (!SCOPES.includes(opts.scope as Scope)) {\n throw new Error(`Unknown scope \"${opts.scope}\". Options: ${SCOPES.join(\", \")}`);\n }\n if (!client.scopes.includes(opts.scope as Scope)) {\n throw new Error(`${client.name} only supports the ${client.scopes.join(\"/\")} scope.`);\n }\n scope = opts.scope as Scope;\n } else if (client.scopes.length > 1 && interactive) {\n const choice = await p.select({\n message: \"Install scope\",\n options: [\n { value: \"global\", label: \"Global\", hint: \"available everywhere on this machine\" },\n { value: \"local\", label: \"Local\", hint: \"this project only\" },\n ].filter((o) => client.scopes.includes(o.value as Scope)),\n });\n if (p.isCancel(choice)) return p.cancel(\"Cancelled.\");\n scope = choice as Scope;\n }\n\n const config = readConfig();\n const apiUrl = resolveApiUrl(config);\n\n // Clack spinners assume a TTY; when piped, log plain lines instead.\n const s = interactive ? p.spinner() : null;\n s?.start(\"Creating a Sequel API key for this agent…\");\n let key: string;\n try {\n ({ key } = await createApiKey(`Sequel CLI (${client.name})`));\n } catch (err) {\n s?.stop(\"Failed to create API key.\");\n throw err;\n }\n s ? s.stop(\"API key created.\") : info(\"API key created.\");\n\n const result = client.install({ apiUrl, apiKey: key, scope });\n\n if (result.kind === \"command\") {\n // e.g. Claude Code: run `claude mcp add …`.\n try {\n execFileSync(result.command, result.args, { stdio: \"inherit\" });\n } catch {\n throw new Error(\n `Failed to run \\`${result.command}\\`. Make sure it's installed, or run manually:\\n${result.command} ${result.args.join(\" \")}`,\n );\n }\n success(`Installed Sequel into ${client.name} (${scope}).`);\n } else {\n success(`Installed Sequel into ${client.name}.`);\n info(`Config written to ${pc.dim(result.path)}`);\n }\n\n // The skill teaches the agent that Sequel's playbooks exist and how to reach\n // them; the MCP server above is what runs them. Install both where we can.\n const skillsDir = client.skillsDir?.({ apiUrl, apiKey: key, scope }) ?? null;\n if (skillsDir) {\n const sk = interactive ? p.spinner() : null;\n sk?.start(\"Installing the Sequel skill…\");\n try {\n const markdown = await fetchSkillMarkdown();\n const written = installSkill({ dir: skillsDir, markdown });\n sk ? sk.stop(\"Sequel skill installed.\") : success(\"Sequel skill installed.\");\n info(`Skill written to ${pc.dim(written.path)}`);\n } catch (err) {\n // The MCP install already succeeded; a skill download failure should not\n // undo that or look like it did.\n sk?.stop(\"Could not install the Sequel skill.\");\n const warning = `${err instanceof Error ? err.message : String(err)}\\nSequel still works through MCP; rerun \\`sequel install ${client.slug}\\` later to add the skill.`;\n if (interactive) p.log.warn(warning);\n else info(`Could not install the Sequel skill. ${warning}`);\n }\n } else {\n info(\n `${client.name} has no skills directory the CLI can write to; the Sequel skill is skipped. Playbooks are still available through MCP.`,\n );\n }\n\n const done = `Restart ${client.name} and ask it to \"list my Sequel connections\" to verify.`;\n if (interactive) p.outro(done);\n else info(done);\n}\n","import { search } from \"../lib/api\";\nimport { info, isJsonMode, pc, printJson } from \"../lib/output\";\n\nexport async function searchCommand(useCase: string, opts: { connection?: string[] }): Promise<void> {\n const res = await search(useCase, opts.connection);\n if (isJsonMode()) return printJson(res);\n\n if (res.results.length === 0) {\n info(\"No matching tools found across your connected sources.\");\n return;\n }\n\n for (const r of res.results) {\n info(`\\n${pc.bold(r.connection_name)} ${pc.dim(`(${r.connection_id} · ${r.app_id})`)}`);\n if (r.instructions) info(pc.dim(r.instructions));\n for (const tool of r.tools) {\n info(` ${pc.cyan(tool.tool_id)}`);\n if (tool.relevant_tables?.length) info(` tables: ${tool.relevant_tables.join(\", \")}`);\n }\n info(pc.dim(` → sequel execute ${r.connection_id} ${r.tools[0]?.tool_id ?? \"<tool>\"} -d '{…}'`));\n }\n}\n","import { execute } from \"../lib/api\";\nimport { info, isJsonMode, pc, printJson, printTable } from \"../lib/output\";\n\nexport async function executeCommand(\n connectionId: string,\n tool: string,\n opts: { data?: string },\n): Promise<void> {\n let params: Record<string, unknown> = {};\n if (opts.data) {\n try {\n params = JSON.parse(opts.data) as Record<string, unknown>;\n } catch {\n throw new Error(\"Invalid JSON passed to -d/--data.\");\n }\n }\n\n const res = await execute(connectionId, tool, params);\n if (isJsonMode()) return printJson(res);\n\n if (res.data.length === 0) {\n info(pc.dim(\"(0 rows)\"));\n return;\n }\n printTable(res.data, res.columns.length ? res.columns : undefined);\n info(pc.dim(`\\n${res.row_count} row(s)${res.truncated ? \" (truncated)\" : \"\"}`));\n}\n","import { writeFile } from \"node:fs/promises\";\nimport { getFileDownloadUrl } from \"../lib/api\";\nimport { info, isJsonMode, pc, printJson } from \"../lib/output\";\n\nfunction formatBytes(n: number): string {\n if (n < 1024) return `${n} B`;\n if (n < 1024 * 1024) return `${(n / 1024).toFixed(1)} KB`;\n return `${(n / (1024 * 1024)).toFixed(1)} MB`;\n}\n\nexport async function downloadCommand(\n sessionId: string,\n filePath: string,\n opts: { output?: string },\n): Promise<void> {\n const meta = await getFileDownloadUrl(sessionId, filePath);\n\n // JSON mode (explicit --json or piped): emit the metadata + signed URL for\n // scripting; don't write a file as a surprise side effect.\n if (isJsonMode()) return printJson(meta);\n\n const res = await fetch(meta.url);\n if (!res.ok) throw new Error(`Download failed (${res.status} ${res.statusText})`);\n const dest = opts.output ?? meta.filename;\n await writeFile(dest, Buffer.from(await res.arrayBuffer()));\n info(`${pc.green(\"✓\")} Downloaded ${pc.bold(meta.filename)} (${formatBytes(meta.size)}) → ${dest}`);\n}\n","import { execFileSync } from \"node:child_process\";\nimport * as p from \"@clack/prompts\";\nimport { isJsonMode, pc, printJson, success } from \"../lib/output\";\n\nconst PKG = \"@sequelsh/cli@latest\";\n\ntype Manager = { name: string; cmd: string; args: string[] };\n\n// Global-install command per package manager, in preference order.\nconst MANAGERS: Manager[] = [\n { name: \"npm\", cmd: \"npm\", args: [\"install\", \"-g\", PKG] },\n { name: \"pnpm\", cmd: \"pnpm\", args: [\"add\", \"-g\", PKG] },\n { name: \"bun\", cmd: \"bun\", args: [\"add\", \"-g\", PKG] },\n { name: \"yarn\", cmd: \"yarn\", args: [\"global\", \"add\", PKG] },\n];\n\nfunction has(cmd: string): boolean {\n try {\n execFileSync(process.platform === \"win32\" ? \"where\" : \"which\", [cmd], { stdio: \"ignore\" });\n return true;\n } catch {\n return false;\n }\n}\n\nexport async function upgradeCommand(): Promise<void> {\n const json = isJsonMode();\n if (!json) p.intro(pc.cyan(\"Upgrade the Sequel CLI\"));\n\n const manager = MANAGERS.find((m) => has(m.cmd));\n if (!manager) {\n const msg =\n \"No supported package manager found (npm, pnpm, bun, or yarn). Install Node.js from https://nodejs.org and try again.\";\n if (json) return printJson({ status: \"error\", error: msg });\n p.cancel(msg);\n return;\n }\n\n const s = json ? null : p.spinner();\n s?.start(`Updating ${PKG} with ${manager.name}…`);\n try {\n execFileSync(manager.cmd, manager.args, { stdio: \"pipe\" });\n } catch (err) {\n s?.stop(\"Upgrade failed.\");\n throw new Error(\n `Failed to run \\`${manager.cmd} ${manager.args.join(\" \")}\\`.\\n${\n err instanceof Error ? err.message : String(err)\n }`,\n );\n }\n s?.stop(\"Updated.\");\n\n if (json) return printJson({ status: \"upgraded\", package: PKG, manager: manager.name });\n success(\"Sequel CLI is now on the latest version.\");\n p.outro(\"Run `sequel --version` to confirm.\");\n}\n","import { Command } from \"commander\";\nimport pkg from \"../package.json\" with { type: \"json\" };\nimport { ApiError } from \"./lib/api\";\nimport { fail, setJsonMode } from \"./lib/output\";\nimport { loginCommand } from \"./commands/login\";\nimport { logoutCommand } from \"./commands/logout\";\nimport { switchCommand } from \"./commands/switch\";\nimport { connectCommand } from \"./commands/connect\";\nimport { sourcesActive, sourcesDelete, sourcesInfo, sourcesList } from \"./commands/sources\";\nimport { skillsList, skillsShow } from \"./commands/skills\";\nimport { installCommand } from \"./commands/install\";\nimport { searchCommand } from \"./commands/search\";\nimport { executeCommand } from \"./commands/execute\";\nimport { downloadCommand } from \"./commands/download\";\nimport { upgradeCommand } from \"./commands/upgrade\";\n\nconst program = new Command();\n\nprogram\n .name(\"sequel\")\n .description(\"Sequel CLI — connect data sources and run tools from your terminal\")\n // Inlined by tsdown at build time, so the reported version always matches\n // what the publish workflow bumped in package.json.\n .version(pkg.version)\n .option(\"--json\", \"output machine-readable JSON\")\n .enablePositionalOptions();\n\n/** Wrap a command action with shared --json handling and error reporting. */\nfunction action<A extends unknown[]>(fn: (...args: A) => Promise<void>) {\n return async (...args: A) => {\n // Auto-enable JSON when stdout is piped (e.g. `sequel sources | jq`), not just --json.\n if (program.opts().json || !process.stdout.isTTY) setJsonMode(true);\n try {\n await fn(...args);\n } catch (err) {\n if (err instanceof ApiError && err.status === 401) {\n fail(\"Unauthorized. Run `sequel login` to sign in again.\");\n } else {\n fail(err instanceof Error ? err.message : String(err));\n }\n process.exitCode = 1;\n }\n };\n}\n\nprogram.command(\"upgrade\").description(\"Upgrade the Sequel CLI to the latest version\").action(action(upgradeCommand));\nprogram\n .command(\"login\")\n .description(\"Sign in to Sequel\")\n .option(\"--no-browser\", \"print the sign-in URL instead of opening a browser\")\n .action(action(loginCommand));\nprogram.command(\"logout\").description(\"Sign out and remove cached credentials\").action(action(logoutCommand));\nprogram.command(\"switch\").description(\"Switch the active organization\").action(action(switchCommand));\n\nprogram\n .command(\"connect\")\n .argument(\"[source]\", \"connector id (e.g. postgres); omit to choose interactively\")\n .description(\"Connect a new data source\")\n .action(action(connectCommand));\n\nconst sources = program.command(\"sources\").description(\"Manage connected data sources\");\nsources.command(\"list\", { isDefault: true }).description(\"List connected sources\").action(action(sourcesList));\nsources.command(\"active\").description(\"List sources with live health status\").action(action(sourcesActive));\nsources\n .command(\"info\")\n .argument(\"[id]\", \"source id or short id\")\n .description(\"Show details for a source\")\n .action(action(sourcesInfo));\nsources\n .command(\"delete\")\n .argument(\"[id]\", \"source id or short id\")\n .description(\"Delete a source\")\n .action(action(sourcesDelete));\n\nconst skills = program.command(\"skills\").description(\"Browse the playbooks your agent can follow\");\nskills.command(\"list\", { isDefault: true }).description(\"List every skill (id and name)\").action(action(skillsList));\nskills\n .command(\"show\")\n .argument(\"<id>\", \"skill id, e.g. seo\")\n .description(\"Print a skill's playbook\")\n .action(action((id: string) => skillsShow(id)));\n\nprogram\n .command(\"install\")\n .argument(\"[agent]\", \"coding agent slug (e.g. cursor, claude-code)\")\n .option(\"-s, --scope <scope>\", \"global or local; skips the prompt (defaults to global when piped)\")\n .option(\"--no-browser\", \"print the sign-in URL instead of opening a browser if sign-in is needed\")\n .description(\"Install the Sequel MCP server into a coding agent\")\n .action(action(installCommand));\n\nprogram\n .command(\"search\")\n .argument(\"<usecase>\", \"what you want to do, e.g. \\\"monthly revenue\\\"\")\n .option(\"-c, --connection <id...>\", \"limit to specific connection short ids\")\n .description(\"Find the right tools for a use case across your sources\")\n .action(action((usecase: string, opts: { connection?: string[] }) => searchCommand(usecase, opts)));\n\nprogram\n .command(\"execute\")\n .argument(\"<connection_id>\", \"connection short id\")\n .argument(\"<tool>\", \"tool id, e.g. postgres.query\")\n .option(\"-d, --data <json>\", \"tool input as a JSON string\")\n .description(\"Execute a tool against a connection\")\n .action(action((connectionId: string, tool: string, opts: { data?: string }) => executeCommand(connectionId, tool, opts)));\n\nprogram\n .command(\"download\")\n .argument(\"<session_id>\", \"session id (from `sequel search` or an agent session)\")\n .argument(\"<path>\", \"file path, e.g. /data/result.csv or result.csv\")\n .option(\"-o, --output <file>\", \"write to this path (default: the file's own name)\")\n .description(\"Download a file produced by a query or workbench run\")\n .action(action((sessionId: string, path: string, opts: { output?: string }) => downloadCommand(sessionId, path, opts)));\n\nprogram.parseAsync(process.argv).catch((err) => {\n fail(err instanceof Error ? err.message : String(err));\n process.exit(1);\n});\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sequelsh/cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"description": "Sequel CLI — connect data sources and run tools from your terminal.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -55,6 +55,7 @@
|
|
|
55
55
|
"yaml": "^2.5.1"
|
|
56
56
|
},
|
|
57
57
|
"devDependencies": {
|
|
58
|
+
"@sequel/mcp-clients": "workspace:*",
|
|
58
59
|
"@sequel/typescript-config": "workspace:*",
|
|
59
60
|
"@types/node": "^22.10.0",
|
|
60
61
|
"tsdown": "^0.9.0",
|