specweave 0.3.13 → 0.4.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/CLAUDE.md +506 -17
- package/README.md +100 -58
- package/bin/install-all.sh +9 -2
- package/bin/install-hooks.sh +57 -0
- package/bin/specweave.js +16 -0
- package/dist/adapters/adapter-base.d.ts +21 -0
- package/dist/adapters/adapter-base.d.ts.map +1 -1
- package/dist/adapters/adapter-base.js +28 -0
- package/dist/adapters/adapter-base.js.map +1 -1
- package/dist/adapters/adapter-interface.d.ts +41 -0
- package/dist/adapters/adapter-interface.d.ts.map +1 -1
- package/dist/adapters/claude/adapter.d.ts +36 -0
- package/dist/adapters/claude/adapter.d.ts.map +1 -1
- package/dist/adapters/claude/adapter.js +135 -0
- package/dist/adapters/claude/adapter.js.map +1 -1
- package/dist/adapters/copilot/adapter.d.ts +25 -0
- package/dist/adapters/copilot/adapter.d.ts.map +1 -1
- package/dist/adapters/copilot/adapter.js +112 -0
- package/dist/adapters/copilot/adapter.js.map +1 -1
- package/dist/adapters/cursor/adapter.d.ts +36 -0
- package/dist/adapters/cursor/adapter.d.ts.map +1 -1
- package/dist/adapters/cursor/adapter.js +140 -0
- package/dist/adapters/cursor/adapter.js.map +1 -1
- package/dist/adapters/generic/adapter.d.ts +25 -0
- package/dist/adapters/generic/adapter.d.ts.map +1 -1
- package/dist/adapters/generic/adapter.js +111 -0
- package/dist/adapters/generic/adapter.js.map +1 -1
- package/dist/cli/commands/init.d.ts.map +1 -1
- package/dist/cli/commands/init.js +103 -1
- package/dist/cli/commands/init.js.map +1 -1
- package/dist/cli/commands/plugin.d.ts +37 -0
- package/dist/cli/commands/plugin.d.ts.map +1 -0
- package/dist/cli/commands/plugin.js +296 -0
- package/dist/cli/commands/plugin.js.map +1 -0
- package/dist/core/agent-model-manager.d.ts +52 -0
- package/dist/core/agent-model-manager.d.ts.map +1 -0
- package/dist/core/agent-model-manager.js +120 -0
- package/dist/core/agent-model-manager.js.map +1 -0
- package/dist/core/cost-tracker.d.ts +108 -0
- package/dist/core/cost-tracker.d.ts.map +1 -0
- package/dist/core/cost-tracker.js +281 -0
- package/dist/core/cost-tracker.js.map +1 -0
- package/dist/core/model-selector.d.ts +57 -0
- package/dist/core/model-selector.d.ts.map +1 -0
- package/dist/core/model-selector.js +115 -0
- package/dist/core/model-selector.js.map +1 -0
- package/dist/core/phase-detector.d.ts +62 -0
- package/dist/core/phase-detector.d.ts.map +1 -0
- package/dist/core/phase-detector.js +229 -0
- package/dist/core/phase-detector.js.map +1 -0
- package/dist/core/plugin-detector.d.ts +96 -0
- package/dist/core/plugin-detector.d.ts.map +1 -0
- package/dist/core/plugin-detector.js +349 -0
- package/dist/core/plugin-detector.js.map +1 -0
- package/dist/core/plugin-loader.d.ts +111 -0
- package/dist/core/plugin-loader.d.ts.map +1 -0
- package/dist/core/plugin-loader.js +319 -0
- package/dist/core/plugin-loader.js.map +1 -0
- package/dist/core/plugin-manager.d.ts +144 -0
- package/dist/core/plugin-manager.d.ts.map +1 -0
- package/dist/core/plugin-manager.js +393 -0
- package/dist/core/plugin-manager.js.map +1 -0
- package/dist/core/schemas/plugin-manifest.schema.json +253 -0
- package/dist/core/types/plugin.d.ts +252 -0
- package/dist/core/types/plugin.d.ts.map +1 -0
- package/dist/core/types/plugin.js +48 -0
- package/dist/core/types/plugin.js.map +1 -0
- package/dist/integrations/jira/jira-mapper.d.ts +2 -2
- package/dist/integrations/jira/jira-mapper.js +2 -2
- package/dist/types/cost-tracking.d.ts +43 -0
- package/dist/types/cost-tracking.d.ts.map +1 -0
- package/dist/types/cost-tracking.js +8 -0
- package/dist/types/cost-tracking.js.map +1 -0
- package/dist/types/model-selection.d.ts +53 -0
- package/dist/types/model-selection.d.ts.map +1 -0
- package/dist/types/model-selection.js +12 -0
- package/dist/types/model-selection.js.map +1 -0
- package/dist/utils/cost-reporter.d.ts +58 -0
- package/dist/utils/cost-reporter.d.ts.map +1 -0
- package/dist/utils/cost-reporter.js +224 -0
- package/dist/utils/cost-reporter.js.map +1 -0
- package/dist/utils/pricing-constants.d.ts +70 -0
- package/dist/utils/pricing-constants.d.ts.map +1 -0
- package/dist/utils/pricing-constants.js +71 -0
- package/dist/utils/pricing-constants.js.map +1 -0
- package/package.json +13 -9
- package/src/adapters/adapter-base.ts +33 -0
- package/src/adapters/adapter-interface.ts +46 -0
- package/src/adapters/claude/adapter.ts +164 -0
- package/src/adapters/copilot/adapter.ts +138 -0
- package/src/adapters/cursor/adapter.ts +170 -0
- package/src/adapters/generic/adapter.ts +137 -0
- package/src/agents/architect/AGENT.md +3 -0
- package/src/agents/code-reviewer.md +156 -0
- package/src/agents/data-scientist/AGENT.md +181 -0
- package/src/agents/database-optimizer/AGENT.md +147 -0
- package/src/agents/devops/AGENT.md +3 -0
- package/src/agents/diagrams-architect/AGENT.md +3 -0
- package/src/agents/docs-writer/AGENT.md +3 -0
- package/src/agents/kubernetes-architect/AGENT.md +142 -0
- package/src/agents/ml-engineer/AGENT.md +150 -0
- package/src/agents/mlops-engineer/AGENT.md +201 -0
- package/src/agents/network-engineer/AGENT.md +149 -0
- package/src/agents/observability-engineer/AGENT.md +213 -0
- package/src/agents/payment-integration/AGENT.md +35 -0
- package/src/agents/performance/AGENT.md +3 -0
- package/src/agents/performance-engineer/AGENT.md +153 -0
- package/src/agents/pm/AGENT.md +3 -0
- package/src/agents/qa-lead/AGENT.md +3 -0
- package/src/agents/security/AGENT.md +3 -0
- package/src/agents/sre/AGENT.md +3 -0
- package/src/agents/tdd-orchestrator/AGENT.md +169 -0
- package/src/agents/tech-lead/AGENT.md +3 -0
- package/src/commands/specweave.costs.md +261 -0
- package/src/commands/specweave.increment.md +48 -4
- package/src/commands/specweave.ml-pipeline.md +292 -0
- package/src/commands/specweave.monitor-setup.md +501 -0
- package/src/commands/specweave.slo-implement.md +1055 -0
- package/src/commands/specweave.sync-github.md +1 -1
- package/src/commands/specweave.tdd-cycle.md +199 -0
- package/src/commands/specweave.tdd-green.md +842 -0
- package/src/commands/specweave.tdd-red.md +135 -0
- package/src/commands/specweave.tdd-refactor.md +165 -0
- package/src/hooks/post-increment-plugin-detect.sh +142 -0
- package/src/hooks/post-task-completion.sh +53 -11
- package/src/hooks/pre-task-plugin-detect.sh +96 -0
- package/src/skills/SKILLS-INDEX.md +18 -10
- package/src/skills/billing-automation/SKILL.md +559 -0
- package/src/skills/distributed-tracing/SKILL.md +438 -0
- package/src/skills/e2e-playwright/README.md +1 -1
- package/src/skills/e2e-playwright/package.json +1 -1
- package/src/skills/gitops-workflow/SKILL.md +285 -0
- package/src/skills/gitops-workflow/references/argocd-setup.md +134 -0
- package/src/skills/gitops-workflow/references/sync-policies.md +131 -0
- package/src/skills/grafana-dashboards/SKILL.md +369 -0
- package/src/skills/helm-chart-scaffolding/SKILL.md +544 -0
- package/src/skills/helm-chart-scaffolding/assets/Chart.yaml.template +42 -0
- package/src/skills/helm-chart-scaffolding/assets/values.yaml.template +185 -0
- package/src/skills/helm-chart-scaffolding/references/chart-structure.md +500 -0
- package/src/skills/helm-chart-scaffolding/scripts/validate-chart.sh +244 -0
- package/src/skills/k8s-manifest-generator/SKILL.md +511 -0
- package/src/skills/k8s-manifest-generator/assets/configmap-template.yaml +296 -0
- package/src/skills/k8s-manifest-generator/assets/deployment-template.yaml +203 -0
- package/src/skills/k8s-manifest-generator/assets/service-template.yaml +171 -0
- package/src/skills/k8s-manifest-generator/references/deployment-spec.md +753 -0
- package/src/skills/k8s-manifest-generator/references/service-spec.md +724 -0
- package/src/skills/k8s-security-policies/SKILL.md +334 -0
- package/src/skills/k8s-security-policies/assets/network-policy-template.yaml +177 -0
- package/src/skills/k8s-security-policies/references/rbac-patterns.md +187 -0
- package/src/skills/ml-pipeline-workflow/SKILL.md +245 -0
- package/src/skills/paypal-integration/SKILL.md +467 -0
- package/src/skills/pci-compliance/SKILL.md +466 -0
- package/src/skills/prometheus-configuration/SKILL.md +392 -0
- package/src/skills/slo-implementation/SKILL.md +329 -0
- package/src/skills/stripe-integration/SKILL.md +442 -0
- package/src/skills/tdd-workflow/SKILL.md +378 -0
- package/src/templates/README.md.template +1 -1
- package/src/skills/bmad-method-expert/SKILL.md +0 -626
- package/src/skills/bmad-method-expert/scripts/analyze-project.js +0 -318
- package/src/skills/bmad-method-expert/scripts/check-setup.js +0 -208
- package/src/skills/bmad-method-expert/scripts/generate-template.js +0 -1149
- package/src/skills/bmad-method-expert/scripts/validate-documents.js +0 -340
- package/src/skills/context-optimizer/SKILL.md +0 -588
- package/src/skills/figma-designer/SKILL.md +0 -149
- package/src/skills/figma-implementer/SKILL.md +0 -148
- package/src/skills/figma-mcp-connector/SKILL.md +0 -136
- package/src/skills/figma-to-code/SKILL.md +0 -128
- package/src/skills/spec-kit-expert/SKILL.md +0 -1010
|
@@ -0,0 +1,393 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Plugin Manager
|
|
3
|
+
*
|
|
4
|
+
* Central orchestrator for plugin lifecycle management.
|
|
5
|
+
* Handles loading/unloading, dependency resolution, configuration management.
|
|
6
|
+
*
|
|
7
|
+
* @module core/plugin-manager
|
|
8
|
+
* @version 0.4.0
|
|
9
|
+
*/
|
|
10
|
+
import * as path from 'path';
|
|
11
|
+
import * as fs from 'fs-extra';
|
|
12
|
+
import * as yaml from 'js-yaml';
|
|
13
|
+
import { PluginLoader } from './plugin-loader.js';
|
|
14
|
+
import { PluginError, PluginDependencyError, PluginNotFoundError } from './types/plugin.js';
|
|
15
|
+
/**
|
|
16
|
+
* PluginManager - Manages plugin lifecycle and configuration
|
|
17
|
+
*/
|
|
18
|
+
export class PluginManager {
|
|
19
|
+
/**
|
|
20
|
+
* Create a new PluginManager
|
|
21
|
+
*
|
|
22
|
+
* @param projectPath - Path to project root
|
|
23
|
+
* @param pluginsDir - Path to plugins directory (default: src/plugins)
|
|
24
|
+
*/
|
|
25
|
+
constructor(projectPath = process.cwd(), pluginsDir) {
|
|
26
|
+
this.projectPath = projectPath;
|
|
27
|
+
this.loader = new PluginLoader();
|
|
28
|
+
this.configPath = path.join(projectPath, '.specweave', 'config.yaml');
|
|
29
|
+
this.pluginsDir = pluginsDir || path.join(projectPath, 'src', 'plugins');
|
|
30
|
+
this.loadedPlugins = new Map();
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Load (enable) a plugin
|
|
34
|
+
*
|
|
35
|
+
* 1. Load plugin from src/plugins/
|
|
36
|
+
* 2. Check dependencies
|
|
37
|
+
* 3. Install via adapter
|
|
38
|
+
* 4. Update config
|
|
39
|
+
*
|
|
40
|
+
* @param name - Plugin name (e.g., "github", "kubernetes")
|
|
41
|
+
* @param adapter - Adapter to use for installation
|
|
42
|
+
* @param options - Load options
|
|
43
|
+
*/
|
|
44
|
+
async loadPlugin(name, adapter, options = {}) {
|
|
45
|
+
console.log(`\n📦 Loading plugin: ${name}...`);
|
|
46
|
+
// Check if already loaded
|
|
47
|
+
if (this.loadedPlugins.has(name) && !options.force) {
|
|
48
|
+
console.log(`ℹ️ Plugin ${name} already loaded`);
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
// Load plugin from disk
|
|
52
|
+
const pluginPath = path.join(this.pluginsDir, name);
|
|
53
|
+
const plugin = await this.loader.loadFromDirectory(pluginPath);
|
|
54
|
+
// Validate plugin integrity
|
|
55
|
+
if (options.validate !== false) {
|
|
56
|
+
const isValid = await this.loader.verifyPlugin(plugin);
|
|
57
|
+
if (!isValid) {
|
|
58
|
+
throw new PluginError(`Plugin ${name} failed integrity check`, name);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
// Check dependencies
|
|
62
|
+
if (!options.skipDependencies) {
|
|
63
|
+
await this.checkDependencies(plugin);
|
|
64
|
+
}
|
|
65
|
+
// Install via adapter
|
|
66
|
+
console.log(`📋 Installing ${name} via ${adapter.name} adapter...`);
|
|
67
|
+
if (adapter.supportsPlugins && adapter.supportsPlugins()) {
|
|
68
|
+
await adapter.compilePlugin(plugin);
|
|
69
|
+
}
|
|
70
|
+
else {
|
|
71
|
+
console.warn(`⚠️ Adapter ${adapter.name} does not support plugins`);
|
|
72
|
+
throw new PluginError(`Adapter ${adapter.name} does not support plugins`, name, 'ADAPTER_NOT_SUPPORTED');
|
|
73
|
+
}
|
|
74
|
+
// Update config
|
|
75
|
+
await this.updateConfig(name, 'enable');
|
|
76
|
+
// Cache loaded plugin
|
|
77
|
+
this.loadedPlugins.set(name, plugin);
|
|
78
|
+
console.log(`✅ Plugin ${name} loaded successfully!`);
|
|
79
|
+
console.log(` - ${plugin.skills.length} skills`);
|
|
80
|
+
console.log(` - ${plugin.agents.length} agents`);
|
|
81
|
+
console.log(` - ${plugin.commands.length} commands`);
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Unload (disable) a plugin
|
|
85
|
+
*
|
|
86
|
+
* @param name - Plugin name
|
|
87
|
+
* @param adapter - Adapter to use for uninstallation
|
|
88
|
+
* @param options - Unload options
|
|
89
|
+
*/
|
|
90
|
+
async unloadPlugin(name, adapter, options = {}) {
|
|
91
|
+
console.log(`\n🗑️ Unloading plugin: ${name}...`);
|
|
92
|
+
// Check if plugin is loaded
|
|
93
|
+
if (!this.loadedPlugins.has(name)) {
|
|
94
|
+
console.log(`ℹ️ Plugin ${name} not loaded`);
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
97
|
+
// Check if other plugins depend on this one
|
|
98
|
+
if (!options.force) {
|
|
99
|
+
const dependents = await this.getDependents(name);
|
|
100
|
+
if (dependents.length > 0) {
|
|
101
|
+
throw new PluginDependencyError(`Cannot unload ${name}: Required by ${dependents.join(', ')}`, name);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
// Uninstall via adapter
|
|
105
|
+
if (adapter.supportsPlugins && adapter.supportsPlugins()) {
|
|
106
|
+
await adapter.unloadPlugin(name);
|
|
107
|
+
}
|
|
108
|
+
// Update config
|
|
109
|
+
await this.updateConfig(name, 'disable');
|
|
110
|
+
// Remove from cache
|
|
111
|
+
this.loadedPlugins.delete(name);
|
|
112
|
+
console.log(`✅ Plugin ${name} unloaded`);
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Get all available plugins (scan src/plugins/)
|
|
116
|
+
*
|
|
117
|
+
* @returns Array of plugin info
|
|
118
|
+
*/
|
|
119
|
+
async getAvailablePlugins() {
|
|
120
|
+
const plugins = [];
|
|
121
|
+
// Check if plugins directory exists
|
|
122
|
+
if (!(await fs.pathExists(this.pluginsDir))) {
|
|
123
|
+
return plugins;
|
|
124
|
+
}
|
|
125
|
+
// Get enabled plugins from config
|
|
126
|
+
const enabledPlugins = await this.getEnabledPlugins();
|
|
127
|
+
// Scan plugins directory
|
|
128
|
+
const dirs = await fs.readdir(this.pluginsDir);
|
|
129
|
+
for (const dir of dirs) {
|
|
130
|
+
const pluginPath = path.join(this.pluginsDir, dir);
|
|
131
|
+
const stat = await fs.stat(pluginPath);
|
|
132
|
+
if (stat.isDirectory()) {
|
|
133
|
+
try {
|
|
134
|
+
const metadata = await this.loader.getMetadata(pluginPath);
|
|
135
|
+
plugins.push({
|
|
136
|
+
name: dir,
|
|
137
|
+
version: metadata.version,
|
|
138
|
+
description: metadata.description,
|
|
139
|
+
path: pluginPath,
|
|
140
|
+
enabled: enabledPlugins.includes(dir),
|
|
141
|
+
skillCount: metadata.skillCount,
|
|
142
|
+
agentCount: metadata.agentCount,
|
|
143
|
+
commandCount: metadata.commandCount
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
catch (error) {
|
|
147
|
+
console.warn(`⚠️ Failed to load metadata for ${dir}: ${error.message}`);
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
return plugins;
|
|
152
|
+
}
|
|
153
|
+
/**
|
|
154
|
+
* Get enabled plugins from config
|
|
155
|
+
*
|
|
156
|
+
* @returns Array of enabled plugin names
|
|
157
|
+
*/
|
|
158
|
+
async getEnabledPlugins() {
|
|
159
|
+
const config = await this.loadConfig();
|
|
160
|
+
return config.enabled || [];
|
|
161
|
+
}
|
|
162
|
+
/**
|
|
163
|
+
* Check if a plugin is enabled
|
|
164
|
+
*
|
|
165
|
+
* @param name - Plugin name
|
|
166
|
+
* @returns True if enabled
|
|
167
|
+
*/
|
|
168
|
+
async isPluginEnabled(name) {
|
|
169
|
+
const enabled = await this.getEnabledPlugins();
|
|
170
|
+
return enabled.includes(name);
|
|
171
|
+
}
|
|
172
|
+
/**
|
|
173
|
+
* Update plugin configuration
|
|
174
|
+
*
|
|
175
|
+
* @param name - Plugin name
|
|
176
|
+
* @param action - 'enable' or 'disable'
|
|
177
|
+
*/
|
|
178
|
+
async updateConfig(name, action) {
|
|
179
|
+
const config = await this.loadConfig();
|
|
180
|
+
if (action === 'enable') {
|
|
181
|
+
if (!config.enabled.includes(name)) {
|
|
182
|
+
config.enabled.push(name);
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
else {
|
|
186
|
+
config.enabled = config.enabled.filter(p => p !== name);
|
|
187
|
+
}
|
|
188
|
+
await this.saveConfig(config);
|
|
189
|
+
}
|
|
190
|
+
/**
|
|
191
|
+
* Load plugin configuration from .specweave/config.yaml
|
|
192
|
+
*
|
|
193
|
+
* @returns Plugin configuration
|
|
194
|
+
*/
|
|
195
|
+
async loadConfig() {
|
|
196
|
+
// Ensure config directory exists
|
|
197
|
+
const configDir = path.dirname(this.configPath);
|
|
198
|
+
await fs.ensureDir(configDir);
|
|
199
|
+
// Check if config file exists
|
|
200
|
+
if (!(await fs.pathExists(this.configPath))) {
|
|
201
|
+
// Create default config
|
|
202
|
+
const defaultConfig = {
|
|
203
|
+
enabled: [],
|
|
204
|
+
settings: {}
|
|
205
|
+
};
|
|
206
|
+
await this.saveConfig(defaultConfig);
|
|
207
|
+
return defaultConfig;
|
|
208
|
+
}
|
|
209
|
+
// Read and parse config
|
|
210
|
+
const content = await fs.readFile(this.configPath, 'utf-8');
|
|
211
|
+
const config = yaml.load(content);
|
|
212
|
+
// Ensure plugins section exists
|
|
213
|
+
if (!config.plugins) {
|
|
214
|
+
config.plugins = { enabled: [], settings: {} };
|
|
215
|
+
}
|
|
216
|
+
return config.plugins;
|
|
217
|
+
}
|
|
218
|
+
/**
|
|
219
|
+
* Save plugin configuration to .specweave/config.yaml
|
|
220
|
+
*
|
|
221
|
+
* @param pluginConfig - Plugin configuration to save
|
|
222
|
+
*/
|
|
223
|
+
async saveConfig(pluginConfig) {
|
|
224
|
+
// Read full config (if exists)
|
|
225
|
+
let fullConfig = {};
|
|
226
|
+
if (await fs.pathExists(this.configPath)) {
|
|
227
|
+
const content = await fs.readFile(this.configPath, 'utf-8');
|
|
228
|
+
fullConfig = yaml.load(content) || {};
|
|
229
|
+
}
|
|
230
|
+
// Update plugins section
|
|
231
|
+
fullConfig.plugins = pluginConfig;
|
|
232
|
+
// Write back
|
|
233
|
+
const yamlContent = yaml.dump(fullConfig, { indent: 2 });
|
|
234
|
+
await fs.writeFile(this.configPath, yamlContent, 'utf-8');
|
|
235
|
+
}
|
|
236
|
+
/**
|
|
237
|
+
* Check plugin dependencies
|
|
238
|
+
*
|
|
239
|
+
* Ensures all required plugins are loaded
|
|
240
|
+
*
|
|
241
|
+
* @param plugin - Plugin to check
|
|
242
|
+
* @throws PluginDependencyError if dependencies are not met
|
|
243
|
+
*/
|
|
244
|
+
async checkDependencies(plugin) {
|
|
245
|
+
const { dependencies } = plugin.manifest;
|
|
246
|
+
if (!dependencies || !dependencies.plugins) {
|
|
247
|
+
return; // No dependencies
|
|
248
|
+
}
|
|
249
|
+
const enabledPlugins = await this.getEnabledPlugins();
|
|
250
|
+
const missingDeps = [];
|
|
251
|
+
for (const depName of dependencies.plugins) {
|
|
252
|
+
if (!enabledPlugins.includes(depName)) {
|
|
253
|
+
missingDeps.push(depName);
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
if (missingDeps.length > 0) {
|
|
257
|
+
throw new PluginDependencyError(`Plugin ${plugin.manifest.name} requires: ${missingDeps.join(', ')}`, plugin.manifest.name);
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
/**
|
|
261
|
+
* Resolve dependency graph for a plugin
|
|
262
|
+
*
|
|
263
|
+
* Returns all plugins that need to be loaded (including transitive deps)
|
|
264
|
+
*
|
|
265
|
+
* @param plugin - Plugin to resolve
|
|
266
|
+
* @returns Array of plugins in load order
|
|
267
|
+
*/
|
|
268
|
+
async resolveDependencies(plugin) {
|
|
269
|
+
const resolved = [];
|
|
270
|
+
const visited = new Set();
|
|
271
|
+
const resolve = async (p) => {
|
|
272
|
+
if (visited.has(p.manifest.name)) {
|
|
273
|
+
return; // Already processed
|
|
274
|
+
}
|
|
275
|
+
visited.add(p.manifest.name);
|
|
276
|
+
// Resolve dependencies first
|
|
277
|
+
if (p.manifest.dependencies?.plugins) {
|
|
278
|
+
for (const depName of p.manifest.dependencies.plugins) {
|
|
279
|
+
const depPath = path.join(this.pluginsDir, depName);
|
|
280
|
+
const depPlugin = await this.loader.loadFromDirectory(depPath);
|
|
281
|
+
await resolve(depPlugin);
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
// Add this plugin
|
|
285
|
+
resolved.push(p);
|
|
286
|
+
};
|
|
287
|
+
await resolve(plugin);
|
|
288
|
+
return resolved;
|
|
289
|
+
}
|
|
290
|
+
/**
|
|
291
|
+
* Get plugins that depend on a given plugin
|
|
292
|
+
*
|
|
293
|
+
* @param name - Plugin name
|
|
294
|
+
* @returns Array of dependent plugin names
|
|
295
|
+
*/
|
|
296
|
+
async getDependents(name) {
|
|
297
|
+
const dependents = [];
|
|
298
|
+
const availablePlugins = await this.getAvailablePlugins();
|
|
299
|
+
for (const info of availablePlugins) {
|
|
300
|
+
if (info.enabled) {
|
|
301
|
+
const plugin = await this.loader.loadFromDirectory(info.path);
|
|
302
|
+
if (plugin.manifest.dependencies?.plugins?.includes(name)) {
|
|
303
|
+
dependents.push(info.name);
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
return dependents;
|
|
308
|
+
}
|
|
309
|
+
/**
|
|
310
|
+
* Validate plugin configuration
|
|
311
|
+
*
|
|
312
|
+
* Checks for circular dependencies, missing plugins, etc.
|
|
313
|
+
*
|
|
314
|
+
* @returns Validation result
|
|
315
|
+
*/
|
|
316
|
+
async validateConfig() {
|
|
317
|
+
const errors = [];
|
|
318
|
+
const enabledPlugins = await this.getEnabledPlugins();
|
|
319
|
+
// Check if all enabled plugins exist
|
|
320
|
+
for (const name of enabledPlugins) {
|
|
321
|
+
const pluginPath = path.join(this.pluginsDir, name);
|
|
322
|
+
if (!(await fs.pathExists(pluginPath))) {
|
|
323
|
+
errors.push(`Enabled plugin '${name}' not found at ${pluginPath}`);
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
// Check for circular dependencies
|
|
327
|
+
const visited = new Set();
|
|
328
|
+
const recursionStack = new Set();
|
|
329
|
+
const hasCycle = async (name) => {
|
|
330
|
+
visited.add(name);
|
|
331
|
+
recursionStack.add(name);
|
|
332
|
+
const pluginPath = path.join(this.pluginsDir, name);
|
|
333
|
+
if (!(await fs.pathExists(pluginPath))) {
|
|
334
|
+
return false;
|
|
335
|
+
}
|
|
336
|
+
const plugin = await this.loader.loadFromDirectory(pluginPath);
|
|
337
|
+
const deps = plugin.manifest.dependencies?.plugins || [];
|
|
338
|
+
for (const dep of deps) {
|
|
339
|
+
if (!visited.has(dep)) {
|
|
340
|
+
if (await hasCycle(dep)) {
|
|
341
|
+
return true;
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
else if (recursionStack.has(dep)) {
|
|
345
|
+
errors.push(`Circular dependency detected: ${name} → ${dep}`);
|
|
346
|
+
return true;
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
recursionStack.delete(name);
|
|
350
|
+
return false;
|
|
351
|
+
};
|
|
352
|
+
for (const name of enabledPlugins) {
|
|
353
|
+
if (!visited.has(name)) {
|
|
354
|
+
await hasCycle(name);
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
return {
|
|
358
|
+
valid: errors.length === 0,
|
|
359
|
+
errors
|
|
360
|
+
};
|
|
361
|
+
}
|
|
362
|
+
/**
|
|
363
|
+
* Get plugin by name
|
|
364
|
+
*
|
|
365
|
+
* @param name - Plugin name
|
|
366
|
+
* @returns Loaded plugin
|
|
367
|
+
* @throws PluginNotFoundError if plugin is not loaded
|
|
368
|
+
*/
|
|
369
|
+
getPlugin(name) {
|
|
370
|
+
const plugin = this.loadedPlugins.get(name);
|
|
371
|
+
if (!plugin) {
|
|
372
|
+
throw new PluginNotFoundError(name);
|
|
373
|
+
}
|
|
374
|
+
return plugin;
|
|
375
|
+
}
|
|
376
|
+
/**
|
|
377
|
+
* Get all loaded plugins
|
|
378
|
+
*
|
|
379
|
+
* @returns Map of loaded plugins
|
|
380
|
+
*/
|
|
381
|
+
getLoadedPlugins() {
|
|
382
|
+
return this.loadedPlugins;
|
|
383
|
+
}
|
|
384
|
+
/**
|
|
385
|
+
* Clear loaded plugins cache
|
|
386
|
+
*
|
|
387
|
+
* Useful for testing or forcing reload
|
|
388
|
+
*/
|
|
389
|
+
clearCache() {
|
|
390
|
+
this.loadedPlugins.clear();
|
|
391
|
+
}
|
|
392
|
+
}
|
|
393
|
+
//# sourceMappingURL=plugin-manager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plugin-manager.js","sourceRoot":"","sources":["../../src/core/plugin-manager.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,253 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
3
|
+
"$id": "https://spec-weave.com/schemas/plugin-manifest.json",
|
|
4
|
+
"title": "SpecWeave Plugin Manifest",
|
|
5
|
+
"description": "Schema for SpecWeave plugin manifest.json files",
|
|
6
|
+
"type": "object",
|
|
7
|
+
"required": ["name", "version", "description", "specweave_core_version", "provides"],
|
|
8
|
+
"properties": {
|
|
9
|
+
"name": {
|
|
10
|
+
"type": "string",
|
|
11
|
+
"pattern": "^specweave-[a-z0-9-]+$",
|
|
12
|
+
"minLength": 11,
|
|
13
|
+
"maxLength": 64,
|
|
14
|
+
"description": "Unique plugin name (must start with 'specweave-')",
|
|
15
|
+
"examples": ["specweave-kubernetes", "specweave-github", "specweave-ml-ops"]
|
|
16
|
+
},
|
|
17
|
+
"version": {
|
|
18
|
+
"type": "string",
|
|
19
|
+
"pattern": "^\\d+\\.\\d+\\.\\d+(-[a-z0-9.-]+)?(\\+[a-z0-9.-]+)?$",
|
|
20
|
+
"description": "Semantic version (e.g., '1.0.0', '2.1.3-beta.1')",
|
|
21
|
+
"examples": ["1.0.0", "2.1.3-beta.1", "0.4.0"]
|
|
22
|
+
},
|
|
23
|
+
"description": {
|
|
24
|
+
"type": "string",
|
|
25
|
+
"minLength": 10,
|
|
26
|
+
"maxLength": 1024,
|
|
27
|
+
"description": "Human-readable description of what this plugin does"
|
|
28
|
+
},
|
|
29
|
+
"author": {
|
|
30
|
+
"type": "string",
|
|
31
|
+
"maxLength": 256,
|
|
32
|
+
"description": "Plugin author name or organization"
|
|
33
|
+
},
|
|
34
|
+
"license": {
|
|
35
|
+
"type": "string",
|
|
36
|
+
"enum": ["MIT", "Apache-2.0", "BSD-3-Clause", "ISC", "GPL-3.0", "LGPL-3.0", "MPL-2.0", "Unlicense"],
|
|
37
|
+
"description": "SPDX license identifier"
|
|
38
|
+
},
|
|
39
|
+
"specweave_core_version": {
|
|
40
|
+
"type": "string",
|
|
41
|
+
"pattern": "^[><=~^]+\\d+\\.\\d+\\.\\d+$",
|
|
42
|
+
"description": "Required SpecWeave core version (e.g., '>=0.4.0', '~0.4.0', '^0.4.0')",
|
|
43
|
+
"examples": [">=0.4.0", "~0.4.0", "^0.4.0"]
|
|
44
|
+
},
|
|
45
|
+
"dependencies": {
|
|
46
|
+
"type": "object",
|
|
47
|
+
"properties": {
|
|
48
|
+
"plugins": {
|
|
49
|
+
"type": "array",
|
|
50
|
+
"items": {
|
|
51
|
+
"type": "string",
|
|
52
|
+
"pattern": "^specweave-[a-z0-9-]+$"
|
|
53
|
+
},
|
|
54
|
+
"uniqueItems": true,
|
|
55
|
+
"description": "Other plugins this plugin requires"
|
|
56
|
+
}
|
|
57
|
+
},
|
|
58
|
+
"additionalProperties": false
|
|
59
|
+
},
|
|
60
|
+
"auto_detect": {
|
|
61
|
+
"type": "object",
|
|
62
|
+
"properties": {
|
|
63
|
+
"files": {
|
|
64
|
+
"type": "array",
|
|
65
|
+
"items": {
|
|
66
|
+
"type": "string",
|
|
67
|
+
"minLength": 1
|
|
68
|
+
},
|
|
69
|
+
"uniqueItems": true,
|
|
70
|
+
"description": "File or directory patterns to detect (e.g., 'kubernetes/', '.git/')"
|
|
71
|
+
},
|
|
72
|
+
"packages": {
|
|
73
|
+
"type": "array",
|
|
74
|
+
"items": {
|
|
75
|
+
"type": "string",
|
|
76
|
+
"minLength": 1
|
|
77
|
+
},
|
|
78
|
+
"uniqueItems": true,
|
|
79
|
+
"description": "NPM package dependencies to detect (from package.json)"
|
|
80
|
+
},
|
|
81
|
+
"env_vars": {
|
|
82
|
+
"type": "array",
|
|
83
|
+
"items": {
|
|
84
|
+
"type": "string",
|
|
85
|
+
"pattern": "^[A-Z][A-Z0-9_]*$"
|
|
86
|
+
},
|
|
87
|
+
"uniqueItems": true,
|
|
88
|
+
"description": "Environment variables to detect"
|
|
89
|
+
},
|
|
90
|
+
"git_remote_pattern": {
|
|
91
|
+
"type": "string",
|
|
92
|
+
"minLength": 1,
|
|
93
|
+
"description": "Regex pattern to match against git remote URL (e.g., 'github\\.com')"
|
|
94
|
+
}
|
|
95
|
+
},
|
|
96
|
+
"additionalProperties": false
|
|
97
|
+
},
|
|
98
|
+
"provides": {
|
|
99
|
+
"type": "object",
|
|
100
|
+
"required": ["skills", "agents", "commands"],
|
|
101
|
+
"properties": {
|
|
102
|
+
"skills": {
|
|
103
|
+
"type": "array",
|
|
104
|
+
"items": {
|
|
105
|
+
"type": "string",
|
|
106
|
+
"pattern": "^[a-z0-9-]+$",
|
|
107
|
+
"minLength": 1
|
|
108
|
+
},
|
|
109
|
+
"uniqueItems": true,
|
|
110
|
+
"description": "Skill names provided by this plugin"
|
|
111
|
+
},
|
|
112
|
+
"agents": {
|
|
113
|
+
"type": "array",
|
|
114
|
+
"items": {
|
|
115
|
+
"type": "string",
|
|
116
|
+
"pattern": "^[a-z0-9-]+$",
|
|
117
|
+
"minLength": 1
|
|
118
|
+
},
|
|
119
|
+
"uniqueItems": true,
|
|
120
|
+
"description": "Agent names provided by this plugin"
|
|
121
|
+
},
|
|
122
|
+
"commands": {
|
|
123
|
+
"type": "array",
|
|
124
|
+
"items": {
|
|
125
|
+
"type": "string",
|
|
126
|
+
"pattern": "^specweave\\.[a-z0-9-.]+$",
|
|
127
|
+
"minLength": 11
|
|
128
|
+
},
|
|
129
|
+
"uniqueItems": true,
|
|
130
|
+
"description": "Command names provided by this plugin (must start with 'specweave.')"
|
|
131
|
+
}
|
|
132
|
+
},
|
|
133
|
+
"additionalProperties": false
|
|
134
|
+
},
|
|
135
|
+
"triggers": {
|
|
136
|
+
"type": "array",
|
|
137
|
+
"items": {
|
|
138
|
+
"type": "string",
|
|
139
|
+
"minLength": 2
|
|
140
|
+
},
|
|
141
|
+
"uniqueItems": true,
|
|
142
|
+
"description": "Keywords that trigger plugin suggestions in specs/tasks"
|
|
143
|
+
},
|
|
144
|
+
"credits": {
|
|
145
|
+
"type": "object",
|
|
146
|
+
"properties": {
|
|
147
|
+
"based_on": {
|
|
148
|
+
"type": ["string", "null"],
|
|
149
|
+
"format": "uri",
|
|
150
|
+
"description": "Upstream source URL if forked from another project"
|
|
151
|
+
},
|
|
152
|
+
"original_author": {
|
|
153
|
+
"type": "string",
|
|
154
|
+
"maxLength": 256,
|
|
155
|
+
"description": "Original author name if forked"
|
|
156
|
+
},
|
|
157
|
+
"contributors": {
|
|
158
|
+
"type": "array",
|
|
159
|
+
"items": {
|
|
160
|
+
"type": "string",
|
|
161
|
+
"maxLength": 256
|
|
162
|
+
},
|
|
163
|
+
"uniqueItems": true,
|
|
164
|
+
"description": "List of contributors to this plugin"
|
|
165
|
+
},
|
|
166
|
+
"modifications": {
|
|
167
|
+
"type": "array",
|
|
168
|
+
"items": {
|
|
169
|
+
"type": "string",
|
|
170
|
+
"maxLength": 512
|
|
171
|
+
},
|
|
172
|
+
"description": "List of modifications made for SpecWeave integration"
|
|
173
|
+
}
|
|
174
|
+
},
|
|
175
|
+
"additionalProperties": false
|
|
176
|
+
}
|
|
177
|
+
},
|
|
178
|
+
"additionalProperties": false,
|
|
179
|
+
"examples": [
|
|
180
|
+
{
|
|
181
|
+
"name": "specweave-github",
|
|
182
|
+
"version": "1.0.0",
|
|
183
|
+
"description": "GitHub issues integration for SpecWeave increments",
|
|
184
|
+
"author": "SpecWeave Team",
|
|
185
|
+
"license": "MIT",
|
|
186
|
+
"specweave_core_version": ">=0.4.0",
|
|
187
|
+
"auto_detect": {
|
|
188
|
+
"files": [".git/"],
|
|
189
|
+
"env_vars": ["GITHUB_TOKEN"],
|
|
190
|
+
"git_remote_pattern": "github\\.com"
|
|
191
|
+
},
|
|
192
|
+
"provides": {
|
|
193
|
+
"skills": ["github-sync", "github-issue-tracker"],
|
|
194
|
+
"agents": ["github-manager"],
|
|
195
|
+
"commands": [
|
|
196
|
+
"specweave.github.create-issue",
|
|
197
|
+
"specweave.github.sync",
|
|
198
|
+
"specweave.github.close-issue"
|
|
199
|
+
]
|
|
200
|
+
},
|
|
201
|
+
"triggers": ["github", "issue", "gh", "pull request", "PR"]
|
|
202
|
+
},
|
|
203
|
+
{
|
|
204
|
+
"name": "specweave-kubernetes",
|
|
205
|
+
"version": "1.0.0",
|
|
206
|
+
"description": "Kubernetes deployment and management for SpecWeave projects",
|
|
207
|
+
"author": "SpecWeave Team",
|
|
208
|
+
"license": "MIT",
|
|
209
|
+
"specweave_core_version": ">=0.4.0",
|
|
210
|
+
"dependencies": {
|
|
211
|
+
"plugins": ["specweave-cloud-infrastructure"]
|
|
212
|
+
},
|
|
213
|
+
"auto_detect": {
|
|
214
|
+
"files": ["kubernetes/", "k8s/", "helm/"],
|
|
215
|
+
"packages": ["@kubernetes/client-node"],
|
|
216
|
+
"env_vars": ["KUBECONFIG"]
|
|
217
|
+
},
|
|
218
|
+
"provides": {
|
|
219
|
+
"skills": ["k8s-deployer", "helm-manager", "k8s-troubleshooter"],
|
|
220
|
+
"agents": ["devops"],
|
|
221
|
+
"commands": ["specweave.k8s.deploy", "specweave.k8s.status"]
|
|
222
|
+
},
|
|
223
|
+
"triggers": ["kubernetes", "k8s", "kubectl", "helm", "pod", "deployment", "service"]
|
|
224
|
+
},
|
|
225
|
+
{
|
|
226
|
+
"name": "specweave-observability",
|
|
227
|
+
"version": "1.0.0",
|
|
228
|
+
"description": "Observability & monitoring for SpecWeave projects (Prometheus, Grafana)",
|
|
229
|
+
"author": "SpecWeave Team",
|
|
230
|
+
"license": "MIT",
|
|
231
|
+
"specweave_core_version": ">=0.4.0",
|
|
232
|
+
"auto_detect": {
|
|
233
|
+
"files": ["prometheus/", "grafana/"],
|
|
234
|
+
"packages": ["prom-client", "@grafana/faro-web-sdk"]
|
|
235
|
+
},
|
|
236
|
+
"provides": {
|
|
237
|
+
"skills": ["monitoring-setup", "metrics-collector", "alerting-config", "dashboard-generator"],
|
|
238
|
+
"agents": ["sre"],
|
|
239
|
+
"commands": ["specweave.observe.metrics", "specweave.observe.alerts"]
|
|
240
|
+
},
|
|
241
|
+
"triggers": ["monitoring", "prometheus", "grafana", "metrics", "observability", "alerting"],
|
|
242
|
+
"credits": {
|
|
243
|
+
"based_on": "https://github.com/wshobson/agents/tree/main/plugins/observability-monitoring",
|
|
244
|
+
"original_author": "Seth Hobson",
|
|
245
|
+
"modifications": [
|
|
246
|
+
"Adapted for SpecWeave increment lifecycle",
|
|
247
|
+
"Added /sync-docs integration",
|
|
248
|
+
"SpecWeave naming conventions"
|
|
249
|
+
]
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
]
|
|
253
|
+
}
|