Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
13 changes: 6 additions & 7 deletions apps/desktop/src/main/browser-agent/driver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ import type { BrowserDownloadsState, BrowserToolbarCommand } from '@sim/desktop-
import { createLogger } from '@sim/logger'
import { getErrorMessage } from '@sim/utils/errors'
import { sleep } from '@sim/utils/helpers'
import { isRecordLike, omit } from '@sim/utils/object'
import { isRecordLike, omit, toRecord } from '@sim/utils/object'
import type { BrowserWindow, MenuItemConstructorOptions, WebContents, WebFrameMain } from 'electron'
import { Menu } from 'electron'
import * as cdp from '@/main/browser-agent/cdp'
Expand Down Expand Up @@ -1015,7 +1015,7 @@ function raceAgainstWatchdog<T>(
*/
async function activeElementState(target: PageExecutionTarget): Promise<Record<string, unknown>> {
const state = await execInPage(target, readActiveElementState, []).catch(() => null)
return isRecordLike(state) ? state : {}
return toRecord(state)
}

function requireSnapshotForElementAction(): void {
Expand Down Expand Up @@ -1191,7 +1191,7 @@ async function pageActionState(
resetMutationRevision,
elementId,
]).catch(() => null)
return isRecordLike(state) ? state : {}
return toRecord(state)
}

function pageEffect(
Expand Down Expand Up @@ -2565,7 +2565,7 @@ async function executeToolInner(
},
}
return {
...(isRecordLike(fallback) ? fallback : {}),
...fallback,
trusted,
...state,
...combinedObservation,
Expand Down Expand Up @@ -2849,12 +2849,11 @@ async function executeToolInner(
await sleep(50)
const state = unwrapPageResult(await execInPage(target, readSelectElementState, [elementId]))
const effectObserved =
isRecordLike(selected) &&
isRecordLike(state) &&
selected.selected === state.selected &&
selected.value === state.value
return {
...(isRecordLike(selected) ? selected : {}),
...selected,
effectObserved,
readback: state,
...(!effectObserved
Expand Down Expand Up @@ -2994,7 +2993,7 @@ async function executeToolInner(
: {}),
}
return {
...(isRecordLike(result) ? result : {}),
...result,
trusted,
effect,
possibleEffectObserved,
Expand Down
17 changes: 0 additions & 17 deletions apps/desktop/src/main/browser-import/browser-sources.ts
Original file line number Diff line number Diff line change
Expand Up @@ -77,23 +77,6 @@ export function userDataDirFor(source: BrowserSource, home: string = homedir()):
return join(home, ...source.userDataSegments)
}

/**
* Splits a bridge profile id back into its browser and profile directory.
*
* Ids are namespaced (`arc:Profile 1`) because profile directory names repeat
* across browsers — every one of them has a `Default`. Returns null for
* anything malformed; the caller then resolves against discovered profiles
* anyway, so a bad id can never become a path.
*/
export function parseProfileId(profileId: string): { sourceId: string; directory: string } | null {
const separator = profileId.indexOf(':')
if (separator <= 0 || separator === profileId.length - 1) return null
return {
sourceId: profileId.slice(0, separator),
directory: profileId.slice(separator + 1),
}
}

export function formatProfileId(sourceId: string, directory: string): string {
return `${sourceId}:${directory}`
}
3 changes: 2 additions & 1 deletion apps/desktop/src/main/browser-import/chromium-profiles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { constants } from 'node:fs'
import { access, lstat, readdir, readFile, realpath } from 'node:fs/promises'
import { homedir } from 'node:os'
import { join } from 'node:path'
import { isRecordLike } from '@sim/utils/object'
import {
BROWSER_SOURCES,
type BrowserSource,
Expand Down Expand Up @@ -134,7 +135,7 @@ async function readProfileDisplayNames(userDataDir: string): Promise<Map<string,
const raw = await readFile(join(userDataDir, 'Local State'), 'utf8')
const infoCache = (JSON.parse(raw) as { profile?: { info_cache?: unknown } }).profile
?.info_cache
if (infoCache && typeof infoCache === 'object' && !Array.isArray(infoCache)) {
if (isRecordLike(infoCache)) {
for (const [dir, info] of Object.entries(infoCache as Record<string, unknown>)) {
if (!PROFILE_DIR_PATTERN.test(dir)) continue
const name = (info as { name?: unknown })?.name
Expand Down
6 changes: 0 additions & 6 deletions apps/desktop/src/main/terminal/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@ import {
type TerminalToolResponse,
} from '@sim/terminal-protocol'
import { sleep } from '@sim/utils/helpers'
import { isRecordLike } from '@sim/utils/object'
import type { BrowserWindow, WebContents } from 'electron'
import {
type FocusedResourceShortcut,
Expand Down Expand Up @@ -1201,8 +1200,3 @@ export class TerminalService {
function unknownTerminal(terminalId: string): string {
return `No terminal with id ${terminalId}. Call terminal_list for the open ones.`
}

/** Narrows an IPC payload to the tool-call shape without trusting the sender. */
export function parseToolParams(value: unknown): Record<string, unknown> {
return isRecordLike(value) ? value : {}
}
28 changes: 0 additions & 28 deletions apps/realtime/src/database/operations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -278,34 +278,6 @@ function findDbDescendants(containerId: string, allBlocks: DbBlockRef[]): string
return descendants
}

/**
* Shared function to handle auto-connect edge insertion
* @param tx - Database transaction
* @param workflowId - The workflow ID
* @param autoConnectEdge - The auto-connect edge data
* @param logger - Logger instance
*/
async function insertAutoConnectEdge(
tx: any,
workflowId: string,
autoConnectEdge: any,
logger: any
) {
if (!autoConnectEdge) return

await tx.insert(workflowEdges).values({
id: autoConnectEdge.id,
workflowId,
sourceBlockId: autoConnectEdge.source,
targetBlockId: autoConnectEdge.target,
sourceHandle: normalizeWorkflowEdgeSourceHandle(autoConnectEdge.sourceHandle),
targetHandle: normalizeWorkflowEdgeTargetHandle(autoConnectEdge.targetHandle),
})
logger.debug(
`Added auto-connect edge ${autoConnectEdge.id}: ${autoConnectEdge.source} -> ${autoConnectEdge.target}`
)
}

enum SubflowType {
LOOP = 'loop',
PARALLEL = 'parallel',
Expand Down

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import type { SVGProps } from 'react'

export const ISO_LINE_STROKE_WIDTH = 3.2
export const ISO_ENDPOINT_STROKE_WIDTH = 3.3
export const ISO_STROKE = 'color-mix(in srgb, var(--text-subtle) 76%, var(--text-muted))'
export const ISO_FILL_LOW = 'var(--surface-6)'
export const ISO_FILL_MID = 'color-mix(in srgb, var(--surface-3) 58%, var(--surface-6))'
Expand Down
20 changes: 0 additions & 20 deletions apps/sim/app/api/credentials/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -117,26 +117,6 @@ async function findExistingCredentialBySourceWith(
return null
}

/**
* `return await` is load-bearing, not redundant. Next 16.3.0's Turbopack
* optimizer models a bare `return <asyncCall>()` tail call as returning the
* promise object, then propagates that always-truthy fact through the caller's
* `await`. It concludes `if (existingCredential)` is always taken and — because
* every branch inside that block returns — deletes the entire create path from
* the emitted bundle, so a first-time create throws on `existingCredential.id`.
* Awaiting here makes the optimizer model the resolved value instead.
*/
async function findExistingCredentialBySource(params: ExistingCredentialSourceParams) {
return await findExistingCredentialBySourceWith(db, params)
}

async function findExistingCredentialBySourceTx(
tx: Parameters<Parameters<typeof db.transaction>[0]>[0],
params: ExistingCredentialSourceParams
) {
return await findExistingCredentialBySourceWith(tx, params)
}

export const GET = withRouteHandler(async (request: NextRequest) => {
const requestId = generateRequestId()
const session = await getSession()
Expand Down
6 changes: 2 additions & 4 deletions apps/sim/app/api/desktop/tool/authorize/route.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { isBrowserToolName } from '@sim/browser-protocol'
import { isTerminalToolName } from '@sim/terminal-protocol'
import { isRecordLike } from '@sim/utils/object'
import { type NextRequest, NextResponse } from 'next/server'
import { authorizeDesktopToolContract } from '@/lib/api/contracts/desktop-tool-authorization'
import { parseRequest } from '@/lib/api/server'
Expand Down Expand Up @@ -43,10 +44,7 @@ export const POST = withRouteHandler(async (request: NextRequest) => {
return createNotFoundResponse('Pending client tool call not found')
}

const args =
toolCall.args && typeof toolCall.args === 'object' && !Array.isArray(toolCall.args)
? (toolCall.args as Record<string, unknown>)
: {}
const args = isRecordLike(toolCall.args) ? (toolCall.args as Record<string, unknown>) : {}
const isBrowserTool = isBrowserToolName(toolCall.toolName)
const isTerminalTool = isTerminalToolName(toolCall.toolName)
const authorized =
Expand Down
Loading
Loading