7bc34c79ed
- Removed all cloud-related functionalities, including login prompts and token handling. - Disabled Laxis cloud features, ensuring no data is sent to external servers. - Updated manifest to reflect the new local-only functionality. - Added a new Python server to handle transcripts locally, including WebSocket support. - Implemented storage management for transcripts, including deduplication and file writing. - Created a smoke test for the WebSocket server to simulate transcript updates. - Updated README with setup instructions and usage details for the new local server.
117 lines
6.8 KiB
Markdown
117 lines
6.8 KiB
Markdown
# Result — 002 Planning
|
|
|
|
> اکشن مرتبط: [`action/002_action_planning.md`](../action/002_action_planning.md)
|
|
> تاریخ اجرا: 2026-06-09
|
|
|
|
---
|
|
|
|
## هدف این جلسه
|
|
|
|
خواندن پروژه، فهمیدن ساختار، و پیادهسازی گام اول MVP:
|
|
اتصال افزونهی Chrome به یک سرور پایتون بیرون مرورگر از طریق WebSocket.
|
|
|
|
---
|
|
|
|
## تصمیمهای کلیدی که گرفته شد
|
|
|
|
### معماری — چرا extension بهعنوان WS client؟
|
|
|
|
افزونه نمیتواند خودش سرور باشد (MV3 سرویسورکر TCP port نمیتواند باز کند).
|
|
پس **افزونه client است و پایتون server** — افزونه به `ws://127.0.0.1:8765` وصل میشود.
|
|
|
|
همچنین WS باید از service worker باز شود، نه content script؛ چون content script
|
|
تابع CSP صفحهی گوگل میت است و `connect-src` اتصال را بلاک میکند.
|
|
|
|
### نقطهی hook در کد افزونه
|
|
|
|
`setSpeaker()` در `storage.js` — هر پاراگراف caption نهایی از این تابع رد میشود.
|
|
یک `chrome.runtime.sendMessage` کوچک به آن اضافه شد که background را خبر میکند.
|
|
|
|
### venv برای پایتون
|
|
|
|
تصمیم گرفته شد پایتون داخل `.venv` اجرا شود تا سیستم کثیف نشود.
|
|
|
|
---
|
|
|
|
## چه چیزی ساخته شد
|
|
|
|
| فایل | نوع | کار |
|
|
|------|-----|-----|
|
|
| `bridge/server.py` | جدید | WebSocket server پایتون روی `127.0.0.1:8765` |
|
|
| `bridge/requirements.txt` | جدید | فقط `websockets>=12.0` |
|
|
| `bridge/.gitignore` | جدید | `.venv/` و `transcripts/` از git خارج |
|
|
| `bridge/README.md` | جدید | راهنمای اجرا با venv |
|
|
| `bridge/_smoke_test.py` | جدید | کلاینت تستی بدون Chrome |
|
|
| `bridge/.venv/` | جدید | محیط ایزوله پایتون |
|
|
| `google-meet-transcripts-extension/bridge.js` | جدید | WS client داخل service worker |
|
|
| `login.js` | ویرایش | اضافه شدن `importScripts("bridge.js")` |
|
|
| `storage.js` | ویرایش | `setSpeaker` حالا `TRANSCRIPT_UPDATE` میفرستد |
|
|
| `manifest.json` | ویرایش | `ws://127.0.0.1:8765/*` به `host_permissions` اضافه شد |
|
|
|
|
---
|
|
|
|
## تست انجام شده
|
|
|
|
سرور پایتون با `_smoke_test.py` end-to-end تست شد:
|
|
- PING → PONG ✅
|
|
- سه `TRANSCRIPT_UPDATE` → سه ACK ✅
|
|
- فایل `transcripts/meeting-abc123.txt` با متن فارسی درست ذخیره شد ✅
|
|
|
|
تست با Chrome واقعی هنوز انجام نشده (نیاز به Reload افزونه و یک جلسهی Meet).
|
|
|
|
---
|
|
|
|
## وضعیت چکلیست اصلی (از action)
|
|
|
|
- [x] حذف کدهای laxis — **انجام شد** (اجرای ۲۰۲۶-۰۶-۱۰، پایین را ببین)
|
|
- [x] لوگوی اختصاصی — **انجام شد** (لوگوی جدید جایگزین شد)
|
|
- [x] گرفتن caption از افزونه — گام ۱ (اتصال) انجام شد
|
|
- [x] سرویس MCP روی پورت — **انجام شد** (روی همان `server.py`)
|
|
- [ ] تست میدانی با Chrome واقعی — باقیمانده (نیاز به مرورگر و یک جلسهی Meet)
|
|
|
|
---
|
|
|
|
## اجرای دوم — پاکسازی laxis + MCP + لوگو (۲۰۲۶-۰۶-۱۰)
|
|
|
|
### پاکسازی laxis (هیچ دادهای دیگر بیرون نمیرود)
|
|
|
|
- `analytics.js`: کاملاً خالی شد (از قبل کامنتشده و مرده بود؛ در manifest هم لود نمیشد).
|
|
- `login.js` (service worker): بازنویسی شد — حذف `tabs.onRemoved` (که transcript را آپلود میکرد)،
|
|
حذف `onMessageExternal` (دریافت توکن) و `getTopics`. فقط import ها + نگهداشتن وضعیت لوکال ماند.
|
|
- `runtime.js` (content script): حذف فراخوانی `addRemindLogin()` و کل listener دریافت توکن/fetch.
|
|
- `meetingInfo.js`: `checkToken` و `renewToken` با `return;` در ابتدا خنثی شدند؛ آپلود پایان جلسه
|
|
(`Export2App` + باز کردن `domainUrl/transcript`) حذف شد.
|
|
- `transcript.js`: `Export2App` بلافاصله reject میکند (آپلود ابری قطع)، `getTopics` خنثی شد،
|
|
`addRemindLogin` خالی شد، منوی دانلود از حالت پیشفرضِ «app/cloud» به دانلود محلی `txt` تغییر کرد.
|
|
- `panel/main.js`: لینک لوگو → `domainUrl/login` در هر سه جا حذف شد؛ متنهای برند «Laxis…» حذف شدند.
|
|
- `manifest.json`: `update_url` فروشگاه حذف شد (که افزونه با ID لاکسیس آپدیت نشود)؛ name/description
|
|
به نسخهی محلی و بدون cloud تغییر کرد.
|
|
|
|
### MCP روی server.py
|
|
|
|
سرور حالا در یک پراسس هم WebSocket (برای افزونه) و هم MCP stdio (برای Claude) را اجرا میکند و
|
|
حافظهی `sessions` را share میکنند. ابزارها: `list_sessions`، `get_transcript`،
|
|
`get_latest_transcript` و resource با الگوی `transcript://{session_id}`. کانفیگ Claude Desktop در
|
|
`bridge/README.md`.
|
|
|
|
### درسآموختهها
|
|
|
|
- **stdout برای MCP رزرو است:** همهی `print` ها به stderr منتقل شدند، وگرنه استریم JSON-RPC خراب میشود.
|
|
برای تست دستیِ WebSocket باید از `python server.py --ws-only` استفاده کرد.
|
|
- **کد افزونه minified است:** برای فایلهای فشرده (`meetingInfo.js`) بهجای حذفِ بدنهها، با `return;`
|
|
در ابتدای تابع خنثیسازی شد (کمریسکتر). کدِ مرده باقی میماند ولی هرگز اجرا نمیشود.
|
|
- **یک رشتهی غیرفعال باقیست:** متنِ «Autosave to Laxis cloud…» در `displayGoogleMeetQuota`
|
|
(`transcript.js`) داخل کدِ مرده مانده — هرگز نمایش داده نمیشود چون فراخوانهایش خنثیاند.
|
|
|
|
### تأیید (validation)
|
|
|
|
- syntax همهی فایلهای JS با `node --check` پاس شد.
|
|
- منطق `server.py` با AST + یک smoke test واقعیِ WebSocket (PONG/ACK + ذخیرهی صحیح فارسی) تأیید شد.
|
|
- ابزار/resource های MCP با `mcp` SDK ساخته و اجرا شدند (`get_latest_transcript` متن را درست برگرداند).
|
|
|
|
### باقیمانده برای تو
|
|
|
|
تست میدانی: venv را بساز/فعال کن، `python server.py --ws-only` را اجرا کن، افزونه را در
|
|
`chrome://extensions` **Reload** کن، در یک Meet واقعی caption را روشن کن و خروجی را در
|
|
`bridge/transcripts/` ببین. بعد کانفیگ MCP را به Claude Desktop اضافه کن.
|