dsh-horon 1.0.0 → 1.0.1
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 +2 -2
- package/artifact.js +20 -9
- package/index.js +2 -0
- package/package.json +8 -3
package/README.md
CHANGED
|
@@ -153,8 +153,8 @@ node test/host-smoke.mjs && node test/artifact-smoke.mjs # 只跑纯函数
|
|
|
153
153
|
| `hooks` | `true` | `false` 只留 `horon` 工具,不挂钩子(也可用环境变量 `HORON_HOOKS=off`) |
|
|
154
154
|
| `skills` | `spawn` / `artifact` 模式外默认开 | 是否注册三个 horon skill |
|
|
155
155
|
| `dataDir` | `~/.horon/docker` | `artifact` 与 `docker` 共用的宿主数据目录(库、`.env`、tag 插件) |
|
|
156
|
-
| `dbFile` | `<dataDir>/data/horon.db` | SQLite 库;`docker`
|
|
157
|
-
| `envFile` | `<dataDir>/.env` | API key / 代理;`docker` 模式缺失时从 `docker/env.example` 复制,`artifact` 模式作为 `app/.env`
|
|
156
|
+
| `dbFile` | `<dataDir>/data/horon.db` | SQLite 库;`docker` 模式挂到容器 `/data`,`artifact` 模式写进 `app/.env` 的 `HORON_DB`。从 docker 切过来时**显式写这一行**,否则会指向另一个库 |
|
|
157
|
+
| `envFile` | `<dataDir>/.env` | API key / 代理;`docker` 模式缺失时从 `docker/env.example` 复制,`artifact` 模式作为 `app/.env` 的种子(`HORON_DB` 由 `dbFile` 覆盖) |
|
|
158
158
|
| `tagPluginsDir` | `<dataDir>/tag_plugins` | tag 插件目录(`docker` 模式挂到 `/app/backend/tag_plugins`) |
|
|
159
159
|
| `dockerBind` / `dockerPort` | `127.0.0.1` / `8710` | 容器发布地址 |
|
|
160
160
|
| `image` / `container` | `<horon.lock.json image>` / `horon` | 镜像与容器名 |
|
package/artifact.js
CHANGED
|
@@ -89,6 +89,14 @@ export function artifactSettings(config) {
|
|
|
89
89
|
basePython: text(c.python) ?? (process.platform === 'win32' ? 'python' : 'python3'),
|
|
90
90
|
// Shared with docker mode on purpose: switching modes keeps the database, .env and tag plugins.
|
|
91
91
|
dataDir: path.resolve(expandHome(text(c.dataDir) ?? path.join(os.homedir(), '.horon', 'docker'))),
|
|
92
|
+
// An explicit dbFile / envFile wins, so a user who ran docker mode keeps the very same memory
|
|
93
|
+
// file and API keys after switching. "My notes are gone" must not be the first report.
|
|
94
|
+
dbFile: text(c.dbFile)
|
|
95
|
+
? path.resolve(expandHome(text(c.dbFile)))
|
|
96
|
+
: path.join(path.resolve(expandHome(text(c.dataDir) ?? path.join(os.homedir(), '.horon', 'docker'))), 'data', 'horon.db'),
|
|
97
|
+
envFile: text(c.envFile)
|
|
98
|
+
? path.resolve(expandHome(text(c.envFile)))
|
|
99
|
+
: path.join(path.resolve(expandHome(text(c.dataDir) ?? path.join(os.homedir(), '.horon', 'docker'))), '.env'),
|
|
92
100
|
lock,
|
|
93
101
|
}
|
|
94
102
|
}
|
|
@@ -221,19 +229,20 @@ async function extract(archive, destination, log) {
|
|
|
221
229
|
}
|
|
222
230
|
|
|
223
231
|
// The service reads ROOT/.env and needs HORON_DB there. The file lives inside the version
|
|
224
|
-
// directory, but every path in it points at the shared
|
|
232
|
+
// directory, but every path in it points outside, at the shared database and key file, so it
|
|
233
|
+
// survives an upgrade. It is rewritten on every start of this code path, so editing dbFile or
|
|
234
|
+
// envFile in the profile takes effect instead of being silently ignored.
|
|
225
235
|
async function writeEnv(a, log) {
|
|
226
236
|
const file = path.join(a.appDir, '.env')
|
|
227
|
-
if (existsSync(file)) return
|
|
228
|
-
const shared = path.join(a.dataDir, '.env')
|
|
229
237
|
let body = ''
|
|
230
|
-
if (existsSync(
|
|
231
|
-
body = await fs.readFile(
|
|
232
|
-
log(`seeded app/.env from ${
|
|
238
|
+
if (existsSync(a.envFile)) {
|
|
239
|
+
body = await fs.readFile(a.envFile, 'utf8')
|
|
240
|
+
log(`seeded app/.env from ${a.envFile}`)
|
|
233
241
|
}
|
|
234
|
-
const
|
|
235
|
-
|
|
236
|
-
|
|
242
|
+
const lines = body.split(/\r?\n/).filter((line) => !/^\s*HORON_DB\s*=/.test(line))
|
|
243
|
+
while (lines.length > 0 && lines[lines.length - 1].trim() === '') lines.pop()
|
|
244
|
+
lines.push(`HORON_DB=${a.dbFile}`)
|
|
245
|
+
await fs.writeFile(file, `${lines.join('\n')}\n`, 'utf8')
|
|
237
246
|
}
|
|
238
247
|
|
|
239
248
|
/**
|
|
@@ -248,6 +257,8 @@ export async function provisionArtifact(a, log = () => {}) {
|
|
|
248
257
|
const python = venvPython(a.appDir)
|
|
249
258
|
if (existsSync(marker) && existsSync(python)) {
|
|
250
259
|
log(`artifact already installed at ${a.root}`)
|
|
260
|
+
// Still reconcile app/.env: the config may name a different database since the last start.
|
|
261
|
+
await writeEnv(a, log)
|
|
251
262
|
return { root: a.appDir, python }
|
|
252
263
|
}
|
|
253
264
|
|
package/index.js
CHANGED
|
@@ -442,6 +442,8 @@ function describeArtifact(a) {
|
|
|
442
442
|
url: a.url,
|
|
443
443
|
sha256: a.sha256 || undefined,
|
|
444
444
|
dataDir: a.dataDir,
|
|
445
|
+
dbFile: a.dbFile,
|
|
446
|
+
envFile: a.envFile,
|
|
445
447
|
pinned: a.lock?.horon?.commit,
|
|
446
448
|
image: a.lock?.image ? `${a.lock.image.name}:${a.lock.image.tag}` : undefined,
|
|
447
449
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-horon",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.1",
|
|
4
4
|
"description": "Horon memory graph as a DeepSeek Harness plugin: the horon tool, lifecycle hooks, the console panel and a one-click service runtime (released artifact or Docker image)",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -40,11 +40,16 @@
|
|
|
40
40
|
"assemble": "node scripts/assemble.mjs"
|
|
41
41
|
},
|
|
42
42
|
"dsh": {
|
|
43
|
-
"bundle": {
|
|
43
|
+
"bundle": {
|
|
44
|
+
"patch": "./cordis.patch.yml"
|
|
45
|
+
},
|
|
44
46
|
"client": {
|
|
45
47
|
"platform": "web",
|
|
46
48
|
"immediately": true,
|
|
47
|
-
"inject": [
|
|
49
|
+
"inject": [
|
|
50
|
+
"@deepseek-ai/dsh-client-locale",
|
|
51
|
+
"@deepseek-ai/dsh-client-ui-settings"
|
|
52
|
+
]
|
|
48
53
|
}
|
|
49
54
|
}
|
|
50
55
|
}
|