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.
Files changed (65) hide show
  1. package/LICENSE +21 -21
  2. package/README.md +100 -100
  3. package/bin/septum.ts +4 -4
  4. package/package.json +63 -62
  5. package/src/cli/commands/check.ts +161 -161
  6. package/src/cli/commands/hook.ts +188 -188
  7. package/src/cli/commands/ingest.ts +29 -29
  8. package/src/cli/commands/init.ts +211 -211
  9. package/src/cli/commands/locate.ts +61 -61
  10. package/src/cli/commands/query.ts +64 -64
  11. package/src/cli/commands/serve.ts +5 -5
  12. package/src/cli/commands/slice.ts +90 -90
  13. package/src/cli/commands/sync.ts +31 -31
  14. package/src/cli/index.ts +199 -178
  15. package/src/cli/templates/hooks.ts +75 -75
  16. package/src/cli/templates/rules.ts +38 -38
  17. package/src/cli/templates/skill.ts +66 -66
  18. package/src/core/boundary/evaluator.ts +210 -210
  19. package/src/core/config/loader.ts +84 -84
  20. package/src/core/config/schema.ts +39 -39
  21. package/src/core/database/client.ts +44 -132
  22. package/src/core/database/repositories/dependency.repository.ts +279 -279
  23. package/src/core/database/repositories/domain.repository.ts +198 -198
  24. package/src/core/database/repositories/file.repository.ts +99 -99
  25. package/src/core/database/repositories/meta.repository.ts +33 -33
  26. package/src/core/database/repositories/symbol.repository.ts +424 -424
  27. package/src/core/database/repository.ts +242 -242
  28. package/src/core/database/schema.ts +120 -0
  29. package/src/core/discovery/topology-detector.ts +418 -418
  30. package/src/core/ingestion/hasher.ts +5 -5
  31. package/src/core/ingestion/pipeline.ts +438 -438
  32. package/src/core/parser/boundary-tracker.ts +128 -128
  33. package/src/core/parser/extractors/base.ts +60 -60
  34. package/src/core/parser/extractors/frontend.ts +194 -194
  35. package/src/core/parser/extractors/go.ts +176 -176
  36. package/src/core/parser/extractors/laravel-semantic.ts +426 -426
  37. package/src/core/parser/extractors/mcp-cli-semantic.ts +199 -199
  38. package/src/core/parser/extractors/nestjs-semantic.ts +119 -119
  39. package/src/core/parser/extractors/php.ts +149 -149
  40. package/src/core/parser/extractors/python.ts +226 -226
  41. package/src/core/parser/extractors/registry.ts +49 -49
  42. package/src/core/parser/extractors/semantic-extractor.interface.ts +21 -21
  43. package/src/core/parser/extractors/typescript.ts +177 -177
  44. package/src/core/parser/tree-sitter.ts +39 -39
  45. package/src/core/resolver/call-graph-tracer.ts +668 -668
  46. package/src/core/resolver/module-resolver.ts +342 -323
  47. package/src/core/resolver/symbol-locator.ts +543 -405
  48. package/src/core/resolver/vertical-slice-tracer.ts +237 -236
  49. package/src/core/session/session-manager.ts +56 -56
  50. package/src/core/telemetry/telemetry.ts +86 -86
  51. package/src/index.ts +18 -18
  52. package/src/mcp/schemas.ts +68 -68
  53. package/src/mcp/server.ts +612 -602
  54. package/src/mcp/tools/check-boundary.ts +102 -102
  55. package/src/mcp/tools/get-domain-catalog.ts +91 -91
  56. package/src/mcp/tools/get-feature-context.ts +116 -116
  57. package/src/mcp/tools/get-symbol-hotspots.ts +49 -49
  58. package/src/mcp/tools/get-symbol-impact.ts +26 -26
  59. package/src/mcp/tools/get-symbol.ts +63 -63
  60. package/src/mcp/tools/locate-symbol.ts +74 -74
  61. package/src/mcp/tools/register-domain.ts +64 -64
  62. package/src/mcp/tools/trace-vertical-slice.ts +102 -102
  63. package/src/types/index.ts +296 -296
  64. package/src/version.ts +3 -0
  65. package/src/core/database/schema.sql +0 -92
package/src/cli/index.ts CHANGED
@@ -1,178 +1,199 @@
1
- import { SessionManager } from "../core/session/session-manager.ts";
2
- import { handleCheckCommand } from "./commands/check.ts";
3
- import { handleHookCommand } from "./commands/hook.ts";
4
- import { handleIngestCommand } from "./commands/ingest.ts";
5
- import { handleInitCommand } from "./commands/init.ts";
6
- import { handleLocateCommand } from "./commands/locate.ts";
7
- import { handleQueryCommand } from "./commands/query.ts";
8
- import { handleServeCommand } from "./commands/serve.ts";
9
- import { handleSliceCommand } from "./commands/slice.ts";
10
- import { handleSyncCommand } from "./commands/sync.ts";
11
-
12
- export async function runCLI(argv: string[]): Promise<void> {
13
- const args = argv.slice(2);
14
- const command = args[0];
15
-
16
- if (!command || command === "--help" || command === "-h" || command === "help") {
17
- printHelp();
18
- return;
19
- }
20
-
21
- if (command === "--version" || command === "-v" || command === "version") {
22
- console.log("Septum v0.1.0");
23
- return;
24
- }
25
-
26
- try {
27
- switch (command) {
28
- case "init": {
29
- const force = args.includes("--force") || args.includes("-f");
30
- await handleInitCommand(force);
31
- break;
32
- }
33
-
34
- case "ingest": {
35
- await handleIngestCommand();
36
- break;
37
- }
38
-
39
- case "sync": {
40
- const json = args.includes("--json");
41
- await handleSyncCommand({ json });
42
- break;
43
- }
44
-
45
- case "query": {
46
- const domainName = args[1] && !args[1].startsWith("-") ? args[1] : undefined;
47
- let archetype: string | undefined;
48
- const archIndex = args.indexOf("--archetype");
49
- if (archIndex !== -1 && args[archIndex + 1]) {
50
- archetype = args[archIndex + 1];
51
- }
52
- const jsonOutput = args.includes("--json");
53
- await handleQueryCommand(domainName, archetype, jsonOutput);
54
- break;
55
- }
56
-
57
- case "locate": {
58
- const query = args[1];
59
- if (!query) {
60
- console.error("Usage: septum locate <symbol-or-error> [--domain <domain>] [--json]");
61
- process.exit(1);
62
- }
63
- let domain: string | undefined;
64
- const domIndex = args.indexOf("--domain");
65
- if (domIndex !== -1 && args[domIndex + 1]) {
66
- domain = args[domIndex + 1];
67
- }
68
- const json = args.includes("--json");
69
- await handleLocateCommand(query, { domain, json });
70
- break;
71
- }
72
-
73
- case "slice": {
74
- const query = args[1];
75
- if (!query) {
76
- console.error("Usage: septum slice <route-or-intent> [--json]");
77
- process.exit(1);
78
- }
79
- const json = args.includes("--json");
80
- await handleSliceCommand(query, { json });
81
- break;
82
- }
83
-
84
- case "check": {
85
- const strict = args.includes("--strict");
86
- const staged = args.includes("--staged");
87
- let feature: string | undefined;
88
- const featIndex = args.indexOf("--feature");
89
- if (featIndex !== -1 && args[featIndex + 1]) {
90
- feature = args[featIndex + 1];
91
- }
92
- await handleCheckCommand({ strict, staged, feature });
93
- break;
94
- }
95
-
96
- case "serve": {
97
- await handleServeCommand();
98
- break;
99
- }
100
-
101
- case "feature": {
102
- const sub = args[1];
103
- if (sub === "clear") {
104
- const cleared = SessionManager.clearActiveSession(process.cwd());
105
- if (cleared) {
106
- console.log("✓ Active feature session successfully cleared.");
107
- } else {
108
- console.log("ℹ No active feature session found.");
109
- }
110
- } else if (sub === "status" || !sub) {
111
- const current = SessionManager.getActiveSession(process.cwd());
112
- if (current) {
113
- console.log(`\nActive Feature Session:`);
114
- console.log(`▶ Feature Key : ${current.feature_key}`);
115
- console.log(`▶ Domain : ${current.domain}`);
116
- console.log(`▶ Locked At : ${current.locked_at}`);
117
- console.log(`▶ Touchpoints : ${current.touchpoints.join(", ")}\n`);
118
- } else {
119
- console.log("ℹ No active feature session. All domain files accessible according to boundary rules.");
120
- }
121
- } else {
122
- console.error(`Unknown feature subcommand: '${sub}'. Use 'status' or 'clear'.`);
123
- process.exit(1);
124
- }
125
- break;
126
- }
127
-
128
- case "hook": {
129
- await handleHookCommand(args);
130
- break;
131
- }
132
-
133
- default: {
134
- console.error(`[Septum] Unknown command: '${command}'`);
135
- console.error("Run 'septum --help' for available commands.");
136
- process.exit(1);
137
- }
138
- }
139
- } catch (err) {
140
- const message = err instanceof Error ? err.message : String(err);
141
- console.error(`\x1b[31m[Septum Error]\x1b[0m ${message}`);
142
- process.exit(1);
143
- }
144
- }
145
-
146
- function printHelp(): void {
147
- console.log(`
148
- Septum — Deterministic Bounded-Context & Structural File Catalog
149
- Version: 0.1.0
150
-
151
- USAGE:
152
- septum <command> [options]
153
-
154
- COMMANDS:
155
- init Initialize configuration, gitignore, pre-commit hook, and ingest catalog
156
- Options:
157
- --force, -f Overwrite existing catalog and configuration
158
- ingest Scan codebase, parse AST, and synchronize .septum/septum.db
159
- sync Fast incremental synchronization of changed files to SQLite SSOT
160
- Options:
161
- --json Output formatted JSON metrics
162
- query [domain] Query structural catalog for a domain or list all domains
163
- Options:
164
- --archetype <name> Filter by archetype (service, model, controller)
165
- --json Output formatted JSON
166
- check Audit codebase for cross-domain boundary violations
167
- Options:
168
- --staged Audit only git staged changes (ideal for pre-commit)
169
- --feature <name> Enforce feature-specific allowed_touchpoints
170
- --strict Exit with code 1 on any violation
171
- feature [status|clear] View or release active feature context session lock
172
- serve Start Model Context Protocol (MCP) server over stdio
173
-
174
- FLAGS:
175
- -h, --help Show this help message
176
- -v, --version Show current version
177
- `);
178
- }
1
+ import { parseArgs } from "node:util";
2
+ import { SessionManager } from "../core/session/session-manager.ts";
3
+ import { SEPTUM_VERSION } from "../version.ts";
4
+ import { handleCheckCommand } from "./commands/check.ts";
5
+ import { handleHookCommand } from "./commands/hook.ts";
6
+ import { handleIngestCommand } from "./commands/ingest.ts";
7
+ import { handleInitCommand } from "./commands/init.ts";
8
+ import { handleLocateCommand } from "./commands/locate.ts";
9
+ import { handleQueryCommand } from "./commands/query.ts";
10
+ import { handleServeCommand } from "./commands/serve.ts";
11
+ import { handleSliceCommand } from "./commands/slice.ts";
12
+ import { handleSyncCommand } from "./commands/sync.ts";
13
+
14
+ export async function runCLI(argv: string[]): Promise<void> {
15
+ let parsed;
16
+ try {
17
+ parsed = parseArgs({
18
+ args: argv.slice(2),
19
+ options: {
20
+ help: { type: "boolean", short: "h" },
21
+ version: { type: "boolean", short: "v" },
22
+ force: { type: "boolean", short: "f" },
23
+ json: { type: "boolean" },
24
+ strict: { type: "boolean" },
25
+ staged: { type: "boolean" },
26
+ domain: { type: "string", short: "d" },
27
+ archetype: { type: "string", short: "a" },
28
+ feature: { type: "string" },
29
+ },
30
+ allowPositionals: true,
31
+ strict: false,
32
+ });
33
+ } catch (err) {
34
+ const message = err instanceof Error ? err.message : String(err);
35
+ console.error(`\x1b[31m[Septum Error]\x1b[0m ${message}`);
36
+ process.exit(1);
37
+ }
38
+
39
+ const { values: flags, positionals } = parsed;
40
+ const command = positionals[0];
41
+
42
+ if (flags.version || command === "version") {
43
+ console.log(`Septum v${SEPTUM_VERSION}`);
44
+ return;
45
+ }
46
+
47
+ if (flags.help || !command || command === "help") {
48
+ printHelp();
49
+ return;
50
+ }
51
+
52
+ try {
53
+ switch (command) {
54
+ case "init": {
55
+ const force = Boolean(flags.force);
56
+ await handleInitCommand(force);
57
+ break;
58
+ }
59
+
60
+ case "ingest": {
61
+ await handleIngestCommand();
62
+ break;
63
+ }
64
+
65
+ case "sync": {
66
+ const json = Boolean(flags.json);
67
+ await handleSyncCommand({ json });
68
+ break;
69
+ }
70
+
71
+ case "query": {
72
+ const domainName = positionals[1];
73
+ const archetype = typeof flags.archetype === "string" ? flags.archetype : undefined;
74
+ const jsonOutput = Boolean(flags.json);
75
+ await handleQueryCommand(domainName, archetype, jsonOutput);
76
+ break;
77
+ }
78
+
79
+ case "locate": {
80
+ const query = positionals[1];
81
+ if (!query) {
82
+ console.error("Usage: septum locate <symbol-or-error> [--domain <domain>] [--json]");
83
+ process.exit(1);
84
+ }
85
+ const domain = typeof flags.domain === "string" ? flags.domain : undefined;
86
+ const json = Boolean(flags.json);
87
+ await handleLocateCommand(query, { domain, json });
88
+ break;
89
+ }
90
+
91
+ case "slice": {
92
+ const query = positionals[1];
93
+ if (!query) {
94
+ console.error("Usage: septum slice <route-or-intent> [--json]");
95
+ process.exit(1);
96
+ }
97
+ const json = Boolean(flags.json);
98
+ await handleSliceCommand(query, { json });
99
+ break;
100
+ }
101
+
102
+ case "check": {
103
+ const strict = Boolean(flags.strict);
104
+ const staged = Boolean(flags.staged);
105
+ const feature = typeof flags.feature === "string" ? flags.feature : undefined;
106
+ await handleCheckCommand({ strict, staged, feature });
107
+ break;
108
+ }
109
+
110
+ case "serve": {
111
+ await handleServeCommand();
112
+ break;
113
+ }
114
+
115
+ case "feature": {
116
+ const sub = positionals[1];
117
+ if (sub === "clear") {
118
+ const cleared = SessionManager.clearActiveSession(process.cwd());
119
+ if (cleared) {
120
+ console.log("✓ Active feature session successfully cleared.");
121
+ } else {
122
+ console.log("ℹ No active feature session found.");
123
+ }
124
+ } else if (sub === "status" || !sub) {
125
+ const current = SessionManager.getActiveSession(process.cwd());
126
+ if (current) {
127
+ console.log(`\nActive Feature Session:`);
128
+ console.log(`▶ Feature Key : ${current.feature_key}`);
129
+ console.log(`▶ Domain : ${current.domain}`);
130
+ console.log(`▶ Locked At : ${current.locked_at}`);
131
+ console.log(`▶ Touchpoints : ${current.touchpoints.join(", ")}\n`);
132
+ } else {
133
+ console.log("ℹ No active feature session. All domain files accessible according to boundary rules.");
134
+ }
135
+ } else {
136
+ console.error(`Unknown feature subcommand: '${sub}'. Use 'status' or 'clear'.`);
137
+ process.exit(1);
138
+ }
139
+ break;
140
+ }
141
+
142
+ case "hook": {
143
+ await handleHookCommand(argv.slice(2));
144
+ break;
145
+ }
146
+
147
+ default: {
148
+ console.error(`[Septum] Unknown command: '${command}'`);
149
+ console.error("Run 'septum --help' for available commands.");
150
+ process.exit(1);
151
+ }
152
+ }
153
+ } catch (err) {
154
+ const message = err instanceof Error ? err.message : String(err);
155
+ console.error(`\x1b[31m[Septum Error]\x1b[0m ${message}`);
156
+ process.exit(1);
157
+ }
158
+ }
159
+
160
+ function printHelp(): void {
161
+ console.log(`
162
+ Septum — Deterministic Bounded-Context & Structural File Catalog
163
+ Version: v${SEPTUM_VERSION}
164
+
165
+ USAGE:
166
+ septum <command> [options]
167
+ septum [flags]
168
+
169
+ COMMANDS:
170
+ Catalog & Ingestion:
171
+ init Initialize configuration, gitignore, pre-commit hook, and catalog
172
+ Flags: -f, --force
173
+ ingest Full AST scan and synchronization to SQLite database
174
+ sync Incremental fast synchronization of modified files
175
+ Flags: --json
176
+
177
+ Structural Discovery:
178
+ query [domain] Query structural catalog for a domain or whole project
179
+ Flags: -a, --archetype <name>, --json
180
+ locate <query> Locate symbol, class, interface, method, or error source
181
+ Flags: -d, --domain <name>, --json
182
+ slice <route|intent> Trace end-to-end vertical execution slice for route/intent
183
+ Flags: --json
184
+
185
+ Boundary & Enforcement:
186
+ check Audit codebase for cross-domain boundary violations
187
+ Flags: --strict, --staged, --feature <name>
188
+ feature [status|clear] View or release active feature context session lock
189
+ hook [subhook] Internal pre-tool guardrail hook (e.g. pre-write)
190
+
191
+ Daemon & Protocol:
192
+ serve Start Model Context Protocol (MCP) server over stdio
193
+
194
+ GLOBAL FLAGS:
195
+ -h, --help Show this help message
196
+ -v, --version Show current version
197
+ --json Output formatted JSON metrics / results
198
+ `);
199
+ }
@@ -1,75 +1,75 @@
1
- export const SEPTUM_HOOKS_CONFIG = {
2
- "septum-boundary-guard": {
3
- "PreToolUse": [
4
- {
5
- "matcher": "write_to_file|replace_file_content",
6
- "hooks": [
7
- {
8
- "type": "command",
9
- "command": "sh -c 'HOOK=\"$(git rev-parse --show-toplevel 2>/dev/null)/.agents/hooks/septum-pre-write.sh\"; if [ -f \"$HOOK\" ]; then exec \"$HOOK\"; else exit 0; fi'",
10
- "timeout": 10,
11
- },
12
- ],
13
- },
14
- ],
15
- "PostToolUse": [
16
- {
17
- "matcher": "write_to_file|replace_file_content",
18
- "hooks": [
19
- {
20
- "type": "command",
21
- "command": "sh -c 'HOOK=\"$(git rev-parse --show-toplevel 2>/dev/null)/.agents/hooks/septum-post-write.sh\"; if [ -f \"$HOOK\" ]; then exec \"$HOOK\"; else exit 0; fi'",
22
- "timeout": 15,
23
- },
24
- ],
25
- },
26
- ],
27
- },
28
- };
29
-
30
- export const SEPTUM_PRE_WRITE_SCRIPT = `#!/usr/bin/env sh
31
- # Septum 3-Gate Boundary Guard Pre-Write Hook
32
- # Intercepts write_to_file and replace_file_content before disk mutation
33
-
34
- ROOT_DIR="$(git rev-parse --show-toplevel 2>/dev/null || pwd)"
35
- if [ ! -f "$ROOT_DIR/.septum/septum.db" ]; then
36
- exit 0
37
- fi
38
-
39
- # Delegate directly to Septum's active 3-gate hook engine
40
- if command -v bun >/dev/null 2>&1 && [ -f "$ROOT_DIR/bin/septum.ts" ]; then
41
- exec bun run "$ROOT_DIR/bin/septum.ts" hook pre-write
42
- elif command -v septum >/dev/null 2>&1; then
43
- exec septum hook pre-write
44
- elif [ -f "$ROOT_DIR/node_modules/.bin/septum" ]; then
45
- exec "$ROOT_DIR/node_modules/.bin/septum" hook pre-write
46
- elif command -v bunx >/dev/null 2>&1; then
47
- exec bunx septum hook pre-write
48
- fi
49
-
50
- exit 0
51
- `;
52
-
53
- export const SEPTUM_POST_WRITE_SCRIPT = `#!/usr/bin/env sh
54
- # Septum Automated Incremental Post-Write Hook
55
- # Syncs modified AST into SQLite SSOT after file mutations
56
-
57
- ROOT_DIR="$(git rev-parse --show-toplevel 2>/dev/null || pwd)"
58
- if [ ! -f "$ROOT_DIR/.septum/septum.db" ]; then
59
- exit 0
60
- fi
61
-
62
- # Trigger background incremental sync
63
- if command -v bun >/dev/null 2>&1 && [ -f "$ROOT_DIR/bin/septum.ts" ]; then
64
- bun run "$ROOT_DIR/bin/septum.ts" sync --json >/dev/null 2>&1 &
65
- elif command -v septum >/dev/null 2>&1; then
66
- septum sync --json >/dev/null 2>&1 &
67
- elif [ -f "$ROOT_DIR/node_modules/.bin/septum" ]; then
68
- "$ROOT_DIR/node_modules/.bin/septum" sync --json >/dev/null 2>&1 &
69
- elif command -v bunx >/dev/null 2>&1; then
70
- bunx septum sync --json >/dev/null 2>&1 &
71
- fi
72
-
73
- exit 0
74
- `;
75
-
1
+ export const SEPTUM_HOOKS_CONFIG = {
2
+ "septum-boundary-guard": {
3
+ "PreToolUse": [
4
+ {
5
+ "matcher": "write_to_file|replace_file_content",
6
+ "hooks": [
7
+ {
8
+ "type": "command",
9
+ "command": "sh -c 'HOOK=\"$(git rev-parse --show-toplevel 2>/dev/null)/.agents/hooks/septum-pre-write.sh\"; if [ -f \"$HOOK\" ]; then exec \"$HOOK\"; else exit 0; fi'",
10
+ "timeout": 10,
11
+ },
12
+ ],
13
+ },
14
+ ],
15
+ "PostToolUse": [
16
+ {
17
+ "matcher": "write_to_file|replace_file_content",
18
+ "hooks": [
19
+ {
20
+ "type": "command",
21
+ "command": "sh -c 'HOOK=\"$(git rev-parse --show-toplevel 2>/dev/null)/.agents/hooks/septum-post-write.sh\"; if [ -f \"$HOOK\" ]; then exec \"$HOOK\"; else exit 0; fi'",
22
+ "timeout": 15,
23
+ },
24
+ ],
25
+ },
26
+ ],
27
+ },
28
+ };
29
+
30
+ export const SEPTUM_PRE_WRITE_SCRIPT = `#!/usr/bin/env sh
31
+ # Septum 3-Gate Boundary Guard Pre-Write Hook
32
+ # Intercepts write_to_file and replace_file_content before disk mutation
33
+
34
+ ROOT_DIR="$(git rev-parse --show-toplevel 2>/dev/null || pwd)"
35
+ if [ ! -f "$ROOT_DIR/.septum/septum.db" ]; then
36
+ exit 0
37
+ fi
38
+
39
+ # Delegate directly to Septum's active 3-gate hook engine
40
+ if command -v bun >/dev/null 2>&1 && [ -f "$ROOT_DIR/bin/septum.ts" ]; then
41
+ exec bun run "$ROOT_DIR/bin/septum.ts" hook pre-write
42
+ elif command -v septum >/dev/null 2>&1; then
43
+ exec septum hook pre-write
44
+ elif [ -f "$ROOT_DIR/node_modules/.bin/septum" ]; then
45
+ exec "$ROOT_DIR/node_modules/.bin/septum" hook pre-write
46
+ elif command -v bunx >/dev/null 2>&1; then
47
+ exec bunx septum hook pre-write
48
+ fi
49
+
50
+ exit 0
51
+ `;
52
+
53
+ export const SEPTUM_POST_WRITE_SCRIPT = `#!/usr/bin/env sh
54
+ # Septum Automated Incremental Post-Write Hook
55
+ # Syncs modified AST into SQLite SSOT after file mutations
56
+
57
+ ROOT_DIR="$(git rev-parse --show-toplevel 2>/dev/null || pwd)"
58
+ if [ ! -f "$ROOT_DIR/.septum/septum.db" ]; then
59
+ exit 0
60
+ fi
61
+
62
+ # Trigger background incremental sync
63
+ if command -v bun >/dev/null 2>&1 && [ -f "$ROOT_DIR/bin/septum.ts" ]; then
64
+ bun run "$ROOT_DIR/bin/septum.ts" sync --json >/dev/null 2>&1 &
65
+ elif command -v septum >/dev/null 2>&1; then
66
+ septum sync --json >/dev/null 2>&1 &
67
+ elif [ -f "$ROOT_DIR/node_modules/.bin/septum" ]; then
68
+ "$ROOT_DIR/node_modules/.bin/septum" sync --json >/dev/null 2>&1 &
69
+ elif command -v bunx >/dev/null 2>&1; then
70
+ bunx septum sync --json >/dev/null 2>&1 &
71
+ fi
72
+
73
+ exit 0
74
+ `;
75
+
@@ -1,38 +1,38 @@
1
- export const SEPTUM_RULES_TEMPLATE = `# Septum Bounded-Context & Anti-Poisoning Partition Rules
2
-
3
- > **Prinsip Utama:** Proyek ini menggunakan **Septum** untuk menegakkan batasan arsitektur (bounded-context) secara deterministik. Setiap AI Coding Agent wajib mematuhi aturan batas domain dan touchpoint berikut.
4
-
5
- ---
6
-
7
- ## 1. Single Source of Truth (SSOT) via Septum MCP
8
-
9
- Sebelum menulis atau mengedit file backend/domain:
10
- 1. **Dilarang Menebak Kontrak Domain:**
11
- Gunakan tool MCP \`septum_get_domain_catalog(domain: "...")\` untuk memeriksa file, arketipe, dan signature publik yang sah di dalam domain tersebut.
12
- 2. **Kunci Scope pada Fitur Aktif:**
13
- Jika sedang mengerjakan fitur spesifik yang terdaftar di katalog Septum, panggil \`septum_get_feature_context(feature: "...")\`.
14
- * **Wajib patuhi \`allowed_touchpoints\`:** Jangan menyentuh atau memodifikasi file di luar daftar yang diizinkan untuk fitur tersebut.
15
- * **Wajib gunakan ulang \`reuse_symbols\`:** Jangan membuat fungsi atau helper duplikat jika simbol tersebut sudah terdaftar di \`reuse_symbols\`.
16
-
17
- ---
18
-
19
- ## 2. Pre-Flight Boundary Check Sebelum Menulis Kode
20
-
21
- Sebelum mengeksekusi penulisan file (\`write_to_file\` atau \`replace_file_content\`):
22
- 1. Panggil tool MCP:
23
- \`\`\`json
24
- septum_check_boundary({
25
- "file_path": "path/ke/file.ts",
26
- "proposed_imports": ["target_import_statement"],
27
- "feature_key": "nama_fitur_opsional"
28
- })
29
- \`\`\`
30
- 2. **Rejection Handling:** Jika Septum mengembalikan status \`rejected\` (\`forbidden_dependency\`, \`disallowed_dependency\`, atau \`touchpoint_violation\`), **BATALKAN** rencana penulisan tersebut dan cari rute arsitektur yang sah (misal melalui Interface/Shared-Kernel yang diizinkan).
31
-
32
- ---
33
-
34
- ## 3. Anti Local Scope Myopia
35
-
36
- * Dilarang menghapus fungsi publik atau mengubah signature class hanya karena fungsi tersebut tidak terlihat dipanggil di file lokal yang sedang diedit.
37
- * Pastikan seluruh dependensi inbound/outbound mematuhi batasan domain yang terdaftar di database Septum (\`.septum/septum.db\`).
38
- `;
1
+ export const SEPTUM_RULES_TEMPLATE = `# Septum Bounded-Context & Anti-Poisoning Partition Rules
2
+
3
+ > **Prinsip Utama:** Proyek ini menggunakan **Septum** untuk menegakkan batasan arsitektur (bounded-context) secara deterministik. Setiap AI Coding Agent wajib mematuhi aturan batas domain dan touchpoint berikut.
4
+
5
+ ---
6
+
7
+ ## 1. Single Source of Truth (SSOT) via Septum MCP
8
+
9
+ Sebelum menulis atau mengedit file backend/domain:
10
+ 1. **Dilarang Menebak Kontrak Domain:**
11
+ Gunakan tool MCP \`septum_get_domain_catalog(domain: "...")\` untuk memeriksa file, arketipe, dan signature publik yang sah di dalam domain tersebut.
12
+ 2. **Kunci Scope pada Fitur Aktif:**
13
+ Jika sedang mengerjakan fitur spesifik yang terdaftar di katalog Septum, panggil \`septum_get_feature_context(feature: "...")\`.
14
+ * **Wajib patuhi \`allowed_touchpoints\`:** Jangan menyentuh atau memodifikasi file di luar daftar yang diizinkan untuk fitur tersebut.
15
+ * **Wajib gunakan ulang \`reuse_symbols\`:** Jangan membuat fungsi atau helper duplikat jika simbol tersebut sudah terdaftar di \`reuse_symbols\`.
16
+
17
+ ---
18
+
19
+ ## 2. Pre-Flight Boundary Check Sebelum Menulis Kode
20
+
21
+ Sebelum mengeksekusi penulisan file (\`write_to_file\` atau \`replace_file_content\`):
22
+ 1. Panggil tool MCP:
23
+ \`\`\`json
24
+ septum_check_boundary({
25
+ "file_path": "path/ke/file.ts",
26
+ "proposed_imports": ["target_import_statement"],
27
+ "feature_key": "nama_fitur_opsional"
28
+ })
29
+ \`\`\`
30
+ 2. **Rejection Handling:** Jika Septum mengembalikan status \`rejected\` (\`forbidden_dependency\`, \`disallowed_dependency\`, atau \`touchpoint_violation\`), **BATALKAN** rencana penulisan tersebut dan cari rute arsitektur yang sah (misal melalui Interface/Shared-Kernel yang diizinkan).
31
+
32
+ ---
33
+
34
+ ## 3. Anti Local Scope Myopia
35
+
36
+ * Dilarang menghapus fungsi publik atau mengubah signature class hanya karena fungsi tersebut tidak terlihat dipanggil di file lokal yang sedang diedit.
37
+ * Pastikan seluruh dependensi inbound/outbound mematuhi batasan domain yang terdaftar di database Septum (\`.septum/septum.db\`).
38
+ `;