Skip to content

Commit dd0ea51

Browse files
committed
Merge remote-tracking branch 'origin/master' into rm-tracking-cookie
2 parents f5b99ca + 7d359fd commit dd0ea51

File tree

32 files changed

+592
-79
lines changed

32 files changed

+592
-79
lines changed

src/CLAUDE.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ This file provides guidance to Claude Code (claude.ai/code) and also Gemini CLI
2020
- Some older code is JavaScript or CoffeeScript, which will be translated to TypeScript
2121
- Use ES modules (import/export) syntax, not CommonJS (require)
2222
- Organize the list of imports in such a way: installed npm packages are on top, newline, then are imports from @cocalc's code base. Sorted alphabetically.
23+
- **Backend Logging**: Use `getLogger` from `@cocalc/project/logger` for logging in backend code. Do NOT use `console.log`. Example: `const L = getLogger("module:name").debug;`
2324

2425
## Development Commands
2526

@@ -88,6 +89,13 @@ CoCalc is organized as a monorepo with key packages:
8889
- **Event Emitters**: Inter-service communication within backend
8990
- **REST-like APIs**: Some HTTP endpoints for specific operations
9091
- **API Schema**: API endpoints in `packages/next/pages/api/v2/` use Zod schemas in `packages/next/lib/api/schema/` for validation. These schemas must be kept in harmony with the TypeScript types sent from frontend applications using `apiPost` (in `packages/next/lib/api/post.ts`) or `api` (in `packages/frontend/client/api.ts`). When adding new fields to API requests, both the frontend types and the API schema validation must be updated.
92+
- **Conat Frontend → Hub Communication**: CoCalc uses a custom distributed messaging system called "Conat" for frontend-to-hub communication:
93+
1. **Frontend ConatClient** (`packages/frontend/conat/client.ts`): Manages WebSocket connection to hub, handles authentication, reconnection, and provides API interfaces
94+
2. **Core Protocol** (`packages/conat/core/client.ts`): NATS-like pub/sub/request/response messaging with automatic chunking, multiple encoding formats (MsgPack, JSON), and delivery confirmation
95+
3. **Hub API Structure** (`packages/conat/hub/api/`): Typed interfaces for different services (system, projects, db, purchases, jupyter) that map function calls to conat subjects
96+
4. **Message Flow**: Frontend calls like `hub.projects.setQuotas()` → ConatClient.callHub() → conat request to subject `hub.account.{account_id}.api` → Hub API dispatcher → actual service implementation
97+
5. **Authentication**: Each conat request includes account_id and is subject to permission checks at the hub level
98+
6. **Subjects**: Messages are routed using hierarchical subjects like `hub.account.{uuid}.{service}` or `project.{uuid}.{compute_server_id}.{service}`
9199

92100
### Key Technologies
93101

src/packages/comm/project-status/utils.ts

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,28 @@ import type {
88
DiskUsageInfo,
99
} from "@cocalc/util/types/project-info/types";
1010

11-
// DiskUsage for /tmp !
11+
/**
12+
* Calculate resource usage statistics from cgroup data.
13+
*
14+
* This function processes cgroup resource information and calculates usage percentages
15+
* for both memory and CPU. It works with both cgroup v1 and v2 data structures,
16+
* handling the unified CGroup interface that abstracts the differences between versions.
17+
*/
1218
export function cgroup_stats(cg: CGroup, du?: DiskUsageInfo) {
13-
// why? /tmp is a memory disk in kucalc
19+
// DiskUsage for /tmp – add to memory usage since it's already been
20+
// calculated appropriately by the backend based on whether /tmp is tmpfs
1421
const mem_rss = cg.mem_stat.total_rss + (du?.usage ?? 0);
1522
const mem_tot = cg.mem_stat.hierarchical_memory_limit;
16-
const mem_pct = 100 * Math.min(1, mem_rss / mem_tot);
17-
const cpu_pct = 100 * Math.min(1, cg.cpu_usage_rate / cg.cpu_cores_limit);
23+
24+
// Handle unlimited (-1) and zero memory limits to avoid division by zero
25+
const mem_pct = mem_tot <= 0 ? 0 : 100 * Math.min(1, mem_rss / mem_tot);
26+
27+
// Handle unlimited (-1) and zero CPU limits to avoid division by zero
28+
const cpu_pct =
29+
cg.cpu_cores_limit <= 0
30+
? 0
31+
: 100 * Math.min(1, cg.cpu_usage_rate / cg.cpu_cores_limit);
32+
1833
const cpu_tot = cg.cpu_usage; // seconds
1934
return { mem_rss, mem_tot, mem_pct, cpu_pct, cpu_tot };
2035
}

src/packages/frontend/cspell.json

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,9 @@
4242
"tolerations",
4343
"undelete",
4444
"undeleting",
45-
"revealjs"
45+
"revealjs",
46+
"conat",
47+
"SocketIO"
4648
],
4749
"ignoreWords": [
4850
"antd",
@@ -67,7 +69,8 @@
6769
"xsmall",
6870
"flyouts",
6971
"buttonbar",
70-
"noconf"
72+
"noconf",
73+
"flyoutdragbar"
7174
],
7275
"flagWords": [],
7376
"ignorePaths": ["node_modules/**", "dist/**", "dist-ts/**", "build/**"],

src/packages/frontend/file-associations.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -230,6 +230,13 @@ file_associations["csv"] = {
230230
opts: {},
231231
};
232232

233+
file_associations["json"] = {
234+
editor: "codemirror",
235+
icon: "js-square",
236+
opts: { mode: "javascript", indent_unit: 2, tab_size: 2 },
237+
name: "JSON",
238+
};
239+
233240
// At https://cs.lmu.edu/~ray/notes/gasexamples/ they use .s, so I'm also including that.
234241
// In fact, GCC only works on files if they end in .s.
235242
file_associations["asm"] = file_associations["s"] = {

src/packages/frontend/i18n/trans/ar_EG.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1222,7 +1222,7 @@
12221222
"project.no-internet-modal.add-license": "إضافة الترخيص",
12231223
"project.no-internet-modal.info": "<strong>تم تعطيل الوصول إلى الإنترنت لهذا المشروع.</strong> هذا التقييد يمنع تثبيت حزم بايثون (pip، conda) أو حزم R، واستخدام Git لاستنساخ المستودعات، وتنزيل مجموعات البيانات أو الوصول إلى واجهات برمجة التطبيقات. قد تتعطل الأوامر التي تحاول الوصول إلى الإنترنت أو تفشل في الاكتمال، حيث يتم حظر الاتصالات الشبكية لمنع سوء الاستخدام. <A>تعرف على المزيد</A>.",
12241224
"project.no-internet-modal.message": "لحل هذه المشكلة، <A1>تحتاج إلى تطبيق</A1> <A2>ترخيص صالح</A2> يوفر ترقيات أو <A3>شراء ترخيص</A3>.",
1225-
"project.no-internet-modal.title": "لا يوجد اتصال بالإنترنت",
1225+
"project.no-internet-modal.title": "المشروع \"{name}\" ليس لديه وصول إلى الإنترنت",
12261226
"project.open_file.what": "افتح الملف \"{path}\"",
12271227
"project.page.activity-bar-layout.title": "تخطيط شريط النشاط",
12281228
"project.page.activity-bar.explanation": "هذه الميزة تعدل وظيفة شريط الأزرار في الجانب الأيسر من المشروع. بشكل افتراضي، تعرض الأزرار صفحات كاملة وعلامات صغيرة للوحات المنبثقة. عند اختيار خيار \"الصفحات الكاملة\"، يتم عرض الأزرار فقط، وتفتح الصفحات الكاملة عند النقر. وعلى العكس، عند اختيار وضع \"اللوحات المنبثقة\"، تتوسع اللوحات المنبثقة فقط عند النقر. في كلتا الحالتين الأخيرتين، يمكن عرض نوع اللوحة البديل بالنقر مع الضغط على مفتاح Shift على الزر المقابل.",

src/packages/frontend/i18n/trans/de_DE.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1222,7 +1222,7 @@
12221222
"project.no-internet-modal.add-license": "Lizenz hinzufügen",
12231223
"project.no-internet-modal.info": "<strong>Der Internetzugang ist für dieses Projekt deaktiviert.</strong> Diese Einschränkung verhindert die Installation von Python-Paketen (pip, conda) oder R-Paketen, die Verwendung von Git zum Klonen von Repositories, das Herunterladen von Datensätzen oder den Zugriff auf APIs. Befehle, die versuchen, auf das Internet zuzugreifen, können hängen bleiben oder nicht abgeschlossen werden, da Netzwerkverbindungen blockiert sind, um Missbrauch zu verhindern. <A>Mehr erfahren</A>.",
12241224
"project.no-internet-modal.message": "Um dies zu beheben, müssen Sie eine <A2>gültige Lizenz</A2> anwenden, die Upgrades bereitstellt oder eine <A3>Lizenz kaufen</A3>.",
1225-
"project.no-internet-modal.title": "Kein Internetzugang",
1225+
"project.no-internet-modal.title": "Projekt \"{name}\" hat keinen Internetzugang",
12261226
"project.open_file.what": "öffne die Datei \"{path}\"",
12271227
"project.page.activity-bar-layout.title": "Layout der Aktivitätsleiste",
12281228
"project.page.activity-bar.explanation": "Diese Funktion ändert die Funktionalität der linken Seitenleiste des Projekts. Standardmäßig werden Schaltflächen für ganze Seiten und kleine Caret-Zeichen für Flyout-Panels angezeigt. Bei Auswahl der Option \"ganze Seiten\" werden nur Schaltflächen angezeigt, die beim Klicken ganze Seiten öffnen. Umgekehrt, wenn die Option \"Flyout-Panels\" gewählt wird, erweitern sich nur Flyout-Panels beim Klicken. In beiden letzteren Fällen kann der alternative Paneltyp durch Shift-Klicken auf die entsprechende Schaltfläche angezeigt werden.",

src/packages/frontend/i18n/trans/es_ES.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1222,7 +1222,7 @@
12221222
"project.no-internet-modal.add-license": "Agregar licencia",
12231223
"project.no-internet-modal.info": "<strong>El acceso a Internet está desactivado para este proyecto.</strong> Esta restricción impide instalar paquetes de Python (pip, conda) o paquetes de R, usar Git para clonar repositorios, descargar conjuntos de datos o acceder a APIs. Los comandos que intenten acceder a Internet pueden quedar en espera o no completarse, ya que las conexiones de red están bloqueadas para prevenir abusos. <A>Más información</A>.",
12241224
"project.no-internet-modal.message": "Para solucionar esto, <A1>necesitas aplicar</A1> una <A2>licencia válida</A2> que proporcione actualizaciones o <A3>comprar una licencia</A3>.",
1225-
"project.no-internet-modal.title": "Sin acceso a Internet",
1225+
"project.no-internet-modal.title": "El proyecto \"{name}\" no tiene acceso a Internet",
12261226
"project.open_file.what": "abre el archivo \"{path}\"",
12271227
"project.page.activity-bar-layout.title": "Diseño de la barra de actividad",
12281228
"project.page.activity-bar.explanation": "Esta función modifica la funcionalidad de la barra de botones en el lado izquierdo del proyecto. Por defecto, muestra botones para páginas completas y pequeños signos de acento para paneles desplegables. Al seleccionar la opción de \"páginas completas\", solo se muestran botones, y estos abren páginas completas al hacer clic. Por el contrario, al optar por el modo de \"paneles desplegables\", solo los paneles desplegables se expanden al hacer clic. En ambos casos, el tipo de panel alternativo se puede mostrar haciendo clic con la tecla shift presionada en el botón correspondiente.",

src/packages/frontend/i18n/trans/es_PV.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1222,7 +1222,7 @@
12221222
"project.no-internet-modal.add-license": "Gehitu Lizentzia",
12231223
"project.no-internet-modal.info": "<strong>Interneteko sarbidea desgaituta dago proiektu honetarako.</strong> Murrizketa honek Python paketeak (pip, conda) edo R paketeak instalatzea eragozten du, Git erabiliz biltegiak klonatzea, datu-multzoak deskargatzea edo APIetara sartzea. Internetera sartzen saiatzen diren komandoek zintzilik geratu edo amaitzea huts egin dezakete, sareko konexioak blokeatuta daudelako gehiegikeria saihesteko. <A>Gehiago ikasi</A>.",
12241224
"project.no-internet-modal.message": "Hau konpontzeko, <A1>behar duzu aplikatu</A1> <A2>baliozko lizentzia</A2> eguneratzeak ematen dituzten edo <A3>lizentzia erosi</A3>.",
1225-
"project.no-internet-modal.title": "Ez dago Interneteko sarbiderik",
1225+
"project.no-internet-modal.title": "Proiektuak \"{name}\" ez dauka interneteko sarbiderik",
12261226
"project.open_file.what": "ireki fitxategia \"{path}\"",
12271227
"project.page.activity-bar-layout.title": "Aktibitate barra diseinua",
12281228
"project.page.activity-bar.explanation": "Ezaugarri honek proiektuaren ezkerreko jarduera-barraren funtzionalitatea aldatzen du. Lehenespenez, orrialde osoetarako botoiak eta flyout panelentzako kurtsore txikiak erakusten ditu. \"Orrialde osoak\" aukera hautatzean, botoiak soilik erakusten dira, eta horiek klik egitean orrialde osoak irekitzen dituzte. Aldiz, \"flyout panelak\" modua aukeratzean, flyout panelak soilik zabaltzen dira klik egitean. Azken bi kasuetan, panel mota alternatiboa dagokion botoia shift-klik eginez erakuts daiteke.",

src/packages/frontend/i18n/trans/fr_FR.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1222,7 +1222,7 @@
12221222
"project.no-internet-modal.add-license": "Ajouter une licence",
12231223
"project.no-internet-modal.info": "<strong>L'accès à Internet est désactivé pour ce projet.</strong> Cette restriction empêche l'installation de packages Python (pip, conda) ou de packages R, l'utilisation de Git pour cloner des dépôts, le téléchargement de jeux de données ou l'accès aux APIs. Les commandes qui tentent d'accéder à Internet peuvent se bloquer ou échouer à se terminer, car les connexions réseau sont bloquées pour prévenir les abus. <A>En savoir plus</A>.",
12241224
"project.no-internet-modal.message": "Pour résoudre ce problème, vous <A1>devez appliquer</A1> une <A2>licence valide</A2> offrant des mises à jour ou <A3>acheter une licence</A3>.",
1225-
"project.no-internet-modal.title": "Pas d'accès Internet",
1225+
"project.no-internet-modal.title": "Le projet \"{name}\" n'a pas d'accès à Internet",
12261226
"project.open_file.what": "ouvrir le fichier \"{path}\"",
12271227
"project.page.activity-bar-layout.title": "Disposition de la barre d'activités",
12281228
"project.page.activity-bar.explanation": "Cette fonctionnalité modifie la fonctionnalité de la barre de boutons à gauche du projet. Par défaut, elle affiche des boutons pour les pages complètes et de petits signes de chevron pour les panneaux déroulants. En sélectionnant l'option \"pages complètes\", seuls les boutons sont affichés et ils ouvrent des pages complètes en cliquant dessus. À l'inverse, en choisissant le mode \"panneaux déroulants\", seuls les panneaux déroulants se déploient en cliquant dessus. Dans les deux derniers cas, le type de panneau alternatif peut être affiché en cliquant tout en maintenant la touche majuscule sur le bouton correspondant.",

src/packages/frontend/i18n/trans/he_IL.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1222,7 +1222,7 @@
12221222
"project.no-internet-modal.add-license": "הוסף רישיון",
12231223
"project.no-internet-modal.info": "<strong>הגישה לאינטרנט מושבתת עבור פרויקט זה.</strong> הגבלה זו מונעת התקנת חבילות Python (pip, conda) או חבילות R, שימוש ב-Git לשכפול מאגרים, הורדת מערכי נתונים או גישה ל-APIs. פקודות שמנסות לגשת לאינטרנט עשויות להיתקע או להיכשל בהשלמה, מכיוון שחיבורים לרשת חסומים כדי למנוע שימוש לרעה. <A>למידע נוסף</A>.",
12241224
"project.no-internet-modal.message": "כדי לתקן זאת, אתה <A1>צריך להפעיל</A1> <A2>רישיון תקף</A2> המספק שדרוגים או <A3>לרכוש רישיון</A3>.",
1225-
"project.no-internet-modal.title": "אין גישה לאינטרנט",
1225+
"project.no-internet-modal.title": "לפרויקט \"{name}\" אין גישה לאינטרנט",
12261226
"project.open_file.what": "פתח את הקובץ \"{path}\"",
12271227
"project.page.activity-bar-layout.title": "פריסת סרגל פעילות",
12281228
"project.page.activity-bar.explanation": "תכונה זו משנה את הפונקציונליות של סרגל הכפתורים בצד השמאלי של הפרויקט. כברירת מחדל, הוא מציג כפתורים עבור דפים מלאים וסימני קריאה קטנים עבור פאנלים נפתחים. בעת בחירת אפשרות \"דפים מלאים\", מוצגים רק כפתורים, והם פותחים דפים מלאים בלחיצה. לעומת זאת, בעת בחירת מצב \"פאנלים נפתחים\", רק פאנלים נפתחים מתרחבים בלחיצה. בשני המקרים האחרונים, ניתן להציג את סוג הפאנל החלופי על ידי לחיצה עם מקש Shift על הכפתור המתאים.",

0 commit comments

Comments
 (0)