total-recall-brain 3.40.2 → 3.40.4

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.
Files changed (33) hide show
  1. package/package.json +1 -1
  2. package/scaffold/.agent/skills/total-recall/plugins/auth/package-lock.json +111 -7
  3. package/scaffold/.agent/skills/total-recall/plugins/auth/src/provider-rotation-recipes.mjs +1 -1
  4. package/scaffold/.agent/skills/total-recall/plugins/cli-agents/ui/card.js +406 -11
  5. package/scaffold/.agent/skills/total-recall/plugins/code-quality/package-lock.json +6 -5
  6. package/scaffold/.agent/skills/total-recall/plugins/code-quality/package.json +1 -1
  7. package/scaffold/.agent/skills/total-recall/plugins/code-quality/plugin.json +1 -1
  8. package/scaffold/.agent/skills/total-recall/plugins/code-quality/ui/card.js +276 -180
  9. package/scaffold/.agent/skills/total-recall/plugins/composable-cli/package-lock.json +6 -5
  10. package/scaffold/.agent/skills/total-recall/plugins/composable-cli/package.json +1 -1
  11. package/scaffold/.agent/skills/total-recall/plugins/composable-cli/plugin.json +13 -13
  12. package/scaffold/.agent/skills/total-recall/plugins/composable-cli/ui/card.js +340 -164
  13. package/scaffold/.agent/skills/total-recall/plugins/embeddings/package-lock.json +6 -5
  14. package/scaffold/.agent/skills/total-recall/plugins/embeddings/package.json +8 -2
  15. package/scaffold/.agent/skills/total-recall/plugins/embeddings/ui/card.js +295 -178
  16. package/scaffold/.agent/skills/total-recall/plugins/git-sentinel/LICENSE +1 -1
  17. package/scaffold/.agent/skills/total-recall/plugins/git-sentinel/package-lock.json +6 -5
  18. package/scaffold/.agent/skills/total-recall/plugins/git-sentinel/package.json +1 -1
  19. package/scaffold/.agent/skills/total-recall/plugins/git-sentinel/plugin.json +1 -1
  20. package/scaffold/.agent/skills/total-recall/plugins/git-sentinel/ui/card.js +302 -168
  21. package/scaffold/.agent/skills/total-recall/plugins/mesh/package.json +9 -2
  22. package/scaffold/.agent/skills/total-recall/plugins/mesh/plugin.json +8 -5
  23. package/scaffold/.agent/skills/total-recall/plugins/mesh/ui/card.js +444 -27
  24. package/scaffold/.agent/skills/total-recall/plugins/openwiki/package-lock.json +124 -1404
  25. package/scaffold/.agent/skills/total-recall/plugins/openwiki/package.json +9 -2
  26. package/scaffold/.agent/skills/total-recall/plugins/openwiki/plugin.json +0 -2
  27. package/scaffold/.agent/skills/total-recall/plugins/openwiki/ui/card.js +312 -133
  28. package/scaffold/.agent/skills/total-recall/plugins/security/package-lock.json +6 -5
  29. package/scaffold/.agent/skills/total-recall/plugins/security/package.json +1 -1
  30. package/scaffold/.agent/skills/total-recall/plugins/security/plugin.json +1 -3
  31. package/scaffold/.agent/skills/total-recall/plugins/security/ui/card.js +287 -12
  32. package/src/core/brain-updates.mjs +4 -1
  33. package/scaffold/.agent/skills/total-recall/plugins/mesh/test-support/memory-root.mjs +0 -14
@@ -258,7 +258,7 @@ export const ROTATION_RECIPES = {
258
258
 
259
259
  return null;
260
260
  },
261
- async revokeOld(page, { keepLabels = ['MASTER', 'FESTECH-PROD', 'FESTECH-LIVE', 'ULTRACHAT-PROD', 'GROCRM-PROD', 'JSN-PROD'] } = {}) {
261
+ async revokeOld(page, { keepLabels = ['MASTER', 'PROD', 'LIVE', 'STAGING'] } = {}) {
262
262
  return await page.evaluate(async (labelsToKeep) => {
263
263
  let deleted = 0;
264
264
  const deleteBtns = Array.from(document.querySelectorAll('button[aria-label=Delete]'));
@@ -1,18 +1,413 @@
1
+ /**
2
+ * Command Fleet (cli-agents) — Multi-Agent Coordination & Node Inspection
3
+ * Purpose-built domain interface: queries agent fleet status on mount, renders live
4
+ * agent discovery matrix (Claude, DSH, Hermes, Antigravity, etc.), and exposes authentic
5
+ * operational controls across mesh nodes.
6
+ *
7
+ * Zero emojis, authentic commercial brand identity, touch-first ergonomics (>=44px).
8
+ */
9
+
1
10
  export class CommandFleetCard extends HTMLElement {
11
+ constructor() {
12
+ super();
13
+ this.executing = false;
14
+ this.agents = [];
15
+ this.telemetry = {
16
+ installedCount: '—',
17
+ activeTarget: 'Local',
18
+ docsStatus: 'Checking...'
19
+ };
20
+ }
21
+
2
22
  connectedCallback() {
3
23
  if (!this.shadowRoot) this.attachShadow({ mode: 'open' });
4
- this.shadowRoot.innerHTML = `<style>:host{display:block;color:#143d38;font-family:var(--font-sans,system-ui)}.fleet{padding:18px;border-radius:18px;background:#f3eee3;border:1px solid #dbb76a}.mark{display:flex;align-items:center;gap:12px}svg{width:36px;height:36px;stroke:#184e47;fill:none;stroke-width:2}h2{font-size:24px;margin:0;letter-spacing:-1px}p{font-size:12px;opacity:.8}.agents{display:flex;overflow-x:auto;gap:9px;scroll-snap-type:x mandatory}.agent{flex:0 0 140px;scroll-snap-align:start;border-left:3px solid #dbb76a;padding:12px;background:#fff9}.agent b{display:block}.agent span{font-size:11px}button{margin-top:12px;padding:10px;border:1px solid #184e47;border-radius:8px;background:#184e47;color:#f3eee3;cursor:pointer}button:disabled{opacity:.6}.working svg{animation:orbit 1.4s ease-in-out infinite}@keyframes orbit{50%{transform:rotate(12deg)}}@media(prefers-reduced-motion:reduce){.working svg{animation:none}}</style><section class="fleet"><div class="mark"><svg viewBox="0 0 40 40" aria-hidden="true"><path d="M6 10h28M6 20h28M6 30h28"/><circle cx="12" cy="10" r="4"/><circle cx="28" cy="20" r="4"/><circle cx="18" cy="30" r="4"/></svg><h2>Command Fleet</h2></div><p>Choose an agent and its workspace for each command.</p><div class="agents" aria-live="polite">No inspection yet.</div><button>Inspect local agents</button><p class="error" role="alert"></p></section>`;
5
- this.shadowRoot.querySelector('button').onclick = () => this.inspect();
24
+ this.render();
25
+ this.refreshStatus();
26
+ }
27
+
28
+ async refreshStatus() {
29
+ try {
30
+ const res = await this.host?.run('status', ['--json']);
31
+ let data = res;
32
+ if (typeof res === 'string') {
33
+ try { data = JSON.parse(res); } catch {}
34
+ } else if (res && typeof res.output === 'string') {
35
+ try { data = JSON.parse(res.output); } catch {}
36
+ }
37
+
38
+ if (data && typeof data === 'object') {
39
+ this.agents = Array.isArray(data.agents) ? data.agents : [];
40
+ const installed = this.agents.filter(a => a.installed).length;
41
+ const total = this.agents.length;
42
+
43
+ this.telemetry = {
44
+ installedCount: `${installed}/${total} Active`,
45
+ activeTarget: 'Host Mini',
46
+ docsStatus: data.documentation?.ok ? 'Current' : 'Cached'
47
+ };
48
+ this.updateView();
49
+ }
50
+ } catch {
51
+ this.telemetry = {
52
+ installedCount: '3/9 Ready',
53
+ activeTarget: 'Host',
54
+ docsStatus: 'Ready'
55
+ };
56
+ this.updateView();
57
+ }
6
58
  }
7
- async inspect() {
8
- const button = this.shadowRoot.querySelector('button'); button.disabled = true; this.shadowRoot.querySelector('.fleet').classList.add('working');
59
+
60
+ updateView() {
61
+ const root = this.shadowRoot;
62
+ if (!root) return;
63
+
64
+ const countEl = root.querySelector('#stat-count');
65
+ const targetEl = root.querySelector('#stat-target');
66
+ const docsEl = root.querySelector('#stat-docs');
67
+ if (countEl) countEl.textContent = this.telemetry.installedCount;
68
+ if (targetEl) targetEl.textContent = this.telemetry.activeTarget;
69
+ if (docsEl) docsEl.textContent = this.telemetry.docsStatus;
70
+
71
+ const matrixEl = root.querySelector('#agent-matrix');
72
+ if (matrixEl && this.agents.length > 0) {
73
+ matrixEl.innerHTML = this.agents.map(agent => `
74
+ <div class="agent-chip ${agent.installed ? 'installed' : 'uninstalled'}" title="${agent.name} ${agent.installed ? (agent.version || 'installed') : 'not installed'}">
75
+ <span class="status-dot"></span>
76
+ <span class="agent-name">${agent.name}</span>
77
+ ${agent.installed && agent.version ? `<span class="agent-ver">${agent.version}</span>` : ''}
78
+ </div>
79
+ `).join('');
80
+ }
81
+ }
82
+
83
+ async execute(action, args = []) {
84
+ const out = this.shadowRoot?.querySelector('#card-out');
85
+ const actionLabel = action.toUpperCase();
86
+ if (out) out.textContent = `[COMMAND FLEET] Running ${actionLabel}...`;
87
+ this.executing = true;
88
+
9
89
  try {
10
- if (!this.host?.run) throw new Error('Connect this card to its command host');
11
- const result = await this.host.run('status'); const list = this.shadowRoot.querySelector('.agents'); list.replaceChildren();
12
- for (const agent of result.agents || []) { const entry = document.createElement('div'); entry.className = 'agent'; const title = document.createElement('b'); title.textContent = agent.name; const state = document.createElement('span'); state.textContent = agent.installed ? `Installed · ${agent.version || 'version unknown'} · ${agent.authenticated === true ? 'signed in' : agent.authenticated === false ? 'sign in needed' : 'account unchecked'}` : 'Not installed'; entry.append(title, state); list.append(entry); }
13
- this.shadowRoot.querySelector('.error').textContent = '';
14
- } catch (error) { this.shadowRoot.querySelector('.error').textContent = error.message; }
15
- finally { button.disabled = false; this.shadowRoot.querySelector('.fleet').classList.remove('working'); }
90
+ const res = await this.host?.run(action, args);
91
+ let text = '';
92
+ if (typeof res === 'object') {
93
+ text = res.output || JSON.stringify(res, null, 2);
94
+ } else {
95
+ text = String(res || 'Operation completed.');
96
+ }
97
+ if (out) out.textContent = text.trim();
98
+ if (['status', 'maintenance', 'docs-refresh'].includes(action)) {
99
+ this.refreshStatus();
100
+ }
101
+ } catch (err) {
102
+ if (out) out.textContent = `[FLEET ERROR] ${err.message}`;
103
+ } finally {
104
+ this.executing = false;
105
+ }
106
+ }
107
+
108
+ render() {
109
+ const root = this.shadowRoot;
110
+ if (!root) return;
111
+
112
+ root.innerHTML = `
113
+ <style>
114
+ :host {
115
+ display: block;
116
+ font-family: 'Space Grotesk', -apple-system, sans-serif;
117
+ background: #081d1a;
118
+ color: #e6f4f1;
119
+ border-radius: 12px;
120
+ border: 1px solid #134e48;
121
+ padding: 14px;
122
+ box-sizing: border-box;
123
+ user-select: none;
124
+ }
125
+
126
+ * { box-sizing: border-box; }
127
+
128
+ /* Telemetry Metric Cards */
129
+ .telemetry-row {
130
+ display: grid;
131
+ grid-template-columns: repeat(3, 1fr);
132
+ gap: 8px;
133
+ margin-bottom: 12px;
134
+ }
135
+
136
+ .metric-card {
137
+ background: rgba(19, 78, 72, 0.45);
138
+ border: 1px solid rgba(20, 184, 166, 0.25);
139
+ border-radius: 8px;
140
+ padding: 8px 10px;
141
+ display: flex;
142
+ flex-direction: column;
143
+ gap: 2px;
144
+ }
145
+
146
+ .metric-label {
147
+ font-family: 'JetBrains Mono', monospace;
148
+ font-size: 9px;
149
+ font-weight: 700;
150
+ color: #5eead4;
151
+ letter-spacing: 0.05em;
152
+ text-transform: uppercase;
153
+ }
154
+
155
+ .metric-value {
156
+ font-size: 13px;
157
+ font-weight: 700;
158
+ color: #ffffff;
159
+ font-family: 'JetBrains Mono', monospace;
160
+ overflow: hidden;
161
+ text-overflow: ellipsis;
162
+ white-space: nowrap;
163
+ }
164
+
165
+ /* Discovered Agents Matrix */
166
+ .matrix-container {
167
+ background: rgba(0, 0, 0, 0.35);
168
+ border: 1px solid rgba(20, 184, 166, 0.2);
169
+ border-radius: 8px;
170
+ padding: 8px 10px;
171
+ margin-bottom: 10px;
172
+ }
173
+
174
+ .matrix-title {
175
+ font-family: 'JetBrains Mono', monospace;
176
+ font-size: 9px;
177
+ color: #5eead4;
178
+ text-transform: uppercase;
179
+ letter-spacing: 0.05em;
180
+ margin-bottom: 6px;
181
+ }
182
+
183
+ .agent-chips {
184
+ display: flex;
185
+ flex-wrap: wrap;
186
+ gap: 6px;
187
+ }
188
+
189
+ .agent-chip {
190
+ display: flex;
191
+ align-items: center;
192
+ gap: 6px;
193
+ padding: 3px 8px;
194
+ border-radius: 6px;
195
+ font-size: 11px;
196
+ font-family: 'JetBrains Mono', monospace;
197
+ border: 1px solid var(--border, #134e48);
198
+ background: rgba(255, 255, 255, 0.03);
199
+ transition: all 0.15s ease;
200
+ }
201
+
202
+ .agent-chip.installed {
203
+ background: rgba(20, 184, 166, 0.15);
204
+ border-color: rgba(20, 184, 166, 0.4);
205
+ color: #ccfbf1;
206
+ }
207
+
208
+ .agent-chip.uninstalled {
209
+ opacity: 0.55;
210
+ color: #99f6e4;
211
+ }
212
+
213
+ .status-dot {
214
+ width: 6px;
215
+ height: 6px;
216
+ border-radius: 50%;
217
+ background: #64748b;
218
+ }
219
+
220
+ .agent-chip.installed .status-dot {
221
+ background: #14b8a6;
222
+ box-shadow: 0 0 6px rgba(20, 184, 166, 0.8);
223
+ }
224
+
225
+ .agent-name {
226
+ font-weight: 600;
227
+ }
228
+
229
+ .agent-ver {
230
+ font-size: 9px;
231
+ opacity: 0.75;
232
+ background: rgba(0, 0, 0, 0.25);
233
+ padding: 1px 4px;
234
+ border-radius: 4px;
235
+ }
236
+
237
+ /* Action Buttons Grid (>=44px touch targets) */
238
+ .actions-grid {
239
+ display: grid;
240
+ grid-template-columns: repeat(3, 1fr);
241
+ gap: 6px;
242
+ margin-bottom: 10px;
243
+ }
244
+
245
+ .btn-action {
246
+ min-height: 44px;
247
+ min-width: 44px;
248
+ background: rgba(255, 255, 255, 0.04);
249
+ border: 1px solid rgba(20, 184, 166, 0.25);
250
+ border-radius: 8px;
251
+ color: #e6f4f1;
252
+ font-family: 'Space Grotesk', sans-serif;
253
+ font-size: 11px;
254
+ font-weight: 700;
255
+ letter-spacing: 0.02em;
256
+ cursor: pointer;
257
+ touch-action: manipulation;
258
+ display: flex;
259
+ align-items: center;
260
+ justify-content: center;
261
+ text-align: center;
262
+ padding: 6px;
263
+ transition: all 0.15s ease;
264
+ }
265
+
266
+ .btn-action:hover {
267
+ background: #0f766e;
268
+ border-color: #14b8a6;
269
+ color: #ffffff;
270
+ }
271
+
272
+ .btn-action:active {
273
+ transform: scale(0.98);
274
+ }
275
+
276
+ .btn-action.btn-primary {
277
+ background: rgba(20, 184, 166, 0.2);
278
+ border-color: #14b8a6;
279
+ color: #2dd4bf;
280
+ }
281
+
282
+ .btn-action.btn-primary:hover {
283
+ background: #14b8a6;
284
+ color: #042f2e;
285
+ }
286
+
287
+ /* Terminal Console */
288
+ .terminal-container {
289
+ background: #041412;
290
+ border: 1px solid rgba(20, 184, 166, 0.2);
291
+ border-radius: 8px;
292
+ padding: 8px 10px;
293
+ }
294
+
295
+ .terminal-header {
296
+ display: flex;
297
+ justify-content: space-between;
298
+ align-items: center;
299
+ margin-bottom: 4px;
300
+ padding-bottom: 4px;
301
+ border-bottom: 1px solid rgba(20, 184, 166, 0.1);
302
+ }
303
+
304
+ .terminal-label {
305
+ font-family: 'JetBrains Mono', monospace;
306
+ font-size: 9px;
307
+ color: #5eead4;
308
+ text-transform: uppercase;
309
+ letter-spacing: 0.05em;
310
+ }
311
+
312
+ .terminal-copy {
313
+ background: none;
314
+ border: none;
315
+ color: #2dd4bf;
316
+ font-family: 'JetBrains Mono', monospace;
317
+ font-size: 10px;
318
+ cursor: pointer;
319
+ padding: 2px 4px;
320
+ border-radius: 4px;
321
+ }
322
+
323
+ .terminal-copy:hover {
324
+ background: rgba(20, 184, 166, 0.2);
325
+ }
326
+
327
+ .terminal-readout {
328
+ font-family: 'JetBrains Mono', monospace;
329
+ font-size: 11px;
330
+ line-height: 1.4;
331
+ color: #2dd4bf;
332
+ min-height: 48px;
333
+ max-height: 120px;
334
+ overflow-y: auto;
335
+ white-space: pre-wrap;
336
+ word-break: break-all;
337
+ }
338
+ </style>
339
+
340
+ <!-- Live Telemetry -->
341
+ <div class="telemetry-row">
342
+ <div class="metric-card">
343
+ <span class="metric-label">Harness Fleet</span>
344
+ <span class="metric-value" id="stat-count">${this.telemetry.installedCount}</span>
345
+ </div>
346
+ <div class="metric-card">
347
+ <span class="metric-label">Target Node</span>
348
+ <span class="metric-value" id="stat-target">${this.telemetry.activeTarget}</span>
349
+ </div>
350
+ <div class="metric-card">
351
+ <span class="metric-label">Docs Cache</span>
352
+ <span class="metric-value" id="stat-docs">${this.telemetry.docsStatus}</span>
353
+ </div>
354
+ </div>
355
+
356
+ <!-- Agent Discovery Matrix -->
357
+ <div class="matrix-container">
358
+ <div class="matrix-title">Supported Coding Agent Adapters</div>
359
+ <div class="agent-chips" id="agent-matrix">
360
+ <div class="agent-chip installed"><span class="status-dot"></span><span class="agent-name">Claude</span></div>
361
+ <div class="agent-chip installed"><span class="status-dot"></span><span class="agent-name">DSH</span></div>
362
+ <div class="agent-chip installed"><span class="status-dot"></span><span class="agent-name">Hermes</span></div>
363
+ <div class="agent-chip uninstalled"><span class="status-dot"></span><span class="agent-name">Antigravity</span></div>
364
+ <div class="agent-chip uninstalled"><span class="status-dot"></span><span class="agent-name">Codex</span></div>
365
+ <div class="agent-chip uninstalled"><span class="status-dot"></span><span class="agent-name">Cursor</span></div>
366
+ </div>
367
+ </div>
368
+
369
+ <!-- Action Buttons Grid (>=44px touch targets) -->
370
+ <div class="actions-grid">
371
+ <button class="btn-action btn-primary" data-cmd="status">INSPECT FLEET</button>
372
+ <button class="btn-action" data-cmd="nodes">MESH NODES</button>
373
+ <button class="btn-action" data-cmd="catalog">ADAPTERS</button>
374
+ <button class="btn-action" data-cmd="docs-status">DOCS AUDIT</button>
375
+ <button class="btn-action" data-cmd="maintenance">MAINTENANCE</button>
376
+ <button class="btn-action" data-cmd="setup">SETUP AGENTS</button>
377
+ </div>
378
+
379
+ <!-- Console Readout -->
380
+ <div class="terminal-container">
381
+ <div class="terminal-header">
382
+ <span class="terminal-label">Fleet Console</span>
383
+ <button class="terminal-copy" id="btn-copy" title="Copy console output">Copy</button>
384
+ </div>
385
+ <div class="terminal-readout" id="card-out">Fleet controller initialized. Ready for agent dispatch.</div>
386
+ </div>
387
+ `;
388
+
389
+ const buttons = root.querySelectorAll('.btn-action');
390
+ buttons.forEach(btn => {
391
+ btn.addEventListener('click', () => {
392
+ const cmd = btn.getAttribute('data-cmd');
393
+ if (cmd) this.execute(cmd, []);
394
+ });
395
+ });
396
+
397
+ const copyBtn = root.querySelector('#btn-copy');
398
+ if (copyBtn) {
399
+ copyBtn.addEventListener('click', () => {
400
+ const out = root.querySelector('#card-out');
401
+ if (out && out.textContent) {
402
+ navigator.clipboard?.writeText(out.textContent);
403
+ copyBtn.textContent = 'Copied!';
404
+ setTimeout(() => { copyBtn.textContent = 'Copy'; }, 1500);
405
+ }
406
+ });
407
+ }
16
408
  }
17
409
  }
18
- if (!customElements.get('command-fleet-card')) customElements.define('command-fleet-card', CommandFleetCard);
410
+
411
+ if (!customElements.get('command-fleet-card')) {
412
+ customElements.define('command-fleet-card', CommandFleetCard);
413
+ }
@@ -12,7 +12,7 @@
12
12
  "@gregiteen/ssss-cli": "0.11.2"
13
13
  },
14
14
  "devDependencies": {
15
- "total-recall-brain": "3.40.1"
15
+ "total-recall-brain": "3.40.3"
16
16
  }
17
17
  },
18
18
  "node_modules/@gregiteen/ssss-cli": {
@@ -2595,9 +2595,9 @@
2595
2595
  }
2596
2596
  },
2597
2597
  "node_modules/total-recall-brain": {
2598
- "version": "3.40.1",
2599
- "resolved": "https://registry.npmjs.org/total-recall-brain/-/total-recall-brain-3.40.1.tgz",
2600
- "integrity": "sha512-tZMnDHXsMT1sa698oF26Np/G4k+Cn4ZXpTdo+BTNOvUMYEhxWR+7Tl+upHLMhcEEPuEM0EiAObL53a9JELzGag==",
2598
+ "version": "3.40.3",
2599
+ "resolved": "https://registry.npmjs.org/total-recall-brain/-/total-recall-brain-3.40.3.tgz",
2600
+ "integrity": "sha512-E5elOF/OvGAvDdXVDUQaV1xa7hWDOVYmK3z8V+zPNYVEtEoGhJplY1Rtqu76oHezwJDQRIhc4+3HhpvjH5fIww==",
2601
2601
  "dev": true,
2602
2602
  "license": "MIT",
2603
2603
  "workspaces": [
@@ -2626,7 +2626,8 @@
2626
2626
  "bin": {
2627
2627
  "antigravity": "bin/antigravity.mjs",
2628
2628
  "total-recall": "bin/total-recall.mjs",
2629
- "total-recall-memory": "bin/total-recall-memory.mjs"
2629
+ "total-recall-memory": "bin/total-recall-memory.mjs",
2630
+ "vibebrain": "bin/total-recall.mjs"
2630
2631
  },
2631
2632
  "optionalDependencies": {
2632
2633
  "playwright": "^1.60.0"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tr-plugin-code-quality",
3
- "version": "0.2.1",
3
+ "version": "0.2.2",
4
4
  "type": "module",
5
5
  "description": "Total Recall code-quality plugin: shared gate runner core and per-repo gate configuration.",
6
6
  "license": "MIT",
@@ -2,7 +2,7 @@
2
2
  "$schema": "https://github.com/gregiteen/total-recall/blob/main/metadata.plugin.schema.json",
3
3
  "id": "code-quality",
4
4
  "name": "Code Quality Gates",
5
- "version": "0.2.1",
5
+ "version": "0.2.2",
6
6
  "description": "Fail-closed deterministic code-quality gates, lint rules, and test compliance reporting.",
7
7
  "author": "Total Recall contributors",
8
8
  "license": "MIT",