@datasynx/agentic-ai-cartography 1.1.0 → 2.0.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 (51) hide show
  1. package/README.md +197 -33
  2. package/dist/bookmarks-VS56KVCO.js +25 -0
  3. package/dist/chunk-CJ2PITFA.js +785 -0
  4. package/dist/chunk-CJ2PITFA.js.map +1 -0
  5. package/dist/chunk-D6SRSLBF.js +48 -0
  6. package/dist/{chunk-WJR63RWY.js → chunk-J6FDZ6HZ.js} +11 -2
  7. package/dist/chunk-J6FDZ6HZ.js.map +1 -0
  8. package/dist/chunk-UGSNG3QJ.js +49 -0
  9. package/dist/chunk-UGSNG3QJ.js.map +1 -0
  10. package/dist/chunk-W7YE6AAH.js +1516 -0
  11. package/dist/chunk-W7YE6AAH.js.map +1 -0
  12. package/dist/cli.js +133 -664
  13. package/dist/cli.js.map +1 -1
  14. package/dist/index.cjs +60115 -0
  15. package/dist/index.cjs.map +1 -0
  16. package/dist/index.d.cts +734 -0
  17. package/dist/index.d.ts +363 -7
  18. package/dist/index.js +1462 -161
  19. package/dist/index.js.map +1 -1
  20. package/dist/mcp-bin.js +33 -0
  21. package/dist/mcp-bin.js.map +1 -0
  22. package/dist/onnxruntime_binding-6Q6HXASN.node +0 -0
  23. package/dist/onnxruntime_binding-EKZT2NRK.node +0 -0
  24. package/dist/onnxruntime_binding-P6S7V3CI.node +0 -0
  25. package/dist/onnxruntime_binding-PJNNIIUO.node +0 -0
  26. package/dist/onnxruntime_binding-UN6SPTQK.node +0 -0
  27. package/dist/sdk-A6NLO3DJ.js +12294 -0
  28. package/dist/sdk-A6NLO3DJ.js.map +1 -0
  29. package/dist/sdk-G5D4WQZ4.js +12293 -0
  30. package/dist/sdk-G5D4WQZ4.js.map +1 -0
  31. package/dist/sdk-QSTAREST.js +4869 -0
  32. package/dist/sdk-QSTAREST.js.map +1 -0
  33. package/dist/sqlite-vec-EZN67B2V.js +40 -0
  34. package/dist/sqlite-vec-EZN67B2V.js.map +1 -0
  35. package/dist/sqlite-vec-UK5YYE5T.js +39 -0
  36. package/dist/sqlite-vec-UK5YYE5T.js.map +1 -0
  37. package/dist/transformers.node-BTYUTJK5.js +42884 -0
  38. package/dist/transformers.node-BTYUTJK5.js.map +1 -0
  39. package/dist/transformers.node-J6PRTTOX.js +42883 -0
  40. package/dist/transformers.node-J6PRTTOX.js.map +1 -0
  41. package/dist/{types-54623ALF.js → types-JG27FR3E.js} +5 -2
  42. package/dist/types-JG27FR3E.js.map +1 -0
  43. package/package.json +53 -17
  44. package/scripts/postinstall.mjs +7 -0
  45. package/server.json +28 -0
  46. package/dist/bookmarks-BWNVQGPG.js +0 -14
  47. package/dist/chunk-QKNYI3SU.js +0 -459
  48. package/dist/chunk-QKNYI3SU.js.map +0 -1
  49. package/dist/chunk-WJR63RWY.js.map +0 -1
  50. /package/dist/{bookmarks-BWNVQGPG.js.map → bookmarks-VS56KVCO.js.map} +0 -0
  51. /package/dist/{types-54623ALF.js.map → chunk-D6SRSLBF.js.map} +0 -0
@@ -8,9 +8,11 @@ import {
8
8
  EDGE_RELATIONSHIPS,
9
9
  EdgeSchema,
10
10
  NODE_TYPES,
11
+ NODE_TYPE_GROUPS,
11
12
  NodeSchema,
12
13
  defaultConfig
13
- } from "./chunk-WJR63RWY.js";
14
+ } from "./chunk-J6FDZ6HZ.js";
15
+ import "./chunk-UGSNG3QJ.js";
14
16
  export {
15
17
  ClusterSchema,
16
18
  ConnectionSchema,
@@ -20,7 +22,8 @@ export {
20
22
  EDGE_RELATIONSHIPS,
21
23
  EdgeSchema,
22
24
  NODE_TYPES,
25
+ NODE_TYPE_GROUPS,
23
26
  NodeSchema,
24
27
  defaultConfig
25
28
  };
26
- //# sourceMappingURL=types-54623ALF.js.map
29
+ //# sourceMappingURL=types-JG27FR3E.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
package/package.json CHANGED
@@ -1,19 +1,34 @@
1
1
  {
2
2
  "name": "@datasynx/agentic-ai-cartography",
3
- "version": "1.1.0",
4
- "description": "AI-powered infrastructure cartography CLI built on Claude Agent SDK",
3
+ "version": "2.0.0",
4
+ "description": "MCP-first infrastructure & agentic-AI cartography — install once, every AI agent knows your system landscape. Read-only discovery exposed over the Model Context Protocol.",
5
5
  "type": "module",
6
+ "sideEffects": false,
7
+ "mcpName": "io.github.datasynx/cartography",
8
+ "main": "./dist/index.cjs",
9
+ "module": "./dist/index.js",
10
+ "types": "./dist/index.d.ts",
6
11
  "bin": {
7
- "datasynx-cartography": "./dist/cli.js"
12
+ "datasynx-cartography": "./dist/cli.js",
13
+ "cartography-mcp": "./dist/mcp-bin.js"
8
14
  },
9
15
  "exports": {
10
16
  ".": {
11
- "import": "./dist/index.js",
12
- "types": "./dist/index.d.ts"
13
- }
17
+ "import": {
18
+ "types": "./dist/index.d.ts",
19
+ "default": "./dist/index.js"
20
+ },
21
+ "require": {
22
+ "types": "./dist/index.d.cts",
23
+ "default": "./dist/index.cjs"
24
+ }
25
+ },
26
+ "./package.json": "./package.json"
14
27
  },
15
28
  "files": [
16
29
  "dist",
30
+ "scripts",
31
+ "server.json",
17
32
  "README.md",
18
33
  "LICENSE"
19
34
  ],
@@ -24,8 +39,10 @@
24
39
  "test:watch": "vitest",
25
40
  "test:coverage": "vitest run --coverage",
26
41
  "lint": "tsc --noEmit",
42
+ "typecheck": "tsc --noEmit",
43
+ "release": "semantic-release",
27
44
  "prepublishOnly": "npm run lint && npm run test && npm run build",
28
- "postinstall": "node -e \"try{require('child_process').execSync('claude --version',{stdio:'pipe'})}catch{console.warn('\\n⚠ datasynx-cartography requires Claude CLI: npm i -g @anthropic-ai/claude-code\\n')}\""
45
+ "postinstall": "node scripts/postinstall.mjs"
29
46
  },
30
47
  "engines": {
31
48
  "node": ">=20.0.0"
@@ -34,14 +51,18 @@
34
51
  "infrastructure",
35
52
  "cartography",
36
53
  "discovery",
37
- "sop",
38
- "claude",
54
+ "topology",
39
55
  "ai-agent",
56
+ "agentic-ai",
57
+ "mcp",
40
58
  "devops",
59
+ "platform-engineering",
41
60
  "mermaid",
42
61
  "backstage",
62
+ "cmdb",
43
63
  "network-topology",
44
- "observability"
64
+ "observability",
65
+ "shadow-it"
45
66
  ],
46
67
  "author": {
47
68
  "name": "Datasynx AI",
@@ -49,29 +70,44 @@
49
70
  },
50
71
  "repository": {
51
72
  "type": "git",
52
- "url": "https://github.com/datasynx/agentic-ai-cartography.git"
73
+ "url": "git+https://github.com/datasynx/agentic-ai-cartography.git"
53
74
  },
54
75
  "homepage": "https://github.com/datasynx/agentic-ai-cartography#readme",
55
76
  "bugs": {
56
77
  "url": "https://github.com/datasynx/agentic-ai-cartography/issues"
57
78
  },
79
+ "publishConfig": {
80
+ "access": "public",
81
+ "provenance": true
82
+ },
58
83
  "license": "MIT",
59
84
  "dependencies": {
60
- "@anthropic-ai/claude-agent-sdk": "^0.2.59",
61
- "@anthropic-ai/sdk": "^0.78.0",
85
+ "@modelcontextprotocol/sdk": "^1.29.0",
62
86
  "better-sqlite3": "^12.6.0",
63
87
  "commander": "^14.0.0",
64
- "ora": "^9.3.0",
65
- "picocolors": "^1.1.1",
66
88
  "zod": "^4.3.6"
67
89
  },
90
+ "optionalDependencies": {
91
+ "@anthropic-ai/claude-agent-sdk": "^0.2.59",
92
+ "@anthropic-ai/sdk": "^0.78.0",
93
+ "@huggingface/transformers": "^4.2.0",
94
+ "sqlite-vec": "^0.1.9"
95
+ },
68
96
  "devDependencies": {
97
+ "@arethetypeswrong/cli": "^0.18.2",
98
+ "@semantic-release/changelog": "^6.0.3",
99
+ "@semantic-release/git": "^10.0.1",
100
+ "@semantic-release/github": "^11.0.1",
101
+ "@semantic-release/npm": "^12.0.1",
69
102
  "@types/better-sqlite3": "^7.6.12",
70
103
  "@types/node": "^22.10.0",
71
- "@vitest/coverage-v8": "^3.2.4",
104
+ "@vitest/coverage-v8": "^4.1.0",
105
+ "license-checker": "^25.0.1",
106
+ "publint": "^0.3.0",
107
+ "semantic-release": "^24.2.0",
72
108
  "tsup": "^8.3.0",
73
109
  "tsx": "^4.19.0",
74
110
  "typescript": "^5.7.2",
75
- "vitest": "^3.0.0"
111
+ "vitest": "^4.1.0"
76
112
  }
77
113
  }
@@ -0,0 +1,7 @@
1
+ import { execSync } from 'child_process';
2
+
3
+ try {
4
+ execSync('claude --version', { stdio: 'pipe' });
5
+ } catch {
6
+ console.warn('\n\u26A0 datasynx-cartography requires Claude CLI: npm i -g @anthropic-ai/claude-code\n');
7
+ }
package/server.json ADDED
@@ -0,0 +1,28 @@
1
+ {
2
+ "$schema": "https://static.modelcontextprotocol.io/schemas/2025-09-08/server.schema.json",
3
+ "name": "io.github.datasynx/cartography",
4
+ "description": "MCP-first infrastructure & agentic-AI cartography — read-only discovery of your system landscape (services, databases, SaaS tools, dependencies) exposed as MCP resources, tools and prompts.",
5
+ "version": "2.0.0",
6
+ "repository": {
7
+ "url": "https://github.com/datasynx/agentic-ai-cartography",
8
+ "source": "github"
9
+ },
10
+ "packages": [
11
+ {
12
+ "registryType": "npm",
13
+ "registryBaseUrl": "https://registry.npmjs.org",
14
+ "identifier": "@datasynx/agentic-ai-cartography",
15
+ "version": "2.0.0",
16
+ "runtimeHint": "npx",
17
+ "transport": { "type": "stdio" },
18
+ "runtimeArguments": [
19
+ { "type": "named", "name": "--package", "value": "@datasynx/agentic-ai-cartography", "isRequired": true },
20
+ { "type": "positional", "value": "cartography-mcp", "isRequired": true }
21
+ ],
22
+ "packageArguments": [
23
+ { "type": "named", "name": "--db", "description": "Path to the SQLite catalog", "isRequired": false },
24
+ { "type": "named", "name": "--session", "description": "Session id to serve, or 'latest'", "isRequired": false }
25
+ ]
26
+ }
27
+ ]
28
+ }
@@ -1,14 +0,0 @@
1
- #!/usr/bin/env node
2
- import {
3
- cleanupTempFiles,
4
- readFirefoxHistory,
5
- scanAllBookmarks,
6
- scanAllHistory
7
- } from "./chunk-QKNYI3SU.js";
8
- export {
9
- cleanupTempFiles,
10
- readFirefoxHistory,
11
- scanAllBookmarks,
12
- scanAllHistory
13
- };
14
- //# sourceMappingURL=bookmarks-BWNVQGPG.js.map
@@ -1,459 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- // src/bookmarks.ts
4
- import { tmpdir } from "os";
5
- import { existsSync as existsSync2, readFileSync, readdirSync, copyFileSync, statSync, unlinkSync } from "fs";
6
- import { join as join2 } from "path";
7
-
8
- // src/platform.ts
9
- import { homedir } from "os";
10
- import { join } from "path";
11
- import { execSync } from "child_process";
12
- import { existsSync } from "fs";
13
- var PLATFORM = process.platform;
14
- var IS_WIN = PLATFORM === "win32";
15
- var IS_MAC = PLATFORM === "darwin";
16
- var IS_LINUX = PLATFORM === "linux";
17
- var HOME = homedir();
18
- function platformShell() {
19
- if (!IS_WIN) return "/bin/sh";
20
- try {
21
- execSync("pwsh -Version", { stdio: "pipe", timeout: 3e3 });
22
- return "pwsh";
23
- } catch {
24
- return "powershell.exe";
25
- }
26
- }
27
- var _shell;
28
- function getShell() {
29
- if (!_shell) _shell = platformShell();
30
- return _shell;
31
- }
32
- var SAFE_ENV_KEYS = [
33
- "PATH",
34
- "HOME",
35
- "USER",
36
- "LANG",
37
- "LC_ALL",
38
- "TERM",
39
- "SHELL",
40
- "USERPROFILE",
41
- "LOCALAPPDATA",
42
- "APPDATA",
43
- "PROGRAMFILES",
44
- "XDG_CONFIG_HOME",
45
- "XDG_DATA_HOME",
46
- "XDG_RUNTIME_DIR",
47
- "AWS_DEFAULT_REGION",
48
- "AWS_PROFILE",
49
- "AWS_CONFIG_FILE",
50
- "KUBECONFIG",
51
- "GOOGLE_APPLICATION_CREDENTIALS",
52
- "AZURE_CONFIG_DIR"
53
- ];
54
- function safeEnv() {
55
- const env = {};
56
- for (const key of SAFE_ENV_KEYS) {
57
- if (process.env[key]) env[key] = process.env[key];
58
- }
59
- return env;
60
- }
61
- function run(cmd, opts = {}) {
62
- try {
63
- return execSync(cmd, {
64
- stdio: "pipe",
65
- timeout: opts.timeout ?? 1e4,
66
- shell: getShell(),
67
- env: opts.env ?? safeEnv()
68
- }).toString().trim();
69
- } catch {
70
- return "";
71
- }
72
- }
73
- function commandExists(cmd) {
74
- if (IS_WIN) {
75
- const r = run(`Get-Command ${cmd} -ErrorAction SilentlyContinue | Select-Object -ExpandProperty Source`, { timeout: 5e3 });
76
- return r;
77
- }
78
- return run(`which ${cmd} 2>/dev/null`);
79
- }
80
- function userDataDir() {
81
- if (IS_WIN) return process.env.APPDATA ?? join(HOME, "AppData", "Roaming");
82
- if (IS_MAC) return join(HOME, "Library", "Application Support");
83
- return process.env.XDG_DATA_HOME ?? join(HOME, ".local", "share");
84
- }
85
- function browserBasePaths() {
86
- if (IS_WIN) {
87
- const local = process.env.LOCALAPPDATA ?? join(HOME, "AppData", "Local");
88
- return {
89
- chrome: join(local, "Google", "Chrome", "User Data"),
90
- chromium: join(local, "Chromium", "User Data"),
91
- edge: join(local, "Microsoft", "Edge", "User Data"),
92
- brave: join(local, "BraveSoftware", "Brave-Browser", "User Data"),
93
- vivaldi: join(local, "Vivaldi", "User Data"),
94
- opera: join(userDataDir(), "Opera Software", "Opera Stable")
95
- };
96
- }
97
- if (IS_MAC) {
98
- const lib = join(HOME, "Library", "Application Support");
99
- return {
100
- chrome: join(lib, "Google", "Chrome"),
101
- chromium: join(lib, "Chromium"),
102
- edge: join(lib, "Microsoft Edge"),
103
- brave: join(lib, "BraveSoftware", "Brave-Browser"),
104
- vivaldi: join(lib, "Vivaldi"),
105
- opera: join(lib, "com.operasoftware.Opera")
106
- };
107
- }
108
- return {
109
- chrome: join(HOME, ".config", "google-chrome"),
110
- chromium: join(HOME, ".config", "chromium"),
111
- edge: join(HOME, ".config", "microsoft-edge"),
112
- brave: join(HOME, ".config", "BraveSoftware", "Brave-Browser"),
113
- vivaldi: join(HOME, ".config", "vivaldi"),
114
- opera: join(HOME, ".config", "opera")
115
- };
116
- }
117
- function firefoxBaseDirs() {
118
- if (IS_WIN) {
119
- const roaming = process.env.APPDATA ?? join(HOME, "AppData", "Roaming");
120
- return [join(roaming, "Mozilla", "Firefox", "Profiles")];
121
- }
122
- if (IS_MAC) {
123
- return [join(HOME, "Library", "Application Support", "Firefox", "Profiles")];
124
- }
125
- return [
126
- join(HOME, ".mozilla", "firefox"),
127
- join(HOME, "snap", "firefox", "common", ".mozilla", "firefox"),
128
- join(HOME, ".var", "app", "org.mozilla.firefox", ".mozilla", "firefox")
129
- ];
130
- }
131
- function dbScanDirs() {
132
- const dirs = [];
133
- if (IS_WIN) {
134
- const local = process.env.LOCALAPPDATA ?? join(HOME, "AppData", "Local");
135
- const roaming = process.env.APPDATA ?? join(HOME, "AppData", "Roaming");
136
- dirs.push(local, roaming);
137
- const pd = join(HOME, "AppData", "Local", "Programs");
138
- if (existsSync(pd)) dirs.push(pd);
139
- } else if (IS_MAC) {
140
- dirs.push(join(HOME, "Library", "Application Support"));
141
- if (existsSync("/var/lib")) dirs.push("/var/lib");
142
- } else {
143
- const configDir = join(HOME, ".config");
144
- const dataDir = join(HOME, ".local", "share");
145
- if (existsSync(configDir)) dirs.push(configDir);
146
- if (existsSync(dataDir)) dirs.push(dataDir);
147
- if (existsSync("/var/lib")) dirs.push("/var/lib");
148
- }
149
- return dirs.filter((d) => existsSync(d));
150
- }
151
- function findFiles(dirs, patterns, maxDepth, limit) {
152
- if (dirs.length === 0) return "";
153
- if (IS_WIN) {
154
- const includes = patterns.map((p) => `'${p}'`).join(",");
155
- const pathList = dirs.map((d) => `'${d}'`).join(",");
156
- return run(
157
- `Get-ChildItem -Path ${pathList} -Recurse -Depth ${maxDepth} -Include ${includes} -ErrorAction SilentlyContinue | Select-Object -First ${limit} -ExpandProperty FullName`,
158
- { timeout: 15e3 }
159
- );
160
- }
161
- const nameArgs = patterns.map((p) => `-name "${p}"`).join(" -o ");
162
- const findCmds = dirs.map((d) => `find "${d}" -maxdepth ${maxDepth} \\( ${nameArgs} \\) 2>/dev/null`).join("; ");
163
- return run(`{ ${findCmds}; } | head -${limit}`, { timeout: 15e3 });
164
- }
165
- function scanWindowsPrograms() {
166
- if (!IS_WIN) return "";
167
- return run(
168
- `$paths = @('HKLM:\\Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\*','HKLM:\\Software\\Wow6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\*','HKCU:\\Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\*'); Get-ItemProperty $paths -ErrorAction SilentlyContinue | Where-Object { $_.DisplayName } | Select-Object -Property DisplayName, Publisher, DisplayVersion | Sort-Object DisplayName | Format-Table -AutoSize | Out-String -Width 300`,
169
- { timeout: 2e4 }
170
- );
171
- }
172
- function scanWindowsDbServices() {
173
- if (!IS_WIN) return "";
174
- return run(
175
- `Get-Service | Where-Object { $_.Name -match 'postgres|mysql|mariadb|mongo|redis|MSSQL|elastic|clickhouse|cassandra' } | Select-Object Name, DisplayName, Status, StartType | Format-Table -AutoSize`,
176
- { timeout: 1e4 }
177
- );
178
- }
179
-
180
- // src/bookmarks.ts
181
- function cleanupTempFiles() {
182
- let cleaned = 0;
183
- const tmp = tmpdir();
184
- try {
185
- for (const f of readdirSync(tmp)) {
186
- if (f.startsWith("cartograph_") && f.endsWith(".sqlite")) {
187
- try {
188
- unlinkSync(join2(tmp, f));
189
- cleaned++;
190
- } catch {
191
- }
192
- }
193
- }
194
- } catch {
195
- }
196
- return cleaned;
197
- }
198
- function extractHost(rawUrl, source) {
199
- try {
200
- const u = new URL(rawUrl);
201
- if (u.protocol !== "http:" && u.protocol !== "https:") return null;
202
- const protocol = u.protocol === "https:" ? "https" : "http";
203
- const port = u.port ? parseInt(u.port, 10) : protocol === "https" ? 443 : 80;
204
- const hostname = u.hostname.toLowerCase();
205
- if (!hostname || hostname === "localhost" || hostname === "127.0.0.1") return null;
206
- return { hostname, port, protocol, source };
207
- } catch {
208
- return null;
209
- }
210
- }
211
- function walkChrome(node, source, out) {
212
- if (node.type === "url" && node.url) {
213
- const h = extractHost(node.url, source);
214
- if (h) out.push(h);
215
- }
216
- if (node.children) {
217
- for (const child of node.children) walkChrome(child, source, out);
218
- }
219
- }
220
- function readChromeLike(filePath, source) {
221
- if (!existsSync2(filePath)) return [];
222
- try {
223
- const raw = JSON.parse(readFileSync(filePath, "utf8"));
224
- const out = [];
225
- for (const root of Object.values(raw.roots)) {
226
- if (root) walkChrome(root, source, out);
227
- }
228
- return out;
229
- } catch {
230
- return [];
231
- }
232
- }
233
- async function readFirefoxBookmarks(profileDir) {
234
- const src = join2(profileDir, "places.sqlite");
235
- if (!existsSync2(src)) return [];
236
- const tmp = join2(tmpdir(), `cartograph_ff_bm_${Date.now()}.sqlite`);
237
- try {
238
- copyFileSync(src, tmp);
239
- const { default: Database } = await import("better-sqlite3");
240
- const db = new Database(tmp, { readonly: true, fileMustExist: true });
241
- const rows = db.prepare(`
242
- SELECT DISTINCT p.url
243
- FROM moz_places p
244
- JOIN moz_bookmarks b ON b.fk = p.id
245
- WHERE b.type = 1 AND p.url NOT LIKE 'place:%'
246
- LIMIT 3000
247
- `).all();
248
- db.close();
249
- return rows.map((r) => extractHost(r.url, "firefox")).filter((h) => h !== null);
250
- } catch {
251
- return [];
252
- } finally {
253
- try {
254
- (await import("fs")).unlinkSync(tmp);
255
- } catch {
256
- }
257
- }
258
- }
259
- async function readFirefoxHistory(profileDir) {
260
- const src = join2(profileDir, "places.sqlite");
261
- if (!existsSync2(src)) return [];
262
- const tmp = join2(tmpdir(), `cartograph_ff_hist_${Date.now()}.sqlite`);
263
- try {
264
- copyFileSync(src, tmp);
265
- const { default: Database } = await import("better-sqlite3");
266
- const db = new Database(tmp, { readonly: true, fileMustExist: true });
267
- const rows = db.prepare(`
268
- SELECT url, visit_count
269
- FROM moz_places
270
- WHERE url NOT LIKE 'place:%'
271
- AND visit_count > 0
272
- ORDER BY visit_count DESC
273
- LIMIT 5000
274
- `).all();
275
- db.close();
276
- return rows.map((r) => {
277
- const h = extractHost(r.url, "firefox");
278
- if (!h) return null;
279
- return { ...h, visitCount: r.visit_count };
280
- }).filter((h) => h !== null);
281
- } catch {
282
- return [];
283
- } finally {
284
- try {
285
- (await import("fs")).unlinkSync(tmp);
286
- } catch {
287
- }
288
- }
289
- }
290
- async function readChromiumHistory(historyPath, source) {
291
- if (!existsSync2(historyPath)) return [];
292
- const tmp = join2(tmpdir(), `cartograph_ch_hist_${Date.now()}.sqlite`);
293
- try {
294
- copyFileSync(historyPath, tmp);
295
- const { default: Database } = await import("better-sqlite3");
296
- const db = new Database(tmp, { readonly: true, fileMustExist: true });
297
- const rows = db.prepare(`
298
- SELECT url, visit_count
299
- FROM urls
300
- WHERE hidden = 0
301
- AND visit_count > 0
302
- ORDER BY visit_count DESC
303
- LIMIT 5000
304
- `).all();
305
- db.close();
306
- return rows.map((r) => {
307
- const h = extractHost(r.url, source);
308
- if (!h) return null;
309
- return { ...h, visitCount: r.visit_count };
310
- }).filter((h) => h !== null);
311
- } catch {
312
- return [];
313
- } finally {
314
- try {
315
- (await import("fs")).unlinkSync(tmp);
316
- } catch {
317
- }
318
- }
319
- }
320
- var IS_LINUX2 = !IS_MAC && !IS_WIN;
321
- function chromeLikePaths(base) {
322
- const paths = [];
323
- const defaultPath = join2(base, "Default", "Bookmarks");
324
- if (existsSync2(defaultPath)) paths.push(defaultPath);
325
- if (existsSync2(base)) {
326
- try {
327
- for (const entry of readdirSync(base)) {
328
- if (entry.startsWith("Profile ")) {
329
- const p = join2(base, entry, "Bookmarks");
330
- if (existsSync2(p)) paths.push(p);
331
- }
332
- }
333
- } catch {
334
- }
335
- }
336
- return paths;
337
- }
338
- function chromeLikeHistoryPaths(base) {
339
- const paths = [];
340
- const defaultPath = join2(base, "Default", "History");
341
- if (existsSync2(defaultPath)) paths.push(defaultPath);
342
- if (existsSync2(base)) {
343
- try {
344
- for (const entry of readdirSync(base)) {
345
- if (entry.startsWith("Profile ")) {
346
- const p = join2(base, entry, "History");
347
- if (existsSync2(p)) paths.push(p);
348
- }
349
- }
350
- } catch {
351
- }
352
- }
353
- return paths;
354
- }
355
- var BROWSER_BASES = browserBasePaths();
356
- var CHROME_BASE = BROWSER_BASES.chrome;
357
- var CHROMIUM_BASE = BROWSER_BASES.chromium;
358
- var EDGE_BASE = BROWSER_BASES.edge;
359
- var BRAVE_BASE = BROWSER_BASES.brave;
360
- var VIVALDI_BASE = BROWSER_BASES.vivaldi;
361
- var OPERA_BASE = BROWSER_BASES.opera;
362
- var CHROMIUM_SNAP_BASE = join2(HOME, "snap", "chromium", "common", "chromium");
363
- var CHROMIUM_FLATPAK_BASE = join2(HOME, ".var", "app", "org.chromium.Chromium", "config", "chromium");
364
- var CHROME_FLATPAK_BASE = join2(HOME, ".var", "app", "com.google.Chrome", "config", "google-chrome");
365
- var BRAVE_FLATPAK_BASE = join2(HOME, ".var", "app", "com.brave.Browser", "config", "BraveSoftware", "Brave-Browser");
366
- var EDGE_FLATPAK_BASE = join2(HOME, ".var", "app", "com.microsoft.Edge", "config", "microsoft-edge");
367
- function firefoxProfileDirs() {
368
- const bases = firefoxBaseDirs();
369
- const dirs = [];
370
- for (const base of bases) {
371
- if (!existsSync2(base)) continue;
372
- try {
373
- for (const d of readdirSync(base)) {
374
- const full = join2(base, d);
375
- try {
376
- if (statSync(full).isDirectory() && existsSync2(join2(full, "places.sqlite"))) {
377
- dirs.push(full);
378
- }
379
- } catch {
380
- }
381
- }
382
- } catch {
383
- }
384
- }
385
- return dirs;
386
- }
387
- async function scanAllBookmarks() {
388
- const all = [];
389
- for (const p of chromeLikePaths(CHROME_BASE)) all.push(...readChromeLike(p, "chrome"));
390
- for (const p of chromeLikePaths(CHROMIUM_BASE)) all.push(...readChromeLike(p, "chromium"));
391
- for (const p of chromeLikePaths(EDGE_BASE)) all.push(...readChromeLike(p, "edge"));
392
- for (const p of chromeLikePaths(BRAVE_BASE)) all.push(...readChromeLike(p, "brave"));
393
- for (const p of chromeLikePaths(VIVALDI_BASE)) all.push(...readChromeLike(p, "vivaldi"));
394
- for (const p of chromeLikePaths(OPERA_BASE)) all.push(...readChromeLike(p, "opera"));
395
- if (IS_LINUX2) {
396
- for (const p of chromeLikePaths(CHROMIUM_SNAP_BASE)) all.push(...readChromeLike(p, "chromium-snap"));
397
- for (const p of chromeLikePaths(CHROMIUM_FLATPAK_BASE)) all.push(...readChromeLike(p, "chromium-flatpak"));
398
- for (const p of chromeLikePaths(CHROME_FLATPAK_BASE)) all.push(...readChromeLike(p, "chrome-flatpak"));
399
- for (const p of chromeLikePaths(BRAVE_FLATPAK_BASE)) all.push(...readChromeLike(p, "brave-flatpak"));
400
- for (const p of chromeLikePaths(EDGE_FLATPAK_BASE)) all.push(...readChromeLike(p, "edge-flatpak"));
401
- }
402
- for (const dir of firefoxProfileDirs()) {
403
- all.push(...await readFirefoxBookmarks(dir));
404
- }
405
- const seen = /* @__PURE__ */ new Set();
406
- return all.filter((h) => {
407
- if (seen.has(h.hostname)) return false;
408
- seen.add(h.hostname);
409
- return true;
410
- });
411
- }
412
- async function scanAllHistory() {
413
- const all = [];
414
- for (const p of chromeLikeHistoryPaths(CHROME_BASE)) all.push(...await readChromiumHistory(p, "chrome"));
415
- for (const p of chromeLikeHistoryPaths(CHROMIUM_BASE)) all.push(...await readChromiumHistory(p, "chromium"));
416
- for (const p of chromeLikeHistoryPaths(EDGE_BASE)) all.push(...await readChromiumHistory(p, "edge"));
417
- for (const p of chromeLikeHistoryPaths(BRAVE_BASE)) all.push(...await readChromiumHistory(p, "brave"));
418
- for (const p of chromeLikeHistoryPaths(VIVALDI_BASE)) all.push(...await readChromiumHistory(p, "vivaldi"));
419
- for (const p of chromeLikeHistoryPaths(OPERA_BASE)) all.push(...await readChromiumHistory(p, "opera"));
420
- if (IS_LINUX2) {
421
- for (const p of chromeLikeHistoryPaths(CHROMIUM_SNAP_BASE)) all.push(...await readChromiumHistory(p, "chromium-snap"));
422
- for (const p of chromeLikeHistoryPaths(CHROMIUM_FLATPAK_BASE)) all.push(...await readChromiumHistory(p, "chromium-flatpak"));
423
- for (const p of chromeLikeHistoryPaths(CHROME_FLATPAK_BASE)) all.push(...await readChromiumHistory(p, "chrome-flatpak"));
424
- for (const p of chromeLikeHistoryPaths(BRAVE_FLATPAK_BASE)) all.push(...await readChromiumHistory(p, "brave-flatpak"));
425
- for (const p of chromeLikeHistoryPaths(EDGE_FLATPAK_BASE)) all.push(...await readChromiumHistory(p, "edge-flatpak"));
426
- }
427
- for (const dir of firefoxProfileDirs()) {
428
- all.push(...await readFirefoxHistory(dir));
429
- }
430
- const byHost = /* @__PURE__ */ new Map();
431
- for (const h of all) {
432
- const existing = byHost.get(h.hostname);
433
- if (existing) {
434
- existing.visitCount += h.visitCount;
435
- } else {
436
- byHost.set(h.hostname, { ...h });
437
- }
438
- }
439
- return [...byHost.values()].sort((a, b) => b.visitCount - a.visitCount);
440
- }
441
-
442
- export {
443
- PLATFORM,
444
- IS_WIN,
445
- IS_MAC,
446
- IS_LINUX,
447
- HOME,
448
- run,
449
- commandExists,
450
- dbScanDirs,
451
- findFiles,
452
- scanWindowsPrograms,
453
- scanWindowsDbServices,
454
- cleanupTempFiles,
455
- readFirefoxHistory,
456
- scanAllBookmarks,
457
- scanAllHistory
458
- };
459
- //# sourceMappingURL=chunk-QKNYI3SU.js.map