septum 0.1.0 → 0.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/LICENSE +21 -21
- package/README.md +100 -100
- package/bin/septum.ts +4 -4
- package/package.json +63 -62
- package/src/cli/commands/check.ts +161 -161
- package/src/cli/commands/hook.ts +188 -188
- package/src/cli/commands/ingest.ts +29 -29
- package/src/cli/commands/init.ts +211 -211
- package/src/cli/commands/locate.ts +61 -61
- package/src/cli/commands/query.ts +64 -64
- package/src/cli/commands/serve.ts +5 -5
- package/src/cli/commands/slice.ts +90 -90
- package/src/cli/commands/sync.ts +31 -31
- package/src/cli/index.ts +199 -178
- package/src/cli/templates/hooks.ts +75 -75
- package/src/cli/templates/rules.ts +38 -38
- package/src/cli/templates/skill.ts +66 -66
- package/src/core/boundary/evaluator.ts +210 -210
- package/src/core/config/loader.ts +84 -84
- package/src/core/config/schema.ts +39 -39
- package/src/core/database/client.ts +44 -132
- package/src/core/database/repositories/dependency.repository.ts +279 -279
- package/src/core/database/repositories/domain.repository.ts +198 -198
- package/src/core/database/repositories/file.repository.ts +99 -99
- package/src/core/database/repositories/meta.repository.ts +33 -33
- package/src/core/database/repositories/symbol.repository.ts +424 -424
- package/src/core/database/repository.ts +242 -242
- package/src/core/database/schema.ts +120 -0
- package/src/core/discovery/topology-detector.ts +418 -418
- package/src/core/ingestion/hasher.ts +5 -5
- package/src/core/ingestion/pipeline.ts +438 -438
- package/src/core/parser/boundary-tracker.ts +128 -128
- package/src/core/parser/extractors/base.ts +60 -60
- package/src/core/parser/extractors/frontend.ts +194 -194
- package/src/core/parser/extractors/go.ts +176 -176
- package/src/core/parser/extractors/laravel-semantic.ts +426 -426
- package/src/core/parser/extractors/mcp-cli-semantic.ts +199 -199
- package/src/core/parser/extractors/nestjs-semantic.ts +119 -119
- package/src/core/parser/extractors/php.ts +149 -149
- package/src/core/parser/extractors/python.ts +226 -226
- package/src/core/parser/extractors/registry.ts +49 -49
- package/src/core/parser/extractors/semantic-extractor.interface.ts +21 -21
- package/src/core/parser/extractors/typescript.ts +177 -177
- package/src/core/parser/tree-sitter.ts +39 -39
- package/src/core/resolver/call-graph-tracer.ts +668 -668
- package/src/core/resolver/module-resolver.ts +342 -323
- package/src/core/resolver/symbol-locator.ts +543 -405
- package/src/core/resolver/vertical-slice-tracer.ts +237 -236
- package/src/core/session/session-manager.ts +56 -56
- package/src/core/telemetry/telemetry.ts +86 -86
- package/src/index.ts +18 -18
- package/src/mcp/schemas.ts +68 -68
- package/src/mcp/server.ts +612 -602
- package/src/mcp/tools/check-boundary.ts +102 -102
- package/src/mcp/tools/get-domain-catalog.ts +91 -91
- package/src/mcp/tools/get-feature-context.ts +116 -116
- package/src/mcp/tools/get-symbol-hotspots.ts +49 -49
- package/src/mcp/tools/get-symbol-impact.ts +26 -26
- package/src/mcp/tools/get-symbol.ts +63 -63
- package/src/mcp/tools/locate-symbol.ts +74 -74
- package/src/mcp/tools/register-domain.ts +64 -64
- package/src/mcp/tools/trace-vertical-slice.ts +102 -102
- package/src/types/index.ts +296 -296
- package/src/version.ts +3 -0
- package/src/core/database/schema.sql +0 -92
|
@@ -1,49 +1,49 @@
|
|
|
1
|
-
import type { ValidatedSeptumConfig } from "../../core/config/schema.ts";
|
|
2
|
-
import type { DatabaseRepository } from "../../core/database/repository.ts";
|
|
3
|
-
import type { SymbolKind } from "../../types/index.ts";
|
|
4
|
-
|
|
5
|
-
export interface GetSymbolHotspotsArgs {
|
|
6
|
-
min_lines?: number;
|
|
7
|
-
kind?: SymbolKind;
|
|
8
|
-
domain?: string;
|
|
9
|
-
limit?: number;
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
export function handleGetSymbolHotspots(
|
|
13
|
-
repo: DatabaseRepository,
|
|
14
|
-
_config: ValidatedSeptumConfig,
|
|
15
|
-
args: GetSymbolHotspotsArgs
|
|
16
|
-
) {
|
|
17
|
-
const minLines = args.min_lines ?? 30;
|
|
18
|
-
const limit = args.limit ?? 30;
|
|
19
|
-
|
|
20
|
-
const hotspots = repo.getHotspotSymbols({
|
|
21
|
-
minLines,
|
|
22
|
-
kind: args.kind,
|
|
23
|
-
domain: args.domain,
|
|
24
|
-
limit,
|
|
25
|
-
});
|
|
26
|
-
|
|
27
|
-
const payload = {
|
|
28
|
-
total_found: hotspots.length,
|
|
29
|
-
threshold_min_lines: minLines,
|
|
30
|
-
hotspots: hotspots.map((h) => ({
|
|
31
|
-
name: h.name,
|
|
32
|
-
kind: h.kind,
|
|
33
|
-
line_count: h.line_count,
|
|
34
|
-
line_span: `${h.line_start}-${h.line_end}`,
|
|
35
|
-
file_path: h.file_path,
|
|
36
|
-
domain: h.domain_name,
|
|
37
|
-
signature: h.signature,
|
|
38
|
-
})),
|
|
39
|
-
};
|
|
40
|
-
|
|
41
|
-
return {
|
|
42
|
-
content: [
|
|
43
|
-
{
|
|
44
|
-
type: "text" as const,
|
|
45
|
-
text: JSON.stringify(payload, null, 2),
|
|
46
|
-
},
|
|
47
|
-
],
|
|
48
|
-
};
|
|
49
|
-
}
|
|
1
|
+
import type { ValidatedSeptumConfig } from "../../core/config/schema.ts";
|
|
2
|
+
import type { DatabaseRepository } from "../../core/database/repository.ts";
|
|
3
|
+
import type { SymbolKind } from "../../types/index.ts";
|
|
4
|
+
|
|
5
|
+
export interface GetSymbolHotspotsArgs {
|
|
6
|
+
min_lines?: number;
|
|
7
|
+
kind?: SymbolKind;
|
|
8
|
+
domain?: string;
|
|
9
|
+
limit?: number;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export function handleGetSymbolHotspots(
|
|
13
|
+
repo: DatabaseRepository,
|
|
14
|
+
_config: ValidatedSeptumConfig,
|
|
15
|
+
args: GetSymbolHotspotsArgs
|
|
16
|
+
) {
|
|
17
|
+
const minLines = args.min_lines ?? 30;
|
|
18
|
+
const limit = args.limit ?? 30;
|
|
19
|
+
|
|
20
|
+
const hotspots = repo.getHotspotSymbols({
|
|
21
|
+
minLines,
|
|
22
|
+
kind: args.kind,
|
|
23
|
+
domain: args.domain,
|
|
24
|
+
limit,
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
const payload = {
|
|
28
|
+
total_found: hotspots.length,
|
|
29
|
+
threshold_min_lines: minLines,
|
|
30
|
+
hotspots: hotspots.map((h) => ({
|
|
31
|
+
name: h.name,
|
|
32
|
+
kind: h.kind,
|
|
33
|
+
line_count: h.line_count,
|
|
34
|
+
line_span: `${h.line_start}-${h.line_end}`,
|
|
35
|
+
file_path: h.file_path,
|
|
36
|
+
domain: h.domain_name,
|
|
37
|
+
signature: h.signature,
|
|
38
|
+
})),
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
return {
|
|
42
|
+
content: [
|
|
43
|
+
{
|
|
44
|
+
type: "text" as const,
|
|
45
|
+
text: JSON.stringify(payload, null, 2),
|
|
46
|
+
},
|
|
47
|
+
],
|
|
48
|
+
};
|
|
49
|
+
}
|
|
@@ -1,26 +1,26 @@
|
|
|
1
|
-
import type { ValidatedSeptumConfig } from "../../core/config/schema.ts";
|
|
2
|
-
import type { SeptumRepository } from "../../core/database/repository.ts";
|
|
3
|
-
import type { GetSymbolImpactArgs } from "../../types/index.ts";
|
|
4
|
-
|
|
5
|
-
export function handleGetSymbolImpact(
|
|
6
|
-
repo: SeptumRepository,
|
|
7
|
-
_config: ValidatedSeptumConfig,
|
|
8
|
-
args: GetSymbolImpactArgs
|
|
9
|
-
) {
|
|
10
|
-
if (!args.symbol) {
|
|
11
|
-
throw new Error(
|
|
12
|
-
"Missing required argument: 'symbol' (e.g. 'OrderService::cancelOrder', 'OrderService', or 'cancelOrder')"
|
|
13
|
-
);
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
const impact = repo.getSymbolImpact(args.symbol);
|
|
17
|
-
|
|
18
|
-
return {
|
|
19
|
-
content: [
|
|
20
|
-
{
|
|
21
|
-
type: "text" as const,
|
|
22
|
-
text: JSON.stringify(impact, null, 2),
|
|
23
|
-
},
|
|
24
|
-
],
|
|
25
|
-
};
|
|
26
|
-
}
|
|
1
|
+
import type { ValidatedSeptumConfig } from "../../core/config/schema.ts";
|
|
2
|
+
import type { SeptumRepository } from "../../core/database/repository.ts";
|
|
3
|
+
import type { GetSymbolImpactArgs } from "../../types/index.ts";
|
|
4
|
+
|
|
5
|
+
export function handleGetSymbolImpact(
|
|
6
|
+
repo: SeptumRepository,
|
|
7
|
+
_config: ValidatedSeptumConfig,
|
|
8
|
+
args: GetSymbolImpactArgs
|
|
9
|
+
) {
|
|
10
|
+
if (!args.symbol) {
|
|
11
|
+
throw new Error(
|
|
12
|
+
"Missing required argument: 'symbol' (e.g. 'OrderService::cancelOrder', 'OrderService', or 'cancelOrder')"
|
|
13
|
+
);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
const impact = repo.getSymbolImpact(args.symbol);
|
|
17
|
+
|
|
18
|
+
return {
|
|
19
|
+
content: [
|
|
20
|
+
{
|
|
21
|
+
type: "text" as const,
|
|
22
|
+
text: JSON.stringify(impact, null, 2),
|
|
23
|
+
},
|
|
24
|
+
],
|
|
25
|
+
};
|
|
26
|
+
}
|
|
@@ -1,63 +1,63 @@
|
|
|
1
|
-
import type { ValidatedSeptumConfig } from "../../core/config/schema.ts";
|
|
2
|
-
import type { SeptumRepository } from "../../core/database/repository.ts";
|
|
3
|
-
import { SymbolLocator } from "../../core/resolver/symbol-locator.ts";
|
|
4
|
-
import type { GetSymbolArgs } from "../../types/index.ts";
|
|
5
|
-
|
|
6
|
-
export function handleGetSymbol(
|
|
7
|
-
repo: SeptumRepository,
|
|
8
|
-
_config: ValidatedSeptumConfig,
|
|
9
|
-
args: GetSymbolArgs
|
|
10
|
-
) {
|
|
11
|
-
if (!args.symbol) {
|
|
12
|
-
throw new Error(
|
|
13
|
-
"Missing required argument: 'symbol' (e.g. 'OrderController::cancelOrder', 'OrderService', or 'cancelOrder')"
|
|
14
|
-
);
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
const details = repo.getSymbolDetails(args.symbol, {
|
|
18
|
-
domain: args.domain,
|
|
19
|
-
includeDependencies: args.include_dependencies,
|
|
20
|
-
});
|
|
21
|
-
|
|
22
|
-
if (details) {
|
|
23
|
-
return {
|
|
24
|
-
content: [
|
|
25
|
-
{
|
|
26
|
-
type: "text" as const,
|
|
27
|
-
text: JSON.stringify(details, null, 2),
|
|
28
|
-
},
|
|
29
|
-
],
|
|
30
|
-
};
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
// Fallback to fuzzy SymbolLocator to provide actionable hints
|
|
34
|
-
const locator = new SymbolLocator(repo);
|
|
35
|
-
const fallback = locator.locate(args.symbol, args.domain);
|
|
36
|
-
|
|
37
|
-
const payload = {
|
|
38
|
-
symbol: args.symbol,
|
|
39
|
-
found: false,
|
|
40
|
-
message: `Symbol '${args.symbol}' was not found in the deterministic catalog.`,
|
|
41
|
-
suggestions: fallback.suggestions.map((s) => ({
|
|
42
|
-
name: s.name,
|
|
43
|
-
similarity_score: Math.round(s.similarity_score * 100) / 100,
|
|
44
|
-
exact_range: {
|
|
45
|
-
start_line: s.line_start,
|
|
46
|
-
end_line: s.line_end,
|
|
47
|
-
total_lines: s.line_end - s.line_start + 1,
|
|
48
|
-
},
|
|
49
|
-
signature: s.signature,
|
|
50
|
-
file_path: s.file_path,
|
|
51
|
-
})),
|
|
52
|
-
sibling_methods: fallback.sibling_methods,
|
|
53
|
-
};
|
|
54
|
-
|
|
55
|
-
return {
|
|
56
|
-
content: [
|
|
57
|
-
{
|
|
58
|
-
type: "text" as const,
|
|
59
|
-
text: JSON.stringify(payload, null, 2),
|
|
60
|
-
},
|
|
61
|
-
],
|
|
62
|
-
};
|
|
63
|
-
}
|
|
1
|
+
import type { ValidatedSeptumConfig } from "../../core/config/schema.ts";
|
|
2
|
+
import type { SeptumRepository } from "../../core/database/repository.ts";
|
|
3
|
+
import { SymbolLocator } from "../../core/resolver/symbol-locator.ts";
|
|
4
|
+
import type { GetSymbolArgs } from "../../types/index.ts";
|
|
5
|
+
|
|
6
|
+
export function handleGetSymbol(
|
|
7
|
+
repo: SeptumRepository,
|
|
8
|
+
_config: ValidatedSeptumConfig,
|
|
9
|
+
args: GetSymbolArgs
|
|
10
|
+
) {
|
|
11
|
+
if (!args.symbol) {
|
|
12
|
+
throw new Error(
|
|
13
|
+
"Missing required argument: 'symbol' (e.g. 'OrderController::cancelOrder', 'OrderService', or 'cancelOrder')"
|
|
14
|
+
);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
const details = repo.getSymbolDetails(args.symbol, {
|
|
18
|
+
domain: args.domain,
|
|
19
|
+
includeDependencies: args.include_dependencies,
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
if (details) {
|
|
23
|
+
return {
|
|
24
|
+
content: [
|
|
25
|
+
{
|
|
26
|
+
type: "text" as const,
|
|
27
|
+
text: JSON.stringify(details, null, 2),
|
|
28
|
+
},
|
|
29
|
+
],
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// Fallback to fuzzy SymbolLocator to provide actionable hints
|
|
34
|
+
const locator = new SymbolLocator(repo);
|
|
35
|
+
const fallback = locator.locate(args.symbol, args.domain);
|
|
36
|
+
|
|
37
|
+
const payload = {
|
|
38
|
+
symbol: args.symbol,
|
|
39
|
+
found: false,
|
|
40
|
+
message: `Symbol '${args.symbol}' was not found in the deterministic catalog.`,
|
|
41
|
+
suggestions: fallback.suggestions.map((s) => ({
|
|
42
|
+
name: s.name,
|
|
43
|
+
similarity_score: Math.round(s.similarity_score * 100) / 100,
|
|
44
|
+
exact_range: {
|
|
45
|
+
start_line: s.line_start,
|
|
46
|
+
end_line: s.line_end,
|
|
47
|
+
total_lines: s.line_end - s.line_start + 1,
|
|
48
|
+
},
|
|
49
|
+
signature: s.signature,
|
|
50
|
+
file_path: s.file_path,
|
|
51
|
+
})),
|
|
52
|
+
sibling_methods: fallback.sibling_methods,
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
return {
|
|
56
|
+
content: [
|
|
57
|
+
{
|
|
58
|
+
type: "text" as const,
|
|
59
|
+
text: JSON.stringify(payload, null, 2),
|
|
60
|
+
},
|
|
61
|
+
],
|
|
62
|
+
};
|
|
63
|
+
}
|
|
@@ -1,74 +1,74 @@
|
|
|
1
|
-
import type { ValidatedSeptumConfig } from "../../core/config/schema.ts";
|
|
2
|
-
import type { SeptumRepository } from "../../core/database/repository.ts";
|
|
3
|
-
import {
|
|
4
|
-
SymbolLocator,
|
|
5
|
-
type SymbolLocationResult,
|
|
6
|
-
} from "../../core/resolver/symbol-locator.ts";
|
|
7
|
-
|
|
8
|
-
export interface LocateSymbolArgs {
|
|
9
|
-
query: string;
|
|
10
|
-
domain?: string;
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
export function handleLocateSymbol(
|
|
14
|
-
repo: SeptumRepository,
|
|
15
|
-
config: ValidatedSeptumConfig,
|
|
16
|
-
args: LocateSymbolArgs
|
|
17
|
-
) {
|
|
18
|
-
if (!args.query) {
|
|
19
|
-
throw new Error(
|
|
20
|
-
"Missing required argument: 'query' (e.g. 'OrderController::calculateTotal' or error log snippet)"
|
|
21
|
-
);
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
const locator = new SymbolLocator(repo);
|
|
25
|
-
const result: SymbolLocationResult = locator.locate(args.query, args.domain);
|
|
26
|
-
|
|
27
|
-
let formattedText = "";
|
|
28
|
-
|
|
29
|
-
if (result.found) {
|
|
30
|
-
formattedText = `=== SYMBOL LOCATED ===\n`;
|
|
31
|
-
formattedText += `Status: FOUND (Exact Match)\n`;
|
|
32
|
-
formattedText += `File: ${result.file_path}\n`;
|
|
33
|
-
if (result.exact_symbol) {
|
|
34
|
-
formattedText += `Symbol: ${result.exact_symbol.name} [${result.exact_symbol.kind.toUpperCase()}]\n`;
|
|
35
|
-
formattedText += `Signature: ${result.exact_symbol.signature}\n`;
|
|
36
|
-
formattedText += `Lines: ${result.exact_symbol.line_start} - ${result.exact_symbol.line_end}\n`;
|
|
37
|
-
}
|
|
38
|
-
if (result.sibling_methods && result.sibling_methods.length > 0) {
|
|
39
|
-
formattedText += `\nSibling Methods in ${result.container_name || "Container"} (${result.sibling_methods.length}):\n`;
|
|
40
|
-
formattedText += ` ${result.sibling_methods.join(", ")}\n`;
|
|
41
|
-
}
|
|
42
|
-
} else {
|
|
43
|
-
formattedText = `=== SYMBOL NOT FOUND / DIAGNOSTIC RESOLUTION ===\n`;
|
|
44
|
-
formattedText += `Status: NOT FOUND\n`;
|
|
45
|
-
if (result.file_path) {
|
|
46
|
-
formattedText += `Target File: ${result.file_path}\n`;
|
|
47
|
-
formattedText += `Target Container: ${result.container_name || "Unknown"}\n`;
|
|
48
|
-
}
|
|
49
|
-
formattedText += `Message: ${result.message}\n`;
|
|
50
|
-
|
|
51
|
-
if (result.sibling_methods && result.sibling_methods.length > 0) {
|
|
52
|
-
formattedText += `\nExisting Methods in ${result.container_name || "Container"} (${result.sibling_methods.length}):\n`;
|
|
53
|
-
formattedText += ` ${result.sibling_methods.join(", ")}\n`;
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
if (result.suggestions.length > 0) {
|
|
57
|
-
formattedText += `\nTop Suggestions (Ranked by Similarity):\n`;
|
|
58
|
-
for (const sug of result.suggestions) {
|
|
59
|
-
const percent = Math.round(sug.similarity_score * 100);
|
|
60
|
-
formattedText += ` • ${sug.name} [${percent}% match] -> lines ${sug.line_start}-${sug.line_end} (${sug.signature})\n`;
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
return {
|
|
66
|
-
content: [
|
|
67
|
-
{
|
|
68
|
-
type: "text",
|
|
69
|
-
text: formattedText.trim(),
|
|
70
|
-
},
|
|
71
|
-
],
|
|
72
|
-
metadata: result,
|
|
73
|
-
};
|
|
74
|
-
}
|
|
1
|
+
import type { ValidatedSeptumConfig } from "../../core/config/schema.ts";
|
|
2
|
+
import type { SeptumRepository } from "../../core/database/repository.ts";
|
|
3
|
+
import {
|
|
4
|
+
SymbolLocator,
|
|
5
|
+
type SymbolLocationResult,
|
|
6
|
+
} from "../../core/resolver/symbol-locator.ts";
|
|
7
|
+
|
|
8
|
+
export interface LocateSymbolArgs {
|
|
9
|
+
query: string;
|
|
10
|
+
domain?: string;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export function handleLocateSymbol(
|
|
14
|
+
repo: SeptumRepository,
|
|
15
|
+
config: ValidatedSeptumConfig,
|
|
16
|
+
args: LocateSymbolArgs
|
|
17
|
+
) {
|
|
18
|
+
if (!args.query) {
|
|
19
|
+
throw new Error(
|
|
20
|
+
"Missing required argument: 'query' (e.g. 'OrderController::calculateTotal' or error log snippet)"
|
|
21
|
+
);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
const locator = new SymbolLocator(repo);
|
|
25
|
+
const result: SymbolLocationResult = locator.locate(args.query, args.domain);
|
|
26
|
+
|
|
27
|
+
let formattedText = "";
|
|
28
|
+
|
|
29
|
+
if (result.found) {
|
|
30
|
+
formattedText = `=== SYMBOL LOCATED ===\n`;
|
|
31
|
+
formattedText += `Status: FOUND (Exact Match)\n`;
|
|
32
|
+
formattedText += `File: ${result.file_path}\n`;
|
|
33
|
+
if (result.exact_symbol) {
|
|
34
|
+
formattedText += `Symbol: ${result.exact_symbol.name} [${result.exact_symbol.kind.toUpperCase()}]\n`;
|
|
35
|
+
formattedText += `Signature: ${result.exact_symbol.signature}\n`;
|
|
36
|
+
formattedText += `Lines: ${result.exact_symbol.line_start} - ${result.exact_symbol.line_end}\n`;
|
|
37
|
+
}
|
|
38
|
+
if (result.sibling_methods && result.sibling_methods.length > 0) {
|
|
39
|
+
formattedText += `\nSibling Methods in ${result.container_name || "Container"} (${result.sibling_methods.length}):\n`;
|
|
40
|
+
formattedText += ` ${result.sibling_methods.join(", ")}\n`;
|
|
41
|
+
}
|
|
42
|
+
} else {
|
|
43
|
+
formattedText = `=== SYMBOL NOT FOUND / DIAGNOSTIC RESOLUTION ===\n`;
|
|
44
|
+
formattedText += `Status: NOT FOUND\n`;
|
|
45
|
+
if (result.file_path) {
|
|
46
|
+
formattedText += `Target File: ${result.file_path}\n`;
|
|
47
|
+
formattedText += `Target Container: ${result.container_name || "Unknown"}\n`;
|
|
48
|
+
}
|
|
49
|
+
formattedText += `Message: ${result.message}\n`;
|
|
50
|
+
|
|
51
|
+
if (result.sibling_methods && result.sibling_methods.length > 0) {
|
|
52
|
+
formattedText += `\nExisting Methods in ${result.container_name || "Container"} (${result.sibling_methods.length}):\n`;
|
|
53
|
+
formattedText += ` ${result.sibling_methods.join(", ")}\n`;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
if (result.suggestions.length > 0) {
|
|
57
|
+
formattedText += `\nTop Suggestions (Ranked by Similarity):\n`;
|
|
58
|
+
for (const sug of result.suggestions) {
|
|
59
|
+
const percent = Math.round(sug.similarity_score * 100);
|
|
60
|
+
formattedText += ` • ${sug.name} [${percent}% match] -> lines ${sug.line_start}-${sug.line_end} (${sug.signature})\n`;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
return {
|
|
66
|
+
content: [
|
|
67
|
+
{
|
|
68
|
+
type: "text",
|
|
69
|
+
text: formattedText.trim(),
|
|
70
|
+
},
|
|
71
|
+
],
|
|
72
|
+
metadata: result,
|
|
73
|
+
};
|
|
74
|
+
}
|
|
@@ -1,64 +1,64 @@
|
|
|
1
|
-
import type { ValidatedSeptumConfig } from "../../core/config/schema.ts";
|
|
2
|
-
import type { SeptumRepository } from "../../core/database/repository.ts";
|
|
3
|
-
import { IngestionPipeline, type IngestionMetrics } from "../../core/ingestion/pipeline.ts";
|
|
4
|
-
import type { DomainConfig } from "../../types/index.ts";
|
|
5
|
-
|
|
6
|
-
export interface RegisterDomainArgs {
|
|
7
|
-
name: string;
|
|
8
|
-
root: string;
|
|
9
|
-
description?: string;
|
|
10
|
-
allowed_dependencies?: string[];
|
|
11
|
-
forbidden_dependencies?: string[];
|
|
12
|
-
archetypes?: Record<string, string>;
|
|
13
|
-
ingest_now?: boolean;
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
export async function handleRegisterDomain(
|
|
17
|
-
repo: SeptumRepository,
|
|
18
|
-
config: ValidatedSeptumConfig,
|
|
19
|
-
args: RegisterDomainArgs
|
|
20
|
-
) {
|
|
21
|
-
if (!args.name || !args.root) {
|
|
22
|
-
throw new Error("Missing required arguments: 'name' and 'root' are required.");
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
const domainConfig: DomainConfig = {
|
|
26
|
-
root: args.root,
|
|
27
|
-
description: args.description || `Domain: ${args.name}`,
|
|
28
|
-
allowed_dependencies: args.allowed_dependencies || [],
|
|
29
|
-
forbidden_dependencies: args.forbidden_dependencies || [],
|
|
30
|
-
archetypes: args.archetypes || {},
|
|
31
|
-
};
|
|
32
|
-
|
|
33
|
-
const domainId = repo.domains.upsertDomain(args.name, domainConfig);
|
|
34
|
-
|
|
35
|
-
config.domains[args.name] = domainConfig;
|
|
36
|
-
|
|
37
|
-
let ingestionMetrics: IngestionMetrics | null = null;
|
|
38
|
-
if (args.ingest_now) {
|
|
39
|
-
const pipeline = new IngestionPipeline(repo);
|
|
40
|
-
ingestionMetrics = await pipeline.run(config);
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
return {
|
|
44
|
-
content: [
|
|
45
|
-
{
|
|
46
|
-
type: "text" as const,
|
|
47
|
-
text: JSON.stringify(
|
|
48
|
-
{
|
|
49
|
-
status: "success",
|
|
50
|
-
message: `Domain '${args.name}' successfully registered in SQLite SSOT.${
|
|
51
|
-
args.ingest_now ? " Initial ingestion completed." : ""
|
|
52
|
-
}`,
|
|
53
|
-
domain_id: domainId,
|
|
54
|
-
domain: args.name,
|
|
55
|
-
config: domainConfig,
|
|
56
|
-
...(ingestionMetrics ? { ingestion_metrics: ingestionMetrics } : {}),
|
|
57
|
-
},
|
|
58
|
-
null,
|
|
59
|
-
2
|
|
60
|
-
),
|
|
61
|
-
},
|
|
62
|
-
],
|
|
63
|
-
};
|
|
64
|
-
}
|
|
1
|
+
import type { ValidatedSeptumConfig } from "../../core/config/schema.ts";
|
|
2
|
+
import type { SeptumRepository } from "../../core/database/repository.ts";
|
|
3
|
+
import { IngestionPipeline, type IngestionMetrics } from "../../core/ingestion/pipeline.ts";
|
|
4
|
+
import type { DomainConfig } from "../../types/index.ts";
|
|
5
|
+
|
|
6
|
+
export interface RegisterDomainArgs {
|
|
7
|
+
name: string;
|
|
8
|
+
root: string;
|
|
9
|
+
description?: string;
|
|
10
|
+
allowed_dependencies?: string[];
|
|
11
|
+
forbidden_dependencies?: string[];
|
|
12
|
+
archetypes?: Record<string, string>;
|
|
13
|
+
ingest_now?: boolean;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export async function handleRegisterDomain(
|
|
17
|
+
repo: SeptumRepository,
|
|
18
|
+
config: ValidatedSeptumConfig,
|
|
19
|
+
args: RegisterDomainArgs
|
|
20
|
+
) {
|
|
21
|
+
if (!args.name || !args.root) {
|
|
22
|
+
throw new Error("Missing required arguments: 'name' and 'root' are required.");
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
const domainConfig: DomainConfig = {
|
|
26
|
+
root: args.root,
|
|
27
|
+
description: args.description || `Domain: ${args.name}`,
|
|
28
|
+
allowed_dependencies: args.allowed_dependencies || [],
|
|
29
|
+
forbidden_dependencies: args.forbidden_dependencies || [],
|
|
30
|
+
archetypes: args.archetypes || {},
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
const domainId = repo.domains.upsertDomain(args.name, domainConfig);
|
|
34
|
+
|
|
35
|
+
config.domains[args.name] = domainConfig;
|
|
36
|
+
|
|
37
|
+
let ingestionMetrics: IngestionMetrics | null = null;
|
|
38
|
+
if (args.ingest_now) {
|
|
39
|
+
const pipeline = new IngestionPipeline(repo);
|
|
40
|
+
ingestionMetrics = await pipeline.run(config);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
return {
|
|
44
|
+
content: [
|
|
45
|
+
{
|
|
46
|
+
type: "text" as const,
|
|
47
|
+
text: JSON.stringify(
|
|
48
|
+
{
|
|
49
|
+
status: "success",
|
|
50
|
+
message: `Domain '${args.name}' successfully registered in SQLite SSOT.${
|
|
51
|
+
args.ingest_now ? " Initial ingestion completed." : ""
|
|
52
|
+
}`,
|
|
53
|
+
domain_id: domainId,
|
|
54
|
+
domain: args.name,
|
|
55
|
+
config: domainConfig,
|
|
56
|
+
...(ingestionMetrics ? { ingestion_metrics: ingestionMetrics } : {}),
|
|
57
|
+
},
|
|
58
|
+
null,
|
|
59
|
+
2
|
|
60
|
+
),
|
|
61
|
+
},
|
|
62
|
+
],
|
|
63
|
+
};
|
|
64
|
+
}
|