specdrive-cli 0.1.10 → 0.1.12

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 (74) hide show
  1. package/README.md +955 -697
  2. package/agents/00-onboarding.md +261 -0
  3. package/agents/01-constitution.md +214 -201
  4. package/agents/02-specification.md +249 -226
  5. package/agents/03-uiux.md +156 -144
  6. package/agents/04-cascade.md +151 -122
  7. package/agents/05-discover-skills.md +136 -136
  8. package/agents/06-documentation.md +158 -145
  9. package/agents/07-implementation.md +201 -169
  10. package/agents/08-performance.md +179 -165
  11. package/agents/09-review-complete.md +239 -168
  12. package/agents/10-security.md +180 -167
  13. package/agents/11-test.md +195 -0
  14. package/commands/gates.js +73 -73
  15. package/commands/manifest.json +113 -95
  16. package/commands/permissions.json +39 -0
  17. package/commands/router.js +151 -127
  18. package/commands/tools.json +19 -19
  19. package/dashboard/app.js +394 -0
  20. package/dashboard/index.html +74 -0
  21. package/dashboard/server.js +166 -0
  22. package/dashboard/style.css +157 -0
  23. package/mcp/mcp.json +31 -0
  24. package/mcp/server.js +108 -0
  25. package/package.json +35 -32
  26. package/schemas/config.schema.json +20 -0
  27. package/schemas/workflow-state.schema.json +149 -38
  28. package/scripts/anti-redundancy.js +176 -176
  29. package/scripts/audit-log.js +46 -46
  30. package/scripts/check-permission.js +87 -0
  31. package/scripts/diff-spec.js +50 -50
  32. package/scripts/diff-version.js +96 -0
  33. package/scripts/generate-adapters.js +80 -80
  34. package/scripts/generate-from-template.js +97 -97
  35. package/scripts/generate-openapi.js +75 -75
  36. package/scripts/github-team-sync.js +80 -80
  37. package/scripts/install-hooks.js +20 -20
  38. package/scripts/load-plugins.js +65 -65
  39. package/scripts/migrate-openspec.js +318 -0
  40. package/scripts/migrate-speckit.js +322 -0
  41. package/scripts/migrate.js +12 -62
  42. package/scripts/onboard.js +312 -0
  43. package/scripts/pre-commit.js +56 -20
  44. package/scripts/team.js +113 -113
  45. package/scripts/test-adapters.js +118 -118
  46. package/scripts/test-create.js +13 -13
  47. package/scripts/test-end-to-end.js +137 -137
  48. package/scripts/test-router.js +110 -110
  49. package/scripts/test-state-transitions.js +146 -146
  50. package/scripts/test-validator.js +152 -152
  51. package/scripts/validate-config.js +36 -0
  52. package/scripts/validate-governance.js +150 -130
  53. package/scripts/verify.js +525 -0
  54. package/scripts/version-new.js +202 -0
  55. package/src/index.js +1010 -807
  56. package/templates/expo/plan.json +12 -0
  57. package/templates/expo/spec.json +12 -0
  58. package/templates/expo/tasks.json +5 -0
  59. package/templates/fastapi/plan.json +12 -0
  60. package/templates/fastapi/spec.json +12 -0
  61. package/templates/fastapi/tasks.json +5 -0
  62. package/templates/generic/plan.json +12 -0
  63. package/templates/generic/spec.json +11 -0
  64. package/templates/generic/tasks.json +5 -0
  65. package/templates/nextjs/plan.json +23 -0
  66. package/templates/nextjs/spec.json +12 -0
  67. package/templates/nextjs/tasks.json +5 -0
  68. package/templates/react-node/plan.json +15 -0
  69. package/templates/react-node/spec.json +12 -0
  70. package/templates/react-node/tasks.json +5 -0
  71. package/templates/registry.json +30 -0
  72. package/templates/turborepo/plan.json +12 -0
  73. package/templates/turborepo/spec.json +12 -0
  74. package/templates/turborepo/tasks.json +5 -0
@@ -0,0 +1,157 @@
1
+ * {
2
+ box-sizing: border-box;
3
+ }
4
+
5
+ body {
6
+ font-family: system-ui, sans-serif;
7
+ margin: 0;
8
+ padding: 0;
9
+ background: #f5f5f5;
10
+ color: #222;
11
+ }
12
+
13
+ header {
14
+ background: #111;
15
+ color: #fff;
16
+ padding: 20px;
17
+ }
18
+
19
+ header h1 {
20
+ margin: 0;
21
+ font-size: 20px;
22
+ }
23
+
24
+ main {
25
+ padding: 20px;
26
+ max-width: 900px;
27
+ margin: 0 auto;
28
+ }
29
+
30
+ section {
31
+ background: #fff;
32
+ padding: 20px;
33
+ margin-bottom: 20px;
34
+ border-radius: 8px;
35
+ box-shadow: 0 1px 3px rgba(0, 0, 0, 0.08);
36
+ }
37
+
38
+ h2 {
39
+ margin-top: 0;
40
+ font-size: 16px;
41
+ color: #333;
42
+ }
43
+
44
+ #feature-filters {
45
+ display: flex;
46
+ flex-wrap: wrap;
47
+ gap: 8px;
48
+ align-items: center;
49
+ }
50
+
51
+ #feature-filters input[type="text"] {
52
+ flex: 1 1 200px;
53
+ min-width: 160px;
54
+ }
55
+
56
+ #feature-filters select {
57
+ flex: 0 0 auto;
58
+ }
59
+
60
+ #feature-filters label {
61
+ display: inline-flex;
62
+ align-items: center;
63
+ gap: 4px;
64
+ color: #444;
65
+ }
66
+
67
+ .feature {
68
+ padding: 12px;
69
+ border-bottom: 1px solid #eee;
70
+ }
71
+
72
+ .feature:last-child {
73
+ border-bottom: none;
74
+ }
75
+
76
+ .feature-name {
77
+ font-weight: bold;
78
+ }
79
+
80
+ .feature-branch {
81
+ font-size: 12px;
82
+ color: #666;
83
+ margin: 4px 0 8px;
84
+ }
85
+
86
+ .gate {
87
+ display: inline-block;
88
+ margin-right: 8px;
89
+ font-size: 12px;
90
+ padding: 2px 6px;
91
+ border-radius: 4px;
92
+ background: #eee;
93
+ }
94
+
95
+ .gate.approved {
96
+ background: #c8f7c5;
97
+ color: #2b6b25;
98
+ }
99
+
100
+ .gate.pending {
101
+ background: #f9e0a0;
102
+ color: #7a5b1a;
103
+ }
104
+
105
+ .gate.in_progress {
106
+ background: #cce4ff;
107
+ color: #1f4d80;
108
+ }
109
+
110
+ .member {
111
+ padding: 6px 0;
112
+ }
113
+
114
+ .audit-event {
115
+ padding: 6px 0;
116
+ font-size: 13px;
117
+ color: #555;
118
+ border-bottom: 1px solid #eee;
119
+ }
120
+
121
+ .traceability {
122
+ margin-top: 8px;
123
+ font-size: 13px;
124
+ color: #444;
125
+ }
126
+
127
+ .feature-version {
128
+ margin-top: 16px;
129
+ padding-top: 12px;
130
+ border-top: 1px solid #eee;
131
+ }
132
+
133
+ .feature-version:first-of-type {
134
+ border-top: none;
135
+ padding-top: 0;
136
+ }
137
+
138
+ .onboarding {
139
+ background: #fff;
140
+ border-radius: 8px;
141
+ }
142
+
143
+ .onboarding h2 {
144
+ margin-top: 0;
145
+ font-size: 16px;
146
+ }
147
+
148
+ .onboarding ul {
149
+ margin: 4px 0 0 20px;
150
+ padding: 0;
151
+ font-size: 13px;
152
+ color: #444;
153
+ }
154
+
155
+ .onboarding li {
156
+ margin-bottom: 2px;
157
+ }
package/mcp/mcp.json ADDED
@@ -0,0 +1,31 @@
1
+ {
2
+ "name": "specdrive",
3
+ "version": "1.0.0",
4
+ "description": "SpecDrive MCP server",
5
+ "methods": [
6
+ {
7
+ "name": "specdrive.list_features",
8
+ "description": "List all SpecDrive features"
9
+ },
10
+ {
11
+ "name": "specdrive.get_feature",
12
+ "description": "Get details of a feature"
13
+ },
14
+ {
15
+ "name": "specdrive.get_spec",
16
+ "description": "Get the spec.json of a feature"
17
+ },
18
+ {
19
+ "name": "specdrive.get_traceability",
20
+ "description": "Get the traceability matrix of a feature"
21
+ },
22
+ {
23
+ "name": "specdrive.validate",
24
+ "description": "Run the governance validator"
25
+ },
26
+ {
27
+ "name": "specdrive.status",
28
+ "description": "Show SpecDrive status summary"
29
+ }
30
+ ]
31
+ }
package/mcp/server.js ADDED
@@ -0,0 +1,108 @@
1
+ #!/usr/bin/env node
2
+
3
+ const fs = require("fs");
4
+ const path = require("path");
5
+
6
+ const projectRoot = process.cwd();
7
+
8
+ function loadWorkflowState() {
9
+ const statePath = path.join(projectRoot, ".sdrive", "workflow-state.json");
10
+
11
+ if (!fs.existsSync(statePath)) {
12
+ return { features: [] };
13
+ }
14
+
15
+ return JSON.parse(fs.readFileSync(statePath, "utf8"));
16
+ }
17
+
18
+ function listFeatures() {
19
+ const state = loadWorkflowState();
20
+ return state.features || [];
21
+ }
22
+
23
+ function getFeature(name) {
24
+ const features = listFeatures();
25
+ return features.find((f) => f.name === name);
26
+ }
27
+
28
+ function getSpec(name) {
29
+ const specPath = path.join(projectRoot, ".sdrive", "governance", name, "spec.json");
30
+
31
+ if (!fs.existsSync(specPath)) {
32
+ return null;
33
+ }
34
+
35
+ return JSON.parse(fs.readFileSync(specPath, "utf8"));
36
+ }
37
+
38
+ function getTraceability(name) {
39
+ const tracePath = path.join(projectRoot, ".sdrive", "governance", name, "traceability.json");
40
+
41
+ if (!fs.existsSync(tracePath)) {
42
+ return null;
43
+ }
44
+
45
+ return JSON.parse(fs.readFileSync(tracePath, "utf8"));
46
+ }
47
+
48
+ function runValidator() {
49
+ const { execSync } = require("child_process");
50
+ const validatorPath = path.join(projectRoot, ".sdrive", "scripts", "validate-governance.js");
51
+
52
+ try {
53
+ execSync(`node "${validatorPath}"`, { stdio: "pipe" });
54
+ return { success: true };
55
+ } catch (error) {
56
+ return { success: false, message: error.message };
57
+ }
58
+ }
59
+
60
+ // ---------- MCP handlers ----------
61
+
62
+ const handlers = {
63
+ "specdrive.list_features": () => {
64
+ return { features: listFeatures() };
65
+ },
66
+ "specdrive.get_feature": ({ name }) => {
67
+ return { feature: getFeature(name) };
68
+ },
69
+ "specdrive.get_spec": ({ name }) => {
70
+ return { spec: getSpec(name) };
71
+ },
72
+ "specdrive.get_traceability": ({ name }) => {
73
+ return { traceability: getTraceability(name) };
74
+ },
75
+ "specdrive.validate": () => {
76
+ return runValidator();
77
+ },
78
+ "specdrive.status": () => {
79
+ const features = listFeatures();
80
+ return {
81
+ count: features.length,
82
+ features: features.map((f) => ({
83
+ name: f.name,
84
+ phase: f.phase,
85
+ currentStep: f.currentStep
86
+ }))
87
+ };
88
+ }
89
+ };
90
+
91
+ // ---------- CLI entry point ----------
92
+
93
+ const input = process.argv[2] ? JSON.parse(process.argv[2]) : null;
94
+
95
+ if (!input) {
96
+ console.error("❌ Usage: node server.js '{\"method\": \"specdrive.list_features\"}'");
97
+ process.exit(1);
98
+ }
99
+
100
+ const handler = handlers[input.method];
101
+
102
+ if (!handler) {
103
+ console.error(`❌ Unknown MCP method: ${input.method}`);
104
+ process.exit(1);
105
+ }
106
+
107
+ const result = handler(input.params || {});
108
+ console.log(JSON.stringify(result, null, 2));
package/package.json CHANGED
@@ -1,32 +1,35 @@
1
- {
2
- "name": "specdrive-cli",
3
- "version": "0.1.10",
4
- "description": "SpecDrive enterprise spec-driven development CLI",
5
- "bin": {
6
- "sdrive": "src/index.js"
7
- },
8
- "main": "src/index.js",
9
- "files": [
10
- "src/",
11
- "scripts/",
12
- "commands/",
13
- "schemas/",
14
- "agents/",
15
- "README.md"
16
- ],
17
- "dependencies": {
18
- "commander": "^12.0.0",
19
- "ajv": "^8.12.0"
20
- },
21
- "engines": {
22
- "node": ">=18.0.0"
23
- },
24
- "keywords": [
25
- "spec-driven",
26
- "ai",
27
- "governance",
28
- "cli",
29
- "specflow"
30
- ],
31
- "license": "MIT"
32
- }
1
+ {
2
+ "name": "specdrive-cli",
3
+ "version": "0.1.12",
4
+ "description": "SpecDrive enterprise spec-driven development CLI",
5
+ "bin": {
6
+ "sdrive": "src/index.js"
7
+ },
8
+ "main": "src/index.js",
9
+ "files": [
10
+ "src/",
11
+ "scripts/",
12
+ "commands/",
13
+ "schemas/",
14
+ "agents/",
15
+ "dashboard/",
16
+ "mcp/",
17
+ "templates/",
18
+ "README.md"
19
+ ],
20
+ "dependencies": {
21
+ "commander": "^12.0.0",
22
+ "ajv": "^8.12.0"
23
+ },
24
+ "engines": {
25
+ "node": ">=18.0.0"
26
+ },
27
+ "keywords": [
28
+ "spec-driven",
29
+ "ai",
30
+ "governance",
31
+ "cli",
32
+ "specflow"
33
+ ],
34
+ "license": "MIT"
35
+ }
@@ -0,0 +1,20 @@
1
+ {
2
+ "$schema": "http://json-schema.org/draft-07/schema#",
3
+ "title": "SpecDrive Config",
4
+ "type": "object",
5
+ "properties": {
6
+ "defaultTemplate": {
7
+ "type": "string",
8
+ "enum": [
9
+ "generic",
10
+ "react-node",
11
+ "nextjs",
12
+ "expo",
13
+ "fastapi",
14
+ "turborepo"
15
+ ]
16
+ }
17
+ },
18
+ "required": ["defaultTemplate"],
19
+ "additionalProperties": false
20
+ }
@@ -12,61 +12,172 @@
12
12
  "type": "string",
13
13
  "pattern": "^[a-z0-9-]+$"
14
14
  },
15
- "phase": {
16
- "enum": ["backlog", "ongoing", "completed", "blocked"]
17
- },
18
- "currentStep": {
19
- "enum": ["specification", "planning", "implementation", "review"]
20
- },
21
15
  "branch": {
22
16
  "type": "string"
23
17
  },
24
- "gates": {
25
- "type": "object",
26
- "properties": {
27
- "specification": {
28
- "enum": ["pending", "approved", "rejected"]
29
- },
30
- "planning": {
31
- "enum": ["pending", "approved", "rejected"]
32
- },
33
- "implementation": {
34
- "enum": ["pending", "in_progress", "approved", "rejected"]
35
- },
36
- "review": {
37
- "enum": ["pending", "approved", "rejected"]
38
- }
39
- },
40
- "required": [
41
- "specification",
42
- "planning",
43
- "implementation",
44
- "review"
45
- ]
18
+ "currentVersion": {
19
+ "type": "string",
20
+ "pattern": "^v[0-9]+$"
46
21
  },
47
- "history": {
22
+ "versions": {
48
23
  "type": "array",
24
+ "minItems": 1,
49
25
  "items": {
50
26
  "type": "object",
51
27
  "properties": {
52
- "event": {
28
+ "id": {
53
29
  "type": "string",
54
- "minLength": 3
30
+ "pattern": "^v[0-9]+$"
55
31
  },
56
- "by": {
57
- "type": "string"
32
+ "phase": {
33
+ "enum": ["backlog", "ongoing", "completed", "blocked"]
58
34
  },
59
- "timestamp": {
60
- "type": "string",
61
- "format": "date-time"
35
+ "currentStep": {
36
+ "enum": ["specification", "planning", "implementation", "review"]
37
+ },
38
+ "gates": {
39
+ "type": "object",
40
+ "properties": {
41
+ "specification": {
42
+ "enum": ["pending", "approved", "rejected"]
43
+ },
44
+ "planning": {
45
+ "enum": ["pending", "approved", "rejected"]
46
+ },
47
+ "implementation": {
48
+ "enum": ["pending", "in_progress", "approved", "rejected"]
49
+ },
50
+ "review": {
51
+ "enum": ["pending", "approved", "rejected"]
52
+ }
53
+ },
54
+ "required": [
55
+ "specification",
56
+ "planning",
57
+ "implementation",
58
+ "review"
59
+ ]
60
+ },
61
+ "history": {
62
+ "type": "array",
63
+ "items": {
64
+ "type": "object",
65
+ "properties": {
66
+ "event": {
67
+ "type": "string",
68
+ "minLength": 3
69
+ },
70
+ "by": {
71
+ "type": "string"
72
+ },
73
+ "timestamp": {
74
+ "type": "string",
75
+ "format": "date-time"
76
+ }
77
+ },
78
+ "required": ["event", "timestamp"]
79
+ }
62
80
  }
63
81
  },
64
- "required": ["event", "timestamp"]
82
+ "required": ["id", "phase", "currentStep", "gates"]
65
83
  }
66
84
  }
67
85
  },
68
- "required": ["name", "phase", "currentStep", "gates"]
86
+ "required": ["name", "currentVersion", "versions"]
69
87
  }
88
+ },
89
+ "onboarding": {
90
+ "type": "object",
91
+ "properties": {
92
+ "mode": {
93
+ "enum": ["greenfield", "brownfield"]
94
+ },
95
+ "date": {
96
+ "type": "string",
97
+ "format": "date-time"
98
+ },
99
+ "detectedSystems": {
100
+ "type": "object",
101
+ "properties": {
102
+ "openspec": {
103
+ "type": "object",
104
+ "properties": {
105
+ "detected": { "type": "boolean" },
106
+ "specs": { "type": "integer" },
107
+ "changes": { "type": "integer" },
108
+ "archived": { "type": "integer" }
109
+ },
110
+ "required": ["detected"],
111
+ "additionalProperties": false
112
+ },
113
+ "speckit": {
114
+ "type": "object",
115
+ "properties": {
116
+ "detected": { "type": "boolean" },
117
+ "specs": { "type": "integer" },
118
+ "hasConstitution": { "type": "boolean" }
119
+ },
120
+ "required": ["detected"],
121
+ "additionalProperties": false
122
+ }
123
+ },
124
+ "additionalProperties": false
125
+ },
126
+ "missing": {
127
+ "type": "array",
128
+ "items": { "type": "string" }
129
+ },
130
+ "deferred": {
131
+ "type": "array",
132
+ "items": { "type": "string" }
133
+ },
134
+ "retroactiveFeatures": {
135
+ "type": "array",
136
+ "items": { "type": "string" }
137
+ },
138
+ "verifiedFeatures": {
139
+ "type": "array",
140
+ "items": { "type": "string" }
141
+ },
142
+ "migrated": {
143
+ "type": "array",
144
+ "items": {
145
+ "type": "object",
146
+ "properties": {
147
+ "feature": { "type": "string" },
148
+ "from": {
149
+ "enum": ["openspec", "speckit", "other"]
150
+ },
151
+ "date": {
152
+ "type": "string",
153
+ "format": "date-time"
154
+ },
155
+ "source": { "type": "string" }
156
+ },
157
+ "required": ["feature", "from", "date"],
158
+ "additionalProperties": false
159
+ }
160
+ },
161
+ "skipped": {
162
+ "type": "array",
163
+ "items": {
164
+ "type": "object",
165
+ "properties": {
166
+ "system": {
167
+ "enum": ["openspec", "speckit", "other"]
168
+ },
169
+ "reason": { "type": "string" }
170
+ },
171
+ "required": ["system"],
172
+ "additionalProperties": false
173
+ }
174
+ },
175
+ "notes": {
176
+ "type": "string"
177
+ }
178
+ },
179
+ "required": ["mode", "date"],
180
+ "additionalProperties": false
70
181
  }
71
182
  },
72
183
  "required": ["features"],