@neurcode-ai/cli 0.9.49 → 0.9.59

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 (109) hide show
  1. package/dist/commands/fix.d.ts +1 -0
  2. package/dist/commands/fix.d.ts.map +1 -1
  3. package/dist/commands/fix.js +710 -29
  4. package/dist/commands/fix.js.map +1 -1
  5. package/dist/commands/generate.d.ts.map +1 -1
  6. package/dist/commands/generate.js +16 -1
  7. package/dist/commands/generate.js.map +1 -1
  8. package/dist/commands/patch-apply.d.ts +7 -0
  9. package/dist/commands/patch-apply.d.ts.map +1 -0
  10. package/dist/commands/patch-apply.js +85 -0
  11. package/dist/commands/patch-apply.js.map +1 -0
  12. package/dist/commands/start-intent.d.ts.map +1 -1
  13. package/dist/commands/start-intent.js +17 -2
  14. package/dist/commands/start-intent.js.map +1 -1
  15. package/dist/commands/verify.d.ts.map +1 -1
  16. package/dist/commands/verify.js +372 -71
  17. package/dist/commands/verify.js.map +1 -1
  18. package/dist/context-engine/graph.d.ts +6 -0
  19. package/dist/context-engine/graph.d.ts.map +1 -0
  20. package/dist/context-engine/graph.js +55 -0
  21. package/dist/context-engine/graph.js.map +1 -0
  22. package/dist/context-engine/index.d.ts +14 -0
  23. package/dist/context-engine/index.d.ts.map +1 -0
  24. package/dist/context-engine/index.js +26 -0
  25. package/dist/context-engine/index.js.map +1 -0
  26. package/dist/context-engine/scanner.d.ts +6 -0
  27. package/dist/context-engine/scanner.d.ts.map +1 -0
  28. package/dist/context-engine/scanner.js +62 -0
  29. package/dist/context-engine/scanner.js.map +1 -0
  30. package/dist/context-engine/scorer.d.ts +9 -0
  31. package/dist/context-engine/scorer.d.ts.map +1 -0
  32. package/dist/context-engine/scorer.js +112 -0
  33. package/dist/context-engine/scorer.js.map +1 -0
  34. package/dist/context-engine/suggestions.d.ts +12 -0
  35. package/dist/context-engine/suggestions.d.ts.map +1 -0
  36. package/dist/context-engine/suggestions.js +22 -0
  37. package/dist/context-engine/suggestions.js.map +1 -0
  38. package/dist/daemon/server.d.ts +23 -0
  39. package/dist/daemon/server.d.ts.map +1 -0
  40. package/dist/daemon/server.js +222 -0
  41. package/dist/daemon/server.js.map +1 -0
  42. package/dist/index.js +22 -0
  43. package/dist/index.js.map +1 -1
  44. package/dist/intent-engine/coverage.d.ts +69 -0
  45. package/dist/intent-engine/coverage.d.ts.map +1 -0
  46. package/dist/intent-engine/coverage.js +140 -0
  47. package/dist/intent-engine/coverage.js.map +1 -0
  48. package/dist/intent-engine/flow-rules.d.ts +21 -0
  49. package/dist/intent-engine/flow-rules.d.ts.map +1 -0
  50. package/dist/intent-engine/flow-rules.js +83 -0
  51. package/dist/intent-engine/flow-rules.js.map +1 -0
  52. package/dist/intent-engine/flow-validator.d.ts +29 -0
  53. package/dist/intent-engine/flow-validator.d.ts.map +1 -0
  54. package/dist/intent-engine/flow-validator.js +202 -0
  55. package/dist/intent-engine/flow-validator.js.map +1 -0
  56. package/dist/intent-engine/graph.d.ts +33 -0
  57. package/dist/intent-engine/graph.d.ts.map +1 -0
  58. package/dist/intent-engine/graph.js +67 -0
  59. package/dist/intent-engine/graph.js.map +1 -0
  60. package/dist/intent-engine/index.d.ts +35 -0
  61. package/dist/intent-engine/index.d.ts.map +1 -0
  62. package/dist/intent-engine/index.js +94 -0
  63. package/dist/intent-engine/index.js.map +1 -0
  64. package/dist/intent-engine/indexer.d.ts +18 -0
  65. package/dist/intent-engine/indexer.d.ts.map +1 -0
  66. package/dist/intent-engine/indexer.js +100 -0
  67. package/dist/intent-engine/indexer.js.map +1 -0
  68. package/dist/intent-engine/matcher.d.ts +35 -0
  69. package/dist/intent-engine/matcher.d.ts.map +1 -0
  70. package/dist/intent-engine/matcher.js +522 -0
  71. package/dist/intent-engine/matcher.js.map +1 -0
  72. package/dist/intent-engine/parser.d.ts +12 -0
  73. package/dist/intent-engine/parser.d.ts.map +1 -0
  74. package/dist/intent-engine/parser.js +93 -0
  75. package/dist/intent-engine/parser.js.map +1 -0
  76. package/dist/intent-engine/regression.d.ts +32 -0
  77. package/dist/intent-engine/regression.d.ts.map +1 -0
  78. package/dist/intent-engine/regression.js +166 -0
  79. package/dist/intent-engine/regression.js.map +1 -0
  80. package/dist/intent-engine/requirements.d.ts +22 -0
  81. package/dist/intent-engine/requirements.d.ts.map +1 -0
  82. package/dist/intent-engine/requirements.js +147 -0
  83. package/dist/intent-engine/requirements.js.map +1 -0
  84. package/dist/intent-engine/state.d.ts +44 -0
  85. package/dist/intent-engine/state.d.ts.map +1 -0
  86. package/dist/intent-engine/state.js +83 -0
  87. package/dist/intent-engine/state.js.map +1 -0
  88. package/dist/patch-engine/diff.d.ts +12 -0
  89. package/dist/patch-engine/diff.d.ts.map +1 -0
  90. package/dist/patch-engine/diff.js +74 -0
  91. package/dist/patch-engine/diff.js.map +1 -0
  92. package/dist/patch-engine/generator.d.ts +13 -0
  93. package/dist/patch-engine/generator.d.ts.map +1 -0
  94. package/dist/patch-engine/generator.js +51 -0
  95. package/dist/patch-engine/generator.js.map +1 -0
  96. package/dist/patch-engine/index.d.ts +47 -0
  97. package/dist/patch-engine/index.d.ts.map +1 -0
  98. package/dist/patch-engine/index.js +182 -0
  99. package/dist/patch-engine/index.js.map +1 -0
  100. package/dist/patch-engine/patterns.d.ts +4 -0
  101. package/dist/patch-engine/patterns.d.ts.map +1 -0
  102. package/dist/patch-engine/patterns.js +99 -0
  103. package/dist/patch-engine/patterns.js.map +1 -0
  104. package/dist/utils/ai-debt-budget.d.ts +3 -2
  105. package/dist/utils/ai-debt-budget.d.ts.map +1 -1
  106. package/dist/utils/ai-debt-budget.js +83 -2
  107. package/dist/utils/ai-debt-budget.js.map +1 -1
  108. package/package.json +8 -7
  109. package/LICENSE +0 -201
@@ -0,0 +1,6 @@
1
+ import type { ProjectScanResult } from './scanner';
2
+ export type DependencyGraph = {
3
+ imports: Record<string, string[]>;
4
+ };
5
+ export declare function buildDependencyGraph(scan: ProjectScanResult): DependencyGraph;
6
+ //# sourceMappingURL=graph.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"graph.d.ts","sourceRoot":"","sources":["../../src/context-engine/graph.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAC;AAEnD,MAAM,MAAM,eAAe,GAAG;IAC5B,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;CACnC,CAAC;AAoCF,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,iBAAiB,GAAG,eAAe,CAuB7E"}
@@ -0,0 +1,55 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.buildDependencyGraph = buildDependencyGraph;
4
+ const path_1 = require("path");
5
+ // Matches: import ... from './foo' or require('./foo')
6
+ const IMPORT_RE = /(?:import\s[^'"]*from|require\()\s*['"](\.[^'"]+)['"]/g;
7
+ function resolveImport(fromFile, importPath) {
8
+ const fromDir = (0, path_1.dirname)(fromFile);
9
+ let resolved = (0, path_1.normalize)((0, path_1.join)(fromDir, importPath)).replace(/\\/g, '/');
10
+ // If no extension, try to match against known files by trying common extensions
11
+ if (!/\.[jt]sx?$/.test(resolved)) {
12
+ // Return as-is with a placeholder — callers reconcile against real files
13
+ return resolved;
14
+ }
15
+ return resolved;
16
+ }
17
+ function reconcileToKnownFile(candidate, fileSet) {
18
+ if (fileSet.has(candidate))
19
+ return candidate;
20
+ const extensions = ['.ts', '.tsx', '.js', '.jsx'];
21
+ for (const ext of extensions) {
22
+ const withExt = `${candidate}${ext}`;
23
+ if (fileSet.has(withExt))
24
+ return withExt;
25
+ }
26
+ // Try index files
27
+ for (const ext of extensions) {
28
+ const index = `${candidate}/index${ext}`;
29
+ if (fileSet.has(index))
30
+ return index;
31
+ }
32
+ return null;
33
+ }
34
+ function buildDependencyGraph(scan) {
35
+ const fileSet = new Set(scan.files);
36
+ const imports = {};
37
+ for (const file of scan.files) {
38
+ imports[file] = [];
39
+ const content = scan.fileContents[file] ?? '';
40
+ let match;
41
+ IMPORT_RE.lastIndex = 0;
42
+ while ((match = IMPORT_RE.exec(content)) !== null) {
43
+ const importPath = match[1];
44
+ if (!importPath)
45
+ continue;
46
+ const resolved = resolveImport(file, importPath);
47
+ const known = reconcileToKnownFile(resolved, fileSet);
48
+ if (known && known !== file) {
49
+ imports[file].push(known);
50
+ }
51
+ }
52
+ }
53
+ return { imports };
54
+ }
55
+ //# sourceMappingURL=graph.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"graph.js","sourceRoot":"","sources":["../../src/context-engine/graph.ts"],"names":[],"mappings":";;AAyCA,oDAuBC;AAhED,+BAAgD;AAOhD,uDAAuD;AACvD,MAAM,SAAS,GAAG,wDAAwD,CAAC;AAE3E,SAAS,aAAa,CAAC,QAAgB,EAAE,UAAkB;IACzD,MAAM,OAAO,GAAG,IAAA,cAAO,EAAC,QAAQ,CAAC,CAAC;IAClC,IAAI,QAAQ,GAAG,IAAA,gBAAS,EAAC,IAAA,WAAI,EAAC,OAAO,EAAE,UAAU,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;IAExE,gFAAgF;IAChF,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC;QACjC,yEAAyE;QACzE,OAAO,QAAQ,CAAC;IAClB,CAAC;IAED,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,SAAS,oBAAoB,CAAC,SAAiB,EAAE,OAAoB;IACnE,IAAI,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC;QAAE,OAAO,SAAS,CAAC;IAE7C,MAAM,UAAU,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;IAClD,KAAK,MAAM,GAAG,IAAI,UAAU,EAAE,CAAC;QAC7B,MAAM,OAAO,GAAG,GAAG,SAAS,GAAG,GAAG,EAAE,CAAC;QACrC,IAAI,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC;YAAE,OAAO,OAAO,CAAC;IAC3C,CAAC;IAED,kBAAkB;IAClB,KAAK,MAAM,GAAG,IAAI,UAAU,EAAE,CAAC;QAC7B,MAAM,KAAK,GAAG,GAAG,SAAS,SAAS,GAAG,EAAE,CAAC;QACzC,IAAI,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC;YAAE,OAAO,KAAK,CAAC;IACvC,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC;AAED,SAAgB,oBAAoB,CAAC,IAAuB;IAC1D,MAAM,OAAO,GAAG,IAAI,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACpC,MAAM,OAAO,GAA6B,EAAE,CAAC;IAE7C,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;QAC9B,OAAO,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC;QACnB,MAAM,OAAO,GAAG,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;QAC9C,IAAI,KAA6B,CAAC;QAElC,SAAS,CAAC,SAAS,GAAG,CAAC,CAAC;QACxB,OAAO,CAAC,KAAK,GAAG,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC;YAClD,MAAM,UAAU,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;YAC5B,IAAI,CAAC,UAAU;gBAAE,SAAS;YAE1B,MAAM,QAAQ,GAAG,aAAa,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC;YACjD,MAAM,KAAK,GAAG,oBAAoB,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;YACtD,IAAI,KAAK,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;gBAC5B,OAAO,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YAC5B,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,EAAE,OAAO,EAAE,CAAC;AACrB,CAAC"}
@@ -0,0 +1,14 @@
1
+ export { scanProject } from './scanner';
2
+ export { buildDependencyGraph } from './graph';
3
+ export { scoreFiles } from './scorer';
4
+ export type { ProjectScanResult } from './scanner';
5
+ export type { DependencyGraph } from './graph';
6
+ export type { ScoredFile } from './scorer';
7
+ export type { FileSuggestion, SuggestionResult } from './suggestions';
8
+ export type ContextAnalysis = {
9
+ suggestedFiles: string[];
10
+ confidence: number;
11
+ details: import('./suggestions').FileSuggestion[];
12
+ };
13
+ export declare function analyzeContext(rootPath: string, intent: string): ContextAnalysis;
14
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/context-engine/index.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AACxC,OAAO,EAAE,oBAAoB,EAAE,MAAM,SAAS,CAAC;AAC/C,OAAO,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AACtC,YAAY,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAC;AACnD,YAAY,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAC/C,YAAY,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAC3C,YAAY,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAEtE,MAAM,MAAM,eAAe,GAAG;IAC5B,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,OAAO,eAAe,EAAE,cAAc,EAAE,CAAC;CACnD,CAAC;AAEF,wBAAgB,cAAc,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,eAAe,CAWhF"}
@@ -0,0 +1,26 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.scoreFiles = exports.buildDependencyGraph = exports.scanProject = void 0;
4
+ exports.analyzeContext = analyzeContext;
5
+ const scanner_1 = require("./scanner");
6
+ const graph_1 = require("./graph");
7
+ const scorer_1 = require("./scorer");
8
+ const suggestions_1 = require("./suggestions");
9
+ var scanner_2 = require("./scanner");
10
+ Object.defineProperty(exports, "scanProject", { enumerable: true, get: function () { return scanner_2.scanProject; } });
11
+ var graph_2 = require("./graph");
12
+ Object.defineProperty(exports, "buildDependencyGraph", { enumerable: true, get: function () { return graph_2.buildDependencyGraph; } });
13
+ var scorer_2 = require("./scorer");
14
+ Object.defineProperty(exports, "scoreFiles", { enumerable: true, get: function () { return scorer_2.scoreFiles; } });
15
+ function analyzeContext(rootPath, intent) {
16
+ const scan = (0, scanner_1.scanProject)(rootPath);
17
+ const graph = (0, graph_1.buildDependencyGraph)(scan);
18
+ const scored = (0, scorer_1.scoreFiles)(intent, graph);
19
+ const result = (0, suggestions_1.getSuggestedFiles)(scored, 5);
20
+ return {
21
+ suggestedFiles: result.suggestions.map((s) => s.file),
22
+ confidence: result.confidence,
23
+ details: result.suggestions,
24
+ };
25
+ }
26
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/context-engine/index.ts"],"names":[],"mappings":";;;AAmBA,wCAWC;AA9BD,uCAAwC;AACxC,mCAA+C;AAC/C,qCAAsC;AACtC,+CAAkD;AAElD,qCAAwC;AAA/B,sGAAA,WAAW,OAAA;AACpB,iCAA+C;AAAtC,6GAAA,oBAAoB,OAAA;AAC7B,mCAAsC;AAA7B,oGAAA,UAAU,OAAA;AAYnB,SAAgB,cAAc,CAAC,QAAgB,EAAE,MAAc;IAC7D,MAAM,IAAI,GAAG,IAAA,qBAAW,EAAC,QAAQ,CAAC,CAAC;IACnC,MAAM,KAAK,GAAG,IAAA,4BAAoB,EAAC,IAAI,CAAC,CAAC;IACzC,MAAM,MAAM,GAAG,IAAA,mBAAU,EAAC,MAAM,EAAE,KAAK,CAAC,CAAC;IACzC,MAAM,MAAM,GAAG,IAAA,+BAAiB,EAAC,MAAM,EAAE,CAAC,CAAC,CAAC;IAE5C,OAAO;QACL,cAAc,EAAE,MAAM,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;QACrD,UAAU,EAAE,MAAM,CAAC,UAAU;QAC7B,OAAO,EAAE,MAAM,CAAC,WAAW;KAC5B,CAAC;AACJ,CAAC"}
@@ -0,0 +1,6 @@
1
+ export type ProjectScanResult = {
2
+ files: string[];
3
+ fileContents: Record<string, string>;
4
+ };
5
+ export declare function scanProject(rootPath: string): ProjectScanResult;
6
+ //# sourceMappingURL=scanner.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scanner.d.ts","sourceRoot":"","sources":["../../src/context-engine/scanner.ts"],"names":[],"mappings":"AAGA,MAAM,MAAM,iBAAiB,GAAG;IAC9B,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACtC,CAAC;AAuDF,wBAAgB,WAAW,CAAC,QAAQ,EAAE,MAAM,GAAG,iBAAiB,CAI/D"}
@@ -0,0 +1,62 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.scanProject = scanProject;
4
+ const fs_1 = require("fs");
5
+ const path_1 = require("path");
6
+ const INCLUDE_EXTENSIONS = new Set(['.ts', '.tsx', '.js', '.jsx']);
7
+ const EXCLUDE_DIRS = new Set([
8
+ 'node_modules',
9
+ '.git',
10
+ 'dist',
11
+ 'build',
12
+ '.cache',
13
+ 'coverage',
14
+ '.next',
15
+ '.turbo',
16
+ ]);
17
+ function walkDir(dir, rootPath, result) {
18
+ let entries;
19
+ try {
20
+ entries = (0, fs_1.readdirSync)(dir);
21
+ }
22
+ catch {
23
+ return;
24
+ }
25
+ for (const entry of entries) {
26
+ if (EXCLUDE_DIRS.has(entry))
27
+ continue;
28
+ const fullPath = (0, path_1.join)(dir, entry);
29
+ let stat;
30
+ try {
31
+ stat = (0, fs_1.statSync)(fullPath);
32
+ }
33
+ catch {
34
+ continue;
35
+ }
36
+ if (stat.isDirectory()) {
37
+ walkDir(fullPath, rootPath, result);
38
+ continue;
39
+ }
40
+ const lastDot = entry.lastIndexOf('.');
41
+ if (lastDot === -1)
42
+ continue;
43
+ const ext = entry.slice(lastDot);
44
+ if (!INCLUDE_EXTENSIONS.has(ext))
45
+ continue;
46
+ // Store relative path from rootPath
47
+ const relativePath = fullPath.slice(rootPath.length).replace(/\\/g, '/').replace(/^\//, '');
48
+ result.files.push(relativePath);
49
+ try {
50
+ result.fileContents[relativePath] = (0, fs_1.readFileSync)(fullPath, 'utf8');
51
+ }
52
+ catch {
53
+ result.fileContents[relativePath] = '';
54
+ }
55
+ }
56
+ }
57
+ function scanProject(rootPath) {
58
+ const result = { files: [], fileContents: {} };
59
+ walkDir(rootPath, rootPath, result);
60
+ return result;
61
+ }
62
+ //# sourceMappingURL=scanner.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scanner.js","sourceRoot":"","sources":["../../src/context-engine/scanner.ts"],"names":[],"mappings":";;AA6DA,kCAIC;AAjED,2BAAyD;AACzD,+BAA4B;AAO5B,MAAM,kBAAkB,GAAG,IAAI,GAAG,CAAC,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC,CAAC;AAEnE,MAAM,YAAY,GAAG,IAAI,GAAG,CAAC;IAC3B,cAAc;IACd,MAAM;IACN,MAAM;IACN,OAAO;IACP,QAAQ;IACR,UAAU;IACV,OAAO;IACP,QAAQ;CACT,CAAC,CAAC;AAEH,SAAS,OAAO,CAAC,GAAW,EAAE,QAAgB,EAAE,MAAyB;IACvE,IAAI,OAAiB,CAAC;IACtB,IAAI,CAAC;QACH,OAAO,GAAG,IAAA,gBAAW,EAAC,GAAG,CAAC,CAAC;IAC7B,CAAC;IAAC,MAAM,CAAC;QACP,OAAO;IACT,CAAC;IAED,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;QAC5B,IAAI,YAAY,CAAC,GAAG,CAAC,KAAK,CAAC;YAAE,SAAS;QAEtC,MAAM,QAAQ,GAAG,IAAA,WAAI,EAAC,GAAG,EAAE,KAAK,CAAC,CAAC;QAClC,IAAI,IAAI,CAAC;QACT,IAAI,CAAC;YACH,IAAI,GAAG,IAAA,aAAQ,EAAC,QAAQ,CAAC,CAAC;QAC5B,CAAC;QAAC,MAAM,CAAC;YACP,SAAS;QACX,CAAC;QAED,IAAI,IAAI,CAAC,WAAW,EAAE,EAAE,CAAC;YACvB,OAAO,CAAC,QAAQ,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAC;YACpC,SAAS;QACX,CAAC;QAED,MAAM,OAAO,GAAG,KAAK,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;QACvC,IAAI,OAAO,KAAK,CAAC,CAAC;YAAE,SAAS;QAC7B,MAAM,GAAG,GAAG,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QACjC,IAAI,CAAC,kBAAkB,CAAC,GAAG,CAAC,GAAG,CAAC;YAAE,SAAS;QAE3C,oCAAoC;QACpC,MAAM,YAAY,GAAG,QAAQ,CAAC,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;QAC5F,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;QAChC,IAAI,CAAC;YACH,MAAM,CAAC,YAAY,CAAC,YAAY,CAAC,GAAG,IAAA,iBAAY,EAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;QACrE,CAAC;QAAC,MAAM,CAAC;YACP,MAAM,CAAC,YAAY,CAAC,YAAY,CAAC,GAAG,EAAE,CAAC;QACzC,CAAC;IACH,CAAC;AACH,CAAC;AAED,SAAgB,WAAW,CAAC,QAAgB;IAC1C,MAAM,MAAM,GAAsB,EAAE,KAAK,EAAE,EAAE,EAAE,YAAY,EAAE,EAAE,EAAE,CAAC;IAClE,OAAO,CAAC,QAAQ,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAC;IACpC,OAAO,MAAM,CAAC;AAChB,CAAC"}
@@ -0,0 +1,9 @@
1
+ import type { DependencyGraph } from './graph';
2
+ export type ScoredFile = {
3
+ file: string;
4
+ score: number;
5
+ reasons: string[];
6
+ };
7
+ export declare function extractTokens(intent: string): string[];
8
+ export declare function scoreFiles(intent: string, graph: DependencyGraph): ScoredFile[];
9
+ //# sourceMappingURL=scorer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scorer.d.ts","sourceRoot":"","sources":["../../src/context-engine/scorer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAE/C,MAAM,MAAM,UAAU,GAAG;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB,CAAC;AAkBF,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CAMtD;AAcD,wBAAgB,UAAU,CACxB,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,eAAe,GACrB,UAAU,EAAE,CAsFd"}
@@ -0,0 +1,112 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.extractTokens = extractTokens;
4
+ exports.scoreFiles = scoreFiles;
5
+ const STOP_WORDS = new Set([
6
+ 'a', 'an', 'the', 'and', 'or', 'but', 'in', 'on', 'at', 'to', 'for',
7
+ 'of', 'with', 'by', 'from', 'up', 'about', 'into', 'through', 'during',
8
+ 'is', 'are', 'was', 'were', 'be', 'been', 'being', 'have', 'has', 'had',
9
+ 'do', 'does', 'did', 'will', 'would', 'could', 'should', 'may', 'might',
10
+ 'add', 'create', 'make', 'update', 'change', 'implement', 'fix', 'get',
11
+ 'set', 'use', 'new', 'my', 'your', 'our', 'this', 'that', 'it',
12
+ ]);
13
+ const SIGNAL_DIRS = [
14
+ 'auth', 'api', 'middleware', 'service', 'services', 'payment', 'payments',
15
+ 'analytics', 'dashboard', 'user', 'users', 'core', 'lib', 'utils', 'hooks',
16
+ 'store', 'redux', 'context', 'database', 'db', 'models', 'routes', 'router',
17
+ 'controllers', 'handlers', 'components', 'pages', 'views',
18
+ ];
19
+ function extractTokens(intent) {
20
+ return intent
21
+ .toLowerCase()
22
+ .replace(/[^a-z0-9\s]/g, ' ')
23
+ .split(/\s+/)
24
+ .filter((t) => t.length > 1 && !STOP_WORDS.has(t));
25
+ }
26
+ function filenameParts(filePath) {
27
+ const parts = filePath.replace(/\\/g, '/').split('/');
28
+ const filename = parts[parts.length - 1] ?? '';
29
+ // Strip extension and split on separators
30
+ return filename.replace(/\.[^.]+$/, '').toLowerCase().split(/[-_.]/);
31
+ }
32
+ function dirParts(filePath) {
33
+ const parts = filePath.replace(/\\/g, '/').split('/');
34
+ return parts.slice(0, -1).map((p) => p.toLowerCase());
35
+ }
36
+ function scoreFiles(intent, graph) {
37
+ const tokens = extractTokens(intent);
38
+ const files = Object.keys(graph.imports);
39
+ const rawScores = {};
40
+ const rawReasons = {};
41
+ for (const file of files) {
42
+ let score = 0;
43
+ const reasons = [];
44
+ const fnParts = filenameParts(file);
45
+ const dParts = dirParts(file);
46
+ // Heuristic 1: filename match (+3 per keyword match)
47
+ for (const token of tokens) {
48
+ if (fnParts.some((p) => p.includes(token))) {
49
+ score += 3;
50
+ reasons.push(`filename matches "${token}"`);
51
+ }
52
+ }
53
+ // Heuristic 2: directory match (+2 per signal dir match)
54
+ for (const dir of dParts) {
55
+ if (SIGNAL_DIRS.includes(dir)) {
56
+ for (const token of tokens) {
57
+ if (dir.includes(token)) {
58
+ score += 2;
59
+ reasons.push(`directory "${dir}" matches "${token}"`);
60
+ break;
61
+ }
62
+ }
63
+ // Also reward being in a recognized signal dir even without token match
64
+ if (tokens.some((t) => dir.includes(t)))
65
+ continue;
66
+ // Check if any token partially matches a signal-dir keyword
67
+ for (const token of tokens) {
68
+ if (SIGNAL_DIRS.some((sd) => sd.includes(token) && dir === sd)) {
69
+ score += 2;
70
+ reasons.push(`located in signal directory "${dir}"`);
71
+ }
72
+ }
73
+ }
74
+ }
75
+ // Heuristic 3: token match in content (+1 per unique token match)
76
+ // We don't have content here, so we rely on the file path
77
+ const fullPathLower = file.toLowerCase();
78
+ for (const token of tokens) {
79
+ if (fullPathLower.includes(token)) {
80
+ score += 1;
81
+ reasons.push(`path contains "${token}"`);
82
+ }
83
+ }
84
+ rawScores[file] = score;
85
+ rawReasons[file] = reasons;
86
+ }
87
+ // Heuristic 4: import proximity (+2 if a file imports a high-scoring file)
88
+ // First pass: collect files with score > 0
89
+ const threshold = 3;
90
+ const highScoreFiles = new Set(Object.entries(rawScores)
91
+ .filter(([, s]) => s >= threshold)
92
+ .map(([f]) => f));
93
+ for (const file of files) {
94
+ const deps = graph.imports[file] ?? [];
95
+ for (const dep of deps) {
96
+ if (highScoreFiles.has(dep)) {
97
+ rawScores[file] = (rawScores[file] ?? 0) + 2;
98
+ rawReasons[file] = [...(rawReasons[file] ?? []), `imports high-relevance file "${dep}"`];
99
+ break; // only apply once per file
100
+ }
101
+ }
102
+ }
103
+ return files
104
+ .map((file) => ({
105
+ file,
106
+ score: rawScores[file] ?? 0,
107
+ reasons: rawReasons[file] ?? [],
108
+ }))
109
+ .filter((f) => f.score > 0)
110
+ .sort((a, b) => b.score - a.score);
111
+ }
112
+ //# sourceMappingURL=scorer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scorer.js","sourceRoot":"","sources":["../../src/context-engine/scorer.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ import type { ScoredFile } from './scorer';
2
+ export type FileSuggestion = {
3
+ file: string;
4
+ confidence: number;
5
+ reasons: string[];
6
+ };
7
+ export type SuggestionResult = {
8
+ suggestions: FileSuggestion[];
9
+ confidence: number;
10
+ };
11
+ export declare function getSuggestedFiles(scored: ScoredFile[], limit?: number): SuggestionResult;
12
+ //# sourceMappingURL=suggestions.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"suggestions.d.ts","sourceRoot":"","sources":["../../src/context-engine/suggestions.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAE3C,MAAM,MAAM,cAAc,GAAG;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG;IAC7B,WAAW,EAAE,cAAc,EAAE,CAAC;IAC9B,UAAU,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF,wBAAgB,iBAAiB,CAC/B,MAAM,EAAE,UAAU,EAAE,EACpB,KAAK,SAAI,GACR,gBAAgB,CAsBlB"}
@@ -0,0 +1,22 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getSuggestedFiles = getSuggestedFiles;
4
+ function getSuggestedFiles(scored, limit = 5) {
5
+ if (scored.length === 0) {
6
+ return { suggestions: [], confidence: 0 };
7
+ }
8
+ const topN = scored.slice(0, limit);
9
+ const maxScore = scored[0].score;
10
+ const suggestions = topN.map((item) => ({
11
+ file: item.file,
12
+ confidence: maxScore > 0 ? parseFloat((item.score / maxScore).toFixed(2)) : 0,
13
+ reasons: item.reasons,
14
+ }));
15
+ // Overall confidence: average of top-N normalized scores, capped at 1
16
+ const avgConfidence = suggestions.reduce((sum, s) => sum + s.confidence, 0) / suggestions.length;
17
+ return {
18
+ suggestions,
19
+ confidence: parseFloat(Math.min(avgConfidence, 1).toFixed(2)),
20
+ };
21
+ }
22
+ //# sourceMappingURL=suggestions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"suggestions.js","sourceRoot":"","sources":["../../src/context-engine/suggestions.ts"],"names":[],"mappings":";;AAaA,8CAyBC;AAzBD,SAAgB,iBAAiB,CAC/B,MAAoB,EACpB,KAAK,GAAG,CAAC;IAET,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACxB,OAAO,EAAE,WAAW,EAAE,EAAE,EAAE,UAAU,EAAE,CAAC,EAAE,CAAC;IAC5C,CAAC;IAED,MAAM,IAAI,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC;IACpC,MAAM,QAAQ,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;IAEjC,MAAM,WAAW,GAAqB,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;QACxD,IAAI,EAAE,IAAI,CAAC,IAAI;QACf,UAAU,EAAE,QAAQ,GAAG,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,KAAK,GAAG,QAAQ,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAC7E,OAAO,EAAE,IAAI,CAAC,OAAO;KACtB,CAAC,CAAC,CAAC;IAEJ,sEAAsE;IACtE,MAAM,aAAa,GACjB,WAAW,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,GAAG,GAAG,CAAC,CAAC,UAAU,EAAE,CAAC,CAAC,GAAG,WAAW,CAAC,MAAM,CAAC;IAE7E,OAAO;QACL,WAAW;QACX,UAAU,EAAE,UAAU,CAAC,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;KAC9D,CAAC;AACJ,CAAC"}
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Neurcode Daemon V2 — lightweight local HTTP bridge.
3
+ *
4
+ * Runs at http://localhost:4321
5
+ *
6
+ * Routes:
7
+ * POST /verify → neurcode verify --json
8
+ * POST /fix → neurcode fix --json
9
+ * POST /fix/apply-safe → neurcode fix --apply-safe --json
10
+ * POST /patch → neurcode patch + verify (auto state sync)
11
+ * GET /health → { ok: true, version }
12
+ *
13
+ * Implementation notes:
14
+ * - Uses runCliJson (internal CLI invocation utility) — no raw child_process
15
+ * - Only accepts requests from 127.0.0.1 / ::1 / localhost
16
+ * - All responses use unified shape: { success, data, error? }
17
+ */
18
+ import * as http from 'node:http';
19
+ export declare const DAEMON_PORT = 4321;
20
+ export declare const DAEMON_HOST = "127.0.0.1";
21
+ export declare function createDaemonServer(): http.Server;
22
+ export declare function startDaemon(): void;
23
+ //# sourceMappingURL=server.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/daemon/server.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAOlC,eAAO,MAAM,WAAW,OAAO,CAAC;AAChC,eAAO,MAAM,WAAW,cAAc,CAAC;AAmHvC,wBAAgB,kBAAkB,IAAI,IAAI,CAAC,MAAM,CAyChD;AAID,wBAAgB,WAAW,IAAI,IAAI,CA4BlC"}
@@ -0,0 +1,222 @@
1
+ "use strict";
2
+ /**
3
+ * Neurcode Daemon V2 — lightweight local HTTP bridge.
4
+ *
5
+ * Runs at http://localhost:4321
6
+ *
7
+ * Routes:
8
+ * POST /verify → neurcode verify --json
9
+ * POST /fix → neurcode fix --json
10
+ * POST /fix/apply-safe → neurcode fix --apply-safe --json
11
+ * POST /patch → neurcode patch + verify (auto state sync)
12
+ * GET /health → { ok: true, version }
13
+ *
14
+ * Implementation notes:
15
+ * - Uses runCliJson (internal CLI invocation utility) — no raw child_process
16
+ * - Only accepts requests from 127.0.0.1 / ::1 / localhost
17
+ * - All responses use unified shape: { success, data, error? }
18
+ */
19
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
20
+ if (k2 === undefined) k2 = k;
21
+ var desc = Object.getOwnPropertyDescriptor(m, k);
22
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
23
+ desc = { enumerable: true, get: function() { return m[k]; } };
24
+ }
25
+ Object.defineProperty(o, k2, desc);
26
+ }) : (function(o, m, k, k2) {
27
+ if (k2 === undefined) k2 = k;
28
+ o[k2] = m[k];
29
+ }));
30
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
31
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
32
+ }) : function(o, v) {
33
+ o["default"] = v;
34
+ });
35
+ var __importStar = (this && this.__importStar) || (function () {
36
+ var ownKeys = function(o) {
37
+ ownKeys = Object.getOwnPropertyNames || function (o) {
38
+ var ar = [];
39
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
40
+ return ar;
41
+ };
42
+ return ownKeys(o);
43
+ };
44
+ return function (mod) {
45
+ if (mod && mod.__esModule) return mod;
46
+ var result = {};
47
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
48
+ __setModuleDefault(result, mod);
49
+ return result;
50
+ };
51
+ })();
52
+ Object.defineProperty(exports, "__esModule", { value: true });
53
+ exports.DAEMON_HOST = exports.DAEMON_PORT = void 0;
54
+ exports.createDaemonServer = createDaemonServer;
55
+ exports.startDaemon = startDaemon;
56
+ const http = __importStar(require("node:http"));
57
+ const path = __importStar(require("node:path"));
58
+ const fs = __importStar(require("node:fs"));
59
+ const cli_json_1 = require("../utils/cli-json");
60
+ // ── Configuration ──────────────────────────────────────────────────────────────
61
+ exports.DAEMON_PORT = 4321;
62
+ exports.DAEMON_HOST = '127.0.0.1';
63
+ // ── Request helpers ────────────────────────────────────────────────────────────
64
+ function readBody(req) {
65
+ return new Promise((resolve, reject) => {
66
+ const chunks = [];
67
+ req.on('data', (c) => chunks.push(c));
68
+ req.on('end', () => resolve(Buffer.concat(chunks).toString('utf8')));
69
+ req.on('error', reject);
70
+ });
71
+ }
72
+ function send(res, status, body) {
73
+ const payload = JSON.stringify(body);
74
+ res.writeHead(status, {
75
+ 'Content-Type': 'application/json',
76
+ 'Content-Length': Buffer.byteLength(payload),
77
+ });
78
+ res.end(payload);
79
+ }
80
+ function success(res, data) {
81
+ send(res, 200, { success: true, data });
82
+ }
83
+ function failure(res, error, status = 200) {
84
+ send(res, status, { success: false, error });
85
+ }
86
+ function addCorsHeaders(res, origin) {
87
+ const allowedOrigin = origin && /^https?:\/\/(localhost|127\.0\.0\.1)(:\d+)?$/.test(origin)
88
+ ? origin
89
+ : 'http://localhost:3000';
90
+ res.setHeader('Access-Control-Allow-Origin', allowedOrigin);
91
+ res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS');
92
+ res.setHeader('Access-Control-Allow-Headers', 'Content-Type');
93
+ res.setHeader('Access-Control-Max-Age', '86400');
94
+ }
95
+ function isLoopback(req) {
96
+ const addr = req.socket.remoteAddress ?? '';
97
+ return addr === '127.0.0.1' || addr === '::1' || addr === '::ffff:127.0.0.1';
98
+ }
99
+ // ── Route handlers ─────────────────────────────────────────────────────────────
100
+ async function handleVerify(_req, res) {
101
+ const result = await (0, cli_json_1.runCliJson)(['verify']);
102
+ if (!result.payload) {
103
+ failure(res, result.stderr.trim() || 'verify produced no JSON output');
104
+ return;
105
+ }
106
+ success(res, result.payload);
107
+ }
108
+ async function handleFix(_req, res) {
109
+ const result = await (0, cli_json_1.runCliJson)(['fix']);
110
+ if (!result.payload) {
111
+ failure(res, result.stderr.trim() || 'fix produced no JSON output');
112
+ return;
113
+ }
114
+ success(res, result.payload);
115
+ }
116
+ async function handleFixApplySafe(_req, res) {
117
+ const result = await (0, cli_json_1.runCliJson)(['fix', '--apply-safe']);
118
+ if (!result.payload) {
119
+ failure(res, result.stderr.trim() || 'fix --apply-safe produced no JSON output');
120
+ return;
121
+ }
122
+ success(res, result.payload);
123
+ }
124
+ async function handlePatch(req, res) {
125
+ let body = {};
126
+ try {
127
+ body = JSON.parse(await readBody(req));
128
+ }
129
+ catch {
130
+ failure(res, 'Invalid JSON body', 400);
131
+ return;
132
+ }
133
+ const file = body.file;
134
+ if (!file || typeof file !== 'string' || file.includes('..')) {
135
+ failure(res, 'Missing or unsafe "file" field', 400);
136
+ return;
137
+ }
138
+ // Run patch
139
+ const patchResult = await (0, cli_json_1.runCliJson)(['patch', '--file', file]);
140
+ const patchData = patchResult.payload ?? { success: false, file, message: 'No patch output' };
141
+ // Auto state sync: immediately run verify after patch (Part 3)
142
+ const verifyResult = await (0, cli_json_1.runCliJson)(['verify']);
143
+ const verifyData = verifyResult.payload ?? null;
144
+ success(res, { patch: patchData, verify: verifyData });
145
+ }
146
+ // ── Server factory ─────────────────────────────────────────────────────────────
147
+ function createDaemonServer() {
148
+ const server = http.createServer(async (req, res) => {
149
+ addCorsHeaders(res, req.headers.origin);
150
+ if (req.method === 'OPTIONS') {
151
+ res.writeHead(204);
152
+ res.end();
153
+ return;
154
+ }
155
+ if (!isLoopback(req)) {
156
+ failure(res, 'Only localhost connections are allowed', 403);
157
+ return;
158
+ }
159
+ const url = req.url ?? '/';
160
+ const method = req.method ?? 'GET';
161
+ try {
162
+ if (method === 'GET' && url === '/health') {
163
+ let version = '0.0.0';
164
+ try {
165
+ const pkgPath = path.resolve(__dirname, '..', '..', 'package.json');
166
+ version = JSON.parse(fs.readFileSync(pkgPath, 'utf8')).version ?? version;
167
+ }
168
+ catch { /* ignore */ }
169
+ send(res, 200, { ok: true, version, cwd: process.cwd() });
170
+ return;
171
+ }
172
+ if (method === 'POST' && url === '/verify') {
173
+ await handleVerify(req, res);
174
+ return;
175
+ }
176
+ if (method === 'POST' && url === '/fix') {
177
+ await handleFix(req, res);
178
+ return;
179
+ }
180
+ if (method === 'POST' && url === '/fix/apply-safe') {
181
+ await handleFixApplySafe(req, res);
182
+ return;
183
+ }
184
+ if (method === 'POST' && url === '/patch') {
185
+ await handlePatch(req, res);
186
+ return;
187
+ }
188
+ failure(res, `No route for ${method} ${url}`, 404);
189
+ }
190
+ catch (err) {
191
+ failure(res, err instanceof Error ? err.message : String(err), 500);
192
+ }
193
+ });
194
+ return server;
195
+ }
196
+ // ── Start function ─────────────────────────────────────────────────────────────
197
+ function startDaemon() {
198
+ const server = createDaemonServer();
199
+ server.on('error', (err) => {
200
+ if (err.code === 'EADDRINUSE') {
201
+ console.error(`\n❌ Port ${exports.DAEMON_PORT} is already in use.\n` +
202
+ ` Another Neurcode daemon may already be running.\n` +
203
+ ` Check with: lsof -i :${exports.DAEMON_PORT}\n`);
204
+ }
205
+ else {
206
+ console.error(`\n❌ Daemon error: ${err.message}\n`);
207
+ }
208
+ process.exit(1);
209
+ });
210
+ server.listen(exports.DAEMON_PORT, exports.DAEMON_HOST, () => {
211
+ console.log(`\nNeurcode daemon v2 running on http://localhost:${exports.DAEMON_PORT}`);
212
+ console.log(` POST /verify → neurcode verify --json`);
213
+ console.log(` POST /fix → neurcode fix --json`);
214
+ console.log(` POST /fix/apply-safe → neurcode fix --apply-safe --json`);
215
+ console.log(` POST /patch → neurcode patch + auto-verify`);
216
+ console.log(`\n CWD: ${process.cwd()}`);
217
+ console.log(` Press Ctrl+C to stop.\n`);
218
+ });
219
+ process.on('SIGINT', () => { server.close(() => { console.log('\nNeurcode daemon stopped.'); process.exit(0); }); });
220
+ process.on('SIGTERM', () => { server.close(() => process.exit(0)); });
221
+ }
222
+ //# sourceMappingURL=server.js.map