specdrive-cli 0.1.9 → 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 -506
  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 +152 -35
  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 +51 -0
  32. package/scripts/diff-version.js +96 -0
  33. package/scripts/generate-adapters.js +80 -80
  34. package/scripts/generate-from-template.js +97 -70
  35. package/scripts/generate-openapi.js +76 -0
  36. package/scripts/github-team-sync.js +81 -0
  37. package/scripts/install-hooks.js +21 -0
  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 -0
  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 -400
  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
@@ -1,119 +1,119 @@
1
- const fs = require("fs");
2
- const path = require("path");
3
- const { execSync } = require("child_process");
4
-
5
- const projectRoot = process.cwd();
6
- const generatorPath = path.join(projectRoot, ".sdrive", "scripts", "generate-adapters.js");
7
-
8
- function testGeneratorCreatesAdapters() {
9
- console.log("\n🧪 Test 1: Generator creates adapters");
10
-
11
- try {
12
- execSync(`node "${generatorPath}"`, { stdio: "pipe" });
13
- } catch (error) {
14
- console.log("āŒ FAIL: Generator failed.");
15
- return false;
16
- }
17
-
18
- const toolsPath = path.join(projectRoot, ".sdrive", "commands", "tools.json");
19
- const tools = JSON.parse(fs.readFileSync(toolsPath, "utf8")).tools;
20
-
21
- for (const tool of tools) {
22
- const fullPath = path.join(projectRoot, tool.adapterPath);
23
-
24
- if (fs.existsSync(fullPath)) {
25
- console.log(` āœ… Found: ${tool.adapterPath}`);
26
- } else {
27
- console.log(` āŒ Missing: ${tool.adapterPath}`);
28
- return false;
29
- }
30
- }
31
-
32
- console.log("āœ… PASS: All adapters created.");
33
- return true;
34
- }
35
-
36
- function testAdapterContent() {
37
- console.log("\n🧪 Test 2: Adapter content includes SpecDrive instructions");
38
-
39
- const adapterPath = path.join(projectRoot, ".github", "copilot-instructions.md");
40
-
41
- if (!fs.existsSync(adapterPath)) {
42
- console.log("āŒ FAIL: Copilot adapter missing.");
43
- return false;
44
- }
45
-
46
- const content = fs.readFileSync(adapterPath, "utf8");
47
-
48
- if (content.includes(".sdrive/commands/manifest.json")) {
49
- console.log("āœ… PASS: Adapter contains manifest reference.");
50
- return true;
51
- }
52
-
53
- console.log("āŒ FAIL: Adapter missing manifest reference.");
54
- return false;
55
- }
56
-
57
- function testSafetyRule() {
58
- console.log("\n🧪 Test 3: Generator does not overwrite existing files");
59
-
60
- const adapterPath = path.join(projectRoot, ".github", "copilot-instructions.md");
61
-
62
- fs.writeFileSync(adapterPath, "# Custom existing file\n", "utf8");
63
-
64
- try {
65
- execSync(`node "${generatorPath}"`, { stdio: "pipe" });
66
- } catch (error) {
67
- console.log("āŒ FAIL: Generator failed.");
68
- return false;
69
- }
70
-
71
- const content = fs.readFileSync(adapterPath, "utf8");
72
-
73
- if (content === "# Custom existing file\n") {
74
- console.log("āœ… PASS: Existing file was not overwritten.");
75
- return true;
76
- }
77
-
78
- console.log("āŒ FAIL: Existing file was overwritten.");
79
- return false;
80
- }
81
-
82
- function cleanup() {
83
- const toolsPath = path.join(projectRoot, ".sdrive", "commands", "tools.json");
84
-
85
- if (fs.existsSync(toolsPath)) {
86
- const tools = JSON.parse(fs.readFileSync(toolsPath, "utf8")).tools;
87
-
88
- tools.forEach((tool) => {
89
- const fullPath = path.join(projectRoot, tool.adapterPath);
90
- if (fs.existsSync(fullPath)) {
91
- fs.rmSync(fullPath, { force: true });
92
- }
93
- });
94
- }
95
-
96
- console.log("\n🧹 Cleaned up adapters.");
97
- }
98
-
99
- function main() {
100
- console.log("=== SpecDrive Adapter Tests ===\n");
101
-
102
- let allPassed = true;
103
-
104
- allPassed &= testGeneratorCreatesAdapters();
105
- allPassed &= testAdapterContent();
106
- allPassed &= testSafetyRule();
107
-
108
- cleanup();
109
-
110
- if (allPassed) {
111
- console.log("\nāœ… All adapter tests passed.");
112
- process.exit(0);
113
- } else {
114
- console.log("\nāŒ Some adapter tests failed.");
115
- process.exit(1);
116
- }
117
- }
118
-
1
+ const fs = require("fs");
2
+ const path = require("path");
3
+ const { execSync } = require("child_process");
4
+
5
+ const projectRoot = process.cwd();
6
+ const generatorPath = path.join(projectRoot, ".sdrive", "scripts", "generate-adapters.js");
7
+
8
+ function testGeneratorCreatesAdapters() {
9
+ console.log("\n🧪 Test 1: Generator creates adapters");
10
+
11
+ try {
12
+ execSync(`node "${generatorPath}"`, { stdio: "pipe" });
13
+ } catch (error) {
14
+ console.log("āŒ FAIL: Generator failed.");
15
+ return false;
16
+ }
17
+
18
+ const toolsPath = path.join(projectRoot, ".sdrive", "commands", "tools.json");
19
+ const tools = JSON.parse(fs.readFileSync(toolsPath, "utf8")).tools;
20
+
21
+ for (const tool of tools) {
22
+ const fullPath = path.join(projectRoot, tool.adapterPath);
23
+
24
+ if (fs.existsSync(fullPath)) {
25
+ console.log(` āœ… Found: ${tool.adapterPath}`);
26
+ } else {
27
+ console.log(` āŒ Missing: ${tool.adapterPath}`);
28
+ return false;
29
+ }
30
+ }
31
+
32
+ console.log("āœ… PASS: All adapters created.");
33
+ return true;
34
+ }
35
+
36
+ function testAdapterContent() {
37
+ console.log("\n🧪 Test 2: Adapter content includes SpecDrive instructions");
38
+
39
+ const adapterPath = path.join(projectRoot, ".github", "copilot-instructions.md");
40
+
41
+ if (!fs.existsSync(adapterPath)) {
42
+ console.log("āŒ FAIL: Copilot adapter missing.");
43
+ return false;
44
+ }
45
+
46
+ const content = fs.readFileSync(adapterPath, "utf8");
47
+
48
+ if (content.includes(".sdrive/commands/manifest.json")) {
49
+ console.log("āœ… PASS: Adapter contains manifest reference.");
50
+ return true;
51
+ }
52
+
53
+ console.log("āŒ FAIL: Adapter missing manifest reference.");
54
+ return false;
55
+ }
56
+
57
+ function testSafetyRule() {
58
+ console.log("\n🧪 Test 3: Generator does not overwrite existing files");
59
+
60
+ const adapterPath = path.join(projectRoot, ".github", "copilot-instructions.md");
61
+
62
+ fs.writeFileSync(adapterPath, "# Custom existing file\n", "utf8");
63
+
64
+ try {
65
+ execSync(`node "${generatorPath}"`, { stdio: "pipe" });
66
+ } catch (error) {
67
+ console.log("āŒ FAIL: Generator failed.");
68
+ return false;
69
+ }
70
+
71
+ const content = fs.readFileSync(adapterPath, "utf8");
72
+
73
+ if (content === "# Custom existing file\n") {
74
+ console.log("āœ… PASS: Existing file was not overwritten.");
75
+ return true;
76
+ }
77
+
78
+ console.log("āŒ FAIL: Existing file was overwritten.");
79
+ return false;
80
+ }
81
+
82
+ function cleanup() {
83
+ const toolsPath = path.join(projectRoot, ".sdrive", "commands", "tools.json");
84
+
85
+ if (fs.existsSync(toolsPath)) {
86
+ const tools = JSON.parse(fs.readFileSync(toolsPath, "utf8")).tools;
87
+
88
+ tools.forEach((tool) => {
89
+ const fullPath = path.join(projectRoot, tool.adapterPath);
90
+ if (fs.existsSync(fullPath)) {
91
+ fs.rmSync(fullPath, { force: true });
92
+ }
93
+ });
94
+ }
95
+
96
+ console.log("\n🧹 Cleaned up adapters.");
97
+ }
98
+
99
+ function main() {
100
+ console.log("=== SpecDrive Adapter Tests ===\n");
101
+
102
+ let allPassed = true;
103
+
104
+ allPassed &= testGeneratorCreatesAdapters();
105
+ allPassed &= testAdapterContent();
106
+ allPassed &= testSafetyRule();
107
+
108
+ cleanup();
109
+
110
+ if (allPassed) {
111
+ console.log("\nāœ… All adapter tests passed.");
112
+ process.exit(0);
113
+ } else {
114
+ console.log("\nāŒ Some adapter tests failed.");
115
+ process.exit(1);
116
+ }
117
+ }
118
+
119
119
  main();
@@ -1,14 +1,14 @@
1
- const { execSync } = require("child_process");
2
- const path = require("path");
3
-
4
- const projectRoot = process.cwd();
5
-
6
- try {
7
- execSync(`node ${path.join(projectRoot, ".sdrive", "src", "index.js")} create test-feature`, {
8
- stdio: "inherit"
9
- });
10
- process.exit(0);
11
- } catch (error) {
12
- console.error("Feature creation failed.");
13
- process.exit(1);
1
+ const { execSync } = require("child_process");
2
+ const path = require("path");
3
+
4
+ const projectRoot = process.cwd();
5
+
6
+ try {
7
+ execSync(`node ${path.join(projectRoot, ".sdrive", "src", "index.js")} create test-feature`, {
8
+ stdio: "inherit"
9
+ });
10
+ process.exit(0);
11
+ } catch (error) {
12
+ console.error("Feature creation failed.");
13
+ process.exit(1);
14
14
  }
@@ -1,138 +1,138 @@
1
- const fs = require("fs");
2
- const path = require("path");
3
- const { execSync } = require("child_process");
4
-
5
- const projectRoot = process.cwd();
6
-
7
- function runCommand(command) {
8
- try {
9
- execSync(command, { stdio: "pipe" });
10
- return true;
11
- } catch (error) {
12
- return false;
13
- }
14
- }
15
-
16
- function resetEnvironment() {
17
- console.log("🧹 Resetting test environment...");
18
-
19
- const specDir = path.join(projectRoot, ".sdrive", "specs", "backlog", "test-feature");
20
- const govDir = path.join(projectRoot, ".sdrive", "governance", "test-feature");
21
-
22
- if (fs.existsSync(specDir)) {
23
- fs.rmSync(specDir, { recursive: true, force: true });
24
- }
25
- if (fs.existsSync(govDir)) {
26
- fs.rmSync(govDir, { recursive: true, force: true });
27
- }
28
-
29
- const workflowStatePath = path.join(projectRoot, ".sdrive", "workflow-state.json");
30
- fs.writeFileSync(workflowStatePath, JSON.stringify({ features: [] }, null, 2));
31
- }
32
-
33
- function testFeatureCreation() {
34
- console.log("\n🧪 Test 1: Feature creation");
35
-
36
- const passed = runCommand(`node .sdrive/scripts/test-create.js`);
37
-
38
- if (passed) {
39
- console.log("āœ… PASS: Feature created.");
40
- return true;
41
- }
42
-
43
- console.log("āŒ FAIL: Feature creation failed.");
44
- return false;
45
- }
46
-
47
- function testSpecGeneration() {
48
- console.log("\n🧪 Test 2: Spec generation");
49
-
50
- const specPath = path.join(projectRoot, ".sdrive", "specs", "backlog", "test-feature", "spec.md");
51
- const govPath = path.join(projectRoot, ".sdrive", "governance", "test-feature", "spec.json");
52
-
53
- const specExists = fs.existsSync(specPath);
54
- const govExists = fs.existsSync(govPath);
55
-
56
- if (specExists && govExists) {
57
- console.log("āœ… PASS: Spec and governance files exist.");
58
- return true;
59
- }
60
-
61
- console.log("āŒ FAIL: Spec or governance files missing.");
62
- return false;
63
- }
64
-
65
- function testTraceabilityGenerated() {
66
- console.log("\n🧪 Test 3: Traceability matrix generated");
67
-
68
- const tracePath = path.join(projectRoot, ".sdrive", "governance", "test-feature", "traceability.json");
69
-
70
- if (fs.existsSync(tracePath)) {
71
- console.log("āœ… PASS: Traceability matrix exists.");
72
- return true;
73
- }
74
-
75
- console.log("āŒ FAIL: Traceability matrix missing.");
76
- return false;
77
- }
78
-
79
- function testValidationPasses() {
80
- console.log("\n🧪 Test 4: Governance validation passes");
81
-
82
- const passed = runCommand("node .sdrive/scripts/validate-governance.js");
83
-
84
- if (passed) {
85
- console.log("āœ… PASS: Governance validation passed.");
86
- return true;
87
- }
88
-
89
- console.log("āŒ FAIL: Governance validation failed.");
90
- return false;
91
- }
92
-
93
- function testWorkflowState() {
94
- console.log("\n🧪 Test 5: Workflow state updated");
95
-
96
- const workflowStatePath = path.join(projectRoot, ".sdrive", "workflow-state.json");
97
-
98
- if (!fs.existsSync(workflowStatePath)) {
99
- console.log("āŒ FAIL: workflow-state.json missing.");
100
- return false;
101
- }
102
-
103
- const state = JSON.parse(fs.readFileSync(workflowStatePath, "utf8"));
104
-
105
- if (state.features && Array.isArray(state.features)) {
106
- console.log("āœ… PASS: Workflow state has features array.");
107
- return true;
108
- }
109
-
110
- console.log("āŒ FAIL: Workflow state invalid.");
111
- return false;
112
- }
113
-
114
- function main() {
115
- console.log("=== SpecDrive End-to-End Tests ===\n");
116
-
117
- resetEnvironment();
118
-
119
- let allPassed = true;
120
-
121
- allPassed &= testFeatureCreation();
122
- allPassed &= testSpecGeneration();
123
- allPassed &= testTraceabilityGenerated();
124
- allPassed &= testValidationPasses();
125
- allPassed &= testWorkflowState();
126
-
127
- resetEnvironment();
128
-
129
- if (allPassed) {
130
- console.log("\nāœ… All end-to-end tests passed.");
131
- process.exit(0);
132
- } else {
133
- console.log("\nāŒ Some end-to-end tests failed.");
134
- process.exit(1);
135
- }
136
- }
137
-
1
+ const fs = require("fs");
2
+ const path = require("path");
3
+ const { execSync } = require("child_process");
4
+
5
+ const projectRoot = process.cwd();
6
+
7
+ function runCommand(command) {
8
+ try {
9
+ execSync(command, { stdio: "pipe" });
10
+ return true;
11
+ } catch (error) {
12
+ return false;
13
+ }
14
+ }
15
+
16
+ function resetEnvironment() {
17
+ console.log("🧹 Resetting test environment...");
18
+
19
+ const specDir = path.join(projectRoot, ".sdrive", "specs", "backlog", "test-feature");
20
+ const govDir = path.join(projectRoot, ".sdrive", "governance", "test-feature");
21
+
22
+ if (fs.existsSync(specDir)) {
23
+ fs.rmSync(specDir, { recursive: true, force: true });
24
+ }
25
+ if (fs.existsSync(govDir)) {
26
+ fs.rmSync(govDir, { recursive: true, force: true });
27
+ }
28
+
29
+ const workflowStatePath = path.join(projectRoot, ".sdrive", "workflow-state.json");
30
+ fs.writeFileSync(workflowStatePath, JSON.stringify({ features: [] }, null, 2));
31
+ }
32
+
33
+ function testFeatureCreation() {
34
+ console.log("\n🧪 Test 1: Feature creation");
35
+
36
+ const passed = runCommand(`node .sdrive/scripts/test-create.js`);
37
+
38
+ if (passed) {
39
+ console.log("āœ… PASS: Feature created.");
40
+ return true;
41
+ }
42
+
43
+ console.log("āŒ FAIL: Feature creation failed.");
44
+ return false;
45
+ }
46
+
47
+ function testSpecGeneration() {
48
+ console.log("\n🧪 Test 2: Spec generation");
49
+
50
+ const specPath = path.join(projectRoot, ".sdrive", "specs", "backlog", "test-feature", "spec.md");
51
+ const govPath = path.join(projectRoot, ".sdrive", "governance", "test-feature", "spec.json");
52
+
53
+ const specExists = fs.existsSync(specPath);
54
+ const govExists = fs.existsSync(govPath);
55
+
56
+ if (specExists && govExists) {
57
+ console.log("āœ… PASS: Spec and governance files exist.");
58
+ return true;
59
+ }
60
+
61
+ console.log("āŒ FAIL: Spec or governance files missing.");
62
+ return false;
63
+ }
64
+
65
+ function testTraceabilityGenerated() {
66
+ console.log("\n🧪 Test 3: Traceability matrix generated");
67
+
68
+ const tracePath = path.join(projectRoot, ".sdrive", "governance", "test-feature", "traceability.json");
69
+
70
+ if (fs.existsSync(tracePath)) {
71
+ console.log("āœ… PASS: Traceability matrix exists.");
72
+ return true;
73
+ }
74
+
75
+ console.log("āŒ FAIL: Traceability matrix missing.");
76
+ return false;
77
+ }
78
+
79
+ function testValidationPasses() {
80
+ console.log("\n🧪 Test 4: Governance validation passes");
81
+
82
+ const passed = runCommand("node .sdrive/scripts/validate-governance.js");
83
+
84
+ if (passed) {
85
+ console.log("āœ… PASS: Governance validation passed.");
86
+ return true;
87
+ }
88
+
89
+ console.log("āŒ FAIL: Governance validation failed.");
90
+ return false;
91
+ }
92
+
93
+ function testWorkflowState() {
94
+ console.log("\n🧪 Test 5: Workflow state updated");
95
+
96
+ const workflowStatePath = path.join(projectRoot, ".sdrive", "workflow-state.json");
97
+
98
+ if (!fs.existsSync(workflowStatePath)) {
99
+ console.log("āŒ FAIL: workflow-state.json missing.");
100
+ return false;
101
+ }
102
+
103
+ const state = JSON.parse(fs.readFileSync(workflowStatePath, "utf8"));
104
+
105
+ if (state.features && Array.isArray(state.features)) {
106
+ console.log("āœ… PASS: Workflow state has features array.");
107
+ return true;
108
+ }
109
+
110
+ console.log("āŒ FAIL: Workflow state invalid.");
111
+ return false;
112
+ }
113
+
114
+ function main() {
115
+ console.log("=== SpecDrive End-to-End Tests ===\n");
116
+
117
+ resetEnvironment();
118
+
119
+ let allPassed = true;
120
+
121
+ allPassed &= testFeatureCreation();
122
+ allPassed &= testSpecGeneration();
123
+ allPassed &= testTraceabilityGenerated();
124
+ allPassed &= testValidationPasses();
125
+ allPassed &= testWorkflowState();
126
+
127
+ resetEnvironment();
128
+
129
+ if (allPassed) {
130
+ console.log("\nāœ… All end-to-end tests passed.");
131
+ process.exit(0);
132
+ } else {
133
+ console.log("\nāŒ Some end-to-end tests failed.");
134
+ process.exit(1);
135
+ }
136
+ }
137
+
138
138
  main();