agentsclimarketplace

Line locator

Skill unkluco/line-locator

Agent skill for precise code navigation: locate functions fast, read less, save tokens.

Install
npx -y skills add unkluco/line-locator

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

One thing to look at

  • 7 stars7 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

What its author says it does

Copied from the file, not written here

Định vị dòng trước khi đọc file hoặc tìm file trong cây thư mục — tránh đọc mù, tiết kiệm token. Dùng khi cần tìm hàm, class, symbol, hoặc bất kỳ pattern nào trong source code trước khi gọi view_range. Hai công cụ: findtree.py (tìm file nào có chứa pattern) và findtool.py (tìm dòng nào trong một file).

SKILL.md

17.4 KB, as published. Nobody here has run it

Line-Locator

Hai script phối hợp để định vị chính xác trước khi đọc:

ScriptPhạm viCâu hỏi trả lời
findtree.pyCả cây thư mụcFile nào chứa pattern này?
findtool.pyMột file duy nhấtDòng nào trong file này?

Workflow:

findtree.py (shortlist files) → findtool.py (locate lines) → view_range (read)

Script nằm tại: skills/line-locator/scripts/


Output contract

Tất cả pattern dùng Python regex.

findtool — success (stdout):

{"matches": {"processOrder": [247, 312]}}
{"line": 248}
{"matched": true}

findtree — success (stdout):

{"matched_files": ["src/order.js", "tests/order.test.js"]}

Failure — cả hai tool (stderr, exit 1):

{"ok": false, "error": "No line matching pattern 'foo' was found after line 0."}

Parse nhanh:

import json, subprocess
out = subprocess.check_output([...])
data = json.loads(out)

# findtool
lines   = data["matches"]["pat"]   # -mr  → list[int]
line    = data["line"]             # -n / -b / -c / -o → int
matched = data["matched"]          # -e   → bool

# findtree
files   = data["matched_files"]    # list[str] relative paths

findtree — tìm file

python findtree.py --root ROOT --pattern PAT [options]
OptionMặc địnhMô tả
--root(required)Thư mục gốc
--pattern(required)Regex pattern
--include GLOB...(tất cả)Chỉ tìm file khớp glob
--exclude GLOB...(không)Bỏ qua file/thư mục khớp glob
--ignore-caseoffCase-insensitive
--max-results N(không giới hạn)Dừng sau N file
--showmatchedmatched / errors / both / summary / all
--max-file-size(không)Bỏ qua file lớn hơn (VD: 64K, 10M)
--no-default-dir-excludesoffTắt auto-skip .git, node_modules, v.v.
--textoffOutput text thay vì JSON

Auto-excluded dirs: .git, .hg, node_modules, venv, .venv, __pycache__, dist, build, target, .mypy_cache, .pytest_cache, .tox, coverage

python findtree.py --root ./src --pattern "processOrder"
python findtree.py --root ./src --pattern "class\s+\w+Service"
python findtree.py --root . --pattern "TODO" --include "*.ts" "*.js" --exclude "dist/**"
python findtree.py --root . --pattern "deprecated_api" --max-results 1

findtool — tìm dòng

python findtool.py --file FILE [--ignore-case] [-s] FLAG... [--text]
FlagArgsMô tảresult key
-mrPAT [PAT ...]Tất cả dòng khớp một hoặc nhiều pattern{"matches": {"pat": [1,5]}}
-nPAT LINEDòng đầu tiên khớp sau LINE (0 = từ đầu file){"line": 45}
-bPAT LINEDòng cuối cùng khớp trước LINE (999999 = cuối file){"line": 12}
-ePATFile có chứa pattern không?{"matched": true}
-cOPEN CLOSE LINE NDòng đóng khớp với OPEN thứ N trên LINE (scan xuôi){"line": 89}
-oOPEN CLOSE LINE NDòng mở khớp với CLOSE thứ N trên LINE (scan ngược){"line": 34}

Flag -s (chỉ dùng với -c/-o): bỏ qua nội dung string và comment khi đếm depth.

python findtool.py --file app.js -mr "processOrder"
python findtool.py --file app.js -mr "processOrder" "cancelOrder" "getUser"
python findtool.py --file app.js -n "function\s+\w+" 0
python findtool.py --file app.js -b "^import\s" 999999
python findtool.py --file app.js -e "TODO"
python findtool.py --file app.js -c "\{" "\}" 248 1
python findtool.py --file app.js -c "\{" "\}" 248 1 -s
python findtool.py --file app.js -o "\{" "\}" 298 1

Pair matching (-c / -o)

Cả hai flag đều nhận OPEN CLOSE LINE N theo cùng thứ tự:

-c  OPEN  CLOSE  LINE  N  →  anchor tại OPEN thứ N trên LINE, scan xuôi  → trả về dòng CLOSE
-o  OPEN  CLOSE  LINE  N  →  anchor tại CLOSE thứ N trên LINE, scan ngược → trả về dòng OPEN

Algorithm: depth-tracking. Mỗi dòng tiếp theo: depth += count(OPEN) - count(CLOSE). Khi depth == 0 → trả về dòng đó.

Flag -s: trước khi đếm, mask toàn bộ string literals và comments (//, #, /* */, '...', "...", backtick, triple-quote). Dùng khi file có nhiều delimiter trong string/comment.

Pairs phổ biến theo ngôn ngữ

Ngôn ngữBlock mởBlock đóngGhi chú
JS/TS/Java/Go/Rust/C/C++/C#\{\}Dùng -s nếu file có { trong string
Bất kỳ — argument list\(\)Áp dụng mọi ngôn ngữ
Bất kỳ — array/list\[\]Áp dụng mọi ngôn ngữ
HTML/XML<div\b[^>]*></div>Thay div bằng tên tag
Ruby\bdo\b\bend\bHoặc \bdef\b / \bend\b
Lua / Pascal-like\bdo\b\bend\b
Shell (bash)\bthen\b|\bdo\b\bfi\b|\bdone\bPhức tạp hơn
Python(không có bracket)(xem note bên dưới)Dùng -n tìm def tiếp theo

Python note: Python dùng indentation thay vì {}. Để tìm cuối hàm, dùng -n "^(def\|class)\s" FUNC_LINE tìm def/class tiếp theo cùng cấp, hoặc đọc từ FUNC_LINE đến dòng trước đó. Với argument list nhiều dòng: -c "\(" "\)" FUNC_LINE 1 vẫn hoạt động.

# JS/TS function
python findtool.py --file service.ts -c "\{" "\}" 248 1 -s
# → {"line": 298}

# HTML div
python findtool.py --file index.html -c "<div\b[^>]*>" "</div>" 10 1
# → {"line": 25}

# Ruby method
python findtool.py --file user.rb -c "\bdef\b" "\bend\b" 42 1
# → {"line": 67}

# Argument list dài nhiều dòng (mọi ngôn ngữ)
python findtool.py --file builder.java -c "\(" "\)" 120 1
# → {"line": 128}

# -o: đang ở dòng }, tìm dòng {
python findtool.py --file app.go -o "\{" "\}" 298 1
# → {"line": 248}

Workflows

1. Đọc một hàm đã biết tên

# Bước 1: Tìm dòng định nghĩa
python findtool.py --file app.js -mr "processOrder"
# → {"matches": {"processOrder": [247, 312]}}  → 247 là định nghĩa

# Bước 2: Tìm dòng OPEN thực sự (KHÔNG đoán cùng dòng hay dòng dưới)
python findtool.py --file app.js -n "\{" 247
# → {"line": 248}

# Bước 3: Tìm dòng đóng
python findtool.py --file app.js -c "\{" "\}" 248 1
# → {"line": 298}

# Bước 4: Đọc
view_range [247, 298]

2. Từ repository lạ → đọc hàm

python findtree.py --root ./src --pattern "processOrder"
# → {"matched_files": ["services/order.js"]}

python findtool.py --file services/order.js -mr "processOrder"
# → tiếp tục Workflow 1

3. Scan cấu trúc tổng thể file

# JS/TS/Java/Go/C#
python findtool.py --file service.ts -mr "class\s+\w+" "function\s+\w+" "\bexport\b"

# Python
python findtool.py --file service.py -mr "^class\s+\w+" "^def\s+\w+" "^    def\s+\w+"

# Ruby
python findtool.py --file user.rb -mr "^\s*def\s+\w+" "^\s*class\s+\w+"

# Java/C#
python findtool.py --file Service.java -mr "public\s+\w" "private\s+\w" "protected\s+\w"

4. Tìm nhiều symbol cùng lúc

python findtool.py --file app.js -mr "processOrder" "cancelOrder" "getUser"
# → {"matches": {"processOrder": [247], "cancelOrder": [312], "getUser": [89]}}
# Lên kế hoạch đọc toàn bộ từ một lần call

5. Đọc tất cả imports

# JS/TS
python findtool.py --file app.ts -mr "^import\s"
# → {"matches": {"^import\\s": [1,2,3,14,15]}} → view_range [1, 15]

# Python
python findtool.py --file app.py -mr "^import\s" "^from\s"

# Java/C#
python findtool.py --file App.java -mr "^import\s" "^using\s"

# Go
python findtool.py --file main.go -mr "^\s*\"" 
# (lines inside import block — hoặc tìm block import trước)

6. Xác định dòng đang thuộc scope nào (ngôn ngữ có {})

python findtool.py --file dao.js -b "\{" X    # → OPEN_LINE
python findtool.py --file dao.js -c "\{" "\}" OPEN_LINE 1  # verify X trong scope này
view_range [OPEN_LINE - 1, OPEN_LINE]         # đọc tên scope

7. Leo scope chain

python findtool.py --file app.js -b "\{" 245  →  198
python findtool.py --file app.js -b "\{" 198  →  134
python findtool.py --file app.js -b "\{" 134  →  12
python findtool.py --file app.js -b "\{" 12   →  error → top-level

8. Tìm decorator / annotation

# Python decorator
python findtool.py --file routes.py -b "@\w+" FUNC_LINE
# → nếu kết quả >= FUNC_LINE - 3 → có decorator trực tiếp

# Java/C# annotation
python findtool.py --file Controller.java -b "@\w+" FUNC_LINE

# JS/TS decorator
python findtool.py --file service.ts -b "@\w+" FUNC_LINE

9. Tìm else / catch / finally

python findtool.py --file handler.js -c "\{" "\}" IF_LINE 1  # → close of if-block
python findtool.py --file handler.js -n "else|catch|finally" CLOSE_LINE
# → nếu ngay sau CLOSE_LINE → đây là else/catch của block đó

⚠️ Sai lầm phổ biến

1. Gọi -c trên dòng function name thay vì dòng {

# ❌ SAI — dòng 247 có tên hàm nhưng chưa chắc có {
python findtool.py --file app.js -c "\{" "\}" 247 1
# → error: "Line 247 contains only 0 occurrence(s) of open pattern '\{'"

# ✅ ĐÚNG — tìm dòng { trước, rồi mới -c
python findtool.py --file app.js -n "\{" 247   # → {"line": 248}
python findtool.py --file app.js -c "\{" "\}" 248 1

Lý do: Trong nhiều ngôn ngữ, { có thể ở dòng tiếp theo sau tên hàm (Allman style). Không bao giờ đoán.


2. Nhầm lẫn kết quả đầu tiên của -mr là định nghĩa

python findtool.py --file app.js -mr "processOrder"
# → {"matches": {"processOrder": [89, 247, 312]}}
#   89  = call site hoặc comment
#   247 = định nghĩa hàm (def/function)
#   312 = call site khác

Số nhỏ nhất chưa chắc là định nghĩa. Đọc thêm vài dòng context để xác nhận, hoặc dùng pattern cụ thể hơn:

python findtool.py --file app.js -mr "function processOrder" "processOrder\s*\("
# → pattern cụ thể hơn → ít kết quả giả hơn

3. Pattern có ký tự đặc biệt không escape

# ❌ SAI — regex error vì ( không được escape
python findtool.py --file app.py -mr "foo(bar)"
# → {"ok": false, "error": "Invalid regex pattern 'foo(bar)': missing ), ..."}

# ✅ ĐÚNG
python findtool.py --file app.py -mr "foo\(bar\)"
# hoặc dùng word boundary thay vì match toàn bộ call:
python findtool.py --file app.py -mr "foo"

Ký tự cần escape trong regex: . ^ $ * + ? { } [ ] \ | ( )


4. Dùng Python {} để match scope hàm

Python không dùng {} cho function/class body. Dùng -c "\{" "\}" sẽ chỉ match dict/set literals.

# ❌ Không có tác dụng cho Python function body
python findtool.py --file service.py -c "\{" "\}" 42 1

# ✅ Python: tìm def/class tiếp theo cùng level
python findtool.py --file service.py -n "^def \|^class " 42
# → dòng tiếp theo ở cùng indent level = kết thúc hàm hiện tại

# ✅ Python method trong class:
python findtool.py --file service.py -n "^    def " 42

5. Quên rằng -nsau LINE, không phải tại LINE

python findtool.py --file app.js -n "def " 247
# → Tìm match STRICTLY AFTER dòng 247, không phải tại 247
# Nếu def ở dòng 247 → sẽ không được trả về

# Để bao gồm chính dòng đó:
python findtool.py --file app.js -n "def " 246  # tìm sau dòng 246

6. Bỏ qua -s khi file có nhiều { trong string/comment

# File có: const tmpl = `SELECT * FROM t WHERE col = '{value}'`
# ❌ Không -s: depth tracking đếm sai vì { trong template string
python findtool.py --file query.ts -c "\{" "\}" 50 1
# → kết quả sai

# ✅ Dùng -s để bỏ qua string/comment
python findtool.py --file query.ts -c "\{" "\}" 50 1 -s

Nên dùng -s khi: file là template (.html, .ejs, .hbs), SQL inline, hoặc bất kỳ file nào có nhiều { không phải code.


7. Dùng findtool trực tiếp mà không biết file ở đâu

# ❌ Tốn thời gian — không biết file nào
python findtool.py --file src/auth/service.js -mr "validateToken"
# → File not found

# ✅ findtree trước
python findtree.py --root ./src --pattern "validateToken"
# → {"matched_files": ["src/auth/service.js"]}

8. Không biết ngôn ngữ dùng { hay không → kiểm tra trước

Trước khi dùng -c "\{" "\}", xác nhận file có { không:

python findtool.py --file service.py -e "\{"
# → {"matched": false} → Python file, không có {-based scope
# → {"matched": true}  → file có {, tiến hành bình thường

9. Dùng \| thay vì | cho alternation trong Python regex

# ❌ SAI — \| trong Python regex là ký tự pipe literal, không phải alternation
python findtool.py --file app.java -mr "focusLost\|hidePopup\|showPopup"
# → {"matches": {"focusLost\\|hidePopup\\|showPopup": []}}  ← tìm chuỗi literal   "focusLost|hidePopup|showPopup"

# ✅ ĐÚNG — | không cần escape trong Python regex
python findtool.py --file app.java -mr "focusLost|hidePopup|showPopup"
# → {"matches": {"focusLost|hidePopup|showPopup": [192, 723, 701]}}

Lý do nhầm: grep basic mode (BRE) dùng \| cho alternation. Python dùng ERE-style — | đã là   alternation, \| là literal pipe.

Khi nào \| hợp lệ: không bao giờ trong Python regex nếu mục đích là alternation.

Bảng quyết định nhanh

Tình huốngDùng gì
Chưa biết file nàofindtree --root ... --pattern ...
Biết tên hàm, muốn đọc body (ngôn ngữ có {})-mr "name"-n "\{" LINE-c "\{" "\}" OPEN 1
Ngôn ngữ không có {} (Python...)-mr "name"-n "^def|^class" LINE
Nhiều hàm cùng lúc-mr "fn1" "fn2" "fn3"
Pattern có ký tự đặc biệtescape: \(, \), \{, \., v.v.
File có nhiều { trong stringthêm -s vào -c/-o
Duyệt từng hàm không biết tên-mr "\{"-c "\{" "\}"-n "\{" → lặp
Ở dòng X, muốn biết thuộc hàm nào-b "\{" X-c "\{" "\}" OPEN 1 verify
Đọc hết imports-mr "^import\s" → min/max → view_range
Argument list nhiều dòng-c "\(" "\)" LINE 1
Tìm else/catch/finally-c "\{" "\}" IF_LINE 1-n "else|catch|finally"
Có decorator/annotation không?-b "@\w+" FUNC_LINE → check khoảng cách
HTML tag pair-c "<tag\b[^>]*>" "</tag>" LINE 1
Ruby/Lua method body-c "\bdef\b" "\bend\b" LINE 1
Scope ngoài cùng-b "\{" lặp đến error
File có chứa pattern không?-e "pattern"
Chỉ tìm trong file .ts .jsfindtree --include "*.ts" "*.js"
Dừng sớm khi tìm đủfindtree --max-results 1

Xử lý lỗi

LỗiNguyên nhânCách xử lý
"For -n, LINE must be >= 0"Truyền số âm vào -nDùng 0 để tìm từ đầu file
"For -b, LINE must be >= 1"Truyền 0 vào -bDùng 999999 để tìm từ cuối file
"Line X contains only 0 occurrence(s) of open pattern"{ không ở dòng đóDùng -n "\{" FUNC_LINE để tìm dòng { thực tế
"No closing match for open pattern"Không tìm thấy CLOSE trong fileFile chưa đóng bracket, hoặc dùng thêm -s
"No line matching pattern ... was found"Pattern không khớp trong phạm viKiểm tra lại regex; với -b có thể tăng LINE
"Invalid regex pattern"Regex sai cú phápEscape: \(, \), \{, \.
"Root directory not found"--root không tồn tạiKiểm tra lại đường dẫn
"N must be >= 1"N = 0 trong -c/-oN bắt đầu từ 1

Ví dụ end-to-end

Bài toán: Đọc hàm validateToken trong codebase 50 file, không biết nó nằm ở đâu.

# 1. Tìm file
python findtree.py --root ./src --pattern "validateToken"
# → {"matched_files": ["auth/service.ts"]}

# 2. Tìm dòng định nghĩa
python findtool.py --file auth/service.ts -mr "validateToken"
# → {"matches": {"validateToken": [312, 467]}}  → 312 là định nghĩa

# 3. Kiểm tra decorator
python findtool.py --file auth/service.ts -b "@\w+" 312
# → {"line": 310}  → có decorator ở dòng 310

# 4. Tìm dòng {
python findtool.py --file auth/service.ts -n "\{" 312
# → {"line": 313}

# 5. Tìm dòng đóng (dùng -s vì file TS hay có template string)
python findtool.py --file auth/service.ts -c "\{" "\}" 313 1 -s
# → {"line": 389}

# 6. Đọc
view_range [310, 389]

Token tiêu thụ: ~80 dòng thay vì hàng nghìn. Tiết kiệm >90%.

Keep looking

Skills are one crate of 328,083. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.