بنیادی وجوہات
پچھلا ایڈیٹر اپنی ورکنگ فائل ہدف کی پیرنٹ ڈائریکٹری میں اپ لوڈ کرتا تھا، جس میں /etc یا /var کے تحت SSH اکاؤنٹ اکثر لکھ نہیں سکتا۔ SFTP کے ذریعے نام بدلنے میں نہ کوئی مجاز sudo راستہ تھا، نہ بنیادی حالت کے مقابلے میں تصادم کی جانچ، نہ سیکیورٹی میٹا ڈیٹا کی تصدیق اور نہ قابلِ اعتماد اوور رائٹ کا مفہوم۔ اس کا خرابی ہینڈلر عارضی کاپی حذف کر دیتا تھا، جس سے تکمیل غیر یقینی ہونے پر بھی بحالی کا مواد ضائع ہو جاتا تھا۔
پہلے سیشن کی حیثیت صرف کنکشن کی حالت دکھاتی تھی۔ ٹرمینل کے اشاریے کو نہ کوئی ICMP پیمائش ملتی تھی اور نہ مستند SSH جواب کی پیمائش۔
محفوظ کاری کا پروٹوکول
- ایک مقررہ SSH ہیلپر ایک لنک والی عام فائل کو ڈسکرپٹر سے نسبتی آپریشنز اور راستے کے ہر جزو کے لیے
O_NOFOLLOWکے ساتھ کھولتا ہے۔ یہ مواد، SHA-256 ہیش، ڈیوائس/inode، UID، GID، مکمل اجازتی بٹس، نینو سیکنڈ تک ترمیم/تبدیلی کے اوقات اور تمام قابلِ مطالعہ توسیعی خصوصیات ریکارڈ کرتا ہے۔ Core ہیش کی تصدیق کرتا ہے اور BOM برقرار رکھتے ہوئے UTF-8 کو سختی سے ڈی کوڈ کرتا ہے۔ ہر دستاویز کو ایک مبہمeditIdملتا ہے جو اس کے پلگ اِن، ٹرمینل سیشن اور سرور کی شناخت تک محدود ہوتا ہے۔ - ایک غیر مراعات یافتہ تیاری کا عمل
pwd.getpwuid(os.getuid())کے ذریعے مستند اکاؤنٹ کی ہوم ڈائریکٹری معلوم کرتا ہے،0700موڈ کے ساتھ$HOME/ch-j-sm/بناتا ہے اور ایک نجی، خصوصی بحالی جرنل بناتا ہے۔ غیر محفوظ ہوم، علامتی لنک والا ورک اسپیس یا کسی دوسرے اکاؤنٹ کی ملکیت والا ورک اسپیس مسترد کیا جاتا ہے۔ - Core ایک چھپی ہوئی، بے ترتیب 128 بٹ نام والی
.tmpورکنگ فائل SFTP کے ذریعے خصوصی تخلیق (wx)،0600موڈ اور ساٹھ سیکنڈ کی چینل/اپ لوڈ حد کے ساتھ اپ لوڈ کرتا ہے۔ جرنل میں ہدف، اصل بنیادی حالت اور ورکنگ فائل کا متوقع ہیش ہوتا ہے؛ اس میں اسناد نہیں ہوتیں۔ - ایک SSH exec پورا حتمی مرحلہ انجام دیتا ہے، اختیاری طور پر موجودہ sudo ایگزیکیوٹر کے ذریعے۔ ہیلپر نجی ورکنگ کاپی کو محفوظ طریقے سے کھولتا، ہیش کرتا اور ڈسک پر flush کرتا ہے۔ یہ اصل inode کو لاک کرتا ہے، اس کی بنیادی حالت جانچتا ہے، ہدف کے برابر ایک خصوصی منزل فائل بناتا ہے، تمام مواد لکھتا ہے، میٹا ڈیٹا لاگو کر کے اس کی تصدیق کرتا ہے، اصل کو دوبارہ جانچتا ہے اور متبادل کو flush کرتا ہے۔
- اسی ڈائریکٹری میں
os.replaceہدف کو جوہری طور پر بدل دیتا ہے۔ پیرنٹ ڈائریکٹری flush کی جاتی ہے اور حتمی راستے، ہیش، inode اور میٹا ڈیٹا کی تصدیق ہوتی ہے۔ اصل راستہ تبدیلی تک دستیاب رہتا ہے۔ ورکنگ فائل کبھی فائل سسٹمز کے پار منتقل نہیں کی جاتی اور حتمی مرحلہ اسے کبھی نہیں ہٹاتا۔ - Core کو تصدیق شدہ کامیابی ملنے کے بعد ایک الگ صفائی، ورکنگ فائل اور جرنل ہٹانے سے پہلے حتمی مواد اور سیکیورٹی میٹا ڈیٹا دوبارہ جانچتی ہے۔ صفائی ناکام ہونے پر بھی
recoveryAvailable: trueکے ساتھ تصدیق شدہ محفوظ کاری رپورٹ کی جاتی ہے۔
ناکام اپ لوڈ، ناکام sudo، تصادم، میٹا ڈیٹا کی خرابی یا ناکام تبدیلی اصل فائل اور تیار کردہ تمام مواد کو محفوظ رکھتی ہے۔ نامکمل اپ لوڈز کو اسی طرح شناخت کیا جاتا ہے اور انہیں مکمل ترمیم شدہ دستاویز کے طور پر بحال نہیں کیا جا سکتا۔ SSH رابطہ ٹوٹنا، ایگزٹ اسٹیٹس کا غائب ہونا، وقت ختم ہونا اور غیر متوقع حتمی نتائج نامعلوم کے طور پر رپورٹ ہوتے ہیں، کبھی محفوظ شدہ کے طور پر نہیں۔ Core غیر یقینی دستاویز پر دوسری محفوظ کاری روک دیتا ہے؛ تبدیلی کی کوئی خودکار دوبارہ کوشش نہیں ہوتی۔
میٹا ڈیٹا، مراعات اور حفاظتی حدود
ہیلپر UID، GID اور تمام POSIX اجازتی بٹس، بشمول ایگزیکیوٹیبل، setuid، setgid اور sticky بٹس، محفوظ رکھتا اور ان کی تصدیق کرتا ہے۔ یہ Linux کی توسیعی خصوصیات کو بائٹ بہ بائٹ دوبارہ بناتا ہے، بشمول POSIX ACLs، capabilities اور SELinux لیبلز۔ ملکیت اور فائل کا مواد سیکیورٹی خصوصیات سے پہلے سیٹ کیا جاتا ہے، کیونکہ لکھنا/chown capabilities یا خصوصی اجازتی بٹس مٹا سکتا ہے۔ منزل پر وراثت میں ملی ایسی خصوصیات جو اصل میں نہیں، ہٹا دی جاتی ہیں۔ ترمیم کا وقت نئی تحریر کی عکاسی کرتا ہے اور اصل سے کاپی نہیں ہوتا۔
ناقابلِ مطالعہ یا ناقابلِ اظہار خصوصیت عمل کو روک دیتی ہے؛ میٹا ڈیٹا خاموشی سے خارج نہیں ہوتا۔ IMA/EVM دستخط صراحتاً مسترد کیے جاتے ہیں کیونکہ مواد/inode سے منسلک سالمیت کے دستخط کاپی کرنے سے وہ کالعدم ہو جائیں گے۔ ہدف یا ہوم راستے میں علامتی لنکس، ہارڈ لنک والی فائلیں اور غیر عام فائلیں مسترد ہوتی ہیں۔ جگہ پر یا کمزور تر SFTP اوور رائٹ والا کوئی متبادل استعمال نہیں ہوتا۔
عام قابلِ تحریر محفوظ کاری SSH اکاؤنٹ کے طور پر چلتی ہے۔ محفوظ کی گئی فائلوں کے لیے واضح { sudo: true } درکار ہے؛ پاس ورڈ کے بغیر sudo کے لیے sudo پاس ورڈ اختیاری ہے۔ پاس ورڈز کی توثیق ہوتی ہے اور انہیں صرف چینل کے stdin پر بھیجا جاتا ہے، کبھی کمانڈ، جرنل، ورکنگ فائل، لاگر یا ریموٹ خرابی میں نہیں۔ Root SSH سیشنز موجودہ براہِ راست root ایگزیکیوٹر استعمال کرتے ہیں۔ ناکام اجازت اصل اور ورکنگ کاپی کو جوں کا توں چھوڑ دیتی ہے۔ root کے طور پر چلنے والی تمام محفوظ کاریاں (براہِ راست root SSH یا sudo) ایسی ہدف ڈائریکٹریز/آبائی ڈائریکٹریز کو بھی مسترد کرتی ہیں جو دوسرے اکاؤنٹس کی ملکیت ہوں یا ان کے لیے قابلِ تحریر ہوں یا جن پر رسائی ACL ہو، بجائے اس کے کہ کسی دوسرے اکاؤنٹ کے کنٹرول والے مراعات یافتہ راستے پر بھروسہ کیا جائے۔
مقررہ ہیلپر python3 -I -B کے ساتھ چلتا ہے: یہ صارف کے Python راستے، ورکنگ ڈائریکٹری اور صارف کے site packages کو نظرانداز کرتا ہے اور کوئی bytecode نہیں لکھتا۔ راستے اور JSON آرگیومنٹس Core میں شیل کے لیے کوٹ کیے جاتے ہیں۔ پلگ اِنز کو کبھی من مانا SSH exec یا SFTP ہینڈلز نہیں ملتے۔ موجودہ sandbox، CSP، manifest اجازتیں، ہوسٹ کلید کی تصدیق اور اپ ڈیٹ کی تصدیق بدستور استعمال میں ہیں۔
Plugin API اور باقی Monaco انضمام
الگ سے تقسیم ہونے والا Monaco/File Manager UI اس checkout میں موجود نہیں۔ اس کا UI انضمام، sudo پیغام، غیر محفوظ بفر کی ہینڈلنگ اور ترجمے یہاں نافذ یا جانچے نہیں جا سکے۔ شامل پلگ اِن سورس Hash & Checksum پلگ اِن ہے۔ کوئی متبادل File Manager سورس ایجاد نہیں کیا گیا۔
موجودہ طریقے دستیاب رہتے ہیں۔ اضافی طریقے/آپشنز sandbox والے preload اور اجازت چیک کرنے والے رن ٹائم کے ذریعے فراہم کیے جاتے ہیں:
const opened = await chjPlugin.files.readText(sessionId, path);
// For a protected read, explicitly pass { sudo: true, sudoPassword }.
const result = await chjPlugin.files.saveText(sessionId, path, editor.getValue(), {
editId: opened.editId,
sudo: true, // Include only after the user authorizes elevation.
sudoPassword // Omit for passwordless sudo; never persist this value.
});
if (result.ok && result.value.status === "saved") {
// Mark this exact submitted editor version as saved. Later edits stay dirty.
} else {
// Keep the Monaco model dirty. Translate result.error.code/status.
// result.error.recoveryId/recoveryPath identify retained working material.
}
await chjPlugin.files.closeText(opened.editId);
const recovery = await chjPlugin.files.listRecovery(sessionId);
const copy = await chjPlugin.files.readRecovery(sessionId, recoveryId);
// Review copy.status and copy.text; open a fresh document before another save.
await chjPlugin.files.cleanupRecovery(sessionId, recoveryId);
// Cleanup rejects anything whose target is not currently confirmed.
جب ہدف کی جانچ کے لیے مراعات بڑھانا ضروری ہو تو بحالی کے طریقے اختیاری آخری آرگیومنٹ { sudo: true, sudoPassword } قبول کرتے ہیں۔ یہ sudo کے ذریعے چلنے پر بھی مستند صارف کا ورک اسپیس برقرار رکھتے ہیں۔ جرنلز ایپ کے دوبارہ شروع ہونے اور SSH دوبارہ جڑنے کے بعد بھی باقی رہتے ہیں؛ بحالی کبھی حتمی مرحلہ خودکار طور پر نہیں دہراتی۔ بحال شدہ بفر کو واضح طور پر محفوظ کرنے سے پہلے اسے نئے سرے سے کھولے گئے ہدف سے ملا کر دیکھیں۔
files.read پڑھنے، جانچ اور ہینڈل چھوڑنے کی حفاظت کرتا ہے۔ files.write محفوظ کاری اور بحالی کی صفائی کی حفاظت کرتا ہے۔ موجودہ پلگ اِنز کے لیے writeText ناکامی پر اب بھی reject کرتا ہے؛ saveText منظم { ok, value/error } لفافہ واپس کرتا ہے کیونکہ Electron مسترد شدہ Error آبجیکٹس کی حسبِ ضرورت خصوصیات ہٹا دیتا ہے۔ تین آرگیومنٹس والا پرانا writeText ایک کھلی دستاویز کی بنیادی حالت استعمال کر سکتا ہے۔ ایک ہی راستے کی متعدد زندہ دستاویزات کے لیے editId درکار ہے؛ مبہم پرانی کالز کسی دوسری دستاویز کی بنیادی حالت چننے کی بجائے محفوظ طریقے سے ناکام ہو جاتی ہیں۔ پلگ اِنز کو غیر استعمال شدہ ہینڈلز چھوڑ دینے چاہییں۔
بیرونی UI کو فوراً محفوظ کاری کی حالت دکھانی چاہیے، ناکامی پر بفرز کو غیر محفوظ رکھنا چاہیے، sudo صرف اجازت/تصدیق کی ناکامی کے بعد پیش کرنا چاہیے، تصادم بغیر اوور رائٹ کے دکھانا چاہیے اور کنکشن ٹوٹنے یا نامعلوم نتیجے کے بعد بحالی پیش کرنی چاہیے۔ اسے یہ حالتیں چیک، جرمن اور انگریزی میں ترجمہ کرنی چاہییں۔ تجویز کردہ متن:
| حالت | چیک | جرمن | انگریزی |
|---|---|---|---|
| محفوظ ہو رہا ہے | Ukládání… | Wird gespeichert… | Saving… |
| تصدیق شدہ | Uloženo | Gespeichert | Saved |
| ناکامی | Uložení selhalo | Speichern fehlgeschlagen | Save failed |
| sudo درکار | Vyžadováno oprávnění sudo | sudo-Autorisierung erforderlich | Sudo authorization required |
| تصادم | Původní soubor byl změněn | Originaldatei wurde geändert | Original file changed |
| منقطع | Spojení bylo přerušeno | Verbindung unterbrochen | Connection lost |
| نامعلوم | Výsledek uložení není znám | Speicherergebnis unbekannt | Save result unknown |
| بحالی | Obnova je dostupná | Wiederherstellung verfügbar | Recovery available |
تاخیر کی تعریفیں اور لائف سائیکل
Ping وہ تاخیر ہے جو SSH کے استعمال کردہ ریزولو شدہ IP کو کلائنٹ کی طرف سے حقیقی ICMP echo جواب رپورٹ کرتا ہے۔ Core پلیٹ فارم کا ping ایگزیکیوٹیبل مقررہ آرگیومنٹ ارے کے ساتھ غیر ہم وقت طریقے سے چلاتا ہے، بغیر شیل اور بغیر ایڈمنسٹریٹر آغاز کی ضرورت کے۔ Linux، macOS (بشمول ping6) اور Windows کے آرگیومنٹس الگ منتخب ہوتے ہیں۔ بلاک شدہ ICMP، گمشدہ ایگزیکیوٹیبل، وقت ختم ہونا، غلط آؤٹ پٹ یا <1ms جیسا صرف بالائی حد والا Windows جواب «دستیاب نہیں» قدر دیتا ہے، کوئی گھڑا ہوا عدد نہیں۔
SSH RTT موجودہ مستند SSH کلائنٹ پر ایک مقررہ true exec درخواست کا performance.now() سے ناپا گیا یک سمتی دورانیہ ہے۔ اس میں چینل سیٹ اپ، سرور پروسیسنگ اور جواب کی ترسیل شامل ہے؛ یہ خالص نیٹ ورک RTT یا SSH لاگ اِن کا دورانیہ نہیں۔ اشاریے کا ترجمہ شدہ ٹول ٹپ یہ فرق واضح کرتا ہے۔
ٹرمینل جڑتے ہی نگرانی شروع ہو جاتی ہے۔ جانچیں ہم وقت اور غیر ہم وقت چلتی ہیں، پانچ سیکنڈ کی درخواست/پروسیس حد کے ساتھ۔ اگلا نمونہ پچھلے نمونے کے مکمل ہونے کے بارہ سیکنڈ بعد طے ہوتا ہے، تاکہ اوورلیپ نہ ہو۔ منقطع ہونا ICMP کو روکتا ہے، ٹائمرز صاف کرتا ہے، زیرِ التوا SSH کام منسوخ کرتا ہے اور قدریں صاف کرتا ہے۔ ریکارڈ کی شناخت کی جانچ دوبارہ جڑنے کے بعد پچھلے کنکشن کو قدریں شائع کرنے سے روکتی ہے۔ ICMP کی ناکامی کبھی SSH کنکشن کی حالت نہیں بدلتی۔
تاخیر موجودہ state ایونٹ / ssh:state IPC پے لوڈ کے اندر جاتی ہے:
latency: { pingMs: 24.1, sshRttMs: 31.25, measuredAt: "…" }
دستیاب نہ ہونے والے اعداد null ہوتے ہیں۔ مختصر ٹرمینل اشاریہ ملی سیکنڈ، مقامی زبان میں «دستیاب نہیں» متن اور چیک/جرمن/انگریزی لیبلز استعمال کرتا ہے۔ منقطع ہونے پر یہ چھپ جاتا ہے۔ renderer کی کسی اضافی عمل کی صلاحیت یا IPC درخواست کی ضرورت نہیں پڑی۔
توثیق اور آپریشنل حدود
app/سے چلائیں:npm ci، پھرnpm test۔- حتمی مقامی نتیجہ: 179 ٹیسٹس؛ 163 کامیاب، 0 ناکام، 16 چھوڑے گئے۔ تمام چھوڑے گئے ٹیسٹس اس macOS ہوسٹ پر Linux فائل سسٹم کیسز ہیں۔
npm ci، Python نحو کی کمپائلیشن اورgit diff --checkکامیابی سے مکمل ہوئے۔ - ٹیسٹس Core کی محفوظ کاری/بحالی، sudo پروٹوکول اور پاس ورڈ چھپانے، خطرناک راستوں کی حقیقی POSIX شیل کوٹنگ، تصادم، اپ لوڈز، ناکام صفائی، غیر یقینی نتائج، بیک وقت دستاویزات، IPC اجازتوں اور تاخیر کے لائف سائیکل کا احاطہ کرتے ہیں۔
- Linux فائل سسٹم ٹیسٹس نجی ٹیسٹ اکاؤنٹ ہوم کی تلاش کے ساتھ فراہم کردہ Python انٹری پوائنٹ چلاتے ہیں: ملکیت/موڈ/xattrs، POSIX ACLs، علامتی/ہارڈ لنکس، FIFOs، اپ لوڈ اور میٹا ڈیٹا کی ناکامیاں، تبدیلی کی ناکامیاں، ہدف پر ریس، تبدیلی کے بعد نامعلوم نتائج اور بحالی۔ فائل سسٹمز کے پار تیاری دستیاب ہونے پر
/dev/shmاور ایک اور فائل سسٹم استعمال کرتی ہے۔ یہ ٹیسٹس غیر Linux ہوسٹس پر چھوڑ دیے جاتے ہیں؛ گمشدہ ACL/الگ فائل سسٹم سہولیات صراحتاً چھوڑی جاتی ہیں۔ - شامل کی گئی Linux GitHub Actions جاب مکمل سوٹ چلاتی ہے اور فائل سسٹم کیسز root کے طور پر دہراتی ہے۔ یہ ورک فلو ابھی اس working tree سے نہیں چلایا گیا۔
- مقامی توثیق macOS پر ہوئی۔ Python سورس کا نحو براہِ راست Command Line Tools کے Python ایگزیکیوٹیبل سے چیک کیا گیا۔ حقیقی macOS loopback ICMP اسموک چیک نے
0.071 msدیا۔ کوئی زندہ ریموٹ SSH سرور، Windows رن ٹائم، Linux رن ٹائم، SELinux تعیناتی یا بیرونی Monaco UI مقامی طور پر نہیں جانچا گیا۔ - ریموٹ ٹیکسٹ ترمیم کے لیے اب Linux اور ڈسکرپٹر سے نسبتی فائل سسٹم/xattr سپورٹ والا Python 3 درکار ہے۔ گمشدہ انٹرپریٹر واضح طور پر ناکام ہوتا ہے۔ یہ Core جان بوجھ کر غیر محفوظ میٹا ڈیٹا، لنکس اور ڈائریکٹری کنفیگریشنز مسترد کرتا ہے۔
- لاکنگ مشاورتی ہے: غیر تعاون کرنے والے پروسیسز آخری بنیادی جانچ اور جوہری نام بدلنے کے درمیان مختصر وقفے میں اب بھی ریس کر سکتے ہیں۔ Linux مواد کے ہیش کا موازنہ کر کے تبدیل کرنے کا کوئی عمومی جوہری عمل فراہم نہیں کرتا۔ جانچیں اس وقفے سے پہلے تبدیلیاں پکڑتی ہیں؛ محفوظ رکھی گئی ورکنگ کاپیاں بعد میں بحالی میں مدد دیتی ہیں۔
- بحالی کا ڈیٹا تصدیق شدہ صفائی تک ریموٹ اکاؤنٹ پر رہتا ہے۔ نامکمل، تصادم والے اور ناقابلِ جانچ جرنلز کبھی خاموشی سے ضائع نہیں کیے جاتے۔ بحالی فائلوں کی کوئی خودکار میعاد ختم نہیں اور کوئی زبردستی اوور رائٹ آپشن نہیں۔
npm ciنے انحصارات کے آڈٹ کے 17 نتائج (9 درمیانے، 8 زیادہ) رپورٹ کیے۔ یہ تبدیلی انحصارات یا ایپلیکیشن کے اپ ڈیٹ اعتماد ماڈل کو نہیں بدلتی۔
صارف نے موجودہ working tree، فی الحال feature/hash-checksum-plugin، میں تبدیلیاں برقرار رکھنے کی درخواست کی؛ کوئی برانچ تبدیلی یا غیر متعلقہ صفائی نہیں کی گئی۔
اس کام کے لیے تبدیل شدہ فائلیں
src/main/files/remoteFileService.jssrc/main/files/remoteEditor.py(نئی)src/main/sessions/sessionManager.jssrc/main/sessions/latencyMonitor.js(نئی)src/main/plugins/pluginRuntime.jssrc/preload/pluginPreload.jssrc/renderer/app.jssrc/renderer/index.htmlsrc/renderer/styles.csssrc/renderer/i18n.jstest/remoteFileService.test.jstest/sessionManager.test.jstest/pluginRuntime.test.jstest/remoteEditor.test.js(نئی)test/remoteEditorProtocol.test.js(نئی)test/remoteEditorLinux.test.js(نئی)test/fixtures/remoteEditorLinux.py(نئی)test/latencyMonitor.test.js(نئی)README.mddocs/remote-editor-latency.md(یہ فائل)../.github/workflows/remote-editor-tests.yml(نئی)