phantom-vscode 3.2.1

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,139 @@
1
+ import * as vscode from 'vscode';
2
+ import { spawn, ChildProcess } from 'child_process';
3
+ import * as path from 'path';
4
+
5
+ let dashboardProcess: ChildProcess | undefined;
6
+ let outputChannel: vscode.OutputChannel;
7
+
8
+ export function activate(context: vscode.ExtensionContext) {
9
+ outputChannel = vscode.window.createOutputChannel('Phantom');
10
+ outputChannel.appendLine('Phantom extension activating...');
11
+
12
+ // Register Dashboard View Provider
13
+ const provider = new PhantomDashboardProvider(context.extensionUri);
14
+ context.subscriptions.push(
15
+ vscode.window.registerWebviewViewProvider('phantom.dashboard', provider)
16
+ );
17
+
18
+ // Register Commands
19
+ context.subscriptions.push(
20
+ vscode.commands.registerCommand('phantom.dashboard.open', () => {
21
+ vscode.commands.executeCommand('workbench.view.extension.phantom-app');
22
+ })
23
+ );
24
+
25
+ context.subscriptions.push(
26
+ vscode.commands.registerCommand('phantom.prd.generate', async () => {
27
+ const title = await vscode.window.showInputBox({ prompt: 'Enter PRD Title' });
28
+ if (title) {
29
+ vscode.window.showInformationMessage(`Generating PRD: ${title}...`);
30
+ // Call CLI
31
+ const cliPath = getCliPath(context);
32
+ if (cliPath) {
33
+ runCliValues(cliPath, ['prd', 'generate', '--title', title]);
34
+ }
35
+ }
36
+ })
37
+ );
38
+
39
+ // Start Dashboard Server
40
+ startDashboardServer(context);
41
+ }
42
+
43
+ export function deactivate() {
44
+ if (dashboardProcess) {
45
+ outputChannel.appendLine('Stopping dashboard server...');
46
+ dashboardProcess.kill();
47
+ }
48
+ }
49
+
50
+ function getCliPath(context: vscode.ExtensionContext): string | undefined {
51
+ // Check bundled resource first
52
+ const bundledPath = context.asAbsolutePath(path.join('resources', 'phantom-cli.mjs'));
53
+ return bundledPath;
54
+ }
55
+
56
+ function startDashboardServer(context: vscode.ExtensionContext) {
57
+ const cliPath = getCliPath(context);
58
+ if (!cliPath) {
59
+ outputChannel.appendLine('Error: Could not find Phantom CLI');
60
+ return;
61
+ }
62
+
63
+ outputChannel.appendLine(`Starting dashboard from: ${cliPath}`);
64
+
65
+ // Spawn: node <cli> dashboard --port 3333
66
+ dashboardProcess = spawn('node', [cliPath, 'dashboard', '--port', '3333'], {
67
+ env: { ...process.env, PHANTOM_MCP_DEBUG: 'true' }
68
+ });
69
+
70
+ dashboardProcess.stdout?.on('data', (data) => {
71
+ outputChannel.append(`[Dashboard] ${data}`);
72
+ });
73
+
74
+ dashboardProcess.stderr?.on('data', (data) => {
75
+ outputChannel.append(`[Dashboard Error] ${data}`);
76
+ });
77
+
78
+ dashboardProcess.on('error', (err) => {
79
+ outputChannel.appendLine(`Failed to start dashboard: ${err.message}`);
80
+ vscode.window.showErrorMessage(`Phantom Dashboard failed to start: ${err.message}`);
81
+ });
82
+
83
+ dashboardProcess.on('exit', (code) => {
84
+ outputChannel.appendLine(`Dashboard process exited with code ${code}`);
85
+ });
86
+ }
87
+
88
+ function runCliValues(cliPath: string, args: string[]) {
89
+ outputChannel.appendLine(`Running CLI: ${args.join(' ')}`);
90
+ const proc = spawn('node', [cliPath, ...args]);
91
+
92
+ proc.stdout.on('data', d => outputChannel.append(d.toString()));
93
+ proc.stderr.on('data', d => outputChannel.append(d.toString()));
94
+
95
+ proc.on('close', code => {
96
+ if (code === 0) {
97
+ vscode.window.showInformationMessage('Phantom Task Completed');
98
+ } else {
99
+ vscode.window.showErrorMessage(`Phantom Task Failed (Exit ${code})`);
100
+ }
101
+ });
102
+ }
103
+
104
+ class PhantomDashboardProvider implements vscode.WebviewViewProvider {
105
+ constructor(private readonly _extensionUri: vscode.Uri) { }
106
+
107
+ public resolveWebviewView(
108
+ webviewView: vscode.WebviewView,
109
+ context: vscode.WebviewViewResolveContext,
110
+ _token: vscode.CancellationToken
111
+ ) {
112
+ webviewView.webview.options = {
113
+ enableScripts: true,
114
+ localResourceRoots: [this._extensionUri]
115
+ };
116
+
117
+ webviewView.webview.html = this._getHtmlForWebview(webviewView.webview);
118
+ }
119
+
120
+ private _getHtmlForWebview(webview: vscode.Webview) {
121
+ return `<!DOCTYPE html>
122
+ <html lang="en">
123
+ <head>
124
+ <meta charset="UTF-8">
125
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
126
+ <title>Phantom Dashboard</title>
127
+ <style>
128
+ body, html { margin: 0; padding: 0; height: 100%; overflow: hidden; background-color: var(--vscode-editor-background); }
129
+ iframe { width: 100%; height: 100%; border: none; }
130
+ .loading { display: flex; justify-content: center; align-items: center; height: 100%; color: var(--vscode-foreground); font-family: var(--vscode-font-family); }
131
+ </style>
132
+ </head>
133
+ <body>
134
+ <iframe src="http://localhost:3333" onload="this.style.visibility='visible'; document.getElementById('loading').style.display='none';"></iframe>
135
+ <div id="loading" class="loading">Loading Phantom Dashboard...</div>
136
+ </body>
137
+ </html>`;
138
+ }
139
+ }
package/tsconfig.json ADDED
@@ -0,0 +1,18 @@
1
+ {
2
+ "compilerOptions": {
3
+ "module": "commonjs",
4
+ "target": "es2020",
5
+ "outDir": "dist",
6
+ "lib": [
7
+ "es2020"
8
+ ],
9
+ "sourceMap": true,
10
+ "rootDir": "src",
11
+ "strict": true,
12
+ "skipLibCheck": true,
13
+ "types": [
14
+ "node",
15
+ "vscode"
16
+ ]
17
+ }
18
+ }