Merge pull request #80 from NeuralNomadsAI/dev

Release 0.7.4
This commit is contained in:
Shantur Rathore
2026-01-20 19:30:19 +00:00
committed by GitHub
9 changed files with 38 additions and 14 deletions

12
package-lock.json generated
View File

@@ -1,12 +1,12 @@
{ {
"name": "codenomad-workspace", "name": "codenomad-workspace",
"version": "0.7.3", "version": "0.7.4",
"lockfileVersion": 3, "lockfileVersion": 3,
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"name": "codenomad-workspace", "name": "codenomad-workspace",
"version": "0.7.3", "version": "0.7.4",
"dependencies": { "dependencies": {
"7zip-bin": "^5.2.0", "7zip-bin": "^5.2.0",
"google-auth-library": "^10.5.0" "google-auth-library": "^10.5.0"
@@ -7389,7 +7389,7 @@
}, },
"packages/electron-app": { "packages/electron-app": {
"name": "@neuralnomads/codenomad-electron-app", "name": "@neuralnomads/codenomad-electron-app",
"version": "0.7.3", "version": "0.7.4",
"dependencies": { "dependencies": {
"@codenomad/ui": "file:../ui", "@codenomad/ui": "file:../ui",
"@neuralnomads/codenomad": "file:../server" "@neuralnomads/codenomad": "file:../server"
@@ -7423,7 +7423,7 @@
}, },
"packages/server": { "packages/server": {
"name": "@neuralnomads/codenomad", "name": "@neuralnomads/codenomad",
"version": "0.7.3", "version": "0.7.4",
"dependencies": { "dependencies": {
"@fastify/cors": "^8.5.0", "@fastify/cors": "^8.5.0",
"@fastify/reply-from": "^9.8.0", "@fastify/reply-from": "^9.8.0",
@@ -7458,14 +7458,14 @@
}, },
"packages/tauri-app": { "packages/tauri-app": {
"name": "@codenomad/tauri-app", "name": "@codenomad/tauri-app",
"version": "0.7.3", "version": "0.7.4",
"devDependencies": { "devDependencies": {
"@tauri-apps/cli": "^2.9.4" "@tauri-apps/cli": "^2.9.4"
} }
}, },
"packages/ui": { "packages/ui": {
"name": "@codenomad/ui", "name": "@codenomad/ui",
"version": "0.7.3", "version": "0.7.4",
"dependencies": { "dependencies": {
"@git-diff-view/solid": "^0.0.8", "@git-diff-view/solid": "^0.0.8",
"@kobalte/core": "0.13.11", "@kobalte/core": "0.13.11",

View File

@@ -1,6 +1,6 @@
{ {
"name": "codenomad-workspace", "name": "codenomad-workspace",
"version": "0.7.3", "version": "0.7.4",
"private": true, "private": true,
"description": "CodeNomad monorepo workspace", "description": "CodeNomad monorepo workspace",
"workspaces": { "workspaces": {

View File

@@ -1,6 +1,6 @@
{ {
"name": "@neuralnomads/codenomad-electron-app", "name": "@neuralnomads/codenomad-electron-app",
"version": "0.7.3", "version": "0.7.4",
"description": "CodeNomad - AI coding assistant", "description": "CodeNomad - AI coding assistant",
"author": { "author": {
"name": "Neural Nomads", "name": "Neural Nomads",

View File

@@ -1,12 +1,12 @@
{ {
"name": "@neuralnomads/codenomad", "name": "@neuralnomads/codenomad",
"version": "0.7.3", "version": "0.7.4",
"lockfileVersion": 3, "lockfileVersion": 3,
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"name": "@neuralnomads/codenomad", "name": "@neuralnomads/codenomad",
"version": "0.7.3", "version": "0.7.4",
"dependencies": { "dependencies": {
"@fastify/cors": "^8.5.0", "@fastify/cors": "^8.5.0",
"commander": "^12.1.0", "commander": "^12.1.0",

View File

@@ -1,6 +1,6 @@
{ {
"name": "@neuralnomads/codenomad", "name": "@neuralnomads/codenomad",
"version": "0.7.3", "version": "0.7.4",
"description": "CodeNomad Server", "description": "CodeNomad Server",
"author": { "author": {
"name": "Neural Nomads", "name": "Neural Nomads",

View File

@@ -1,6 +1,6 @@
{ {
"name": "@codenomad/tauri-app", "name": "@codenomad/tauri-app",
"version": "0.7.3", "version": "0.7.4",
"private": true, "private": true,
"scripts": { "scripts": {
"dev": "tauri dev", "dev": "tauri dev",

View File

@@ -1,6 +1,6 @@
{ {
"name": "@codenomad/ui", "name": "@codenomad/ui",
"version": "0.7.3", "version": "0.7.4",
"private": true, "private": true,
"type": "module", "type": "module",
"scripts": { "scripts": {

View File

@@ -92,6 +92,19 @@ function workspaceDescriptorToInstance(descriptor: WorkspaceDescriptor): Instanc
} }
} }
function ensureActiveInstanceSelected(): void {
const current = activeInstanceId()
const instanceMap = instances()
if (current && instanceMap.has(current)) return
for (const [id, instance] of instanceMap.entries()) {
if (instance.status === "ready") {
setActiveInstanceId(id)
return
}
}
}
function upsertWorkspace(descriptor: WorkspaceDescriptor) { function upsertWorkspace(descriptor: WorkspaceDescriptor) {
const mapped = workspaceDescriptorToInstance(descriptor) const mapped = workspaceDescriptorToInstance(descriptor)
if (instances().has(descriptor.id)) { if (instances().has(descriptor.id)) {
@@ -102,6 +115,9 @@ function upsertWorkspace(descriptor: WorkspaceDescriptor) {
if (descriptor.status === "ready") { if (descriptor.status === "ready") {
attachClient(descriptor) attachClient(descriptor)
// If no tab is currently selected (common after UI refresh),
// auto-select the first ready instance.
ensureActiveInstanceSelected()
} }
} }
@@ -225,15 +241,18 @@ async function hydrateInstanceData(instanceId: string) {
} }
} }
void (async function initializeWorkspaces() { void (async function initializeWorkspaces() {
try { try {
const workspaces = await serverApi.fetchWorkspaces() const workspaces = await serverApi.fetchWorkspaces()
workspaces.forEach((workspace) => upsertWorkspace(workspace)) workspaces.forEach((workspace) => upsertWorkspace(workspace))
// After a UI refresh, we may have instances but no active selection.
ensureActiveInstanceSelected()
} catch (error) { } catch (error) {
log.error("Failed to load workspaces", error) log.error("Failed to load workspaces", error)
} }
})() })()
serverEvents.on("*", (event) => handleWorkspaceEvent(event)) serverEvents.on("*", (event) => handleWorkspaceEvent(event))
function handleWorkspaceEvent(event: WorkspaceEventPayload) { function handleWorkspaceEvent(event: WorkspaceEventPayload) {

View File

@@ -39,6 +39,7 @@ import { loadMessages } from "./session-api"
import { import {
applyPartUpdateV2, applyPartUpdateV2,
replaceMessageIdV2, replaceMessageIdV2,
reconcilePendingQuestionsV2,
upsertMessageInfoV2, upsertMessageInfoV2,
upsertPermissionV2, upsertPermissionV2,
upsertQuestionV2, upsertQuestionV2,
@@ -230,6 +231,10 @@ function handleMessageUpdate(instanceId: string, event: MessageUpdateEvent | Mes
applyPartUpdateV2(instanceId, { ...part, sessionID: sessionId, messageID: messageId }) applyPartUpdateV2(instanceId, { ...part, sessionID: sessionId, messageID: messageId })
if (part.type === "tool" && part.tool === "question") {
// Questions can arrive before their tool part exists; re-link now.
reconcilePendingQuestionsV2(instanceId, sessionId)
}
updateSessionInfo(instanceId, sessionId) updateSessionInfo(instanceId, sessionId)
} else if (event.type === "message.updated") { } else if (event.type === "message.updated") {