mirror of
https://github.com/wu736139669/hapi.git
synced 2026-08-05 06:24:37 +00:00
Unify protocol types and modes
This commit is contained in:
@@ -0,0 +1,2 @@
|
||||
export * from './modes'
|
||||
export type * from './types'
|
||||
@@ -0,0 +1,62 @@
|
||||
export const CLAUDE_PERMISSION_MODES = ['default', 'acceptEdits', 'bypassPermissions', 'plan'] as const
|
||||
export type ClaudePermissionMode = typeof CLAUDE_PERMISSION_MODES[number]
|
||||
|
||||
export const CODEX_PERMISSION_MODES = ['default', 'read-only', 'safe-yolo', 'yolo'] as const
|
||||
export type CodexPermissionMode = typeof CODEX_PERMISSION_MODES[number]
|
||||
|
||||
export const PERMISSION_MODES = [
|
||||
'default',
|
||||
'acceptEdits',
|
||||
'bypassPermissions',
|
||||
'plan',
|
||||
'read-only',
|
||||
'safe-yolo',
|
||||
'yolo'
|
||||
] as const
|
||||
export type PermissionMode = typeof PERMISSION_MODES[number]
|
||||
|
||||
export const MODEL_MODES = ['default', 'sonnet', 'opus'] as const
|
||||
export type ModelMode = typeof MODEL_MODES[number]
|
||||
|
||||
export type AgentFlavor = 'claude' | 'codex' | 'gemini'
|
||||
|
||||
export const PERMISSION_MODE_LABELS: Record<PermissionMode, string> = {
|
||||
default: 'Default',
|
||||
acceptEdits: 'Accept Edits',
|
||||
plan: 'Plan Mode',
|
||||
bypassPermissions: 'Yolo',
|
||||
'read-only': 'Read Only',
|
||||
'safe-yolo': 'Safe Yolo',
|
||||
yolo: 'Yolo'
|
||||
}
|
||||
|
||||
export const MODEL_MODE_LABELS: Record<ModelMode, string> = {
|
||||
default: 'Default',
|
||||
sonnet: 'Sonnet',
|
||||
opus: 'Opus'
|
||||
}
|
||||
|
||||
export function getPermissionModesForFlavor(flavor?: string | null): readonly PermissionMode[] {
|
||||
if (flavor === 'codex') {
|
||||
return CODEX_PERMISSION_MODES
|
||||
}
|
||||
if (flavor === 'gemini') {
|
||||
return []
|
||||
}
|
||||
return CLAUDE_PERMISSION_MODES
|
||||
}
|
||||
|
||||
export function isPermissionModeAllowedForFlavor(mode: PermissionMode, flavor?: string | null): boolean {
|
||||
return getPermissionModesForFlavor(flavor).includes(mode)
|
||||
}
|
||||
|
||||
export function getModelModesForFlavor(flavor?: string | null): readonly ModelMode[] {
|
||||
if (flavor === 'codex' || flavor === 'gemini') {
|
||||
return []
|
||||
}
|
||||
return MODEL_MODES
|
||||
}
|
||||
|
||||
export function isModelModeAllowedForFlavor(mode: ModelMode, flavor?: string | null): boolean {
|
||||
return getModelModesForFlavor(flavor).includes(mode)
|
||||
}
|
||||
@@ -0,0 +1,165 @@
|
||||
import { z } from 'zod'
|
||||
import { MODEL_MODES, PERMISSION_MODES } from './modes'
|
||||
|
||||
export const PermissionModeSchema = z.enum(PERMISSION_MODES)
|
||||
export const ModelModeSchema = z.enum(MODEL_MODES)
|
||||
|
||||
const MetadataSummarySchema = z.object({
|
||||
text: z.string(),
|
||||
updatedAt: z.number()
|
||||
})
|
||||
|
||||
export const WorktreeMetadataSchema = z.object({
|
||||
basePath: z.string(),
|
||||
branch: z.string(),
|
||||
name: z.string(),
|
||||
worktreePath: z.string().optional(),
|
||||
createdAt: z.number().optional()
|
||||
}).passthrough()
|
||||
|
||||
export type WorktreeMetadata = z.infer<typeof WorktreeMetadataSchema>
|
||||
|
||||
export const MetadataSchema = z.object({
|
||||
path: z.string(),
|
||||
host: z.string(),
|
||||
version: z.string().optional(),
|
||||
name: z.string().optional(),
|
||||
os: z.string().optional(),
|
||||
summary: MetadataSummarySchema.optional(),
|
||||
machineId: z.string().optional(),
|
||||
claudeSessionId: z.string().optional(),
|
||||
codexSessionId: z.string().optional(),
|
||||
tools: z.array(z.string()).optional(),
|
||||
slashCommands: z.array(z.string()).optional(),
|
||||
homeDir: z.string().optional(),
|
||||
happyHomeDir: z.string().optional(),
|
||||
happyLibDir: z.string().optional(),
|
||||
happyToolsDir: z.string().optional(),
|
||||
startedFromDaemon: z.boolean().optional(),
|
||||
hostPid: z.number().optional(),
|
||||
startedBy: z.enum(['daemon', 'terminal']).optional(),
|
||||
lifecycleState: z.string().optional(),
|
||||
lifecycleStateSince: z.number().optional(),
|
||||
archivedBy: z.string().optional(),
|
||||
archiveReason: z.string().optional(),
|
||||
flavor: z.string().nullish(),
|
||||
worktree: WorktreeMetadataSchema.optional()
|
||||
}).passthrough()
|
||||
|
||||
export type Metadata = z.infer<typeof MetadataSchema>
|
||||
|
||||
export const AgentStateRequestSchema = z.object({
|
||||
tool: z.string(),
|
||||
arguments: z.unknown(),
|
||||
createdAt: z.number().nullish()
|
||||
}).passthrough()
|
||||
|
||||
export type AgentStateRequest = z.infer<typeof AgentStateRequestSchema>
|
||||
|
||||
export const AgentStateCompletedRequestSchema = z.object({
|
||||
tool: z.string(),
|
||||
arguments: z.unknown(),
|
||||
createdAt: z.number().nullish(),
|
||||
completedAt: z.number().nullish(),
|
||||
status: z.enum(['canceled', 'denied', 'approved']),
|
||||
reason: z.string().optional(),
|
||||
mode: z.string().optional(),
|
||||
decision: z.enum(['approved', 'approved_for_session', 'denied', 'abort']).optional(),
|
||||
allowTools: z.array(z.string()).optional(),
|
||||
answers: z.record(z.string(), z.array(z.string())).optional()
|
||||
}).passthrough()
|
||||
|
||||
export type AgentStateCompletedRequest = z.infer<typeof AgentStateCompletedRequestSchema>
|
||||
|
||||
export const AgentStateSchema = z.object({
|
||||
controlledByUser: z.boolean().nullish(),
|
||||
requests: z.record(z.string(), AgentStateRequestSchema).nullish(),
|
||||
completedRequests: z.record(z.string(), AgentStateCompletedRequestSchema).nullish()
|
||||
}).passthrough()
|
||||
|
||||
export type AgentState = z.infer<typeof AgentStateSchema>
|
||||
|
||||
export const TodoItemSchema = z.object({
|
||||
content: z.string(),
|
||||
status: z.enum(['pending', 'in_progress', 'completed']),
|
||||
priority: z.enum(['high', 'medium', 'low']),
|
||||
id: z.string()
|
||||
}).passthrough()
|
||||
|
||||
export type TodoItem = z.infer<typeof TodoItemSchema>
|
||||
|
||||
export const TodosSchema = z.array(TodoItemSchema)
|
||||
|
||||
export const DecryptedMessageSchema = z.object({
|
||||
id: z.string(),
|
||||
seq: z.number().nullable(),
|
||||
localId: z.string().nullable(),
|
||||
content: z.unknown(),
|
||||
createdAt: z.number()
|
||||
}).passthrough()
|
||||
|
||||
export type DecryptedMessage = z.infer<typeof DecryptedMessageSchema>
|
||||
|
||||
export const SessionSchema = z.object({
|
||||
id: z.string(),
|
||||
namespace: z.string(),
|
||||
seq: z.number(),
|
||||
createdAt: z.number(),
|
||||
updatedAt: z.number(),
|
||||
active: z.boolean(),
|
||||
activeAt: z.number(),
|
||||
metadata: MetadataSchema.nullable(),
|
||||
metadataVersion: z.number(),
|
||||
agentState: AgentStateSchema.nullable(),
|
||||
agentStateVersion: z.number(),
|
||||
thinking: z.boolean(),
|
||||
thinkingAt: z.number(),
|
||||
todos: TodosSchema.optional(),
|
||||
permissionMode: PermissionModeSchema.optional(),
|
||||
modelMode: ModelModeSchema.optional()
|
||||
}).passthrough()
|
||||
|
||||
export type Session = z.infer<typeof SessionSchema>
|
||||
|
||||
const SessionEventBaseSchema = z.object({
|
||||
namespace: z.string().optional()
|
||||
})
|
||||
|
||||
const SessionChangedSchema = SessionEventBaseSchema.extend({
|
||||
sessionId: z.string()
|
||||
})
|
||||
|
||||
const MachineChangedSchema = SessionEventBaseSchema.extend({
|
||||
machineId: z.string()
|
||||
})
|
||||
|
||||
export const SyncEventSchema = z.discriminatedUnion('type', [
|
||||
SessionChangedSchema.extend({
|
||||
type: z.literal('session-added'),
|
||||
data: z.unknown().optional()
|
||||
}),
|
||||
SessionChangedSchema.extend({
|
||||
type: z.literal('session-updated'),
|
||||
data: z.unknown().optional()
|
||||
}),
|
||||
SessionEventBaseSchema.extend({
|
||||
type: z.literal('session-removed'),
|
||||
sessionId: z.string()
|
||||
}),
|
||||
SessionChangedSchema.extend({
|
||||
type: z.literal('message-received'),
|
||||
message: DecryptedMessageSchema
|
||||
}),
|
||||
MachineChangedSchema.extend({
|
||||
type: z.literal('machine-updated'),
|
||||
data: z.unknown().optional()
|
||||
}),
|
||||
SessionEventBaseSchema.extend({
|
||||
type: z.literal('connection-changed'),
|
||||
data: z.object({
|
||||
status: z.string()
|
||||
}).optional()
|
||||
})
|
||||
])
|
||||
|
||||
export type SyncEvent = z.infer<typeof SyncEventSchema>
|
||||
@@ -0,0 +1,19 @@
|
||||
export type {
|
||||
AgentState,
|
||||
AgentStateCompletedRequest,
|
||||
AgentStateRequest,
|
||||
DecryptedMessage,
|
||||
Metadata,
|
||||
Session,
|
||||
SyncEvent,
|
||||
TodoItem,
|
||||
WorktreeMetadata
|
||||
} from './schemas'
|
||||
|
||||
export type {
|
||||
AgentFlavor,
|
||||
ClaudePermissionMode,
|
||||
CodexPermissionMode,
|
||||
ModelMode,
|
||||
PermissionMode
|
||||
} from './modes'
|
||||
Reference in New Issue
Block a user