@aroman22/codegraph-vba 1.3.3

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 (153) hide show
  1. package/README.md +855 -0
  2. package/dist/bin/codegraph.d.ts +26 -0
  3. package/dist/bin/command-supervision.d.ts +12 -0
  4. package/dist/bin/fatal-handler.d.ts +20 -0
  5. package/dist/bin/node-version-check.d.ts +37 -0
  6. package/dist/bin/uninstall.d.ts +14 -0
  7. package/dist/context/formatter.d.ts +30 -0
  8. package/dist/context/index.d.ts +119 -0
  9. package/dist/context/markers.d.ts +19 -0
  10. package/dist/db/index.d.ts +122 -0
  11. package/dist/db/migrations.d.ts +44 -0
  12. package/dist/db/queries.d.ts +402 -0
  13. package/dist/db/sqlite-adapter.d.ts +53 -0
  14. package/dist/directory.d.ts +179 -0
  15. package/dist/errors.d.ts +136 -0
  16. package/dist/extraction/astro-extractor.d.ts +79 -0
  17. package/dist/extraction/dfm-extractor.d.ts +31 -0
  18. package/dist/extraction/extraction-version.d.ts +25 -0
  19. package/dist/extraction/function-ref.d.ts +118 -0
  20. package/dist/extraction/generated-detection.d.ts +30 -0
  21. package/dist/extraction/grammars.d.ts +128 -0
  22. package/dist/extraction/index.d.ts +187 -0
  23. package/dist/extraction/languages/c-cpp.d.ts +12 -0
  24. package/dist/extraction/languages/csharp.d.ts +25 -0
  25. package/dist/extraction/languages/dart.d.ts +3 -0
  26. package/dist/extraction/languages/go.d.ts +3 -0
  27. package/dist/extraction/languages/index.d.ts +10 -0
  28. package/dist/extraction/languages/java.d.ts +3 -0
  29. package/dist/extraction/languages/javascript.d.ts +3 -0
  30. package/dist/extraction/languages/kotlin.d.ts +3 -0
  31. package/dist/extraction/languages/lua.d.ts +3 -0
  32. package/dist/extraction/languages/luau.d.ts +3 -0
  33. package/dist/extraction/languages/objc.d.ts +3 -0
  34. package/dist/extraction/languages/pascal.d.ts +3 -0
  35. package/dist/extraction/languages/php.d.ts +3 -0
  36. package/dist/extraction/languages/python.d.ts +3 -0
  37. package/dist/extraction/languages/r.d.ts +3 -0
  38. package/dist/extraction/languages/ruby.d.ts +3 -0
  39. package/dist/extraction/languages/rust.d.ts +3 -0
  40. package/dist/extraction/languages/scala.d.ts +3 -0
  41. package/dist/extraction/languages/swift.d.ts +3 -0
  42. package/dist/extraction/languages/typescript.d.ts +16 -0
  43. package/dist/extraction/liquid-extractor.d.ts +59 -0
  44. package/dist/extraction/mybatis-extractor.d.ts +48 -0
  45. package/dist/extraction/parse-pool.d.ts +126 -0
  46. package/dist/extraction/parse-worker.d.ts +8 -0
  47. package/dist/extraction/razor-extractor.d.ts +42 -0
  48. package/dist/extraction/sql-query-extractor.d.ts +25 -0
  49. package/dist/extraction/svelte-extractor.d.ts +56 -0
  50. package/dist/extraction/tree-sitter-helpers.d.ts +28 -0
  51. package/dist/extraction/tree-sitter-types.d.ts +239 -0
  52. package/dist/extraction/tree-sitter.d.ts +647 -0
  53. package/dist/extraction/vba-extractor.d.ts +394 -0
  54. package/dist/extraction/vba-form-extractor.d.ts +89 -0
  55. package/dist/extraction/vba-preprocess.d.ts +81 -0
  56. package/dist/extraction/vue-extractor.d.ts +51 -0
  57. package/dist/extraction/wasm-runtime-flags.d.ts +38 -0
  58. package/dist/graph/index.d.ts +8 -0
  59. package/dist/graph/queries.d.ts +106 -0
  60. package/dist/graph/traversal.d.ts +127 -0
  61. package/dist/index.d.ts +563 -0
  62. package/dist/installer/config-writer.d.ts +28 -0
  63. package/dist/installer/index.d.ts +100 -0
  64. package/dist/installer/instructions-template.d.ts +41 -0
  65. package/dist/installer/targets/antigravity.d.ts +57 -0
  66. package/dist/installer/targets/claude.d.ts +62 -0
  67. package/dist/installer/targets/codex.d.ts +18 -0
  68. package/dist/installer/targets/cursor.d.ts +35 -0
  69. package/dist/installer/targets/gemini.d.ts +26 -0
  70. package/dist/installer/targets/hermes.d.ts +18 -0
  71. package/dist/installer/targets/kiro.d.ts +27 -0
  72. package/dist/installer/targets/opencode.d.ts +38 -0
  73. package/dist/installer/targets/registry.d.ts +35 -0
  74. package/dist/installer/targets/shared.d.ts +101 -0
  75. package/dist/installer/targets/toml.d.ts +52 -0
  76. package/dist/installer/targets/types.d.ts +108 -0
  77. package/dist/mcp/daemon-manager.d.ts +42 -0
  78. package/dist/mcp/daemon-paths.d.ts +73 -0
  79. package/dist/mcp/daemon-registry.d.ts +47 -0
  80. package/dist/mcp/daemon.d.ts +258 -0
  81. package/dist/mcp/dynamic-boundaries.d.ts +41 -0
  82. package/dist/mcp/engine.d.ts +122 -0
  83. package/dist/mcp/index.d.ts +113 -0
  84. package/dist/mcp/liveness-watchdog.d.ts +18 -0
  85. package/dist/mcp/ppid-watchdog.d.ts +62 -0
  86. package/dist/mcp/proxy.d.ts +87 -0
  87. package/dist/mcp/query-pool.d.ts +94 -0
  88. package/dist/mcp/query-worker.d.ts +24 -0
  89. package/dist/mcp/server-instructions.d.ts +34 -0
  90. package/dist/mcp/session.d.ts +79 -0
  91. package/dist/mcp/stdin-teardown.d.ts +27 -0
  92. package/dist/mcp/tools.d.ts +591 -0
  93. package/dist/mcp/transport.d.ts +188 -0
  94. package/dist/mcp/version.d.ts +19 -0
  95. package/dist/project-config.d.ts +56 -0
  96. package/dist/reasoning/config.d.ts +45 -0
  97. package/dist/reasoning/credentials.d.ts +5 -0
  98. package/dist/reasoning/login.d.ts +21 -0
  99. package/dist/reasoning/reasoner.d.ts +43 -0
  100. package/dist/resolution/c-fnptr-synthesizer.d.ts +5 -0
  101. package/dist/resolution/callback-synthesizer.d.ts +15 -0
  102. package/dist/resolution/frameworks/astro.d.ts +9 -0
  103. package/dist/resolution/frameworks/cargo-workspace.d.ts +18 -0
  104. package/dist/resolution/frameworks/csharp.d.ts +8 -0
  105. package/dist/resolution/frameworks/drupal.d.ts +51 -0
  106. package/dist/resolution/frameworks/expo-modules.d.ts +3 -0
  107. package/dist/resolution/frameworks/express.d.ts +8 -0
  108. package/dist/resolution/frameworks/fabric.d.ts +3 -0
  109. package/dist/resolution/frameworks/go.d.ts +8 -0
  110. package/dist/resolution/frameworks/goframe.d.ts +41 -0
  111. package/dist/resolution/frameworks/index.d.ts +50 -0
  112. package/dist/resolution/frameworks/java.d.ts +8 -0
  113. package/dist/resolution/frameworks/laravel.d.ts +13 -0
  114. package/dist/resolution/frameworks/nestjs.d.ts +26 -0
  115. package/dist/resolution/frameworks/play.d.ts +19 -0
  116. package/dist/resolution/frameworks/python.d.ts +10 -0
  117. package/dist/resolution/frameworks/react-native.d.ts +3 -0
  118. package/dist/resolution/frameworks/react.d.ts +8 -0
  119. package/dist/resolution/frameworks/ruby.d.ts +8 -0
  120. package/dist/resolution/frameworks/rust.d.ts +8 -0
  121. package/dist/resolution/frameworks/svelte.d.ts +9 -0
  122. package/dist/resolution/frameworks/swift-objc.d.ts +37 -0
  123. package/dist/resolution/frameworks/swift.d.ts +10 -0
  124. package/dist/resolution/frameworks/vue.d.ts +9 -0
  125. package/dist/resolution/go-module.d.ts +26 -0
  126. package/dist/resolution/goframe-synthesizer.d.ts +28 -0
  127. package/dist/resolution/import-resolver.d.ts +78 -0
  128. package/dist/resolution/index.d.ts +196 -0
  129. package/dist/resolution/lru-cache.d.ts +24 -0
  130. package/dist/resolution/name-matcher.d.ts +93 -0
  131. package/dist/resolution/path-aliases.d.ts +68 -0
  132. package/dist/resolution/strip-comments.d.ts +27 -0
  133. package/dist/resolution/swift-objc-bridge.d.ts +134 -0
  134. package/dist/resolution/types.d.ts +233 -0
  135. package/dist/resolution/workspace-packages.d.ts +48 -0
  136. package/dist/search/query-parser.d.ts +57 -0
  137. package/dist/search/query-utils.d.ts +87 -0
  138. package/dist/sync/git-hooks.d.ts +45 -0
  139. package/dist/sync/index.d.ts +19 -0
  140. package/dist/sync/watch-policy.d.ts +48 -0
  141. package/dist/sync/watcher.d.ts +358 -0
  142. package/dist/sync/worktree.d.ts +54 -0
  143. package/dist/telemetry/index.d.ts +143 -0
  144. package/dist/types.d.ts +409 -0
  145. package/dist/ui/glyphs.d.ts +42 -0
  146. package/dist/ui/shimmer-progress.d.ts +11 -0
  147. package/dist/ui/shimmer-worker.d.ts +2 -0
  148. package/dist/ui/types.d.ts +17 -0
  149. package/dist/upgrade/index.d.ts +132 -0
  150. package/dist/utils.d.ts +224 -0
  151. package/npm-sdk.js +75 -0
  152. package/npm-shim.js +246 -0
  153. package/package.json +32 -0
@@ -0,0 +1,224 @@
1
+ /**
2
+ * CodeGraph Utilities
3
+ *
4
+ * Common utility functions for memory management, concurrency, batching,
5
+ * and security validation.
6
+ *
7
+ * @module utils
8
+ *
9
+ * @example
10
+ * ```typescript
11
+ * import { Mutex, processInBatches, MemoryMonitor, validatePathWithinRoot } from 'codegraph';
12
+ *
13
+ * // Use mutex for concurrent safety
14
+ * const mutex = new Mutex();
15
+ * await mutex.withLock(async () => {
16
+ * await performCriticalOperation();
17
+ * });
18
+ *
19
+ * // Process items in batches to manage memory
20
+ * const results = await processInBatches(items, 100, async (item) => {
21
+ * return await processItem(item);
22
+ * });
23
+ *
24
+ * // Monitor memory usage
25
+ * const monitor = new MemoryMonitor(512, (usage) => {
26
+ * console.warn(`Memory usage exceeded 512MB: ${usage / 1024 / 1024}MB`);
27
+ * });
28
+ * monitor.start();
29
+ * ```
30
+ */
31
+ /**
32
+ * Config "languages" whose nodes are pure key/value DATA lifted from a config
33
+ * file (e.g. Spring `application.{yml,properties}`), not source code.
34
+ */
35
+ export declare const CONFIG_LEAF_LANGUAGES: ReadonlySet<string>;
36
+ /**
37
+ * A config-leaf node is a single key lifted out of a pure config/data file —
38
+ * `kind: 'constant'` in a {@link CONFIG_LEAF_LANGUAGES} language. Its on-disk
39
+ * line is `key = <value>`, and that value is routinely a secret (DB password,
40
+ * API key, JDBC URL with embedded creds). CodeGraph must surface the KEY only
41
+ * and never read/return the value, or it pushes secrets into agent context
42
+ * unbidden — the value isn't needed for resolution, and an agent that genuinely
43
+ * needs it can read the file directly. (#383)
44
+ */
45
+ export declare function isConfigLeafNode(node: {
46
+ kind: string;
47
+ language?: string;
48
+ }): boolean;
49
+ /**
50
+ * Validate that a file path stays within the project root, resolving symlinks.
51
+ *
52
+ * Two layers: a cheap lexical check that catches `../` traversal, then a
53
+ * realpath check that catches symlink escapes — an in-repo symlink whose
54
+ * logical path is inside the root but whose real target points outside it
55
+ * (issue #527). A symlink that stays within the root is still allowed, so
56
+ * legitimate in-tree symlinks keep working. Both content-serving read sinks
57
+ * (codegraph_node `includeCode`, codegraph_explore source) go through here, so
58
+ * this is the chokepoint that keeps out-of-root file contents from leaking.
59
+ *
60
+ * `allowSymlinkEscape` waives **only** the realpath-escape rejection (the
61
+ * lexical `../` guard still applies) for the INDEXING read path. The directory
62
+ * walk deliberately descends into in-root symlinks whose targets live outside
63
+ * the root (e.g. a `game/` symlink in a Dota custom-game tree, #935); discovery
64
+ * and the reader must agree, or every file the walk enumerated fails to index.
65
+ * Indexing only reads paths it just discovered, into a local index — it never
66
+ * serves them to an agent, so this does not widen the #527 leak surface. The
67
+ * content-serving sinks must never pass this flag.
68
+ *
69
+ * @param projectRoot - The project root directory
70
+ * @param filePath - The (relative or absolute) file path to validate
71
+ * @param options.allowSymlinkEscape - Follow in-root symlinks out of the root
72
+ * (indexing read path only); defaults to the strict, leak-safe behavior.
73
+ * @returns The resolved absolute path (realpath when it exists), or null if it
74
+ * escapes the root
75
+ */
76
+ export declare function validatePathWithinRoot(projectRoot: string, filePath: string, options?: {
77
+ allowSymlinkEscape?: boolean;
78
+ }): string | null;
79
+ /**
80
+ * Validate that a path is a safe project root directory.
81
+ *
82
+ * Rejects sensitive system directories and ensures the path is
83
+ * a real, existing directory. Used at MCP and API entry points
84
+ * to prevent arbitrary directory access.
85
+ *
86
+ * @param dirPath - The path to validate
87
+ * @returns An error message if invalid, or null if valid
88
+ */
89
+ export declare function validateProjectPath(dirPath: string): string | null;
90
+ /**
91
+ * Safely parse JSON with a fallback value.
92
+ * Prevents crashes from corrupted database metadata.
93
+ */
94
+ export declare function safeJsonParse<T>(value: string, fallback: T): T;
95
+ /**
96
+ * Clamp a numeric value to a range.
97
+ * Used to enforce sane limits on MCP tool inputs.
98
+ */
99
+ export declare function clamp(value: number, min: number, max: number): number;
100
+ /**
101
+ * Normalize a file path to use forward slashes.
102
+ * Fixes Windows backslash paths so glob matching works consistently.
103
+ */
104
+ export declare function normalizePath(filePath: string): string;
105
+ /**
106
+ * Cross-process file lock using a lock file with PID tracking.
107
+ *
108
+ * Prevents multiple processes (e.g., git hooks, CLI, MCP server) from
109
+ * writing to the same database simultaneously.
110
+ */
111
+ export declare class FileLock {
112
+ private lockPath;
113
+ private held;
114
+ /** Locks older than this are considered stale regardless of PID status */
115
+ private static readonly STALE_TIMEOUT_MS;
116
+ constructor(lockPath: string);
117
+ /**
118
+ * Acquire the lock. Throws if the lock is held by another live process.
119
+ */
120
+ acquire(): void;
121
+ /**
122
+ * Release the lock
123
+ */
124
+ release(): void;
125
+ /**
126
+ * Execute a function while holding the lock
127
+ */
128
+ withLock<T>(fn: () => T): T;
129
+ /**
130
+ * Execute an async function while holding the lock
131
+ */
132
+ withLockAsync<T>(fn: () => Promise<T>): Promise<T>;
133
+ /**
134
+ * Check if a process is still running
135
+ */
136
+ private isProcessAlive;
137
+ }
138
+ /**
139
+ * Process items in batches to manage memory
140
+ *
141
+ * @param items - Array of items to process
142
+ * @param batchSize - Number of items per batch
143
+ * @param processor - Function to process each item
144
+ * @param onBatchComplete - Optional callback after each batch
145
+ * @returns Array of results
146
+ */
147
+ export declare function processInBatches<T, R>(items: T[], batchSize: number, processor: (item: T, index: number) => Promise<R>, onBatchComplete?: (completed: number, total: number) => void): Promise<R[]>;
148
+ /**
149
+ * Simple mutex lock for preventing concurrent operations
150
+ */
151
+ export declare class Mutex {
152
+ private locked;
153
+ private waitQueue;
154
+ /**
155
+ * Acquire the lock
156
+ *
157
+ * @returns A release function to call when done
158
+ */
159
+ acquire(): Promise<() => void>;
160
+ /**
161
+ * Execute a function while holding the lock
162
+ */
163
+ withLock<T>(fn: () => Promise<T> | T): Promise<T>;
164
+ /**
165
+ * Check if the lock is currently held
166
+ */
167
+ isLocked(): boolean;
168
+ }
169
+ /**
170
+ * Chunked file reader for large files
171
+ *
172
+ * Reads a file in chunks to avoid loading entire file into memory.
173
+ */
174
+ export declare function readFileInChunks(filePath: string, chunkSize?: number): AsyncGenerator<string, void, undefined>;
175
+ /**
176
+ * Debounce a function
177
+ *
178
+ * @param fn - Function to debounce
179
+ * @param delay - Delay in milliseconds
180
+ * @returns Debounced function
181
+ */
182
+ export declare function debounce<T extends (...args: unknown[]) => unknown>(fn: T, delay: number): (...args: Parameters<T>) => void;
183
+ /**
184
+ * Throttle a function
185
+ *
186
+ * @param fn - Function to throttle
187
+ * @param limit - Minimum time between calls in milliseconds
188
+ * @returns Throttled function
189
+ */
190
+ export declare function throttle<T extends (...args: unknown[]) => unknown>(fn: T, limit: number): (...args: Parameters<T>) => void;
191
+ /**
192
+ * Estimate memory usage of an object (rough approximation)
193
+ *
194
+ * @param obj - Object to measure
195
+ * @returns Approximate size in bytes
196
+ */
197
+ export declare function estimateSize(obj: unknown): number;
198
+ /**
199
+ * Memory monitor for tracking usage during operations
200
+ */
201
+ export declare class MemoryMonitor {
202
+ private checkInterval;
203
+ private peakUsage;
204
+ private threshold;
205
+ private onThresholdExceeded?;
206
+ constructor(thresholdMB?: number, onThresholdExceeded?: (usage: number) => void);
207
+ /**
208
+ * Start monitoring memory usage
209
+ */
210
+ start(intervalMs?: number): void;
211
+ /**
212
+ * Stop monitoring
213
+ */
214
+ stop(): void;
215
+ /**
216
+ * Get peak memory usage in bytes
217
+ */
218
+ getPeakUsage(): number;
219
+ /**
220
+ * Get current memory usage in bytes
221
+ */
222
+ getCurrentUsage(): number;
223
+ }
224
+ //# sourceMappingURL=utils.d.ts.map
package/npm-sdk.js ADDED
@@ -0,0 +1,75 @@
1
+ 'use strict';
2
+ //
3
+ // Programmatic / embedded SDK entry for codegraph-vba (issue #354).
4
+ //
5
+ // The CLI/MCP `bin` (npm-shim.js) execs the per-platform bundle's OWN Node 24 so
6
+ // the tool never depends on the user's runtime. Embedded library consumers are
7
+ // the opposite case: they already run their own Node and just want the compiled
8
+ // API — `require("codegraph-vba")` returning the CodeGraph class et al.
9
+ //
10
+ // The compiled library + its production dependencies (web-tree-sitter,
11
+ // tree-sitter-wasms, …) ship INSIDE the per-platform bundle, at
12
+ // codegraph-vba-<platform>-<arch>/lib/dist/index.js
13
+ // (with the deps in the sibling lib/node_modules). Re-exporting that bundle keeps
14
+ // the main package thin — no second 50 MB copy of the grammars — while making the
15
+ // SDK work in the consumer's process. Types are a separate concern: the main
16
+ // package ships its own dist/**/*.d.ts tree (pointed at by `types`), built from
17
+ // the same release so it can never skew from the runtime it re-exports.
18
+ //
19
+ // node:sqlite (Node >= 22.5) is required to OPEN a graph, but only lazily inside
20
+ // the SQLite adapter — so loading this module is safe on older Node, and the
21
+ // node:sqlite requirement surfaces with an actionable error only when a DB is
22
+ // actually opened. Heavy extraction additionally wants the bundled launcher's
23
+ // --liftoff-only flag (the WASM Zone-OOM guard, issues #293/#298); an embedded
24
+ // host that drives large indexing should pass that flag to its own Node.
25
+
26
+ var path = require('path');
27
+ var os = require('os');
28
+ var fs = require('fs');
29
+
30
+ var target = process.platform + '-' + process.arch; // e.g. darwin-arm64, linux-x64
31
+ var pkg = '@aroman22/codegraph-vba-' + target;
32
+
33
+ module.exports = require(resolveLibrary());
34
+
35
+ // Locate the compiled library entry inside the installed per-platform bundle.
36
+ // Throws an actionable error (rather than a bare MODULE_NOT_FOUND) when no bundle
37
+ // is present, so an embedded consumer knows exactly what to install.
38
+ function resolveLibrary() {
39
+ // 1) The npm-installed optional dependency — the normal case.
40
+ try {
41
+ return require.resolve(pkg + '/lib/dist/index.js');
42
+ } catch (e) {
43
+ /* fall through to the self-healed cache */
44
+ }
45
+
46
+ // 2) A bundle the CLI shim self-healed from GitHub Releases into the cache
47
+ // (issue #303). Same node/lib/bin layout as the npm package. We only REUSE a
48
+ // cached bundle here — unlike the CLI shim we never trigger a network
49
+ // download from inside require(), which must stay synchronous and cheap.
50
+ var cached = cachedLibrary();
51
+ if (cached) return cached;
52
+
53
+ throw new Error(
54
+ 'codegraph: the programmatic API is unavailable because the platform bundle\n' +
55
+ '(' + pkg + ') is not installed.\n' +
56
+ 'The compiled library ships inside that per-platform optional dependency.\n' +
57
+ 'Fixes:\n' +
58
+ ' - install from the official npm registry so the matching bundle is fetched:\n' +
59
+ ' npm i codegraph-vba --registry=https://registry.npmjs.org\n' +
60
+ ' - or run the CLI once (e.g. `npx codegraph-vba status`) to\n' +
61
+ ' self-heal the bundle into ~/.codegraph, then require() will find it.'
62
+ );
63
+ }
64
+
65
+ function cachedLibrary() {
66
+ try {
67
+ var version = require(path.join(__dirname, 'package.json')).version;
68
+ var base = process.env.CODEGRAPH_INSTALL_DIR || path.join(os.homedir(), '.codegraph');
69
+ var lib = path.join(base, 'bundles', target + '-' + version, 'lib', 'dist', 'index.js');
70
+ if (fs.existsSync(lib)) return lib;
71
+ } catch (e) {
72
+ /* no readable cache → caller reports the install guidance */
73
+ }
74
+ return null;
75
+ }
package/npm-shim.js ADDED
@@ -0,0 +1,246 @@
1
+ #!/usr/bin/env node
2
+ 'use strict';
3
+ //
4
+ // npm thin-installer launcher for CodeGraph.
5
+ //
6
+ // The heavy artifact (a vendored Node runtime + the app) ships as a per-platform
7
+ // optionalDependency: codegraph-vba-<platform>-<arch>. npm installs
8
+ // only the one matching the host, via each package's `os`/`cpu` fields (the
9
+ // esbuild pattern). This shim — run by the user's OWN Node — locates that bundle
10
+ // and execs its launcher, so the real work always runs on the bundled Node 24
11
+ // (with node:sqlite), regardless of the user's Node version. The user's Node is
12
+ // only ever a launcher; even an ancient version can run this file.
13
+ //
14
+ // Self-heal (issue #303): some registries — notably the npmmirror/cnpm mirrors,
15
+ // and some corporate proxies — don't reliably mirror the per-platform
16
+ // optionalDependencies. npm treats an unfetchable optional dep as success and
17
+ // silently skips it, so the bundle goes missing and every command fails. When
18
+ // the installed bundle can't be resolved, this shim falls back to downloading
19
+ // the matching bundle straight from GitHub Releases — the very archive
20
+ // install.sh uses — into a cache dir, then runs that. Knobs:
21
+ // CODEGRAPH_NO_DOWNLOAD=1 disable the network fallback (print guidance)
22
+ // CODEGRAPH_INSTALL_DIR=DIR cache location (default: ~/.codegraph)
23
+ // CODEGRAPH_DOWNLOAD_BASE=URL release-download base (for mirrors/air-gapped)
24
+ //
25
+ // Wired up at release time as the main package's `bin`:
26
+ // "bin": { "codegraph": "npm-shim.js" }
27
+ // with the platform packages listed in `optionalDependencies`.
28
+
29
+ var childProcess = require('child_process');
30
+ var fs = require('fs');
31
+ var os = require('os');
32
+ var path = require('path');
33
+
34
+ var target = process.platform + '-' + process.arch; // e.g. darwin-arm64, linux-x64
35
+ var pkg = '@aroman22/codegraph-vba-' + target;
36
+ var isWindows = process.platform === 'win32';
37
+ var REPO = 'ardelperal/codegraph';
38
+
39
+ main().catch(function (e) {
40
+ process.stderr.write('codegraph: ' + (e && e.message ? e.message : String(e)) + '\n');
41
+ process.exit(1);
42
+ });
43
+
44
+ async function main() {
45
+ // Happy path: the npm-installed optional dependency. Fall back to a download
46
+ // when the registry didn't deliver it.
47
+ var resolved = resolveInstalledBundle() || (await selfHealBundle());
48
+ var res = childProcess.spawnSync(resolved.command, resolved.args, { stdio: 'inherit' });
49
+ if (res.error) {
50
+ process.stderr.write('codegraph: ' + res.error.message + '\n');
51
+ process.exit(1);
52
+ }
53
+ process.exit(res.status === null ? 1 : res.status);
54
+ }
55
+
56
+ // Resolve the launcher from the installed per-platform optionalDependency.
57
+ // Returns {command, args} or null if the package isn't installed.
58
+ function resolveInstalledBundle() {
59
+ try {
60
+ if (isWindows) {
61
+ // Modern Node refuses to spawn the bundle's .cmd directly (EINVAL, the
62
+ // CVE-2024-27980 hardening on Node 24), so invoke the bundled node.exe
63
+ // against the app entry point and pass --liftoff-only here.
64
+ var nodeExe = require.resolve(pkg + '/node.exe');
65
+ var entry = require.resolve(pkg + '/lib/dist/bin/codegraph.js');
66
+ return { command: nodeExe, args: liftoff(entry) };
67
+ }
68
+ return { command: require.resolve(pkg + '/bin/codegraph'), args: process.argv.slice(2) };
69
+ } catch (e) {
70
+ return null;
71
+ }
72
+ }
73
+
74
+ // Locate the launcher inside an extracted GitHub bundle directory (same
75
+ // node/lib/bin layout as the npm platform package). Returns {command, args} or
76
+ // null when the directory doesn't hold a usable bundle yet.
77
+ function launcherIn(dir) {
78
+ if (isWindows) {
79
+ var nodeExe = path.join(dir, 'node.exe');
80
+ var entry = path.join(dir, 'lib', 'dist', 'bin', 'codegraph.js');
81
+ if (fs.existsSync(nodeExe) && fs.existsSync(entry)) {
82
+ return { command: nodeExe, args: liftoff(entry) };
83
+ }
84
+ } else {
85
+ var launcher = path.join(dir, 'bin', 'codegraph');
86
+ if (fs.existsSync(launcher)) return { command: launcher, args: process.argv.slice(2) };
87
+ }
88
+ return null;
89
+ }
90
+
91
+ // --liftoff-only keeps tree-sitter's WASM grammars off V8's turboshaft tier to
92
+ // avoid the Zone OOM on Node >= 22 (issues #293/#298). The unix bin/codegraph
93
+ // launcher already passes it; on Windows we invoke node.exe directly so add it.
94
+ function liftoff(entry) {
95
+ return ['--liftoff-only', entry].concat(process.argv.slice(2));
96
+ }
97
+
98
+ // Download + cache the platform bundle from GitHub Releases. Returns
99
+ // {command, args}; exits the process with guidance if it can't.
100
+ async function selfHealBundle() {
101
+ var version = readVersion();
102
+ var bundlesDir = path.join(process.env.CODEGRAPH_INSTALL_DIR || path.join(os.homedir(), '.codegraph'), 'bundles');
103
+ var dest = path.join(bundlesDir, target + '-' + version);
104
+
105
+ // Already downloaded by a previous run? Use it even when downloads are
106
+ // disabled — CODEGRAPH_NO_DOWNLOAD blocks fetching, not a cached bundle.
107
+ var cached = launcherIn(dest);
108
+ if (cached) return cached;
109
+
110
+ if (process.env.CODEGRAPH_NO_DOWNLOAD) {
111
+ fail('the network fallback is disabled (CODEGRAPH_NO_DOWNLOAD is set).');
112
+ }
113
+
114
+ var asset = 'codegraph-vba-' + target + (isWindows ? '.zip' : '.tar.gz');
115
+ var base = process.env.CODEGRAPH_DOWNLOAD_BASE || ('https://github.com/' + REPO + '/releases/download');
116
+ var url = base + '/v' + version + '/' + asset;
117
+
118
+ process.stderr.write(
119
+ 'codegraph: platform bundle missing (registry did not provide ' + pkg + ').\n' +
120
+ 'codegraph: downloading ' + asset + ' from GitHub Releases (' + version + ')...\n'
121
+ );
122
+
123
+ // Stage inside bundlesDir so the final rename is on the same filesystem (atomic,
124
+ // no EXDEV across tmpfs). Strip the archive's top-level codegraph-<target>/ dir.
125
+ fs.mkdirSync(bundlesDir, { recursive: true });
126
+ var stage = fs.mkdtempSync(path.join(bundlesDir, '.dl-'));
127
+ try {
128
+ var archivePath = path.join(stage, asset);
129
+ await download(url, archivePath, 6);
130
+ await verifyChecksum(archivePath, asset, base, version);
131
+ var extracted = path.join(stage, 'bundle');
132
+ fs.mkdirSync(extracted);
133
+ extract(archivePath, extracted);
134
+
135
+ var raced = launcherIn(dest); // another process may have finished meanwhile
136
+ if (raced) { rmrf(stage); return raced; }
137
+ try {
138
+ fs.renameSync(extracted, dest);
139
+ } catch (e) {
140
+ var other = launcherIn(dest); // lost the race but theirs is valid
141
+ if (other) { rmrf(stage); return other; }
142
+ throw e;
143
+ }
144
+ } catch (e) {
145
+ rmrf(stage);
146
+ fail('download failed (' + e.message + ').\n URL: ' + url);
147
+ }
148
+ rmrf(stage);
149
+
150
+ var ready = launcherIn(dest);
151
+ if (!ready) fail('downloaded bundle is missing its launcher under ' + dest + '.');
152
+ process.stderr.write('codegraph: bundle ready.\n');
153
+ return ready;
154
+ }
155
+
156
+ function readVersion() {
157
+ try {
158
+ return require(path.join(__dirname, 'package.json')).version;
159
+ } catch (e) {
160
+ fail('could not read this package\'s version to locate a matching release.');
161
+ }
162
+ }
163
+
164
+ // GET with manual redirect following (GitHub release URLs redirect to a CDN).
165
+ function download(url, dest, redirectsLeft) {
166
+ return new Promise(function (resolve, reject) {
167
+ var https = require('https');
168
+ // timeout is an idle/inactivity timeout — it won't kill a slow-but-progressing
169
+ // download, only a stalled connection (so a blocked mirror fails fast with
170
+ // guidance instead of hanging the user's command forever).
171
+ var req = https.get(url, { headers: { 'User-Agent': 'codegraph-npm-shim' }, timeout: 30000 }, function (res) {
172
+ var status = res.statusCode;
173
+ if (status >= 300 && status < 400 && res.headers.location) {
174
+ res.resume();
175
+ if (redirectsLeft <= 0) { reject(new Error('too many redirects')); return; }
176
+ download(new URL(res.headers.location, url).toString(), dest, redirectsLeft - 1).then(resolve, reject);
177
+ return;
178
+ }
179
+ if (status !== 200) { res.resume(); reject(new Error('HTTP ' + status)); return; }
180
+ var file = fs.createWriteStream(dest);
181
+ res.on('error', reject);
182
+ res.pipe(file);
183
+ file.on('error', reject);
184
+ file.on('finish', function () { file.close(function () { resolve(); }); });
185
+ });
186
+ req.on('timeout', function () { req.destroy(new Error('connection timed out')); });
187
+ req.on('error', reject);
188
+ });
189
+ }
190
+
191
+ // Best-effort integrity check. When the release publishes a SHA256SUMS file, the
192
+ // downloaded archive MUST match its listed hash or we abort. When that file is
193
+ // absent (older releases) or simply unreachable, we proceed — the archive still
194
+ // arrived from GitHub over TLS. So tampering/corruption is caught, while a
195
+ // missing checksum never breaks an install.
196
+ async function verifyChecksum(archivePath, asset, base, version) {
197
+ var sumsPath = archivePath + '.SHA256SUMS';
198
+ try {
199
+ await download(base + '/v' + version + '/SHA256SUMS', sumsPath, 6);
200
+ } catch (e) {
201
+ return; // not published / unreachable → skip
202
+ }
203
+ var expected = null;
204
+ var lines = fs.readFileSync(sumsPath, 'utf8').split('\n');
205
+ for (var i = 0; i < lines.length; i++) {
206
+ var m = lines[i].trim().match(/^([0-9a-fA-F]{64})\s+\*?(.+)$/);
207
+ if (m && path.basename(m[2].trim()) === asset) { expected = m[1].toLowerCase(); break; }
208
+ }
209
+ if (!expected) return; // asset not listed → nothing to check
210
+ var actual = require('crypto').createHash('sha256').update(fs.readFileSync(archivePath)).digest('hex');
211
+ if (actual !== expected) {
212
+ throw new Error('checksum mismatch for ' + asset +
213
+ ' (expected ' + expected.slice(0, 12) + '…, got ' + actual.slice(0, 12) + '…)');
214
+ }
215
+ process.stderr.write('codegraph: checksum verified.\n');
216
+ }
217
+
218
+ // Extract via the system tar — present on macOS, Linux, and Windows 10+
219
+ // (bsdtar reads .zip too). No third-party dependency in the shim.
220
+ function extract(archive, destDir) {
221
+ var args = isWindows
222
+ ? ['-xf', archive, '-C', destDir, '--strip-components=1']
223
+ : ['-xzf', archive, '-C', destDir, '--strip-components=1'];
224
+ var res = childProcess.spawnSync('tar', args, { stdio: 'ignore' });
225
+ if (res.error) throw new Error('tar unavailable: ' + res.error.message);
226
+ if (res.status !== 0) throw new Error('tar exited ' + res.status);
227
+ }
228
+
229
+ function rmrf(p) {
230
+ try { fs.rmSync(p, { recursive: true, force: true }); } catch (e) { /* best effort */ }
231
+ }
232
+
233
+ function fail(reason) {
234
+ process.stderr.write(
235
+ 'codegraph: no prebuilt bundle for ' + target + '.\n' +
236
+ (reason ? 'codegraph: ' + reason + '\n' : '') +
237
+ 'Expected the optional package ' + pkg + ' to be installed.\n' +
238
+ 'A registry mirror (e.g. npmmirror/cnpm) that did not mirror the per-platform\n' +
239
+ 'package is the usual cause. Fixes:\n' +
240
+ ' - install from the official registry:\n' +
241
+ ' npm i -g codegraph-vba --registry=https://registry.npmjs.org\n' +
242
+ ' - or use the standalone installer (no Node required):\n' +
243
+ ' curl -fsSL https://raw.githubusercontent.com/' + REPO + '/main/install.sh | sh\n'
244
+ );
245
+ process.exit(1);
246
+ }
package/package.json ADDED
@@ -0,0 +1,32 @@
1
+ {
2
+ "name": "@aroman22/codegraph-vba",
3
+ "version": "1.3.3",
4
+ "description": "Local-first code intelligence for AI agents (MCP). Self-contained — bundles its own runtime.",
5
+ "bin": {
6
+ "codegraph-vba": "npm-shim.js"
7
+ },
8
+ "main": "npm-sdk.js",
9
+ "types": "dist/index.d.ts",
10
+ "exports": {
11
+ ".": {
12
+ "types": "./dist/index.d.ts",
13
+ "default": "./npm-sdk.js"
14
+ },
15
+ "./package.json": "./package.json"
16
+ },
17
+ "optionalDependencies": {
18
+ "@aroman22/codegraph-vba-darwin-arm64": "1.3.3",
19
+ "@aroman22/codegraph-vba-darwin-x64": "1.3.3",
20
+ "@aroman22/codegraph-vba-linux-arm64": "1.3.3",
21
+ "@aroman22/codegraph-vba-linux-x64": "1.3.3",
22
+ "@aroman22/codegraph-vba-win32-arm64": "1.3.3",
23
+ "@aroman22/codegraph-vba-win32-x64": "1.3.3"
24
+ },
25
+ "files": [
26
+ "npm-shim.js",
27
+ "npm-sdk.js",
28
+ "dist",
29
+ "README.md"
30
+ ],
31
+ "license": "MIT"
32
+ }