اگر تا به حال یک تنظیمات کارآمد Beancount را به یک همکار، یک لپتاپ جدید یا یک کار cron شبانه تحویل دادهاید، میدانید که حسابداری هرگز بخش سخت نبود. بخش سخت، زنجیره ابزار بود: یک پایتون سازگار، bean-check و bean-query در مسیر، یک کتابخانه گزارشگیری که فقط برای یک ترازنامه نصب شده بود، و یک فرمتکننده که به محض پرسیدن سؤال، فایلهای شما را بازنویسی میکرد. bea 0.2.0 که در ۱۲ سپتامبر ۲۰۲۶ منتشر شد، این چکلیست را با یک نصب جایگزین میکند. دستور bea اکنون کل زنجیره ابزار بومی Beancount را حمل میکند، آن را در یک موتور مدیریتشده که خودش فراهم میکند اجرا میکند، و قرارداد قابلخواندن توسط ماشین را که اسکریپتها و عوامل هوش مصنوعی به آن وابستهاند، حفظ میکند.
این یادداشت انتشار برای نسخه 0.2.0 است که به همان شکلی نوشته شده که ما یک انتشار را در داخل پیگیری میکنیم: چه چیزی ارائه شد، چه چیزی در زیرساخت تغییر کرد، چگونه قبل از رسیدن به ایندکس بستهها تأیید شد، عمداً چه کاری انجام نمیدهد، و چگونه ارتقا دهید. اگر به دنبال داستان اولین اجرا هستید، پست راهاندازی 0.1.0 و شروع سریع CLI خواندنیهای کوتاهتری هستند.
انتشار در یک نگاه
دو کانال همان دستور را منتشر میکنند. یکی را انتخاب کنید، سپس تأیید کنید که با نسخه خود پاسخ میدهد:
$ brew install bex-co/tap/bea # macOS و Linuxbrew
$ uv tool install beancount-io # هر جا با uv و پایتون 3.12 یا جدیدتر
$ bea --version
bea 0.2.0cli-v0.2.02026-09-12beancount 3.2.3 beanquery 0.2.0beangulp 0.2.0 beanprice 2.1.03.12 3.14کارت انتشار 0.2.0: تگ و تاریخ انتشار، نسخههای Beancount و Beanquery که موتور مدیریتشده به آنها متصل است، دو ویژگی اختیاری موتور، و نسخههای پایتونی که انتشار روی آنها نصب و آزمایش شده است.
| فیلد | مقدار |
|---|---|
| نسخه | 0.2.0، تگ cli-v0.2.0، منتشر شده در PyPI و مخزن Homebrew bex-co/homebrew-tap در ۲۰۲۶-۰۹-۱۲ |
| انتشار قبلی | 0.1.0، تگشده در ۲۰۲۶-۰۹-۰۹، سه روز زودتر |
| مجموعه تغییرات | ۲۷ کامیت در CLI، ۱۱۹ فایل تغییر کرده، تقریباً ۱۲٬۳۰۰ خط اضافه و ۲٬۱۰۰ خط حذف |
| اتصالهای موتور | Beancount 3.2.3 و Beanquery 0.2.0 در موتور پایه؛ Beangulp 0.2.0 و Beanprice 2.1.0 بهعنوان ویژگیهای اختیاری |
| عنوان اصلی | هر ابزار بومی Beancount زیر یک پیشوند، سرویسدهی توسط یک موتور مدیریتشده؛ پوسته JSON و قرارداد کدهای خروجی از 0.1.0 بدون تغییر است |
چه چیزی در زیرساخت تغییر کرد: موتور مدیریتشده
در 0.1.0، bea Beancount را در فرآیند خودش وارد میکرد، همانطور که هر ابزار پایتونی انجام میدهد. این کار میکرد، اما نمودار وابستگی CLI را به نمودار وابستگی Beancount تبدیل میکرد و «ابتدا Beancount را نصب کنید» را به یک مرحله نانوشته در هر راهنما تبدیل میکرد.
0.2.0 یک خط از وسط برنامه میکشد. رابط کاربری bea، بخشی که مالک دستورات، گزینهها و رندر است، هرگز Beancount، Beanquery یا کد گزارشگیری Fava را بارگذاری نمیکند. کارهای دفتر محلی در یک موتور مدیریتشده اجرا میشوند: یک محیط پایتون جداگانه که bea از یک قفل با هش پینشده فراهم میکند و بهعنوان یک مفسر کودک راهاندازی میکند. رابط کاربری یک درخواست JSON را در آن مرز ارسال میکند و آنچه برمیگردد را رندر میکند. شما Beancount را نصب نمیکنید، ابزارهای bean-* را در مسیر خود قرار نمیدهید، یا به این فکر نمیکنید که آنها کدام پایتون را پیدا کردهاند.
نحوه رسیدن موتور به کانال بستگی دارد:
- Homebrew محیطهای رابط کاربری و موتور را در طول نصب ایجاد میکند. دستورات محلی از موتور محلی keg با هیچ دانلود اضافی استفاده میکنند.
- PyPI (
uv tool installیا pipx) در اولین استفاده فراهم میکند. اولین دستور محلی که به موتور نیاز دارد، ترکیب پینشده را دانلود میکند، که به دسترسی شبکه وuvدر مسیر یک بار نیاز دارد. دستورات بعدی آن را بهصورت آفلاین از~/.local/share/bea/engine/<version>یا زیرXDG_DATA_HOMEاگر آن را تنظیم کردهاید، دوباره استفاده میکنند.
سه ویژگی از آن طراحی به دست میآید و هر کدام یک تیکت پشتیبانی را که قبلاً دیدهایم حذف میکند:
- ارتقاها جفت میمانند.
bea upgradeبهروزرسانی را به هر مدیر بستهای که این نسخه را نصب کرده است میسپارد، سپس موتور متناظر را بازسازی میکند، بنابراین رابط کاربری و موتور هرگز نمیتوانند به نسخههای متفاوت منحرف شوند. - یک موتور خراب خودش را ترمیم میکند. اگر فراهمسازی در نیمهراه شکست بخورد، محیط مدیریتشده دور ریخته میشود و در تلاش موفق بعدی بازسازی میشود. باینریهای سرگردان
bean-checkدر جای دیگر مسیر نادیده گرفته میشوند نه اینکه تصادفاً انتخاب شوند. - قطعات سنگین اختیاری اختیاری میمانند. چارچوب واردات Beangulp به کتابخانه سیستمی
libmagicنیاز دارد و Beanprice وابستگیهای دریافت نقلقول را جذب میکند. هیچکدام در موتور پایه نیستند. شما آنها را صریحاً و فقط در موتور فعال میکنید.
$ bea engine status
$ bea engine enable beangulp # کمکهای ورود داده؛ به کتابخانه سیستمی libmagic نیاز دارد
$ bea engine enable beanprice # دریافت نقلقول bean-pricebea engine status گزارش میدهد که آیا موتور فراهم شده است و کدام ویژگیهای اختیاری فعال هستند و برای گفتن این کار به شبکه نیاز ندارد. اگر فراهمسازی اولین استفاده شکست خورد، شبکه یا uv را تعمیر کنید و هر دستور محلی مانند bea check را دوباره اجرا کنید. در کنار آن pip install beancount انجام ندهید: رابط کاربری از آن استفاده نخواهد کرد.
هر ابزار بومی، یک پیشوند
موتور مکانیزم است. تغییر کاربرپسند برابری است: هر اجرایی که پروژه بالادستی Beancount ارائه میدهد اکنون یک همتای bea دارد، با همان آرگومانها که ارسال میشوند و همان خروجی که حفظ میشود.
$ bea check # bean-check، بهعلاوه پوسته --json در bea
$ bea format main.bean -o clean.bean # bean-format: خروجی پیشفرض stdout، -i بازنویسی میکند
$ bea query "SELECT account, sum(position) GROUP BY account"
$ bea doctor context main.bean 2026-01-02 # هر یازده عملیات bean-doctor
$ bea example --seed 1 -o example.beancount # bean-example
$ bea treeify < balances.txt # treeify
$ bea ingest identify --config ingest.py inbox # Beangulp، پس از فعالسازی موتور
$ bea price -e USD:yahoo/AAPL # bean-price، پس از فعالسازی موتورbean-checkbea checkbean-formatbea formatbean-querybea querybean-doctorbea doctorbean-examplebea exampletreeifybea treeifybeangulpbea ingest bea engine enable beangulpbean-pricebea price bea engine enable beanpriceنقشه برابری: شش اجرایی بومی Beancount بالای خط چین از ابتدا کار میکنند؛ دو مورد زیر آن به Beangulp و Beanprice ارسال میشوند پس از اینکه آن ویژگی را در موتور فعال کنید.
چند مورد از اینها بیش از یک ردیف در جدول سزاوارند.
bea check همان bean-check است با پوسته JSON در bea که روی آن لایهبندی شده: همان اعتبارسنجی، همان پیامهای خطا، و زیر --json همان فیلدهای valid و errors که اسکریپتها قبلاً تجزیه میکنند.
رفتار bea format تغییر کرد و این تنها تغییری در این انتشار است که میتواند یک اسکریپت را غافلگیر کند. در 0.1.0، bea format PATH فایل را بازنویسی میکرد. اکنون متن فرمتشده را در stdout چاپ میکند و فایل را دستنخورده میگذارد. --in-place (-i) چیزی است که بازنویسی میکند، --output FILE (-o) در جای دیگری مینویسد، --check دروازه CI است که وقتی فایلها نیاز به فرمت دارند با کد ۱ خارج میشود، و --dry-run فهرست میکند چه چیزی تغییر میکند. این از bean-format پیروی میکند که پیشفرض آن امن است: دستوری که مسیر را میخواند و بیصدا آن را بازنویسی میکند نمیتواند ابتدا امتحان شود. فرمتبندی یک تبدیل متن است، نه یک تجزیه، بنابراین دیگر فایلی با خطای نحو را رد نمیکند؛ آنچه را تشخیص میدهد همتراز میکند و بقیه را رها میکند. برای اعتبارسنجی bea check را اجرا کنید.
bea query کل سطح بومی را رشد داد. BQL را بهعنوان آرگومان، از stdin، یا در شل تعاملی میگیرد، که اکنون شل بالادستی Beanquery است که بهعنوان یک فرآیند کودک با دستورات .format، .output، .run و .set دستنخورده راهاندازی میشود. --format رندر text، csv یا beancount را انتخاب میکند، --numberify مبالغ را به یک ستون برای هر ارز تقسیم میکند، -o در یک فایل مینویسد، و --source URI یک منبع بومی Beanquery را مستقیماً ارسال میکند.
bea doctor هر یازده عملیات bean-doctor را در معرض دید قرار میدهد: lex، parse، roundtrip، directories، list-options، print-options، context، linked، region، missing-open و display-context. اگر تا به حال یک مشکل ثبت را با bean-doctor context اشکالزدایی کردهاید، همان ابزار در همان آدرس است.
bea example و bea treeify تولیدکننده بومی و رندر درخت بومی هستند که همانطور که هستند ارسال میشوند.
bea ingest و bea price به ترتیب به identify، extract و archive در Beangulp و به bean-price ارسال میشوند، پس از bea engine enable. مسیر CSV بدون پایتون، bea import --csv، به هیچکدام نیاز ندارد و بدون تغییر است.
یک قانون دستورات ارسالشده را به هم متصل میکند: doctor، example، treeify، price و ingest آرگومانهای خود را بدون تغییر به بالادست میدهند و خروجی و وضعیت خروج بالادست را حفظ میکنند. این همچنین به این معنی است که آنها دفتر را بهعنوان آرگومان موقعیتی خود میگیرند، مانند bea doctor lex main.bean، نه از طریق --file سراسری. پوسته و دستههای کد خروجی زیر دستورات خود bea را توصیف میکنند.
قراردادی که اسکریپتها میتوانند به آن اعتماد کنند
هیچچیز درباره سطح قابلخواندن توسط ماشین حرکت نکرد. --json سراسری هنوز یک پوسته در stdout با bea، target، data و truncated قرار میدهد، بهعلاوه limit در فهرستهای محدود و page در فهرستهای میزبانیشده صفحهبندیشده. مبالغ رشتههای اعشاری هستند، هرگز شناور نیستند، و تاریخها ISO YYYY-MM-DD هستند. --json به معنای --no-input است؛ همینطور یک stdin غیرترمینال یا یک متغیر CI درست، بنابراین یک کار بدون نظارت هرگز منتظر انسان نمیماند. --strict حتی در یک ترمینال پاسخهای جزئی را رد میکند و --allow-errors هر دستور خواندن دوباره انتخاب میکند.
یک شکست هیچچیز در stdout نمینویسد و دقیقاً یک شیء در stderr:
{
"error": {
"category": "validation",
"message": "Ledger has 3 error(s). Pass --allow-errors to report anyway.",
"exit_code": 1,
"details": ["main.bean:1: Transaction does not balance: (2.50 USD)"]
}
}پنج کد خروجی و رشته category که هر کدام در شیء خطای JSON حمل میکند. یک اسکریپت بر اساس عدد شاخه میزند؛ یک انسان دسته را میخواند.
| کد | دسته | معنی |
|---|---|---|
| 0 | هیچ | موفقیت، شامل پیشنمایشها و رد شدن عمدی موارد تکراری |
| 1 | validation | خطای دفتر یا اعتبارسنجی، و دسته فراگیر برای هر شکست دیگر در زمان اجرا |
| 2 | usage | آرگومانهای بد، هدف یا اضافی از دست رفته، یا ورودی لازم زیر --no-input |
| 3 | auth | شکست احراز هویت یا مجوز، شامل مقصد فقطخواندنی |
| 4 | conflict | تغییر همزمان، وارداتی که نیاز به بررسی تکراری دارد، یا نوشتنی که نتیجه آن ناشناخته است |
دو جزئیات برای هر کسی که در شکست دوباره تلاش میکند مهم است. خروج غیرصفر به معنای جهانی این نیست که هیچچیز تغییر نکرده است: add transactions --partial میتواند ردیفهای پذیرفتهشده را بنویسد، format -i روی چند فایل میتواند برخی را قبل از شکست در یکی بازنویسی کند، و cloud ledger create --clone میتواند دفتر را قبل از شکست کلون ایجاد کند. قبل از تلاش دوباره برای یک تغییر، error.result را بخوانید. و دستورات میزبانیشده وضعیت HTTP سرور را روی همان جدول نگاشت میکنند و پیام خود سرور را حفظ میکنند: 401 و 403 با کد ۳ خارج میشوند، 400 با کد ۲، 409 با کد ۴، و هر چیز دیگر، شامل محدودیت نرخ، با کد ۱. یک نوشتن که نتیجه آن را CLI نمیتواند بداند، مانند وقفه زمانی در وسط حذف، با کد ۴ خارج میشود و آن را میگوید بهجای حدس زدن.
راهنمای اتوماسیون یک خط لوله jq را از طریق این پوسته از ابتدا تا انتها طی میکند.
اصلاحاتی که همراه آمدند
یک انتشار برابری همچنین فرصتی است برای بستن نقصهایی که یک انتشار اول نشان میدهد. اینها بین دو تگ انجام شدند، هر کدام با یک آزمایش رگرسیون:
- اعداد بهعنوان متن با نقطه ثابت نوشته میشوند، هرگز نماد علمی، شامل موجودیهای افتتاحیه که
bea initرندر میکند. دفتری که1E+3میگوید از نظر فنی معتبر و عملاً غیرقابلخواندن است. - لاتهای هزینه از سریالسازی JSON جان سالم به در میبرند با تاریخها و برچسبهایشان دستنخورده، و برچسبهای لات وقتی یک تراکنش نوشته میشود بهدرستی فرار میکنند.
- پستینگهای صفر صریح در طول واردات مبالغ واقعی هستند، بهجای اینکه بهعنوان «حذفشده، لطفاً من را متوازن کن» خوانده شوند.
- واردات CSV از یک خواننده سختگیر میگذرد. کشف هدر قبلاً نام ستونها را حذف میکرد در حالی که استخراج کلیدهای خام را حفظ میکرد، بنابراین یک هدر با فاصله که مستندات قول پذیرش آن را داده بود بهعنوان یک ستون از دست رفته شکست میخورد. اکنون نامها یک بار حذف میشوند، یک ستون نگاشتشده باید دقیقاً یک بار ظاهر شود، و یک نقلقول بستهنشده با شماره خط خود قبل از نوشتن هر چیزی شکست میخورد.
- BQL مسیر دقیق دفتر را بارگذاری میکند بهجای یک رشته اتصال تجزیهشده URL، بنابراین مسیرهای غیرمعمول به همان شکلی که بقیه CLI آنها را حل میکند حل میشوند.
bea balance <term>فقط آنچه را نشان میدهد جمع میزند. یک والد نگهداشتهشده دیگر مجموع خواهر و برادرهای حذفشده را گزارش نمیکند، یک دارایی بدون قیمت نامرتبط دیگر یک انتخاب USD را شکست نمیدهد، و پوسته فیلتر اعمالشده را گزارش میکند. یک الگوی--accountبدفرم در گزارشها با کد ۲ خارج میشود بهعنوان خطای استفاده که هست.- stderr در حالت JSON همیشه یک شیء است، حتی وقتی هشدارهای تحملشده قبل از شکست باشند.
- اعتبارنامههای میزبانیشده زود و پیوسته شکست میخورند: یک
BEA_TOKENحاوی فضای خالی قبل از هر درخواست رد میشود، یک اعتبارنامه لغوشده به همان روش توسطcloud statusو دستورات دفتر گزارش میشود، وowner/nameقبل از یک اعلان تأیید یا یک تماس احراز هویتشده اعتبارسنجی میشود.cloud logoutBEA_TOKENرا دستنخورده میگذارد، وcloud ledger list --jsonصفحهای را که واقعاً سرویس داده است بازتاب میکند. - فرمول Homebrew دقیقاً URL مصنوع PyPI را پین میکند، بنابراین یک نصب tap و یک نصب PyPI بهطور قابل اثبات همان بایتها هستند.
چگونه قبل از دیدن شما تأیید شد
یک انتشار یک ادعاست و خط لوله شواهد است. یک تگ cli-v0.2.0 باید یک کامیت در main را نام ببرد که نسخه pyproject.toml آن دقیقاً مطابقت دارد؛ گردش کار هر چیز دیگری، شامل پسوندهای پیشانتشار را رد میکند. از آنجا:
- مجموعه کامل بررسیها ابتدا اجرا میشود.
make check-allشامل لینت، قالببندی، mypy سختگیرانه، تشخیص کد مرده، بررسی انحراف مرجع تولیدشده و مجموعه آزمایش است. درخواست ادغام انتشار ۶۳۵ آزمایش موفق را ثبت میکند. - قفل موتور صادر و با هش پین میشود، و توزیع منبع و چرخ یک بار ساخته میشوند. هر مرحله بعدی دقیقاً آن مصنوعات را آزمایش میکند، نه یک بازسازی.
- نصبهای تمیز روی سه سیستم عامل و دو پایتون. چرخ از طریق
uv toolو sdist از طریقpipدر لینوکس، macOS و ویندوز، روی پایتون 3.12 و 3.14، شامل ویژگی اضافی اختیاری AI نصب میشود. یک کار Homebrew sdist را از طریق یک tap موقت در macOS و لینوکس نصب میکند. - انتشار ترتیبی و بدون توکن است. PyPI مصنوعات را از طریق انتشار مورد اعتماد دریافت میکند، بنابراین هیچ توکن API طولانیمدتی برای نشت وجود ندارد؛ انتشار GitHub با گواهیهای انتشار پیوست ایجاد میشود؛ و
Formula/bea.rbبا URL و هش sdist که PyPI واقعاً سرویس داده است به tap عمومی ارسال میشود. - آزمایشهای دود پس از انتشار از ایندکسهای واقعی نصب میکنند. کارهای جداگانه نسخه پینشده را از PyPI و از tap عمومی نصب میکنند و همان آزمایشهای دود مشتری را در برابر اجرایی نصبشده اجرا میکنند. شکست در آنجا هیچچیز را برنمیگرداند، اما به این معنی است که انتشار قبل از اینکه به کسی گفته شود نیاز به توجه دارد.
این پست در آن سوی مرحله پنج نوشته میشود.
ارتقا از 0.1.0
ارتقا را از طریق مدیری که نسخه شما را نصب کرده اجرا کنید، یا بگذارید bea آن را انجام دهد:
$ bea upgrade --check # نسخههای نصبشده و آخرین و دستوری که اجرا میشود را گزارش میکند
$ bea upgrade # brew upgrade bea، uv tool upgrade beancount-io، یا pipx upgrade beancount-ioپس از اتمام مدیر، bea upgrade موتور مدیریتشده را تازه میکند تا این دو جفت بمانند. سپس سه چیز را بررسی کنید:
- هر اسکریپتی که
bea format PATHرا برای بازنویسی یک فایل اجرا میکرد اکنون بهbea format -i PATHنیاز دارد. پیشفرض قدیمی قابل پیشنمایش نبود و جدید قابل پیشنمایش است. - هر اسکریپتی که برای گرفتن خطای نحو به
formatتکیه میکرد باید برای آنbea checkرا صدا بزند، زیرا قالببندی دیگر تجزیه نمیکند. - نصبهای PyPI یک بار به شبکه و
uvنیاز دارند برای اولین دستور محلی پس از ارتقا، تا موتور فراهم شود. نصبهای Homebrew به هیچچیز نیاز ندارند.
هر چیزی که اسکریپتهای شما قبلاً تجزیه میکنند، کلیدهای پوسته، رشتههای اعشاری و کدهای خروجی، بدون تغییر است. فیلد bea در پوسته اکنون 0.2.0 را میخواند.
آنچه این انتشار انجام نمیدهد
- هدفگیری میزبانیشده پیادهسازی نشده است. هیچ پرچم
--ledgerوجود ندارد؛ دستورات محلی فایلهای محلی را میخوانند و هرگز بهطور ضمنی یکی را آپلود نمیکنند. دفترهای میزبانیشده زیرbea cloudمدیریت میشوند و بهعنوان کلونهای git کار میشوند. bea askهنوز به افزونهaskو اعتبارنامههای Beancount.io نیاز دارد و از--jsonپشتیبانی نمیکند. نصب پیشفرض هیچ وابستگی AI حمل نمیکند.- Beangulp و Beanprice اختیاری هستند و Beangulp به کتابخانه سیستمی
libmagicنیاز دارد.bea import --csvصادرات بانک را بدون هیچکدام پوشش میدهد. - دستورات بومی ارسالشده پوسته را منتشر نمیکنند. اگر به خروجی ساختیافته از یک عملیات doctor نیاز دارید، این درخواستی است که دوست داریم بشنویم.
از زمان تگ، main قبلاً اولین دور QA را روی 0.2.0 برداشته است و آن سوار انتشار بعدی خواهد شد: bea format stdin را بهعنوان یک فیلتر میخواند و حالت -o FILE آن با یک پوسته پاسخ میدهد که آنچه نوشته را نام میبرد؛ --json check پرچمهای فقط bean-check را رد میکند، و --json بهطور کامل روی doctor، example و treeify رد میشود تا یک اسکریپت نتواند متن بومی را با یک پوسته اشتباه بگیرد؛ --json query -o FILE پوسته را بهصورت اتمی در فایل مینویسد، با --numberify که روی JSON نیز اعمال میشود؛ bea engine status نام میبرد کدام لایه موتور در حال سرویس است؛ یک پرسوجوی BQL که با یک نظر باز میشود اجرا میشود؛ --help عبوری بومی قبل از فراهمشدن موتور کار میکند؛ و .output شل پرسوجو جریان اصلی را پس از یک تغییر مسیر ناموفق بازیابی میکند.
کجا برویم بعد
- شروع سریع CLI: نصب، اولین دفتر، اولین خرید، اولین بررسی موجودی.
- ماه اول شما با bea: از
initتا یک گزارش پایان ماه تطبیقشده. - واردات صادرات بانک: مسیر CSV بدون پایتون، فایلهای قوانین و واردکنندههای پایتون.
- اتوماسیون دفترداری با bea: حل دفتر، خواندن پوسته، شاخهزنی روی کدهای خروجی، زمانبندی.
- مرجع CLI Beancount: هر دستور، گزینه، متغیر محیطی و کد خروجی، بررسیشده در برابر مرجع تولیدشده CLI.
- به عامل AI خود یک دفتر بدهید: راهنمای عامل-اول از راهاندازی 0.1.0.
- تغییرات: هر انتشار، جدیدترین اول.
کتابهای خود را بهعنوان کد نگه دارید
یک زنجیره ابزار که میتوانید در یک خط نصب کنید، زنجیرهای است که میتوانید به هر کسی بدهید: یک همبنیانگذار، یک دفتردار، یک اجراکننده CI، یک عامل AI. Beancount.io حسابداری متنساده را فراهم میکند که شفاف، کنترلنسخه و قابلتولید مجدد میماند، با bea بهعنوان دستوری که یک دفتر محلی را صادق نگه میدارد و سرویس میزبانیشده بهعنوان جایی که تیم، تلفن و دستیار شما همان کتابها را ملاقات میکنند. bea را نصب کنید و اولین بررسی خود را اجرا کنید، و اگر انتشار کاری انجام داد که انتظارش را نداشتید، مخزن GitHub جایی است که میخواهیم آن را بشنویم.


