dsh-github-flow 0.1.6 → 0.1.8
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.en.md +200 -67
- package/README.md +199 -65
- package/docs/architecture.md +66 -15
- package/docs/images/1.png +0 -0
- package/docs/images/2.png +0 -0
- package/docs/images/3.png +0 -0
- package/lib/api/routes.d.ts +3 -1
- package/lib/api/routes.js +208 -13
- package/lib/client/panel.js +28 -1
- package/lib/client.js +1002 -43
- package/lib/commands/gh.d.ts +2 -1
- package/lib/commands/gh.js +40 -3
- package/lib/executor.d.ts +6 -5
- package/lib/executor.js +42 -15
- package/lib/main.d.ts +11 -0
- package/lib/main.js +41 -3
- package/lib/tools/api.js +2 -1
- package/lib/tools/issue.js +13 -8
- package/lib/tools/pr.js +14 -9
- package/lib/tools/repo.js +6 -4
- package/lib/tools/run.js +12 -7
- package/lib/types.d.ts +87 -9
- package/lib/updater.d.ts +41 -0
- package/lib/updater.js +160 -0
- package/lib/upgrade-manager.d.ts +54 -0
- package/lib/upgrade-manager.js +299 -0
- package/lib/version.d.ts +13 -0
- package/lib/version.js +13 -0
- package/lib/workspace.d.ts +6 -3
- package/lib/workspace.js +24 -9
- package/package.json +1 -1
package/lib/types.d.ts
CHANGED
|
@@ -14,10 +14,18 @@ export interface PluginConfig {
|
|
|
14
14
|
cacheTtlMs?: number;
|
|
15
15
|
/** 查询列表默认限制条数,默认 20 */
|
|
16
16
|
defaultListLimit?: number;
|
|
17
|
+
/** 是否开启新版本自动检查提示,默认 true */
|
|
18
|
+
checkUpdate?: boolean;
|
|
19
|
+
/** 检查更新间隔毫秒数,默认 86,400,000 (24小时) */
|
|
20
|
+
updateCheckIntervalMs?: number;
|
|
21
|
+
/** 自定义 npm Registry 镜像地址,留空则自动选用 npmmirror 与 npmjs */
|
|
22
|
+
registryUrl?: string;
|
|
17
23
|
}
|
|
18
24
|
export interface GhExecutionOptions {
|
|
19
25
|
/** 命令执行的工作目录,优先使用当前 Agent 会话所在的 Workspace 物理路径 */
|
|
20
26
|
cwd?: string;
|
|
27
|
+
/** 当前调用的会话 ID,用于精确关联物理工作区路径 */
|
|
28
|
+
sessionId?: string;
|
|
21
29
|
/** 进程超时限制(毫秒),默认 30,000ms */
|
|
22
30
|
timeoutMs?: number;
|
|
23
31
|
/** 附加环境变量 */
|
|
@@ -86,6 +94,19 @@ export interface PrItem {
|
|
|
86
94
|
url: string;
|
|
87
95
|
updatedAt: string;
|
|
88
96
|
}
|
|
97
|
+
/**
|
|
98
|
+
* Issue 分类维度契约:
|
|
99
|
+
* - reported: 用户提起的(他人向我名下项目或本仓库提交的 Issue 反馈)
|
|
100
|
+
* - assigned: 分配给我的(指派给当前账号的待办任务,跨仓库通用)
|
|
101
|
+
* - created: 我创建的(由当前账号亲自发起的 Issue)
|
|
102
|
+
*/
|
|
103
|
+
export type IssueCategory = 'reported' | 'assigned' | 'created';
|
|
104
|
+
export interface IssueStats {
|
|
105
|
+
total: number;
|
|
106
|
+
reported: number;
|
|
107
|
+
assigned: number;
|
|
108
|
+
created: number;
|
|
109
|
+
}
|
|
89
110
|
export interface IssueItem {
|
|
90
111
|
number: number;
|
|
91
112
|
title: string;
|
|
@@ -102,6 +123,8 @@ export interface IssueItem {
|
|
|
102
123
|
}>;
|
|
103
124
|
url: string;
|
|
104
125
|
updatedAt: string;
|
|
126
|
+
/** 命中的所有身份分类 */
|
|
127
|
+
categories?: IssueCategory[];
|
|
105
128
|
}
|
|
106
129
|
export interface WorkflowRunItem {
|
|
107
130
|
databaseId: number;
|
|
@@ -118,9 +141,12 @@ export interface GitHubOverviewData {
|
|
|
118
141
|
repo?: RepoMetadata;
|
|
119
142
|
pullRequests: PrItem[];
|
|
120
143
|
issues: IssueItem[];
|
|
144
|
+
issueStats?: IssueStats;
|
|
121
145
|
runs: WorkflowRunItem[];
|
|
122
146
|
lastUpdated: string;
|
|
123
147
|
error?: string;
|
|
148
|
+
/** 插件版本与升级信息(由内存缓存快速读取,不阻塞首屏业务) */
|
|
149
|
+
updateInfo?: UpdateInfo;
|
|
124
150
|
}
|
|
125
151
|
export interface UserRepoItem {
|
|
126
152
|
name: string;
|
|
@@ -140,6 +166,28 @@ export interface WorkspaceMatrixItem {
|
|
|
140
166
|
repo?: RepoMetadata;
|
|
141
167
|
sessionCount: number;
|
|
142
168
|
}
|
|
169
|
+
export interface GlobalIssueItem {
|
|
170
|
+
number: number;
|
|
171
|
+
title: string;
|
|
172
|
+
repository: {
|
|
173
|
+
name?: string;
|
|
174
|
+
nameWithOwner: string;
|
|
175
|
+
};
|
|
176
|
+
author?: {
|
|
177
|
+
login: string;
|
|
178
|
+
};
|
|
179
|
+
assignees?: Array<{
|
|
180
|
+
login: string;
|
|
181
|
+
}>;
|
|
182
|
+
labels?: Array<{
|
|
183
|
+
name: string;
|
|
184
|
+
color: string;
|
|
185
|
+
}>;
|
|
186
|
+
url: string;
|
|
187
|
+
updatedAt: string;
|
|
188
|
+
state?: 'OPEN' | 'CLOSED';
|
|
189
|
+
categories: IssueCategory[];
|
|
190
|
+
}
|
|
143
191
|
export interface GlobalOverviewData {
|
|
144
192
|
auth: AuthStatus;
|
|
145
193
|
userRepos: UserRepoItem[];
|
|
@@ -153,17 +201,47 @@ export interface GlobalOverviewData {
|
|
|
153
201
|
url: string;
|
|
154
202
|
updatedAt: string;
|
|
155
203
|
}>;
|
|
156
|
-
myIssues:
|
|
157
|
-
|
|
158
|
-
title: string;
|
|
159
|
-
repository: {
|
|
160
|
-
nameWithOwner: string;
|
|
161
|
-
};
|
|
162
|
-
url: string;
|
|
163
|
-
updatedAt: string;
|
|
164
|
-
}>;
|
|
204
|
+
myIssues: GlobalIssueItem[];
|
|
205
|
+
issueStats?: IssueStats;
|
|
165
206
|
lastUpdated: string;
|
|
166
207
|
error?: string;
|
|
167
208
|
/** 工作区矩阵读取失败的原因。区分「没有工作区」与「读不到工作区」,避免把故障显示成空状态 */
|
|
168
209
|
workspaceError?: string;
|
|
210
|
+
/** 插件版本与升级信息(由内存缓存快速读取,不阻塞首屏业务) */
|
|
211
|
+
updateInfo?: UpdateInfo;
|
|
212
|
+
}
|
|
213
|
+
/**
|
|
214
|
+
* 插件版本检查信息
|
|
215
|
+
*/
|
|
216
|
+
export interface UpdateInfo {
|
|
217
|
+
currentVersion: string;
|
|
218
|
+
latestVersion?: string;
|
|
219
|
+
hasUpdate: boolean;
|
|
220
|
+
upgradeCommand: string;
|
|
221
|
+
allCommands: {
|
|
222
|
+
dshCli: string;
|
|
223
|
+
profile: string;
|
|
224
|
+
pnpm: string;
|
|
225
|
+
npm: string;
|
|
226
|
+
};
|
|
227
|
+
releaseNotesUrl: string;
|
|
228
|
+
checkedAt: number;
|
|
229
|
+
}
|
|
230
|
+
export type UpgradeState = 'idle' | 'upgrading' | 'success' | 'failed';
|
|
231
|
+
export interface UpgradeStatusResult {
|
|
232
|
+
state: UpgradeState;
|
|
233
|
+
targetVersion?: string;
|
|
234
|
+
message?: string;
|
|
235
|
+
log?: string;
|
|
236
|
+
startedAt?: number;
|
|
237
|
+
completedAt?: number;
|
|
238
|
+
/** 识别到的宿主环境类型:desktop 为桌面版,web 为网页/CLI版 */
|
|
239
|
+
environment?: 'desktop' | 'web';
|
|
240
|
+
}
|
|
241
|
+
export interface UpgradeExecutionResult {
|
|
242
|
+
ok: boolean;
|
|
243
|
+
message: string;
|
|
244
|
+
needRestart: boolean;
|
|
245
|
+
log?: string;
|
|
246
|
+
environment?: 'desktop' | 'web';
|
|
169
247
|
}
|
package/lib/updater.d.ts
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import type { UpdateInfo } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* 极简语义化版本大小比较函数 (latest > current 时返回 true)
|
|
4
|
+
*
|
|
5
|
+
* 为什么自研而不引入 semver npm 依赖:
|
|
6
|
+
* 避免为了简单的 x.y.z 比对而引入数十个传递子依赖,保持 DSH 插件轻量纯净与零运行期依赖负担。
|
|
7
|
+
* 约束条件:标准处理 x.y.z 形式,自动过滤前导 'v' 或 '^' 等非数字字符,忽略 pre-release 标签后续对比。
|
|
8
|
+
*/
|
|
9
|
+
export declare function isNewerVersion(current: string, latest: string): boolean;
|
|
10
|
+
/**
|
|
11
|
+
* 插件版本检测引擎
|
|
12
|
+
*
|
|
13
|
+
* 架构约束与为什么这样设计:
|
|
14
|
+
* 1. 业务解耦:getQuickStatus 同步读取内存缓存,耗时 0ms,供主业务路由无感调用;
|
|
15
|
+
* 2. 闲时触发:check() 异步外网探测,首选淘宝镜像加速 (npmmirror.com),官方 npmjs 兜底;
|
|
16
|
+
* 3. 避免击穿:通过 inFlightPromise 合并并发调用,防止多处同时触发重复请求;
|
|
17
|
+
* 4. 彻底容灾:任何网络或解析异常 100% 内部吸收,返回 hasUpdate: false,绝不影响主流程。
|
|
18
|
+
*/
|
|
19
|
+
export declare class UpdateChecker {
|
|
20
|
+
private cachedInfo;
|
|
21
|
+
private inFlightPromise;
|
|
22
|
+
private readonly intervalMs;
|
|
23
|
+
private readonly customRegistry?;
|
|
24
|
+
constructor(options?: {
|
|
25
|
+
intervalMs?: number;
|
|
26
|
+
customRegistry?: string;
|
|
27
|
+
});
|
|
28
|
+
/**
|
|
29
|
+
* 同步获取当前已知的版本状态(0ms 纯内存读取,绝不发外网请求)
|
|
30
|
+
*/
|
|
31
|
+
getQuickStatus(): UpdateInfo;
|
|
32
|
+
/**
|
|
33
|
+
* 异步触发版本检测
|
|
34
|
+
* @param force 是否忽略 24h 缓存强制穿透探测
|
|
35
|
+
*/
|
|
36
|
+
check(force?: boolean): Promise<UpdateInfo>;
|
|
37
|
+
/**
|
|
38
|
+
* 内部双 Registry 竞速/降级探测
|
|
39
|
+
*/
|
|
40
|
+
private performCheck;
|
|
41
|
+
}
|
package/lib/updater.js
ADDED
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
import { CURRENT_PLUGIN_VERSION, PLUGIN_PACKAGE_NAME, NPM_PACKAGE_URL, NPM_REGISTRY_MIRROR, NPM_REGISTRY_OFFICIAL, } from './version.js';
|
|
2
|
+
/**
|
|
3
|
+
* 极简语义化版本大小比较函数 (latest > current 时返回 true)
|
|
4
|
+
*
|
|
5
|
+
* 为什么自研而不引入 semver npm 依赖:
|
|
6
|
+
* 避免为了简单的 x.y.z 比对而引入数十个传递子依赖,保持 DSH 插件轻量纯净与零运行期依赖负担。
|
|
7
|
+
* 约束条件:标准处理 x.y.z 形式,自动过滤前导 'v' 或 '^' 等非数字字符,忽略 pre-release 标签后续对比。
|
|
8
|
+
*/
|
|
9
|
+
export function isNewerVersion(current, latest) {
|
|
10
|
+
if (!current || !latest)
|
|
11
|
+
return false;
|
|
12
|
+
const parseParts = (v) => {
|
|
13
|
+
return v
|
|
14
|
+
.replace(/^[^\d]*/, '')
|
|
15
|
+
.split('-')[0]
|
|
16
|
+
.split('.')
|
|
17
|
+
.map((part) => parseInt(part, 10) || 0);
|
|
18
|
+
};
|
|
19
|
+
const cParts = parseParts(current);
|
|
20
|
+
const lParts = parseParts(latest);
|
|
21
|
+
const len = Math.max(cParts.length, lParts.length, 3);
|
|
22
|
+
for (let i = 0; i < len; i++) {
|
|
23
|
+
const c = cParts[i] ?? 0;
|
|
24
|
+
const l = lParts[i] ?? 0;
|
|
25
|
+
if (l > c)
|
|
26
|
+
return true;
|
|
27
|
+
if (l < c)
|
|
28
|
+
return false;
|
|
29
|
+
}
|
|
30
|
+
return false;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* 插件版本检测引擎
|
|
34
|
+
*
|
|
35
|
+
* 架构约束与为什么这样设计:
|
|
36
|
+
* 1. 业务解耦:getQuickStatus 同步读取内存缓存,耗时 0ms,供主业务路由无感调用;
|
|
37
|
+
* 2. 闲时触发:check() 异步外网探测,首选淘宝镜像加速 (npmmirror.com),官方 npmjs 兜底;
|
|
38
|
+
* 3. 避免击穿:通过 inFlightPromise 合并并发调用,防止多处同时触发重复请求;
|
|
39
|
+
* 4. 彻底容灾:任何网络或解析异常 100% 内部吸收,返回 hasUpdate: false,绝不影响主流程。
|
|
40
|
+
*/
|
|
41
|
+
export class UpdateChecker {
|
|
42
|
+
cachedInfo = null;
|
|
43
|
+
inFlightPromise = null;
|
|
44
|
+
intervalMs;
|
|
45
|
+
customRegistry;
|
|
46
|
+
constructor(options = {}) {
|
|
47
|
+
// 默认缓存 24 小时,杜绝高频击穿 npm
|
|
48
|
+
this.intervalMs = typeof options.intervalMs === 'number' && options.intervalMs > 0
|
|
49
|
+
? options.intervalMs
|
|
50
|
+
: 86_400_000;
|
|
51
|
+
this.customRegistry = options.customRegistry;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* 同步获取当前已知的版本状态(0ms 纯内存读取,绝不发外网请求)
|
|
55
|
+
*/
|
|
56
|
+
getQuickStatus() {
|
|
57
|
+
if (this.cachedInfo) {
|
|
58
|
+
return this.cachedInfo;
|
|
59
|
+
}
|
|
60
|
+
return {
|
|
61
|
+
currentVersion: CURRENT_PLUGIN_VERSION,
|
|
62
|
+
hasUpdate: false,
|
|
63
|
+
upgradeCommand: `pnpm dsh plugin update ${PLUGIN_PACKAGE_NAME}`,
|
|
64
|
+
allCommands: {
|
|
65
|
+
dshCli: `pnpm dsh plugin update ${PLUGIN_PACKAGE_NAME}`,
|
|
66
|
+
profile: `dsh plugin --profile default add ${PLUGIN_PACKAGE_NAME}@latest`,
|
|
67
|
+
pnpm: `pnpm add ${PLUGIN_PACKAGE_NAME}@latest`,
|
|
68
|
+
npm: `npm install -g ${PLUGIN_PACKAGE_NAME}@latest`,
|
|
69
|
+
},
|
|
70
|
+
releaseNotesUrl: `${NPM_PACKAGE_URL}?activeTab=versions`,
|
|
71
|
+
checkedAt: 0,
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* 异步触发版本检测
|
|
76
|
+
* @param force 是否忽略 24h 缓存强制穿透探测
|
|
77
|
+
*/
|
|
78
|
+
async check(force = false) {
|
|
79
|
+
const now = Date.now();
|
|
80
|
+
// 1. 命中有效缓存直接返回
|
|
81
|
+
if (!force && this.cachedInfo && now - this.cachedInfo.checkedAt < this.intervalMs) {
|
|
82
|
+
return this.cachedInfo;
|
|
83
|
+
}
|
|
84
|
+
// 2. 复用正在途中的网络请求,避免并发重复打 npm
|
|
85
|
+
if (this.inFlightPromise) {
|
|
86
|
+
return this.inFlightPromise;
|
|
87
|
+
}
|
|
88
|
+
this.inFlightPromise = this.performCheck(now).finally(() => {
|
|
89
|
+
this.inFlightPromise = null;
|
|
90
|
+
});
|
|
91
|
+
return this.inFlightPromise;
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* 内部双 Registry 竞速/降级探测
|
|
95
|
+
*/
|
|
96
|
+
async performCheck(now) {
|
|
97
|
+
const fallback = this.getQuickStatus();
|
|
98
|
+
// 双通道策略:用户自定义源 > 国内淘宝镜像 (2.5s极速) > 官方 npmjs 源 (3.5s兜底)
|
|
99
|
+
const endpoints = [];
|
|
100
|
+
if (this.customRegistry) {
|
|
101
|
+
endpoints.push(`${this.customRegistry.replace(/\/$/, '')}/${PLUGIN_PACKAGE_NAME}/latest`);
|
|
102
|
+
}
|
|
103
|
+
else {
|
|
104
|
+
endpoints.push(`${NPM_REGISTRY_MIRROR}/${PLUGIN_PACKAGE_NAME}/latest`);
|
|
105
|
+
endpoints.push(`${NPM_REGISTRY_OFFICIAL}/${PLUGIN_PACKAGE_NAME}/latest`);
|
|
106
|
+
}
|
|
107
|
+
let latestVersion = null;
|
|
108
|
+
for (const url of endpoints) {
|
|
109
|
+
try {
|
|
110
|
+
const isMirror = url.includes('npmmirror');
|
|
111
|
+
const timeoutMs = isMirror ? 2_500 : 3_500;
|
|
112
|
+
const controller = new AbortController();
|
|
113
|
+
const timer = setTimeout(() => controller.abort(), timeoutMs);
|
|
114
|
+
const res = await fetch(url, {
|
|
115
|
+
signal: controller.signal,
|
|
116
|
+
headers: {
|
|
117
|
+
'Accept': 'application/json',
|
|
118
|
+
'User-Agent': `dsh-plugin-updater/${CURRENT_PLUGIN_VERSION}`,
|
|
119
|
+
},
|
|
120
|
+
});
|
|
121
|
+
clearTimeout(timer);
|
|
122
|
+
if (res.ok) {
|
|
123
|
+
const json = (await res.json());
|
|
124
|
+
if (json && typeof json.version === 'string' && json.version.trim()) {
|
|
125
|
+
latestVersion = json.version.trim();
|
|
126
|
+
break;
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
catch {
|
|
131
|
+
// 单个源故障静默尝试下一个备用源,确保高可用
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
// 若双源均未拉取到版本,保留保底数据并记录时间戳,防止密集重试
|
|
135
|
+
if (!latestVersion) {
|
|
136
|
+
this.cachedInfo = {
|
|
137
|
+
...fallback,
|
|
138
|
+
checkedAt: now,
|
|
139
|
+
};
|
|
140
|
+
return this.cachedInfo;
|
|
141
|
+
}
|
|
142
|
+
const hasUpdate = isNewerVersion(CURRENT_PLUGIN_VERSION, latestVersion);
|
|
143
|
+
const targetPkg = `${PLUGIN_PACKAGE_NAME}@${latestVersion}`;
|
|
144
|
+
this.cachedInfo = {
|
|
145
|
+
currentVersion: CURRENT_PLUGIN_VERSION,
|
|
146
|
+
latestVersion,
|
|
147
|
+
hasUpdate,
|
|
148
|
+
upgradeCommand: `pnpm dsh plugin add ${targetPkg}`,
|
|
149
|
+
allCommands: {
|
|
150
|
+
dshCli: `pnpm dsh plugin add ${targetPkg}`,
|
|
151
|
+
profile: `dsh plugin --profile default add ${targetPkg}`,
|
|
152
|
+
pnpm: `pnpm add ${targetPkg}`,
|
|
153
|
+
npm: `npm install -g ${targetPkg}`,
|
|
154
|
+
},
|
|
155
|
+
releaseNotesUrl: `${NPM_PACKAGE_URL}?activeTab=versions`,
|
|
156
|
+
checkedAt: now,
|
|
157
|
+
};
|
|
158
|
+
return this.cachedInfo;
|
|
159
|
+
}
|
|
160
|
+
}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import type { UpgradeExecutionResult, UpgradeStatusResult } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* 构建跨平台环境自愈增强的 ProcessEnv (重点解决 macOS GUI 应用丢失 PATH 的痛点)
|
|
4
|
+
*
|
|
5
|
+
* 为什么必须这样做:
|
|
6
|
+
* 1. 在 macOS 系统上,若 DSH 桌面客户端由 Finder / Dock / Spotlight (GUI) 启动,进程默认只继承
|
|
7
|
+
* 极简系统 PATH (/usr/bin:/bin:/usr/sbin:/sbin),不会自动读取用户 shell 配置文件 (~/.zshrc, ~/.bash_profile);
|
|
8
|
+
* 2. 用户通过 Homebrew (/opt/homebrew/bin 或 /usr/local/bin) 或 nvm 安装的 node、npm、pnpm 默认在 GUI 下不可见;
|
|
9
|
+
* 3. 动态将当前 node 运行时所在目录 (path.dirname(process.execPath)) 及 Mac 常用包管理器路径注入 PATH 首端,
|
|
10
|
+
* 彻底实现 macOS 与 Linux 环境下子进程对 npm / pnpm 命令的 100% 自愈发现。
|
|
11
|
+
*/
|
|
12
|
+
export declare function buildCrossPlatformEnv(): NodeJS.ProcessEnv;
|
|
13
|
+
/**
|
|
14
|
+
* 自动升级执行引擎
|
|
15
|
+
*
|
|
16
|
+
* 核心设计考量与约束条件:
|
|
17
|
+
* 1. 互斥保护 (Mutex):同一时刻仅允许一个升级任务执行,防止用户连击或并发请求击垮包管理器 lockfile;
|
|
18
|
+
* 2. 环境自省 (Dev-Link Safe):检测是否在本地源码工作区调试,若是则阻断自动覆盖,保护源码不被破坏;
|
|
19
|
+
* 3. 跨平台兼容 (macOS / Windows / Linux):自动适配 cmd.exe 与 sh/zsh,自愈补全 macOS PATH 变量;
|
|
20
|
+
* 4. 稳态超时:设置 60s 进程上限,杜绝子进程因网络悬挂死锁宿主 WebServer;
|
|
21
|
+
* 5. 重启指引:Node.js 运行时内存不可变,升级成功后明确要求重启 DSH 彻底加载最新后端能力。
|
|
22
|
+
*/
|
|
23
|
+
export declare class UpgradeManager {
|
|
24
|
+
private isUpgrading;
|
|
25
|
+
private lastResult;
|
|
26
|
+
private logBuffer;
|
|
27
|
+
/**
|
|
28
|
+
* 探测当前插件是否是以本地 Git 源码软链接方式运行
|
|
29
|
+
*/
|
|
30
|
+
isDevLinked(): boolean;
|
|
31
|
+
/**
|
|
32
|
+
* 智能识别当前 DSH 运行环境 (桌面版 vs Web/CLI 版)
|
|
33
|
+
*
|
|
34
|
+
* 依据事实源:
|
|
35
|
+
* 1. 桌面版启动时会固定注入 DSH_PROFILE=desktop 与 DSH_PROFILE_DIR (~/.dsh/profiles/desktop);
|
|
36
|
+
* 2. Web版/CLI版通常 DSH_PROFILE 为 default 或自定义工作区 profile;
|
|
37
|
+
* 3. 跨平台支持:通过 os.homedir() 安全解析 ~/.dsh 目录。
|
|
38
|
+
*/
|
|
39
|
+
detectEnvironment(): {
|
|
40
|
+
isDesktop: boolean;
|
|
41
|
+
profile: string;
|
|
42
|
+
profileDir?: string;
|
|
43
|
+
isDevLinked: boolean;
|
|
44
|
+
platform: NodeJS.Platform;
|
|
45
|
+
};
|
|
46
|
+
/**
|
|
47
|
+
* 获取当前升级状态
|
|
48
|
+
*/
|
|
49
|
+
getStatus(): UpgradeStatusResult;
|
|
50
|
+
/**
|
|
51
|
+
* 执行一键升级核心流程
|
|
52
|
+
*/
|
|
53
|
+
executeUpgrade(targetVersion?: string): Promise<UpgradeExecutionResult>;
|
|
54
|
+
}
|