@s-gw/s-gw 0.1.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 (123) hide show
  1. package/.codex-plugin/plugin.json +35 -0
  2. package/.mcp.json +16 -0
  3. package/LICENSE +201 -0
  4. package/NOTICE +7 -0
  5. package/README.md +197 -0
  6. package/TRADEMARKS.md +9 -0
  7. package/assets/icons/aws-ec2.png +0 -0
  8. package/assets/icons/lucide/bot.svg +8 -0
  9. package/assets/icons/lucide/monitor.svg +5 -0
  10. package/assets/icons/lucide/server.svg +6 -0
  11. package/assets/icons/lucide/terminal.svg +4 -0
  12. package/assets/icons/s-gw-128.png +0 -0
  13. package/assets/icons/s-gw-16.png +0 -0
  14. package/assets/icons/s-gw-180.png +0 -0
  15. package/assets/icons/s-gw-192.png +0 -0
  16. package/assets/icons/s-gw-32.png +0 -0
  17. package/assets/icons/s-gw-64.png +0 -0
  18. package/assets/icons/s-gw-menu-bar-template.png +0 -0
  19. package/dist/agent-context.d.ts +17 -0
  20. package/dist/agent-context.js +207 -0
  21. package/dist/agents.d.ts +64 -0
  22. package/dist/agents.js +763 -0
  23. package/dist/cli.d.ts +2 -0
  24. package/dist/cli.js +1385 -0
  25. package/dist/command-suggest.d.ts +3 -0
  26. package/dist/command-suggest.js +131 -0
  27. package/dist/console-server.d.ts +16 -0
  28. package/dist/console-server.js +978 -0
  29. package/dist/console-ui/assets/codex-DYTPdPxi.png +0 -0
  30. package/dist/console-ui/assets/cursor-CBrUTJD-.png +0 -0
  31. package/dist/console-ui/assets/geist-cyrillic-ext-wght-normal-DjL33-gN.woff2 +0 -0
  32. package/dist/console-ui/assets/geist-cyrillic-wght-normal-BEAKL7Jp.woff2 +0 -0
  33. package/dist/console-ui/assets/geist-latin-ext-wght-normal-DC-KSUi6.woff2 +0 -0
  34. package/dist/console-ui/assets/geist-latin-wght-normal-BgDaEnEv.woff2 +0 -0
  35. package/dist/console-ui/assets/geist-vietnamese-wght-normal-6IgcOCM7.woff2 +0 -0
  36. package/dist/console-ui/assets/hermes-B8hNbJPm.png +0 -0
  37. package/dist/console-ui/assets/index-BxUf0Sye.js +96 -0
  38. package/dist/console-ui/assets/index-CmTiBR_w.css +2 -0
  39. package/dist/console-ui/assets/omnigent-Cxa4p2Mq.png +0 -0
  40. package/dist/console-ui/assets/openclaw-C5wL4ZVW.png +0 -0
  41. package/dist/console-ui/assets/opencode-D_wFATSC.png +0 -0
  42. package/dist/console-ui/assets/openhands-DnrlGgev.svg +9 -0
  43. package/dist/console-ui/assets/s-gw-64-ByMUGQ3K.png +0 -0
  44. package/dist/console-ui/assets/vscode-Bdtr9eyf.png +0 -0
  45. package/dist/console-ui/assets/zeptoclaw-DztQW8Sw.png +0 -0
  46. package/dist/console-ui/index.html +13 -0
  47. package/dist/crypto.d.ts +6 -0
  48. package/dist/crypto.js +53 -0
  49. package/dist/executor.d.ts +7 -0
  50. package/dist/executor.js +297 -0
  51. package/dist/gateway.d.ts +31 -0
  52. package/dist/gateway.js +114 -0
  53. package/dist/guard.d.ts +61 -0
  54. package/dist/guard.js +247 -0
  55. package/dist/install.d.ts +146 -0
  56. package/dist/install.js +629 -0
  57. package/dist/mcp-server.d.ts +2 -0
  58. package/dist/mcp-server.js +119 -0
  59. package/dist/native/s-gw-core +0 -0
  60. package/dist/native/s-gw-keychain-helper +0 -0
  61. package/dist/onepassword.d.ts +48 -0
  62. package/dist/onepassword.js +412 -0
  63. package/dist/paths.d.ts +4 -0
  64. package/dist/paths.js +22 -0
  65. package/dist/s-gw Menu Bar.app/Contents/Info.plist +28 -0
  66. package/dist/s-gw Menu Bar.app/Contents/MacOS/s-gw-menu-bar-helper +0 -0
  67. package/dist/s-gw Menu Bar.app/Contents/Resources/AppIcon.icns +0 -0
  68. package/dist/s-gw Menu Bar.app/Contents/Resources/AwsEc2.png +0 -0
  69. package/dist/s-gw Menu Bar.app/Contents/Resources/Lucide-bot.svg +8 -0
  70. package/dist/s-gw Menu Bar.app/Contents/Resources/Lucide-monitor.svg +5 -0
  71. package/dist/s-gw Menu Bar.app/Contents/Resources/Lucide-server.svg +6 -0
  72. package/dist/s-gw Menu Bar.app/Contents/Resources/Lucide-terminal.svg +4 -0
  73. package/dist/s-gw Menu Bar.app/Contents/Resources/MenuBarTemplate.png +0 -0
  74. package/dist/s-gw Menu Bar.app/Contents/_CodeSignature/CodeResources +194 -0
  75. package/dist/s-gw.app/Contents/Info.plist +28 -0
  76. package/dist/s-gw.app/Contents/MacOS/s-gw +0 -0
  77. package/dist/s-gw.app/Contents/Resources/AppIcon.icns +0 -0
  78. package/dist/s-gw.app/Contents/Resources/MenuBarTemplate.png +0 -0
  79. package/dist/s-gw.app/Contents/_CodeSignature/CodeResources +139 -0
  80. package/dist/scanner.d.ts +9 -0
  81. package/dist/scanner.js +437 -0
  82. package/dist/ssh.d.ts +31 -0
  83. package/dist/ssh.js +286 -0
  84. package/dist/store.d.ts +131 -0
  85. package/dist/store.js +1611 -0
  86. package/dist/types.d.ts +196 -0
  87. package/dist/types.js +2 -0
  88. package/dist/unlock.d.ts +29 -0
  89. package/dist/unlock.js +274 -0
  90. package/dist/windows/VERSION.txt +1 -0
  91. package/dist/windows/s-gw-client.cmd +4 -0
  92. package/dist/windows/s-gw-client.ps1 +106 -0
  93. package/dist/windows/s-gw-credential.cmd +4 -0
  94. package/dist/windows/s-gw-credential.ps1 +167 -0
  95. package/dist/windows/s-gw-helper.cmd +4 -0
  96. package/dist/windows/s-gw-helper.ps1 +180 -0
  97. package/docs/README.md +23 -0
  98. package/docs/agents.md +160 -0
  99. package/docs/architecture.md +72 -0
  100. package/docs/deployment.md +447 -0
  101. package/docs/detection.md +44 -0
  102. package/docs/images/s-gw-overview.png +0 -0
  103. package/docs/integrations.md +195 -0
  104. package/docs/keychain.md +39 -0
  105. package/docs/onepassword.md +84 -0
  106. package/docs/quickstart.md +104 -0
  107. package/docs/threat-model.md +100 -0
  108. package/docs/ui/THIRD_PARTY_NOTICES.md +111 -0
  109. package/docs/ui/apple-touch-icon.png +0 -0
  110. package/docs/ui/favicon-32.png +0 -0
  111. package/docs/ui/local-console.html +4477 -0
  112. package/docs/ui/vendor/d3-sankey/d3-array.LICENSE.txt +27 -0
  113. package/docs/ui/vendor/d3-sankey/d3-array.min.js +2 -0
  114. package/docs/ui/vendor/d3-sankey/d3-path.LICENSE.txt +27 -0
  115. package/docs/ui/vendor/d3-sankey/d3-path.min.js +2 -0
  116. package/docs/ui/vendor/d3-sankey/d3-sankey.LICENSE.txt +27 -0
  117. package/docs/ui/vendor/d3-sankey/d3-sankey.min.js +2 -0
  118. package/docs/ui/vendor/d3-sankey/d3-shape.LICENSE.txt +27 -0
  119. package/docs/ui/vendor/d3-sankey/d3-shape.min.js +2 -0
  120. package/docs/ui/vendor/sankeymatic/LICENSE.txt +17 -0
  121. package/docs/ui/vendor/sankeymatic/sankey.js +897 -0
  122. package/package.json +117 -0
  123. package/skills/s-gw/SKILL.md +19 -0
@@ -0,0 +1,437 @@
1
+ import { randomBytes } from "node:crypto";
2
+ const detectorRules = [
3
+ {
4
+ id: "SEC-PRIVATE-KEY",
5
+ type: "private-key",
6
+ provider: "generic",
7
+ label: "private key block",
8
+ regex: /-----BEGIN (?:RSA |EC |DSA |OPENSSH |PGP )?PRIVATE KEY-----[\s\S]+?-----END (?:RSA |EC |DSA |OPENSSH |PGP )?PRIVATE KEY-----/g,
9
+ severity: "critical",
10
+ confidence: 0.98
11
+ },
12
+ {
13
+ id: "SEC-ANTHROPIC",
14
+ type: "api-token",
15
+ provider: "anthropic",
16
+ label: "Anthropic API key",
17
+ regex: /\bsk-ant-[A-Za-z0-9_-]{20,}\b/g,
18
+ severity: "critical",
19
+ confidence: 0.98
20
+ },
21
+ {
22
+ id: "SEC-OPENAI-PROJECT",
23
+ type: "api-token",
24
+ provider: "openai",
25
+ label: "OpenAI project key",
26
+ regex: /\bsk-proj-[A-Za-z0-9_-]{20,}\b/g,
27
+ severity: "critical",
28
+ confidence: 0.95
29
+ },
30
+ {
31
+ id: "SEC-OPENAI",
32
+ type: "api-token",
33
+ provider: "openai",
34
+ label: "OpenAI API key",
35
+ regex: /\bsk-[A-Za-z0-9]{40,}\b/g,
36
+ severity: "critical",
37
+ confidence: 0.85
38
+ },
39
+ {
40
+ id: "SEC-AWS-ACCESS-KEY",
41
+ type: "access-key",
42
+ provider: "aws",
43
+ label: "AWS access key id",
44
+ regex: /\b(?:AKIA|AGPA|AIDA|AROA|AIPA|ANPA|ANVA|ASIA)[0-9A-Z]{16,}\b/g,
45
+ severity: "critical",
46
+ confidence: 0.95
47
+ },
48
+ {
49
+ id: "SEC-AWS-SECRET",
50
+ type: "credential",
51
+ provider: "aws",
52
+ label: "AWS secret access key",
53
+ regex: /\b(?:aws_?)?(?:secret_?)?(?:access_?)?key\b\s*[:=]\s*["']?([A-Za-z0-9/+=]{40})["']?/gi,
54
+ group: 1,
55
+ severity: "critical",
56
+ confidence: 0.9
57
+ },
58
+ {
59
+ id: "SEC-GITHUB-FINE",
60
+ type: "api-token",
61
+ provider: "github",
62
+ label: "GitHub fine-grained PAT",
63
+ regex: /\bgithub_pat_[A-Za-z0-9_]{22,}\b/g,
64
+ severity: "critical",
65
+ confidence: 0.95
66
+ },
67
+ {
68
+ id: "SEC-GITHUB-TOKEN",
69
+ type: "api-token",
70
+ provider: "github",
71
+ label: "GitHub token",
72
+ regex: /\bgh[pousr]_[A-Za-z0-9]{30,}\b/g,
73
+ severity: "critical",
74
+ confidence: 0.95
75
+ },
76
+ {
77
+ id: "SEC-GITLAB",
78
+ type: "api-token",
79
+ provider: "gitlab",
80
+ label: "GitLab access token",
81
+ regex: /\bgl(?:pat|ptt|soat)-[A-Za-z0-9_-]{20,}\b/g,
82
+ severity: "critical",
83
+ confidence: 0.95
84
+ },
85
+ {
86
+ id: "SEC-SLACK-TOKEN",
87
+ type: "api-token",
88
+ provider: "slack",
89
+ label: "Slack token",
90
+ regex: /\bxox[baprs]-[0-9A-Za-z-]{20,}\b/g,
91
+ severity: "critical",
92
+ confidence: 0.9
93
+ },
94
+ {
95
+ id: "SEC-SLACK-WEBHOOK",
96
+ type: "api-token",
97
+ provider: "slack",
98
+ label: "Slack webhook URL",
99
+ regex: /https:\/\/hooks\.slack\.com\/services\/T[A-Z0-9]+\/B[A-Z0-9]+\/[A-Za-z0-9]+/g,
100
+ severity: "critical",
101
+ confidence: 0.95
102
+ },
103
+ {
104
+ id: "SEC-DISCORD-WEBHOOK",
105
+ type: "api-token",
106
+ provider: "discord",
107
+ label: "Discord webhook URL",
108
+ regex: /https:\/\/discord(?:app)?\.com\/api\/webhooks\/\d+\/[A-Za-z0-9_-]+/g,
109
+ severity: "critical",
110
+ confidence: 0.95
111
+ },
112
+ {
113
+ id: "SEC-STRIPE-SECRET",
114
+ type: "api-token",
115
+ provider: "stripe",
116
+ label: "Stripe secret key",
117
+ regex: /\b(?:sk_live_|sk_test_|rk_live_|rk_test_)[A-Za-z0-9]{20,}\b/g,
118
+ severity: "critical",
119
+ confidence: 0.95
120
+ },
121
+ {
122
+ id: "SEC-STRIPE-PUBLISHABLE",
123
+ type: "api-token",
124
+ provider: "stripe",
125
+ label: "Stripe publishable key",
126
+ regex: /\bpk_(?:live|test)_[A-Za-z0-9]{20,}\b/g,
127
+ severity: "low",
128
+ confidence: 0.8
129
+ },
130
+ {
131
+ id: "SEC-GOOGLE-API",
132
+ type: "api-token",
133
+ provider: "google",
134
+ label: "Google API key",
135
+ regex: /\bAIza[0-9A-Za-z_-]{35}\b/g,
136
+ severity: "high",
137
+ confidence: 0.9
138
+ },
139
+ {
140
+ id: "SEC-AZURE-STORAGE",
141
+ type: "credential",
142
+ provider: "azure",
143
+ label: "Azure storage account key",
144
+ regex: /\bAccountKey=([A-Za-z0-9+/=]{44,})/gi,
145
+ group: 1,
146
+ severity: "critical",
147
+ confidence: 0.92
148
+ },
149
+ {
150
+ id: "SEC-AZURE-SAS",
151
+ type: "api-token",
152
+ provider: "azure",
153
+ label: "Azure SAS signature",
154
+ regex: /[?&]sig=([A-Za-z0-9%+/=]{30,})/gi,
155
+ group: 1,
156
+ severity: "high",
157
+ confidence: 0.85
158
+ },
159
+ {
160
+ id: "SEC-SENDGRID",
161
+ type: "api-token",
162
+ provider: "sendgrid",
163
+ label: "SendGrid API key",
164
+ regex: /\bSG\.[A-Za-z0-9_-]{22}\.[A-Za-z0-9_-]{30,}\b/g,
165
+ severity: "critical",
166
+ confidence: 0.95
167
+ },
168
+ {
169
+ id: "SEC-MAILGUN",
170
+ type: "api-token",
171
+ provider: "mailgun",
172
+ label: "Mailgun API key",
173
+ regex: /\bkey-[A-Za-z0-9]{32}\b/g,
174
+ severity: "critical",
175
+ confidence: 0.9
176
+ },
177
+ {
178
+ id: "SEC-TWILIO-AUTH",
179
+ type: "api-token",
180
+ provider: "twilio",
181
+ label: "Twilio auth token",
182
+ regex: /\btwilio[\w-]*(?:auth|token)\b\s*[:=]\s*["']?([0-9a-fA-F]{32})["']?/gi,
183
+ group: 1,
184
+ severity: "critical",
185
+ confidence: 0.9
186
+ },
187
+ {
188
+ id: "SEC-TWILIO-KEY",
189
+ type: "api-token",
190
+ provider: "twilio",
191
+ label: "Twilio API key",
192
+ regex: /\bSK[0-9a-fA-F]{32}\b/g,
193
+ severity: "high",
194
+ confidence: 0.8
195
+ },
196
+ {
197
+ id: "SEC-NPM",
198
+ type: "api-token",
199
+ provider: "npm",
200
+ label: "npm access token",
201
+ regex: /\bnpm_[A-Za-z0-9]{36,}\b/g,
202
+ severity: "critical",
203
+ confidence: 0.95
204
+ },
205
+ {
206
+ id: "SEC-PYPI",
207
+ type: "api-token",
208
+ provider: "pypi",
209
+ label: "PyPI API token",
210
+ regex: /\bpypi-[A-Za-z0-9_-]{50,}\b/g,
211
+ severity: "critical",
212
+ confidence: 0.95
213
+ },
214
+ {
215
+ id: "SEC-JWT",
216
+ type: "api-token",
217
+ provider: "jwt",
218
+ label: "JWT token",
219
+ regex: /\beyJ[A-Za-z0-9_-]{10,}\.eyJ[A-Za-z0-9_-]{10,}\.[A-Za-z0-9_.+/=-]+\b/g,
220
+ severity: "medium",
221
+ confidence: 0.7,
222
+ validator: looksLikeJwt
223
+ },
224
+ {
225
+ id: "SEC-CONNECTION-STRING",
226
+ type: "credential",
227
+ provider: "database",
228
+ label: "connection string credentials",
229
+ regex: /\b(?:mongodb(?:\+srv)?|postgres(?:ql)?|mysql|redis|amqp):\/\/([^:\s/@]+:[^@\s]+)@/gi,
230
+ group: 1,
231
+ severity: "critical",
232
+ confidence: 0.9
233
+ },
234
+ {
235
+ id: "SEC-BASIC-AUTH",
236
+ type: "credential",
237
+ provider: "http",
238
+ label: "Basic auth header",
239
+ regex: /\b(?:authorization|auth)\b\s*[:=]\s*["']?Basic\s+([A-Za-z0-9+/=]{10,})["']?/gi,
240
+ group: 1,
241
+ severity: "high",
242
+ confidence: 0.82
243
+ },
244
+ {
245
+ id: "SEC-BEARER",
246
+ type: "api-token",
247
+ provider: "http",
248
+ label: "Bearer token",
249
+ regex: /\b(?:authorization|auth|bearer)\b\s*[:=]\s*["']?Bearer\s+([A-Za-z0-9_.~+/=-]{20,})["']?/gi,
250
+ group: 1,
251
+ severity: "high",
252
+ confidence: 0.82
253
+ },
254
+ {
255
+ id: "SEC-HEX-ASSIGNMENT",
256
+ type: "credential",
257
+ provider: "generic",
258
+ label: "hex-encoded secret assignment",
259
+ regex: /\b[A-Z0-9_.-]*(?:SECRET(?:_KEY)?|API[_-]?KEY|ACCESS[_-]?TOKEN|AUTH[_-]?TOKEN)[A-Z0-9_.-]*\s*[:=]\s*["']([a-f0-9]{32,})["']/gi,
260
+ group: 1,
261
+ severity: "high",
262
+ confidence: 0.72
263
+ },
264
+ {
265
+ id: "SEC-GENERIC-ASSIGNMENT",
266
+ type: "credential",
267
+ provider: "generic",
268
+ label: "credential assignment",
269
+ regex: /\b[A-Z0-9_.-]*(?:API[_-]?KEY|TOKEN|SECRET|PASSWORD|PRIVATE[_-]?KEY|CLIENT[_-]?SECRET)[A-Z0-9_.-]*\s*[:=]\s*["']?([A-Za-z0-9][A-Za-z0-9_\-./+=:@]{15,})["']?/gim,
270
+ group: 1,
271
+ severity: "high",
272
+ confidence: 0.68
273
+ },
274
+ {
275
+ id: "SEC-PASSWORD-ASSIGNMENT",
276
+ type: "password",
277
+ provider: "generic",
278
+ label: "password assignment",
279
+ regex: /\b(?:password|passwd|pwd)\b\s*[:=]\s*["']?([^\s;,'"]{12,})["']?/gi,
280
+ group: 1,
281
+ severity: "high",
282
+ confidence: 0.66
283
+ }
284
+ ];
285
+ export async function scanText(text, getHandle) {
286
+ const candidates = collectCandidates(text);
287
+ const findings = [];
288
+ const chunks = [];
289
+ let cursor = 0;
290
+ for (const candidate of candidates) {
291
+ if (candidate.start < cursor) {
292
+ continue;
293
+ }
294
+ const handle = await getHandle(candidate);
295
+ const token = tokenForHandle(handle);
296
+ findings.push({
297
+ type: candidate.type,
298
+ label: candidate.label,
299
+ provider: candidate.provider,
300
+ ruleId: candidate.ruleId,
301
+ severity: candidate.severity,
302
+ confidence: candidate.confidence,
303
+ handle,
304
+ token,
305
+ start: candidate.start,
306
+ end: candidate.end
307
+ });
308
+ chunks.push(text.slice(cursor, candidate.start));
309
+ chunks.push(token);
310
+ cursor = candidate.end;
311
+ }
312
+ chunks.push(text.slice(cursor));
313
+ return {
314
+ tokenizedText: chunks.join(""),
315
+ findings
316
+ };
317
+ }
318
+ export function previewHandle(candidate) {
319
+ return `s-gw:preview:${candidate.type}:${randomBytes(9).toString("base64url")}`;
320
+ }
321
+ export function tokenForHandle(handle) {
322
+ return `<<SGW_SECRET:${handle}>>`;
323
+ }
324
+ export function sanitizeKnownSecrets(text, pairs) {
325
+ let out = text;
326
+ const ordered = [...pairs].sort((left, right) => right.value.length - left.value.length);
327
+ for (const pair of ordered) {
328
+ if (!pair.value) {
329
+ continue;
330
+ }
331
+ out = out.split(pair.value).join(tokenForHandle(pair.handle));
332
+ }
333
+ return out;
334
+ }
335
+ function collectCandidates(text) {
336
+ const found = [];
337
+ for (const rule of detectorRules) {
338
+ rule.regex.lastIndex = 0;
339
+ let match = rule.regex.exec(text);
340
+ while (match) {
341
+ const value = rule.group ? match[rule.group] : match[0];
342
+ if (value && shouldKeepCandidate(value, rule)) {
343
+ const baseIndex = match.index;
344
+ const offset = rule.group ? match[0].indexOf(value) : 0;
345
+ const start = baseIndex + offset;
346
+ found.push({
347
+ type: rule.type,
348
+ label: rule.label,
349
+ provider: rule.provider,
350
+ ruleId: rule.id,
351
+ severity: rule.severity,
352
+ confidence: rule.confidence,
353
+ value,
354
+ start,
355
+ end: start + value.length
356
+ });
357
+ }
358
+ match = rule.regex.exec(text);
359
+ }
360
+ }
361
+ found.sort((a, b) => {
362
+ if (a.start === b.start) {
363
+ return b.end - a.end;
364
+ }
365
+ return a.start - b.start;
366
+ });
367
+ const out = [];
368
+ let occupiedUntil = -1;
369
+ for (const item of found) {
370
+ if (item.start < occupiedUntil) {
371
+ continue;
372
+ }
373
+ out.push(item);
374
+ occupiedUntil = item.end;
375
+ }
376
+ return out;
377
+ }
378
+ function shouldKeepCandidate(value, rule) {
379
+ if (!likelySecret(value)) {
380
+ return false;
381
+ }
382
+ if (looksLikePlaceholder(value)) {
383
+ return false;
384
+ }
385
+ if (rule.validator && !rule.validator(value)) {
386
+ return false;
387
+ }
388
+ return true;
389
+ }
390
+ function likelySecret(value) {
391
+ if (value.length < 16) {
392
+ return false;
393
+ }
394
+ const uniqueChars = new Set(value).size;
395
+ if (uniqueChars < 8) {
396
+ return false;
397
+ }
398
+ if (/^(true|false|null|undefined)$/i.test(value)) {
399
+ return false;
400
+ }
401
+ return true;
402
+ }
403
+ function looksLikePlaceholder(value) {
404
+ const compact = value.toLowerCase().replace(/[^a-z0-9]/g, "");
405
+ if (!compact) {
406
+ return true;
407
+ }
408
+ if (/^(x+|0+|1+|a+|z+)$/.test(compact)) {
409
+ return true;
410
+ }
411
+ return (compact.includes("example") ||
412
+ compact.includes("placeholder") ||
413
+ compact.includes("changeme") ||
414
+ compact.includes("replacewith") ||
415
+ compact.includes("yourtoken") ||
416
+ compact.includes("yourkey") ||
417
+ compact.includes("yourapikey"));
418
+ }
419
+ function looksLikeJwt(value) {
420
+ const parts = value.split(".");
421
+ if (parts.length !== 3) {
422
+ return false;
423
+ }
424
+ for (const part of parts.slice(0, 2)) {
425
+ try {
426
+ const normalized = part.replace(/-/g, "+").replace(/_/g, "/");
427
+ const padded = normalized.padEnd(Math.ceil(normalized.length / 4) * 4, "=");
428
+ const decoded = Buffer.from(padded, "base64").toString("utf8");
429
+ JSON.parse(decoded);
430
+ }
431
+ catch {
432
+ return false;
433
+ }
434
+ }
435
+ return true;
436
+ }
437
+ //# sourceMappingURL=scanner.js.map
package/dist/ssh.d.ts ADDED
@@ -0,0 +1,31 @@
1
+ import type { CommandAction, ExecutionSummary, RequestRecord, SecretRecord } from "./types.js";
2
+ export declare const SGW_SSH_SESSION_COMMAND = "s-gw:ssh-session";
3
+ export interface SshSessionInput {
4
+ target: string;
5
+ port?: number;
6
+ args?: string[];
7
+ injectEnv?: string;
8
+ workingDir?: string;
9
+ timeoutMs?: number;
10
+ }
11
+ interface ProcessResult {
12
+ exitCode: number | null;
13
+ signal: NodeJS.Signals | null;
14
+ stdout: string;
15
+ stderr: string;
16
+ durationMs: number;
17
+ timedOut: boolean;
18
+ }
19
+ export declare function buildSshSessionAction(input: SshSessionInput): CommandAction;
20
+ export declare function defaultSshInjectEnv(secret: SecretRecord): string;
21
+ export declare function normalizeSshTarget(target: string): string;
22
+ export declare function normalizeSshPort(port?: number): number;
23
+ export declare function sshSessionIdentity(action: CommandAction): string;
24
+ export declare function runOwnedSshSession(request: RequestRecord, secretRecord: SecretRecord, secretValue: string, home?: string): Promise<ExecutionSummary>;
25
+ export declare function closeOwnedSshSession(input: {
26
+ handle: string;
27
+ target: string;
28
+ port?: number;
29
+ home?: string;
30
+ }): Promise<ProcessResult>;
31
+ export {};