dsh-manage-session 0.1.0-alpha.0 → 0.2.3
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/CHANGELOG.ja.md +159 -0
- package/CHANGELOG.ko.md +160 -0
- package/CHANGELOG.md +232 -0
- package/INSTALL.ja.md +2 -2
- package/INSTALL.ko.md +2 -2
- package/INSTALL.md +4 -4
- package/INSTALL.zh.md +4 -4
- package/README.en.md +63 -63
- package/README.ja.md +63 -63
- package/README.ko.md +61 -61
- package/README.md +96 -75
- package/dsh.plugin.json +22 -22
- package/lib/client.js +560 -120
- package/lib/index.d.ts +333 -78
- package/lib/index.js +694 -97
- package/package.json +121 -104
- package/screenshots.json +3 -3
- package/src/client/card.tsx +153 -106
- package/src/client/health-panel.tsx +397 -205
- package/src/client/history-panel.tsx +150 -35
- package/src/client/host-api.ts +177 -135
- package/src/client/index.ts +234 -198
- package/src/client/locales.ts +203 -153
- package/src/client/panel.tsx +118 -106
- package/src/config.ts +1 -1
- package/src/host/health/cache.ts +97 -0
- package/src/host/health/decode.ts +307 -307
- package/src/host/health/gates.ts +331 -312
- package/src/host/health/repair.ts +217 -126
- package/src/host/health/scan.ts +156 -114
- package/src/host/history/archive-source.ts +103 -42
- package/src/host/history/archive.ts +54 -5
- package/src/host/history/purge.ts +323 -0
- package/src/index.ts +504 -417
package/lib/index.d.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
//#region node_modules
|
|
1
|
+
//#region node_modules/cosmokit/lib/index.d.ts
|
|
2
2
|
type Dict<T = any, K extends string | symbol = string> = { [key in K]: T; };
|
|
3
3
|
type Promisify<T> = Promise<T extends Promise<infer S> ? S : T>;
|
|
4
4
|
type Awaitable<T> = [T] extends [Promise<unknown>] ? T : T | Promise<T>;
|
|
5
5
|
//#endregion
|
|
6
|
-
//#region node_modules
|
|
6
|
+
//#region node_modules/@standard-schema/spec/dist/index.d.ts
|
|
7
7
|
/** The Standard Typed interface. This is a base type extended by other specs. */
|
|
8
8
|
interface StandardTypedV1<Input = unknown, Output = Input> {
|
|
9
9
|
/** The Standard properties. */
|
|
@@ -80,7 +80,7 @@ declare namespace StandardSchemaV1 {
|
|
|
80
80
|
type InferOutput<Schema extends StandardTypedV1> = StandardTypedV1.InferOutput<Schema>;
|
|
81
81
|
}
|
|
82
82
|
//#endregion
|
|
83
|
-
//#region node_modules
|
|
83
|
+
//#region node_modules/cordis/lib/utils.d.ts
|
|
84
84
|
declare class DisposableList<T extends WeakKey> {
|
|
85
85
|
private sn;
|
|
86
86
|
private map;
|
|
@@ -112,7 +112,7 @@ declare const symbols: {
|
|
|
112
112
|
resolveConfig: typeof Service.resolveConfig;
|
|
113
113
|
};
|
|
114
114
|
//#endregion
|
|
115
|
-
//#region node_modules
|
|
115
|
+
//#region node_modules/cordis/lib/registry.d.ts
|
|
116
116
|
type Inject<M = Dict> = (keyof M)[] | { [K in keyof M]?: M[K]; };
|
|
117
117
|
type InjectKey = keyof { [K in keyof Context & string as Context[K] extends {
|
|
118
118
|
[symbols.config]: any;
|
|
@@ -182,7 +182,7 @@ declare class RegistryService {
|
|
|
182
182
|
plugin(plugin: Plugin, config?: any, getOuterStack?: () => string[]): Fiber & PromiseLike<Fiber>;
|
|
183
183
|
}
|
|
184
184
|
//#endregion
|
|
185
|
-
//#region node_modules
|
|
185
|
+
//#region node_modules/cordis/lib/reflect.d.ts
|
|
186
186
|
declare module './context' {
|
|
187
187
|
interface Context {
|
|
188
188
|
get<K extends string & keyof this>(name: K, strict?: boolean): undefined | this[K];
|
|
@@ -230,7 +230,7 @@ declare class ReflectService {
|
|
|
230
230
|
bind<T extends Function>(callback: T): T;
|
|
231
231
|
}
|
|
232
232
|
//#endregion
|
|
233
|
-
//#region node_modules
|
|
233
|
+
//#region node_modules/cordis/lib/fiber.d.ts
|
|
234
234
|
declare module './context' {
|
|
235
235
|
interface Context extends Pick<Fiber, 'effect'> {
|
|
236
236
|
fiber: Fiber;
|
|
@@ -291,7 +291,7 @@ declare class Fiber {
|
|
|
291
291
|
update(config: any, noSave?: boolean): Awaitable<void>;
|
|
292
292
|
}
|
|
293
293
|
//#endregion
|
|
294
|
-
//#region node_modules
|
|
294
|
+
//#region node_modules/cordis/lib/events.d.ts
|
|
295
295
|
type Parameters<F> = F extends ((...args: infer P) => any) ? P : never;
|
|
296
296
|
type ReturnType<F> = F extends ((...args: any) => infer R) ? R : never;
|
|
297
297
|
type ThisType<F> = F extends ((this: infer T, ...args: any) => any) ? T : never;
|
|
@@ -349,7 +349,7 @@ interface Events {
|
|
|
349
349
|
'internal/dispatch'(mode: DispatchMode, name: string | symbol, args: any[], thisArg: any): void;
|
|
350
350
|
}
|
|
351
351
|
//#endregion
|
|
352
|
-
//#region node_modules
|
|
352
|
+
//#region node_modules/cordis/lib/logger.d.ts
|
|
353
353
|
declare module './context' {
|
|
354
354
|
interface Intercept {
|
|
355
355
|
logger: LoggerService.Intercept;
|
|
@@ -411,7 +411,7 @@ declare class LoggerService {
|
|
|
411
411
|
[symbols.invoke](name?: string): Logger;
|
|
412
412
|
}
|
|
413
413
|
//#endregion
|
|
414
|
-
//#region node_modules
|
|
414
|
+
//#region node_modules/cordis/lib/context.d.ts
|
|
415
415
|
interface Context {
|
|
416
416
|
[symbols.isolate]: Dict<symbol>;
|
|
417
417
|
[symbols.intercept]: Dict;
|
|
@@ -438,7 +438,7 @@ declare class Context {
|
|
|
438
438
|
intercept(name: string, config: any): this;
|
|
439
439
|
}
|
|
440
440
|
//#endregion
|
|
441
|
-
//#region node_modules
|
|
441
|
+
//#region node_modules/cordis/lib/service.d.ts
|
|
442
442
|
declare abstract class Service<out T = never> {
|
|
443
443
|
protected ctx: Context;
|
|
444
444
|
static readonly init: unique symbol;
|
|
@@ -469,7 +469,7 @@ declare abstract class Service<out T = never> {
|
|
|
469
469
|
interface StewardConfig {
|
|
470
470
|
/** 插件总开关。 */
|
|
471
471
|
enabled: boolean;
|
|
472
|
-
/** 会话历史文件(归档浏览与清理)。关闭后不注册 history
|
|
472
|
+
/** 会话历史文件(归档浏览与清理)。关闭后不注册 history 路由、不渲染「养老院」页签。 */
|
|
473
473
|
historyFiles?: boolean;
|
|
474
474
|
/** 会话健康检查(体检 → 处方 → 出院)。关闭后不注册 health 路由、不渲染「体检」页签。 */
|
|
475
475
|
healthCheck?: boolean;
|
|
@@ -486,6 +486,13 @@ declare const STEWARD_API_PREFIX = "/session-steward/api";
|
|
|
486
486
|
interface StewardArchiveRead {
|
|
487
487
|
ids: readonly string[];
|
|
488
488
|
source: 'registry' | 'storage-file' | 'none';
|
|
489
|
+
/**
|
|
490
|
+
* 宿主内存 registry 里的同一集合(尽力而为,读不到时缺省)。
|
|
491
|
+
*
|
|
492
|
+
* 与 `ids` 的差集 = 「已从存储文件移除、但本进程仍生效」的悬挂项:
|
|
493
|
+
* registry 是宿主启动时载入的快照,prune 写不到它,重启才会重载。
|
|
494
|
+
*/
|
|
495
|
+
registryIds?: readonly string[];
|
|
489
496
|
}
|
|
490
497
|
/** workspaceRegistry 镜像面(只读 getter)。 */
|
|
491
498
|
interface StewardRegistryFace {
|
|
@@ -493,17 +500,44 @@ interface StewardRegistryFace {
|
|
|
493
500
|
}
|
|
494
501
|
/**
|
|
495
502
|
* 解析一次官方归档集合。
|
|
503
|
+
*
|
|
504
|
+
* **存储文件优先**:prune 唯一能改的就是这份文件,列表必须与「能被改的那份」
|
|
505
|
+
* 同源,否则清理成功后面板看起来毫无变化 —— 宿主 registry 是进程启动时的快照,
|
|
506
|
+
* 直接编辑文件不会回写它,于是「文件在瘦身、列表纹丝不动」。
|
|
507
|
+
* registry 退居为文件缺失时的兜底,同时作为诊断面(`registryIds`)返回。
|
|
496
508
|
* @param registry - 惰性 workspaceRegistry 面(可能缺失或抛错)。
|
|
497
509
|
* @param searchPaths - 可选候选路径覆盖(DSH_HOME 非默认值或测试注入时使用)。
|
|
498
|
-
* @returns 归档 ids
|
|
510
|
+
* @returns 归档 ids、服务它的来源,以及宿主内存里的同一集合。
|
|
499
511
|
*/
|
|
500
512
|
declare function readArchiveSet(registry?: StewardRegistryFace, searchPaths?: readonly string[]): StewardArchiveRead;
|
|
513
|
+
/** 一次存储文件编辑的结果。 */
|
|
514
|
+
type StewardEditOutcome = {
|
|
515
|
+
ok: true;
|
|
516
|
+
changed: boolean;
|
|
517
|
+
file: string;
|
|
518
|
+
} | {
|
|
519
|
+
ok: false;
|
|
520
|
+
reason: string;
|
|
521
|
+
};
|
|
501
522
|
/**
|
|
502
|
-
*
|
|
523
|
+
* **本插件写 workspace.json 的唯一入口。**
|
|
524
|
+
*
|
|
525
|
+
* 任何「改归档集合 / 改工作区成员表」都必须走这里 —— 出现第二个写文件的实现,
|
|
526
|
+
* 就会重现「读的人和写的人不是同一份数据」那类问题。
|
|
503
527
|
*
|
|
504
|
-
*
|
|
505
|
-
*
|
|
506
|
-
*
|
|
528
|
+
* 协议与 storage-json 自身一致:读 → `edit(document)` 就地改 → 备份 → 同目录临时写入
|
|
529
|
+
* → 原子改名。`edit` 返回 `false` 表示无需写入(此时**不产生备份**)。
|
|
530
|
+
* @param path - 规范存储文件路径。
|
|
531
|
+
* @param edit - 就地修改文档;返回是否真的改了。
|
|
532
|
+
* @param log - 可选日志出口。
|
|
533
|
+
* @returns 编辑结果;失败时给出原因而非抛错。
|
|
534
|
+
*/
|
|
535
|
+
declare function editWorkspaceDocument(path: string, edit: (document: Record<string, unknown>) => boolean, log?: (msg: string) => void): StewardEditOutcome;
|
|
536
|
+
/**
|
|
537
|
+
* 从存储中枢的 `global.archivedSessionIds` 中移除会话 id(= 取消归档状态)。
|
|
538
|
+
*
|
|
539
|
+
* 官方后端没有 unarchive 端点,因此直接编辑规范文件;运行中的宿主把集合留在内存里、
|
|
540
|
+
* 只在启动时重载 —— 调用方必须提示需要重启 DSH。
|
|
507
541
|
* @param ids - 要从归档数组中移除的会话 id。
|
|
508
542
|
* @param log - 可选日志出口。
|
|
509
543
|
* @param searchPaths - 可选候选路径覆盖(测试注入用)。
|
|
@@ -515,61 +549,6 @@ declare function pruneArchiveFile(ids: readonly string[], log?: (msg: string) =>
|
|
|
515
549
|
file?: string;
|
|
516
550
|
};
|
|
517
551
|
//#endregion
|
|
518
|
-
//#region src/host/history/archive.d.ts
|
|
519
|
-
/** 一行历史文件条目(尽力而为的元数据)。 */
|
|
520
|
-
interface StewardHistoryRow {
|
|
521
|
-
sessionId: string;
|
|
522
|
-
title: string;
|
|
523
|
-
cwd: string;
|
|
524
|
-
updatedAt: number;
|
|
525
|
-
}
|
|
526
|
-
/** 列表结果。 */
|
|
527
|
-
interface StewardHistoryListResult {
|
|
528
|
-
ok: boolean;
|
|
529
|
-
items?: StewardHistoryRow[];
|
|
530
|
-
/** 归档集合来源;`none` 表示两处都没读到。 */
|
|
531
|
-
source?: 'registry' | 'storage-file' | 'none';
|
|
532
|
-
/** 元数据降级原因(标题/cwd 缺失时给出)。 */
|
|
533
|
-
degraded?: string;
|
|
534
|
-
error?: string;
|
|
535
|
-
}
|
|
536
|
-
/** 标题快照读取面(结构化镜像,零 value import)。 */
|
|
537
|
-
interface StewardTitleQueryFace {
|
|
538
|
-
readTitleSnapshots?(ids: readonly string[]): Promise<readonly {
|
|
539
|
-
status: 'fulfilled' | 'rejected';
|
|
540
|
-
value?: {
|
|
541
|
-
title?: {
|
|
542
|
-
title: string;
|
|
543
|
-
};
|
|
544
|
-
};
|
|
545
|
-
}[]>;
|
|
546
|
-
}
|
|
547
|
-
/**
|
|
548
|
-
* `session-history-list`:列出官方归档集合(尽力附带标题等元数据)。
|
|
549
|
-
* @param getRegistry - 惰性 workspaceRegistry 面。
|
|
550
|
-
* @param query - 可选标题快照面。
|
|
551
|
-
* @param searchPaths - 可选存储文件候选路径(DSH_HOME 非默认值/测试注入)。
|
|
552
|
-
* @returns 归档行清单。
|
|
553
|
-
*/
|
|
554
|
-
declare function listHistory(getRegistry: () => StewardRegistryFace | undefined, query?: StewardTitleQueryFace, searchPaths?: readonly string[]): Promise<StewardHistoryListResult>;
|
|
555
|
-
/** 清理结果。 */
|
|
556
|
-
interface StewardHistoryPruneResult {
|
|
557
|
-
ok: boolean;
|
|
558
|
-
removed?: number;
|
|
559
|
-
remaining?: number;
|
|
560
|
-
requiresRestart?: boolean;
|
|
561
|
-
error?: string;
|
|
562
|
-
}
|
|
563
|
-
/**
|
|
564
|
-
* `session-history-prune`:从官方归档数组中批量移除会话 id。
|
|
565
|
-
* 行为与迁移前等价:校验入参 → 备份并原子替换存储文件 → 返回 removed/remaining,
|
|
566
|
-
* 并明确要求重启 DSH(宿主内存中的集合只在启动时重载)。
|
|
567
|
-
* @param payload - `{ sessionIds: string[] }`。
|
|
568
|
-
* @param log - 可选日志出口。
|
|
569
|
-
* @param searchPaths - 可选候选路径覆盖(测试注入用)。
|
|
570
|
-
*/
|
|
571
|
-
declare function pruneHistory(payload: unknown, log?: (msg: string) => void, searchPaths?: readonly string[]): StewardHistoryPruneResult;
|
|
572
|
-
//#endregion
|
|
573
552
|
//#region src/host/health/decode.d.ts
|
|
574
553
|
/** 一次读取的统计与问题清单。 */
|
|
575
554
|
interface SessionLogRead {
|
|
@@ -631,8 +610,21 @@ declare function decodeSessionLogBytes(file: string, bytes: Buffer, decoders?: O
|
|
|
631
610
|
declare function decodeSessionLogFile(file: string, decoders?: OfficialDecoders): SessionLogRead;
|
|
632
611
|
//#endregion
|
|
633
612
|
//#region src/host/health/gates.d.ts
|
|
634
|
-
/**
|
|
635
|
-
|
|
613
|
+
/**
|
|
614
|
+
* gate 严重级。
|
|
615
|
+
*
|
|
616
|
+
* 判定标准(新增 gate 必须遵守):
|
|
617
|
+
* - `ok`:判定通过;
|
|
618
|
+
* - `warn`:**观测到了**异常现象,但尚不致命(必须有可复现的观测依据);
|
|
619
|
+
* - `fail`:观测到硬损坏,判定不通过;
|
|
620
|
+
* - `skipped`:**无从观测/无从判定**(冷态会话没有热态投影、缓存记录尚未生成、
|
|
621
|
+
* 日志里没有 turn/end 可判)——中性档,不抬升会话总判。
|
|
622
|
+
*
|
|
623
|
+
* 关键区分:把「无法判定」记成 `warn` 是错的。那会让所有无从观测的会话恒为
|
|
624
|
+
* 「注意」,真信号被淹没(实测事故:30 条会话全标「注意」)。
|
|
625
|
+
* 无从观测 ⇒ `skipped`,有观测依据 ⇒ `warn`。
|
|
626
|
+
*/
|
|
627
|
+
type GateLevel = 'ok' | 'warn' | 'fail' | 'skipped';
|
|
636
628
|
/** 归属信息:把失败字段指回具体插件包与字段路径。 */
|
|
637
629
|
interface GateAttribution {
|
|
638
630
|
/** 投影 key(例如 liveTokenStats)。 */
|
|
@@ -712,6 +704,198 @@ declare function gateColdRead(facts: TailFacts): GateResult;
|
|
|
712
704
|
/** 聚合四门结果为一份报告。 */
|
|
713
705
|
declare function buildSessionReport(context: GateContext): SessionHealthReport;
|
|
714
706
|
//#endregion
|
|
707
|
+
//#region src/host/health/cache.d.ts
|
|
708
|
+
/** 一份已成型的缓存。 */
|
|
709
|
+
interface HealthCacheEntry {
|
|
710
|
+
/** 非 ok 的会话报告(与 `onlyProblems: true` 的扫描结果同构)。 */
|
|
711
|
+
findings: SessionHealthReport[];
|
|
712
|
+
/** 生成这份缓存时的语料总数(用于「语料已变化」判断)。 */
|
|
713
|
+
total: number;
|
|
714
|
+
/** 生成时刻(epoch ms)。面板据此显示「N 分钟前」。 */
|
|
715
|
+
generatedAt: number;
|
|
716
|
+
}
|
|
717
|
+
/** 进程内体检缓存:分批扫描过程中累积,走完一遍语料才成型。 */
|
|
718
|
+
declare class HealthCache {
|
|
719
|
+
private ready;
|
|
720
|
+
private pending;
|
|
721
|
+
/** 读当前成型的缓存(未成型则 undefined)。 */
|
|
722
|
+
read(): HealthCacheEntry | undefined;
|
|
723
|
+
/** 开始一轮分批扫描(客户端以 `offset: 0` 发起时调用)。 */
|
|
724
|
+
begin(total: number): void;
|
|
725
|
+
/**
|
|
726
|
+
* 追加一批扫描结果。
|
|
727
|
+
*
|
|
728
|
+
* 只有累积的已访问数走满语料总数才成型;语言中途断掉(关面板、报错)不会留下
|
|
729
|
+
* 半份缓存冒充完整结果。
|
|
730
|
+
* @param findings - 本批的非 ok 报告。
|
|
731
|
+
* @param scanned - 本批**已访问**的会话数(不是命中数)。
|
|
732
|
+
* @param now - 时间源(测试可控)。
|
|
733
|
+
* @returns 本批追加后缓存是否刚好成型。
|
|
734
|
+
*/
|
|
735
|
+
append(findings: SessionHealthReport[], scanned: number, now?: () => number): boolean;
|
|
736
|
+
/**
|
|
737
|
+
* 单条就地回写(单会话体检 / 可逆处置后调用)。
|
|
738
|
+
*
|
|
739
|
+
* 这是缓存的**关键收益**:处置本就重算了 `after` 报告,把它写回即可,
|
|
740
|
+
* 不必为了刷新一行而重扫整个语料。
|
|
741
|
+
* @param report - 重算出的单会话报告。
|
|
742
|
+
* @returns 是否真的改动了缓存(无缓存时为 false)。
|
|
743
|
+
*/
|
|
744
|
+
patch(report: SessionHealthReport): boolean;
|
|
745
|
+
/** 丢弃缓存与未完成的累积。 */
|
|
746
|
+
clear(): void;
|
|
747
|
+
}
|
|
748
|
+
//#endregion
|
|
749
|
+
//#region src/host/history/archive.d.ts
|
|
750
|
+
/** 一行历史文件条目(尽力而为的元数据 + 磁盘占用)。 */
|
|
751
|
+
interface StewardHistoryRow {
|
|
752
|
+
sessionId: string;
|
|
753
|
+
title: string;
|
|
754
|
+
cwd: string;
|
|
755
|
+
updatedAt: number;
|
|
756
|
+
/** 转录目录占用字节数(未知/未解析时为 0)。 */
|
|
757
|
+
bytes: number;
|
|
758
|
+
/** 投影缓存占用字节数。 */
|
|
759
|
+
cacheBytes: number;
|
|
760
|
+
}
|
|
761
|
+
/** 列表结果。 */
|
|
762
|
+
interface StewardHistoryListResult {
|
|
763
|
+
ok: boolean;
|
|
764
|
+
items?: StewardHistoryRow[];
|
|
765
|
+
/** 归档集合来源;`none` 表示两处都没读到。 */
|
|
766
|
+
source?: 'registry' | 'storage-file' | 'none';
|
|
767
|
+
/** 元数据降级原因(标题/cwd 缺失时给出)。 */
|
|
768
|
+
degraded?: string;
|
|
769
|
+
/**
|
|
770
|
+
* 已从存储文件移除、但宿主内存 registry 里仍生效的 id 数。
|
|
771
|
+
*
|
|
772
|
+
* 大于 0 时列表展示的是**存储文件真值**(已不含这些 id),但它们在本进程内
|
|
773
|
+
* 仍然隐藏着对应会话 —— 面板据此提示「需重启 DSH 才彻底消失」。
|
|
774
|
+
*/
|
|
775
|
+
pendingRestart?: number;
|
|
776
|
+
error?: string;
|
|
777
|
+
}
|
|
778
|
+
/** 标题快照读取面(结构化镜像,零 value import)。 */
|
|
779
|
+
interface StewardTitleQueryFace {
|
|
780
|
+
readTitleSnapshots?(ids: readonly string[]): Promise<readonly {
|
|
781
|
+
status: 'fulfilled' | 'rejected';
|
|
782
|
+
value?: {
|
|
783
|
+
title?: {
|
|
784
|
+
title: string;
|
|
785
|
+
};
|
|
786
|
+
};
|
|
787
|
+
}[]>;
|
|
788
|
+
}
|
|
789
|
+
/**
|
|
790
|
+
* `session-history-list`:列出官方归档集合(尽力附带标题等元数据)。
|
|
791
|
+
* @param getRegistry - 惰性 workspaceRegistry 面。
|
|
792
|
+
* @param query - 可选标题快照面。
|
|
793
|
+
* @param searchPaths - 可选存储文件候选路径(DSH_HOME 非默认值/测试注入)。
|
|
794
|
+
* @returns 归档行清单。
|
|
795
|
+
*/
|
|
796
|
+
declare function listHistory(getRegistry: () => StewardRegistryFace | undefined, query?: StewardTitleQueryFace, searchPaths?: readonly string[], dshHome?: string): Promise<StewardHistoryListResult>;
|
|
797
|
+
/** 清理结果。 */
|
|
798
|
+
interface StewardHistoryPruneResult {
|
|
799
|
+
ok: boolean;
|
|
800
|
+
removed?: number;
|
|
801
|
+
remaining?: number;
|
|
802
|
+
requiresRestart?: boolean;
|
|
803
|
+
error?: string;
|
|
804
|
+
}
|
|
805
|
+
/**
|
|
806
|
+
* `session-history-prune`:从官方归档数组中批量移除会话 id。
|
|
807
|
+
* 行为与迁移前等价:校验入参 → 备份并原子替换存储文件 → 返回 removed/remaining,
|
|
808
|
+
* 并明确要求重启 DSH(宿主内存中的集合只在启动时重载)。
|
|
809
|
+
* @param payload - `{ sessionIds: string[] }`。
|
|
810
|
+
* @param log - 可选日志出口。
|
|
811
|
+
* @param searchPaths - 可选候选路径覆盖(测试注入用)。
|
|
812
|
+
*/
|
|
813
|
+
declare function pruneHistory(payload: unknown, log?: (msg: string) => void, searchPaths?: readonly string[]): StewardHistoryPruneResult;
|
|
814
|
+
//#endregion
|
|
815
|
+
//#region src/host/history/purge.d.ts
|
|
816
|
+
/** 一个归档会话在磁盘上的实体与占用。 */
|
|
817
|
+
interface StewardSessionUsage {
|
|
818
|
+
sessionId: string;
|
|
819
|
+
/** 转录目录绝对路径(不存在时缺省)。 */
|
|
820
|
+
dir?: string;
|
|
821
|
+
/** 转录目录占用字节数。 */
|
|
822
|
+
bytes: number;
|
|
823
|
+
/** 投影缓存文件绝对路径(不存在时缺省)。 */
|
|
824
|
+
cacheFile?: string;
|
|
825
|
+
/** 投影缓存占用字节数。 */
|
|
826
|
+
cacheBytes: number;
|
|
827
|
+
}
|
|
828
|
+
/** 转录根目录(`<dshHome>/sessions`)。 */
|
|
829
|
+
declare function sessionsRootFor(dshHome: string): string;
|
|
830
|
+
/**
|
|
831
|
+
* 投影缓存(**逐条布局**)根目录。
|
|
832
|
+
*
|
|
833
|
+
* 注意另有一个 `<dshHome>/storages/session_projcache.json`(整份布局)——
|
|
834
|
+
* 那是布局迁移留下的**化石**,宿主早已不再写它,本插件也不碰它。
|
|
835
|
+
*/
|
|
836
|
+
declare function projCacheRootFor(dshHome: string): string;
|
|
837
|
+
/**
|
|
838
|
+
* 扫一遍转录根,建立「会话 id → 目录」索引。
|
|
839
|
+
*
|
|
840
|
+
* 同一个 id 同时存在带前缀与不带前缀的目录时,**优先带 `session-` 前缀的那个**
|
|
841
|
+
* (归档集合里的 id 本身带前缀)。
|
|
842
|
+
* @param sessionsRoot - `<dshHome>/sessions`。
|
|
843
|
+
* @returns 归一化 id → 目录绝对路径。
|
|
844
|
+
*/
|
|
845
|
+
declare function indexSessionDirs(sessionsRoot: string): Map<string, string>;
|
|
846
|
+
/** 递归求目录占用字节数(读不到的条目跳过,不抛错)。 */
|
|
847
|
+
declare function dirSize(dir: string): number;
|
|
848
|
+
/**
|
|
849
|
+
* 解析一批会话在磁盘上的实体与占用(**只读,不删任何东西**)。
|
|
850
|
+
*
|
|
851
|
+
* 列表按行显示体积就走这里 —— 体积差异极大(实测单条缓存可达 23 MB、单条转录可达
|
|
852
|
+
* 6 MB,也有 0 字节的),报一个总量对用户没有意义。
|
|
853
|
+
* @param ids - 会话 id(带不带 `session-` 前缀都接受)。
|
|
854
|
+
* @param dshHome - DSH 主目录。
|
|
855
|
+
* @returns 会话 id → 实体位置与占用。
|
|
856
|
+
*/
|
|
857
|
+
declare function locateSessionUsage(ids: readonly string[], dshHome: string): Map<string, StewardSessionUsage>;
|
|
858
|
+
/**
|
|
859
|
+
* 断言目标是 `root` 的**直接子项**(层级也校验)。
|
|
860
|
+
*
|
|
861
|
+
* 破坏性操作不能只靠「路径拼对了」—— 拼错一层就是删掉整个 sessions 根。
|
|
862
|
+
* @param root - 允许的父目录。
|
|
863
|
+
* @param target - 待删目标。
|
|
864
|
+
* @param depth - 相对 root 的期望层数。
|
|
865
|
+
* @returns 是否安全。
|
|
866
|
+
*/
|
|
867
|
+
declare function isSafeChild(root: string, target: string, depth: number): boolean;
|
|
868
|
+
/** 清理结果。 */
|
|
869
|
+
interface StewardHistoryPurgeResult {
|
|
870
|
+
ok: boolean;
|
|
871
|
+
/** 成功清理的会话数。 */
|
|
872
|
+
purged?: number;
|
|
873
|
+
/** 释放的字节数(转录 + 投影缓存)。 */
|
|
874
|
+
freedBytes?: number;
|
|
875
|
+
/** 逐条失败原因;不阻断其余条目。 */
|
|
876
|
+
failures?: {
|
|
877
|
+
sessionId: string;
|
|
878
|
+
reason: string;
|
|
879
|
+
}[];
|
|
880
|
+
requiresRestart?: boolean;
|
|
881
|
+
error?: string;
|
|
882
|
+
}
|
|
883
|
+
/** 清理选项。 */
|
|
884
|
+
interface StewardPurgeOptions {
|
|
885
|
+
/** DSH 主目录;**缺失时拒绝执行**(破坏性操作不接受猜测的路径)。 */
|
|
886
|
+
dshHome?: string;
|
|
887
|
+
/** workspace.json 候选路径覆盖(测试注入用)。 */
|
|
888
|
+
searchPaths?: readonly string[];
|
|
889
|
+
}
|
|
890
|
+
/**
|
|
891
|
+
* `session-history-purge`:**真删除**归档会话的磁盘实体,并连带取消其归档状态。
|
|
892
|
+
* @param payload - `{ sessionIds: string[] }`。
|
|
893
|
+
* @param log - 可选日志出口。
|
|
894
|
+
* @param options - `dshHome` 必填;`searchPaths` 可选覆盖。
|
|
895
|
+
* @returns 清理条数、释放字节数与逐条失败。
|
|
896
|
+
*/
|
|
897
|
+
declare function purgeHistory(payload: unknown, log?: (msg: string) => void, options?: StewardPurgeOptions): StewardHistoryPurgeResult;
|
|
898
|
+
//#endregion
|
|
715
899
|
//#region src/host/health/lossless.d.ts
|
|
716
900
|
/**
|
|
717
901
|
* 无损 JSON 判定 —— 本次事故的核心 gate 判据。
|
|
@@ -790,6 +974,44 @@ declare function quarantineProjectionCache(sessionId: string, dshHome?: string,
|
|
|
790
974
|
* @returns 可复制执行的命令与人读说明。
|
|
791
975
|
*/
|
|
792
976
|
declare function prescribe(report: SessionHealthReport, dshHome?: string): string[];
|
|
977
|
+
/** 处置结果的定性分类。 */
|
|
978
|
+
type RepairVerdict =
|
|
979
|
+
/** 四门全绿,没有要做的事。 */
|
|
980
|
+
'nothing-to-do' |
|
|
981
|
+
/** 处置生效且异常已消除。 */
|
|
982
|
+
'repaired' |
|
|
983
|
+
/** 处置生效,但仍有与投影缓存无关的异常(如会话日志的 open step)。 */
|
|
984
|
+
'repaired-with-residual' |
|
|
985
|
+
/** 没有任何可逆处置项能命中当前异常。 */
|
|
986
|
+
'not-applicable' |
|
|
987
|
+
/** 处置本身执行失败。 */
|
|
988
|
+
'failed';
|
|
989
|
+
/** 处置结果的判定。 */
|
|
990
|
+
interface RepairAssessment {
|
|
991
|
+
verdict: RepairVerdict;
|
|
992
|
+
/** 人读说明:直接展示给用户,解释「为什么处置后还是异常/已恢复」。 */
|
|
993
|
+
explanation: string;
|
|
994
|
+
/** 处置后仍未解决的门(可处置档位)。 */
|
|
995
|
+
residual: {
|
|
996
|
+
id: string;
|
|
997
|
+
level: GateLevel;
|
|
998
|
+
}[];
|
|
999
|
+
}
|
|
1000
|
+
/**
|
|
1001
|
+
* 判定一次处置的结果,并给出人读说明。
|
|
1002
|
+
*
|
|
1003
|
+
* 存在的理由:处置**只**隔离投影缓存记录,而会话的异常可能来自别处
|
|
1004
|
+
* (最典型是 `cold-read` 的 open step——插件红线不改会话日志,这类异常
|
|
1005
|
+
* 本就不该由处置修复)。旧版 UI 只显示 `处置前/处置后` 两个档位,
|
|
1006
|
+
* 两者都是「异常」时用户无法判断是处置失败还是处置与病灶无关。
|
|
1007
|
+
*
|
|
1008
|
+
* @param input - 处置前后的报告与处置执行结果。
|
|
1009
|
+
*/
|
|
1010
|
+
declare function assessRepair(input: {
|
|
1011
|
+
before: SessionHealthReport;
|
|
1012
|
+
after: SessionHealthReport;
|
|
1013
|
+
repair: RepairOutcome;
|
|
1014
|
+
}): RepairAssessment;
|
|
793
1015
|
//#endregion
|
|
794
1016
|
//#region src/host/health/scan.d.ts
|
|
795
1017
|
/** 一个已发现的会话日志。 */
|
|
@@ -801,24 +1023,45 @@ interface DiscoveredSession {
|
|
|
801
1023
|
}
|
|
802
1024
|
/** 枚举全部会话日志(按 mtime 倒序),带可选上限。 */
|
|
803
1025
|
declare function discoverSessions(dshHome?: string, limit?: number): DiscoveredSession[];
|
|
1026
|
+
/**
|
|
1027
|
+
* 语料总数:只做目录枚举,**不跑体检**。
|
|
1028
|
+
*
|
|
1029
|
+
* 用于判断缓存是否已过期——枚举很便宜,而重扫要解 zstd、跑四门。
|
|
1030
|
+
* 正因为两者代价差着量级,「对账」才不构成缓存失效策略本身。
|
|
1031
|
+
* @param dshHome - DSH home(缺省 ~/.dsh)。
|
|
1032
|
+
*/
|
|
1033
|
+
declare function countCorpus(dshHome?: string): number;
|
|
804
1034
|
/** 定位一个会话的日志路径(跨工程目录查找)。 */
|
|
805
1035
|
declare function findSessionLog(sessionId: string, dshHome?: string): string | undefined;
|
|
806
1036
|
/** 扫描结果。 */
|
|
807
1037
|
interface HealthScanResult {
|
|
808
1038
|
ok: boolean;
|
|
1039
|
+
/** 本批实际体检的会话数(已访问数,不受 onlyProblems 过滤影响)。 */
|
|
809
1040
|
scanned: number;
|
|
1041
|
+
/**
|
|
1042
|
+
* 语料总数(进度分母)。分批调用时每批都拿到同一个值,客户端据此算
|
|
1043
|
+
* `已访问 = offset + scanned` / `total`,宿主无需持有跨请求状态。
|
|
1044
|
+
*/
|
|
1045
|
+
total: number;
|
|
1046
|
+
/** 本批在语料中的起点(原样回显,便于客户端对账)。 */
|
|
1047
|
+
offset: number;
|
|
810
1048
|
findings: SessionHealthReport[];
|
|
811
1049
|
/** 仅保留非 ok 的报告时使用。 */
|
|
812
1050
|
filtered?: boolean;
|
|
813
1051
|
error?: string;
|
|
814
1052
|
}
|
|
815
1053
|
/**
|
|
816
|
-
*
|
|
817
|
-
*
|
|
1054
|
+
* 批量体检(支持分批)。
|
|
1055
|
+
*
|
|
1056
|
+
* 语料先整体列出(按 mtime 倒序,≤ DISCOVERY_LIMIT),再按 `[offset, offset+limit)`
|
|
1057
|
+
* 切片扫描。这样客户端可以用小批次连续调用、自己累计真实进度,而宿主保持无状态
|
|
1058
|
+
* ——不必把同步循环改成异步,也不必新增进度轮询端点。
|
|
1059
|
+
* @param options - dshHome / 批大小 / 批起点 / 是否只返回非 ok / 归属查询 / 热态状态提供者。
|
|
818
1060
|
*/
|
|
819
1061
|
declare function scanSessions(options: {
|
|
820
1062
|
dshHome?: string;
|
|
821
1063
|
limit?: number;
|
|
1064
|
+
offset?: number;
|
|
822
1065
|
onlyProblems?: boolean;
|
|
823
1066
|
attribute?: GateContext['attribute'];
|
|
824
1067
|
projectionStateFor?: (sessionId: string) => Record<string, unknown> | undefined;
|
|
@@ -840,9 +1083,21 @@ interface StewardRuntime {
|
|
|
840
1083
|
field?: string;
|
|
841
1084
|
} | undefined;
|
|
842
1085
|
log: (message: string) => void;
|
|
1086
|
+
/**
|
|
1087
|
+
* 体检结果缓存(进程内,随 fiber 存活)。
|
|
1088
|
+
*
|
|
1089
|
+
* 可选:缺省表示本次装配不启用缓存(只影响「关面板重开」是否零延迟,
|
|
1090
|
+
* 不影响任何判定结果)。`apply()` 总是提供实例。
|
|
1091
|
+
*/
|
|
1092
|
+
cache?: HealthCache;
|
|
843
1093
|
}
|
|
844
|
-
/**
|
|
845
|
-
|
|
1094
|
+
/**
|
|
1095
|
+
* 支持的路由方法(按子域分组;用于对外声明与测试断言)。
|
|
1096
|
+
*
|
|
1097
|
+
* `session-history-prune` 与 `session-history-purge` 是**两件事**,不可合并:
|
|
1098
|
+
* prune = 取消归档状态(可逆,会话回到侧边栏);purge = 清理归档文件(不可逆,真删实体)。
|
|
1099
|
+
*/
|
|
1100
|
+
declare const HISTORY_METHODS: readonly ["session-history-list", "session-history-prune", "session-history-purge"];
|
|
846
1101
|
declare const HEALTH_METHODS: readonly ["session-health-status", "session-health-scan", "session-health-session", "session-health-repair"];
|
|
847
1102
|
/** 依据开关判定某方法是否启用。 */
|
|
848
1103
|
declare function methodEnabled(method: string, config: Required<StewardConfig>): boolean;
|
|
@@ -859,4 +1114,4 @@ declare function handleMethod(method: string, payload: unknown, runtime: Steward
|
|
|
859
1114
|
*/
|
|
860
1115
|
declare function apply(ctx: Context): void;
|
|
861
1116
|
//#endregion
|
|
862
|
-
export { DEFAULT_CONFIG, HEALTH_METHODS, HISTORY_METHODS, STEWARD_API_PREFIX, STEWARD_SETTINGS_NAMESPACE, type StewardConfig, StewardRuntime, apply, buildProjectionOwnerIndex, buildSessionReport, createAttributor, decodeSessionLogBytes, decodeSessionLogFile, discoverSessions, findSessionLog, firstLosslessViolation, gateColdRead, gateLogIntegrity, gateLosslessJson, gateProjectionCache, handleMethod, inject, isLossless, listHistory, methodEnabled, prescribe, pruneArchiveFile, pruneHistory, quarantineProjectionCache, readArchiveSet, readProjectionCache, readTailFacts, scanSessions, scanZstdFrames };
|
|
1117
|
+
export { DEFAULT_CONFIG, HEALTH_METHODS, HISTORY_METHODS, HealthCache, type HealthCacheEntry, type RepairAssessment, type RepairVerdict, STEWARD_API_PREFIX, STEWARD_SETTINGS_NAMESPACE, type StewardConfig, StewardRuntime, apply, assessRepair, buildProjectionOwnerIndex, buildSessionReport, countCorpus, createAttributor, decodeSessionLogBytes, decodeSessionLogFile, dirSize, discoverSessions, editWorkspaceDocument, findSessionLog, firstLosslessViolation, gateColdRead, gateLogIntegrity, gateLosslessJson, gateProjectionCache, handleMethod, indexSessionDirs, inject, isLossless, isSafeChild, listHistory, locateSessionUsage, methodEnabled, prescribe, projCacheRootFor, pruneArchiveFile, pruneHistory, purgeHistory, quarantineProjectionCache, readArchiveSet, readProjectionCache, readTailFacts, scanSessions, scanZstdFrames, sessionsRootFor };
|