kaizenai 0.3.0 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/kaizen +16 -5
- package/dist/client/app-icon-180.png +0 -0
- package/dist/client/app-icon-192.png +0 -0
- package/dist/client/app-icon-512.png +0 -0
- package/dist/client/app-icon-96.png +0 -0
- package/dist/client/apple-touch-icon.png +0 -0
- package/dist/client/assets/index-BR0jGwm_.css +32 -0
- package/dist/client/assets/index-CYqy6l6r.js +628 -0
- package/dist/client/favicon.png +0 -0
- package/dist/client/index.html +17 -10
- package/dist/client/manifest-dark.webmanifest +3 -3
- package/dist/client/manifest.webmanifest +3 -3
- package/dist/client/pwa-192.png +0 -0
- package/dist/client/pwa-512.png +0 -0
- package/dist/server/cli-supervisor.js +307 -0
- package/dist/server/cli.js +12371 -0
- package/package.json +7 -9
- package/dist/client/assets/index-BBs80KD-.js +0 -623
- package/dist/client/assets/index-CkCgyLNq.css +0 -32
- package/src/server/acp-shared.ts +0 -315
- package/src/server/agent.ts +0 -1159
- package/src/server/attachments.ts +0 -133
- package/src/server/backgrounds.ts +0 -74
- package/src/server/cli-runtime.ts +0 -375
- package/src/server/cli-supervisor.ts +0 -97
- package/src/server/cli.ts +0 -68
- package/src/server/codex-app-server-protocol.ts +0 -453
- package/src/server/codex-app-server.ts +0 -1350
- package/src/server/cursor-acp.ts +0 -819
- package/src/server/discovery.ts +0 -322
- package/src/server/event-store.ts +0 -1470
- package/src/server/events.ts +0 -252
- package/src/server/external-open.ts +0 -272
- package/src/server/gemini-acp.ts +0 -844
- package/src/server/gemini-cli.ts +0 -525
- package/src/server/generate-title.ts +0 -36
- package/src/server/git-manager.ts +0 -79
- package/src/server/git-repository.ts +0 -101
- package/src/server/harness-types.ts +0 -20
- package/src/server/keybindings.ts +0 -177
- package/src/server/machine-name.ts +0 -22
- package/src/server/paths.ts +0 -112
- package/src/server/process-utils.ts +0 -22
- package/src/server/project-icon.ts +0 -352
- package/src/server/project-metadata.ts +0 -10
- package/src/server/provider-catalog.ts +0 -85
- package/src/server/provider-settings.ts +0 -155
- package/src/server/quick-response.ts +0 -153
- package/src/server/read-models.ts +0 -275
- package/src/server/recovery.ts +0 -507
- package/src/server/restart.ts +0 -56
- package/src/server/server.ts +0 -244
- package/src/server/terminal-manager.ts +0 -350
- package/src/server/theme-settings.ts +0 -179
- package/src/server/update-manager.ts +0 -230
- package/src/server/usage/base-provider-usage.ts +0 -57
- package/src/server/usage/claude-usage.ts +0 -558
- package/src/server/usage/codex-usage.ts +0 -144
- package/src/server/usage/cursor-browser.ts +0 -120
- package/src/server/usage/cursor-cookies.ts +0 -390
- package/src/server/usage/cursor-usage.ts +0 -490
- package/src/server/usage/gemini-usage.ts +0 -24
- package/src/server/usage/provider-usage.ts +0 -61
- package/src/server/usage/test-helpers.ts +0 -9
- package/src/server/usage/types.ts +0 -54
- package/src/server/usage/utils.ts +0 -325
- package/src/server/ws-router.ts +0 -742
- package/src/shared/branding.ts +0 -83
- package/src/shared/dev-ports.ts +0 -43
- package/src/shared/ports.ts +0 -2
- package/src/shared/protocol.ts +0 -156
- package/src/shared/tools.ts +0 -251
- package/src/shared/types.ts +0 -1040
package/src/shared/branding.ts
DELETED
|
@@ -1,83 +0,0 @@
|
|
|
1
|
-
export const APP_NAME = "Kaizen"
|
|
2
|
-
export const CLI_COMMAND = "kaizen"
|
|
3
|
-
export const DATA_ROOT_NAME = ".kaizen"
|
|
4
|
-
export const DEV_DATA_ROOT_NAME = ".kaizen-dev"
|
|
5
|
-
export const PACKAGE_NAME = "kaizenai"
|
|
6
|
-
export const PROJECT_METADATA_DIR_NAME = ".kaizen"
|
|
7
|
-
export const RUNTIME_PROFILE_ENV_VAR = "KAIZEN_RUNTIME_PROFILE"
|
|
8
|
-
export const DISABLE_SELF_UPDATE_ENV_VAR = "KAIZEN_DISABLE_SELF_UPDATE"
|
|
9
|
-
export const DEV_ALLOWED_HOSTS_ENV_VAR = "KAIZEN_DEV_ALLOWED_HOSTS"
|
|
10
|
-
export const DEV_BACKEND_TARGET_HOST_ENV_VAR = "KAIZEN_DEV_BACKEND_TARGET_HOST"
|
|
11
|
-
export const DEV_BACKEND_PORT_ENV_VAR = "KAIZEN_DEV_BACKEND_PORT"
|
|
12
|
-
// Read version from package.json — JSON import works in both Bun and Vite
|
|
13
|
-
import pkg from "../../package.json"
|
|
14
|
-
export const SDK_CLIENT_APP = `kaizen/${pkg.version}`
|
|
15
|
-
export const LOG_PREFIX = "[kaizen]"
|
|
16
|
-
export const DEFAULT_NEW_PROJECT_ROOT = `~/${APP_NAME}`
|
|
17
|
-
export const BROWSER_STORAGE_PREFIX = "kaizen:"
|
|
18
|
-
|
|
19
|
-
export type RuntimeProfile = "dev" | "prod"
|
|
20
|
-
|
|
21
|
-
type RuntimeEnv = Record<string, string | undefined> | undefined
|
|
22
|
-
|
|
23
|
-
function getRuntimeEnv(): RuntimeEnv {
|
|
24
|
-
const candidate = globalThis as typeof globalThis & {
|
|
25
|
-
process?: {
|
|
26
|
-
env?: Record<string, string | undefined>
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
return candidate.process?.env
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
export function getRuntimeProfile(env: RuntimeEnv = getRuntimeEnv()): RuntimeProfile {
|
|
33
|
-
const profile = env?.[RUNTIME_PROFILE_ENV_VAR]
|
|
34
|
-
return profile?.trim().toLowerCase() === "dev" ? "dev" : "prod"
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
export function getDataRootName(env: RuntimeEnv = getRuntimeEnv()) {
|
|
38
|
-
return getRuntimeProfile(env) === "dev" ? DEV_DATA_ROOT_NAME : DATA_ROOT_NAME
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
export function getDataRootDir(homeDir: string, env: RuntimeEnv = getRuntimeEnv()) {
|
|
42
|
-
return `${homeDir}/${getDataRootName(env)}`
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
export function getDataRootDirDisplay(env: RuntimeEnv = getRuntimeEnv()) {
|
|
46
|
-
return `~/${getDataRootName(env)}`
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
export function getDataDir(homeDir: string, env: RuntimeEnv = getRuntimeEnv()) {
|
|
50
|
-
return `${getDataRootDir(homeDir, env)}/data`
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
export function getDataDirDisplay(env: RuntimeEnv = getRuntimeEnv()) {
|
|
54
|
-
return `${getDataRootDirDisplay(env)}/data`
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
export function getKeybindingsFilePath(homeDir: string, env: RuntimeEnv = getRuntimeEnv()) {
|
|
58
|
-
return `${getDataRootDir(homeDir, env)}/keybindings.json`
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
export function getKeybindingsFilePathDisplay(env: RuntimeEnv = getRuntimeEnv()) {
|
|
62
|
-
return `${getDataRootDirDisplay(env)}/keybindings.json`
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
export function getThemeSettingsFilePath(homeDir: string, env: RuntimeEnv = getRuntimeEnv()) {
|
|
66
|
-
return `${getDataRootDir(homeDir, env)}/theme.json`
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
export function getThemeSettingsFilePathDisplay(env: RuntimeEnv = getRuntimeEnv()) {
|
|
70
|
-
return `${getDataRootDirDisplay(env)}/theme.json`
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
export function getProviderSettingsFilePath(homeDir: string, env: RuntimeEnv = getRuntimeEnv()) {
|
|
74
|
-
return `${getDataRootDir(homeDir, env)}/providers.json`
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
export function getProviderSettingsFilePathDisplay(env: RuntimeEnv = getRuntimeEnv()) {
|
|
78
|
-
return `${getDataRootDirDisplay(env)}/providers.json`
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
export function getCliInvocation(arg?: string) {
|
|
82
|
-
return arg ? `${CLI_COMMAND} ${arg}` : CLI_COMMAND
|
|
83
|
-
}
|
package/src/shared/dev-ports.ts
DELETED
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
export const DEFAULT_DEV_CLIENT_PORT = 5174
|
|
2
|
-
|
|
3
|
-
export function getDefaultDevServerPort(clientPort = DEFAULT_DEV_CLIENT_PORT) {
|
|
4
|
-
return clientPort + 1
|
|
5
|
-
}
|
|
6
|
-
|
|
7
|
-
export function resolveDevPorts(args: string[]) {
|
|
8
|
-
let clientPort = DEFAULT_DEV_CLIENT_PORT
|
|
9
|
-
|
|
10
|
-
for (let index = 0; index < args.length; index += 1) {
|
|
11
|
-
const arg = args[index]
|
|
12
|
-
if (arg !== "--port") continue
|
|
13
|
-
|
|
14
|
-
const next = args[index + 1]
|
|
15
|
-
if (!next || next.startsWith("-")) {
|
|
16
|
-
throw new Error("Missing value for --port")
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
clientPort = Number(next)
|
|
20
|
-
index += 1
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
return {
|
|
24
|
-
clientPort,
|
|
25
|
-
serverPort: getDefaultDevServerPort(clientPort),
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
export function stripPortArg(args: string[]) {
|
|
30
|
-
const stripped: string[] = []
|
|
31
|
-
|
|
32
|
-
for (let index = 0; index < args.length; index += 1) {
|
|
33
|
-
const arg = args[index]
|
|
34
|
-
if (arg === "--port") {
|
|
35
|
-
index += 1
|
|
36
|
-
continue
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
stripped.push(arg)
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
return stripped
|
|
43
|
-
}
|
package/src/shared/ports.ts
DELETED
package/src/shared/protocol.ts
DELETED
|
@@ -1,156 +0,0 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
DirectoryBrowserSnapshot,
|
|
3
|
-
AgentProvider,
|
|
4
|
-
ChatUserMessage,
|
|
5
|
-
ChatSnapshot,
|
|
6
|
-
FeatureBrowserState,
|
|
7
|
-
FeatureStage,
|
|
8
|
-
KeybindingsSnapshot,
|
|
9
|
-
ProviderSettingsSnapshot,
|
|
10
|
-
LocalProjectsSnapshot,
|
|
11
|
-
ModelOptions,
|
|
12
|
-
SidebarData,
|
|
13
|
-
FeatureOverviewSnapshot,
|
|
14
|
-
ThemeSettingsSnapshot,
|
|
15
|
-
UpdateSnapshot,
|
|
16
|
-
} from "./types"
|
|
17
|
-
|
|
18
|
-
export type EditorPreset = "cursor" | "vscode" | "windsurf" | "custom"
|
|
19
|
-
|
|
20
|
-
export interface EditorOpenSettings {
|
|
21
|
-
preset: EditorPreset
|
|
22
|
-
commandTemplate: string
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
export type SubscriptionTopic =
|
|
26
|
-
| { type: "sidebar" }
|
|
27
|
-
| { type: "local-projects" }
|
|
28
|
-
| { type: "update" }
|
|
29
|
-
| { type: "keybindings" }
|
|
30
|
-
| { type: "theme-settings" }
|
|
31
|
-
| { type: "provider-settings" }
|
|
32
|
-
| { type: "chat"; chatId: string }
|
|
33
|
-
| { type: "feature-overview"; featureId: string }
|
|
34
|
-
| { type: "terminal"; terminalId: string }
|
|
35
|
-
|
|
36
|
-
export interface TerminalSnapshot {
|
|
37
|
-
terminalId: string
|
|
38
|
-
title: string
|
|
39
|
-
cwd: string
|
|
40
|
-
shell: string
|
|
41
|
-
cols: number
|
|
42
|
-
rows: number
|
|
43
|
-
scrollback: number
|
|
44
|
-
serializedState: string
|
|
45
|
-
status: "running" | "exited"
|
|
46
|
-
exitCode: number | null
|
|
47
|
-
signal?: number
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
export type TerminalEvent =
|
|
51
|
-
| { type: "terminal.output"; terminalId: string; data: string }
|
|
52
|
-
| { type: "terminal.exit"; terminalId: string; exitCode: number; signal?: number }
|
|
53
|
-
|
|
54
|
-
export type ClientCommand =
|
|
55
|
-
| { type: "project.open"; localPath: string }
|
|
56
|
-
| { type: "project.create"; localPath: string; title: string }
|
|
57
|
-
| { type: "project.remove"; projectId: string }
|
|
58
|
-
| { type: "project.setBrowserState"; projectId: string; browserState: FeatureBrowserState }
|
|
59
|
-
| { type: "project.setGeneralChatsBrowserState"; projectId: string; browserState: FeatureBrowserState }
|
|
60
|
-
| { type: "project.hide"; localPath: string }
|
|
61
|
-
| { type: "project.setProjectMetadataDirectoryCommitMode"; projectId?: string; localPath?: string; commitProjectMetadata: boolean }
|
|
62
|
-
| { type: "system.listDirectory"; localPath?: string }
|
|
63
|
-
| { type: "system.ping" }
|
|
64
|
-
| { type: "system.openUrl"; url: string }
|
|
65
|
-
| { type: "update.check"; force?: boolean }
|
|
66
|
-
| { type: "update.install" }
|
|
67
|
-
| { type: "settings.readKeybindings" }
|
|
68
|
-
| { type: "settings.writeKeybindings"; bindings: KeybindingsSnapshot["bindings"] }
|
|
69
|
-
| { type: "settings.writeThemeSettings"; settings: ThemeSettingsSnapshot["settings"] }
|
|
70
|
-
| { type: "settings.writeProviderSettings"; settings: ProviderSettingsSnapshot["settings"] }
|
|
71
|
-
| {
|
|
72
|
-
type: "system.openExternal"
|
|
73
|
-
localPath: string
|
|
74
|
-
action: "open_finder" | "open_terminal" | "open_editor"
|
|
75
|
-
line?: number
|
|
76
|
-
column?: number
|
|
77
|
-
editor?: EditorOpenSettings
|
|
78
|
-
}
|
|
79
|
-
| { type: "chat.create"; projectId: string; featureId?: string }
|
|
80
|
-
| { type: "feature.create"; projectId: string; title: string; description?: string; generateOverview?: boolean }
|
|
81
|
-
| { type: "feature.rename"; featureId: string; title: string }
|
|
82
|
-
| { type: "feature.setBrowserState"; featureId: string; browserState: FeatureBrowserState }
|
|
83
|
-
| { type: "feature.setStage"; featureId: string; stage: FeatureStage }
|
|
84
|
-
| { type: "feature.reorder"; projectId: string; orderedFeatureIds: string[] }
|
|
85
|
-
| { type: "feature.delete"; featureId: string }
|
|
86
|
-
| { type: "feature.updateOverview"; featureId: string; content: string }
|
|
87
|
-
| { type: "chat.setFeature"; chatId: string; featureId: string | null }
|
|
88
|
-
| { type: "chat.rename"; chatId: string; title: string }
|
|
89
|
-
| { type: "chat.delete"; chatId: string }
|
|
90
|
-
| {
|
|
91
|
-
type: "chat.send"
|
|
92
|
-
chatId?: string
|
|
93
|
-
projectId?: string
|
|
94
|
-
provider?: AgentProvider
|
|
95
|
-
message: ChatUserMessage
|
|
96
|
-
model?: string
|
|
97
|
-
modelOptions?: ModelOptions
|
|
98
|
-
effort?: string
|
|
99
|
-
planMode?: boolean
|
|
100
|
-
}
|
|
101
|
-
| { type: "chat.cancel"; chatId: string }
|
|
102
|
-
| { type: "chat.respondTool"; chatId: string; toolUseId: string; result: unknown }
|
|
103
|
-
| { type: "provider.refreshUsage"; provider?: AgentProvider }
|
|
104
|
-
| { type: "provider.browserLogin"; provider: AgentProvider }
|
|
105
|
-
| { type: "provider.importUsageCurl"; provider: AgentProvider; curlCommand: string }
|
|
106
|
-
| { type: "terminal.create"; projectId: string; terminalId: string; cols: number; rows: number; scrollback: number }
|
|
107
|
-
| { type: "terminal.input"; terminalId: string; data: string }
|
|
108
|
-
| { type: "terminal.resize"; terminalId: string; cols: number; rows: number }
|
|
109
|
-
| { type: "terminal.close"; terminalId: string }
|
|
110
|
-
| { type: "git.getBranches"; projectId: string }
|
|
111
|
-
| { type: "git.switchBranch"; projectId: string; branchName: string }
|
|
112
|
-
| { type: "git.createBranch"; projectId: string; branchName: string; checkout: boolean }
|
|
113
|
-
|
|
114
|
-
export type ClientEnvelope =
|
|
115
|
-
| { v: 1; type: "subscribe"; id: string; topic: SubscriptionTopic }
|
|
116
|
-
| { v: 1; type: "unsubscribe"; id: string }
|
|
117
|
-
| { v: 1; type: "command"; id: string; command: ClientCommand }
|
|
118
|
-
|
|
119
|
-
export type ServerSnapshot =
|
|
120
|
-
| { type: "sidebar"; data: SidebarData }
|
|
121
|
-
| { type: "local-projects"; data: LocalProjectsSnapshot }
|
|
122
|
-
| { type: "update"; data: UpdateSnapshot }
|
|
123
|
-
| { type: "keybindings"; data: KeybindingsSnapshot }
|
|
124
|
-
| { type: "theme-settings"; data: ThemeSettingsSnapshot }
|
|
125
|
-
| { type: "provider-settings"; data: ProviderSettingsSnapshot }
|
|
126
|
-
| { type: "chat"; data: ChatSnapshot | null }
|
|
127
|
-
| { type: "feature-overview"; data: FeatureOverviewSnapshot | null }
|
|
128
|
-
| { type: "terminal"; data: TerminalSnapshot | null }
|
|
129
|
-
|
|
130
|
-
export type ServerEnvelope =
|
|
131
|
-
| { v: 1; type: "snapshot"; id: string; snapshot: ServerSnapshot }
|
|
132
|
-
| { v: 1; type: "event"; id: string; event: TerminalEvent }
|
|
133
|
-
| { v: 1; type: "ack"; id: string; result?: unknown }
|
|
134
|
-
| { v: 1; type: "error"; id?: string; message: string }
|
|
135
|
-
|
|
136
|
-
export interface GitBranchesResult {
|
|
137
|
-
isRepo: boolean
|
|
138
|
-
currentBranch: string | null
|
|
139
|
-
branches: string[]
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
export interface GitSwitchBranchResult {
|
|
143
|
-
currentBranch: string
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
export interface GitCreateBranchResult {
|
|
147
|
-
currentBranch: string
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
export interface DirectoryListResult extends DirectoryBrowserSnapshot {}
|
|
151
|
-
|
|
152
|
-
export function isClientEnvelope(value: unknown): value is ClientEnvelope {
|
|
153
|
-
if (!value || typeof value !== "object") return false
|
|
154
|
-
const candidate = value as Partial<ClientEnvelope>
|
|
155
|
-
return candidate.v === 1 && typeof candidate.type === "string"
|
|
156
|
-
}
|
package/src/shared/tools.ts
DELETED
|
@@ -1,251 +0,0 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
AskUserQuestionItem,
|
|
3
|
-
AskUserQuestionAnswerMap,
|
|
4
|
-
AskUserQuestionToolResult,
|
|
5
|
-
ExitPlanModeToolResult,
|
|
6
|
-
HydratedToolCall,
|
|
7
|
-
NormalizedToolCall,
|
|
8
|
-
ReadFileToolResult,
|
|
9
|
-
TodoItem,
|
|
10
|
-
} from "./types"
|
|
11
|
-
|
|
12
|
-
function asRecord(value: unknown): Record<string, unknown> | null {
|
|
13
|
-
if (!value || typeof value !== "object" || Array.isArray(value)) return null
|
|
14
|
-
return value as Record<string, unknown>
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
export function normalizeToolCall(args: {
|
|
18
|
-
toolName: string
|
|
19
|
-
toolId: string
|
|
20
|
-
input: Record<string, unknown>
|
|
21
|
-
}): NormalizedToolCall {
|
|
22
|
-
const { toolName, toolId, input } = args
|
|
23
|
-
|
|
24
|
-
switch (toolName) {
|
|
25
|
-
case "AskUserQuestion":
|
|
26
|
-
return {
|
|
27
|
-
kind: "tool",
|
|
28
|
-
toolKind: "ask_user_question",
|
|
29
|
-
toolName,
|
|
30
|
-
toolId,
|
|
31
|
-
input: {
|
|
32
|
-
questions: Array.isArray(input.questions) ? (input.questions as AskUserQuestionItem[]) : [],
|
|
33
|
-
},
|
|
34
|
-
rawInput: input,
|
|
35
|
-
}
|
|
36
|
-
case "ExitPlanMode":
|
|
37
|
-
return {
|
|
38
|
-
kind: "tool",
|
|
39
|
-
toolKind: "exit_plan_mode",
|
|
40
|
-
toolName,
|
|
41
|
-
toolId,
|
|
42
|
-
input: {
|
|
43
|
-
plan: typeof input.plan === "string" ? input.plan : undefined,
|
|
44
|
-
summary: typeof input.summary === "string" ? input.summary : undefined,
|
|
45
|
-
},
|
|
46
|
-
rawInput: input,
|
|
47
|
-
}
|
|
48
|
-
case "TodoWrite":
|
|
49
|
-
return {
|
|
50
|
-
kind: "tool",
|
|
51
|
-
toolKind: "todo_write",
|
|
52
|
-
toolName,
|
|
53
|
-
toolId,
|
|
54
|
-
input: {
|
|
55
|
-
todos: Array.isArray(input.todos) ? (input.todos as TodoItem[]) : [],
|
|
56
|
-
},
|
|
57
|
-
rawInput: input,
|
|
58
|
-
}
|
|
59
|
-
case "Skill":
|
|
60
|
-
return {
|
|
61
|
-
kind: "tool",
|
|
62
|
-
toolKind: "skill",
|
|
63
|
-
toolName,
|
|
64
|
-
toolId,
|
|
65
|
-
input: {
|
|
66
|
-
skill: typeof input.skill === "string" ? input.skill : "",
|
|
67
|
-
},
|
|
68
|
-
rawInput: input,
|
|
69
|
-
}
|
|
70
|
-
case "Glob":
|
|
71
|
-
return {
|
|
72
|
-
kind: "tool",
|
|
73
|
-
toolKind: "glob",
|
|
74
|
-
toolName,
|
|
75
|
-
toolId,
|
|
76
|
-
input: {
|
|
77
|
-
pattern: typeof input.pattern === "string" ? input.pattern : "",
|
|
78
|
-
},
|
|
79
|
-
rawInput: input,
|
|
80
|
-
}
|
|
81
|
-
case "Grep":
|
|
82
|
-
return {
|
|
83
|
-
kind: "tool",
|
|
84
|
-
toolKind: "grep",
|
|
85
|
-
toolName,
|
|
86
|
-
toolId,
|
|
87
|
-
input: {
|
|
88
|
-
pattern: typeof input.pattern === "string" ? input.pattern : "",
|
|
89
|
-
outputMode: typeof input.output_mode === "string" ? input.output_mode : undefined,
|
|
90
|
-
},
|
|
91
|
-
rawInput: input,
|
|
92
|
-
}
|
|
93
|
-
case "Bash":
|
|
94
|
-
return {
|
|
95
|
-
kind: "tool",
|
|
96
|
-
toolKind: "bash",
|
|
97
|
-
toolName,
|
|
98
|
-
toolId,
|
|
99
|
-
input: {
|
|
100
|
-
command: typeof input.command === "string" ? input.command : "",
|
|
101
|
-
description: typeof input.description === "string" ? input.description : undefined,
|
|
102
|
-
timeoutMs: typeof input.timeout === "number" ? input.timeout : undefined,
|
|
103
|
-
runInBackground: Boolean(input.run_in_background),
|
|
104
|
-
},
|
|
105
|
-
rawInput: input,
|
|
106
|
-
}
|
|
107
|
-
case "WebSearch":
|
|
108
|
-
return {
|
|
109
|
-
kind: "tool",
|
|
110
|
-
toolKind: "web_search",
|
|
111
|
-
toolName,
|
|
112
|
-
toolId,
|
|
113
|
-
input: {
|
|
114
|
-
query: typeof input.query === "string" ? input.query : "",
|
|
115
|
-
},
|
|
116
|
-
rawInput: input,
|
|
117
|
-
}
|
|
118
|
-
case "Read":
|
|
119
|
-
return {
|
|
120
|
-
kind: "tool",
|
|
121
|
-
toolKind: "read_file",
|
|
122
|
-
toolName,
|
|
123
|
-
toolId,
|
|
124
|
-
input: {
|
|
125
|
-
filePath: typeof input.file_path === "string" ? input.file_path : "",
|
|
126
|
-
},
|
|
127
|
-
rawInput: input,
|
|
128
|
-
}
|
|
129
|
-
case "Write":
|
|
130
|
-
return {
|
|
131
|
-
kind: "tool",
|
|
132
|
-
toolKind: "write_file",
|
|
133
|
-
toolName,
|
|
134
|
-
toolId,
|
|
135
|
-
input: {
|
|
136
|
-
filePath: typeof input.file_path === "string" ? input.file_path : "",
|
|
137
|
-
content: typeof input.content === "string" ? input.content : "",
|
|
138
|
-
},
|
|
139
|
-
rawInput: input,
|
|
140
|
-
}
|
|
141
|
-
case "Edit":
|
|
142
|
-
return {
|
|
143
|
-
kind: "tool",
|
|
144
|
-
toolKind: "edit_file",
|
|
145
|
-
toolName,
|
|
146
|
-
toolId,
|
|
147
|
-
input: {
|
|
148
|
-
filePath: typeof input.file_path === "string" ? input.file_path : "",
|
|
149
|
-
oldString: typeof input.old_string === "string" ? input.old_string : "",
|
|
150
|
-
newString: typeof input.new_string === "string" ? input.new_string : "",
|
|
151
|
-
},
|
|
152
|
-
rawInput: input,
|
|
153
|
-
}
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
const mcpMatch = toolName.match(/^mcp__(.+?)__(.+)$/)
|
|
157
|
-
if (mcpMatch) {
|
|
158
|
-
return {
|
|
159
|
-
kind: "tool",
|
|
160
|
-
toolKind: "mcp_generic",
|
|
161
|
-
toolName,
|
|
162
|
-
toolId,
|
|
163
|
-
input: {
|
|
164
|
-
server: mcpMatch[1],
|
|
165
|
-
tool: mcpMatch[2],
|
|
166
|
-
payload: input,
|
|
167
|
-
},
|
|
168
|
-
rawInput: input,
|
|
169
|
-
}
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
if (typeof input.subagent_type === "string") {
|
|
173
|
-
return {
|
|
174
|
-
kind: "tool",
|
|
175
|
-
toolKind: "subagent_task",
|
|
176
|
-
toolName,
|
|
177
|
-
toolId,
|
|
178
|
-
input: {
|
|
179
|
-
subagentType: input.subagent_type,
|
|
180
|
-
},
|
|
181
|
-
rawInput: input,
|
|
182
|
-
}
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
return {
|
|
186
|
-
kind: "tool",
|
|
187
|
-
toolKind: "unknown_tool",
|
|
188
|
-
toolName,
|
|
189
|
-
toolId,
|
|
190
|
-
input: {
|
|
191
|
-
payload: input,
|
|
192
|
-
},
|
|
193
|
-
rawInput: input,
|
|
194
|
-
}
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
function parseJsonValue(value: unknown): unknown {
|
|
198
|
-
if (typeof value !== "string") return value
|
|
199
|
-
try {
|
|
200
|
-
return JSON.parse(value)
|
|
201
|
-
} catch {
|
|
202
|
-
return value
|
|
203
|
-
}
|
|
204
|
-
}
|
|
205
|
-
|
|
206
|
-
export function hydrateToolResult(tool: NormalizedToolCall, raw: unknown): HydratedToolCall["result"] {
|
|
207
|
-
const parsed = parseJsonValue(raw)
|
|
208
|
-
|
|
209
|
-
switch (tool.toolKind) {
|
|
210
|
-
case "ask_user_question": {
|
|
211
|
-
const record = asRecord(parsed)
|
|
212
|
-
const answers = asRecord(record?.answers) ?? (record ? record : {})
|
|
213
|
-
return {
|
|
214
|
-
answers: Object.fromEntries(
|
|
215
|
-
Object.entries(answers).map(([key, value]) => {
|
|
216
|
-
if (Array.isArray(value)) {
|
|
217
|
-
return [key, value.map((entry) => String(entry))]
|
|
218
|
-
}
|
|
219
|
-
if (value && typeof value === "object" && Array.isArray((value as { answers?: unknown }).answers)) {
|
|
220
|
-
return [key, (value as { answers: unknown[] }).answers.map((entry) => String(entry))]
|
|
221
|
-
}
|
|
222
|
-
if (value == null || value === "") {
|
|
223
|
-
return [key, []]
|
|
224
|
-
}
|
|
225
|
-
return [key, [String(value)]]
|
|
226
|
-
})
|
|
227
|
-
) as AskUserQuestionAnswerMap,
|
|
228
|
-
...(record?.discarded === true ? { discarded: true } : {}),
|
|
229
|
-
} satisfies AskUserQuestionToolResult
|
|
230
|
-
}
|
|
231
|
-
case "exit_plan_mode": {
|
|
232
|
-
const record = asRecord(parsed)
|
|
233
|
-
return {
|
|
234
|
-
confirmed: typeof record?.confirmed === "boolean" ? record.confirmed : undefined,
|
|
235
|
-
clearContext: typeof record?.clearContext === "boolean" ? record.clearContext : undefined,
|
|
236
|
-
message: typeof record?.message === "string" ? record.message : undefined,
|
|
237
|
-
...(record?.discarded === true ? { discarded: true } : {}),
|
|
238
|
-
} satisfies ExitPlanModeToolResult
|
|
239
|
-
}
|
|
240
|
-
case "read_file":
|
|
241
|
-
if (typeof parsed === "string") {
|
|
242
|
-
return parsed
|
|
243
|
-
}
|
|
244
|
-
const record = asRecord(parsed)
|
|
245
|
-
return {
|
|
246
|
-
content: typeof record?.content === "string" ? record.content : JSON.stringify(parsed, null, 2),
|
|
247
|
-
} satisfies ReadFileToolResult
|
|
248
|
-
default:
|
|
249
|
-
return parsed
|
|
250
|
-
}
|
|
251
|
-
}
|