mirror of
https://github.com/wu736139669/hapi.git
synced 2026-10-22 22:01:18 +00:00
feat: add real-time permission and model mode synchronization close #21
Implements bidirectional sync of permission/model modes between CLI sessions and web app. Adds Codex-specific permission modes (read-only, safe-yolo, yolo) alongside Claude's modes. Web can now control CLI session state via RPC set-session-config handler, while CLI broadcasts state changes through keep-alive payloads. UI controls are flavor-aware, showing appropriate modes for Claude vs Codex vs Gemini. Type centralization in api/types eliminates circular dependencies.
This commit is contained in:
@@ -7,7 +7,19 @@ import { backoff } from '@/utils/time'
|
||||
import { AsyncLock } from '@/utils/lock'
|
||||
import type { RawJSONLines } from '@/claude/types'
|
||||
import { configuration } from '@/configuration'
|
||||
import type { AgentState, ClientToServerEvents, MessageContent, MessageMeta, Metadata, ServerToClientEvents, Session, Update, UserMessage } from './types'
|
||||
import type {
|
||||
AgentState,
|
||||
ClientToServerEvents,
|
||||
MessageContent,
|
||||
MessageMeta,
|
||||
Metadata,
|
||||
ServerToClientEvents,
|
||||
Session,
|
||||
SessionModelMode,
|
||||
SessionPermissionMode,
|
||||
Update,
|
||||
UserMessage
|
||||
} from './types'
|
||||
import { AgentStateSchema, MetadataSchema, UserMessageSchema } from './types'
|
||||
import { RpcHandlerManager } from './rpc/RpcHandlerManager'
|
||||
import { registerCommonHandlers } from '../modules/common/registerCommonHandlers'
|
||||
@@ -300,12 +312,17 @@ export class ApiSessionClient extends EventEmitter {
|
||||
})
|
||||
}
|
||||
|
||||
keepAlive(thinking: boolean, mode: 'local' | 'remote'): void {
|
||||
keepAlive(
|
||||
thinking: boolean,
|
||||
mode: 'local' | 'remote',
|
||||
runtime?: { permissionMode?: SessionPermissionMode; modelMode?: SessionModelMode }
|
||||
): void {
|
||||
this.socket.volatile.emit('session-alive', {
|
||||
sid: this.sessionId,
|
||||
time: Date.now(),
|
||||
thinking,
|
||||
mode
|
||||
mode,
|
||||
...(runtime ?? {})
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
+15
-6
@@ -1,6 +1,5 @@
|
||||
import { z } from 'zod'
|
||||
import { UsageSchema } from '@/claude/types'
|
||||
import type { PermissionMode } from '@/claude/loop'
|
||||
import type {
|
||||
TerminalClosePayload,
|
||||
TerminalExitPayload,
|
||||
@@ -14,6 +13,11 @@ import type {
|
||||
|
||||
export type Usage = z.infer<typeof UsageSchema>
|
||||
|
||||
export type ClaudePermissionMode = 'default' | 'acceptEdits' | 'bypassPermissions' | 'plan'
|
||||
export type CodexPermissionMode = 'default' | 'read-only' | 'safe-yolo' | 'yolo'
|
||||
export type SessionPermissionMode = ClaudePermissionMode | CodexPermissionMode
|
||||
export type SessionModelMode = 'default' | 'sonnet' | 'opus'
|
||||
|
||||
export type Metadata = {
|
||||
path: string
|
||||
host: string
|
||||
@@ -145,8 +149,8 @@ export type Session = {
|
||||
agentStateVersion: number
|
||||
thinking?: boolean
|
||||
thinkingAt?: number
|
||||
permissionMode?: PermissionMode | null
|
||||
modelMode?: 'default' | 'sonnet' | 'opus' | null
|
||||
permissionMode?: SessionPermissionMode
|
||||
modelMode?: SessionModelMode
|
||||
}
|
||||
|
||||
export const MachineMetadataSchema = z.object({
|
||||
@@ -273,8 +277,6 @@ export type CreateMachineResponse = z.infer<typeof CreateMachineResponseSchema>
|
||||
|
||||
export const MessageMetaSchema = z.object({
|
||||
sentFrom: z.string().optional(),
|
||||
permissionMode: z.string().optional(),
|
||||
model: z.string().nullable().optional(),
|
||||
fallbackModel: z.string().nullable().optional(),
|
||||
customSystemPrompt: z.string().nullable().optional(),
|
||||
appendSystemPrompt: z.string().nullable().optional(),
|
||||
@@ -323,7 +325,14 @@ export interface ServerToClientEvents {
|
||||
|
||||
export interface ClientToServerEvents {
|
||||
message: (data: { sid: string; message: unknown; localId?: string }) => void
|
||||
'session-alive': (data: { sid: string; time: number; thinking: boolean; mode?: 'local' | 'remote' }) => void
|
||||
'session-alive': (data: {
|
||||
sid: string
|
||||
time: number
|
||||
thinking: boolean
|
||||
mode?: 'local' | 'remote'
|
||||
permissionMode?: SessionPermissionMode
|
||||
modelMode?: SessionModelMode
|
||||
}) => void
|
||||
'session-end': (data: { sid: string; time: number }) => void
|
||||
'update-metadata': (data: { sid: string; expectedVersion: number; metadata: unknown }, cb: (answer: {
|
||||
result: 'error'
|
||||
|
||||
Reference in New Issue
Block a user