@tekyzinc/gsd-t 2.20.1 → 2.20.2
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/CHANGELOG.md +8 -0
- package/bin/gsd-t.js +125 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,14 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to GSD-T are documented here. Updated with each release.
|
|
4
4
|
|
|
5
|
+
## [2.20.2] - 2026-02-16
|
|
6
|
+
|
|
7
|
+
### Added
|
|
8
|
+
- **CLI health checks**: `update-all` and `doctor` now check all projects for missing Playwright and Swagger/OpenAPI
|
|
9
|
+
- Smart API detection: scans `package.json`, `requirements.txt`, `pyproject.toml` for API frameworks (Express, Fastify, Hono, Django, FastAPI, etc.)
|
|
10
|
+
- Swagger detection: checks for spec files (`openapi.json/yaml`, `swagger.json/yaml`) and swagger packages in dependencies
|
|
11
|
+
- Health summary in `update-all` shows counts of missing Playwright and Swagger across all registered projects
|
|
12
|
+
|
|
5
13
|
## [2.20.1] - 2026-02-16
|
|
6
14
|
|
|
7
15
|
### Added
|
package/bin/gsd-t.js
CHANGED
|
@@ -90,6 +90,70 @@ function copyFile(src, dest, label) {
|
|
|
90
90
|
success(label || path.basename(dest));
|
|
91
91
|
}
|
|
92
92
|
|
|
93
|
+
function hasPlaywright(projectDir) {
|
|
94
|
+
const configs = ["playwright.config.ts", "playwright.config.js", "playwright.config.mjs"];
|
|
95
|
+
return configs.some((f) => fs.existsSync(path.join(projectDir, f)));
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
function hasSwagger(projectDir) {
|
|
99
|
+
// Check for OpenAPI/Swagger spec files
|
|
100
|
+
const specFiles = [
|
|
101
|
+
"swagger.json", "swagger.yaml", "swagger.yml",
|
|
102
|
+
"openapi.json", "openapi.yaml", "openapi.yml",
|
|
103
|
+
];
|
|
104
|
+
if (specFiles.some((f) => fs.existsSync(path.join(projectDir, f)))) return true;
|
|
105
|
+
|
|
106
|
+
// Check package.json for swagger dependencies
|
|
107
|
+
const pkgPath = path.join(projectDir, "package.json");
|
|
108
|
+
if (fs.existsSync(pkgPath)) {
|
|
109
|
+
try {
|
|
110
|
+
const pkg = JSON.parse(fs.readFileSync(pkgPath, "utf8"));
|
|
111
|
+
const allDeps = Object.keys(pkg.dependencies || {}).concat(Object.keys(pkg.devDependencies || {}));
|
|
112
|
+
const swaggerPkgs = ["swagger-jsdoc", "swagger-ui-express", "@fastify/swagger", "@nestjs/swagger", "swagger-ui", "express-openapi-validator"];
|
|
113
|
+
if (swaggerPkgs.some((p) => allDeps.includes(p))) return true;
|
|
114
|
+
} catch { /* ignore */ }
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
// Check for Python FastAPI (has built-in OpenAPI)
|
|
118
|
+
const pyFiles = ["requirements.txt", "pyproject.toml"];
|
|
119
|
+
for (const f of pyFiles) {
|
|
120
|
+
const fp = path.join(projectDir, f);
|
|
121
|
+
if (fs.existsSync(fp)) {
|
|
122
|
+
try {
|
|
123
|
+
const content = fs.readFileSync(fp, "utf8");
|
|
124
|
+
if (content.includes("fastapi")) return true;
|
|
125
|
+
} catch { /* ignore */ }
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
return false;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
function hasApi(projectDir) {
|
|
133
|
+
// Quick check: does this project likely have API endpoints?
|
|
134
|
+
const pkgPath = path.join(projectDir, "package.json");
|
|
135
|
+
if (fs.existsSync(pkgPath)) {
|
|
136
|
+
try {
|
|
137
|
+
const pkg = JSON.parse(fs.readFileSync(pkgPath, "utf8"));
|
|
138
|
+
const allDeps = Object.keys(pkg.dependencies || {}).concat(Object.keys(pkg.devDependencies || {}));
|
|
139
|
+
const apiFrameworks = ["express", "fastify", "hono", "koa", "hapi", "@nestjs/core", "next"];
|
|
140
|
+
if (apiFrameworks.some((p) => allDeps.includes(p))) return true;
|
|
141
|
+
} catch { /* ignore */ }
|
|
142
|
+
}
|
|
143
|
+
// Check for Python API frameworks
|
|
144
|
+
const pyFiles = ["requirements.txt", "pyproject.toml"];
|
|
145
|
+
for (const f of pyFiles) {
|
|
146
|
+
const fp = path.join(projectDir, f);
|
|
147
|
+
if (fs.existsSync(fp)) {
|
|
148
|
+
try {
|
|
149
|
+
const content = fs.readFileSync(fp, "utf8");
|
|
150
|
+
if (content.includes("fastapi") || content.includes("flask") || content.includes("django")) return true;
|
|
151
|
+
} catch { /* ignore */ }
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
return false;
|
|
155
|
+
}
|
|
156
|
+
|
|
93
157
|
function getInstalledVersion() {
|
|
94
158
|
try {
|
|
95
159
|
return fs.readFileSync(VERSION_FILE, "utf8").trim();
|
|
@@ -716,6 +780,37 @@ function doUpdateAll() {
|
|
|
716
780
|
}
|
|
717
781
|
}
|
|
718
782
|
|
|
783
|
+
// Health check: Playwright and Swagger across all projects
|
|
784
|
+
heading("Project Health");
|
|
785
|
+
let playwrightMissing = [];
|
|
786
|
+
let swaggerMissing = [];
|
|
787
|
+
|
|
788
|
+
for (const projectDir of projects) {
|
|
789
|
+
if (!fs.existsSync(projectDir)) continue;
|
|
790
|
+
const name = path.basename(projectDir);
|
|
791
|
+
|
|
792
|
+
if (!hasPlaywright(projectDir)) {
|
|
793
|
+
playwrightMissing.push(name);
|
|
794
|
+
}
|
|
795
|
+
|
|
796
|
+
if (hasApi(projectDir) && !hasSwagger(projectDir)) {
|
|
797
|
+
swaggerMissing.push(name);
|
|
798
|
+
}
|
|
799
|
+
}
|
|
800
|
+
|
|
801
|
+
if (playwrightMissing.length === 0 && swaggerMissing.length === 0) {
|
|
802
|
+
success("All projects have Playwright and Swagger configured");
|
|
803
|
+
} else {
|
|
804
|
+
if (playwrightMissing.length > 0) {
|
|
805
|
+
warn(`Playwright missing: ${playwrightMissing.join(", ")}`);
|
|
806
|
+
info("Playwright will be auto-installed when you run a GSD-T command in each project");
|
|
807
|
+
}
|
|
808
|
+
if (swaggerMissing.length > 0) {
|
|
809
|
+
warn(`Swagger/OpenAPI missing (API detected): ${swaggerMissing.join(", ")}`);
|
|
810
|
+
info("Swagger will be auto-configured when an API endpoint is created or modified");
|
|
811
|
+
}
|
|
812
|
+
}
|
|
813
|
+
|
|
719
814
|
// Summary
|
|
720
815
|
log("");
|
|
721
816
|
heading("Update All Complete");
|
|
@@ -725,6 +820,12 @@ function doUpdateAll() {
|
|
|
725
820
|
if (missing > 0) {
|
|
726
821
|
log(` Not found: ${missing}`);
|
|
727
822
|
}
|
|
823
|
+
if (playwrightMissing.length > 0) {
|
|
824
|
+
log(` Missing Playwright: ${playwrightMissing.length}`);
|
|
825
|
+
}
|
|
826
|
+
if (swaggerMissing.length > 0) {
|
|
827
|
+
log(` Missing Swagger: ${swaggerMissing.length}`);
|
|
828
|
+
}
|
|
728
829
|
log("");
|
|
729
830
|
}
|
|
730
831
|
|
|
@@ -804,7 +905,30 @@ function doDoctor() {
|
|
|
804
905
|
info("No settings.json (not required)");
|
|
805
906
|
}
|
|
806
907
|
|
|
807
|
-
// 7.
|
|
908
|
+
// 7. Playwright check (current project)
|
|
909
|
+
const cwd = process.cwd();
|
|
910
|
+
if (hasPlaywright(cwd)) {
|
|
911
|
+
success("Playwright configured");
|
|
912
|
+
} else {
|
|
913
|
+
warn("Playwright not configured in this project");
|
|
914
|
+
info("Will be auto-installed when you run a GSD-T testing command");
|
|
915
|
+
issues++;
|
|
916
|
+
}
|
|
917
|
+
|
|
918
|
+
// 8. Swagger/OpenAPI check (current project)
|
|
919
|
+
if (hasApi(cwd)) {
|
|
920
|
+
if (hasSwagger(cwd)) {
|
|
921
|
+
success("Swagger/OpenAPI configured");
|
|
922
|
+
} else {
|
|
923
|
+
warn("API framework detected but no Swagger/OpenAPI spec found");
|
|
924
|
+
info("Will be auto-configured when an API endpoint is created or modified");
|
|
925
|
+
issues++;
|
|
926
|
+
}
|
|
927
|
+
} else {
|
|
928
|
+
info("No API framework detected (Swagger check skipped)");
|
|
929
|
+
}
|
|
930
|
+
|
|
931
|
+
// 9. Check for encoding issues in command files
|
|
808
932
|
let encodingIssues = 0;
|
|
809
933
|
for (const file of installed) {
|
|
810
934
|
const content = fs.readFileSync(path.join(COMMANDS_DIR, file), "utf8");
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tekyzinc/gsd-t",
|
|
3
|
-
"version": "2.20.
|
|
3
|
+
"version": "2.20.2",
|
|
4
4
|
"description": "GSD-T: Contract-Driven Development for Claude Code — 41 slash commands with backlog management, impact analysis, test sync, and milestone archival",
|
|
5
5
|
"author": "Tekyz, Inc.",
|
|
6
6
|
"license": "MIT",
|