sdlc-agent-4-enterprise-server 1.53.3 → 1.53.12

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/README.md CHANGED
@@ -6,7 +6,7 @@
6
6
  </p>
7
7
 
8
8
  <p align="center">
9
- <img src="https://img.shields.io/badge/version-1.53.3-blue?style=for-the-badge" alt="Version">
9
+ <img src="https://img.shields.io/badge/version-1.53.4-blue?style=for-the-badge" alt="Version">
10
10
  <img src="https://img.shields.io/badge/tools-66+-teal?style=for-the-badge" alt="Tools">
11
11
  <img src="https://img.shields.io/badge/node-%3E%3D18-green?style=for-the-badge" alt="Node">
12
12
  </p>
@@ -0,0 +1,192 @@
1
+ /**
2
+ * Unified config schema + shared config constants (BR-18 split from index.ts).
3
+ * The Zod schema is the single source of truth for the backend config shape;
4
+ * index.ts assembles the raw object and parses it through this schema.
5
+ */
6
+ import { z } from 'zod';
7
+ export declare const DEFAULT_EXCLUDE: string[];
8
+ export declare const DEFAULT_EXTENSIONS: string[];
9
+ export declare const UnifiedConfigSchema: z.ZodObject<{
10
+ port: z.ZodDefault<z.ZodNumber>;
11
+ host: z.ZodDefault<z.ZodString>;
12
+ onnxModelPath: z.ZodDefault<z.ZodString>;
13
+ embeddingModelId: z.ZodDefault<z.ZodString>;
14
+ embeddingCacheDir: z.ZodString;
15
+ embeddingQuantized: z.ZodDefault<z.ZodBoolean>;
16
+ logLevel: z.ZodDefault<z.ZodEnum<["debug", "info", "warn", "error"]>>;
17
+ viewerPort: z.ZodDefault<z.ZodNumber>;
18
+ watchEnabled: z.ZodDefault<z.ZodBoolean>;
19
+ watchDebounceMs: z.ZodDefault<z.ZodNumber>;
20
+ ollamaUrl: z.ZodDefault<z.ZodNullable<z.ZodString>>;
21
+ ollamaModel: z.ZodDefault<z.ZodString>;
22
+ maxFileSize: z.ZodDefault<z.ZodNumber>;
23
+ projectId: z.ZodDefault<z.ZodString>;
24
+ workspace: z.ZodString;
25
+ indexTempDir: z.ZodString;
26
+ dbPath: z.ZodString;
27
+ configPath: z.ZodString;
28
+ dataDir: z.ZodString;
29
+ sqliteDbPath: z.ZodString;
30
+ orchestrationConfigPath: z.ZodString;
31
+ excludePatterns: z.ZodArray<z.ZodString, "many">;
32
+ includeExtensions: z.ZodArray<z.ZodString, "many">;
33
+ sandbox: z.ZodObject<{
34
+ defaultMode: z.ZodDefault<z.ZodEnum<["docker", "local"]>>;
35
+ fallbackToLocal: z.ZodDefault<z.ZodBoolean>;
36
+ maxSessions: z.ZodDefault<z.ZodNumber>;
37
+ defaultTtl: z.ZodDefault<z.ZodNumber>;
38
+ defaultImage: z.ZodDefault<z.ZodString>;
39
+ reaperIntervalMs: z.ZodDefault<z.ZodNumber>;
40
+ maxOutputBytes: z.ZodDefault<z.ZodNumber>;
41
+ commandTimeoutDefault: z.ZodDefault<z.ZodNumber>;
42
+ commandTimeoutMax: z.ZodDefault<z.ZodNumber>;
43
+ mountExcludePatterns: z.ZodDefault<z.ZodArray<z.ZodString, "many">>;
44
+ defaultResources: z.ZodDefault<z.ZodObject<{
45
+ memory: z.ZodDefault<z.ZodString>;
46
+ cpu: z.ZodDefault<z.ZodString>;
47
+ disk: z.ZodDefault<z.ZodString>;
48
+ pidsLimit: z.ZodDefault<z.ZodNumber>;
49
+ }, "strip", z.ZodTypeAny, {
50
+ memory: string;
51
+ cpu: string;
52
+ disk: string;
53
+ pidsLimit: number;
54
+ }, {
55
+ memory?: string | undefined;
56
+ cpu?: string | undefined;
57
+ disk?: string | undefined;
58
+ pidsLimit?: number | undefined;
59
+ }>>;
60
+ dockerSocket: z.ZodOptional<z.ZodString>;
61
+ }, "strip", z.ZodTypeAny, {
62
+ defaultMode: "docker" | "local";
63
+ fallbackToLocal: boolean;
64
+ maxSessions: number;
65
+ defaultTtl: number;
66
+ defaultImage: string;
67
+ reaperIntervalMs: number;
68
+ maxOutputBytes: number;
69
+ commandTimeoutDefault: number;
70
+ commandTimeoutMax: number;
71
+ mountExcludePatterns: string[];
72
+ defaultResources: {
73
+ memory: string;
74
+ cpu: string;
75
+ disk: string;
76
+ pidsLimit: number;
77
+ };
78
+ dockerSocket?: string | undefined;
79
+ }, {
80
+ defaultMode?: "docker" | "local" | undefined;
81
+ fallbackToLocal?: boolean | undefined;
82
+ maxSessions?: number | undefined;
83
+ defaultTtl?: number | undefined;
84
+ defaultImage?: string | undefined;
85
+ reaperIntervalMs?: number | undefined;
86
+ maxOutputBytes?: number | undefined;
87
+ commandTimeoutDefault?: number | undefined;
88
+ commandTimeoutMax?: number | undefined;
89
+ mountExcludePatterns?: string[] | undefined;
90
+ defaultResources?: {
91
+ memory?: string | undefined;
92
+ cpu?: string | undefined;
93
+ disk?: string | undefined;
94
+ pidsLimit?: number | undefined;
95
+ } | undefined;
96
+ dockerSocket?: string | undefined;
97
+ }>;
98
+ entra: z.ZodType<import("./EntraConfig.js").EntraSurface, z.ZodTypeDef, unknown>;
99
+ }, "strip", z.ZodTypeAny, {
100
+ entra: import("./EntraConfig.js").EntraSurface;
101
+ host: string;
102
+ port: number;
103
+ onnxModelPath: string;
104
+ embeddingModelId: string;
105
+ embeddingCacheDir: string;
106
+ embeddingQuantized: boolean;
107
+ logLevel: "error" | "warn" | "info" | "debug";
108
+ viewerPort: number;
109
+ watchEnabled: boolean;
110
+ watchDebounceMs: number;
111
+ ollamaUrl: string | null;
112
+ ollamaModel: string;
113
+ maxFileSize: number;
114
+ projectId: string;
115
+ workspace: string;
116
+ indexTempDir: string;
117
+ dbPath: string;
118
+ configPath: string;
119
+ dataDir: string;
120
+ sqliteDbPath: string;
121
+ orchestrationConfigPath: string;
122
+ excludePatterns: string[];
123
+ includeExtensions: string[];
124
+ sandbox: {
125
+ defaultMode: "docker" | "local";
126
+ fallbackToLocal: boolean;
127
+ maxSessions: number;
128
+ defaultTtl: number;
129
+ defaultImage: string;
130
+ reaperIntervalMs: number;
131
+ maxOutputBytes: number;
132
+ commandTimeoutDefault: number;
133
+ commandTimeoutMax: number;
134
+ mountExcludePatterns: string[];
135
+ defaultResources: {
136
+ memory: string;
137
+ cpu: string;
138
+ disk: string;
139
+ pidsLimit: number;
140
+ };
141
+ dockerSocket?: string | undefined;
142
+ };
143
+ }, {
144
+ embeddingCacheDir: string;
145
+ workspace: string;
146
+ indexTempDir: string;
147
+ dbPath: string;
148
+ configPath: string;
149
+ dataDir: string;
150
+ sqliteDbPath: string;
151
+ orchestrationConfigPath: string;
152
+ excludePatterns: string[];
153
+ includeExtensions: string[];
154
+ sandbox: {
155
+ defaultMode?: "docker" | "local" | undefined;
156
+ fallbackToLocal?: boolean | undefined;
157
+ maxSessions?: number | undefined;
158
+ defaultTtl?: number | undefined;
159
+ defaultImage?: string | undefined;
160
+ reaperIntervalMs?: number | undefined;
161
+ maxOutputBytes?: number | undefined;
162
+ commandTimeoutDefault?: number | undefined;
163
+ commandTimeoutMax?: number | undefined;
164
+ mountExcludePatterns?: string[] | undefined;
165
+ defaultResources?: {
166
+ memory?: string | undefined;
167
+ cpu?: string | undefined;
168
+ disk?: string | undefined;
169
+ pidsLimit?: number | undefined;
170
+ } | undefined;
171
+ dockerSocket?: string | undefined;
172
+ };
173
+ entra?: unknown;
174
+ host?: string | undefined;
175
+ port?: number | undefined;
176
+ onnxModelPath?: string | undefined;
177
+ embeddingModelId?: string | undefined;
178
+ embeddingQuantized?: boolean | undefined;
179
+ logLevel?: "error" | "warn" | "info" | "debug" | undefined;
180
+ viewerPort?: number | undefined;
181
+ watchEnabled?: boolean | undefined;
182
+ watchDebounceMs?: number | undefined;
183
+ ollamaUrl?: string | null | undefined;
184
+ ollamaModel?: string | undefined;
185
+ maxFileSize?: number | undefined;
186
+ projectId?: string | undefined;
187
+ }>;
188
+ export type UnifiedConfig = z.infer<typeof UnifiedConfigSchema>;
189
+ export type AppConfig = UnifiedConfig;
190
+ export type BackendConfig = UnifiedConfig;
191
+ export declare function envBool(key: string, fallback: boolean): boolean;
192
+ export declare function envInt(key: string, fallback: number): number;
@@ -0,0 +1,70 @@
1
+ /**
2
+ * Unified config schema + shared config constants (BR-18 split from index.ts).
3
+ * The Zod schema is the single source of truth for the backend config shape;
4
+ * index.ts assembles the raw object and parses it through this schema.
5
+ */
6
+ import { z } from 'zod';
7
+ import { SandboxConfigSchema } from './SandboxConfig.js';
8
+ import { EntraSurfaceSchema } from './EntraConfig.js';
9
+ export const DEFAULT_EXCLUDE = [
10
+ 'node_modules', '.git', 'dist', 'build', '.gradle',
11
+ '.idea', '.vscode', '__pycache__', '.venv', 'target',
12
+ '.code-intel', 'coverage', '.next', '.nuxt',
13
+ 'rules',
14
+ '.pega-cache',
15
+ ];
16
+ export const DEFAULT_EXTENSIONS = [
17
+ '.ts', '.tsx', '.js', '.jsx', '.kt', '.java', '.py',
18
+ '.go', '.rs', '.c', '.cpp', '.h', '.hpp', '.cs',
19
+ '.rb', '.php', '.swift', '.scala', '.sql', '.sh',
20
+ '.yaml', '.yml', '.json', '.toml', '.gradle.kts',
21
+ '.cls', '.trigger',
22
+ // ---- SA4E-223: new Salesforce simple extensions (Gate 2) ----
23
+ '.apex', '.soql', '.page', '.component', '.cmp', '.app', '.evt', '.intf', '.tokens',
24
+ // ---- SA4E-225: un-skip PowerShell ----
25
+ '.ps1',
26
+ ];
27
+ export const UnifiedConfigSchema = z.object({
28
+ port: z.number().min(1024).max(65535).default(48721),
29
+ host: z.string().default('0.0.0.0'),
30
+ // Legacy/deprecated — nothing loads a bare .onnx file anymore; kept for
31
+ // backward-compatible admin config output. See embeddingModelId below.
32
+ onnxModelPath: z.string().default('models/model.onnx'),
33
+ // SA4E-44 / AD-6 — real ONNX embeddings via transformers.js (EmbeddingService).
34
+ embeddingModelId: z.string().default('Xenova/paraphrase-multilingual-MiniLM-L12-v2'),
35
+ embeddingCacheDir: z.string(),
36
+ embeddingQuantized: z.boolean().default(true),
37
+ logLevel: z.enum(['debug', 'info', 'warn', 'error']).default('info'),
38
+ viewerPort: z.number().default(3202),
39
+ watchEnabled: z.boolean().default(true),
40
+ watchDebounceMs: z.number().default(500),
41
+ ollamaUrl: z.string().nullable().default(null),
42
+ ollamaModel: z.string().default('nomic-embed-text'),
43
+ maxFileSize: z.number().default(512_000),
44
+ projectId: z.string().default('default'),
45
+ workspace: z.string(),
46
+ indexTempDir: z.string(),
47
+ dbPath: z.string(),
48
+ configPath: z.string(),
49
+ dataDir: z.string(),
50
+ sqliteDbPath: z.string(),
51
+ orchestrationConfigPath: z.string(),
52
+ excludePatterns: z.array(z.string()),
53
+ includeExtensions: z.array(z.string()),
54
+ sandbox: SandboxConfigSchema,
55
+ entra: EntraSurfaceSchema, // SA4E-264 — Entra ID SSO surface (gate: SSO_ENABLED)
56
+ });
57
+ export function envBool(key, fallback) {
58
+ const val = process.env[key];
59
+ if (val === undefined)
60
+ return fallback;
61
+ return val === '1' || val.toLowerCase() === 'true';
62
+ }
63
+ export function envInt(key, fallback) {
64
+ const val = process.env[key];
65
+ if (val === undefined)
66
+ return fallback;
67
+ const parsed = parseInt(val, 10);
68
+ return isNaN(parsed) ? fallback : parsed;
69
+ }
70
+ //# sourceMappingURL=schema.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schema.js","sourceRoot":"","sources":["../../src/config/schema.ts"],"names":[],"mappings":"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"}
@@ -2,7 +2,7 @@
2
2
  * SA4E-261 Unified extension whitelist — single source of truth.
3
3
  * Used by backend resolver and contract test.
4
4
  */
5
- export declare const UNIFIED_EXTENSIONS: readonly ["ts", "tsx", "js", "jsx", "kt", "java", "py", "go", "rs", "c", "cpp", "h", "hpp", "cs", "php", "rb", "scala", "swift", "cls", "trigger", "apex", "soql", "page", "component", "cmp", "app", "evt", "intf", "tokens", "pega", "html", "jsp", "xml", "sql", "properties", "yml", "yaml", "css", "ps1"];
5
+ export declare const UNIFIED_EXTENSIONS: readonly ["ts", "tsx", "js", "jsx", "kt", "java", "py", "go", "rs", "c", "cpp", "h", "hpp", "cs", "php", "rb", "scala", "swift", "cls", "trigger", "apex", "soql", "page", "component", "cmp", "app", "evt", "intf", "tokens", "html", "jsp", "xml", "sql", "properties", "yml", "yaml", "css", "ps1"];
6
6
  export type UnifiedExtension = typeof UNIFIED_EXTENSIONS[number];
7
7
  /**
8
8
  * Extension list with leading dot for file matching.
@@ -7,7 +7,7 @@ export const UNIFIED_EXTENSIONS = [
7
7
  'kt', 'java', 'py', 'go', 'rs',
8
8
  'c', 'cpp', 'h', 'hpp',
9
9
  'cs', 'php', 'rb', 'scala', 'swift',
10
- 'cls', 'trigger', 'apex', 'soql', 'page', 'component', 'cmp', 'app', 'evt', 'intf', 'tokens', 'pega',
10
+ 'cls', 'trigger', 'apex', 'soql', 'page', 'component', 'cmp', 'app', 'evt', 'intf', 'tokens',
11
11
  'html', 'jsp', 'xml', 'sql', 'properties', 'yml', 'yaml', 'css',
12
12
  'ps1'
13
13
  ];
@@ -1 +1 @@
1
- {"version":3,"file":"unified-extensions.js","sourceRoot":"","sources":["../../src/config/unified-extensions.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG;IAChC,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK;IACxB,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI;IAC9B,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE,KAAK;IACtB,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO;IACnC,KAAK,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM;IACpG,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,YAAY,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK;IAC/D,KAAK;CACG,CAAC;AAIX;;GAEG;AACH,MAAM,CAAC,MAAM,2BAA2B,GAAG,kBAAkB,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC"}
1
+ {"version":3,"file":"unified-extensions.js","sourceRoot":"","sources":["../../src/config/unified-extensions.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG;IAChC,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK;IACxB,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI;IAC9B,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE,KAAK;IACtB,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO;IACnC,KAAK,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ;IAC5F,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,YAAY,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK;IAC/D,KAAK;CACG,CAAC;AAIX;;GAEG;AACH,MAAM,CAAC,MAAM,2BAA2B,GAAG,kBAAkB,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC"}
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Language detection for the file scanner (extension maps + compound suffixes).
3
+ * Extracted from file-scanner.ts (BR-18) — no behavior change.
4
+ */
5
+ export declare const EXTENSION_LANGUAGE_MAP: Record<string, string>;
6
+ /**
7
+ * SA4E-223 — Single source of truth for Salesforce `*-meta.xml` compound suffixes.
8
+ * Used by detectLanguage() so *.xml files are routed to the `salesforce-meta` parser.
9
+ * (Compound-suffix files have ext === '.xml' which is NOT in includeExtensions, but
10
+ * processFile/async-file-scanner exempt `language === 'salesforce-meta'`.)
11
+ */
12
+ export declare const SALESFORCE_META_SUFFIXES: string[];
13
+ /** Detect language from file extension — supports compound extensions. */
14
+ export declare function detectLanguage(filePath: string): string | null;
15
+ export declare function getExtension(filePath: string): string;
@@ -0,0 +1,74 @@
1
+ /**
2
+ * Language detection for the file scanner (extension maps + compound suffixes).
3
+ * Extracted from file-scanner.ts (BR-18) — no behavior change.
4
+ */
5
+ import * as path from 'path';
6
+ export const EXTENSION_LANGUAGE_MAP = {
7
+ '.ts': 'typescript', '.tsx': 'typescript',
8
+ '.js': 'javascript', '.jsx': 'javascript',
9
+ '.kt': 'kotlin', '.kts': 'kotlin',
10
+ '.java': 'java',
11
+ '.py': 'python',
12
+ '.go': 'go',
13
+ '.rs': 'rust',
14
+ '.c': 'c', '.h': 'c',
15
+ '.cpp': 'cpp', '.hpp': 'cpp', '.cc': 'cpp', '.cxx': 'cpp',
16
+ '.cs': 'csharp',
17
+ '.rb': 'ruby',
18
+ '.php': 'php',
19
+ '.swift': 'swift',
20
+ '.scala': 'scala',
21
+ '.sql': 'sql',
22
+ '.sh': 'bash',
23
+ '.yaml': 'yaml', '.yml': 'yaml',
24
+ '.json': 'json',
25
+ '.toml': 'toml',
26
+ '.cls': 'apex',
27
+ '.trigger': 'apex',
28
+ // ---- SA4E-223: new Salesforce simple extensions ----
29
+ '.apex': 'apex',
30
+ '.soql': 'apex',
31
+ '.page': 'visualforce',
32
+ '.component': 'visualforce',
33
+ '.cmp': 'aura',
34
+ '.app': 'aura',
35
+ '.evt': 'aura',
36
+ '.intf': 'aura',
37
+ '.tokens': 'aura',
38
+ // ---- SA4E-... LWC HTML template support ----
39
+ '.html': 'lwc-html',
40
+ // ---- SA4E-261: Tier B extensions for unified whitelist ----
41
+ '.jsp': 'jsp',
42
+ '.xml': 'xml',
43
+ '.properties': 'properties',
44
+ '.css': 'css',
45
+ '.ps1': 'powershell',
46
+ };
47
+ /**
48
+ * SA4E-223 — Single source of truth for Salesforce `*-meta.xml` compound suffixes.
49
+ * Used by detectLanguage() so *.xml files are routed to the `salesforce-meta` parser.
50
+ * (Compound-suffix files have ext === '.xml' which is NOT in includeExtensions, but
51
+ * processFile/async-file-scanner exempt `language === 'salesforce-meta'`.)
52
+ */
53
+ export const SALESFORCE_META_SUFFIXES = [
54
+ '.flow-meta.xml', '.object-meta.xml', '.field-meta.xml', '.js-meta.xml', '.component-meta.xml',
55
+ '.flexipage-meta.xml', '.permissionset-meta.xml', '.profile-meta.xml', '.labels-meta.xml',
56
+ '.tab-meta.xml', '.layout-meta.xml', '.report-meta.xml', '.dashboard-meta.xml',
57
+ '.site-meta.xml', '.resource-meta.xml', '.email-meta.xml', '.testsuite-meta.xml',
58
+ ];
59
+ /** Detect language from file extension — supports compound extensions. */
60
+ export function detectLanguage(filePath) {
61
+ // Check compound extensions first (Salesforce metadata)
62
+ const lowerPath = filePath.toLowerCase().replace(/\\/g, '/');
63
+ if (SALESFORCE_META_SUFFIXES.some(s => lowerPath.endsWith(s))) {
64
+ return 'salesforce-meta';
65
+ }
66
+ const ext = getExtension(filePath);
67
+ return EXTENSION_LANGUAGE_MAP[ext] ?? null;
68
+ }
69
+ export function getExtension(filePath) {
70
+ if (filePath.endsWith('.gradle.kts'))
71
+ return '.kts';
72
+ return path.extname(filePath).toLowerCase();
73
+ }
74
+ //# sourceMappingURL=languages.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"languages.js","sourceRoot":"","sources":["../../../../src/engine/indexer/file-scanner/languages.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAE7B,MAAM,CAAC,MAAM,sBAAsB,GAA2B;IAC5D,KAAK,EAAE,YAAY,EAAE,MAAM,EAAE,YAAY;IACzC,KAAK,EAAE,YAAY,EAAE,MAAM,EAAE,YAAY;IACzC,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,QAAQ;IACjC,OAAO,EAAE,MAAM;IACf,KAAK,EAAE,QAAQ;IACf,KAAK,EAAE,IAAI;IACX,KAAK,EAAE,MAAM;IACb,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG;IACpB,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK;IACzD,KAAK,EAAE,QAAQ;IACf,KAAK,EAAE,MAAM;IACb,MAAM,EAAE,KAAK;IACb,QAAQ,EAAE,OAAO;IACjB,QAAQ,EAAE,OAAO;IACjB,MAAM,EAAE,KAAK;IACb,KAAK,EAAE,MAAM;IACb,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;IAC/B,OAAO,EAAE,MAAM;IACf,OAAO,EAAE,MAAM;IACf,MAAM,EAAE,MAAM;IACd,UAAU,EAAE,MAAM;IAClB,uDAAuD;IACvD,OAAO,EAAE,MAAM;IACf,OAAO,EAAE,MAAM;IACf,OAAO,EAAE,aAAa;IACtB,YAAY,EAAE,aAAa;IAC3B,MAAM,EAAE,MAAM;IACd,MAAM,EAAE,MAAM;IACd,MAAM,EAAE,MAAM;IACd,OAAO,EAAE,MAAM;IACf,SAAS,EAAE,MAAM;IACjB,+CAA+C;IAC/C,OAAO,EAAE,UAAU;IACnB,8DAA8D;IAC9D,MAAM,EAAE,KAAK;IACb,MAAM,EAAE,KAAK;IACb,aAAa,EAAE,YAAY;IAC3B,MAAM,EAAE,KAAK;IACb,MAAM,EAAE,YAAY;CACrB,CAAC;AAEF;;;;;GAKG;AACH,MAAM,CAAC,MAAM,wBAAwB,GAAa;IAChD,gBAAgB,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,cAAc,EAAE,qBAAqB;IAC9F,qBAAqB,EAAE,yBAAyB,EAAE,mBAAmB,EAAE,kBAAkB;IACzF,eAAe,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,qBAAqB;IAC9E,gBAAgB,EAAE,oBAAoB,EAAE,iBAAiB,EAAE,qBAAqB;CACjF,CAAC;AAEF,0EAA0E;AAC1E,MAAM,UAAU,cAAc,CAAC,QAAgB;IAC7C,wDAAwD;IACxD,MAAM,SAAS,GAAG,QAAQ,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;IAC7D,IAAI,wBAAwB,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QAC9D,OAAO,iBAAiB,CAAC;IAC3B,CAAC;IAED,MAAM,GAAG,GAAG,YAAY,CAAC,QAAQ,CAAC,CAAC;IACnC,OAAO,sBAAsB,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC;AAC7C,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,QAAgB;IAC3C,IAAI,QAAQ,CAAC,QAAQ,CAAC,aAAa,CAAC;QAAE,OAAO,MAAM,CAAC;IACpD,OAAO,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,WAAW,EAAE,CAAC;AAC9C,CAAC"}
@@ -5,6 +5,8 @@ const BASE_EXCLUDES = ['.git', '.svn', '.hg'];
5
5
  const FALLBACK_EXCLUDES = [
6
6
  'node_modules', '.git', 'dist', 'build', '.gradle',
7
7
  '.idea', '.vscode', '__pycache__', '.venv', 'target',
8
+ 'rules',
9
+ '.pega-cache',
8
10
  ];
9
11
  /** Fallback extensions aligned with unified whitelist (SA4E-261) */
10
12
  export const FALLBACK_EXTENSIONS = [...UNIFIED_EXTENSIONS_WITH_DOT];
@@ -1 +1 @@
1
- {"version":3,"file":"resolver.js","sourceRoot":"","sources":["../../../../src/engine/indexer/project-type/resolver.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,2BAA2B,EAAE,MAAM,uCAAuC,CAAC;AAEpF,8DAA8D;AAC9D,MAAM,aAAa,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,CAAC,CAAC;AAE9C,0EAA0E;AAC1E,MAAM,iBAAiB,GAAG;IACxB,cAAc,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,SAAS;IAClD,OAAO,EAAE,SAAS,EAAE,aAAa,EAAE,OAAO,EAAE,QAAQ;CACrD,CAAC;AAEF,oEAAoE;AACpE,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,GAAG,2BAA2B,CAAC,CAAC;AAEpE;;;GAGG;AACH,MAAM,OAAO,wBAAwB;IAEnC,oDAAoD;IACpD,OAAO,CAAC,SAA0B;QAChC,OAAO;YACL,WAAW,EAAE,SAAS,CAAC,YAAY;YACnC,eAAe,EAAE,CAAC,GAAG,aAAa,EAAE,GAAG,SAAS,CAAC,gBAAgB,CAAC;YAClE,iBAAiB,EAAE,SAAS,CAAC,UAAU;YACvC,SAAS,EAAE,SAAS,CAAC,UAAU;YAC/B,SAAS,EAAE,cAAc;SAC1B,CAAC;IACJ,CAAC;IAED,yEAAyE;IACzE,WAAW;QACT,OAAO;YACL,WAAW,EAAE,EAAE;YACf,eAAe,EAAE,iBAAiB;YAClC,iBAAiB,EAAE,mBAAmB;YACtC,SAAS,EAAE,EAAE;YACb,SAAS,EAAE,SAAS;SACrB,CAAC;IACJ,CAAC;CACF"}
1
+ {"version":3,"file":"resolver.js","sourceRoot":"","sources":["../../../../src/engine/indexer/project-type/resolver.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,2BAA2B,EAAE,MAAM,uCAAuC,CAAC;AAEpF,8DAA8D;AAC9D,MAAM,aAAa,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,CAAC,CAAC;AAE9C,0EAA0E;AAC1E,MAAM,iBAAiB,GAAG;IACxB,cAAc,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,SAAS;IAClD,OAAO,EAAE,SAAS,EAAE,aAAa,EAAE,OAAO,EAAE,QAAQ;IACpD,OAAO;IACP,aAAa;CACd,CAAC;AAEF,oEAAoE;AACpE,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,GAAG,2BAA2B,CAAC,CAAC;AAEpE;;;GAGG;AACH,MAAM,OAAO,wBAAwB;IAEnC,oDAAoD;IACpD,OAAO,CAAC,SAA0B;QAChC,OAAO;YACL,WAAW,EAAE,SAAS,CAAC,YAAY;YACnC,eAAe,EAAE,CAAC,GAAG,aAAa,EAAE,GAAG,SAAS,CAAC,gBAAgB,CAAC;YAClE,iBAAiB,EAAE,SAAS,CAAC,UAAU;YACvC,SAAS,EAAE,SAAS,CAAC,UAAU;YAC/B,SAAS,EAAE,cAAc;SAC1B,CAAC;IACJ,CAAC;IAED,yEAAyE;IACzE,WAAW;QACT,OAAO;YACL,WAAW,EAAE,EAAE;YACf,eAAe,EAAE,iBAAiB;YAClC,iBAAiB,EAAE,mBAAmB;YACtC,SAAS,EAAE,EAAE;YACb,SAAS,EAAE,SAAS;SACrB,CAAC;IACJ,CAAC;CACF"}
@@ -12,6 +12,7 @@ import { createProjectContext } from '../../modules/memory/ProjectContext.js';
12
12
  import { SessionService } from '../services/SessionService.js';
13
13
  import { getEntraVerifier, isEntraToken, tryEntraVerification, validateEntraAuthConfig } from './verifiers/entra-auth.js';
14
14
  import { getJwtSecret } from '../../admin/db/jwt.js';
15
+ import { getDbAdapter } from '../../admin/admin-db.js';
15
16
  const REQUIRE_AUTH = process.env.CODE_INTEL_REQUIRE_AUTH === 'true';
16
17
  const TOKEN_SECRET = process.env.KB_TOKEN_SECRET || '';
17
18
  /** Validate startup config. */
@@ -25,6 +26,24 @@ export function validateJwtConfig() {
25
26
  export function isJwtAuthRequired() {
26
27
  return REQUIRE_AUTH;
27
28
  }
29
+ /** SA4E-375: Auto-upsert project in project_registry to avoid PROJECT_NOT_REGISTERED. */
30
+ async function autoUpsertProject(projectId, workspaceRoot, userId) {
31
+ if (!projectId || projectId === 'default' || !projectId.trim())
32
+ return;
33
+ try {
34
+ const adapter = getDbAdapter();
35
+ const displayName = workspaceRoot ? workspaceRoot.split(/[\\/]/).pop() || projectId : projectId;
36
+ await adapter.runAsync(`INSERT INTO project_registry (project_id, display_name, workspace_path, created_by, last_seen)
37
+ VALUES (?, ?, ?, ?, current_timestamp)
38
+ ON CONFLICT(project_id) DO UPDATE SET
39
+ display_name = COALESCE(EXCLUDED.display_name, display_name),
40
+ workspace_path = COALESCE(EXCLUDED.workspace_path, workspace_path),
41
+ last_seen = current_timestamp`, [projectId, displayName, workspaceRoot, userId || '']);
42
+ }
43
+ catch {
44
+ // Non-fatal: ignore upsert errors, project may already exist or DB error
45
+ }
46
+ }
28
47
  function decodeJwtPayload(token) {
29
48
  try {
30
49
  const parts = token.split('.');
@@ -64,11 +83,16 @@ function createJwtAuth(alwaysRequire = false) {
64
83
  return async (c, next) => {
65
84
  // X-Project-Id header is the mandatory source of project identity
66
85
  const projectId = c.req.header('X-Project-Id') || '';
86
+ const workspaceRoot = c.req.header('X-Workspace-Root') || '';
67
87
  const authHeader = c.req.header('Authorization');
68
88
  const mustAuth = REQUIRE_AUTH || alwaysRequire;
69
- const anonymous = () => {
70
- const ctx = createProjectContext(projectId, 'anonymous');
71
- c.set('projectContext', ctx);
89
+ const commitContext = async (ctxProjectId, userId) => {
90
+ c.set('projectContext', createProjectContext(ctxProjectId, userId));
91
+ // SA4E-375: auto-upsert project on every authenticated request to ensure project_registry exists
92
+ await autoUpsertProject(ctxProjectId, workspaceRoot, userId);
93
+ };
94
+ const anonymous = async () => {
95
+ await commitContext(projectId, 'anonymous');
72
96
  return next();
73
97
  };
74
98
  const unauthorized = (code, message) => c.json({ data: null, error: { code, message } }, 401);
@@ -107,8 +131,9 @@ function createJwtAuth(alwaysRequire = false) {
107
131
  return anonymous();
108
132
  return unauthorized('TOKEN_INVALID', 'Invalid or expired token');
109
133
  }
110
- const ctx = createProjectContext(projectId || payload.pid || '', payload.sub || 'anonymous', undefined, payload.wid || undefined);
111
- c.set('projectContext', ctx);
134
+ const ctxProjectId = projectId || payload.pid || '';
135
+ const userId = payload.sub || 'anonymous';
136
+ await commitContext(ctxProjectId, userId);
112
137
  return next();
113
138
  }
114
139
  const userAgent = c.req.header('user-agent') || '';
@@ -125,8 +150,7 @@ function createJwtAuth(alwaysRequire = false) {
125
150
  return anonymous();
126
151
  return unauthorized('TOKEN_INVALID', 'Invalid or expired token');
127
152
  }
128
- const ctx = createProjectContext(projectId, session.userId);
129
- c.set('projectContext', ctx);
153
+ await commitContext(projectId, session.userId);
130
154
  return next();
131
155
  };
132
156
  }
@@ -1 +1 @@
1
- {"version":3,"file":"jwt-auth.js","sourceRoot":"","sources":["../../../src/server/middleware/jwt-auth.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"jwt-auth.js","sourceRoot":"","sources":["../../../src/server/middleware/jwt-auth.ts"],"names":[],"mappings":"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"}
@@ -74,15 +74,23 @@ export function createAdminContext(logger, registry) {
74
74
  const row = await adapter.getAsync('SELECT project_id FROM project_registry WHERE project_id = ?', [projectId]);
75
75
  if (row)
76
76
  return projectId;
77
- return c.json({
78
- __error: true,
79
- error: {
80
- code: 'PROJECT_NOT_REGISTERED',
81
- message: `Project ${projectId} is not registered. Call POST /api/admin/projects/register first.`,
82
- action: 'register',
83
- projectId,
84
- }
85
- }, 404);
77
+ // SA4E-375: Server-side auto-upsert project on first access to avoid PROJECT_NOT_REGISTERED
78
+ const workspaceRoot = c.req.header('X-Workspace-Root') || '';
79
+ const displayName = workspaceRoot ? workspaceRoot.split(/[\\/]/).pop() || projectId : projectId;
80
+ try {
81
+ await adapter.runAsync(`INSERT INTO project_registry (project_id, display_name, workspace_path, created_by, last_seen)
82
+ VALUES (?, ?, ?, ?, current_timestamp)
83
+ ON CONFLICT(project_id) DO UPDATE SET
84
+ display_name = COALESCE(EXCLUDED.display_name, display_name),
85
+ workspace_path = COALESCE(EXCLUDED.workspace_path, workspace_path),
86
+ last_seen = current_timestamp`, [projectId, displayName, workspaceRoot, '']);
87
+ logger.info({ projectId, displayName, workspaceRoot }, '[ensureProjectRegistered] auto-upserted project');
88
+ }
89
+ catch (upsertErr) {
90
+ // Non-fatal: log and continue; subsequent requests may succeed
91
+ logger.warn({ err: upsertErr, projectId }, '[ensureProjectRegistered] auto-upsert failed, proceeding');
92
+ }
93
+ return projectId;
86
94
  }
87
95
  catch (err) {
88
96
  logger.error({ err }, '[ensureProjectRegistered] check failed');
@@ -1 +1 @@
1
- {"version":3,"file":"context.js","sourceRoot":"","sources":["../../../../src/server/routes/admin/context.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"context.js","sourceRoot":"","sources":["../../../../src/server/routes/admin/context.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sdlc-agent-4-enterprise-server",
3
- "version": "1.53.3",
3
+ "version": "1.53.12",
4
4
  "description": "Code Intelligence MCP Server — multi-agent SDLC pipeline with semantic memory, code graph, and draw.io integration",
5
5
  "main": "dist/index.js",
6
6
  "bin": {
@@ -18,7 +18,7 @@ describe('DEFAULT_EXTENSIONS (SA4E-223)', () => {
18
18
  // regression: legacy extensions preserved
19
19
  expect(cfg.includeExtensions).toContain('.cls');
20
20
  expect(cfg.includeExtensions).toContain('.trigger');
21
- expect(cfg.includeExtensions).toContain('.pega');
21
+ expect(cfg.includeExtensions).not.toContain('.pega');
22
22
  } finally {
23
23
  fs.rmSync(ws, { recursive: true, force: true });
24
24
  }
@@ -0,0 +1,77 @@
1
+ /**
2
+ * Unified config schema + shared config constants (BR-18 split from index.ts).
3
+ * The Zod schema is the single source of truth for the backend config shape;
4
+ * index.ts assembles the raw object and parses it through this schema.
5
+ */
6
+
7
+ import { z } from 'zod';
8
+ import { SandboxConfigSchema } from './SandboxConfig.js';
9
+ import { EntraSurfaceSchema } from './EntraConfig.js';
10
+
11
+ export const DEFAULT_EXCLUDE = [
12
+ 'node_modules', '.git', 'dist', 'build', '.gradle',
13
+ '.idea', '.vscode', '__pycache__', '.venv', 'target',
14
+ '.code-intel', 'coverage', '.next', '.nuxt',
15
+ 'rules',
16
+ '.pega-cache',
17
+ ];
18
+
19
+ export const DEFAULT_EXTENSIONS = [
20
+ '.ts', '.tsx', '.js', '.jsx', '.kt', '.java', '.py',
21
+ '.go', '.rs', '.c', '.cpp', '.h', '.hpp', '.cs',
22
+ '.rb', '.php', '.swift', '.scala', '.sql', '.sh',
23
+ '.yaml', '.yml', '.json', '.toml', '.gradle.kts',
24
+ '.cls', '.trigger',
25
+ // ---- SA4E-223: new Salesforce simple extensions (Gate 2) ----
26
+ '.apex', '.soql', '.page', '.component', '.cmp', '.app', '.evt', '.intf', '.tokens',
27
+ // ---- SA4E-225: un-skip PowerShell ----
28
+ '.ps1',
29
+ ];
30
+
31
+ export const UnifiedConfigSchema = z.object({
32
+ port: z.number().min(1024).max(65535).default(48721),
33
+ host: z.string().default('0.0.0.0'),
34
+ // Legacy/deprecated — nothing loads a bare .onnx file anymore; kept for
35
+ // backward-compatible admin config output. See embeddingModelId below.
36
+ onnxModelPath: z.string().default('models/model.onnx'),
37
+ // SA4E-44 / AD-6 — real ONNX embeddings via transformers.js (EmbeddingService).
38
+ embeddingModelId: z.string().default('Xenova/paraphrase-multilingual-MiniLM-L12-v2'),
39
+ embeddingCacheDir: z.string(),
40
+ embeddingQuantized: z.boolean().default(true),
41
+ logLevel: z.enum(['debug', 'info', 'warn', 'error']).default('info'),
42
+ viewerPort: z.number().default(3202),
43
+ watchEnabled: z.boolean().default(true),
44
+ watchDebounceMs: z.number().default(500),
45
+ ollamaUrl: z.string().nullable().default(null),
46
+ ollamaModel: z.string().default('nomic-embed-text'),
47
+ maxFileSize: z.number().default(512_000),
48
+ projectId: z.string().default('default'),
49
+ workspace: z.string(),
50
+ indexTempDir: z.string(),
51
+ dbPath: z.string(),
52
+ configPath: z.string(),
53
+ dataDir: z.string(),
54
+ sqliteDbPath: z.string(),
55
+ orchestrationConfigPath: z.string(),
56
+ excludePatterns: z.array(z.string()),
57
+ includeExtensions: z.array(z.string()),
58
+ sandbox: SandboxConfigSchema,
59
+ entra: EntraSurfaceSchema, // SA4E-264 — Entra ID SSO surface (gate: SSO_ENABLED)
60
+ });
61
+
62
+ export type UnifiedConfig = z.infer<typeof UnifiedConfigSchema>;
63
+ export type AppConfig = UnifiedConfig;
64
+ export type BackendConfig = UnifiedConfig;
65
+
66
+ export function envBool(key: string, fallback: boolean): boolean {
67
+ const val = process.env[key];
68
+ if (val === undefined) return fallback;
69
+ return val === '1' || val.toLowerCase() === 'true';
70
+ }
71
+
72
+ export function envInt(key: string, fallback: number): number {
73
+ const val = process.env[key];
74
+ if (val === undefined) return fallback;
75
+ const parsed = parseInt(val, 10);
76
+ return isNaN(parsed) ? fallback : parsed;
77
+ }
@@ -7,7 +7,7 @@ export const UNIFIED_EXTENSIONS = [
7
7
  'kt', 'java', 'py', 'go', 'rs',
8
8
  'c', 'cpp', 'h', 'hpp',
9
9
  'cs', 'php', 'rb', 'scala', 'swift',
10
- 'cls', 'trigger', 'apex', 'soql', 'page', 'component', 'cmp', 'app', 'evt', 'intf', 'tokens', 'pega',
10
+ 'cls', 'trigger', 'apex', 'soql', 'page', 'component', 'cmp', 'app', 'evt', 'intf', 'tokens',
11
11
  'html', 'jsp', 'xml', 'sql', 'properties', 'yml', 'yaml', 'css',
12
12
  'ps1'
13
13
  ] as const;
@@ -113,10 +113,10 @@ describe('detectLanguage', () => {
113
113
  });
114
114
 
115
115
  // ---- SA4E-223: regression — .cls/.trigger/.pega unchanged (TC-05) ----
116
- it('keeps legacy apex/pega mappings', () => {
116
+ it('keeps legacy apex mappings, pega removed for SRP', () => {
117
117
  expect(detectLanguage('/a/C.cls')).toBe('apex');
118
118
  expect(detectLanguage('/a/T.trigger')).toBe('apex');
119
- expect(detectLanguage('/a/R.pega')).toBe('pega');
119
+ expect(detectLanguage('/a/R.pega')).toBeNull();
120
120
  });
121
121
 
122
122
  // ---- SA4E-223: unknown still null (TC-06) ----
@@ -0,0 +1,78 @@
1
+ /**
2
+ * Language detection for the file scanner (extension maps + compound suffixes).
3
+ * Extracted from file-scanner.ts (BR-18) — no behavior change.
4
+ */
5
+
6
+ import * as path from 'path';
7
+
8
+ export const EXTENSION_LANGUAGE_MAP: Record<string, string> = {
9
+ '.ts': 'typescript', '.tsx': 'typescript',
10
+ '.js': 'javascript', '.jsx': 'javascript',
11
+ '.kt': 'kotlin', '.kts': 'kotlin',
12
+ '.java': 'java',
13
+ '.py': 'python',
14
+ '.go': 'go',
15
+ '.rs': 'rust',
16
+ '.c': 'c', '.h': 'c',
17
+ '.cpp': 'cpp', '.hpp': 'cpp', '.cc': 'cpp', '.cxx': 'cpp',
18
+ '.cs': 'csharp',
19
+ '.rb': 'ruby',
20
+ '.php': 'php',
21
+ '.swift': 'swift',
22
+ '.scala': 'scala',
23
+ '.sql': 'sql',
24
+ '.sh': 'bash',
25
+ '.yaml': 'yaml', '.yml': 'yaml',
26
+ '.json': 'json',
27
+ '.toml': 'toml',
28
+ '.cls': 'apex',
29
+ '.trigger': 'apex',
30
+ // ---- SA4E-223: new Salesforce simple extensions ----
31
+ '.apex': 'apex',
32
+ '.soql': 'apex',
33
+ '.page': 'visualforce',
34
+ '.component': 'visualforce',
35
+ '.cmp': 'aura',
36
+ '.app': 'aura',
37
+ '.evt': 'aura',
38
+ '.intf': 'aura',
39
+ '.tokens': 'aura',
40
+ // ---- SA4E-... LWC HTML template support ----
41
+ '.html': 'lwc-html',
42
+ // ---- SA4E-261: Tier B extensions for unified whitelist ----
43
+ '.jsp': 'jsp',
44
+ '.xml': 'xml',
45
+ '.properties': 'properties',
46
+ '.css': 'css',
47
+ '.ps1': 'powershell',
48
+ };
49
+
50
+ /**
51
+ * SA4E-223 — Single source of truth for Salesforce `*-meta.xml` compound suffixes.
52
+ * Used by detectLanguage() so *.xml files are routed to the `salesforce-meta` parser.
53
+ * (Compound-suffix files have ext === '.xml' which is NOT in includeExtensions, but
54
+ * processFile/async-file-scanner exempt `language === 'salesforce-meta'`.)
55
+ */
56
+ export const SALESFORCE_META_SUFFIXES: string[] = [
57
+ '.flow-meta.xml', '.object-meta.xml', '.field-meta.xml', '.js-meta.xml', '.component-meta.xml',
58
+ '.flexipage-meta.xml', '.permissionset-meta.xml', '.profile-meta.xml', '.labels-meta.xml',
59
+ '.tab-meta.xml', '.layout-meta.xml', '.report-meta.xml', '.dashboard-meta.xml',
60
+ '.site-meta.xml', '.resource-meta.xml', '.email-meta.xml', '.testsuite-meta.xml',
61
+ ];
62
+
63
+ /** Detect language from file extension — supports compound extensions. */
64
+ export function detectLanguage(filePath: string): string | null {
65
+ // Check compound extensions first (Salesforce metadata)
66
+ const lowerPath = filePath.toLowerCase().replace(/\\/g, '/');
67
+ if (SALESFORCE_META_SUFFIXES.some(s => lowerPath.endsWith(s))) {
68
+ return 'salesforce-meta';
69
+ }
70
+
71
+ const ext = getExtension(filePath);
72
+ return EXTENSION_LANGUAGE_MAP[ext] ?? null;
73
+ }
74
+
75
+ export function getExtension(filePath: string): string {
76
+ if (filePath.endsWith('.gradle.kts')) return '.kts';
77
+ return path.extname(filePath).toLowerCase();
78
+ }
@@ -40,8 +40,9 @@ describe('IndexingStrategyResolver', () => {
40
40
 
41
41
  it('SA4E-223: getFallback includes new Salesforce extensions', () => {
42
42
  const exts = resolver.getFallback().includeExtensions;
43
- for (const e of ['.apex', '.soql', '.page', '.component', '.cmp', '.app', '.evt', '.intf', '.tokens', '.cls', '.trigger', '.pega']) {
43
+ for (const e of ['.apex', '.soql', '.page', '.component', '.cmp', '.app', '.evt', '.intf', '.tokens', '.cls', '.trigger']) {
44
44
  expect(exts).toContain(e);
45
45
  }
46
+ expect(exts).not.toContain('.pega');
46
47
  });
47
48
  });
@@ -12,6 +12,8 @@ const BASE_EXCLUDES = ['.git', '.svn', '.hg'];
12
12
  const FALLBACK_EXCLUDES = [
13
13
  'node_modules', '.git', 'dist', 'build', '.gradle',
14
14
  '.idea', '.vscode', '__pycache__', '.venv', 'target',
15
+ 'rules',
16
+ '.pega-cache',
15
17
  ];
16
18
 
17
19
  /** Fallback extensions aligned with unified whitelist (SA4E-261) */
@@ -14,6 +14,7 @@ import { createProjectContext } from '../../modules/memory/ProjectContext.js';
14
14
  import { SessionService } from '../services/SessionService.js';
15
15
  import { getEntraVerifier, isEntraToken, tryEntraVerification, validateEntraAuthConfig } from './verifiers/entra-auth.js';
16
16
  import { getJwtSecret } from '../../admin/db/jwt.js';
17
+ import { getDbAdapter } from '../../admin/admin-db.js';
17
18
 
18
19
  const REQUIRE_AUTH = process.env.CODE_INTEL_REQUIRE_AUTH === 'true';
19
20
  const TOKEN_SECRET = process.env.KB_TOKEN_SECRET || '';
@@ -31,6 +32,26 @@ export function isJwtAuthRequired(): boolean {
31
32
  return REQUIRE_AUTH;
32
33
  }
33
34
 
35
+ /** SA4E-375: Auto-upsert project in project_registry to avoid PROJECT_NOT_REGISTERED. */
36
+ async function autoUpsertProject(projectId: string, workspaceRoot: string, userId: string) {
37
+ if (!projectId || projectId === 'default' || !projectId.trim()) return;
38
+ try {
39
+ const adapter = getDbAdapter();
40
+ const displayName = workspaceRoot ? workspaceRoot.split(/[\\/]/).pop() || projectId : projectId;
41
+ await adapter.runAsync(
42
+ `INSERT INTO project_registry (project_id, display_name, workspace_path, created_by, last_seen)
43
+ VALUES (?, ?, ?, ?, current_timestamp)
44
+ ON CONFLICT(project_id) DO UPDATE SET
45
+ display_name = COALESCE(EXCLUDED.display_name, display_name),
46
+ workspace_path = COALESCE(EXCLUDED.workspace_path, workspace_path),
47
+ last_seen = current_timestamp`,
48
+ [projectId, displayName, workspaceRoot, userId || '']
49
+ );
50
+ } catch {
51
+ // Non-fatal: ignore upsert errors, project may already exist or DB error
52
+ }
53
+ }
54
+
34
55
  function decodeJwtPayload(token: string): Record<string, any> | null {
35
56
  try {
36
57
  const parts = token.split('.');
@@ -69,12 +90,18 @@ function createJwtAuth(alwaysRequire = false): MiddlewareHandler {
69
90
  return async (c, next) => {
70
91
  // X-Project-Id header is the mandatory source of project identity
71
92
  const projectId = c.req.header('X-Project-Id') || '';
93
+ const workspaceRoot = c.req.header('X-Workspace-Root') || '';
72
94
  const authHeader = c.req.header('Authorization');
73
95
  const mustAuth = REQUIRE_AUTH || alwaysRequire;
74
96
 
75
- const anonymous = () => {
76
- const ctx = createProjectContext(projectId, 'anonymous');
77
- c.set('projectContext', ctx);
97
+ const commitContext = async (ctxProjectId: string, userId: string) => {
98
+ c.set('projectContext', createProjectContext(ctxProjectId, userId));
99
+ // SA4E-375: auto-upsert project on every authenticated request to ensure project_registry exists
100
+ await autoUpsertProject(ctxProjectId, workspaceRoot, userId);
101
+ };
102
+
103
+ const anonymous = async () => {
104
+ await commitContext(projectId, 'anonymous');
78
105
  return next();
79
106
  };
80
107
 
@@ -117,13 +144,9 @@ function createJwtAuth(alwaysRequire = false): MiddlewareHandler {
117
144
  if (!mustAuth) return anonymous();
118
145
  return unauthorized('TOKEN_INVALID', 'Invalid or expired token');
119
146
  }
120
- const ctx = createProjectContext(
121
- projectId || payload.pid || '',
122
- payload.sub || 'anonymous',
123
- undefined,
124
- payload.wid || undefined,
125
- );
126
- c.set('projectContext', ctx);
147
+ const ctxProjectId = projectId || payload.pid || '';
148
+ const userId = payload.sub || 'anonymous';
149
+ await commitContext(ctxProjectId, userId);
127
150
  return next();
128
151
  }
129
152
 
@@ -139,8 +162,7 @@ function createJwtAuth(alwaysRequire = false): MiddlewareHandler {
139
162
  if (!mustAuth) return anonymous();
140
163
  return unauthorized('TOKEN_INVALID', 'Invalid or expired token');
141
164
  }
142
- const ctx = createProjectContext(projectId, session.userId);
143
- c.set('projectContext', ctx);
165
+ await commitContext(projectId, session.userId);
144
166
  return next();
145
167
  };
146
168
  }
@@ -111,15 +111,25 @@ export function createAdminContext(logger: Logger, registry?: any): AdminContext
111
111
  [projectId]
112
112
  );
113
113
  if (row) return projectId;
114
- return c.json({
115
- __error: true,
116
- error: {
117
- code: 'PROJECT_NOT_REGISTERED',
118
- message: `Project ${projectId} is not registered. Call POST /api/admin/projects/register first.`,
119
- action: 'register',
120
- projectId,
121
- }
122
- }, 404);
114
+ // SA4E-375: Server-side auto-upsert project on first access to avoid PROJECT_NOT_REGISTERED
115
+ const workspaceRoot = c.req.header('X-Workspace-Root') || '';
116
+ const displayName = workspaceRoot ? workspaceRoot.split(/[\\/]/).pop() || projectId : projectId;
117
+ try {
118
+ await adapter.runAsync(
119
+ `INSERT INTO project_registry (project_id, display_name, workspace_path, created_by, last_seen)
120
+ VALUES (?, ?, ?, ?, current_timestamp)
121
+ ON CONFLICT(project_id) DO UPDATE SET
122
+ display_name = COALESCE(EXCLUDED.display_name, display_name),
123
+ workspace_path = COALESCE(EXCLUDED.workspace_path, workspace_path),
124
+ last_seen = current_timestamp`,
125
+ [projectId, displayName, workspaceRoot, '']
126
+ );
127
+ logger.info({ projectId, displayName, workspaceRoot }, '[ensureProjectRegistered] auto-upserted project');
128
+ } catch (upsertErr: any) {
129
+ // Non-fatal: log and continue; subsequent requests may succeed
130
+ logger.warn({ err: upsertErr, projectId }, '[ensureProjectRegistered] auto-upsert failed, proceeding');
131
+ }
132
+ return projectId;
123
133
  } catch (err: any) {
124
134
  logger.error({ err }, '[ensureProjectRegistered] check failed');
125
135
  return c.json({ __error: true, error: { code: 'INTERNAL_ERROR', message: err.message } }, 500);