total-recall-brain 3.41.2 → 3.41.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/bin/total-recall.mjs +19 -4
- package/frontend/dist/assets/{index-BG9NkVUy.css → index-BIQmqDKP.css} +1 -1
- package/frontend/dist/assets/{index-BtuiZqwP.js → index-CRzjQLu7.js} +7 -7
- package/frontend/dist/index.html +2 -2
- package/frontend/dist/sw.js +8 -5
- package/frontend/src/api/auth.ts +0 -3
- package/frontend/src/components/plugins/PluginPanel.tsx +7 -3
- package/frontend/src/components/plugins/card/CardEngine.tsx +1 -1
- package/frontend/src/pages/LoginPage.tsx +1 -41
- package/frontend/src/pages/PluginsPage.tsx +14 -7
- package/package.json +7 -5
- package/scaffold/.agent/skills/plugin/scripts/record.mjs +6 -3
- package/scaffold/.agent/skills/total-recall/plugins/auth/cli.mjs +197 -31
- package/scaffold/.agent/skills/total-recall/plugins/auth/package-lock.json +6 -6
- package/scaffold/.agent/skills/total-recall/plugins/auth/package.json +1 -1
- package/scaffold/.agent/skills/total-recall/plugins/auth/plugin.json +8 -1
- package/scaffold/.agent/skills/total-recall/plugins/auth/src/cli-secret.mjs +48 -0
- package/scaffold/.agent/skills/total-recall/plugins/auth/src/login-projections.mjs +42 -0
- package/scaffold/.agent/skills/total-recall/plugins/auth/src/mesh-secrets.mjs +18 -0
- package/scaffold/.agent/skills/total-recall/plugins/auth/src/routes/secrets.mjs +5 -2
- package/scaffold/.agent/skills/total-recall/plugins/auth/src/secrets-carriers.mjs +76 -0
- package/scaffold/.agent/skills/total-recall/plugins/auth/src/secrets-prune.mjs +37 -0
- package/scaffold/.agent/skills/total-recall/plugins/auth/src/secrets-sync.mjs +53 -17
- package/scaffold/.agent/skills/total-recall/plugins/auth/ui/DESIGN.md +56 -8
- package/scaffold/.agent/skills/total-recall/plugins/auth/ui/card.js +1068 -204
- package/scaffold/.agent/skills/total-recall/plugins/auth/ui/panel.js +4 -2
- package/scaffold/.agent/skills/total-recall/plugins/cli-agents/ui/DESIGN.md +32 -0
- package/scaffold/.agent/skills/total-recall/plugins/cli-agents/ui/card.js +436 -274
- package/scaffold/.agent/skills/total-recall/plugins/code-quality/package-lock.json +12 -12
- package/scaffold/.agent/skills/total-recall/plugins/code-quality/package.json +1 -1
- package/scaffold/.agent/skills/total-recall/plugins/code-quality/ui/DESIGN.md +16 -2
- package/scaffold/.agent/skills/total-recall/plugins/code-quality/ui/card.js +461 -242
- package/scaffold/.agent/skills/total-recall/plugins/composable-cli/package-lock.json +12 -12
- package/scaffold/.agent/skills/total-recall/plugins/composable-cli/package.json +1 -1
- package/scaffold/.agent/skills/total-recall/plugins/composable-cli/plugin.json +1 -7
- package/scaffold/.agent/skills/total-recall/plugins/composable-cli/ui/DESIGN.md +17 -2
- package/scaffold/.agent/skills/total-recall/plugins/composable-cli/ui/card.js +426 -300
- package/scaffold/.agent/skills/total-recall/plugins/embeddings/package-lock.json +23 -8
- package/scaffold/.agent/skills/total-recall/plugins/embeddings/package.json +6 -2
- package/scaffold/.agent/skills/total-recall/plugins/embeddings/ui/DESIGN.md +32 -0
- package/scaffold/.agent/skills/total-recall/plugins/embeddings/ui/card.js +350 -283
- package/scaffold/.agent/skills/total-recall/plugins/git-sentinel/package-lock.json +23 -8
- package/scaffold/.agent/skills/total-recall/plugins/git-sentinel/package.json +5 -1
- package/scaffold/.agent/skills/total-recall/plugins/git-sentinel/ui/card.js +31 -19
- package/scaffold/.agent/skills/total-recall/plugins/mesh/package-lock.json +23 -10
- package/scaffold/.agent/skills/total-recall/plugins/mesh/package.json +5 -3
- package/scaffold/.agent/skills/total-recall/plugins/mesh/plugin.json +1 -1
- package/scaffold/.agent/skills/total-recall/plugins/mesh/src/cli/grants.mjs +7 -3
- package/scaffold/.agent/skills/total-recall/plugins/mesh/src/cli/mesh.mjs +61 -38
- package/scaffold/.agent/skills/total-recall/plugins/mesh/src/core/leader-election.mjs +57 -2
- package/scaffold/.agent/skills/total-recall/plugins/mesh/src/core/mesh.mjs +220 -36
- package/scaffold/.agent/skills/total-recall/plugins/mesh/src/server/routes/mesh.mjs +7 -2
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/README.md +65 -0
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/capability/BRICK.md +59 -0
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/capability/index.mjs +534 -0
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/cli.mjs +139 -0
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/package-lock.json +2849 -0
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/package.json +26 -0
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/plugin.json +376 -0
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/skills/meta-harness/SKILL.md +37 -0
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/adapters/dsh.mjs +446 -0
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/alerts.mjs +23 -0
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/coordinator.mjs +398 -0
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/documentation.mjs +152 -0
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/executor.mjs +82 -0
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/learner.mjs +90 -0
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/router.mjs +415 -0
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/runtime.mjs +36 -0
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/setup.mjs +35 -0
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/tracker.mjs +133 -0
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/worker.mjs +233 -0
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/ui/DESIGN.md +32 -0
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/ui/card.js +845 -0
- package/scaffold/.agent/skills/total-recall/plugins/openwiki/capability/BRICK.md +64 -0
- package/scaffold/.agent/skills/total-recall/plugins/openwiki/capability/index.mjs +250 -0
- package/scaffold/.agent/skills/total-recall/plugins/openwiki/cli.mjs +344 -14
- package/scaffold/.agent/skills/total-recall/plugins/openwiki/package-lock.json +2917 -140
- package/scaffold/.agent/skills/total-recall/plugins/openwiki/package.json +9 -3
- package/scaffold/.agent/skills/total-recall/plugins/openwiki/plugin.json +223 -5
- package/scaffold/.agent/skills/total-recall/plugins/openwiki/src/config.mjs +129 -0
- package/scaffold/.agent/skills/total-recall/plugins/openwiki/src/refresh.mjs +355 -0
- package/scaffold/.agent/skills/total-recall/plugins/openwiki/src/upstream-watcher.mjs +375 -0
- package/scaffold/.agent/skills/total-recall/plugins/openwiki/ui/DESIGN.md +37 -10
- package/scaffold/.agent/skills/total-recall/plugins/openwiki/ui/card.js +986 -280
- package/scaffold/.agent/skills/total-recall/plugins/security/cli.mjs +7 -1
- package/scaffold/.agent/skills/total-recall/plugins/security/package-lock.json +25 -10
- package/scaffold/.agent/skills/total-recall/plugins/security/package.json +6 -2
- package/scaffold/.agent/skills/total-recall/plugins/security/plugin.json +1 -1
- package/scaffold/.agent/skills/total-recall/plugins/security/src/scanner.mjs +17 -3
- package/scaffold/.agent/skills/total-recall/plugins/security/ui/DESIGN.md +38 -15
- package/scaffold/.agent/skills/total-recall/plugins/security/ui/card.js +60 -34
- package/src/cli/command.mjs +23 -18
- package/src/cli/config.mjs +3 -0
- package/src/cli/connect.mjs +12 -116
- package/src/cli/daemon.mjs +23 -1
- package/src/cli/harness.mjs +0 -1
- package/src/cli/plugin/copies.mjs +8 -5
- package/src/cli/plugin/create.mjs +56 -3
- package/src/cli/plugin/index.mjs +40 -5
- package/src/cli/plugin/monetization.mjs +232 -12
- package/src/cli/preflight.mjs +161 -0
- package/src/cli/rebuild.mjs +22 -0
- package/src/cli/reset-password.mjs +3 -2
- package/src/cli/skill.mjs +8 -2
- package/src/cli/status.mjs +25 -7
- package/src/core/automatic-brain-updates.mjs +9 -3
- package/src/core/brain-updates.mjs +63 -5
- package/src/core/cli-commands.mjs +2 -0
- package/src/core/context-compiler.mjs +8 -1
- package/src/core/default-plugins.mjs +1 -1
- package/src/core/global-brain-updates.mjs +21 -1
- package/src/core/mesh-brain-updates.mjs +5 -2
- package/src/core/meta-harness.mjs +32 -79
- package/src/core/plugin-dependencies.mjs +6 -1
- package/src/core/plugin-runner.mjs +6 -1
- package/src/core/plugin-store.mjs +67 -1
- package/src/core/plugin-updates.mjs +1 -1
- package/src/core/portable-skills-maintenance.mjs +19 -0
- package/src/core/preflight-gate.mjs +77 -0
- package/src/core/preflight-receipt.mjs +123 -0
- package/src/core/required-plugins.mjs +7 -0
- package/src/core/runtime.mjs +0 -3
- package/src/core/skills-registry.mjs +33 -3
- package/src/core/surface.mjs +38 -1
- package/src/server/auth.mjs +41 -1
- package/src/server/memory-app.mjs +2 -1
- package/src/server/routes/auth.mjs +25 -1
- package/src/server/routes/plugins.mjs +17 -4
|
@@ -907,7 +907,13 @@ export async function run(argv = []) {
|
|
|
907
907
|
}
|
|
908
908
|
if (IMPLEMENTED[sub]) {
|
|
909
909
|
try { return await IMPLEMENTED[sub](args.slice(1)); }
|
|
910
|
-
catch
|
|
910
|
+
catch (error) {
|
|
911
|
+
// Say what failed. The generic text hid every cause, including a scan that
|
|
912
|
+
// simply hit its coverage limit. Messages are paths and limits, never matched content.
|
|
913
|
+
console.log(JSON.stringify({ status: 'failed', operation: sub, error: `Security operation failed: ${String(error?.message || error).slice(0, 300)}. No success was established.` }));
|
|
914
|
+
process.exitCode = 1;
|
|
915
|
+
return;
|
|
916
|
+
}
|
|
911
917
|
}
|
|
912
918
|
console.error(`Security: "${sub}" is not implemented.`);
|
|
913
919
|
process.exitCode = 2;
|
|
@@ -1,16 +1,19 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "tr-plugin-security",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.3",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "tr-plugin-security",
|
|
9
|
-
"version": "0.3.
|
|
9
|
+
"version": "0.3.3",
|
|
10
10
|
"license": "MIT",
|
|
11
|
+
"dependencies": {
|
|
12
|
+
"@gregiteen/ssss-cli": "0.14.3"
|
|
13
|
+
},
|
|
11
14
|
"devDependencies": {
|
|
12
15
|
"jsdom": "^26.1.0",
|
|
13
|
-
"total-recall-brain": "3.41.
|
|
16
|
+
"total-recall-brain": "3.41.3"
|
|
14
17
|
}
|
|
15
18
|
},
|
|
16
19
|
"node_modules/@asamuzakjp/css-color": {
|
|
@@ -142,6 +145,18 @@
|
|
|
142
145
|
"node": ">=18"
|
|
143
146
|
}
|
|
144
147
|
},
|
|
148
|
+
"node_modules/@gregiteen/ssss-cli": {
|
|
149
|
+
"version": "0.14.3",
|
|
150
|
+
"resolved": "https://registry.npmjs.org/@gregiteen/ssss-cli/-/ssss-cli-0.14.3.tgz",
|
|
151
|
+
"integrity": "sha512-vvGgiNLjus3/xp+iotiGqbSG0R7+Q/bP5cP2Psa7Rhtm/vrMuM5B4LebYu7bPf3TzgCyTbv96PcxGWf6gxbW0Q==",
|
|
152
|
+
"license": "ISC",
|
|
153
|
+
"bin": {
|
|
154
|
+
"ssss": "scripts/ssss.mjs"
|
|
155
|
+
},
|
|
156
|
+
"engines": {
|
|
157
|
+
"node": ">=18"
|
|
158
|
+
}
|
|
159
|
+
},
|
|
145
160
|
"node_modules/@hexagon/base64": {
|
|
146
161
|
"version": "1.1.28",
|
|
147
162
|
"resolved": "https://registry.npmjs.org/@hexagon/base64/-/base64-1.1.28.tgz",
|
|
@@ -479,9 +494,9 @@
|
|
|
479
494
|
},
|
|
480
495
|
"node_modules/@ssss/cli": {
|
|
481
496
|
"name": "@gregiteen/ssss-cli",
|
|
482
|
-
"version": "0.
|
|
483
|
-
"resolved": "https://registry.npmjs.org/@gregiteen/ssss-cli/-/ssss-cli-0.
|
|
484
|
-
"integrity": "sha512-
|
|
497
|
+
"version": "0.12.1",
|
|
498
|
+
"resolved": "https://registry.npmjs.org/@gregiteen/ssss-cli/-/ssss-cli-0.12.1.tgz",
|
|
499
|
+
"integrity": "sha512-ff0L2LV4db1CfD4W3VmIJwT9fvrpuKDGDfhe6gtjrrgtRmo7BP7jYjRtH7yuQipKikyiP9LIvmVIaxvbjLTwkA==",
|
|
485
500
|
"dev": true,
|
|
486
501
|
"license": "ISC",
|
|
487
502
|
"bin": {
|
|
@@ -2916,9 +2931,9 @@
|
|
|
2916
2931
|
}
|
|
2917
2932
|
},
|
|
2918
2933
|
"node_modules/total-recall-brain": {
|
|
2919
|
-
"version": "3.41.
|
|
2920
|
-
"resolved": "https://registry.npmjs.org/total-recall-brain/-/total-recall-brain-3.41.
|
|
2921
|
-
"integrity": "sha512-
|
|
2934
|
+
"version": "3.41.3",
|
|
2935
|
+
"resolved": "https://registry.npmjs.org/total-recall-brain/-/total-recall-brain-3.41.3.tgz",
|
|
2936
|
+
"integrity": "sha512-0uIh3WZE3dHxrKFTtRMxvSBLx7aV3j7ry9H9NxRShtCycwQ38T7+70Q/GJAqsdpwt894h8B6AAmWJnHwsFG3XQ==",
|
|
2922
2937
|
"dev": true,
|
|
2923
2938
|
"license": "MIT",
|
|
2924
2939
|
"workspaces": [
|
|
@@ -2926,7 +2941,7 @@
|
|
|
2926
2941
|
],
|
|
2927
2942
|
"dependencies": {
|
|
2928
2943
|
"@simplewebauthn/server": "^13.3.2",
|
|
2929
|
-
"@ssss/cli": "npm:@gregiteen/ssss-cli@0.
|
|
2944
|
+
"@ssss/cli": "npm:@gregiteen/ssss-cli@0.12.1",
|
|
2930
2945
|
"bcrypt": "^6.0.0",
|
|
2931
2946
|
"better-sqlite3": "^12.11.1",
|
|
2932
2947
|
"cookie-parser": "^1.4.7",
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "tr-plugin-security",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.3",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Standalone security suite for Total Recall: static analysis, file and permission hardening schemes, AES-256-GCM encryption tools, and egress audit controls",
|
|
6
6
|
"scripts": {
|
|
7
7
|
"test": "node --test test/*.test.mjs",
|
|
8
|
-
"build:ui": "node scripts/build-ui.mjs"
|
|
8
|
+
"build:ui": "node scripts/build-ui.mjs",
|
|
9
|
+
"ssss": "ssss"
|
|
9
10
|
},
|
|
10
11
|
"license": "MIT",
|
|
11
12
|
"files": [
|
|
@@ -21,5 +22,8 @@
|
|
|
21
22
|
],
|
|
22
23
|
"publishConfig": {
|
|
23
24
|
"access": "public"
|
|
25
|
+
},
|
|
26
|
+
"dependencies": {
|
|
27
|
+
"@gregiteen/ssss-cli": "0.14.3"
|
|
24
28
|
}
|
|
25
29
|
}
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"$schema": "https://github.com/gregiteen/total-recall/blob/main/metadata.plugin.schema.json",
|
|
3
3
|
"id": "security",
|
|
4
4
|
"name": "Security Assessments",
|
|
5
|
-
"version": "0.3.
|
|
5
|
+
"version": "0.3.3",
|
|
6
6
|
"description": "Machine and device security assessments for macOS, Linux, Windows, Android, Chromebook, iPhone and iPad, with explicit measured and manual coverage.",
|
|
7
7
|
"license": "MIT",
|
|
8
8
|
"branding": {
|
|
@@ -5,8 +5,12 @@ import path from 'node:path';
|
|
|
5
5
|
export function scanSource(targetPath) {
|
|
6
6
|
const root = fs.realpathSync(path.resolve(targetPath));
|
|
7
7
|
const findings = [];
|
|
8
|
-
|
|
8
|
+
// Generated brain data (indexes, sessions, logs) is not source; scanning it
|
|
9
|
+
// only hit the size limit and aborted the whole scan.
|
|
10
|
+
const skipped = new Set(['node_modules', '.git', 'dist', 'coverage', 'memory-vault', 'memory-derived', 'sessions', '.cache', '.venv', '__pycache__']);
|
|
11
|
+
const MAX_FILES = 20000, MAX_BYTES = 2097152;
|
|
9
12
|
let count = 0;
|
|
13
|
+
let limited = false;
|
|
10
14
|
function visit(file) {
|
|
11
15
|
const stat = fs.lstatSync(file);
|
|
12
16
|
if (stat.isSymbolicLink()) {
|
|
@@ -14,11 +18,21 @@ export function scanSource(targetPath) {
|
|
|
14
18
|
return;
|
|
15
19
|
}
|
|
16
20
|
if (stat.isDirectory()) {
|
|
17
|
-
for (const name of fs.readdirSync(file)) if (!skipped.has(name)) visit(path.join(file, name));
|
|
21
|
+
for (const name of fs.readdirSync(file)) { if (limited) return; if (!skipped.has(name)) visit(path.join(file, name)); }
|
|
18
22
|
return;
|
|
19
23
|
}
|
|
20
24
|
if (!stat.isFile() || !/\.(?:[cm]?js|tsx?|py|sh|bash|ps1|json|env|ya?ml)$|(?:^|\/)\.env(?:\.|$)/.test(file)) return;
|
|
21
|
-
|
|
25
|
+
// Report incomplete coverage as a finding instead of aborting: an aborted
|
|
26
|
+
// scan returned nothing, which callers could not tell apart from a failure.
|
|
27
|
+
if (stat.size > MAX_BYTES) {
|
|
28
|
+
findings.push({ file: path.relative(root, file), line: 0, rule: 'oversized-file-unscanned', severity: 'HIGH', detail: `Larger than ${MAX_BYTES} bytes; not inspected, coverage incomplete` });
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
if (++count > MAX_FILES) {
|
|
32
|
+
limited = true;
|
|
33
|
+
findings.push({ file: '.', line: 0, rule: 'coverage-limit-reached', severity: 'HIGH', detail: `Stopped after ${MAX_FILES} files; narrow the target, coverage incomplete` });
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
22
36
|
const testFile = /(?:^|\/)(?:test|tests|fixtures)(?:\/|$)|\.(?:test|spec)\./.test(file);
|
|
23
37
|
fs.readFileSync(file, 'utf8').split('\n').forEach((line, index) => {
|
|
24
38
|
const rules = [];
|
|
@@ -1,18 +1,41 @@
|
|
|
1
|
-
# DESIGN.md — Tin Foil
|
|
1
|
+
# DESIGN.md — Security Plugin (Tin Foil)
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
3
|
+
## Brand Identity & Aesthetic
|
|
4
|
+
- **Brand Name**: Tin Foil
|
|
5
|
+
- **Wordmark**: `[TIN//FOIL]`
|
|
6
|
+
- **Theme**: Crimson and Obsidian Host Hardening Console
|
|
7
|
+
- **Tone**: Deterministic, vigilant, fail-closed, precise
|
|
8
|
+
|
|
9
|
+
## Design Tokens
|
|
10
|
+
|
|
11
|
+
The card face defines and consumes these custom properties:
|
|
12
|
+
|
|
13
|
+
```css
|
|
14
|
+
:host {
|
|
15
|
+
--face-bg: #180d11;
|
|
16
|
+
--face-bg-subtle: #251017;
|
|
17
|
+
--face-bg-surface: #11070a;
|
|
18
|
+
--face-bg-table: #0d0508;
|
|
19
|
+
--face-bg-code: #0a0406;
|
|
20
|
+
--face-accent: #f43f5e;
|
|
21
|
+
--face-accent-hover: rgba(244, 63, 94, 0.22);
|
|
22
|
+
--face-accent-glow: rgba(244, 63, 94, 0.35);
|
|
23
|
+
--face-border-subtle: rgba(244, 63, 94, 0.28);
|
|
24
|
+
--face-border-faint: rgba(244, 63, 94, 0.2);
|
|
25
|
+
--face-border-cell: rgba(244, 63, 94, 0.15);
|
|
26
|
+
--face-border-alert: rgba(244, 63, 94, 0.25);
|
|
27
|
+
--face-text: #f1f5f9;
|
|
28
|
+
--face-text-heading: #fecdd3;
|
|
29
|
+
--face-text-muted: #fda4af;
|
|
30
|
+
--face-text-cell: #f8fafc;
|
|
31
|
+
--face-text-desc: #cbd5e1;
|
|
32
|
+
--face-danger: #fb7185;
|
|
33
|
+
--face-warning: #fca5a5;
|
|
34
|
+
}
|
|
13
35
|
```
|
|
14
36
|
|
|
15
|
-
##
|
|
16
|
-
-
|
|
17
|
-
-
|
|
18
|
-
-
|
|
37
|
+
## System Integration
|
|
38
|
+
- The face binds `--text-primary` with fallback to `var(--face-text)`.
|
|
39
|
+
- The face binds `--border` with fallback to `var(--face-accent-glow)`.
|
|
40
|
+
- All clickable elements enforce a minimum height of 44px for touch ergonomics.
|
|
41
|
+
- Reduced motion styles suppress animation when requested by system settings.
|
|
@@ -5,11 +5,31 @@ export class SecuritySecurityCard extends HTMLElement {
|
|
|
5
5
|
root.innerHTML = `
|
|
6
6
|
<style>
|
|
7
7
|
:host {
|
|
8
|
+
--face-bg: #180d11;
|
|
9
|
+
--face-bg-subtle: #251017;
|
|
10
|
+
--face-bg-surface: #11070a;
|
|
11
|
+
--face-bg-table: #0d0508;
|
|
12
|
+
--face-bg-code: #0a0406;
|
|
13
|
+
--face-accent: #f43f5e;
|
|
14
|
+
--face-accent-hover: rgba(244, 63, 94, 0.22);
|
|
15
|
+
--face-accent-glow: rgba(244, 63, 94, 0.35);
|
|
16
|
+
--face-border-subtle: rgba(244, 63, 94, 0.28);
|
|
17
|
+
--face-border-faint: rgba(244, 63, 94, 0.2);
|
|
18
|
+
--face-border-cell: rgba(244, 63, 94, 0.15);
|
|
19
|
+
--face-border-alert: rgba(244, 63, 94, 0.25);
|
|
20
|
+
--face-text: #f1f5f9;
|
|
21
|
+
--face-text-heading: #fecdd3;
|
|
22
|
+
--face-text-muted: #fda4af;
|
|
23
|
+
--face-text-cell: #f8fafc;
|
|
24
|
+
--face-text-desc: #cbd5e1;
|
|
25
|
+
--face-danger: #fb7185;
|
|
26
|
+
--face-warning: #fca5a5;
|
|
27
|
+
|
|
8
28
|
display: block;
|
|
9
29
|
font-family: ui-sans-serif, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
|
|
10
|
-
color:
|
|
11
|
-
background:
|
|
12
|
-
border: 1px solid
|
|
30
|
+
color: var(--text-primary, var(--face-text));
|
|
31
|
+
background: var(--face-bg);
|
|
32
|
+
border: 1px solid var(--border, var(--face-accent-glow));
|
|
13
33
|
border-radius: 10px;
|
|
14
34
|
padding: 18px;
|
|
15
35
|
box-shadow: 0 10px 28px rgba(0, 0, 0, 0.45);
|
|
@@ -27,7 +47,7 @@ export class SecuritySecurityCard extends HTMLElement {
|
|
|
27
47
|
.brand-icon {
|
|
28
48
|
width: 32px;
|
|
29
49
|
height: 38px;
|
|
30
|
-
color:
|
|
50
|
+
color: var(--face-accent);
|
|
31
51
|
flex-shrink: 0;
|
|
32
52
|
}
|
|
33
53
|
|
|
@@ -43,12 +63,12 @@ export class SecuritySecurityCard extends HTMLElement {
|
|
|
43
63
|
font-weight: 700;
|
|
44
64
|
letter-spacing: 0.03em;
|
|
45
65
|
text-transform: uppercase;
|
|
46
|
-
color:
|
|
66
|
+
color: var(--face-text-heading);
|
|
47
67
|
}
|
|
48
68
|
|
|
49
69
|
p.desc {
|
|
50
70
|
margin: 0 0 14px 0;
|
|
51
|
-
color:
|
|
71
|
+
color: var(--face-text-muted);
|
|
52
72
|
font-size: 12px;
|
|
53
73
|
line-height: 1.5;
|
|
54
74
|
}
|
|
@@ -66,11 +86,11 @@ export class SecuritySecurityCard extends HTMLElement {
|
|
|
66
86
|
|
|
67
87
|
button, input, select {
|
|
68
88
|
min-height: 44px;
|
|
69
|
-
border: 1px solid
|
|
89
|
+
border: 1px solid var(--face-border-subtle);
|
|
70
90
|
border-radius: 6px;
|
|
71
91
|
padding: 8px 12px;
|
|
72
|
-
background:
|
|
73
|
-
color:
|
|
92
|
+
background: var(--face-bg-subtle);
|
|
93
|
+
color: var(--face-text);
|
|
74
94
|
font-size: 11px;
|
|
75
95
|
font-weight: 600;
|
|
76
96
|
letter-spacing: 0.02em;
|
|
@@ -84,8 +104,8 @@ export class SecuritySecurityCard extends HTMLElement {
|
|
|
84
104
|
}
|
|
85
105
|
|
|
86
106
|
button:hover {
|
|
87
|
-
background:
|
|
88
|
-
border-color:
|
|
107
|
+
background: var(--face-accent-hover);
|
|
108
|
+
border-color: var(--face-accent);
|
|
89
109
|
}
|
|
90
110
|
|
|
91
111
|
button:active {
|
|
@@ -101,17 +121,17 @@ export class SecuritySecurityCard extends HTMLElement {
|
|
|
101
121
|
min-width: 0;
|
|
102
122
|
flex: 1;
|
|
103
123
|
font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
|
|
104
|
-
background:
|
|
124
|
+
background: var(--face-bg-surface);
|
|
105
125
|
}
|
|
106
126
|
|
|
107
127
|
input:focus, select:focus {
|
|
108
|
-
border-color:
|
|
128
|
+
border-color: var(--face-accent);
|
|
109
129
|
outline: none;
|
|
110
|
-
box-shadow: 0 0 0 1px
|
|
130
|
+
box-shadow: 0 0 0 1px var(--face-accent-glow);
|
|
111
131
|
}
|
|
112
132
|
|
|
113
133
|
select {
|
|
114
|
-
background:
|
|
134
|
+
background: var(--face-bg-surface);
|
|
115
135
|
cursor: pointer;
|
|
116
136
|
}
|
|
117
137
|
|
|
@@ -120,66 +140,66 @@ export class SecuritySecurityCard extends HTMLElement {
|
|
|
120
140
|
font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
|
|
121
141
|
font-size: 11px;
|
|
122
142
|
font-weight: 700;
|
|
123
|
-
color:
|
|
124
|
-
background:
|
|
143
|
+
color: var(--face-danger);
|
|
144
|
+
background: var(--face-bg-surface);
|
|
125
145
|
padding: 6px 10px;
|
|
126
146
|
border-radius: 4px;
|
|
127
|
-
border: 1px solid
|
|
147
|
+
border: 1px solid var(--face-border-faint);
|
|
128
148
|
}
|
|
129
149
|
|
|
130
150
|
.scroll {
|
|
131
151
|
overflow-x: auto;
|
|
132
152
|
margin-bottom: 10px;
|
|
133
153
|
border-radius: 6px;
|
|
134
|
-
border: 1px solid
|
|
154
|
+
border: 1px solid var(--face-border-faint);
|
|
135
155
|
}
|
|
136
156
|
|
|
137
157
|
table {
|
|
138
158
|
width: 100%;
|
|
139
159
|
border-collapse: collapse;
|
|
140
160
|
font-size: 11px;
|
|
141
|
-
background:
|
|
161
|
+
background: var(--face-bg-table);
|
|
142
162
|
}
|
|
143
163
|
|
|
144
164
|
th {
|
|
145
|
-
background:
|
|
146
|
-
color:
|
|
165
|
+
background: var(--face-bg-subtle);
|
|
166
|
+
color: var(--face-text-heading);
|
|
147
167
|
font-weight: 700;
|
|
148
168
|
text-transform: uppercase;
|
|
149
169
|
letter-spacing: 0.04em;
|
|
150
170
|
padding: 8px 10px;
|
|
151
|
-
border-bottom: 1px solid
|
|
171
|
+
border-bottom: 1px solid var(--face-border-subtle);
|
|
152
172
|
text-align: left;
|
|
153
173
|
}
|
|
154
174
|
|
|
155
175
|
td {
|
|
156
176
|
padding: 8px 10px;
|
|
157
177
|
text-align: left;
|
|
158
|
-
border-bottom: 1px solid
|
|
178
|
+
border-bottom: 1px solid var(--face-border-cell);
|
|
159
179
|
vertical-align: top;
|
|
160
|
-
color:
|
|
180
|
+
color: var(--face-text-cell);
|
|
161
181
|
}
|
|
162
182
|
|
|
163
183
|
td:first-child {
|
|
164
184
|
font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
|
|
165
185
|
font-weight: 600;
|
|
166
|
-
color:
|
|
186
|
+
color: var(--face-text-muted);
|
|
167
187
|
}
|
|
168
188
|
|
|
169
189
|
td:last-child {
|
|
170
190
|
line-height: 1.45;
|
|
171
|
-
color:
|
|
191
|
+
color: var(--face-text-desc);
|
|
172
192
|
}
|
|
173
193
|
|
|
174
194
|
pre {
|
|
175
|
-
background:
|
|
176
|
-
border: 1px solid
|
|
195
|
+
background: var(--face-bg-code);
|
|
196
|
+
border: 1px solid var(--face-border-faint);
|
|
177
197
|
border-radius: 6px;
|
|
178
198
|
padding: 8px 10px;
|
|
179
199
|
font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;
|
|
180
200
|
font-size: 10.5px;
|
|
181
201
|
line-height: 1.45;
|
|
182
|
-
color:
|
|
202
|
+
color: var(--face-danger);
|
|
183
203
|
white-space: pre-wrap;
|
|
184
204
|
overflow-wrap: anywhere;
|
|
185
205
|
max-height: 160px;
|
|
@@ -188,8 +208,8 @@ export class SecuritySecurityCard extends HTMLElement {
|
|
|
188
208
|
}
|
|
189
209
|
|
|
190
210
|
#device-review {
|
|
191
|
-
background:
|
|
192
|
-
border: 1px solid
|
|
211
|
+
background: var(--face-bg-surface);
|
|
212
|
+
border: 1px solid var(--face-border-alert);
|
|
193
213
|
border-radius: 6px;
|
|
194
214
|
padding: 10px;
|
|
195
215
|
margin-top: 10px;
|
|
@@ -198,7 +218,7 @@ export class SecuritySecurityCard extends HTMLElement {
|
|
|
198
218
|
#device-review p {
|
|
199
219
|
margin: 0 0 8px 0;
|
|
200
220
|
font-size: 11px;
|
|
201
|
-
color:
|
|
221
|
+
color: var(--face-warning);
|
|
202
222
|
}
|
|
203
223
|
|
|
204
224
|
#device-checks label {
|
|
@@ -209,9 +229,15 @@ export class SecuritySecurityCard extends HTMLElement {
|
|
|
209
229
|
#device-checks label p {
|
|
210
230
|
margin: 0 0 4px 0;
|
|
211
231
|
font-size: 11px;
|
|
212
|
-
color:
|
|
232
|
+
color: var(--face-text-heading);
|
|
213
233
|
font-weight: 600;
|
|
214
234
|
}
|
|
235
|
+
|
|
236
|
+
@media (prefers-reduced-motion: reduce) {
|
|
237
|
+
button, input, select {
|
|
238
|
+
transition: none !important;
|
|
239
|
+
}
|
|
240
|
+
}
|
|
215
241
|
</style>
|
|
216
242
|
|
|
217
243
|
<header>
|
package/src/cli/command.mjs
CHANGED
|
@@ -222,6 +222,27 @@ function headerTags(description, risk) {
|
|
|
222
222
|
return (description ? `// @description ${one(description)}\n` : '') + (risk ? `// @risk ${risk}\n` : '');
|
|
223
223
|
}
|
|
224
224
|
|
|
225
|
+
/**
|
|
226
|
+
* Build a custom command's file from author-supplied source.
|
|
227
|
+
*
|
|
228
|
+
* The source may be a BODY for run(argv) or a complete module. Blindly wrapping it failed two ways:
|
|
229
|
+
* a module produced "Unexpected identifier 'fs'", and a body that declared its own `args` produced
|
|
230
|
+
* "Identifier 'args' has already been declared". Detect the shape instead of assuming it, and declare
|
|
231
|
+
* `args` only when the body does not. The default export delegates so the body is written once.
|
|
232
|
+
*/
|
|
233
|
+
function buildCommandFile(name, description, risk, code) {
|
|
234
|
+
const source = String(code ?? '');
|
|
235
|
+
const header = `// Auto-generated custom CLI command: ${name}\n${headerTags(description, risk)}`;
|
|
236
|
+
if (/^\s*(?:import|export)\s/m.test(source)) {
|
|
237
|
+
return `${header}// Supplied as a complete module; used as written.\n${source}\n`;
|
|
238
|
+
}
|
|
239
|
+
const declaresArgs = /(?:^|\n)\s*(?:const|let|var)\s+args\b/.test(source);
|
|
240
|
+
const argsLine = declaresArgs ? '' : 'const args = Array.isArray(argv) ? argv.slice(3) : [];\n';
|
|
241
|
+
return `${header}// Your source is the BODY of run(argv). \`argv\` is in scope${declaresArgs ? '' : ', and so is `args` (argv minus the command name)'}.\n`
|
|
242
|
+
+ "// Use `await import('node:module')`; write no import/export statements here.\n"
|
|
243
|
+
+ `export async function run(argv = []) {\n${argsLine}${source}\n}\nexport default function (argv = []) {\n return run(argv);\n}\n`;
|
|
244
|
+
}
|
|
245
|
+
|
|
225
246
|
function existingTag(file, key) {
|
|
226
247
|
try { return fs.readFileSync(file, 'utf8').match(new RegExp(`^// @${key} (.+)$`, 'm'))?.[1] || undefined; } catch { return undefined; }
|
|
227
248
|
}
|
|
@@ -373,15 +394,7 @@ export default async function commandCmd(rawArgs = []) {
|
|
|
373
394
|
}
|
|
374
395
|
|
|
375
396
|
// Wrap code in an exported run/default function for composable CLI execution
|
|
376
|
-
const fileContent =
|
|
377
|
-
${headerTags(description, risk)}export async function run(argv = []) {
|
|
378
|
-
const args = Array.isArray(argv) ? argv.slice(3) : [];
|
|
379
|
-
${code}
|
|
380
|
-
}
|
|
381
|
-
export default async function (args = []) {
|
|
382
|
-
${code}
|
|
383
|
-
}
|
|
384
|
-
`;
|
|
397
|
+
const fileContent = buildCommandFile(name, description, risk, code);
|
|
385
398
|
|
|
386
399
|
fs.writeFileSync(commandPath, fileContent, 'utf8');
|
|
387
400
|
console.log(`\x1b[32m✔ Successfully created custom command: \x1b[1mnpx total-recall ${name}\x1b[0m`);
|
|
@@ -413,15 +426,7 @@ export default async function (args = []) {
|
|
|
413
426
|
// Keep the declared description/risk unless the update replaces them.
|
|
414
427
|
const keptDescription = description ?? existingTag(commandPath, 'description');
|
|
415
428
|
const keptRisk = risk ?? existingTag(commandPath, 'risk');
|
|
416
|
-
const fileContent =
|
|
417
|
-
${headerTags(keptDescription, keptRisk)}export async function run(argv = []) {
|
|
418
|
-
const args = Array.isArray(argv) ? argv.slice(3) : [];
|
|
419
|
-
${code}
|
|
420
|
-
}
|
|
421
|
-
export default async function (args = []) {
|
|
422
|
-
${code}
|
|
423
|
-
}
|
|
424
|
-
`;
|
|
429
|
+
const fileContent = buildCommandFile(name, keptDescription, keptRisk, code);
|
|
425
430
|
|
|
426
431
|
fs.writeFileSync(commandPath, fileContent, 'utf8');
|
|
427
432
|
console.log(`\x1b[32m✔ Successfully updated custom command: \x1b[1m${name}\x1b[0m`);
|
package/src/cli/config.mjs
CHANGED
|
@@ -17,6 +17,9 @@ const KEY_MAP = {
|
|
|
17
17
|
'public_health': { file: 'security', path: 'network.public_health', type: 'boolean' },
|
|
18
18
|
'allowed_origins': { file: 'security', path: 'network.allowed_origins', type: 'array' },
|
|
19
19
|
|
|
20
|
+
// How long a `total-recall preflight ack` receipt stays fresh. Recorded in the receipt when it is written.
|
|
21
|
+
'preflight_max_age_minutes': { file: 'preflight', path: 'preflight.max_age_minutes', type: 'number' },
|
|
22
|
+
|
|
20
23
|
'daily_cap_usd': { file: 'budget', path: 'budget.daily_cap_usd', type: 'number' },
|
|
21
24
|
'weekly_cap_usd': { file: 'budget', path: 'budget.weekly_cap_usd', type: 'number' },
|
|
22
25
|
'budget_enabled': { file: 'budget', path: 'budget.enabled', type: 'boolean' },
|