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,147 +1,147 @@
1
- import { existsSync, statSync } from "node:fs";
2
- import { dirname, isAbsolute, join, normalize, resolve } from "node:path";
3
-
4
- export const PROJECT_ROOT_MARKERS = [
5
- "package.json",
6
- "composer.json",
7
- "go.mod",
8
- "pyproject.toml",
9
- "Cargo.toml",
10
- ".git",
11
- ".septum",
12
- "pnpm-workspace.yaml",
13
- "lerna.json",
14
- "tsconfig.json",
15
- "jsconfig.json",
16
- ];
17
-
18
- let lastKnownProjectRoot: string | undefined;
19
-
20
- /**
21
- * Normalizes and canonicalizes a path for cross-platform consistency.
22
- * On Windows, uppercases drive letters (e.g. "c:\" -> "C:\") to eliminate map lookup misses.
23
- */
24
- export function canonicalizePath(targetPath: string): string {
25
- if (!targetPath || typeof targetPath !== "string") {
26
- return targetPath;
27
- }
28
- let abs = normalize(resolve(targetPath));
29
- if (process.platform === "win32") {
30
- abs = abs.replace(/^[a-zA-Z]:/, (m) => m.toUpperCase());
31
- }
32
- return abs;
33
- }
34
-
35
- export function setLastKnownProjectRoot(root: string): void {
36
- if (root && typeof root === "string") {
37
- lastKnownProjectRoot = canonicalizePath(root);
38
- }
39
- }
40
-
41
- export function getLastKnownProjectRoot(): string | undefined {
42
- return lastKnownProjectRoot;
43
- }
44
-
45
- export function clearLastKnownProjectRoot(): void {
46
- lastKnownProjectRoot = undefined;
47
- }
48
-
49
- /**
50
- * Checks whether a given directory is an MCP host / IDE installation directory
51
- * (e.g. Antigravity Electron install directory) rather than a user project codebase.
52
- */
53
- export function isAppHostDirectory(dirPath: string): boolean {
54
- try {
55
- const norm = dirPath.toLowerCase().replace(/\\/g, "/");
56
- if (norm.includes("/antigravity") || norm.includes("/appdata/local/programs/antigravity")) {
57
- // Check if it has Electron app runtime signatures
58
- if (
59
- existsSync(join(dirPath, "resources", "app.asar")) ||
60
- existsSync(join(dirPath, "resources", "app.asar.unpacked")) ||
61
- existsSync(join(dirPath, "locales"))
62
- ) {
63
- return true;
64
- }
65
- }
66
- } catch {
67
- // Ignore error
68
- }
69
- return false;
70
- }
71
-
72
- /**
73
- * Discovers the project root directory by walking up looking for marker files.
74
- */
75
- export function findProjectRoot(fromPath: string): string {
76
- try {
77
- let dir = resolve(fromPath);
78
-
79
- if (existsSync(dir)) {
80
- const stat = statSync(dir);
81
- if (!stat.isDirectory()) {
82
- dir = dirname(dir);
83
- }
84
- } else {
85
- dir = dirname(dir);
86
- }
87
-
88
- let current = dir;
89
- while (true) {
90
- // Don't treat an app host directory as a project root
91
- if (!isAppHostDirectory(current)) {
92
- for (const marker of PROJECT_ROOT_MARKERS) {
93
- if (existsSync(join(current, marker))) {
94
- return canonicalizePath(current);
95
- }
96
- }
97
- }
98
-
99
- const parent = dirname(current);
100
- if (parent === current) break;
101
- current = parent;
102
- }
103
- } catch {
104
- // Filesystem traversal error fallback
105
- }
106
-
107
- return canonicalizePath(dirname(resolve(fromPath)));
108
- }
109
-
110
- /**
111
- * Ergonomically resolves the active workspace root:
112
- * 1. Explicit pathHint (if provided and valid).
113
- * 2. SEPTUM_WORKSPACE_ROOT environment variable.
114
- * 3. lastKnownProjectRoot (if cached from earlier tool calls).
115
- * 4. findProjectRoot from process.cwd() (if not an app host directory).
116
- */
117
- export function resolveWorkspaceRoot(pathHint?: string): string {
118
- if (pathHint && typeof pathHint === "string" && pathHint.trim()) {
119
- const trimmed = pathHint.trim().replace(/^['"]|['"]$/g, "");
120
- const candidate = findProjectRoot(trimmed);
121
- if (candidate && existsSync(candidate) && !isAppHostDirectory(candidate)) {
122
- setLastKnownProjectRoot(candidate);
123
- return candidate;
124
- }
125
- }
126
-
127
- const envRoot = process.env.SEPTUM_WORKSPACE_ROOT || process.env.WORKSPACE_ROOT;
128
- if (envRoot && existsSync(envRoot) && !isAppHostDirectory(envRoot)) {
129
- const candidate = canonicalizePath(envRoot);
130
- setLastKnownProjectRoot(candidate);
131
- return candidate;
132
- }
133
-
134
- if (lastKnownProjectRoot && existsSync(lastKnownProjectRoot)) {
135
- return lastKnownProjectRoot;
136
- }
137
-
138
- const cwd = process.cwd();
139
- if (!isAppHostDirectory(cwd)) {
140
- const candidate = findProjectRoot(cwd);
141
- setLastKnownProjectRoot(candidate);
142
- return candidate;
143
- }
144
-
145
- // Fallback if inside app host directory: keep looking in lastKnown or return cwd
146
- return canonicalizePath(cwd);
147
- }
1
+ import { existsSync, statSync } from "node:fs";
2
+ import { dirname, isAbsolute, join, normalize, resolve } from "node:path";
3
+
4
+ export const PROJECT_ROOT_MARKERS = [
5
+ "package.json",
6
+ "composer.json",
7
+ "go.mod",
8
+ "pyproject.toml",
9
+ "Cargo.toml",
10
+ ".git",
11
+ ".septum",
12
+ "pnpm-workspace.yaml",
13
+ "lerna.json",
14
+ "tsconfig.json",
15
+ "jsconfig.json",
16
+ ];
17
+
18
+ let lastKnownProjectRoot: string | undefined;
19
+
20
+ /**
21
+ * Normalizes and canonicalizes a path for cross-platform consistency.
22
+ * On Windows, uppercases drive letters (e.g. "c:\" -> "C:\") to eliminate map lookup misses.
23
+ */
24
+ export function canonicalizePath(targetPath: string): string {
25
+ if (!targetPath || typeof targetPath !== "string") {
26
+ return targetPath;
27
+ }
28
+ let abs = normalize(resolve(targetPath));
29
+ if (process.platform === "win32") {
30
+ abs = abs.replace(/^[a-zA-Z]:/, (m) => m.toUpperCase());
31
+ }
32
+ return abs;
33
+ }
34
+
35
+ export function setLastKnownProjectRoot(root: string): void {
36
+ if (root && typeof root === "string") {
37
+ lastKnownProjectRoot = canonicalizePath(root);
38
+ }
39
+ }
40
+
41
+ export function getLastKnownProjectRoot(): string | undefined {
42
+ return lastKnownProjectRoot;
43
+ }
44
+
45
+ export function clearLastKnownProjectRoot(): void {
46
+ lastKnownProjectRoot = undefined;
47
+ }
48
+
49
+ /**
50
+ * Checks whether a given directory is an MCP host / IDE installation directory
51
+ * (e.g. Antigravity Electron install directory) rather than a user project codebase.
52
+ */
53
+ export function isAppHostDirectory(dirPath: string): boolean {
54
+ try {
55
+ const norm = dirPath.toLowerCase().replace(/\\/g, "/");
56
+ if (norm.includes("/antigravity") || norm.includes("/appdata/local/programs/antigravity")) {
57
+ // Check if it has Electron app runtime signatures
58
+ if (
59
+ existsSync(join(dirPath, "resources", "app.asar")) ||
60
+ existsSync(join(dirPath, "resources", "app.asar.unpacked")) ||
61
+ existsSync(join(dirPath, "locales"))
62
+ ) {
63
+ return true;
64
+ }
65
+ }
66
+ } catch {
67
+ // Ignore error
68
+ }
69
+ return false;
70
+ }
71
+
72
+ /**
73
+ * Discovers the project root directory by walking up looking for marker files.
74
+ */
75
+ export function findProjectRoot(fromPath: string): string {
76
+ try {
77
+ let dir = resolve(fromPath);
78
+
79
+ if (existsSync(dir)) {
80
+ const stat = statSync(dir);
81
+ if (!stat.isDirectory()) {
82
+ dir = dirname(dir);
83
+ }
84
+ } else {
85
+ dir = dirname(dir);
86
+ }
87
+
88
+ let current = dir;
89
+ while (true) {
90
+ // Don't treat an app host directory as a project root
91
+ if (!isAppHostDirectory(current)) {
92
+ for (const marker of PROJECT_ROOT_MARKERS) {
93
+ if (existsSync(join(current, marker))) {
94
+ return canonicalizePath(current);
95
+ }
96
+ }
97
+ }
98
+
99
+ const parent = dirname(current);
100
+ if (parent === current) break;
101
+ current = parent;
102
+ }
103
+ } catch {
104
+ // Filesystem traversal error fallback
105
+ }
106
+
107
+ return canonicalizePath(dirname(resolve(fromPath)));
108
+ }
109
+
110
+ /**
111
+ * Ergonomically resolves the active workspace root:
112
+ * 1. Explicit pathHint (if provided and valid).
113
+ * 2. SEPTUM_WORKSPACE_ROOT environment variable.
114
+ * 3. lastKnownProjectRoot (if cached from earlier tool calls).
115
+ * 4. findProjectRoot from process.cwd() (if not an app host directory).
116
+ */
117
+ export function resolveWorkspaceRoot(pathHint?: string): string {
118
+ if (pathHint && typeof pathHint === "string" && pathHint.trim()) {
119
+ const trimmed = pathHint.trim().replace(/^['"]|['"]$/g, "");
120
+ const candidate = findProjectRoot(trimmed);
121
+ if (candidate && existsSync(candidate) && !isAppHostDirectory(candidate)) {
122
+ setLastKnownProjectRoot(candidate);
123
+ return candidate;
124
+ }
125
+ }
126
+
127
+ const envRoot = process.env.SEPTUM_WORKSPACE_ROOT || process.env.WORKSPACE_ROOT;
128
+ if (envRoot && existsSync(envRoot) && !isAppHostDirectory(envRoot)) {
129
+ const candidate = canonicalizePath(envRoot);
130
+ setLastKnownProjectRoot(candidate);
131
+ return candidate;
132
+ }
133
+
134
+ if (lastKnownProjectRoot && existsSync(lastKnownProjectRoot)) {
135
+ return lastKnownProjectRoot;
136
+ }
137
+
138
+ const cwd = process.cwd();
139
+ if (!isAppHostDirectory(cwd)) {
140
+ const candidate = findProjectRoot(cwd);
141
+ setLastKnownProjectRoot(candidate);
142
+ return candidate;
143
+ }
144
+
145
+ // Fallback if inside app host directory: keep looking in lastKnown or return cwd
146
+ return canonicalizePath(cwd);
147
+ }