@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 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. Check for encoding issues in command files
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.1",
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",