vscode-pi-companion 0.2.0 → 0.2.2

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.
@@ -0,0 +1,15 @@
1
+ {
2
+ "branches": ["main"],
3
+ "plugins": [
4
+ "@semantic-release/commit-analyzer",
5
+ "@semantic-release/release-notes-generator",
6
+ [
7
+ "@semantic-release/github",
8
+ {
9
+ "successComment": false,
10
+ "failComment": false,
11
+ "releasedLabels": false
12
+ }
13
+ ]
14
+ ]
15
+ }
package/.vscodeignore CHANGED
@@ -12,3 +12,4 @@ tsconfig.json
12
12
  .envrc
13
13
  hooks/
14
14
  scripts/
15
+ test/
@@ -138,16 +138,24 @@ async function getLivePort(): Promise<number | undefined> {
138
138
  function updateWidget(): void {
139
139
  if (!currentCtx) return;
140
140
 
141
- if (!currentContext || !currentContext.workspaceState.openFiles.length) {
142
- // Show "Connected" only while waiting for file context, or "Disconnected" if not connected
143
- const status = isConnected ? "VS Code: Connected" : "VS Code: Disconnected";
144
- currentCtx.ui.setWidget("pi-companion", [status]);
141
+ if (!isConnected) {
142
+ currentCtx.ui.setWidget("pi-companion", ["vscode: disconnected"]);
143
+ return;
144
+ }
145
+
146
+ if (!currentContext) {
147
+ currentCtx.ui.setWidget("pi-companion", ["vscode: connected"]);
148
+ return;
149
+ }
150
+
151
+ if (!currentContext.workspaceState.openFiles.length) {
152
+ currentCtx.ui.setWidget("pi-companion", ["vscode: no files"]);
145
153
  return;
146
154
  }
147
155
 
148
156
  const { workspaceState } = currentContext;
149
- const lines: string[] = [];
150
- const activeFile = workspaceState.openFiles.find((f) => f.isActive);
157
+ const activeFile = workspaceState.openFiles.find((f) => f.isActive) || workspaceState.openFiles[0];
158
+ const filenames = workspaceState.openFiles.map((f) => f.path.split("/").pop() || f.path);
151
159
 
152
160
  if (activeFile) {
153
161
  const filename = activeFile.path.split("/").pop() || activeFile.path;
@@ -157,24 +165,14 @@ function updateWidget(): void {
157
165
  const end = activeFile.selectionEnd.line;
158
166
  location = start === end ? ` L${start}` : ` L${start}:${end}`;
159
167
  }
160
- lines.push(`📄 ${filename}${location}`);
161
- }
162
-
163
- const otherCount = workspaceState.openFiles.length - 1;
164
- if (otherCount > 0) {
165
- lines.push(` +${otherCount} more file${otherCount > 1 ? "s" : ""}`);
168
+ const label = filenames.length === 1
169
+ ? `${filename}${location}`
170
+ : `${filename}${location} +${filenames.length - 1}`;
171
+ currentCtx.ui.setWidget("pi-companion", [label]);
172
+ return;
166
173
  }
167
174
 
168
- const widgetKey = lines.join("|");
169
- if (widgetDebounceTimer) clearTimeout(widgetDebounceTimer);
170
-
171
- widgetDebounceTimer = setTimeout(() => {
172
- if (widgetKey !== lastWidgetKey) {
173
- lastWidgetKey = widgetKey;
174
- currentCtx!.ui.setWidget("pi-companion", lines);
175
- }
176
- widgetDebounceTimer = undefined;
177
- }, WIDGET_DEBOUNCE_MS);
175
+ currentCtx.ui.setWidget("pi-companion", [filenames.join(", ")]);
178
176
  }
179
177
 
180
178
  async function connectSSE(): Promise<void> {
@@ -224,6 +222,8 @@ async function connectSSE(): Promise<void> {
224
222
  }
225
223
 
226
224
  function scheduleReconnect(): void {
225
+ isConnected = false;
226
+ updateWidget();
227
227
  if (reconnectTimer || !currentCtx) return;
228
228
  reconnectTimer = setTimeout(() => {
229
229
  reconnectTimer = undefined;
@@ -272,6 +272,8 @@ export default function (pi: ExtensionAPI) {
272
272
  });
273
273
 
274
274
  pi.on("session_shutdown", async () => {
275
+ currentCtx = undefined;
276
+ isConnected = false;
275
277
  if (reconnectTimer) {
276
278
  clearTimeout(reconnectTimer);
277
279
  reconnectTimer = undefined;
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "displayName": "PI Companion",
4
4
  "description": "Share VS Code context with pi coding agent",
5
5
  "repository": "https://github.com/ravshansbox/vscode-pi-companion",
6
- "version": "0.2.0",
6
+ "version": "0.2.2",
7
7
  "publisher": "ravshansbox",
8
8
  "keywords": [
9
9
  "pi-package"
@@ -20,24 +20,25 @@
20
20
  "compile": "tsc -p ./",
21
21
  "watch": "tsc -watch -p ./",
22
22
  "package": "vsce package",
23
- "vscode:prepublish": "npm run compile"
23
+ "vscode:prepublish": "npm run compile",
24
+ "test": "node --import ./test/setup.mjs --test test/*.test.mjs"
24
25
  },
25
26
  "devDependencies": {
26
27
  "@types/cors": "^2.8.19",
27
28
  "@types/express": "^5.0.6",
28
- "@types/node": "^18.0.0",
29
+ "@types/node": "^26.6.5",
29
30
  "@types/vscode": "^1.85.0",
30
- "@types/ws": "^8.18.1",
31
- "@vscode/vsce": "^3.7.1",
32
- "esbuild": "^0.27.4",
33
- "typescript": "^5.0.0"
31
+ "@types/ws": "^8.18.2",
32
+ "@vscode/vsce": "^4.0.0",
33
+ "esbuild": "^0.28.2",
34
+ "typescript": "^7.0.2"
34
35
  },
35
36
  "dependencies": {
36
- "@modelcontextprotocol/sdk": "^1.0.0",
37
- "cors": "^2.8.5",
38
- "express": "^4.18.2",
39
- "ws": "^8.16.0",
40
- "zod": "^3.22.4"
37
+ "@modelcontextprotocol/sdk": "^1.32.1",
38
+ "cors": "^2.8.6",
39
+ "express": "^5.3.0",
40
+ "ws": "^8.22.0",
41
+ "zod": "^4.6.7"
41
42
  },
42
43
  "pi": {
43
44
  "extensions": [
package/src/ide-server.ts CHANGED
@@ -256,7 +256,7 @@ export class IDEServer {
256
256
  (server as any).tool(
257
257
  'read_file',
258
258
  'Read the contents of a file',
259
- { path: { type: 'string', description: 'Absolute path to the file' } },
259
+ { path: z.string().describe('Absolute path to the file') },
260
260
  async (args: { path: string }) => {
261
261
  try {
262
262
  const content = await fs.promises.readFile(args.path, 'utf-8');
@@ -287,9 +287,9 @@ export class IDEServer {
287
287
  'goto',
288
288
  'Open a file at a specific location',
289
289
  {
290
- path: { type: 'string', description: 'Absolute path to the file' },
291
- line: { type: 'number', description: 'Line number (1-based)' },
292
- character: { type: 'number', description: 'Character position (1-based)' },
290
+ path: z.string().describe('Absolute path to the file'),
291
+ line: z.number().optional().describe('Line number (1-based)'),
292
+ character: z.number().optional().describe('Character position (1-based)'),
293
293
  },
294
294
  async (args: { path: string; line?: number; character?: number }) => {
295
295
  try {
package/.mcp.json DELETED
@@ -1,7 +0,0 @@
1
- {
2
- "mcpServers": {
3
- "forge_extension": {
4
- "url": "http://localhost:15045/mcp"
5
- }
6
- }
7
- }
@@ -1,47 +0,0 @@
1
- #!/usr/bin/env bash
2
- set -euo pipefail
3
-
4
- version="${1:-}"
5
- if [[ -z "$version" ]]; then
6
- echo "Usage: ./scripts/release.sh <version>"
7
- exit 1
8
- fi
9
-
10
- if [[ -z "${VSCE_TOKEN:-}" ]]; then
11
- echo "VSCE_TOKEN is required"
12
- exit 1
13
- fi
14
-
15
- if ! command -v gh >/dev/null 2>&1; then
16
- echo "gh CLI is required"
17
- exit 1
18
- fi
19
-
20
- branch=$(git symbolic-ref --short HEAD 2>/dev/null || true)
21
- if [[ "$branch" != "main" ]]; then
22
- echo "Release must be run from main"
23
- exit 1
24
- fi
25
-
26
- if [[ -n "$(git status --porcelain)" ]]; then
27
- echo "Working tree must be clean"
28
- exit 1
29
- fi
30
-
31
- npm version "$version" --no-git-tag-version
32
- npm run compile
33
- npx vsce publish "$version" --pat "$VSCE_TOKEN" --skip-duplicate --no-git-tag-version
34
-
35
- git add package.json package-lock.json
36
- if ! git diff --cached --quiet; then
37
- git commit -m "$version"
38
- fi
39
-
40
- tag="v$version"
41
- git tag -f "$tag"
42
- git push origin main "$tag"
43
-
44
- gh release view "$tag" --repo ravshansbox/vscode-pi-companion >/dev/null 2>&1 || \
45
- gh release create "$tag" --repo ravshansbox/vscode-pi-companion --title "$tag" --generate-notes
46
-
47
- echo "Released $tag"