@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/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@solongate/proxy",
|
|
3
|
-
"version": "0.82.
|
|
3
|
+
"version": "0.82.22",
|
|
4
4
|
"description": "AI tool security proxy: protect any AI tool server with customizable policies, path/command constraints, rate limiting, and audit logging. No code changes required.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
package/dist/create.d.ts
DELETED
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
/**
|
|
3
|
-
* solongate create — Scaffold a new MCP server project with SolonGate protection built in.
|
|
4
|
-
*
|
|
5
|
-
* Usage:
|
|
6
|
-
* npx @solongate/proxy create <name> [options]
|
|
7
|
-
*
|
|
8
|
-
* Options:
|
|
9
|
-
* --policy <file> Policy JSON file (default: cloud-managed)
|
|
10
|
-
* --no-install Skip dependency installation
|
|
11
|
-
* -h, --help Show help
|
|
12
|
-
*/
|
|
13
|
-
export {};
|
package/dist/create.js
DELETED
|
@@ -1,329 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
// src/create.ts
|
|
4
|
-
import { mkdirSync, writeFileSync, existsSync } from "fs";
|
|
5
|
-
import { resolve, join } from "path";
|
|
6
|
-
import { execSync } from "child_process";
|
|
7
|
-
|
|
8
|
-
// src/cli-utils.ts
|
|
9
|
-
var c = {
|
|
10
|
-
reset: "\x1B[0m",
|
|
11
|
-
bold: "\x1B[1m",
|
|
12
|
-
dim: "\x1B[2m",
|
|
13
|
-
italic: "\x1B[3m",
|
|
14
|
-
white: "\x1B[97m",
|
|
15
|
-
gray: "\x1B[90m",
|
|
16
|
-
blue1: "\x1B[38;2;20;50;160m",
|
|
17
|
-
blue2: "\x1B[38;2;40;80;190m",
|
|
18
|
-
blue3: "\x1B[38;2;60;110;215m",
|
|
19
|
-
blue4: "\x1B[38;2;90;140;230m",
|
|
20
|
-
blue5: "\x1B[38;2;130;170;240m",
|
|
21
|
-
blue6: "\x1B[38;2;170;200;250m",
|
|
22
|
-
green: "\x1B[38;2;80;200;120m",
|
|
23
|
-
red: "\x1B[38;2;220;80;80m",
|
|
24
|
-
cyan: "\x1B[38;2;100;200;220m",
|
|
25
|
-
yellow: "\x1B[38;2;220;200;80m",
|
|
26
|
-
bgBlue: "\x1B[48;2;20;50;160m"
|
|
27
|
-
};
|
|
28
|
-
function log(msg) {
|
|
29
|
-
process.stderr.write(msg + "\n");
|
|
30
|
-
}
|
|
31
|
-
var BANNER_FULL = [
|
|
32
|
-
" \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2557 \u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557",
|
|
33
|
-
" \u2588\u2588\u2554\u2550\u2550\u2550\u2550\u255D\u2588\u2588\u2554\u2550\u2550\u2550\u2588\u2588\u2557\u2588\u2588\u2551 \u2588\u2588\u2554\u2550\u2550\u2550\u2588\u2588\u2557\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2551\u2588\u2588\u2554\u2550\u2550\u2550\u2550\u255D \u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2557\u255A\u2550\u2550\u2588\u2588\u2554\u2550\u2550\u255D\u2588\u2588\u2554\u2550\u2550\u2550\u2550\u255D",
|
|
34
|
-
" \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2554\u2588\u2588\u2557 \u2588\u2588\u2551\u2588\u2588\u2551 \u2588\u2588\u2588\u2557\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588\u2588\u2588\u2588\u2557 ",
|
|
35
|
-
" \u255A\u2550\u2550\u2550\u2550\u2588\u2588\u2551\u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2551\u255A\u2588\u2588\u2557\u2588\u2588\u2551\u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588\u2554\u2550\u2550\u255D ",
|
|
36
|
-
" \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2551\u255A\u2588\u2588\u2588\u2588\u2588\u2588\u2554\u255D\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u255A\u2588\u2588\u2588\u2588\u2588\u2588\u2554\u255D\u2588\u2588\u2551 \u255A\u2588\u2588\u2588\u2588\u2551\u255A\u2588\u2588\u2588\u2588\u2588\u2588\u2554\u255D\u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557",
|
|
37
|
-
" \u255A\u2550\u2550\u2550\u2550\u2550\u2550\u255D \u255A\u2550\u2550\u2550\u2550\u2550\u255D \u255A\u2550\u2550\u2550\u2550\u2550\u2550\u255D \u255A\u2550\u2550\u2550\u2550\u2550\u255D \u255A\u2550\u255D \u255A\u2550\u2550\u2550\u255D \u255A\u2550\u2550\u2550\u2550\u2550\u255D \u255A\u2550\u255D \u255A\u2550\u255D \u255A\u2550\u255D \u255A\u2550\u2550\u2550\u2550\u2550\u2550\u255D"
|
|
38
|
-
];
|
|
39
|
-
var BANNER_COLORS = [c.blue1, c.blue2, c.blue3, c.blue4, c.blue5, c.blue6];
|
|
40
|
-
function printBanner(subtitle) {
|
|
41
|
-
log("");
|
|
42
|
-
for (let i = 0; i < BANNER_FULL.length; i++) {
|
|
43
|
-
log(`${c.bold}${BANNER_COLORS[i]}${BANNER_FULL[i]}${c.reset}`);
|
|
44
|
-
}
|
|
45
|
-
log("");
|
|
46
|
-
log(` ${c.dim}${c.italic}${subtitle}${c.reset}`);
|
|
47
|
-
log("");
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
// src/create.ts
|
|
51
|
-
function withSpinner(message, fn) {
|
|
52
|
-
const frames = ["\u28FE", "\u28FD", "\u28FB", "\u28BF", "\u287F", "\u28DF", "\u28EF", "\u28F7"];
|
|
53
|
-
let i = 0;
|
|
54
|
-
const id = setInterval(() => {
|
|
55
|
-
const color = i % 2 === 0 ? c.blue3 : c.blue5;
|
|
56
|
-
process.stderr.write(`\r ${color}${frames[i++ % frames.length]}${c.reset} ${c.dim}${message}${c.reset}`);
|
|
57
|
-
}, 80);
|
|
58
|
-
try {
|
|
59
|
-
const result = fn();
|
|
60
|
-
clearInterval(id);
|
|
61
|
-
process.stderr.write(`\r ${c.green}\u2713${c.reset} ${message}${" ".repeat(20)}
|
|
62
|
-
`);
|
|
63
|
-
return result;
|
|
64
|
-
} catch (err) {
|
|
65
|
-
clearInterval(id);
|
|
66
|
-
process.stderr.write(`\r ${c.red}\u2717${c.reset} ${message} \u2014 failed${" ".repeat(10)}
|
|
67
|
-
`);
|
|
68
|
-
throw err;
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
function parseCreateArgs(argv) {
|
|
72
|
-
const args = argv.slice(2);
|
|
73
|
-
const opts = {
|
|
74
|
-
name: "",
|
|
75
|
-
policy: "",
|
|
76
|
-
noInstall: false
|
|
77
|
-
};
|
|
78
|
-
for (let i = 0; i < args.length; i++) {
|
|
79
|
-
switch (args[i]) {
|
|
80
|
-
case "--policy":
|
|
81
|
-
opts.policy = args[++i];
|
|
82
|
-
break;
|
|
83
|
-
case "--no-install":
|
|
84
|
-
opts.noInstall = true;
|
|
85
|
-
break;
|
|
86
|
-
case "--help":
|
|
87
|
-
case "-h":
|
|
88
|
-
printHelp();
|
|
89
|
-
process.exit(0);
|
|
90
|
-
break;
|
|
91
|
-
default:
|
|
92
|
-
if (!args[i].startsWith("-") && !opts.name) {
|
|
93
|
-
opts.name = args[i];
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
if (!opts.name) {
|
|
98
|
-
log("");
|
|
99
|
-
log(" Error: Project name required.");
|
|
100
|
-
log("");
|
|
101
|
-
log(" Usage: npx @solongate/proxy create <name>");
|
|
102
|
-
log("");
|
|
103
|
-
log(" Examples:");
|
|
104
|
-
log(" npx @solongate/proxy create my-mcp-server");
|
|
105
|
-
log(" npx @solongate/proxy create weather-api");
|
|
106
|
-
process.exit(1);
|
|
107
|
-
}
|
|
108
|
-
return opts;
|
|
109
|
-
}
|
|
110
|
-
function printHelp() {
|
|
111
|
-
log(`
|
|
112
|
-
SolonGate Create \u2014 Scaffold a secure MCP server in seconds
|
|
113
|
-
|
|
114
|
-
USAGE
|
|
115
|
-
npx @solongate/proxy create <name> [options]
|
|
116
|
-
|
|
117
|
-
OPTIONS
|
|
118
|
-
--policy <file> Policy JSON file (default: cloud-managed)
|
|
119
|
-
--no-install Skip dependency installation
|
|
120
|
-
-h, --help Show this help message
|
|
121
|
-
|
|
122
|
-
EXAMPLES
|
|
123
|
-
npx @solongate/proxy create my-server
|
|
124
|
-
npx @solongate/proxy create db-tools --policy ./policy.json
|
|
125
|
-
`);
|
|
126
|
-
}
|
|
127
|
-
function createProject(dir, name, _policy) {
|
|
128
|
-
writeFileSync(
|
|
129
|
-
join(dir, "package.json"),
|
|
130
|
-
JSON.stringify(
|
|
131
|
-
{
|
|
132
|
-
name,
|
|
133
|
-
version: "0.1.0",
|
|
134
|
-
type: "module",
|
|
135
|
-
private: true,
|
|
136
|
-
bin: { [name]: "./dist/index.js" },
|
|
137
|
-
scripts: {
|
|
138
|
-
build: "tsup src/index.ts --format esm",
|
|
139
|
-
dev: "tsx --env-file=.env src/index.ts",
|
|
140
|
-
start: "node --env-file=.env dist/index.js"
|
|
141
|
-
},
|
|
142
|
-
dependencies: {
|
|
143
|
-
"@modelcontextprotocol/sdk": "^1.26.0",
|
|
144
|
-
"@solongate/proxy": "latest",
|
|
145
|
-
zod: "^3.25.0"
|
|
146
|
-
},
|
|
147
|
-
devDependencies: {
|
|
148
|
-
"@types/node": "^22.0.0",
|
|
149
|
-
tsup: "^8.3.0",
|
|
150
|
-
tsx: "^4.19.0",
|
|
151
|
-
typescript: "^5.7.0"
|
|
152
|
-
}
|
|
153
|
-
},
|
|
154
|
-
null,
|
|
155
|
-
2
|
|
156
|
-
) + "\n"
|
|
157
|
-
);
|
|
158
|
-
writeFileSync(
|
|
159
|
-
join(dir, "tsconfig.json"),
|
|
160
|
-
JSON.stringify(
|
|
161
|
-
{
|
|
162
|
-
compilerOptions: {
|
|
163
|
-
target: "ES2022",
|
|
164
|
-
module: "ESNext",
|
|
165
|
-
moduleResolution: "bundler",
|
|
166
|
-
esModuleInterop: true,
|
|
167
|
-
strict: true,
|
|
168
|
-
outDir: "dist",
|
|
169
|
-
rootDir: "src",
|
|
170
|
-
declaration: true,
|
|
171
|
-
skipLibCheck: true
|
|
172
|
-
},
|
|
173
|
-
include: ["src"]
|
|
174
|
-
},
|
|
175
|
-
null,
|
|
176
|
-
2
|
|
177
|
-
) + "\n"
|
|
178
|
-
);
|
|
179
|
-
mkdirSync(join(dir, "src"), { recursive: true });
|
|
180
|
-
writeFileSync(
|
|
181
|
-
join(dir, "src", "index.ts"),
|
|
182
|
-
`#!/usr/bin/env node
|
|
183
|
-
|
|
184
|
-
console.log = (...args: unknown[]) => {
|
|
185
|
-
process.stderr.write(args.map(String).join(' ') + '\\n');
|
|
186
|
-
};
|
|
187
|
-
|
|
188
|
-
import { SecureMcpServer } from '@solongate/proxy';
|
|
189
|
-
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
|
|
190
|
-
import { z } from 'zod';
|
|
191
|
-
|
|
192
|
-
// Policy is managed from the SolonGate Dashboard (https://solongate.com)
|
|
193
|
-
// No local policySet needed \u2014 it's fetched from the cloud via your API key.
|
|
194
|
-
const server = new SecureMcpServer(
|
|
195
|
-
{ name: '${name}', version: '0.1.0' },
|
|
196
|
-
);
|
|
197
|
-
|
|
198
|
-
server.tool(
|
|
199
|
-
'hello',
|
|
200
|
-
'Say hello to someone',
|
|
201
|
-
{ name: z.string().describe('Name of the person to greet') },
|
|
202
|
-
async ({ name }: { name: string }) => ({
|
|
203
|
-
content: [{ type: 'text', text: \`Hello, \${name}! Welcome to ${name}.\` }],
|
|
204
|
-
}),
|
|
205
|
-
);
|
|
206
|
-
|
|
207
|
-
const transport = new StdioServerTransport();
|
|
208
|
-
await server.connect(transport);
|
|
209
|
-
console.log('');
|
|
210
|
-
console.log('${name} is running (stdio mode)');
|
|
211
|
-
console.log('');
|
|
212
|
-
console.log('MCP servers communicate over stdin/stdout \u2014 not HTTP.');
|
|
213
|
-
console.log('You need an MCP client to connect:');
|
|
214
|
-
console.log('');
|
|
215
|
-
console.log(' Claude Code Open this folder, .mcp.json is auto-detected');
|
|
216
|
-
console.log(' Antigravity .agents/mcp_config.json (or ~/.gemini/config/mcp_config.json)');
|
|
217
|
-
console.log(' OpenClaw Uses openclaw.plugin.json config');
|
|
218
|
-
console.log('');
|
|
219
|
-
console.log('Press Ctrl+C to stop.');
|
|
220
|
-
`
|
|
221
|
-
);
|
|
222
|
-
writeFileSync(
|
|
223
|
-
join(dir, ".mcp.json"),
|
|
224
|
-
JSON.stringify(
|
|
225
|
-
{
|
|
226
|
-
mcpServers: {
|
|
227
|
-
[name]: {
|
|
228
|
-
command: "node",
|
|
229
|
-
args: ["dist/index.js"],
|
|
230
|
-
env: {
|
|
231
|
-
SOLONGATE_API_KEY: "sg_live_YOUR_KEY_HERE"
|
|
232
|
-
}
|
|
233
|
-
}
|
|
234
|
-
}
|
|
235
|
-
},
|
|
236
|
-
null,
|
|
237
|
-
2
|
|
238
|
-
) + "\n"
|
|
239
|
-
);
|
|
240
|
-
writeFileSync(
|
|
241
|
-
join(dir, ".env"),
|
|
242
|
-
`SOLONGATE_API_KEY=sg_live_YOUR_KEY_HERE
|
|
243
|
-
`
|
|
244
|
-
);
|
|
245
|
-
writeFileSync(
|
|
246
|
-
join(dir, ".gitignore"),
|
|
247
|
-
`node_modules/
|
|
248
|
-
dist/
|
|
249
|
-
*.solongate-backup
|
|
250
|
-
.env
|
|
251
|
-
.env.local
|
|
252
|
-
.mcp.json
|
|
253
|
-
`
|
|
254
|
-
);
|
|
255
|
-
}
|
|
256
|
-
async function main() {
|
|
257
|
-
const opts = parseCreateArgs(process.argv);
|
|
258
|
-
const dir = resolve(opts.name);
|
|
259
|
-
printBanner("Create MCP Server");
|
|
260
|
-
if (existsSync(dir)) {
|
|
261
|
-
log(` ${c.red}Error:${c.reset} Directory "${opts.name}" already exists.`);
|
|
262
|
-
process.exit(1);
|
|
263
|
-
}
|
|
264
|
-
withSpinner(`Setting up ${opts.name}...`, () => {
|
|
265
|
-
mkdirSync(dir, { recursive: true });
|
|
266
|
-
createProject(dir, opts.name, opts.policy);
|
|
267
|
-
});
|
|
268
|
-
if (!opts.noInstall) {
|
|
269
|
-
withSpinner("Installing dependencies...", () => {
|
|
270
|
-
execSync("npm install", { cwd: dir, stdio: "pipe" });
|
|
271
|
-
});
|
|
272
|
-
}
|
|
273
|
-
log("");
|
|
274
|
-
const stripAnsi = (s) => s.replace(/\x1b\[[0-9;]*m/g, "");
|
|
275
|
-
const W = 52;
|
|
276
|
-
const hr = "\u2500".repeat(W + 2);
|
|
277
|
-
const bLine = (text) => {
|
|
278
|
-
const visible = stripAnsi(text);
|
|
279
|
-
const padding = W - visible.length;
|
|
280
|
-
log(` ${c.dim}\u2502${c.reset} ${text}${" ".repeat(Math.max(0, padding))} ${c.dim}\u2502${c.reset}`);
|
|
281
|
-
};
|
|
282
|
-
const bEmpty = () => log(` ${c.dim}\u2502${c.reset} ${" ".repeat(W)} ${c.dim}\u2502${c.reset}`);
|
|
283
|
-
log(` ${c.dim}\u256D${hr}\u256E${c.reset}`);
|
|
284
|
-
log(` ${c.dim}\u2502${c.reset} ${c.green}${c.bold}\u2714 MCP Server created successfully!${c.reset}${" ".repeat(W - 35)} ${c.dim}\u2502${c.reset}`);
|
|
285
|
-
log(` ${c.dim}\u251C${hr}\u2524${c.reset}`);
|
|
286
|
-
bEmpty();
|
|
287
|
-
bLine(`${c.yellow}Next steps:${c.reset}`);
|
|
288
|
-
bEmpty();
|
|
289
|
-
bLine(` ${c.cyan}$${c.reset} cd ${c.bold}${opts.name}${c.reset}`);
|
|
290
|
-
bLine(` ${c.cyan}$${c.reset} npm run build`);
|
|
291
|
-
bLine(` ${c.cyan}$${c.reset} npm run dev ${c.dim}# dev mode${c.reset}`);
|
|
292
|
-
bLine(` ${c.cyan}$${c.reset} npm start ${c.dim}# production${c.reset}`);
|
|
293
|
-
bEmpty();
|
|
294
|
-
log(` ${c.dim}\u251C${hr}\u2524${c.reset}`);
|
|
295
|
-
bEmpty();
|
|
296
|
-
bLine(`${c.yellow}Set your API key:${c.reset}`);
|
|
297
|
-
bEmpty();
|
|
298
|
-
bLine(` ${c.cyan}$${c.reset} export SOLONGATE_API_KEY=${c.blue3}sg_live_xxx${c.reset}`);
|
|
299
|
-
bEmpty();
|
|
300
|
-
bLine(`${c.dim}https://dashboard.solongate.com/api-keys/${c.reset}`);
|
|
301
|
-
bEmpty();
|
|
302
|
-
log(` ${c.dim}\u251C${hr}\u2524${c.reset}`);
|
|
303
|
-
bEmpty();
|
|
304
|
-
bLine(`${c.yellow}Use with any MCP server:${c.reset}`);
|
|
305
|
-
bEmpty();
|
|
306
|
-
bLine(` ${c.cyan}$${c.reset} solongate-proxy -- npx @modelcontextprotocol/server-filesystem .`);
|
|
307
|
-
bLine(` ${c.cyan}$${c.reset} solongate-proxy -- npx @playwright/mcp@latest`);
|
|
308
|
-
bLine(` ${c.dim}Wraps any MCP server or AI tool with SolonGate protection${c.reset}`);
|
|
309
|
-
bEmpty();
|
|
310
|
-
log(` ${c.dim}\u251C${hr}\u2524${c.reset}`);
|
|
311
|
-
bEmpty();
|
|
312
|
-
bLine(`${c.yellow}Use with Claude Code / MCP client:${c.reset}`);
|
|
313
|
-
bEmpty();
|
|
314
|
-
bLine(` ${c.dim}1.${c.reset} Replace ${c.blue3}sg_live_YOUR_KEY_HERE${c.reset} in .mcp.json`);
|
|
315
|
-
bLine(` ${c.dim}2.${c.reset} Open this folder in your MCP client`);
|
|
316
|
-
bLine(` ${c.dim}3.${c.reset} .mcp.json is auto-detected on startup`);
|
|
317
|
-
bEmpty();
|
|
318
|
-
bLine(`${c.yellow}Direct test (without MCP client):${c.reset}`);
|
|
319
|
-
bEmpty();
|
|
320
|
-
bLine(` ${c.dim}1.${c.reset} Replace ${c.blue3}sg_live_YOUR_KEY_HERE${c.reset} in .env`);
|
|
321
|
-
bLine(` ${c.dim}2.${c.reset} ${c.cyan}$${c.reset} npm run build && npm start`);
|
|
322
|
-
bEmpty();
|
|
323
|
-
log(` ${c.dim}\u2570${hr}\u256F${c.reset}`);
|
|
324
|
-
log("");
|
|
325
|
-
}
|
|
326
|
-
main().catch((err) => {
|
|
327
|
-
log(`Fatal: ${err instanceof Error ? err.message : String(err)}`);
|
|
328
|
-
process.exit(1);
|
|
329
|
-
});
|
package/dist/inject.d.ts
DELETED
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
/**
|
|
3
|
-
* solongate inject — Auto-inject SolonGate SDK into an existing MCP server.
|
|
4
|
-
*
|
|
5
|
-
* Detects a TypeScript MCP server project, installs the SDK, and makes minimal
|
|
6
|
-
* source code changes to add SolonGate protection. Creates a backup so
|
|
7
|
-
* changes can be reverted with --restore.
|
|
8
|
-
*
|
|
9
|
-
* Usage:
|
|
10
|
-
* solongate-proxy inject [options]
|
|
11
|
-
*
|
|
12
|
-
* Options:
|
|
13
|
-
* --file <path> Entry file to modify (default: auto-detect)
|
|
14
|
-
* --dry-run Preview changes without writing
|
|
15
|
-
* --restore Restore from backup
|
|
16
|
-
* --skip-install Don't install SDK package
|
|
17
|
-
* -h, --help Show help
|
|
18
|
-
*/
|
|
19
|
-
export {};
|