deskbuddy 0.2.0-beta.3 → 0.2.0-beta.5
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/dist/cli.js +1441 -628
- package/dist/hook.cjs +44 -3
- package/hook/hook.cjs +44 -3
- package/package.json +1 -1
package/dist/hook.cjs
CHANGED
|
@@ -26,7 +26,7 @@ const MAX_SESSIONS = 20
|
|
|
26
26
|
* 快照整包带的能力声明(前置 spec 2026-09-29 §4.4,服务端写 deskbuddy:caps:{clientId})。
|
|
27
27
|
* 与 src/core/snapshot.ts 的 CAPS 一致
|
|
28
28
|
*/
|
|
29
|
-
const CAPS = ['cmd_result', 'window_inject']
|
|
29
|
+
const CAPS = ['cmd_result', 'window_inject', 'resume_ended']
|
|
30
30
|
/** 状态文件里保留的最近事件条数,与 src/core/state.ts 的 RECENT_MAX 一致 */
|
|
31
31
|
const RECENT_MAX = 8
|
|
32
32
|
const REPORT_TIMEOUT_MS = 2000
|
|
@@ -556,6 +556,40 @@ function writeState(s) {
|
|
|
556
556
|
fs.renameSync(tmp, statePath(s.sessionId))
|
|
557
557
|
}
|
|
558
558
|
|
|
559
|
+
// ---------- 已结束记录(与 src/core/ended.ts 同构,续跑方案 spec 2026-09-29 §5.1) ----------
|
|
560
|
+
|
|
561
|
+
const ENDED_TTL_MS = 7 * 24 * 60 * 60 * 1000
|
|
562
|
+
|
|
563
|
+
function writeEnded(s, now) {
|
|
564
|
+
const sid = String((s && s.sessionId) || '')
|
|
565
|
+
if (!/^[A-Za-z0-9_-]{1,64}$/.test(sid)) return
|
|
566
|
+
try {
|
|
567
|
+
const dir = path.join(deskbuddyHome(), 'ended')
|
|
568
|
+
fs.mkdirSync(dir, { recursive: true, mode: 0o700 })
|
|
569
|
+
const t = now || Date.now()
|
|
570
|
+
const rec = { sessionId: sid, tool: s.tool || '', cwd: s.cwd || '', interactive: s.interactive === true, endedAt: t }
|
|
571
|
+
const file = path.join(dir, sid + '.json')
|
|
572
|
+
fs.writeFileSync(file + '.tmp', JSON.stringify(rec), { encoding: 'utf8', mode: 0o600 })
|
|
573
|
+
fs.renameSync(file + '.tmp', file)
|
|
574
|
+
for (const n of fs.readdirSync(dir)) {
|
|
575
|
+
const f = path.join(dir, n)
|
|
576
|
+
try {
|
|
577
|
+
if (t - fs.statSync(f).mtimeMs > ENDED_TTL_MS) fs.rmSync(f, { force: true })
|
|
578
|
+
} catch (e) {
|
|
579
|
+
/* ignore */
|
|
580
|
+
}
|
|
581
|
+
}
|
|
582
|
+
} catch (e) {
|
|
583
|
+
/* 记不下:只是这个会话结束后不能从设备续跑 */
|
|
584
|
+
}
|
|
585
|
+
}
|
|
586
|
+
|
|
587
|
+
/** 会话结束:先写已结束记录,再删状态(删状态的地方都走这里,/clear 除外) */
|
|
588
|
+
function retireState(s, now) {
|
|
589
|
+
writeEnded(s, now)
|
|
590
|
+
removeState(s.sessionId)
|
|
591
|
+
}
|
|
592
|
+
|
|
559
593
|
function removeState(sessionId) {
|
|
560
594
|
try {
|
|
561
595
|
fs.rmSync(statePath(sessionId), { force: true })
|
|
@@ -591,7 +625,7 @@ function readAliveStates(tool) {
|
|
|
591
625
|
}
|
|
592
626
|
if (!s || s.tool !== tool) continue
|
|
593
627
|
if (s.pid && !isAlive(s.pid, s.pidName)) {
|
|
594
|
-
|
|
628
|
+
retireState(s) // 窗口已关:记下已结束、剔除并自我清理,state 目录不再无限增长
|
|
595
629
|
continue
|
|
596
630
|
}
|
|
597
631
|
alive.push(s)
|
|
@@ -1090,8 +1124,13 @@ async function main(argv) {
|
|
|
1090
1124
|
if (event === 'SessionEnd' && payload.reason === 'clear') {
|
|
1091
1125
|
const old = readState(sessionId)
|
|
1092
1126
|
if (old && old.pid) markClear(old.pid, sessionId)
|
|
1127
|
+
// /clear 引起的结束交给别名改绑,不写已结束记录
|
|
1128
|
+
removeState(sessionId)
|
|
1129
|
+
} else {
|
|
1130
|
+
// 先记下已结束(设备再回复时续跑要知道 cwd),再删状态。状态文件没有就用这次事件里的 cwd
|
|
1131
|
+
const old = readState(sessionId)
|
|
1132
|
+
retireState(old || { sessionId: sessionId, tool: tool, cwd: payload.cwd || '', interactive: false })
|
|
1093
1133
|
}
|
|
1094
|
-
removeState(sessionId)
|
|
1095
1134
|
// 删完补发一次剩余会话,否则这条会一直挂在屏上等服务端失联 TTL。
|
|
1096
1135
|
// 关掉最后一个窗口时发的是空列表——服务端放行空快照,该机器该工具随即从屏上消失
|
|
1097
1136
|
await reportIfAuthorized(tool, Date.now())
|
|
@@ -1199,6 +1238,8 @@ module.exports = {
|
|
|
1199
1238
|
readGitBranch,
|
|
1200
1239
|
readState,
|
|
1201
1240
|
removeState,
|
|
1241
|
+
retireState,
|
|
1242
|
+
writeEnded,
|
|
1202
1243
|
resolveAgentPid,
|
|
1203
1244
|
resolveTitle,
|
|
1204
1245
|
takeNotice,
|
package/hook/hook.cjs
CHANGED
|
@@ -26,7 +26,7 @@ const MAX_SESSIONS = 20
|
|
|
26
26
|
* 快照整包带的能力声明(前置 spec 2026-09-29 §4.4,服务端写 deskbuddy:caps:{clientId})。
|
|
27
27
|
* 与 src/core/snapshot.ts 的 CAPS 一致
|
|
28
28
|
*/
|
|
29
|
-
const CAPS = ['cmd_result', 'window_inject']
|
|
29
|
+
const CAPS = ['cmd_result', 'window_inject', 'resume_ended']
|
|
30
30
|
/** 状态文件里保留的最近事件条数,与 src/core/state.ts 的 RECENT_MAX 一致 */
|
|
31
31
|
const RECENT_MAX = 8
|
|
32
32
|
const REPORT_TIMEOUT_MS = 2000
|
|
@@ -556,6 +556,40 @@ function writeState(s) {
|
|
|
556
556
|
fs.renameSync(tmp, statePath(s.sessionId))
|
|
557
557
|
}
|
|
558
558
|
|
|
559
|
+
// ---------- 已结束记录(与 src/core/ended.ts 同构,续跑方案 spec 2026-09-29 §5.1) ----------
|
|
560
|
+
|
|
561
|
+
const ENDED_TTL_MS = 7 * 24 * 60 * 60 * 1000
|
|
562
|
+
|
|
563
|
+
function writeEnded(s, now) {
|
|
564
|
+
const sid = String((s && s.sessionId) || '')
|
|
565
|
+
if (!/^[A-Za-z0-9_-]{1,64}$/.test(sid)) return
|
|
566
|
+
try {
|
|
567
|
+
const dir = path.join(deskbuddyHome(), 'ended')
|
|
568
|
+
fs.mkdirSync(dir, { recursive: true, mode: 0o700 })
|
|
569
|
+
const t = now || Date.now()
|
|
570
|
+
const rec = { sessionId: sid, tool: s.tool || '', cwd: s.cwd || '', interactive: s.interactive === true, endedAt: t }
|
|
571
|
+
const file = path.join(dir, sid + '.json')
|
|
572
|
+
fs.writeFileSync(file + '.tmp', JSON.stringify(rec), { encoding: 'utf8', mode: 0o600 })
|
|
573
|
+
fs.renameSync(file + '.tmp', file)
|
|
574
|
+
for (const n of fs.readdirSync(dir)) {
|
|
575
|
+
const f = path.join(dir, n)
|
|
576
|
+
try {
|
|
577
|
+
if (t - fs.statSync(f).mtimeMs > ENDED_TTL_MS) fs.rmSync(f, { force: true })
|
|
578
|
+
} catch (e) {
|
|
579
|
+
/* ignore */
|
|
580
|
+
}
|
|
581
|
+
}
|
|
582
|
+
} catch (e) {
|
|
583
|
+
/* 记不下:只是这个会话结束后不能从设备续跑 */
|
|
584
|
+
}
|
|
585
|
+
}
|
|
586
|
+
|
|
587
|
+
/** 会话结束:先写已结束记录,再删状态(删状态的地方都走这里,/clear 除外) */
|
|
588
|
+
function retireState(s, now) {
|
|
589
|
+
writeEnded(s, now)
|
|
590
|
+
removeState(s.sessionId)
|
|
591
|
+
}
|
|
592
|
+
|
|
559
593
|
function removeState(sessionId) {
|
|
560
594
|
try {
|
|
561
595
|
fs.rmSync(statePath(sessionId), { force: true })
|
|
@@ -591,7 +625,7 @@ function readAliveStates(tool) {
|
|
|
591
625
|
}
|
|
592
626
|
if (!s || s.tool !== tool) continue
|
|
593
627
|
if (s.pid && !isAlive(s.pid, s.pidName)) {
|
|
594
|
-
|
|
628
|
+
retireState(s) // 窗口已关:记下已结束、剔除并自我清理,state 目录不再无限增长
|
|
595
629
|
continue
|
|
596
630
|
}
|
|
597
631
|
alive.push(s)
|
|
@@ -1090,8 +1124,13 @@ async function main(argv) {
|
|
|
1090
1124
|
if (event === 'SessionEnd' && payload.reason === 'clear') {
|
|
1091
1125
|
const old = readState(sessionId)
|
|
1092
1126
|
if (old && old.pid) markClear(old.pid, sessionId)
|
|
1127
|
+
// /clear 引起的结束交给别名改绑,不写已结束记录
|
|
1128
|
+
removeState(sessionId)
|
|
1129
|
+
} else {
|
|
1130
|
+
// 先记下已结束(设备再回复时续跑要知道 cwd),再删状态。状态文件没有就用这次事件里的 cwd
|
|
1131
|
+
const old = readState(sessionId)
|
|
1132
|
+
retireState(old || { sessionId: sessionId, tool: tool, cwd: payload.cwd || '', interactive: false })
|
|
1093
1133
|
}
|
|
1094
|
-
removeState(sessionId)
|
|
1095
1134
|
// 删完补发一次剩余会话,否则这条会一直挂在屏上等服务端失联 TTL。
|
|
1096
1135
|
// 关掉最后一个窗口时发的是空列表——服务端放行空快照,该机器该工具随即从屏上消失
|
|
1097
1136
|
await reportIfAuthorized(tool, Date.now())
|
|
@@ -1199,6 +1238,8 @@ module.exports = {
|
|
|
1199
1238
|
readGitBranch,
|
|
1200
1239
|
readState,
|
|
1201
1240
|
removeState,
|
|
1241
|
+
retireState,
|
|
1242
|
+
writeEnded,
|
|
1202
1243
|
resolveAgentPid,
|
|
1203
1244
|
resolveTitle,
|
|
1204
1245
|
takeNotice,
|