purecontext-mcp 1.1.1 → 1.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/docs/dev/API_STABILITY.md +0 -319
- package/docs/dev/DECISIONS.md +0 -22
- package/docs/dev/DOCUMENTATION_PLAN.md +0 -113
- package/docs/dev/PHASE10_TASKS.md +0 -476
- package/docs/dev/PHASE11_TASKS.md +0 -385
- package/docs/dev/PHASE12_TASKS.md +0 -335
- package/docs/dev/PHASE13_TASKS.md +0 -381
- package/docs/dev/PHASE14_TASKS.md +0 -371
- package/docs/dev/PHASE15_TASKS.md +0 -256
- package/docs/dev/PHASE16_TASKS.md +0 -314
- package/docs/dev/PHASE17_TASKS.md +0 -321
- package/docs/dev/PHASE18_TASKS.md +0 -345
- package/docs/dev/PHASE19_TASKS.md +0 -261
- package/docs/dev/PHASE1_TASKS.md +0 -443
- package/docs/dev/PHASE20_TASKS.md +0 -280
- package/docs/dev/PHASE21_TASKS.md +0 -355
- package/docs/dev/PHASE22_TASKS.md +0 -371
- package/docs/dev/PHASE23_TASKS.md +0 -274
- package/docs/dev/PHASE24_TASKS.md +0 -326
- package/docs/dev/PHASE25_TASKS.md +0 -452
- package/docs/dev/PHASE26_TASKS.md +0 -253
- package/docs/dev/PHASE27_TASKS.md +0 -410
- package/docs/dev/PHASE2_TASKS.md +0 -328
- package/docs/dev/PHASE3_TASKS.md +0 -571
- package/docs/dev/PHASE4_TASKS.md +0 -531
- package/docs/dev/PHASE5_TASKS.md +0 -835
- package/docs/dev/PHASE6_TASKS.md +0 -347
- package/docs/dev/PHASE7_TASKS.md +0 -257
- package/docs/dev/PHASE8_TASKS.md +0 -299
- package/docs/dev/PHASE9_TASKS.md +0 -320
- package/docs/dev/PureContext_MCP_PRD_v1.0.docx +0 -0
- package/docs/dev/SELF_HOSTING.md +0 -142
- package/docs/dev/TEAM_SETUP.md +0 -316
- package/docs/dev/TELEMETRY.md +0 -99
- package/docs/dev/feature-analysis.md +0 -305
- package/docs/dev/phase-1-notes.md +0 -3
package/docs/dev/PHASE6_TASKS.md
DELETED
|
@@ -1,347 +0,0 @@
|
|
|
1
|
-
# Phase 6 — Task Breakdown
|
|
2
|
-
|
|
3
|
-
**Goal**: Expand language coverage to C++, Lua, and Dart, and deliver the Flutter framework adapter. This phase completes the systems-language tier (C++ extends the C foundation from Phase 5), adds Lua for the game scripting and embedded scripting community, and adds Dart/Flutter for the mobile and cross-platform development community.
|
|
4
|
-
|
|
5
|
-
**Scope rationale**: Phase 5 delivered PHP, Ruby, Kotlin, C, and all Python/Go framework adapters. The three remaining languages with good grammar availability and strong demand are C++ (official grammar, extends C), Lua (community grammar, widely used via Neovim and game engines), and Dart (community grammar, driven by Flutter adoption). C++ is the most complex handler in this phase due to namespace context tracking and template unwrapping. Lua and Dart are lower complexity. Flutter is Dart's dominant framework and a straightforward adapter once the Dart handler exists.
|
|
6
|
-
|
|
7
|
-
**Approach**: Tasks are sequenced so each one builds on the previous. C++ should be done first (it builds conceptually on the C handler from Phase 5). Lua and Dart are independent of each other and of C++. Flutter follows Dart. Complete tasks in order within each language group; language groups can be parallelised if desired.
|
|
8
|
-
|
|
9
|
-
---
|
|
10
|
-
|
|
11
|
-
## Task 61: Extend SymbolKind for Phase 6
|
|
12
|
-
|
|
13
|
-
Add two new `SymbolKind` values required by C++ and Flutter before those handlers compile.
|
|
14
|
-
|
|
15
|
-
**Deliverables:**
|
|
16
|
-
- Update `src/core/types.ts` — extend the `SymbolKind` union:
|
|
17
|
-
```typescript
|
|
18
|
-
export type SymbolKind =
|
|
19
|
-
// Existing (Phase 1–5, unchanged)
|
|
20
|
-
| 'function' | 'class' | 'method' | 'const' | 'type'
|
|
21
|
-
| 'interface' | 'enum' | 'component' | 'composable'
|
|
22
|
-
| 'hook' | 'route' | 'decorator' | 'middleware'
|
|
23
|
-
| 'model' | 'view' | 'struct' | 'macro' | 'signal'
|
|
24
|
-
// Phase 6 additions
|
|
25
|
-
| 'namespace' // C++ named namespace; PHP namespace (retroactive enrichment); Kotlin package object
|
|
26
|
-
| 'widget'; // Flutter StatelessWidget / StatefulWidget subclasses
|
|
27
|
-
```
|
|
28
|
-
|
|
29
|
-
**Rationale:**
|
|
30
|
-
- `namespace`: C++ namespaces are first-class navigational units — agents frequently ask "what's in namespace Foo?". Using `type` or `class` loses this distinction. Also applicable retroactively to PHP namespace declarations (the Phase 5 PHP handler tracks namespaces as prefixes but does not emit them as symbols — emitting them as `namespace` kind is opt-in and additive).
|
|
31
|
-
- `widget`: Flutter's defining pattern is a class extending `StatelessWidget` or `StatefulWidget` with a `build()` method. A dedicated kind lets agents query "find all widgets" meaningfully, distinct from plain `class` symbols.
|
|
32
|
-
|
|
33
|
-
**Backward-compatibility:** Both additions are appended to the union. No migrations required.
|
|
34
|
-
|
|
35
|
-
**Verify:** `npm run build` succeeds. All Phase 1–5 tests still pass.
|
|
36
|
-
|
|
37
|
-
**Tests:** Type-level assertion that new kinds are valid `SymbolKind` values.
|
|
38
|
-
|
|
39
|
-
---
|
|
40
|
-
|
|
41
|
-
## Task 62: C++ Language Handler
|
|
42
|
-
|
|
43
|
-
Add C++ as the most complex language handler in Phase 6. C++ extends C with classes, namespaces, templates, and inheritance — requiring a namespace context stack and template unwrapping during AST traversal.
|
|
44
|
-
|
|
45
|
-
**Deliverables:**
|
|
46
|
-
- Download and bundle `grammars/tree-sitter-cpp.wasm`
|
|
47
|
-
- Source: `tree-sitter-cpp` npm package (official tree-sitter grammar, extends C grammar)
|
|
48
|
-
- Build: `npx tree-sitter build-wasm node_modules/tree-sitter-cpp`
|
|
49
|
-
- `src/handlers/cpp.ts` — implements `LanguageHandler`
|
|
50
|
-
- `extensions()`: `['.cpp', '.cxx', '.cc', '.c++', '.hpp', '.hxx', '.hh', '.h++']`
|
|
51
|
-
- `grammarPath()`: path to `tree-sitter-cpp.wasm`
|
|
52
|
-
- `extractSymbols(tree, source)`:
|
|
53
|
-
- Use a recursive `walkNode(node, context: { nsStack: string[], className: string | null, accessLevel: 'public' | 'private' | 'protected' })` helper
|
|
54
|
-
- **Namespace context stack**: when entering `namespace_definition`, push the namespace name (or `<anonymous>` for unnamed namespaces) onto `nsStack`; pop on exit. Qualify all emitted symbol names with `nsStack.join('::')`.
|
|
55
|
-
- **Top-level and namespace-scoped declarations**:
|
|
56
|
-
- `function_definition` → kind `'function'`, name qualified with namespace stack
|
|
57
|
-
- `class_specifier` or `struct_specifier` as the type in a `type_definition` or directly at namespace scope → kind `'class'` (for `class`) or `'struct'` (for `struct`)
|
|
58
|
-
- `enum_specifier` → kind `'enum'`
|
|
59
|
-
- `alias_declaration` (`using Foo = Bar`) → kind `'type'`
|
|
60
|
-
- `namespace_definition` → kind `'namespace'`, name from `name` child; recurse into body
|
|
61
|
-
- `template_declaration` wrapping any of the above → unwrap (see below) and emit the inner symbol
|
|
62
|
-
- **Class body** (inside `class_specifier` or `struct_specifier` body `field_declaration_list`):
|
|
63
|
-
- Track current access level: default is `private` for `class`, `public` for `struct`
|
|
64
|
-
- `access_specifier` node (`public:`, `private:`, `protected:`) → update context `accessLevel`
|
|
65
|
-
- Skip nodes where `accessLevel` is `'private'`
|
|
66
|
-
- `function_definition` inside class body → kind `'method'`, name = `Namespace::ClassName::methodName`
|
|
67
|
-
- `constructor_definition` → kind `'method'`, name = `ClassName::ClassName`
|
|
68
|
-
- `destructor_name` function → kind `'method'`, name = `ClassName::~ClassName`
|
|
69
|
-
- Nested `class_specifier` or `struct_specifier` → recurse with updated className context
|
|
70
|
-
- **Template unwrapping**:
|
|
71
|
-
- `template_declaration` has a `template_parameters` child and a declaration child
|
|
72
|
-
- Find the first child that is a `function_definition`, `class_specifier`, `struct_specifier`, or `alias_declaration`
|
|
73
|
-
- Extract the template parameter list string (`template<...>`) and prepend it to the symbol signature
|
|
74
|
-
- Emit the inner symbol normally; skip explicit template specializations (they have `<` immediately after the name)
|
|
75
|
-
- **Preprocessor macros** (same as C handler):
|
|
76
|
-
- `preproc_def` → kind `'macro'`; skip `preproc_function_def` and guard macros
|
|
77
|
-
- `extractImports(tree, source)`:
|
|
78
|
-
- `preproc_include` nodes — same as C handler
|
|
79
|
-
- `using_declaration` (`using std::vector`) — record as an import with specifier = qualified name
|
|
80
|
-
- `using_directive` (`using namespace std`) — record with specifier = namespace name, `importedNames: []`
|
|
81
|
-
- `extractDocstring(node)`:
|
|
82
|
-
- Same as C handler: walk `previousNamedSibling` for `comment` nodes; handle `//` and `/* */`
|
|
83
|
-
- Also handle Doxygen `///` prefix lines
|
|
84
|
-
- Update `src/handlers/handler-registry.ts` — add entry for C++ extensions
|
|
85
|
-
- Update `src/index.ts` — register C++ handler in bootstrap
|
|
86
|
-
|
|
87
|
-
**Signature building:**
|
|
88
|
-
- Functions: `[template<T>] returnType qualifiedName(params)`
|
|
89
|
-
- Classes: `[template<T>] class Namespace::Name [: public Base]`
|
|
90
|
-
- Structs: `[template<T>] struct Namespace::Name`
|
|
91
|
-
- Namespaces: `namespace Name` (signature is just the declaration line)
|
|
92
|
-
- Methods: `[virtual] [static] returnType ClassName::methodName(params) [const] [override]`
|
|
93
|
-
- Destructors: `~ClassName()`
|
|
94
|
-
- Type aliases: `using Name = Type`
|
|
95
|
-
- Macros: `#define NAME value`
|
|
96
|
-
- Keep signatures under 120 chars
|
|
97
|
-
|
|
98
|
-
**Key technical notes:**
|
|
99
|
-
- **Namespace stack is critical**: without it, symbols from `namespace Foo { namespace Bar { class Baz {}}}` would emit as just `Baz` instead of `Foo::Bar::Baz`
|
|
100
|
-
- **Anonymous namespaces** (`namespace { ... }`): symbols inside have internal linkage — skip or emit with `<anonymous>::Name` prefix. In Phase 6, skip anonymous namespace symbols entirely (implementation details).
|
|
101
|
-
- **Template specialisation detection**: `template<>` (empty template parameters) indicates a full specialisation — skip these, they are implementation details of the primary template.
|
|
102
|
-
- **Operator overloads**: `operator==`, `operator<<` — the name child will be an `operator_name` node; emit as `'method'` with name `ClassName::operator==`
|
|
103
|
-
- **`inline` and `constexpr`**: modifiers in `declaration_specifiers` — include in signature but do not affect extraction logic
|
|
104
|
-
- **Forward declarations**: `class Foo;` at namespace scope — skip (no body means no symbols to extract)
|
|
105
|
-
- The C++ handler reuses the name-unwrapping helper from the C handler for pointer declarators
|
|
106
|
-
|
|
107
|
-
**Verify:** Index `test/fixtures/cpp-project/`. Verify namespace-qualified names (`Foo::Bar::method`), template class extraction, struct vs class distinction, access specifier filtering (private methods skipped), destructor extraction.
|
|
108
|
-
|
|
109
|
-
**Tests:** Named namespace qualifying names, nested namespaces (`::` separator), top-level function, class with public/private methods (private skipped), struct with public fields, `template<T>` class, template function, `using Foo = Bar` type alias, `#define` macro, `#include`, destructor, constructor, operator overload name.
|
|
110
|
-
|
|
111
|
-
---
|
|
112
|
-
|
|
113
|
-
## Task 63: Lua Language Handler
|
|
114
|
-
|
|
115
|
-
Add Lua as a lightweight scripting language handler. Lua's grammar is well-maintained by the community (used by Neovim's tree-sitter integration) and its function definition patterns, while idiomatic, are well-defined.
|
|
116
|
-
|
|
117
|
-
**Deliverables:**
|
|
118
|
-
- Download and bundle `grammars/tree-sitter-lua.wasm`
|
|
119
|
-
- Source: `tree-sitter-lua` npm package (MunifTanjim/tree-sitter-lua, used by Neovim)
|
|
120
|
-
- Build: `npx tree-sitter build-wasm node_modules/tree-sitter-lua`
|
|
121
|
-
- `src/handlers/lua.ts` — implements `LanguageHandler`
|
|
122
|
-
- `extensions()`: `['.lua']`
|
|
123
|
-
- `grammarPath()`: path to `tree-sitter-lua.wasm`
|
|
124
|
-
- `extractSymbols(tree, source)`:
|
|
125
|
-
- Lua has multiple function definition patterns — all must be detected:
|
|
126
|
-
|
|
127
|
-
**1. Named function declaration** (`function foo() ... end`):
|
|
128
|
-
- `function_declaration` node → kind `'function'`
|
|
129
|
-
- Name from `dot_index_expression` or `method_index_expression` child (module methods) or plain `identifier`
|
|
130
|
-
- `method_index_expression` (`Module:method`) → kind `'method'`, name = `Module:method`
|
|
131
|
-
|
|
132
|
-
**2. Local function** (`local function foo() ... end`):
|
|
133
|
-
- `local_function` node → kind `'function'`
|
|
134
|
-
|
|
135
|
-
**3. Variable assignment to function literal** (`foo = function() ... end`):
|
|
136
|
-
- `assignment_statement` where the RHS is a `function_definition` node
|
|
137
|
-
- LHS is a `variable_list` with one `identifier` → kind `'function'`
|
|
138
|
-
- LHS is a `dot_index_expression` (`Module.foo = function()`) → kind `'method'`, name = `Module.foo`
|
|
139
|
-
|
|
140
|
-
**4. Local variable assignment to function literal** (`local foo = function() ... end`):
|
|
141
|
-
- `local_variable_declaration` where the `expression_list` contains a `function_definition`
|
|
142
|
-
- Kind `'function'`
|
|
143
|
-
|
|
144
|
-
**Module table constants** (top-level `assignment_statement` where RHS is a `table_constructor` and LHS is an uppercase or PascalCase identifier):
|
|
145
|
-
- Emit kind `'const'` — Lua module tables are the nearest equivalent to constants
|
|
146
|
-
|
|
147
|
-
**Skip**: nested function definitions (inside other functions), `do ... end` blocks at non-top-level
|
|
148
|
-
|
|
149
|
-
- `extractImports(tree, source)`:
|
|
150
|
-
- Scan for `assignment_statement` nodes where the RHS is a `call_expression` whose function name is `require`
|
|
151
|
-
- Specifier: the first argument string to `require` (e.g. `"socket"`, `"mymodule.utils"`)
|
|
152
|
-
- `resolvedPath`: convert dot-separated module path to file path (`"mymodule.utils"` → `mymodule/utils.lua`); return `null` if path cannot be resolved
|
|
153
|
-
- `importedNames`: the LHS variable name(s) (what the require result is assigned to)
|
|
154
|
-
- `isTypeOnly`: `false`
|
|
155
|
-
- `extractDocstring(node)`:
|
|
156
|
-
- Walk `previousNamedSibling` chain for consecutive `comment` nodes (`--` prefix)
|
|
157
|
-
- Also handle block comments (`--[[ ... ]]`) immediately preceding a declaration
|
|
158
|
-
- Strip `-- ` prefix, concatenate, return first paragraph
|
|
159
|
-
|
|
160
|
-
**Signature building:**
|
|
161
|
-
- Functions: `function name(params)` or `local function name(params)`
|
|
162
|
-
- Methods (dot-index): `function Module.name(params)`
|
|
163
|
-
- Methods (colon-index): `function Module:name(params)`
|
|
164
|
-
- Constants (module tables): `local Module = { ... }` (truncate body)
|
|
165
|
-
- Keep signatures under 120 chars
|
|
166
|
-
|
|
167
|
-
**Key technical notes:**
|
|
168
|
-
- Lua has no class system — OOP is simulated via metatables and module patterns. The handler only extracts function definitions and module-level constants; metatable wiring is not parsed.
|
|
169
|
-
- The colon syntax `Module:method(params)` desugars to `Module.method(self, params)` — emit with the colon notation preserved in the name for clarity
|
|
170
|
-
- Lua files often begin with `local M = {}` then populate `M` then `return M` — only emit symbols that are clearly exported (accessible via the returned table). In Phase 6, emit all top-level and module-level function assignments without trying to determine if they are in the returned table.
|
|
171
|
-
- `pcall`, `require`, `ipairs`, `pairs` are standard library calls — they will not match function definition patterns and should not be extracted
|
|
172
|
-
|
|
173
|
-
**Verify:** Index `test/fixtures/lua-project/`. Verify `function foo()` is kind `'function'`, `function M.bar()` is kind `'method'` with name `M.bar`, `function M:baz()` is kind `'method'` with name `M:baz`, `local function helper()` is kind `'function'`.
|
|
174
|
-
|
|
175
|
-
**Tests:** `function foo()`, `local function helper()`, `M.bar = function()`, `function M:baz()`, `local M = {}` table constant, `require("socket")` import, `--` comment docstring.
|
|
176
|
-
|
|
177
|
-
---
|
|
178
|
-
|
|
179
|
-
## Task 64: Dart Language Handler
|
|
180
|
-
|
|
181
|
-
Add Dart as the language handler required by the Flutter adapter. Dart's community grammar is actively maintained and used by several editor plugins.
|
|
182
|
-
|
|
183
|
-
**Deliverables:**
|
|
184
|
-
- Download and bundle `grammars/tree-sitter-dart.wasm`
|
|
185
|
-
- Source: `tree-sitter-dart` npm package (UserNobody14/tree-sitter-dart)
|
|
186
|
-
- Build: `npx tree-sitter build-wasm node_modules/tree-sitter-dart`
|
|
187
|
-
- `src/handlers/dart.ts` — implements `LanguageHandler`
|
|
188
|
-
- `extensions()`: `['.dart']`
|
|
189
|
-
- `grammarPath()`: path to `tree-sitter-dart.wasm`
|
|
190
|
-
- `extractSymbols(tree, source)`:
|
|
191
|
-
- `class_definition` → kind `'class'`
|
|
192
|
-
- `mixin_declaration` → kind `'class'` with `frameworkMeta.dart_mixin: true`
|
|
193
|
-
- `extension_declaration` → kind `'class'` with `frameworkMeta.dart_extension: true`; name = `Extension:ExtendedType` if named, `<anonymous extension>` if not
|
|
194
|
-
- `enum_declaration` → kind `'enum'`
|
|
195
|
-
- `type_alias` (`typedef`) → kind `'type'`
|
|
196
|
-
- Top-level `function_signature` followed by `function_body` → kind `'function'`
|
|
197
|
-
- Top-level `getter_signature` / `setter_signature` → kind `'function'` (getters/setters at top level are function-like)
|
|
198
|
-
- `method_signature` inside `class_body` → kind `'method'`, name = `ClassName.methodName`
|
|
199
|
-
- `constructor_signature` → kind `'method'`, name = `ClassName.ClassName` (or `ClassName.namedConstructor`)
|
|
200
|
-
- Top-level `initialized_variable_definition` with `const` or `final` keyword → kind `'const'`
|
|
201
|
-
- Visibility: Dart uses `_` prefix for private names — skip symbols whose name starts with `_`
|
|
202
|
-
- `extractImports(tree, source)`:
|
|
203
|
-
- `import_or_export` nodes containing `import_specification`
|
|
204
|
-
- `specifier`: the URI string (e.g. `'dart:core'`, `'package:http/http.dart'`, `'../utils.dart'`)
|
|
205
|
-
- `importedNames`: symbols from `show` clause if present; `[]` otherwise
|
|
206
|
-
- `resolvedPath`: for `'../relative/path.dart'` style — resolve relative to file; for `'package:...'` and `'dart:...'` — `null`
|
|
207
|
-
- `isTypeOnly`: `false` (Dart has no type-only imports)
|
|
208
|
-
- `extractDocstring(node)`:
|
|
209
|
-
- Dart doc comments use `///` (triple-slash) lines or `/** */` block comments
|
|
210
|
-
- Walk `previousNamedSibling` for `documentation_comment` or `comment` nodes
|
|
211
|
-
- Strip `/// ` prefix, concatenate, return first paragraph
|
|
212
|
-
|
|
213
|
-
**Signature building:**
|
|
214
|
-
- Classes: `class Name [extends Base] [implements Interface, ...] [with Mixin, ...]`
|
|
215
|
-
- Mixins: `mixin Name [on ConstraintType]`
|
|
216
|
-
- Functions: `[async] returnType name(params)`
|
|
217
|
-
- Methods: `[static] [async] returnType name(params)` (including class context in name)
|
|
218
|
-
- Constructors: `ClassName([params])` or `ClassName.namedConstructor([params])`
|
|
219
|
-
- Constants: `const Type name = value`
|
|
220
|
-
- Enums: `enum Name { value1, value2, ... }` (show first 3 values)
|
|
221
|
-
- Keep signatures under 120 chars
|
|
222
|
-
|
|
223
|
-
**Key technical notes:**
|
|
224
|
-
- Dart's `async`, `async*`, `sync*` function modifiers appear in the function signature — include them
|
|
225
|
-
- Named constructors (`User.fromJson(...)`) have a `.constructorName` suffix in the node — emit as `ClassName.constructorName`
|
|
226
|
-
- `factory` constructors are `constructor_signature` nodes with a `factory` modifier — extract normally
|
|
227
|
-
- Class body includes `operator` method declarations — emit as `'method'` with name `ClassName.operator==` etc.
|
|
228
|
-
- Dart null safety annotations (`?`, `!`, `required`) appear in type annotations — preserve in signatures
|
|
229
|
-
|
|
230
|
-
**Verify:** Index `test/fixtures/dart-project/`. Verify class, mixin, enum, top-level function, and class method extraction. Verify private `_names` are skipped. Verify `///` doc comments are captured.
|
|
231
|
-
|
|
232
|
-
**Tests:** `class`, `mixin`, `extension`, `enum`, top-level function, class method, named constructor, `typedef`, `const` top-level, `import` with `show` clause, `_private` name (skipped), `///` doc comment.
|
|
233
|
-
|
|
234
|
-
---
|
|
235
|
-
|
|
236
|
-
## Task 65: Flutter Adapter
|
|
237
|
-
|
|
238
|
-
Extract Flutter widget symbols from Dart projects. Flutter's defining pattern is classes extending `StatelessWidget` or `StatefulWidget` — the adapter reclassifies these from `'class'` to `'widget'`.
|
|
239
|
-
|
|
240
|
-
**Deliverables:**
|
|
241
|
-
- `src/adapters/flutter.ts` — implements `FrameworkAdapter`
|
|
242
|
-
- `name`: `'flutter'`
|
|
243
|
-
- `extensions()`: `[]` — `.dart` files are handled by the Dart handler
|
|
244
|
-
- `detect(projectRoot)`:
|
|
245
|
-
- Read `pubspec.yaml` — check for `sdk: flutter` under the `flutter:` key, or `flutter` in `dependencies`
|
|
246
|
-
- As a fallback: check if `pubspec.yaml` exists and contains the string `flutter` anywhere (broad but reliable for Flutter projects)
|
|
247
|
-
- `fileFilter(filePath)`: `.dart` files only
|
|
248
|
-
- `extractFrameworkSymbols(tree, source, filePath)`:
|
|
249
|
-
- Scan for `class_definition` nodes whose superclass chain includes `StatelessWidget`, `StatefulWidget`, `State`, `InheritedWidget`, or `RenderObject`
|
|
250
|
-
- Detection: check the `extends_clause` child of `class_definition` for these type names
|
|
251
|
-
- Emit kind `'widget'`
|
|
252
|
-
- `frameworkMeta.flutter_widget_type`: `'stateless'` | `'stateful'` | `'state'` | `'inherited'` | `'render'`
|
|
253
|
-
- `frameworkMeta.flutter_widget: true`
|
|
254
|
-
- For `StatefulWidget` subclasses: also scan for the associated `State<T>` class and link them via `frameworkMeta.state_class` (name of the State class)
|
|
255
|
-
- Scan for `@immutable` annotated classes (common Flutter pattern for data classes) → emit kind `'class'` with `frameworkMeta.flutter_immutable: true`
|
|
256
|
-
- Scan for `ChangeNotifier` / `Listenable` subclasses → emit kind `'class'` with `frameworkMeta.flutter_notifier: true`
|
|
257
|
-
- `enrichMetadata(symbol)`:
|
|
258
|
-
- For kind `'class'` symbols in Flutter files: if the class name ends in `Widget` and the Dart handler didn't find an `extends` clause (e.g. due to truncation) → leave as `'class'`, do not guess
|
|
259
|
-
- Do not downgrade `'widget'` symbols set by `extractFrameworkSymbols`
|
|
260
|
-
- Register via `registerAdapter(flutterAdapter)` at module level
|
|
261
|
-
|
|
262
|
-
**Key technical notes:**
|
|
263
|
-
- `StatefulWidget` and its `State<T>` subclass are always declared in the same file — the adapter can link them by scanning the file for both
|
|
264
|
-
- Flutter's provider pattern (`ChangeNotifier`, `ValueNotifier`) is widely used for state management — the `frameworkMeta.flutter_notifier` flag helps agents distinguish state from UI
|
|
265
|
-
- Flutter test files (`*_test.dart`) contain `testWidgets(...)` calls — the adapter should not emit route or widget symbols from test files (apply path filter `!filePath.endsWith('_test.dart')`)
|
|
266
|
-
- `BuildContext` parameter in `build()` method is a Flutter-specific type — its presence in method signatures is a strong signal but the class inheritance check is more reliable
|
|
267
|
-
|
|
268
|
-
**Verify:** Index `test/fixtures/flutter-project/`. Verify `class MyWidget extends StatelessWidget` produces kind `'widget'` with `flutter_widget_type: 'stateless'`. Verify `class MyWidgetState extends State<MyWidget>` produces kind `'widget'` with `flutter_widget_type: 'state'`. Verify a plain Dart class does not produce kind `'widget'`.
|
|
269
|
-
|
|
270
|
-
**Tests:** `StatelessWidget` subclass, `StatefulWidget` + linked `State` class, `InheritedWidget`, `ChangeNotifier` subclass, plain class (stays `'class'`), test file widget (not extracted as widget).
|
|
271
|
-
|
|
272
|
-
---
|
|
273
|
-
|
|
274
|
-
## Task 66: Phase 6 Test Fixtures and Integration Tests
|
|
275
|
-
|
|
276
|
-
Validate the full Phase 6 pipeline end-to-end across all new handlers and adapters.
|
|
277
|
-
|
|
278
|
-
**Deliverables:**
|
|
279
|
-
|
|
280
|
-
- `test/fixtures/cpp-project/` — representative C++ project:
|
|
281
|
-
- `include/auth.hpp` — namespace `Auth`, class `AuthService` with public/private methods, template class
|
|
282
|
-
- `src/auth.cpp` — `Auth::AuthService` method implementations
|
|
283
|
-
- `include/models.hpp` — nested namespace `App::Models`, structs, enums
|
|
284
|
-
- `src/utils.cpp` — free functions in namespace, `#define` macros, `using` type aliases
|
|
285
|
-
- `CMakeLists.txt` (presence marker, not parsed)
|
|
286
|
-
|
|
287
|
-
- `test/fixtures/lua-project/` — representative Lua project:
|
|
288
|
-
- `src/auth.lua` — `local M = {}`, `M.login = function()`, `M:logout()`, module return
|
|
289
|
-
- `src/utils.lua` — top-level `function format(...)`, `local function helper()`, `require` calls
|
|
290
|
-
- `src/config.lua` — top-level constant table
|
|
291
|
-
|
|
292
|
-
- `test/fixtures/dart-project/` — representative Dart project:
|
|
293
|
-
- `lib/src/auth_service.dart` — class with methods, named constructor, `///` doc comments
|
|
294
|
-
- `lib/src/models/user.dart` — class with `const` constructor, `final` fields
|
|
295
|
-
- `lib/src/utils.dart` — top-level functions, `typedef`
|
|
296
|
-
- `test/auth_service_test.dart` — test file (lower priority)
|
|
297
|
-
|
|
298
|
-
- `test/fixtures/flutter-project/` — minimal Flutter application:
|
|
299
|
-
- `pubspec.yaml` with `sdk: flutter`
|
|
300
|
-
- `lib/widgets/my_button.dart` — `class MyButton extends StatelessWidget` with `build()`
|
|
301
|
-
- `lib/screens/home_screen.dart` — `class HomeScreen extends StatefulWidget` + `class _HomeScreenState extends State<HomeScreen>`
|
|
302
|
-
- `lib/providers/auth_provider.dart` — `class AuthProvider extends ChangeNotifier`
|
|
303
|
-
- `lib/models/user.dart` — plain Dart class (not a widget)
|
|
304
|
-
|
|
305
|
-
- Integration tests `test/integration/phase6.test.ts`:
|
|
306
|
-
1. C++: `namespace Auth { class AuthService { ... } }` → symbol name is `Auth::AuthService`
|
|
307
|
-
2. C++: nested namespace → `App::Models::User`
|
|
308
|
-
3. C++: `template<T> class Cache` → kind `'class'` with template prefix in signature
|
|
309
|
-
4. C++: private method → not extracted; public method → extracted
|
|
310
|
-
5. C++: `struct Point` → kind `'struct'` (not `'class'`)
|
|
311
|
-
6. C++: `namespace Auth` declaration → kind `'namespace'`
|
|
312
|
-
7. Lua: `function M.login()` → kind `'method'` with name `M.login`
|
|
313
|
-
8. Lua: `function M:logout()` → kind `'method'` with name `M:logout`
|
|
314
|
-
9. Lua: top-level `function format()` → kind `'function'`
|
|
315
|
-
10. Dart: class with public methods → extracted; `_private` method → skipped
|
|
316
|
-
11. Dart: named constructor → kind `'method'` with name `ClassName.namedConstructor`
|
|
317
|
-
12. Dart: `///` doc comment captured
|
|
318
|
-
13. Flutter: `StatelessWidget` subclass → kind `'widget'` with `flutter_widget_type: 'stateless'`
|
|
319
|
-
14. Flutter: `StatefulWidget` + linked `State` class → both emitted as `'widget'`
|
|
320
|
-
15. Flutter: `ChangeNotifier` subclass → kind `'class'` with `flutter_notifier: true`
|
|
321
|
-
16. Flutter: plain Dart class → kind `'class'`, not `'widget'`
|
|
322
|
-
17. `search-symbols` with `kind: 'widget'` returns only Flutter widgets
|
|
323
|
-
18. `search-symbols` with `kind: 'namespace'` returns only C++ namespaces
|
|
324
|
-
19. Full suite regression: all Phase 1–5 tests still green
|
|
325
|
-
|
|
326
|
-
- **Performance benchmark** `test/benchmarks/phase6.bench.ts`:
|
|
327
|
-
- Index each language fixture, record time and symbol count
|
|
328
|
-
- C++ fixture specifically: verify namespace-qualified name generation does not degrade indexing performance vs. C fixture
|
|
329
|
-
|
|
330
|
-
**Verify:** `npm run test` passes entirely — all Phase 1–6 tests green. No regressions.
|
|
331
|
-
|
|
332
|
-
---
|
|
333
|
-
|
|
334
|
-
## Order of Execution
|
|
335
|
-
|
|
336
|
-
```
|
|
337
|
-
Task 61: Extend SymbolKind ██░░░░░░░░ Foundation
|
|
338
|
-
Task 62: C++ language handler ████░░░░░░ C++
|
|
339
|
-
Task 63: Lua language handler ██████░░░░ Lua
|
|
340
|
-
Task 64: Dart language handler ████████░░ Dart
|
|
341
|
-
Task 65: Flutter adapter █████████░ Dart/Flutter
|
|
342
|
-
Task 66: Fixtures + integration tests ██████████ Polish
|
|
343
|
-
```
|
|
344
|
-
|
|
345
|
-
Task 61 must come first. Task 62 (C++) is independent of Tasks 63–65 (Lua/Dart/Flutter). Task 65 (Flutter) depends on Task 64 (Dart handler). Otherwise Tasks 62, 63, and 64 can be developed in parallel.
|
|
346
|
-
|
|
347
|
-
**After Phase 6 is complete**, move to Phase 7: Swift language handler and Vapor server-side Swift adapter.
|
package/docs/dev/PHASE7_TASKS.md
DELETED
|
@@ -1,257 +0,0 @@
|
|
|
1
|
-
# Phase 7 — Task Breakdown
|
|
2
|
-
|
|
3
|
-
**Goal**: Add Swift as the final language handler and deliver the Vapor server-side Swift framework adapter. This phase closes the language expansion roadmap started in Phase 5, bringing PureContext to full language parity with jCodeMunch across all targeted languages.
|
|
4
|
-
|
|
5
|
-
**Scope rationale**: Phase 6 completed C++, Lua, Dart, and Flutter. Swift is the last language in the expansion plan and the most complex grammar of the entire set. It was deliberately deferred to a standalone phase because (1) the Swift tree-sitter grammar is large and the most complex of all targeted languages (actors, result builders, property wrappers, async/await, opaque types), (2) Vapor's server-side Swift market is smaller than other targets, so the ROI is lower and rushing the implementation risks quality, and (3) by Phase 7 the grammar-loading and WASM pipeline is battle-tested, making the infrastructure risk minimal. The integration test task in Phase 7 is expanded to include a full benchmark comparison against jCodeMunch across all shared languages.
|
|
6
|
-
|
|
7
|
-
**Approach**: Tasks are sequenced linearly: Swift handler → Vapor adapter → integration tests and competitive benchmark. Each task must be complete before the next begins.
|
|
8
|
-
|
|
9
|
-
---
|
|
10
|
-
|
|
11
|
-
## Task 67: Swift Language Handler
|
|
12
|
-
|
|
13
|
-
Add Swift as the final new language handler. Swift's grammar is the most complex in the entire PureContext handler set, requiring careful handling of access control, extensions, actors, and optional chaining in type signatures.
|
|
14
|
-
|
|
15
|
-
**Deliverables:**
|
|
16
|
-
- Download and bundle `grammars/tree-sitter-swift.wasm`
|
|
17
|
-
- Source: `tree-sitter-swift` npm package (alex-pinkus/tree-sitter-swift, community-maintained and widely adopted)
|
|
18
|
-
- Build: `npx tree-sitter build-wasm node_modules/tree-sitter-swift`
|
|
19
|
-
- Note: the Swift WASM file is significantly larger than other grammars (~3–5 MB vs. ~0.5–1 MB). Verify the grammar loads and parses correctly before proceeding to handler implementation.
|
|
20
|
-
- `src/handlers/swift.ts` — implements `LanguageHandler`
|
|
21
|
-
- `extensions()`: `['.swift']`
|
|
22
|
-
- `grammarPath()`: path to `tree-sitter-swift.wasm`
|
|
23
|
-
- `extractSymbols(tree, source)`:
|
|
24
|
-
- Use a recursive `walkNode(node, context: { typeName: string | null, accessLevel: string | null })` helper
|
|
25
|
-
- **Access control filter**: only extract symbols with `public`, `open`, or no explicit modifier (Swift's default is `internal`, which is package-visible and useful for navigation). Skip `private` and `fileprivate` symbols.
|
|
26
|
-
- Extract `visibility_modifier` from the `modifiers` sequence preceding declarations.
|
|
27
|
-
|
|
28
|
-
**Top-level declarations:**
|
|
29
|
-
- `function_declaration` → kind `'function'`
|
|
30
|
-
- `class_declaration` → kind `'class'`
|
|
31
|
-
- `struct_declaration` → kind `'class'` (Swift structs are value-type equivalents of classes)
|
|
32
|
-
- `enum_declaration` → kind `'enum'`
|
|
33
|
-
- `protocol_declaration` → kind `'interface'`
|
|
34
|
-
- `actor_declaration` (Swift 5.5+) → kind `'class'` with `frameworkMeta.swift_actor: true`
|
|
35
|
-
- `extension_declaration` → kind `'class'` with `frameworkMeta.swift_extension: true`; name derived from extended type (e.g. `String+MyExtensions` or just the extended type name)
|
|
36
|
-
- `typealias_declaration` → kind `'type'`
|
|
37
|
-
- `let_declaration` / `var_declaration` at top level with `let` and uppercase or PascalCase name → kind `'const'`
|
|
38
|
-
|
|
39
|
-
**Type body declarations** (inside `class`, `struct`, `actor`, `extension`, `enum` body):
|
|
40
|
-
- `function_declaration` → kind `'method'`, name = `TypeName.methodName`
|
|
41
|
-
- `init_declaration` → kind `'method'`, name = `TypeName.init`; failable init (`init?`) → name = `TypeName.init?`
|
|
42
|
-
- `deinit_declaration` → kind `'method'`, name = `TypeName.deinit`
|
|
43
|
-
- `subscript_declaration` → kind `'method'`, name = `TypeName.subscript`
|
|
44
|
-
- `computed_property` (`var name: Type { get { ... } }`) → kind `'const'` (properties as named access points)
|
|
45
|
-
- Nested type declarations → recurse with updated `typeName` context
|
|
46
|
-
|
|
47
|
-
**Protocol body declarations**:
|
|
48
|
-
- `protocol_function_declaration` (requirement stubs) → kind `'method'`
|
|
49
|
-
- `protocol_property_declaration` → kind `'const'`
|
|
50
|
-
|
|
51
|
-
- `extractImports(tree, source)`:
|
|
52
|
-
- `import_declaration` nodes → specifier = module name (e.g. `Foundation`, `UIKit`, `Vapor`)
|
|
53
|
-
- `resolvedPath`: `null` for all (Swift Package Manager handles resolution)
|
|
54
|
-
- `importedNames`: `[]` (Swift `import` brings the whole module into scope)
|
|
55
|
-
- `isTypeOnly`: `false`
|
|
56
|
-
- `extractDocstring(node)`:
|
|
57
|
-
- Swift uses `///` triple-slash doc comments (DocC format)
|
|
58
|
-
- Walk `previousNamedSibling` for consecutive `comment` nodes with `///` prefix
|
|
59
|
-
- Also handle `/** */` block comments
|
|
60
|
-
- Strip `/// ` prefix and DocC markup (e.g. `- Parameter x:` → include in docstring, strip formatting)
|
|
61
|
-
- Return first paragraph (up to first blank line or 200 chars)
|
|
62
|
-
- Update `src/handlers/handler-registry.ts` — add entry for Swift extensions
|
|
63
|
-
- Update `src/index.ts` — register Swift handler in bootstrap
|
|
64
|
-
|
|
65
|
-
**Signature building:**
|
|
66
|
-
- Functions: `[public/open] [static/class] func name(params) [async] [throws] -> ReturnType`
|
|
67
|
-
- Classes: `[public] class Name[: SuperClass[, Protocol, ...]]`
|
|
68
|
-
- Structs: `[public] struct Name[: Protocol, ...]`
|
|
69
|
-
- Protocols: `[public] protocol Name[: BaseProtocol]`
|
|
70
|
-
- Actors: `[public] actor Name`
|
|
71
|
-
- Extensions: `extension TypeName[: Protocol]`
|
|
72
|
-
- Methods: same as functions but omitting `func` keyword in method context
|
|
73
|
-
- Init: `init([params]) [throws]` or `init?([params])`
|
|
74
|
-
- Type aliases: `typealias Name = Type`
|
|
75
|
-
- Constants: `let Name: Type = value` or `var Name: Type { get }`
|
|
76
|
-
- Include `async` and `throws` in signatures where present
|
|
77
|
-
- Keep signatures under 120 chars; truncate parameter lists with `...` if needed
|
|
78
|
-
|
|
79
|
-
**Key technical notes:**
|
|
80
|
-
- **Property wrappers** (`@State`, `@Binding`, `@Published`, `@AppStorage`, etc.) appear as `attribute` nodes inside the `modifiers` list — include the first attribute in the signature but do not emit them as separate symbols
|
|
81
|
-
- **Result builders** (`@ViewBuilder`, `@ResultBuilder`): function bodies with result builder syntax look like normal function bodies in the AST — no special handling needed
|
|
82
|
-
- **`some` and `any` opaque types** in return positions — preserve in signature as text
|
|
83
|
-
- **`async` functions** (`async throws`): `async_modifier` and `throws_modifier` appear in `function_modifiers` — include both in signature
|
|
84
|
-
- **Extension named types**: `extension String { ... }` — emit as kind `'class'` with name `String` and `frameworkMeta.swift_extension: true`. When the extension has a protocol conformance (`extension String: Encodable { ... }`), include `": Encodable"` in the signature.
|
|
85
|
-
- **Generic constraints** (`where T: Equatable`): very common in Swift — truncate after `where` clause if the signature exceeds 120 chars
|
|
86
|
-
- **`@objc` and `@objcMembers`**: include in signature as annotation prefix, do not affect extraction logic
|
|
87
|
-
|
|
88
|
-
**Verify:** Index `test/fixtures/swift-project/`. Verify class, struct, protocol, actor, extension, and top-level function extraction. Verify `private` and `fileprivate` symbols are skipped. Verify `///` doc comments are captured. Verify `extension String` produces a symbol named `String` with extension metadata.
|
|
89
|
-
|
|
90
|
-
**Tests:** `public class`, `struct`, `protocol`, `actor`, `extension` (named type), `extension` with protocol conformance, top-level `func`, class method, `init` and `init?`, `deinit`, `typealias`, `import`, `///` doc comment, `private func` (skipped), `fileprivate class` (skipped), `@State` property (attribute in signature), `async throws` function.
|
|
91
|
-
|
|
92
|
-
---
|
|
93
|
-
|
|
94
|
-
## Task 68: Vapor Adapter
|
|
95
|
-
|
|
96
|
-
Extract route and middleware symbols from Vapor server-side Swift applications. Vapor's routing API uses a method-call DSL on a `RoutesBuilder`.
|
|
97
|
-
|
|
98
|
-
**Deliverables:**
|
|
99
|
-
- `src/adapters/vapor.ts` — implements `FrameworkAdapter`
|
|
100
|
-
- `name`: `'vapor'`
|
|
101
|
-
- `extensions()`: `[]` — `.swift` files handled by the Swift handler
|
|
102
|
-
- `detect(projectRoot)`:
|
|
103
|
-
- Read `Package.swift` — check for `.package(url:` containing `vapor/vapor` (case-insensitive)
|
|
104
|
-
- Regex: `/\.package\s*\(.*["']https:\/\/github\.com\/vapor\/vapor/i`
|
|
105
|
-
- `fileFilter(filePath)`: `.swift` files only
|
|
106
|
-
- `extractFrameworkSymbols(tree, source, filePath)`:
|
|
107
|
-
- Scan for `call_expression` nodes matching Vapor's routing API:
|
|
108
|
-
- `app.get(...)`, `app.post(...)`, `app.put(...)`, `app.delete(...)`, `app.patch(...)`, `app.webSocket(...)` → kind `'route'`
|
|
109
|
-
- `routes.get(...)`, `router.get(...)`, etc. — same pattern with alternate variable names
|
|
110
|
-
- For each matched call:
|
|
111
|
-
- Extract the path components from the arguments (Vapor uses variadic path components: `app.get("users", ":id", use: handler)`)
|
|
112
|
-
- Join path components with `/` to form the route path string (e.g. `"users", ":id"` → `/users/:id`)
|
|
113
|
-
- Skip path components that are not string literals (e.g. `PathComponent.catchall`)
|
|
114
|
-
- Emit kind `'route'`
|
|
115
|
-
- `frameworkMeta.http_method`: uppercase method name
|
|
116
|
-
- `frameworkMeta.route_path`: constructed path string
|
|
117
|
-
- `frameworkMeta.vapor_route: true`
|
|
118
|
-
- Scan for classes or structs conforming to `RouteCollection` → emit kind `'class'` with `frameworkMeta.vapor_route_collection: true`
|
|
119
|
-
- Scan for `app.middleware.use(...)` calls → emit kind `'middleware'` with `frameworkMeta.vapor_middleware: true`
|
|
120
|
-
- `enrichMetadata(symbol)`: no-op
|
|
121
|
-
- Register via `registerAdapter(vaporAdapter)` at module level
|
|
122
|
-
|
|
123
|
-
**Key technical notes:**
|
|
124
|
-
- Vapor path components use string literals for static segments and `:paramName` for dynamic segments — both appear as string arguments to the route method
|
|
125
|
-
- Vapor's `PathComponent` enum (`.parameter("id")`, `.catchall`) is the typed equivalent — out of scope for Phase 7; skip non-string-literal path components
|
|
126
|
-
- `RouteCollection` protocol: classes/structs conforming to it define routes in a `boot(routes:)` method — the adapter emits the `RouteCollection` conformance as metadata but does not parse the `boot` method body (that would require data-flow analysis)
|
|
127
|
-
- Vapor middleware: `app.middleware.use(CORSMiddleware())` — extract the middleware type name as the symbol name
|
|
128
|
-
|
|
129
|
-
**Verify:** Index `test/fixtures/vapor-project/`. Verify `app.get("users", ":id", use: handler)` produces a route with path `/users/:id`. Verify `app.post("users", use: create)` produces a POST route. Verify `RouteCollection` conforming struct produces class symbol with metadata.
|
|
130
|
-
|
|
131
|
-
**Tests:** `app.get` single segment, `app.post` multi-segment path, dynamic path component (`:id`), `app.webSocket`, `RouteCollection` conformance, `app.middleware.use`, non-route call (not extracted).
|
|
132
|
-
|
|
133
|
-
---
|
|
134
|
-
|
|
135
|
-
## Task 69: Phase 7 Test Fixtures, Integration Tests, and Competitive Benchmark
|
|
136
|
-
|
|
137
|
-
Validate Phase 7 end-to-end and deliver a formal competitive benchmark comparing PureContext against jCodeMunch across all shared languages.
|
|
138
|
-
|
|
139
|
-
**Deliverables:**
|
|
140
|
-
|
|
141
|
-
- `test/fixtures/swift-project/` — representative Swift project:
|
|
142
|
-
- `Sources/Auth/AuthService.swift` — `public class AuthService`, methods, `///` doc comments
|
|
143
|
-
- `Sources/Models/User.swift` — `public struct User`, protocol conformances
|
|
144
|
-
- `Sources/Models/Role.swift` — `public enum Role`
|
|
145
|
-
- `Sources/Protocols/Authenticatable.swift` — `public protocol Authenticatable`
|
|
146
|
-
- `Sources/Extensions/String+Validation.swift` — `extension String` with methods
|
|
147
|
-
- `Sources/Actors/TokenStore.swift` — `public actor TokenStore`
|
|
148
|
-
- `Package.swift` — minimal package manifest (no Vapor dependency — that is in the Vapor fixture)
|
|
149
|
-
|
|
150
|
-
- `test/fixtures/vapor-project/` — minimal Vapor application:
|
|
151
|
-
- `Package.swift` — with `vapor/vapor` dependency
|
|
152
|
-
- `Sources/App/routes.swift` — `app.get`, `app.post`, route group
|
|
153
|
-
- `Sources/App/Controllers/UserController.swift` — `struct UserController: RouteCollection`
|
|
154
|
-
- `Sources/App/Middleware/AuthMiddleware.swift` — `app.middleware.use`
|
|
155
|
-
|
|
156
|
-
- Integration tests `test/integration/phase7.test.ts`:
|
|
157
|
-
1. Swift: `public class AuthService` extracted, `private func helper()` skipped
|
|
158
|
-
2. Swift: `public struct User: Encodable` → kind `'class'` with struct in signature
|
|
159
|
-
3. Swift: `public protocol Authenticatable` → kind `'interface'`
|
|
160
|
-
4. Swift: `public actor TokenStore` → kind `'class'` with `swift_actor: true`
|
|
161
|
-
5. Swift: `extension String` → kind `'class'` with `swift_extension: true`
|
|
162
|
-
6. Swift: `///` triple-slash doc comment captured
|
|
163
|
-
7. Swift: `async throws` included in function signature
|
|
164
|
-
8. Vapor: `app.get("users", ":id", use: handler)` → route with path `/users/:id`
|
|
165
|
-
9. Vapor: `app.post("users", use: create)` → route with http_method `POST`
|
|
166
|
-
10. Vapor: `RouteCollection` conformance → class with `vapor_route_collection: true`
|
|
167
|
-
11. Full suite regression: all Phase 1–6 tests still green
|
|
168
|
-
|
|
169
|
-
- **Competitive benchmark** `test/benchmarks/competitive.bench.ts`:
|
|
170
|
-
|
|
171
|
-
This benchmark measures PureContext token efficiency against jCodeMunch using the same corpus defined in `reference/jcodemunch-mcp/benchmarks/tasks.json`.
|
|
172
|
-
|
|
173
|
-
**Benchmark methodology** (identical to jCodeMunch's published approach):
|
|
174
|
-
- Baseline: concatenate all indexed source files for each repo, count tokens using `tiktoken cl100k_base` encoding
|
|
175
|
-
- PureContext workflow per query: `search-symbols` (max 5 results) + `get-symbol-source` for top 3 hits
|
|
176
|
-
- Token counting: sum all tool response JSON bytes / 4 (cl100k_base approximation)
|
|
177
|
-
- Reduction formula: `(1 - purecontext_tokens / baseline_tokens) * 100`
|
|
178
|
-
|
|
179
|
-
**Repos** (from `tasks.json`):
|
|
180
|
-
- `expressjs/express` — JavaScript/TypeScript (both tools index this fully)
|
|
181
|
-
- `nestjs/nest` — TypeScript with NestJS (PureContext has advantage via NestJS adapter)
|
|
182
|
-
- `gin-gonic/gin` — Go (both tools index this; add Gin adapter routes)
|
|
183
|
-
- `fastapi/fastapi` — Python (both tools index this; add FastAPI adapter routes)
|
|
184
|
-
- `rails/rails` — Ruby (Phase 5 added Ruby handler and Rails adapter)
|
|
185
|
-
|
|
186
|
-
**Queries** (from `tasks.json`, applied to all repos):
|
|
187
|
-
1. `router route handler`
|
|
188
|
-
2. `middleware`
|
|
189
|
-
3. `error exception`
|
|
190
|
-
4. `request response`
|
|
191
|
-
5. `context bind`
|
|
192
|
-
|
|
193
|
-
**Output format** (matches jCodeMunch's `results.md` table format for easy side-by-side comparison):
|
|
194
|
-
```
|
|
195
|
-
| Repo | Files | Baseline tokens | PureContext tokens | Reduction |
|
|
196
|
-
|-------------------|------:|----------------:|----------------:|----------:|
|
|
197
|
-
| expressjs/express | 34 | 73,838 | 3,124 | **95.8%** |
|
|
198
|
-
| ... | | | | |
|
|
199
|
-
| Grand total | — | 1,865,210 | — | —% |
|
|
200
|
-
```
|
|
201
|
-
|
|
202
|
-
**Run command:**
|
|
203
|
-
```bash
|
|
204
|
-
npm run benchmark:competitive
|
|
205
|
-
```
|
|
206
|
-
|
|
207
|
-
**Notes:**
|
|
208
|
-
- The benchmark requires the `index-repo` tool (Task 40) to clone and index the test repos
|
|
209
|
-
- Results are written to `benchmarks/results.md`
|
|
210
|
-
- jCodeMunch's canonical results are in `reference/jcodemunch-mcp/benchmarks/results.md` for direct comparison
|
|
211
|
-
- The benchmark is run once on demand, not as part of `npm run test` (it requires network access and disk space)
|
|
212
|
-
|
|
213
|
-
**Verify:** All Phase 7 tests pass. Benchmark produces a results table with token reduction percentages for each repo/query combination. `npm run test` green (1000+ tests, no regressions).
|
|
214
|
-
|
|
215
|
-
---
|
|
216
|
-
|
|
217
|
-
## Order of Execution
|
|
218
|
-
|
|
219
|
-
```
|
|
220
|
-
Task 67: Swift language handler ████░░░░░░ Swift
|
|
221
|
-
Task 68: Vapor adapter ████████░░ Swift/Vapor
|
|
222
|
-
Task 69: Fixtures + integration + bench ██████████ Polish
|
|
223
|
-
```
|
|
224
|
-
|
|
225
|
-
Tasks proceed strictly in order: the Swift handler (67) must be complete before the Vapor adapter (68), which must be complete before the integration tests and benchmark (69).
|
|
226
|
-
|
|
227
|
-
---
|
|
228
|
-
|
|
229
|
-
## Post-Phase 7: What Comes Next
|
|
230
|
-
|
|
231
|
-
With Phase 7 complete, PureContext will support the following languages and frameworks:
|
|
232
|
-
|
|
233
|
-
| Language | Handler | Framework Adapters |
|
|
234
|
-
|---|---|---|
|
|
235
|
-
| TypeScript / JavaScript | Phase 1 | Vue, Nuxt, React, Next.js, Angular, NestJS, Express, Fastify |
|
|
236
|
-
| Python | Phase 3 | Flask, FastAPI, Django |
|
|
237
|
-
| Go | Phase 3 | Gin, Echo, Fiber |
|
|
238
|
-
| Rust | Phase 4 | — |
|
|
239
|
-
| Java | Phase 4 | — |
|
|
240
|
-
| C# | Phase 4 | — |
|
|
241
|
-
| PHP | Phase 5 | Laravel, Symfony |
|
|
242
|
-
| Ruby | Phase 5 | Rails, Sinatra |
|
|
243
|
-
| Kotlin | Phase 5 | Ktor, Spring |
|
|
244
|
-
| C | Phase 5 | — |
|
|
245
|
-
| C++ | Phase 6 | — |
|
|
246
|
-
| Lua | Phase 6 | — |
|
|
247
|
-
| Dart | Phase 6 | Flutter |
|
|
248
|
-
| Swift | Phase 7 | Vapor |
|
|
249
|
-
|
|
250
|
-
**Potential future work after Phase 7:**
|
|
251
|
-
- Approximate nearest-neighbour semantic search (HNSW) for repos with > 50k symbols (Phase 41 item from PRD)
|
|
252
|
-
- Rate limiting and multi-tenant auth for hosted deployments
|
|
253
|
-
- Web UI for exploring the symbol graph visually
|
|
254
|
-
- Additional language handlers: Elixir, Haskell, Scala, R
|
|
255
|
-
- Additional framework adapters: Spring (Java), Hibernate, SQLAlchemy, Django ORM enrichment
|
|
256
|
-
- Rust framework adapters: Axum, Actix-web, Rocket
|
|
257
|
-
- Java framework adapters: Spring Boot (Java), Micronaut, Quarkus
|