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
@@ -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();
@@ -1,111 +1,111 @@
1
- const fs = require("fs");
2
- const path = require("path");
3
- const { execSync } = require("child_process");
4
-
5
- const projectRoot = process.cwd();
6
- const routerPath = path.join(projectRoot, ".sdrive", "commands", "router.js");
7
-
8
- function runRouter(command, feature) {
9
- try {
10
- const args = feature ? ` ${feature}` : "";
11
- execSync(`node "${routerPath}" ${command}${args}`, { stdio: "pipe" });
12
- return true;
13
- } catch (error) {
14
- return false;
15
- }
16
- }
17
-
18
- function testKnownCommand() {
19
- console.log("\n๐Ÿงช Test 1: Known command should pass");
20
-
21
- const passed = runRouter("/sdrive:constitution");
22
-
23
- if (passed) {
24
- console.log("โœ… PASS: Router accepted /sdrive:constitution.");
25
- return true;
26
- }
27
-
28
- console.log("โŒ FAIL: Router rejected /sdrive:constitution.");
29
- return false;
30
- }
31
-
32
- function testUnknownCommand() {
33
- console.log("\n๐Ÿงช Test 2: Unknown command should fail");
34
-
35
- const passed = runRouter("/sdrive:unknown");
36
-
37
- if (!passed) {
38
- console.log("โœ… PASS: Router rejected unknown command.");
39
- return true;
40
- }
41
-
42
- console.log("โŒ FAIL: Router accepted unknown command.");
43
- return false;
44
- }
45
-
46
- function testMissingFeatureForGatedCommand() {
47
- console.log("\n๐Ÿงช Test 3: Gated command without feature should fail");
48
-
49
- const passed = runRouter("/sdrive:propose");
50
-
51
- if (!passed) {
52
- console.log("โœ… PASS: Router blocked gated command without feature.");
53
- return true;
54
- }
55
-
56
- console.log("โŒ FAIL: Router allowed gated command without feature.");
57
- return false;
58
- }
59
-
60
- function testFeatureConversion() {
61
- console.log("\n๐Ÿงช Test 4: Natural feature description should convert to kebab-case");
62
-
63
- try {
64
- const output = execSync(
65
- `node "${routerPath}" /sdrive:propose "User login with email"`,
66
- { stdio: "pipe", encoding: "utf8" }
67
- );
68
-
69
- if (output.includes("user-login-with-email")) {
70
- console.log("โœ… PASS: Feature converted to kebab-case.");
71
- return true;
72
- }
73
-
74
- console.log("โŒ FAIL: Feature not converted correctly.");
75
- return false;
76
- } catch (error) {
77
- if (error.stdout && error.stdout.includes("user-login-with-email")) {
78
- console.log("โœ… PASS: Feature converted to kebab-case.");
79
- return true;
80
- }
81
-
82
- if (error.stdout && error.stdout.includes("user-login-with-email")) {
83
- console.log("โœ… PASS: Feature converted to kebab-case.");
84
- return true;
85
- }
86
-
87
- console.log("โŒ FAIL: Feature not converted correctly.");
88
- return false;
89
- }
90
- }
91
-
92
- function main() {
93
- console.log("=== SpecDrive Router Tests ===\n");
94
-
95
- let allPassed = true;
96
-
97
- allPassed &= testKnownCommand();
98
- allPassed &= testUnknownCommand();
99
- allPassed &= testMissingFeatureForGatedCommand();
100
- allPassed &= testFeatureConversion();
101
-
102
- if (allPassed) {
103
- console.log("\nโœ… All router tests passed.");
104
- process.exit(0);
105
- } else {
106
- console.log("\nโŒ Some router tests failed.");
107
- process.exit(1);
108
- }
109
- }
110
-
1
+ const fs = require("fs");
2
+ const path = require("path");
3
+ const { execSync } = require("child_process");
4
+
5
+ const projectRoot = process.cwd();
6
+ const routerPath = path.join(projectRoot, ".sdrive", "commands", "router.js");
7
+
8
+ function runRouter(command, feature) {
9
+ try {
10
+ const args = feature ? ` ${feature}` : "";
11
+ execSync(`node "${routerPath}" ${command}${args}`, { stdio: "pipe" });
12
+ return true;
13
+ } catch (error) {
14
+ return false;
15
+ }
16
+ }
17
+
18
+ function testKnownCommand() {
19
+ console.log("\n๐Ÿงช Test 1: Known command should pass");
20
+
21
+ const passed = runRouter("/sdrive:constitution");
22
+
23
+ if (passed) {
24
+ console.log("โœ… PASS: Router accepted /sdrive:constitution.");
25
+ return true;
26
+ }
27
+
28
+ console.log("โŒ FAIL: Router rejected /sdrive:constitution.");
29
+ return false;
30
+ }
31
+
32
+ function testUnknownCommand() {
33
+ console.log("\n๐Ÿงช Test 2: Unknown command should fail");
34
+
35
+ const passed = runRouter("/sdrive:unknown");
36
+
37
+ if (!passed) {
38
+ console.log("โœ… PASS: Router rejected unknown command.");
39
+ return true;
40
+ }
41
+
42
+ console.log("โŒ FAIL: Router accepted unknown command.");
43
+ return false;
44
+ }
45
+
46
+ function testMissingFeatureForGatedCommand() {
47
+ console.log("\n๐Ÿงช Test 3: Gated command without feature should fail");
48
+
49
+ const passed = runRouter("/sdrive:propose");
50
+
51
+ if (!passed) {
52
+ console.log("โœ… PASS: Router blocked gated command without feature.");
53
+ return true;
54
+ }
55
+
56
+ console.log("โŒ FAIL: Router allowed gated command without feature.");
57
+ return false;
58
+ }
59
+
60
+ function testFeatureConversion() {
61
+ console.log("\n๐Ÿงช Test 4: Natural feature description should convert to kebab-case");
62
+
63
+ try {
64
+ const output = execSync(
65
+ `node "${routerPath}" /sdrive:propose "User login with email"`,
66
+ { stdio: "pipe", encoding: "utf8" }
67
+ );
68
+
69
+ if (output.includes("user-login-with-email")) {
70
+ console.log("โœ… PASS: Feature converted to kebab-case.");
71
+ return true;
72
+ }
73
+
74
+ console.log("โŒ FAIL: Feature not converted correctly.");
75
+ return false;
76
+ } catch (error) {
77
+ if (error.stdout && error.stdout.includes("user-login-with-email")) {
78
+ console.log("โœ… PASS: Feature converted to kebab-case.");
79
+ return true;
80
+ }
81
+
82
+ if (error.stdout && error.stdout.includes("user-login-with-email")) {
83
+ console.log("โœ… PASS: Feature converted to kebab-case.");
84
+ return true;
85
+ }
86
+
87
+ console.log("โŒ FAIL: Feature not converted correctly.");
88
+ return false;
89
+ }
90
+ }
91
+
92
+ function main() {
93
+ console.log("=== SpecDrive Router Tests ===\n");
94
+
95
+ let allPassed = true;
96
+
97
+ allPassed &= testKnownCommand();
98
+ allPassed &= testUnknownCommand();
99
+ allPassed &= testMissingFeatureForGatedCommand();
100
+ allPassed &= testFeatureConversion();
101
+
102
+ if (allPassed) {
103
+ console.log("\nโœ… All router tests passed.");
104
+ process.exit(0);
105
+ } else {
106
+ console.log("\nโŒ Some router tests failed.");
107
+ process.exit(1);
108
+ }
109
+ }
110
+
111
111
  main();