teamspec 3.2.0

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.
Files changed (45) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +252 -0
  3. package/bin/teamspec-init.js +10 -0
  4. package/extensions/teamspec-0.1.0.vsix +0 -0
  5. package/lib/cli.js +1174 -0
  6. package/lib/extension-installer.js +236 -0
  7. package/lib/linter.js +1184 -0
  8. package/lib/prompt-generator.js +409 -0
  9. package/package.json +51 -0
  10. package/teamspec-core/agents/AGENT_BA.md +486 -0
  11. package/teamspec-core/agents/AGENT_BOOTSTRAP.md +447 -0
  12. package/teamspec-core/agents/AGENT_DES.md +623 -0
  13. package/teamspec-core/agents/AGENT_DEV.md +611 -0
  14. package/teamspec-core/agents/AGENT_FA.md +736 -0
  15. package/teamspec-core/agents/AGENT_FEEDBACK.md +202 -0
  16. package/teamspec-core/agents/AGENT_FIX.md +380 -0
  17. package/teamspec-core/agents/AGENT_QA.md +756 -0
  18. package/teamspec-core/agents/AGENT_SA.md +581 -0
  19. package/teamspec-core/agents/AGENT_SM.md +771 -0
  20. package/teamspec-core/agents/README.md +383 -0
  21. package/teamspec-core/context/_schema.yml +222 -0
  22. package/teamspec-core/copilot-instructions.md +356 -0
  23. package/teamspec-core/definitions/definition-of-done.md +129 -0
  24. package/teamspec-core/definitions/definition-of-ready.md +104 -0
  25. package/teamspec-core/profiles/enterprise.yml +127 -0
  26. package/teamspec-core/profiles/platform-team.yml +104 -0
  27. package/teamspec-core/profiles/regulated.yml +97 -0
  28. package/teamspec-core/profiles/startup.yml +85 -0
  29. package/teamspec-core/teamspec.yml +69 -0
  30. package/teamspec-core/templates/README.md +211 -0
  31. package/teamspec-core/templates/active-sprint-template.md +98 -0
  32. package/teamspec-core/templates/adr-template.md +194 -0
  33. package/teamspec-core/templates/bug-report-template.md +188 -0
  34. package/teamspec-core/templates/business-analysis-template.md +164 -0
  35. package/teamspec-core/templates/decision-log-template.md +216 -0
  36. package/teamspec-core/templates/feature-template.md +269 -0
  37. package/teamspec-core/templates/functional-spec-template.md +161 -0
  38. package/teamspec-core/templates/refinement-notes-template.md +133 -0
  39. package/teamspec-core/templates/sprint-goal-template.md +129 -0
  40. package/teamspec-core/templates/sprint-template.md +175 -0
  41. package/teamspec-core/templates/sprints-index-template.md +67 -0
  42. package/teamspec-core/templates/story-template.md +244 -0
  43. package/teamspec-core/templates/storymap-template.md +204 -0
  44. package/teamspec-core/templates/testcases-template.md +147 -0
  45. package/teamspec-core/templates/uat-pack-template.md +161 -0
@@ -0,0 +1,236 @@
1
+ /**
2
+ * TeamSpec Extension Installer
3
+ *
4
+ * Handles installation of the TeamSpec VS Code extension.
5
+ * Used by the CLI during 'teamspec init --ide vscode' flow.
6
+ */
7
+
8
+ const fs = require('fs');
9
+ const path = require('path');
10
+ const { exec, execSync } = require('child_process');
11
+
12
+ // =============================================================================
13
+ // Constants
14
+ // =============================================================================
15
+
16
+ const EXTENSION_ID = 'teamspec.teamspec';
17
+ const EXTENSION_NAME = 'TeamSpec';
18
+
19
+ // =============================================================================
20
+ // Utilities
21
+ // =============================================================================
22
+
23
+ /**
24
+ * Check if VS Code CLI is available
25
+ */
26
+ function isVSCodeAvailable() {
27
+ try {
28
+ execSync('code --version', { stdio: 'ignore' });
29
+ return true;
30
+ } catch {
31
+ return false;
32
+ }
33
+ }
34
+
35
+ /**
36
+ * Check if the extension is already installed
37
+ */
38
+ function isExtensionInstalled() {
39
+ try {
40
+ const result = execSync('code --list-extensions', { encoding: 'utf-8' });
41
+ return result.toLowerCase().includes(EXTENSION_ID.toLowerCase());
42
+ } catch {
43
+ return false;
44
+ }
45
+ }
46
+
47
+ /**
48
+ * Get the path to the bundled VSIX file
49
+ */
50
+ function getBundledVsixPath() {
51
+ // Check for VSIX in the CLI package
52
+ const packageDir = path.join(__dirname, '..');
53
+ const vsixCandidates = [
54
+ path.join(packageDir, 'extensions', 'teamspec-0.1.0.vsix'),
55
+ path.join(packageDir, 'teamspec-0.1.0.vsix'),
56
+ path.join(__dirname, '..', '..', 'vscode-extension', 'teamspec-0.1.0.vsix'),
57
+ ];
58
+
59
+ for (const candidate of vsixCandidates) {
60
+ if (fs.existsSync(candidate)) {
61
+ return candidate;
62
+ }
63
+ }
64
+
65
+ return null;
66
+ }
67
+
68
+ /**
69
+ * Install extension from VSIX file
70
+ */
71
+ function installFromVsix(vsixPath) {
72
+ return new Promise((resolve, reject) => {
73
+ exec(`code --install-extension "${vsixPath}"`, (error, stdout, stderr) => {
74
+ if (error) {
75
+ reject(new Error(`Failed to install extension: ${stderr || error.message}`));
76
+ } else {
77
+ resolve(stdout);
78
+ }
79
+ });
80
+ });
81
+ }
82
+
83
+ /**
84
+ * Install extension from marketplace (future support)
85
+ */
86
+ function installFromMarketplace() {
87
+ return new Promise((resolve, reject) => {
88
+ exec(`code --install-extension ${EXTENSION_ID}`, (error, stdout, stderr) => {
89
+ if (error) {
90
+ // Marketplace install failed, extension may not be published yet
91
+ reject(new Error(`Failed to install from marketplace: ${stderr || error.message}`));
92
+ } else {
93
+ resolve(stdout);
94
+ }
95
+ });
96
+ });
97
+ }
98
+
99
+ // =============================================================================
100
+ // Main Installation Function
101
+ // =============================================================================
102
+
103
+ /**
104
+ * Install the TeamSpec VS Code extension
105
+ *
106
+ * @param {Object} options Installation options
107
+ * @param {boolean} options.force Force reinstall even if already installed
108
+ * @param {string} options.vsixPath Custom path to VSIX file
109
+ * @param {Function} options.onProgress Progress callback
110
+ * @returns {Promise<{success: boolean, message: string}>}
111
+ */
112
+ async function installExtension(options = {}) {
113
+ const { force = false, vsixPath = null, onProgress = () => {} } = options;
114
+
115
+ // Check VS Code availability
116
+ onProgress('Checking VS Code installation...');
117
+ if (!isVSCodeAvailable()) {
118
+ return {
119
+ success: false,
120
+ message: 'VS Code CLI not found. Please install VS Code and ensure "code" command is in PATH.',
121
+ hint: 'You can add VS Code to PATH via: Command Palette > "Shell Command: Install code command in PATH"'
122
+ };
123
+ }
124
+
125
+ // Check if already installed
126
+ if (!force && isExtensionInstalled()) {
127
+ return {
128
+ success: true,
129
+ message: 'TeamSpec extension is already installed.',
130
+ alreadyInstalled: true
131
+ };
132
+ }
133
+
134
+ // Try to find VSIX
135
+ const vsix = vsixPath || getBundledVsixPath();
136
+
137
+ if (vsix) {
138
+ // Install from bundled VSIX
139
+ onProgress(`Installing extension from ${path.basename(vsix)}...`);
140
+ try {
141
+ await installFromVsix(vsix);
142
+ return {
143
+ success: true,
144
+ message: 'TeamSpec extension installed successfully from local package.'
145
+ };
146
+ } catch (error) {
147
+ return {
148
+ success: false,
149
+ message: `Failed to install from VSIX: ${error.message}`,
150
+ error
151
+ };
152
+ }
153
+ } else {
154
+ // Try marketplace (may not be available yet)
155
+ onProgress('Installing extension from VS Code Marketplace...');
156
+ try {
157
+ await installFromMarketplace();
158
+ return {
159
+ success: true,
160
+ message: 'TeamSpec extension installed successfully from Marketplace.'
161
+ };
162
+ } catch (error) {
163
+ return {
164
+ success: false,
165
+ message: 'Extension not found in Marketplace and no local VSIX available.',
166
+ hint: 'Build the extension with: cd vscode-extension && npm run package',
167
+ error
168
+ };
169
+ }
170
+ }
171
+ }
172
+
173
+ /**
174
+ * Copy extension files to workspace for development/testing
175
+ */
176
+ function copyExtensionToWorkspace(targetDir, sourceExtensionDir) {
177
+ const vscodeDir = path.join(targetDir, '.vscode');
178
+ fs.mkdirSync(vscodeDir, { recursive: true });
179
+
180
+ // Create a settings.json with TeamSpec recommendations
181
+ const settingsPath = path.join(vscodeDir, 'settings.json');
182
+ let settings = {};
183
+
184
+ if (fs.existsSync(settingsPath)) {
185
+ try {
186
+ settings = JSON.parse(fs.readFileSync(settingsPath, 'utf-8'));
187
+ } catch {
188
+ // Ignore parse errors, start fresh
189
+ }
190
+ }
191
+
192
+ // Add TeamSpec settings
193
+ settings['teamspec.enforceGates'] = true;
194
+ settings['files.associations'] = settings['files.associations'] || {};
195
+ settings['files.associations']['*.teamspec'] = 'yaml';
196
+
197
+ fs.writeFileSync(settingsPath, JSON.stringify(settings, null, 2));
198
+
199
+ // Create extensions.json to recommend the extension
200
+ const extensionsPath = path.join(vscodeDir, 'extensions.json');
201
+ const extensions = {
202
+ recommendations: [EXTENSION_ID]
203
+ };
204
+
205
+ if (fs.existsSync(extensionsPath)) {
206
+ try {
207
+ const existing = JSON.parse(fs.readFileSync(extensionsPath, 'utf-8'));
208
+ if (existing.recommendations && !existing.recommendations.includes(EXTENSION_ID)) {
209
+ existing.recommendations.push(EXTENSION_ID);
210
+ }
211
+ extensions.recommendations = existing.recommendations || [EXTENSION_ID];
212
+ } catch {
213
+ // Ignore parse errors
214
+ }
215
+ }
216
+
217
+ fs.writeFileSync(extensionsPath, JSON.stringify(extensions, null, 2));
218
+
219
+ return {
220
+ settingsPath,
221
+ extensionsPath
222
+ };
223
+ }
224
+
225
+ // =============================================================================
226
+ // Exports
227
+ // =============================================================================
228
+
229
+ module.exports = {
230
+ installExtension,
231
+ copyExtensionToWorkspace,
232
+ isVSCodeAvailable,
233
+ isExtensionInstalled,
234
+ EXTENSION_ID,
235
+ EXTENSION_NAME
236
+ };