@selesai/code 0.9.4 → 0.9.5
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/CHANGELOG.md +6 -0
- package/README.md +1 -1
- package/dist/core/extensions/types.d.ts +2 -0
- package/dist/extensions/question/index.ts +81 -6
- package/dist/extensions/question/tests/wizard.test.ts +19 -3
- package/dist/modes/rpc/rpc-mode.js +1 -0
- package/dist/modes/rpc/rpc-types.d.ts +11 -0
- package/docs/extensions.md +4 -1
- package/docs/rpc.md +26 -3
- package/package.json +1 -1
- package/docs/research/kilo-vscode-and-selesai-integration.md +0 -319
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,12 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to `@selesai/code` will be documented in this file.
|
|
4
4
|
|
|
5
|
+
## [0.9.5] - 2026-08-23
|
|
6
|
+
|
|
7
|
+
### Added
|
|
8
|
+
- **Questions in non-TUI modes.** The bundled `question` tool now works outside the terminal TUI (e.g. RPC/VS Code hosts): questions are answered through the host's `extension_ui_request` dialogs (`select`/`input`) instead of throwing, mirroring Cline/Kilo. Multi-select questions preserve full multi-selection when the host supports the new `multiselect` UI method, with single-select fallback for older hosts.
|
|
9
|
+
- **`multiselect` extension UI method.** `ExtensionUIContext.multiselect()` prompts for multiple choices and returns `string[] | undefined`. In RPC mode it emits an `extension_ui_request` with `method: "multiselect"` and accepts an `extension_ui_response` with a `values` array.
|
|
10
|
+
|
|
5
11
|
## [0.9.4] - 2026-08-22
|
|
6
12
|
|
|
7
13
|
### Changed
|
package/README.md
CHANGED
|
@@ -81,7 +81,7 @@ DuckDuckGo works as the default search path. Optional first-run onboarding can c
|
|
|
81
81
|
|
|
82
82
|
### Interactive questions
|
|
83
83
|
|
|
84
|
-
The bundled `question` tool gives the agent a real
|
|
84
|
+
The bundled `question` tool gives the agent a real UI for decisions instead of forcing every clarification through plain text. It supports:
|
|
85
85
|
|
|
86
86
|
- single- and multi-select options
|
|
87
87
|
- descriptions and context summaries
|
|
@@ -68,6 +68,8 @@ export type EditorFactory = (tui: TUI, theme: EditorTheme, keybindings: Keybindi
|
|
|
68
68
|
export interface ExtensionUIContext {
|
|
69
69
|
/** Show a selector and return the user's choice. */
|
|
70
70
|
select(title: string, options: string[], opts?: ExtensionUIDialogOptions): Promise<string | undefined>;
|
|
71
|
+
/** Show a multi-select dialog and return the user's selections (labels), or undefined if cancelled. */
|
|
72
|
+
multiselect?(title: string, options: string[], opts?: ExtensionUIDialogOptions): Promise<string[] | undefined>;
|
|
71
73
|
/** Show a confirmation dialog. */
|
|
72
74
|
confirm(title: string, message: string, opts?: ExtensionUIDialogOptions): Promise<boolean>;
|
|
73
75
|
/** Show a text input dialog. */
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// Batch-first interactive question tool.
|
|
2
2
|
|
|
3
|
-
import type { ExtensionAPI, KeybindingsManager, Theme } from "@selesai/code";
|
|
3
|
+
import type { ExtensionAPI, ExtensionUIContext, KeybindingsManager, Theme } from "@selesai/code";
|
|
4
4
|
import {
|
|
5
5
|
Container,
|
|
6
6
|
type Component,
|
|
@@ -18,6 +18,78 @@ import {
|
|
|
18
18
|
import { buildQuestionAnswers, prepareQuestions, saveDraftQuestion } from "./batch.ts";
|
|
19
19
|
import { BOX_BORDER_LEFT, BOX_BORDER_OVERHEAD, BOX_BORDER_RIGHT, DISABLED_SHORTCUT, QUESTION_VERSION } from "./constants.ts";
|
|
20
20
|
import { createSelectionResponse, createTextResponse, formatQuestionResponse, formatResponseSummary, oneLine, previewText, trimText } from "./helpers.ts";
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Answer a question outside the terminal TUI (e.g. RPC/extension mode) using
|
|
24
|
+
* the per-mode ExtensionUIContext, which emits extension_ui_request dialogs
|
|
25
|
+
* (select/input) that the VS Code host renders. Mirrors Cline/Kilo: a pending
|
|
26
|
+
* question is surfaced in the webview and blocks until the user answers.
|
|
27
|
+
*/
|
|
28
|
+
function answerQuestionViaUi(question: PreparedQuestion, ctx: { ui: ExtensionUIContext }): Promise<QuestionResponse | null> {
|
|
29
|
+
const title = question.context ? `${question.question}
|
|
30
|
+
|
|
31
|
+
${question.context}` : question.question;
|
|
32
|
+
if (question.type === "text") {
|
|
33
|
+
return ctx.ui.input(title).then((text) => createTextResponse(text));
|
|
34
|
+
}
|
|
35
|
+
const optionLabels = new Map(question.options.map((option) => [option.label, option.value] as const));
|
|
36
|
+
const optionValues = question.options.map((option) => option.value);
|
|
37
|
+
const labels = question.options.map((option) => option.label);
|
|
38
|
+
if (question.type === "select") {
|
|
39
|
+
return ctx.ui
|
|
40
|
+
.select(title, labels)
|
|
41
|
+
.then((selected) => {
|
|
42
|
+
if (selected === undefined) return null;
|
|
43
|
+
const value = optionLabels.get(selected);
|
|
44
|
+
const isOther = value === undefined;
|
|
45
|
+
if (isOther) {
|
|
46
|
+
if (!question.allowOther) return null;
|
|
47
|
+
return ctx.ui.input(title).then((text) => createSelectionResponse([], text ?? undefined));
|
|
48
|
+
}
|
|
49
|
+
return createSelectionResponse([value]);
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
// RPC/webview hosts can preserve true multi-selection. Older hosts fall back to
|
|
53
|
+
// one choice rather than making the question tool unavailable entirely. When
|
|
54
|
+
// allowOther is set the host sees an explicit "Other" choice, surfacing a free
|
|
55
|
+
// text follow-up exactly like the TUI wizard.
|
|
56
|
+
if (ctx.ui.multiselect) {
|
|
57
|
+
const other = question.allowOther ? ["Other"] : [];
|
|
58
|
+
return ctx.ui.multiselect(title, [...labels, ...other]).then((selected) => {
|
|
59
|
+
if (selected === undefined) return null;
|
|
60
|
+
const values = selected.filter((label) => label !== "Other").map((label) => optionLabels.get(label)).filter((value): value is string => value !== undefined);
|
|
61
|
+
if (question.allowOther && selected.includes("Other")) {
|
|
62
|
+
return ctx.ui.input(title).then((text) => createSelectionResponse(values, text ?? undefined));
|
|
63
|
+
}
|
|
64
|
+
return createSelectionResponse(values);
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
return ctx.ui.select(title, labels).then((selected) => {
|
|
68
|
+
if (selected === undefined) return null;
|
|
69
|
+
const value = optionLabels.get(selected);
|
|
70
|
+
return value === undefined
|
|
71
|
+
? question.allowOther ? ctx.ui.input(title).then((text) => createSelectionResponse([], text ?? undefined)) : null
|
|
72
|
+
: createSelectionResponse([value]);
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Non-TUI fallback that answers each question in sequence via the host UI.
|
|
78
|
+
* Returns null when the user cancels any question.
|
|
79
|
+
*/
|
|
80
|
+
async function answerQuestionsViaUi(questions: PreparedQuestion[], ctx: { ui: ExtensionUIContext }): Promise<QuestionResponse[] | null> {
|
|
81
|
+
const answers: QuestionResponse[] = [];
|
|
82
|
+
for (const question of questions) {
|
|
83
|
+
const response = await answerQuestionViaUi(question, ctx);
|
|
84
|
+
if (response === null) return null;
|
|
85
|
+
answers.push(response);
|
|
86
|
+
}
|
|
87
|
+
return answers;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
function buildAnswersFromResponses(questions: PreparedQuestion[], responses: QuestionResponse[]): QuestionAnswer[] {
|
|
91
|
+
return questions.map((question, index) => ({ id: question.id, status: "answered" as const, response: responses[index]! }));
|
|
92
|
+
}
|
|
21
93
|
import { QuestionList } from "./question-list.ts";
|
|
22
94
|
import { MultiSelect, SingleSelect } from "./selection-mode.ts";
|
|
23
95
|
import { QuestionParamsSchema } from "./schemas.ts";
|
|
@@ -557,14 +629,17 @@ export default function questionExtension(pi: ExtensionAPI) {
|
|
|
557
629
|
async execute(_toolCallId, params, signal, onUpdate, ctx) {
|
|
558
630
|
const prepared = prepareQuestions(params.questions);
|
|
559
631
|
if ("error" in prepared) throw new Error(prepared.error);
|
|
560
|
-
if (ctx.mode !== "tui") throw new Error("Question requires terminal TUI mode.");
|
|
561
632
|
if (signal?.aborted) return { content: [{ type: "text", text: "Question cancelled" }], details: { status: "cancelled", reason: "user" } satisfies QuestionToolResult };
|
|
562
633
|
|
|
563
634
|
onUpdate?.({ content: [{ type: "text", text: `Waiting for answers to ${prepared.questions.length} question${prepared.questions.length === 1 ? "" : "s"}...` }] });
|
|
564
|
-
const result =
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
635
|
+
const result: QuestionToolResult | undefined = ctx.mode === "tui"
|
|
636
|
+
? await ctx.ui.custom<QuestionToolResult>((tui, theme, keybindings, done) => {
|
|
637
|
+
if (signal) signal.addEventListener("abort", () => done({ status: "cancelled", reason: "user" }), { once: true });
|
|
638
|
+
return new BatchQuestionComponent(prepared.questions, tui, theme, keybindings, done);
|
|
639
|
+
})
|
|
640
|
+
: await answerQuestionsViaUi(prepared.questions, ctx).then((responses) =>
|
|
641
|
+
responses ? { status: "submitted" as const, answers: buildAnswersFromResponses(prepared.questions, responses) } : { status: "cancelled" as const, reason: "user" as const },
|
|
642
|
+
);
|
|
568
643
|
if (!result) throw new Error("Question TUI did not return a result.");
|
|
569
644
|
|
|
570
645
|
if (result.status === "cancelled") {
|
|
@@ -197,13 +197,29 @@ describe("question wizard", () => {
|
|
|
197
197
|
expect(emitted2).toEqual(["question:submitted"]);
|
|
198
198
|
});
|
|
199
199
|
|
|
200
|
-
it("
|
|
200
|
+
it("uses extension UI requests in RPC mode", async () => {
|
|
201
201
|
let tool: any;
|
|
202
202
|
questionExtension({ registerTool: (entry: unknown) => (tool = entry), events: { emit() {} } } as any);
|
|
203
|
+
const result = await tool.execute("call", { questions: [{ type: "select", question: "Choose", options: [{ value: "x", label: "X" }] }] }, undefined, undefined, {
|
|
204
|
+
mode: "rpc",
|
|
205
|
+
ui: { select: async () => "X" },
|
|
206
|
+
} as any);
|
|
207
|
+
expect(result.details).toEqual({ status: "submitted", answers: [{ id: "q1", status: "answered", response: { kind: "selection", values: ["x"] } }] });
|
|
208
|
+
});
|
|
203
209
|
|
|
204
|
-
|
|
210
|
+
it("preserves multiple RPC selections", async () => {
|
|
211
|
+
let tool: any;
|
|
212
|
+
questionExtension({ registerTool: (entry: unknown) => (tool = entry), events: { emit() {} } } as any);
|
|
213
|
+
const result = await tool.execute("call", { questions: [{ type: "multiselect", question: "Choose many", options: [{ value: "a", label: "A" }, { value: "b", label: "B" }] }] }, undefined, undefined, {
|
|
205
214
|
mode: "rpc",
|
|
206
|
-
|
|
215
|
+
ui: { multiselect: async () => ["A", "B"] },
|
|
216
|
+
} as any);
|
|
217
|
+
expect(result.details).toEqual({ status: "submitted", answers: [{ id: "q1", status: "answered", response: { kind: "selection", values: ["a", "b"] } }] });
|
|
218
|
+
});
|
|
219
|
+
|
|
220
|
+
it("rejects invalid params", async () => {
|
|
221
|
+
let tool: any;
|
|
222
|
+
questionExtension({ registerTool: (entry: unknown) => (tool = entry), events: { emit() {} } } as any);
|
|
207
223
|
|
|
208
224
|
await expect(tool.execute("call", { questions: [] }, undefined, undefined, {
|
|
209
225
|
mode: "tui",
|
|
@@ -81,6 +81,7 @@ export async function runRpcMode(runtimeHost) {
|
|
|
81
81
|
*/
|
|
82
82
|
const createExtensionUIContext = () => ({
|
|
83
83
|
select: (title, options, opts) => createDialogPromise(opts, undefined, { method: "select", title, options, timeout: opts?.timeout }, (r) => "cancelled" in r && r.cancelled ? undefined : "value" in r ? r.value : undefined),
|
|
84
|
+
multiselect: (title, options, opts) => createDialogPromise(opts, undefined, { method: "multiselect", title, options, timeout: opts?.timeout }, (r) => "cancelled" in r && r.cancelled ? undefined : "values" in r ? r.values : undefined),
|
|
84
85
|
confirm: (title, message, opts) => createDialogPromise(opts, false, { method: "confirm", title, message, timeout: opts?.timeout }, (r) => "cancelled" in r && r.cancelled ? false : "confirmed" in r ? r.confirmed : false),
|
|
85
86
|
input: (title, placeholder, opts) => createDialogPromise(opts, undefined, { method: "input", title, placeholder, timeout: opts?.timeout }, (r) => "cancelled" in r && r.cancelled ? undefined : "value" in r ? r.value : undefined),
|
|
86
87
|
notify(message, type) {
|
|
@@ -418,6 +418,13 @@ export type RpcExtensionUIRequest = {
|
|
|
418
418
|
title: string;
|
|
419
419
|
options: string[];
|
|
420
420
|
timeout?: number;
|
|
421
|
+
} | {
|
|
422
|
+
type: "extension_ui_request";
|
|
423
|
+
id: string;
|
|
424
|
+
method: "multiselect";
|
|
425
|
+
title: string;
|
|
426
|
+
options: string[];
|
|
427
|
+
timeout?: number;
|
|
421
428
|
} | {
|
|
422
429
|
type: "extension_ui_request";
|
|
423
430
|
id: string;
|
|
@@ -473,6 +480,10 @@ export type RpcExtensionUIResponse = {
|
|
|
473
480
|
type: "extension_ui_response";
|
|
474
481
|
id: string;
|
|
475
482
|
value: string;
|
|
483
|
+
} | {
|
|
484
|
+
type: "extension_ui_response";
|
|
485
|
+
id: string;
|
|
486
|
+
values: string[];
|
|
476
487
|
} | {
|
|
477
488
|
type: "extension_ui_response";
|
|
478
489
|
id: string;
|
package/docs/extensions.md
CHANGED
|
@@ -9,7 +9,7 @@ Extensions are TypeScript modules that extend pi's behavior. They can subscribe
|
|
|
9
9
|
**Key capabilities:**
|
|
10
10
|
- **Custom tools** - Register tools the LLM can call via `pi.registerTool()`
|
|
11
11
|
- **Event interception** - Block or modify tool calls, inject context, customize compaction
|
|
12
|
-
- **User interaction** - Prompt users via `ctx.ui` (select, confirm, input, notify)
|
|
12
|
+
- **User interaction** - Prompt users via `ctx.ui` (select, multiselect, confirm, input, notify)
|
|
13
13
|
- **Custom UI components** - Full TUI components with keyboard input via `ctx.ui.custom()` for complex interactions
|
|
14
14
|
- **Custom commands** - Register commands like `/mycommand` via `pi.registerCommand()`
|
|
15
15
|
- **Session persistence** - Store state that survives restarts via `pi.appendEntry()`
|
|
@@ -2201,6 +2201,9 @@ Extensions can interact with users via `ctx.ui` methods and customize how messag
|
|
|
2201
2201
|
// Select from options
|
|
2202
2202
|
const choice = await ctx.ui.select("Pick one:", ["A", "B", "C"]);
|
|
2203
2203
|
|
|
2204
|
+
// Multi-select from options (string[] | undefined; optional in hosts that do not support it)
|
|
2205
|
+
const choices = await ctx.ui.multiselect?.("Pick many:", ["A", "B", "C"]);
|
|
2206
|
+
|
|
2204
2207
|
// Confirm dialog
|
|
2205
2208
|
const ok = await ctx.ui.confirm("Delete?", "This cannot be undone");
|
|
2206
2209
|
|
package/docs/rpc.md
CHANGED
|
@@ -1008,7 +1008,7 @@ Extensions can request user interaction via `ctx.ui.select()`, `ctx.ui.confirm()
|
|
|
1008
1008
|
|
|
1009
1009
|
There are two categories of extension UI methods:
|
|
1010
1010
|
|
|
1011
|
-
- **Dialog methods** (`select`, `confirm`, `input`, `editor`): emit an `extension_ui_request` on stdout and block until the client sends back an `extension_ui_response` on stdin with the matching `id`.
|
|
1011
|
+
- **Dialog methods** (`select`, `multiselect`, `confirm`, `input`, `editor`): emit an `extension_ui_request` on stdout and block until the client sends back an `extension_ui_response` on stdin with the matching `id`.
|
|
1012
1012
|
- **Fire-and-forget methods** (`notify`, `setStatus`, `setWidget`, `setTitle`, `set_editor_text`): emit an `extension_ui_request` on stdout but do not expect a response. The client can display the information or ignore it.
|
|
1013
1013
|
|
|
1014
1014
|
If a dialog method includes a `timeout` field, the agent-side will auto-resolve with a default value when the timeout expires. The client does not need to track timeouts.
|
|
@@ -1046,6 +1046,23 @@ Prompt the user to choose from a list. Dialog methods with a `timeout` field inc
|
|
|
1046
1046
|
|
|
1047
1047
|
Expected response: `extension_ui_response` with `value` (the selected option string) or `cancelled: true`.
|
|
1048
1048
|
|
|
1049
|
+
#### multiselect
|
|
1050
|
+
|
|
1051
|
+
Prompt the user to choose zero or more options from a list. Dialog methods with a `timeout` field include the timeout in milliseconds; the agent auto-resolves with `undefined` if the client doesn't respond in time.
|
|
1052
|
+
|
|
1053
|
+
```json
|
|
1054
|
+
{
|
|
1055
|
+
"type": "extension_ui_request",
|
|
1056
|
+
"id": "uuid-10",
|
|
1057
|
+
"method": "multiselect",
|
|
1058
|
+
"title": "Which regions?",
|
|
1059
|
+
"options": ["us-east", "eu-west", "ap-southeast"],
|
|
1060
|
+
"timeout": 10000
|
|
1061
|
+
}
|
|
1062
|
+
```
|
|
1063
|
+
|
|
1064
|
+
Expected response: `extension_ui_response` with `values` (the selected option strings) or `cancelled: true`.
|
|
1065
|
+
|
|
1049
1066
|
#### confirm
|
|
1050
1067
|
|
|
1051
1068
|
Prompt the user for yes/no confirmation.
|
|
@@ -1172,7 +1189,7 @@ Set the text in the input editor. Fire-and-forget.
|
|
|
1172
1189
|
|
|
1173
1190
|
### Extension UI Responses (stdin)
|
|
1174
1191
|
|
|
1175
|
-
Responses are sent for dialog methods only (`select`, `confirm`, `input`, `editor`). The `id` must match the request.
|
|
1192
|
+
Responses are sent for dialog methods only (`select`, `multiselect`, `confirm`, `input`, `editor`). The `id` must match the request.
|
|
1176
1193
|
|
|
1177
1194
|
#### Value response (select, input, editor)
|
|
1178
1195
|
|
|
@@ -1180,6 +1197,12 @@ Responses are sent for dialog methods only (`select`, `confirm`, `input`, `edito
|
|
|
1180
1197
|
{"type": "extension_ui_response", "id": "uuid-1", "value": "Allow"}
|
|
1181
1198
|
```
|
|
1182
1199
|
|
|
1200
|
+
#### Values response (multiselect)
|
|
1201
|
+
|
|
1202
|
+
```json
|
|
1203
|
+
{"type": "extension_ui_response", "id": "uuid-10", "values": ["us-east", "ap-southeast"]}
|
|
1204
|
+
```
|
|
1205
|
+
|
|
1183
1206
|
#### Confirmation response (confirm)
|
|
1184
1207
|
|
|
1185
1208
|
```json
|
|
@@ -1188,7 +1211,7 @@ Responses are sent for dialog methods only (`select`, `confirm`, `input`, `edito
|
|
|
1188
1211
|
|
|
1189
1212
|
#### Cancellation response (any dialog)
|
|
1190
1213
|
|
|
1191
|
-
Dismiss any dialog method. The extension receives `undefined` (for select/input/editor) or `false` (for confirm).
|
|
1214
|
+
Dismiss any dialog method. The extension receives `undefined` (for select/multiselect/input/editor) or `false` (for confirm).
|
|
1192
1215
|
|
|
1193
1216
|
```json
|
|
1194
1217
|
{"type": "extension_ui_response", "id": "uuid-3", "cancelled": true}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@selesai/code",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.5",
|
|
4
4
|
"description": "Maintained, extension-first Pi coding agent with built-in workflows, subagents, web research, questions, skills, and an enhanced terminal UI.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"repository": {
|
|
@@ -1,319 +0,0 @@
|
|
|
1
|
-
# Kilo Code VS Code Architecture and Selesai Integration Feasibility
|
|
2
|
-
|
|
3
|
-
**Research date:** 2026-08-20
|
|
4
|
-
**Repositories:** [Kilo Code](https://github.com/Kilo-Org/kilocode), this Selesai Code repository
|
|
5
|
-
**Question:** Does Kilo use RPA or another integration mechanism, and can Selesai provide a similar or better VS Code extension?
|
|
6
|
-
|
|
7
|
-
## Executive conclusion
|
|
8
|
-
|
|
9
|
-
Kilo Code is **not primarily an RPA application** and its core is not an LSP client/server. It is a layered VS Code product:
|
|
10
|
-
|
|
11
|
-
1. A normal VS Code extension host (`packages/kilo-vscode`) activated through `vscode` APIs.
|
|
12
|
-
2. Webview-based UI surfaces (sidebar, panels, agent manager, settings, diffs).
|
|
13
|
-
3. A lazily spawned local Kilo CLI backend (`kilo serve --port 0`).
|
|
14
|
-
4. An SDK/client connection from the extension host to that backend over authenticated local HTTP APIs and SSE event streaming.
|
|
15
|
-
5. Separate WebSocket paths for selected features such as PTY terminal streaming and cloud event service.
|
|
16
|
-
6. MCP client transports for tool/server integration: local stdio subprocesses and remote HTTP/SSE transports.
|
|
17
|
-
|
|
18
|
-
The important correction to a simplistic “Webview only” description is that **Webview `postMessage` is only the UI bridge**. In the current Kilo repository, the extension also connects to a local backend server. The extension spawns the backend, discovers its ephemeral port from stdout, gives it a generated password, and uses an SDK plus HTTP/SSE with Basic authentication.
|
|
19
|
-
|
|
20
|
-
Selesai can absolutely support a comparable VS Code extension. The shortest path is a VS Code extension-host backend that starts `selesai --mode rpc` and adapts the existing strict JSONL RPC client/events into a Webview. The best long-term path is probably a two-tier design:
|
|
21
|
-
|
|
22
|
-
- **MVP:** local child process + existing Selesai RPC over private stdin/stdout.
|
|
23
|
-
- **Better product integration:** a small authenticated local HTTP/SSE or WebSocket server facade, or direct in-process SDK use where safe, with a stable VS Code-oriented protocol.
|
|
24
|
-
|
|
25
|
-
Selesai already has unusually strong agent/session/extension primitives. Its main missing pieces for Kilo-level VS Code integration are a polished VS Code package, a durable UI protocol/adapter, explicit trust UX, and (if remote or multi-client use is desired) authenticated network transport.
|
|
26
|
-
|
|
27
|
-
## 1. What Kilo actually uses
|
|
28
|
-
|
|
29
|
-
### 1.1 VS Code extension activation
|
|
30
|
-
|
|
31
|
-
Kilo's extension is a conventional TypeScript VS Code extension. The activation function accepts `vscode.ExtensionContext`, constructs shared services, and registers views/providers through the VS Code API:
|
|
32
|
-
|
|
33
|
-
- [`packages/kilo-vscode/src/extension.ts`](https://github.com/Kilo-Org/kilocode/blob/main/packages/kilo-vscode/src/extension.ts#L45-L61) — `activate(context)` and shared `KiloConnectionService`.
|
|
34
|
-
- [`packages/kilo-vscode/src/extension.ts`](https://github.com/Kilo-Org/kilocode/blob/main/packages/kilo-vscode/src/extension.ts#L131-L143) — creates `KiloProvider` and calls `vscode.window.registerWebviewViewProvider(...)`.
|
|
35
|
-
- The extension manifest/build configuration is in [`packages/kilo-vscode/package.json`](https://github.com/Kilo-Org/kilocode/blob/main/packages/kilo-vscode/package.json) and the repository root package configuration.
|
|
36
|
-
|
|
37
|
-
This is ordinary VS Code extension-host architecture, not RPA automation of the VS Code UI.
|
|
38
|
-
|
|
39
|
-
### 1.2 Webview UI bridge
|
|
40
|
-
|
|
41
|
-
Kilo's chat and panels use Webviews. The extension host attaches a Webview and receives structured messages with `webview.onDidReceiveMessage`; it sends state, stream, and command results back using `webview.postMessage`:
|
|
42
|
-
|
|
43
|
-
- [`KiloProvider.ts`](https://github.com/Kilo-Org/kilocode/blob/main/packages/kilo-vscode/src/KiloProvider.ts#L987-L1019) — `attachToWebview`, handler setup, interception, and routing.
|
|
44
|
-
- [`KiloProvider.ts`](https://github.com/Kilo-Org/kilocode/blob/main/packages/kilo-vscode/src/KiloProvider.ts#L1013-L1040) — inbound message handling and dispatch.
|
|
45
|
-
- [`extension.ts`](https://github.com/Kilo-Org/kilocode/blob/main/packages/kilo-vscode/src/extension.ts#L137-L143) — sidebar Webview registration.
|
|
46
|
-
|
|
47
|
-
The Webview bridge is **structured local message passing across the VS Code extension/Webview boundary**. It is not HTTP RPC, LSP, or RPA.
|
|
48
|
-
|
|
49
|
-
### 1.3 The extension spawns a local backend
|
|
50
|
-
|
|
51
|
-
The current code explicitly documents that the CLI backend starts lazily rather than during extension activation:
|
|
52
|
-
|
|
53
|
-
> “The CLI backend is NOT spawned here; it starts lazily when a webview connects or when ensureBackendForAutocomplete() triggers it.”
|
|
54
|
-
|
|
55
|
-
Source: [`packages/kilo-vscode/src/extension.ts`](https://github.com/Kilo-Org/kilocode/blob/main/packages/kilo-vscode/src/extension.ts#L45-L49).
|
|
56
|
-
|
|
57
|
-
The server manager starts a local CLI process with an ephemeral port:
|
|
58
|
-
|
|
59
|
-
- [`server-manager.ts`](https://github.com/Kilo-Org/kilocode/blob/main/packages/kilo-vscode/src/services/cli-backend/server-manager.ts#L92-L120) — spawns `cliPath serve --port 0` with a workspace-derived cwd.
|
|
60
|
-
- [`server-manager.ts`](https://github.com/Kilo-Org/kilocode/blob/main/packages/kilo-vscode/src/services/cli-backend/server-manager.ts#L118-L161) — passes environment, including `KILO_SERVER_PASSWORD`, parent PID, VS Code metadata, and `stdio: ["ignore", "pipe", "pipe"]`.
|
|
61
|
-
- [`server-manager.ts`](https://github.com/Kilo-Org/kilocode/blob/main/packages/kilo-vscode/src/services/cli-backend/server-manager.ts#L167-L177) — reads child stdout and parses the selected port.
|
|
62
|
-
|
|
63
|
-
This is a **local child process plus local server** architecture. It is RPC-like in the broad sense, but it is not RPA.
|
|
64
|
-
|
|
65
|
-
### 1.4 HTTP/API client and SSE events
|
|
66
|
-
|
|
67
|
-
`KiloConnectionService` owns one backend manager, one Kilo SDK client, and one SSE adapter for multiple UI providers:
|
|
68
|
-
|
|
69
|
-
- [`connection-service.ts`](https://github.com/Kilo-Org/kilocode/blob/main/packages/kilo-vscode/src/services/cli-backend/connection-service.ts#L80-L99) — describes and declares the shared service, client, and SSE adapter.
|
|
70
|
-
- [`connection-service.ts`](https://github.com/Kilo-Org/kilocode/blob/main/packages/kilo-vscode/src/services/cli-backend/connection-service.ts#L149-L150) — lazy startup/connection entrypoint.
|
|
71
|
-
- [`types.ts`](https://github.com/Kilo-Org/kilocode/blob/main/packages/kilo-vscode/src/services/cli-backend/types.ts#L1-L20) — server configuration includes `baseUrl` and `password`.
|
|
72
|
-
|
|
73
|
-
The extension checks backend health over HTTP with Basic authentication:
|
|
74
|
-
|
|
75
|
-
- [`connection-service.ts`](https://github.com/Kilo-Org/kilocode/blob/main/packages/kilo-vscode/src/services/cli-backend/connection-service.ts#L733-L777) — periodic `GET ${baseUrl}/global/health`, `Authorization: Basic ...`, and reconnect behavior.
|
|
76
|
-
|
|
77
|
-
Thus the current Kilo architecture is more accurately:
|
|
78
|
-
|
|
79
|
-
```text
|
|
80
|
-
VS Code Webview
|
|
81
|
-
│ postMessage / onDidReceiveMessage
|
|
82
|
-
▼
|
|
83
|
-
Kilo extension host
|
|
84
|
-
│ Kilo SDK over authenticated localhost HTTP
|
|
85
|
-
│ SSE event stream
|
|
86
|
-
▼
|
|
87
|
-
local `kilo serve --port 0` process
|
|
88
|
-
│
|
|
89
|
-
├─ model/provider APIs
|
|
90
|
-
├─ sessions/tools/filesystem
|
|
91
|
-
└─ MCP clients
|
|
92
|
-
```
|
|
93
|
-
|
|
94
|
-
### 1.5 WebSockets are feature-specific, not the basic UI bridge
|
|
95
|
-
|
|
96
|
-
The repository has WebSocket use for feature-specific paths. For example, the Agent Manager terminal routes PTY bytes over a WebSocket rather than through Webview messages:
|
|
97
|
-
|
|
98
|
-
- [`terminal-manager.ts`](https://github.com/Kilo-Org/kilocode/blob/main/packages/kilo-vscode/src/agent-manager/terminal-manager.ts#L1-L10) — describes PTY output over `/pty/:id/connect` WebSocket.
|
|
99
|
-
- [`terminal-routing.ts`](https://github.com/Kilo-Org/kilocode/blob/main/packages/kilo-vscode/src/agent-manager/terminal-routing.ts#L242-L248) — builds an authenticated loopback WebSocket URL with `auth_token`.
|
|
100
|
-
- [`event-service-client.ts`](https://github.com/Kilo-Org/kilocode/blob/main/packages/kilo-vscode/src/kiloclaw/event-service-client.ts#L1-L10) — cloud event-service ticket flow and WebSocket subprotocol.
|
|
101
|
-
|
|
102
|
-
This demonstrates that Kilo chooses transport by use case: Webview messages for UI commands/state, HTTP/SSE for backend API/events, and WebSocket for high-volume or cloud event paths.
|
|
103
|
-
|
|
104
|
-
### 1.6 MCP is an integration protocol, not the extension connection
|
|
105
|
-
|
|
106
|
-
Kilo's MCP code imports multiple official MCP SDK transports:
|
|
107
|
-
|
|
108
|
-
- [`packages/opencode/src/mcp/index.ts`](https://github.com/Kilo-Org/kilocode/blob/main/packages/opencode/src/mcp/index.ts#L15-L19) — `StreamableHTTPClientTransport`, `SSEClientTransport`, and `StdioClientTransport`.
|
|
109
|
-
- [`packages/opencode/src/mcp/index.ts`](https://github.com/Kilo-Org/kilocode/blob/main/packages/opencode/src/mcp/index.ts#L369-L389) — local MCP config launches a command using `StdioClientTransport` with cwd/environment.
|
|
110
|
-
|
|
111
|
-
MCP lets the coding agent connect to tools/resources exposed by configured MCP servers. It does **not** appear to be the protocol connecting Kilo's VS Code Webview to its extension host. Those are separate layers.
|
|
112
|
-
|
|
113
|
-
## 2. Is it RPA, LSP, RPC, or something else?
|
|
114
|
-
|
|
115
|
-
| Technology | Kilo role | Conclusion |
|
|
116
|
-
|---|---|---|
|
|
117
|
-
| RPA (Robotic Process Automation) | None identified as a framework/protocol | No. Agentic file/terminal/browser automation is not conventional RPA architecture. |
|
|
118
|
-
| VS Code Extension API | Activation, commands, views, workspace, terminals, Webviews | Yes; foundational. |
|
|
119
|
-
| Webview message bridge | UI ↔ extension host messages | Yes; local structured messaging. |
|
|
120
|
-
| Local child process | Extension starts `kilo serve` | Yes. |
|
|
121
|
-
| HTTP | Extension ↔ local backend API and health checks | Yes; authenticated localhost API. |
|
|
122
|
-
| SSE | Backend event stream to extension | Yes. |
|
|
123
|
-
| WebSocket | PTY and selected cloud/event paths | Yes, feature-specific. |
|
|
124
|
-
| MCP | Agent ↔ configured external tools/resources | Yes; separate integration layer. |
|
|
125
|
-
| LSP | Language server/client lifecycle | No evidence of core LSP architecture. |
|
|
126
|
-
| JSON-RPC | Not the main current VS Code connection identified in Kilo | Do not assume this is Kilo's transport. |
|
|
127
|
-
|
|
128
|
-
## 3. What Selesai already provides
|
|
129
|
-
|
|
130
|
-
### 3.1 Existing RPC mode
|
|
131
|
-
|
|
132
|
-
Selesai RPC is a headless JSONL protocol over a child process:
|
|
133
|
-
|
|
134
|
-
- [`docs/rpc.md`](../rpc.md) — protocol, commands, event stream, extension UI protocol, framing, and client examples.
|
|
135
|
-
- [`src/modes/rpc/rpc-mode.ts`](../../src/modes/rpc/rpc-mode.ts) — server implementation over stdin/stdout.
|
|
136
|
-
- [`src/modes/rpc/rpc-types.ts`](../../src/modes/rpc/rpc-types.ts) — typed commands, responses, events, and extension UI messages.
|
|
137
|
-
- [`src/modes/rpc/rpc-client.ts`](../../src/modes/rpc/rpc-client.ts) — typed subprocess client and request correlation.
|
|
138
|
-
- [`src/rpc-entry.ts`](../../src/rpc-entry.ts) — RPC executable entrypoint.
|
|
139
|
-
|
|
140
|
-
The transport is strict LF-delimited JSONL. It has request IDs for responses and asynchronous events for streaming output/tool lifecycle. A VS Code extension can spawn:
|
|
141
|
-
|
|
142
|
-
```text
|
|
143
|
-
selesai --mode rpc --cwd <workspace> [other options]
|
|
144
|
-
```
|
|
145
|
-
|
|
146
|
-
(or spawn the packaged Node CLI with equivalent arguments), then:
|
|
147
|
-
|
|
148
|
-
1. Write one JSON object plus `\n` to stdin.
|
|
149
|
-
2. Parse stdout one LF record at a time.
|
|
150
|
-
3. Correlate `type: "response"` records by `id`.
|
|
151
|
-
4. Render `message_update`, `tool_execution_*`, and lifecycle events.
|
|
152
|
-
5. Wait for `agent_settled`/`agent_end`, not merely prompt acceptance.
|
|
153
|
-
6. Answer `extension_ui_request` records when an extension asks for a dialog.
|
|
154
|
-
|
|
155
|
-
This is sufficient for a local VS Code extension MVP.
|
|
156
|
-
|
|
157
|
-
### 3.2 Direct SDK option
|
|
158
|
-
|
|
159
|
-
Selesai also exports a direct TypeScript/Node SDK:
|
|
160
|
-
|
|
161
|
-
- [`docs/sdk.md`](../sdk.md) — `createAgentSession`, `createAgentSessionRuntime`, event subscription, tools, sessions, cwd, auth, and resources.
|
|
162
|
-
- [`src/core/sdk.ts`](../../src/core/sdk.ts) — SDK options and construction.
|
|
163
|
-
- [`src/index.ts`](../../src/index.ts) — public exports.
|
|
164
|
-
|
|
165
|
-
A VS Code extension host is itself Node-based, so it can potentially use `createAgentSession()` in-process. Advantages are lower latency, no JSON serialization, direct typed events, and custom tool/resource integration. Disadvantages are tighter coupling, more difficult fault isolation, extension-host memory/lifecycle risk, and the need to manage session replacement and extension binding carefully.
|
|
166
|
-
|
|
167
|
-
### 3.3 Existing extension system and RPC UI support
|
|
168
|
-
|
|
169
|
-
Selesai extensions can register tools, commands, event handlers, and UI operations. In RPC mode, dialog and notification UI is translated into an explicit request/response protocol:
|
|
170
|
-
|
|
171
|
-
- [`docs/extensions.md`](../extensions.md) — extension API and security model.
|
|
172
|
-
- [`docs/rpc.md`](../rpc.md) — `select`, `confirm`, `input`, `editor`, `notify`, status, widget, title, and editor-text requests.
|
|
173
|
-
|
|
174
|
-
This is a useful foundation for mapping agent permission questions to VS Code dialogs, status bar items, notifications, and editor input.
|
|
175
|
-
|
|
176
|
-
## 4. Selesai versus Kilo: capability comparison
|
|
177
|
-
|
|
178
|
-
| Capability | Kilo current approach | Selesai current position | Assessment |
|
|
179
|
-
|---|---|---|---|
|
|
180
|
-
| VS Code package | Dedicated `packages/kilo-vscode` extension | No dedicated VS Code extension found in this repository | Kilo leads on product packaging. |
|
|
181
|
-
| Main UI | Multiple Webviews/panels/providers | RPC UI protocol can feed a new Webview | Selesai has protocol primitives; Kilo has finished UI. |
|
|
182
|
-
| Agent backend isolation | Spawned local CLI server | Spawned local RPC process | Both isolate backend; Selesai MVP is simpler. |
|
|
183
|
-
| Backend network API | Authenticated localhost HTTP + SSE | No TCP/HTTP RPC server; stdin/stdout JSONL | Kilo leads for multi-client/network-capable architecture. |
|
|
184
|
-
| Transport auth | Generated password; Basic/loopback auth | No RPC auth handshake; private pipes only | Selesai needs auth before exposing network transport. |
|
|
185
|
-
| Streaming | SSE and WebSocket for relevant paths | JSONL event stream | Both support streaming; Selesai JSONL is easy to adapt. |
|
|
186
|
-
| Sessions | Backend session APIs and shared connection service | Rich RPC/SDK session lifecycle and tree operations | Selesai is strong at protocol-level session control. |
|
|
187
|
-
| Extensions/plugins | Agent/runtime extensions and Kilo services | Extension-first tools/events/UI; RPC-compatible UI | Selesai is potentially more extensible, but needs VS Code UX. |
|
|
188
|
-
| MCP | Local stdio and remote transports | Extension/tool ecosystem exists; MCP parity should be audited separately | Kilo has explicit MCP transport integration. |
|
|
189
|
-
| Terminal/PTy | Dedicated terminal manager and WebSocket streaming | RPC bash exists; no Kilo-equivalent VS Code PTY bridge identified | Kilo leads for native terminal UX. |
|
|
190
|
-
| Trust/security | Backend password and process lifecycle controls | Explicit extension trust exists, but RPC has no auth | Selesai needs a dedicated integration security model. |
|
|
191
|
-
| In-process embedding | Backend/client architecture | First-class SDK | Selesai may be better for tightly integrated custom clients. |
|
|
192
|
-
|
|
193
|
-
## 5. Feasibility: how to build a Selesai VS Code extension
|
|
194
|
-
|
|
195
|
-
### Phase 1 — local MVP (recommended first)
|
|
196
|
-
|
|
197
|
-
Build a conventional VS Code extension with:
|
|
198
|
-
|
|
199
|
-
```text
|
|
200
|
-
VS Code Webview UI
|
|
201
|
-
│ vscode.postMessage
|
|
202
|
-
▼
|
|
203
|
-
Extension host controller
|
|
204
|
-
│ child_process / existing RpcClient
|
|
205
|
-
▼
|
|
206
|
-
selesai --mode rpc (private stdin/stdout)
|
|
207
|
-
```
|
|
208
|
-
|
|
209
|
-
Minimum components:
|
|
210
|
-
|
|
211
|
-
- `ExtensionHostController`: owns one Selesai process per workspace/session.
|
|
212
|
-
- `RpcClientAdapter`: wraps the existing `RpcClient`; add or expose extension UI request handling if the current public client does not already do so.
|
|
213
|
-
- `WorkspaceManager`: resolves workspace cwd, session directory, and project trust.
|
|
214
|
-
- `EventStore`: maps streamed events into Webview state, with bounded history and reconnection handling.
|
|
215
|
-
- `WebviewProvider`: chat, streaming text, tool calls, approval questions, model picker, session picker.
|
|
216
|
-
- `Command` registrations: open sidebar, new session, abort, steer, follow-up, model selection.
|
|
217
|
-
- `dispose()` handling: send shutdown/EOF, wait briefly, terminate if necessary.
|
|
218
|
-
|
|
219
|
-
This does **not** need RPA, LSP, MCP, or a network server.
|
|
220
|
-
|
|
221
|
-
### Phase 2 — native VS Code experience
|
|
222
|
-
|
|
223
|
-
Add the features that make an extension feel better than a terminal wrapper:
|
|
224
|
-
|
|
225
|
-
- Inline editor selection/context actions (“Ask Selesai about this”, “Fix this”).
|
|
226
|
-
- Diff-aware edit review using VS Code `WorkspaceEdit` or controlled file edits.
|
|
227
|
-
- Native permission prompts for writes, shell commands, and external tools.
|
|
228
|
-
- Diagnostics/code actions where agent output can be represented safely.
|
|
229
|
-
- Native terminal/task integration and cancellation.
|
|
230
|
-
- Status bar progress, notifications, output channel, and session restoration.
|
|
231
|
-
- Workspace-specific context files and explicit trust prompts.
|
|
232
|
-
- Webview state restoration and multiple workspace/session routing.
|
|
233
|
-
|
|
234
|
-
### Phase 3 — Kilo-like backend facade (only if needed)
|
|
235
|
-
|
|
236
|
-
If Selesai needs multiple clients, remote control, or richer WebSocket/SSE behavior, add an authenticated local server mode rather than exposing raw stdin/stdout through an ad-hoc bridge.
|
|
237
|
-
|
|
238
|
-
Suggested shape:
|
|
239
|
-
|
|
240
|
-
```text
|
|
241
|
-
VS Code extension ── authenticated HTTP/SSE or WebSocket ── Selesai server
|
|
242
|
-
```
|
|
243
|
-
|
|
244
|
-
Requirements before shipping:
|
|
245
|
-
|
|
246
|
-
- Bind to loopback by default, never `0.0.0.0` by accident.
|
|
247
|
-
- Generate a high-entropy per-process secret.
|
|
248
|
-
- Require authentication on every endpoint/stream.
|
|
249
|
-
- Scope sessions and cwd to the requesting workspace/client.
|
|
250
|
-
- Validate origin and reject cross-workspace access.
|
|
251
|
-
- Provide process parent watchdog and graceful shutdown.
|
|
252
|
-
- Avoid leaking session paths, API keys, prompts, or tool output in logs.
|
|
253
|
-
- Define protocol versioning and event replay/reconnect semantics.
|
|
254
|
-
- Add rate limits and explicit authorization for destructive operations.
|
|
255
|
-
|
|
256
|
-
## 6. Key risks and design decisions
|
|
257
|
-
|
|
258
|
-
### Security
|
|
259
|
-
|
|
260
|
-
Selesai's RPC stdin/stdout is relatively safe because it is private to the spawned child process. It has no token, handshake, or authorization layer. It must **not** simply be put behind a TCP port. A Kilo-like server facade needs authentication, loopback binding, workspace isolation, and process lifecycle controls.
|
|
261
|
-
|
|
262
|
-
Selesai extensions execute with full system permissions, as documented in [`docs/extensions.md`](../extensions.md). The VS Code extension should not silently enable untrusted project-local extensions or resources. Mirror VS Code's workspace trust decision in the agent startup path.
|
|
263
|
-
|
|
264
|
-
### Prompt completion versus acceptance
|
|
265
|
-
|
|
266
|
-
RPC prompt acceptance is not completion. The UI must track the asynchronous event stream and mark a run complete only on the settled/end lifecycle event. This is essential for streaming text, tool progress, approval prompts, and cancellation.
|
|
267
|
-
|
|
268
|
-
### RPC UI limitations
|
|
269
|
-
|
|
270
|
-
RPC mode supports dialogs and simple status/widget notifications but not all TUI capabilities. A VS Code adapter needs to decide how to map or replace unsupported methods such as custom TUI components, terminal raw input, and theme-specific rendering.
|
|
271
|
-
|
|
272
|
-
### Process versus in-process SDK
|
|
273
|
-
|
|
274
|
-
Use RPC first when reliability and isolation matter. Use the SDK when the extension needs deep typed access and can own the agent lifecycle. A hybrid is possible: keep the default backend out-of-process, offer an in-process mode for development/advanced integrations.
|
|
275
|
-
|
|
276
|
-
### Multi-root workspaces
|
|
277
|
-
|
|
278
|
-
Both resource discovery and tool paths depend on cwd. The extension must choose and persist a workspace root/session mapping rather than relying on the extension host's process cwd. For multi-root workspaces, each session should carry an explicit workspace directory.
|
|
279
|
-
|
|
280
|
-
## 7. Recommended product strategy
|
|
281
|
-
|
|
282
|
-
Selesai can be “similar or better than Kilo” if it focuses on its existing strengths instead of copying every transport immediately:
|
|
283
|
-
|
|
284
|
-
1. **Ship a focused Webview extension over existing RPC.** This delivers value quickly and preserves process isolation.
|
|
285
|
-
2. **Use Selesai's extension-first model as the differentiator:** custom tools, lifecycle hooks, prompt/context injection, subagents, workflows, and provider customization.
|
|
286
|
-
3. **Provide native approvals and diffs**, rather than exposing a terminal transcript inside a Webview.
|
|
287
|
-
4. **Add robust session restoration and workspace routing.** Selesai's RPC/session APIs already provide a good base.
|
|
288
|
-
5. **Add an authenticated HTTP/SSE server only when remote/multi-client requirements justify it.** Do not introduce a network daemon solely to imitate Kilo.
|
|
289
|
-
6. **Add MCP transport parity deliberately** if tool-server interoperability is a product requirement; keep MCP separate from the VS Code UI protocol.
|
|
290
|
-
|
|
291
|
-
### Final answer to the user's questions
|
|
292
|
-
|
|
293
|
-
- **Did Kilo connect using RPA?** No evidence. It uses VS Code APIs, Webview messages, a spawned local CLI backend, authenticated localhost HTTP/SSE, feature-specific WebSockets, and MCP for external tools.
|
|
294
|
-
- **Can Selesai connect through RPC?** Yes. Existing Selesai RPC is a strong local integration seam: strict JSONL over a private child process with typed commands/events and extension UI requests.
|
|
295
|
-
- **Can Selesai have a similar or better VS Code extension?** Yes. A local RPC-backed extension is straightforward and likely the right MVP. Selesai can exceed Kilo in extensibility and session/workflow customization, while Kilo currently has an advantage in mature VS Code UX, native terminal/PTY integration, backend HTTP/SSE, and polished multi-provider UI.
|
|
296
|
-
|
|
297
|
-
## Primary-source references
|
|
298
|
-
|
|
299
|
-
### Kilo Code
|
|
300
|
-
|
|
301
|
-
- [Extension activation](https://github.com/Kilo-Org/kilocode/blob/main/packages/kilo-vscode/src/extension.ts)
|
|
302
|
-
- [Kilo Webview provider](https://github.com/Kilo-Org/kilocode/blob/main/packages/kilo-vscode/src/KiloProvider.ts)
|
|
303
|
-
- [CLI server manager](https://github.com/Kilo-Org/kilocode/blob/main/packages/kilo-vscode/src/services/cli-backend/server-manager.ts)
|
|
304
|
-
- [Shared backend connection service](https://github.com/Kilo-Org/kilocode/blob/main/packages/kilo-vscode/src/services/cli-backend/connection-service.ts)
|
|
305
|
-
- [Backend server config](https://github.com/Kilo-Org/kilocode/blob/main/packages/kilo-vscode/src/services/cli-backend/types.ts)
|
|
306
|
-
- [MCP transports](https://github.com/Kilo-Org/kilocode/blob/main/packages/opencode/src/mcp/index.ts)
|
|
307
|
-
- [PTY WebSocket routing](https://github.com/Kilo-Org/kilocode/blob/main/packages/kilo-vscode/src/agent-manager/terminal-routing.ts)
|
|
308
|
-
- [PTY WebSocket manager](https://github.com/Kilo-Org/kilocode/blob/main/packages/kilo-vscode/src/agent-manager/terminal-manager.ts)
|
|
309
|
-
|
|
310
|
-
### Selesai Code
|
|
311
|
-
|
|
312
|
-
- [`docs/rpc.md`](../rpc.md)
|
|
313
|
-
- [`docs/sdk.md`](../sdk.md)
|
|
314
|
-
- [`docs/extensions.md`](../extensions.md)
|
|
315
|
-
- [`src/modes/rpc/rpc-mode.ts`](../../src/modes/rpc/rpc-mode.ts)
|
|
316
|
-
- [`src/modes/rpc/rpc-types.ts`](../../src/modes/rpc/rpc-types.ts)
|
|
317
|
-
- [`src/modes/rpc/rpc-client.ts`](../../src/modes/rpc/rpc-client.ts)
|
|
318
|
-
- [`src/core/sdk.ts`](../../src/core/sdk.ts)
|
|
319
|
-
- [`src/index.ts`](../../src/index.ts)
|