ابزارهای داخلی عامل
اینها ابزارهایی مقید به سرور هستند که زمان اجرای عامل داخلی مستقیماً ثبت میکند — سرور زبان، جستوجوی ساختاری، اشکالزدا، کرنلها، پرسشها و کنترل کارگر — در برابر ابزارهای MCP که پل میزند و ابزارهای عمومی فایل، جستوجو و شل از زمان اجرای هارنس. اینها روی رجیستری MCP نیستند: یک کارخواه بیرونی MCP آنها را نمیبیند، چون هرکدام به یک منبع زندهٔ سمت سرور مقید است — یک فرایند سرور زبان، یک آداپتور اشکالزدا، یک مفسر — که به یک اجرا تعلق دارد.
هر ابزار اینجا تنها زمانی ثبت میشود که منبع پشتیبانش برای اجرا سیمکشی شده باشد — یک ناظر سرور زبان یا اشکالزدایی، یک تجزیهگر tree-sitter، یک کارخانهٔ کرنل، یک پورت پرسش، یک فهرست vibe. تشخیص یک سرور زبان یا آداپتور اشکالزدا برای همین چکاوت بررسیای جداگانه و دیرتر است (status / adapters): آن ابزارها روی سطح میمانند تا عامل بتواند بپرسد چرا هیچچیز قابل استفاده نیست، بهجای اینکه حدس بزند.
ردههای تأیید
بخش با عنوان “ردههای تأیید”هر ابزار یک رده اعلام میکند، و رده تعیین میکند کدام سطحها آن را میبینند — نه فقط اینکه آیا پرامپت میدهد یا نه. حالت برنامه و زیرعاملهای فقطخواندنی تا read سقفگذاری شدهاند، پس ابزاری در ردهٔ write یا exec بهکل از شمای آنان غایب است.
| رده | معنا | ابزارهای اینجا |
|---|---|---|
read |
بدون اثر جانبی | lsp، ast_grep، ask_user، پنج vibe_* |
write |
فایلها را تغییر میدهد | lsp_rename، ast_edit، resolve |
exec |
یک فرایند را آغاز یا کنترل میکند | debug، eval |
lsp — پرسوجوهای سرور زبان
بخش با عنوان “lsp — پرسوجوهای سرور زبان”وقتی اجرا یک ناظر سرور زبان و یک پوشهٔ کاری داشته باشد ثبت میشود. اینکه یک سرور واقعاً بتواند پاسخ دهد، در زمان فراخوانی بهصورت یک اشتراک تشخیص داده میشود: هم باید نشانگر ریشه وجود داشته باشد و هم باینری سرور قابل یافتن باشد. هر یک بهتنهایی یعنی هیچ سروری آغاز نمیشود — status همین را میگوید — نه یک حدس بیصدا.
موقعیتها با line بهعلاوهٔ یک زیررشتهٔ symbol نشانی میشوند، هرگز با ستون. مدلی که از او ستون بخواهند، حدس میزند، و یک حدس غلط به نماد دیگری در همان خط میرسد — پاسخی که درست به نظر میرسد و دربارهٔ چیز دیگری است. حذف symbol در یک کنش ناوبری یک خطاست، نه حدس زدن ستون نخست.
| کنش | آرگومانها | برمیگرداند |
|---|---|---|
diagnostics |
file (یا "*") |
خطاها و هشدارها؛ "*" بهجایش بررسیکنندهٔ پروژه را اجرا میکند |
definition |
file, line, symbol |
جایی که نماد اعلان شده است |
type_definition |
file, line, symbol |
جایی که نوعش اعلان شده است |
implementation |
file, line, symbol |
پیادهسازیهای عینی |
references |
file, line, symbol |
هر کاربرد، حداکثر ۵۰ مورد |
hover |
file, line, symbol |
امضا و کامنت مستندات |
symbols |
query یا file |
جستوجوی فضای کاری با query (حداکثر ۱۰۰ مورد)؛ نمادهای سند با file (حداکثر ۲۰۰ مورد) |
code_actions |
file, line, symbol |
اصلاحهای سریعی که سرور عرضه میکند |
status |
— | کدام سرورها در حال اجرا هستند، و برای کدام ریشهها |
reload |
— | سرور را برای این ریشه دوباره راهاندازی میکند |
پیامهای تشخیصی هنگام نوشتن
بخش با عنوان “پیامهای تشخیصی هنگام نوشتن”سود ماجرا خودِ ابزار نیست. write، edit و apply_patch پیچیده شدهاند: پس از نوشتن، فایل از سرور زبان همگام و ذخیره میشود، و تنها پیامهای تشخیصی تازهمعرفیشده در نتیجهٔ ابزار گنجانده میشوند. عامل همان لحظهای که بیلد را شکسته است میفهمد که شکسته، بدون اینکه لازم باشد یادش باشد که بپرسد.
پیامهای تشخیصیای که پیشتر گزارش شدهاند، با یک دفتر ثبت بهازای هر اجرا سرکوب میشوند که کلیدش شدت، کد و پیام است — موقعیت عمداً کنار گذاشته شده است، پس پیامی تشخیصی که فقط چهار خط پایینتر رفته است، دوباره بهعنوان تازه گزارش نمیشود.
lsp_rename — تغییر نام در سراسر پروژه
بخش با عنوان “lsp_rename — تغییر نام در سراسر پروژه”ابزاری جداگانه در ردهٔ write، دقیقاً به یک دلیل: رده است که دیدپذیری را تعیین میکند. گنجاندن تغییر نام در lsp یا به یک کاوشگر فقطخواندنی توان بازنویسی مخزن را میدهد، یا هر hover را پشت یک پرامپت تأیید میگذارد.
| آرگومان | معنا |
|---|---|
file |
جایی که نماد قرار دارد |
line |
خط با شمارهگذاری از ۱ |
symbol |
زیررشتهای که آن را در آن خط مشخص میکند |
new_name |
نام تازهٔ آن |
ast_grep — جستوجوی ساختاری
بخش با عنوان “ast_grep — جستوجوی ساختاری”کد را بر پایهٔ شکل مییابد، نه بر پایهٔ متن. $NAME با هر گره مطابقت میکند، $$$NAME با رشتهای از گرههای خواهر و برادر، و $_ یک نویسهٔ عام است که چیزی را مقید نمیکند.
ویژگیای که آن را بهجای یک regex با چند مرحلهٔ اضافه، یک تطبیقدهنده میکند این است: فرامتغیری که در یک الگو تکرار میشود باید همان متن را بگیرد.
ast_grep(pattern: "if ($X != null) $X.dispose()", language: "dart")با نگهبانی مطابقت میکند که همان چیزی را که آزموده آزاد میکند، و با نگهبانی که چیز دیگری را آزاد میکند مطابقت نمیکند.
| آرگومان | معنا |
|---|---|
pattern |
قطعهای کد با فرامتغیرها |
path |
فایل یا پوشهای که جستوجو شود؛ بهطور پیشفرض کل فضای کاری |
language |
شناسهٔ یک گرامر عرضهشده (dart, python, rust, c, …). وقتی path نام یک فایل را ببرد، استنباط میشود |
max_results |
پیشفرض ۵۰ |
ast_edit — بازنویسی ساختاری، در مرحلهٔ آمادهسازی
بخش با عنوان “ast_edit — بازنویسی ساختاری، در مرحلهٔ آمادهسازی”همان تطبیق، بههمراه یک الگوی rewrite که در آن فرامتغیرها بازجایگذاری شدهاند. هیچ چیزی نوشته نمیشود. تغییر در مرحلهٔ آمادهسازی نگه داشته میشود و نتیجه یک edit_id نام میبرد.
ast_edit(pattern: "dispose($X)", rewrite: "$X.dispose()", language: "dart")→ (proposed) 12 replacements in 4 files … call resolve with edit_id "edit_1"| آرگومان | معنا |
|---|---|
pattern |
آنچه باید مطابقت داده شود |
rewrite |
آنچه باید آنجا گذاشته شود، با جایگذاری $NAME |
path |
محدوده؛ بهطور پیشفرض کل فضای کاری |
language |
شناسهٔ زبان |
resolve — کامیت یا دور انداختن یک تغییر آمادهشده
بخش با عنوان “resolve — کامیت یا دور انداختن یک تغییر آمادهشده”| آرگومان | معنا |
|---|---|
edit_id |
از نتیجهٔ (proposed) |
action |
accept یا discard |
هر فایل با محتوایی سنجیده میشود که در زمان آمادهسازی ثبت شده است، و هر ناهمخوانی کل تغییر را رد میکند. بازنویسی ساختاری نیمهاعمالشده درختی بر جا میگذارد که زیر هیچیک از آن دو شکل، نه شکل قدیم و نه شکل تازه، کامپایل نمیشود.
debug — راندن یک اشکالزدا
بخش با عنوان “debug — راندن یک اشکالزدا”وقتی اجرا یک ناظر نشست اشکالزدایی، یک پوشهٔ کاری و یک شناسهٔ گفتگو داشته باشد ثبت میشود. اینکه یک آداپتور واقعاً بتواند آغاز به کار کند، در زمان فراخوانی و با همان قاعدهٔ اشتراک سرور زبان تشخیص داده میشود (نشانگر ریشه و باینری). ردهٔ exec؛ موازیایمن نیست (یک نشست وضعیتی است که میان فراخوانیها میماند، پس اگر continue از stack جلو بزند، فریمی را میخواند که پیشتر جابهجا شده است).
یک نشست بهازای هر گفتگو، با یک TTL سخت (۳۰ دقیقه). launch دوم رد میشود، نه اینکه بیصدا جای اولی را بگیرد.
| عملیات | آرگومانها | یادداشتها |
|---|---|---|
adapters |
— | کدام آداپتورها اینجا قابل استفادهاند، و چرا نه |
status |
— | آیا نشستی در حال اجراست، و کجا متوقف شده |
breakpoints |
file, lines[] |
lines خالی فایل را پاک میکند. میتواند پیش از راهاندازی تنظیم شود |
launch |
program, args[] |
برنامه را متوقف روی نقاط توقف شما آغاز میکند |
attach |
port |
به برنامهٔ در حال اشکالزدایی که از قبل در حال اجراست وصل میشود |
continue |
thread_id? |
تا توقف بعدی اجرا میکند |
pause |
thread_id? |
همانجا که هست متوقفش میکند |
step_over / step_in / step_out |
thread_id? |
یک گام پیش میرود |
threads |
— | شناسهها و نامهای رشتهها |
stack |
thread_id? |
فریمها، حداکثر ۳۰ مورد |
scopes |
frame_id |
حوزههای یک فریم، هرکدام با یک reference |
variables |
reference |
فرزندان، حداکثر ۵۰ مورد، مقادیر حداکثر ۴۰۰ نویسه |
evaluate |
expression, frame_id? |
در حوزهٔ خودِ فریم ارزیابی میشود |
output |
— | stdout/stderr برنامهٔ در حال اشکالزدایی، کراندار |
terminate |
— | نشست را پایان میدهد و آداپتور را میکشد |
آداپتورها
بخش با عنوان “آداپتورها”| شناسه | فرمان | نشانگرهای ریشه |
|---|---|---|
dart |
dart debug_adapter |
pubspec.yaml |
debugpy |
python3 -m debugpy.adapter |
pyproject.toml, setup.py, requirements.txt |
lldb |
lldb-dap |
Cargo.toml, CMakeLists.txt |
delve |
dlv dap |
go.mod |
debugpy یک .venv/bin یا venv/bin محلیِ پروژه را به $PATH ترجیح میدهد: یک python از $PATH محیطی متفاوت است، و اتصال از محیط اشتباه به شکلی شکست میخورد که مانند کد خراب خوانده میشود.
eval — مفسرهای پایدار
بخش با عنوان “eval — مفسرهای پایدار”سلولی پایتون یا جاوااسکریپت که متغیرها، واردات و دادههای بارگذاریشدهاش میان فراخوانیها باقی میمانند. ردهٔ exec؛ موازیایمن نیست.
| آرگومان | معنا |
|---|---|
code |
سلول |
description |
اجباری. ۵ تا ۱۰ واژه برای برچسب رونوشت |
language |
python (پیشفرض) یا javascript |
reset |
مفسر را دور میریزد و ابتدا یکی تمیز آغاز میکند |
- آخرین عبارت همانطور که یک نوتبوک بازتاب میدهد، چاپ میشود.
-
display()کار میکند، یک دیتافریم pandas بهصورت جدول رندر میشود، و یک شکل matplotlib بهصورت تصویری که رونوشت نشان میدهد برمیگردد. - اصطلاحات IPython که افراد بهطور بازتابی تایپ میکنند —
%pip،%cd،!cmd،%%bash،%%timeit— به کد ساده بازنویسی میشوند.%pipهمچنینsys.modulesرا بیرون میاندازد، پسimportبعدی چیزی را میبیند که همین حالا نصب شده است.
صدا زدن ابزارهای خودتان از داخل یک سلول
بخش با عنوان “صدا زدن ابزارهای خودتان از داخل یک سلول”contents = tool("read", {"path": "lib/auth.dart"})این پل دوباره به رجیستری ابزار هارنس وارد میشود، بنابراین گاردریلها، تأیید و هر پوششدهنده دقیقاً همانطور اعمال میشوند که برای یک فراخوانی صادرشده از مدل. روی همان لولهٔ خودِ کرنل سوار است، نه یک سوکت حلقهبازگشتی: نه پورت، نه رمز، نه قاعدهٔ خروج.
مهلت سلول یک بودجهٔ عدم فعالیت است (پیشفرض ۵ دقیقه) و تا وقتی یک فراخوانی پلشده در جریان است معلق میشود، پس سلولی که کار را به زیرعاملها پخش میکند، در میانهٔ پخش کشته نمیشود.
ask_user — پرسیدن یک پرسش از انسان
بخش با عنوان “ask_user — پرسیدن یک پرسش از انسان”ردهٔ read. تنها راهی که یک اجرا چیزی از اپراتور میپرسد. یک کارت شمارهدار در گفتگو رندر میکند و تا وقتی کسی پاسخ دهد، رد کند، یا پرسش مهلتش تمام شود مسدود میماند. هرگز پرسش را بهصورت یک پیام گفتگو ننویسید — این کار نوبت را پایان میدهد.
| آرگومان | معنا |
|---|---|
question |
آنچه باید پرسید |
context |
اختیاری: چرا میپرسید و چه چیزی به پاسخ بند است |
options[] |
گزینهها، هرکدام {label, description?} |
allow_free_text |
آیا پاسخ تایپشده پذیرفته میشود |
multi_select |
آیا میتوان چند گزینه را برگزید |
رد کردن یک موفقیت است: بر پایهٔ یک فرض بیانشده پیش بروید و دوباره نپرسید. مهلت تمامشده یک خطاست با همان دستور. پرامپتهای اجازه («آیا این کار را بکنم؟») دروازهای جداگانهاند و بهصورت همان کارت در گفتگو رندر میشوند.
فقط وقتی هم یک پورت پرسش و هم یک فضای هدف وجود داشته باشد ثبت میشود. بدون یک انسان متصل، فراخوانی شکست میخورد، نه اینکه تا ابد مسدود بماند — همان موضع «در خطا، بستن» که یک prompt گاردریل در نبود یک تأییدکنندهٔ وصل اتخاذ میکند.
vibe_* — هدایت کارگران پسزمینه
بخش با عنوان “vibe_* — هدایت کارگران پسزمینه”فقط تا وقتی حالت vibe روشن است ثبت میشوند. هر پنج در ردهٔ read هستند: دروازه باید روی ابزارهای کارگر باشد، همانجا که ویرایش واقعاً رخ میدهد.
| ابزار | آرگومانها | یادداشتها |
|---|---|---|
vibe_spawn |
brief, label, tier? |
بیدرنگ برمیگردد؛ کارگر به کارش ادامه میدهد |
vibe_send |
worker_id, message |
به بریف میافزاید و دوباره اجرا میکند |
vibe_wait |
worker_id, timeout_seconds? |
تا پایان یافتن آن مسدود میماند |
vibe_kill |
worker_id |
متوقفش میکند |
vibe_list |
— | رده، وضعیت، زمان سپریشده و آخرین نتیجه |
tier یکی از fast (کار مکانیکی با مشخصات روشن) یا good (طراحی، قضاوت، یا بازبینی خروجی یک کارگر fast) است.