dsh-api-runner 0.1.0 → 0.2.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 +71 -15
- package/client/client.js +1840 -1604
- package/package.json +71 -77
- package/src/java-runner.js +3 -3
- package/src/main.js +31 -2
- package/src/ops.js +1268 -1039
- package/src/project-store.js +350 -334
- package/src/restart.js +43 -12
- package/test/client.mjs +162 -109
- package/test/plugin.mjs +34 -0
- package/test/smoke.mjs +199 -0
package/package.json
CHANGED
|
@@ -1,77 +1,71 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "dsh-api-runner",
|
|
3
|
-
"version": "0.1
|
|
4
|
-
"description": "DSH 插件:按配置调用后端 HTTP 接口、启停/重启本地开发服务、增量读取日志并等待日志特征,让模型能\"改完自己验\"。",
|
|
5
|
-
"type": "module",
|
|
6
|
-
"license": "MIT",
|
|
7
|
-
"author": "Moz (lhhzmz229)",
|
|
8
|
-
"repository": {
|
|
9
|
-
"type": "git",
|
|
10
|
-
"url": "git+https://github.com/lhhzmz229/dsh-api-runner.git"
|
|
11
|
-
},
|
|
12
|
-
"homepage": "https://github.com/lhhzmz229/dsh-api-runner#readme",
|
|
13
|
-
"bugs": {
|
|
14
|
-
"url": "https://github.com/lhhzmz229/dsh-api-runner/issues"
|
|
15
|
-
},
|
|
16
|
-
"keywords": [
|
|
17
|
-
"dsh",
|
|
18
|
-
"dsh-plugin",
|
|
19
|
-
"deepseek-harness",
|
|
20
|
-
"api-runner",
|
|
21
|
-
"http-client",
|
|
22
|
-
"log-tail",
|
|
23
|
-
"spring-boot",
|
|
24
|
-
"java",
|
|
25
|
-
"devtools"
|
|
26
|
-
],
|
|
27
|
-
"main": "src/main.js",
|
|
28
|
-
"exports": {
|
|
29
|
-
".": "./src/main.js",
|
|
30
|
-
"./runner": "./src/main.js",
|
|
31
|
-
"./client": "./client/client.js",
|
|
32
|
-
"./package.json": "./package.json"
|
|
33
|
-
},
|
|
34
|
-
"engines": {
|
|
35
|
-
"node": ">=20",
|
|
36
|
-
"dsh": ">=0.1.0-rc.6 <0.2.0-0 || >=0.2.0-rc.1 <0.3.0-0"
|
|
37
|
-
},
|
|
38
|
-
"scripts": {
|
|
39
|
-
"test": "node test/smoke.mjs && node test/plugin.mjs",
|
|
40
|
-
"test:all": "node test/smoke.mjs && node test/plugin.mjs && node test/client.mjs && node test/managed.mjs && node test/java.mjs",
|
|
41
|
-
"stage": "node scripts/stage.mjs",
|
|
42
|
-
"release": "node scripts/stage.mjs --release"
|
|
43
|
-
},
|
|
44
|
-
"dependencies": {
|
|
45
|
-
"yaml": "^2.8.0"
|
|
46
|
-
},
|
|
47
|
-
"
|
|
48
|
-
"
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
"
|
|
52
|
-
"
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
"
|
|
68
|
-
"
|
|
69
|
-
"
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
"test",
|
|
73
|
-
"README.md",
|
|
74
|
-
"LICENSE",
|
|
75
|
-
"dsh-api-runner.example.yml"
|
|
76
|
-
]
|
|
77
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "dsh-api-runner",
|
|
3
|
+
"version": "0.2.1",
|
|
4
|
+
"description": "DSH 插件:按配置调用后端 HTTP 接口、启停/重启本地开发服务、增量读取日志并等待日志特征,让模型能\"改完自己验\"。",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"author": "Moz (lhhzmz229)",
|
|
8
|
+
"repository": {
|
|
9
|
+
"type": "git",
|
|
10
|
+
"url": "git+https://github.com/lhhzmz229/dsh-api-runner.git"
|
|
11
|
+
},
|
|
12
|
+
"homepage": "https://github.com/lhhzmz229/dsh-api-runner#readme",
|
|
13
|
+
"bugs": {
|
|
14
|
+
"url": "https://github.com/lhhzmz229/dsh-api-runner/issues"
|
|
15
|
+
},
|
|
16
|
+
"keywords": [
|
|
17
|
+
"dsh",
|
|
18
|
+
"dsh-plugin",
|
|
19
|
+
"deepseek-harness",
|
|
20
|
+
"api-runner",
|
|
21
|
+
"http-client",
|
|
22
|
+
"log-tail",
|
|
23
|
+
"spring-boot",
|
|
24
|
+
"java",
|
|
25
|
+
"devtools"
|
|
26
|
+
],
|
|
27
|
+
"main": "src/main.js",
|
|
28
|
+
"exports": {
|
|
29
|
+
".": "./src/main.js",
|
|
30
|
+
"./runner": "./src/main.js",
|
|
31
|
+
"./client": "./client/client.js",
|
|
32
|
+
"./package.json": "./package.json"
|
|
33
|
+
},
|
|
34
|
+
"engines": {
|
|
35
|
+
"node": ">=20",
|
|
36
|
+
"dsh": ">=0.1.0-rc.6 <0.2.0-0 || >=0.2.0-rc.1 <0.3.0-0"
|
|
37
|
+
},
|
|
38
|
+
"scripts": {
|
|
39
|
+
"test": "node test/smoke.mjs && node test/plugin.mjs",
|
|
40
|
+
"test:all": "node test/smoke.mjs && node test/plugin.mjs && node test/client.mjs && node test/managed.mjs && node test/java.mjs",
|
|
41
|
+
"stage": "node scripts/stage.mjs",
|
|
42
|
+
"release": "node scripts/stage.mjs --release"
|
|
43
|
+
},
|
|
44
|
+
"dependencies": {
|
|
45
|
+
"yaml": "^2.8.0"
|
|
46
|
+
},
|
|
47
|
+
"dsh": {
|
|
48
|
+
"bundle": {
|
|
49
|
+
"patch": "./cordis.patch.yml"
|
|
50
|
+
},
|
|
51
|
+
"client": {
|
|
52
|
+
"platform": "web",
|
|
53
|
+
"inject": [
|
|
54
|
+
"@deepseek-ai/dsh-client-ui-layout",
|
|
55
|
+
"@deepseek-ai/dsh-client-ui-sidebar",
|
|
56
|
+
"@deepseek-ai/dsh-client-ui-sidebar-right"
|
|
57
|
+
]
|
|
58
|
+
}
|
|
59
|
+
},
|
|
60
|
+
"files": [
|
|
61
|
+
"cordis.patch.yml",
|
|
62
|
+
"src",
|
|
63
|
+
"client",
|
|
64
|
+
"docs",
|
|
65
|
+
"scripts",
|
|
66
|
+
"test",
|
|
67
|
+
"README.md",
|
|
68
|
+
"LICENSE",
|
|
69
|
+
"dsh-api-runner.example.yml"
|
|
70
|
+
]
|
|
71
|
+
}
|
package/src/java-runner.js
CHANGED
|
@@ -267,7 +267,7 @@ export class JavaRunner {
|
|
|
267
267
|
extraJvmArgs: [`-DdshApiRunner.runId=${id}`],
|
|
268
268
|
});
|
|
269
269
|
this._ensureLogHeader(logPath, `接管 pid ${sourcePid}(${id})`);
|
|
270
|
-
const spawned = spawnService({ javaExe: snapshot.javaExe, argv: built.argv, cwd: snapshot.cwd, logPath });
|
|
270
|
+
const spawned = await spawnService({ javaExe: snapshot.javaExe, argv: built.argv, cwd: snapshot.cwd, logPath });
|
|
271
271
|
if (!spawned.ok) return { ok: false, code: 'SPAWN_FAILED', message: spawned.message, compile };
|
|
272
272
|
|
|
273
273
|
const record = {
|
|
@@ -459,7 +459,7 @@ export class JavaRunner {
|
|
|
459
459
|
|
|
460
460
|
// 每次重启开一个新日志段,历史启动记录不被覆盖
|
|
461
461
|
const logPath = this.logPathOf(entry.id);
|
|
462
|
-
const spawned = spawnService({ javaExe: entry.javaExe, argv: entry.argv, cwd: entry.cwd, logPath });
|
|
462
|
+
const spawned = await spawnService({ javaExe: entry.javaExe, argv: entry.argv, cwd: entry.cwd, logPath });
|
|
463
463
|
if (!spawned.ok) return { ok: false, code: 'SPAWN_FAILED', message: spawned.message, compile };
|
|
464
464
|
|
|
465
465
|
const record = { ...entry, pid: spawned.pid, logPath, argv: entry.argv, startedAt: new Date().toISOString(), stoppedAt: '' };
|
|
@@ -530,7 +530,7 @@ export class JavaRunner {
|
|
|
530
530
|
});
|
|
531
531
|
const logPath = this.logPathOf(id);
|
|
532
532
|
this._ensureLogHeader(logPath, `按保存的配置启动 ${id}`);
|
|
533
|
-
const spawned = spawnService({ javaExe: saved.javaExe, argv: built.argv, cwd: saved.cwd, logPath });
|
|
533
|
+
const spawned = await spawnService({ javaExe: saved.javaExe, argv: built.argv, cwd: saved.cwd, logPath });
|
|
534
534
|
if (!spawned.ok) return { ok: false, code: 'SPAWN_FAILED', message: spawned.message, compile };
|
|
535
535
|
|
|
536
536
|
const record = {
|
package/src/main.js
CHANGED
|
@@ -61,8 +61,13 @@ const PARAMETERS = {
|
|
|
61
61
|
log_id: { type: 'string', description: '日志 id 或 name(log、wait_log、reset_log 用;省略时取第一个日志)' },
|
|
62
62
|
java_action: {
|
|
63
63
|
type: 'string',
|
|
64
|
-
enum: ['list', 'start', 'stop', 'restart', 'log', 'status', 'detail', 'ignore', 'unignore', 'save', 'unsave', 'start_saved', 'settings'],
|
|
65
|
-
description: 'Java 服务动作(action=java 用):list 列出;detail 服务详情+日志;start 接管启动(先编译再杀旧进程);stop/restart 只对插件启动的生效;log 读日志;ignore/unignore 在面板列表中隐藏/恢复;save 把当前进程的启动配方向保存下来(之后不用 IDEA 也能起);unsave 删除保存;start_saved
|
|
64
|
+
enum: ['list', 'start', 'stop', 'restart', 'log', 'status', 'detail', 'ignore', 'unignore', 'save', 'unsave', 'start_saved', 'start_all', 'settings'],
|
|
65
|
+
description: 'Java 服务动作(action=java 用):list 列出;detail 服务详情+日志;start 接管启动(先编译再杀旧进程);stop/restart 只对插件启动的生效;log 读日志;ignore/unignore 在面板列表中隐藏/恢复;save 把当前进程的启动配方向保存下来(之后不用 IDEA 也能起);unsave 删除保存;start_saved 按保存的配置启动一个;start_all 一键启动所有已保存的服务(已运行的跳过,单个失败不影响其余,返回每个的成败);settings 读写插件设置(数据目录/默认工作区)',
|
|
66
|
+
},
|
|
67
|
+
java_ids: {
|
|
68
|
+
type: 'array',
|
|
69
|
+
items: { type: 'string' },
|
|
70
|
+
description: 'java_action=start_all 时只启动这些服务(省略则启动全部已保存的)',
|
|
66
71
|
},
|
|
67
72
|
pid: { type: 'number', description: '要接管的 Java 进程 pid(java_action=start 用)' },
|
|
68
73
|
java_id: { type: 'string', description: '插件托管的服务名或 pid(java_action=stop/restart/log/save/unsave/start_saved 用)' },
|
|
@@ -187,6 +192,18 @@ async function runTool(service, args, projectPath) {
|
|
|
187
192
|
timeoutMs,
|
|
188
193
|
});
|
|
189
194
|
}
|
|
195
|
+
// 一键启动:把「已保存」里的服务全拉起来(或只拉 java_ids 列的那几个)
|
|
196
|
+
if (javaAction === 'start_all') {
|
|
197
|
+
const ids = Array.isArray(args.java_ids)
|
|
198
|
+
? args.java_ids.map((id) => String(id))
|
|
199
|
+
: (args.java_id ? [String(args.java_id)] : []);
|
|
200
|
+
return service.startAllSavedJava(projectPath, ids, {
|
|
201
|
+
compile: args.compile !== false,
|
|
202
|
+
restart: args.restart === true,
|
|
203
|
+
timeoutMs,
|
|
204
|
+
compileTimeoutMs: args.timeout_ms ? Number(args.timeout_ms) : undefined,
|
|
205
|
+
});
|
|
206
|
+
}
|
|
190
207
|
if (javaAction === 'settings') {
|
|
191
208
|
if (args.settings && typeof args.settings === 'object') return service.saveSettings(asObject(args.settings));
|
|
192
209
|
return service.settings();
|
|
@@ -547,6 +564,18 @@ async function handleHttp(req, res, service, projectOf) {
|
|
|
547
564
|
timeoutMs: body.timeout_ms ? Number(body.timeout_ms) : undefined,
|
|
548
565
|
}));
|
|
549
566
|
}
|
|
567
|
+
// 一键启动:后台跑,立刻返回批次 id;面板轮询 java/start-all/status 看进度
|
|
568
|
+
if (route === 'java/start-all' && req.method === 'POST') {
|
|
569
|
+
const body = await readBody();
|
|
570
|
+
return send(200, service.startSavedJavaBatch(pickCwd(cwd, url, body), Array.isArray(body.ids) ? body.ids : [], {
|
|
571
|
+
compile: body.compile !== false,
|
|
572
|
+
restart: body.restart === true,
|
|
573
|
+
timeoutMs: body.timeout_ms ? Number(body.timeout_ms) : undefined,
|
|
574
|
+
}));
|
|
575
|
+
}
|
|
576
|
+
if (route === 'java/start-all/status' && req.method === 'GET') {
|
|
577
|
+
return send(200, service.startBatchStatus(url.searchParams.get('batch') || ''));
|
|
578
|
+
}
|
|
550
579
|
if (route === 'settings' && req.method === 'GET') {
|
|
551
580
|
return send(200, service.settings());
|
|
552
581
|
}
|