projscan 1.7.0 → 1.8.0

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 (56) hide show
  1. package/dist/core/applyFix.js +5 -46
  2. package/dist/core/applyFix.js.map +1 -1
  3. package/dist/core/embeddings.d.ts +9 -0
  4. package/dist/core/embeddings.js +45 -5
  5. package/dist/core/embeddings.js.map +1 -1
  6. package/dist/core/languages/LanguageAdapter.d.ts +1 -1
  7. package/dist/core/languages/cppFunctions.js +40 -1
  8. package/dist/core/languages/cppFunctions.js.map +1 -1
  9. package/dist/core/languages/registry.js +2 -0
  10. package/dist/core/languages/registry.js.map +1 -1
  11. package/dist/core/languages/swiftAdapter.d.ts +2 -0
  12. package/dist/core/languages/swiftAdapter.js +130 -0
  13. package/dist/core/languages/swiftAdapter.js.map +1 -0
  14. package/dist/core/languages/swiftCallSites.d.ts +14 -0
  15. package/dist/core/languages/swiftCallSites.js +60 -0
  16. package/dist/core/languages/swiftCallSites.js.map +1 -0
  17. package/dist/core/languages/swiftCyclomatic.d.ts +24 -0
  18. package/dist/core/languages/swiftCyclomatic.js +54 -0
  19. package/dist/core/languages/swiftCyclomatic.js.map +1 -0
  20. package/dist/core/languages/swiftExports.d.ts +13 -0
  21. package/dist/core/languages/swiftExports.js +95 -0
  22. package/dist/core/languages/swiftExports.js.map +1 -0
  23. package/dist/core/languages/swiftFunctions.d.ts +28 -0
  24. package/dist/core/languages/swiftFunctions.js +162 -0
  25. package/dist/core/languages/swiftFunctions.js.map +1 -0
  26. package/dist/core/languages/swiftImports.d.ts +26 -0
  27. package/dist/core/languages/swiftImports.js +45 -0
  28. package/dist/core/languages/swiftImports.js.map +1 -0
  29. package/dist/core/languages/swiftManifests.d.ts +17 -0
  30. package/dist/core/languages/swiftManifests.js +49 -0
  31. package/dist/core/languages/swiftManifests.js.map +1 -0
  32. package/dist/core/languages/treeSitterLoader.js +2 -0
  33. package/dist/core/languages/treeSitterLoader.js.map +1 -1
  34. package/dist/core/session.d.ts +18 -4
  35. package/dist/core/session.js +20 -5
  36. package/dist/core/session.js.map +1 -1
  37. package/dist/core/taint.d.ts +17 -0
  38. package/dist/core/taint.js +19 -1
  39. package/dist/core/taint.js.map +1 -1
  40. package/dist/grammars/tree-sitter-swift.wasm +0 -0
  41. package/dist/mcp/server.js +60 -1
  42. package/dist/mcp/server.js.map +1 -1
  43. package/dist/mcp/tools/_shared.d.ts +25 -1
  44. package/dist/mcp/tools/_shared.js.map +1 -1
  45. package/dist/mcp/tools/costSummary.js +12 -3
  46. package/dist/mcp/tools/costSummary.js.map +1 -1
  47. package/dist/mcp/tools/reviewWatch.d.ts +7 -0
  48. package/dist/mcp/tools/reviewWatch.js +228 -0
  49. package/dist/mcp/tools/reviewWatch.js.map +1 -0
  50. package/dist/mcp/tools.js +2 -0
  51. package/dist/mcp/tools.js.map +1 -1
  52. package/dist/tool-manifest.json +37 -3
  53. package/dist/utils/atomicWrite.d.ts +26 -0
  54. package/dist/utils/atomicWrite.js +69 -0
  55. package/dist/utils/atomicWrite.js.map +1 -0
  56. package/package.json +3 -2
@@ -0,0 +1 @@
1
+ {"version":3,"file":"swiftCyclomatic.js","sourceRoot":"","sources":["../../../src/core/languages/swiftCyclomatic.ts"],"names":[],"mappings":"AAMA;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,UAAU,sBAAsB,CAAC,IAAY;IACjD,IAAI,SAAS,GAAG,CAAC,CAAC;IAClB,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,EAAE,EAAE;QACf,IAAI,eAAe,CAAC,CAAC,CAAC;YAAE,SAAS,EAAE,CAAC;IACtC,CAAC,CAAC,CAAC;IACH,OAAO,SAAS,GAAG,CAAC,CAAC;AACvB,CAAC;AAED,SAAS,eAAe,CAAC,CAAS;IAChC,QAAQ,CAAC,CAAC,IAAI,EAAE,CAAC;QACf,KAAK,cAAc,CAAC;QACpB,KAAK,iBAAiB,CAAC;QACvB,KAAK,eAAe,CAAC;QACrB,KAAK,iBAAiB,CAAC;QACvB,KAAK,wBAAwB,CAAC;QAC9B,KAAK,cAAc,CAAC;QACpB,KAAK,aAAa,CAAC;QACnB,KAAK,cAAc,CAAC;QACpB,KAAK,wBAAwB,CAAC;QAC9B,KAAK,wBAAwB;YAC3B,OAAO,IAAI,CAAC;QACd,KAAK,cAAc,CAAC,CAAC,CAAC;YACpB,wEAAwE;YACxE,sEAAsE;YACtE,MAAM,SAAS,GAAG,CAAC,CAAC,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,gBAAgB,IAAI,CAAC,CAAC,IAAI,KAAK,YAAY,CAAC,CAAC;YACvG,OAAO,CAAC,SAAS,CAAC;QACpB,CAAC;QACD;YACE,OAAO,KAAK,CAAC;IACjB,CAAC;AACH,CAAC;AAED,SAAS,IAAI,CAAC,IAAY,EAAE,KAA0B;IACpD,KAAK,CAAC,IAAI,CAAC,CAAC;IACZ,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,aAAa;QAAE,IAAI,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;AAC7D,CAAC"}
@@ -0,0 +1,13 @@
1
+ import type { AstExport } from '../ast.js';
2
+ interface TsNode {
3
+ type: string;
4
+ text: string;
5
+ startPosition: {
6
+ row: number;
7
+ column: number;
8
+ };
9
+ namedChildren: TsNode[];
10
+ childForFieldName?: (name: string) => TsNode | null;
11
+ }
12
+ export declare function extractSwiftExports(root: TsNode): AstExport[];
13
+ export {};
@@ -0,0 +1,95 @@
1
+ /**
2
+ * Extract Swift top-level declarations as exports. Swift's default
3
+ * visibility is `internal` (visible within the module). For graph
4
+ * purposes we treat everything that is NOT explicitly `private` or
5
+ * `fileprivate` as exported — module-internal symbols still participate
6
+ * in cross-file resolution within the module.
7
+ *
8
+ * Kinds:
9
+ * func foo() → function
10
+ * class Foo / struct Foo → class
11
+ * protocol Foo → interface
12
+ * enum Color → enum
13
+ * typealias Bar = ... → type
14
+ * let / var x → variable
15
+ * actor Foo → class
16
+ */
17
+ const EXPORT_NODE_TO_KIND = {
18
+ function_declaration: 'function',
19
+ class_declaration: 'class',
20
+ protocol_declaration: 'interface',
21
+ typealias_declaration: 'type',
22
+ property_declaration: 'variable',
23
+ };
24
+ export function extractSwiftExports(root) {
25
+ const exports = [];
26
+ for (const child of root.namedChildren) {
27
+ visitTopLevel(child, exports);
28
+ }
29
+ return exports;
30
+ }
31
+ function visitTopLevel(node, out) {
32
+ if (node.type === 'class_declaration') {
33
+ if (isHidden(node))
34
+ return;
35
+ const name = nameOf(node);
36
+ if (!name)
37
+ return;
38
+ const head = headerText(node);
39
+ let kind = 'class';
40
+ if (/\benum\b/.test(head))
41
+ kind = 'enum';
42
+ out.push({ name, kind, typeOnly: false, line: node.startPosition.row + 1 });
43
+ return;
44
+ }
45
+ const kind = EXPORT_NODE_TO_KIND[node.type];
46
+ if (!kind) {
47
+ for (const c of node.namedChildren)
48
+ visitTopLevel(c, out);
49
+ return;
50
+ }
51
+ if (isHidden(node))
52
+ return;
53
+ const name = nameOf(node);
54
+ if (!name)
55
+ return;
56
+ out.push({ name, kind, typeOnly: false, line: node.startPosition.row + 1 });
57
+ }
58
+ function headerText(node) {
59
+ const idx = node.text.indexOf('{');
60
+ return idx >= 0 ? node.text.slice(0, idx) : node.text;
61
+ }
62
+ function isHidden(node) {
63
+ for (const c of node.namedChildren) {
64
+ if (c.type === 'modifiers' || c.type === 'modifier_list') {
65
+ for (const m of c.namedChildren) {
66
+ const t = m.text.trim();
67
+ if (t === 'private' || t === 'fileprivate')
68
+ return true;
69
+ }
70
+ }
71
+ if (c.type === 'visibility_modifier') {
72
+ const t = c.text.trim();
73
+ if (t === 'private' || t === 'fileprivate')
74
+ return true;
75
+ }
76
+ }
77
+ return false;
78
+ }
79
+ function nameOf(node) {
80
+ if (node.childForFieldName) {
81
+ const id = node.childForFieldName('name');
82
+ if (id && id.text)
83
+ return id.text;
84
+ }
85
+ for (const c of node.namedChildren) {
86
+ if (c.type === 'simple_identifier' || c.type === 'identifier' || c.type === 'type_identifier') {
87
+ return c.text;
88
+ }
89
+ }
90
+ const m = /\b(let|var)\s+([A-Za-z_][A-Za-z0-9_]*)/.exec(node.text);
91
+ if (m)
92
+ return m[2];
93
+ return null;
94
+ }
95
+ //# sourceMappingURL=swiftExports.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"swiftExports.js","sourceRoot":"","sources":["../../../src/core/languages/swiftExports.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,28 @@
1
+ import type { FunctionInfo } from '../ast.js';
2
+ interface TsNode {
3
+ type: string;
4
+ text: string;
5
+ startPosition: {
6
+ row: number;
7
+ column: number;
8
+ };
9
+ endPosition: {
10
+ row: number;
11
+ column: number;
12
+ };
13
+ namedChildren: TsNode[];
14
+ childForFieldName?: (name: string) => TsNode | null;
15
+ }
16
+ /**
17
+ * Per-function McCabe CC for Swift. Walks `function_declaration` nodes
18
+ * (top-level + class/struct/protocol/extension methods). Methods inside
19
+ * `class Foo { func m() }` are named `Foo.m`. Closures and trailing-closure
20
+ * blocks aren't extracted as separate functions; their decision points
21
+ * fold into the enclosing function (matches projscan's convention for
22
+ * Rust closures and Go func literals).
23
+ *
24
+ * `switch` cases each count as +1; the `default` arm does not. Optional
25
+ * chaining (`?.`) and nil-coalescing (`??`) are NOT counted.
26
+ */
27
+ export declare function extractSwiftFunctions(root: TsNode): FunctionInfo[];
28
+ export {};
@@ -0,0 +1,162 @@
1
+ const SWIFT_DECISION_NODES = new Set([
2
+ 'if_statement',
3
+ 'guard_statement',
4
+ 'for_statement',
5
+ 'while_statement',
6
+ 'repeat_while_statement',
7
+ 'do_statement',
8
+ 'catch_block',
9
+ 'catch_clause',
10
+ ]);
11
+ /**
12
+ * Per-function McCabe CC for Swift. Walks `function_declaration` nodes
13
+ * (top-level + class/struct/protocol/extension methods). Methods inside
14
+ * `class Foo { func m() }` are named `Foo.m`. Closures and trailing-closure
15
+ * blocks aren't extracted as separate functions; their decision points
16
+ * fold into the enclosing function (matches projscan's convention for
17
+ * Rust closures and Go func literals).
18
+ *
19
+ * `switch` cases each count as +1; the `default` arm does not. Optional
20
+ * chaining (`?.`) and nil-coalescing (`??`) are NOT counted.
21
+ */
22
+ export function extractSwiftFunctions(root) {
23
+ const out = [];
24
+ walk(root, null, out);
25
+ return out;
26
+ }
27
+ function walk(node, ownerName, out) {
28
+ if (node.type === 'class_declaration' ||
29
+ node.type === 'protocol_declaration' ||
30
+ node.type === 'extension_declaration') {
31
+ const name = nameOfDecl(node) ?? ownerName;
32
+ const body = bodyOf(node);
33
+ if (body) {
34
+ for (const child of body.namedChildren)
35
+ walk(child, name, out);
36
+ }
37
+ return;
38
+ }
39
+ if (node.type === 'function_declaration' ||
40
+ node.type === 'init_declaration' ||
41
+ node.type === 'deinit_declaration' ||
42
+ node.type === 'subscript_declaration') {
43
+ let baseName;
44
+ if (node.type === 'init_declaration')
45
+ baseName = 'init';
46
+ else if (node.type === 'deinit_declaration')
47
+ baseName = 'deinit';
48
+ else if (node.type === 'subscript_declaration')
49
+ baseName = 'subscript';
50
+ else
51
+ baseName = nameOfDecl(node) ?? '<anonymous>';
52
+ const fnName = ownerName ? `${ownerName}.${baseName}` : baseName;
53
+ const line = node.startPosition.row + 1;
54
+ const endLine = node.endPosition.row + 1;
55
+ const { cc, callSites } = analyzeBody(node);
56
+ out.push({ name: fnName, line, endLine, cyclomaticComplexity: cc, callSites });
57
+ return;
58
+ }
59
+ for (const child of node.namedChildren)
60
+ walk(child, ownerName, out);
61
+ }
62
+ function nameOfDecl(node) {
63
+ if (node.childForFieldName) {
64
+ const id = node.childForFieldName('name');
65
+ if (id && id.text)
66
+ return id.text;
67
+ }
68
+ for (const c of node.namedChildren) {
69
+ if (c.type === 'simple_identifier' || c.type === 'identifier' || c.type === 'type_identifier') {
70
+ return c.text;
71
+ }
72
+ }
73
+ return null;
74
+ }
75
+ function bodyOf(node) {
76
+ if (node.childForFieldName) {
77
+ const b = node.childForFieldName('body');
78
+ if (b)
79
+ return b;
80
+ }
81
+ for (const c of node.namedChildren) {
82
+ if (c.type === 'class_body' ||
83
+ c.type === 'protocol_body' ||
84
+ c.type === 'function_body' ||
85
+ c.type === 'extension_body') {
86
+ return c;
87
+ }
88
+ }
89
+ return null;
90
+ }
91
+ function analyzeBody(fnNode) {
92
+ let count = 0;
93
+ const calls = new Set();
94
+ const body = bodyOf(fnNode);
95
+ if (!body)
96
+ return { cc: 1, callSites: [] };
97
+ walkSkipNested(body, (n) => {
98
+ if (SWIFT_DECISION_NODES.has(n.type)) {
99
+ count++;
100
+ return;
101
+ }
102
+ if (n.type === 'switch_entry') {
103
+ // The default arm has no value child (no case_label patterns) — non-
104
+ // default arms always carry one or more case_label / case_pattern
105
+ // children. Mirrors the kotlin/cpp structural-detection approach.
106
+ const isDefault = !n.namedChildren.some((c) => c.type === 'switch_pattern' || c.type === 'case_label');
107
+ if (!isDefault)
108
+ count++;
109
+ return;
110
+ }
111
+ if (n.type === 'conjunction_expression' || n.type === 'disjunction_expression') {
112
+ count++;
113
+ return;
114
+ }
115
+ if (n.type === 'call_expression') {
116
+ const fn = n.childForFieldName ? n.childForFieldName('function') : n.namedChildren[0] ?? null;
117
+ const name = bareName(fn);
118
+ if (name)
119
+ calls.add(name);
120
+ }
121
+ });
122
+ return { cc: count + 1, callSites: [...calls] };
123
+ }
124
+ function bareName(node) {
125
+ if (!node)
126
+ return null;
127
+ switch (node.type) {
128
+ case 'simple_identifier':
129
+ case 'identifier':
130
+ case 'type_identifier':
131
+ return node.text;
132
+ case 'navigation_expression': {
133
+ const last = node.namedChildren[node.namedChildren.length - 1];
134
+ return last ? bareName(last) : null;
135
+ }
136
+ case 'navigation_suffix': {
137
+ for (const c of node.namedChildren) {
138
+ const n = bareName(c);
139
+ if (n)
140
+ return n;
141
+ }
142
+ return null;
143
+ }
144
+ default:
145
+ return null;
146
+ }
147
+ }
148
+ function walkSkipNested(node, visit) {
149
+ visit(node);
150
+ for (const child of node.namedChildren) {
151
+ if (child.type === 'function_declaration' ||
152
+ child.type === 'init_declaration' ||
153
+ child.type === 'class_declaration' ||
154
+ child.type === 'protocol_declaration' ||
155
+ child.type === 'lambda_literal' ||
156
+ child.type === 'closure_expression') {
157
+ continue;
158
+ }
159
+ walkSkipNested(child, visit);
160
+ }
161
+ }
162
+ //# sourceMappingURL=swiftFunctions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"swiftFunctions.js","sourceRoot":"","sources":["../../../src/core/languages/swiftFunctions.ts"],"names":[],"mappings":"AAWA,MAAM,oBAAoB,GAAG,IAAI,GAAG,CAAC;IACnC,cAAc;IACd,iBAAiB;IACjB,eAAe;IACf,iBAAiB;IACjB,wBAAwB;IACxB,cAAc;IACd,aAAa;IACb,cAAc;CACf,CAAC,CAAC;AAEH;;;;;;;;;;GAUG;AACH,MAAM,UAAU,qBAAqB,CAAC,IAAY;IAChD,MAAM,GAAG,GAAmB,EAAE,CAAC;IAC/B,IAAI,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,CAAC,CAAC;IACtB,OAAO,GAAG,CAAC;AACb,CAAC;AAED,SAAS,IAAI,CAAC,IAAY,EAAE,SAAwB,EAAE,GAAmB;IACvE,IACE,IAAI,CAAC,IAAI,KAAK,mBAAmB;QACjC,IAAI,CAAC,IAAI,KAAK,sBAAsB;QACpC,IAAI,CAAC,IAAI,KAAK,uBAAuB,EACrC,CAAC;QACD,MAAM,IAAI,GAAG,UAAU,CAAC,IAAI,CAAC,IAAI,SAAS,CAAC;QAC3C,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC;QAC1B,IAAI,IAAI,EAAE,CAAC;YACT,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,aAAa;gBAAE,IAAI,CAAC,KAAK,EAAE,IAAI,EAAE,GAAG,CAAC,CAAC;QACjE,CAAC;QACD,OAAO;IACT,CAAC;IAED,IACE,IAAI,CAAC,IAAI,KAAK,sBAAsB;QACpC,IAAI,CAAC,IAAI,KAAK,kBAAkB;QAChC,IAAI,CAAC,IAAI,KAAK,oBAAoB;QAClC,IAAI,CAAC,IAAI,KAAK,uBAAuB,EACrC,CAAC;QACD,IAAI,QAAgB,CAAC;QACrB,IAAI,IAAI,CAAC,IAAI,KAAK,kBAAkB;YAAE,QAAQ,GAAG,MAAM,CAAC;aACnD,IAAI,IAAI,CAAC,IAAI,KAAK,oBAAoB;YAAE,QAAQ,GAAG,QAAQ,CAAC;aAC5D,IAAI,IAAI,CAAC,IAAI,KAAK,uBAAuB;YAAE,QAAQ,GAAG,WAAW,CAAC;;YAClE,QAAQ,GAAG,UAAU,CAAC,IAAI,CAAC,IAAI,aAAa,CAAC;QAClD,MAAM,MAAM,GAAG,SAAS,CAAC,CAAC,CAAC,GAAG,SAAS,IAAI,QAAQ,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC;QACjE,MAAM,IAAI,GAAG,IAAI,CAAC,aAAa,CAAC,GAAG,GAAG,CAAC,CAAC;QACxC,MAAM,OAAO,GAAG,IAAI,CAAC,WAAW,CAAC,GAAG,GAAG,CAAC,CAAC;QACzC,MAAM,EAAE,EAAE,EAAE,SAAS,EAAE,GAAG,WAAW,CAAC,IAAI,CAAC,CAAC;QAC5C,GAAG,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,oBAAoB,EAAE,EAAE,EAAE,SAAS,EAAE,CAAC,CAAC;QAC/E,OAAO;IACT,CAAC;IAED,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,aAAa;QAAE,IAAI,CAAC,KAAK,EAAE,SAAS,EAAE,GAAG,CAAC,CAAC;AACtE,CAAC;AAED,SAAS,UAAU,CAAC,IAAY;IAC9B,IAAI,IAAI,CAAC,iBAAiB,EAAE,CAAC;QAC3B,MAAM,EAAE,GAAG,IAAI,CAAC,iBAAiB,CAAC,MAAM,CAAC,CAAC;QAC1C,IAAI,EAAE,IAAI,EAAE,CAAC,IAAI;YAAE,OAAO,EAAE,CAAC,IAAI,CAAC;IACpC,CAAC;IACD,KAAK,MAAM,CAAC,IAAI,IAAI,CAAC,aAAa,EAAE,CAAC;QACnC,IAAI,CAAC,CAAC,IAAI,KAAK,mBAAmB,IAAI,CAAC,CAAC,IAAI,KAAK,YAAY,IAAI,CAAC,CAAC,IAAI,KAAK,iBAAiB,EAAE,CAAC;YAC9F,OAAO,CAAC,CAAC,IAAI,CAAC;QAChB,CAAC;IACH,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,SAAS,MAAM,CAAC,IAAY;IAC1B,IAAI,IAAI,CAAC,iBAAiB,EAAE,CAAC;QAC3B,MAAM,CAAC,GAAG,IAAI,CAAC,iBAAiB,CAAC,MAAM,CAAC,CAAC;QACzC,IAAI,CAAC;YAAE,OAAO,CAAC,CAAC;IAClB,CAAC;IACD,KAAK,MAAM,CAAC,IAAI,IAAI,CAAC,aAAa,EAAE,CAAC;QACnC,IACE,CAAC,CAAC,IAAI,KAAK,YAAY;YACvB,CAAC,CAAC,IAAI,KAAK,eAAe;YAC1B,CAAC,CAAC,IAAI,KAAK,eAAe;YAC1B,CAAC,CAAC,IAAI,KAAK,gBAAgB,EAC3B,CAAC;YACD,OAAO,CAAC,CAAC;QACX,CAAC;IACH,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,SAAS,WAAW,CAAC,MAAc;IACjC,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,MAAM,KAAK,GAAG,IAAI,GAAG,EAAU,CAAC;IAChC,MAAM,IAAI,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC;IAC5B,IAAI,CAAC,IAAI;QAAE,OAAO,EAAE,EAAE,EAAE,CAAC,EAAE,SAAS,EAAE,EAAE,EAAE,CAAC;IAC3C,cAAc,CAAC,IAAI,EAAE,CAAC,CAAC,EAAE,EAAE;QACzB,IAAI,oBAAoB,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC;YACrC,KAAK,EAAE,CAAC;YACR,OAAO;QACT,CAAC;QACD,IAAI,CAAC,CAAC,IAAI,KAAK,cAAc,EAAE,CAAC;YAC9B,qEAAqE;YACrE,kEAAkE;YAClE,kEAAkE;YAClE,MAAM,SAAS,GAAG,CAAC,CAAC,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,gBAAgB,IAAI,CAAC,CAAC,IAAI,KAAK,YAAY,CAAC,CAAC;YACvG,IAAI,CAAC,SAAS;gBAAE,KAAK,EAAE,CAAC;YACxB,OAAO;QACT,CAAC;QACD,IAAI,CAAC,CAAC,IAAI,KAAK,wBAAwB,IAAI,CAAC,CAAC,IAAI,KAAK,wBAAwB,EAAE,CAAC;YAC/E,KAAK,EAAE,CAAC;YACR,OAAO;QACT,CAAC;QACD,IAAI,CAAC,CAAC,IAAI,KAAK,iBAAiB,EAAE,CAAC;YACjC,MAAM,EAAE,GAAG,CAAC,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC,CAAC,iBAAiB,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC;YAC9F,MAAM,IAAI,GAAG,QAAQ,CAAC,EAAE,CAAC,CAAC;YAC1B,IAAI,IAAI;gBAAE,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAC5B,CAAC;IACH,CAAC,CAAC,CAAC;IACH,OAAO,EAAE,EAAE,EAAE,KAAK,GAAG,CAAC,EAAE,SAAS,EAAE,CAAC,GAAG,KAAK,CAAC,EAAE,CAAC;AAClD,CAAC;AAED,SAAS,QAAQ,CAAC,IAAmB;IACnC,IAAI,CAAC,IAAI;QAAE,OAAO,IAAI,CAAC;IACvB,QAAQ,IAAI,CAAC,IAAI,EAAE,CAAC;QAClB,KAAK,mBAAmB,CAAC;QACzB,KAAK,YAAY,CAAC;QAClB,KAAK,iBAAiB;YACpB,OAAO,IAAI,CAAC,IAAI,CAAC;QACnB,KAAK,uBAAuB,CAAC,CAAC,CAAC;YAC7B,MAAM,IAAI,GAAG,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,aAAa,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;YAC/D,OAAO,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;QACtC,CAAC;QACD,KAAK,mBAAmB,CAAC,CAAC,CAAC;YACzB,KAAK,MAAM,CAAC,IAAI,IAAI,CAAC,aAAa,EAAE,CAAC;gBACnC,MAAM,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC;gBACtB,IAAI,CAAC;oBAAE,OAAO,CAAC,CAAC;YAClB,CAAC;YACD,OAAO,IAAI,CAAC;QACd,CAAC;QACD;YACE,OAAO,IAAI,CAAC;IAChB,CAAC;AACH,CAAC;AAED,SAAS,cAAc,CAAC,IAAY,EAAE,KAA0B;IAC9D,KAAK,CAAC,IAAI,CAAC,CAAC;IACZ,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,aAAa,EAAE,CAAC;QACvC,IACE,KAAK,CAAC,IAAI,KAAK,sBAAsB;YACrC,KAAK,CAAC,IAAI,KAAK,kBAAkB;YACjC,KAAK,CAAC,IAAI,KAAK,mBAAmB;YAClC,KAAK,CAAC,IAAI,KAAK,sBAAsB;YACrC,KAAK,CAAC,IAAI,KAAK,gBAAgB;YAC/B,KAAK,CAAC,IAAI,KAAK,oBAAoB,EACnC,CAAC;YACD,SAAS;QACX,CAAC;QACD,cAAc,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;IAC/B,CAAC;AACH,CAAC"}
@@ -0,0 +1,26 @@
1
+ import type { AstImport } from '../ast.js';
2
+ interface TsNode {
3
+ type: string;
4
+ text: string;
5
+ startPosition: {
6
+ row: number;
7
+ column: number;
8
+ };
9
+ namedChildren: TsNode[];
10
+ childForFieldName?: (name: string) => TsNode | null;
11
+ }
12
+ /**
13
+ * Extract Swift `import` statements from a tree-sitter-swift AST.
14
+ *
15
+ * Handled forms:
16
+ * import Foundation → source = "Foundation"
17
+ * import struct Foo.Bar → source = "Foo.Bar"
18
+ * import class Foo.Bar.Baz → source = "Foo.Bar.Baz"
19
+ * @testable import MyModule → source = "MyModule"
20
+ * @_implementationOnly import Private → source = "Private"
21
+ *
22
+ * Swift modules don't expose individual symbols at import time the way
23
+ * JS named imports do; the import binds the whole module / submodule.
24
+ */
25
+ export declare function extractSwiftImports(root: TsNode): AstImport[];
26
+ export {};
@@ -0,0 +1,45 @@
1
+ /**
2
+ * Extract Swift `import` statements from a tree-sitter-swift AST.
3
+ *
4
+ * Handled forms:
5
+ * import Foundation → source = "Foundation"
6
+ * import struct Foo.Bar → source = "Foo.Bar"
7
+ * import class Foo.Bar.Baz → source = "Foo.Bar.Baz"
8
+ * @testable import MyModule → source = "MyModule"
9
+ * @_implementationOnly import Private → source = "Private"
10
+ *
11
+ * Swift modules don't expose individual symbols at import time the way
12
+ * JS named imports do; the import binds the whole module / submodule.
13
+ */
14
+ export function extractSwiftImports(root) {
15
+ const imports = [];
16
+ walk(root, (n) => {
17
+ if (n.type !== 'import_declaration')
18
+ return;
19
+ const source = readImportPath(n);
20
+ if (!source)
21
+ return;
22
+ imports.push({
23
+ source,
24
+ kind: 'static',
25
+ specifiers: [],
26
+ typeOnly: false,
27
+ line: n.startPosition.row + 1,
28
+ });
29
+ });
30
+ return imports;
31
+ }
32
+ function readImportPath(node) {
33
+ const text = node.text.trim();
34
+ let body = text.replace(/^\s*(@[A-Za-z_][\w]*\s*)+/, '');
35
+ body = body.replace(/^\s*import\b/, '').trim();
36
+ body = body.replace(/^(typealias|struct|class|enum|protocol|let|var|func)\b\s*/, '');
37
+ const m = /^[A-Za-z_][\w.]*/.exec(body);
38
+ return m ? m[0] : '';
39
+ }
40
+ function walk(node, visit) {
41
+ visit(node);
42
+ for (const child of node.namedChildren)
43
+ walk(child, visit);
44
+ }
45
+ //# sourceMappingURL=swiftImports.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"swiftImports.js","sourceRoot":"","sources":["../../../src/core/languages/swiftImports.ts"],"names":[],"mappings":"AAUA;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,mBAAmB,CAAC,IAAY;IAC9C,MAAM,OAAO,GAAgB,EAAE,CAAC;IAChC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,EAAE,EAAE;QACf,IAAI,CAAC,CAAC,IAAI,KAAK,oBAAoB;YAAE,OAAO;QAC5C,MAAM,MAAM,GAAG,cAAc,CAAC,CAAC,CAAC,CAAC;QACjC,IAAI,CAAC,MAAM;YAAE,OAAO;QACpB,OAAO,CAAC,IAAI,CAAC;YACX,MAAM;YACN,IAAI,EAAE,QAAQ;YACd,UAAU,EAAE,EAAE;YACd,QAAQ,EAAE,KAAK;YACf,IAAI,EAAE,CAAC,CAAC,aAAa,CAAC,GAAG,GAAG,CAAC;SAC9B,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IACH,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,SAAS,cAAc,CAAC,IAAY;IAClC,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;IAC9B,IAAI,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,2BAA2B,EAAE,EAAE,CAAC,CAAC;IACzD,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,cAAc,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;IAC/C,IAAI,GAAG,IAAI,CAAC,OAAO,CACjB,2DAA2D,EAC3D,EAAE,CACH,CAAC;IACF,MAAM,CAAC,GAAG,kBAAkB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACxC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;AACvB,CAAC;AAED,SAAS,IAAI,CAAC,IAAY,EAAE,KAA0B;IACpD,KAAK,CAAC,IAAI,CAAC,CAAC;IACZ,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,aAAa;QAAE,IAAI,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;AAC7D,CAAC"}
@@ -0,0 +1,17 @@
1
+ import type { FileEntry } from '../../types.js';
2
+ export interface SwiftProjectInfo {
3
+ /**
4
+ * Detected Swift source roots. For SwiftPM projects this is typically
5
+ * `Sources/<Module>` per declared target; we fall back to the conventional
6
+ * `Sources/` and the repo root when no Package.swift exists.
7
+ */
8
+ packageRoots: string[];
9
+ /** Did we see a Package.swift / .xcodeproj manifest? Used for diagnostics only. */
10
+ hasManifest: boolean;
11
+ }
12
+ /**
13
+ * Detect Swift source roots. We don't parse Package.swift; instead we
14
+ * survey the .swift file paths and pick whichever conventional roots
15
+ * actually contain Swift sources.
16
+ */
17
+ export declare function detectSwiftProject(rootPath: string, files: FileEntry[]): Promise<SwiftProjectInfo | null>;
@@ -0,0 +1,49 @@
1
+ import fs from 'node:fs/promises';
2
+ import path from 'node:path';
3
+ const COMMON_SWIFT_ROOTS = ['Sources', 'Tests', '.'];
4
+ /**
5
+ * Detect Swift source roots. We don't parse Package.swift; instead we
6
+ * survey the .swift file paths and pick whichever conventional roots
7
+ * actually contain Swift sources.
8
+ */
9
+ export async function detectSwiftProject(rootPath, files) {
10
+ const swiftFiles = files.filter((f) => f.relativePath.endsWith('.swift'));
11
+ if (swiftFiles.length === 0)
12
+ return null;
13
+ const hasManifest = await hasSwiftManifest(rootPath);
14
+ const packageRoots = [];
15
+ for (const candidate of COMMON_SWIFT_ROOTS) {
16
+ if (candidate === '.') {
17
+ if (swiftFiles.some((f) => !f.relativePath.includes('/')))
18
+ packageRoots.push('.');
19
+ }
20
+ else if (swiftFiles.some((f) => f.relativePath.startsWith(candidate + '/'))) {
21
+ packageRoots.push(candidate);
22
+ }
23
+ }
24
+ if (packageRoots.length === 0)
25
+ packageRoots.push('.');
26
+ return { packageRoots, hasManifest };
27
+ }
28
+ async function hasSwiftManifest(rootPath) {
29
+ const candidates = ['Package.swift', 'Package.resolved'];
30
+ for (const c of candidates) {
31
+ try {
32
+ await fs.access(path.join(rootPath, c));
33
+ return true;
34
+ }
35
+ catch {
36
+ // try next
37
+ }
38
+ }
39
+ try {
40
+ const entries = await fs.readdir(rootPath, { withFileTypes: true });
41
+ if (entries.some((e) => e.isDirectory() && e.name.endsWith('.xcodeproj')))
42
+ return true;
43
+ }
44
+ catch {
45
+ // ignore
46
+ }
47
+ return false;
48
+ }
49
+ //# sourceMappingURL=swiftManifests.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"swiftManifests.js","sourceRoot":"","sources":["../../../src/core/languages/swiftManifests.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAClC,OAAO,IAAI,MAAM,WAAW,CAAC;AAc7B,MAAM,kBAAkB,GAAG,CAAC,SAAS,EAAE,OAAO,EAAE,GAAG,CAAC,CAAC;AAErD;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,kBAAkB,CACtC,QAAgB,EAChB,KAAkB;IAElB,MAAM,UAAU,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,YAAY,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC;IAC1E,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IAEzC,MAAM,WAAW,GAAG,MAAM,gBAAgB,CAAC,QAAQ,CAAC,CAAC;IACrD,MAAM,YAAY,GAAa,EAAE,CAAC;IAClC,KAAK,MAAM,SAAS,IAAI,kBAAkB,EAAE,CAAC;QAC3C,IAAI,SAAS,KAAK,GAAG,EAAE,CAAC;YACtB,IAAI,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;gBAAE,YAAY,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACpF,CAAC;aAAM,IAAI,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,YAAY,CAAC,UAAU,CAAC,SAAS,GAAG,GAAG,CAAC,CAAC,EAAE,CAAC;YAC9E,YAAY,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QAC/B,CAAC;IACH,CAAC;IACD,IAAI,YAAY,CAAC,MAAM,KAAK,CAAC;QAAE,YAAY,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACtD,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,CAAC;AACvC,CAAC;AAED,KAAK,UAAU,gBAAgB,CAAC,QAAgB;IAC9C,MAAM,UAAU,GAAG,CAAC,eAAe,EAAE,kBAAkB,CAAC,CAAC;IACzD,KAAK,MAAM,CAAC,IAAI,UAAU,EAAE,CAAC;QAC3B,IAAI,CAAC;YACH,MAAM,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,CAAC;YACxC,OAAO,IAAI,CAAC;QACd,CAAC;QAAC,MAAM,CAAC;YACP,WAAW;QACb,CAAC;IACH,CAAC;IACD,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,MAAM,EAAE,CAAC,OAAO,CAAC,QAAQ,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC;QACpE,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,EAAE,IAAI,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAC;YAAE,OAAO,IAAI,CAAC;IACzF,CAAC;IAAC,MAAM,CAAC;QACP,SAAS;IACX,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC"}
@@ -33,6 +33,7 @@ function grammarDirs() {
33
33
  // ensureBuiltWasm). At test time (vitest running off src/) the wasm
34
34
  // sits inside the package directory, so probe it there too.
35
35
  const nodeModulesKotlin = path.join(repoRoot, 'node_modules', 'tree-sitter-kotlin');
36
+ const nodeModulesSwift = path.join(repoRoot, 'node_modules', 'tree-sitter-swift');
36
37
  const nodeModulesCpp = path.join(repoRoot, 'node_modules', 'tree-sitter-cpp');
37
38
  return [
38
39
  distDir,
@@ -45,6 +46,7 @@ function grammarDirs() {
45
46
  nodeModulesPhp,
46
47
  nodeModulesCSharp,
47
48
  nodeModulesKotlin,
49
+ nodeModulesSwift,
48
50
  nodeModulesCpp,
49
51
  ];
50
52
  }
@@ -1 +1 @@
1
- {"version":3,"file":"treeSitterLoader.js","sourceRoot":"","sources":["../../../src/core/languages/treeSitterLoader.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"treeSitterLoader.js","sourceRoot":"","sources":["../../../src/core/languages/treeSitterLoader.ts"],"names":[],"mappings":"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"}
@@ -86,10 +86,24 @@ export declare function recordEvent(session: Session, kind: string, data?: Recor
86
86
  * Persist the session to disk. Best-effort; failures are swallowed so
87
87
  * a transient write error doesn't break the calling tool.
88
88
  *
89
- * Last-write-wins semantics for now. If two MCP servers run against the
90
- * same repo concurrently, the later writer overwrites the earlier; this
91
- * is acceptable for the v1 scope (the multi-process case is rare and the
92
- * downside is just a slightly stale touched-file count, not corruption).
89
+ * 1.8+ uses atomicWriteFile (tmp + fsync + rename + parent-dir fsync)
90
+ * instead of a naive fs.writeFile. Two reasons:
91
+ *
92
+ * 1. Crash safety. A naive writeFile can leave the file truncated to
93
+ * zero bytes if the process is killed mid-write — and on next
94
+ * startup the corrupt file is treated as a new session, losing the
95
+ * touched-file map and event log.
96
+ *
97
+ * 2. Concurrent processes. The previous "last-write-wins" comment was
98
+ * true at the *file* level: two writers could clobber each other.
99
+ * With atomic rename the in-flight tmp paths are unique (random
100
+ * UUID suffix), so the only collision point is the rename — which
101
+ * is atomic at the journal-record level on every supported FS.
102
+ * Either A wins or B wins; neither sees a half-written read.
103
+ *
104
+ * The session payload is JSON; we still don't merge concurrent writes
105
+ * (one writer's view may shadow another's recent touches by a few
106
+ * seconds), but corruption is no longer possible.
93
107
  */
94
108
  export declare function saveSession(rootPath: string, session: Session): Promise<void>;
95
109
  /**
@@ -1,6 +1,7 @@
1
1
  import fs from 'node:fs/promises';
2
2
  import path from 'node:path';
3
3
  import { randomUUID } from 'node:crypto';
4
+ import { atomicWriteFile } from '../utils/atomicWrite.js';
4
5
  /**
5
6
  * Session — durable cross-invocation state for projscan (1.4+).
6
7
  *
@@ -121,17 +122,31 @@ export function recordEvent(session, kind, data) {
121
122
  * Persist the session to disk. Best-effort; failures are swallowed so
122
123
  * a transient write error doesn't break the calling tool.
123
124
  *
124
- * Last-write-wins semantics for now. If two MCP servers run against the
125
- * same repo concurrently, the later writer overwrites the earlier; this
126
- * is acceptable for the v1 scope (the multi-process case is rare and the
127
- * downside is just a slightly stale touched-file count, not corruption).
125
+ * 1.8+ uses atomicWriteFile (tmp + fsync + rename + parent-dir fsync)
126
+ * instead of a naive fs.writeFile. Two reasons:
127
+ *
128
+ * 1. Crash safety. A naive writeFile can leave the file truncated to
129
+ * zero bytes if the process is killed mid-write — and on next
130
+ * startup the corrupt file is treated as a new session, losing the
131
+ * touched-file map and event log.
132
+ *
133
+ * 2. Concurrent processes. The previous "last-write-wins" comment was
134
+ * true at the *file* level: two writers could clobber each other.
135
+ * With atomic rename the in-flight tmp paths are unique (random
136
+ * UUID suffix), so the only collision point is the rename — which
137
+ * is atomic at the journal-record level on every supported FS.
138
+ * Either A wins or B wins; neither sees a half-written read.
139
+ *
140
+ * The session payload is JSON; we still don't merge concurrent writes
141
+ * (one writer's view may shadow another's recent touches by a few
142
+ * seconds), but corruption is no longer possible.
128
143
  */
129
144
  export async function saveSession(rootPath, session) {
130
145
  try {
131
146
  const dir = path.join(rootPath, SESSION_DIR);
132
147
  await fs.mkdir(dir, { recursive: true });
133
148
  const filePath = sessionFilePath(rootPath);
134
- await fs.writeFile(filePath, JSON.stringify(session, null, 2), 'utf-8');
149
+ await atomicWriteFile(filePath, JSON.stringify(session, null, 2));
135
150
  }
136
151
  catch {
137
152
  // Swallow — sessions are best-effort.
@@ -1 +1 @@
1
- {"version":3,"file":"session.js","sourceRoot":"","sources":["../../src/core/session.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"session.js","sourceRoot":"","sources":["../../src/core/session.ts"],"names":[],"mappings":"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"}
@@ -80,6 +80,23 @@ export interface TaintReport {
80
80
  /** The effective sources/sinks list used for this run (after merging defaults + config). */
81
81
  effectiveSources: string[];
82
82
  effectiveSinks: string[];
83
+ /**
84
+ * 1.8+ — true when the BFS hit MAX_DEPTH for at least one source with
85
+ * a non-empty frontier still pending. When set, the agent should know
86
+ * that flows deeper than MAX_DEPTH may exist but weren't reported.
87
+ * Pairs with `truncatedSources` so a follow-up scan can re-target.
88
+ */
89
+ truncated?: boolean;
90
+ /**
91
+ * 1.8+ — function names whose BFS exited at MAX_DEPTH with the
92
+ * frontier non-empty. Empty when no truncation occurred.
93
+ */
94
+ truncatedSources?: string[];
95
+ /**
96
+ * 1.8+ — the depth cap actually used. Surfacing this lets agents
97
+ * notice when projscan's defaults shift between releases.
98
+ */
99
+ maxDepth?: number;
83
100
  }
84
101
  /**
85
102
  * Compute taint flows over the given code graph. Per-function callSites