مواد پر جائیں

آرکیٹیکچر

Control Center فیچر-فرسٹ کلین آرکیٹیکچر کی پیروی کرتا ہے، پورٹس اینڈ اڈاپٹرز پیٹرن کے ساتھ۔ کوڈ بیس کاروباری ڈومینز (فیچرز) کے گرد منظم ہے، اور سخت انحصاری قواعد ایک خودکار آرکیٹیکچر ٹیسٹ کے ذریعے نافذ کیے جاتے ہیں۔

Control Center ایک تھن-کلائنٹ آرکیٹیکچر ہے۔ کوئی بھی کلائنٹ ڈیٹا بیس نہیں کھولتا — ایک ہیڈلیس cc_server پروسیس ڈیٹا کا مالک ہے (ایک چھوٹا global.db اور فی ورک اسپیس ایک SQLite فائل، جو ضرورت پڑنے پر کھولی جاتی ہے) اور اسے WebSocket RPC پر پیش کرتا ہے۔ ڈیسک ٹاپ ایپ، ویب بلڈ اور فون ساتھی، سب اسی ایک RPC کنکشن پر رینڈرر ہیں۔

ڈیسک ٹاپ پہلی بار چلانے پر خود چنتا ہے کہ اپنے سرور تک کیسے پہنچے گا: مقامی (یہ اسی مشین پر ایک cc_server شروع کرتا ہے اور loopback پر بات کرتا ہے — یہی ڈیفالٹ ہے) یا ریموٹ (یہ کہیں اور موجود cc_server سے ایک محفوظ WebSocket پر جڑتا ہے)۔ ویب کلائنٹ ہمیشہ ریموٹ ہوتا ہے۔ بوٹ ریزالور (bootstrap/server_backend.dart) Riverpod کے وجود میں آنے سے پہلے راستہ چنتا ہے، پھر rpcClientProvider کو جڑے ہوئے کلائنٹ سے بدل دیتا ہے — لہٰذا ہر فیچر مقامی ڈیٹا بیس کے بجائے سرور کے ذریعے پڑھتا اور لکھتا ہے۔

RPC پرت خود اسٹیٹ لیس ہے: سیشن تصدیق شدہ ہوتا ہے، مگر وہ کسی ورک اسپیس سے بندھا نہیں ہوتا۔ ورک اسپیس سے منسلک ہر کال اپنے آرگیومنٹس میں اپنا workspace_id رکھتی ہے اور ڈسپیچر ایسی کال اس کے بغیر رد کر دیتا ہے۔ یہی چیز ایک سرور پر دو کلائنٹس کو مختلف فعال ورک اسپیسز رکھنے دیتی ہے، بغیر اس کے کہ سرور کے پاس کوئی ایسا “موجودہ ورک اسپیس” ہو جس پر اختلاف ہو — اور اس کا مطلب ہے کہ تنہائی فی کال نافذ ہوتی ہے، فی کنکشن نہیں۔

یہ ایک واحد resolved-lockfile والا Dart ورک اسپیس ہے جس کے اکیس ارکان ہیں — پندرہ پیکیجز اور چھ ایپس — اور اس کے ورک اسپیس روٹ پر ڈیسک ٹاپ+ویب ایپ (control_center) ہے۔ چھ ایپس یہ ہیں: ہیڈلیس سرور بائنری (cc_server)، ہیڈلیس فلیٹ ایگزیکیوٹر (cc_worker)، فون PWA (cc_remote)، WebSocket ریلے بروکر (cc_signaling_server)، Widgetbook گیلری (cc_gallery) اور عوامی ڈیمو میزبان (cc_demo_server)۔ پندرہ پیکیجز یہ ہیں: cc_ui (ڈیزائن سسٹم)، cc_domain (خالص-Dart مشترکہ کرنل: اینٹٹیز، ویلیو آبجیکٹس، پورٹس، ایونٹس اور ہر فیچر کی ڈومین پرت)، cc_harness (بلٹ اِن ایجنٹ کرنل: ایک خالص-Dart ایجنٹ لوپ — پیغامات، پرووائیڈر پورٹ، ٹولز، کمپیکشن، اسٹیئرنگ، ہکس، ذیلی ایجنٹس — جس میں نہ dart:io ہے اور نہ کوئی اور cc_* انحصار)، cc_harness_runtime (بلٹ اِن ہارنس رن ٹائم اڈاپٹر: صرف-VM اسٹریمنگ پرووائیڈرز، OAuth/PKCE کریڈینشل بروکرنگ، کریڈینشل اسٹورز اور عمومی ٹول سیٹ — بغیر کوئی بیرونی CLI انسٹال کیے ایجنٹس چلاتا ہے)، cc_rpc (کلائنٹ ٹرانسپورٹس)، cc_host (سرور کرنل)، cc_data (ریموٹ ریپوزٹریز)، cc_persistence (سرور سائیڈ DB)، cc_server_core (ایپ-سرور کمپوزیشن + شناخت/موجودگی/فلیٹ/ایویلز رن ٹائم)، cc_infra (صرف-VM اڈاپٹرز)، cc_mcp (MCP ٹولز)، cc_mcp_client (بیرونی MCP سرورز کے لیے کلائنٹ، جو ان کے ٹولز کو مقامی رجسٹری میں جوڑتا ہے)، cc_markdown (ان-ریپو markdown انجن)، cc_natives (FFI لیف) اور system_audio_capture۔ مکمل کلائنٹ میٹرکس اور یہ کہ کیا کہاں چلتا ہے، کے لیے ڈیپلائمنٹ اور کلائنٹس دیکھیں۔

Presentation → Application/Providers → Domain ← Infrastructure
  • ڈومین پرت: خالص Dart اینٹٹیز، ویلیو آبجیکٹس، ریپوزٹری انٹرفیسز، پورٹس اور ڈومین سروسز۔ انفراسٹرکچر کے زیرو امپورٹس (نہ dio، نہ drift، نہ نیٹ ورک ماڈلز)۔
  • پریزنٹیشن پرت: اسکرینز، ویجٹس، نوٹیفائرز۔ drift/DAO/ڈیٹا-پرت تک براہِ راست رسائی نہیں؛ سب کچھ Riverpod پرووائیڈرز → ریپوزٹریز سے گزرتا ہے۔
  • انفراسٹرکچر پرت: ڈومین پورٹس اور ریپوزٹری انٹرفیسز کی ٹھوس امپلیمنٹیشنز۔ ڈومین پر منحصر ہے، کبھی اُلٹ نہیں۔

مکمل فیچر کی شکل یہ ہے:

feature_name/
├── data/ # Repository implementations, data sources, services, DTOs, mappers
├── domain/ # Entities, repository interfaces, ports, use cases
├── presentation/ # Screens, widgets, notifiers
└── providers/ # Riverpod providers

lib/features/ کے تحت بہت کم فیچرز واقعی یہ چاروں حصے رکھتے ہیں، اور یہ خلا معلوماتی ہیں، حادثاتی نہیں۔ مشترکہ کرنل ہر فیچر کی domain/ کو cc_domain میں جذب کر چکا ہے اور تھن کلائنٹ کے پاس کوئی ریپوزٹری امپلیمنٹیشن نہیں، اس لیے lib/ کے تحت بیشتر فیچرز صرف presentation/ اور providers/ ہیں اور کچھ نہیں۔ کلائنٹ میں بچ جانے والی کوئی data/ یا domain/ ڈائریکٹری کسی واقعی کلائنٹ-سائیڈ چیز کی نشان دہی کرتی ہے۔

دو نامزد استثنائیں جاننے کے قابل ہیں:

  • mcp صرف providers/ پر مشتمل ہے۔ اس کی ترتیبات اور حالت والی UI settings/ کے تحت ہے اور خود ٹول سطح ایک پیکیج (cc_mcp) ہے، فیچر فولڈر نہیں۔
  • orchestration اور plan_studio صرف presentation/ اور providers/ رکھتے ہیں۔

guardrails فیچر اپنی ڈومین پرت کو روٹ ایپ کے بجائے cc_domain/features/guardrails/ میں رکھتا ہے، کیونکہ اسے سرور نافذ کرتا ہے: ایک قاعدہ کسی ActionClass (یا شیل commandPrefix) کو کسی اسکوپ پر ایک فیصلے سے جوڑتا ہے — allow، prompt یا deny — قواعد فی ورک اسپیس محفوظ ہوتے ہیں اور ہر زیرِ انتظام ایجنٹ ایکشن چلنے سے پہلے پالیسی چین سے گزر کر حل ہوتا ہے۔ حل کرنے کا سلسلہ space > agent > workspace > mode preset > built-in default پر چلتا ہے اور فیصلہ پہلے اُس اسکوپ سے ہوتا ہے جس میں کوئی مماثل قاعدہ ہو؛ سب سے پابند فیصلہ صرف ایک ہی اسکوپ کے اندر اور ایک ایکشن کے اعلان کردہ متعدد کلاسز کو یکجا کرنے میں ٹائی بریکر ہے۔ آپریٹر کو نظر آنے والی سطح ترتیبات → ورک اسپیس → ایجنٹ اجازتیں ہے، یعنی /workspaces/<id>/settings/workspace/permissions پر۔ ماڈل کے لیے گارڈریلز دیکھیں۔

packages/cc_domain/lib/core/domain/ میں وہ اینٹٹیز اور ریپوزٹریز رکھی جاتی ہیں جو 3+ فیچرز میں مشترک ہیں۔ یہ خالص Dart ہے جس میں انفراسٹرکچر کے زیرو انحصار ہیں، اور یہی چیز Flutter کلائنٹ اور Flutter سے پاک سرور بائنری دونوں کو ایک ہی تعریفات امپورٹ کرنے دیتی ہے:

  • بنیادی اینٹٹیز: Agent, AgentRunLog, Workspace, Repo, ReviewSpaceAssociation
  • شناخت اور ملٹی پلیئر: User, Principal (sealed UserPrincipal | AgentPrincipal), WorkspaceMember, WorkspaceRole
  • میموری اینٹٹیز: MemoryFact, MemoryPolicy, AgentWorkingMemory, MemoryAccessGrant
  • مشترکہ ویلیو آبجیکٹس: AgentSkills, AgentRole, Mode, SandboxBackend, SandboxSpec, RunCost
  • مشترکہ پورٹس: SandboxPort, CredentialBrokerPort, WorkspaceFilesystemPort, GitRepoInspectorPort, EmbeddingPort
  • ڈومین سروسز: MemoryAccessPolicy, ActivityLogger, MentionResolver, RunLivenessClassifier
  • DomainEventBus + ایونٹ کی اقسام (ورک اسپیس/ایجنٹ، PR/ریویو، میسجنگ، ٹکٹنگ، پائپ لائن، آرکیسٹریشن، میموری، کیلنڈر/میٹنگز، شناخت اور رکنیت، آبزرویبیلٹی)

Control Center ملٹی یوزر ہے: انسان اور ایجنٹس ہم پلہ اداکار ہیں جنہیں ایک Principal یکجا کرتا ہے۔ ورک اسپیس کا رکن ایک User ہوتا ہے جو کسی WorkspaceRole (owner/admin/member/viewer/guest) پر ایک Workspace سے بندھا ہوتا ہے۔ رکنیت ہی رسائی کی حد ہے — پیئرنگ کی نہیں — اور فی ریپو گرانٹس ورک اسپیس رکنیت کو forge سے زیادہ مراعات یافتہ ہونے سے روکتے ہیں۔ نئے سرور پر سب سے پہلے بنایا جانے والا صارف انسٹال کا مالک ہوتا ہے؛ باقی دعوت نامے یا OIDC سے شامل ہوتے ہیں۔ ورک اسپیس بنانے پر وہ صارف owner کے طور پر رجسٹر ہوتا ہے۔

ریئل ٹائم تعاون authoritative-server + فی-فیلڈ last-writer-wins (LWW) ہے، CRDT نہیں۔ موجودگی (presence) — کون یہاں ہے، کہاں ہے، کرسرز، ٹائپنگ، ایجنٹ کی لائیو حالت اور چلتی لاگت — ایک الگ عارضی لین جو کبھی محفوظ نہیں ہوتی؛ پائیدار اسٹیٹ optimistic-mutation + server-rebase + LWW کی ریڑھ پر سوار ہوتی ہے۔ انسان اور ایجنٹ ایک ہی راسٹر شیئر کرتے ہیں۔ ایک ہی انسانی آپریٹر کے ساتھ موجودگی کی لین بیکار پڑی رہتی ہے اور کوئی راسٹر کروم ظاہر نہیں ہوتا — ملٹی پلیئر اکیلے صارف کو کچھ مہنگا نہیں پڑتا۔

پورٹس ڈومین پرت میں abstract انٹرفیسز ہیں۔ اڈاپٹرز انفراسٹرکچر میں ٹھوس امپلیمنٹیشنز ہیں۔ چونکہ ہیڈلیس سرور ڈیٹا کا مالک ہے اور اسے Flutter سے پاک بلڈ ہونا چاہیے، اس لیے تقریباً ہر اڈاپٹر صرف-VM ہے اور packages/cc_infra/lib/src/ میں رکھا گیا ہے، شعبوں کے لحاظ سے منظم:

پورٹ اڈاپٹر کا مقام
SandboxPort cc_infra/lib/src/sandboxing/ (native_sandbox_adapter.dart)
CredentialBrokerPort cc_infra/lib/src/sandboxing/ (env_credential_broker.dart, github_fine_grained_broker.dart)
GitRepoInspectorPort cc_infra/lib/src/git/ (git_repo_inspector.dart)
EmbeddingPort cc_infra/lib/src/embedding/ (embedding_service.dart)
NotificationPort lib/core/notifications/ (کلائنٹ سائیڈ: سرور ایونٹس مقامی طور پر رینڈر کرتا ہے)
AgentBackend cc_infra/lib/src/dispatch/backends/ (acp_backend.dart, harness_backend.dart, cli_backends.dart)
TicketProviderPort cc_infra/lib/src/tickets/linear/ (LinearTicketAdapter). Jira، ClickUp اور GitHub Issues cc_infra/lib/src/tickets/sync/ میں ٹکٹ-سنک اڈاپٹرز ہیں؛ مقامی ٹکٹس ورک اسپیس ڈیٹا بیس میں رہتے ہیں اور ان کے لیے کوئی TicketProviderPort نہیں۔
PipelineEnginePort cc_domain features/pipelines/domain/services/ (ایک خالص-Dart ڈومین سروس — اسے کسی انفراسٹرکچر کی ضرورت نہیں)

ایپ کمپوزیشن روٹ (di/providers.dart) کلائنٹ سائیڈ پورٹس کو Riverpod پرووائیڈرز کے ذریعے امپلیمنٹیشنز سے باندھتا ہے؛ سرور اپنے اڈاپٹرز cc_server_core میں جوڑتا ہے۔

تمام کلائنٹ اسٹیٹ کے لیے Riverpod:

  • تبدیل ہونے والی اسٹیٹ کے لیے Notifier<T> اور AsyncNotifier<T>
  • async ڈیٹا کے لیے FutureProvider<T>
  • لسٹس اور لائیو قطاریں RPC سبسکرپشنز پر AsyncValue<List<T>> کے طور پر آتی ہیں — سرور اندرونی طور پر Drift .watch() استعمال کرتا ہے؛ کوئی کلائنٹ Drift نہیں کھولتا
  • MCP ٹولز انحصارات کو ٹائپ شدہ کنسٹرکٹر پیرامیٹرز کے طور پر وصول کرتے ہیں، کبھی Ref کے طور پر نہیں

Drift (SQLite)، دو ڈیٹا بیسز میں تقسیم، دونوں cc_persistence میں:

  • GlobalDatabase (<dataDir>/global.db) — حقیقی طور پر سرور بھر کے ٹیبلز کی ایک مختصر فہرست: ورک اسپیس رجسٹری، صارفین/ترجیحات/پیئر شدہ ڈیوائسز، SSO کنکشنز، انسٹال بھر کی سرور ترتیبات، منظم ایکشن پالیسیاں (ایک انسٹال بھر کی پابندی جو ورک اسپیس گارڈریلز کو صرف مزید سخت کر سکتی ہے)، فی صارف نیوز فیڈ، فلیٹ قطار (ورکرز/جابز/پلیسمنٹ لاگ)، تصدیق سے پہلے کا workspace_routes انڈیکس اور انسٹال میٹا ڈیٹا۔ بوٹ صرف اسی فائل کو کھولتا ہے، اس لیے اسٹارٹ اپ لاگت فلیٹ رہتی ہے، چاہے ورک اسپیسز کتنی ہی تاریخ جمع کر لیں۔ یہاں ٹیبل شامل کرنا ایک تنہائی کا فیصلہ ہے جس کے لیے ایک ratchet ٹیسٹ آپ سے دلیل مانگتا ہے۔
  • WorkspaceDatabase (<dataDir>/<workspaceId>/workspace.db) — فی ورک اسپیس ایک ڈائریکٹری، جس میں ایک SQLite فائل کے علاوہ وہ سب کچھ ہوتا ہے جو صرف اسی ورک اسپیس کا ہے، اس لیے کسی گفتگو کے worktrees اور ایجنٹ فائلیں ڈیٹا بیس کے ساتھ ہی رہتی ہیں اور اس کے ساتھ ہی حذف ہو جاتی ہیں۔ تقریباً سب کچھ یہیں رہتا ہے: ایجنٹس، اسپیسز، ٹکٹس، میموری، پائپ لائنز، میٹنگز، کوڈ گراف، ریویوز، ریپوز۔ فائلیں پہلی رسائی پر WorkspaceDatabaseManager.of(workspaceId) کے ذریعے ضرورت پڑنے پر کھلتی ہیں اور تب اپنا quick_check، FTS/trigger انسٹال اور vector_init ادا کرتی ہیں۔

دونوں حصے ایک squashed v1 بیس لائن سے شروع ہوئے — onCreate موجودہ اسکیما بناتا ہے — اور مائیگریشن مراحل صرف اسی صورت میں شامل کیے جاتے ہیں جب کسی ڈیپلائے شدہ ڈیٹا بیس کو آگے لے جانا ہو۔

چونکہ ایک ورک اسپیس ایک فائل ہے، ورک اسپیس ایکسپورٹ کرنا ایک ہی VACUUM INTO اسٹیٹمنٹ (workspace.export) ہے، ٹیبل بہ ٹیبل ڈمپ نہیں؛ workspace.import ایسی فائل کو اپناتا ہے اور اندر موجود workspace_meta سے پتہ لگاتا ہے کہ اس کی اپنی فائل دوبارہ اپنائی گئی ہے یا وہ کسی دوسرے انسٹال سے آئی ہے۔

دونوں ڈیٹا بیسز cc_persistence کی ملکیت ہیں اور صرف cc_server انہیں کھولتا ہے؛ کوئی کلائنٹ DB نہیں کھولتا — ہر کلائنٹ RPC پر پڑھتا/لکھتا ہے۔ ٹیبلز packages/cc_persistence/lib/database/tables/ میں، DAOs .../daos/ میں متعین ہیں؛ ڈومین اینٹٹیز خالص Dart ہیں، Drift ٹیبل کلاسز سے الگ، اور mapping ڈیٹا پرتوں میں ہے۔ FTS5 فل ٹیکسٹ سرچ اور sqlite_vector ایمبیڈنگز سنبھالتا ہے، دونوں صرف سرور پر؛ دونوں ڈیٹا بیسز WAL journal موڈ میں PRAGMA foreign_keys=ON چلاتے ہیں۔

go_router، اور ایک حقیقت باقی سب کچھ طے کرتی ہے: ایپ کے اندر ہر منزل ورک اسپیس سے پہلے لگی ہوتی ہے یعنی /workspaces/:workspaceId/…۔ URL میں ورک اسپیس آئی ڈی فعال ورک اسپیس کا واحد ذریعۂ حقیقت ہے — activeWorkspaceIdProvider روٹ سے چلایا جاتا ہے، اُلٹ نہیں — اسی لیے کسی پری فکس شدہ روٹ سے باہر ورک اسپیس سے منسلک ڈیٹا پڑھنے کو اپنی آئی ڈی کہیں سے نہیں ملتی۔

  • router/routes.dart میں روٹ بلڈر فنکشنز، ہر ایک ورک اسپیس آئی ڈی کو اپنی پہلی آرگیومنٹ کے طور پر لیتا ہے، اسٹرنگ کانسٹنٹس نہیں
  • چار pre-context روٹس بغیر پری فکس کے ہیں: /splash, /onboarding, /signed-out اور /workspaces (پکر)
  • ShellRoute ایپ شیل کو لپیٹتا ہے؛ وہ چاروں سطحیں اس سے باہر فل اسکرین رینڈر ہوتی ہیں
  • تصدیق کا گارڈ: نامکمل سیٹ اپ /onboarding پر جاتا ہے؛ مکمل سیٹ اپ جس کا forge کریڈینشل ختم ہو گیا ہو /signed-out پر جاتا ہے۔ مکمل کا مطلب ہے کہ سائن اِن صارف کے لیے کم از کم ایک forge جڑا ہوا ہو اور کم از کم ایک ورک اسپیس موجود ہو — خاص طور پر GitHub نہیں، اور gh CLI کوئی تصدیقی طریقہ نہیں
  • Onboarding گیٹ features/auth/providers/ میں

تمام بیرونی HTTP سرور میں رہتی ہے۔ کلائنٹس کبھی براہِ راست GitHub، Linear یا Google سے رابطہ نہیں کرتے — وہ سرور کے RPC اوپس کال کرتے ہیں اور حتیٰ کہ ریموٹ میڈیا بھی اپ اسٹریم اوریجن سے نہیں بلکہ سرور کے /proxy/media اینڈ پوائنٹ سے حاصل کیا جاتا ہے۔

  • packages/cc_infra/lib/src/ میں dio کلائنٹس: GitHubApiClient, GitHubPrClient, GitHubContentClient, GitHubGraphQLClient, GitLabApiClient, BitbucketApiClient, LinearGraphQlClient اور GoogleCalendarApiClient
  • انٹرسیپٹرز کے ذریعے auth ٹوکن انجیکشن، بشمول cc_server_core میں فی اکاؤنٹ Google OAuth انٹرسیپٹر جو 401 پر ٹوکنز ریفریش کرتا ہے
  • تمام ایررز packages/cc_infra/lib/src/network/error_mapper.dart سے گزر کر → cc_domain میں متعین ٹائپ شدہ AppException سب کلاسز میں map ہوتے ہیں

سرور وہ کریڈینشلز رکھتا ہے جو اہم ہیں: ایجنٹ لانچ کے لیے GitHub اور ٹکٹنگ ٹوکنز، LLM پرووائیڈر کیز اور OAuth ٹوکنز سب سرور ڈیٹا ڈائرکٹری یا اس کے ماحول کے تحت رہتے ہیں۔ کلائنٹ کی کی چین کے پاس اب بھی اپنا ڈیوائس کریڈینشل اور ریموٹ سرور کے لیے پیئرنگ کی ہوتی ہے۔

  • flutter_secure_storage میں سیکرٹس (macOS کی چین، Windows کریڈینشل مینیجر، Linux libsecret) — کلائنٹ کا ڈیوائس کریڈینشل اور ریموٹ پیئرنگ کیز، پرووائیڈر ٹوکنز نہیں
  • shared_preferences صرف غیر حساس ترجیحات کے لیے (تھیم، فونٹ، لے آؤٹ)
  • پرانے انسٹالز سے بچے ہوئے پرووائیڈر سیکرٹس ایک بار features/auth/providers/credential_migration.dart کے ذریعے سرور کے حوالے کیے جاتے ہیں، پھر کلائنٹ کی چین سے حذف کر دیے جاتے ہیں

آرکیٹیکچر کی پابندیاں test/core/architecture_constraints_test.dart سے جانچی جاتی ہیں، جو انحصاری قواعد کی خلاف ورزی پر فیل ہو جاتا ہے۔