project-iris 0.1.2 → 0.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.
package/lib/installer.js CHANGED
@@ -2,6 +2,7 @@ const fs = require('fs-extra');
2
2
  const path = require('path');
3
3
  const prompts = require('prompts');
4
4
  const yaml = require('js-yaml');
5
+ const { execSync } = require('child_process');
5
6
  const CLIUtils = require('./cli-utils');
6
7
  const InstallerFactory = require('./InstallerFactory');
7
8
  const { FLOWS } = require('./constants');
@@ -67,6 +68,168 @@ async function detectTools() {
67
68
  return detected;
68
69
  }
69
70
 
71
+ // VS Code-based tools that can use the iris Dashboard extension
72
+ const VSCODE_TOOLS = ['claude', 'cursor', 'copilot', 'windsurf', 'cline', 'roo', 'antigravity'];
73
+
74
+ /**
75
+ * Find VS Code CLI executable
76
+ * @returns {string|null} Path to VS Code CLI or null if not found
77
+ */
78
+ function findVSCodeCLI() {
79
+ const platform = process.platform;
80
+
81
+ // Possible CLI paths by platform
82
+ const paths = [];
83
+
84
+ if (platform === 'darwin') {
85
+ // macOS - check common application locations
86
+ paths.push(
87
+ '/Applications/Visual Studio Code.app/Contents/Resources/app/bin/code',
88
+ '/Applications/Visual Studio Code - Insiders.app/Contents/Resources/app/bin/code',
89
+ `${process.env.HOME}/Applications/Visual Studio Code.app/Contents/Resources/app/bin/code`
90
+ );
91
+ } else if (platform === 'win32') {
92
+ // Windows
93
+ const localAppData = process.env.LOCALAPPDATA || '';
94
+ const programFiles = process.env['ProgramFiles'] || 'C:\\Program Files';
95
+ paths.push(
96
+ `${localAppData}\\Programs\\Microsoft VS Code\\bin\\code.cmd`,
97
+ `${programFiles}\\Microsoft VS Code\\bin\\code.cmd`
98
+ );
99
+ } else {
100
+ // Linux
101
+ paths.push(
102
+ '/usr/bin/code',
103
+ '/usr/local/bin/code',
104
+ '/snap/bin/code'
105
+ );
106
+ }
107
+
108
+ // Check each path
109
+ for (const p of paths) {
110
+ try {
111
+ if (fs.existsSync(p)) {
112
+ return p;
113
+ }
114
+ } catch {
115
+ // Ignore errors
116
+ }
117
+ }
118
+
119
+ // Fall back to trying 'code' from PATH
120
+ try {
121
+ execSync('which code || where code', { stdio: 'pipe' });
122
+ return 'code';
123
+ } catch {
124
+ return null;
125
+ }
126
+ }
127
+
128
+ /**
129
+ * Find Cursor CLI executable
130
+ * @returns {string|null} Path to Cursor CLI or null if not found
131
+ */
132
+ function findCursorCLI() {
133
+ const platform = process.platform;
134
+
135
+ const paths = [];
136
+
137
+ if (platform === 'darwin') {
138
+ paths.push(
139
+ '/Applications/Cursor.app/Contents/Resources/app/bin/cursor',
140
+ `${process.env.HOME}/Applications/Cursor.app/Contents/Resources/app/bin/cursor`
141
+ );
142
+ } else if (platform === 'win32') {
143
+ const localAppData = process.env.LOCALAPPDATA || '';
144
+ paths.push(
145
+ `${localAppData}\\Programs\\Cursor\\resources\\app\\bin\\cursor.cmd`
146
+ );
147
+ }
148
+
149
+ for (const p of paths) {
150
+ try {
151
+ if (fs.existsSync(p)) {
152
+ return p;
153
+ }
154
+ } catch {
155
+ // Ignore errors
156
+ }
157
+ }
158
+
159
+ try {
160
+ execSync('which cursor || where cursor', { stdio: 'pipe' });
161
+ return 'cursor';
162
+ } catch {
163
+ return null;
164
+ }
165
+ }
166
+
167
+ /**
168
+ * Install VS Code extension if any VS Code-based tool is selected
169
+ * @param {string[]} selectedToolKeys - Selected tool keys
170
+ * @returns {boolean} Whether extension was installed
171
+ */
172
+ async function installVSCodeExtension(selectedToolKeys) {
173
+ // Check if any VS Code-based tool is selected
174
+ const hasVSCodeTool = selectedToolKeys.some(key => VSCODE_TOOLS.includes(key));
175
+ if (!hasVSCodeTool) {
176
+ return false;
177
+ }
178
+
179
+ const extensionPath = path.join(__dirname, '..', 'extensions', 'iris-dashboard-0.0.1.vsix');
180
+
181
+ // Check if extension file exists
182
+ if (!await fs.pathExists(extensionPath)) {
183
+ console.log(theme.dim(' VS Code extension not found, skipping...'));
184
+ return false;
185
+ }
186
+
187
+ console.log(theme.dim(' Installing iris Dashboard VS Code extension...'));
188
+
189
+ let installed = false;
190
+
191
+ // Try VS Code
192
+ const vscodeCLI = findVSCodeCLI();
193
+ if (vscodeCLI) {
194
+ try {
195
+ execSync(`"${vscodeCLI}" --install-extension "${extensionPath}" --force`, {
196
+ stdio: 'pipe',
197
+ timeout: 60000,
198
+ shell: true
199
+ });
200
+ installed = true;
201
+ CLIUtils.displayStatus('', 'Installed iris Dashboard extension for VS Code', 'success');
202
+ } catch (err) {
203
+ console.log(theme.dim(` VS Code install failed: ${err.message}`));
204
+ }
205
+ }
206
+
207
+ // Try Cursor if selected
208
+ if (selectedToolKeys.includes('cursor')) {
209
+ const cursorCLI = findCursorCLI();
210
+ if (cursorCLI) {
211
+ try {
212
+ execSync(`"${cursorCLI}" --install-extension "${extensionPath}" --force`, {
213
+ stdio: 'pipe',
214
+ timeout: 60000,
215
+ shell: true
216
+ });
217
+ installed = true;
218
+ CLIUtils.displayStatus('', 'Installed iris Dashboard extension for Cursor', 'success');
219
+ } catch (err) {
220
+ console.log(theme.dim(` Cursor install failed: ${err.message}`));
221
+ }
222
+ }
223
+ }
224
+
225
+ if (!installed) {
226
+ console.log(theme.dim(' Could not auto-install extension. Install manually:'));
227
+ console.log(theme.dim(` code --install-extension "${extensionPath}"`));
228
+ }
229
+
230
+ return installed;
231
+ }
232
+
70
233
  async function install() {
71
234
  // Initialize analytics (respects opt-out env vars)
72
235
  analytics.init();
@@ -153,6 +316,9 @@ async function install() {
153
316
  try {
154
317
  const filesCreated = await installFlow(selectedFlow, selectedToolKeys);
155
318
 
319
+ // Install VS Code extension if applicable
320
+ await installVSCodeExtension(selectedToolKeys);
321
+
156
322
  // Track successful installation for each tool
157
323
  const durationMs = Date.now() - installStartTime;
158
324
  for (const toolKey of selectedToolKeys) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "project-iris",
3
- "version": "0.1.2",
3
+ "version": "0.2.1",
4
4
  "description": "Multi-agent orchestration system for AI-native software development. Delivers AI-DLC, Agile, and custom SDLC flows as markdown-based agent systems.",
5
5
  "main": "lib/installer.js",
6
6
  "bin": {
@@ -34,6 +34,7 @@
34
34
  },
35
35
  "files": [
36
36
  "bin/",
37
+ "extensions/",
37
38
  "flows/",
38
39
  "lib/",
39
40
  "scripts/",