@tekyzinc/gsd-t 2.30.10 → 2.31.11
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/README.md +1 -0
- package/bin/gsd-t.js +63 -0
- package/commands/gsd-t-help.md +3 -1
- package/docs/GSD-T-README.md +1 -0
- package/package.json +1 -1
- package/scripts/gsd-t-auto-route.js +39 -0
- package/templates/CLAUDE-global.md +2 -0
package/README.md
CHANGED
|
@@ -94,6 +94,7 @@ This will replace changed command files, back up your CLAUDE.md if customized, a
|
|
|
94
94
|
| Command | Purpose | Auto |
|
|
95
95
|
|---------|---------|------|
|
|
96
96
|
| `/user:gsd {request}` | Describe what you need → auto-routes to the right command | Manual |
|
|
97
|
+
| _(any plain text)_ | Auto-routed via UserPromptSubmit hook — no leading `/` needed | Auto |
|
|
97
98
|
|
|
98
99
|
### Help & Onboarding
|
|
99
100
|
|
package/bin/gsd-t.js
CHANGED
|
@@ -456,6 +456,66 @@ function configureUpdateCheckHook(scriptPath) {
|
|
|
456
456
|
}
|
|
457
457
|
}
|
|
458
458
|
|
|
459
|
+
// ─── Auto-Route Hook ─────────────────────────────────────────────────────────
|
|
460
|
+
|
|
461
|
+
const AUTO_ROUTE_SCRIPT = "gsd-t-auto-route.js";
|
|
462
|
+
|
|
463
|
+
function installAutoRoute() {
|
|
464
|
+
ensureDir(SCRIPTS_DIR);
|
|
465
|
+
|
|
466
|
+
const src = path.join(PKG_SCRIPTS, AUTO_ROUTE_SCRIPT);
|
|
467
|
+
const dest = path.join(SCRIPTS_DIR, AUTO_ROUTE_SCRIPT);
|
|
468
|
+
|
|
469
|
+
if (!fs.existsSync(src)) {
|
|
470
|
+
warn("Auto-route script not found in package — skipping");
|
|
471
|
+
return;
|
|
472
|
+
}
|
|
473
|
+
|
|
474
|
+
const srcContent = fs.readFileSync(src, "utf8");
|
|
475
|
+
const destContent = fs.existsSync(dest) ? fs.readFileSync(dest, "utf8") : "";
|
|
476
|
+
|
|
477
|
+
if (normalizeEol(srcContent) !== normalizeEol(destContent)) {
|
|
478
|
+
copyFile(src, dest, AUTO_ROUTE_SCRIPT);
|
|
479
|
+
} else {
|
|
480
|
+
info("Auto-route script unchanged");
|
|
481
|
+
}
|
|
482
|
+
|
|
483
|
+
configureAutoRouteHook(dest);
|
|
484
|
+
}
|
|
485
|
+
|
|
486
|
+
function configureAutoRouteHook(scriptPath) {
|
|
487
|
+
const parsed = readSettingsJson();
|
|
488
|
+
if (parsed === null && fs.existsSync(SETTINGS_JSON)) {
|
|
489
|
+
warn("settings.json has invalid JSON — cannot configure auto-route hook");
|
|
490
|
+
return;
|
|
491
|
+
}
|
|
492
|
+
const settings = parsed || {};
|
|
493
|
+
if (!settings.hooks) settings.hooks = {};
|
|
494
|
+
if (!settings.hooks.UserPromptSubmit) settings.hooks.UserPromptSubmit = [];
|
|
495
|
+
|
|
496
|
+
const cmd = `node "${scriptPath.replace(/\\/g, "\\\\")}"`;
|
|
497
|
+
const hasAutoRoute = settings.hooks.UserPromptSubmit.some((entry) =>
|
|
498
|
+
entry.hooks && entry.hooks.some((h) => h.command && h.command.includes(AUTO_ROUTE_SCRIPT))
|
|
499
|
+
);
|
|
500
|
+
|
|
501
|
+
if (hasAutoRoute) {
|
|
502
|
+
info("Auto-route hook already configured");
|
|
503
|
+
return;
|
|
504
|
+
}
|
|
505
|
+
|
|
506
|
+
settings.hooks.UserPromptSubmit.push({
|
|
507
|
+
matcher: "",
|
|
508
|
+
hooks: [{ type: "command", command: cmd }],
|
|
509
|
+
});
|
|
510
|
+
|
|
511
|
+
if (!isSymlink(SETTINGS_JSON)) {
|
|
512
|
+
fs.writeFileSync(SETTINGS_JSON, JSON.stringify(settings, null, 2));
|
|
513
|
+
success("Auto-route hook configured in settings.json");
|
|
514
|
+
} else {
|
|
515
|
+
warn("Skipping settings.json write — target is a symlink");
|
|
516
|
+
}
|
|
517
|
+
}
|
|
518
|
+
|
|
459
519
|
// ─── Utility Scripts ─────────────────────────────────────────────────────────
|
|
460
520
|
|
|
461
521
|
const UTILITY_SCRIPTS = ["gsd-t-tools.js", "gsd-t-statusline.js"];
|
|
@@ -597,6 +657,9 @@ function doInstall(opts = {}) {
|
|
|
597
657
|
heading("Update Check (Session Start)");
|
|
598
658
|
installUpdateCheck();
|
|
599
659
|
|
|
660
|
+
heading("Auto-Route (UserPromptSubmit)");
|
|
661
|
+
installAutoRoute();
|
|
662
|
+
|
|
600
663
|
heading("Utility Scripts");
|
|
601
664
|
installUtilityScripts();
|
|
602
665
|
saveInstalledVersion();
|
package/commands/gsd-t-help.md
CHANGED
|
@@ -135,11 +135,13 @@ Use these when user asks for help on a specific command:
|
|
|
135
135
|
|
|
136
136
|
### gsd (smart router)
|
|
137
137
|
- **Summary**: Describe what you need in plain language — auto-routes to the right GSD-T command using semantic evaluation
|
|
138
|
-
- **Auto-invoked**:
|
|
138
|
+
- **Auto-invoked**: Yes — via UserPromptSubmit hook when prompt does not start with `/`
|
|
139
139
|
- **Files**: Reads `CLAUDE.md`, `.gsd-t/progress.md`, command summaries from `gsd-t-help`
|
|
140
140
|
- **How it works**: Evaluates your request against every command's purpose and "Use when" criteria. Commands that match get shortlisted, best fit is selected. Shows runner-up when close.
|
|
141
|
+
- **Auto-route**: After `gsd-t install`, any plain text message (no leading `/`) is automatically routed through `/gsd`. Slash commands pass through unchanged. Binary detection — no heuristics.
|
|
141
142
|
- **Use when**: You don't want to remember which command to use — just describe what you want
|
|
142
143
|
- **Examples**: `/user:gsd Fix the login bug`, `/user:gsd Add dark mode`, `/user:gsd Scan for tech debt`
|
|
144
|
+
- **Auto-route examples**: `Fix the login bug` (no slash needed), `Add dark mode`, `Scan for tech debt`
|
|
143
145
|
|
|
144
146
|
### prompt
|
|
145
147
|
- **Summary**: Help formulate project/feature/milestone prompts through guided questions
|
package/docs/GSD-T-README.md
CHANGED
|
@@ -63,6 +63,7 @@ GSD-T reads all state files and tells you exactly where you left off.
|
|
|
63
63
|
| Command | Purpose | Auto |
|
|
64
64
|
|---------|---------|------|
|
|
65
65
|
| `/user:gsd {request}` | Describe what you need → auto-routes to the right command | Manual |
|
|
66
|
+
| _(any plain text)_ | Auto-routed via UserPromptSubmit hook — no leading `/` needed | Auto |
|
|
66
67
|
|
|
67
68
|
### Help & Onboarding
|
|
68
69
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tekyzinc/gsd-t",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.31.11",
|
|
4
4
|
"description": "GSD-T: Contract-Driven Development for Claude Code — 46 slash commands with backlog management, impact analysis, test sync, milestone archival, and PRD generation",
|
|
5
5
|
"author": "Tekyz, Inc.",
|
|
6
6
|
"license": "MIT",
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* GSD-T UserPromptSubmit hook — auto-routes plain text prompts through /gsd.
|
|
4
|
+
*
|
|
5
|
+
* Receives JSON on stdin: { "prompt": "...", "cwd": "...", "session_id": "..." }
|
|
6
|
+
* Outputs to stdout: injected as system context before Claude processes the prompt.
|
|
7
|
+
*
|
|
8
|
+
* Logic:
|
|
9
|
+
* - Not a GSD-T project (no .gsd-t/progress.md in cwd) → exit silently
|
|
10
|
+
* - Prompt starts with "/" → exit silently (user typed a command, pass through)
|
|
11
|
+
* - Prompt is plain text → emit [GSD-T AUTO-ROUTE] signal so Claude routes via /gsd
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
const fs = require("fs");
|
|
15
|
+
const path = require("path");
|
|
16
|
+
|
|
17
|
+
let input = "";
|
|
18
|
+
process.stdin.setEncoding("utf8");
|
|
19
|
+
process.stdin.on("data", (chunk) => { input += chunk; });
|
|
20
|
+
process.stdin.on("end", () => {
|
|
21
|
+
try {
|
|
22
|
+
const data = JSON.parse(input);
|
|
23
|
+
// Guard: only activate in GSD-T projects
|
|
24
|
+
const cwd = typeof data.cwd === "string" ? data.cwd : process.cwd();
|
|
25
|
+
if (!fs.existsSync(path.join(cwd, ".gsd-t", "progress.md"))) process.exit(0);
|
|
26
|
+
const prompt = (typeof data.prompt === "string" ? data.prompt : "").trimStart();
|
|
27
|
+
if (prompt.startsWith("/")) process.exit(0); // slash command — pass through
|
|
28
|
+
if (!prompt) process.exit(0); // empty prompt — pass through
|
|
29
|
+
// Plain text prompt in a GSD-T project — inject routing signal
|
|
30
|
+
process.stdout.write(
|
|
31
|
+
"[GSD-T AUTO-ROUTE] The user typed a plain text message (no leading /). " +
|
|
32
|
+
"Route it automatically through the /gsd smart router — execute the /user:gsd " +
|
|
33
|
+
"command with the user's full message as the argument."
|
|
34
|
+
);
|
|
35
|
+
} catch {
|
|
36
|
+
// JSON parse error or any other failure — never block the prompt
|
|
37
|
+
}
|
|
38
|
+
process.exit(0);
|
|
39
|
+
});
|
|
@@ -191,6 +191,8 @@ On session start, a version check hook auto-updates GSD-T and outputs a status m
|
|
|
191
191
|
|
|
192
192
|
Only execute GSD-T workflow behavior when a `/gsd-t-*` command is invoked or when actively mid-phase (resumed via `/gsd-t-resume`). **Plain text messages — especially questions — should be answered conversationally.** Do not launch into workflow execution, file reading, or phase advancement from a question or comment. If the user wants work done, they will invoke a command.
|
|
193
193
|
|
|
194
|
+
**Exception — Auto-Route signal**: When `[GSD-T AUTO-ROUTE]` appears in your context (injected by the UserPromptSubmit hook), the user's plain text message should be treated as a `/user:gsd {message}` invocation. Execute the `/gsd` smart router with the user's full message as the argument instead of replying conversationally. The hook only fires in GSD-T projects (directories containing `.gsd-t/progress.md`) — it silently passes through in all other directories.
|
|
195
|
+
|
|
194
196
|
## Auto-Init Guard
|
|
195
197
|
|
|
196
198
|
Before executing any GSD-T workflow command, check if **any** of these files are missing in the current project:
|