@tekyzinc/gsd-t 2.39.11 → 2.39.13

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,15 +2,17 @@
2
2
 
3
3
  All notable changes to GSD-T are documented here. Updated with each release.
4
4
 
5
- ## [2.39.11] - 2026-03-19
5
+ ## [2.39.12] - 2026-03-19
6
6
 
7
7
  ### Added
8
8
  - **Graph auto-sync at command boundary** — every GSD-T command now checks index freshness automatically; both native JSON and CGC/Neo4j are re-indexed when files change (500ms TTL deduplication)
9
9
  - **Neo4j setup guide** — `docs/neo4j-setup.md` with full instructions for Docker container, CGC install, project indexing, and scanning
10
- - Backlog item #8: Auto-Setup Graph Dependencies feature
10
+ - Backlog items #8 (Auto-Setup Graph Dependencies) and #9 (Provider Failure Warnings + Auto-Recovery)
11
11
 
12
12
  ### Fixed
13
13
  - CGC sync uses `cgc index` CLI instead of broken `add_code_to_graph` MCP tool call (CGC 0.3.1 Windows bug workaround)
14
+ - CGC sync retries with `--force` on failure, warns user clearly instead of silently swallowing errors
15
+ - CGC sync sets `PYTHONIOENCODING=utf-8` to prevent crash on emoji/Unicode in source code on Windows
14
16
 
15
17
  ## [2.39.10] - 2026-03-19
16
18
 
@@ -364,16 +364,39 @@ const grepProvider = {
364
364
  // --- CGC Sync (Phase 2: keep Neo4j in sync at command boundary) ---
365
365
 
366
366
  function _syncCgc(projectRoot) {
367
+ if (!cgcProvider.available()) return;
368
+ // Use CLI instead of MCP tool call — add_code_to_graph MCP is broken
369
+ // on Windows in CGC 0.3.1 (directory param arrives as None)
370
+ const { execFileSync } = require('child_process');
371
+ const cgcEnv = { ...process.env, PYTHONIOENCODING: 'utf-8' };
372
+ const cgcOpts = { timeout: 30000, stdio: ['pipe', 'pipe', 'pipe'], env: cgcEnv };
373
+
374
+ // Attempt 1: normal sync
367
375
  try {
368
- if (!cgcProvider.available()) return;
369
- // Use CLI instead of MCP tool call — add_code_to_graph MCP is broken
370
- // on Windows in CGC 0.3.1 (directory param arrives as None)
371
- const { execFileSync } = require('child_process');
372
- execFileSync('cgc', ['index', projectRoot], {
373
- timeout: 30000,
374
- stdio: ['pipe', 'pipe', 'pipe']
375
- });
376
- } catch { /* CGC sync is best-effort */ }
376
+ execFileSync('cgc', ['index', projectRoot], cgcOpts);
377
+ return;
378
+ } catch (err1) {
379
+ const msg1 = err1.stderr ? err1.stderr.toString() : err1.message;
380
+ // Attempt 2: force re-index to recover from corrupt state
381
+ try {
382
+ execFileSync('cgc', ['index', projectRoot, '--force'], cgcOpts);
383
+ process.stderr.write(
384
+ '[GSD-T] CGC sync recovered via force re-index for ' +
385
+ projectRoot + '\n'
386
+ );
387
+ return;
388
+ } catch (err2) {
389
+ const msg2 = err2.stderr ? err2.stderr.toString() : err2.message;
390
+ // Both attempts failed — warn the user clearly
391
+ process.stderr.write(
392
+ '[GSD-T] ⚠ CGC sync FAILED for ' + projectRoot + '\n' +
393
+ ' Error: ' + (msg2 || msg1).split('\n')[0] + '\n' +
394
+ ' Impact: Neo4j graph is stale — deep call chain analysis ' +
395
+ 'may return outdated results\n' +
396
+ ' Fix: run "cgc index ' + projectRoot + ' --force" manually\n'
397
+ );
398
+ }
399
+ }
377
400
  }
378
401
 
379
402
  // --- Main query function ---
@@ -213,6 +213,26 @@ If `README.md` exists, update it to reflect the completed milestone:
213
213
 
214
214
  If `README.md` doesn't exist, create one with project name, description, version, tech stack, setup instructions, and link to `docs/`.
215
215
 
216
+ ## Step 8.5: Scan Doc Milestone Checkpoint
217
+
218
+ Before tagging, ensure scan docs reflect the final state of the codebase after all milestone work. This is the full-refresh counterpart to the micro-updates done during execute/quick/debug.
219
+
220
+ If `.gsd-t/scan/` exists (a prior scan has been run):
221
+ 1. Check `.gsd-t/scan/.cache.json` for staleness — count commits since last scan
222
+ 2. If **any dimension is stale** (>0 commits since scan):
223
+ - Log: "Running milestone scan checkpoint — refreshing all stale scan dimensions..."
224
+ - Re-run all stale dimensions using scan teammates (same team structure as `gsd-t-scan` Step 2):
225
+ - Stale `architecture.md` → architecture teammate (model: haiku)
226
+ - Stale `quality.md` → quality teammate (model: sonnet)
227
+ - Stale `security.md` → security teammate (model: sonnet)
228
+ - Stale `business-rules.md` → business-rules teammate (model: haiku)
229
+ - Stale `contract-drift.md` → contracts teammate (model: haiku)
230
+ - Update `.gsd-t/scan/.cache.json` after refresh
231
+ - Update `.gsd-t/techdebt.md` — mark any items resolved during this milestone as `[RESOLVED]`
232
+ 3. If all dimensions are fresh → skip with log: "Scan docs are fresh — no checkpoint refresh needed"
233
+
234
+ If `.gsd-t/scan/` doesn't exist → skip (no scan data to maintain).
235
+
216
236
  ## Step 9: Document Ripple
217
237
 
218
238
  Before creating the git tag, verify all documentation is up to date:
@@ -262,6 +262,18 @@ After fixing, assess what documentation was affected by the change and update AL
262
262
  9. **Domain `tasks.md`** — If the bug was in an active milestone, update task status or add a remediation task
263
263
  10. **`CLAUDE.md`** — Did the fix establish a new convention or pattern that future work should follow? Add it
264
264
 
265
+ ### Scan Doc Micro-Update (if `.gsd-t/scan/` exists):
266
+ Patch structural metadata in scan docs so they stay fresh between full scans. Near-zero cost — no LLM re-analysis.
267
+
268
+ For each scan doc that exists, apply only the relevant patches:
269
+ - **`.gsd-t/scan/architecture.md`** — Update file/directory counts if the fix added/removed files
270
+ - **`.gsd-t/scan/quality.md`** — Mark resolved TODOs/FIXMEs, update test counts if tests were added
271
+ - **`.gsd-t/scan/security.md`** — If the bug was a security issue, mark the finding `[RESOLVED]`
272
+ - **`.gsd-t/scan/business-rules.md`** — If the fix changed validation/auth/workflow logic, update the rule
273
+ - **`.gsd-t/scan/contract-drift.md`** — If contracts were updated as part of the fix, mark resolved drift items
274
+
275
+ Skip scan docs not affected by this fix. Skip analytical sections — those require a full scan.
276
+
265
277
  ### Skip what's not affected — don't update docs for the sake of updating them.
266
278
 
267
279
  ## Step 5: Test Verification (run tests confirming fix)
@@ -259,6 +259,18 @@ Execute modifies source code, so the Pre-Commit Gate (referenced in Step 9) cove
259
259
  4. **`docs/architecture.md`** — Did a task add/change a component or data flow? Update it
260
260
  5. **`.gsd-t/techdebt.md`** — Did a task resolve a debt item? Mark it done. Did it reveal new debt? Add it
261
261
 
262
+ ### Scan Doc Micro-Update (if `.gsd-t/scan/` exists):
263
+ After all tasks complete, patch structural metadata in scan docs so they stay fresh between full scans. This is near-zero cost — no LLM re-analysis, just updating counts and lists from code.
264
+
265
+ For each scan doc that exists, apply only the relevant patches:
266
+ - **`.gsd-t/scan/architecture.md`** — Update file/directory counts, add new files/modules created during execution
267
+ - **`.gsd-t/scan/quality.md`** — Mark resolved TODOs/FIXMEs, update test counts (run `grep -rc "test\|it\|describe" tests/` or equivalent), append new files to Consumer Surfaces table if applicable
268
+ - **`.gsd-t/scan/security.md`** — If a security finding was fixed during execution, mark it `[RESOLVED]`
269
+ - **`.gsd-t/scan/business-rules.md`** — Append any new validation/auth/workflow rules added during execution
270
+ - **`.gsd-t/scan/contract-drift.md`** — If contracts were updated, mark resolved drift items
271
+
272
+ Skip any scan doc that wasn't affected by the executed tasks. Skip analytical sections (assessments, recommendations) — those require a full scan to update.
273
+
262
274
  $ARGUMENTS
263
275
 
264
276
  ## Auto-Clear
@@ -2,6 +2,24 @@
2
2
 
3
3
  You are the lead agent planning a significant new feature for an existing codebase. Unlike `/user:gsd-t-project` (greenfield), this command respects and builds on what already exists — existing patterns, schema, auth, conventions, and contracts.
4
4
 
5
+ ## Step 0.5: Scan Freshness Auto-Refresh
6
+
7
+ Before reading scan data for impact analysis, check if scan docs are stale and auto-refresh if needed. This ensures feature planning is based on current code — no warnings, no user involvement.
8
+
9
+ If `.gsd-t/scan/.cache.json` exists:
10
+ 1. Read the cache and check `scannedAt` for each dimension
11
+ 2. Count commits since the scan: `git rev-list --count --after="{scannedAt}" HEAD`
12
+ 3. If **>10 commits since scan** OR **scan is older than 14 days**:
13
+ - Log: "Auto-refreshing scan docs (stale by {N} commits / {N} days)..."
14
+ - Re-run only the stale dimensions by spawning the relevant scan teammates:
15
+ - If `quality.md` stale → spawn quality teammate (model: sonnet)
16
+ - If `architecture.md` stale → spawn architecture teammate (model: haiku)
17
+ - If `security.md` stale → spawn security teammate (model: sonnet)
18
+ - Update `.gsd-t/scan/.cache.json` after refresh
19
+ 4. If fresh → proceed silently
20
+
21
+ If `.gsd-t/scan/` doesn't exist at all → skip (no scan data to refresh).
22
+
5
23
  ## Step 1: Understand What Exists
6
24
 
7
25
  Read everything:
@@ -2,6 +2,23 @@
2
2
 
3
3
  You are performing a gap analysis between a provided specification and the existing codebase. The user pastes requirements or a spec, and you systematically identify what's done, what's partial, what's wrong, and what's missing.
4
4
 
5
+ ## Step 0.5: Scan Freshness Auto-Refresh
6
+
7
+ Before reading scan data for gap classification, check if scan docs are stale and auto-refresh if needed. This ensures gap analysis is based on current code — no warnings, no user involvement.
8
+
9
+ If `.gsd-t/scan/.cache.json` exists:
10
+ 1. Read the cache and check `scannedAt` for each dimension
11
+ 2. Count commits since the scan: `git rev-list --count --after="{scannedAt}" HEAD`
12
+ 3. If **>10 commits since scan** OR **scan is older than 14 days**:
13
+ - Log: "Auto-refreshing scan docs (stale by {N} commits / {N} days)..."
14
+ - Re-run only the stale dimensions by spawning the relevant scan teammates:
15
+ - If `architecture.md` stale → spawn architecture teammate (model: haiku)
16
+ - If `quality.md` stale → spawn quality teammate (model: sonnet)
17
+ - Update `.gsd-t/scan/.cache.json` after refresh
18
+ 4. If fresh → proceed silently
19
+
20
+ If `.gsd-t/scan/` doesn't exist at all → skip (no scan data to refresh).
21
+
5
22
  ## Step 1: Load Context
6
23
 
7
24
  Read (if they exist):
@@ -2,6 +2,23 @@
2
2
 
3
3
  You are the lead agent in a contract-driven development workflow. Your job is to decompose the current milestone into independent domains with explicit boundaries and contracts.
4
4
 
5
+ ## Step 0.5: Scan Freshness Auto-Refresh
6
+
7
+ Before reading scan data, check if scan docs are stale and auto-refresh if needed. This ensures partition decisions are based on current code — no warnings, no user involvement.
8
+
9
+ If `.gsd-t/scan/.cache.json` exists:
10
+ 1. Read the cache and check `dimensions.quality.scannedAt` and `dimensions.architecture.scannedAt`
11
+ 2. Count commits since the scan: `git rev-list --count --after="{scannedAt}" HEAD`
12
+ 3. If **>10 commits since scan** OR **scan is older than 14 days**:
13
+ - Log: "Auto-refreshing scan docs (stale by {N} commits / {N} days)..."
14
+ - Re-run only the stale dimensions by spawning the relevant scan teammates:
15
+ - If `quality.md` stale → spawn quality teammate (model: sonnet)
16
+ - If `architecture.md` stale → spawn architecture teammate (model: haiku)
17
+ - Update `.gsd-t/scan/.cache.json` after refresh
18
+ 4. If fresh → proceed silently
19
+
20
+ If `.gsd-t/scan/` doesn't exist at all → skip (no scan data to refresh).
21
+
5
22
  ## Step 1: Understand the Project
6
23
 
7
24
  Read these files in order:
@@ -100,6 +100,18 @@ If `.gsd-t/progress.md` exists, assess what documentation was affected and updat
100
100
  8. **`.gsd-t/techdebt.md`** — Did this task resolve a debt item? Mark it done. Did it reveal new debt? Add it
101
101
  9. **`CLAUDE.md`** — Did this task establish a convention future work should follow? Add it
102
102
 
103
+ ### Scan Doc Micro-Update (if `.gsd-t/scan/` exists):
104
+ Patch structural metadata in scan docs so they stay fresh between full scans. Near-zero cost — no LLM re-analysis.
105
+
106
+ For each scan doc that exists, apply only the relevant patches:
107
+ - **`.gsd-t/scan/architecture.md`** — Update file/directory counts, add new files/modules created
108
+ - **`.gsd-t/scan/quality.md`** — Mark resolved TODOs/FIXMEs, update test counts, append new files to Consumer Surfaces if applicable
109
+ - **`.gsd-t/scan/security.md`** — If a security finding was fixed, mark it `[RESOLVED]`
110
+ - **`.gsd-t/scan/business-rules.md`** — Append any new validation/auth/workflow rules added
111
+ - **`.gsd-t/scan/contract-drift.md`** — If contracts were updated, mark resolved drift items
112
+
113
+ Skip scan docs not affected by this task. Skip analytical sections — those require a full scan.
114
+
103
115
  ### Skip what's not affected — most quick tasks will only touch 1-2 of these.
104
116
 
105
117
  ## Step 5: Test & Verify (MANDATORY)
@@ -497,6 +497,50 @@ After updating living documents, verify nothing was broken:
497
497
  2. **Verify passing**: If any tests fail that were passing before the scan began, investigate and fix
498
498
  3. **Log test baseline**: Record the current test state in `.gsd-t/scan/test-baseline.md` — this gives future milestones a starting point
499
499
 
500
+ ## Step 6.5: Generate Scan Freshness Cache
501
+
502
+ After the scan completes and living docs are updated, generate a hash cache so downstream commands can detect staleness without re-scanning.
503
+
504
+ Create `.gsd-t/scan/.cache.json` with this structure:
505
+
506
+ ```bash
507
+ node -e "
508
+ const fs = require('fs');
509
+ const path = require('path');
510
+ const crypto = require('crypto');
511
+
512
+ const root = process.argv[1];
513
+ const scanDir = path.join(root, '.gsd-t', 'scan');
514
+
515
+ // Hash all source files that affect each scan dimension
516
+ const dimensions = {
517
+ architecture: ['**/*.js', '**/*.ts', '**/*.py', '**/*.json', '**/package.json', '**/tsconfig.json'],
518
+ quality: ['**/*.js', '**/*.ts', '**/*.py', '**/*.test.*', '**/*.spec.*'],
519
+ security: ['**/*.js', '**/*.ts', '**/*.py', '**/*.env*', '**/package.json', '**/package-lock.json'],
520
+ 'business-rules': ['**/*.js', '**/*.ts', '**/*.py'],
521
+ 'contract-drift': ['.gsd-t/contracts/**']
522
+ };
523
+
524
+ // For each dimension, hash the scan doc itself to track its version
525
+ const cache = { generated: new Date().toISOString(), dimensions: {} };
526
+ for (const [dim, _patterns] of Object.entries(dimensions)) {
527
+ const scanFile = path.join(scanDir, dim + '.md');
528
+ if (fs.existsSync(scanFile)) {
529
+ const content = fs.readFileSync(scanFile, 'utf8');
530
+ cache.dimensions[dim] = {
531
+ scanHash: crypto.createHash('md5').update(content).digest('hex'),
532
+ scannedAt: new Date().toISOString()
533
+ };
534
+ }
535
+ }
536
+
537
+ fs.writeFileSync(path.join(scanDir, '.cache.json'), JSON.stringify(cache, null, 2));
538
+ console.log('Scan cache generated:', Object.keys(cache.dimensions).length, 'dimensions cached');
539
+ " "$PROJECT_ROOT"
540
+ ```
541
+
542
+ This cache enables downstream commands (`partition`, `feature`, `gap-analysis`) to check scan freshness and auto-refresh stale dimensions before consuming scan data.
543
+
500
544
  ## Step 7: Update Project State
501
545
 
502
546
  If `.gsd-t/progress.md` exists:
@@ -150,11 +150,34 @@ docker volume rm neo4j_data neo4j_logs
150
150
  | `docker: command not found` | Install Docker Desktop |
151
151
  | Container not starting | Check `docker logs gsd-t-neo4j` for errors |
152
152
  | CGC MCP `add_code_to_graph` fails on Windows | Known CGC 0.3.1 bug — use `cgc index .` CLI instead |
153
+ | `UnicodeEncodeError: 'charmap'` on Windows | CGC crashes on emoji/Unicode in source code. Fix: `set PYTHONIOENCODING=utf-8` before running `cgc index`, or use `PYTHONIOENCODING=utf-8 cgc index .` in bash. GSD-T's auto-sync sets this automatically. |
153
154
  | 0 entities indexed | Project may be docs-only (no `.js`/`.ts`/`.py` files) |
155
+ | Very few entities (e.g., 1 function for a large project) | CGC likely crashed mid-index on a file with special characters. Force re-index with UTF-8: `PYTHONIOENCODING=utf-8 cgc index . --force` |
154
156
  | Neo4j connection refused | Ensure container is running: `docker start gsd-t-neo4j` |
157
+ | `[GSD-T] CGC sync FAILED` warning | Auto-sync tried twice and failed. Run the manual fix command shown in the warning message. Check that Neo4j container is running and CGC is installed. |
155
158
 
156
159
  ## Known Limitations
157
160
 
158
- - **CGC 0.3.1 Windows bug:** The `add_code_to_graph` MCP tool call passes `None` for the directory parameter on Windows. Use `cgc index <path>` CLI as a workaround.
161
+ - **CGC 0.3.1 Windows bugs:**
162
+ - The `add_code_to_graph` MCP tool call passes `None` for the directory parameter on Windows. GSD-T uses `cgc index` CLI as a workaround.
163
+ - CGC crashes with `UnicodeEncodeError` when source files contain emoji or non-ASCII characters on Windows. GSD-T sets `PYTHONIOENCODING=utf-8` automatically. For manual CLI use, prefix commands with `PYTHONIOENCODING=utf-8`.
159
164
  - **Language support:** Native indexer supports JS/TS/Python. CGC supports JS/TS/Python plus additional languages via Tree-sitter.
160
165
  - **Docs-only projects:** Projects without source code files produce 0 entities — this is expected behavior, not an error.
166
+
167
+ ## Auto-Sync Error Handling
168
+
169
+ GSD-T's graph auto-sync (v2.39.11+) does not silently ignore failures. When CGC sync fails:
170
+
171
+ 1. **Attempt 1:** Normal `cgc index` with UTF-8 encoding
172
+ 2. **Attempt 2:** Force re-index (`cgc index --force`) to recover from corrupt state
173
+ 3. **If both fail:** Warns the user with the error, impact, and fix command
174
+
175
+ You will see a message like:
176
+ ```
177
+ [GSD-T] ⚠ CGC sync FAILED for C:\Users\david\MyProject
178
+ Error: UnicodeEncodeError: 'charmap' codec can't encode character...
179
+ Impact: Neo4j graph is stale — deep call chain analysis may return outdated results
180
+ Fix: run "cgc index C:\Users\david\MyProject --force" manually
181
+ ```
182
+
183
+ The native JSON index is unaffected by CGC failures — it always updates successfully.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tekyzinc/gsd-t",
3
- "version": "2.39.11",
3
+ "version": "2.39.13",
4
4
  "description": "GSD-T: Contract-Driven Development for Claude Code — 49 slash commands with graph-powered code analysis, real-time agent dashboard, execution intelligence, backlog management, impact analysis, test sync, milestone archival, and PRD generation",
5
5
  "author": "Tekyz, Inc.",
6
6
  "license": "MIT",