@tekyzinc/gsd-t 2.20.0 → 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,20 @@
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
+
13
+ ## [2.20.1] - 2026-02-16
14
+
15
+ ### Added
16
+ - **API Documentation Guard (Swagger/OpenAPI)**: Every API endpoint must be documented in Swagger/OpenAPI spec — no exceptions. Auto-detects framework and installs appropriate Swagger integration. Swagger URL must be published in CLAUDE.md, README.md, and docs/infrastructure.md
17
+ - Pre-Commit Gate now checks for Swagger spec updates on any API endpoint change
18
+
5
19
  ## [2.20.0] - 2026-02-16
6
20
 
7
21
  ### 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.0",
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",
@@ -201,6 +201,25 @@ Before any command that involves testing (`gsd-t-execute`, `gsd-t-test-sync`, `g
201
201
 
202
202
  Playwright must always be ready before any testing occurs. Do not skip this check. Do not defer setup to "later."
203
203
 
204
+ ## API Documentation Guard (Swagger/OpenAPI)
205
+
206
+ **Every API endpoint MUST be documented in a Swagger/OpenAPI spec. No exceptions.**
207
+
208
+ When any GSD-T command creates or modifies an API endpoint:
209
+ 1. **If no Swagger/OpenAPI spec exists**: Set one up immediately
210
+ - Detect the framework (Express, Fastify, Hono, Django, FastAPI, etc.)
211
+ - Install the appropriate Swagger integration (e.g., `swagger-jsdoc` + `swagger-ui-express`, `@fastify/swagger`, FastAPI's built-in OpenAPI)
212
+ - Create the OpenAPI spec file or configure auto-generation from code
213
+ - Add a `/docs` or `/api-docs` route serving the Swagger UI
214
+ 2. **Update the spec**: Every new or changed endpoint must be reflected in the Swagger/OpenAPI spec — routes, request/response schemas, auth requirements, error responses
215
+ 3. **Publish the Swagger URL**: The Swagger/API docs URL MUST appear in:
216
+ - `CLAUDE.md` — under Documentation or Infrastructure section
217
+ - `README.md` — under API section or Getting Started
218
+ - `docs/infrastructure.md` — under API documentation
219
+ 4. **Verify**: After any API change, confirm the Swagger UI loads and reflects the current endpoints
220
+
221
+ This applies during: `gsd-t-execute`, `gsd-t-quick`, `gsd-t-integrate`, `gsd-t-wave`, and any command that touches API code.
222
+
204
223
  ## Prime Rule
205
224
  KEEP GOING. Only stop for:
206
225
  1. Unrecoverable errors after 2 fix attempts
@@ -219,8 +238,10 @@ BEFORE EVERY COMMIT:
219
238
  │ Compare against "Expected branch" in project CLAUDE.md
220
239
  │ WRONG BRANCH → STOP. Do NOT commit. Switch to the correct branch first.
221
240
  │ No guard set → Proceed (but warn user to set one)
222
- ├── Did I change an API endpoint or response shape?
241
+ ├── Did I create or change an API endpoint or response shape?
223
242
  │ YES → Update .gsd-t/contracts/api-contract.md
243
+ │ YES → Update Swagger/OpenAPI spec (see API Documentation Guard below)
244
+ │ YES → Verify Swagger URL is in CLAUDE.md and README.md
224
245
  ├── Did I change the database schema?
225
246
  │ YES → Update .gsd-t/contracts/schema-contract.md AND docs/schema.md
226
247
  ├── Did I add/change a UI component interface?