Fix session persistence: deterministic workspace IDs based on folder path, improve Antigravity auth error handling
Some checks failed
Release Binaries / release (push) Has been cancelled

This commit is contained in:
Gemini AI
2025-12-27 11:31:25 +04:00
Unverified
parent 6fe7367eff
commit 6b87882d8d
4 changed files with 75 additions and 9 deletions

View File

@@ -0,0 +1,19 @@
{
"sessions": {
"01KDFB53053F09XN5CJ3S7PQWH": {
"id": "01KDFB53053F09XN5CJ3S7PQWH",
"workspaceId": "mjnz73yi",
"title": "New Session",
"parentId": null,
"createdAt": 1766820318213,
"updatedAt": 1766820318213,
"messageIds": [],
"model": {
"providerId": "opencode-zen",
"modelId": "grok-code"
},
"agent": "Assistant"
}
},
"messages": {}
}

View File

@@ -110,9 +110,12 @@ export async function registerAntigravityRoutes(
})
if (!response.ok) {
const error = await response.text()
logger.error({ error, status: response.status }, "Device auth request failed")
return reply.status(500).send({ error: "Failed to start device authorization" })
const errorText = await response.text()
logger.error({ error: errorText, status: response.status }, "Device auth request failed")
return reply.status(500).send({
error: `Device authorization failed: ${response.status}`,
details: errorText
})
}
const data = await response.json() as {
@@ -142,7 +145,7 @@ export async function registerAntigravityRoutes(
}
}
logger.info({ sessionId, userCode: data.user_code }, "Device auth session created")
logger.info({ sessionId, userCode: data.user_code, verificationUrl: data.verification_url }, "Device auth session created")
return {
sessionId,
@@ -151,9 +154,12 @@ export async function registerAntigravityRoutes(
expiresIn: data.expires_in,
interval: data.interval
}
} catch (error) {
logger.error({ error }, "Failed to start device authorization")
return reply.status(500).send({ error: "Failed to start device authorization" })
} catch (error: any) {
logger.error({ error: error.message, stack: error.stack }, "Failed to start device authorization")
return reply.status(500).send({
error: "Failed to start device authorization",
details: error.message
})
}
})

View File

@@ -45,6 +45,31 @@ export class WorkspaceManager {
return this.workspaces.get(id)?.port
}
/**
* Generate a deterministic workspace ID based on folder path
* This ensures the same folder always gets the same workspace ID,
* allowing sessions to persist across app restarts
*/
private generateDeterministicId(folderPath: string): string {
// Normalize the path for consistent hashing across platforms
const normalizedPath = folderPath.replace(/\\/g, '/').toLowerCase()
// Simple hash function to create a short, deterministic ID
let hash = 0
for (let i = 0; i < normalizedPath.length; i++) {
const char = normalizedPath.charCodeAt(i)
hash = ((hash << 5) - hash) + char
hash = hash & hash // Convert to 32bit integer
}
// Convert to base36 and ensure positive
const hashStr = Math.abs(hash).toString(36)
// Return a short but unique ID
return hashStr.padStart(8, '0')
}
listFiles(workspaceId: string, relativePath = "."): FileSystemEntry[] {
const workspace = this.requireWorkspace(workspaceId)
const browser = new FileSystemBrowser({ rootDir: workspace.path })
@@ -71,10 +96,21 @@ export class WorkspaceManager {
// Special constant for Native mode (no OpenCode binary)
const NATIVE_MODE_PATH = "__nomadarch_native__"
const id = `${Date.now().toString(36)}`
const binary = this.options.binaryRegistry.resolveDefault()
const resolvedBinaryPath = this.resolveBinaryPath(binary.path)
const workspacePath = path.isAbsolute(folder) ? folder : path.resolve(this.options.rootDir, folder)
// Generate a deterministic workspace ID based on the folder path
// This ensures the same folder always gets the same ID, allowing sessions to persist
const id = this.generateDeterministicId(workspacePath)
// Check if workspace already exists - if so, return the existing one
const existingWorkspace = this.workspaces.get(id)
if (existingWorkspace && existingWorkspace.status === "ready") {
this.options.logger.info({ workspaceId: id }, "Reusing existing workspace")
return existingWorkspace
}
clearWorkspaceSearchCache(workspacePath)
// Check if we're in native mode

View File

@@ -154,7 +154,12 @@ const AntigravitySettings: Component = () => {
} catch (err: any) {
console.error('Device auth error:', err)
setError(err.message || 'Authentication failed')
// Try to get detailed error message
let errorMessage = err.message || 'Authentication failed'
if (err.details) {
errorMessage += ` - ${err.details}`
}
setError(errorMessage)
setIsAuthenticating(false)
}
}