@tekyzinc/gsd-t 2.35.10 → 2.36.10
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 +2 -1
- package/commands/global-change.md +205 -0
- package/commands/gsd-t-help.md +9 -0
- package/docs/GSD-T-README.md +1 -0
- package/package.json +1 -1
- package/scripts/gsd-t-dashboard.html +27 -27
- package/scripts/gsd-t-event-writer.js +1 -0
- package/templates/CLAUDE-global.md +8 -0
package/README.md
CHANGED
|
@@ -20,7 +20,7 @@ A methodology for reliable, parallelizable development using Claude Code with op
|
|
|
20
20
|
npx @tekyzinc/gsd-t install
|
|
21
21
|
```
|
|
22
22
|
|
|
23
|
-
This installs 44 GSD-T commands +
|
|
23
|
+
This installs 44 GSD-T commands + 5 utility commands (49 total) to `~/.claude/commands/` and the global CLAUDE.md to `~/.claude/CLAUDE.md`. Works on Windows, Mac, and Linux.
|
|
24
24
|
|
|
25
25
|
### Start Using It
|
|
26
26
|
|
|
@@ -175,6 +175,7 @@ This will replace changed command files, back up your CLAUDE.md if customized, a
|
|
|
175
175
|
| `/user:branch` | Create and switch to a new git branch | Manual |
|
|
176
176
|
| `/user:checkin` | Auto-bump version, stage, commit, and push | Manual |
|
|
177
177
|
| `/user:Claude-md` | Reload CLAUDE.md directives mid-session | Manual |
|
|
178
|
+
| `/global-change` | Apply file changes across all registered GSD-T projects | Manual |
|
|
178
179
|
|
|
179
180
|
---
|
|
180
181
|
|
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
# GSD-T: Global Change — Apply Changes Across All GSD-T Projects
|
|
2
|
+
|
|
3
|
+
You are applying a file-level change to every GSD-T project registered in `.claude/.gsd-t-projects`. This is a **global** slash command (installed to `~/.claude/commands/`) that enables bulk updates to project configuration, CLAUDE.md files, templates, and any other files that need to stay consistent across the GSD-T ecosystem.
|
|
4
|
+
|
|
5
|
+
## Syntax
|
|
6
|
+
|
|
7
|
+
```
|
|
8
|
+
/global-change <operation> <relative-path/filename> [arguments]
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
### Operations
|
|
12
|
+
|
|
13
|
+
| Operation | Arguments | Description |
|
|
14
|
+
|-----------|-----------|-------------|
|
|
15
|
+
| `copy` | `<relative-path/filename>` | Copy file from the GSD-T package directory to the same relative path in all projects |
|
|
16
|
+
| `insert` | `<relative-path/filename> <content>` | Append content to the specified file in all projects |
|
|
17
|
+
| `update` | `<relative-path/filename> <old_content> %%REPLACE_WITH%% <new_content>` | Find `old_content` in the file and replace it with `new_content` in all projects |
|
|
18
|
+
| `delete` | `<relative-path/filename>` | Delete the specified file from all projects |
|
|
19
|
+
|
|
20
|
+
### Examples
|
|
21
|
+
|
|
22
|
+
```
|
|
23
|
+
/global-change copy .gsd-t/templates/contract.md
|
|
24
|
+
|
|
25
|
+
/global-change insert .gsd-t/config.json {"newSetting": true}
|
|
26
|
+
|
|
27
|
+
/global-change update CLAUDE.md
|
|
28
|
+
- `model: haiku` — mechanical tasks
|
|
29
|
+
- `model: sonnet` (default) — reasoning tasks
|
|
30
|
+
%%REPLACE_WITH%%
|
|
31
|
+
- `model: haiku` — mechanical tasks (same as now)
|
|
32
|
+
- `model: sonnet` — mid-tier reasoning: routine code changes, standard refactors, test writing, straightforward synthesis
|
|
33
|
+
- `model: opus` — high-stakes reasoning: architecture decisions, security analysis, complex debugging, cross-module refactors, quality judgment on critical paths
|
|
34
|
+
|
|
35
|
+
/global-change delete .gsd-t/deprecated-template.md
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
## Step 1: Load the Project Registry
|
|
39
|
+
|
|
40
|
+
Read `~/.claude/.gsd-t-projects`. This file contains one absolute project path per line.
|
|
41
|
+
|
|
42
|
+
```
|
|
43
|
+
# Example .gsd-t-projects
|
|
44
|
+
C:/Users/david/MyNextListen
|
|
45
|
+
C:/Users/david/TimeTracking
|
|
46
|
+
C:/Users/david/tekyz-ai-copilot
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
If the file does not exist or is empty:
|
|
50
|
+
- STOP. Tell the user: "No GSD-T projects registered. Register projects by adding their absolute paths (one per line) to `~/.claude/.gsd-t-projects`."
|
|
51
|
+
- Do NOT proceed.
|
|
52
|
+
|
|
53
|
+
Parse the file:
|
|
54
|
+
- Skip blank lines
|
|
55
|
+
- Skip lines starting with `#` (comments)
|
|
56
|
+
- Trim whitespace from each path
|
|
57
|
+
- Store as `PROJECT_PATHS[]`
|
|
58
|
+
|
|
59
|
+
## Step 2: Parse Arguments
|
|
60
|
+
|
|
61
|
+
Extract from $ARGUMENTS:
|
|
62
|
+
1. **operation** — first word: `copy`, `insert`, `update`, or `delete`
|
|
63
|
+
2. **relative-path/filename** — second token: the file path relative to each project root (e.g., `CLAUDE.md`, `.gsd-t/config.json`, `docs/architecture.md`)
|
|
64
|
+
3. **Remaining arguments** depend on the operation:
|
|
65
|
+
- `copy` — no additional arguments
|
|
66
|
+
- `insert` — everything after the filename is the content to append
|
|
67
|
+
- `update` — everything after the filename is split by the `%%REPLACE_WITH%%` delimiter into **old_content** (before) and **new_content** (after)
|
|
68
|
+
- `delete` — no additional arguments
|
|
69
|
+
|
|
70
|
+
### Parsing the `update` Delimiter
|
|
71
|
+
|
|
72
|
+
For `update` operations, the content portion (everything after the filename) MUST contain the literal string `%%REPLACE_WITH%%` on its own line. Split on this delimiter:
|
|
73
|
+
- **old_content** = trimmed text before `%%REPLACE_WITH%%` — the exact text to find in the target file
|
|
74
|
+
- **new_content** = trimmed text after `%%REPLACE_WITH%%` — the replacement text
|
|
75
|
+
|
|
76
|
+
If the delimiter is missing, STOP and show the user the correct syntax:
|
|
77
|
+
```
|
|
78
|
+
Usage: /global-change update <file> <old content> %%REPLACE_WITH%% <new content>
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
### Validation Rules
|
|
82
|
+
|
|
83
|
+
- If operation is missing or not one of `copy|insert|update|delete` → STOP, show usage syntax
|
|
84
|
+
- If relative-path/filename is missing → STOP, show usage syntax
|
|
85
|
+
- If operation is `insert` and no content is provided → STOP, tell the user content is required
|
|
86
|
+
- If operation is `update` and `%%REPLACE_WITH%%` delimiter is missing → STOP, show correct syntax
|
|
87
|
+
- If operation is `update` and either old_content or new_content is empty → STOP, both sides of the delimiter are required
|
|
88
|
+
- If operation is `copy` and the source file does not exist in the GSD-T package directory → STOP, tell the user the source file was not found
|
|
89
|
+
|
|
90
|
+
### Determine GSD-T Package Directory
|
|
91
|
+
|
|
92
|
+
The source directory for `copy` operations is the installed GSD-T package location. Resolve it by checking (in order):
|
|
93
|
+
1. The directory containing this command file (walk up to the package root)
|
|
94
|
+
2. `node_modules/@tekyz/gsd-t/` relative to the global npm prefix
|
|
95
|
+
3. Ask the user if neither resolves
|
|
96
|
+
|
|
97
|
+
## Step 3: Dry Run — Scan All Projects First
|
|
98
|
+
|
|
99
|
+
Before making any changes, scan every project to preview what will happen. For each project in `PROJECT_PATHS[]`:
|
|
100
|
+
|
|
101
|
+
### For `copy`:
|
|
102
|
+
- Check if the target file already exists → note "will overwrite" or "will create"
|
|
103
|
+
|
|
104
|
+
### For `insert`:
|
|
105
|
+
- Check if the target file exists → note "will append to existing" or "will create new file"
|
|
106
|
+
|
|
107
|
+
### For `update`:
|
|
108
|
+
- Read the target file
|
|
109
|
+
- Search for `old_content` in the file contents
|
|
110
|
+
- If found → note "match found — will replace"
|
|
111
|
+
- If NOT found → note "⚠ NO MATCH — will skip" (do NOT modify files where the old content isn't found)
|
|
112
|
+
- If found multiple times → note "⚠ MULTIPLE MATCHES ([count]) — will replace all occurrences"
|
|
113
|
+
|
|
114
|
+
### For `delete`:
|
|
115
|
+
- Check if the target file exists → note "will delete" or "will skip (not found)"
|
|
116
|
+
|
|
117
|
+
### Display the dry run summary:
|
|
118
|
+
|
|
119
|
+
```
|
|
120
|
+
Global Change — Pre-flight Summary
|
|
121
|
+
Operation: [operation]
|
|
122
|
+
Target: [relative-path/filename]
|
|
123
|
+
Projects: [N] registered
|
|
124
|
+
|
|
125
|
+
[For update — show old/new content preview]
|
|
126
|
+
|
|
127
|
+
Dry run results:
|
|
128
|
+
[status] [project-name] — [description]
|
|
129
|
+
[status] [project-name] — [description]
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
**Level 3 (Full Auto)**: If ALL projects show clean matches (no warnings), auto-proceed to Step 4 without asking. If ANY project shows a warning (no match, multiple matches), pause and ask.
|
|
133
|
+
|
|
134
|
+
**Level 1-2**: Always pause and ask for confirmation.
|
|
135
|
+
|
|
136
|
+
## Step 4: Execute Changes
|
|
137
|
+
|
|
138
|
+
For each project that passed the dry run:
|
|
139
|
+
|
|
140
|
+
### `copy`
|
|
141
|
+
1. Determine the target: `{PROJECT_PATH}/{relative-path/filename}`
|
|
142
|
+
2. If the target directory does not exist → create it (including intermediate directories)
|
|
143
|
+
3. Copy the source file to the target, overwriting if it exists
|
|
144
|
+
|
|
145
|
+
### `insert`
|
|
146
|
+
1. Determine the target: `{PROJECT_PATH}/{relative-path/filename}`
|
|
147
|
+
2. If the target directory does not exist → create it (including intermediate directories)
|
|
148
|
+
3. If the target file does not exist → create it with the provided content
|
|
149
|
+
4. If the target file exists → append a newline + the provided content to the end
|
|
150
|
+
|
|
151
|
+
### `update`
|
|
152
|
+
1. Determine the target: `{PROJECT_PATH}/{relative-path/filename}`
|
|
153
|
+
2. If the file does not exist → skip
|
|
154
|
+
3. Read the file contents
|
|
155
|
+
4. Search for `old_content` (exact string match, whitespace-sensitive)
|
|
156
|
+
5. If NOT found → skip
|
|
157
|
+
6. If found → replace ALL occurrences of `old_content` with `new_content`
|
|
158
|
+
7. Write the modified contents back to the file
|
|
159
|
+
|
|
160
|
+
### `delete`
|
|
161
|
+
1. Determine the target: `{PROJECT_PATH}/{relative-path/filename}`
|
|
162
|
+
2. If the target file does not exist → skip
|
|
163
|
+
3. If the target file exists → delete it
|
|
164
|
+
4. Do NOT delete the parent directory even if empty
|
|
165
|
+
|
|
166
|
+
### Error Handling
|
|
167
|
+
- On failure, record: `FAILED: {error message}`
|
|
168
|
+
- Never abort the entire run because one project failed — continue to the next
|
|
169
|
+
|
|
170
|
+
## Step 5: Report Results
|
|
171
|
+
|
|
172
|
+
Display the final summary:
|
|
173
|
+
|
|
174
|
+
```
|
|
175
|
+
Global Change — Results
|
|
176
|
+
Operation: [operation] [relative-path/filename]
|
|
177
|
+
Succeeded: [N] / [total] projects
|
|
178
|
+
Failed: [N]
|
|
179
|
+
Skipped: [N]
|
|
180
|
+
|
|
181
|
+
[status] [project-name] — [result]
|
|
182
|
+
[status] [project-name] — [result]
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
Status icons:
|
|
186
|
+
- `✓` — success
|
|
187
|
+
- `⊘` — skipped (file not found, no match, etc.)
|
|
188
|
+
- `✗` — failed with error
|
|
189
|
+
|
|
190
|
+
If there were failures, list them with actionable error messages.
|
|
191
|
+
|
|
192
|
+
## Notes
|
|
193
|
+
|
|
194
|
+
- **Relative paths use forward slashes** regardless of OS
|
|
195
|
+
- **No glob patterns** — operates on a single file per invocation
|
|
196
|
+
- **Content for `insert`** can be provided inline or pasted in the user's message
|
|
197
|
+
- **Content for `update`** uses the `%%REPLACE_WITH%%` delimiter — old_content match is exact and whitespace-sensitive
|
|
198
|
+
- **Project names in logs** are derived from the last segment of the project path
|
|
199
|
+
- **The `.gsd-t-projects` file** is maintained by `gsd-t init` (auto-registers) and `gsd-t update-all` (reads)
|
|
200
|
+
|
|
201
|
+
$ARGUMENTS
|
|
202
|
+
|
|
203
|
+
## Auto-Clear
|
|
204
|
+
|
|
205
|
+
All work is committed to project files. Execute `/clear` to free the context window for the next command.
|
package/commands/gsd-t-help.md
CHANGED
|
@@ -62,6 +62,7 @@ UTILITIES Manual
|
|
|
62
62
|
version-update Update GSD-T package to latest version
|
|
63
63
|
version-update-all Update GSD-T package + all registered projects
|
|
64
64
|
triage-and-merge Auto-review, merge, and publish GitHub branches
|
|
65
|
+
global-change Apply file changes across all registered GSD-T projects
|
|
65
66
|
|
|
66
67
|
BACKLOG Manual
|
|
67
68
|
───────────────────────────────────────────────────────────────────────────────
|
|
@@ -347,6 +348,14 @@ Use these when user asks for help on a specific command:
|
|
|
347
348
|
- **Use when**: Collaborators have pushed branches and you want to batch-review, merge, and publish without manual per-branch ceremony
|
|
348
349
|
- **Features**: 3-tier impact scoring (auto-merge / review / skip), publish gate (auto in Level 3, prompted otherwise), conflict detection, sensitive file detection
|
|
349
350
|
|
|
351
|
+
### global-change
|
|
352
|
+
- **Summary**: Apply file changes (copy/insert/update/delete) across all registered GSD-T projects
|
|
353
|
+
- **Auto-invoked**: No
|
|
354
|
+
- **Files**: Reads `~/.claude/.gsd-t-projects`; modifies target file in each registered project
|
|
355
|
+
- **Use when**: You need to make the same change to CLAUDE.md, contracts, templates, or config across multiple projects at once
|
|
356
|
+
- **Operations**: `copy` (file from GSD-T package), `insert` (append content), `update` (find/replace with `%%REPLACE_WITH%%` delimiter), `delete` (remove file)
|
|
357
|
+
- **Features**: Dry run preview, per-project match validation, parallel execution, skip-on-no-match safety
|
|
358
|
+
|
|
350
359
|
### backlog-add
|
|
351
360
|
- **Summary**: Capture a new backlog item with auto-categorization
|
|
352
361
|
- **Auto-invoked**: No
|
package/docs/GSD-T-README.md
CHANGED
|
@@ -122,6 +122,7 @@ GSD-T reads all state files and tells you exactly where you left off.
|
|
|
122
122
|
| `/user:gsd-t-version-update` | Update GSD-T to latest version | Manual |
|
|
123
123
|
| `/user:gsd-t-version-update-all` | Update GSD-T + all registered projects | Manual |
|
|
124
124
|
| `/user:gsd-t-triage-and-merge` | Auto-review, merge, and publish GitHub branches | Manual |
|
|
125
|
+
| `/global-change` | Apply file changes (copy/insert/update/delete) across all GSD-T projects | Manual |
|
|
125
126
|
|
|
126
127
|
### Backlog Management
|
|
127
128
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tekyzinc/gsd-t",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.36.10",
|
|
4
4
|
"description": "GSD-T: Contract-Driven Development for Claude Code — 48 slash commands with 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",
|
|
@@ -23,43 +23,33 @@ body{background:var(--bg);color:var(--text);font-family:var(--font);font-size:12
|
|
|
23
23
|
font-size:10px;border:1px solid;}
|
|
24
24
|
.status.live{background:var(--green-bg);border-color:var(--green);color:var(--green);}
|
|
25
25
|
.status.wait{background:var(--yellow-bg);border-color:var(--yellow);color:var(--yellow);}
|
|
26
|
-
.dot{width:6px;height:6px;border-radius:50%;background:currentColor;
|
|
27
|
-
animation:pdot 1.5s ease-in-out infinite;}
|
|
26
|
+
.dot{width:6px;height:6px;border-radius:50%;background:currentColor;animation:pdot 1.5s ease-in-out infinite;}
|
|
28
27
|
@keyframes pdot{0%,100%{opacity:1}50%{opacity:.3}}
|
|
29
|
-
.hright{margin-left:auto;color:var(--muted);font-size:11px;}
|
|
30
|
-
.
|
|
31
|
-
.
|
|
32
|
-
.rfwrap{width:100%;height:100%;}
|
|
33
|
-
.react-flow__background{background:var(--bg);}
|
|
34
|
-
.react-flow__node{font-family:var(--font);font-size:11px;}
|
|
28
|
+
.hright{margin-left:auto;color:var(--muted);font-size:11px;}.main{display:flex;flex:1;overflow:hidden;}
|
|
29
|
+
.garea{flex:1;position:relative;background:var(--bg);}.rfwrap{width:100%;height:100%;}
|
|
30
|
+
.react-flow__background{background:var(--bg);}.react-flow__node{font-family:var(--font);font-size:11px;}
|
|
35
31
|
.agent-node{background:var(--surface);border:1px solid var(--border);border-radius:6px;
|
|
36
32
|
padding:8px 12px;min-width:120px;text-align:center;}
|
|
37
|
-
.agent-node.success{border-color:var(--green);background:var(--green-bg);}
|
|
38
|
-
.agent-node.
|
|
39
|
-
.
|
|
40
|
-
.agent-node.session{border-color:var(--blue);background:var(--blue-bg);}
|
|
41
|
-
.node-id{color:var(--text);font-weight:500;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;max-width:140px;}
|
|
42
|
-
.node-cnt{color:var(--muted);font-size:9px;margin-top:2px;}
|
|
33
|
+
.agent-node.success{border-color:var(--green);background:var(--green-bg);}.agent-node.failure{border-color:var(--red);background:var(--red-bg);}
|
|
34
|
+
.agent-node.learning,.agent-node.deferred{border-color:var(--yellow);background:var(--yellow-bg);}.agent-node.session{border-color:var(--blue);background:var(--blue-bg);}
|
|
35
|
+
.node-id{color:var(--text);font-weight:500;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;max-width:140px;}.node-cnt{color:var(--muted);font-size:9px;margin-top:2px;}
|
|
43
36
|
.sidebar{width:300px;background:var(--surface);border-left:1px solid var(--border);
|
|
44
37
|
display:flex;flex-direction:column;overflow:hidden;}
|
|
45
38
|
.sb-hdr{padding:10px 12px;border-bottom:1px solid var(--border);color:var(--muted);
|
|
46
39
|
font-size:10px;text-transform:uppercase;letter-spacing:.8px;flex-shrink:0;}
|
|
47
|
-
.feed{flex:1;overflow-y:auto;padding:8px;}
|
|
48
|
-
.feed::-webkit-scrollbar{width:4px;}
|
|
49
|
-
.feed::-webkit-scrollbar-thumb{background:var(--border);border-radius:2px;}
|
|
40
|
+
.feed{flex:1;overflow-y:auto;padding:8px;}.feed::-webkit-scrollbar{width:4px;}.feed::-webkit-scrollbar-thumb{background:var(--border);border-radius:2px;}
|
|
50
41
|
.ev{border-radius:4px;padding:6px 8px;margin-bottom:5px;border-left:3px solid var(--border);
|
|
51
42
|
background:#1c2128;}
|
|
52
|
-
.ev.success{border-left-color:var(--green);}
|
|
53
|
-
.ev.
|
|
54
|
-
.ev.learning,.ev.deferred{border-left-color:var(--yellow);}
|
|
55
|
-
.ev-type{font-weight:500;color:var(--text);font-size:11px;}
|
|
56
|
-
.ev-cmd{color:var(--blue);font-size:10px;margin-top:1px;}
|
|
57
|
-
.ev-ts{color:var(--muted);font-size:9px;margin-top:2px;}
|
|
43
|
+
.ev.success{border-left-color:var(--green);}.ev.failure{border-left-color:var(--red);}.ev.learning,.ev.deferred{border-left-color:var(--yellow);}
|
|
44
|
+
.ev-type{font-weight:500;color:var(--text);font-size:11px;}.ev-cmd{color:var(--blue);font-size:10px;margin-top:1px;}.ev-ts{color:var(--muted);font-size:9px;margin-top:2px;}
|
|
58
45
|
.badge{display:inline-block;font-size:9px;padding:1px 5px;border-radius:3px;font-weight:bold;margin-left:4px;}
|
|
59
|
-
.badge.success{background:var(--green-bg);color:var(--green);}
|
|
60
|
-
.badge.failure{background:var(--red-bg);color:var(--red);}
|
|
61
|
-
.badge.learning,.badge.deferred{background:var(--yellow-bg);color:var(--yellow);}
|
|
46
|
+
.badge.success{background:var(--green-bg);color:var(--green);}.badge.failure{background:var(--red-bg);color:var(--red);}.badge.learning,.badge.deferred{background:var(--yellow-bg);color:var(--yellow);}
|
|
62
47
|
.noevents{color:var(--muted);font-size:11px;padding:12px;text-align:center;}
|
|
48
|
+
.models{padding:8px 12px;border-bottom:1px solid var(--border);flex-shrink:0;}
|
|
49
|
+
.model-row{display:flex;align-items:center;gap:8px;margin-bottom:4px;font-size:11px;}
|
|
50
|
+
.model-name{width:50px;color:var(--text);font-weight:500;}.model-bar-bg{flex:1;height:8px;background:var(--bg);border-radius:4px;overflow:hidden;}
|
|
51
|
+
.model-bar{height:100%;border-radius:4px;transition:width .3s ease;}.model-bar.opus{background:var(--blue);}.model-bar.sonnet{background:var(--green);}.model-bar.haiku{background:var(--yellow);}
|
|
52
|
+
.model-cnt{color:var(--muted);font-size:10px;min-width:20px;text-align:right;}
|
|
63
53
|
</style>
|
|
64
54
|
</head>
|
|
65
55
|
<body>
|
|
@@ -71,6 +61,8 @@ body{background:var(--bg);color:var(--text);font-family:var(--font);font-size:12
|
|
|
71
61
|
<div class="main">
|
|
72
62
|
<div class="garea"><div id="rf-root" class="rfwrap"></div></div>
|
|
73
63
|
<div class="sidebar">
|
|
64
|
+
<div class="sb-hdr">Models Invoked</div>
|
|
65
|
+
<div id="models" class="models"><div class="noevents">No model data yet</div></div>
|
|
74
66
|
<div class="sb-hdr">Live Event Feed</div>
|
|
75
67
|
<div id="feed" class="feed"><div class="noevents">Waiting for events...</div></div>
|
|
76
68
|
</div>
|
|
@@ -109,12 +101,16 @@ function Dashboard(){
|
|
|
109
101
|
const [edges,setEdges,onEdgesChange]=useEdgesState([]);
|
|
110
102
|
const [events,setEvents]=useState([]);
|
|
111
103
|
const agentMap=useRef({});
|
|
104
|
+
const modelCounts=useRef({});
|
|
112
105
|
|
|
113
106
|
const processEvent=useCallback((ev)=>{
|
|
114
107
|
setEvents(prev=>{
|
|
115
108
|
const next=[ev,...prev];
|
|
116
109
|
return next.length>MAX_EVENTS?next.slice(0,MAX_EVENTS):next;
|
|
117
110
|
});
|
|
111
|
+
const m=ev.model||(ev.event_type==='session_start'&&ev.reasoning?ev.reasoning.match(/opus|sonnet|haiku/i):null);
|
|
112
|
+
const mName=m?(typeof m==='string'?m:m[0]).toLowerCase():null;
|
|
113
|
+
if(mName){modelCounts.current[mName]=(modelCounts.current[mName]||0)+1;}
|
|
118
114
|
if(!ev.agent_id)return;
|
|
119
115
|
const id=ev.agent_id;
|
|
120
116
|
const prev=agentMap.current[id]||{count:0,outcome:null,parent:null,nodeType:null,firstTs:null};
|
|
@@ -167,14 +163,18 @@ function Dashboard(){
|
|
|
167
163
|
|
|
168
164
|
useEffect(()=>{
|
|
169
165
|
document.getElementById('ev-count').textContent=`${events.length} event${events.length!==1?'s':''}`;
|
|
166
|
+
const mp=document.getElementById('models'),mc=modelCounts.current,mEntries=Object.entries(mc).sort((a,b)=>b[1]-a[1]);
|
|
167
|
+
if(mEntries.length){const maxC=Math.max(...mEntries.map(e=>e[1]));
|
|
168
|
+
mp.innerHTML=mEntries.map(([n,c])=>`<div class="model-row"><span class="model-name">${n}</span><div class="model-bar-bg"><div class="model-bar ${n}" style="width:${Math.round((c/maxC)*100)}%"></div></div><span class="model-cnt">${c}</span></div>`).join('');}
|
|
170
169
|
const feed=document.getElementById('feed');
|
|
171
170
|
if(!events.length){feed.innerHTML='<div class="noevents">Waiting for events...</div>';return;}
|
|
172
171
|
feed.innerHTML=events.slice(0,50).map(ev=>{
|
|
173
172
|
const oc=outcomeClass(ev.outcome);
|
|
174
173
|
const ts=ev.ts?new Date(ev.ts).toLocaleTimeString():'';
|
|
175
174
|
const cmd=ev.command||ev.phase||'';
|
|
175
|
+
const evModel=ev.model||null;
|
|
176
176
|
return`<div class="ev${oc?' '+oc:''}">
|
|
177
|
-
<div class="ev-type">${ev.event_type||'event'}${oc?`<span class="badge ${oc}">${ev.outcome}</span>`:''}</div>
|
|
177
|
+
<div class="ev-type">${ev.event_type||'event'}${evModel?` <span style="color:var(--muted);font-size:9px">[${evModel}]</span>`:''}${oc?`<span class="badge ${oc}">${ev.outcome}</span>`:''}</div>
|
|
178
178
|
${cmd?`<div class="ev-cmd">${cmd}</div>`:''}
|
|
179
179
|
${ev.reasoning?`<div class="ev-ts" style="color:var(--muted)">${ev.reasoning.slice(0,60)}</div>`:''}
|
|
180
180
|
<div class="ev-ts">${ts}</div>
|
|
@@ -76,6 +76,7 @@ PROJECT or FEATURE or SCAN
|
|
|
76
76
|
| `/user:branch` | Create and switch to a new git branch |
|
|
77
77
|
| `/user:checkin` | Auto-bump version, stage, commit, and push |
|
|
78
78
|
| `/user:Claude-md` | Reload and apply CLAUDE.md directives |
|
|
79
|
+
| `/global-change` | Apply file changes across all registered GSD-T projects |
|
|
79
80
|
|
|
80
81
|
|
|
81
82
|
# Living Documents
|
|
@@ -252,6 +253,13 @@ Report: pass/fail counts and any coverage gaps."
|
|
|
252
253
|
|
|
253
254
|
**QA failure blocks phase completion.** Lead cannot proceed until QA reports PASS or user explicitly overrides.
|
|
254
255
|
|
|
256
|
+
## Model Display (MANDATORY)
|
|
257
|
+
|
|
258
|
+
**Before every subagent spawn, display the model being used to the user:**
|
|
259
|
+
`⚙ [{model}] {command} → {brief description}` (e.g., `⚙ [sonnet] gsd-t-execute → domain: auth-service`, `⚙ [haiku] gsd-t-execute → QA validation`)
|
|
260
|
+
|
|
261
|
+
This gives the user real-time visibility into which model is handling each operation.
|
|
262
|
+
|
|
255
263
|
## API Documentation Guard (Swagger/OpenAPI)
|
|
256
264
|
|
|
257
265
|
**Every API endpoint MUST be documented in a Swagger/OpenAPI spec. No exceptions.**
|