Merge pull request #79 from NeuralNomadsAI/dev

Release 0.7.3 - Bug fixes and minor improvements
This commit is contained in:
Shantur Rathore
2026-01-20 18:53:39 +00:00
committed by GitHub
12 changed files with 53 additions and 27 deletions

12
package-lock.json generated
View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -127,10 +127,18 @@ function parsePort(input: string): number {
}
function resolveHost(input: string | undefined): string {
if (input && input.trim() === "0.0.0.0") {
const trimmed = input?.trim()
if (!trimmed) return DEFAULT_HOST
if (trimmed === "0.0.0.0") {
return "0.0.0.0"
}
return DEFAULT_HOST
if (trimmed === "localhost") {
return DEFAULT_HOST
}
return trimmed
}
async function main() {
@@ -149,11 +157,13 @@ async function main() {
const eventBus = new EventBus(eventLogger)
const isLoopbackHost = (host: string) => host === "127.0.0.1" || host === "::1" || host.startsWith("127.")
const serverMeta: ServerMeta = {
httpBaseUrl: `http://${options.host}:${options.port}`,
eventsUrl: `/api/events`,
host: options.host,
listeningMode: options.host === "0.0.0.0" ? "all" : "local",
listeningMode: isLoopbackHost(options.host) ? "local" : "all",
port: options.port,
hostLabel: options.host,
workspaceRoot: options.rootDir,

View File

@@ -93,6 +93,7 @@ export function createHttpServer(deps: HttpServerDeps) {
})
const allowedDevOrigins = new Set(["http://localhost:3000", "http://127.0.0.1:3000"])
const isLoopbackHost = (host: string) => host === "127.0.0.1" || host === "::1" || host.startsWith("127.")
app.register(cors, {
origin: (origin, cb) => {
@@ -113,10 +114,17 @@ export function createHttpServer(deps: HttpServerDeps) {
return
}
if (allowedDevOrigins.has(origin)) {
cb(null, true)
return
}
if (allowedDevOrigins.has(origin)) {
cb(null, true)
return
}
// When we bind to a non-loopback host (e.g., 0.0.0.0 or LAN IP), allow cross-origin UI access.
if (deps.host === "0.0.0.0" || !isLoopbackHost(deps.host)) {
cb(null, true)
return
}
cb(null, false)
},
@@ -275,13 +283,13 @@ export function createHttpServer(deps: HttpServerDeps) {
}
}
const displayHost = deps.host === "0.0.0.0" ? "127.0.0.1" : deps.host === "127.0.0.1" ? "localhost" : deps.host
const displayHost = deps.host === "127.0.0.1" ? "localhost" : deps.host
const serverUrl = `http://${displayHost}:${actualPort}`
deps.serverMeta.httpBaseUrl = serverUrl
deps.serverMeta.host = deps.host
deps.serverMeta.port = actualPort
deps.serverMeta.listeningMode = deps.host === "0.0.0.0" ? "all" : "local"
deps.serverMeta.listeningMode = deps.host === "0.0.0.0" || !isLoopbackHost(deps.host) ? "all" : "local"
deps.logger.info({ port: actualPort, host: deps.host }, "HTTP server listening")
console.log(`CodeNomad Server is ready at ${serverUrl}`)

View File

@@ -17,7 +17,7 @@ function buildMetaResponse(meta: ServerMeta): ServerMeta {
return {
...meta,
port,
listeningMode: meta.host === "0.0.0.0" ? "all" : "local",
listeningMode: meta.host === "0.0.0.0" || !isLoopbackHost(meta.host) ? "all" : "local",
addresses,
}
}
@@ -35,6 +35,10 @@ function resolvePort(meta: ServerMeta): number {
}
}
function isLoopbackHost(host: string): boolean {
return host === "127.0.0.1" || host === "::1" || host.startsWith("127.")
}
function resolveAddresses(port: number, host: string): NetworkAddress[] {
const interfaces = os.networkInterfaces()
const seen = new Set<string>()

View File

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

View File

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

View File

@@ -604,6 +604,7 @@ export default function PromptInput(props: PromptInputProps) {
}
}
setExpandState("normal")
clearPrompt()
// Ignore attachments for slash commands, but keep them for next prompt.
@@ -843,7 +844,10 @@ export default function PromptInput(props: PromptInputProps) {
const currentPrompt = prompt()
const pos = atPosition()
const cursorPos = textareaRef?.selectionStart || 0
const folderMention = relativePath === "." || relativePath === "" ? "/" : displayPath
const folderMention =
relativePath === "." || relativePath === ""
? "/"
: relativePath.replace(/\/+$/, "") + "/"
if (pos !== null) {
const before = currentPrompt.substring(0, pos + 1)
@@ -887,7 +891,7 @@ export default function PromptInput(props: PromptInputProps) {
if (pos !== null) {
const before = currentPrompt.substring(0, pos)
const after = currentPrompt.substring(cursorPos)
const attachmentText = `@${filename}`
const attachmentText = `@${normalizedPath}`
const newPrompt = before + attachmentText + " " + after
setPrompt(newPrompt)

View File

@@ -339,7 +339,7 @@ const UnifiedPicker: Component<UnifiedPickerProps> = (props) => {
e.preventDefault()
setSelectedIndex((prev) => Math.max(prev - 1, 0))
scrollToSelected()
} else if (e.key === "Enter") {
} else if (e.key === "Enter" || e.key === "Tab") {
e.preventDefault()
const selected = items[selectedIndex()]
if (selected) {
@@ -534,7 +534,7 @@ const UnifiedPicker: Component<UnifiedPickerProps> = (props) => {
<div class="dropdown-footer">
<div>
<span class="font-medium"></span> navigate <span class="font-medium">Enter</span> select {" "}
<span class="font-medium"></span> navigate <span class="font-medium">Tab/Enter</span> select {" "}
<span class="font-medium">Esc</span> close
</div>
</div>