sublyzer-snapshot 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (115) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +306 -0
  3. package/dist/api/sublyzer.d.ts +29 -0
  4. package/dist/api/sublyzer.d.ts.map +1 -0
  5. package/dist/api/sublyzer.js +61 -0
  6. package/dist/api/sublyzer.js.map +1 -0
  7. package/dist/cli.d.ts +3 -0
  8. package/dist/cli.d.ts.map +1 -0
  9. package/dist/cli.js +199 -0
  10. package/dist/cli.js.map +1 -0
  11. package/dist/commands/ci.d.ts +9 -0
  12. package/dist/commands/ci.d.ts.map +1 -0
  13. package/dist/commands/ci.js +65 -0
  14. package/dist/commands/ci.js.map +1 -0
  15. package/dist/commands/compare.d.ts +7 -0
  16. package/dist/commands/compare.d.ts.map +1 -0
  17. package/dist/commands/compare.js +60 -0
  18. package/dist/commands/compare.js.map +1 -0
  19. package/dist/commands/doctor.d.ts +13 -0
  20. package/dist/commands/doctor.d.ts.map +1 -0
  21. package/dist/commands/doctor.js +100 -0
  22. package/dist/commands/doctor.js.map +1 -0
  23. package/dist/commands/init.d.ts +10 -0
  24. package/dist/commands/init.d.ts.map +1 -0
  25. package/dist/commands/init.js +88 -0
  26. package/dist/commands/init.js.map +1 -0
  27. package/dist/commands/open.d.ts +2 -0
  28. package/dist/commands/open.d.ts.map +1 -0
  29. package/dist/commands/open.js +16 -0
  30. package/dist/commands/open.js.map +1 -0
  31. package/dist/commands/pull.d.ts +9 -0
  32. package/dist/commands/pull.d.ts.map +1 -0
  33. package/dist/commands/pull.js +34 -0
  34. package/dist/commands/pull.js.map +1 -0
  35. package/dist/commands/report.d.ts +8 -0
  36. package/dist/commands/report.d.ts.map +1 -0
  37. package/dist/commands/report.js +47 -0
  38. package/dist/commands/report.js.map +1 -0
  39. package/dist/commands/run.d.ts +21 -0
  40. package/dist/commands/run.d.ts.map +1 -0
  41. package/dist/commands/run.js +96 -0
  42. package/dist/commands/run.js.map +1 -0
  43. package/dist/commands/status.d.ts +5 -0
  44. package/dist/commands/status.d.ts.map +1 -0
  45. package/dist/commands/status.js +52 -0
  46. package/dist/commands/status.js.map +1 -0
  47. package/dist/config.d.ts +36 -0
  48. package/dist/config.d.ts.map +1 -0
  49. package/dist/config.js +58 -0
  50. package/dist/config.js.map +1 -0
  51. package/dist/constants.d.ts +13 -0
  52. package/dist/constants.d.ts.map +1 -0
  53. package/dist/constants.js +12 -0
  54. package/dist/constants.js.map +1 -0
  55. package/dist/detect/git.d.ts +9 -0
  56. package/dist/detect/git.d.ts.map +1 -0
  57. package/dist/detect/git.js +25 -0
  58. package/dist/detect/git.js.map +1 -0
  59. package/dist/detect/meta.d.ts +8 -0
  60. package/dist/detect/meta.d.ts.map +1 -0
  61. package/dist/detect/meta.js +42 -0
  62. package/dist/detect/meta.js.map +1 -0
  63. package/dist/detect/routes.d.ts +2 -0
  64. package/dist/detect/routes.d.ts.map +1 -0
  65. package/dist/detect/routes.js +104 -0
  66. package/dist/detect/routes.js.map +1 -0
  67. package/dist/detect/stack.d.ts +15 -0
  68. package/dist/detect/stack.d.ts.map +1 -0
  69. package/dist/detect/stack.js +114 -0
  70. package/dist/detect/stack.js.map +1 -0
  71. package/dist/detect/workspaces.d.ts +6 -0
  72. package/dist/detect/workspaces.d.ts.map +1 -0
  73. package/dist/detect/workspaces.js +54 -0
  74. package/dist/detect/workspaces.js.map +1 -0
  75. package/dist/report/markdown.d.ts +5 -0
  76. package/dist/report/markdown.d.ts.map +1 -0
  77. package/dist/report/markdown.js +81 -0
  78. package/dist/report/markdown.js.map +1 -0
  79. package/dist/scan/audit.d.ts +16 -0
  80. package/dist/scan/audit.d.ts.map +1 -0
  81. package/dist/scan/audit.js +53 -0
  82. package/dist/scan/audit.js.map +1 -0
  83. package/dist/scan/health-score.d.ts +13 -0
  84. package/dist/scan/health-score.d.ts.map +1 -0
  85. package/dist/scan/health-score.js +60 -0
  86. package/dist/scan/health-score.js.map +1 -0
  87. package/dist/scan/history.d.ts +21 -0
  88. package/dist/scan/history.d.ts.map +1 -0
  89. package/dist/scan/history.js +82 -0
  90. package/dist/scan/history.js.map +1 -0
  91. package/dist/scan/outdated.d.ts +15 -0
  92. package/dist/scan/outdated.d.ts.map +1 -0
  93. package/dist/scan/outdated.js +54 -0
  94. package/dist/scan/outdated.js.map +1 -0
  95. package/dist/scan/policy.d.ts +5 -0
  96. package/dist/scan/policy.d.ts.map +1 -0
  97. package/dist/scan/policy.js +20 -0
  98. package/dist/scan/policy.js.map +1 -0
  99. package/dist/scan/snapshot.d.ts +47 -0
  100. package/dist/scan/snapshot.d.ts.map +1 -0
  101. package/dist/scan/snapshot.js +176 -0
  102. package/dist/scan/snapshot.js.map +1 -0
  103. package/dist/utils/gitignore.d.ts +3 -0
  104. package/dist/utils/gitignore.d.ts.map +1 -0
  105. package/dist/utils/gitignore.js +34 -0
  106. package/dist/utils/gitignore.js.map +1 -0
  107. package/dist/utils/log.d.ts +6 -0
  108. package/dist/utils/log.d.ts.map +1 -0
  109. package/dist/utils/log.js +17 -0
  110. package/dist/utils/log.js.map +1 -0
  111. package/dist/utils/prompt.d.ts +4 -0
  112. package/dist/utils/prompt.d.ts.map +1 -0
  113. package/dist/utils/prompt.js +35 -0
  114. package/dist/utils/prompt.js.map +1 -0
  115. package/package.json +51 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Sublyzer
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,306 @@
1
+ <div align="center">
2
+
3
+ # Sublyzer Snapshot
4
+
5
+ <img src="./Sublyzer1.png" alt="Sublyzer" width="96" />
6
+
7
+ **Turn any codebase into a live Sublyzer dashboard in 30 seconds.**
8
+
9
+ Scan routes, dependencies, and vulnerabilities locally — get a health score — push everything to [Sublyzer](https://sublyzer.com). No SDK required for your first check.
10
+
11
+ <br />
12
+
13
+ [![npm version](https://img.shields.io/badge/npm-v0.3.0-2563eb?style=for-the-badge&logo=npm&logoColor=white)](https://www.npmjs.com/package/sublyzer-snapshot)
14
+ [![License: MIT](https://img.shields.io/badge/License-MIT-22c55e?style=for-the-badge)](LICENSE)
15
+ [![Node.js](https://img.shields.io/badge/Node.js-18%2B-339933?style=for-the-badge&logo=node.js&logoColor=white)](https://nodejs.org)
16
+ [![TypeScript](https://img.shields.io/badge/TypeScript-5.x-3178C6?style=for-the-badge&logo=typescript&logoColor=white)](https://www.typescriptlang.org)
17
+ [![Sublyzer](https://img.shields.io/badge/Powered%20by-Sublyzer-6366f1?style=for-the-badge)](https://sublyzer.com)
18
+
19
+ <br />
20
+
21
+ [`Quick Start`](#-quick-start) · [`How It Works`](#-how-it-works) · [`Commands`](#-commands) · [`CI/CD`](#-cicd) · [`Docs`](#-environment-variables) · [Sublyzer Dashboard](https://sublyzer.com/dashboard)
22
+
23
+ <br />
24
+
25
+ ```
26
+ $ npx sublyzer-snapshot init && npx sublyzer-snapshot run
27
+
28
+ Project: my-saas-app
29
+ Stack: Next.js (high)
30
+ Health: [████████░░] 82/100 grade B
31
+ Routes: 14
32
+ Vulnerabilities: 2 (critical 0, high 1)
33
+ ✓ Sent 6 events → dashboard updated
34
+ ```
35
+
36
+ </div>
37
+
38
+ ---
39
+
40
+ ## ✨ Introduction
41
+
42
+ **Sublyzer Snapshot** is an open-source CLI that answers one question every developer asks:
43
+
44
+ > *"How healthy is my project right now?"*
45
+
46
+ Instead of wiring up three separate tools (dependency scanner, route inventory, monitoring dashboard), you run **one command**. Snapshot scans your repo locally, computes a **health score (0–100)**, and pushes structured events to your **Sublyzer** integration — where you (or an AI agent like Hermes) can read them back.
47
+
48
+ Built for **indie hackers**, **startup teams**, and **agencies** who want instant project visibility without a week of DevOps setup.
49
+
50
+ ---
51
+
52
+ ## 🎯 What is it for?
53
+
54
+ | Use case | What you get |
55
+ |----------|--------------|
56
+ | **First-time project check** | Stack detection, route map, CVE summary in ~30s |
57
+ | **Pre-deploy sanity check** | Health score + vulnerability gate before shipping |
58
+ | **CI/CD pipeline** | `--fail-on high` blocks merges with critical CVEs |
59
+ | **Client / team reports** | `report --out HEALTH.md` — shareable Markdown |
60
+ | **Trend tracking** | `compare` shows what changed since last scan |
61
+ | **Sublyzer onboarding** | Data in your dashboard before installing the browser SDK |
62
+
63
+ ### Before vs After
64
+
65
+ | Before | After (Sublyzer Snapshot) |
66
+ |--------|---------------------------|
67
+ | Sentry + Dependabot + manual spreadsheet | One CLI, one dashboard |
68
+ | 45+ min setup | ~30 seconds |
69
+ | No unified health score | 0–100 score with grade A–F |
70
+ | Hard to show clients "project status" | Export `report.md` in one command |
71
+
72
+ ---
73
+
74
+ ## ⚙️ How it works
75
+
76
+ ```mermaid
77
+ flowchart LR
78
+ A[Your repo] --> B[sublyzer-snapshot run]
79
+ B --> C[Local scan]
80
+ C --> D[Routes · deps · audit · git]
81
+ D --> E[Health score 0-100]
82
+ E --> F[Sublyzer API]
83
+ F --> G[Dashboard]
84
+ G --> H[Hermes / agents / team]
85
+
86
+ style A fill:#1e293b,stroke:#475569,color:#f8fafc
87
+ style G fill:#2563eb,stroke:#1d4ed8,color:#fff
88
+ style E fill:#22c55e,stroke:#16a34a,color:#fff
89
+ ```
90
+
91
+ 1. **`init`** — Links your project folder to a Sublyzer integration (24-char code).
92
+ 2. **`run`** — Scans locally: framework, routes, `npm audit`, outdated packages, git metadata.
93
+ 3. **Score** — Computes health grade from vulnerabilities, routes, env hygiene, and more.
94
+ 4. **Push** — Sends events to `POST /data-collection/collect-batch` on Sublyzer.
95
+ 5. **Dashboard** — Data appears under your integration; optional SDK for live telemetry later.
96
+
97
+ Scan history is stored in `.sublyzer/` (gitignored automatically) so `compare` can show diffs over time.
98
+
99
+ ---
100
+
101
+ ## 🚀 Quick start
102
+
103
+ ### Prerequisites
104
+
105
+ - **Node.js 18+**
106
+ - **npm** (for audit/outdated; optional with `--skip-audit`)
107
+ - A [Sublyzer](https://sublyzer.com) account + **integration code** (24 chars, from Dashboard → Integrations)
108
+
109
+ ### Install & run
110
+
111
+ ```bash
112
+ # 1. Link your project
113
+ npx sublyzer-snapshot init
114
+
115
+ # 2. Scan and push
116
+ npx sublyzer-snapshot run
117
+
118
+ # 3. Open dashboard
119
+ npx sublyzer-snapshot open
120
+ ```
121
+
122
+ Non-interactive (CI / scripts):
123
+
124
+ ```bash
125
+ export SUBLYZER_INTEGRATION_CODE="YOUR_24_CHAR_CODE"
126
+ npx sublyzer-snapshot init -y
127
+ npx sublyzer-snapshot run --fail-on high
128
+ ```
129
+
130
+ ### Development (this monorepo)
131
+
132
+ ```bash
133
+ cd projects/sublyzer-snapshot
134
+ npm install && npm run build
135
+ node dist/cli.js init --code YOUR_CODE -y
136
+ node dist/cli.js run --dry-run
137
+ ```
138
+
139
+ ---
140
+
141
+ ## 🧰 Commands
142
+
143
+ | Command | Description |
144
+ |---------|-------------|
145
+ | `init` | Detect stack, validate code, write `.sublyzer/snapshot.json` |
146
+ | `run` | Full scan + push to Sublyzer |
147
+ | `report` | Generate Markdown health report (`--out report.md`) |
148
+ | `compare` | Diff routes, vulns, and score vs previous scan |
149
+ | `ci` | Print or write GitHub Actions workflow |
150
+ | `status` | Show linked integration + last scan |
151
+ | `doctor` | Verify config, API, integration code, read key |
152
+ | `pull` | Fetch data back via public read API (needs `apiReadKey`) |
153
+ | `open` | Open integration in browser |
154
+
155
+ ### Common flags
156
+
157
+ ```bash
158
+ sublyzer-snapshot run --dry-run # Local preview, no push
159
+ sublyzer-snapshot run --skip-audit # Faster scan
160
+ sublyzer-snapshot run --fail-on high # Exit 1 on high/critical CVEs
161
+ sublyzer-snapshot run --json # CI-friendly JSON output
162
+
163
+ sublyzer-snapshot report --out HEALTH.md
164
+ sublyzer-snapshot compare --rescan
165
+ sublyzer-snapshot ci --out .github/workflows/sublyzer-snapshot.yml
166
+ ```
167
+
168
+ ---
169
+
170
+ ## 📊 Health score
171
+
172
+ Every scan produces a **0–100 score** and letter grade (**A–F**):
173
+
174
+ | Factor | Impact |
175
+ |--------|--------|
176
+ | Critical CVEs | −25 each (max −50) |
177
+ | High CVEs | −10 each (max −30) |
178
+ | Moderate CVEs | −3 each |
179
+ | Web stack with 0 routes detected | −8 |
180
+ | Dirty git working tree | −3 |
181
+ | Missing `.env.example` | −2 |
182
+ | Major outdated packages | −3 each |
183
+
184
+ Example terminal output:
185
+
186
+ ```
187
+ Health: [████████░░] 82/100 grade B
188
+ ```
189
+
190
+ The score is also sent to Sublyzer as a `snapshot_health_score` performance metric.
191
+
192
+ ---
193
+
194
+ ## 🔍 What gets detected
195
+
196
+ | Stack | Signals |
197
+ |-------|---------|
198
+ | **Next.js** | `next` in package.json, `app/` & `pages/` routes |
199
+ | **NestJS** | `@nestjs/core`, decorator routes |
200
+ | **Express / Fastify** | Route patterns in source |
201
+ | **Remix / Nuxt / SvelteKit** | package.json dependencies |
202
+ | **React / Vue / Node** | Fallback detection |
203
+ | **Monorepos** | npm & pnpm workspaces |
204
+
205
+ Each `run` sends:
206
+
207
+ - `custom_event` → `project_snapshot` (stack, routes, git, audit summary)
208
+ - `vulnerability` → top npm audit findings
209
+ - `performance` → health score + route count
210
+
211
+ ---
212
+
213
+ ## 🔄 CI/CD
214
+
215
+ ### Fail the build on vulnerabilities
216
+
217
+ ```bash
218
+ sublyzer-snapshot run --fail-on high --json > snapshot-result.json
219
+ ```
220
+
221
+ Levels: `critical` · `high` · `moderate` · `any`
222
+
223
+ ### Generate GitHub Actions workflow
224
+
225
+ ```bash
226
+ sublyzer-snapshot ci --out .github/workflows/sublyzer-snapshot.yml
227
+ ```
228
+
229
+ Add repository secret: **`SUBLYZER_INTEGRATION_CODE`**
230
+
231
+ The generated workflow runs on push, PR, and weekly schedule — uploads JSON + Markdown report as artifacts.
232
+
233
+ ---
234
+
235
+ ## 🤖 Read data back (agents & API)
236
+
237
+ Push uses the **integration code**. To **read** snapshot data programmatically (e.g. Hermes):
238
+
239
+ ```bash
240
+ # Get read key (authenticated)
241
+ curl "https://api.sublyzer.com/integrations/{id}/read-access" \
242
+ -H "Authorization: Bearer YOUR_JWT"
243
+
244
+ # Or via CLI
245
+ sublyzer-snapshot pull --read-key YOUR_READ_KEY
246
+ ```
247
+
248
+ Set `SUBLYZER_READ_KEY` in env or save during `init --read-key ...`.
249
+
250
+ ---
251
+
252
+ ## 🔐 Environment variables
253
+
254
+ | Variable | Required | Description |
255
+ |----------|----------|-------------|
256
+ | `SUBLYZER_INTEGRATION_CODE` | For `init` | 24-character integration code |
257
+ | `SUBLYZER_READ_KEY` | For `pull` | Public read API key |
258
+ | `SUBLYZER_API_URL` | No | Default: `https://api.sublyzer.com` |
259
+ | `SUBLYZER_DASHBOARD_URL` | No | Default: `https://sublyzer.com` |
260
+
261
+ > **Security:** `.sublyzer/snapshot.json` contains your integration code. It is auto-added to `.gitignore` on `init` — never commit it to public repos.
262
+
263
+ ---
264
+
265
+ ## 📁 Project structure (local)
266
+
267
+ ```
268
+ your-project/
269
+ ├── .sublyzer/
270
+ │ ├── snapshot.json # Linked integration config
271
+ │ ├── last-snapshot.json # Latest scan cache
272
+ │ └── history/ # Previous scans (for compare)
273
+ ├── src/
274
+ └── package.json
275
+ ```
276
+
277
+ ---
278
+
279
+ ## 🛣️ Roadmap
280
+
281
+ - [ ] npm publish (`npx sublyzer-snapshot`)
282
+ - [ ] `login` flow (no manual code paste)
283
+ - [ ] Bundle size analysis
284
+ - [ ] PR comment bot (GitHub App)
285
+
286
+ ---
287
+
288
+ ## 📄 License
289
+
290
+ MIT © [Sublyzer](https://sublyzer.com) — see [LICENSE](./LICENSE).
291
+
292
+ ---
293
+
294
+ <div align="center">
295
+
296
+ **[Sublyzer](https://sublyzer.com)** · **[Documentation](https://sublyzer.com/docs)** · **[Dashboard](https://sublyzer.com/dashboard)**
297
+
298
+ <br />
299
+
300
+ If this saved you time, ⭐ star the repo — it helps other devs find it.
301
+
302
+ <br />
303
+
304
+ <sub>Built with TypeScript · Powered by <a href="https://sublyzer.com">Sublyzer</a> observability platform</sub>
305
+
306
+ </div>
@@ -0,0 +1,29 @@
1
+ import type { CollectItem } from '../scan/snapshot.js';
2
+ export type ValidateResult = {
3
+ success: boolean;
4
+ valid: boolean;
5
+ integration?: {
6
+ id: string;
7
+ name: string;
8
+ status: string;
9
+ };
10
+ message?: string;
11
+ };
12
+ export type PublicReadOptions = {
13
+ limit?: number;
14
+ windowDays?: number;
15
+ include?: string[];
16
+ };
17
+ export declare function validateIntegrationCode(apiUrl: string, integrationCode: string): Promise<ValidateResult>;
18
+ export declare function pushSnapshot(apiUrl: string, integrationCode: string, items: CollectItem[]): Promise<{
19
+ success: boolean;
20
+ processed?: number;
21
+ error?: string;
22
+ }>;
23
+ export declare function fetchPublicSnapshot(apiUrl: string, integrationCode: string, readKey: string, opts?: PublicReadOptions): Promise<{
24
+ ok: boolean;
25
+ status: number;
26
+ data?: unknown;
27
+ error?: string;
28
+ }>;
29
+ //# sourceMappingURL=sublyzer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sublyzer.d.ts","sourceRoot":"","sources":["../../src/api/sublyzer.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAEvD,MAAM,MAAM,cAAc,GAAG;IAC3B,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,EAAE,OAAO,CAAC;IACf,WAAW,CAAC,EAAE;QACZ,EAAE,EAAE,MAAM,CAAC;QACX,IAAI,EAAE,MAAM,CAAC;QACb,MAAM,EAAE,MAAM,CAAC;KAChB,CAAC;IACF,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB,CAAC;AAEF,MAAM,MAAM,iBAAiB,GAAG;IAC9B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;CACpB,CAAC;AAEF,wBAAsB,uBAAuB,CAAC,MAAM,EAAE,MAAM,EAAE,eAAe,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC,CAI9G;AAED,wBAAsB,YAAY,CAChC,MAAM,EAAE,MAAM,EACd,eAAe,EAAE,MAAM,EACvB,KAAK,EAAE,WAAW,EAAE,GACnB,OAAO,CAAC;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CA6BnE;AAED,wBAAsB,mBAAmB,CACvC,MAAM,EAAE,MAAM,EACd,eAAe,EAAE,MAAM,EACvB,OAAO,EAAE,MAAM,EACf,IAAI,GAAE,iBAAsB,GAC3B,OAAO,CAAC;IAAE,EAAE,EAAE,OAAO,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CAyB1E"}
@@ -0,0 +1,61 @@
1
+ import { SDK_NAME, SDK_VERSION } from '../constants.js';
2
+ export async function validateIntegrationCode(apiUrl, integrationCode) {
3
+ const base = apiUrl.replace(/\/$/, '');
4
+ const res = await fetch(`${base}/data-collection/integration/${integrationCode}/validate`);
5
+ return (await res.json());
6
+ }
7
+ export async function pushSnapshot(apiUrl, integrationCode, items) {
8
+ const base = apiUrl.replace(/\/$/, '');
9
+ const res = await fetch(`${base}/data-collection/collect-batch`, {
10
+ method: 'POST',
11
+ headers: { 'Content-Type': 'application/json' },
12
+ body: JSON.stringify({
13
+ integrationCode,
14
+ sdkName: SDK_NAME,
15
+ sdkVersion: SDK_VERSION,
16
+ data: items,
17
+ }),
18
+ });
19
+ let body = {};
20
+ try {
21
+ body = await res.json();
22
+ }
23
+ catch {
24
+ body = {};
25
+ }
26
+ if (!res.ok) {
27
+ return { success: false, error: body?.message || body?.error || `HTTP ${res.status}` };
28
+ }
29
+ return {
30
+ success: body?.success !== false,
31
+ processed: body?.processed ?? items.length,
32
+ error: body?.error,
33
+ };
34
+ }
35
+ export async function fetchPublicSnapshot(apiUrl, integrationCode, readKey, opts = {}) {
36
+ const base = apiUrl.replace(/\/$/, '');
37
+ const url = new URL(`${base}/data-collection/integration/${integrationCode}/data`);
38
+ url.searchParams.set('key', readKey);
39
+ if (opts.limit != null)
40
+ url.searchParams.set('limit', String(opts.limit));
41
+ if (opts.windowDays != null)
42
+ url.searchParams.set('windowDays', String(opts.windowDays));
43
+ if (opts.include?.length)
44
+ url.searchParams.set('include', opts.include.join(','));
45
+ const res = await fetch(url.toString());
46
+ let data;
47
+ try {
48
+ data = await res.json();
49
+ }
50
+ catch {
51
+ data = null;
52
+ }
53
+ if (!res.ok) {
54
+ const errMsg = data?.message ||
55
+ data?.error ||
56
+ (typeof data === 'object' && data && 'statusCode' in data ? JSON.stringify(data) : `HTTP ${res.status}`);
57
+ return { ok: false, status: res.status, error: String(errMsg) };
58
+ }
59
+ return { ok: true, status: res.status, data };
60
+ }
61
+ //# sourceMappingURL=sublyzer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sublyzer.js","sourceRoot":"","sources":["../../src/api/sublyzer.ts"],"names":[],"mappings":"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"}
package/dist/cli.d.ts ADDED
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=cli.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":""}
package/dist/cli.js ADDED
@@ -0,0 +1,199 @@
1
+ #!/usr/bin/env node
2
+ import { Command } from 'commander';
3
+ import { SDK_NAME, SDK_VERSION } from './constants.js';
4
+ import { runCi } from './commands/ci.js';
5
+ import { runCompare } from './commands/compare.js';
6
+ import { runDoctor } from './commands/doctor.js';
7
+ import { runInit } from './commands/init.js';
8
+ import { runOpen } from './commands/open.js';
9
+ import { runPull } from './commands/pull.js';
10
+ import { runReport } from './commands/report.js';
11
+ import { runScan } from './commands/run.js';
12
+ import { runStatus } from './commands/status.js';
13
+ const program = new Command();
14
+ function handleError(e) {
15
+ const msg = e instanceof Error ? e.message : String(e);
16
+ console.error(`\x1b[31m✗\x1b[0m ${msg}`);
17
+ process.exit(1);
18
+ }
19
+ const FAIL_ON_LEVELS = ['critical', 'high', 'moderate', 'any'];
20
+ program
21
+ .name('sublyzer-snapshot')
22
+ .description('Scan any project and push a health snapshot to Sublyzer')
23
+ .version(SDK_VERSION);
24
+ program
25
+ .command('init')
26
+ .description('Detect stack and link this project to your Sublyzer integration')
27
+ .option('--code <code>', 'Integration code (24 chars); or SUBLYZER_INTEGRATION_CODE')
28
+ .option('--read-key <key>', 'Optional apiReadKey for pull; or SUBLYZER_READ_KEY')
29
+ .option('--api-url <url>', 'Sublyzer API base URL')
30
+ .option('--dashboard-url <url>', 'Dashboard base URL')
31
+ .option('-y, --yes', 'Non-interactive when code is provided')
32
+ .option('--skip-gitignore', 'Do not update .gitignore')
33
+ .action(async (opts) => {
34
+ try {
35
+ await runInit({
36
+ code: opts.code,
37
+ readKey: opts.readKey,
38
+ apiUrl: opts.apiUrl,
39
+ dashboardUrl: opts.dashboardUrl,
40
+ yes: opts.yes,
41
+ skipGitignore: opts.skipGitignore,
42
+ });
43
+ }
44
+ catch (e) {
45
+ handleError(e);
46
+ }
47
+ });
48
+ program
49
+ .command('run')
50
+ .description('Scan routes, dependencies, vulnerabilities and push to Sublyzer')
51
+ .option('--dry-run', 'Scan locally without sending data')
52
+ .option('--skip-audit', 'Skip npm audit (faster)')
53
+ .option('--skip-outdated', 'Skip npm outdated check')
54
+ .option('--json', 'Output machine-readable JSON (CI friendly)')
55
+ .option('--fail-on <level>', 'Exit 1 if vulns at level: critical|high|moderate|any')
56
+ .action(async (opts) => {
57
+ try {
58
+ const failOn = FAIL_ON_LEVELS.includes(opts.failOn) ? opts.failOn : undefined;
59
+ const result = await runScan({
60
+ dryRun: opts.dryRun,
61
+ skipAudit: opts.skipAudit,
62
+ skipOutdated: opts.skipOutdated,
63
+ json: opts.json,
64
+ failOn,
65
+ });
66
+ if (opts.json)
67
+ console.log(JSON.stringify(result, null, 2));
68
+ if (result.policyFailed)
69
+ process.exit(1);
70
+ }
71
+ catch (e) {
72
+ handleError(e);
73
+ }
74
+ });
75
+ program
76
+ .command('status')
77
+ .description('Show linked integration and last scan summary')
78
+ .option('--json', 'Output machine-readable JSON')
79
+ .action(async (opts) => {
80
+ try {
81
+ const data = await runStatus({ json: opts.json });
82
+ if (opts.json)
83
+ console.log(JSON.stringify(data, null, 2));
84
+ }
85
+ catch (e) {
86
+ handleError(e);
87
+ }
88
+ });
89
+ program
90
+ .command('doctor')
91
+ .description('Verify config, API connectivity, integration code and read key')
92
+ .option('--json', 'Output machine-readable JSON')
93
+ .action(async (opts) => {
94
+ try {
95
+ const result = await runDoctor({ json: opts.json });
96
+ if (opts.json)
97
+ console.log(JSON.stringify(result, null, 2));
98
+ if (!result.ok)
99
+ process.exit(1);
100
+ }
101
+ catch (e) {
102
+ handleError(e);
103
+ }
104
+ });
105
+ program
106
+ .command('compare')
107
+ .description('Diff current vs previous scan (routes, vulns, health score)')
108
+ .option('--json', 'Output machine-readable JSON')
109
+ .option('--rescan', 'Run a fresh scan before comparing')
110
+ .option('--skip-audit', 'Skip audit when using --rescan')
111
+ .action(async (opts) => {
112
+ try {
113
+ const data = await runCompare({
114
+ json: opts.json,
115
+ rescan: opts.rescan,
116
+ skipAudit: opts.skipAudit,
117
+ });
118
+ if (opts.json)
119
+ console.log(JSON.stringify(data, null, 2));
120
+ }
121
+ catch (e) {
122
+ handleError(e);
123
+ }
124
+ });
125
+ program
126
+ .command('report')
127
+ .description('Generate a Markdown health report (stdout or --out file)')
128
+ .option('--out <file>', 'Write report to file (e.g. sublyzer-report.md)')
129
+ .option('--rescan', 'Run a fresh scan instead of using last cached scan')
130
+ .option('--skip-audit', 'Skip audit when using --rescan')
131
+ .option('--json', 'Output JSON wrapper with markdown body')
132
+ .action(async (opts) => {
133
+ try {
134
+ const out = await runReport({
135
+ out: opts.out,
136
+ rescan: opts.rescan,
137
+ skipAudit: opts.skipAudit,
138
+ json: opts.json,
139
+ });
140
+ if (opts.json)
141
+ console.log(out);
142
+ }
143
+ catch (e) {
144
+ handleError(e);
145
+ }
146
+ });
147
+ program
148
+ .command('ci')
149
+ .description('Print or write a GitHub Actions workflow for automated snapshots')
150
+ .option('--out <path>', 'Write workflow file (default: .github/workflows/sublyzer-snapshot.yml)')
151
+ .option('--print', 'Print template to stdout only')
152
+ .action(async (opts) => {
153
+ try {
154
+ await runCi({ out: opts.out, print: opts.print ?? !opts.out });
155
+ }
156
+ catch (e) {
157
+ handleError(e);
158
+ }
159
+ });
160
+ program
161
+ .command('pull')
162
+ .description('Fetch integration data from Sublyzer (requires apiReadKey)')
163
+ .option('--read-key <key>', 'apiReadKey; or SUBLYZER_READ_KEY in env/config')
164
+ .option('--limit <n>', 'Max events', (v) => parseInt(v, 10))
165
+ .option('--window-days <n>', 'Lookback window in days', (v) => parseInt(v, 10))
166
+ .option('--include <csv>', 'stats,events,telemetry,performance,sdkStatus,activeErrors')
167
+ .option('--json', 'Output raw API JSON only')
168
+ .action(async (opts) => {
169
+ try {
170
+ const data = await runPull({
171
+ readKey: opts.readKey,
172
+ limit: opts.limit,
173
+ windowDays: opts.windowDays,
174
+ include: opts.include,
175
+ json: opts.json,
176
+ });
177
+ if (opts.json)
178
+ console.log(JSON.stringify(data, null, 2));
179
+ }
180
+ catch (e) {
181
+ handleError(e);
182
+ }
183
+ });
184
+ program
185
+ .command('open')
186
+ .description('Open the Sublyzer dashboard for this integration')
187
+ .action(async () => {
188
+ try {
189
+ await runOpen();
190
+ }
191
+ catch (e) {
192
+ handleError(e);
193
+ }
194
+ });
195
+ program.parseAsync(process.argv).catch((e) => {
196
+ console.error(`[${SDK_NAME}]`, e);
197
+ process.exit(1);
198
+ });
199
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ export type CiOptions = {
2
+ out?: string;
3
+ print?: boolean;
4
+ };
5
+ export declare function runCi(opts?: CiOptions): Promise<{
6
+ path: string;
7
+ content: string;
8
+ }>;
9
+ //# sourceMappingURL=ci.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ci.d.ts","sourceRoot":"","sources":["../../src/commands/ci.ts"],"names":[],"mappings":"AAgDA,MAAM,MAAM,SAAS,GAAG;IACtB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB,CAAC;AAEF,wBAAsB,KAAK,CAAC,IAAI,GAAE,SAAc,GAAG,OAAO,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC,CAmB5F"}