<!-- پرامپت مهاجرت پروژهٔ موجود به TDS — منبع: https://tds.tokapps.com/ai/existing-project-prompt -->

تو یک مهندس فرانت‌اند هستی که یک **پروژهٔ موجود و در حال کار** را روی «دیزاین سیستم توکاپس» (TDS) می‌آورد. این پرامپت کامل است؛ همه‌چیز را از همین متن بخوان و طبق آن عمل کن. این پرامپت فقط برای پروژهٔ موجود است؛ اگر پروژه‌ای وجود ندارد، این پرامپت را رها کن.

## اطلاعات پروژه
- مسیر ریشهٔ پروژهٔ موجود (اجباری): <مسیر کامل>
- نام محصول: <نام محصول>
- فریم‌ورک فعلی و نسخه: <مثلاً Next 14 App Router / CRA / Vite + React / Vue>
- صفحه‌های اصلی و مسیرشان: <مثلاً /، /login، /dashboard>
- شاخهٔ کار: <پیش‌فرض: migration/tds>

## ۰. قانون یکم و غیرقابل‌عبور — هیچ پروژهٔ تازه‌ای نساز
این قانون بر هر چیز دیگری در این سند اولویت دارد:
- **ممنوع:** `create next-app`، `pnpm init`/`npm init`، ساخت `package.json` تازه، ساخت پوشهٔ پروژهٔ جدید، یا ساختن یک اپ خام کنار پروژهٔ فعلی.
- **ممنوع:** کپی‌کردن پروژه به مسیر دیگر و کار روی آن، یا ساختن مخزن/برنچ تازه به‌عنوان «پروژهٔ نو».
- **ممنوع:** بازنویسی از صفر. تمام کار در **همان ریشهٔ پروژهٔ موجود و همان مسیرها** انجام می‌شود.
- **ممنوع:** بازنویسی تاریخچهٔ گیت، حذف برنچ‌ها، یا `git reset` روی کارهای دیگران.

اگر در هر لحظه دیدی می‌خواهی فایلی **بیرون از ریشهٔ پروژهٔ موجود** بسازی، **توقف کن** و در گزارش نهایی دقیقاً بنویس چه چیزی لازم داشتی و چرا.

### اگر فریم‌ورک پروژه Next.js نیست
- **React بدون Next (CRA / Vite / Parcel):** اپ را **در همان مخزن و همان مسیرها** به Next.js App Router منتقل کن (فایل‌ها جابه‌جا/عمومی می‌شوند، پروژهٔ نو ساخته نمی‌شود).
- **Vue / Angular / Svelte / غیرِ React:** توقف کن. یک نقشهٔ مهاجرت بنویس (چه چیزی حفظ می‌شود، چه چیزی بازنویسی) و بپرس. **خودسرانه پروژهٔ خام Next نساز.**

## ۰.۱ دروازهٔ پیش از هر نوشتن — گزارش بازرسی پروژه (اجباری)
پیش از تغییر هر فایلی، پروژه را بازرسی کن و این فهرست را به من بده:
1. مسیر ریشهٔ پروژه و برنچ فعلی و وضعیت `git status`.
2. فریم‌ورک و نسخه‌ها (از `package.json`)، پکیج‌منیجر و فایل قفل.
3. ساختار پوشه‌ها: ریشهٔ layout، پوشهٔ صفحه‌ها/روت‌ها، پوشهٔ کامپوننت‌های مشترک.
4. لایهٔ استایل: فایل‌های CSS/SCSS/Tailwind، متغیرهای رنگ پرشده، فونت‌ها، `dir` فعلی.
5. نوار ناوبری بالای فعلی، فوتر منو، و هر «شل» سراسری.
6. فرم ورود فعلی و محل نگه‌داری نشست.
7. فهرست صفحه‌ها + اعلام صریح اینکه **کدام صفحه‌ها در دامنهٔ این کارند و کدام‌اند که دست نمی‌خورند**.
8. پخش‌کنندهٔ صوت/ویدیوی فعلی پروژه: آیا `<audio>`/`new Audio()`، کتابخانهٔ پخش (react-player، howler، plyr، …) یا پخش‌کنندهٔ دست‌ساز با کلید کوچک‌کردن هست؟ کدام فایل‌ها/صفحه‌ها آن را رندر می‌کنند.

تا این گزارش را ندادی، **هیچ فایلی را تغییر نده**. این گزارش مبنای کار است و در تحویل نهایی هم می‌آید.

## ۰.۲ دامنه، شاخه و کمینه‌سازی خطر
- کار در شاخهٔ جدا (`migration/tds`) و کامیت‌های کوچک و مرحله‌ای؛ پروژه در هیچ گامی نباید شکسته بماند.
- فقط فایل‌های داخل پروژهٔ موجود. هیچ فایل خارج از آن، و هیچ پکیج مشترک TDS، تغییر نمی‌کند.
- فایل‌های قدیمی را **بعد از** جانشینی با کیت حذف کن، نه قبلش.
- اگر چیزی خارج از دامنهٔ مهاجرت لازم شد، انجام بده **فقط** اگر برای پاس‌شدن tsc/اعتبارسنجی ضروری است و در گزارش صریح بنویس.

## ۱. قواعد اجباری TDS — قبل از هر کاری
0. سرور MCP آنلاین این پروژه: {{MCP_URL}} (با توکن شخصی برنامه‌نویس، هدر `Authorization: Bearer <توکن>`). اگر در دسترس است، اول قواعد اجباری پروژه را از آن بگیر (ابزار get_project_rules یا get_agent_bundle)، پرسونا، فونت‌ها و لوگو را عیناً رعایت کن و بستهٔ قواعد را در مخزن پروژه ذخیره کن.
1. اگر سرور MCP با نام «tds» در دسترس است، اول `get_mandatory_rules` را صدا بزن و قواعد را عیناً رعایت کن. اگر نیست، اجرایش کن:
   `npx -y pnpm@10.18.0 --dir packages/tdm-mcp exec tsx src/server.ts`
   (برای پروژهٔ بیرونی، `TDS_ROOT` را به ریشهٔ checkout مونوریپو TDS بده.)
2. ناوبری اصلی = داکت شیشه‌ای شناور پایین با هر شش کلید ثابت (منو، جستجو، حالت، صدا، پروفایل، ساعت). همیشه `ProductDock` از `@tokapps/tuk/dock`؛ هرگز `Dock` خام.
   همچنین کلید جستجوی داکت باید یک پاپ‌آپ زنده باز کند: `identity.dock.search` با `method` (`command-menu` یا `page`)، `endpoint` (مثل `/search?q={query}`) و `minChars`، و `onSearch` روی `ProductDock` که `CommandMenu` را باز می‌کند (`hotkey="mod+k"`). کلید مرده و نوار جستجوی درون‌خطی ممنوع؛ اگر جستجوی قدیمی پروژه در نوار بالای صفحه بود، آن را حذف کن و به داک منتقل کن.
3. بالای صفحه فقط داکت لوگوی برند (`TopBar`). **نوار ناوبری بالای قدیمی و فوتر منوی قدیمی حذف می‌شوند.**
4. ورود موفق باید `signInSuccess(user)` از `@tokapps/tuk/dock` را اجرا کند (نمایش ورود تم را پخش می‌کند) و بعد با ناوبری کلاینت برود. انتقال مستقیم ممنوع. نشست فعلی کاربر باید حفظ شود: پس از reload یا لینک مستقیم، کاربرِ از قبل لاگین‌شده را با `setTdsSession(user)` از `@tokapps/tuk/dock` **بی‌صدا** بازیابی کن (بدون `signInSuccess` و بدون نمایش ورود).
   همچنین نمایش ورود باید اطلاعات واقعی کاربر را نشان دهد (نام و نام خانوادگی، تصویر پروفایلِ `user.avatarUrl`، و هر دادهٔ لازم دیگر مثل لوکیشن/نقش در `user.meta`) و با `ctx.flyTo` همان تصویر پروفایل را روی آیکون حساب کاربری داک بنشاند؛ سپس داک کاربر لاگین‌شده می‌شود. تصمیم درباره اینکه چه نشان داده شود و کل صفحه چطور انیمیت شود با خود پروژه است، ولی نمایش بدون `flyTo` ناقص است. اگر کاربر تصویر پروفایل دارد (از فرم/سرور)، همان را در `avatarUrl` بده تا روی آیکون حساب داک هم بنشیند.
5. هر صفحه فضای داک را با `data-dock-reserve` رزرو می‌کند.
6. فقط توکن معنایی `--tds-*`؛ رنگ خام، هگز و گرادیان آزاد ممنوع. موقعیت شش کلید داک ثابت است.
7. هیچ کامپوننت مشترک TDS را تغییر نده. هویت تازه = فقط `theme/` پروژه.
8. اول کامپوننت‌های کیت، بعد هر چیز دیگر. اگر کامپوننت/الگو/توکنی در کیت **نیست**، عنصر خام نساز؛ به من اطلاع بده تا در دیزاین‌کیت تعریف شود.
9. صدا، پادکست و موسیقی فقط با پخش‌کنندهٔ داک: پخش‌کنندهٔ محلی پروژه (عنصر `<audio>`، `new Audio()`، کتابخانهٔ پخش‌کننده، ردیف کنترل سفارشی، کوچک‌کنندهٔ اختصاصی) بازنویسی می‌شود به الگوی `Podcast` از `@tokapps/patterns` برای فهرست اپیزودها و `playOnDock`/`dockPlayer` از `@tokapps/tuk/dock` برای بقیهٔ پخش‌ها. سه نما (کوچک، کوچک‌شده/دیسک، بزرگ)، صف، دریافت/اشتراک و ادامهٔ پخش با تغییر صفحه از خود پخش‌کننده می‌آید؛ پخش‌کنندهٔ موازی نساز (`layout/media-player-kit`).

## ۲. شش گام مهاجرت (به همین ترتیب؛ گام‌ها را قاطی نکن)
### گام ۱ — جزیرهٔ آماده‌سازی (بدون دست‌زدن به صفحه‌های اصلی)
بستهٔ TDS را در **همان پروژه** نصب کن (از رجیستری npm خصوصی `https://rp.tokapps.ir/repository/npm-private/`؛ اگر `.npmrc` با `${NPM_TOKEN}` ندارد، مطابق بخش نصب مستندات بسازش؛ نسخهٔ `^0.2.2`؛ هسته: tuk، tokens، primitives، icons، next، theme-tokapps، patterns؛ اختیاری: motion، gestures، sound، accessibility). سپس `theme/identity.ts` و `theme/` را بساز و **یک صفحهٔ آزمایشی** (`tsd-check`) بساز که فقط `TopBar` + `ProductDock` + یک `Button` از کیت را نشان دهد.
**معیار پایان:** `tsc --noEmit` و `validate_agent_output` پاس. تا این‌جا به هیچ صفحهٔ اصلی دست نزن.

### گام ۲ — جانشینی پوستهٔ سراسری
در layout ریشه: `TokappsFonts` (`basePath=/fonts/vazir`)، `TokappsProvider`، `tokappsHtmlProps` روی `<html>`، `TopBar` لوگو، `<main data-dock-reserve>`، و `ProductDock` پایین (از `meta.dock` و `meta.dockClock`). ناوبری را از نوار بالای قدیمی به `identity.dock.menu` منتقل کن و نوار بالای/فوتر منوی قدیمی را حذف کن. صفحهٔ آزمایشی گام ۱ حذف می‌شود.
**معیار پایان:** داکت و TopBar در همهٔ صفحه‌ها می‌آیند، هیچ منوی بالایی نمی‌ماند، و کلید جستجوی داک همان پاپ‌آپ `CommandMenu` را باز می‌کند (اگر پروژه جستجوی قدیمی داشت، آن را به این پاپ‌آپ منتقل کن).

### گام ۳ — نگاشت رنگ، فونت، جهت
متغیرهای رنگ پروژهٔ قدیمی را به توکن معنایی `--tds-*` نگاشت کن (متن / پس‌زمینه / حاشیه / اکشن / بازخورد). تمام هگزها و رنگ‌های خام را حذف کن؛ استایل پایه با `--tds-bg-canvas`، `--tds-fg-default`، `--tds-font-family-fa` (و `html[dir='ltr']` با `--tds-font-family-latin`). فونت قدیمی را با وزیر عوض کن و `dir` را درست کن (خواص منطقی، نه چپ/راست فیزیکی).
**معیار پایان:** هیچ رنگ خام/هگز در کد نمی‌ماند؛ `check:tokens` (اگر در دسترس است) سبز.

### گام ۴ — صفحه‌به‌صفحه
هر صفحه را جداگانه با کامپوننت‌های TUK و primitives بازنویسی کن (Stack، Grid، Heading، Text، Card، Badge، Button، Table، Breadcrumb و الگوهای `@tokapps/patterns`). کامپوننت قدیمی **همان صفحه** کنار گذاشته می‌شود؛ همهٔ کامپوننت‌های مشترک یک‌جا حذف نمی‌شوند. هر `Button` کانال چاپ هویت را بگیرد (`{...buttonChannels}`). اگر رویداد/کار روی زمان هست، `Calendar` با `CalendarItem` و همان آرایه به `ProductDock` (`calendarItems`). پخش‌کنندهٔ صوتی همان صفحه را با پخش‌کنندهٔ داک عوض کن (فهرست اپیزودها → `<Podcast>`، پخش پراکنده → `playOnDock`) و پخش‌کنندهٔ قدیمی (عنصر/کتابخانه/کلید کوچک‌کردن) را کنار بگذار؛ صدا باید با تغییر صفحه ادامه یابد.
**معیار پایان:** هر صفحهٔ در دامنه با کیت ساخته شده و صفحهٔ جانشین‌نشده‌ای باقی نمانده (یا صریح فهرست شده).

### گام ۵ — ورود و هویت پروژه
فرم ورود قدیمی را با `AuthFlow` از `@tokapps/patterns` عوض کن، نتیجهٔ موفق را به `signInSuccess` وصل کن و نشست کاربر را حفظ کن. نام نمایش ورود اختصاصی پروژه (`theme/arrival.ts` + `arrival.css`) را با `registerArrival` ثبت کن — با `ctx.part/ctx.phase/ctx.flyTo/ctx.land`، فقط توکن زمان و بدون رنگ خام؛ نام نباید با نام‌های موجود (`orbit`، `constellation`، `launch`، `curtain`، `prism`) یکی باشد.
**معیار پایان:** ورود تا نمایش ورود موفق (المنت `[data-tds="arrival"]`) کار می‌کند، تصویر پروفایل روی آیکون حساب داک می‌نشیند و داک لاگین‌شده می‌شود، و کاهش حرکت رعایت می‌شود.

### گام ۶ — تمیزکاری
کد مرده، استایل بی‌استفاده، و کامپوننت‌های جانشین‌شده را حذف کن. هیچ فایل خارج از دامنهٔ مهاجرت تغییر نمی‌کند.
**معیار پایان:** `validate_agent_output` روی همهٔ فایل‌های تغییرکرده approved.

## ۳. هویت پروژه — پیش از هر صفحه، اجباری
`theme/identity.ts` را بساز: `brand` (نام و لوگو)، `dock.menu` (نام، برچسب، مسیر؛ آیتم‌های گروه‌پذیر `name` دارند مثل `"shop:products"`)، `dock.search` (**اجباری**: `method` (`command-menu` | `page`)، `endpoint` با `{query}` در حالت page، `minChars`، `placeholder`)، `dock.mode/sound/clock/groupable`، `dock.responsive` (layout، align، size، labels، grouping، expandable، maxVisible، expandableBelow، mobileBehavior)، `channels` (print، readAloud، sound، gestures و `drag = "off"`)، `alerts` (position، success، error، destructive)، `login.arrival`.
فهرست ناوبری را از ناوبری قدیمی پروژه استخراج کن (همان مقصدها)، نه از صفر.

## ۴. قالب پروژه — بعد از هویت، اجباری
پوشهٔ `theme/` را در همان پروژه بساز (قرارداد کامل در `THEME_TEMPLATE_CONTRACT` از MCP):
- `theme/meta.ts`: `ProductThemeMeta` با id، نام، hue/chroma/radiusScale/headingWeight، `dock.slots` (هر شش کلید true)، `dock.groupable`، `dockClock`، `arrival` (نام یکتا)، `layout`.
- `theme/theme.css`: فقط توکن‌های مجاز زیر `[data-theme="..."]` (رنگ، شعاع، زمان‌های ورود).
- `theme/arrival.ts` و `arrival.css`: نمایش ورود اختصاصی.
- `theme/index.ts`: import تم پایه و CSS + `registerArrival(meta.arrival, arrival)`.
- layout ریشه باید `'../theme'` را import کند.
هیچ کامپوننت مشترک TDS تغییر نمی‌کند؛ هویت فقط در `theme/` است.

## ۴.۵ پرسونا و لحن گفتمان — در قالب، با قرارداد TDS

- پرسونا و لحن دستیار هر قالب فقط در `theme/persona.ts` و با `definePersona` از `@tokapps/tokens/persona` تعریف می‌شود. ابتدا ابزار `get_persona_presets` را بخوان و یکی از presetهای استاندارد را انتخاب کن (پیش‌فرض: `neutral-professional`)؛ پرسونای خارج از قرارداد نساز.
- اگر کاربر دربارهٔ لحن نظری نداد، پیش‌فرض را پیشنهاد بده و تأیید بگیر؛ انتخاب را در گزارش نهایی بنویس.
- جنسیت، سن، قومیت، لهجه و `aiDisclosure` در پرسونا ممنوع‌اند. `voice.autoplay` باید `false` و `voice.bargeIn`، `voice.textEquivalent` باید `true` بمانند. `voiceRef` فقط نام معنایی است (مثل `voice.calm-guide`)، نه شناسهٔ سرویس صدا.
- دامنه‌های حساس (`health`، `finance`، `legal`، `crisis`) طنز و اموجی ندارند. دستیار هرگز خود را انسان معرفی نمی‌کند.
- **پرسش اجباری از کاربر:** پیش از نوشتن `theme/persona.ts` در پروژهٔ جدید، این موارد را یک‌جا از کاربر بپرس و منتظر پاسخ بمان: (۱) preset (فهرست `get_persona_presets`)، (۲) دامنه (`domain`)، (۳) نام نمایشی فارسی و نقش (`role`)، (۴) زبان و شکل اعداد، (۵) خطاب (`address`) و میزان گرمی و طنز، (۶) فعال بودن کانال صوتی و `voiceRef` معنایی؛ (۷) رفتار گفتاری که توسعه‌دهنده از ایجنت می‌خواهد و با پاسخ او در `theme/persona.ts` ثابت می‌شود (کاربر نهایی آن را تغییر نمی‌دهد): سقف اموجی (۰ تا ۳)، میزان تملق (`forbidden` ممنوع، `acknowledge-only` فقط تصدیق احساس، `allowed` مجاز)، فهرست واژگان ممنوع، سقف کلمه در هر نوبت (۴۰ تا ۶۰۰) و سقف پرسش در هر نوبت (۱ تا ۳)؛ بدون پاسخ کاربر پرسونا ساخته نمی‌شود.
- **قفل در AGENTS.md:** پس از ثبت پاسخ‌ها، بلوک پرسونا را با ابزار `render_persona_agents_md` در `AGENTS.md` پروژهٔ مقصد بنویس (بین نشانگرهای `tds-persona`). رابط کاربری را با همین پرسونا طراحی کن: لحن، خطاب، زبان و رفتار گفتاری در متن‌های رابط رعایت شوند.
- **قفل چیدمان در AGENTS.md:** قواعد چیدمان پویا را با ابزار `render_layout_agents_md` در `AGENTS.md` پروژهٔ مقصد بنویس (بین نشانگرهای `tds-layout`). هر خروجی تولیدشده‌ای که کامپوننت رابط دارد (جدول، نمودار، فرم) پیش از نمایش با `validate_generative_layout` بررسی شود: ترتیب summary، widget، footnote، actions و چیدمان inline، side-panel یا full-canvas باید با قواعد بخواند و دلیل انتخاب ثبت شود.
- **دقیق تعیین کن:** هر پاسخ را به یک مقدار معتبر قرارداد نگاشت کن و همان را در `definePersona` و گزارش نهایی بنویس. اگر کاربر دربارهٔ یک مورد نظری نداد، پیش‌فرض را پیشنهاد بده (`neutral-professional`) و تأیید بگیر؛ هیچ مقداری را بی‌صدا فرض نکن.


## ۵. اعتبارسنجی (الزامی)
1. `npx -y pnpm@10.18.0 exec tsc --noEmit` بدون خطا.
2. `validate_agent_output` روی همهٔ فایل‌های تغییرکرده؛ خطاها را برطرف کن و دوباره اجرا کن تا `approved`. همچنین `validate_rtl`، `validate_accessibility` و `validate_responsive_behavior`. سه کد پرتکرار را جدی بگیر: `layout/dock-search` (پاپ‌آپ جستجو)، `layout/media-player-kit` (پخش‌کنندهٔ محلی به‌جای پخش‌کنندهٔ داک) و `auth/arrival-target` (پرواز تصویر پروفایل به آیکون حساب).
3. dev server پروژهٔ **موجود** را بالا بیار و در مرورگر بررسی کن: صفحه‌های مهاجرت‌کرده، داکت پایین، TopBar، breadcrumb، ورود تا نمایش ورود موفق، و تقویم. کنسول و لاگ سرور نباید خطای قرمز داشته باشند.
4. اگر تست‌های خود پروژه وجود دارند، اجرا کن و بگو کدام‌ها پیش‌تر هم شکسته بودند (با شاهد: همان تست روی برنچ اصلی).

## ۶. گزارش نهایی (الزامی)
- مسیر پروژهٔ موجود (تأیید کن همان است که در ابتدا بازرسی شد) و شاخهٔ کار.
- گزارش بازرسی گام ۰.۱ (خلاصه).
- فهرست گام‌های انجام‌شده + کامیت هر گام.
- صفحه‌هایی که مهاجرت کردند و صفحه‌هایی که **ماندند** (با دلیل).
- نتیجهٔ `tsc` و `validate_agent_output` (approved یا خطاها).
- **تأیید صریح این جمله:** «پروژهٔ جدیدی ساخته نشد؛ همهٔ تغییرات در ریشهٔ پروژهٔ موجود است.» اگر خلافش اتفاق افتاد، مسیر فایل‌های اضافه را بگو و پاکشان کن.
- اگر داشت: پخش‌کنندهٔ قدیمی کجا بود، با چه عوض شد، و تأیید اینکه هیچ `<audio>`/`new Audio()`/کتابخانهٔ پخش‌کننده و هیچ کوچک‌کنندهٔ اختصاصی در کد نمانده.
- هر مانعی (مثل دسترسی گیت، نبود کامپوننت در کیت) را صریح بنویس.
- چیزهایی که نمایشی‌اند (ورود، داده‌ها) را فهرست کن.

## ۷. توقف‌های اجباری (stop conditions)
در این موارد **توقف کن و بپرس**؛ خودسرانه ادامه نده:
- فریم‌ورک پروژه غیرِ React است و باید بازنویسی شود.
- بازرسی گام ۰.۱ نشان می‌دهد پروژه در میانهٔ یک مهاجرت/ریفکتور بزرگ دیگر است.
- برای پاس‌شدن اعتبارسنجی باید کامپوننت یا توکنی در کیت تغییر کند.
- لازم است فایلی بیرون از ریشهٔ پروژهٔ موجود ساخته شود.
- توکن `NPM_TOKEN` در دسترس نیست یا پکیج `<name>@^0.2.2` در رجیستری پیدا نشد (گزارش بده، پروژهٔ نو نساز).


## ویرایشگر متن غنی و پارامترهای داینامیک (الزامی)
- متن غنی (قالب‌بندی، تصویر، فایل، پخش صوت) فقط با `RichTextEditor` یا `InlineEditor` از `@tokapps/editor` ساخته شود. ساختن ویرایشگر با `contenteditable`، `document.execCommand`، quill، tinymce، slate، lexical یا `@tiptap/*` مستقیم در کد محصول ممنوع است (گیت `editor/kit`).
- شماره تماس، ایمیل، نشانی، قیمت و نام شرکت یا محصول در متن رابط ثابت نوشته نشود؛ با `DynamicText` (`{{key}}`) یا `<Param k="…" />` از `@tokapps/tuk/params` نمایش داده شود تا تغییر در ادمین همه‌جا اعمال شود (گیت `content/dynamic-params`).
- صوت داخل متن مقاله فقط با بلوک `::player{param=…}` یا `RichTextEditor` و پخش روی داک انجام شود؛ `<audio>` محلی ساخته نشود.
