Skip to content

Commit ec5465f

Browse files
patrozagithub-actions[bot]
authored andcommitted
feat(vscode): introduce the VS Code integration overlay
1 parent 93900f7 commit ec5465f

32 files changed

Lines changed: 6173 additions & 0 deletions

.vscode/launch.json

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
{
2+
"version": "0.2.0",
3+
"configurations": [
4+
{
5+
"name": "Run T3 Code VS Code Extension",
6+
"type": "extensionHost",
7+
"request": "launch",
8+
"args": ["--extensionDevelopmentPath=${workspaceFolder}/apps/vscode"],
9+
"outFiles": ["${workspaceFolder}/apps/vscode/dist/**/*.cjs"],
10+
"preLaunchTask": "build-vscode-extension"
11+
}
12+
]
13+
}

apps/vscode/.vscodeignore

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
.vscode/**
2+
node_modules/**
3+
src/**
4+
tsconfig.json
5+
vite.config.*
6+
*.test.*

apps/vscode/README.md

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
# T3 Code for VS Code
2+
3+
This package exposes T3 Code as a dedicated VS Code secondary-sidebar chat tab, alongside the
4+
Claude Code, Chat, and Codex tabs. It connects directly to the same T3 Code server used by the web,
5+
desktop, and mobile clients, so projects, threads, messages, turn state, and assistant streaming
6+
remain synchronized. It also provides an optional native `@t3` participant inside VS Code Chat.
7+
8+
## Development
9+
10+
1. Start T3 Code (`pnpm dev`), which listens at `http://127.0.0.1:3773` by default.
11+
2. Build the extension with `pnpm --filter t3-code build`.
12+
3. Open this repository in VS Code, choose **Run Extension** from the Run and Debug view, and point
13+
the extension-development host at `apps/vscode` if prompted.
14+
4. Select the **T3 Code** tab in the secondary sidebar. Use **T3 Code: Open Chat** from the Command
15+
Palette if the secondary sidebar is hidden.
16+
17+
The extension first uses the backend advertised by the T3 Desktop runtime beside its extension
18+
host. This works independently in local, SSH, and other remote windows and avoids treating a
19+
synced `127.0.0.1` setting as the same machine. For a fallback backend, set `t3Code.serverUrl`.
20+
Remote servers can use **T3 Code: Set Server Bearer Token**; the token is stored in VS Code secret
21+
storage and exchanged for a short-lived WebSocket ticket.
22+
23+
## Dedicated chat workflow
24+
25+
The T3 Code tab contains a worktree-scoped thread picker, synchronized transcript, context control,
26+
and prompt composer. Select a thread to continue it on any T3 client, or use **+** to create one for
27+
the open worktree. Enter sends; Shift+Enter inserts a newline.
28+
29+
The same operations are also available through the optional native Chat participant:
30+
31+
- `@t3 /threads` selects an existing thread whose worktree matches the open workspace folder.
32+
- `@t3 /new` creates a synchronized thread (and a project when the folder is not registered yet).
33+
- A normal `@t3` prompt continues the last selected thread, or the most recently updated matching
34+
thread. If none exists, it creates one.
35+
- `@t3 /history`, `/status`, and `/stop` inspect or control the selected server thread.
36+
37+
Active editor context is included by default and can be toggled from the composer, with
38+
`@t3 /context`, or **T3 Code: Toggle Automatic Editor Context**. This preference is kept in VS Code's
39+
extension state and never written to workspace settings. A non-empty
40+
selection includes the exact character range; an empty selection includes the cursor line and
41+
column. Explicit Chat references such as `#file` and attached selections are always included.
42+
43+
The **T3 Code: Ask About Selection** editor action opens Chat with `@t3` prefilled. Context is sent
44+
as structured-looking provider context using workspace-relative paths and language-aware Markdown
45+
fences. T3 Code clients present that envelope as a context reference rather than authored text.

apps/vscode/media/t3-code.svg

Lines changed: 3 additions & 0 deletions
Loading

apps/vscode/package.json

Lines changed: 210 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,210 @@
1+
{
2+
"name": "t3-code",
3+
"displayName": "T3 Code",
4+
"version": "0.0.40",
5+
"private": true,
6+
"description": "A dedicated VS Code chat client for synchronized T3 Code threads.",
7+
"categories": [
8+
"AI",
9+
"Chat",
10+
"Other"
11+
],
12+
"publisher": "patroza",
13+
"type": "module",
14+
"main": "./dist/extension.cjs",
15+
"scripts": {
16+
"build": "esbuild src/extension.ts --bundle --platform=node --format=cjs --target=node20 --external:vscode --outfile=dist/extension.cjs && esbuild src/webview.ts --bundle --platform=browser --format=iife --target=es2022 --outfile=dist/webview.js",
17+
"typecheck": "tsgo --noEmit",
18+
"test": "vp test run"
19+
},
20+
"dependencies": {
21+
"@t3tools/client-runtime": "workspace:*",
22+
"@t3tools/contracts": "workspace:*",
23+
"@t3tools/shared": "workspace:*",
24+
"dompurify": "^3.2.6",
25+
"effect": "catalog:",
26+
"marked": "^15.0.12"
27+
},
28+
"devDependencies": {
29+
"@types/vscode": "1.95.0",
30+
"esbuild": "^0.28.0",
31+
"vite-plus": "catalog:"
32+
},
33+
"contributes": {
34+
"viewsContainers": {
35+
"activitybar": [
36+
{
37+
"id": "t3CodeViewContainer",
38+
"title": "T3 Code",
39+
"icon": "media/t3-code.svg",
40+
"when": "t3Code.useActivityBar"
41+
}
42+
],
43+
"secondarySidebar": [
44+
{
45+
"id": "t3CodeSecondaryViewContainer",
46+
"title": "T3 Code",
47+
"icon": "media/t3-code.svg",
48+
"when": "!t3Code.useActivityBar"
49+
}
50+
]
51+
},
52+
"views": {
53+
"t3CodeViewContainer": [
54+
{
55+
"id": "t3Code.chatView",
56+
"type": "webview",
57+
"name": "T3 Code",
58+
"when": "t3Code.useActivityBar"
59+
}
60+
],
61+
"t3CodeSecondaryViewContainer": [
62+
{
63+
"id": "t3Code.chatViewSecondary",
64+
"type": "webview",
65+
"name": "T3 Code",
66+
"when": "!t3Code.useActivityBar"
67+
}
68+
]
69+
},
70+
"chatParticipants": [
71+
{
72+
"id": "t3-code.chat",
73+
"name": "t3",
74+
"fullName": "T3 Code",
75+
"description": "Work with synchronized Codex, Claude, Cursor, Grok, and OpenCode threads.",
76+
"isSticky": true,
77+
"commands": [
78+
{
79+
"name": "new",
80+
"description": "Create a thread for this worktree"
81+
},
82+
{
83+
"name": "threads",
84+
"description": "Choose a thread for this worktree"
85+
},
86+
{
87+
"name": "history",
88+
"description": "Show the synchronized thread history"
89+
},
90+
{
91+
"name": "context",
92+
"description": "Toggle automatic editor context"
93+
},
94+
{
95+
"name": "stop",
96+
"description": "Interrupt the active turn"
97+
},
98+
{
99+
"name": "status",
100+
"description": "Show connection and thread status"
101+
}
102+
]
103+
}
104+
],
105+
"commands": [
106+
{
107+
"command": "t3Code.newThread",
108+
"title": "T3 Code: New Thread for Worktree",
109+
"category": "T3 Code"
110+
},
111+
{
112+
"command": "t3Code.selectThread",
113+
"title": "T3 Code: Select Worktree Thread",
114+
"category": "T3 Code"
115+
},
116+
{
117+
"command": "t3Code.askSelection",
118+
"title": "T3 Code: Ask About Selection",
119+
"category": "T3 Code",
120+
"icon": "$(comment-discussion)"
121+
},
122+
{
123+
"command": "t3Code.toggleEditorContext",
124+
"title": "T3 Code: Toggle Automatic Editor Context",
125+
"category": "T3 Code"
126+
},
127+
{
128+
"command": "t3Code.showDiagnostics",
129+
"title": "T3 Code: Show Diagnostics",
130+
"category": "T3 Code"
131+
},
132+
{
133+
"command": "t3Code.setBearerToken",
134+
"title": "T3 Code: Set Server Bearer Token",
135+
"category": "T3 Code"
136+
},
137+
{
138+
"command": "t3Code.clearBearerToken",
139+
"title": "T3 Code: Clear Server Bearer Token",
140+
"category": "T3 Code"
141+
},
142+
{
143+
"command": "t3Code.openChat",
144+
"title": "T3 Code: Open Chat",
145+
"category": "T3 Code"
146+
},
147+
{
148+
"command": "t3Code.openInT3",
149+
"title": "T3 Code: Open in T3",
150+
"category": "T3 Code",
151+
"icon": "$(link-external)"
152+
}
153+
],
154+
"menus": {
155+
"editor/context": [
156+
{
157+
"command": "t3Code.askSelection",
158+
"group": "navigation@90",
159+
"when": "editorHasSelection"
160+
}
161+
]
162+
},
163+
"configuration": {
164+
"title": "T3 Code",
165+
"properties": {
166+
"t3Code.serverUrl": {
167+
"type": "string",
168+
"scope": "machine",
169+
"default": "http://127.0.0.1:3773",
170+
"description": "Fallback T3 Code server HTTP URL when no local T3 Desktop runtime is advertised. WebSocket and environment endpoints are derived from it."
171+
},
172+
"t3Code.defaultRuntimeMode": {
173+
"type": "string",
174+
"enum": [
175+
"approval-required",
176+
"auto-accept-edits",
177+
"full-access"
178+
],
179+
"default": "full-access",
180+
"description": "Runtime mode for new T3 Code threads."
181+
},
182+
"t3Code.desktopClientSettingsPath": {
183+
"type": "string",
184+
"default": "",
185+
"description": "Optional path to T3 Desktop's client-settings.json for sharing provider and model favorites. The default auto-detects ~/.t3/userdata or ~/.t3/dev."
186+
}
187+
}
188+
}
189+
},
190+
"activationEvents": [
191+
"onChatParticipant:t3-code.chat",
192+
"onCommand:t3Code.askSelection",
193+
"onCommand:t3Code.clearBearerToken",
194+
"onCommand:t3Code.newThread",
195+
"onCommand:t3Code.openChat",
196+
"onCommand:t3Code.openInT3",
197+
"onCommand:t3Code.selectThread",
198+
"onCommand:t3Code.setBearerToken",
199+
"onCommand:t3Code.showDiagnostics",
200+
"onCommand:t3Code.toggleEditorContext",
201+
"onView:t3Code.chatView",
202+
"onView:t3Code.chatViewSecondary"
203+
],
204+
"extensionKind": [
205+
"workspace"
206+
],
207+
"engines": {
208+
"vscode": "^1.95.0"
209+
}
210+
}

0 commit comments

Comments
 (0)