@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 +14 -0
- package/bin/gsd-t.js +125 -1
- package/package.json +1 -1
- package/templates/CLAUDE-global.md +22 -1
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.
|
|
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",
|
|
@@ -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?
|