mirror of
https://github.com/deepseek-ai/deepseek-harness.git
synced 2026-09-12 04:01:20 +00:00
feat(web): add native file actions to artifact cards
This commit is contained in:
@@ -1,10 +1,11 @@
|
||||
/** Session Remote owner: cold reads, explicit Agent commands, and live control state. */
|
||||
|
||||
import { hostname } from 'node:os'
|
||||
import { Context } from '@deepseek-ai/cordis'
|
||||
import z from '@deepseek-ai/schemastery'
|
||||
import { errorChain } from '@deepseek-ai/dsh-llm'
|
||||
import type {} from '@deepseek-ai/dsh-client-file-upload'
|
||||
import { canOpenNativePath, openNativePath } from '@deepseek-ai/dsh-native-command'
|
||||
import { canOpenNativePath, nativeFileManager, openNativePath, revealNativePath } from '@deepseek-ai/dsh-native-command'
|
||||
import type { SessionId } from '@deepseek-ai/dsh-session'
|
||||
import type { SessionInspection } from '@deepseek-ai/dsh-session-persistence'
|
||||
import type { SessionObservation } from '@deepseek-ai/dsh-session-query'
|
||||
@@ -76,6 +77,8 @@ export interface Config {
|
||||
export interface SessionControllerInternals {
|
||||
/** Native default-application handoff. */
|
||||
readonly openPath?: (path: string, signal: AbortSignal) => Promise<void>
|
||||
/** Native file-manager handoff. */
|
||||
readonly revealPath?: (path: string, signal: AbortSignal) => Promise<void>
|
||||
/** Native handoff availability probe. */
|
||||
readonly canOpenPath?: () => boolean
|
||||
}
|
||||
@@ -105,6 +108,7 @@ export class SessionController extends TypertRemoteService {
|
||||
private readonly history: SessionHistoryController
|
||||
private readonly listState: ApiSessionList
|
||||
private readonly openPath: (path: string, signal: AbortSignal) => Promise<void>
|
||||
private readonly revealPath: (path: string, signal: AbortSignal) => Promise<void>
|
||||
private readonly canOpenPath: () => boolean
|
||||
private readonly promotions = new Set<Promise<void>>()
|
||||
|
||||
@@ -132,6 +136,7 @@ export class SessionController extends TypertRemoteService {
|
||||
this.history = new SessionHistoryController(ctx, (observation) => { this.promote(observation) })
|
||||
this.listState = new ApiSessionList(ctx)
|
||||
this.openPath = internals.openPath ?? openNativePath
|
||||
this.revealPath = internals.revealPath ?? revealNativePath
|
||||
this.canOpenPath = internals.canOpenPath
|
||||
?? (() => config.nativeOpen ?? (internals.openPath !== undefined || canOpenNativePath()))
|
||||
ctx.plugin(SessionFileReferences)
|
||||
@@ -268,6 +273,15 @@ export class SessionController extends TypertRemoteService {
|
||||
return this.canOpenPath()
|
||||
}
|
||||
|
||||
/**
|
||||
* Describe the serving desktop for authenticated file-action routes.
|
||||
* @returns Host name, configured availability, and platform-specific file-manager behavior.
|
||||
*/
|
||||
workspaceDesktop(): { name: string; available: boolean; fileManager: 'finder' | 'explorer' | 'directory' | null } {
|
||||
const fileManager = nativeFileManager()
|
||||
return { name: hostname(), available: fileManager !== null && this.canOpenPath(), fileManager }
|
||||
}
|
||||
|
||||
/**
|
||||
* Open one path prepared by a Session-aware caller on the Host desktop.
|
||||
* @param request - path after best-effort Session workspace resolution.
|
||||
@@ -289,7 +303,8 @@ export class SessionController extends TypertRemoteService {
|
||||
}
|
||||
signal.throwIfAborted()
|
||||
try {
|
||||
await this.openPath(request.path, signal)
|
||||
if (request.action === 'reveal') await this.revealPath(request.path, signal)
|
||||
else await this.openPath(request.path, signal)
|
||||
return { opened: true }
|
||||
} catch (error: unknown) {
|
||||
if (signal.aborted) throw new RemoteError('gateway/cancelled', 'path open was aborted', {})
|
||||
|
||||
@@ -358,6 +358,8 @@ export interface SessionCancelValue {
|
||||
|
||||
/** Request to open one path prepared by a Session-aware caller on the Host desktop. */
|
||||
export interface SessionOpenWorkspacePathRequest {
|
||||
/** File-manager navigation when requested; omission uses the default application. */
|
||||
readonly action?: 'reveal'
|
||||
/** Path after best-effort Session workspace resolution, in Host filesystem syntax. */
|
||||
readonly path: string
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user