A real-time chat between two users#2
Conversation
….test.one-on-one-chat1@0.1.0)
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 3 potential issues.
Autofix Details
Bugbot Autofix prepared fixes for all 3 issues found in the latest run.
- ✅ Fixed: Wrong package in env file
- Updated .env VITE_PACKAGE_NAME from 'com.calimero.chat' to 'com.calimero-studio.test.one-on-one-chat1' to match studio.config.json.
- ✅ Fixed: Message times use wrong units
- Removed the multiplication by 1000 in formatTime since created_at from the chat service is already in milliseconds, not seconds.
- ✅ Fixed: Join does not select namespace
- Added setSelectedNsId(nsId) and persistSelectedNamespaceId(nsId) calls after successful joinNamespace to select the joined namespace.
Or push these changes by commenting:
@cursor push f6cb19548e
Preview (f6cb19548e)
diff --git a/app/.env b/app/.env
--- a/app/.env
+++ b/app/.env
@@ -1 +1 @@
-VITE_PACKAGE_NAME=com.calimero.chat
+VITE_PACKAGE_NAME=com.calimero-studio.test.one-on-one-chat1
diff --git a/app/src/components/MessageBubble.tsx b/app/src/components/MessageBubble.tsx
--- a/app/src/components/MessageBubble.tsx
+++ b/app/src/components/MessageBubble.tsx
@@ -11,11 +11,11 @@
}
/**
- * Format a Unix-second timestamp as a local time string.
- * `created_at` from the chat service is in seconds (u64).
+ * Format a Unix-millisecond timestamp as a local time string.
+ * `created_at` from the chat service is in milliseconds (u64).
*/
-function formatTime(createdAtSec: number): string {
- const d = new Date(createdAtSec * 1_000);
+function formatTime(createdAtMs: number): string {
+ const d = new Date(createdAtMs);
return d.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' });
}
diff --git a/app/src/hooks/useChatLobby.ts b/app/src/hooks/useChatLobby.ts
--- a/app/src/hooks/useChatLobby.ts
+++ b/app/src/hooks/useChatLobby.ts
@@ -319,6 +319,8 @@
const result = await joinNamespace(nsId, { invitation, groupAlias });
if (result) {
+ setSelectedNsId(nsId);
+ persistSelectedNamespaceId(nsId);
await refetchNamespaces();
return true;
}You can send follow-ups to the cloud agent here.
| @@ -0,0 +1 @@ | |||
| VITE_PACKAGE_NAME=com.calimero.chat | |||
There was a problem hiding this comment.
Wrong package in env file
High Severity
VITE_PACKAGE_NAME is set to com.calimero.chat, while studio.config.json and APP_PACKAGE use com.calimero-studio.test.one-on-one-chat1. App.tsx prefers the env value for MeroProvider, so the UI can target a different Calimero package than the published bundle and backend.
Additional Locations (1)
Reviewed by Cursor Bugbot for commit 478473a. Configure here.
| */ | ||
| function formatTime(createdAtSec: number): string { | ||
| const d = new Date(createdAtSec * 1_000); | ||
| return d.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' }); |
There was a problem hiding this comment.
Message times use wrong units
Medium Severity
formatTime treats created_at as Unix seconds, but the chat service stores created_at (and edited_at) in milliseconds. Multiplying by 1,000 before Date yields incorrect clock labels in the message list.
Additional Locations (1)
Reviewed by Cursor Bugbot for commit 478473a. Configure here.
|
|
||
| if (result) { | ||
| await refetchNamespaces(); | ||
| return true; |
There was a problem hiding this comment.
Join does not select namespace
Medium Severity
After a successful joinNamespace, joinLobbyViaInvitation only refetches namespaces and never sets the active namespace to the one from the invitation. The UI can stay on another conversation while the user has joined a different chat.
Reviewed by Cursor Bugbot for commit 478473a. Configure here.
The foundation template ships app/.env VITE_PACKAGE_NAME=com.calimero.chat, which shadowed APP_PACKAGE and made the deployed app request a package that is not in the registry. Make APP_PACKAGE (studio.config.json) authoritative.
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
There are 4 total unresolved issues (including 3 from previous reviews).
Bugbot Autofix prepared a fix for the issue found in the latest run.
- ✅ Fixed: clearAuth wrong storage key
- Updated clearAuth to dynamically derive the storage key from studio.config.json using loadStudioConfig() helper, ensuring it clears the correct app-specific key.
Or push these changes by commenting:
@cursor push bd78ad5b57
Preview (bd78ad5b57)
diff --git a/app/e2e/helpers.ts b/app/e2e/helpers.ts
--- a/app/e2e/helpers.ts
+++ b/app/e2e/helpers.ts
@@ -6,19 +6,27 @@
const __dirname = path.dirname(fileURLToPath(import.meta.url));
const STATE_FILE = path.resolve(__dirname, '..', '.playwright-data', 'pw-state.json');
-// App-agnostic post-auth route — read from studio.config.json so this
+// App-agnostic config — read from studio.config.json so this
// infra file is identical across the foundation and every generated app
-// (no per-app patching). Foundation chat → "/chat".
-function appRoute(): string {
+// (no per-app patching).
+function loadStudioConfig(): { appName?: string; metadata?: { route?: string } } {
try {
const cfgPath = path.resolve(__dirname, '..', '..', 'studio.config.json');
- const cfg = JSON.parse(readFileSync(cfgPath, 'utf-8'));
- return cfg?.metadata?.route || '/';
+ return JSON.parse(readFileSync(cfgPath, 'utf-8'));
} catch {
- return '/';
+ return {};
}
}
+function appRoute(): string {
+ return loadStudioConfig()?.metadata?.route || '/';
+}
+
+function selectedNamespaceKey(): string {
+ const appName = loadStudioConfig()?.appName || 'chat';
+ return `${appName}:selectedNamespaceId`;
+}
+
interface NodeState {
name: string;
adminUrl: string;
@@ -70,12 +78,13 @@
try {
const url = page.url();
if (url === 'about:blank' || !url.startsWith('http')) return;
- await page.evaluate(() => {
+ const nsKey = selectedNamespaceKey();
+ await page.evaluate((namespaceKey) => {
[
'mero:access_token', 'mero:refresh_token', 'mero:expires_at',
'mero:node_url', 'mero:application_id', 'mero:context_id',
- 'mero:context_identity', 'chat:selectedNamespaceId',
+ 'mero:context_identity', namespaceKey,
].forEach((k) => localStorage.removeItem(k));
- });
+ }, nsKey);
} catch { /* page may be closed */ }
}You can send follow-ups to the cloud agent here.
Reviewed by Cursor Bugbot for commit 6c44fe1. Configure here.
| [ | ||
| 'mero:access_token', 'mero:refresh_token', 'mero:expires_at', | ||
| 'mero:node_url', 'mero:application_id', 'mero:context_id', | ||
| 'mero:context_identity', 'chat:selectedNamespaceId', |
There was a problem hiding this comment.
clearAuth wrong storage key
Low Severity
clearAuth removes chat:selectedNamespaceId, but the app persists selection under one-on-one-chat:selectedNamespaceId from SELECTED_NAMESPACE_KEY, so e2e cleanup leaves stale conversation selection in localStorage.
Reviewed by Cursor Bugbot for commit 6c44fe1. Configure here.
….test.one-on-one-chat1@0.1.0)
….test.one-on-one-chat1@0.1.0)
….test.one-on-one-chat1@0.1.0)
….test.one-on-one-chat1@0.1.0)



Publish com.calimero-studio.test.one-on-one-chat1@0.1.0
Note
High Risk
High risk because it commits large
.playwright-dataartifacts (RocksDB auth state, logs, node keypairs) and introduces new automation that starts/stops localmerodprocesses, which can impact CI and leak sensitive data.Overview
Introduces a new
app/frontend package (Vite + React) and documents the chat feature plan inIMPLEMENTATION_PLAN.md, alongside project setup tweaks (.nvmrc, expanded.gitignore).Adds Playwright E2E coverage with a global setup/teardown that spawns up to 3 local
merodnodes, authenticates via embedded auth, installs the built.mpk, and runs sender/recipient/history scenarios.Notably, the PR also commits generated runtime/test artifacts under
app/.playwright-data/(node configs, auth RocksDB files, and very large logs).Reviewed by Cursor Bugbot for commit 749b127. Bugbot is set up for automated code reviews on this repo. Configure here.