total-recall-brain 3.40.3 → 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 (31) 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/code-quality/package-lock.json +6 -5
  5. package/scaffold/.agent/skills/total-recall/plugins/code-quality/package.json +1 -1
  6. package/scaffold/.agent/skills/total-recall/plugins/code-quality/plugin.json +1 -1
  7. package/scaffold/.agent/skills/total-recall/plugins/composable-cli/package-lock.json +6 -5
  8. package/scaffold/.agent/skills/total-recall/plugins/composable-cli/package.json +1 -1
  9. package/scaffold/.agent/skills/total-recall/plugins/composable-cli/plugin.json +13 -13
  10. package/scaffold/.agent/skills/total-recall/plugins/composable-cli/ui/card.js +340 -164
  11. package/scaffold/.agent/skills/total-recall/plugins/embeddings/package-lock.json +6 -5
  12. package/scaffold/.agent/skills/total-recall/plugins/embeddings/package.json +8 -2
  13. package/scaffold/.agent/skills/total-recall/plugins/embeddings/ui/card.js +295 -178
  14. package/scaffold/.agent/skills/total-recall/plugins/git-sentinel/LICENSE +1 -1
  15. package/scaffold/.agent/skills/total-recall/plugins/git-sentinel/package-lock.json +6 -5
  16. package/scaffold/.agent/skills/total-recall/plugins/git-sentinel/package.json +1 -1
  17. package/scaffold/.agent/skills/total-recall/plugins/git-sentinel/plugin.json +1 -1
  18. package/scaffold/.agent/skills/total-recall/plugins/git-sentinel/ui/card.js +302 -168
  19. package/scaffold/.agent/skills/total-recall/plugins/mesh/package.json +9 -2
  20. package/scaffold/.agent/skills/total-recall/plugins/mesh/plugin.json +8 -5
  21. package/scaffold/.agent/skills/total-recall/plugins/mesh/ui/card.js +444 -27
  22. package/scaffold/.agent/skills/total-recall/plugins/openwiki/package-lock.json +124 -1404
  23. package/scaffold/.agent/skills/total-recall/plugins/openwiki/package.json +9 -2
  24. package/scaffold/.agent/skills/total-recall/plugins/openwiki/plugin.json +0 -2
  25. package/scaffold/.agent/skills/total-recall/plugins/openwiki/ui/card.js +312 -133
  26. package/scaffold/.agent/skills/total-recall/plugins/security/package-lock.json +6 -5
  27. package/scaffold/.agent/skills/total-recall/plugins/security/package.json +1 -1
  28. package/scaffold/.agent/skills/total-recall/plugins/security/plugin.json +1 -3
  29. package/scaffold/.agent/skills/total-recall/plugins/security/ui/card.js +287 -12
  30. package/src/core/brain-updates.mjs +4 -1
  31. package/scaffold/.agent/skills/total-recall/plugins/mesh/test-support/memory-root.mjs +0 -14
@@ -2,18 +2,291 @@ export class SecuritySecurityCard extends HTMLElement {
2
2
  connectedCallback() {
3
3
  if (this.shadowRoot) return;
4
4
  const root = this.attachShadow({ mode: 'open' });
5
- root.innerHTML = `<style>
6
- :host{display:block;color:#edf3fa;background:#16222e;font:14px system-ui;border-radius:12px;padding:18px}header{display:flex;align-items:center;gap:12px}svg{width:32px;height:38px;color:#73d6bf}h2{margin:0;font-size:20px}p{color:#bbcad6;line-height:1.5}nav{display:flex;gap:8px;flex-wrap:wrap}button,input,select{min-height:44px;border:1px solid #71928e;border-radius:6px;padding:8px 12px;background:#213644;color:inherit}button{cursor:pointer}button:disabled{opacity:.5}input{min-width:0;flex:1}#state{margin:14px 0;color:#73d6bf}table{width:100%;border-collapse:collapse}td,th{padding:10px 6px;text-align:left;border-bottom:1px solid #3a4e5c;vertical-align:top}td:last-child{line-height:1.5}pre{white-space:pre-wrap;overflow-wrap:anywhere;max-height:360px;overflow:auto}.scroll{overflow:auto}
7
- </style><header><svg viewBox="0 0 32 38" fill="none" aria-hidden="true"><path d="M16 2 29 8v11c0 8-7 14-13 17C10 33 3 27 3 19V8Z" stroke="currentColor" stroke-width="2"/><path d="m9 19 5 5 10-12" stroke="currentColor" stroke-width="2"/></svg><h2>Security Assessments</h2></header>
8
- <p>Inspect this machine or your mesh. Review firewall, SSH, disk protection, and listening services with concrete remediation.</p>
9
- <nav><button data-action="machine">This machine</button><button data-action="fleet">Mesh fleet</button><button data-action="plugins">Plugin audit</button><button data-action="harden">Hardening plan</button></nav>
10
- <nav style="margin-top:10px"><input id="target" aria-label="Machine name" placeholder="Optional mesh machine name"><button id="selected">Audit selected</button></nav>
11
- <nav style="margin-top:10px"><input id="website" type="url" aria-label="Authorized HTTPS website" placeholder="https://your-site.example"><button id="probe">Check website</button></nav>
12
- <nav style="margin-top:10px"><input id="source" aria-label="Source directory" placeholder="Source directory"><button id="scan">Scan source</button><button id="permissions">Repair local SSH permissions</button></nav>
13
- <nav style="margin-top:10px"><select id="platform" aria-label="Device platform"><option value="ios">iPhone</option><option value="ipados">iPad</option><option value="android">Android</option><option value="chromeos">Chromebook</option><option value="chromeos-flex">ChromeOS Flex</option><option value="windows">Windows</option></select><input id="device" aria-label="Device label" placeholder="Device label (no passwords)"><button id="review-device">Review device</button></nav>
14
- <section id="device-review" hidden><p>Manual device review — answers are your observations, not an automatic scan. Unknown checks remain unverified. Never enter passwords or recovery keys.</p><div id="device-checks"></div><button id="evaluate-device">Evaluate review</button></section>
15
- <nav style="margin-top:10px"><input id="android-serial" aria-label="Already authorized Android serial" placeholder="Already authorized Android serial"><button id="android-check">Read Android properties</button></nav>
16
- <div id="state" role="status">Not audited</div><div class="scroll"><table hidden><thead><tr><th>Check / machine</th><th>State</th><th>Remediation / coverage</th></tr></thead><tbody></tbody></table></div><pre id="details"></pre>`;
5
+ root.innerHTML = `
6
+ <style>
7
+ :host {
8
+ display: block;
9
+ font-family: ui-sans-serif, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
10
+ color: #f1f5f9;
11
+ background: #180d11;
12
+ border: 1px solid rgba(244, 63, 94, 0.35);
13
+ border-radius: 10px;
14
+ padding: 18px;
15
+ box-shadow: 0 10px 28px rgba(0, 0, 0, 0.45);
16
+ box-sizing: border-box;
17
+ overflow: hidden;
18
+ }
19
+
20
+ header {
21
+ display: flex;
22
+ align-items: center;
23
+ gap: 12px;
24
+ margin-bottom: 12px;
25
+ }
26
+
27
+ .brand-icon {
28
+ width: 32px;
29
+ height: 38px;
30
+ color: #f43f5e;
31
+ flex-shrink: 0;
32
+ }
33
+
34
+ .title-block {
35
+ display: flex;
36
+ flex-direction: column;
37
+ gap: 2px;
38
+ }
39
+
40
+ h2 {
41
+ margin: 0;
42
+ font-size: 16px;
43
+ font-weight: 700;
44
+ letter-spacing: 0.03em;
45
+ text-transform: uppercase;
46
+ color: #fecdd3;
47
+ }
48
+
49
+ p.desc {
50
+ margin: 0 0 14px 0;
51
+ color: #fda4af;
52
+ font-size: 12px;
53
+ line-height: 1.5;
54
+ }
55
+
56
+ nav {
57
+ display: flex;
58
+ gap: 6px;
59
+ flex-wrap: wrap;
60
+ margin-top: 8px;
61
+ }
62
+
63
+ nav:first-of-type {
64
+ margin-top: 0;
65
+ }
66
+
67
+ button, input, select {
68
+ min-height: 44px;
69
+ border: 1px solid rgba(244, 63, 94, 0.28);
70
+ border-radius: 6px;
71
+ padding: 8px 12px;
72
+ background: #251017;
73
+ color: #f1f5f9;
74
+ font-size: 11px;
75
+ font-weight: 600;
76
+ letter-spacing: 0.02em;
77
+ box-sizing: border-box;
78
+ }
79
+
80
+ button {
81
+ cursor: pointer;
82
+ text-transform: uppercase;
83
+ transition: background 0.15s ease, border-color 0.15s ease;
84
+ }
85
+
86
+ button:hover {
87
+ background: rgba(244, 63, 94, 0.22);
88
+ border-color: #f43f5e;
89
+ }
90
+
91
+ button:active {
92
+ transform: translateY(1px);
93
+ }
94
+
95
+ button:disabled, input:disabled, select:disabled {
96
+ opacity: 0.5;
97
+ cursor: not-allowed;
98
+ }
99
+
100
+ input {
101
+ min-width: 0;
102
+ flex: 1;
103
+ font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
104
+ background: #11070a;
105
+ }
106
+
107
+ input:focus, select:focus {
108
+ border-color: #f43f5e;
109
+ outline: none;
110
+ box-shadow: 0 0 0 1px rgba(244, 63, 94, 0.3);
111
+ }
112
+
113
+ select {
114
+ background: #11070a;
115
+ cursor: pointer;
116
+ }
117
+
118
+ #state {
119
+ margin: 14px 0 8px 0;
120
+ font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
121
+ font-size: 11px;
122
+ font-weight: 700;
123
+ color: #fb7185;
124
+ background: #11070a;
125
+ padding: 6px 10px;
126
+ border-radius: 4px;
127
+ border: 1px solid rgba(244, 63, 94, 0.2);
128
+ }
129
+
130
+ .scroll {
131
+ overflow-x: auto;
132
+ margin-bottom: 10px;
133
+ border-radius: 6px;
134
+ border: 1px solid rgba(244, 63, 94, 0.2);
135
+ }
136
+
137
+ table {
138
+ width: 100%;
139
+ border-collapse: collapse;
140
+ font-size: 11px;
141
+ background: #0d0508;
142
+ }
143
+
144
+ th {
145
+ background: #251017;
146
+ color: #fecdd3;
147
+ font-weight: 700;
148
+ text-transform: uppercase;
149
+ letter-spacing: 0.04em;
150
+ padding: 8px 10px;
151
+ border-bottom: 1px solid rgba(244, 63, 94, 0.3);
152
+ text-align: left;
153
+ }
154
+
155
+ td {
156
+ padding: 8px 10px;
157
+ text-align: left;
158
+ border-bottom: 1px solid rgba(244, 63, 94, 0.15);
159
+ vertical-align: top;
160
+ color: #f8fafc;
161
+ }
162
+
163
+ td:first-child {
164
+ font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
165
+ font-weight: 600;
166
+ color: #fda4af;
167
+ }
168
+
169
+ td:last-child {
170
+ line-height: 1.45;
171
+ color: #cbd5e1;
172
+ }
173
+
174
+ pre {
175
+ background: #0a0406;
176
+ border: 1px solid rgba(244, 63, 94, 0.2);
177
+ border-radius: 6px;
178
+ padding: 8px 10px;
179
+ font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;
180
+ font-size: 10.5px;
181
+ line-height: 1.45;
182
+ color: #fb7185;
183
+ white-space: pre-wrap;
184
+ overflow-wrap: anywhere;
185
+ max-height: 160px;
186
+ overflow-y: auto;
187
+ margin: 0;
188
+ }
189
+
190
+ #device-review {
191
+ background: #11070a;
192
+ border: 1px solid rgba(244, 63, 94, 0.25);
193
+ border-radius: 6px;
194
+ padding: 10px;
195
+ margin-top: 10px;
196
+ }
197
+
198
+ #device-review p {
199
+ margin: 0 0 8px 0;
200
+ font-size: 11px;
201
+ color: #fca5a5;
202
+ }
203
+
204
+ #device-checks label {
205
+ display: block;
206
+ margin-bottom: 8px;
207
+ }
208
+
209
+ #device-checks label p {
210
+ margin: 0 0 4px 0;
211
+ font-size: 11px;
212
+ color: #fecdd3;
213
+ font-weight: 600;
214
+ }
215
+ </style>
216
+
217
+ <header>
218
+ <svg class="brand-icon" viewBox="0 0 32 38" fill="none" aria-hidden="true">
219
+ <path d="M16 2 29 8v11c0 8-7 14-13 17C10 33 3 27 3 19V8Z" stroke="currentColor" stroke-width="2"/>
220
+ <path d="m9 19 5 5 10-12" stroke="currentColor" stroke-width="2"/>
221
+ </svg>
222
+ <div class="title-block">
223
+ <h2>Security Assessments</h2>
224
+ </div>
225
+ </header>
226
+
227
+ <p class="desc">Inspect this machine or your mesh. Review firewall, SSH, disk protection, and listening services with concrete remediation.</p>
228
+
229
+ <nav>
230
+ <button data-action="machine">This machine</button>
231
+ <button data-action="fleet">Mesh fleet</button>
232
+ <button data-action="plugins">Plugin audit</button>
233
+ <button data-action="harden">Hardening plan</button>
234
+ </nav>
235
+
236
+ <nav>
237
+ <input id="target" aria-label="Machine name" placeholder="Optional mesh machine name">
238
+ <button id="selected">Audit selected</button>
239
+ </nav>
240
+
241
+ <nav>
242
+ <input id="website" type="url" aria-label="Authorized HTTPS website" placeholder="https://your-site.example">
243
+ <button id="probe">Check website</button>
244
+ </nav>
245
+
246
+ <nav>
247
+ <input id="source" aria-label="Source directory" placeholder="Source directory">
248
+ <button id="scan">Scan source</button>
249
+ <button id="permissions">Repair SSH permissions</button>
250
+ </nav>
251
+
252
+ <nav>
253
+ <select id="platform" aria-label="Device platform">
254
+ <option value="ios">iPhone</option>
255
+ <option value="ipados">iPad</option>
256
+ <option value="android">Android</option>
257
+ <option value="chromeos">Chromebook</option>
258
+ <option value="chromeos-flex">ChromeOS Flex</option>
259
+ <option value="windows">Windows</option>
260
+ </select>
261
+ <input id="device" aria-label="Device label" placeholder="Device label (no passwords)">
262
+ <button id="review-device">Review device</button>
263
+ </nav>
264
+
265
+ <section id="device-review" hidden>
266
+ <p>Manual device review — answers are your observations, not an automatic scan. Unknown checks remain unverified. Never enter passwords or recovery keys.</p>
267
+ <div id="device-checks"></div>
268
+ <button id="evaluate-device">Evaluate review</button>
269
+ </section>
270
+
271
+ <nav>
272
+ <input id="android-serial" aria-label="Already authorized Android serial" placeholder="Already authorized Android serial">
273
+ <button id="android-check">Read Android properties</button>
274
+ </nav>
275
+
276
+ <div id="state" role="status">Not audited</div>
277
+
278
+ <div class="scroll">
279
+ <table hidden>
280
+ <thead>
281
+ <tr><th>Check / machine</th><th>State</th><th>Remediation / coverage</th></tr>
282
+ </thead>
283
+ <tbody></tbody>
284
+ </table>
285
+ </div>
286
+
287
+ <pre id="details"></pre>
288
+ `;
289
+
17
290
  root.querySelectorAll('[data-action]').forEach(button => button.addEventListener('click', () => this.execute(button.dataset.action)));
18
291
  root.querySelector('#selected').addEventListener('click', () => {
19
292
  const target = root.querySelector('#target').value.trim();
@@ -46,6 +319,7 @@ export class SecuritySecurityCard extends HTMLElement {
46
319
  });
47
320
  root.querySelector('#android-check').addEventListener('click', () => this.execute('android', ['--serial', root.querySelector('#android-serial').value.trim()]));
48
321
  }
322
+
49
323
  async execute(action, args = []) {
50
324
  const root = this.shadowRoot;
51
325
  const state = root.querySelector('#state');
@@ -92,4 +366,5 @@ export class SecuritySecurityCard extends HTMLElement {
92
366
  finally { root.querySelectorAll('button,input,select').forEach(button => { button.disabled = false; }); }
93
367
  }
94
368
  }
369
+
95
370
  if (!customElements.get('tr-security-card')) customElements.define('tr-security-card', SecuritySecurityCard);
@@ -100,7 +100,10 @@ export async function updateAllBrains(opts = {}) {
100
100
  const errors = [];
101
101
  const brains = roots.map(root => ({ root, brain: path.join(root, '.agent', 'skills', 'total-recall') }))
102
102
  .filter(({ brain }) => fs.existsSync(brain));
103
- if (opts.brainDir) brains.push({ root: opts.brainDir, brain: opts.brainDir });
103
+ if (opts.brainDir) {
104
+ brains.push({ root: opts.brainDir, brain: opts.brainDir });
105
+ roots.push(opts.brainDir);
106
+ }
104
107
  for (const { root, brain } of brains) {
105
108
  if (!dryRun && opts.ensureDefaults === true) {
106
109
  try { ensureRequiredPlugins(brain); }
@@ -1,14 +0,0 @@
1
- /** Per-worker isolation must exist before modules initialize config or logging. */
2
- import fs from 'node:fs';
3
- import os from 'node:os';
4
- import path from 'node:path';
5
- import { afterAll } from 'vitest';
6
-
7
- const previous = process.env._TR_TEST_AGENT_DIR;
8
- const fixture = fs.mkdtempSync(path.join(os.tmpdir(), 'tr-suite-brain-'));
9
- process.env._TR_TEST_AGENT_DIR = fixture;
10
- afterAll(() => {
11
- if (previous === undefined) delete process.env._TR_TEST_AGENT_DIR;
12
- else process.env._TR_TEST_AGENT_DIR = previous;
13
- fs.rmSync(fixture, { recursive: true, force: true });
14
- });