kanna-code 0.9.1 → 0.11.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/dist/client/assets/index-BBq_6S76.js +503 -0
- package/dist/client/assets/index-C6-Y890P.css +32 -0
- package/dist/client/index.html +2 -2
- package/package.json +2 -2
- package/src/server/cli-runtime.test.ts +21 -1
- package/src/server/cli-runtime.ts +4 -0
- package/src/server/event-store.test.ts +22 -0
- package/src/server/event-store.ts +52 -44
- package/src/server/keybindings.test.ts +132 -0
- package/src/server/keybindings.ts +175 -0
- package/src/server/server.ts +5 -6
- package/src/server/ws-router.test.ts +107 -63
- package/src/server/ws-router.ts +22 -35
- package/src/shared/branding.test.ts +31 -0
- package/src/shared/branding.ts +41 -6
- package/src/shared/protocol.ts +6 -20
- package/src/shared/types.ts +30 -33
- package/dist/client/assets/index-Yjf7kxJf.js +0 -533
- package/dist/client/assets/index-gEOLdGK-.css +0 -32
- package/src/server/file-tree-manager.test.ts +0 -116
- package/src/server/file-tree-manager.ts +0 -372
package/src/server/ws-router.ts
CHANGED
|
@@ -6,7 +6,7 @@ import type { AgentCoordinator } from "./agent"
|
|
|
6
6
|
import type { DiscoveredProject } from "./discovery"
|
|
7
7
|
import { EventStore } from "./event-store"
|
|
8
8
|
import { openExternal } from "./external-open"
|
|
9
|
-
import {
|
|
9
|
+
import { KeybindingsManager } from "./keybindings"
|
|
10
10
|
import { ensureProjectDirectory } from "./paths"
|
|
11
11
|
import { TerminalManager } from "./terminal-manager"
|
|
12
12
|
import { deriveChatSnapshot, deriveLocalProjectsSnapshot, deriveSidebarData } from "./read-models"
|
|
@@ -19,7 +19,7 @@ interface CreateWsRouterArgs {
|
|
|
19
19
|
store: EventStore
|
|
20
20
|
agent: AgentCoordinator
|
|
21
21
|
terminals: TerminalManager
|
|
22
|
-
|
|
22
|
+
keybindings: KeybindingsManager
|
|
23
23
|
refreshDiscovery: () => Promise<DiscoveredProject[]>
|
|
24
24
|
getDiscoveredProjects: () => DiscoveredProject[]
|
|
25
25
|
machineDisplayName: string
|
|
@@ -33,7 +33,7 @@ export function createWsRouter({
|
|
|
33
33
|
store,
|
|
34
34
|
agent,
|
|
35
35
|
terminals,
|
|
36
|
-
|
|
36
|
+
keybindings,
|
|
37
37
|
refreshDiscovery,
|
|
38
38
|
getDiscoveredProjects,
|
|
39
39
|
machineDisplayName,
|
|
@@ -68,26 +68,26 @@ export function createWsRouter({
|
|
|
68
68
|
}
|
|
69
69
|
}
|
|
70
70
|
|
|
71
|
-
if (topic.type === "
|
|
71
|
+
if (topic.type === "keybindings") {
|
|
72
72
|
return {
|
|
73
73
|
v: PROTOCOL_VERSION,
|
|
74
74
|
type: "snapshot",
|
|
75
75
|
id,
|
|
76
76
|
snapshot: {
|
|
77
|
-
type: "
|
|
78
|
-
data:
|
|
77
|
+
type: "keybindings",
|
|
78
|
+
data: keybindings.getSnapshot(),
|
|
79
79
|
},
|
|
80
80
|
}
|
|
81
81
|
}
|
|
82
82
|
|
|
83
|
-
if (topic.type === "
|
|
83
|
+
if (topic.type === "terminal") {
|
|
84
84
|
return {
|
|
85
85
|
v: PROTOCOL_VERSION,
|
|
86
86
|
type: "snapshot",
|
|
87
87
|
id,
|
|
88
88
|
snapshot: {
|
|
89
|
-
type: "
|
|
90
|
-
data:
|
|
89
|
+
type: "terminal",
|
|
90
|
+
data: terminals.getSnapshot(topic.terminalId),
|
|
91
91
|
},
|
|
92
92
|
}
|
|
93
93
|
}
|
|
@@ -142,16 +142,11 @@ export function createWsRouter({
|
|
|
142
142
|
pushTerminalEvent(event.terminalId, event)
|
|
143
143
|
})
|
|
144
144
|
|
|
145
|
-
const
|
|
145
|
+
const disposeKeybindingEvents = keybindings.onChange(() => {
|
|
146
146
|
for (const ws of sockets) {
|
|
147
147
|
for (const [id, topic] of ws.data.subscriptions.entries()) {
|
|
148
|
-
if (topic.type !== "
|
|
149
|
-
send(ws,
|
|
150
|
-
v: PROTOCOL_VERSION,
|
|
151
|
-
type: "event",
|
|
152
|
-
id,
|
|
153
|
-
event,
|
|
154
|
-
})
|
|
148
|
+
if (topic.type !== "keybindings") continue
|
|
149
|
+
send(ws, createEnvelope(id, topic))
|
|
155
150
|
}
|
|
156
151
|
}
|
|
157
152
|
})
|
|
@@ -164,6 +159,15 @@ export function createWsRouter({
|
|
|
164
159
|
send(ws, { v: PROTOCOL_VERSION, type: "ack", id })
|
|
165
160
|
return
|
|
166
161
|
}
|
|
162
|
+
case "settings.readKeybindings": {
|
|
163
|
+
send(ws, { v: PROTOCOL_VERSION, type: "ack", id, result: keybindings.getSnapshot() })
|
|
164
|
+
return
|
|
165
|
+
}
|
|
166
|
+
case "settings.writeKeybindings": {
|
|
167
|
+
const snapshot = await keybindings.write(command.bindings)
|
|
168
|
+
send(ws, { v: PROTOCOL_VERSION, type: "ack", id, result: snapshot })
|
|
169
|
+
return
|
|
170
|
+
}
|
|
167
171
|
case "project.open": {
|
|
168
172
|
await ensureProjectDirectory(command.localPath)
|
|
169
173
|
const project = await store.openProject(command.localPath)
|
|
@@ -257,11 +261,6 @@ export function createWsRouter({
|
|
|
257
261
|
pushTerminalSnapshot(command.terminalId)
|
|
258
262
|
return
|
|
259
263
|
}
|
|
260
|
-
case "file-tree.readDirectory": {
|
|
261
|
-
const result = await fileTree.readDirectory(command)
|
|
262
|
-
send(ws, { v: PROTOCOL_VERSION, type: "ack", id, result })
|
|
263
|
-
return
|
|
264
|
-
}
|
|
265
264
|
}
|
|
266
265
|
|
|
267
266
|
broadcastSnapshots()
|
|
@@ -276,11 +275,6 @@ export function createWsRouter({
|
|
|
276
275
|
sockets.add(ws)
|
|
277
276
|
},
|
|
278
277
|
handleClose(ws: ServerWebSocket<ClientState>) {
|
|
279
|
-
for (const topic of ws.data.subscriptions.values()) {
|
|
280
|
-
if (topic.type === "file-tree") {
|
|
281
|
-
fileTree.unsubscribe(topic.projectId)
|
|
282
|
-
}
|
|
283
|
-
}
|
|
284
278
|
sockets.delete(ws)
|
|
285
279
|
},
|
|
286
280
|
broadcastSnapshots,
|
|
@@ -300,9 +294,6 @@ export function createWsRouter({
|
|
|
300
294
|
|
|
301
295
|
if (parsed.type === "subscribe") {
|
|
302
296
|
ws.data.subscriptions.set(parsed.id, parsed.topic)
|
|
303
|
-
if (parsed.topic.type === "file-tree") {
|
|
304
|
-
fileTree.subscribe(parsed.topic.projectId)
|
|
305
|
-
}
|
|
306
297
|
if (parsed.topic.type === "local-projects") {
|
|
307
298
|
void refreshDiscovery().then(() => {
|
|
308
299
|
if (ws.data.subscriptions.has(parsed.id)) {
|
|
@@ -315,11 +306,7 @@ export function createWsRouter({
|
|
|
315
306
|
}
|
|
316
307
|
|
|
317
308
|
if (parsed.type === "unsubscribe") {
|
|
318
|
-
const topic = ws.data.subscriptions.get(parsed.id)
|
|
319
309
|
ws.data.subscriptions.delete(parsed.id)
|
|
320
|
-
if (topic?.type === "file-tree") {
|
|
321
|
-
fileTree.unsubscribe(topic.projectId)
|
|
322
|
-
}
|
|
323
310
|
send(ws, { v: PROTOCOL_VERSION, type: "ack", id: parsed.id })
|
|
324
311
|
return
|
|
325
312
|
}
|
|
@@ -328,7 +315,7 @@ export function createWsRouter({
|
|
|
328
315
|
},
|
|
329
316
|
dispose() {
|
|
330
317
|
disposeTerminalEvents()
|
|
331
|
-
|
|
318
|
+
disposeKeybindingEvents()
|
|
332
319
|
},
|
|
333
320
|
}
|
|
334
321
|
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { describe, expect, test } from "bun:test"
|
|
2
|
+
import {
|
|
3
|
+
getDataDir,
|
|
4
|
+
getDataDirDisplay,
|
|
5
|
+
getDataRootName,
|
|
6
|
+
getKeybindingsFilePath,
|
|
7
|
+
getKeybindingsFilePathDisplay,
|
|
8
|
+
getRuntimeProfile,
|
|
9
|
+
} from "./branding"
|
|
10
|
+
|
|
11
|
+
describe("runtime profile helpers", () => {
|
|
12
|
+
test("defaults to the prod profile when unset", () => {
|
|
13
|
+
expect(getRuntimeProfile({})).toBe("prod")
|
|
14
|
+
expect(getDataRootName({})).toBe(".kanna")
|
|
15
|
+
expect(getDataDir("/tmp/home", {})).toBe("/tmp/home/.kanna/data")
|
|
16
|
+
expect(getDataDirDisplay({})).toBe("~/.kanna/data")
|
|
17
|
+
expect(getKeybindingsFilePath("/tmp/home", {})).toBe("/tmp/home/.kanna/keybindings.json")
|
|
18
|
+
expect(getKeybindingsFilePathDisplay({})).toBe("~/.kanna/keybindings.json")
|
|
19
|
+
})
|
|
20
|
+
|
|
21
|
+
test("switches to dev paths for the dev profile", () => {
|
|
22
|
+
const env = { KANNA_RUNTIME_PROFILE: "dev" }
|
|
23
|
+
|
|
24
|
+
expect(getRuntimeProfile(env)).toBe("dev")
|
|
25
|
+
expect(getDataRootName(env)).toBe(".kanna-dev")
|
|
26
|
+
expect(getDataDir("/tmp/home", env)).toBe("/tmp/home/.kanna-dev/data")
|
|
27
|
+
expect(getDataDirDisplay(env)).toBe("~/.kanna-dev/data")
|
|
28
|
+
expect(getKeybindingsFilePath("/tmp/home", env)).toBe("/tmp/home/.kanna-dev/keybindings.json")
|
|
29
|
+
expect(getKeybindingsFilePathDisplay(env)).toBe("~/.kanna-dev/keybindings.json")
|
|
30
|
+
})
|
|
31
|
+
})
|
package/src/shared/branding.ts
CHANGED
|
@@ -1,23 +1,58 @@
|
|
|
1
1
|
export const APP_NAME = "Kanna"
|
|
2
2
|
export const CLI_COMMAND = "kanna"
|
|
3
3
|
export const DATA_ROOT_NAME = ".kanna"
|
|
4
|
+
export const DEV_DATA_ROOT_NAME = ".kanna-dev"
|
|
4
5
|
export const PACKAGE_NAME = "kanna-code"
|
|
6
|
+
export const RUNTIME_PROFILE_ENV_VAR = "KANNA_RUNTIME_PROFILE"
|
|
5
7
|
// Read version from package.json — JSON import works in both Bun and Vite
|
|
6
8
|
import pkg from "../../package.json"
|
|
7
9
|
export const SDK_CLIENT_APP = `kanna/${pkg.version}`
|
|
8
10
|
export const LOG_PREFIX = "[kanna]"
|
|
9
11
|
export const DEFAULT_NEW_PROJECT_ROOT = `~/${APP_NAME}`
|
|
10
12
|
|
|
11
|
-
export
|
|
12
|
-
|
|
13
|
+
export type RuntimeProfile = "dev" | "prod"
|
|
14
|
+
|
|
15
|
+
type RuntimeEnv = Record<string, string | undefined> | undefined
|
|
16
|
+
|
|
17
|
+
function getRuntimeEnv(): RuntimeEnv {
|
|
18
|
+
const candidate = globalThis as typeof globalThis & {
|
|
19
|
+
process?: {
|
|
20
|
+
env?: Record<string, string | undefined>
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
return candidate.process?.env
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export function getRuntimeProfile(env: RuntimeEnv = getRuntimeEnv()): RuntimeProfile {
|
|
27
|
+
return env?.[RUNTIME_PROFILE_ENV_VAR]?.trim().toLowerCase() === "dev" ? "dev" : "prod"
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export function getDataRootName(env: RuntimeEnv = getRuntimeEnv()) {
|
|
31
|
+
return getRuntimeProfile(env) === "dev" ? DEV_DATA_ROOT_NAME : DATA_ROOT_NAME
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export function getDataRootDir(homeDir: string, env: RuntimeEnv = getRuntimeEnv()) {
|
|
35
|
+
return `${homeDir}/${getDataRootName(env)}`
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export function getDataRootDirDisplay(env: RuntimeEnv = getRuntimeEnv()) {
|
|
39
|
+
return `~/${getDataRootName(env)}`
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export function getDataDir(homeDir: string, env: RuntimeEnv = getRuntimeEnv()) {
|
|
43
|
+
return `${getDataRootDir(homeDir, env)}/data`
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export function getDataDirDisplay(env: RuntimeEnv = getRuntimeEnv()) {
|
|
47
|
+
return `${getDataRootDirDisplay(env)}/data`
|
|
13
48
|
}
|
|
14
49
|
|
|
15
|
-
export function
|
|
16
|
-
return `${homeDir}
|
|
50
|
+
export function getKeybindingsFilePath(homeDir: string, env: RuntimeEnv = getRuntimeEnv()) {
|
|
51
|
+
return `${getDataRootDir(homeDir, env)}/keybindings.json`
|
|
17
52
|
}
|
|
18
53
|
|
|
19
|
-
export function
|
|
20
|
-
return
|
|
54
|
+
export function getKeybindingsFilePathDisplay(env: RuntimeEnv = getRuntimeEnv()) {
|
|
55
|
+
return `${getDataRootDirDisplay(env)}/keybindings.json`
|
|
21
56
|
}
|
|
22
57
|
|
|
23
58
|
export function getCliInvocation(arg?: string) {
|
package/src/shared/protocol.ts
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import type {
|
|
2
2
|
AgentProvider,
|
|
3
3
|
ChatSnapshot,
|
|
4
|
-
|
|
5
|
-
FileTreeSnapshot,
|
|
4
|
+
KeybindingsSnapshot,
|
|
6
5
|
LocalProjectsSnapshot,
|
|
7
6
|
ModelOptions,
|
|
8
7
|
SidebarData,
|
|
@@ -18,7 +17,7 @@ export interface EditorOpenSettings {
|
|
|
18
17
|
export type SubscriptionTopic =
|
|
19
18
|
| { type: "sidebar" }
|
|
20
19
|
| { type: "local-projects" }
|
|
21
|
-
| { type: "
|
|
20
|
+
| { type: "keybindings" }
|
|
22
21
|
| { type: "chat"; chatId: string }
|
|
23
22
|
| { type: "terminal"; terminalId: string }
|
|
24
23
|
|
|
@@ -45,6 +44,8 @@ export type ClientCommand =
|
|
|
45
44
|
| { type: "project.create"; localPath: string; title: string }
|
|
46
45
|
| { type: "project.remove"; projectId: string }
|
|
47
46
|
| { type: "system.ping" }
|
|
47
|
+
| { type: "settings.readKeybindings" }
|
|
48
|
+
| { type: "settings.writeKeybindings"; bindings: KeybindingsSnapshot["bindings"] }
|
|
48
49
|
| {
|
|
49
50
|
type: "system.openExternal"
|
|
50
51
|
localPath: string
|
|
@@ -73,13 +74,6 @@ export type ClientCommand =
|
|
|
73
74
|
| { type: "terminal.input"; terminalId: string; data: string }
|
|
74
75
|
| { type: "terminal.resize"; terminalId: string; cols: number; rows: number }
|
|
75
76
|
| { type: "terminal.close"; terminalId: string }
|
|
76
|
-
| {
|
|
77
|
-
type: "file-tree.readDirectory"
|
|
78
|
-
projectId: string
|
|
79
|
-
directoryPath: string
|
|
80
|
-
cursor?: string
|
|
81
|
-
limit?: number
|
|
82
|
-
}
|
|
83
77
|
|
|
84
78
|
export type ClientEnvelope =
|
|
85
79
|
| { v: 1; type: "subscribe"; id: string; topic: SubscriptionTopic }
|
|
@@ -89,24 +83,16 @@ export type ClientEnvelope =
|
|
|
89
83
|
export type ServerSnapshot =
|
|
90
84
|
| { type: "sidebar"; data: SidebarData }
|
|
91
85
|
| { type: "local-projects"; data: LocalProjectsSnapshot }
|
|
92
|
-
| { type: "
|
|
86
|
+
| { type: "keybindings"; data: KeybindingsSnapshot }
|
|
93
87
|
| { type: "chat"; data: ChatSnapshot | null }
|
|
94
88
|
| { type: "terminal"; data: TerminalSnapshot | null }
|
|
95
89
|
|
|
96
|
-
export type FileTreeEvent = {
|
|
97
|
-
type: "file-tree.invalidate"
|
|
98
|
-
projectId: string
|
|
99
|
-
directoryPaths: string[]
|
|
100
|
-
}
|
|
101
|
-
|
|
102
90
|
export type ServerEnvelope =
|
|
103
91
|
| { v: 1; type: "snapshot"; id: string; snapshot: ServerSnapshot }
|
|
104
|
-
| { v: 1; type: "event"; id: string; event: TerminalEvent
|
|
92
|
+
| { v: 1; type: "event"; id: string; event: TerminalEvent }
|
|
105
93
|
| { v: 1; type: "ack"; id: string; result?: unknown }
|
|
106
94
|
| { v: 1; type: "error"; id?: string; message: string }
|
|
107
95
|
|
|
108
|
-
export type FileTreeReadDirectoryResult = FileTreeDirectoryPage
|
|
109
|
-
|
|
110
96
|
export function isClientEnvelope(value: unknown): value is ClientEnvelope {
|
|
111
97
|
if (!value || typeof value !== "object") return false
|
|
112
98
|
const candidate = value as Partial<ClientEnvelope>
|
package/src/shared/types.ts
CHANGED
|
@@ -167,28 +167,25 @@ export interface LocalProjectsSnapshot {
|
|
|
167
167
|
projects: LocalProjectSummary[]
|
|
168
168
|
}
|
|
169
169
|
|
|
170
|
-
export type
|
|
170
|
+
export type KeybindingAction =
|
|
171
|
+
| "toggleEmbeddedTerminal"
|
|
172
|
+
| "toggleRightSidebar"
|
|
173
|
+
| "openInFinder"
|
|
174
|
+
| "openInEditor"
|
|
175
|
+
| "addSplitTerminal"
|
|
171
176
|
|
|
172
|
-
export
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
+
export const DEFAULT_KEYBINDINGS: Record<KeybindingAction, string[]> = {
|
|
178
|
+
toggleEmbeddedTerminal: ["cmd+j", "ctrl+`"],
|
|
179
|
+
toggleRightSidebar: ["cmd+b", "ctrl+b"],
|
|
180
|
+
openInFinder: ["cmd+alt+f", "ctrl+alt+f"],
|
|
181
|
+
openInEditor: ["cmd+shift+o", "ctrl+shift+o"],
|
|
182
|
+
addSplitTerminal: ["cmd+/", "ctrl+/"],
|
|
177
183
|
}
|
|
178
184
|
|
|
179
|
-
export interface
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
hasMore: boolean
|
|
184
|
-
error?: string
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
export interface FileTreeSnapshot {
|
|
188
|
-
projectId: string
|
|
189
|
-
rootPath: string
|
|
190
|
-
pageSize: number
|
|
191
|
-
supportsRealtime: true
|
|
185
|
+
export interface KeybindingsSnapshot {
|
|
186
|
+
bindings: Record<KeybindingAction, string[]>
|
|
187
|
+
warning: string | null
|
|
188
|
+
filePathDisplay: string
|
|
192
189
|
}
|
|
193
190
|
|
|
194
191
|
export interface McpServerInfo {
|
|
@@ -244,46 +241,46 @@ interface ToolCallBase<TKind extends string, TInput> {
|
|
|
244
241
|
}
|
|
245
242
|
|
|
246
243
|
export interface AskUserQuestionToolCall
|
|
247
|
-
extends ToolCallBase<"ask_user_question", { questions: AskUserQuestionItem[] }> {}
|
|
244
|
+
extends ToolCallBase<"ask_user_question", { questions: AskUserQuestionItem[] }> { }
|
|
248
245
|
|
|
249
246
|
export interface ExitPlanModeToolCall
|
|
250
|
-
extends ToolCallBase<"exit_plan_mode", { plan?: string; summary?: string }> {}
|
|
247
|
+
extends ToolCallBase<"exit_plan_mode", { plan?: string; summary?: string }> { }
|
|
251
248
|
|
|
252
249
|
export interface TodoWriteToolCall
|
|
253
|
-
extends ToolCallBase<"todo_write", { todos: TodoItem[] }> {}
|
|
250
|
+
extends ToolCallBase<"todo_write", { todos: TodoItem[] }> { }
|
|
254
251
|
|
|
255
252
|
export interface SkillToolCall
|
|
256
|
-
extends ToolCallBase<"skill", { skill: string }> {}
|
|
253
|
+
extends ToolCallBase<"skill", { skill: string }> { }
|
|
257
254
|
|
|
258
255
|
export interface GlobToolCall
|
|
259
|
-
extends ToolCallBase<"glob", { pattern: string }> {}
|
|
256
|
+
extends ToolCallBase<"glob", { pattern: string }> { }
|
|
260
257
|
|
|
261
258
|
export interface GrepToolCall
|
|
262
|
-
extends ToolCallBase<"grep", { pattern: string; outputMode?: string }> {}
|
|
259
|
+
extends ToolCallBase<"grep", { pattern: string; outputMode?: string }> { }
|
|
263
260
|
|
|
264
261
|
export interface BashToolCall
|
|
265
|
-
extends ToolCallBase<"bash", { command: string; description?: string; timeoutMs?: number; runInBackground?: boolean }> {}
|
|
262
|
+
extends ToolCallBase<"bash", { command: string; description?: string; timeoutMs?: number; runInBackground?: boolean }> { }
|
|
266
263
|
|
|
267
264
|
export interface WebSearchToolCall
|
|
268
|
-
extends ToolCallBase<"web_search", { query: string }> {}
|
|
265
|
+
extends ToolCallBase<"web_search", { query: string }> { }
|
|
269
266
|
|
|
270
267
|
export interface ReadFileToolCall
|
|
271
|
-
extends ToolCallBase<"read_file", { filePath: string }> {}
|
|
268
|
+
extends ToolCallBase<"read_file", { filePath: string }> { }
|
|
272
269
|
|
|
273
270
|
export interface WriteFileToolCall
|
|
274
|
-
extends ToolCallBase<"write_file", { filePath: string; content: string }> {}
|
|
271
|
+
extends ToolCallBase<"write_file", { filePath: string; content: string }> { }
|
|
275
272
|
|
|
276
273
|
export interface EditFileToolCall
|
|
277
|
-
extends ToolCallBase<"edit_file", { filePath: string; oldString: string; newString: string }> {}
|
|
274
|
+
extends ToolCallBase<"edit_file", { filePath: string; oldString: string; newString: string }> { }
|
|
278
275
|
|
|
279
276
|
export interface SubagentTaskToolCall
|
|
280
|
-
extends ToolCallBase<"subagent_task", { subagentType?: string }> {}
|
|
277
|
+
extends ToolCallBase<"subagent_task", { subagentType?: string }> { }
|
|
281
278
|
|
|
282
279
|
export interface McpGenericToolCall
|
|
283
|
-
extends ToolCallBase<"mcp_generic", { server: string; tool: string; payload: Record<string, unknown> }> {}
|
|
280
|
+
extends ToolCallBase<"mcp_generic", { server: string; tool: string; payload: Record<string, unknown> }> { }
|
|
284
281
|
|
|
285
282
|
export interface UnknownToolCall
|
|
286
|
-
extends ToolCallBase<"unknown_tool", { payload: Record<string, unknown> }> {}
|
|
283
|
+
extends ToolCallBase<"unknown_tool", { payload: Record<string, unknown> }> { }
|
|
287
284
|
|
|
288
285
|
export type NormalizedToolCall =
|
|
289
286
|
| AskUserQuestionToolCall
|