@tekyzinc/gsd-t 2.73.23 → 2.73.24

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,17 @@
2
2
 
3
3
  All notable changes to GSD-T are documented here. Updated with each release.
4
4
 
5
+ ## [2.73.24] - 2026-04-09
6
+
7
+ ### Added
8
+ - **Remove element button** — hover over any component in the list to reveal a red × button. Clicking it excludes the element from review and auto-comments "EXCLUDED — not in Figma design". Excluded count shown in submit stats.
9
+
10
+ ### Fixed
11
+ - **Comment validation removed** — all comments are now accepted (questions, exclusions, feedback). The "don't suggest specific changes" popup no longer blocks submission.
12
+
13
+ ### Changed
14
+ - **Submit stats** show removed count alongside changed/commented.
15
+
5
16
  ## [2.73.23] - 2026-04-09
6
17
 
7
18
  ### Fixed
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tekyzinc/gsd-t",
3
- "version": "2.73.23",
3
+ "version": "2.73.24",
4
4
  "description": "GSD-T: Contract-Driven Development for Claude Code — 56 slash commands with headless CI/CD mode, graph-powered code analysis, real-time agent dashboard, execution intelligence, task telemetry, doc-ripple enforcement, backlog management, impact analysis, test sync, milestone archival, and PRD generation",
5
5
  "author": "Tekyz, Inc.",
6
6
  "license": "MIT",
@@ -195,6 +195,12 @@
195
195
 
196
196
  .component-name { flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
197
197
  .component-type { font-size: 10px; color: #94a3b8; }
198
+ .remove-btn {
199
+ display: none; background: none; border: none; color: #ef4444; font-size: 16px;
200
+ cursor: pointer; padding: 0 4px; line-height: 1; opacity: 0.6;
201
+ }
202
+ .remove-btn:hover { opacity: 1; }
203
+ .component-item:hover .remove-btn { display: block; }
198
204
 
199
205
  /* ── Submit bar ─────────────────────────────────── */
200
206
  .submit-bar {
@@ -801,6 +807,7 @@
801
807
  let inspectActive = false;
802
808
  const changes = new Map(); // componentId → [{path, property, oldValue, newValue}]
803
809
  const comments = new Map(); // componentId → string
810
+ const excluded = new Set(); // componentIds removed from review
804
811
  let currentElementPath = null;
805
812
  let currentStyles = null;
806
813
 
@@ -952,14 +959,28 @@
952
959
  statusClass = "rejected";
953
960
  }
954
961
 
962
+ if (excluded.has(item.id)) return; // skip excluded elements
963
+
955
964
  const div = document.createElement("div");
956
965
  div.className = `component-item${idx === selectedIdx ? " selected" : ""}`;
957
966
  div.innerHTML = `
958
967
  <div class="component-status ${statusClass}"></div>
959
968
  <div class="component-name">${item.name || item.id}</div>
960
969
  <div class="component-type">${item.type || ""}</div>
970
+ <button class="remove-btn" title="Remove from review">×</button>
961
971
  `;
962
- div.addEventListener("click", () => selectComponent(idx));
972
+ div.querySelector(".component-name").addEventListener("click", () => selectComponent(idx));
973
+ div.querySelector(".component-status").addEventListener("click", () => selectComponent(idx));
974
+ div.querySelector(".remove-btn").addEventListener("click", (e) => {
975
+ e.stopPropagation();
976
+ excluded.add(item.id);
977
+ comments.set(item.id, "EXCLUDED — not in Figma design");
978
+ if (selectedIdx === idx) {
979
+ selectedIdx = Math.min(idx, filteredQueue.filter(q => !excluded.has(q.id)).length - 1);
980
+ }
981
+ renderComponentList();
982
+ updateSubmitStats();
983
+ });
963
984
  componentList.appendChild(div);
964
985
  });
965
986
  }
@@ -2110,21 +2131,20 @@
2110
2131
  // ── Submit ────────────────────────────────────────
2111
2132
  function updateSubmitStats() {
2112
2133
  const total = queue.length;
2134
+ const excludedCount = excluded.size;
2113
2135
  const changed = Array.from(changes.keys()).filter(id => (changes.get(id) || []).length > 0).length;
2114
- const commented = comments.size;
2115
-
2116
- if (changed > 0 || commented > 0) {
2117
- submitStats.innerHTML = `
2118
- <span><span class="component-status changed" style="display:inline-block"></span> ${changed} changed</span>
2119
- <span><span class="component-status rejected" style="display:inline-block"></span> ${commented} commented</span>
2120
- <span style="color:var(--text-dim)">${total} total</span>
2121
- `;
2122
- } else {
2123
- submitStats.innerHTML = `<span style="color:var(--text-dim)">${total} elements no changes</span>`;
2124
- }
2125
-
2126
- submitAll.textContent = changed > 0 || commented > 0
2127
- ? `Submit (${changed} changes, ${commented} comments)`
2136
+ const commented = Array.from(comments.keys()).filter(id => !excluded.has(id)).length;
2137
+
2138
+ const parts = [];
2139
+ if (changed > 0) parts.push(`<span><span class="component-status changed" style="display:inline-block"></span> ${changed} changed</span>`);
2140
+ if (commented > 0) parts.push(`<span><span class="component-status rejected" style="display:inline-block"></span> ${commented} commented</span>`);
2141
+ if (excludedCount > 0) parts.push(`<span style="color:#ef4444">${excludedCount} removed</span>`);
2142
+ parts.push(`<span style="color:var(--text-dim)">${total - excludedCount} of ${total}</span>`);
2143
+ submitStats.innerHTML = parts.join(" ");
2144
+
2145
+ const actionCount = changed + commented + excludedCount;
2146
+ submitAll.textContent = actionCount > 0
2147
+ ? `Submit (${changed} changes, ${commented} comments, ${excludedCount} removed)`
2128
2148
  : "Submit — Approve All";
2129
2149
  }
2130
2150
 
@@ -2136,28 +2156,7 @@
2136
2156
  else comments.delete(filteredQueue[selectedIdx].id);
2137
2157
  }
2138
2158
 
2139
- // Check for non-actionable comments (documentation, not change requests)
2140
- const actionWords = /change|make|set|move|add|remove|reduce|increase|fix|use|switch|replace|adjust|align|center|should be|needs to|too |bigger|smaller|wider|narrower|thicker|thinner|lighter|darker|bolder|px|rem|%|#[0-9a-f]/i;
2141
- const docComments = [];
2142
- for (const [compId, comment] of comments) {
2143
- if (!actionWords.test(comment)) {
2144
- const item = queue.find(q => q.id === compId);
2145
- docComments.push(item ? item.name : compId);
2146
- }
2147
- }
2148
- if (docComments.length > 0) {
2149
- const proceed = confirm(
2150
- "These comments don't suggest specific changes:\n\n" +
2151
- docComments.map(n => " \u2022 " + n).join("\n") +
2152
- "\n\nComments should describe what to change, e.g.:\n" +
2153
- ' "make padding 8px"\n "use darker blue"\n "reduce gap between title and chart"\n\n' +
2154
- "Non-actionable comments will be discarded.\n\nSubmit anyway?"
2155
- );
2156
- if (!proceed) return;
2157
- for (const [compId, comment] of comments) {
2158
- if (!actionWords.test(comment)) comments.delete(compId);
2159
- }
2160
- }
2159
+ // All comments are accepted — questions, exclusions, and change requests alike
2161
2160
 
2162
2161
  // Build feedback: each element gets its changes and comments
2163
2162
  const feedback = queue.map(item => ({