@dshtrading/dsh-home 0.1.6
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/LICENSE +75 -0
- package/lib/index.d.ts +63 -0
- package/lib/index.js +123 -0
- package/package.json +30 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
Copyright (c) 2026 zhu1090093659 (dsh-trading)
|
|
2
|
+
|
|
3
|
+
# PolyForm Noncommercial License 1.0.0
|
|
4
|
+
|
|
5
|
+
<https://polyformproject.org/licenses/noncommercial/1.0.0>
|
|
6
|
+
|
|
7
|
+
## Acceptance
|
|
8
|
+
|
|
9
|
+
In order to get any license under these terms, you must agree to them as both strict obligations and conditions to all your licenses.
|
|
10
|
+
|
|
11
|
+
## Copyright License
|
|
12
|
+
|
|
13
|
+
The licensor grants you a copyright license for the software to do everything you might do with the software that would otherwise infringe the licensor's copyright in it for any permitted purpose. However, you may only distribute the software according to [Distribution License](#distribution-license) and make changes or new works based on the software according to [Changes and New Works License](#changes-and-new-works-license).
|
|
14
|
+
|
|
15
|
+
## Distribution License
|
|
16
|
+
|
|
17
|
+
The licensor grants you an additional copyright license to distribute copies of the software. Your license to distribute covers distributing the software with changes and new works permitted by [Changes and New Works License](#changes-and-new-works-license).
|
|
18
|
+
|
|
19
|
+
## Notices
|
|
20
|
+
|
|
21
|
+
You must ensure that anyone who gets a copy of any part of the software from you also gets a copy of these terms or the URL for them above, as well as copies of any plain-text lines beginning with `Required Notice:` that the licensor provided with the software. For example:
|
|
22
|
+
|
|
23
|
+
> Required Notice: Copyright Yoyodyne, Inc. (http://example.com)
|
|
24
|
+
|
|
25
|
+
## Changes and New Works License
|
|
26
|
+
|
|
27
|
+
The licensor grants you an additional copyright license to make changes and new works based on the software for any permitted purpose.
|
|
28
|
+
|
|
29
|
+
## Patent License
|
|
30
|
+
|
|
31
|
+
The licensor grants you a patent license for the software that covers patent claims the licensor can license, or becomes able to license, that you would infringe by using the software.
|
|
32
|
+
|
|
33
|
+
## Noncommercial Purposes
|
|
34
|
+
|
|
35
|
+
Any noncommercial purpose is a permitted purpose.
|
|
36
|
+
|
|
37
|
+
## Personal Uses
|
|
38
|
+
|
|
39
|
+
Personal use for research, experiment, and testing for the benefit of public knowledge, personal study, private entertainment, hobby projects, amateur pursuits, or religious observance, without any anticipated commercial application, is use for a permitted purpose.
|
|
40
|
+
|
|
41
|
+
## Noncommercial Organizations
|
|
42
|
+
|
|
43
|
+
Use by any charitable organization, educational institution, public research organization, public safety or health organization, environmental protection organization, or government institution is use for a permitted purpose regardless of the source of funding or obligations resulting from the funding.
|
|
44
|
+
|
|
45
|
+
## Fair Use
|
|
46
|
+
|
|
47
|
+
You may have "fair use" rights for the software under the law. These terms do not limit them.
|
|
48
|
+
|
|
49
|
+
## No Other Rights
|
|
50
|
+
|
|
51
|
+
These terms do not allow you to sublicense or transfer any of your licenses to anyone else, or prevent the licensor from granting licenses to anyone else. These terms do not imply any other licenses.
|
|
52
|
+
|
|
53
|
+
## Patent Defense
|
|
54
|
+
|
|
55
|
+
If you make any written claim that the software infringes or contributes to infringement of any patent, your patent license for the software granted under these terms ends immediately. If your company makes such a claim, your patent license ends immediately for work on behalf of your company.
|
|
56
|
+
|
|
57
|
+
## Violations
|
|
58
|
+
|
|
59
|
+
The first time you are notified in writing that you have violated any of these terms, or done anything with the software not covered by your licenses, your licenses can nonetheless continue if you come into full compliance with these terms, and take practical steps to correct past violations, within 32 days of receiving notice. Otherwise, all your licenses end immediately.
|
|
60
|
+
|
|
61
|
+
## No Liability
|
|
62
|
+
|
|
63
|
+
***As far as the law allows, the software comes as is, without any warranty or condition, and the licensor will not be liable to you for any damages arising out of these terms or the use or nature of the software, under any kind of legal claim.***
|
|
64
|
+
|
|
65
|
+
## Definitions
|
|
66
|
+
|
|
67
|
+
The **licensor** is the individual or entity offering these terms, and the **software** is the software the licensor makes available under these terms.
|
|
68
|
+
|
|
69
|
+
**You** refers to the individual or entity agreeing to these terms.
|
|
70
|
+
|
|
71
|
+
**Your company** is any legal entity, sole proprietorship, or other kind of organization that you work for, plus all organizations that have control over, are under the control of, or are under common control with that organization. **Control** means ownership of substantially all the assets of an entity, or the power to direct its management and policies by vote, contract, or otherwise. Control can be direct or indirect.
|
|
72
|
+
|
|
73
|
+
**Your licenses** are all the licenses granted to you for the software under these terms.
|
|
74
|
+
|
|
75
|
+
**Use** means anything you do with the software requiring one of your licenses.
|
package/lib/index.d.ts
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
//#region src/index.d.ts
|
|
2
|
+
/**
|
|
3
|
+
* dsh home 根目录解析,与宿主 @deepseek-ai/dsh-home-paths 同语义:
|
|
4
|
+
* 优先级 显式传入 > `$DSH_HOME`(空白视为未设,支持 `~` 展开)> `~/.dsh`,
|
|
5
|
+
* 相对路径按 CWD 解析。
|
|
6
|
+
*
|
|
7
|
+
* dsh-trading 各包的 home 数据文件(watchlists.json、knowledge/cards.json、
|
|
8
|
+
* trading-tasks/ledger 等)一律经此解析,使整套 trading 实例可以通过
|
|
9
|
+
* `DSH_HOME=~/.dsh-trading` 迁到独立 home,与 dsh web 宿主 home 彻底分开
|
|
10
|
+
* (2026-09-08 DSH_HOME 分离,note: implemented/process/2026-09-08-separate-dsh-home.md)。
|
|
11
|
+
*/
|
|
12
|
+
/**
|
|
13
|
+
* 解析 dsh home 根目录。
|
|
14
|
+
* @param env 环境变量映射,缺省读 `process.env`;空白 `$DSH_HOME` 视为未设。
|
|
15
|
+
*/
|
|
16
|
+
declare function dshHomeDir(env?: Record<string, string | undefined>): string;
|
|
17
|
+
/** 缺省 home(`~/.dsh`)——迁移判据用:解析结果等于它就没有旧 home 可迁。 */
|
|
18
|
+
declare function defaultDshHome(): string;
|
|
19
|
+
/**
|
|
20
|
+
* dsh-trading 自有数据条目(迁移白名单)。
|
|
21
|
+
*
|
|
22
|
+
* 只搬这些——`sessions/`、`storages/`、`memory/`、`task-board/`、`integrations/`
|
|
23
|
+
* 是宿主/共居资产(搬了会双实例重复收发消息或抢会话),settings/credentials 是
|
|
24
|
+
* 宿主级配置(两个 home 刻意各自演化)。见
|
|
25
|
+
* `.agents/notes/implemented/process/2026-09-08-separate-dsh-home.md`。
|
|
26
|
+
*/
|
|
27
|
+
declare const TRADING_HOME_ENTRIES: readonly ["watchlists.json", "selection.json", "watchlist-groups.json", "knowledge", "holdings", "indicators", "strategies", "trading-tasks", "trading-updater"];
|
|
28
|
+
/** 迁移标记文件名(写在目标 home;存在即不再迁移,用户删档也不会被搬回)。 */
|
|
29
|
+
declare const HOME_MIGRATION_MARKER = ".legacy-home-migrated.json";
|
|
30
|
+
interface LegacyHomeMigrationOptions {
|
|
31
|
+
/** 环境变量映射(缺省 `process.env`);解析结果等于缺省 home 时直接跳过。 */
|
|
32
|
+
env?: Record<string, string | undefined>;
|
|
33
|
+
/** 旧 home 根(缺省 `~/.dsh`)。 */
|
|
34
|
+
legacyHome?: string;
|
|
35
|
+
/** 日志回调(缺省静默)。 */
|
|
36
|
+
log?: (message: string) => void;
|
|
37
|
+
}
|
|
38
|
+
interface LegacyHomeMigrationResult {
|
|
39
|
+
from: string;
|
|
40
|
+
to: string;
|
|
41
|
+
/** 本次复制过来的条目。 */
|
|
42
|
+
copied: string[];
|
|
43
|
+
/** 旧 home 有、目标 home 已有而跳过的条目(用户已自行迁移或本就同源)。 */
|
|
44
|
+
skipped: string[];
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* 旧 home → 当前 home 的一次性数据迁移(2026-09-08 审查 H4)。
|
|
48
|
+
*
|
|
49
|
+
* 背景:桌面壳内置缺省 home 翻到 `~/.dsh-trading` 后,老用户 `~/.dsh` 下的自选/
|
|
50
|
+
* 持仓/知识库/定时任务数据不再被读取——表现是升级后「数据全空」。
|
|
51
|
+
*
|
|
52
|
+
* 语义(严格非破坏):
|
|
53
|
+
* - 解析结果等于缺省 home(`~/.dsh`)→ 不做任何事(CLI 缺省路径零影响);
|
|
54
|
+
* - 目标 home 已有标记文件 → 不再迁移(幂等;用户删除的文件不会被搬回);
|
|
55
|
+
* - 逐条目:目标已存在 → 跳过;旧 home 存在 → `cpSync` 复制(**复制不是移动**,
|
|
56
|
+
* 旧 home 原样保留,回滚即删新 home 或继续用旧 home);
|
|
57
|
+
* - 只处理 {@link TRADING_HOME_ENTRIES} 白名单,绝不触碰宿主资产。
|
|
58
|
+
*
|
|
59
|
+
* @returns 迁移结果;未触发(同源/已迁移)返回 null。
|
|
60
|
+
*/
|
|
61
|
+
declare function migrateLegacyTradingHome(options?: LegacyHomeMigrationOptions): LegacyHomeMigrationResult | null;
|
|
62
|
+
//#endregion
|
|
63
|
+
export { HOME_MIGRATION_MARKER, LegacyHomeMigrationOptions, LegacyHomeMigrationResult, TRADING_HOME_ENTRIES, defaultDshHome, dshHomeDir, migrateLegacyTradingHome };
|
package/lib/index.js
ADDED
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
import { cpSync, existsSync, mkdirSync, writeFileSync } from "node:fs";
|
|
2
|
+
import { homedir } from "node:os";
|
|
3
|
+
import { join, resolve } from "node:path";
|
|
4
|
+
//#region src/index.ts
|
|
5
|
+
/**
|
|
6
|
+
* dsh home 根目录解析,与宿主 @deepseek-ai/dsh-home-paths 同语义:
|
|
7
|
+
* 优先级 显式传入 > `$DSH_HOME`(空白视为未设,支持 `~` 展开)> `~/.dsh`,
|
|
8
|
+
* 相对路径按 CWD 解析。
|
|
9
|
+
*
|
|
10
|
+
* dsh-trading 各包的 home 数据文件(watchlists.json、knowledge/cards.json、
|
|
11
|
+
* trading-tasks/ledger 等)一律经此解析,使整套 trading 实例可以通过
|
|
12
|
+
* `DSH_HOME=~/.dsh-trading` 迁到独立 home,与 dsh web 宿主 home 彻底分开
|
|
13
|
+
* (2026-09-08 DSH_HOME 分离,note: implemented/process/2026-09-08-separate-dsh-home.md)。
|
|
14
|
+
*/
|
|
15
|
+
const DEFAULT_HOME_DIR_NAME = ".dsh";
|
|
16
|
+
/** 展开 `~` 与 `~/` 前缀(对齐宿主 expandHomePath;Windows 反斜杠前缀同样接受)。 */
|
|
17
|
+
function expandHomePath(path) {
|
|
18
|
+
const home = homedir();
|
|
19
|
+
if (path === "~") return home;
|
|
20
|
+
if (path.startsWith("~/") || path.startsWith("~\\")) return resolve(home, path.slice(2));
|
|
21
|
+
return path;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* 解析 dsh home 根目录。
|
|
25
|
+
* @param env 环境变量映射,缺省读 `process.env`;空白 `$DSH_HOME` 视为未设。
|
|
26
|
+
*/
|
|
27
|
+
function dshHomeDir(env = process.env) {
|
|
28
|
+
const fromEnv = env.DSH_HOME;
|
|
29
|
+
const configured = fromEnv !== void 0 && fromEnv.trim().length > 0 ? fromEnv : resolve(homedir(), DEFAULT_HOME_DIR_NAME);
|
|
30
|
+
return resolve(expandHomePath(configured));
|
|
31
|
+
}
|
|
32
|
+
/** 缺省 home(`~/.dsh`)——迁移判据用:解析结果等于它就没有旧 home 可迁。 */
|
|
33
|
+
function defaultDshHome() {
|
|
34
|
+
return resolve(homedir(), DEFAULT_HOME_DIR_NAME);
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* dsh-trading 自有数据条目(迁移白名单)。
|
|
38
|
+
*
|
|
39
|
+
* 只搬这些——`sessions/`、`storages/`、`memory/`、`task-board/`、`integrations/`
|
|
40
|
+
* 是宿主/共居资产(搬了会双实例重复收发消息或抢会话),settings/credentials 是
|
|
41
|
+
* 宿主级配置(两个 home 刻意各自演化)。见
|
|
42
|
+
* `.agents/notes/implemented/process/2026-09-08-separate-dsh-home.md`。
|
|
43
|
+
*/
|
|
44
|
+
const TRADING_HOME_ENTRIES = [
|
|
45
|
+
"watchlists.json",
|
|
46
|
+
"selection.json",
|
|
47
|
+
"watchlist-groups.json",
|
|
48
|
+
"knowledge",
|
|
49
|
+
"holdings",
|
|
50
|
+
"indicators",
|
|
51
|
+
"strategies",
|
|
52
|
+
"trading-tasks",
|
|
53
|
+
"trading-updater"
|
|
54
|
+
];
|
|
55
|
+
/** 迁移标记文件名(写在目标 home;存在即不再迁移,用户删档也不会被搬回)。 */
|
|
56
|
+
const HOME_MIGRATION_MARKER = ".legacy-home-migrated.json";
|
|
57
|
+
/**
|
|
58
|
+
* 旧 home → 当前 home 的一次性数据迁移(2026-09-08 审查 H4)。
|
|
59
|
+
*
|
|
60
|
+
* 背景:桌面壳内置缺省 home 翻到 `~/.dsh-trading` 后,老用户 `~/.dsh` 下的自选/
|
|
61
|
+
* 持仓/知识库/定时任务数据不再被读取——表现是升级后「数据全空」。
|
|
62
|
+
*
|
|
63
|
+
* 语义(严格非破坏):
|
|
64
|
+
* - 解析结果等于缺省 home(`~/.dsh`)→ 不做任何事(CLI 缺省路径零影响);
|
|
65
|
+
* - 目标 home 已有标记文件 → 不再迁移(幂等;用户删除的文件不会被搬回);
|
|
66
|
+
* - 逐条目:目标已存在 → 跳过;旧 home 存在 → `cpSync` 复制(**复制不是移动**,
|
|
67
|
+
* 旧 home 原样保留,回滚即删新 home 或继续用旧 home);
|
|
68
|
+
* - 只处理 {@link TRADING_HOME_ENTRIES} 白名单,绝不触碰宿主资产。
|
|
69
|
+
*
|
|
70
|
+
* @returns 迁移结果;未触发(同源/已迁移)返回 null。
|
|
71
|
+
*/
|
|
72
|
+
function migrateLegacyTradingHome(options = {}) {
|
|
73
|
+
const log = options.log ?? (() => {});
|
|
74
|
+
const to = dshHomeDir(options.env ?? process.env);
|
|
75
|
+
const from = resolve(expandHomePath(options.legacyHome ?? join(homedir(), DEFAULT_HOME_DIR_NAME)));
|
|
76
|
+
if (from === to) return null;
|
|
77
|
+
const marker = join(to, HOME_MIGRATION_MARKER);
|
|
78
|
+
if (existsSync(marker)) return null;
|
|
79
|
+
const copied = [];
|
|
80
|
+
const skipped = [];
|
|
81
|
+
for (const entry of TRADING_HOME_ENTRIES) {
|
|
82
|
+
const source = join(from, entry);
|
|
83
|
+
const target = join(to, entry);
|
|
84
|
+
if (!existsSync(source)) continue;
|
|
85
|
+
if (existsSync(target)) {
|
|
86
|
+
skipped.push(entry);
|
|
87
|
+
continue;
|
|
88
|
+
}
|
|
89
|
+
try {
|
|
90
|
+
mkdirSync(to, { recursive: true });
|
|
91
|
+
cpSync(source, target, {
|
|
92
|
+
recursive: true,
|
|
93
|
+
force: false,
|
|
94
|
+
errorOnExist: false,
|
|
95
|
+
preserveTimestamps: true
|
|
96
|
+
});
|
|
97
|
+
copied.push(entry);
|
|
98
|
+
} catch (error) {
|
|
99
|
+
log(`[dsh-home] legacy home migration failed for ${entry}: ${error instanceof Error ? error.message : String(error)}`);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
try {
|
|
103
|
+
mkdirSync(to, { recursive: true });
|
|
104
|
+
writeFileSync(marker, `${JSON.stringify({
|
|
105
|
+
from,
|
|
106
|
+
to,
|
|
107
|
+
copied,
|
|
108
|
+
skipped,
|
|
109
|
+
at: (/* @__PURE__ */ new Date()).toISOString()
|
|
110
|
+
}, null, 2)}\n`, "utf8");
|
|
111
|
+
} catch (error) {
|
|
112
|
+
log(`[dsh-home] could not write migration marker ${marker}: ${error instanceof Error ? error.message : String(error)}`);
|
|
113
|
+
}
|
|
114
|
+
if (copied.length > 0) log(`[dsh-home] migrated legacy trading data from ${from} to ${to}: ${copied.join(", ")} (originals kept)`);
|
|
115
|
+
return {
|
|
116
|
+
from,
|
|
117
|
+
to,
|
|
118
|
+
copied,
|
|
119
|
+
skipped
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
//#endregion
|
|
123
|
+
export { HOME_MIGRATION_MARKER, TRADING_HOME_ENTRIES, defaultDshHome, dshHomeDir, migrateLegacyTradingHome };
|
package/package.json
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@dshtrading/dsh-home",
|
|
3
|
+
"description": "dsh home 根目录解析($DSH_HOME 环境变量感知,缺省 ~/.dsh,对齐宿主 dsh-home-paths 语义)——dsh-trading 各包 home 数据文件的唯一路径来源",
|
|
4
|
+
"version": "0.1.6",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "lib/index.js",
|
|
7
|
+
"types": "./lib/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"types": "./lib/index.d.ts",
|
|
11
|
+
"default": "./lib/index.js"
|
|
12
|
+
},
|
|
13
|
+
"./package.json": "./package.json"
|
|
14
|
+
},
|
|
15
|
+
"files": [
|
|
16
|
+
"lib"
|
|
17
|
+
],
|
|
18
|
+
"license": "PolyForm-Noncommercial-1.0.0",
|
|
19
|
+
"dependencies": {},
|
|
20
|
+
"devDependencies": {
|
|
21
|
+
"@types/node": "^24.0.0",
|
|
22
|
+
"tsdown": "^0.22.0",
|
|
23
|
+
"typescript": "^5.9.3",
|
|
24
|
+
"vitest": "^3.0.0"
|
|
25
|
+
},
|
|
26
|
+
"scripts": {
|
|
27
|
+
"build": "tsdown",
|
|
28
|
+
"test": "vitest run"
|
|
29
|
+
}
|
|
30
|
+
}
|