memory-eternal 0.10.54 → 0.12.0
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/.claude-plugin/plugin.json +1 -1
- package/.codex-plugin/plugin.json +1 -1
- package/.cursor-plugin/plugin.json +1 -1
- package/README.en.md +42 -10
- package/README.md +42 -10
- package/assets/icon.png +0 -0
- package/cursor-extension/README.md +41 -0
- package/cursor-extension/extension.js +58 -0
- package/cursor-extension/icon.png +0 -0
- package/cursor-extension/package.json +54 -0
- package/dsh-tui-plugin/README.md +48 -0
- package/dsh-tui-plugin/cordis.patch.yml +3 -0
- package/dsh-tui-plugin/dsh-plugin.json +37 -0
- package/dsh-tui-plugin/main.js +54 -0
- package/dsh-tui-plugin/package.json +29 -0
- package/index.js +15 -0
- package/lib/api.js +25 -0
- package/lib/client.js +376 -21
- package/lib/web.js +16 -0
- package/orca-plugin/README.md +46 -0
- package/orca-plugin/assets/icon.png +0 -0
- package/orca-plugin/orca-plugin.json +36 -0
- package/orca-plugin/panel.html +200 -0
- package/package.json +6 -1
- package/skills/memory-open/SKILL.md +22 -0
- package/web/app.js +383 -28
- package/web/icon.png +0 -0
- package/web/support/group-qr.jpg +0 -0
- package/web/support/wechat-pay.jpg +0 -0
- package/web/support/wechat-reward.jpg +0 -0
package/lib/web.js
CHANGED
|
@@ -192,6 +192,22 @@ export function startWebServer({ port = DEFAULT_WEB_PORT, vaultRoot = defaultVau
|
|
|
192
192
|
return res.end(missingIndexHtml({ missing, webRoot, version: VERSION }))
|
|
193
193
|
}
|
|
194
194
|
}
|
|
195
|
+
if (p.startsWith('/support/')) {
|
|
196
|
+
const name = p.slice('/support/'.length)
|
|
197
|
+
if (!/^[a-z0-9-]+\.(jpg|jpeg|png)$/i.test(name)) {
|
|
198
|
+
res.writeHead(404, { 'Content-Type': 'text/plain; charset=utf-8' })
|
|
199
|
+
return res.end('not found')
|
|
200
|
+
}
|
|
201
|
+
try {
|
|
202
|
+
const buf = await fs.readFile(path.join(webRoot, 'support', name))
|
|
203
|
+
res.writeHead(200, { 'Content-Type': /\.png$/i.test(name) ? 'image/png' : 'image/jpeg', 'Cache-Control': 'public, max-age=3600' })
|
|
204
|
+
return res.end(buf)
|
|
205
|
+
} catch (error) {
|
|
206
|
+
if (!isMissingFile(error)) throw error
|
|
207
|
+
res.writeHead(404, { 'Content-Type': 'text/plain; charset=utf-8' })
|
|
208
|
+
return res.end('not found')
|
|
209
|
+
}
|
|
210
|
+
}
|
|
195
211
|
if (p === '/app.js') {
|
|
196
212
|
let buf
|
|
197
213
|
try {
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# Orca plugin — Memory Atlas 启动器
|
|
2
|
+
|
|
3
|
+
在 Orca 右侧栏添加一个「记忆」面板,一键在终端执行 `dsh-memory open`,打开本地 Memory Atlas Web UI。
|
|
4
|
+
|
|
5
|
+
## 安装
|
|
6
|
+
|
|
7
|
+
1. 确认本机已安装并运行 `memory-eternal`(默认 Web 服务 `http://127.0.0.1:7999/`)。
|
|
8
|
+
2. 确认终端能找到 CLI:
|
|
9
|
+
|
|
10
|
+
```bash
|
|
11
|
+
dsh-memory --help
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
3. 在 Orca 中安装本目录:
|
|
15
|
+
|
|
16
|
+
```text
|
|
17
|
+
Orca → Plugins → Install plugin → 选择 orca-plugin/
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
4. 打开右侧栏的「记忆」图标,选择终端,点「打开 Memory Atlas」。
|
|
21
|
+
|
|
22
|
+
## 它做什么
|
|
23
|
+
|
|
24
|
+
- 调 Orca 官方 `workspace.readContext` 读取当前工作区终端
|
|
25
|
+
- 调 Orca 官方 `terminal.sendText` 执行 `dsh-memory open`
|
|
26
|
+
- 不 iframe、不 fetch、不复制第二套 UI
|
|
27
|
+
|
|
28
|
+
## 为什么不是完整内嵌 UI
|
|
29
|
+
|
|
30
|
+
Orca panel 使用严格沙箱 CSP:
|
|
31
|
+
|
|
32
|
+
```text
|
|
33
|
+
default-src 'none'
|
|
34
|
+
connect-src 'none'
|
|
35
|
+
img-src data:
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
因此 panel 内不能 iframe `127.0.0.1:7999`、不能 fetch API、不能 `window.open`。
|
|
39
|
+
完整 Memory Atlas 仍由 Web UI 提供;Orca 只做官方能力内的启动器。
|
|
40
|
+
|
|
41
|
+
## 权限
|
|
42
|
+
|
|
43
|
+
- `workspace:read`:读取当前工作区终端列表
|
|
44
|
+
- `terminal:send`:向指定终端发送命令
|
|
45
|
+
|
|
46
|
+
没有任何内存卡写入、审核批准或 agent 权限。
|
|
Binary file
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
{
|
|
2
|
+
"manifestVersion": 1,
|
|
3
|
+
"id": "memory-eternal",
|
|
4
|
+
"publisher": "eternalnight996",
|
|
5
|
+
"name": "memory-eternal",
|
|
6
|
+
"version": "0.12.0",
|
|
7
|
+
"description": "Memory Atlas for Orca: open the local memory vault, pending review and knowledge graph from a sandboxed Orca panel.",
|
|
8
|
+
"author": {
|
|
9
|
+
"name": "EternalNight996",
|
|
10
|
+
"url": "https://github.com/EternalNight996"
|
|
11
|
+
},
|
|
12
|
+
"repository": "https://github.com/EternalNight996/memory-eternal",
|
|
13
|
+
"icon": "assets/icon.png",
|
|
14
|
+
"engines": {
|
|
15
|
+
"orca": ">=1.4.0"
|
|
16
|
+
},
|
|
17
|
+
"pluginApi": 1,
|
|
18
|
+
"contributes": {
|
|
19
|
+
"panels": [
|
|
20
|
+
{
|
|
21
|
+
"id": "memory",
|
|
22
|
+
"title": "记忆",
|
|
23
|
+
"icon": "brain",
|
|
24
|
+
"entry": "panel.html"
|
|
25
|
+
}
|
|
26
|
+
]
|
|
27
|
+
},
|
|
28
|
+
"capabilities": [
|
|
29
|
+
{
|
|
30
|
+
"kind": "workspace:read"
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
"kind": "terminal:send"
|
|
34
|
+
}
|
|
35
|
+
]
|
|
36
|
+
}
|
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html lang="zh-CN">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="utf-8" />
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
6
|
+
<title>Memory Atlas</title>
|
|
7
|
+
<style>
|
|
8
|
+
:root { color-scheme: dark; }
|
|
9
|
+
* { box-sizing: border-box; }
|
|
10
|
+
body {
|
|
11
|
+
margin: 0;
|
|
12
|
+
min-height: 100vh;
|
|
13
|
+
padding: 18px 16px 22px;
|
|
14
|
+
font-family: var(--font-sans, system-ui, -apple-system, "Segoe UI", "Microsoft YaHei", sans-serif);
|
|
15
|
+
font-size: 12.5px;
|
|
16
|
+
line-height: 1.6;
|
|
17
|
+
color: var(--foreground, #f3f5f8);
|
|
18
|
+
background:
|
|
19
|
+
radial-gradient(120% 80% at 100% 0%, rgba(255,122,69,.10), transparent 55%),
|
|
20
|
+
var(--background, #1e2228);
|
|
21
|
+
}
|
|
22
|
+
.brand { display: flex; align-items: center; gap: 10px; margin-bottom: 16px; }
|
|
23
|
+
.mark {
|
|
24
|
+
width: 38px; height: 38px; flex: none;
|
|
25
|
+
display: flex; align-items: center; justify-content: center;
|
|
26
|
+
border-radius: 11px; font-size: 21px;
|
|
27
|
+
background: rgba(255,122,69,.10);
|
|
28
|
+
border: 1px solid rgba(255,122,69,.24);
|
|
29
|
+
}
|
|
30
|
+
.brand h1 { margin: 0; font-size: 16px; line-height: 1.2; font-weight: 650; }
|
|
31
|
+
.brand p { margin: 2px 0 0; font-size: 10px; letter-spacing: .12em; color: var(--muted-foreground, #99a1ac); }
|
|
32
|
+
.card {
|
|
33
|
+
padding: 14px;
|
|
34
|
+
border: 1px solid var(--border, #3a404a);
|
|
35
|
+
border-radius: 12px;
|
|
36
|
+
background: var(--card, rgba(38,43,51,.92));
|
|
37
|
+
}
|
|
38
|
+
.card h2 { margin: 0 0 5px; font-size: 12.5px; font-weight: 600; }
|
|
39
|
+
.card p { margin: 0; color: var(--muted-foreground, #b0b7c1); font-size: 11px; }
|
|
40
|
+
.row { display: flex; flex-direction: column; gap: 5px; margin-top: 13px; }
|
|
41
|
+
.row label { font-size: 10px; color: var(--muted-foreground, #99a1ac); }
|
|
42
|
+
select {
|
|
43
|
+
width: 100%;
|
|
44
|
+
padding: 7px 8px;
|
|
45
|
+
border-radius: 7px;
|
|
46
|
+
border: 1px solid var(--border, #3a404a);
|
|
47
|
+
background: var(--secondary, #2a2f37);
|
|
48
|
+
color: var(--foreground, #f3f5f8);
|
|
49
|
+
font: inherit;
|
|
50
|
+
font-size: 11px;
|
|
51
|
+
}
|
|
52
|
+
button {
|
|
53
|
+
width: 100%;
|
|
54
|
+
margin-top: 13px;
|
|
55
|
+
padding: 9px 10px;
|
|
56
|
+
border: 1px solid transparent;
|
|
57
|
+
border-radius: 8px;
|
|
58
|
+
background: var(--primary, #ff7a45);
|
|
59
|
+
color: var(--primary-foreground, #1b1f25);
|
|
60
|
+
font: inherit;
|
|
61
|
+
font-size: 12px;
|
|
62
|
+
font-weight: 650;
|
|
63
|
+
cursor: pointer;
|
|
64
|
+
}
|
|
65
|
+
button:hover { filter: brightness(1.06); }
|
|
66
|
+
button:disabled { opacity: .45; cursor: default; }
|
|
67
|
+
.status { min-height: 1.6em; margin: 10px 0 0; font-size: 10.5px; color: var(--muted-foreground, #99a1ac); }
|
|
68
|
+
.fallback { margin-top: 14px; padding-top: 12px; border-top: 1px solid var(--border, #3a404a); font-size: 10.5px; color: var(--muted-foreground, #99a1ac); }
|
|
69
|
+
.fallback code {
|
|
70
|
+
display: inline-block;
|
|
71
|
+
margin-top: 4px;
|
|
72
|
+
padding: 2px 6px;
|
|
73
|
+
border-radius: 4px;
|
|
74
|
+
background: rgba(127,127,127,.12);
|
|
75
|
+
color: var(--foreground, #f3f5f8);
|
|
76
|
+
font-family: ui-monospace, "Cascadia Code", Consolas, monospace;
|
|
77
|
+
font-size: 10px;
|
|
78
|
+
}
|
|
79
|
+
.warn { color: var(--destructive, #f87171); }
|
|
80
|
+
.ok { color: #4ade80; }
|
|
81
|
+
</style>
|
|
82
|
+
</head>
|
|
83
|
+
<body>
|
|
84
|
+
<div class="brand">
|
|
85
|
+
<div class="mark">🧠</div>
|
|
86
|
+
<div>
|
|
87
|
+
<h1>Memory Atlas</h1>
|
|
88
|
+
<p>MEMORY ETERNAL</p>
|
|
89
|
+
</div>
|
|
90
|
+
</div>
|
|
91
|
+
|
|
92
|
+
<div class="card">
|
|
93
|
+
<h2>本地记忆库</h2>
|
|
94
|
+
<p>记忆库、待审、读卡器与知识星图都在 Web 面板里;Orca 只负责一键打开,不复制第二套 UI。</p>
|
|
95
|
+
|
|
96
|
+
<div class="row">
|
|
97
|
+
<label for="terminal">发送到终端</label>
|
|
98
|
+
<select id="terminal"><option value="">正在读取工作区…</option></select>
|
|
99
|
+
</div>
|
|
100
|
+
|
|
101
|
+
<button id="open" disabled>打开 Memory Atlas</button>
|
|
102
|
+
<p id="status" class="status"></p>
|
|
103
|
+
|
|
104
|
+
<div class="fallback">
|
|
105
|
+
如果按钮无响应,在任意终端执行:
|
|
106
|
+
<code>dsh-memory open</code>
|
|
107
|
+
<br/>Web 地址:<code>http://127.0.0.1:7999/</code>
|
|
108
|
+
</div>
|
|
109
|
+
</div>
|
|
110
|
+
|
|
111
|
+
<script>
|
|
112
|
+
'use strict'
|
|
113
|
+
|
|
114
|
+
var seq = 0
|
|
115
|
+
var pending = new Map()
|
|
116
|
+
var statusEl = document.getElementById('status')
|
|
117
|
+
var terminalEl = document.getElementById('terminal')
|
|
118
|
+
var openBtn = document.getElementById('open')
|
|
119
|
+
|
|
120
|
+
function setStatus(text, cls) {
|
|
121
|
+
statusEl.textContent = text || ''
|
|
122
|
+
statusEl.className = 'status' + (cls ? ' ' + cls : '')
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
function call(action, params) {
|
|
126
|
+
return new Promise(function (resolve, reject) {
|
|
127
|
+
var requestId = 'req-' + (++seq)
|
|
128
|
+
pending.set(requestId, { resolve: resolve, reject: reject })
|
|
129
|
+
window.parent.postMessage({
|
|
130
|
+
type: 'orca-panel-action',
|
|
131
|
+
requestId: requestId,
|
|
132
|
+
action: action,
|
|
133
|
+
params: params || {}
|
|
134
|
+
}, '*')
|
|
135
|
+
})
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
window.addEventListener('message', function (event) {
|
|
139
|
+
var data = event.data
|
|
140
|
+
if (!data || data.type !== 'orca-panel-action-result') return
|
|
141
|
+
var entry = pending.get(data.requestId)
|
|
142
|
+
if (!entry) return
|
|
143
|
+
pending.delete(data.requestId)
|
|
144
|
+
if (data.ok) entry.resolve(data.value)
|
|
145
|
+
else entry.reject(new Error(data.error || data.errorCode || 'action failed'))
|
|
146
|
+
})
|
|
147
|
+
|
|
148
|
+
async function loadTerminals() {
|
|
149
|
+
try {
|
|
150
|
+
var ctx = await call('workspace.readContext')
|
|
151
|
+
var terminals = (ctx && ctx.terminals) || []
|
|
152
|
+
terminalEl.innerHTML = ''
|
|
153
|
+
if (!terminals.length) {
|
|
154
|
+
var opt = document.createElement('option')
|
|
155
|
+
opt.value = ''
|
|
156
|
+
opt.textContent = '请先打开一个 Orca 终端'
|
|
157
|
+
terminalEl.appendChild(opt)
|
|
158
|
+
openBtn.disabled = true
|
|
159
|
+
setStatus('需要一个终端来执行 dsh-memory open。', 'warn')
|
|
160
|
+
return
|
|
161
|
+
}
|
|
162
|
+
terminals.forEach(function (term, index) {
|
|
163
|
+
var opt = document.createElement('option')
|
|
164
|
+
opt.value = term.id
|
|
165
|
+
opt.textContent = '终端 ' + (index + 1)
|
|
166
|
+
terminalEl.appendChild(opt)
|
|
167
|
+
})
|
|
168
|
+
openBtn.disabled = false
|
|
169
|
+
setStatus('已就绪。')
|
|
170
|
+
} catch (err) {
|
|
171
|
+
setStatus('无法读取工作区终端:' + err.message, 'warn')
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
openBtn.addEventListener('click', async function () {
|
|
176
|
+
var terminalId = terminalEl.value
|
|
177
|
+
if (!terminalId) {
|
|
178
|
+
setStatus('请先选择一个终端。', 'warn')
|
|
179
|
+
return
|
|
180
|
+
}
|
|
181
|
+
openBtn.disabled = true
|
|
182
|
+
setStatus('正在拉起 Memory Atlas…')
|
|
183
|
+
try {
|
|
184
|
+
await call('terminal.sendText', {
|
|
185
|
+
terminalId: terminalId,
|
|
186
|
+
text: 'dsh-memory open',
|
|
187
|
+
enter: true
|
|
188
|
+
})
|
|
189
|
+
setStatus('已发送 dsh-memory open。浏览器/WebView 打开后即可使用。', 'ok')
|
|
190
|
+
} catch (err) {
|
|
191
|
+
setStatus('打开失败:' + err.message + '。请在终端手动执行 dsh-memory open。', 'warn')
|
|
192
|
+
} finally {
|
|
193
|
+
openBtn.disabled = false
|
|
194
|
+
}
|
|
195
|
+
})
|
|
196
|
+
|
|
197
|
+
loadTerminals()
|
|
198
|
+
</script>
|
|
199
|
+
</body>
|
|
200
|
+
</html>
|
package/package.json
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "memory-eternal",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.12.0",
|
|
4
4
|
"description": "记忆核心(Memory Eternal):自研的 DeepSeek Harness 记忆插件,不移植任何既有记忆框架——对话结束后自动沉淀知识卡到本地 Markdown Vault(自研去重、自研 CJK 检索、可 git 管理),设置页提供图形化知识库(统计 / 搜索 / 知识图谱 + 侧边栏一键弹窗),Agent 通过 memory_recall 工具按需召回历史上下文。零人工干预。",
|
|
5
|
+
"icon": "assets/icon.png",
|
|
5
6
|
"license": "MIT",
|
|
6
7
|
"repository": {
|
|
7
8
|
"type": "git",
|
|
@@ -32,6 +33,10 @@
|
|
|
32
33
|
"web",
|
|
33
34
|
"hooks",
|
|
34
35
|
"skills",
|
|
36
|
+
"assets/icon.png",
|
|
37
|
+
"orca-plugin",
|
|
38
|
+
"dsh-tui-plugin",
|
|
39
|
+
"cursor-extension",
|
|
35
40
|
".claude-plugin",
|
|
36
41
|
".codex-plugin",
|
|
37
42
|
".cursor-plugin",
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: memory-open
|
|
3
|
+
description: Open the local Memory Atlas Web UI (memory-eternal) from Codex or Claude Code. Use when the user asks to open the memory library, review queue or knowledge graph.
|
|
4
|
+
allowed-tools: Bash(dsh-memory open)
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Open Memory Atlas
|
|
8
|
+
|
|
9
|
+
Run this once, from the workspace root:
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
dsh-memory open
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
It ensures the local memory Web UI is running on `http://127.0.0.1:7999/` and opens the default browser.
|
|
16
|
+
|
|
17
|
+
Rules:
|
|
18
|
+
|
|
19
|
+
- Do not approve or reject cards from here. Review is done by the person in the Web UI.
|
|
20
|
+
- Do not write or mutate memory cards.
|
|
21
|
+
- If `dsh-memory` is not on PATH, read the repository `README.md` for the CLI install path, or ask the user to run the command manually.
|
|
22
|
+
- After opening, tell the user the review queue is available in the Web UI; keep the reply short.
|