septum 0.1.4 → 0.1.6

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 (70) hide show
  1. package/LICENSE +21 -21
  2. package/README.md +105 -105
  3. package/bin/septum.ts +4 -4
  4. package/package.json +63 -63
  5. package/src/cli/commands/check.ts +161 -161
  6. package/src/cli/commands/hook.ts +216 -188
  7. package/src/cli/commands/ingest.ts +29 -29
  8. package/src/cli/commands/init.ts +213 -211
  9. package/src/cli/commands/locate.ts +61 -61
  10. package/src/cli/commands/query.ts +104 -64
  11. package/src/cli/commands/serve.ts +5 -5
  12. package/src/cli/commands/slice.ts +50 -48
  13. package/src/cli/commands/sync.ts +31 -31
  14. package/src/cli/index.ts +220 -210
  15. package/src/cli/templates/hooks.ts +75 -75
  16. package/src/cli/templates/rules.ts +50 -38
  17. package/src/cli/templates/skill.ts +65 -69
  18. package/src/core/boundary/evaluator.ts +429 -210
  19. package/src/core/config/loader.ts +117 -97
  20. package/src/core/config/schema.ts +39 -39
  21. package/src/core/database/client.ts +44 -44
  22. package/src/core/database/repositories/dependency.repository.ts +552 -349
  23. package/src/core/database/repositories/domain.repository.ts +275 -198
  24. package/src/core/database/repositories/file.repository.ts +117 -106
  25. package/src/core/database/repositories/meta.repository.ts +33 -33
  26. package/src/core/database/repositories/symbol.repository.ts +482 -443
  27. package/src/core/database/repository.ts +281 -260
  28. package/src/core/database/schema.ts +154 -153
  29. package/src/core/discovery/topology-detector.ts +486 -486
  30. package/src/core/ingestion/hasher.ts +5 -5
  31. package/src/core/ingestion/pipeline.ts +606 -535
  32. package/src/core/parser/boundary-tracker.ts +433 -288
  33. package/src/core/parser/extractors/base.ts +62 -62
  34. package/src/core/parser/extractors/blade.ts +158 -158
  35. package/src/core/parser/extractors/frontend.ts +147 -194
  36. package/src/core/parser/extractors/go.ts +408 -180
  37. package/src/core/parser/extractors/laravel-semantic.ts +1045 -901
  38. package/src/core/parser/extractors/mcp-cli-semantic.ts +328 -199
  39. package/src/core/parser/extractors/nestjs-semantic.ts +134 -119
  40. package/src/core/parser/extractors/php.ts +415 -153
  41. package/src/core/parser/extractors/python.ts +460 -228
  42. package/src/core/parser/extractors/registry.ts +70 -70
  43. package/src/core/parser/extractors/semantic-extractor.interface.ts +21 -21
  44. package/src/core/parser/extractors/typescript.ts +668 -181
  45. package/src/core/parser/tree-sitter.ts +41 -41
  46. package/src/core/parser/wasm-loader.ts +271 -0
  47. package/src/core/resolver/call-graph-tracer.ts +698 -668
  48. package/src/core/resolver/module-resolver.ts +479 -342
  49. package/src/core/resolver/path-resolver.ts +147 -147
  50. package/src/core/resolver/symbol-locator.ts +543 -543
  51. package/src/core/resolver/vertical-slice-tracer.ts +323 -285
  52. package/src/core/session/session-manager.ts +56 -56
  53. package/src/core/telemetry/telemetry.ts +86 -86
  54. package/src/core/topology/environment-detector.ts +109 -6
  55. package/src/index.ts +21 -21
  56. package/src/mcp/schemas.ts +695 -286
  57. package/src/mcp/server.ts +927 -716
  58. package/src/mcp/tools/check-boundary.ts +307 -152
  59. package/src/mcp/tools/get-domain-catalog.ts +155 -121
  60. package/src/mcp/tools/get-environment-topology.ts +3 -6
  61. package/src/mcp/tools/get-feature-context.ts +227 -116
  62. package/src/mcp/tools/get-symbol-hotspots.ts +54 -59
  63. package/src/mcp/tools/get-symbol-impact.ts +28 -26
  64. package/src/mcp/tools/get-symbol.ts +65 -63
  65. package/src/mcp/tools/locate-symbol.ts +169 -190
  66. package/src/mcp/tools/register-domain.ts +59 -64
  67. package/src/mcp/tools/register-feature.ts +91 -0
  68. package/src/mcp/tools/trace-vertical-slice.ts +74 -48
  69. package/src/types/index.ts +366 -315
  70. package/src/version.ts +3 -3
@@ -1,56 +1,56 @@
1
- import { existsSync, mkdirSync, readFileSync, rmSync, writeFileSync } from "node:fs";
2
- import { join } from "node:path";
3
- import type { ActiveFeatureSession } from "../../types/index.ts";
4
-
5
- export class SessionManager {
6
- private static readonly SESSION_FILE = ".septum/session.json";
7
-
8
- /**
9
- * Save the active feature session to .septum/session.json
10
- */
11
- public static saveActiveSession(workspaceRoot: string, session: ActiveFeatureSession): void {
12
- const septumDir = join(workspaceRoot, ".septum");
13
- if (!existsSync(septumDir)) {
14
- mkdirSync(septumDir, { recursive: true });
15
- }
16
- const sessionPath = join(workspaceRoot, SessionManager.SESSION_FILE);
17
- writeFileSync(sessionPath, JSON.stringify(session, null, 2), "utf-8");
18
- }
19
-
20
- /**
21
- * Get the active feature session, or null if no session exists or file is invalid
22
- */
23
- public static getActiveSession(workspaceRoot: string): ActiveFeatureSession | null {
24
- const sessionPath = join(workspaceRoot, SessionManager.SESSION_FILE);
25
- if (!existsSync(sessionPath)) {
26
- return null;
27
- }
28
-
29
- try {
30
- const raw = readFileSync(sessionPath, "utf-8");
31
- const parsed = JSON.parse(raw) as ActiveFeatureSession;
32
- if (parsed && typeof parsed.feature_key === "string" && Array.isArray(parsed.touchpoints)) {
33
- return parsed;
34
- }
35
- return null;
36
- } catch {
37
- return null;
38
- }
39
- }
40
-
41
- /**
42
- * Clear the active feature session
43
- */
44
- public static clearActiveSession(workspaceRoot: string): boolean {
45
- const sessionPath = join(workspaceRoot, SessionManager.SESSION_FILE);
46
- if (existsSync(sessionPath)) {
47
- try {
48
- rmSync(sessionPath, { force: true });
49
- return true;
50
- } catch {
51
- return false;
52
- }
53
- }
54
- return false;
55
- }
56
- }
1
+ import { existsSync, mkdirSync, readFileSync, rmSync, writeFileSync } from "node:fs";
2
+ import { join } from "node:path";
3
+ import type { ActiveFeatureSession } from "../../types/index.ts";
4
+
5
+ export class SessionManager {
6
+ private static readonly SESSION_FILE = ".septum/session.json";
7
+
8
+ /**
9
+ * Save the active feature session to .septum/session.json
10
+ */
11
+ public static saveActiveSession(workspaceRoot: string, session: ActiveFeatureSession): void {
12
+ const septumDir = join(workspaceRoot, ".septum");
13
+ if (!existsSync(septumDir)) {
14
+ mkdirSync(septumDir, { recursive: true });
15
+ }
16
+ const sessionPath = join(workspaceRoot, SessionManager.SESSION_FILE);
17
+ writeFileSync(sessionPath, JSON.stringify(session, null, 2), "utf-8");
18
+ }
19
+
20
+ /**
21
+ * Get the active feature session, or null if no session exists or file is invalid
22
+ */
23
+ public static getActiveSession(workspaceRoot: string): ActiveFeatureSession | null {
24
+ const sessionPath = join(workspaceRoot, SessionManager.SESSION_FILE);
25
+ if (!existsSync(sessionPath)) {
26
+ return null;
27
+ }
28
+
29
+ try {
30
+ const raw = readFileSync(sessionPath, "utf-8");
31
+ const parsed = JSON.parse(raw) as ActiveFeatureSession;
32
+ if (parsed && typeof parsed.feature_key === "string" && Array.isArray(parsed.touchpoints)) {
33
+ return parsed;
34
+ }
35
+ return null;
36
+ } catch {
37
+ return null;
38
+ }
39
+ }
40
+
41
+ /**
42
+ * Clear the active feature session
43
+ */
44
+ public static clearActiveSession(workspaceRoot: string): boolean {
45
+ const sessionPath = join(workspaceRoot, SessionManager.SESSION_FILE);
46
+ if (existsSync(sessionPath)) {
47
+ try {
48
+ rmSync(sessionPath, { force: true });
49
+ return true;
50
+ } catch {
51
+ return false;
52
+ }
53
+ }
54
+ return false;
55
+ }
56
+ }
@@ -1,86 +1,86 @@
1
- import { appendFileSync, existsSync, mkdirSync, renameSync, statSync } from "node:fs";
2
- import { dirname, join } from "node:path";
3
-
4
- export interface SeptumToolCallEvent {
5
- timestamp?: string;
6
- event: "tool_call_completed" | "tool_call_failed";
7
- tool: string;
8
- duration_ms: number;
9
- input: Record<string, any>;
10
- metrics?: {
11
- bytes_out?: number;
12
- lines_out?: number;
13
- nodes_returned?: number;
14
- };
15
- session?: {
16
- feature_key?: string | null;
17
- domain?: string | null;
18
- } | null;
19
- status: "success" | "error";
20
- error?: {
21
- code?: string;
22
- message: string;
23
- stack?: string;
24
- };
25
- }
26
-
27
- export class SeptumTelemetry {
28
- private static readonly MAX_LOG_SIZE_BYTES = 2 * 1024 * 1024; // 2MB
29
- private static readonly SLOW_EXECUTION_THRESHOLD_MS = 250;
30
-
31
- /**
32
- * Resolves the log file path inside the active workspace's .septum directory.
33
- */
34
- public static getLogPath(workspaceRoot: string = process.cwd()): string {
35
- return join(workspaceRoot, ".septum", "septum.log");
36
- }
37
-
38
- /**
39
- * Records a tool call event to both stderr (dual-sink) and .septum/septum.log.
40
- */
41
- public static recordToolCall(
42
- event: SeptumToolCallEvent,
43
- workspaceRoot: string = process.cwd()
44
- ): void {
45
- const payload: SeptumToolCallEvent = {
46
- timestamp: event.timestamp || new Date().toISOString(),
47
- ...event,
48
- };
49
-
50
- const jsonLine = JSON.stringify(payload);
51
-
52
- // Sink 1: Live stderr stream for operator monitoring (slow queries & failures)
53
- if (payload.status === "error") {
54
- console.error(`[Septum Telemetry ERROR] ${jsonLine}`);
55
- } else if (payload.duration_ms >= this.SLOW_EXECUTION_THRESHOLD_MS) {
56
- console.error(`[Septum Telemetry SLOW_WARN] ${jsonLine}`);
57
- }
58
-
59
- // Sink 2: Append-only persistent file recorder in .septum/septum.log
60
- try {
61
- const logPath = this.getLogPath(workspaceRoot);
62
- const logDir = dirname(logPath);
63
-
64
- if (!existsSync(logDir)) {
65
- mkdirSync(logDir, { recursive: true });
66
- }
67
-
68
- // Check for rotation if file exceeds 2MB
69
- if (existsSync(logPath)) {
70
- try {
71
- const stats = statSync(logPath);
72
- if (stats.size >= this.MAX_LOG_SIZE_BYTES) {
73
- const rotatedPath = `${logPath}.1`;
74
- renameSync(logPath, rotatedPath);
75
- }
76
- } catch {
77
- // If stat/rotation fails, proceed to append without crashing
78
- }
79
- }
80
-
81
- appendFileSync(logPath, `${jsonLine}\n`, "utf8");
82
- } catch {
83
- // Telemetry file writes must never crash the main application process
84
- }
85
- }
86
- }
1
+ import { appendFileSync, existsSync, mkdirSync, renameSync, statSync } from "node:fs";
2
+ import { dirname, join } from "node:path";
3
+
4
+ export interface SeptumToolCallEvent {
5
+ timestamp?: string;
6
+ event: "tool_call_completed" | "tool_call_failed";
7
+ tool: string;
8
+ duration_ms: number;
9
+ input: Record<string, any>;
10
+ metrics?: {
11
+ bytes_out?: number;
12
+ lines_out?: number;
13
+ nodes_returned?: number;
14
+ };
15
+ session?: {
16
+ feature_key?: string | null;
17
+ domain?: string | null;
18
+ } | null;
19
+ status: "success" | "error";
20
+ error?: {
21
+ code?: string;
22
+ message: string;
23
+ stack?: string;
24
+ };
25
+ }
26
+
27
+ export class SeptumTelemetry {
28
+ private static readonly MAX_LOG_SIZE_BYTES = 2 * 1024 * 1024; // 2MB
29
+ private static readonly SLOW_EXECUTION_THRESHOLD_MS = 250;
30
+
31
+ /**
32
+ * Resolves the log file path inside the active workspace's .septum directory.
33
+ */
34
+ public static getLogPath(workspaceRoot: string = process.cwd()): string {
35
+ return join(workspaceRoot, ".septum", "septum.log");
36
+ }
37
+
38
+ /**
39
+ * Records a tool call event to both stderr (dual-sink) and .septum/septum.log.
40
+ */
41
+ public static recordToolCall(
42
+ event: SeptumToolCallEvent,
43
+ workspaceRoot: string = process.cwd()
44
+ ): void {
45
+ const payload: SeptumToolCallEvent = {
46
+ timestamp: event.timestamp || new Date().toISOString(),
47
+ ...event,
48
+ };
49
+
50
+ const jsonLine = JSON.stringify(payload);
51
+
52
+ // Sink 1: Live stderr stream for operator monitoring (slow queries & failures)
53
+ if (payload.status === "error") {
54
+ console.error(`[Septum Telemetry ERROR] ${jsonLine}`);
55
+ } else if (payload.duration_ms >= this.SLOW_EXECUTION_THRESHOLD_MS) {
56
+ console.error(`[Septum Telemetry SLOW_WARN] ${jsonLine}`);
57
+ }
58
+
59
+ // Sink 2: Append-only persistent file recorder in .septum/septum.log
60
+ try {
61
+ const logPath = this.getLogPath(workspaceRoot);
62
+ const logDir = dirname(logPath);
63
+
64
+ if (!existsSync(logDir)) {
65
+ mkdirSync(logDir, { recursive: true });
66
+ }
67
+
68
+ // Check for rotation if file exceeds 2MB
69
+ if (existsSync(logPath)) {
70
+ try {
71
+ const stats = statSync(logPath);
72
+ if (stats.size >= this.MAX_LOG_SIZE_BYTES) {
73
+ const rotatedPath = `${logPath}.1`;
74
+ renameSync(logPath, rotatedPath);
75
+ }
76
+ } catch {
77
+ // If stat/rotation fails, proceed to append without crashing
78
+ }
79
+ }
80
+
81
+ appendFileSync(logPath, `${jsonLine}\n`, "utf8");
82
+ } catch {
83
+ // Telemetry file writes must never crash the main application process
84
+ }
85
+ }
86
+ }
@@ -556,22 +556,120 @@ export class EnvironmentDetector {
556
556
  const realEnv = this.parseEnvFileSafe(path.join(root, ".env"));
557
557
  const mergedEnv = new Map([...envMap, ...realEnv]);
558
558
  const detectedStorage: string[] = [];
559
+ const detectedFrom = new Set<string>();
559
560
 
560
561
  const dbConn = mergedEnv.get("DB_CONNECTION")?.toLowerCase() || "";
561
562
  const dbPort = mergedEnv.get("DB_PORT") || "";
562
563
 
563
- if (dbConn === "mysql" || dbPort === "3306" || [...mergedEnv.keys()].some(k => k.startsWith("MYSQL_"))) {
564
+ if (dbConn === "mysql" || dbPort === "3306" || [...mergedEnv.keys()].some((k) => k.startsWith("MYSQL_"))) {
564
565
  detectedStorage.push("MySQL / MariaDB");
565
- } else if (dbConn === "pgsql" || dbPort === "5432" || [...mergedEnv.keys()].some(k => k.startsWith("POSTGRES_"))) {
566
+ detectedFrom.add(".env");
567
+ } else if (
568
+ dbConn === "pgsql" ||
569
+ dbPort === "5432" ||
570
+ [...mergedEnv.keys()].some((k) => k.startsWith("POSTGRES_"))
571
+ ) {
566
572
  detectedStorage.push("PostgreSQL");
573
+ detectedFrom.add(".env");
567
574
  } else if (dbConn === "sqlite" || fs.existsSync(path.join(root, "database", "database.sqlite"))) {
568
575
  detectedStorage.push("SQLite (File-based)");
576
+ detectedFrom.add(dbConn === "sqlite" ? ".env" : "database/database.sqlite");
569
577
  }
570
578
 
571
579
  const queueConn = mergedEnv.get("QUEUE_CONNECTION")?.toLowerCase() || "";
572
580
  const redisHost = mergedEnv.get("REDIS_HOST");
573
581
  if (queueConn === "redis" || redisHost || mergedEnv.has("REDIS_CLIENT")) {
574
582
  detectedStorage.push("Redis (Cache & Queues)");
583
+ detectedFrom.add(".env");
584
+ }
585
+
586
+ // Inspect package.json dependencies & devDependencies
587
+ const packageJson = this.readJsonSafe(path.join(root, "package.json"));
588
+ const allPkgDeps: Record<string, string> = {
589
+ ...(packageJson?.dependencies || {}),
590
+ ...(packageJson?.devDependencies || {}),
591
+ };
592
+
593
+ const addStorageUnique = (label: string, source: string): void => {
594
+ if (!detectedStorage.some((s) => s.toLowerCase().startsWith(label.split(" ")[0].toLowerCase()))) {
595
+ detectedStorage.push(label);
596
+ }
597
+ detectedFrom.add(source);
598
+ };
599
+
600
+ if (allPkgDeps["mysql2"] || allPkgDeps["mysql"]) {
601
+ addStorageUnique("MySQL / MariaDB", "package.json");
602
+ }
603
+ if (allPkgDeps["pg"] || allPkgDeps["postgres"]) {
604
+ addStorageUnique("PostgreSQL", "package.json");
605
+ }
606
+ if (allPkgDeps["better-sqlite3"] || allPkgDeps["sqlite3"] || allPkgDeps["@libsql/client"]) {
607
+ addStorageUnique("SQLite (Embedded / Local WAL)", "package.json");
608
+ }
609
+ if (allPkgDeps["redis"] || allPkgDeps["ioredis"]) {
610
+ addStorageUnique("Redis (Cache & Queues)", "package.json");
611
+ }
612
+
613
+ // Inspect go.mod for Go database drivers
614
+ const goMod = this.readFileSafe(path.join(root, "go.mod"));
615
+ if (goMod) {
616
+ if (goMod.includes("go-sql-driver/mysql") || goMod.includes("driver/mysql")) {
617
+ addStorageUnique("MySQL / MariaDB", "go.mod");
618
+ }
619
+ if (goMod.includes("lib/pq") || goMod.includes("jackc/pgx") || goMod.includes("driver/postgres")) {
620
+ addStorageUnique("PostgreSQL", "go.mod");
621
+ }
622
+ if (
623
+ goMod.includes("mattn/go-sqlite3") ||
624
+ goMod.includes("modernc.org/sqlite") ||
625
+ goMod.includes("driver/sqlite")
626
+ ) {
627
+ addStorageUnique("SQLite (Embedded / Local WAL)", "go.mod");
628
+ }
629
+ if (goMod.includes("go-redis")) {
630
+ addStorageUnique("Redis (Cache & Queues)", "go.mod");
631
+ }
632
+ }
633
+
634
+ // Inspect .septum/septum.db or bun:sqlite usage in source
635
+ const hasSeptumDb = fs.existsSync(path.join(root, ".septum", "septum.db"));
636
+ const hasBunSqliteConn =
637
+ fs.existsSync(path.join(root, "src", "core", "database", "connection.ts")) &&
638
+ this.readFileSafe(path.join(root, "src", "core", "database", "connection.ts")).includes("bun:sqlite");
639
+
640
+ if (hasSeptumDb || hasBunSqliteConn) {
641
+ addStorageUnique(
642
+ "SQLite (Embedded / Local WAL)",
643
+ hasBunSqliteConn ? "src/core/database/connection.ts (bun:sqlite)" : ".septum/septum.db"
644
+ );
645
+ } else if (allPkgDeps["@types/bun"] || packageJson?.engines?.bun) {
646
+ const entryFiles = [
647
+ path.join(root, "src", "index.ts"),
648
+ path.join(root, "src", "db.ts"),
649
+ path.join(root, "src", "database.ts"),
650
+ ];
651
+ for (const ef of entryFiles) {
652
+ if (fs.existsSync(ef) && this.readFileSafe(ef).includes("bun:sqlite")) {
653
+ addStorageUnique("SQLite (Embedded / Local WAL)", path.relative(root, ef));
654
+ break;
655
+ }
656
+ }
657
+ }
658
+
659
+ if (
660
+ detectedStorage.length === 0 &&
661
+ (allPkgDeps["@prisma/client"] || allPkgDeps["drizzle-orm"])
662
+ ) {
663
+ const prismaSchema = this.readFileSafe(path.join(root, "prisma", "schema.prisma"));
664
+ if (prismaSchema.includes('"sqlite"')) {
665
+ addStorageUnique("SQLite (Embedded / Local WAL)", "prisma/schema.prisma");
666
+ } else if (prismaSchema.includes('"postgresql"')) {
667
+ addStorageUnique("PostgreSQL", "prisma/schema.prisma");
668
+ } else if (prismaSchema.includes('"mysql"')) {
669
+ addStorageUnique("MySQL / MariaDB", "prisma/schema.prisma");
670
+ } else {
671
+ addStorageUnique("SQL Database (Prisma / Drizzle ORM)", "package.json");
672
+ }
575
673
  }
576
674
 
577
675
  if (detectedStorage.length > 0) {
@@ -580,7 +678,7 @@ export class EnvironmentDetector {
580
678
  platform: detectedStorage.join(" + "),
581
679
  canonical_tag: "managed_db",
582
680
  status: "DETECTED",
583
- detected_from: [".env"],
681
+ detected_from: Array.from(detectedFrom),
584
682
  constraints: [
585
683
  "Database connection pool limits and socket timeouts must be configured.",
586
684
  "Pada Shared Hosting: Akses MySQL biasanya terikat ke 'localhost' / loopback dengan batas koneksi maksimal.",
@@ -713,12 +811,17 @@ export class EnvironmentDetector {
713
811
  }
714
812
 
715
813
  // Distributed Interplay 5: Database Migration Concurrency Invariant
716
- const computeNodes = nodes.filter((n) => n.layer === "host" || (n.layer === "runtime" && n.role !== "frontend_spa"));
717
- if (computeNodes.length > 1) {
814
+ const hostLayerNodes = nodes.filter((n) => n.layer === "host");
815
+ const backendRuntimeNodes = nodes.filter((n) => n.layer === "runtime" && n.role !== "frontend_spa");
816
+ if (hostLayerNodes.length > 1 || backendRuntimeNodes.length > 1) {
817
+ const involvedComputeIds = [
818
+ ...(hostLayerNodes.length > 1 ? hostLayerNodes.map((n) => n.id) : []),
819
+ ...(backendRuntimeNodes.length > 1 ? backendRuntimeNodes.map((n) => n.id) : []),
820
+ ];
718
821
  interplays.push({
719
822
  title: "Distributed Database Migration Concurrency Invariant",
720
823
  involved_layers: ["host", "storage"],
721
- involved_node_ids: computeNodes.map((n) => n.id),
824
+ involved_node_ids: involvedComputeIds,
722
825
  risk_or_rule: "Terdapat lebih dari 1 instance host/compute (multi-VPS / multi-node) yang terhubung ke database bersama. Menjalankan migrasi database serentak saat deployment memicu deadlock tabel atau migration race condition.",
723
826
  required_action: "Pastikan script migrasi (seperti 'artisan migrate --isolated') hanya dijalankan oleh satu designated deploy pipeline runner sebelum node lain menerima traffic.",
724
827
  });
package/src/index.ts CHANGED
@@ -1,21 +1,21 @@
1
- export * from "./types/index.ts";
2
- export * from "./core/config/schema.ts";
3
- export * from "./core/config/loader.ts";
4
- export * from "./core/database/client.ts";
5
- export * from "./core/database/repository.ts";
6
- export * from "./core/parser/extractors/base.ts";
7
- export * from "./core/parser/tree-sitter.ts";
8
- export * from "./core/ingestion/pipeline.ts";
9
- export * from "./core/boundary/evaluator.ts";
10
- export * from "./core/resolver/call-graph-tracer.ts";
11
- export * from "./core/resolver/vertical-slice-tracer.ts";
12
- export * from "./core/topology/types.ts";
13
- export * from "./core/topology/environment-detector.ts";
14
- export * from "./mcp/tools/get-environment-topology.ts";
15
- export * from "./mcp/server.ts";
16
- export * from "./cli/index.ts";
17
-
18
- import { runCLI } from "./cli/index.ts";
19
- if (import.meta.main) {
20
- runCLI(process.argv);
21
- }
1
+ export * from "./types/index.ts";
2
+ export * from "./core/config/schema.ts";
3
+ export * from "./core/config/loader.ts";
4
+ export * from "./core/database/client.ts";
5
+ export * from "./core/database/repository.ts";
6
+ export * from "./core/parser/extractors/base.ts";
7
+ export * from "./core/parser/tree-sitter.ts";
8
+ export * from "./core/ingestion/pipeline.ts";
9
+ export * from "./core/boundary/evaluator.ts";
10
+ export * from "./core/resolver/call-graph-tracer.ts";
11
+ export * from "./core/resolver/vertical-slice-tracer.ts";
12
+ export * from "./core/topology/types.ts";
13
+ export * from "./core/topology/environment-detector.ts";
14
+ export * from "./mcp/tools/get-environment-topology.ts";
15
+ export * from "./mcp/server.ts";
16
+ export * from "./cli/index.ts";
17
+
18
+ import { runCLI } from "./cli/index.ts";
19
+ if (import.meta.main) {
20
+ runCLI(process.argv);
21
+ }