Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 10 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

> **LLM-optimised code structure extractor** — Dart · Python · TypeScript · Rust · v0.1.0

A fast Rust CLI that statically analyses source files and returns a structured JSON map of every **class, interface, mixin, enum, and method** — together with its **exact line range** — without executing the code.
A fast Rust CLI that statically analyses source files and returns a structured JSON map of every **class, interface, mixin, enum, and method** — together with its **exact line range** and **documentation comments** — without executing the code.

---

Expand Down Expand Up @@ -50,11 +50,11 @@ The intended workflow is a **two-phase read pattern**:

| Language | Extension | Parser backend | Detects |
|---|---|---|---|
| **Dart** | `.dart` | Hand-rolled tokeniser | `class`, `abstract class`, `mixin`, `extension`, `enum` |
| **Python** | `.py` | tree-sitter-python 0.21 | `class` (all method types incl. `@decorator`) |
| **TypeScript** | `.ts`, `.tsx` | tree-sitter-typescript 0.21 | `class`, `abstract class`, `interface`, `enum` |
| **Dart** | `.dart` | Hand-rolled tokeniser | `class`, `abstract class`, `mixin`, `extension`, `enum` + `///` and `/** */` doc comments |
| **Python** | `.py` | tree-sitter-python 0.21 | `class` (all method types incl. `@decorator`) + docstrings |
| **TypeScript** | `.ts`, `.tsx` | tree-sitter-typescript 0.21 | `class`, `abstract class`, `interface`, `enum` + JSDoc comments |

For each type the tool extracts: `name`, `kind`, `line_start`, `line_end`, and an array of `methods` — each with their own line range.
For each type the tool extracts: `name`, `kind`, `line_start`, `line_end`, `doc` (documentation), and an array of `methods` — each with their own line range and optional documentation.

---

Expand Down Expand Up @@ -132,11 +132,12 @@ The tool always emits a JSON array — one element per parsed file.
"kind": "class",
"line_start": 8,
"line_end": 47,
"doc": "Handles all user-related operations including\nfetching, updating, and deleting users.",
"methods": [
{ "name": "UserService", "line_start": 12, "line_end": 12 },
{ "name": "fetchUser", "line_start": 15, "line_end": 22 },
{ "name": "UserService", "line_start": 12, "line_end": 12, "doc": "Creates a new UserService instance." },
{ "name": "fetchUser", "line_start": 15, "line_end": 22, "doc": "Fetches a user by ID from the remote API." },
{ "name": "get displayName", "line_start": 24, "line_end": 24 },
{ "name": "deleteUser", "line_start": 26, "line_end": 33 }
{ "name": "deleteUser", "line_start": 26, "line_end": 33, "doc": "Permanently deletes a user account." }
]
}
]
Expand All @@ -155,6 +156,7 @@ The tool always emits a JSON array — one element per parsed file.
| `kind` | string | `class`, `abstract class`, `interface`, `mixin`, `extension`, `enum` |
| `line_start` | number (1-based) | First line of the type declaration |
| `line_end` | number (1-based) | Last line of the closing brace |
| `doc` | string (optional) | Documentation comment (docstring, JSDoc, or Dart doc comment) |
| `methods` | array | All methods / constructors / getters / setters |

---
Expand Down
7 changes: 4 additions & 3 deletions code-parser-commands/README.md
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
# code-parser Claude Code Commands

Six slash commands that integrate `code-parser` into Claude Code for surgical,
token-efficient codebase navigation.
Seven slash commands that integrate `code-parser` into Claude Code for surgical,
token-efficient codebase navigation and documentation extraction.

## Commands

| Command | Arguments | Purpose |
|---|---|---|
| `/index` | `[path]` | Index a file or directory — shows all classes, methods, and line ranges |
| `/index` | `[path]` | Index a file or directory — shows all classes, methods, docs, and line ranges |
| `/parse-find` | `<name> [path]` | Locate a class or method — returns file and exact line range |
| `/parse-read` | `<file> <start> <end>` | Read specific lines from a file using the index |
| `/parse-docs` | `[path] [Class] [Method]` | Extract documentation comments (docstrings, JSDoc, Dart docs) |
| `/parse-edit` | `<file> <Class.method> <instruction>` | Surgical edit — indexes first, reads only relevant lines |
| `/parse-audit` | `[path]` | Full architecture report — class sizes, god classes, structural overview |
| `/parse-stats` | `[path]` | Token saving summary for the session |
Expand Down
24 changes: 14 additions & 10 deletions code-parser-commands/index.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
name: index
description: Index a file or directory with code-parser and display all classes, methods, and line ranges. Use this before reading any Dart, Python, or TypeScript source files to avoid loading entire files into context.
description: Index a file or directory with code-parser and display all classes, methods, documentation, and line ranges. Use this before reading any Dart, Python, or TypeScript source files to avoid loading entire files into context.
argument-hint: [path]
allowed-tools: Bash(code-parser *), Bash(ls *), Bash(find *)
---
Expand All @@ -25,32 +25,36 @@ If the binary is not found on PATH, check these locations before giving up:
- Each file found
- Every class/interface/mixin/enum with its kind and line range
- Every method inside each class with its line range
- Documentation comments (docstrings, JSDoc, Dart doc comments) when present
- Total counts: files indexed, classes found, methods found

3. Highlight anything notable:
- Large classes (more than 15 methods)
- Files with no classes (likely utility scripts)
- Any files that failed to parse (warnings from stderr)
- Classes/methods with documentation (indicated with 📝)

## Output format

Present the index as a structured, scannable summary — NOT raw JSON. Use a format like:

```
📁 lib/services/user_service.dart (dart)
└── UserService [class] lines 8–47
├── UserService() lines 12–12
├── fetchUser() lines 15–22
└── UserService [class] lines 8–47 📝
├── UserService() lines 12–12 📝
├── fetchUser() lines 15–22 📝
├── deleteUser() lines 24–31
└── get displayName lines 33–33

📁 lib/models/user.dart (dart)
└── User [class] lines 3–28
├── User() lines 7–7
├── fromJson() lines 10–16
└── toJson() lines 18–23
└── User [class] lines 3–28 📝
├── fromJson() lines 10–16 📝
└── toJson() lines 18–23 📝

Indexed: 2 files · 2 classes · 7 methods
Indexed: 2 files · 2 classes · 5 methods · 5 with docs
```

After the summary, remind the user they can now use `/parse-find` to locate specific classes, or `/parse-read` to read method bodies by line range.
After the summary, remind the user they can now use:
- `/parse-find` to locate specific classes
- `/parse-read` to read method bodies by line range
- `/parse-docs` to extract only documentation comments
1 change: 1 addition & 0 deletions code-parser-commands/install-commands.sh
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ echo "Done. Available commands:"
echo " /index [path] — index a file or directory"
echo " /parse-find <ClassName> [path] — locate a class or method"
echo " /parse-read <file> <start> <end> — read specific lines"
echo " /parse-docs [path] [Class] [Method] — extract documentation comments"
echo " /parse-edit <file> <Class.method> — surgical edit via index"
echo " /parse-audit [path] — full project structure report"
echo " /parse-stats [path] — token saving summary"
Expand Down
144 changes: 144 additions & 0 deletions code-parser-commands/parse-docs.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
---
name: parse-docs
description: Extract and display documentation (docstrings, JSDoc, Dart doc comments) from classes and methods using code-parser. Returns structured documentation without code bodies.
argument-hint: [path] [ClassName] [MethodName]
allowed-tools: Bash(code-parser *), Bash(jq *), Bash(ls *)
---

Extract documentation from the codebase at `$ARGUMENTS` using code-parser.

## Parse the arguments

- **No arguments**: Extract all docs from current directory
- **One argument (path)**: Extract all docs from specified path
- **Two arguments (path ClassName)**: Extract docs for specific class
- **Three arguments (path ClassName MethodName)**: Extract docs for specific method

## Steps

### 1. Run code-parser and extract docs

```bash
# All docs from path
code-parser ${PATH:-.} --format json | jq '
.[] | {
file: .file,
language: .language,
classes: [.classes[] | select(.doc != null) | {
name: .name,
kind: .kind,
doc: .doc,
methods: [.methods[] | select(.doc != null) | {name, doc}]
}]
} | select(.classes | length > 0)
'
Comment on lines +21 to +34

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Critical: ${PATH:-.} will use system PATH variable, not the command argument.

Line 23 uses ${PATH:-.} but PATH is a reserved system environment variable containing executable search paths. This will produce unexpected results. Use a different variable name or $1.

🐛 Proposed fix
 ```bash
 # All docs from path
-code-parser ${PATH:-.} --format json | jq '
+code-parser ${1:-.} --format json | jq '
   .[] | {
     file: .file,

Or use a more descriptive variable like ${TARGET_PATH:-.} with appropriate setup.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@code-parser-commands/parse-docs.md` around lines 21 - 34, The script
incorrectly uses the reserved environment variable ${PATH:-.} which will expand
to the system executable search path; update the command invocation in this file
to use a positional or non-reserved variable instead (e.g., replace ${PATH:-.}
with ${1:-.} or ${TARGET_PATH:-.}) so the CLI receives the intended directory
argument; locate the occurrence of ${PATH:-.} in the example command and change
it to the chosen safe variable name in the code block.


# Specific class docs
code-parser FILE --format json | jq --arg class "$CLASSNAME" '
.[0] | {
file: .file,
class: (.classes[] | select(.name == $class) | {
name: .name,
kind: .kind,
doc: .doc,
methods: [.methods[] | select(.doc != null) | {name, doc}]
})
}
'

# Specific method doc
code-parser FILE --format json | jq --arg class "$CLASSNAME" --arg method "$METHODNAME" '
.[0].classes[] | select(.name == $class) |
.methods[] | select(.name == $method) |
{class: .name, method: .name, doc: .doc}
'
```
Comment on lines +49 to +55

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Incorrect field reference in method doc extraction.

Line 53 creates {class: .name, method: .name, doc: .doc} but at this point in the jq pipeline, we're inside a method object (after select(.name == $method)). The .name here refers to the method's name, not the class name. The class name is lost.

🐛 Proposed fix to capture class name
 # Specific method doc
 code-parser FILE --format json | jq --arg class "$CLASSNAME" --arg method "$METHODNAME" '
-  .[0].classes[] | select(.name == $class) |
-  .methods[] | select(.name == $method) |
-  {class: .name, method: .name, doc: .doc}
+  .[0].classes[] | select(.name == $class) | 
+  . as $cls |
+  .methods[] | select(.name == $method) |
+  {class: $cls.name, method: .name, doc: .doc}
 '
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
# Specific method doc
code-parser FILE --format json | jq --arg class "$CLASSNAME" --arg method "$METHODNAME" '
.[0].classes[] | select(.name == $class) |
.methods[] | select(.name == $method) |
{class: .name, method: .name, doc: .doc}
'
```
# Specific method doc
code-parser FILE --format json | jq --arg class "$CLASSNAME" --arg method "$METHODNAME" '
.[0].classes[] | select(.name == $class) |
. as $cls |
.methods[] | select(.name == $method) |
{class: $cls.name, method: .name, doc: .doc}
'
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@code-parser-commands/parse-docs.md` around lines 49 - 55, The jq pipeline
loses the class name because after .[0].classes[] | select(.name == $class) you
descend into .methods[] so .name refers to the method; capture the class name
before iterating methods (e.g., bind the matched class to a variable with as
$cls or use the existing $class input) and then inside .methods[] | select(.name
== $method) construct the object using the captured class (use $cls or $class
for the class field) and the method's .name and .doc so {class: $cls, method:
.name, doc: .doc}.


### 2. Present findings clearly

Format the output as readable documentation:

```
📁 lib/services/user_service.dart (dart)

╔═══ UserService [class] ═════════════════════════════════════════╗
║ Handles all user-related operations including ║
║ fetching, updating, and deleting users from the API. ║
║ ║
║ Methods with documentation: ║
║ • UserService() ║
║ Creates a new UserService instance ║
║ ║
║ • fetchUser(id: String) ║
║ Fetches a user by ID from the remote API. ║
║ Throws [ApiException] if user not found. ║
║ ║
║ • deleteUser(id: String) ║
║ Permanently deletes a user account. ║
╚════════════════════════════════════════════════════════════════╝

📁 lib/models/user.dart (dart)

╔═══ User [class] ════════════════════════════════════════════════╗
║ Data model representing a user in the system. ║
║ ║
║ Methods with documentation: ║
║ • fromJson(json) ║
║ Creates a User from JSON map ║
║ ║
║ • toJson() ║
║ Converts User to JSON map ║
╚════════════════════════════════════════════════════════════════╝

Summary: 2 files · 2 classes · 5 documented methods
```

### 3. Handle edge cases

- **No documentation found**: Report "No documentation comments found in specified path"
- **Class not found**: Report "Class 'ClassName' not found in FILE"
- **Method not found**: Report "Method 'MethodName' not found in class 'ClassName'"

### 4. Optional: Generate API documentation

For generating markdown documentation:

```bash
code-parser ./lib --format json | jq -r '
.[] |
"# " + .file + "\n\n" +
(.classes[] |
"## " + .name + " (" + .kind + ")\n\n" +
(.doc // "No documentation") + "\n\n" +
"### Methods\n\n" +
(.methods[] |
"#### " + .name + "\n\n" +
(.doc // "No documentation") + "\n"
)
)
' > API_DOCS.md
```

## Usage examples

```bash
# Extract all documentation from project
/parse-docs ./lib

# Get docs for specific class
/parse-docs ./lib UserService

# Get docs for specific method
/parse-docs ./lib UserService fetchUser

# Generate markdown API documentation
code-parser ./src --format json | jq -r '...' > docs/API.md
```

## Notes

- Python: Extracts triple-quoted docstrings (`"""..."""` or `'''...'''`)
- TypeScript: Extracts JSDoc comments (`/** ... */`)
- Dart: Extracts doc comments (`///` or `/** ... */`)
- Only classes/methods with documentation are included in output
- Empty docstrings are treated as no documentation
Loading