@solongate/proxy 0.82.21 → 0.82.22
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +140 -791
- package/package.json +1 -1
- package/dist/create.d.ts +0 -13
- package/dist/create.js +0 -329
- package/dist/inject.d.ts +0 -19
- package/dist/inject.js +0 -375
package/dist/index.js
CHANGED
|
@@ -3398,12 +3398,12 @@ ${ctx.indent}`;
|
|
|
3398
3398
|
for (const {
|
|
3399
3399
|
format,
|
|
3400
3400
|
test,
|
|
3401
|
-
resolve:
|
|
3401
|
+
resolve: resolve7
|
|
3402
3402
|
} of tags) {
|
|
3403
3403
|
if (test) {
|
|
3404
3404
|
const match = str.match(test);
|
|
3405
3405
|
if (match) {
|
|
3406
|
-
let res =
|
|
3406
|
+
let res = resolve7.apply(null, match);
|
|
3407
3407
|
if (!(res instanceof Scalar)) res = new Scalar(res);
|
|
3408
3408
|
if (format) res.format = format;
|
|
3409
3409
|
return res;
|
|
@@ -6507,18 +6507,6 @@ var init_src = __esm({
|
|
|
6507
6507
|
});
|
|
6508
6508
|
|
|
6509
6509
|
// src/cli-utils.ts
|
|
6510
|
-
function log3(msg) {
|
|
6511
|
-
process.stderr.write(msg + "\n");
|
|
6512
|
-
}
|
|
6513
|
-
function printBanner(subtitle) {
|
|
6514
|
-
log3("");
|
|
6515
|
-
for (let i = 0; i < BANNER_FULL.length; i++) {
|
|
6516
|
-
log3(`${c.bold}${BANNER_COLORS[i]}${BANNER_FULL[i]}${c.reset}`);
|
|
6517
|
-
}
|
|
6518
|
-
log3("");
|
|
6519
|
-
log3(` ${c.dim}${c.italic}${subtitle}${c.reset}`);
|
|
6520
|
-
log3("");
|
|
6521
|
-
}
|
|
6522
6510
|
var c, BANNER_FULL, BANNER_COLORS;
|
|
6523
6511
|
var init_cli_utils = __esm({
|
|
6524
6512
|
"src/cli-utils.ts"() {
|
|
@@ -6622,9 +6610,9 @@ async function fetchLatest() {
|
|
|
6622
6610
|
function spawnGlobalInstall(version) {
|
|
6623
6611
|
try {
|
|
6624
6612
|
mkdirSync3(join4(homedir2(), ".solongate"), { recursive: true });
|
|
6625
|
-
const
|
|
6613
|
+
const log4 = openSync(LOG_FILE, "a");
|
|
6626
6614
|
const p = spawn("npm", ["install", "-g", `${PKG}@${version}`], {
|
|
6627
|
-
stdio: ["ignore",
|
|
6615
|
+
stdio: ["ignore", log4, log4],
|
|
6628
6616
|
detached: true,
|
|
6629
6617
|
windowsHide: true,
|
|
6630
6618
|
shell: process.platform === "win32"
|
|
@@ -6638,7 +6626,7 @@ function spawnGlobalInstall(version) {
|
|
|
6638
6626
|
}
|
|
6639
6627
|
}
|
|
6640
6628
|
function runGlobalInstall(version) {
|
|
6641
|
-
return new Promise((
|
|
6629
|
+
return new Promise((resolve7) => {
|
|
6642
6630
|
try {
|
|
6643
6631
|
mkdirSync3(join4(homedir2(), ".solongate"), { recursive: true });
|
|
6644
6632
|
execFile(
|
|
@@ -6653,11 +6641,11 @@ ${stderr}
|
|
|
6653
6641
|
`, { flag: "a" });
|
|
6654
6642
|
} catch {
|
|
6655
6643
|
}
|
|
6656
|
-
|
|
6644
|
+
resolve7(!err2);
|
|
6657
6645
|
}
|
|
6658
6646
|
);
|
|
6659
6647
|
} catch {
|
|
6660
|
-
|
|
6648
|
+
resolve7(false);
|
|
6661
6649
|
}
|
|
6662
6650
|
});
|
|
6663
6651
|
}
|
|
@@ -6772,11 +6760,11 @@ function startLogsServerDaemon() {
|
|
|
6772
6760
|
}
|
|
6773
6761
|
try {
|
|
6774
6762
|
mkdirSync4(DIR, { recursive: true });
|
|
6775
|
-
const
|
|
6763
|
+
const log4 = openSync2(LOG_FILE2, "a");
|
|
6776
6764
|
const cli = join5(dirname2(fileURLToPath2(import.meta.url)), "index.js");
|
|
6777
6765
|
const p = spawn2(process.execPath, [cli, "logs-server"], {
|
|
6778
6766
|
detached: true,
|
|
6779
|
-
stdio: ["ignore",
|
|
6767
|
+
stdio: ["ignore", log4, log4],
|
|
6780
6768
|
windowsHide: true
|
|
6781
6769
|
});
|
|
6782
6770
|
p.on("error", () => {
|
|
@@ -7854,7 +7842,7 @@ function LivePanel({ active: active2 }) {
|
|
|
7854
7842
|
const [localBuf, setLocalBuf] = useState2([]);
|
|
7855
7843
|
const [localOn, setLocalOn] = useState2(null);
|
|
7856
7844
|
const [ring, setRing] = useState2(null);
|
|
7857
|
-
const [
|
|
7845
|
+
const [log4, setLog] = useState2([]);
|
|
7858
7846
|
const [filter, setFilter] = useState2("all");
|
|
7859
7847
|
const [signal, setSignal] = useState2("none");
|
|
7860
7848
|
const [search, setSearch] = useState2("");
|
|
@@ -8698,7 +8686,7 @@ function LivePanel({ active: active2 }) {
|
|
|
8698
8686
|
] }),
|
|
8699
8687
|
/* @__PURE__ */ jsxs2(Box2, { flexDirection: "column", width: colW, overflow: "hidden", children: [
|
|
8700
8688
|
/* @__PURE__ */ jsx2(PaneTitle, { label: "EVENT LOG", extra: "system heartbeat", width: colW }),
|
|
8701
|
-
|
|
8689
|
+
log4.slice(-(colH - 1)).map((l, i) => /* @__PURE__ */ jsxs2(Text2, { wrap: "truncate", children: [
|
|
8702
8690
|
/* @__PURE__ */ jsxs2(Text2, { color: theme.dim, children: [
|
|
8703
8691
|
hhmmss(l.ts),
|
|
8704
8692
|
" "
|
|
@@ -12605,644 +12593,16 @@ var init_logs_server = __esm({
|
|
|
12605
12593
|
}
|
|
12606
12594
|
});
|
|
12607
12595
|
|
|
12608
|
-
// src/inject.ts
|
|
12609
|
-
var inject_exports = {};
|
|
12610
|
-
import { readFileSync as readFileSync12, writeFileSync as writeFileSync10, existsSync as existsSync7, copyFileSync } from "fs";
|
|
12611
|
-
import { resolve as resolve6 } from "path";
|
|
12612
|
-
import { execSync } from "child_process";
|
|
12613
|
-
function parseInjectArgs(argv) {
|
|
12614
|
-
const args = argv.slice(2);
|
|
12615
|
-
const opts = {
|
|
12616
|
-
dryRun: false,
|
|
12617
|
-
restore: false,
|
|
12618
|
-
skipInstall: false
|
|
12619
|
-
};
|
|
12620
|
-
for (let i = 0; i < args.length; i++) {
|
|
12621
|
-
switch (args[i]) {
|
|
12622
|
-
case "--file":
|
|
12623
|
-
opts.file = args[++i];
|
|
12624
|
-
break;
|
|
12625
|
-
case "--dry-run":
|
|
12626
|
-
opts.dryRun = true;
|
|
12627
|
-
break;
|
|
12628
|
-
case "--restore":
|
|
12629
|
-
opts.restore = true;
|
|
12630
|
-
break;
|
|
12631
|
-
case "--skip-install":
|
|
12632
|
-
opts.skipInstall = true;
|
|
12633
|
-
break;
|
|
12634
|
-
case "--help":
|
|
12635
|
-
case "-h":
|
|
12636
|
-
printHelp();
|
|
12637
|
-
process.exit(0);
|
|
12638
|
-
}
|
|
12639
|
-
}
|
|
12640
|
-
return opts;
|
|
12641
|
-
}
|
|
12642
|
-
function printHelp() {
|
|
12643
|
-
log3(`
|
|
12644
|
-
SolonGate Inject \u2014 Add security to your MCP server in seconds
|
|
12645
|
-
|
|
12646
|
-
USAGE
|
|
12647
|
-
npx @solongate/proxy inject [options]
|
|
12648
|
-
|
|
12649
|
-
OPTIONS
|
|
12650
|
-
--file <path> Entry file to modify (default: auto-detect)
|
|
12651
|
-
--dry-run Preview changes without writing
|
|
12652
|
-
--restore Restore original file from backup
|
|
12653
|
-
--skip-install Don't install SDK package
|
|
12654
|
-
-h, --help Show this help message
|
|
12655
|
-
|
|
12656
|
-
EXAMPLES
|
|
12657
|
-
npx @solongate/proxy inject # Auto-detect and inject
|
|
12658
|
-
npx @solongate/proxy inject --file src/main.ts # Specify entry file
|
|
12659
|
-
npx @solongate/proxy inject --dry-run # Preview changes
|
|
12660
|
-
npx @solongate/proxy inject --restore # Undo injection
|
|
12661
|
-
|
|
12662
|
-
WHAT IT DOES
|
|
12663
|
-
Replaces McpServer with SecureMcpServer (2 lines changed)
|
|
12664
|
-
All tool() calls are automatically protected by SolonGate.
|
|
12665
|
-
`);
|
|
12666
|
-
}
|
|
12667
|
-
function detectProject() {
|
|
12668
|
-
if (!existsSync7(resolve6("package.json"))) return false;
|
|
12669
|
-
try {
|
|
12670
|
-
const pkg = JSON.parse(readFileSync12(resolve6("package.json"), "utf-8"));
|
|
12671
|
-
const allDeps = { ...pkg.dependencies, ...pkg.devDependencies };
|
|
12672
|
-
return !!(allDeps["@modelcontextprotocol/sdk"] || allDeps["@modelcontextprotocol/server"]);
|
|
12673
|
-
} catch {
|
|
12674
|
-
return false;
|
|
12675
|
-
}
|
|
12676
|
-
}
|
|
12677
|
-
function findTsEntryFile() {
|
|
12678
|
-
try {
|
|
12679
|
-
const pkg = JSON.parse(readFileSync12(resolve6("package.json"), "utf-8"));
|
|
12680
|
-
if (pkg.bin) {
|
|
12681
|
-
const binPath = typeof pkg.bin === "string" ? pkg.bin : Object.values(pkg.bin)[0];
|
|
12682
|
-
if (typeof binPath === "string") {
|
|
12683
|
-
const srcPath = binPath.replace(/^\.\/dist\//, "./src/").replace(/\.js$/, ".ts");
|
|
12684
|
-
if (existsSync7(resolve6(srcPath))) return resolve6(srcPath);
|
|
12685
|
-
if (existsSync7(resolve6(binPath))) return resolve6(binPath);
|
|
12686
|
-
}
|
|
12687
|
-
}
|
|
12688
|
-
if (pkg.main) {
|
|
12689
|
-
const srcPath = pkg.main.replace(/^\.\/dist\//, "./src/").replace(/\.js$/, ".ts");
|
|
12690
|
-
if (existsSync7(resolve6(srcPath))) return resolve6(srcPath);
|
|
12691
|
-
}
|
|
12692
|
-
} catch {
|
|
12693
|
-
}
|
|
12694
|
-
const candidates = [
|
|
12695
|
-
"src/index.ts",
|
|
12696
|
-
"src/server.ts",
|
|
12697
|
-
"src/main.ts",
|
|
12698
|
-
"index.ts",
|
|
12699
|
-
"server.ts",
|
|
12700
|
-
"main.ts"
|
|
12701
|
-
];
|
|
12702
|
-
for (const c2 of candidates) {
|
|
12703
|
-
const full = resolve6(c2);
|
|
12704
|
-
if (existsSync7(full)) {
|
|
12705
|
-
try {
|
|
12706
|
-
const content = readFileSync12(full, "utf-8");
|
|
12707
|
-
if (content.includes("McpServer") || content.includes("McpServer")) {
|
|
12708
|
-
return full;
|
|
12709
|
-
}
|
|
12710
|
-
} catch {
|
|
12711
|
-
}
|
|
12712
|
-
}
|
|
12713
|
-
}
|
|
12714
|
-
for (const c2 of candidates) {
|
|
12715
|
-
if (existsSync7(resolve6(c2))) return resolve6(c2);
|
|
12716
|
-
}
|
|
12717
|
-
return null;
|
|
12718
|
-
}
|
|
12719
|
-
function detectPackageManager() {
|
|
12720
|
-
if (existsSync7(resolve6("pnpm-lock.yaml"))) return "pnpm";
|
|
12721
|
-
if (existsSync7(resolve6("yarn.lock"))) return "yarn";
|
|
12722
|
-
return "npm";
|
|
12723
|
-
}
|
|
12724
|
-
function installSdk() {
|
|
12725
|
-
try {
|
|
12726
|
-
const pkg = JSON.parse(readFileSync12(resolve6("package.json"), "utf-8"));
|
|
12727
|
-
const allDeps = { ...pkg.dependencies, ...pkg.devDependencies };
|
|
12728
|
-
if (allDeps["@solongate/proxy"]) {
|
|
12729
|
-
log3(" @solongate/proxy already installed");
|
|
12730
|
-
return true;
|
|
12731
|
-
}
|
|
12732
|
-
} catch {
|
|
12733
|
-
}
|
|
12734
|
-
const pm = detectPackageManager();
|
|
12735
|
-
const cmd = pm === "yarn" ? "yarn add @solongate/proxy" : `${pm} install @solongate/proxy`;
|
|
12736
|
-
log3(` Installing @solongate/proxy via ${pm}...`);
|
|
12737
|
-
try {
|
|
12738
|
-
execSync(cmd, { stdio: "pipe", cwd: process.cwd() });
|
|
12739
|
-
return true;
|
|
12740
|
-
} catch (err2) {
|
|
12741
|
-
log3(` Failed to install: ${err2 instanceof Error ? err2.message : String(err2)}`);
|
|
12742
|
-
log3(" You can install manually: npm install @solongate/proxy");
|
|
12743
|
-
return false;
|
|
12744
|
-
}
|
|
12745
|
-
}
|
|
12746
|
-
function injectTypeScript(filePath) {
|
|
12747
|
-
const original = readFileSync12(filePath, "utf-8");
|
|
12748
|
-
const changes = [];
|
|
12749
|
-
let modified = original;
|
|
12750
|
-
if (modified.includes("SecureMcpServer")) {
|
|
12751
|
-
return { file: filePath, changes: ["Already injected \u2014 skipping"], original, modified };
|
|
12752
|
-
}
|
|
12753
|
-
const mcpImportPatterns = [
|
|
12754
|
-
// Solo import: import { McpServer } from '...'
|
|
12755
|
-
/import\s*\{\s*McpServer\s*\}\s*from\s*['"][^'"]+['"]/,
|
|
12756
|
-
// Import with others: import { McpServer, ... } from '...'
|
|
12757
|
-
/import\s*\{[^}]*McpServer[^}]*\}\s*from\s*['"][^'"]+['"]/
|
|
12758
|
-
];
|
|
12759
|
-
let importReplaced = false;
|
|
12760
|
-
for (const pattern of mcpImportPatterns) {
|
|
12761
|
-
const match = modified.match(pattern);
|
|
12762
|
-
if (match) {
|
|
12763
|
-
const importLine = match[0];
|
|
12764
|
-
const namedImports = importLine.match(/\{([^}]+)\}/)?.[1] ?? "";
|
|
12765
|
-
const importNames = namedImports.split(",").map((s) => s.trim()).filter(Boolean);
|
|
12766
|
-
if (importNames.length === 1 && importNames[0] === "McpServer") {
|
|
12767
|
-
modified = modified.replace(
|
|
12768
|
-
importLine,
|
|
12769
|
-
`import { SecureMcpServer } from '@solongate/proxy'`
|
|
12770
|
-
);
|
|
12771
|
-
changes.push("Replaced McpServer import with SecureMcpServer from @solongate/proxy");
|
|
12772
|
-
} else {
|
|
12773
|
-
const otherImports = importNames.filter((n) => n !== "McpServer");
|
|
12774
|
-
const fromModule = importLine.match(/from\s*['"]([^'"]+)['"]/)?.[1] ?? "";
|
|
12775
|
-
modified = modified.replace(
|
|
12776
|
-
importLine,
|
|
12777
|
-
`import { ${otherImports.join(", ")} } from '${fromModule}';
|
|
12778
|
-
import { SecureMcpServer } from '@solongate/proxy'`
|
|
12779
|
-
);
|
|
12780
|
-
changes.push("Removed McpServer from existing import, added SecureMcpServer import from @solongate/proxy");
|
|
12781
|
-
}
|
|
12782
|
-
importReplaced = true;
|
|
12783
|
-
break;
|
|
12784
|
-
}
|
|
12785
|
-
}
|
|
12786
|
-
if (!importReplaced) {
|
|
12787
|
-
const insertPos = findImportInsertPosition(modified);
|
|
12788
|
-
modified = modified.slice(0, insertPos) + `import { SecureMcpServer } from '@solongate/proxy';
|
|
12789
|
-
` + modified.slice(insertPos);
|
|
12790
|
-
changes.push("Added SecureMcpServer import from @solongate/proxy");
|
|
12791
|
-
}
|
|
12792
|
-
const constructorPattern = /new\s+McpServer\s*\(/g;
|
|
12793
|
-
const constructorCount = (modified.match(constructorPattern) || []).length;
|
|
12794
|
-
if (constructorCount > 0) {
|
|
12795
|
-
modified = modified.replace(constructorPattern, "new SecureMcpServer(");
|
|
12796
|
-
changes.push(`Replaced ${constructorCount} McpServer constructor(s) with SecureMcpServer`);
|
|
12797
|
-
}
|
|
12798
|
-
return { file: filePath, changes, original, modified };
|
|
12799
|
-
}
|
|
12800
|
-
function findImportInsertPosition(content) {
|
|
12801
|
-
let pos = 0;
|
|
12802
|
-
if (content.startsWith("#!")) {
|
|
12803
|
-
pos = content.indexOf("\n") + 1;
|
|
12804
|
-
}
|
|
12805
|
-
const lines = content.slice(pos).split("\n");
|
|
12806
|
-
let offset = pos;
|
|
12807
|
-
for (const line of lines) {
|
|
12808
|
-
const trimmed = line.trim();
|
|
12809
|
-
if (trimmed === "" || trimmed.startsWith("//") || trimmed.startsWith("/*") || trimmed.startsWith("*") || trimmed.startsWith("*/")) {
|
|
12810
|
-
offset += line.length + 1;
|
|
12811
|
-
} else {
|
|
12812
|
-
break;
|
|
12813
|
-
}
|
|
12814
|
-
}
|
|
12815
|
-
const importRegex = /^import\s+.+$/gm;
|
|
12816
|
-
let lastImportEnd = offset;
|
|
12817
|
-
let importMatch;
|
|
12818
|
-
while ((importMatch = importRegex.exec(content)) !== null) {
|
|
12819
|
-
lastImportEnd = importMatch.index + importMatch[0].length + 1;
|
|
12820
|
-
}
|
|
12821
|
-
return lastImportEnd > offset ? lastImportEnd : offset;
|
|
12822
|
-
}
|
|
12823
|
-
function showDiff(result) {
|
|
12824
|
-
if (result.original === result.modified) {
|
|
12825
|
-
log3(" No changes needed.");
|
|
12826
|
-
return;
|
|
12827
|
-
}
|
|
12828
|
-
const origLines = result.original.split("\n");
|
|
12829
|
-
const modLines = result.modified.split("\n");
|
|
12830
|
-
log3("");
|
|
12831
|
-
log3(` File: ${result.file}`);
|
|
12832
|
-
log3(" \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500");
|
|
12833
|
-
const maxLines = Math.max(origLines.length, modLines.length);
|
|
12834
|
-
let diffCount = 0;
|
|
12835
|
-
for (let i = 0; i < maxLines; i++) {
|
|
12836
|
-
const orig = origLines[i];
|
|
12837
|
-
const mod = modLines[i];
|
|
12838
|
-
if (orig !== mod) {
|
|
12839
|
-
if (diffCount < 30) {
|
|
12840
|
-
if (orig !== void 0) log3(` - ${orig}`);
|
|
12841
|
-
if (mod !== void 0) log3(` + ${mod}`);
|
|
12842
|
-
}
|
|
12843
|
-
diffCount++;
|
|
12844
|
-
}
|
|
12845
|
-
}
|
|
12846
|
-
if (diffCount > 30) {
|
|
12847
|
-
log3(` ... and ${diffCount - 30} more line changes`);
|
|
12848
|
-
}
|
|
12849
|
-
log3("");
|
|
12850
|
-
}
|
|
12851
|
-
async function main() {
|
|
12852
|
-
const opts = parseInjectArgs(process.argv);
|
|
12853
|
-
printBanner("Inject SDK");
|
|
12854
|
-
if (!detectProject()) {
|
|
12855
|
-
log3(" Could not detect a TypeScript MCP server project.");
|
|
12856
|
-
log3(" Make sure you are in a project directory with:");
|
|
12857
|
-
log3(" package.json + @modelcontextprotocol/sdk in dependencies");
|
|
12858
|
-
log3("");
|
|
12859
|
-
log3(" To create a new MCP server: npx @solongate/proxy create <name>");
|
|
12860
|
-
process.exit(1);
|
|
12861
|
-
}
|
|
12862
|
-
log3(" Language: TypeScript");
|
|
12863
|
-
const entryFile = opts.file ? resolve6(opts.file) : findTsEntryFile();
|
|
12864
|
-
if (!entryFile || !existsSync7(entryFile)) {
|
|
12865
|
-
log3(` Could not find entry file.${opts.file ? ` File not found: ${opts.file}` : ""}`);
|
|
12866
|
-
log3("");
|
|
12867
|
-
log3(" Specify it manually: --file <path>");
|
|
12868
|
-
log3("");
|
|
12869
|
-
log3(" Common entry points:");
|
|
12870
|
-
log3(" src/index.ts, src/server.ts, index.ts");
|
|
12871
|
-
process.exit(1);
|
|
12872
|
-
}
|
|
12873
|
-
log3(` Entry: ${entryFile}`);
|
|
12874
|
-
log3("");
|
|
12875
|
-
const backupPath = entryFile + ".solongate-backup";
|
|
12876
|
-
if (opts.restore) {
|
|
12877
|
-
if (!existsSync7(backupPath)) {
|
|
12878
|
-
log3(" No backup found. Nothing to restore.");
|
|
12879
|
-
process.exit(1);
|
|
12880
|
-
}
|
|
12881
|
-
copyFileSync(backupPath, entryFile);
|
|
12882
|
-
log3(` Restored original file from backup.`);
|
|
12883
|
-
log3(` Backup: ${backupPath}`);
|
|
12884
|
-
process.exit(0);
|
|
12885
|
-
}
|
|
12886
|
-
if (!opts.skipInstall && !opts.dryRun) {
|
|
12887
|
-
installSdk();
|
|
12888
|
-
log3("");
|
|
12889
|
-
}
|
|
12890
|
-
const result = injectTypeScript(entryFile);
|
|
12891
|
-
log3(` Changes (${result.changes.length}):`);
|
|
12892
|
-
for (const change of result.changes) {
|
|
12893
|
-
log3(` - ${change}`);
|
|
12894
|
-
}
|
|
12895
|
-
if (result.changes.length === 1 && result.changes[0].includes("Already injected")) {
|
|
12896
|
-
log3("");
|
|
12897
|
-
log3(" Your MCP server is already protected by SolonGate!");
|
|
12898
|
-
process.exit(0);
|
|
12899
|
-
}
|
|
12900
|
-
if (result.original === result.modified) {
|
|
12901
|
-
log3("");
|
|
12902
|
-
log3(" No changes were made. The file may not contain recognizable MCP patterns.");
|
|
12903
|
-
log3(" See docs: https://solongate.com/docs/integration");
|
|
12904
|
-
process.exit(0);
|
|
12905
|
-
}
|
|
12906
|
-
if (opts.dryRun) {
|
|
12907
|
-
log3("");
|
|
12908
|
-
log3(" --- DRY RUN (no changes written) ---");
|
|
12909
|
-
showDiff(result);
|
|
12910
|
-
log3(" To apply: npx @solongate/proxy inject");
|
|
12911
|
-
process.exit(0);
|
|
12912
|
-
}
|
|
12913
|
-
if (!existsSync7(backupPath)) {
|
|
12914
|
-
copyFileSync(entryFile, backupPath);
|
|
12915
|
-
log3("");
|
|
12916
|
-
log3(` Backup: ${backupPath}`);
|
|
12917
|
-
}
|
|
12918
|
-
writeFileSync10(entryFile, result.modified);
|
|
12919
|
-
log3("");
|
|
12920
|
-
log3(" \u250C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510");
|
|
12921
|
-
log3(" \u2502 SolonGate SDK injected successfully! \u2502");
|
|
12922
|
-
log3(" \u2502 \u2502");
|
|
12923
|
-
log3(" \u2502 McpServer \u2192 SecureMcpServer \u2502");
|
|
12924
|
-
log3(" \u2502 All tool() calls are now auto-protected. \u2502");
|
|
12925
|
-
log3(" \u2502 \u2502");
|
|
12926
|
-
log3(" \u2502 Set your API key: \u2502");
|
|
12927
|
-
log3(" \u2502 export SOLONGATE_API_KEY=sg_live_xxx \u2502");
|
|
12928
|
-
log3(" \u2502 \u2502");
|
|
12929
|
-
log3(" \u2502 To undo: \u2502");
|
|
12930
|
-
log3(" \u2502 npx @solongate/proxy inject --restore \u2502");
|
|
12931
|
-
log3(" \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518");
|
|
12932
|
-
log3("");
|
|
12933
|
-
}
|
|
12934
|
-
var init_inject = __esm({
|
|
12935
|
-
"src/inject.ts"() {
|
|
12936
|
-
"use strict";
|
|
12937
|
-
init_cli_utils();
|
|
12938
|
-
main().catch((err2) => {
|
|
12939
|
-
log3(`Fatal: ${err2 instanceof Error ? err2.message : String(err2)}`);
|
|
12940
|
-
process.exit(1);
|
|
12941
|
-
});
|
|
12942
|
-
}
|
|
12943
|
-
});
|
|
12944
|
-
|
|
12945
|
-
// src/create.ts
|
|
12946
|
-
var create_exports = {};
|
|
12947
|
-
import { mkdirSync as mkdirSync10, writeFileSync as writeFileSync11, existsSync as existsSync8 } from "fs";
|
|
12948
|
-
import { resolve as resolve7, join as join16 } from "path";
|
|
12949
|
-
import { execSync as execSync2 } from "child_process";
|
|
12950
|
-
function withSpinner(message, fn) {
|
|
12951
|
-
const frames = ["\u28FE", "\u28FD", "\u28FB", "\u28BF", "\u287F", "\u28DF", "\u28EF", "\u28F7"];
|
|
12952
|
-
let i = 0;
|
|
12953
|
-
const id = setInterval(() => {
|
|
12954
|
-
const color = i % 2 === 0 ? c.blue3 : c.blue5;
|
|
12955
|
-
process.stderr.write(`\r ${color}${frames[i++ % frames.length]}${c.reset} ${c.dim}${message}${c.reset}`);
|
|
12956
|
-
}, 80);
|
|
12957
|
-
try {
|
|
12958
|
-
const result = fn();
|
|
12959
|
-
clearInterval(id);
|
|
12960
|
-
process.stderr.write(`\r ${c.green}\u2713${c.reset} ${message}${" ".repeat(20)}
|
|
12961
|
-
`);
|
|
12962
|
-
return result;
|
|
12963
|
-
} catch (err2) {
|
|
12964
|
-
clearInterval(id);
|
|
12965
|
-
process.stderr.write(`\r ${c.red}\u2717${c.reset} ${message} \u2014 failed${" ".repeat(10)}
|
|
12966
|
-
`);
|
|
12967
|
-
throw err2;
|
|
12968
|
-
}
|
|
12969
|
-
}
|
|
12970
|
-
function parseCreateArgs(argv) {
|
|
12971
|
-
const args = argv.slice(2);
|
|
12972
|
-
const opts = {
|
|
12973
|
-
name: "",
|
|
12974
|
-
policy: "",
|
|
12975
|
-
noInstall: false
|
|
12976
|
-
};
|
|
12977
|
-
for (let i = 0; i < args.length; i++) {
|
|
12978
|
-
switch (args[i]) {
|
|
12979
|
-
case "--policy":
|
|
12980
|
-
opts.policy = args[++i];
|
|
12981
|
-
break;
|
|
12982
|
-
case "--no-install":
|
|
12983
|
-
opts.noInstall = true;
|
|
12984
|
-
break;
|
|
12985
|
-
case "--help":
|
|
12986
|
-
case "-h":
|
|
12987
|
-
printHelp2();
|
|
12988
|
-
process.exit(0);
|
|
12989
|
-
break;
|
|
12990
|
-
default:
|
|
12991
|
-
if (!args[i].startsWith("-") && !opts.name) {
|
|
12992
|
-
opts.name = args[i];
|
|
12993
|
-
}
|
|
12994
|
-
}
|
|
12995
|
-
}
|
|
12996
|
-
if (!opts.name) {
|
|
12997
|
-
log3("");
|
|
12998
|
-
log3(" Error: Project name required.");
|
|
12999
|
-
log3("");
|
|
13000
|
-
log3(" Usage: npx @solongate/proxy create <name>");
|
|
13001
|
-
log3("");
|
|
13002
|
-
log3(" Examples:");
|
|
13003
|
-
log3(" npx @solongate/proxy create my-mcp-server");
|
|
13004
|
-
log3(" npx @solongate/proxy create weather-api");
|
|
13005
|
-
process.exit(1);
|
|
13006
|
-
}
|
|
13007
|
-
return opts;
|
|
13008
|
-
}
|
|
13009
|
-
function printHelp2() {
|
|
13010
|
-
log3(`
|
|
13011
|
-
SolonGate Create \u2014 Scaffold a secure MCP server in seconds
|
|
13012
|
-
|
|
13013
|
-
USAGE
|
|
13014
|
-
npx @solongate/proxy create <name> [options]
|
|
13015
|
-
|
|
13016
|
-
OPTIONS
|
|
13017
|
-
--policy <file> Policy JSON file (default: cloud-managed)
|
|
13018
|
-
--no-install Skip dependency installation
|
|
13019
|
-
-h, --help Show this help message
|
|
13020
|
-
|
|
13021
|
-
EXAMPLES
|
|
13022
|
-
npx @solongate/proxy create my-server
|
|
13023
|
-
npx @solongate/proxy create db-tools --policy ./policy.json
|
|
13024
|
-
`);
|
|
13025
|
-
}
|
|
13026
|
-
function createProject(dir, name, _policy) {
|
|
13027
|
-
writeFileSync11(
|
|
13028
|
-
join16(dir, "package.json"),
|
|
13029
|
-
JSON.stringify(
|
|
13030
|
-
{
|
|
13031
|
-
name,
|
|
13032
|
-
version: "0.1.0",
|
|
13033
|
-
type: "module",
|
|
13034
|
-
private: true,
|
|
13035
|
-
bin: { [name]: "./dist/index.js" },
|
|
13036
|
-
scripts: {
|
|
13037
|
-
build: "tsup src/index.ts --format esm",
|
|
13038
|
-
dev: "tsx --env-file=.env src/index.ts",
|
|
13039
|
-
start: "node --env-file=.env dist/index.js"
|
|
13040
|
-
},
|
|
13041
|
-
dependencies: {
|
|
13042
|
-
"@modelcontextprotocol/sdk": "^1.26.0",
|
|
13043
|
-
"@solongate/proxy": "latest",
|
|
13044
|
-
zod: "^3.25.0"
|
|
13045
|
-
},
|
|
13046
|
-
devDependencies: {
|
|
13047
|
-
"@types/node": "^22.0.0",
|
|
13048
|
-
tsup: "^8.3.0",
|
|
13049
|
-
tsx: "^4.19.0",
|
|
13050
|
-
typescript: "^5.7.0"
|
|
13051
|
-
}
|
|
13052
|
-
},
|
|
13053
|
-
null,
|
|
13054
|
-
2
|
|
13055
|
-
) + "\n"
|
|
13056
|
-
);
|
|
13057
|
-
writeFileSync11(
|
|
13058
|
-
join16(dir, "tsconfig.json"),
|
|
13059
|
-
JSON.stringify(
|
|
13060
|
-
{
|
|
13061
|
-
compilerOptions: {
|
|
13062
|
-
target: "ES2022",
|
|
13063
|
-
module: "ESNext",
|
|
13064
|
-
moduleResolution: "bundler",
|
|
13065
|
-
esModuleInterop: true,
|
|
13066
|
-
strict: true,
|
|
13067
|
-
outDir: "dist",
|
|
13068
|
-
rootDir: "src",
|
|
13069
|
-
declaration: true,
|
|
13070
|
-
skipLibCheck: true
|
|
13071
|
-
},
|
|
13072
|
-
include: ["src"]
|
|
13073
|
-
},
|
|
13074
|
-
null,
|
|
13075
|
-
2
|
|
13076
|
-
) + "\n"
|
|
13077
|
-
);
|
|
13078
|
-
mkdirSync10(join16(dir, "src"), { recursive: true });
|
|
13079
|
-
writeFileSync11(
|
|
13080
|
-
join16(dir, "src", "index.ts"),
|
|
13081
|
-
`#!/usr/bin/env node
|
|
13082
|
-
|
|
13083
|
-
console.log = (...args: unknown[]) => {
|
|
13084
|
-
process.stderr.write(args.map(String).join(' ') + '\\n');
|
|
13085
|
-
};
|
|
13086
|
-
|
|
13087
|
-
import { SecureMcpServer } from '@solongate/proxy';
|
|
13088
|
-
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
|
|
13089
|
-
import { z } from 'zod';
|
|
13090
|
-
|
|
13091
|
-
// Policy is managed from the SolonGate Dashboard (https://solongate.com)
|
|
13092
|
-
// No local policySet needed \u2014 it's fetched from the cloud via your API key.
|
|
13093
|
-
const server = new SecureMcpServer(
|
|
13094
|
-
{ name: '${name}', version: '0.1.0' },
|
|
13095
|
-
);
|
|
13096
|
-
|
|
13097
|
-
server.tool(
|
|
13098
|
-
'hello',
|
|
13099
|
-
'Say hello to someone',
|
|
13100
|
-
{ name: z.string().describe('Name of the person to greet') },
|
|
13101
|
-
async ({ name }: { name: string }) => ({
|
|
13102
|
-
content: [{ type: 'text', text: \`Hello, \${name}! Welcome to ${name}.\` }],
|
|
13103
|
-
}),
|
|
13104
|
-
);
|
|
13105
|
-
|
|
13106
|
-
const transport = new StdioServerTransport();
|
|
13107
|
-
await server.connect(transport);
|
|
13108
|
-
console.log('');
|
|
13109
|
-
console.log('${name} is running (stdio mode)');
|
|
13110
|
-
console.log('');
|
|
13111
|
-
console.log('MCP servers communicate over stdin/stdout \u2014 not HTTP.');
|
|
13112
|
-
console.log('You need an MCP client to connect:');
|
|
13113
|
-
console.log('');
|
|
13114
|
-
console.log(' Claude Code Open this folder, .mcp.json is auto-detected');
|
|
13115
|
-
console.log(' Antigravity .agents/mcp_config.json (or ~/.gemini/config/mcp_config.json)');
|
|
13116
|
-
console.log(' OpenClaw Uses openclaw.plugin.json config');
|
|
13117
|
-
console.log('');
|
|
13118
|
-
console.log('Press Ctrl+C to stop.');
|
|
13119
|
-
`
|
|
13120
|
-
);
|
|
13121
|
-
writeFileSync11(
|
|
13122
|
-
join16(dir, ".mcp.json"),
|
|
13123
|
-
JSON.stringify(
|
|
13124
|
-
{
|
|
13125
|
-
mcpServers: {
|
|
13126
|
-
[name]: {
|
|
13127
|
-
command: "node",
|
|
13128
|
-
args: ["dist/index.js"],
|
|
13129
|
-
env: {
|
|
13130
|
-
SOLONGATE_API_KEY: "sg_live_YOUR_KEY_HERE"
|
|
13131
|
-
}
|
|
13132
|
-
}
|
|
13133
|
-
}
|
|
13134
|
-
},
|
|
13135
|
-
null,
|
|
13136
|
-
2
|
|
13137
|
-
) + "\n"
|
|
13138
|
-
);
|
|
13139
|
-
writeFileSync11(
|
|
13140
|
-
join16(dir, ".env"),
|
|
13141
|
-
`SOLONGATE_API_KEY=sg_live_YOUR_KEY_HERE
|
|
13142
|
-
`
|
|
13143
|
-
);
|
|
13144
|
-
writeFileSync11(
|
|
13145
|
-
join16(dir, ".gitignore"),
|
|
13146
|
-
`node_modules/
|
|
13147
|
-
dist/
|
|
13148
|
-
*.solongate-backup
|
|
13149
|
-
.env
|
|
13150
|
-
.env.local
|
|
13151
|
-
.mcp.json
|
|
13152
|
-
`
|
|
13153
|
-
);
|
|
13154
|
-
}
|
|
13155
|
-
async function main2() {
|
|
13156
|
-
const opts = parseCreateArgs(process.argv);
|
|
13157
|
-
const dir = resolve7(opts.name);
|
|
13158
|
-
printBanner("Create MCP Server");
|
|
13159
|
-
if (existsSync8(dir)) {
|
|
13160
|
-
log3(` ${c.red}Error:${c.reset} Directory "${opts.name}" already exists.`);
|
|
13161
|
-
process.exit(1);
|
|
13162
|
-
}
|
|
13163
|
-
withSpinner(`Setting up ${opts.name}...`, () => {
|
|
13164
|
-
mkdirSync10(dir, { recursive: true });
|
|
13165
|
-
createProject(dir, opts.name, opts.policy);
|
|
13166
|
-
});
|
|
13167
|
-
if (!opts.noInstall) {
|
|
13168
|
-
withSpinner("Installing dependencies...", () => {
|
|
13169
|
-
execSync2("npm install", { cwd: dir, stdio: "pipe" });
|
|
13170
|
-
});
|
|
13171
|
-
}
|
|
13172
|
-
log3("");
|
|
13173
|
-
const stripAnsi = (s) => s.replace(/\x1b\[[0-9;]*m/g, "");
|
|
13174
|
-
const W = 52;
|
|
13175
|
-
const hr = "\u2500".repeat(W + 2);
|
|
13176
|
-
const bLine = (text) => {
|
|
13177
|
-
const visible = stripAnsi(text);
|
|
13178
|
-
const padding = W - visible.length;
|
|
13179
|
-
log3(` ${c.dim}\u2502${c.reset} ${text}${" ".repeat(Math.max(0, padding))} ${c.dim}\u2502${c.reset}`);
|
|
13180
|
-
};
|
|
13181
|
-
const bEmpty = () => log3(` ${c.dim}\u2502${c.reset} ${" ".repeat(W)} ${c.dim}\u2502${c.reset}`);
|
|
13182
|
-
log3(` ${c.dim}\u256D${hr}\u256E${c.reset}`);
|
|
13183
|
-
log3(` ${c.dim}\u2502${c.reset} ${c.green}${c.bold}\u2714 MCP Server created successfully!${c.reset}${" ".repeat(W - 35)} ${c.dim}\u2502${c.reset}`);
|
|
13184
|
-
log3(` ${c.dim}\u251C${hr}\u2524${c.reset}`);
|
|
13185
|
-
bEmpty();
|
|
13186
|
-
bLine(`${c.yellow}Next steps:${c.reset}`);
|
|
13187
|
-
bEmpty();
|
|
13188
|
-
bLine(` ${c.cyan}$${c.reset} cd ${c.bold}${opts.name}${c.reset}`);
|
|
13189
|
-
bLine(` ${c.cyan}$${c.reset} npm run build`);
|
|
13190
|
-
bLine(` ${c.cyan}$${c.reset} npm run dev ${c.dim}# dev mode${c.reset}`);
|
|
13191
|
-
bLine(` ${c.cyan}$${c.reset} npm start ${c.dim}# production${c.reset}`);
|
|
13192
|
-
bEmpty();
|
|
13193
|
-
log3(` ${c.dim}\u251C${hr}\u2524${c.reset}`);
|
|
13194
|
-
bEmpty();
|
|
13195
|
-
bLine(`${c.yellow}Set your API key:${c.reset}`);
|
|
13196
|
-
bEmpty();
|
|
13197
|
-
bLine(` ${c.cyan}$${c.reset} export SOLONGATE_API_KEY=${c.blue3}sg_live_xxx${c.reset}`);
|
|
13198
|
-
bEmpty();
|
|
13199
|
-
bLine(`${c.dim}https://dashboard.solongate.com/api-keys/${c.reset}`);
|
|
13200
|
-
bEmpty();
|
|
13201
|
-
log3(` ${c.dim}\u251C${hr}\u2524${c.reset}`);
|
|
13202
|
-
bEmpty();
|
|
13203
|
-
bLine(`${c.yellow}Use with any MCP server:${c.reset}`);
|
|
13204
|
-
bEmpty();
|
|
13205
|
-
bLine(` ${c.cyan}$${c.reset} solongate-proxy -- npx @modelcontextprotocol/server-filesystem .`);
|
|
13206
|
-
bLine(` ${c.cyan}$${c.reset} solongate-proxy -- npx @playwright/mcp@latest`);
|
|
13207
|
-
bLine(` ${c.dim}Wraps any MCP server or AI tool with SolonGate protection${c.reset}`);
|
|
13208
|
-
bEmpty();
|
|
13209
|
-
log3(` ${c.dim}\u251C${hr}\u2524${c.reset}`);
|
|
13210
|
-
bEmpty();
|
|
13211
|
-
bLine(`${c.yellow}Use with Claude Code / MCP client:${c.reset}`);
|
|
13212
|
-
bEmpty();
|
|
13213
|
-
bLine(` ${c.dim}1.${c.reset} Replace ${c.blue3}sg_live_YOUR_KEY_HERE${c.reset} in .mcp.json`);
|
|
13214
|
-
bLine(` ${c.dim}2.${c.reset} Open this folder in your MCP client`);
|
|
13215
|
-
bLine(` ${c.dim}3.${c.reset} .mcp.json is auto-detected on startup`);
|
|
13216
|
-
bEmpty();
|
|
13217
|
-
bLine(`${c.yellow}Direct test (without MCP client):${c.reset}`);
|
|
13218
|
-
bEmpty();
|
|
13219
|
-
bLine(` ${c.dim}1.${c.reset} Replace ${c.blue3}sg_live_YOUR_KEY_HERE${c.reset} in .env`);
|
|
13220
|
-
bLine(` ${c.dim}2.${c.reset} ${c.cyan}$${c.reset} npm run build && npm start`);
|
|
13221
|
-
bEmpty();
|
|
13222
|
-
log3(` ${c.dim}\u2570${hr}\u256F${c.reset}`);
|
|
13223
|
-
log3("");
|
|
13224
|
-
}
|
|
13225
|
-
var init_create = __esm({
|
|
13226
|
-
"src/create.ts"() {
|
|
13227
|
-
"use strict";
|
|
13228
|
-
init_cli_utils();
|
|
13229
|
-
main2().catch((err2) => {
|
|
13230
|
-
log3(`Fatal: ${err2 instanceof Error ? err2.message : String(err2)}`);
|
|
13231
|
-
process.exit(1);
|
|
13232
|
-
});
|
|
13233
|
-
}
|
|
13234
|
-
});
|
|
13235
|
-
|
|
13236
12596
|
// src/pull-push.ts
|
|
13237
12597
|
var pull_push_exports = {};
|
|
13238
|
-
import { readFileSync as
|
|
13239
|
-
import { resolve as
|
|
12598
|
+
import { readFileSync as readFileSync12, writeFileSync as writeFileSync10, existsSync as existsSync7 } from "fs";
|
|
12599
|
+
import { resolve as resolve6 } from "path";
|
|
13240
12600
|
function loadEnv() {
|
|
13241
12601
|
if (process.env.SOLONGATE_API_KEY) return;
|
|
13242
|
-
const envPath =
|
|
13243
|
-
if (!
|
|
12602
|
+
const envPath = resolve6(".env");
|
|
12603
|
+
if (!existsSync7(envPath)) return;
|
|
13244
12604
|
try {
|
|
13245
|
-
const content =
|
|
12605
|
+
const content = readFileSync12(envPath, "utf-8");
|
|
13246
12606
|
for (const line of content.split("\n")) {
|
|
13247
12607
|
const trimmed = line.trim();
|
|
13248
12608
|
if (!trimmed || trimmed.startsWith("#")) continue;
|
|
@@ -13284,20 +12644,20 @@ function parseCliArgs() {
|
|
|
13284
12644
|
}
|
|
13285
12645
|
}
|
|
13286
12646
|
if (!apiKey) {
|
|
13287
|
-
|
|
13288
|
-
|
|
13289
|
-
|
|
13290
|
-
|
|
13291
|
-
|
|
13292
|
-
|
|
13293
|
-
|
|
12647
|
+
log3(red2("ERROR: API key not found."));
|
|
12648
|
+
log3("");
|
|
12649
|
+
log3("Set it in .env file:");
|
|
12650
|
+
log3(" SOLONGATE_API_KEY=sg_live_...");
|
|
12651
|
+
log3("");
|
|
12652
|
+
log3("Or pass via environment:");
|
|
12653
|
+
log3(` SOLONGATE_API_KEY=sg_live_... solongate-proxy ${command}`);
|
|
13294
12654
|
process.exit(1);
|
|
13295
12655
|
}
|
|
13296
12656
|
if (!apiKey.startsWith("sg_live_")) {
|
|
13297
|
-
|
|
12657
|
+
log3(red2("ERROR: Pull/push/list requires a live API key (sg_live_...)."));
|
|
13298
12658
|
process.exit(1);
|
|
13299
12659
|
}
|
|
13300
|
-
return { command, apiKey, file:
|
|
12660
|
+
return { command, apiKey, file: resolve6(file), policyId };
|
|
13301
12661
|
}
|
|
13302
12662
|
async function listPolicies(apiKey) {
|
|
13303
12663
|
const res = await fetch(`${API_URL}/api/v1/policies`, {
|
|
@@ -13310,18 +12670,18 @@ async function listPolicies(apiKey) {
|
|
|
13310
12670
|
async function list5(apiKey, policyId) {
|
|
13311
12671
|
const policies = await listPolicies(apiKey);
|
|
13312
12672
|
if (policies.length === 0) {
|
|
13313
|
-
|
|
13314
|
-
|
|
12673
|
+
log3(yellow2("No policies found. Create one in the dashboard first."));
|
|
12674
|
+
log3(dim2(" https://dashboard.solongate.com/policies"));
|
|
13315
12675
|
return;
|
|
13316
12676
|
}
|
|
13317
12677
|
if (policyId) {
|
|
13318
12678
|
const match = policies.find((p) => p.id === policyId);
|
|
13319
12679
|
if (!match) {
|
|
13320
|
-
|
|
13321
|
-
|
|
13322
|
-
|
|
12680
|
+
log3(red2(`Policy not found: ${policyId}`));
|
|
12681
|
+
log3("");
|
|
12682
|
+
log3("Available policies:");
|
|
13323
12683
|
for (const p of policies) {
|
|
13324
|
-
|
|
12684
|
+
log3(` ${dim2("\u2022")} ${p.id}`);
|
|
13325
12685
|
}
|
|
13326
12686
|
process.exit(1);
|
|
13327
12687
|
}
|
|
@@ -13329,10 +12689,10 @@ async function list5(apiKey, policyId) {
|
|
|
13329
12689
|
printPolicyDetail(full);
|
|
13330
12690
|
return;
|
|
13331
12691
|
}
|
|
13332
|
-
|
|
13333
|
-
|
|
13334
|
-
|
|
13335
|
-
|
|
12692
|
+
log3("");
|
|
12693
|
+
log3(bold2(` Policies (${policies.length})`));
|
|
12694
|
+
log3(dim2(" \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"));
|
|
12695
|
+
log3("");
|
|
13336
12696
|
const fullPolicies = await Promise.all(
|
|
13337
12697
|
policies.map(
|
|
13338
12698
|
(p) => fetchCloudPolicy(apiKey, API_URL, p.id).then((full) => ({ policy: p, rules: full.rules })).catch(() => ({ policy: p, rules: [] }))
|
|
@@ -13341,136 +12701,136 @@ async function list5(apiKey, policyId) {
|
|
|
13341
12701
|
for (const { policy, rules } of fullPolicies) {
|
|
13342
12702
|
printPolicySummary(policy, [...rules]);
|
|
13343
12703
|
}
|
|
13344
|
-
|
|
13345
|
-
|
|
13346
|
-
|
|
13347
|
-
|
|
13348
|
-
|
|
13349
|
-
|
|
12704
|
+
log3(dim2(" \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"));
|
|
12705
|
+
log3("");
|
|
12706
|
+
log3(` ${dim2("View details:")} solongate-proxy list --policy-id <ID>`);
|
|
12707
|
+
log3(` ${dim2("Pull policy:")} solongate-proxy pull --policy-id <ID>`);
|
|
12708
|
+
log3(` ${dim2("Push policy:")} solongate-proxy push --policy-id <ID>`);
|
|
12709
|
+
log3("");
|
|
13350
12710
|
}
|
|
13351
12711
|
function printPolicySummary(p, rules) {
|
|
13352
12712
|
const ruleCount = rules.length;
|
|
13353
12713
|
const allowCount = rules.filter((r) => r.effect === "ALLOW").length;
|
|
13354
12714
|
const denyCount = rules.filter((r) => r.effect === "DENY").length;
|
|
13355
|
-
|
|
13356
|
-
|
|
13357
|
-
|
|
12715
|
+
log3(` ${cyan2(p.id)}`);
|
|
12716
|
+
log3(` ${bold2(p.name)} ${dim2(`v${p.version ?? "?"}`)}`);
|
|
12717
|
+
log3(` ${dim2("Rules:")} ${ruleCount} ${green2(`${allowCount} ALLOW`)} ${red2(`${denyCount} DENY`)}`);
|
|
13358
12718
|
if (p.created_at) {
|
|
13359
|
-
|
|
12719
|
+
log3(` ${dim2("Updated:")} ${new Date(p.created_at).toLocaleString()}`);
|
|
13360
12720
|
}
|
|
13361
|
-
|
|
12721
|
+
log3("");
|
|
13362
12722
|
}
|
|
13363
12723
|
function printPolicyDetail(policy) {
|
|
13364
|
-
|
|
13365
|
-
|
|
13366
|
-
|
|
13367
|
-
|
|
12724
|
+
log3("");
|
|
12725
|
+
log3(bold2(` ${policy.name}`));
|
|
12726
|
+
log3(` ${dim2("ID:")} ${cyan2(policy.id)} ${dim2("Version:")} ${policy.version} ${dim2("Rules:")} ${policy.rules.length}`);
|
|
12727
|
+
log3("");
|
|
13368
12728
|
if (policy.rules.length === 0) {
|
|
13369
|
-
|
|
13370
|
-
|
|
12729
|
+
log3(yellow2(" No rules defined."));
|
|
12730
|
+
log3("");
|
|
13371
12731
|
return;
|
|
13372
12732
|
}
|
|
13373
|
-
|
|
12733
|
+
log3(dim2(" \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"));
|
|
13374
12734
|
for (const rule of policy.rules) {
|
|
13375
12735
|
const effectColor = rule.effect === "ALLOW" ? green2 : red2;
|
|
13376
|
-
|
|
13377
|
-
|
|
12736
|
+
log3("");
|
|
12737
|
+
log3(` ${effectColor(rule.effect.padEnd(5))} ${bold2(rule.toolPattern)} ${dim2(`P:${rule.priority}`)}`);
|
|
13378
12738
|
if (rule.description) {
|
|
13379
|
-
|
|
12739
|
+
log3(` ${dim2(rule.description)}`);
|
|
13380
12740
|
}
|
|
13381
|
-
|
|
12741
|
+
log3(` ${dim2(`${rule.permission} trust:${rule.minimumTrustLevel || "UNTRUSTED"}`)}`);
|
|
13382
12742
|
if (rule.pathConstraints) {
|
|
13383
12743
|
const pc = rule.pathConstraints;
|
|
13384
|
-
if (pc.rootDirectory)
|
|
13385
|
-
if (pc.allowed?.length)
|
|
13386
|
-
if (pc.denied?.length)
|
|
12744
|
+
if (pc.rootDirectory) log3(` ${magenta("ROOT")} ${pc.rootDirectory}`);
|
|
12745
|
+
if (pc.allowed?.length) log3(` ${green2("PATHS")} ${pc.allowed.join(", ")}`);
|
|
12746
|
+
if (pc.denied?.length) log3(` ${red2("DENY")} ${pc.denied.join(", ")}`);
|
|
13387
12747
|
}
|
|
13388
12748
|
if (rule.commandConstraints) {
|
|
13389
12749
|
const cc = rule.commandConstraints;
|
|
13390
|
-
if (cc.allowed?.length)
|
|
13391
|
-
if (cc.denied?.length)
|
|
12750
|
+
if (cc.allowed?.length) log3(` ${green2("CMDS")} ${cc.allowed.join(", ")}`);
|
|
12751
|
+
if (cc.denied?.length) log3(` ${red2("DENY")} ${cc.denied.join(", ")}`);
|
|
13392
12752
|
}
|
|
13393
12753
|
if (rule.filenameConstraints) {
|
|
13394
12754
|
const fc = rule.filenameConstraints;
|
|
13395
|
-
if (fc.allowed?.length)
|
|
13396
|
-
if (fc.denied?.length)
|
|
12755
|
+
if (fc.allowed?.length) log3(` ${green2("FILES")} ${fc.allowed.join(", ")}`);
|
|
12756
|
+
if (fc.denied?.length) log3(` ${red2("DENY")} ${fc.denied.join(", ")}`);
|
|
13397
12757
|
}
|
|
13398
12758
|
if (rule.urlConstraints) {
|
|
13399
12759
|
const uc = rule.urlConstraints;
|
|
13400
|
-
if (uc.allowed?.length)
|
|
13401
|
-
if (uc.denied?.length)
|
|
12760
|
+
if (uc.allowed?.length) log3(` ${green2("URLS")} ${uc.allowed.join(", ")}`);
|
|
12761
|
+
if (uc.denied?.length) log3(` ${red2("DENY")} ${uc.denied.join(", ")}`);
|
|
13402
12762
|
}
|
|
13403
12763
|
}
|
|
13404
|
-
|
|
13405
|
-
|
|
13406
|
-
|
|
12764
|
+
log3("");
|
|
12765
|
+
log3(dim2(" \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"));
|
|
12766
|
+
log3("");
|
|
13407
12767
|
}
|
|
13408
12768
|
async function pull(apiKey, file, policyId) {
|
|
13409
12769
|
if (!policyId) {
|
|
13410
12770
|
const policies = await listPolicies(apiKey);
|
|
13411
12771
|
if (policies.length === 0) {
|
|
13412
|
-
|
|
12772
|
+
log3(red2("No policies found. Create one in the dashboard first."));
|
|
13413
12773
|
process.exit(1);
|
|
13414
12774
|
}
|
|
13415
12775
|
if (policies.length === 1) {
|
|
13416
12776
|
policyId = policies[0].id;
|
|
13417
|
-
|
|
12777
|
+
log3(dim2(`Auto-selecting only policy: ${policyId}`));
|
|
13418
12778
|
} else {
|
|
13419
|
-
|
|
13420
|
-
|
|
12779
|
+
log3(yellow2(`Found ${policies.length} policies:`));
|
|
12780
|
+
log3("");
|
|
13421
12781
|
for (const p of policies) {
|
|
13422
|
-
|
|
12782
|
+
log3(` ${cyan2(p.id)} ${p.name} ${dim2(`v${p.version ?? "?"}`)}`);
|
|
13423
12783
|
}
|
|
13424
|
-
|
|
13425
|
-
|
|
12784
|
+
log3("");
|
|
12785
|
+
log3("Use --policy-id <ID> to specify which one to pull.");
|
|
13426
12786
|
process.exit(1);
|
|
13427
12787
|
}
|
|
13428
12788
|
}
|
|
13429
|
-
|
|
12789
|
+
log3(`Pulling ${cyan2(policyId)} from dashboard...`);
|
|
13430
12790
|
const policy = await fetchCloudPolicy(apiKey, API_URL, policyId);
|
|
13431
12791
|
const { id: _id, ...policyWithoutId } = policy;
|
|
13432
12792
|
const json = JSON.stringify(policyWithoutId, null, 2) + "\n";
|
|
13433
|
-
|
|
13434
|
-
|
|
13435
|
-
|
|
13436
|
-
|
|
13437
|
-
|
|
13438
|
-
|
|
13439
|
-
|
|
13440
|
-
|
|
13441
|
-
|
|
13442
|
-
|
|
12793
|
+
writeFileSync10(file, json, "utf-8");
|
|
12794
|
+
log3("");
|
|
12795
|
+
log3(green2(" Saved to: ") + file);
|
|
12796
|
+
log3(` ${dim2("Name:")} ${policy.name}`);
|
|
12797
|
+
log3(` ${dim2("Version:")} ${policy.version}`);
|
|
12798
|
+
log3(` ${dim2("Rules:")} ${policy.rules.length}`);
|
|
12799
|
+
log3("");
|
|
12800
|
+
log3(dim2("The policy file does not contain an ID."));
|
|
12801
|
+
log3(dim2("Use --policy-id to specify the target when pushing/pulling."));
|
|
12802
|
+
log3("");
|
|
13443
12803
|
}
|
|
13444
12804
|
async function push(apiKey, file, policyId) {
|
|
13445
|
-
if (!
|
|
13446
|
-
|
|
12805
|
+
if (!existsSync7(file)) {
|
|
12806
|
+
log3(red2(`ERROR: File not found: ${file}`));
|
|
13447
12807
|
process.exit(1);
|
|
13448
12808
|
}
|
|
13449
12809
|
if (!policyId) {
|
|
13450
|
-
|
|
13451
|
-
|
|
13452
|
-
|
|
13453
|
-
|
|
13454
|
-
|
|
13455
|
-
|
|
13456
|
-
|
|
13457
|
-
|
|
13458
|
-
|
|
13459
|
-
|
|
12810
|
+
log3(red2("ERROR: --policy-id is required for push."));
|
|
12811
|
+
log3("");
|
|
12812
|
+
log3("This determines which cloud policy to update.");
|
|
12813
|
+
log3("");
|
|
12814
|
+
log3("Usage:");
|
|
12815
|
+
log3(" solongate-proxy push --policy-id my-policy");
|
|
12816
|
+
log3(" solongate-proxy push --policy-id my-policy --file custom.json");
|
|
12817
|
+
log3("");
|
|
12818
|
+
log3("List your policies:");
|
|
12819
|
+
log3(" solongate-proxy list");
|
|
13460
12820
|
process.exit(1);
|
|
13461
12821
|
}
|
|
13462
|
-
const content =
|
|
12822
|
+
const content = readFileSync12(file, "utf-8");
|
|
13463
12823
|
let policy;
|
|
13464
12824
|
try {
|
|
13465
12825
|
policy = JSON.parse(content);
|
|
13466
12826
|
} catch {
|
|
13467
|
-
|
|
12827
|
+
log3(red2(`ERROR: Invalid JSON in ${file}`));
|
|
13468
12828
|
process.exit(1);
|
|
13469
12829
|
}
|
|
13470
|
-
|
|
13471
|
-
|
|
13472
|
-
|
|
13473
|
-
|
|
12830
|
+
log3(`Pushing to ${cyan2(policyId)}...`);
|
|
12831
|
+
log3(` ${dim2("File:")} ${file}`);
|
|
12832
|
+
log3(` ${dim2("Name:")} ${policy.name || "Unnamed"}`);
|
|
12833
|
+
log3(` ${dim2("Rules:")} ${(policy.rules || []).length}`);
|
|
13474
12834
|
const checkRes = await fetch(`${API_URL}/api/v1/policies/${policyId}`, {
|
|
13475
12835
|
headers: { "Authorization": `Bearer ${apiKey}` }
|
|
13476
12836
|
});
|
|
@@ -13492,17 +12852,17 @@ async function push(apiKey, file, policyId) {
|
|
|
13492
12852
|
});
|
|
13493
12853
|
if (!res.ok) {
|
|
13494
12854
|
const body = await res.text().catch(() => "");
|
|
13495
|
-
|
|
12855
|
+
log3(red2(`ERROR: Push failed (${res.status}): ${body}`));
|
|
13496
12856
|
process.exit(1);
|
|
13497
12857
|
}
|
|
13498
12858
|
const data = await res.json();
|
|
13499
|
-
|
|
13500
|
-
|
|
13501
|
-
|
|
13502
|
-
|
|
13503
|
-
|
|
12859
|
+
log3("");
|
|
12860
|
+
log3(green2(` Pushed to cloud: v${data._version ?? "created"}`));
|
|
12861
|
+
log3(` ${dim2("Policy ID:")} ${policyId}`);
|
|
12862
|
+
log3(` ${dim2("Method:")} ${method === "PUT" ? "Updated existing" : "Created new"}`);
|
|
12863
|
+
log3("");
|
|
13504
12864
|
}
|
|
13505
|
-
async function
|
|
12865
|
+
async function main() {
|
|
13506
12866
|
const { command, apiKey, file, policyId } = parseCliArgs();
|
|
13507
12867
|
try {
|
|
13508
12868
|
if (command === "pull") {
|
|
@@ -13512,32 +12872,32 @@ async function main3() {
|
|
|
13512
12872
|
} else if (command === "list" || command === "ls") {
|
|
13513
12873
|
await list5(apiKey, policyId);
|
|
13514
12874
|
} else {
|
|
13515
|
-
|
|
13516
|
-
|
|
13517
|
-
|
|
13518
|
-
|
|
13519
|
-
|
|
13520
|
-
|
|
13521
|
-
|
|
13522
|
-
|
|
13523
|
-
|
|
13524
|
-
|
|
13525
|
-
|
|
13526
|
-
|
|
13527
|
-
|
|
12875
|
+
log3(red2(`Unknown command: ${command}`));
|
|
12876
|
+
log3("");
|
|
12877
|
+
log3(bold2("Usage:"));
|
|
12878
|
+
log3(" solongate-proxy list List all policies");
|
|
12879
|
+
log3(" solongate-proxy list --policy-id <ID> Show policy details");
|
|
12880
|
+
log3(" solongate-proxy pull --policy-id <ID> Pull policy to local file");
|
|
12881
|
+
log3(" solongate-proxy push --policy-id <ID> Push local file to cloud");
|
|
12882
|
+
log3("");
|
|
12883
|
+
log3(bold2("Flags:"));
|
|
12884
|
+
log3(" --policy-id, --id <ID> Cloud policy ID (required for push)");
|
|
12885
|
+
log3(" --file, -f <path> Local file path (default: policy.json)");
|
|
12886
|
+
log3(" --api-key <key> API key (or set SOLONGATE_API_KEY)");
|
|
12887
|
+
log3("");
|
|
13528
12888
|
process.exit(1);
|
|
13529
12889
|
}
|
|
13530
12890
|
} catch (err2) {
|
|
13531
|
-
|
|
12891
|
+
log3(red2(`ERROR: ${err2 instanceof Error ? err2.message : String(err2)}`));
|
|
13532
12892
|
process.exit(1);
|
|
13533
12893
|
}
|
|
13534
12894
|
}
|
|
13535
|
-
var
|
|
12895
|
+
var log3, dim2, bold2, green2, red2, yellow2, cyan2, magenta, API_URL;
|
|
13536
12896
|
var init_pull_push = __esm({
|
|
13537
12897
|
"src/pull-push.ts"() {
|
|
13538
12898
|
"use strict";
|
|
13539
12899
|
init_config();
|
|
13540
|
-
|
|
12900
|
+
log3 = (...args) => process.stderr.write(`${args.map(String).join(" ")}
|
|
13541
12901
|
`);
|
|
13542
12902
|
dim2 = (s) => `\x1B[2m${s}\x1B[0m`;
|
|
13543
12903
|
bold2 = (s) => `\x1B[1m${s}\x1B[0m`;
|
|
@@ -13547,15 +12907,15 @@ var init_pull_push = __esm({
|
|
|
13547
12907
|
cyan2 = (s) => `\x1B[36m${s}\x1B[0m`;
|
|
13548
12908
|
magenta = (s) => `\x1B[35m${s}\x1B[0m`;
|
|
13549
12909
|
API_URL = "https://api.solongate.com";
|
|
13550
|
-
|
|
12910
|
+
main();
|
|
13551
12911
|
}
|
|
13552
12912
|
});
|
|
13553
12913
|
|
|
13554
12914
|
// src/index.ts
|
|
13555
12915
|
init_config();
|
|
13556
|
-
import { readFileSync as
|
|
12916
|
+
import { readFileSync as readFileSync13 } from "fs";
|
|
13557
12917
|
import { fileURLToPath as fileURLToPath4 } from "url";
|
|
13558
|
-
import { dirname as dirname4, join as
|
|
12918
|
+
import { dirname as dirname4, join as join16 } from "path";
|
|
13559
12919
|
|
|
13560
12920
|
// src/proxy.ts
|
|
13561
12921
|
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
|
|
@@ -15979,7 +15339,7 @@ var Mutex = class {
|
|
|
15979
15339
|
this.locked = true;
|
|
15980
15340
|
return;
|
|
15981
15341
|
}
|
|
15982
|
-
return new Promise((
|
|
15342
|
+
return new Promise((resolve7, reject) => {
|
|
15983
15343
|
const timer = setTimeout(() => {
|
|
15984
15344
|
const idx = this.queue.indexOf(onReady);
|
|
15985
15345
|
if (idx !== -1) this.queue.splice(idx, 1);
|
|
@@ -15987,7 +15347,7 @@ var Mutex = class {
|
|
|
15987
15347
|
}, timeoutMs);
|
|
15988
15348
|
const onReady = () => {
|
|
15989
15349
|
clearTimeout(timer);
|
|
15990
|
-
|
|
15350
|
+
resolve7();
|
|
15991
15351
|
};
|
|
15992
15352
|
this.queue.push(onReady);
|
|
15993
15353
|
});
|
|
@@ -16578,7 +15938,7 @@ ${msg.content.text}`;
|
|
|
16578
15938
|
|
|
16579
15939
|
// src/index.ts
|
|
16580
15940
|
init_cli_utils();
|
|
16581
|
-
var CLI_SUBCOMMANDS = /* @__PURE__ */ new Set(["
|
|
15941
|
+
var CLI_SUBCOMMANDS = /* @__PURE__ */ new Set(["pull", "push", "list", "ls", "logs-server", "local-logs", "policy", "ratelimit", "dlp", "stats", "audit", "agents", "agent", "doctor", "watch", "alerts", "webhooks", "dataroom"]);
|
|
16582
15942
|
var CLI_INFO_ARGS = /* @__PURE__ */ new Set(["login", "help", "--help", "-h", "--version", "-v", "version"]);
|
|
16583
15943
|
var IS_HUMAN_CLI = process.argv.length <= 2 || CLI_SUBCOMMANDS.has(process.argv[2] ?? "") || CLI_INFO_ARGS.has(process.argv[2] ?? "");
|
|
16584
15944
|
if (!IS_HUMAN_CLI) {
|
|
@@ -16597,8 +15957,8 @@ if (!IS_HUMAN_CLI) {
|
|
|
16597
15957
|
}
|
|
16598
15958
|
var PKG_VERSION = (() => {
|
|
16599
15959
|
try {
|
|
16600
|
-
const p =
|
|
16601
|
-
return JSON.parse(
|
|
15960
|
+
const p = join16(dirname4(fileURLToPath4(import.meta.url)), "..", "package.json");
|
|
15961
|
+
return JSON.parse(readFileSync13(p, "utf-8")).version || "unknown";
|
|
16602
15962
|
} catch {
|
|
16603
15963
|
return "unknown";
|
|
16604
15964
|
}
|
|
@@ -16617,7 +15977,7 @@ function printWelcome() {
|
|
|
16617
15977
|
console.log(` ${c.dim}Manage it at ${c.reset}${c.cyan}https://dashboard.solongate.com${c.reset}`);
|
|
16618
15978
|
console.log("");
|
|
16619
15979
|
}
|
|
16620
|
-
function
|
|
15980
|
+
function printHelp() {
|
|
16621
15981
|
const W = 46;
|
|
16622
15982
|
const head = (t) => console.log(`
|
|
16623
15983
|
${c.bold}${t}${c.reset}`);
|
|
@@ -16640,7 +16000,6 @@ function printHelp3() {
|
|
|
16640
16000
|
head("Setup & status");
|
|
16641
16001
|
cmd("solongate", "open the dataroom UI (login, policies, audit, settings)");
|
|
16642
16002
|
cmd("doctor [--json]", "health check: login, policy, guard, local logs");
|
|
16643
|
-
cmd("create", "scaffold a guarded MCP server in this folder");
|
|
16644
16003
|
cmd("logs-server", "serve local audit logs to the dashboard");
|
|
16645
16004
|
head("Policies");
|
|
16646
16005
|
cmd("policy list", "list all policies");
|
|
@@ -16687,10 +16046,10 @@ function printHelp3() {
|
|
|
16687
16046
|
console.log(` ${c.dim}Details for a command: ${c.reset}${c.cyan}solongate <command> help${c.reset}${c.dim} \xB7 Dashboard: ${c.reset}${c.cyan}https://dashboard.solongate.com${c.reset}`);
|
|
16688
16047
|
console.log("");
|
|
16689
16048
|
}
|
|
16690
|
-
async function
|
|
16049
|
+
async function main2() {
|
|
16691
16050
|
const subcommand = process.argv[2];
|
|
16692
16051
|
if (subcommand === "--help" || subcommand === "-h" || subcommand === "help") {
|
|
16693
|
-
|
|
16052
|
+
printHelp();
|
|
16694
16053
|
return;
|
|
16695
16054
|
}
|
|
16696
16055
|
if (subcommand === "--version" || subcommand === "-v" || subcommand === "version") {
|
|
@@ -16740,16 +16099,6 @@ async function main4() {
|
|
|
16740
16099
|
await runLogsServer2();
|
|
16741
16100
|
return;
|
|
16742
16101
|
}
|
|
16743
|
-
if (subcommand === "inject") {
|
|
16744
|
-
process.argv.splice(2, 1);
|
|
16745
|
-
await Promise.resolve().then(() => (init_inject(), inject_exports));
|
|
16746
|
-
return;
|
|
16747
|
-
}
|
|
16748
|
-
if (subcommand === "create") {
|
|
16749
|
-
process.argv.splice(2, 1);
|
|
16750
|
-
await Promise.resolve().then(() => (init_create(), create_exports));
|
|
16751
|
-
return;
|
|
16752
|
-
}
|
|
16753
16102
|
if (subcommand === "pull" || subcommand === "push" || subcommand === "list" || subcommand === "ls") {
|
|
16754
16103
|
await Promise.resolve().then(() => (init_pull_push(), pull_push_exports));
|
|
16755
16104
|
return;
|
|
@@ -16776,4 +16125,4 @@ async function main4() {
|
|
|
16776
16125
|
process.exit(1);
|
|
16777
16126
|
}
|
|
16778
16127
|
}
|
|
16779
|
-
|
|
16128
|
+
main2();
|