depwire-cli 1.1.0 → 1.1.2
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/README.md +34 -25
- package/dist/{chunk-W3ZVSDFL.js → chunk-M5BETAND.js} +8 -8
- package/dist/{chunk-WLKW7X7G.js → chunk-ZO3LWFDE.js} +1465 -157
- package/dist/index.js +2 -2
- package/dist/mcpb-entry.js +2 -2
- package/dist/parser/grammars/tree-sitter-swift.wasm +0 -0
- package/dist/sdk.js +1 -1
- package/package.json +4 -2
package/README.md
CHANGED
|
@@ -2,28 +2,24 @@
|
|
|
2
2
|
|
|
3
3
|
<div align="center">
|
|
4
4
|
|
|
5
|
-
[
|
|
24
|
-

|
|
25
|
-

|
|
26
|
-

|
|
5
|
+
[](https://www.npmjs.com/package/depwire-cli)
|
|
6
|
+
[](https://www.npmjs.com/package/depwire-cli)
|
|
7
|
+
[](https://github.com/depwire/depwire/stargazers)
|
|
8
|
+
[](https://github.com/depwire/depwire/blob/main/LICENSE)
|
|
9
|
+
[](https://github.com/depwire/depwire)
|
|
10
|
+
|
|
11
|
+
[](https://github.com/depwire/depwire)
|
|
12
|
+
[](https://github.com/depwire/depwire)
|
|
13
|
+
[](https://github.com/depwire/depwire)
|
|
14
|
+
[](https://github.com/depwire/depwire)
|
|
15
|
+
[](https://github.com/depwire/depwire)
|
|
16
|
+
[](https://github.com/depwire/depwire)
|
|
17
|
+
[](https://github.com/depwire/depwire)
|
|
18
|
+
[](https://github.com/depwire/depwire)
|
|
19
|
+
|
|
20
|
+
[](https://www.youtube.com/watch?v=ujBg0H3eqpE)
|
|
21
|
+
[](https://www.youtube.com/watch?v=wdTJfSRTQu8)
|
|
22
|
+
[](https://app.depwire.dev)
|
|
27
23
|
|
|
28
24
|
</div>
|
|
29
25
|
|
|
@@ -35,7 +31,7 @@
|
|
|
35
31
|
<img src="./assets/deterministic_vs_rag_diagram.svg" alt="Depwire deterministic graph vs RAG probabilistic approach" width="680" />
|
|
36
32
|
</p>
|
|
37
33
|
|
|
38
|
-
Depwire builds a **DETERMINISTIC, NOT PROBABILISTIC** dependency graph of your codebase. This is not RAG. There are no embeddings, no similarity scores, no vector databases, no guesses. Depwire uses tree-sitter — the same parser powering GitHub's code intelligence — to extract exact symbol-level facts from every file: every function, every class, every interface, every import and export relationship, across
|
|
34
|
+
Depwire builds a **DETERMINISTIC, NOT PROBABILISTIC** dependency graph of your codebase. This is not RAG. There are no embeddings, no similarity scores, no vector databases, no guesses. Depwire uses tree-sitter — the same parser powering GitHub's code intelligence — to extract exact symbol-level facts from every file: every function, every class, every interface, every import and export relationship, across 12 programming languages. When you ask "what breaks if I delete `encodeToken` in `auth/token.ts`?", Depwire does not search for similar-looking code and estimate an answer. It traverses the exact dependency graph and returns the precise list of 14 files that import that symbol, which import chains break, and what your health score drops by. This is compiler-level precision applied to AI-assisted development — not a language model's best guess about your code.
|
|
39
35
|
|
|
40
36
|
**Not a build graph either.** Tools like Nx, Turborepo, and Grapher track package-level dependencies for build caching. Depwire tracks symbol-level dependencies — every function, class, and import relationship — which is what makes What If simulation, graph-aware security scanning, and exact blast radius analysis possible.
|
|
41
37
|
|
|
@@ -96,6 +92,15 @@ depwire viz # see your entire architecture instantly
|
|
|
96
92
|
|
|
97
93
|
---
|
|
98
94
|
|
|
95
|
+
## Tested on real-world projects
|
|
96
|
+
|
|
97
|
+
| Project | Language | Files | Symbols | Edges | Health Score |
|
|
98
|
+
|---------|----------|-------|---------|-------|--------------|
|
|
99
|
+
| [honojs/hono](https://github.com/honojs/hono) | TypeScript | 352 | 6,245 | 3,100+ | 41/100 |
|
|
100
|
+
| [CodeGraphContext/CodeGraphContext](https://github.com/CodeGraphContext/CodeGraphContext) | Python/TS | 398 | 12,001 | 5,406 | 66/100 |
|
|
101
|
+
|
|
102
|
+
---
|
|
103
|
+
|
|
99
104
|
## What If simulation
|
|
100
105
|
|
|
101
106
|
Know the blast radius before you touch anything.
|
|
@@ -322,7 +327,7 @@ The SDK is the stable public API surface. All integrations should import from `d
|
|
|
322
327
|
|
|
323
328
|
## Language support
|
|
324
329
|
|
|
325
|
-
TypeScript, JavaScript, Python, Go, Rust, C, C#, Java, C++, Kotlin, PHP — with cross-language edge detection between all supported languages.
|
|
330
|
+
TypeScript, JavaScript, Python, Go, Rust, C, C#, Java, C++, Kotlin, PHP, Swift, Mojo — with cross-language edge detection between all supported languages.
|
|
326
331
|
|
|
327
332
|
**Java / JVM** — classes, interfaces, enums, records, annotations, inner classes, anonymous classes, lambda expressions, Maven pom.xml and Gradle build file dependency edges, Spring Boot cross-language edges (@GetMapping, @PostMapping, @RequestMapping), JAX-RS / Jakarta EE route detection, Spring WebFlux RouterFunction support.
|
|
328
333
|
|
|
@@ -334,6 +339,10 @@ TypeScript, JavaScript, Python, Go, Rust, C, C#, Java, C++, Kotlin, PHP — with
|
|
|
334
339
|
|
|
335
340
|
**PHP / Web** — functions, classes, methods, interfaces, traits, enums, namespaces, use statements, require/include dependency edges. Both procedural and OOP styles. Laravel (Route::get/post/put/delete/patch, middleware), Symfony (#[Route(...)]), Slim Framework, and WordPress REST API (register_rest_route) cross-language route detection. Guzzle and file_get_contents HTTP client edge detection. Dead code detection with WordPress hooks, Laravel service providers, Symfony controllers, and magic method exclusions (__construct, __get, __set, __call). Security scanner: database query injection patterns, dynamic code execution patterns, OS command execution patterns, regex modifier vulnerabilities, unsafe deserialization patterns, unsafe variable extraction patterns, weak hashing for passwords, deprecated crypto libraries, weak PRNG in security contexts, hardcoded credentials.
|
|
336
341
|
|
|
342
|
+
**Swift / Apple** — functions, methods, initializers (init), deinitializers (deinit), classes, structs, enums, protocols, extensions, actors (Swift concurrency), properties (var, let), computed properties, type aliases, associated types. Package.swift (SPM) dependency parsing. Vapor, Hummingbird, and Perfect cross-language route detection. URLSession and Alamofire HTTP client edge detection. Dead code detection with AppDelegate/SceneDelegate lifecycle, SwiftUI View body, @IBAction/@IBOutlet, @objc, protocol conformance, Codable synthesis, XCTestCase, and @main entry point exclusions. Security scanner: SQL injection via string interpolation, Process() command injection, unsafe pointer usage, UserDefaults storing sensitive data, CC_MD5/CC_SHA1 weak hashing, Insecure.MD5/SHA1 from CryptoKit, arc4random in crypto contexts, App Transport Security bypass, hardcoded credentials, hardcoded HTTP URLs.
|
|
343
|
+
|
|
344
|
+
**Mojo / AI-native** *(strategic support)* — fn (typed functions), def (Python-compatible functions), structs (value types), classes, traits (interfaces), alias (type aliases and compile-time constants), var/let declarations, import and from...import statements. Pattern-based parser (no tree-sitter-mojo available). Supports @value, @register_passable, @staticmethod decorators, inout/owned/borrowed parameter modifiers, SIMD/Tensor/DType type references. mojoproject.toml dependency parsing. Python interop detection (from python import). Cross-language route detection via Python framework interop (FastAPI/Starlette). Dead code detection with __init__/__copyinit__/__moveinit__ lifecycle, trait implementations, MLIR dialect operations, and @export exclusions. Security scanner: Pointer[T] and DTypePointer unsafe memory, Python eval() via interop, uninitialized memory patterns, SIMD store/load without bounds checking, weak random via Python random module, hardcoded keys in alias declarations, hashlib via Python interop in crypto contexts. *Mojo is the first AI-native language supported by Depwire.*
|
|
345
|
+
|
|
337
346
|
---
|
|
338
347
|
|
|
339
348
|
## GitHub Action — PR Impact Analysis
|
|
@@ -396,7 +405,7 @@ Block PRs that hurt your architecture:
|
|
|
396
405
|
**Shipped**
|
|
397
406
|
- Arc diagram visualization
|
|
398
407
|
- 17 MCP tools
|
|
399
|
-
- Multi-language support (TypeScript, JavaScript, Python, Go, Rust, C, C#, Java, C++, Kotlin, PHP)
|
|
408
|
+
- Multi-language support (TypeScript, JavaScript, Python, Go, Rust, C, C#, Java, C++, Kotlin, PHP, Swift, Mojo)
|
|
400
409
|
- Architecture health score
|
|
401
410
|
- Dead code detection
|
|
402
411
|
- Temporal graph
|
|
@@ -16,7 +16,7 @@ import {
|
|
|
16
16
|
parseTypeScriptFile,
|
|
17
17
|
scanSecurity,
|
|
18
18
|
searchSymbols
|
|
19
|
-
} from "./chunk-
|
|
19
|
+
} from "./chunk-ZO3LWFDE.js";
|
|
20
20
|
|
|
21
21
|
// src/viz/data.ts
|
|
22
22
|
import { basename } from "path";
|
|
@@ -122,26 +122,26 @@ function watchProject(projectRoot, callbacks) {
|
|
|
122
122
|
const watcher = chokidar.watch(projectRoot, watcherOptions);
|
|
123
123
|
console.error("[Watcher] Attaching event listeners...");
|
|
124
124
|
watcher.on("change", (absolutePath) => {
|
|
125
|
-
const validExtensions = [".ts", ".tsx", ".js", ".jsx", ".mjs", ".cjs", ".py", ".go", ".rs", ".c", ".h", ".cs", ".csx", ".csproj", ".java", ".kt", ".kts", ".cpp", ".cc", ".cxx", ".c++", ".hpp", ".hh", ".hxx", ".h++", ".inl", ".ipp", ".php"];
|
|
125
|
+
const validExtensions = [".ts", ".tsx", ".js", ".jsx", ".mjs", ".cjs", ".py", ".go", ".rs", ".c", ".h", ".cs", ".csx", ".csproj", ".java", ".kt", ".kts", ".cpp", ".cc", ".cxx", ".c++", ".hpp", ".hh", ".hxx", ".h++", ".inl", ".ipp", ".php", ".swift", ".mojo", ".\u{1F525}"];
|
|
126
126
|
if (!validExtensions.some((ext) => absolutePath.endsWith(ext))) return;
|
|
127
127
|
const fileName = absolutePath.split("/").pop() || "";
|
|
128
|
-
if (!validExtensions.some((ext) => absolutePath.endsWith(ext)) && !["pom.xml", "build.gradle", "build.gradle.kts", "settings.gradle.kts", "settings.gradle", "CMakeLists.txt", "conanfile.txt", "vcpkg.json"].includes(fileName)) return;
|
|
128
|
+
if (!validExtensions.some((ext) => absolutePath.endsWith(ext)) && !["pom.xml", "build.gradle", "build.gradle.kts", "settings.gradle.kts", "settings.gradle", "CMakeLists.txt", "conanfile.txt", "vcpkg.json", "Package.swift", "mojoproject.toml"].includes(fileName)) return;
|
|
129
129
|
if (absolutePath.endsWith("_test.go")) return;
|
|
130
130
|
const relativePath = absolutePath.replace(projectRoot + "/", "");
|
|
131
131
|
console.error(`[Watcher] Change event: ${relativePath}`);
|
|
132
132
|
callbacks.onFileChanged(relativePath);
|
|
133
133
|
});
|
|
134
134
|
watcher.on("add", (absolutePath) => {
|
|
135
|
-
const validExtensions = [".ts", ".tsx", ".js", ".jsx", ".mjs", ".cjs", ".py", ".go", ".rs", ".c", ".h", ".cs", ".csx", ".csproj", ".java", ".kt", ".kts", ".cpp", ".cc", ".cxx", ".c++", ".hpp", ".hh", ".hxx", ".h++", ".inl", ".ipp", ".php"];
|
|
135
|
+
const validExtensions = [".ts", ".tsx", ".js", ".jsx", ".mjs", ".cjs", ".py", ".go", ".rs", ".c", ".h", ".cs", ".csx", ".csproj", ".java", ".kt", ".kts", ".cpp", ".cc", ".cxx", ".c++", ".hpp", ".hh", ".hxx", ".h++", ".inl", ".ipp", ".php", ".swift", ".mojo", ".\u{1F525}"];
|
|
136
136
|
const addFileName = absolutePath.split("/").pop() || "";
|
|
137
|
-
if (!validExtensions.some((ext) => absolutePath.endsWith(ext)) && !["pom.xml", "build.gradle", "build.gradle.kts", "settings.gradle.kts", "settings.gradle", "CMakeLists.txt", "conanfile.txt", "vcpkg.json"].includes(addFileName)) return;
|
|
137
|
+
if (!validExtensions.some((ext) => absolutePath.endsWith(ext)) && !["pom.xml", "build.gradle", "build.gradle.kts", "settings.gradle.kts", "settings.gradle", "CMakeLists.txt", "conanfile.txt", "vcpkg.json", "Package.swift", "mojoproject.toml"].includes(addFileName)) return;
|
|
138
138
|
if (absolutePath.endsWith("_test.go")) return;
|
|
139
139
|
const relativePath = absolutePath.replace(projectRoot + "/", "");
|
|
140
140
|
console.error(`[Watcher] Add event: ${relativePath}`);
|
|
141
141
|
callbacks.onFileAdded(relativePath);
|
|
142
142
|
});
|
|
143
143
|
watcher.on("unlink", (absolutePath) => {
|
|
144
|
-
const validExtensions = [".ts", ".tsx", ".js", ".jsx", ".mjs", ".cjs", ".py", ".go", ".rs", ".c", ".h", ".cs", ".csx", ".csproj", ".java", ".kt", ".kts", ".cpp", ".cc", ".cxx", ".c++", ".hpp", ".hh", ".hxx", ".h++", ".inl", ".ipp", ".php"];
|
|
144
|
+
const validExtensions = [".ts", ".tsx", ".js", ".jsx", ".mjs", ".cjs", ".py", ".go", ".rs", ".c", ".h", ".cs", ".csx", ".csproj", ".java", ".kt", ".kts", ".cpp", ".cc", ".cxx", ".c++", ".hpp", ".hh", ".hxx", ".h++", ".inl", ".ipp", ".php", ".swift", ".mojo", ".\u{1F525}"];
|
|
145
145
|
if (!validExtensions.some((ext) => absolutePath.endsWith(ext))) return;
|
|
146
146
|
if (absolutePath.endsWith("_test.go")) return;
|
|
147
147
|
const relativePath = absolutePath.replace(projectRoot + "/", "");
|
|
@@ -159,10 +159,10 @@ function watchProject(projectRoot, callbacks) {
|
|
|
159
159
|
for (const dir of dirs) {
|
|
160
160
|
const files = watched[dir];
|
|
161
161
|
fileCount += files.filter(
|
|
162
|
-
(f) => f.endsWith(".ts") || f.endsWith(".tsx") || f.endsWith(".js") || f.endsWith(".jsx") || f.endsWith(".mjs") || f.endsWith(".cjs") || f.endsWith(".py") || f.endsWith(".go") && !f.endsWith("_test.go") || f.endsWith(".rs") || f.endsWith(".c") || f.endsWith(".h") || f.endsWith(".cs") || f.endsWith(".csx") || f.endsWith(".csproj") || f.endsWith(".java") || f === "pom.xml" || f === "build.gradle" || f === "build.gradle.kts" || f.endsWith(".kt") || f.endsWith(".kts") || f === "settings.gradle.kts" || f === "settings.gradle" || f.endsWith(".php") || f.endsWith(".cpp") || f.endsWith(".cc") || f.endsWith(".cxx") || f.endsWith(".c++") || f.endsWith(".hpp") || f.endsWith(".hh") || f.endsWith(".hxx") || f.endsWith(".h++") || f.endsWith(".inl") || f.endsWith(".ipp") || f === "CMakeLists.txt" || f === "conanfile.txt" || f === "vcpkg.json"
|
|
162
|
+
(f) => f.endsWith(".ts") || f.endsWith(".tsx") || f.endsWith(".js") || f.endsWith(".jsx") || f.endsWith(".mjs") || f.endsWith(".cjs") || f.endsWith(".py") || f.endsWith(".go") && !f.endsWith("_test.go") || f.endsWith(".rs") || f.endsWith(".c") || f.endsWith(".h") || f.endsWith(".cs") || f.endsWith(".csx") || f.endsWith(".csproj") || f.endsWith(".java") || f === "pom.xml" || f === "build.gradle" || f === "build.gradle.kts" || f.endsWith(".kt") || f.endsWith(".kts") || f === "settings.gradle.kts" || f === "settings.gradle" || f.endsWith(".php") || f.endsWith(".swift") || f.endsWith(".mojo") || f.endsWith(".\u{1F525}") || f.endsWith(".cpp") || f.endsWith(".cc") || f.endsWith(".cxx") || f.endsWith(".c++") || f.endsWith(".hpp") || f.endsWith(".hh") || f.endsWith(".hxx") || f.endsWith(".h++") || f.endsWith(".inl") || f.endsWith(".ipp") || f === "CMakeLists.txt" || f === "conanfile.txt" || f === "vcpkg.json"
|
|
163
163
|
).length;
|
|
164
164
|
}
|
|
165
|
-
console.error(`[Watcher] Watching ${fileCount} TypeScript/JavaScript/Python/Go/Rust/C/C++/C#/Java/Kotlin/PHP files in ${dirs.length} directories`);
|
|
165
|
+
console.error(`[Watcher] Watching ${fileCount} TypeScript/JavaScript/Python/Go/Rust/C/C++/C#/Java/Kotlin/PHP/Swift/Mojo files in ${dirs.length} directories`);
|
|
166
166
|
});
|
|
167
167
|
return watcher;
|
|
168
168
|
}
|