@hasna/terminal 3.3.4 → 3.3.5

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.
@@ -149,14 +149,40 @@ function extractSymbols(filePath) {
149
149
  });
150
150
  continue;
151
151
  }
152
- // Classes
152
+ // Classes — also extract methods inside the class body
153
153
  const classMatch = line.match(/(?:export\s+)?class\s+(\w+)(?:\s+extends\s+(\w+))?/);
154
154
  if (classMatch) {
155
+ const className = classMatch[1];
155
156
  symbols.push({
156
- name: classMatch[1], kind: "class", file, line: lineNum,
157
+ name: className, kind: "class", file, line: lineNum,
157
158
  signature: line.trim().replace(/\{.*$/, "").trim(),
158
159
  exported: isExported,
159
160
  });
161
+ // Walk class body to find methods
162
+ let braceDepth = 0;
163
+ for (let j = i; j < lines.length; j++) {
164
+ for (const ch of lines[j]) {
165
+ if (ch === "{")
166
+ braceDepth++;
167
+ if (ch === "}")
168
+ braceDepth--;
169
+ }
170
+ if (j > i) {
171
+ const memberLine = lines[j];
172
+ // Class methods: async methodName(...), methodName(...), get/set name(...)
173
+ const methodMatch = memberLine.match(/^\s+(?:async\s+)?(?:(?:public|private|protected|static|readonly|override|abstract)\s+)*(?:get\s+|set\s+)?(\w+)\s*[\(<]/);
174
+ const RESERVED = new Set(["if", "for", "while", "switch", "catch", "return", "throw", "new", "delete", "typeof", "void", "yield", "await", "try", "else"]);
175
+ if (methodMatch && !RESERVED.has(methodMatch[1])) {
176
+ symbols.push({
177
+ name: `${className}.${methodMatch[1]}`, kind: "function", file, line: j + 1,
178
+ signature: memberLine.trim().replace(/\{.*$/, "").trim(),
179
+ exported: isExported,
180
+ });
181
+ }
182
+ }
183
+ if (braceDepth === 0 && j > i)
184
+ break; // end of class
185
+ }
160
186
  continue;
161
187
  }
162
188
  // Interfaces
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hasna/terminal",
3
- "version": "3.3.4",
3
+ "version": "3.3.5",
4
4
  "description": "Smart terminal wrapper for AI agents and humans — structured output, token compression, MCP server, natural language",
5
5
  "type": "module",
6
6
  "files": [
@@ -172,14 +172,37 @@ function extractSymbols(filePath: string): CodeSymbol[] {
172
172
  continue;
173
173
  }
174
174
 
175
- // Classes
175
+ // Classes — also extract methods inside the class body
176
176
  const classMatch = line.match(/(?:export\s+)?class\s+(\w+)(?:\s+extends\s+(\w+))?/);
177
177
  if (classMatch) {
178
+ const className = classMatch[1];
178
179
  symbols.push({
179
- name: classMatch[1], kind: "class", file, line: lineNum,
180
+ name: className, kind: "class", file, line: lineNum,
180
181
  signature: line.trim().replace(/\{.*$/, "").trim(),
181
182
  exported: isExported,
182
183
  });
184
+ // Walk class body to find methods
185
+ let braceDepth = 0;
186
+ for (let j = i; j < lines.length; j++) {
187
+ for (const ch of lines[j]) {
188
+ if (ch === "{") braceDepth++;
189
+ if (ch === "}") braceDepth--;
190
+ }
191
+ if (j > i) {
192
+ const memberLine = lines[j];
193
+ // Class methods: async methodName(...), methodName(...), get/set name(...)
194
+ const methodMatch = memberLine.match(/^\s+(?:async\s+)?(?:(?:public|private|protected|static|readonly|override|abstract)\s+)*(?:get\s+|set\s+)?(\w+)\s*[\(<]/);
195
+ const RESERVED = new Set(["if", "for", "while", "switch", "catch", "return", "throw", "new", "delete", "typeof", "void", "yield", "await", "try", "else"]);
196
+ if (methodMatch && !RESERVED.has(methodMatch[1])) {
197
+ symbols.push({
198
+ name: `${className}.${methodMatch[1]}`, kind: "function", file, line: j + 1,
199
+ signature: memberLine.trim().replace(/\{.*$/, "").trim(),
200
+ exported: isExported,
201
+ });
202
+ }
203
+ }
204
+ if (braceDepth === 0 && j > i) break; // end of class
205
+ }
183
206
  continue;
184
207
  }
185
208