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.
- package/CHANGELOG.md +17 -0
- package/LICENSE +686 -0
- package/LICENSES.md +141 -0
- package/README.md +331 -0
- package/electron/main.cjs +2849 -0
- package/electron/plugin-loader.cjs +184 -0
- package/electron/preload.cjs +108 -0
- package/package.json +216 -0
- package/packages/core/bin/codesynapt-mcp.cjs +611 -0
- package/packages/core/bin/codesynapt.cjs +1933 -0
- package/packages/core/legacy.js +300 -0
- package/packages/core/lib/control-server.cjs +1539 -0
- package/packages/core/lib/embedding.cjs +89 -0
- package/packages/core/lib/logger.cjs +63 -0
- package/packages/core/lib/search-cache.cjs +140 -0
- package/packages/core/lib/search-worker.cjs +255 -0
- package/packages/core/lib/search.cjs +211 -0
- package/packages/core/lib/symbol-graph.cjs +402 -0
- package/packages/core/lib/symbol-parser-js.cjs +542 -0
- package/packages/core/lib/symbol-parser-misc.cjs +394 -0
- package/packages/core/lib/symbol-parser-py.cjs +215 -0
- package/packages/core/lib/symbol-parser-treesitter.cjs +658 -0
- package/packages/core/lib/symbol-parser-tsc.cjs +332 -0
- package/packages/core/monorepo.js +310 -0
- package/packages/core/parser.js +2234 -0
- package/packages/core/scanner.js +623 -0
- package/plugin-api/LICENSE +21 -0
- package/plugin-api/README.md +114 -0
- package/plugin-api/docs/01-getting-started.md +197 -0
- package/plugin-api/docs/02-concepts.md +269 -0
- package/plugin-api/docs/api-reference.md +463 -0
- package/plugin-api/docs/troubleshooting.md +332 -0
- package/plugin-api/docs/types/exporter.md +377 -0
- package/plugin-api/docs/types/theme.md +312 -0
- package/plugin-api/examples/hello-world-plugin/README.md +70 -0
- package/plugin-api/examples/hello-world-plugin/main.js +36 -0
- package/plugin-api/examples/hello-world-plugin/manifest.json +12 -0
- package/plugin-api/examples/mermaid-exporter/README.md +125 -0
- package/plugin-api/examples/mermaid-exporter/main.js +58 -0
- package/plugin-api/examples/mermaid-exporter/manifest.json +12 -0
- package/plugin-api/examples/rust-parser/README.md +71 -0
- package/plugin-api/examples/rust-parser/main.js +123 -0
- package/plugin-api/examples/rust-parser/manifest.json +12 -0
- package/plugin-api/examples/sunset-theme/README.md +95 -0
- package/plugin-api/examples/sunset-theme/manifest.json +12 -0
- package/plugin-api/examples/sunset-theme/theme.css +31 -0
- package/plugin-api/package.json +20 -0
- package/plugin-api/types.d.ts +395 -0
- package/public/app.js +6837 -0
- package/public/backend.js +285 -0
- package/public/index.html +647 -0
- package/public/plugin-host.js +321 -0
- package/public/style.css +4359 -0
- package/public/vendor/three.module.js +53044 -0
- package/scripts/competitor-watch.mjs +144 -0
- package/scripts/copy-vendor.js +21 -0
- package/scripts/download-bundled-node.cjs +53 -0
- package/scripts/fuses-after-pack.cjs +34 -0
- package/scripts/license-check.js +119 -0
- package/scripts/perf-test.js +200 -0
- package/server.js +132 -0
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
// ═══════════════════════════════════════════════════════════
|
|
2
|
+
// Plugin loader — main process side
|
|
3
|
+
//
|
|
4
|
+
// Responsibilities:
|
|
5
|
+
// - Discover plugin folders under the user's plugin directory
|
|
6
|
+
// - Read and validate each manifest.json
|
|
7
|
+
// - Hand the list back to the renderer; the renderer activates
|
|
8
|
+
// code plugins inside its own context (sandboxed by Electron's
|
|
9
|
+
// contextIsolation) and loads theme CSS directly.
|
|
10
|
+
//
|
|
11
|
+
// The plugin directory is one of:
|
|
12
|
+
// macOS: ~/Library/Application Support/codesynapt/plugins
|
|
13
|
+
// Windows: %APPDATA%\codesynapt\plugins
|
|
14
|
+
// Linux: ~/.config/codesynapt/plugins
|
|
15
|
+
//
|
|
16
|
+
// Each plugin is its own folder containing manifest.json plus
|
|
17
|
+
// the entry file (theme.css or main.js).
|
|
18
|
+
// ═══════════════════════════════════════════════════════════
|
|
19
|
+
const fs = require('fs')
|
|
20
|
+
const path = require('path')
|
|
21
|
+
const { app } = require('electron')
|
|
22
|
+
|
|
23
|
+
const VALID_TYPES = new Set(['theme', 'exporter', 'parser', 'layout', 'panel', 'action'])
|
|
24
|
+
const VALID_PERMISSIONS = new Set([
|
|
25
|
+
'read-files', 'read-graph', 'modify-graph',
|
|
26
|
+
'ui-panel', 'context-menu', 'export', 'parse'
|
|
27
|
+
])
|
|
28
|
+
|
|
29
|
+
// Resolve the per-OS plugin folder. We pin it under userData so the
|
|
30
|
+
// app handles cross-platform paths for us.
|
|
31
|
+
function getPluginDir() {
|
|
32
|
+
return path.join(app.getPath('userData'), 'plugins')
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
// Make sure the directory exists so users can drop plugins into it
|
|
36
|
+
// without having to mkdir manually.
|
|
37
|
+
function ensurePluginDir() {
|
|
38
|
+
const dir = getPluginDir()
|
|
39
|
+
try {
|
|
40
|
+
if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true })
|
|
41
|
+
} catch (err) {
|
|
42
|
+
console.warn('[plugin-loader] could not create plugin dir:', err.message)
|
|
43
|
+
}
|
|
44
|
+
return dir
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// Validate a parsed manifest against the schema. Returns either
|
|
48
|
+
// { ok: true, manifest } or { ok: false, reason: string }.
|
|
49
|
+
function validateManifest(raw) {
|
|
50
|
+
if (!raw || typeof raw !== 'object') return { ok: false, reason: 'not an object' }
|
|
51
|
+
const required = ['id', 'name', 'version', 'type', 'main']
|
|
52
|
+
for (const k of required) {
|
|
53
|
+
if (!raw[k] || typeof raw[k] !== 'string') {
|
|
54
|
+
return { ok: false, reason: `missing or invalid "${k}"` }
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
if (!/^[a-z0-9][a-z0-9-_]*$/i.test(raw.id)) {
|
|
58
|
+
return { ok: false, reason: `invalid id "${raw.id}" (use alphanumeric + dash/underscore)` }
|
|
59
|
+
}
|
|
60
|
+
if (!VALID_TYPES.has(raw.type)) {
|
|
61
|
+
return { ok: false, reason: `unknown type "${raw.type}"` }
|
|
62
|
+
}
|
|
63
|
+
// Permissions are optional; if present must be an array of known strings
|
|
64
|
+
if (raw.permissions !== undefined) {
|
|
65
|
+
if (!Array.isArray(raw.permissions)) {
|
|
66
|
+
return { ok: false, reason: 'permissions must be an array' }
|
|
67
|
+
}
|
|
68
|
+
for (const p of raw.permissions) {
|
|
69
|
+
if (!VALID_PERMISSIONS.has(p)) {
|
|
70
|
+
return { ok: false, reason: `unknown permission "${p}"` }
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
// Provide defaults for optional fields so the renderer doesn't
|
|
75
|
+
// have to null-check them
|
|
76
|
+
return {
|
|
77
|
+
ok: true,
|
|
78
|
+
manifest: {
|
|
79
|
+
id: raw.id,
|
|
80
|
+
name: raw.name,
|
|
81
|
+
version: raw.version,
|
|
82
|
+
author: raw.author || 'unknown',
|
|
83
|
+
description: raw.description || '',
|
|
84
|
+
type: raw.type,
|
|
85
|
+
main: raw.main,
|
|
86
|
+
minAppVersion: raw.minAppVersion || '0.0.0',
|
|
87
|
+
license: raw.license || 'unknown',
|
|
88
|
+
homepage: raw.homepage || null,
|
|
89
|
+
permissions: raw.permissions || [],
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
// Discover all plugins. Returns an array of:
|
|
95
|
+
// { manifest, folder, entryPath, entryContent?, error? }
|
|
96
|
+
//
|
|
97
|
+
// For theme plugins we read the CSS file directly here so the renderer
|
|
98
|
+
// can just inject it. For code plugins we read the JS source string and
|
|
99
|
+
// pass it to the renderer to execute in its sandbox.
|
|
100
|
+
function discoverPlugins() {
|
|
101
|
+
const dir = ensurePluginDir()
|
|
102
|
+
let entries
|
|
103
|
+
try {
|
|
104
|
+
entries = fs.readdirSync(dir, { withFileTypes: true })
|
|
105
|
+
} catch (err) {
|
|
106
|
+
console.warn('[plugin-loader] cannot read plugin dir:', err.message)
|
|
107
|
+
return []
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
const results = []
|
|
111
|
+
for (const entry of entries) {
|
|
112
|
+
if (!entry.isDirectory()) continue
|
|
113
|
+
if (entry.name.startsWith('.') || entry.name.startsWith('_')) continue
|
|
114
|
+
const folder = path.join(dir, entry.name)
|
|
115
|
+
const manifestPath = path.join(folder, 'manifest.json')
|
|
116
|
+
|
|
117
|
+
let raw
|
|
118
|
+
try {
|
|
119
|
+
raw = JSON.parse(fs.readFileSync(manifestPath, 'utf8'))
|
|
120
|
+
} catch (err) {
|
|
121
|
+
results.push({
|
|
122
|
+
folder, error: `manifest unreadable: ${err.message}`,
|
|
123
|
+
manifest: { id: entry.name, name: entry.name, type: 'unknown' }
|
|
124
|
+
})
|
|
125
|
+
continue
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
const validation = validateManifest(raw)
|
|
129
|
+
if (!validation.ok) {
|
|
130
|
+
results.push({
|
|
131
|
+
folder, error: `invalid manifest: ${validation.reason}`,
|
|
132
|
+
manifest: { id: raw.id || entry.name, name: raw.name || entry.name, type: raw.type || 'unknown' }
|
|
133
|
+
})
|
|
134
|
+
continue
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
const { manifest } = validation
|
|
138
|
+
// Security: the entry file must live inside the plugin folder.
|
|
139
|
+
// Reject anything escaping with .. or absolute paths.
|
|
140
|
+
const entryPath = path.resolve(folder, manifest.main)
|
|
141
|
+
const rel = path.relative(folder, entryPath)
|
|
142
|
+
if (rel.startsWith('..') || path.isAbsolute(rel)) {
|
|
143
|
+
results.push({
|
|
144
|
+
folder, manifest,
|
|
145
|
+
error: `entry path escapes plugin folder: ${manifest.main}`
|
|
146
|
+
})
|
|
147
|
+
continue
|
|
148
|
+
}
|
|
149
|
+
if (!fs.existsSync(entryPath)) {
|
|
150
|
+
results.push({
|
|
151
|
+
folder, manifest,
|
|
152
|
+
error: `entry file not found: ${manifest.main}`
|
|
153
|
+
})
|
|
154
|
+
continue
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
let entryContent = null
|
|
158
|
+
try {
|
|
159
|
+
entryContent = fs.readFileSync(entryPath, 'utf8')
|
|
160
|
+
} catch (err) {
|
|
161
|
+
results.push({
|
|
162
|
+
folder, manifest,
|
|
163
|
+
error: `cannot read entry: ${err.message}`
|
|
164
|
+
})
|
|
165
|
+
continue
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
results.push({
|
|
169
|
+
folder,
|
|
170
|
+
manifest,
|
|
171
|
+
entryPath,
|
|
172
|
+
entryContent,
|
|
173
|
+
error: null,
|
|
174
|
+
})
|
|
175
|
+
}
|
|
176
|
+
return results
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
module.exports = {
|
|
180
|
+
getPluginDir,
|
|
181
|
+
ensurePluginDir,
|
|
182
|
+
discoverPlugins,
|
|
183
|
+
validateManifest,
|
|
184
|
+
}
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
// Preload — safe IPC bridge between renderer (untrusted) and main (privileged)
|
|
2
|
+
const { contextBridge, ipcRenderer } = require('electron')
|
|
3
|
+
|
|
4
|
+
const csApi = {
|
|
5
|
+
// Imperative
|
|
6
|
+
pickFolder: () => ipcRenderer.invoke('pick-folder'),
|
|
7
|
+
loadFolder: (path) => ipcRenderer.invoke('load-folder', path),
|
|
8
|
+
closeFolder: () => ipcRenderer.invoke('close-folder'),
|
|
9
|
+
getState: () => ipcRenderer.invoke('get-state'),
|
|
10
|
+
readFile: (id) => ipcRenderer.invoke('read-file', id),
|
|
11
|
+
writeFile: (id, content) => ipcRenderer.invoke('write-file', id, content),
|
|
12
|
+
listHistory: (id) => ipcRenderer.invoke('list-history', id),
|
|
13
|
+
readHistory: (id, ts) => ipcRenderer.invoke('read-history', id, ts),
|
|
14
|
+
restoreHistory: (id, ts) => ipcRenderer.invoke('restore-history', id, ts),
|
|
15
|
+
setHistoryEnabled: (enabled) => ipcRenderer.invoke('set-history-enabled', enabled),
|
|
16
|
+
getHistoryEnabled: () => ipcRenderer.invoke('get-history-enabled'),
|
|
17
|
+
controlPort: () => ipcRenderer.invoke('control-port'),
|
|
18
|
+
onControl: (cb) => {
|
|
19
|
+
const onFocus = (_e, data) => cb({ type: 'focus', ...data })
|
|
20
|
+
const onOpen = (_e, data) => cb({ type: 'open', ...data })
|
|
21
|
+
const onTrace = (_e, data) => cb({ type: 'trace', ...data })
|
|
22
|
+
const onBlast = (_e, data) => cb({ type: 'blast', ...data })
|
|
23
|
+
ipcRenderer.on('control:focus', onFocus)
|
|
24
|
+
ipcRenderer.on('control:open', onOpen)
|
|
25
|
+
ipcRenderer.on('control:trace', onTrace)
|
|
26
|
+
ipcRenderer.on('control:blast', onBlast)
|
|
27
|
+
return () => {
|
|
28
|
+
ipcRenderer.off('control:focus', onFocus)
|
|
29
|
+
ipcRenderer.off('control:open', onOpen)
|
|
30
|
+
ipcRenderer.off('control:trace', onTrace)
|
|
31
|
+
ipcRenderer.off('control:blast', onBlast)
|
|
32
|
+
}
|
|
33
|
+
},
|
|
34
|
+
revealInOS: (id) => ipcRenderer.invoke('reveal-in-os', id),
|
|
35
|
+
openInEditor: (id) => ipcRenderer.invoke('open-in-editor', id),
|
|
36
|
+
|
|
37
|
+
// Event subscriptions (main → renderer)
|
|
38
|
+
onSnapshot: (cb) => {
|
|
39
|
+
const handler = (_e, data) => cb(data)
|
|
40
|
+
ipcRenderer.on('snapshot', handler)
|
|
41
|
+
return () => ipcRenderer.off('snapshot', handler)
|
|
42
|
+
},
|
|
43
|
+
onFolderLoaded: (cb) => {
|
|
44
|
+
const handler = (_e, data) => cb(data)
|
|
45
|
+
ipcRenderer.on('folder-loaded', handler)
|
|
46
|
+
return () => ipcRenderer.off('folder-loaded', handler)
|
|
47
|
+
},
|
|
48
|
+
onNoFolder: (cb) => {
|
|
49
|
+
const handler = () => cb()
|
|
50
|
+
ipcRenderer.on('no-folder', handler)
|
|
51
|
+
return () => ipcRenderer.off('no-folder', handler)
|
|
52
|
+
},
|
|
53
|
+
onError: (cb) => {
|
|
54
|
+
const handler = (_e, data) => cb(data)
|
|
55
|
+
ipcRenderer.on('error', handler)
|
|
56
|
+
return () => ipcRenderer.off('error', handler)
|
|
57
|
+
},
|
|
58
|
+
onWindowVisibility: (cb) => {
|
|
59
|
+
const handler = (_e, data) => cb(data)
|
|
60
|
+
ipcRenderer.on('window-visibility', handler)
|
|
61
|
+
return () => ipcRenderer.off('window-visibility', handler)
|
|
62
|
+
},
|
|
63
|
+
onScanProgress: (cb) => {
|
|
64
|
+
const handler = (_e, data) => cb(data)
|
|
65
|
+
ipcRenderer.on('scan-progress', handler)
|
|
66
|
+
return () => ipcRenderer.off('scan-progress', handler)
|
|
67
|
+
},
|
|
68
|
+
|
|
69
|
+
// Panel data — bypasses fetch/CSP for tour, timeline, changes
|
|
70
|
+
getTour: () => ipcRenderer.invoke('panel:tour'),
|
|
71
|
+
getTimeline: () => ipcRenderer.invoke('panel:timeline'),
|
|
72
|
+
getChanges: () => ipcRenderer.invoke('panel:changes'),
|
|
73
|
+
getChangeDiff: (id) => ipcRenderer.invoke('panel:change-diff', id),
|
|
74
|
+
getPackages: () => ipcRenderer.invoke('panel:packages'),
|
|
75
|
+
getPackage: (name) => ipcRenderer.invoke('panel:package', name),
|
|
76
|
+
getLegacy: () => ipcRenderer.invoke('panel:legacy'),
|
|
77
|
+
// Trace session — live AI activity log
|
|
78
|
+
traceLog: (opts) => ipcRenderer.invoke('trace:log', opts || {}),
|
|
79
|
+
traceStats: () => ipcRenderer.invoke('trace:stats'),
|
|
80
|
+
traceSessions: () => ipcRenderer.invoke('trace:sessions'),
|
|
81
|
+
traceSession: (id) => ipcRenderer.invoke('trace:session', id),
|
|
82
|
+
traceClear: () => ipcRenderer.invoke('trace:clear'),
|
|
83
|
+
traceExport: (path) => ipcRenderer.invoke('trace:export', path),
|
|
84
|
+
|
|
85
|
+
// Pinned projects (multi-folder workspace)
|
|
86
|
+
listProjects: () => ipcRenderer.invoke('list-projects'),
|
|
87
|
+
pinProject: (path, name, color) => ipcRenderer.invoke('pin-project', { path, name, color }),
|
|
88
|
+
unpinProject: (path) => ipcRenderer.invoke('unpin-project', path),
|
|
89
|
+
renameProject: (path, name) => ipcRenderer.invoke('rename-project', { path, name }),
|
|
90
|
+
|
|
91
|
+
// Plugin system
|
|
92
|
+
listPlugins: () => ipcRenderer.invoke('list-plugins'),
|
|
93
|
+
openPluginDir: () => ipcRenderer.invoke('open-plugin-dir'),
|
|
94
|
+
pluginDir: () => ipcRenderer.invoke('plugin-dir'),
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
// Expose under both names: 'codesynapt' is the canonical namespace from 0.14.6+;
|
|
98
|
+
// 'fg3d' is a legacy alias kept for backward compat (plugin authors, etc.).
|
|
99
|
+
// Both refer to the SAME object — no extra memory.
|
|
100
|
+
contextBridge.exposeInMainWorld('codesynapt', csApi)
|
|
101
|
+
contextBridge.exposeInMainWorld('fg3d', csApi)
|
|
102
|
+
|
|
103
|
+
// Platform info for renderer
|
|
104
|
+
contextBridge.exposeInMainWorld('platform', {
|
|
105
|
+
os: process.platform,
|
|
106
|
+
isMac: process.platform === 'darwin',
|
|
107
|
+
isElectron: true,
|
|
108
|
+
})
|
package/package.json
ADDED
|
@@ -0,0 +1,216 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "codesynapt",
|
|
3
|
+
"version": "0.0.0",
|
|
4
|
+
"description": "MCP-native code graph for AI agents — see blast radius live. 3D visualizer + CLI + MCP server, one package.",
|
|
5
|
+
"license": "AGPL-3.0-or-later",
|
|
6
|
+
"author": {
|
|
7
|
+
"name": "wing1008",
|
|
8
|
+
"url": "https://github.com/wing1008"
|
|
9
|
+
},
|
|
10
|
+
"funding": [
|
|
11
|
+
{
|
|
12
|
+
"type": "github",
|
|
13
|
+
"url": "https://github.com/sponsors/wing1008"
|
|
14
|
+
},
|
|
15
|
+
{
|
|
16
|
+
"type": "individual",
|
|
17
|
+
"url": "https://buymeacoffee.com/wing1008"
|
|
18
|
+
}
|
|
19
|
+
],
|
|
20
|
+
"homepage": "https://github.com/wing1008/codesynapt#readme",
|
|
21
|
+
"repository": {
|
|
22
|
+
"type": "git",
|
|
23
|
+
"url": "git+https://github.com/wing1008/codesynapt.git"
|
|
24
|
+
},
|
|
25
|
+
"bugs": {
|
|
26
|
+
"url": "https://github.com/wing1008/codesynapt/issues"
|
|
27
|
+
},
|
|
28
|
+
"keywords": [
|
|
29
|
+
"code-visualization",
|
|
30
|
+
"dependency-graph",
|
|
31
|
+
"mcp",
|
|
32
|
+
"ai-coding-agent",
|
|
33
|
+
"blast-radius",
|
|
34
|
+
"3d",
|
|
35
|
+
"electron",
|
|
36
|
+
"three.js",
|
|
37
|
+
"developer-tools"
|
|
38
|
+
],
|
|
39
|
+
"type": "module",
|
|
40
|
+
"main": "electron/main.cjs",
|
|
41
|
+
"bin": {
|
|
42
|
+
"codesynapt-server": "server.js",
|
|
43
|
+
"codesynapt": "packages/core/bin/codesynapt.cjs",
|
|
44
|
+
"cs": "packages/core/bin/codesynapt.cjs",
|
|
45
|
+
"codesynapt-mcp": "packages/core/bin/codesynapt-mcp.cjs"
|
|
46
|
+
},
|
|
47
|
+
"files": [
|
|
48
|
+
"packages/core/",
|
|
49
|
+
"electron/",
|
|
50
|
+
"public/",
|
|
51
|
+
"scripts/",
|
|
52
|
+
"plugin-api/",
|
|
53
|
+
"server.js",
|
|
54
|
+
"LICENSE",
|
|
55
|
+
"LICENSES.md",
|
|
56
|
+
"CHANGELOG.md",
|
|
57
|
+
"README.md"
|
|
58
|
+
],
|
|
59
|
+
"scripts": {
|
|
60
|
+
"postinstall": "node scripts/copy-vendor.js",
|
|
61
|
+
"start": "electron .",
|
|
62
|
+
"electron": "electron .",
|
|
63
|
+
"server": "node server.js",
|
|
64
|
+
"test": "vitest run",
|
|
65
|
+
"test:watch": "vitest",
|
|
66
|
+
"test:smoke": "node test.js",
|
|
67
|
+
"bench": "node scripts/perf-test.js",
|
|
68
|
+
"license-check": "node scripts/license-check.js",
|
|
69
|
+
"dist": "electron-builder",
|
|
70
|
+
"dist:mac": "electron-builder --mac",
|
|
71
|
+
"dist:win": "node scripts/download-bundled-node.cjs && electron-builder --win",
|
|
72
|
+
"dist:linux": "electron-builder --linux"
|
|
73
|
+
},
|
|
74
|
+
"dependencies": {
|
|
75
|
+
"@babel/parser": "^7.24.0",
|
|
76
|
+
"@babel/traverse": "^7.24.0",
|
|
77
|
+
"chokidar": "^3.6.0",
|
|
78
|
+
"tree-sitter-wasms": "^0.1.13",
|
|
79
|
+
"typescript": "^6.0.3",
|
|
80
|
+
"web-tree-sitter": "^0.20.8"
|
|
81
|
+
},
|
|
82
|
+
"optionalDependencies": {
|
|
83
|
+
"@xenova/transformers": "^2.17.2",
|
|
84
|
+
"three": "^0.160.0",
|
|
85
|
+
"ws": "^8.16.0"
|
|
86
|
+
},
|
|
87
|
+
"devDependencies": {
|
|
88
|
+
"@electron/fuses": "^2.1.1",
|
|
89
|
+
"autocannon": "^8.0.0",
|
|
90
|
+
"clinic": "^13.0.0",
|
|
91
|
+
"electron": "^41.0.0",
|
|
92
|
+
"electron-builder": "^25.0.0",
|
|
93
|
+
"electron-updater": "^6.8.3",
|
|
94
|
+
"memlab": "^2.0.3",
|
|
95
|
+
"playwright": "^1.60.0",
|
|
96
|
+
"vitest": "^2.1.9"
|
|
97
|
+
},
|
|
98
|
+
"build": {
|
|
99
|
+
"appId": "io.codesynapt.desktop",
|
|
100
|
+
"productName": "CodeSynapt",
|
|
101
|
+
"artifactName": "${productName}-Setup-${version}.${ext}",
|
|
102
|
+
"afterPack": "scripts/fuses-after-pack.cjs",
|
|
103
|
+
"asar": false,
|
|
104
|
+
"files": [
|
|
105
|
+
"electron/**/*",
|
|
106
|
+
"public/**/*",
|
|
107
|
+
"packages/core/**/*",
|
|
108
|
+
"plugin-api/**/*",
|
|
109
|
+
"scripts/**/*",
|
|
110
|
+
"server.js",
|
|
111
|
+
"package.json"
|
|
112
|
+
],
|
|
113
|
+
"extraResources": [
|
|
114
|
+
{
|
|
115
|
+
"from": "build/bundled-node/",
|
|
116
|
+
"to": "bundled-node/",
|
|
117
|
+
"filter": [
|
|
118
|
+
"**/*"
|
|
119
|
+
]
|
|
120
|
+
},
|
|
121
|
+
{
|
|
122
|
+
"from": "build/installer-bin/",
|
|
123
|
+
"to": "installer-bin/",
|
|
124
|
+
"filter": [
|
|
125
|
+
"**/*"
|
|
126
|
+
]
|
|
127
|
+
}
|
|
128
|
+
],
|
|
129
|
+
"directories": {
|
|
130
|
+
"buildResources": "build",
|
|
131
|
+
"output": "dist"
|
|
132
|
+
},
|
|
133
|
+
"mac": {
|
|
134
|
+
"category": "public.app-category.developer-tools",
|
|
135
|
+
"target": [
|
|
136
|
+
{
|
|
137
|
+
"target": "dmg",
|
|
138
|
+
"arch": [
|
|
139
|
+
"x64",
|
|
140
|
+
"arm64"
|
|
141
|
+
]
|
|
142
|
+
},
|
|
143
|
+
{
|
|
144
|
+
"target": "zip",
|
|
145
|
+
"arch": [
|
|
146
|
+
"x64",
|
|
147
|
+
"arm64"
|
|
148
|
+
]
|
|
149
|
+
}
|
|
150
|
+
],
|
|
151
|
+
"hardenedRuntime": true,
|
|
152
|
+
"gatekeeperAssess": false,
|
|
153
|
+
"entitlements": "build/entitlements.mac.plist",
|
|
154
|
+
"entitlementsInherit": "build/entitlements.mac.plist"
|
|
155
|
+
},
|
|
156
|
+
"win": {
|
|
157
|
+
"target": [
|
|
158
|
+
{
|
|
159
|
+
"target": "nsis",
|
|
160
|
+
"arch": [
|
|
161
|
+
"x64"
|
|
162
|
+
]
|
|
163
|
+
}
|
|
164
|
+
]
|
|
165
|
+
},
|
|
166
|
+
"nsis": {
|
|
167
|
+
"oneClick": false,
|
|
168
|
+
"perMachine": false,
|
|
169
|
+
"allowToChangeInstallationDirectory": true,
|
|
170
|
+
"allowElevation": false,
|
|
171
|
+
"createDesktopShortcut": true,
|
|
172
|
+
"createStartMenuShortcut": true,
|
|
173
|
+
"shortcutName": "CodeSynapt",
|
|
174
|
+
"uninstallDisplayName": "CodeSynapt ${version}",
|
|
175
|
+
"deleteAppDataOnUninstall": false,
|
|
176
|
+
"differentialPackage": false,
|
|
177
|
+
"runAfterFinish": true,
|
|
178
|
+
"include": "build/installer.nsh"
|
|
179
|
+
},
|
|
180
|
+
"linux": {
|
|
181
|
+
"target": [
|
|
182
|
+
{
|
|
183
|
+
"target": "AppImage",
|
|
184
|
+
"arch": [
|
|
185
|
+
"x64"
|
|
186
|
+
]
|
|
187
|
+
},
|
|
188
|
+
{
|
|
189
|
+
"target": "deb",
|
|
190
|
+
"arch": [
|
|
191
|
+
"x64"
|
|
192
|
+
]
|
|
193
|
+
},
|
|
194
|
+
{
|
|
195
|
+
"target": "tar.gz",
|
|
196
|
+
"arch": [
|
|
197
|
+
"x64"
|
|
198
|
+
]
|
|
199
|
+
}
|
|
200
|
+
],
|
|
201
|
+
"category": "Development",
|
|
202
|
+
"synopsis": "MCP-native code graph visualizer for AI coding agents",
|
|
203
|
+
"description": "CodeSynapt visualizes how files in a codebase connect to each other in 3D, and exposes the dependency graph to AI coding agents via MCP — so agents can see blast radius before editing."
|
|
204
|
+
},
|
|
205
|
+
"publish": [
|
|
206
|
+
{
|
|
207
|
+
"provider": "github",
|
|
208
|
+
"owner": "wing1008",
|
|
209
|
+
"repo": "codesynapt"
|
|
210
|
+
}
|
|
211
|
+
]
|
|
212
|
+
},
|
|
213
|
+
"engines": {
|
|
214
|
+
"node": ">=20"
|
|
215
|
+
}
|
|
216
|
+
}
|