codesynapt 0.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 (61) hide show
  1. package/CHANGELOG.md +17 -0
  2. package/LICENSE +686 -0
  3. package/LICENSES.md +141 -0
  4. package/README.md +331 -0
  5. package/electron/main.cjs +2849 -0
  6. package/electron/plugin-loader.cjs +184 -0
  7. package/electron/preload.cjs +108 -0
  8. package/package.json +216 -0
  9. package/packages/core/bin/codesynapt-mcp.cjs +611 -0
  10. package/packages/core/bin/codesynapt.cjs +1933 -0
  11. package/packages/core/legacy.js +300 -0
  12. package/packages/core/lib/control-server.cjs +1539 -0
  13. package/packages/core/lib/embedding.cjs +89 -0
  14. package/packages/core/lib/logger.cjs +63 -0
  15. package/packages/core/lib/search-cache.cjs +140 -0
  16. package/packages/core/lib/search-worker.cjs +255 -0
  17. package/packages/core/lib/search.cjs +211 -0
  18. package/packages/core/lib/symbol-graph.cjs +402 -0
  19. package/packages/core/lib/symbol-parser-js.cjs +542 -0
  20. package/packages/core/lib/symbol-parser-misc.cjs +394 -0
  21. package/packages/core/lib/symbol-parser-py.cjs +215 -0
  22. package/packages/core/lib/symbol-parser-treesitter.cjs +658 -0
  23. package/packages/core/lib/symbol-parser-tsc.cjs +332 -0
  24. package/packages/core/monorepo.js +310 -0
  25. package/packages/core/parser.js +2234 -0
  26. package/packages/core/scanner.js +623 -0
  27. package/plugin-api/LICENSE +21 -0
  28. package/plugin-api/README.md +114 -0
  29. package/plugin-api/docs/01-getting-started.md +197 -0
  30. package/plugin-api/docs/02-concepts.md +269 -0
  31. package/plugin-api/docs/api-reference.md +463 -0
  32. package/plugin-api/docs/troubleshooting.md +332 -0
  33. package/plugin-api/docs/types/exporter.md +377 -0
  34. package/plugin-api/docs/types/theme.md +312 -0
  35. package/plugin-api/examples/hello-world-plugin/README.md +70 -0
  36. package/plugin-api/examples/hello-world-plugin/main.js +36 -0
  37. package/plugin-api/examples/hello-world-plugin/manifest.json +12 -0
  38. package/plugin-api/examples/mermaid-exporter/README.md +125 -0
  39. package/plugin-api/examples/mermaid-exporter/main.js +58 -0
  40. package/plugin-api/examples/mermaid-exporter/manifest.json +12 -0
  41. package/plugin-api/examples/rust-parser/README.md +71 -0
  42. package/plugin-api/examples/rust-parser/main.js +123 -0
  43. package/plugin-api/examples/rust-parser/manifest.json +12 -0
  44. package/plugin-api/examples/sunset-theme/README.md +95 -0
  45. package/plugin-api/examples/sunset-theme/manifest.json +12 -0
  46. package/plugin-api/examples/sunset-theme/theme.css +31 -0
  47. package/plugin-api/package.json +20 -0
  48. package/plugin-api/types.d.ts +395 -0
  49. package/public/app.js +6837 -0
  50. package/public/backend.js +285 -0
  51. package/public/index.html +647 -0
  52. package/public/plugin-host.js +321 -0
  53. package/public/style.css +4359 -0
  54. package/public/vendor/three.module.js +53044 -0
  55. package/scripts/competitor-watch.mjs +144 -0
  56. package/scripts/copy-vendor.js +21 -0
  57. package/scripts/download-bundled-node.cjs +53 -0
  58. package/scripts/fuses-after-pack.cjs +34 -0
  59. package/scripts/license-check.js +119 -0
  60. package/scripts/perf-test.js +200 -0
  61. package/server.js +132 -0
package/server.js ADDED
@@ -0,0 +1,132 @@
1
+ #!/usr/bin/env node
2
+ import http from 'http'
3
+ import fs from 'fs'
4
+ import path from 'path'
5
+ import { fileURLToPath } from 'url'
6
+ import { WebSocketServer } from 'ws'
7
+ import { Scanner } from './packages/core/scanner.js'
8
+
9
+ // ─── CLI ──────────────────────────────────────────────────────
10
+ const args = process.argv.slice(2)
11
+ if (args.includes('-h') || args.includes('--help')) {
12
+ console.log(`
13
+ codesynapt — Real-time 3D file/code dependency visualizer
14
+
15
+ Usage:
16
+ codesynapt <directory> [--port <n>]
17
+
18
+ Examples:
19
+ codesynapt .
20
+ codesynapt ~/projects/myapp --port 8080
21
+ `)
22
+ process.exit(0)
23
+ }
24
+
25
+ const portIdx = args.indexOf('--port')
26
+ const PORT = portIdx >= 0 ? parseInt(args[portIdx + 1]) : 7777
27
+ const dirArg = args.find((a) => !a.startsWith('--') && a !== String(PORT)) || '.'
28
+ const ROOT = path.resolve(dirArg)
29
+
30
+ if (!fs.existsSync(ROOT) || !fs.statSync(ROOT).isDirectory()) {
31
+ console.error(`✗ Not a directory: ${ROOT}`)
32
+ process.exit(1)
33
+ }
34
+
35
+ // ─── Static file server ───────────────────────────────────────
36
+ const __dirname = path.dirname(fileURLToPath(import.meta.url))
37
+ const PUBLIC = path.join(__dirname, 'public')
38
+
39
+ const MIME = {
40
+ '.html': 'text/html; charset=utf-8',
41
+ '.js': 'text/javascript; charset=utf-8',
42
+ '.css': 'text/css; charset=utf-8',
43
+ '.json': 'application/json',
44
+ '.svg': 'image/svg+xml',
45
+ }
46
+
47
+ // Robust containment check — `startsWith` alone leaks sibling dirs that share
48
+ // a prefix (e.g. /a/public vs /a/public-secret). Resolve and use path.relative.
49
+ const isInside = (base, target) => {
50
+ const rel = path.relative(base, target)
51
+ return rel === '' || (!rel.startsWith('..') && !path.isAbsolute(rel))
52
+ }
53
+
54
+ const server = http.createServer((req, res) => {
55
+ let rel = req.url.split('?')[0]
56
+ try { rel = decodeURIComponent(rel) } catch {} // normalize %2e%2e etc.
57
+ if (rel === '/') rel = '/index.html'
58
+ const filePath = path.join(PUBLIC, rel)
59
+ if (!isInside(PUBLIC, filePath)) {
60
+ res.writeHead(403); res.end(); return
61
+ }
62
+ fs.readFile(filePath, (err, data) => {
63
+ if (err) { res.writeHead(404); res.end('Not found'); return }
64
+ res.writeHead(200, { 'Content-Type': MIME[path.extname(filePath)] || 'text/plain' })
65
+ res.end(data)
66
+ })
67
+ })
68
+
69
+ // ─── WebSocket ────────────────────────────────────────────────
70
+ const wss = new WebSocketServer({ server })
71
+ const scanner = new Scanner(ROOT)
72
+
73
+ const broadcast = (msg) => {
74
+ const str = JSON.stringify(msg)
75
+ wss.clients.forEach((c) => c.readyState === 1 && c.send(str))
76
+ }
77
+
78
+ scanner.on('snapshot', (data) => broadcast({ type: 'snapshot', ...data, root: ROOT }))
79
+ scanner.on('stats', (s) => broadcast({ type: 'stats', ...s }))
80
+ scanner.on('scan-progress', (p) => broadcast({ type: 'scan-progress', ...p }))
81
+
82
+ wss.on('connection', (ws) => {
83
+ // New client gets current state
84
+ ws.send(JSON.stringify({ type: 'snapshot', ...scanner.snapshot(), root: ROOT }))
85
+
86
+ ws.on('message', (raw) => {
87
+ let msg
88
+ try { msg = JSON.parse(raw) } catch { return }
89
+
90
+ if (msg.type === 'read_file') {
91
+ try {
92
+ const full = path.join(ROOT, msg.id)
93
+ if (!isInside(ROOT, full)) return
94
+ const stat = fs.statSync(full)
95
+ if (stat.size > 500_000) {
96
+ ws.send(JSON.stringify({ type: 'file_content', id: msg.id,
97
+ content: '[file too large to preview]', truncated: true }))
98
+ return
99
+ }
100
+ const content = fs.readFileSync(full, 'utf8').slice(0, 100_000)
101
+ ws.send(JSON.stringify({ type: 'file_content', id: msg.id, content }))
102
+ } catch (e) {
103
+ ws.send(JSON.stringify({ type: 'file_content', id: msg.id,
104
+ content: `[error: ${e.message}]`, error: true }))
105
+ }
106
+ }
107
+ })
108
+ })
109
+
110
+ // ─── Start ────────────────────────────────────────────────────
111
+ // Bind to loopback only — never expose this dev server to the LAN.
112
+ server.listen(PORT, '127.0.0.1', () => {
113
+ console.log(`
114
+ ┌─ codesynapt ─────────────────────────────────
115
+ │ root: ${ROOT}
116
+ │ open: http://localhost:${PORT}
117
+ └───────────────────────────────────────────────
118
+ `)
119
+ })
120
+
121
+ scanner.start()
122
+
123
+ // A bad file / rejected promise must not kill the dev server.
124
+ process.on('uncaughtException', (e) => console.error('[server] uncaughtException:', e && e.stack || e))
125
+ process.on('unhandledRejection', (e) => console.error('[server] unhandledRejection:', e && e.stack || e))
126
+
127
+ process.on('SIGINT', () => {
128
+ console.log('\nshutting down…')
129
+ scanner.stop()
130
+ wss.close()
131
+ server.close(() => process.exit(0))
132
+ })