pi-compass 0.2.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 (102) hide show
  1. package/README.md +74 -0
  2. package/dist/analyzers/build-script-detector.d.ts +3 -0
  3. package/dist/analyzers/build-script-detector.d.ts.map +1 -0
  4. package/dist/analyzers/build-script-detector.js +75 -0
  5. package/dist/analyzers/build-script-detector.js.map +1 -0
  6. package/dist/analyzers/convention-detector.d.ts +3 -0
  7. package/dist/analyzers/convention-detector.d.ts.map +1 -0
  8. package/dist/analyzers/convention-detector.js +47 -0
  9. package/dist/analyzers/convention-detector.js.map +1 -0
  10. package/dist/analyzers/directory-tree.d.ts +4 -0
  11. package/dist/analyzers/directory-tree.d.ts.map +1 -0
  12. package/dist/analyzers/directory-tree.js +60 -0
  13. package/dist/analyzers/directory-tree.js.map +1 -0
  14. package/dist/analyzers/entry-point-detector.d.ts +3 -0
  15. package/dist/analyzers/entry-point-detector.d.ts.map +1 -0
  16. package/dist/analyzers/entry-point-detector.js +87 -0
  17. package/dist/analyzers/entry-point-detector.js.map +1 -0
  18. package/dist/analyzers/framework-detector.d.ts +3 -0
  19. package/dist/analyzers/framework-detector.d.ts.map +1 -0
  20. package/dist/analyzers/framework-detector.js +63 -0
  21. package/dist/analyzers/framework-detector.js.map +1 -0
  22. package/dist/analyzers/index.d.ts +8 -0
  23. package/dist/analyzers/index.d.ts.map +1 -0
  24. package/dist/analyzers/index.js +8 -0
  25. package/dist/analyzers/index.js.map +1 -0
  26. package/dist/analyzers/key-file-detector.d.ts +3 -0
  27. package/dist/analyzers/key-file-detector.d.ts.map +1 -0
  28. package/dist/analyzers/key-file-detector.js +32 -0
  29. package/dist/analyzers/key-file-detector.js.map +1 -0
  30. package/dist/analyzers/package-detector.d.ts +3 -0
  31. package/dist/analyzers/package-detector.d.ts.map +1 -0
  32. package/dist/analyzers/package-detector.js +78 -0
  33. package/dist/analyzers/package-detector.js.map +1 -0
  34. package/dist/codemap-formatter.d.ts +4 -0
  35. package/dist/codemap-formatter.d.ts.map +1 -0
  36. package/dist/codemap-formatter.js +72 -0
  37. package/dist/codemap-formatter.js.map +1 -0
  38. package/dist/codemap-generator.d.ts +10 -0
  39. package/dist/codemap-generator.d.ts.map +1 -0
  40. package/dist/codemap-generator.js +80 -0
  41. package/dist/codemap-generator.js.map +1 -0
  42. package/dist/codemap-injector.d.ts +12 -0
  43. package/dist/codemap-injector.d.ts.map +1 -0
  44. package/dist/codemap-injector.js +20 -0
  45. package/dist/codemap-injector.js.map +1 -0
  46. package/dist/fs-utils.d.ts +3 -0
  47. package/dist/fs-utils.d.ts.map +1 -0
  48. package/dist/fs-utils.js +21 -0
  49. package/dist/fs-utils.js.map +1 -0
  50. package/dist/index.d.ts +3 -0
  51. package/dist/index.d.ts.map +1 -0
  52. package/dist/index.js +69 -0
  53. package/dist/index.js.map +1 -0
  54. package/dist/onboard-command.d.ts +5 -0
  55. package/dist/onboard-command.d.ts.map +1 -0
  56. package/dist/onboard-command.js +33 -0
  57. package/dist/onboard-command.js.map +1 -0
  58. package/dist/onboard-tools.d.ts +4 -0
  59. package/dist/onboard-tools.d.ts.map +1 -0
  60. package/dist/onboard-tools.js +77 -0
  61. package/dist/onboard-tools.js.map +1 -0
  62. package/dist/project.d.ts +4 -0
  63. package/dist/project.d.ts.map +1 -0
  64. package/dist/project.js +20 -0
  65. package/dist/project.js.map +1 -0
  66. package/dist/storage.d.ts +12 -0
  67. package/dist/storage.d.ts.map +1 -0
  68. package/dist/storage.js +46 -0
  69. package/dist/storage.js.map +1 -0
  70. package/dist/tour-command.d.ts +5 -0
  71. package/dist/tour-command.d.ts.map +1 -0
  72. package/dist/tour-command.js +26 -0
  73. package/dist/tour-command.js.map +1 -0
  74. package/dist/tour-generator.d.ts +6 -0
  75. package/dist/tour-generator.d.ts.map +1 -0
  76. package/dist/tour-generator.js +204 -0
  77. package/dist/tour-generator.js.map +1 -0
  78. package/dist/types.d.ts +89 -0
  79. package/dist/types.d.ts.map +1 -0
  80. package/dist/types.js +2 -0
  81. package/dist/types.js.map +1 -0
  82. package/package.json +71 -0
  83. package/src/analyzers/build-script-detector.ts +85 -0
  84. package/src/analyzers/convention-detector.ts +52 -0
  85. package/src/analyzers/directory-tree.ts +65 -0
  86. package/src/analyzers/entry-point-detector.ts +98 -0
  87. package/src/analyzers/framework-detector.ts +76 -0
  88. package/src/analyzers/index.ts +7 -0
  89. package/src/analyzers/key-file-detector.ts +36 -0
  90. package/src/analyzers/package-detector.ts +87 -0
  91. package/src/codemap-formatter.ts +90 -0
  92. package/src/codemap-generator.ts +110 -0
  93. package/src/codemap-injector.ts +44 -0
  94. package/src/fs-utils.ts +19 -0
  95. package/src/index.ts +90 -0
  96. package/src/onboard-command.ts +60 -0
  97. package/src/onboard-tools.ts +116 -0
  98. package/src/project.ts +29 -0
  99. package/src/storage.ts +82 -0
  100. package/src/tour-command.ts +50 -0
  101. package/src/tour-generator.ts +237 -0
  102. package/src/types.ts +104 -0
package/README.md ADDED
@@ -0,0 +1,74 @@
1
+ # pi-compass
2
+
3
+ Codebase navigation for [Pi coding agent](https://github.com/nicholasgasior/pi-coding-agent) sessions. Generates structured codemaps and interactive code tours so agents (and developers) can orient themselves in unfamiliar repos without burning tokens on exploration.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ pi install npm:pi-compass
9
+ ```
10
+
11
+ ## Usage
12
+
13
+ ### Generate a codebase map
14
+
15
+ ```
16
+ /onboard
17
+ ```
18
+
19
+ Analyzes the current repo and generates a structured map covering:
20
+ - Directory structure
21
+ - Package managers and dependencies
22
+ - Detected frameworks
23
+ - Entry points
24
+ - Build, test, and deploy scripts
25
+ - Coding conventions (from AGENTS.md, CLAUDE.md, lint configs, etc.)
26
+ - Key files (README, LICENSE, CI configs, etc.)
27
+
28
+ The map is cached and automatically injected into the agent's system prompt on the first turn of each session.
29
+
30
+ ### Force regeneration
31
+
32
+ ```
33
+ /onboard --refresh
34
+ ```
35
+
36
+ ### Take a code tour
37
+
38
+ ```
39
+ /tour # list available topics
40
+ /tour auth # guided walkthrough of the auth module
41
+ /tour testing # walkthrough of test infrastructure
42
+ /tour ci # walkthrough of CI/CD configuration
43
+ ```
44
+
45
+ Topics are detected automatically from directory structure and project configuration.
46
+
47
+ ## LLM Tools
48
+
49
+ | Tool | Description |
50
+ |------|-------------|
51
+ | `codebase_map` | Returns the cached codemap (generates if missing) |
52
+ | `code_tour` | Returns a guided walkthrough for a topic, or lists available topics |
53
+
54
+ ## How it works
55
+
56
+ All analysis is deterministic (no LLM calls). The extension reads config files, directory listings, and package manifests to build a structured overview. Results are cached per project with content-hash invalidation: the cache is marked stale when key config files or the directory structure changes.
57
+
58
+ ### Cache invalidation
59
+
60
+ The content hash covers: package.json, tsconfig.json, go.mod, Cargo.toml, pyproject.toml, and the top-level directory listing. When any of these change, the cached codemap is marked stale. Stale maps are still served (better than nothing) with a note to run `/onboard` to refresh.
61
+
62
+ ## Storage
63
+
64
+ ```
65
+ ~/.pi/compass/
66
+ projects/<project-hash>/
67
+ codemap.json # Cached codemap
68
+ tours/
69
+ <topic>.json # Cached tours
70
+ ```
71
+
72
+ ## License
73
+
74
+ MIT
@@ -0,0 +1,3 @@
1
+ import type { BuildScript } from "../types.js";
2
+ export declare function detectBuildScripts(cwd: string): readonly BuildScript[];
3
+ //# sourceMappingURL=build-script-detector.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"build-script-detector.d.ts","sourceRoot":"","sources":["../../src/analyzers/build-script-detector.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAQ/C,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,WAAW,EAAE,CAStE"}
@@ -0,0 +1,75 @@
1
+ import { existsSync, readFileSync } from "node:fs";
2
+ import { join } from "node:path";
3
+ const INTERESTING_SCRIPTS = new Set([
4
+ "build", "dev", "start", "test", "lint", "check",
5
+ "typecheck", "format", "deploy", "clean", "serve",
6
+ "preview", "generate", "migrate", "seed",
7
+ ]);
8
+ export function detectBuildScripts(cwd) {
9
+ const results = [];
10
+ results.push(...extractNpmScripts(cwd));
11
+ results.push(...extractMakefileTargets(cwd));
12
+ results.push(...detectCiFiles(cwd));
13
+ results.push(...detectContainerFiles(cwd));
14
+ return results;
15
+ }
16
+ function extractNpmScripts(cwd) {
17
+ try {
18
+ const raw = readFileSync(join(cwd, "package.json"), "utf-8");
19
+ const pkg = JSON.parse(raw);
20
+ const scripts = pkg["scripts"];
21
+ if (!scripts || typeof scripts !== "object")
22
+ return [];
23
+ return Object.entries(scripts)
24
+ .filter(([name]) => INTERESTING_SCRIPTS.has(name))
25
+ .map(([name, cmd]) => ({
26
+ name,
27
+ command: typeof cmd === "string" ? cmd : String(cmd),
28
+ source: "package.json",
29
+ }));
30
+ }
31
+ catch {
32
+ return [];
33
+ }
34
+ }
35
+ function extractMakefileTargets(cwd) {
36
+ const makefilePath = join(cwd, "Makefile");
37
+ try {
38
+ const content = readFileSync(makefilePath, "utf-8");
39
+ const targets = [...content.matchAll(/^([a-zA-Z_][\w-]*)\s*:/gm)];
40
+ return targets
41
+ .filter(([, name]) => name && !name.startsWith("."))
42
+ .map(([, name]) => ({
43
+ name: name,
44
+ command: `make ${name}`,
45
+ source: "Makefile",
46
+ }));
47
+ }
48
+ catch {
49
+ return [];
50
+ }
51
+ }
52
+ function detectCiFiles(cwd) {
53
+ const results = [];
54
+ if (existsSync(join(cwd, ".github", "workflows"))) {
55
+ results.push({ name: "ci", command: "GitHub Actions", source: ".github/workflows/" });
56
+ }
57
+ if (existsSync(join(cwd, ".gitlab-ci.yml"))) {
58
+ results.push({ name: "ci", command: "GitLab CI", source: ".gitlab-ci.yml" });
59
+ }
60
+ if (existsSync(join(cwd, "Jenkinsfile"))) {
61
+ results.push({ name: "ci", command: "Jenkins", source: "Jenkinsfile" });
62
+ }
63
+ return results;
64
+ }
65
+ function detectContainerFiles(cwd) {
66
+ const results = [];
67
+ if (existsSync(join(cwd, "Dockerfile"))) {
68
+ results.push({ name: "docker", command: "docker build", source: "Dockerfile" });
69
+ }
70
+ if (existsSync(join(cwd, "docker-compose.yml")) || existsSync(join(cwd, "docker-compose.yaml"))) {
71
+ results.push({ name: "docker-compose", command: "docker compose up", source: "docker-compose.yml" });
72
+ }
73
+ return results;
74
+ }
75
+ //# sourceMappingURL=build-script-detector.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"build-script-detector.js","sourceRoot":"","sources":["../../src/analyzers/build-script-detector.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { Convention } from "../types.js";
2
+ export declare function detectConventions(cwd: string): readonly Convention[];
3
+ //# sourceMappingURL=convention-detector.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"convention-detector.d.ts","sourceRoot":"","sources":["../../src/analyzers/convention-detector.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AA+B9C,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,UAAU,EAAE,CAcpE"}
@@ -0,0 +1,47 @@
1
+ import { join } from "node:path";
2
+ import { readTextFile } from "../fs-utils.js";
3
+ const MAX_CONTENT_LENGTH = 2000;
4
+ const CONVENTION_FILES = [
5
+ "AGENTS.md",
6
+ "CLAUDE.md",
7
+ "GEMINI.md",
8
+ ".editorconfig",
9
+ "eslint.config.js",
10
+ "eslint.config.ts",
11
+ "eslint.config.mjs",
12
+ ".eslintrc.json",
13
+ ".eslintrc.js",
14
+ ".eslintrc.yml",
15
+ "prettier.config.js",
16
+ "prettier.config.ts",
17
+ ".prettierrc",
18
+ ".prettierrc.json",
19
+ "biome.json",
20
+ "biome.jsonc",
21
+ "rustfmt.toml",
22
+ ".golangci.yml",
23
+ ".golangci.yaml",
24
+ "CONTRIBUTING.md",
25
+ ".stylelintrc.json",
26
+ "deno.json",
27
+ "deno.jsonc",
28
+ ];
29
+ export function detectConventions(cwd) {
30
+ const results = [];
31
+ for (const file of CONVENTION_FILES) {
32
+ const content = readTextFile(join(cwd, file));
33
+ if (content !== null) {
34
+ results.push({
35
+ source: file,
36
+ content: truncate(content, MAX_CONTENT_LENGTH),
37
+ });
38
+ }
39
+ }
40
+ return results;
41
+ }
42
+ function truncate(text, maxLength) {
43
+ if (text.length <= maxLength)
44
+ return text;
45
+ return text.slice(0, maxLength) + "\n... (truncated)";
46
+ }
47
+ //# sourceMappingURL=convention-detector.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"convention-detector.js","sourceRoot":"","sources":["../../src/analyzers/convention-detector.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAE9C,MAAM,kBAAkB,GAAG,IAAI,CAAC;AAEhC,MAAM,gBAAgB,GAAsB;IAC1C,WAAW;IACX,WAAW;IACX,WAAW;IACX,eAAe;IACf,kBAAkB;IAClB,kBAAkB;IAClB,mBAAmB;IACnB,gBAAgB;IAChB,cAAc;IACd,eAAe;IACf,oBAAoB;IACpB,oBAAoB;IACpB,aAAa;IACb,kBAAkB;IAClB,YAAY;IACZ,aAAa;IACb,cAAc;IACd,eAAe;IACf,gBAAgB;IAChB,iBAAiB;IACjB,mBAAmB;IACnB,WAAW;IACX,YAAY;CACb,CAAC;AAEF,MAAM,UAAU,iBAAiB,CAAC,GAAW;IAC3C,MAAM,OAAO,GAAiB,EAAE,CAAC;IAEjC,KAAK,MAAM,IAAI,IAAI,gBAAgB,EAAE,CAAC;QACpC,MAAM,OAAO,GAAG,YAAY,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC,CAAC;QAC9C,IAAI,OAAO,KAAK,IAAI,EAAE,CAAC;YACrB,OAAO,CAAC,IAAI,CAAC;gBACX,MAAM,EAAE,IAAI;gBACZ,OAAO,EAAE,QAAQ,CAAC,OAAO,EAAE,kBAAkB,CAAC;aAC/C,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,SAAS,QAAQ,CAAC,IAAY,EAAE,SAAiB;IAC/C,IAAI,IAAI,CAAC,MAAM,IAAI,SAAS;QAAE,OAAO,IAAI,CAAC;IAC1C,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,SAAS,CAAC,GAAG,mBAAmB,CAAC;AACxD,CAAC"}
@@ -0,0 +1,4 @@
1
+ import type { DirectoryEntry } from "../types.js";
2
+ export declare function buildDirectoryTree(cwd: string, depth?: number): readonly DirectoryEntry[];
3
+ export declare function formatDirectoryTree(entries: readonly DirectoryEntry[], indent?: string): string;
4
+ //# sourceMappingURL=directory-tree.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"directory-tree.d.ts","sourceRoot":"","sources":["../../src/analyzers/directory-tree.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AASlD,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,SAAI,GAAG,SAAS,cAAc,EAAE,CAEpF;AAqCD,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,SAAS,cAAc,EAAE,EAAE,MAAM,SAAK,GAAG,MAAM,CAc3F"}
@@ -0,0 +1,60 @@
1
+ import { readdirSync, statSync } from "node:fs";
2
+ import { join } from "node:path";
3
+ const IGNORED_DIRS = new Set([
4
+ "node_modules", ".git", "dist", "build", ".next", ".nuxt",
5
+ "__pycache__", ".tox", ".mypy_cache", ".pytest_cache",
6
+ "target", ".gradle", ".idea", ".vscode",
7
+ "vendor", "coverage", ".turbo", ".cache",
8
+ ]);
9
+ export function buildDirectoryTree(cwd, depth = 2) {
10
+ return scanDir(cwd, cwd, depth);
11
+ }
12
+ function scanDir(dir, root, remaining) {
13
+ if (remaining <= 0)
14
+ return [];
15
+ let entries;
16
+ try {
17
+ entries = readdirSync(dir);
18
+ }
19
+ catch {
20
+ return [];
21
+ }
22
+ const result = [];
23
+ for (const name of entries.sort()) {
24
+ if (name.startsWith(".") && name !== ".github")
25
+ continue;
26
+ if (IGNORED_DIRS.has(name))
27
+ continue;
28
+ const fullPath = join(dir, name);
29
+ let stat;
30
+ try {
31
+ stat = statSync(fullPath);
32
+ }
33
+ catch {
34
+ continue;
35
+ }
36
+ if (stat.isDirectory()) {
37
+ const children = remaining > 1 ? scanDir(fullPath, root, remaining - 1) : undefined;
38
+ result.push({ name, type: "dir", ...(children ? { children } : {}) });
39
+ }
40
+ else if (stat.isFile()) {
41
+ result.push({ name, type: "file" });
42
+ }
43
+ }
44
+ return result;
45
+ }
46
+ export function formatDirectoryTree(entries, indent = "") {
47
+ const lines = [];
48
+ for (let i = 0; i < entries.length; i++) {
49
+ const entry = entries[i];
50
+ const isLast = i === entries.length - 1;
51
+ const prefix = isLast ? "└── " : "├── ";
52
+ const childIndent = indent + (isLast ? " " : "│ ");
53
+ lines.push(`${indent}${prefix}${entry.name}${entry.type === "dir" ? "/" : ""}`);
54
+ if (entry.children && entry.children.length > 0) {
55
+ lines.push(formatDirectoryTree(entry.children, childIndent));
56
+ }
57
+ }
58
+ return lines.join("\n");
59
+ }
60
+ //# sourceMappingURL=directory-tree.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"directory-tree.js","sourceRoot":"","sources":["../../src/analyzers/directory-tree.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAChD,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAGjC,MAAM,YAAY,GAAG,IAAI,GAAG,CAAC;IAC3B,cAAc,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO;IACzD,aAAa,EAAE,MAAM,EAAE,aAAa,EAAE,eAAe;IACrD,QAAQ,EAAE,SAAS,EAAE,OAAO,EAAE,SAAS;IACvC,QAAQ,EAAE,UAAU,EAAE,QAAQ,EAAE,QAAQ;CACzC,CAAC,CAAC;AAEH,MAAM,UAAU,kBAAkB,CAAC,GAAW,EAAE,KAAK,GAAG,CAAC;IACvD,OAAO,OAAO,CAAC,GAAG,EAAE,GAAG,EAAE,KAAK,CAAC,CAAC;AAClC,CAAC;AAED,SAAS,OAAO,CAAC,GAAW,EAAE,IAAY,EAAE,SAAiB;IAC3D,IAAI,SAAS,IAAI,CAAC;QAAE,OAAO,EAAE,CAAC;IAE9B,IAAI,OAAiB,CAAC;IACtB,IAAI,CAAC;QACH,OAAO,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC;IAC7B,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,MAAM,MAAM,GAAqB,EAAE,CAAC;IAEpC,KAAK,MAAM,IAAI,IAAI,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC;QAClC,IAAI,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,IAAI,KAAK,SAAS;YAAE,SAAS;QACzD,IAAI,YAAY,CAAC,GAAG,CAAC,IAAI,CAAC;YAAE,SAAS;QAErC,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;QACjC,IAAI,IAAI,CAAC;QACT,IAAI,CAAC;YACH,IAAI,GAAG,QAAQ,CAAC,QAAQ,CAAC,CAAC;QAC5B,CAAC;QAAC,MAAM,CAAC;YACP,SAAS;QACX,CAAC;QAED,IAAI,IAAI,CAAC,WAAW,EAAE,EAAE,CAAC;YACvB,MAAM,QAAQ,GAAG,SAAS,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,QAAQ,EAAE,IAAI,EAAE,SAAS,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;YACpF,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;QACxE,CAAC;aAAM,IAAI,IAAI,CAAC,MAAM,EAAE,EAAE,CAAC;YACzB,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC;QACtC,CAAC;IACH,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,MAAM,UAAU,mBAAmB,CAAC,OAAkC,EAAE,MAAM,GAAG,EAAE;IACjF,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACxC,MAAM,KAAK,GAAG,OAAO,CAAC,CAAC,CAAE,CAAC;QAC1B,MAAM,MAAM,GAAG,CAAC,KAAK,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC;QACxC,MAAM,MAAM,GAAG,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC;QACxC,MAAM,WAAW,GAAG,MAAM,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;QAExD,KAAK,CAAC,IAAI,CAAC,GAAG,MAAM,GAAG,MAAM,GAAG,KAAK,CAAC,IAAI,GAAG,KAAK,CAAC,IAAI,KAAK,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QAChF,IAAI,KAAK,CAAC,QAAQ,IAAI,KAAK,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAChD,KAAK,CAAC,IAAI,CAAC,mBAAmB,CAAC,KAAK,CAAC,QAAQ,EAAE,WAAW,CAAC,CAAC,CAAC;QAC/D,CAAC;IACH,CAAC;IACD,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { PackageInfo, EntryPoint } from "../types.js";
2
+ export declare function detectEntryPoints(cwd: string, packages: readonly PackageInfo[]): readonly EntryPoint[];
3
+ //# sourceMappingURL=entry-point-detector.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"entry-point-detector.d.ts","sourceRoot":"","sources":["../../src/analyzers/entry-point-detector.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AA8C3D,wBAAgB,iBAAiB,CAC/B,GAAG,EAAE,MAAM,EACX,QAAQ,EAAE,SAAS,WAAW,EAAE,GAC/B,SAAS,UAAU,EAAE,CAmCvB"}
@@ -0,0 +1,87 @@
1
+ import { existsSync, readFileSync } from "node:fs";
2
+ import { join } from "node:path";
3
+ const COMMON_ENTRY_POINTS = [
4
+ { path: "src/index.ts", kind: "index" },
5
+ { path: "src/index.tsx", kind: "index" },
6
+ { path: "src/index.js", kind: "index" },
7
+ { path: "src/main.ts", kind: "main" },
8
+ { path: "src/main.tsx", kind: "main" },
9
+ { path: "src/main.js", kind: "main" },
10
+ { path: "src/app.ts", kind: "main" },
11
+ { path: "src/app.tsx", kind: "main" },
12
+ { path: "src/app.js", kind: "main" },
13
+ { path: "index.ts", kind: "index" },
14
+ { path: "index.js", kind: "index" },
15
+ { path: "main.go", kind: "main" },
16
+ { path: "cmd/main.go", kind: "main" },
17
+ { path: "src/main.rs", kind: "main" },
18
+ { path: "src/lib.rs", kind: "main" },
19
+ { path: "manage.py", kind: "main" },
20
+ { path: "app.py", kind: "main" },
21
+ { path: "main.py", kind: "main" },
22
+ ];
23
+ const ROUTE_DIRS = [
24
+ "src/routes",
25
+ "src/pages",
26
+ "src/api",
27
+ "app/routes",
28
+ "app/api",
29
+ "pages",
30
+ "routes",
31
+ "api",
32
+ ];
33
+ const CONFIG_FILES = [
34
+ "next.config.js",
35
+ "next.config.ts",
36
+ "next.config.mjs",
37
+ "vite.config.ts",
38
+ "vite.config.js",
39
+ "webpack.config.js",
40
+ "webpack.config.ts",
41
+ "nuxt.config.ts",
42
+ "astro.config.mjs",
43
+ ];
44
+ export function detectEntryPoints(cwd, packages) {
45
+ const results = [];
46
+ const seen = new Set();
47
+ for (const pkg of packages) {
48
+ if (pkg.manager === "npm") {
49
+ const mainField = extractMainField(cwd);
50
+ if (mainField && !seen.has(mainField)) {
51
+ seen.add(mainField);
52
+ results.push({ path: mainField, kind: "main" });
53
+ }
54
+ }
55
+ }
56
+ for (const { path, kind } of COMMON_ENTRY_POINTS) {
57
+ if (!seen.has(path) && existsSync(join(cwd, path))) {
58
+ seen.add(path);
59
+ results.push({ path, kind });
60
+ }
61
+ }
62
+ for (const dir of ROUTE_DIRS) {
63
+ if (existsSync(join(cwd, dir))) {
64
+ results.push({ path: dir, kind: "route" });
65
+ }
66
+ }
67
+ for (const config of CONFIG_FILES) {
68
+ if (!seen.has(config) && existsSync(join(cwd, config))) {
69
+ seen.add(config);
70
+ results.push({ path: config, kind: "config" });
71
+ }
72
+ }
73
+ return results;
74
+ }
75
+ function extractMainField(cwd) {
76
+ try {
77
+ const raw = readFileSync(join(cwd, "package.json"), "utf-8");
78
+ const pkg = JSON.parse(raw);
79
+ if (typeof pkg["main"] === "string")
80
+ return pkg["main"];
81
+ }
82
+ catch {
83
+ // absent
84
+ }
85
+ return null;
86
+ }
87
+ //# sourceMappingURL=entry-point-detector.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"entry-point-detector.js","sourceRoot":"","sources":["../../src/analyzers/entry-point-detector.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACnD,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAGjC,MAAM,mBAAmB,GAA0D;IACjF,EAAE,IAAI,EAAE,cAAc,EAAE,IAAI,EAAE,OAAO,EAAE;IACvC,EAAE,IAAI,EAAE,eAAe,EAAE,IAAI,EAAE,OAAO,EAAE;IACxC,EAAE,IAAI,EAAE,cAAc,EAAE,IAAI,EAAE,OAAO,EAAE;IACvC,EAAE,IAAI,EAAE,aAAa,EAAE,IAAI,EAAE,MAAM,EAAE;IACrC,EAAE,IAAI,EAAE,cAAc,EAAE,IAAI,EAAE,MAAM,EAAE;IACtC,EAAE,IAAI,EAAE,aAAa,EAAE,IAAI,EAAE,MAAM,EAAE;IACrC,EAAE,IAAI,EAAE,YAAY,EAAE,IAAI,EAAE,MAAM,EAAE;IACpC,EAAE,IAAI,EAAE,aAAa,EAAE,IAAI,EAAE,MAAM,EAAE;IACrC,EAAE,IAAI,EAAE,YAAY,EAAE,IAAI,EAAE,MAAM,EAAE;IACpC,EAAE,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,OAAO,EAAE;IACnC,EAAE,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,OAAO,EAAE;IACnC,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,EAAE;IACjC,EAAE,IAAI,EAAE,aAAa,EAAE,IAAI,EAAE,MAAM,EAAE;IACrC,EAAE,IAAI,EAAE,aAAa,EAAE,IAAI,EAAE,MAAM,EAAE;IACrC,EAAE,IAAI,EAAE,YAAY,EAAE,IAAI,EAAE,MAAM,EAAE;IACpC,EAAE,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE,MAAM,EAAE;IACnC,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,EAAE;IAChC,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,EAAE;CAClC,CAAC;AAEF,MAAM,UAAU,GAAsB;IACpC,YAAY;IACZ,WAAW;IACX,SAAS;IACT,YAAY;IACZ,SAAS;IACT,OAAO;IACP,QAAQ;IACR,KAAK;CACN,CAAC;AAEF,MAAM,YAAY,GAAsB;IACtC,gBAAgB;IAChB,gBAAgB;IAChB,iBAAiB;IACjB,gBAAgB;IAChB,gBAAgB;IAChB,mBAAmB;IACnB,mBAAmB;IACnB,gBAAgB;IAChB,kBAAkB;CACnB,CAAC;AAEF,MAAM,UAAU,iBAAiB,CAC/B,GAAW,EACX,QAAgC;IAEhC,MAAM,OAAO,GAAiB,EAAE,CAAC;IACjC,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;IAE/B,KAAK,MAAM,GAAG,IAAI,QAAQ,EAAE,CAAC;QAC3B,IAAI,GAAG,CAAC,OAAO,KAAK,KAAK,EAAE,CAAC;YAC1B,MAAM,SAAS,GAAG,gBAAgB,CAAC,GAAG,CAAC,CAAC;YACxC,IAAI,SAAS,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,CAAC;gBACtC,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;gBACpB,OAAO,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC;YAClD,CAAC;QACH,CAAC;IACH,CAAC;IAED,KAAK,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,mBAAmB,EAAE,CAAC;QACjD,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,UAAU,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC,EAAE,CAAC;YACnD,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;YACf,OAAO,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;QAC/B,CAAC;IACH,CAAC;IAED,KAAK,MAAM,GAAG,IAAI,UAAU,EAAE,CAAC;QAC7B,IAAI,UAAU,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,EAAE,CAAC;YAC/B,OAAO,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC;QAC7C,CAAC;IACH,CAAC;IAED,KAAK,MAAM,MAAM,IAAI,YAAY,EAAE,CAAC;QAClC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,UAAU,CAAC,IAAI,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC,EAAE,CAAC;YACvD,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;YACjB,OAAO,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC,CAAC;QACjD,CAAC;IACH,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,SAAS,gBAAgB,CAAC,GAAW;IACnC,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,YAAY,CAAC,IAAI,CAAC,GAAG,EAAE,cAAc,CAAC,EAAE,OAAO,CAAC,CAAC;QAC7D,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAA4B,CAAC;QACvD,IAAI,OAAO,GAAG,CAAC,MAAM,CAAC,KAAK,QAAQ;YAAE,OAAO,GAAG,CAAC,MAAM,CAAC,CAAC;IAC1D,CAAC;IAAC,MAAM,CAAC;QACP,SAAS;IACX,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { PackageInfo, FrameworkDetection } from "../types.js";
2
+ export declare function detectFrameworks(packages: readonly PackageInfo[]): readonly FrameworkDetection[];
3
+ //# sourceMappingURL=framework-detector.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"framework-detector.d.ts","sourceRoot":"","sources":["../../src/analyzers/framework-detector.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAkDnE,wBAAgB,gBAAgB,CAC9B,QAAQ,EAAE,SAAS,WAAW,EAAE,GAC/B,SAAS,kBAAkB,EAAE,CAuB/B"}
@@ -0,0 +1,63 @@
1
+ const FRAMEWORK_RULES = [
2
+ { dep: "next", name: "Next.js", confidence: "definite" },
3
+ { dep: "react", name: "React", confidence: "definite" },
4
+ { dep: "vue", name: "Vue", confidence: "definite" },
5
+ { dep: "@angular/core", name: "Angular", confidence: "definite" },
6
+ { dep: "svelte", name: "Svelte", confidence: "definite" },
7
+ { dep: "express", name: "Express", confidence: "definite" },
8
+ { dep: "fastify", name: "Fastify", confidence: "definite" },
9
+ { dep: "hono", name: "Hono", confidence: "definite" },
10
+ { dep: "koa", name: "Koa", confidence: "definite" },
11
+ { dep: "nestjs", name: "NestJS", confidence: "likely" },
12
+ { dep: "@nestjs/core", name: "NestJS", confidence: "definite" },
13
+ { dep: "nuxt", name: "Nuxt", confidence: "definite" },
14
+ { dep: "remix", name: "Remix", confidence: "likely" },
15
+ { dep: "@remix-run/react", name: "Remix", confidence: "definite" },
16
+ { dep: "astro", name: "Astro", confidence: "definite" },
17
+ { dep: "gatsby", name: "Gatsby", confidence: "definite" },
18
+ { dep: "tailwindcss", name: "Tailwind CSS", confidence: "definite" },
19
+ { dep: "prisma", name: "Prisma", confidence: "definite" },
20
+ { dep: "@prisma/client", name: "Prisma", confidence: "definite" },
21
+ { dep: "drizzle-orm", name: "Drizzle", confidence: "definite" },
22
+ { dep: "django", name: "Django", confidence: "definite" },
23
+ { dep: "flask", name: "Flask", confidence: "definite" },
24
+ { dep: "fastapi", name: "FastAPI", confidence: "definite" },
25
+ { dep: "spring-boot", name: "Spring Boot", confidence: "likely" },
26
+ { dep: "actix-web", name: "Actix Web", confidence: "definite" },
27
+ { dep: "rocket", name: "Rocket", confidence: "definite" },
28
+ { dep: "axum", name: "Axum", confidence: "definite" },
29
+ { dep: "tokio", name: "Tokio", confidence: "definite" },
30
+ { dep: "gin-gonic/gin", name: "Gin", confidence: "definite" },
31
+ { dep: "labstack/echo", name: "Echo", confidence: "definite" },
32
+ { dep: "gofiber/fiber", name: "Fiber", confidence: "definite" },
33
+ { dep: "laravel/framework", name: "Laravel", confidence: "definite" },
34
+ { dep: "symfony/framework-bundle", name: "Symfony", confidence: "definite" },
35
+ { dep: "vitest", name: "Vitest", confidence: "definite" },
36
+ { dep: "jest", name: "Jest", confidence: "definite" },
37
+ { dep: "playwright", name: "Playwright", confidence: "definite" },
38
+ { dep: "@playwright/test", name: "Playwright", confidence: "definite" },
39
+ { dep: "cypress", name: "Cypress", confidence: "definite" },
40
+ { dep: "pytest", name: "pytest", confidence: "definite" },
41
+ ];
42
+ export function detectFrameworks(packages) {
43
+ const allDeps = new Set();
44
+ for (const pkg of packages) {
45
+ for (const dep of pkg.dependencies) {
46
+ allDeps.add(dep);
47
+ }
48
+ }
49
+ const seen = new Set();
50
+ const results = [];
51
+ for (const rule of FRAMEWORK_RULES) {
52
+ if (allDeps.has(rule.dep) && !seen.has(rule.name)) {
53
+ seen.add(rule.name);
54
+ results.push({
55
+ name: rule.name,
56
+ confidence: rule.confidence,
57
+ source: rule.dep,
58
+ });
59
+ }
60
+ }
61
+ return results;
62
+ }
63
+ //# sourceMappingURL=framework-detector.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"framework-detector.js","sourceRoot":"","sources":["../../src/analyzers/framework-detector.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ export { buildDirectoryTree, formatDirectoryTree } from "./directory-tree.js";
2
+ export { detectPackages } from "./package-detector.js";
3
+ export { detectFrameworks } from "./framework-detector.js";
4
+ export { detectEntryPoints } from "./entry-point-detector.js";
5
+ export { detectBuildScripts } from "./build-script-detector.js";
6
+ export { detectConventions } from "./convention-detector.js";
7
+ export { detectKeyFiles } from "./key-file-detector.js";
8
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/analyzers/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAC9E,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAC3D,OAAO,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAC9D,OAAO,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AAChE,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAC7D,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC"}
@@ -0,0 +1,8 @@
1
+ export { buildDirectoryTree, formatDirectoryTree } from "./directory-tree.js";
2
+ export { detectPackages } from "./package-detector.js";
3
+ export { detectFrameworks } from "./framework-detector.js";
4
+ export { detectEntryPoints } from "./entry-point-detector.js";
5
+ export { detectBuildScripts } from "./build-script-detector.js";
6
+ export { detectConventions } from "./convention-detector.js";
7
+ export { detectKeyFiles } from "./key-file-detector.js";
8
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/analyzers/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAC9E,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAC3D,OAAO,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAC9D,OAAO,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AAChE,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAC7D,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { KeyFile } from "../types.js";
2
+ export declare function detectKeyFiles(cwd: string): readonly KeyFile[];
3
+ //# sourceMappingURL=key-file-detector.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"key-file-detector.d.ts","sourceRoot":"","sources":["../../src/analyzers/key-file-detector.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAuB3C,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,OAAO,EAAE,CAU9D"}
@@ -0,0 +1,32 @@
1
+ import { existsSync } from "node:fs";
2
+ import { join } from "node:path";
3
+ const KEY_FILES = [
4
+ { path: "README.md", description: "Project documentation" },
5
+ { path: "LICENSE", description: "License file" },
6
+ { path: "LICENSE.md", description: "License file" },
7
+ { path: "CHANGELOG.md", description: "Release history" },
8
+ { path: "CONTRIBUTING.md", description: "Contribution guidelines" },
9
+ { path: "SECURITY.md", description: "Security policy" },
10
+ { path: "ARCHITECTURE.md", description: "Architecture documentation" },
11
+ { path: "AGENTS.md", description: "AI agent conventions" },
12
+ { path: "CLAUDE.md", description: "Claude Code instructions" },
13
+ { path: ".env.example", description: "Environment variable template" },
14
+ { path: ".env.sample", description: "Environment variable template" },
15
+ { path: "Dockerfile", description: "Container build definition" },
16
+ { path: "docker-compose.yml", description: "Container orchestration" },
17
+ { path: "docker-compose.yaml", description: "Container orchestration" },
18
+ { path: "Makefile", description: "Build automation" },
19
+ { path: ".github/workflows", description: "GitHub Actions CI/CD" },
20
+ { path: ".gitlab-ci.yml", description: "GitLab CI/CD" },
21
+ { path: "Jenkinsfile", description: "Jenkins pipeline" },
22
+ ];
23
+ export function detectKeyFiles(cwd) {
24
+ const results = [];
25
+ for (const { path, description } of KEY_FILES) {
26
+ if (existsSync(join(cwd, path))) {
27
+ results.push({ path, description });
28
+ }
29
+ }
30
+ return results;
31
+ }
32
+ //# sourceMappingURL=key-file-detector.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"key-file-detector.js","sourceRoot":"","sources":["../../src/analyzers/key-file-detector.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAGjC,MAAM,SAAS,GAAqD;IAClE,EAAE,IAAI,EAAE,WAAW,EAAE,WAAW,EAAE,uBAAuB,EAAE;IAC3D,EAAE,IAAI,EAAE,SAAS,EAAE,WAAW,EAAE,cAAc,EAAE;IAChD,EAAE,IAAI,EAAE,YAAY,EAAE,WAAW,EAAE,cAAc,EAAE;IACnD,EAAE,IAAI,EAAE,cAAc,EAAE,WAAW,EAAE,iBAAiB,EAAE;IACxD,EAAE,IAAI,EAAE,iBAAiB,EAAE,WAAW,EAAE,yBAAyB,EAAE;IACnE,EAAE,IAAI,EAAE,aAAa,EAAE,WAAW,EAAE,iBAAiB,EAAE;IACvD,EAAE,IAAI,EAAE,iBAAiB,EAAE,WAAW,EAAE,4BAA4B,EAAE;IACtE,EAAE,IAAI,EAAE,WAAW,EAAE,WAAW,EAAE,sBAAsB,EAAE;IAC1D,EAAE,IAAI,EAAE,WAAW,EAAE,WAAW,EAAE,0BAA0B,EAAE;IAC9D,EAAE,IAAI,EAAE,cAAc,EAAE,WAAW,EAAE,+BAA+B,EAAE;IACtE,EAAE,IAAI,EAAE,aAAa,EAAE,WAAW,EAAE,+BAA+B,EAAE;IACrE,EAAE,IAAI,EAAE,YAAY,EAAE,WAAW,EAAE,4BAA4B,EAAE;IACjE,EAAE,IAAI,EAAE,oBAAoB,EAAE,WAAW,EAAE,yBAAyB,EAAE;IACtE,EAAE,IAAI,EAAE,qBAAqB,EAAE,WAAW,EAAE,yBAAyB,EAAE;IACvE,EAAE,IAAI,EAAE,UAAU,EAAE,WAAW,EAAE,kBAAkB,EAAE;IACrD,EAAE,IAAI,EAAE,mBAAmB,EAAE,WAAW,EAAE,sBAAsB,EAAE;IAClE,EAAE,IAAI,EAAE,gBAAgB,EAAE,WAAW,EAAE,cAAc,EAAE;IACvD,EAAE,IAAI,EAAE,aAAa,EAAE,WAAW,EAAE,kBAAkB,EAAE;CACzD,CAAC;AAEF,MAAM,UAAU,cAAc,CAAC,GAAW;IACxC,MAAM,OAAO,GAAc,EAAE,CAAC;IAE9B,KAAK,MAAM,EAAE,IAAI,EAAE,WAAW,EAAE,IAAI,SAAS,EAAE,CAAC;QAC9C,IAAI,UAAU,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC,EAAE,CAAC;YAChC,OAAO,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,CAAC,CAAC;QACtC,CAAC;IACH,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { PackageInfo } from "../types.js";
2
+ export declare function detectPackages(cwd: string): readonly PackageInfo[];
3
+ //# sourceMappingURL=package-detector.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"package-detector.d.ts","sourceRoot":"","sources":["../../src/analyzers/package-detector.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAG/C,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,WAAW,EAAE,CAiFlE"}