total-recall-brain 3.13.0 → 3.13.2
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/README.md +91 -108
- package/bin/antigravity.mjs +81 -52
- package/bin/total-recall.mjs +32 -57
- package/extension/background.js +1 -1
- package/extension/options/options.js +9 -3
- package/extension/sidepanel/sidepanel.js +0 -2
- package/frontend/index.html +4 -3
- package/frontend/package.json +1 -0
- package/frontend/src/App.tsx +109 -152
- package/frontend/src/api.ts +605 -23
- package/frontend/src/components/BrainSelector.tsx +211 -199
- package/frontend/src/components/DocumentEditorModal.tsx +57 -0
- package/frontend/src/components/DocumentTable.tsx +47 -0
- package/frontend/src/components/Graph3D.tsx +120 -71
- package/frontend/src/components/UsageChart.tsx +3 -3
- package/frontend/src/components/brand/BrandMark.tsx +95 -0
- package/frontend/src/index.css +286 -86
- package/frontend/src/pages/ApiKeysPage.tsx +1878 -215
- package/frontend/src/pages/ChatPage.tsx +103 -45
- package/frontend/src/pages/DesignDocsPage.tsx +5 -5
- package/frontend/src/pages/FilesPage.tsx +10 -6
- package/frontend/src/pages/GraphPage.tsx +5 -3
- package/frontend/src/pages/HelpPage.tsx +2 -2
- package/frontend/src/pages/InboxPage.tsx +82 -0
- package/frontend/src/pages/InstructionsPage.tsx +1 -1
- package/frontend/src/pages/IntegrationsPage.tsx +21 -10
- package/frontend/src/pages/LoginPage.tsx +95 -77
- package/frontend/src/pages/MemoryPage.tsx +31 -8
- package/frontend/src/pages/OnboardingPage.tsx +690 -0
- package/frontend/src/pages/OpenWikiPage.tsx +412 -323
- package/frontend/src/pages/SettingsPage.tsx +825 -922
- package/frontend/src/pages/SkillsPage.tsx +272 -147
- package/frontend/src/pages/UsagePage.tsx +23 -31
- package/frontend/src/pages/VaultPage.tsx +223 -0
- package/frontend/src/types.ts +13 -0
- package/package.json +4 -4
- package/scaffold/.agent/skills/total-recall/SKILL.md +43 -4
- package/scaffold/.agent/skills/total-recall/modules/README.md +10 -0
- package/scaffold/.agent/skills/total-recall/modules/agents/README.md +5 -0
- package/scaffold/.agent/skills/total-recall/{skills/tr-cli-agents → modules/agents}/agents.yml +8 -0
- package/scaffold/.agent/skills/total-recall/modules/skill-deploy/README.md +9 -0
- package/scaffold/.agent/skills/total-recall/openwiki/README.md +10 -0
- package/scaffold/.agent/skills/total-recall/openwiki/architecture.md +5 -0
- package/scaffold/.agent/skills/total-recall/openwiki/ide.md +10 -0
- package/scaffold/.agent/skills/total-recall/openwiki/memory.md +11 -0
- package/scaffold/.agent/skills/total-recall/openwiki/secrets.md +7 -0
- package/scaffold/.agent/skills/total-recall/openwiki/skills.md +7 -0
- package/src/cli/brain.mjs +63 -5
- package/src/cli/connect.mjs +11 -19
- package/src/cli/daemon.mjs +5 -4
- package/src/cli/deploy-ui.mjs +8 -3
- package/src/cli/deploy.mjs +84 -27
- package/src/cli/ingest/index.mjs +1 -1
- package/src/cli/init.mjs +63 -34
- package/src/cli/remember.mjs +3 -3
- package/src/cli/secret.mjs +812 -0
- package/src/cli/setup.mjs +34 -7
- package/src/cli/share.mjs +2 -2
- package/src/cli/skill.mjs +396 -35
- package/src/cli/sync.mjs +4 -4
- package/src/cli/task.mjs +287 -0
- package/src/core/clarity-rewriter.mjs +5 -5
- package/src/core/config.mjs +44 -2
- package/src/core/conflict-detector.mjs +5 -5
- package/src/core/crons.mjs +54 -0
- package/src/core/daemon-loop.mjs +87 -235
- package/src/core/dream.mjs +170 -10
- package/src/core/env-import.mjs +456 -0
- package/src/core/fact-seeker.mjs +14 -14
- package/src/core/import-rules.mjs +20 -7
- package/src/core/inference-engine.mjs +3 -3
- package/src/core/migrate.mjs +14 -8
- package/src/core/okf-adapter.mjs +2 -2
- package/src/core/operation-validator.mjs +39 -331
- package/src/core/optimizer.mjs +7 -0
- package/src/core/post-mortem.mjs +2 -2
- package/src/core/project-brain.mjs +349 -0
- package/src/core/provider-catalog.mjs +296 -0
- package/src/core/quick-capture.mjs +1 -1
- package/src/core/remote-vault-sync.mjs +194 -0
- package/src/core/research-queue.mjs +7 -11
- package/src/core/runtime.mjs +33 -9
- package/src/core/scheduler.mjs +59 -5
- package/src/core/schema.mjs +14 -0
- package/src/core/search.mjs +1 -1
- package/src/core/secrets-env-export.mjs +323 -0
- package/src/core/secrets-rotate.mjs +245 -0
- package/src/core/secrets-store.mjs +645 -0
- package/src/core/semantic-index.mjs +3 -3
- package/src/core/skills-registry.mjs +1062 -0
- package/src/core/source-adapters.mjs +4 -1
- package/src/core/ssss-host-extension.mjs +94 -0
- package/src/core/ssss-kernel-bridge.mjs +530 -0
- package/src/core/surface.mjs +14 -0
- package/src/core/task-envelope.mjs +298 -0
- package/src/core/task-executors.mjs +600 -0
- package/src/core/validated-write.mjs +124 -56
- package/src/core/vault.mjs +21 -34
- package/src/core/webauthn-store.mjs +272 -0
- package/src/server/api.mjs +26 -16
- package/src/server/auth.mjs +51 -0
- package/src/server/index.mjs +3 -3
- package/src/server/keys.mjs +30 -4
- package/src/server/rest.mjs +198 -25
- package/src/server/route-manifest.json +156 -0
- package/src/server/routes/_shared.mjs +40 -1
- package/src/server/routes/docs.mjs +260 -0
- package/src/server/routes/memory.mjs +145 -32
- package/src/server/routes/research.mjs +30 -0
- package/src/server/routes/secrets.mjs +470 -0
- package/src/server/routes/share.mjs +2 -2
- package/src/server/routes/skills.mjs +452 -54
- package/src/server/routes/sync.mjs +48 -0
- package/src/server/routes/webauthn.mjs +184 -0
- package/src/server/update-route-manifest.mjs +39 -0
- package/templates/onboarding-interview.md +32 -22
- package/templates/openwiki/README.md +10 -0
- package/templates/openwiki/architecture.md +5 -0
- package/templates/openwiki/ide.md +10 -0
- package/templates/openwiki/memory.md +11 -0
- package/templates/openwiki/secrets.md +7 -0
- package/templates/openwiki/skills.md +7 -0
- package/scaffold/.agent/skills/total-recall/skills/tr-cli-agents/SKILL.md +0 -121
- package/scaffold/.agent/skills/total-recall/skills/tr-cli-agents/references/antigravity.txt +0 -20
- package/scaffold/.agent/skills/total-recall/skills/tr-cli-agents/references/claude.txt +0 -58
- package/scaffold/.agent/skills/total-recall/skills/tr-cli-agents/references/codex.txt +0 -81
- package/scaffold/.agent/skills/total-recall/skills/tr-cli-agents/references/gemini.txt +0 -44
- package/scaffold/.agent/skills/total-recall/skills/tr-cli-agents/scripts/.gitkeep +0 -0
- package/scaffold/.agent/skills/total-recall/skills/tr-cli-agents/subagents/.gitkeep +0 -0
- package/scaffold/.agent/skills/total-recall/skills/tr-research/SKILL.md +0 -338
- package/scaffold/.agent/skills/total-recall/skills/tr-skill/SKILL.md +0 -282
- package/scaffold/.agent/skills/total-recall/skills/tr-skill/assets/skill-template/SKILL.md +0 -20
- package/scaffold/.agent/skills/total-recall/skills/tr-skill/evals/evals.json +0 -20
- package/scaffold/.agent/skills/total-recall/skills/tr-skill/hooks/on-skill-add.sh +0 -14
- package/scaffold/.agent/skills/total-recall/skills/tr-skill/hooks/on-skill-delete.sh +0 -14
- package/scaffold/.agent/skills/total-recall/skills/tr-skill/learnings/.gitkeep +0 -0
- package/scaffold/.agent/skills/total-recall/skills/tr-skill/references/.gitkeep +0 -0
- package/scaffold/.agent/skills/total-recall/skills/tr-skill/scripts/.gitkeep +0 -0
- package/scaffold/.agent/skills/total-recall/skills/tr-skill/scripts/create-skill.sh +0 -65
- package/scaffold/.agent/skills/total-recall/skills/tr-skill/scripts/enforce-skill-optimization.mjs +0 -135
- package/scaffold/.agent/skills/total-recall/skills/tr-skill/scripts/skill-watcher.mjs +0 -64
- package/scaffold/.agent/skills/total-recall/skills/tr-skill/subagents/audit-all-skills.md +0 -62
- package/scaffold/.agent/skills/total-recall/skills/tr-ssss/SKILL.md +0 -298
- package/scaffold/.agent/skills/total-recall/skills/tr-ssss/evals/evals.json +0 -17
- package/scaffold/.agent/skills/total-recall/skills/tr-ssss/references/CHANGELOG.md +0 -124
- package/scaffold/.agent/skills/total-recall/skills/tr-ssss/references/ssss-spec.md +0 -1325
- package/scaffold/.agent/skills/total-recall/skills/tr-ssss/scripts/validate-schema.mjs +0 -232
- package/scaffold/.agent/skills/total-recall/skills/tr-ssss/subagents/audit-ssss-node.md +0 -9
- /package/scaffold/.agent/skills/total-recall/{skills/tr-cli-agents/evals → modules/skill-deploy/scripts}/.gitkeep +0 -0
- /package/scaffold/.agent/skills/total-recall/{skills/tr-skill → modules/skill-deploy}/scripts/find-skills.mjs +0 -0
- /package/scaffold/.agent/skills/total-recall/{skills/tr-skill → modules/skill-deploy}/scripts/install-skill.mjs +0 -0
- /package/scaffold/.agent/skills/total-recall/{skills/tr-skill → modules/skill-deploy}/scripts/scan-skill.mjs +0 -0
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { useState, useRef, useEffect } from "react"
|
|
2
2
|
import { login, changePassword, getAuthStatus, setupPassword } from "../api"
|
|
3
|
+
import BrandMark from "../components/brand/BrandMark"
|
|
3
4
|
|
|
4
5
|
interface Props {
|
|
5
6
|
onAuthenticated: () => void
|
|
@@ -73,7 +74,7 @@ export default function LoginPage({ onAuthenticated }: Props) {
|
|
|
73
74
|
if (res.ok) {
|
|
74
75
|
if (res.requiresPasswordReset) {
|
|
75
76
|
setNeedsReset(true)
|
|
76
|
-
setPassword("")
|
|
77
|
+
setPassword("")
|
|
77
78
|
} else {
|
|
78
79
|
onAuthenticated()
|
|
79
80
|
}
|
|
@@ -88,63 +89,66 @@ export default function LoginPage({ onAuthenticated }: Props) {
|
|
|
88
89
|
}
|
|
89
90
|
}
|
|
90
91
|
|
|
92
|
+
const disabled = loading || ((isFirstTime || needsReset) ? !newPassword : !password)
|
|
93
|
+
|
|
91
94
|
return (
|
|
92
|
-
<div
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
}}>
|
|
110
|
-
{/* Brand */}
|
|
111
|
-
<div style={{ textAlign: "center" }}>
|
|
112
|
-
<div style={{
|
|
113
|
-
width: 48,
|
|
114
|
-
height: 48,
|
|
115
|
-
borderRadius: 12,
|
|
116
|
-
background: (needsReset || isFirstTime) ? "linear-gradient(135deg, #f59e0b, #d97706)" : "linear-gradient(135deg, var(--accent), #7c3aed)",
|
|
117
|
-
margin: "0 auto 16px",
|
|
118
|
-
display: "flex",
|
|
119
|
-
alignItems: "center",
|
|
120
|
-
justifyContent: "center",
|
|
121
|
-
}}>
|
|
122
|
-
{(needsReset || isFirstTime) ? (
|
|
123
|
-
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="white" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
|
|
95
|
+
<div className="login-shell">
|
|
96
|
+
<div className="login-card">
|
|
97
|
+
<div style={{ textAlign: "center", display: "flex", flexDirection: "column", alignItems: "center", gap: 16 }}>
|
|
98
|
+
{(needsReset || isFirstTime) ? (
|
|
99
|
+
<div
|
|
100
|
+
style={{
|
|
101
|
+
width: 56,
|
|
102
|
+
height: 56,
|
|
103
|
+
borderRadius: 16,
|
|
104
|
+
background: "linear-gradient(135deg, #f59e0b, #d97706)",
|
|
105
|
+
display: "flex",
|
|
106
|
+
alignItems: "center",
|
|
107
|
+
justifyContent: "center",
|
|
108
|
+
boxShadow: "0 12px 32px rgba(245, 158, 11, 0.35)",
|
|
109
|
+
}}
|
|
110
|
+
>
|
|
111
|
+
<svg width="26" height="26" viewBox="0 0 24 24" fill="none" stroke="white" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
|
|
124
112
|
<rect x="3" y="11" width="18" height="11" rx="2" ry="2"/>
|
|
125
113
|
<path d="M7 11V7a5 5 0 0 1 10 0v4"/>
|
|
126
114
|
</svg>
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
115
|
+
</div>
|
|
116
|
+
) : (
|
|
117
|
+
<div
|
|
118
|
+
style={{
|
|
119
|
+
width: "100%",
|
|
120
|
+
maxWidth: 280,
|
|
121
|
+
borderRadius: 16,
|
|
122
|
+
padding: "14px 18px",
|
|
123
|
+
background: "linear-gradient(180deg, #f8fafc 0%, #e8eef9 100%)",
|
|
124
|
+
boxShadow:
|
|
125
|
+
"0 1px 0 rgba(255,255,255,0.75) inset, 0 16px 40px rgba(15, 23, 42, 0.45), 0 0 0 1px rgba(148,163,184,0.25)",
|
|
126
|
+
}}
|
|
127
|
+
>
|
|
128
|
+
<BrandMark variant="lockup" height={56} alt="Total Recall" />
|
|
129
|
+
</div>
|
|
130
|
+
)}
|
|
131
|
+
<div>
|
|
132
|
+
<h1 style={{ fontSize: 22, fontWeight: 700, color: "var(--text-primary)", margin: 0, letterSpacing: "-0.03em" }}>
|
|
133
|
+
{needsReset ? "Action Required" : isFirstTime ? "Setup Admin Password" : "Welcome back"}
|
|
134
|
+
</h1>
|
|
135
|
+
<p style={{ fontSize: 13.5, color: "var(--text-secondary)", margin: "8px 0 0", lineHeight: 1.5 }}>
|
|
136
|
+
{needsReset
|
|
137
|
+
? "You must change your temporary password to continue."
|
|
138
|
+
: isFirstTime
|
|
139
|
+
? "Choose a strong password to secure your local memory dashboard."
|
|
140
|
+
: "Portable personal memory · any IDE"}
|
|
141
|
+
</p>
|
|
134
142
|
</div>
|
|
135
|
-
<h1 style={{ fontSize: 20, fontWeight: 700, color: "var(--text-primary)", margin: 0 }}>
|
|
136
|
-
{needsReset ? "Action Required" : isFirstTime ? "Setup Admin Password" : "Total Recall"}
|
|
137
|
-
</h1>
|
|
138
|
-
<p style={{ fontSize: 13, color: "var(--text-tertiary)", margin: "4px 0 0" }}>
|
|
139
|
-
{needsReset ? "You must change your temporary password to continue." : isFirstTime ? "Choose a strong password to secure your dashboard." : "Sovereign Brain v3.0"}
|
|
140
|
-
</p>
|
|
141
143
|
</div>
|
|
142
144
|
|
|
143
|
-
{/* Form */}
|
|
144
145
|
<form onSubmit={handleSubmit} style={{ display: "flex", flexDirection: "column", gap: 16 }}>
|
|
145
146
|
<input type="text" name="username" autoComplete="username" style={{ display: "none" }} />
|
|
146
|
-
<div style={{ display: "flex", flexDirection: "column", gap:
|
|
147
|
-
<label
|
|
147
|
+
<div style={{ display: "flex", flexDirection: "column", gap: 8 }}>
|
|
148
|
+
<label
|
|
149
|
+
htmlFor="login-password"
|
|
150
|
+
style={{ fontSize: 11, fontWeight: 600, color: "var(--text-tertiary)", textTransform: "uppercase", letterSpacing: "0.08em" }}
|
|
151
|
+
>
|
|
148
152
|
{(needsReset || isFirstTime) ? "New Password" : "Password"}
|
|
149
153
|
</label>
|
|
150
154
|
<input
|
|
@@ -161,30 +165,43 @@ export default function LoginPage({ onAuthenticated }: Props) {
|
|
|
161
165
|
autoComplete={(isFirstTime || needsReset) ? "new-password" : "current-password"}
|
|
162
166
|
disabled={loading}
|
|
163
167
|
style={{
|
|
164
|
-
background: "
|
|
165
|
-
border: `1px solid ${error ? "
|
|
166
|
-
borderRadius:
|
|
167
|
-
padding: "
|
|
168
|
+
background: "rgba(7, 11, 20, 0.65)",
|
|
169
|
+
border: `1px solid ${error ? "rgba(248,113,113,0.55)" : "var(--border)"}`,
|
|
170
|
+
borderRadius: 12,
|
|
171
|
+
padding: "12px 16px",
|
|
168
172
|
color: "var(--text-primary)",
|
|
169
173
|
fontSize: 14,
|
|
170
174
|
outline: "none",
|
|
171
|
-
transition: "border-color 0.15s",
|
|
175
|
+
transition: "border-color 0.15s, box-shadow 0.15s",
|
|
176
|
+
boxShadow: error ? "0 0 0 3px rgba(248,113,113,0.12)" : "inset 0 1px 2px rgba(0,0,0,0.25)",
|
|
177
|
+
}}
|
|
178
|
+
onFocus={e => {
|
|
179
|
+
if (!error) {
|
|
180
|
+
e.currentTarget.style.borderColor = "var(--border-accent)"
|
|
181
|
+
e.currentTarget.style.boxShadow = "0 0 0 3px var(--accent-glow)"
|
|
182
|
+
}
|
|
183
|
+
}}
|
|
184
|
+
onBlur={e => {
|
|
185
|
+
e.currentTarget.style.borderColor = error ? "rgba(248,113,113,0.55)" : "var(--border)"
|
|
186
|
+
e.currentTarget.style.boxShadow = error ? "0 0 0 3px rgba(248,113,113,0.12)" : "inset 0 1px 2px rgba(0,0,0,0.25)"
|
|
172
187
|
}}
|
|
173
188
|
/>
|
|
174
189
|
</div>
|
|
175
190
|
|
|
176
191
|
{error && (
|
|
177
|
-
<div
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
192
|
+
<div
|
|
193
|
+
style={{
|
|
194
|
+
background: "rgba(248,113,113,0.1)",
|
|
195
|
+
border: "1px solid rgba(248,113,113,0.3)",
|
|
196
|
+
borderRadius: 12,
|
|
197
|
+
padding: "11px 14px",
|
|
198
|
+
fontSize: 13,
|
|
199
|
+
color: "#fca5a5",
|
|
200
|
+
display: "flex",
|
|
201
|
+
alignItems: "center",
|
|
202
|
+
gap: 8,
|
|
203
|
+
}}
|
|
204
|
+
>
|
|
188
205
|
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" style={{ flexShrink: 0 }}>
|
|
189
206
|
<circle cx="12" cy="12" r="10"/><line x1="12" y1="8" x2="12" y2="12"/><line x1="12" y1="16" x2="12.01" y2="16"/>
|
|
190
207
|
</svg>
|
|
@@ -195,20 +212,20 @@ export default function LoginPage({ onAuthenticated }: Props) {
|
|
|
195
212
|
<button
|
|
196
213
|
id="login-submit"
|
|
197
214
|
type="submit"
|
|
198
|
-
disabled={
|
|
215
|
+
disabled={disabled}
|
|
216
|
+
className={disabled ? undefined : "btn btn-primary"}
|
|
199
217
|
style={{
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
borderRadius: 8,
|
|
204
|
-
padding: "11px 0",
|
|
218
|
+
width: "100%",
|
|
219
|
+
justifyContent: "center",
|
|
220
|
+
padding: "12px 0",
|
|
205
221
|
fontSize: 14,
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
222
|
+
borderRadius: 12,
|
|
223
|
+
border: "none",
|
|
224
|
+
cursor: disabled ? "not-allowed" : "pointer",
|
|
225
|
+
background: disabled ? "var(--bg-tertiary)" : undefined,
|
|
226
|
+
color: disabled ? "var(--text-tertiary)" : undefined,
|
|
209
227
|
display: "flex",
|
|
210
228
|
alignItems: "center",
|
|
211
|
-
justifyContent: "center",
|
|
212
229
|
gap: 8,
|
|
213
230
|
}}
|
|
214
231
|
>
|
|
@@ -224,8 +241,9 @@ export default function LoginPage({ onAuthenticated }: Props) {
|
|
|
224
241
|
</form>
|
|
225
242
|
|
|
226
243
|
{(!needsReset && !isFirstTime) && (
|
|
227
|
-
<p style={{ textAlign: "center", fontSize: 11, color: "var(--text-tertiary)", margin: 0 }}>
|
|
228
|
-
|
|
244
|
+
<p style={{ textAlign: "center", fontSize: 11, color: "var(--text-tertiary)", margin: 0, lineHeight: 1.5 }}>
|
|
245
|
+
Local-first vault · credentials in{" "}
|
|
246
|
+
<code style={{ color: "#93c5fd", fontSize: 11 }}>~/.agent/config/security.yml</code>
|
|
229
247
|
</p>
|
|
230
248
|
)}
|
|
231
249
|
</div>
|
|
@@ -222,7 +222,7 @@ export default function MemoryPage({ activeBrainId }: { activeBrainId?: string }
|
|
|
222
222
|
related: relatedArr,
|
|
223
223
|
contradicts: contradictsArr,
|
|
224
224
|
supersedes: supersedesArr
|
|
225
|
-
})
|
|
225
|
+
}, activeBrainId)
|
|
226
226
|
setSelected(updated)
|
|
227
227
|
setIsEditing(false)
|
|
228
228
|
fetchNodes()
|
|
@@ -260,7 +260,7 @@ export default function MemoryPage({ activeBrainId }: { activeBrainId?: string }
|
|
|
260
260
|
related: relatedArr,
|
|
261
261
|
contradicts: contradictsArr,
|
|
262
262
|
supersedes: supersedesArr
|
|
263
|
-
})
|
|
263
|
+
}, activeBrainId)
|
|
264
264
|
setIsCreating(false)
|
|
265
265
|
setSelected(created)
|
|
266
266
|
setSearchParams({ slug: created.slug })
|
|
@@ -277,7 +277,7 @@ export default function MemoryPage({ activeBrainId }: { activeBrainId?: string }
|
|
|
277
277
|
setLoading(true)
|
|
278
278
|
setError("")
|
|
279
279
|
try {
|
|
280
|
-
await deleteMemory(slug)
|
|
280
|
+
await deleteMemory(slug, activeBrainId)
|
|
281
281
|
setSelected(null)
|
|
282
282
|
setSearchParams({})
|
|
283
283
|
fetchNodes()
|
|
@@ -339,14 +339,34 @@ export default function MemoryPage({ activeBrainId }: { activeBrainId?: string }
|
|
|
339
339
|
useEffect(() => {
|
|
340
340
|
if (urlSlug) {
|
|
341
341
|
const loadUrlSlug = async () => {
|
|
342
|
+
// Prefer list payload (already loaded for the active brain) so project-brain
|
|
343
|
+
// nodes render even before a scoped GET completes.
|
|
344
|
+
const fromList = nodes.find((n) => n.slug === urlSlug)
|
|
345
|
+
if (fromList && (fromList.content || fromList.body)) {
|
|
346
|
+
setSelected(fromList)
|
|
347
|
+
setError("")
|
|
348
|
+
return
|
|
349
|
+
}
|
|
342
350
|
setLoading(true)
|
|
343
351
|
setError("")
|
|
344
352
|
try {
|
|
345
|
-
const full = await readMemory(urlSlug)
|
|
346
|
-
|
|
353
|
+
const full = await readMemory(urlSlug, activeBrainId)
|
|
354
|
+
if (full) {
|
|
355
|
+
setSelected(full)
|
|
356
|
+
} else if (fromList) {
|
|
357
|
+
setSelected(fromList)
|
|
358
|
+
} else {
|
|
359
|
+
setError(`Memory node not found: ${urlSlug}`)
|
|
360
|
+
setSelected(null)
|
|
361
|
+
}
|
|
347
362
|
} catch (e) {
|
|
348
|
-
|
|
349
|
-
|
|
363
|
+
if (fromList) {
|
|
364
|
+
setSelected(fromList)
|
|
365
|
+
setError("")
|
|
366
|
+
} else {
|
|
367
|
+
setError(`Failed to load memory node '${urlSlug}': ${(e as Error).message}`)
|
|
368
|
+
setSelected(null)
|
|
369
|
+
}
|
|
350
370
|
} finally {
|
|
351
371
|
setLoading(false)
|
|
352
372
|
}
|
|
@@ -356,7 +376,7 @@ export default function MemoryPage({ activeBrainId }: { activeBrainId?: string }
|
|
|
356
376
|
// eslint-disable-next-line react-hooks/set-state-in-effect -- legitimate reset on url change
|
|
357
377
|
setSelected(null)
|
|
358
378
|
}
|
|
359
|
-
}, [urlSlug])
|
|
379
|
+
}, [urlSlug, activeBrainId, nodes])
|
|
360
380
|
|
|
361
381
|
// Wire SSE Live Agent Monitor Streaming (Port 9111)
|
|
362
382
|
useEffect(() => {
|
|
@@ -390,6 +410,9 @@ export default function MemoryPage({ activeBrainId }: { activeBrainId?: string }
|
|
|
390
410
|
}, [fetchNodes, fetchConflictsList])
|
|
391
411
|
|
|
392
412
|
const handleSelect = (node: MemoryNode) => {
|
|
413
|
+
// Show immediately from list (includes body/content for the vault that listed it)
|
|
414
|
+
setSelected(node)
|
|
415
|
+
setError("")
|
|
393
416
|
setSearchParams({ slug: node.slug })
|
|
394
417
|
}
|
|
395
418
|
|