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.
- package/package.json +1 -1
- package/scaffold/.agent/skills/total-recall/plugins/auth/package-lock.json +111 -7
- package/scaffold/.agent/skills/total-recall/plugins/auth/src/provider-rotation-recipes.mjs +1 -1
- package/scaffold/.agent/skills/total-recall/plugins/code-quality/package-lock.json +6 -5
- package/scaffold/.agent/skills/total-recall/plugins/code-quality/package.json +1 -1
- package/scaffold/.agent/skills/total-recall/plugins/code-quality/plugin.json +1 -1
- package/scaffold/.agent/skills/total-recall/plugins/composable-cli/package-lock.json +6 -5
- package/scaffold/.agent/skills/total-recall/plugins/composable-cli/package.json +1 -1
- package/scaffold/.agent/skills/total-recall/plugins/composable-cli/plugin.json +13 -13
- package/scaffold/.agent/skills/total-recall/plugins/composable-cli/ui/card.js +340 -164
- package/scaffold/.agent/skills/total-recall/plugins/embeddings/package-lock.json +6 -5
- package/scaffold/.agent/skills/total-recall/plugins/embeddings/package.json +8 -2
- package/scaffold/.agent/skills/total-recall/plugins/embeddings/ui/card.js +295 -178
- package/scaffold/.agent/skills/total-recall/plugins/git-sentinel/LICENSE +1 -1
- package/scaffold/.agent/skills/total-recall/plugins/git-sentinel/package-lock.json +6 -5
- package/scaffold/.agent/skills/total-recall/plugins/git-sentinel/package.json +1 -1
- package/scaffold/.agent/skills/total-recall/plugins/git-sentinel/plugin.json +1 -1
- package/scaffold/.agent/skills/total-recall/plugins/git-sentinel/ui/card.js +302 -168
- package/scaffold/.agent/skills/total-recall/plugins/mesh/package.json +9 -2
- package/scaffold/.agent/skills/total-recall/plugins/mesh/plugin.json +8 -5
- package/scaffold/.agent/skills/total-recall/plugins/mesh/ui/card.js +444 -27
- package/scaffold/.agent/skills/total-recall/plugins/openwiki/package-lock.json +124 -1404
- package/scaffold/.agent/skills/total-recall/plugins/openwiki/package.json +9 -2
- package/scaffold/.agent/skills/total-recall/plugins/openwiki/plugin.json +0 -2
- package/scaffold/.agent/skills/total-recall/plugins/openwiki/ui/card.js +312 -133
- package/scaffold/.agent/skills/total-recall/plugins/security/package-lock.json +6 -5
- package/scaffold/.agent/skills/total-recall/plugins/security/package.json +1 -1
- package/scaffold/.agent/skills/total-recall/plugins/security/plugin.json +1 -3
- package/scaffold/.agent/skills/total-recall/plugins/security/ui/card.js +287 -12
- package/src/core/brain-updates.mjs +4 -1
- 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 =
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
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)
|
|
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
|
-
});
|