@shield-agent/kya 0.10.1 → 0.12.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.
Files changed (79) hide show
  1. package/.mcp.json +1 -1
  2. package/README.md +3 -3
  3. package/amp/settings.example.json +1 -1
  4. package/claude/claude_desktop_config.example.json +1 -1
  5. package/cline/cline_mcp_settings.example.json +1 -1
  6. package/copilot/mcp-config.example.json +1 -1
  7. package/dist/cli.d.ts.map +1 -1
  8. package/dist/cli.js +80 -1
  9. package/dist/cli.js.map +1 -1
  10. package/dist/commands/connect.d.ts +14 -2
  11. package/dist/commands/connect.d.ts.map +1 -1
  12. package/dist/commands/connect.js +84 -31
  13. package/dist/commands/connect.js.map +1 -1
  14. package/dist/commands/gate-serve.d.ts +23 -0
  15. package/dist/commands/gate-serve.d.ts.map +1 -0
  16. package/dist/commands/gate-serve.js +93 -0
  17. package/dist/commands/gate-serve.js.map +1 -0
  18. package/dist/commands/gate.d.ts +85 -0
  19. package/dist/commands/gate.d.ts.map +1 -0
  20. package/dist/commands/gate.js +268 -0
  21. package/dist/commands/gate.js.map +1 -0
  22. package/dist/commands/stop.d.ts +3 -0
  23. package/dist/commands/stop.d.ts.map +1 -1
  24. package/dist/commands/stop.js +34 -0
  25. package/dist/commands/stop.js.map +1 -1
  26. package/dist/gate/binary.d.ts +49 -0
  27. package/dist/gate/binary.d.ts.map +1 -0
  28. package/dist/gate/binary.js +129 -0
  29. package/dist/gate/binary.js.map +1 -0
  30. package/dist/gate/config-gen.d.ts +24 -0
  31. package/dist/gate/config-gen.d.ts.map +1 -0
  32. package/dist/gate/config-gen.js +146 -0
  33. package/dist/gate/config-gen.js.map +1 -0
  34. package/dist/gate/config.d.ts +39 -0
  35. package/dist/gate/config.d.ts.map +1 -0
  36. package/dist/gate/config.js +177 -0
  37. package/dist/gate/config.js.map +1 -0
  38. package/dist/gate/daemon.d.ts +38 -0
  39. package/dist/gate/daemon.d.ts.map +1 -0
  40. package/dist/gate/daemon.js +117 -0
  41. package/dist/gate/daemon.js.map +1 -0
  42. package/dist/gate/otlp-decode.d.ts +21 -0
  43. package/dist/gate/otlp-decode.d.ts.map +1 -0
  44. package/dist/gate/otlp-decode.js +268 -0
  45. package/dist/gate/otlp-decode.js.map +1 -0
  46. package/dist/gate/otlp-receiver.d.ts +35 -0
  47. package/dist/gate/otlp-receiver.d.ts.map +1 -0
  48. package/dist/gate/otlp-receiver.js +186 -0
  49. package/dist/gate/otlp-receiver.js.map +1 -0
  50. package/dist/mcp-servers.d.ts +34 -0
  51. package/dist/mcp-servers.d.ts.map +1 -0
  52. package/dist/mcp-servers.js +272 -0
  53. package/dist/mcp-servers.js.map +1 -0
  54. package/dist/offline-evaluate.d.ts.map +1 -1
  55. package/dist/offline-evaluate.js +19 -0
  56. package/dist/offline-evaluate.js.map +1 -1
  57. package/dist/receipt/dashboard.d.ts +2 -0
  58. package/dist/receipt/dashboard.d.ts.map +1 -1
  59. package/dist/receipt/dashboard.js +12 -0
  60. package/dist/receipt/dashboard.js.map +1 -1
  61. package/dist/receipt/render-receipt.d.ts +2 -0
  62. package/dist/receipt/render-receipt.d.ts.map +1 -1
  63. package/dist/receipt/render-receipt.js +24 -4
  64. package/dist/receipt/render-receipt.js.map +1 -1
  65. package/droid/README.md +1 -1
  66. package/droid/mcp.example.json +1 -1
  67. package/gemini/settings.example.json +1 -1
  68. package/grok/README.md +1 -1
  69. package/kilo/kilo.example.json +1 -1
  70. package/kimi/mcp.example.json +1 -1
  71. package/kiro/mcp.example.json +1 -1
  72. package/manifest.json +1 -1
  73. package/mastracode/mcp.example.json +1 -1
  74. package/mcp.json +1 -1
  75. package/openai/codex.config.example.toml +1 -1
  76. package/opencode/opencode.example.json +1 -1
  77. package/package.json +1 -1
  78. package/qwen/settings.example.json +1 -1
  79. package/server.json +2 -2
@@ -1 +1 @@
1
- {"version":3,"file":"stop.js","sourceRoot":"","sources":["../../src/commands/stop.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,EACL,gBAAgB,EAChB,qBAAqB,EACrB,sBAAsB,EACtB,kBAAkB,EAClB,QAAQ,EACR,eAAe,GAEhB,MAAM,sBAAsB,CAAC;AAwB9B,SAAS,KAAK,CAAC,EAAU;IACvB,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,CAAC;AAC3D,CAAC;AAED,SAAS,WAAW,CAAC,GAAW;IAC9B,IAAI,CAAC;QACH,OAAO,CAAC,IAAI,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC;IAC/B,CAAC;IAAC,MAAM,CAAC;QACP,gBAAgB;IAClB,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,OAAO,CAAC,GAAW,EAAE,UAAuB,EAAE;IAClE,MAAM,KAAK,GAAG,eAAe,CAAC,GAAG,CAAC,CAAC;IACnC,IAAI,OAAO,GAAG,KAAK,CAAC;IACpB,IAAI,KAAK,GAAG,KAAK,CAAC;IAClB,IAAI,KAAK,EAAE,CAAC;QACV,IAAI,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,sBAAsB,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC;YAC9D,4DAA4D;YAC5D,gBAAgB,CAAC,GAAG,CAAC,CAAC;YACtB,KAAK,GAAG,IAAI,CAAC;QACf,CAAC;aAAM,CAAC;YACN,IAAI,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC;gBACxB,WAAW,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;gBACvB,KAAK,IAAI,MAAM,GAAG,CAAC,EAAE,MAAM,GAAG,KAAK,IAAI,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,MAAM,IAAI,GAAG,EAAE,CAAC;oBAC1E,MAAM,KAAK,CAAC,GAAG,CAAC,CAAC;gBACnB,CAAC;YACH,CAAC;YACD,gBAAgB,CAAC,GAAG,CAAC,CAAC;YACtB,OAAO,GAAG,IAAI,CAAC;QACjB,CAAC;IACH,CAAC;IAED,IAAI,YAA2C,CAAC;IAChD,IAAI,gBAAgB,GAAG,KAAK,CAAC;IAC7B,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC;QAChB,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,IAAI,OAAO,CAAC,QAAQ,CAAC;QACtD,IAAI,QAAQ,KAAK,OAAO,EAAE,CAAC;YACzB,uEAAuE;YACvE,8DAA8D;YAC9D,gBAAgB,GAAG,IAAI,CAAC;YACxB,YAAY,GAAG,EAAE,CAAC;QACpB,CAAC;aAAM,CAAC;YACN,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,IAAI,WAAW,CAAC;YACzC,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,IAAI,kBAAkB,CAAC,QAAQ,CAAC,CAAC;YAC5D,MAAM,KAAK,GAAa,EAAE,CAAC;YAC3B,KAAK,MAAM,GAAG,IAAI,qBAAqB,CAAC,KAAK,CAAC,EAAE,CAAC;gBAC/C,IAAI,OAAO,IAAI,GAAG,KAAK,KAAK,EAAE,GAAG;oBAAE,SAAS,CAAC,wBAAwB;gBACrE,IAAI,CAAC,GAAG,CAAC,CAAC;gBACV,KAAK,IAAI,MAAM,GAAG,CAAC,EAAE,MAAM,GAAG,KAAK,IAAI,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,IAAI,GAAG,EAAE,CAAC;oBACpE,MAAM,KAAK,CAAC,GAAG,CAAC,CAAC;gBACnB,CAAC;gBACD,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YAClB,CAAC;YACD,YAAY,GAAG,KAAK,CAAC;QACvB,CAAC;IACH,CAAC;IAED,OAAO;QACL,OAAO;QACP,GAAG,EAAE,KAAK,EAAE,GAAG;QACf,KAAK,EAAE,KAAK,IAAI,SAAS;QACzB,YAAY;QACZ,gBAAgB,EAAE,gBAAgB,IAAI,SAAS;KAChD,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,CAAa;IAC3C,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,IAAI,CAAC,CAAC,KAAK,EAAE,CAAC;QACZ,KAAK,CAAC,IAAI,CAAC,6BAA6B,CAAC,CAAC,GAAG,yCAAyC,CAAC,CAAC;IAC1F,CAAC;SAAM,CAAC;QACN,KAAK,CAAC,IAAI,CACR,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,8BAA8B,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,0BAA0B,CAChF,CAAC;IACJ,CAAC;IACD,IAAI,CAAC,CAAC,gBAAgB,EAAE,CAAC;QACvB,KAAK,CAAC,IAAI,CACR,iHAAiH,CAClH,CAAC;IACJ,CAAC;SAAM,IAAI,CAAC,CAAC,YAAY,EAAE,CAAC;QAC1B,KAAK,CAAC,IAAI,CACR,CAAC,CAAC,YAAY,CAAC,MAAM,GAAG,CAAC;YACvB,CAAC,CAAC,WAAW,CAAC,CAAC,YAAY,CAAC,MAAM,6BAA6B,CAAC,CAAC,YAAY;iBACxE,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,OAAO,GAAG,EAAE,CAAC;iBAC1B,IAAI,CAAC,IAAI,CAAC,EAAE;YACjB,CAAC,CAAC,kCAAkC,CACvC,CAAC;IACJ,CAAC;IACD,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC"}
1
+ {"version":3,"file":"stop.js","sourceRoot":"","sources":["../../src/commands/stop.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,49 @@
1
+ /** Pinned gateway build. Bump only together with the repack workflow input. */
2
+ export declare const GATE_VERSION = "1.5.0";
3
+ export declare function gateBinDir(env?: NodeJS.ProcessEnv): string;
4
+ export declare function gateBinaryPath(env?: NodeJS.ProcessEnv, platform?: NodeJS.Platform): string;
5
+ export interface GatePlatform {
6
+ readonly os: "linux" | "darwin" | "windows";
7
+ readonly arch: "amd64" | "arm64";
8
+ }
9
+ export declare function resolveGatePlatform(platform?: NodeJS.Platform, arch?: string): GatePlatform;
10
+ export declare function gateArtifactName(version: string, p: GatePlatform): string;
11
+ export declare function gateArtifactUrl(version: string, p: GatePlatform): string;
12
+ export declare function sha256Hex(buf: Uint8Array): string;
13
+ /** First hex token of a `<sha256> <name>` checksum file. */
14
+ export declare function parseSha256File(text: string): string;
15
+ export interface GateBinaryStatus {
16
+ readonly path: string;
17
+ readonly present: boolean;
18
+ /** First line of `kya-gate --version`, when readable. */
19
+ readonly version?: string;
20
+ }
21
+ export declare function inspectGateBinary(env?: NodeJS.ProcessEnv, platform?: NodeJS.Platform): GateBinaryStatus;
22
+ export interface EnsureBinaryDeps {
23
+ readonly env?: NodeJS.ProcessEnv;
24
+ readonly platform?: NodeJS.Platform;
25
+ readonly arch?: string;
26
+ /** Injectable for tests; defaults to global fetch. */
27
+ readonly fetchFn?: (url: string) => Promise<{
28
+ ok: boolean;
29
+ status: number;
30
+ arrayBuffer: () => Promise<ArrayBuffer>;
31
+ text: () => Promise<string>;
32
+ }>;
33
+ /** Injectable for tests; defaults to tar extraction via the system tar. */
34
+ readonly extract?: (tarGzPath: string, destDir: string) => void;
35
+ }
36
+ export interface EnsureBinaryResult {
37
+ readonly path: string;
38
+ readonly installed: boolean;
39
+ readonly version: string;
40
+ }
41
+ /**
42
+ * Install the pinned gateway binary when absent or stale (reported version ≠
43
+ * GATE_VERSION). Never silently downloads: this runs only from
44
+ * `kya gate setup`. A checksum mismatch aborts the install and leaves the
45
+ * previous binary untouched; the install itself is atomic (temp file +
46
+ * rename inside the bin dir).
47
+ */
48
+ export declare function ensureGateBinary(deps?: EnsureBinaryDeps): Promise<EnsureBinaryResult>;
49
+ //# sourceMappingURL=binary.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"binary.d.ts","sourceRoot":"","sources":["../../src/gate/binary.ts"],"names":[],"mappings":"AAeA,+EAA+E;AAC/E,eAAO,MAAM,YAAY,UAAU,CAAC;AAIpC,wBAAgB,UAAU,CAAC,GAAG,GAAE,MAAM,CAAC,UAAwB,GAAG,MAAM,CAEvE;AAED,wBAAgB,cAAc,CAC5B,GAAG,GAAE,MAAM,CAAC,UAAwB,EACpC,QAAQ,GAAE,MAAM,CAAC,QAA2B,GAC3C,MAAM,CAER;AAED,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,EAAE,EAAE,OAAO,GAAG,QAAQ,GAAG,SAAS,CAAC;IAC5C,QAAQ,CAAC,IAAI,EAAE,OAAO,GAAG,OAAO,CAAC;CAClC;AAED,wBAAgB,mBAAmB,CACjC,QAAQ,GAAE,MAAM,CAAC,QAA2B,EAC5C,IAAI,GAAE,MAAqB,GAC1B,YAAY,CAWd;AAED,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,EAAE,CAAC,EAAE,YAAY,GAAG,MAAM,CAEzE;AAED,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,EAAE,CAAC,EAAE,YAAY,GAAG,MAAM,CAExE;AAED,wBAAgB,SAAS,CAAC,GAAG,EAAE,UAAU,GAAG,MAAM,CAEjD;AAED,6DAA6D;AAC7D,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAIpD;AAED,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,yDAAyD;IACzD,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED,wBAAgB,iBAAiB,CAC/B,GAAG,GAAE,MAAM,CAAC,UAAwB,EACpC,QAAQ,GAAE,MAAM,CAAC,QAA2B,GAC3C,gBAAgB,CAqBlB;AAED,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;IACjC,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC,QAAQ,CAAC;IACpC,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB,sDAAsD;IACtD,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC;QAAE,EAAE,EAAE,OAAO,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,OAAO,CAAC,WAAW,CAAC,CAAC;QAAC,IAAI,EAAE,MAAM,OAAO,CAAC,MAAM,CAAC,CAAA;KAAE,CAAC,CAAC;IACnJ,2EAA2E;IAC3E,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;CACjE;AAMD,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;IAC5B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B;AAED;;;;;;GAMG;AACH,wBAAsB,gBAAgB,CAAC,IAAI,GAAE,gBAAqB,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAuD/F"}
@@ -0,0 +1,129 @@
1
+ /**
2
+ * Local gateway binary management. `kya gate setup` is the ONLY place a
3
+ * binary is downloaded: it fetches the pinned repacked artifact from this
4
+ * repo's own `gate-v*` GitHub release, verifies the published sha256, and
5
+ * installs to `<global .kya>/bin/kya-gate`. Everything else (run/doctor)
6
+ * only ever uses the binary already on disk.
7
+ */
8
+ import { createHash } from "node:crypto";
9
+ import { execFileSync } from "node:child_process";
10
+ import { chmodSync, existsSync, mkdirSync, mkdtempSync, readFileSync, renameSync, rmSync, writeFileSync } from "node:fs";
11
+ import { tmpdir } from "node:os";
12
+ import { join } from "node:path";
13
+ import { globalConfigDir } from "../config.js";
14
+ import { KyaError } from "../errors.js";
15
+ /** Pinned gateway build. Bump only together with the repack workflow input. */
16
+ export const GATE_VERSION = "1.5.0";
17
+ const RELEASE_REPO = "The-Pixel-Boys/shield-kya";
18
+ export function gateBinDir(env = process.env) {
19
+ return join(globalConfigDir(env), "bin");
20
+ }
21
+ export function gateBinaryPath(env = process.env, platform = process.platform) {
22
+ return join(gateBinDir(env), platform === "win32" ? "kya-gate.exe" : "kya-gate");
23
+ }
24
+ export function resolveGatePlatform(platform = process.platform, arch = process.arch) {
25
+ const os = platform === "darwin" ? "darwin" : platform === "win32" ? "windows" : platform === "linux" ? "linux" : undefined;
26
+ const a = arch === "x64" ? "amd64" : arch === "arm64" ? "arm64" : undefined;
27
+ if (!os || !a) {
28
+ throw new KyaError(`no gateway build for ${platform}/${arch} — supported: linux, darwin, windows × amd64, arm64`, "GATE_UNSUPPORTED_PLATFORM");
29
+ }
30
+ return { os, arch: a };
31
+ }
32
+ export function gateArtifactName(version, p) {
33
+ return `kya-gate-${version}-${p.os}-${p.arch}.tar.gz`;
34
+ }
35
+ export function gateArtifactUrl(version, p) {
36
+ return `https://github.com/${RELEASE_REPO}/releases/download/gate-v${version}/${gateArtifactName(version, p)}`;
37
+ }
38
+ export function sha256Hex(buf) {
39
+ return createHash("sha256").update(buf).digest("hex");
40
+ }
41
+ /** First hex token of a `<sha256> <name>` checksum file. */
42
+ export function parseSha256File(text) {
43
+ const m = /^([0-9a-f]{64})/i.exec(text.trim());
44
+ if (!m)
45
+ throw new KyaError("checksum file is malformed", "GATE_CHECKSUM_MALFORMED");
46
+ return m[1].toLowerCase();
47
+ }
48
+ export function inspectGateBinary(env = process.env, platform = process.platform) {
49
+ const path = gateBinaryPath(env, platform);
50
+ if (!existsSync(path))
51
+ return { path, present: false };
52
+ let version;
53
+ try {
54
+ const out = execFileSync(path, ["--version"], {
55
+ encoding: "utf8",
56
+ stdio: ["ignore", "pipe", "ignore"],
57
+ timeout: 5_000,
58
+ }).trim();
59
+ // The binary prints a JSON build object; fall back to the first line.
60
+ try {
61
+ const parsed = JSON.parse(out);
62
+ version = typeof parsed.version === "string" ? parsed.version : undefined;
63
+ }
64
+ catch {
65
+ version = out.split("\n")[0]?.trim();
66
+ }
67
+ }
68
+ catch {
69
+ version = undefined;
70
+ }
71
+ return { path, present: true, version: version || undefined };
72
+ }
73
+ function defaultExtract(tarGzPath, destDir) {
74
+ execFileSync("tar", ["-xzf", tarGzPath, "-C", destDir], { stdio: ["ignore", "ignore", "pipe"] });
75
+ }
76
+ /**
77
+ * Install the pinned gateway binary when absent or stale (reported version ≠
78
+ * GATE_VERSION). Never silently downloads: this runs only from
79
+ * `kya gate setup`. A checksum mismatch aborts the install and leaves the
80
+ * previous binary untouched; the install itself is atomic (temp file +
81
+ * rename inside the bin dir).
82
+ */
83
+ export async function ensureGateBinary(deps = {}) {
84
+ const env = deps.env ?? process.env;
85
+ const platform = deps.platform ?? process.platform;
86
+ const p = resolveGatePlatform(platform, deps.arch ?? process.arch);
87
+ const path = gateBinaryPath(env, platform);
88
+ const existing = inspectGateBinary(env, platform);
89
+ if (existing.present && existing.version === GATE_VERSION) {
90
+ return { path, installed: false, version: GATE_VERSION };
91
+ }
92
+ const fetchFn = deps.fetchFn ??
93
+ ((url) => fetch(url, { redirect: "follow", signal: AbortSignal.timeout(120_000) }));
94
+ const name = gateArtifactName(GATE_VERSION, p);
95
+ const base = gateArtifactUrl(GATE_VERSION, p);
96
+ const binDir = gateBinDir(env);
97
+ mkdirSync(binDir, { recursive: true });
98
+ const stage = mkdtempSync(join(tmpdir(), "kya-gate-"));
99
+ try {
100
+ const [tgzRes, sumRes] = [await fetchFn(base), await fetchFn(`${base}.sha256`)];
101
+ if (!tgzRes.ok || !sumRes.ok) {
102
+ throw new KyaError(`gateway artifact ${name} not available (HTTP ${!tgzRes.ok ? tgzRes.status : sumRes.status}) — run the repack workflow first or check the release tag gate-v${GATE_VERSION}`, "GATE_DOWNLOAD_FAILED");
103
+ }
104
+ const tgz = Buffer.from(await tgzRes.arrayBuffer());
105
+ const expected = parseSha256File(await sumRes.text());
106
+ const actual = sha256Hex(tgz);
107
+ if (actual !== expected) {
108
+ throw new KyaError(`gateway artifact checksum mismatch (expected ${expected}, got ${actual}) — refusing to install`, "GATE_CHECKSUM_MISMATCH");
109
+ }
110
+ const tgzPath = join(stage, name);
111
+ writeFileSync(tgzPath, tgz);
112
+ (deps.extract ?? defaultExtract)(tgzPath, stage);
113
+ const extracted = join(stage, platform === "win32" ? "kya-gate.exe" : "kya-gate");
114
+ if (!existsSync(extracted)) {
115
+ throw new KyaError(`gateway artifact ${name} did not contain a kya-gate binary — corrupt repack?`, "GATE_ARTIFACT_INVALID");
116
+ }
117
+ // Atomic install: stage beside the target, then rename over it.
118
+ const tmpTarget = join(binDir, `.kya-gate.${process.pid}.tmp`);
119
+ writeFileSync(tmpTarget, readFileSync(extracted));
120
+ if (platform !== "win32")
121
+ chmodSync(tmpTarget, 0o755);
122
+ renameSync(tmpTarget, path);
123
+ return { path, installed: true, version: GATE_VERSION };
124
+ }
125
+ finally {
126
+ rmSync(stage, { recursive: true, force: true });
127
+ }
128
+ }
129
+ //# sourceMappingURL=binary.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"binary.js","sourceRoot":"","sources":["../../src/gate/binary.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,24 @@
1
+ import type { GatewayServer, GatewaysConfig } from "./config.js";
2
+ /** Destructive-name family denied on every target, registry or not. */
3
+ export declare const DESTRUCTIVE_PATTERN = "(?:^|_)(?:drop|truncate|purge|transfer)(?:_|$)";
4
+ /** Loopback-only L4 rule for the (wildcard-bound) MCP listener. */
5
+ export declare const LOOPBACK_RULE = "cidr(\"127.0.0.0/8\").containsIP(source.address) || source.address == \"::1\"";
6
+ /** Deny patterns for one server: destructive family + its ADMIN registry rules. */
7
+ export declare function denyPatternsFor(serverId: string): readonly string[];
8
+ /**
9
+ * Whether an unmatched tool on this server is allowed: the registry
10
+ * defaultTier — READ and WRITE both map to allow (WRITE is observed, not
11
+ * blocked); an ADMIN default would deny. Unknown servers allow (local
12
+ * observe gateway), subject to the destructive deny.
13
+ */
14
+ export declare function unmatchedAllowed(serverId: string): boolean;
15
+ /** The OR-allow CEL rule for one server target. */
16
+ export declare function celAllowRule(server: GatewayServer): string;
17
+ /**
18
+ * Standalone gateway YAML: one listener multiplexing every server as an MCP
19
+ * target behind a loopback-only L4 allowlist, generated CEL authorization,
20
+ * OTLP/HTTP traces to the local receiver. `failureMode` (gateways.json,
21
+ * default failOpen) decides whether one broken target takes the gateway down.
22
+ */
23
+ export declare function generateGatewayYaml(config: GatewaysConfig): string;
24
+ //# sourceMappingURL=config-gen.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config-gen.d.ts","sourceRoot":"","sources":["../../src/gate/config-gen.ts"],"names":[],"mappings":"AA6BA,OAAO,KAAK,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAEjE,uEAAuE;AACvE,eAAO,MAAM,mBAAmB,mDAAmD,CAAC;AAEpF,mEAAmE;AACnE,eAAO,MAAM,aAAa,kFACmD,CAAC;AAE9E,mFAAmF;AACnF,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,MAAM,EAAE,CAGnE;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAE1D;AAMD,mDAAmD;AACnD,wBAAgB,YAAY,CAAC,MAAM,EAAE,aAAa,GAAG,MAAM,CAS1D;AA0CD;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,cAAc,GAAG,MAAM,CA0ClE"}
@@ -0,0 +1,146 @@
1
+ /**
2
+ * Generate the gateway YAML from `.kya/gateways.json` + the MCP server
3
+ * registry tiers. The CEL authorization rules are always derived from the
4
+ * registry — never hand-written:
5
+ *
6
+ * - destructive names (drop|truncate|purge|transfer, word-boundary anchored
7
+ * so `dropdown_select` is untouched) are denied for every server, and
8
+ * this deny always wins (rules are OR-allow, so the deny is expressed as
9
+ * "allow … AND NOT matches(deny)");
10
+ * - the server's ADMIN-tier registry patterns join the deny set;
11
+ * - everything else on the target is allowed: READ → allow, WRITE → allow
12
+ * (observe mode — allowed calls are audited, not blocked), and unmatched
13
+ * tools follow the server's defaultTier, which for every registered
14
+ * server resolves to one of those two allows;
15
+ * - unknown servers get the destructive-name deny only.
16
+ *
17
+ * A tool whose name matches the deny set has no allow rule, so the gateway
18
+ * denies the call (and filters it from tools/list).
19
+ *
20
+ * Listener hardening: the binary binds UNSPECIFIED with no config knob, so
21
+ * exposure is cut at L4 — a frontend networkAuthorization allowlist permits
22
+ * only loopback sources (127.0.0.0/8, ::1) — and the stats/readiness/admin
23
+ * listeners are turned off entirely. Logging is pinned to warn so module
24
+ * noise (and upstream build strings) stays out of gate.log.
25
+ */
26
+ import { mcpServerAdminPatterns, mcpServerDefaultTier, } from "../mcp-servers.js";
27
+ /** Destructive-name family denied on every target, registry or not. */
28
+ export const DESTRUCTIVE_PATTERN = "(?:^|_)(?:drop|truncate|purge|transfer)(?:_|$)";
29
+ /** Loopback-only L4 rule for the (wildcard-bound) MCP listener. */
30
+ export const LOOPBACK_RULE = 'cidr("127.0.0.0/8").containsIP(source.address) || source.address == "::1"';
31
+ /** Deny patterns for one server: destructive family + its ADMIN registry rules. */
32
+ export function denyPatternsFor(serverId) {
33
+ const admin = mcpServerAdminPatterns(serverId) ?? [];
34
+ return [...new Set([DESTRUCTIVE_PATTERN, ...admin])];
35
+ }
36
+ /**
37
+ * Whether an unmatched tool on this server is allowed: the registry
38
+ * defaultTier — READ and WRITE both map to allow (WRITE is observed, not
39
+ * blocked); an ADMIN default would deny. Unknown servers allow (local
40
+ * observe gateway), subject to the destructive deny.
41
+ */
42
+ export function unmatchedAllowed(serverId) {
43
+ return mcpServerDefaultTier(serverId) !== "ADMIN";
44
+ }
45
+ function celString(s) {
46
+ return `'${s.replace(/\\/g, "\\\\").replace(/'/g, "\\'")}'`;
47
+ }
48
+ /** The OR-allow CEL rule for one server target. */
49
+ export function celAllowRule(server) {
50
+ const target = `mcp.tool.target == ${celString(server.id)}`;
51
+ const deny = denyPatternsFor(server.id).join("|");
52
+ if (!unmatchedAllowed(server.id)) {
53
+ // ADMIN defaultTier: only explicitly non-denied, non-admin tools may run —
54
+ // allow nothing unmatched (no registered server has this today).
55
+ return `${target} && false`;
56
+ }
57
+ return `${target} && !mcp.tool.name.matches(${celString(deny)})`;
58
+ }
59
+ function q(s) {
60
+ return JSON.stringify(s);
61
+ }
62
+ function indent(lines, pad) {
63
+ return lines.map((l) => (l ? pad + l : l));
64
+ }
65
+ function targetYaml(server) {
66
+ const lines = [`- name: ${q(server.id)}`];
67
+ if (server.transport === "stdio") {
68
+ const [cmd, ...args] = server.cmd;
69
+ lines.push(" stdio:");
70
+ lines.push(` cmd: ${q(cmd)}`);
71
+ if (args.length > 0) {
72
+ lines.push(" args:");
73
+ lines.push(...args.map((a) => ` - ${q(a)}`));
74
+ }
75
+ if (server.env && Object.keys(server.env).length > 0) {
76
+ lines.push(" env:");
77
+ for (const [k, v] of Object.entries(server.env)) {
78
+ lines.push(` ${q(k)}: ${q(v)}`);
79
+ }
80
+ }
81
+ }
82
+ else {
83
+ lines.push(" mcp:");
84
+ lines.push(` host: ${q(server.url)}`);
85
+ if (server.headers && Object.keys(server.headers).length > 0) {
86
+ // Transport policy on the http target: static auth headers.
87
+ lines.push(" policies:");
88
+ lines.push(" requestHeaderModifier:");
89
+ lines.push(" set:");
90
+ for (const [k, v] of Object.entries(server.headers)) {
91
+ lines.push(` ${q(k)}: ${q(v)}`);
92
+ }
93
+ }
94
+ }
95
+ return lines;
96
+ }
97
+ /**
98
+ * Standalone gateway YAML: one listener multiplexing every server as an MCP
99
+ * target behind a loopback-only L4 allowlist, generated CEL authorization,
100
+ * OTLP/HTTP traces to the local receiver. `failureMode` (gateways.json,
101
+ * default failOpen) decides whether one broken target takes the gateway down.
102
+ */
103
+ export function generateGatewayYaml(config) {
104
+ const lines = [
105
+ "# Generated by kya gate — regenerate with `kya gate run` (do not edit).",
106
+ "config:",
107
+ ' statsAddr: "off"',
108
+ ' readinessAddr: "off"',
109
+ ' adminAddr: "off"',
110
+ " logging:",
111
+ ' level: "warn"',
112
+ " tracing:",
113
+ ` otlpEndpoint: ${q(`http://127.0.0.1:${config.otlpPort}`)}`,
114
+ ` otlpProtocol: "http"`,
115
+ " randomSampling: true",
116
+ "frontendPolicies:",
117
+ " networkAuthorization:",
118
+ " rules:",
119
+ ` - allow: ${q(LOOPBACK_RULE)}`,
120
+ "binds:",
121
+ ` - port: ${config.port}`,
122
+ " listeners:",
123
+ " - routes:",
124
+ " - backends:",
125
+ " - mcp:",
126
+ ` failureMode: ${q(config.failureMode)}`,
127
+ ];
128
+ if (config.servers.length === 0) {
129
+ lines.push(" targets: []");
130
+ return `${lines.join("\n")}\n`;
131
+ }
132
+ lines.push(" targets:");
133
+ for (const server of config.servers) {
134
+ lines.push(...indent(targetYaml(server), " "));
135
+ }
136
+ // Backend-level policies: sibling of `mcp`, applies to the whole target set
137
+ // (per-target rules match on mcp.tool.target inside the CEL).
138
+ lines.push(" policies:");
139
+ lines.push(" mcpAuthorization:");
140
+ lines.push(" rules:");
141
+ for (const server of config.servers) {
142
+ lines.push(` - ${q(celAllowRule(server))}`);
143
+ }
144
+ return `${lines.join("\n")}\n`;
145
+ }
146
+ //# sourceMappingURL=config-gen.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config-gen.js","sourceRoot":"","sources":["../../src/gate/config-gen.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,39 @@
1
+ export interface GatewayServer {
2
+ readonly id: string;
3
+ readonly transport: "stdio" | "http";
4
+ readonly cmd?: readonly string[];
5
+ readonly url?: string;
6
+ readonly env?: Readonly<Record<string, string>>;
7
+ /** http only: request headers for the remote server (auth tokens go here). */
8
+ readonly headers?: Readonly<Record<string, string>>;
9
+ }
10
+ export type GateFailureMode = "failOpen" | "failClosed";
11
+ export interface GatewaysConfig {
12
+ /** Listener port on 127.0.0.1 (default 3930). */
13
+ readonly port: number;
14
+ /** Local OTLP/HTTP receiver port (default 3931). */
15
+ readonly otlpPort: number;
16
+ /**
17
+ * Gateway behavior when a target fails to initialize: failOpen serves the
18
+ * healthy targets (default, better local UX); failClosed takes the whole
19
+ * gateway down (strict — a silently missing server is impossible).
20
+ */
21
+ readonly failureMode: GateFailureMode;
22
+ readonly servers: readonly GatewayServer[];
23
+ }
24
+ export declare const GATE_DEFAULT_PORT = 3930;
25
+ export declare const GATE_DEFAULT_OTLP_PORT = 3931;
26
+ export declare function gatewaysPath(env?: NodeJS.ProcessEnv): string;
27
+ /** Validate raw parsed JSON into a GatewaysConfig. Unknown top-level keys (recipes) are ignored. */
28
+ export declare function validateGateways(raw: unknown): GatewaysConfig;
29
+ export declare function readGateways(env?: NodeJS.ProcessEnv): GatewaysConfig;
30
+ /**
31
+ * Scaffold `.kya/gateways.json`: an empty active `servers` list plus the
32
+ * `recipes` catalog — move a recipe object into `servers` and fill its
33
+ * placeholders to enable it. Idempotent: an existing file is left alone.
34
+ */
35
+ export declare function scaffoldGateways(env?: NodeJS.ProcessEnv): {
36
+ path: string;
37
+ created: boolean;
38
+ };
39
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/gate/config.ts"],"names":[],"mappings":"AAYA,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,SAAS,EAAE,OAAO,GAAG,MAAM,CAAC;IACrC,QAAQ,CAAC,GAAG,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACjC,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,GAAG,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IAChD,8EAA8E;IAC9E,QAAQ,CAAC,OAAO,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;CACrD;AAED,MAAM,MAAM,eAAe,GAAG,UAAU,GAAG,YAAY,CAAC;AAExD,MAAM,WAAW,cAAc;IAC7B,iDAAiD;IACjD,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,oDAAoD;IACpD,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B;;;;OAIG;IACH,QAAQ,CAAC,WAAW,EAAE,eAAe,CAAC;IACtC,QAAQ,CAAC,OAAO,EAAE,SAAS,aAAa,EAAE,CAAC;CAC5C;AAED,eAAO,MAAM,iBAAiB,OAAO,CAAC;AACtC,eAAO,MAAM,sBAAsB,OAAO,CAAC;AAE3C,wBAAgB,YAAY,CAAC,GAAG,GAAE,MAAM,CAAC,UAAwB,GAAG,MAAM,CAEzE;AAsFD,oGAAoG;AACpG,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,OAAO,GAAG,cAAc,CAuB7D;AAED,wBAAgB,YAAY,CAC1B,GAAG,GAAE,MAAM,CAAC,UAAwB,GACnC,cAAc,CAYhB;AA6BD;;;;GAIG;AACH,wBAAgB,gBAAgB,CAC9B,GAAG,GAAE,MAAM,CAAC,UAAwB,GACnC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,OAAO,CAAA;CAAE,CAepC"}
@@ -0,0 +1,177 @@
1
+ /**
2
+ * `.kya/gateways.json` — the upstream MCP servers the local kya gateway
3
+ * federates. Strict JSON (hand-editable, merge-safe); `kya gate init` seeds
4
+ * it with a `recipes` catalog of ready-to-move entries for the well-known
5
+ * servers from the MCP server registry.
6
+ */
7
+ import { existsSync, mkdirSync, readFileSync } from "node:fs";
8
+ import { join } from "node:path";
9
+ import { globalConfigDir } from "../config.js";
10
+ import { UsageError } from "../errors.js";
11
+ import { atomicWriteSync } from "../fs-atomic.js";
12
+ export const GATE_DEFAULT_PORT = 3930;
13
+ export const GATE_DEFAULT_OTLP_PORT = 3931;
14
+ export function gatewaysPath(env = process.env) {
15
+ return join(globalConfigDir(env), "gateways.json");
16
+ }
17
+ const TARGET_ID_RE = /^[a-z0-9][a-z0-9-]*$/;
18
+ function isPlainObject(v) {
19
+ return typeof v === "object" && v !== null && !Array.isArray(v);
20
+ }
21
+ function parsePort(raw, key, fallback) {
22
+ if (raw === undefined)
23
+ return fallback;
24
+ if (typeof raw !== "number" || !Number.isInteger(raw) || raw < 1 || raw > 65535) {
25
+ throw new UsageError(`gateways.json: "${key}" must be an integer port 1-65535`);
26
+ }
27
+ return raw;
28
+ }
29
+ function parseServer(raw, index) {
30
+ const where = `gateways.json: servers[${index}]`;
31
+ if (!isPlainObject(raw))
32
+ throw new UsageError(`${where} must be an object`);
33
+ const id = raw.id;
34
+ if (typeof id !== "string" || !TARGET_ID_RE.test(id)) {
35
+ throw new UsageError(`${where}.id must match ${TARGET_ID_RE} (the gateway rejects underscores in target names)`);
36
+ }
37
+ const transport = raw.transport;
38
+ if (transport !== "stdio" && transport !== "http") {
39
+ throw new UsageError(`${where}.transport must be "stdio" or "http"`);
40
+ }
41
+ let cmd;
42
+ if (raw.cmd !== undefined) {
43
+ if (!Array.isArray(raw.cmd) ||
44
+ raw.cmd.length === 0 ||
45
+ raw.cmd.some((c) => typeof c !== "string" || c.length === 0)) {
46
+ throw new UsageError(`${where}.cmd must be a non-empty array of strings`);
47
+ }
48
+ cmd = raw.cmd;
49
+ }
50
+ let url;
51
+ if (raw.url !== undefined) {
52
+ if (typeof raw.url !== "string" || !/^https?:\/\//.test(raw.url)) {
53
+ throw new UsageError(`${where}.url must be an http(s) URL`);
54
+ }
55
+ url = raw.url;
56
+ }
57
+ let env;
58
+ if (raw.env !== undefined) {
59
+ if (!isPlainObject(raw.env) || Object.values(raw.env).some((v) => typeof v !== "string")) {
60
+ throw new UsageError(`${where}.env must be an object of string values`);
61
+ }
62
+ env = raw.env;
63
+ }
64
+ let headers;
65
+ if (raw.headers !== undefined) {
66
+ if (!isPlainObject(raw.headers) || Object.values(raw.headers).some((v) => typeof v !== "string")) {
67
+ throw new UsageError(`${where}.headers must be an object of string values`);
68
+ }
69
+ headers = raw.headers;
70
+ }
71
+ if (transport === "stdio" && !cmd) {
72
+ throw new UsageError(`${where}: transport "stdio" requires "cmd"`);
73
+ }
74
+ if (transport === "http" && !url) {
75
+ throw new UsageError(`${where}: transport "http" requires "url"`);
76
+ }
77
+ if (transport === "http" && env) {
78
+ // The gateway's http targets have no env concept; auth travels as headers.
79
+ throw new UsageError(`${where}: transport "http" does not support "env" — use "headers" (e.g. {"authorization": "Bearer …"})`);
80
+ }
81
+ if (transport === "stdio" && headers) {
82
+ throw new UsageError(`${where}: "headers" only applies to transport "http"`);
83
+ }
84
+ return {
85
+ id,
86
+ transport,
87
+ ...(cmd ? { cmd } : {}),
88
+ ...(url ? { url } : {}),
89
+ ...(env ? { env } : {}),
90
+ ...(headers ? { headers } : {}),
91
+ };
92
+ }
93
+ /** Validate raw parsed JSON into a GatewaysConfig. Unknown top-level keys (recipes) are ignored. */
94
+ export function validateGateways(raw) {
95
+ if (!isPlainObject(raw))
96
+ throw new UsageError("gateways.json must be a JSON object");
97
+ const port = parsePort(raw.port, "port", GATE_DEFAULT_PORT);
98
+ const otlpPort = parsePort(raw.otlpPort, "otlpPort", GATE_DEFAULT_OTLP_PORT);
99
+ let failureMode = "failOpen";
100
+ if (raw.failureMode !== undefined) {
101
+ if (raw.failureMode !== "failOpen" && raw.failureMode !== "failClosed") {
102
+ throw new UsageError('gateways.json: "failureMode" must be "failOpen" or "failClosed"');
103
+ }
104
+ failureMode = raw.failureMode;
105
+ }
106
+ if (raw.servers !== undefined && !Array.isArray(raw.servers)) {
107
+ throw new UsageError('gateways.json: "servers" must be an array');
108
+ }
109
+ const servers = (raw.servers ?? []).map(parseServer);
110
+ const seen = new Set();
111
+ for (const s of servers) {
112
+ if (seen.has(s.id)) {
113
+ throw new UsageError(`gateways.json: duplicate server id "${s.id}"`);
114
+ }
115
+ seen.add(s.id);
116
+ }
117
+ return { port, otlpPort, failureMode, servers };
118
+ }
119
+ export function readGateways(env = process.env) {
120
+ const path = gatewaysPath(env);
121
+ if (!existsSync(path)) {
122
+ return { port: GATE_DEFAULT_PORT, otlpPort: GATE_DEFAULT_OTLP_PORT, failureMode: "failOpen", servers: [] };
123
+ }
124
+ let raw;
125
+ try {
126
+ raw = JSON.parse(readFileSync(path, "utf8"));
127
+ }
128
+ catch {
129
+ throw new UsageError(`${path} is not valid JSON — fix it by hand, then re-run kya gate run`);
130
+ }
131
+ return validateGateways(raw);
132
+ }
133
+ const RECIPES = [
134
+ { id: "playwright", transport: "stdio", cmd: ["npx", "-y", "@playwright/mcp@latest"], note: "Browser automation" },
135
+ { id: "github", transport: "http", url: "https://api.githubcopilot.com/mcp/", headers: { authorization: "Bearer <github-pat>" }, note: "GitHub (remote; auth travels as a header — the gateway's http targets have no env)" },
136
+ { id: "slack", transport: "stdio", cmd: ["npx", "-y", "@modelcontextprotocol/server-slack"], env: { SLACK_BOT_TOKEN: "<xoxb-…>", SLACK_TEAM_ID: "<T…>" }, note: "Slack workspace" },
137
+ { id: "postgresql", transport: "stdio", cmd: ["npx", "-y", "@modelcontextprotocol/server-postgres", "postgresql://localhost/mydb"], note: "PostgreSQL (pass the connection string as the last arg)" },
138
+ { id: "filesystem", transport: "stdio", cmd: ["npx", "-y", "@modelcontextprotocol/server-filesystem", "."], note: "Local filesystem (scope = last args)" },
139
+ { id: "context7", transport: "http", url: "https://mcp.context7.com/mcp", note: "Library docs" },
140
+ { id: "figma", transport: "http", url: "https://mcp.figma.com/mcp", note: "Figma Dev Mode (remote)" },
141
+ { id: "browser-use", transport: "stdio", cmd: ["uvx", "browser-use", "--mcp"], note: "Browser Use agent" },
142
+ { id: "chrome-devtools", transport: "stdio", cmd: ["npx", "-y", "chrome-devtools-mcp@latest"], note: "Chrome DevTools" },
143
+ { id: "atlassian", transport: "http", url: "https://mcp.atlassian.com/v1/sse", note: "Jira/Confluence (remote, OAuth)" },
144
+ { id: "notion", transport: "http", url: "https://mcp.notion.com/mcp", note: "Notion (remote)" },
145
+ { id: "supabase", transport: "stdio", cmd: ["npx", "-y", "@supabase/mcp-server-supabase@latest"], env: { SUPABASE_ACCESS_TOKEN: "<sbp_…>" }, note: "Supabase projects" },
146
+ { id: "firecrawl", transport: "stdio", cmd: ["npx", "-y", "firecrawl-mcp"], env: { FIRECRAWL_API_KEY: "<fc-…>" }, note: "Web scraping" },
147
+ { id: "sequential-thinking", transport: "stdio", cmd: ["npx", "-y", "@modelcontextprotocol/server-sequential-thinking"], note: "Reasoning scratchpad" },
148
+ { id: "n8n", transport: "stdio", cmd: ["npx", "-y", "n8n-mcp"], note: "n8n workflows" },
149
+ { id: "linear", transport: "http", url: "https://mcp.linear.app/sse", note: "Linear (remote, OAuth)" },
150
+ { id: "serena", transport: "stdio", cmd: ["uvx", "--from", "git+https://github.com/oraios/serena", "serena-mcp-server"], note: "Code navigation" },
151
+ { id: "sentry", transport: "http", url: "https://mcp.sentry.dev/mcp", note: "Sentry (remote, OAuth)" },
152
+ { id: "zapier", transport: "http", url: "https://mcp.zapier.com/api/mcp/mcp", note: "Zapier actions (use your own MCP URL)" },
153
+ { id: "exa", transport: "http", url: "https://mcp.exa.ai/mcp", note: "Web search" },
154
+ ];
155
+ /**
156
+ * Scaffold `.kya/gateways.json`: an empty active `servers` list plus the
157
+ * `recipes` catalog — move a recipe object into `servers` and fill its
158
+ * placeholders to enable it. Idempotent: an existing file is left alone.
159
+ */
160
+ export function scaffoldGateways(env = process.env) {
161
+ const path = gatewaysPath(env);
162
+ if (existsSync(path))
163
+ return { path, created: false };
164
+ mkdirSync(globalConfigDir(env), { recursive: true });
165
+ const doc = {
166
+ port: GATE_DEFAULT_PORT,
167
+ // failOpen: one broken target never takes the gateway down (a missing
168
+ // server then fails silently — its tools just vanish). failClosed is the
169
+ // strict choice: any broken target stops the whole gateway.
170
+ failureMode: "failOpen",
171
+ servers: [],
172
+ recipes: RECIPES.map(({ note, ...entry }) => ({ note, ...entry })),
173
+ };
174
+ atomicWriteSync(path, `${JSON.stringify(doc, null, 2)}\n`);
175
+ return { path, created: true };
176
+ }
177
+ //# sourceMappingURL=config.js.map